LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgInNlbGVjdG9ycy5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCgojaWZkZWYgTVpfU1VQUE9SVEVECgojaW5jbHVkZSA8c3lzL21tYW4uaD4KCi8qIGRlZmluZSB0aGlzIHRvIHRyeSBtYXBwaW5nIHRocm91Z2ggL3Byb2MvcGlkL21lbSBpbnN0ZWFkIG9mIGEgdGVtcCBmaWxlLAogICBidXQgTGludXMgZG9lc24ndCBsaWtlIG1tYXBwaW5nIC9wcm9jL3BpZC9tZW0sIHNvIGl0IGRvZXNuJ3Qgd29yayBmb3IgbWUgKi8KI3VuZGVmIE1aX01BUFNFTEYKCiNkZWZpbmUgQklPU19EQVRBX1NFR01FTlQgMHg0MAojZGVmaW5lIFNUQVJUX09GRlNFVCAwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKc3RhdGljIHZvaWQgTVpfSW5pdFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kbGluZSwgV09SRCBlbnYgKQp7CiBQREIqcHNwPWxwUFNQOwogY29uc3QgY2hhcipjbWQ9Y21kbGluZT9zdHJjaHIoY21kbGluZSwnICcpOk5VTEw7CgogcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogLyogc29tZSBwcm9ncmFtcyB1c2UgdGhpcyB0byBjYWxjdWxhdGUgaG93IG11Y2ggbWVtb3J5IHRoZXkgbmVlZCAqLwogcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsKIHBzcC0+ZW52aXJvbm1lbnQ9ZW52OwogLyogY29weSBwYXJhbWV0ZXJzICovCiBpZiAoY21kKSB7CiNpZiAwCiAgLyogY29tbWFuZC5jb20gZG9lc24ndCBkbyB0aGlzICovCiAgd2hpbGUgKCpjbWQgPT0gJyAnKSBjbWQrKzsKI2VuZGlmCiAgcHNwLT5jbWRMaW5lWzBdPXN0cmxlbihjbWQpOwogIHN0cmNweShwc3AtPmNtZExpbmUrMSxjbWQpOwogIHBzcC0+Y21kTGluZVtwc3AtPmNtZExpbmVbMF0rMV09J1xyJzsKIH0gZWxzZSBwc3AtPmNtZExpbmVbMV09J1xyJzsKIC8qIEZJWE1FOiBpbnRlZ3JhdGUgdGhlIG1lbW9yeSBzdHVmZiBmcm9tIFdpbmUgKG1zZG9zL2Rvc21lbS5jKSAqLwogLyogRklYTUU6IGludGVncmF0ZSB0aGUgUERCIHN0dWZmIGZyb20gV2luZSAobG9hZGVyL3Rhc2suYykgKi8KfQoKc3RhdGljIGNoYXIgZW50ZXJfeG1zW109ewovKiBYTVMgaG9va2FibGUgZW50cnkgcG9pbnQgKi8KIDB4RUIsMHgwMywgICAgICAgICAgIC8qIGptcCBlbnRyeSAqLwogMHg5MCwweDkwLDB4OTAsICAgICAgLyogbm9wO25vcDtub3AgKi8KICAgICAgICAgICAgICAgICAgICAgIC8qIGVudHJ5OiAqLwovKiByZWFsIGVudHJ5IHBvaW50ICovCi8qIGZvciBzaW1wbGljaXR5LCB3ZSdsbCBqdXN0IHVzZSB0aGUgc2FtZSBob29rIGFzIERQTUkgYmVsb3cgKi8KIDB4Q0QsMHgzMSwgICAgICAgICAgIC8qIGludCAkMHgzMSAqLwogMHhDQiAgICAgICAgICAgICAgICAgLyogbHJldCAqLwp9OwoKc3RhdGljIHZvaWQgTVpfSW5pdFhNUyggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHNpemVvZihlbnRlcl94bXMpLCYobHBEb3NUYXNrLT54bXNfc2VnKSk7CiBtZW1jcHkoc3RhcnQsZW50ZXJfeG1zLHNpemVvZihlbnRlcl94bXMpKTsKfQoKc3RhdGljIGNoYXIgZW50ZXJfcG1bXT17CiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4NTIsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkeCAqLwogMHg1NSwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWJwICovCiAweDg5LDB4RTUsICAgICAgICAgICAvKiBtb3Z3ICVzcCwlYnAgKi8KLyogZ2V0IHJldHVybiBDUyAqLwogMHg4QiwweDU2LDB4MDgsICAgICAgLyogbW92dyA4KCVicCksJWR4ICovCi8qIGp1c3QgY2FsbCBpbnQgMzEgaGVyZSB0byBnZXQgaW50byBwcm90ZWN0ZWQgbW9kZS4uLiAqLwovKiBpdCdsbCBjaGVjayB3aGV0aGVyIGl0IHdhcyBjYWxsZWQgZnJvbSBkcG1pX3NlZy4uLiAqLwogMHhDRCwweDMxLCAgICAgICAgICAgLyogaW50ICQweDMxICovCi8qIHdlIGFyZSBub3cgaW4gdGhlIGNvbnRleHQgb2YgYSAxNi1iaXQgcmVsYXkgY2FsbCAqLwovKiBuZWVkIHRvIGZpeHVwIG91ciBzdGFjazsKICogMTYtYml0IHJlbGF5IHJldHVybiBhZGRyZXNzIHdpbGwgYmUgbG9zdCwgYnV0IHdlIHdvbid0IHdvcnJ5IHF1aXRlIHlldCAqLwogMHg4RSwweEQwLCAgICAgICAgICAgLyogbW92dyAlYXgsJXNzICovCiAweDY2LDB4MEYsMHhCNywweEU1LCAvKiBtb3Z6d2wgJWJwLCVlc3AgKi8KLyogc2V0IHJldHVybiBDUyAqLwogMHg4OSwweDU2LDB4MDgsICAgICAgLyogbW92dyAlZHgsOCglYnApICovCiAweDVELCAgICAgICAgICAgICAgICAvKiBwb3B3ICVicCAqLwogMHg1QSwgICAgICAgICAgICAgICAgLyogcG9wdyAlZHggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENCICAgICAgICAgICAgICAgICAvKiBscmV0ICovCn07CgpzdGF0aWMgY2hhciB3cmFwX3JtW109ewogMHhDRCwweDMxLCAgICAgICAgICAgLyogaW50ICQweDMxICovCiAweENCICAgICAgICAgICAgICAgICAvKiBscmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0RFBNSSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIHVuc2lnbmVkIHNpemU9c2l6ZW9mKGVudGVyX3BtKStzaXplb2Yod3JhcF9ybSk7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxzaXplLCYobHBEb3NUYXNrLT5kcG1pX3NlZykpOwogCiBscERvc1Rhc2stPmRwbWlfc2VsID0gU0VMRUNUT1JfQWxsb2NCbG9jayggc3RhcnQsIHNpemUsIFNFR01FTlRfQ09ERSwgRkFMU0UsIEZBTFNFICk7CiBscERvc1Rhc2stPndyYXBfb2ZzID0gc2l6ZS1zaXplb2Yod3JhcF9ybSk7CiBscERvc1Rhc2stPmNhbGxfb2ZzID0gc2l6ZS0xOwoKIG1lbWNweShzdGFydCxlbnRlcl9wbSxzaXplb2YoZW50ZXJfcG0pKTsKfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUERPU1RBU0sgbHBEb3NUYXNrLCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHN6K3NpemVvZihXT1JEKStzdHJsZW4obmFtZSkrMSwmc2VnKTsKIC8qIGZpbGwgaXQgKi8KIGlmIChlbnYpIHsKICBtZW1jcHkoZW52YmxrLGVudixzeik7CiB9IGVsc2UgZW52YmxrWzBdPTA7CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKaW50IE1aX0luaXRNZW1vcnkoIExQRE9TVEFTSyBscERvc1Rhc2ssIE5FX01PRFVMRSAqcE1vZHVsZSApCnsKIGludCB4OwoKIGlmIChscERvc1Rhc2stPmltZ19vZnMpIHJldHVybiAzMjsgLyogYWxyZWFkeSBhbGxvY2F0ZWQgKi8KCiAvKiBhbGxvY2F0ZSAxTUIrNjRLIHNoYXJlZCBtZW1vcnkgKi8KIGxwRG9zVGFzay0+aW1nX29mcz1TVEFSVF9PRkZTRVQ7CiNpZmRlZiBNWl9NQVBTRUxGCiBscERvc1Rhc2stPmltZz1WaXJ0dWFsQWxsb2MoTlVMTCwweDExMDAwMCxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKIC8qIG1ha2Ugc3VyZSBtbWFwIGFjY2VwdHMgaXQgKi8KICgoY2hhciopbHBEb3NUYXNrLT5pbWcpWzB4MTBGRkZGXT0wOwojZWxzZQogdG1wbmFtKGxwRG9zVGFzay0+bW1fbmFtZSk7Ci8qIHN0cmNweShscERvc1Rhc2stPm1tX25hbWUsIi90bXAvbXlkb3NpbWFnZSIpOyAqLwogbHBEb3NUYXNrLT5tbV9mZD1vcGVuKGxwRG9zVGFzay0+bW1fbmFtZSxPX1JEV1J8T19DUkVBVCAvKiB8T19UUlVOQyAqLyxTX0lSVVNSfFNfSVdVU1IpOwogaWYgKGxwRG9zVGFzay0+bW1fZmQ8MCkgRVJSKG1vZHVsZSwiZmlsZSAlcyBjb3VsZCBub3QgYmUgb3BlbmVkXG4iLGxwRG9zVGFzay0+bW1fbmFtZSk7CiAvKiBleHBhbmQgZmlsZSB0byAxTUIrNjRLICovCiBsc2VlayhscERvc1Rhc2stPm1tX2ZkLDB4MTEwMDAwLTEsU0VFS19TRVQpOwogeD0wOyB3cml0ZShscERvc1Rhc2stPm1tX2ZkLCZ4LDEpOwogLyogbWFwIGl0IGluICovCiBscERvc1Rhc2stPmltZz1tbWFwKE5VTEwsMHgxMTAwMDAtU1RBUlRfT0ZGU0VULFBST1RfUkVBRHxQUk9UX1dSSVRFLE1BUF9TSEFSRUQsbHBEb3NUYXNrLT5tbV9mZCwwKTsKI2VuZGlmCiBpZiAobHBEb3NUYXNrLT5pbWc9PShMUFZPSUQpLTEpIHsKICBFUlIobW9kdWxlLCJjb3VsZCBub3QgbWFwIHNoYXJlZCBtZW1vcnksIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgcmV0dXJuIDA7CiB9CiBUUkFDRShtb2R1bGUsIkRPUyBWTTg2IGltYWdlIG1hcHBlZCBhdCAlMDhseFxuIiwoRFdPUkQpbHBEb3NUYXNrLT5pbWcpOwogcE1vZHVsZS0+ZG9zX2ltYWdlPWxwRG9zVGFzay0+aW1nOwoKIC8qIGluaXRpYWxpemUgdGhlIG1lbW9yeSAqLwogVFJBQ0UobW9kdWxlLCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKIERPU01FTV9Jbml0KGxwRG9zVGFzay0+aE1vZHVsZSk7CiBNWl9Jbml0WE1TKGxwRG9zVGFzayk7CiBNWl9Jbml0RFBNSShscERvc1Rhc2spOwogcmV0dXJuIGxwRG9zVGFzay0+aE1vZHVsZTsKfQoKc3RhdGljIGludCBNWl9Mb2FkSW1hZ2UoIEhGSUxFMTYgaEZpbGUsIExQQ1NUUiBuYW1lLCBMUENTVFIgY21kbGluZSwKICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBlbnYsIExQRE9TVEFTSyBscERvc1Rhc2ssIE5FX01PRFVMRSAqcE1vZHVsZSApCnsKIElNQUdFX0RPU19IRUFERVIgbXpfaGVhZGVyOwogRFdPUkQgaW1hZ2Vfc3RhcnQsaW1hZ2Vfc2l6ZSxtaW5fc2l6ZSxtYXhfc2l6ZSxhdmFpbDsKIEJZVEUqcHNwX3N0YXJ0LCpsb2FkX3N0YXJ0OwogaW50IHgsb2xkX2NvbT0wOwogU0VHUFRSIHJlbG9jOwogV09SRCBlbnZfc2VnOwoKIGlmICgoX2hyZWFkMTYoaEZpbGUsJm16X2hlYWRlcixzaXplb2YobXpfaGVhZGVyKSkgIT0gc2l6ZW9mKG16X2hlYWRlcikpIHx8CiAgICAgKG16X2hlYWRlci5lX21hZ2ljICE9IElNQUdFX0RPU19TSUdOQVRVUkUpKSB7CiNpZiAwCiAgICAgcmV0dXJuIDExOyAvKiBpbnZhbGlkIGV4ZSAqLwojZW5kaWYKICBvbGRfY29tPTE7IC8qIGFzc3VtZSAuQ09NIGZpbGUgKi8KICBpbWFnZV9zdGFydD0wOwogIGltYWdlX3NpemU9R2V0RmlsZVNpemUoSEZJTEUxNl9UT19IRklMRTMyKGhGaWxlKSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgaWYgKChtel9oZWFkZXIuZV9jYmxwIT0wKSYmKG16X2hlYWRlci5lX2NibHAhPTQpKSBpbWFnZV9zaXplLT01MTItbXpfaGVhZGVyLmVfY2JscDsKICBpbWFnZV9zaXplLT1pbWFnZV9zdGFydDsKICBtaW5fc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWluYWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiAgbWF4X3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21heGFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogfQoKIE1aX0luaXRNZW1vcnkobHBEb3NUYXNrLHBNb2R1bGUpOwoKIC8qIGFsbG9jYXRlIGVudmlyb25tZW50IGJsb2NrICovCiBlbnZfc2VnPU1aX0luaXRFbnZpcm9ubWVudChscERvc1Rhc2ssZW52LG5hbWUpOwoKIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGV4ZWN1dGFibGUgKi8KIFRSQUNFKG1vZHVsZSwiQWxsb2NhdGluZyBET1MgbWVtb3J5IChtaW49JWxkLCBtYXg9JWxkKVxuIixtaW5fc2l6ZSxtYXhfc2l6ZSk7CiBhdmFpbD1ET1NNRU1fQXZhaWxhYmxlKGxwRG9zVGFzay0+aE1vZHVsZSk7CiBpZiAoYXZhaWw8bWluX3NpemUpIHsKICBFUlIobW9kdWxlLCAiaW5zdWZmaWNpZW50IERPUyBtZW1vcnlcbiIpOwogIHJldHVybiAwOwogfQogaWYgKGF2YWlsPm1heF9zaXplKSBhdmFpbD1tYXhfc2l6ZTsKIHBzcF9zdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLGF2YWlsLCZscERvc1Rhc2stPnBzcF9zZWcpOwogaWYgKCFwc3Bfc3RhcnQpIHsKICBFUlIobW9kdWxlLCAiZXJyb3IgYWxsb2NhdGluZyBET1MgbWVtb3J5XG4iKTsKICByZXR1cm4gMDsKIH0KIGxwRG9zVGFzay0+bG9hZF9zZWc9bHBEb3NUYXNrLT5wc3Bfc2VnKyhvbGRfY29tPzA6UFNQX1NJWkUpOwogbG9hZF9zdGFydD1wc3Bfc3RhcnQrKFBTUF9TSVpFPDw0KTsKIE1aX0luaXRQU1AocHNwX3N0YXJ0LCBjbWRsaW5lLCBlbnZfc2VnKTsKCiAvKiBsb2FkIGV4ZWN1dGFibGUgaW1hZ2UgKi8KIFRSQUNFKG1vZHVsZSwibG9hZGluZyBET1MgJXMgaW1hZ2UsICUwOGx4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBfbGxzZWVrMTYoaEZpbGUsaW1hZ2Vfc3RhcnQsRklMRV9CRUdJTik7CiBpZiAoKF9ocmVhZDE2KGhGaWxlLGxvYWRfc3RhcnQsaW1hZ2Vfc2l6ZSkpICE9IGltYWdlX3NpemUpCiAgcmV0dXJuIDExOyAvKiBpbnZhbGlkIGV4ZSAqLwoKIGlmIChtel9oZWFkZXIuZV9jcmxjKSB7CiAgLyogbG9hZCByZWxvY2F0aW9uIHRhYmxlICovCiAgVFJBQ0UobW9kdWxlLCJsb2FkaW5nIERPUyBFWEUgcmVsb2NhdGlvbiB0YWJsZSwgJWQgZW50cmllc1xuIixtel9oZWFkZXIuZV9sZmFybGMpOwogIC8qIEZJWE1FOiBpcyB0aGlzIHRvbyBzbG93IHdpdGhvdXQgcmVhZCBidWZmZXJpbmc/ICovCiAgX2xsc2VlazE2KGhGaWxlLG16X2hlYWRlci5lX2xmYXJsYyxGSUxFX0JFR0lOKTsKICBmb3IgKHg9MDsgeDxtel9oZWFkZXIuZV9jcmxjOyB4KyspIHsKICAgaWYgKF9scmVhZDE2KGhGaWxlLCZyZWxvYyxzaXplb2YocmVsb2MpKSAhPSBzaXplb2YocmVsb2MpKQogICAgcmV0dXJuIDExOyAvKiBpbnZhbGlkIGV4ZSAqLwogICAqKFdPUkQqKVNFR1BUUjE2KGxvYWRfc3RhcnQscmVsb2MpKz1scERvc1Rhc2stPmxvYWRfc2VnOwogIH0KIH0KCiBscERvc1Rhc2stPmluaXRfY3M9bHBEb3NUYXNrLT5sb2FkX3NlZyttel9oZWFkZXIuZV9jczsKIGxwRG9zVGFzay0+aW5pdF9pcD1tel9oZWFkZXIuZV9pcDsKIGxwRG9zVGFzay0+aW5pdF9zcz1scERvc1Rhc2stPmxvYWRfc2VnK216X2hlYWRlci5lX3NzOwogbHBEb3NUYXNrLT5pbml0X3NwPW16X2hlYWRlci5lX3NwOwoKIFRSQUNFKG1vZHVsZSwiZW50cnkgcG9pbnQ6ICUwNHg6JTA0eFxuIixscERvc1Rhc2stPmluaXRfY3MsbHBEb3NUYXNrLT5pbml0X2lwKTsKCiByZXR1cm4gbHBEb3NUYXNrLT5oTW9kdWxlOwp9CgpMUERPU1RBU0sgTVpfQWxsb2NEUE1JVGFzayggSE1PRFVMRTE2IGhNb2R1bGUgKQp7CiBMUERPU1RBU0sgbHBEb3NUYXNrID0gY2FsbG9jKDEsIHNpemVvZihET1NUQVNLKSk7CiBORV9NT0RVTEUgKnBNb2R1bGU7CgogaWYgKGxwRG9zVGFzaykgewogIGxwRG9zVGFzay0+aE1vZHVsZSA9IGhNb2R1bGU7CgogIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KGhNb2R1bGUpOwogIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKIAogIGxwRG9zVGFzay0+aW1nPU5VTEw7IGxwRG9zVGFzay0+bW1fbmFtZVswXT0wOyBscERvc1Rhc2stPm1tX2ZkPS0xOwoKICBNWl9Jbml0TWVtb3J5KGxwRG9zVGFzaywgcE1vZHVsZSk7CgogIEdsb2JhbFVubG9jazE2KGhNb2R1bGUpOwogfQogcmV0dXJuIGxwRG9zVGFzazsKfQoKaW50IE1aX0luaXRUYXNrKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogaW50IHJlYWRfZmRbMl0sd3JpdGVfZmRbMl07CiBwaWRfdCBjaGlsZDsKIGNoYXIgKmZuYW1lLCpmYXJnLGFyZ1sxNl0sZnByb2NbNjRdLHBhdGhbMjU2XSwqZnBhdGg7CgogaWYgKCFscERvc1Rhc2spIHJldHVybiAwOwogLyogY3JlYXRlIHJlYWQgcGlwZSAqLwogaWYgKHBpcGUocmVhZF9mZCk8MCkgcmV0dXJuIDA7CiBpZiAocGlwZSh3cml0ZV9mZCk8MCkgewogIGNsb3NlKHJlYWRfZmRbMF0pOyBjbG9zZShyZWFkX2ZkWzFdKTsgcmV0dXJuIDA7CiB9CiBscERvc1Rhc2stPnJlYWRfcGlwZT1yZWFkX2ZkWzBdOwogbHBEb3NUYXNrLT53cml0ZV9waXBlPXdyaXRlX2ZkWzFdOwogLyogaWYgd2UgaGF2ZSBhIG1hcHBpbmcgZmlsZSwgdXNlIGl0ICovCiBmbmFtZT1scERvc1Rhc2stPm1tX25hbWU7IGZhcmc9TlVMTDsKIGlmICghZm5hbWVbMF0pIHsKICAvKiBvdGhlcndpc2UsIG1hcCBvdXIgb3duIG1lbW9yeSBpbWFnZSAqLwogIHNwcmludGYoZnByb2MsIi9wcm9jLyVkL21lbSIsZ2V0cGlkKCkpOwogIHNwcmludGYoYXJnLCIlbGQiLCh1bnNpZ25lZCBsb25nKWxwRG9zVGFzay0+aW1nKTsKICBmbmFtZT1mcHJvYzsgZmFyZz1hcmc7CiB9CgogVFJBQ0UobW9kdWxlLCJMb2FkaW5nIERPUyBWTSBzdXBwb3J0IG1vZHVsZSAoaG1vZHVsZT0lMDR4KVxuIixscERvc1Rhc2stPmhNb2R1bGUpOwogaWYgKChjaGlsZD1mb3JrKCkpPDApIHsKICBjbG9zZSh3cml0ZV9mZFswXSk7IGNsb3NlKHdyaXRlX2ZkWzFdKTsKICBjbG9zZShyZWFkX2ZkWzBdKTsgY2xvc2UocmVhZF9mZFsxXSk7IHJldHVybiAwOwogfQogaWYgKGNoaWxkIT0wKSB7CiAgLyogcGFyZW50IHByb2Nlc3MgKi8KICBpbnQgcmV0OwoKICBjbG9zZShyZWFkX2ZkWzFdKTsgY2xvc2Uod3JpdGVfZmRbMF0pOwogIGxwRG9zVGFzay0+dGFzaz1jaGlsZDsKICAvKiB3YWl0IGZvciBjaGlsZCBwcm9jZXNzIHRvIHNpZ25hbCByZWFkaW5lc3MgKi8KICBkbyB7CiAgIGlmIChyZWFkKGxwRG9zVGFzay0+cmVhZF9waXBlLCZyZXQsc2l6ZW9mKHJldCkpIT1zaXplb2YocmV0KSkgewogICAgaWYgKChlcnJubz09RUlOVFIpfHwoZXJybm89PUVBR0FJTikpIGNvbnRpbnVlOwogICAgLyogZmFpbHVyZSAqLwogICAgRVJSKG1vZHVsZSwiZG9zbW9kIGhhcyBmYWlsZWQgdG8gaW5pdGlhbGl6ZVxuIik7CiAgICBpZiAobHBEb3NUYXNrLT5tbV9uYW1lWzBdIT0wKSB1bmxpbmsobHBEb3NUYXNrLT5tbV9uYW1lKTsKICAgIHJldHVybiAwOwogICB9CiAgfSB3aGlsZSAoMCk7CiAgLyogdGhlIGNoaWxkIGhhcyBub3cgbW1hcGVkIHRoZSB0ZW1wIGZpbGUsIGl0J3Mgbm93IHNhZmUgdG8gdW5saW5rLgogICAqIGRvIGl0IGhlcmUgdG8gYXZvaWQgbGVhdmluZyBhIG1lc3MgaW4gL3RtcCBpZi93aGVuIFdpbmUgY3Jhc2hlcy4uLiAqLwogIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogIC8qIGFsbCBzeXN0ZW1zIGFyZSBub3cgZ28gKi8KIH0gZWxzZSB7CiAgLyogY2hpbGQgcHJvY2VzcyAqLwogIGNsb3NlKHJlYWRfZmRbMF0pOyBjbG9zZSh3cml0ZV9mZFsxXSk7CiAgLyogcHV0IG91ciBwaXBlcyBzb21ld2hlcmUgZG9zbW9kIGNhbiBmaW5kIHRoZW0gKi8KICBkdXAyKHdyaXRlX2ZkWzBdLDApOyAgICAgIC8qIHN0ZGluICovCiAgZHVwMihyZWFkX2ZkWzFdLDEpOyAgICAgICAvKiBzdGRvdXQgKi8KICAvKiBub3cgbG9hZCBkb3Ntb2QgKi8KICBleGVjbHAoImRvc21vZCIsZm5hbWUsZmFyZyxOVUxMKTsKICBleGVjbCgiZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIC8qIGhtbSwgdGhleSBkaWRuJ3QgaW5zdGFsbCBwcm9wZXJseSAqLwogIGV4ZWNsKCJsb2FkZXIvZG9zL2Rvc21vZCIsZm5hbWUsZmFyZyxOVUxMKTsKICAvKiBsYXN0IHJlc29ydCwgdHJ5IHRvIGZpbmQgaXQgdGhyb3VnaCBhcmd2WzBdICovCiAgZnBhdGg9c3RycmNocihzdHJjcHkocGF0aCxPcHRpb25zLmFyZ3YwKSwnLycpOwogIGlmIChmcGF0aCkgewogICBzdHJjcHkoZnBhdGgsIi9sb2FkZXIvZG9zL2Rvc21vZCIpOwogICBleGVjbChwYXRoLGZuYW1lLGZhcmcsTlVMTCk7CiAgfQogIC8qIGlmIGZhaWx1cmUsIGV4aXQgKi8KICBFUlIobW9kdWxlLCJGYWlsZWQgdG8gc3Bhd24gZG9zbW9kLCBlcnJvcj0lc1xuIixzdHJlcnJvcihlcnJubykpOwogIGV4aXQoMSk7CiB9CiAvKiBzdGFydCBzaW11bGF0ZWQgc3lzdGVtIDU1SHogdGltZXIgKi8KIGxwRG9zVGFzay0+c3lzdGVtX3RpbWVyID0gQ3JlYXRlU3lzdGVtVGltZXIoIDU1LCAoRkFSUFJPQzE2KU1aX1RpY2sgKTsKIFRSQUNFKG1vZHVsZSwiY3JlYXRlZCA1NUh6IHRpbWVyIHRpY2ssIGhhbmRsZT0lZFxuIixscERvc1Rhc2stPnN5c3RlbV90aW1lcik7CiByZXR1cm4gbHBEb3NUYXNrLT5oTW9kdWxlOwp9CgpISU5TVEFOQ0UxNiBNWl9DcmVhdGVQcm9jZXNzKCBMUENTVFIgbmFtZSwgTFBDU1RSIGNtZGxpbmUsIExQQ1NUUiBlbnYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUQVJUVVBJTkZPMzJBIHN0YXJ0dXAsIExQUFJPQ0VTU19JTkZPUk1BVElPTiBpbmZvICkKewogTFBET1NUQVNLIGxwRG9zVGFzayA9IE5VTEw7IC8qIGtlZXAgZ2NjIGZyb20gY29tcGxhaW5pbmcgKi8KIEhNT0RVTEUxNiBoTW9kdWxlOwogSElOU1RBTkNFMTYgaEluc3RhbmNlOwogUERCMzIgKnBkYiA9IFBST0NFU1NfQ3VycmVudCgpOwogVERCICpwVGFzayA9IChUREIqKUdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogTkVfTU9EVUxFICpwTW9kdWxlID0gcFRhc2sgPyBORV9HZXRQdHIoIHBUYXNrLT5oTW9kdWxlICkgOiBOVUxMOwogSEZJTEUxNiBoRmlsZTsKIE9GU1RSVUNUIG9mczsKIGludCBlcnIsIGFsbG9jID0gIShwTW9kdWxlICYmIHBNb2R1bGUtPmRvc19pbWFnZSk7CgogR2xvYmFsVW5sb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKCiBpZiAoYWxsb2MgJiYgKGxwRG9zVGFzayA9IGNhbGxvYygxLCBzaXplb2YoRE9TVEFTSykpKSA9PSBOVUxMKQogIHJldHVybiAwOwoKIGlmICgoaEZpbGUgPSBPcGVuRmlsZTE2KCBuYW1lLCAmb2ZzLCBPRl9SRUFEICkpID09IEhGSUxFX0VSUk9SMTYpCiAgcmV0dXJuIDI7IC8qIEZpbGUgbm90IGZvdW5kICovCgogaWYgKCghZW52KSYmcGRiKSBlbnYgPSBwZGItPmVudl9kYi0+ZW52aXJvbjsKIGlmIChhbGxvYykgewogIGlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSgmb2ZzKSkgPCAzMikKICAgcmV0dXJuIGhNb2R1bGU7CgogIGxwRG9zVGFzay0+aE1vZHVsZSA9IGhNb2R1bGU7CgogIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KGhNb2R1bGUpOwogIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKIAogIGxwRG9zVGFzay0+aW1nPU5VTEw7IGxwRG9zVGFzay0+bW1fbmFtZVswXT0wOyBscERvc1Rhc2stPm1tX2ZkPS0xOwogfSBlbHNlIGxwRG9zVGFzaz1wTW9kdWxlLT5scERvc1Rhc2s7CiBlcnIgPSBNWl9Mb2FkSW1hZ2UoIGhGaWxlLCBuYW1lLCBjbWRsaW5lLCBlbnYsIGxwRG9zVGFzaywgcE1vZHVsZSApOwogX2xjbG9zZTE2KGhGaWxlKTsKIGlmIChhbGxvYykgewogIHBNb2R1bGUtPmRvc19pbWFnZSA9IGxwRG9zVGFzay0+aW1nOwogIGlmIChlcnI8MzIpIHsKICAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgewogICAgaWYgKGxwRG9zVGFzay0+aW1nIT1OVUxMKSBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICAgIGlmIChscERvc1Rhc2stPm1tX2ZkPj0wKSBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKICAgIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICB9IGVsc2UKICAgIGlmIChscERvc1Rhc2stPmltZyE9TlVMTCkgVmlydHVhbEZyZWUobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAsTUVNX1JFTEVBU0UpOwogICByZXR1cm4gZXJyOwogIH0KICBlcnIgPSBNWl9Jbml0VGFzayggbHBEb3NUYXNrICk7CiAgaWYgKGVycjwzMikgewogICBNWl9LaWxsTW9kdWxlKCBscERvc1Rhc2sgKTsKICAgLyogRklYTUU6IGNsZWFudXAgaE1vZHVsZSAqLwogICByZXR1cm4gZXJyOwogIH0KCiAgaEluc3RhbmNlID0gTkVfQ3JlYXRlSW5zdGFuY2UocE1vZHVsZSwgTlVMTCwgKGNtZGxpbmUgPT0gTlVMTCkpOwogIFBST0NFU1NfQ3JlYXRlKCBwTW9kdWxlLCBjbWRsaW5lLCBlbnYsIGhJbnN0YW5jZSwgMCwgc3RhcnR1cCwgaW5mbyApOwogIHJldHVybiBoSW5zdGFuY2U7CiB9IGVsc2UgewogIHJldHVybiAoZXJyPDMyKSA/IGVyciA6IHBUYXNrLT5oSW5zdGFuY2U7CiB9Cn0KCnZvaWQgTVpfS2lsbE1vZHVsZSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIFRSQUNFKG1vZHVsZSwia2lsbGluZyBET1MgdGFza1xuIik7CiBTWVNURU1fS2lsbFN5c3RlbVRpbWVyKGxwRG9zVGFzay0+c3lzdGVtX3RpbWVyKTsKIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKIH0gZWxzZSBWaXJ0dWFsRnJlZShscERvc1Rhc2stPmltZywweDExMDAwMCxNRU1fUkVMRUFTRSk7CiBjbG9zZShscERvc1Rhc2stPnJlYWRfcGlwZSk7CiBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwoga2lsbChscERvc1Rhc2stPnRhc2ssU0lHVEVSTSk7CiNpZiAwCiAvKiBGSVhNRTogdGhpcyBzZWVtcyB0byBjcmFzaCAqLwogaWYgKGxwRG9zVGFzay0+ZHBtaV9zZWwpCiAgVW5NYXBMUyhQVFJfU0VHX09GRl9UT19TRUdQVFIobHBEb3NUYXNrLT5kcG1pX3NlbCwwKSk7CiNlbmRpZgp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgpISU5TVEFOQ0UxNiBNWl9DcmVhdGVQcm9jZXNzKCBMUENTVFIgbmFtZSwgTFBDU1RSIGNtZGxpbmUsIExQQ1NUUiBlbnYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUQVJUVVBJTkZPMzJBIHN0YXJ0dXAsIExQUFJPQ0VTU19JTkZPUk1BVElPTiBpbmZvICkKewogV0FSTihtb2R1bGUsIkRPUyBleGVjdXRhYmxlcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlXG4iKTsKIHJldHVybiAoSE1PRFVMRTE2KTExOyAgLyogaW52YWxpZCBleGUgKi8KfQoKI2VuZGlmCg==