LyoKICogQ29weXJpZ2h0IDE5OTggTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAwIEJyYWRsZXkgQmFldHoKICogQ29weXJpZ2h0IDIwMDMgTWljaGFlbCBH/G5uZXdpZwogKiBDb3B5cmlnaHQgMjAwNSBEbWl0cnkgVGltb3Noa292CiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBGSVhNRTogVGhpcyBhbGwgYXNzdW1lcyAzMiBiaXQgY29kZWNzCiAqCQlXaW45NSBhcHBlYXJzIHRvIHByZWZlciAzMiBiaXQgY29kZWNzLCBldmVuIGZyb20gMTYgYml0IGNvZGUuCiAqCQlUaGVyZSBpcyB0aGUgSUNPcGVuRnVuY3Rpb24xNiB0byB3b3JyeSBhYm91dCBzdGlsbCwgdGhvdWdoLgogKiAgICAgIAogKiBUT0RPCiAqICAgICAgLSBubyB0aHJlYWQgc2FmZXR5CiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2RlZmluZSBDT01fTk9fV0lORE9XU19ICiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgImNvbW1kbGcuaCIKI2luY2x1ZGUgInZmdy5oIgojaW5jbHVkZSAibXN2aWRlb19wcml2YXRlLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgovKiBEcml2ZXJzMzIgc2V0dGluZ3MgKi8KI2RlZmluZSBIS0xNX0RSSVZFUlMzMiAiU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93cyBOVFxcQ3VycmVudFZlcnNpb25cXERyaXZlcnMzMiIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1zdmlkZW8pOwoKc3RhdGljIGlubGluZSBjb25zdCBjaGFyICp3aW5lX2RiZ3N0cl9mY2MoIERXT1JEIGZjYyApCnsKICAgIHJldHVybiB3aW5lX2RiZ19zcHJpbnRmKCIlYyVjJWMlYyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9CWVRFKExPV09SRChmY2MpKSwgSElCWVRFKExPV09SRChmY2MpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPQllURShISVdPUkQoZmNjKSksIEhJQllURShISVdPUkQoZmNjKSkpOwp9CgpMUkVTVUxUIChDQUxMQkFDSyAqcEZuQ2FsbFRvMTYpKEhEUlZSLCBISUMsIFVJTlQsIExQQVJBTSwgTFBBUkFNKSA9IE5VTEw7CgpzdGF0aWMgV0lORV9ISUMqICAgICAgICBNU1ZJREVPX0ZpcnN0SGljIC8qID0gTlVMTCAqLzsKCnR5cGVkZWYgc3RydWN0IF9yZWdfZHJpdmVyIHJlZ19kcml2ZXI7CnN0cnVjdCBfcmVnX2RyaXZlcgp7CiAgICBEV09SRCAgICAgICBmY2NUeXBlOwogICAgRFdPUkQgICAgICAgZmNjSGFuZGxlcjsKICAgIERSSVZFUlBST0MgIHByb2M7CiAgICBMUFdTVFIgICAgICBuYW1lOwogICAgcmVnX2RyaXZlciogbmV4dDsKfTsKCnN0YXRpYyByZWdfZHJpdmVyKiByZWdfZHJpdmVyX2xpc3QgPSBOVUxMOwoKLyogVGhpcyBvbmUgaXMgYSBtYWNybyBzdWNoIHRoYXQgaXQgd29ya3MgZm9yIGJvdGggQVNDSUkgYW5kIFVuaWNvZGUgKi8KI2RlZmluZSBmb3VyY2NfdG9fc3RyaW5nKHN0ciwgZmNjKSBkbyB7IFwKCShzdHIpWzBdID0gTE9CWVRFKExPV09SRChmY2MpKTsgXAoJKHN0cilbMV0gPSBISUJZVEUoTE9XT1JEKGZjYykpOyBcCgkoc3RyKVsyXSA9IExPQllURShISVdPUkQoZmNjKSk7IFwKCShzdHIpWzNdID0gSElCWVRFKEhJV09SRChmY2MpKTsgXAoJfSB3aGlsZSgwKQoKSE1PRFVMRSBNU1ZGVzMyX2hNb2R1bGU7CgpCT09MIFdJTkFQSSBEbGxNYWluKCBISU5TVEFOQ0UgaGluc3QsIERXT1JEIHJlYXNvbiwgTFBWT0lEIHJlc2VydmVkICkKewogICAgVFJBQ0UoIiVwLCVseCwlcFxuIiwgaGluc3QsIHJlYXNvbiwgcmVzZXJ2ZWQpOwoKICAgIHN3aXRjaChyZWFzb24pCiAgICB7CiAgICAgICAgY2FzZSBETExfUFJPQ0VTU19BVFRBQ0g6CiAgICAgICAgICAgIERpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMoaGluc3QpOwogICAgICAgICAgICBNU1ZGVzMyX2hNb2R1bGUgPSAoSE1PRFVMRSloaW5zdDsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIGludCBjb21wYXJlX2ZvdXJjYyhEV09SRCBmY2MxLCBEV09SRCBmY2MyKQp7CiAgY2hhciBmY2Nfc3RyMVs0XTsKICBjaGFyIGZjY19zdHIyWzRdOwogIGZvdXJjY190b19zdHJpbmcoZmNjX3N0cjEsIGZjYzEpOwogIGZvdXJjY190b19zdHJpbmcoZmNjX3N0cjIsIGZjYzIpOwogIHJldHVybiBzdHJuY2FzZWNtcChmY2Nfc3RyMSwgZmNjX3N0cjIsIDQpOwp9Cgp0eXBlZGVmIEJPT0wgKCplbnVtX2hhbmRsZXJfdCkoY29uc3QgY2hhciosIGludCwgdm9pZCopOwoKc3RhdGljIEJPT0wgZW51bV9kcml2ZXJzKERXT1JEIGZjY1R5cGUsIGVudW1faGFuZGxlcl90IGhhbmRsZXIsIHZvaWQqIHBhcmFtKQp7CiAgICBDSEFSIGJ1ZlsyMDQ4XSwgZmNjVHlwZVN0cls1XSwgKnM7CiAgICBEV09SRCBpLCBjbnQgPSAwLCBidWZMZW4sIGxSZXQ7CiAgICBCT09MIHJlc3VsdCA9IEZBTFNFOwogICAgRklMRVRJTUUgbGFzdFdyaXRlOwogICAgSEtFWSBoS2V5OwoKICAgIGZvdXJjY190b19zdHJpbmcoZmNjVHlwZVN0ciwgZmNjVHlwZSk7CiAgICBmY2NUeXBlU3RyWzRdID0gJy4nOwoKICAgIC8qIGZpcnN0LCBnbyB0aHJvdWdoIHRoZSByZWdpc3RyeSBlbnRyaWVzICovCiAgICBsUmV0ID0gUmVnT3BlbktleUV4QShIS0VZX0xPQ0FMX01BQ0hJTkUsIEhLTE1fRFJJVkVSUzMyLCAwLCBLRVlfUVVFUllfVkFMVUUsICZoS2V5KTsKICAgIGlmIChsUmV0ID09IEVSUk9SX1NVQ0NFU1MpIAogICAgewoJRFdPUkQgbnVta2V5czsKCVJlZ1F1ZXJ5SW5mb0tleUEoIGhLZXksIDAsIDAsIDAsICZudW1rZXlzLCAwLCAwLCAwLCAwLCAwLCAwLCAwKTsKCWZvciAoaSA9IDA7IGkgPCBudW1rZXlzOyBpKyspIAoJewoJICAgIGJ1ZkxlbiA9IHNpemVvZihidWYpIC8gc2l6ZW9mKGJ1ZlswXSk7CgkgICAgbFJldCA9IFJlZ0VudW1LZXlFeEEoaEtleSwgaSwgYnVmLCAmYnVmTGVuLCAwLCAwLCAwLCAmbGFzdFdyaXRlKTsKCSAgICBpZiAobFJldCAhPSBFUlJPUl9TVUNDRVNTKSBjb250aW51ZTsKCSAgICBpZiAoc3RybmNhc2VjbXAoYnVmLCBmY2NUeXBlU3RyLCA1KSB8fCBidWZbOV0gIT0gJz0nKSBjb250aW51ZTsKCSAgICBpZiAoKHJlc3VsdCA9IGhhbmRsZXIoYnVmLCBjbnQrKywgcGFyYW0pKSkgYnJlYWs7Cgl9CiAgICAJUmVnQ2xvc2VLZXkoIGhLZXkgKTsKICAgIH0KICAgIGlmIChyZXN1bHQpIHJldHVybiByZXN1bHQ7CgogICAgLyogaWYgdGhhdCBkaWRuJ3Qgd29yaywgZ28gdGhyb3VnaCB0aGUgdmFsdWVzIGluIHN5c3RlbS5pbmkgKi8KICAgIGlmIChHZXRQcml2YXRlUHJvZmlsZVNlY3Rpb25BKCJkcml2ZXJzMzIiLCBidWYsIHNpemVvZihidWYpLCAic3lzdGVtLmluaSIpKSAKICAgIHsKCWZvciAocyA9IGJ1ZjsgKnM7IHMgKz0gc3RybGVuKHMpICsgMSkKCXsKICAgICAgICAgICAgVFJBQ0UoImdvdCAlc1xuIiwgcyk7CgkgICAgaWYgKHN0cm5jYXNlY21wKHMsIGZjY1R5cGVTdHIsIDUpIHx8IHNbOV0gIT0gJz0nKSBjb250aW51ZTsKCSAgICBpZiAoKHJlc3VsdCA9IGhhbmRsZXIocywgY250KyssIHBhcmFtKSkpIGJyZWFrOwoJfQogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1TVklERU9fR2V0SGljUHRyCiAqCiAqCiAqLwpXSU5FX0hJQyogICBNU1ZJREVPX0dldEhpY1B0cihISUMgaGljKQp7CiAgICBXSU5FX0hJQyogICB3aGljOwoKICAgIGZvciAod2hpYyA9IE1TVklERU9fRmlyc3RIaWM7IHdoaWMgJiYgd2hpYy0+aGljICE9IGhpYzsgd2hpYyA9IHdoaWMtPm5leHQpOwogICAgcmV0dXJuIHdoaWM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJVmlkZW9Gb3JXaW5kb3dzVmVyc2lvbgkJW01TVkZXMzIuMl0KICoJCVZpZGVvRm9yV2luZG93c1ZlcnNpb24JCVtNU1ZJREVPLjJdCiAqIFJldHVybnMgdGhlIHZlcnNpb24gaW4gbWFqb3IubWlub3IgZm9ybS4KICogSW4gV2luZG93czk1IHRoaXMgcmV0dXJucyAweDA0MDAwM2I2ICg0Ljk1MCkKICovCkRXT1JEIFdJTkFQSSBWaWRlb0ZvcldpbmRvd3NWZXJzaW9uKHZvaWQpIAp7CiAgICByZXR1cm4gMHgwNDAwMDNCNjsgLyogNC45NTAgKi8KfQoKc3RhdGljIEJPT0wgSUNJbmZvX2VudW1faGFuZGxlcihjb25zdCBjaGFyICpkcnYsIGludCBuciwgdm9pZCAqcGFyYW0pCnsKICAgIElDSU5GTyAqbHBpY2luZm8gPSAoSUNJTkZPICopcGFyYW07CiAgICBEV09SRCBmY2NIYW5kbGVyID0gbW1pb1N0cmluZ1RvRk9VUkNDQShkcnYgKyA1LCAwKTsKCiAgICAvKiBleGFjdCBtYXRjaCBvZiBmY2NIYW5kbGVyIG9yIG50aCBkcml2ZXIgZm91bmQgKi8KICAgIGlmICgobHBpY2luZm8tPmZjY0hhbmRsZXIgIT0gbnIpICYmIChscGljaW5mby0+ZmNjSGFuZGxlciAhPSBmY2NIYW5kbGVyKSkKCXJldHVybiBGQUxTRTsKCiAgICBscGljaW5mby0+ZmNjSGFuZGxlciA9IGZjY0hhbmRsZXI7CiAgICBscGljaW5mby0+ZHdGbGFncyA9IDA7CiAgICBscGljaW5mby0+ZHdWZXJzaW9uID0gMDsKICAgIGxwaWNpbmZvLT5kd1ZlcnNpb25JQ00gPSBJQ1ZFUlNJT047CiAgICBscGljaW5mby0+c3pOYW1lWzBdID0gMDsKICAgIGxwaWNpbmZvLT5zekRlc2NyaXB0aW9uWzBdID0gMDsKICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBkcnYgKyAxMCwgLTEsIGxwaWNpbmZvLT5zekRyaXZlciwgCgkJCXNpemVvZihscGljaW5mby0+c3pEcml2ZXIpL3NpemVvZihXQ0hBUikpOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlDSW5mbwkJCQlbTVNWRlczMi5AXQogKiBHZXQgaW5mb3JtYXRpb24gYWJvdXQgYW4gaW5zdGFsbGFibGUgY29tcHJlc3Nvci4gUmV0dXJuIFRSVUUgaWYgdGhlcmUKICogaXMgb25lLgogKgogKiBQQVJBTVMKICogICBmY2NUeXBlICAgICBbSV0gdHlwZSBvZiBjb21wcmVzc29yIChlLmcuICd2aWRjJykKICogICBmY2NIYW5kbGVyICBbSV0gcmVhbCBmY2MgZm9yIGhhbmRsZXIgb3IgPG4+dGggY29tcHJlc3NvcgogKiAgIGxwaWNpbmZvICAgIFtPXSBpbmZvcm1hdGlvbiBhYm91dCBjb21wcmVzc29yCiAqLwpCT09MIFZGV0FQSSBJQ0luZm8oIERXT1JEIGZjY1R5cGUsIERXT1JEIGZjY0hhbmRsZXIsIElDSU5GTyAqbHBpY2luZm8pCnsKICAgIFRSQUNFKCIoJXMsJXMvJTA4bHgsJXApXG4iLCAKICAgICAgICAgIHdpbmVfZGJnc3RyX2ZjYyhmY2NUeXBlKSwgd2luZV9kYmdzdHJfZmNjKGZjY0hhbmRsZXIpLCBmY2NIYW5kbGVyLCBscGljaW5mbyk7CgogICAgbHBpY2luZm8tPmZjY1R5cGUgPSBmY2NUeXBlOwogICAgbHBpY2luZm8tPmZjY0hhbmRsZXIgPSBmY2NIYW5kbGVyOwogICAgcmV0dXJuIGVudW1fZHJpdmVycyhmY2NUeXBlLCBJQ0luZm9fZW51bV9oYW5kbGVyLCBscGljaW5mbyk7Cn0KCnN0YXRpYyBEV09SRCBJQ19IYW5kbGVSZWYgPSAxOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ0luc3RhbGwJCQlbTVNWRlczMi5AXQogKi8KQk9PTCBWRldBUEkgSUNJbnN0YWxsKERXT1JEIGZjY1R5cGUsIERXT1JEIGZjY0hhbmRsZXIsIExQQVJBTSBsUGFyYW0sIExQU1RSIHN6RGVzYywgVUlOVCB3RmxhZ3MpIAp7CiAgICByZWdfZHJpdmVyKiBkcml2ZXI7CiAgICB1bnNpZ25lZCBsZW47CgogICAgVFJBQ0UoIiglcywlcywlcCwlcCwweCUwOHgpXG4iLCB3aW5lX2RiZ3N0cl9mY2MoZmNjVHlwZSksIHdpbmVfZGJnc3RyX2ZjYyhmY2NIYW5kbGVyKSwgKHZvaWQqKWxQYXJhbSwgc3pEZXNjLCB3RmxhZ3MpOwoKICAgIC8qIENoZWNrIGlmIGEgZHJpdmVyIGlzIGFscmVhZHkgcmVnaXN0ZXJlZCAqLwogICAgZm9yIChkcml2ZXIgPSByZWdfZHJpdmVyX2xpc3Q7IGRyaXZlcjsgZHJpdmVyID0gZHJpdmVyLT5uZXh0KQogICAgewogICAgICAgIGlmICghY29tcGFyZV9mb3VyY2MoZmNjVHlwZSwgZHJpdmVyLT5mY2NUeXBlKSAmJgogICAgICAgICAgICAhY29tcGFyZV9mb3VyY2MoZmNjSGFuZGxlciwgZHJpdmVyLT5mY2NIYW5kbGVyKSkKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBpZiAoZHJpdmVyKSByZXR1cm4gRkFMU0U7CgogICAgLyogUmVnaXN0ZXIgdGhlIGRyaXZlciAqLwogICAgZHJpdmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihyZWdfZHJpdmVyKSk7CiAgICBpZiAoIWRyaXZlcikgZ290byBvb207CiAgICBkcml2ZXItPmZjY1R5cGUgPSBmY2NUeXBlOwogICAgZHJpdmVyLT5mY2NIYW5kbGVyID0gZmNjSGFuZGxlcjsKCiAgICBzd2l0Y2god0ZsYWdzKQogICAgewogICAgY2FzZSBJQ0lOU1RBTExfRlVOQ1RJT046CiAgICAgICAgZHJpdmVyLT5wcm9jID0gKERSSVZFUlBST0MpbFBhcmFtOwoJZHJpdmVyLT5uYW1lID0gTlVMTDsKICAgICAgICBicmVhazsKICAgIGNhc2UgSUNJTlNUQUxMX0RSSVZFUjoKCWRyaXZlci0+cHJvYyA9IE5VTEw7CiAgICAgICAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIChjaGFyKilsUGFyYW0sIC0xLCBOVUxMLCAwKTsKICAgICAgICBkcml2ZXItPm5hbWUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgaWYgKCFkcml2ZXItPm5hbWUpIGdvdG8gb29tOwogICAgICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCAoY2hhciopbFBhcmFtLCAtMSwgZHJpdmVyLT5uYW1lLCBsZW4pOwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJRVJSKCJJbnZhbGlkIGZsYWdzIVxuIik7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkcml2ZXIpOwoJcmV0dXJuIEZBTFNFOwogICB9CgogICAvKiBJbnNlcnQgb3VyIGRyaXZlciBpbiB0aGUgbGlzdCovCiAgIGRyaXZlci0+bmV4dCA9IHJlZ19kcml2ZXJfbGlzdDsKICAgcmVnX2RyaXZlcl9saXN0ID0gZHJpdmVyOwogICAgCiAgIHJldHVybiBUUlVFOwpvb206CiAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRyaXZlcik7CiAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ1JlbW92ZQkJCVtNU1ZGVzMyLkBdCiAqLwpCT09MIFZGV0FQSSBJQ1JlbW92ZShEV09SRCBmY2NUeXBlLCBEV09SRCBmY2NIYW5kbGVyLCBVSU5UIHdGbGFncykgCnsKICAgIHJlZ19kcml2ZXIqKiBwZHJpdmVyOwogICAgcmVnX2RyaXZlciogIGRydjsKCiAgICBUUkFDRSgiKCVzLCVzLDB4JTA4eClcbiIsIHdpbmVfZGJnc3RyX2ZjYyhmY2NUeXBlKSwgd2luZV9kYmdzdHJfZmNjKGZjY0hhbmRsZXIpLCB3RmxhZ3MpOwoKICAgIC8qIENoZWNrIGlmIGEgZHJpdmVyIGlzIGFscmVhZHkgcmVnaXN0ZXJlZCAqLwogICAgZm9yIChwZHJpdmVyID0gJnJlZ19kcml2ZXJfbGlzdDsgKnBkcml2ZXI7IHBkcml2ZXIgPSAmKCpwZHJpdmVyKS0+bmV4dCkKICAgIHsKICAgICAgICBpZiAoIWNvbXBhcmVfZm91cmNjKGZjY1R5cGUsICgqcGRyaXZlciktPmZjY1R5cGUpICYmCiAgICAgICAgICAgICFjb21wYXJlX2ZvdXJjYyhmY2NIYW5kbGVyLCAoKnBkcml2ZXIpLT5mY2NIYW5kbGVyKSkKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBpZiAoISpwZHJpdmVyKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICAvKiBSZW1vdmUgdGhlIGRyaXZlciBmcm9tIHRoZSBsaXN0ICovCiAgICBkcnYgPSAqcGRyaXZlcjsKICAgICpwZHJpdmVyID0gKCpwZHJpdmVyKS0+bmV4dDsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRydi0+bmFtZSk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkcnYpOwogICAgCiAgICByZXR1cm4gVFJVRTsgIAp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ09wZW4JCQkJW01TVkZXMzIuQF0KICogT3BlbnMgYW4gaW5zdGFsbGFibGUgY29tcHJlc3Nvci4gUmV0dXJuIHNwZWNpYWwgaGFuZGxlLgogKi8KSElDIFZGV0FQSSBJQ09wZW4oRFdPUkQgZmNjVHlwZSwgRFdPUkQgZmNjSGFuZGxlciwgVUlOVCB3TW9kZSkgCnsKICAgIFdDSEFSCQljb2RlY25hbWVbMTBdOwogICAgSUNPUEVOCQlpY29wZW47CiAgICBIRFJWUgkJaGRydjsKICAgIFdJTkVfSElDKiAgICAgICAgICAgd2hpYzsKICAgIEJPT0wgICAgICAgICAgICAgICAgYklzMTY7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgIGRydjMyV1tdID0geydkJywncicsJ2knLCd2JywnZScsJ3InLCdzJywnMycsJzInLCdcMCd9OwogICAgcmVnX2RyaXZlciogICAgICAgICBkcml2ZXI7CgogICAgVFJBQ0UoIiglcywlcywweCUwOHgpXG4iLCB3aW5lX2RiZ3N0cl9mY2MoZmNjVHlwZSksIHdpbmVfZGJnc3RyX2ZjYyhmY2NIYW5kbGVyKSwgd01vZGUpOwoKICAgIC8qIENoZWNrIGlmIHRoZXJlIGlzIGEgcmVnaXN0ZXJlZCBkcml2ZXIgdGhhdCBtYXRjaGVzICovCiAgICBkcml2ZXIgPSByZWdfZHJpdmVyX2xpc3Q7CiAgICB3aGlsZShkcml2ZXIpCiAgICAgICAgaWYgKCFjb21wYXJlX2ZvdXJjYyhmY2NUeXBlLCBkcml2ZXItPmZjY1R5cGUpICYmCiAgICAgICAgICAgICFjb21wYXJlX2ZvdXJjYyhmY2NIYW5kbGVyLCBkcml2ZXItPmZjY0hhbmRsZXIpKQoJICAgIGJyZWFrOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZHJpdmVyID0gZHJpdmVyLT5uZXh0OwoKICAgIGlmIChkcml2ZXIgJiYgZHJpdmVyLT5wcm9jKQoJLyogVGhlIGRyaXZlciBoYXMgYmVlbiByZWdpc3RlcmVkIGF0IHJ1bnRpbWUgd2l0aCBpdHMgZHJpdmVycHJvYyAqLwogICAgICAgIHJldHVybiBNU1ZJREVPX09wZW5GdW5jdGlvbihmY2NUeXBlLCBmY2NIYW5kbGVyLCB3TW9kZSwgKERSSVZFUlBST0MpZHJpdmVyLT5wcm9jLCAoRFdPUkQpTlVMTCk7CiAgCiAgICAvKiBXZWxsLCBsUGFyYW0yIGlzIGluIGZhY3QgYSBMUFZJREVPX09QRU5fUEFSTVMsIGJ1dCBpdCBoYXMgdGhlCiAgICAgKiBzYW1lIGxheW91dCBhcyBJQ09QRU4KICAgICAqLwogICAgaWNvcGVuLmR3U2l6ZQkJPSBzaXplb2YoSUNPUEVOKTsKICAgIGljb3Blbi5mY2NUeXBlCQk9IGZjY1R5cGU7CiAgICBpY29wZW4uZmNjSGFuZGxlcgkgICAgICAgID0gZmNjSGFuZGxlcjsKICAgIGljb3Blbi5kd1ZlcnNpb24gICAgICAgICAgICA9IDB4MDAwMDEwMDA7IC8qIEZJWE1FICovCiAgICBpY29wZW4uZHdGbGFncwkJPSB3TW9kZTsKICAgIGljb3Blbi5kd0Vycm9yICAgICAgICAgICAgICA9IDA7CiAgICBpY29wZW4ucFYxUmVzZXJ2ZWQgICAgICAgICAgPSBOVUxMOwogICAgaWNvcGVuLnBWMlJlc2VydmVkICAgICAgICAgID0gTlVMTDsKICAgIGljb3Blbi5kbkRldk5vZGUgICAgICAgICAgICA9IDA7IC8qIEZJWE1FICovCgkKICAgIGlmICghZHJpdmVyKSB7CiAgICAgICAgLyogVGhlIGRyaXZlciBpcyByZWdpc3RlcmVkIGluIHRoZSByZWdpc3RyeSAqLwoJZm91cmNjX3RvX3N0cmluZyhjb2RlY25hbWUsIGZjY1R5cGUpOwogICAgICAgIGNvZGVjbmFtZVs0XSA9ICcuJzsKCWZvdXJjY190b19zdHJpbmcoY29kZWNuYW1lICsgNSwgZmNjSGFuZGxlcik7CiAgICAgICAgY29kZWNuYW1lWzldID0gJ1wwJzsKCiAgICAgICAgaGRydiA9IE9wZW5Ecml2ZXIoY29kZWNuYW1lLCBkcnYzMlcsIChMUEFSQU0pJmljb3Blbik7CiAgICAgICAgaWYgKCFoZHJ2KSAKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICB9IGVsc2UgewogICAgICAgIC8qIFRoZSBkcml2ZXIgaGFzIGJlZW4gcmVnaXN0ZXJlZCBhdCBydW50aW1lIHdpdGggaXRzIG5hbWUgKi8KICAgICAgICBoZHJ2ID0gT3BlbkRyaXZlcihkcml2ZXItPm5hbWUsIE5VTEwsIChMUEFSQU0pJmljb3Blbik7CiAgICAgICAgaWYgKCFoZHJ2KSAKICAgICAgICAgICAgcmV0dXJuIDA7IAogICAgfQogICAgYklzMTYgPSBHZXREcml2ZXJGbGFncyhoZHJ2KSAmIDB4MTAwMDAwMDA7IC8qIHVuZG9jdW1lbnRlZCBmbGFnOiBXSU5FX0dERl8xNkJJVCAqLwoKICAgIGlmIChiSXMxNiAmJiAhcEZuQ2FsbFRvMTYpCiAgICB7CiAgICAgICAgRklYTUUoIkdvdCBhIDE2IGJpdCBkcml2ZXIsIGJ1dCBubyAxNiBiaXQgc3VwcG9ydCBpbiBtc3Zmd1xuIik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICB3aGljID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihXSU5FX0hJQykpOwogICAgaWYgKCF3aGljKQogICAgewogICAgICAgIENsb3NlRHJpdmVyKGhkcnYsIDAsIDApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIHdoaWMtPmhkcnYgICAgICAgICAgPSBoZHJ2OwogICAgLyogRklYTUU6IGlzIHRoZSBzaWduYXR1cmUgdGhlIHJlYWwgb25lID8gKi8KICAgIHdoaWMtPmRyaXZlcnByb2MgICAgPSBiSXMxNiA/IChEUklWRVJQUk9DKXBGbkNhbGxUbzE2IDogTlVMTDsKICAgIHdoaWMtPmRyaXZlcnByb2MxNiAgPSAwOwogICAgd2hpYy0+dHlwZSAgICAgICAgICA9IGZjY1R5cGU7CiAgICB3aGljLT5oYW5kbGVyICAgICAgID0gZmNjSGFuZGxlcjsKICAgIHdoaWxlIChNU1ZJREVPX0dldEhpY1B0cihISUNfMzIoSUNfSGFuZGxlUmVmKSkgIT0gTlVMTCkgSUNfSGFuZGxlUmVmKys7CiAgICB3aGljLT5oaWMgICAgICAgICAgID0gSElDXzMyKElDX0hhbmRsZVJlZisrKTsKICAgIHdoaWMtPm5leHQgICAgICAgICAgPSBNU1ZJREVPX0ZpcnN0SGljOwogICAgTVNWSURFT19GaXJzdEhpYyA9IHdoaWM7CgogICAgVFJBQ0UoIj0+ICVwXG4iLCB3aGljLT5oaWMpOwogICAgcmV0dXJuIHdoaWMtPmhpYzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNU1ZJREVPX09wZW5GdW5jdGlvbgogKi8KSElDIE1TVklERU9fT3BlbkZ1bmN0aW9uKERXT1JEIGZjY1R5cGUsIERXT1JEIGZjY0hhbmRsZXIsIFVJTlQgd01vZGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgRFJJVkVSUFJPQyBscGZuSGFuZGxlciwgRFdPUkQgbHBmbkhhbmRsZXIxNikgCnsKICAgIElDT1BFTiAgICAgIGljb3BlbjsKICAgIFdJTkVfSElDKiAgIHdoaWM7CgogICAgVFJBQ0UoIiglcywlcywlZCwlcCwlMDhseClcbiIsIAogICAgICAgICAgd2luZV9kYmdzdHJfZmNjKGZjY1R5cGUpLCB3aW5lX2RiZ3N0cl9mY2MoZmNjSGFuZGxlciksIHdNb2RlLCBscGZuSGFuZGxlciwgbHBmbkhhbmRsZXIxNik7CgogICAgaWNvcGVuLmR3U2l6ZQkJPSBzaXplb2YoSUNPUEVOKTsKICAgIGljb3Blbi5mY2NUeXBlCQk9IGZjY1R5cGU7CiAgICBpY29wZW4uZmNjSGFuZGxlcgkgICAgICAgID0gZmNjSGFuZGxlcjsKICAgIGljb3Blbi5kd1ZlcnNpb24gICAgICAgICAgICA9IElDVkVSU0lPTjsKICAgIGljb3Blbi5kd0ZsYWdzCQk9IHdNb2RlOwogICAgaWNvcGVuLmR3RXJyb3IgICAgICAgICAgICAgID0gMDsKICAgIGljb3Blbi5wVjFSZXNlcnZlZCAgICAgICAgICA9IE5VTEw7CiAgICBpY29wZW4ucFYyUmVzZXJ2ZWQgICAgICAgICAgPSBOVUxMOwogICAgaWNvcGVuLmRuRGV2Tm9kZSAgICAgICAgICAgID0gMDsgLyogRklYTUUgKi8KCiAgICB3aGljID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihXSU5FX0hJQykpOwogICAgaWYgKCF3aGljKSByZXR1cm4gMDsKCiAgICB3aGljLT5kcml2ZXJwcm9jICAgPSBscGZuSGFuZGxlcjsKICAgIHdoaWMtPmRyaXZlcnByb2MxNiA9IGxwZm5IYW5kbGVyMTY7CiAgICB3aGlsZSAoTVNWSURFT19HZXRIaWNQdHIoSElDXzMyKElDX0hhbmRsZVJlZikpICE9IE5VTEwpIElDX0hhbmRsZVJlZisrOwogICAgd2hpYy0+aGljICAgICAgICAgID0gSElDXzMyKElDX0hhbmRsZVJlZisrKTsKICAgIHdoaWMtPm5leHQgICAgICAgICA9IE1TVklERU9fRmlyc3RIaWM7CiAgICBNU1ZJREVPX0ZpcnN0SGljID0gd2hpYzsKCiAgICAvKiBOb3cgdHJ5IG9wZW5pbmcvbG9hZGluZyB0aGUgZHJpdmVyLiBUYWtlbiBmcm9tIERSSVZFUl9BZGRUb0xpc3QgKi8KICAgIC8qIFdoYXQgaWYgdGhlIGZ1bmN0aW9uIGlzIHVzZWQgbW9yZSB0aGFuIG9uY2U/ICovCgogICAgaWYgKE1TVklERU9fU2VuZE1lc3NhZ2Uod2hpYywgRFJWX0xPQUQsIDBMLCAwTCkgIT0gRFJWX1NVQ0NFU1MpIAogICAgewogICAgICAgIFdBUk4oIkRSVl9MT0FEIGZhaWxlZCBmb3IgaGljICVwXG4iLCB3aGljLT5oaWMpOwogICAgICAgIE1TVklERU9fRmlyc3RIaWMgPSB3aGljLT5uZXh0OwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHdoaWMpOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgLyogcmV0dXJuIHZhbHVlIGlzIG5vdCBjaGVja2VkICovCiAgICBNU1ZJREVPX1NlbmRNZXNzYWdlKHdoaWMsIERSVl9FTkFCTEUsIDBMLCAwTCk7CgogICAgd2hpYy0+ZHJpdmVySWQgPSAoRFdPUkQpTVNWSURFT19TZW5kTWVzc2FnZSh3aGljLCBEUlZfT1BFTiwgMCwgKERXT1JEX1BUUikmaWNvcGVuKTsKICAgIC8qIEZJWE1FOiBXaGF0IHNob3VsZCB3ZSBwdXQgaGVyZT8gKi8KICAgIHdoaWMtPmhkcnYgPSBOVUxMOwogICAgCiAgICBpZiAod2hpYy0+ZHJpdmVySWQgPT0gMCkgCiAgICB7CiAgICAgICAgV0FSTigiRFJWX09QRU4gZmFpbGVkIGZvciBoaWMgJXBcbiIsIHdoaWMtPmhpYyk7CiAgICAgICAgTVNWSURFT19GaXJzdEhpYyA9IHdoaWMtPm5leHQ7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd2hpYyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgVFJBQ0UoIj0+ICVwXG4iLCB3aGljLT5oaWMpOwogICAgcmV0dXJuIHdoaWMtPmhpYzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ09wZW5GdW5jdGlvbgkJCVtNU1ZGVzMyLkBdCiAqLwpISUMgVkZXQVBJIElDT3BlbkZ1bmN0aW9uKERXT1JEIGZjY1R5cGUsIERXT1JEIGZjY0hhbmRsZXIsIFVJTlQgd01vZGUsIEZBUlBST0MgbHBmbkhhbmRsZXIpIAp7CiAgICByZXR1cm4gTVNWSURFT19PcGVuRnVuY3Rpb24oZmNjVHlwZSwgZmNjSGFuZGxlciwgd01vZGUsIChEUklWRVJQUk9DKWxwZm5IYW5kbGVyLCAwKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ0dldEluZm8JCQlbTVNWRlczMi5AXQogKi8KTFJFU1VMVCBWRldBUEkgSUNHZXRJbmZvKEhJQyBoaWMsIElDSU5GTyAqcGljaW5mbywgRFdPUkQgY2IpIAp7CiAgICBMUkVTVUxUCXJldDsKICAgIFdJTkVfSElDKiAgIHdoaWMgPSBNU1ZJREVPX0dldEhpY1B0cihoaWMpOwoKICAgIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgaGljLCBwaWNpbmZvLCBjYik7CgogICAgd2hpYyA9IE1TVklERU9fR2V0SGljUHRyKGhpYyk7CiAgICBpZiAoIXdoaWMpIHJldHVybiBJQ0VSUl9CQURIQU5ETEU7CiAgICBpZiAoIXBpY2luZm8pIHJldHVybiBNTVNZU0VSUl9JTlZBTFBBUkFNOwoKICAgIC8qIChXUykgVGhlIGZpZWxkIHN6RHJpdmVyIHNob3VsZCBiZSBpbml0aWFsaXplZCBiZWNhdXNlIHRoZSBkcml2ZXIgCiAgICAgKiBpcyBub3Qgb2JsaWdlZCBhbmQgb2Z0ZW4gd2lsbCBub3QgZG8gaXQuIFNvbWUgYXBwbGljYXRpb25zLCBsaWtlCiAgICAgKiBWaXJ0dWFsRHViLCByZWx5IG9uIHRoaXMgZmllbGQgYW5kIHdpbGwgb2NjYXNpb25hbGx5IGNyYXNoIGlmIGl0CiAgICAgKiBnb2VzIHVuaXRpYWxpemVkLgogICAgICovCiAgICBpZiAoY2IgPj0gc2l6ZW9mKElDSU5GTykpIHBpY2luZm8tPnN6RHJpdmVyWzBdID0gJ1wwJzsKCiAgICByZXQgPSBJQ1NlbmRNZXNzYWdlKGhpYywgSUNNX0dFVElORk8sIChEV09SRF9QVFIpcGljaW5mbywgY2IpOwoKICAgIC8qIChXUykgV2hlbiBzekRyaXZlciB3YXMgbm90IHN1cHBsaWVkIGJ5IHRoZSBkcml2ZXIgaXRzZWxmLCBhcHBhcmVudGx5IAogICAgICogV2luZG93cyB3aWxsIHNldCBpdHMgdmFsdWUgZXF1YWwgdG8gdGhlIGRyaXZlciBmaWxlIG5hbWUuIFRoaXMgY2FuCiAgICAgKiBiZSBvYnRhaW5lZCBmcm9tIHRoZSByZWdpc3RyeSBhcyB3ZSBkbyBoZXJlLgogICAgICovCiAgICBpZiAoY2IgPj0gc2l6ZW9mKElDSU5GTykgJiYgcGljaW5mby0+c3pEcml2ZXJbMF0gPT0gMCkKICAgIHsKICAgICAgICBJQ0lORk8gIGlpOwoKICAgICAgICBtZW1zZXQoJmlpLCAwLCBzaXplb2YoaWkpKTsKICAgICAgICBpaS5kd1NpemUgPSBzaXplb2YoaWkpOwogICAgICAgIElDSW5mbyhwaWNpbmZvLT5mY2NUeXBlLCBwaWNpbmZvLT5mY2NIYW5kbGVyLCAmaWkpOwogICAgICAgIGxzdHJjcHlXKHBpY2luZm8tPnN6RHJpdmVyLCBpaS5zekRyaXZlcik7CiAgICB9CgogICAgVFJBQ0UoIgktPiAweCUwOGx4XG4iLCByZXQpOwogICAgcmV0dXJuIHJldDsKfQoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQgZmNjVHlwZTsKICAgIERXT1JEIGZjY0hhbmRsZXI7CiAgICBMUEJJVE1BUElORk9IRUFERVIgbHBiaUluOwogICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQ7CiAgICBXT1JEIHdNb2RlOwogICAgRFdPUkQgcXVlcnltc2c7CiAgICBISUMgaGljOwp9IGRyaXZlcl9pbmZvX3Q7CgpzdGF0aWMgSElDIHRyeV9kcml2ZXIoZHJpdmVyX2luZm9fdCAqaW5mbykKewogICAgSElDICAgaGljOwoKICAgIGlmICgoaGljID0gSUNPcGVuKGluZm8tPmZjY1R5cGUsIGluZm8tPmZjY0hhbmRsZXIsIGluZm8tPndNb2RlKSkpIAogICAgewoJaWYgKCFJQ1NlbmRNZXNzYWdlKGhpYywgaW5mby0+cXVlcnltc2csIChEV09SRF9QVFIpaW5mby0+bHBiaUluLCAoRFdPUkRfUFRSKWluZm8tPmxwYmlPdXQpKQoJICAgIHJldHVybiBoaWM7CglJQ0Nsb3NlKGhpYyk7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIEJPT0wgSUNMb2NhdGVfZW51bV9oYW5kbGVyKGNvbnN0IGNoYXIgKmRydiwgaW50IG5yLCB2b2lkICpwYXJhbSkKewogICAgZHJpdmVyX2luZm9fdCAqaW5mbyA9IChkcml2ZXJfaW5mb190ICopcGFyYW07CiAgICBpbmZvLT5mY2NIYW5kbGVyID0gbW1pb1N0cmluZ1RvRk9VUkNDQShkcnYgKyA1LCAwKTsKICAgIGluZm8tPmhpYyA9IHRyeV9kcml2ZXIoaW5mbyk7CiAgICByZXR1cm4gaW5mby0+aGljICE9IDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSUNMb2NhdGUJCQlbTVNWRlczMi5AXQogKi8KSElDIFZGV0FQSSBJQ0xvY2F0ZShEV09SRCBmY2NUeXBlLCBEV09SRCBmY2NIYW5kbGVyLCBMUEJJVE1BUElORk9IRUFERVIgbHBiaUluLAogICAgICAgICAgICAgICAgICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0LCBXT1JEIHdNb2RlKQp7CiAgICBkcml2ZXJfaW5mb190IGluZm87CgogICAgVFJBQ0UoIiglcywlcywlcCwlcCwweCUwNHgpXG4iLCAKICAgICAgICAgIHdpbmVfZGJnc3RyX2ZjYyhmY2NUeXBlKSwgd2luZV9kYmdzdHJfZmNjKGZjY0hhbmRsZXIpLCBscGJpSW4sIGxwYmlPdXQsIHdNb2RlKTsKCiAgICBpbmZvLmZjY1R5cGUgPSBmY2NUeXBlOwogICAgaW5mby5mY2NIYW5kbGVyID0gZmNjSGFuZGxlcjsKICAgIGluZm8ubHBiaUluID0gbHBiaUluOwogICAgaW5mby5scGJpT3V0ID0gbHBiaU91dDsKICAgIGluZm8ud01vZGUgPSB3TW9kZTsKCiAgICBzd2l0Y2ggKHdNb2RlKSAKICAgIHsKICAgIGNhc2UgSUNNT0RFX0ZBU1RDT01QUkVTUzoKICAgIGNhc2UgSUNNT0RFX0NPTVBSRVNTOgogICAgICAgIGluZm8ucXVlcnltc2cgPSBJQ01fQ09NUFJFU1NfUVVFUlk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIElDTU9ERV9GQVNUREVDT01QUkVTUzoKICAgIGNhc2UgSUNNT0RFX0RFQ09NUFJFU1M6CiAgICAgICAgaW5mby5xdWVyeW1zZyA9IElDTV9ERUNPTVBSRVNTX1FVRVJZOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBJQ01PREVfRFJBVzoKICAgICAgICBpbmZvLnF1ZXJ5bXNnID0gSUNNX0RSQVdfUVVFUlk7CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIFdBUk4oIlVua25vd24gbW9kZSAoJWQpXG4iLCB3TW9kZSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyogRWFzeSBjYXNlOiBoYW5kbGVyL3R5cGUgbWF0Y2gsIHdlIGp1c3QgZmlyZSBhIHF1ZXJ5IGFuZCByZXR1cm4gKi8KICAgIGluZm8uaGljID0gdHJ5X2RyaXZlcigmaW5mbyk7CiAgICAvKiBJZiBpdCBkaWRuJ3Qgd29yaywgdHJ5IGVhY2ggZHJpdmVyIGluIHR1cm4uIDMyIGJpdCBjb2RlY3Mgb25seS4gKi8KICAgIC8qIEZJWE1FOiBNb3ZlIHRoaXMgdG8gYW4gaW5pdCByb3V0aW5lPyAqLwogICAgaWYgKCFpbmZvLmhpYykgZW51bV9kcml2ZXJzKGZjY1R5cGUsIElDTG9jYXRlX2VudW1faGFuZGxlciwgJmluZm8pOwoKICAgIGlmIChpbmZvLmhpYykgCiAgICB7CiAgICAgICAgVFJBQ0UoIj0+ICVwXG4iLCBpbmZvLmhpYyk7CglyZXR1cm4gaW5mby5oaWM7CiAgICB9CgogICAgaWYgKGZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSAKICAgICAgICByZXR1cm4gSUNMb2NhdGUoSUNUWVBFX1ZJREVPLCBmY2NIYW5kbGVyLCBscGJpSW4sIGxwYmlPdXQsIHdNb2RlKTsKICAgIAogICAgV0FSTigiKCVzLCVzLCVwLCVwLDB4JTA0eCkgbm90IGZvdW5kIVxuIiwKICAgICAgICAgd2luZV9kYmdzdHJfZmNjKGZjY1R5cGUpLCB3aW5lX2RiZ3N0cl9mY2MoZmNjSGFuZGxlciksIGxwYmlJbiwgbHBiaU91dCwgd01vZGUpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSUNHZXREaXNwbGF5Rm9ybWF0CQkJW01TVkZXMzIuQF0KICovCkhJQyBWRldBUEkgSUNHZXREaXNwbGF5Rm9ybWF0KAoJSElDIGhpYyxMUEJJVE1BUElORk9IRUFERVIgbHBiaUluLExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0LAoJSU5UIGRlcHRoLElOVCBkeCxJTlQgZHkpCnsKCUhJQwl0bXBoaWMgPSBoaWM7CgoJVFJBQ0UoIiglcCwlcCwlcCwlZCwlZCwlZCkhXG4iLGhpYyxscGJpSW4sbHBiaU91dCxkZXB0aCxkeCxkeSk7CgoJaWYgKCF0bXBoaWMpIHsKCQl0bXBoaWM9SUNMb2NhdGUoSUNUWVBFX1ZJREVPLDAsbHBiaUluLE5VTEwsSUNNT0RFX0RFQ09NUFJFU1MpOwoJCWlmICghdG1waGljKQoJCQlyZXR1cm4gdG1waGljOwoJfQoJaWYgKChkeSA9PSBscGJpSW4tPmJpSGVpZ2h0KSAmJiAoZHggPT0gbHBiaUluLT5iaVdpZHRoKSkKCQlkeSA9IGR4ID0gMDsgLyogbm8gcmVzaXplIG5lZWRlZCAqLwoKCS8qIENhbiB3ZSBkZWNvbXByZXNzIGl0ID8gKi8KCWlmIChJQ0RlY29tcHJlc3NRdWVyeSh0bXBoaWMsbHBiaUluLE5VTEwpICE9IDApCgkJZ290byBlcnJvdXQ7IC8qIG5vLCBzb3JyeSAqLwoKCUlDRGVjb21wcmVzc0dldEZvcm1hdCh0bXBoaWMsbHBiaUluLGxwYmlPdXQpOwoKCWlmIChscGJpT3V0LT5iaUNvbXByZXNzaW9uICE9IDApIHsKCSAgIEZJWE1FKCJPb2NoLCBob3cgY29tZSBkZWNvbXByZXNzb3Igb3V0cHV0cyBjb21wcmVzc2VkIGRhdGEgKCVsZCk/P1xuIiwKCQkJIGxwYmlPdXQtPmJpQ29tcHJlc3Npb24pOwoJfQoJaWYgKGxwYmlPdXQtPmJpU2l6ZSA8IHNpemVvZigqbHBiaU91dCkpIHsKCSAgIEZJWE1FKCJPb2NoLCBzaXplIG9mIG91dHB1dCBCSUggaXMgdG9vIHNtYWxsICglbGQpXG4iLAoJCQkgbHBiaU91dC0+YmlTaXplKTsKCSAgIGxwYmlPdXQtPmJpU2l6ZSA9IHNpemVvZigqbHBiaU91dCk7Cgl9CglpZiAoIWRlcHRoKSB7CgkJSERDCWhkYzsKCgkJaGRjID0gR2V0REMoMCk7CgkJZGVwdGggPSBHZXREZXZpY2VDYXBzKGhkYyxCSVRTUElYRUwpKkdldERldmljZUNhcHMoaGRjLFBMQU5FUyk7CgkJUmVsZWFzZURDKDAsaGRjKTsKCQlpZiAoZGVwdGg9PTE1KQlkZXB0aCA9IDE2OwoJCWlmIChkZXB0aDw4KQlkZXB0aCA9ICA4OwoJfQoJaWYgKGxwYmlJbi0+YmlCaXRDb3VudCA9PSA4KQoJCWRlcHRoID0gODsKCglUUkFDRSgiPT4gJXBcbiIsIHRtcGhpYyk7CglyZXR1cm4gdG1waGljOwplcnJvdXQ6CglpZiAoaGljIT10bXBoaWMpCgkJSUNDbG9zZSh0bXBoaWMpOwoKCVRSQUNFKCI9PiAwXG4iKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlDQ29tcHJlc3MJCQlbTVNWRlczMi5AXQogKi8KRFdPUkQgVkZXQVBJVgpJQ0NvbXByZXNzKAoJSElDIGhpYyxEV09SRCBkd0ZsYWdzLExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0cHV0LExQVk9JRCBscERhdGEsCglMUEJJVE1BUElORk9IRUFERVIgbHBiaUlucHV0LExQVk9JRCBscEJpdHMsTFBEV09SRCBscGNraWQsCglMUERXT1JEIGxwZHdGbGFncyxMT05HIGxGcmFtZU51bSxEV09SRCBkd0ZyYW1lU2l6ZSxEV09SRCBkd1F1YWxpdHksCglMUEJJVE1BUElORk9IRUFERVIgbHBiaVByZXYsTFBWT0lEIGxwUHJldikKewoJSUNDT01QUkVTUwlpY2NtcDsKCglUUkFDRSgiKCVwLCVsZCwlcCwlcCwlcCwlcCwuLi4pXG4iLGhpYyxkd0ZsYWdzLGxwYmlPdXRwdXQsbHBEYXRhLGxwYmlJbnB1dCxscEJpdHMpOwoKCWljY21wLmR3RmxhZ3MJCT0gZHdGbGFnczsKCglpY2NtcC5scGJpT3V0cHV0CT0gbHBiaU91dHB1dDsKCWljY21wLmxwT3V0cHV0CQk9IGxwRGF0YTsKCWljY21wLmxwYmlJbnB1dAkJPSBscGJpSW5wdXQ7CglpY2NtcC5scElucHV0CQk9IGxwQml0czsKCglpY2NtcC5scGNraWQJCT0gbHBja2lkOwoJaWNjbXAubHBkd0ZsYWdzCQk9IGxwZHdGbGFnczsKCWljY21wLmxGcmFtZU51bQkJPSBsRnJhbWVOdW07CglpY2NtcC5kd0ZyYW1lU2l6ZQk9IGR3RnJhbWVTaXplOwoJaWNjbXAuZHdRdWFsaXR5CQk9IGR3UXVhbGl0eTsKCWljY21wLmxwYmlQcmV2CQk9IGxwYmlQcmV2OwoJaWNjbXAubHBQcmV2CQk9IGxwUHJldjsKCXJldHVybiBJQ1NlbmRNZXNzYWdlKGhpYyxJQ01fQ09NUFJFU1MsKERXT1JEX1BUUikmaWNjbXAsc2l6ZW9mKGljY21wKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSUNEZWNvbXByZXNzCQkJW01TVkZXMzIuQF0KICovCkRXT1JEIFZGV0FQSVYgIElDRGVjb21wcmVzcyhISUMgaGljLERXT1JEIGR3RmxhZ3MsTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlGb3JtYXQsCgkJCQlMUFZPSUQgbHBEYXRhLExQQklUTUFQSU5GT0hFQURFUiBscGJpLExQVk9JRCBscEJpdHMpCnsKCUlDREVDT01QUkVTUwlpY2Q7CglEV09SRCByZXQ7CgoJVFJBQ0UoIiglcCwlbGQsJXAsJXAsJXAsJXApXG4iLGhpYyxkd0ZsYWdzLGxwYmlGb3JtYXQsbHBEYXRhLGxwYmksbHBCaXRzKTsKCglUUkFDRSgibHBCaXRzWzBdID09ICVseFxuIiwoKExQRFdPUkQpbHBCaXRzKVswXSk7CgoJaWNkLmR3RmxhZ3MJPSBkd0ZsYWdzOwoJaWNkLmxwYmlJbnB1dAk9IGxwYmlGb3JtYXQ7CglpY2QubHBJbnB1dAk9IGxwRGF0YTsKCglpY2QubHBiaU91dHB1dAk9IGxwYmk7CglpY2QubHBPdXRwdXQJPSBscEJpdHM7CglpY2QuY2tpZAk9IDA7CglyZXQgPSBJQ1NlbmRNZXNzYWdlKGhpYyxJQ01fREVDT01QUkVTUywoRFdPUkRfUFRSKSZpY2Qsc2l6ZW9mKElDREVDT01QUkVTUykpOwoKCVRSQUNFKCJscEJpdHNbMF0gPT0gJWx4XG4iLCgoTFBEV09SRClscEJpdHMpWzBdKTsKCglUUkFDRSgiLT4gJWxkXG4iLHJldCk7CgoJcmV0dXJuIHJldDsKfQoKCnN0cnVjdCBjaG9vc2VfY29tcHJlc3Nvcgp7CiAgICBVSU5UIGZsYWdzOwogICAgTFBDU1RSIHRpdGxlOwogICAgQ09NUFZBUlMgY3Y7Cn07CgpzdHJ1Y3QgY29kZWNfaW5mbwp7CiAgICBISUMgaGljOwogICAgSUNJTkZPIGljaW5mbzsKfTsKCnN0YXRpYyBCT09MIGVudW1fY29tcHJlc3NvcnMoSFdORCBsaXN0LCBDT01QVkFSUyAqcGN2LCBCT09MIGVudW1fYWxsKQp7CiAgICBVSU5UIGlkLCB0b3RhbCA9IDA7CiAgICBJQ0lORk8gaWNpbmZvOwoKICAgIGlkID0gMDsKCiAgICB3aGlsZSAoSUNJbmZvKHBjdi0+ZmNjVHlwZSwgaWQsICZpY2luZm8pKQogICAgewogICAgICAgIHN0cnVjdCBjb2RlY19pbmZvICppYzsKICAgICAgICBEV09SRCBpZHg7CiAgICAgICAgSElDIGhpYzsKCiAgICAgICAgaWQrKzsKCiAgICAgICAgaGljID0gSUNPcGVuKGljaW5mby5mY2NUeXBlLCBpY2luZm8uZmNjSGFuZGxlciwgSUNNT0RFX0NPTVBSRVNTKTsKCiAgICAgICAgaWYgKGhpYykKICAgICAgICB7CiAgICAgICAgICAgIC8qIGZvciB1bmtub3duIHJlYXNvbiBmY2NIYW5kbGVyIHJlcG9ydGVkIGJ5IHRoZSBkcml2ZXIKICAgICAgICAgICAgICogZG9lc24ndCBhbHdheXMgd29yaywgdXNlIHRoZSBvbmUgcmV0dXJuZWQgYnkgSUNJbmZvIGluc3RlYWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBEV09SRCBmY2NIYW5kbGVyID0gaWNpbmZvLmZjY0hhbmRsZXI7CgogICAgICAgICAgICBpZiAoIWVudW1fYWxsICYmIHBjdi0+bHBiaUluKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoSUNDb21wcmVzc1F1ZXJ5KGhpYywgcGN2LT5scGJpSW4sIE5VTEwpICE9IElDRVJSX09LKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJmY2NIYW5kbGVyICVzIGRvZXNuJ3Qgc3VwcG9ydCBpbnB1dCBESUIgZm9ybWF0ICVsZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5lX2RiZ3N0cl9mY2MoaWNpbmZvLmZjY0hhbmRsZXIpLCBwY3YtPmxwYmlJbi0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24pOwogICAgICAgICAgICAgICAgICAgIElDQ2xvc2UoaGljKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgSUNHZXRJbmZvKGhpYywgJmljaW5mbywgc2l6ZW9mKGljaW5mbykpOwogICAgICAgICAgICBpY2luZm8uZmNjSGFuZGxlciA9IGZjY0hhbmRsZXI7CgogICAgICAgICAgICBpZHggPSBTZW5kTWVzc2FnZVcobGlzdCwgQ0JfQUREU1RSSU5HLCAwLCAoTFBBUkFNKWljaW5mby5zekRlc2NyaXB0aW9uKTsKCiAgICAgICAgICAgIGljID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihzdHJ1Y3QgY29kZWNfaW5mbykpOwogICAgICAgICAgICBtZW1jcHkoJmljLT5pY2luZm8sICZpY2luZm8sIHNpemVvZihJQ0lORk8pKTsKICAgICAgICAgICAgaWMtPmhpYyA9IGhpYzsKICAgICAgICAgICAgU2VuZE1lc3NhZ2VXKGxpc3QsIENCX1NFVElURU1EQVRBLCBpZHgsIChMUEFSQU0paWMpOwogICAgICAgIH0KICAgICAgICB0b3RhbCsrOwogICAgfQoKICAgIHJldHVybiB0b3RhbCAhPSAwOwp9CgpzdGF0aWMgSU5UX1BUUiBDQUxMQkFDSyBpY21fY2hvb3NlX2NvbXByZXNzb3JfZGxncHJvYyhIV05EIGhkbGcsIFVJTlQgbXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CiAgICBzd2l0Y2ggKG1zZykKICAgIHsKICAgIGNhc2UgV01fSU5JVERJQUxPRzoKICAgIHsKICAgICAgICBzdHJ1Y3QgY29kZWNfaW5mbyAqaWM7CiAgICAgICAgV0NIQVIgYnVmWzEyOF07CiAgICAgICAgc3RydWN0IGNob29zZV9jb21wcmVzc29yICpjaG9vc2VfY29tcCA9IChzdHJ1Y3QgY2hvb3NlX2NvbXByZXNzb3IgKilscGFyYW07CgogICAgICAgIFNldFdpbmRvd0xvbmdQdHJXKGhkbGcsIERXTFBfVVNFUiwgbHBhcmFtKTsKCiAgICAgICAgLyogRklYTUUgKi8KICAgICAgICBjaG9vc2VfY29tcC0+ZmxhZ3MgJj0gfihJQ01GX0NIT09TRV9EQVRBUkFURSB8IElDTUZfQ0hPT1NFX0tFWUZSQU1FKTsKCiAgICAgICAgaWYgKGNob29zZV9jb21wLT50aXRsZSkKICAgICAgICAgICAgU2V0V2luZG93VGV4dEEoaGRsZywgY2hvb3NlX2NvbXAtPnRpdGxlKTsKCiAgICAgICAgaWYgKCEoY2hvb3NlX2NvbXAtPmZsYWdzICYgSUNNRl9DSE9PU0VfREFUQVJBVEUpKQogICAgICAgIHsKICAgICAgICAgICAgU2hvd1dpbmRvdyhHZXREbGdJdGVtKGhkbGcsIElEQ19EQVRBUkFURV9DSEVDS0JPWCksIFNXX0hJREUpOwogICAgICAgICAgICBTaG93V2luZG93KEdldERsZ0l0ZW0oaGRsZywgSURDX0RBVEFSQVRFKSwgU1dfSElERSk7CiAgICAgICAgICAgIFNob3dXaW5kb3coR2V0RGxnSXRlbShoZGxnLCBJRENfREFUQVJBVEVfS0IpLCBTV19ISURFKTsKICAgICAgICB9CgogICAgICAgIGlmICghKGNob29zZV9jb21wLT5mbGFncyAmIElDTUZfQ0hPT1NFX0tFWUZSQU1FKSkKICAgICAgICB7CiAgICAgICAgICAgIFNob3dXaW5kb3coR2V0RGxnSXRlbShoZGxnLCBJRENfS0VZRlJBTUVfQ0hFQ0tCT1gpLCBTV19ISURFKTsKICAgICAgICAgICAgU2hvd1dpbmRvdyhHZXREbGdJdGVtKGhkbGcsIElEQ19LRVlGUkFNRSksIFNXX0hJREUpOwogICAgICAgICAgICBTaG93V2luZG93KEdldERsZ0l0ZW0oaGRsZywgSURDX0tFWUZSQU1FX0ZSQU1FUyksIFNXX0hJREUpOwogICAgICAgIH0KCiAgICAgICAgLyogRklYTUUgKi8KICAgICAgICBFbmFibGVXaW5kb3coR2V0RGxnSXRlbShoZGxnLCBJRENfUVVBTElUWV9TQ1JPTEwpLCBGQUxTRSk7CiAgICAgICAgRW5hYmxlV2luZG93KEdldERsZ0l0ZW0oaGRsZywgSURDX1FVQUxJVFlfVFhUKSwgRkFMU0UpOwoKICAgICAgICAvKmlmICghKGNob29zZV9jb21wLT5mbGFncyAmIElDTUZfQ0hPT1NFX1BSRVZJRVcpKQogICAgICAgICAgICBTaG93V2luZG93KEdldERsZ0l0ZW0oaGRsZywgSURDX1BSRVZJRVcpLCBTV19ISURFKTsqLwoKICAgICAgICBMb2FkU3RyaW5nVyhNU1ZGVzMyX2hNb2R1bGUsIElEU19GVUxMRlJBTUVTLCBidWYsIDEyOCk7CiAgICAgICAgU2VuZERsZ0l0ZW1NZXNzYWdlVyhoZGxnLCBJRENfQ09NUF9MSVNULCBDQl9BRERTVFJJTkcsIDAsIChMUEFSQU0pYnVmKTsKCiAgICAgICAgaWMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKHN0cnVjdCBjb2RlY19pbmZvKSk7CiAgICAgICAgaWMtPmljaW5mby5mY2NUeXBlID0gc3RyZWFtdHlwZVZJREVPOwogICAgICAgIGljLT5pY2luZm8uZmNjSGFuZGxlciA9IGNvbXB0eXBlRElCOwogICAgICAgIGljLT5oaWMgPSAwOwogICAgICAgIFNlbmREbGdJdGVtTWVzc2FnZVcoaGRsZywgSURDX0NPTVBfTElTVCwgQ0JfU0VUSVRFTURBVEEsIDAsIChMUEFSQU0paWMpOwoKICAgICAgICBlbnVtX2NvbXByZXNzb3JzKEdldERsZ0l0ZW0oaGRsZywgSURDX0NPTVBfTElTVCksICZjaG9vc2VfY29tcC0+Y3YsIGNob29zZV9jb21wLT5mbGFncyAmIElDTUZfQ0hPT1NFX0FMTENPTVBSRVNTT1JTKTsKCiAgICAgICAgU2VuZERsZ0l0ZW1NZXNzYWdlVyhoZGxnLCBJRENfQ09NUF9MSVNULCBDQl9TRVRDVVJTRUwsIDAsIDApOwogICAgICAgIFNldEZvY3VzKEdldERsZ0l0ZW0oaGRsZywgSURDX0NPTVBfTElTVCkpOwoKICAgICAgICBTZXRXaW5kb3dMb25nUHRyVyhoZGxnLCBEV0xQX1VTRVIsIChVTE9OR19QVFIpY2hvb3NlX2NvbXApOwogICAgICAgIGJyZWFrOwogICAgfQoKICAgIGNhc2UgV01fQ09NTUFORDoKICAgICAgICBzd2l0Y2ggKExPV09SRCh3cGFyYW0pKQogICAgICAgIHsKICAgICAgICBjYXNlIElEQ19DT01QX0xJU1Q6CiAgICAgICAgewogICAgICAgICAgICBJTlQgY3VyX3NlbDsKICAgICAgICAgICAgc3RydWN0IGNvZGVjX2luZm8gKmljOwogICAgICAgICAgICBCT09MIGNhbl9jb25maWd1cmUgPSBGQUxTRSwgY2FuX2Fib3V0ID0gRkFMU0U7CiAgICAgICAgICAgIHN0cnVjdCBjaG9vc2VfY29tcHJlc3NvciAqY2hvb3NlX2NvbXA7CgogICAgICAgICAgICBpZiAoSElXT1JEKHdwYXJhbSkgIT0gQ0JOX1NFTENIQU5HRSAmJiBISVdPUkQod3BhcmFtKSAhPSBDQk5fU0VURk9DVVMpCiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNob29zZV9jb21wID0gKHN0cnVjdCBjaG9vc2VfY29tcHJlc3NvciAqKUdldFdpbmRvd0xvbmdQdHJXKGhkbGcsIERXTFBfVVNFUik7CgogICAgICAgICAgICBjdXJfc2VsID0gU2VuZE1lc3NhZ2VXKChIV05EKWxwYXJhbSwgQ0JfR0VUQ1VSU0VMLCAwLCAwKTsKCiAgICAgICAgICAgIGljID0gKHN0cnVjdCBjb2RlY19pbmZvICopU2VuZE1lc3NhZ2VXKChIV05EKWxwYXJhbSwgQ0JfR0VUSVRFTURBVEEsIGN1cl9zZWwsIDApOwogICAgICAgICAgICBpZiAoaWMgJiYgaWMtPmhpYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKElDUXVlcnlDb25maWd1cmUoaWMtPmhpYykgPT0gRFJWQ05GX09LKQogICAgICAgICAgICAgICAgICAgIGNhbl9jb25maWd1cmUgPSBUUlVFOwogICAgICAgICAgICAgICAgaWYgKElDUXVlcnlBYm91dChpYy0+aGljKSA9PSBEUlZDTkZfT0spCiAgICAgICAgICAgICAgICAgICAgY2FuX2Fib3V0ID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBFbmFibGVXaW5kb3coR2V0RGxnSXRlbShoZGxnLCBJRENfQ09ORklHVVJFKSwgY2FuX2NvbmZpZ3VyZSk7CiAgICAgICAgICAgIEVuYWJsZVdpbmRvdyhHZXREbGdJdGVtKGhkbGcsIElEQ19BQk9VVCksIGNhbl9hYm91dCk7CgogICAgICAgICAgICBpZiAoY2hvb3NlX2NvbXAtPmZsYWdzICYgSUNNRl9DSE9PU0VfREFUQVJBVEUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEZJWE1FICovCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNob29zZV9jb21wLT5mbGFncyAmIElDTUZfQ0hPT1NFX0tFWUZSQU1FKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBGSVhNRSAqLwogICAgICAgICAgICB9CgogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgSURDX0NPTkZJR1VSRToKICAgICAgICBjYXNlIElEQ19BQk9VVDoKICAgICAgICB7CiAgICAgICAgICAgIEhXTkQgbGlzdCA9IEdldERsZ0l0ZW0oaGRsZywgSURDX0NPTVBfTElTVCk7CiAgICAgICAgICAgIElOVCBjdXJfc2VsOwogICAgICAgICAgICBzdHJ1Y3QgY29kZWNfaW5mbyAqaWM7CgogICAgICAgICAgICBpZiAoSElXT1JEKHdwYXJhbSkgIT0gQk5fQ0xJQ0tFRCkKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY3VyX3NlbCA9IFNlbmRNZXNzYWdlVyhsaXN0LCBDQl9HRVRDVVJTRUwsIDAsIDApOwoKICAgICAgICAgICAgaWMgPSAoc3RydWN0IGNvZGVjX2luZm8gKilTZW5kTWVzc2FnZVcobGlzdCwgQ0JfR0VUSVRFTURBVEEsIGN1cl9zZWwsIDApOwogICAgICAgICAgICBpZiAoaWMgJiYgaWMtPmhpYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKExPV09SRCh3cGFyYW0pID09IElEQ19DT05GSUdVUkUpCiAgICAgICAgICAgICAgICAgICAgSUNDb25maWd1cmUoaWMtPmhpYywgaGRsZyk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgSUNBYm91dChpYy0+aGljLCBoZGxnKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIElET0s6CiAgICAgICAgewogICAgICAgICAgICBIV05EIGxpc3QgPSBHZXREbGdJdGVtKGhkbGcsIElEQ19DT01QX0xJU1QpOwogICAgICAgICAgICBJTlQgY3VyX3NlbDsKICAgICAgICAgICAgc3RydWN0IGNvZGVjX2luZm8gKmljOwoKICAgICAgICAgICAgaWYgKEhJV09SRCh3cGFyYW0pICE9IEJOX0NMSUNLRUQpCiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGN1cl9zZWwgPSBTZW5kTWVzc2FnZVcobGlzdCwgQ0JfR0VUQ1VSU0VMLCAwLCAwKTsKICAgICAgICAgICAgaWMgPSAoc3RydWN0IGNvZGVjX2luZm8gKilTZW5kTWVzc2FnZVcobGlzdCwgQ0JfR0VUSVRFTURBVEEsIGN1cl9zZWwsIDApOwogICAgICAgICAgICBpZiAoaWMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cnVjdCBjaG9vc2VfY29tcHJlc3NvciAqY2hvb3NlX2NvbXAgPSAoc3RydWN0IGNob29zZV9jb21wcmVzc29yICopR2V0V2luZG93TG9uZ1B0clcoaGRsZywgRFdMUF9VU0VSKTsKCiAgICAgICAgICAgICAgICBjaG9vc2VfY29tcC0+Y3YuaGljID0gaWMtPmhpYzsKICAgICAgICAgICAgICAgIGNob29zZV9jb21wLT5jdi5mY2NUeXBlID0gaWMtPmljaW5mby5mY2NUeXBlOwogICAgICAgICAgICAgICAgY2hvb3NlX2NvbXAtPmN2LmZjY0hhbmRsZXIgPSBpYy0+aWNpbmZvLmZjY0hhbmRsZXI7CiAgICAgICAgICAgICAgICAvKiBGSVhNRTogZmlsbCBldmVyeXRoaW5nIGVsc2UgKi8KCiAgICAgICAgICAgICAgICAvKiBwcmV2ZW50IGNsb3NpbmcgdGhlIGNvZGVjIGhhbmRsZSBiZWxvdyAqLwogICAgICAgICAgICAgICAgaWMtPmhpYyA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCiAgICAgICAgY2FzZSBJRENBTkNFTDoKICAgICAgICB7CiAgICAgICAgICAgIEhXTkQgbGlzdCA9IEdldERsZ0l0ZW0oaGRsZywgSURDX0NPTVBfTElTVCk7CiAgICAgICAgICAgIElOVCBpZHggPSAwOwoKICAgICAgICAgICAgaWYgKEhJV09SRCh3cGFyYW0pICE9IEJOX0NMSUNLRUQpCiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIHdoaWxlICgxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJ1Y3QgY29kZWNfaW5mbyAqaWM7CiAgICAKICAgICAgICAgICAgICAgIGljID0gKHN0cnVjdCBjb2RlY19pbmZvICopU2VuZE1lc3NhZ2VXKGxpc3QsIENCX0dFVElURU1EQVRBLCBpZHgrKywgMCk7CgogICAgICAgICAgICAgICAgaWYgKCFpYyB8fCAoTE9OR19QVFIpaWMgPT0gQ0JfRVJSKSBicmVhazsKCiAgICAgICAgICAgICAgICBpZiAoaWMtPmhpYykgSUNDbG9zZShpYy0+aGljKTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGljKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgRW5kRGlhbG9nKGhkbGcsIExPV09SRCh3cGFyYW0pID09IElET0spOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIGJyZWFrOwogICAgfQoKICAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ0NvbXByZXNzb3JDaG9vc2UgICBbTVNWRlczMi5AXQogKi8KQk9PTCBWRldBUEkgSUNDb21wcmVzc29yQ2hvb3NlKEhXTkQgaHduZCwgVUlOVCB1aUZsYWdzLCBMUFZPSUQgcHZJbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBscERhdGEsIFBDT01QVkFSUyBwYywgTFBTVFIgbHBzelRpdGxlKQp7CiAgICBzdHJ1Y3QgY2hvb3NlX2NvbXByZXNzb3IgY2hvb3NlX2NvbXA7CiAgICBCT09MIHJldDsKCiAgICBUUkFDRSgiKCVwLCUwOHgsJXAsJXAsJXAsJXMpXG4iLCBod25kLCB1aUZsYWdzLCBwdkluLCBscERhdGEsIHBjLCBscHN6VGl0bGUpOwoKICAgIGlmICghcGMgfHwgcGMtPmNiU2l6ZSAhPSBzaXplb2YoQ09NUFZBUlMpKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAoIShwYy0+ZHdGbGFncyAmIElDTUZfQ09NUFZBUlNfVkFMSUQpKQogICAgewogICAgICAgIHBjLT5kd0ZsYWdzICAgPSAwOwogICAgICAgIHBjLT5mY2NUeXBlICAgPSBwYy0+ZmNjSGFuZGxlciA9IDA7CiAgICAgICAgcGMtPmhpYyAgICAgICA9IE5VTEw7CiAgICAgICAgcGMtPmxwYmlJbiAgICA9IE5VTEw7CiAgICAgICAgcGMtPmxwYmlPdXQgICA9IE5VTEw7CiAgICAgICAgcGMtPmxwQml0c091dCA9IHBjLT5scEJpdHNQcmV2ID0gcGMtPmxwU3RhdGUgPSBOVUxMOwogICAgICAgIHBjLT5sUSAgICAgICAgPSBJQ1FVQUxJVFlfREVGQVVMVDsKICAgICAgICBwYy0+bEtleSAgICAgID0gLTE7CiAgICAgICAgcGMtPmxEYXRhUmF0ZSA9IDMwMDsgLyoga0IgKi8KICAgICAgICBwYy0+bHBTdGF0ZSAgID0gTlVMTDsKICAgICAgICBwYy0+Y2JTdGF0ZSAgID0gMDsKICAgIH0KICAgIGlmIChwYy0+ZmNjVHlwZSA9PSAwKQogICAgICAgIHBjLT5mY2NUeXBlID0gSUNUWVBFX1ZJREVPOwoKICAgIGNob29zZV9jb21wLmN2ID0gKnBjOwogICAgY2hvb3NlX2NvbXAuZmxhZ3MgPSB1aUZsYWdzOwogICAgY2hvb3NlX2NvbXAudGl0bGUgPSBscHN6VGl0bGU7CgogICAgcmV0ID0gRGlhbG9nQm94UGFyYW1XKE1TVkZXMzJfaE1vZHVsZSwgTUFLRUlOVFJFU09VUkNFVyhJQ01fQ0hPT1NFX0NPTVBSRVNTT1IpLCBod25kLAogICAgICAgICAgICAgICAgICAgICAgICAgIGljbV9jaG9vc2VfY29tcHJlc3Nvcl9kbGdwcm9jLCAoTFBBUkFNKSZjaG9vc2VfY29tcCk7CgogICAgaWYgKHJldCkKICAgIHsKICAgICAgICAqcGMgPSBjaG9vc2VfY29tcC5jdjsKICAgICAgICBwYy0+ZHdGbGFncyB8PSBJQ01GX0NPTVBWQVJTX1ZBTElEOwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlDQ29tcHJlc3NvckZyZWUgICBbTVNWRlczMi5AXQogKi8Kdm9pZCBWRldBUEkgSUNDb21wcmVzc29yRnJlZShQQ09NUFZBUlMgcGMpCnsKICBUUkFDRSgiKCVwKVxuIixwYyk7CgogIGlmIChwYyAhPSBOVUxMICYmIHBjLT5jYlNpemUgPT0gc2l6ZW9mKENPTVBWQVJTKSkgewogICAgaWYgKHBjLT5oaWMgIT0gTlVMTCkgewogICAgICBJQ0Nsb3NlKHBjLT5oaWMpOwogICAgICBwYy0+aGljID0gTlVMTDsKICAgIH0KICAgIGlmIChwYy0+bHBiaUluICE9IE5VTEwpIHsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGMtPmxwYmlJbik7CiAgICAgIHBjLT5scGJpSW4gPSBOVUxMOwogICAgfQogICAgaWYgKHBjLT5scEJpdHNPdXQgIT0gTlVMTCkgewogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBCaXRzT3V0KTsKICAgICAgcGMtPmxwQml0c091dCA9IE5VTEw7CiAgICB9CiAgICBpZiAocGMtPmxwQml0c1ByZXYgIT0gTlVMTCkgewogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBCaXRzUHJldik7CiAgICAgIHBjLT5scEJpdHNQcmV2ID0gTlVMTDsKICAgIH0KICAgIGlmIChwYy0+bHBTdGF0ZSAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBjLT5scFN0YXRlKTsKICAgICAgcGMtPmxwU3RhdGUgPSBOVUxMOwogICAgfQogICAgcGMtPmR3RmxhZ3MgPSAwOwogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1TVklERU9fU2VuZE1lc3NhZ2UKICoKICoKICovCkxSRVNVTFQgTVNWSURFT19TZW5kTWVzc2FnZShXSU5FX0hJQyogd2hpYywgVUlOVCBtc2csIERXT1JEX1BUUiBsUGFyYW0xLCBEV09SRF9QVFIgbFBhcmFtMikKewogICAgTFJFU1VMVCAgICAgcmV0OwogICAgCiNkZWZpbmUgWFgoeCkgY2FzZSB4OiBUUkFDRSgiKCVwLCIjeCIsMHglMDhseCwweCUwOGx4KVxuIix3aGljLGxQYXJhbTEsbFBhcmFtMik7IGJyZWFrOwogICAgCiAgICBzd2l0Y2ggKG1zZykgewogICAgICAgIC8qIERSVl8qICovCiAgICAgICAgWFgoRFJWX0xPQUQpOwogICAgICAgIFhYKERSVl9FTkFCTEUpOwogICAgICAgIFhYKERSVl9PUEVOKTsKICAgICAgICBYWChEUlZfQ0xPU0UpOwogICAgICAgIFhYKERSVl9ESVNBQkxFKTsKICAgICAgICBYWChEUlZfRlJFRSk7CiAgICAgICAgLyogSUNNX1JFU0VSVkVEK1ggKi8KICAgICAgICBYWChJQ01fQUJPVVQpOwogICAgICAgIFhYKElDTV9DT05GSUdVUkUpOwogICAgICAgIFhYKElDTV9HRVQpOwogICAgICAgIFhYKElDTV9HRVRJTkZPKTsKICAgICAgICBYWChJQ01fR0VUREVGQVVMVFFVQUxJVFkpOwogICAgICAgIFhYKElDTV9HRVRRVUFMSVRZKTsKICAgICAgICBYWChJQ01fR0VUU1RBVEUpOwogICAgICAgIFhYKElDTV9TRVRRVUFMSVRZKTsKICAgICAgICBYWChJQ01fU0VUKTsKICAgICAgICBYWChJQ01fU0VUU1RBVEUpOwogICAgICAgIC8qIElDTV9VU0VSK1ggKi8KICAgICAgICBYWChJQ01fQ09NUFJFU1NfRlJBTUVTX0lORk8pOwogICAgICAgIFhYKElDTV9DT01QUkVTU19HRVRfRk9STUFUKTsKICAgICAgICBYWChJQ01fQ09NUFJFU1NfR0VUX1NJWkUpOwogICAgICAgIFhYKElDTV9DT01QUkVTU19RVUVSWSk7CiAgICAgICAgWFgoSUNNX0NPTVBSRVNTX0JFR0lOKTsKICAgICAgICBYWChJQ01fQ09NUFJFU1MpOwogICAgICAgIFhYKElDTV9DT01QUkVTU19FTkQpOwogICAgICAgIFhYKElDTV9ERUNPTVBSRVNTX0dFVF9GT1JNQVQpOwogICAgICAgIFhYKElDTV9ERUNPTVBSRVNTX1FVRVJZKTsKICAgICAgICBYWChJQ01fREVDT01QUkVTU19CRUdJTik7CiAgICAgICAgWFgoSUNNX0RFQ09NUFJFU1MpOwogICAgICAgIFhYKElDTV9ERUNPTVBSRVNTX0VORCk7CiAgICAgICAgWFgoSUNNX0RFQ09NUFJFU1NfU0VUX1BBTEVUVEUpOwogICAgICAgIFhYKElDTV9ERUNPTVBSRVNTX0dFVF9QQUxFVFRFKTsKICAgICAgICBYWChJQ01fRFJBV19RVUVSWSk7CiAgICAgICAgWFgoSUNNX0RSQVdfQkVHSU4pOwogICAgICAgIFhYKElDTV9EUkFXX0dFVF9QQUxFVFRFKTsKICAgICAgICBYWChJQ01fRFJBV19TVEFSVCk7CiAgICAgICAgWFgoSUNNX0RSQVdfU1RPUCk7CiAgICAgICAgWFgoSUNNX0RSQVdfRU5EKTsKICAgICAgICBYWChJQ01fRFJBV19HRVRUSU1FKTsKICAgICAgICBYWChJQ01fRFJBVyk7CiAgICAgICAgWFgoSUNNX0RSQVdfV0lORE9XKTsKICAgICAgICBYWChJQ01fRFJBV19TRVRUSU1FKTsKICAgICAgICBYWChJQ01fRFJBV19SRUFMSVpFKTsKICAgICAgICBYWChJQ01fRFJBV19GTFVTSCk7CiAgICAgICAgWFgoSUNNX0RSQVdfUkVOREVSQlVGRkVSKTsKICAgICAgICBYWChJQ01fRFJBV19TVEFSVF9QTEFZKTsKICAgICAgICBYWChJQ01fRFJBV19TVE9QX1BMQVkpOwogICAgICAgIFhYKElDTV9EUkFXX1NVR0dFU1RGT1JNQVQpOwogICAgICAgIFhYKElDTV9EUkFXX0NIQU5HRVBBTEVUVEUpOwogICAgICAgIFhYKElDTV9HRVRCVUZGRVJTV0FOVEVEKTsKICAgICAgICBYWChJQ01fR0VUREVGQVVMVEtFWUZSQU1FUkFURSk7CiAgICAgICAgWFgoSUNNX0RFQ09NUFJFU1NFWF9CRUdJTik7CiAgICAgICAgWFgoSUNNX0RFQ09NUFJFU1NFWF9RVUVSWSk7CiAgICAgICAgWFgoSUNNX0RFQ09NUFJFU1NFWCk7CiAgICAgICAgWFgoSUNNX0RFQ09NUFJFU1NFWF9FTkQpOwogICAgICAgIFhYKElDTV9TRVRfU1RBVFVTX1BST0MpOwogICAgZGVmYXVsdDoKICAgICAgICBGSVhNRSgiKCVwLDB4JTA4bHgsMHglMDhseCwweCUwOGx4KSB1bmtub3duIG1lc3NhZ2VcbiIsd2hpYywoRFdPUkQpbXNnLGxQYXJhbTEsbFBhcmFtMik7CiAgICB9CiAgICAKI3VuZGVmIFhYCiAgICAKICAgIGlmICh3aGljLT5kcml2ZXJwcm9jKSB7CgkvKiBkd0RyaXZlcklkIHBhcmFtZXRlciBpcyB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIERSVl9PUEVOICovCiAgICAgICAgcmV0ID0gd2hpYy0+ZHJpdmVycHJvYyh3aGljLT5kcml2ZXJJZCwgd2hpYy0+aGRydiwgbXNnLCBsUGFyYW0xLCBsUGFyYW0yKTsKICAgIH0gZWxzZSB7CiAgICAgICAgcmV0ID0gU2VuZERyaXZlck1lc3NhZ2Uod2hpYy0+aGRydiwgbXNnLCBsUGFyYW0xLCBsUGFyYW0yKTsKICAgIH0KCiAgICBUUkFDRSgiCS0+IDB4JTA4bHhcbiIsIHJldCk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlDU2VuZE1lc3NhZ2UJCQlbTVNWRlczMi5AXQogKi8KTFJFU1VMVCBWRldBUEkgSUNTZW5kTWVzc2FnZShISUMgaGljLCBVSU5UIG1zZywgRFdPUkRfUFRSIGxQYXJhbTEsIERXT1JEX1BUUiBsUGFyYW0yKSAKewogICAgV0lORV9ISUMqICAgd2hpYyA9IE1TVklERU9fR2V0SGljUHRyKGhpYyk7CgogICAgaWYgKCF3aGljKSByZXR1cm4gSUNFUlJfQkFESEFORExFOwogICAgcmV0dXJuIE1TVklERU9fU2VuZE1lc3NhZ2Uod2hpYywgbXNnLCBsUGFyYW0xLCBsUGFyYW0yKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ0RyYXdCZWdpbgkJW01TVkZXMzIuQF0KICovCkRXT1JEIFZGV0FQSVYgSUNEcmF3QmVnaW4oCglISUMgICAgICAgICAgICAgICAgaGljLCAgICAgLyogW2luXSAqLwoJRFdPUkQgICAgICAgICAgICAgIGR3RmxhZ3MsIC8qIFtpbl0gZmxhZ3MgKi8KCUhQQUxFVFRFICAgICAgICAgICBocGFsLCAgICAvKiBbaW5dIHBhbGV0dGUgdG8gZHJhdyB3aXRoICovCglIV05EICAgICAgICAgICAgICAgaHduZCwgICAgLyogW2luXSB3aW5kb3cgdG8gZHJhdyB0byAqLwoJSERDICAgICAgICAgICAgICAgIGhkYywgICAgIC8qIFtpbl0gSERDIHRvIGRyYXcgdG8gKi8KCUlOVCAgICAgICAgICAgICAgICB4RHN0LCAgICAvKiBbaW5dIGRlc3RpbmF0aW9uIHJlY3RhbmdsZSAqLwoJSU5UICAgICAgICAgICAgICAgIHlEc3QsICAgIC8qIFtpbl0gKi8KCUlOVCAgICAgICAgICAgICAgICBkeERzdCwgICAvKiBbaW5dICovCglJTlQgICAgICAgICAgICAgICAgZHlEc3QsICAgLyogW2luXSAqLwoJTFBCSVRNQVBJTkZPSEVBREVSIGxwYmksICAgIC8qIFtpbl0gZm9ybWF0IG9mIGZyYW1lIHRvIGRyYXcgKi8KCUlOVCAgICAgICAgICAgICAgICB4U3JjLCAgICAvKiBbaW5dIHNvdXJjZSByZWN0YW5nbGUgKi8KCUlOVCAgICAgICAgICAgICAgICB5U3JjLCAgICAvKiBbaW5dICovCglJTlQgICAgICAgICAgICAgICAgZHhTcmMsICAgLyogW2luXSAqLwoJSU5UICAgICAgICAgICAgICAgIGR5U3JjLCAgIC8qIFtpbl0gKi8KCURXT1JEICAgICAgICAgICAgICBkd1JhdGUsICAvKiBbaW5dIGZyYW1lcy9zZWNvbmQgPSAoZHdSYXRlL2R3U2NhbGUpICovCglEV09SRCAgICAgICAgICAgICAgZHdTY2FsZSkgLyogW2luXSAqLwp7CgoJSUNEUkFXQkVHSU4JaWNkYjsKCglUUkFDRSgiKCVwLCVsZCwlcCwlcCwlcCwldSwldSwldSwldSwlcCwldSwldSwldSwldSwlbGQsJWxkKVxuIiwKCQkgIGhpYywgZHdGbGFncywgaHBhbCwgaHduZCwgaGRjLCB4RHN0LCB5RHN0LCBkeERzdCwgZHlEc3QsCgkJICBscGJpLCB4U3JjLCB5U3JjLCBkeFNyYywgZHlTcmMsIGR3UmF0ZSwgZHdTY2FsZSk7CgoJaWNkYi5kd0ZsYWdzID0gZHdGbGFnczsKCWljZGIuaHBhbCA9IGhwYWw7CglpY2RiLmh3bmQgPSBod25kOwoJaWNkYi5oZGMgPSBoZGM7CglpY2RiLnhEc3QgPSB4RHN0OwoJaWNkYi55RHN0ID0geURzdDsKCWljZGIuZHhEc3QgPSBkeERzdDsKCWljZGIuZHlEc3QgPSBkeURzdDsKCWljZGIubHBiaSA9IGxwYmk7CglpY2RiLnhTcmMgPSB4U3JjOwoJaWNkYi55U3JjID0geVNyYzsKCWljZGIuZHhTcmMgPSBkeFNyYzsKCWljZGIuZHlTcmMgPSBkeVNyYzsKCWljZGIuZHdSYXRlID0gZHdSYXRlOwoJaWNkYi5kd1NjYWxlID0gZHdTY2FsZTsKCXJldHVybiBJQ1NlbmRNZXNzYWdlKGhpYyxJQ01fRFJBV19CRUdJTiwoRFdPUkRfUFRSKSZpY2RiLHNpemVvZihpY2RiKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSUNEcmF3CQkJW01TVkZXMzIuQF0KICovCkRXT1JEIFZGV0FQSVYgSUNEcmF3KEhJQyBoaWMsIERXT1JEIGR3RmxhZ3MsIExQVk9JRCBscEZvcm1hdCwgTFBWT0lEIGxwRGF0YSwgRFdPUkQgY2JEYXRhLCBMT05HIGxUaW1lKSB7CglJQ0RSQVcJaWNkOwoKCVRSQUNFKCIoJXAsJWxkLCVwLCVwLCVsZCwlbGQpXG4iLGhpYyxkd0ZsYWdzLGxwRm9ybWF0LGxwRGF0YSxjYkRhdGEsbFRpbWUpOwoKCWljZC5kd0ZsYWdzID0gZHdGbGFnczsKCWljZC5scEZvcm1hdCA9IGxwRm9ybWF0OwoJaWNkLmxwRGF0YSA9IGxwRGF0YTsKCWljZC5jYkRhdGEgPSBjYkRhdGE7CglpY2QubFRpbWUgPSBsVGltZTsKCglyZXR1cm4gSUNTZW5kTWVzc2FnZShoaWMsSUNNX0RSQVcsKERXT1JEX1BUUikmaWNkLHNpemVvZihpY2QpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ0Nsb3NlCQkJW01TVkZXMzIuQF0KICovCkxSRVNVTFQgV0lOQVBJIElDQ2xvc2UoSElDIGhpYykKewogICAgV0lORV9ISUMqIHdoaWMgPSBNU1ZJREVPX0dldEhpY1B0cihoaWMpOwogICAgV0lORV9ISUMqKiBwOwoKICAgIFRSQUNFKCIoJXApXG4iLGhpYyk7CgogICAgaWYgKCF3aGljKSByZXR1cm4gSUNFUlJfQkFESEFORExFOwoKICAgIGlmICh3aGljLT5kcml2ZXJwcm9jKSAKICAgIHsKICAgICAgICBNU1ZJREVPX1NlbmRNZXNzYWdlKHdoaWMsIERSVl9DTE9TRSwgMCwgMCk7CiAgICAgICAgTVNWSURFT19TZW5kTWVzc2FnZSh3aGljLCBEUlZfRElTQUJMRSwgMCwgMCk7CiAgICAgICAgTVNWSURFT19TZW5kTWVzc2FnZSh3aGljLCBEUlZfRlJFRSwgMCwgMCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgQ2xvc2VEcml2ZXIod2hpYy0+aGRydiwgMCwgMCk7CiAgICB9CgogICAgLyogcmVtb3ZlIHdoaWMgZnJvbSBsaXN0ICovCiAgICBmb3IgKHAgPSAmTVNWSURFT19GaXJzdEhpYzsgKnAgIT0gTlVMTDsgcCA9ICYoKCpwKS0+bmV4dCkpCiAgICB7CiAgICAgICAgaWYgKCgqcCkgPT0gd2hpYykKICAgICAgICB7CiAgICAgICAgICAgICpwID0gd2hpYy0+bmV4dDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHdoaWMpOwogICAgcmV0dXJuIDA7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ0ltYWdlQ29tcHJlc3MJW01TVkZXMzIuQF0KICovCkhBTkRMRSBWRldBUEkgSUNJbWFnZUNvbXByZXNzKAoJSElDIGhpYywgVUlOVCB1aUZsYWdzLAoJTFBCSVRNQVBJTkZPIGxwYmlJbiwgTFBWT0lEIGxwQml0cywKCUxQQklUTUFQSU5GTyBscGJpT3V0LCBMT05HIGxRdWFsaXR5LAoJTE9ORyogcGxTaXplKQp7CglGSVhNRSgiKCVwLCUwOHgsJXAsJXAsJXAsJWxkLCVwKVxuIiwKCQloaWMsIHVpRmxhZ3MsIGxwYmlJbiwgbHBCaXRzLCBscGJpT3V0LCBsUXVhbGl0eSwgcGxTaXplKTsKCglyZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJQ0ltYWdlRGVjb21wcmVzcwlbTVNWRlczMi5AXQogKi8KCkhBTkRMRSBWRldBUEkgSUNJbWFnZURlY29tcHJlc3MoCglISUMgaGljLCBVSU5UIHVpRmxhZ3MsIExQQklUTUFQSU5GTyBscGJpSW4sCglMUFZPSUQgbHBCaXRzLCBMUEJJVE1BUElORk8gbHBiaU91dCkKewoJSEdMT0JBTAloTWVtID0gTlVMTDsKCUJZVEUqCXBNZW0gPSBOVUxMOwoJQk9PTAliUmVsZWFzZUlDID0gRkFMU0U7CglCWVRFKglwSGRyID0gTlVMTDsKCVVMT05HCWNiSGRyID0gMDsKCUJPT0wJYlN1Y2NlZWRlZCA9IEZBTFNFOwoJQk9PTAliSW5EZWNvbXByZXNzID0gRkFMU0U7CglEV09SRAliaVNpemVJbWFnZTsKCglUUkFDRSgiKCVwLCUwOHgsJXAsJXAsJXApXG4iLAoJCWhpYywgdWlGbGFncywgbHBiaUluLCBscEJpdHMsIGxwYmlPdXQpOwoKCWlmICggaGljID09IE5VTEwgKQoJewoJCWhpYyA9IElDRGVjb21wcmVzc09wZW4oIElDVFlQRV9WSURFTywgMCwgJmxwYmlJbi0+Ym1pSGVhZGVyLCAobHBiaU91dCAhPSBOVUxMKSA/ICZscGJpT3V0LT5ibWlIZWFkZXIgOiBOVUxMICk7CgkJaWYgKCBoaWMgPT0gTlVMTCApCgkJewoJCQlXQVJOKCJubyBoYW5kbGVyXG4iICk7CgkJCWdvdG8gZXJyOwoJCX0KCQliUmVsZWFzZUlDID0gVFJVRTsKCX0KCWlmICggdWlGbGFncyAhPSAwICkKCXsKCQlGSVhNRSggInVua25vd24gZmxhZyAlMDh4XG4iLCB1aUZsYWdzICk7CgkJZ290byBlcnI7Cgl9CglpZiAoIGxwYmlJbiA9PSBOVUxMIHx8IGxwQml0cyA9PSBOVUxMICkKCXsKCQlXQVJOKCJpbnZhbGlkIGFyZ3VtZW50XG4iKTsKCQlnb3RvIGVycjsKCX0KCglpZiAoIGxwYmlPdXQgIT0gTlVMTCApCgl7CgkJaWYgKCBscGJpT3V0LT5ibWlIZWFkZXIuYmlTaXplICE9IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSApCgkJCWdvdG8gZXJyOwoJCWNiSGRyID0gc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpOwoJCWlmICggbHBiaU91dC0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPT0gMyApCgkJCWNiSGRyICs9IHNpemVvZihEV09SRCkqMzsKCQllbHNlCgkJaWYgKCBscGJpT3V0LT5ibWlIZWFkZXIuYmlCaXRDb3VudCA8PSA4ICkKCQl7CgkJCWlmICggbHBiaU91dC0+Ym1pSGVhZGVyLmJpQ2xyVXNlZCA9PSAwICkKCQkJCWNiSGRyICs9IHNpemVvZihSR0JRVUFEKSAqICgxPDxscGJpT3V0LT5ibWlIZWFkZXIuYmlCaXRDb3VudCk7CgkJCWVsc2UKCQkJCWNiSGRyICs9IHNpemVvZihSR0JRVUFEKSAqIGxwYmlPdXQtPmJtaUhlYWRlci5iaUNsclVzZWQ7CgkJfQoJfQoJZWxzZQoJewoJCVRSQUNFKCAiZ2V0IGZvcm1hdFxuIiApOwoKCQljYkhkciA9IElDRGVjb21wcmVzc0dldEZvcm1hdFNpemUoaGljLGxwYmlJbik7CgkJaWYgKCBjYkhkciA8IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSApCgkJCWdvdG8gZXJyOwoJCXBIZHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLGNiSGRyK3NpemVvZihSR0JRVUFEKSoyNTYpOwoJCWlmICggcEhkciA9PSBOVUxMICkKCQkJZ290byBlcnI7CgkJWmVyb01lbW9yeSggcEhkciwgY2JIZHIrc2l6ZW9mKFJHQlFVQUQpKjI1NiApOwoJCWlmICggSUNEZWNvbXByZXNzR2V0Rm9ybWF0KCBoaWMsIGxwYmlJbiwgKEJJVE1BUElORk8qKXBIZHIgKSAhPSBJQ0VSUl9PSyApCgkJCWdvdG8gZXJyOwoJCWxwYmlPdXQgPSAoQklUTUFQSU5GTyopcEhkcjsKCQlpZiAoIGxwYmlPdXQtPmJtaUhlYWRlci5iaUJpdENvdW50IDw9IDggJiYKCQkJIElDRGVjb21wcmVzc0dldFBhbGV0dGUoIGhpYywgbHBiaUluLCBscGJpT3V0ICkgIT0gSUNFUlJfT0sgJiYKCQkJIGxwYmlJbi0+Ym1pSGVhZGVyLmJpQml0Q291bnQgPT0gbHBiaU91dC0+Ym1pSGVhZGVyLmJpQml0Q291bnQgKQoJCXsKCQkJaWYgKCBscGJpSW4tPmJtaUhlYWRlci5iaUNsclVzZWQgPT0gMCApCgkJCQltZW1jcHkoIGxwYmlPdXQtPmJtaUNvbG9ycywgbHBiaUluLT5ibWlDb2xvcnMsIHNpemVvZihSR0JRVUFEKSooMTw8bHBiaU91dC0+Ym1pSGVhZGVyLmJpQml0Q291bnQpICk7CgkJCWVsc2UKCQkJCW1lbWNweSggbHBiaU91dC0+Ym1pQ29sb3JzLCBscGJpSW4tPmJtaUNvbG9ycywgc2l6ZW9mKFJHQlFVQUQpKmxwYmlJbi0+Ym1pSGVhZGVyLmJpQ2xyVXNlZCApOwoJCX0KCQlpZiAoIGxwYmlPdXQtPmJtaUhlYWRlci5iaUJpdENvdW50IDw9IDggJiYKCQkJIGxwYmlPdXQtPmJtaUhlYWRlci5iaUNsclVzZWQgPT0gMCApCgkJCWxwYmlPdXQtPmJtaUhlYWRlci5iaUNsclVzZWQgPSAxPDxscGJpT3V0LT5ibWlIZWFkZXIuYmlCaXRDb3VudDsKCgkJbHBiaU91dC0+Ym1pSGVhZGVyLmJpU2l6ZSA9IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKTsKCQljYkhkciA9IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSArIHNpemVvZihSR0JRVUFEKSpscGJpT3V0LT5ibWlIZWFkZXIuYmlDbHJVc2VkOwoJfQoKCWJpU2l6ZUltYWdlID0gbHBiaU91dC0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlOwoJaWYgKCBiaVNpemVJbWFnZSA9PSAwICkKCQliaVNpemVJbWFnZSA9ICgoKChscGJpT3V0LT5ibWlIZWFkZXIuYmlXaWR0aCAqIGxwYmlPdXQtPmJtaUhlYWRlci5iaUJpdENvdW50ICsgNykgPj4gMykgKyAzKSAmICh+MykpICogYWJzKGxwYmlPdXQtPmJtaUhlYWRlci5iaUhlaWdodCk7CgoJVFJBQ0UoICJjYWxsIElDRGVjb21wcmVzc0JlZ2luXG4iICk7CgoJaWYgKCBJQ0RlY29tcHJlc3NCZWdpbiggaGljLCBscGJpSW4sIGxwYmlPdXQgKSAhPSBJQ0VSUl9PSyApCgkJZ290byBlcnI7CgliSW5EZWNvbXByZXNzID0gVFJVRTsKCglUUkFDRSggImNiSGRyICVsZCwgYmlTaXplSW1hZ2UgJWxkXG4iLCBjYkhkciwgYmlTaXplSW1hZ2UgKTsKCgloTWVtID0gR2xvYmFsQWxsb2MoIEdNRU1fTU9WRUFCTEV8R01FTV9aRVJPSU5JVCwgY2JIZHIgKyBiaVNpemVJbWFnZSApOwoJaWYgKCBoTWVtID09IE5VTEwgKQoJewoJCVdBUk4oICJvdXQgb2YgbWVtb3J5XG4iICk7CgkJZ290byBlcnI7Cgl9CglwTWVtID0gKEJZVEUqKUdsb2JhbExvY2soIGhNZW0gKTsKCWlmICggcE1lbSA9PSBOVUxMICkKCQlnb3RvIGVycjsKCW1lbWNweSggcE1lbSwgbHBiaU91dCwgY2JIZHIgKTsKCglUUkFDRSggImNhbGwgSUNEZWNvbXByZXNzXG4iICk7CglpZiAoIElDRGVjb21wcmVzcyggaGljLCAwLCAmbHBiaUluLT5ibWlIZWFkZXIsIGxwQml0cywgJmxwYmlPdXQtPmJtaUhlYWRlciwgcE1lbStjYkhkciApICE9IElDRVJSX09LICkKCQlnb3RvIGVycjsKCgliU3VjY2VlZGVkID0gVFJVRTsKZXJyOgoJaWYgKCBiSW5EZWNvbXByZXNzICkKCQlJQ0RlY29tcHJlc3NFbmQoIGhpYyApOwoJaWYgKCBiUmVsZWFzZUlDICkKCQlJQ0Nsb3NlKGhpYyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLHBIZHIpOwoJaWYgKCBwTWVtICE9IE5VTEwgKQoJCUdsb2JhbFVubG9jayggaE1lbSApOwoJaWYgKCAhYlN1Y2NlZWRlZCAmJiBoTWVtICE9IE5VTEwgKQoJewoJCUdsb2JhbEZyZWUoaE1lbSk7IGhNZW0gPSBOVUxMOwoJfQoKCXJldHVybiAoSEFORExFKWhNZW07Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIElDU2VxQ29tcHJlc3NGcmFtZSAgIFtNU1ZGVzMyLkBdCiAqLwpMUFZPSUQgVkZXQVBJIElDU2VxQ29tcHJlc3NGcmFtZShQQ09NUFZBUlMgcGMsIFVJTlQgdWlGbGFncywgTFBWT0lEIGxwQml0cywgQk9PTCAqcGZLZXksIExPTkcgKnBsU2l6ZSkKewogICAgSUNDT01QUkVTUyogaWNDb21wID0gKElDQ09NUFJFU1MgKilwYy0+bHBTdGF0ZTsKICAgIERXT1JEIHJldDsKICAgIFRSQUNFKCIoJXAsIDB4JTA4eCwgJXAsICVwLCAlcClcbiIsIHBjLCB1aUZsYWdzLCBscEJpdHMsIHBmS2V5LCBwbFNpemUpOwoKICAgIGlmIChwYy0+Y2JTdGF0ZSAhPSBzaXplb2YoSUNDT01QUkVTUykpCiAgICB7CiAgICAgICBFUlIoIkludmFsaWQgY2JTdGF0ZSAoJWxpIHNob3VsZCBiZSAlaSlcbiIsIHBjLT5jYlN0YXRlLCBzaXplb2YoSUNDT01QUkVTUykpOwogICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKCFwYy0+bEtleUNvdW50KyspCiAgICAgICBpY0NvbXAtPmR3RmxhZ3MgPSBJQ0NPTVBSRVNTX0tFWUZSQU1FOwogICAgZWxzZQogICAgewogICAgICAgIGlmIChwYy0+bEtleSAmJiBwYy0+bEtleUNvdW50ID09IChwYy0+bEtleSAtIDEpKQogICAgICAgIC8qIE5vIGtleSBmcmFtZXMgaWYgcGMtPmxLZXkgPT0gMCAqLwogICAgICAgICAgIHBjLT5sS2V5Q291bnQgPSAwOwoJaWNDb21wLT5kd0ZsYWdzID0gMDsKICAgIH0KCiAgICBpY0NvbXAtPmxwSW5wdXQgPSBscEJpdHM7CiAgICBpY0NvbXAtPmxGcmFtZU51bSA9IHBjLT5sRnJhbWUrKzsKICAgIGljQ29tcC0+bHBPdXRwdXQgPSBwYy0+bHBCaXRzT3V0OwogICAgaWNDb21wLT5scFByZXYgPSBwYy0+bHBCaXRzUHJldjsKICAgIHJldCA9IElDU2VuZE1lc3NhZ2UocGMtPmhpYywgSUNNX0NPTVBSRVNTLCAoRFdPUkRfUFRSKWljQ29tcCwgc2l6ZW9mKGljQ29tcCkpOwoKICAgIGlmIChpY0NvbXAtPmR3RmxhZ3MgJiBBVklJRl9LRVlGUkFNRSkKICAgIHsKICAgICAgIHBjLT5sS2V5Q291bnQgPSAxOwogICAgICAgKnBmS2V5ID0gVFJVRTsKICAgICAgIFRSQUNFKCJLZXkgZnJhbWVcbiIpOwogICAgfQogICAgZWxzZQogICAgICAgKnBmS2V5ID0gRkFMU0U7CgogICAgKnBsU2l6ZSA9IGljQ29tcC0+bHBiaU91dHB1dC0+YmlTaXplSW1hZ2U7CiAgICBUUkFDRSgiIC0tIDB4JTA4bHhcbiIsIHJldCk7CiAgICBpZiAocmV0ID09IElDRVJSX09LKQogICAgewogICAgICAgTFBWT0lEIG9sZHByZXYsIG9sZG91dDsKLyogV2Ugc2hpZnQgUHJldiBhbmQgT3V0LCBzbyB3ZSBkb24ndCBoYXZlIHRvIGFsbG9jYXRlIGFuZCByZWxlYXNlIG1lbW9yeSAqLwogICAgICAgb2xkcHJldiA9IHBjLT5scEJpdHNQcmV2OwogICAgICAgb2xkb3V0ID0gcGMtPmxwQml0c091dDsKICAgICAgIHBjLT5scEJpdHNQcmV2ID0gb2xkb3V0OwogICAgICAgcGMtPmxwQml0c091dCA9IG9sZHByZXY7CgogICAgICAgVFJBQ0UoInJldHVybmluZzogJXBcbiIsIGljQ29tcC0+bHBPdXRwdXQpOwogICAgICAgcmV0dXJuIGljQ29tcC0+bHBPdXRwdXQ7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgSUNTZXFDb21wcmVzc0ZyYW1lRW5kICAgW01TVkZXMzIuQF0KICovCnZvaWQgVkZXQVBJIElDU2VxQ29tcHJlc3NGcmFtZUVuZChQQ09NUFZBUlMgcGMpCnsKICAgIERXT1JEIHJldDsKICAgIFRSQUNFKCIoJXApXG4iLCBwYyk7CiAgICByZXQgPSBJQ1NlbmRNZXNzYWdlKHBjLT5oaWMsIElDTV9DT01QUkVTU19FTkQsIDAsIDApOwogICAgVFJBQ0UoIiAtLSAlbHgiLCByZXQpOwogICAgaWYgKHBjLT5scGJpSW4pCiAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBiaUluKTsKICAgIGlmIChwYy0+bHBCaXRzUHJldikKICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBjLT5scEJpdHNQcmV2KTsKICAgIGlmIChwYy0+bHBCaXRzT3V0KQogICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGMtPmxwQml0c091dCk7CiAgICBpZiAocGMtPmxwU3RhdGUpCiAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBTdGF0ZSk7CiAgICBwYy0+bHBiaUluID0gcGMtPmxwQml0c1ByZXYgPSBwYy0+bHBCaXRzT3V0ID0gcGMtPmxwU3RhdGUgPSBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBJQ1NlcUNvbXByZXNzRnJhbWVTdGFydCBbTVNWRlczMi5AXQogKi8KQk9PTCBWRldBUEkgSUNTZXFDb21wcmVzc0ZyYW1lU3RhcnQoUENPTVBWQVJTIHBjLCBMUEJJVE1BUElORk8gbHBiaUluKQp7CiAgICAvKiBJJ20gaWdub3JpbmcgYm1pQ29sb3JzIGFzIEkgZG9uJ3Qga25vdyB3aGF0IHRvIGRvIHdpdGggaXQsCiAgICAgKiBpdCBkb2Vzbid0IGFwcGVhciB0byBiZSB1c2VkIHRob3VnaAogICAgICovCiAgICBEV09SRCByZXQ7CiAgICBwYy0+bHBiaUluID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihCSVRNQVBJTkZPKSk7CiAgICBpZiAoIXBjLT5scGJpSW4pCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIG1lbWNweShwYy0+bHBiaUluLCBscGJpSW4sIHNpemVvZihCSVRNQVBJTkZPKSk7CiAgICBwYy0+bHBCaXRzUHJldiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBiaUluLT5ibWlIZWFkZXIuYmlTaXplSW1hZ2UpOwogICAgaWYgKCFwYy0+bHBCaXRzUHJldikKICAgIHsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBiaUluKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBwYy0+bHBTdGF0ZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoSUNDT01QUkVTUykpOwogICAgaWYgKCFwYy0+bHBTdGF0ZSkKICAgIHsKICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBjLT5scGJpSW4pOwogICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGMtPmxwQml0c1ByZXYpOwogICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgcGMtPmNiU3RhdGUgPSBzaXplb2YoSUNDT01QUkVTUyk7CgogICAgcGMtPmxwQml0c091dCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBiaU91dC0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlKTsKICAgIGlmICghcGMtPmxwQml0c091dCkKICAgIHsKICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBjLT5scGJpSW4pOwogICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGMtPmxwQml0c1ByZXYpOwogICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGMtPmxwU3RhdGUpOwogICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgVFJBQ0UoIkNvbXB2YXJzOlxuIgoJICAiXHRwYzpcbiIKCSAgIlx0c2l6ZTogJWxpXG4iCgkgICJcdGZsYWdzOiAlbGlcbiIKCSAgIlx0aGljOiAlcFxuIgoJICAiXHR0eXBlOiAlbHhcbiIKCSAgIlx0aGFuZGxlcjogJWx4XG4iCgkgICJcdGluL291dDogJXAvJXBcbiIKCSAgImtleS9kYXRhL3F1YWxpdHk6ICVsaS8lbGkvJWxpXG4iLAoJICAgICBwYy0+Y2JTaXplLCBwYy0+ZHdGbGFncywgcGMtPmhpYywgcGMtPmZjY1R5cGUsIHBjLT5mY2NIYW5kbGVyLAoJICAgICBwYy0+bHBiaUluLCBwYy0+bHBiaU91dCwgcGMtPmxLZXksIHBjLT5sRGF0YVJhdGUsIHBjLT5sUSk7CgogICAgcmV0ID0gSUNTZW5kTWVzc2FnZShwYy0+aGljLCBJQ01fQ09NUFJFU1NfQkVHSU4sIChEV09SRF9QVFIpcGMtPmxwYmlJbiwgKERXT1JEX1BUUilwYy0+bHBiaU91dCk7CiAgICBUUkFDRSgiIC0tICVseFxuIiwgcmV0KTsKICAgIGlmIChyZXQgPT0gSUNFUlJfT0spCiAgICB7CiAgICAgICBJQ0NPTVBSRVNTKiBpY0NvbXAgPSAoSUNDT01QUkVTUyAqKXBjLT5scFN0YXRlOwogICAgICAgLyogSW5pdGlhbGlzZSBzb21lIHZhcmlhYmxlcyAqLwogICAgICAgcGMtPmxGcmFtZSA9IDA7IHBjLT5sS2V5Q291bnQgPSAwOwoKICAgICAgIGljQ29tcC0+bHBiaU91dHB1dCA9ICZwYy0+bHBiaU91dC0+Ym1pSGVhZGVyOwogICAgICAgaWNDb21wLT5scGJpSW5wdXQgPSAmcGMtPmxwYmlJbi0+Ym1pSGVhZGVyOwogICAgICAgaWNDb21wLT5scGNraWQgPSBOVUxMOwogICAgICAgaWNDb21wLT5kd0ZyYW1lU2l6ZSA9IDA7CiAgICAgICBpY0NvbXAtPmR3UXVhbGl0eSA9IHBjLT5sUTsKICAgICAgIGljQ29tcC0+bHBiaVByZXYgPSAmcGMtPmxwYmlJbi0+Ym1pSGVhZGVyOwogICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYy0+bHBiaUluKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBjLT5scEJpdHNQcmV2KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBjLT5scFN0YXRlKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBjLT5scEJpdHNPdXQpOwogICAgcGMtPmxwQml0c1ByZXYgPSBwYy0+bHBiaUluID0gcGMtPmxwU3RhdGUgPSBwYy0+bHBCaXRzT3V0ID0gTlVMTDsKICAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgR2V0RmlsZU5hbWVQcmV2aWV3ICAgW01TVkZXMzIuQF0KICovCnN0YXRpYyBCT09MIEdldEZpbGVOYW1lUHJldmlldyhMUFZPSUQgbHBvZm4sQk9PTCBiU2F2ZSxCT09MIGJVbmljb2RlKQp7CiAgQ0hBUiAgICBzekZ1bmN0aW9uTmFtZVsyMF07CiAgQk9PTCAgICAoKmZuR2V0RmlsZU5hbWUpKExQVk9JRCk7CiAgSE1PRFVMRSBoQ29tZGxnMzI7CiAgQk9PTCAgICByZXQ7CgogIEZJWE1FKCIoJXAsJWQsJWQpLCBzZW1pLXN0dWIhXG4iLGxwb2ZuLGJTYXZlLGJVbmljb2RlKTsKCiAgbHN0cmNweUEoc3pGdW5jdGlvbk5hbWUsIChiU2F2ZSA/ICJHZXRTYXZlRmlsZU5hbWUiIDogIkdldE9wZW5GaWxlTmFtZSIpKTsKICBsc3RyY2F0QShzekZ1bmN0aW9uTmFtZSwgKGJVbmljb2RlID8gIlciIDogIkEiKSk7CgogIGhDb21kbGczMiA9IExvYWRMaWJyYXJ5QSgiQ09NRExHMzIuRExMIik7CiAgaWYgKGhDb21kbGczMiA9PSBOVUxMKQogICAgcmV0dXJuIEZBTFNFOwoKICBmbkdldEZpbGVOYW1lID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoQ29tZGxnMzIsIHN6RnVuY3Rpb25OYW1lKTsKICBpZiAoZm5HZXRGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEZBTFNFOwoKICAvKiBGSVhNRTogbmVlZCB0byBhZGQgT0ZOX0VOQUJMRUhPT0sgYW5kIG91ciBvd24gaGFuZGxlciAqLwogIHJldCA9IGZuR2V0RmlsZU5hbWUobHBvZm4pOwoKICBGcmVlTGlicmFyeShoQ29tZGxnMzIpOwogIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0T3BlbkZpbGVOYW1lUHJldmlld0EJW01TVkZXMzIuQF0KICovCkJPT0wgV0lOQVBJIEdldE9wZW5GaWxlTmFtZVByZXZpZXdBKExQT1BFTkZJTEVOQU1FQSBscG9mbikKewogIEZJWE1FKCIoJXApLCBzZW1pLXN0dWIhXG4iLCBscG9mbik7CgogIHJldHVybiBHZXRGaWxlTmFtZVByZXZpZXcobHBvZm4sIEZBTFNFLCBGQUxTRSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0T3BlbkZpbGVOYW1lUHJldmlld1cJW01TVkZXMzIuQF0KICovCkJPT0wgV0lOQVBJIEdldE9wZW5GaWxlTmFtZVByZXZpZXdXKExQT1BFTkZJTEVOQU1FVyBscG9mbikKewogIEZJWE1FKCIoJXApLCBzZW1pLXN0dWIhXG4iLCBscG9mbik7CgogIHJldHVybiBHZXRGaWxlTmFtZVByZXZpZXcobHBvZm4sIEZBTFNFLCBUUlVFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRTYXZlRmlsZU5hbWVQcmV2aWV3QQlbTVNWRlczMi5AXQogKi8KQk9PTCBXSU5BUEkgR2V0U2F2ZUZpbGVOYW1lUHJldmlld0EoTFBPUEVORklMRU5BTUVBIGxwb2ZuKQp7CiAgRklYTUUoIiglcCksIHNlbWktc3R1YiFcbiIsIGxwb2ZuKTsKCiAgcmV0dXJuIEdldEZpbGVOYW1lUHJldmlldyhscG9mbiwgVFJVRSwgRkFMU0UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFNhdmVGaWxlTmFtZVByZXZpZXdXCVtNU1ZGVzMyLkBdCiAqLwpCT09MIFdJTkFQSSBHZXRTYXZlRmlsZU5hbWVQcmV2aWV3VyhMUE9QRU5GSUxFTkFNRVcgbHBvZm4pCnsKICBGSVhNRSgiKCVwKSwgc2VtaS1zdHViIVxuIiwgbHBvZm4pOwoKICByZXR1cm4gR2V0RmlsZU5hbWVQcmV2aWV3KGxwb2ZuLCBUUlVFLCBUUlVFKTsKfQo=