LyoKICogTG9jYWxlIHN1cHBvcnQKICoKICogQ29weXJpZ2h0IDE5OTUgTWFydGluIHZvbiBMb2V3aXMKICogQ29weXJpZ2h0IDE5OTggRGF2aWQgTGVlIExhbWJlcnQKICogQ29weXJpZ2h0IDIwMDAgSnVsaW8gQ+lzYXIgR+F6cXVlegogKiBDb3B5cmlnaHQgMjAwMiBBbGV4YW5kcmUgSnVsbGlhcmQgZm9yIENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojaW5jbHVkZSAibnRzdGF0dXMuaCIKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2ludXNlci5oIiAgLyogZm9yIFJUX1NUUklOR1cgKi8KI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAid2ludGVybmwuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAidGhyZWFkLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChubHMpOwoKI2RlZmluZSBMT0NBTEVfTE9DQUxFSU5GT0ZMQUdTTUFTSyAoTE9DQUxFX05PVVNFUk9WRVJSSURFfExPQ0FMRV9VU0VfQ1BfQUNQfExPQ0FMRV9SRVRVUk5fTlVNQkVSKQoKc3RhdGljIGNvbnN0IFdDSEFSIGtlcm5lbDMyV1tdID0geyAnSycsJ0UnLCdSJywnTicsJ0UnLCdMJywnMycsJzInLCdcMCcgfTsKCi8qIGN1cnJlbnQgY29kZSBwYWdlcyAqLwpzdGF0aWMgY29uc3QgdW5pb24gY3B0YWJsZSAqYW5zaV9jcHRhYmxlOwpzdGF0aWMgY29uc3QgdW5pb24gY3B0YWJsZSAqb2VtX2NwdGFibGU7CnN0YXRpYyBjb25zdCB1bmlvbiBjcHRhYmxlICptYWNfY3B0YWJsZTsKc3RhdGljIGNvbnN0IHVuaW9uIGNwdGFibGUgKnVuaXhfY3B0YWJsZTsgIC8qIE5VTEwgaWYgVVRGOCAqLwoKLyogQ2hhcnNldCB0byBjb2RlcGFnZSBtYXAsIHNvcnRlZCBieSBuYW1lLiAqLwpzdGF0aWMgY29uc3Qgc3RydWN0IGNoYXJzZXRfZW50cnkKewogICAgY29uc3QgY2hhciAqY2hhcnNldF9uYW1lOwogICAgVUlOVCAgICAgICAgY29kZXBhZ2U7Cn0gY2hhcnNldF9uYW1lc1tdID0KewogICAgeyAiQ1AxMjUwIiwgMTI1MCB9LAogICAgeyAiQ1AxMjUxIiwgMTI1MSB9LAogICAgeyAiQ1AxMjUyIiwgMTI1MiB9LAogICAgeyAiQ1AxMjUzIiwgMTI1MyB9LAogICAgeyAiQ1AxMjU0IiwgMTI1NCB9LAogICAgeyAiQ1AxMjU1IiwgMTI1NSB9LAogICAgeyAiQ1AxMjU2IiwgMTI1NiB9LAogICAgeyAiQ1AxMjU3IiwgMTI1NyB9LAogICAgeyAiQ1AxMjU4IiwgMTI1OCB9LAogICAgeyAiSUJNMDM3IiwgMzcgfSwKICAgIHsgIklCTTEwMjYiLCAxMDI2IH0sCiAgICB7ICJJQk00MjQiLCA0MjQgfSwKICAgIHsgIklCTTQzNyIsIDQzNyB9LAogICAgeyAiSUJNNTAwIiwgNTAwIH0sCiAgICB7ICJJQk04NTAiLCA4NTAgfSwKICAgIHsgIklCTTg1MiIsIDg1MiB9LAogICAgeyAiSUJNODU1IiwgODU1IH0sCiAgICB7ICJJQk04NTciLCA4NTcgfSwKICAgIHsgIklCTTg2MCIsIDg2MCB9LAogICAgeyAiSUJNODYxIiwgODYxIH0sCiAgICB7ICJJQk04NjIiLCA4NjIgfSwKICAgIHsgIklCTTg2MyIsIDg2MyB9LAogICAgeyAiSUJNODY0IiwgODY0IH0sCiAgICB7ICJJQk04NjUiLCA4NjUgfSwKICAgIHsgIklCTTg2NiIsIDg2NiB9LAogICAgeyAiSUJNODY5IiwgODY5IH0sCiAgICB7ICJJQk04NzQiLCA4NzQgfSwKICAgIHsgIklCTTg3NSIsIDg3NSB9LAogICAgeyAiSVNPODg1OTEiLCAyODU5MSB9LAogICAgeyAiSVNPODg1OTEwIiwgMjg2MDAgfSwKICAgIHsgIklTTzg4NTkxMyIsIDI4NjAzIH0sCiAgICB7ICJJU084ODU5MTQiLCAyODYwNCB9LAogICAgeyAiSVNPODg1OTE1IiwgMjg2MDUgfSwKICAgIHsgIklTTzg4NTkyIiwgMjg1OTIgfSwKICAgIHsgIklTTzg4NTkzIiwgMjg1OTMgfSwKICAgIHsgIklTTzg4NTk0IiwgMjg1OTQgfSwKICAgIHsgIklTTzg4NTk1IiwgMjg1OTUgfSwKICAgIHsgIklTTzg4NTk2IiwgMjg1OTYgfSwKICAgIHsgIklTTzg4NTk3IiwgMjg1OTcgfSwKICAgIHsgIklTTzg4NTk4IiwgMjg1OTggfSwKICAgIHsgIklTTzg4NTk5IiwgMjg1OTkgfSwKICAgIHsgIktPSThSIiwgMjA4NjYgfSwKICAgIHsgIktPSThVIiwgMjA4NjYgfSwKICAgIHsgIlVURjgiLCBDUF9VVEY4IH0KfTsKCiNkZWZpbmUgTkxTX01BWF9MQU5HVUFHRVMgMjAKdHlwZWRlZiBzdHJ1Y3QgewogICAgV0NIQVIgbGFuZ1sxMjhdOwogICAgV0NIQVIgY291bnRyeVs0XTsKICAgIExBTkdJRCBmb3VuZF9sYW5nX2lkW05MU19NQVhfTEFOR1VBR0VTXTsKICAgIFdDSEFSIGZvdW5kX2xhbmd1YWdlW05MU19NQVhfTEFOR1VBR0VTXVszXTsKICAgIFdDSEFSIGZvdW5kX2NvdW50cnlbTkxTX01BWF9MQU5HVUFHRVNdWzNdOwogICAgaW50IG5fZm91bmQ7Cn0gTEFOR19GSU5EX0RBVEE7CgoKLyogY29weSBVbmljb2RlIHN0cmluZyB0byBBc2NpaSB3aXRob3V0IHVzaW5nIGNvZGVwYWdlcyAqLwpzdGF0aWMgaW5saW5lIHZvaWQgc3RyY3B5V3RvQSggY2hhciAqZHN0LCBjb25zdCBXQ0hBUiAqc3JjICkKewogICAgd2hpbGUgKCgqZHN0KysgPSAqc3JjKyspKTsKfQoKLyogQ29weSBBc2NpaSBzdHJpbmcgdG8gVW5pY29kZSB3aXRob3V0IHVzaW5nIGNvZGVwYWdlcyAqLwpzdGF0aWMgaW5saW5lIHZvaWQgc3RyY3B5bkF0b1coIFdDSEFSICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IG4gKQp7CiAgICB3aGlsZSAobiA+IDEgJiYgKnNyYykKICAgIHsKICAgICAgICAqZHN0KysgPSAodW5zaWduZWQgY2hhcikqc3JjKys7CiAgICAgICAgbi0tOwogICAgfQogICAgaWYgKG4pICpkc3QgPSAwOwp9CgovKiByZXR1cm4gYSBwcmludGFibGUgc3RyaW5nIGZvciBhIGxhbmd1YWdlIGlkICovCnN0YXRpYyBjb25zdCBjaGFyICpkZWJ1Z3N0cl9sYW5nKCBMQU5HSUQgbGFuZyApCnsKICAgIFdDSEFSIGxhbmdXWzRdLCBjb3VudHJ5V1s0XTsKICAgIGNoYXIgYnVmZmVyWzhdOwogICAgTENJRCBsY2lkID0gTUFLRUxDSUQoIGxhbmcsIFNPUlRfREVGQVVMVCApOwoKICAgIEdldExvY2FsZUluZm9XKGxjaWQsIExPQ0FMRV9TSVNPNjM5TEFOR05BTUV8TE9DQUxFX05PVVNFUk9WRVJSSURFLCBsYW5nVywgc2l6ZW9mKGxhbmdXKSk7CiAgICBHZXRMb2NhbGVJbmZvVyhsY2lkLCBMT0NBTEVfU0lTTzMxNjZDVFJZTkFNRXxMT0NBTEVfTk9VU0VST1ZFUlJJREUsIGNvdW50cnlXLCBzaXplb2YoY291bnRyeVcpKTsKICAgIHN0cmNweVd0b0EoIGJ1ZmZlciwgbGFuZ1cgKTsKICAgIHN0cmNhdCggYnVmZmVyLCAiXyIgKTsKICAgIHN0cmNweVd0b0EoIGJ1ZmZlciArIHN0cmxlbihidWZmZXIpLCBjb3VudHJ5VyApOwogICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoICIlcyIsIGJ1ZmZlciApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWdldF9sY2lkX2NvZGVwYWdlCiAqCiAqIFJldHJpZXZlIHRoZSBBTlNJIGNvZGVwYWdlIGZvciBhIGdpdmVuIGxvY2FsZS4KICovCmlubGluZSBzdGF0aWMgVUlOVCBnZXRfbGNpZF9jb2RlcGFnZSggTENJRCBsY2lkICkKewogICAgVUlOVCByZXQ7CiAgICBpZiAoIUdldExvY2FsZUluZm9XKCBsY2lkLCBMT0NBTEVfSURFRkFVTFRBTlNJQ09ERVBBR0V8TE9DQUxFX1JFVFVSTl9OVU1CRVIsIChXQ0hBUiAqKSZyZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocmV0KS9zaXplb2YoV0NIQVIpICkpIHJldCA9IDA7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlnZXRfY29kZXBhZ2VfdGFibGUKICoKICogRmluZCB0aGUgdGFibGUgZm9yIGEgZ2l2ZW4gY29kZXBhZ2UsIGhhbmRsaW5nIENQX0FDUCBldGMuIHBzZXVkby1jb2RlcGFnZXMKICovCnN0YXRpYyBjb25zdCB1bmlvbiBjcHRhYmxlICpnZXRfY29kZXBhZ2VfdGFibGUoIHVuc2lnbmVkIGludCBjb2RlcGFnZSApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnJldCA9IE5VTEw7CgogICAgYXNzZXJ0KCBhbnNpX2NwdGFibGUgKTsgIC8qIGluaXQgbXVzdCBoYXZlIGJlZW4gZG9uZSBhbHJlYWR5ICovCgogICAgc3dpdGNoKGNvZGVwYWdlKQogICAgewogICAgY2FzZSBDUF9BQ1A6CiAgICAgICAgcmV0dXJuIGFuc2lfY3B0YWJsZTsKICAgIGNhc2UgQ1BfT0VNQ1A6CiAgICAgICAgcmV0dXJuIG9lbV9jcHRhYmxlOwogICAgY2FzZSBDUF9NQUNDUDoKICAgICAgICByZXR1cm4gbWFjX2NwdGFibGU7CiAgICBjYXNlIENQX1VURjc6CiAgICBjYXNlIENQX1VURjg6CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENQX1RIUkVBRF9BQ1A6CiAgICAgICAgaWYgKCEoY29kZXBhZ2UgPSBOdEN1cnJlbnRUZWIoKS0+Y29kZV9wYWdlKSkgcmV0dXJuIGFuc2lfY3B0YWJsZTsKICAgICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgIGRlZmF1bHQ6CiAgICAgICAgaWYgKGNvZGVwYWdlID09IGFuc2lfY3B0YWJsZS0+aW5mby5jb2RlcGFnZSkgcmV0dXJuIGFuc2lfY3B0YWJsZTsKICAgICAgICBpZiAoY29kZXBhZ2UgPT0gb2VtX2NwdGFibGUtPmluZm8uY29kZXBhZ2UpIHJldHVybiBvZW1fY3B0YWJsZTsKICAgICAgICBpZiAoY29kZXBhZ2UgPT0gbWFjX2NwdGFibGUtPmluZm8uY29kZXBhZ2UpIHJldHVybiBtYWNfY3B0YWJsZTsKICAgICAgICByZXQgPSB3aW5lX2NwX2dldF90YWJsZSggY29kZXBhZ2UgKTsKICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJY3JlYXRlX3JlZ2lzdHJ5X2tleQogKgogKiBDcmVhdGUgdGhlIENvbnRyb2wgUGFuZWxcXEludGVybmF0aW9uYWwgcmVnaXN0cnkga2V5LgogKi8KaW5saW5lIHN0YXRpYyBIS0VZIGNyZWF0ZV9yZWdpc3RyeV9rZXkodm9pZCkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIGludGxXW10gPSB7J0MnLCdvJywnbicsJ3QnLCdyJywnbycsJ2wnLCcgJywnUCcsJ2EnLCduJywnZScsJ2wnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnSScsJ24nLCd0JywnZScsJ3InLCduJywnYScsJ3QnLCdpJywnbycsJ24nLCdhJywnbCcsMH07CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CiAgICBIS0VZIGhrZXk7CgogICAgaWYgKFJ0bE9wZW5DdXJyZW50VXNlciggS0VZX0FMTF9BQ0NFU1MsICZoa2V5ICkgIT0gU1RBVFVTX1NVQ0NFU1MpIHJldHVybiAwOwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gaGtleTsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBpbnRsVyApOwoKICAgIGlmIChOdENyZWF0ZUtleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApICE9IFNUQVRVU19TVUNDRVNTKSBoa2V5ID0gMDsKICAgIE50Q2xvc2UoIGF0dHIuUm9vdERpcmVjdG9yeSApOwogICAgcmV0dXJuIGhrZXk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUxPQ0FMRV9Jbml0UmVnaXN0cnkKICoKICogVXBkYXRlIHJlZ2lzdHJ5IGNvbnRlbnRzIG9uIHN0YXJ0dXAgaWYgdGhlIHVzZXIgbG9jYWxlIGhhcyBjaGFuZ2VkLgogKiBUaGlzIHNpbXVsYXRlcyB0aGUgYWN0aW9uIG9mIHRoZSBXaW5kb3dzIGNvbnRyb2wgcGFuZWwuCiAqLwp2b2lkIExPQ0FMRV9Jbml0UmVnaXN0cnkodm9pZCkKewogICAgc3RhdGljIGNvbnN0IFVTSE9SVCB1cGRhdGVWYWx1ZXNbXSA9IHsKICAgICAgTE9DQUxFX1NMQU5HVUFHRSwKICAgICAgTE9DQUxFX1NDT1VOVFJZLCBMT0NBTEVfSUNPVU5UUlksCiAgICAgIExPQ0FMRV9TMTE1OSwgTE9DQUxFX1MyMzU5LAogICAgICBMT0NBTEVfU1RJTUUsIExPQ0FMRV9JVElNRSwKICAgICAgTE9DQUxFX0lUTFpFUk8sCiAgICAgIExPQ0FMRV9TU0hPUlREQVRFLAogICAgICBMT0NBTEVfSURBVEUsCiAgICAgIExPQ0FMRV9TTE9OR0RBVEUsCiAgICAgIExPQ0FMRV9TREFURSwKICAgICAgTE9DQUxFX1NDVVJSRU5DWSwgTE9DQUxFX0lDVVJSRU5DWSwKICAgICAgTE9DQUxFX0lORUdDVVJSLAogICAgICBMT0NBTEVfSUNVUlJESUdJVFMsCiAgICAgIExPQ0FMRV9TREVDSU1BTCwKICAgICAgTE9DQUxFX1NMSVNULAogICAgICBMT0NBTEVfU1RIT1VTQU5ELAogICAgICBMT0NBTEVfSURJR0lUUywKICAgICAgTE9DQUxFX0lESUdJVFNVQlNUSVRVVElPTiwKICAgICAgTE9DQUxFX1NOQVRJVkVESUdJVFMsCiAgICAgIExPQ0FMRV9JVElNRU1BUktQT1NOLAogICAgICBMT0NBTEVfSUNBTEVOREFSVFlQRSwKICAgICAgTE9DQUxFX0lMWkVSTywKICAgICAgTE9DQUxFX0lNRUFTVVJFCiAgICB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIExvY2FsZVdbXSA9IHsnTCcsJ28nLCdjJywnYScsJ2wnLCdlJywwfTsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgY2hhciBidWZmZXJbMjBdOwogICAgV0NIQVIgYnVmZmVyV1s4MF07CiAgICBEV09SRCBjb3VudCwgaTsKICAgIEhLRVkgaGtleTsKICAgIExDSUQgbGNpZCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwoKICAgIGlmICghKGhrZXkgPSBjcmVhdGVfcmVnaXN0cnlfa2V5KCkpKQogICAgICAgIHJldHVybjsgIC8qIGRvbid0IGRvIGFueXRoaW5nIGlmIHdlIGNhbid0IGNyZWF0ZSB0aGUgcmVnaXN0cnkga2V5ICovCgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgTG9jYWxlVyApOwogICAgY291bnQgPSBzaXplb2YoYnVmZmVyVyk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleShoa2V5LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCAoTFBCWVRFKWJ1ZmZlclcsIGNvdW50LCAmY291bnQpKQogICAgewogICAgICAgIGNvbnN0IEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICppbmZvID0gKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopYnVmZmVyVzsKICAgICAgICBMUENXU1RSIHN6VmFsdWVUZXh0ID0gKExQQ1dTVFIpaW5mby0+RGF0YTsKCiAgICAgICAgaWYgKHN0cnRvdWxXKCBzelZhbHVlVGV4dCwgTlVMTCwgMTYgKSA9PSBsY2lkKSAgLyogYWxyZWFkeSBzZXQgY29ycmVjdGx5ICovCiAgICAgICAgewogICAgICAgICAgICBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoICJ1cGRhdGluZyByZWdpc3RyeSwgbG9jYWxlIGNoYW5nZWQgJXMgLT4gJTA4bHhcbiIsIGRlYnVnc3RyX3coc3pWYWx1ZVRleHQpLCBsY2lkICk7CiAgICB9CiAgICBlbHNlIFRSQUNFKCAidXBkYXRpbmcgcmVnaXN0cnksIGxvY2FsZSBjaGFuZ2VkIG5vbmUgLT4gJTA4bHhcbiIsIGxjaWQgKTsKCiAgICBzcHJpbnRmKCBidWZmZXIsICIlMDhseCIsIGxjaWQgKTsKICAgIC8qIE5vdGU6ICc5JyBjb25zdGFudCBiZWxvdyBpcyBzdHJsZW4oYnVmZmVyKSArIDEgKi8KICAgIFJ0bE11bHRpQnl0ZVRvVW5pY29kZU4oIGJ1ZmZlclcsIHNpemVvZihidWZmZXJXKSwgTlVMTCwgYnVmZmVyLCA5ICk7CiAgICBOdFNldFZhbHVlS2V5KCBoa2V5LCAmbmFtZVcsIDAsIFJFR19TWiwgYnVmZmVyVywgOSAqIHNpemVvZihXQ0hBUikgKTsKICAgIE50Q2xvc2UoIGhrZXkgKTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZW9mKHVwZGF0ZVZhbHVlcykvc2l6ZW9mKHVwZGF0ZVZhbHVlc1swXSk7IGkrKykKICAgIHsKICAgICAgICBHZXRMb2NhbGVJbmZvVyggbGNpZCwgdXBkYXRlVmFsdWVzW2ldIHwgTE9DQUxFX05PVVNFUk9WRVJSSURFLCBidWZmZXJXLAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoYnVmZmVyVykvc2l6ZW9mKFdDSEFSKSApOwogICAgICAgIFNldExvY2FsZUluZm9XKCBsY2lkLCB1cGRhdGVWYWx1ZXNbaV0sIGJ1ZmZlclcgKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgZmluZF9sYW5ndWFnZV9pZF9wcm9jCiAqLwpzdGF0aWMgQk9PTCBDQUxMQkFDSyBmaW5kX2xhbmd1YWdlX2lkX3Byb2MoIEhNT0RVTEUgaE1vZHVsZSwgTFBDV1NUUiB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbmFtZSwgV09SRCBMYW5nSUQsIExQQVJBTSBsUGFyYW0gKQp7CiAgICBMQU5HX0ZJTkRfREFUQSAqbF9kYXRhID0gKExBTkdfRklORF9EQVRBICopbFBhcmFtOwogICAgTENJRCBsY2lkID0gTUFLRUxDSUQoTGFuZ0lELCBTT1JUX0RFRkFVTFQpOwogICAgV0NIQVIgYnVmX2xhbmd1YWdlWzEyOF07CiAgICBXQ0hBUiBidWZfY291bnRyeVsxMjhdOwogICAgV0NIQVIgYnVmX2VuX2xhbmd1YWdlWzEyOF07CgogICAgaWYoUFJJTUFSWUxBTkdJRChMYW5nSUQpID09IExBTkdfTkVVVFJBTCkKICAgICAgICByZXR1cm4gVFJVRTsgLyogY29udGludWUgc2VhcmNoICovCgogICAgYnVmX2xhbmd1YWdlWzBdID0gMDsKICAgIGJ1Zl9jb3VudHJ5WzBdID0gMDsKCiAgICBHZXRMb2NhbGVJbmZvVyhsY2lkLCBMT0NBTEVfU0lTTzYzOUxBTkdOQU1FfExPQ0FMRV9OT1VTRVJPVkVSUklERSwKICAgICAgICAgICAgICAgICAgIGJ1Zl9sYW5ndWFnZSwgc2l6ZW9mKGJ1Zl9sYW5ndWFnZSkpOwogICAgR2V0TG9jYWxlSW5mb1cobGNpZCwgTE9DQUxFX1NJU08zMTY2Q1RSWU5BTUV8TE9DQUxFX05PVVNFUk9WRVJSSURFLAogICAgICAgICAgICAgICAgICAgYnVmX2NvdW50cnksIHNpemVvZihidWZfY291bnRyeSkpOwoKICAgIGlmKGxfZGF0YS0+bGFuZ1swXSAmJiAhc3RyY21waVcobF9kYXRhLT5sYW5nLCBidWZfbGFuZ3VhZ2UpKQogICAgewogICAgICAgIGlmKGxfZGF0YS0+Y291bnRyeVswXSkKICAgICAgICB7CiAgICAgICAgICAgIGlmKCFzdHJjbXBpVyhsX2RhdGEtPmNvdW50cnksIGJ1Zl9jb3VudHJ5KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbF9kYXRhLT5mb3VuZF9sYW5nX2lkWzBdID0gTGFuZ0lEOwogICAgICAgICAgICAgICAgbF9kYXRhLT5uX2ZvdW5kID0gMTsKICAgICAgICAgICAgICAgIFRSQUNFKCJGb3VuZCBpZCAlMDRYIGZvciBsYW5nICVzIGNvdW50cnkgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICBMYW5nSUQsIGRlYnVnc3RyX3cobF9kYXRhLT5sYW5nKSwgZGVidWdzdHJfdyhsX2RhdGEtPmNvdW50cnkpKTsKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsgLyogc3RvcCBlbnVtZXJhdGlvbiAqLwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgZ290byBmb3VuZDsgLyogbF9kYXRhLT5jb3VudHJ5IG5vdCBzcGVjaWZpZWQgKi8KICAgIH0KCiAgICAvKiBKdXN0IGluIGNhc2UsIGNoZWNrIExPQ0FMRV9TRU5HTEFOR1VBR0UgdG9vLAogICAgICogaW4gaG9wZSB0aGF0IHBvc3NpYmxlIGFsaWFzIG5hbWUgbWlnaHQgaGF2ZSB0aGF0IHZhbHVlLgogICAgICovCiAgICBidWZfZW5fbGFuZ3VhZ2VbMF0gPSAwOwogICAgR2V0TG9jYWxlSW5mb1cobGNpZCwgTE9DQUxFX1NFTkdMQU5HVUFHRXxMT0NBTEVfTk9VU0VST1ZFUlJJREUsCiAgICAgICAgICAgICAgICAgICBidWZfZW5fbGFuZ3VhZ2UsIHNpemVvZihidWZfZW5fbGFuZ3VhZ2UpKTsKCiAgICBpZihsX2RhdGEtPmxhbmdbMF0gJiYgIXN0cmNtcGlXKGxfZGF0YS0+bGFuZywgYnVmX2VuX2xhbmd1YWdlKSkgZ290byBmb3VuZDsKICAgIHJldHVybiBUUlVFOyAgLyogbm90IGZvdW5kLCBjb250aW51ZSBzZWFyY2ggKi8KCmZvdW5kOgogICAgbF9kYXRhLT5mb3VuZF9sYW5nX2lkW2xfZGF0YS0+bl9mb3VuZF0gPSBMYW5nSUQ7CiAgICBzdHJuY3B5VyhsX2RhdGEtPmZvdW5kX2NvdW50cnlbbF9kYXRhLT5uX2ZvdW5kXSwgYnVmX2NvdW50cnksIDMpOwogICAgc3RybmNweVcobF9kYXRhLT5mb3VuZF9sYW5ndWFnZVtsX2RhdGEtPm5fZm91bmRdLCBidWZfbGFuZ3VhZ2UsIDMpOwogICAgbF9kYXRhLT5uX2ZvdW5kKys7CiAgICBUUkFDRSgiRm91bmQgaWQgJTA0WCBmb3IgbGFuZyAlc1xuIiwgTGFuZ0lELCBkZWJ1Z3N0cl93KGxfZGF0YS0+bGFuZykpOwogICAgcmV0dXJuIChsX2RhdGEtPm5fZm91bmQgPCBOTFNfTUFYX0xBTkdVQUdFUyk7IC8qIGNvbnRpbnVlIHNlYXJjaCwgdW5sZXNzIHdlIGhhdmUgZW5vdWdoICovCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIGdldF9sYW5ndWFnZV9pZAogKgogKiBJTlBVVDoKICoJTGFuZzogYSBzdHJpbmcgd2hvc2UgdHdvIGZpcnN0IGNoYXJzIGFyZSB0aGUgaXNvIG5hbWUgb2YgYSBsYW5ndWFnZS4KICoJQ291bnRyeTogYSBzdHJpbmcgd2hvc2UgdHdvIGZpcnN0IGNoYXJzIGFyZSB0aGUgaXNvIG5hbWUgb2YgY291bnRyeQogKglDaGFyc2V0OiBhIHN0cmluZyBkZWZpbmluZyB0aGUgY2hvc2VuIGNoYXJzZXQgZW5jb2RpbmcKICoJRGlhbGVjdDogYSBzdHJpbmcgZGVmaW5pbmcgYSB2YXJpYXRpb24gb2YgdGhlIGxvY2FsZQogKgogKglhbGwgdGhvc2UgdmFsdWVzIGFyZSBmcm9tIHRoZSBzdGFuZGFyZGl6ZWQgZm9ybWF0IG9mIGxvY2FsZQogKgluYW1lIGluIHVuaXggd2hpY2ggaXM6IExhbmdbX0NvdW50cnldWy5DaGFyc2V0XVtARGlhbGVjdF0KICoKICogUkVUVVJOUzoKICoJdGhlIG51bWVyaWMgY29kZSBvZiB0aGUgbGFuZ3VhZ2UgdXNlZCBieSBXaW5kb3dzCiAqCiAqIEZJWE1FOiBDaGFyc2V0IGFuZCBEaWFsZWN0IGFyZSBub3QgaGFuZGxlZAogKi8Kc3RhdGljIExBTkdJRCBnZXRfbGFuZ3VhZ2VfaWQoTFBDU1RSIExhbmcsIExQQ1NUUiBDb3VudHJ5LCBMUENTVFIgQ2hhcnNldCwgTFBDU1RSIERpYWxlY3QpCnsKICAgIExBTkdfRklORF9EQVRBIGxfZGF0YTsKICAgIEhNT0RVTEUgaEtlcm5lbDMyOwoKICAgIGlmKCFMYW5nKQogICAgewogICAgICAgIGxfZGF0YS5mb3VuZF9sYW5nX2lkWzBdID0gTUFLRUxBTkdJRChMQU5HX0VOR0xJU0gsIFNVQkxBTkdfREVGQVVMVCk7CiAgICAgICAgZ290byBFTkQ7CiAgICB9CgogICAgbF9kYXRhLm5fZm91bmQgPSAwOwogICAgc3RyY3B5bkF0b1cobF9kYXRhLmxhbmcsIExhbmcsIHNpemVvZihsX2RhdGEubGFuZykpOwoKICAgIGlmIChDb3VudHJ5KSBzdHJjcHluQXRvVyhsX2RhdGEuY291bnRyeSwgQ291bnRyeSwgc2l6ZW9mKGxfZGF0YS5jb3VudHJ5KSk7CiAgICBlbHNlIGxfZGF0YS5jb3VudHJ5WzBdID0gMDsKCiAgICBoS2VybmVsMzIgPSBHZXRNb2R1bGVIYW5kbGVXKGtlcm5lbDMyVyk7CgogICAgRW51bVJlc291cmNlTGFuZ3VhZ2VzVyhoS2VybmVsMzIsIChMUENXU1RSKVJUX1NUUklORywgKExQQ1dTVFIpTE9DQUxFX0lMQU5HVUFHRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluZF9sYW5ndWFnZV9pZF9wcm9jLCAoTFBBUkFNKSZsX2RhdGEpOwoKICAgIGlmIChsX2RhdGEubl9mb3VuZCA9PSAxKSBnb3RvIEVORDsKCiAgICBpZighbF9kYXRhLm5fZm91bmQpCiAgICB7CiAgICAgICAgaWYobF9kYXRhLmNvdW50cnlbMF0pCiAgICAgICAgewogICAgICAgICAgICAvKiByZXRyeSB3aXRob3V0IGNvdW50cnkgbmFtZSAqLwogICAgICAgICAgICBsX2RhdGEuY291bnRyeVswXSA9IDA7CiAgICAgICAgICAgIEVudW1SZXNvdXJjZUxhbmd1YWdlc1coaEtlcm5lbDMyLCAoTFBDV1NUUilSVF9TVFJJTkcsIChMUENXU1RSKUxPQ0FMRV9JTEFOR1VBR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluZF9sYW5ndWFnZV9pZF9wcm9jLCAoTE9ORykmbF9kYXRhKTsKICAgICAgICAgICAgaWYgKCFsX2RhdGEubl9mb3VuZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTUVTU0FHRSgiV2FybmluZzogTGFuZ3VhZ2UgJyVzXyVzJyB3YXMgbm90IHJlY29nbml6ZWQsIGRlZmF1bHRpbmcgdG8gRW5nbGlzaC5cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIExhbmcsIENvdW50cnkpOwogICAgICAgICAgICAgICAgbF9kYXRhLmZvdW5kX2xhbmdfaWRbMF0gPSBNQUtFTEFOR0lEKExBTkdfRU5HTElTSCwgU1VCTEFOR19ERUZBVUxUKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIE1FU1NBR0UoIldhcm5pbmc6IExhbmd1YWdlICclc18lcycgd2FzIG5vdCByZWNvZ25pemVkLCBkZWZhdWx0aW5nIHRvICclcycuXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgTGFuZywgQ291bnRyeSwgZGVidWdzdHJfbGFuZyhsX2RhdGEuZm91bmRfbGFuZ19pZFswXSkgKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgTUVTU0FHRSgiV2FybmluZzogTGFuZ3VhZ2UgJyVzJyB3YXMgbm90IHJlY29nbml6ZWQsIGRlZmF1bHRpbmcgdG8gRW5nbGlzaC5cbiIsIExhbmcpOwogICAgICAgICAgICBsX2RhdGEuZm91bmRfbGFuZ19pZFswXSA9IE1BS0VMQU5HSUQoTEFOR19FTkdMSVNILCBTVUJMQU5HX0RFRkFVTFQpOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpbnQgaTsKCiAgICAgICAgaWYgKENvdW50cnkgJiYgQ291bnRyeVswXSkKICAgICAgICAgICAgTUVTU0FHRSgiRm9yIGxhbmd1YWdlICclc18lcycgc2V2ZXJhbCBsYW5ndWFnZSBpZHMgd2VyZSBmb3VuZDpcbiIsIExhbmcsIENvdW50cnkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgTUVTU0FHRSgiRm9yIGxhbmd1YWdlICclcycgc2V2ZXJhbCBsYW5ndWFnZSBpZHMgd2VyZSBmb3VuZDpcbiIsIExhbmcpOwoKICAgICAgICAvKiBwcmludCBhIGxpc3Qgb2YgbGFuZ3VhZ2VzIHdpdGggdGhlaXIgZGVzY3JpcHRpb24gKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbF9kYXRhLm5fZm91bmQ7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSIGJ1ZmZXWzEyOF07CiAgICAgICAgICAgIGNoYXIgYnVmZkFbMTI4XTsKICAgICAgICAgICAgR2V0TG9jYWxlSW5mb1coIE1BS0VMQ0lEKCBsX2RhdGEuZm91bmRfbGFuZ19pZFtpXSwgU09SVF9ERUZBVUxUICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExPQ0FMRV9TTEFOR1VBR0V8TE9DQUxFX05PVVNFUk9WRVJSSURFLCBidWZmVywgc2l6ZW9mKGJ1ZmZXKSk7CiAgICAgICAgICAgIHN0cmNweVd0b0EoIGJ1ZmZBLCBidWZmVyApOwogICAgICAgICAgICBNRVNTQUdFKCAiICAgJXMgKCUwNFgpIC0gJXNcbiIsIGRlYnVnc3RyX2xhbmcobF9kYXRhLmZvdW5kX2xhbmdfaWRbaV0pLAogICAgICAgICAgICAgICAgICAgICBsX2RhdGEuZm91bmRfbGFuZ19pZFtpXSwgYnVmZkEgKTsKICAgICAgICB9CiAgICAgICAgTUVTU0FHRSgiRGVmYXVsdGluZyB0byAnJXMnLiBZb3Ugc2hvdWxkIHNwZWNpZnkgdGhlIGV4YWN0IGxhbmd1YWdlIHlvdSB3YW50XG4iCiAgICAgICAgICAgICAgICAiYnkgZGVmaW5pbmcgeW91ciBMQU5HIGVudmlyb25tZW50IHZhcmlhYmxlIGxpa2UgdGhpczogTEFORz0lc1xuIiwKICAgICAgICAgICAgICAgIGRlYnVnc3RyX2xhbmcobF9kYXRhLmZvdW5kX2xhbmdfaWRbMF0pLCBkZWJ1Z3N0cl9sYW5nKGxfZGF0YS5mb3VuZF9sYW5nX2lkWzBdKSApOwogICAgfQpFTkQ6CiAgICBUUkFDRSgiUmV0dXJuaW5nICUwNFggKCVzKVxuIiwgbF9kYXRhLmZvdW5kX2xhbmdfaWRbMF0sIGRlYnVnc3RyX2xhbmcobF9kYXRhLmZvdW5kX2xhbmdfaWRbMF0pKTsKICAgIHJldHVybiBsX2RhdGEuZm91bmRfbGFuZ19pZFswXTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgY2hhcnNldF9jbXAgKGludGVybmFsKQogKi8Kc3RhdGljIGludCBjaGFyc2V0X2NtcCggY29uc3Qgdm9pZCAqbmFtZSwgY29uc3Qgdm9pZCAqZW50cnkgKQp7CiAgICBjb25zdCBzdHJ1Y3QgY2hhcnNldF9lbnRyeSAqY2hhcnNldCA9IChzdHJ1Y3QgY2hhcnNldF9lbnRyeSAqKWVudHJ5OwogICAgcmV0dXJuIHN0cmNhc2VjbXAoIChjaGFyICopbmFtZSwgY2hhcnNldC0+Y2hhcnNldF9uYW1lICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJaW5pdF9kZWZhdWx0X2xjaWQKICovCnN0YXRpYyBMQ0lEIGluaXRfZGVmYXVsdF9sY2lkKCBVSU5UICp1bml4X2NwICkKewogICAgY2hhciAqYnVmLCAqbGFuZywqY291bnRyeSwqY2hhcnNldCwqZGlhbGVjdCwqbmV4dDsKICAgIExDSUQgcmV0ID0gMDsKCiAgICBpZiAoKGxhbmcgPSBnZXRlbnYoICJMQ19BTEwiICkpIHx8CiAgICAgICAgKGxhbmcgPSBnZXRlbnYoICJMQ19DVFlQRSIgKSkgfHwKICAgICAgICAobGFuZyA9IGdldGVudiggIkxBTkdVQUdFIiApKSB8fAogICAgICAgIChsYW5nID0gZ2V0ZW52KCAiTENfTUVTU0FHRVMiICkpIHx8CiAgICAgICAgKGxhbmcgPSBnZXRlbnYoICJMQU5HIiApKSkKICAgIHsKICAgICAgICBpZiAoIXN0cmNtcChsYW5nLCJQT1NJWCIpIHx8ICFzdHJjbXAobGFuZywiQyIpKSBnb3RvIGRvbmU7CgogICAgICAgIGJ1ZiA9IFJ0bEFsbG9jYXRlSGVhcCggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RybGVuKGxhbmcpICsgMSApOwogICAgICAgIHN0cmNweSggYnVmLCBsYW5nICk7CiAgICAgICAgbGFuZz1idWY7CgogICAgICAgIGRvIHsKICAgICAgICAgICAgbmV4dD1zdHJjaHIobGFuZywnOicpOyBpZiAobmV4dCkgKm5leHQrKz0nXDAnOwogICAgICAgICAgICBkaWFsZWN0PXN0cmNocihsYW5nLCdAJyk7IGlmIChkaWFsZWN0KSAqZGlhbGVjdCsrPSdcMCc7CiAgICAgICAgICAgIGNoYXJzZXQ9c3RyY2hyKGxhbmcsJy4nKTsgaWYgKGNoYXJzZXQpICpjaGFyc2V0Kys9J1wwJzsKICAgICAgICAgICAgY291bnRyeT1zdHJjaHIobGFuZywnXycpOyBpZiAoY291bnRyeSkgKmNvdW50cnkrKz0nXDAnOwoKICAgICAgICAgICAgcmV0ID0gZ2V0X2xhbmd1YWdlX2lkKGxhbmcsIGNvdW50cnksIGNoYXJzZXQsIGRpYWxlY3QpOwogICAgICAgICAgICBpZiAocmV0ICYmIGNoYXJzZXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBjaGFyc2V0X2VudHJ5ICplbnRyeTsKICAgICAgICAgICAgICAgIGNoYXIgY2hhcnNldF9uYW1lWzE2XTsKICAgICAgICAgICAgICAgIHNpemVfdCBpLCBqOwoKICAgICAgICAgICAgICAgIC8qIHJlbW92ZSBwdW5jdHVhdGlvbiBjaGFyYWN0ZXJzIGZyb20gY2hhcnNldCBuYW1lICovCiAgICAgICAgICAgICAgICBmb3IgKGkgPSBqID0gMDsgY2hhcnNldFtpXSAmJiBqIDwgc2l6ZW9mKGNoYXJzZXRfbmFtZSktMTsgaSsrKQogICAgICAgICAgICAgICAgICAgIGlmIChpc2FsbnVtKGNoYXJzZXRbaV0pKSBjaGFyc2V0X25hbWVbaisrXSA9IGNoYXJzZXRbaV07CiAgICAgICAgICAgICAgICBjaGFyc2V0X25hbWVbal0gPSAwOwoKICAgICAgICAgICAgICAgIGVudHJ5ID0gYnNlYXJjaCggY2hhcnNldF9uYW1lLCBjaGFyc2V0X25hbWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoY2hhcnNldF9uYW1lcykvc2l6ZW9mKGNoYXJzZXRfbmFtZXNbMF0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoY2hhcnNldF9uYW1lc1swXSksIGNoYXJzZXRfY21wICk7CiAgICAgICAgICAgICAgICBpZiAoZW50cnkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgKnVuaXhfY3AgPSBlbnRyeS0+Y29kZXBhZ2U7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoImNoYXJzZXQgJXMgd2FzIG1hcHBlZCB0byBjcCAldVxuIiwgY2hhcnNldCwgKnVuaXhfY3ApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJjaGFyc2V0ICVzIHdhcyBub3QgcmVjb2duaXplZFxuIiwgY2hhcnNldCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxhbmc9bmV4dDsKICAgICAgICB9IHdoaWxlIChsYW5nICYmICFyZXQpOwoKICAgICAgICBpZiAoIXJldCkgTUVTU0FHRSgiV2FybmluZzogbGFuZ3VhZ2UgJyVzJyBub3QgcmVjb2duaXplZCwgZGVmYXVsdGluZyB0byBFbmdsaXNoXG4iLCBidWYpOwogICAgICAgIFJ0bEZyZWVIZWFwKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBidWYgKTsKICAgIH0KCiBkb25lOgogICAgaWYgKCFyZXQpIHJldCA9IE1BS0VMQ0lEKCBNQUtFTEFOR0lEKExBTkdfRU5HTElTSCxTVUJMQU5HX0RFRkFVTFQpLCBTT1JUX0RFRkFVTFQpIDsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFVzZXJEZWZhdWx0TGFuZ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBjdXJyZW50IHVzZXIuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IGxhbmd1YWdlIGZvciB0aGUgY3VycmVudCB1c2VyLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRVc2VyRGVmYXVsdExhbmdJRCh2b2lkKQp7CiAgICByZXR1cm4gTEFOR0lERlJPTUxDSUQoR2V0VXNlckRlZmF1bHRMQ0lEKCkpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRTeXN0ZW1EZWZhdWx0TGFuZ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IGxhbmd1YWdlIGZvciB0aGUgc3lzdGVtLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRTeXN0ZW1EZWZhdWx0TGFuZ0lEKHZvaWQpCnsKICAgIHJldHVybiBHZXRVc2VyRGVmYXVsdExhbmdJRCgpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRVc2VyRGVmYXVsdExDSUQgKEtFUk5FTDMyLkApCiAqCiAqIEdldCB0aGUgZGVmYXVsdCBsb2NhbGUgSWQgZm9yIHRoZSBjdXJyZW50IHVzZXIuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTENJRCBvZiB0aGUgZGVmYXVsdCBsb2NhbGUgZm9yIHRoZSBjdXJyZW50IHVzZXIuCiAqLwpMQ0lEIFdJTkFQSSBHZXRVc2VyRGVmYXVsdExDSUQodm9pZCkKewogICAgTENJRCBsY2lkOwogICAgTnRRdWVyeURlZmF1bHRMb2NhbGUoIFRSVUUsICZsY2lkICk7CiAgICByZXR1cm4gbGNpZDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0U3lzdGVtRGVmYXVsdExDSUQgKEtFUk5FTDMyLkApCiAqCiAqIEdldCB0aGUgZGVmYXVsdCBsb2NhbGUgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTENJRCBvZiB0aGUgZGVmYXVsdCBsb2NhbGUgZm9yIHRoZSBzeXN0ZW0uCiAqLwpMQ0lEIFdJTkFQSSBHZXRTeXN0ZW1EZWZhdWx0TENJRCh2b2lkKQp7CiAgICBMQ0lEIGxjaWQ7CiAgICBOdFF1ZXJ5RGVmYXVsdExvY2FsZSggRkFMU0UsICZsY2lkICk7CiAgICByZXR1cm4gbGNpZDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0VXNlckRlZmF1bHRVSUxhbmd1YWdlIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgdXNlciBpbnRlcmZhY2UgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBjdXJyZW50IHVzZXIuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IFVJIGxhbmd1YWdlIGZvciB0aGUgY3VycmVudCB1c2VyLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRVc2VyRGVmYXVsdFVJTGFuZ3VhZ2Uodm9pZCkKewogICAgcmV0dXJuIEdldFVzZXJEZWZhdWx0TGFuZ0lEKCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFN5c3RlbURlZmF1bHRVSUxhbmd1YWdlIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgdXNlciBpbnRlcmZhY2UgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IFVJIGxhbmd1YWdlIGZvciB0aGUgc3lzdGVtLiBUaGlzIGlzCiAqICB0eXBpY2FsbHkgdGhlIHNhbWUgbGFuZ3VhZ2UgdXNlZCBkdXJpbmcgdGhlIGluc3RhbGxhdGlvbiBwcm9jZXNzLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRTeXN0ZW1EZWZhdWx0VUlMYW5ndWFnZSh2b2lkKQp7CiAgICByZXR1cm4gR2V0U3lzdGVtRGVmYXVsdExhbmdJRCgpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJZ2V0X2xvY2FsZV92YWx1ZV9uYW1lCiAqCiAqIEdldHMgdGhlIHJlZ2lzdHJ5IHZhbHVlIG5hbWUgZm9yIGEgZ2l2ZW4gbGN0eXBlLgogKi8Kc3RhdGljIGNvbnN0IFdDSEFSICpnZXRfbG9jYWxlX3ZhbHVlX25hbWUoIERXT1JEIGxjdHlwZSApCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpQ2FsZW5kYXJUeXBlV1tdID0geydpJywnQycsJ2EnLCdsJywnZScsJ24nLCdkJywnYScsJ3InLCdUJywneScsJ3AnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpQ291bnRyeVdbXSA9IHsnaScsJ0MnLCdvJywndScsJ24nLCd0JywncicsJ3knLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlDdXJyRGlnaXRzV1tdID0geydpJywnQycsJ3UnLCdyJywncicsJ0QnLCdpJywnZycsJ2knLCd0JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUN1cnJlbmN5V1tdID0geydpJywnQycsJ3UnLCdyJywncicsJ2UnLCduJywnYycsJ3knLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlEYXRlV1tdID0geydpJywnRCcsJ2EnLCd0JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaURpZ2l0c1dbXSA9IHsnaScsJ0QnLCdpJywnZycsJ2knLCd0JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUZpcnN0RGF5T2ZXZWVrV1tdID0geydpJywnRicsJ2knLCdyJywncycsJ3QnLCdEJywnYScsJ3knLCdPJywnZicsJ1cnLCdlJywnZScsJ2snLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlGaXJzdFdlZWtPZlllYXJXW10gPSB7J2knLCdGJywnaScsJ3InLCdzJywndCcsJ1cnLCdlJywnZScsJ2snLCdPJywnZicsJ1knLCdlJywnYScsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlMRGF0ZVdbXSA9IHsnaScsJ0wnLCdEJywnYScsJ3QnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpTFplcm9XW10gPSB7J2knLCdMJywnWicsJ2UnLCdyJywnbycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaU1lYXN1cmVXW10gPSB7J2knLCdNJywnZScsJ2EnLCdzJywndScsJ3InLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpTmVnQ3VycldbXSA9IHsnaScsJ04nLCdlJywnZycsJ0MnLCd1JywncicsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlOZWdOdW1iZXJXW10gPSB7J2knLCdOJywnZScsJ2cnLCdOJywndScsJ20nLCdiJywnZScsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlQYXBlclNpemVXW10gPSB7J2knLCdQJywnYScsJ3AnLCdlJywncicsJ1MnLCdpJywneicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlUTFplcm9XW10gPSB7J2knLCdUJywnTCcsJ1onLCdlJywncicsJ28nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlUaW1lUHJlZml4V1tdID0geydpJywnVCcsJ2knLCdtJywnZScsJ1AnLCdyJywnZScsJ2YnLCdpJywneCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaVRpbWVXW10gPSB7J2knLCdUJywnaScsJ20nLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzMTE1OVdbXSA9IHsncycsJzEnLCcxJywnNScsJzknLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHMyMzU5V1tdID0geydzJywnMicsJzMnLCc1JywnOScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0NvdW50cnlXW10gPSB7J3MnLCdDJywnbycsJ3UnLCduJywndCcsJ3InLCd5JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzQ3VycmVuY3lXW10gPSB7J3MnLCdDJywndScsJ3InLCdyJywnZScsJ24nLCdjJywneScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0RhdGVXW10gPSB7J3MnLCdEJywnYScsJ3QnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzRGVjaW1hbFdbXSA9IHsncycsJ0QnLCdlJywnYycsJ2knLCdtJywnYScsJ2wnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNHcm91cGluZ1dbXSA9IHsncycsJ0cnLCdyJywnbycsJ3UnLCdwJywnaScsJ24nLCdnJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTGFuZ3VhZ2VXW10gPSB7J3MnLCdMJywnYScsJ24nLCdnJywndScsJ2EnLCdnJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0xpc3RXW10gPSB7J3MnLCdMJywnaScsJ3MnLCd0JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTG9uZ0RhdGVXW10gPSB7J3MnLCdMJywnbycsJ24nLCdnJywnRCcsJ2EnLCd0JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc01vbkRlY2ltYWxTZXBXW10gPSB7J3MnLCdNJywnbycsJ24nLCdEJywnZScsJ2MnLCdpJywnbScsJ2EnLCdsJywnUycsJ2UnLCdwJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTW9uR3JvdXBpbmdXW10gPSB7J3MnLCdNJywnbycsJ24nLCdHJywncicsJ28nLCd1JywncCcsJ2knLCduJywnZycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc01vblRob3VzYW5kU2VwV1tdID0geydzJywnTScsJ28nLCduJywnVCcsJ2gnLCdvJywndScsJ3MnLCdhJywnbicsJ2QnLCdTJywnZScsJ3AnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNOYXRpdmVEaWdpdHNXW10gPSB7J3MnLCdOJywnYScsJ3QnLCdpJywndicsJ2UnLCdEJywnaScsJ2cnLCdpJywndCcsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNOZWdhdGl2ZVNpZ25XW10gPSB7J3MnLCdOJywnZScsJ2cnLCdhJywndCcsJ2knLCd2JywnZScsJ1MnLCdpJywnZycsJ24nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNQb3NpdGl2ZVNpZ25XW10gPSB7J3MnLCdQJywnbycsJ3MnLCdpJywndCcsJ2knLCd2JywnZScsJ1MnLCdpJywnZycsJ24nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNTaG9ydERhdGVXW10gPSB7J3MnLCdTJywnaCcsJ28nLCdyJywndCcsJ0QnLCdhJywndCcsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNUaG91c2FuZFdbXSA9IHsncycsJ1QnLCdoJywnbycsJ3UnLCdzJywnYScsJ24nLCdkJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzVGltZUZvcm1hdFdbXSA9IHsncycsJ1QnLCdpJywnbScsJ2UnLCdGJywnbycsJ3InLCdtJywnYScsJ3QnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNUaW1lV1tdID0geydzJywnVCcsJ2knLCdtJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc1llYXJNb250aFdbXSA9IHsncycsJ1knLCdlJywnYScsJ3InLCdNJywnbycsJ24nLCd0JywnaCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgTnVtU2hhcGVXW10gPSB7J04nLCd1JywnbScsJ3MnLCdoJywnYScsJ3AnLCdlJywwfTsKCiAgICBzd2l0Y2ggKGxjdHlwZSkKICAgIHsKICAgIC8qIFRoZXNlIHZhbHVlcyBhcmUgdXNlZCBieSBTZXRMb2NhbGVJbmZvIGFuZCBHZXRMb2NhbGVJbmZvLCBhbmQKICAgICAqIHRoZSB2YWx1ZXMgYXJlIHN0b3JlZCBpbiB0aGUgcmVnaXN0cnksIGNvbmZpcm1lZCB1bmRlciBXaW5kb3dzLgogICAgICovCiAgICBjYXNlIExPQ0FMRV9JQ0FMRU5EQVJUWVBFOiAgICByZXR1cm4gaUNhbGVuZGFyVHlwZVc7CiAgICBjYXNlIExPQ0FMRV9JQ1VSUkRJR0lUUzogICAgICByZXR1cm4gaUN1cnJEaWdpdHNXOwogICAgY2FzZSBMT0NBTEVfSUNVUlJFTkNZOiAgICAgICAgcmV0dXJuIGlDdXJyZW5jeVc7CiAgICBjYXNlIExPQ0FMRV9JRElHSVRTOiAgICAgICAgICByZXR1cm4gaURpZ2l0c1c7CiAgICBjYXNlIExPQ0FMRV9JRklSU1REQVlPRldFRUs6ICByZXR1cm4gaUZpcnN0RGF5T2ZXZWVrVzsKICAgIGNhc2UgTE9DQUxFX0lGSVJTVFdFRUtPRllFQVI6IHJldHVybiBpRmlyc3RXZWVrT2ZZZWFyVzsKICAgIGNhc2UgTE9DQUxFX0lMWkVSTzogICAgICAgICAgIHJldHVybiBpTFplcm9XOwogICAgY2FzZSBMT0NBTEVfSU1FQVNVUkU6ICAgICAgICAgcmV0dXJuIGlNZWFzdXJlVzsKICAgIGNhc2UgTE9DQUxFX0lORUdDVVJSOiAgICAgICAgIHJldHVybiBpTmVnQ3Vyclc7CiAgICBjYXNlIExPQ0FMRV9JTkVHTlVNQkVSOiAgICAgICByZXR1cm4gaU5lZ051bWJlclc7CiAgICBjYXNlIExPQ0FMRV9JUEFQRVJTSVpFOiAgICAgICByZXR1cm4gaVBhcGVyU2l6ZVc7CiAgICBjYXNlIExPQ0FMRV9JVElNRTogICAgICAgICAgICByZXR1cm4gaVRpbWVXOwogICAgY2FzZSBMT0NBTEVfUzExNTk6ICAgICAgICAgICAgcmV0dXJuIHMxMTU5VzsKICAgIGNhc2UgTE9DQUxFX1MyMzU5OiAgICAgICAgICAgIHJldHVybiBzMjM1OVc7CiAgICBjYXNlIExPQ0FMRV9TQ1VSUkVOQ1k6ICAgICAgICByZXR1cm4gc0N1cnJlbmN5VzsKICAgIGNhc2UgTE9DQUxFX1NEQVRFOiAgICAgICAgICAgIHJldHVybiBzRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9TREVDSU1BTDogICAgICAgICByZXR1cm4gc0RlY2ltYWxXOwogICAgY2FzZSBMT0NBTEVfU0dST1VQSU5HOiAgICAgICAgcmV0dXJuIHNHcm91cGluZ1c7CiAgICBjYXNlIExPQ0FMRV9TTElTVDogICAgICAgICAgICByZXR1cm4gc0xpc3RXOwogICAgY2FzZSBMT0NBTEVfU0xPTkdEQVRFOiAgICAgICAgcmV0dXJuIHNMb25nRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9TTU9OREVDSU1BTFNFUDogICByZXR1cm4gc01vbkRlY2ltYWxTZXBXOwogICAgY2FzZSBMT0NBTEVfU01PTkdST1VQSU5HOiAgICAgcmV0dXJuIHNNb25Hcm91cGluZ1c7CiAgICBjYXNlIExPQ0FMRV9TTU9OVEhPVVNBTkRTRVA6ICByZXR1cm4gc01vblRob3VzYW5kU2VwVzsKICAgIGNhc2UgTE9DQUxFX1NORUdBVElWRVNJR046ICAgIHJldHVybiBzTmVnYXRpdmVTaWduVzsKICAgIGNhc2UgTE9DQUxFX1NQT1NJVElWRVNJR046ICAgIHJldHVybiBzUG9zaXRpdmVTaWduVzsKICAgIGNhc2UgTE9DQUxFX1NTSE9SVERBVEU6ICAgICAgIHJldHVybiBzU2hvcnREYXRlVzsKICAgIGNhc2UgTE9DQUxFX1NUSE9VU0FORDogICAgICAgIHJldHVybiBzVGhvdXNhbmRXOwogICAgY2FzZSBMT0NBTEVfU1RJTUU6ICAgICAgICAgICAgcmV0dXJuIHNUaW1lVzsKICAgIGNhc2UgTE9DQUxFX1NUSU1FRk9STUFUOiAgICAgIHJldHVybiBzVGltZUZvcm1hdFc7CiAgICBjYXNlIExPQ0FMRV9TWUVBUk1PTlRIOiAgICAgICByZXR1cm4gc1llYXJNb250aFc7CgogICAgLyogVGhlIGZvbGxvd2luZyBhcmUgbm90IGxpc3RlZCB1bmRlciBNU0ROIGFzIHN1cHBvcnRlZCwKICAgICAqIGJ1dCBzZWVtIHRvIGJlIHVzZWQgYW5kIGFsc28gc3RvcmVkIGluIHRoZSByZWdpc3RyeS4KICAgICAqLwogICAgY2FzZSBMT0NBTEVfSUNPVU5UUlk6ICAgICAgICAgcmV0dXJuIGlDb3VudHJ5VzsKICAgIGNhc2UgTE9DQUxFX0lEQVRFOiAgICAgICAgICAgIHJldHVybiBpRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9JTERBVEU6ICAgICAgICAgICByZXR1cm4gaUxEYXRlVzsKICAgIGNhc2UgTE9DQUxFX0lUTFpFUk86ICAgICAgICAgIHJldHVybiBpVExaZXJvVzsKICAgIGNhc2UgTE9DQUxFX1NDT1VOVFJZOiAgICAgICAgIHJldHVybiBzQ291bnRyeVc7CiAgICBjYXNlIExPQ0FMRV9TTEFOR1VBR0U6ICAgICAgICByZXR1cm4gc0xhbmd1YWdlVzsKCiAgICAvKiBUaGUgZm9sbG93aW5nIGFyZSB1c2VkIGluIFhQIGFuZCBsYXRlciAqLwogICAgY2FzZSBMT0NBTEVfSURJR0lUU1VCU1RJVFVUSU9OOiByZXR1cm4gTnVtU2hhcGVXOwogICAgY2FzZSBMT0NBTEVfU05BVElWRURJR0lUUzogICAgICByZXR1cm4gc05hdGl2ZURpZ2l0c1c7CiAgICBjYXNlIExPQ0FMRV9JVElNRU1BUktQT1NOOiAgICAgIHJldHVybiBpVGltZVByZWZpeFc7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWdldF9yZWdpc3RyeV9sb2NhbGVfaW5mbwogKgogKiBSZXRyaWV2ZSB1c2VyLW1vZGlmaWVkIGxvY2FsZSBpbmZvIGZyb20gdGhlIHJlZ2lzdHJ5LgogKiBSZXR1cm4gbGVuZ3RoLCAwIG9uIGVycm9yLCAtMSBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgSU5UIGdldF9yZWdpc3RyeV9sb2NhbGVfaW5mbyggTFBDV1NUUiB2YWx1ZSwgTFBXU1RSIGJ1ZmZlciwgSU5UIGxlbiApCnsKICAgIERXT1JEIHNpemU7CiAgICBJTlQgcmV0OwogICAgSEtFWSBoa2V5OwogICAgTlRTVEFUVVMgc3RhdHVzOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CiAgICBLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqaW5mbzsKICAgIHN0YXRpYyBjb25zdCBpbnQgaW5mb19zaXplID0gRklFTERfT0ZGU0VUKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OLCBEYXRhKTsKCiAgICBpZiAoIShoa2V5ID0gY3JlYXRlX3JlZ2lzdHJ5X2tleSgpKSkgcmV0dXJuIC0xOwoKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIHZhbHVlICk7CiAgICBzaXplID0gaW5mb19zaXplICsgbGVuICogc2l6ZW9mKFdDSEFSKTsKCiAgICBpZiAoIShpbmZvID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplICkpKQogICAgewogICAgICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgc3RhdHVzID0gTnRRdWVyeVZhbHVlS2V5KCBoa2V5LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCBpbmZvLCBzaXplLCAmc2l6ZSApOwogICAgaWYgKHN0YXR1cyA9PSBTVEFUVVNfQlVGRkVSX09WRVJGTE9XICYmICFidWZmZXIpIHN0YXR1cyA9IDA7CgogICAgaWYgKCFzdGF0dXMpCiAgICB7CiAgICAgICAgcmV0ID0gKHNpemUgLSBpbmZvX3NpemUpIC8gc2l6ZW9mKFdDSEFSKTsKICAgICAgICAvKiBhcHBlbmQgdGVybWluYXRpbmcgbnVsbCBpZiBuZWVkZWQgKi8KICAgICAgICBpZiAoIXJldCB8fCAoKFdDSEFSICopaW5mby0+RGF0YSlbcmV0LTFdKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHJldCA8IGxlbiB8fCAhYnVmZmVyKSByZXQrKzsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIgKTsKICAgICAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHJldCAmJiBidWZmZXIpCiAgICAgICAgewogICAgICAgICAgICBtZW1jcHkoIGJ1ZmZlciwgaW5mby0+RGF0YSwgKHJldC0xKSAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICAgICAgYnVmZmVyW3JldC0xXSA9IDA7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChzdGF0dXMgPT0gU1RBVFVTX09CSkVDVF9OQU1FX05PVF9GT1VORCkgcmV0ID0gLTE7CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBSdGxOdFN0YXR1c1RvRG9zRXJyb3Ioc3RhdHVzKSApOwogICAgICAgICAgICByZXQgPSAwOwogICAgICAgIH0KICAgIH0KICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0TG9jYWxlSW5mb0EgKEtFUk5FTDMyLkApCiAqCiAqIEdldCBpbmZvcm1hdGlvbiBhYm91dCBhbiBhc3BlY3Qgb2YgYSBsb2NhbGUuCiAqCiAqIFBBUkFNUwogKiAgbGNpZCAgIFtJXSBMQ0lEIG9mIHRoZSBsb2NhbGUKICogIGxjdHlwZSBbSV0gTENUWVBFXyBmbGFncyBmcm9tICJ3aW5ubHMuaCIKICogIGJ1ZmZlciBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBpbmZvcm1hdGlvbgogKiAgbGVuICAgIFtJXSBMZW5ndGggb2YgYnVmZmVyIGluIGNoYXJhY3RlcnMKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIHNpemUgb2YgdGhlIGRhdGEgcmVxdWVzdGVkLiBJZiBidWZmZXIgaXMgbm9uLU5VTEwsIGl0IGlzIGZpbGxlZAogKiAgICAgICAgICAgd2l0aCB0aGUgaW5mb3JtYXRpb24uCiAqICBGYWlsdXJlOiAwLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICoKICogTk9URVMKICogIC0gTE9DQUxFX05FVVRSQUwgaXMgZXF1YWwgdG8gTE9DQUxFX1NZU1RFTV9ERUZBVUxUCiAqICAtIFRoZSBzdHJpbmcgcmV0dXJuZWQgaXMgTlVMIHRlcm1pbmF0ZWQsIGV4Y2VwdCBmb3IgTE9DQUxFX0ZPTlRTSUdOQVRVUkUsCiAqICAgIHdoaWNoIGlzIGEgYml0IHN0cmluZy4KICovCklOVCBXSU5BUEkgR2V0TG9jYWxlSW5mb0EoIExDSUQgbGNpZCwgTENUWVBFIGxjdHlwZSwgTFBTVFIgYnVmZmVyLCBJTlQgbGVuICkKewogICAgV0NIQVIgKmJ1ZmZlclc7CiAgICBJTlQgbGVuVywgcmV0OwoKICAgIGlmIChsZW4gPCAwIHx8IChsZW4gJiYgIWJ1ZmZlcikpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCFsZW4pIGJ1ZmZlciA9IE5VTEw7CgogICAgaWYgKCEobGVuVyA9IEdldExvY2FsZUluZm9XKCBsY2lkLCBsY3R5cGUsIE5VTEwsIDAgKSkpIHJldHVybiAwOwoKICAgIGlmICghKGJ1ZmZlclcgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxlblcgKiBzaXplb2YoV0NIQVIpICkpKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGlmICgocmV0ID0gR2V0TG9jYWxlSW5mb1coIGxjaWQsIGxjdHlwZSwgYnVmZmVyVywgbGVuVyApKSkKICAgIHsKICAgICAgICBpZiAoKGxjdHlwZSAmIExPQ0FMRV9SRVRVUk5fTlVNQkVSKSB8fAogICAgICAgICAgICAoKGxjdHlwZSAmIH5MT0NBTEVfTE9DQUxFSU5GT0ZMQUdTTUFTSykgPT0gTE9DQUxFX0ZPTlRTSUdOQVRVUkUpKQogICAgICAgIHsKICAgICAgICAgICAgLyogaXQncyBub3QgYW4gQVNDSUkgc3RyaW5nLCBqdXN0IGJ5dGVzICovCiAgICAgICAgICAgIHJldCAqPSBzaXplb2YoV0NIQVIpOwogICAgICAgICAgICBpZiAoYnVmZmVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocmV0IDw9IGxlbikgbWVtY3B5KCBidWZmZXIsIGJ1ZmZlclcsIHJldCApOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiApOwogICAgICAgICAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgVUlOVCBjb2RlcGFnZSA9IENQX0FDUDsKICAgICAgICAgICAgaWYgKCEobGN0eXBlICYgTE9DQUxFX1VTRV9DUF9BQ1ApKSBjb2RlcGFnZSA9IGdldF9sY2lkX2NvZGVwYWdlKCBsY2lkICk7CiAgICAgICAgICAgIHJldCA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUoIGNvZGVwYWdlLCAwLCBidWZmZXJXLCByZXQsIGJ1ZmZlciwgbGVuLCBOVUxMLCBOVUxMICk7CiAgICAgICAgfQogICAgfQogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGJ1ZmZlclcgKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRMb2NhbGVJbmZvVyAoS0VSTkVMMzIuQCkKICoKICogU2VlIEdldExvY2FsZUluZm9BLgogKi8KSU5UIFdJTkFQSSBHZXRMb2NhbGVJbmZvVyggTENJRCBsY2lkLCBMQ1RZUEUgbGN0eXBlLCBMUFdTVFIgYnVmZmVyLCBJTlQgbGVuICkKewogICAgTEFOR0lEIGxhbmdfaWQ7CiAgICBIUlNSQyBocnNyYzsKICAgIEhHTE9CQUwgaG1lbTsKICAgIEhNT0RVTEUgaE1vZHVsZTsKICAgIElOVCByZXQ7CiAgICBVSU5UIGxjZmxhZ3M7CiAgICBjb25zdCBXQ0hBUiAqcDsKICAgIHVuc2lnbmVkIGludCBpOwoKICAgIGlmIChsZW4gPCAwIHx8IChsZW4gJiYgIWJ1ZmZlcikpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCFsZW4pIGJ1ZmZlciA9IE5VTEw7CgogICAgbGNpZCA9IENvbnZlcnREZWZhdWx0TG9jYWxlKGxjaWQpOwoKICAgIGxjZmxhZ3MgPSBsY3R5cGUgJiBMT0NBTEVfTE9DQUxFSU5GT0ZMQUdTTUFTSzsKICAgIGxjdHlwZSAmPSAweGZmZmY7CgogICAgLyogZmlyc3QgY2hlY2sgZm9yIG92ZXJyaWRlcyBpbiB0aGUgcmVnaXN0cnkgKi8KCiAgICBpZiAoIShsY2ZsYWdzICYgTE9DQUxFX05PVVNFUk9WRVJSSURFKSAmJiBsY2lkID09IEdldFVzZXJEZWZhdWx0TENJRCgpKQogICAgewogICAgICAgIGNvbnN0IFdDSEFSICp2YWx1ZSA9IGdldF9sb2NhbGVfdmFsdWVfbmFtZShsY3R5cGUpOwoKICAgICAgICBpZiAodmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAobGNmbGFncyAmIExPQ0FMRV9SRVRVUk5fTlVNQkVSKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ0hBUiB0bXBbMTZdOwogICAgICAgICAgICAgICAgcmV0ID0gZ2V0X3JlZ2lzdHJ5X2xvY2FsZV9pbmZvKCB2YWx1ZSwgdG1wLCBzaXplb2YodG1wKS9zaXplb2YoV0NIQVIpICk7CiAgICAgICAgICAgICAgICBpZiAocmV0ID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQ0hBUiAqZW5kOwogICAgICAgICAgICAgICAgICAgIFVJTlQgbnVtYmVyID0gc3RydG9sVyggdG1wLCAmZW5kLCAxMCApOwogICAgICAgICAgICAgICAgICAgIGlmICgqZW5kKSAgLyogaW52YWxpZCBudW1iZXIgKi8KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9GTEFHUyApOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gc2l6ZW9mKFVJTlQpL3NpemVvZihXQ0hBUik7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFidWZmZXIpIHJldHVybiByZXQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJldCA+IGxlbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiApOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KCBidWZmZXIsICZudW1iZXIsIHNpemVvZihudW1iZXIpICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSByZXQgPSBnZXRfcmVnaXN0cnlfbG9jYWxlX2luZm8oIHZhbHVlLCBidWZmZXIsIGxlbiApOwoKICAgICAgICAgICAgaWYgKHJldCAhPSAtMSkgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICB9CgogICAgLyogbm93IGxvYWQgaXQgZnJvbSBrZXJuZWwgcmVzb3VyY2VzICovCgogICAgbGFuZ19pZCA9IExBTkdJREZST01MQ0lEKCBsY2lkICk7CgogICAgLyogcmVwbGFjZSBTVUJMQU5HX05FVVRSQUwgYnkgU1VCTEFOR19ERUZBVUxUICovCiAgICBpZiAoU1VCTEFOR0lEKGxhbmdfaWQpID09IFNVQkxBTkdfTkVVVFJBTCkKICAgICAgICBsYW5nX2lkID0gTUFLRUxBTkdJRChQUklNQVJZTEFOR0lEKGxhbmdfaWQpLCBTVUJMQU5HX0RFRkFVTFQpOwoKICAgIGhNb2R1bGUgPSBHZXRNb2R1bGVIYW5kbGVXKCBrZXJuZWwzMlcgKTsKICAgIGlmICghKGhyc3JjID0gRmluZFJlc291cmNlRXhXKCBoTW9kdWxlLCAoTFBXU1RSKVJUX1NUUklORywgKExQQ1dTVFIpKChsY3R5cGUgPj4gNCkgKyAxKSwgbGFuZ19pZCApKSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfRkxBR1MgKTsgIC8qIG5vIHN1Y2ggbGN0eXBlICovCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBpZiAoIShobWVtID0gTG9hZFJlc291cmNlKCBoTW9kdWxlLCBocnNyYyApKSkKICAgICAgICByZXR1cm4gMDsKCiAgICBwID0gTG9ja1Jlc291cmNlKCBobWVtICk7CiAgICBmb3IgKGkgPSAwOyBpIDwgKGxjdHlwZSAmIDB4MGYpOyBpKyspIHAgKz0gKnAgKyAxOwoKICAgIGlmIChsY2ZsYWdzICYgTE9DQUxFX1JFVFVSTl9OVU1CRVIpIHJldCA9IHNpemVvZihVSU5UKS9zaXplb2YoV0NIQVIpOwogICAgZWxzZSByZXQgPSAobGN0eXBlID09IExPQ0FMRV9GT05UU0lHTkFUVVJFKSA/ICpwIDogKnAgKyAxOwoKICAgIGlmICghYnVmZmVyKSByZXR1cm4gcmV0OwoKICAgIGlmIChyZXQgPiBsZW4pCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKGxjZmxhZ3MgJiBMT0NBTEVfUkVUVVJOX05VTUJFUikKICAgIHsKICAgICAgICBVSU5UIG51bWJlcjsKICAgICAgICBXQ0hBUiAqZW5kLCAqdG1wID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCAoKnAgKyAxKSAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICBpZiAoIXRtcCkgcmV0dXJuIDA7CiAgICAgICAgbWVtY3B5KCB0bXAsIHAgKyAxLCAqcCAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICB0bXBbKnBdID0gMDsKICAgICAgICBudW1iZXIgPSBzdHJ0b2xXKCB0bXAsICZlbmQsIDEwICk7CiAgICAgICAgaWYgKCEqZW5kKQogICAgICAgICAgICBtZW1jcHkoIGJ1ZmZlciwgJm51bWJlciwgc2l6ZW9mKG51bWJlcikgKTsKICAgICAgICBlbHNlICAvKiBpbnZhbGlkIG51bWJlciAqLwogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX0ZMQUdTICk7CiAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB0bXAgKTsKCiAgICAgICAgVFJBQ0UoICIobGNpZD0weCVseCxsY3R5cGU9MHglbHgsJXAsJWQpIHJldHVybmluZyBudW1iZXIgJWRcbiIsCiAgICAgICAgICAgICAgIGxjaWQsIGxjdHlwZSwgYnVmZmVyLCBsZW4sIG51bWJlciApOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIG1lbWNweSggYnVmZmVyLCBwICsgMSwgKnAgKiBzaXplb2YoV0NIQVIpICk7CiAgICAgICAgaWYgKGxjdHlwZSAhPSBMT0NBTEVfRk9OVFNJR05BVFVSRSkgYnVmZmVyW3JldC0xXSA9IDA7CgogICAgICAgIFRSQUNFKCAiKGxjaWQ9MHglbHgsbGN0eXBlPTB4JWx4LCVwLCVkKSByZXR1cm5pbmcgJWQgJXNcbiIsCiAgICAgICAgICAgICAgIGxjaWQsIGxjdHlwZSwgYnVmZmVyLCBsZW4sIHJldCwgZGVidWdzdHJfdyhidWZmZXIpICk7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU2V0TG9jYWxlSW5mb0EJW0tFUk5FTDMyLkBdCiAqCiAqIFNldCBpbmZvcm1hdGlvbiBhYm91dCBhbiBhc3BlY3Qgb2YgYSBsb2NhbGUuCiAqCiAqIFBBUkFNUwogKiAgbGNpZCAgIFtJXSBMQ0lEIG9mIHRoZSBsb2NhbGUKICogIGxjdHlwZSBbSV0gTENUWVBFXyBmbGFncyBmcm9tICJ3aW5ubHMuaCIKICogIGRhdGEgICBbSV0gSW5mb3JtYXRpb24gdG8gc2V0CiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuIFRoZSBpbmZvcm1hdGlvbiBnaXZlbiB3aWxsIGJlIHJldHVybmVkIGJ5IEdldExvY2FsZUluZm9BKCkKICogICAgICAgICAgIHdoZW5ldmVyIGl0IGlzIGNhbGxlZCB3aXRob3V0IExPQ0FMRV9OT1VTRVJPVkVSUklERS4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICoKICogTk9URVMKICogIC0gVmFsdWVzIGFyZSBvbmx5IGJlIHNldCBmb3IgdGhlIGN1cnJlbnQgdXNlciBsb2NhbGU7IHRoZSBzeXN0ZW0gbG9jYWxlCiAqICBzZXR0aW5ncyBjYW5ub3QgYmUgY2hhbmdlZC4KICogIC0gQW55IHNldHRpbmdzIGNoYW5nZWQgYnkgdGhpcyBjYWxsIGFyZSBsb3N0IHdoZW4gdGhlIGxvY2FsZSBpcyBjaGFuZ2VkIGJ5CiAqICB0aGUgY29udHJvbCBwYW5lbCAoaW4gV2luZSwgdGhpcyBoYXBwZW5zIGV2ZXJ5IHRpbWUgeW91IGNoYW5nZSBMQU5HKS4KICogIC0gVGhlIG5hdGl2ZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGZ1bmN0aW9uIGRvZXMgbm90IGNoZWNrIHRoYXQgbGNpZCBtYXRjaGVzCiAqICB0aGUgY3VycmVudCB1c2VyIGxvY2FsZSwgYW5kIHNpbXBseSBzZXRzIHRoZSBuZXcgdmFsdWVzLiBXaW5lIHdhcm5zIHlvdSBpbgogKiAgdGhpcyBjYXNlLCBidXQgYmVoYXZlcyB0aGUgc2FtZS4KICovCkJPT0wgV0lOQVBJIFNldExvY2FsZUluZm9BKExDSUQgbGNpZCwgTENUWVBFIGxjdHlwZSwgTFBDU1RSIGRhdGEpCnsKICAgIFVJTlQgY29kZXBhZ2UgPSBDUF9BQ1A7CiAgICBXQ0hBUiAqc3RyVzsKICAgIERXT1JEIGxlbjsKICAgIEJPT0wgcmV0OwoKICAgIGxjaWQgPSBDb252ZXJ0RGVmYXVsdExvY2FsZShsY2lkKTsKCiAgICBpZiAoIShsY3R5cGUgJiBMT0NBTEVfVVNFX0NQX0FDUCkpIGNvZGVwYWdlID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxjaWQgKTsKICAgIGxlbiA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoIGNvZGVwYWdlLCAwLCBkYXRhLCAtMSwgTlVMTCwgMCApOwogICAgaWYgKCEoc3RyVyA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKFdDSEFSKSApKSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgTXVsdGlCeXRlVG9XaWRlQ2hhciggY29kZXBhZ2UsIDAsIGRhdGEsIC0xLCBzdHJXLCBsZW4gKTsKICAgIHJldCA9IFNldExvY2FsZUluZm9XKCBsY2lkLCBsY3R5cGUsIHN0clcgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJXICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU2V0TG9jYWxlSW5mb1cJKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBTZXRMb2NhbGVJbmZvQS4KICovCkJPT0wgV0lOQVBJIFNldExvY2FsZUluZm9XKCBMQ0lEIGxjaWQsIExDVFlQRSBsY3R5cGUsIExQQ1dTVFIgZGF0YSApCnsKICAgIGNvbnN0IFdDSEFSICp2YWx1ZTsKICAgIGNvbnN0IFdDSEFSIGludGxXW10gPSB7J2knLCduJywndCcsJ2wnLDAgfTsKICAgIFVOSUNPREVfU1RSSU5HIHZhbHVlVzsKICAgIE5UU1RBVFVTIHN0YXR1czsKICAgIEhLRVkgaGtleTsKCiAgICBsY2lkID0gQ29udmVydERlZmF1bHRMb2NhbGUobGNpZCk7CgogICAgbGN0eXBlICY9IDB4ZmZmZjsKICAgIHZhbHVlID0gZ2V0X2xvY2FsZV92YWx1ZV9uYW1lKCBsY3R5cGUgKTsKCiAgICBpZiAoIWRhdGEgfHwgIXZhbHVlKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKGxjdHlwZSA9PSBMT0NBTEVfSURBVEUgfHwgbGN0eXBlID09IExPQ0FMRV9JTERBVEUpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX0ZMQUdTICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChsY2lkICE9IEdldFVzZXJEZWZhdWx0TENJRCgpKQogICAgewogICAgICAgIC8qIFdpbmRvd3MgZG9lcyBub3QgY2hlY2sgdGhhdCB0aGUgbGNpZCBtYXRjaGVzIHRoZSBjdXJyZW50IGxjaWQgKi8KICAgICAgICBXQVJOKCJsb2NhbGUgMHglMDhseCBpc24ndCB0aGUgY3VycmVudCBsb2NhbGUgKDB4JTA4bHgpLCBzZXR0aW5nIGFueXdheSFcbiIsCiAgICAgICAgICAgICBsY2lkLCBHZXRVc2VyRGVmYXVsdExDSUQoKSk7CiAgICB9CgogICAgVFJBQ0UoInNldHRpbmcgJWx4IHRvICVzXG4iLCBsY3R5cGUsIGRlYnVnc3RyX3coZGF0YSkgKTsKCiAgICAvKiBGSVhNRTogc2hvdWxkIGNoZWNrIHRoYXQgZGF0YSB0byBzZXQgaXMgc2FuZSAqLwoKICAgIC8qIEZJWE1FOiBwcm9maWxlIGZ1bmN0aW9ucyBzaG91bGQgbWFwIHRvIHJlZ2lzdHJ5ICovCiAgICBXcml0ZVByb2ZpbGVTdHJpbmdXKCBpbnRsVywgdmFsdWUsIGRhdGEgKTsKCiAgICBpZiAoIShoa2V5ID0gY3JlYXRlX3JlZ2lzdHJ5X2tleSgpKSkgcmV0dXJuIEZBTFNFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZ2YWx1ZVcsIHZhbHVlICk7CiAgICBzdGF0dXMgPSBOdFNldFZhbHVlS2V5KCBoa2V5LCAmdmFsdWVXLCAwLCBSRUdfU1osIGRhdGEsIChzdHJsZW5XKGRhdGEpKzEpKnNpemVvZihXQ0hBUikgKTsKCiAgICBpZiAobGN0eXBlID09IExPQ0FMRV9TREFURSB8fCBsY3R5cGUgPT0gTE9DQUxFX1NMT05HREFURSkKICAgIHsKICAgICAgLyogU2V0IEktdmFsdWUgZnJvbSBTIHZhbHVlICovCiAgICAgIFdDSEFSICpscEQsICpscE0sICpscFk7CiAgICAgIFdDSEFSIHN6QnVmZlsyXTsKCiAgICAgIGxwRCA9IHN0cmNoclcoZGF0YSwgJ2QnKTsKICAgICAgbHBNID0gc3RyY2hyVyhkYXRhLCAnTScpOwogICAgICBscFkgPSBzdHJjaHJXKGRhdGEsICd5Jyk7CgogICAgICBpZiAobHBEIDw9IGxwTSkKICAgICAgewogICAgICAgIHN6QnVmZlswXSA9ICcxJzsgLyogRC1NLVkgKi8KICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICBpZiAobHBZIDw9IGxwTSkKICAgICAgICAgIHN6QnVmZlswXSA9ICcyJzsgLyogWS1NLUQgKi8KICAgICAgICBlbHNlCiAgICAgICAgICBzekJ1ZmZbMF0gPSAnMCc7IC8qIE0tRC1ZICovCiAgICAgIH0KCiAgICAgIHN6QnVmZlsxXSA9ICdcMCc7CgogICAgICBpZiAobGN0eXBlID09IExPQ0FMRV9TREFURSkKICAgICAgICBsY3R5cGUgPSBMT0NBTEVfSURBVEU7CiAgICAgIGVsc2UKICAgICAgICBsY3R5cGUgPSBMT0NBTEVfSUxEQVRFOwoKICAgICAgdmFsdWUgPSBnZXRfbG9jYWxlX3ZhbHVlX25hbWUoIGxjdHlwZSApOwoKICAgICAgV3JpdGVQcm9maWxlU3RyaW5nVyggaW50bFcsIHZhbHVlLCBzekJ1ZmYgKTsKCiAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmdmFsdWVXLCB2YWx1ZSApOwogICAgICBzdGF0dXMgPSBOdFNldFZhbHVlS2V5KCBoa2V5LCAmdmFsdWVXLCAwLCBSRUdfU1osIHN6QnVmZiwgc2l6ZW9mKHN6QnVmZikgKTsKICAgIH0KCiAgICBOdENsb3NlKCBoa2V5ICk7CgogICAgaWYgKHN0YXR1cykgU2V0TGFzdEVycm9yKCBSdGxOdFN0YXR1c1RvRG9zRXJyb3Ioc3RhdHVzKSApOwogICAgcmV0dXJuICFzdGF0dXM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBHZXRBQ1AgICAoS0VSTkVMMzIuQCkKICoKICogR2V0IHRoZSBjdXJyZW50IEFuc2kgY29kZSBwYWdlIElkIGZvciB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogICAgVGhlIGN1cnJlbnQgQW5zaSBjb2RlIHBhZ2UgaWRlbnRpZmllciBmb3IgdGhlIHN5c3RlbS4KICovClVJTlQgV0lOQVBJIEdldEFDUCh2b2lkKQp7CiAgICBhc3NlcnQoIGFuc2lfY3B0YWJsZSApOwogICAgcmV0dXJuIGFuc2lfY3B0YWJsZS0+aW5mby5jb2RlcGFnZTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgR2V0T0VNQ1AgICAoS0VSTkVMMzIuQCkKICoKICogR2V0IHRoZSBjdXJyZW50IE9FTSBjb2RlIHBhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgICBUaGUgY3VycmVudCBPRU0gY29kZSBwYWdlIGlkZW50aWZpZXIgZm9yIHRoZSBzeXN0ZW0uCiAqLwpVSU5UIFdJTkFQSSBHZXRPRU1DUCh2b2lkKQp7CiAgICBhc3NlcnQoIG9lbV9jcHRhYmxlICk7CiAgICByZXR1cm4gb2VtX2NwdGFibGUtPmluZm8uY29kZXBhZ2U7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElzVmFsaWRDb2RlUGFnZSAgIChLRVJORUwzMi5AKQogKgogKiBEZXRlcm1pbmUgaWYgYSBnaXZlbiBjb2RlIHBhZ2UgaWRlbnRpZmllciBpcyB2YWxpZC4KICoKICogUEFSQU1TCiAqICBjb2RlcGFnZSBbSV0gQ29kZSBwYWdlIElkIHRvIHZlcmlmeS4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgSWYgY29kZXBhZ2UgaXMgdmFsaWQgYW5kIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNWYWxpZENvZGVQYWdlKCBVSU5UIGNvZGVwYWdlICkKewogICAgc3dpdGNoKGNvZGVwYWdlKSB7CiAgICBjYXNlIENQX1NZTUJPTDoKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIENQX1VURjc6CiAgICBjYXNlIENQX1VURjg6CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiB3aW5lX2NwX2dldF90YWJsZSggY29kZXBhZ2UgKSAhPSBOVUxMOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJc0RCQ1NMZWFkQnl0ZUV4ICAgKEtFUk5FTDMyLkApCiAqCiAqIERldGVybWluZSBpZiBhIGNoYXJhY3RlciBpcyBhIGxlYWQgYnl0ZSBpbiBhIGdpdmVuIGNvZGUgcGFnZS4KICoKICogUEFSQU1TCiAqICBjb2RlcGFnZSBbSV0gQ29kZSBwYWdlIGZvciB0aGUgdGVzdC4KICogIHRlc3RjaGFyIFtJXSBDaGFyYWN0ZXIgdG8gdGVzdAogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB0ZXN0Y2hhciBpcyBhIGxlYWQgYnl0ZSBpbiBjb2RlcGFnZSwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzREJDU0xlYWRCeXRlRXgoIFVJTlQgY29kZXBhZ2UsIEJZVEUgdGVzdGNoYXIgKQp7CiAgICBjb25zdCB1bmlvbiBjcHRhYmxlICp0YWJsZSA9IGdldF9jb2RlcGFnZV90YWJsZSggY29kZXBhZ2UgKTsKICAgIHJldHVybiB0YWJsZSAmJiBpc19kYmNzX2xlYWRieXRlKCB0YWJsZSwgdGVzdGNoYXIgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSXNEQkNTTGVhZEJ5dGUgICAoS0VSTkVMMzIuQCkKICogICAgICAgICAgIElzREJDU0xlYWRCeXRlICAgKEtFUk5FTC4yMDcpCiAqCiAqIERldGVybWluZSBpZiBhIGNoYXJhY3RlciBpcyBhIGxlYWQgYnl0ZS4KICoKICogUEFSQU1TCiAqICB0ZXN0Y2hhciBbSV0gQ2hhcmFjdGVyIHRvIHRlc3QKICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgdGVzdGNoYXIgaXMgYSBsZWFkIGJ5dGUgaW4gdGhlIEFuc2lpIGNvZGUgcGFnZSwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzREJDU0xlYWRCeXRlKCBCWVRFIHRlc3RjaGFyICkKewogICAgaWYgKCFhbnNpX2NwdGFibGUpIHJldHVybiBGQUxTRTsKICAgIHJldHVybiBpc19kYmNzX2xlYWRieXRlKCBhbnNpX2NwdGFibGUsIHRlc3RjaGFyICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEdldENQSW5mbyAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgaW5mb3JtYXRpb24gYWJvdXQgYSBjb2RlIHBhZ2UuCiAqCiAqIFBBUkFNUwogKiAgY29kZXBhZ2UgW0ldIENvZGUgcGFnZSBudW1iZXIKICogIGNwaW5mbyAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29kZSBwYWdlIGluZm9ybWF0aW9uCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuIGNwaW5mbyBpcyB1cGRhdGVkIHdpdGggdGhlIGluZm9ybWF0aW9uIGFib3V0IGNvZGVwYWdlLgogKiAgRmFpbHVyZTogRkFMU0UsIGlmIGNvZGVwYWdlIGlzIGludmFsaWQgb3IgY3BpbmZvIGlzIE5VTEwuCiAqLwpCT09MIFdJTkFQSSBHZXRDUEluZm8oIFVJTlQgY29kZXBhZ2UsIExQQ1BJTkZPIGNwaW5mbyApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlID0gZ2V0X2NvZGVwYWdlX3RhYmxlKCBjb2RlcGFnZSApOwoKICAgIGlmICghdGFibGUpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIGlmICh0YWJsZS0+aW5mby5kZWZfY2hhciAmIDB4ZmYwMCkKICAgIHsKICAgICAgICBjcGluZm8tPkRlZmF1bHRDaGFyWzBdID0gdGFibGUtPmluZm8uZGVmX2NoYXIgJiAweGZmMDA7CiAgICAgICAgY3BpbmZvLT5EZWZhdWx0Q2hhclsxXSA9IHRhYmxlLT5pbmZvLmRlZl9jaGFyICYgMHgwMGZmOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGNwaW5mby0+RGVmYXVsdENoYXJbMF0gPSB0YWJsZS0+aW5mby5kZWZfY2hhciAmIDB4ZmY7CiAgICAgICAgY3BpbmZvLT5EZWZhdWx0Q2hhclsxXSA9IDA7CiAgICB9CiAgICBpZiAoKGNwaW5mby0+TWF4Q2hhclNpemUgPSB0YWJsZS0+aW5mby5jaGFyX3NpemUpID09IDIpCiAgICAgICAgbWVtY3B5KCBjcGluZm8tPkxlYWRCeXRlLCB0YWJsZS0+ZGJjcy5sZWFkX2J5dGVzLCBzaXplb2YoY3BpbmZvLT5MZWFkQnl0ZSkgKTsKICAgIGVsc2UKICAgICAgICBjcGluZm8tPkxlYWRCeXRlWzBdID0gY3BpbmZvLT5MZWFkQnl0ZVsxXSA9IDA7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0Q1BJbmZvRXhBICAgKEtFUk5FTDMyLkApCiAqCiAqIEdldCBleHRlbmRlZCBpbmZvcm1hdGlvbiBhYm91dCBhIGNvZGUgcGFnZS4KICoKICogUEFSQU1TCiAqICBjb2RlcGFnZSBbSV0gQ29kZSBwYWdlIG51bWJlcgogKiAgZHdGbGFncyAgW0ldIFJlc2VydmVkLCBtdXN0IHRvIDAuCiAqICBjcGluZm8gICBbT10gRGVzdGluYXRpb24gZm9yIGNvZGUgcGFnZSBpbmZvcm1hdGlvbgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLiBjcGluZm8gaXMgdXBkYXRlZCB3aXRoIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBjb2RlcGFnZS4KICogIEZhaWx1cmU6IEZBTFNFLCBpZiBjb2RlcGFnZSBpcyBpbnZhbGlkIG9yIGNwaW5mbyBpcyBOVUxMLgogKi8KQk9PTCBXSU5BUEkgR2V0Q1BJbmZvRXhBKCBVSU5UIGNvZGVwYWdlLCBEV09SRCBkd0ZsYWdzLCBMUENQSU5GT0VYQSBjcGluZm8gKQp7CiAgICBjb25zdCB1bmlvbiBjcHRhYmxlICp0YWJsZSA9IGdldF9jb2RlcGFnZV90YWJsZSggY29kZXBhZ2UgKTsKCiAgICBpZiAoIUdldENQSW5mbyggY29kZXBhZ2UsIChMUENQSU5GTyljcGluZm8gKSkKICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGNwaW5mby0+Q29kZVBhZ2UgPSBjb2RlcGFnZTsKICAgIGNwaW5mby0+VW5pY29kZURlZmF1bHRDaGFyID0gdGFibGUtPmluZm8uZGVmX3VuaWNvZGVfY2hhcjsKICAgIHN0cmNweShjcGluZm8tPkNvZGVQYWdlTmFtZSwgdGFibGUtPmluZm8ubmFtZSk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRDUEluZm9FeFcgICAoS0VSTkVMMzIuQCkKICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIEdldENQSW5mb0V4QS4KICovCkJPT0wgV0lOQVBJIEdldENQSW5mb0V4VyggVUlOVCBjb2RlcGFnZSwgRFdPUkQgZHdGbGFncywgTFBDUElORk9FWFcgY3BpbmZvICkKewogICAgY29uc3QgdW5pb24gY3B0YWJsZSAqdGFibGUgPSBnZXRfY29kZXBhZ2VfdGFibGUoIGNvZGVwYWdlICk7CgogICAgaWYgKCFHZXRDUEluZm8oIGNvZGVwYWdlLCAoTFBDUElORk8pY3BpbmZvICkpCiAgICAgIHJldHVybiBGQUxTRTsKCiAgICBjcGluZm8tPkNvZGVQYWdlID0gY29kZXBhZ2U7CiAgICBjcGluZm8tPlVuaWNvZGVEZWZhdWx0Q2hhciA9IHRhYmxlLT5pbmZvLmRlZl91bmljb2RlX2NoYXI7CiAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIHRhYmxlLT5pbmZvLm5hbWUsIC0xLCBjcGluZm8tPkNvZGVQYWdlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihjcGluZm8tPkNvZGVQYWdlTmFtZSkvc2l6ZW9mKFdDSEFSKSk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBFbnVtU3lzdGVtQ29kZVBhZ2VzQSAgIChLRVJORUwzMi5AKQogKgogKiBDYWxsIGEgdXNlciBkZWZpbmVkIGZ1bmN0aW9uIGZvciBldmVyeSBjb2RlIHBhZ2UgaW5zdGFsbGVkIG9uIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgIGxwZm5Db2RlUGFnZUVudW0gW0ldIFVzZXIgQ09ERVBBR0VfRU5VTVBST0MgdG8gY2FsbCB3aXRoIGVhY2ggZm91bmQgY29kZSBwYWdlCiAqICAgZmxhZ3MgICAgICAgICAgICBbSV0gUmVzZXJ2ZWQsIHNldCB0byAwLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBJZiBhbGwgY29kZSBwYWdlcyBoYXZlIGJlZW4gZW51bWVyYXRlZCwgb3IKICogIEZBTFNFIGlmIGxwZm5Db2RlUGFnZUVudW0gcmV0dXJuZWQgRkFMU0UgdG8gc3RvcCB0aGUgZW51bWVyYXRpb24uCiAqLwpCT09MIFdJTkFQSSBFbnVtU3lzdGVtQ29kZVBhZ2VzQSggQ09ERVBBR0VfRU5VTVBST0NBIGxwZm5Db2RlUGFnZUVudW0sIERXT1JEIGZsYWdzICkKewogICAgY29uc3QgdW5pb24gY3B0YWJsZSAqdGFibGU7CiAgICBjaGFyIGJ1ZmZlclsxMF07CiAgICBpbnQgaW5kZXggPSAwOwoKICAgIGZvciAoOzspCiAgICB7CiAgICAgICAgaWYgKCEodGFibGUgPSB3aW5lX2NwX2VudW1fdGFibGUoIGluZGV4KysgKSkpIGJyZWFrOwogICAgICAgIHNwcmludGYoIGJ1ZmZlciwgIiVkIiwgdGFibGUtPmluZm8uY29kZXBhZ2UgKTsKICAgICAgICBpZiAoIWxwZm5Db2RlUGFnZUVudW0oIGJ1ZmZlciApKSBicmVhazsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBFbnVtU3lzdGVtQ29kZVBhZ2VzVyAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgRW51bVN5c3RlbUNvZGVQYWdlc0EuCiAqLwpCT09MIFdJTkFQSSBFbnVtU3lzdGVtQ29kZVBhZ2VzVyggQ09ERVBBR0VfRU5VTVBST0NXIGxwZm5Db2RlUGFnZUVudW0sIERXT1JEIGZsYWdzICkKewogICAgY29uc3QgdW5pb24gY3B0YWJsZSAqdGFibGU7CiAgICBXQ0hBUiBidWZmZXJbMTBdLCAqcDsKICAgIGludCBwYWdlLCBpbmRleCA9IDA7CgogICAgZm9yICg7OykKICAgIHsKICAgICAgICBpZiAoISh0YWJsZSA9IHdpbmVfY3BfZW51bV90YWJsZSggaW5kZXgrKyApKSkgYnJlYWs7CiAgICAgICAgcCA9IGJ1ZmZlciArIHNpemVvZihidWZmZXIpL3NpemVvZihXQ0hBUik7CiAgICAgICAgKi0tcCA9IDA7CiAgICAgICAgcGFnZSA9IHRhYmxlLT5pbmZvLmNvZGVwYWdlOwogICAgICAgIGRvCiAgICAgICAgewogICAgICAgICAgICAqLS1wID0gJzAnICsgKHBhZ2UgJSAxMCk7CiAgICAgICAgICAgIHBhZ2UgLz0gMTA7CiAgICAgICAgfSB3aGlsZSggcGFnZSApOwogICAgICAgIGlmICghbHBmbkNvZGVQYWdlRW51bSggcCApKSBicmVhazsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyICAgKEtFUk5FTDMyLkApCiAqCiAqIENvbnZlcnQgYSBtdWx0aWJ5dGUgY2hhcmFjdGVyIHN0cmluZyBpbnRvIGEgVW5pY29kZSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgIHBhZ2UgICBbSV0gQ29kZXBhZ2UgY2hhcmFjdGVyIHNldCB0byBjb252ZXJ0IGZyb20KICogICBmbGFncyAgW0ldIENoYXJhY3RlciBtYXBwaW5nIGZsYWdzCiAqICAgc3JjICAgIFtJXSBTb3VyY2Ugc3RyaW5nIGJ1ZmZlcgogKiAgIHNyY2xlbiBbSV0gTGVuZ3RoIG9mIHNyYywgb3IgLTEgaWYgc3JjIGlzIE5VTCB0ZXJtaW5hdGVkCiAqICAgZHN0ICAgIFtPXSBEZXN0aW5hdGlvbiBidWZmZXIKICogICBkc3RsZW4gW0ldIExlbmd0aCBvZiBkc3QsIG9yIDAgdG8gY29tcHV0ZSB0aGUgcmVxdWlyZWQgbGVuZ3RoCiAqCiAqIFJFVFVSTlMKICogICBTdWNjZXNzOiBJZiBkc3RsZW4gPiAwLCB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgd3JpdHRlbiB0byBkc3QuCiAqICAgICAgICAgICAgSWYgZHN0bGVuID09IDAsIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBuZWVkZWQgdG8gcGVyZm9ybSB0aGUKICogICAgICAgICAgICBjb252ZXJzaW9uLiBJbiBib3RoIGNhc2VzIHRoZSBjb3VudCBpbmNsdWRlcyB0aGUgdGVybWluYXRpbmcgTlVMLgogKiAgIEZhaWx1cmU6IDAuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLiBQb3NzaWJsZSBlcnJvcnMgYXJlCiAqICAgICAgICAgICAgRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiwgaWYgbm90IGVub3VnaCBzcGFjZSBpcyBhdmFpbGFibGUgaW4gZHN0CiAqICAgICAgICAgICAgYW5kIGRzdGxlbiAhPSAwOyBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiwgIGlmIGFuIGludmFsaWQgcGFyYW1ldGVyCiAqICAgICAgICAgICAgaXMgcGFzc2VkLCBhbmQgRVJST1JfTk9fVU5JQ09ERV9UUkFOU0xBVElPTiBpZiBubyB0cmFuc2xhdGlvbiBpcwogKiAgICAgICAgICAgIHBvc3NpYmxlIGZvciBzcmMuCiAqLwpJTlQgV0lOQVBJIE11bHRpQnl0ZVRvV2lkZUNoYXIoIFVJTlQgcGFnZSwgRFdPUkQgZmxhZ3MsIExQQ1NUUiBzcmMsIElOVCBzcmNsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGRzdCwgSU5UIGRzdGxlbiApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlOwogICAgaW50IHJldDsKCiAgICBpZiAoIXNyYyB8fCAoIWRzdCAmJiBkc3RsZW4pKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoc3JjbGVuIDwgMCkgc3JjbGVuID0gc3RybGVuKHNyYykgKyAxOwoKICAgIGlmIChmbGFncyAmIE1CX1VTRUdMWVBIQ0hBUlMpIEZJWE1FKCJNQl9VU0VHTFlQSENIQVJTIG5vdCBzdXBwb3J0ZWRcbiIpOwoKICAgIHN3aXRjaChwYWdlKQogICAgewogICAgY2FzZSBDUF9VVEY3OgogICAgICAgIEZJWE1FKCJVVEYtNyBub3Qgc3VwcG9ydGVkXG4iKTsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0NBTExfTk9UX0lNUExFTUVOVEVEICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICBjYXNlIENQX1VOSVhDUDoKICAgICAgICBpZiAodW5peF9jcHRhYmxlKQogICAgICAgIHsKICAgICAgICAgICAgcmV0ID0gd2luZV9jcF9tYnN0b3djcyggdW5peF9jcHRhYmxlLCBmbGFncywgc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgIGNhc2UgQ1BfVVRGODoKICAgICAgICByZXQgPSB3aW5lX3V0ZjhfbWJzdG93Y3MoIGZsYWdzLCBzcmMsIHNyY2xlbiwgZHN0LCBkc3RsZW4gKTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgaWYgKCEodGFibGUgPSBnZXRfY29kZXBhZ2VfdGFibGUoIHBhZ2UgKSkpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICByZXQgPSB3aW5lX2NwX21ic3Rvd2NzKCB0YWJsZSwgZmxhZ3MsIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbiApOwogICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChyZXQgPCAwKQogICAgewogICAgICAgIHN3aXRjaChyZXQpCiAgICAgICAgewogICAgICAgIGNhc2UgLTE6IFNldExhc3RFcnJvciggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiApOyBicmVhazsKICAgICAgICBjYXNlIC0yOiBTZXRMYXN0RXJyb3IoIEVSUk9SX05PX1VOSUNPREVfVFJBTlNMQVRJT04gKTsgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHJldCA9IDA7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlICAgKEtFUk5FTDMyLkApCiAqCiAqIENvbnZlcnQgYSBVbmljb2RlIGNoYXJhY3RlciBzdHJpbmcgaW50byBhIG11bHRpYnl0ZSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgIHBhZ2UgICAgW0ldIENvZGUgcGFnZSBjaGFyYWN0ZXIgc2V0IHRvIGNvbnZlcnQgdG8KICogICBmbGFncyAgIFtJXSBNYXBwaW5nIEZsYWdzIChNQl8gY29uc3RhbnRzIGZyb20gIndpbm5scy5oIikuCiAqICAgc3JjICAgICBbSV0gU291cmNlIHN0cmluZyBidWZmZXIKICogICBzcmNsZW4gIFtJXSBMZW5ndGggb2Ygc3JjLCBvciAtMSBpZiBzcmMgaXMgTlVMIHRlcm1pbmF0ZWQKICogICBkc3QgICAgIFtPXSBEZXN0aW5hdGlvbiBidWZmZXIKICogICBkc3RsZW4gIFtJXSBMZW5ndGggb2YgZHN0LCBvciAwIHRvIGNvbXB1dGUgdGhlIHJlcXVpcmVkIGxlbmd0aAogKiAgIGRlZmNoYXIgW0ldIERlZmF1bHQgY2hhcmFjdGVyIHRvIHVzZSBmb3IgY29udmVyc2lvbiBpZiBubyBleGFjdAogKgkJICAgIGNvbnZlcnNpb24gY2FuIGJlIG1hZGUKICogICB1c2VkICAgIFtPXSBTZXQgaWYgZGVmYXVsdCBjaGFyYWN0ZXIgd2FzIHVzZWQgaW4gdGhlIGNvbnZlcnNpb24KICoKICogUkVUVVJOUwogKiAgIFN1Y2Nlc3M6IElmIGRzdGxlbiA+IDAsIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB3cml0dGVuIHRvIGRzdC4KICogICAgICAgICAgICBJZiBkc3RsZW4gPT0gMCwgbnVtYmVyIG9mIGNoYXJhY3RlcnMgbmVlZGVkIHRvIHBlcmZvcm0gdGhlCiAqICAgICAgICAgICAgY29udmVyc2lvbi4gSW4gYm90aCBjYXNlcyB0aGUgY291bnQgaW5jbHVkZXMgdGhlIHRlcm1pbmF0aW5nIE5VTC4KICogICBGYWlsdXJlOiAwLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4gUG9zc2libGUgZXJyb3JzIGFyZQogKiAgICAgICAgICAgIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIsIGlmIG5vdCBlbm91Z2ggc3BhY2UgaXMgYXZhaWxhYmxlIGluIGRzdAogKiAgICAgICAgICAgIGFuZCBkc3RsZW4gIT0gMCwgYW5kIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSLCBpZiBhbiBpbnZhbGlkCiAqICAgICAgICAgICAgcGFyYW1ldGVyIHdhcyBnaXZlbi4KICovCklOVCBXSU5BUEkgV2lkZUNoYXJUb011bHRpQnl0ZSggVUlOVCBwYWdlLCBEV09SRCBmbGFncywgTFBDV1NUUiBzcmMsIElOVCBzcmNsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgZHN0LCBJTlQgZHN0bGVuLCBMUENTVFIgZGVmY2hhciwgQk9PTCAqdXNlZCApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlOwogICAgaW50IHJldCwgdXNlZF90bXA7CgogICAgaWYgKCFzcmMgfHwgKCFkc3QgJiYgZHN0bGVuKSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKHNyY2xlbiA8IDApIHNyY2xlbiA9IHN0cmxlblcoc3JjKSArIDE7CgogICAgc3dpdGNoKHBhZ2UpCiAgICB7CiAgICBjYXNlIENQX1VURjc6CiAgICAgICAgRklYTUUoIlVURi03IG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfQ0FMTF9OT1RfSU1QTEVNRU5URUQgKTsKICAgICAgICByZXR1cm4gMDsKICAgIGNhc2UgQ1BfVU5JWENQOgogICAgICAgIGlmICh1bml4X2NwdGFibGUpCiAgICAgICAgewogICAgICAgICAgICByZXQgPSB3aW5lX2NwX3djc3RvbWJzKCB1bml4X2NwdGFibGUsIGZsYWdzLCBzcmMsIHNyY2xlbiwgZHN0LCBkc3RsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmNoYXIsIHVzZWQgPyAmdXNlZF90bXAgOiBOVUxMICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgIGNhc2UgQ1BfVVRGODoKICAgICAgICByZXQgPSB3aW5lX3V0Zjhfd2NzdG9tYnMoIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbiApOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBpZiAoISh0YWJsZSA9IGdldF9jb2RlcGFnZV90YWJsZSggcGFnZSApKSkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIHJldCA9IHdpbmVfY3Bfd2NzdG9tYnMoIHRhYmxlLCBmbGFncywgc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmNoYXIsIHVzZWQgPyAmdXNlZF90bXAgOiBOVUxMICk7CiAgICAgICAgaWYgKHVzZWQpICp1c2VkID0gdXNlZF90bXA7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHJldCA9PSAtMSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIgKTsKICAgICAgICByZXQgPSAwOwogICAgfQogICAgVFJBQ0UoImNwICVkICVzIC0+ICVzXG4iLCBwYWdlLCBkZWJ1Z3N0cl93KHNyYyksIGRlYnVnc3RyX2EoZHN0KSk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRUaHJlYWRMb2NhbGUgICAgKEtFUk5FTDMyLkApCiAqCiAqIEdldCB0aGUgY3VycmVudCB0aHJlYWRzIGxvY2FsZS4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICBUaGUgTENJRCBjdXJyZW50bHkgYXNzb2NhdGVkIHdpdGggdGhlIGNhbGxpbmcgdGhyZWFkLgogKi8KTENJRCBXSU5BUEkgR2V0VGhyZWFkTG9jYWxlKHZvaWQpCnsKICAgIExDSUQgcmV0ID0gTnRDdXJyZW50VGViKCktPkN1cnJlbnRMb2NhbGU7CiAgICBpZiAoIXJldCkgTnRDdXJyZW50VGViKCktPkN1cnJlbnRMb2NhbGUgPSByZXQgPSBHZXRVc2VyRGVmYXVsdExDSUQoKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBTZXRUaHJlYWRMb2NhbGUgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNldCB0aGUgY3VycmVudCB0aHJlYWRzIGxvY2FsZS4KICoKICogUEFSQU1TCiAqICBsY2lkIFtJXSBMQ0lEIG9mIHRoZSBsb2NhbGUgdG8gc2V0CiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuIFRoZSB0aHJlYWRzIGxvY2FsZSBpcyBzZXQgdG8gbGNpZC4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCkJPT0wgV0lOQVBJIFNldFRocmVhZExvY2FsZSggTENJRCBsY2lkICkKewogICAgVFJBQ0UoIigweCUwNGxYKVxuIiwgbGNpZCk7CgogICAgbGNpZCA9IENvbnZlcnREZWZhdWx0TG9jYWxlKGxjaWQpOwoKICAgIGlmIChsY2lkICE9IEdldFRocmVhZExvY2FsZSgpKQogICAgewogICAgICAgIGlmICghSXNWYWxpZExvY2FsZShsY2lkLCBMQ0lEX1NVUFBPUlRFRCkpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQoKICAgICAgICBOdEN1cnJlbnRUZWIoKS0+Q3VycmVudExvY2FsZSA9IGxjaWQ7CiAgICAgICAgTnRDdXJyZW50VGViKCktPmNvZGVfcGFnZSA9IGdldF9sY2lkX2NvZGVwYWdlKCBsY2lkICk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQ29udmVydERlZmF1bHRMb2NhbGUgKEtFUk5FTDMyLkApCiAqCiAqIENvbnZlcnQgYSBkZWZhdWx0IGxvY2FsZSBpZGVudGlmaWVyIGludG8gYSByZWFsIGlkZW50aWZpZXIuCiAqCiAqIFBBUkFNUwogKiAgbGNpZCBbSV0gTENJRCBpZGVudGlmaWVyIG9mIHRoZSBsb2NhbGUgdG8gY29udmVydAogKgogKiBSRVRVUk5TCiAqICBsY2lkIHVuY2hhbmdlZCwgaWYgbm90IGEgZGVmYXVsdCBsb2NhbGUgb3IgaXRzIHN1Ymxhbmd1YWdlIGlzCiAqICAgbm90IFNVQkxBTkdfTkVVVFJBTC4KICogIEdldFN5c3RlbURlZmF1bHRMQ0lEKCksIGlmIGxjaWQgPT0gTE9DQUxFX1NZU1RFTV9ERUZBVUxULgogKiAgR2V0VXNlckRlZmF1bHRMQ0lEKCksIGlmIGxjaWQgPT0gTE9DQUxFX1VTRVJfREVGQVVMVCBvciBMT0NBTEVfTkVVVFJBTC4KICogIE90aGVyd2lzZSwgbGNpZCB3aXRoIHN1Ymxhbmd1YWdlIGNoYW5nZWQgdG8gU1VCTEFOR19ERUZBVUxULgogKi8KTENJRCBXSU5BUEkgQ29udmVydERlZmF1bHRMb2NhbGUoIExDSUQgbGNpZCApCnsKICAgIExBTkdJRCBsYW5naWQ7CgogICAgc3dpdGNoIChsY2lkKQogICAgewogICAgY2FzZSBMT0NBTEVfU1lTVEVNX0RFRkFVTFQ6CiAgICAgICAgbGNpZCA9IEdldFN5c3RlbURlZmF1bHRMQ0lEKCk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIExPQ0FMRV9VU0VSX0RFRkFVTFQ6CiAgICBjYXNlIExPQ0FMRV9ORVVUUkFMOgogICAgICAgIGxjaWQgPSBHZXRVc2VyRGVmYXVsdExDSUQoKTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgLyogUmVwbGFjZSBTVUJMQU5HX05FVVRSQUwgd2l0aCBTVUJMQU5HX0RFRkFVTFQgKi8KICAgICAgICBsYW5naWQgPSBMQU5HSURGUk9NTENJRChsY2lkKTsKICAgICAgICBpZiAoU1VCTEFOR0lEKGxhbmdpZCkgPT0gU1VCTEFOR19ORVVUUkFMKQogICAgICAgIHsKICAgICAgICAgIGxhbmdpZCA9IE1BS0VMQU5HSUQoUFJJTUFSWUxBTkdJRChsYW5naWQpLCBTVUJMQU5HX0RFRkFVTFQpOwogICAgICAgICAgbGNpZCA9IE1BS0VMQ0lEKGxhbmdpZCwgU09SVElERlJPTUxDSUQobGNpZCkpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBsY2lkOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSXNWYWxpZExvY2FsZSAgIChLRVJORUwzMi5AKQogKgogKiBEZXRlcm1pbmUgaWYgYSBsb2NhbGUgaXMgdmFsaWQuCiAqCiAqIFBBUkFNUwogKiAgbGNpZCAgW0ldIExDSUQgb2YgdGhlIGxvY2FsZSB0byBjaGVjawogKiAgZmxhZ3MgW0ldIExDSURfU1VQUE9SVEVEID0gVmFsaWQsIExDSURfSU5TVEFMTEVEID0gVmFsaWQgYW5kIGluc3RhbGxlZCBvbiB0aGUgc3lzdGVtCiAqCiAqIFJFVFVSTgogKiAgVFJVRSwgIGlmIGxjaWQgaXMgdmFsaWQsCiAqICBGQUxTRSwgb3RoZXJ3aXNlLgogKgogKiBOT1RFUwogKiAgV2luZSBkb2VzIG5vdCBjdXJyZW50bHkgbWFrZSB0aGUgZGlzdGluY3Rpb24gYmV0d2VlbiBzdXBwb3J0ZWQgYW5kIGluc3RhbGxlZC4gQWxsCiAqICBsYW5ndWFnZXMgc3VwcG9ydGVkIGFyZSBpbnN0YWxsZWQgYnkgZGVmYXVsdC4KICovCkJPT0wgV0lOQVBJIElzVmFsaWRMb2NhbGUoIExDSUQgbGNpZCwgRFdPUkQgZmxhZ3MgKQp7CiAgICAvKiBjaGVjayBpZiBsYW5ndWFnZSBpcyByZWdpc3RlcmVkIGluIHRoZSBrZXJuZWwzMiByZXNvdXJjZXMgKi8KICAgIHJldHVybiBGaW5kUmVzb3VyY2VFeFcoIEdldE1vZHVsZUhhbmRsZVcoa2VybmVsMzJXKSwgKExQV1NUUilSVF9TVFJJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBDV1NUUilMT0NBTEVfSUxBTkdVQUdFLCBMQU5HSURGUk9NTENJRChsY2lkKSkgIT0gMDsKfQoKCnN0YXRpYyBCT09MIENBTExCQUNLIGVudW1fbGFuZ19wcm9jX2EoIEhNT0RVTEUgaE1vZHVsZSwgTFBDU1RSIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBuYW1lLCBXT1JEIExhbmdJRCwgTE9ORyBsUGFyYW0gKQp7CiAgICBMT0NBTEVfRU5VTVBST0NBIGxwZm5Mb2NhbGVFbnVtID0gKExPQ0FMRV9FTlVNUFJPQ0EpbFBhcmFtOwogICAgY2hhciBidWZbMjBdOwoKICAgIHNwcmludGYoYnVmLCAiJTA4eCIsIChVSU5UKUxhbmdJRCk7CiAgICByZXR1cm4gbHBmbkxvY2FsZUVudW0oIGJ1ZiApOwp9CgpzdGF0aWMgQk9PTCBDQUxMQkFDSyBlbnVtX2xhbmdfcHJvY193KCBITU9EVUxFIGhNb2R1bGUsIExQQ1dTVFIgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBuYW1lLCBXT1JEIExhbmdJRCwgTE9ORyBsUGFyYW0gKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgZm9ybWF0V1tdID0geyclJywnMCcsJzgnLCd4JywwfTsKICAgIExPQ0FMRV9FTlVNUFJPQ1cgbHBmbkxvY2FsZUVudW0gPSAoTE9DQUxFX0VOVU1QUk9DVylsUGFyYW07CiAgICBXQ0hBUiBidWZbMjBdOwogICAgc3ByaW50ZlcoIGJ1ZiwgZm9ybWF0VywgKFVJTlQpTGFuZ0lEICk7CiAgICByZXR1cm4gbHBmbkxvY2FsZUVudW0oIGJ1ZiApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtU3lzdGVtTG9jYWxlc0EgIChLRVJORUwzMi5AKQogKgogKiBDYWxsIGEgdXNlcnMgZnVuY3Rpb24gZm9yIGVhY2ggbG9jYWxlIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIGxwZm5Mb2NhbGVFbnVtIFtJXSBDYWxsYmFjayBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGxvY2FsZQogKiAgZHdGbGFncyAgICAgICAgW0ldIExPQ0FMRV9TVVBQT1JURUQ9QWxsIHN1cHBvcnRlZCwgTE9DQUxFX0lOU1RBTExFRD1JbnN0YWxsZWQgb25seQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUxvY2FsZXNBKCBMT0NBTEVfRU5VTVBST0NBIGxwZm5Mb2NhbGVFbnVtLCBEV09SRCBkd0ZsYWdzICkKewogICAgVFJBQ0UoIiglcCwlMDhseClcbiIsIGxwZm5Mb2NhbGVFbnVtLCBkd0ZsYWdzKTsKICAgIEVudW1SZXNvdXJjZUxhbmd1YWdlc0EoIEdldE1vZHVsZUhhbmRsZVcoa2VybmVsMzJXKSwgKExQU1RSKVJUX1NUUklORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUENTVFIpTE9DQUxFX0lMQU5HVUFHRSwgZW51bV9sYW5nX3Byb2NfYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMT05HKWxwZm5Mb2NhbGVFbnVtKTsKICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRW51bVN5c3RlbUxvY2FsZXNXICAoS0VSTkVMMzIuQCkKICoKICogU2VlIEVudW1TeXN0ZW1Mb2NhbGVzQS4KICovCkJPT0wgV0lOQVBJIEVudW1TeXN0ZW1Mb2NhbGVzVyggTE9DQUxFX0VOVU1QUk9DVyBscGZuTG9jYWxlRW51bSwgRFdPUkQgZHdGbGFncyApCnsKICAgIFRSQUNFKCIoJXAsJTA4bHgpXG4iLCBscGZuTG9jYWxlRW51bSwgZHdGbGFncyk7CiAgICBFbnVtUmVzb3VyY2VMYW5ndWFnZXNXKCBHZXRNb2R1bGVIYW5kbGVXKGtlcm5lbDMyVyksIChMUFdTVFIpUlRfU1RSSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQ1dTVFIpTE9DQUxFX0lMQU5HVUFHRSwgZW51bV9sYW5nX3Byb2NfdywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMT05HKWxwZm5Mb2NhbGVFbnVtKTsKICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBWZXJMYW5ndWFnZU5hbWVBICAoS0VSTkVMMzIuQCkKICoKICogR2V0IHRoZSBuYW1lIG9mIGEgbGFuZ3VhZ2UuCiAqCiAqIFBBUkFNUwogKiAgd0xhbmcgIFtJXSBMQU5HSUQgb2YgdGhlIGxhbmd1YWdlCiAqICBzekxhbmcgW09dIERlc3RpbmF0aW9uIGZvciB0aGUgbGFuZ3VhZ2UgbmFtZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgc2l6ZSBvZiB0aGUgbGFuZ3VhZ2UgbmFtZS4gSWYgc3pMYW5nIGlzIG5vbi1OVUxMLCBpdCBpcyBmaWxsZWQKICogICAgICAgICAgIHdpdGggdGhlIG5hbWUuCiAqICBGYWlsdXJlOiAwLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICoKICovCkRXT1JEIFdJTkFQSSBWZXJMYW5ndWFnZU5hbWVBKCBVSU5UIHdMYW5nLCBMUFNUUiBzekxhbmcsIFVJTlQgblNpemUgKQp7CiAgICByZXR1cm4gR2V0TG9jYWxlSW5mb0EoIE1BS0VMQ0lEKHdMYW5nLCBTT1JUX0RFRkFVTFQpLCBMT0NBTEVfU0VOR0xBTkdVQUdFLCBzekxhbmcsIG5TaXplICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFZlckxhbmd1YWdlTmFtZVcgIChLRVJORUwzMi5AKQogKgogKiBTZWUgVmVyTGFuZ3VhZ2VOYW1lQS4KICovCkRXT1JEIFdJTkFQSSBWZXJMYW5ndWFnZU5hbWVXKCBVSU5UIHdMYW5nLCBMUFdTVFIgc3pMYW5nLCBVSU5UIG5TaXplICkKewogICAgcmV0dXJuIEdldExvY2FsZUluZm9XKCBNQUtFTENJRCh3TGFuZywgU09SVF9ERUZBVUxUKSwgTE9DQUxFX1NFTkdMQU5HVUFHRSwgc3pMYW5nLCBuU2l6ZSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0U3RyaW5nVHlwZVcgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBHZXRTdHJpbmdUeXBlQS4KICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGVXKCBEV09SRCB0eXBlLCBMUENXU1RSIHNyYywgSU5UIGNvdW50LCBMUFdPUkQgY2hhcnR5cGUgKQp7CiAgICBpZiAoY291bnQgPT0gLTEpIGNvdW50ID0gc3RybGVuVyhzcmMpICsgMTsKICAgIHN3aXRjaCh0eXBlKQogICAgewogICAgY2FzZSBDVF9DVFlQRTE6CiAgICAgICAgd2hpbGUgKGNvdW50LS0pICpjaGFydHlwZSsrID0gZ2V0X2NoYXJfdHlwZVcoICpzcmMrKyApICYgMHhmZmY7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENUX0NUWVBFMjoKICAgICAgICB3aGlsZSAoY291bnQtLSkgKmNoYXJ0eXBlKysgPSBnZXRfY2hhcl90eXBlVyggKnNyYysrICkgPj4gMTI7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENUX0NUWVBFMzoKICAgIHsKICAgICAgICBXQVJOKCJDVF9DVFlQRTM6IHNlbWktc3R1Yi5cbiIpOwogICAgICAgIHdoaWxlIChjb3VudC0tKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGMgPSAqc3JjOwogICAgICAgICAgICBXT1JEIHR5cGUxLCB0eXBlMyA9IDA7IC8qIEMzX05PVEFQUExJQ0FCTEUgKi8KCiAgICAgICAgICAgIHR5cGUxID0gZ2V0X2NoYXJfdHlwZVcoICpzcmMrKyApICYgMHhmZmY7CiAgICAgICAgICAgIC8qIHRyeSB0byBjb25zdHJ1Y3QgdHlwZTMgZnJvbSB0eXBlMSAqLwogICAgICAgICAgICBpZih0eXBlMSAmIEMxX1NQQUNFKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmKHR5cGUxICYgQzFfQUxQSEEpIHR5cGUzIHw9IEMzX0FMUEhBOwogICAgICAgICAgICBpZiAoKGM+PTB4MzBBMCkmJihjPD0weDMwRkYpKSB0eXBlMyB8PSBDM19LQVRBS0FOQTsKICAgICAgICAgICAgaWYgKChjPj0weDMwNDApJiYoYzw9MHgzMDlGKSkgdHlwZTMgfD0gQzNfSElSQUdBTkE7CiAgICAgICAgICAgIGlmICgoYz49MHg0RTAwKSYmKGM8PTB4OUZBRikpIHR5cGUzIHw9IEMzX0lERU9HUkFQSDsKICAgICAgICAgICAgaWYgKChjPj0weDA2MDApJiYoYzw9MHgwNkZGKSkgdHlwZTMgfD0gQzNfS0FTSElEQTsKICAgICAgICAgICAgaWYgKChjPj0weDMwMDApJiYoYzw9MHgzMDNGKSkgdHlwZTMgfD0gQzNfU1lNQk9MOwoKICAgICAgICAgICAgaWYgKChjPj0weEZGMDApJiYoYzw9MHhGRjYwKSkgdHlwZTMgfD0gQzNfRlVMTFdJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkYwMCkmJihjPD0weEZGMjApKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjNCKSYmKGM8PTB4RkY0MCkpIHR5cGUzIHw9IEMzX1NZTUJPTDsKICAgICAgICAgICAgaWYgKChjPj0weEZGNUIpJiYoYzw9MHhGRjYwKSkgdHlwZTMgfD0gQzNfU1lNQk9MOwogICAgICAgICAgICBpZiAoKGM+PTB4RkYyMSkmJihjPD0weEZGM0EpKSB0eXBlMyB8PSBDM19BTFBIQTsKICAgICAgICAgICAgaWYgKChjPj0weEZGNDEpJiYoYzw9MHhGRjVBKSkgdHlwZTMgfD0gQzNfQUxQSEE7CiAgICAgICAgICAgIGlmICgoYz49MHhGRkUwKSYmKGM8PTB4RkZFNikpIHR5cGUzIHw9IEMzX0ZVTExXSURUSDsKICAgICAgICAgICAgaWYgKChjPj0weEZGRTApJiYoYzw9MHhGRkU2KSkgdHlwZTMgfD0gQzNfU1lNQk9MOwoKICAgICAgICAgICAgaWYgKChjPj0weEZGNjEpJiYoYzw9MHhGRkRDKSkgdHlwZTMgfD0gQzNfSEFMRldJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkY2MSkmJihjPD0weEZGNjQpKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjY1KSYmKGM8PTB4RkY5RikpIHR5cGUzIHw9IEMzX0tBVEFLQU5BOwogICAgICAgICAgICBpZiAoKGM+PTB4RkY2NSkmJihjPD0weEZGOUYpKSB0eXBlMyB8PSBDM19BTFBIQTsKICAgICAgICAgICAgaWYgKChjPj0weEZGRTgpJiYoYzw9MHhGRkVFKSkgdHlwZTMgfD0gQzNfSEFMRldJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkZFOCkmJihjPD0weEZGRUUpKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgICpjaGFydHlwZSsrID0gdHlwZTM7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgZGVmYXVsdDoKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlRXhXICAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgR2V0U3RyaW5nVHlwZUV4QS4KICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGVFeFcoIExDSUQgbG9jYWxlLCBEV09SRCB0eXBlLCBMUENXU1RSIHNyYywgSU5UIGNvdW50LCBMUFdPUkQgY2hhcnR5cGUgKQp7CiAgICAvKiBsb2NhbGUgaXMgaWdub3JlZCBmb3IgVW5pY29kZSAqLwogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKCB0eXBlLCBzcmMsIGNvdW50LCBjaGFydHlwZSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0U3RyaW5nVHlwZUEgICAgKEtFUk5FTDMyLkApCiAqCiAqIEdldCBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIGNoYXJhY3RlcnMgbWFraW5nIHVwIGEgc3RyaW5nLgogKgogKiBQQVJBTVMKICogIGxvY2FsZSAgIFtJXSBMb2NhbGUgSWQgZm9yIHRoZSBzdHJpbmcKICogIHR5cGUgICAgIFtJXSBDVF9DVFlQRTEgPSBjbGFzc2lmaWNhdGlvbiwgQ1RfQ1RZUEUyID0gZGlyZWN0aW9uYWxpdHksIENUX0NUWVBFMyA9IHR5cG9ncmFwaGljIGluZm8KICogIHNyYyAgICAgIFtJXSBTdHJpbmcgdG8gYW5hbHlzZQogKiAgY291bnQgICAgW0ldIExlbmd0aCBvZiBzcmMgaW4gY2hhcnMsIG9yIC0xIGlmIHNyYyBpcyBOVUwgdGVybWluYXRlZAogKiAgY2hhcnR5cGUgW09dIERlc3RpbmF0aW9uIGZvciB0aGUgY2FsY3VsYXRlZCBjaGFyYWN0ZXJpc3RpY3MKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gY2hhcnR5cGUgaXMgZmlsbGVkIHdpdGggdGhlIHJlcXVlc3RlZCBjaGFyYWN0ZXJpc3RpY3Mgb2YgZWFjaCBjaGFyCiAqICAgICAgICAgICBpbiBzcmMuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpCT09MIFdJTkFQSSBHZXRTdHJpbmdUeXBlQSggTENJRCBsb2NhbGUsIERXT1JEIHR5cGUsIExQQ1NUUiBzcmMsIElOVCBjb3VudCwgTFBXT1JEIGNoYXJ0eXBlICkKewogICAgVUlOVCBjcDsKICAgIElOVCBjb3VudFc7CiAgICBMUFdTVFIgc3JjVzsKICAgIEJPT0wgcmV0ID0gRkFMU0U7CgogICAgaWYoY291bnQgPT0gLTEpIGNvdW50ID0gc3RybGVuKHNyYykgKyAxOwoKICAgIGlmICghKGNwID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxvY2FsZSApKSkKICAgIHsKICAgICAgICBGSVhNRSgiRm9yIGxvY2FsZSAlMDRseCB1c2luZyBjdXJyZW50IEFOU0kgY29kZSBwYWdlXG4iLCBsb2NhbGUpOwogICAgICAgIGNwID0gR2V0QUNQKCk7CiAgICB9CgogICAgY291bnRXID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihjcCwgMCwgc3JjLCBjb3VudCwgTlVMTCwgMCk7CiAgICBpZigoc3JjVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjb3VudFcgKiBzaXplb2YoV0NIQVIpKSkpCiAgICB7CiAgICAgICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihjcCwgMCwgc3JjLCBjb3VudCwgc3JjVywgY291bnRXKTsKICAgIC8qCiAgICAgKiBOT1RFOiB0aGUgdGFyZ2V0IGJ1ZmZlciBoYXMgMSB3b3JkIGZvciBlYWNoIENIQVJBQ1RFUiBpbiB0aGUgc291cmNlCiAgICAgKiBzdHJpbmcsIHdpdGggbXVsdGlieXRlIGNoYXJhY3RlcnMgdGhlcmUgbWF5YmUgYmUgbW9yZSBieXRlcyBpbiBjb3VudAogICAgICogdGhhbiBjaGFyYWN0ZXIgc3BhY2UgaW4gdGhlIGJ1ZmZlciEKICAgICAqLwogICAgICAgIHJldCA9IEdldFN0cmluZ1R5cGVXKHR5cGUsIHNyY1csIGNvdW50VywgY2hhcnR5cGUpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY1cpOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0U3RyaW5nVHlwZUV4QSAgICAoS0VSTkVMMzIuQCkKICoKICogR2V0IGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgY2hhcmFjdGVycyBtYWtpbmcgdXAgYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgbG9jYWxlICAgW0ldIExvY2FsZSBJZCBmb3IgdGhlIHN0cmluZwogKiAgdHlwZSAgICAgW0ldIENUX0NUWVBFMSA9IGNsYXNzaWZpY2F0aW9uLCBDVF9DVFlQRTIgPSBkaXJlY3Rpb25hbGl0eSwgQ1RfQ1RZUEUzID0gdHlwb2dyYXBoaWMgaW5mbwogKiAgc3JjICAgICAgW0ldIFN0cmluZyB0byBhbmFseXNlCiAqICBjb3VudCAgICBbSV0gTGVuZ3RoIG9mIHNyYyBpbiBjaGFycywgb3IgLTEgaWYgc3JjIGlzIE5VTCB0ZXJtaW5hdGVkCiAqICBjaGFydHlwZSBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBjYWxjdWxhdGVkIGNoYXJhY3RlcmlzdGljcwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLiBjaGFydHlwZSBpcyBmaWxsZWQgd2l0aCB0aGUgcmVxdWVzdGVkIGNoYXJhY3RlcmlzdGljcyBvZiBlYWNoIGNoYXIKICogICAgICAgICAgIGluIHNyYy4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGVFeEEoIExDSUQgbG9jYWxlLCBEV09SRCB0eXBlLCBMUENTVFIgc3JjLCBJTlQgY291bnQsIExQV09SRCBjaGFydHlwZSApCnsKICAgIHJldHVybiBHZXRTdHJpbmdUeXBlQShsb2NhbGUsIHR5cGUsIHNyYywgY291bnQsIGNoYXJ0eXBlKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBMQ01hcFN0cmluZ1cgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBMQ01hcFN0cmluZ0EuCiAqLwpJTlQgV0lOQVBJIExDTWFwU3RyaW5nVyhMQ0lEIGxjaWQsIERXT1JEIGZsYWdzLCBMUENXU1RSIHNyYywgSU5UIHNyY2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGRzdCwgSU5UIGRzdGxlbikKewogICAgTFBXU1RSIGRzdF9wdHI7CgogICAgaWYgKCFzcmMgfHwgIXNyY2xlbiB8fCBkc3RsZW4gPCAwKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyogbXV0dWFsbHkgZXhjbHVzaXZlIGZsYWdzICovCiAgICBpZiAoKGZsYWdzICYgKExDTUFQX0xPV0VSQ0FTRSB8IExDTUFQX1VQUEVSQ0FTRSkpID09IChMQ01BUF9MT1dFUkNBU0UgfCBMQ01BUF9VUFBFUkNBU0UpIHx8CiAgICAgICAgKGZsYWdzICYgKExDTUFQX0hJUkFHQU5BIHwgTENNQVBfS0FUQUtBTkEpKSA9PSAoTENNQVBfSElSQUdBTkEgfCBMQ01BUF9LQVRBS0FOQSkgfHwKICAgICAgICAoZmxhZ3MgJiAoTENNQVBfSEFMRldJRFRIIHwgTENNQVBfRlVMTFdJRFRIKSkgPT0gKExDTUFQX0hBTEZXSURUSCB8IExDTUFQX0ZVTExXSURUSCkgfHwKICAgICAgICAoZmxhZ3MgJiAoTENNQVBfVFJBRElUSU9OQUxfQ0hJTkVTRSB8IExDTUFQX1NJTVBMSUZJRURfQ0hJTkVTRSkpID09IChMQ01BUF9UUkFESVRJT05BTF9DSElORVNFIHwgTENNQVBfU0lNUExJRklFRF9DSElORVNFKSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKCFkc3RsZW4pIGRzdCA9IE5VTEw7CgogICAgbGNpZCA9IENvbnZlcnREZWZhdWx0TG9jYWxlKGxjaWQpOwoKICAgIGlmIChmbGFncyAmIExDTUFQX1NPUlRLRVkpCiAgICB7CiAgICAgICAgaWYgKHNyYyA9PSBkc3QpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNyY2xlbiA8IDApIHNyY2xlbiA9IHN0cmxlblcoc3JjKTsKCiAgICAgICAgVFJBQ0UoIigweCUwNGx4LDB4JTA4bHgsJXMsJWQsJXAsJWQpXG4iLAogICAgICAgICAgICAgIGxjaWQsIGZsYWdzLCBkZWJ1Z3N0cl93bihzcmMsIHNyY2xlbiksIHNyY2xlbiwgZHN0LCBkc3RsZW4pOwoKICAgICAgICByZXR1cm4gd2luZV9nZXRfc29ydGtleShmbGFncywgc3JjLCBzcmNsZW4sIChjaGFyICopZHN0LCBkc3RsZW4pOwogICAgfQoKICAgIC8qIFNPUlRfU1RSSU5HU09SVCBtdXN0IGJlIHVzZWQgZXhjbHVzaXZlbHkgd2l0aCBMQ01BUF9TT1JUS0VZICovCiAgICBpZiAoZmxhZ3MgJiBTT1JUX1NUUklOR1NPUlQpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChzcmNsZW4gPCAwKSBzcmNsZW4gPSBzdHJsZW5XKHNyYykgKyAxOwoKICAgIFRSQUNFKCIoMHglMDRseCwweCUwOGx4LCVzLCVkLCVwLCVkKVxuIiwKICAgICAgICAgIGxjaWQsIGZsYWdzLCBkZWJ1Z3N0cl93bihzcmMsIHNyY2xlbiksIHNyY2xlbiwgZHN0LCBkc3RsZW4pOwoKICAgIGlmICghZHN0KSAvKiByZXR1cm4gcmVxdWlyZWQgc3RyaW5nIGxlbmd0aCAqLwogICAgewogICAgICAgIElOVCBsZW47CgogICAgICAgIGZvciAobGVuID0gMDsgc3JjbGVuOyBzcmMrKywgc3JjbGVuLS0pCiAgICAgICAgewogICAgICAgICAgICBXQ0hBUiB3Y2ggPSAqc3JjOwogICAgICAgICAgICAvKiB0ZXN0cyBzaG93IHRoYXQgd2luMmsganVzdCBpZ25vcmVzIE5PUk1fSUdOT1JFTk9OU1BBQ0UsCiAgICAgICAgICAgICAqIGFuZCBza2lwcyB3aGl0ZSBzcGFjZSBhbmQgcHVuY3R1YXRpb24gY2hhcmFjdGVycyBmb3IKICAgICAgICAgICAgICogTk9STV9JR05PUkVTWU1CT0xTLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKChmbGFncyAmIE5PUk1fSUdOT1JFU1lNQk9MUykgJiYgKGdldF9jaGFyX3R5cGVXKHdjaCkgJiAoQzFfUFVOQ1QgfCBDMV9TUEFDRSkpKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGxlbisrOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbGVuOwogICAgfQoKICAgIGlmIChmbGFncyAmIExDTUFQX1VQUEVSQ0FTRSkKICAgIHsKICAgICAgICBmb3IgKGRzdF9wdHIgPSBkc3Q7IHNyY2xlbiAmJiBkc3RsZW47IHNyYysrLCBzcmNsZW4tLSkKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSIHdjaCA9ICpzcmM7CiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBOT1JNX0lHTk9SRVNZTUJPTFMpICYmIChnZXRfY2hhcl90eXBlVyh3Y2gpICYgKEMxX1BVTkNUIHwgQzFfU1BBQ0UpKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAqZHN0X3B0cisrID0gdG91cHBlclcod2NoKTsKICAgICAgICAgICAgZHN0bGVuLS07CiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZiAoZmxhZ3MgJiBMQ01BUF9MT1dFUkNBU0UpCiAgICB7CiAgICAgICAgZm9yIChkc3RfcHRyID0gZHN0OyBzcmNsZW4gJiYgZHN0bGVuOyBzcmMrKywgc3JjbGVuLS0pCiAgICAgICAgewogICAgICAgICAgICBXQ0hBUiB3Y2ggPSAqc3JjOwogICAgICAgICAgICBpZiAoKGZsYWdzICYgTk9STV9JR05PUkVTWU1CT0xTKSAmJiAoZ2V0X2NoYXJfdHlwZVcod2NoKSAmIChDMV9QVU5DVCB8IEMxX1NQQUNFKSkpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgKmRzdF9wdHIrKyA9IHRvbG93ZXJXKHdjaCk7CiAgICAgICAgICAgIGRzdGxlbi0tOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAoc3JjID09IGRzdCkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIGZvciAoZHN0X3B0ciA9IGRzdDsgc3JjbGVuICYmIGRzdGxlbjsgc3JjKyssIHNyY2xlbi0tKQogICAgICAgIHsKICAgICAgICAgICAgV0NIQVIgd2NoID0gKnNyYzsKICAgICAgICAgICAgaWYgKChmbGFncyAmIE5PUk1fSUdOT1JFU1lNQk9MUykgJiYgKGdldF9jaGFyX3R5cGVXKHdjaCkgJiAoQzFfUFVOQ1QgfCBDMV9TUEFDRSkpKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICpkc3RfcHRyKysgPSB3Y2g7CiAgICAgICAgICAgIGRzdGxlbi0tOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoc3JjbGVuKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICByZXR1cm4gZHN0X3B0ciAtIGRzdDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIExDTWFwU3RyaW5nQSAgICAoS0VSTkVMMzIuQCkKICoKICogTWFwIGNoYXJhY3RlcnMgaW4gYSBsb2NhbGUgc2Vuc2l0aXZlIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBsY2lkICAgW0ldIExDSUQgZm9yIHRoZSBjb252ZXJzaW9uLgogKiAgZmxhZ3MgIFtJXSBGbGFncyBjb250cm9sbGluZyB0aGUgbWFwcGluZyAoTENNQVBfIGNvbnN0YW50cyBmcm9tICJ3aW5ubHMuaCIpLgogKiAgc3JjICAgIFtJXSBTdHJpbmcgdG8gbWFwCiAqICBzcmNsZW4gW0ldIExlbmd0aCBvZiBzcmMgaW4gY2hhcnMsIG9yIC0xIGlmIHNyYyBpcyBOVUwgdGVybWluYXRlZAogKiAgZHN0ICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgbWFwcGVkIHN0cmluZwogKiAgZHN0bGVuIFtJXSBMZW5ndGggb2YgZHN0IGluIGNoYXJhY3RlcnMKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIGxlbmd0aCBvZiB0aGUgbWFwcGVkIHN0cmluZyBpbiBkc3QsIGluY2x1ZGluZyB0aGUgTlVMIHRlcm1pbmF0b3IuCiAqICBGYWlsdXJlOiAwLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCklOVCBXSU5BUEkgTENNYXBTdHJpbmdBKExDSUQgbGNpZCwgRFdPUkQgZmxhZ3MsIExQQ1NUUiBzcmMsIElOVCBzcmNsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGRzdCwgSU5UIGRzdGxlbikKewogICAgV0NIQVIgKmJ1ZlcgPSBOdEN1cnJlbnRUZWIoKS0+U3RhdGljVW5pY29kZUJ1ZmZlcjsKICAgIExQV1NUUiBzcmNXLCBkc3RXOwogICAgSU5UIHJldCA9IDAsIHNyY2xlblcsIGRzdGxlblc7CiAgICBVSU5UIGxvY2FsZV9jcDsKCiAgICBpZiAoIXNyYyB8fCAhc3JjbGVuIHx8IGRzdGxlbiA8IDApCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBsb2NhbGVfY3AgPSBnZXRfbGNpZF9jb2RlcGFnZShsY2lkKTsKCiAgICBzcmNsZW5XID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHNyYywgc3JjbGVuLCBidWZXLCAyNjApOwogICAgaWYgKHNyY2xlblcpCiAgICAgICAgc3JjVyA9IGJ1Zlc7CiAgICBlbHNlCiAgICB7CiAgICAgICAgc3JjbGVuVyA9IE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzcmMsIHNyY2xlbiwgTlVMTCwgMCk7CiAgICAgICAgc3JjVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzcmNsZW5XICogc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgaWYgKCFzcmNXKQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzcmMsIHNyY2xlbiwgc3JjVywgc3JjbGVuVyk7CiAgICB9CgogICAgaWYgKGZsYWdzICYgTENNQVBfU09SVEtFWSkKICAgIHsKICAgICAgICBpZiAoc3JjID09IGRzdCkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICAgICAgZ290byBtYXBfc3RyaW5nX2V4aXQ7CiAgICAgICAgfQogICAgICAgIHJldCA9IHdpbmVfZ2V0X3NvcnRrZXkoZmxhZ3MsIHNyY1csIHNyY2xlblcsIGRzdCwgZHN0bGVuKTsKICAgICAgICBnb3RvIG1hcF9zdHJpbmdfZXhpdDsKICAgIH0KCiAgICBpZiAoZmxhZ3MgJiBTT1JUX1NUUklOR1NPUlQpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgIGdvdG8gbWFwX3N0cmluZ19leGl0OwogICAgfQoKICAgIGRzdGxlblcgPSBMQ01hcFN0cmluZ1cobGNpZCwgZmxhZ3MsIHNyY1csIHNyY2xlblcsIE5VTEwsIDApOwogICAgaWYgKCFkc3RsZW5XKQogICAgICAgIGdvdG8gbWFwX3N0cmluZ19leGl0OwoKICAgIGRzdFcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0bGVuVyAqIHNpemVvZihXQ0hBUikpOwogICAgaWYgKCFkc3RXKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgICAgZ290byBtYXBfc3RyaW5nX2V4aXQ7CiAgICB9CgogICAgTENNYXBTdHJpbmdXKGxjaWQsIGZsYWdzLCBzcmNXLCBzcmNsZW5XLCBkc3RXLCBkc3RsZW5XKTsKICAgIHJldCA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUobG9jYWxlX2NwLCAwLCBkc3RXLCBkc3RsZW5XLCBkc3QsIGRzdGxlbiwgTlVMTCwgTlVMTCk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3RXKTsKCm1hcF9zdHJpbmdfZXhpdDoKICAgIGlmIChzcmNXICE9IGJ1ZlcpIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY1cpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEZvbGRTdHJpbmdBICAgIChLRVJORUwzMi5AKQogKgogKiBNYXAgY2hhcmFjdGVycyBpbiBhIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBkd0ZsYWdzIFtJXSBGbGFncyBjb250cm9sbGluZyBjaGFycyB0byBtYXAgKE1BUF8gY29uc3RhbnRzIGZyb20gIndpbm5scy5oIikKICogIHNyYyAgICAgW0ldIFN0cmluZyB0byBtYXAKICogIHNyY2xlbiAgW0ldIExlbmd0aCBvZiBzcmMsIG9yIC0xIGlmIHNyYyBpcyBOVUwgdGVybWluYXRlZAogKiAgZHN0ICAgICBbT10gRGVzdGluYXRpb24gZm9yIG1hcHBlZCBzdHJpbmcKICogIGRzdGxlbiAgW0ldIExlbmd0aCBvZiBkc3QsIG9yIDAgdG8gZmluZCB0aGUgcmVxdWlyZWQgbGVuZ3RoIGZvciB0aGUgbWFwcGVkIHN0cmluZwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgd3JpdHRlbiB0byBkc3QsIGluY2x1ZGluZyB0aGUgdGVybWluYXRpbmcgTlVMLiBJZgogKiAgICAgICAgICAgZHN0bGVuIGlzIDAsIHRoZSB2YWx1ZSByZXR1cm5lZCBpcyB0aGUgc2FtZSwgYnV0IG5vdGhpbmcgaXMgd3JpdHRlbiB0byBkc3QsCiAqICAgICAgICAgICBhbmQgZHN0IG1heSBiZSBOVUxMLgogKiAgRmFpbHVyZTogMC4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpJTlQgV0lOQVBJIEZvbGRTdHJpbmdBKERXT1JEIGR3RmxhZ3MsIExQQ1NUUiBzcmMsIElOVCBzcmNsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgZHN0LCBJTlQgZHN0bGVuKQp7CiAgICBJTlQgcmV0ID0gMCwgc3JjbGVuVyA9IDA7CiAgICBXQ0hBUiAqc3JjVyA9IE5VTEwsICpkc3RXID0gTlVMTDsKCiAgICBpZiAoIXNyYyB8fCAhc3JjbGVuIHx8IGRzdGxlbiA8IDAgfHwgKGRzdGxlbiAmJiAhZHN0KSB8fCBzcmMgPT0gZHN0KQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgc3JjbGVuVyA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCBkd0ZsYWdzICYgTUFQX0NPTVBPU0lURSA/IE1CX0NPTVBPU0lURSA6IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmMsIHNyY2xlbiwgTlVMTCwgMCk7CiAgICBzcmNXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY2xlblcgKiBzaXplb2YoV0NIQVIpKTsKCiAgICBpZiAoIXNyY1cpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgICBnb3RvIEZvbGRTdHJpbmdBX2V4aXQ7CiAgICB9CgogICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIGR3RmxhZ3MgJiBNQVBfQ09NUE9TSVRFID8gTUJfQ09NUE9TSVRFIDogMCwKICAgICAgICAgICAgICAgICAgICAgICAgc3JjLCBzcmNsZW4sIHNyY1csIHNyY2xlblcpOwoKICAgIGR3RmxhZ3MgPSAoZHdGbGFncyAmIH5NQVBfUFJFQ09NUE9TRUQpIHwgTUFQX0ZPTERDWk9ORTsKCiAgICByZXQgPSBGb2xkU3RyaW5nVyhkd0ZsYWdzLCBzcmNXLCBzcmNsZW5XLCBOVUxMLCAwKTsKICAgIGlmIChyZXQgJiYgZHN0bGVuKQogICAgewogICAgICAgIGRzdFcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmV0ICogc2l6ZW9mKFdDSEFSKSk7CgogICAgICAgIGlmICghZHN0VykKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgICAgICAgIGdvdG8gRm9sZFN0cmluZ0FfZXhpdDsKICAgICAgICB9CgogICAgICAgIHJldCA9IEZvbGRTdHJpbmdXKGR3RmxhZ3MsIHNyY1csIHNyY2xlblcsIGRzdFcsIHJldCk7CiAgICAgICAgaWYgKCFXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgZHN0VywgcmV0LCBkc3QsIGRzdGxlbiwgTlVMTCwgTlVMTCkpCiAgICAgICAgewogICAgICAgICAgICByZXQgPSAwOwogICAgICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUik7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChkc3RXKQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRzdFcpOwoKRm9sZFN0cmluZ0FfZXhpdDoKICAgIGlmIChzcmNXKQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY1cpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEZvbGRTdHJpbmdXICAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgRm9sZFN0cmluZ0EuCiAqLwpJTlQgV0lOQVBJIEZvbGRTdHJpbmdXKERXT1JEIGR3RmxhZ3MsIExQQ1dTVFIgc3JjLCBJTlQgc3JjbGVuLAogICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBkc3QsIElOVCBkc3RsZW4pCnsKICAgIGludCByZXQ7CgogICAgc3dpdGNoIChkd0ZsYWdzICYgKE1BUF9DT01QT1NJVEV8TUFQX1BSRUNPTVBPU0VEfE1BUF9FWFBBTkRfTElHQVRVUkVTKSkKICAgIHsKICAgIGNhc2UgMDoKICAgICAgICBpZiAoZHdGbGFncykKICAgICAgICAgIGJyZWFrOwogICAgICAgIC8qIEZhbGwgdGhyb3VnaCBmb3IgZHdGbGFncyA9PSAwICovCiAgICBjYXNlIE1BUF9QUkVDT01QT1NFRHxNQVBfQ09NUE9TSVRFOgogICAgY2FzZSBNQVBfUFJFQ09NUE9TRUR8TUFQX0VYUEFORF9MSUdBVFVSRVM6CiAgICBjYXNlIE1BUF9DT01QT1NJVEV8TUFQX0VYUEFORF9MSUdBVFVSRVM6CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmICghc3JjIHx8ICFzcmNsZW4gfHwgZHN0bGVuIDwgMCB8fCAoZHN0bGVuICYmICFkc3QpIHx8IHNyYyA9PSBkc3QpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICByZXQgPSB3aW5lX2ZvbGRfc3RyaW5nKGR3RmxhZ3MsIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbik7CiAgICBpZiAoIXJldCkKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUik7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBDb21wYXJlU3RyaW5nVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIENvbXBhcmVTdHJpbmdBLgogKi8KSU5UIFdJTkFQSSBDb21wYXJlU3RyaW5nVyhMQ0lEIGxjaWQsIERXT1JEIHN0eWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgc3RyMSwgSU5UIGxlbjEsIExQQ1dTVFIgc3RyMiwgSU5UIGxlbjIpCnsKICAgIElOVCByZXQ7CgogICAgaWYgKCFzdHIxIHx8ICFzdHIyKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYoIHN0eWxlICYgfihOT1JNX0lHTk9SRUNBU0V8Tk9STV9JR05PUkVOT05TUEFDRXxOT1JNX0lHTk9SRVNZTUJPTFN8CiAgICAgICAgU09SVF9TVFJJTkdTT1JUfE5PUk1fSUdOT1JFS0FOQVRZUEV8Tk9STV9JR05PUkVXSURUSHwweDEwMDAwMDAwKSApCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChzdHlsZSAmIDB4MTAwMDAwMDApCiAgICAgICAgRklYTUUoIklnbm9yaW5nIHVua25vd24gc3R5bGUgMHgxMDAwMDAwMFxuIik7CgogICAgaWYgKGxlbjEgPCAwKSBsZW4xID0gc3RybGVuVyhzdHIxKTsKICAgIGlmIChsZW4yIDwgMCkgbGVuMiA9IHN0cmxlblcoc3RyMik7CgogICAgcmV0ID0gd2luZV9jb21wYXJlX3N0cmluZyhzdHlsZSwgc3RyMSwgbGVuMSwgc3RyMiwgbGVuMik7CgogICAgaWYgKHJldCkgLyogbmVlZCB0byB0cmFuc2xhdGUgcmVzdWx0ICovCiAgICAgICAgcmV0dXJuIChyZXQgPCAwKSA/IENTVFJfTEVTU19USEFOIDogQ1NUUl9HUkVBVEVSX1RIQU47CiAgICByZXR1cm4gQ1NUUl9FUVVBTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgQ29tcGFyZVN0cmluZ0EgICAgKEtFUk5FTDMyLkApCiAqCiAqIENvbXBhcmUgdHdvIGxvY2FsZSBzZW5zaXRpdmUgc3RyaW5ncy4KICoKICogUEFSQU1TCiAqICBsY2lkICBbSV0gTENJRCBmb3IgdGhlIGNvbXBhcmFzb24KICogIHN0eWxlIFtJXSBGbGFncyBmb3IgdGhlIGNvbXBhcmFzb24gKE5PUk1fIGNvbnN0YW50cyBmcm9tICJ3aW5ubHMuaCIpLgogKiAgc3RyMSAgW0ldIEZpcnN0IHN0cmluZyB0byBjb21wYXJlCiAqICBsZW4xICBbSV0gTGVuZ3RoIG9mIHN0cjEsIG9yIC0xIGlmIHN0cjEgaXMgTlVMIHRlcm1pbmF0ZWQKICogIHN0cjIgIFtJXSBTZWNvbmQgc3RyaW5nIHRvIGNvbXBhcmUKICogIGxlbjIgIFtJXSBMZW5ndGggb2Ygc3RyMiwgb3IgLTEgaWYgc3RyMiBpcyBOVUwgdGVybWluYXRlZAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBDU1RSX0xFU1NfVEhBTiwgQ1NUUl9FUVVBTCBvciBDU1RSX0dSRUFURVJfVEhBTiBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgICAgICAgICAgc3RyMiBpcyBsZXNzIHRoYW4sIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiBzdHIxIHJlc3BlY3RpdmVseS4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCklOVCBXSU5BUEkgQ29tcGFyZVN0cmluZ0EoTENJRCBsY2lkLCBEV09SRCBzdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgc3RyMSwgSU5UIGxlbjEsIExQQ1NUUiBzdHIyLCBJTlQgbGVuMikKewogICAgV0NIQVIgKmJ1ZjFXID0gTnRDdXJyZW50VGViKCktPlN0YXRpY1VuaWNvZGVCdWZmZXI7CiAgICBXQ0hBUiAqYnVmMlcgPSBidWYxVyArIDEzMDsKICAgIExQV1NUUiBzdHIxVywgc3RyMlc7CiAgICBJTlQgbGVuMVcsIGxlbjJXLCByZXQ7CiAgICBVSU5UIGxvY2FsZV9jcDsKCiAgICBpZiAoIXN0cjEgfHwgIXN0cjIpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGlmIChsZW4xIDwgMCkgbGVuMSA9IHN0cmxlbihzdHIxKTsKICAgIGlmIChsZW4yIDwgMCkgbGVuMiA9IHN0cmxlbihzdHIyKTsKCiAgICBsb2NhbGVfY3AgPSBnZXRfbGNpZF9jb2RlcGFnZShsY2lkKTsKCiAgICBsZW4xVyA9IE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzdHIxLCBsZW4xLCBidWYxVywgMTMwKTsKICAgIGlmIChsZW4xVykKICAgICAgICBzdHIxVyA9IGJ1ZjFXOwogICAgZWxzZQogICAgewogICAgICAgIGxlbjFXID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHN0cjEsIGxlbjEsIE5VTEwsIDApOwogICAgICAgIHN0cjFXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbjFXICogc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgaWYgKCFzdHIxVykKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3RyMSwgbGVuMSwgc3RyMVcsIGxlbjFXKTsKICAgIH0KICAgIGxlbjJXID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHN0cjIsIGxlbjIsIGJ1ZjJXLCAxMzApOwogICAgaWYgKGxlbjJXKQogICAgICAgIHN0cjJXID0gYnVmMlc7CiAgICBlbHNlCiAgICB7CiAgICAgICAgbGVuMlcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3RyMiwgbGVuMiwgTlVMTCwgMCk7CiAgICAgICAgc3RyMlcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuMlcgKiBzaXplb2YoV0NIQVIpKTsKICAgICAgICBpZiAoIXN0cjJXKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHN0cjFXICE9IGJ1ZjFXKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIxVyk7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3RyMiwgbGVuMiwgc3RyMlcsIGxlbjJXKTsKICAgIH0KCiAgICByZXQgPSBDb21wYXJlU3RyaW5nVyhsY2lkLCBzdHlsZSwgc3RyMVcsIGxlbjFXLCBzdHIyVywgbGVuMlcpOwoKICAgIGlmIChzdHIxVyAhPSBidWYxVykgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyMVcpOwogICAgaWYgKHN0cjJXICE9IGJ1ZjJXKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIyVyk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgbHN0cmNtcCAgICAgKEtFUk5FTDMyLkApCiAqICAgICAgICAgICBsc3RyY21wQSAgICAoS0VSTkVMMzIuQCkKICoKICogQ29tcGFyZSB0d28gc3RyaW5ncyB1c2luZyB0aGUgY3VycmVudCB0aHJlYWQgbG9jYWxlLgogKgogKiBQQVJBTVMKICogIHN0cjEgIFtJXSBGaXJzdCBzdHJpbmcgdG8gY29tcGFyZQogKiAgc3RyMiAgW0ldIFNlY29uZCBzdHJpbmcgdG8gY29tcGFyZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBBIG51bWJlciBsZXNzIHRoYW4sIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICAgICAgICAgICBzdHIyIGlzIGxlc3MgdGhhbiwgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHN0cjEgcmVzcGVjdGl2ZWx5LgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KaW50IFdJTkFQSSBsc3RyY21wQShMUENTVFIgc3RyMSwgTFBDU1RSIHN0cjIpCnsKICAgIGludCByZXQgPSBDb21wYXJlU3RyaW5nQShHZXRUaHJlYWRMb2NhbGUoKSwgMCwgc3RyMSwgLTEsIHN0cjIsIC0xKTsKICAgIGlmIChyZXQpIHJldCAtPSAyOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIGxzdHJjbXBpICAgICAoS0VSTkVMMzIuQCkKICogICAgICAgICAgIGxzdHJjbXBpQSAgICAoS0VSTkVMMzIuQCkKICoKICogQ29tcGFyZSB0d28gc3RyaW5ncyB1c2luZyB0aGUgY3VycmVudCB0aHJlYWQgbG9jYWxlLCBpZ25vcmluZyBjYXNlLgogKgogKiBQQVJBTVMKICogIHN0cjEgIFtJXSBGaXJzdCBzdHJpbmcgdG8gY29tcGFyZQogKiAgc3RyMiAgW0ldIFNlY29uZCBzdHJpbmcgdG8gY29tcGFyZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBBIG51bWJlciBsZXNzIHRoYW4sIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICAgICAgICAgICBzdHIyIGlzIGxlc3MgdGhhbiwgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHN0cjEgcmVzcGVjdGl2ZWx5LgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KaW50IFdJTkFQSSBsc3RyY21waUEoTFBDU1RSIHN0cjEsIExQQ1NUUiBzdHIyKQp7CiAgICBpbnQgcmV0ID0gQ29tcGFyZVN0cmluZ0EoR2V0VGhyZWFkTG9jYWxlKCksIE5PUk1fSUdOT1JFQ0FTRSwgc3RyMSwgLTEsIHN0cjIsIC0xKTsKICAgIGlmIChyZXQpIHJldCAtPSAyOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIGxzdHJjbXBXICAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgbHN0cmNtcEEuCiAqLwppbnQgV0lOQVBJIGxzdHJjbXBXKExQQ1dTVFIgc3RyMSwgTFBDV1NUUiBzdHIyKQp7CiAgICBpbnQgcmV0ID0gQ29tcGFyZVN0cmluZ1coR2V0VGhyZWFkTG9jYWxlKCksIDAsIHN0cjEsIC0xLCBzdHIyLCAtMSk7CiAgICBpZiAocmV0KSByZXQgLT0gMjsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBsc3RyY21waVcgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBsc3RyY21waUEuCiAqLwppbnQgV0lOQVBJIGxzdHJjbXBpVyhMUENXU1RSIHN0cjEsIExQQ1dTVFIgc3RyMikKewogICAgaW50IHJldCA9IENvbXBhcmVTdHJpbmdXKEdldFRocmVhZExvY2FsZSgpLCBOT1JNX0lHTk9SRUNBU0UsIHN0cjEsIC0xLCBzdHIyLCAtMSk7CiAgICBpZiAocmV0KSByZXQgLT0gMjsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUxPQ0FMRV9Jbml0CiAqLwp2b2lkIExPQ0FMRV9Jbml0KHZvaWQpCnsKICAgIGV4dGVybiB2b2lkIF9fd2luZV9pbml0X2NvZGVwYWdlcyggY29uc3QgdW5pb24gY3B0YWJsZSAqYW5zaV9jcCwgY29uc3QgdW5pb24gY3B0YWJsZSAqb2VtX2NwICk7CgogICAgVUlOVCBhbnNpX2NwID0gMTI1Miwgb2VtX2NwID0gNDM3LCBtYWNfY3AgPSAxMDAwMCwgdW5peF9jcCA9IH4wVTsKICAgIExDSUQgbGNpZCA9IGluaXRfZGVmYXVsdF9sY2lkKCAmdW5peF9jcCApOwoKICAgIE50U2V0RGVmYXVsdExvY2FsZSggRkFMU0UsIGxjaWQgKTsKICAgIE50U2V0RGVmYXVsdExvY2FsZSggVFJVRSwgbGNpZCApOwoKICAgIGFuc2lfY3AgPSBnZXRfbGNpZF9jb2RlcGFnZShsY2lkKTsKICAgIEdldExvY2FsZUluZm9XKCBsY2lkLCBMT0NBTEVfSURFRkFVTFRNQUNDT0RFUEFHRSB8IExPQ0FMRV9SRVRVUk5fTlVNQkVSLAogICAgICAgICAgICAgICAgICAgIChMUFdTVFIpJm1hY19jcCwgc2l6ZW9mKG1hY19jcCkvc2l6ZW9mKFdDSEFSKSApOwogICAgR2V0TG9jYWxlSW5mb1coIGxjaWQsIExPQ0FMRV9JREVGQVVMVENPREVQQUdFIHwgTE9DQUxFX1JFVFVSTl9OVU1CRVIsCiAgICAgICAgICAgICAgICAgICAgKExQV1NUUikmb2VtX2NwLCBzaXplb2Yob2VtX2NwKS9zaXplb2YoV0NIQVIpICk7CiAgICBpZiAodW5peF9jcCA9PSB+MFUpCiAgICAgICAgR2V0TG9jYWxlSW5mb1coIGxjaWQsIExPQ0FMRV9JREVGQVVMVFVOSVhDT0RFUEFHRSB8IExPQ0FMRV9SRVRVUk5fTlVNQkVSLAogICAgICAgICAgICAgICAgICAgIChMUFdTVFIpJnVuaXhfY3AsIHNpemVvZih1bml4X2NwKS9zaXplb2YoV0NIQVIpICk7CgogICAgaWYgKCEoYW5zaV9jcHRhYmxlID0gd2luZV9jcF9nZXRfdGFibGUoIGFuc2lfY3AgKSkpCiAgICAgICAgYW5zaV9jcHRhYmxlID0gd2luZV9jcF9nZXRfdGFibGUoIDEyNTIgKTsKICAgIGlmICghKG9lbV9jcHRhYmxlID0gd2luZV9jcF9nZXRfdGFibGUoIG9lbV9jcCApKSkKICAgICAgICBvZW1fY3B0YWJsZSAgPSB3aW5lX2NwX2dldF90YWJsZSggNDM3ICk7CiAgICBpZiAoIShtYWNfY3B0YWJsZSA9IHdpbmVfY3BfZ2V0X3RhYmxlKCBtYWNfY3AgKSkpCiAgICAgICAgbWFjX2NwdGFibGUgID0gd2luZV9jcF9nZXRfdGFibGUoIDEwMDAwICk7CiAgICBpZiAodW5peF9jcCAhPSBDUF9VVEY4KQogICAgewogICAgICAgIGlmICghKHVuaXhfY3B0YWJsZSA9IHdpbmVfY3BfZ2V0X3RhYmxlKCB1bml4X2NwICkpKQogICAgICAgICAgICB1bml4X2NwdGFibGUgID0gd2luZV9jcF9nZXRfdGFibGUoIDI4NTkxICk7CiAgICB9CgogICAgX193aW5lX2luaXRfY29kZXBhZ2VzKCBhbnNpX2NwdGFibGUsIG9lbV9jcHRhYmxlICk7CgogICAgVFJBQ0UoICJhbnNpPSUwM2Qgb2VtPSUwM2QgbWFjPSUwM2QgdW5peD0lMDNkXG4iLAogICAgICAgICAgIGFuc2lfY3B0YWJsZS0+aW5mby5jb2RlcGFnZSwgb2VtX2NwdGFibGUtPmluZm8uY29kZXBhZ2UsCiAgICAgICAgICAgbWFjX2NwdGFibGUtPmluZm8uY29kZXBhZ2UsIHVuaXhfY3AgKTsKfQoKc3RhdGljIEhLRVkgTkxTX1JlZ09wZW5LZXkoSEtFWSBoUm9vdEtleSwgTFBDV1NUUiBzektleU5hbWUpCnsKICAgIFVOSUNPREVfU1RSSU5HIGtleU5hbWU7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgSEtFWSBoa2V5OwoKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAma2V5TmFtZSwgc3pLZXlOYW1lICk7CiAgICBJbml0aWFsaXplT2JqZWN0QXR0cmlidXRlcygmYXR0ciwgJmtleU5hbWUsIDAsIGhSb290S2V5LCBOVUxMKTsKCiAgICBpZiAoTnRPcGVuS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyICkgIT0gU1RBVFVTX1NVQ0NFU1MpCiAgICAgICAgaGtleSA9IDA7CgogICAgcmV0dXJuIGhrZXk7Cn0KCnN0YXRpYyBIS0VZIE5MU19SZWdPcGVuU3ViS2V5KEhLRVkgaFJvb3RLZXksIExQQ1dTVFIgc3pLZXlOYW1lKQp7CiAgICBIS0VZIGhLZXkgPSBOTFNfUmVnT3BlbktleShoUm9vdEtleSwgc3pLZXlOYW1lKTsKCiAgICBpZiAoaFJvb3RLZXkpCiAgICAgICAgTnRDbG9zZSggaFJvb3RLZXkgKTsKCiAgICByZXR1cm4gaEtleTsKfQoKc3RhdGljIEJPT0wgTkxTX1JlZ0VudW1TdWJLZXkoSEtFWSBoS2V5LCBVSU5UIHVsSW5kZXgsIExQV1NUUiBzektleU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIGtleU5hbWVTaXplKQp7CiAgICBCWVRFIGJ1ZmZlcls4MF07CiAgICBLRVlfQkFTSUNfSU5GT1JNQVRJT04gKmluZm8gPSAoS0VZX0JBU0lDX0lORk9STUFUSU9OICopYnVmZmVyOwogICAgRFdPUkQgZHdMZW47CgogICAgaWYgKE50RW51bWVyYXRlS2V5KCBoS2V5LCB1bEluZGV4LCBLZXlCYXNpY0luZm9ybWF0aW9uLCBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihidWZmZXIpLCAmZHdMZW4pICE9IFNUQVRVU19TVUNDRVNTIHx8CiAgICAgICAgaW5mby0+TmFtZUxlbmd0aCA+IGtleU5hbWVTaXplKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBUUkFDRSgiaW5mby0+TmFtZSAlcyBpbmZvLT5OYW1lTGVuZ3RoICVsZFxuIiwgZGVidWdzdHJfdyhpbmZvLT5OYW1lKSwgaW5mby0+TmFtZUxlbmd0aCk7CgogICAgbWVtY3B5KCBzektleU5hbWUsIGluZm8tPk5hbWUsIGluZm8tPk5hbWVMZW5ndGgpOwogICAgc3pLZXlOYW1lW2luZm8tPk5hbWVMZW5ndGggLyBzaXplb2YoV0NIQVIpXSA9ICdcMCc7CgogICAgVFJBQ0UoInJldHVybmluZyAlc1xuIiwgZGVidWdzdHJfdyhzektleU5hbWUpKTsKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBOTFNfUmVnRW51bVZhbHVlKEhLRVkgaEtleSwgVUlOVCB1bEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBzelZhbHVlTmFtZSwgVUxPTkcgdmFsdWVOYW1lU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgc3pWYWx1ZURhdGEsIFVMT05HIHZhbHVlRGF0YVNpemUpCnsKICAgIEJZVEUgYnVmZmVyWzgwXTsKICAgIEtFWV9WQUxVRV9GVUxMX0lORk9STUFUSU9OICppbmZvID0gKEtFWV9WQUxVRV9GVUxMX0lORk9STUFUSU9OICopYnVmZmVyOwogICAgRFdPUkQgZHdMZW47CgogICAgaWYgKE50RW51bWVyYXRlVmFsdWVLZXkoIGhLZXksIHVsSW5kZXgsIEtleVZhbHVlRnVsbEluZm9ybWF0aW9uLAogICAgICAgIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksICZkd0xlbiApICE9IFNUQVRVU19TVUNDRVNTIHx8CiAgICAgICAgaW5mby0+TmFtZUxlbmd0aCA+IHZhbHVlTmFtZVNpemUgfHwKICAgICAgICBpbmZvLT5EYXRhTGVuZ3RoID4gdmFsdWVEYXRhU2l6ZSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgVFJBQ0UoImluZm8tPk5hbWUgJXMgaW5mby0+RGF0YUxlbmd0aCAlbGRcbiIsIGRlYnVnc3RyX3coaW5mby0+TmFtZSksIGluZm8tPkRhdGFMZW5ndGgpOwoKICAgIG1lbWNweSggc3pWYWx1ZU5hbWUsIGluZm8tPk5hbWUsIGluZm8tPk5hbWVMZW5ndGgpOwogICAgc3pWYWx1ZU5hbWVbaW5mby0+TmFtZUxlbmd0aCAvIHNpemVvZihXQ0hBUildID0gJ1wwJzsKICAgIG1lbWNweSggc3pWYWx1ZURhdGEsIGJ1ZmZlciArIGluZm8tPkRhdGFPZmZzZXQsIGluZm8tPkRhdGFMZW5ndGggKTsKICAgIHN6VmFsdWVEYXRhW2luZm8tPkRhdGFMZW5ndGggLyBzaXplb2YoV0NIQVIpXSA9ICdcMCc7CgogICAgVFJBQ0UoInJldHVybmluZyAlcyAlc1xuIiwgZGVidWdzdHJfdyhzelZhbHVlTmFtZSksIGRlYnVnc3RyX3coc3pWYWx1ZURhdGEpKTsKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBOTFNfUmVnR2V0RHdvcmQoSEtFWSBoS2V5LCBMUENXU1RSIHN6VmFsdWVOYW1lLCBEV09SRCAqbHBWYWwpCnsKICAgIEJZVEUgYnVmZmVyWzEyOF07CiAgICBjb25zdCBLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqaW5mbyA9IChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKWJ1ZmZlcjsKICAgIERXT1JEIGR3U2l6ZSA9IHNpemVvZihidWZmZXIpOwogICAgVU5JQ09ERV9TVFJJTkcgdmFsdWVOYW1lOwoKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmdmFsdWVOYW1lLCBzelZhbHVlTmFtZSApOwoKICAgIFRSQUNFKCIlcCwgJXNcbiIsIGhLZXksIGRlYnVnc3RyX3coc3pWYWx1ZU5hbWUpKTsKICAgIGlmIChOdFF1ZXJ5VmFsdWVLZXkoIGhLZXksICZ2YWx1ZU5hbWUsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLCBkd1NpemUsICZkd1NpemUgKSA9PSBTVEFUVVNfU1VDQ0VTUyAmJgogICAgICAgIGluZm8tPkRhdGFMZW5ndGggPT0gc2l6ZW9mKERXT1JEKSkKICAgIHsKICAgICAgICBtZW1jcHkobHBWYWwsIGluZm8tPkRhdGEsIHNpemVvZihEV09SRCkpOwogICAgICAgIHJldHVybiBUUlVFOwogICAgfQoKICAgIHJldHVybiBGQUxTRTsKfQoKc3RhdGljIEJPT0wgTkxTX0dldExhbmd1YWdlR3JvdXBOYW1lKExHUlBJRCBsZ3JwaWQsIExQV1NUUiBzek5hbWUsIFVMT05HIG5hbWVTaXplKQp7CiAgICBITU9EVUxFIGhNb2R1bGUgPSBHZXRNb2R1bGVIYW5kbGVXKGtlcm5lbDMyVyk7CiAgICBMQU5HSUQgIGxhbmdJZDsKICAgIExQQ1dTVFIgc3pSZXNvdXJjZU5hbWUgPSAoTFBDV1NUUikoKChsZ3JwaWQgKyAweDIwMDApID4+IDQpICsgMSk7CiAgICBIUlNSQyAgIGhSZXNvdXJjZTsKICAgIEJPT0wgICAgYlJldCA9IEZBTFNFOwoKICAgIC8qIEZJWE1FOiBJcyBpdCBjb3JyZWN0IHRvIHVzZSB0aGUgc3lzdGVtIGRlZmF1bHQgbGFuZ2lkPyAqLwogICAgbGFuZ0lkID0gR2V0U3lzdGVtRGVmYXVsdExhbmdJRCgpOwoKICAgIGlmIChTVUJMQU5HSUQobGFuZ0lkKSA9PSBTVUJMQU5HX05FVVRSQUwpCiAgICAgICAgbGFuZ0lkID0gTUFLRUxBTkdJRCggUFJJTUFSWUxBTkdJRChsYW5nSWQpLCBTVUJMQU5HX0RFRkFVTFQgKTsKCiAgICBoUmVzb3VyY2UgPSBGaW5kUmVzb3VyY2VFeFcoIGhNb2R1bGUsIChMUFdTVFIpUlRfU1RSSU5HLCBzelJlc291cmNlTmFtZSwgbGFuZ0lkICk7CgogICAgaWYgKGhSZXNvdXJjZSkKICAgIHsKICAgICAgICBIR0xPQkFMIGhSZXNEaXIgPSBMb2FkUmVzb3VyY2UoIGhNb2R1bGUsIGhSZXNvdXJjZSApOwoKICAgICAgICBpZiAoaFJlc0RpcikKICAgICAgICB7CiAgICAgICAgICAgIFVMT05HICAgaVJlc291cmNlSW5kZXggPSBsZ3JwaWQgJiAweGY7CiAgICAgICAgICAgIExQQ1dTVFIgbHBSZXNFbnRyeSA9IExvY2tSZXNvdXJjZSggaFJlc0RpciApOwogICAgICAgICAgICBVTE9ORyAgIGk7CgogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgaVJlc291cmNlSW5kZXg7IGkrKykKICAgICAgICAgICAgICAgIGxwUmVzRW50cnkgKz0gKmxwUmVzRW50cnkgKyAxOwoKICAgICAgICAgICAgaWYgKCpscFJlc0VudHJ5IDwgbmFtZVNpemUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG1lbWNweSggc3pOYW1lLCBscFJlc0VudHJ5ICsgMSwgKmxwUmVzRW50cnkgKiBzaXplb2YoV0NIQVIpICk7CiAgICAgICAgICAgICAgICBzek5hbWVbKmxwUmVzRW50cnldID0gJ1wwJzsKICAgICAgICAgICAgICAgIGJSZXQgPSBUUlVFOwogICAgICAgICAgICB9CgogICAgICAgIH0KICAgICAgICBGcmVlUmVzb3VyY2UoIGhSZXNvdXJjZSApOwogICAgfQogICAgcmV0dXJuIGJSZXQ7Cn0KCi8qIFJlZ2lzdHJ5IGtleXMgZm9yIE5MUyByZWxhdGVkIGluZm9ybWF0aW9uICovCnN0YXRpYyBjb25zdCBXQ0hBUiBzek5sc0tleU5hbWVbXSA9IHsKICAgICdNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLCdTJywneScsJ3MnLCd0JywnZScsJ20nLCdcXCcsCiAgICAnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ0MnLCdvJywnbicsJ3QnLCdyJywnbycsJ2wnLCdTJywnZScsJ3QnLCdcXCcsCiAgICAnQycsJ28nLCduJywndCcsJ3InLCdvJywnbCcsJ1xcJywnTicsJ2wnLCdzJywnXDAnCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pMYW5nR3JvdXBzS2V5TmFtZVtdID0gewogICAgJ0wnLCdhJywnbicsJ2cnLCd1JywnYScsJ2cnLCdlJywnICcsJ0cnLCdyJywnbycsJ3UnLCdwJywncycsJ1wwJwp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6Q291bnRyeUxpc3ROYW1lW10gPSB7CiAgICAnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXFwnLAogICAgJ1QnLCdlJywnbCcsJ2UnLCdwJywnaCcsJ28nLCduJywneScsJ1xcJywKICAgICdDJywnbycsJ3UnLCduJywndCcsJ3InLCd5JywnICcsJ0wnLCdpJywncycsJ3QnLCdcMCcKfTsKCgovKiBDYWxsYmFjayBmdW5jdGlvbiBwdHJzIGZvciBFbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHNBL1cgKi8KdHlwZWRlZiBzdHJ1Y3QKewogIExBTkdVQUdFR1JPVVBfRU5VTVBST0NBIHByb2NBOwogIExBTkdVQUdFR1JPVVBfRU5VTVBST0NXIHByb2NXOwogIERXT1JEICAgIGR3RmxhZ3M7CiAgTE9OR19QVFIgbFBhcmFtOwp9IEVOVU1MQU5HVUFHRUdST1VQX0NBTExCQUNLUzsKCi8qIEludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc0EvVyAqLwpzdGF0aWMgQk9PTCBOTFNfRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzKEVOVU1MQU5HVUFHRUdST1VQX0NBTExCQUNLUyAqbHBQcm9jcykKewogICAgV0NIQVIgc3pOdW1iZXJbMTBdLCBzelZhbHVlWzRdOwogICAgSEtFWSBoS2V5OwogICAgQk9PTCBiQ29udGludWUgPSBUUlVFOwogICAgVUxPTkcgdWxJbmRleCA9IDA7CgogICAgaWYgKCFscFByb2NzKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHN3aXRjaCAobHBQcm9jcy0+ZHdGbGFncykKICAgIHsKICAgIGNhc2UgMDoKICAgICAgICAvKiBEZWZhdWx0IHRvIExHUlBJRF9JTlNUQUxMRUQgKi8KICAgICAgICBscFByb2NzLT5kd0ZsYWdzID0gTEdSUElEX0lOU1RBTExFRDsKICAgICAgICAvKiBGYWxsIHRocm91Z2guLi4gKi8KICAgIGNhc2UgTEdSUElEX0lOU1RBTExFRDoKICAgIGNhc2UgTEdSUElEX1NVUFBPUlRFRDoKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBoS2V5ID0gTkxTX1JlZ09wZW5TdWJLZXkoIE5MU19SZWdPcGVuS2V5KCAwLCBzek5sc0tleU5hbWUgKSwgc3pMYW5nR3JvdXBzS2V5TmFtZSApOwoKICAgIGlmICghaEtleSkKICAgICAgV0FSTigiTkxTIHJlZ2lzdHJ5IGtleSBub3QgZm91bmQuIFBsZWFzZSBhcHBseSB0aGUgZGVmYXVsdCByZWdpc3RyeSBmaWxlICd3aW5lZGVmYXVsdC5yZWcnXG4iKTsKCiAgICB3aGlsZSAoYkNvbnRpbnVlKQogICAgewogICAgICAgIGlmIChOTFNfUmVnRW51bVZhbHVlKCBoS2V5LCB1bEluZGV4LCBzek51bWJlciwgc2l6ZW9mKHN6TnVtYmVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3pWYWx1ZSwgc2l6ZW9mKHN6VmFsdWUpICkpCiAgICAgICAgewogICAgICAgICAgICBCT09MIGJJbnN0YWxsZWQgPSBzelZhbHVlWzBdID09ICcxJyA/IFRSVUUgOiBGQUxTRTsKICAgICAgICAgICAgTEdSUElEIGxncnBpZCA9IHN0cnRvdWxXKCBzek51bWJlciwgTlVMTCwgMTYgKTsKCiAgICAgICAgICAgIFRSQUNFKCJncnBpZCAlcyAoJXNpbnN0YWxsZWQpXG4iLCBkZWJ1Z3N0cl93KHN6TnVtYmVyKSwKICAgICAgICAgICAgICAgICAgIGJJbnN0YWxsZWQgPyAiIiA6ICJub3QgIik7CgogICAgICAgICAgICBpZiAobHBQcm9jcy0+ZHdGbGFncyA9PSBMR1JQSURfU1VQUE9SVEVEIHx8IGJJbnN0YWxsZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDSEFSIHN6R3JwTmFtZVs0OF07CgogICAgICAgICAgICAgICAgaWYgKCFOTFNfR2V0TGFuZ3VhZ2VHcm91cE5hbWUoIGxncnBpZCwgc3pHcnBOYW1lLCBzaXplb2Yoc3pHcnBOYW1lKSAvIHNpemVvZihXQ0hBUikgKSkKICAgICAgICAgICAgICAgICAgICBzekdycE5hbWVbMF0gPSAnXDAnOwoKICAgICAgICAgICAgICAgIGlmIChscFByb2NzLT5wcm9jVykKICAgICAgICAgICAgICAgICAgICBiQ29udGludWUgPSBscFByb2NzLT5wcm9jVyggbGdycGlkLCBzek51bWJlciwgc3pHcnBOYW1lLCBscFByb2NzLT5kd0ZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscFByb2NzLT5sUGFyYW0gKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjaGFyIHN6TnVtYmVyQVtzaXplb2Yoc3pOdW1iZXIpL3NpemVvZihXQ0hBUildOwogICAgICAgICAgICAgICAgICAgIGNoYXIgc3pHcnBOYW1lQVs0OF07CgogICAgICAgICAgICAgICAgICAgIC8qIEZJWE1FOiBNU0ROIGRvZXNuJ3Qgc2F5IHdoaWNoIGNvZGUgcGFnZSB0aGUgVy0+QSB0cmFuc2xhdGlvbiB1c2VzLAogICAgICAgICAgICAgICAgICAgICAqICAgICAgICBvciB3aGV0aGVyIHRoZSBsYW5ndWFnZSBuYW1lcyBhcmUgZXZlciBsb2NhbGlzZWQuIEFzc3VtZSBDUF9BQ1AuCiAgICAgICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBzek51bWJlciwgLTEsIHN6TnVtYmVyQSwgc2l6ZW9mKHN6TnVtYmVyQSksIDAsIDApOwogICAgICAgICAgICAgICAgICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBzekdycE5hbWUsIC0xLCBzekdycE5hbWVBLCBzaXplb2Yoc3pHcnBOYW1lQSksIDAsIDApOwoKICAgICAgICAgICAgICAgICAgICBiQ29udGludWUgPSBscFByb2NzLT5wcm9jQSggbGdycGlkLCBzek51bWJlckEsIHN6R3JwTmFtZUEsIGxwUHJvY3MtPmR3RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwUHJvY3MtPmxQYXJhbSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB1bEluZGV4Kys7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgICAgYkNvbnRpbnVlID0gRkFMU0U7CgogICAgICAgIGlmICghYkNvbnRpbnVlKQogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAoaEtleSkKICAgICAgICBOdENsb3NlKCBoS2V5ICk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc0EgICAgKEtFUk5FTDMyLkApCiAqCiAqIENhbGwgYSB1c2VycyBmdW5jdGlvbiBmb3IgZWFjaCBsYW5ndWFnZSBncm91cCBhdmFpbGFibGUgb24gdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBwTGFuZ0dycEVudW1Qcm9jIFtJXSBDYWxsYmFjayBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGxhbmd1YWdlIGdyb3VwCiAqICBkd0ZsYWdzICAgICAgICAgIFtJXSBMR1JQSURfU1VQUE9SVEVEPUFsbCBTdXBwb3J0ZWQsIExHUlBJRF9JTlNUQUxMRUQ9SW5zdGFsbGVkIG9ubHkKICogIGxQYXJhbSAgICAgICAgICAgW0ldIFVzZXIgcGFyYW1ldGVyIHRvIHBhc3MgdG8gcExhbmdHcnBFbnVtUHJvYwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzQShMQU5HVUFHRUdST1VQX0VOVU1QUk9DQSBwTGFuZ0dycEVudW1Qcm9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3RmxhZ3MsIExPTkdfUFRSIGxQYXJhbSkKewogICAgRU5VTUxBTkdVQUdFR1JPVVBfQ0FMTEJBQ0tTIHByb2NzOwoKICAgIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYKVxuIiwgcExhbmdHcnBFbnVtUHJvYywgZHdGbGFncywgbFBhcmFtKTsKCiAgICBwcm9jcy5wcm9jQSA9IHBMYW5nR3JwRW51bVByb2M7CiAgICBwcm9jcy5wcm9jVyA9IE5VTEw7CiAgICBwcm9jcy5kd0ZsYWdzID0gZHdGbGFnczsKICAgIHByb2NzLmxQYXJhbSA9IGxQYXJhbTsKCiAgICByZXR1cm4gTkxTX0VudW1TeXN0ZW1MYW5ndWFnZUdyb3VwcyggcExhbmdHcnBFbnVtUHJvYyA/ICZwcm9jcyA6IE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHNXICAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzQS4KICovCkJPT0wgV0lOQVBJIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc1coTEFOR1VBR0VHUk9VUF9FTlVNUFJPQ1cgcExhbmdHcnBFbnVtUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd0ZsYWdzLCBMT05HX1BUUiBsUGFyYW0pCnsKICAgIEVOVU1MQU5HVUFHRUdST1VQX0NBTExCQUNLUyBwcm9jczsKCiAgICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWClcbiIsIHBMYW5nR3JwRW51bVByb2MsIGR3RmxhZ3MsIGxQYXJhbSk7CgogICAgcHJvY3MucHJvY0EgPSBOVUxMOwogICAgcHJvY3MucHJvY1cgPSBwTGFuZ0dycEVudW1Qcm9jOwogICAgcHJvY3MuZHdGbGFncyA9IGR3RmxhZ3M7CiAgICBwcm9jcy5sUGFyYW0gPSBsUGFyYW07CgogICAgcmV0dXJuIE5MU19FbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHMoIHBMYW5nR3JwRW51bVByb2MgPyAmcHJvY3MgOiBOVUxMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSXNWYWxpZExhbmd1YWdlR3JvdXAgICAgKEtFUk5FTDMyLkApCiAqCiAqIERldGVybWluZSBpZiBhIGxhbmd1YWdlIGdyb3VwIGlzIHN1cHBvcnRlZCBhbmQvb3IgaW5zdGFsbGVkLgogKgogKiBQQVJBTVMKICogIGxncnBpZCAgW0ldIExhbmd1YWdlIEdyb3VwIElkIChMR1JQSURfIHZhbHVlcyBmcm9tICJ3aW5ubHMuaCIpCiAqICBkd0ZsYWdzIFtJXSBMR1JQSURfU1VQUE9SVEVEPVN1cHBvcnRlZCwgTEdSUElEX0lOU1RBTExFRD1JbnN0YWxsZWQKICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgbGdycGlkIGlzIHN1cHBvcnRlZCBhbmQvb3IgaW5zdGFsbGVkLCBhY2NvcmRpbmcgdG8gZHdGbGFncy4KICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzVmFsaWRMYW5ndWFnZUdyb3VwKExHUlBJRCBsZ3JwaWQsIERXT1JEIGR3RmxhZ3MpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzekZvcm1hdFtdID0geyAnJScsJ3gnLCdcMCcgfTsKICAgIFdDSEFSIHN6VmFsdWVOYW1lWzE2XSwgc3pWYWx1ZVsyXTsKICAgIEJPT0wgYlN1cHBvcnRlZCA9IEZBTFNFLCBiSW5zdGFsbGVkID0gRkFMU0U7CiAgICBIS0VZIGhLZXk7CgoKICAgIHN3aXRjaCAoZHdGbGFncykKICAgIHsKICAgIGNhc2UgTEdSUElEX0lOU1RBTExFRDoKICAgIGNhc2UgTEdSUElEX1NVUFBPUlRFRDoKCiAgICAgICAgaEtleSA9IE5MU19SZWdPcGVuU3ViS2V5KCBOTFNfUmVnT3BlbktleSggMCwgc3pObHNLZXlOYW1lICksIHN6TGFuZ0dyb3Vwc0tleU5hbWUgKTsKCiAgICAgICAgc3ByaW50ZlcoIHN6VmFsdWVOYW1lLCBzekZvcm1hdCwgbGdycGlkICk7CgogICAgICAgIGlmIChOTFNfUmVnR2V0RHdvcmQoIGhLZXksIHN6VmFsdWVOYW1lLCAoTFBEV09SRCkmc3pWYWx1ZSApKQogICAgICAgIHsKICAgICAgICAgICAgYlN1cHBvcnRlZCA9IFRSVUU7CgogICAgICAgICAgICBpZiAoc3pWYWx1ZVswXSA9PSAnMScpCiAgICAgICAgICAgICAgICBiSW5zdGFsbGVkID0gVFJVRTsKICAgICAgICB9CgogICAgICAgIGlmIChoS2V5KQogICAgICAgICAgICBOdENsb3NlKCBoS2V5ICk7CgogICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmICgoZHdGbGFncyA9PSBMR1JQSURfU1VQUE9SVEVEICYmIGJTdXBwb3J0ZWQpIHx8CiAgICAgICAgKGR3RmxhZ3MgPT0gTEdSUElEX0lOU1RBTExFRCAmJiBiSW5zdGFsbGVkKSkKICAgICAgICByZXR1cm4gVFJVRTsKCiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qIENhbGxiYWNrIGZ1bmN0aW9uIHB0cnMgZm9yIEVudW1MYW5ndWFnZUdyb3VwbG9jYWxlc0EvVyAqLwp0eXBlZGVmIHN0cnVjdAp7CiAgTEFOR0dST1VQTE9DQUxFX0VOVU1QUk9DQSBwcm9jQTsKICBMQU5HR1JPVVBMT0NBTEVfRU5VTVBST0NXIHByb2NXOwogIERXT1JEICAgIGR3RmxhZ3M7CiAgTEdSUElEICAgbGdycGlkOwogIExPTkdfUFRSIGxQYXJhbTsKfSBFTlVNTEFOR1VBR0VHUk9VUExPQ0FMRV9DQUxMQkFDS1M7CgovKiBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBvZiBFbnVtTGFuZ3VhZ2VHcm91cGxvY2FsZXNBL1cgKi8Kc3RhdGljIEJPT0wgTkxTX0VudW1MYW5ndWFnZUdyb3VwTG9jYWxlcyhFTlVNTEFOR1VBR0VHUk9VUExPQ0FMRV9DQUxMQkFDS1MgKmxwUHJvY3MpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzekxvY2FsZUtleU5hbWVbXSA9IHsKICAgICAgJ0wnLCdvJywnYycsJ2EnLCdsJywnZScsJ1wwJwogICAgfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzekFsdGVybmF0ZVNvcnRzS2V5TmFtZVtdID0gewogICAgICAnQScsJ2wnLCd0JywnZScsJ3InLCduJywnYScsJ3QnLCdlJywnICcsJ1MnLCdvJywncicsJ3QnLCdzJywnXDAnCiAgICB9OwogICAgV0NIQVIgc3pOdW1iZXJbMTBdLCBzelZhbHVlWzRdOwogICAgSEtFWSBoS2V5OwogICAgQk9PTCBiQ29udGludWUgPSBUUlVFLCBiQWx0ZXJuYXRlID0gRkFMU0U7CiAgICBMR1JQSUQgbGdycGlkOwogICAgVUxPTkcgdWxJbmRleCA9IDE7ICAvKiBJZ25vcmUgZGVmYXVsdCBlbnRyeSBvZiAxc3Qga2V5ICovCgogICAgaWYgKCFscFByb2NzIHx8ICFscFByb2NzLT5sZ3JwaWQgfHwgbHBQcm9jcy0+bGdycGlkID4gTEdSUElEX0FSTUVOSUFOKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChscFByb2NzLT5kd0ZsYWdzKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaEtleSA9IE5MU19SZWdPcGVuU3ViS2V5KCBOTFNfUmVnT3BlbktleSggMCwgc3pObHNLZXlOYW1lICksIHN6TG9jYWxlS2V5TmFtZSApOwoKICAgIGlmICghaEtleSkKICAgICAgV0FSTigiTkxTIHJlZ2lzdHJ5IGtleSBub3QgZm91bmQuIFBsZWFzZSBhcHBseSB0aGUgZGVmYXVsdCByZWdpc3RyeSBmaWxlICd3aW5lZGVmYXVsdC5yZWcnXG4iKTsKCiAgICB3aGlsZSAoYkNvbnRpbnVlKQogICAgewogICAgICAgIGlmIChOTFNfUmVnRW51bVZhbHVlKCBoS2V5LCB1bEluZGV4LCBzek51bWJlciwgc2l6ZW9mKHN6TnVtYmVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3pWYWx1ZSwgc2l6ZW9mKHN6VmFsdWUpICkpCiAgICAgICAgewogICAgICAgICAgICBsZ3JwaWQgPSBzdHJ0b3VsVyggc3pWYWx1ZSwgTlVMTCwgMTYgKTsKCiAgICAgICAgICAgIFRSQUNFKCJsY2lkICVzLCBncnBpZCAlbGQgKCVzbWF0Y2hlZClcbiIsIGRlYnVnc3RyX3coc3pOdW1iZXIpLAogICAgICAgICAgICAgICAgICAgbGdycGlkLCBsZ3JwaWQgPT0gbHBQcm9jcy0+bGdycGlkID8gIiIgOiAibm90ICIpOwoKICAgICAgICAgICAgaWYgKGxncnBpZCA9PSBscFByb2NzLT5sZ3JwaWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIExDSUQgbGNpZDsKCiAgICAgICAgICAgICAgICBsY2lkID0gc3RydG91bFcoIHN6TnVtYmVyLCBOVUxMLCAxNiApOwoKICAgICAgICAgICAgICAgIC8qIEZJWE1FOiBuYXRpdmUgcmV0dXJucyBleHRyYSB0ZXh0IGZvciBhIGZldyAoMTcvMTUwKSBsb2NhbGVzLCBlLmc6CiAgICAgICAgICAgICAgICAgKiAnMDAwMDA0MzcgICAgICAgICAgO0dlb3JnaWFuJwogICAgICAgICAgICAgICAgICogQXQgcHJlc2VudCB3ZSBvbmx5IHBhc3MgdGhlIExDSUQgc3RyaW5nLgogICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgaWYgKGxwUHJvY3MtPnByb2NXKQogICAgICAgICAgICAgICAgICAgIGJDb250aW51ZSA9IGxwUHJvY3MtPnByb2NXKCBsZ3JwaWQsIGxjaWQsIHN6TnVtYmVyLCBscFByb2NzLT5sUGFyYW0gKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjaGFyIHN6TnVtYmVyQVtzaXplb2Yoc3pOdW1iZXIpL3NpemVvZihXQ0hBUildOwoKICAgICAgICAgICAgICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3pOdW1iZXIsIC0xLCBzek51bWJlckEsIHNpemVvZihzek51bWJlckEpLCAwLCAwKTsKCiAgICAgICAgICAgICAgICAgICAgYkNvbnRpbnVlID0gbHBQcm9jcy0+cHJvY0EoIGxncnBpZCwgbGNpZCwgc3pOdW1iZXJBLCBscFByb2NzLT5sUGFyYW0gKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdWxJbmRleCsrOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBGaW5pc2hlZCBlbnVtZXJhdGluZyB0aGlzIGtleSAqLwogICAgICAgICAgICBpZiAoIWJBbHRlcm5hdGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEVudW1lcmF0ZSBhbHRlcm5hdGUgc29ydHMgYWxzbyAqLwogICAgICAgICAgICAgICAgaEtleSA9IE5MU19SZWdPcGVuS2V5KCBoS2V5LCBzekFsdGVybmF0ZVNvcnRzS2V5TmFtZSApOwogICAgICAgICAgICAgICAgYkFsdGVybmF0ZSA9IFRSVUU7CiAgICAgICAgICAgICAgICB1bEluZGV4ID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBiQ29udGludWUgPSBGQUxTRTsgLyogRmluaXNoZWQgYm90aCBrZXlzICovCiAgICAgICAgfQoKICAgICAgICBpZiAoIWJDb250aW51ZSkKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKGhLZXkpCiAgICAgICAgTnRDbG9zZSggaEtleSApOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXNBICAgIChLRVJORUwzMi5AKQogKgogKiBDYWxsIGEgdXNlcnMgZnVuY3Rpb24gZm9yIGV2ZXJ5IGxvY2FsZSBpbiBhIGxhbmd1YWdlIGdyb3VwIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIHBMYW5nR3JwTGNFbnVtUHJvYyBbSV0gQ2FsbGJhY2sgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBsb2NhbGUKICogIGxncnBpZCAgICAgICAgICAgICBbSV0gTGFuZ3VhZ2UgZ3JvdXAgKExHUlBJRF8gdmFsdWVzIGZyb20gIndpbm5scy5oIikKICogIGR3RmxhZ3MgICAgICAgICAgICBbSV0gUmVzZXJ2ZWQsIHNldCB0byAwCiAqICBsUGFyYW0gICAgICAgICAgICAgW0ldIFVzZXIgcGFyYW1ldGVyIHRvIHBhc3MgdG8gcExhbmdHcnBMY0VudW1Qcm9jCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpCT09MIFdJTkFQSSBFbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXNBKExBTkdHUk9VUExPQ0FMRV9FTlVNUFJPQ0EgcExhbmdHcnBMY0VudW1Qcm9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExHUlBJRCBsZ3JwaWQsIERXT1JEIGR3RmxhZ3MsIExPTkdfUFRSIGxQYXJhbSkKewogICAgRU5VTUxBTkdVQUdFR1JPVVBMT0NBTEVfQ0FMTEJBQ0tTIGNhbGxiYWNrczsKCiAgICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWCwweCUwOGxYKVxuIiwgcExhbmdHcnBMY0VudW1Qcm9jLCBsZ3JwaWQsIGR3RmxhZ3MsIGxQYXJhbSk7CgogICAgY2FsbGJhY2tzLnByb2NBICAgPSBwTGFuZ0dycExjRW51bVByb2M7CiAgICBjYWxsYmFja3MucHJvY1cgICA9IE5VTEw7CiAgICBjYWxsYmFja3MuZHdGbGFncyA9IGR3RmxhZ3M7CiAgICBjYWxsYmFja3MubGdycGlkICA9IGxncnBpZDsKICAgIGNhbGxiYWNrcy5sUGFyYW0gID0gbFBhcmFtOwoKICAgIHJldHVybiBOTFNfRW51bUxhbmd1YWdlR3JvdXBMb2NhbGVzKCBwTGFuZ0dycExjRW51bVByb2MgPyAmY2FsbGJhY2tzIDogTlVMTCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXNXICAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgRW51bUxhbmd1YWdlR3JvdXBMb2NhbGVzQS4KICovCkJPT0wgV0lOQVBJIEVudW1MYW5ndWFnZUdyb3VwTG9jYWxlc1coTEFOR0dST1VQTE9DQUxFX0VOVU1QUk9DVyBwTGFuZ0dycExjRW51bVByb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTEdSUElEIGxncnBpZCwgRFdPUkQgZHdGbGFncywgTE9OR19QVFIgbFBhcmFtKQp7CiAgICBFTlVNTEFOR1VBR0VHUk9VUExPQ0FMRV9DQUxMQkFDS1MgY2FsbGJhY2tzOwoKICAgIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYLDB4JTA4bFgpXG4iLCBwTGFuZ0dycExjRW51bVByb2MsIGxncnBpZCwgZHdGbGFncywgbFBhcmFtKTsKCiAgICBjYWxsYmFja3MucHJvY0EgICA9IE5VTEw7CiAgICBjYWxsYmFja3MucHJvY1cgICA9IHBMYW5nR3JwTGNFbnVtUHJvYzsKICAgIGNhbGxiYWNrcy5kd0ZsYWdzID0gZHdGbGFnczsKICAgIGNhbGxiYWNrcy5sZ3JwaWQgID0gbGdycGlkOwogICAgY2FsbGJhY2tzLmxQYXJhbSAgPSBsUGFyYW07CgogICAgcmV0dXJuIE5MU19FbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXMoIHBMYW5nR3JwTGNFbnVtUHJvYyA/ICZjYWxsYmFja3MgOiBOVUxMICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEVudW1TeXN0ZW1HZW9JRCAgICAoS0VSTkVMMzIuQCkKICoKICogQ2FsbCBhIHVzZXJzIGZ1bmN0aW9uIGZvciBldmVyeSBsb2NhdGlvbiBhdmFpbGFibGUgb24gdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBnZW9jbGFzcyAgICAgW0ldIFR5cGUgb2YgaW5mb3JtYXRpb24gZGVzaXJlZCAoU1lTR0VPVFlQRSBlbnVtIGZyb20gIndpbm5scy5oIikKICogIHJlc2VydmVkICAgICBbSV0gUmVzZXJ2ZWQsIHNldCB0byAwCiAqICBwR2VvRW51bVByb2MgW0ldIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggbG9jYXRpb24KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCkJPT0wgV0lOQVBJIEVudW1TeXN0ZW1HZW9JRChHRU9DTEFTUyBnZW9jbGFzcywgR0VPSUQgcmVzZXJ2ZWQsIEdFT19FTlVNUFJPQyBwR2VvRW51bVByb2MpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzekNvdW50cnlDb2RlVmFsdWVOYW1lW10gPSB7CiAgICAgICdDJywnbycsJ3UnLCduJywndCcsJ3InLCd5JywnQycsJ28nLCdkJywnZScsJ1wwJwogICAgfTsKICAgIFdDSEFSIHN6TnVtYmVyWzEwXTsKICAgIEhLRVkgaEtleTsKICAgIFVMT05HIHVsSW5kZXggPSAwOwoKICAgIFRSQUNFKCIoMHglMDhsWCwweCUwOGxYLCVwKVxuIiwgZ2VvY2xhc3MsIHJlc2VydmVkLCBwR2VvRW51bVByb2MpOwoKICAgIGlmIChnZW9jbGFzcyAhPSBHRU9DTEFTU19OQVRJT04gfHwgcmVzZXJ2ZWQgfHwgIXBHZW9FbnVtUHJvYykKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBoS2V5ID0gTkxTX1JlZ09wZW5LZXkoIDAsIHN6Q291bnRyeUxpc3ROYW1lICk7CgogICAgd2hpbGUgKE5MU19SZWdFbnVtU3ViS2V5KCBoS2V5LCB1bEluZGV4LCBzek51bWJlciwgc2l6ZW9mKHN6TnVtYmVyKSApKQogICAgewogICAgICAgIEJPT0wgYkNvbnRpbnVlID0gVFJVRTsKICAgICAgICBEV09SRCBkd0dlb0lkOwogICAgICAgIEhLRVkgaFN1YktleSA9IE5MU19SZWdPcGVuS2V5KCBoS2V5LCBzek51bWJlciApOwoKICAgICAgICBpZiAoaFN1YktleSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChOTFNfUmVnR2V0RHdvcmQoIGhTdWJLZXksIHN6Q291bnRyeUNvZGVWYWx1ZU5hbWUsICZkd0dlb0lkICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJHb3QgZ2VvaWQgJWxkXG4iLCBkd0dlb0lkKTsKCiAgICAgICAgICAgICAgICBpZiAoIXBHZW9FbnVtUHJvYyggZHdHZW9JZCApKQogICAgICAgICAgICAgICAgICAgIGJDb250aW51ZSA9IEZBTFNFOwogICAgICAgICAgICB9CgogICAgICAgICAgICBOdENsb3NlKCBoU3ViS2V5ICk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWJDb250aW51ZSkKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIHVsSW5kZXgrKzsKICAgIH0KCiAgICBpZiAoaEtleSkKICAgICAgICBOdENsb3NlKCBoS2V5ICk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEludmFsaWRhdGVOTFNDYWNoZSAgICAgICAgICAgKEtFUk5FTDMyLkApCiAqCiAqIEludmFsaWRhdGUgdGhlIGNhY2hlIG9mIE5MUyB2YWx1ZXMuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLgogKi8KQk9PTCBXSU5BUEkgSW52YWxpZGF0ZU5MU0NhY2hlKHZvaWQpCnsKICBGSVhNRSgiKCkgc3R1YlxuIik7CiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRVc2VyR2VvSUQgKEtFUk5FTDMyLkApCiAqLwpHRU9JRCBXSU5BUEkgR2V0VXNlckdlb0lEKCBHRU9DTEFTUyBHZW9DbGFzcyApCnsKICAgIEZJWE1FKCIlbGRcbiIsR2VvQ2xhc3MpOwogICAgcmV0dXJuIEdFT0lEX05PVF9BVkFJTEFCTEU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFNldFVzZXJHZW9JRCAoS0VSTkVMMzIuQCkKICovCkJPT0wgV0lOQVBJIFNldFVzZXJHZW9JRCggR0VPSUQgR2VvSUQgKQp7CiAgICBGSVhNRSgiJWxkXG4iLEdlb0lEKTsKICAgIHJldHVybiBGQUxTRTsKfQo=