LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAicGVleGUuaCIKI2luY2x1ZGUgIm5lZXhlLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJzZWxlY3RvcnMuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImxkdC5oIgojaW5jbHVkZSAicHJvY2Vzcy5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJkb3Ntb2QuaCIKI2luY2x1ZGUgIm9wdGlvbnMuaCIKI2luY2x1ZGUgInNlcnZlci5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKG1vZHVsZSkKCiNpZmRlZiBNWl9TVVBQT1JURUQKCiNpZmRlZiBIQVZFX1NZU19NTUFOX0gKIyBpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKCi8qIGRlZmluZSB0aGlzIHRvIHRyeSBtYXBwaW5nIHRocm91Z2ggL3Byb2MvcGlkL21lbSBpbnN0ZWFkIG9mIGEgdGVtcCBmaWxlLAogICBidXQgTGludXMgZG9lc24ndCBsaWtlIG1tYXBwaW5nIC9wcm9jL3BpZC9tZW0sIHNvIGl0IGRvZXNuJ3Qgd29yayBmb3IgbWUgKi8KI3VuZGVmIE1aX01BUFNFTEYKCiNkZWZpbmUgQklPU19EQVRBX1NFR01FTlQgMHg0MAojZGVmaW5lIFNUQVJUX09GRlNFVCAwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKc3RhdGljIHZvaWQgTVpfSW5pdFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kbGluZSwgV09SRCBlbnYgKQp7CiBQREIxNipwc3A9bHBQU1A7CiBjb25zdCBjaGFyKmNtZD1jbWRsaW5lP3N0cmNocihjbWRsaW5lLCcgJyk6TlVMTDsKCiBwc3AtPmludDIwPTB4MjBDRDsgLyogaW50IDIwICovCiAvKiBzb21lIHByb2dyYW1zIHVzZSB0aGlzIHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgdGhleSBuZWVkICovCiBwc3AtPm5leHRQYXJhZ3JhcGg9MHg5RkZGOwogcHNwLT5lbnZpcm9ubWVudD1lbnY7CiAvKiBjb3B5IHBhcmFtZXRlcnMgKi8KIGlmIChjbWQpIHsKI2lmIDAKICAvKiBjb21tYW5kLmNvbSBkb2Vzbid0IGRvIHRoaXMgKi8KICB3aGlsZSAoKmNtZCA9PSAnICcpIGNtZCsrOwojZW5kaWYKICBwc3AtPmNtZExpbmVbMF09c3RybGVuKGNtZCk7CiAgc3RyY3B5KHBzcC0+Y21kTGluZSsxLGNtZCk7CiAgcHNwLT5jbWRMaW5lW3BzcC0+Y21kTGluZVswXSsxXT0nXHInOwogfSBlbHNlIHBzcC0+Y21kTGluZVsxXT0nXHInOwogLyogRklYTUU6IGludGVncmF0ZSB0aGUgbWVtb3J5IHN0dWZmIGZyb20gV2luZSAobXNkb3MvZG9zbWVtLmMpICovCiAvKiBGSVhNRTogaW50ZWdyYXRlIHRoZSBQREIgc3R1ZmYgZnJvbSBXaW5lIChsb2FkZXIvdGFzay5jKSAqLwp9CgovKiBkZWZhdWx0IElOVCAwOCBoYW5kbGVyOiBpbmNyZWFzZXMgdGltZXIgdGljayBjb3VudGVyIGJ1dCBub3QgbXVjaCBtb3JlICovCnN0YXRpYyBjaGFyIGludDA4W109ewogMHhDRCwweDFDLCAgICAgICAgICAgLyogaW50ICQweDFjICovCiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4MUUsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkcyAqLwogMHhCOCwweDQwLDB4MDAsICAgICAgLyogbW92dyAkMHg0MCwlYXggKi8KIDB4OEUsMHhEOCwgICAgICAgICAgIC8qIG1vdncgJWF4LCVkcyAqLwojaWYgMAogMHg4MywweDA2LDB4NkMsMHgwMCwweDAxLCAvKiBhZGR3ICQxLCgweDZjKSAqLwogMHg4MywweDE2LDB4NkUsMHgwMCwweDAwLCAvKiBhZGN3ICQwLCgweDZlKSAqLwojZWxzZQogMHg2NiwweEZGLDB4MDYsMHg2QywweDAwLCAvKiBpbmNsICgweDZjKSAqLwojZW5kaWYKIDB4QjAsMHgyMCwgICAgICAgICAgIC8qIG1vdmIgJDB4MjAsJWFsICovCiAweEU2LDB4MjAsICAgICAgICAgICAvKiBvdXRiICVhbCwkMHgyMCAqLwogMHgxRiwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENGICAgICAgICAgICAgICAgICAvKiBpcmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0SGFuZGxlcnMoIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBXT1JEIHNlZzsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHNpemVvZihpbnQwOCksJnNlZyk7CiBtZW1jcHkoc3RhcnQsaW50MDgsc2l6ZW9mKGludDA4KSk7Ci8qIElOVCAwODogcG9pbnQgaXQgYXQgb3VyIHRpY2staW5jcmVtZW50aW5nIGhhbmRsZXIgKi8KICgoU0VHUFRSKikobHBEb3NUYXNrLT5pbWcpKVsweDA4XT1QVFJfU0VHX09GRl9UT19TRUdQVFIoc2VnLDApOwovKiBJTlQgMUM6IGp1c3QgcG9pbnQgaXQgdG8gSVJFVCwgd2UgZG9uJ3Qgd2FudCB0byBoYW5kbGUgaXQgb3Vyc2VsdmVzICovCiAoKFNFR1BUUiopKGxwRG9zVGFzay0+aW1nKSlbMHgxQ109UFRSX1NFR19PRkZfVE9fU0VHUFRSKHNlZyxzaXplb2YoaW50MDgpLTEpOwp9CgpzdGF0aWMgY2hhciBlbnRlcl94bXNbXT17Ci8qIFhNUyBob29rYWJsZSBlbnRyeSBwb2ludCAqLwogMHhFQiwweDAzLCAgICAgICAgICAgLyogam1wIGVudHJ5ICovCiAweDkwLDB4OTAsMHg5MCwgICAgICAvKiBub3A7bm9wO25vcCAqLwogICAgICAgICAgICAgICAgICAgICAgLyogZW50cnk6ICovCi8qIHJlYWwgZW50cnkgcG9pbnQgKi8KLyogZm9yIHNpbXBsaWNpdHksIHdlJ2xsIGp1c3QgdXNlIHRoZSBzYW1lIGhvb2sgYXMgRFBNSSBiZWxvdyAqLwogMHhDRCwweDMxLCAgICAgICAgICAgLyogaW50ICQweDMxICovCiAweENCICAgICAgICAgICAgICAgICAvKiBscmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0WE1TKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogTFBCWVRFIHN0YXJ0PURPU01FTV9HZXRCbG9jayhscERvc1Rhc2stPmhNb2R1bGUsc2l6ZW9mKGVudGVyX3htcyksJihscERvc1Rhc2stPnhtc19zZWcpKTsKIG1lbWNweShzdGFydCxlbnRlcl94bXMsc2l6ZW9mKGVudGVyX3htcykpOwp9CgpzdGF0aWMgY2hhciBlbnRlcl9wbVtdPXsKIDB4NTAsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVheCAqLwogMHg1MiwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWR4ICovCiAweDU1LCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYnAgKi8KIDB4ODksMHhFNSwgICAgICAgICAgIC8qIG1vdncgJXNwLCVicCAqLwovKiBnZXQgcmV0dXJuIENTICovCiAweDhCLDB4NTYsMHgwOCwgICAgICAvKiBtb3Z3IDgoJWJwKSwlZHggKi8KLyoganVzdCBjYWxsIGludCAzMSBoZXJlIHRvIGdldCBpbnRvIHByb3RlY3RlZCBtb2RlLi4uICovCi8qIGl0J2xsIGNoZWNrIHdoZXRoZXIgaXQgd2FzIGNhbGxlZCBmcm9tIGRwbWlfc2VnLi4uICovCiAweENELDB4MzEsICAgICAgICAgICAvKiBpbnQgJDB4MzEgKi8KLyogd2UgYXJlIG5vdyBpbiB0aGUgY29udGV4dCBvZiBhIDE2LWJpdCByZWxheSBjYWxsICovCi8qIG5lZWQgdG8gZml4dXAgb3VyIHN0YWNrOwogKiAxNi1iaXQgcmVsYXkgcmV0dXJuIGFkZHJlc3Mgd2lsbCBiZSBsb3N0LCBidXQgd2Ugd29uJ3Qgd29ycnkgcXVpdGUgeWV0ICovCiAweDhFLDB4RDAsICAgICAgICAgICAvKiBtb3Z3ICVheCwlc3MgKi8KIDB4NjYsMHgwRiwweEI3LDB4RTUsIC8qIG1vdnp3bCAlYnAsJWVzcCAqLwovKiBzZXQgcmV0dXJuIENTICovCiAweDg5LDB4NTYsMHgwOCwgICAgICAvKiBtb3Z3ICVkeCw4KCVicCkgKi8KIDB4NUQsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWJwICovCiAweDVBLCAgICAgICAgICAgICAgICAvKiBwb3B3ICVkeCAqLwogMHg1OCwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4Q0IgICAgICAgICAgICAgICAgIC8qIGxyZXQgKi8KfTsKCnN0YXRpYyB2b2lkIE1aX0luaXREUE1JKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogdW5zaWduZWQgc2l6ZT1zaXplb2YoZW50ZXJfcG0pOwogTFBCWVRFIHN0YXJ0PURPU01FTV9HZXRCbG9jayhscERvc1Rhc2stPmhNb2R1bGUsc2l6ZSwmKGxwRG9zVGFzay0+ZHBtaV9zZWcpKTsKIAogbHBEb3NUYXNrLT5kcG1pX3NlbCA9IFNFTEVDVE9SX0FsbG9jQmxvY2soIHN0YXJ0LCBzaXplLCBTRUdNRU5UX0NPREUsIEZBTFNFLCBGQUxTRSApOwoKIG1lbWNweShzdGFydCxlbnRlcl9wbSxzaXplb2YoZW50ZXJfcG0pKTsKfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUERPU1RBU0sgbHBEb3NUYXNrLCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHN6K3NpemVvZihXT1JEKStzdHJsZW4obmFtZSkrMSwmc2VnKTsKIC8qIGZpbGwgaXQgKi8KIGlmIChlbnYpIHsKICBtZW1jcHkoZW52YmxrLGVudixzeik7CiB9IGVsc2UgZW52YmxrWzBdPTA7CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdE1lbW9yeSggTFBET1NUQVNLIGxwRG9zVGFzaywgTkVfTU9EVUxFICpwTW9kdWxlICkKewogaW50IHg7CgogaWYgKGxwRG9zVGFzay0+aW1nKSByZXR1cm4gVFJVRTsgLyogYWxyZWFkeSBhbGxvY2F0ZWQgKi8KCiAvKiBhbGxvY2F0ZSAxTUIrNjRLIHNoYXJlZCBtZW1vcnkgKi8KIGxwRG9zVGFzay0+aW1nX29mcz1TVEFSVF9PRkZTRVQ7CiNpZmRlZiBNWl9NQVBTRUxGCiBscERvc1Rhc2stPmltZz1WaXJ0dWFsQWxsb2MoTlVMTCwweDExMDAwMCxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKIC8qIG1ha2Ugc3VyZSBtbWFwIGFjY2VwdHMgaXQgKi8KICgoY2hhciopbHBEb3NUYXNrLT5pbWcpWzB4MTBGRkZGXT0wOwojZWxzZQogdG1wbmFtKGxwRG9zVGFzay0+bW1fbmFtZSk7Ci8qIHN0cmNweShscERvc1Rhc2stPm1tX25hbWUsIi90bXAvbXlkb3NpbWFnZSIpOyAqLwogbHBEb3NUYXNrLT5tbV9mZD1vcGVuKGxwRG9zVGFzay0+bW1fbmFtZSxPX1JEV1J8T19DUkVBVCAvKiB8T19UUlVOQyAqLyxTX0lSVVNSfFNfSVdVU1IpOwogaWYgKGxwRG9zVGFzay0+bW1fZmQ8MCkgRVJSKCJmaWxlICVzIGNvdWxkIG5vdCBiZSBvcGVuZWRcbiIsbHBEb3NUYXNrLT5tbV9uYW1lKTsKIC8qIGV4cGFuZCBmaWxlIHRvIDFNQis2NEsgKi8KIGxzZWVrKGxwRG9zVGFzay0+bW1fZmQsMHgxMTAwMDAtMSxTRUVLX1NFVCk7CiB4PTA7IHdyaXRlKGxwRG9zVGFzay0+bW1fZmQsJngsMSk7CiAvKiBtYXAgaXQgaW4gKi8KIGxwRG9zVGFzay0+aW1nPW1tYXAoTlVMTCwweDExMDAwMC1TVEFSVF9PRkZTRVQsUFJPVF9SRUFEfFBST1RfV1JJVEUsTUFQX1NIQVJFRCxscERvc1Rhc2stPm1tX2ZkLDApOwojZW5kaWYKIGlmIChscERvc1Rhc2stPmltZz09KExQVk9JRCktMSkgewogIEVSUigiY291bGQgbm90IG1hcCBzaGFyZWQgbWVtb3J5LCBlcnJvcj0lc1xuIixzdHJlcnJvcihlcnJubykpOwogIHJldHVybiBGQUxTRTsKIH0KIFRSQUNFKCJET1MgVk04NiBpbWFnZSBtYXBwZWQgYXQgJTA4bHhcbiIsKERXT1JEKWxwRG9zVGFzay0+aW1nKTsKIHBNb2R1bGUtPmRvc19pbWFnZT1scERvc1Rhc2stPmltZzsKCiAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KIFRSQUNFKCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKIERPU01FTV9Jbml0KGxwRG9zVGFzay0+aE1vZHVsZSk7CiBNWl9Jbml0SGFuZGxlcnMobHBEb3NUYXNrKTsKIE1aX0luaXRYTVMobHBEb3NUYXNrKTsKIE1aX0luaXREUE1JKGxwRG9zVGFzayk7CiByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgTVpfTG9hZEltYWdlKCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSwgTFBDU1RSIGNtZGxpbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGVudiwgTFBET1NUQVNLIGxwRG9zVGFzaywgTkVfTU9EVUxFICpwTW9kdWxlICkKewogSU1BR0VfRE9TX0hFQURFUiBtel9oZWFkZXI7CiBEV09SRCBpbWFnZV9zdGFydCxpbWFnZV9zaXplLG1pbl9zaXplLG1heF9zaXplLGF2YWlsOwogQllURSpwc3Bfc3RhcnQsKmxvYWRfc3RhcnQ7CiBpbnQgeCxvbGRfY29tPTA7CiBTRUdQVFIgcmVsb2M7CiBXT1JEIGVudl9zZWc7CiBEV09SRCBsZW47CgogU2V0RmlsZVBvaW50ZXIoaEZpbGUsMCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCAgICFSZWFkRmlsZShoRmlsZSwmbXpfaGVhZGVyLHNpemVvZihtel9oZWFkZXIpLCZsZW4sTlVMTCkKICAgICB8fCBsZW4gIT0gc2l6ZW9mKG16X2hlYWRlcikgCiAgICAgfHwgbXpfaGVhZGVyLmVfbWFnaWMgIT0gSU1BR0VfRE9TX1NJR05BVFVSRSkgewogIG9sZF9jb209MTsgLyogYXNzdW1lIC5DT00gZmlsZSAqLwogIGltYWdlX3N0YXJ0PTA7CiAgaW1hZ2Vfc2l6ZT1HZXRGaWxlU2l6ZShoRmlsZSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgaWYgKChtel9oZWFkZXIuZV9jYmxwIT0wKSYmKG16X2hlYWRlci5lX2NibHAhPTQpKSBpbWFnZV9zaXplLT01MTItbXpfaGVhZGVyLmVfY2JscDsKICBpbWFnZV9zaXplLT1pbWFnZV9zdGFydDsKICBtaW5fc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWluYWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiAgbWF4X3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21heGFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogfQoKIE1aX0luaXRNZW1vcnkobHBEb3NUYXNrLHBNb2R1bGUpOwoKIC8qIGFsbG9jYXRlIGVudmlyb25tZW50IGJsb2NrICovCiBlbnZfc2VnPU1aX0luaXRFbnZpcm9ubWVudChscERvc1Rhc2ssZW52LGZpbGVuYW1lKTsKCiAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBleGVjdXRhYmxlICovCiBUUkFDRSgiQWxsb2NhdGluZyBET1MgbWVtb3J5IChtaW49JWxkLCBtYXg9JWxkKVxuIixtaW5fc2l6ZSxtYXhfc2l6ZSk7CiBhdmFpbD1ET1NNRU1fQXZhaWxhYmxlKGxwRG9zVGFzay0+aE1vZHVsZSk7CiBpZiAoYXZhaWw8bWluX3NpemUpIHsKICBFUlIoImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogIHJldHVybiBGQUxTRTsKIH0KIGlmIChhdmFpbD5tYXhfc2l6ZSkgYXZhaWw9bWF4X3NpemU7CiBwc3Bfc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxhdmFpbCwmbHBEb3NUYXNrLT5wc3Bfc2VnKTsKIGlmICghcHNwX3N0YXJ0KSB7CiAgRVJSKCJlcnJvciBhbGxvY2F0aW5nIERPUyBtZW1vcnlcbiIpOwogIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgcmV0dXJuIEZBTFNFOwogfQogbHBEb3NUYXNrLT5sb2FkX3NlZz1scERvc1Rhc2stPnBzcF9zZWcrKG9sZF9jb20/MDpQU1BfU0laRSk7CiBsb2FkX3N0YXJ0PXBzcF9zdGFydCsoUFNQX1NJWkU8PDQpOwogTVpfSW5pdFBTUChwc3Bfc3RhcnQsIGNtZGxpbmUsIGVudl9zZWcpOwoKIC8qIGxvYWQgZXhlY3V0YWJsZSBpbWFnZSAqLwogVFJBQ0UoImxvYWRpbmcgRE9TICVzIGltYWdlLCAlMDhseCBieXRlc1xuIixvbGRfY29tPyJDT00iOiJFWEUiLGltYWdlX3NpemUpOwogU2V0RmlsZVBvaW50ZXIoaEZpbGUsaW1hZ2Vfc3RhcnQsTlVMTCxGSUxFX0JFR0lOKTsKIGlmICghUmVhZEZpbGUoaEZpbGUsbG9hZF9zdGFydCxpbWFnZV9zaXplLCZsZW4sTlVMTCkgfHwgbGVuICE9IGltYWdlX3NpemUpIHsKICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgcmV0dXJuIEZBTFNFOwogfQoKIGlmIChtel9oZWFkZXIuZV9jcmxjKSB7CiAgLyogbG9hZCByZWxvY2F0aW9uIHRhYmxlICovCiAgVFJBQ0UoImxvYWRpbmcgRE9TIEVYRSByZWxvY2F0aW9uIHRhYmxlLCAlZCBlbnRyaWVzXG4iLG16X2hlYWRlci5lX2NybGMpOwogIC8qIEZJWE1FOiBpcyB0aGlzIHRvbyBzbG93IHdpdGhvdXQgcmVhZCBidWZmZXJpbmc/ICovCiAgU2V0RmlsZVBvaW50ZXIoaEZpbGUsbXpfaGVhZGVyLmVfbGZhcmxjLE5VTEwsRklMRV9CRUdJTik7CiAgZm9yICh4PTA7IHg8bXpfaGVhZGVyLmVfY3JsYzsgeCsrKSB7CiAgIGlmICghUmVhZEZpbGUoaEZpbGUsJnJlbG9jLHNpemVvZihyZWxvYyksJmxlbixOVUxMKSB8fCBsZW4gIT0gc2l6ZW9mKHJlbG9jKSkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgcmV0dXJuIEZBTFNFOwogICB9CiAgICooV09SRCopU0VHUFRSMTYobG9hZF9zdGFydCxyZWxvYykrPWxwRG9zVGFzay0+bG9hZF9zZWc7CiAgfQogfQoKIGxwRG9zVGFzay0+aW5pdF9jcz1scERvc1Rhc2stPmxvYWRfc2VnK216X2hlYWRlci5lX2NzOwogbHBEb3NUYXNrLT5pbml0X2lwPW16X2hlYWRlci5lX2lwOwogbHBEb3NUYXNrLT5pbml0X3NzPWxwRG9zVGFzay0+bG9hZF9zZWcrbXpfaGVhZGVyLmVfc3M7CiBscERvc1Rhc2stPmluaXRfc3A9bXpfaGVhZGVyLmVfc3A7CgogVFJBQ0UoImVudHJ5IHBvaW50OiAlMDR4OiUwNHhcbiIsbHBEb3NUYXNrLT5pbml0X2NzLGxwRG9zVGFzay0+aW5pdF9pcCk7CiByZXR1cm4gVFJVRTsKfQoKTFBET1NUQVNLIE1aX0FsbG9jRFBNSVRhc2soIEhNT0RVTEUxNiBoTW9kdWxlICkKewogTFBET1NUQVNLIGxwRG9zVGFzayA9IGNhbGxvYygxLCBzaXplb2YoRE9TVEFTSykpOwogTkVfTU9EVUxFICpwTW9kdWxlOwoKIGlmIChscERvc1Rhc2spIHsKICBscERvc1Rhc2stPmhNb2R1bGUgPSBoTW9kdWxlOwoKICBwTW9kdWxlID0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNihoTW9kdWxlKTsKICBwTW9kdWxlLT5scERvc1Rhc2sgPSBscERvc1Rhc2s7CiAKICBscERvc1Rhc2stPmltZz1OVUxMOyBscERvc1Rhc2stPm1tX25hbWVbMF09MDsgbHBEb3NUYXNrLT5tbV9mZD0tMTsKCiAgTVpfSW5pdE1lbW9yeShscERvc1Rhc2ssIHBNb2R1bGUpOwoKICBHbG9iYWxVbmxvY2sxNihoTW9kdWxlKTsKIH0KIHJldHVybiBscERvc1Rhc2s7Cn0KCnN0YXRpYyB2b2lkIE1aX0luaXRUaW1lciggTFBET1NUQVNLIGxwRG9zVGFzaywgaW50IHZlciApCnsKIGlmICh2ZXI8MSkgewogIC8qIGNhbid0IG1ha2UgdGltZXIgdGlja3MgKi8KIH0gZWxzZSB7CiAgaW50IGZ1bmM7CiAgc3RydWN0IHRpbWV2YWwgdGltOwoKICAvKiBzdGFydCBkb3Ntb2QgdGltZXIgYXQgNTVtcyAoMTguMkh6KSAqLwogIGZ1bmM9RE9TTU9EX1NFVF9USU1FUjsKICB0aW0udHZfc2VjPTA7IHRpbS50dl91c2VjPTU0OTI1OwogIHdyaXRlKGxwRG9zVGFzay0+d3JpdGVfcGlwZSwmZnVuYyxzaXplb2YoZnVuYykpOwogIHdyaXRlKGxwRG9zVGFzay0+d3JpdGVfcGlwZSwmdGltLHNpemVvZih0aW0pKTsKIH0KfQoKQk9PTCBNWl9Jbml0VGFzayggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKICBpbnQgd3JpdGVfZmRbMl0seF9mZDsKICBwaWRfdCBjaGlsZDsKICBjaGFyICpmbmFtZSwqZmFyZyxhcmdbMTZdLGZwcm9jWzY0XSxwYXRoWzI1Nl0sKmZwYXRoOwogIFNFQ1VSSVRZX0FUVFJJQlVURVMgYXR0cj17c2l6ZW9mKGF0dHIpLE5VTEwsVFJVRX07CiAgc3RydWN0IGdldF9yZWFkX2ZkX3JlcXVlc3QgKnJfcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKICBzdHJ1Y3QgZ2V0X3dyaXRlX2ZkX3JlcXVlc3QgKndfcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKCiAgaWYgKCFscERvc1Rhc2spIHJldHVybiBGQUxTRTsKICAvKiBjcmVhdGUgcGlwZXMgKi8KICAvKiB0aGlzIGhhcHBlbnMgaW4gdGhlIHdyb25nIHByb2Nlc3MgY29udGV4dCwgc28gd2UgaGF2ZSB0byBsZXQgdGhlIG5ldyBwcm9jZXNzCiAgICAgaW5oZXJpdCBpdC4uLiAoRklYTUU6IGNhbGwgTVpfSW5pdFRhc2sgaW4gdGhlIHJpZ2h0IHByb2Nlc3MgY29udGV4dCkgKi8KICBpZiAoIUNyZWF0ZVBpcGUoJihscERvc1Rhc2stPmhSZWFkUGlwZSksJihscERvc1Rhc2stPmhYUGlwZSksJmF0dHIsMCkpIHJldHVybiBGQUxTRTsKICBpZiAocGlwZSh3cml0ZV9mZCk8MCkgewogICAgQ2xvc2VIYW5kbGUobHBEb3NUYXNrLT5oUmVhZFBpcGUpOwogICAgQ2xvc2VIYW5kbGUobHBEb3NUYXNrLT5oWFBpcGUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KICByX3JlcS0+aGFuZGxlID0gbHBEb3NUYXNrLT5oUmVhZFBpcGU7CiAgc2VydmVyX2NhbGxfZmQoIFJFUV9HRVRfUkVBRF9GRCwgLTEsICZscERvc1Rhc2stPnJlYWRfcGlwZSApOwogIHdfcmVxLT5oYW5kbGUgPSBscERvc1Rhc2stPmhYUGlwZTsKICBzZXJ2ZXJfY2FsbF9mZCggUkVRX0dFVF9XUklURV9GRCwgLTEsICZ4X2ZkICk7CgogIFRSQUNFKCJ3aW4zMiBwaXBlOiByZWFkPSVkLCB3cml0ZT0lZCwgdW5peCBwaXBlOiByZWFkPSVkLCB3cml0ZT0lZFxuIiwKCSAgICAgICBscERvc1Rhc2stPmhSZWFkUGlwZSxscERvc1Rhc2stPmhYUGlwZSxscERvc1Rhc2stPnJlYWRfcGlwZSx4X2ZkKTsKICBUUkFDRSgib3V0Ym91bmQgdW5peCBwaXBlOiByZWFkPSVkLCB3cml0ZT0lZCwgcGlkPSVkXG4iLHdyaXRlX2ZkWzBdLHdyaXRlX2ZkWzFdLGdldHBpZCgpKTsKCiAgbHBEb3NUYXNrLT53cml0ZV9waXBlPXdyaXRlX2ZkWzFdOwoKICBscERvc1Rhc2stPmhDb25JbnB1dD1HZXRTdGRIYW5kbGUoU1REX0lOUFVUX0hBTkRMRSk7CiAgbHBEb3NUYXNrLT5oQ29uT3V0cHV0PUdldFN0ZEhhbmRsZShTVERfT1VUUFVUX0hBTkRMRSk7CgogIC8qIGlmIHdlIGhhdmUgYSBtYXBwaW5nIGZpbGUsIHVzZSBpdCAqLwogIGZuYW1lPWxwRG9zVGFzay0+bW1fbmFtZTsgZmFyZz1OVUxMOwogIGlmICghZm5hbWVbMF0pIHsKICAgIC8qIG90aGVyd2lzZSwgbWFwIG91ciBvd24gbWVtb3J5IGltYWdlICovCiAgICBzcHJpbnRmKGZwcm9jLCIvcHJvYy8lZC9tZW0iLGdldHBpZCgpKTsKICAgIHNwcmludGYoYXJnLCIlbGQiLCh1bnNpZ25lZCBsb25nKWxwRG9zVGFzay0+aW1nKTsKICAgIGZuYW1lPWZwcm9jOyBmYXJnPWFyZzsKICB9CgogIFRSQUNFKCJMb2FkaW5nIERPUyBWTSBzdXBwb3J0IG1vZHVsZSAoaG1vZHVsZT0lMDR4KVxuIixscERvc1Rhc2stPmhNb2R1bGUpOwogIGlmICgoY2hpbGQ9Zm9yaygpKTwwKSB7CiAgICBjbG9zZSh3cml0ZV9mZFswXSk7CiAgICBjbG9zZShscERvc1Rhc2stPnJlYWRfcGlwZSk7CiAgICBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwogICAgY2xvc2UoeF9mZCk7CiAgICBDbG9zZUhhbmRsZShscERvc1Rhc2stPmhSZWFkUGlwZSk7CiAgICBDbG9zZUhhbmRsZShscERvc1Rhc2stPmhYUGlwZSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQogaWYgKGNoaWxkIT0wKSB7CiAgLyogcGFyZW50IHByb2Nlc3MgKi8KICBpbnQgcmV0OwoKICBjbG9zZSh3cml0ZV9mZFswXSk7CiAgY2xvc2UoeF9mZCk7CiAgbHBEb3NUYXNrLT50YXNrPWNoaWxkOwogIC8qIHdhaXQgZm9yIGNoaWxkIHByb2Nlc3MgdG8gc2lnbmFsIHJlYWRpbmVzcyAqLwogIHdoaWxlICgxKSB7CiAgICBpZiAocmVhZChscERvc1Rhc2stPnJlYWRfcGlwZSwmcmV0LHNpemVvZihyZXQpKT09c2l6ZW9mKHJldCkpIGJyZWFrOwogICAgaWYgKChlcnJubz09RUlOVFIpfHwoZXJybm89PUVBR0FJTikpIGNvbnRpbnVlOwogICAgLyogZmFpbHVyZSAqLwogICAgRVJSKCJkb3Ntb2QgaGFzIGZhaWxlZCB0byBpbml0aWFsaXplXG4iKTsKICAgIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KICAvKiB0aGUgY2hpbGQgaGFzIG5vdyBtbWFwZWQgdGhlIHRlbXAgZmlsZSwgaXQncyBub3cgc2FmZSB0byB1bmxpbmsuCiAgICogZG8gaXQgaGVyZSB0byBhdm9pZCBsZWF2aW5nIGEgbWVzcyBpbiAvdG1wIGlmL3doZW4gV2luZSBjcmFzaGVzLi4uICovCiAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgdW5saW5rKGxwRG9zVGFzay0+bW1fbmFtZSk7CiAgLyogc3RhcnQgc2ltdWxhdGVkIHN5c3RlbSB0aW1lciAqLwogIE1aX0luaXRUaW1lcihscERvc1Rhc2sscmV0KTsKICBpZiAocmV0PDIpIHsKICAgIEVSUigiZG9zbW9kIHZlcnNpb24gdG9vIG9sZCEgUGxlYXNlIGluc3RhbGwgbmV3ZXIgZG9zbW9kIHByb3Blcmx5XG4iKTsKICAgIEVSUigiSWYgeW91IGRvbid0LCB0aGUgbmV3IGRvc21vZCBldmVudCBoYW5kbGluZyBzeXN0ZW0gd2lsbCBub3Qgd29ya1xuIik7CiAgfQogIC8qIGFsbCBzeXN0ZW1zIGFyZSBub3cgZ28gKi8KIH0gZWxzZSB7CiAgLyogY2hpbGQgcHJvY2VzcyAqLwogIGNsb3NlKGxwRG9zVGFzay0+cmVhZF9waXBlKTsKICBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwogIC8qIHB1dCBvdXIgcGlwZXMgc29tZXdoZXJlIGRvc21vZCBjYW4gZmluZCB0aGVtICovCiAgZHVwMih3cml0ZV9mZFswXSwwKTsgLyogc3RkaW4gKi8KICBkdXAyKHhfZmQsMSk7ICAgICAgICAvKiBzdGRvdXQgKi8KICAvKiBub3cgbG9hZCBkb3Ntb2QgKi8KICAvKiBjaGVjayBhcmd2WzBdLWRlcml2ZWQgcGF0aHMgZmlyc3QsIHNpbmNlIHRoZSBuZXdlc3QgZG9zbW9kIGlzIG1vc3QgbGlrZWx5IHRoZXJlCiAgICogKGF0IGxlYXN0IGl0IHdhcyBvbmNlIGZvciBBbmRyZWFzIE1vaHIsIHNvIEkgZGVjaWRlZCB0byBtYWtlIGl0IGVhc2llciBmb3IgaGltKSAqLwogIGZwYXRoPXN0cnJjaHIoc3RyY3B5KHBhdGgsT3B0aW9ucy5hcmd2MCksJy8nKTsKICBpZiAoZnBhdGgpIHsKICAgc3RyY3B5KGZwYXRoLCIvZG9zbW9kIik7CiAgIGV4ZWNsKHBhdGgsZm5hbWUsZmFyZyxOVUxMKTsKICAgc3RyY3B5KGZwYXRoLCIvbG9hZGVyL2Rvcy9kb3Ntb2QiKTsKICAgZXhlY2wocGF0aCxmbmFtZSxmYXJnLE5VTEwpOwogIH0KICAvKiBva2F5LCBpdCB3YXNuJ3QgdGhlcmUsIHRyeSBpbiB0aGUgcGF0aCAqLwogIGV4ZWNscCgiZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIC8qIGxhc3QgZGVzcGVyYXRlIGF0dGVtcHRzOiBjdXJyZW50IGRpcmVjdG9yeSAqLwogIGV4ZWNsKCJkb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgLyogYW5kLCBqdXN0IGZvciBjb21wbGV0ZW5lc3MuLi4gKi8KICBleGVjbCgibG9hZGVyL2Rvcy9kb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgLyogaWYgZmFpbHVyZSwgZXhpdCAqLwogIEVSUigiRmFpbGVkIHRvIHNwYXduIGRvc21vZCwgZXJyb3I9JXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICBleGl0KDEpOwogfQogcmV0dXJuIFRSVUU7Cn0KCkJPT0wgTVpfQ3JlYXRlUHJvY2VzcyggSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUsIExQQ1NUUiBjbWRsaW5lLCBMUENTVFIgZW52LCAKICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgcHNhLCBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgdHNhLAogICAgICAgICAgICAgICAgICAgICAgIEJPT0wgaW5oZXJpdCwgRFdPUkQgZmxhZ3MsIExQU1RBUlRVUElORk9BIHN0YXJ0dXAsIAogICAgICAgICAgICAgICAgICAgICAgIExQUFJPQ0VTU19JTkZPUk1BVElPTiBpbmZvICkKewogTFBET1NUQVNLIGxwRG9zVGFzayA9IE5VTEw7IC8qIGtlZXAgZ2NjIGZyb20gY29tcGxhaW5pbmcgKi8KIEhNT0RVTEUxNiBoTW9kdWxlOwogUERCICpwZGIgPSBQUk9DRVNTX0N1cnJlbnQoKTsKIFREQiAqcFRhc2sgPSAoVERCKilHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKIE5FX01PRFVMRSAqcE1vZHVsZSA9IHBUYXNrID8gTkVfR2V0UHRyKCBwVGFzay0+aE1vZHVsZSApIDogTlVMTDsKIGludCBhbGxvYyA9ICEocE1vZHVsZSAmJiBwTW9kdWxlLT5kb3NfaW1hZ2UpOwoKIGlmIChhbGxvYyAmJiAobHBEb3NUYXNrID0gY2FsbG9jKDEsIHNpemVvZihET1NUQVNLKSkpID09IE5VTEwpIHsKICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogIHJldHVybiBGQUxTRTsKIH0KCiBpZiAoKCFlbnYpJiZwZGIpIGVudiA9IHBkYi0+ZW52X2RiLT5lbnZpcm9uOwogaWYgKGFsbG9jKSB7CiAgaWYgKChoTW9kdWxlID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKGZpbGVuYW1lLCAwKSkgPCAzMikgewogICBTZXRMYXN0RXJyb3IoaE1vZHVsZSk7CiAgIHJldHVybiBGQUxTRTsKICB9CiAgbHBEb3NUYXNrLT5oTW9kdWxlID0gaE1vZHVsZTsKCiAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoaE1vZHVsZSk7CiAgcE1vZHVsZS0+bHBEb3NUYXNrID0gbHBEb3NUYXNrOwogCiAgbHBEb3NUYXNrLT5pbWc9TlVMTDsgbHBEb3NUYXNrLT5tbV9uYW1lWzBdPTA7IGxwRG9zVGFzay0+bW1fZmQ9LTE7CiB9IGVsc2UgbHBEb3NUYXNrPXBNb2R1bGUtPmxwRG9zVGFzazsKIGlmICghTVpfTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIGNtZGxpbmUsIGVudiwgbHBEb3NUYXNrLCBwTW9kdWxlICkpIHsKICBpZiAoYWxsb2MpIHsKICAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgewogICAgaWYgKGxwRG9zVGFzay0+aW1nIT1OVUxMKSBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICAgIGlmIChscERvc1Rhc2stPm1tX2ZkPj0wKSBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKICAgIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICB9IGVsc2UKICAgIGlmIChscERvc1Rhc2stPmltZyE9TlVMTCkgVmlydHVhbEZyZWUobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAsTUVNX1JFTEVBU0UpOwogIH0KICByZXR1cm4gRkFMU0U7CiB9CiBpZiAoYWxsb2MpIHsKICBwTW9kdWxlLT5kb3NfaW1hZ2UgPSBscERvc1Rhc2stPmltZzsKICBpZiAoIU1aX0luaXRUYXNrKCBscERvc1Rhc2sgKSkgewogICBNWl9LaWxsTW9kdWxlKCBscERvc1Rhc2sgKTsKICAgLyogRklYTUU6IGNsZWFudXAgaE1vZHVsZSAqLwogICBTZXRMYXN0RXJyb3IoRVJST1JfR0VOX0ZBSUxVUkUpOwogICByZXR1cm4gRkFMU0U7CiAgfQogIGluaGVyaXQgPSBUUlVFOyAvKiBiYWQgaGFjayBmb3IgaW5oZXJpdGluZyB0aGUgQ3JlYXRlUGlwZS4uLiAqLwogIGlmICghUFJPQ0VTU19DcmVhdGUoIHBNb2R1bGUsIGNtZGxpbmUsIGVudiwgCiAgICAgICAgICAgICAgICAgICAgICAgcHNhLCB0c2EsIGluaGVyaXQsIGZsYWdzLCBzdGFydHVwLCBpbmZvICkpCiAgIHJldHVybiBGQUxTRTsKIH0KIHJldHVybiBUUlVFOwp9Cgp2b2lkIE1aX0tpbGxNb2R1bGUoIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiAgRE9TRVZFTlQgKmV2ZW50LCpwX2V2ZW50OwogIERPU1NZU1RFTSAqc3lzLCpwX3N5czsKCiAgVFJBQ0UoImtpbGxpbmcgRE9TIHRhc2tcbiIpOwogIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICAgIG11bm1hcChscERvc1Rhc2stPmltZywweDExMDAwMC1TVEFSVF9PRkZTRVQpOwogICAgY2xvc2UobHBEb3NUYXNrLT5tbV9mZCk7CiAgfSBlbHNlIFZpcnR1YWxGcmVlKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLE1FTV9SRUxFQVNFKTsKICBjbG9zZShscERvc1Rhc2stPnJlYWRfcGlwZSk7CiAgY2xvc2UobHBEb3NUYXNrLT53cml0ZV9waXBlKTsKICBDbG9zZUhhbmRsZShscERvc1Rhc2stPmhSZWFkUGlwZSk7CiAgQ2xvc2VIYW5kbGUobHBEb3NUYXNrLT5oWFBpcGUpOwogIGtpbGwobHBEb3NUYXNrLT50YXNrLFNJR1RFUk0pOwovKiBmcmVlIG1lbW9yeSBhbGxvY2F0ZWQgZm9yIGV2ZW50cyBhbmQgc3lzdGVtcyAqLwojZGVmaW5lIERGUkVFKHZhcixwdmFyLHN2YXIpIFwKICB2YXIgPSBscERvc1Rhc2stPnN2YXI7IFwKICB3aGlsZSAodmFyKSB7IFwKICAgIGlmICh2YXItPmRhdGEpIGZyZWUodmFyLT5kYXRhKTsgXAogICAgcHZhciA9IHZhci0+bmV4dDsgZnJlZSh2YXIpOyB2YXIgPSBwdmFyOyBcCiAgfQoKICBERlJFRShldmVudCxwX2V2ZW50LHBlbmRpbmcpCiAgREZSRUUoZXZlbnQscF9ldmVudCxjdXJyZW50KQogIERGUkVFKHN5cyxwX3N5cyxzeXMpCgojdW5kZWYgREZSRUUKCiNpZiAwCiAgLyogRklYTUU6IHRoaXMgc2VlbXMgdG8gY3Jhc2ggKi8KICBpZiAobHBEb3NUYXNrLT5kcG1pX3NlbCkKICAgIFNFTEVDVE9SX0ZyZWVCbG9jayhscERvc1Rhc2stPmRwbWlfc2VsLCAxKTsKI2VuZGlmCn0KCkxQRE9TVEFTSyBNWl9DdXJyZW50KCB2b2lkICkKewogIFREQiAqcFRhc2sgPSAoVERCICopR2xvYmFsTG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiAgTkVfTU9EVUxFICpwTW9kdWxlID0gcFRhc2sgPyBORV9HZXRQdHIoIHBUYXNrLT5oTW9kdWxlICkgOiBOVUxMOwoKICBHbG9iYWxVbmxvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwoKICBpZiAocE1vZHVsZSkKICAgIHJldHVybiBwTW9kdWxlLT5scERvc1Rhc2s7CgogIHJldHVybiBOVUxMOwp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgpCT09MIE1aX0NyZWF0ZVByb2Nlc3MoIEhBTkRMRSBoRmlsZSwgTFBDU1RSIGZpbGVuYW1lLCBMUENTVFIgY21kbGluZSwgTFBDU1RSIGVudiwKICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgcHNhLCBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgdHNhLAogICAgICAgICAgICAgICAgICAgICAgIEJPT0wgaW5oZXJpdCwgRFdPUkQgZmxhZ3MsIExQU1RBUlRVUElORk9BIHN0YXJ0dXAsCiAgICAgICAgICAgICAgICAgICAgICAgTFBQUk9DRVNTX0lORk9STUFUSU9OIGluZm8gKQp7CiBXQVJOKCJET1MgZXhlY3V0YWJsZXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZVxuIik7CiBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiByZXR1cm4gRkFMU0U7Cn0KCkxQRE9TVEFTSyBNWl9DdXJyZW50KCB2b2lkICkKewogIHJldHVybiBOVUxMOwp9CgojZW5kaWYK