LyogRmlsZTogYnV0dG9uLmMgLS0gQnV0dG9uIHR5cGUgd2lkZ2V0cwogKgogKiBDb3B5cmlnaHQgKEMpIDE5OTMgSm9oYW5uZXMgUnVzY2hlaW5za2kKICogQ29weXJpZ2h0IChDKSAxOTkzIERhdmlkIE1ldGNhbGZlCiAqIENvcHlyaWdodCAoQykgMTk5NCBBbGV4YW5kcmUgSnVsbGlhcmQKICovCgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJ3aW4uaCIKI2luY2x1ZGUgImJ1dHRvbi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbmUvd2ludXNlcjE2LmgiCiNpbmNsdWRlICJ0d2Vhay5oIgoKc3RhdGljIHZvaWQgUGFpbnRHcmF5T25HcmF5KCBIREMgaERDLEhGT05UIGhGb250LFJFQ1QgKnJjLAoJCQkgICAgIGNoYXIgKnRleHQsIFVJTlQgZm9ybWF0ICk7CgpzdGF0aWMgdm9pZCBQQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICk7CnN0YXRpYyB2b2lkIENCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKTsKc3RhdGljIHZvaWQgR0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApOwpzdGF0aWMgdm9pZCBVQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICk7CnN0YXRpYyB2b2lkIE9CX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKTsKc3RhdGljIHZvaWQgQlVUVE9OX0NoZWNrQXV0b1JhZGlvQnV0dG9uKCBXTkQgKnduZFB0ciApOwpzdGF0aWMgdm9pZCBCVVRUT05fRHJhd1B1c2hCdXR0b24oIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiwgQk9PTCBwdXNoZWRTdGF0ZSk7CgojZGVmaW5lIE1BWF9CVE5fVFlQRSAgMTIKCnN0YXRpYyBjb25zdCBXT1JEIG1heENoZWNrU3RhdGVbTUFYX0JUTl9UWVBFXSA9CnsKICAgIEJVVFRPTl9VTkNIRUNLRUQsICAgLyogQlNfUFVTSEJVVFRPTiAqLwogICAgQlVUVE9OX1VOQ0hFQ0tFRCwgICAvKiBCU19ERUZQVVNIQlVUVE9OICovCiAgICBCVVRUT05fQ0hFQ0tFRCwgICAgIC8qIEJTX0NIRUNLQk9YICovCiAgICBCVVRUT05fQ0hFQ0tFRCwgICAgIC8qIEJTX0FVVE9DSEVDS0JPWCAqLwogICAgQlVUVE9OX0NIRUNLRUQsICAgICAvKiBCU19SQURJT0JVVFRPTiAqLwogICAgQlVUVE9OXzNTVEFURSwgICAgICAvKiBCU18zU1RBVEUgKi8KICAgIEJVVFRPTl8zU1RBVEUsICAgICAgLyogQlNfQVVUTzNTVEFURSAqLwogICAgQlVUVE9OX1VOQ0hFQ0tFRCwgICAvKiBCU19HUk9VUEJPWCAqLwogICAgQlVUVE9OX1VOQ0hFQ0tFRCwgICAvKiBCU19VU0VSQlVUVE9OICovCiAgICBCVVRUT05fQ0hFQ0tFRCwgICAgIC8qIEJTX0FVVE9SQURJT0JVVFRPTiAqLwogICAgQlVUVE9OX1VOQ0hFQ0tFRCwgICAvKiBOb3QgZGVmaW5lZCAqLwogICAgQlVUVE9OX1VOQ0hFQ0tFRCAgICAvKiBCU19PV05FUkRSQVcgKi8KfTsKCnR5cGVkZWYgdm9pZCAoKnBmUGFpbnQpKCBXTkQgKnduZFB0ciwgSERDIGhkYywgV09SRCBhY3Rpb24gKTsKCnN0YXRpYyBjb25zdCBwZlBhaW50IGJ0blBhaW50RnVuY1tNQVhfQlROX1RZUEVdID0KewogICAgUEJfUGFpbnQsICAgIC8qIEJTX1BVU0hCVVRUT04gKi8KICAgIFBCX1BhaW50LCAgICAvKiBCU19ERUZQVVNIQlVUVE9OICovCiAgICBDQl9QYWludCwgICAgLyogQlNfQ0hFQ0tCT1ggKi8KICAgIENCX1BhaW50LCAgICAvKiBCU19BVVRPQ0hFQ0tCT1ggKi8KICAgIENCX1BhaW50LCAgICAvKiBCU19SQURJT0JVVFRPTiAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTXzNTVEFURSAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX0FVVE8zU1RBVEUgKi8KICAgIEdCX1BhaW50LCAgICAvKiBCU19HUk9VUEJPWCAqLwogICAgVUJfUGFpbnQsICAgIC8qIEJTX1VTRVJCVVRUT04gKi8KICAgIENCX1BhaW50LCAgICAvKiBCU19BVVRPUkFESU9CVVRUT04gKi8KICAgIE5VTEwsICAgICAgICAvKiBOb3QgZGVmaW5lZCAqLwogICAgT0JfUGFpbnQgICAgIC8qIEJTX09XTkVSRFJBVyAqLwp9OwoKI2RlZmluZSBQQUlOVF9CVVRUT04od25kUHRyLHN0eWxlLGFjdGlvbikgXAogICAgIGlmIChidG5QYWludEZ1bmNbc3R5bGVdKSB7IFwKICAgICAgICAgSERDIGhkYyA9IEdldERDKCAod25kUHRyKS0+aHduZFNlbGYgKTsgXAogICAgICAgICAoYnRuUGFpbnRGdW5jW3N0eWxlXSkod25kUHRyLGhkYyxhY3Rpb24pOyBcCiAgICAgICAgIFJlbGVhc2VEQyggKHduZFB0ciktPmh3bmRTZWxmLCBoZGMgKTsgfQoKI2RlZmluZSBCVVRUT05fU0VORF9DVExDT0xPUih3bmRQdHIsaGRjKSBcCiAgICBTZW5kTWVzc2FnZUEoIEdldFBhcmVudCgod25kUHRyKS0+aHduZFNlbGYpLCBXTV9DVExDT0xPUkJUTiwgXAogICAgICAgICAgICAgICAgICAgIChoZGMpLCAod25kUHRyKS0+aHduZFNlbGYgKQoKc3RhdGljIEhCSVRNQVAgaGJpdG1hcENoZWNrQm94ZXMgPSAwOwpzdGF0aWMgV09SRCBjaGVja0JveFdpZHRoID0gMCwgY2hlY2tCb3hIZWlnaHQgPSAwOwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgQnV0dG9uV25kUHJvY19sb2NrZWQKICogCiAqIENhbGxlZCB3aXRoIHdpbmRvdyBsb2NrIGhlbGQuCiAqLwpzdGF0aWMgaW5saW5lIExSRVNVTFQgV0lOQVBJIEJ1dHRvblduZFByb2NfbG9ja2VkKFdORCogd25kUHRyLCBVSU5UIHVNc2csCgkJCQkJICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSApCnsKICAgIFJFQ1QgcmVjdDsKICAgIEhXTkQJaFduZCA9IHduZFB0ci0+aHduZFNlbGY7CiAgICBQT0lOVCBwdDsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwogICAgTE9ORyBzdHlsZSA9IHduZFB0ci0+ZHdTdHlsZSAmIDB4MGY7CiAgICBIQU5ETEUgb2xkSGJpdG1hcDsKCiAgICBwdC54ID0gTE9XT1JEKGxQYXJhbSk7CiAgICBwdC55ID0gSElXT1JEKGxQYXJhbSk7CgogICAgc3dpdGNoICh1TXNnKQogICAgewogICAgY2FzZSBXTV9HRVRETEdDT0RFOgogICAgICAgIHN3aXRjaChzdHlsZSkKICAgICAgICB7CiAgICAgICAgY2FzZSBCU19QVVNIQlVUVE9OOiAgICAgIHJldHVybiBETEdDX0JVVFRPTiB8IERMR0NfVU5ERUZQVVNIQlVUVE9OOwogICAgICAgIGNhc2UgQlNfREVGUFVTSEJVVFRPTjogICByZXR1cm4gRExHQ19CVVRUT04gfCBETEdDX0RFRlBVU0hCVVRUT047CiAgICAgICAgY2FzZSBCU19SQURJT0JVVFRPTjoKICAgICAgICBjYXNlIEJTX0FVVE9SQURJT0JVVFRPTjogcmV0dXJuIERMR0NfQlVUVE9OIHwgRExHQ19SQURJT0JVVFRPTjsKICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgcmV0dXJuIERMR0NfQlVUVE9OOwogICAgICAgIH0KCiAgICBjYXNlIFdNX0VOQUJMRToKICAgICAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9EUkFXRU5USVJFICk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9DUkVBVEU6CiAgICAgICAgaWYgKCFoYml0bWFwQ2hlY2tCb3hlcykKICAgICAgICB7CiAgICAgICAgICAgIEJJVE1BUCBibXA7CiAgICAgICAgICAgIGhiaXRtYXBDaGVja0JveGVzID0gTG9hZEJpdG1hcEEoMCwgTUFLRUlOVFJFU09VUkNFQShPQk1fQ0hFQ0tCT1hFUykpOwogICAgICAgICAgICBHZXRPYmplY3RBKCBoYml0bWFwQ2hlY2tCb3hlcywgc2l6ZW9mKGJtcCksICZibXAgKTsKICAgICAgICAgICAgY2hlY2tCb3hXaWR0aCAgPSBibXAuYm1XaWR0aCAvIDQ7CiAgICAgICAgICAgIGNoZWNrQm94SGVpZ2h0ID0gYm1wLmJtSGVpZ2h0IC8gMzsKICAgICAgICB9CiAgICAgICAgaWYgKHN0eWxlIDwgMEwgfHwgc3R5bGUgPj0gTUFYX0JUTl9UWVBFKQogICAgICAgICAgICByZXR1cm4gLTE7IC8qIGFib3J0ICovCiAgICAgICAgaW5mb1B0ci0+c3RhdGUgPSBCVVRUT05fVU5DSEVDS0VEOwogICAgICAgIGluZm9QdHItPmhGb250ID0gMDsKICAgICAgICBpbmZvUHRyLT5oSW1hZ2UgPSAwOwogICAgICAgIHJldHVybiAwOwoKICAgIGNhc2UgV01fRVJBU0VCS0dORDoKICAgICAgICByZXR1cm4gMTsKCiAgICBjYXNlIFdNX1BBSU5UOgogICAgICAgIGlmIChidG5QYWludEZ1bmNbc3R5bGVdKQogICAgICAgIHsKICAgICAgICAgICAgUEFJTlRTVFJVQ1QgcHM7CiAgICAgICAgICAgIEhEQyBoZGMgPSB3UGFyYW0gPyAoSERDKXdQYXJhbSA6IEJlZ2luUGFpbnQoIGhXbmQsICZwcyApOwogICAgICAgICAgICBpbnQgbk9sZE1vZGUgPSBTZXRCa01vZGUoIGhkYywgT1BBUVVFICk7CiAgICAgICAgICAgIChidG5QYWludEZ1bmNbc3R5bGVdKSggd25kUHRyLCBoZGMsIE9EQV9EUkFXRU5USVJFICk7CiAgICAgICAgICAgIFNldEJrTW9kZShoZGMsIG5PbGRNb2RlKTsgLyogIHJlc2V0IHBhaW50aW5nIG1vZGUgKi8KICAgICAgICAgICAgaWYoICF3UGFyYW0gKSBFbmRQYWludCggaFduZCwgJnBzICk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fS0VZRE9XTjoKCWlmICh3UGFyYW0gPT0gVktfU1BBQ0UpCgl7CgkgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRTVEFURSwgVFJVRSwgMCApOwoJICAgIGluZm9QdHItPnN0YXRlIHw9IEJVVFRPTl9CVE5QUkVTU0VEOwoJfQoJYnJlYWs7CgkKICAgIGNhc2UgV01fTEJVVFRPTkRCTENMSzoKICAgICAgICBpZih3bmRQdHItPmR3U3R5bGUgJiBCU19OT1RJRlkgfHwgCiAgICAgICAgICAgICAgICBzdHlsZT09QlNfUkFESU9CVVRUT04gfHwKICAgICAgICAgICAgICAgIHN0eWxlPT1CU19VU0VSQlVUVE9OIHx8CiAgICAgICAgICAgICAgICBzdHlsZT09QlNfT1dORVJEUkFXKSB7CiAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggR2V0UGFyZW50KGhXbmQpLCBXTV9DT01NQU5ELAogICAgICAgICAgICAgICAgICAgIE1BS0VXUEFSQU0oIHduZFB0ci0+d0lEbWVudSwgQk5fRE9VQkxFQ0xJQ0tFRCApLCBoV25kKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIC8qIGZhbGwgdGhyb3VnaCAqLwogICAgY2FzZSBXTV9MQlVUVE9ORE9XTjoKICAgICAgICBTZXRDYXB0dXJlKCBoV25kICk7CiAgICAgICAgU2V0Rm9jdXMoIGhXbmQgKTsKICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVFNUQVRFLCBUUlVFLCAwICk7CiAgICAgICAgaW5mb1B0ci0+c3RhdGUgfD0gQlVUVE9OX0JUTlBSRVNTRUQ7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9LRVlVUDoKCWlmICh3UGFyYW0gIT0gVktfU1BBQ0UpCgkgICAgYnJlYWs7CgkvKiBmYWxsIHRocm91Z2ggKi8KICAgIGNhc2UgV01fTEJVVFRPTlVQOgogICAgICAgIGlmICghKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0JUTlBSRVNTRUQpKSBicmVhazsKICAgICAgICBpbmZvUHRyLT5zdGF0ZSAmPSBCVVRUT05fTlNUQVRFUzsKICAgICAgICBpZiAoIShpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCkpIHsKICAgICAgICAgICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUU1RBVEUsIEZBTFNFLCAwICk7CiAgICAgICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgICAgICBHZXRDbGllbnRSZWN0KCBoV25kLCAmcmVjdCApOwoJaWYgKHVNc2cgPT0gV01fS0VZVVAgfHwgUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgIHsKICAgICAgICAgICAgc3dpdGNoKHN0eWxlKQogICAgICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgQlNfQVVUT0NIRUNLQk9YOgogICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRDSEVDSywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0NIRUNLRUQpLCAwICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBCU19BVVRPUkFESU9CVVRUT046CiAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVENIRUNLLCBUUlVFLCAwICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBCU19BVVRPM1NUQVRFOgogICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRDSEVDSywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fM1NUQVRFKSA/IDAgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoaW5mb1B0ci0+c3RhdGUgJiAzKSArIDEpLCAwICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBTZW5kTWVzc2FnZUEoIEdldFBhcmVudChoV25kKSwgV01fQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BS0VXUEFSQU0oIHduZFB0ci0+d0lEbWVudSwgQk5fQ0xJQ0tFRCApLCBoV25kKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9DQVBUVVJFQ0hBTkdFRDoKICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fQlROUFJFU1NFRCkgewogICAgICAgICAgICBpbmZvUHRyLT5zdGF0ZSAmPSBCVVRUT05fTlNUQVRFUzsKICAgICAgICAgICAgaWYgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSAKICAgICAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUU1RBVEUsIEZBTFNFLCAwICk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fTU9VU0VNT1ZFOgogICAgICAgIGlmIChHZXRDYXB0dXJlKCkgPT0gaFduZCkKICAgICAgICB7CiAgICAgICAgICAgIEdldENsaWVudFJlY3QoIGhXbmQsICZyZWN0ICk7CiAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUU1RBVEUsIFB0SW5SZWN0KCZyZWN0LCBwdCksIDAgKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9OQ0hJVFRFU1Q6CiAgICAgICAgaWYoc3R5bGUgPT0gQlNfR1JPVVBCT1gpIHJldHVybiBIVFRSQU5TUEFSRU5UOwogICAgICAgIHJldHVybiBEZWZXaW5kb3dQcm9jQSggaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0gKTsKCiAgICBjYXNlIFdNX1NFVFRFWFQ6CiAgICAgICAgREVGV05EX1NldFRleHQoIHduZFB0ciwgKExQQ1NUUilsUGFyYW0gKTsKCWlmKCB3bmRQdHItPmR3U3R5bGUgJiBXU19WSVNJQkxFICkKICAgICAgICAgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfRFJBV0VOVElSRSApOwogICAgICAgIHJldHVybiAwOwoKICAgIGNhc2UgV01fU0VURk9OVDoKICAgICAgICBpbmZvUHRyLT5oRm9udCA9IChIRk9OVDE2KXdQYXJhbTsKICAgICAgICBpZiAobFBhcmFtICYmICh3bmRQdHItPmR3U3R5bGUgJiBXU19WSVNJQkxFKSkgCgkgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfRFJBV0VOVElSRSApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fR0VURk9OVDoKICAgICAgICByZXR1cm4gaW5mb1B0ci0+aEZvbnQ7CgogICAgY2FzZSBXTV9TRVRGT0NVUzoKICAgICAgICBpZiAoKHN0eWxlID09IEJTX1JBRElPQlVUVE9OIHx8IHN0eWxlID09IEJTX0FVVE9SQURJT0JVVFRPTikgJiYgKEdldENhcHR1cmUoKSAhPSBoV25kKSAmJgogICAgICAgICAgICAhKFNlbmRNZXNzYWdlQShoV25kLCBCTV9HRVRDSEVDSywgMCwgMCkgJiBCU1RfQ0hFQ0tFRCkpCgl7CiAgICAgICAgICAgIC8qIFRoZSBub3RpZmljYXRpb24gaXMgc2VudCB3aGVuIHRoZSBidXR0b24gKEJTX0FVVE9SQURJT0JVVFRPTikgCiAgICAgICAgICAgICAgIGlzIHVuY2tlY2tlZCBhbmQgdGhlIGZvY3VzIHdhcyBub3QgZ2l2ZW4gYnkgYSBtb3VzZSBjbGljay4gKi8KCSAgICBpZiAoc3R5bGUgPT0gQlNfQVVUT1JBRElPQlVUVE9OKQoJCSAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVENIRUNLLCBCVVRUT05fQ0hFQ0tFRCwgMCApOwogICAgICAgICAgICBTZW5kTWVzc2FnZUEoIEdldFBhcmVudChoV25kKSwgV01fQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgICAgICBNQUtFV1BBUkFNKCB3bmRQdHItPndJRG1lbnUsIEJOX0NMSUNLRUQgKSwgaFduZCk7CiAgICAgICAgfQogICAgICAgIGluZm9QdHItPnN0YXRlIHw9IEJVVFRPTl9IQVNGT0NVUzsKICAgICAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9GT0NVUyApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fS0lMTEZPQ1VTOgogICAgICAgIGluZm9QdHItPnN0YXRlICY9IH5CVVRUT05fSEFTRk9DVVM7CglQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9GT0NVUyApOwoJSW52YWxpZGF0ZVJlY3QoIGhXbmQsIE5VTEwsIFRSVUUgKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX1NZU0NPTE9SQ0hBTkdFOgogICAgICAgIEludmFsaWRhdGVSZWN0KCBoV25kLCBOVUxMLCBGQUxTRSApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQk1fU0VUU1RZTEUxNjoKICAgIGNhc2UgQk1fU0VUU1RZTEU6CiAgICAgICAgaWYgKCh3UGFyYW0gJiAweDBmKSA+PSBNQVhfQlROX1RZUEUpIGJyZWFrOwogICAgICAgIHduZFB0ci0+ZHdTdHlsZSA9ICh3bmRQdHItPmR3U3R5bGUgJiAweGZmZmZmZmYwKSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAod1BhcmFtICYgMHgwMDAwMDAwZik7CiAgICAgICAgc3R5bGUgPSB3bmRQdHItPmR3U3R5bGUgJiAweDAwMDAwMDBmOwoKICAgICAgICAvKiBPbmx5IHJlZHJhdyBpZiBsUGFyYW0gZmxhZyBpcyBzZXQuKi8KICAgICAgICBpZiAobFBhcmFtKQogICAgICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX0RSQVdFTlRJUkUgKTsKCiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBCTV9DTElDSzoKCVNlbmRNZXNzYWdlQSggaFduZCwgV01fTEJVVFRPTkRPV04sIDAsIDAgKTsKCVNlbmRNZXNzYWdlQSggaFduZCwgV01fTEJVVFRPTlVQLCAwLCAwICk7CglicmVhazsKCiAgICBjYXNlIEJNX1NFVElNQUdFOgoJb2xkSGJpdG1hcCA9IGluZm9QdHItPmhJbWFnZTsKCWlmICgod25kUHRyLT5kd1N0eWxlICYgQlNfQklUTUFQKSB8fCAod25kUHRyLT5kd1N0eWxlICYgQlNfSUNPTikpCgl7CgkgICAgaW5mb1B0ci0+aEltYWdlID0gKEhBTkRMRSkgbFBhcmFtOwoJICAgIEludmFsaWRhdGVSZWN0KCBoV25kLCBOVUxMLCBGQUxTRSApOwoJfQoJcmV0dXJuIG9sZEhiaXRtYXA7CgogICAgY2FzZSBCTV9HRVRJTUFHRToKICAgICAgICBpZiAod1BhcmFtID09IElNQUdFX0JJVE1BUCkKCSAgICByZXR1cm4gKEhCSVRNQVApaW5mb1B0ci0+aEltYWdlOwoJZWxzZSBpZiAod1BhcmFtID09IElNQUdFX0lDT04pCgkgICAgcmV0dXJuIChISUNPTilpbmZvUHRyLT5oSW1hZ2U7CgllbHNlCgkgICAgcmV0dXJuIChISUNPTikwOwoKICAgIGNhc2UgQk1fR0VUQ0hFQ0sxNjoKICAgIGNhc2UgQk1fR0VUQ0hFQ0s6CiAgICAgICAgcmV0dXJuIGluZm9QdHItPnN0YXRlICYgMzsKCiAgICBjYXNlIEJNX1NFVENIRUNLMTY6CiAgICBjYXNlIEJNX1NFVENIRUNLOgogICAgICAgIGlmICh3UGFyYW0gPiBtYXhDaGVja1N0YXRlW3N0eWxlXSkgd1BhcmFtID0gbWF4Q2hlY2tTdGF0ZVtzdHlsZV07CiAgICAgICAgaWYgKChpbmZvUHRyLT5zdGF0ZSAmIDMpICE9IHdQYXJhbSkKICAgICAgICB7CgkgICAgaWYgKChzdHlsZSA9PSBCU19SQURJT0JVVFRPTikgfHwgKHN0eWxlID09IEJTX0FVVE9SQURJT0JVVFRPTikpCgkgICAgewoJCWlmICh3UGFyYW0pCgkJICAgIHduZFB0ci0+ZHdTdHlsZSB8PSBXU19UQUJTVE9QOwoJCWVsc2UKCQkgICAgd25kUHRyLT5kd1N0eWxlICY9IH5XU19UQUJTVE9QOwoJICAgIH0KICAgICAgICAgICAgaW5mb1B0ci0+c3RhdGUgPSAoaW5mb1B0ci0+c3RhdGUgJiB+MykgfCB3UGFyYW07CiAgICAgICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX1NFTEVDVCApOwogICAgICAgIH0KICAgICAgICBpZiAoKHN0eWxlID09IEJTX0FVVE9SQURJT0JVVFRPTikgJiYgKHdQYXJhbSA9PSBCVVRUT05fQ0hFQ0tFRCkpCiAgICAgICAgICAgIEJVVFRPTl9DaGVja0F1dG9SYWRpb0J1dHRvbiggd25kUHRyICk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBCTV9HRVRTVEFURTE2OgogICAgY2FzZSBCTV9HRVRTVEFURToKICAgICAgICByZXR1cm4gaW5mb1B0ci0+c3RhdGU7CgogICAgY2FzZSBCTV9TRVRTVEFURTE2OgogICAgY2FzZSBCTV9TRVRTVEFURToKICAgICAgICBpZiAod1BhcmFtKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSBicmVhazsKICAgICAgICAgICAgaW5mb1B0ci0+c3RhdGUgfD0gQlVUVE9OX0hJR0hMSUdIVEVEOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBpZiAoIShpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCkpIGJyZWFrOwogICAgICAgICAgICBpbmZvUHRyLT5zdGF0ZSAmPSB+QlVUVE9OX0hJR0hMSUdIVEVEOwogICAgICAgIH0KICAgICAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9TRUxFQ1QgKTsKICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBEZWZXaW5kb3dQcm9jQShoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBCdXR0b25XbmRQcm9jCiAqIFRoZSBidXR0b24gd2luZG93IHByb2NlZHVyZS4gVGhpcyBpcyBqdXN0IGEgd3JhcHBlciB3aGljaCBsb2NrcwogKiB0aGUgcGFzc2VkIEhXTkQgYW5kIGNhbGxzIHRoZSByZWFsIHdpbmRvdyBwcm9jZWR1cmUgKHdpdGggYSBXTkQqCiAqIHBvaW50ZXIgcG9pbnRpbmcgdG8gdGhlIGxvY2tlZCB3aW5kb3dzdHJ1Y3R1cmUpLgogKi8KTFJFU1VMVCBXSU5BUEkgQnV0dG9uV25kUHJvYyggSFdORCBoV25kLCBVSU5UIHVNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0gKQp7CiAgICBMUkVTVUxUIHJlczsKICAgIFdORCAqd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoaFduZCk7CgogICAgcmVzID0gQnV0dG9uV25kUHJvY19sb2NrZWQod25kUHRyLHVNc2csd1BhcmFtLGxQYXJhbSk7CgogICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKICAgIHJldHVybiByZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIFB1c2ggQnV0dG9uIEZ1bmN0aW9ucwogKi8Kc3RhdGljIHZvaWQgUEJfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApCnsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgICAgICA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CiAgICBCT09MICAgICAgICBiSGlnaExpZ2h0ZWQgPSAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpOwoKICAgIC8qIAogICAgICogRGVsZWdhdGUgdGhpcyB0byB0aGUgbW9yZSBnZW5lcmljIHB1c2hidXR0b24gcGFpbnRpbmcKICAgICAqIG1ldGhvZC4KICAgICAqLwogICAgQlVUVE9OX0RyYXdQdXNoQnV0dG9uKHduZFB0ciwKCQkJICBoREMsCgkJCSAgYWN0aW9uLAoJCQkgIGJIaWdoTGlnaHRlZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoaXMgbWV0aG9kIHdpbGwgYWN0dWFsbHkgZG8gdGhlIGRyYXdpbmcgb2YgdGhlIHB1c2hidXR0b24gCiAqIGRlcGVuZGluZyBvbiBpdCdzIHN0YXRlIGFuZCB0aGUgcHVzaGVkU3RhdGUgcGFyYW1ldGVyLgogKi8Kc3RhdGljIHZvaWQgQlVUVE9OX0RyYXdQdXNoQnV0dG9uKAogIFdORCogd25kUHRyLAogIEhEQyAgaERDLCAKICBXT1JEIGFjdGlvbiwgCiAgQk9PTCBwdXNoZWRTdGF0ZSApCnsKICAgIFJFQ1QgcmMsIGZvY3VzX3JlY3Q7CiAgICBIUEVOIGhPbGRQZW47CiAgICBIQlJVU0ggaE9sZEJydXNoOwogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CiAgICBpbnQgeEJvcmRlck9mZnNldCwgeUJvcmRlck9mZnNldDsKICAgIHhCb3JkZXJPZmZzZXQgPSB5Qm9yZGVyT2Zmc2V0ID0gMDsKCiAgICBHZXRDbGllbnRSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmcmMgKTsKCiAgICAgIC8qIFNlbmQgV01fQ1RMQ09MT1IgdG8gYWxsb3cgY2hhbmdpbmcgdGhlIGZvbnQgKHRoZSBjb2xvcnMgYXJlIGZpeGVkKSAqLwogICAgaWYgKGluZm9QdHItPmhGb250KSBTZWxlY3RPYmplY3QoIGhEQywgaW5mb1B0ci0+aEZvbnQgKTsKICAgIEJVVFRPTl9TRU5EX0NUTENPTE9SKCB3bmRQdHIsIGhEQyApOwogICAgaE9sZFBlbiA9IChIUEVOKVNlbGVjdE9iamVjdChoREMsIEdldFN5c0NvbG9yUGVuKENPTE9SX1dJTkRPV0ZSQU1FKSk7CiAgICBoT2xkQnJ1c2ggPShIQlJVU0gpU2VsZWN0T2JqZWN0KGhEQyxHZXRTeXNDb2xvckJydXNoKENPTE9SX0JUTkZBQ0UpKTsKICAgIFNldEJrTW9kZShoREMsIFRSQU5TUEFSRU5UKTsKCiAgICBpZiAoIFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCiAgICB7CiAgICAgICAgUmVjdGFuZ2xlKGhEQywgcmMubGVmdCwgcmMudG9wLCByYy5yaWdodCwgcmMuYm90dG9tKTsKCiAgICAgICAgU2V0UGl4ZWwoIGhEQywgcmMubGVmdCwgcmMudG9wLCBHZXRTeXNDb2xvcihDT0xPUl9XSU5ET1cpICk7CiAgICAgICAgU2V0UGl4ZWwoIGhEQywgcmMubGVmdCwgcmMuYm90dG9tLTEsIEdldFN5c0NvbG9yKENPTE9SX1dJTkRPVykgKTsKICAgICAgICBTZXRQaXhlbCggaERDLCByYy5yaWdodC0xLCByYy50b3AsIEdldFN5c0NvbG9yKENPTE9SX1dJTkRPVykgKTsKICAgICAgICBTZXRQaXhlbCggaERDLCByYy5yaWdodC0xLCByYy5ib3R0b20tMSwgR2V0U3lzQ29sb3IoQ09MT1JfV0lORE9XKSk7CglJbmZsYXRlUmVjdCggJnJjLCAtMSwgLTEgKTsKICAgIH0KICAgIAogICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiAweDAwMGYpID09IEJTX0RFRlBVU0hCVVRUT04pCiAgICB7CiAgICAgICAgUmVjdGFuZ2xlKGhEQywgcmMubGVmdCwgcmMudG9wLCByYy5yaWdodCwgcmMuYm90dG9tKTsKCUluZmxhdGVSZWN0KCAmcmMsIC0xLCAtMSApOwogICAgfQoKICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQogICAgewogICAgICAgIGlmIChwdXNoZWRTdGF0ZSkKCXsKCSAgICAvKiBkcmF3IGJ1dHRvbiBzaGFkb3c6ICovCgkgICAgU2VsZWN0T2JqZWN0KGhEQywgR2V0U3lzQ29sb3JCcnVzaChDT0xPUl9CVE5TSEFET1cpKTsKCSAgICBQYXRCbHQoaERDLCByYy5sZWZ0LCByYy50b3AsIDEsIHJjLmJvdHRvbS1yYy50b3AsIFBBVENPUFkgKTsKCSAgICBQYXRCbHQoaERDLCByYy5sZWZ0LCByYy50b3AsIHJjLnJpZ2h0LXJjLmxlZnQsIDEsIFBBVENPUFkgKTsKCSAgICByYy5sZWZ0ICs9IDI7ICAvKiBUbyBwb3NpdGlvbiB0aGUgdGV4dCBkb3duIGFuZCByaWdodCAqLwoJICAgIHJjLnRvcCAgKz0gMjsKCX0gZWxzZSB7CgkgICByYy5yaWdodCsrLCByYy5ib3R0b20rKzsKCSAgIERyYXdFZGdlKCBoREMsICZyYywgRURHRV9SQUlTRUQsIEJGX1JFQ1QgKTsKCgkgICAvKiBUbyBwbGFjZSBkZSBiaXRtYXAgY29ycmVjdGx5ICovCgkgICB4Qm9yZGVyT2Zmc2V0ICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hFREdFKTsKCSAgIHlCb3JkZXJPZmZzZXQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUVER0UpOwoKCSAgIHJjLnJpZ2h0LS0sIHJjLmJvdHRvbS0tOwoJfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIFVJTlQgdVN0YXRlID0gREZDU19CVVRUT05QVVNIOwoKICAgICAgICBpZiAocHVzaGVkU3RhdGUpCgl7CgkgICAgaWYgKCAod25kUHRyLT5kd1N0eWxlICYgMHgwMDBmKSA9PSBCU19ERUZQVVNIQlVUVE9OICkKCSAgICAgICAgdVN0YXRlIHw9IERGQ1NfRkxBVDsKCSAgICBlbHNlCgkgICAgICAgIHVTdGF0ZSB8PSBERkNTX1BVU0hFRDsKCX0KCglEcmF3RnJhbWVDb250cm9sKCBoREMsICZyYywgREZDX0JVVFRPTiwgdVN0YXRlICk7CglJbmZsYXRlUmVjdCggJnJjLCAtMiwgLTIgKTsKCglmb2N1c19yZWN0ID0gcmM7CgogICAgICAgIGlmIChwdXNoZWRTdGF0ZSkKCXsKCSAgICByYy5sZWZ0ICs9IDI7ICAvKiBUbyBwb3NpdGlvbiB0aGUgdGV4dCBkb3duIGFuZCByaWdodCAqLwoJICAgIHJjLnRvcCAgKz0gMjsKCX0KICAgIH0KCiAgICAvKiBkcmF3IGJ1dHRvbiBsYWJlbCwgaWYgYW55OgogICAgICoKICAgICAqIEluIHdpbjl4IHdlIGRvbid0IHNob3cgdGV4dCBpZiB0aGVyZSBpcyBhIGJpdG1hcCBvciBpY29uLgogICAgICogSSBkb24ndCBrbm93IGFib3V0IHdpbjMxIHNvIEkgbGVhdmUgaXQgYXMgaXQgd2FzIGZvciB3aW4zMS4KICAgICAqIERlbm5pcyBCavZya2x1bmQgMTIgSnVsLCA5OQogICAgICovCiAgICBpZiAoIHduZFB0ci0+dGV4dCAmJiB3bmRQdHItPnRleHRbMF0KCSAmJiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSyB8fCAhKHduZFB0ci0+ZHdTdHlsZSAmIChCU19JQ09OfEJTX0JJVE1BUCkpKSApCiAgICB7CiAgICAgICAgTE9HQlJVU0ggbGI7CiAgICAgICAgR2V0T2JqZWN0QSggR2V0U3lzQ29sb3JCcnVzaChDT0xPUl9CVE5GQUNFKSwgc2l6ZW9mKGxiKSwgJmxiICk7CiAgICAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEICYmCiAgICAgICAgICAgIEdldFN5c0NvbG9yKENPTE9SX0dSQVlURVhUKT09bGIubGJDb2xvcikKICAgICAgICAgICAgLyogZG9uJ3Qgd3JpdGUgZ3JheSB0ZXh0IG9uIGdyYXkgYmFja2dyb3VuZCAqLwogICAgICAgICAgICBQYWludEdyYXlPbkdyYXkoIGhEQyxpbmZvUHRyLT5oRm9udCwmcmMsd25kUHRyLT50ZXh0LAoJCQkgICAgICAgRFRfQ0VOVEVSIHwgRFRfVkNFTlRFUiApOwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFNldFRleHRDb2xvciggaERDLCAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQpID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0U3lzQ29sb3IoQ09MT1JfR1JBWVRFWFQpIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0U3lzQ29sb3IoQ09MT1JfQlROVEVYVCkgKTsKICAgICAgICAgICAgRHJhd1RleHRBKCBoREMsIHduZFB0ci0+dGV4dCwgLTEsICZyYywKICAgICAgICAgICAgICAgICAgICAgICAgIERUX1NJTkdMRUxJTkUgfCBEVF9DRU5URVIgfCBEVF9WQ0VOVEVSICk7CiAgICAgICAgICAgIC8qIGRvIHdlIGhhdmUgdGhlIGZvY3VzPwoJICAgICAqIFdpbjl4IGRyYXdzIGZvY3VzIGxhc3Qgd2l0aCBhIHNpemUgcHJvcC4gdG8gdGhlIGJ1dHRvbgoJICAgICAqLwogICAgICAgICAgICBpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSwoJCSYmIGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hBU0ZPQ1VTKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSRUNUIHIgPSB7IDAsIDAsIDAsIDAgfTsKICAgICAgICAgICAgICAgIElOVCB4ZGVsdGEsIHlkZWx0YTsKCiAgICAgICAgICAgICAgICBEcmF3VGV4dEEoIGhEQywgd25kUHRyLT50ZXh0LCAtMSwgJnIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfU0lOR0xFTElORSB8IERUX0NBTENSRUNUICk7CiAgICAgICAgICAgICAgICB4ZGVsdGEgPSAoKHJjLnJpZ2h0IC0gcmMubGVmdCkgLSAoci5yaWdodCAtIHIubGVmdCkgLSAxKSAvIDI7CiAgICAgICAgICAgICAgICB5ZGVsdGEgPSAoKHJjLmJvdHRvbSAtIHJjLnRvcCkgLSAoci5ib3R0b20gLSByLnRvcCkgLSAxKSAvIDI7CiAgICAgICAgICAgICAgICBpZiAoeGRlbHRhIDwgMCkgeGRlbHRhID0gMDsKICAgICAgICAgICAgICAgIGlmICh5ZGVsdGEgPCAwKSB5ZGVsdGEgPSAwOwogICAgICAgICAgICAgICAgSW5mbGF0ZVJlY3QoICZyYywgLXhkZWx0YSwgLXlkZWx0YSApOwogICAgICAgICAgICAgICAgRHJhd0ZvY3VzUmVjdCggaERDLCAmcmMgKTsKICAgICAgICAgICAgfQogICAgICAgIH0gICAKICAgIH0KICAgIGlmICggKCh3bmRQdHItPmR3U3R5bGUgJiBCU19JQ09OKSB8fCAod25kUHRyLT5kd1N0eWxlICYgQlNfQklUTUFQKSApICYmCgkgKGluZm9QdHItPmhJbWFnZSAhPSAwKSApCiAgICB7CglpbnQgeU9mZnNldCwgeE9mZnNldDsKCWludCBpbWFnZVdpZHRoLCBpbWFnZUhlaWdodDsKCgkvKgoJICogV2UgZXh0cmFjdCB0aGUgc2l6ZSBvZiB0aGUgaW1hZ2UgZnJvbSB0aGUgaGFuZGxlLgoJICovCglpZiAod25kUHRyLT5kd1N0eWxlICYgQlNfSUNPTikKCXsKCSAgICBJQ09OSU5GTyBpY29uSW5mbzsKCSAgICBCSVRNQVAgICBibTsKCgkgICAgR2V0SWNvbkluZm8oKEhJQ09OKWluZm9QdHItPmhJbWFnZSwgJmljb25JbmZvKTsKCSAgICBHZXRPYmplY3RBIChpY29uSW5mby5oYm1Db2xvciwgc2l6ZW9mKEJJVE1BUCksICZibSk7CgkgICAgCgkgICAgaW1hZ2VXaWR0aCAgPSBibS5ibVdpZHRoOwoJICAgIGltYWdlSGVpZ2h0ID0gYm0uYm1IZWlnaHQ7CgogICAgICAgICAgICBEZWxldGVPYmplY3QoaWNvbkluZm8uaGJtQ29sb3IpOwogICAgICAgICAgICBEZWxldGVPYmplY3QoaWNvbkluZm8uaGJtTWFzayk7CgoJfQoJZWxzZQoJewoJICAgIEJJVE1BUCAgIGJtOwoKCSAgICBHZXRPYmplY3RBIChpbmZvUHRyLT5oSW1hZ2UsIHNpemVvZihCSVRNQVApLCAmYm0pOwoJCgkgICAgaW1hZ2VXaWR0aCAgPSBibS5ibVdpZHRoOwoJICAgIGltYWdlSGVpZ2h0ID0gYm0uYm1IZWlnaHQ7Cgl9CgoJLyogQ2VudGVyIHRoZSBiaXRtYXAgKi8KCXhPZmZzZXQgPSAoKChyYy5yaWdodCAtIHJjLmxlZnQpIC0gMip4Qm9yZGVyT2Zmc2V0KSAtIGltYWdlV2lkdGggKSAvIDI7Cgl5T2Zmc2V0ID0gKCgocmMuYm90dG9tIC0gcmMudG9wKSAtIDIqeUJvcmRlck9mZnNldCkgLSBpbWFnZUhlaWdodCkgLyAyOwoKCS8qIElmIHRoZSBpbWFnZSBpcyB0b28gYmlnIGZvciB0aGUgYnV0dG9uIHRoZW4gY3JlYXRlIGEgcmVnaW9uKi8KICAgICAgICBpZih4T2Zmc2V0IDwgMCB8fCB5T2Zmc2V0IDwgMCkKCXsKICAgICAgICAgICAgSFJHTiBoQml0bWFwUmduID0gMDsKICAgICAgICAgICAgaEJpdG1hcFJnbiA9IENyZWF0ZVJlY3RSZ24oCiAgICAgICAgICAgICAgICByYy5sZWZ0ICsgeEJvcmRlck9mZnNldCwgcmMudG9wICt5Qm9yZGVyT2Zmc2V0LCAKICAgICAgICAgICAgICAgIHJjLnJpZ2h0IC0geEJvcmRlck9mZnNldCwgcmMuYm90dG9tIC0geUJvcmRlck9mZnNldCk7CiAgICAgICAgICAgIFNlbGVjdENsaXBSZ24oaERDLCBoQml0bWFwUmduKTsKICAgICAgICAgICAgRGVsZXRlT2JqZWN0KGhCaXRtYXBSZ24pOwoJfQoKCS8qIExldCBtaW5pbXVtIDEgc3BhY2UgZnJvbSBib3JkZXIgKi8KCXhPZmZzZXQrKywgeU9mZnNldCsrOwoKCS8qCgkgKiBEcmF3IHRoZSBpbWFnZSBub3cuCgkgKi8KCWlmICh3bmRQdHItPmR3U3R5bGUgJiBCU19JQ09OKQoJewogIAkgICAgRHJhd0ljb24oaERDLAogICAgICAgICAgICAgICAgcmMubGVmdCArIHhPZmZzZXQsIHJjLnRvcCArIHlPZmZzZXQsCgkJICAgICAoSElDT04paW5mb1B0ci0+aEltYWdlKTsKCX0KCWVsc2UKICAgICAgICB7CgkgICAgSERDIGhkY01lbTsKCgkgICAgaGRjTWVtID0gQ3JlYXRlQ29tcGF0aWJsZURDIChoREMpOwoJICAgIFNlbGVjdE9iamVjdCAoaGRjTWVtLCAoSEJJVE1BUClpbmZvUHRyLT5oSW1hZ2UpOwoJICAgIEJpdEJsdChoREMsIAoJCSAgIHJjLmxlZnQgKyB4T2Zmc2V0LCAKCQkgICByYy50b3AgKyB5T2Zmc2V0LCAKCQkgICBpbWFnZVdpZHRoLCBpbWFnZUhlaWdodCwKCQkgICBoZGNNZW0sIDAsIDAsIFNSQ0NPUFkpOwoJICAgIAoJICAgIERlbGV0ZURDIChoZGNNZW0pOwoJfQoKICAgICAgICBpZih4T2Zmc2V0IDwgMCB8fCB5T2Zmc2V0IDwgMCkKICAgICAgICB7CiAgICAgICAgICAgIFNlbGVjdENsaXBSZ24oaERDLCAwKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKFRXRUFLX1dpbmVMb29rICE9IFdJTjMxX0xPT0sKCSYmIGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hBU0ZPQ1VTKQogICAgewogICAgICAgIEluZmxhdGVSZWN0KCAmZm9jdXNfcmVjdCwgLTEsIC0xICk7CiAgICAgICAgRHJhd0ZvY3VzUmVjdCggaERDLCAmZm9jdXNfcmVjdCApOwogICAgfQoKICAgIAogICAgU2VsZWN0T2JqZWN0KCBoREMsIGhPbGRQZW4gKTsKICAgIFNlbGVjdE9iamVjdCggaERDLCBoT2xkQnJ1c2ggKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgUEJfUGFpbnQgJiBDQl9QYWludCBzdWIgZnVuY3Rpb24gICAgICAgICAgICAgICAgICAgICAgICBbaW50ZXJuYWxdCiAqICAgUGFpbnQgdGV4dCB1c2luZyBhIHJhc3RlciBicnVzaCB0byBhdm9pZCBncmF5IHRleHQgb24gZ3JheSAKICogICBiYWNrZ3JvdW5kLiAnZm9ybWF0JyBjYW4gYmUgYSBjb21iaW5hdGlvbiBvZiBEVF9DRU5URVIgYW5kIAogKiAgIERUX1ZDRU5URVIgdG8gdXNlIHRoaXMgZnVuY3Rpb24gaW4gYm90aCBQQl9QQUlOVCBhbmQgCiAqICAgQ0JfUEFJTlQuICAgLSBEaXJrIFRoaWVyYmFjaAogKgogKiAgIEZJWE1FOiBUaGlzIGFuZCBURVhUX0dyYXlTdHJpbmcgc2hvdWxkIGJlIGV2ZW50dWFsbHkgY29tYmluZWQsCiAqICAgc28gY2FsbGluZyBvbmUgY29tbW9uIGZ1bmN0aW9uIGZyb20gUEJfUGFpbnQsIENCX1BhaW50IGFuZAogKiAgIFRFWFRfR3JheVN0cmluZyB3aWxsIGJlIGVub3VnaC4gQWxzbyBub3RlIHRoYXQgdGhpcwogKiAgIGZ1bmN0aW9uIGlnbm9yZXMgdGhlIENBQ0hFX0dldFBhdHRlcm4gZnVuY3MuCiAqLwoKdm9pZCBQYWludEdyYXlPbkdyYXkoSERDIGhEQyxIRk9OVCBoRm9udCxSRUNUICpyYyxjaGFyICp0ZXh0LAoJCQlVSU5UIGZvcm1hdCkKewovKiAgVGhpcyBpcyB0aGUgc3RhbmRhcmQgZ3JheSBvbiBncmF5IHBhdHRlcm46CiAgICBzdGF0aWMgY29uc3QgV09SRCBQYXR0ZXJuW10gPSB7MHhBQSwweDU1LDB4QUEsMHg1NSwweEFBLDB4NTUsMHhBQSwweDU1fTsgCiovCi8qICBUaGlzIHBhdHRlcm4gZ2l2ZXMgYmV0dGVyIHJlYWRhYmlsaXR5IHdpdGggWCBGb250cy4KICAgIEZJWE1FOiBNYXliZSB0aGUgdXNlciBzaG91bGQgYmUgYWxsb3dlZCB0byBkZWNpZGUgd2hpY2ggaGUgd2FudHMuICovCiAgICBzdGF0aWMgY29uc3QgV09SRCBQYXR0ZXJuW10gPSB7MHg1NSwweEZGLDB4QUEsMHhGRiwweDU1LDB4RkYsMHhBQSwweEZGfTsgCgogICAgSEJJVE1BUCBoYm0gID0gQ3JlYXRlQml0bWFwKCA4LCA4LCAxLCAxLCBQYXR0ZXJuICk7CiAgICBIREMgaGRjTWVtID0gQ3JlYXRlQ29tcGF0aWJsZURDKGhEQyk7CiAgICBIQklUTUFQIGhibU1lbTsKICAgIEhCUlVTSCBoQnI7CiAgICBSRUNUIHJlY3QscmMyOwoKICAgIHJlY3Q9KnJjOwogICAgRHJhd1RleHRBKCBoREMsIHRleHQsIC0xLCAmcmVjdCwgRFRfU0lOR0xFTElORSB8IERUX0NBTENSRUNUKTsKICAgIC8qIG5vdyB0ZXh0IHdpZHRoIGFuZCBoZWlnaHQgYXJlIGluIHJlY3QucmlnaHQgYW5kIHJlY3QuYm90dG9tICovCiAgICByYzI9cmVjdDsKICAgIHJlY3QubGVmdCA9IHJlY3QudG9wID0gMDsgLyogZHJhd2luZyBwb3MgaW4gaGRjTWVtICovCiAgICBpZiAoZm9ybWF0ICYgRFRfQ0VOVEVSKSByZWN0LmxlZnQ9KHJjLT5yaWdodC1yZWN0LnJpZ2h0KS8yOwogICAgaWYgKGZvcm1hdCAmIERUX1ZDRU5URVIpIHJlY3QudG9wPShyYy0+Ym90dG9tLXJlY3QuYm90dG9tKS8yOwogICAgaGJtTWVtID0gQ3JlYXRlQ29tcGF0aWJsZUJpdG1hcCggaERDLHJlY3QucmlnaHQscmVjdC5ib3R0b20gKTsKICAgIFNlbGVjdE9iamVjdCggaGRjTWVtLCBoYm1NZW0pOwogICAgUGF0Qmx0KCBoZGNNZW0sMCwwLHJlY3QucmlnaHQscmVjdC5ib3R0b20sV0hJVEVORVNTKTsKICAgICAgLyogd2lsbCBiZSBvdmVyd3JpdHRlbiBieSBEcmF3VGV4dCwgYnV0IGp1c3QgaW4gY2FzZSAqLwogICAgaWYgKGhGb250KSBTZWxlY3RPYmplY3QoIGhkY01lbSwgaEZvbnQpOwogICAgRHJhd1RleHRBKCBoZGNNZW0sIHRleHQsIC0xLCAmcmMyLCBEVF9TSU5HTEVMSU5FKTsgIAogICAgICAvKiBBZnRlciBkcmF3OiBmb3JlZ3JvdW5kID0gMCBiaXRzLCBiYWNrZ3JvdW5kID0gMSBiaXRzICovCiAgICBoQnIgPSBTZWxlY3RPYmplY3QoIGhkY01lbSwgQ3JlYXRlUGF0dGVybkJydXNoKGhibSkgKTsKICAgIERlbGV0ZU9iamVjdCggaGJtICk7CiAgICBQYXRCbHQoIGhkY01lbSwwLDAscmVjdC5yaWdodCxyZWN0LmJvdHRvbSwweEFGMDIyOSk7IAogICAgICAvKiBvbmx5IGtlZXAgdGhlIGZvcmVncm91bmQgYml0cyB3aGVyZSBwYXR0ZXJuIGlzIDEgKi8KICAgIERlbGV0ZU9iamVjdCggU2VsZWN0T2JqZWN0KCBoZGNNZW0saEJyKSApOwogICAgQml0Qmx0KGhEQyxyZWN0LmxlZnQscmVjdC50b3AscmVjdC5yaWdodCxyZWN0LmJvdHRvbSxoZGNNZW0sMCwwLFNSQ0FORCk7CiAgICAgIC8qIGtlZXAgdGhlIGJhY2tncm91bmQgb2YgdGhlIGRlc3QgKi8KICAgIERlbGV0ZURDKCBoZGNNZW0pOwogICAgRGVsZXRlT2JqZWN0KCBoYm1NZW0gKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIENoZWNrIEJveCAmIFJhZGlvIEJ1dHRvbiBGdW5jdGlvbnMKICovCgpzdGF0aWMgdm9pZCBDQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICkKewogICAgUkVDVCByYm94LCBydGV4dCwgY2xpZW50OwogICAgSEJSVVNIIGhCcnVzaDsKICAgIGludCB0ZXh0bGVuLCBkZWx0YTsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwoKICAgIC8qIAogICAgICogaWYgdGhlIGJ1dHRvbiBoYXMgYSBiaXRtYXAvaWNvbiwgZHJhdyBhIG5vcm1hbCBwdXNoYnV0dG9uCiAgICAgKiBpbnN0ZWFkIG9mIGEgcmFkaW9uIGJ1dHRvbi4KICAgICAqLwogICAgaWYgKGluZm9QdHItPmhJbWFnZSAhPSAwKQogICAgewogICAgICAgIEJPT0wgYkhpZ2hMaWdodGVkID0gKChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCkgfHwKCQkJICAgICAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fQ0hFQ0tFRCkpOwoKICAgICAgICBCVVRUT05fRHJhd1B1c2hCdXR0b24od25kUHRyLAoJCQkgICAgICBoREMsCgkJCSAgICAgIGFjdGlvbiwKCQkJICAgICAgYkhpZ2hMaWdodGVkKTsKCXJldHVybjsKICAgIH0KCiAgICB0ZXh0bGVuID0gMDsKICAgIEdldENsaWVudFJlY3Qod25kUHRyLT5od25kU2VsZiwgJmNsaWVudCk7CiAgICByYm94ID0gcnRleHQgPSBjbGllbnQ7CgogICAgaWYgKGluZm9QdHItPmhGb250KSBTZWxlY3RPYmplY3QoIGhEQywgaW5mb1B0ci0+aEZvbnQgKTsKCiAgICAvKiBTb21ldGhpbmcgaXMgc3RpbGwgbm90IHJpZ2h0LCBjaGVja2JveGVzIChhbmQgZWRpdCBjb250cm9scykKICAgICAqIGluIHdzcGluZzMyIGhhdmUgd2hpdGUgYmFja2dyb3VuZHMgaW5zdGVhZCBvZiBkYXJrIGdyZXkuCiAgICAgKiBCVVRUT05fU0VORF9DVExDT0xPUigpIGlzIGV2ZW4gd29yc2Ugc2luY2UgaXQgcmV0dXJucyAwIGluIHRoaXMKICAgICAqIHBhcnRpY3VsYXIgY2FzZSBhbmQgdGhlIGJhY2tncm91bmQgaXMgbm90IHBhaW50ZWQgYXQgYWxsLgogICAgICovCgogICAgaEJydXNoID0gR2V0Q29udHJvbEJydXNoMTYoIHduZFB0ci0+aHduZFNlbGYsIGhEQywgQ1RMQ09MT1JfQlROICk7CgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0xFRlRURVhUKSAKICAgIHsKCS8qIG1hZ2ljICs0IGlzIHdoYXQgQ1RMM0QgZXhwZWN0cyAqLwoKICAgICAgICBydGV4dC5yaWdodCAtPSBjaGVja0JveFdpZHRoICsgNDsKICAgICAgICByYm94LmxlZnQgPSByYm94LnJpZ2h0IC0gY2hlY2tCb3hXaWR0aDsKICAgIH0KICAgIGVsc2UgCiAgICB7CiAgICAgICAgcnRleHQubGVmdCArPSBjaGVja0JveFdpZHRoICsgNDsKICAgICAgICByYm94LnJpZ2h0ID0gY2hlY2tCb3hXaWR0aDsKICAgIH0KCiAgICAgIC8qIERyYXcgdGhlIGNoZWNrLWJveCBiaXRtYXAgKi8KCiAgICBpZiAod25kUHRyLT50ZXh0KSB0ZXh0bGVuID0gc3RybGVuKCB3bmRQdHItPnRleHQgKTsKICAgIGlmIChhY3Rpb24gPT0gT0RBX0RSQVdFTlRJUkUgfHwgYWN0aW9uID09IE9EQV9TRUxFQ1QpCiAgICB7IAogICAgICAgIGlmKCBUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LICkKICAgICAgICB7CiAgICAgICAgSERDIGhNZW1EQyA9IENyZWF0ZUNvbXBhdGlibGVEQyggaERDICk7CiAgICAgICAgaW50IHggPSAwLCB5ID0gMDsKICAgICAgICBkZWx0YSA9IChyYm94LmJvdHRvbSAtIHJib3gudG9wIC0gY2hlY2tCb3hIZWlnaHQpIC8gMjsKCgkvKiBDaGVjayBpbiBjYXNlIHRoZSBjbGllbnQgYXJlYSBpcyBzbWFsbGVyIHRoYW4gdGhlIGNoZWNrYm94IGJpdG1hcCAqLwoJaWYgKGRlbHRhIDwgMCkgZGVsdGEgPSAwOwoKICAgICAgICBpZiAoYWN0aW9uID09IE9EQV9TRUxFQ1QpIEZpbGxSZWN0KCBoREMsICZyYm94LCBoQnJ1c2ggKTsKICAgICAgICBlbHNlIEZpbGxSZWN0KCBoREMsICZjbGllbnQsIGhCcnVzaCApOwoKICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpIHggKz0gMiAqIGNoZWNrQm94V2lkdGg7CiAgICAgICAgaWYgKGluZm9QdHItPnN0YXRlICYgKEJVVFRPTl9DSEVDS0VEIHwgQlVUVE9OXzNTVEFURSkpIHggKz0gY2hlY2tCb3hXaWR0aDsKICAgICAgICBpZiAoKCh3bmRQdHItPmR3U3R5bGUgJiAweDBmKSA9PSBCU19SQURJT0JVVFRPTikgfHwKICAgICAgICAgICAgKCh3bmRQdHItPmR3U3R5bGUgJiAweDBmKSA9PSBCU19BVVRPUkFESU9CVVRUT04pKSB5ICs9IGNoZWNrQm94SGVpZ2h0OwogICAgICAgIGVsc2UgaWYgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OXzNTVEFURSkgeSArPSAyICogY2hlY2tCb3hIZWlnaHQ7CgoJLyogVGhlIGJpdG1hcCBmb3IgdGhlIHJhZGlvIGJ1dHRvbiBpcyBub3QgYWxpZ25lZCB3aXRoIHRoZQoJICogbGVmdCBvZiB0aGUgd2luZG93LCBpdCBpcyAxIHBpeGVsIG9mZi4gKi8KICAgICAgICBpZiAoKCh3bmRQdHItPmR3U3R5bGUgJiAweDBmKSA9PSBCU19SQURJT0JVVFRPTikgfHwKICAgICAgICAgICAgKCh3bmRQdHItPmR3U3R5bGUgJiAweDBmKSA9PSBCU19BVVRPUkFESU9CVVRUT04pKQoJICByYm94LmxlZnQgKz0gMTsKCglTZWxlY3RPYmplY3QoIGhNZW1EQywgaGJpdG1hcENoZWNrQm94ZXMgKTsKCUJpdEJsdCggaERDLCByYm94LmxlZnQsIHJib3gudG9wICsgZGVsdGEsIGNoZWNrQm94V2lkdGgsCgkJICBjaGVja0JveEhlaWdodCwgaE1lbURDLCB4LCB5LCBTUkNDT1BZICk7CglEZWxldGVEQyggaE1lbURDICk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CgkgICAgVUlOVCBzdGF0ZTsKCiAgICAgICAgICAgIGlmICgoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX1JBRElPQlVUVE9OKSB8fAogICAgICAgICAgICAgICAgKCh3bmRQdHItPmR3U3R5bGUgJiAweDBmKSA9PSBCU19BVVRPUkFESU9CVVRUT04pKSBzdGF0ZSA9IERGQ1NfQlVUVE9OUkFESU87CiAgICAgICAgICAgIGVsc2UgaWYgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OXzNTVEFURSkgc3RhdGUgPSBERkNTX0JVVFRPTjNTVEFURTsKCSAgICBlbHNlIHN0YXRlID0gREZDU19CVVRUT05DSEVDSzsKCiAgICAgICAgICAgIGlmIChpbmZvUHRyLT5zdGF0ZSAmIChCVVRUT05fQ0hFQ0tFRCB8IEJVVFRPTl8zU1RBVEUpKSBzdGF0ZSB8PSBERkNTX0NIRUNLRUQ7CgkgICAgCgkgICAgaWYgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSBzdGF0ZSB8PSBERkNTX1BVU0hFRDsKCgkgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEKSBzdGF0ZSB8PSBERkNTX0lOQUNUSVZFOwoKCSAgICAvKiByYm94IG11c3QgaGF2ZSB0aGUgY29ycmVjdCBoZWlnaHQgKi8gCiAJICAgIGRlbHRhID0gcmJveC5ib3R0b20gLSByYm94LnRvcCAtIGNoZWNrQm94SGVpZ2h0OwoJICAgIGlmIChkZWx0YSA+IDApIAoJICAgIHsgIAoJCWludCBvZnMgPSAoYWJzKGRlbHRhKSAvIDIpOwoJCXJib3guYm90dG9tIC09IG9mcyArIDE7CgkJcmJveC50b3AgPSByYm94LmJvdHRvbSAtIGNoZWNrQm94SGVpZ2h0OwoJICAgIH0KCSAgICBlbHNlIGlmIChkZWx0YSA8IDApCgkgICAgewoJCWludCBvZnMgPSAoYWJzKGRlbHRhKSAvIDIpOwoJCXJib3gudG9wIC09IG9mcyArIDE7CgkJcmJveC5ib3R0b20gPSByYm94LnRvcCArIGNoZWNrQm94SGVpZ2h0OwoJICAgIH0KCgkgICAgRHJhd0ZyYW1lQ29udHJvbCggaERDLCAmcmJveCwgREZDX0JVVFRPTiwgc3RhdGUgKTsKICAgICAgICB9CgogICAgICAgIGlmKCB0ZXh0bGVuICYmIGFjdGlvbiAhPSBPREFfU0VMRUNUICkKICAgICAgICB7CgkgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCAmJgoJICAgICAgR2V0U3lzQ29sb3IoQ09MT1JfR1JBWVRFWFQpPT1HZXRCa0NvbG9yKGhEQykpIHsKICAgICAgICAgICAgLyogZG9uJ3Qgd3JpdGUgZ3JheSB0ZXh0IG9uIGdyYXkgYmFja2dyb3VuZCAqLwogICAgICAgICAgICBQYWludEdyYXlPbkdyYXkoIGhEQywgaW5mb1B0ci0+aEZvbnQsICZydGV4dCwgd25kUHRyLT50ZXh0LAoJCQkgICAgIERUX1ZDRU5URVIpOwoJICB9IGVsc2UgewogICAgICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQpCiAgICAgICAgICAgICAgICBTZXRUZXh0Q29sb3IoIGhEQywgR2V0U3lzQ29sb3IoQ09MT1JfR1JBWVRFWFQpICk7CiAgICAgICAgICAgIERyYXdUZXh0QSggaERDLCB3bmRQdHItPnRleHQsIHRleHRsZW4sICZydGV4dCwKCQkJIERUX1NJTkdMRUxJTkUgfCBEVF9WQ0VOVEVSICk7CgkgIH0KICAgICAgICB9CiAgICB9CgogICAgaWYgKChhY3Rpb24gPT0gT0RBX0ZPQ1VTKSB8fAogICAgICAgICgoYWN0aW9uID09IE9EQV9EUkFXRU5USVJFKSAmJiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpKSkKICAgIHsKCS8qIGFnYWluLCB0aGlzIGlzIHdoYXQgQ1RMM0QgZXhwZWN0cyAqLwoKICAgICAgICBTZXRSZWN0RW1wdHkoJnJib3gpOwogICAgICAgIGlmKCB0ZXh0bGVuICkKICAgICAgICAgICAgRHJhd1RleHRBKCBoREMsIHduZFB0ci0+dGV4dCwgdGV4dGxlbiwgJnJib3gsCgkJCSBEVF9TSU5HTEVMSU5FIHwgRFRfQ0FMQ1JFQ1QgKTsKICAgICAgICB0ZXh0bGVuID0gcmJveC5ib3R0b20gLSByYm94LnRvcDsKICAgICAgICBkZWx0YSA9ICgocnRleHQuYm90dG9tIC0gcnRleHQudG9wKSAtIHRleHRsZW4pLzI7CiAgICAgICAgcmJveC5ib3R0b20gPSAocmJveC50b3AgPSBydGV4dC50b3AgKyBkZWx0YSAtIDEpICsgdGV4dGxlbiArIDI7CiAgICAgICAgdGV4dGxlbiA9IHJib3gucmlnaHQgLSByYm94LmxlZnQ7CiAgICAgICAgcmJveC5yaWdodCA9IChyYm94LmxlZnQgKz0gLS1ydGV4dC5sZWZ0KSArIHRleHRsZW4gKyAyOwogICAgICAgIEludGVyc2VjdFJlY3QoJnJib3gsICZyYm94LCAmcnRleHQpOwogICAgICAgIERyYXdGb2N1c1JlY3QoIGhEQywgJnJib3ggKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIEJVVFRPTl9DaGVja0F1dG9SYWRpb0J1dHRvbgogKgogKiB3bmRQdHIgaXMgY2hlY2tlZCwgdW5jaGVjayBldmVyeSBvdGhlciBhdXRvIHJhZGlvIGJ1dHRvbiBpbiBncm91cAogKi8Kc3RhdGljIHZvaWQgQlVUVE9OX0NoZWNrQXV0b1JhZGlvQnV0dG9uKCBXTkQgKnduZFB0ciApCnsKICAgIEhXTkQgcGFyZW50LCBzaWJsaW5nLCBzdGFydDsKICAgIGlmICghKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NISUxEKSkgcmV0dXJuOwogICAgcGFyZW50ID0gd25kUHRyLT5wYXJlbnQtPmh3bmRTZWxmOwogICAgLyogYXNzdXJlIHRoYXQgc3RhcnRpbmcgY29udHJvbCBpcyBub3QgZGlzYWJsZWQgb3IgaW52aXNpYmxlICovCiAgICBzdGFydCA9IHNpYmxpbmcgPSBHZXROZXh0RGxnR3JvdXBJdGVtKCBwYXJlbnQsIHduZFB0ci0+aHduZFNlbGYsIFRSVUUgKTsKICAgIGRvCiAgICB7CiAgICAgICAgV05EICp0bXBXbmQ7CiAgICAgICAgaWYgKCFzaWJsaW5nKSBicmVhazsKICAgICAgICB0bXBXbmQgPSBXSU5fRmluZFduZFB0cihzaWJsaW5nKTsKICAgICAgICBpZiAoKHduZFB0ci0+aHduZFNlbGYgIT0gc2libGluZykgJiYKICAgICAgICAgICAgKCh0bXBXbmQtPmR3U3R5bGUgJiAweDBmKSA9PSBCU19BVVRPUkFESU9CVVRUT04pKQogICAgICAgICAgICBTZW5kTWVzc2FnZUEoIHNpYmxpbmcsIEJNX1NFVENIRUNLLCBCVVRUT05fVU5DSEVDS0VELCAwICk7CiAgICAgICAgc2libGluZyA9IEdldE5leHREbGdHcm91cEl0ZW0oIHBhcmVudCwgc2libGluZywgRkFMU0UgKTsKICAgICAgICBXSU5fUmVsZWFzZVduZFB0cih0bXBXbmQpOwogICAgfSB3aGlsZSAoc2libGluZyAhPSBzdGFydCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICBHcm91cCBCb3ggRnVuY3Rpb25zCiAqLwoKc3RhdGljIHZvaWQgR0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApCnsKICAgIFJFQ1QgcmMsIHJjRnJhbWU7CiAgICBCVVRUT05JTkZPICppbmZvUHRyID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKCiAgICBpZiAoYWN0aW9uICE9IE9EQV9EUkFXRU5USVJFKSByZXR1cm47CgogICAgQlVUVE9OX1NFTkRfQ1RMQ09MT1IoIHduZFB0ciwgaERDICk7CgogICAgR2V0Q2xpZW50UmVjdCggd25kUHRyLT5od25kU2VsZiwgJnJjKTsKICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKSB7CiAgICAgICAgSFBFTiBoUHJldlBlbiA9IFNlbGVjdE9iamVjdCggaERDLAoJCQkJCSAgR2V0U3lzQ29sb3JQZW4oQ09MT1JfV0lORE9XRlJBTUUpKTsKCUhCUlVTSCBoUHJldkJydXNoID0gU2VsZWN0T2JqZWN0KCBoREMsCgkJCQkJICAgICAgR2V0U3RvY2tPYmplY3QoTlVMTF9CUlVTSCkgKTsKCglSZWN0YW5nbGUoIGhEQywgcmMubGVmdCwgcmMudG9wICsgMiwgcmMucmlnaHQgLSAxLCByYy5ib3R0b20gLSAxICk7CglTZWxlY3RPYmplY3QoIGhEQywgaFByZXZCcnVzaCApOwoJU2VsZWN0T2JqZWN0KCBoREMsIGhQcmV2UGVuICk7CiAgICB9IGVsc2UgewoJVEVYVE1FVFJJQ0EgdG07CglyY0ZyYW1lID0gcmM7CgoJaWYgKGluZm9QdHItPmhGb250KQoJICAgIFNlbGVjdE9iamVjdCAoaERDLCBpbmZvUHRyLT5oRm9udCk7CglHZXRUZXh0TWV0cmljc0EgKGhEQywgJnRtKTsKCXJjRnJhbWUudG9wICs9ICh0bS50bUhlaWdodCAvIDIpIC0gMTsKCURyYXdFZGdlIChoREMsICZyY0ZyYW1lLCBFREdFX0VUQ0hFRCwgQkZfUkVDVCk7CiAgICB9CgogICAgaWYgKHduZFB0ci0+dGV4dCkKICAgIHsKCWlmIChpbmZvUHRyLT5oRm9udCkgU2VsZWN0T2JqZWN0KCBoREMsIGluZm9QdHItPmhGb250ICk7CiAgICAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEKQogICAgICAgICAgICBTZXRUZXh0Q29sb3IoIGhEQywgR2V0U3lzQ29sb3IoQ09MT1JfR1JBWVRFWFQpICk7CiAgICAgICAgcmMubGVmdCArPSAxMDsKICAgICAgICBEcmF3VGV4dEEoIGhEQywgd25kUHRyLT50ZXh0LCAtMSwgJnJjLCBEVF9TSU5HTEVMSU5FIHwgRFRfTk9DTElQICk7CiAgICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICBVc2VyIEJ1dHRvbiBGdW5jdGlvbnMKICovCgpzdGF0aWMgdm9pZCBVQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICkKewogICAgUkVDVCByYzsKICAgIEhCUlVTSCBoQnJ1c2g7CiAgICBCVVRUT05JTkZPICppbmZvUHRyID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKCiAgICBpZiAoYWN0aW9uID09IE9EQV9TRUxFQ1QpIHJldHVybjsKCiAgICBHZXRDbGllbnRSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmcmMpOwoKICAgIGlmIChpbmZvUHRyLT5oRm9udCkgU2VsZWN0T2JqZWN0KCBoREMsIGluZm9QdHItPmhGb250ICk7CiAgICBoQnJ1c2ggPSBHZXRDb250cm9sQnJ1c2gxNiggd25kUHRyLT5od25kU2VsZiwgaERDLCBDVExDT0xPUl9CVE4gKTsKCiAgICBGaWxsUmVjdCggaERDLCAmcmMsIGhCcnVzaCApOwogICAgaWYgKChhY3Rpb24gPT0gT0RBX0ZPQ1VTKSB8fAogICAgICAgICgoYWN0aW9uID09IE9EQV9EUkFXRU5USVJFKSAmJiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpKSkKICAgICAgICBEcmF3Rm9jdXNSZWN0KCBoREMsICZyYyApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgT3duZXJkcmF3biBCdXR0b24gRnVuY3Rpb25zCiAqLwoKc3RhdGljIHZvaWQgT0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApCnsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwogICAgRFJBV0lURU1TVFJVQ1QgZGlzOwoKICAgIGRpcy5DdGxUeXBlICAgID0gT0RUX0JVVFRPTjsKICAgIGRpcy5DdGxJRCAgICAgID0gd25kUHRyLT53SURtZW51OwogICAgZGlzLml0ZW1JRCAgICAgPSAwOwogICAgZGlzLml0ZW1BY3Rpb24gPSBhY3Rpb247CiAgICBkaXMuaXRlbVN0YXRlICA9ICgoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpID8gT0RTX0ZPQ1VTIDogMCkgfAogICAgICAgICAgICAgICAgICAgICAoKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSA/IE9EU19TRUxFQ1RFRCA6IDApIHwKICAgICAgICAgICAgICAgICAgICAgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCkgPyBPRFNfRElTQUJMRUQgOiAwKTsKICAgIGRpcy5od25kSXRlbSAgID0gd25kUHRyLT5od25kU2VsZjsKICAgIGRpcy5oREMgICAgICAgID0gaERDOwogICAgZGlzLml0ZW1EYXRhICAgPSAwOwogICAgR2V0Q2xpZW50UmVjdCggd25kUHRyLT5od25kU2VsZiwgJmRpcy5yY0l0ZW0gKTsKCiAgICBTZXRCa0NvbG9yKCBoREMsIEdldFN5c0NvbG9yKCBDT0xPUl9CVE5GQUNFICkgKTsKCiAgICBTZW5kTWVzc2FnZUEoIEdldFBhcmVudCh3bmRQdHItPmh3bmRTZWxmKSwgV01fRFJBV0lURU0sCiAgICAgICAgICAgICAgICAgICAgd25kUHRyLT53SURtZW51LCAoTFBBUkFNKSZkaXMgKTsKfQoK