LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgInNlbGVjdG9ycy5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc21vZC5oIgojaW5jbHVkZSAib3B0aW9ucy5oIgojaW5jbHVkZSAidmdhLmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwobW9kdWxlKTsKCnN0YXRpYyBMUERPU1RBU0sgZG9zX2N1cnJlbnQ7CgojaWZkZWYgTVpfU1VQUE9SVEVECgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgovKiBkZWZpbmUgdGhpcyB0byB0cnkgbWFwcGluZyB0aHJvdWdoIC9wcm9jL3BpZC9tZW0gaW5zdGVhZCBvZiBhIHRlbXAgZmlsZSwKICAgYnV0IExpbnVzIGRvZXNuJ3QgbGlrZSBtbWFwcGluZyAvcHJvYy9waWQvbWVtLCBzbyBpdCBkb2Vzbid0IHdvcmsgZm9yIG1lICovCiN1bmRlZiBNWl9NQVBTRUxGCgojZGVmaW5lIEJJT1NfREFUQV9TRUdNRU5UIDB4NDAKI2RlZmluZSBQU1BfU0laRSAweDEwCgojZGVmaW5lIFNFRzE2KHB0cixzZWcpICgoTFBWT0lEKSgoQllURSopcHRyKygoRFdPUkQpKHNlZyk8PDQpKSkKI2RlZmluZSBTRUdQVFIxNihwdHIsc2VncHRyKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKVNFTEVDVE9ST0Yoc2VncHRyKTw8NCkrT0ZGU0VUT0Yoc2VncHRyKSkpCgovKiBzdHJ1Y3R1cmVzIGZvciBFWEVDICovCgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBlbnZfc2VnOwogIERXT1JEIGNtZGxpbmUgV0lORV9QQUNLRUQ7CiAgRFdPUkQgZmNiMSBXSU5FX1BBQ0tFRDsKICBEV09SRCBmY2IyIFdJTkVfUEFDS0VEOwogIFdPUkQgaW5pdF9zcDsKICBXT1JEIGluaXRfc3M7CiAgV09SRCBpbml0X2lwOwogIFdPUkQgaW5pdF9jczsKfSBFeGVjQmxvY2s7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBsb2FkX3NlZzsKICBXT1JEIHJlbF9zZWc7Cn0gT3ZlcmxheUJsb2NrOwoKLyogZ2xvYmFsIHZhcmlhYmxlcyAqLwoKc3RhdGljIFdPUkQgaW5pdF9jcyxpbml0X2lwLGluaXRfc3MsaW5pdF9zcDsKc3RhdGljIGNoYXIgbW1fbmFtZVsxMjhdOwoKaW50IHJlYWRfcGlwZSwgd3JpdGVfcGlwZTsKSEFORExFIGhSZWFkUGlwZSwgaFdyaXRlUGlwZTsKcGlkX3QgZG9zbW9kX3BpZDsKCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCh2b2lkKTsKc3RhdGljIEJPT0wgTVpfSW5pdFRhc2sodm9pZCk7CnN0YXRpYyB2b2lkIE1aX0tpbGxUYXNrKHZvaWQpOwoKc3RhdGljIHZvaWQgTVpfQ3JlYXRlUFNQKCBMUFZPSUQgbHBQU1AsIFdPUkQgZW52LCBXT1JEIHBhciApCnsKICBQREIxNipwc3A9bHBQU1A7CgogIHBzcC0+aW50MjA9MHgyMENEOyAvKiBpbnQgMjAgKi8KICAvKiBzb21lIHByb2dyYW1zIHVzZSB0aGlzIHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgdGhleSBuZWVkICovCiAgcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsgLyogRklYTUU6IHVzZSBhIHJlYWwgdmFsdWUgKi8KICAvKiBGSVhNRTogZGlzcGF0Y2hlciAqLwogIHBzcC0+c2F2ZWRpbnQyMiA9IElOVF9HZXRSTUhhbmRsZXIoMHgyMik7CiAgcHNwLT5zYXZlZGludDIzID0gSU5UX0dldFJNSGFuZGxlcigweDIzKTsKICBwc3AtPnNhdmVkaW50MjQgPSBJTlRfR2V0Uk1IYW5kbGVyKDB4MjQpOwogIHBzcC0+cGFyZW50UFNQPXBhcjsKICBwc3AtPmVudmlyb25tZW50PWVudjsKICAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKc3RhdGljIHZvaWQgTVpfRmlsbFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kbGluZSApCnsKIFBEQjE2KnBzcD1scFBTUDsKIGNvbnN0IGNoYXIqY21kPWNtZGxpbmU/c3RyY2hyKGNtZGxpbmUsJyAnKTpOVUxMOwoKIC8qIGNvcHkgcGFyYW1ldGVycyAqLwogaWYgKGNtZCkgewojaWYgMAogIC8qIGNvbW1hbmQuY29tIGRvZXNuJ3QgZG8gdGhpcyAqLwogIHdoaWxlICgqY21kID09ICcgJykgY21kKys7CiNlbmRpZgogIHBzcC0+Y21kTGluZVswXT1zdHJsZW4oY21kKTsKICBzdHJjcHkocHNwLT5jbWRMaW5lKzEsY21kKTsKICBwc3AtPmNtZExpbmVbcHNwLT5jbWRMaW5lWzBdKzFdPSdccic7CiB9IGVsc2UgcHNwLT5jbWRMaW5lWzFdPSdccic7CiAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKLyogZGVmYXVsdCBJTlQgMDggaGFuZGxlcjogaW5jcmVhc2VzIHRpbWVyIHRpY2sgY291bnRlciBidXQgbm90IG11Y2ggbW9yZSAqLwpzdGF0aWMgY2hhciBpbnQwOFtdPXsKIDB4Q0QsMHgxQywgICAgICAgICAgIC8qIGludCAkMHgxYyAqLwogMHg1MCwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWF4ICovCiAweDFFLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlZHMgKi8KIDB4QjgsMHg0MCwweDAwLCAgICAgIC8qIG1vdncgJDB4NDAsJWF4ICovCiAweDhFLDB4RDgsICAgICAgICAgICAvKiBtb3Z3ICVheCwlZHMgKi8KI2lmIDAKIDB4ODMsMHgwNiwweDZDLDB4MDAsMHgwMSwgLyogYWRkdyAkMSwoMHg2YykgKi8KIDB4ODMsMHgxNiwweDZFLDB4MDAsMHgwMCwgLyogYWRjdyAkMCwoMHg2ZSkgKi8KI2Vsc2UKIDB4NjYsMHhGRiwweDA2LDB4NkMsMHgwMCwgLyogaW5jbCAoMHg2YykgKi8KI2VuZGlmCiAweEIwLDB4MjAsICAgICAgICAgICAvKiBtb3ZiICQweDIwLCVhbCAqLwogMHhFNiwweDIwLCAgICAgICAgICAgLyogb3V0YiAlYWwsJDB4MjAgKi8KIDB4MUYsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweDU4LCAgICAgICAgICAgICAgICAvKiBwb3B3ICVheCAqLwogMHhDRiAgICAgICAgICAgICAgICAgLyogaXJldCAqLwp9OwoKc3RhdGljIHZvaWQgTVpfSW5pdEhhbmRsZXJzKHZvaWQpCnsKIFdPUkQgc2VnOwogTFBCWVRFIHN0YXJ0PURPU01FTV9HZXRCbG9jayhzaXplb2YoaW50MDgpLCZzZWcpOwogbWVtY3B5KHN0YXJ0LGludDA4LHNpemVvZihpbnQwOCkpOwovKiBJTlQgMDg6IHBvaW50IGl0IGF0IG91ciB0aWNrLWluY3JlbWVudGluZyBoYW5kbGVyICovCiAoKFNFR1BUUiopMClbMHgwOF09UFRSX1NFR19PRkZfVE9fU0VHUFRSKHNlZywwKTsKLyogSU5UIDFDOiBqdXN0IHBvaW50IGl0IHRvIElSRVQsIHdlIGRvbid0IHdhbnQgdG8gaGFuZGxlIGl0IG91cnNlbHZlcyAqLwogKChTRUdQVFIqKTApWzB4MUNdPVBUUl9TRUdfT0ZGX1RPX1NFR1BUUihzZWcsc2l6ZW9mKGludDA4KS0xKTsKfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fR2V0QmxvY2soc3orc2l6ZW9mKFdPUkQpK3N0cmxlbihuYW1lKSsxLCZzZWcpOwogLyogZmlsbCBpdCAqLwogaWYgKGVudikgewogIG1lbWNweShlbnZibGssZW52LHN6KTsKIH0gZWxzZSBlbnZibGtbMF09MDsKIC8qIERPUyAzLng6IHRoZSBibG9jayBjb250YWlucyAxIGFkZGl0aW9uYWwgc3RyaW5nICovCiAqKFdPUkQqKShlbnZibGsrc3opPTE7CiAvKiBiZWluZyB0aGUgcHJvZ3JhbSBuYW1lIGl0c2VsZiAqLwogc3RyY3B5KGVudmJsaytzeitzaXplb2YoV09SRCksbmFtZSk7CiByZXR1cm4gc2VnOwp9CgpzdGF0aWMgQk9PTCBNWl9Jbml0TWVtb3J5KHZvaWQpCnsKICAgIGludCBtbV9mZDsKICAgIHZvaWQgKmltZ19iYXNlOwoKICAgIC8qIGluaXRpYWxpemUgdGhlIG1lbW9yeSAqLwogICAgVFJBQ0UoIkluaXRpYWxpemluZyBET1MgbWVtb3J5IHN0cnVjdHVyZXNcbiIpOwogICAgRE9TTUVNX0luaXQoVFJVRSk7CgogICAgLyogYWxsb2NhdGUgMU1CKzY0SyBzaGFyZWQgbWVtb3J5ICovCiAgICB0bXBuYW0obW1fbmFtZSk7CiAgICAvKiBzdHJjcHkobW1fbmFtZSwiL3RtcC9teWRvc2ltYWdlIik7ICovCiAgICBtbV9mZCA9IG9wZW4obW1fbmFtZSxPX1JEV1J8T19DUkVBVCAvKiB8T19UUlVOQyAqLyxTX0lSVVNSfFNfSVdVU1IpOwogICAgaWYgKG1tX2ZkIDwgMCkgRVJSKCJmaWxlICVzIGNvdWxkIG5vdCBiZSBvcGVuZWRcbiIsbW1fbmFtZSk7CiAgICAvKiBmaWxsIHRoZSBmaWxlIHdpdGggdGhlIERPUyBtZW1vcnkgKi8KICAgIGlmICh3cml0ZSggbW1fZmQsIE5VTEwsIDB4MTEwMDAwICkgIT0gMHgxMTAwMDApIEVSUigiY2Fubm90IHdyaXRlIERPUyBtZW1cbiIpOwogICAgLyogbWFwIGl0IGluICovCiAgICBpbWdfYmFzZSA9IG1tYXAoTlVMTCwweDExMDAwMCxQUk9UX1JFQUR8UFJPVF9XUklURXxQUk9UX0VYRUMsTUFQX1NIQVJFRHxNQVBfRklYRUQsbW1fZmQsMCk7CiAgICBjbG9zZSggbW1fZmQgKTsKCiAgICBpZiAoaW1nX2Jhc2UpCiAgICB7CiAgICAgICAgRVJSKCJjb3VsZCBub3QgbWFwIHNoYXJlZCBtZW1vcnksIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgTVpfSW5pdEhhbmRsZXJzKCk7CiAgICByZXR1cm4gVFJVRTsKfQoKQk9PTCBNWl9Eb0xvYWRJbWFnZSggSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUsIE92ZXJsYXlCbG9jayAqb2JsayApCnsKICBMUERPU1RBU0sgbHBEb3NUYXNrID0gZG9zX2N1cnJlbnQ7CiAgSU1BR0VfRE9TX0hFQURFUiBtel9oZWFkZXI7CiAgRFdPUkQgaW1hZ2Vfc3RhcnQsaW1hZ2Vfc2l6ZSxtaW5fc2l6ZSxtYXhfc2l6ZSxhdmFpbDsKICBCWVRFKnBzcF9zdGFydCwqbG9hZF9zdGFydCwqb2xkZW52OwogIGludCB4LCBvbGRfY29tPTAsIGFsbG9jOwogIFNFR1BUUiByZWxvYzsKICBXT1JEIGVudl9zZWcsIGxvYWRfc2VnLCByZWxfc2VnLCBvbGRwc3Bfc2VnOwogIERXT1JEIGxlbjsKCiAgaWYgKGxwRG9zVGFzaykgewogICAgLyogRE9TIHByb2Nlc3MgYWxyZWFkeSBydW5uaW5nLCBpbmhlcml0IGZyb20gaXQgKi8KICAgIFBEQjE2KiBwYXJfcHNwID0gKFBEQjE2KikoKERXT1JEKWxwRG9zVGFzay0+cHNwX3NlZyA8PCA0KTsKICAgIGFsbG9jPTA7CiAgICBvbGRlbnYgPSAoTFBCWVRFKSgoRFdPUkQpcGFyX3BzcC0+ZW52aXJvbm1lbnQgPDwgNCk7CiAgICBvbGRwc3Bfc2VnID0gbHBEb3NUYXNrLT5wc3Bfc2VnOwogIH0gZWxzZSB7CiAgICAvKiBhbGxvY2F0ZSBuZXcgRE9TIHByb2Nlc3MsIGluaGVyaXRpbmcgZnJvbSBXaW5lIGVudmlyb25tZW50ICovCiAgICBhbGxvYz0xOwogICAgbHBEb3NUYXNrID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihET1NUQVNLKSk7CiAgICBkb3NfY3VycmVudCA9IGxwRG9zVGFzazsKICAgIG9sZGVudiA9IEdldEVudmlyb25tZW50U3RyaW5nc0EoKTsKICAgIG9sZHBzcF9zZWcgPSAwOwogIH0KCiBTZXRGaWxlUG9pbnRlcihoRmlsZSwwLE5VTEwsRklMRV9CRUdJTik7CiBpZiAoICAgIVJlYWRGaWxlKGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlciksJmxlbixOVUxMKQogICAgIHx8IGxlbiAhPSBzaXplb2YobXpfaGVhZGVyKSAKICAgICB8fCBtel9oZWFkZXIuZV9tYWdpYyAhPSBJTUFHRV9ET1NfU0lHTkFUVVJFKSB7CiAgY2hhciAqcCA9IHN0cnJjaHIoIGZpbGVuYW1lLCAnLicgKTsKICBpZiAoIXAgfHwgc3RyY2FzZWNtcCggcCwgIi5jb20iICkpICAvKiBjaGVjayBmb3IgLkNPTSBleHRlbnNpb24gKi8KICB7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogIH0KICBvbGRfY29tPTE7IC8qIGFzc3VtZSAuQ09NIGZpbGUgKi8KICBpbWFnZV9zdGFydD0wOwogIGltYWdlX3NpemU9R2V0RmlsZVNpemUoaEZpbGUsTlVMTCk7CiAgbWluX3NpemU9MHgxMDAwMDsgbWF4X3NpemU9MHgxMDAwMDA7CiAgbXpfaGVhZGVyLmVfY3JsYz0wOwogIG16X2hlYWRlci5lX3NzPTA7IG16X2hlYWRlci5lX3NwPTB4RkZGRTsKICBtel9oZWFkZXIuZV9jcz0wOyBtel9oZWFkZXIuZV9pcD0weDEwMDsKIH0gZWxzZSB7CiAgLyogY2FsY3VsYXRlIGxvYWQgc2l6ZSAqLwogIGltYWdlX3N0YXJ0PW16X2hlYWRlci5lX2NwYXJoZHI8PDQ7CiAgaW1hZ2Vfc2l6ZT1tel9oZWFkZXIuZV9jcDw8OTsgLyogcGFnZXMgYXJlIDUxMiBieXRlcyAqLwogIGlmICgobXpfaGVhZGVyLmVfY2JscCE9MCkmJihtel9oZWFkZXIuZV9jYmxwIT00KSkgaW1hZ2Vfc2l6ZS09NTEyLW16X2hlYWRlci5lX2NibHA7CiAgaW1hZ2Vfc2l6ZS09aW1hZ2Vfc3RhcnQ7CiAgbWluX3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21pbmFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogIG1heF9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9tYXhhbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKIH0KCiAgaWYgKGFsbG9jKSBNWl9Jbml0TWVtb3J5KCk7CgogIGlmIChvYmxrKSB7CiAgICAvKiBsb2FkIG92ZXJsYXkgaW50byBwcmVhbGxvY2F0ZWQgbWVtb3J5ICovCiAgICBsb2FkX3NlZz1vYmxrLT5sb2FkX3NlZzsKICAgIHJlbF9zZWc9b2Jsay0+cmVsX3NlZzsKICAgIGxvYWRfc3RhcnQ9KExQQllURSkoKERXT1JEKWxvYWRfc2VnPDw0KTsKICB9IGVsc2UgewogICAgLyogYWxsb2NhdGUgZW52aXJvbm1lbnQgYmxvY2sgKi8KICAgIGVudl9zZWc9TVpfSW5pdEVudmlyb25tZW50KG9sZGVudiwgZmlsZW5hbWUpOwoKICAgIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGV4ZWN1dGFibGUgKi8KICAgIFRSQUNFKCJBbGxvY2F0aW5nIERPUyBtZW1vcnkgKG1pbj0lbGQsIG1heD0lbGQpXG4iLG1pbl9zaXplLG1heF9zaXplKTsKICAgIGF2YWlsPURPU01FTV9BdmFpbGFibGUoKTsKICAgIGlmIChhdmFpbDxtaW5fc2l6ZSkgewogICAgICBFUlIoImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogICAgfQogICAgaWYgKGF2YWlsPm1heF9zaXplKSBhdmFpbD1tYXhfc2l6ZTsKICAgIHBzcF9zdGFydD1ET1NNRU1fR2V0QmxvY2soYXZhaWwsJmxwRG9zVGFzay0+cHNwX3NlZyk7CiAgICBpZiAoIXBzcF9zdGFydCkgewogICAgICBFUlIoImVycm9yIGFsbG9jYXRpbmcgRE9TIG1lbW9yeVxuIik7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgIH0KICAgIGxvYWRfc2VnPWxwRG9zVGFzay0+cHNwX3NlZysob2xkX2NvbT8wOlBTUF9TSVpFKTsKICAgIHJlbF9zZWc9bG9hZF9zZWc7CiAgICBsb2FkX3N0YXJ0PXBzcF9zdGFydCsoUFNQX1NJWkU8PDQpOwogICAgTVpfQ3JlYXRlUFNQKHBzcF9zdGFydCwgZW52X3NlZywgb2xkcHNwX3NlZyk7CiAgfQoKIC8qIGxvYWQgZXhlY3V0YWJsZSBpbWFnZSAqLwogVFJBQ0UoImxvYWRpbmcgRE9TICVzIGltYWdlLCAlMDhseCBieXRlc1xuIixvbGRfY29tPyJDT00iOiJFWEUiLGltYWdlX3NpemUpOwogU2V0RmlsZVBvaW50ZXIoaEZpbGUsaW1hZ2Vfc3RhcnQsTlVMTCxGSUxFX0JFR0lOKTsKIGlmICghUmVhZEZpbGUoaEZpbGUsbG9hZF9zdGFydCxpbWFnZV9zaXplLCZsZW4sTlVMTCkgfHwgbGVuICE9IGltYWdlX3NpemUpIHsKICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgZ290byBsb2FkX2Vycm9yOwogfQoKIGlmIChtel9oZWFkZXIuZV9jcmxjKSB7CiAgLyogbG9hZCByZWxvY2F0aW9uIHRhYmxlICovCiAgVFJBQ0UoImxvYWRpbmcgRE9TIEVYRSByZWxvY2F0aW9uIHRhYmxlLCAlZCBlbnRyaWVzXG4iLG16X2hlYWRlci5lX2NybGMpOwogIC8qIEZJWE1FOiBpcyB0aGlzIHRvbyBzbG93IHdpdGhvdXQgcmVhZCBidWZmZXJpbmc/ICovCiAgU2V0RmlsZVBvaW50ZXIoaEZpbGUsbXpfaGVhZGVyLmVfbGZhcmxjLE5VTEwsRklMRV9CRUdJTik7CiAgZm9yICh4PTA7IHg8bXpfaGVhZGVyLmVfY3JsYzsgeCsrKSB7CiAgIGlmICghUmVhZEZpbGUoaEZpbGUsJnJlbG9jLHNpemVvZihyZWxvYyksJmxlbixOVUxMKSB8fCBsZW4gIT0gc2l6ZW9mKHJlbG9jKSkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgZ290byBsb2FkX2Vycm9yOwogICB9CiAgICooV09SRCopU0VHUFRSMTYobG9hZF9zdGFydCxyZWxvYykrPXJlbF9zZWc7CiAgfQogfQoKICBpZiAoIW9ibGspIHsKICAgIGluaXRfY3MgPSBsb2FkX3NlZyttel9oZWFkZXIuZV9jczsKICAgIGluaXRfaXAgPSBtel9oZWFkZXIuZV9pcDsKICAgIGluaXRfc3MgPSBsb2FkX3NlZyttel9oZWFkZXIuZV9zczsKICAgIGluaXRfc3AgPSBtel9oZWFkZXIuZV9zcDsKCiAgICBUUkFDRSgiZW50cnkgcG9pbnQ6ICUwNHg6JTA0eFxuIixpbml0X2NzLGluaXRfaXApOwogIH0KCiAgaWYgKGFsbG9jICYmICFNWl9Jbml0VGFzaygpKSB7CiAgICBNWl9LaWxsVGFzaygpOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0dFTl9GQUlMVVJFKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIHJldHVybiBUUlVFOwoKbG9hZF9lcnJvcjoKICBscERvc1Rhc2stPnBzcF9zZWcgPSBvbGRwc3Bfc2VnOwogIGlmIChhbGxvYykgewogICAgZG9zX2N1cnJlbnQgPSBOVUxMOwogICAgaWYgKG1tX25hbWVbMF0hPTApIHVubGluayhtbV9uYW1lKTsKICB9CgogIHJldHVybiBGQUxTRTsKfQoKQk9PTCBNWl9Mb2FkSW1hZ2UoIExQQ1NUUiBjbWRsaW5lICkKewogICAgSEZJTEUgaEZpbGU7CiAgICBjaGFyICpuYW1lLCBidWZmZXJbTUFYX1BBVEhdOwogICAgTFBDU1RSIHAgPSBzdHJjaHIoIGNtZGxpbmUsICcgJyApOwoKICAgIGlmIChwKQogICAgewogICAgICAgIGlmICghKG5hbWUgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIHAgLSBjbWRsaW5lICsgMSApKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIG1lbWNweSggbmFtZSwgY21kbGluZSwgcCAtIGNtZGxpbmUgKTsKICAgICAgICBuYW1lW3AgLSBjbWRsaW5lXSA9IDA7CiAgICB9CiAgICBlbHNlIG5hbWUgPSAoY2hhciAqKWNtZGxpbmU7CgogICAgaWYgKCFTZWFyY2hQYXRoQSggTlVMTCwgbmFtZSwgIi5leGUiLCBzaXplb2YoYnVmZmVyKSwgYnVmZmVyLCBOVUxMICkpIGdvdG8gZXJyb3I7CiAgICBpZiAoKGhGaWxlID0gQ3JlYXRlRmlsZUEoIGJ1ZmZlciwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIC0xICkpID09IElOVkFMSURfSEFORExFX1ZBTFVFKQogICAgICAgIGdvdG8gZXJyb3I7CiAgICBpZiAoIU1aX0RvTG9hZEltYWdlKCBoRmlsZSwgYnVmZmVyLCBOVUxMICkpCiAgICB7CiAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIE1aX0xhdW5jaCgpOwogZXJyb3I6CiAgICBpZiAobmFtZSAhPSBjbWRsaW5lKSBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbmFtZSApOwogICAgcmV0dXJuIEZBTFNFOwp9CgpCT09MIE1aX0V4ZWMoIENPTlRFWFQ4NiAqY29udGV4dCwgTFBDU1RSIGZpbGVuYW1lLCBCWVRFIGZ1bmMsIExQVk9JRCBwYXJhbWJsayApCnsKICAvKiB0aGlzIG1heSBvbmx5IGJlIGNhbGxlZCBmcm9tIGV4aXN0aW5nIERPUyBwcm9jZXNzZXMKICAgKiAoaS5lLiBvbmUgRE9TIGFwcCBzcGF3bmluZyBhbm90aGVyKSAqLwogIC8qIEZJWE1FOiBkbyB3ZSB3YW50IHRvIGNoZWNrIGJpbmFyeSB0eXBlIGZpcnN0LCB0byBjaGVjawogICAqIHdoZXRoZXIgaXQncyBhIE5FL1BFIGV4ZWN1dGFibGU/ICovCiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IE1aX0N1cnJlbnQoKTsKICBIRklMRSBoRmlsZSA9IENyZWF0ZUZpbGVBKCBmaWxlbmFtZSwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsCgkJCSAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgLTEpOwogIEJPT0wgcmV0ID0gRkFMU0U7CiAgaWYgKGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSByZXR1cm4gRkFMU0U7CiAgc3dpdGNoIChmdW5jKSB7CiAgY2FzZSAwOiAvKiBsb2FkIGFuZCBleGVjdXRlICovCiAgY2FzZSAxOiAvKiBsb2FkIGJ1dCBkb24ndCBleGVjdXRlICovCiAgICB7CiAgICAgIC8qIHNhdmUgY3VycmVudCBwcm9jZXNzJ3MgcmV0dXJuIFNTOlNQIG5vdyAqLwogICAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKWxwRG9zVGFzay0+cHNwX3NlZyA8PCA0KTsKICAgICAgUERCMTYgKnBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgICAgcHNwLT5zYXZlU3RhY2sgPSAoRFdPUkQpUFRSX1NFR19PRkZfVE9fU0VHUFRSKGNvbnRleHQtPlNlZ1NzLCBMT1dPUkQoY29udGV4dC0+RXNwKSk7CiAgICB9CiAgICByZXQgPSBNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBOVUxMICk7CiAgICBpZiAocmV0KSB7CiAgICAgIC8qIE1aX0xvYWRJbWFnZSBjcmVhdGVkIGEgbmV3IFBTUCBhbmQgbG9hZGVkIG5ldyB2YWx1ZXMgaW50byBscERvc1Rhc2ssCiAgICAgICAqIGxldCdzIHdvcmsgb24gdGhlIG5ldyB2YWx1ZXMgbm93ICovCiAgICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpbHBEb3NUYXNrLT5wc3Bfc2VnIDw8IDQpOwogICAgICBFeGVjQmxvY2sgKmJsayA9IChFeGVjQmxvY2sgKilwYXJhbWJsazsKICAgICAgTVpfRmlsbFBTUChwc3Bfc3RhcnQsIERPU01FTV9NYXBSZWFsVG9MaW5lYXIoYmxrLT5jbWRsaW5lKSk7CiAgICAgIC8qIHRoZSBsYW1lIE1TLURPUyBlbmdpbmVlcnMgZGVjaWRlZCB0aGF0IHRoZSByZXR1cm4gYWRkcmVzcyBzaG91bGQgYmUgaW4gaW50MjIgKi8KICAgICAgSU5UX1NldFJNSGFuZGxlcigweDIyLCAoRkFSUFJPQzE2KVBUUl9TRUdfT0ZGX1RPX1NFR1BUUihjb250ZXh0LT5TZWdDcywgTE9XT1JEKGNvbnRleHQtPkVpcCkpKTsKICAgICAgaWYgKGZ1bmMpIHsKCS8qIGRvbid0IGV4ZWN1dGUsIGp1c3QgcmV0dXJuIHN0YXJ0dXAgc3RhdGUgKi8KCWJsay0+aW5pdF9jcyA9IGluaXRfY3M7CglibGstPmluaXRfaXAgPSBpbml0X2lwOwoJYmxrLT5pbml0X3NzID0gaW5pdF9zczsKCWJsay0+aW5pdF9zcCA9IGluaXRfc3A7CiAgICAgIH0gZWxzZSB7CgkvKiBleGVjdXRlIGJ5IG1ha2luZyB1cyByZXR1cm4gdG8gbmV3IHByb2Nlc3MgKi8KCWNvbnRleHQtPlNlZ0NzID0gaW5pdF9jczsKCWNvbnRleHQtPkVpcCAgID0gaW5pdF9pcDsKCWNvbnRleHQtPlNlZ1NzID0gaW5pdF9zczsKCWNvbnRleHQtPkVzcCAgID0gaW5pdF9zcDsKCWNvbnRleHQtPlNlZ0RzID0gbHBEb3NUYXNrLT5wc3Bfc2VnOwoJY29udGV4dC0+U2VnRXMgPSBscERvc1Rhc2stPnBzcF9zZWc7Cgljb250ZXh0LT5FYXggICA9IDA7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2UgMzogLyogbG9hZCBvdmVybGF5ICovCiAgICB7CiAgICAgIE92ZXJsYXlCbG9jayAqYmxrID0gKE92ZXJsYXlCbG9jayAqKXBhcmFtYmxrOwogICAgICByZXQgPSBNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBibGsgKTsKICAgIH0KICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBGSVhNRSgiRVhFQyBsb2FkIHR5cGUgJWQgbm90IGltcGxlbWVudGVkXG4iLCBmdW5jKTsKICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZVTkNUSU9OKTsKICAgIGJyZWFrOwogIH0KICBDbG9zZUhhbmRsZShoRmlsZSk7CiAgcmV0dXJuIHJldDsKfQoKTFBET1NUQVNLIE1aX0FsbG9jRFBNSVRhc2soIHZvaWQgKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoRE9TVEFTSykpOwoKICBpZiAobHBEb3NUYXNrKSB7CiAgICBkb3NfY3VycmVudCA9IGxwRG9zVGFzazsKICAgIE1aX0luaXRNZW1vcnkoKTsKICAgIE1aX0luaXRUYXNrKCk7CiAgfQogIHJldHVybiBscERvc1Rhc2s7Cn0KCnN0YXRpYyB2b2lkIE1aX0luaXRUaW1lciggaW50IHZlciApCnsKIGlmICh2ZXI8MSkgewogIC8qIGNhbid0IG1ha2UgdGltZXIgdGlja3MgKi8KIH0gZWxzZSB7CiAgaW50IGZ1bmM7CiAgc3RydWN0IHRpbWV2YWwgdGltOwoKICAvKiBzdGFydCBkb3Ntb2QgdGltZXIgYXQgNTVtcyAoMTguMkh6KSAqLwogIGZ1bmM9RE9TTU9EX1NFVF9USU1FUjsKICB0aW0udHZfc2VjPTA7IHRpbS50dl91c2VjPTU0OTI1OwogIHdyaXRlKHdyaXRlX3BpcGUsJmZ1bmMsc2l6ZW9mKGZ1bmMpKTsKICB3cml0ZSh3cml0ZV9waXBlLCZ0aW0sc2l6ZW9mKHRpbSkpOwogfQp9CgpzdGF0aWMgQk9PTCBNWl9Jbml0VGFzayh2b2lkKQp7CiAgaW50IHdyaXRlX2ZkWzJdLHhfZmQ7CiAgcGlkX3QgY2hpbGQ7CiAgY2hhciBwYXRoWzI1Nl0sKmZwYXRoOwoKICAvKiBjcmVhdGUgcGlwZXMgKi8KICBpZiAoIUNyZWF0ZVBpcGUoJmhSZWFkUGlwZSwmaFdyaXRlUGlwZSxOVUxMLDApKSByZXR1cm4gRkFMU0U7CiAgaWYgKHBpcGUod3JpdGVfZmQpPDApIHsKICAgIENsb3NlSGFuZGxlKGhSZWFkUGlwZSk7CiAgICBDbG9zZUhhbmRsZShoV3JpdGVQaXBlKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIHJlYWRfcGlwZSA9IEZJTEVfR2V0VW5peEhhbmRsZSggaFJlYWRQaXBlLCBHRU5FUklDX1JFQUQgKTsKICB4X2ZkID0gRklMRV9HZXRVbml4SGFuZGxlKCBoV3JpdGVQaXBlLCBHRU5FUklDX1dSSVRFICk7CgogIFRSQUNFKCJ3aW4zMiBwaXBlOiByZWFkPSVkLCB3cml0ZT0lZCwgdW5peCBwaXBlOiByZWFkPSVkLCB3cml0ZT0lZFxuIiwKICAgICAgICBoUmVhZFBpcGUsaFdyaXRlUGlwZSxyZWFkX3BpcGUseF9mZCk7CiAgVFJBQ0UoIm91dGJvdW5kIHVuaXggcGlwZTogcmVhZD0lZCwgd3JpdGU9JWQsIHBpZD0lZFxuIix3cml0ZV9mZFswXSx3cml0ZV9mZFsxXSxnZXRwaWQoKSk7CgogIHdyaXRlX3BpcGU9d3JpdGVfZmRbMV07CgogIFRSQUNFKCJMb2FkaW5nIERPUyBWTSBzdXBwb3J0IG1vZHVsZVxuIik7CiAgaWYgKChjaGlsZD1mb3JrKCkpPDApIHsKICAgIGNsb3NlKHdyaXRlX2ZkWzBdKTsKICAgIGNsb3NlKHJlYWRfcGlwZSk7CiAgICBjbG9zZSh3cml0ZV9waXBlKTsKICAgIGNsb3NlKHhfZmQpOwogICAgQ2xvc2VIYW5kbGUoaFJlYWRQaXBlKTsKICAgIENsb3NlSGFuZGxlKGhXcml0ZVBpcGUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KIGlmIChjaGlsZCE9MCkgewogIC8qIHBhcmVudCBwcm9jZXNzICovCiAgaW50IHJldDsKCiAgY2xvc2Uod3JpdGVfZmRbMF0pOwogIGNsb3NlKHhfZmQpOwogIGRvc21vZF9waWQgPSBjaGlsZDsKICAvKiB3YWl0IGZvciBjaGlsZCBwcm9jZXNzIHRvIHNpZ25hbCByZWFkaW5lc3MgKi8KICB3aGlsZSAoMSkgewogICAgaWYgKHJlYWQocmVhZF9waXBlLCZyZXQsc2l6ZW9mKHJldCkpPT1zaXplb2YocmV0KSkgYnJlYWs7CiAgICBpZiAoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkgY29udGludWU7CiAgICAvKiBmYWlsdXJlICovCiAgICBFUlIoImRvc21vZCBoYXMgZmFpbGVkIHRvIGluaXRpYWxpemVcbiIpOwogICAgaWYgKG1tX25hbWVbMF0hPTApIHVubGluayhtbV9uYW1lKTsKICAgIHJldHVybiBGQUxTRTsKICB9CiAgLyogdGhlIGNoaWxkIGhhcyBub3cgbW1hcGVkIHRoZSB0ZW1wIGZpbGUsIGl0J3Mgbm93IHNhZmUgdG8gdW5saW5rLgogICAqIGRvIGl0IGhlcmUgdG8gYXZvaWQgbGVhdmluZyBhIG1lc3MgaW4gL3RtcCBpZi93aGVuIFdpbmUgY3Jhc2hlcy4uLiAqLwogIGlmIChtbV9uYW1lWzBdIT0wKSB1bmxpbmsobW1fbmFtZSk7CiAgLyogc3RhcnQgc2ltdWxhdGVkIHN5c3RlbSB0aW1lciAqLwogIE1aX0luaXRUaW1lcihyZXQpOwogIGlmIChyZXQ8MikgewogICAgRVJSKCJkb3Ntb2QgdmVyc2lvbiB0b28gb2xkISBQbGVhc2UgaW5zdGFsbCBuZXdlciBkb3Ntb2QgcHJvcGVybHlcbiIpOwogICAgRVJSKCJJZiB5b3UgZG9uJ3QsIHRoZSBuZXcgZG9zbW9kIGV2ZW50IGhhbmRsaW5nIHN5c3RlbSB3aWxsIG5vdCB3b3JrXG4iKTsKICB9CiAgLyogYWxsIHN5c3RlbXMgYXJlIG5vdyBnbyAqLwogfSBlbHNlIHsKICAvKiBjaGlsZCBwcm9jZXNzICovCiAgY2xvc2UocmVhZF9waXBlKTsKICBjbG9zZSh3cml0ZV9waXBlKTsKICAvKiBwdXQgb3VyIHBpcGVzIHNvbWV3aGVyZSBkb3Ntb2QgY2FuIGZpbmQgdGhlbSAqLwogIGR1cDIod3JpdGVfZmRbMF0sMCk7IC8qIHN0ZGluICovCiAgZHVwMih4X2ZkLDEpOyAgICAgICAgLyogc3Rkb3V0ICovCiAgLyogbm93IGxvYWQgZG9zbW9kICovCiAgLyogY2hlY2sgYXJndlswXS1kZXJpdmVkIHBhdGhzIGZpcnN0LCBzaW5jZSB0aGUgbmV3ZXN0IGRvc21vZCBpcyBtb3N0IGxpa2VseSB0aGVyZQogICAqIChhdCBsZWFzdCBpdCB3YXMgb25jZSBmb3IgQW5kcmVhcyBNb2hyLCBzbyBJIGRlY2lkZWQgdG8gbWFrZSBpdCBlYXNpZXIgZm9yIGhpbSkgKi8KICBmcGF0aD1zdHJyY2hyKHN0cmNweShwYXRoLGZ1bGxfYXJndjApLCcvJyk7CiAgaWYgKGZwYXRoKSB7CiAgIHN0cmNweShmcGF0aCwiL2Rvc21vZCIpOwogICBleGVjbChwYXRoLG1tX25hbWUsTlVMTCk7CiAgIHN0cmNweShmcGF0aCwiL2xvYWRlci9kb3MvZG9zbW9kIik7CiAgIGV4ZWNsKHBhdGgsbW1fbmFtZSxOVUxMKTsKICB9CiAgLyogb2theSwgaXQgd2Fzbid0IHRoZXJlLCB0cnkgaW4gdGhlIHBhdGggKi8KICBleGVjbHAoImRvc21vZCIsbW1fbmFtZSxOVUxMKTsKICAvKiBsYXN0IGRlc3BlcmF0ZSBhdHRlbXB0czogY3VycmVudCBkaXJlY3RvcnkgKi8KICBleGVjbCgiZG9zbW9kIixtbV9uYW1lLE5VTEwpOwogIC8qIGFuZCwganVzdCBmb3IgY29tcGxldGVuZXNzLi4uICovCiAgZXhlY2woImxvYWRlci9kb3MvZG9zbW9kIixtbV9uYW1lLE5VTEwpOwogIC8qIGlmIGZhaWx1cmUsIGV4aXQgKi8KICBFUlIoIkZhaWxlZCB0byBzcGF3biBkb3Ntb2QsIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgZXhpdCgxKTsKIH0KIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2godm9pZCkKewogIExQRE9TVEFTSyBscERvc1Rhc2sgPSBNWl9DdXJyZW50KCk7CiAgQ09OVEVYVCBjb250ZXh0OwogIFREQiAqcFRhc2sgPSAoVERCICopR2xvYmFsTG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiAgQllURSAqcHNwX3N0YXJ0ID0gUFRSX1JFQUxfVE9fTElOKCBscERvc1Rhc2stPnBzcF9zZWcsIDAgKTsKCiAgTVpfRmlsbFBTUChwc3Bfc3RhcnQsIEdldENvbW1hbmRMaW5lQSgpKTsKICBwVGFzay0+ZmxhZ3MgfD0gVERCRl9XSU5PTERBUDsKCiAgbWVtc2V0KCAmY29udGV4dCwgMCwgc2l6ZW9mKGNvbnRleHQpICk7CiAgY29udGV4dC5TZWdDcyAgPSBpbml0X2NzOwogIGNvbnRleHQuRWlwICAgID0gaW5pdF9pcDsKICBjb250ZXh0LlNlZ1NzICA9IGluaXRfc3M7CiAgY29udGV4dC5Fc3AgICAgPSBpbml0X3NwOwogIGNvbnRleHQuU2VnRHMgID0gbHBEb3NUYXNrLT5wc3Bfc2VnOwogIGNvbnRleHQuU2VnRXMgID0gbHBEb3NUYXNrLT5wc3Bfc2VnOwogIGNvbnRleHQuRUZsYWdzID0gMHgwMDA4MDAwMDsgIC8qIHZpcnR1YWwgaW50ZXJydXB0IGZsYWcgKi8KICBET1NWTV9FbnRlciggJmNvbnRleHQgKTsKfQoKc3RhdGljIHZvaWQgTVpfS2lsbFRhc2sodm9pZCkKewogIFRSQUNFKCJraWxsaW5nIERPUyB0YXNrXG4iKTsKICBWR0FfQ2xlYW4oKTsKICBraWxsKGRvc21vZF9waWQsU0lHVEVSTSk7Cn0KCnZvaWQgTVpfRXhpdCggQ09OVEVYVDg2ICpjb250ZXh0LCBCT09MIGNzX3BzcCwgV09SRCByZXR2YWwgKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IE1aX0N1cnJlbnQoKTsKICBpZiAobHBEb3NUYXNrKSB7CiAgICBXT1JEIHBzcF9zZWcgPSBjc19wc3AgPyBjb250ZXh0LT5TZWdDcyA6IGxwRG9zVGFzay0+cHNwX3NlZzsKICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpcHNwX3NlZyA8PCA0KTsKICAgIFBEQjE2ICpwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICBXT1JEIHBhcnBzcCA9IHBzcC0+cGFyZW50UFNQOyAvKiBjaGVjayBmb3IgcGFyZW50IERPUyBwcm9jZXNzICovCiAgICBpZiAocGFycHNwKSB7CiAgICAgIC8qIHJldHJpZXZlIHBhcmVudCdzIHJldHVybiBhZGRyZXNzICovCiAgICAgIEZBUlBST0MxNiByZXRhZGRyID0gSU5UX0dldFJNSGFuZGxlcigweDIyKTsKICAgICAgLyogcmVzdG9yZSBpbnRlcnJ1cHRzICovCiAgICAgIElOVF9TZXRSTUhhbmRsZXIoMHgyMiwgcHNwLT5zYXZlZGludDIyKTsKICAgICAgSU5UX1NldFJNSGFuZGxlcigweDIzLCBwc3AtPnNhdmVkaW50MjMpOwogICAgICBJTlRfU2V0Uk1IYW5kbGVyKDB4MjQsIHBzcC0+c2F2ZWRpbnQyNCk7CiAgICAgIC8qIEZJWE1FOiBkZWFsbG9jYXRlIGZpbGUgaGFuZGxlcyBldGMgKi8KICAgICAgLyogZnJlZSBwcm9jZXNzJ3MgYXNzb2NpYXRlZCBtZW1vcnkKICAgICAgICogRklYTUU6IHdhbGsgbWVtb3J5IGFuZCBkZWFsbG9jYXRlIGFsbCBibG9ja3Mgb3duZWQgYnkgcHJvY2VzcyAqLwogICAgICBET1NNRU1fRnJlZUJsb2NrKERPU01FTV9NYXBSZWFsVG9MaW5lYXIoTUFLRUxPTkcoMCxwc3AtPmVudmlyb25tZW50KSkpOwogICAgICBET1NNRU1fRnJlZUJsb2NrKERPU01FTV9NYXBSZWFsVG9MaW5lYXIoTUFLRUxPTkcoMCxscERvc1Rhc2stPnBzcF9zZWcpKSk7CiAgICAgIC8qIHN3aXRjaCB0byBwYXJlbnQncyBQU1AgKi8KICAgICAgbHBEb3NUYXNrLT5wc3Bfc2VnID0gcGFycHNwOwogICAgICBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpcGFycHNwIDw8IDQpOwogICAgICBwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICAgIC8qIG5vdyByZXR1cm4gdG8gcGFyZW50ICovCiAgICAgIGxwRG9zVGFzay0+cmV0dmFsID0gcmV0dmFsOwogICAgICBjb250ZXh0LT5TZWdDcyA9IFNFTEVDVE9ST0YocmV0YWRkcik7CiAgICAgIGNvbnRleHQtPkVpcCAgID0gT0ZGU0VUT0YocmV0YWRkcik7CiAgICAgIGNvbnRleHQtPlNlZ1NzID0gU0VMRUNUT1JPRihwc3AtPnNhdmVTdGFjayk7CiAgICAgIGNvbnRleHQtPkVzcCAgID0gT0ZGU0VUT0YocHNwLT5zYXZlU3RhY2spOwogICAgICByZXR1cm47CiAgICB9IGVsc2UKICAgICAgTVpfS2lsbFRhc2soKTsKICB9CiAgRXhpdFRocmVhZCggcmV0dmFsICk7Cn0KCiNlbHNlIC8qICFNWl9TVVBQT1JURUQgKi8KCkJPT0wgTVpfTG9hZEltYWdlKCBMUENTVFIgY21kbGluZSApCnsKICBXQVJOKCJET1MgZXhlY3V0YWJsZXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIHBsYXRmb3JtXG4iKTsKICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgcmV0dXJuIEZBTFNFOwp9CgpCT09MIE1aX0V4ZWMoIENPTlRFWFQ4NiAqY29udGV4dCwgTFBDU1RSIGZpbGVuYW1lLCBCWVRFIGZ1bmMsIExQVk9JRCBwYXJhbWJsayApCnsKICAvKiBjYW4ndCBoYXBwZW4gKi8KICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgcmV0dXJuIEZBTFNFOwp9CgpMUERPU1RBU0sgTVpfQWxsb2NEUE1JVGFzayggdm9pZCApCnsKICAgIEVSUigiQWN0dWFsIHJlYWwtbW9kZSBjYWxscyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm0hXG4iKTsKICAgIHJldHVybiBOVUxMOwp9Cgp2b2lkIE1aX0V4aXQoIENPTlRFWFQ4NiAqY29udGV4dCwgQk9PTCBjc19wc3AsIFdPUkQgcmV0dmFsICkKewogIEV4aXRUaHJlYWQoIHJldHZhbCApOwp9CgojZW5kaWYgLyogIU1aX1NVUFBPUlRFRCAqLwoKTFBET1NUQVNLIE1aX0N1cnJlbnQoIHZvaWQgKQp7CiAgcmV0dXJuIGRvc19jdXJyZW50Owp9Cg==