LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgInNlbGVjdG9ycy5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc21vZC5oIgojaW5jbHVkZSAib3B0aW9ucy5oIgojaW5jbHVkZSAidmdhLmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwobW9kdWxlKTsKCnN0YXRpYyBMUERPU1RBU0sgZG9zX2N1cnJlbnQ7CgojaWZkZWYgTVpfU1VQUE9SVEVECgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgovKiBkZWZpbmUgdGhpcyB0byB0cnkgbWFwcGluZyB0aHJvdWdoIC9wcm9jL3BpZC9tZW0gaW5zdGVhZCBvZiBhIHRlbXAgZmlsZSwKICAgYnV0IExpbnVzIGRvZXNuJ3QgbGlrZSBtbWFwcGluZyAvcHJvYy9waWQvbWVtLCBzbyBpdCBkb2Vzbid0IHdvcmsgZm9yIG1lICovCiN1bmRlZiBNWl9NQVBTRUxGCgojZGVmaW5lIEJJT1NfREFUQV9TRUdNRU5UIDB4NDAKI2RlZmluZSBQU1BfU0laRSAweDEwCgojZGVmaW5lIFNFRzE2KHB0cixzZWcpICgoTFBWT0lEKSgoQllURSopcHRyKygoRFdPUkQpKHNlZyk8PDQpKSkKI2RlZmluZSBTRUdQVFIxNihwdHIsc2VncHRyKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKVNFTEVDVE9ST0Yoc2VncHRyKTw8NCkrT0ZGU0VUT0Yoc2VncHRyKSkpCgovKiBzdHJ1Y3R1cmVzIGZvciBFWEVDICovCgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBlbnZfc2VnOwogIERXT1JEIGNtZGxpbmUgV0lORV9QQUNLRUQ7CiAgRFdPUkQgZmNiMSBXSU5FX1BBQ0tFRDsKICBEV09SRCBmY2IyIFdJTkVfUEFDS0VEOwogIFdPUkQgaW5pdF9zcDsKICBXT1JEIGluaXRfc3M7CiAgV09SRCBpbml0X2lwOwogIFdPUkQgaW5pdF9jczsKfSBFeGVjQmxvY2s7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBsb2FkX3NlZzsKICBXT1JEIHJlbF9zZWc7Cn0gT3ZlcmxheUJsb2NrOwoKLyogZ2xvYmFsIHZhcmlhYmxlcyAqLwoKc3RhdGljIFdPUkQgaW5pdF9jcyxpbml0X2lwLGluaXRfc3MsaW5pdF9zcDsKc3RhdGljIGNoYXIgbW1fbmFtZVsxMjhdOwoKaW50IHJlYWRfcGlwZSwgd3JpdGVfcGlwZTsKSEFORExFIGhSZWFkUGlwZSwgaFdyaXRlUGlwZTsKcGlkX3QgZG9zbW9kX3BpZDsKCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCh2b2lkKTsKc3RhdGljIEJPT0wgTVpfSW5pdFRhc2sodm9pZCk7CnN0YXRpYyB2b2lkIE1aX0tpbGxUYXNrKHZvaWQpOwoKc3RhdGljIHZvaWQgTVpfQ3JlYXRlUFNQKCBMUFZPSUQgbHBQU1AsIFdPUkQgZW52LCBXT1JEIHBhciApCnsKICBQREIxNipwc3A9bHBQU1A7CgogIHBzcC0+aW50MjA9MHgyMENEOyAvKiBpbnQgMjAgKi8KICAvKiBzb21lIHByb2dyYW1zIHVzZSB0aGlzIHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgdGhleSBuZWVkICovCiAgcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsgLyogRklYTUU6IHVzZSBhIHJlYWwgdmFsdWUgKi8KICAvKiBGSVhNRTogZGlzcGF0Y2hlciAqLwogIHBzcC0+c2F2ZWRpbnQyMiA9IElOVF9HZXRSTUhhbmRsZXIoMHgyMik7CiAgcHNwLT5zYXZlZGludDIzID0gSU5UX0dldFJNSGFuZGxlcigweDIzKTsKICBwc3AtPnNhdmVkaW50MjQgPSBJTlRfR2V0Uk1IYW5kbGVyKDB4MjQpOwogIHBzcC0+cGFyZW50UFNQPXBhcjsKICBwc3AtPmVudmlyb25tZW50PWVudjsKICAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKc3RhdGljIHZvaWQgTVpfRmlsbFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kbGluZSApCnsKIFBEQjE2KnBzcD1scFBTUDsKIGNvbnN0IGNoYXIqY21kPWNtZGxpbmU/c3RyY2hyKGNtZGxpbmUsJyAnKTpOVUxMOwoKIC8qIGNvcHkgcGFyYW1ldGVycyAqLwogaWYgKGNtZCkgewojaWYgMAogIC8qIGNvbW1hbmQuY29tIGRvZXNuJ3QgZG8gdGhpcyAqLwogIHdoaWxlICgqY21kID09ICcgJykgY21kKys7CiNlbmRpZgogIHBzcC0+Y21kTGluZVswXT1zdHJsZW4oY21kKTsKICBzdHJjcHkocHNwLT5jbWRMaW5lKzEsY21kKTsKICBwc3AtPmNtZExpbmVbcHNwLT5jbWRMaW5lWzBdKzFdPSdccic7CiB9IGVsc2UgcHNwLT5jbWRMaW5lWzFdPSdccic7CiAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKLyogZGVmYXVsdCBJTlQgMDggaGFuZGxlcjogaW5jcmVhc2VzIHRpbWVyIHRpY2sgY291bnRlciBidXQgbm90IG11Y2ggbW9yZSAqLwpzdGF0aWMgY2hhciBpbnQwOFtdPXsKIDB4Q0QsMHgxQywgICAgICAgICAgIC8qIGludCAkMHgxYyAqLwogMHg1MCwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWF4ICovCiAweDFFLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlZHMgKi8KIDB4QjgsMHg0MCwweDAwLCAgICAgIC8qIG1vdncgJDB4NDAsJWF4ICovCiAweDhFLDB4RDgsICAgICAgICAgICAvKiBtb3Z3ICVheCwlZHMgKi8KI2lmIDAKIDB4ODMsMHgwNiwweDZDLDB4MDAsMHgwMSwgLyogYWRkdyAkMSwoMHg2YykgKi8KIDB4ODMsMHgxNiwweDZFLDB4MDAsMHgwMCwgLyogYWRjdyAkMCwoMHg2ZSkgKi8KI2Vsc2UKIDB4NjYsMHhGRiwweDA2LDB4NkMsMHgwMCwgLyogaW5jbCAoMHg2YykgKi8KI2VuZGlmCiAweEIwLDB4MjAsICAgICAgICAgICAvKiBtb3ZiICQweDIwLCVhbCAqLwogMHhFNiwweDIwLCAgICAgICAgICAgLyogb3V0YiAlYWwsJDB4MjAgKi8KIDB4MUYsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweDU4LCAgICAgICAgICAgICAgICAvKiBwb3B3ICVheCAqLwogMHhDRiAgICAgICAgICAgICAgICAgLyogaXJldCAqLwp9OwoKc3RhdGljIHZvaWQgTVpfSW5pdEhhbmRsZXJzKHZvaWQpCnsKIFdPUkQgc2VnOwogTFBCWVRFIHN0YXJ0PURPU01FTV9HZXRCbG9jayhzaXplb2YoaW50MDgpLCZzZWcpOwogbWVtY3B5KHN0YXJ0LGludDA4LHNpemVvZihpbnQwOCkpOwovKiBJTlQgMDg6IHBvaW50IGl0IGF0IG91ciB0aWNrLWluY3JlbWVudGluZyBoYW5kbGVyICovCiAoKFNFR1BUUiopMClbMHgwOF09UFRSX1NFR19PRkZfVE9fU0VHUFRSKHNlZywwKTsKLyogSU5UIDFDOiBqdXN0IHBvaW50IGl0IHRvIElSRVQsIHdlIGRvbid0IHdhbnQgdG8gaGFuZGxlIGl0IG91cnNlbHZlcyAqLwogKChTRUdQVFIqKTApWzB4MUNdPVBUUl9TRUdfT0ZGX1RPX1NFR1BUUihzZWcsc2l6ZW9mKGludDA4KS0xKTsKfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fR2V0QmxvY2soc3orc2l6ZW9mKFdPUkQpK3N0cmxlbihuYW1lKSsxLCZzZWcpOwogLyogZmlsbCBpdCAqLwogaWYgKGVudikgewogIG1lbWNweShlbnZibGssZW52LHN6KTsKIH0gZWxzZSBlbnZibGtbMF09MDsKIC8qIERPUyAzLng6IHRoZSBibG9jayBjb250YWlucyAxIGFkZGl0aW9uYWwgc3RyaW5nICovCiAqKFdPUkQqKShlbnZibGsrc3opPTE7CiAvKiBiZWluZyB0aGUgcHJvZ3JhbSBuYW1lIGl0c2VsZiAqLwogc3RyY3B5KGVudmJsaytzeitzaXplb2YoV09SRCksbmFtZSk7CiByZXR1cm4gc2VnOwp9CgpzdGF0aWMgQk9PTCBNWl9Jbml0TWVtb3J5KHZvaWQpCnsKICAgIGludCBtbV9mZDsKICAgIHZvaWQgKmltZ19iYXNlOwoKICAgIC8qIGluaXRpYWxpemUgdGhlIG1lbW9yeSAqLwogICAgVFJBQ0UoIkluaXRpYWxpemluZyBET1MgbWVtb3J5IHN0cnVjdHVyZXNcbiIpOwogICAgRE9TTUVNX0luaXQoVFJVRSk7CgogICAgLyogYWxsb2NhdGUgMU1CKzY0SyBzaGFyZWQgbWVtb3J5ICovCiAgICB0bXBuYW0obW1fbmFtZSk7CiAgICAvKiBzdHJjcHkobW1fbmFtZSwiL3RtcC9teWRvc2ltYWdlIik7ICovCiAgICBtbV9mZCA9IG9wZW4obW1fbmFtZSxPX1JEV1J8T19DUkVBVCAvKiB8T19UUlVOQyAqLyxTX0lSVVNSfFNfSVdVU1IpOwogICAgaWYgKG1tX2ZkIDwgMCkgRVJSKCJmaWxlICVzIGNvdWxkIG5vdCBiZSBvcGVuZWRcbiIsbW1fbmFtZSk7CiAgICAvKiBmaWxsIHRoZSBmaWxlIHdpdGggdGhlIERPUyBtZW1vcnkgKi8KICAgIGlmICh3cml0ZSggbW1fZmQsIE5VTEwsIDB4MTEwMDAwICkgIT0gMHgxMTAwMDApIEVSUigiY2Fubm90IHdyaXRlIERPUyBtZW1cbiIpOwogICAgLyogbWFwIGl0IGluICovCiAgICBpbWdfYmFzZSA9IG1tYXAoTlVMTCwweDExMDAwMCxQUk9UX1JFQUR8UFJPVF9XUklURXxQUk9UX0VYRUMsTUFQX1NIQVJFRHxNQVBfRklYRUQsbW1fZmQsMCk7CiAgICBjbG9zZSggbW1fZmQgKTsKCiAgICBpZiAoaW1nX2Jhc2UpCiAgICB7CiAgICAgICAgRVJSKCJjb3VsZCBub3QgbWFwIHNoYXJlZCBtZW1vcnksIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgTVpfSW5pdEhhbmRsZXJzKCk7CiAgICByZXR1cm4gVFJVRTsKfQoKQk9PTCBNWl9Eb0xvYWRJbWFnZSggSE1PRFVMRSBtb2R1bGUsIEhBTkRMRSBoRmlsZSwgTFBDU1RSIGZpbGVuYW1lLCBPdmVybGF5QmxvY2sgKm9ibGsgKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IGRvc19jdXJyZW50OwogIElNQUdFX0RPU19IRUFERVIgbXpfaGVhZGVyOwogIERXT1JEIGltYWdlX3N0YXJ0LGltYWdlX3NpemUsbWluX3NpemUsbWF4X3NpemUsYXZhaWw7CiAgQllURSpwc3Bfc3RhcnQsKmxvYWRfc3RhcnQsKm9sZGVudjsKICBpbnQgeCwgb2xkX2NvbT0wLCBhbGxvYzsKICBTRUdQVFIgcmVsb2M7CiAgV09SRCBlbnZfc2VnLCBsb2FkX3NlZywgcmVsX3NlZywgb2xkcHNwX3NlZzsKICBEV09SRCBsZW47CgogIGlmIChscERvc1Rhc2spIHsKICAgIC8qIERPUyBwcm9jZXNzIGFscmVhZHkgcnVubmluZywgaW5oZXJpdCBmcm9tIGl0ICovCiAgICBQREIxNiogcGFyX3BzcCA9IChQREIxNiopKChEV09SRClscERvc1Rhc2stPnBzcF9zZWcgPDwgNCk7CiAgICBhbGxvYz0wOwogICAgb2xkZW52ID0gKExQQllURSkoKERXT1JEKXBhcl9wc3AtPmVudmlyb25tZW50IDw8IDQpOwogICAgb2xkcHNwX3NlZyA9IGxwRG9zVGFzay0+cHNwX3NlZzsKICB9IGVsc2UgewogICAgLyogYWxsb2NhdGUgbmV3IERPUyBwcm9jZXNzLCBpbmhlcml0aW5nIGZyb20gV2luZSBlbnZpcm9ubWVudCAqLwogICAgYWxsb2M9MTsKICAgIGxwRG9zVGFzayA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoRE9TVEFTSykpOwogICAgZG9zX2N1cnJlbnQgPSBscERvc1Rhc2s7CiAgICBvbGRlbnYgPSBHZXRFbnZpcm9ubWVudFN0cmluZ3NBKCk7CiAgICBvbGRwc3Bfc2VnID0gMDsKICB9CgogU2V0RmlsZVBvaW50ZXIoaEZpbGUsMCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCAgICFSZWFkRmlsZShoRmlsZSwmbXpfaGVhZGVyLHNpemVvZihtel9oZWFkZXIpLCZsZW4sTlVMTCkKICAgICB8fCBsZW4gIT0gc2l6ZW9mKG16X2hlYWRlcikgCiAgICAgfHwgbXpfaGVhZGVyLmVfbWFnaWMgIT0gSU1BR0VfRE9TX1NJR05BVFVSRSkgewogIG9sZF9jb209MTsgLyogYXNzdW1lIC5DT00gZmlsZSAqLwogIGltYWdlX3N0YXJ0PTA7CiAgaW1hZ2Vfc2l6ZT1HZXRGaWxlU2l6ZShoRmlsZSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgaWYgKChtel9oZWFkZXIuZV9jYmxwIT0wKSYmKG16X2hlYWRlci5lX2NibHAhPTQpKSBpbWFnZV9zaXplLT01MTItbXpfaGVhZGVyLmVfY2JscDsKICBpbWFnZV9zaXplLT1pbWFnZV9zdGFydDsKICBtaW5fc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWluYWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiAgbWF4X3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21heGFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogfQoKICBpZiAoYWxsb2MpIE1aX0luaXRNZW1vcnkoKTsKCiAgaWYgKG9ibGspIHsKICAgIC8qIGxvYWQgb3ZlcmxheSBpbnRvIHByZWFsbG9jYXRlZCBtZW1vcnkgKi8KICAgIGxvYWRfc2VnPW9ibGstPmxvYWRfc2VnOwogICAgcmVsX3NlZz1vYmxrLT5yZWxfc2VnOwogICAgbG9hZF9zdGFydD0oTFBCWVRFKSgoRFdPUkQpbG9hZF9zZWc8PDQpOwogIH0gZWxzZSB7CiAgICAvKiBhbGxvY2F0ZSBlbnZpcm9ubWVudCBibG9jayAqLwogICAgZW52X3NlZz1NWl9Jbml0RW52aXJvbm1lbnQob2xkZW52LCBmaWxlbmFtZSk7CgogICAgLyogYWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgZXhlY3V0YWJsZSAqLwogICAgVFJBQ0UoIkFsbG9jYXRpbmcgRE9TIG1lbW9yeSAobWluPSVsZCwgbWF4PSVsZClcbiIsbWluX3NpemUsbWF4X3NpemUpOwogICAgYXZhaWw9RE9TTUVNX0F2YWlsYWJsZSgpOwogICAgaWYgKGF2YWlsPG1pbl9zaXplKSB7CiAgICAgIEVSUigiaW5zdWZmaWNpZW50IERPUyBtZW1vcnlcbiIpOwogICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogICAgICBnb3RvIGxvYWRfZXJyb3I7CiAgICB9CiAgICBpZiAoYXZhaWw+bWF4X3NpemUpIGF2YWlsPW1heF9zaXplOwogICAgcHNwX3N0YXJ0PURPU01FTV9HZXRCbG9jayhhdmFpbCwmbHBEb3NUYXNrLT5wc3Bfc2VnKTsKICAgIGlmICghcHNwX3N0YXJ0KSB7CiAgICAgIEVSUigiZXJyb3IgYWxsb2NhdGluZyBET1MgbWVtb3J5XG4iKTsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogICAgfQogICAgbG9hZF9zZWc9bHBEb3NUYXNrLT5wc3Bfc2VnKyhvbGRfY29tPzA6UFNQX1NJWkUpOwogICAgcmVsX3NlZz1sb2FkX3NlZzsKICAgIGxvYWRfc3RhcnQ9cHNwX3N0YXJ0KyhQU1BfU0laRTw8NCk7CiAgICBNWl9DcmVhdGVQU1AocHNwX3N0YXJ0LCBlbnZfc2VnLCBvbGRwc3Bfc2VnKTsKICB9CgogLyogbG9hZCBleGVjdXRhYmxlIGltYWdlICovCiBUUkFDRSgibG9hZGluZyBET1MgJXMgaW1hZ2UsICUwOGx4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBTZXRGaWxlUG9pbnRlcihoRmlsZSxpbWFnZV9zdGFydCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCFSZWFkRmlsZShoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUsJmxlbixOVUxMKSB8fCBsZW4gIT0gaW1hZ2Vfc2l6ZSkgewogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICBnb3RvIGxvYWRfZXJyb3I7CiB9CgogaWYgKG16X2hlYWRlci5lX2NybGMpIHsKICAvKiBsb2FkIHJlbG9jYXRpb24gdGFibGUgKi8KICBUUkFDRSgibG9hZGluZyBET1MgRVhFIHJlbG9jYXRpb24gdGFibGUsICVkIGVudHJpZXNcbiIsbXpfaGVhZGVyLmVfY3JsYyk7CiAgLyogRklYTUU6IGlzIHRoaXMgdG9vIHNsb3cgd2l0aG91dCByZWFkIGJ1ZmZlcmluZz8gKi8KICBTZXRGaWxlUG9pbnRlcihoRmlsZSxtel9oZWFkZXIuZV9sZmFybGMsTlVMTCxGSUxFX0JFR0lOKTsKICBmb3IgKHg9MDsgeDxtel9oZWFkZXIuZV9jcmxjOyB4KyspIHsKICAgaWYgKCFSZWFkRmlsZShoRmlsZSwmcmVsb2Msc2l6ZW9mKHJlbG9jKSwmbGVuLE5VTEwpIHx8IGxlbiAhPSBzaXplb2YocmVsb2MpKSB7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgICBnb3RvIGxvYWRfZXJyb3I7CiAgIH0KICAgKihXT1JEKilTRUdQVFIxNihsb2FkX3N0YXJ0LHJlbG9jKSs9cmVsX3NlZzsKICB9CiB9CgogIGlmICghb2JsaykgewogICAgaW5pdF9jcyA9IGxvYWRfc2VnK216X2hlYWRlci5lX2NzOwogICAgaW5pdF9pcCA9IG16X2hlYWRlci5lX2lwOwogICAgaW5pdF9zcyA9IGxvYWRfc2VnK216X2hlYWRlci5lX3NzOwogICAgaW5pdF9zcCA9IG16X2hlYWRlci5lX3NwOwoKICAgIFRSQUNFKCJlbnRyeSBwb2ludDogJTA0eDolMDR4XG4iLGluaXRfY3MsaW5pdF9pcCk7CiAgfQoKICBpZiAoYWxsb2MgJiYgIU1aX0luaXRUYXNrKCkpIHsKICAgIE1aX0tpbGxUYXNrKCk7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfR0VOX0ZBSUxVUkUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgcmV0dXJuIFRSVUU7Cgpsb2FkX2Vycm9yOgogIGxwRG9zVGFzay0+cHNwX3NlZyA9IG9sZHBzcF9zZWc7CiAgaWYgKGFsbG9jKSB7CiAgICBkb3NfY3VycmVudCA9IE5VTEw7CiAgICBpZiAobW1fbmFtZVswXSE9MCkgdW5saW5rKG1tX25hbWUpOwogIH0KCiAgcmV0dXJuIEZBTFNFOwp9CgpCT09MIE1aX0xvYWRJbWFnZSggSE1PRFVMRSBtb2R1bGUsIEhBTkRMRSBoRmlsZSwgTFBDU1RSIGZpbGVuYW1lICkKewogIElNQUdFX05UX0hFQURFUlMgKndpbl9oZHIgPSBQRV9IRUFERVIobW9kdWxlKTsKCiAgaWYgKHdpbl9oZHIpIHsKICAgIHdpbl9oZHItPk9wdGlvbmFsSGVhZGVyLlN1YnN5c3RlbSA9IElNQUdFX1NVQlNZU1RFTV9XSU5ET1dTX0NVSTsKICAgIHdpbl9oZHItPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQgPSAoTFBCWVRFKU1aX0xhdW5jaCAtIChMUEJZVEUpbW9kdWxlOwogIH0KCiAgcmV0dXJuIE1aX0RvTG9hZEltYWdlKCBtb2R1bGUsIGhGaWxlLCBmaWxlbmFtZSwgTlVMTCApOwp9CgpCT09MIE1aX0V4ZWMoIENPTlRFWFQ4NiAqY29udGV4dCwgTFBDU1RSIGZpbGVuYW1lLCBCWVRFIGZ1bmMsIExQVk9JRCBwYXJhbWJsayApCnsKICAvKiB0aGlzIG1heSBvbmx5IGJlIGNhbGxlZCBmcm9tIGV4aXN0aW5nIERPUyBwcm9jZXNzZXMKICAgKiAoaS5lLiBvbmUgRE9TIGFwcCBzcGF3bmluZyBhbm90aGVyKSAqLwogIC8qIEZJWE1FOiBkbyB3ZSB3YW50IHRvIGNoZWNrIGJpbmFyeSB0eXBlIGZpcnN0LCB0byBjaGVjawogICAqIHdoZXRoZXIgaXQncyBhIE5FL1BFIGV4ZWN1dGFibGU/ICovCiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IE1aX0N1cnJlbnQoKTsKICBIRklMRSBoRmlsZSA9IENyZWF0ZUZpbGVBKCBmaWxlbmFtZSwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsCgkJCSAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgLTEpOwogIEJPT0wgcmV0ID0gRkFMU0U7CiAgaWYgKGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSByZXR1cm4gRkFMU0U7CiAgc3dpdGNoIChmdW5jKSB7CiAgY2FzZSAwOiAvKiBsb2FkIGFuZCBleGVjdXRlICovCiAgY2FzZSAxOiAvKiBsb2FkIGJ1dCBkb24ndCBleGVjdXRlICovCiAgICB7CiAgICAgIC8qIHNhdmUgY3VycmVudCBwcm9jZXNzJ3MgcmV0dXJuIFNTOlNQIG5vdyAqLwogICAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKWxwRG9zVGFzay0+cHNwX3NlZyA8PCA0KTsKICAgICAgUERCMTYgKnBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgICAgcHNwLT5zYXZlU3RhY2sgPSAoRFdPUkQpUFRSX1NFR19PRkZfVE9fU0VHUFRSKGNvbnRleHQtPlNlZ1NzLCBMT1dPUkQoY29udGV4dC0+RXNwKSk7CiAgICB9CiAgICByZXQgPSBNWl9Eb0xvYWRJbWFnZSggTlVMTCwgaEZpbGUsIGZpbGVuYW1lLCBOVUxMICk7CiAgICBpZiAocmV0KSB7CiAgICAgIC8qIE1aX0xvYWRJbWFnZSBjcmVhdGVkIGEgbmV3IFBTUCBhbmQgbG9hZGVkIG5ldyB2YWx1ZXMgaW50byBscERvc1Rhc2ssCiAgICAgICAqIGxldCdzIHdvcmsgb24gdGhlIG5ldyB2YWx1ZXMgbm93ICovCiAgICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpbHBEb3NUYXNrLT5wc3Bfc2VnIDw8IDQpOwogICAgICBFeGVjQmxvY2sgKmJsayA9IChFeGVjQmxvY2sgKilwYXJhbWJsazsKICAgICAgTVpfRmlsbFBTUChwc3Bfc3RhcnQsIERPU01FTV9NYXBSZWFsVG9MaW5lYXIoYmxrLT5jbWRsaW5lKSk7CiAgICAgIC8qIHRoZSBsYW1lIE1TLURPUyBlbmdpbmVlcnMgZGVjaWRlZCB0aGF0IHRoZSByZXR1cm4gYWRkcmVzcyBzaG91bGQgYmUgaW4gaW50MjIgKi8KICAgICAgSU5UX1NldFJNSGFuZGxlcigweDIyLCAoRkFSUFJPQzE2KVBUUl9TRUdfT0ZGX1RPX1NFR1BUUihjb250ZXh0LT5TZWdDcywgTE9XT1JEKGNvbnRleHQtPkVpcCkpKTsKICAgICAgaWYgKGZ1bmMpIHsKCS8qIGRvbid0IGV4ZWN1dGUsIGp1c3QgcmV0dXJuIHN0YXJ0dXAgc3RhdGUgKi8KCWJsay0+aW5pdF9jcyA9IGluaXRfY3M7CglibGstPmluaXRfaXAgPSBpbml0X2lwOwoJYmxrLT5pbml0X3NzID0gaW5pdF9zczsKCWJsay0+aW5pdF9zcCA9IGluaXRfc3A7CiAgICAgIH0gZWxzZSB7CgkvKiBleGVjdXRlIGJ5IG1ha2luZyB1cyByZXR1cm4gdG8gbmV3IHByb2Nlc3MgKi8KCWNvbnRleHQtPlNlZ0NzID0gaW5pdF9jczsKCWNvbnRleHQtPkVpcCAgID0gaW5pdF9pcDsKCWNvbnRleHQtPlNlZ1NzID0gaW5pdF9zczsKCWNvbnRleHQtPkVzcCAgID0gaW5pdF9zcDsKCWNvbnRleHQtPlNlZ0RzID0gbHBEb3NUYXNrLT5wc3Bfc2VnOwoJY29udGV4dC0+U2VnRXMgPSBscERvc1Rhc2stPnBzcF9zZWc7Cgljb250ZXh0LT5FYXggICA9IDA7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2UgMzogLyogbG9hZCBvdmVybGF5ICovCiAgICB7CiAgICAgIE92ZXJsYXlCbG9jayAqYmxrID0gKE92ZXJsYXlCbG9jayAqKXBhcmFtYmxrOwogICAgICByZXQgPSBNWl9Eb0xvYWRJbWFnZSggTlVMTCwgaEZpbGUsIGZpbGVuYW1lLCBibGsgKTsKICAgIH0KICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBGSVhNRSgiRVhFQyBsb2FkIHR5cGUgJWQgbm90IGltcGxlbWVudGVkXG4iLCBmdW5jKTsKICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZVTkNUSU9OKTsKICAgIGJyZWFrOwogIH0KICBDbG9zZUhhbmRsZShoRmlsZSk7CiAgcmV0dXJuIHJldDsKfQoKTFBET1NUQVNLIE1aX0FsbG9jRFBNSVRhc2soIHZvaWQgKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoRE9TVEFTSykpOwoKICBpZiAobHBEb3NUYXNrKSB7CiAgICBkb3NfY3VycmVudCA9IGxwRG9zVGFzazsKICAgIE1aX0luaXRNZW1vcnkoKTsKICAgIE1aX0luaXRUYXNrKCk7CiAgfQogIHJldHVybiBscERvc1Rhc2s7Cn0KCnN0YXRpYyB2b2lkIE1aX0luaXRUaW1lciggaW50IHZlciApCnsKIGlmICh2ZXI8MSkgewogIC8qIGNhbid0IG1ha2UgdGltZXIgdGlja3MgKi8KIH0gZWxzZSB7CiAgaW50IGZ1bmM7CiAgc3RydWN0IHRpbWV2YWwgdGltOwoKICAvKiBzdGFydCBkb3Ntb2QgdGltZXIgYXQgNTVtcyAoMTguMkh6KSAqLwogIGZ1bmM9RE9TTU9EX1NFVF9USU1FUjsKICB0aW0udHZfc2VjPTA7IHRpbS50dl91c2VjPTU0OTI1OwogIHdyaXRlKHdyaXRlX3BpcGUsJmZ1bmMsc2l6ZW9mKGZ1bmMpKTsKICB3cml0ZSh3cml0ZV9waXBlLCZ0aW0sc2l6ZW9mKHRpbSkpOwogfQp9CgpzdGF0aWMgQk9PTCBNWl9Jbml0VGFzayh2b2lkKQp7CiAgaW50IHdyaXRlX2ZkWzJdLHhfZmQ7CiAgcGlkX3QgY2hpbGQ7CiAgY2hhciBwYXRoWzI1Nl0sKmZwYXRoOwoKICAvKiBjcmVhdGUgcGlwZXMgKi8KICBpZiAoIUNyZWF0ZVBpcGUoJmhSZWFkUGlwZSwmaFdyaXRlUGlwZSxOVUxMLDApKSByZXR1cm4gRkFMU0U7CiAgaWYgKHBpcGUod3JpdGVfZmQpPDApIHsKICAgIENsb3NlSGFuZGxlKGhSZWFkUGlwZSk7CiAgICBDbG9zZUhhbmRsZShoV3JpdGVQaXBlKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIHJlYWRfcGlwZSA9IEZJTEVfR2V0VW5peEhhbmRsZSggaFJlYWRQaXBlLCBHRU5FUklDX1JFQUQgKTsKICB4X2ZkID0gRklMRV9HZXRVbml4SGFuZGxlKCBoV3JpdGVQaXBlLCBHRU5FUklDX1dSSVRFICk7CgogIFRSQUNFKCJ3aW4zMiBwaXBlOiByZWFkPSVkLCB3cml0ZT0lZCwgdW5peCBwaXBlOiByZWFkPSVkLCB3cml0ZT0lZFxuIiwKICAgICAgICBoUmVhZFBpcGUsaFdyaXRlUGlwZSxyZWFkX3BpcGUseF9mZCk7CiAgVFJBQ0UoIm91dGJvdW5kIHVuaXggcGlwZTogcmVhZD0lZCwgd3JpdGU9JWQsIHBpZD0lZFxuIix3cml0ZV9mZFswXSx3cml0ZV9mZFsxXSxnZXRwaWQoKSk7CgogIHdyaXRlX3BpcGU9d3JpdGVfZmRbMV07CgogIFRSQUNFKCJMb2FkaW5nIERPUyBWTSBzdXBwb3J0IG1vZHVsZVxuIik7CiAgaWYgKChjaGlsZD1mb3JrKCkpPDApIHsKICAgIGNsb3NlKHdyaXRlX2ZkWzBdKTsKICAgIGNsb3NlKHJlYWRfcGlwZSk7CiAgICBjbG9zZSh3cml0ZV9waXBlKTsKICAgIGNsb3NlKHhfZmQpOwogICAgQ2xvc2VIYW5kbGUoaFJlYWRQaXBlKTsKICAgIENsb3NlSGFuZGxlKGhXcml0ZVBpcGUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KIGlmIChjaGlsZCE9MCkgewogIC8qIHBhcmVudCBwcm9jZXNzICovCiAgaW50IHJldDsKCiAgY2xvc2Uod3JpdGVfZmRbMF0pOwogIGNsb3NlKHhfZmQpOwogIGRvc21vZF9waWQgPSBjaGlsZDsKICAvKiB3YWl0IGZvciBjaGlsZCBwcm9jZXNzIHRvIHNpZ25hbCByZWFkaW5lc3MgKi8KICB3aGlsZSAoMSkgewogICAgaWYgKHJlYWQocmVhZF9waXBlLCZyZXQsc2l6ZW9mKHJldCkpPT1zaXplb2YocmV0KSkgYnJlYWs7CiAgICBpZiAoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkgY29udGludWU7CiAgICAvKiBmYWlsdXJlICovCiAgICBFUlIoImRvc21vZCBoYXMgZmFpbGVkIHRvIGluaXRpYWxpemVcbiIpOwogICAgaWYgKG1tX25hbWVbMF0hPTApIHVubGluayhtbV9uYW1lKTsKICAgIHJldHVybiBGQUxTRTsKICB9CiAgLyogdGhlIGNoaWxkIGhhcyBub3cgbW1hcGVkIHRoZSB0ZW1wIGZpbGUsIGl0J3Mgbm93IHNhZmUgdG8gdW5saW5rLgogICAqIGRvIGl0IGhlcmUgdG8gYXZvaWQgbGVhdmluZyBhIG1lc3MgaW4gL3RtcCBpZi93aGVuIFdpbmUgY3Jhc2hlcy4uLiAqLwogIGlmIChtbV9uYW1lWzBdIT0wKSB1bmxpbmsobW1fbmFtZSk7CiAgLyogc3RhcnQgc2ltdWxhdGVkIHN5c3RlbSB0aW1lciAqLwogIE1aX0luaXRUaW1lcihyZXQpOwogIGlmIChyZXQ8MikgewogICAgRVJSKCJkb3Ntb2QgdmVyc2lvbiB0b28gb2xkISBQbGVhc2UgaW5zdGFsbCBuZXdlciBkb3Ntb2QgcHJvcGVybHlcbiIpOwogICAgRVJSKCJJZiB5b3UgZG9uJ3QsIHRoZSBuZXcgZG9zbW9kIGV2ZW50IGhhbmRsaW5nIHN5c3RlbSB3aWxsIG5vdCB3b3JrXG4iKTsKICB9CiAgLyogYWxsIHN5c3RlbXMgYXJlIG5vdyBnbyAqLwogfSBlbHNlIHsKICAvKiBjaGlsZCBwcm9jZXNzICovCiAgY2xvc2UocmVhZF9waXBlKTsKICBjbG9zZSh3cml0ZV9waXBlKTsKICAvKiBwdXQgb3VyIHBpcGVzIHNvbWV3aGVyZSBkb3Ntb2QgY2FuIGZpbmQgdGhlbSAqLwogIGR1cDIod3JpdGVfZmRbMF0sMCk7IC8qIHN0ZGluICovCiAgZHVwMih4X2ZkLDEpOyAgICAgICAgLyogc3Rkb3V0ICovCiAgLyogbm93IGxvYWQgZG9zbW9kICovCiAgLyogY2hlY2sgYXJndlswXS1kZXJpdmVkIHBhdGhzIGZpcnN0LCBzaW5jZSB0aGUgbmV3ZXN0IGRvc21vZCBpcyBtb3N0IGxpa2VseSB0aGVyZQogICAqIChhdCBsZWFzdCBpdCB3YXMgb25jZSBmb3IgQW5kcmVhcyBNb2hyLCBzbyBJIGRlY2lkZWQgdG8gbWFrZSBpdCBlYXNpZXIgZm9yIGhpbSkgKi8KICBmcGF0aD1zdHJyY2hyKHN0cmNweShwYXRoLGZ1bGxfYXJndjApLCcvJyk7CiAgaWYgKGZwYXRoKSB7CiAgIHN0cmNweShmcGF0aCwiL2Rvc21vZCIpOwogICBleGVjbChwYXRoLG1tX25hbWUsTlVMTCk7CiAgIHN0cmNweShmcGF0aCwiL2xvYWRlci9kb3MvZG9zbW9kIik7CiAgIGV4ZWNsKHBhdGgsbW1fbmFtZSxOVUxMKTsKICB9CiAgLyogb2theSwgaXQgd2Fzbid0IHRoZXJlLCB0cnkgaW4gdGhlIHBhdGggKi8KICBleGVjbHAoImRvc21vZCIsbW1fbmFtZSxOVUxMKTsKICAvKiBsYXN0IGRlc3BlcmF0ZSBhdHRlbXB0czogY3VycmVudCBkaXJlY3RvcnkgKi8KICBleGVjbCgiZG9zbW9kIixtbV9uYW1lLE5VTEwpOwogIC8qIGFuZCwganVzdCBmb3IgY29tcGxldGVuZXNzLi4uICovCiAgZXhlY2woImxvYWRlci9kb3MvZG9zbW9kIixtbV9uYW1lLE5VTEwpOwogIC8qIGlmIGZhaWx1cmUsIGV4aXQgKi8KICBFUlIoIkZhaWxlZCB0byBzcGF3biBkb3Ntb2QsIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgZXhpdCgxKTsKIH0KIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2godm9pZCkKewogIExQRE9TVEFTSyBscERvc1Rhc2sgPSBNWl9DdXJyZW50KCk7CiAgQ09OVEVYVCBjb250ZXh0OwogIFREQiAqcFRhc2sgPSAoVERCICopR2xvYmFsTG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiAgQllURSAqcHNwX3N0YXJ0ID0gUFRSX1JFQUxfVE9fTElOKCBscERvc1Rhc2stPnBzcF9zZWcsIDAgKTsKCiAgTVpfRmlsbFBTUChwc3Bfc3RhcnQsIEdldENvbW1hbmRMaW5lQSgpKTsKICBwVGFzay0+ZmxhZ3MgfD0gVERCRl9XSU5PTERBUDsKCiAgbWVtc2V0KCAmY29udGV4dCwgMCwgc2l6ZW9mKGNvbnRleHQpICk7CiAgY29udGV4dC5TZWdDcyAgPSBpbml0X2NzOwogIGNvbnRleHQuRWlwICAgID0gaW5pdF9pcDsKICBjb250ZXh0LlNlZ1NzICA9IGluaXRfc3M7CiAgY29udGV4dC5Fc3AgICAgPSBpbml0X3NwOwogIGNvbnRleHQuU2VnRHMgID0gbHBEb3NUYXNrLT5wc3Bfc2VnOwogIGNvbnRleHQuU2VnRXMgID0gbHBEb3NUYXNrLT5wc3Bfc2VnOwogIGNvbnRleHQuRUZsYWdzID0gMHgwMDA4MDAwMDsgIC8qIHZpcnR1YWwgaW50ZXJydXB0IGZsYWcgKi8KICBET1NWTV9FbnRlciggJmNvbnRleHQgKTsKfQoKc3RhdGljIHZvaWQgTVpfS2lsbFRhc2sodm9pZCkKewogIFRSQUNFKCJraWxsaW5nIERPUyB0YXNrXG4iKTsKICBWR0FfQ2xlYW4oKTsKICBraWxsKGRvc21vZF9waWQsU0lHVEVSTSk7Cn0KCnZvaWQgTVpfRXhpdCggQ09OVEVYVDg2ICpjb250ZXh0LCBCT09MIGNzX3BzcCwgV09SRCByZXR2YWwgKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IE1aX0N1cnJlbnQoKTsKICBpZiAobHBEb3NUYXNrKSB7CiAgICBXT1JEIHBzcF9zZWcgPSBjc19wc3AgPyBjb250ZXh0LT5TZWdDcyA6IGxwRG9zVGFzay0+cHNwX3NlZzsKICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpcHNwX3NlZyA8PCA0KTsKICAgIFBEQjE2ICpwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICBXT1JEIHBhcnBzcCA9IHBzcC0+cGFyZW50UFNQOyAvKiBjaGVjayBmb3IgcGFyZW50IERPUyBwcm9jZXNzICovCiAgICBpZiAocGFycHNwKSB7CiAgICAgIC8qIHJldHJpZXZlIHBhcmVudCdzIHJldHVybiBhZGRyZXNzICovCiAgICAgIEZBUlBST0MxNiByZXRhZGRyID0gSU5UX0dldFJNSGFuZGxlcigweDIyKTsKICAgICAgLyogcmVzdG9yZSBpbnRlcnJ1cHRzICovCiAgICAgIElOVF9TZXRSTUhhbmRsZXIoMHgyMiwgcHNwLT5zYXZlZGludDIyKTsKICAgICAgSU5UX1NldFJNSGFuZGxlcigweDIzLCBwc3AtPnNhdmVkaW50MjMpOwogICAgICBJTlRfU2V0Uk1IYW5kbGVyKDB4MjQsIHBzcC0+c2F2ZWRpbnQyNCk7CiAgICAgIC8qIEZJWE1FOiBkZWFsbG9jYXRlIGZpbGUgaGFuZGxlcyBldGMgKi8KICAgICAgLyogZnJlZSBwcm9jZXNzJ3MgYXNzb2NpYXRlZCBtZW1vcnkKICAgICAgICogRklYTUU6IHdhbGsgbWVtb3J5IGFuZCBkZWFsbG9jYXRlIGFsbCBibG9ja3Mgb3duZWQgYnkgcHJvY2VzcyAqLwogICAgICBET1NNRU1fRnJlZUJsb2NrKERPU01FTV9NYXBSZWFsVG9MaW5lYXIoTUFLRUxPTkcoMCxwc3AtPmVudmlyb25tZW50KSkpOwogICAgICBET1NNRU1fRnJlZUJsb2NrKERPU01FTV9NYXBSZWFsVG9MaW5lYXIoTUFLRUxPTkcoMCxscERvc1Rhc2stPnBzcF9zZWcpKSk7CiAgICAgIC8qIHN3aXRjaCB0byBwYXJlbnQncyBQU1AgKi8KICAgICAgbHBEb3NUYXNrLT5wc3Bfc2VnID0gcGFycHNwOwogICAgICBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpcGFycHNwIDw8IDQpOwogICAgICBwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICAgIC8qIG5vdyByZXR1cm4gdG8gcGFyZW50ICovCiAgICAgIGxwRG9zVGFzay0+cmV0dmFsID0gcmV0dmFsOwogICAgICBjb250ZXh0LT5TZWdDcyA9IFNFTEVDVE9ST0YocmV0YWRkcik7CiAgICAgIGNvbnRleHQtPkVpcCAgID0gT0ZGU0VUT0YocmV0YWRkcik7CiAgICAgIGNvbnRleHQtPlNlZ1NzID0gU0VMRUNUT1JPRihwc3AtPnNhdmVTdGFjayk7CiAgICAgIGNvbnRleHQtPkVzcCAgID0gT0ZGU0VUT0YocHNwLT5zYXZlU3RhY2spOwogICAgICByZXR1cm47CiAgICB9IGVsc2UKICAgICAgTVpfS2lsbFRhc2soKTsKICB9CiAgRXhpdFRocmVhZCggcmV0dmFsICk7Cn0KCiNlbHNlIC8qICFNWl9TVVBQT1JURUQgKi8KCkJPT0wgTVpfTG9hZEltYWdlKCBITU9EVUxFIG1vZHVsZSwgSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUgKQp7CiAgV0FSTigiRE9TIGV4ZWN1dGFibGVzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBwbGF0Zm9ybVxuIik7CiAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogIHJldHVybiBGQUxTRTsKfQoKQk9PTCBNWl9FeGVjKCBDT05URVhUODYgKmNvbnRleHQsIExQQ1NUUiBmaWxlbmFtZSwgQllURSBmdW5jLCBMUFZPSUQgcGFyYW1ibGsgKQp7CiAgLyogY2FuJ3QgaGFwcGVuICovCiAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogIHJldHVybiBGQUxTRTsKfQoKTFBET1NUQVNLIE1aX0FsbG9jRFBNSVRhc2soIHZvaWQgKQp7CiAgICBFUlIoIkFjdHVhbCByZWFsLW1vZGUgY2FsbHMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIHBsYXRmb3JtIVxuIik7CiAgICByZXR1cm4gTlVMTDsKfQoKdm9pZCBNWl9FeGl0KCBDT05URVhUODYgKmNvbnRleHQsIEJPT0wgY3NfcHNwLCBXT1JEIHJldHZhbCApCnsKICBFeGl0VGhyZWFkKCByZXR2YWwgKTsKfQoKI2VuZGlmIC8qICFNWl9TVVBQT1JURUQgKi8KCkxQRE9TVEFTSyBNWl9DdXJyZW50KCB2b2lkICkKewogIHJldHVybiBkb3NfY3VycmVudDsKfQo=