LyoKICogVGhlIHBhcmFtZXRlcnMgb2YgbWFueSBmdW5jdGlvbnMgY2hhbmdlcyBiZXR3ZWVuIGRpZmZlcmVudCBPUyB2ZXJzaW9ucwogKiAoTlQgdXNlcyBVbmljb2RlIHN0cmluZ3MsIDk1IHVzZXMgQVNDSUkgc3RyaW5ncykKICogCiAqIENvcHlyaWdodCAxOTk3IE1hcmN1cyBNZWlzc25lcgogKiAgICAgICAgICAgMTk5OCBK/HJnZW4gU2NobWllZAogKi8KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2ludmVyc2lvbi5oIgojaW5jbHVkZSAiaGVhcC5oIgoKI2luY2x1ZGUgInNoZWxsYXBpLmgiCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNoZWxsMzJfbWFpbi5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKHNoZWxsKQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hDaGFuZ2VOb3RpZnlSZWdpc3RlcgkJCVtTSEVMTDMyLjJdCiAqCiAqIE5PVEVTCiAqICAgSWRsaXN0IGlzIGFuIGFycmF5IG9mIHN0cnVjdHVyZXMgYW5kIENvdW50IHNwZWNpZmllcyBob3cgbWFueSBpdGVtcyBpbiB0aGUgYXJyYXkKICogICAodXN1YWxseSBqdXN0IG9uZSBJIHRoaW5rKS4KICovCkRXT1JEIFdJTkFQSQpTSENoYW5nZU5vdGlmeVJlZ2lzdGVyKAogICAgSFdORCBod25kLAogICAgTE9ORyBldmVudHMxLAogICAgTE9ORyBldmVudHMyLAogICAgRFdPUkQgbXNnLAogICAgaW50IGNvdW50LAogICAgSURTVFJVQ1QgKmlkbGlzdCkKewlGSVhNRShzaGVsbCwiKDB4JTA0eCwweCUwOGx4LDB4JTA4bHgsMHglMDhseCwweCUwOHgsJXApOnN0dWIuXG4iLAoJCWh3bmQsZXZlbnRzMSxldmVudHMyLG1zZyxjb3VudCxpZGxpc3QpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hDaGFuZ2VOb3RpZnlEZXJlZ2lzdGVyCQkJW1NIRUxMMzIuNF0KICovCkRXT1JEIFdJTkFQSQpTSENoYW5nZU5vdGlmeURlcmVnaXN0ZXIoTE9ORyB4MSkKewlGSVhNRShzaGVsbCwiKDB4JTA4bHgpOnN0dWIuXG4iLHgxKTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE5UU0hDaGFuZ2VOb3RpZnlSZWdpc3RlcgkJCVtTSEVMTDMyLjY0MF0KICogTk9URVMKICogICBJZGxpc3QgaXMgYW4gYXJyYXkgb2Ygc3RydWN0dXJlcyBhbmQgQ291bnQgc3BlY2lmaWVzIGhvdyBtYW55IGl0ZW1zIGluIHRoZSBhcnJheQogKiAgICh1c3VhbGx5IGp1c3Qgb25lIEkgdGhpbmspLgogKi8KRFdPUkQgV0lOQVBJIE5UU0hDaGFuZ2VOb3RpZnlSZWdpc3RlcigKICAgIEhXTkQgaHduZCwKICAgIExPTkcgZXZlbnRzMSwKICAgIExPTkcgZXZlbnRzMiwKICAgIERXT1JEIG1zZywKICAgIGludCBjb3VudCwKICAgIElEU1RSVUNUICppZGxpc3QpCnsJRklYTUUoc2hlbGwsIigweCUwNHgsMHglMDhseCwweCUwOGx4LDB4JTA4bHgsMHglMDh4LCVwKTpzdHViLlxuIiwKCQlod25kLGV2ZW50czEsZXZlbnRzMixtc2csY291bnQsaWRsaXN0KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE5UU0hDaGFuZ2VOb3RpZnlEZXJlZ2lzdGVyCQkJW1NIRUxMMzIuNjQxXQogKi8KRFdPUkQgV0lOQVBJIE5UU0hDaGFuZ2VOb3RpZnlEZXJlZ2lzdGVyKExPTkcgeDEpCnsJRklYTUUoc2hlbGwsIigweCUwOGx4KTpzdHViLlxuIix4MSk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUGFyc2VGaWVsZAkJCQkJW1NIRUxMMzIuNThdCiAqCiAqLwpEV09SRCBXSU5BUEkgUGFyc2VGaWVsZEEoTFBDU1RSIHNyYywgRFdPUkQgZmllbGQsIExQU1RSIGRzdCwgRFdPUkQgbGVuKSAKewlXQVJOKHNoZWxsLCIoJyVzJywweCUwOGx4LCVwLCVsZCkgc2VtaS1zdHViLlxuIixzcmMsZmllbGQsZHN0LGxlbik7CgoJaWYgKCFzcmMgfHwgIXNyY1swXSB8fCAhZHN0IHx8ICFsZW4pCgkgIHJldHVybiAwOwoKCWlmIChmaWVsZCA+MSkKCXsgZmllbGQtLTsJCgkgIHdoaWxlIChmaWVsZCkKCSAgeyBpZiAoKnNyYz09MHgwKSByZXR1cm4gRkFMU0U7CgkgICAgaWYgKCpzcmM9PScsJykgZmllbGQtLTsKCSAgICBzcmMrKzsKCSAgfQoJfQoKCXdoaWxlICgqc3JjIT0weDAwICYmICpzcmMhPScsJyAmJiBsZW4+MCkgCgl7ICpkc3Q9KnNyYzsgZHN0KyssIHNyYysrOyBsZW4tLTsKCX0KCSpkc3Q9MHgwOwoJCglyZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUGlja0ljb25EbGcJCQkJCVtTSEVMTDMyLjYyXQogKiAKICovCkRXT1JEIFdJTkFQSSBQaWNrSWNvbkRsZyhEV09SRCB4LERXT1JEIHksRFdPUkQgeixEV09SRCBhKSAKewlGSVhNRShzaGVsbCwiKCUwOGx4LCUwOGx4LCUwOGx4LCUwOGx4KTpzdHViLlxuIix4LHkseixhKTsKCXJldHVybiAweGZmZmZmZmZmOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBHZXRGaWxlTmFtZUZyb21Ccm93c2UJCQlbU0hFTEwzMi42M10KICogCiAqLwpEV09SRCBXSU5BUEkgR2V0RmlsZU5hbWVGcm9tQnJvd3NlKEhXTkQgaG93bmVyLCBMUFNUUiB0YXJnZXRidWYsIERXT1JEIGxlbiwgRFdPUkQgeCwgTFBDU1RSIHN1ZmZpeCwgTFBDU1RSIHksIExQQ1NUUiBjbWQpIAp7CUZJWE1FKHNoZWxsLCIoJTA0eCwlcCwlbGQsJTA4bHgsJXMsJXMsJXMpOnN0dWIuXG4iLAoJICAgIGhvd25lcix0YXJnZXRidWYsbGVuLHgsc3VmZml4LHksY21kKTsKICAgIC8qIHB1dHMgdXAgYSBPcGVuIERpYWxvZyBhbmQgcmVxdWVzdHMgaW5wdXQgaW50byB0YXJnZXRidWYgKi8KICAgIC8qIE9GTl9ISURFUkVBRE9OTFl8T0ZOX05PQ0hBTkdFRElSfE9GTl9GSUxFTVVTVEVYSVNUfE9GTl91bmtub3duICovCiAgICBsc3RyY3B5QSh0YXJnZXRidWYsIng6XFxkdW1teS5leGUiKTsKICAgIHJldHVybiAxOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEdldFNldHRpbmdzCQkJCVtTSEVMTDMyLjY4XQogKiAKICogTk9URVMKICogIHRoZSByZWdpc3RyeSBwYXRoIGFyZSBmb3Igd2luOTggKHRlc3RlZCkKICogIGFuZCBwb3NzaWJseSBhcmUgdGhlIHNhbWUgaW4gbnQ0MAogKi8Kdm9pZCBXSU5BUEkgU0hHZXRTZXR0aW5ncyhMUFNIRUxMRkxBR1NUQVRFIGxwc2ZzLCBEV09SRCBkd01hc2ssIERXT1JEIGR3eCkKewoJSEtFWQloS2V5OwoJRFdPUkQJZHdEYXRhOwoJRFdPUkQJZHdEYXRhU2l6ZSA9IHNpemVvZiAoRFdPUkQpOwoKCVRSQUNFKHNoZWxsLCIoJXAgMHglMDhseCAweCUwOHgpXG4iLGxwc2ZzLGR3TWFzaywgZHd4KTsKCQoJaWYgKFJlZ0NyZWF0ZUtleUV4QShIS0VZX0NVUlJFTlRfVVNFUiwgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxFeHBsb3JlclxcQWR2YW5jZWQiLAoJCQkJIDAsIDAsIDAsIEtFWV9BTExfQUNDRVNTLCAwLCAmaEtleSwgMCkpCgkgIHJldHVybjsKCQoJaWYgKCAoU1NGX1NIT1dFWFRFTlNJT05TICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiSGlkZUZpbGVFeHQiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZTaG93RXh0ZW5zaW9ucyAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX1NIT1dJTkZPVElQICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiU2hvd0luZm9UaXAiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZTaG93SW5mb1RpcCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX0RPTlRQUkVUVFlQQVRIICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiRG9udFByZXR0eVBhdGgiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZEb250UHJldHR5UGF0aCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX0hJREVJQ09OUyAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIkhpZGVJY29ucyIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+ZkhpZGVJY29ucyAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX01BUE5FVERSVkJVVFRPTiAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIk1hcE5ldERydkJ0biIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+Zk1hcE5ldERydkJ0biAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX1NIT1dBVFRSSUJDT0wgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJTaG93QXR0cmliQ29sIiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgkgIGxwc2ZzLT5mU2hvd0F0dHJpYkNvbCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCgoU1NGX1NIT1dBTExPQkpFQ1RTIHwgU1NGX1NIT1dTWVNGSUxFUykgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJIaWRkZW4iLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCXsgaWYgKGR3RGF0YSA9PSAwKQoJICB7IGlmIChTU0ZfU0hPV0FMTE9CSkVDVFMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd0FsbE9iamVjdHMgID0gMDsKCSAgICBpZiAoU1NGX1NIT1dTWVNGSUxFUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93U3lzRmlsZXMgID0gMDsKCSAgfQoJICBlbHNlIGlmIChkd0RhdGEgPT0gMSkKCSAgeyBpZiAoU1NGX1NIT1dBTExPQkpFQ1RTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dBbGxPYmplY3RzICA9IDE7CgkgICAgaWYgKFNTRl9TSE9XU1lTRklMRVMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd1N5c0ZpbGVzICA9IDA7CgkgIH0KCSAgZWxzZSBpZiAoZHdEYXRhID09IDIpCgkgIHsgaWYgKFNTRl9TSE9XQUxMT0JKRUNUUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93QWxsT2JqZWN0cyAgPSAwOwoJICAgIGlmIChTU0ZfU0hPV1NZU0ZJTEVTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dTeXNGaWxlcyAgPSAxOwoJICB9Cgl9CglSZWdDbG9zZUtleSAoaEtleSk7CgoJVFJBQ0Uoc2hlbGwsIi0tIDB4JTA0eFxuIiwgKihXT1JEKilscHNmcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIU2hlbGxGb2xkZXJWaWV3X01lc3NhZ2UJCQlbU0hFTEwzMi43M10KICoKICogUEFSQU1FVEVSUwogKiAgaHduZENhYmluZXQgZGVmaW5lcyB0aGUgZXhwbG9yZXIgY2FiaW5ldCB3aW5kb3cgdGhhdCBjb250YWlucyB0aGUgCiAqICAgICAgICAgICAgICBzaGVsbHZpZXcgeW91IG5lZWQgdG8gY29tbXVuaWNhdGUgd2l0aAogKiAgdU1zZyAgICAgICAgaWRlbnRpZnlpbmcgdGhlIFNGVk0gZW51bSB0byBwZXJmb3JtCiAqICBsUGFyYW0KICoKICogTk9URVMKICogIE1lc3NhZ2UgU0ZWTV9SRUFSUkFOR0UgPSAxCiAqICAgIFRoaXMgbWVzc2FnZSBnZXRzIHNlbnQgd2hlbiBhIGNvbHVtbiBnZXRzIGNsaWNrZWQgdG8gaW5zdHJ1Y3QgdGhlCiAqICAgIHNoZWxsIHZpZXcgdG8gcmUtc29ydCB0aGUgaXRlbSBsaXN0LiBsUGFyYW0gaWRlbnRpZmllcyB0aGUgY29sdW1uCiAqICAgIHRoYXQgd2FzIGNsaWNrZWQuCiAqLwppbnQgV0lOQVBJIFNIU2hlbGxGb2xkZXJWaWV3X01lc3NhZ2UoSFdORCBod25kQ2FiaW5ldCxVSU5UIHVNc2csTFBBUkFNIGxQYXJhbSkKeyBGSVhNRShzaGVsbCwiJTA0eCAlMDh1eCAlMDhseCBzdHViXG4iLGh3bmRDYWJpbmV0LHVNc2csbFBhcmFtKTsKICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogT2xlU3RyVG9TdHJOCQkJCQlbU0hFTEwzMi43OF0KICovCkJPT0wgV0lOQVBJIE9sZVN0clRvU3RyTiAoTFBTVFIgbHBNdWx0aSwgSU5UIG5NdWx0aSwgTFBDV1NUUiBscFdpZGUsIElOVCBuV2lkZSkgCnsKCVRSQUNFKHNoZWxsLCIlcyAleCAlcyAleFxuIiwgbHBNdWx0aSwgbk11bHRpLCBkZWJ1Z3N0cl93KGxwV2lkZSksIG5XaWRlKTsKCXJldHVybiBXaWRlQ2hhclRvTXVsdGlCeXRlICgwLCAwLCBscFdpZGUsIG5XaWRlLCBscE11bHRpLCBuTXVsdGksIE5VTEwsIE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTdHJUb09sZVN0ck4JCQkJCVtTSEVMTDMyLjc5XQogKi8KQk9PTCBXSU5BUEkgU3RyVG9PbGVTdHJOIChMUFdTVFIgbHBXaWRlLCBJTlQgbldpZGUsIExQQ1NUUiBscE11bHRpLCBJTlQgbk11bHRpKSAKewoJVFJBQ0Uoc2hlbGwsIiVzICV4ICVzICV4XG4iLCBkZWJ1Z3N0cl93KGxwV2lkZSksIG5XaWRlLCBscE11bHRpLCBuTXVsdGkpOwoJcmV0dXJuIE11bHRpQnl0ZVRvV2lkZUNoYXIgKDAsIDAsIGxwTXVsdGksIG5NdWx0aSwgbHBXaWRlLCBuV2lkZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ2lzdGVyU2hlbGxIb29rCQkJCVtTSEVMTDMyLjE4MV0KICoKICogUEFSQU1TCiAqICAgICAgaHduZCBbSV0gIHdpbmRvdyBoYW5kbGUKICogICAgICB5ICAgIFtJXSAgZmxhZyA/Pz8/CiAqIAogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8Kdm9pZCBXSU5BUEkgUmVnaXN0ZXJTaGVsbEhvb2soSFdORCBod25kLCBEV09SRCB5KSB7CiAgICBGSVhNRShzaGVsbCwiKDB4JTA4eCwweCUwOGx4KTpzdHViLlxuIixod25kLHkpOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNoZWxsTWVzc2FnZUJveFcJCQkJW1NIRUxMMzIuMTgyXQogKgogKiBGb3JtYXQgYW5kIG91dHB1dCBlcnJvcm1lc3NhZ2UuCiAqCiAqIGlkVGV4dAlyZXNvdXJjZSBJRCBvZiB0aXRsZSBvciBMUFNUUgogKiBpZFRpdGxlCXJlc291cmNlIElEIG9mIHRpdGxlIG9yIExQU1RSCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpJTlQgX19jZGVjbApTaGVsbE1lc3NhZ2VCb3hXKEhNT0RVTEUgaG1vZCxIV05EIGh3bmQsRFdPUkQgaWRUZXh0LERXT1JEIGlkVGl0bGUsRFdPUkQgdVR5cGUsTFBDVk9JRCBhcmdsaXN0KSAKewlXQ0hBUglzelRleHRbMTAwXSxzelRpdGxlWzEwMF0sc3pUZW1wWzI1Nl07CglMUFdTVFIgICBwc3pUZXh0ID0gJnN6VGV4dFswXSwgcHN6VGl0bGUgPSAmc3pUaXRsZVswXTsKCUxQVk9JRAlhcmdzID0gJmFyZ2xpc3Q7CgoJVFJBQ0Uoc2hlbGwsIiglMDhseCwlMDhseCwlMDhseCwlMDhseCwlMDhseCwlcClcbiIsKERXT1JEKWhtb2QsKERXT1JEKWh3bmQsaWRUZXh0LGlkVGl0bGUsdVR5cGUsYXJnbGlzdCk7CgoJaWYgKCFISVdPUkQgKGlkVGl0bGUpKQoJICBMb2FkU3RyaW5nVyhobW9kLGlkVGl0bGUscHN6VGl0bGUsMTAwKTsKCWVsc2UKCSAgcHN6VGl0bGUgPSAoTFBXU1RSKWlkVGl0bGU7CgoJaWYgKCEgSElXT1JEIChpZFRleHQpKQoJICBMb2FkU3RyaW5nVyhobW9kLGlkVGV4dCxwc3pUZXh0LDEwMCk7CgllbHNlCgkgIHBzelRleHQgPSAoTFBXU1RSKWlkVGV4dDsKCglGb3JtYXRNZXNzYWdlVyhGT1JNQVRfTUVTU0FHRV9GUk9NX1NUUklORyB8IEZPUk1BVF9NRVNTQUdFX0FSR1VNRU5UX0FSUkFZICxzelRleHQsMCwwLHN6VGVtcCwyNTYsYXJncyk7CglyZXR1cm4gTWVzc2FnZUJveFcoaHduZCxzelRlbXAsc3pUaXRsZSx1VHlwZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNoZWxsTWVzc2FnZUJveEEJCQkJW1NIRUxMMzIuMTgzXQogKi8KSU5UIF9fY2RlY2wKU2hlbGxNZXNzYWdlQm94QShITU9EVUxFIGhtb2QsSFdORCBod25kLERXT1JEIGlkVGV4dCxEV09SRCBpZFRpdGxlLERXT1JEIHVUeXBlLExQQ1ZPSUQgYXJnbGlzdCkgCnsJY2hhcglzelRleHRbMTAwXSxzelRpdGxlWzEwMF0sc3pUZW1wWzI1Nl07CglMUFNUUiAgIHBzelRleHQgPSAmc3pUZXh0WzBdLCBwc3pUaXRsZSA9ICZzelRpdGxlWzBdOwoJTFBWT0lECWFyZ3MgPSAmYXJnbGlzdDsKCglUUkFDRShzaGVsbCwiKCUwOGx4LCUwOGx4LCUwOGx4LCUwOGx4LCUwOGx4LCVwKVxuIiwgKERXT1JEKWhtb2QsKERXT1JEKWh3bmQsaWRUZXh0LGlkVGl0bGUsdVR5cGUsYXJnbGlzdCk7CgoJaWYgKCFISVdPUkQgKGlkVGl0bGUpKQoJICBMb2FkU3RyaW5nQShobW9kLGlkVGl0bGUscHN6VGl0bGUsMTAwKTsKCWVsc2UKCSAgcHN6VGl0bGUgPSAoTFBTVFIpaWRUaXRsZTsKCglpZiAoISBISVdPUkQgKGlkVGV4dCkpCgkgIExvYWRTdHJpbmdBKGhtb2QsaWRUZXh0LHBzelRleHQsMTAwKTsKCWVsc2UKCSAgcHN6VGV4dCA9IChMUFNUUilpZFRleHQ7CgoJRm9ybWF0TWVzc2FnZUEoRk9STUFUX01FU1NBR0VfRlJPTV9TVFJJTkcgfCBGT1JNQVRfTUVTU0FHRV9BUkdVTUVOVF9BUlJBWSAscHN6VGV4dCwwLDAsc3pUZW1wLDI1NixhcmdzKTsKCXJldHVybiBNZXNzYWdlQm94QShod25kLHN6VGVtcCxwc3pUaXRsZSx1VHlwZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIUmVzdHJpY3RlZAkJCQlbU0hFTEwzMi4xMDBdCiAqCiAqIHdhbGtzIHRocm91Z2ggcG9saWN5IHRhYmxlLCBxdWVyaWVzIDxhcHA+IGtleSwgPHR5cGU+IHZhbHVlLCByZXR1cm5zIAogKiBxdWVyaWVkIChEV09SRCkgdmFsdWUuCiAqIHsweDAwMDAxLEV4cGxvcmVyLE5vUnVufQogKiB7MHgwMDAwMixFeHBsb3JlcixOb0Nsb3NlfQogKiB7MHgwMDAwNCxFeHBsb3JlcixOb1NhdmVTZXR0aW5nc30KICogezB4MDAwMDgsRXhwbG9yZXIsTm9GaWxlTWVudX0KICogezB4MDAwMTAsRXhwbG9yZXIsTm9TZXRGb2xkZXJzfQogKiB7MHgwMDAyMCxFeHBsb3JlcixOb1NldFRhc2tiYXJ9CiAqIHsweDAwMDQwLEV4cGxvcmVyLE5vRGVza3RvcH0KICogezB4MDAwODAsRXhwbG9yZXIsTm9GaW5kfQogKiB7MHgwMDEwMCxFeHBsb3JlcixOb0RyaXZlc30KICogezB4MDAyMDAsRXhwbG9yZXIsTm9Ecml2ZUF1dG9SdW59CiAqIHsweDAwNDAwLEV4cGxvcmVyLE5vRHJpdmVUeXBlQXV0b1J1bn0KICogezB4MDA4MDAsRXhwbG9yZXIsTm9OZXRIb29kfQogKiB7MHgwMTAwMCxFeHBsb3JlcixOb1N0YXJ0QmFubmVyfQogKiB7MHgwMjAwMCxFeHBsb3JlcixSZXN0cmljdFJ1bn0KICogezB4MDQwMDAsRXhwbG9yZXIsTm9QcmludGVyVGFic30KICogezB4MDgwMDAsRXhwbG9yZXIsTm9EZWxldGVQcmludGVyfQogKiB7MHgxMDAwMCxFeHBsb3JlcixOb0FkZFByaW50ZXJ9CiAqIHsweDIwMDAwLEV4cGxvcmVyLE5vU3RhcnRNZW51U3ViRm9sZGVyc30KICogezB4NDAwMDAsRXhwbG9yZXIsTXlEb2NzT25OZXR9CiAqIHsweDgwMDAwLFdpbk9sZEFwcCxOb1JlYWxNb2RlfQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KRFdPUkQgV0lOQVBJIFNIUmVzdHJpY3RlZCAoRFdPUkQgcG9sKSB7CglIS0VZCXhoa2V5OwoKCUZJWE1FKHNoZWxsLCIoJTA4bHgpOnN0dWIuXG4iLHBvbCk7CglpZiAoUmVnT3BlbktleUEoSEtFWV9DVVJSRU5UX1VTRVIsIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxQb2xpY2llcyIsJnhoa2V5KSkKCQlyZXR1cm4gMDsKCS8qIEZJWE1FOiBkbyBub3RoaW5nIGZvciBub3csIGp1c3QgcmV0dXJuIDAgKD09ICJhbGxvd2VkIikgKi8KCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENyZWF0ZURpcmVjdG9yeQkJCQlbU0hFTEwzMi4xNjVdCiAqCiAqIE5PVEVTCiAqICBleHBvcnRlZCBieSBvcmRpbmFsCiAqICBub3Qgc3VyZSBhYm91dCBMUFNFQ1VSSVRZX0FUVFJJQlVURVMKICovCkRXT1JEIFdJTkFQSSBTSENyZWF0ZURpcmVjdG9yeShMUFNFQ1VSSVRZX0FUVFJJQlVURVMgc2VjLExQQ1NUUiBwYXRoKSB7CglUUkFDRShzaGVsbCwiKCVwLCVzKTpzdHViLlxuIixzZWMscGF0aCk7CglpZiAoQ3JlYXRlRGlyZWN0b3J5QShwYXRoLHNlYykpCgkJcmV0dXJuIFRSVUU7CgkvKiBTSENoYW5nZU5vdGlmeSg4LDEscGF0aCwwKTsgKi8KCXJldHVybiBGQUxTRTsKI2lmIDAKCWlmIChTSEVMTDMyXzc5KHBhdGgsKExQVk9JRCl4KSkKCQlyZXR1cm4gMDsKCUZJWE1FKHNoZWxsLCIoJTA4bHgsJXMpOnN0dWIuXG4iLHgscGF0aCk7CglyZXR1cm4gMDsKI2VuZGlmCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRnJlZQkJCQkJW1NIRUxMMzIuMTk1XQogKgogKiBOT1RFUwogKiAgICAgZnJlZV9wdHIoKSAtIGZyZWVzIG1lbW9yeSB1c2luZyBJTWFsbG9jCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpEV09SRCBXSU5BUEkgU0hGcmVlKExQVk9JRCB4KSB7CiAgVFJBQ0Uoc2hlbGwsIiVwXG4iLHgpOwogIGlmICghSElXT1JEKHgpKQogIHsgKihMUERXT1JEKTB4ZGVhZjAwMDAgPSAwOwogIH0KICByZXR1cm4gSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLHgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFsbG9jCQkJCQlbU0hFTEwzMi4xOTZdCiAqCiAqIE5PVEVTCiAqICAgICB2b2lkICp0YXNrX2FsbG9jKERXT1JEIGxlbiksIHVzZXMgU0hNYWxsb2MgYWxsb2NhdG9yCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpMUFZPSUQgV0lOQVBJIFNIQWxsb2MoRFdPUkQgbGVuKSB7CiAvKiB2b2lkICogcmV0ID0gKExQVk9JRClMb2NhbEFsbG9jMzIobGVuLExNRU1fWkVST0lOSVQpOyovIC8qIGNocmFzaGVzICovCiB2b2lkICogcmV0ID0gKExQVk9JRCkgSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxsZW4pOwogIFRSQUNFKHNoZWxsLCIlbHUgYnl0ZXMgYXQgJXBcbiIsbGVuLCByZXQpOwogIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIUmVnaXN0ZXJEcmFnRHJvcAkJCQlbU0hFTEwzMi44Nl0KICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG9yZGluYWwKICovCkRXT1JEIFdJTkFQSSBTSFJlZ2lzdGVyRHJhZ0Ryb3AoSFdORCBoV25kLElEcm9wVGFyZ2V0ICogcERyb3BUYXJnZXQpIAp7CglGSVhNRSAoc2hlbGwsICIoMHglMDh4LCVwKTpzdHViLlxuIiwgaFduZCwgcERyb3BUYXJnZXQpOwoJcmV0dXJuICAgICBSZWdpc3RlckRyYWdEcm9wKGhXbmQsIHBEcm9wVGFyZ2V0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hSZXZva2VEcmFnRHJvcAkJCQlbU0hFTEwzMi44N10KICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG9yZGluYWwKICovCkRXT1JEIFdJTkFQSSBTSFJldm9rZURyYWdEcm9wKERXT1JEIHgpIHsKICAgIEZJWE1FKHNoZWxsLCIoMHglMDhseCk6c3R1Yi5cbiIseCk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUnVuRmlsZURsZwkJCQkJW1NIRUxMMzIuNjFdCiAqCiAqIE5PVEVTCiAqICAgICBPcmlnaW5hbCBuYW1lOiBSdW5GaWxlRGxnIChleHBvcnRlZCBieSBvcmRpbmFsKQogKi8KRFdPUkQgV0lOQVBJClJ1bkZpbGVEbGcgKEhXTkQgaHduZE93bmVyLCBEV09SRCBkd1BhcmFtMSwgRFdPUkQgZHdQYXJhbTIsCgkgICAgTFBTVFIgbHBzelRpdGxlLCBMUFNUUiBscHN6UHJvbXB0LCBVSU5UIHVGbGFncykKewogICAgRklYTUUgKHNoZWxsLCIoMHglMDh4IDB4JWx4IDB4JWx4IFwiJXNcIiBcIiVzXCIgMHgleCk6c3R1Yi5cbiIsCgkgICBod25kT3duZXIsIGR3UGFyYW0xLCBkd1BhcmFtMiwgbHBzelRpdGxlLCBscHN6UHJvbXB0LCB1RmxhZ3MpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEV4aXRXaW5kb3dzRGlhbG9nCQkJCVtTSEVMTDMyLjYwXQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8Kdm9pZCBXSU5BUEkgRXhpdFdpbmRvd3NEaWFsb2cgKEhXTkQgaFduZE93bmVyKQp7CglUUkFDRSAoc2hlbGwsIigweCUwOHgpXG4iLCBoV25kT3duZXIpOwoJaWYgKE1lc3NhZ2VCb3hBKCBoV25kT3duZXIsICJEbyB5b3Ugd2FudCB0byBleGl0IFdJTkU/IiwgIlNodXRkb3duIiwgTUJfWUVTTk98TUJfSUNPTlFVRVNUSU9OKSA9PSBJRE9LKQoJeyBTZW5kTWVzc2FnZUEgKCBoV25kT3duZXIsIFdNX1FVSVQsIDAsIDApOwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBcnJhbmdlV2luZG93cwkJCQlbU0hFTEwzMi4xODRdCiAqIAogKi8KRFdPUkQgV0lOQVBJCkFycmFuZ2VXaW5kb3dzIChEV09SRCBkd1BhcmFtMSwgRFdPUkQgZHdQYXJhbTIsIERXT1JEIGR3UGFyYW0zLAoJCURXT1JEIGR3UGFyYW00LCBEV09SRCBkd1BhcmFtNSkKewogICAgRklYTUUgKHNoZWxsLCIoMHglbHggMHglbHggMHglbHggMHglbHggMHglbHgpOnN0dWIuXG4iLAoJICAgZHdQYXJhbTEsIGR3UGFyYW0yLCBkd1BhcmFtMywgZHdQYXJhbTQsIGR3UGFyYW01KTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTaWduYWxGaWxlT3BlbgkJCQlbU0hFTEwzMi4xMDNdCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpEV09SRCBXSU5BUEkKU2lnbmFsRmlsZU9wZW4gKERXT1JEIGR3UGFyYW0xKQp7CiAgICBGSVhNRSAoc2hlbGwsIigweCUwOGx4KTpzdHViLlxuIiwgZHdQYXJhbTEpOwoKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFkZFRvUmVjZW50RG9jcwkJCQlbU0hFTEwzMi4yMzRdCiAqCiAqIFBBUkFNRVRFUlMKICogICB1RmxhZ3MgIFtJTl0gU0hBUkRfUEFUSCBvciBTSEFSRF9QSURMCiAqICAgcHYgICAgICBbSU5dIHN0cmluZyBvciBwaWRsLCBOVUxMIGNsZWFycyB0aGUgbGlzdAogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgbmFtZQogKi8KRFdPUkQgV0lOQVBJIFNIQWRkVG9SZWNlbnREb2NzIChVSU5UIHVGbGFncyxMUENWT0lEIHB2KSAgIAp7IGlmIChTSEFSRF9QSURMPT11RmxhZ3MpCiAgeyBGSVhNRSAoc2hlbGwsIigweCUwOHgscGlkbD0lcCk6c3R1Yi5cbiIsIHVGbGFncyxwdik7Cgl9CgllbHNlCgl7IEZJWE1FIChzaGVsbCwiKDB4JTA4eCwlcyk6c3R1Yi5cbiIsIHVGbGFncywoY2hhciopcHYpOwoJfQogIHJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRmlsZU9wZXJhdGlvbgkJCQlbU0hFTEwzMi4yNDJdCiAqCiAqLwpEV09SRCBXSU5BUEkgU0hGaWxlT3BlcmF0aW9uQVcoRFdPUkQgeCkKewlGSVhNRShzaGVsbCwiMHglMDhseCBzdHViXG4iLHgpOwoJcmV0dXJuIDA7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEZpbGVPcGVyYXRpb25BCQkJCVtTSEVMTDMyLjI0M10KICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG5hbWUKICovCkRXT1JEIFdJTkFQSSBTSEZpbGVPcGVyYXRpb25BIChMUFNIRklMRU9QU1RSVUNUQSBscEZpbGVPcCkgICAKeyBGSVhNRSAoc2hlbGwsIiglcCk6c3R1Yi5cbiIsIGxwRmlsZU9wKTsKICByZXR1cm4gMTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEZpbGVPcGVyYXRpb25XCQkJCVtTSEVMTDMyLjI0NF0KICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG5hbWUKICovCkRXT1JEIFdJTkFQSSBTSEZpbGVPcGVyYXRpb25XIChMUFNIRklMRU9QU1RSVUNUVyBscEZpbGVPcCkgICAKeyBGSVhNRSAoc2hlbGwsIiglcCk6c3R1Yi5cbiIsIGxwRmlsZU9wKTsKICByZXR1cm4gMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hDaGFuZ2VOb3RpZnkJCQkJW1NIRUxMMzIuMjM5XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgbmFtZQogKi8KRFdPUkQgV0lOQVBJIFNIQ2hhbmdlTm90aWZ5ICgKICAgIElOVCAgIHdFdmVudElkLCAgLyogW0lOXSBmbGFncyB0aGF0IHNwZWNpZmllcyB0aGUgZXZlbnQqLwogICAgVUlOVCAgdUZsYWdzLCAgIC8qIFtJTl0gdGhlIG1lYW5pbmcgb2YgZHdJdGVtWzF8Ml0qLwoJCUxQQ1ZPSUQgZHdJdGVtMSwKCQlMUENWT0lEIGR3SXRlbTIpCnsgRklYTUUgKHNoZWxsLCIoMHglMDh4LDB4JTA4dXgsJXAsJXApOnN0dWIuXG4iLCB3RXZlbnRJZCx1RmxhZ3MsZHdJdGVtMSxkd0l0ZW0yKTsKICByZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENyZWF0ZVNoZWxsRm9sZGVyVmlld0V4CQkJW1NIRUxMMzIuMTc0XQogKgogKiBOT1RFUwogKiAgc2VlIElTaGVsbEZvbGRlcjo6Q3JlYXRlVmlld09iamVjdAogKi8KSFJFU1VMVCBXSU5BUEkgU0hDcmVhdGVTaGVsbEZvbGRlclZpZXdFeCgKICBMUFNIRUxMVklFV0RBVEEgcHN2Y2JpLCAvKltpbiBdIHNoZWxsdGVtcGxhdGUgc3RydWN0Ki8KICBMUFZPSUQqIHBwdikgICAgICAgICAgICAvKltvdXRdIElTaGVsbFZpZXcgcG9pbnRlciovCnsgRklYTUUgKHNoZWxsLCIoJXAsJXApOnN0dWIuXG4iLCBwc3ZjYmkscHB2KTsKICByZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgU0hXaW5IZWxwCQkJCQlbU0hFTEwzMi4xMjddCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFdpbkhlbHAgKERXT1JEIHYsIERXT1JEIHcsIERXT1JEIHgsIERXT1JEIHopCnsJRklYTUUoc2hlbGwsIjB4JTA4bHggMHglMDhseCAweCUwOGx4IDB4JTA4bHggc3R1YlxuIix2LHcseCx6KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBTSFJ1bkNvbnRyb2xQYW5lbCBbU0hFTEwzMi4xNjFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFJ1bkNvbnRyb2xQYW5lbCAoRFdPUkQgeCwgRFdPUkQgeikKewlGSVhNRShzaGVsbCwiMHglMDhseCAweCUwOGx4IHN0dWJcbiIseCx6KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNoZWxsRXhlY3V0ZUV4CQkJCVtTSEVMTDMyLjI5MV0KICoKICovCkJPT0wgV0lOQVBJIFNoZWxsRXhlY3V0ZUV4QVcgKExQVk9JRCBzZWkpCnsJaWYgKFZFUlNJT05fT3NJc1VuaWNvZGUoKSkKCSAgcmV0dXJuIFNoZWxsRXhlY3V0ZUV4VyAoc2VpKTsKCXJldHVybiBTaGVsbEV4ZWN1dGVFeEEgKHNlaSk7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2hlbGxFeGVjdXRlRXhBCQkJCVtTSEVMTDMyLjI5Ml0KICoKICovCkJPT0wgV0lOQVBJIFNoZWxsRXhlY3V0ZUV4QSAoTFBTSEVMTEVYRUNVVEVJTkZPQSBzZWkpCnsgCUNIQVIgc3pBcHBsaWNhdGlvbk5hbWVbTUFYX1BBVEhdLHN6Q29tbWFuZGxpbmVbTUFYX1BBVEhdLHN6UGlkbFsyMF07CglMUFNUUiBwb3M7CglpbnQgZ2FwLCBsZW47CglTVEFSVFVQSU5GT0EgIHN0YXJ0dXBpbmZvOwoJUFJPQ0VTU19JTkZPUk1BVElPTiBwcm9jZXNzaW5mb3JtYXRpb247CgkJCQogIAlXQVJOKHNoZWxsLCJtYXNrPTB4JTA4bHggaHduZD0weCUwNHggdmVyYj0lcyBmaWxlPSVzIHBhcm09JXMgZGlyPSVzIHNob3c9MHglMDh4IGNsYXNzPSVzIGluY29tcGxldGVcbiIsCgkJc2VpLT5mTWFzaywgc2VpLT5od25kLCBzZWktPmxwVmVyYiwgc2VpLT5scEZpbGUsCgkJc2VpLT5scFBhcmFtZXRlcnMsIHNlaS0+bHBEaXJlY3RvcnksIHNlaS0+blNob3csIHNlaS0+bHBDbGFzcyk7CgoJWmVyb01lbW9yeShzekFwcGxpY2F0aW9uTmFtZSxNQVhfUEFUSCk7CglpZiAoc2VpLT5scEZpbGUpCgkgIHN0cmNweShzekFwcGxpY2F0aW9uTmFtZSwgc2VpLT5scEZpbGUpOwoJCglaZXJvTWVtb3J5KHN6Q29tbWFuZGxpbmUsTUFYX1BBVEgpOwoJaWYgKHNlaS0+bHBQYXJhbWV0ZXJzKQoJICBzdHJjcHkoc3pDb21tYW5kbGluZSwgc2VpLT5scFBhcmFtZXRlcnMpOwoJCQkKCWlmIChzZWktPmZNYXNrICYgKFNFRV9NQVNLX0NMQVNTS0VZIHwgU0VFX01BU0tfSU5WT0tFSURMSVNUIHwgU0VFX01BU0tfSUNPTiB8IFNFRV9NQVNLX0hPVEtFWSB8CgkJCSAgU0VFX01BU0tfTk9DTE9TRVBST0NFU1MgfCBTRUVfTUFTS19DT05ORUNUTkVURFJWIHwgU0VFX01BU0tfRkxBR19EREVXQUlUIHwKCQkJICBTRUVfTUFTS19ET0VOVlNVQlNUIHwgU0VFX01BU0tfRkxBR19OT19VSSB8IFNFRV9NQVNLX1VOSUNPREUgfCAKCQkJICBTRUVfTUFTS19OT19DT05TT0xFIHwgU0VFX01BU0tfQVNZTkNPSyB8IFNFRV9NQVNLX0hNT05JVE9SICkpCgl7IEZJWE1FIChzaGVsbCwiZmxhZ3MgaWdub3JlZDogMHglMDhseFxuIiwgc2VpLT5mTWFzayk7Cgl9CgoJaWYgKHNlaS0+Zk1hc2sgJiBTRUVfTUFTS19DTEFTU05BTUUpCgl7IEhDUl9HZXRFeGVjdXRlQ29tbWFuZChzZWktPmxwQ2xhc3MsIChzZWktPmxwVmVyYikgPyBzZWktPmxwVmVyYiA6ICJvcGVuIiwgc3pDb21tYW5kbGluZSwgMjU2KTsJICAgIAoJfQoKCS8qIHByb2Nlc3MgdGhlIElETGlzdCAqLwoJaWYgKCAoc2VpLT5mTWFzayAmIFNFRV9NQVNLX0lOVk9LRUlETElTVCkgPT0gU0VFX01BU0tfSU5WT0tFSURMSVNUKSAvKjB4MGMqLwoJeyBTSEdldFBhdGhGcm9tSURMaXN0QSAoc2VpLT5scElETGlzdCxzekFwcGxpY2F0aW9uTmFtZSk7CgkgIFRSQUNFKHNoZWxsLCItLSBpZGxpc3Q9JXAgKCVzKVxuIiwgc2VpLT5scElETGlzdCwgc3pBcHBsaWNhdGlvbk5hbWUpOwoJfQoJZWxzZQoJeyBpZiAoc2VpLT5mTWFzayAmIFNFRV9NQVNLX0lETElTVCApCgkgIHsgLyogJUkgaXMgdGhlIGFkcmVzcyBvZiBhIGdsb2JhbCBpdGVtIElEKi8KCSAgICBwb3MgPSBzdHJzdHIoc3pDb21tYW5kbGluZSwgIiVJIik7CgkgICAgaWYgKHBvcykKCSAgICB7IEhHTE9CQUwgaG1lbSA9IFNIQWxsb2NTaGFyZWQgKCBzZWktPmxwSURMaXN0LCBJTEdldFNpemUoc2VpLT5scElETGlzdCksIDApOwoJICAgICAgc3ByaW50ZihzelBpZGwsIjolbGkiLChEV09SRClTSExvY2tTaGFyZWQoaG1lbSwwKSApOwoJICAgICAgU0hVbmxvY2tTaGFyZWQoaG1lbSk7CgkgICAgCgkgICAgICBnYXAgPSBzdHJsZW4oc3pQaWRsKTsKCSAgICAgIGxlbiA9IHN0cmxlbihwb3MpLTI7CgkgICAgICBtZW1tb3ZlKHBvcytnYXAscG9zKzIsbGVuKTsKCSAgICAgIG1lbWNweShwb3Msc3pQaWRsLGdhcCk7CgoJICAgIH0KCSAgfQoJfQoKCXBvcyA9IHN0cnN0cihzekNvbW1hbmRsaW5lLCAiLCVMIik7CS8qIGR1bm5vIHdoYXQgaXQgbWVhbnM6IGtpbGwgaXQqLwoJaWYgKHBvcykKCXsgbGVuID0gc3RybGVuKHBvcyktMjsKCSAgKnBvcz0weDA7CgkgIG1lbW1vdmUocG9zLHBvcyszLGxlbik7Cgl9CgoJVFJBQ0Uoc2hlbGwsImV4ZWN1dGU6ICVzICVzXG4iLHN6QXBwbGljYXRpb25OYW1lLCBzekNvbW1hbmRsaW5lKTsKCglaZXJvTWVtb3J5KCZzdGFydHVwaW5mbyxzaXplb2YoU1RBUlRVUElORk9BKSk7CglzdGFydHVwaW5mby5jYiA9IHNpemVvZihTVEFSVFVQSU5GT0EpOwoKCXJldHVybiBDcmVhdGVQcm9jZXNzQShzekFwcGxpY2F0aW9uTmFtZVswXSA/IHN6QXBwbGljYXRpb25OYW1lOk5VTEwsCgkJCSBzekNvbW1hbmRsaW5lWzBdID8gc3pDb21tYW5kbGluZSA6IE5VTEwsCgkJCSBOVUxMLCBOVUxMLCBGQUxTRSwgMCwgCgkJCSBOVUxMLCBOVUxMLCAmc3RhcnR1cGluZm8sICZwcm9jZXNzaW5mb3JtYXRpb24pOwoJICAKCQp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNoZWxsRXhlY3V0ZUV4VwkJCQlbU0hFTEwzMi4yOTNdCiAqCiAqLwpCT09MIFdJTkFQSSBTaGVsbEV4ZWN1dGVFeFcgKExQU0hFTExFWEVDVVRFSU5GT1cgc2VpKQp7CVNIRUxMRVhFQ1VURUlORk9BIHNlaUE7CglEV09SRCByZXQ7CgoJVFJBQ0UgKHNoZWxsLCIlcFxuIiwgc2VpKTsKCgltZW1jcHkoJnNlaUEsIHNlaSwgc2l6ZW9mKFNIRUxMRVhFQ1VURUlORk9BKSk7CgkKICAgICAgICBpZiAoc2VpLT5scFZlcmIpCgkgIHNlaUEubHBWZXJiID0gSEVBUF9zdHJkdXBXdG9BKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzZWktPmxwVmVyYik7CgogICAgICAgIGlmIChzZWktPmxwRmlsZSkKCSAgc2VpQS5scEZpbGUgPSBIRUFQX3N0cmR1cFd0b0EoIEdldFByb2Nlc3NIZWFwKCksIDAsIHNlaS0+bHBGaWxlKTsKCiAgICAgICAgaWYgKHNlaS0+bHBQYXJhbWV0ZXJzKQoJICBzZWlBLmxwUGFyYW1ldGVycyA9IEhFQVBfc3RyZHVwV3RvQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2VpLT5scFBhcmFtZXRlcnMpOwoKCWlmIChzZWktPmxwRGlyZWN0b3J5KQoJICBzZWlBLmxwRGlyZWN0b3J5ID0gSEVBUF9zdHJkdXBXdG9BKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzZWktPmxwRGlyZWN0b3J5KTsKCiAgICAgICAgaWYgKChzZWktPmZNYXNrICYgU0VFX01BU0tfQ0xBU1NOQU1FKSAmJiBzZWktPmxwQ2xhc3MpCgkgIHNlaUEubHBDbGFzcyA9IEhFQVBfc3RyZHVwV3RvQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2VpLT5scENsYXNzKTsKCWVsc2UKCSAgc2VpQS5scENsYXNzID0gTlVMTDsKCSAgCSAgCglyZXQgPSBTaGVsbEV4ZWN1dGVFeEEoJnNlaUEpOwoKICAgICAgICBpZiAoc2VpQS5scFZlcmIpCUhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCAoTFBTVFIpIHNlaUEubHBWZXJiICk7CglpZiAoc2VpQS5scEZpbGUpCUhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCAoTFBTVFIpIHNlaUEubHBGaWxlICk7CglpZiAoc2VpQS5scFBhcmFtZXRlcnMpCUhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCAoTFBTVFIpIHNlaUEubHBQYXJhbWV0ZXJzICk7CglpZiAoc2VpQS5scERpcmVjdG9yeSkJSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIChMUFNUUikgc2VpQS5scERpcmVjdG9yeSApOwoJaWYgKHNlaUEubHBDbGFzcykJSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIChMUFNUUikgc2VpQS5scENsYXNzICk7CgogCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBMUFVOS05PV04gU0hFTEwzMl9JRXhwbG9yZXJJbnRlcmZhY2U9MDsKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hTZXRJbnN0YW5jZUV4cGxvcmVyCQkJW1NIRUxMMzIuMTc2XQogKgogKiBOT1RFUwogKiAgU2V0cyB0aGUgaW50ZXJmYWNlCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFNldEluc3RhbmNlRXhwbG9yZXIgKExQVU5LTk9XTiBscFVua25vd24pCnsJVFJBQ0UgKHNoZWxsLCIlcFxuIiwgbHBVbmtub3duKTsKCVNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlID0gbHBVbmtub3duOwoJcmV0dXJuIChIUkVTVUxUKSBscFVua25vd247Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hHZXRJbnN0YW5jZUV4cGxvcmVyCQkJW1NIRUxMMzIuMjU2XQogKgogKiBOT1RFUwogKiAgZ2V0cyB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgb2YgdGhlIGV4cGxvcmVyIGFuZCBhIHJlZmVyZW5jZQogKi8KSFJFU1VMVCBXSU5BUEkgU0hHZXRJbnN0YW5jZUV4cGxvcmVyIChMUFVOS05PV04gKiBscFVua25vd24pCnsJVFJBQ0Uoc2hlbGwsIiVwXG4iLCBscFVua25vd24pOwoKCSpscFVua25vd24gPSBTSEVMTDMyX0lFeHBsb3JlckludGVyZmFjZTsKCglpZiAoIVNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlKQoJICByZXR1cm4gRV9GQUlMOwoKCVNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlLT5scHZ0YmwtPmZuQWRkUmVmKFNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlKTsKCXJldHVybiBOT0VSUk9SOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRnJlZVVudXNlZExpYnJhcmllcwkJCVtTSEVMTDMyLjEyM10KICoKICogTk9URVMKICogIGV4cG9ydGVkIGJ5IG5hbWUKICovCkhSRVNVTFQgV0lOQVBJIFNIRnJlZVVudXNlZExpYnJhcmllcyAodm9pZCkKewlGSVhNRShzaGVsbCwic3R1YlxuIik7CglyZXR1cm4gVFJVRTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfU2hvd0RyYWdJbWFnZQkJCQlbU0hFTEwzMi4xMzddCiAqCiAqIE5PVEVTCiAqICBleHBvcnRlZCBieSBuYW1lCiAqLwpIUkVTVUxUIFdJTkFQSSBEQURfU2hvd0RyYWdJbWFnZSAoRFdPUkQgdSkKeyBGSVhNRShzaGVsbCwiMHglMDhseCBzdHViXG4iLHUpOwogIHJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIUmVnQ2xvc2VLZXkJCQlbTlQ0LjA6U0hFTEwzMi41MDVdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFJlZ0Nsb3NlS2V5IChIS0VZIGhrZXkpCnsJVFJBQ0Uoc2hlbGwsIjB4JTA0eFxuIixoa2V5KTsKCXJldHVybiBSZWdDbG9zZUtleSggaGtleSApOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIUmVnT3BlbktleUEJCQkJW1NIRUxMMzIuNTA2XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZWdPcGVuS2V5QShIS0VZIGhLZXksIExQU1RSIGxwU3ViS2V5LCBMUEhLRVkgcGhrUmVzdWx0KQp7CUZJWE1FKHNoZWxsLCIoMHglMDh4LCAlcywgJXApXG4iLCBoS2V5LCBkZWJ1Z3N0cl9hKGxwU3ViS2V5KSwKCSAgICAgIHBoa1Jlc3VsdCk7CglyZXR1cm4gUmVnT3BlbktleUEoaEtleSwgbHBTdWJLZXksIHBoa1Jlc3VsdCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIUmVnT3BlbktleVcJCQkJW05UNC4wOlNIRUxMMzIuNTA3XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZWdPcGVuS2V5VyAoSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkpCnsJV0FSTihzaGVsbCwiMHglMDR4ICVzICVwXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxyZXRrZXkpOwoJcmV0dXJuIFJlZ09wZW5LZXlXKCBoa2V5LCBscHN6U3ViS2V5LCByZXRrZXkgKTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJlZ1F1ZXJ5VmFsdWVFeEEJCQkJW1NIRUxMMzIuNTA5XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZWdRdWVyeVZhbHVlRXhBKERXT1JEIHUsIExQU1RSIHYsIERXT1JEIHcsIERXT1JEIHgsCgkJCQkgIERXT1JEIHksIERXT1JEIHopCnsJRklYTUUoc2hlbGwsIjB4JTA0bHggJXMgMHglMDRseCAweCUwNGx4IDB4JTA0bHggIDB4JTA0bHggc3R1YlxuIiwKCQl1LGRlYnVnc3RyX2Eodiksdyx4LHkseik7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJlZ1F1ZXJ5VmFsdWVXCQkJCVtOVDQuMDpTSEVMTDMyLjUxMF0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIUmVnUXVlcnlWYWx1ZVcgKEhLRVkgaGtleSwgTFBXU1RSIGxwc3pTdWJLZXksCgkJCQkgTFBXU1RSIGxwc3pEYXRhLCBMUERXT1JEIGxwY2JEYXRhICkKewlXQVJOKHNoZWxsLCIweCUwNHggJXMgJXAgJXAgc2VtaS1zdHViXG4iLAoJCWhrZXksIGRlYnVnc3RyX3cobHBzelN1YktleSksIGxwc3pEYXRhLCBscGNiRGF0YSk7CglyZXR1cm4gUmVnUXVlcnlWYWx1ZVcoIGhrZXksIGxwc3pTdWJLZXksIGxwc3pEYXRhLCBscGNiRGF0YSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJlZ1F1ZXJ5VmFsdWVFeFcJCQkJW05UNC4wOlNIRUxMMzIuNTExXQogKgogKiBGSVhNRSAKICogIGlmIHRoZSBkYXRhdHlwZSBSRUdfRVhQQU5EX1NaIHRoZW4gZXhwYW5kIHRoZSBzdHJpbmcgYW5kIGNoYW5nZQogKiAgKnBkd1R5cGUgdG8gUkVHX1NaLiAKICovCkhSRVNVTFQgV0lOQVBJIFNIUmVnUXVlcnlWYWx1ZUV4VyAoSEtFWSBoa2V5LCBMUFdTVFIgcHN6VmFsdWUsIExQRFdPUkQgcGR3UmVzZXJ2ZWQsCgkJIExQRFdPUkQgcGR3VHlwZSwgTFBWT0lEIHB2RGF0YSwgTFBEV09SRCBwY2JEYXRhKQp7CURXT1JEIHJldDsKCVdBUk4oc2hlbGwsIjB4JTA0eCAlcyAlcCAlcCAlcCAlcCBzZW1pLXN0dWJcbiIsCgkJaGtleSwgZGVidWdzdHJfdyhwc3pWYWx1ZSksIHBkd1Jlc2VydmVkLCBwZHdUeXBlLCBwdkRhdGEsIHBjYkRhdGEpOwoJcmV0ID0gUmVnUXVlcnlWYWx1ZUV4VyAoIGhrZXksIHBzelZhbHVlLCBwZHdSZXNlcnZlZCwgcGR3VHlwZSwgcHZEYXRhLCBwY2JEYXRhKTsKCXJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlYWRDYWJpbmV0U3RhdGUJCQkJW05UIDQuMDpTSEVMTDMyLjY1MV0KICoKICovCkhSRVNVTFQgV0lOQVBJIFJlYWRDYWJpbmV0U3RhdGUoRFdPUkQgdSwgRFdPUkQgdikKewlGSVhNRShzaGVsbCwiMHglMDRseCAweCUwNGx4IHN0dWJcbiIsdSx2KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFdyaXRlQ2FiaW5ldFN0YXRlCQkJCVtOVCA0LjA6U0hFTEwzMi42NTJdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBXcml0ZUNhYmluZXRTdGF0ZShEV09SRCB1KQp7CUZJWE1FKHNoZWxsLCIweCUwNGx4IHN0dWJcbiIsdSk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBGaWxlSWNvbkluaXQgCQkJCVtTSEVMTDMyLjY2MF0KICoKICovCkJPT0wgV0lOQVBJIEZpbGVJY29uSW5pdChCT09MIGJGdWxsSW5pdCkKewlGSVhNRShzaGVsbCwiKCVzKVxuIiwgYkZ1bGxJbml0ID8gInRydWUiIDogImZhbHNlIik7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJc1VzZXJBZG1pbgkJCQkJW05UIDQuMDpTSEVMTDMyLjY4MF0KICoKICovCkhSRVNVTFQgV0lOQVBJIElzVXNlckFkbWluKHZvaWQpCnsJRklYTUUoc2hlbGwsInN0dWJcbiIpOwoJcmV0dXJuIFRSVUU7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU3RyUmV0VG9TdHJOCQkJCQlbU0hFTEwzMi45Nl0KICogCiAqIGNvbnZlcnRzIGEgU1RSUkVUIHRvIGEgbm9ybWFsIHN0cmluZwogKgogKiBOT1RFUwogKiAgdGhlIHBpZGwgaXMgZm9yIFNUUlJFVCBPRkZTRVQKICovCkhSRVNVTFQgV0lOQVBJIFN0clJldFRvU3RyTiAoTFBWT0lEIGRlc3QsIERXT1JEIGxlbiwgTFBTVFJSRVQgc3JjLCBMUElURU1JRExJU1QgcGlkbCkKewlUUkFDRShzaGVsbCwiZGVzdD0weCVwIGxlbj0weCVseCBzdHJyZXQ9MHglcCBwaWRsPSVwIHN0dWJcbiIsZGVzdCxsZW4sc3JjLHBpZGwpOwoKCXN3aXRjaCAoc3JjLT51VHlwZSkKCXsgY2FzZSBTVFJSRVRfV1NUUjoKCSAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3JjLT51LnBPbGVTdHIsIC0xLCAoTFBTVFIpZGVzdCwgbGVuLCBOVUxMLCBOVUxMKTsKCSAgICBTSEZyZWUoc3JjLT51LnBPbGVTdHIpOwoJICAgIGJyZWFrOwoKCSAgY2FzZSBTVFJSRVRfQ1NUUkE6CgkgICAgaWYgKFZFUlNJT05fT3NJc1VuaWNvZGUoKSkKCSAgICAgIGxzdHJjcHluQXRvVygoTFBXU1RSKWRlc3QsIHNyYy0+dS5jU3RyLCBsZW4pOwoJICAgIGVsc2UKCSAgICAgIHN0cm5jcHkoKExQU1RSKWRlc3QsIHNyYy0+dS5jU3RyLCBsZW4pOwoJICAgIGJyZWFrOwoKCSAgY2FzZSBTVFJSRVRfT0ZGU0VUQToKCSAgICBpZiAocGlkbCkKCSAgICB7IGlmKFZFUlNJT05fT3NJc1VuaWNvZGUoKSkKCSAgICAgICAgbHN0cmNweW5BdG9XKChMUFdTVFIpZGVzdCwgKChMUENTVFIpJnBpZGwtPm1raWQpK3NyYy0+dS51T2Zmc2V0LCBsZW4pOwoJICAgICAgZWxzZQoJICAgICAgICBzdHJuY3B5KChMUFNUUilkZXN0LCAoKExQQ1NUUikmcGlkbC0+bWtpZCkrc3JjLT51LnVPZmZzZXQsIGxlbik7CgkgICAgICBicmVhazsKCSAgICB9CgoJICBkZWZhdWx0OgoJICAgIEZJWE1FKHNoZWxsLCJ1bmtub3duIHR5cGUhXG4iKTsKCSAgICBpZiAobGVuKQoJICAgIHsgKihMUFNUUilkZXN0ID0gJ1wwJzsKCSAgICB9CgkgICAgcmV0dXJuKEZBTFNFKTsKCX0KCXJldHVybihUUlVFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU3RyQ2hyVwkJCQkJW05UIDQuMDpTSEVMTDMyLjY1MV0KICoKICovCkxQV1NUUiBXSU5BUEkgU3RyQ2hyVyAoTFBXU1RSIHN0ciwgV0NIQVIgeCApCnsJTFBXU1RSIHB0cj1zdHI7CgkKCVRSQUNFKHNoZWxsLCIlcyAweCUwNHhcbiIsZGVidWdzdHJfdyhzdHIpLHgpOwoJZG8gCgl7ICBpZiAoKnB0cj09eCkKCSAgIHsgcmV0dXJuIHB0cjsKCSAgIH0KCSAgIHB0cisrOwoJfSB3aGlsZSAoKnB0cik7CglyZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU3RyQ21wTklXCQkJCQlbTlQgNC4wOlNIRUxMMzIuKl0KICoKICovCklOVCBXSU5BUEkgU3RyQ21wTklXICggTFBXU1RSIHdzdHIxLCBMUFdTVFIgd3N0cjIsIElOVCBsZW4pCnsJRklYTUUoIHNoZWxsLCIlcyAlcyAlaSBzdHViXG4iLCBkZWJ1Z3N0cl93KHdzdHIxKSxkZWJ1Z3N0cl93KHdzdHIyKSxsZW4pOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQWxsb2NTaGFyZWQJCQkJW1NIRUxMMzIuNTIwXQogKgogKiBOT1RFUwogKiAgcGFyYW1ldGVyMSBpcyByZXR1cm4gdmFsdWUgZnJvbSBIZWFwQWxsb2MKICogIHBhcmFtZXRlcjIgaXMgZXF1YWwgdG8gdGhlIHNpemUgYWxsb2NhdGVkIHdpdGggSGVhcEFsbG9jCiAqICBwYXJhbWV0ZXIzIGlzIHJldHVybiB2YWx1ZSBmcm9tIEdldEN1cnJlbnRQcm9jZXNzSWQKICoKICogIHRoZSByZXR1cm4gdmFsdWUgaXMgcG9zdGVkIGFzIGxQYXJhbSB3aXRoIDB4NDAyIChXTV9VU0VSKzIpIHRvIHNvbWV3aGVyZQogKiAgV01fVVNFUisyIGNvdWxkIGJlIHRoZSB1bmRvY3VtZW50ZWQgQ1dNX1NFVFBBVEgKICogIHRoZSBhbGxvY2F0ZWQgbWVtb3J5IGNvbnRhaW5zIGEgcGlkbAogKi8KSEdMT0JBTCBXSU5BUEkgU0hBbGxvY1NoYXJlZChMUFZPSUQgcHNyYywgRFdPUkQgc2l6ZSwgRFdPUkQgcHJvY0lEKQp7CUhHTE9CQUwgaG1lbTsKCUxQVk9JRCBwbWVtOwoJCglUUkFDRShzaGVsbCwicHRyPSVwIHNpemU9MHglMDRseCBwcm9jSUQ9MHglMDRseFxuIixwc3JjLHNpemUscHJvY0lEKTsKCWhtZW0gPSBHbG9iYWxBbGxvYyhHTUVNX0ZJWEVELCBzaXplKTsKCWlmICghaG1lbSkKCSAgcmV0dXJuIDA7CgkKCXBtZW0gPSAgR2xvYmFsTG9jayAoaG1lbSk7CgoJaWYgKCEgcG1lbSkKCSAgcmV0dXJuIDA7CgkgIAoJbWVtY3B5IChwbWVtLCBwc3JjLCBzaXplKTsKCUdsb2JhbFVubG9jayhobWVtKTsgCglyZXR1cm4gaG1lbTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSExvY2tTaGFyZWQJCQkJCVtTSEVMTDMyLjUyMV0KICoKICogTk9URVMKICogIHBhcmFtZXRlcjEgaXMgcmV0dXJuIHZhbHVlIGZyb20gU0hBbGxvY1NoYXJlZAogKiAgcGFyYW1ldGVyMiBpcyByZXR1cm4gdmFsdWUgZnJvbSBHZXRDdXJyZW50UHJvY2Vzc0lkCiAqICB0aGUgcmVjZWl2ZXIgb2YgKFdNX1VTRVIrMikgdHJ5cyB0byBsb2NrIHRoZSBIQU5ETEUgKD8pIAogKiAgdGhlIHJldHVybnZhbHVlIHNlZW1zIHRvIGJlIGEgbWVtb3J5YWRyZXNzCiAqLwpMUFZPSUQgV0lOQVBJIFNITG9ja1NoYXJlZChIQU5ETEUgaG1lbSwgRFdPUkQgcHJvY0lEKQp7CVRSQUNFKHNoZWxsLCJoYW5kbGU9MHglMDR4IHByb2NJRD0weCUwNGx4XG4iLGhtZW0scHJvY0lEKTsKCXJldHVybiBHbG9iYWxMb2NrKGhtZW0pOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIVW5sb2NrU2hhcmVkCQkJCVtTSEVMTDMyLjUyMl0KICoKICogTk9URVMKICogIHBhcmFtZXRlcjEgaXMgcmV0dXJuIHZhbHVlIGZyb20gU0hMb2NrU2hhcmVkCiAqLwpCT09MIFdJTkFQSSBTSFVubG9ja1NoYXJlZChIQU5ETEUgcG1lbSkKewlUUkFDRShzaGVsbCwiaGFuZGxlPTB4JTA0eFxuIixwbWVtKTsKCXJldHVybiBHbG9iYWxVbmxvY2socG1lbSk7IAp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRnJlZVNoYXJlZAkJCQkJW1NIRUxMMzIuNTIzXQogKgogKiBOT1RFUwogKiAgcGFyYW1ldGVyMSBpcyByZXR1cm4gdmFsdWUgZnJvbSBTSEFsbG9jU2hhcmVkCiAqICBwYXJhbWV0ZXIyIGlzIHJldHVybiB2YWx1ZSBmcm9tIEdldEN1cnJlbnRQcm9jZXNzSWQKICovCkhBTkRMRSBXSU5BUEkgU0hGcmVlU2hhcmVkKEhBTkRMRSBobWVtLCBEV09SRCBwcm9jSUQpCnsJVFJBQ0Uoc2hlbGwsImhhbmRsZT0weCUwNHggMHglMDRseFxuIixobWVtLHByb2NJRCk7CglyZXR1cm4gR2xvYmFsRnJlZShobWVtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2V0QXBwU3RhcnRpbmdDdXJzb3IJCQkJW1NIRUxMMzIuOTldCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTZXRBcHBTdGFydGluZ0N1cnNvcihIV05EIHUsIERXT1JEIHYpCnsJRklYTUUoc2hlbGwsImh3bmQ9MHglMDR4IDB4JTA0bHggc3R1YlxuIix1LHYgKTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNITG9hZE9MRQkJCQkJW1NIRUxMMzIuMTUxXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hMb2FkT0xFKERXT1JEIHUpCnsJRklYTUUoc2hlbGwsIjB4JTA0bHggc3R1YlxuIix1KTsKCXJldHVybiBTX09LOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERyaXZlVHlwZQkJCQkJW1NIRUxMMzIuNjRdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBEcml2ZVR5cGUoRFdPUkQgdSkKewlGSVhNRShzaGVsbCwiMHglMDRseCBzdHViXG4iLHUpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hBYm9ydEludm9rZUNvbW1hbmQJCQkJW1NIRUxMMzIuMTk4XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hBYm9ydEludm9rZUNvbW1hbmQodm9pZCkKewlGSVhNRShzaGVsbCwic3R1YlxuIik7CglyZXR1cm4gMTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSE91dE9mTWVtb3J5TWVzc2FnZUJveAkJCVtTSEVMTDMyLjEyNl0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIT3V0T2ZNZW1vcnlNZXNzYWdlQm94KERXT1JEIHUsIERXT1JEIHYsIERXT1JEIHcpCnsJRklYTUUoc2hlbGwsIjB4JTA0bHggMHglMDRseCAweCUwNGx4IHN0dWJcbiIsdSx2LHcpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGbHVzaENsaXBib2FyZAkJCQlbU0hFTEwzMi4xMjFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEZsdXNoQ2xpcGJvYXJkKHZvaWQpCnsJRklYTUUoc2hlbGwsInN0dWJcbiIpOwoJcmV0dXJuIDE7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU3RyUkNoclcJCQkJCVtTSEVMTDMyLjMyMF0KICoKICovCkxQV1NUUiBXSU5BUEkgU3RyUkNoclcoTFBXU1RSIGxwU3RhcnQsIExQV1NUUiBscEVuZCwgRFdPUkQgd01hdGNoKQp7CUxQV1NUUiB3cHRyPU5VTEw7CglUUkFDRShzaGVsbCwiJXMgJXMgMHglMDR4XG4iLGRlYnVnc3RyX3cobHBTdGFydCksZGVidWdzdHJfdyhscEVuZCksIChXQ0hBUil3TWF0Y2ggKTsKCgkvKiBpZiB0aGUgZW5kIG5vdCBnaXZlbiwgc2VhcmNoKi8KCWlmICghbHBFbmQpCgl7IGxwRW5kPWxwU3RhcnQ7CgkgIHdoaWxlICgqbHBFbmQpIAoJICAgIGxwRW5kKys7Cgl9CgoJZG8gCgl7IGlmICgqbHBTdGFydD09KFdDSEFSKXdNYXRjaCkKCSAgICB3cHRyID0gbHBTdGFydDsKCSAgbHBTdGFydCsrOyAgCgl9IHdoaWxlICggbHBTdGFydDw9bHBFbmQgKTsgCglyZXR1cm4gd3B0cjsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIFN0ckZvcm1hdEJ5dGVTaXplCQkJCVtTSExXQVBJXQoqLwpMUFNUUiBXSU5BUEkgU3RyRm9ybWF0Qnl0ZVNpemVBICggRFdPUkQgZHcsIExQU1RSIHBzekJ1ZiwgVUlOVCBjY2hCdWYgKQp7CWNoYXIgYnVmWzY0XTsKCVRSQUNFKHNoZWxsLCIlbHggJXAgJWlcbiIsIGR3LCBwc3pCdWYsIGNjaEJ1Zik7CglpZiAoIGR3PDEwMjRMICkKCXsgc3ByaW50ZiAoYnVmLCIlMy4xZiBieXRlcyIsIChGTE9BVClkdyk7Cgl9CgllbHNlIGlmICggZHc8MTA0ODU3NkwpCgl7IHNwcmludGYgKGJ1ZiwiJTMuMWYgS0IiLCAoRkxPQVQpZHcvMTAyNCk7Cgl9CgllbHNlIGlmICggZHcgPCAxMDczNzQxODI0TCkKCXsgc3ByaW50ZiAoYnVmLCIlMy4xZiBNQiIsIChGTE9BVClkdy8xMDQ4NTc2TCk7Cgl9CgllbHNlCgl7IHNwcmludGYgKGJ1ZiwiJTMuMWYgR0IiLCAoRkxPQVQpZHcvMTA3Mzc0MTgyNEwpOwoJfQoJc3RybmNweSAocHN6QnVmLCBidWYsIGNjaEJ1Zik7CglyZXR1cm4gcHN6QnVmOwkKfQpMUFdTVFIgV0lOQVBJIFN0ckZvcm1hdEJ5dGVTaXplVyAoIERXT1JEIGR3LCBMUFdTVFIgcHN6QnVmLCBVSU5UIGNjaEJ1ZiApCnsJY2hhciBidWZbNjRdOwoJVFJBQ0Uoc2hlbGwsIiVseCAlcCAlaVxuIiwgZHcsIHBzekJ1ZiwgY2NoQnVmKTsKCWlmICggZHc8MTAyNEwgKQoJeyBzcHJpbnRmIChidWYsIiUzLjFmIGJ5dGVzIiwgKEZMT0FUKWR3KTsKCX0KCWVsc2UgaWYgKCBkdzwxMDQ4NTc2TCkKCXsgc3ByaW50ZiAoYnVmLCIlMy4xZiBLQiIsIChGTE9BVClkdy8xMDI0KTsKCX0KCWVsc2UgaWYgKCBkdyA8IDEwNzM3NDE4MjRMKQoJeyBzcHJpbnRmIChidWYsIiUzLjFmIE1CIiwgKEZMT0FUKWR3LzEwNDg1NzZMKTsKCX0KCWVsc2UKCXsgc3ByaW50ZiAoYnVmLCIlMy4xZiBHQiIsIChGTE9BVClkdy8xMDczNzQxODI0TCk7Cgl9Cglsc3RyY3B5bkF0b1cgKHBzekJ1ZiwgYnVmLCBjY2hCdWYpOwoJcmV0dXJuIHBzekJ1ZjsJCn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hXYWl0Rm9yRmlsZVRvT3BlbgkJCQlbU0hFTEwzMi45N10KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIV2FpdEZvckZpbGVUb09wZW4oRFdPUkQgdSwgRFdPUkQgdiwgRFdPUkQgdykKewlGSVhNRShzaGVsbCwiMHglMDRseCAweCUwNGx4IDB4JTA0bHggc3R1YlxuIix1LHYsdyk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb250cm9sX0ZpbGxDYWNoZV9SdW5ETEwJCQlbU0hFTEwzMi44XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgQ29udHJvbF9GaWxsQ2FjaGVfUnVuRExMKEhXTkQgaFduZCwgSEFORExFIGhNb2R1bGUsIERXT1JEIHcsIERXT1JEIHgpCnsJRklYTUUoc2hlbGwsIjB4JTA0eCAweCUwNHggMHglMDRseCAweCUwNGx4IHN0dWJcbiIsaFduZCwgaE1vZHVsZSx3LHgpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUnVuRExMX0NhbGxFbnRyeTE2CQkJCVtTSEVMTDMyLjEyMl0KICogdGhlIG5hbWUgaXMgcHJvcGFibHkgd3JvbmcKICovCkhSRVNVTFQgV0lOQVBJIFJ1bkRMTF9DYWxsRW50cnkxNihEV09SRCB2LCBEV09SRCB3LCBEV09SRCB4LCBEV09SRCB5LCBEV09SRCB6KQp7CUZJWE1FKHNoZWxsLCIweCUwNGx4IDB4JTA0bHggMHglMDRseCAweCUwNGx4IDB4JTA0bHggc3R1YlxuIix2LHcseCx5LHopOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJc2hlbGwzMl82NTQJCQkJW1NIRUxMMzIuNjU0XQogKgogKi8KSFJFU1VMVCBzaGVsbDMyXzY1NCAoRFdPUkQgeCwgRFdPUkQgeSkKewlGSVhNRShzaGVsbCwiMHglMDhseCAweCUwOGx4IHN0dWJcbiIseCx5KTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVJMQnVpbGRMaXN0T2ZQYXRocwkJCVtTSEVMTDMyLjE0Nl0KICoKICogTk9URVMKICogICBidWlsZHMgYSBEUEEKICovCkRXT1JEIFdJTkFQSSBSTEJ1aWxkTGlzdE9mUGF0aHMgKCkKewlGSVhNRSAoc2hlbGwsInN0dWJcbiIpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglTdHJUb09sZVN0cgkJCVtTSEVMTDMyLjE2M10KICoKICovCmludCBXSU5BUEkgU3RyVG9PbGVTdHIgKExQV1NUUiBscFdpZGVDaGFyU3RyLCBMUENTVFIgbHBNdWx0aUJ5dGVTdHJpbmcpCnsKCVRSQUNFKHNoZWxsLCIlcCAlcCglcylcbiIsCglscFdpZGVDaGFyU3RyLCBscE11bHRpQnl0ZVN0cmluZywgbHBNdWx0aUJ5dGVTdHJpbmcpOwoKCXJldHVybiBNdWx0aUJ5dGVUb1dpZGVDaGFyKDAsIDAsIGxwTXVsdGlCeXRlU3RyaW5nLCAtMSwgbHBXaWRlQ2hhclN0ciwgTUFYX1BBVEgpOwoKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVNIVmFsaWRhdGVVTkMJCQkJW1NIRUxMMzIuMTczXQogKgogKi8KSFJFU1VMVCBTSFZhbGlkYXRlVU5DIChEV09SRCB4LCBEV09SRCB5LCBEV09SRCB6KQp7CUZJWE1FKHNoZWxsLCIweCUwOGx4IDB4JTA4bHggMHglMDh4IHN0dWJcbiIseCx5LHopOwoJcmV0dXJuIDA7Cn0K