LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgInNlbGVjdG9ycy5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCgojaWZkZWYgTVpfU1VQUE9SVEVECgojaW5jbHVkZSA8c3lzL21tYW4uaD4KCi8qIGRlZmluZSB0aGlzIHRvIHRyeSBtYXBwaW5nIHRocm91Z2ggL3Byb2MvcGlkL21lbSBpbnN0ZWFkIG9mIGEgdGVtcCBmaWxlLAogICBidXQgTGludXMgZG9lc24ndCBsaWtlIG1tYXBwaW5nIC9wcm9jL3BpZC9tZW0sIHNvIGl0IGRvZXNuJ3Qgd29yayBmb3IgbWUgKi8KI3VuZGVmIE1aX01BUFNFTEYKCiNkZWZpbmUgQklPU19EQVRBX1NFR01FTlQgMHg0MAojZGVmaW5lIFNUQVJUX09GRlNFVCAwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKc3RhdGljIHZvaWQgTVpfSW5pdFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kbGluZSwgV09SRCBlbnYgKQp7CiBQREIqcHNwPWxwUFNQOwogY29uc3QgY2hhcipjbWQ9Y21kbGluZT9zdHJjaHIoY21kbGluZSwnICcpOk5VTEw7CgogcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogLyogc29tZSBwcm9ncmFtcyB1c2UgdGhpcyB0byBjYWxjdWxhdGUgaG93IG11Y2ggbWVtb3J5IHRoZXkgbmVlZCAqLwogcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsKIHBzcC0+ZW52aXJvbm1lbnQ9ZW52OwogLyogY29weSBwYXJhbWV0ZXJzICovCiBpZiAoY21kKSB7CiNpZiAwCiAgLyogY29tbWFuZC5jb20gZG9lc24ndCBkbyB0aGlzICovCiAgd2hpbGUgKCpjbWQgPT0gJyAnKSBjbWQrKzsKI2VuZGlmCiAgcHNwLT5jbWRMaW5lWzBdPXN0cmxlbihjbWQpOwogIHN0cmNweShwc3AtPmNtZExpbmUrMSxjbWQpOwogIHBzcC0+Y21kTGluZVtwc3AtPmNtZExpbmVbMF0rMV09J1xyJzsKIH0gZWxzZSBwc3AtPmNtZExpbmVbMV09J1xyJzsKIC8qIEZJWE1FOiBpbnRlZ3JhdGUgdGhlIG1lbW9yeSBzdHVmZiBmcm9tIFdpbmUgKG1zZG9zL2Rvc21lbS5jKSAqLwogLyogRklYTUU6IGludGVncmF0ZSB0aGUgUERCIHN0dWZmIGZyb20gV2luZSAobG9hZGVyL3Rhc2suYykgKi8KfQoKc3RhdGljIGNoYXIgZW50ZXJfeG1zW109ewovKiBYTVMgaG9va2FibGUgZW50cnkgcG9pbnQgKi8KIDB4RUIsMHgwMywgICAgICAvKiBqbXAgZW50cnkgKi8KIDB4OTAsMHg5MCwweDkwLCAvKiBub3A7bm9wO25vcCAqLwogICAgICAgICAgICAgICAgIC8qIGVudHJ5OiAqLwovKiByZWFsIGVudHJ5IHBvaW50ICovCi8qIGZvciBzaW1wbGljaXR5LCB3ZSdsbCBqdXN0IHVzZSB0aGUgc2FtZSBob29rIGFzIERQTUkgYmVsb3cgKi8KIDB4Q0QsMHgzMSwgICAgICAvKiBpbnQgMHgzMSAqLwogMHhDQiAgICAgICAgICAgIC8qIHJldGYgKi8KfTsKCnN0YXRpYyB2b2lkIE1aX0luaXRYTVMoIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxzaXplb2YoZW50ZXJfeG1zKSwmKGxwRG9zVGFzay0+eG1zX3NlZykpOwogbWVtY3B5KHN0YXJ0LGVudGVyX3htcyxzaXplb2YoZW50ZXJfeG1zKSk7Cn0KCnN0YXRpYyBjaGFyIGVudGVyX3BtW109ewogMHg1MCwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWF4ICovCiAweDUyLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlZHggKi8KIDB4NTUsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVicCAqLwogMHg4OSwweEU1LCAgICAgICAgICAgLyogbW92dyAlc3AsJWJwICovCi8qIGdldCByZXR1cm4gQ1MgKi8KIDB4OEIsMHg1NiwweDA4LCAgICAgIC8qIG1vdncgOCglYnApLCVkeCAqLwovKiBqdXN0IGNhbGwgaW50IDMxIGhlcmUgdG8gZ2V0IGludG8gcHJvdGVjdGVkIG1vZGUuLi4gKi8KLyogaXQnbGwgY2hlY2sgd2hldGhlciBpdCB3YXMgY2FsbGVkIGZyb20gZHBtaV9zZWcuLi4gKi8KIDB4Q0QsMHgzMSwgICAgICAgICAgIC8qIGludCAweDMxICovCi8qIHdlIGFyZSBub3cgaW4gdGhlIGNvbnRleHQgb2YgYSAxNi1iaXQgcmVsYXkgY2FsbCAqLwovKiBuZWVkIHRvIGZpeHVwIG91ciBzdGFjazsKICogMTYtYml0IHJlbGF5IHJldHVybiBhZGRyZXNzIHdpbGwgYmUgbG9zdCwgYnV0IHdlIHdvbid0IHdvcnJ5IHF1aXRlIHlldCAqLwogMHg4RSwweEQwLCAgICAgICAgICAgLyogbW92dyAlYXgsJXNzICovCiAweDY2LDB4MEYsMHhCNywweEU1LCAvKiBtb3Z6d2wgJWJwLCVlc3AgKi8KLyogc2V0IHJldHVybiBDUyAqLwogMHg4OSwweDU2LDB4MDgsICAgICAgLyogbW92dyAlZHgsOCglYnApICovCiAweDVELCAgICAgICAgICAgICAgICAvKiBwb3B3ICVicCAqLwogMHg1QSwgICAgICAgICAgICAgICAgLyogcG9wdyAlZHggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENCICAgICAgICAgICAgICAgICAvKiByZXRmICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0RFBNSSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHNpemVvZihlbnRlcl9wbSksJihscERvc1Rhc2stPmRwbWlfc2VnKSk7CiAKIGxwRG9zVGFzay0+ZHBtaV9zZWwgPSBTRUxFQ1RPUl9BbGxvY0Jsb2NrKCBzdGFydCwgc2l6ZW9mKGVudGVyX3BtKSwgU0VHTUVOVF9DT0RFLCBGQUxTRSwgRkFMU0UgKTsKCiBtZW1jcHkoc3RhcnQsZW50ZXJfcG0sc2l6ZW9mKGVudGVyX3BtKSk7Cn0KCnN0YXRpYyBXT1JEIE1aX0luaXRFbnZpcm9ubWVudCggTFBET1NUQVNLIGxwRG9zVGFzaywgTFBDU1RSIGVudiwgTFBDU1RSIG5hbWUgKQp7CiB1bnNpZ25lZCBzej0wOwogV09SRCBzZWc7CiBMUFNUUiBlbnZibGs7CgogaWYgKGVudikgewogIC8qIGdldCBzaXplIG9mIGVudmlyb25tZW50IGJsb2NrICovCiAgd2hpbGUgKGVudltzeisrXSkgc3orPXN0cmxlbihlbnYrc3opOwogfSBlbHNlIHN6Kys7CiAvKiBhbGxvY2F0ZSBpdCAqLwogZW52YmxrPURPU01FTV9HZXRCbG9jayhscERvc1Rhc2stPmhNb2R1bGUsc3orc2l6ZW9mKFdPUkQpK3N0cmxlbihuYW1lKSsxLCZzZWcpOwogLyogZmlsbCBpdCAqLwogaWYgKGVudikgewogIG1lbWNweShlbnZibGssZW52LHN6KTsKIH0gZWxzZSBlbnZibGtbMF09MDsKIC8qIERPUyAzLng6IHRoZSBibG9jayBjb250YWlucyAxIGFkZGl0aW9uYWwgc3RyaW5nICovCiAqKFdPUkQqKShlbnZibGsrc3opPTE7CiAvKiBiZWluZyB0aGUgcHJvZ3JhbSBuYW1lIGl0c2VsZiAqLwogc3RyY3B5KGVudmJsaytzeitzaXplb2YoV09SRCksbmFtZSk7CiByZXR1cm4gc2VnOwp9CgppbnQgTVpfSW5pdE1lbW9yeSggTFBET1NUQVNLIGxwRG9zVGFzaywgTkVfTU9EVUxFICpwTW9kdWxlICkKewogaW50IHg7CgogaWYgKGxwRG9zVGFzay0+aW1nX29mcykgcmV0dXJuIDMyOyAvKiBhbHJlYWR5IGFsbG9jYXRlZCAqLwoKIC8qIGFsbG9jYXRlIDFNQis2NEsgc2hhcmVkIG1lbW9yeSAqLwogbHBEb3NUYXNrLT5pbWdfb2ZzPVNUQVJUX09GRlNFVDsKI2lmZGVmIE1aX01BUFNFTEYKIGxwRG9zVGFzay0+aW1nPVZpcnR1YWxBbGxvYyhOVUxMLDB4MTEwMDAwLE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwogLyogbWFrZSBzdXJlIG1tYXAgYWNjZXB0cyBpdCAqLwogKChjaGFyKilscERvc1Rhc2stPmltZylbMHgxMEZGRkZdPTA7CiNlbHNlCiB0bXBuYW0obHBEb3NUYXNrLT5tbV9uYW1lKTsKLyogc3RyY3B5KGxwRG9zVGFzay0+bW1fbmFtZSwiL3RtcC9teWRvc2ltYWdlIik7ICovCiBscERvc1Rhc2stPm1tX2ZkPW9wZW4obHBEb3NUYXNrLT5tbV9uYW1lLE9fUkRXUnxPX0NSRUFUIC8qIHxPX1RSVU5DICovLFNfSVJVU1J8U19JV1VTUik7CiBpZiAobHBEb3NUYXNrLT5tbV9mZDwwKSBFUlIobW9kdWxlLCJmaWxlICVzIGNvdWxkIG5vdCBiZSBvcGVuZWRcbiIsbHBEb3NUYXNrLT5tbV9uYW1lKTsKIC8qIGV4cGFuZCBmaWxlIHRvIDFNQis2NEsgKi8KIGxzZWVrKGxwRG9zVGFzay0+bW1fZmQsMHgxMTAwMDAtMSxTRUVLX1NFVCk7CiB4PTA7IHdyaXRlKGxwRG9zVGFzay0+bW1fZmQsJngsMSk7CiAvKiBtYXAgaXQgaW4gKi8KIGxwRG9zVGFzay0+aW1nPW1tYXAoTlVMTCwweDExMDAwMC1TVEFSVF9PRkZTRVQsUFJPVF9SRUFEfFBST1RfV1JJVEUsTUFQX1NIQVJFRCxscERvc1Rhc2stPm1tX2ZkLDApOwojZW5kaWYKIGlmIChscERvc1Rhc2stPmltZz09KExQVk9JRCktMSkgewogIEVSUihtb2R1bGUsImNvdWxkIG5vdCBtYXAgc2hhcmVkIG1lbW9yeSwgZXJyb3I9JXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICByZXR1cm4gMDsKIH0KIFRSQUNFKG1vZHVsZSwiRE9TIFZNODYgaW1hZ2UgbWFwcGVkIGF0ICUwOGx4XG4iLChEV09SRClscERvc1Rhc2stPmltZyk7CiBwTW9kdWxlLT5kb3NfaW1hZ2U9bHBEb3NUYXNrLT5pbWc7CgogLyogaW5pdGlhbGl6ZSB0aGUgbWVtb3J5ICovCiBUUkFDRShtb2R1bGUsIkluaXRpYWxpemluZyBET1MgbWVtb3J5IHN0cnVjdHVyZXNcbiIpOwogRE9TTUVNX0luaXQobHBEb3NUYXNrLT5oTW9kdWxlKTsKIE1aX0luaXRYTVMobHBEb3NUYXNrKTsKIE1aX0luaXREUE1JKGxwRG9zVGFzayk7CiByZXR1cm4gMzI7Cn0KCnN0YXRpYyBpbnQgTVpfTG9hZEltYWdlKCBIRklMRTE2IGhGaWxlLCBMUENTVFIgbmFtZSwgTFBDU1RSIGNtZGxpbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgZW52LCBMUERPU1RBU0sgbHBEb3NUYXNrLCBORV9NT0RVTEUgKnBNb2R1bGUgKQp7CiBJTUFHRV9ET1NfSEVBREVSIG16X2hlYWRlcjsKIERXT1JEIGltYWdlX3N0YXJ0LGltYWdlX3NpemUsbWluX3NpemUsbWF4X3NpemUsYXZhaWw7CiBCWVRFKnBzcF9zdGFydCwqbG9hZF9zdGFydDsKIGludCB4LG9sZF9jb209MDsKIFNFR1BUUiByZWxvYzsKIFdPUkQgZW52X3NlZzsKCiBpZiAoKF9ocmVhZDE2KGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlcikpICE9IHNpemVvZihtel9oZWFkZXIpKSB8fAogICAgIChtel9oZWFkZXIuZV9tYWdpYyAhPSBJTUFHRV9ET1NfU0lHTkFUVVJFKSkgewojaWYgMAogICAgIHJldHVybiAxMTsgLyogaW52YWxpZCBleGUgKi8KI2VuZGlmCiAgb2xkX2NvbT0xOyAvKiBhc3N1bWUgLkNPTSBmaWxlICovCiAgaW1hZ2Vfc3RhcnQ9MDsKICBpbWFnZV9zaXplPUdldEZpbGVTaXplKEhGSUxFMTZfVE9fSEZJTEUzMihoRmlsZSksTlVMTCk7CiAgbWluX3NpemU9MHgxMDAwMDsgbWF4X3NpemU9MHgxMDAwMDA7CiAgbXpfaGVhZGVyLmVfY3JsYz0wOwogIG16X2hlYWRlci5lX3NzPTA7IG16X2hlYWRlci5lX3NwPTB4RkZGRTsKICBtel9oZWFkZXIuZV9jcz0wOyBtel9oZWFkZXIuZV9pcD0weDEwMDsKIH0gZWxzZSB7CiAgLyogY2FsY3VsYXRlIGxvYWQgc2l6ZSAqLwogIGltYWdlX3N0YXJ0PW16X2hlYWRlci5lX2NwYXJoZHI8PDQ7CiAgaW1hZ2Vfc2l6ZT1tel9oZWFkZXIuZV9jcDw8OTsgLyogcGFnZXMgYXJlIDUxMiBieXRlcyAqLwogIGlmICgobXpfaGVhZGVyLmVfY2JscCE9MCkmJihtel9oZWFkZXIuZV9jYmxwIT00KSkgaW1hZ2Vfc2l6ZS09NTEyLW16X2hlYWRlci5lX2NibHA7CiAgaW1hZ2Vfc2l6ZS09aW1hZ2Vfc3RhcnQ7CiAgbWluX3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21pbmFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogIG1heF9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9tYXhhbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKIH0KCiBNWl9Jbml0TWVtb3J5KGxwRG9zVGFzayxwTW9kdWxlKTsKCiAvKiBhbGxvY2F0ZSBlbnZpcm9ubWVudCBibG9jayAqLwogZW52X3NlZz1NWl9Jbml0RW52aXJvbm1lbnQobHBEb3NUYXNrLGVudixuYW1lKTsKCiAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBleGVjdXRhYmxlICovCiBUUkFDRShtb2R1bGUsIkFsbG9jYXRpbmcgRE9TIG1lbW9yeSAobWluPSVsZCwgbWF4PSVsZClcbiIsbWluX3NpemUsbWF4X3NpemUpOwogYXZhaWw9RE9TTUVNX0F2YWlsYWJsZShscERvc1Rhc2stPmhNb2R1bGUpOwogaWYgKGF2YWlsPG1pbl9zaXplKSB7CiAgRVJSKG1vZHVsZSwgImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICByZXR1cm4gMDsKIH0KIGlmIChhdmFpbD5tYXhfc2l6ZSkgYXZhaWw9bWF4X3NpemU7CiBwc3Bfc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxhdmFpbCwmbHBEb3NUYXNrLT5wc3Bfc2VnKTsKIGlmICghcHNwX3N0YXJ0KSB7CiAgRVJSKG1vZHVsZSwgImVycm9yIGFsbG9jYXRpbmcgRE9TIG1lbW9yeVxuIik7CiAgcmV0dXJuIDA7CiB9CiBscERvc1Rhc2stPmxvYWRfc2VnPWxwRG9zVGFzay0+cHNwX3NlZysob2xkX2NvbT8wOlBTUF9TSVpFKTsKIGxvYWRfc3RhcnQ9cHNwX3N0YXJ0KyhQU1BfU0laRTw8NCk7CiBNWl9Jbml0UFNQKHBzcF9zdGFydCwgY21kbGluZSwgZW52X3NlZyk7CgogLyogbG9hZCBleGVjdXRhYmxlIGltYWdlICovCiBUUkFDRShtb2R1bGUsImxvYWRpbmcgRE9TICVzIGltYWdlLCAlMDhseCBieXRlc1xuIixvbGRfY29tPyJDT00iOiJFWEUiLGltYWdlX3NpemUpOwogX2xsc2VlazE2KGhGaWxlLGltYWdlX3N0YXJ0LEZJTEVfQkVHSU4pOwogaWYgKChfaHJlYWQxNihoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUpKSAhPSBpbWFnZV9zaXplKQogIHJldHVybiAxMTsgLyogaW52YWxpZCBleGUgKi8KCiBpZiAobXpfaGVhZGVyLmVfY3JsYykgewogIC8qIGxvYWQgcmVsb2NhdGlvbiB0YWJsZSAqLwogIFRSQUNFKG1vZHVsZSwibG9hZGluZyBET1MgRVhFIHJlbG9jYXRpb24gdGFibGUsICVkIGVudHJpZXNcbiIsbXpfaGVhZGVyLmVfbGZhcmxjKTsKICAvKiBGSVhNRTogaXMgdGhpcyB0b28gc2xvdyB3aXRob3V0IHJlYWQgYnVmZmVyaW5nPyAqLwogIF9sbHNlZWsxNihoRmlsZSxtel9oZWFkZXIuZV9sZmFybGMsRklMRV9CRUdJTik7CiAgZm9yICh4PTA7IHg8bXpfaGVhZGVyLmVfY3JsYzsgeCsrKSB7CiAgIGlmIChfbHJlYWQxNihoRmlsZSwmcmVsb2Msc2l6ZW9mKHJlbG9jKSkgIT0gc2l6ZW9mKHJlbG9jKSkKICAgIHJldHVybiAxMTsgLyogaW52YWxpZCBleGUgKi8KICAgKihXT1JEKilTRUdQVFIxNihsb2FkX3N0YXJ0LHJlbG9jKSs9bHBEb3NUYXNrLT5sb2FkX3NlZzsKICB9CiB9CgogbHBEb3NUYXNrLT5pbml0X2NzPWxwRG9zVGFzay0+bG9hZF9zZWcrbXpfaGVhZGVyLmVfY3M7CiBscERvc1Rhc2stPmluaXRfaXA9bXpfaGVhZGVyLmVfaXA7CiBscERvc1Rhc2stPmluaXRfc3M9bHBEb3NUYXNrLT5sb2FkX3NlZyttel9oZWFkZXIuZV9zczsKIGxwRG9zVGFzay0+aW5pdF9zcD1tel9oZWFkZXIuZV9zcDsKCiBUUkFDRShtb2R1bGUsImVudHJ5IHBvaW50OiAlMDR4OiUwNHhcbiIsbHBEb3NUYXNrLT5pbml0X2NzLGxwRG9zVGFzay0+aW5pdF9pcCk7CgogcmV0dXJuIDMyOwp9CgppbnQgTVpfSW5pdFRhc2soIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBpbnQgcmVhZF9mZFsyXSx3cml0ZV9mZFsyXTsKIHBpZF90IGNoaWxkOwogY2hhciAqZm5hbWUsKmZhcmcsYXJnWzE2XSxmcHJvY1s2NF0scGF0aFsyNTZdLCpmcGF0aDsKCiAvKiBjcmVhdGUgcmVhZCBwaXBlICovCiBpZiAocGlwZShyZWFkX2ZkKTwwKSByZXR1cm4gMDsKIGlmIChwaXBlKHdyaXRlX2ZkKTwwKSB7CiAgY2xvc2UocmVhZF9mZFswXSk7IGNsb3NlKHJlYWRfZmRbMV0pOyByZXR1cm4gMDsKIH0KIGxwRG9zVGFzay0+cmVhZF9waXBlPXJlYWRfZmRbMF07CiBscERvc1Rhc2stPndyaXRlX3BpcGU9d3JpdGVfZmRbMV07CiAvKiBpZiB3ZSBoYXZlIGEgbWFwcGluZyBmaWxlLCB1c2UgaXQgKi8KIGZuYW1lPWxwRG9zVGFzay0+bW1fbmFtZTsgZmFyZz1OVUxMOwogaWYgKCFmbmFtZVswXSkgewogIC8qIG90aGVyd2lzZSwgbWFwIG91ciBvd24gbWVtb3J5IGltYWdlICovCiAgc3ByaW50ZihmcHJvYywiL3Byb2MvJWQvbWVtIixnZXRwaWQoKSk7CiAgc3ByaW50ZihhcmcsIiVsZCIsKHVuc2lnbmVkIGxvbmcpbHBEb3NUYXNrLT5pbWcpOwogIGZuYW1lPWZwcm9jOyBmYXJnPWFyZzsKIH0KCiBUUkFDRShtb2R1bGUsIkxvYWRpbmcgRE9TIFZNIHN1cHBvcnQgbW9kdWxlIChobW9kdWxlPSUwNHgpXG4iLGxwRG9zVGFzay0+aE1vZHVsZSk7CiBpZiAoKGNoaWxkPWZvcmsoKSk8MCkgewogIGNsb3NlKHdyaXRlX2ZkWzBdKTsgY2xvc2Uod3JpdGVfZmRbMV0pOwogIGNsb3NlKHJlYWRfZmRbMF0pOyBjbG9zZShyZWFkX2ZkWzFdKTsgcmV0dXJuIDA7CiB9CiBpZiAoY2hpbGQhPTApIHsKICAvKiBwYXJlbnQgcHJvY2VzcyAqLwogIGludCByZXQ7CgogIGNsb3NlKHJlYWRfZmRbMV0pOyBjbG9zZSh3cml0ZV9mZFswXSk7CiAgbHBEb3NUYXNrLT50YXNrPWNoaWxkOwogIC8qIHdhaXQgZm9yIGNoaWxkIHByb2Nlc3MgdG8gc2lnbmFsIHJlYWRpbmVzcyAqLwogIGRvIHsKICAgaWYgKHJlYWQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJnJldCxzaXplb2YocmV0KSkhPXNpemVvZihyZXQpKSB7CiAgICBpZiAoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkgY29udGludWU7CiAgICAvKiBmYWlsdXJlICovCiAgICBFUlIobW9kdWxlLCJkb3Ntb2QgaGFzIGZhaWxlZCB0byBpbml0aWFsaXplXG4iKTsKICAgIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICAgcmV0dXJuIDA7CiAgIH0KICB9IHdoaWxlICgwKTsKICAvKiB0aGUgY2hpbGQgaGFzIG5vdyBtbWFwZWQgdGhlIHRlbXAgZmlsZSwgaXQncyBub3cgc2FmZSB0byB1bmxpbmsuCiAgICogZG8gaXQgaGVyZSB0byBhdm9pZCBsZWF2aW5nIGEgbWVzcyBpbiAvdG1wIGlmL3doZW4gV2luZSBjcmFzaGVzLi4uICovCiAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgdW5saW5rKGxwRG9zVGFzay0+bW1fbmFtZSk7CiAgLyogYWxsIHN5c3RlbXMgYXJlIG5vdyBnbyAqLwogfSBlbHNlIHsKICAvKiBjaGlsZCBwcm9jZXNzICovCiAgY2xvc2UocmVhZF9mZFswXSk7IGNsb3NlKHdyaXRlX2ZkWzFdKTsKICAvKiBwdXQgb3VyIHBpcGVzIHNvbWV3aGVyZSBkb3Ntb2QgY2FuIGZpbmQgdGhlbSAqLwogIGR1cDIod3JpdGVfZmRbMF0sMCk7ICAgICAgLyogc3RkaW4gKi8KICBkdXAyKHJlYWRfZmRbMV0sMSk7ICAgICAgIC8qIHN0ZG91dCAqLwogIC8qIG5vdyBsb2FkIGRvc21vZCAqLwogIGV4ZWNscCgiZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIGV4ZWNsKCJkb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgLyogaG1tLCB0aGV5IGRpZG4ndCBpbnN0YWxsIHByb3Blcmx5ICovCiAgZXhlY2woImxvYWRlci9kb3MvZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIC8qIGxhc3QgcmVzb3J0LCB0cnkgdG8gZmluZCBpdCB0aHJvdWdoIGFyZ3ZbMF0gKi8KICBmcGF0aD1zdHJyY2hyKHN0cmNweShwYXRoLE9wdGlvbnMuYXJndjApLCcvJyk7CiAgaWYgKGZwYXRoKSB7CiAgIHN0cmNweShmcGF0aCwiL2xvYWRlci9kb3MvZG9zbW9kIik7CiAgIGV4ZWNsKHBhdGgsZm5hbWUsZmFyZyxOVUxMKTsKICB9CiAgLyogaWYgZmFpbHVyZSwgZXhpdCAqLwogIEVSUihtb2R1bGUsIkZhaWxlZCB0byBzcGF3biBkb3Ntb2QsIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgZXhpdCgxKTsKIH0KIHJldHVybiAzMjsKfQoKSElOU1RBTkNFMTYgTVpfQ3JlYXRlUHJvY2VzcyggTFBDU1RSIG5hbWUsIExQQ1NUUiBjbWRsaW5lLCBMUENTVFIgZW52LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVEFSVFVQSU5GTzMyQSBzdGFydHVwLCBMUFBST0NFU1NfSU5GT1JNQVRJT04gaW5mbyApCnsKIExQRE9TVEFTSyBscERvc1Rhc2sgPSBOVUxMOyAvKiBrZWVwIGdjYyBmcm9tIGNvbXBsYWluaW5nICovCiBITU9EVUxFMTYgaE1vZHVsZTsKIEhJTlNUQU5DRTE2IGhJbnN0YW5jZTsKIFREQiAqcFRhc2sgPSAoVERCKilHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKIE5FX01PRFVMRSAqcE1vZHVsZSA9IHBUYXNrID8gTkVfR2V0UHRyKCBwVGFzay0+aE1vZHVsZSApIDogTlVMTDsKIEhGSUxFMTYgaEZpbGU7CiBPRlNUUlVDVCBvZnM7CiBpbnQgZXJyLCBhbGxvYyA9ICEocE1vZHVsZSAmJiBwTW9kdWxlLT5kb3NfaW1hZ2UpOwoKIEdsb2JhbFVubG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CgogaWYgKGFsbG9jICYmIChscERvc1Rhc2sgPSBjYWxsb2MoMSwgc2l6ZW9mKERPU1RBU0spKSkgPT0gTlVMTCkKICByZXR1cm4gMDsKCiBpZiAoKGhGaWxlID0gT3BlbkZpbGUxNiggbmFtZSwgJm9mcywgT0ZfUkVBRCApKSA9PSBIRklMRV9FUlJPUjE2KQogIHJldHVybiAyOyAvKiBGaWxlIG5vdCBmb3VuZCAqLwoKIGlmIChhbGxvYykgewogIGlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSgmb2ZzKSkgPCAzMikKICAgcmV0dXJuIGhNb2R1bGU7CgogIGxwRG9zVGFzay0+aE1vZHVsZSA9IGhNb2R1bGU7CgogIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KGhNb2R1bGUpOwogIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKIAogIGxwRG9zVGFzay0+aW1nPU5VTEw7IGxwRG9zVGFzay0+bW1fbmFtZVswXT0wOyBscERvc1Rhc2stPm1tX2ZkPS0xOwogfSBlbHNlIGxwRG9zVGFzaz1wTW9kdWxlLT5scERvc1Rhc2s7CiBlcnIgPSBNWl9Mb2FkSW1hZ2UoIGhGaWxlLCBuYW1lLCBjbWRsaW5lLCBlbnYsIGxwRG9zVGFzaywgcE1vZHVsZSApOwogX2xjbG9zZTE2KGhGaWxlKTsKIGlmIChhbGxvYykgewogIHBNb2R1bGUtPmRvc19pbWFnZSA9IGxwRG9zVGFzay0+aW1nOwogIGlmIChlcnI8MzIpIHsKICAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgewogICAgaWYgKGxwRG9zVGFzay0+aW1nIT1OVUxMKSBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICAgIGlmIChscERvc1Rhc2stPm1tX2ZkPj0wKSBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKICAgIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICB9IGVsc2UKICAgIGlmIChscERvc1Rhc2stPmltZyE9TlVMTCkgVmlydHVhbEZyZWUobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAsTUVNX1JFTEVBU0UpOwogICByZXR1cm4gZXJyOwogIH0KICBlcnIgPSBNWl9Jbml0VGFzayggbHBEb3NUYXNrICk7CiAgaWYgKGVycjwzMikgewogICBNWl9LaWxsTW9kdWxlKCBscERvc1Rhc2sgKTsKICAgLyogRklYTUU6IGNsZWFudXAgaE1vZHVsZSAqLwogICByZXR1cm4gZXJyOwogIH0KCiAgaEluc3RhbmNlID0gTkVfQ3JlYXRlSW5zdGFuY2UocE1vZHVsZSwgTlVMTCwgKGNtZGxpbmUgPT0gTlVMTCkpOwogIFBST0NFU1NfQ3JlYXRlKCBwTW9kdWxlLCBjbWRsaW5lLCBlbnYsIGhJbnN0YW5jZSwgMCwgc3RhcnR1cCwgaW5mbyApOwogIHJldHVybiBoSW5zdGFuY2U7CiB9IGVsc2UgewogIHJldHVybiAoZXJyPDMyKSA/IGVyciA6IHBUYXNrLT5oSW5zdGFuY2U7CiB9Cn0KCnZvaWQgTVpfS2lsbE1vZHVsZSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKIH0gZWxzZSBWaXJ0dWFsRnJlZShscERvc1Rhc2stPmltZywweDExMDAwMCxNRU1fUkVMRUFTRSk7CiBjbG9zZShscERvc1Rhc2stPnJlYWRfcGlwZSk7CiBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwoga2lsbChscERvc1Rhc2stPnRhc2ssU0lHVEVSTSk7CiNpZiAwCiAvKiBGSVhNRTogdGhpcyBzZWVtcyB0byBjcmFzaCAqLwogaWYgKGxwRG9zVGFzay0+ZHBtaV9zZWwpCiAgVW5NYXBMUyhQVFJfU0VHX09GRl9UT19TRUdQVFIobHBEb3NUYXNrLT5kcG1pX3NlbCwwKSk7CiNlbmRpZgp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgpISU5TVEFOQ0UxNiBNWl9DcmVhdGVQcm9jZXNzKCBMUENTVFIgbmFtZSwgTFBDU1RSIGNtZGxpbmUsIExQQ1NUUiBlbnYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUQVJUVVBJTkZPMzJBIHN0YXJ0dXAsIExQUFJPQ0VTU19JTkZPUk1BVElPTiBpbmZvICkKewogV0FSTihtb2R1bGUsIkRPUyBleGVjdXRhYmxlcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlXG4iKTsKIHJldHVybiAoSE1PRFVMRTE2KTExOyAgLyogaW52YWxpZCBleGUgKi8KfQoKI2VuZGlmCg==