LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJkb3Ntb2QuaCIKI2luY2x1ZGUgIm9wdGlvbnMuaCIKI2luY2x1ZGUgInZnYS5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CgpzdGF0aWMgTFBET1NUQVNLIGRvc19jdXJyZW50OwoKI2lmZGVmIE1aX1NVUFBPUlRFRAoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKLyogZGVmaW5lIHRoaXMgdG8gdHJ5IG1hcHBpbmcgdGhyb3VnaCAvcHJvYy9waWQvbWVtIGluc3RlYWQgb2YgYSB0ZW1wIGZpbGUsCiAgIGJ1dCBMaW51cyBkb2Vzbid0IGxpa2UgbW1hcHBpbmcgL3Byb2MvcGlkL21lbSwgc28gaXQgZG9lc24ndCB3b3JrIGZvciBtZSAqLwojdW5kZWYgTVpfTUFQU0VMRgoKI2RlZmluZSBCSU9TX0RBVEFfU0VHTUVOVCAweDQwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKLyogc3RydWN0dXJlcyBmb3IgRVhFQyAqLwoKdHlwZWRlZiBzdHJ1Y3QgewogIFdPUkQgZW52X3NlZzsKICBEV09SRCBjbWRsaW5lIFdJTkVfUEFDS0VEOwogIERXT1JEIGZjYjEgV0lORV9QQUNLRUQ7CiAgRFdPUkQgZmNiMiBXSU5FX1BBQ0tFRDsKICBXT1JEIGluaXRfc3A7CiAgV09SRCBpbml0X3NzOwogIFdPUkQgaW5pdF9pcDsKICBXT1JEIGluaXRfY3M7Cn0gRXhlY0Jsb2NrOwoKdHlwZWRlZiBzdHJ1Y3QgewogIFdPUkQgbG9hZF9zZWc7CiAgV09SRCByZWxfc2VnOwp9IE92ZXJsYXlCbG9jazsKCi8qIGdsb2JhbCB2YXJpYWJsZXMgKi8KCnN0YXRpYyBXT1JEIGluaXRfY3MsaW5pdF9pcCxpbml0X3NzLGluaXRfc3A7CnN0YXRpYyBjaGFyIG1tX25hbWVbMTI4XTsKCmludCByZWFkX3BpcGUsIHdyaXRlX3BpcGU7CkhBTkRMRSBoUmVhZFBpcGUsIGhXcml0ZVBpcGU7CnBpZF90IGRvc21vZF9waWQ7CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2godm9pZCk7CnN0YXRpYyBCT09MIE1aX0luaXRUYXNrKHZvaWQpOwpzdGF0aWMgdm9pZCBNWl9LaWxsVGFzayh2b2lkKTsKCnN0YXRpYyB2b2lkIE1aX0NyZWF0ZVBTUCggTFBWT0lEIGxwUFNQLCBXT1JEIGVudiwgV09SRCBwYXIgKQp7CiAgUERCMTYqcHNwPWxwUFNQOwoKICBwc3AtPmludDIwPTB4MjBDRDsgLyogaW50IDIwICovCiAgLyogc29tZSBwcm9ncmFtcyB1c2UgdGhpcyB0byBjYWxjdWxhdGUgaG93IG11Y2ggbWVtb3J5IHRoZXkgbmVlZCAqLwogIHBzcC0+bmV4dFBhcmFncmFwaD0weDlGRkY7IC8qIEZJWE1FOiB1c2UgYSByZWFsIHZhbHVlICovCiAgLyogRklYTUU6IGRpc3BhdGNoZXIgKi8KICBwc3AtPnNhdmVkaW50MjIgPSBJTlRfR2V0Uk1IYW5kbGVyKDB4MjIpOwogIHBzcC0+c2F2ZWRpbnQyMyA9IElOVF9HZXRSTUhhbmRsZXIoMHgyMyk7CiAgcHNwLT5zYXZlZGludDI0ID0gSU5UX0dldFJNSGFuZGxlcigweDI0KTsKICBwc3AtPnBhcmVudFBTUD1wYXI7CiAgcHNwLT5lbnZpcm9ubWVudD1lbnY7CiAgLyogRklYTUU6IG1vcmUgUFNQIHN0dWZmICovCn0KCnN0YXRpYyB2b2lkIE1aX0ZpbGxQU1AoIExQVk9JRCBscFBTUCwgTFBDU1RSIGNtZGxpbmUgKQp7CiBQREIxNipwc3A9bHBQU1A7CiBjb25zdCBjaGFyKmNtZD1jbWRsaW5lP3N0cmNocihjbWRsaW5lLCcgJyk6TlVMTDsKCiAvKiBjb3B5IHBhcmFtZXRlcnMgKi8KIGlmIChjbWQpIHsKI2lmIDAKICAvKiBjb21tYW5kLmNvbSBkb2Vzbid0IGRvIHRoaXMgKi8KICB3aGlsZSAoKmNtZCA9PSAnICcpIGNtZCsrOwojZW5kaWYKICBwc3AtPmNtZExpbmVbMF09c3RybGVuKGNtZCk7CiAgc3RyY3B5KHBzcC0+Y21kTGluZSsxLGNtZCk7CiAgcHNwLT5jbWRMaW5lW3BzcC0+Y21kTGluZVswXSsxXT0nXHInOwogfSBlbHNlIHBzcC0+Y21kTGluZVsxXT0nXHInOwogLyogRklYTUU6IG1vcmUgUFNQIHN0dWZmICovCn0KCi8qIGRlZmF1bHQgSU5UIDA4IGhhbmRsZXI6IGluY3JlYXNlcyB0aW1lciB0aWNrIGNvdW50ZXIgYnV0IG5vdCBtdWNoIG1vcmUgKi8Kc3RhdGljIGNoYXIgaW50MDhbXT17CiAweENELDB4MUMsICAgICAgICAgICAvKiBpbnQgJDB4MWMgKi8KIDB4NTAsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVheCAqLwogMHgxRSwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWRzICovCiAweEI4LDB4NDAsMHgwMCwgICAgICAvKiBtb3Z3ICQweDQwLCVheCAqLwogMHg4RSwweEQ4LCAgICAgICAgICAgLyogbW92dyAlYXgsJWRzICovCiNpZiAwCiAweDgzLDB4MDYsMHg2QywweDAwLDB4MDEsIC8qIGFkZHcgJDEsKDB4NmMpICovCiAweDgzLDB4MTYsMHg2RSwweDAwLDB4MDAsIC8qIGFkY3cgJDAsKDB4NmUpICovCiNlbHNlCiAweDY2LDB4RkYsMHgwNiwweDZDLDB4MDAsIC8qIGluY2wgKDB4NmMpICovCiNlbmRpZgogMHhCMCwweDIwLCAgICAgICAgICAgLyogbW92YiAkMHgyMCwlYWwgKi8KIDB4RTYsMHgyMCwgICAgICAgICAgIC8qIG91dGIgJWFsLCQweDIwICovCiAweDFGLCAgICAgICAgICAgICAgICAvKiBwb3B3ICVheCAqLwogMHg1OCwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4Q0YgICAgICAgICAgICAgICAgIC8qIGlyZXQgKi8KfTsKCnN0YXRpYyB2b2lkIE1aX0luaXRIYW5kbGVycyh2b2lkKQp7CiBXT1JEIHNlZzsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2soc2l6ZW9mKGludDA4KSwmc2VnKTsKIG1lbWNweShzdGFydCxpbnQwOCxzaXplb2YoaW50MDgpKTsKLyogSU5UIDA4OiBwb2ludCBpdCBhdCBvdXIgdGljay1pbmNyZW1lbnRpbmcgaGFuZGxlciAqLwogKChTRUdQVFIqKTApWzB4MDhdPU1BS0VTRUdQVFIoc2VnLDApOwovKiBJTlQgMUM6IGp1c3QgcG9pbnQgaXQgdG8gSVJFVCwgd2UgZG9uJ3Qgd2FudCB0byBoYW5kbGUgaXQgb3Vyc2VsdmVzICovCiAoKFNFR1BUUiopMClbMHgxQ109TUFLRVNFR1BUUihzZWcsc2l6ZW9mKGludDA4KS0xKTsKfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fR2V0QmxvY2soc3orc2l6ZW9mKFdPUkQpK3N0cmxlbihuYW1lKSsxLCZzZWcpOwogLyogZmlsbCBpdCAqLwogaWYgKGVudikgewogIG1lbWNweShlbnZibGssZW52LHN6KTsKIH0gZWxzZSBlbnZibGtbMF09MDsKIC8qIERPUyAzLng6IHRoZSBibG9jayBjb250YWlucyAxIGFkZGl0aW9uYWwgc3RyaW5nICovCiAqKFdPUkQqKShlbnZibGsrc3opPTE7CiAvKiBiZWluZyB0aGUgcHJvZ3JhbSBuYW1lIGl0c2VsZiAqLwogc3RyY3B5KGVudmJsaytzeitzaXplb2YoV09SRCksbmFtZSk7CiByZXR1cm4gc2VnOwp9CgpzdGF0aWMgQk9PTCBNWl9Jbml0TWVtb3J5KHZvaWQpCnsKICAgIGludCBtbV9mZDsKICAgIHZvaWQgKmltZ19iYXNlOwoKICAgIC8qIGluaXRpYWxpemUgdGhlIG1lbW9yeSAqLwogICAgVFJBQ0UoIkluaXRpYWxpemluZyBET1MgbWVtb3J5IHN0cnVjdHVyZXNcbiIpOwogICAgRE9TTUVNX0luaXQoVFJVRSk7CgogICAgLyogYWxsb2NhdGUgMU1CKzY0SyBzaGFyZWQgbWVtb3J5ICovCiAgICB0bXBuYW0obW1fbmFtZSk7CiAgICAvKiBzdHJjcHkobW1fbmFtZSwiL3RtcC9teWRvc2ltYWdlIik7ICovCiAgICBtbV9mZCA9IG9wZW4obW1fbmFtZSxPX1JEV1J8T19DUkVBVCAvKiB8T19UUlVOQyAqLyxTX0lSVVNSfFNfSVdVU1IpOwogICAgaWYgKG1tX2ZkIDwgMCkgRVJSKCJmaWxlICVzIGNvdWxkIG5vdCBiZSBvcGVuZWRcbiIsbW1fbmFtZSk7CiAgICAvKiBmaWxsIHRoZSBmaWxlIHdpdGggdGhlIERPUyBtZW1vcnkgKi8KICAgIGlmICh3cml0ZSggbW1fZmQsIE5VTEwsIDB4MTEwMDAwICkgIT0gMHgxMTAwMDApIEVSUigiY2Fubm90IHdyaXRlIERPUyBtZW1cbiIpOwogICAgLyogbWFwIGl0IGluICovCiAgICBpbWdfYmFzZSA9IG1tYXAoTlVMTCwweDExMDAwMCxQUk9UX1JFQUR8UFJPVF9XUklURXxQUk9UX0VYRUMsTUFQX1NIQVJFRHxNQVBfRklYRUQsbW1fZmQsMCk7CiAgICBjbG9zZSggbW1fZmQgKTsKCiAgICBpZiAoaW1nX2Jhc2UpCiAgICB7CiAgICAgICAgRVJSKCJjb3VsZCBub3QgbWFwIHNoYXJlZCBtZW1vcnksIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgTVpfSW5pdEhhbmRsZXJzKCk7CiAgICByZXR1cm4gVFJVRTsKfQoKQk9PTCBNWl9Eb0xvYWRJbWFnZSggSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUsIE92ZXJsYXlCbG9jayAqb2JsayApCnsKICBMUERPU1RBU0sgbHBEb3NUYXNrID0gZG9zX2N1cnJlbnQ7CiAgSU1BR0VfRE9TX0hFQURFUiBtel9oZWFkZXI7CiAgRFdPUkQgaW1hZ2Vfc3RhcnQsaW1hZ2Vfc2l6ZSxtaW5fc2l6ZSxtYXhfc2l6ZSxhdmFpbDsKICBCWVRFKnBzcF9zdGFydCwqbG9hZF9zdGFydCwqb2xkZW52OwogIGludCB4LCBvbGRfY29tPTAsIGFsbG9jOwogIFNFR1BUUiByZWxvYzsKICBXT1JEIGVudl9zZWcsIGxvYWRfc2VnLCByZWxfc2VnLCBvbGRwc3Bfc2VnOwogIERXT1JEIGxlbjsKCiAgaWYgKGxwRG9zVGFzaykgewogICAgLyogRE9TIHByb2Nlc3MgYWxyZWFkeSBydW5uaW5nLCBpbmhlcml0IGZyb20gaXQgKi8KICAgIFBEQjE2KiBwYXJfcHNwID0gKFBEQjE2KikoKERXT1JEKWxwRG9zVGFzay0+cHNwX3NlZyA8PCA0KTsKICAgIGFsbG9jPTA7CiAgICBvbGRlbnYgPSAoTFBCWVRFKSgoRFdPUkQpcGFyX3BzcC0+ZW52aXJvbm1lbnQgPDwgNCk7CiAgICBvbGRwc3Bfc2VnID0gbHBEb3NUYXNrLT5wc3Bfc2VnOwogIH0gZWxzZSB7CiAgICAvKiBhbGxvY2F0ZSBuZXcgRE9TIHByb2Nlc3MsIGluaGVyaXRpbmcgZnJvbSBXaW5lIGVudmlyb25tZW50ICovCiAgICBhbGxvYz0xOwogICAgbHBEb3NUYXNrID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihET1NUQVNLKSk7CiAgICBkb3NfY3VycmVudCA9IGxwRG9zVGFzazsKICAgIG9sZGVudiA9IEdldEVudmlyb25tZW50U3RyaW5nc0EoKTsKICAgIG9sZHBzcF9zZWcgPSAwOwogIH0KCiBTZXRGaWxlUG9pbnRlcihoRmlsZSwwLE5VTEwsRklMRV9CRUdJTik7CiBpZiAoICAgIVJlYWRGaWxlKGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlciksJmxlbixOVUxMKQogICAgIHx8IGxlbiAhPSBzaXplb2YobXpfaGVhZGVyKSAKICAgICB8fCBtel9oZWFkZXIuZV9tYWdpYyAhPSBJTUFHRV9ET1NfU0lHTkFUVVJFKSB7CiAgY2hhciAqcCA9IHN0cnJjaHIoIGZpbGVuYW1lLCAnLicgKTsKICBpZiAoIXAgfHwgc3RyY2FzZWNtcCggcCwgIi5jb20iICkpICAvKiBjaGVjayBmb3IgLkNPTSBleHRlbnNpb24gKi8KICB7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogIH0KICBvbGRfY29tPTE7IC8qIGFzc3VtZSAuQ09NIGZpbGUgKi8KICBpbWFnZV9zdGFydD0wOwogIGltYWdlX3NpemU9R2V0RmlsZVNpemUoaEZpbGUsTlVMTCk7CiAgbWluX3NpemU9MHgxMDAwMDsgbWF4X3NpemU9MHgxMDAwMDA7CiAgbXpfaGVhZGVyLmVfY3JsYz0wOwogIG16X2hlYWRlci5lX3NzPTA7IG16X2hlYWRlci5lX3NwPTB4RkZGRTsKICBtel9oZWFkZXIuZV9jcz0wOyBtel9oZWFkZXIuZV9pcD0weDEwMDsKIH0gZWxzZSB7CiAgLyogY2FsY3VsYXRlIGxvYWQgc2l6ZSAqLwogIGltYWdlX3N0YXJ0PW16X2hlYWRlci5lX2NwYXJoZHI8PDQ7CiAgaW1hZ2Vfc2l6ZT1tel9oZWFkZXIuZV9jcDw8OTsgLyogcGFnZXMgYXJlIDUxMiBieXRlcyAqLwogIGlmICgobXpfaGVhZGVyLmVfY2JscCE9MCkmJihtel9oZWFkZXIuZV9jYmxwIT00KSkgaW1hZ2Vfc2l6ZS09NTEyLW16X2hlYWRlci5lX2NibHA7CiAgaW1hZ2Vfc2l6ZS09aW1hZ2Vfc3RhcnQ7CiAgbWluX3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21pbmFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogIG1heF9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9tYXhhbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKIH0KCiAgaWYgKGFsbG9jKSBNWl9Jbml0TWVtb3J5KCk7CgogIGlmIChvYmxrKSB7CiAgICAvKiBsb2FkIG92ZXJsYXkgaW50byBwcmVhbGxvY2F0ZWQgbWVtb3J5ICovCiAgICBsb2FkX3NlZz1vYmxrLT5sb2FkX3NlZzsKICAgIHJlbF9zZWc9b2Jsay0+cmVsX3NlZzsKICAgIGxvYWRfc3RhcnQ9KExQQllURSkoKERXT1JEKWxvYWRfc2VnPDw0KTsKICB9IGVsc2UgewogICAgLyogYWxsb2NhdGUgZW52aXJvbm1lbnQgYmxvY2sgKi8KICAgIGVudl9zZWc9TVpfSW5pdEVudmlyb25tZW50KG9sZGVudiwgZmlsZW5hbWUpOwoKICAgIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGV4ZWN1dGFibGUgKi8KICAgIFRSQUNFKCJBbGxvY2F0aW5nIERPUyBtZW1vcnkgKG1pbj0lbGQsIG1heD0lbGQpXG4iLG1pbl9zaXplLG1heF9zaXplKTsKICAgIGF2YWlsPURPU01FTV9BdmFpbGFibGUoKTsKICAgIGlmIChhdmFpbDxtaW5fc2l6ZSkgewogICAgICBFUlIoImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogICAgfQogICAgaWYgKGF2YWlsPm1heF9zaXplKSBhdmFpbD1tYXhfc2l6ZTsKICAgIHBzcF9zdGFydD1ET1NNRU1fR2V0QmxvY2soYXZhaWwsJmxwRG9zVGFzay0+cHNwX3NlZyk7CiAgICBpZiAoIXBzcF9zdGFydCkgewogICAgICBFUlIoImVycm9yIGFsbG9jYXRpbmcgRE9TIG1lbW9yeVxuIik7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgIH0KICAgIGxvYWRfc2VnPWxwRG9zVGFzay0+cHNwX3NlZysob2xkX2NvbT8wOlBTUF9TSVpFKTsKICAgIHJlbF9zZWc9bG9hZF9zZWc7CiAgICBsb2FkX3N0YXJ0PXBzcF9zdGFydCsoUFNQX1NJWkU8PDQpOwogICAgTVpfQ3JlYXRlUFNQKHBzcF9zdGFydCwgZW52X3NlZywgb2xkcHNwX3NlZyk7CiAgfQoKIC8qIGxvYWQgZXhlY3V0YWJsZSBpbWFnZSAqLwogVFJBQ0UoImxvYWRpbmcgRE9TICVzIGltYWdlLCAlMDhseCBieXRlc1xuIixvbGRfY29tPyJDT00iOiJFWEUiLGltYWdlX3NpemUpOwogU2V0RmlsZVBvaW50ZXIoaEZpbGUsaW1hZ2Vfc3RhcnQsTlVMTCxGSUxFX0JFR0lOKTsKIGlmICghUmVhZEZpbGUoaEZpbGUsbG9hZF9zdGFydCxpbWFnZV9zaXplLCZsZW4sTlVMTCkgfHwgbGVuICE9IGltYWdlX3NpemUpIHsKICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgZ290byBsb2FkX2Vycm9yOwogfQoKIGlmIChtel9oZWFkZXIuZV9jcmxjKSB7CiAgLyogbG9hZCByZWxvY2F0aW9uIHRhYmxlICovCiAgVFJBQ0UoImxvYWRpbmcgRE9TIEVYRSByZWxvY2F0aW9uIHRhYmxlLCAlZCBlbnRyaWVzXG4iLG16X2hlYWRlci5lX2NybGMpOwogIC8qIEZJWE1FOiBpcyB0aGlzIHRvbyBzbG93IHdpdGhvdXQgcmVhZCBidWZmZXJpbmc/ICovCiAgU2V0RmlsZVBvaW50ZXIoaEZpbGUsbXpfaGVhZGVyLmVfbGZhcmxjLE5VTEwsRklMRV9CRUdJTik7CiAgZm9yICh4PTA7IHg8bXpfaGVhZGVyLmVfY3JsYzsgeCsrKSB7CiAgIGlmICghUmVhZEZpbGUoaEZpbGUsJnJlbG9jLHNpemVvZihyZWxvYyksJmxlbixOVUxMKSB8fCBsZW4gIT0gc2l6ZW9mKHJlbG9jKSkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgZ290byBsb2FkX2Vycm9yOwogICB9CiAgICooV09SRCopU0VHUFRSMTYobG9hZF9zdGFydCxyZWxvYykrPXJlbF9zZWc7CiAgfQogfQoKICBpZiAoIW9ibGspIHsKICAgIGluaXRfY3MgPSBsb2FkX3NlZyttel9oZWFkZXIuZV9jczsKICAgIGluaXRfaXAgPSBtel9oZWFkZXIuZV9pcDsKICAgIGluaXRfc3MgPSBsb2FkX3NlZyttel9oZWFkZXIuZV9zczsKICAgIGluaXRfc3AgPSBtel9oZWFkZXIuZV9zcDsKCiAgICBUUkFDRSgiZW50cnkgcG9pbnQ6ICUwNHg6JTA0eFxuIixpbml0X2NzLGluaXRfaXApOwogIH0KCiAgaWYgKGFsbG9jICYmICFNWl9Jbml0VGFzaygpKSB7CiAgICBNWl9LaWxsVGFzaygpOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0dFTl9GQUlMVVJFKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIHJldHVybiBUUlVFOwoKbG9hZF9lcnJvcjoKICBscERvc1Rhc2stPnBzcF9zZWcgPSBvbGRwc3Bfc2VnOwogIGlmIChhbGxvYykgewogICAgZG9zX2N1cnJlbnQgPSBOVUxMOwogICAgaWYgKG1tX25hbWVbMF0hPTApIHVubGluayhtbV9uYW1lKTsKICB9CgogIHJldHVybiBGQUxTRTsKfQoKQk9PTCBNWl9Mb2FkSW1hZ2UoIExQQ1NUUiBjbWRsaW5lICkKewogICAgSEZJTEUgaEZpbGU7CiAgICBjaGFyICpuYW1lLCBidWZmZXJbTUFYX1BBVEhdOwogICAgTFBDU1RSIHAgPSBzdHJjaHIoIGNtZGxpbmUsICcgJyApOwoKICAgIGlmIChwKQogICAgewogICAgICAgIGlmICghKG5hbWUgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIHAgLSBjbWRsaW5lICsgMSApKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIG1lbWNweSggbmFtZSwgY21kbGluZSwgcCAtIGNtZGxpbmUgKTsKICAgICAgICBuYW1lW3AgLSBjbWRsaW5lXSA9IDA7CiAgICB9CiAgICBlbHNlIG5hbWUgPSAoY2hhciAqKWNtZGxpbmU7CgogICAgaWYgKCFTZWFyY2hQYXRoQSggTlVMTCwgbmFtZSwgIi5leGUiLCBzaXplb2YoYnVmZmVyKSwgYnVmZmVyLCBOVUxMICkpIGdvdG8gZXJyb3I7CiAgICBpZiAoKGhGaWxlID0gQ3JlYXRlRmlsZUEoIGJ1ZmZlciwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIC0xICkpID09IElOVkFMSURfSEFORExFX1ZBTFVFKQogICAgICAgIGdvdG8gZXJyb3I7CiAgICBpZiAoIU1aX0RvTG9hZEltYWdlKCBoRmlsZSwgYnVmZmVyLCBOVUxMICkpCiAgICB7CiAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIE1aX0xhdW5jaCgpOwogZXJyb3I6CiAgICBpZiAobmFtZSAhPSBjbWRsaW5lKSBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbmFtZSApOwogICAgcmV0dXJuIEZBTFNFOwp9CgpCT09MIE1aX0V4ZWMoIENPTlRFWFQ4NiAqY29udGV4dCwgTFBDU1RSIGZpbGVuYW1lLCBCWVRFIGZ1bmMsIExQVk9JRCBwYXJhbWJsayApCnsKICAvKiB0aGlzIG1heSBvbmx5IGJlIGNhbGxlZCBmcm9tIGV4aXN0aW5nIERPUyBwcm9jZXNzZXMKICAgKiAoaS5lLiBvbmUgRE9TIGFwcCBzcGF3bmluZyBhbm90aGVyKSAqLwogIC8qIEZJWE1FOiBkbyB3ZSB3YW50IHRvIGNoZWNrIGJpbmFyeSB0eXBlIGZpcnN0LCB0byBjaGVjawogICAqIHdoZXRoZXIgaXQncyBhIE5FL1BFIGV4ZWN1dGFibGU/ICovCiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IE1aX0N1cnJlbnQoKTsKICBIRklMRSBoRmlsZSA9IENyZWF0ZUZpbGVBKCBmaWxlbmFtZSwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsCgkJCSAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgLTEpOwogIEJPT0wgcmV0ID0gRkFMU0U7CiAgaWYgKGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSByZXR1cm4gRkFMU0U7CiAgc3dpdGNoIChmdW5jKSB7CiAgY2FzZSAwOiAvKiBsb2FkIGFuZCBleGVjdXRlICovCiAgY2FzZSAxOiAvKiBsb2FkIGJ1dCBkb24ndCBleGVjdXRlICovCiAgICB7CiAgICAgIC8qIHNhdmUgY3VycmVudCBwcm9jZXNzJ3MgcmV0dXJuIFNTOlNQIG5vdyAqLwogICAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKWxwRG9zVGFzay0+cHNwX3NlZyA8PCA0KTsKICAgICAgUERCMTYgKnBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgICAgcHNwLT5zYXZlU3RhY2sgPSAoRFdPUkQpTUFLRVNFR1BUUihjb250ZXh0LT5TZWdTcywgTE9XT1JEKGNvbnRleHQtPkVzcCkpOwogICAgfQogICAgcmV0ID0gTVpfRG9Mb2FkSW1hZ2UoIGhGaWxlLCBmaWxlbmFtZSwgTlVMTCApOwogICAgaWYgKHJldCkgewogICAgICAvKiBNWl9Mb2FkSW1hZ2UgY3JlYXRlZCBhIG5ldyBQU1AgYW5kIGxvYWRlZCBuZXcgdmFsdWVzIGludG8gbHBEb3NUYXNrLAogICAgICAgKiBsZXQncyB3b3JrIG9uIHRoZSBuZXcgdmFsdWVzIG5vdyAqLwogICAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKWxwRG9zVGFzay0+cHNwX3NlZyA8PCA0KTsKICAgICAgRXhlY0Jsb2NrICpibGsgPSAoRXhlY0Jsb2NrICopcGFyYW1ibGs7CiAgICAgIE1aX0ZpbGxQU1AocHNwX3N0YXJ0LCBET1NNRU1fTWFwUmVhbFRvTGluZWFyKGJsay0+Y21kbGluZSkpOwogICAgICAvKiB0aGUgbGFtZSBNUy1ET1MgZW5naW5lZXJzIGRlY2lkZWQgdGhhdCB0aGUgcmV0dXJuIGFkZHJlc3Mgc2hvdWxkIGJlIGluIGludDIyICovCiAgICAgIElOVF9TZXRSTUhhbmRsZXIoMHgyMiwgKEZBUlBST0MxNilNQUtFU0VHUFRSKGNvbnRleHQtPlNlZ0NzLCBMT1dPUkQoY29udGV4dC0+RWlwKSkpOwogICAgICBpZiAoZnVuYykgewoJLyogZG9uJ3QgZXhlY3V0ZSwganVzdCByZXR1cm4gc3RhcnR1cCBzdGF0ZSAqLwoJYmxrLT5pbml0X2NzID0gaW5pdF9jczsKCWJsay0+aW5pdF9pcCA9IGluaXRfaXA7CglibGstPmluaXRfc3MgPSBpbml0X3NzOwoJYmxrLT5pbml0X3NwID0gaW5pdF9zcDsKICAgICAgfSBlbHNlIHsKCS8qIGV4ZWN1dGUgYnkgbWFraW5nIHVzIHJldHVybiB0byBuZXcgcHJvY2VzcyAqLwoJY29udGV4dC0+U2VnQ3MgPSBpbml0X2NzOwoJY29udGV4dC0+RWlwICAgPSBpbml0X2lwOwoJY29udGV4dC0+U2VnU3MgPSBpbml0X3NzOwoJY29udGV4dC0+RXNwICAgPSBpbml0X3NwOwoJY29udGV4dC0+U2VnRHMgPSBscERvc1Rhc2stPnBzcF9zZWc7Cgljb250ZXh0LT5TZWdFcyA9IGxwRG9zVGFzay0+cHNwX3NlZzsKCWNvbnRleHQtPkVheCAgID0gMDsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSAzOiAvKiBsb2FkIG92ZXJsYXkgKi8KICAgIHsKICAgICAgT3ZlcmxheUJsb2NrICpibGsgPSAoT3ZlcmxheUJsb2NrICopcGFyYW1ibGs7CiAgICAgIHJldCA9IE1aX0RvTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIGJsayApOwogICAgfQogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIEZJWE1FKCJFWEVDIGxvYWQgdHlwZSAlZCBub3QgaW1wbGVtZW50ZWRcbiIsIGZ1bmMpOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRlVOQ1RJT04pOwogICAgYnJlYWs7CiAgfQogIENsb3NlSGFuZGxlKGhGaWxlKTsKICByZXR1cm4gcmV0Owp9CgpMUERPU1RBU0sgTVpfQWxsb2NEUE1JVGFzayggdm9pZCApCnsKICBMUERPU1RBU0sgbHBEb3NUYXNrID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihET1NUQVNLKSk7CgogIGlmIChscERvc1Rhc2spIHsKICAgIGRvc19jdXJyZW50ID0gbHBEb3NUYXNrOwogICAgTVpfSW5pdE1lbW9yeSgpOwogICAgTVpfSW5pdFRhc2soKTsKICB9CiAgcmV0dXJuIGxwRG9zVGFzazsKfQoKc3RhdGljIHZvaWQgTVpfSW5pdFRpbWVyKCBpbnQgdmVyICkKewogaWYgKHZlcjwxKSB7CiAgLyogY2FuJ3QgbWFrZSB0aW1lciB0aWNrcyAqLwogfSBlbHNlIHsKICBpbnQgZnVuYzsKICBzdHJ1Y3QgdGltZXZhbCB0aW07CgogIC8qIHN0YXJ0IGRvc21vZCB0aW1lciBhdCA1NW1zICgxOC4ySHopICovCiAgZnVuYz1ET1NNT0RfU0VUX1RJTUVSOwogIHRpbS50dl9zZWM9MDsgdGltLnR2X3VzZWM9NTQ5MjU7CiAgd3JpdGUod3JpdGVfcGlwZSwmZnVuYyxzaXplb2YoZnVuYykpOwogIHdyaXRlKHdyaXRlX3BpcGUsJnRpbSxzaXplb2YodGltKSk7CiB9Cn0KCnN0YXRpYyBCT09MIE1aX0luaXRUYXNrKHZvaWQpCnsKICBpbnQgd3JpdGVfZmRbMl0seF9mZDsKICBwaWRfdCBjaGlsZDsKICBjaGFyIHBhdGhbMjU2XSwqZnBhdGg7CgogIC8qIGNyZWF0ZSBwaXBlcyAqLwogIGlmICghQ3JlYXRlUGlwZSgmaFJlYWRQaXBlLCZoV3JpdGVQaXBlLE5VTEwsMCkpIHJldHVybiBGQUxTRTsKICBpZiAocGlwZSh3cml0ZV9mZCk8MCkgewogICAgQ2xvc2VIYW5kbGUoaFJlYWRQaXBlKTsKICAgIENsb3NlSGFuZGxlKGhXcml0ZVBpcGUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgcmVhZF9waXBlID0gRklMRV9HZXRVbml4SGFuZGxlKCBoUmVhZFBpcGUsIEdFTkVSSUNfUkVBRCApOwogIHhfZmQgPSBGSUxFX0dldFVuaXhIYW5kbGUoIGhXcml0ZVBpcGUsIEdFTkVSSUNfV1JJVEUgKTsKCiAgVFJBQ0UoIndpbjMyIHBpcGU6IHJlYWQ9JWQsIHdyaXRlPSVkLCB1bml4IHBpcGU6IHJlYWQ9JWQsIHdyaXRlPSVkXG4iLAogICAgICAgIGhSZWFkUGlwZSxoV3JpdGVQaXBlLHJlYWRfcGlwZSx4X2ZkKTsKICBUUkFDRSgib3V0Ym91bmQgdW5peCBwaXBlOiByZWFkPSVkLCB3cml0ZT0lZCwgcGlkPSVkXG4iLHdyaXRlX2ZkWzBdLHdyaXRlX2ZkWzFdLGdldHBpZCgpKTsKCiAgd3JpdGVfcGlwZT13cml0ZV9mZFsxXTsKCiAgVFJBQ0UoIkxvYWRpbmcgRE9TIFZNIHN1cHBvcnQgbW9kdWxlXG4iKTsKICBpZiAoKGNoaWxkPWZvcmsoKSk8MCkgewogICAgY2xvc2Uod3JpdGVfZmRbMF0pOwogICAgY2xvc2UocmVhZF9waXBlKTsKICAgIGNsb3NlKHdyaXRlX3BpcGUpOwogICAgY2xvc2UoeF9mZCk7CiAgICBDbG9zZUhhbmRsZShoUmVhZFBpcGUpOwogICAgQ2xvc2VIYW5kbGUoaFdyaXRlUGlwZSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQogaWYgKGNoaWxkIT0wKSB7CiAgLyogcGFyZW50IHByb2Nlc3MgKi8KICBpbnQgcmV0OwoKICBjbG9zZSh3cml0ZV9mZFswXSk7CiAgY2xvc2UoeF9mZCk7CiAgZG9zbW9kX3BpZCA9IGNoaWxkOwogIC8qIHdhaXQgZm9yIGNoaWxkIHByb2Nlc3MgdG8gc2lnbmFsIHJlYWRpbmVzcyAqLwogIHdoaWxlICgxKSB7CiAgICBpZiAocmVhZChyZWFkX3BpcGUsJnJldCxzaXplb2YocmV0KSk9PXNpemVvZihyZXQpKSBicmVhazsKICAgIGlmICgoZXJybm89PUVJTlRSKXx8KGVycm5vPT1FQUdBSU4pKSBjb250aW51ZTsKICAgIC8qIGZhaWx1cmUgKi8KICAgIEVSUigiZG9zbW9kIGhhcyBmYWlsZWQgdG8gaW5pdGlhbGl6ZVxuIik7CiAgICBpZiAobW1fbmFtZVswXSE9MCkgdW5saW5rKG1tX25hbWUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KICAvKiB0aGUgY2hpbGQgaGFzIG5vdyBtbWFwZWQgdGhlIHRlbXAgZmlsZSwgaXQncyBub3cgc2FmZSB0byB1bmxpbmsuCiAgICogZG8gaXQgaGVyZSB0byBhdm9pZCBsZWF2aW5nIGEgbWVzcyBpbiAvdG1wIGlmL3doZW4gV2luZSBjcmFzaGVzLi4uICovCiAgaWYgKG1tX25hbWVbMF0hPTApIHVubGluayhtbV9uYW1lKTsKICAvKiBzdGFydCBzaW11bGF0ZWQgc3lzdGVtIHRpbWVyICovCiAgTVpfSW5pdFRpbWVyKHJldCk7CiAgaWYgKHJldDwyKSB7CiAgICBFUlIoImRvc21vZCB2ZXJzaW9uIHRvbyBvbGQhIFBsZWFzZSBpbnN0YWxsIG5ld2VyIGRvc21vZCBwcm9wZXJseVxuIik7CiAgICBFUlIoIklmIHlvdSBkb24ndCwgdGhlIG5ldyBkb3Ntb2QgZXZlbnQgaGFuZGxpbmcgc3lzdGVtIHdpbGwgbm90IHdvcmtcbiIpOwogIH0KICAvKiBhbGwgc3lzdGVtcyBhcmUgbm93IGdvICovCiB9IGVsc2UgewogIC8qIGNoaWxkIHByb2Nlc3MgKi8KICBjbG9zZShyZWFkX3BpcGUpOwogIGNsb3NlKHdyaXRlX3BpcGUpOwogIC8qIHB1dCBvdXIgcGlwZXMgc29tZXdoZXJlIGRvc21vZCBjYW4gZmluZCB0aGVtICovCiAgZHVwMih3cml0ZV9mZFswXSwwKTsgLyogc3RkaW4gKi8KICBkdXAyKHhfZmQsMSk7ICAgICAgICAvKiBzdGRvdXQgKi8KICAvKiBub3cgbG9hZCBkb3Ntb2QgKi8KICAvKiBjaGVjayBhcmd2WzBdLWRlcml2ZWQgcGF0aHMgZmlyc3QsIHNpbmNlIHRoZSBuZXdlc3QgZG9zbW9kIGlzIG1vc3QgbGlrZWx5IHRoZXJlCiAgICogKGF0IGxlYXN0IGl0IHdhcyBvbmNlIGZvciBBbmRyZWFzIE1vaHIsIHNvIEkgZGVjaWRlZCB0byBtYWtlIGl0IGVhc2llciBmb3IgaGltKSAqLwogIGZwYXRoPXN0cnJjaHIoc3RyY3B5KHBhdGgsZnVsbF9hcmd2MCksJy8nKTsKICBpZiAoZnBhdGgpIHsKICAgc3RyY3B5KGZwYXRoLCIvZG9zbW9kIik7CiAgIGV4ZWNsKHBhdGgsbW1fbmFtZSxOVUxMKTsKICAgc3RyY3B5KGZwYXRoLCIvbG9hZGVyL2Rvcy9kb3Ntb2QiKTsKICAgZXhlY2wocGF0aCxtbV9uYW1lLE5VTEwpOwogIH0KICAvKiBva2F5LCBpdCB3YXNuJ3QgdGhlcmUsIHRyeSBpbiB0aGUgcGF0aCAqLwogIGV4ZWNscCgiZG9zbW9kIixtbV9uYW1lLE5VTEwpOwogIC8qIGxhc3QgZGVzcGVyYXRlIGF0dGVtcHRzOiBjdXJyZW50IGRpcmVjdG9yeSAqLwogIGV4ZWNsKCJkb3Ntb2QiLG1tX25hbWUsTlVMTCk7CiAgLyogYW5kLCBqdXN0IGZvciBjb21wbGV0ZW5lc3MuLi4gKi8KICBleGVjbCgibG9hZGVyL2Rvcy9kb3Ntb2QiLG1tX25hbWUsTlVMTCk7CiAgLyogaWYgZmFpbHVyZSwgZXhpdCAqLwogIEVSUigiRmFpbGVkIHRvIHNwYXduIGRvc21vZCwgZXJyb3I9JXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICBleGl0KDEpOwogfQogcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCh2b2lkKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IE1aX0N1cnJlbnQoKTsKICBDT05URVhUIGNvbnRleHQ7CiAgVERCICpwVGFzayA9IChUREIgKilHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKICBCWVRFICpwc3Bfc3RhcnQgPSBQVFJfUkVBTF9UT19MSU4oIGxwRG9zVGFzay0+cHNwX3NlZywgMCApOwoKICBNWl9GaWxsUFNQKHBzcF9zdGFydCwgR2V0Q29tbWFuZExpbmVBKCkpOwogIHBUYXNrLT5mbGFncyB8PSBUREJGX1dJTk9MREFQOwoKICBtZW1zZXQoICZjb250ZXh0LCAwLCBzaXplb2YoY29udGV4dCkgKTsKICBjb250ZXh0LlNlZ0NzICA9IGluaXRfY3M7CiAgY29udGV4dC5FaXAgICAgPSBpbml0X2lwOwogIGNvbnRleHQuU2VnU3MgID0gaW5pdF9zczsKICBjb250ZXh0LkVzcCAgICA9IGluaXRfc3A7CiAgY29udGV4dC5TZWdEcyAgPSBscERvc1Rhc2stPnBzcF9zZWc7CiAgY29udGV4dC5TZWdFcyAgPSBscERvc1Rhc2stPnBzcF9zZWc7CiAgY29udGV4dC5FRmxhZ3MgPSAweDAwMDgwMDAwOyAgLyogdmlydHVhbCBpbnRlcnJ1cHQgZmxhZyAqLwogIERPU1ZNX0VudGVyKCAmY29udGV4dCApOwp9CgpzdGF0aWMgdm9pZCBNWl9LaWxsVGFzayh2b2lkKQp7CiAgVFJBQ0UoImtpbGxpbmcgRE9TIHRhc2tcbiIpOwogIFZHQV9DbGVhbigpOwogIGtpbGwoZG9zbW9kX3BpZCxTSUdURVJNKTsKfQoKdm9pZCBNWl9FeGl0KCBDT05URVhUODYgKmNvbnRleHQsIEJPT0wgY3NfcHNwLCBXT1JEIHJldHZhbCApCnsKICBMUERPU1RBU0sgbHBEb3NUYXNrID0gTVpfQ3VycmVudCgpOwogIGlmIChscERvc1Rhc2spIHsKICAgIFdPUkQgcHNwX3NlZyA9IGNzX3BzcCA/IGNvbnRleHQtPlNlZ0NzIDogbHBEb3NUYXNrLT5wc3Bfc2VnOwogICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClwc3Bfc2VnIDw8IDQpOwogICAgUERCMTYgKnBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgIFdPUkQgcGFycHNwID0gcHNwLT5wYXJlbnRQU1A7IC8qIGNoZWNrIGZvciBwYXJlbnQgRE9TIHByb2Nlc3MgKi8KICAgIGlmIChwYXJwc3ApIHsKICAgICAgLyogcmV0cmlldmUgcGFyZW50J3MgcmV0dXJuIGFkZHJlc3MgKi8KICAgICAgRkFSUFJPQzE2IHJldGFkZHIgPSBJTlRfR2V0Uk1IYW5kbGVyKDB4MjIpOwogICAgICAvKiByZXN0b3JlIGludGVycnVwdHMgKi8KICAgICAgSU5UX1NldFJNSGFuZGxlcigweDIyLCBwc3AtPnNhdmVkaW50MjIpOwogICAgICBJTlRfU2V0Uk1IYW5kbGVyKDB4MjMsIHBzcC0+c2F2ZWRpbnQyMyk7CiAgICAgIElOVF9TZXRSTUhhbmRsZXIoMHgyNCwgcHNwLT5zYXZlZGludDI0KTsKICAgICAgLyogRklYTUU6IGRlYWxsb2NhdGUgZmlsZSBoYW5kbGVzIGV0YyAqLwogICAgICAvKiBmcmVlIHByb2Nlc3MncyBhc3NvY2lhdGVkIG1lbW9yeQogICAgICAgKiBGSVhNRTogd2FsayBtZW1vcnkgYW5kIGRlYWxsb2NhdGUgYWxsIGJsb2NrcyBvd25lZCBieSBwcm9jZXNzICovCiAgICAgIERPU01FTV9GcmVlQmxvY2soRE9TTUVNX01hcFJlYWxUb0xpbmVhcihNQUtFTE9ORygwLHBzcC0+ZW52aXJvbm1lbnQpKSk7CiAgICAgIERPU01FTV9GcmVlQmxvY2soRE9TTUVNX01hcFJlYWxUb0xpbmVhcihNQUtFTE9ORygwLGxwRG9zVGFzay0+cHNwX3NlZykpKTsKICAgICAgLyogc3dpdGNoIHRvIHBhcmVudCdzIFBTUCAqLwogICAgICBscERvc1Rhc2stPnBzcF9zZWcgPSBwYXJwc3A7CiAgICAgIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClwYXJwc3AgPDwgNCk7CiAgICAgIHBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgICAgLyogbm93IHJldHVybiB0byBwYXJlbnQgKi8KICAgICAgbHBEb3NUYXNrLT5yZXR2YWwgPSByZXR2YWw7CiAgICAgIGNvbnRleHQtPlNlZ0NzID0gU0VMRUNUT1JPRihyZXRhZGRyKTsKICAgICAgY29udGV4dC0+RWlwICAgPSBPRkZTRVRPRihyZXRhZGRyKTsKICAgICAgY29udGV4dC0+U2VnU3MgPSBTRUxFQ1RPUk9GKHBzcC0+c2F2ZVN0YWNrKTsKICAgICAgY29udGV4dC0+RXNwICAgPSBPRkZTRVRPRihwc3AtPnNhdmVTdGFjayk7CiAgICAgIHJldHVybjsKICAgIH0gZWxzZQogICAgICBNWl9LaWxsVGFzaygpOwogIH0KICBFeGl0VGhyZWFkKCByZXR2YWwgKTsKfQoKI2Vsc2UgLyogIU1aX1NVUFBPUlRFRCAqLwoKQk9PTCBNWl9Mb2FkSW1hZ2UoIExQQ1NUUiBjbWRsaW5lICkKewogIFdBUk4oIkRPUyBleGVjdXRhYmxlcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm1cbiIpOwogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICByZXR1cm4gRkFMU0U7Cn0KCkJPT0wgTVpfRXhlYyggQ09OVEVYVDg2ICpjb250ZXh0LCBMUENTVFIgZmlsZW5hbWUsIEJZVEUgZnVuYywgTFBWT0lEIHBhcmFtYmxrICkKewogIC8qIGNhbid0IGhhcHBlbiAqLwogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICByZXR1cm4gRkFMU0U7Cn0KCkxQRE9TVEFTSyBNWl9BbGxvY0RQTUlUYXNrKCB2b2lkICkKewogICAgRVJSKCJBY3R1YWwgcmVhbC1tb2RlIGNhbGxzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBwbGF0Zm9ybSFcbiIpOwogICAgcmV0dXJuIE5VTEw7Cn0KCnZvaWQgTVpfRXhpdCggQ09OVEVYVDg2ICpjb250ZXh0LCBCT09MIGNzX3BzcCwgV09SRCByZXR2YWwgKQp7CiAgRXhpdFRocmVhZCggcmV0dmFsICk7Cn0KCiNlbmRpZiAvKiAhTVpfU1VQUE9SVEVEICovCgpMUERPU1RBU0sgTVpfQ3VycmVudCggdm9pZCApCnsKICByZXR1cm4gZG9zX2N1cnJlbnQ7Cn0K