LyoKICogVGhlIHBhcmFtZXRlcnMgb2YgbWFueSBmdW5jdGlvbnMgY2hhbmdlcyBiZXR3ZWVuIGRpZmZlcmVudCBPUyB2ZXJzaW9ucwogKiAoTlQgdXNlcyBVbmljb2RlIHN0cmluZ3MsIDk1IHVzZXMgQVNDSUkgc3RyaW5ncykKICogCiAqIENvcHlyaWdodCAxOTk3IE1hcmN1cyBNZWlzc25lcgogKiAgICAgICAgICAgMTk5OCBK/HJnZW4gU2NobWllZAogKi8KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW52ZXJzaW9uLmgiCiNpbmNsdWRlICJoZWFwLmgiCgojaW5jbHVkZSAic2hlbGxhcGkuaCIKI2luY2x1ZGUgInNobG9iai5oIgojaW5jbHVkZSAic2hlbGwzMl9tYWluLmgiCiNpbmNsdWRlICJ3aW5lL3VuZG9jc2hlbGwuaCIKI2luY2x1ZGUgInNocG9saWN5LmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwoc2hlbGwpCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENoYW5nZU5vdGlmeVJlZ2lzdGVyCQkJW1NIRUxMMzIuMl0KICoKICogTk9URVMKICogICBJZGxpc3QgaXMgYW4gYXJyYXkgb2Ygc3RydWN0dXJlcyBhbmQgQ291bnQgc3BlY2lmaWVzIGhvdyBtYW55IGl0ZW1zIGluIHRoZSBhcnJheQogKiAgICh1c3VhbGx5IGp1c3Qgb25lIEkgdGhpbmspLgogKi8KRFdPUkQgV0lOQVBJClNIQ2hhbmdlTm90aWZ5UmVnaXN0ZXIoCiAgICBIV05EIGh3bmQsCiAgICBMT05HIGV2ZW50czEsCiAgICBMT05HIGV2ZW50czIsCiAgICBEV09SRCBtc2csCiAgICBpbnQgY291bnQsCiAgICBJRFNUUlVDVCAqaWRsaXN0KQp7CUZJWE1FKCIoMHglMDR4LDB4JTA4bHgsMHglMDhseCwweCUwOGx4LDB4JTA4eCwlcCk6c3R1Yi5cbiIsCgkJaHduZCxldmVudHMxLGV2ZW50czIsbXNnLGNvdW50LGlkbGlzdCk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENoYW5nZU5vdGlmeURlcmVnaXN0ZXIJCQlbU0hFTEwzMi40XQogKi8KRFdPUkQgV0lOQVBJClNIQ2hhbmdlTm90aWZ5RGVyZWdpc3RlcihMT05HIHgxKQp7CUZJWE1FKCIoMHglMDhseCk6c3R1Yi5cbiIseDEpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTlRTSENoYW5nZU5vdGlmeVJlZ2lzdGVyCQkJW1NIRUxMMzIuNjQwXQogKiBOT1RFUwogKiAgIElkbGlzdCBpcyBhbiBhcnJheSBvZiBzdHJ1Y3R1cmVzIGFuZCBDb3VudCBzcGVjaWZpZXMgaG93IG1hbnkgaXRlbXMgaW4gdGhlIGFycmF5CiAqICAgKHVzdWFsbHkganVzdCBvbmUgSSB0aGluaykuCiAqLwpEV09SRCBXSU5BUEkgTlRTSENoYW5nZU5vdGlmeVJlZ2lzdGVyKAogICAgSFdORCBod25kLAogICAgTE9ORyBldmVudHMxLAogICAgTE9ORyBldmVudHMyLAogICAgRFdPUkQgbXNnLAogICAgaW50IGNvdW50LAogICAgSURTVFJVQ1QgKmlkbGlzdCkKewlGSVhNRSgiKDB4JTA0eCwweCUwOGx4LDB4JTA4bHgsMHglMDhseCwweCUwOHgsJXApOnN0dWIuXG4iLAoJCWh3bmQsZXZlbnRzMSxldmVudHMyLG1zZyxjb3VudCxpZGxpc3QpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTlRTSENoYW5nZU5vdGlmeURlcmVnaXN0ZXIJCQlbU0hFTEwzMi42NDFdCiAqLwpEV09SRCBXSU5BUEkgTlRTSENoYW5nZU5vdGlmeURlcmVnaXN0ZXIoTE9ORyB4MSkKewlGSVhNRSgiKDB4JTA4bHgpOnN0dWIuXG4iLHgxKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQYXJzZUZpZWxkCQkJCQlbU0hFTEwzMi41OF0KICoKICovCkRXT1JEIFdJTkFQSSBQYXJzZUZpZWxkQShMUENTVFIgc3JjLCBEV09SRCBmaWVsZCwgTFBTVFIgZHN0LCBEV09SRCBsZW4pIAp7CVdBUk4oIignJXMnLDB4JTA4bHgsJXAsJWxkKSBzZW1pLXN0dWIuXG4iLHNyYyxmaWVsZCxkc3QsbGVuKTsKCglpZiAoIXNyYyB8fCAhc3JjWzBdIHx8ICFkc3QgfHwgIWxlbikKCSAgcmV0dXJuIDA7CgoJaWYgKGZpZWxkID4xKQoJeyBmaWVsZC0tOwkKCSAgd2hpbGUgKGZpZWxkKQoJICB7IGlmICgqc3JjPT0weDApIHJldHVybiBGQUxTRTsKCSAgICBpZiAoKnNyYz09JywnKSBmaWVsZC0tOwoJICAgIHNyYysrOwoJICB9Cgl9CgoJd2hpbGUgKCpzcmMhPTB4MDAgJiYgKnNyYyE9JywnICYmIGxlbj4wKSAKCXsgKmRzdD0qc3JjOyBkc3QrKywgc3JjKys7IGxlbi0tOwoJfQoJKmRzdD0weDA7CgkKCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQaWNrSWNvbkRsZwkJCQkJW1NIRUxMMzIuNjJdCiAqIAogKi8KRFdPUkQgV0lOQVBJIFBpY2tJY29uRGxnKERXT1JEIHgsRFdPUkQgeSxEV09SRCB6LERXT1JEIGEpIAp7CUZJWE1FKCIoJTA4bHgsJTA4bHgsJTA4bHgsJTA4bHgpOnN0dWIuXG4iLHgseSx6LGEpOwoJcmV0dXJuIDB4ZmZmZmZmZmY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEdldEZpbGVOYW1lRnJvbUJyb3dzZQkJCVtTSEVMTDMyLjYzXQogKiAKICovCkRXT1JEIFdJTkFQSSBHZXRGaWxlTmFtZUZyb21Ccm93c2UoSFdORCBob3duZXIsIExQU1RSIHRhcmdldGJ1ZiwgRFdPUkQgbGVuLCBEV09SRCB4LCBMUENTVFIgc3VmZml4LCBMUENTVFIgeSwgTFBDU1RSIGNtZCkgCnsJRklYTUUoIiglMDR4LCVwLCVsZCwlMDhseCwlcywlcywlcyk6c3R1Yi5cbiIsCgkgICAgaG93bmVyLHRhcmdldGJ1ZixsZW4seCxzdWZmaXgseSxjbWQpOwogICAgLyogcHV0cyB1cCBhIE9wZW4gRGlhbG9nIGFuZCByZXF1ZXN0cyBpbnB1dCBpbnRvIHRhcmdldGJ1ZiAqLwogICAgLyogT0ZOX0hJREVSRUFET05MWXxPRk5fTk9DSEFOR0VESVJ8T0ZOX0ZJTEVNVVNURVhJU1R8T0ZOX3Vua25vd24gKi8KICAgIGxzdHJjcHlBKHRhcmdldGJ1ZiwieDpcXGR1bW15LmV4ZSIpOwogICAgcmV0dXJuIDE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIR2V0U2V0dGluZ3MJCQkJW1NIRUxMMzIuNjhdCiAqIAogKiBOT1RFUwogKiAgdGhlIHJlZ2lzdHJ5IHBhdGggYXJlIGZvciB3aW45OCAodGVzdGVkKQogKiAgYW5kIHBvc3NpYmx5IGFyZSB0aGUgc2FtZSBpbiBudDQwCiAqLwp2b2lkIFdJTkFQSSBTSEdldFNldHRpbmdzKExQU0hFTExGTEFHU1RBVEUgbHBzZnMsIERXT1JEIGR3TWFzaywgRFdPUkQgZHd4KQp7CglIS0VZCWhLZXk7CglEV09SRAlkd0RhdGE7CglEV09SRAlkd0RhdGFTaXplID0gc2l6ZW9mIChEV09SRCk7CgoJVFJBQ0UoIiglcCAweCUwOGx4IDB4JTA4bHgpXG4iLGxwc2ZzLGR3TWFzaywgZHd4KTsKCQoJaWYgKFJlZ0NyZWF0ZUtleUV4QShIS0VZX0NVUlJFTlRfVVNFUiwgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxFeHBsb3JlclxcQWR2YW5jZWQiLAoJCQkJIDAsIDAsIDAsIEtFWV9BTExfQUNDRVNTLCAwLCAmaEtleSwgMCkpCgkgIHJldHVybjsKCQoJaWYgKCAoU1NGX1NIT1dFWFRFTlNJT05TICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiSGlkZUZpbGVFeHQiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZTaG93RXh0ZW5zaW9ucyAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX1NIT1dJTkZPVElQICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiU2hvd0luZm9UaXAiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZTaG93SW5mb1RpcCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX0RPTlRQUkVUVFlQQVRIICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiRG9udFByZXR0eVBhdGgiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZEb250UHJldHR5UGF0aCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX0hJREVJQ09OUyAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIkhpZGVJY29ucyIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+ZkhpZGVJY29ucyAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX01BUE5FVERSVkJVVFRPTiAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIk1hcE5ldERydkJ0biIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+Zk1hcE5ldERydkJ0biAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX1NIT1dBVFRSSUJDT0wgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJTaG93QXR0cmliQ29sIiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgkgIGxwc2ZzLT5mU2hvd0F0dHJpYkNvbCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCgoU1NGX1NIT1dBTExPQkpFQ1RTIHwgU1NGX1NIT1dTWVNGSUxFUykgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJIaWRkZW4iLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCXsgaWYgKGR3RGF0YSA9PSAwKQoJICB7IGlmIChTU0ZfU0hPV0FMTE9CSkVDVFMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd0FsbE9iamVjdHMgID0gMDsKCSAgICBpZiAoU1NGX1NIT1dTWVNGSUxFUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93U3lzRmlsZXMgID0gMDsKCSAgfQoJICBlbHNlIGlmIChkd0RhdGEgPT0gMSkKCSAgeyBpZiAoU1NGX1NIT1dBTExPQkpFQ1RTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dBbGxPYmplY3RzICA9IDE7CgkgICAgaWYgKFNTRl9TSE9XU1lTRklMRVMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd1N5c0ZpbGVzICA9IDA7CgkgIH0KCSAgZWxzZSBpZiAoZHdEYXRhID09IDIpCgkgIHsgaWYgKFNTRl9TSE9XQUxMT0JKRUNUUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93QWxsT2JqZWN0cyAgPSAwOwoJICAgIGlmIChTU0ZfU0hPV1NZU0ZJTEVTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dTeXNGaWxlcyAgPSAxOwoJICB9Cgl9CglSZWdDbG9zZUtleSAoaEtleSk7CgoJVFJBQ0UoIi0tIDB4JTA0eFxuIiwgKihXT1JEKilscHNmcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIU2hlbGxGb2xkZXJWaWV3X01lc3NhZ2UJCQlbU0hFTEwzMi43M10KICoKICogUEFSQU1FVEVSUwogKiAgaHduZENhYmluZXQgZGVmaW5lcyB0aGUgZXhwbG9yZXIgY2FiaW5ldCB3aW5kb3cgdGhhdCBjb250YWlucyB0aGUgCiAqICAgICAgICAgICAgICBzaGVsbHZpZXcgeW91IG5lZWQgdG8gY29tbXVuaWNhdGUgd2l0aAogKiAgdU1zZyAgICAgICAgaWRlbnRpZnlpbmcgdGhlIFNGVk0gZW51bSB0byBwZXJmb3JtCiAqICBsUGFyYW0KICoKICogTk9URVMKICogIE1lc3NhZ2UgU0ZWTV9SRUFSUkFOR0UgPSAxCiAqICAgIFRoaXMgbWVzc2FnZSBnZXRzIHNlbnQgd2hlbiBhIGNvbHVtbiBnZXRzIGNsaWNrZWQgdG8gaW5zdHJ1Y3QgdGhlCiAqICAgIHNoZWxsIHZpZXcgdG8gcmUtc29ydCB0aGUgaXRlbSBsaXN0LiBsUGFyYW0gaWRlbnRpZmllcyB0aGUgY29sdW1uCiAqICAgIHRoYXQgd2FzIGNsaWNrZWQuCiAqLwppbnQgV0lOQVBJIFNIU2hlbGxGb2xkZXJWaWV3X01lc3NhZ2UoSFdORCBod25kQ2FiaW5ldCxVSU5UIHVNc2csTFBBUkFNIGxQYXJhbSkKeyBGSVhNRSgiJTA0eCAlMDh1eCAlMDhseCBzdHViXG4iLGh3bmRDYWJpbmV0LHVNc2csbFBhcmFtKTsKICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogT2xlU3RyVG9TdHJOCQkJCQlbU0hFTEwzMi43OF0KICovCkJPT0wgV0lOQVBJIE9sZVN0clRvU3RyTkEgKExQU1RSIGxwU3RyLCBJTlQgblN0ciwgTFBDV1NUUiBscE9sZSwgSU5UIG5PbGUpIAp7CglUUkFDRSgiJXAgJXggJXMgJXhcbiIsIGxwU3RyLCBuU3RyLCBkZWJ1Z3N0cl93KGxwT2xlKSwgbk9sZSk7CglyZXR1cm4gV2lkZUNoYXJUb011bHRpQnl0ZSAoMCwgMCwgbHBPbGUsIG5PbGUsIGxwU3RyLCBuU3RyLCBOVUxMLCBOVUxMKTsKfQoKQk9PTCBXSU5BUEkgT2xlU3RyVG9TdHJOVyAoTFBXU1RSIGxwd1N0ciwgSU5UIG53U3RyLCBMUENXU1RSIGxwT2xlLCBJTlQgbk9sZSkgCnsKCVRSQUNFKCIlcCAleCAlcyAleFxuIiwgbHB3U3RyLCBud1N0ciwgZGVidWdzdHJfdyhscE9sZSksIG5PbGUpOwoKCWlmIChsc3RyY3B5blcgKCBscHdTdHIsIGxwT2xlLCBud1N0cikpCgl7IHJldHVybiBsc3RybGVuVyAobHB3U3RyKTsKCX0KCXJldHVybiAwOwp9CgpCT09MIFdJTkFQSSBPbGVTdHJUb1N0ck5BVyAoTFBWT0lEIGxwT3V0LCBJTlQgbk91dCwgTFBDVk9JRCBscEluLCBJTlQgbkluKSAKewoJaWYgKFZFUlNJT05fT3NJc1VuaWNvZGUoKSkKCSAgcmV0dXJuIE9sZVN0clRvU3RyTlcgKGxwT3V0LCBuT3V0LCBscEluLCBuSW4pOwoJcmV0dXJuIE9sZVN0clRvU3RyTkEgKGxwT3V0LCBuT3V0LCBscEluLCBuSW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTdHJUb09sZVN0ck4JCQkJCVtTSEVMTDMyLjc5XQogKiAgbHBNdWx0aSwgbk11bHRpLCBuV2lkZSBbSU5dCiAqICBscFdpZGUgW09VVF0KICovCkJPT0wgV0lOQVBJIFN0clRvT2xlU3RyTkEgKExQV1NUUiBscFdpZGUsIElOVCBuV2lkZSwgTFBDU1RSIGxwU3RyQSwgSU5UIG5TdHIpIAp7CglUUkFDRSgiJXAgJXggJXMgJXhcbiIsIGxwV2lkZSwgbldpZGUsIGxwU3RyQSwgblN0cik7CglyZXR1cm4gTXVsdGlCeXRlVG9XaWRlQ2hhciAoMCwgMCwgbHBTdHJBLCBuU3RyLCBscFdpZGUsIG5XaWRlKTsKfQpCT09MIFdJTkFQSSBTdHJUb09sZVN0ck5XIChMUFdTVFIgbHBXaWRlLCBJTlQgbldpZGUsIExQQ1dTVFIgbHBTdHJXLCBJTlQgblN0cikgCnsKCVRSQUNFKCIlcCAleCAlcyAleFxuIiwgbHBXaWRlLCBuV2lkZSwgZGVidWdzdHJfdyhscFN0clcpLCBuU3RyKTsKCglpZiAobHN0cmNweW5XIChscFdpZGUsIGxwU3RyVywgbldpZGUpKQoJeyByZXR1cm4gbHN0cmxlblcgKGxwV2lkZSk7Cgl9CglyZXR1cm4gMDsKfQoKQk9PTCBXSU5BUEkgU3RyVG9PbGVTdHJOQVcgKExQV1NUUiBscFdpZGUsIElOVCBuV2lkZSwgTFBDVk9JRCBscFN0ciwgSU5UIG5TdHIpIAp7CglpZiAoVkVSU0lPTl9Pc0lzVW5pY29kZSgpKQoJICByZXR1cm4gU3RyVG9PbGVTdHJOVyAobHBXaWRlLCBuV2lkZSwgbHBTdHIsIG5TdHIpOwoJcmV0dXJuIFN0clRvT2xlU3RyTkEgKGxwV2lkZSwgbldpZGUsIGxwU3RyLCBuU3RyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnaXN0ZXJTaGVsbEhvb2sJCQkJW1NIRUxMMzIuMTgxXQogKgogKiBQQVJBTVMKICogICAgICBod25kIFtJXSAgd2luZG93IGhhbmRsZQogKiAgICAgIHkgICAgW0ldICBmbGFnID8/Pz8KICogCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwp2b2lkIFdJTkFQSSBSZWdpc3RlclNoZWxsSG9vayhIV05EIGh3bmQsIERXT1JEIHkpIHsKICAgIEZJWE1FKCIoMHglMDh4LDB4JTA4bHgpOnN0dWIuXG4iLGh3bmQseSk7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2hlbGxNZXNzYWdlQm94VwkJCQlbU0hFTEwzMi4xODJdCiAqCiAqIEZvcm1hdCBhbmQgb3V0cHV0IGVycm9ybWVzc2FnZS4KICoKICogaWRUZXh0CXJlc291cmNlIElEIG9mIHRpdGxlIG9yIExQU1RSCiAqIGlkVGl0bGUJcmVzb3VyY2UgSUQgb2YgdGl0bGUgb3IgTFBTVFIKICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG9yZGluYWwKICovCklOVCBfX2NkZWNsClNoZWxsTWVzc2FnZUJveFcoSE1PRFVMRSBobW9kLEhXTkQgaHduZCxEV09SRCBpZFRleHQsRFdPUkQgaWRUaXRsZSxEV09SRCB1VHlwZSxMUENWT0lEIGFyZ2xpc3QpIAp7CVdDSEFSCXN6VGV4dFsxMDBdLHN6VGl0bGVbMTAwXSxzelRlbXBbMjU2XTsKCUxQV1NUUiAgIHBzelRleHQgPSAmc3pUZXh0WzBdLCBwc3pUaXRsZSA9ICZzelRpdGxlWzBdOwoJTFBWT0lECWFyZ3MgPSAmYXJnbGlzdDsKCglUUkFDRSgiKCUwOGx4LCUwOGx4LCUwOGx4LCUwOGx4LCUwOGx4LCVwKVxuIiwoRFdPUkQpaG1vZCwoRFdPUkQpaHduZCxpZFRleHQsaWRUaXRsZSx1VHlwZSxhcmdsaXN0KTsKCglpZiAoIUhJV09SRCAoaWRUaXRsZSkpCgkgIExvYWRTdHJpbmdXKGhtb2QsaWRUaXRsZSxwc3pUaXRsZSwxMDApOwoJZWxzZQoJICBwc3pUaXRsZSA9IChMUFdTVFIpaWRUaXRsZTsKCglpZiAoISBISVdPUkQgKGlkVGV4dCkpCgkgIExvYWRTdHJpbmdXKGhtb2QsaWRUZXh0LHBzelRleHQsMTAwKTsKCWVsc2UKCSAgcHN6VGV4dCA9IChMUFdTVFIpaWRUZXh0OwoKCUZvcm1hdE1lc3NhZ2VXKEZPUk1BVF9NRVNTQUdFX0ZST01fU1RSSU5HIHwgRk9STUFUX01FU1NBR0VfQVJHVU1FTlRfQVJSQVkgLHN6VGV4dCwwLDAsc3pUZW1wLDI1NixhcmdzKTsKCXJldHVybiBNZXNzYWdlQm94Vyhod25kLHN6VGVtcCxzelRpdGxlLHVUeXBlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2hlbGxNZXNzYWdlQm94QQkJCQlbU0hFTEwzMi4xODNdCiAqLwpJTlQgX19jZGVjbApTaGVsbE1lc3NhZ2VCb3hBKEhNT0RVTEUgaG1vZCxIV05EIGh3bmQsRFdPUkQgaWRUZXh0LERXT1JEIGlkVGl0bGUsRFdPUkQgdVR5cGUsTFBDVk9JRCBhcmdsaXN0KSAKewljaGFyCXN6VGV4dFsxMDBdLHN6VGl0bGVbMTAwXSxzelRlbXBbMjU2XTsKCUxQU1RSICAgcHN6VGV4dCA9ICZzelRleHRbMF0sIHBzelRpdGxlID0gJnN6VGl0bGVbMF07CglMUFZPSUQJYXJncyA9ICZhcmdsaXN0OwoKCVRSQUNFKCIoJTA4bHgsJTA4bHgsJTA4bHgsJTA4bHgsJTA4bHgsJXApXG4iLCAoRFdPUkQpaG1vZCwoRFdPUkQpaHduZCxpZFRleHQsaWRUaXRsZSx1VHlwZSxhcmdsaXN0KTsKCglpZiAoIUhJV09SRCAoaWRUaXRsZSkpCgkgIExvYWRTdHJpbmdBKGhtb2QsaWRUaXRsZSxwc3pUaXRsZSwxMDApOwoJZWxzZQoJICBwc3pUaXRsZSA9IChMUFNUUilpZFRpdGxlOwoKCWlmICghIEhJV09SRCAoaWRUZXh0KSkKCSAgTG9hZFN0cmluZ0EoaG1vZCxpZFRleHQscHN6VGV4dCwxMDApOwoJZWxzZQoJICBwc3pUZXh0ID0gKExQU1RSKWlkVGV4dDsKCglGb3JtYXRNZXNzYWdlQShGT1JNQVRfTUVTU0FHRV9GUk9NX1NUUklORyB8IEZPUk1BVF9NRVNTQUdFX0FSR1VNRU5UX0FSUkFZICxwc3pUZXh0LDAsMCxzelRlbXAsMjU2LGFyZ3MpOwoJcmV0dXJuIE1lc3NhZ2VCb3hBKGh3bmQsc3pUZW1wLHBzelRpdGxlLHVUeXBlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hSZXN0cmljdGVkCQkJCVtTSEVMTDMyLjEwMF0KICoKICogd2Fsa3MgdGhyb3VnaCBwb2xpY3kgdGFibGUsIHF1ZXJpZXMgPGFwcD4ga2V5LCA8dHlwZT4gdmFsdWUsIHJldHVybnMgCiAqIHF1ZXJpZWQgKERXT1JEKSB2YWx1ZSwgYW5kIGNhY2hlcyBpdCBiZXR3ZWVuIGNhbGxlZCB0byBTSEluaXRSZXN0cmljdGVkCiAqIHRvIHByZXZlbnQgdW5uZWNlc3NhcnkgcmVnaXN0cnkgYWNjZXNzLgogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKgogKiBSRUZFUkVOQ0VTOiAKICogICAgIE1TIFN5c3RlbSBQb2xpY3kgRWRpdG9yCiAqICAgICA5OExpdGUgMi4wICh3aGljaCB1c2VzIG1hbnkgb2YgdGhlc2UgcG9saWN5IGtleXMpIGh0dHA6Ly93d3cuOThsaXRlLm5ldC8KICogICAgICJUaGUgV2luZG93cyA5NSBSZWdpc3RyeSIsIGJ5IEpvaG4gV29yYW0sIDE5OTYgTUlTOiBQcmVzcwogKi8KRFdPUkQgV0lOQVBJIFNIUmVzdHJpY3RlZCAoRFdPUkQgcG9sKSB7CiAgICAgICAgY2hhciByZWdzdHJbMjU2XTsKCUhLRVkJeGhrZXk7CglEV09SRCAgIHJldHZhbCwgcG9saWR4LCBpLCBkYXRzaXplID0gNDsKCglUUkFDRSgiKCUwOGx4KVxuIixwb2wpOwoKCXBvbGlkeCA9IC0xOwoKCS8qIHNjYW4gdG8gc2VlIGlmIHdlIGtub3cgdGhpcyBwb2xpY3kgSUQgKi8KCWZvciAoaSA9IDA7IGkgPCBTSEVMTF9NQVhfUE9MSUNJRVM7IGkrKykKCXsKCSAgICAgaWYgKHBvbCA9PSBzaDMyX3BvbGljeV90YWJsZVtpXS5wb2xmbGFncykKCSAgICAgewoJICAgICAgICAgcG9saWR4ID0gaTsKCQkgYnJlYWs7CgkgICAgIH0KCX0KCglpZiAocG9saWR4ID09IC0xKQoJewoJICAgIC8qIHdlIGRvbid0IGtub3cgdGhpcyBwb2xpY3ksIHJldHVybiAwICovCgkgICAgVFJBQ0UoInVua25vd24gcG9saWN5OiAoJTA4bHgpXG4iLCBwb2wpOwoJCXJldHVybiAwOwoJfQoKCS8qIHdlIGhhdmUgYSBrbm93biBwb2xpY3kgKi8KICAgICAgCWxzdHJjcHlBKHJlZ3N0ciwgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxQb2xpY2llc1xcIik7Cglsc3RyY2F0QShyZWdzdHIsIHNoMzJfcG9saWN5X3RhYmxlW3BvbGlkeF0uYXBwc3RyKTsKCgkvKiBmaXJzdCBjaGVjayBpZiB0aGlzIHBvbGljeSBoYXMgYmVlbiBjYWNoZWQsIHJldHVybiBpdCBpZiBzbyAqLwoJaWYgKHNoMzJfcG9saWN5X3RhYmxlW3BvbGlkeF0uY2FjaGUgIT0gU0hFTExfTk9fUE9MSUNZKQoJewoJICAgIHJldHVybiBzaDMyX3BvbGljeV90YWJsZVtwb2xpZHhdLmNhY2hlOwoJfQoKCS8qIHJldHVybiAwIGFuZCBkb24ndCBzZXQgdGhlIGNhY2hlIGlmIGFueSByZWdpc3RyeSBlcnJvcnMgb2NjdXIgKi8KCXJldHZhbCA9IDA7CglpZiAoUmVnT3BlbktleUEoSEtFWV9DVVJSRU5UX1VTRVIsIHJlZ3N0ciwgJnhoa2V5KSA9PSBFUlJPUl9TVUNDRVNTKQoJewoJICAgIGlmIChSZWdRdWVyeVZhbHVlRXhBKHhoa2V5LCBzaDMyX3BvbGljeV90YWJsZVtwb2xpZHhdLmtleXN0ciwgTlVMTCwgTlVMTCwgKExQQllURSkmcmV0dmFsLCAmZGF0c2l6ZSkgPT0gRVJST1JfU1VDQ0VTUykKCSAgICB7CgkgICAgICAgIHNoMzJfcG9saWN5X3RhYmxlW3BvbGlkeF0uY2FjaGUgPSByZXR2YWw7CgkgICAgfQoKCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKfQoKCXJldHVybiByZXR2YWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hJbml0UmVzdHJpY3RlZCAgICAgICAgICAgICAgICAgICAgICAgICBbU0hFTEwzMi4yNDRdCiAqCiAqIFdpbjk4KyBieS1vcmRpbmFsIG9ubHkgcm91dGluZSBjYWxsZWQgYnkgRXhwbG9yZXIgYW5kIE1TSUUgNCBhbmQgNS4KICogSW5pdHMgdGhlIHBvbGljeSBjYWNoZSB1c2VkIGJ5IFNIUmVzdHJpY3RlZCB0byBhdm9pZCBleGNlc3MKICogcmVnaXN0cnkgYWNjZXNzLgogKgogKiBJTlBVVFMKICogVHdvIGlucHV0czogb25lIGlzIGEgc3RyaW5nIG9yIE5VTEwuICBJZiBub24tTlVMTCB0aGUgcG9pbnRlcgogKiBzaG91bGQgcG9pbnQgdG8gYSBzdHJpbmcgY29udGFpbmluZyB0aGUgZm9sbG93aW5nIGV4YWN0IHRleHQ6CiAqICJTb2Z0d2FyZVxNaWNyb3NvZnRcV2luZG93c1xDdXJyZW50VmVyc2lvblxQb2xpY2llcyIuCiAqIFRoZSBvdGhlciBpbnB1dCBpcyB1bnVzZWQuCiAqCiAqIE5PVEVTCiAqIElmIHRoZSBpbnB1dCBpcyBub24tTlVMTCBhbmQgZG9lcyBub3QgcG9pbnQgdG8gYSBzdHJpbmcgY29udGFpbmluZwogKiB0aGF0IGV4YWN0IHRleHQgdGhlIHJvdXRpbmUgd2lsbCBkbyBub3RoaW5nLgogKgogKiBJZiB0aGUgdGV4dCBkb2VzIG1hdGNoIG9yIHRoZSBwb2ludGVyIGlzIE5VTEwsIHRoZW4gdGhlIHJvdXRpbmUKICogd2lsbCBpbml0IFNIUmVzdHJpY3RlZCgpJ3MgcG9saWN5IGNhY2hlIHRvIGFsbCAweGZmZmZmZmZmIGFuZAogKiByZXR1cm5zIDB4ZmZmZmZmZmYgYXMgd2VsbC4KICoKICogSSBoYXZlbid0IHlldCBydW4gaW50byBhbnl0aGluZyBjYWxsaW5nIHRoaXMgd2l0aCBpbnB1dHMgb3RoZXIgdGhhbgogKiAoTlVMTCwgTlVMTCksIHNvIEkgbWF5IGhhdmUgdGhlIGlucHV0cyByZXZlcnNlZC4KICovCgpCT09MIFdJTkFQSSBTSEluaXRSZXN0cmljdGVkKExQU1RSIGlucFJlZ0tleSwgTFBTVFIgcGFybTIpCnsKICAgICBpbnQgaTsKCiAgICAgVFJBQ0UoIiglcCwgJXApXG4iLCBpbnBSZWdLZXksIHBhcm0yKTsKCiAgICAgLyogZmlyc3QgY2hlY2sgLSBpZiBpbnB1dCBpcyBub24tTlVMTCBhbmQgcG9pbnRzIHRvIHRoZSBzZWNyZXQKICAgICAgICBrZXkgc3RyaW5nLCB0aGVuIHBhc3MuICBPdGhlcndpc2UgcmV0dXJuIDAuCiAgICAgKi8KCiAgICAgaWYgKGlucFJlZ0tleSAhPSAoTFBTVFIpTlVMTCkKICAgICB7CiAgICAgICAgIGlmIChsc3RyY21waUEoaW5wUmVnS2V5LCAiU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudFZlcnNpb25cXFBvbGljaWVzIikpCgkgewoJICAgICAvKiBkb2Vzbid0IG1hdGNoLCBmYWlsICovCgkgICAgIHJldHVybiAwOwoJIH0KICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoKICAgICAvKiBjaGVjayBwYXNzZWQsIGluaXQgYWxsIHBvbGljeSBjYWNoZSBlbnRyaWVzIHdpdGggU0hFTExfTk9fUE9MSUNZICovCiAgICAgZm9yIChpID0gMDsgaSA8IFNIRUxMX01BWF9QT0xJQ0lFUzsgaSsrKQogICAgIHsKICAgICAgICAgIHNoMzJfcG9saWN5X3RhYmxlW2ldLmNhY2hlID0gU0hFTExfTk9fUE9MSUNZOwogICAgIH0KCiAgICAgcmV0dXJuIFNIRUxMX05PX1BPTElDWTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hDcmVhdGVEaXJlY3RvcnkJCQkJW1NIRUxMMzIuMTY1XQogKgogKiBOT1RFUwogKiAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKiAgbm90IHN1cmUgYWJvdXQgTFBTRUNVUklUWV9BVFRSSUJVVEVTCiAqLwpEV09SRCBXSU5BUEkgU0hDcmVhdGVEaXJlY3RvcnkoTFBTRUNVUklUWV9BVFRSSUJVVEVTIHNlYyxMUENTVFIgcGF0aCkgewoJVFJBQ0UoIiglcCwlcyk6c3R1Yi5cbiIsc2VjLHBhdGgpOwoJaWYgKENyZWF0ZURpcmVjdG9yeUEocGF0aCxzZWMpKQoJCXJldHVybiBUUlVFOwoJLyogU0hDaGFuZ2VOb3RpZnkoOCwxLHBhdGgsMCk7ICovCglyZXR1cm4gRkFMU0U7CiNpZiAwCglpZiAoU0hFTEwzMl83OShwYXRoLChMUFZPSUQpeCkpCgkJcmV0dXJuIDA7CglGSVhNRSgiKCUwOGx4LCVzKTpzdHViLlxuIix4LHBhdGgpOwoJcmV0dXJuIDA7CiNlbmRpZgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEZyZWUJCQkJCVtTSEVMTDMyLjE5NV0KICoKICogTk9URVMKICogICAgIGZyZWVfcHRyKCkgLSBmcmVlcyBtZW1vcnkgdXNpbmcgSU1hbGxvYwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KLyojZGVmaW5lIE1FTV9ERUJVRyAxKi8KRFdPUkQgV0lOQVBJIFNIRnJlZShMUFZPSUQgeCkgCnsKI2lmZGVmIE1FTV9ERUJVRwoJV09SRCBsZW4gPSAqKExQV09SRCkoeC0yKTsKCglpZiAoICooTFBXT1JEKSh4K2xlbikgIT0gMHg3Mzg0KQoJICBFUlIoIk1BR0lDMiFcbiIpOwoKCWlmICggKCooTFBXT1JEKSh4LTQpKSAhPSAweDgyNzEpCgkgIEVSUigiTUFHSUMxIVxuIik7CgllbHNlCgkgIG1lbXNldCh4LTQsIDB4ZGUsIGxlbis2KTsKCglUUkFDRSgiJXAgbGVuPSV1XG4iLHgsIGxlbik7CgoJeCAtPSA0OwojZWxzZQoJVFJBQ0UoIiVwXG4iLHgpOwojZW5kaWYKCXJldHVybiBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCB4KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hBbGxvYwkJCQkJW1NIRUxMMzIuMTk2XQogKgogKiBOT1RFUwogKiAgICAgdm9pZCAqdGFza19hbGxvYyhEV09SRCBsZW4pLCB1c2VzIFNITWFsbG9jIGFsbG9jYXRvcgogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KTFBWT0lEIFdJTkFQSSBTSEFsbG9jKERXT1JEIGxlbikgCnsKCUxQQllURSByZXQ7CgojaWZkZWYgTUVNX0RFQlVHCglyZXQgPSAoTFBWT0lEKSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLGxlbis2KTsKI2Vsc2UKCXJldCA9IChMUFZPSUQpIEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsbGVuKTsKI2VuZGlmCgojaWZkZWYgTUVNX0RFQlVHCgkqKExQV09SRCkocmV0KSA9IDB4ODI3MTsKCSooTFBXT1JEKShyZXQrMikgPSAoV09SRClsZW47CgkqKExQV09SRCkocmV0KzQrbGVuKSA9IDB4NzM4NDsKCXJldCArPSA0OwoJbWVtc2V0KHJldCwgMHhkZiwgbGVuKTsKI2VuZGlmCglUUkFDRSgiJWx1IGJ5dGVzIGF0ICVwXG4iLGxlbiwgcmV0KTsKCXJldHVybiAoTFBWT0lEKXJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hSZWdpc3RlckRyYWdEcm9wCQkJCVtTSEVMTDMyLjg2XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KRFdPUkQgV0lOQVBJIFNIUmVnaXN0ZXJEcmFnRHJvcChIV05EIGhXbmQsSURyb3BUYXJnZXQgKiBwRHJvcFRhcmdldCkgCnsKCUZJWE1FKCIoMHglMDh4LCVwKTpzdHViLlxuIiwgaFduZCwgcERyb3BUYXJnZXQpOwoJcmV0dXJuICAgICBSZWdpc3RlckRyYWdEcm9wKGhXbmQsIHBEcm9wVGFyZ2V0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hSZXZva2VEcmFnRHJvcAkJCQlbU0hFTEwzMi44N10KICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG9yZGluYWwKICovCkRXT1JEIFdJTkFQSSBTSFJldm9rZURyYWdEcm9wKERXT1JEIHgpIHsKICAgIEZJWE1FKCIoMHglMDhseCk6c3R1Yi5cbiIseCk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hEb0RyYWdEcm9wCQkJCQlbU0hFTEwzMi44OF0KICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG9yZGluYWwKICovCkRXT1JEIFdJTkFQSSBTSERvRHJhZ0Ryb3AoRFdPUkQgdSwgRFdPUkQgdiwgRFdPUkQgdywgRFdPUkQgeCwgRFdPUkQgeSwgRFdPUkQgeikgewogICAgRklYTUUoIigweCUwOGx4IDB4JTA4bHggMHglMDhseCAweCUwOGx4IDB4JTA4bHggMHglMDhseCk6c3R1Yi5cbiIsdSx2LHcseCx5LHopOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJ1bkZpbGVEbGcJCQkJCVtTSEVMTDMyLjYxXQogKgogKiBOT1RFUwogKiAgICAgT3JpZ2luYWwgbmFtZTogUnVuRmlsZURsZyAoZXhwb3J0ZWQgYnkgb3JkaW5hbCkKICovCkRXT1JEIFdJTkFQSQpSdW5GaWxlRGxnIChIV05EIGh3bmRPd25lciwgRFdPUkQgZHdQYXJhbTEsIERXT1JEIGR3UGFyYW0yLAoJICAgIExQU1RSIGxwc3pUaXRsZSwgTFBTVFIgbHBzelByb21wdCwgVUlOVCB1RmxhZ3MpCnsKICAgIEZJWE1FKCIoMHglMDh4IDB4JWx4IDB4JWx4IFwiJXNcIiBcIiVzXCIgMHgleCk6c3R1Yi5cbiIsCgkgICBod25kT3duZXIsIGR3UGFyYW0xLCBkd1BhcmFtMiwgbHBzelRpdGxlLCBscHN6UHJvbXB0LCB1RmxhZ3MpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEV4aXRXaW5kb3dzRGlhbG9nCQkJCVtTSEVMTDMyLjYwXQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8Kdm9pZCBXSU5BUEkgRXhpdFdpbmRvd3NEaWFsb2cgKEhXTkQgaFduZE93bmVyKQp7CglUUkFDRSgiKDB4JTA4eClcbiIsIGhXbmRPd25lcik7CglpZiAoTWVzc2FnZUJveEEoIGhXbmRPd25lciwgIkRvIHlvdSB3YW50IHRvIGV4aXQgV0lORT8iLCAiU2h1dGRvd24iLCBNQl9ZRVNOT3xNQl9JQ09OUVVFU1RJT04pID09IElET0spCgl7IFNlbmRNZXNzYWdlQSAoIGhXbmRPd25lciwgV01fUVVJVCwgMCwgMCk7Cgl9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFycmFuZ2VXaW5kb3dzCQkJCVtTSEVMTDMyLjE4NF0KICogCiAqLwpEV09SRCBXSU5BUEkKQXJyYW5nZVdpbmRvd3MgKERXT1JEIGR3UGFyYW0xLCBEV09SRCBkd1BhcmFtMiwgRFdPUkQgZHdQYXJhbTMsCgkJRFdPUkQgZHdQYXJhbTQsIERXT1JEIGR3UGFyYW01KQp7CiAgICBGSVhNRSgiKDB4JWx4IDB4JWx4IDB4JWx4IDB4JWx4IDB4JWx4KTpzdHViLlxuIiwKCSAgIGR3UGFyYW0xLCBkd1BhcmFtMiwgZHdQYXJhbTMsIGR3UGFyYW00LCBkd1BhcmFtNSk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2lnbmFsRmlsZU9wZW4JCQkJW1NIRUxMMzIuMTAzXQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KRFdPUkQgV0lOQVBJClNpZ25hbEZpbGVPcGVuIChEV09SRCBkd1BhcmFtMSkKewogICAgRklYTUUoIigweCUwOGx4KTpzdHViLlxuIiwgZHdQYXJhbTEpOwoKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFkZFRvUmVjZW50RG9jcwkJCQlbU0hFTEwzMi4yMzRdCiAqCiAqIFBBUkFNRVRFUlMKICogICB1RmxhZ3MgIFtJTl0gU0hBUkRfUEFUSCBvciBTSEFSRF9QSURMCiAqICAgcHYgICAgICBbSU5dIHN0cmluZyBvciBwaWRsLCBOVUxMIGNsZWFycyB0aGUgbGlzdAogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgbmFtZQogKi8KRFdPUkQgV0lOQVBJIFNIQWRkVG9SZWNlbnREb2NzIChVSU5UIHVGbGFncyxMUENWT0lEIHB2KSAgIAp7IGlmIChTSEFSRF9QSURMPT11RmxhZ3MpCiAgeyBGSVhNRSgiKDB4JTA4eCxwaWRsPSVwKTpzdHViLlxuIiwgdUZsYWdzLHB2KTsKCX0KCWVsc2UKCXsgRklYTUUoIigweCUwOHgsJXMpOnN0dWIuXG4iLCB1RmxhZ3MsKGNoYXIqKXB2KTsKCX0KICByZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEZpbGVPcGVyYXRpb24JCQkJW1NIRUxMMzIuMjQyXQogKgogKi8KRFdPUkQgV0lOQVBJIFNIRmlsZU9wZXJhdGlvbkFXKERXT1JEIHgpCnsJRklYTUUoIjB4JTA4bHggc3R1YlxuIix4KTsKCXJldHVybiAwOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGaWxlT3BlcmF0aW9uQQkJCQlbU0hFTEwzMi4yNDNdCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBuYW1lCiAqLwpEV09SRCBXSU5BUEkgU0hGaWxlT3BlcmF0aW9uQSAoTFBTSEZJTEVPUFNUUlVDVEEgbHBGaWxlT3ApICAgCnsgRklYTUUoIiglcCk6c3R1Yi5cbiIsIGxwRmlsZU9wKTsKICByZXR1cm4gMTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEZpbGVPcGVyYXRpb25XCQkJCVtTSEVMTDMyLjI0NF0KICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG5hbWUKICovCkRXT1JEIFdJTkFQSSBTSEZpbGVPcGVyYXRpb25XIChMUFNIRklMRU9QU1RSVUNUVyBscEZpbGVPcCkgICAKeyBGSVhNRSgiKCVwKTpzdHViLlxuIiwgbHBGaWxlT3ApOwogIHJldHVybiAxOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENoYW5nZU5vdGlmeQkJCQlbU0hFTEwzMi4yMzldCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBuYW1lCiAqLwpEV09SRCBXSU5BUEkgU0hDaGFuZ2VOb3RpZnkgKAogICAgSU5UICAgd0V2ZW50SWQsICAvKiBbSU5dIGZsYWdzIHRoYXQgc3BlY2lmaWVzIHRoZSBldmVudCovCiAgICBVSU5UICB1RmxhZ3MsICAgLyogW0lOXSB0aGUgbWVhbmluZyBvZiBkd0l0ZW1bMXwyXSovCgkJTFBDVk9JRCBkd0l0ZW0xLAoJCUxQQ1ZPSUQgZHdJdGVtMikKeyBGSVhNRSgiKDB4JTA4eCwweCUwOHV4LCVwLCVwKTpzdHViLlxuIiwgd0V2ZW50SWQsdUZsYWdzLGR3SXRlbTEsZHdJdGVtMik7CiAgcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hDcmVhdGVTaGVsbEZvbGRlclZpZXdFeAkJCVtTSEVMTDMyLjE3NF0KICoKICogTk9URVMKICogIHNlZSBJU2hlbGxGb2xkZXI6OkNyZWF0ZVZpZXdPYmplY3QKICovCkhSRVNVTFQgV0lOQVBJIFNIQ3JlYXRlU2hlbGxGb2xkZXJWaWV3RXgoCiAgTFBTSEVMTFZJRVdEQVRBIHBzdmNiaSwgLypbaW4gXSBzaGVsbHRlbXBsYXRlIHN0cnVjdCovCiAgTFBWT0lEKiBwcHYpICAgICAgICAgICAgLypbb3V0XSBJU2hlbGxWaWV3IHBvaW50ZXIqLwp7CglJU2hlbGxWaWV3ICogcHNmOwoJSFJFU1VMVCBoUmVzOwoJCglUUkFDRSgic2Y9JXAgcGlkbD0lcCBjYj0lcCBtb2RlPTB4JTA4bHggcGFybT0weCUwOGx4XG4iLCAKCSAgcHN2Y2JpLT5wU2hlbGxGb2xkZXIsIHBzdmNiaS0+cGlkbCwgcHN2Y2JpLT5wQ2FsbEJhY2ssIHBzdmNiaS0+dmlld21vZGUsIHBzdmNiaS0+ZHdVc2VyUGFyYW0pOwoKCXBzZiA9IElTaGVsbFZpZXdfQ29uc3RydWN0b3IocHN2Y2JpLT5wU2hlbGxGb2xkZXIpOwoJCglpZiAoIXBzZikKCSAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgoJSVNoZWxsVmlld19BZGRSZWYocHNmKTsKCWhSZXMgPSBJU2hlbGxWaWV3X1F1ZXJ5SW50ZXJmYWNlKHBzZiwgJklJRF9JU2hlbGxWaWV3LCAoTFBWT0lEICopcHB2KTsKCUlTaGVsbFZpZXdfUmVsZWFzZShwc2YpOwoKCXJldHVybiBoUmVzOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBTSFdpbkhlbHAJCQkJCVtTSEVMTDMyLjEyN10KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIV2luSGVscCAoRFdPUkQgdiwgRFdPUkQgdywgRFdPUkQgeCwgRFdPUkQgeikKewlGSVhNRSgiMHglMDhseCAweCUwOGx4IDB4JTA4bHggMHglMDhseCBzdHViXG4iLHYsdyx4LHopOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIFNIUnVuQ29udHJvbFBhbmVsIFtTSEVMTDMyLjE2MV0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIUnVuQ29udHJvbFBhbmVsIChEV09SRCB4LCBEV09SRCB6KQp7CUZJWE1FKCIweCUwOGx4IDB4JTA4bHggc3R1YlxuIix4LHopOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2hlbGxFeGVjdXRlRXgJCQkJW1NIRUxMMzIuMjkxXQogKgogKi8KQk9PTCBXSU5BUEkgU2hlbGxFeGVjdXRlRXhBVyAoTFBWT0lEIHNlaSkKewlpZiAoVkVSU0lPTl9Pc0lzVW5pY29kZSgpKQoJICByZXR1cm4gU2hlbGxFeGVjdXRlRXhXIChzZWkpOwoJcmV0dXJuIFNoZWxsRXhlY3V0ZUV4QSAoc2VpKTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTaGVsbEV4ZWN1dGVFeEEJCQkJW1NIRUxMMzIuMjkyXQogKgogKi8KQk9PTCBXSU5BUEkgU2hlbGxFeGVjdXRlRXhBIChMUFNIRUxMRVhFQ1VURUlORk9BIHNlaSkKeyAJQ0hBUiBzekFwcGxpY2F0aW9uTmFtZVtNQVhfUEFUSF0sc3pDb21tYW5kbGluZVtNQVhfUEFUSF0sc3pQaWRsWzIwXTsKCUxQU1RSIHBvczsKCWludCBnYXAsIGxlbjsKCVNUQVJUVVBJTkZPQSAgc3RhcnR1cGluZm87CglQUk9DRVNTX0lORk9STUFUSU9OIHByb2Nlc3NpbmZvcm1hdGlvbjsKCQkJCglXQVJOKCJtYXNrPTB4JTA4bHggaHduZD0weCUwNHggdmVyYj0lcyBmaWxlPSVzIHBhcm09JXMgZGlyPSVzIHNob3c9MHglMDh4IGNsYXNzPSVzIGluY29tcGxldGVcbiIsCgkJc2VpLT5mTWFzaywgc2VpLT5od25kLCBzZWktPmxwVmVyYiwgc2VpLT5scEZpbGUsCgkJc2VpLT5scFBhcmFtZXRlcnMsIHNlaS0+bHBEaXJlY3RvcnksIHNlaS0+blNob3csIAoJCShzZWktPmZNYXNrICYgU0VFX01BU0tfQ0xBU1NOQU1FKSA/IHNlaS0+bHBDbGFzcyA6ICJub3QgdXNlZCIpOwoKCVplcm9NZW1vcnkoc3pBcHBsaWNhdGlvbk5hbWUsTUFYX1BBVEgpOwoJaWYgKHNlaS0+bHBGaWxlKQoJICBzdHJjcHkoc3pBcHBsaWNhdGlvbk5hbWUsIHNlaS0+bHBGaWxlKTsKCQoJWmVyb01lbW9yeShzekNvbW1hbmRsaW5lLE1BWF9QQVRIKTsKCWlmIChzZWktPmxwUGFyYW1ldGVycykKCSAgc3RyY3B5KHN6Q29tbWFuZGxpbmUsIHNlaS0+bHBQYXJhbWV0ZXJzKTsKCQkJCglpZiAoc2VpLT5mTWFzayAmIChTRUVfTUFTS19DTEFTU0tFWSB8IFNFRV9NQVNLX0lOVk9LRUlETElTVCB8IFNFRV9NQVNLX0lDT04gfCBTRUVfTUFTS19IT1RLRVkgfAoJCQkgIFNFRV9NQVNLX05PQ0xPU0VQUk9DRVNTIHwgU0VFX01BU0tfQ09OTkVDVE5FVERSViB8IFNFRV9NQVNLX0ZMQUdfRERFV0FJVCB8CgkJCSAgU0VFX01BU0tfRE9FTlZTVUJTVCB8IFNFRV9NQVNLX0ZMQUdfTk9fVUkgfCBTRUVfTUFTS19VTklDT0RFIHwgCgkJCSAgU0VFX01BU0tfTk9fQ09OU09MRSB8IFNFRV9NQVNLX0FTWU5DT0sgfCBTRUVfTUFTS19ITU9OSVRPUiApKQoJeyBGSVhNRSgiZmxhZ3MgaWdub3JlZDogMHglMDhseFxuIiwgc2VpLT5mTWFzayk7Cgl9CgoJaWYgKHNlaS0+Zk1hc2sgJiBTRUVfTUFTS19DTEFTU05BTUUpCgl7IEhDUl9HZXRFeGVjdXRlQ29tbWFuZChzZWktPmxwQ2xhc3MsIChzZWktPmxwVmVyYikgPyBzZWktPmxwVmVyYiA6ICJvcGVuIiwgc3pDb21tYW5kbGluZSwgMjU2KTsJICAgIAoJfQoKCS8qIHByb2Nlc3MgdGhlIElETGlzdCAqLwoJaWYgKCAoc2VpLT5mTWFzayAmIFNFRV9NQVNLX0lOVk9LRUlETElTVCkgPT0gU0VFX01BU0tfSU5WT0tFSURMSVNUKSAvKjB4MGMqLwoJeyBTSEdldFBhdGhGcm9tSURMaXN0QSAoc2VpLT5scElETGlzdCxzekFwcGxpY2F0aW9uTmFtZSk7CgkgIFRSQUNFKCItLSBpZGxpc3Q9JXAgKCVzKVxuIiwgc2VpLT5scElETGlzdCwgc3pBcHBsaWNhdGlvbk5hbWUpOwoJfQoJZWxzZQoJeyBpZiAoc2VpLT5mTWFzayAmIFNFRV9NQVNLX0lETElTVCApCgkgIHsgLyogJUkgaXMgdGhlIGFkcmVzcyBvZiBhIGdsb2JhbCBpdGVtIElEKi8KCSAgICBwb3MgPSBzdHJzdHIoc3pDb21tYW5kbGluZSwgIiVJIik7CgkgICAgaWYgKHBvcykKCSAgICB7IEhHTE9CQUwgaG1lbSA9IFNIQWxsb2NTaGFyZWQgKCBzZWktPmxwSURMaXN0LCBJTEdldFNpemUoc2VpLT5scElETGlzdCksIDApOwoJICAgICAgc3ByaW50ZihzelBpZGwsIjolbGkiLChEV09SRClTSExvY2tTaGFyZWQoaG1lbSwwKSApOwoJICAgICAgU0hVbmxvY2tTaGFyZWQoaG1lbSk7CgkgICAgCgkgICAgICBnYXAgPSBzdHJsZW4oc3pQaWRsKTsKCSAgICAgIGxlbiA9IHN0cmxlbihwb3MpLTI7CgkgICAgICBtZW1tb3ZlKHBvcytnYXAscG9zKzIsbGVuKTsKCSAgICAgIG1lbWNweShwb3Msc3pQaWRsLGdhcCk7CgoJICAgIH0KCSAgfQoJfQoKCXBvcyA9IHN0cnN0cihzekNvbW1hbmRsaW5lLCAiLCVMIik7CS8qIGR1bm5vIHdoYXQgaXQgbWVhbnM6IGtpbGwgaXQqLwoJaWYgKHBvcykKCXsgbGVuID0gc3RybGVuKHBvcyktMjsKCSAgKnBvcz0weDA7CgkgIG1lbW1vdmUocG9zLHBvcyszLGxlbik7Cgl9CgoJVFJBQ0UoImV4ZWN1dGU6ICVzICVzXG4iLHN6QXBwbGljYXRpb25OYW1lLCBzekNvbW1hbmRsaW5lKTsKCglaZXJvTWVtb3J5KCZzdGFydHVwaW5mbyxzaXplb2YoU1RBUlRVUElORk9BKSk7CglzdGFydHVwaW5mby5jYiA9IHNpemVvZihTVEFSVFVQSU5GT0EpOwoKCXJldHVybiBDcmVhdGVQcm9jZXNzQShzekFwcGxpY2F0aW9uTmFtZVswXSA/IHN6QXBwbGljYXRpb25OYW1lOk5VTEwsCgkJCSBzekNvbW1hbmRsaW5lWzBdID8gc3pDb21tYW5kbGluZSA6IE5VTEwsCgkJCSBOVUxMLCBOVUxMLCBGQUxTRSwgMCwgCgkJCSBOVUxMLCBOVUxMLCAmc3RhcnR1cGluZm8sICZwcm9jZXNzaW5mb3JtYXRpb24pOwoJICAKCQp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNoZWxsRXhlY3V0ZUV4VwkJCQlbU0hFTEwzMi4yOTNdCiAqCiAqLwpCT09MIFdJTkFQSSBTaGVsbEV4ZWN1dGVFeFcgKExQU0hFTExFWEVDVVRFSU5GT1cgc2VpKQp7CVNIRUxMRVhFQ1VURUlORk9BIHNlaUE7CglEV09SRCByZXQ7CgoJVFJBQ0UoIiVwXG4iLCBzZWkpOwoKCW1lbWNweSgmc2VpQSwgc2VpLCBzaXplb2YoU0hFTExFWEVDVVRFSU5GT0EpKTsKCQogICAgICAgIGlmIChzZWktPmxwVmVyYikKCSAgc2VpQS5scFZlcmIgPSBIRUFQX3N0cmR1cFd0b0EoIEdldFByb2Nlc3NIZWFwKCksIDAsIHNlaS0+bHBWZXJiKTsKCiAgICAgICAgaWYgKHNlaS0+bHBGaWxlKQoJICBzZWlBLmxwRmlsZSA9IEhFQVBfc3RyZHVwV3RvQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2VpLT5scEZpbGUpOwoKICAgICAgICBpZiAoc2VpLT5scFBhcmFtZXRlcnMpCgkgIHNlaUEubHBQYXJhbWV0ZXJzID0gSEVBUF9zdHJkdXBXdG9BKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzZWktPmxwUGFyYW1ldGVycyk7CgoJaWYgKHNlaS0+bHBEaXJlY3RvcnkpCgkgIHNlaUEubHBEaXJlY3RvcnkgPSBIRUFQX3N0cmR1cFd0b0EoIEdldFByb2Nlc3NIZWFwKCksIDAsIHNlaS0+bHBEaXJlY3RvcnkpOwoKICAgICAgICBpZiAoKHNlaS0+Zk1hc2sgJiBTRUVfTUFTS19DTEFTU05BTUUpICYmIHNlaS0+bHBDbGFzcykKCSAgc2VpQS5scENsYXNzID0gSEVBUF9zdHJkdXBXdG9BKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzZWktPmxwQ2xhc3MpOwoJZWxzZQoJICBzZWlBLmxwQ2xhc3MgPSBOVUxMOwoJICAJICAKCXJldCA9IFNoZWxsRXhlY3V0ZUV4QSgmc2VpQSk7CgogICAgICAgIGlmIChzZWlBLmxwVmVyYikJSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIChMUFNUUikgc2VpQS5scFZlcmIgKTsKCWlmIChzZWlBLmxwRmlsZSkJSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIChMUFNUUikgc2VpQS5scEZpbGUgKTsKCWlmIChzZWlBLmxwUGFyYW1ldGVycykJSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIChMUFNUUikgc2VpQS5scFBhcmFtZXRlcnMgKTsKCWlmIChzZWlBLmxwRGlyZWN0b3J5KQlIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKExQU1RSKSBzZWlBLmxwRGlyZWN0b3J5ICk7CglpZiAoc2VpQS5scENsYXNzKQlIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKExQU1RSKSBzZWlBLmxwQ2xhc3MgKTsKCiAJcmV0dXJuIHJldDsKfQoKc3RhdGljIExQVU5LTk9XTiBTSEVMTDMyX0lFeHBsb3JlckludGVyZmFjZT0wOwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFNldEluc3RhbmNlRXhwbG9yZXIJCQlbU0hFTEwzMi4xNzZdCiAqCiAqIE5PVEVTCiAqICBTZXRzIHRoZSBpbnRlcmZhY2UKICovCkhSRVNVTFQgV0lOQVBJIFNIU2V0SW5zdGFuY2VFeHBsb3JlciAoTFBVTktOT1dOIGxwVW5rbm93bikKewlUUkFDRSgiJXBcbiIsIGxwVW5rbm93bik7CglTSEVMTDMyX0lFeHBsb3JlckludGVyZmFjZSA9IGxwVW5rbm93bjsKCXJldHVybiAoSFJFU1VMVCkgbHBVbmtub3duOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIR2V0SW5zdGFuY2VFeHBsb3JlcgkJCVtTSEVMTDMyLjI1Nl0KICoKICogTk9URVMKICogIGdldHMgdGhlIGludGVyZmFjZSBwb2ludGVyIG9mIHRoZSBleHBsb3JlciBhbmQgYSByZWZlcmVuY2UKICovCkhSRVNVTFQgV0lOQVBJIFNIR2V0SW5zdGFuY2VFeHBsb3JlciAoTFBVTktOT1dOICogbHBVbmtub3duKQp7CVRSQUNFKCIlcFxuIiwgbHBVbmtub3duKTsKCgkqbHBVbmtub3duID0gU0hFTEwzMl9JRXhwbG9yZXJJbnRlcmZhY2U7CgoJaWYgKCFTSEVMTDMyX0lFeHBsb3JlckludGVyZmFjZSkKCSAgcmV0dXJuIEVfRkFJTDsKCglJVW5rbm93bl9BZGRSZWYoU0hFTEwzMl9JRXhwbG9yZXJJbnRlcmZhY2UpOwoJcmV0dXJuIE5PRVJST1I7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGcmVlVW51c2VkTGlicmFyaWVzCQkJW1NIRUxMMzIuMTIzXQogKgogKiBOT1RFUwogKiAgZXhwb3J0ZWQgYnkgbmFtZQogKi8KSFJFU1VMVCBXSU5BUEkgU0hGcmVlVW51c2VkTGlicmFyaWVzICh2b2lkKQp7CUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBUUlVFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERBRF9TZXREcmFnSW1hZ2UJCQkJW1NIRUxMMzIuMTM2XQogKgogKiBOT1RFUwogKiAgZXhwb3J0ZWQgYnkgbmFtZQogKi8KSFJFU1VMVCBXSU5BUEkgREFEX1NldERyYWdJbWFnZSAoRFdPUkQgdSwgRFdPUkQgdikKeyBGSVhNRSgiMHglMDhseCAweCUwOGx4IHN0dWJcbiIsdSwgdik7CiAgcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX1Nob3dEcmFnSW1hZ2UJCQkJW1NIRUxMMzIuMTM3XQogKgogKiBOT1RFUwogKiAgZXhwb3J0ZWQgYnkgbmFtZQogKi8KSFJFU1VMVCBXSU5BUEkgREFEX1Nob3dEcmFnSW1hZ2UgKERXT1JEIHUpCnsgRklYTUUoIjB4JTA4bHggc3R1YlxuIix1KTsKICByZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJlZ0Nsb3NlS2V5CQkJW05UNC4wOlNIRUxMMzIuNTA1XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZWdDbG9zZUtleSAoSEtFWSBoa2V5KQp7CVRSQUNFKCIweCUwNHhcbiIsaGtleSk7CglyZXR1cm4gUmVnQ2xvc2VLZXkoIGhrZXkgKTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJlZ09wZW5LZXlBCQkJCVtTSEVMTDMyLjUwNl0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIUmVnT3BlbktleUEoSEtFWSBoS2V5LCBMUFNUUiBscFN1YktleSwgTFBIS0VZIHBoa1Jlc3VsdCkKewoJVFJBQ0UoIigweCUwOHgsICVzLCAlcClcbiIsIGhLZXksIGRlYnVnc3RyX2EobHBTdWJLZXkpLCBwaGtSZXN1bHQpOwoJcmV0dXJuIFJlZ09wZW5LZXlBKGhLZXksIGxwU3ViS2V5LCBwaGtSZXN1bHQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJlZ09wZW5LZXlXCQkJCVtOVDQuMDpTSEVMTDMyLjUwN10KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIUmVnT3BlbktleVcgKEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5KQp7CVdBUk4oIjB4JTA0eCAlcyAlcFxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkscmV0a2V5KTsKCXJldHVybiBSZWdPcGVuS2V5VyggaGtleSwgbHBzelN1YktleSwgcmV0a2V5ICk7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hSZWdRdWVyeVZhbHVlRXhBCQkJCVtTSEVMTDMyLjUwOV0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIUmVnUXVlcnlWYWx1ZUV4QSgKCUhLRVkgaGtleSwKCUxQU1RSIGxwVmFsdWVOYW1lLAoJTFBEV09SRCBscFJlc2VydmVkLAoJTFBEV09SRCBscFR5cGUsCglMUEJZVEUgbHBEYXRhLAoJTFBEV09SRCBscGNiRGF0YSkKewoJVFJBQ0UoIjB4JTA0eCAlcyAlcCAlcCAlcCAlcFxuIiwgaGtleSwgbHBWYWx1ZU5hbWUsIGxwUmVzZXJ2ZWQsIGxwVHlwZSwgbHBEYXRhLCBscGNiRGF0YSk7CglyZXR1cm4gUmVnUXVlcnlWYWx1ZUV4QSAoaGtleSwgbHBWYWx1ZU5hbWUsIGxwUmVzZXJ2ZWQsIGxwVHlwZSwgbHBEYXRhLCBscGNiRGF0YSk7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hSZWdRdWVyeVZhbHVlVwkJCQlbTlQ0LjA6U0hFTEwzMi41MTBdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFJlZ1F1ZXJ5VmFsdWVXIChIS0VZIGhrZXksIExQV1NUUiBscHN6U3ViS2V5LAoJCQkJIExQV1NUUiBscHN6RGF0YSwgTFBEV09SRCBscGNiRGF0YSApCnsJV0FSTigiMHglMDR4ICVzICVwICVwIHNlbWktc3R1YlxuIiwKCQloa2V5LCBkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLCBscHN6RGF0YSwgbHBjYkRhdGEpOwoJcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVXKCBoa2V5LCBscHN6U3ViS2V5LCBscHN6RGF0YSwgbHBjYkRhdGEgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hSZWdRdWVyeVZhbHVlRXhXCQkJCVtOVDQuMDpTSEVMTDMyLjUxMV0KICoKICogRklYTUUgCiAqICBpZiB0aGUgZGF0YXR5cGUgUkVHX0VYUEFORF9TWiB0aGVuIGV4cGFuZCB0aGUgc3RyaW5nIGFuZCBjaGFuZ2UKICogICpwZHdUeXBlIHRvIFJFR19TWi4gCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFJlZ1F1ZXJ5VmFsdWVFeFcgKEhLRVkgaGtleSwgTFBXU1RSIHBzelZhbHVlLCBMUERXT1JEIHBkd1Jlc2VydmVkLAoJCSBMUERXT1JEIHBkd1R5cGUsIExQVk9JRCBwdkRhdGEsIExQRFdPUkQgcGNiRGF0YSkKewlEV09SRCByZXQ7CglXQVJOKCIweCUwNHggJXMgJXAgJXAgJXAgJXAgc2VtaS1zdHViXG4iLAoJCWhrZXksIGRlYnVnc3RyX3cocHN6VmFsdWUpLCBwZHdSZXNlcnZlZCwgcGR3VHlwZSwgcHZEYXRhLCBwY2JEYXRhKTsKCXJldCA9IFJlZ1F1ZXJ5VmFsdWVFeFcgKCBoa2V5LCBwc3pWYWx1ZSwgcGR3UmVzZXJ2ZWQsIHBkd1R5cGUsIHB2RGF0YSwgcGNiRGF0YSk7CglyZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWFkQ2FiaW5ldFN0YXRlCQkJCVtOVCA0LjA6U0hFTEwzMi42NTFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBSZWFkQ2FiaW5ldFN0YXRlKERXT1JEIHUsIERXT1JEIHYpCnsJRklYTUUoIjB4JTA0bHggMHglMDRseCBzdHViXG4iLHUsdik7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBXcml0ZUNhYmluZXRTdGF0ZQkJCQlbTlQgNC4wOlNIRUxMMzIuNjUyXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgV3JpdGVDYWJpbmV0U3RhdGUoRFdPUkQgdSkKewlGSVhNRSgiMHglMDRseCBzdHViXG4iLHUpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRmlsZUljb25Jbml0IAkJCQlbU0hFTEwzMi42NjBdCiAqCiAqLwpCT09MIFdJTkFQSSBGaWxlSWNvbkluaXQoQk9PTCBiRnVsbEluaXQpCnsJRklYTUUoIiglcylcbiIsIGJGdWxsSW5pdCA/ICJ0cnVlIiA6ICJmYWxzZSIpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSXNVc2VyQWRtaW4JCQkJCVtOVCA0LjA6U0hFTEwzMi42ODBdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBJc1VzZXJBZG1pbih2b2lkKQp7CUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBUUlVFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFN0clJldFRvU3RyTgkJCQkJW1NIRUxMMzIuOTZdCiAqIAogKiBjb252ZXJ0cyBhIFNUUlJFVCB0byBhIG5vcm1hbCBzdHJpbmcKICoKICogTk9URVMKICogIHRoZSBwaWRsIGlzIGZvciBTVFJSRVQgT0ZGU0VUCiAqLwpIUkVTVUxUIFdJTkFQSSBTdHJSZXRUb0J1ZkEgKExQU1RSUkVUIHNyYywgTFBJVEVNSURMSVNUIHBpZGwsIExQU1RSIGRlc3QsIERXT1JEIGxlbikKewoJcmV0dXJuIFN0clJldFRvU3RyTkEoZGVzdCwgbGVuLCBzcmMsIHBpZGwpOwp9CgpIUkVTVUxUIFdJTkFQSSBTdHJSZXRUb1N0ck5BIChMUFZPSUQgZGVzdCwgRFdPUkQgbGVuLCBMUFNUUlJFVCBzcmMsIExQSVRFTUlETElTVCBwaWRsKQp7CglUUkFDRSgiZGVzdD0weCVwIGxlbj0weCVseCBzdHJyZXQ9MHglcCBwaWRsPSVwIHN0dWJcbiIsZGVzdCxsZW4sc3JjLHBpZGwpOwoKCXN3aXRjaCAoc3JjLT51VHlwZSkKCXsKCSAgY2FzZSBTVFJSRVRfV1NUUjoKCSAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3JjLT51LnBPbGVTdHIsIC0xLCAoTFBTVFIpZGVzdCwgbGVuLCBOVUxMLCBOVUxMKTsKCSAgICBTSEZyZWUoc3JjLT51LnBPbGVTdHIpOwoJICAgIGJyZWFrOwoKCSAgY2FzZSBTVFJSRVRfQ1NUUkE6CgkgICAgbHN0cmNweW5BKChMUFNUUilkZXN0LCBzcmMtPnUuY1N0ciwgbGVuKTsKCSAgICBicmVhazsKCgkgIGNhc2UgU1RSUkVUX09GRlNFVEE6CgkgICAgbHN0cmNweW5BKChMUFNUUilkZXN0LCAoKExQQ1NUUikmcGlkbC0+bWtpZCkrc3JjLT51LnVPZmZzZXQsIGxlbik7CgkgICAgYnJlYWs7CgoJICBkZWZhdWx0OgoJICAgIEZJWE1FKCJ1bmtub3duIHR5cGUhXG4iKTsKCSAgICBpZiAobGVuKQoJICAgIHsKCSAgICAgICooTFBTVFIpZGVzdCA9ICdcMCc7CgkgICAgfQoJICAgIHJldHVybihGQUxTRSk7Cgl9CglyZXR1cm4gU19PSzsKfQoKSFJFU1VMVCBXSU5BUEkgU3RyUmV0VG9CdWZXIChMUFNUUlJFVCBzcmMsIExQSVRFTUlETElTVCBwaWRsLCBMUFdTVFIgZGVzdCwgRFdPUkQgbGVuKQp7CglyZXR1cm4gU3RyUmV0VG9TdHJOVyhkZXN0LCBsZW4sIHNyYywgcGlkbCk7Cn0KCkhSRVNVTFQgV0lOQVBJIFN0clJldFRvU3RyTlcgKExQVk9JRCBkZXN0LCBEV09SRCBsZW4sIExQU1RSUkVUIHNyYywgTFBJVEVNSURMSVNUIHBpZGwpCnsKCVRSQUNFKCJkZXN0PTB4JXAgbGVuPTB4JWx4IHN0cnJldD0weCVwIHBpZGw9JXAgc3R1YlxuIixkZXN0LGxlbixzcmMscGlkbCk7CgoJc3dpdGNoIChzcmMtPnVUeXBlKQoJewoJICBjYXNlIFNUUlJFVF9XU1RSOgoJICAgIGxzdHJjcHluVygoTFBXU1RSKWRlc3QsIHNyYy0+dS5wT2xlU3RyLCBsZW4pOwoJICAgIFNIRnJlZShzcmMtPnUucE9sZVN0cik7CgkgICAgYnJlYWs7CgoJICBjYXNlIFNUUlJFVF9DU1RSQToKCSAgICBsc3RyY3B5bkF0b1coKExQV1NUUilkZXN0LCBzcmMtPnUuY1N0ciwgbGVuKTsKCSAgICBicmVhazsKCgkgIGNhc2UgU1RSUkVUX09GRlNFVEE6CgkgICAgaWYgKHBpZGwpCgkgICAgewoJICAgICAgbHN0cmNweW5BdG9XKChMUFdTVFIpZGVzdCwgKChMUENTVFIpJnBpZGwtPm1raWQpK3NyYy0+dS51T2Zmc2V0LCBsZW4pOwoJICAgIH0KCSAgICBicmVhazsKCgkgIGRlZmF1bHQ6CgkgICAgRklYTUUoInVua25vd24gdHlwZSFcbiIpOwoJICAgIGlmIChsZW4pCgkgICAgeyAqKExQU1RSKWRlc3QgPSAnXDAnOwoJICAgIH0KCSAgICByZXR1cm4oRkFMU0UpOwoJfQoJcmV0dXJuIFNfT0s7Cn0KSFJFU1VMVCBXSU5BUEkgU3RyUmV0VG9TdHJOQVcgKExQVk9JRCBkZXN0LCBEV09SRCBsZW4sIExQU1RSUkVUIHNyYywgTFBJVEVNSURMSVNUIHBpZGwpCnsKCWlmKFZFUlNJT05fT3NJc1VuaWNvZGUoKSkKCSAgcmV0dXJuIFN0clJldFRvU3RyTlcgKGRlc3QsIGxlbiwgc3JjLCBwaWRsKTsKCXJldHVybiBTdHJSZXRUb1N0ck5BIChkZXN0LCBsZW4sIHNyYywgcGlkbCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFN0ckNoclcJCQkJCVtOVCA0LjA6U0hFTEwzMi42NTFdCiAqCiAqLwpMUFdTVFIgV0lOQVBJIFN0ckNoclcgKExQV1NUUiBzdHIsIFdDSEFSIHggKQp7CUxQV1NUUiBwdHI9c3RyOwoJCglUUkFDRSgiJXMgMHglMDR4XG4iLGRlYnVnc3RyX3coc3RyKSx4KTsKCWRvIAoJeyAgaWYgKCpwdHI9PXgpCgkgICB7IHJldHVybiBwdHI7CgkgICB9CgkgICBwdHIrKzsKCX0gd2hpbGUgKCpwdHIpOwoJcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFN0ckNtcE5JVwkJCQkJW05UIDQuMDpTSEVMTDMyLipdCiAqCiAqLwpJTlQgV0lOQVBJIFN0ckNtcE5JVyAoIExQV1NUUiB3c3RyMSwgTFBXU1RSIHdzdHIyLCBJTlQgbGVuKQp7CUZJWE1FKCIlcyAlcyAlaSBzdHViXG4iLCBkZWJ1Z3N0cl93KHdzdHIxKSxkZWJ1Z3N0cl93KHdzdHIyKSxsZW4pOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQWxsb2NTaGFyZWQJCQkJW1NIRUxMMzIuNTIwXQogKgogKiBOT1RFUwogKiAgcGFyYW1ldGVyMSBpcyByZXR1cm4gdmFsdWUgZnJvbSBIZWFwQWxsb2MKICogIHBhcmFtZXRlcjIgaXMgZXF1YWwgdG8gdGhlIHNpemUgYWxsb2NhdGVkIHdpdGggSGVhcEFsbG9jCiAqICBwYXJhbWV0ZXIzIGlzIHJldHVybiB2YWx1ZSBmcm9tIEdldEN1cnJlbnRQcm9jZXNzSWQKICoKICogIHRoZSByZXR1cm4gdmFsdWUgaXMgcG9zdGVkIGFzIGxQYXJhbSB3aXRoIDB4NDAyIChXTV9VU0VSKzIpIHRvIHNvbWV3aGVyZQogKiAgV01fVVNFUisyIGNvdWxkIGJlIHRoZSB1bmRvY3VtZW50ZWQgQ1dNX1NFVFBBVEgKICogIHRoZSBhbGxvY2F0ZWQgbWVtb3J5IGNvbnRhaW5zIGEgcGlkbAogKi8KSEdMT0JBTCBXSU5BUEkgU0hBbGxvY1NoYXJlZChMUFZPSUQgcHNyYywgRFdPUkQgc2l6ZSwgRFdPUkQgcHJvY0lEKQp7CUhHTE9CQUwgaG1lbTsKCUxQVk9JRCBwbWVtOwoJCglUUkFDRSgicHRyPSVwIHNpemU9MHglMDRseCBwcm9jSUQ9MHglMDRseFxuIixwc3JjLHNpemUscHJvY0lEKTsKCWhtZW0gPSBHbG9iYWxBbGxvYyhHTUVNX0ZJWEVELCBzaXplKTsKCWlmICghaG1lbSkKCSAgcmV0dXJuIDA7CgkKCXBtZW0gPSAgR2xvYmFsTG9jayAoaG1lbSk7CgoJaWYgKCEgcG1lbSkKCSAgcmV0dXJuIDA7CgkgIAoJbWVtY3B5IChwbWVtLCBwc3JjLCBzaXplKTsKCUdsb2JhbFVubG9jayhobWVtKTsgCglyZXR1cm4gaG1lbTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSExvY2tTaGFyZWQJCQkJCVtTSEVMTDMyLjUyMV0KICoKICogTk9URVMKICogIHBhcmFtZXRlcjEgaXMgcmV0dXJuIHZhbHVlIGZyb20gU0hBbGxvY1NoYXJlZAogKiAgcGFyYW1ldGVyMiBpcyByZXR1cm4gdmFsdWUgZnJvbSBHZXRDdXJyZW50UHJvY2Vzc0lkCiAqICB0aGUgcmVjZWl2ZXIgb2YgKFdNX1VTRVIrMikgdHJ5cyB0byBsb2NrIHRoZSBIQU5ETEUgKD8pIAogKiAgdGhlIHJldHVybnZhbHVlIHNlZW1zIHRvIGJlIGEgbWVtb3J5YWRyZXNzCiAqLwpMUFZPSUQgV0lOQVBJIFNITG9ja1NoYXJlZChIQU5ETEUgaG1lbSwgRFdPUkQgcHJvY0lEKQp7CVRSQUNFKCJoYW5kbGU9MHglMDR4IHByb2NJRD0weCUwNGx4XG4iLGhtZW0scHJvY0lEKTsKCXJldHVybiBHbG9iYWxMb2NrKGhtZW0pOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIVW5sb2NrU2hhcmVkCQkJCVtTSEVMTDMyLjUyMl0KICoKICogTk9URVMKICogIHBhcmFtZXRlcjEgaXMgcmV0dXJuIHZhbHVlIGZyb20gU0hMb2NrU2hhcmVkCiAqLwpCT09MIFdJTkFQSSBTSFVubG9ja1NoYXJlZChIQU5ETEUgcG1lbSkKewlUUkFDRSgiaGFuZGxlPTB4JTA0eFxuIixwbWVtKTsKCXJldHVybiBHbG9iYWxVbmxvY2socG1lbSk7IAp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRnJlZVNoYXJlZAkJCQkJW1NIRUxMMzIuNTIzXQogKgogKiBOT1RFUwogKiAgcGFyYW1ldGVyMSBpcyByZXR1cm4gdmFsdWUgZnJvbSBTSEFsbG9jU2hhcmVkCiAqICBwYXJhbWV0ZXIyIGlzIHJldHVybiB2YWx1ZSBmcm9tIEdldEN1cnJlbnRQcm9jZXNzSWQKICovCkhBTkRMRSBXSU5BUEkgU0hGcmVlU2hhcmVkKEhBTkRMRSBobWVtLCBEV09SRCBwcm9jSUQpCnsJVFJBQ0UoImhhbmRsZT0weCUwNHggMHglMDRseFxuIixobWVtLHByb2NJRCk7CglyZXR1cm4gR2xvYmFsRnJlZShobWVtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2V0QXBwU3RhcnRpbmdDdXJzb3IJCQkJW1NIRUxMMzIuOTldCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTZXRBcHBTdGFydGluZ0N1cnNvcihIV05EIHUsIERXT1JEIHYpCnsJRklYTUUoImh3bmQ9MHglMDR4IDB4JTA0bHggc3R1YlxuIix1LHYgKTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNITG9hZE9MRQkJCQkJW1NIRUxMMzIuMTUxXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hMb2FkT0xFKERXT1JEIHUpCnsJRklYTUUoIjB4JTA0bHggc3R1YlxuIix1KTsKCXJldHVybiBTX09LOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERyaXZlVHlwZQkJCQkJW1NIRUxMMzIuNjRdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBEcml2ZVR5cGUoRFdPUkQgdSkKewlGSVhNRSgiMHglMDRseCBzdHViXG4iLHUpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hBYm9ydEludm9rZUNvbW1hbmQJCQkJW1NIRUxMMzIuMTk4XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hBYm9ydEludm9rZUNvbW1hbmQodm9pZCkKewlGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gMTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSE91dE9mTWVtb3J5TWVzc2FnZUJveAkJCVtTSEVMTDMyLjEyNl0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIT3V0T2ZNZW1vcnlNZXNzYWdlQm94KERXT1JEIHUsIERXT1JEIHYsIERXT1JEIHcpCnsJRklYTUUoIjB4JTA0bHggMHglMDRseCAweCUwNGx4IHN0dWJcbiIsdSx2LHcpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGbHVzaENsaXBib2FyZAkJCQlbU0hFTEwzMi4xMjFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEZsdXNoQ2xpcGJvYXJkKHZvaWQpCnsJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIDE7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU3RyUkNockEJCQkJCVtTSEVMTDMyLjM0Nl0KICoKICovCkxQU1RSIFdJTkFQSSBTdHJSQ2hyQShMUENTVFIgbHBTdGFydCwgTFBDU1RSIGxwRW5kLCBEV09SRCB3TWF0Y2gpCnsKICAgIAlpZiAoIWxwU3RhcnQpCgkgICAgcmV0dXJuIE5VTEw7CgoJLyogaWYgdGhlIGVuZCBub3QgZ2l2ZW4sIHNlYXJjaCovCglpZiAoIWxwRW5kKQoJeyBscEVuZD1scFN0YXJ0OwoJICB3aGlsZSAoKmxwRW5kKSAKCSAgICBscEVuZCsrOwoJfQoKCWZvciAoLS1scEVuZDtscFN0YXJ0IDw9IGxwRW5kOyBscEVuZC0tKQoJICAgIGlmICgqbHBFbmQ9PShjaGFyKXdNYXRjaCkKCQlyZXR1cm4gKExQU1RSKWxwRW5kOwoKCXJldHVybiBOVUxMOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFN0clJDaHJXCQkJCQlbU0hFTEwzMi4zMjBdCiAqCiAqLwpMUFdTVFIgV0lOQVBJIFN0clJDaHJXKExQV1NUUiBscFN0YXJ0LCBMUFdTVFIgbHBFbmQsIERXT1JEIHdNYXRjaCkKewlMUFdTVFIgd3B0cj1OVUxMOwoJVFJBQ0UoIiVzICVzIDB4JTA0eFxuIixkZWJ1Z3N0cl93KGxwU3RhcnQpLGRlYnVnc3RyX3cobHBFbmQpLCAoV0NIQVIpd01hdGNoICk7CgoJLyogaWYgdGhlIGVuZCBub3QgZ2l2ZW4sIHNlYXJjaCovCglpZiAoIWxwRW5kKQoJeyBscEVuZD1scFN0YXJ0OwoJICB3aGlsZSAoKmxwRW5kKSAKCSAgICBscEVuZCsrOwoJfQoKCWRvIAoJeyBpZiAoKmxwU3RhcnQ9PShXQ0hBUil3TWF0Y2gpCgkgICAgd3B0ciA9IGxwU3RhcnQ7CgkgIGxwU3RhcnQrKzsgIAoJfSB3aGlsZSAoIGxwU3RhcnQ8PWxwRW5kICk7IAoJcmV0dXJuIHdwdHI7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBTdHJGb3JtYXRCeXRlU2l6ZQkJCQlbU0hMV0FQSV0KKi8KTFBTVFIgV0lOQVBJIFN0ckZvcm1hdEJ5dGVTaXplQSAoIERXT1JEIGR3LCBMUFNUUiBwc3pCdWYsIFVJTlQgY2NoQnVmICkKewljaGFyIGJ1Zls2NF07CglUUkFDRSgiJWx4ICVwICVpXG4iLCBkdywgcHN6QnVmLCBjY2hCdWYpOwoJaWYgKCBkdzwxMDI0TCApCgl7IHNwcmludGYgKGJ1ZiwiJTMuMWYgYnl0ZXMiLCAoRkxPQVQpZHcpOwoJfQoJZWxzZSBpZiAoIGR3PDEwNDg1NzZMKQoJeyBzcHJpbnRmIChidWYsIiUzLjFmIEtCIiwgKEZMT0FUKWR3LzEwMjQpOwoJfQoJZWxzZSBpZiAoIGR3IDwgMTA3Mzc0MTgyNEwpCgl7IHNwcmludGYgKGJ1ZiwiJTMuMWYgTUIiLCAoRkxPQVQpZHcvMTA0ODU3NkwpOwoJfQoJZWxzZQoJeyBzcHJpbnRmIChidWYsIiUzLjFmIEdCIiwgKEZMT0FUKWR3LzEwNzM3NDE4MjRMKTsKCX0KCWxzdHJjcHluQSAocHN6QnVmLCBidWYsIGNjaEJ1Zik7CglyZXR1cm4gcHN6QnVmOwkKfQpMUFdTVFIgV0lOQVBJIFN0ckZvcm1hdEJ5dGVTaXplVyAoIERXT1JEIGR3LCBMUFdTVFIgcHN6QnVmLCBVSU5UIGNjaEJ1ZiApCnsJY2hhciBidWZbNjRdOwoJVFJBQ0UoIiVseCAlcCAlaVxuIiwgZHcsIHBzekJ1ZiwgY2NoQnVmKTsKCWlmICggZHc8MTAyNEwgKQoJeyBzcHJpbnRmIChidWYsIiUzLjFmIGJ5dGVzIiwgKEZMT0FUKWR3KTsKCX0KCWVsc2UgaWYgKCBkdzwxMDQ4NTc2TCkKCXsgc3ByaW50ZiAoYnVmLCIlMy4xZiBLQiIsIChGTE9BVClkdy8xMDI0KTsKCX0KCWVsc2UgaWYgKCBkdyA8IDEwNzM3NDE4MjRMKQoJeyBzcHJpbnRmIChidWYsIiUzLjFmIE1CIiwgKEZMT0FUKWR3LzEwNDg1NzZMKTsKCX0KCWVsc2UKCXsgc3ByaW50ZiAoYnVmLCIlMy4xZiBHQiIsIChGTE9BVClkdy8xMDczNzQxODI0TCk7Cgl9Cglsc3RyY3B5bkF0b1cgKHBzekJ1ZiwgYnVmLCBjY2hCdWYpOwoJcmV0dXJuIHBzekJ1ZjsJCn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hXYWl0Rm9yRmlsZVRvT3BlbgkJCQlbU0hFTEwzMi45N10KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIV2FpdEZvckZpbGVUb09wZW4oRFdPUkQgdSwgRFdPUkQgdiwgRFdPUkQgdykKewlGSVhNRSgiMHglMDRseCAweCUwNGx4IDB4JTA0bHggc3R1YlxuIix1LHYsdyk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb250cm9sX0ZpbGxDYWNoZV9SdW5ETEwJCQlbU0hFTEwzMi44XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgQ29udHJvbF9GaWxsQ2FjaGVfUnVuRExMKEhXTkQgaFduZCwgSEFORExFIGhNb2R1bGUsIERXT1JEIHcsIERXT1JEIHgpCnsJRklYTUUoIjB4JTA0eCAweCUwNHggMHglMDRseCAweCUwNGx4IHN0dWJcbiIsaFduZCwgaE1vZHVsZSx3LHgpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUnVuRExMX0NhbGxFbnRyeTE2CQkJCVtTSEVMTDMyLjEyMl0KICogdGhlIG5hbWUgaXMgcHJvcGFibHkgd3JvbmcKICovCkhSRVNVTFQgV0lOQVBJIFJ1bkRMTF9DYWxsRW50cnkxNihEV09SRCB2LCBEV09SRCB3LCBEV09SRCB4LCBEV09SRCB5LCBEV09SRCB6KQp7CUZJWE1FKCIweCUwNGx4IDB4JTA0bHggMHglMDRseCAweCUwNGx4IDB4JTA0bHggc3R1YlxuIix2LHcseCx5LHopOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJc2hlbGwzMl82NTQJCQkJW1NIRUxMMzIuNjU0XQogKgogKiBOT1RFUzogZmlyc3QgcGFyYW1ldGVyIHNlZW1zIHRvIGJlIGEgcG9pbnRlciAoc2FtZSBhcyBwYXNzZWQgdG8gV3JpdGVDYWJpbmV0U3RhdGUpCiAqIHNlY29uZCBvbmUgY291bGQgYmUgYSBzaXplICgweDBjKS4gVGhlIHNpemUgaXMgdGhlIHNhbWUgYXMgdGhlIHN0cnVjdHVyZSBzYXZlZCB0bwogKiBIQ1VcU29mdHdhcmVcTWljcm9zb2Z0XFdpbmRvd3NcQ3VycmVudFZlcnNpb25cRXhwbG9yZXJcQ2FiaW5ldFN0YXRlCiAqIEknbSAoanMpIGd1ZXNzaW5nOiB0aGlzIG9uZSBpcyBqdXN0IFJlYWRDYWJpbmV0U3RhdGUgOy0pCiAqLwpIUkVTVUxUIFdJTkFQSSBzaGVsbDMyXzY1NCAoRFdPUkQgeCwgRFdPUkQgeSkKewlGSVhNRSgiMHglMDhseCAweCUwOGx4IHN0dWJcbiIseCx5KTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVJMQnVpbGRMaXN0T2ZQYXRocwkJCVtTSEVMTDMyLjE0Nl0KICoKICogTk9URVMKICogICBidWlsZHMgYSBEUEEKICovCkRXT1JEIFdJTkFQSSBSTEJ1aWxkTGlzdE9mUGF0aHMgKHZvaWQpCnsJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglTdHJUb09sZVN0cgkJCVtTSEVMTDMyLjE2M10KICoKICovCmludCBXSU5BUEkgU3RyVG9PbGVTdHJBIChMUFdTVFIgbHBXaWRlQ2hhclN0ciwgTFBDU1RSIGxwTXVsdGlCeXRlU3RyaW5nKQp7CglUUkFDRSgiJXAgJXAoJXMpXG4iLAoJbHBXaWRlQ2hhclN0ciwgbHBNdWx0aUJ5dGVTdHJpbmcsIGxwTXVsdGlCeXRlU3RyaW5nKTsKCglyZXR1cm4gTXVsdGlCeXRlVG9XaWRlQ2hhcigwLCAwLCBscE11bHRpQnl0ZVN0cmluZywgLTEsIGxwV2lkZUNoYXJTdHIsIE1BWF9QQVRIKTsKCn0KaW50IFdJTkFQSSBTdHJUb09sZVN0clcgKExQV1NUUiBscFdpZGVDaGFyU3RyLCBMUENXU1RSIGxwV1N0cmluZykKewoJVFJBQ0UoIiVwICVwKCVzKVxuIiwKCWxwV2lkZUNoYXJTdHIsIGxwV1N0cmluZywgZGVidWdzdHJfdyhscFdTdHJpbmcpKTsKCglpZiAobHN0cmNweVcgKGxwV2lkZUNoYXJTdHIsIGxwV1N0cmluZyApKQoJeyByZXR1cm4gbHN0cmxlblcgKGxwV2lkZUNoYXJTdHIpOwoJfQoJcmV0dXJuIDA7Cn0KCkJPT0wgV0lOQVBJIFN0clRvT2xlU3RyQVcgKExQV1NUUiBscFdpZGVDaGFyU3RyLCBMUENWT0lEIGxwU3RyaW5nKQp7CglpZiAoVkVSU0lPTl9Pc0lzVW5pY29kZSgpKQoJICByZXR1cm4gU3RyVG9PbGVTdHJXIChscFdpZGVDaGFyU3RyLCBscFN0cmluZyk7CglyZXR1cm4gU3RyVG9PbGVTdHJBIChscFdpZGVDaGFyU3RyLCBscFN0cmluZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJU0hWYWxpZGF0ZVVOQwkJCQlbU0hFTEwzMi4xNzNdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFZhbGlkYXRlVU5DIChEV09SRCB4LCBEV09SRCB5LCBEV09SRCB6KQp7CglGSVhNRSgiMHglMDhseCAweCUwOGx4IDB4JTA4bHggc3R1YlxuIix4LHkseik7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglEb0Vudmlyb25tZW50U3Vic3RXCQkJW1NIRUxMMzIuNTNdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBEb0Vudmlyb25tZW50U3Vic3RBKExQU1RSIHgsIExQU1RSIHkpCnsKCUZJWE1FKCIlcCglcykgJXAoJXMpIHN0dWJcbiIsIHgsIHgsIHksIHkpOwoJcmV0dXJuIDA7Cn0KCkhSRVNVTFQgV0lOQVBJIERvRW52aXJvbm1lbnRTdWJzdFcoTFBXU1RSIHgsIExQV1NUUiB5KQp7CglGSVhNRSgiJXAoJXMpICVwKCVzKSBzdHViXG4iLCB4LCBkZWJ1Z3N0cl93KHgpLCB5LCBkZWJ1Z3N0cl93KHkpKTsKCXJldHVybiAwOwp9CgpIUkVTVUxUIFdJTkFQSSBEb0Vudmlyb25tZW50U3Vic3RBVyhMUFZPSUQgeCwgTFBWT0lEIHkpCnsKCWlmIChWRVJTSU9OX09zSXNVbmljb2RlKCkpCgkgIHJldHVybiBEb0Vudmlyb25tZW50U3Vic3RXKHgsIHkpOwoJcmV0dXJuIERvRW52aXJvbm1lbnRTdWJzdEEoeCwgeSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgc2hlbGwzMl8yNDMgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtTSEVMTDMyLjI0M10KICogCiAqIFdpbjk4KyBieS1vcmRpbmFsIHJvdXRpbmUuICBJbiBXaW45OCB0aGlzIHJvdXRpbmUgcmV0dXJucyB6ZXJvIGFuZAogKiBkb2VzIG5vdGhpbmcgZWxzZS4gIFBvc3NpYmx5IHRoaXMgZG9lcyBzb21ldGhpbmcgaW4gTlQgb3IgU0hFTEwzMiA1LjA/CiAqCiAqLwoKQk9PTCBXSU5BUEkgc2hlbGwzMl8yNDMoRFdPUkQgYSwgRFdPUkQgYikgCnsgCiAgcmV0dXJuIEZBTFNFOyAKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFdpbjMyRGVsZXRlRmlsZSAgICAgICAgICAgICAgICAgICAgICAgICBbU0hFTEwzMi4xNjRdICAKICoKICogRGVsZXRlcyBhIGZpbGUuICBBbHNvIHRyaWdnZXJzIGEgY2hhbmdlIG5vdGlmeSBpZiBvbmUgZXhpc3RzLCBidXQKICogdGhhdCBtZWNoYW5pc20gZG9lc24ndCB5ZXQgZXhpc3QgaW4gV2luZSdzIFNIRUxMMzIuCiAqCiAqIEZJWE1FOgogKiBWZXJpZmllZCBvbiBXaW45OCAvIElFIDUgKFNIRUxMMzIgNC43MiwgTWFyY2ggMTk5OSBidWlsZCkgdG8gYmUKICogQU5TSS4gIElzIHRoaXMgVW5pY29kZSBvbiBOVD8KICoKICovIAoKQk9PTCBXSU5BUEkgV2luMzJEZWxldGVGaWxlKExQU1RSIGZOYW1lKQp7CiAgRklYTUUoIiVwKCVzKTogcGFydGlhbCBzdHViXG4iLCBmTmFtZSwgZk5hbWUpOwoKICBEZWxldGVGaWxlQShmTmFtZSk7CgogIHJldHVybiBUUlVFOwp9Cg==