LyogRmlsZTogYnV0dG9uLmMgLS0gQnV0dG9uIHR5cGUgd2lkZ2V0cwogKgogKiBDb3B5cmlnaHQgKEMpIDE5OTMgSm9oYW5uZXMgUnVzY2hlaW5za2kKICogQ29weXJpZ2h0IChDKSAxOTkzIERhdmlkIE1ldGNhbGZlCiAqIENvcHlyaWdodCAoQykgMTk5NCBBbGV4YW5kcmUgSnVsbGlhcmQKICovCgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJ3aW4uaCIKI2luY2x1ZGUgImJ1dHRvbi5oIgojaW5jbHVkZSAid2luZS93aW51c2VyMTYuaCIKI2luY2x1ZGUgInR3ZWFrLmgiCgpzdGF0aWMgdm9pZCBQYWludEdyYXlPbkdyYXkoIEhEQyBoREMsSEZPTlQgaEZvbnQsUkVDVCAqcmMsCgkJCSAgICAgY2hhciAqdGV4dCwgVUlOVCBmb3JtYXQgKTsKCnN0YXRpYyB2b2lkIFBCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKTsKc3RhdGljIHZvaWQgQ0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApOwpzdGF0aWMgdm9pZCBHQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICk7CnN0YXRpYyB2b2lkIFVCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKTsKc3RhdGljIHZvaWQgT0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApOwpzdGF0aWMgdm9pZCBCVVRUT05fQ2hlY2tBdXRvUmFkaW9CdXR0b24oIFdORCAqd25kUHRyICk7CnN0YXRpYyB2b2lkIEJVVFRPTl9EcmF3UHVzaEJ1dHRvbiggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uLCBCT09MIHB1c2hlZFN0YXRlKTsKCiNkZWZpbmUgTUFYX0JUTl9UWVBFICAxMgoKc3RhdGljIGNvbnN0IFdPUkQgbWF4Q2hlY2tTdGF0ZVtNQVhfQlROX1RZUEVdID0KewogICAgQlVUVE9OX1VOQ0hFQ0tFRCwgICAvKiBCU19QVVNIQlVUVE9OICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIEJTX0RFRlBVU0hCVVRUT04gKi8KICAgIEJVVFRPTl9DSEVDS0VELCAgICAgLyogQlNfQ0hFQ0tCT1ggKi8KICAgIEJVVFRPTl9DSEVDS0VELCAgICAgLyogQlNfQVVUT0NIRUNLQk9YICovCiAgICBCVVRUT05fQ0hFQ0tFRCwgICAgIC8qIEJTX1JBRElPQlVUVE9OICovCiAgICBCVVRUT05fM1NUQVRFLCAgICAgIC8qIEJTXzNTVEFURSAqLwogICAgQlVUVE9OXzNTVEFURSwgICAgICAvKiBCU19BVVRPM1NUQVRFICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIEJTX0dST1VQQk9YICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIEJTX1VTRVJCVVRUT04gKi8KICAgIEJVVFRPTl9DSEVDS0VELCAgICAgLyogQlNfQVVUT1JBRElPQlVUVE9OICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIE5vdCBkZWZpbmVkICovCiAgICBCVVRUT05fVU5DSEVDS0VEICAgIC8qIEJTX09XTkVSRFJBVyAqLwp9OwoKdHlwZWRlZiB2b2lkICgqcGZQYWludCkoIFdORCAqd25kUHRyLCBIREMgaGRjLCBXT1JEIGFjdGlvbiApOwoKc3RhdGljIGNvbnN0IHBmUGFpbnQgYnRuUGFpbnRGdW5jW01BWF9CVE5fVFlQRV0gPQp7CiAgICBQQl9QYWludCwgICAgLyogQlNfUFVTSEJVVFRPTiAqLwogICAgUEJfUGFpbnQsICAgIC8qIEJTX0RFRlBVU0hCVVRUT04gKi8KICAgIENCX1BhaW50LCAgICAvKiBCU19DSEVDS0JPWCAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX0FVVE9DSEVDS0JPWCAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX1JBRElPQlVUVE9OICovCiAgICBDQl9QYWludCwgICAgLyogQlNfM1NUQVRFICovCiAgICBDQl9QYWludCwgICAgLyogQlNfQVVUTzNTVEFURSAqLwogICAgR0JfUGFpbnQsICAgIC8qIEJTX0dST1VQQk9YICovCiAgICBVQl9QYWludCwgICAgLyogQlNfVVNFUkJVVFRPTiAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX0FVVE9SQURJT0JVVFRPTiAqLwogICAgTlVMTCwgICAgICAgIC8qIE5vdCBkZWZpbmVkICovCiAgICBPQl9QYWludCAgICAgLyogQlNfT1dORVJEUkFXICovCn07CgojZGVmaW5lIFBBSU5UX0JVVFRPTih3bmRQdHIsc3R5bGUsYWN0aW9uKSBcCiAgICAgaWYgKGJ0blBhaW50RnVuY1tzdHlsZV0pIHsgXAogICAgICAgICBIREMgaGRjID0gR2V0REMoICh3bmRQdHIpLT5od25kU2VsZiApOyBcCiAgICAgICAgIChidG5QYWludEZ1bmNbc3R5bGVdKSh3bmRQdHIsaGRjLGFjdGlvbik7IFwKICAgICAgICAgUmVsZWFzZURDKCAod25kUHRyKS0+aHduZFNlbGYsIGhkYyApOyB9CgojZGVmaW5lIEJVVFRPTl9TRU5EX0NUTENPTE9SKHduZFB0cixoZGMpIFwKICAgIFNlbmRNZXNzYWdlQSggR2V0UGFyZW50KCh3bmRQdHIpLT5od25kU2VsZiksIFdNX0NUTENPTE9SQlROLCBcCiAgICAgICAgICAgICAgICAgICAgKGhkYyksICh3bmRQdHIpLT5od25kU2VsZiApCgpzdGF0aWMgSEJJVE1BUCBoYml0bWFwQ2hlY2tCb3hlcyA9IDA7CnN0YXRpYyBXT1JEIGNoZWNrQm94V2lkdGggPSAwLCBjaGVja0JveEhlaWdodCA9IDA7CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBCdXR0b25XbmRQcm9jX2xvY2tlZAogKiAKICogQ2FsbGVkIHdpdGggd2luZG93IGxvY2sgaGVsZC4KICovCnN0YXRpYyBpbmxpbmUgTFJFU1VMVCBXSU5BUEkgQnV0dG9uV25kUHJvY19sb2NrZWQoV05EKiB3bmRQdHIsIFVJTlQgdU1zZywKCQkJCQkgICBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtICkKewogICAgUkVDVCByZWN0OwogICAgSFdORAloV25kID0gd25kUHRyLT5od25kU2VsZjsKICAgIFBPSU5UIHB0OwogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CiAgICBMT05HIHN0eWxlID0gd25kUHRyLT5kd1N0eWxlICYgMHgwZjsKICAgIEhBTkRMRSBvbGRIYml0bWFwOwoKICAgIHB0LnggPSBMT1dPUkQobFBhcmFtKTsKICAgIHB0LnkgPSBISVdPUkQobFBhcmFtKTsKCiAgICBzd2l0Y2ggKHVNc2cpCiAgICB7CiAgICBjYXNlIFdNX0dFVERMR0NPREU6CiAgICAgICAgc3dpdGNoKHN0eWxlKQogICAgICAgIHsKICAgICAgICBjYXNlIEJTX1BVU0hCVVRUT046ICAgICAgcmV0dXJuIERMR0NfQlVUVE9OIHwgRExHQ19VTkRFRlBVU0hCVVRUT047CiAgICAgICAgY2FzZSBCU19ERUZQVVNIQlVUVE9OOiAgIHJldHVybiBETEdDX0JVVFRPTiB8IERMR0NfREVGUFVTSEJVVFRPTjsKICAgICAgICBjYXNlIEJTX1JBRElPQlVUVE9OOgogICAgICAgIGNhc2UgQlNfQVVUT1JBRElPQlVUVE9OOiByZXR1cm4gRExHQ19CVVRUT04gfCBETEdDX1JBRElPQlVUVE9OOwogICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICByZXR1cm4gRExHQ19CVVRUT047CiAgICAgICAgfQoKICAgIGNhc2UgV01fRU5BQkxFOgogICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX0RSQVdFTlRJUkUgKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX0NSRUFURToKICAgICAgICBpZiAoIWhiaXRtYXBDaGVja0JveGVzKQogICAgICAgIHsKICAgICAgICAgICAgQklUTUFQIGJtcDsKICAgICAgICAgICAgaGJpdG1hcENoZWNrQm94ZXMgPSBMb2FkQml0bWFwQSgwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9DSEVDS0JPWEVTKSk7CiAgICAgICAgICAgIEdldE9iamVjdEEoIGhiaXRtYXBDaGVja0JveGVzLCBzaXplb2YoYm1wKSwgJmJtcCApOwogICAgICAgICAgICBjaGVja0JveFdpZHRoICA9IGJtcC5ibVdpZHRoIC8gNDsKICAgICAgICAgICAgY2hlY2tCb3hIZWlnaHQgPSBibXAuYm1IZWlnaHQgLyAzOwogICAgICAgIH0KICAgICAgICBpZiAoc3R5bGUgPCAwTCB8fCBzdHlsZSA+PSBNQVhfQlROX1RZUEUpCiAgICAgICAgICAgIHJldHVybiAtMTsgLyogYWJvcnQgKi8KICAgICAgICBpbmZvUHRyLT5zdGF0ZSA9IEJVVFRPTl9VTkNIRUNLRUQ7CiAgICAgICAgaW5mb1B0ci0+aEZvbnQgPSAwOwogICAgICAgIGluZm9QdHItPmhJbWFnZSA9IDA7CiAgICAgICAgcmV0dXJuIDA7CgogICAgY2FzZSBXTV9FUkFTRUJLR05EOgogICAgICAgIHJldHVybiAxOwoKICAgIGNhc2UgV01fUEFJTlQ6CiAgICAgICAgaWYgKGJ0blBhaW50RnVuY1tzdHlsZV0pCiAgICAgICAgewogICAgICAgICAgICBQQUlOVFNUUlVDVCBwczsKICAgICAgICAgICAgSERDIGhkYyA9IHdQYXJhbSA/IChIREMpd1BhcmFtIDogQmVnaW5QYWludCggaFduZCwgJnBzICk7CgkgICAgU2V0QmtNb2RlKCBoZGMsIE9QQVFVRSApOwogICAgICAgICAgICAoYnRuUGFpbnRGdW5jW3N0eWxlXSkoIHduZFB0ciwgaGRjLCBPREFfRFJBV0VOVElSRSApOwogICAgICAgICAgICBpZiggIXdQYXJhbSApIEVuZFBhaW50KCBoV25kLCAmcHMgKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9LRVlET1dOOgoJaWYgKHdQYXJhbSA9PSBWS19TUEFDRSkKCXsKCSAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVFNUQVRFLCBUUlVFLCAwICk7CgkgICAgaW5mb1B0ci0+c3RhdGUgfD0gQlVUVE9OX0JUTlBSRVNTRUQ7Cgl9CglicmVhazsKCQogICAgY2FzZSBXTV9MQlVUVE9OREJMQ0xLOgogICAgICAgIGlmKHduZFB0ci0+ZHdTdHlsZSAmIEJTX05PVElGWSB8fCAKICAgICAgICAgICAgICAgIHN0eWxlPT1CU19SQURJT0JVVFRPTiB8fAogICAgICAgICAgICAgICAgc3R5bGU9PUJTX1VTRVJCVVRUT04gfHwKICAgICAgICAgICAgICAgIHN0eWxlPT1CU19PV05FUkRSQVcpIHsKICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBHZXRQYXJlbnQoaFduZCksIFdNX0NPTU1BTkQsCiAgICAgICAgICAgICAgICAgICAgTUFLRVdQQVJBTSggd25kUHRyLT53SURtZW51LCBCTl9ET1VCTEVDTElDS0VEICksIGhXbmQpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCiAgICBjYXNlIFdNX0xCVVRUT05ET1dOOgogICAgICAgIFNldENhcHR1cmUoIGhXbmQgKTsKICAgICAgICBTZXRGb2N1cyggaFduZCApOwogICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUU1RBVEUsIFRSVUUsIDAgKTsKICAgICAgICBpbmZvUHRyLT5zdGF0ZSB8PSBCVVRUT05fQlROUFJFU1NFRDsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX0tFWVVQOgoJaWYgKHdQYXJhbSAhPSBWS19TUEFDRSkKCSAgICBicmVhazsKCS8qIGZhbGwgdGhyb3VnaCAqLwogICAgY2FzZSBXTV9MQlVUVE9OVVA6CiAgICAgICAgaWYgKCEoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fQlROUFJFU1NFRCkpIGJyZWFrOwogICAgICAgIGluZm9QdHItPnN0YXRlICY9IEJVVFRPTl9OU1RBVEVTOwogICAgICAgIGlmICghKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSkgewogICAgICAgICAgICBSZWxlYXNlQ2FwdHVyZSgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRTVEFURSwgRkFMU0UsIDAgKTsKICAgICAgICBSZWxlYXNlQ2FwdHVyZSgpOwogICAgICAgIEdldENsaWVudFJlY3QoIGhXbmQsICZyZWN0ICk7CglpZiAodU1zZyA9PSBXTV9LRVlVUCB8fCBQdEluUmVjdCggJnJlY3QsIHB0ICkpCiAgICAgICAgewogICAgICAgICAgICBzd2l0Y2goc3R5bGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBCU19BVVRPQ0hFQ0tCT1g6CiAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVENIRUNLLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICEoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fQ0hFQ0tFRCksIDAgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEJTX0FVVE9SQURJT0JVVFRPTjoKICAgICAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUQ0hFQ0ssIFRSVUUsIDAgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEJTX0FVVE8zU1RBVEU6CiAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVENIRUNLLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl8zU1RBVEUpID8gMCA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChpbmZvUHRyLT5zdGF0ZSAmIDMpICsgMSksIDAgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggR2V0UGFyZW50KGhXbmQpLCBXTV9DT01NQU5ELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFLRVdQQVJBTSggd25kUHRyLT53SURtZW51LCBCTl9DTElDS0VEICksIGhXbmQpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX0NBUFRVUkVDSEFOR0VEOgogICAgICAgIGlmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9CVE5QUkVTU0VEKSB7CiAgICAgICAgICAgIGluZm9QdHItPnN0YXRlICY9IEJVVFRPTl9OU1RBVEVTOwogICAgICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpIAogICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRTVEFURSwgRkFMU0UsIDAgKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9NT1VTRU1PVkU6CiAgICAgICAgaWYgKEdldENhcHR1cmUoKSA9PSBoV25kKQogICAgICAgIHsKICAgICAgICAgICAgR2V0Q2xpZW50UmVjdCggaFduZCwgJnJlY3QgKTsKICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRTVEFURSwgUHRJblJlY3QoJnJlY3QsIHB0KSwgMCApOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX05DSElUVEVTVDoKICAgICAgICBpZihzdHlsZSA9PSBCU19HUk9VUEJPWCkgcmV0dXJuIEhUVFJBTlNQQVJFTlQ7CiAgICAgICAgcmV0dXJuIERlZldpbmRvd1Byb2NBKCBoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSApOwoKICAgIGNhc2UgV01fU0VUVEVYVDoKICAgICAgICBERUZXTkRfU2V0VGV4dCggd25kUHRyLCAoTFBDU1RSKWxQYXJhbSApOwoJaWYoIHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZJU0lCTEUgKQogICAgICAgICAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9EUkFXRU5USVJFICk7CiAgICAgICAgcmV0dXJuIDA7CgogICAgY2FzZSBXTV9TRVRGT05UOgogICAgICAgIGluZm9QdHItPmhGb250ID0gKEhGT05UMTYpd1BhcmFtOwogICAgICAgIGlmIChsUGFyYW0gJiYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZJU0lCTEUpKSAKCSAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9EUkFXRU5USVJFICk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9HRVRGT05UOgogICAgICAgIHJldHVybiBpbmZvUHRyLT5oRm9udDsKCiAgICBjYXNlIFdNX1NFVEZPQ1VTOgogICAgICAgIGlmICgoc3R5bGUgPT0gQlNfQVVUT1JBRElPQlVUVE9OKSAmJiAoR2V0Q2FwdHVyZSgpICE9IGhXbmQpICYmCiAgICAgICAgICAgICEoU2VuZE1lc3NhZ2VBKGhXbmQsIEJNX0dFVENIRUNLLCAwLCAwKSAmIEJTVF9DSEVDS0VEKSkKCXsKICAgICAgICAgICAgLyogVGhlIG5vdGlmaWNhdGlvbiBpcyBzZW50IHdoZW4gdGhlIGJ1dHRvbiAoQlNfQVVUT1JBRElPQlVUVE9OKSAKICAgICAgICAgICAgICAgaXMgdW5ja2Vja2VkIGFuZCB0aGUgZm9jdXMgd2FzIG5vdCBnaXZlbiBieSBhIG1vdXNlIGNsaWNrLiAqLwogICAgICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVENIRUNLLCBUUlVFLCAwICk7CiAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggR2V0UGFyZW50KGhXbmQpLCBXTV9DT01NQU5ELAogICAgICAgICAgICAgICAgICAgICAgICAgIE1BS0VXUEFSQU0oIHduZFB0ci0+d0lEbWVudSwgQk5fQ0xJQ0tFRCApLCBoV25kKTsKICAgICAgICB9CiAgICAgICAgaW5mb1B0ci0+c3RhdGUgfD0gQlVUVE9OX0hBU0ZPQ1VTOwogICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX0ZPQ1VTICk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9LSUxMRk9DVVM6CiAgICAgICAgaW5mb1B0ci0+c3RhdGUgJj0gfkJVVFRPTl9IQVNGT0NVUzsKCVBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX0ZPQ1VTICk7CglJbnZhbGlkYXRlUmVjdCggaFduZCwgTlVMTCwgVFJVRSApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fU1lTQ09MT1JDSEFOR0U6CiAgICAgICAgSW52YWxpZGF0ZVJlY3QoIGhXbmQsIE5VTEwsIEZBTFNFICk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBCTV9TRVRTVFlMRTE2OgogICAgY2FzZSBCTV9TRVRTVFlMRToKICAgICAgICBpZiAoKHdQYXJhbSAmIDB4MGYpID49IE1BWF9CVE5fVFlQRSkgYnJlYWs7CiAgICAgICAgd25kUHRyLT5kd1N0eWxlID0gKHduZFB0ci0+ZHdTdHlsZSAmIDB4ZmZmZmZmZjApIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICh3UGFyYW0gJiAweDAwMDAwMDBmKTsKICAgICAgICBzdHlsZSA9IHduZFB0ci0+ZHdTdHlsZSAmIDB4MDAwMDAwMGY7CiAgICAgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfRFJBV0VOVElSRSApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQk1fU0VUSU1BR0U6CglvbGRIYml0bWFwID0gaW5mb1B0ci0+aEltYWdlOwoJaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBCU19CSVRNQVApIHx8ICh3bmRQdHItPmR3U3R5bGUgJiBCU19JQ09OKSkKCSAgICBpbmZvUHRyLT5oSW1hZ2UgPSAoSEFORExFKSBsUGFyYW07CglyZXR1cm4gb2xkSGJpdG1hcDsKCiAgICBjYXNlIEJNX0dFVElNQUdFOgogICAgICAgIGlmICh3UGFyYW0gPT0gSU1BR0VfQklUTUFQKQoJICAgIHJldHVybiAoSEJJVE1BUClpbmZvUHRyLT5oSW1hZ2U7CgllbHNlIGlmICh3UGFyYW0gPT0gSU1BR0VfSUNPTikKCSAgICByZXR1cm4gKEhJQ09OKWluZm9QdHItPmhJbWFnZTsKCWVsc2UKCSAgICByZXR1cm4gKEhJQ09OKTA7CgogICAgY2FzZSBCTV9HRVRDSEVDSzE2OgogICAgY2FzZSBCTV9HRVRDSEVDSzoKICAgICAgICByZXR1cm4gaW5mb1B0ci0+c3RhdGUgJiAzOwoKICAgIGNhc2UgQk1fU0VUQ0hFQ0sxNjoKICAgIGNhc2UgQk1fU0VUQ0hFQ0s6CiAgICAgICAgaWYgKHdQYXJhbSA+IG1heENoZWNrU3RhdGVbc3R5bGVdKSB3UGFyYW0gPSBtYXhDaGVja1N0YXRlW3N0eWxlXTsKICAgICAgICBpZiAoKGluZm9QdHItPnN0YXRlICYgMykgIT0gd1BhcmFtKQogICAgICAgIHsKCSAgICBpZiAoKHN0eWxlID09IEJTX1JBRElPQlVUVE9OKSB8fCAoc3R5bGUgPT0gQlNfQVVUT1JBRElPQlVUVE9OKSkKCSAgICB7CgkJaWYgKHdQYXJhbSkKCQkgICAgd25kUHRyLT5kd1N0eWxlIHw9IFdTX1RBQlNUT1A7CgkJZWxzZQoJCSAgICB3bmRQdHItPmR3U3R5bGUgJj0gfldTX1RBQlNUT1A7CgkgICAgfQogICAgICAgICAgICBpbmZvUHRyLT5zdGF0ZSA9IChpbmZvUHRyLT5zdGF0ZSAmIH4zKSB8IHdQYXJhbTsKICAgICAgICAgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfU0VMRUNUICk7CiAgICAgICAgfQogICAgICAgIGlmICgoc3R5bGUgPT0gQlNfQVVUT1JBRElPQlVUVE9OKSAmJiAod1BhcmFtID09IEJVVFRPTl9DSEVDS0VEKSkKICAgICAgICAgICAgQlVUVE9OX0NoZWNrQXV0b1JhZGlvQnV0dG9uKCB3bmRQdHIgKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIEJNX0dFVFNUQVRFMTY6CiAgICBjYXNlIEJNX0dFVFNUQVRFOgogICAgICAgIHJldHVybiBpbmZvUHRyLT5zdGF0ZTsKCiAgICBjYXNlIEJNX1NFVFNUQVRFMTY6CiAgICBjYXNlIEJNX1NFVFNUQVRFOgogICAgICAgIGlmICh3UGFyYW0pCiAgICAgICAgewogICAgICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpIGJyZWFrOwogICAgICAgICAgICBpbmZvUHRyLT5zdGF0ZSB8PSBCVVRUT05fSElHSExJR0hURUQ7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmICghKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSkgYnJlYWs7CiAgICAgICAgICAgIGluZm9QdHItPnN0YXRlICY9IH5CVVRUT05fSElHSExJR0hURUQ7CiAgICAgICAgfQogICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX1NFTEVDVCApOwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIERlZldpbmRvd1Byb2NBKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKICAgIH0KICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEJ1dHRvblduZFByb2MKICogVGhlIGJ1dHRvbiB3aW5kb3cgcHJvY2VkdXJlLiBUaGlzIGlzIGp1c3QgYSB3cmFwcGVyIHdoaWNoIGxvY2tzCiAqIHRoZSBwYXNzZWQgSFdORCBhbmQgY2FsbHMgdGhlIHJlYWwgd2luZG93IHByb2NlZHVyZSAod2l0aCBhIFdORCoKICogcG9pbnRlciBwb2ludGluZyB0byB0aGUgbG9ja2VkIHdpbmRvd3N0cnVjdHVyZSkuCiAqLwpMUkVTVUxUIFdJTkFQSSBCdXR0b25XbmRQcm9jKCBIV05EIGhXbmQsIFVJTlQgdU1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSApCnsKICAgIExSRVNVTFQgcmVzOwogICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0cihoV25kKTsKCiAgICByZXMgPSBCdXR0b25XbmRQcm9jX2xvY2tlZCh3bmRQdHIsdU1zZyx3UGFyYW0sbFBhcmFtKTsKCiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuIHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgUHVzaCBCdXR0b24gRnVuY3Rpb25zCiAqLwpzdGF0aWMgdm9pZCBQQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICkKewogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciAgICAgID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKICAgIEJPT0wgICAgICAgIGJIaWdoTGlnaHRlZCA9IChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCk7CgogICAgLyogCiAgICAgKiBEZWxlZ2F0ZSB0aGlzIHRvIHRoZSBtb3JlIGdlbmVyaWMgcHVzaGJ1dHRvbiBwYWludGluZwogICAgICogbWV0aG9kLgogICAgICovCiAgICBCVVRUT05fRHJhd1B1c2hCdXR0b24od25kUHRyLAoJCQkgIGhEQywKCQkJICBhY3Rpb24sCgkJCSAgYkhpZ2hMaWdodGVkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhpcyBtZXRob2Qgd2lsbCBhY3R1YWxseSBkbyB0aGUgZHJhd2luZyBvZiB0aGUgcHVzaGJ1dHRvbiAKICogZGVwZW5kaW5nIG9uIGl0J3Mgc3RhdGUgYW5kIHRoZSBwdXNoZWRTdGF0ZSBwYXJhbWV0ZXIuCiAqLwpzdGF0aWMgdm9pZCBCVVRUT05fRHJhd1B1c2hCdXR0b24oCiAgV05EKiB3bmRQdHIsCiAgSERDICBoREMsIAogIFdPUkQgYWN0aW9uLCAKICBCT09MIHB1c2hlZFN0YXRlICkKewogICAgUkVDVCByYywgZm9jdXNfcmVjdDsKICAgIEhQRU4gaE9sZFBlbjsKICAgIEhCUlVTSCBoT2xkQnJ1c2g7CiAgICBCVVRUT05JTkZPICppbmZvUHRyID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKICAgIGludCB4Qm9yZGVyT2Zmc2V0LCB5Qm9yZGVyT2Zmc2V0OwogICAgeEJvcmRlck9mZnNldCA9IHlCb3JkZXJPZmZzZXQgPSAwOwoKICAgIEdldENsaWVudFJlY3QoIHduZFB0ci0+aHduZFNlbGYsICZyYyApOwoKICAgICAgLyogU2VuZCBXTV9DVExDT0xPUiB0byBhbGxvdyBjaGFuZ2luZyB0aGUgZm9udCAodGhlIGNvbG9ycyBhcmUgZml4ZWQpICovCiAgICBpZiAoaW5mb1B0ci0+aEZvbnQpIFNlbGVjdE9iamVjdCggaERDLCBpbmZvUHRyLT5oRm9udCApOwogICAgQlVUVE9OX1NFTkRfQ1RMQ09MT1IoIHduZFB0ciwgaERDICk7CiAgICBoT2xkUGVuID0gKEhQRU4pU2VsZWN0T2JqZWN0KGhEQywgR2V0U3lzQ29sb3JQZW4oQ09MT1JfV0lORE9XRlJBTUUpKTsKICAgIGhPbGRCcnVzaCA9KEhCUlVTSClTZWxlY3RPYmplY3QoaERDLEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfQlRORkFDRSkpOwogICAgU2V0QmtNb2RlKGhEQywgVFJBTlNQQVJFTlQpOwoKICAgIGlmICggVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKICAgIHsKICAgICAgICBSZWN0YW5nbGUoaERDLCByYy5sZWZ0LCByYy50b3AsIHJjLnJpZ2h0LCByYy5ib3R0b20pOwoKICAgICAgICBTZXRQaXhlbCggaERDLCByYy5sZWZ0LCByYy50b3AsIEdldFN5c0NvbG9yKENPTE9SX1dJTkRPVykgKTsKICAgICAgICBTZXRQaXhlbCggaERDLCByYy5sZWZ0LCByYy5ib3R0b20tMSwgR2V0U3lzQ29sb3IoQ09MT1JfV0lORE9XKSApOwogICAgICAgIFNldFBpeGVsKCBoREMsIHJjLnJpZ2h0LTEsIHJjLnRvcCwgR2V0U3lzQ29sb3IoQ09MT1JfV0lORE9XKSApOwogICAgICAgIFNldFBpeGVsKCBoREMsIHJjLnJpZ2h0LTEsIHJjLmJvdHRvbS0xLCBHZXRTeXNDb2xvcihDT0xPUl9XSU5ET1cpKTsKCUluZmxhdGVSZWN0KCAmcmMsIC0xLCAtMSApOwogICAgfQogICAgCiAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MDAwZikgPT0gQlNfREVGUFVTSEJVVFRPTikKICAgIHsKICAgICAgICBSZWN0YW5nbGUoaERDLCByYy5sZWZ0LCByYy50b3AsIHJjLnJpZ2h0LCByYy5ib3R0b20pOwoJSW5mbGF0ZVJlY3QoICZyYywgLTEsIC0xICk7CiAgICB9CgogICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCiAgICB7CiAgICAgICAgaWYgKHB1c2hlZFN0YXRlKQoJewoJICAgIC8qIGRyYXcgYnV0dG9uIHNoYWRvdzogKi8KCSAgICBTZWxlY3RPYmplY3QoaERDLCBHZXRTeXNDb2xvckJydXNoKENPTE9SX0JUTlNIQURPVykpOwoJICAgIFBhdEJsdChoREMsIHJjLmxlZnQsIHJjLnRvcCwgMSwgcmMuYm90dG9tLXJjLnRvcCwgUEFUQ09QWSApOwoJICAgIFBhdEJsdChoREMsIHJjLmxlZnQsIHJjLnRvcCwgcmMucmlnaHQtcmMubGVmdCwgMSwgUEFUQ09QWSApOwoJICAgIHJjLmxlZnQgKz0gMjsgIC8qIFRvIHBvc2l0aW9uIHRoZSB0ZXh0IGRvd24gYW5kIHJpZ2h0ICovCgkgICAgcmMudG9wICArPSAyOwoJfSBlbHNlIHsKCSAgIHJjLnJpZ2h0KyssIHJjLmJvdHRvbSsrOwoJICAgRHJhd0VkZ2UoIGhEQywgJnJjLCBFREdFX1JBSVNFRCwgQkZfUkVDVCApOwoKCSAgIC8qIFRvIHBsYWNlIGRlIGJpdG1hcCBjb3JyZWN0bHkgKi8KCSAgIHhCb3JkZXJPZmZzZXQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWEVER0UpOwoJICAgeUJvcmRlck9mZnNldCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSk7CgoJICAgcmMucmlnaHQtLSwgcmMuYm90dG9tLS07Cgl9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgVUlOVCB1U3RhdGUgPSBERkNTX0JVVFRPTlBVU0g7CgogICAgICAgIGlmIChwdXNoZWRTdGF0ZSkKCXsKCSAgICBpZiAoICh3bmRQdHItPmR3U3R5bGUgJiAweDAwMGYpID09IEJTX0RFRlBVU0hCVVRUT04gKQoJICAgICAgICB1U3RhdGUgfD0gREZDU19GTEFUOwoJICAgIGVsc2UKCSAgICAgICAgdVN0YXRlIHw9IERGQ1NfUFVTSEVEOwoJfQoKCURyYXdGcmFtZUNvbnRyb2woIGhEQywgJnJjLCBERkNfQlVUVE9OLCB1U3RhdGUgKTsKCUluZmxhdGVSZWN0KCAmcmMsIC0yLCAtMiApOwoKCWZvY3VzX3JlY3QgPSByYzsKCiAgICAgICAgaWYgKHB1c2hlZFN0YXRlKQoJewoJICAgIHJjLmxlZnQgKz0gMjsgIC8qIFRvIHBvc2l0aW9uIHRoZSB0ZXh0IGRvd24gYW5kIHJpZ2h0ICovCgkgICAgcmMudG9wICArPSAyOwoJfQogICAgfQoKICAgIC8qIGRyYXcgYnV0dG9uIGxhYmVsLCBpZiBhbnk6CiAgICAgKgogICAgICogSW4gd2luOXggd2UgZG9uJ3Qgc2hvdyB0ZXh0IGlmIHRoZXJlIGlzIGEgYml0bWFwIG9yIGljb24uCiAgICAgKiBJIGRvbid0IGtub3cgYWJvdXQgd2luMzEgc28gSSBsZWF2ZSBpdCBhcyBpdCB3YXMgZm9yIHdpbjMxLgogICAgICogRGVubmlzIEJq9nJrbHVuZCAxMiBKdWwsIDk5CiAgICAgKi8KICAgIGlmICggd25kUHRyLT50ZXh0ICYmIHduZFB0ci0+dGV4dFswXQoJICYmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LIHx8ICEod25kUHRyLT5kd1N0eWxlICYgKEJTX0lDT058QlNfQklUTUFQKSkpICkKICAgIHsKICAgICAgICBMT0dCUlVTSCBsYjsKICAgICAgICBHZXRPYmplY3RBKCBHZXRTeXNDb2xvckJydXNoKENPTE9SX0JUTkZBQ0UpLCBzaXplb2YobGIpLCAmbGIgKTsKICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQgJiYKICAgICAgICAgICAgR2V0U3lzQ29sb3IoQ09MT1JfR1JBWVRFWFQpPT1sYi5sYkNvbG9yKQogICAgICAgICAgICAvKiBkb24ndCB3cml0ZSBncmF5IHRleHQgb24gZ3JheSBiYWNrZ3JvdW5kICovCiAgICAgICAgICAgIFBhaW50R3JheU9uR3JheSggaERDLGluZm9QdHItPmhGb250LCZyYyx3bmRQdHItPnRleHQsCgkJCSAgICAgICBEVF9DRU5URVIgfCBEVF9WQ0VOVEVSICk7CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgU2V0VGV4dENvbG9yKCBoREMsICh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCkgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXNDb2xvcihDT0xPUl9CVE5URVhUKSApOwogICAgICAgICAgICBEcmF3VGV4dEEoIGhEQywgd25kUHRyLT50ZXh0LCAtMSwgJnJjLAogICAgICAgICAgICAgICAgICAgICAgICAgRFRfU0lOR0xFTElORSB8IERUX0NFTlRFUiB8IERUX1ZDRU5URVIgKTsKICAgICAgICAgICAgLyogZG8gd2UgaGF2ZSB0aGUgZm9jdXM/CgkgICAgICogV2luOXggZHJhd3MgZm9jdXMgbGFzdCB3aXRoIGEgc2l6ZSBwcm9wLiB0byB0aGUgYnV0dG9uCgkgICAgICovCiAgICAgICAgICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LCgkJJiYgaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJFQ1QgciA9IHsgMCwgMCwgMCwgMCB9OwogICAgICAgICAgICAgICAgSU5UIHhkZWx0YSwgeWRlbHRhOwoKICAgICAgICAgICAgICAgIERyYXdUZXh0QSggaERDLCB3bmRQdHItPnRleHQsIC0xLCAmciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9TSU5HTEVMSU5FIHwgRFRfQ0FMQ1JFQ1QgKTsKICAgICAgICAgICAgICAgIHhkZWx0YSA9ICgocmMucmlnaHQgLSByYy5sZWZ0KSAtIChyLnJpZ2h0IC0gci5sZWZ0KSAtIDEpIC8gMjsKICAgICAgICAgICAgICAgIHlkZWx0YSA9ICgocmMuYm90dG9tIC0gcmMudG9wKSAtIChyLmJvdHRvbSAtIHIudG9wKSAtIDEpIC8gMjsKICAgICAgICAgICAgICAgIGlmICh4ZGVsdGEgPCAwKSB4ZGVsdGEgPSAwOwogICAgICAgICAgICAgICAgaWYgKHlkZWx0YSA8IDApIHlkZWx0YSA9IDA7CiAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCggJnJjLCAteGRlbHRhLCAteWRlbHRhICk7CiAgICAgICAgICAgICAgICBEcmF3Rm9jdXNSZWN0KCBoREMsICZyYyApOwogICAgICAgICAgICB9CiAgICAgICAgfSAgIAogICAgfQogICAgaWYgKCAoKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0lDT04pIHx8ICh3bmRQdHItPmR3U3R5bGUgJiBCU19CSVRNQVApICkgJiYKCSAoaW5mb1B0ci0+aEltYWdlICE9IDApICkKICAgIHsKCWludCB5T2Zmc2V0LCB4T2Zmc2V0OwoJaW50IGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0OwoKCS8qCgkgKiBXZSBleHRyYWN0IHRoZSBzaXplIG9mIHRoZSBpbWFnZSBmcm9tIHRoZSBoYW5kbGUuCgkgKi8KCWlmICh3bmRQdHItPmR3U3R5bGUgJiBCU19JQ09OKQoJewoJICAgIElDT05JTkZPIGljb25JbmZvOwoJICAgIEJJVE1BUCAgIGJtOwoKCSAgICBHZXRJY29uSW5mbygoSElDT04paW5mb1B0ci0+aEltYWdlLCAmaWNvbkluZm8pOwoJICAgIEdldE9iamVjdEEgKGljb25JbmZvLmhibUNvbG9yLCBzaXplb2YoQklUTUFQKSwgJmJtKTsKCSAgICAKCSAgICBpbWFnZVdpZHRoICA9IGJtLmJtV2lkdGg7CgkgICAgaW1hZ2VIZWlnaHQgPSBibS5ibUhlaWdodDsKCiAgICAgICAgICAgIERlbGV0ZU9iamVjdChpY29uSW5mby5oYm1Db2xvcik7CiAgICAgICAgICAgIERlbGV0ZU9iamVjdChpY29uSW5mby5oYm1NYXNrKTsKCgl9CgllbHNlCgl7CgkgICAgQklUTUFQICAgYm07CgoJICAgIEdldE9iamVjdEEgKGluZm9QdHItPmhJbWFnZSwgc2l6ZW9mKEJJVE1BUCksICZibSk7CgkKCSAgICBpbWFnZVdpZHRoICA9IGJtLmJtV2lkdGg7CgkgICAgaW1hZ2VIZWlnaHQgPSBibS5ibUhlaWdodDsKCX0KCgkvKiBDZW50ZXIgdGhlIGJpdG1hcCAqLwoJeE9mZnNldCA9ICgoKHJjLnJpZ2h0IC0gcmMubGVmdCkgLSAyKnhCb3JkZXJPZmZzZXQpIC0gaW1hZ2VXaWR0aCApIC8gMjsKCXlPZmZzZXQgPSAoKChyYy5ib3R0b20gLSByYy50b3ApIC0gMip5Qm9yZGVyT2Zmc2V0KSAtIGltYWdlSGVpZ2h0KSAvIDI7CgoJLyogSWYgdGhlIGltYWdlIGlzIHRvbyBiaWcgZm9yIHRoZSBidXR0b24gdGhlbiBjcmVhdGUgYSByZWdpb24qLwogICAgICAgIGlmKHhPZmZzZXQgPCAwIHx8IHlPZmZzZXQgPCAwKQoJewogICAgICAgICAgICBIUkdOIGhCaXRtYXBSZ24gPSAwOwogICAgICAgICAgICBoQml0bWFwUmduID0gQ3JlYXRlUmVjdFJnbigKICAgICAgICAgICAgICAgIHJjLmxlZnQgKyB4Qm9yZGVyT2Zmc2V0LCByYy50b3AgK3lCb3JkZXJPZmZzZXQsIAogICAgICAgICAgICAgICAgcmMucmlnaHQgLSB4Qm9yZGVyT2Zmc2V0LCByYy5ib3R0b20gLSB5Qm9yZGVyT2Zmc2V0KTsKICAgICAgICAgICAgU2VsZWN0Q2xpcFJnbihoREMsIGhCaXRtYXBSZ24pOwogICAgICAgICAgICBEZWxldGVPYmplY3QoaEJpdG1hcFJnbik7Cgl9CgoJLyogTGV0IG1pbmltdW0gMSBzcGFjZSBmcm9tIGJvcmRlciAqLwoJeE9mZnNldCsrLCB5T2Zmc2V0Kys7CgoJLyoKCSAqIERyYXcgdGhlIGltYWdlIG5vdy4KCSAqLwoJaWYgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0lDT04pCgl7CiAgCSAgICBEcmF3SWNvbihoREMsCiAgICAgICAgICAgICAgICByYy5sZWZ0ICsgeE9mZnNldCwgcmMudG9wICsgeU9mZnNldCwKCQkgICAgIChISUNPTilpbmZvUHRyLT5oSW1hZ2UpOwoJfQoJZWxzZQogICAgICAgIHsKCSAgICBIREMgaGRjTWVtOwoKCSAgICBoZGNNZW0gPSBDcmVhdGVDb21wYXRpYmxlREMgKGhEQyk7CgkgICAgU2VsZWN0T2JqZWN0IChoZGNNZW0sIChIQklUTUFQKWluZm9QdHItPmhJbWFnZSk7CgkgICAgQml0Qmx0KGhEQywgCgkJICAgcmMubGVmdCArIHhPZmZzZXQsIAoJCSAgIHJjLnRvcCArIHlPZmZzZXQsIAoJCSAgIGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0LAoJCSAgIGhkY01lbSwgMCwgMCwgU1JDQ09QWSk7CgkgICAgCgkgICAgRGVsZXRlREMgKGhkY01lbSk7Cgl9CgogICAgICAgIGlmKHhPZmZzZXQgPCAwIHx8IHlPZmZzZXQgPCAwKQogICAgICAgIHsKICAgICAgICAgICAgU2VsZWN0Q2xpcFJnbihoREMsIDApOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoVFdFQUtfV2luZUxvb2sgIT0gV0lOMzFfTE9PSwoJJiYgaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpCiAgICB7CiAgICAgICAgSW5mbGF0ZVJlY3QoICZmb2N1c19yZWN0LCAtMSwgLTEgKTsKICAgICAgICBEcmF3Rm9jdXNSZWN0KCBoREMsICZmb2N1c19yZWN0ICk7CiAgICB9CgogICAgCiAgICBTZWxlY3RPYmplY3QoIGhEQywgaE9sZFBlbiApOwogICAgU2VsZWN0T2JqZWN0KCBoREMsIGhPbGRCcnVzaCApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICBQQl9QYWludCAmIENCX1BhaW50IHN1YiBmdW5jdGlvbiAgICAgICAgICAgICAgICAgICAgICAgIFtpbnRlcm5hbF0KICogICBQYWludCB0ZXh0IHVzaW5nIGEgcmFzdGVyIGJydXNoIHRvIGF2b2lkIGdyYXkgdGV4dCBvbiBncmF5IAogKiAgIGJhY2tncm91bmQuICdmb3JtYXQnIGNhbiBiZSBhIGNvbWJpbmF0aW9uIG9mIERUX0NFTlRFUiBhbmQgCiAqICAgRFRfVkNFTlRFUiB0byB1c2UgdGhpcyBmdW5jdGlvbiBpbiBib3RoIFBCX1BBSU5UIGFuZCAKICogICBDQl9QQUlOVC4gICAtIERpcmsgVGhpZXJiYWNoCiAqCiAqICAgRklYTUU6IFRoaXMgYW5kIFRFWFRfR3JheVN0cmluZyBzaG91bGQgYmUgZXZlbnR1YWxseSBjb21iaW5lZCwKICogICBzbyBjYWxsaW5nIG9uZSBjb21tb24gZnVuY3Rpb24gZnJvbSBQQl9QYWludCwgQ0JfUGFpbnQgYW5kCiAqICAgVEVYVF9HcmF5U3RyaW5nIHdpbGwgYmUgZW5vdWdoLiBBbHNvIG5vdGUgdGhhdCB0aGlzCiAqICAgZnVuY3Rpb24gaWdub3JlcyB0aGUgQ0FDSEVfR2V0UGF0dGVybiBmdW5jcy4KICovCgp2b2lkIFBhaW50R3JheU9uR3JheShIREMgaERDLEhGT05UIGhGb250LFJFQ1QgKnJjLGNoYXIgKnRleHQsCgkJCVVJTlQgZm9ybWF0KQp7Ci8qICBUaGlzIGlzIHRoZSBzdGFuZGFyZCBncmF5IG9uIGdyYXkgcGF0dGVybjoKICAgIHN0YXRpYyBjb25zdCBXT1JEIFBhdHRlcm5bXSA9IHsweEFBLDB4NTUsMHhBQSwweDU1LDB4QUEsMHg1NSwweEFBLDB4NTV9OyAKKi8KLyogIFRoaXMgcGF0dGVybiBnaXZlcyBiZXR0ZXIgcmVhZGFiaWxpdHkgd2l0aCBYIEZvbnRzLgogICAgRklYTUU6IE1heWJlIHRoZSB1c2VyIHNob3VsZCBiZSBhbGxvd2VkIHRvIGRlY2lkZSB3aGljaCBoZSB3YW50cy4gKi8KICAgIHN0YXRpYyBjb25zdCBXT1JEIFBhdHRlcm5bXSA9IHsweDU1LDB4RkYsMHhBQSwweEZGLDB4NTUsMHhGRiwweEFBLDB4RkZ9OyAKCiAgICBIQklUTUFQIGhibSAgPSBDcmVhdGVCaXRtYXAoIDgsIDgsIDEsIDEsIFBhdHRlcm4gKTsKICAgIEhEQyBoZGNNZW0gPSBDcmVhdGVDb21wYXRpYmxlREMoaERDKTsKICAgIEhCSVRNQVAgaGJtTWVtOwogICAgSEJSVVNIIGhCcjsKICAgIFJFQ1QgcmVjdCxyYzI7CgogICAgcmVjdD0qcmM7CiAgICBEcmF3VGV4dEEoIGhEQywgdGV4dCwgLTEsICZyZWN0LCBEVF9TSU5HTEVMSU5FIHwgRFRfQ0FMQ1JFQ1QpOwogICAgLyogbm93IHRleHQgd2lkdGggYW5kIGhlaWdodCBhcmUgaW4gcmVjdC5yaWdodCBhbmQgcmVjdC5ib3R0b20gKi8KICAgIHJjMj1yZWN0OwogICAgcmVjdC5sZWZ0ID0gcmVjdC50b3AgPSAwOyAvKiBkcmF3aW5nIHBvcyBpbiBoZGNNZW0gKi8KICAgIGlmIChmb3JtYXQgJiBEVF9DRU5URVIpIHJlY3QubGVmdD0ocmMtPnJpZ2h0LXJlY3QucmlnaHQpLzI7CiAgICBpZiAoZm9ybWF0ICYgRFRfVkNFTlRFUikgcmVjdC50b3A9KHJjLT5ib3R0b20tcmVjdC5ib3R0b20pLzI7CiAgICBoYm1NZW0gPSBDcmVhdGVDb21wYXRpYmxlQml0bWFwKCBoREMscmVjdC5yaWdodCxyZWN0LmJvdHRvbSApOwogICAgU2VsZWN0T2JqZWN0KCBoZGNNZW0sIGhibU1lbSk7CiAgICBQYXRCbHQoIGhkY01lbSwwLDAscmVjdC5yaWdodCxyZWN0LmJvdHRvbSxXSElURU5FU1MpOwogICAgICAvKiB3aWxsIGJlIG92ZXJ3cml0dGVuIGJ5IERyYXdUZXh0LCBidXQganVzdCBpbiBjYXNlICovCiAgICBpZiAoaEZvbnQpIFNlbGVjdE9iamVjdCggaGRjTWVtLCBoRm9udCk7CiAgICBEcmF3VGV4dEEoIGhkY01lbSwgdGV4dCwgLTEsICZyYzIsIERUX1NJTkdMRUxJTkUpOyAgCiAgICAgIC8qIEFmdGVyIGRyYXc6IGZvcmVncm91bmQgPSAwIGJpdHMsIGJhY2tncm91bmQgPSAxIGJpdHMgKi8KICAgIGhCciA9IFNlbGVjdE9iamVjdCggaGRjTWVtLCBDcmVhdGVQYXR0ZXJuQnJ1c2goaGJtKSApOwogICAgRGVsZXRlT2JqZWN0KCBoYm0gKTsKICAgIFBhdEJsdCggaGRjTWVtLDAsMCxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tLDB4QUYwMjI5KTsgCiAgICAgIC8qIG9ubHkga2VlcCB0aGUgZm9yZWdyb3VuZCBiaXRzIHdoZXJlIHBhdHRlcm4gaXMgMSAqLwogICAgRGVsZXRlT2JqZWN0KCBTZWxlY3RPYmplY3QoIGhkY01lbSxoQnIpICk7CiAgICBCaXRCbHQoaERDLHJlY3QubGVmdCxyZWN0LnRvcCxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tLGhkY01lbSwwLDAsU1JDQU5EKTsKICAgICAgLyoga2VlcCB0aGUgYmFja2dyb3VuZCBvZiB0aGUgZGVzdCAqLwogICAgRGVsZXRlREMoIGhkY01lbSk7CiAgICBEZWxldGVPYmplY3QoIGhibU1lbSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgQ2hlY2sgQm94ICYgUmFkaW8gQnV0dG9uIEZ1bmN0aW9ucwogKi8KCnN0YXRpYyB2b2lkIENCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKQp7CiAgICBSRUNUIHJib3gsIHJ0ZXh0LCBjbGllbnQ7CiAgICBIQlJVU0ggaEJydXNoOwogICAgaW50IHRleHRsZW4sIGRlbHRhOwogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CgogICAgLyogCiAgICAgKiBpZiB0aGUgYnV0dG9uIGhhcyBhIGJpdG1hcC9pY29uLCBkcmF3IGEgbm9ybWFsIHB1c2hidXR0b24KICAgICAqIGluc3RlYWQgb2YgYSByYWRpb24gYnV0dG9uLgogICAgICovCiAgICBpZiAoaW5mb1B0ci0+aEltYWdlICE9IDApCiAgICB7CiAgICAgICAgQk9PTCBiSGlnaExpZ2h0ZWQgPSAoKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSB8fAoJCQkgICAgIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9DSEVDS0VEKSk7CgogICAgICAgIEJVVFRPTl9EcmF3UHVzaEJ1dHRvbih3bmRQdHIsCgkJCSAgICAgIGhEQywKCQkJICAgICAgYWN0aW9uLAoJCQkgICAgICBiSGlnaExpZ2h0ZWQpOwoJcmV0dXJuOwogICAgfQoKICAgIHRleHRsZW4gPSAwOwogICAgR2V0Q2xpZW50UmVjdCh3bmRQdHItPmh3bmRTZWxmLCAmY2xpZW50KTsKICAgIHJib3ggPSBydGV4dCA9IGNsaWVudDsKCiAgICBpZiAoaW5mb1B0ci0+aEZvbnQpIFNlbGVjdE9iamVjdCggaERDLCBpbmZvUHRyLT5oRm9udCApOwoKICAgIC8qIFNvbWV0aGluZyBpcyBzdGlsbCBub3QgcmlnaHQsIGNoZWNrYm94ZXMgKGFuZCBlZGl0IGNvbnRyb2xzKQogICAgICogaW4gd3NwaW5nMzIgaGF2ZSB3aGl0ZSBiYWNrZ3JvdW5kcyBpbnN0ZWFkIG9mIGRhcmsgZ3JleS4KICAgICAqIEJVVFRPTl9TRU5EX0NUTENPTE9SKCkgaXMgZXZlbiB3b3JzZSBzaW5jZSBpdCByZXR1cm5zIDAgaW4gdGhpcwogICAgICogcGFydGljdWxhciBjYXNlIGFuZCB0aGUgYmFja2dyb3VuZCBpcyBub3QgcGFpbnRlZCBhdCBhbGwuCiAgICAgKi8KCiAgICBoQnJ1c2ggPSBHZXRDb250cm9sQnJ1c2gxNiggd25kUHRyLT5od25kU2VsZiwgaERDLCBDVExDT0xPUl9CVE4gKTsKCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgQlNfTEVGVFRFWFQpIAogICAgewoJLyogbWFnaWMgKzQgaXMgd2hhdCBDVEwzRCBleHBlY3RzICovCgogICAgICAgIHJ0ZXh0LnJpZ2h0IC09IGNoZWNrQm94V2lkdGggKyA0OwogICAgICAgIHJib3gubGVmdCA9IHJib3gucmlnaHQgLSBjaGVja0JveFdpZHRoOwogICAgfQogICAgZWxzZSAKICAgIHsKICAgICAgICBydGV4dC5sZWZ0ICs9IGNoZWNrQm94V2lkdGggKyA0OwogICAgICAgIHJib3gucmlnaHQgPSBjaGVja0JveFdpZHRoOwogICAgfQoKICAgICAgLyogRHJhdyB0aGUgY2hlY2stYm94IGJpdG1hcCAqLwoKICAgIGlmICh3bmRQdHItPnRleHQpIHRleHRsZW4gPSBzdHJsZW4oIHduZFB0ci0+dGV4dCApOwogICAgaWYgKGFjdGlvbiA9PSBPREFfRFJBV0VOVElSRSB8fCBhY3Rpb24gPT0gT0RBX1NFTEVDVCkKICAgIHsgCiAgICAgICAgaWYoIFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0sgKQogICAgICAgIHsKICAgICAgICBIREMgaE1lbURDID0gQ3JlYXRlQ29tcGF0aWJsZURDKCBoREMgKTsKICAgICAgICBpbnQgeCA9IDAsIHkgPSAwOwogICAgICAgIGRlbHRhID0gKHJib3guYm90dG9tIC0gcmJveC50b3AgLSBjaGVja0JveEhlaWdodCkgLyAyOwoKCS8qIENoZWNrIGluIGNhc2UgdGhlIGNsaWVudCBhcmVhIGlzIHNtYWxsZXIgdGhhbiB0aGUgY2hlY2tib3ggYml0bWFwICovCglpZiAoZGVsdGEgPCAwKSBkZWx0YSA9IDA7CgogICAgICAgIGlmIChhY3Rpb24gPT0gT0RBX1NFTEVDVCkgRmlsbFJlY3QoIGhEQywgJnJib3gsIGhCcnVzaCApOwogICAgICAgIGVsc2UgRmlsbFJlY3QoIGhEQywgJmNsaWVudCwgaEJydXNoICk7CgogICAgICAgIGlmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCkgeCArPSAyICogY2hlY2tCb3hXaWR0aDsKICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiAoQlVUVE9OX0NIRUNLRUQgfCBCVVRUT05fM1NUQVRFKSkgeCArPSBjaGVja0JveFdpZHRoOwogICAgICAgIGlmICgoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX1JBRElPQlVUVE9OKSB8fAogICAgICAgICAgICAoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX0FVVE9SQURJT0JVVFRPTikpIHkgKz0gY2hlY2tCb3hIZWlnaHQ7CiAgICAgICAgZWxzZSBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fM1NUQVRFKSB5ICs9IDIgKiBjaGVja0JveEhlaWdodDsKCgkvKiBUaGUgYml0bWFwIGZvciB0aGUgcmFkaW8gYnV0dG9uIGlzIG5vdCBhbGlnbmVkIHdpdGggdGhlCgkgKiBsZWZ0IG9mIHRoZSB3aW5kb3csIGl0IGlzIDEgcGl4ZWwgb2ZmLiAqLwogICAgICAgIGlmICgoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX1JBRElPQlVUVE9OKSB8fAogICAgICAgICAgICAoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX0FVVE9SQURJT0JVVFRPTikpCgkgIHJib3gubGVmdCArPSAxOwoKCVNlbGVjdE9iamVjdCggaE1lbURDLCBoYml0bWFwQ2hlY2tCb3hlcyApOwoJQml0Qmx0KCBoREMsIHJib3gubGVmdCwgcmJveC50b3AgKyBkZWx0YSwgY2hlY2tCb3hXaWR0aCwKCQkgIGNoZWNrQm94SGVpZ2h0LCBoTWVtREMsIHgsIHksIFNSQ0NPUFkgKTsKCURlbGV0ZURDKCBoTWVtREMgKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKCSAgICBVSU5UIHN0YXRlOwoKICAgICAgICAgICAgaWYgKCgod25kUHRyLT5kd1N0eWxlICYgMHgwZikgPT0gQlNfUkFESU9CVVRUT04pIHx8CiAgICAgICAgICAgICAgICAoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX0FVVE9SQURJT0JVVFRPTikpIHN0YXRlID0gREZDU19CVVRUT05SQURJTzsKICAgICAgICAgICAgZWxzZSBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fM1NUQVRFKSBzdGF0ZSA9IERGQ1NfQlVUVE9OM1NUQVRFOwoJICAgIGVsc2Ugc3RhdGUgPSBERkNTX0JVVFRPTkNIRUNLOwoKICAgICAgICAgICAgaWYgKGluZm9QdHItPnN0YXRlICYgKEJVVFRPTl9DSEVDS0VEIHwgQlVUVE9OXzNTVEFURSkpIHN0YXRlIHw9IERGQ1NfQ0hFQ0tFRDsKCSAgICAKCSAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpIHN0YXRlIHw9IERGQ1NfUFVTSEVEOwoKCSAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQpIHN0YXRlIHw9IERGQ1NfSU5BQ1RJVkU7CgoJICAgIERyYXdGcmFtZUNvbnRyb2woIGhEQywgJnJib3gsIERGQ19CVVRUT04sIHN0YXRlICk7CiAgICAgICAgfQoKCiAgICAgICAgaWYoIHRleHRsZW4gJiYgYWN0aW9uICE9IE9EQV9TRUxFQ1QgKQogICAgICAgIHsKCSAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEICYmCgkgICAgICBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCk9PUdldEJrQ29sb3IoaERDKSkgewogICAgICAgICAgICAvKiBkb24ndCB3cml0ZSBncmF5IHRleHQgb24gZ3JheSBiYWNrZ3JvdW5kICovCiAgICAgICAgICAgIFBhaW50R3JheU9uR3JheSggaERDLCBpbmZvUHRyLT5oRm9udCwgJnJ0ZXh0LCB3bmRQdHItPnRleHQsCgkJCSAgICAgRFRfVkNFTlRFUik7CgkgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCkKICAgICAgICAgICAgICAgIFNldFRleHRDb2xvciggaERDLCBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCkgKTsKICAgICAgICAgICAgRHJhd1RleHRBKCBoREMsIHduZFB0ci0+dGV4dCwgdGV4dGxlbiwgJnJ0ZXh0LAoJCQkgRFRfU0lOR0xFTElORSB8IERUX1ZDRU5URVIgKTsKCSAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZiAoKGFjdGlvbiA9PSBPREFfRk9DVVMpIHx8CiAgICAgICAgKChhY3Rpb24gPT0gT0RBX0RSQVdFTlRJUkUpICYmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykpKQogICAgewoJLyogYWdhaW4sIHRoaXMgaXMgd2hhdCBDVEwzRCBleHBlY3RzICovCgogICAgICAgIFNldFJlY3RFbXB0eSgmcmJveCk7CiAgICAgICAgaWYoIHRleHRsZW4gKQogICAgICAgICAgICBEcmF3VGV4dEEoIGhEQywgd25kUHRyLT50ZXh0LCB0ZXh0bGVuLCAmcmJveCwKCQkJIERUX1NJTkdMRUxJTkUgfCBEVF9DQUxDUkVDVCApOwogICAgICAgIHRleHRsZW4gPSByYm94LmJvdHRvbSAtIHJib3gudG9wOwogICAgICAgIGRlbHRhID0gKChydGV4dC5ib3R0b20gLSBydGV4dC50b3ApIC0gdGV4dGxlbikvMjsKICAgICAgICByYm94LmJvdHRvbSA9IChyYm94LnRvcCA9IHJ0ZXh0LnRvcCArIGRlbHRhIC0gMSkgKyB0ZXh0bGVuICsgMjsKICAgICAgICB0ZXh0bGVuID0gcmJveC5yaWdodCAtIHJib3gubGVmdDsKICAgICAgICByYm94LnJpZ2h0ID0gKHJib3gubGVmdCArPSAtLXJ0ZXh0LmxlZnQpICsgdGV4dGxlbiArIDI7CiAgICAgICAgSW50ZXJzZWN0UmVjdCgmcmJveCwgJnJib3gsICZydGV4dCk7CiAgICAgICAgRHJhd0ZvY3VzUmVjdCggaERDLCAmcmJveCApOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgQlVUVE9OX0NoZWNrQXV0b1JhZGlvQnV0dG9uCiAqCiAqIHduZFB0ciBpcyBjaGVja2VkLCB1bmNoZWNrIGV2ZXJ5IG90aGVyIGF1dG8gcmFkaW8gYnV0dG9uIGluIGdyb3VwCiAqLwpzdGF0aWMgdm9pZCBCVVRUT05fQ2hlY2tBdXRvUmFkaW9CdXR0b24oIFdORCAqd25kUHRyICkKewogICAgSFdORCBwYXJlbnQsIHNpYmxpbmcsIHN0YXJ0OwogICAgaWYgKCEod25kUHRyLT5kd1N0eWxlICYgV1NfQ0hJTEQpKSByZXR1cm47CiAgICBwYXJlbnQgPSB3bmRQdHItPnBhcmVudC0+aHduZFNlbGY7CiAgICAvKiBhc3N1cmUgdGhhdCBzdGFydGluZyBjb250cm9sIGlzIG5vdCBkaXNhYmxlZCBvciBpbnZpc2libGUgKi8KICAgIHN0YXJ0ID0gc2libGluZyA9IEdldE5leHREbGdHcm91cEl0ZW0oIHBhcmVudCwgd25kUHRyLT5od25kU2VsZiwgVFJVRSApOwogICAgZG8KICAgIHsKICAgICAgICBXTkQgKnRtcFduZDsKICAgICAgICBpZiAoIXNpYmxpbmcpIGJyZWFrOwogICAgICAgIHRtcFduZCA9IFdJTl9GaW5kV25kUHRyKHNpYmxpbmcpOwogICAgICAgIGlmICgod25kUHRyLT5od25kU2VsZiAhPSBzaWJsaW5nKSAmJgogICAgICAgICAgICAoKHRtcFduZC0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX0FVVE9SQURJT0JVVFRPTikpCiAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggc2libGluZywgQk1fU0VUQ0hFQ0ssIEJVVFRPTl9VTkNIRUNLRUQsIDAgKTsKICAgICAgICBzaWJsaW5nID0gR2V0TmV4dERsZ0dyb3VwSXRlbSggcGFyZW50LCBzaWJsaW5nLCBGQUxTRSApOwogICAgICAgIFdJTl9SZWxlYXNlV25kUHRyKHRtcFduZCk7CiAgICB9IHdoaWxlIChzaWJsaW5nICE9IHN0YXJ0KTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIEdyb3VwIEJveCBGdW5jdGlvbnMKICovCgpzdGF0aWMgdm9pZCBHQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICkKewogICAgUkVDVCByYywgcmNGcmFtZTsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwoKICAgIGlmIChhY3Rpb24gIT0gT0RBX0RSQVdFTlRJUkUpIHJldHVybjsKCiAgICBCVVRUT05fU0VORF9DVExDT0xPUiggd25kUHRyLCBoREMgKTsKCiAgICBHZXRDbGllbnRSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmcmMpOwogICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spIHsKICAgICAgICBIUEVOIGhQcmV2UGVuID0gU2VsZWN0T2JqZWN0KCBoREMsCgkJCQkJICBHZXRTeXNDb2xvclBlbihDT0xPUl9XSU5ET1dGUkFNRSkpOwoJSEJSVVNIIGhQcmV2QnJ1c2ggPSBTZWxlY3RPYmplY3QoIGhEQywKCQkJCQkgICAgICBHZXRTdG9ja09iamVjdChOVUxMX0JSVVNIKSApOwoKCVJlY3RhbmdsZSggaERDLCByYy5sZWZ0LCByYy50b3AgKyAyLCByYy5yaWdodCAtIDEsIHJjLmJvdHRvbSAtIDEgKTsKCVNlbGVjdE9iamVjdCggaERDLCBoUHJldkJydXNoICk7CglTZWxlY3RPYmplY3QoIGhEQywgaFByZXZQZW4gKTsKICAgIH0gZWxzZSB7CglURVhUTUVUUklDQSB0bTsKCXJjRnJhbWUgPSByYzsKCglpZiAoaW5mb1B0ci0+aEZvbnQpCgkgICAgU2VsZWN0T2JqZWN0IChoREMsIGluZm9QdHItPmhGb250KTsKCUdldFRleHRNZXRyaWNzQSAoaERDLCAmdG0pOwoJcmNGcmFtZS50b3AgKz0gKHRtLnRtSGVpZ2h0IC8gMikgLSAxOwoJRHJhd0VkZ2UgKGhEQywgJnJjRnJhbWUsIEVER0VfRVRDSEVELCBCRl9SRUNUKTsKICAgIH0KCiAgICBpZiAod25kUHRyLT50ZXh0KQogICAgewoJaWYgKGluZm9QdHItPmhGb250KSBTZWxlY3RPYmplY3QoIGhEQywgaW5mb1B0ci0+aEZvbnQgKTsKICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQpCiAgICAgICAgICAgIFNldFRleHRDb2xvciggaERDLCBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCkgKTsKICAgICAgICByYy5sZWZ0ICs9IDEwOwogICAgICAgIERyYXdUZXh0QSggaERDLCB3bmRQdHItPnRleHQsIC0xLCAmcmMsIERUX1NJTkdMRUxJTkUgfCBEVF9OT0NMSVAgKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIFVzZXIgQnV0dG9uIEZ1bmN0aW9ucwogKi8KCnN0YXRpYyB2b2lkIFVCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKQp7CiAgICBSRUNUIHJjOwogICAgSEJSVVNIIGhCcnVzaDsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwoKICAgIGlmIChhY3Rpb24gPT0gT0RBX1NFTEVDVCkgcmV0dXJuOwoKICAgIEdldENsaWVudFJlY3QoIHduZFB0ci0+aHduZFNlbGYsICZyYyk7CgogICAgaWYgKGluZm9QdHItPmhGb250KSBTZWxlY3RPYmplY3QoIGhEQywgaW5mb1B0ci0+aEZvbnQgKTsKICAgIGhCcnVzaCA9IEdldENvbnRyb2xCcnVzaDE2KCB3bmRQdHItPmh3bmRTZWxmLCBoREMsIENUTENPTE9SX0JUTiApOwoKICAgIEZpbGxSZWN0KCBoREMsICZyYywgaEJydXNoICk7CiAgICBpZiAoKGFjdGlvbiA9PSBPREFfRk9DVVMpIHx8CiAgICAgICAgKChhY3Rpb24gPT0gT0RBX0RSQVdFTlRJUkUpICYmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykpKQogICAgICAgIERyYXdGb2N1c1JlY3QoIGhEQywgJnJjICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICBPd25lcmRyYXduIEJ1dHRvbiBGdW5jdGlvbnMKICovCgpzdGF0aWMgdm9pZCBPQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICkKewogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CiAgICBEUkFXSVRFTVNUUlVDVCBkaXM7CgogICAgZGlzLkN0bFR5cGUgICAgPSBPRFRfQlVUVE9OOwogICAgZGlzLkN0bElEICAgICAgPSB3bmRQdHItPndJRG1lbnU7CiAgICBkaXMuaXRlbUlEICAgICA9IDA7CiAgICBkaXMuaXRlbUFjdGlvbiA9IGFjdGlvbjsKICAgIGRpcy5pdGVtU3RhdGUgID0gKChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykgPyBPRFNfRk9DVVMgOiAwKSB8CiAgICAgICAgICAgICAgICAgICAgICgoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpID8gT0RTX1NFTEVDVEVEIDogMCkgfAogICAgICAgICAgICAgICAgICAgICAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEKSA/IE9EU19ESVNBQkxFRCA6IDApOwogICAgZGlzLmh3bmRJdGVtICAgPSB3bmRQdHItPmh3bmRTZWxmOwogICAgZGlzLmhEQyAgICAgICAgPSBoREM7CiAgICBkaXMuaXRlbURhdGEgICA9IDA7CiAgICBHZXRDbGllbnRSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmZGlzLnJjSXRlbSApOwoKICAgIFNldEJrQ29sb3IoIGhEQywgR2V0U3lzQ29sb3IoIENPTE9SX0JUTkZBQ0UgKSApOwoKICAgIFNlbmRNZXNzYWdlQSggR2V0UGFyZW50KHduZFB0ci0+aHduZFNlbGYpLCBXTV9EUkFXSVRFTSwKICAgICAgICAgICAgICAgICAgICB3bmRQdHItPndJRG1lbnUsIChMUEFSQU0pJmRpcyApOwp9Cgo=