LyogRmlsZTogYnV0dG9uLmMgLS0gQnV0dG9uIHR5cGUgd2lkZ2V0cwogKgogKiBDb3B5cmlnaHQgKEMpIDE5OTMgSm9oYW5uZXMgUnVzY2hlaW5za2kKICogQ29weXJpZ2h0IChDKSAxOTkzIERhdmlkIE1ldGNhbGZlCiAqIENvcHlyaWdodCAoQykgMTk5NCBBbGV4YW5kcmUgSnVsbGlhcmQKICovCgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJ3aW4uaCIKI2luY2x1ZGUgImJ1dHRvbi5oIgojaW5jbHVkZSAid2luZS93aW51c2VyMTYuaCIKI2luY2x1ZGUgInR3ZWFrLmgiCgpzdGF0aWMgdm9pZCBQYWludEdyYXlPbkdyYXkoIEhEQyBoREMsSEZPTlQgaEZvbnQsUkVDVCAqcmMsCgkJCSAgICAgY2hhciAqdGV4dCwgVUlOVCBmb3JtYXQgKTsKCnN0YXRpYyB2b2lkIFBCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKTsKc3RhdGljIHZvaWQgQ0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApOwpzdGF0aWMgdm9pZCBHQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICk7CnN0YXRpYyB2b2lkIFVCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKTsKc3RhdGljIHZvaWQgT0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApOwpzdGF0aWMgdm9pZCBCVVRUT05fQ2hlY2tBdXRvUmFkaW9CdXR0b24oIFdORCAqd25kUHRyICk7CnN0YXRpYyB2b2lkIEJVVFRPTl9EcmF3UHVzaEJ1dHRvbiggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uLCBCT09MIHB1c2hlZFN0YXRlKTsKCiNkZWZpbmUgTUFYX0JUTl9UWVBFICAxMgoKc3RhdGljIGNvbnN0IFdPUkQgbWF4Q2hlY2tTdGF0ZVtNQVhfQlROX1RZUEVdID0KewogICAgQlVUVE9OX1VOQ0hFQ0tFRCwgICAvKiBCU19QVVNIQlVUVE9OICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIEJTX0RFRlBVU0hCVVRUT04gKi8KICAgIEJVVFRPTl9DSEVDS0VELCAgICAgLyogQlNfQ0hFQ0tCT1ggKi8KICAgIEJVVFRPTl9DSEVDS0VELCAgICAgLyogQlNfQVVUT0NIRUNLQk9YICovCiAgICBCVVRUT05fQ0hFQ0tFRCwgICAgIC8qIEJTX1JBRElPQlVUVE9OICovCiAgICBCVVRUT05fM1NUQVRFLCAgICAgIC8qIEJTXzNTVEFURSAqLwogICAgQlVUVE9OXzNTVEFURSwgICAgICAvKiBCU19BVVRPM1NUQVRFICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIEJTX0dST1VQQk9YICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIEJTX1VTRVJCVVRUT04gKi8KICAgIEJVVFRPTl9DSEVDS0VELCAgICAgLyogQlNfQVVUT1JBRElPQlVUVE9OICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIE5vdCBkZWZpbmVkICovCiAgICBCVVRUT05fVU5DSEVDS0VEICAgIC8qIEJTX09XTkVSRFJBVyAqLwp9OwoKdHlwZWRlZiB2b2lkICgqcGZQYWludCkoIFdORCAqd25kUHRyLCBIREMgaGRjLCBXT1JEIGFjdGlvbiApOwoKc3RhdGljIGNvbnN0IHBmUGFpbnQgYnRuUGFpbnRGdW5jW01BWF9CVE5fVFlQRV0gPQp7CiAgICBQQl9QYWludCwgICAgLyogQlNfUFVTSEJVVFRPTiAqLwogICAgUEJfUGFpbnQsICAgIC8qIEJTX0RFRlBVU0hCVVRUT04gKi8KICAgIENCX1BhaW50LCAgICAvKiBCU19DSEVDS0JPWCAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX0FVVE9DSEVDS0JPWCAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX1JBRElPQlVUVE9OICovCiAgICBDQl9QYWludCwgICAgLyogQlNfM1NUQVRFICovCiAgICBDQl9QYWludCwgICAgLyogQlNfQVVUTzNTVEFURSAqLwogICAgR0JfUGFpbnQsICAgIC8qIEJTX0dST1VQQk9YICovCiAgICBVQl9QYWludCwgICAgLyogQlNfVVNFUkJVVFRPTiAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX0FVVE9SQURJT0JVVFRPTiAqLwogICAgTlVMTCwgICAgICAgIC8qIE5vdCBkZWZpbmVkICovCiAgICBPQl9QYWludCAgICAgLyogQlNfT1dORVJEUkFXICovCn07CgojZGVmaW5lIFBBSU5UX0JVVFRPTih3bmRQdHIsc3R5bGUsYWN0aW9uKSBcCiAgICAgaWYgKGJ0blBhaW50RnVuY1tzdHlsZV0pIHsgXAogICAgICAgICBIREMgaGRjID0gR2V0REMoICh3bmRQdHIpLT5od25kU2VsZiApOyBcCiAgICAgICAgIChidG5QYWludEZ1bmNbc3R5bGVdKSh3bmRQdHIsaGRjLGFjdGlvbik7IFwKICAgICAgICAgUmVsZWFzZURDKCAod25kUHRyKS0+aHduZFNlbGYsIGhkYyApOyB9CgojZGVmaW5lIEJVVFRPTl9TRU5EX0NUTENPTE9SKHduZFB0cixoZGMpIFwKICAgIFNlbmRNZXNzYWdlQSggR2V0UGFyZW50KCh3bmRQdHIpLT5od25kU2VsZiksIFdNX0NUTENPTE9SQlROLCBcCiAgICAgICAgICAgICAgICAgICAgKGhkYyksICh3bmRQdHIpLT5od25kU2VsZiApCgpzdGF0aWMgSEJJVE1BUCBoYml0bWFwQ2hlY2tCb3hlcyA9IDA7CnN0YXRpYyBXT1JEIGNoZWNrQm94V2lkdGggPSAwLCBjaGVja0JveEhlaWdodCA9IDA7CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBCdXR0b25XbmRQcm9jX2xvY2tlZAogKiAKICogQ2FsbGVkIHdpdGggd2luZG93IGxvY2sgaGVsZC4KICovCnN0YXRpYyBpbmxpbmUgTFJFU1VMVCBXSU5BUEkgQnV0dG9uV25kUHJvY19sb2NrZWQoV05EKiB3bmRQdHIsIFVJTlQgdU1zZywKCQkJCQkgICBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtICkKewogICAgUkVDVCByZWN0OwogICAgSFdORAloV25kID0gd25kUHRyLT5od25kU2VsZjsKICAgIFBPSU5UIHB0OwogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CiAgICBMT05HIHN0eWxlID0gd25kUHRyLT5kd1N0eWxlICYgMHgwZjsKICAgIEhBTkRMRSBvbGRIYml0bWFwOwoKICAgIHB0LnggPSBMT1dPUkQobFBhcmFtKTsKICAgIHB0LnkgPSBISVdPUkQobFBhcmFtKTsKCiAgICBzd2l0Y2ggKHVNc2cpCiAgICB7CiAgICBjYXNlIFdNX0dFVERMR0NPREU6CiAgICAgICAgc3dpdGNoKHN0eWxlKQogICAgICAgIHsKICAgICAgICBjYXNlIEJTX1BVU0hCVVRUT046ICAgICAgcmV0dXJuIERMR0NfQlVUVE9OIHwgRExHQ19VTkRFRlBVU0hCVVRUT047CiAgICAgICAgY2FzZSBCU19ERUZQVVNIQlVUVE9OOiAgIHJldHVybiBETEdDX0JVVFRPTiB8IERMR0NfREVGUFVTSEJVVFRPTjsKICAgICAgICBjYXNlIEJTX1JBRElPQlVUVE9OOgogICAgICAgIGNhc2UgQlNfQVVUT1JBRElPQlVUVE9OOiByZXR1cm4gRExHQ19CVVRUT04gfCBETEdDX1JBRElPQlVUVE9OOwogICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICByZXR1cm4gRExHQ19CVVRUT047CiAgICAgICAgfQoKICAgIGNhc2UgV01fRU5BQkxFOgogICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX0RSQVdFTlRJUkUgKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX0NSRUFURToKICAgICAgICBpZiAoIWhiaXRtYXBDaGVja0JveGVzKQogICAgICAgIHsKICAgICAgICAgICAgQklUTUFQIGJtcDsKICAgICAgICAgICAgaGJpdG1hcENoZWNrQm94ZXMgPSBMb2FkQml0bWFwQSgwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9DSEVDS0JPWEVTKSk7CiAgICAgICAgICAgIEdldE9iamVjdEEoIGhiaXRtYXBDaGVja0JveGVzLCBzaXplb2YoYm1wKSwgJmJtcCApOwogICAgICAgICAgICBjaGVja0JveFdpZHRoICA9IGJtcC5ibVdpZHRoIC8gNDsKICAgICAgICAgICAgY2hlY2tCb3hIZWlnaHQgPSBibXAuYm1IZWlnaHQgLyAzOwogICAgICAgIH0KICAgICAgICBpZiAoc3R5bGUgPCAwTCB8fCBzdHlsZSA+PSBNQVhfQlROX1RZUEUpCiAgICAgICAgICAgIHJldHVybiAtMTsgLyogYWJvcnQgKi8KICAgICAgICBpbmZvUHRyLT5zdGF0ZSA9IEJVVFRPTl9VTkNIRUNLRUQ7CiAgICAgICAgaW5mb1B0ci0+aEZvbnQgPSAwOwogICAgICAgIGluZm9QdHItPmhJbWFnZSA9IDA7CiAgICAgICAgcmV0dXJuIDA7CgogICAgY2FzZSBXTV9FUkFTRUJLR05EOgogICAgICAgIHJldHVybiAxOwoKICAgIGNhc2UgV01fUEFJTlQ6CiAgICAgICAgaWYgKGJ0blBhaW50RnVuY1tzdHlsZV0pCiAgICAgICAgewogICAgICAgICAgICBQQUlOVFNUUlVDVCBwczsKICAgICAgICAgICAgSERDIGhkYyA9IHdQYXJhbSA/IChIREMpd1BhcmFtIDogQmVnaW5QYWludCggaFduZCwgJnBzICk7CgkgICAgU2V0QmtNb2RlKCBoZGMsIE9QQVFVRSApOwogICAgICAgICAgICAoYnRuUGFpbnRGdW5jW3N0eWxlXSkoIHduZFB0ciwgaGRjLCBPREFfRFJBV0VOVElSRSApOwogICAgICAgICAgICBpZiggIXdQYXJhbSApIEVuZFBhaW50KCBoV25kLCAmcHMgKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9LRVlET1dOOgoJaWYgKHdQYXJhbSA9PSBWS19TUEFDRSkKCXsKCSAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVFNUQVRFLCBUUlVFLCAwICk7CgkgICAgaW5mb1B0ci0+c3RhdGUgfD0gQlVUVE9OX0JUTlBSRVNTRUQ7Cgl9CglicmVhazsKCQogICAgY2FzZSBXTV9MQlVUVE9OREJMQ0xLOgogICAgICAgIGlmKHduZFB0ci0+ZHdTdHlsZSAmIEJTX05PVElGWSB8fCAKICAgICAgICAgICAgICAgIHN0eWxlPT1CU19SQURJT0JVVFRPTiB8fAogICAgICAgICAgICAgICAgc3R5bGU9PUJTX1VTRVJCVVRUT04gfHwKICAgICAgICAgICAgICAgIHN0eWxlPT1CU19PV05FUkRSQVcpIHsKICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBHZXRQYXJlbnQoaFduZCksIFdNX0NPTU1BTkQsCiAgICAgICAgICAgICAgICAgICAgTUFLRVdQQVJBTSggd25kUHRyLT53SURtZW51LCBCTl9ET1VCTEVDTElDS0VEICksIGhXbmQpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCiAgICBjYXNlIFdNX0xCVVRUT05ET1dOOgogICAgICAgIFNldENhcHR1cmUoIGhXbmQgKTsKICAgICAgICBTZXRGb2N1cyggaFduZCApOwogICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUU1RBVEUsIFRSVUUsIDAgKTsKICAgICAgICBpbmZvUHRyLT5zdGF0ZSB8PSBCVVRUT05fQlROUFJFU1NFRDsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX0tFWVVQOgoJaWYgKHdQYXJhbSAhPSBWS19TUEFDRSkKCSAgICBicmVhazsKCS8qIGZhbGwgdGhyb3VnaCAqLwogICAgY2FzZSBXTV9MQlVUVE9OVVA6CiAgICAgICAgaWYgKCEoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fQlROUFJFU1NFRCkpIGJyZWFrOwogICAgICAgIGluZm9QdHItPnN0YXRlICY9IEJVVFRPTl9OU1RBVEVTOwogICAgICAgIGlmICghKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSkgewogICAgICAgICAgICBSZWxlYXNlQ2FwdHVyZSgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRTVEFURSwgRkFMU0UsIDAgKTsKICAgICAgICBSZWxlYXNlQ2FwdHVyZSgpOwogICAgICAgIEdldENsaWVudFJlY3QoIGhXbmQsICZyZWN0ICk7CglpZiAodU1zZyA9PSBXTV9LRVlVUCB8fCBQdEluUmVjdCggJnJlY3QsIHB0ICkpCiAgICAgICAgewogICAgICAgICAgICBzd2l0Y2goc3R5bGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBCU19BVVRPQ0hFQ0tCT1g6CiAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVENIRUNLLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICEoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fQ0hFQ0tFRCksIDAgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEJTX0FVVE9SQURJT0JVVFRPTjoKICAgICAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUQ0hFQ0ssIFRSVUUsIDAgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEJTX0FVVE8zU1RBVEU6CiAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVENIRUNLLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl8zU1RBVEUpID8gMCA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChpbmZvUHRyLT5zdGF0ZSAmIDMpICsgMSksIDAgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggR2V0UGFyZW50KGhXbmQpLCBXTV9DT01NQU5ELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFLRVdQQVJBTSggd25kUHRyLT53SURtZW51LCBCTl9DTElDS0VEICksIGhXbmQpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX0NBUFRVUkVDSEFOR0VEOgogICAgICAgIGlmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9CVE5QUkVTU0VEKSB7CiAgICAgICAgICAgIGluZm9QdHItPnN0YXRlICY9IEJVVFRPTl9OU1RBVEVTOwogICAgICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpIAogICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRTVEFURSwgRkFMU0UsIDAgKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9NT1VTRU1PVkU6CiAgICAgICAgaWYgKEdldENhcHR1cmUoKSA9PSBoV25kKQogICAgICAgIHsKICAgICAgICAgICAgR2V0Q2xpZW50UmVjdCggaFduZCwgJnJlY3QgKTsKICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRTVEFURSwgUHRJblJlY3QoJnJlY3QsIHB0KSwgMCApOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX05DSElUVEVTVDoKICAgICAgICBpZihzdHlsZSA9PSBCU19HUk9VUEJPWCkgcmV0dXJuIEhUVFJBTlNQQVJFTlQ7CiAgICAgICAgcmV0dXJuIERlZldpbmRvd1Byb2NBKCBoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSApOwoKICAgIGNhc2UgV01fU0VUVEVYVDoKICAgICAgICBERUZXTkRfU2V0VGV4dCggd25kUHRyLCAoTFBDU1RSKWxQYXJhbSApOwoJaWYoIHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZJU0lCTEUgKQogICAgICAgICAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9EUkFXRU5USVJFICk7CiAgICAgICAgcmV0dXJuIDA7CgogICAgY2FzZSBXTV9TRVRGT05UOgogICAgICAgIGluZm9QdHItPmhGb250ID0gKEhGT05UMTYpd1BhcmFtOwogICAgICAgIGlmIChsUGFyYW0gJiYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZJU0lCTEUpKSAKCSAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9EUkFXRU5USVJFICk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9HRVRGT05UOgogICAgICAgIHJldHVybiBpbmZvUHRyLT5oRm9udDsKCiAgICBjYXNlIFdNX1NFVEZPQ1VTOgogICAgICAgIGlmICgoc3R5bGUgPT0gQlNfQVVUT1JBRElPQlVUVE9OKSAmJiAoR2V0Q2FwdHVyZSgpICE9IGhXbmQpICYmCiAgICAgICAgICAgICEoU2VuZE1lc3NhZ2VBKGhXbmQsIEJNX0dFVENIRUNLLCAwLCAwKSAmIEJTVF9DSEVDS0VEKSkKCXsKICAgICAgICAgICAgLyogVGhlIG5vdGlmaWNhdGlvbiBpcyBzZW50IHdoZW4gdGhlIGJ1dHRvbiAoQlNfQVVUT1JBRElPQlVUVE9OKSAKICAgICAgICAgICAgICAgaXMgdW5ja2Vja2VkIGFuZCB0aGUgZm9jdXMgd2FzIG5vdCBnaXZlbiBieSBhIG1vdXNlIGNsaWNrLiAqLwogICAgICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVENIRUNLLCBUUlVFLCAwICk7CiAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggR2V0UGFyZW50KGhXbmQpLCBXTV9DT01NQU5ELAogICAgICAgICAgICAgICAgICAgICAgICAgIE1BS0VXUEFSQU0oIHduZFB0ci0+d0lEbWVudSwgQk5fQ0xJQ0tFRCApLCBoV25kKTsKICAgICAgICB9CiAgICAgICAgaW5mb1B0ci0+c3RhdGUgfD0gQlVUVE9OX0hBU0ZPQ1VTOwogICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX0ZPQ1VTICk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9LSUxMRk9DVVM6CiAgICAgICAgaW5mb1B0ci0+c3RhdGUgJj0gfkJVVFRPTl9IQVNGT0NVUzsKCVBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX0ZPQ1VTICk7CglJbnZhbGlkYXRlUmVjdCggaFduZCwgTlVMTCwgVFJVRSApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fU1lTQ09MT1JDSEFOR0U6CiAgICAgICAgSW52YWxpZGF0ZVJlY3QoIGhXbmQsIE5VTEwsIEZBTFNFICk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBCTV9TRVRTVFlMRTE2OgogICAgY2FzZSBCTV9TRVRTVFlMRToKICAgICAgICBpZiAoKHdQYXJhbSAmIDB4MGYpID49IE1BWF9CVE5fVFlQRSkgYnJlYWs7CiAgICAgICAgd25kUHRyLT5kd1N0eWxlID0gKHduZFB0ci0+ZHdTdHlsZSAmIDB4ZmZmZmZmZjApIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICh3UGFyYW0gJiAweDAwMDAwMDBmKTsKICAgICAgICBzdHlsZSA9IHduZFB0ci0+ZHdTdHlsZSAmIDB4MDAwMDAwMGY7CiAgICAgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfRFJBV0VOVElSRSApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQk1fQ0xJQ0s6CglTZW5kTWVzc2FnZUEoIGhXbmQsIFdNX0xCVVRUT05ET1dOLCAwLCAwICk7CglTZW5kTWVzc2FnZUEoIGhXbmQsIFdNX0xCVVRUT05VUCwgMCwgMCApOwoJYnJlYWs7CgogICAgY2FzZSBCTV9TRVRJTUFHRToKCW9sZEhiaXRtYXAgPSBpbmZvUHRyLT5oSW1hZ2U7CglpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0JJVE1BUCkgfHwgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0lDT04pKQoJICAgIGluZm9QdHItPmhJbWFnZSA9IChIQU5ETEUpIGxQYXJhbTsKCXJldHVybiBvbGRIYml0bWFwOwoKICAgIGNhc2UgQk1fR0VUSU1BR0U6CiAgICAgICAgaWYgKHdQYXJhbSA9PSBJTUFHRV9CSVRNQVApCgkgICAgcmV0dXJuIChIQklUTUFQKWluZm9QdHItPmhJbWFnZTsKCWVsc2UgaWYgKHdQYXJhbSA9PSBJTUFHRV9JQ09OKQoJICAgIHJldHVybiAoSElDT04paW5mb1B0ci0+aEltYWdlOwoJZWxzZQoJICAgIHJldHVybiAoSElDT04pMDsKCiAgICBjYXNlIEJNX0dFVENIRUNLMTY6CiAgICBjYXNlIEJNX0dFVENIRUNLOgogICAgICAgIHJldHVybiBpbmZvUHRyLT5zdGF0ZSAmIDM7CgogICAgY2FzZSBCTV9TRVRDSEVDSzE2OgogICAgY2FzZSBCTV9TRVRDSEVDSzoKICAgICAgICBpZiAod1BhcmFtID4gbWF4Q2hlY2tTdGF0ZVtzdHlsZV0pIHdQYXJhbSA9IG1heENoZWNrU3RhdGVbc3R5bGVdOwogICAgICAgIGlmICgoaW5mb1B0ci0+c3RhdGUgJiAzKSAhPSB3UGFyYW0pCiAgICAgICAgewoJICAgIGlmICgoc3R5bGUgPT0gQlNfUkFESU9CVVRUT04pIHx8IChzdHlsZSA9PSBCU19BVVRPUkFESU9CVVRUT04pKQoJICAgIHsKCQlpZiAod1BhcmFtKQoJCSAgICB3bmRQdHItPmR3U3R5bGUgfD0gV1NfVEFCU1RPUDsKCQllbHNlCgkJICAgIHduZFB0ci0+ZHdTdHlsZSAmPSB+V1NfVEFCU1RPUDsKCSAgICB9CiAgICAgICAgICAgIGluZm9QdHItPnN0YXRlID0gKGluZm9QdHItPnN0YXRlICYgfjMpIHwgd1BhcmFtOwogICAgICAgICAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9TRUxFQ1QgKTsKICAgICAgICB9CiAgICAgICAgaWYgKChzdHlsZSA9PSBCU19BVVRPUkFESU9CVVRUT04pICYmICh3UGFyYW0gPT0gQlVUVE9OX0NIRUNLRUQpKQogICAgICAgICAgICBCVVRUT05fQ2hlY2tBdXRvUmFkaW9CdXR0b24oIHduZFB0ciApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQk1fR0VUU1RBVEUxNjoKICAgIGNhc2UgQk1fR0VUU1RBVEU6CiAgICAgICAgcmV0dXJuIGluZm9QdHItPnN0YXRlOwoKICAgIGNhc2UgQk1fU0VUU1RBVEUxNjoKICAgIGNhc2UgQk1fU0VUU1RBVEU6CiAgICAgICAgaWYgKHdQYXJhbSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCkgYnJlYWs7CiAgICAgICAgICAgIGluZm9QdHItPnN0YXRlIHw9IEJVVFRPTl9ISUdITElHSFRFRDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpKSBicmVhazsKICAgICAgICAgICAgaW5mb1B0ci0+c3RhdGUgJj0gfkJVVFRPTl9ISUdITElHSFRFRDsKICAgICAgICB9CiAgICAgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfU0VMRUNUICk7CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gRGVmV2luZG93UHJvY0EoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgQnV0dG9uV25kUHJvYwogKiBUaGUgYnV0dG9uIHdpbmRvdyBwcm9jZWR1cmUuIFRoaXMgaXMganVzdCBhIHdyYXBwZXIgd2hpY2ggbG9ja3MKICogdGhlIHBhc3NlZCBIV05EIGFuZCBjYWxscyB0aGUgcmVhbCB3aW5kb3cgcHJvY2VkdXJlICh3aXRoIGEgV05EKgogKiBwb2ludGVyIHBvaW50aW5nIHRvIHRoZSBsb2NrZWQgd2luZG93c3RydWN0dXJlKS4KICovCkxSRVNVTFQgV0lOQVBJIEJ1dHRvblduZFByb2MoIEhXTkQgaFduZCwgVUlOVCB1TXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtICkKewogICAgTFJFU1VMVCByZXM7CiAgICBXTkQgKnduZFB0ciA9IFdJTl9GaW5kV25kUHRyKGhXbmQpOwoKICAgIHJlcyA9IEJ1dHRvblduZFByb2NfbG9ja2VkKHduZFB0cix1TXNnLHdQYXJhbSxsUGFyYW0pOwoKICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7CiAgICByZXR1cm4gcmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICBQdXNoIEJ1dHRvbiBGdW5jdGlvbnMKICovCnN0YXRpYyB2b2lkIFBCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKQp7CiAgICBCVVRUT05JTkZPICppbmZvUHRyICAgICAgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwogICAgQk9PTCAgICAgICAgYkhpZ2hMaWdodGVkID0gKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKTsKCiAgICAvKiAKICAgICAqIERlbGVnYXRlIHRoaXMgdG8gdGhlIG1vcmUgZ2VuZXJpYyBwdXNoYnV0dG9uIHBhaW50aW5nCiAgICAgKiBtZXRob2QuCiAgICAgKi8KICAgIEJVVFRPTl9EcmF3UHVzaEJ1dHRvbih3bmRQdHIsCgkJCSAgaERDLAoJCQkgIGFjdGlvbiwKCQkJICBiSGlnaExpZ2h0ZWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGlzIG1ldGhvZCB3aWxsIGFjdHVhbGx5IGRvIHRoZSBkcmF3aW5nIG9mIHRoZSBwdXNoYnV0dG9uIAogKiBkZXBlbmRpbmcgb24gaXQncyBzdGF0ZSBhbmQgdGhlIHB1c2hlZFN0YXRlIHBhcmFtZXRlci4KICovCnN0YXRpYyB2b2lkIEJVVFRPTl9EcmF3UHVzaEJ1dHRvbigKICBXTkQqIHduZFB0ciwKICBIREMgIGhEQywgCiAgV09SRCBhY3Rpb24sIAogIEJPT0wgcHVzaGVkU3RhdGUgKQp7CiAgICBSRUNUIHJjLCBmb2N1c19yZWN0OwogICAgSFBFTiBoT2xkUGVuOwogICAgSEJSVVNIIGhPbGRCcnVzaDsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwogICAgaW50IHhCb3JkZXJPZmZzZXQsIHlCb3JkZXJPZmZzZXQ7CiAgICB4Qm9yZGVyT2Zmc2V0ID0geUJvcmRlck9mZnNldCA9IDA7CgogICAgR2V0Q2xpZW50UmVjdCggd25kUHRyLT5od25kU2VsZiwgJnJjICk7CgogICAgICAvKiBTZW5kIFdNX0NUTENPTE9SIHRvIGFsbG93IGNoYW5naW5nIHRoZSBmb250ICh0aGUgY29sb3JzIGFyZSBmaXhlZCkgKi8KICAgIGlmIChpbmZvUHRyLT5oRm9udCkgU2VsZWN0T2JqZWN0KCBoREMsIGluZm9QdHItPmhGb250ICk7CiAgICBCVVRUT05fU0VORF9DVExDT0xPUiggd25kUHRyLCBoREMgKTsKICAgIGhPbGRQZW4gPSAoSFBFTilTZWxlY3RPYmplY3QoaERDLCBHZXRTeXNDb2xvclBlbihDT0xPUl9XSU5ET1dGUkFNRSkpOwogICAgaE9sZEJydXNoID0oSEJSVVNIKVNlbGVjdE9iamVjdChoREMsR2V0U3lzQ29sb3JCcnVzaChDT0xPUl9CVE5GQUNFKSk7CiAgICBTZXRCa01vZGUoaERDLCBUUkFOU1BBUkVOVCk7CgogICAgaWYgKCBUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQogICAgewogICAgICAgIFJlY3RhbmdsZShoREMsIHJjLmxlZnQsIHJjLnRvcCwgcmMucmlnaHQsIHJjLmJvdHRvbSk7CgogICAgICAgIFNldFBpeGVsKCBoREMsIHJjLmxlZnQsIHJjLnRvcCwgR2V0U3lzQ29sb3IoQ09MT1JfV0lORE9XKSApOwogICAgICAgIFNldFBpeGVsKCBoREMsIHJjLmxlZnQsIHJjLmJvdHRvbS0xLCBHZXRTeXNDb2xvcihDT0xPUl9XSU5ET1cpICk7CiAgICAgICAgU2V0UGl4ZWwoIGhEQywgcmMucmlnaHQtMSwgcmMudG9wLCBHZXRTeXNDb2xvcihDT0xPUl9XSU5ET1cpICk7CiAgICAgICAgU2V0UGl4ZWwoIGhEQywgcmMucmlnaHQtMSwgcmMuYm90dG9tLTEsIEdldFN5c0NvbG9yKENPTE9SX1dJTkRPVykpOwoJSW5mbGF0ZVJlY3QoICZyYywgLTEsIC0xICk7CiAgICB9CiAgICAKICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgMHgwMDBmKSA9PSBCU19ERUZQVVNIQlVUVE9OKQogICAgewogICAgICAgIFJlY3RhbmdsZShoREMsIHJjLmxlZnQsIHJjLnRvcCwgcmMucmlnaHQsIHJjLmJvdHRvbSk7CglJbmZsYXRlUmVjdCggJnJjLCAtMSwgLTEgKTsKICAgIH0KCiAgICBpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKICAgIHsKICAgICAgICBpZiAocHVzaGVkU3RhdGUpCgl7CgkgICAgLyogZHJhdyBidXR0b24gc2hhZG93OiAqLwoJICAgIFNlbGVjdE9iamVjdChoREMsIEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfQlROU0hBRE9XKSk7CgkgICAgUGF0Qmx0KGhEQywgcmMubGVmdCwgcmMudG9wLCAxLCByYy5ib3R0b20tcmMudG9wLCBQQVRDT1BZICk7CgkgICAgUGF0Qmx0KGhEQywgcmMubGVmdCwgcmMudG9wLCByYy5yaWdodC1yYy5sZWZ0LCAxLCBQQVRDT1BZICk7CgkgICAgcmMubGVmdCArPSAyOyAgLyogVG8gcG9zaXRpb24gdGhlIHRleHQgZG93biBhbmQgcmlnaHQgKi8KCSAgICByYy50b3AgICs9IDI7Cgl9IGVsc2UgewoJICAgcmMucmlnaHQrKywgcmMuYm90dG9tKys7CgkgICBEcmF3RWRnZSggaERDLCAmcmMsIEVER0VfUkFJU0VELCBCRl9SRUNUICk7CgoJICAgLyogVG8gcGxhY2UgZGUgYml0bWFwIGNvcnJlY3RseSAqLwoJICAgeEJvcmRlck9mZnNldCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRURHRSk7CgkgICB5Qm9yZGVyT2Zmc2V0ICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lFREdFKTsKCgkgICByYy5yaWdodC0tLCByYy5ib3R0b20tLTsKCX0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBVSU5UIHVTdGF0ZSA9IERGQ1NfQlVUVE9OUFVTSDsKCiAgICAgICAgaWYgKHB1c2hlZFN0YXRlKQoJewoJICAgIGlmICggKHduZFB0ci0+ZHdTdHlsZSAmIDB4MDAwZikgPT0gQlNfREVGUFVTSEJVVFRPTiApCgkgICAgICAgIHVTdGF0ZSB8PSBERkNTX0ZMQVQ7CgkgICAgZWxzZQoJICAgICAgICB1U3RhdGUgfD0gREZDU19QVVNIRUQ7Cgl9CgoJRHJhd0ZyYW1lQ29udHJvbCggaERDLCAmcmMsIERGQ19CVVRUT04sIHVTdGF0ZSApOwoJSW5mbGF0ZVJlY3QoICZyYywgLTIsIC0yICk7CgoJZm9jdXNfcmVjdCA9IHJjOwoKICAgICAgICBpZiAocHVzaGVkU3RhdGUpCgl7CgkgICAgcmMubGVmdCArPSAyOyAgLyogVG8gcG9zaXRpb24gdGhlIHRleHQgZG93biBhbmQgcmlnaHQgKi8KCSAgICByYy50b3AgICs9IDI7Cgl9CiAgICB9CgogICAgLyogZHJhdyBidXR0b24gbGFiZWwsIGlmIGFueToKICAgICAqCiAgICAgKiBJbiB3aW45eCB3ZSBkb24ndCBzaG93IHRleHQgaWYgdGhlcmUgaXMgYSBiaXRtYXAgb3IgaWNvbi4KICAgICAqIEkgZG9uJ3Qga25vdyBhYm91dCB3aW4zMSBzbyBJIGxlYXZlIGl0IGFzIGl0IHdhcyBmb3Igd2luMzEuCiAgICAgKiBEZW5uaXMgQmr2cmtsdW5kIDEyIEp1bCwgOTkKICAgICAqLwogICAgaWYgKCB3bmRQdHItPnRleHQgJiYgd25kUHRyLT50ZXh0WzBdCgkgJiYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0sgfHwgISh3bmRQdHItPmR3U3R5bGUgJiAoQlNfSUNPTnxCU19CSVRNQVApKSkgKQogICAgewogICAgICAgIExPR0JSVVNIIGxiOwogICAgICAgIEdldE9iamVjdEEoIEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfQlRORkFDRSksIHNpemVvZihsYiksICZsYiApOwogICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCAmJgogICAgICAgICAgICBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCk9PWxiLmxiQ29sb3IpCiAgICAgICAgICAgIC8qIGRvbid0IHdyaXRlIGdyYXkgdGV4dCBvbiBncmF5IGJhY2tncm91bmQgKi8KICAgICAgICAgICAgUGFpbnRHcmF5T25HcmF5KCBoREMsaW5mb1B0ci0+aEZvbnQsJnJjLHduZFB0ci0+dGV4dCwKCQkJICAgICAgIERUX0NFTlRFUiB8IERUX1ZDRU5URVIgKTsKICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBTZXRUZXh0Q29sb3IoIGhEQywgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFN5c0NvbG9yKENPTE9SX0dSQVlURVhUKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFN5c0NvbG9yKENPTE9SX0JUTlRFWFQpICk7CiAgICAgICAgICAgIERyYXdUZXh0QSggaERDLCB3bmRQdHItPnRleHQsIC0xLCAmcmMsCiAgICAgICAgICAgICAgICAgICAgICAgICBEVF9TSU5HTEVMSU5FIHwgRFRfQ0VOVEVSIHwgRFRfVkNFTlRFUiApOwogICAgICAgICAgICAvKiBkbyB3ZSBoYXZlIHRoZSBmb2N1cz8KCSAgICAgKiBXaW45eCBkcmF3cyBmb2N1cyBsYXN0IHdpdGggYSBzaXplIHByb3AuIHRvIHRoZSBidXR0b24KCSAgICAgKi8KICAgICAgICAgICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0sKCQkmJiBpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUkVDVCByID0geyAwLCAwLCAwLCAwIH07CiAgICAgICAgICAgICAgICBJTlQgeGRlbHRhLCB5ZGVsdGE7CgogICAgICAgICAgICAgICAgRHJhd1RleHRBKCBoREMsIHduZFB0ci0+dGV4dCwgLTEsICZyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX1NJTkdMRUxJTkUgfCBEVF9DQUxDUkVDVCApOwogICAgICAgICAgICAgICAgeGRlbHRhID0gKChyYy5yaWdodCAtIHJjLmxlZnQpIC0gKHIucmlnaHQgLSByLmxlZnQpIC0gMSkgLyAyOwogICAgICAgICAgICAgICAgeWRlbHRhID0gKChyYy5ib3R0b20gLSByYy50b3ApIC0gKHIuYm90dG9tIC0gci50b3ApIC0gMSkgLyAyOwogICAgICAgICAgICAgICAgaWYgKHhkZWx0YSA8IDApIHhkZWx0YSA9IDA7CiAgICAgICAgICAgICAgICBpZiAoeWRlbHRhIDwgMCkgeWRlbHRhID0gMDsKICAgICAgICAgICAgICAgIEluZmxhdGVSZWN0KCAmcmMsIC14ZGVsdGEsIC15ZGVsdGEgKTsKICAgICAgICAgICAgICAgIERyYXdGb2N1c1JlY3QoIGhEQywgJnJjICk7CiAgICAgICAgICAgIH0KICAgICAgICB9ICAgCiAgICB9CiAgICBpZiAoICgod25kUHRyLT5kd1N0eWxlICYgQlNfSUNPTikgfHwgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0JJVE1BUCkgKSAmJgoJIChpbmZvUHRyLT5oSW1hZ2UgIT0gMCkgKQogICAgewoJaW50IHlPZmZzZXQsIHhPZmZzZXQ7CglpbnQgaW1hZ2VXaWR0aCwgaW1hZ2VIZWlnaHQ7CgoJLyoKCSAqIFdlIGV4dHJhY3QgdGhlIHNpemUgb2YgdGhlIGltYWdlIGZyb20gdGhlIGhhbmRsZS4KCSAqLwoJaWYgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0lDT04pCgl7CgkgICAgSUNPTklORk8gaWNvbkluZm87CgkgICAgQklUTUFQICAgYm07CgoJICAgIEdldEljb25JbmZvKChISUNPTilpbmZvUHRyLT5oSW1hZ2UsICZpY29uSW5mbyk7CgkgICAgR2V0T2JqZWN0QSAoaWNvbkluZm8uaGJtQ29sb3IsIHNpemVvZihCSVRNQVApLCAmYm0pOwoJICAgIAoJICAgIGltYWdlV2lkdGggID0gYm0uYm1XaWR0aDsKCSAgICBpbWFnZUhlaWdodCA9IGJtLmJtSGVpZ2h0OwoKICAgICAgICAgICAgRGVsZXRlT2JqZWN0KGljb25JbmZvLmhibUNvbG9yKTsKICAgICAgICAgICAgRGVsZXRlT2JqZWN0KGljb25JbmZvLmhibU1hc2spOwoKCX0KCWVsc2UKCXsKCSAgICBCSVRNQVAgICBibTsKCgkgICAgR2V0T2JqZWN0QSAoaW5mb1B0ci0+aEltYWdlLCBzaXplb2YoQklUTUFQKSwgJmJtKTsKCQoJICAgIGltYWdlV2lkdGggID0gYm0uYm1XaWR0aDsKCSAgICBpbWFnZUhlaWdodCA9IGJtLmJtSGVpZ2h0OwoJfQoKCS8qIENlbnRlciB0aGUgYml0bWFwICovCgl4T2Zmc2V0ID0gKCgocmMucmlnaHQgLSByYy5sZWZ0KSAtIDIqeEJvcmRlck9mZnNldCkgLSBpbWFnZVdpZHRoICkgLyAyOwoJeU9mZnNldCA9ICgoKHJjLmJvdHRvbSAtIHJjLnRvcCkgLSAyKnlCb3JkZXJPZmZzZXQpIC0gaW1hZ2VIZWlnaHQpIC8gMjsKCgkvKiBJZiB0aGUgaW1hZ2UgaXMgdG9vIGJpZyBmb3IgdGhlIGJ1dHRvbiB0aGVuIGNyZWF0ZSBhIHJlZ2lvbiovCiAgICAgICAgaWYoeE9mZnNldCA8IDAgfHwgeU9mZnNldCA8IDApCgl7CiAgICAgICAgICAgIEhSR04gaEJpdG1hcFJnbiA9IDA7CiAgICAgICAgICAgIGhCaXRtYXBSZ24gPSBDcmVhdGVSZWN0UmduKAogICAgICAgICAgICAgICAgcmMubGVmdCArIHhCb3JkZXJPZmZzZXQsIHJjLnRvcCAreUJvcmRlck9mZnNldCwgCiAgICAgICAgICAgICAgICByYy5yaWdodCAtIHhCb3JkZXJPZmZzZXQsIHJjLmJvdHRvbSAtIHlCb3JkZXJPZmZzZXQpOwogICAgICAgICAgICBTZWxlY3RDbGlwUmduKGhEQywgaEJpdG1hcFJnbik7CiAgICAgICAgICAgIERlbGV0ZU9iamVjdChoQml0bWFwUmduKTsKCX0KCgkvKiBMZXQgbWluaW11bSAxIHNwYWNlIGZyb20gYm9yZGVyICovCgl4T2Zmc2V0KyssIHlPZmZzZXQrKzsKCgkvKgoJICogRHJhdyB0aGUgaW1hZ2Ugbm93LgoJICovCglpZiAod25kUHRyLT5kd1N0eWxlICYgQlNfSUNPTikKCXsKICAJICAgIERyYXdJY29uKGhEQywKICAgICAgICAgICAgICAgIHJjLmxlZnQgKyB4T2Zmc2V0LCByYy50b3AgKyB5T2Zmc2V0LAoJCSAgICAgKEhJQ09OKWluZm9QdHItPmhJbWFnZSk7Cgl9CgllbHNlCiAgICAgICAgewoJICAgIEhEQyBoZGNNZW07CgoJICAgIGhkY01lbSA9IENyZWF0ZUNvbXBhdGlibGVEQyAoaERDKTsKCSAgICBTZWxlY3RPYmplY3QgKGhkY01lbSwgKEhCSVRNQVApaW5mb1B0ci0+aEltYWdlKTsKCSAgICBCaXRCbHQoaERDLCAKCQkgICByYy5sZWZ0ICsgeE9mZnNldCwgCgkJICAgcmMudG9wICsgeU9mZnNldCwgCgkJICAgaW1hZ2VXaWR0aCwgaW1hZ2VIZWlnaHQsCgkJICAgaGRjTWVtLCAwLCAwLCBTUkNDT1BZKTsKCSAgICAKCSAgICBEZWxldGVEQyAoaGRjTWVtKTsKCX0KCiAgICAgICAgaWYoeE9mZnNldCA8IDAgfHwgeU9mZnNldCA8IDApCiAgICAgICAgewogICAgICAgICAgICBTZWxlY3RDbGlwUmduKGhEQywgMCk7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChUV0VBS19XaW5lTG9vayAhPSBXSU4zMV9MT09LCgkmJiBpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykKICAgIHsKICAgICAgICBJbmZsYXRlUmVjdCggJmZvY3VzX3JlY3QsIC0xLCAtMSApOwogICAgICAgIERyYXdGb2N1c1JlY3QoIGhEQywgJmZvY3VzX3JlY3QgKTsKICAgIH0KCiAgICAKICAgIFNlbGVjdE9iamVjdCggaERDLCBoT2xkUGVuICk7CiAgICBTZWxlY3RPYmplY3QoIGhEQywgaE9sZEJydXNoICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgIFBCX1BhaW50ICYgQ0JfUGFpbnQgc3ViIGZ1bmN0aW9uICAgICAgICAgICAgICAgICAgICAgICAgW2ludGVybmFsXQogKiAgIFBhaW50IHRleHQgdXNpbmcgYSByYXN0ZXIgYnJ1c2ggdG8gYXZvaWQgZ3JheSB0ZXh0IG9uIGdyYXkgCiAqICAgYmFja2dyb3VuZC4gJ2Zvcm1hdCcgY2FuIGJlIGEgY29tYmluYXRpb24gb2YgRFRfQ0VOVEVSIGFuZCAKICogICBEVF9WQ0VOVEVSIHRvIHVzZSB0aGlzIGZ1bmN0aW9uIGluIGJvdGggUEJfUEFJTlQgYW5kIAogKiAgIENCX1BBSU5ULiAgIC0gRGlyayBUaGllcmJhY2gKICoKICogICBGSVhNRTogVGhpcyBhbmQgVEVYVF9HcmF5U3RyaW5nIHNob3VsZCBiZSBldmVudHVhbGx5IGNvbWJpbmVkLAogKiAgIHNvIGNhbGxpbmcgb25lIGNvbW1vbiBmdW5jdGlvbiBmcm9tIFBCX1BhaW50LCBDQl9QYWludCBhbmQKICogICBURVhUX0dyYXlTdHJpbmcgd2lsbCBiZSBlbm91Z2guIEFsc28gbm90ZSB0aGF0IHRoaXMKICogICBmdW5jdGlvbiBpZ25vcmVzIHRoZSBDQUNIRV9HZXRQYXR0ZXJuIGZ1bmNzLgogKi8KCnZvaWQgUGFpbnRHcmF5T25HcmF5KEhEQyBoREMsSEZPTlQgaEZvbnQsUkVDVCAqcmMsY2hhciAqdGV4dCwKCQkJVUlOVCBmb3JtYXQpCnsKLyogIFRoaXMgaXMgdGhlIHN0YW5kYXJkIGdyYXkgb24gZ3JheSBwYXR0ZXJuOgogICAgc3RhdGljIGNvbnN0IFdPUkQgUGF0dGVybltdID0gezB4QUEsMHg1NSwweEFBLDB4NTUsMHhBQSwweDU1LDB4QUEsMHg1NX07IAoqLwovKiAgVGhpcyBwYXR0ZXJuIGdpdmVzIGJldHRlciByZWFkYWJpbGl0eSB3aXRoIFggRm9udHMuCiAgICBGSVhNRTogTWF5YmUgdGhlIHVzZXIgc2hvdWxkIGJlIGFsbG93ZWQgdG8gZGVjaWRlIHdoaWNoIGhlIHdhbnRzLiAqLwogICAgc3RhdGljIGNvbnN0IFdPUkQgUGF0dGVybltdID0gezB4NTUsMHhGRiwweEFBLDB4RkYsMHg1NSwweEZGLDB4QUEsMHhGRn07IAoKICAgIEhCSVRNQVAgaGJtICA9IENyZWF0ZUJpdG1hcCggOCwgOCwgMSwgMSwgUGF0dGVybiApOwogICAgSERDIGhkY01lbSA9IENyZWF0ZUNvbXBhdGlibGVEQyhoREMpOwogICAgSEJJVE1BUCBoYm1NZW07CiAgICBIQlJVU0ggaEJyOwogICAgUkVDVCByZWN0LHJjMjsKCiAgICByZWN0PSpyYzsKICAgIERyYXdUZXh0QSggaERDLCB0ZXh0LCAtMSwgJnJlY3QsIERUX1NJTkdMRUxJTkUgfCBEVF9DQUxDUkVDVCk7CiAgICAvKiBub3cgdGV4dCB3aWR0aCBhbmQgaGVpZ2h0IGFyZSBpbiByZWN0LnJpZ2h0IGFuZCByZWN0LmJvdHRvbSAqLwogICAgcmMyPXJlY3Q7CiAgICByZWN0LmxlZnQgPSByZWN0LnRvcCA9IDA7IC8qIGRyYXdpbmcgcG9zIGluIGhkY01lbSAqLwogICAgaWYgKGZvcm1hdCAmIERUX0NFTlRFUikgcmVjdC5sZWZ0PShyYy0+cmlnaHQtcmVjdC5yaWdodCkvMjsKICAgIGlmIChmb3JtYXQgJiBEVF9WQ0VOVEVSKSByZWN0LnRvcD0ocmMtPmJvdHRvbS1yZWN0LmJvdHRvbSkvMjsKICAgIGhibU1lbSA9IENyZWF0ZUNvbXBhdGlibGVCaXRtYXAoIGhEQyxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tICk7CiAgICBTZWxlY3RPYmplY3QoIGhkY01lbSwgaGJtTWVtKTsKICAgIFBhdEJsdCggaGRjTWVtLDAsMCxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tLFdISVRFTkVTUyk7CiAgICAgIC8qIHdpbGwgYmUgb3ZlcndyaXR0ZW4gYnkgRHJhd1RleHQsIGJ1dCBqdXN0IGluIGNhc2UgKi8KICAgIGlmIChoRm9udCkgU2VsZWN0T2JqZWN0KCBoZGNNZW0sIGhGb250KTsKICAgIERyYXdUZXh0QSggaGRjTWVtLCB0ZXh0LCAtMSwgJnJjMiwgRFRfU0lOR0xFTElORSk7ICAKICAgICAgLyogQWZ0ZXIgZHJhdzogZm9yZWdyb3VuZCA9IDAgYml0cywgYmFja2dyb3VuZCA9IDEgYml0cyAqLwogICAgaEJyID0gU2VsZWN0T2JqZWN0KCBoZGNNZW0sIENyZWF0ZVBhdHRlcm5CcnVzaChoYm0pICk7CiAgICBEZWxldGVPYmplY3QoIGhibSApOwogICAgUGF0Qmx0KCBoZGNNZW0sMCwwLHJlY3QucmlnaHQscmVjdC5ib3R0b20sMHhBRjAyMjkpOyAKICAgICAgLyogb25seSBrZWVwIHRoZSBmb3JlZ3JvdW5kIGJpdHMgd2hlcmUgcGF0dGVybiBpcyAxICovCiAgICBEZWxldGVPYmplY3QoIFNlbGVjdE9iamVjdCggaGRjTWVtLGhCcikgKTsKICAgIEJpdEJsdChoREMscmVjdC5sZWZ0LHJlY3QudG9wLHJlY3QucmlnaHQscmVjdC5ib3R0b20saGRjTWVtLDAsMCxTUkNBTkQpOwogICAgICAvKiBrZWVwIHRoZSBiYWNrZ3JvdW5kIG9mIHRoZSBkZXN0ICovCiAgICBEZWxldGVEQyggaGRjTWVtKTsKICAgIERlbGV0ZU9iamVjdCggaGJtTWVtICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICBDaGVjayBCb3ggJiBSYWRpbyBCdXR0b24gRnVuY3Rpb25zCiAqLwoKc3RhdGljIHZvaWQgQ0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApCnsKICAgIFJFQ1QgcmJveCwgcnRleHQsIGNsaWVudDsKICAgIEhCUlVTSCBoQnJ1c2g7CiAgICBpbnQgdGV4dGxlbiwgZGVsdGE7CiAgICBCVVRUT05JTkZPICppbmZvUHRyID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKCiAgICAvKiAKICAgICAqIGlmIHRoZSBidXR0b24gaGFzIGEgYml0bWFwL2ljb24sIGRyYXcgYSBub3JtYWwgcHVzaGJ1dHRvbgogICAgICogaW5zdGVhZCBvZiBhIHJhZGlvbiBidXR0b24uCiAgICAgKi8KICAgIGlmIChpbmZvUHRyLT5oSW1hZ2UgIT0gMCkKICAgIHsKICAgICAgICBCT09MIGJIaWdoTGlnaHRlZCA9ICgoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpIHx8CgkJCSAgICAgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0NIRUNLRUQpKTsKCiAgICAgICAgQlVUVE9OX0RyYXdQdXNoQnV0dG9uKHduZFB0ciwKCQkJICAgICAgaERDLAoJCQkgICAgICBhY3Rpb24sCgkJCSAgICAgIGJIaWdoTGlnaHRlZCk7CglyZXR1cm47CiAgICB9CgogICAgdGV4dGxlbiA9IDA7CiAgICBHZXRDbGllbnRSZWN0KHduZFB0ci0+aHduZFNlbGYsICZjbGllbnQpOwogICAgcmJveCA9IHJ0ZXh0ID0gY2xpZW50OwoKICAgIGlmIChpbmZvUHRyLT5oRm9udCkgU2VsZWN0T2JqZWN0KCBoREMsIGluZm9QdHItPmhGb250ICk7CgogICAgLyogU29tZXRoaW5nIGlzIHN0aWxsIG5vdCByaWdodCwgY2hlY2tib3hlcyAoYW5kIGVkaXQgY29udHJvbHMpCiAgICAgKiBpbiB3c3BpbmczMiBoYXZlIHdoaXRlIGJhY2tncm91bmRzIGluc3RlYWQgb2YgZGFyayBncmV5LgogICAgICogQlVUVE9OX1NFTkRfQ1RMQ09MT1IoKSBpcyBldmVuIHdvcnNlIHNpbmNlIGl0IHJldHVybnMgMCBpbiB0aGlzCiAgICAgKiBwYXJ0aWN1bGFyIGNhc2UgYW5kIHRoZSBiYWNrZ3JvdW5kIGlzIG5vdCBwYWludGVkIGF0IGFsbC4KICAgICAqLwoKICAgIGhCcnVzaCA9IEdldENvbnRyb2xCcnVzaDE2KCB3bmRQdHItPmh3bmRTZWxmLCBoREMsIENUTENPTE9SX0JUTiApOwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBCU19MRUZUVEVYVCkgCiAgICB7CgkvKiBtYWdpYyArNCBpcyB3aGF0IENUTDNEIGV4cGVjdHMgKi8KCiAgICAgICAgcnRleHQucmlnaHQgLT0gY2hlY2tCb3hXaWR0aCArIDQ7CiAgICAgICAgcmJveC5sZWZ0ID0gcmJveC5yaWdodCAtIGNoZWNrQm94V2lkdGg7CiAgICB9CiAgICBlbHNlIAogICAgewogICAgICAgIHJ0ZXh0LmxlZnQgKz0gY2hlY2tCb3hXaWR0aCArIDQ7CiAgICAgICAgcmJveC5yaWdodCA9IGNoZWNrQm94V2lkdGg7CiAgICB9CgogICAgICAvKiBEcmF3IHRoZSBjaGVjay1ib3ggYml0bWFwICovCgogICAgaWYgKHduZFB0ci0+dGV4dCkgdGV4dGxlbiA9IHN0cmxlbiggd25kUHRyLT50ZXh0ICk7CiAgICBpZiAoYWN0aW9uID09IE9EQV9EUkFXRU5USVJFIHx8IGFjdGlvbiA9PSBPREFfU0VMRUNUKQogICAgeyAKICAgICAgICBpZiggVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSyApCiAgICAgICAgewogICAgICAgIEhEQyBoTWVtREMgPSBDcmVhdGVDb21wYXRpYmxlREMoIGhEQyApOwogICAgICAgIGludCB4ID0gMCwgeSA9IDA7CiAgICAgICAgZGVsdGEgPSAocmJveC5ib3R0b20gLSByYm94LnRvcCAtIGNoZWNrQm94SGVpZ2h0KSAvIDI7CgoJLyogQ2hlY2sgaW4gY2FzZSB0aGUgY2xpZW50IGFyZWEgaXMgc21hbGxlciB0aGFuIHRoZSBjaGVja2JveCBiaXRtYXAgKi8KCWlmIChkZWx0YSA8IDApIGRlbHRhID0gMDsKCiAgICAgICAgaWYgKGFjdGlvbiA9PSBPREFfU0VMRUNUKSBGaWxsUmVjdCggaERDLCAmcmJveCwgaEJydXNoICk7CiAgICAgICAgZWxzZSBGaWxsUmVjdCggaERDLCAmY2xpZW50LCBoQnJ1c2ggKTsKCiAgICAgICAgaWYgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSB4ICs9IDIgKiBjaGVja0JveFdpZHRoOwogICAgICAgIGlmIChpbmZvUHRyLT5zdGF0ZSAmIChCVVRUT05fQ0hFQ0tFRCB8IEJVVFRPTl8zU1RBVEUpKSB4ICs9IGNoZWNrQm94V2lkdGg7CiAgICAgICAgaWYgKCgod25kUHRyLT5kd1N0eWxlICYgMHgwZikgPT0gQlNfUkFESU9CVVRUT04pIHx8CiAgICAgICAgICAgICgod25kUHRyLT5kd1N0eWxlICYgMHgwZikgPT0gQlNfQVVUT1JBRElPQlVUVE9OKSkgeSArPSBjaGVja0JveEhlaWdodDsKICAgICAgICBlbHNlIGlmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl8zU1RBVEUpIHkgKz0gMiAqIGNoZWNrQm94SGVpZ2h0OwoKCS8qIFRoZSBiaXRtYXAgZm9yIHRoZSByYWRpbyBidXR0b24gaXMgbm90IGFsaWduZWQgd2l0aCB0aGUKCSAqIGxlZnQgb2YgdGhlIHdpbmRvdywgaXQgaXMgMSBwaXhlbCBvZmYuICovCiAgICAgICAgaWYgKCgod25kUHRyLT5kd1N0eWxlICYgMHgwZikgPT0gQlNfUkFESU9CVVRUT04pIHx8CiAgICAgICAgICAgICgod25kUHRyLT5kd1N0eWxlICYgMHgwZikgPT0gQlNfQVVUT1JBRElPQlVUVE9OKSkKCSAgcmJveC5sZWZ0ICs9IDE7CgoJU2VsZWN0T2JqZWN0KCBoTWVtREMsIGhiaXRtYXBDaGVja0JveGVzICk7CglCaXRCbHQoIGhEQywgcmJveC5sZWZ0LCByYm94LnRvcCArIGRlbHRhLCBjaGVja0JveFdpZHRoLAoJCSAgY2hlY2tCb3hIZWlnaHQsIGhNZW1EQywgeCwgeSwgU1JDQ09QWSApOwoJRGVsZXRlREMoIGhNZW1EQyApOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewoJICAgIFVJTlQgc3RhdGU7CgogICAgICAgICAgICBpZiAoKCh3bmRQdHItPmR3U3R5bGUgJiAweDBmKSA9PSBCU19SQURJT0JVVFRPTikgfHwKICAgICAgICAgICAgICAgICgod25kUHRyLT5kd1N0eWxlICYgMHgwZikgPT0gQlNfQVVUT1JBRElPQlVUVE9OKSkgc3RhdGUgPSBERkNTX0JVVFRPTlJBRElPOwogICAgICAgICAgICBlbHNlIGlmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl8zU1RBVEUpIHN0YXRlID0gREZDU19CVVRUT04zU1RBVEU7CgkgICAgZWxzZSBzdGF0ZSA9IERGQ1NfQlVUVE9OQ0hFQ0s7CgogICAgICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiAoQlVUVE9OX0NIRUNLRUQgfCBCVVRUT05fM1NUQVRFKSkgc3RhdGUgfD0gREZDU19DSEVDS0VEOwoJICAgIAoJICAgIGlmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCkgc3RhdGUgfD0gREZDU19QVVNIRUQ7CgoJICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCkgc3RhdGUgfD0gREZDU19JTkFDVElWRTsKCgkgICAgRHJhd0ZyYW1lQ29udHJvbCggaERDLCAmcmJveCwgREZDX0JVVFRPTiwgc3RhdGUgKTsKICAgICAgICB9CgoKICAgICAgICBpZiggdGV4dGxlbiAmJiBhY3Rpb24gIT0gT0RBX1NFTEVDVCApCiAgICAgICAgewoJICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQgJiYKCSAgICAgIEdldFN5c0NvbG9yKENPTE9SX0dSQVlURVhUKT09R2V0QmtDb2xvcihoREMpKSB7CiAgICAgICAgICAgIC8qIGRvbid0IHdyaXRlIGdyYXkgdGV4dCBvbiBncmF5IGJhY2tncm91bmQgKi8KICAgICAgICAgICAgUGFpbnRHcmF5T25HcmF5KCBoREMsIGluZm9QdHItPmhGb250LCAmcnRleHQsIHduZFB0ci0+dGV4dCwKCQkJICAgICBEVF9WQ0VOVEVSKTsKCSAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEKQogICAgICAgICAgICAgICAgU2V0VGV4dENvbG9yKCBoREMsIEdldFN5c0NvbG9yKENPTE9SX0dSQVlURVhUKSApOwogICAgICAgICAgICBEcmF3VGV4dEEoIGhEQywgd25kUHRyLT50ZXh0LCB0ZXh0bGVuLCAmcnRleHQsCgkJCSBEVF9TSU5HTEVMSU5FIHwgRFRfVkNFTlRFUiApOwoJICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmICgoYWN0aW9uID09IE9EQV9GT0NVUykgfHwKICAgICAgICAoKGFjdGlvbiA9PSBPREFfRFJBV0VOVElSRSkgJiYgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hBU0ZPQ1VTKSkpCiAgICB7CgkvKiBhZ2FpbiwgdGhpcyBpcyB3aGF0IENUTDNEIGV4cGVjdHMgKi8KCiAgICAgICAgU2V0UmVjdEVtcHR5KCZyYm94KTsKICAgICAgICBpZiggdGV4dGxlbiApCiAgICAgICAgICAgIERyYXdUZXh0QSggaERDLCB3bmRQdHItPnRleHQsIHRleHRsZW4sICZyYm94LAoJCQkgRFRfU0lOR0xFTElORSB8IERUX0NBTENSRUNUICk7CiAgICAgICAgdGV4dGxlbiA9IHJib3guYm90dG9tIC0gcmJveC50b3A7CiAgICAgICAgZGVsdGEgPSAoKHJ0ZXh0LmJvdHRvbSAtIHJ0ZXh0LnRvcCkgLSB0ZXh0bGVuKS8yOwogICAgICAgIHJib3guYm90dG9tID0gKHJib3gudG9wID0gcnRleHQudG9wICsgZGVsdGEgLSAxKSArIHRleHRsZW4gKyAyOwogICAgICAgIHRleHRsZW4gPSByYm94LnJpZ2h0IC0gcmJveC5sZWZ0OwogICAgICAgIHJib3gucmlnaHQgPSAocmJveC5sZWZ0ICs9IC0tcnRleHQubGVmdCkgKyB0ZXh0bGVuICsgMjsKICAgICAgICBJbnRlcnNlY3RSZWN0KCZyYm94LCAmcmJveCwgJnJ0ZXh0KTsKICAgICAgICBEcmF3Rm9jdXNSZWN0KCBoREMsICZyYm94ICk7CiAgICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICBCVVRUT05fQ2hlY2tBdXRvUmFkaW9CdXR0b24KICoKICogd25kUHRyIGlzIGNoZWNrZWQsIHVuY2hlY2sgZXZlcnkgb3RoZXIgYXV0byByYWRpbyBidXR0b24gaW4gZ3JvdXAKICovCnN0YXRpYyB2b2lkIEJVVFRPTl9DaGVja0F1dG9SYWRpb0J1dHRvbiggV05EICp3bmRQdHIgKQp7CiAgICBIV05EIHBhcmVudCwgc2libGluZywgc3RhcnQ7CiAgICBpZiAoISh3bmRQdHItPmR3U3R5bGUgJiBXU19DSElMRCkpIHJldHVybjsKICAgIHBhcmVudCA9IHduZFB0ci0+cGFyZW50LT5od25kU2VsZjsKICAgIC8qIGFzc3VyZSB0aGF0IHN0YXJ0aW5nIGNvbnRyb2wgaXMgbm90IGRpc2FibGVkIG9yIGludmlzaWJsZSAqLwogICAgc3RhcnQgPSBzaWJsaW5nID0gR2V0TmV4dERsZ0dyb3VwSXRlbSggcGFyZW50LCB3bmRQdHItPmh3bmRTZWxmLCBUUlVFICk7CiAgICBkbwogICAgewogICAgICAgIFdORCAqdG1wV25kOwogICAgICAgIGlmICghc2libGluZykgYnJlYWs7CiAgICAgICAgdG1wV25kID0gV0lOX0ZpbmRXbmRQdHIoc2libGluZyk7CiAgICAgICAgaWYgKCh3bmRQdHItPmh3bmRTZWxmICE9IHNpYmxpbmcpICYmCiAgICAgICAgICAgICgodG1wV25kLT5kd1N0eWxlICYgMHgwZikgPT0gQlNfQVVUT1JBRElPQlVUVE9OKSkKICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBzaWJsaW5nLCBCTV9TRVRDSEVDSywgQlVUVE9OX1VOQ0hFQ0tFRCwgMCApOwogICAgICAgIHNpYmxpbmcgPSBHZXROZXh0RGxnR3JvdXBJdGVtKCBwYXJlbnQsIHNpYmxpbmcsIEZBTFNFICk7CiAgICAgICAgV0lOX1JlbGVhc2VXbmRQdHIodG1wV25kKTsKICAgIH0gd2hpbGUgKHNpYmxpbmcgIT0gc3RhcnQpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgR3JvdXAgQm94IEZ1bmN0aW9ucwogKi8KCnN0YXRpYyB2b2lkIEdCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKQp7CiAgICBSRUNUIHJjLCByY0ZyYW1lOwogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CgogICAgaWYgKGFjdGlvbiAhPSBPREFfRFJBV0VOVElSRSkgcmV0dXJuOwoKICAgIEJVVFRPTl9TRU5EX0NUTENPTE9SKCB3bmRQdHIsIGhEQyApOwoKICAgIEdldENsaWVudFJlY3QoIHduZFB0ci0+aHduZFNlbGYsICZyYyk7CiAgICBpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykgewogICAgICAgIEhQRU4gaFByZXZQZW4gPSBTZWxlY3RPYmplY3QoIGhEQywKCQkJCQkgIEdldFN5c0NvbG9yUGVuKENPTE9SX1dJTkRPV0ZSQU1FKSk7CglIQlJVU0ggaFByZXZCcnVzaCA9IFNlbGVjdE9iamVjdCggaERDLAoJCQkJCSAgICAgIEdldFN0b2NrT2JqZWN0KE5VTExfQlJVU0gpICk7CgoJUmVjdGFuZ2xlKCBoREMsIHJjLmxlZnQsIHJjLnRvcCArIDIsIHJjLnJpZ2h0IC0gMSwgcmMuYm90dG9tIC0gMSApOwoJU2VsZWN0T2JqZWN0KCBoREMsIGhQcmV2QnJ1c2ggKTsKCVNlbGVjdE9iamVjdCggaERDLCBoUHJldlBlbiApOwogICAgfSBlbHNlIHsKCVRFWFRNRVRSSUNBIHRtOwoJcmNGcmFtZSA9IHJjOwoKCWlmIChpbmZvUHRyLT5oRm9udCkKCSAgICBTZWxlY3RPYmplY3QgKGhEQywgaW5mb1B0ci0+aEZvbnQpOwoJR2V0VGV4dE1ldHJpY3NBIChoREMsICZ0bSk7CglyY0ZyYW1lLnRvcCArPSAodG0udG1IZWlnaHQgLyAyKSAtIDE7CglEcmF3RWRnZSAoaERDLCAmcmNGcmFtZSwgRURHRV9FVENIRUQsIEJGX1JFQ1QpOwogICAgfQoKICAgIGlmICh3bmRQdHItPnRleHQpCiAgICB7CglpZiAoaW5mb1B0ci0+aEZvbnQpIFNlbGVjdE9iamVjdCggaERDLCBpbmZvUHRyLT5oRm9udCApOwogICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCkKICAgICAgICAgICAgU2V0VGV4dENvbG9yKCBoREMsIEdldFN5c0NvbG9yKENPTE9SX0dSQVlURVhUKSApOwogICAgICAgIHJjLmxlZnQgKz0gMTA7CiAgICAgICAgRHJhd1RleHRBKCBoREMsIHduZFB0ci0+dGV4dCwgLTEsICZyYywgRFRfU0lOR0xFTElORSB8IERUX05PQ0xJUCApOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgVXNlciBCdXR0b24gRnVuY3Rpb25zCiAqLwoKc3RhdGljIHZvaWQgVUJfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApCnsKICAgIFJFQ1QgcmM7CiAgICBIQlJVU0ggaEJydXNoOwogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CgogICAgaWYgKGFjdGlvbiA9PSBPREFfU0VMRUNUKSByZXR1cm47CgogICAgR2V0Q2xpZW50UmVjdCggd25kUHRyLT5od25kU2VsZiwgJnJjKTsKCiAgICBpZiAoaW5mb1B0ci0+aEZvbnQpIFNlbGVjdE9iamVjdCggaERDLCBpbmZvUHRyLT5oRm9udCApOwogICAgaEJydXNoID0gR2V0Q29udHJvbEJydXNoMTYoIHduZFB0ci0+aHduZFNlbGYsIGhEQywgQ1RMQ09MT1JfQlROICk7CgogICAgRmlsbFJlY3QoIGhEQywgJnJjLCBoQnJ1c2ggKTsKICAgIGlmICgoYWN0aW9uID09IE9EQV9GT0NVUykgfHwKICAgICAgICAoKGFjdGlvbiA9PSBPREFfRFJBV0VOVElSRSkgJiYgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hBU0ZPQ1VTKSkpCiAgICAgICAgRHJhd0ZvY3VzUmVjdCggaERDLCAmcmMgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIE93bmVyZHJhd24gQnV0dG9uIEZ1bmN0aW9ucwogKi8KCnN0YXRpYyB2b2lkIE9CX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKQp7CiAgICBCVVRUT05JTkZPICppbmZvUHRyID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKICAgIERSQVdJVEVNU1RSVUNUIGRpczsKCiAgICBkaXMuQ3RsVHlwZSAgICA9IE9EVF9CVVRUT047CiAgICBkaXMuQ3RsSUQgICAgICA9IHduZFB0ci0+d0lEbWVudTsKICAgIGRpcy5pdGVtSUQgICAgID0gMDsKICAgIGRpcy5pdGVtQWN0aW9uID0gYWN0aW9uOwogICAgZGlzLml0ZW1TdGF0ZSAgPSAoKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hBU0ZPQ1VTKSA/IE9EU19GT0NVUyA6IDApIHwKICAgICAgICAgICAgICAgICAgICAgKChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCkgPyBPRFNfU0VMRUNURUQgOiAwKSB8CiAgICAgICAgICAgICAgICAgICAgICgod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQpID8gT0RTX0RJU0FCTEVEIDogMCk7CiAgICBkaXMuaHduZEl0ZW0gICA9IHduZFB0ci0+aHduZFNlbGY7CiAgICBkaXMuaERDICAgICAgICA9IGhEQzsKICAgIGRpcy5pdGVtRGF0YSAgID0gMDsKICAgIEdldENsaWVudFJlY3QoIHduZFB0ci0+aHduZFNlbGYsICZkaXMucmNJdGVtICk7CgogICAgU2V0QmtDb2xvciggaERDLCBHZXRTeXNDb2xvciggQ09MT1JfQlRORkFDRSApICk7CgogICAgU2VuZE1lc3NhZ2VBKCBHZXRQYXJlbnQod25kUHRyLT5od25kU2VsZiksIFdNX0RSQVdJVEVNLAogICAgICAgICAgICAgICAgICAgIHduZFB0ci0+d0lEbWVudSwgKExQQVJBTSkmZGlzICk7Cn0KCg==