LyogRmlsZTogYnV0dG9uLmMgLS0gQnV0dG9uIHR5cGUgd2lkZ2V0cwogKgogKiBDb3B5cmlnaHQgKEMpIDE5OTMgSm9oYW5uZXMgUnVzY2hlaW5za2kKICogQ29weXJpZ2h0IChDKSAxOTkzIERhdmlkIE1ldGNhbGZlCiAqIENvcHlyaWdodCAoQykgMTk5NCBBbGV4YW5kcmUgSnVsbGlhcmQKICovCgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJ3aW4uaCIKI2luY2x1ZGUgImJ1dHRvbi5oIgojaW5jbHVkZSAid2luZS93aW51c2VyMTYuaCIKI2luY2x1ZGUgInR3ZWFrLmgiCgpzdGF0aWMgdm9pZCBQYWludEdyYXlPbkdyYXkoIEhEQyBoREMsSEZPTlQgaEZvbnQsUkVDVCAqcmMsCgkJCSAgICAgY2hhciAqdGV4dCwgVUlOVCBmb3JtYXQgKTsKCnN0YXRpYyB2b2lkIFBCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKTsKc3RhdGljIHZvaWQgQ0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApOwpzdGF0aWMgdm9pZCBHQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICk7CnN0YXRpYyB2b2lkIFVCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKTsKc3RhdGljIHZvaWQgT0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApOwpzdGF0aWMgdm9pZCBCVVRUT05fQ2hlY2tBdXRvUmFkaW9CdXR0b24oIFdORCAqd25kUHRyICk7CnN0YXRpYyB2b2lkIEJVVFRPTl9EcmF3UHVzaEJ1dHRvbiggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uLCBCT09MIHB1c2hlZFN0YXRlKTsKCiNkZWZpbmUgTUFYX0JUTl9UWVBFICAxMgoKc3RhdGljIGNvbnN0IFdPUkQgbWF4Q2hlY2tTdGF0ZVtNQVhfQlROX1RZUEVdID0KewogICAgQlVUVE9OX1VOQ0hFQ0tFRCwgICAvKiBCU19QVVNIQlVUVE9OICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIEJTX0RFRlBVU0hCVVRUT04gKi8KICAgIEJVVFRPTl9DSEVDS0VELCAgICAgLyogQlNfQ0hFQ0tCT1ggKi8KICAgIEJVVFRPTl9DSEVDS0VELCAgICAgLyogQlNfQVVUT0NIRUNLQk9YICovCiAgICBCVVRUT05fQ0hFQ0tFRCwgICAgIC8qIEJTX1JBRElPQlVUVE9OICovCiAgICBCVVRUT05fM1NUQVRFLCAgICAgIC8qIEJTXzNTVEFURSAqLwogICAgQlVUVE9OXzNTVEFURSwgICAgICAvKiBCU19BVVRPM1NUQVRFICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIEJTX0dST1VQQk9YICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIEJTX1VTRVJCVVRUT04gKi8KICAgIEJVVFRPTl9DSEVDS0VELCAgICAgLyogQlNfQVVUT1JBRElPQlVUVE9OICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIE5vdCBkZWZpbmVkICovCiAgICBCVVRUT05fVU5DSEVDS0VEICAgIC8qIEJTX09XTkVSRFJBVyAqLwp9OwoKdHlwZWRlZiB2b2lkICgqcGZQYWludCkoIFdORCAqd25kUHRyLCBIREMgaGRjLCBXT1JEIGFjdGlvbiApOwoKc3RhdGljIGNvbnN0IHBmUGFpbnQgYnRuUGFpbnRGdW5jW01BWF9CVE5fVFlQRV0gPQp7CiAgICBQQl9QYWludCwgICAgLyogQlNfUFVTSEJVVFRPTiAqLwogICAgUEJfUGFpbnQsICAgIC8qIEJTX0RFRlBVU0hCVVRUT04gKi8KICAgIENCX1BhaW50LCAgICAvKiBCU19DSEVDS0JPWCAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX0FVVE9DSEVDS0JPWCAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX1JBRElPQlVUVE9OICovCiAgICBDQl9QYWludCwgICAgLyogQlNfM1NUQVRFICovCiAgICBDQl9QYWludCwgICAgLyogQlNfQVVUTzNTVEFURSAqLwogICAgR0JfUGFpbnQsICAgIC8qIEJTX0dST1VQQk9YICovCiAgICBVQl9QYWludCwgICAgLyogQlNfVVNFUkJVVFRPTiAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX0FVVE9SQURJT0JVVFRPTiAqLwogICAgTlVMTCwgICAgICAgIC8qIE5vdCBkZWZpbmVkICovCiAgICBPQl9QYWludCAgICAgLyogQlNfT1dORVJEUkFXICovCn07CgojZGVmaW5lIFBBSU5UX0JVVFRPTih3bmRQdHIsc3R5bGUsYWN0aW9uKSBcCiAgICAgaWYgKGJ0blBhaW50RnVuY1tzdHlsZV0pIHsgXAogICAgICAgICBIREMgaGRjID0gR2V0REMoICh3bmRQdHIpLT5od25kU2VsZiApOyBcCiAgICAgICAgIChidG5QYWludEZ1bmNbc3R5bGVdKSh3bmRQdHIsaGRjLGFjdGlvbik7IFwKICAgICAgICAgUmVsZWFzZURDKCAod25kUHRyKS0+aHduZFNlbGYsIGhkYyApOyB9CgojZGVmaW5lIEJVVFRPTl9TRU5EX0NUTENPTE9SKHduZFB0cixoZGMpIFwKICAgIFNlbmRNZXNzYWdlQSggR2V0UGFyZW50KCh3bmRQdHIpLT5od25kU2VsZiksIFdNX0NUTENPTE9SQlROLCBcCiAgICAgICAgICAgICAgICAgICAgKGhkYyksICh3bmRQdHIpLT5od25kU2VsZiApCgpzdGF0aWMgSEJJVE1BUCBoYml0bWFwQ2hlY2tCb3hlcyA9IDA7CnN0YXRpYyBXT1JEIGNoZWNrQm94V2lkdGggPSAwLCBjaGVja0JveEhlaWdodCA9IDA7CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBCdXR0b25XbmRQcm9jX2xvY2tlZAogKiAKICogQ2FsbGVkIHdpdGggd2luZG93IGxvY2sgaGVsZC4KICovCnN0YXRpYyBpbmxpbmUgTFJFU1VMVCBXSU5BUEkgQnV0dG9uV25kUHJvY19sb2NrZWQoV05EKiB3bmRQdHIsIFVJTlQgdU1zZywKCQkJCQkgICBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtICkKewogICAgUkVDVCByZWN0OwogICAgSFdORAloV25kID0gd25kUHRyLT5od25kU2VsZjsKICAgIFBPSU5UIHB0OwogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CiAgICBMT05HIHN0eWxlID0gd25kUHRyLT5kd1N0eWxlICYgMHgwZjsKICAgIEhBTkRMRSBvbGRIYml0bWFwOwoKICAgIHB0LnggPSBMT1dPUkQobFBhcmFtKTsKICAgIHB0LnkgPSBISVdPUkQobFBhcmFtKTsKCiAgICBzd2l0Y2ggKHVNc2cpCiAgICB7CiAgICBjYXNlIFdNX0dFVERMR0NPREU6CiAgICAgICAgc3dpdGNoKHN0eWxlKQogICAgICAgIHsKICAgICAgICBjYXNlIEJTX1BVU0hCVVRUT046ICAgICAgcmV0dXJuIERMR0NfQlVUVE9OIHwgRExHQ19VTkRFRlBVU0hCVVRUT047CiAgICAgICAgY2FzZSBCU19ERUZQVVNIQlVUVE9OOiAgIHJldHVybiBETEdDX0JVVFRPTiB8IERMR0NfREVGUFVTSEJVVFRPTjsKICAgICAgICBjYXNlIEJTX1JBRElPQlVUVE9OOgogICAgICAgIGNhc2UgQlNfQVVUT1JBRElPQlVUVE9OOiByZXR1cm4gRExHQ19CVVRUT04gfCBETEdDX1JBRElPQlVUVE9OOwogICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICByZXR1cm4gRExHQ19CVVRUT047CiAgICAgICAgfQoKICAgIGNhc2UgV01fRU5BQkxFOgogICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX0RSQVdFTlRJUkUgKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX0NSRUFURToKICAgICAgICBpZiAoIWhiaXRtYXBDaGVja0JveGVzKQogICAgICAgIHsKICAgICAgICAgICAgQklUTUFQIGJtcDsKICAgICAgICAgICAgaGJpdG1hcENoZWNrQm94ZXMgPSBMb2FkQml0bWFwQSgwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9DSEVDS0JPWEVTKSk7CiAgICAgICAgICAgIEdldE9iamVjdEEoIGhiaXRtYXBDaGVja0JveGVzLCBzaXplb2YoYm1wKSwgJmJtcCApOwogICAgICAgICAgICBjaGVja0JveFdpZHRoICA9IGJtcC5ibVdpZHRoIC8gNDsKICAgICAgICAgICAgY2hlY2tCb3hIZWlnaHQgPSBibXAuYm1IZWlnaHQgLyAzOwogICAgICAgIH0KICAgICAgICBpZiAoc3R5bGUgPCAwTCB8fCBzdHlsZSA+PSBNQVhfQlROX1RZUEUpCiAgICAgICAgICAgIHJldHVybiAtMTsgLyogYWJvcnQgKi8KICAgICAgICBpbmZvUHRyLT5zdGF0ZSA9IEJVVFRPTl9VTkNIRUNLRUQ7CiAgICAgICAgaW5mb1B0ci0+aEZvbnQgPSAwOwogICAgICAgIGluZm9QdHItPmhJbWFnZSA9IE5VTEw7CiAgICAgICAgcmV0dXJuIDA7CgogICAgY2FzZSBXTV9FUkFTRUJLR05EOgogICAgICAgIHJldHVybiAxOwoKICAgIGNhc2UgV01fUEFJTlQ6CiAgICAgICAgaWYgKGJ0blBhaW50RnVuY1tzdHlsZV0pCiAgICAgICAgewogICAgICAgICAgICBQQUlOVFNUUlVDVCBwczsKICAgICAgICAgICAgSERDIGhkYyA9IHdQYXJhbSA/IChIREMpd1BhcmFtIDogQmVnaW5QYWludCggaFduZCwgJnBzICk7CgkgICAgU2V0QmtNb2RlKCBoZGMsIE9QQVFVRSApOwogICAgICAgICAgICAoYnRuUGFpbnRGdW5jW3N0eWxlXSkoIHduZFB0ciwgaGRjLCBPREFfRFJBV0VOVElSRSApOwogICAgICAgICAgICBpZiggIXdQYXJhbSApIEVuZFBhaW50KCBoV25kLCAmcHMgKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9MQlVUVE9OREJMQ0xLOgogICAgICAgIGlmKHduZFB0ci0+ZHdTdHlsZSAmIEJTX05PVElGWSB8fCAKICAgICAgICAgICAgICAgIHN0eWxlPT1CU19SQURJT0JVVFRPTiB8fAogICAgICAgICAgICAgICAgc3R5bGU9PUJTX1VTRVJCVVRUT04gfHwKICAgICAgICAgICAgICAgIHN0eWxlPT1CU19PV05FUkRSQVcpIHsKICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBHZXRQYXJlbnQoaFduZCksIFdNX0NPTU1BTkQsCiAgICAgICAgICAgICAgICAgICAgTUFLRVdQQVJBTSggd25kUHRyLT53SURtZW51LCBCTl9ET1VCTEVDTElDS0VEICksIGhXbmQpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCiAgICBjYXNlIFdNX0xCVVRUT05ET1dOOgogICAgICAgIFNldENhcHR1cmUoIGhXbmQgKTsKICAgICAgICBTZXRGb2N1cyggaFduZCApOwogICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUU1RBVEUsIFRSVUUsIDAgKTsKICAgICAgICBpbmZvUHRyLT5zdGF0ZSB8PSBCVVRUT05fQlROUFJFU1NFRDsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX0xCVVRUT05VUDoKICAgICAgICBpZiAoIShpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9CVE5QUkVTU0VEKSkgYnJlYWs7CiAgICAgICAgaW5mb1B0ci0+c3RhdGUgJj0gQlVUVE9OX05TVEFURVM7CiAgICAgICAgaWYgKCEoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpKSB7CiAgICAgICAgICAgIFJlbGVhc2VDYXB0dXJlKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVFNUQVRFLCBGQUxTRSwgMCApOwogICAgICAgIFJlbGVhc2VDYXB0dXJlKCk7CiAgICAgICAgR2V0Q2xpZW50UmVjdCggaFduZCwgJnJlY3QgKTsKICAgICAgICBpZiAoUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgIHsKICAgICAgICAgICAgc3dpdGNoKHN0eWxlKQogICAgICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgQlNfQVVUT0NIRUNLQk9YOgogICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRDSEVDSywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0NIRUNLRUQpLCAwICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBCU19BVVRPUkFESU9CVVRUT046CiAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVENIRUNLLCBUUlVFLCAwICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBCU19BVVRPM1NUQVRFOgogICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRDSEVDSywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fM1NUQVRFKSA/IDAgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoaW5mb1B0ci0+c3RhdGUgJiAzKSArIDEpLCAwICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBTZW5kTWVzc2FnZUEoIEdldFBhcmVudChoV25kKSwgV01fQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BS0VXUEFSQU0oIHduZFB0ci0+d0lEbWVudSwgQk5fQ0xJQ0tFRCApLCBoV25kKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9DQVBUVVJFQ0hBTkdFRDoKICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fQlROUFJFU1NFRCkgewogICAgICAgICAgICBpbmZvUHRyLT5zdGF0ZSAmPSBCVVRUT05fTlNUQVRFUzsKICAgICAgICAgICAgaWYgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSAKICAgICAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUU1RBVEUsIEZBTFNFLCAwICk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fTU9VU0VNT1ZFOgogICAgICAgIGlmIChHZXRDYXB0dXJlKCkgPT0gaFduZCkKICAgICAgICB7CiAgICAgICAgICAgIEdldENsaWVudFJlY3QoIGhXbmQsICZyZWN0ICk7CiAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUU1RBVEUsIFB0SW5SZWN0KCZyZWN0LCBwdCksIDAgKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9OQ0hJVFRFU1Q6CiAgICAgICAgaWYoc3R5bGUgPT0gQlNfR1JPVVBCT1gpIHJldHVybiBIVFRSQU5TUEFSRU5UOwogICAgICAgIHJldHVybiBEZWZXaW5kb3dQcm9jQSggaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0gKTsKCiAgICBjYXNlIFdNX1NFVFRFWFQ6CiAgICAgICAgREVGV05EX1NldFRleHQoIHduZFB0ciwgKExQQ1NUUilsUGFyYW0gKTsKCWlmKCB3bmRQdHItPmR3U3R5bGUgJiBXU19WSVNJQkxFICkKICAgICAgICAgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfRFJBV0VOVElSRSApOwogICAgICAgIHJldHVybiAwOwoKICAgIGNhc2UgV01fU0VURk9OVDoKICAgICAgICBpbmZvUHRyLT5oRm9udCA9IChIRk9OVDE2KXdQYXJhbTsKICAgICAgICBpZiAobFBhcmFtICYmICh3bmRQdHItPmR3U3R5bGUgJiBXU19WSVNJQkxFKSkgCgkgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfRFJBV0VOVElSRSApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fR0VURk9OVDoKICAgICAgICByZXR1cm4gaW5mb1B0ci0+aEZvbnQ7CgogICAgY2FzZSBXTV9TRVRGT0NVUzoKICAgICAgICBpZiAoKHN0eWxlID09IEJTX0FVVE9SQURJT0JVVFRPTikgJiYgKEdldENhcHR1cmUoKSAhPSBoV25kKSAmJgogICAgICAgICAgICAhKFNlbmRNZXNzYWdlQShoV25kLCBCTV9HRVRDSEVDSywgMCwgMCkgJiBCU1RfQ0hFQ0tFRCkpCgl7CiAgICAgICAgICAgIC8qIFRoZSBub3RpZmljYXRpb24gaXMgc2VudCB3aGVuIHRoZSBidXR0b24gKEJTX0FVVE9SQURJT0JVVFRPTikgCiAgICAgICAgICAgICAgIGlzIHVuY2tlY2tlZCBhbmQgdGhlIGZvY3VzIHdhcyBub3QgZ2l2ZW4gYnkgYSBtb3VzZSBjbGljay4gKi8KICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRDSEVDSywgVFJVRSwgMCApOwogICAgICAgICAgICBTZW5kTWVzc2FnZUEoIEdldFBhcmVudChoV25kKSwgV01fQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgICAgICBNQUtFV1BBUkFNKCB3bmRQdHItPndJRG1lbnUsIEJOX0NMSUNLRUQgKSwgaFduZCk7CiAgICAgICAgfQogICAgICAgIGluZm9QdHItPnN0YXRlIHw9IEJVVFRPTl9IQVNGT0NVUzsKICAgICAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9GT0NVUyApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fS0lMTEZPQ1VTOgogICAgICAgIGluZm9QdHItPnN0YXRlICY9IH5CVVRUT05fSEFTRk9DVVM7CglQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9GT0NVUyApOwoJSW52YWxpZGF0ZVJlY3QoIGhXbmQsIE5VTEwsIFRSVUUgKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX1NZU0NPTE9SQ0hBTkdFOgogICAgICAgIEludmFsaWRhdGVSZWN0KCBoV25kLCBOVUxMLCBGQUxTRSApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQk1fU0VUU1RZTEUxNjoKICAgIGNhc2UgQk1fU0VUU1RZTEU6CiAgICAgICAgaWYgKCh3UGFyYW0gJiAweDBmKSA+PSBNQVhfQlROX1RZUEUpIGJyZWFrOwogICAgICAgIHduZFB0ci0+ZHdTdHlsZSA9ICh3bmRQdHItPmR3U3R5bGUgJiAweGZmZmZmZmYwKSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAod1BhcmFtICYgMHgwMDAwMDAwZik7CiAgICAgICAgc3R5bGUgPSB3bmRQdHItPmR3U3R5bGUgJiAweDAwMDAwMDBmOwogICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX0RSQVdFTlRJUkUgKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIEJNX1NFVElNQUdFOgoJb2xkSGJpdG1hcCA9IGluZm9QdHItPmhJbWFnZTsKCWlmICgod25kUHRyLT5kd1N0eWxlICYgQlNfQklUTUFQKSB8fCAod25kUHRyLT5kd1N0eWxlICYgQlNfSUNPTikpCgkgICAgaW5mb1B0ci0+aEltYWdlID0gKEhBTkRMRSkgbFBhcmFtOwoJcmV0dXJuIG9sZEhiaXRtYXA7CgogICAgY2FzZSBCTV9HRVRJTUFHRToKICAgICAgICBpZiAod1BhcmFtID09IElNQUdFX0JJVE1BUCkKCSAgICByZXR1cm4gKEhCSVRNQVApaW5mb1B0ci0+aEltYWdlOwoJZWxzZSBpZiAod1BhcmFtID09IElNQUdFX0lDT04pCgkgICAgcmV0dXJuIChISUNPTilpbmZvUHRyLT5oSW1hZ2U7CgllbHNlCgkgICAgcmV0dXJuIE5VTEw7CgogICAgY2FzZSBCTV9HRVRDSEVDSzE2OgogICAgY2FzZSBCTV9HRVRDSEVDSzoKICAgICAgICByZXR1cm4gaW5mb1B0ci0+c3RhdGUgJiAzOwoKICAgIGNhc2UgQk1fU0VUQ0hFQ0sxNjoKICAgIGNhc2UgQk1fU0VUQ0hFQ0s6CiAgICAgICAgaWYgKHdQYXJhbSA+IG1heENoZWNrU3RhdGVbc3R5bGVdKSB3UGFyYW0gPSBtYXhDaGVja1N0YXRlW3N0eWxlXTsKICAgICAgICBpZiAoKGluZm9QdHItPnN0YXRlICYgMykgIT0gd1BhcmFtKQogICAgICAgIHsKCSAgICBpZiAoKHN0eWxlID09IEJTX1JBRElPQlVUVE9OKSB8fCAoc3R5bGUgPT0gQlNfQVVUT1JBRElPQlVUVE9OKSkKCSAgICB7CgkJaWYgKHdQYXJhbSkKCQkgICAgd25kUHRyLT5kd1N0eWxlIHw9IFdTX1RBQlNUT1A7CgkJZWxzZQoJCSAgICB3bmRQdHItPmR3U3R5bGUgJj0gfldTX1RBQlNUT1A7CgkgICAgfQogICAgICAgICAgICBpbmZvUHRyLT5zdGF0ZSA9IChpbmZvUHRyLT5zdGF0ZSAmIH4zKSB8IHdQYXJhbTsKICAgICAgICAgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfU0VMRUNUICk7CiAgICAgICAgfQogICAgICAgIGlmICgoc3R5bGUgPT0gQlNfQVVUT1JBRElPQlVUVE9OKSAmJiAod1BhcmFtID09IEJVVFRPTl9DSEVDS0VEKSkKICAgICAgICAgICAgQlVUVE9OX0NoZWNrQXV0b1JhZGlvQnV0dG9uKCB3bmRQdHIgKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIEJNX0dFVFNUQVRFMTY6CiAgICBjYXNlIEJNX0dFVFNUQVRFOgogICAgICAgIHJldHVybiBpbmZvUHRyLT5zdGF0ZTsKCiAgICBjYXNlIEJNX1NFVFNUQVRFMTY6CiAgICBjYXNlIEJNX1NFVFNUQVRFOgogICAgICAgIGlmICh3UGFyYW0pCiAgICAgICAgewogICAgICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpIGJyZWFrOwogICAgICAgICAgICBpbmZvUHRyLT5zdGF0ZSB8PSBCVVRUT05fSElHSExJR0hURUQ7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmICghKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSkgYnJlYWs7CiAgICAgICAgICAgIGluZm9QdHItPnN0YXRlICY9IH5CVVRUT05fSElHSExJR0hURUQ7CiAgICAgICAgfQogICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX1NFTEVDVCApOwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIERlZldpbmRvd1Byb2NBKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKICAgIH0KICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEJ1dHRvblduZFByb2MKICogVGhlIGJ1dHRvbiB3aW5kb3cgcHJvY2VkdXJlLiBUaGlzIGlzIGp1c3QgYSB3cmFwcGVyIHdoaWNoIGxvY2tzCiAqIHRoZSBwYXNzZWQgSFdORCBhbmQgY2FsbHMgdGhlIHJlYWwgd2luZG93IHByb2NlZHVyZSAod2l0aCBhIFdORCoKICogcG9pbnRlciBwb2ludGluZyB0byB0aGUgbG9ja2VkIHdpbmRvd3N0cnVjdHVyZSkuCiAqLwpMUkVTVUxUIFdJTkFQSSBCdXR0b25XbmRQcm9jKCBIV05EIGhXbmQsIFVJTlQgdU1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSApCnsKICAgIExSRVNVTFQgcmVzOwogICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0cihoV25kKTsKCiAgICByZXMgPSBCdXR0b25XbmRQcm9jX2xvY2tlZCh3bmRQdHIsdU1zZyx3UGFyYW0sbFBhcmFtKTsKCiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuIHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgUHVzaCBCdXR0b24gRnVuY3Rpb25zCiAqLwpzdGF0aWMgdm9pZCBQQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICkKewogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciAgICAgID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKICAgIEJPT0wgICAgICAgIGJIaWdoTGlnaHRlZCA9IChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCk7CgogICAgLyogCiAgICAgKiBEZWxlZ2F0ZSB0aGlzIHRvIHRoZSBtb3JlIGdlbmVyaWMgcHVzaGJ1dHRvbiBwYWludGluZwogICAgICogbWV0aG9kLgogICAgICovCiAgICBCVVRUT05fRHJhd1B1c2hCdXR0b24od25kUHRyLAoJCQkgIGhEQywKCQkJICBhY3Rpb24sCgkJCSAgYkhpZ2hMaWdodGVkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhpcyBtZXRob2Qgd2lsbCBhY3R1YWxseSBkbyB0aGUgZHJhd2luZyBvZiB0aGUgcHVzaGJ1dHRvbiAKICogZGVwZW5kaW5nIG9uIGl0J3Mgc3RhdGUgYW5kIHRoZSBwdXNoZWRTdGF0ZSBwYXJhbWV0ZXIuCiAqLwpzdGF0aWMgdm9pZCBCVVRUT05fRHJhd1B1c2hCdXR0b24oCiAgV05EKiB3bmRQdHIsCiAgSERDICBoREMsIAogIFdPUkQgYWN0aW9uLCAKICBCT09MIHB1c2hlZFN0YXRlICkKewogICAgUkVDVCByYywgZm9jdXNfcmVjdDsKICAgIEhQRU4gaE9sZFBlbjsKICAgIEhCUlVTSCBoT2xkQnJ1c2g7CiAgICBCVVRUT05JTkZPICppbmZvUHRyID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKICAgIGludCB4Qm9yZGVyT2Zmc2V0LCB5Qm9yZGVyT2Zmc2V0OwogICAgeEJvcmRlck9mZnNldCA9IHlCb3JkZXJPZmZzZXQgPSAwOwoKICAgIEdldENsaWVudFJlY3QoIHduZFB0ci0+aHduZFNlbGYsICZyYyApOwoKICAgICAgLyogU2VuZCBXTV9DVExDT0xPUiB0byBhbGxvdyBjaGFuZ2luZyB0aGUgZm9udCAodGhlIGNvbG9ycyBhcmUgZml4ZWQpICovCiAgICBpZiAoaW5mb1B0ci0+aEZvbnQpIFNlbGVjdE9iamVjdCggaERDLCBpbmZvUHRyLT5oRm9udCApOwogICAgQlVUVE9OX1NFTkRfQ1RMQ09MT1IoIHduZFB0ciwgaERDICk7CiAgICBoT2xkUGVuID0gKEhQRU4pU2VsZWN0T2JqZWN0KGhEQywgR2V0U3lzQ29sb3JQZW4oQ09MT1JfV0lORE9XRlJBTUUpKTsKICAgIGhPbGRCcnVzaCA9KEhCUlVTSClTZWxlY3RPYmplY3QoaERDLEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfQlRORkFDRSkpOwogICAgU2V0QmtNb2RlKGhEQywgVFJBTlNQQVJFTlQpOwoKICAgIGlmICggVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKICAgIHsKICAgICAgICBSZWN0YW5nbGUoaERDLCByYy5sZWZ0LCByYy50b3AsIHJjLnJpZ2h0LCByYy5ib3R0b20pOwoKICAgICAgICBTZXRQaXhlbCggaERDLCByYy5sZWZ0LCByYy50b3AsIEdldFN5c0NvbG9yKENPTE9SX1dJTkRPVykgKTsKICAgICAgICBTZXRQaXhlbCggaERDLCByYy5sZWZ0LCByYy5ib3R0b20tMSwgR2V0U3lzQ29sb3IoQ09MT1JfV0lORE9XKSApOwogICAgICAgIFNldFBpeGVsKCBoREMsIHJjLnJpZ2h0LTEsIHJjLnRvcCwgR2V0U3lzQ29sb3IoQ09MT1JfV0lORE9XKSApOwogICAgICAgIFNldFBpeGVsKCBoREMsIHJjLnJpZ2h0LTEsIHJjLmJvdHRvbS0xLCBHZXRTeXNDb2xvcihDT0xPUl9XSU5ET1cpKTsKCUluZmxhdGVSZWN0KCAmcmMsIC0xLCAtMSApOwogICAgfQogICAgCiAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MDAwZikgPT0gQlNfREVGUFVTSEJVVFRPTikKICAgIHsKICAgICAgICBSZWN0YW5nbGUoaERDLCByYy5sZWZ0LCByYy50b3AsIHJjLnJpZ2h0LCByYy5ib3R0b20pOwoJSW5mbGF0ZVJlY3QoICZyYywgLTEsIC0xICk7CiAgICB9CgogICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCiAgICB7CiAgICAgICAgaWYgKHB1c2hlZFN0YXRlKQoJewoJICAgIC8qIGRyYXcgYnV0dG9uIHNoYWRvdzogKi8KCSAgICBTZWxlY3RPYmplY3QoaERDLCBHZXRTeXNDb2xvckJydXNoKENPTE9SX0JUTlNIQURPVykpOwoJICAgIFBhdEJsdChoREMsIHJjLmxlZnQsIHJjLnRvcCwgMSwgcmMuYm90dG9tLXJjLnRvcCwgUEFUQ09QWSApOwoJICAgIFBhdEJsdChoREMsIHJjLmxlZnQsIHJjLnRvcCwgcmMucmlnaHQtcmMubGVmdCwgMSwgUEFUQ09QWSApOwoJICAgIHJjLmxlZnQgKz0gMjsgIC8qIFRvIHBvc2l0aW9uIHRoZSB0ZXh0IGRvd24gYW5kIHJpZ2h0ICovCgkgICAgcmMudG9wICArPSAyOwoJfSBlbHNlIHsKCSAgIHJjLnJpZ2h0KyssIHJjLmJvdHRvbSsrOwoJICAgRHJhd0VkZ2UoIGhEQywgJnJjLCBFREdFX1JBSVNFRCwgQkZfUkVDVCApOwoKCSAgIC8qIFRvIHBsYWNlIGRlIGJpdG1hcCBjb3JyZWN0bHkgKi8KCSAgIHhCb3JkZXJPZmZzZXQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWEVER0UpOwoJICAgeUJvcmRlck9mZnNldCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSk7CgoJICAgcmMucmlnaHQtLSwgcmMuYm90dG9tLS07Cgl9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgVUlOVCB1U3RhdGUgPSBERkNTX0JVVFRPTlBVU0g7CgogICAgICAgIGlmIChwdXNoZWRTdGF0ZSkKCXsKCSAgICBpZiAoICh3bmRQdHItPmR3U3R5bGUgJiAweDAwMGYpID09IEJTX0RFRlBVU0hCVVRUT04gKQoJICAgICAgICB1U3RhdGUgfD0gREZDU19GTEFUOwoJICAgIGVsc2UKCSAgICAgICAgdVN0YXRlIHw9IERGQ1NfUFVTSEVEOwoJfQoKCURyYXdGcmFtZUNvbnRyb2woIGhEQywgJnJjLCBERkNfQlVUVE9OLCB1U3RhdGUgKTsKCUluZmxhdGVSZWN0KCAmcmMsIC0yLCAtMiApOwoKCWZvY3VzX3JlY3QgPSByYzsKCiAgICAgICAgaWYgKHB1c2hlZFN0YXRlKQoJewoJICAgIHJjLmxlZnQgKz0gMjsgIC8qIFRvIHBvc2l0aW9uIHRoZSB0ZXh0IGRvd24gYW5kIHJpZ2h0ICovCgkgICAgcmMudG9wICArPSAyOwoJfQogICAgfQoKICAgIC8qIGRyYXcgYnV0dG9uIGxhYmVsLCBpZiBhbnk6CiAgICAgKgogICAgICogSW4gd2luOXggd2UgZG9uJ3Qgc2hvdyB0ZXh0IGlmIHRoZXJlIGlzIGEgYml0bWFwIG9yIGljb24uCiAgICAgKiBJIGRvbid0IGtub3cgYWJvdXQgd2luMzEgc28gSSBsZWF2ZSBpdCBhcyBpdCB3YXMgZm9yIHdpbjMxLgogICAgICogRGVubmlzIEJq9nJrbHVuZCAxMiBKdWwsIDk5CiAgICAgKi8KICAgIGlmICggd25kUHRyLT50ZXh0ICYmIHduZFB0ci0+dGV4dFswXQoJICYmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LIHx8ICEod25kUHRyLT5kd1N0eWxlICYgKEJTX0lDT058QlNfQklUTUFQKSkpICkKICAgIHsKICAgICAgICBMT0dCUlVTSCBsYjsKICAgICAgICBHZXRPYmplY3RBKCBHZXRTeXNDb2xvckJydXNoKENPTE9SX0JUTkZBQ0UpLCBzaXplb2YobGIpLCAmbGIgKTsKICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQgJiYKICAgICAgICAgICAgR2V0U3lzQ29sb3IoQ09MT1JfR1JBWVRFWFQpPT1sYi5sYkNvbG9yKQogICAgICAgICAgICAvKiBkb24ndCB3cml0ZSBncmF5IHRleHQgb24gZ3JheSBiYWNrZ3JvdW5kICovCiAgICAgICAgICAgIFBhaW50R3JheU9uR3JheSggaERDLGluZm9QdHItPmhGb250LCZyYyx3bmRQdHItPnRleHQsCgkJCSAgICAgICBEVF9DRU5URVIgfCBEVF9WQ0VOVEVSICk7CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgU2V0VGV4dENvbG9yKCBoREMsICh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCkgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXNDb2xvcihDT0xPUl9CVE5URVhUKSApOwogICAgICAgICAgICBEcmF3VGV4dEEoIGhEQywgd25kUHRyLT50ZXh0LCAtMSwgJnJjLAogICAgICAgICAgICAgICAgICAgICAgICAgRFRfU0lOR0xFTElORSB8IERUX0NFTlRFUiB8IERUX1ZDRU5URVIgKTsKICAgICAgICAgICAgLyogZG8gd2UgaGF2ZSB0aGUgZm9jdXM/CgkgICAgICogV2luOXggZHJhd3MgZm9jdXMgbGFzdCB3aXRoIGEgc2l6ZSBwcm9wLiB0byB0aGUgYnV0dG9uCgkgICAgICovCiAgICAgICAgICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LCgkJJiYgaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJFQ1QgciA9IHsgMCwgMCwgMCwgMCB9OwogICAgICAgICAgICAgICAgSU5UIHhkZWx0YSwgeWRlbHRhOwoKICAgICAgICAgICAgICAgIERyYXdUZXh0QSggaERDLCB3bmRQdHItPnRleHQsIC0xLCAmciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9TSU5HTEVMSU5FIHwgRFRfQ0FMQ1JFQ1QgKTsKICAgICAgICAgICAgICAgIHhkZWx0YSA9ICgocmMucmlnaHQgLSByYy5sZWZ0KSAtIChyLnJpZ2h0IC0gci5sZWZ0KSAtIDEpIC8gMjsKICAgICAgICAgICAgICAgIHlkZWx0YSA9ICgocmMuYm90dG9tIC0gcmMudG9wKSAtIChyLmJvdHRvbSAtIHIudG9wKSAtIDEpIC8gMjsKICAgICAgICAgICAgICAgIGlmICh4ZGVsdGEgPCAwKSB4ZGVsdGEgPSAwOwogICAgICAgICAgICAgICAgaWYgKHlkZWx0YSA8IDApIHlkZWx0YSA9IDA7CiAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCggJnJjLCAteGRlbHRhLCAteWRlbHRhICk7CiAgICAgICAgICAgICAgICBEcmF3Rm9jdXNSZWN0KCBoREMsICZyYyApOwogICAgICAgICAgICB9CiAgICAgICAgfSAgIAogICAgfQogICAgaWYgKCAoKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0lDT04pIHx8ICh3bmRQdHItPmR3U3R5bGUgJiBCU19CSVRNQVApICkgJiYKCSAoaW5mb1B0ci0+aEltYWdlICE9IE5VTEwpICkKICAgIHsKCWludCB5T2Zmc2V0LCB4T2Zmc2V0OwoJaW50IGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0OwoKCS8qCgkgKiBXZSBleHRyYWN0IHRoZSBzaXplIG9mIHRoZSBpbWFnZSBmcm9tIHRoZSBoYW5kbGUuCgkgKi8KCWlmICh3bmRQdHItPmR3U3R5bGUgJiBCU19JQ09OKQoJewoJICAgIElDT05JTkZPIGljb25JbmZvOwoJICAgIEJJVE1BUCAgIGJtOwoKCSAgICBHZXRJY29uSW5mbygoSElDT04paW5mb1B0ci0+aEltYWdlLCAmaWNvbkluZm8pOwoJICAgIEdldE9iamVjdEEgKGljb25JbmZvLmhibUNvbG9yLCBzaXplb2YoQklUTUFQKSwgJmJtKTsKCSAgICAKCSAgICBpbWFnZVdpZHRoICA9IGJtLmJtV2lkdGg7CgkgICAgaW1hZ2VIZWlnaHQgPSBibS5ibUhlaWdodDsKCiAgICAgICAgICAgIERlbGV0ZU9iamVjdChpY29uSW5mby5oYm1Db2xvcik7CiAgICAgICAgICAgIERlbGV0ZU9iamVjdChpY29uSW5mby5oYm1NYXNrKTsKCgl9CgllbHNlCgl7CgkgICAgQklUTUFQICAgYm07CgoJICAgIEdldE9iamVjdEEgKGluZm9QdHItPmhJbWFnZSwgc2l6ZW9mKEJJVE1BUCksICZibSk7CgkKCSAgICBpbWFnZVdpZHRoICA9IGJtLmJtV2lkdGg7CgkgICAgaW1hZ2VIZWlnaHQgPSBibS5ibUhlaWdodDsKCX0KCgkvKiBDZW50ZXIgdGhlIGJpdG1hcCAqLwoJeE9mZnNldCA9ICgoKHJjLnJpZ2h0IC0gcmMubGVmdCkgLSAyKnhCb3JkZXJPZmZzZXQpIC0gaW1hZ2VXaWR0aCApIC8gMjsKCXlPZmZzZXQgPSAoKChyYy5ib3R0b20gLSByYy50b3ApIC0gMip5Qm9yZGVyT2Zmc2V0KSAtIGltYWdlSGVpZ2h0KSAvIDI7CgoJLyogSWYgdGhlIGltYWdlIGlzIHRvbyBiaWcgZm9yIHRoZSBidXR0b24gdGhlbiBjcmVhdGUgYSByZWdpb24qLwogICAgICAgIGlmKHhPZmZzZXQgPCAwIHx8IHlPZmZzZXQgPCAwKQoJewogICAgICAgICAgICBIUkdOIGhCaXRtYXBSZ24gPSBOVUxMOwogICAgICAgICAgICBoQml0bWFwUmduID0gQ3JlYXRlUmVjdFJnbigKICAgICAgICAgICAgICAgIHJjLmxlZnQgKyB4Qm9yZGVyT2Zmc2V0LCByYy50b3AgK3lCb3JkZXJPZmZzZXQsIAogICAgICAgICAgICAgICAgcmMucmlnaHQgLSB4Qm9yZGVyT2Zmc2V0LCByYy5ib3R0b20gLSB5Qm9yZGVyT2Zmc2V0KTsKICAgICAgICAgICAgU2VsZWN0Q2xpcFJnbihoREMsIGhCaXRtYXBSZ24pOwogICAgICAgICAgICBEZWxldGVPYmplY3QoaEJpdG1hcFJnbik7Cgl9CgoJLyogTGV0IG1pbmltdW0gMSBzcGFjZSBmcm9tIGJvcmRlciAqLwoJeE9mZnNldCsrLCB5T2Zmc2V0Kys7CgoJLyoKCSAqIERyYXcgdGhlIGltYWdlIG5vdy4KCSAqLwoJaWYgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0lDT04pCgl7CiAgCSAgICBEcmF3SWNvbihoREMsCiAgICAgICAgICAgICAgICByYy5sZWZ0ICsgeE9mZnNldCwgcmMudG9wICsgeU9mZnNldCwKCQkgICAgIChISUNPTilpbmZvUHRyLT5oSW1hZ2UpOwoJfQoJZWxzZQogICAgICAgIHsKCSAgICBIREMgaGRjTWVtOwoKCSAgICBoZGNNZW0gPSBDcmVhdGVDb21wYXRpYmxlREMgKGhEQyk7CgkgICAgU2VsZWN0T2JqZWN0IChoZGNNZW0sIChIQklUTUFQKWluZm9QdHItPmhJbWFnZSk7CgkgICAgQml0Qmx0KGhEQywgCgkJICAgcmMubGVmdCArIHhPZmZzZXQsIAoJCSAgIHJjLnRvcCArIHlPZmZzZXQsIAoJCSAgIGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0LAoJCSAgIGhkY01lbSwgMCwgMCwgU1JDQ09QWSk7CgkgICAgCgkgICAgRGVsZXRlREMgKGhkY01lbSk7Cgl9CgogICAgICAgIGlmKHhPZmZzZXQgPCAwIHx8IHlPZmZzZXQgPCAwKQogICAgICAgIHsKICAgICAgICAgICAgU2VsZWN0Q2xpcFJnbihoREMsIE5VTEwpOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoVFdFQUtfV2luZUxvb2sgIT0gV0lOMzFfTE9PSwoJJiYgaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpCiAgICB7CiAgICAgICAgSW5mbGF0ZVJlY3QoICZmb2N1c19yZWN0LCAtMSwgLTEgKTsKICAgICAgICBEcmF3Rm9jdXNSZWN0KCBoREMsICZmb2N1c19yZWN0ICk7CiAgICB9CgogICAgCiAgICBTZWxlY3RPYmplY3QoIGhEQywgaE9sZFBlbiApOwogICAgU2VsZWN0T2JqZWN0KCBoREMsIGhPbGRCcnVzaCApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICBQQl9QYWludCAmIENCX1BhaW50IHN1YiBmdW5jdGlvbiAgICAgICAgICAgICAgICAgICAgICAgIFtpbnRlcm5hbF0KICogICBQYWludCB0ZXh0IHVzaW5nIGEgcmFzdGVyIGJydXNoIHRvIGF2b2lkIGdyYXkgdGV4dCBvbiBncmF5IAogKiAgIGJhY2tncm91bmQuICdmb3JtYXQnIGNhbiBiZSBhIGNvbWJpbmF0aW9uIG9mIERUX0NFTlRFUiBhbmQgCiAqICAgRFRfVkNFTlRFUiB0byB1c2UgdGhpcyBmdW5jdGlvbiBpbiBib3RoIFBCX1BBSU5UIGFuZCAKICogICBDQl9QQUlOVC4gICAtIERpcmsgVGhpZXJiYWNoCiAqCiAqICAgRklYTUU6IFRoaXMgYW5kIFRFWFRfR3JheVN0cmluZyBzaG91bGQgYmUgZXZlbnR1YWxseSBjb21iaW5lZCwKICogICBzbyBjYWxsaW5nIG9uZSBjb21tb24gZnVuY3Rpb24gZnJvbSBQQl9QYWludCwgQ0JfUGFpbnQgYW5kCiAqICAgVEVYVF9HcmF5U3RyaW5nIHdpbGwgYmUgZW5vdWdoLiBBbHNvIG5vdGUgdGhhdCB0aGlzCiAqICAgZnVuY3Rpb24gaWdub3JlcyB0aGUgQ0FDSEVfR2V0UGF0dGVybiBmdW5jcy4KICovCgp2b2lkIFBhaW50R3JheU9uR3JheShIREMgaERDLEhGT05UIGhGb250LFJFQ1QgKnJjLGNoYXIgKnRleHQsCgkJCVVJTlQgZm9ybWF0KQp7Ci8qICBUaGlzIGlzIHRoZSBzdGFuZGFyZCBncmF5IG9uIGdyYXkgcGF0dGVybjoKICAgIHN0YXRpYyBjb25zdCBXT1JEIFBhdHRlcm5bXSA9IHsweEFBLDB4NTUsMHhBQSwweDU1LDB4QUEsMHg1NSwweEFBLDB4NTV9OyAKKi8KLyogIFRoaXMgcGF0dGVybiBnaXZlcyBiZXR0ZXIgcmVhZGFiaWxpdHkgd2l0aCBYIEZvbnRzLgogICAgRklYTUU6IE1heWJlIHRoZSB1c2VyIHNob3VsZCBiZSBhbGxvd2VkIHRvIGRlY2lkZSB3aGljaCBoZSB3YW50cy4gKi8KICAgIHN0YXRpYyBjb25zdCBXT1JEIFBhdHRlcm5bXSA9IHsweDU1LDB4RkYsMHhBQSwweEZGLDB4NTUsMHhGRiwweEFBLDB4RkZ9OyAKCiAgICBIQklUTUFQIGhibSAgPSBDcmVhdGVCaXRtYXAoIDgsIDgsIDEsIDEsIFBhdHRlcm4gKTsKICAgIEhEQyBoZGNNZW0gPSBDcmVhdGVDb21wYXRpYmxlREMoaERDKTsKICAgIEhCSVRNQVAgaGJtTWVtOwogICAgSEJSVVNIIGhCcjsKICAgIFJFQ1QgcmVjdCxyYzI7CgogICAgcmVjdD0qcmM7CiAgICBEcmF3VGV4dEEoIGhEQywgdGV4dCwgLTEsICZyZWN0LCBEVF9TSU5HTEVMSU5FIHwgRFRfQ0FMQ1JFQ1QpOwogICAgLyogbm93IHRleHQgd2lkdGggYW5kIGhlaWdodCBhcmUgaW4gcmVjdC5yaWdodCBhbmQgcmVjdC5ib3R0b20gKi8KICAgIHJjMj1yZWN0OwogICAgcmVjdC5sZWZ0ID0gcmVjdC50b3AgPSAwOyAvKiBkcmF3aW5nIHBvcyBpbiBoZGNNZW0gKi8KICAgIGlmIChmb3JtYXQgJiBEVF9DRU5URVIpIHJlY3QubGVmdD0ocmMtPnJpZ2h0LXJlY3QucmlnaHQpLzI7CiAgICBpZiAoZm9ybWF0ICYgRFRfVkNFTlRFUikgcmVjdC50b3A9KHJjLT5ib3R0b20tcmVjdC5ib3R0b20pLzI7CiAgICBoYm1NZW0gPSBDcmVhdGVDb21wYXRpYmxlQml0bWFwKCBoREMscmVjdC5yaWdodCxyZWN0LmJvdHRvbSApOwogICAgU2VsZWN0T2JqZWN0KCBoZGNNZW0sIGhibU1lbSk7CiAgICBQYXRCbHQoIGhkY01lbSwwLDAscmVjdC5yaWdodCxyZWN0LmJvdHRvbSxXSElURU5FU1MpOwogICAgICAvKiB3aWxsIGJlIG92ZXJ3cml0dGVuIGJ5IERyYXdUZXh0LCBidXQganVzdCBpbiBjYXNlICovCiAgICBpZiAoaEZvbnQpIFNlbGVjdE9iamVjdCggaGRjTWVtLCBoRm9udCk7CiAgICBEcmF3VGV4dEEoIGhkY01lbSwgdGV4dCwgLTEsICZyYzIsIERUX1NJTkdMRUxJTkUpOyAgCiAgICAgIC8qIEFmdGVyIGRyYXc6IGZvcmVncm91bmQgPSAwIGJpdHMsIGJhY2tncm91bmQgPSAxIGJpdHMgKi8KICAgIGhCciA9IFNlbGVjdE9iamVjdCggaGRjTWVtLCBDcmVhdGVQYXR0ZXJuQnJ1c2goaGJtKSApOwogICAgRGVsZXRlT2JqZWN0KCBoYm0gKTsKICAgIFBhdEJsdCggaGRjTWVtLDAsMCxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tLDB4QUYwMjI5KTsgCiAgICAgIC8qIG9ubHkga2VlcCB0aGUgZm9yZWdyb3VuZCBiaXRzIHdoZXJlIHBhdHRlcm4gaXMgMSAqLwogICAgRGVsZXRlT2JqZWN0KCBTZWxlY3RPYmplY3QoIGhkY01lbSxoQnIpICk7CiAgICBCaXRCbHQoaERDLHJlY3QubGVmdCxyZWN0LnRvcCxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tLGhkY01lbSwwLDAsU1JDQU5EKTsKICAgICAgLyoga2VlcCB0aGUgYmFja2dyb3VuZCBvZiB0aGUgZGVzdCAqLwogICAgRGVsZXRlREMoIGhkY01lbSk7CiAgICBEZWxldGVPYmplY3QoIGhibU1lbSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgQ2hlY2sgQm94ICYgUmFkaW8gQnV0dG9uIEZ1bmN0aW9ucwogKi8KCnN0YXRpYyB2b2lkIENCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKQp7CiAgICBSRUNUIHJib3gsIHJ0ZXh0LCBjbGllbnQ7CiAgICBIQlJVU0ggaEJydXNoOwogICAgaW50IHRleHRsZW4sIGRlbHRhOwogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CgogICAgLyogCiAgICAgKiBpZiB0aGUgYnV0dG9uIGhhcyBhIGJpdG1hcC9pY29uLCBkcmF3IGEgbm9ybWFsIHB1c2hidXR0b24KICAgICAqIGluc3RlYWQgb2YgYSByYWRpb24gYnV0dG9uLgogICAgICovCiAgICBpZiAoaW5mb1B0ci0+aEltYWdlIT1OVUxMKQogICAgewogICAgICAgIEJPT0wgYkhpZ2hMaWdodGVkID0gKChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCkgfHwKCQkJICAgICAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fQ0hFQ0tFRCkpOwoKICAgICAgICBCVVRUT05fRHJhd1B1c2hCdXR0b24od25kUHRyLAoJCQkgICAgICBoREMsCgkJCSAgICAgIGFjdGlvbiwKCQkJICAgICAgYkhpZ2hMaWdodGVkKTsKCXJldHVybjsKICAgIH0KCiAgICB0ZXh0bGVuID0gMDsKICAgIEdldENsaWVudFJlY3Qod25kUHRyLT5od25kU2VsZiwgJmNsaWVudCk7CiAgICByYm94ID0gcnRleHQgPSBjbGllbnQ7CgogICAgaWYgKGluZm9QdHItPmhGb250KSBTZWxlY3RPYmplY3QoIGhEQywgaW5mb1B0ci0+aEZvbnQgKTsKCiAgICAvKiBTb21ldGhpbmcgaXMgc3RpbGwgbm90IHJpZ2h0LCBjaGVja2JveGVzIChhbmQgZWRpdCBjb250cm9scykKICAgICAqIGluIHdzcGluZzMyIGhhdmUgd2hpdGUgYmFja2dyb3VuZHMgaW5zdGVhZCBvZiBkYXJrIGdyZXkuCiAgICAgKiBCVVRUT05fU0VORF9DVExDT0xPUigpIGlzIGV2ZW4gd29yc2Ugc2luY2UgaXQgcmV0dXJucyAwIGluIHRoaXMKICAgICAqIHBhcnRpY3VsYXIgY2FzZSBhbmQgdGhlIGJhY2tncm91bmQgaXMgbm90IHBhaW50ZWQgYXQgYWxsLgogICAgICovCgogICAgaEJydXNoID0gR2V0Q29udHJvbEJydXNoMTYoIHduZFB0ci0+aHduZFNlbGYsIGhEQywgQ1RMQ09MT1JfQlROICk7CgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0xFRlRURVhUKSAKICAgIHsKCS8qIG1hZ2ljICs0IGlzIHdoYXQgQ1RMM0QgZXhwZWN0cyAqLwoKICAgICAgICBydGV4dC5yaWdodCAtPSBjaGVja0JveFdpZHRoICsgNDsKICAgICAgICByYm94LmxlZnQgPSByYm94LnJpZ2h0IC0gY2hlY2tCb3hXaWR0aDsKICAgIH0KICAgIGVsc2UgCiAgICB7CiAgICAgICAgcnRleHQubGVmdCArPSBjaGVja0JveFdpZHRoICsgNDsKICAgICAgICByYm94LnJpZ2h0ID0gY2hlY2tCb3hXaWR0aDsKICAgIH0KCiAgICAgIC8qIERyYXcgdGhlIGNoZWNrLWJveCBiaXRtYXAgKi8KCiAgICBpZiAod25kUHRyLT50ZXh0KSB0ZXh0bGVuID0gc3RybGVuKCB3bmRQdHItPnRleHQgKTsKICAgIGlmIChhY3Rpb24gPT0gT0RBX0RSQVdFTlRJUkUgfHwgYWN0aW9uID09IE9EQV9TRUxFQ1QpCiAgICB7IAogICAgICAgIGlmKCBUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LICkKICAgICAgICB7CiAgICAgICAgSERDIGhNZW1EQyA9IENyZWF0ZUNvbXBhdGlibGVEQyggaERDICk7CiAgICAgICAgaW50IHggPSAwLCB5ID0gMDsKICAgICAgICBkZWx0YSA9IChyYm94LmJvdHRvbSAtIHJib3gudG9wIC0gY2hlY2tCb3hIZWlnaHQpIC8gMjsKCgkvKiBDaGVjayBpbiBjYXNlIHRoZSBjbGllbnQgYXJlYSBpcyBzbWFsbGVyIHRoYW4gdGhlIGNoZWNrYm94IGJpdG1hcCAqLwoJaWYgKGRlbHRhIDwgMCkgZGVsdGEgPSAwOwoKICAgICAgICBpZiAoYWN0aW9uID09IE9EQV9TRUxFQ1QpIEZpbGxSZWN0KCBoREMsICZyYm94LCBoQnJ1c2ggKTsKICAgICAgICBlbHNlIEZpbGxSZWN0KCBoREMsICZjbGllbnQsIGhCcnVzaCApOwoKICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpIHggKz0gMiAqIGNoZWNrQm94V2lkdGg7CiAgICAgICAgaWYgKGluZm9QdHItPnN0YXRlICYgKEJVVFRPTl9DSEVDS0VEIHwgQlVUVE9OXzNTVEFURSkpIHggKz0gY2hlY2tCb3hXaWR0aDsKICAgICAgICBpZiAoKCh3bmRQdHItPmR3U3R5bGUgJiAweDBmKSA9PSBCU19SQURJT0JVVFRPTikgfHwKICAgICAgICAgICAgKCh3bmRQdHItPmR3U3R5bGUgJiAweDBmKSA9PSBCU19BVVRPUkFESU9CVVRUT04pKSB5ICs9IGNoZWNrQm94SGVpZ2h0OwogICAgICAgIGVsc2UgaWYgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OXzNTVEFURSkgeSArPSAyICogY2hlY2tCb3hIZWlnaHQ7CgoJLyogVGhlIGJpdG1hcCBmb3IgdGhlIHJhZGlvIGJ1dHRvbiBpcyBub3QgYWxpZ25lZCB3aXRoIHRoZQoJICogbGVmdCBvZiB0aGUgd2luZG93LCBpdCBpcyAxIHBpeGVsIG9mZi4gKi8KICAgICAgICBpZiAoKCh3bmRQdHItPmR3U3R5bGUgJiAweDBmKSA9PSBCU19SQURJT0JVVFRPTikgfHwKICAgICAgICAgICAgKCh3bmRQdHItPmR3U3R5bGUgJiAweDBmKSA9PSBCU19BVVRPUkFESU9CVVRUT04pKQoJICByYm94LmxlZnQgKz0gMTsKCglTZWxlY3RPYmplY3QoIGhNZW1EQywgaGJpdG1hcENoZWNrQm94ZXMgKTsKCUJpdEJsdCggaERDLCByYm94LmxlZnQsIHJib3gudG9wICsgZGVsdGEsIGNoZWNrQm94V2lkdGgsCgkJICBjaGVja0JveEhlaWdodCwgaE1lbURDLCB4LCB5LCBTUkNDT1BZICk7CglEZWxldGVEQyggaE1lbURDICk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CgkgICAgVUlOVCBzdGF0ZTsKCiAgICAgICAgICAgIGlmICgoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX1JBRElPQlVUVE9OKSB8fAogICAgICAgICAgICAgICAgKCh3bmRQdHItPmR3U3R5bGUgJiAweDBmKSA9PSBCU19BVVRPUkFESU9CVVRUT04pKSBzdGF0ZSA9IERGQ1NfQlVUVE9OUkFESU87CiAgICAgICAgICAgIGVsc2UgaWYgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OXzNTVEFURSkgc3RhdGUgPSBERkNTX0JVVFRPTjNTVEFURTsKCSAgICBlbHNlIHN0YXRlID0gREZDU19CVVRUT05DSEVDSzsKCiAgICAgICAgICAgIGlmIChpbmZvUHRyLT5zdGF0ZSAmIChCVVRUT05fQ0hFQ0tFRCB8IEJVVFRPTl8zU1RBVEUpKSBzdGF0ZSB8PSBERkNTX0NIRUNLRUQ7CgkgICAgCgkgICAgaWYgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSBzdGF0ZSB8PSBERkNTX1BVU0hFRDsKCgkgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEKSBzdGF0ZSB8PSBERkNTX0lOQUNUSVZFOwoKCSAgICBEcmF3RnJhbWVDb250cm9sKCBoREMsICZyYm94LCBERkNfQlVUVE9OLCBzdGF0ZSApOwogICAgICAgIH0KCgogICAgICAgIGlmKCB0ZXh0bGVuICYmIGFjdGlvbiAhPSBPREFfU0VMRUNUICkKICAgICAgICB7CgkgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCAmJgoJICAgICAgR2V0U3lzQ29sb3IoQ09MT1JfR1JBWVRFWFQpPT1HZXRCa0NvbG9yKGhEQykpIHsKICAgICAgICAgICAgLyogZG9uJ3Qgd3JpdGUgZ3JheSB0ZXh0IG9uIGdyYXkgYmFja2dyb3VuZCAqLwogICAgICAgICAgICBQYWludEdyYXlPbkdyYXkoIGhEQywgaW5mb1B0ci0+aEZvbnQsICZydGV4dCwgd25kUHRyLT50ZXh0LAoJCQkgICAgIERUX1ZDRU5URVIpOwoJICB9IGVsc2UgewogICAgICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQpCiAgICAgICAgICAgICAgICBTZXRUZXh0Q29sb3IoIGhEQywgR2V0U3lzQ29sb3IoQ09MT1JfR1JBWVRFWFQpICk7CiAgICAgICAgICAgIERyYXdUZXh0QSggaERDLCB3bmRQdHItPnRleHQsIHRleHRsZW4sICZydGV4dCwKCQkJIERUX1NJTkdMRUxJTkUgfCBEVF9WQ0VOVEVSICk7CgkgIH0KICAgICAgICB9CiAgICB9CgogICAgaWYgKChhY3Rpb24gPT0gT0RBX0ZPQ1VTKSB8fAogICAgICAgICgoYWN0aW9uID09IE9EQV9EUkFXRU5USVJFKSAmJiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpKSkKICAgIHsKCS8qIGFnYWluLCB0aGlzIGlzIHdoYXQgQ1RMM0QgZXhwZWN0cyAqLwoKICAgICAgICBTZXRSZWN0RW1wdHkoJnJib3gpOwogICAgICAgIGlmKCB0ZXh0bGVuICkKICAgICAgICAgICAgRHJhd1RleHRBKCBoREMsIHduZFB0ci0+dGV4dCwgdGV4dGxlbiwgJnJib3gsCgkJCSBEVF9TSU5HTEVMSU5FIHwgRFRfQ0FMQ1JFQ1QgKTsKICAgICAgICB0ZXh0bGVuID0gcmJveC5ib3R0b20gLSByYm94LnRvcDsKICAgICAgICBkZWx0YSA9ICgocnRleHQuYm90dG9tIC0gcnRleHQudG9wKSAtIHRleHRsZW4pLzI7CiAgICAgICAgcmJveC5ib3R0b20gPSAocmJveC50b3AgPSBydGV4dC50b3AgKyBkZWx0YSAtIDEpICsgdGV4dGxlbiArIDI7CiAgICAgICAgdGV4dGxlbiA9IHJib3gucmlnaHQgLSByYm94LmxlZnQ7CiAgICAgICAgcmJveC5yaWdodCA9IChyYm94LmxlZnQgKz0gLS1ydGV4dC5sZWZ0KSArIHRleHRsZW4gKyAyOwogICAgICAgIEludGVyc2VjdFJlY3QoJnJib3gsICZyYm94LCAmcnRleHQpOwogICAgICAgIERyYXdGb2N1c1JlY3QoIGhEQywgJnJib3ggKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIEJVVFRPTl9DaGVja0F1dG9SYWRpb0J1dHRvbgogKgogKiB3bmRQdHIgaXMgY2hlY2tlZCwgdW5jaGVjayBldmVyeSBvdGhlciBhdXRvIHJhZGlvIGJ1dHRvbiBpbiBncm91cAogKi8Kc3RhdGljIHZvaWQgQlVUVE9OX0NoZWNrQXV0b1JhZGlvQnV0dG9uKCBXTkQgKnduZFB0ciApCnsKICAgIEhXTkQgcGFyZW50LCBzaWJsaW5nLCBzdGFydDsKICAgIGlmICghKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NISUxEKSkgcmV0dXJuOwogICAgcGFyZW50ID0gd25kUHRyLT5wYXJlbnQtPmh3bmRTZWxmOwogICAgLyogYXNzdXJlIHRoYXQgc3RhcnRpbmcgY29udHJvbCBpcyBub3QgZGlzYWJsZWQgb3IgaW52aXNpYmxlICovCiAgICBzdGFydCA9IHNpYmxpbmcgPSBHZXROZXh0RGxnR3JvdXBJdGVtKCBwYXJlbnQsIHduZFB0ci0+aHduZFNlbGYsIFRSVUUgKTsKICAgIGRvCiAgICB7CiAgICAgICAgV05EICp0bXBXbmQ7CiAgICAgICAgaWYgKCFzaWJsaW5nKSBicmVhazsKICAgICAgICB0bXBXbmQgPSBXSU5fRmluZFduZFB0cihzaWJsaW5nKTsKICAgICAgICBpZiAoKHduZFB0ci0+aHduZFNlbGYgIT0gc2libGluZykgJiYKICAgICAgICAgICAgKCh0bXBXbmQtPmR3U3R5bGUgJiAweDBmKSA9PSBCU19BVVRPUkFESU9CVVRUT04pKQogICAgICAgICAgICBTZW5kTWVzc2FnZUEoIHNpYmxpbmcsIEJNX1NFVENIRUNLLCBCVVRUT05fVU5DSEVDS0VELCAwICk7CiAgICAgICAgc2libGluZyA9IEdldE5leHREbGdHcm91cEl0ZW0oIHBhcmVudCwgc2libGluZywgRkFMU0UgKTsKICAgICAgICBXSU5fUmVsZWFzZVduZFB0cih0bXBXbmQpOwogICAgfSB3aGlsZSAoc2libGluZyAhPSBzdGFydCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICBHcm91cCBCb3ggRnVuY3Rpb25zCiAqLwoKc3RhdGljIHZvaWQgR0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApCnsKICAgIFJFQ1QgcmMsIHJjRnJhbWU7CiAgICBCVVRUT05JTkZPICppbmZvUHRyID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKCiAgICBpZiAoYWN0aW9uICE9IE9EQV9EUkFXRU5USVJFKSByZXR1cm47CgogICAgQlVUVE9OX1NFTkRfQ1RMQ09MT1IoIHduZFB0ciwgaERDICk7CgogICAgR2V0Q2xpZW50UmVjdCggd25kUHRyLT5od25kU2VsZiwgJnJjKTsKICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKSB7CiAgICAgICAgSFBFTiBoUHJldlBlbiA9IFNlbGVjdE9iamVjdCggaERDLAoJCQkJCSAgR2V0U3lzQ29sb3JQZW4oQ09MT1JfV0lORE9XRlJBTUUpKTsKCUhCUlVTSCBoUHJldkJydXNoID0gU2VsZWN0T2JqZWN0KCBoREMsCgkJCQkJICAgICAgR2V0U3RvY2tPYmplY3QoTlVMTF9CUlVTSCkgKTsKCglSZWN0YW5nbGUoIGhEQywgcmMubGVmdCwgcmMudG9wICsgMiwgcmMucmlnaHQgLSAxLCByYy5ib3R0b20gLSAxICk7CglTZWxlY3RPYmplY3QoIGhEQywgaFByZXZCcnVzaCApOwoJU2VsZWN0T2JqZWN0KCBoREMsIGhQcmV2UGVuICk7CiAgICB9IGVsc2UgewoJVEVYVE1FVFJJQ0EgdG07CglyY0ZyYW1lID0gcmM7CgoJaWYgKGluZm9QdHItPmhGb250KQoJICAgIFNlbGVjdE9iamVjdCAoaERDLCBpbmZvUHRyLT5oRm9udCk7CglHZXRUZXh0TWV0cmljc0EgKGhEQywgJnRtKTsKCXJjRnJhbWUudG9wICs9ICh0bS50bUhlaWdodCAvIDIpIC0gMTsKCURyYXdFZGdlIChoREMsICZyY0ZyYW1lLCBFREdFX0VUQ0hFRCwgQkZfUkVDVCk7CiAgICB9CgogICAgaWYgKHduZFB0ci0+dGV4dCkKICAgIHsKCWlmIChpbmZvUHRyLT5oRm9udCkgU2VsZWN0T2JqZWN0KCBoREMsIGluZm9QdHItPmhGb250ICk7CiAgICAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEKQogICAgICAgICAgICBTZXRUZXh0Q29sb3IoIGhEQywgR2V0U3lzQ29sb3IoQ09MT1JfR1JBWVRFWFQpICk7CiAgICAgICAgcmMubGVmdCArPSAxMDsKICAgICAgICBEcmF3VGV4dEEoIGhEQywgd25kUHRyLT50ZXh0LCAtMSwgJnJjLCBEVF9TSU5HTEVMSU5FIHwgRFRfTk9DTElQICk7CiAgICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICBVc2VyIEJ1dHRvbiBGdW5jdGlvbnMKICovCgpzdGF0aWMgdm9pZCBVQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICkKewogICAgUkVDVCByYzsKICAgIEhCUlVTSCBoQnJ1c2g7CiAgICBCVVRUT05JTkZPICppbmZvUHRyID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKCiAgICBpZiAoYWN0aW9uID09IE9EQV9TRUxFQ1QpIHJldHVybjsKCiAgICBHZXRDbGllbnRSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmcmMpOwoKICAgIGlmIChpbmZvUHRyLT5oRm9udCkgU2VsZWN0T2JqZWN0KCBoREMsIGluZm9QdHItPmhGb250ICk7CiAgICBoQnJ1c2ggPSBHZXRDb250cm9sQnJ1c2gxNiggd25kUHRyLT5od25kU2VsZiwgaERDLCBDVExDT0xPUl9CVE4gKTsKCiAgICBGaWxsUmVjdCggaERDLCAmcmMsIGhCcnVzaCApOwogICAgaWYgKChhY3Rpb24gPT0gT0RBX0ZPQ1VTKSB8fAogICAgICAgICgoYWN0aW9uID09IE9EQV9EUkFXRU5USVJFKSAmJiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpKSkKICAgICAgICBEcmF3Rm9jdXNSZWN0KCBoREMsICZyYyApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgT3duZXJkcmF3biBCdXR0b24gRnVuY3Rpb25zCiAqLwoKc3RhdGljIHZvaWQgT0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApCnsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwogICAgRFJBV0lURU1TVFJVQ1QgZGlzOwoKICAgIGRpcy5DdGxUeXBlICAgID0gT0RUX0JVVFRPTjsKICAgIGRpcy5DdGxJRCAgICAgID0gd25kUHRyLT53SURtZW51OwogICAgZGlzLml0ZW1JRCAgICAgPSAwOwogICAgZGlzLml0ZW1BY3Rpb24gPSBhY3Rpb247CiAgICBkaXMuaXRlbVN0YXRlICA9ICgoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpID8gT0RTX0ZPQ1VTIDogMCkgfAogICAgICAgICAgICAgICAgICAgICAoKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSA/IE9EU19TRUxFQ1RFRCA6IDApIHwKICAgICAgICAgICAgICAgICAgICAgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCkgPyBPRFNfRElTQUJMRUQgOiAwKTsKICAgIGRpcy5od25kSXRlbSAgID0gd25kUHRyLT5od25kU2VsZjsKICAgIGRpcy5oREMgICAgICAgID0gaERDOwogICAgZGlzLml0ZW1EYXRhICAgPSAwOwogICAgR2V0Q2xpZW50UmVjdCggd25kUHRyLT5od25kU2VsZiwgJmRpcy5yY0l0ZW0gKTsKCiAgICBTZXRCa0NvbG9yKCBoREMsIEdldFN5c0NvbG9yKCBDT0xPUl9CVE5GQUNFICkgKTsKCiAgICBTZW5kTWVzc2FnZUEoIEdldFBhcmVudCh3bmRQdHItPmh3bmRTZWxmKSwgV01fRFJBV0lURU0sCiAgICAgICAgICAgICAgICAgICAgd25kUHRyLT53SURtZW51LCAoTFBBUkFNKSZkaXMgKTsKfQoK