LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgInNlbGVjdG9ycy5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc21vZC5oIgojaW5jbHVkZSAib3B0aW9ucy5oIgojaW5jbHVkZSAic2VydmVyLmgiCiNpbmNsdWRlICJ2Z2EuaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTChtb2R1bGUpCgojaWZkZWYgTVpfU1VQUE9SVEVECgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgovKiBkZWZpbmUgdGhpcyB0byB0cnkgbWFwcGluZyB0aHJvdWdoIC9wcm9jL3BpZC9tZW0gaW5zdGVhZCBvZiBhIHRlbXAgZmlsZSwKICAgYnV0IExpbnVzIGRvZXNuJ3QgbGlrZSBtbWFwcGluZyAvcHJvYy9waWQvbWVtLCBzbyBpdCBkb2Vzbid0IHdvcmsgZm9yIG1lICovCiN1bmRlZiBNWl9NQVBTRUxGCgojZGVmaW5lIEJJT1NfREFUQV9TRUdNRU5UIDB4NDAKI2RlZmluZSBTVEFSVF9PRkZTRVQgMAojZGVmaW5lIFBTUF9TSVpFIDB4MTAKCiNkZWZpbmUgU0VHMTYocHRyLHNlZykgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRCkoc2VnKTw8NCkpKQojZGVmaW5lIFNFR1BUUjE2KHB0cixzZWdwdHIpICgoTFBWT0lEKSgoQllURSopcHRyKygoRFdPUkQpU0VMRUNUT1JPRihzZWdwdHIpPDw0KStPRkZTRVRPRihzZWdwdHIpKSkKCnN0YXRpYyBMUERPU1RBU0sgZG9zX2N1cnJlbnQ7CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2godm9pZCk7CgpzdGF0aWMgdm9pZCBNWl9DcmVhdGVQU1AoIExQVk9JRCBscFBTUCwgV09SRCBlbnYgKQp7CiBQREIxNipwc3A9bHBQU1A7CgogcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogLyogc29tZSBwcm9ncmFtcyB1c2UgdGhpcyB0byBjYWxjdWxhdGUgaG93IG11Y2ggbWVtb3J5IHRoZXkgbmVlZCAqLwogcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsKIHBzcC0+ZW52aXJvbm1lbnQ9ZW52OwogLyogRklYTUU6IG1vcmUgUFNQIHN0dWZmICovCn0KCnN0YXRpYyB2b2lkIE1aX0ZpbGxQU1AoIExQVk9JRCBscFBTUCwgTFBDU1RSIGNtZGxpbmUgKQp7CiBQREIxNipwc3A9bHBQU1A7CiBjb25zdCBjaGFyKmNtZD1jbWRsaW5lP3N0cmNocihjbWRsaW5lLCcgJyk6TlVMTDsKCiAvKiBjb3B5IHBhcmFtZXRlcnMgKi8KIGlmIChjbWQpIHsKI2lmIDAKICAvKiBjb21tYW5kLmNvbSBkb2Vzbid0IGRvIHRoaXMgKi8KICB3aGlsZSAoKmNtZCA9PSAnICcpIGNtZCsrOwojZW5kaWYKICBwc3AtPmNtZExpbmVbMF09c3RybGVuKGNtZCk7CiAgc3RyY3B5KHBzcC0+Y21kTGluZSsxLGNtZCk7CiAgcHNwLT5jbWRMaW5lW3BzcC0+Y21kTGluZVswXSsxXT0nXHInOwogfSBlbHNlIHBzcC0+Y21kTGluZVsxXT0nXHInOwogLyogRklYTUU6IG1vcmUgUFNQIHN0dWZmICovCn0KCi8qIGRlZmF1bHQgSU5UIDA4IGhhbmRsZXI6IGluY3JlYXNlcyB0aW1lciB0aWNrIGNvdW50ZXIgYnV0IG5vdCBtdWNoIG1vcmUgKi8Kc3RhdGljIGNoYXIgaW50MDhbXT17CiAweENELDB4MUMsICAgICAgICAgICAvKiBpbnQgJDB4MWMgKi8KIDB4NTAsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVheCAqLwogMHgxRSwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWRzICovCiAweEI4LDB4NDAsMHgwMCwgICAgICAvKiBtb3Z3ICQweDQwLCVheCAqLwogMHg4RSwweEQ4LCAgICAgICAgICAgLyogbW92dyAlYXgsJWRzICovCiNpZiAwCiAweDgzLDB4MDYsMHg2QywweDAwLDB4MDEsIC8qIGFkZHcgJDEsKDB4NmMpICovCiAweDgzLDB4MTYsMHg2RSwweDAwLDB4MDAsIC8qIGFkY3cgJDAsKDB4NmUpICovCiNlbHNlCiAweDY2LDB4RkYsMHgwNiwweDZDLDB4MDAsIC8qIGluY2wgKDB4NmMpICovCiNlbmRpZgogMHhCMCwweDIwLCAgICAgICAgICAgLyogbW92YiAkMHgyMCwlYWwgKi8KIDB4RTYsMHgyMCwgICAgICAgICAgIC8qIG91dGIgJWFsLCQweDIwICovCiAweDFGLCAgICAgICAgICAgICAgICAvKiBwb3B3ICVheCAqLwogMHg1OCwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4Q0YgICAgICAgICAgICAgICAgIC8qIGlyZXQgKi8KfTsKCnN0YXRpYyB2b2lkIE1aX0luaXRIYW5kbGVycyggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIFdPUkQgc2VnOwogTFBCWVRFIHN0YXJ0PURPU01FTV9HZXRCbG9jayhzaXplb2YoaW50MDgpLCZzZWcpOwogbWVtY3B5KHN0YXJ0LGludDA4LHNpemVvZihpbnQwOCkpOwovKiBJTlQgMDg6IHBvaW50IGl0IGF0IG91ciB0aWNrLWluY3JlbWVudGluZyBoYW5kbGVyICovCiAoKFNFR1BUUiopKGxwRG9zVGFzay0+aW1nKSlbMHgwOF09UFRSX1NFR19PRkZfVE9fU0VHUFRSKHNlZywwKTsKLyogSU5UIDFDOiBqdXN0IHBvaW50IGl0IHRvIElSRVQsIHdlIGRvbid0IHdhbnQgdG8gaGFuZGxlIGl0IG91cnNlbHZlcyAqLwogKChTRUdQVFIqKShscERvc1Rhc2stPmltZykpWzB4MUNdPVBUUl9TRUdfT0ZGX1RPX1NFR1BUUihzZWcsc2l6ZW9mKGludDA4KS0xKTsKfQoKc3RhdGljIGNoYXIgZW50ZXJfeG1zW109ewovKiBYTVMgaG9va2FibGUgZW50cnkgcG9pbnQgKi8KIDB4RUIsMHgwMywgICAgICAgICAgIC8qIGptcCBlbnRyeSAqLwogMHg5MCwweDkwLDB4OTAsICAgICAgLyogbm9wO25vcDtub3AgKi8KICAgICAgICAgICAgICAgICAgICAgIC8qIGVudHJ5OiAqLwovKiByZWFsIGVudHJ5IHBvaW50ICovCi8qIGZvciBzaW1wbGljaXR5LCB3ZSdsbCBqdXN0IHVzZSB0aGUgc2FtZSBob29rIGFzIERQTUkgYmVsb3cgKi8KIDB4Q0QsMHgzMSwgICAgICAgICAgIC8qIGludCAkMHgzMSAqLwogMHhDQiAgICAgICAgICAgICAgICAgLyogbHJldCAqLwp9OwoKc3RhdGljIHZvaWQgTVpfSW5pdFhNUyggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2soc2l6ZW9mKGVudGVyX3htcyksJihscERvc1Rhc2stPnhtc19zZWcpKTsKIG1lbWNweShzdGFydCxlbnRlcl94bXMsc2l6ZW9mKGVudGVyX3htcykpOwp9CgpzdGF0aWMgY2hhciBlbnRlcl9wbVtdPXsKIDB4NTAsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVheCAqLwogMHg1MiwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWR4ICovCiAweDU1LCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYnAgKi8KIDB4ODksMHhFNSwgICAgICAgICAgIC8qIG1vdncgJXNwLCVicCAqLwovKiBnZXQgcmV0dXJuIENTICovCiAweDhCLDB4NTYsMHgwOCwgICAgICAvKiBtb3Z3IDgoJWJwKSwlZHggKi8KLyoganVzdCBjYWxsIGludCAzMSBoZXJlIHRvIGdldCBpbnRvIHByb3RlY3RlZCBtb2RlLi4uICovCi8qIGl0J2xsIGNoZWNrIHdoZXRoZXIgaXQgd2FzIGNhbGxlZCBmcm9tIGRwbWlfc2VnLi4uICovCiAweENELDB4MzEsICAgICAgICAgICAvKiBpbnQgJDB4MzEgKi8KLyogd2UgYXJlIG5vdyBpbiB0aGUgY29udGV4dCBvZiBhIDE2LWJpdCByZWxheSBjYWxsICovCi8qIG5lZWQgdG8gZml4dXAgb3VyIHN0YWNrOwogKiAxNi1iaXQgcmVsYXkgcmV0dXJuIGFkZHJlc3Mgd2lsbCBiZSBsb3N0LCBidXQgd2Ugd29uJ3Qgd29ycnkgcXVpdGUgeWV0ICovCiAweDhFLDB4RDAsICAgICAgICAgICAvKiBtb3Z3ICVheCwlc3MgKi8KIDB4NjYsMHgwRiwweEI3LDB4RTUsIC8qIG1vdnp3bCAlYnAsJWVzcCAqLwovKiBzZXQgcmV0dXJuIENTICovCiAweDg5LDB4NTYsMHgwOCwgICAgICAvKiBtb3Z3ICVkeCw4KCVicCkgKi8KIDB4NUQsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWJwICovCiAweDVBLCAgICAgICAgICAgICAgICAvKiBwb3B3ICVkeCAqLwogMHg1OCwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4Q0IgICAgICAgICAgICAgICAgIC8qIGxyZXQgKi8KfTsKCnN0YXRpYyB2b2lkIE1aX0luaXREUE1JKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogdW5zaWduZWQgc2l6ZT1zaXplb2YoZW50ZXJfcG0pOwogTFBCWVRFIHN0YXJ0PURPU01FTV9HZXRCbG9jayhzaXplLCYobHBEb3NUYXNrLT5kcG1pX3NlZykpOwogCiBscERvc1Rhc2stPmRwbWlfc2VsID0gU0VMRUNUT1JfQWxsb2NCbG9jayggc3RhcnQsIHNpemUsIFNFR01FTlRfQ09ERSwgRkFMU0UsIEZBTFNFICk7CgogbWVtY3B5KHN0YXJ0LGVudGVyX3BtLHNpemVvZihlbnRlcl9wbSkpOwp9CgpzdGF0aWMgV09SRCBNWl9Jbml0RW52aXJvbm1lbnQoIExQRE9TVEFTSyBscERvc1Rhc2ssIExQQ1NUUiBlbnYsIExQQ1NUUiBuYW1lICkKewogdW5zaWduZWQgc3o9MDsKIFdPUkQgc2VnOwogTFBTVFIgZW52YmxrOwoKIGlmIChlbnYpIHsKICAvKiBnZXQgc2l6ZSBvZiBlbnZpcm9ubWVudCBibG9jayAqLwogIHdoaWxlIChlbnZbc3orK10pIHN6Kz1zdHJsZW4oZW52K3N6KSsxOwogfSBlbHNlIHN6Kys7CiAvKiBhbGxvY2F0ZSBpdCAqLwogZW52YmxrPURPU01FTV9HZXRCbG9jayhzeitzaXplb2YoV09SRCkrc3RybGVuKG5hbWUpKzEsJnNlZyk7CiAvKiBmaWxsIGl0ICovCiBpZiAoZW52KSB7CiAgbWVtY3B5KGVudmJsayxlbnYsc3opOwogfSBlbHNlIGVudmJsa1swXT0wOwogLyogRE9TIDMueDogdGhlIGJsb2NrIGNvbnRhaW5zIDEgYWRkaXRpb25hbCBzdHJpbmcgKi8KICooV09SRCopKGVudmJsaytzeik9MTsKIC8qIGJlaW5nIHRoZSBwcm9ncmFtIG5hbWUgaXRzZWxmICovCiBzdHJjcHkoZW52YmxrK3N6K3NpemVvZihXT1JEKSxuYW1lKTsKIHJldHVybiBzZWc7Cn0KCnN0YXRpYyBCT09MIE1aX0luaXRNZW1vcnkoIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBpZiAobHBEb3NUYXNrLT5pbWcpIHJldHVybiBUUlVFOyAvKiBhbHJlYWR5IGFsbG9jYXRlZCAqLwoKIC8qIGFsbG9jYXRlIDFNQis2NEsgc2hhcmVkIG1lbW9yeSAqLwogbHBEb3NUYXNrLT5pbWdfb2ZzPVNUQVJUX09GRlNFVDsKI2lmZGVmIE1aX01BUFNFTEYKIGxwRG9zVGFzay0+aW1nPVZpcnR1YWxBbGxvYyhOVUxMLDB4MTEwMDAwLE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwogLyogbWFrZSBzdXJlIG1tYXAgYWNjZXB0cyBpdCAqLwogKChjaGFyKilscERvc1Rhc2stPmltZylbMHgxMEZGRkZdPTA7CiNlbHNlCiB0bXBuYW0obHBEb3NUYXNrLT5tbV9uYW1lKTsKLyogc3RyY3B5KGxwRG9zVGFzay0+bW1fbmFtZSwiL3RtcC9teWRvc2ltYWdlIik7ICovCiBscERvc1Rhc2stPm1tX2ZkPW9wZW4obHBEb3NUYXNrLT5tbV9uYW1lLE9fUkRXUnxPX0NSRUFUIC8qIHxPX1RSVU5DICovLFNfSVJVU1J8U19JV1VTUik7CiBpZiAobHBEb3NUYXNrLT5tbV9mZDwwKSBFUlIoImZpbGUgJXMgY291bGQgbm90IGJlIG9wZW5lZFxuIixscERvc1Rhc2stPm1tX25hbWUpOwogLyogZXhwYW5kIGZpbGUgdG8gMU1CKzY0SyAqLwogZnRydW5jYXRlKGxwRG9zVGFzay0+bW1fZmQsMHgxMTAwMDApOwogLyogbWFwIGl0IGluICovCiBscERvc1Rhc2stPmltZz1tbWFwKE5VTEwsMHgxMTAwMDAtU1RBUlRfT0ZGU0VULFBST1RfUkVBRHxQUk9UX1dSSVRFLE1BUF9TSEFSRUQsbHBEb3NUYXNrLT5tbV9mZCwwKTsKI2VuZGlmCiBpZiAobHBEb3NUYXNrLT5pbWc9PShMUFZPSUQpLTEpIHsKICBFUlIoImNvdWxkIG5vdCBtYXAgc2hhcmVkIG1lbW9yeSwgZXJyb3I9JXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICByZXR1cm4gRkFMU0U7CiB9CiBUUkFDRSgiRE9TIFZNODYgaW1hZ2UgbWFwcGVkIGF0ICUwOGx4XG4iLChEV09SRClscERvc1Rhc2stPmltZyk7CgogLyogaW5pdGlhbGl6ZSB0aGUgbWVtb3J5ICovCiBUUkFDRSgiSW5pdGlhbGl6aW5nIERPUyBtZW1vcnkgc3RydWN0dXJlc1xuIik7CiBET1NNRU1fSW5pdChUUlVFKTsKIE1aX0luaXRIYW5kbGVycyhscERvc1Rhc2spOwogTVpfSW5pdFhNUyhscERvc1Rhc2spOwogTVpfSW5pdERQTUkobHBEb3NUYXNrKTsKIHJldHVybiBUUlVFOwp9CgpCT09MIE1aX0xvYWRJbWFnZSggSE1PRFVMRSBtb2R1bGUsIEhBTkRMRSBoRmlsZSwgTFBDU1RSIGZpbGVuYW1lICkKewogIExQRE9TVEFTSyBscERvc1Rhc2sgPSBkb3NfY3VycmVudDsKICBJTUFHRV9OVF9IRUFERVJTICp3aW5faGRyID0gUEVfSEVBREVSKG1vZHVsZSk7CiAgSU1BR0VfRE9TX0hFQURFUiBtel9oZWFkZXI7CiAgRFdPUkQgaW1hZ2Vfc3RhcnQsaW1hZ2Vfc2l6ZSxtaW5fc2l6ZSxtYXhfc2l6ZSxhdmFpbDsKICBCWVRFKnBzcF9zdGFydCwqbG9hZF9zdGFydDsKICBpbnQgeCwgb2xkX2NvbT0wLCBhbGxvYz0wOwogIFNFR1BUUiByZWxvYzsKICBXT1JEIGVudl9zZWc7CiAgRFdPUkQgbGVuOwoKICB3aW5faGRyLT5PcHRpb25hbEhlYWRlci5TdWJzeXN0ZW0gPSBJTUFHRV9TVUJTWVNURU1fV0lORE9XU19DVUk7CiAgd2luX2hkci0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCA9IChMUEJZVEUpTVpfTGF1bmNoIC0gKExQQllURSltb2R1bGU7CgogIGlmICghbHBEb3NUYXNrKSB7CiAgICBhbGxvYz0xOwogICAgbHBEb3NUYXNrID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihET1NUQVNLKSk7CiAgICBscERvc1Rhc2stPm1tX2ZkID0gLTE7CiAgICBkb3NfY3VycmVudCA9IGxwRG9zVGFzazsKICB9CgogU2V0RmlsZVBvaW50ZXIoaEZpbGUsMCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCAgICFSZWFkRmlsZShoRmlsZSwmbXpfaGVhZGVyLHNpemVvZihtel9oZWFkZXIpLCZsZW4sTlVMTCkKICAgICB8fCBsZW4gIT0gc2l6ZW9mKG16X2hlYWRlcikgCiAgICAgfHwgbXpfaGVhZGVyLmVfbWFnaWMgIT0gSU1BR0VfRE9TX1NJR05BVFVSRSkgewogIG9sZF9jb209MTsgLyogYXNzdW1lIC5DT00gZmlsZSAqLwogIGltYWdlX3N0YXJ0PTA7CiAgaW1hZ2Vfc2l6ZT1HZXRGaWxlU2l6ZShoRmlsZSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgaWYgKChtel9oZWFkZXIuZV9jYmxwIT0wKSYmKG16X2hlYWRlci5lX2NibHAhPTQpKSBpbWFnZV9zaXplLT01MTItbXpfaGVhZGVyLmVfY2JscDsKICBpbWFnZV9zaXplLT1pbWFnZV9zdGFydDsKICBtaW5fc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWluYWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiAgbWF4X3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21heGFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogfQoKIE1aX0luaXRNZW1vcnkobHBEb3NUYXNrKTsKCiAvKiBhbGxvY2F0ZSBlbnZpcm9ubWVudCBibG9jayAqLwogZW52X3NlZz1NWl9Jbml0RW52aXJvbm1lbnQobHBEb3NUYXNrLEdldEVudmlyb25tZW50U3RyaW5nc0EoKSxmaWxlbmFtZSk7CgogLyogYWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgZXhlY3V0YWJsZSAqLwogVFJBQ0UoIkFsbG9jYXRpbmcgRE9TIG1lbW9yeSAobWluPSVsZCwgbWF4PSVsZClcbiIsbWluX3NpemUsbWF4X3NpemUpOwogYXZhaWw9RE9TTUVNX0F2YWlsYWJsZSgpOwogaWYgKGF2YWlsPG1pbl9zaXplKSB7CiAgRVJSKCJpbnN1ZmZpY2llbnQgRE9TIG1lbW9yeVxuIik7CiAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICBnb3RvIGxvYWRfZXJyb3I7CiB9CiBpZiAoYXZhaWw+bWF4X3NpemUpIGF2YWlsPW1heF9zaXplOwogcHNwX3N0YXJ0PURPU01FTV9HZXRCbG9jayhhdmFpbCwmbHBEb3NUYXNrLT5wc3Bfc2VnKTsKIGlmICghcHNwX3N0YXJ0KSB7CiAgRVJSKCJlcnJvciBhbGxvY2F0aW5nIERPUyBtZW1vcnlcbiIpOwogIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgZ290byBsb2FkX2Vycm9yOwogfQogbHBEb3NUYXNrLT5sb2FkX3NlZz1scERvc1Rhc2stPnBzcF9zZWcrKG9sZF9jb20/MDpQU1BfU0laRSk7CiBsb2FkX3N0YXJ0PXBzcF9zdGFydCsoUFNQX1NJWkU8PDQpOwogTVpfQ3JlYXRlUFNQKHBzcF9zdGFydCwgZW52X3NlZyk7CgogLyogbG9hZCBleGVjdXRhYmxlIGltYWdlICovCiBUUkFDRSgibG9hZGluZyBET1MgJXMgaW1hZ2UsICUwOGx4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBTZXRGaWxlUG9pbnRlcihoRmlsZSxpbWFnZV9zdGFydCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCFSZWFkRmlsZShoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUsJmxlbixOVUxMKSB8fCBsZW4gIT0gaW1hZ2Vfc2l6ZSkgewogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICBnb3RvIGxvYWRfZXJyb3I7CiB9CgogaWYgKG16X2hlYWRlci5lX2NybGMpIHsKICAvKiBsb2FkIHJlbG9jYXRpb24gdGFibGUgKi8KICBUUkFDRSgibG9hZGluZyBET1MgRVhFIHJlbG9jYXRpb24gdGFibGUsICVkIGVudHJpZXNcbiIsbXpfaGVhZGVyLmVfY3JsYyk7CiAgLyogRklYTUU6IGlzIHRoaXMgdG9vIHNsb3cgd2l0aG91dCByZWFkIGJ1ZmZlcmluZz8gKi8KICBTZXRGaWxlUG9pbnRlcihoRmlsZSxtel9oZWFkZXIuZV9sZmFybGMsTlVMTCxGSUxFX0JFR0lOKTsKICBmb3IgKHg9MDsgeDxtel9oZWFkZXIuZV9jcmxjOyB4KyspIHsKICAgaWYgKCFSZWFkRmlsZShoRmlsZSwmcmVsb2Msc2l6ZW9mKHJlbG9jKSwmbGVuLE5VTEwpIHx8IGxlbiAhPSBzaXplb2YocmVsb2MpKSB7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgICBnb3RvIGxvYWRfZXJyb3I7CiAgIH0KICAgKihXT1JEKilTRUdQVFIxNihsb2FkX3N0YXJ0LHJlbG9jKSs9bHBEb3NUYXNrLT5sb2FkX3NlZzsKICB9CiB9CgogbHBEb3NUYXNrLT5pbml0X2NzPWxwRG9zVGFzay0+bG9hZF9zZWcrbXpfaGVhZGVyLmVfY3M7CiBscERvc1Rhc2stPmluaXRfaXA9bXpfaGVhZGVyLmVfaXA7CiBscERvc1Rhc2stPmluaXRfc3M9bHBEb3NUYXNrLT5sb2FkX3NlZyttel9oZWFkZXIuZV9zczsKIGxwRG9zVGFzay0+aW5pdF9zcD1tel9oZWFkZXIuZV9zcDsKCiAgVFJBQ0UoImVudHJ5IHBvaW50OiAlMDR4OiUwNHhcbiIsbHBEb3NUYXNrLT5pbml0X2NzLGxwRG9zVGFzay0+aW5pdF9pcCk7CgogIGlmICghTVpfSW5pdFRhc2sobHBEb3NUYXNrKSkgewogICAgTVpfS2lsbFRhc2sobHBEb3NUYXNrKTsKICAgIFNldExhc3RFcnJvcihFUlJPUl9HRU5fRkFJTFVSRSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICByZXR1cm4gVFJVRTsKCmxvYWRfZXJyb3I6CiAgaWYgKGFsbG9jKSB7CiAgICBkb3NfY3VycmVudCA9IE5VTEw7CiAgICBpZiAobHBEb3NUYXNrLT5tbV9uYW1lWzBdIT0wKSB7CiAgICAgIGlmIChscERvc1Rhc2stPmltZyE9TlVMTCkgbXVubWFwKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLVNUQVJUX09GRlNFVCk7CiAgICAgIGlmIChscERvc1Rhc2stPm1tX2ZkPj0wKSBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKICAgICAgdW5saW5rKGxwRG9zVGFzay0+bW1fbmFtZSk7CiAgICB9IGVsc2UKICAgICAgaWYgKGxwRG9zVGFzay0+aW1nIT1OVUxMKSBWaXJ0dWFsRnJlZShscERvc1Rhc2stPmltZywweDExMDAwMCxNRU1fUkVMRUFTRSk7CiAgfQoKICByZXR1cm4gRkFMU0U7Cn0KCkxQRE9TVEFTSyBNWl9BbGxvY0RQTUlUYXNrKCB2b2lkICkKewogIExQRE9TVEFTSyBscERvc1Rhc2sgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKERPU1RBU0spKTsKCiAgaWYgKGxwRG9zVGFzaykgewogICAgbHBEb3NUYXNrLT5tbV9mZCA9IC0xOwogICAgZG9zX2N1cnJlbnQgPSBscERvc1Rhc2s7CiAgICBNWl9Jbml0TWVtb3J5KGxwRG9zVGFzayk7CiAgfQogIHJldHVybiBscERvc1Rhc2s7Cn0KCnN0YXRpYyB2b2lkIE1aX0luaXRUaW1lciggTFBET1NUQVNLIGxwRG9zVGFzaywgaW50IHZlciApCnsKIGlmICh2ZXI8MSkgewogIC8qIGNhbid0IG1ha2UgdGltZXIgdGlja3MgKi8KIH0gZWxzZSB7CiAgaW50IGZ1bmM7CiAgc3RydWN0IHRpbWV2YWwgdGltOwoKICAvKiBzdGFydCBkb3Ntb2QgdGltZXIgYXQgNTVtcyAoMTguMkh6KSAqLwogIGZ1bmM9RE9TTU9EX1NFVF9USU1FUjsKICB0aW0udHZfc2VjPTA7IHRpbS50dl91c2VjPTU0OTI1OwogIHdyaXRlKGxwRG9zVGFzay0+d3JpdGVfcGlwZSwmZnVuYyxzaXplb2YoZnVuYykpOwogIHdyaXRlKGxwRG9zVGFzay0+d3JpdGVfcGlwZSwmdGltLHNpemVvZih0aW0pKTsKIH0KfQoKQk9PTCBNWl9Jbml0VGFzayggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKICBpbnQgd3JpdGVfZmRbMl0seF9mZDsKICBwaWRfdCBjaGlsZDsKICBjaGFyICpmbmFtZSwqZmFyZyxhcmdbMTZdLGZwcm9jWzY0XSxwYXRoWzI1Nl0sKmZwYXRoOwogIHN0cnVjdCBnZXRfcmVhZF9mZF9yZXF1ZXN0ICpyX3JlcSA9IGdldF9yZXFfYnVmZmVyKCk7CiAgc3RydWN0IGdldF93cml0ZV9mZF9yZXF1ZXN0ICp3X3JlcSA9IGdldF9yZXFfYnVmZmVyKCk7CgogIGlmICghbHBEb3NUYXNrKSByZXR1cm4gRkFMU0U7CiAgLyogY3JlYXRlIHBpcGVzICovCiAgaWYgKCFDcmVhdGVQaXBlKCYobHBEb3NUYXNrLT5oUmVhZFBpcGUpLCYobHBEb3NUYXNrLT5oWFBpcGUpLE5VTEwsMCkpIHJldHVybiBGQUxTRTsKICBpZiAocGlwZSh3cml0ZV9mZCk8MCkgewogICAgQ2xvc2VIYW5kbGUobHBEb3NUYXNrLT5oUmVhZFBpcGUpOwogICAgQ2xvc2VIYW5kbGUobHBEb3NUYXNrLT5oWFBpcGUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgcl9yZXEtPmhhbmRsZSA9IGxwRG9zVGFzay0+aFJlYWRQaXBlOwogIHNlcnZlcl9jYWxsX2ZkKCBSRVFfR0VUX1JFQURfRkQsIC0xLCAmbHBEb3NUYXNrLT5yZWFkX3BpcGUgKTsKICB3X3JlcS0+aGFuZGxlID0gbHBEb3NUYXNrLT5oWFBpcGU7CiAgc2VydmVyX2NhbGxfZmQoIFJFUV9HRVRfV1JJVEVfRkQsIC0xLCAmeF9mZCApOwoKICBUUkFDRSgid2luMzIgcGlwZTogcmVhZD0lZCwgd3JpdGU9JWQsIHVuaXggcGlwZTogcmVhZD0lZCwgd3JpdGU9JWRcbiIsCgkgICAgICAgbHBEb3NUYXNrLT5oUmVhZFBpcGUsbHBEb3NUYXNrLT5oWFBpcGUsbHBEb3NUYXNrLT5yZWFkX3BpcGUseF9mZCk7CiAgVFJBQ0UoIm91dGJvdW5kIHVuaXggcGlwZTogcmVhZD0lZCwgd3JpdGU9JWQsIHBpZD0lZFxuIix3cml0ZV9mZFswXSx3cml0ZV9mZFsxXSxnZXRwaWQoKSk7CgogIGxwRG9zVGFzay0+d3JpdGVfcGlwZT13cml0ZV9mZFsxXTsKCiAgbHBEb3NUYXNrLT5oQ29uSW5wdXQ9R2V0U3RkSGFuZGxlKFNURF9JTlBVVF9IQU5ETEUpOwogIGxwRG9zVGFzay0+aENvbk91dHB1dD1HZXRTdGRIYW5kbGUoU1REX09VVFBVVF9IQU5ETEUpOwoKICAvKiBpZiB3ZSBoYXZlIGEgbWFwcGluZyBmaWxlLCB1c2UgaXQgKi8KICBmbmFtZT1scERvc1Rhc2stPm1tX25hbWU7IGZhcmc9TlVMTDsKICBpZiAoIWZuYW1lWzBdKSB7CiAgICAvKiBvdGhlcndpc2UsIG1hcCBvdXIgb3duIG1lbW9yeSBpbWFnZSAqLwogICAgc3ByaW50ZihmcHJvYywiL3Byb2MvJWQvbWVtIixnZXRwaWQoKSk7CiAgICBzcHJpbnRmKGFyZywiJWxkIiwodW5zaWduZWQgbG9uZylscERvc1Rhc2stPmltZyk7CiAgICBmbmFtZT1mcHJvYzsgZmFyZz1hcmc7CiAgfQoKICBUUkFDRSgiTG9hZGluZyBET1MgVk0gc3VwcG9ydCBtb2R1bGVcbiIpOwogIGlmICgoY2hpbGQ9Zm9yaygpKTwwKSB7CiAgICBjbG9zZSh3cml0ZV9mZFswXSk7CiAgICBjbG9zZShscERvc1Rhc2stPnJlYWRfcGlwZSk7CiAgICBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwogICAgY2xvc2UoeF9mZCk7CiAgICBDbG9zZUhhbmRsZShscERvc1Rhc2stPmhSZWFkUGlwZSk7CiAgICBDbG9zZUhhbmRsZShscERvc1Rhc2stPmhYUGlwZSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQogaWYgKGNoaWxkIT0wKSB7CiAgLyogcGFyZW50IHByb2Nlc3MgKi8KICBpbnQgcmV0OwoKICBjbG9zZSh3cml0ZV9mZFswXSk7CiAgY2xvc2UoeF9mZCk7CiAgbHBEb3NUYXNrLT50YXNrPWNoaWxkOwogIC8qIHdhaXQgZm9yIGNoaWxkIHByb2Nlc3MgdG8gc2lnbmFsIHJlYWRpbmVzcyAqLwogIHdoaWxlICgxKSB7CiAgICBpZiAocmVhZChscERvc1Rhc2stPnJlYWRfcGlwZSwmcmV0LHNpemVvZihyZXQpKT09c2l6ZW9mKHJldCkpIGJyZWFrOwogICAgaWYgKChlcnJubz09RUlOVFIpfHwoZXJybm89PUVBR0FJTikpIGNvbnRpbnVlOwogICAgLyogZmFpbHVyZSAqLwogICAgRVJSKCJkb3Ntb2QgaGFzIGZhaWxlZCB0byBpbml0aWFsaXplXG4iKTsKICAgIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KICAvKiB0aGUgY2hpbGQgaGFzIG5vdyBtbWFwZWQgdGhlIHRlbXAgZmlsZSwgaXQncyBub3cgc2FmZSB0byB1bmxpbmsuCiAgICogZG8gaXQgaGVyZSB0byBhdm9pZCBsZWF2aW5nIGEgbWVzcyBpbiAvdG1wIGlmL3doZW4gV2luZSBjcmFzaGVzLi4uICovCiAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgdW5saW5rKGxwRG9zVGFzay0+bW1fbmFtZSk7CiAgLyogc3RhcnQgc2ltdWxhdGVkIHN5c3RlbSB0aW1lciAqLwogIE1aX0luaXRUaW1lcihscERvc1Rhc2sscmV0KTsKICBpZiAocmV0PDIpIHsKICAgIEVSUigiZG9zbW9kIHZlcnNpb24gdG9vIG9sZCEgUGxlYXNlIGluc3RhbGwgbmV3ZXIgZG9zbW9kIHByb3Blcmx5XG4iKTsKICAgIEVSUigiSWYgeW91IGRvbid0LCB0aGUgbmV3IGRvc21vZCBldmVudCBoYW5kbGluZyBzeXN0ZW0gd2lsbCBub3Qgd29ya1xuIik7CiAgfQogIC8qIGFsbCBzeXN0ZW1zIGFyZSBub3cgZ28gKi8KIH0gZWxzZSB7CiAgLyogY2hpbGQgcHJvY2VzcyAqLwogIGNsb3NlKGxwRG9zVGFzay0+cmVhZF9waXBlKTsKICBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwogIC8qIHB1dCBvdXIgcGlwZXMgc29tZXdoZXJlIGRvc21vZCBjYW4gZmluZCB0aGVtICovCiAgZHVwMih3cml0ZV9mZFswXSwwKTsgLyogc3RkaW4gKi8KICBkdXAyKHhfZmQsMSk7ICAgICAgICAvKiBzdGRvdXQgKi8KICAvKiBub3cgbG9hZCBkb3Ntb2QgKi8KICAvKiBjaGVjayBhcmd2WzBdLWRlcml2ZWQgcGF0aHMgZmlyc3QsIHNpbmNlIHRoZSBuZXdlc3QgZG9zbW9kIGlzIG1vc3QgbGlrZWx5IHRoZXJlCiAgICogKGF0IGxlYXN0IGl0IHdhcyBvbmNlIGZvciBBbmRyZWFzIE1vaHIsIHNvIEkgZGVjaWRlZCB0byBtYWtlIGl0IGVhc2llciBmb3IgaGltKSAqLwogIGZwYXRoPXN0cnJjaHIoc3RyY3B5KHBhdGgsZnVsbF9hcmd2MCksJy8nKTsKICBpZiAoZnBhdGgpIHsKICAgc3RyY3B5KGZwYXRoLCIvZG9zbW9kIik7CiAgIGV4ZWNsKHBhdGgsZm5hbWUsZmFyZyxOVUxMKTsKICAgc3RyY3B5KGZwYXRoLCIvbG9hZGVyL2Rvcy9kb3Ntb2QiKTsKICAgZXhlY2wocGF0aCxmbmFtZSxmYXJnLE5VTEwpOwogIH0KICAvKiBva2F5LCBpdCB3YXNuJ3QgdGhlcmUsIHRyeSBpbiB0aGUgcGF0aCAqLwogIGV4ZWNscCgiZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIC8qIGxhc3QgZGVzcGVyYXRlIGF0dGVtcHRzOiBjdXJyZW50IGRpcmVjdG9yeSAqLwogIGV4ZWNsKCJkb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgLyogYW5kLCBqdXN0IGZvciBjb21wbGV0ZW5lc3MuLi4gKi8KICBleGVjbCgibG9hZGVyL2Rvcy9kb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgLyogaWYgZmFpbHVyZSwgZXhpdCAqLwogIEVSUigiRmFpbGVkIHRvIHNwYXduIGRvc21vZCwgZXJyb3I9JXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICBleGl0KDEpOwogfQogcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCh2b2lkKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IE1aX0N1cnJlbnQoKTsKICBCWVRFICpwc3Bfc3RhcnQgPSAoQllURSopbHBEb3NUYXNrLT5pbWcgKyAoKERXT1JEKWxwRG9zVGFzay0+cHNwX3NlZyA8PCA0KTsKCiAgTVpfRmlsbFBTUChwc3Bfc3RhcnQsIEdldENvbW1hbmRMaW5lQSgpKTsKCiAgRE9TVk1fRW50ZXIoTlVMTCk7Cn0KCnZvaWQgTVpfS2lsbFRhc2soIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiAgRE9TRVZFTlQgKmV2ZW50LCpwX2V2ZW50OwogIERPU1NZU1RFTSAqc3lzLCpwX3N5czsKCiAgVFJBQ0UoImtpbGxpbmcgRE9TIHRhc2tcbiIpOwogIFZHQV9DbGVhbigpOwogIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICAgIG11bm1hcChscERvc1Rhc2stPmltZywweDExMDAwMC1TVEFSVF9PRkZTRVQpOwogICAgY2xvc2UobHBEb3NUYXNrLT5tbV9mZCk7CiAgfSBlbHNlIFZpcnR1YWxGcmVlKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLE1FTV9SRUxFQVNFKTsKICBjbG9zZShscERvc1Rhc2stPnJlYWRfcGlwZSk7CiAgY2xvc2UobHBEb3NUYXNrLT53cml0ZV9waXBlKTsKICBDbG9zZUhhbmRsZShscERvc1Rhc2stPmhSZWFkUGlwZSk7CiAgQ2xvc2VIYW5kbGUobHBEb3NUYXNrLT5oWFBpcGUpOwogIGtpbGwobHBEb3NUYXNrLT50YXNrLFNJR1RFUk0pOwovKiBmcmVlIG1lbW9yeSBhbGxvY2F0ZWQgZm9yIGV2ZW50cyBhbmQgc3lzdGVtcyAqLwojZGVmaW5lIERGUkVFKHZhcixwdmFyLHN2YXIpIFwKICB2YXIgPSBscERvc1Rhc2stPnN2YXI7IFwKICB3aGlsZSAodmFyKSB7IFwKICAgIGlmICh2YXItPmRhdGEpIGZyZWUodmFyLT5kYXRhKTsgXAogICAgcHZhciA9IHZhci0+bmV4dDsgZnJlZSh2YXIpOyB2YXIgPSBwdmFyOyBcCiAgfQoKICBERlJFRShldmVudCxwX2V2ZW50LHBlbmRpbmcpCiAgREZSRUUoZXZlbnQscF9ldmVudCxjdXJyZW50KQogIERGUkVFKHN5cyxwX3N5cyxzeXMpCgojdW5kZWYgREZSRUUKCiNpZiAwCiAgLyogRklYTUU6IHRoaXMgc2VlbXMgdG8gY3Jhc2ggKi8KICBpZiAobHBEb3NUYXNrLT5kcG1pX3NlbCkKICAgIFNFTEVDVE9SX0ZyZWVCbG9jayhscERvc1Rhc2stPmRwbWlfc2VsLCAxKTsKI2VuZGlmCn0KCkxQRE9TVEFTSyBNWl9DdXJyZW50KCB2b2lkICkKewogIHJldHVybiBkb3NfY3VycmVudDsKfQoKI2Vsc2UgLyogIU1aX1NVUFBPUlRFRCAqLwoKQk9PTCBNWl9Mb2FkSW1hZ2UoIEhNT0RVTEUgbW9kdWxlLCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSApCnsKIFdBUk4oIkRPUyBleGVjdXRhYmxlcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlXG4iKTsKIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKIHJldHVybiBGQUxTRTsKfQoKTFBET1NUQVNLIE1aX0N1cnJlbnQoIHZvaWQgKQp7CiAgcmV0dXJuIE5VTEw7Cn0KCiNlbmRpZgo=