LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAicGVleGUuaCIKI2luY2x1ZGUgIm5lZXhlLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJzZWxlY3RvcnMuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImxkdC5oIgojaW5jbHVkZSAicHJvY2Vzcy5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAiZG9zbW9kLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCiNpbmNsdWRlICJzZXJ2ZXIuaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTChtb2R1bGUpCgojaWZkZWYgTVpfU1VQUE9SVEVECgojaW5jbHVkZSA8c3lzL21tYW4uaD4KCi8qIGRlZmluZSB0aGlzIHRvIHRyeSBtYXBwaW5nIHRocm91Z2ggL3Byb2MvcGlkL21lbSBpbnN0ZWFkIG9mIGEgdGVtcCBmaWxlLAogICBidXQgTGludXMgZG9lc24ndCBsaWtlIG1tYXBwaW5nIC9wcm9jL3BpZC9tZW0sIHNvIGl0IGRvZXNuJ3Qgd29yayBmb3IgbWUgKi8KI3VuZGVmIE1aX01BUFNFTEYKCiNkZWZpbmUgQklPU19EQVRBX1NFR01FTlQgMHg0MAojZGVmaW5lIFNUQVJUX09GRlNFVCAwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKc3RhdGljIHZvaWQgTVpfSW5pdFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kbGluZSwgV09SRCBlbnYgKQp7CiBQREIxNipwc3A9bHBQU1A7CiBjb25zdCBjaGFyKmNtZD1jbWRsaW5lP3N0cmNocihjbWRsaW5lLCcgJyk6TlVMTDsKCiBwc3AtPmludDIwPTB4MjBDRDsgLyogaW50IDIwICovCiAvKiBzb21lIHByb2dyYW1zIHVzZSB0aGlzIHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgdGhleSBuZWVkICovCiBwc3AtPm5leHRQYXJhZ3JhcGg9MHg5RkZGOwogcHNwLT5lbnZpcm9ubWVudD1lbnY7CiAvKiBjb3B5IHBhcmFtZXRlcnMgKi8KIGlmIChjbWQpIHsKI2lmIDAKICAvKiBjb21tYW5kLmNvbSBkb2Vzbid0IGRvIHRoaXMgKi8KICB3aGlsZSAoKmNtZCA9PSAnICcpIGNtZCsrOwojZW5kaWYKICBwc3AtPmNtZExpbmVbMF09c3RybGVuKGNtZCk7CiAgc3RyY3B5KHBzcC0+Y21kTGluZSsxLGNtZCk7CiAgcHNwLT5jbWRMaW5lW3BzcC0+Y21kTGluZVswXSsxXT0nXHInOwogfSBlbHNlIHBzcC0+Y21kTGluZVsxXT0nXHInOwogLyogRklYTUU6IGludGVncmF0ZSB0aGUgbWVtb3J5IHN0dWZmIGZyb20gV2luZSAobXNkb3MvZG9zbWVtLmMpICovCiAvKiBGSVhNRTogaW50ZWdyYXRlIHRoZSBQREIgc3R1ZmYgZnJvbSBXaW5lIChsb2FkZXIvdGFzay5jKSAqLwp9CgovKiBkZWZhdWx0IElOVCAwOCBoYW5kbGVyOiBpbmNyZWFzZXMgdGltZXIgdGljayBjb3VudGVyIGJ1dCBub3QgbXVjaCBtb3JlICovCnN0YXRpYyBjaGFyIGludDA4W109ewogMHhDRCwweDFDLCAgICAgICAgICAgLyogaW50ICQweDFjICovCiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4MUUsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkcyAqLwogMHhCOCwweDQwLDB4MDAsICAgICAgLyogbW92dyAkMHg0MCwlYXggKi8KIDB4OEUsMHhEOCwgICAgICAgICAgIC8qIG1vdncgJWF4LCVkcyAqLwojaWYgMAogMHg4MywweDA2LDB4NkMsMHgwMCwweDAxLCAvKiBhZGR3ICQxLCgweDZjKSAqLwogMHg4MywweDE2LDB4NkUsMHgwMCwweDAwLCAvKiBhZGN3ICQwLCgweDZlKSAqLwojZWxzZQogMHg2NiwweEZGLDB4MDYsMHg2QywweDAwLCAvKiBpbmNsICgweDZjKSAqLwojZW5kaWYKIDB4QjAsMHgyMCwgICAgICAgICAgIC8qIG1vdmIgJDB4MjAsJWFsICovCiAweEU2LDB4MjAsICAgICAgICAgICAvKiBvdXRiICVhbCwkMHgyMCAqLwogMHgxRiwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENGICAgICAgICAgICAgICAgICAvKiBpcmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0SGFuZGxlcnMoIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBXT1JEIHNlZzsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHNpemVvZihpbnQwOCksJnNlZyk7CiBtZW1jcHkoc3RhcnQsaW50MDgsc2l6ZW9mKGludDA4KSk7Ci8qIElOVCAwODogcG9pbnQgaXQgYXQgb3VyIHRpY2staW5jcmVtZW50aW5nIGhhbmRsZXIgKi8KICgoU0VHUFRSKikobHBEb3NUYXNrLT5pbWcpKVsweDA4XT1QVFJfU0VHX09GRl9UT19TRUdQVFIoc2VnLDApOwovKiBJTlQgMUM6IGp1c3QgcG9pbnQgaXQgdG8gSVJFVCwgd2UgZG9uJ3Qgd2FudCB0byBoYW5kbGUgaXQgb3Vyc2VsdmVzICovCiAoKFNFR1BUUiopKGxwRG9zVGFzay0+aW1nKSlbMHgxQ109UFRSX1NFR19PRkZfVE9fU0VHUFRSKHNlZyxzaXplb2YoaW50MDgpLTEpOwp9CgpzdGF0aWMgY2hhciBlbnRlcl94bXNbXT17Ci8qIFhNUyBob29rYWJsZSBlbnRyeSBwb2ludCAqLwogMHhFQiwweDAzLCAgICAgICAgICAgLyogam1wIGVudHJ5ICovCiAweDkwLDB4OTAsMHg5MCwgICAgICAvKiBub3A7bm9wO25vcCAqLwogICAgICAgICAgICAgICAgICAgICAgLyogZW50cnk6ICovCi8qIHJlYWwgZW50cnkgcG9pbnQgKi8KLyogZm9yIHNpbXBsaWNpdHksIHdlJ2xsIGp1c3QgdXNlIHRoZSBzYW1lIGhvb2sgYXMgRFBNSSBiZWxvdyAqLwogMHhDRCwweDMxLCAgICAgICAgICAgLyogaW50ICQweDMxICovCiAweENCICAgICAgICAgICAgICAgICAvKiBscmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0WE1TKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogTFBCWVRFIHN0YXJ0PURPU01FTV9HZXRCbG9jayhscERvc1Rhc2stPmhNb2R1bGUsc2l6ZW9mKGVudGVyX3htcyksJihscERvc1Rhc2stPnhtc19zZWcpKTsKIG1lbWNweShzdGFydCxlbnRlcl94bXMsc2l6ZW9mKGVudGVyX3htcykpOwp9CgpzdGF0aWMgY2hhciBlbnRlcl9wbVtdPXsKIDB4NTAsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVheCAqLwogMHg1MiwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWR4ICovCiAweDU1LCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYnAgKi8KIDB4ODksMHhFNSwgICAgICAgICAgIC8qIG1vdncgJXNwLCVicCAqLwovKiBnZXQgcmV0dXJuIENTICovCiAweDhCLDB4NTYsMHgwOCwgICAgICAvKiBtb3Z3IDgoJWJwKSwlZHggKi8KLyoganVzdCBjYWxsIGludCAzMSBoZXJlIHRvIGdldCBpbnRvIHByb3RlY3RlZCBtb2RlLi4uICovCi8qIGl0J2xsIGNoZWNrIHdoZXRoZXIgaXQgd2FzIGNhbGxlZCBmcm9tIGRwbWlfc2VnLi4uICovCiAweENELDB4MzEsICAgICAgICAgICAvKiBpbnQgJDB4MzEgKi8KLyogd2UgYXJlIG5vdyBpbiB0aGUgY29udGV4dCBvZiBhIDE2LWJpdCByZWxheSBjYWxsICovCi8qIG5lZWQgdG8gZml4dXAgb3VyIHN0YWNrOwogKiAxNi1iaXQgcmVsYXkgcmV0dXJuIGFkZHJlc3Mgd2lsbCBiZSBsb3N0LCBidXQgd2Ugd29uJ3Qgd29ycnkgcXVpdGUgeWV0ICovCiAweDhFLDB4RDAsICAgICAgICAgICAvKiBtb3Z3ICVheCwlc3MgKi8KIDB4NjYsMHgwRiwweEI3LDB4RTUsIC8qIG1vdnp3bCAlYnAsJWVzcCAqLwovKiBzZXQgcmV0dXJuIENTICovCiAweDg5LDB4NTYsMHgwOCwgICAgICAvKiBtb3Z3ICVkeCw4KCVicCkgKi8KIDB4NUQsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWJwICovCiAweDVBLCAgICAgICAgICAgICAgICAvKiBwb3B3ICVkeCAqLwogMHg1OCwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4Q0IgICAgICAgICAgICAgICAgIC8qIGxyZXQgKi8KfTsKCnN0YXRpYyB2b2lkIE1aX0luaXREUE1JKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogdW5zaWduZWQgc2l6ZT1zaXplb2YoZW50ZXJfcG0pOwogTFBCWVRFIHN0YXJ0PURPU01FTV9HZXRCbG9jayhscERvc1Rhc2stPmhNb2R1bGUsc2l6ZSwmKGxwRG9zVGFzay0+ZHBtaV9zZWcpKTsKIAogbHBEb3NUYXNrLT5kcG1pX3NlbCA9IFNFTEVDVE9SX0FsbG9jQmxvY2soIHN0YXJ0LCBzaXplLCBTRUdNRU5UX0NPREUsIEZBTFNFLCBGQUxTRSApOwoKIG1lbWNweShzdGFydCxlbnRlcl9wbSxzaXplb2YoZW50ZXJfcG0pKTsKfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUERPU1RBU0sgbHBEb3NUYXNrLCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHN6K3NpemVvZihXT1JEKStzdHJsZW4obmFtZSkrMSwmc2VnKTsKIC8qIGZpbGwgaXQgKi8KIGlmIChlbnYpIHsKICBtZW1jcHkoZW52YmxrLGVudixzeik7CiB9IGVsc2UgZW52YmxrWzBdPTA7CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdE1lbW9yeSggTFBET1NUQVNLIGxwRG9zVGFzaywgTkVfTU9EVUxFICpwTW9kdWxlICkKewogaW50IHg7CgogaWYgKGxwRG9zVGFzay0+aW1nX29mcykgcmV0dXJuIFRSVUU7IC8qIGFscmVhZHkgYWxsb2NhdGVkICovCgogLyogYWxsb2NhdGUgMU1CKzY0SyBzaGFyZWQgbWVtb3J5ICovCiBscERvc1Rhc2stPmltZ19vZnM9U1RBUlRfT0ZGU0VUOwojaWZkZWYgTVpfTUFQU0VMRgogbHBEb3NUYXNrLT5pbWc9VmlydHVhbEFsbG9jKE5VTEwsMHgxMTAwMDAsTUVNX0NPTU1JVCxQQUdFX1JFQURXUklURSk7CiAvKiBtYWtlIHN1cmUgbW1hcCBhY2NlcHRzIGl0ICovCiAoKGNoYXIqKWxwRG9zVGFzay0+aW1nKVsweDEwRkZGRl09MDsKI2Vsc2UKIHRtcG5hbShscERvc1Rhc2stPm1tX25hbWUpOwovKiBzdHJjcHkobHBEb3NUYXNrLT5tbV9uYW1lLCIvdG1wL215ZG9zaW1hZ2UiKTsgKi8KIGxwRG9zVGFzay0+bW1fZmQ9b3BlbihscERvc1Rhc2stPm1tX25hbWUsT19SRFdSfE9fQ1JFQVQgLyogfE9fVFJVTkMgKi8sU19JUlVTUnxTX0lXVVNSKTsKIGlmIChscERvc1Rhc2stPm1tX2ZkPDApIEVSUihtb2R1bGUsImZpbGUgJXMgY291bGQgbm90IGJlIG9wZW5lZFxuIixscERvc1Rhc2stPm1tX25hbWUpOwogLyogZXhwYW5kIGZpbGUgdG8gMU1CKzY0SyAqLwogbHNlZWsobHBEb3NUYXNrLT5tbV9mZCwweDExMDAwMC0xLFNFRUtfU0VUKTsKIHg9MDsgd3JpdGUobHBEb3NUYXNrLT5tbV9mZCwmeCwxKTsKIC8qIG1hcCBpdCBpbiAqLwogbHBEb3NUYXNrLT5pbWc9bW1hcChOVUxMLDB4MTEwMDAwLVNUQVJUX09GRlNFVCxQUk9UX1JFQUR8UFJPVF9XUklURSxNQVBfU0hBUkVELGxwRG9zVGFzay0+bW1fZmQsMCk7CiNlbmRpZgogaWYgKGxwRG9zVGFzay0+aW1nPT0oTFBWT0lEKS0xKSB7CiAgRVJSKG1vZHVsZSwiY291bGQgbm90IG1hcCBzaGFyZWQgbWVtb3J5LCBlcnJvcj0lc1xuIixzdHJlcnJvcihlcnJubykpOwogIHJldHVybiBGQUxTRTsKIH0KIFRSQUNFKG1vZHVsZSwiRE9TIFZNODYgaW1hZ2UgbWFwcGVkIGF0ICUwOGx4XG4iLChEV09SRClscERvc1Rhc2stPmltZyk7CiBwTW9kdWxlLT5kb3NfaW1hZ2U9bHBEb3NUYXNrLT5pbWc7CgogLyogaW5pdGlhbGl6ZSB0aGUgbWVtb3J5ICovCiBUUkFDRShtb2R1bGUsIkluaXRpYWxpemluZyBET1MgbWVtb3J5IHN0cnVjdHVyZXNcbiIpOwogRE9TTUVNX0luaXQobHBEb3NUYXNrLT5oTW9kdWxlKTsKIE1aX0luaXRIYW5kbGVycyhscERvc1Rhc2spOwogTVpfSW5pdFhNUyhscERvc1Rhc2spOwogTVpfSW5pdERQTUkobHBEb3NUYXNrKTsKIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBNWl9Mb2FkSW1hZ2UoIEhGSUxFIGhGaWxlLCBPRlNUUlVDVCAqb2ZzLCBMUENTVFIgY21kbGluZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgZW52LCBMUERPU1RBU0sgbHBEb3NUYXNrLCBORV9NT0RVTEUgKnBNb2R1bGUgKQp7CiBJTUFHRV9ET1NfSEVBREVSIG16X2hlYWRlcjsKIERXT1JEIGltYWdlX3N0YXJ0LGltYWdlX3NpemUsbWluX3NpemUsbWF4X3NpemUsYXZhaWw7CiBCWVRFKnBzcF9zdGFydCwqbG9hZF9zdGFydDsKIGludCB4LG9sZF9jb209MDsKIFNFR1BUUiByZWxvYzsKIFdPUkQgZW52X3NlZzsKCiBfbGxzZWVrKGhGaWxlLDAsRklMRV9CRUdJTik7CiBpZiAoKF9scmVhZChoRmlsZSwmbXpfaGVhZGVyLHNpemVvZihtel9oZWFkZXIpKSAhPSBzaXplb2YobXpfaGVhZGVyKSkgfHwKICAgICAobXpfaGVhZGVyLmVfbWFnaWMgIT0gSU1BR0VfRE9TX1NJR05BVFVSRSkpIHsKICBvbGRfY29tPTE7IC8qIGFzc3VtZSAuQ09NIGZpbGUgKi8KICBpbWFnZV9zdGFydD0wOwogIGltYWdlX3NpemU9R2V0RmlsZVNpemUoaEZpbGUsTlVMTCk7CiAgbWluX3NpemU9MHgxMDAwMDsgbWF4X3NpemU9MHgxMDAwMDA7CiAgbXpfaGVhZGVyLmVfY3JsYz0wOwogIG16X2hlYWRlci5lX3NzPTA7IG16X2hlYWRlci5lX3NwPTB4RkZGRTsKICBtel9oZWFkZXIuZV9jcz0wOyBtel9oZWFkZXIuZV9pcD0weDEwMDsKIH0gZWxzZSB7CiAgLyogY2FsY3VsYXRlIGxvYWQgc2l6ZSAqLwogIGltYWdlX3N0YXJ0PW16X2hlYWRlci5lX2NwYXJoZHI8PDQ7CiAgaW1hZ2Vfc2l6ZT1tel9oZWFkZXIuZV9jcDw8OTsgLyogcGFnZXMgYXJlIDUxMiBieXRlcyAqLwogIGlmICgobXpfaGVhZGVyLmVfY2JscCE9MCkmJihtel9oZWFkZXIuZV9jYmxwIT00KSkgaW1hZ2Vfc2l6ZS09NTEyLW16X2hlYWRlci5lX2NibHA7CiAgaW1hZ2Vfc2l6ZS09aW1hZ2Vfc3RhcnQ7CiAgbWluX3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21pbmFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogIG1heF9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9tYXhhbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKIH0KCiBNWl9Jbml0TWVtb3J5KGxwRG9zVGFzayxwTW9kdWxlKTsKCiAvKiBhbGxvY2F0ZSBlbnZpcm9ubWVudCBibG9jayAqLwogZW52X3NlZz1NWl9Jbml0RW52aXJvbm1lbnQobHBEb3NUYXNrLGVudixvZnMtPnN6UGF0aE5hbWUpOwoKIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGV4ZWN1dGFibGUgKi8KIFRSQUNFKG1vZHVsZSwiQWxsb2NhdGluZyBET1MgbWVtb3J5IChtaW49JWxkLCBtYXg9JWxkKVxuIixtaW5fc2l6ZSxtYXhfc2l6ZSk7CiBhdmFpbD1ET1NNRU1fQXZhaWxhYmxlKGxwRG9zVGFzay0+aE1vZHVsZSk7CiBpZiAoYXZhaWw8bWluX3NpemUpIHsKICBFUlIobW9kdWxlLCAiaW5zdWZmaWNpZW50IERPUyBtZW1vcnlcbiIpOwogIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgcmV0dXJuIEZBTFNFOwogfQogaWYgKGF2YWlsPm1heF9zaXplKSBhdmFpbD1tYXhfc2l6ZTsKIHBzcF9zdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLGF2YWlsLCZscERvc1Rhc2stPnBzcF9zZWcpOwogaWYgKCFwc3Bfc3RhcnQpIHsKICBFUlIobW9kdWxlLCAiZXJyb3IgYWxsb2NhdGluZyBET1MgbWVtb3J5XG4iKTsKICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogIHJldHVybiBGQUxTRTsKIH0KIGxwRG9zVGFzay0+bG9hZF9zZWc9bHBEb3NUYXNrLT5wc3Bfc2VnKyhvbGRfY29tPzA6UFNQX1NJWkUpOwogbG9hZF9zdGFydD1wc3Bfc3RhcnQrKFBTUF9TSVpFPDw0KTsKIE1aX0luaXRQU1AocHNwX3N0YXJ0LCBjbWRsaW5lLCBlbnZfc2VnKTsKCiAvKiBsb2FkIGV4ZWN1dGFibGUgaW1hZ2UgKi8KIFRSQUNFKG1vZHVsZSwibG9hZGluZyBET1MgJXMgaW1hZ2UsICUwOGx4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBfbGxzZWVrKGhGaWxlLGltYWdlX3N0YXJ0LEZJTEVfQkVHSU4pOwogaWYgKChfbHJlYWQoaEZpbGUsbG9hZF9zdGFydCxpbWFnZV9zaXplKSkgIT0gaW1hZ2Vfc2l6ZSkgewogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICByZXR1cm4gRkFMU0U7CiB9CgogaWYgKG16X2hlYWRlci5lX2NybGMpIHsKICAvKiBsb2FkIHJlbG9jYXRpb24gdGFibGUgKi8KICBUUkFDRShtb2R1bGUsImxvYWRpbmcgRE9TIEVYRSByZWxvY2F0aW9uIHRhYmxlLCAlZCBlbnRyaWVzXG4iLG16X2hlYWRlci5lX2NybGMpOwogIC8qIEZJWE1FOiBpcyB0aGlzIHRvbyBzbG93IHdpdGhvdXQgcmVhZCBidWZmZXJpbmc/ICovCiAgX2xsc2VlayhoRmlsZSxtel9oZWFkZXIuZV9sZmFybGMsRklMRV9CRUdJTik7CiAgZm9yICh4PTA7IHg8bXpfaGVhZGVyLmVfY3JsYzsgeCsrKSB7CiAgIGlmIChfbHJlYWQoaEZpbGUsJnJlbG9jLHNpemVvZihyZWxvYykpICE9IHNpemVvZihyZWxvYykpIHsKICAgIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICAgIHJldHVybiBGQUxTRTsKICAgfQogICAqKFdPUkQqKVNFR1BUUjE2KGxvYWRfc3RhcnQscmVsb2MpKz1scERvc1Rhc2stPmxvYWRfc2VnOwogIH0KIH0KCiBscERvc1Rhc2stPmluaXRfY3M9bHBEb3NUYXNrLT5sb2FkX3NlZyttel9oZWFkZXIuZV9jczsKIGxwRG9zVGFzay0+aW5pdF9pcD1tel9oZWFkZXIuZV9pcDsKIGxwRG9zVGFzay0+aW5pdF9zcz1scERvc1Rhc2stPmxvYWRfc2VnK216X2hlYWRlci5lX3NzOwogbHBEb3NUYXNrLT5pbml0X3NwPW16X2hlYWRlci5lX3NwOwoKIFRSQUNFKG1vZHVsZSwiZW50cnkgcG9pbnQ6ICUwNHg6JTA0eFxuIixscERvc1Rhc2stPmluaXRfY3MsbHBEb3NUYXNrLT5pbml0X2lwKTsKIHJldHVybiBUUlVFOwp9CgpMUERPU1RBU0sgTVpfQWxsb2NEUE1JVGFzayggSE1PRFVMRTE2IGhNb2R1bGUgKQp7CiBMUERPU1RBU0sgbHBEb3NUYXNrID0gY2FsbG9jKDEsIHNpemVvZihET1NUQVNLKSk7CiBORV9NT0RVTEUgKnBNb2R1bGU7CgogaWYgKGxwRG9zVGFzaykgewogIGxwRG9zVGFzay0+aE1vZHVsZSA9IGhNb2R1bGU7CgogIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KGhNb2R1bGUpOwogIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKIAogIGxwRG9zVGFzay0+aW1nPU5VTEw7IGxwRG9zVGFzay0+bW1fbmFtZVswXT0wOyBscERvc1Rhc2stPm1tX2ZkPS0xOwoKICBNWl9Jbml0TWVtb3J5KGxwRG9zVGFzaywgcE1vZHVsZSk7CgogIEdsb2JhbFVubG9jazE2KGhNb2R1bGUpOwogfQogcmV0dXJuIGxwRG9zVGFzazsKfQoKc3RhdGljIHZvaWQgTVpfSW5pdFRpbWVyKCBMUERPU1RBU0sgbHBEb3NUYXNrLCBpbnQgdmVyICkKewogaWYgKHZlcjwxKSB7CiAgLyogY2FuJ3QgbWFrZSB0aW1lciB0aWNrcyAqLwogfSBlbHNlIHsKICBpbnQgZnVuYzsKICBzdHJ1Y3QgdGltZXZhbCB0aW07CgogIC8qIHN0YXJ0IGRvc21vZCB0aW1lciBhdCA1NUh6ICovCiAgZnVuYz1ET1NNT0RfU0VUX1RJTUVSOwogIHRpbS50dl9zZWM9MDsgdGltLnR2X3VzZWM9NTQ5MjU7CiAgd3JpdGUobHBEb3NUYXNrLT53cml0ZV9waXBlLCZmdW5jLHNpemVvZihmdW5jKSk7CiAgd3JpdGUobHBEb3NUYXNrLT53cml0ZV9waXBlLCZ0aW0sc2l6ZW9mKHRpbSkpOwogfQp9CgpCT09MIE1aX0luaXRUYXNrKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogIGludCB3cml0ZV9mZFsyXSx4X2ZkOwogIHBpZF90IGNoaWxkOwogIGNoYXIgKmZuYW1lLCpmYXJnLGFyZ1sxNl0sZnByb2NbNjRdLHBhdGhbMjU2XSwqZnBhdGg7CiAgU0VDVVJJVFlfQVRUUklCVVRFUyBhdHRyPXtzaXplb2YoYXR0ciksTlVMTCxUUlVFfTsKICBzdHJ1Y3QgZ2V0X3JlYWRfZmRfcmVxdWVzdCByX3JlcTsKICBzdHJ1Y3QgZ2V0X3dyaXRlX2ZkX3JlcXVlc3Qgd19yZXE7CgogIGlmICghbHBEb3NUYXNrKSByZXR1cm4gRkFMU0U7CiAgLyogY3JlYXRlIHBpcGVzICovCiAgLyogdGhpcyBoYXBwZW5zIGluIHRoZSB3cm9uZyBwcm9jZXNzIGNvbnRleHQsIHNvIHdlIGhhdmUgdG8gbGV0IHRoZSBuZXcgcHJvY2VzcwogICAgIGluaGVyaXQgaXQuLi4gKEZJWE1FOiBjYWxsIE1aX0luaXRUYXNrIGluIHRoZSByaWdodCBwcm9jZXNzIGNvbnRleHQpICovCiAgaWYgKCFDcmVhdGVQaXBlKCYobHBEb3NUYXNrLT5oUmVhZFBpcGUpLCYobHBEb3NUYXNrLT5oWFBpcGUpLCZhdHRyLDApKSByZXR1cm4gRkFMU0U7CiAgaWYgKHBpcGUod3JpdGVfZmQpPDApIHsKICAgIENsb3NlSGFuZGxlKGxwRG9zVGFzay0+aFJlYWRQaXBlKTsKICAgIENsb3NlSGFuZGxlKGxwRG9zVGFzay0+aFhQaXBlKTsKICAgIHJldHVybiBGQUxTRTsKICB9CiAgcl9yZXEuaGFuZGxlID0gbHBEb3NUYXNrLT5oUmVhZFBpcGU7CiAgQ0xJRU5UX1NlbmRSZXF1ZXN0KCBSRVFfR0VUX1JFQURfRkQsIC0xLCAxLCAmcl9yZXEsIHNpemVvZihyX3JlcSkgKTsKICBDTElFTlRfV2FpdFJlcGx5KCBOVUxMLCAmKGxwRG9zVGFzay0+cmVhZF9waXBlKSwgMCApOwogIHdfcmVxLmhhbmRsZSA9IGxwRG9zVGFzay0+aFhQaXBlOwogIENMSUVOVF9TZW5kUmVxdWVzdCggUkVRX0dFVF9XUklURV9GRCwgLTEsIDEsICZ3X3JlcSwgc2l6ZW9mKHdfcmVxKSApOwogIENMSUVOVF9XYWl0UmVwbHkoIE5VTEwsICZ4X2ZkLCAwICk7CgogIFRSQUNFKG1vZHVsZSwid2luMzIgcGlwZTogcmVhZD0lZCwgd3JpdGU9JWQsIHVuaXggcGlwZTogcmVhZD0lZCwgd3JpdGU9JWRcbiIsCgkgICAgICAgbHBEb3NUYXNrLT5oUmVhZFBpcGUsbHBEb3NUYXNrLT5oWFBpcGUsbHBEb3NUYXNrLT5yZWFkX3BpcGUseF9mZCk7CiAgVFJBQ0UobW9kdWxlLCJvdXRib3VuZCB1bml4IHBpcGU6IHJlYWQ9JWQsIHdyaXRlPSVkLCBwaWQ9JWRcbiIsd3JpdGVfZmRbMF0sd3JpdGVfZmRbMV0sZ2V0cGlkKCkpOwoKICBscERvc1Rhc2stPndyaXRlX3BpcGU9d3JpdGVfZmRbMV07CgogLyogaWYgd2UgaGF2ZSBhIG1hcHBpbmcgZmlsZSwgdXNlIGl0ICovCiBmbmFtZT1scERvc1Rhc2stPm1tX25hbWU7IGZhcmc9TlVMTDsKIGlmICghZm5hbWVbMF0pIHsKICAvKiBvdGhlcndpc2UsIG1hcCBvdXIgb3duIG1lbW9yeSBpbWFnZSAqLwogIHNwcmludGYoZnByb2MsIi9wcm9jLyVkL21lbSIsZ2V0cGlkKCkpOwogIHNwcmludGYoYXJnLCIlbGQiLCh1bnNpZ25lZCBsb25nKWxwRG9zVGFzay0+aW1nKTsKICBmbmFtZT1mcHJvYzsgZmFyZz1hcmc7CiB9CgogIFRSQUNFKG1vZHVsZSwiTG9hZGluZyBET1MgVk0gc3VwcG9ydCBtb2R1bGUgKGhtb2R1bGU9JTA0eClcbiIsbHBEb3NUYXNrLT5oTW9kdWxlKTsKICBpZiAoKGNoaWxkPWZvcmsoKSk8MCkgewogICAgY2xvc2Uod3JpdGVfZmRbMF0pOwogICAgY2xvc2UobHBEb3NUYXNrLT5yZWFkX3BpcGUpOwogICAgY2xvc2UobHBEb3NUYXNrLT53cml0ZV9waXBlKTsKICAgIGNsb3NlKHhfZmQpOwogICAgQ2xvc2VIYW5kbGUobHBEb3NUYXNrLT5oUmVhZFBpcGUpOwogICAgQ2xvc2VIYW5kbGUobHBEb3NUYXNrLT5oWFBpcGUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KIGlmIChjaGlsZCE9MCkgewogIC8qIHBhcmVudCBwcm9jZXNzICovCiAgaW50IHJldDsKCiAgY2xvc2Uod3JpdGVfZmRbMF0pOwogIGNsb3NlKHhfZmQpOwogIGxwRG9zVGFzay0+dGFzaz1jaGlsZDsKICAvKiB3YWl0IGZvciBjaGlsZCBwcm9jZXNzIHRvIHNpZ25hbCByZWFkaW5lc3MgKi8KICBkbyB7CiAgIGlmIChyZWFkKGxwRG9zVGFzay0+cmVhZF9waXBlLCZyZXQsc2l6ZW9mKHJldCkpIT1zaXplb2YocmV0KSkgewogICAgaWYgKChlcnJubz09RUlOVFIpfHwoZXJybm89PUVBR0FJTikpIGNvbnRpbnVlOwogICAgLyogZmFpbHVyZSAqLwogICAgRVJSKG1vZHVsZSwiZG9zbW9kIGhhcyBmYWlsZWQgdG8gaW5pdGlhbGl6ZVxuIik7CiAgICBpZiAobHBEb3NUYXNrLT5tbV9uYW1lWzBdIT0wKSB1bmxpbmsobHBEb3NUYXNrLT5tbV9uYW1lKTsKICAgIHJldHVybiBGQUxTRTsKICAgfQogIH0gd2hpbGUgKDApOwogIC8qIHRoZSBjaGlsZCBoYXMgbm93IG1tYXBlZCB0aGUgdGVtcCBmaWxlLCBpdCdzIG5vdyBzYWZlIHRvIHVubGluay4KICAgKiBkbyBpdCBoZXJlIHRvIGF2b2lkIGxlYXZpbmcgYSBtZXNzIGluIC90bXAgaWYvd2hlbiBXaW5lIGNyYXNoZXMuLi4gKi8KICBpZiAobHBEb3NUYXNrLT5tbV9uYW1lWzBdIT0wKSB1bmxpbmsobHBEb3NUYXNrLT5tbV9uYW1lKTsKICAvKiBzdGFydCBzaW11bGF0ZWQgc3lzdGVtIHRpbWVyICovCiAgTVpfSW5pdFRpbWVyKGxwRG9zVGFzayxyZXQpOwogIGlmIChyZXQ8MikgewogICAgRVJSKG1vZHVsZSwiZG9zbW9kIHZlcnNpb24gdG9vIG9sZCEgUGxlYXNlIGluc3RhbGwgbmV3ZXIgZG9zbW9kIHByb3Blcmx5XG4iKTsKICAgIEVSUihtb2R1bGUsIklmIHlvdSBkb24ndCwgdGhlIG5ldyBkb3Ntb2QgZXZlbnQgaGFuZGxpbmcgc3lzdGVtIHdpbGwgbm90IHdvcmtcbiIpOwogIH0KICAvKiBhbGwgc3lzdGVtcyBhcmUgbm93IGdvICovCiB9IGVsc2UgewogIC8qIGNoaWxkIHByb2Nlc3MgKi8KICBjbG9zZShscERvc1Rhc2stPnJlYWRfcGlwZSk7CiAgY2xvc2UobHBEb3NUYXNrLT53cml0ZV9waXBlKTsKICAvKiBwdXQgb3VyIHBpcGVzIHNvbWV3aGVyZSBkb3Ntb2QgY2FuIGZpbmQgdGhlbSAqLwogIGR1cDIod3JpdGVfZmRbMF0sMCk7IC8qIHN0ZGluICovCiAgZHVwMih4X2ZkLDEpOyAgICAgICAgLyogc3Rkb3V0ICovCiAgLyogZW5hYmxlIHNpZ25hbHMgKi8KICBTSUdOQUxfTWFza0FzeW5jRXZlbnRzKEZBTFNFKTsKICAvKiBub3cgbG9hZCBkb3Ntb2QgKi8KICAvKiBjaGVjayBhcmd2WzBdLWRlcml2ZWQgcGF0aHMgZmlyc3QsIHNpbmNlIHRoZSBuZXdlc3QgZG9zbW9kIGlzIG1vc3QgbGlrZWx5IHRoZXJlCiAgICogKGF0IGxlYXN0IGl0IHdhcyBvbmNlIGZvciBBbmRyZWFzIE1vaHIsIHNvIEkgZGVjaWRlZCB0byBtYWtlIGl0IGVhc2llciBmb3IgaGltKSAqLwogIGZwYXRoPXN0cnJjaHIoc3RyY3B5KHBhdGgsT3B0aW9ucy5hcmd2MCksJy8nKTsKICBpZiAoZnBhdGgpIHsKICAgc3RyY3B5KGZwYXRoLCIvZG9zbW9kIik7CiAgIGV4ZWNsKHBhdGgsZm5hbWUsZmFyZyxOVUxMKTsKICAgc3RyY3B5KGZwYXRoLCIvbG9hZGVyL2Rvcy9kb3Ntb2QiKTsKICAgZXhlY2wocGF0aCxmbmFtZSxmYXJnLE5VTEwpOwogIH0KICAvKiBva2F5LCBpdCB3YXNuJ3QgdGhlcmUsIHRyeSBpbiB0aGUgcGF0aCAqLwogIGV4ZWNscCgiZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIC8qIGxhc3QgZGVzcGVyYXRlIGF0dGVtcHRzOiBjdXJyZW50IGRpcmVjdG9yeSAqLwogIGV4ZWNsKCJkb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgLyogYW5kLCBqdXN0IGZvciBjb21wbGV0ZW5lc3MuLi4gKi8KICBleGVjbCgibG9hZGVyL2Rvcy9kb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgLyogaWYgZmFpbHVyZSwgZXhpdCAqLwogIEVSUihtb2R1bGUsIkZhaWxlZCB0byBzcGF3biBkb3Ntb2QsIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgZXhpdCgxKTsKIH0KIHJldHVybiBUUlVFOwp9CgpCT09MIE1aX0NyZWF0ZVByb2Nlc3MoIEhGSUxFIGhGaWxlLCBPRlNUUlVDVCAqb2ZzLCBMUENTVFIgY21kbGluZSwgTFBDU1RSIGVudiwgCiAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIHBzYSwgTFBTRUNVUklUWV9BVFRSSUJVVEVTIHRzYSwKICAgICAgICAgICAgICAgICAgICAgICBCT09MIGluaGVyaXQsIExQU1RBUlRVUElORk9BIHN0YXJ0dXAsIAogICAgICAgICAgICAgICAgICAgICAgIExQUFJPQ0VTU19JTkZPUk1BVElPTiBpbmZvICkKewogTFBET1NUQVNLIGxwRG9zVGFzayA9IE5VTEw7IC8qIGtlZXAgZ2NjIGZyb20gY29tcGxhaW5pbmcgKi8KIEhNT0RVTEUxNiBoTW9kdWxlOwogUERCICpwZGIgPSBQUk9DRVNTX0N1cnJlbnQoKTsKIFREQiAqcFRhc2sgPSAoVERCKilHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKIE5FX01PRFVMRSAqcE1vZHVsZSA9IHBUYXNrID8gTkVfR2V0UHRyKCBwVGFzay0+aE1vZHVsZSApIDogTlVMTDsKIGludCBhbGxvYyA9ICEocE1vZHVsZSAmJiBwTW9kdWxlLT5kb3NfaW1hZ2UpOwoKIGlmIChhbGxvYyAmJiAobHBEb3NUYXNrID0gY2FsbG9jKDEsIHNpemVvZihET1NUQVNLKSkpID09IE5VTEwpIHsKICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogIHJldHVybiBGQUxTRTsKIH0KCiBpZiAoKCFlbnYpJiZwZGIpIGVudiA9IHBkYi0+ZW52X2RiLT5lbnZpcm9uOwogaWYgKGFsbG9jKSB7CiAgaWYgKChoTW9kdWxlID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKG9mcywgTlVMTCkpIDwgMzIpIHsKICAgU2V0TGFzdEVycm9yKGhNb2R1bGUpOwogICByZXR1cm4gRkFMU0U7CiAgfQogIGxwRG9zVGFzay0+aE1vZHVsZSA9IGhNb2R1bGU7CgogIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KGhNb2R1bGUpOwogIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKIAogIGxwRG9zVGFzay0+aW1nPU5VTEw7IGxwRG9zVGFzay0+bW1fbmFtZVswXT0wOyBscERvc1Rhc2stPm1tX2ZkPS0xOwogfSBlbHNlIGxwRG9zVGFzaz1wTW9kdWxlLT5scERvc1Rhc2s7CiBpZiAoIU1aX0xvYWRJbWFnZSggaEZpbGUsIG9mcywgY21kbGluZSwgZW52LCBscERvc1Rhc2ssIHBNb2R1bGUgKSkgewogIGlmIChhbGxvYykgewogICBpZiAobHBEb3NUYXNrLT5tbV9uYW1lWzBdIT0wKSB7CiAgICBpZiAobHBEb3NUYXNrLT5pbWchPU5VTEwpIG11bm1hcChscERvc1Rhc2stPmltZywweDExMDAwMC1TVEFSVF9PRkZTRVQpOwogICAgaWYgKGxwRG9zVGFzay0+bW1fZmQ+PTApIGNsb3NlKGxwRG9zVGFzay0+bW1fZmQpOwogICAgdW5saW5rKGxwRG9zVGFzay0+bW1fbmFtZSk7CiAgIH0gZWxzZQogICAgaWYgKGxwRG9zVGFzay0+aW1nIT1OVUxMKSBWaXJ0dWFsRnJlZShscERvc1Rhc2stPmltZywweDExMDAwMCxNRU1fUkVMRUFTRSk7CiAgfQogIHJldHVybiBGQUxTRTsKIH0KIGlmIChhbGxvYykgewogIHBNb2R1bGUtPmRvc19pbWFnZSA9IGxwRG9zVGFzay0+aW1nOwogIGlmICghTVpfSW5pdFRhc2soIGxwRG9zVGFzayApKSB7CiAgIE1aX0tpbGxNb2R1bGUoIGxwRG9zVGFzayApOwogICAvKiBGSVhNRTogY2xlYW51cCBoTW9kdWxlICovCiAgIFNldExhc3RFcnJvcihFUlJPUl9HRU5fRkFJTFVSRSk7CiAgIHJldHVybiBGQUxTRTsKICB9CiAgaW5oZXJpdCA9IFRSVUU7IC8qIGJhZCBoYWNrIGZvciBpbmhlcml0aW5nIHRoZSBDcmVhdGVQaXBlLi4uICovCiAgaWYgKCFQUk9DRVNTX0NyZWF0ZSggcE1vZHVsZSwgY21kbGluZSwgZW52LCAwLCAwLCAKICAgICAgICAgICAgICAgICAgICAgICBwc2EsIHRzYSwgaW5oZXJpdCwgc3RhcnR1cCwgaW5mbyApKQogICByZXR1cm4gRkFMU0U7CiB9CiByZXR1cm4gVFJVRTsKfQoKdm9pZCBNWl9LaWxsTW9kdWxlKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogIERPU0VWRU5UICpldmVudCwqcF9ldmVudDsKICBET1NTWVNURU0gKnN5cywqcF9zeXM7CgogIFRSQUNFKG1vZHVsZSwia2lsbGluZyBET1MgdGFza1xuIik7CiAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgewogICAgbXVubWFwKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLVNUQVJUX09GRlNFVCk7CiAgICBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKICB9IGVsc2UgVmlydHVhbEZyZWUobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAsTUVNX1JFTEVBU0UpOwogIGNsb3NlKGxwRG9zVGFzay0+cmVhZF9waXBlKTsKICBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwogIENsb3NlSGFuZGxlKGxwRG9zVGFzay0+aFJlYWRQaXBlKTsKICBDbG9zZUhhbmRsZShscERvc1Rhc2stPmhYUGlwZSk7CiAga2lsbChscERvc1Rhc2stPnRhc2ssU0lHVEVSTSk7Ci8qIGZyZWUgbWVtb3J5IGFsbG9jYXRlZCBmb3IgZXZlbnRzIGFuZCBzeXN0ZW1zICovCiNkZWZpbmUgREZSRUUodmFyLHB2YXIsc3ZhcikgXAogIHZhciA9IGxwRG9zVGFzay0+c3ZhcjsgXAogIHdoaWxlICh2YXIpIHsgXAogICAgaWYgKHZhci0+ZGF0YSkgZnJlZSh2YXItPmRhdGEpOyBcCiAgICBwdmFyID0gdmFyLT5uZXh0OyBmcmVlKHZhcik7IHZhciA9IHB2YXI7IFwKICB9CgogIERGUkVFKGV2ZW50LHBfZXZlbnQscGVuZGluZykKICBERlJFRShldmVudCxwX2V2ZW50LGN1cnJlbnQpCiAgREZSRUUoc3lzLHBfc3lzLHN5cykKCiN1bmRlZiBERlJFRQoKI2lmIDAKIC8qIEZJWE1FOiB0aGlzIHNlZW1zIHRvIGNyYXNoICovCiBpZiAobHBEb3NUYXNrLT5kcG1pX3NlbCkKICBVbk1hcExTKFBUUl9TRUdfT0ZGX1RPX1NFR1BUUihscERvc1Rhc2stPmRwbWlfc2VsLDApKTsKI2VuZGlmCn0KCiNlbHNlIC8qICFNWl9TVVBQT1JURUQgKi8KCkJPT0wgTVpfQ3JlYXRlUHJvY2VzcyggSEZJTEUgaEZpbGUsIE9GU1RSVUNUICpvZnMsIExQQ1NUUiBjbWRsaW5lLCBMUENTVFIgZW52LCAKICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgcHNhLCBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgdHNhLAogICAgICAgICAgICAgICAgICAgICAgIEJPT0wgaW5oZXJpdCwgTFBTVEFSVFVQSU5GT0Egc3RhcnR1cCwgCiAgICAgICAgICAgICAgICAgICAgICAgTFBQUk9DRVNTX0lORk9STUFUSU9OIGluZm8gKQp7CiBXQVJOKG1vZHVsZSwiRE9TIGV4ZWN1dGFibGVzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBhcmNoaXRlY3R1cmVcbiIpOwogU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogcmV0dXJuIEZBTFNFOwp9CgojZW5kaWYK