LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICoKICogTm90ZTogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxmY250bC5oPgojaW5jbHVkZSA8c2lnbmFsLmg+CiNpZmRlZiBIQVZFX1VOSVNURF9ICiMgaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaWZkZWYgSEFWRV9TWVNfVElNRV9ICiMgaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2VuZGlmCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc3ZtLmgiCiNpbmNsdWRlICJ2Z2EuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CgpzdGF0aWMgQk9PTCBET1NWTV9pc2Rvc2V4ZTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgIERPU1ZNX0lzV2luMTYKICogCiAqIFJldHVybiBUUlVFIGlmIHdlIGFyZSBpbiBXaW5kb3dzIHByb2Nlc3MuCiAqLwpCT09MIERPU1ZNX0lzV2luMTYodm9pZCkKewogIHJldHVybiBET1NWTV9pc2Rvc2V4ZSA/IEZBTFNFIDogVFJVRTsKfQoKI2lmZGVmIE1aX1NVUFBPUlRFRAoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKLyogZGVmaW5lIHRoaXMgdG8gdHJ5IG1hcHBpbmcgdGhyb3VnaCAvcHJvYy9waWQvbWVtIGluc3RlYWQgb2YgYSB0ZW1wIGZpbGUsCiAgIGJ1dCBMaW51cyBkb2Vzbid0IGxpa2UgbW1hcHBpbmcgL3Byb2MvcGlkL21lbSwgc28gaXQgZG9lc24ndCB3b3JrIGZvciBtZSAqLwojdW5kZWYgTVpfTUFQU0VMRgoKI2RlZmluZSBCSU9TX0RBVEFfU0VHTUVOVCAweDQwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKLyogc3RydWN0dXJlcyBmb3IgRVhFQyAqLwoKdHlwZWRlZiBzdHJ1Y3QgewogIFdPUkQgZW52X3NlZzsKICBEV09SRCBjbWRsaW5lIFdJTkVfUEFDS0VEOwogIERXT1JEIGZjYjEgV0lORV9QQUNLRUQ7CiAgRFdPUkQgZmNiMiBXSU5FX1BBQ0tFRDsKICBXT1JEIGluaXRfc3A7CiAgV09SRCBpbml0X3NzOwogIFdPUkQgaW5pdF9pcDsKICBXT1JEIGluaXRfY3M7Cn0gRXhlY0Jsb2NrOwoKdHlwZWRlZiBzdHJ1Y3QgewogIFdPUkQgbG9hZF9zZWc7CiAgV09SRCByZWxfc2VnOwp9IE92ZXJsYXlCbG9jazsKCi8qIGdsb2JhbCB2YXJpYWJsZXMgKi8KCnBpZF90IGRvc3ZtX3BpZDsKCnN0YXRpYyBXT1JEIGluaXRfY3MsaW5pdF9pcCxpbml0X3NzLGluaXRfc3A7CnN0YXRpYyBIQU5ETEUgZG9zdm1fdGhyZWFkLCBsb29wX3RocmVhZDsKc3RhdGljIERXT1JEIGRvc3ZtX3RpZCwgbG9vcF90aWQ7CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2godm9pZCk7CnN0YXRpYyBCT09MIE1aX0luaXRUYXNrKHZvaWQpOwoKc3RhdGljIHZvaWQgTVpfQ3JlYXRlUFNQKCBMUFZPSUQgbHBQU1AsIFdPUkQgZW52LCBXT1JEIHBhciApCnsKICBQREIxNipwc3A9bHBQU1A7CgogIHBzcC0+aW50MjA9MHgyMENEOyAvKiBpbnQgMjAgKi8KICAvKiBzb21lIHByb2dyYW1zIHVzZSB0aGlzIHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgdGhleSBuZWVkICovCiAgcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsgLyogRklYTUU6IHVzZSBhIHJlYWwgdmFsdWUgKi8KICAvKiBGSVhNRTogZGlzcGF0Y2hlciAqLwogIHBzcC0+c2F2ZWRpbnQyMiA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIyKTsKICBwc3AtPnNhdmVkaW50MjMgPSBET1NWTV9HZXRSTUhhbmRsZXIoMHgyMyk7CiAgcHNwLT5zYXZlZGludDI0ID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjQpOwogIHBzcC0+cGFyZW50UFNQPXBhcjsKICBwc3AtPmVudmlyb25tZW50PWVudjsKICAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKc3RhdGljIHZvaWQgTVpfRmlsbFBTUCggTFBWT0lEIGxwUFNQLCBMUEJZVEUgY21kbGluZSwgaW50IGxlbmd0aCApCnsKICBQREIxNiAgICAgICpwc3AgPSBscFBTUDsKCiAgd2hpbGUobGVuZ3RoID4gMCAmJiAqY21kbGluZSAhPSAnICcpIHsKICAgIGxlbmd0aC0tOwogICAgY21kbGluZSsrOwogIH0KCiAgLyogY29tbWFuZC5jb20gZG9lcyBub3Qgc2tpcCBvdmVyIG11bHRpcGxlIHNwYWNlcyAqLwoKICBpZihsZW5ndGggPiAxMjYpIHsKICAgIC8qCiAgICAgKiBGSVhNRTogSWYgbGVuZ3RoID4gMTI2IHdlIHNob3VsZCBwdXQgdHJ1bmNhdGVkIGNvbW1hbmQgbGluZSB0bwogICAgICogICAgICAgIFBTUCBhbmQgc3RvcmUgdGhlIGVudGlyZSBjb21tYW5kIGxpbmUgaW4gdGhlIGVudmlyb25tZW50IAogICAgICogICAgICAgIHZhcmlhYmxlIENNRExJTkUuCiAgICAgKi8KICAgIEZJWE1FKCJDb21tYW5kIGxpbmUgdHJ1bmNhdGVkISAobGVuZ3RoICVkID4gbWF4aW11bSBsZW5ndGggMTI2KVxuIiwKICAgICAgICAgIGxlbmd0aCk7CiAgICBsZW5ndGggPSAxMjY7CiAgfQoKICBwc3AtPmNtZExpbmVbMF0gPSBsZW5ndGg7CiAgaWYobGVuZ3RoID4gMCkKICAgIG1lbW1vdmUocHNwLT5jbWRMaW5lKzEsIGNtZGxpbmUsIGxlbmd0aCk7CiAgcHNwLT5jbWRMaW5lW2xlbmd0aCsxXSA9ICdccic7CgogIC8qIEZJWE1FOiBtb3JlIFBTUCBzdHVmZiAqLwp9CgovKiBkZWZhdWx0IElOVCAwOCBoYW5kbGVyOiBpbmNyZWFzZXMgdGltZXIgdGljayBjb3VudGVyIGJ1dCBub3QgbXVjaCBtb3JlICovCnN0YXRpYyBjaGFyIGludDA4W109ewogMHhDRCwweDFDLCAgICAgICAgICAgLyogaW50ICQweDFjICovCiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4MUUsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkcyAqLwogMHhCOCwweDQwLDB4MDAsICAgICAgLyogbW92dyAkMHg0MCwlYXggKi8KIDB4OEUsMHhEOCwgICAgICAgICAgIC8qIG1vdncgJWF4LCVkcyAqLwojaWYgMAogMHg4MywweDA2LDB4NkMsMHgwMCwweDAxLCAvKiBhZGR3ICQxLCgweDZjKSAqLwogMHg4MywweDE2LDB4NkUsMHgwMCwweDAwLCAvKiBhZGN3ICQwLCgweDZlKSAqLwojZWxzZQogMHg2NiwweEZGLDB4MDYsMHg2QywweDAwLCAvKiBpbmNsICgweDZjKSAqLwojZW5kaWYKIDB4QjAsMHgyMCwgICAgICAgICAgIC8qIG1vdmIgJDB4MjAsJWFsICovCiAweEU2LDB4MjAsICAgICAgICAgICAvKiBvdXRiICVhbCwkMHgyMCAqLwogMHgxRiwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENGICAgICAgICAgICAgICAgICAvKiBpcmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0SGFuZGxlcnModm9pZCkKewogV09SRCBzZWc7CiBMUEJZVEUgc3RhcnQgPSBET1NWTV9BbGxvY0NvZGVVTUIoIHNpemVvZihpbnQwOCksICZzZWcsIDAgKTsKIG1lbWNweShzdGFydCxpbnQwOCxzaXplb2YoaW50MDgpKTsKLyogSU5UIDA4OiBwb2ludCBpdCBhdCBvdXIgdGljay1pbmNyZW1lbnRpbmcgaGFuZGxlciAqLwogKChTRUdQVFIqKTApWzB4MDhdPU1BS0VTRUdQVFIoc2VnLDApOwovKiBJTlQgMUM6IGp1c3QgcG9pbnQgaXQgdG8gSVJFVCwgd2UgZG9uJ3Qgd2FudCB0byBoYW5kbGUgaXQgb3Vyc2VsdmVzICovCiAoKFNFR1BUUiopMClbMHgxQ109TUFLRVNFR1BUUihzZWcsc2l6ZW9mKGludDA4KS0xKTsKfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fR2V0QmxvY2soc3orc2l6ZW9mKFdPUkQpK3N0cmxlbihuYW1lKSsxLCZzZWcpOwogLyogZmlsbCBpdCAqLwogaWYgKGVudikgewogIG1lbWNweShlbnZibGssZW52LHN6KTsKIH0gZWxzZSBlbnZibGtbMF09MDsKIC8qIERPUyAzLng6IHRoZSBibG9jayBjb250YWlucyAxIGFkZGl0aW9uYWwgc3RyaW5nICovCiAqKFdPUkQqKShlbnZibGsrc3opPTE7CiAvKiBiZWluZyB0aGUgcHJvZ3JhbSBuYW1lIGl0c2VsZiAqLwogc3RyY3B5KGVudmJsaytzeitzaXplb2YoV09SRCksbmFtZSk7CiByZXR1cm4gc2VnOwp9CgpzdGF0aWMgQk9PTCBNWl9Jbml0TWVtb3J5KHZvaWQpCnsKICAgIC8qIGluaXRpYWxpemUgdGhlIG1lbW9yeSAqLwogICAgVFJBQ0UoIkluaXRpYWxpemluZyBET1MgbWVtb3J5IHN0cnVjdHVyZXNcbiIpOwogICAgRE9TTUVNX0luaXQoVFJVRSk7CiAgICBET1NERVZfSW5zdGFsbERPU0RldmljZXMoKTsKCiAgICBNWl9Jbml0SGFuZGxlcnMoKTsKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBNWl9Eb0xvYWRJbWFnZSggSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUsIE92ZXJsYXlCbG9jayAqb2JsayApCnsKICBJTUFHRV9ET1NfSEVBREVSIG16X2hlYWRlcjsKICBEV09SRCBpbWFnZV9zdGFydCxpbWFnZV9zaXplLG1pbl9zaXplLG1heF9zaXplLGF2YWlsOwogIEJZVEUqcHNwX3N0YXJ0LCpsb2FkX3N0YXJ0LCpvbGRlbnY7CiAgaW50IHgsIG9sZF9jb209MCwgYWxsb2M7CiAgU0VHUFRSIHJlbG9jOwogIFdPUkQgZW52X3NlZywgbG9hZF9zZWcsIHJlbF9zZWcsIG9sZHBzcF9zZWc7CiAgRFdPUkQgbGVuOwoKICBpZiAoRE9TVk1fcHNwKSB7CiAgICAvKiBET1MgcHJvY2VzcyBhbHJlYWR5IHJ1bm5pbmcsIGluaGVyaXQgZnJvbSBpdCAqLwogICAgUERCMTYqIHBhcl9wc3AgPSAoUERCMTYqKSgoRFdPUkQpRE9TVk1fcHNwIDw8IDQpOwogICAgYWxsb2M9MDsKICAgIG9sZGVudiA9IChMUEJZVEUpKChEV09SRClwYXJfcHNwLT5lbnZpcm9ubWVudCA8PCA0KTsKICAgIG9sZHBzcF9zZWcgPSBET1NWTV9wc3A7CiAgfSBlbHNlIHsKICAgIC8qIGFsbG9jYXRlIG5ldyBET1MgcHJvY2VzcywgaW5oZXJpdGluZyBmcm9tIFdpbmUgZW52aXJvbm1lbnQgKi8KICAgIGFsbG9jPTE7CiAgICBvbGRlbnYgPSBHZXRFbnZpcm9ubWVudFN0cmluZ3NBKCk7CiAgICBvbGRwc3Bfc2VnID0gMDsKICB9CgogU2V0RmlsZVBvaW50ZXIoaEZpbGUsMCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCAgICFSZWFkRmlsZShoRmlsZSwmbXpfaGVhZGVyLHNpemVvZihtel9oZWFkZXIpLCZsZW4sTlVMTCkKICAgICB8fCBsZW4gIT0gc2l6ZW9mKG16X2hlYWRlcikKICAgICB8fCBtel9oZWFkZXIuZV9tYWdpYyAhPSBJTUFHRV9ET1NfU0lHTkFUVVJFKSB7CiAgY2hhciAqcCA9IHN0cnJjaHIoIGZpbGVuYW1lLCAnLicgKTsKICBpZiAoIXAgfHwgc3RyY2FzZWNtcCggcCwgIi5jb20iICkpICAvKiBjaGVjayBmb3IgLkNPTSBleHRlbnNpb24gKi8KICB7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogIH0KICBvbGRfY29tPTE7IC8qIGFzc3VtZSAuQ09NIGZpbGUgKi8KICBpbWFnZV9zdGFydD0wOwogIGltYWdlX3NpemU9R2V0RmlsZVNpemUoaEZpbGUsTlVMTCk7CiAgbWluX3NpemU9MHgxMDAwMDsgbWF4X3NpemU9MHgxMDAwMDA7CiAgbXpfaGVhZGVyLmVfY3JsYz0wOwogIG16X2hlYWRlci5lX3NzPTA7IG16X2hlYWRlci5lX3NwPTB4RkZGRTsKICBtel9oZWFkZXIuZV9jcz0wOyBtel9oZWFkZXIuZV9pcD0weDEwMDsKIH0gZWxzZSB7CiAgLyogY2FsY3VsYXRlIGxvYWQgc2l6ZSAqLwogIGltYWdlX3N0YXJ0PW16X2hlYWRlci5lX2NwYXJoZHI8PDQ7CiAgaW1hZ2Vfc2l6ZT1tel9oZWFkZXIuZV9jcDw8OTsgLyogcGFnZXMgYXJlIDUxMiBieXRlcyAqLwogIGlmICgobXpfaGVhZGVyLmVfY2JscCE9MCkmJihtel9oZWFkZXIuZV9jYmxwIT00KSkgaW1hZ2Vfc2l6ZS09NTEyLW16X2hlYWRlci5lX2NibHA7CiAgaW1hZ2Vfc2l6ZS09aW1hZ2Vfc3RhcnQ7CiAgbWluX3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21pbmFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogIG1heF9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9tYXhhbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKIH0KCiAgaWYgKGFsbG9jKSBNWl9Jbml0TWVtb3J5KCk7CgogIGlmIChvYmxrKSB7CiAgICAvKiBsb2FkIG92ZXJsYXkgaW50byBwcmVhbGxvY2F0ZWQgbWVtb3J5ICovCiAgICBsb2FkX3NlZz1vYmxrLT5sb2FkX3NlZzsKICAgIHJlbF9zZWc9b2Jsay0+cmVsX3NlZzsKICAgIGxvYWRfc3RhcnQ9KExQQllURSkoKERXT1JEKWxvYWRfc2VnPDw0KTsKICB9IGVsc2UgewogICAgLyogYWxsb2NhdGUgZW52aXJvbm1lbnQgYmxvY2sgKi8KICAgIGVudl9zZWc9TVpfSW5pdEVudmlyb25tZW50KG9sZGVudiwgZmlsZW5hbWUpOwoKICAgIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGV4ZWN1dGFibGUgKi8KICAgIFRSQUNFKCJBbGxvY2F0aW5nIERPUyBtZW1vcnkgKG1pbj0lbGQsIG1heD0lbGQpXG4iLG1pbl9zaXplLG1heF9zaXplKTsKICAgIGF2YWlsPURPU01FTV9BdmFpbGFibGUoKTsKICAgIGlmIChhdmFpbDxtaW5fc2l6ZSkgewogICAgICBFUlIoImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogICAgfQogICAgaWYgKGF2YWlsPm1heF9zaXplKSBhdmFpbD1tYXhfc2l6ZTsKICAgIHBzcF9zdGFydD1ET1NNRU1fR2V0QmxvY2soYXZhaWwsJkRPU1ZNX3BzcCk7CiAgICBpZiAoIXBzcF9zdGFydCkgewogICAgICBFUlIoImVycm9yIGFsbG9jYXRpbmcgRE9TIG1lbW9yeVxuIik7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgIH0KICAgIGxvYWRfc2VnPURPU1ZNX3BzcCsob2xkX2NvbT8wOlBTUF9TSVpFKTsKICAgIHJlbF9zZWc9bG9hZF9zZWc7CiAgICBsb2FkX3N0YXJ0PXBzcF9zdGFydCsoUFNQX1NJWkU8PDQpOwogICAgTVpfQ3JlYXRlUFNQKHBzcF9zdGFydCwgZW52X3NlZywgb2xkcHNwX3NlZyk7CiAgfQoKIC8qIGxvYWQgZXhlY3V0YWJsZSBpbWFnZSAqLwogVFJBQ0UoImxvYWRpbmcgRE9TICVzIGltYWdlLCAlMDhseCBieXRlc1xuIixvbGRfY29tPyJDT00iOiJFWEUiLGltYWdlX3NpemUpOwogU2V0RmlsZVBvaW50ZXIoaEZpbGUsaW1hZ2Vfc3RhcnQsTlVMTCxGSUxFX0JFR0lOKTsKIGlmICghUmVhZEZpbGUoaEZpbGUsbG9hZF9zdGFydCxpbWFnZV9zaXplLCZsZW4sTlVMTCkgfHwgbGVuICE9IGltYWdlX3NpemUpIHsKICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgZ290byBsb2FkX2Vycm9yOwogfQoKIGlmIChtel9oZWFkZXIuZV9jcmxjKSB7CiAgLyogbG9hZCByZWxvY2F0aW9uIHRhYmxlICovCiAgVFJBQ0UoImxvYWRpbmcgRE9TIEVYRSByZWxvY2F0aW9uIHRhYmxlLCAlZCBlbnRyaWVzXG4iLG16X2hlYWRlci5lX2NybGMpOwogIC8qIEZJWE1FOiBpcyB0aGlzIHRvbyBzbG93IHdpdGhvdXQgcmVhZCBidWZmZXJpbmc/ICovCiAgU2V0RmlsZVBvaW50ZXIoaEZpbGUsbXpfaGVhZGVyLmVfbGZhcmxjLE5VTEwsRklMRV9CRUdJTik7CiAgZm9yICh4PTA7IHg8bXpfaGVhZGVyLmVfY3JsYzsgeCsrKSB7CiAgIGlmICghUmVhZEZpbGUoaEZpbGUsJnJlbG9jLHNpemVvZihyZWxvYyksJmxlbixOVUxMKSB8fCBsZW4gIT0gc2l6ZW9mKHJlbG9jKSkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgZ290byBsb2FkX2Vycm9yOwogICB9CiAgICooV09SRCopU0VHUFRSMTYobG9hZF9zdGFydCxyZWxvYykrPXJlbF9zZWc7CiAgfQogfQoKICBpZiAoIW9ibGspIHsKICAgIGluaXRfY3MgPSBsb2FkX3NlZyttel9oZWFkZXIuZV9jczsKICAgIGluaXRfaXAgPSBtel9oZWFkZXIuZV9pcDsKICAgIGluaXRfc3MgPSBsb2FkX3NlZyttel9oZWFkZXIuZV9zczsKICAgIGluaXRfc3AgPSBtel9oZWFkZXIuZV9zcDsKCiAgICBUUkFDRSgiZW50cnkgcG9pbnQ6ICUwNHg6JTA0eFxuIixpbml0X2NzLGluaXRfaXApOwogIH0KCiAgaWYgKGFsbG9jICYmICFNWl9Jbml0VGFzaygpKSB7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfR0VOX0ZBSUxVUkUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgcmV0dXJuIFRSVUU7Cgpsb2FkX2Vycm9yOgogIERPU1ZNX3BzcCA9IG9sZHBzcF9zZWc7CgogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlMb2FkRG9zRXhlIChXSU5FRE9TLkApCiAqCiAqIENhbGxlZCBmcm9tIFdpbmUgbG9hZGVyIHdoZW4gYSBuZXcgcmVhbC1tb2RlIERPUyBwcm9jZXNzIGlzIHN0YXJ0ZWQuCiAqIExvYWRzIERPUyBwcm9ncmFtIGludG8gbWVtb3J5IGFuZCBleGVjdXRlcyB0aGUgcHJvZ3JhbS4KICovCnZvaWQgV0lOQVBJIE1aX0xvYWRJbWFnZSggTFBDU1RSIGZpbGVuYW1lLCBIQU5ETEUgaEZpbGUgKQp7CiAgRE9TVk1faXNkb3NleGUgPSBUUlVFOwogIGlmIChNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBOVUxMICkpIE1aX0xhdW5jaCgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0V4ZWMKICoKICogdGhpcyBtYXkgb25seSBiZSBjYWxsZWQgZnJvbSBleGlzdGluZyBET1MgcHJvY2Vzc2VzCiAqLwpCT09MIFdJTkFQSSBNWl9FeGVjKCBDT05URVhUODYgKmNvbnRleHQsIExQQ1NUUiBmaWxlbmFtZSwgQllURSBmdW5jLCBMUFZPSUQgcGFyYW1ibGsgKQp7CiAgRFdPUkQgYmluVHlwZTsKICBTVEFSVFVQSU5GT0Egc3Q7CiAgUFJPQ0VTU19JTkZPUk1BVElPTiBwZTsKICBIQU5ETEUgaEZpbGU7CgogIEJPT0wgcmV0ID0gRkFMU0U7CgogIGlmKCFHZXRCaW5hcnlUeXBlQShmaWxlbmFtZSwgJmJpblR5cGUpKSAgIC8qIGRldGVybWluZSB3aGF0IGtpbmQgb2YgYmluYXJ5IHRoaXMgaXMgKi8KICB7CiAgICByZXR1cm4gRkFMU0U7IC8qIGJpbmFyeSBpcyBub3QgYW4gZXhlY3V0YWJsZSAqLwogIH0KCiAgLyogaGFuZGxlIG5vbi1kb3MgZXhlY3V0YWJsZXMgKi8KICBpZihiaW5UeXBlICE9IFNDU19ET1NfQklOQVJZKQogIHsKICAgIGlmKGZ1bmMgPT0gMCkgLyogbG9hZCBhbmQgZXhlY3V0ZSAqLwogICAgewogICAgICBMUEJZVEUgZnVsbENtZExpbmU7CiAgICAgIFdPUkQgZnVsbENtZExlbmd0aDsKICAgICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICAgIFBEQjE2ICpwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICAgIEV4ZWNCbG9jayAqYmxrID0gKEV4ZWNCbG9jayAqKXBhcmFtYmxrOwogICAgICBMUEJZVEUgY21kbGluZSA9IFBUUl9SRUFMX1RPX0xJTihTRUxFQ1RPUk9GKGJsay0+Y21kbGluZSksT0ZGU0VUT0YoYmxrLT5jbWRsaW5lKSk7CiAgICAgIExQQllURSBlbnZibG9jayA9IFBUUl9SRUFMX1RPX0xJTihwc3AtPmVudmlyb25tZW50LCAwKTsKICAgICAgQllURSBjbWRMZW5ndGggPSBjbWRsaW5lWzBdOwoKICAgICAgLyoKICAgICAgICogRklYTUU6IElmIGNtZExlbmd0aCA9PSAxMjYsIFBTUCBtYXkgY29udGFpbiB0cnVuY2F0ZWQgdmVyc2lvbgogICAgICAgKiAgICAgICAgb2YgdGhlIGZ1bGwgY29tbWFuZCBsaW5lLiBJbiB0aGlzIGNhc2UgZW52aXJvbm1lbnQKICAgICAgICogICAgICAgIHZhcmlhYmxlIENNRExJTkUgY29udGFpbnMgdGhlIGVudGlyZSBjb21tYW5kIGxpbmUuCiAgICAgICAqLwoKICAgICAgZnVsbENtZExlbmd0aCA9IChzdHJsZW4oZmlsZW5hbWUpICsgMSkgKyBjbWRMZW5ndGggKyAxOyAvKiBmaWxlbmFtZSArIHNwYWNlICsgY21kbGluZSArIHRlcm1pbmF0aW5nIG51bGwgY2hhcmFjdGVyICovCgogICAgICBmdWxsQ21kTGluZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBmdWxsQ21kTGVuZ3RoKTsKICAgICAgaWYoIWZ1bGxDbWRMaW5lKSByZXR1cm4gRkFMU0U7IC8qIHJldHVybiBmYWxzZSBvbiBtZW1vcnkgYWxsb2MgZmFpbHVyZSAqLwoKICAgICAgLyogYnVpbGQgdGhlIGZ1bGwgY29tbWFuZCBsaW5lIGZyb20gdGhlIGV4ZWN1dGFibGUgZmlsZSBhbmQgdGhlIGNvbW1hbmQgbGluZSBiZWluZyBwYXNzZWQgaW4gKi8KICAgICAgc25wcmludGYoZnVsbENtZExpbmUsIGZ1bGxDbWRMZW5ndGgsICIlcyAiLCBmaWxlbmFtZSk7IC8qIHN0YXJ0IG9mZiB3aXRoIHRoZSBleGVjdXRhYmxlIGZpbGVuYW1lIGFuZCBhIHNwYWNlICovCiAgICAgIG1lbWNweShmdWxsQ21kTGluZSArIHN0cmxlbihmdWxsQ21kTGluZSksIGNtZGxpbmUgKyAxLCBjbWRMZW5ndGgpOyAvKiBhcHBlbmQgY21kbGluZSBvbnRvIHRoZSBlbmQgKi8KICAgICAgZnVsbENtZExpbmVbZnVsbENtZExlbmd0aCAtIDFdID0gMDsgLyogbnVsbCB0ZXJtaW5hdGUgc3RyaW5nICovCgogICAgICBaZXJvTWVtb3J5ICgmc3QsIHNpemVvZihTVEFSVFVQSU5GT0EpKTsKICAgICAgc3QuY2IgPSBzaXplb2YoU1RBUlRVUElORk9BKTsKICAgICAgcmV0ID0gQ3JlYXRlUHJvY2Vzc0EgKE5VTEwsIGZ1bGxDbWRMaW5lLCBOVUxMLCBOVUxMLCBUUlVFLCAwLCBlbnZibG9jaywgTlVMTCwgJnN0LCAmcGUpOwoKICAgICAgLyogd2FpdCBmb3IgdGhlIGFwcCB0byBmaW5pc2ggYW5kIGNsZWFuIHVwIFBST0NFU1NfSU5GT1JNQVRJT04gaGFuZGxlcyAqLwogICAgICBpZihyZXQpCiAgICAgIHsKICAgICAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KHBlLmhQcm9jZXNzLCBJTkZJTklURSk7ICAvKiB3YWl0IGhlcmUgdW50aWwgdGhlIGNoaWxkIHByb2Nlc3MgaXMgY29tcGxldGUgKi8KICAgICAgICBDbG9zZUhhbmRsZShwZS5oUHJvY2Vzcyk7CiAgICAgICAgQ2xvc2VIYW5kbGUocGUuaFRocmVhZCk7CiAgICAgIH0KCiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGZ1bGxDbWRMaW5lKTsgIC8qIGZyZWUgdGhlIG1lbW9yeSB3ZSBhbGxvY2F0ZWQgKi8KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgRklYTUUoIkVYRUMgdHlwZSBvZiAlZCBub3QgaW1wbGVtZW50ZWQgZm9yIG5vbi1kb3MgZXhlY3V0YWJsZXNcbiIsIGZ1bmMpOwogICAgICByZXQgPSBGQUxTRTsKICAgIH0KCiAgICByZXR1cm4gcmV0OwogIH0gLyogaWYoYmluVHlwZSAhPSBTQ1NfRE9TX0JJTkFSWSkgKi8KCgogIC8qIGhhbmRsZSBkb3MgZXhlY3V0YWJsZXMgKi8KCiAgaEZpbGUgPSBDcmVhdGVGaWxlQSggZmlsZW5hbWUsIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELAoJCQkgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIDApOwogIGlmIChoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgcmV0dXJuIEZBTFNFOwoKICBzd2l0Y2ggKGZ1bmMpIHsKICBjYXNlIDA6IC8qIGxvYWQgYW5kIGV4ZWN1dGUgKi8KICBjYXNlIDE6IC8qIGxvYWQgYnV0IGRvbid0IGV4ZWN1dGUgKi8KICAgIHsKICAgICAgLyogc2F2ZSBjdXJyZW50IHByb2Nlc3MncyByZXR1cm4gU1M6U1Agbm93ICovCiAgICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpRE9TVk1fcHNwIDw8IDQpOwogICAgICBQREIxNiAqcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgICBwc3AtPnNhdmVTdGFjayA9IChEV09SRClNQUtFU0VHUFRSKGNvbnRleHQtPlNlZ1NzLCBMT1dPUkQoY29udGV4dC0+RXNwKSk7CiAgICB9CiAgICByZXQgPSBNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBOVUxMICk7CiAgICBpZiAocmV0KSB7CiAgICAgIC8qIE1aX0xvYWRJbWFnZSBjcmVhdGVkIGEgbmV3IFBTUCBhbmQgbG9hZGVkIG5ldyB2YWx1ZXMgaW50byBpdCwKICAgICAgICogbGV0J3Mgd29yayBvbiB0aGUgbmV3IHZhbHVlcyBub3cgKi8KICAgICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICAgIEV4ZWNCbG9jayAqYmxrID0gKEV4ZWNCbG9jayAqKXBhcmFtYmxrOwogICAgICBMUEJZVEUgY21kbGluZSA9IFBUUl9SRUFMX1RPX0xJTihTRUxFQ1RPUk9GKGJsay0+Y21kbGluZSksT0ZGU0VUT0YoYmxrLT5jbWRsaW5lKSk7CgogICAgICAvKiBGaXJzdCBjaGFyYWN0ZXIgY29udGFpbnMgdGhlIGxlbmd0aCBvZiB0aGUgY29tbWFuZCBsaW5lLiAqLwogICAgICBNWl9GaWxsUFNQKHBzcF9zdGFydCwgY21kbGluZSArIDEsIGNtZGxpbmVbMF0pOwoKICAgICAgLyogdGhlIGxhbWUgTVMtRE9TIGVuZ2luZWVycyBkZWNpZGVkIHRoYXQgdGhlIHJldHVybiBhZGRyZXNzIHNob3VsZCBiZSBpbiBpbnQyMiAqLwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyMiwgKEZBUlBST0MxNilNQUtFU0VHUFRSKGNvbnRleHQtPlNlZ0NzLCBMT1dPUkQoY29udGV4dC0+RWlwKSkpOwogICAgICBpZiAoZnVuYykgewoJLyogZG9uJ3QgZXhlY3V0ZSwganVzdCByZXR1cm4gc3RhcnR1cCBzdGF0ZSAqLwoJYmxrLT5pbml0X2NzID0gaW5pdF9jczsKCWJsay0+aW5pdF9pcCA9IGluaXRfaXA7CglibGstPmluaXRfc3MgPSBpbml0X3NzOwoJYmxrLT5pbml0X3NwID0gaW5pdF9zcDsKICAgICAgfSBlbHNlIHsKCS8qIGV4ZWN1dGUgYnkgbWFraW5nIHVzIHJldHVybiB0byBuZXcgcHJvY2VzcyAqLwoJY29udGV4dC0+U2VnQ3MgPSBpbml0X2NzOwoJY29udGV4dC0+RWlwICAgPSBpbml0X2lwOwoJY29udGV4dC0+U2VnU3MgPSBpbml0X3NzOwoJY29udGV4dC0+RXNwICAgPSBpbml0X3NwOwoJY29udGV4dC0+U2VnRHMgPSBET1NWTV9wc3A7Cgljb250ZXh0LT5TZWdFcyA9IERPU1ZNX3BzcDsKCWNvbnRleHQtPkVheCAgID0gMDsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSAzOiAvKiBsb2FkIG92ZXJsYXkgKi8KICAgIHsKICAgICAgT3ZlcmxheUJsb2NrICpibGsgPSAoT3ZlcmxheUJsb2NrICopcGFyYW1ibGs7CiAgICAgIHJldCA9IE1aX0RvTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIGJsayApOwogICAgfQogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIEZJWE1FKCJFWEVDIGxvYWQgdHlwZSAlZCBub3QgaW1wbGVtZW50ZWRcbiIsIGZ1bmMpOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRlVOQ1RJT04pOwogICAgYnJlYWs7CiAgfQogIENsb3NlSGFuZGxlKGhGaWxlKTsKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0FsbG9jRFBNSVRhc2sKICovCnZvaWQgV0lOQVBJIE1aX0FsbG9jRFBNSVRhc2soIHZvaWQgKQp7CiAgTVpfSW5pdE1lbW9yeSgpOwogIE1aX0luaXRUYXNrKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfUnVuSW5UaHJlYWQKICovCnZvaWQgV0lOQVBJIE1aX1J1bkluVGhyZWFkKCBQQVBDRlVOQyBwcm9jLCBVTE9OR19QVFIgYXJnICkKewogIGlmIChsb29wX3RocmVhZCkgewogICAgRE9TX1NQQyBzcGM7CiAgICBIQU5ETEUgZXZlbnQ7CgogICAgc3BjLnByb2MgPSBwcm9jOwogICAgc3BjLmFyZyA9IGFyZzsKICAgIGV2ZW50ID0gQ3JlYXRlRXZlbnRBKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKICAgIFBvc3RUaHJlYWRNZXNzYWdlQShsb29wX3RpZCwgV01fVVNFUiwgKFdQQVJBTSlldmVudCwgKExQQVJBTSkmc3BjKTsKICAgIFdhaXRGb3JTaW5nbGVPYmplY3QoZXZlbnQsIElORklOSVRFKTsKICAgIENsb3NlSGFuZGxlKGV2ZW50KTsKICB9IGVsc2UKICAgIHByb2MoYXJnKTsKfQoKc3RhdGljIERXT1JEIFdJTkFQSSBNWl9ET1NWTSggTFBWT0lEIGxwRXh0cmEgKQp7CiAgQ09OVEVYVCBjb250ZXh0OwogIERXT1JEIHJldDsKCiAgZG9zdm1fcGlkID0gZ2V0cGlkKCk7CgogIG1lbXNldCggJmNvbnRleHQsIDAsIHNpemVvZihjb250ZXh0KSApOwogIGNvbnRleHQuU2VnQ3MgID0gaW5pdF9jczsKICBjb250ZXh0LkVpcCAgICA9IGluaXRfaXA7CiAgY29udGV4dC5TZWdTcyAgPSBpbml0X3NzOwogIGNvbnRleHQuRXNwICAgID0gaW5pdF9zcDsKICBjb250ZXh0LlNlZ0RzICA9IERPU1ZNX3BzcDsKICBjb250ZXh0LlNlZ0VzICA9IERPU1ZNX3BzcDsKICBjb250ZXh0LkVGbGFncyA9IDB4MDAwODAwMDA7ICAvKiB2aXJ0dWFsIGludGVycnVwdCBmbGFnICovCiAgRE9TVk1fU2V0VGltZXIoMHgxMDAwMCk7CiAgcmV0ID0gRE9TVk1fRW50ZXIoICZjb250ZXh0ICk7CgogIGRvc3ZtX3BpZCA9IDA7CiAgcmV0dXJuIHJldDsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdFRhc2sodm9pZCkKewogIGlmICghRHVwbGljYXRlSGFuZGxlKEdldEN1cnJlbnRQcm9jZXNzKCksIEdldEN1cnJlbnRUaHJlYWQoKSwKICAgICAgICAgICAgICAgICAgICAgICBHZXRDdXJyZW50UHJvY2VzcygpLCAmbG9vcF90aHJlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgMCwgRkFMU0UsIERVUExJQ0FURV9TQU1FX0FDQ0VTUykpCiAgICByZXR1cm4gRkFMU0U7CiAgZG9zdm1fdGhyZWFkID0gQ3JlYXRlVGhyZWFkKE5VTEwsIDAsIE1aX0RPU1ZNLCBOVUxMLCBDUkVBVEVfU1VTUEVOREVELCAmZG9zdm1fdGlkKTsKICBpZiAoIWRvc3ZtX3RocmVhZCkgewogICAgQ2xvc2VIYW5kbGUobG9vcF90aHJlYWQpOwogICAgbG9vcF90aHJlYWQgPSAwOwogICAgcmV0dXJuIEZBTFNFOwogIH0KICBsb29wX3RpZCA9IEdldEN1cnJlbnRUaHJlYWRJZCgpOwogIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2godm9pZCkKewogIFREQiAqcFRhc2sgPSBHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKICBCWVRFICpwc3Bfc3RhcnQgPSBQVFJfUkVBTF9UT19MSU4oIERPU1ZNX3BzcCwgMCApOwogIExQU1RSIGNtZGxpbmUgPSBHZXRDb21tYW5kTGluZUEoKTsKICBEV09SRCBydjsKICBTWVNMRVZFTCAqbG9jazsKCiAgTVpfRmlsbFBTUChwc3Bfc3RhcnQsIGNtZGxpbmUsIGNtZGxpbmUgPyBzdHJsZW4oY21kbGluZSkgOiAwKTsKICBwVGFzay0+ZmxhZ3MgfD0gVERCRl9XSU5PTERBUDsKCiAgLyogRFRBIGlzIHNldCB0byBQU1A6MDA4MGggd2hlbiBhIHByb2dyYW0gaXMgc3RhcnRlZC4gKi8KICBwVGFzay0+ZHRhID0gTUFLRVNFR1BUUiggRE9TVk1fcHNwLCAweDgwICk7CgogIEdldHBXaW4xNkxvY2soICZsb2NrICk7CiAgX0xlYXZlU3lzTGV2ZWwoIGxvY2sgKTsKCiAgUmVzdW1lVGhyZWFkKGRvc3ZtX3RocmVhZCk7CiAgcnYgPSBET1NWTV9Mb29wKGRvc3ZtX3RocmVhZCk7CgogIENsb3NlSGFuZGxlKGRvc3ZtX3RocmVhZCk7CiAgZG9zdm1fdGhyZWFkID0gMDsgZG9zdm1fdGlkID0gMDsKICBDbG9zZUhhbmRsZShsb29wX3RocmVhZCk7CiAgbG9vcF90aHJlYWQgPSAwOyBsb29wX3RpZCA9IDA7CgogIFZHQV9DbGVhbigpOwogIEV4aXRUaHJlYWQocnYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0V4aXQKICovCnZvaWQgV0lOQVBJIE1aX0V4aXQoIENPTlRFWFQ4NiAqY29udGV4dCwgQk9PTCBjc19wc3AsIFdPUkQgcmV0dmFsICkKewogIGlmIChET1NWTV9wc3ApIHsKICAgIFdPUkQgcHNwX3NlZyA9IGNzX3BzcCA/IGNvbnRleHQtPlNlZ0NzIDogRE9TVk1fcHNwOwogICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClwc3Bfc2VnIDw8IDQpOwogICAgUERCMTYgKnBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgIFdPUkQgcGFycHNwID0gcHNwLT5wYXJlbnRQU1A7IC8qIGNoZWNrIGZvciBwYXJlbnQgRE9TIHByb2Nlc3MgKi8KICAgIGlmIChwYXJwc3ApIHsKICAgICAgLyogcmV0cmlldmUgcGFyZW50J3MgcmV0dXJuIGFkZHJlc3MgKi8KICAgICAgRkFSUFJPQzE2IHJldGFkZHIgPSBET1NWTV9HZXRSTUhhbmRsZXIoMHgyMik7CiAgICAgIC8qIHJlc3RvcmUgaW50ZXJydXB0cyAqLwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyMiwgcHNwLT5zYXZlZGludDIyKTsKICAgICAgRE9TVk1fU2V0Uk1IYW5kbGVyKDB4MjMsIHBzcC0+c2F2ZWRpbnQyMyk7CiAgICAgIERPU1ZNX1NldFJNSGFuZGxlcigweDI0LCBwc3AtPnNhdmVkaW50MjQpOwogICAgICAvKiBGSVhNRTogZGVhbGxvY2F0ZSBmaWxlIGhhbmRsZXMgZXRjICovCiAgICAgIC8qIGZyZWUgcHJvY2VzcydzIGFzc29jaWF0ZWQgbWVtb3J5CiAgICAgICAqIEZJWE1FOiB3YWxrIG1lbW9yeSBhbmQgZGVhbGxvY2F0ZSBhbGwgYmxvY2tzIG93bmVkIGJ5IHByb2Nlc3MgKi8KICAgICAgRE9TTUVNX0ZyZWVCbG9jayggUFRSX1JFQUxfVE9fTElOKHBzcC0+ZW52aXJvbm1lbnQsMCkgKTsKICAgICAgRE9TTUVNX0ZyZWVCbG9jayggUFRSX1JFQUxfVE9fTElOKERPU1ZNX3BzcCwwKSApOwogICAgICAvKiBzd2l0Y2ggdG8gcGFyZW50J3MgUFNQICovCiAgICAgIERPU1ZNX3BzcCA9IHBhcnBzcDsKICAgICAgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKXBhcnBzcCA8PCA0KTsKICAgICAgcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgICAvKiBub3cgcmV0dXJuIHRvIHBhcmVudCAqLwogICAgICBET1NWTV9yZXR2YWwgPSByZXR2YWw7CiAgICAgIGNvbnRleHQtPlNlZ0NzID0gU0VMRUNUT1JPRihyZXRhZGRyKTsKICAgICAgY29udGV4dC0+RWlwICAgPSBPRkZTRVRPRihyZXRhZGRyKTsKICAgICAgY29udGV4dC0+U2VnU3MgPSBTRUxFQ1RPUk9GKHBzcC0+c2F2ZVN0YWNrKTsKICAgICAgY29udGV4dC0+RXNwICAgPSBPRkZTRVRPRihwc3AtPnNhdmVTdGFjayk7CiAgICAgIHJldHVybjsKICAgIH0gZWxzZQogICAgICBUUkFDRSgia2lsbGluZyBET1MgdGFza1xuIik7CiAgfQogIEV4aXRUaHJlYWQoIHJldHZhbCApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9DdXJyZW50CiAqLwpCT09MIFdJTkFQSSBNWl9DdXJyZW50KCB2b2lkICkKewogIHJldHVybiAoZG9zdm1fcGlkICE9IDApOyAvKiBGSVhNRTogZG8gYSBiZXR0ZXIgY2hlY2sgKi8KfQoKI2Vsc2UgLyogIU1aX1NVUFBPUlRFRCAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlMb2FkRG9zRXhlIChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBNWl9Mb2FkSW1hZ2UoIExQQ1NUUiBmaWxlbmFtZSwgSEFORExFIGhGaWxlICkKewogIFdBUk4oIkRPUyBleGVjdXRhYmxlcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm1cbiIpOwogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGVjCiAqLwpCT09MIFdJTkFQSSBNWl9FeGVjKCBDT05URVhUODYgKmNvbnRleHQsIExQQ1NUUiBmaWxlbmFtZSwgQllURSBmdW5jLCBMUFZPSUQgcGFyYW1ibGsgKQp7CiAgLyogY2FuJ3QgaGFwcGVuICovCiAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9BbGxvY0RQTUlUYXNrCiAqLwp2b2lkIFdJTkFQSSBNWl9BbGxvY0RQTUlUYXNrKCB2b2lkICkKewogICAgRVJSKCJBY3R1YWwgcmVhbC1tb2RlIGNhbGxzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBwbGF0Zm9ybSFcbiIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX1J1bkluVGhyZWFkCiAqLwp2b2lkIFdJTkFQSSBNWl9SdW5JblRocmVhZCggUEFQQ0ZVTkMgcHJvYywgVUxPTkdfUFRSIGFyZyApCnsKICAgIHByb2MoYXJnKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGl0CiAqLwp2b2lkIFdJTkFQSSBNWl9FeGl0KCBDT05URVhUODYgKmNvbnRleHQsIEJPT0wgY3NfcHNwLCBXT1JEIHJldHZhbCApCnsKICBFeGl0VGhyZWFkKCByZXR2YWwgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9DdXJyZW50CiAqLwpCT09MIFdJTkFQSSBNWl9DdXJyZW50KCB2b2lkICkKewogICAgcmV0dXJuIEZBTFNFOwp9CgojZW5kaWYgLyogIU1aX1NVUFBPUlRFRCAqLwo=