LyoKICogTm9uLWNsaWVudCBhcmVhIHdpbmRvdyBmdW5jdGlvbnMKICoKICogQ29weXJpZ2h0IDE5OTQgQWxleGFuZHJlIEp1bGxpYXJkCiAqCiAqLwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW5lL3dpbnVzZXIxNi5oIgojaW5jbHVkZSAidmVyc2lvbi5oIgojaW5jbHVkZSAid2luLmgiCiNpbmNsdWRlICJtZXNzYWdlLmgiCiNpbmNsdWRlICJ1c2VyLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJkY2UuaCIKI2luY2x1ZGUgImN1cnNvcmljb24uaCIKI2luY2x1ZGUgImRpYWxvZy5oIgojaW5jbHVkZSAibWVudS5oIgojaW5jbHVkZSAid2lucG9zLmgiCiNpbmNsdWRlICJob29rLmgiCiNpbmNsdWRlICJzY3JvbGwuaCIKI2luY2x1ZGUgIm5vbmNsaWVudC5oIgojaW5jbHVkZSAicXVldWUuaCIKI2luY2x1ZGUgInNlbGVjdG9ycy5oIgojaW5jbHVkZSAidHdlYWsuaCIKI2luY2x1ZGUgImRlYnVndG9vbHMuaCIKI2luY2x1ZGUgIm9wdGlvbnMuaCIKI2luY2x1ZGUgInNoZWxsYXBpLmgiCiNpbmNsdWRlICJjYWNoZS5oIgojaW5jbHVkZSAiYml0bWFwLmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwobm9uY2xpZW50KQpERUNMQVJFX0RFQlVHX0NIQU5ORUwoc2hlbGwpCgpCT09MIE5DX0RyYXdHcmF5QnV0dG9uKEhEQyBoZGMsIGludCB4LCBpbnQgeSk7CgpzdGF0aWMgSEJJVE1BUDE2IGhiaXRtYXBDbG9zZSA9IDA7CnN0YXRpYyBIQklUTUFQMTYgaGJpdG1hcENsb3NlRCA9IDA7CnN0YXRpYyBIQklUTUFQMTYgaGJpdG1hcE1pbmltaXplID0gMDsKc3RhdGljIEhCSVRNQVAxNiBoYml0bWFwTWluaW1pemVEID0gMDsKc3RhdGljIEhCSVRNQVAxNiBoYml0bWFwTWF4aW1pemUgPSAwOwpzdGF0aWMgSEJJVE1BUDE2IGhiaXRtYXBNYXhpbWl6ZUQgPSAwOwpzdGF0aWMgSEJJVE1BUDE2IGhiaXRtYXBSZXN0b3JlID0gMDsKc3RhdGljIEhCSVRNQVAxNiBoYml0bWFwUmVzdG9yZUQgPSAwOwoKQllURSBscEdyYXlNYXNrW10gPSB7IDB4QUEsIDB4QTAsCgkJICAgICAgMHg1NSwgMHg1MCwgIAoJCSAgICAgIDB4QUEsIDB4QTAsCgkJICAgICAgMHg1NSwgMHg1MCwgIAoJCSAgICAgIDB4QUEsIDB4QTAsCgkJICAgICAgMHg1NSwgMHg1MCwgIAoJCSAgICAgIDB4QUEsIDB4QTAsCgkJICAgICAgMHg1NSwgMHg1MCwgIAoJCSAgICAgIDB4QUEsIDB4QTAsCgkJICAgICAgMHg1NSwgMHg1MH07CgojZGVmaW5lIFNDX0FCT1VUV0lORSAgICAJKFNDX1NDUkVFTlNBVkUrMSkKI2RlZmluZSBTQ19QVVRNQVJLICAgICAJCShTQ19TQ1JFRU5TQVZFKzIpCgogIC8qIFNvbWUgdXNlZnVsIG1hY3JvcyAqLwojZGVmaW5lIEhBU19ETEdGUkFNRShzdHlsZSxleFN0eWxlKSBcCiAgICAoKChleFN0eWxlKSAmIFdTX0VYX0RMR01PREFMRlJBTUUpIHx8IFwKICAgICAoKChzdHlsZSkgJiBXU19ETEdGUkFNRSkgJiYgISgoc3R5bGUpICYgV1NfVEhJQ0tGUkFNRSkpKQoKI2RlZmluZSBIQVNfVEhJQ0tGUkFNRShzdHlsZSxleFN0eWxlKSBcCiAgICAoKChzdHlsZSkgJiBXU19USElDS0ZSQU1FKSAmJiBcCiAgICAgISgoKHN0eWxlKSAmIChXU19ETEdGUkFNRXxXU19CT1JERVIpKSA9PSBXU19ETEdGUkFNRSkpCgojZGVmaW5lIEhBU19USElORlJBTUUoc3R5bGUpIFwKICAgICgoKHN0eWxlKSAmIFdTX0JPUkRFUikgfHwgISgoc3R5bGUpICYgKFdTX0NISUxEIHwgV1NfUE9QVVApKSkKCiNkZWZpbmUgSEFTX0JJR0ZSQU1FKHN0eWxlLGV4U3R5bGUpIFwKICAgICgoKHN0eWxlKSAmIChXU19USElDS0ZSQU1FIHwgV1NfRExHRlJBTUUpKSB8fCBcCiAgICAgKChleFN0eWxlKSAmIFdTX0VYX0RMR01PREFMRlJBTUUpKQoKI2RlZmluZSBIQVNfQU5ZRlJBTUUoc3R5bGUsZXhTdHlsZSkgXAogICAgKCgoc3R5bGUpICYgKFdTX1RISUNLRlJBTUUgfCBXU19ETEdGUkFNRSB8IFdTX0JPUkRFUikpIHx8IFwKICAgICAoKGV4U3R5bGUpICYgV1NfRVhfRExHTU9EQUxGUkFNRSkgfHwgXAogICAgICEoKHN0eWxlKSAmIChXU19DSElMRCB8IFdTX1BPUFVQKSkpCgojZGVmaW5lIEhBU19NRU5VKHcpICAoISgodyktPmR3U3R5bGUgJiBXU19DSElMRCkgJiYgKCh3KS0+d0lEbWVudSAhPSAwKSkKCiNkZWZpbmUgT05fTEVGVF9CT1JERVIoaGl0KSBcCiAoKChoaXQpID09IEhUTEVGVCkgfHwgKChoaXQpID09IEhUVE9QTEVGVCkgfHwgKChoaXQpID09IEhUQk9UVE9NTEVGVCkpCiNkZWZpbmUgT05fUklHSFRfQk9SREVSKGhpdCkgXAogKCgoaGl0KSA9PSBIVFJJR0hUKSB8fCAoKGhpdCkgPT0gSFRUT1BSSUdIVCkgfHwgKChoaXQpID09IEhUQk9UVE9NUklHSFQpKQojZGVmaW5lIE9OX1RPUF9CT1JERVIoaGl0KSBcCiAoKChoaXQpID09IEhUVE9QKSB8fCAoKGhpdCkgPT0gSFRUT1BMRUZUKSB8fCAoKGhpdCkgPT0gSFRUT1BSSUdIVCkpCiNkZWZpbmUgT05fQk9UVE9NX0JPUkRFUihoaXQpIFwKICgoKGhpdCkgPT0gSFRCT1RUT00pIHx8ICgoaGl0KSA9PSBIVEJPVFRPTUxFRlQpIHx8ICgoaGl0KSA9PSBIVEJPVFRPTVJJR0hUKSkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgV0lOX1dpbmRvd05lZWRzV01Cb3JkZXIKICoKICogVGhpcyBtZXRob2QgZGVmaW5lcyB0aGUgcnVsZXMgZm9yIGEgd2luZG93IHRvIGhhdmUgYSBXTSBib3JkZXIsCiAqIGNhcHRpb24uLi4gIEl0IGlzIHVzZWQgZm9yIGNvbnNpdGVuY3kgcHVycG9zZXMuCiAqLwpCT09MIFdJTl9XaW5kb3dOZWVkc1dNQm9yZGVyKCBEV09SRCBzdHlsZSwgRFdPUkQgZXhTdHlsZSApCnsKICAgIGlmICghKHN0eWxlICYgV1NfQ0hJTEQpICYmIAoJT3B0aW9ucy5tYW5hZ2VkICAmJgoJIShleFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykgJiYKICAgICAgICAoICgoc3R5bGUgJiBXU19DQVBUSU9OKSA9PSBXU19DQVBUSU9OKSB8fAoJICAoc3R5bGUgJiBXU19USElDS0ZSQU1FKSkpCiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICBpZiAoZXhTdHlsZSAmIFdTX0VYX1RSQVlXSU5ET1cpCglyZXR1cm4gVFJVRTsKICAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19BZGp1c3RSZWN0CiAqCiAqIENvbXB1dGUgdGhlIHNpemUgb2YgdGhlIHdpbmRvdyByZWN0YW5nbGUgZnJvbSB0aGUgc2l6ZSBvZiB0aGUKICogY2xpZW50IHJlY3RhbmdsZS4KICovCnN0YXRpYyB2b2lkIE5DX0FkanVzdFJlY3QoIExQUkVDVDE2IHJlY3QsIERXT1JEIHN0eWxlLCBCT09MIG1lbnUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGV4U3R5bGUgKQp7CiAgICBpZiAoVFdFQUtfV2luZUxvb2sgPiBXSU4zMV9MT09LKQoJRVJSKCJDYWxsZWQgaW4gV2luOTUgbW9kZS4gQWllZSEgUGxlYXNlIHJlcG9ydCB0aGlzLlxuIiApOwoKICAgIGlmKHN0eWxlICYgV1NfSUNPTklDKSByZXR1cm47CiAgICAvKiBEZWNpZGUgaWYgdGhlIHdpbmRvdyB3aWxsIGJlIG1hbmFnZWQgKHNlZSBDcmVhdGVXaW5kb3dFeCkgKi8KICAgIGlmICghV0lOX1dpbmRvd05lZWRzV01Cb3JkZXIoc3R5bGUsIGV4U3R5bGUpKQogICAgewogICAgICAgIGlmIChIQVNfVEhJQ0tGUkFNRSggc3R5bGUsIGV4U3R5bGUgKSkKICAgICAgICAgICAgSW5mbGF0ZVJlY3QxNiggcmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWEZSQU1FKSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSApOwogICAgICAgIGVsc2UKICAgICAgICBpZiAoSEFTX0RMR0ZSQU1FKCBzdHlsZSwgZXhTdHlsZSApKQogICAgICAgICAgICBJbmZsYXRlUmVjdDE2KCByZWN0LCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRExHRlJBTUUpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRExHRlJBTUUpICk7CiAgICAgICAgZWxzZQogICAgICAgIGlmIChIQVNfVEhJTkZSQU1FKCBzdHlsZSApKQogICAgICAgICAgICBJbmZsYXRlUmVjdDE2KCByZWN0LCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYQk9SREVSKSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikpOwoKICAgICAgICBpZiAoKHN0eWxlICYgV1NfQ0FQVElPTikgPT0gV1NfQ0FQVElPTikKICAgICAgICAgICAgcmVjdC0+dG9wIC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpOwogICAgfQogICAgaWYgKG1lbnUpIHJlY3QtPnRvcCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZTUVOVSkgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKTsKCiAgICBpZiAoc3R5bGUgJiBXU19WU0NST0xMKSB7CiAgICAgIHJlY3QtPnJpZ2h0ICArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCkgLSAxOwogICAgICBpZighSEFTX0FOWUZSQU1FKCBzdHlsZSwgZXhTdHlsZSApKQoJIHJlY3QtPnJpZ2h0Kys7CiAgICB9CgogICAgaWYgKHN0eWxlICYgV1NfSFNDUk9MTCkgewogICAgICByZWN0LT5ib3R0b20gKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpIC0gMTsKICAgICAgaWYoIUhBU19BTllGUkFNRSggc3R5bGUsIGV4U3R5bGUgKSkKCSByZWN0LT5ib3R0b20rKzsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTkNfQWRqdXN0UmVjdE91dGVyOTUKICoKICogQ29tcHV0ZXMgdGhlIHNpemUgb2YgdGhlICJvdXRzaWRlIiBwYXJ0cyBvZiB0aGUgd2luZG93IGJhc2VkIG9uIHRoZQogKiBwYXJhbWV0ZXJzIG9mIHRoZSBjbGllbnQgYXJlYS4KICoKICsgUEFSQU1TCiAqICAgICBMUFJFQ1QxNiAgcmVjdAogKiAgICAgRFdPUkQgIHN0eWxlCiAqICAgICBCT09MICBtZW51CiAqICAgICBEV09SRCAgZXhTdHlsZQogKgogKiBOT1RFUwogKiAgICAgIk91dGVyIiBwYXJ0cyBvZiBhIHdpbmRvdyBtZWFucyB0aGUgd2hvbGUgd2luZG93IGZyYW1lLCBjYXB0aW9uIGFuZAogKiAgICAgbWVudSBiYXIuIEl0IGRvZXMgbm90IGluY2x1ZGUgImlubmVyIiBwYXJ0cyBvZiB0aGUgZnJhbWUgbGlrZSBjbGllbnQKICogICAgIGVkZ2UsIHN0YXRpYyBlZGdlIG9yIHNjcm9sbCBiYXJzLgogKgogKiBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAwNS1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgIE9yaWdpbmFsIChOQ19BZGp1c3RSZWN0OTUpIGN1dCAmIHBhc3RlIGZyb20gTkNfQWRqdXN0UmVjdAogKgogKiAgICAgMjAtSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgIFNwbGl0IE5DX0FkanVzdFJlY3Q5NSBpbnRvIE5DX0FkanVzdFJlY3RPdXRlcjk1IGFuZAogKiAgICAgICAgTkNfQWRqdXN0UmVjdElubmVyOTUgYW5kIGFkZGVkIGhhbmRsaW5nIG9mIFdpbjk1IHN0eWxlcy4KICoKICogICAgIDI4LUp1bC0xOTk5IE92ZSBL5XZlbiAob3Zla0BhcmN0aWNuZXQubm8pCiAqICAgICAgICBTdHJlYW1saW5lZCB3aW5kb3cgc3R5bGUgY2hlY2tzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZApOQ19BZGp1c3RSZWN0T3V0ZXI5NSAoTFBSRUNUMTYgcmVjdCwgRFdPUkQgc3R5bGUsIEJPT0wgbWVudSwgRFdPUkQgZXhTdHlsZSkKewogICAgaWYoc3R5bGUgJiBXU19JQ09OSUMpIHJldHVybjsKCiAgICAvKiBEZWNpZGUgaWYgdGhlIHdpbmRvdyB3aWxsIGJlIG1hbmFnZWQgKHNlZSBDcmVhdGVXaW5kb3dFeCkgKi8KICAgIGlmICghV0lOX1dpbmRvd05lZWRzV01Cb3JkZXIoc3R5bGUsIGV4U3R5bGUpKQogICAgewogICAgICAgIGlmIChIQVNfVEhJQ0tGUkFNRSggc3R5bGUsIGV4U3R5bGUgKSkKICAgICAgICAgICAgSW5mbGF0ZVJlY3QxNiggcmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWEZSQU1FKSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSApOwogICAgICAgIGVsc2UKICAgICAgICBpZiAoSEFTX0RMR0ZSQU1FKCBzdHlsZSwgZXhTdHlsZSApKQogICAgICAgICAgICBJbmZsYXRlUmVjdDE2KHJlY3QsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hETEdGUkFNRSksIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lETEdGUkFNRSkgKTsKICAgICAgICBlbHNlCiAgICAgICAgaWYgKEhBU19USElORlJBTUUoIHN0eWxlICkpCiAgICAgICAgICAgIEluZmxhdGVSZWN0MTYoIHJlY3QsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKSk7CgogICAgICAgIGlmICgoc3R5bGUgJiBXU19DQVBUSU9OKSA9PSBXU19DQVBUSU9OKQogICAgICAgIHsKCSAgICBpZiAoZXhTdHlsZSAmIFdTX0VYX1RPT0xXSU5ET1cpCgkJcmVjdC0+dG9wIC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUNBUFRJT04pOwoJICAgIGVsc2UKCQlyZWN0LT50b3AgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAobWVudSkKCXJlY3QtPnRvcCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZTUVOVSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE5DX0FkanVzdFJlY3RJbm5lcjk1CiAqCiAqIENvbXB1dGVzIHRoZSBzaXplIG9mIHRoZSAiaW5zaWRlIiBwYXJ0IG9mIHRoZSB3aW5kb3cgYmFzZWQgb24gdGhlCiAqIHBhcmFtZXRlcnMgb2YgdGhlIGNsaWVudCBhcmVhLgogKgogKyBQQVJBTVMKICogICAgIExQUkVDVDE2IHJlY3QKICogICAgIERXT1JEICAgIHN0eWxlCiAqICAgICBEV09SRCAgICBleFN0eWxlCiAqCiAqIE5PVEVTCiAqICAgICAiSW5uZXIiIHBhcnQgb2YgYSB3aW5kb3cgbWVhbnMgdGhlIHdpbmRvdyBmcmFtZSBpbnNpZGUgb2YgdGhlIGZsYXQKICogICAgIHdpbmRvdyBmcmFtZS4gSXQgaW5jbHVkZXMgdGhlIGNsaWVudCBlZGdlLCB0aGUgc3RhdGljIGVkZ2UgYW5kIHRoZQogKiAgICAgc2Nyb2xsIGJhcnMuCiAqCiAqIFJldmlzaW9uIGhpc3RvcnkKICogICAgIDA1LUp1bC0xOTk3IERhdmUgQ3V0aGJlcnQgKGRhY3V0QGVjZS5jbXUuZWR1KQogKiAgICAgICAgT3JpZ2luYWwgKE5DX0FkanVzdFJlY3Q5NSkgY3V0ICYgcGFzdGUgZnJvbSBOQ19BZGp1c3RSZWN0CiAqCiAqICAgICAyMC1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgU3BsaXQgTkNfQWRqdXN0UmVjdDk1IGludG8gTkNfQWRqdXN0UmVjdE91dGVyOTUgYW5kCiAqICAgICAgICBOQ19BZGp1c3RSZWN0SW5uZXI5NSBhbmQgYWRkZWQgaGFuZGxpbmcgb2YgV2luOTUgc3R5bGVzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZApOQ19BZGp1c3RSZWN0SW5uZXI5NSAoTFBSRUNUMTYgcmVjdCwgRFdPUkQgc3R5bGUsIERXT1JEIGV4U3R5bGUpCnsKICAgIGlmKHN0eWxlICYgV1NfSUNPTklDKSByZXR1cm47CgogICAgaWYgKGV4U3R5bGUgJiBXU19FWF9DTElFTlRFREdFKQoJSW5mbGF0ZVJlY3QxNiAocmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWEVER0UpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSkpOwoKICAgIGlmIChleFN0eWxlICYgV1NfRVhfU1RBVElDRURHRSkKCUluZmxhdGVSZWN0MTYgKHJlY3QsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKSk7CgogICAgaWYgKHN0eWxlICYgV1NfVlNDUk9MTCkgcmVjdC0+cmlnaHQgICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKTsKICAgIGlmIChzdHlsZSAmIFdTX0hTQ1JPTEwpIHJlY3QtPmJvdHRvbSArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRHJhd0NhcHRpb24xNiBbVVNFUi42NjBdIERyYXdzIGEgY2FwdGlvbiBiYXIKICoKICogUEFSQU1TCiAqICAgICBod25kICAgW0ldCiAqICAgICBoZGMgICAgW0ldCiAqICAgICBscFJlY3QgW0ldCiAqICAgICB1RmxhZ3MgW0ldCiAqCiAqIFJFVFVSTlMKICogICAgIFN1Y2Nlc3M6CiAqICAgICBGYWlsdXJlOgogKi8KCkJPT0wxNiBXSU5BUEkKRHJhd0NhcHRpb24xNiAoSFdORDE2IGh3bmQsIEhEQzE2IGhkYywgY29uc3QgUkVDVDE2ICpyZWN0LCBVSU5UMTYgdUZsYWdzKQp7CiAgICBSRUNUIHJlY3QzMjsKCiAgICBpZiAocmVjdCkKCUNPTlZfUkVDVDE2VE8zMiAocmVjdCwgJnJlY3QzMik7CgogICAgcmV0dXJuIChCT09MMTYpRHJhd0NhcHRpb25UZW1wQSAoaHduZCwgaGRjLCByZWN0ID8gJnJlY3QzMiA6IE5VTEwsCgkJCQkgICAgICAgMCwgMCwgTlVMTCwgdUZsYWdzICYgMHgxRik7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRHJhd0NhcHRpb24gW1VTRVIzMi4xNTRdIERyYXdzIGEgY2FwdGlvbiBiYXIKICoKICogUEFSQU1TCiAqICAgICBod25kICAgW0ldCiAqICAgICBoZGMgICAgW0ldCiAqICAgICBscFJlY3QgW0ldCiAqICAgICB1RmxhZ3MgW0ldCiAqCiAqIFJFVFVSTlMKICogICAgIFN1Y2Nlc3M6CiAqICAgICBGYWlsdXJlOgogKi8KCkJPT0wgV0lOQVBJCkRyYXdDYXB0aW9uIChIV05EIGh3bmQsIEhEQyBoZGMsIGNvbnN0IFJFQ1QgKmxwUmVjdCwgVUlOVCB1RmxhZ3MpCnsKICAgIHJldHVybiBEcmF3Q2FwdGlvblRlbXBBIChod25kLCBoZGMsIGxwUmVjdCwgMCwgMCwgTlVMTCwgdUZsYWdzICYgMHgxRik7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRHJhd0NhcHRpb25UZW1wMTYgW1VTRVIuNjU3XQogKgogKiBQQVJBTVMKICoKICogUkVUVVJOUwogKiAgICAgU3VjY2VzczoKICogICAgIEZhaWx1cmU6CiAqLwoKQk9PTDE2IFdJTkFQSQpEcmF3Q2FwdGlvblRlbXAxNiAoSFdORDE2IGh3bmQsIEhEQzE2IGhkYywgY29uc3QgUkVDVDE2ICpyZWN0LCBIRk9OVDE2IGhGb250LAoJCSAgIEhJQ09OMTYgaEljb24sIExQQ1NUUiBzdHIsIFVJTlQxNiB1RmxhZ3MpCnsKICAgIFJFQ1QgcmVjdDMyOwoKICAgIGlmIChyZWN0KQoJQ09OVl9SRUNUMTZUTzMyKHJlY3QsJnJlY3QzMik7CgogICAgcmV0dXJuIChCT09MMTYpRHJhd0NhcHRpb25UZW1wQSAoaHduZCwgaGRjLCByZWN0PyZyZWN0MzI6TlVMTCwgaEZvbnQsCgkJCQkgICAgICAgaEljb24sIHN0ciwgdUZsYWdzICYgMHgxRik7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRHJhd0NhcHRpb25UZW1wQSBbVVNFUjMyLjU5OV0KICoKICogUEFSQU1TCiAqCiAqIFJFVFVSTlMKICogICAgIFN1Y2Nlc3M6CiAqICAgICBGYWlsdXJlOgogKi8KCkJPT0wgV0lOQVBJCkRyYXdDYXB0aW9uVGVtcEEgKEhXTkQgaHduZCwgSERDIGhkYywgY29uc3QgUkVDVCAqcmVjdCwgSEZPTlQgaEZvbnQsCgkJICAgIEhJQ09OIGhJY29uLCBMUENTVFIgc3RyLCBVSU5UIHVGbGFncykKewogICAgUkVDVCAgIHJjID0gKnJlY3Q7CgogICAgVFJBQ0UoIiglMDh4LCUwOHgsJXAsJTA4eCwlMDh4LFwiJXNcIiwlMDh4KVxuIiwKICAgICAgICAgIGh3bmQsIGhkYywgcmVjdCwgaEZvbnQsIGhJY29uLCBzdHIsIHVGbGFncyk7CgogICAgLyogZHJhd2luZyBiYWNrZ3JvdW5kICovCiAgICBpZiAodUZsYWdzICYgRENfSU5CVVRUT04pIHsKCUZpbGxSZWN0IChoZGMsICZyYywgR2V0U3lzQ29sb3JCcnVzaCAoQ09MT1JfM0RGQUNFKSk7CgoJaWYgKHVGbGFncyAmIERDX0FDVElWRSkgewoJICAgIEhCUlVTSCBoYnIgPSBTZWxlY3RPYmplY3QgKGhkYywgQ0FDSEVfR2V0UGF0dGVybjU1QUFCcnVzaCAoKSk7CgkgICAgUGF0Qmx0IChoZGMsIHJjLmxlZnQsIHJjLnRvcCwKCQkgICAgICByYy5yaWdodC1yYy5sZWZ0LCByYy5ib3R0b20tcmMudG9wLCAweEZBMDA4OSk7CgkgICAgU2VsZWN0T2JqZWN0IChoZGMsIGhicik7Cgl9CiAgICB9CiAgICBlbHNlIHsKCUZpbGxSZWN0IChoZGMsICZyYywgR2V0U3lzQ29sb3JCcnVzaCAoKHVGbGFncyAmIERDX0FDVElWRSkgPwoJCSAgICBDT0xPUl9BQ1RJVkVDQVBUSU9OIDogQ09MT1JfSU5BQ1RJVkVDQVBUSU9OKSk7CiAgICB9CgoKICAgIC8qIGRyYXdpbmcgaWNvbiAqLwogICAgaWYgKCh1RmxhZ3MgJiBEQ19JQ09OKSAmJiAhKHVGbGFncyAmIERDX1NNQUxMQ0FQKSkgewoJUE9JTlQgcHQ7CgoJcHQueCA9IHJjLmxlZnQgKyAyOwoJcHQueSA9IChyYy5ib3R0b20gKyByYy50b3AgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01JQ09OKSkgLyAyOwoKCWlmIChoSWNvbikgewoJICAgIERyYXdJY29uRXggKGhkYywgcHQueCwgcHQueSwgaEljb24sIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTTUlDT04pLAoJCQkgIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUlDT04pLCAwLCAwLCBESV9OT1JNQUwpOwoJfQoJZWxzZSB7CgkgICAgV05EKiB3bmRQdHIgPSBXSU5fRmluZFduZFB0cihod25kKTsKCSAgICBISUNPTiBoQXBwSWNvbiA9IChISUNPTikgTkNfSWNvbkZvcldpbmRvdyh3bmRQdHIpOwoJICAgIERyYXdJY29uRXggKGhkYywgcHQueCwgcHQueSwgaEFwcEljb24sIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTTUlDT04pLAoJCQkgIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUlDT04pLCAwLCAwLCBESV9OT1JNQUwpOwogICAgICAgICAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwoJfQoKCXJjLmxlZnQgKz0gKHJjLmJvdHRvbSAtIHJjLnRvcCk7CiAgICB9CgogICAgLyogZHJhd2luZyB0ZXh0ICovCiAgICBpZiAodUZsYWdzICYgRENfVEVYVCkgewoJSEZPTlQgaE9sZEZvbnQ7CgoJaWYgKHVGbGFncyAmIERDX0lOQlVUVE9OKQoJICAgIFNldFRleHRDb2xvciAoaGRjLCBHZXRTeXNDb2xvciAoQ09MT1JfQlROVEVYVCkpOwoJZWxzZSBpZiAodUZsYWdzICYgRENfQUNUSVZFKQoJICAgIFNldFRleHRDb2xvciAoaGRjLCBHZXRTeXNDb2xvciAoQ09MT1JfQ0FQVElPTlRFWFQpKTsKCWVsc2UKCSAgICBTZXRUZXh0Q29sb3IgKGhkYywgR2V0U3lzQ29sb3IgKENPTE9SX0lOQUNUSVZFQ0FQVElPTlRFWFQpKTsKCglTZXRCa01vZGUgKGhkYywgVFJBTlNQQVJFTlQpOwoKCWlmIChoRm9udCkKCSAgICBoT2xkRm9udCA9IFNlbGVjdE9iamVjdCAoaGRjLCBoRm9udCk7CgllbHNlIHsKCSAgICBOT05DTElFTlRNRVRSSUNTQSBuY2xtOwoJICAgIEhGT05UIGhOZXdGb250OwoJICAgIG5jbG0uY2JTaXplID0gc2l6ZW9mKE5PTkNMSUVOVE1FVFJJQ1NBKTsKCSAgICBTeXN0ZW1QYXJhbWV0ZXJzSW5mb0EgKFNQSV9HRVROT05DTElFTlRNRVRSSUNTLCAwLCAmbmNsbSwgMCk7CgkgICAgaE5ld0ZvbnQgPSBDcmVhdGVGb250SW5kaXJlY3RBICgodUZsYWdzICYgRENfU01BTExDQVApID8KCQkmbmNsbS5sZlNtQ2FwdGlvbkZvbnQgOiAmbmNsbS5sZkNhcHRpb25Gb250KTsKCSAgICBoT2xkRm9udCA9IFNlbGVjdE9iamVjdCAoaGRjLCBoTmV3Rm9udCk7Cgl9CgoJaWYgKHN0cikKCSAgICBEcmF3VGV4dEEgKGhkYywgc3RyLCAtMSwgJnJjLAoJCQkgRFRfU0lOR0xFTElORSB8IERUX1ZDRU5URVIgfCBEVF9OT1BSRUZJWCB8IERUX0xFRlQpOwoJZWxzZSB7CgkgICAgQ0hBUiBzelRleHRbMTI4XTsKCSAgICBJTlQgbkxlbjsKCSAgICBuTGVuID0gR2V0V2luZG93VGV4dEEgKGh3bmQsIHN6VGV4dCwgMTI4KTsKCSAgICBEcmF3VGV4dEEgKGhkYywgc3pUZXh0LCBuTGVuLCAmcmMsCgkJCSBEVF9TSU5HTEVMSU5FIHwgRFRfVkNFTlRFUiB8IERUX05PUFJFRklYIHwgRFRfTEVGVCk7Cgl9CgoJaWYgKGhGb250KQoJICAgIFNlbGVjdE9iamVjdCAoaGRjLCBoT2xkRm9udCk7CgllbHNlCgkgICAgRGVsZXRlT2JqZWN0IChTZWxlY3RPYmplY3QgKGhkYywgaE9sZEZvbnQpKTsKICAgIH0KCiAgICAvKiBkcmF3aW5nIGZvY3VzID8/PyAqLwogICAgaWYgKHVGbGFncyAmIDB4MjAwMCkKCUZJWE1FKCJ1bmRvY3VtZW50ZWQgZmxhZyAoMHgyMDAwKSFcbiIpOwoKICAgIHJldHVybiAwOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERyYXdDYXB0aW9uVGVtcFcgW1VTRVIzMi42MDJdCiAqCiAqIFBBUkFNUwogKgogKiBSRVRVUk5TCiAqICAgICBTdWNjZXNzOgogKiAgICAgRmFpbHVyZToKICovCgpCT09MIFdJTkFQSQpEcmF3Q2FwdGlvblRlbXBXIChIV05EIGh3bmQsIEhEQyBoZGMsIGNvbnN0IFJFQ1QgKnJlY3QsIEhGT05UIGhGb250LAoJCSAgICBISUNPTiBoSWNvbiwgTFBDV1NUUiBzdHIsIFVJTlQgdUZsYWdzKQp7CiAgICBMUFNUUiBwID0gSEVBUF9zdHJkdXBXdG9BIChHZXRQcm9jZXNzSGVhcCAoKSwgMCwgc3RyKTsKICAgIEJPT0wgcmVzID0gRHJhd0NhcHRpb25UZW1wQSAoaHduZCwgaGRjLCByZWN0LCBoRm9udCwgaEljb24sIHAsIHVGbGFncyk7CiAgICBIZWFwRnJlZSAoR2V0UHJvY2Vzc0hlYXAgKCksIDAsIHApOwogICAgcmV0dXJuIHJlczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgQWRqdXN0V2luZG93UmVjdDE2ICAgIChVU0VSLjEwMikKICovCkJPT0wxNiBXSU5BUEkgQWRqdXN0V2luZG93UmVjdDE2KCBMUFJFQ1QxNiByZWN0LCBEV09SRCBzdHlsZSwgQk9PTDE2IG1lbnUgKQp7CiAgICByZXR1cm4gQWRqdXN0V2luZG93UmVjdEV4MTYoIHJlY3QsIHN0eWxlLCBtZW51LCAwICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEFkanVzdFdpbmRvd1JlY3QgICAgKFVTRVIzMi4yKQogKi8KQk9PTCBXSU5BUEkgQWRqdXN0V2luZG93UmVjdCggTFBSRUNUIHJlY3QsIERXT1JEIHN0eWxlLCBCT09MIG1lbnUgKQp7CiAgICByZXR1cm4gQWRqdXN0V2luZG93UmVjdEV4KCByZWN0LCBzdHlsZSwgbWVudSwgMCApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBBZGp1c3RXaW5kb3dSZWN0RXgxNiAgICAoVVNFUi40NTQpCiAqLwpCT09MMTYgV0lOQVBJIEFkanVzdFdpbmRvd1JlY3RFeDE2KCBMUFJFQ1QxNiByZWN0LCBEV09SRCBzdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTDE2IG1lbnUsIERXT1JEIGV4U3R5bGUgKQp7CiAgICAgIC8qIENvcnJlY3QgdGhlIHdpbmRvdyBzdHlsZSAqLwoKICAgIGlmICghKHN0eWxlICYgKFdTX1BPUFVQIHwgV1NfQ0hJTEQpKSkgIC8qIE92ZXJsYXBwZWQgd2luZG93ICovCglzdHlsZSB8PSBXU19DQVBUSU9OOwogICAgc3R5bGUgJj0gKFdTX0RMR0ZSQU1FIHwgV1NfQk9SREVSIHwgV1NfVEhJQ0tGUkFNRSB8IFdTX0NISUxEKTsKICAgIGV4U3R5bGUgJj0gKFdTX0VYX0RMR01PREFMRlJBTUUgfCBXU19FWF9DTElFTlRFREdFIHwKCQlXU19FWF9TVEFUSUNFREdFIHwgV1NfRVhfVE9PTFdJTkRPVyk7CiAgICBpZiAoZXhTdHlsZSAmIFdTX0VYX0RMR01PREFMRlJBTUUpIHN0eWxlICY9IH5XU19USElDS0ZSQU1FOwoKICAgIFRSQUNFKCIoJWQsJWQpLSglZCwlZCkgJTA4bHggJWQgJTA4bHhcbiIsCiAgICAgICAgICByZWN0LT5sZWZ0LCByZWN0LT50b3AsIHJlY3QtPnJpZ2h0LCByZWN0LT5ib3R0b20sCiAgICAgICAgICBzdHlsZSwgbWVudSwgZXhTdHlsZSApOwoKICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQoJTkNfQWRqdXN0UmVjdCggcmVjdCwgc3R5bGUsIG1lbnUsIGV4U3R5bGUgKTsKICAgIGVsc2UgewoJTkNfQWRqdXN0UmVjdE91dGVyOTUoIHJlY3QsIHN0eWxlLCBtZW51LCBleFN0eWxlICk7CglOQ19BZGp1c3RSZWN0SW5uZXI5NSggcmVjdCwgc3R5bGUsIGV4U3R5bGUgKTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgQWRqdXN0V2luZG93UmVjdEV4ICAgIChVU0VSMzIuMykKICovCkJPT0wgV0lOQVBJIEFkanVzdFdpbmRvd1JlY3RFeCggTFBSRUNUIHJlY3QsIERXT1JEIHN0eWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIG1lbnUsIERXT1JEIGV4U3R5bGUgKQp7CiAgICBSRUNUMTYgcmVjdDE2OwogICAgQk9PTCByZXQ7CgogICAgQ09OVl9SRUNUMzJUTzE2KCByZWN0LCAmcmVjdDE2ICk7CiAgICByZXQgPSBBZGp1c3RXaW5kb3dSZWN0RXgxNiggJnJlY3QxNiwgc3R5bGUsIChCT09MMTYpbWVudSwgZXhTdHlsZSApOwogICAgQ09OVl9SRUNUMTZUTzMyKCAmcmVjdDE2LCByZWN0ICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19IYW5kbGVOQ0NhbGNTaXplCiAqCiAqIEhhbmRsZSBhIFdNX05DQ0FMQ1NJWkUgbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVOQ0NhbGNTaXplKCBXTkQgKnBXbmQsIFJFQ1QgKndpblJlY3QgKQp7CiAgICBSRUNUMTYgdG1wUmVjdCA9IHsgMCwgMCwgMCwgMCB9OwogICAgTE9ORyByZXN1bHQgPSAwOwogICAgVUlOVCBzdHlsZSA9IChVSU5UKSBHZXRDbGFzc0xvbmdBKHBXbmQtPmh3bmRTZWxmLCBHQ0xfU1RZTEUpOwoKICAgIGlmIChzdHlsZSAmIENTX1ZSRURSQVcpIHJlc3VsdCB8PSBXVlJfVlJFRFJBVzsKICAgIGlmIChzdHlsZSAmIENTX0hSRURSQVcpIHJlc3VsdCB8PSBXVlJfSFJFRFJBVzsKCiAgICBpZiggISggcFduZC0+ZHdTdHlsZSAmIFdTX01JTklNSVpFICkgKSB7CglpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKCSAgICBOQ19BZGp1c3RSZWN0KCAmdG1wUmVjdCwgcFduZC0+ZHdTdHlsZSwgRkFMU0UsIHBXbmQtPmR3RXhTdHlsZSApOwoJZWxzZQoJICAgIE5DX0FkanVzdFJlY3RPdXRlcjk1KCAmdG1wUmVjdCwgcFduZC0+ZHdTdHlsZSwgRkFMU0UsIHBXbmQtPmR3RXhTdHlsZSApOwoKCXdpblJlY3QtPmxlZnQgICAtPSB0bXBSZWN0LmxlZnQ7Cgl3aW5SZWN0LT50b3AgICAgLT0gdG1wUmVjdC50b3A7Cgl3aW5SZWN0LT5yaWdodCAgLT0gdG1wUmVjdC5yaWdodDsKCXdpblJlY3QtPmJvdHRvbSAtPSB0bXBSZWN0LmJvdHRvbTsKCglpZiAoSEFTX01FTlUocFduZCkpIHsKCSAgICBUUkFDRSgiQ2FsbGluZyBHZXRNZW51QmFySGVpZ2h0IHdpdGggSFdORCAweCV4LCB3aWR0aCAlZCwgIgogICAgICAgICAgICAgICAgICAiYXQgKCVkLCAlZCkuXG4iLCBwV25kLT5od25kU2VsZiwKICAgICAgICAgICAgICAgICAgd2luUmVjdC0+cmlnaHQgLSB3aW5SZWN0LT5sZWZ0LAogICAgICAgICAgICAgICAgICAtdG1wUmVjdC5sZWZ0LCAtdG1wUmVjdC50b3AgKTsKCgkgICAgd2luUmVjdC0+dG9wICs9CgkJTUVOVV9HZXRNZW51QmFySGVpZ2h0KCBwV25kLT5od25kU2VsZiwKCQkJCSAgICAgICB3aW5SZWN0LT5yaWdodCAtIHdpblJlY3QtPmxlZnQsCgkJCQkgICAgICAgLXRtcFJlY3QubGVmdCwgLXRtcFJlY3QudG9wICkgKyAxOwoJfQoKCWlmIChUV0VBS19XaW5lTG9vayA+IFdJTjMxX0xPT0spIHsKCSAgICBTZXRSZWN0MTYgKCZ0bXBSZWN0LCAwLCAwLCAwLCAwKTsKCSAgICBOQ19BZGp1c3RSZWN0SW5uZXI5NSAoJnRtcFJlY3QsIHBXbmQtPmR3U3R5bGUsIHBXbmQtPmR3RXhTdHlsZSk7CgkgICAgd2luUmVjdC0+bGVmdCAgIC09IHRtcFJlY3QubGVmdDsKCSAgICB3aW5SZWN0LT50b3AgICAgLT0gdG1wUmVjdC50b3A7CgkgICAgd2luUmVjdC0+cmlnaHQgIC09IHRtcFJlY3QucmlnaHQ7CgkgICAgd2luUmVjdC0+Ym90dG9tIC09IHRtcFJlY3QuYm90dG9tOwoJfQoKICAgICAgICBpZiAod2luUmVjdC0+dG9wID4gd2luUmVjdC0+Ym90dG9tKQogICAgICAgICAgICB3aW5SZWN0LT5ib3R0b20gPSB3aW5SZWN0LT50b3A7CgogICAgICAgIGlmICh3aW5SZWN0LT5sZWZ0ID4gd2luUmVjdC0+cmlnaHQpCiAgICAgICAgICAgIHdpblJlY3QtPnJpZ2h0ID0gd2luUmVjdC0+bGVmdDsKICAgIH0KICAgIHJldHVybiByZXN1bHQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0dldEluc2lkZVJlY3QKICoKICogR2V0IHRoZSAnaW5zaWRlJyByZWN0YW5nbGUgb2YgYSB3aW5kb3csIGkuZS4gdGhlIHdob2xlIHdpbmRvdyByZWN0YW5nbGUKICogYnV0IHdpdGhvdXQgdGhlIGJvcmRlcnMgKGlmIGFueSkuCiAqIFRoZSByZWN0YW5nbGUgaXMgaW4gd2luZG93IGNvb3JkaW5hdGVzIChmb3IgZHJhd2luZyB3aXRoIEdldFdpbmRvd0RDKCkpLgogKi8Kc3RhdGljIHZvaWQgTkNfR2V0SW5zaWRlUmVjdCggSFdORCBod25kLCBSRUNUICpyZWN0ICkKewogICAgV05EICogd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICByZWN0LT50b3AgICAgPSByZWN0LT5sZWZ0ID0gMDsKICAgIHJlY3QtPnJpZ2h0ICA9IHduZFB0ci0+cmVjdFdpbmRvdy5yaWdodCAtIHduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0OwogICAgcmVjdC0+Ym90dG9tID0gd25kUHRyLT5yZWN0V2luZG93LmJvdHRvbSAtIHduZFB0ci0+cmVjdFdpbmRvdy50b3A7CgogICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19JQ09OSUMpIHx8ICh3bmRQdHItPmZsYWdzICYgV0lOX01BTkFHRUQpKSBnb3RvIEVORDsKCiAgICAvKiBSZW1vdmUgZnJhbWUgZnJvbSByZWN0YW5nbGUgKi8KICAgIGlmIChIQVNfVEhJQ0tGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKQoJSW5mbGF0ZVJlY3QoIHJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRlJBTUUpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSApOwogICAgZWxzZQogICAgaWYgKEhBU19ETEdGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKQogICAgewoJSW5mbGF0ZVJlY3QoIHJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRExHRlJBTUUpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWURMR0ZSQU1FKSk7CgkvKiBGSVhNRTogdGhpcyBpc24ndCBpbiBOQ19BZGp1c3RSZWN0PyB3aHkgbm90PyAqLwoJaWYgKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfRExHTU9EQUxGUkFNRSkKICAgICAgICAgICAgSW5mbGF0ZVJlY3QoIHJlY3QsIC0xLCAwICk7CiAgICB9CiAgICBlbHNlCiAgICBpZiAoSEFTX1RISU5GUkFNRSggd25kUHRyLT5kd1N0eWxlICkpCglJbmZsYXRlUmVjdCggcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikgKTsKRU5EOgogICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKICAgIHJldHVybjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfR2V0SW5zaWRlUmVjdDk1CiAqCiAqIEdldCB0aGUgJ2luc2lkZScgcmVjdGFuZ2xlIG9mIGEgd2luZG93LCBpLmUuIHRoZSB3aG9sZSB3aW5kb3cgcmVjdGFuZ2xlCiAqIGJ1dCB3aXRob3V0IHRoZSBib3JkZXJzIChpZiBhbnkpLgogKiBUaGUgcmVjdGFuZ2xlIGlzIGluIHdpbmRvdyBjb29yZGluYXRlcyAoZm9yIGRyYXdpbmcgd2l0aCBHZXRXaW5kb3dEQygpKS4KICovCgpzdGF0aWMgdm9pZApOQ19HZXRJbnNpZGVSZWN0OTUgKEhXTkQgaHduZCwgUkVDVCAqcmVjdCkKewogICAgV05EICogd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICByZWN0LT50b3AgICAgPSByZWN0LT5sZWZ0ID0gMDsKICAgIHJlY3QtPnJpZ2h0ICA9IHduZFB0ci0+cmVjdFdpbmRvdy5yaWdodCAtIHduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0OwogICAgcmVjdC0+Ym90dG9tID0gd25kUHRyLT5yZWN0V2luZG93LmJvdHRvbSAtIHduZFB0ci0+cmVjdFdpbmRvdy50b3A7CgogICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19JQ09OSUMpIHx8ICh3bmRQdHItPmZsYWdzICYgV0lOX01BTkFHRUQpKSBnb3RvIEVORDsKCiAgICAvKiBSZW1vdmUgZnJhbWUgZnJvbSByZWN0YW5nbGUgKi8KICAgIGlmIChIQVNfVEhJQ0tGUkFNRSAod25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSkpCiAgICB7CglJbmZsYXRlUmVjdCggcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFRlJBTUUpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkVGUkFNRSkgKTsKICAgIH0KICAgIGVsc2UgaWYgKEhBU19ETEdGUkFNRSAod25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKQogICAgewoJSW5mbGF0ZVJlY3QoIHJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRklYRURGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRklYRURGUkFNRSkpOwogICAgfQogICAgZWxzZSBpZiAoSEFTX1RISU5GUkFNRSAod25kUHRyLT5kd1N0eWxlKSkKICAgIHsKICAgICAgICBJbmZsYXRlUmVjdCggcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikgKTsKICAgIH0KCiAgICAvKiBXZSBoYXZlIGFkZGl0aW9uYWwgYm9yZGVyIGluZm9ybWF0aW9uIGlmIHRoZSB3aW5kb3cKICAgICAqIGlzIGEgY2hpbGQgKGJ1dCBub3QgYW4gTURJIGNoaWxkKSAqLwogICAgaWYgKCAod25kUHRyLT5kd1N0eWxlICYgV1NfQ0hJTEQpICAmJgoJICggKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfTURJQ0hJTEQpID09IDAgKSApCiAgICB7IAoJaWYgKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfQ0xJRU5URURHRSkKCSAgICBJbmZsYXRlUmVjdCAocmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hFREdFKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lFREdFKSk7CgoJaWYgKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfU1RBVElDRURHRSkKCSAgICBJbmZsYXRlUmVjdCAocmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikpOwogICAgfQpFTkQ6CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE5DX0RvTkNIaXRUZXN0CiAqCiAqIEhhbmRsZSBhIFdNX05DSElUVEVTVCBtZXNzYWdlLiBDYWxsZWQgZnJvbSBOQ19IYW5kbGVOQ0hpdFRlc3QoKS4KICovCgpzdGF0aWMgTE9ORyBOQ19Eb05DSGl0VGVzdCAoV05EICp3bmRQdHIsIFBPSU5UIHB0ICkKewogICAgUkVDVCByZWN0OwoKICAgIFRSQUNFKCJod25kPSUwNHggcHQ9JWxkLCVsZFxuIiwgd25kUHRyLT5od25kU2VsZiwgcHQueCwgcHQueSApOwoKICAgIEdldFdpbmRvd1JlY3Qod25kUHRyLT5od25kU2VsZiwgJnJlY3QgKTsKICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFROT1dIRVJFOwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRSkgcmV0dXJuIEhUQ0FQVElPTjsKCiAgICBpZiAoISh3bmRQdHItPmZsYWdzICYgV0lOX01BTkFHRUQpKQogICAgewogICAgICAgIC8qIENoZWNrIGJvcmRlcnMgKi8KICAgICAgICBpZiAoSEFTX1RISUNLRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgICAgICB7CiAgICAgICAgICAgIEluZmxhdGVSZWN0KCAmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpICk7CiAgICAgICAgICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBDaGVjayB0b3Agc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVFRPUExFRlQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVFRPUFJJR0hUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVFRPUDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8qIENoZWNrIGJvdHRvbSBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVEJPVFRPTUxFRlQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVEJPVFRPTVJJR0hUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVEJPVFRPTTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8qIENoZWNrIGxlZnQgc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICAgICAgaWYgKHB0LnggPCByZWN0LmxlZnQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVFRPUExFRlQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnkgPj0gcmVjdC5ib3R0b20tR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRCT1RUT01MRUZUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVExFRlQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiBDaGVjayByaWdodCBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChwdC55IDwgcmVjdC50b3ArR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRUT1BSSUdIVDsKICAgICAgICAgICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbS1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVEJPVFRPTVJJR0hUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVFJJR0hUOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgIC8qIE5vIHRoaWNrIGZyYW1lICovCiAgICAgICAgewogICAgICAgICAgICBpZiAoSEFTX0RMR0ZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICkpCiAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCgmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hETEdGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRExHRlJBTUUpKTsKICAgICAgICAgICAgZWxzZSBpZiAoSEFTX1RISU5GUkFNRSggd25kUHRyLT5kd1N0eWxlICkpCiAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCgmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikpOwogICAgICAgICAgICBpZiAoIVB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUQk9SREVSOwogICAgICAgIH0KCiAgICAgICAgLyogQ2hlY2sgY2FwdGlvbiAqLwoKICAgICAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NBUFRJT04pID09IFdTX0NBUFRJT04pCiAgICAgICAgewogICAgICAgICAgICByZWN0LnRvcCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKTsKICAgICAgICAgICAgaWYgKCFQdEluUmVjdCggJnJlY3QsIHB0ICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIENoZWNrIHN5c3RlbSBtZW51ICovCiAgICAgICAgICAgICAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1NZU01FTlUpICYmICEod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9UT09MV0lORE9XKSkKICAgICAgICAgICAgICAgICAgICByZWN0LmxlZnQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpOwogICAgICAgICAgICAgICAgaWYgKHB0LnggPD0gcmVjdC5sZWZ0KSByZXR1cm4gSFRTWVNNRU5VOwoKICAgICAgICAgICAgICAgIC8qIENoZWNrIG1heGltaXplIGJveCAqLwogICAgICAgICAgICAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01BWElNSVpFQk9YKQogICAgICAgICAgICAgICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKCiAgICAgICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0KSByZXR1cm4gSFRNQVhCVVRUT047CiAgICAgICAgICAgICAgICAvKiBDaGVjayBtaW5pbWl6ZSBib3ggKi8KICAgICAgICAgICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRUJPWCkKICAgICAgICAgICAgICAgICAgICByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CiAgICAgICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0KSByZXR1cm4gSFRNSU5CVVRUT047CiAgICAgICAgICAgICAgICByZXR1cm4gSFRDQVBUSU9OOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgICAgLyogQ2hlY2sgY2xpZW50IGFyZWEgKi8KCiAgICBTY3JlZW5Ub0NsaWVudCggd25kUHRyLT5od25kU2VsZiwgJnB0ICk7CiAgICBHZXRDbGllbnRSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmcmVjdCApOwogICAgaWYgKFB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUQ0xJRU5UOwoKICAgICAgLyogQ2hlY2sgdmVydGljYWwgc2Nyb2xsIGJhciAqLwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19WU0NST0xMKQogICAgewoJcmVjdC5yaWdodCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCk7CglpZiAoUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFRWU0NST0xMOwogICAgfQoKICAgICAgLyogQ2hlY2sgaG9yaXpvbnRhbCBzY3JvbGwgYmFyICovCgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0hTQ1JPTEwpCiAgICB7CglyZWN0LmJvdHRvbSArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCk7CglpZiAoUHRJblJlY3QoICZyZWN0LCBwdCApKQoJewoJICAgICAgLyogQ2hlY2sgc2l6ZSBib3ggKi8KCSAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpICYmCgkJKHB0LnggPj0gcmVjdC5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKSkpCgkJcmV0dXJuIEhUU0laRTsKCSAgICByZXR1cm4gSFRIU0NST0xMOwoJfQogICAgfQoKICAgICAgLyogQ2hlY2sgbWVudSBiYXIgKi8KCiAgICBpZiAoSEFTX01FTlUod25kUHRyKSkKICAgIHsKCWlmICgocHQueSA8IDApICYmIChwdC54ID49IDApICYmIChwdC54IDwgcmVjdC5yaWdodCkpCgkgICAgcmV0dXJuIEhUTUVOVTsKICAgIH0KCiAgICAvKiBIYXMgdG8gcmV0dXJuIEhUTk9XSEVSRSBpZiBub3RoaW5nIHdhcyBmb3VuZCAgCiAgICAgICBDb3VsZCBoYXBwZW4gd2hlbiBhIHdpbmRvdyBoYXMgYSBjdXN0b21pemVkIG5vbiBjbGllbnQgYXJlYSAqLwogICAgcmV0dXJuIEhUTk9XSEVSRTsgIAp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE5DX0RvTkNIaXRUZXN0OTUKICoKICogSGFuZGxlIGEgV01fTkNISVRURVNUIG1lc3NhZ2UuIENhbGxlZCBmcm9tIE5DX0hhbmRsZU5DSGl0VGVzdCgpLgogKgogKiBGSVhNRTogIEp1c3QgYSBtb2RpZmllZCBjb3B5IG9mIHRoZSBXaW4gMy4xIHZlcnNpb24uCiAqLwoKc3RhdGljIExPTkcgTkNfRG9OQ0hpdFRlc3Q5NSAoV05EICp3bmRQdHIsIFBPSU5UIHB0ICkKewogICAgUkVDVCByZWN0OwoKICAgIFRSQUNFKCJod25kPSUwNHggcHQ9JWxkLCVsZFxuIiwgd25kUHRyLT5od25kU2VsZiwgcHQueCwgcHQueSApOwoKICAgIEdldFdpbmRvd1JlY3Qod25kUHRyLT5od25kU2VsZiwgJnJlY3QgKTsKICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFROT1dIRVJFOwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRSkgcmV0dXJuIEhUQ0FQVElPTjsKCiAgICBpZiAoISh3bmRQdHItPmZsYWdzICYgV0lOX01BTkFHRUQpKQogICAgewogICAgICAgIC8qIENoZWNrIGJvcmRlcnMgKi8KICAgICAgICBpZiAoSEFTX1RISUNLRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgICAgICB7CiAgICAgICAgICAgIEluZmxhdGVSZWN0KCAmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpICk7CiAgICAgICAgICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBDaGVjayB0b3Agc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVFRPUExFRlQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVFRPUFJJR0hUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVFRPUDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8qIENoZWNrIGJvdHRvbSBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVEJPVFRPTUxFRlQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVEJPVFRPTVJJR0hUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVEJPVFRPTTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8qIENoZWNrIGxlZnQgc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICAgICAgaWYgKHB0LnggPCByZWN0LmxlZnQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVFRPUExFRlQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnkgPj0gcmVjdC5ib3R0b20tR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRCT1RUT01MRUZUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVExFRlQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiBDaGVjayByaWdodCBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChwdC55IDwgcmVjdC50b3ArR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRUT1BSSUdIVDsKICAgICAgICAgICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbS1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVEJPVFRPTVJJR0hUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVFJJR0hUOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgIC8qIE5vIHRoaWNrIGZyYW1lICovCiAgICAgICAgewogICAgICAgICAgICBpZiAoSEFTX0RMR0ZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICkpCiAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCgmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hETEdGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRExHRlJBTUUpKTsKICAgICAgICAgICAgZWxzZSBpZiAoSEFTX1RISU5GUkFNRSggd25kUHRyLT5kd1N0eWxlICkpCiAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCgmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikpOwogICAgICAgICAgICBpZiAoIVB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUQk9SREVSOwogICAgICAgIH0KCiAgICAgICAgLyogQ2hlY2sgY2FwdGlvbiAqLwoKICAgICAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NBUFRJT04pID09IFdTX0NBUFRJT04pCiAgICAgICAgewoJICAgIGlmICh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX1RPT0xXSU5ET1cpCgkgICAgICAgIHJlY3QudG9wICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUNBUFRJT04pIC0gMTsKCSAgICBlbHNlCgkgICAgICAgIHJlY3QudG9wICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIDE7CiAgICAgICAgICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBDaGVjayBzeXN0ZW0gbWVudSAqLwogICAgICAgICAgICAgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19TWVNNRU5VKSAmJiAhKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykpCgkJewoJCSAgICBpZiAoTkNfSWNvbkZvcldpbmRvdyh3bmRQdHIpKQoJCQlyZWN0LmxlZnQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKCQl9CiAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCkgcmV0dXJuIEhUU1lTTUVOVTsKCiAgICAgICAgICAgICAgICAvKiBDaGVjayBjbG9zZSBidXR0b24gKi8KICAgICAgICAgICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19TWVNNRU5VKQogICAgICAgICAgICAgICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKICAgICAgICAgICAgICAgIGlmIChwdC54ID4gcmVjdC5yaWdodCkgcmV0dXJuIEhUQ0xPU0U7CgogICAgICAgICAgICAgICAgLyogQ2hlY2sgbWF4aW1pemUgYm94ICovCgkJLyogSW4gd2luOTUgdGhlcmUgaXMgYXV0b21hdGljYWxseSBhIE1heGltaXplIGJ1dHRvbiB3aGVuIHRoZXJlIGlzIGEgbWluaW1pemUgb25lKi8KICAgICAgICAgICAgICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfTUFYSU1JWkVCT1gpfHwgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFQk9YKSkKICAgICAgICAgICAgICAgICAgICByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CiAgICAgICAgICAgICAgICBpZiAocHQueCA+IHJlY3QucmlnaHQpIHJldHVybiBIVE1BWEJVVFRPTjsKCiAgICAgICAgICAgICAgICAvKiBDaGVjayBtaW5pbWl6ZSBib3ggKi8KCQkvKiBJbiB3aW45NSB0aGVyZSBpcyBhdXRvbWF0aWNhbGx5IGEgTWF4aW1pemUgYnV0dG9uIHdoZW4gdGhlcmUgaXMgYSBNYXhpbWl6ZSBvbmUqLwogICAgICAgICAgICAgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRUJPWCl8fCh3bmRQdHItPmR3U3R5bGUgJiBXU19NQVhJTUlaRUJPWCkpCiAgICAgICAgICAgICAgICAgICAgcmVjdC5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwoKICAgICAgICAgICAgICAgIGlmIChwdC54ID4gcmVjdC5yaWdodCkgcmV0dXJuIEhUTUlOQlVUVE9OOwogICAgICAgICAgICAgICAgcmV0dXJuIEhUQ0FQVElPTjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAgIC8qIENoZWNrIGNsaWVudCBhcmVhICovCgogICAgU2NyZWVuVG9DbGllbnQoIHduZFB0ci0+aHduZFNlbGYsICZwdCApOwogICAgR2V0Q2xpZW50UmVjdCggd25kUHRyLT5od25kU2VsZiwgJnJlY3QgKTsKICAgIGlmIChQdEluUmVjdCggJnJlY3QsIHB0ICkpIHJldHVybiBIVENMSUVOVDsKCiAgICAgIC8qIENoZWNrIHZlcnRpY2FsIHNjcm9sbCBiYXIgKi8KCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfVlNDUk9MTCkKICAgIHsKCXJlY3QucmlnaHQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpOwoJaWYgKFB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUVlNDUk9MTDsKICAgIH0KCiAgICAgIC8qIENoZWNrIGhvcml6b250YWwgc2Nyb2xsIGJhciAqLwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19IU0NST0xMKQogICAgewoJcmVjdC5ib3R0b20gKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpOwoJaWYgKFB0SW5SZWN0KCAmcmVjdCwgcHQgKSkKCXsKCSAgICAgIC8qIENoZWNrIHNpemUgYm94ICovCgkgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19WU0NST0xMKSAmJgoJCShwdC54ID49IHJlY3QucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCkpKQoJCXJldHVybiBIVFNJWkU7CgkgICAgcmV0dXJuIEhUSFNDUk9MTDsKCX0KICAgIH0KCiAgICAgIC8qIENoZWNrIG1lbnUgYmFyICovCgogICAgaWYgKEhBU19NRU5VKHduZFB0cikpCiAgICB7CglpZiAoKHB0LnkgPCAwKSAmJiAocHQueCA+PSAwKSAmJiAocHQueCA8IHJlY3QucmlnaHQpKQoJICAgIHJldHVybiBIVE1FTlU7CiAgICB9CgogICAgLyogSGFzIHRvIHJldHVybiBIVE5PV0hFUkUgaWYgbm90aGluZyB3YXMgZm91bmQgIAogICAgICAgQ291bGQgaGFwcGVuIHdoZW4gYSB3aW5kb3cgaGFzIGEgY3VzdG9taXplZCBub24gY2xpZW50IGFyZWEgKi8KICAgIHJldHVybiBIVE5PV0hFUkU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTkNfSGFuZGxlTkNIaXRUZXN0CiAqCiAqIEhhbmRsZSBhIFdNX05DSElUVEVTVCBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZU5DSGl0VGVzdCAoSFdORCBod25kICwgUE9JTlQgcHQpCnsKICAgIExPTkcgcmV0dmFsdWU7CiAgICBXTkQgKnduZFB0ciA9IFdJTl9GaW5kV25kUHRyIChod25kKTsKCiAgICBpZiAoIXduZFB0cikKCXJldHVybiBIVEVSUk9SOwoKICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQogICAgICAgIHJldHZhbHVlID0gTkNfRG9OQ0hpdFRlc3QgKHduZFB0ciwgcHQpOwogICAgZWxzZQogICAgICAgIHJldHZhbHVlID0gTkNfRG9OQ0hpdFRlc3Q5NSAod25kUHRyLCBwdCk7CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuIHJldHZhbHVlOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3U3lzQnV0dG9uCiAqLwp2b2lkIE5DX0RyYXdTeXNCdXR0b24oIEhXTkQgaHduZCwgSERDIGhkYywgQk9PTCBkb3duICkKewogICAgUkVDVCByZWN0OwogICAgSERDIGhkY01lbTsKICAgIEhCSVRNQVAgaGJpdG1hcDsKICAgIFdORCAqd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICBpZiggISh3bmRQdHItPmZsYWdzICYgV0lOX01BTkFHRUQpICkKICAgIHsKICAgICAgTkNfR2V0SW5zaWRlUmVjdCggaHduZCwgJnJlY3QgKTsKICAgICAgaGRjTWVtID0gQ3JlYXRlQ29tcGF0aWJsZURDKCBoZGMgKTsKICAgICAgaGJpdG1hcCA9IFNlbGVjdE9iamVjdCggaGRjTWVtLCBoYml0bWFwQ2xvc2UgKTsKICAgICAgQml0Qmx0KGhkYywgcmVjdC5sZWZ0LCByZWN0LnRvcCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSksCiAgICAgICAgICAgICAgIGhkY01lbSwgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NISUxEKSA/IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSA6IDAsIDAsCiAgICAgICAgICAgICAgIGRvd24gPyBOT1RTUkNDT1BZIDogU1JDQ09QWSApOwogICAgICBTZWxlY3RPYmplY3QoIGhkY01lbSwgaGJpdG1hcCApOwogICAgICBEZWxldGVEQyggaGRjTWVtICk7CiAgICB9CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3TWF4QnV0dG9uCiAqLwpzdGF0aWMgdm9pZCBOQ19EcmF3TWF4QnV0dG9uKCBIV05EIGh3bmQsIEhEQzE2IGhkYywgQk9PTCBkb3duICkKewogICAgUkVDVCByZWN0OwogICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwogICAgSERDIGhkY01lbTsKCiAgICBpZiggISh3bmRQdHItPmZsYWdzICYgV0lOX01BTkFHRUQpICkKICAgIHsKICAgICAgTkNfR2V0SW5zaWRlUmVjdCggaHduZCwgJnJlY3QgKTsKICAgICAgaGRjTWVtID0gQ3JlYXRlQ29tcGF0aWJsZURDKCBoZGMgKTsKICAgICAgU2VsZWN0T2JqZWN0KCBoZGNNZW0sICAoSXNab29tZWQoaHduZCkgCgkJCSAgICAgPyAoZG93biA/IGhiaXRtYXBSZXN0b3JlRCA6IGhiaXRtYXBSZXN0b3JlKQoJCQkgICAgIDogKGRvd24gPyBoYml0bWFwTWF4aW1pemVEIDogaGJpdG1hcE1heGltaXplKSkgKTsKICAgICAgQml0Qmx0KCBoZGMsIHJlY3QucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgLSAxLCByZWN0LnRvcCwKCQlHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSksIGhkY01lbSwgMCwgMCwKCQlTUkNDT1BZICk7CiAgICAgIERlbGV0ZURDKCBoZGNNZW0gKTsKICAgIH0KICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7Cgp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3TWluQnV0dG9uCiAqLwpzdGF0aWMgdm9pZCBOQ19EcmF3TWluQnV0dG9uKCBIV05EIGh3bmQsIEhEQzE2IGhkYywgQk9PTCBkb3duICkKewogICAgUkVDVCByZWN0OwogICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwogICAgSERDIGhkY01lbTsKCiAgICBpZiggISh3bmRQdHItPmZsYWdzICYgV0lOX01BTkFHRUQpICkKICAgIHsKICAgICAgTkNfR2V0SW5zaWRlUmVjdCggaHduZCwgJnJlY3QgKTsKICAgICAgaGRjTWVtID0gQ3JlYXRlQ29tcGF0aWJsZURDKCBoZGMgKTsKICAgICAgU2VsZWN0T2JqZWN0KCBoZGNNZW0sIChkb3duID8gaGJpdG1hcE1pbmltaXplRCA6IGhiaXRtYXBNaW5pbWl6ZSkgKTsKICAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01BWElNSVpFQk9YKSByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSsxOwogICAgICBCaXRCbHQoIGhkYywgcmVjdC5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSAtIDEsIHJlY3QudG9wLAoJCUdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDEsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSwgaGRjTWVtLCAwLCAwLAoJCVNSQ0NPUFkgKTsKICAgICAgRGVsZXRlREMoIGhkY01lbSApOwogICAgfQogICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICB2b2lkICBOQ19EcmF3U3lzQnV0dG9uOTUoCiAqICAgICAgSFdORCAgaHduZCwKICogICAgICBIREMgIGhkYywKICogICAgICBCT09MICBkb3duICkKICoKICogICBEcmF3cyB0aGUgV2luOTUgc3lzdGVtIGljb24uCiAqCiAqICAgUmV2aXNpb24gaGlzdG9yeQogKiAgICAgICAgMDUtSnVsLTE5OTcgRGF2ZSBDdXRoYmVydCAoZGFjdXRAZWNlLmNtdS5lZHUpCiAqICAgICAgICAgICAgIE9yaWdpbmFsIGltcGxlbWVudGF0aW9uIGZyb20gTkNfRHJhd1N5c0J1dHRvbiBzb3VyY2UuCiAqICAgICAgICAxMS1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgICAgICBGaXhlZCBtb3N0IGJ1Z3MuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCkJPT0wKTkNfRHJhd1N5c0J1dHRvbjk1IChIV05EIGh3bmQsIEhEQyBoZGMsIEJPT0wgZG93bikKewogICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwoKICAgIGlmKCAhKHduZFB0ci0+ZmxhZ3MgJiBXSU5fTUFOQUdFRCkgKQogICAgewoJSElDT04gIGhJY29uOwoJUkVDVCByZWN0OwoKCU5DX0dldEluc2lkZVJlY3Q5NSggaHduZCwgJnJlY3QgKTsKCgloSWNvbiA9IE5DX0ljb25Gb3JXaW5kb3coIHduZFB0ciApOwoKCWlmIChoSWNvbikKCSAgICBEcmF3SWNvbkV4IChoZGMsIHJlY3QubGVmdCArIDIsIHJlY3QudG9wICsgMiwgaEljb24sCgkJCSAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNNSUNPTiksCgkJCSAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNSUNPTiksCgkJCSAgMCwgMCwgRElfTk9STUFMKTsKCiAgICAgICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKCXJldHVybiAoaEljb24gIT0gMCk7CiAgICB9CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuIEZBTFNFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIHZvaWQgIE5DX0RyYXdDbG9zZUJ1dHRvbjk1KAogKiAgICAgIEhXTkQgIGh3bmQsCiAqICAgICAgSERDICBoZGMsCiAqICAgICAgQk9PTCAgZG93biwKICogICAgICBCT09MICAgIGJHcmF5ZWQgKQogKgogKiAgIERyYXdzIHRoZSBXaW45NSBjbG9zZSBidXR0b24uCiAqCiAqICAgSWYgYkdyYXllZCBpcyB0cnVlLCB0aGVuIGRyYXcgYSBkaXNhYmxlZCBDbG9zZSBidXR0b24KICoKICogICBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAgICAxMS1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgICAgICBPcmlnaW5hbCBpbXBsZW1lbnRhdGlvbiBmcm9tIE5DX0RyYXdTeXNCdXR0b245NSBzb3VyY2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkIE5DX0RyYXdDbG9zZUJ1dHRvbjk1IChIV05EIGh3bmQsIEhEQyBoZGMsIEJPT0wgZG93biwgQk9PTCBiR3JheWVkKQp7CiAgICBSRUNUIHJlY3Q7CiAgICBIREMgaGRjTWVtOwogICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwoKICAgIGlmKCAhKHduZFB0ci0+ZmxhZ3MgJiBXSU5fTUFOQUdFRCkgKQogICAgewoJQklUTUFQIGJtcDsKCUhCSVRNQVAgaEJtcCwgaE9sZEJtcDsKCglOQ19HZXRJbnNpZGVSZWN0OTUoIGh3bmQsICZyZWN0ICk7CgoJLyogQSB0b29sIHdpbmRvdyBoYXMgYSBzbWFsbGVyIENsb3NlIGJ1dHRvbiAqLwoJaWYod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9UT09MV0lORE9XKQoJewogICAgICAgICAgICBSRUNUIHRvb2xSZWN0OwkgICAgIAogICAgICAgICAgICBJTlQgaUJtcEhlaWdodCA9IDExOyAvKiBXaW5kb3dzIGRvZXMgbm90IHVzZSBTTV9DWFNNU0laRSBhbmQgU01fQ1lTTVNJWkUgICAqLwogICAgICAgICAgICBJTlQgaUJtcFdpZHRoID0gMTE7ICAvKiBpdCB1c2VzIDExeDExIGZvciAgdGhlIGNsb3NlIGJ1dHRvbiBpbiB0b29sIHdpbmRvdyAqLyAJICAJIAogICAgICAgICAgICBJTlQgaUNhcHRpb25IZWlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01DQVBUSU9OKTsKCiAgICAgICAgICAgIHRvb2xSZWN0LnRvcCA9IHJlY3QudG9wICsgKGlDYXB0aW9uSGVpZ2h0IC0gMSAtIGlCbXBIZWlnaHQpIC8gMjsKICAgICAgICAgICAgdG9vbFJlY3QubGVmdCA9IHJlY3QucmlnaHQgLSAoaUNhcHRpb25IZWlnaHQgKyAxICsgaUJtcFdpZHRoKSAvIDI7CiAgICAgICAgICAgIHRvb2xSZWN0LmJvdHRvbSA9IHRvb2xSZWN0LnRvcCArIGlCbXBIZWlnaHQ7CiAgICAgICAgICAgIHRvb2xSZWN0LnJpZ2h0ID0gdG9vbFJlY3QubGVmdCArIGlCbXBXaWR0aDsKICAgICAgICAgICAgRHJhd0ZyYW1lQ29udHJvbChoZGMsJnRvb2xSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIERGQ19DQVBUSU9OLERGQ1NfQ0FQVElPTkNMT1NFIHwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG93biA/IERGQ1NfUFVTSEVEIDogMCB8IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJHcmF5ZWQgPyBERkNTX0lOQUNUSVZFIDogMCk7Cgl9CgllbHNlCgl7CiAgICAgICAgICAgIGhkY01lbSA9IENyZWF0ZUNvbXBhdGlibGVEQyggaGRjICk7CiAgICAgICAgICAgIGhCbXAgPSBkb3duID8gaGJpdG1hcENsb3NlRCA6IGhiaXRtYXBDbG9zZTsKICAgICAgICAgICAgaE9sZEJtcCA9IFNlbGVjdE9iamVjdCAoaGRjTWVtLCBoQm1wKTsKICAgICAgICAgICAgR2V0T2JqZWN0QSAoaEJtcCwgc2l6ZW9mKEJJVE1BUCksICZibXApOwoKICAgICAgICAgICAgQml0Qmx0IChoZGMsIHJlY3QucmlnaHQgLSAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pICsgMSArIGJtcC5ibVdpZHRoKSAvIDIsCiAgICAgICAgICAgICAgICAgICAgcmVjdC50b3AgKyAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMSAtIGJtcC5ibUhlaWdodCkgLyAyLAogICAgICAgICAgICAgICAgICAgIGJtcC5ibVdpZHRoLCBibXAuYm1IZWlnaHQsIGhkY01lbSwgMCwgMCwgU1JDQ09QWSk7CgogICAgICAgICAgICBpZihiR3JheWVkKQogICAgICAgICAgICAgICAgTkNfRHJhd0dyYXlCdXR0b24oaGRjLHJlY3QucmlnaHQgLSAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pICsgMSArIGJtcC5ibVdpZHRoKSAvIDIgKyAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjdC50b3AgKyAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMSAtIGJtcC5ibUhlaWdodCkgLyAyICsgMik7CgogICAgICAgICAgICBTZWxlY3RPYmplY3QgKGhkY01lbSwgaE9sZEJtcCk7CiAgICAgICAgICAgIERlbGV0ZURDIChoZGNNZW0pOwoJfQogICAgfQogICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIE5DX0RyYXdNYXhCdXR0b245NSgKICogICAgICBIV05EICBod25kLAogKiAgICAgIEhEQzE2ICBoZGMsCiAqICAgICAgQk9PTCAgZG93biAKICogICAgICBCT09MICAgIGJHcmF5ZWQgKQogKgogKiAgIERyYXdzIHRoZSBtYXhpbWl6ZSBidXR0b24gZm9yIFdpbjk1IHN0eWxlIHdpbmRvd3MuCiAqCiAqICAgSWYgYkdyYXllZCBpcyB0cnVlLCB0aGVuIGRyYXcgYSBkaXNhYmxlZCBNYXhpbWl6ZSBidXR0b24KICoKICogICBCdWdzCiAqICAgICAgICBNYW55LiAgU3BhY2luZyBtaWdodCBzdGlsbCBiZSBpbmNvcnJlY3QuICBOZWVkIHRvIGZpdCBhIGNsb3NlCiAqICAgICAgICBidXR0b24gYmV0d2VlbiB0aGUgbWF4IGJ1dHRvbiBhbmQgdGhlIGVkZ2UuCiAqICAgICAgICBTaG91bGQgc2NhbGUgdGhlIGltYWdlIHdpdGggdGhlIHRpdGxlIGJhci4gIEFuZCBtb3JlLi4uCiAqCiAqICAgUmV2aXNpb24gaGlzdG9yeQogKiAgICAgICAgMDUtSnVsLTE5OTcgRGF2ZSBDdXRoYmVydCAoZGFjdXRAZWNlLmNtdS5lZHUpCiAqICAgICAgICAgICAgIE9yaWdpbmFsIGltcGxlbWVudGF0aW9uLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZCBOQ19EcmF3TWF4QnV0dG9uOTUoSFdORCBod25kLEhEQzE2IGhkYyxCT09MIGRvd24sIEJPT0wgYkdyYXllZCkKewogICAgUkVDVCByZWN0OwogICAgSERDIGhkY01lbTsKICAgIFdORCAqd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICBpZiggISh3bmRQdHItPmZsYWdzICYgV0lOX01BTkFHRUQpKQogICAgewogICAgICAgIEJJVE1BUCAgYm1wOwogICAgICAgIEhCSVRNQVAgIGhCbXAsaE9sZEJtcDsKCglOQ19HZXRJbnNpZGVSZWN0OTUoIGh3bmQsICZyZWN0ICk7CgloZGNNZW0gPSBDcmVhdGVDb21wYXRpYmxlREMoIGhkYyApOwoJaEJtcCA9IElzWm9vbWVkKGh3bmQpID8KCSAgICAoZG93biA/IGhiaXRtYXBSZXN0b3JlRCA6IGhiaXRtYXBSZXN0b3JlICkgOgoJICAgIChkb3duID8gaGJpdG1hcE1heGltaXplRDogaGJpdG1hcE1heGltaXplKTsKCWhPbGRCbXA9U2VsZWN0T2JqZWN0KCBoZGNNZW0sIGhCbXAgKTsKCUdldE9iamVjdEEgKGhCbXAsIHNpemVvZihCSVRNQVApLCAmYm1wKTsKCQoJaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1NZU01FTlUpCgkgICAgcmVjdC5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgKyAxOwoJCglCaXRCbHQoIGhkYywgcmVjdC5yaWdodCAtIChHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyBibXAuYm1XaWR0aCkgLyAyLAoJCSAgcmVjdC50b3AgKyAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMSAtIGJtcC5ibUhlaWdodCkgLyAyLAoJCSAgYm1wLmJtV2lkdGgsIGJtcC5ibUhlaWdodCwgaGRjTWVtLCAwLCAwLCBTUkNDT1BZICk7CgkKCWlmKGJHcmF5ZWQpCgkgICAgTkNfRHJhd0dyYXlCdXR0b24oaGRjLCByZWN0LnJpZ2h0IC0gKEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIGJtcC5ibVdpZHRoKSAvIDIgKyAyLAoJCQkgICAgICByZWN0LnRvcCArIChHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSAxIC0gYm1wLmJtSGVpZ2h0KSAvIDIgKyAyKTsKCSAgICAKCQoJU2VsZWN0T2JqZWN0IChoZGNNZW0sIGhPbGRCbXApOwoJRGVsZXRlREMoIGhkY01lbSApOwogICAgfQogICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIE5DX0RyYXdNaW5CdXR0b245NSgKICogICAgICBIV05EICBod25kLAogKiAgICAgIEhEQzE2ICBoZGMsCiAqICAgICAgQk9PTCAgZG93biwKICogICAgICBCT09MICAgIGJHcmF5ZWQgKQogKgogKiAgIERyYXdzIHRoZSBtaW5pbWl6ZSBidXR0b24gZm9yIFdpbjk1IHN0eWxlIHdpbmRvd3MuCiAqCiAqICAgSWYgYkdyYXllZCBpcyB0cnVlLCB0aGVuIGRyYXcgYSBkaXNhYmxlZCBNaW5pbWl6ZSBidXR0b24KICoKICogICBCdWdzCiAqICAgICAgICBNYW55LiAgU3BhY2luZyBpcyBzdGlsbCBpbmNvcnJlY3QuICBTaG91bGQgc2NhbGUgdGhlIGltYWdlIHdpdGggdGhlCiAqICAgICAgICB0aXRsZSBiYXIuICBBbmQgbW9yZS4uLgogKgogKiAgIFJldmlzaW9uIGhpc3RvcnkKICogICAgICAgIDA1LUp1bC0xOTk3IERhdmUgQ3V0aGJlcnQgKGRhY3V0QGVjZS5jbXUuZWR1KQogKiAgICAgICAgICAgICBPcmlnaW5hbCBpbXBsZW1lbnRhdGlvbi4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHZvaWQgIE5DX0RyYXdNaW5CdXR0b245NShIV05EIGh3bmQsSERDMTYgaGRjLEJPT0wgZG93biwgQk9PTCBiR3JheWVkKQp7CiAgICBSRUNUIHJlY3Q7CiAgICBIREMgaGRjTWVtOwogICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwoKICAgIGlmKCAhKHduZFB0ci0+ZmxhZ3MgJiBXSU5fTUFOQUdFRCkpCiAgICAgICAgCiAgICB7CiAgICAgICBCSVRNQVAgIGJtcDsKICAgICAgIEhCSVRNQVAgIGhCbXAsaE9sZEJtcDsKCQoJTkNfR2V0SW5zaWRlUmVjdDk1KCBod25kLCAmcmVjdCApOwoKICAgICAgIGhkY01lbSA9IENyZWF0ZUNvbXBhdGlibGVEQyggaGRjICk7CiAgICAgICBoQm1wID0gZG93biA/IGhiaXRtYXBNaW5pbWl6ZUQgOiBoYml0bWFwTWluaW1pemU7CiAgICAgICBoT2xkQm1wPSBTZWxlY3RPYmplY3QoIGhkY01lbSwgaEJtcCApOwoJR2V0T2JqZWN0QSAoaEJtcCwgc2l6ZW9mKEJJVE1BUCksICZibXApOwoKCWlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19TWVNNRU5VKQoJICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pICsgMTsKCgkvKiBJbiB3aW4gOTUgdGhlcmUgaXMgYWx3YXlzIGEgTWF4aW1pemUgYm94IHdoZW4gdGhlcmUgaXMgYSBNaW5pbWl6ZSBvbmUgKi8KCWlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfTUFYSU1JWkVCT1gpIHx8ICh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRUJPWCkpIAoJICAgIHJlY3QucmlnaHQgKz0gLTEgLSAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgYm1wLmJtV2lkdGgpIC8gMjsKCglCaXRCbHQoIGhkYywgcmVjdC5yaWdodCAtIChHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyBibXAuYm1XaWR0aCkgLyAyLAoJCSAgcmVjdC50b3AgKyAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMSAtIGJtcC5ibUhlaWdodCkgLyAyLAoJCSAgYm1wLmJtV2lkdGgsIGJtcC5ibUhlaWdodCwgaGRjTWVtLCAwLCAwLCBTUkNDT1BZICk7CgoJaWYoYkdyYXllZCkKCSAgICBOQ19EcmF3R3JheUJ1dHRvbihoZGMsIHJlY3QucmlnaHQgLSAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgYm1wLmJtV2lkdGgpIC8gMiArIDIsCgkJCSAgICAgIHJlY3QudG9wICsgKEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIDEgLSBibXAuYm1IZWlnaHQpIC8gMiArIDIpOwoJCQkgIAoJCiAgICAgICBTZWxlY3RPYmplY3QgKGhkY01lbSwgaE9sZEJtcCk7CiAgICAgICBEZWxldGVEQyggaGRjTWVtICk7CiAgICB9CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0RyYXdGcmFtZQogKgogKiBEcmF3IGEgd2luZG93IGZyYW1lIGluc2lkZSB0aGUgZ2l2ZW4gcmVjdGFuZ2xlLCBhbmQgdXBkYXRlIHRoZSByZWN0YW5nbGUuCiAqIFRoZSBjb3JyZWN0IHBlbiBmb3IgdGhlIGZyYW1lIG11c3QgYmUgc2VsZWN0ZWQgaW4gdGhlIERDLgogKi8Kc3RhdGljIHZvaWQgTkNfRHJhd0ZyYW1lKCBIREMgaGRjLCBSRUNUICpyZWN0LCBCT09MIGRsZ0ZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgYWN0aXZlICkKewogICAgSU5UIHdpZHRoLCBoZWlnaHQ7CgogICAgaWYgKFRXRUFLX1dpbmVMb29rICE9IFdJTjMxX0xPT0spCglFUlIoIkNhbGxlZCBpbiBXaW45NSBtb2RlLiBBaWVlISBQbGVhc2UgcmVwb3J0IHRoaXMuXG4iICk7CgogICAgaWYgKGRsZ0ZyYW1lKQogICAgewoJd2lkdGggPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRExHRlJBTUUpIC0gMTsKCWhlaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lETEdGUkFNRSkgLSAxOwogICAgICAgIFNlbGVjdE9iamVjdCggaGRjLCBHZXRTeXNDb2xvckJydXNoKGFjdGl2ZSA/IENPTE9SX0FDVElWRUNBUFRJT04gOgoJCQkJCQlDT0xPUl9JTkFDVElWRUNBUFRJT04pICk7CiAgICB9CiAgICBlbHNlCiAgICB7Cgl3aWR0aCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSkgLSAyOwoJaGVpZ2h0ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSAtIDI7CiAgICAgICAgU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN5c0NvbG9yQnJ1c2goYWN0aXZlID8gQ09MT1JfQUNUSVZFQk9SREVSIDoKCQkJCQkJQ09MT1JfSU5BQ1RJVkVCT1JERVIpICk7CiAgICB9CgogICAgICAvKiBEcmF3IGZyYW1lICovCiAgICBQYXRCbHQoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+dG9wLAogICAgICAgICAgICAgIHJlY3QtPnJpZ2h0IC0gcmVjdC0+bGVmdCwgaGVpZ2h0LCBQQVRDT1BZICk7CiAgICBQYXRCbHQoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+dG9wLAogICAgICAgICAgICAgIHdpZHRoLCByZWN0LT5ib3R0b20gLSByZWN0LT50b3AsIFBBVENPUFkgKTsKICAgIFBhdEJsdCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT5ib3R0b20gLSAxLAogICAgICAgICAgICAgIHJlY3QtPnJpZ2h0IC0gcmVjdC0+bGVmdCwgLWhlaWdodCwgUEFUQ09QWSApOwogICAgUGF0Qmx0KCBoZGMsIHJlY3QtPnJpZ2h0IC0gMSwgcmVjdC0+dG9wLAogICAgICAgICAgICAgIC13aWR0aCwgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLCBQQVRDT1BZICk7CgogICAgaWYgKGRsZ0ZyYW1lKQogICAgewoJSW5mbGF0ZVJlY3QoIHJlY3QsIC13aWR0aCwgLWhlaWdodCApOwogICAgfSAKICAgIGVsc2UKICAgIHsKICAgICAgICBJTlQgZGVjWU9mZiA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSkgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgLSAxOwoJSU5UIGRlY1hPZmYgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpIC0gMTsKCiAgICAgIC8qIERyYXcgaW5uZXIgcmVjdGFuZ2xlICovCgoJU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN0b2NrT2JqZWN0KE5VTExfQlJVU0gpICk7CglSZWN0YW5nbGUoIGhkYywgcmVjdC0+bGVmdCArIHdpZHRoLCByZWN0LT50b3AgKyBoZWlnaHQsCgkJICAgICByZWN0LT5yaWdodCAtIHdpZHRoICwgcmVjdC0+Ym90dG9tIC0gaGVpZ2h0ICk7CgogICAgICAvKiBEcmF3IHRoZSBkZWNvcmF0aW9ucyAqLwoKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCArIGRlY1lPZmYsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByZWN0LT5sZWZ0ICsgd2lkdGgsIHJlY3QtPnRvcCArIGRlY1lPZmYgKTsKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPnJpZ2h0IC0gMSwgcmVjdC0+dG9wICsgZGVjWU9mZiwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHJlY3QtPnJpZ2h0IC0gd2lkdGggLSAxLCByZWN0LT50b3AgKyBkZWNZT2ZmICk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT5ib3R0b20gLSBkZWNZT2ZmLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+bGVmdCArIHdpZHRoLCByZWN0LT5ib3R0b20gLSBkZWNZT2ZmICk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5yaWdodCAtIDEsIHJlY3QtPmJvdHRvbSAtIGRlY1lPZmYsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByZWN0LT5yaWdodCAtIHdpZHRoIC0gMSwgcmVjdC0+Ym90dG9tIC0gZGVjWU9mZiApOwoKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPmxlZnQgKyBkZWNYT2ZmLCByZWN0LT50b3AsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByZWN0LT5sZWZ0ICsgZGVjWE9mZiwgcmVjdC0+dG9wICsgaGVpZ2h0KTsKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPmxlZnQgKyBkZWNYT2ZmLCByZWN0LT5ib3R0b20gLSAxLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+bGVmdCArIGRlY1hPZmYsIHJlY3QtPmJvdHRvbSAtIGhlaWdodCAtIDEgKTsKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPnJpZ2h0IC0gZGVjWE9mZiwgcmVjdC0+dG9wLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+cmlnaHQgLSBkZWNYT2ZmLCByZWN0LT50b3AgKyBoZWlnaHQgKTsKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPnJpZ2h0IC0gZGVjWE9mZiwgcmVjdC0+Ym90dG9tIC0gMSwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHJlY3QtPnJpZ2h0IC0gZGVjWE9mZiwgcmVjdC0+Ym90dG9tIC0gaGVpZ2h0IC0gMSApOwoKCUluZmxhdGVSZWN0KCByZWN0LCAtd2lkdGggLSAxLCAtaGVpZ2h0IC0gMSApOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIHZvaWQgIE5DX0RyYXdGcmFtZTk1KAogKiAgICAgIEhEQyAgaGRjLAogKiAgICAgIFJFQ1QgICpyZWN0LAogKiAgICAgIEJPT0wgIGRsZ0ZyYW1lLAogKiAgICAgIEJPT0wgIGFjdGl2ZSApCiAqCiAqICAgRHJhdyBhIHdpbmRvdyBmcmFtZSBpbnNpZGUgdGhlIGdpdmVuIHJlY3RhbmdsZSwgYW5kIHVwZGF0ZSB0aGUgcmVjdGFuZ2xlLgogKiAgIFRoZSBjb3JyZWN0IHBlbiBmb3IgdGhlIGZyYW1lIG11c3QgYmUgc2VsZWN0ZWQgaW4gdGhlIERDLgogKgogKiAgIEJ1Z3MKICogICAgICAgIE1hbnkuICBGaXJzdCwganVzdCB3aGF0IElTIGEgZnJhbWUgaW4gV2luOTU/ICBOb3RlIHRoYXQgdGhlIDNEIGxvb2sKICogICAgICAgIG9uIHRoZSBvdXRlciBlZGdlIGlzIGhhbmRsZWQgYnkgTkNfRG9OQ1BhaW50OTUuICBBcyBpcyB0aGUgaW5uZXIKICogICAgICAgIGVkZ2UuICBUaGUgaW5uZXIgcmVjdGFuZ2xlIGp1c3QgaW5zaWRlIHRoZSBmcmFtZSBpcyBoYW5kbGVkIGJ5IHRoZQogKiAgICAgICAgQ2FwdGlvbiBjb2RlLgogKgogKiAgICAgICAgSW4gc2hvcnQsIGZvciBtb3N0IHBlb3BsZSwgdGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgYSBub3AgKHVubGVzcwogKiAgICAgICAgeW91IExJS0UgdGhpY2sgYm9yZGVycyBpbiBXaW45NS9OVDQuMCAtLSBJJ3ZlIGJlZW4gd29ya2luZyB3aXRoCiAqICAgICAgICB0aGVtIGxhdGVseSwgYnV0IGp1c3QgdG8gZ2V0IHRoaXMgY29kZSByaWdodCkuICBFdmVuIHNvLCBpdCBkb2Vzbid0CiAqICAgICAgICBhcHBlYXIgdG8gYmUgc28uICBJdCdzIGJlaW5nIHdvcmtlZCBvbi4uLgogKiAKICogICBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAgICAwNi1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgICAgICAgT3JpZ2luYWwgaW1wbGVtZW50YXRpb24gKGJhc2VkIG9uIE5DX0RyYXdGcmFtZSkKICogICAgICAgIDAyLUp1bi0xOTk4IEVyaWMgS29obCAoZWtvaGxAYWJvLnJoZWluLXplaXR1bmcuZGUpCiAqICAgICAgICAgICAgIFNvbWUgbWlub3IgZml4ZXMuCiAqICAgICAgICAyOS1KdW4tMTk5OSBPdmUgS+V2ZW4gKG92ZWtAYXJjdGljbmV0Lm5vKQogKiAgICAgICAgICAgICBGaXhlZCBhIGZpeCBvciBzb21ldGhpbmcuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkICBOQ19EcmF3RnJhbWU5NSgKICAgIEhEQyAgaGRjLAogICAgUkVDVCAgKnJlY3QsCiAgICBCT09MICBkbGdGcmFtZSwKICAgIEJPT0wgIGFjdGl2ZSApCnsKICAgIElOVCB3aWR0aCwgaGVpZ2h0OwoKICAgIGlmIChkbGdGcmFtZSkKICAgIHsKCXdpZHRoID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWERMR0ZSQU1FKSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hFREdFKTsKCWhlaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lETEdGUkFNRSkgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSk7CiAgICB9CiAgICBlbHNlCiAgICB7Cgl3aWR0aCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSkgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRURHRSk7CgloZWlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUVER0UpOwogICAgfQoKICAgIFNlbGVjdE9iamVjdCggaGRjLCBHZXRTeXNDb2xvckJydXNoKGFjdGl2ZSA/IENPTE9SX0FDVElWRUJPUkRFUiA6CgkJQ09MT1JfSU5BQ1RJVkVCT1JERVIpICk7CgogICAgLyogRHJhdyBmcmFtZSAqLwogICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICByZWN0LT5yaWdodCAtIHJlY3QtPmxlZnQsIGhlaWdodCwgUEFUQ09QWSApOwogICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICB3aWR0aCwgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLCBQQVRDT1BZICk7CiAgICBQYXRCbHQoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+Ym90dG9tIC0gMSwKICAgICAgICAgICAgICByZWN0LT5yaWdodCAtIHJlY3QtPmxlZnQsIC1oZWlnaHQsIFBBVENPUFkgKTsKICAgIFBhdEJsdCggaGRjLCByZWN0LT5yaWdodCAtIDEsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAtd2lkdGgsIHJlY3QtPmJvdHRvbSAtIHJlY3QtPnRvcCwgUEFUQ09QWSApOwoKICAgIEluZmxhdGVSZWN0KCByZWN0LCAtd2lkdGgsIC1oZWlnaHQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3TW92aW5nRnJhbWUKICoKICogRHJhdyB0aGUgZnJhbWUgdXNlZCB3aGVuIG1vdmluZyBvciByZXNpemluZyB3aW5kb3cuCiAqCiAqIEZJWE1FOiAgVGhpcyBjYXVzZXMgcHJvYmxlbXMgaW4gV2luOTUgbW9kZS4gICh3aHk/KQogKi8Kc3RhdGljIHZvaWQgTkNfRHJhd01vdmluZ0ZyYW1lKCBIREMgaGRjLCBSRUNUICpyZWN0LCBCT09MIHRoaWNrZnJhbWUgKQp7CiAgICBpZiAodGhpY2tmcmFtZSkKICAgIHsKICAgICAgICBSRUNUMTYgcjE2OwogICAgICAgIENPTlZfUkVDVDMyVE8xNiggcmVjdCwgJnIxNiApOwogICAgICAgIEZhc3RXaW5kb3dGcmFtZTE2KCBoZGMsICZyMTYsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpLCBQQVRJTlZFUlQgKTsKICAgIH0KICAgIGVsc2UgRHJhd0ZvY3VzUmVjdCggaGRjLCByZWN0ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0RyYXdDYXB0aW9uCiAqCiAqIERyYXcgdGhlIHdpbmRvdyBjYXB0aW9uLgogKiBUaGUgY29ycmVjdCBwZW4gZm9yIHRoZSB3aW5kb3cgZnJhbWUgbXVzdCBiZSBzZWxlY3RlZCBpbiB0aGUgREMuCiAqLwpzdGF0aWMgdm9pZCBOQ19EcmF3Q2FwdGlvbiggSERDIGhkYywgUkVDVCAqcmVjdCwgSFdORCBod25kLAoJCQkgICAgRFdPUkQgc3R5bGUsIEJPT0wgYWN0aXZlICkKewogICAgUkVDVCByID0gKnJlY3Q7CiAgICBXTkQgKiB3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwogICAgY2hhciBidWZmZXJbMjU2XTsKCiAgICBpZiAod25kUHRyLT5mbGFncyAmIFdJTl9NQU5BR0VEKQogICAgewogICAgICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICghaGJpdG1hcENsb3NlKQogICAgewoJaWYgKCEoaGJpdG1hcENsb3NlID0gTG9hZEJpdG1hcDE2KCAwLCBNQUtFSU5UUkVTT1VSQ0UxNihPQk1fQ0xPU0UpICkpKQogICAgICAgIHsKICAgICAgICAgICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKCSAgICByZXR1cm47CiAgICAgICAgfQoJaGJpdG1hcENsb3NlRCAgICA9IExvYWRCaXRtYXAxNiggMCwgTUFLRUlOVFJFU09VUkNFMTYoT0JNX0NMT1NFRCkgKTsKCWhiaXRtYXBNaW5pbWl6ZSAgPSBMb2FkQml0bWFwMTYoIDAsIE1BS0VJTlRSRVNPVVJDRTE2KE9CTV9SRURVQ0UpICk7CgloYml0bWFwTWluaW1pemVEID0gTG9hZEJpdG1hcDE2KCAwLCBNQUtFSU5UUkVTT1VSQ0UxNihPQk1fUkVEVUNFRCkgKTsKCWhiaXRtYXBNYXhpbWl6ZSAgPSBMb2FkQml0bWFwMTYoIDAsIE1BS0VJTlRSRVNPVVJDRTE2KE9CTV9aT09NKSApOwoJaGJpdG1hcE1heGltaXplRCA9IExvYWRCaXRtYXAxNiggMCwgTUFLRUlOVFJFU09VUkNFMTYoT0JNX1pPT01EKSApOwoJaGJpdG1hcFJlc3RvcmUgICA9IExvYWRCaXRtYXAxNiggMCwgTUFLRUlOVFJFU09VUkNFMTYoT0JNX1JFU1RPUkUpICk7CgloYml0bWFwUmVzdG9yZUQgID0gTG9hZEJpdG1hcDE2KCAwLCBNQUtFSU5UUkVTT1VSQ0UxNihPQk1fUkVTVE9SRUQpICk7CiAgICB9CiAgICAKICAgIGlmICh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX0RMR01PREFMRlJBTUUpCiAgICB7CiAgICAgICAgSEJSVVNIIGhicnVzaE9sZCA9IFNlbGVjdE9iamVjdChoZGMsIEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfV0lORE9XKSApOwoJUGF0Qmx0KCBoZGMsIHIubGVmdCwgci50b3AsIDEsIHIuYm90dG9tLXIudG9wKzEsUEFUQ09QWSApOwoJUGF0Qmx0KCBoZGMsIHIucmlnaHQtMSwgci50b3AsIDEsIHIuYm90dG9tLXIudG9wKzEsIFBBVENPUFkgKTsKCVBhdEJsdCggaGRjLCByLmxlZnQsIHIudG9wLTEsIHIucmlnaHQtci5sZWZ0LCAxLCBQQVRDT1BZICk7CglyLmxlZnQrKzsKCXIucmlnaHQtLTsKCVNlbGVjdE9iamVjdCggaGRjLCBoYnJ1c2hPbGQgKTsKICAgIH0KICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7CiAgICBNb3ZlVG9FeCggaGRjLCByLmxlZnQsIHIuYm90dG9tLCBOVUxMICk7CiAgICBMaW5lVG8oIGhkYywgci5yaWdodCwgci5ib3R0b20gKTsKCiAgICBpZiAoc3R5bGUgJiBXU19TWVNNRU5VKQogICAgewoJTkNfRHJhd1N5c0J1dHRvbiggaHduZCwgaGRjLCBGQUxTRSApOwoJci5sZWZ0ICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CglNb3ZlVG9FeCggaGRjLCByLmxlZnQgLSAxLCByLnRvcCwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHIubGVmdCAtIDEsIHIuYm90dG9tICk7CiAgICB9CiAgICBpZiAoc3R5bGUgJiBXU19NQVhJTUlaRUJPWCkKICAgIHsKCU5DX0RyYXdNYXhCdXR0b24oIGh3bmQsIGhkYywgRkFMU0UgKTsKCXIucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKICAgIH0KICAgIGlmIChzdHlsZSAmIFdTX01JTklNSVpFQk9YKQogICAgewoJTkNfRHJhd01pbkJ1dHRvbiggaHduZCwgaGRjLCBGQUxTRSApOwoJci5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwogICAgfQoKICAgIEZpbGxSZWN0KCBoZGMsICZyLCBHZXRTeXNDb2xvckJydXNoKGFjdGl2ZSA/IENPTE9SX0FDVElWRUNBUFRJT04gOgoJCQkJCSAgICBDT0xPUl9JTkFDVElWRUNBUFRJT04pICk7CgogICAgaWYgKEdldFdpbmRvd1RleHRBKCBod25kLCBidWZmZXIsIHNpemVvZihidWZmZXIpICkpCiAgICB7CglpZiAoYWN0aXZlKSBTZXRUZXh0Q29sb3IoIGhkYywgR2V0U3lzQ29sb3IoIENPTE9SX0NBUFRJT05URVhUICkgKTsKCWVsc2UgU2V0VGV4dENvbG9yKCBoZGMsIEdldFN5c0NvbG9yKCBDT0xPUl9JTkFDVElWRUNBUFRJT05URVhUICkgKTsKCVNldEJrTW9kZSggaGRjLCBUUkFOU1BBUkVOVCApOwoJRHJhd1RleHRBKCBoZGMsIGJ1ZmZlciwgLTEsICZyLAogICAgICAgICAgICAgICAgICAgICBEVF9TSU5HTEVMSU5FIHwgRFRfQ0VOVEVSIHwgRFRfVkNFTlRFUiB8IERUX05PUFJFRklYICk7CiAgICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqICAgTkNfRHJhd0NhcHRpb245NSgKICogICAgICBIREMgIGhkYywKICogICAgICBSRUNUICpyZWN0LAogKiAgICAgIEhXTkQgaHduZCwKICogICAgICBEV09SRCAgc3R5bGUsCiAqICAgICAgQk9PTCBhY3RpdmUgKQogKgogKiAgIERyYXcgdGhlIHdpbmRvdyBjYXB0aW9uIGZvciBXaW45NSBzdHlsZSB3aW5kb3dzLgogKiAgIFRoZSBjb3JyZWN0IHBlbiBmb3IgdGhlIHdpbmRvdyBmcmFtZSBtdXN0IGJlIHNlbGVjdGVkIGluIHRoZSBEQy4KICoKICogICBCdWdzCiAqICAgICAgICBIZXksIGEgZnVuY3Rpb24gdGhhdCBmaW5hbGx5IHdvcmtzISAgV2VsbCwgYWxtb3N0LgogKiAgICAgICAgSXQncyBiZWluZyB3b3JrZWQgb24uCiAqCiAqICAgUmV2aXNpb24gaGlzdG9yeQogKiAgICAgICAgMDUtSnVsLTE5OTcgRGF2ZSBDdXRoYmVydCAoZGFjdXRAZWNlLmNtdS5lZHUpCiAqICAgICAgICAgICAgIE9yaWdpbmFsIGltcGxlbWVudGF0aW9uLgogKiAgICAgICAgMDItSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgICAgICAgU29tZSBtaW5vciBmaXhlcy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHZvaWQgIE5DX0RyYXdDYXB0aW9uOTUoCiAgICBIREMgIGhkYywKICAgIFJFQ1QgKnJlY3QsCiAgICBIV05EIGh3bmQsCiAgICBEV09SRCAgc3R5bGUsCiAgICBEV09SRCAgZXhTdHlsZSwKICAgIEJPT0wgYWN0aXZlICkKewogICAgUkVDVCAgciA9ICpyZWN0OwogICAgV05EICAgICAqd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKICAgIGNoYXIgICAgYnVmZmVyWzI1Nl07CiAgICBIUEVOICBoUHJldlBlbjsKICAgIEhNRU5VIGhTeXNNZW51OwoKICAgIGlmICh3bmRQdHItPmZsYWdzICYgV0lOX01BTkFHRUQpCiAgICB7CiAgICAgICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwoKICAgIGhQcmV2UGVuID0gU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN5c0NvbG9yUGVuKENPTE9SXzNERkFDRSkgKTsKICAgIE1vdmVUb0V4KCBoZGMsIHIubGVmdCwgci5ib3R0b20gLSAxLCBOVUxMICk7CiAgICBMaW5lVG8oIGhkYywgci5yaWdodCwgci5ib3R0b20gLSAxICk7CiAgICBTZWxlY3RPYmplY3QoIGhkYywgaFByZXZQZW4gKTsKICAgIHIuYm90dG9tLS07CgogICAgRmlsbFJlY3QoIGhkYywgJnIsIEdldFN5c0NvbG9yQnJ1c2goYWN0aXZlID8gQ09MT1JfQUNUSVZFQ0FQVElPTiA6CgkJCQkJICAgIENPTE9SX0lOQUNUSVZFQ0FQVElPTikgKTsKCiAgICBpZiAoIWhiaXRtYXBDbG9zZSkgewoJaWYgKCEoaGJpdG1hcENsb3NlID0gTG9hZEJpdG1hcDE2KCAwLCBNQUtFSU5UUkVTT1VSQ0UxNihPQk1fQ0xPU0UpICkpKQoJICAgIHJldHVybjsKICAgICAgICBoYml0bWFwQ2xvc2VEID0gTG9hZEJpdG1hcDE2KCAwLCBNQUtFSU5UUkVTT1VSQ0UxNihPQk1fQ0xPU0VEKSk7CgloYml0bWFwTWluaW1pemUgID0gTG9hZEJpdG1hcDE2KCAwLCBNQUtFSU5UUkVTT1VSQ0UxNihPQk1fUkVEVUNFKSApOwoJaGJpdG1hcE1pbmltaXplRCA9IExvYWRCaXRtYXAxNiggMCwgTUFLRUlOVFJFU09VUkNFMTYoT0JNX1JFRFVDRUQpICk7CgloYml0bWFwTWF4aW1pemUgID0gTG9hZEJpdG1hcDE2KCAwLCBNQUtFSU5UUkVTT1VSQ0UxNihPQk1fWk9PTSkgKTsKCWhiaXRtYXBNYXhpbWl6ZUQgPSBMb2FkQml0bWFwMTYoIDAsIE1BS0VJTlRSRVNPVVJDRTE2KE9CTV9aT09NRCkgKTsKCWhiaXRtYXBSZXN0b3JlICAgPSBMb2FkQml0bWFwMTYoIDAsIE1BS0VJTlRSRVNPVVJDRTE2KE9CTV9SRVNUT1JFKSApOwoJaGJpdG1hcFJlc3RvcmVEICA9IExvYWRCaXRtYXAxNiggMCwgTUFLRUlOVFJFU09VUkNFMTYoT0JNX1JFU1RPUkVEKSApOwogICAgfQogICAgCiAgICBpZiAoKHN0eWxlICYgV1NfU1lTTUVOVSkgJiYgIShleFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykpIHsKCWlmIChOQ19EcmF3U3lzQnV0dG9uOTUgKGh3bmQsIGhkYywgRkFMU0UpKQoJICAgIHIubGVmdCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSAxOwogICAgfQoKICAgIGlmIChzdHlsZSAmIFdTX1NZU01FTlUpIAogICAgewoJVUlOVCBzdGF0ZTsKCgkvKiBHbyBnZXQgdGhlIHN5c21lbnUgKi8KCWhTeXNNZW51ID0gR2V0U3lzdGVtTWVudShod25kLCBGQUxTRSk7CglzdGF0ZSA9IEdldE1lbnVTdGF0ZShoU3lzTWVudSwgU0NfQ0xPU0UsIE1GX0JZQ09NTUFORCk7CgoJLyogRHJhdyBhIGdyYXllZCBjbG9zZSBidXR0b24gaWYgZGlzYWJsZWQgYW5kIGEgbm9ybWFsIG9uZSBpZiBTQ19DTE9TRSBpcyBub3QgdGhlcmUgKi8KCU5DX0RyYXdDbG9zZUJ1dHRvbjk1IChod25kLCBoZGMsIEZBTFNFLCAKCQkJICAgICAgKCgoKHN0YXRlICYgTUZfRElTQUJMRUQpIHx8IChzdGF0ZSAmIE1GX0dSQVlFRCkpKSAmJiAoc3RhdGUgIT0gMHhGRkZGRkZGRikpKTsKCXIucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKCglpZiAoKHN0eWxlICYgV1NfTUFYSU1JWkVCT1gpIHx8IChzdHlsZSAmIFdTX01JTklNSVpFQk9YKSkKCXsKCSAgICAvKiBJbiB3aW45NSB0aGUgdHdvIGJ1dHRvbnMgYXJlIGFsd2F5cyB0aGVyZSAqLwoJICAgIC8qIEJ1dCBpZiB0aGUgbWVudSBpdGVtIGlzIG5vdCBpbiB0aGUgbWVudSB0aGV5J3JlIGRpc2FibGVkKi8KCgkgICAgTkNfRHJhd01heEJ1dHRvbjk1KCBod25kLCBoZGMsIEZBTFNFLCAoIShzdHlsZSAmIFdTX01BWElNSVpFQk9YKSkpOwoJICAgIHIucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKCSAgICAKCSAgICBOQ19EcmF3TWluQnV0dG9uOTUoIGh3bmQsIGhkYywgRkFMU0UsICAoIShzdHlsZSAmIFdTX01JTklNSVpFQk9YKSkpOwoJICAgIHIucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKCX0KICAgIH0KCiAgICBpZiAoR2V0V2luZG93VGV4dEEoIGh3bmQsIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikgKSkgewoJTk9OQ0xJRU5UTUVUUklDU0EgbmNsbTsKCUhGT05UIGhGb250LCBoT2xkRm9udDsKCW5jbG0uY2JTaXplID0gc2l6ZW9mKE5PTkNMSUVOVE1FVFJJQ1NBKTsKCVN5c3RlbVBhcmFtZXRlcnNJbmZvQSAoU1BJX0dFVE5PTkNMSUVOVE1FVFJJQ1MsIDAsICZuY2xtLCAwKTsKCWlmIChleFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykKCSAgICBoRm9udCA9IENyZWF0ZUZvbnRJbmRpcmVjdEEgKCZuY2xtLmxmU21DYXB0aW9uRm9udCk7CgllbHNlCgkgICAgaEZvbnQgPSBDcmVhdGVGb250SW5kaXJlY3RBICgmbmNsbS5sZkNhcHRpb25Gb250KTsKCWhPbGRGb250ID0gU2VsZWN0T2JqZWN0IChoZGMsIGhGb250KTsKCWlmIChhY3RpdmUpIFNldFRleHRDb2xvciggaGRjLCBHZXRTeXNDb2xvciggQ09MT1JfQ0FQVElPTlRFWFQgKSApOwoJZWxzZSBTZXRUZXh0Q29sb3IoIGhkYywgR2V0U3lzQ29sb3IoIENPTE9SX0lOQUNUSVZFQ0FQVElPTlRFWFQgKSApOwoJU2V0QmtNb2RlKCBoZGMsIFRSQU5TUEFSRU5UICk7CglyLmxlZnQgKz0gMjsKCURyYXdUZXh0QSggaGRjLCBidWZmZXIsIC0xLCAmciwKCQkgICAgIERUX1NJTkdMRUxJTkUgfCBEVF9WQ0VOVEVSIHwgRFRfTk9QUkVGSVggfCBEVF9MRUZUICk7CglEZWxldGVPYmplY3QgKFNlbGVjdE9iamVjdCAoaGRjLCBoT2xkRm9udCkpOwogICAgfQp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfRG9OQ1BhaW50CiAqCiAqIFBhaW50IHRoZSBub24tY2xpZW50IGFyZWEuIGNsaXAgaXMgY3VycmVudGx5IHVudXNlZC4KICovCnN0YXRpYyB2b2lkIE5DX0RvTkNQYWludCggV05EKiB3bmRQdHIsIEhSR04gY2xpcCwgQk9PTCBzdXBwcmVzc19tZW51cGFpbnQgKQp7CiAgICBIREMgaGRjOwogICAgUkVDVCByZWN0OwogICAgQk9PTCBhY3RpdmU7CiAgICBIV05EIGh3bmQgPSB3bmRQdHItPmh3bmRTZWxmOwoKICAgIGlmICggd25kUHRyLT5kd1N0eWxlICYgV1NfTUlOSU1JWkUgfHwKCSFXSU5fSXNXaW5kb3dEcmF3YWJsZSggd25kUHRyLCAwICkpIHJldHVybjsgLyogTm90aGluZyB0byBkbyAqLwoKICAgIGFjdGl2ZSAgPSB3bmRQdHItPmZsYWdzICYgV0lOX05DQUNUSVZBVEVEOwoKICAgIFRSQUNFKCIlMDR4ICVkXG4iLCBod25kLCBhY3RpdmUgKTsKCiAgICBpZiAoIShoZGMgPSBHZXREQ0V4KCBod25kLCAoY2xpcCA+IDEpID8gY2xpcCA6IDAsIERDWF9VU0VTVFlMRSB8IERDWF9XSU5ET1cgfAoJCQkgICAgICAoKGNsaXAgPiAxKSA/IChEQ1hfSU5URVJTRUNUUkdOIHwgRENYX0tFRVBDTElQUkdOKTogMCkgKSkpIHJldHVybjsKCiAgICBpZiAoRXhjbHVkZVZpc1JlY3QxNiggaGRjLCB3bmRQdHItPnJlY3RDbGllbnQubGVmdC13bmRQdHItPnJlY3RXaW5kb3cubGVmdCwKCQkgICAgICAgIHduZFB0ci0+cmVjdENsaWVudC50b3Atd25kUHRyLT5yZWN0V2luZG93LnRvcCwKCQkgICAgICAgIHduZFB0ci0+cmVjdENsaWVudC5yaWdodC13bmRQdHItPnJlY3RXaW5kb3cubGVmdCwKCQkgICAgICAgIHduZFB0ci0+cmVjdENsaWVudC5ib3R0b20td25kUHRyLT5yZWN0V2luZG93LnRvcCApCgk9PSBOVUxMUkVHSU9OKQogICAgewoJUmVsZWFzZURDKCBod25kLCBoZGMgKTsKCXJldHVybjsKICAgIH0KCiAgICByZWN0LnRvcCA9IHJlY3QubGVmdCA9IDA7CiAgICByZWN0LnJpZ2h0ICA9IHduZFB0ci0+cmVjdFdpbmRvdy5yaWdodCAtIHduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0OwogICAgcmVjdC5ib3R0b20gPSB3bmRQdHItPnJlY3RXaW5kb3cuYm90dG9tIC0gd25kUHRyLT5yZWN0V2luZG93LnRvcDsKCiAgICBTZWxlY3RPYmplY3QoIGhkYywgR2V0U3lzQ29sb3JQZW4oQ09MT1JfV0lORE9XRlJBTUUpICk7CgogICAgaWYgKCEod25kUHRyLT5mbGFncyAmIFdJTl9NQU5BR0VEKSkKICAgIHsKICAgICAgICBpZiAoSEFTX0FOWUZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICkpCgl7CgkgICAgU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN0b2NrT2JqZWN0KE5VTExfQlJVU0gpICk7CiAgICAgICAgICAgIFJlY3RhbmdsZSggaGRjLCAwLCAwLCByZWN0LnJpZ2h0LCByZWN0LmJvdHRvbSApOwogICAgICAgICAgICBJbmZsYXRlUmVjdCggJnJlY3QsIC0xLCAtMSApOwogICAgICAgIH0KCglpZiAoSEFTX1RISUNLRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgICAgICAgICAgTkNfRHJhd0ZyYW1lKGhkYywgJnJlY3QsIEZBTFNFLCBhY3RpdmUgKTsKCWVsc2UgaWYgKEhBU19ETEdGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKSAKICAgICAgICAgICAgTkNfRHJhd0ZyYW1lKCBoZGMsICZyZWN0LCBUUlVFLCBhY3RpdmUgKTsKCiAgICAgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19DQVBUSU9OKSA9PSBXU19DQVBUSU9OKQogICAgICAgIHsKICAgICAgICAgICAgUkVDVCByID0gcmVjdDsKICAgICAgICAgICAgci5ib3R0b20gPSByZWN0LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKTsKICAgICAgICAgICAgcmVjdC50b3AgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUik7CiAgICAgICAgICAgIE5DX0RyYXdDYXB0aW9uKCBoZGMsICZyLCBod25kLCB3bmRQdHItPmR3U3R5bGUsIGFjdGl2ZSApOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoSEFTX01FTlUod25kUHRyKSkKICAgIHsKCVJFQ1QgciA9IHJlY3Q7CglyLmJvdHRvbSA9IHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWU1FTlUpOyAgLyogZGVmYXVsdCBoZWlnaHQgKi8KCXJlY3QudG9wICs9IE1FTlVfRHJhd01lbnVCYXIoIGhkYywgJnIsIGh3bmQsIHN1cHByZXNzX21lbnVwYWludCApOwogICAgfQoKICAgICAgLyogRHJhdyB0aGUgc2Nyb2xsLWJhcnMgKi8KCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfVlNDUk9MTCkKICAgICAgICBTQ1JPTExfRHJhd1Njcm9sbEJhciggaHduZCwgaGRjLCBTQl9WRVJULCBUUlVFLCBUUlVFICk7CiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfSFNDUk9MTCkKICAgICAgICBTQ1JPTExfRHJhd1Njcm9sbEJhciggaHduZCwgaGRjLCBTQl9IT1JaLCBUUlVFLCBUUlVFICk7CgogICAgICAvKiBEcmF3IHRoZSAic2l6ZS1ib3giICovCgogICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19WU0NST0xMKSAmJiAod25kUHRyLT5kd1N0eWxlICYgV1NfSFNDUk9MTCkpCiAgICB7CiAgICAgICAgUkVDVCByID0gcmVjdDsKICAgICAgICByLmxlZnQgPSByLnJpZ2h0IC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpICsgMTsKICAgICAgICByLnRvcCAgPSByLmJvdHRvbSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lIU0NST0xMKSArIDE7CglpZih3bmRQdHItPmR3U3R5bGUgJiBXU19CT1JERVIpIHsKCSAgci5sZWZ0Kys7CgkgIHIudG9wKys7Cgl9CiAgICAgICAgRmlsbFJlY3QoIGhkYywgJnIsIEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfU0NST0xMQkFSKSApOwogICAgfSAgICAKCiAgICBSZWxlYXNlREMoIGh3bmQsIGhkYyApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIHZvaWQgIE5DX0RvTkNQYWludDk1KAogKiAgICAgIFdORCAgKnduZFB0ciwKICogICAgICBIUkdOICBjbGlwLAogKiAgICAgIEJPT0wgIHN1cHByZXNzX21lbnVwYWludCApCiAqCiAqICAgUGFpbnQgdGhlIG5vbi1jbGllbnQgYXJlYSBmb3IgV2luOTUgd2luZG93cy4gIFRoZSBjbGlwIHJlZ2lvbiBpcwogKiAgIGN1cnJlbnRseSBpZ25vcmVkLgogKgogKiAgIEJ1Z3MKICogICAgICAgIGdyZXAgLUUgLUExMCAtQjUgXCg5NVwpXHxcKEJ1Z3NcKVx8XChGSVhNRVwpIHdpbmRvd3Mvbm9uY2xpZW50LmMgXAogKiAgICAgICAgICAgbWlzYy90d2Vhay5jIGNvbnRyb2xzL21lbnUuYyAgIyA6LSkKICoKICogICBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAgICAwMy1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgICAgICAgT3JpZ2luYWwgaW1wbGVtZW50YXRpb24KICogICAgICAgIDEwLUp1bi0xOTk4IEVyaWMgS29obCAoZWtvaGxAYWJvLnJoZWluLXplaXR1bmcuZGUpCiAqICAgICAgICAgICAgIEZpeGVkIHNvbWUgYnVncy4KICogICAgICAgIDI5LUp1bi0xOTk5IE92ZSBL5XZlbiAob3Zla0BhcmN0aWNuZXQubm8pCiAqICAgICAgICAgICAgIFN0cmVhbWxpbmVkIHdpbmRvdyBzdHlsZSBjaGVja3MuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkICBOQ19Eb05DUGFpbnQ5NSgKICAgIFdORCAgKnduZFB0ciwKICAgIEhSR04gIGNsaXAsCiAgICBCT09MICBzdXBwcmVzc19tZW51cGFpbnQgKQp7CiAgICBIREMgaGRjOwogICAgUkVDVCByZnV6eiwgcmVjdCwgcmVjdENsaXA7CiAgICBCT09MIGFjdGl2ZTsKICAgIEhXTkQgaHduZCA9IHduZFB0ci0+aHduZFNlbGY7CgogICAgaWYgKCB3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRSB8fAoJIVdJTl9Jc1dpbmRvd0RyYXdhYmxlKCB3bmRQdHIsIDAgKSkgcmV0dXJuOyAvKiBOb3RoaW5nIHRvIGRvICovCgogICAgYWN0aXZlICA9IHduZFB0ci0+ZmxhZ3MgJiBXSU5fTkNBQ1RJVkFURUQ7CgogICAgVFJBQ0UoIiUwNHggJWRcbiIsIGh3bmQsIGFjdGl2ZSApOwoKICAgIC8qIE1TRE4gZG9jcyBhcmUgcHJldHR5IGlkaW90aWMgaGVyZSwgdGhleSBzYXkgYXBwIENBTiB1c2UgY2xpcFJnbiBpbgogICAgICAgdGhlIGNhbGwgdG8gR2V0RENFeCBpbXBseWluZyB0aGF0IGl0IGlzIGFsbG93ZWQgbm90IHRvIHVzZSBpdCBlaXRoZXIuCiAgICAgICBIb3dldmVyLCB0aGUgc3VnZ2VzdGVkIEdldERDRXgoICAgICwgRENYX1dJTkRPVyB8IERDWF9JTlRFUlNFQ1RSR04pCiAgICAgICB3aWxsIGNhdXNlIGNsaXBSZ24gdG8gYmUgZGVsZXRlZCBhZnRlciBSZWxlYXNlREMoKS4KICAgICAgIE5vdywgaG93IGlzIHRoZSAic3lzdGVtIiBzdXBwb3NlZCB0byB0ZWxsIHdoYXQgaGFwcGVuZWQ/CiAgICAgKi8KCiAgICBpZiAoIShoZGMgPSBHZXREQ0V4KCBod25kLCAoY2xpcCA+IDEpID8gY2xpcCA6IDAsIERDWF9VU0VTVFlMRSB8IERDWF9XSU5ET1cgfAoJCQkgICAgICAoKGNsaXAgPiAxKSA/KERDWF9JTlRFUlNFQ1RSR04gfCBEQ1hfS0VFUENMSVBSR04pIDogMCkgKSkpIHJldHVybjsKCgogICAgaWYgKEV4Y2x1ZGVWaXNSZWN0MTYoIGhkYywgd25kUHRyLT5yZWN0Q2xpZW50LmxlZnQtd25kUHRyLT5yZWN0V2luZG93LmxlZnQsCgkJICAgICAgICB3bmRQdHItPnJlY3RDbGllbnQudG9wLXduZFB0ci0+cmVjdFdpbmRvdy50b3AsCgkJICAgICAgICB3bmRQdHItPnJlY3RDbGllbnQucmlnaHQtd25kUHRyLT5yZWN0V2luZG93LmxlZnQsCgkJICAgICAgICB3bmRQdHItPnJlY3RDbGllbnQuYm90dG9tLXduZFB0ci0+cmVjdFdpbmRvdy50b3AgKQoJPT0gTlVMTFJFR0lPTikKICAgIHsKCVJlbGVhc2VEQyggaHduZCwgaGRjICk7CglyZXR1cm47CiAgICB9CgogICAgcmVjdC50b3AgPSByZWN0LmxlZnQgPSAwOwogICAgcmVjdC5yaWdodCAgPSB3bmRQdHItPnJlY3RXaW5kb3cucmlnaHQgLSB3bmRQdHItPnJlY3RXaW5kb3cubGVmdDsKICAgIHJlY3QuYm90dG9tID0gd25kUHRyLT5yZWN0V2luZG93LmJvdHRvbSAtIHduZFB0ci0+cmVjdFdpbmRvdy50b3A7CgogICAgaWYoIGNsaXAgPiAxICkKCUdldFJnbkJveCggY2xpcCwgJnJlY3RDbGlwICk7CiAgICBlbHNlCiAgICB7CgljbGlwID0gMDsKCXJlY3RDbGlwID0gcmVjdDsKICAgIH0KCiAgICBTZWxlY3RPYmplY3QoIGhkYywgR2V0U3lzQ29sb3JQZW4oQ09MT1JfV0lORE9XRlJBTUUpICk7CgogICAgaWYoISh3bmRQdHItPmZsYWdzICYgV0lOX01BTkFHRUQpKSB7CiAgICAgICAgaWYgKEhBU19CSUdGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSkpIHsKICAgICAgICAgICAgRHJhd0VkZ2UgKGhkYywgJnJlY3QsIEVER0VfUkFJU0VELCBCRl9SRUNUIHwgQkZfQURKVVNUKTsKICAgICAgICB9CglpZiAoSEFTX1RISUNLRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgICAgICAgICAgTkNfRHJhd0ZyYW1lOTUoaGRjLCAmcmVjdCwgRkFMU0UsIGFjdGl2ZSApOwogICAgICAgIGVsc2UgaWYgKEhBU19ETEdGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKSAKICAgICAgICAgICAgTkNfRHJhd0ZyYW1lOTUoIGhkYywgJnJlY3QsIFRSVUUsIGFjdGl2ZSApOwoJZWxzZSBpZiAoSEFTX1RISU5GUkFNRSggd25kUHRyLT5kd1N0eWxlICkpIHsKICAgICAgICAgICAgU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN0b2NrT2JqZWN0KE5VTExfQlJVU0gpICk7CiAgICAgICAgICAgIFJlY3RhbmdsZSggaGRjLCAwLCAwLCByZWN0LnJpZ2h0LCByZWN0LmJvdHRvbSApOwoJfQoKICAgICAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NBUFRJT04pID09IFdTX0NBUFRJT04pCiAgICAgICAgewogICAgICAgICAgICBSRUNUICByID0gcmVjdDsKCSAgICBpZiAod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9UT09MV0lORE9XKSB7CgkJci5ib3R0b20gPSByZWN0LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUNBUFRJT04pOwoJCXJlY3QudG9wICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUNBUFRJT04pOwoJICAgIH0KCSAgICBlbHNlIHsKCQlyLmJvdHRvbSA9IHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pOwoJCXJlY3QudG9wICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKTsKCSAgICB9CgkgICAgaWYoICFjbGlwIHx8IEludGVyc2VjdFJlY3QoICZyZnV6eiwgJnIsICZyZWN0Q2xpcCApICkKICAgICAgICAgICAgICAgIE5DX0RyYXdDYXB0aW9uOTUgKGhkYywgJnIsIGh3bmQsIHduZFB0ci0+ZHdTdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHduZFB0ci0+ZHdFeFN0eWxlLCBhY3RpdmUpOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoSEFTX01FTlUod25kUHRyKSkKICAgIHsKCVJFQ1QgciA9IHJlY3Q7CglyLmJvdHRvbSA9IHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWU1FTlUpOwoJCglUUkFDRSgiQ2FsbGluZyBEcmF3TWVudUJhciB3aXRoIHJlY3QgKCVkLCAlZCktKCVkLCAlZClcbiIsCiAgICAgICAgICAgICAgci5sZWZ0LCByLnRvcCwgci5yaWdodCwgci5ib3R0b20pOwoKCXJlY3QudG9wICs9IE1FTlVfRHJhd01lbnVCYXIoIGhkYywgJnIsIGh3bmQsIHN1cHByZXNzX21lbnVwYWludCApICsgMTsKICAgIH0KCiAgICBUUkFDRSgiQWZ0ZXIgTWVudUJhciwgcmVjdCBpcyAoJWQsICVkKS0oJWQsICVkKS5cbiIsCiAgICAgICAgICByZWN0LmxlZnQsIHJlY3QudG9wLCByZWN0LnJpZ2h0LCByZWN0LmJvdHRvbSApOwoKICAgIGlmICh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX0NMSUVOVEVER0UpCglEcmF3RWRnZSAoaGRjLCAmcmVjdCwgRURHRV9TVU5LRU4sIEJGX1JFQ1QgfCBCRl9BREpVU1QpOwoKICAgIGlmICh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX1NUQVRJQ0VER0UpCglEcmF3RWRnZSAoaGRjLCAmcmVjdCwgQkRSX1NVTktFTk9VVEVSLCBCRl9SRUNUIHwgQkZfQURKVVNUKTsKCiAgICAvKiBEcmF3IHRoZSBzY3JvbGwtYmFycyAqLwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19WU0NST0xMKQogICAgICAgIFNDUk9MTF9EcmF3U2Nyb2xsQmFyKCBod25kLCBoZGMsIFNCX1ZFUlQsIFRSVUUsIFRSVUUgKTsKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19IU0NST0xMKQogICAgICAgIFNDUk9MTF9EcmF3U2Nyb2xsQmFyKCBod25kLCBoZGMsIFNCX0hPUlosIFRSVUUsIFRSVUUgKTsKCiAgICAvKiBEcmF3IHRoZSAic2l6ZS1ib3giICovCiAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpICYmICh3bmRQdHItPmR3U3R5bGUgJiBXU19IU0NST0xMKSkKICAgIHsKICAgICAgICBSRUNUIHIgPSByZWN0OwogICAgICAgIHIubGVmdCA9IHIucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCkgKyAxOwogICAgICAgIHIudG9wICA9IHIuYm90dG9tIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpICsgMTsKICAgICAgICBGaWxsUmVjdCggaGRjLCAmciwgIEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfU0NST0xMQkFSKSApOwogICAgfSAgICAKCiAgICBSZWxlYXNlREMoIGh3bmQsIGhkYyApOwp9CgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZU5DUGFpbnQKICoKICogSGFuZGxlIGEgV01fTkNQQUlOVCBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZU5DUGFpbnQoIEhXTkQgaHduZCAsIEhSR04gY2xpcCkKewogICAgV05EKiB3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwoKICAgIGlmKCB3bmRQdHIgJiYgd25kUHRyLT5kd1N0eWxlICYgV1NfVklTSUJMRSApCiAgICB7CglpZiggd25kUHRyLT5kd1N0eWxlICYgV1NfTUlOSU1JWkUgKQoJICAgIFdJTlBPU19SZWRyYXdJY29uVGl0bGUoIGh3bmQgKTsKCWVsc2UgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCgkgICAgTkNfRG9OQ1BhaW50KCB3bmRQdHIsIGNsaXAsIEZBTFNFICk7CgllbHNlCgkgICAgTkNfRG9OQ1BhaW50OTUoIHduZFB0ciwgY2xpcCwgRkFMU0UgKTsKICAgIH0KICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7CiAgICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfSGFuZGxlTkNBY3RpdmF0ZQogKgogKiBIYW5kbGUgYSBXTV9OQ0FDVElWQVRFIG1lc3NhZ2UuIENhbGxlZCBmcm9tIERlZldpbmRvd1Byb2MoKS4KICovCkxPTkcgTkNfSGFuZGxlTkNBY3RpdmF0ZSggV05EICp3bmRQdHIsIFdQQVJBTTE2IHdQYXJhbSApCnsKICAgIFdPUkQgd1N0YXRlQ2hhbmdlOwoKICAgIGlmKCB3UGFyYW0gKSB3U3RhdGVDaGFuZ2UgPSAhKHduZFB0ci0+ZmxhZ3MgJiBXSU5fTkNBQ1RJVkFURUQpOwogICAgZWxzZSB3U3RhdGVDaGFuZ2UgPSB3bmRQdHItPmZsYWdzICYgV0lOX05DQUNUSVZBVEVEOwoKICAgIGlmKCB3U3RhdGVDaGFuZ2UgKQogICAgewoJaWYgKHdQYXJhbSkgd25kUHRyLT5mbGFncyB8PSBXSU5fTkNBQ1RJVkFURUQ7CgllbHNlIHduZFB0ci0+ZmxhZ3MgJj0gfldJTl9OQ0FDVElWQVRFRDsKCglpZiggd25kUHRyLT5kd1N0eWxlICYgV1NfTUlOSU1JWkUgKSAKCSAgICBXSU5QT1NfUmVkcmF3SWNvblRpdGxlKCB3bmRQdHItPmh3bmRTZWxmICk7CgllbHNlIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQoJICAgIE5DX0RvTkNQYWludCggd25kUHRyLCAoSFJHTikxLCBGQUxTRSApOwoJZWxzZQoJICAgIE5DX0RvTkNQYWludDk1KCB3bmRQdHIsIChIUkdOKTEsIEZBTFNFICk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfSGFuZGxlU2V0Q3Vyc29yCiAqCiAqIEhhbmRsZSBhIFdNX1NFVENVUlNPUiBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZVNldEN1cnNvciggSFdORCBod25kLCBXUEFSQU0xNiB3UGFyYW0sIExQQVJBTSBsUGFyYW0gKQp7CiAgICBpZiAoaHduZCAhPSAoSFdORCl3UGFyYW0pIHJldHVybiAwOyAgLyogRG9uJ3Qgc2V0IHRoZSBjdXJzb3IgZm9yIGNoaWxkIHdpbmRvd3MgKi8KCiAgICBzd2l0Y2goTE9XT1JEKGxQYXJhbSkpCiAgICB7CiAgICBjYXNlIEhURVJST1I6Cgl7CgkgICAgV09SRCBtc2cgPSBISVdPUkQoIGxQYXJhbSApOwoJICAgIGlmICgobXNnID09IFdNX0xCVVRUT05ET1dOKSB8fCAobXNnID09IFdNX01CVVRUT05ET1dOKSB8fAoJCShtc2cgPT0gV01fUkJVVFRPTkRPV04pKQoJCU1lc3NhZ2VCZWVwKDApOwoJfQoJYnJlYWs7CgogICAgY2FzZSBIVENMSUVOVDoKCXsKCSAgICBISUNPTjE2IGhDdXJzb3IgPSAoSElDT04xNikgR2V0Q2xhc3NXb3JkKGh3bmQsIEdDV19IQ1VSU09SKTsKCSAgICBpZihoQ3Vyc29yKSB7CgkJU2V0Q3Vyc29yMTYoaEN1cnNvcik7CgkJcmV0dXJuIFRSVUU7CgkgICAgfQogICAgICAgICAgICByZXR1cm4gRkFMU0U7Cgl9CgogICAgY2FzZSBIVExFRlQ6CiAgICBjYXNlIEhUUklHSFQ6CglyZXR1cm4gKExPTkcpU2V0Q3Vyc29yMTYoIExvYWRDdXJzb3IxNiggMCwgSURDX1NJWkVXRTE2ICkgKTsKCiAgICBjYXNlIEhUVE9QOgogICAgY2FzZSBIVEJPVFRPTToKCXJldHVybiAoTE9ORylTZXRDdXJzb3IxNiggTG9hZEN1cnNvcjE2KCAwLCBJRENfU0laRU5TMTYgKSApOwoKICAgIGNhc2UgSFRUT1BMRUZUOgogICAgY2FzZSBIVEJPVFRPTVJJR0hUOgkKCXJldHVybiAoTE9ORylTZXRDdXJzb3IxNiggTG9hZEN1cnNvcjE2KCAwLCBJRENfU0laRU5XU0UxNiApICk7CgogICAgY2FzZSBIVFRPUFJJR0hUOgogICAgY2FzZSBIVEJPVFRPTUxFRlQ6CglyZXR1cm4gKExPTkcpU2V0Q3Vyc29yMTYoIExvYWRDdXJzb3IxNiggMCwgSURDX1NJWkVORVNXMTYgKSApOwogICAgfQoKICAgIC8qIERlZmF1bHQgY3Vyc29yOiBhcnJvdyAqLwogICAgcmV0dXJuIChMT05HKVNldEN1cnNvcjE2KCBMb2FkQ3Vyc29yMTYoIDAsIElEQ19BUlJPVzE2ICkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19HZXRTeXNQb3B1cFBvcwogKi8KQk9PTCBOQ19HZXRTeXNQb3B1cFBvcyggV05EKiB3bmRQdHIsIFJFQ1QqIHJlY3QgKQp7CiAgaWYoIHduZFB0ci0+aFN5c01lbnUgKQogIHsKICAgICAgaWYoIHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFICkKCSAgR2V0V2luZG93UmVjdCggd25kUHRyLT5od25kU2VsZiwgcmVjdCApOwogICAgICBlbHNlCiAgICAgIHsKICAgICAgICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQogICAgICAgICAgICAgIE5DX0dldEluc2lkZVJlY3QoIHduZFB0ci0+aHduZFNlbGYsIHJlY3QgKTsKICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICBOQ19HZXRJbnNpZGVSZWN0OTUoIHduZFB0ci0+aHduZFNlbGYsIHJlY3QgKTsKICAJICBPZmZzZXRSZWN0KCByZWN0LCB3bmRQdHItPnJlY3RXaW5kb3cubGVmdCwgd25kUHRyLT5yZWN0V2luZG93LnRvcCk7CiAgCSAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NISUxEKQogICAgIAkgICAgICBDbGllbnRUb1NjcmVlbiggd25kUHRyLT5wYXJlbnQtPmh3bmRTZWxmLCAoUE9JTlQgKilyZWN0ICk7CiAgICAgICAgICBpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykgewogICAgICAgICAgICByZWN0LT5yaWdodCA9IHJlY3QtPmxlZnQgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSk7CiAgICAgICAgICAgIHJlY3QtPmJvdHRvbSA9IHJlY3QtPnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKTsKCSAgfQoJICBlbHNlIHsKICAgICAgICAgICAgcmVjdC0+cmlnaHQgPSByZWN0LT5sZWZ0ICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKICAgICAgICAgICAgcmVjdC0+Ym90dG9tID0gcmVjdC0+dG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKCSAgfQogICAgICB9CiAgICAgIHJldHVybiBUUlVFOwogIH0KICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfU3RhcnRTaXplTW92ZQogKgogKiBJbml0aWFsaXNhdGlvbiBvZiBhIG1vdmUgb3IgcmVzaXplLCB3aGVuIGluaXRpYXRpZWQgZnJvbSBhIG1lbnUgY2hvaWNlLgogKiBSZXR1cm4gaGl0IHRlc3QgY29kZSBmb3IgY2FwdGlvbiBvciBzaXppbmcgYm9yZGVyLgogKi8Kc3RhdGljIExPTkcgTkNfU3RhcnRTaXplTW92ZSggV05EKiB3bmRQdHIsIFdQQVJBTTE2IHdQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE9JTlQgKmNhcHR1cmVQb2ludCApCnsKICAgIExPTkcgaGl0dGVzdCA9IDA7CiAgICBQT0lOVCBwdDsKICAgIE1TRyBtc2c7CiAgICBSRUNUIHJlY3RXaW5kb3c7CgogICAgR2V0V2luZG93UmVjdCh3bmRQdHItPmh3bmRTZWxmLCZyZWN0V2luZG93KTsKCiAgICBpZiAoKHdQYXJhbSAmIDB4ZmZmMCkgPT0gU0NfTU9WRSkKICAgIHsKCSAgLyogTW92ZSBwb2ludGVyIGF0IHRoZSBjZW50ZXIgb2YgdGhlIGNhcHRpb24gKi8KCVJFQ1QgcmVjdDsKICAgICAgICBpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKICAgICAgICAgICAgTkNfR2V0SW5zaWRlUmVjdCggd25kUHRyLT5od25kU2VsZiwgJnJlY3QgKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIE5DX0dldEluc2lkZVJlY3Q5NSggd25kUHRyLT5od25kU2VsZiwgJnJlY3QgKTsKCWlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19TWVNNRU5VKQoJICAgIHJlY3QubGVmdCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwoJaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFQk9YKQoJICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKCWlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19NQVhJTUlaRUJPWCkKCSAgICByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CglwdC54ID0gcmVjdFdpbmRvdy5sZWZ0ICsgKHJlY3QucmlnaHQgLSByZWN0LmxlZnQpIC8gMjsKCXB0LnkgPSByZWN0V2luZG93LnRvcCArIHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpLzI7CgloaXR0ZXN0ID0gSFRDQVBUSU9OOwoJKmNhcHR1cmVQb2ludCA9IHB0OwogICAgfQogICAgZWxzZSAgLyogU0NfU0laRSAqLwogICAgewoJd2hpbGUoIWhpdHRlc3QpCgl7CiAgICAgICAgICAgIE1TR19JbnRlcm5hbEdldE1lc3NhZ2UoIFFNU0dfV0lOMzJBLCAmbXNnLCAwLCAwLCBNU0dGX1NJWkUsIFBNX1JFTU9WRSwgRkFMU0UsIE5VTEwgKTsKCSAgICBzd2l0Y2gobXNnLm1lc3NhZ2UpCgkgICAgewoJICAgIGNhc2UgV01fTU9VU0VNT1ZFOgogICAgICAgICAgICAgICAgaGl0dGVzdCA9IE5DX0hhbmRsZU5DSGl0VGVzdCggd25kUHRyLT5od25kU2VsZiwgbXNnLnB0ICk7CgkJaWYgKChoaXR0ZXN0IDwgSFRMRUZUKSB8fCAoaGl0dGVzdCA+IEhUQk9UVE9NUklHSFQpKQoJCSAgICBoaXR0ZXN0ID0gMDsKCQlicmVhazsKCgkgICAgY2FzZSBXTV9MQlVUVE9OVVA6CgkJcmV0dXJuIDA7CgoJICAgIGNhc2UgV01fS0VZRE9XTjoKCQlzd2l0Y2gobXNnLndQYXJhbSkKCQl7CgkJY2FzZSBWS19VUDoKCQkgICAgaGl0dGVzdCA9IEhUVE9QOwoJCSAgICBwdC54ID0ocmVjdFdpbmRvdy5sZWZ0K3JlY3RXaW5kb3cucmlnaHQpLzI7CgkJICAgIHB0LnkgPSByZWN0V2luZG93LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lGUkFNRSkgLyAyOwoJCSAgICBicmVhazsKCQljYXNlIFZLX0RPV046CgkJICAgIGhpdHRlc3QgPSBIVEJPVFRPTTsKCQkgICAgcHQueCA9KHJlY3RXaW5kb3cubGVmdCtyZWN0V2luZG93LnJpZ2h0KS8yOwoJCSAgICBwdC55ID0gcmVjdFdpbmRvdy5ib3R0b20gLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpIC8gMjsKCQkgICAgYnJlYWs7CgkJY2FzZSBWS19MRUZUOgoJCSAgICBoaXR0ZXN0ID0gSFRMRUZUOwoJCSAgICBwdC54ID0gcmVjdFdpbmRvdy5sZWZ0ICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWEZSQU1FKSAvIDI7CgkJICAgIHB0LnkgPShyZWN0V2luZG93LnRvcCtyZWN0V2luZG93LmJvdHRvbSkvMjsKCQkgICAgYnJlYWs7CgkJY2FzZSBWS19SSUdIVDoKCQkgICAgaGl0dGVzdCA9IEhUUklHSFQ7CgkJICAgIHB0LnggPSByZWN0V2luZG93LnJpZ2h0IC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWEZSQU1FKSAvIDI7CgkJICAgIHB0LnkgPShyZWN0V2luZG93LnRvcCtyZWN0V2luZG93LmJvdHRvbSkvMjsKCQkgICAgYnJlYWs7CgkJY2FzZSBWS19SRVRVUk46CgkJY2FzZSBWS19FU0NBUEU6IHJldHVybiAwOwoJCX0KCSAgICB9Cgl9CgkqY2FwdHVyZVBvaW50ID0gcHQ7CiAgICB9CiAgICBTZXRDdXJzb3JQb3MoIHB0LngsIHB0LnkgKTsKICAgIE5DX0hhbmRsZVNldEN1cnNvciggd25kUHRyLT5od25kU2VsZiwgCgkJCXduZFB0ci0+aHduZFNlbGYsIE1BS0VMT05HKCBoaXR0ZXN0LCBXTV9NT1VTRU1PVkUgKSk7CiAgICByZXR1cm4gaGl0dGVzdDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfRG9TaXplTW92ZQogKgogKiBQZXJmb3JtIFNDX01PVkUgYW5kIFNDX1NJWkUgY29tbWFuZHMuICAgICAgICAgICAgICAgYAogKi8Kc3RhdGljIHZvaWQgTkNfRG9TaXplTW92ZSggSFdORCBod25kLCBXT1JEIHdQYXJhbSApCnsKICAgIE1TRyBtc2c7CiAgICBSRUNUIHNpemluZ1JlY3QsIG1vdXNlUmVjdCwgb3JpZ1JlY3Q7CiAgICBIREMgaGRjOwogICAgTE9ORyBoaXR0ZXN0ID0gKExPTkcpKHdQYXJhbSAmIDB4MGYpOwogICAgSENVUlNPUjE2IGhEcmFnQ3Vyc29yID0gMCwgaE9sZEN1cnNvciA9IDA7CiAgICBQT0lOVCBtaW5UcmFjaywgbWF4VHJhY2s7CiAgICBQT0lOVCBjYXB0dXJlUG9pbnQsIHB0OwogICAgV05EICogICAgIHduZFB0ciA9IFdJTl9GaW5kV25kUHRyKCBod25kICk7CiAgICBCT09MICAgIHRoaWNrZnJhbWUgPSBIQVNfVEhJQ0tGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApOwogICAgQk9PTCAgICBpY29uaWMgPSB3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRTsKICAgIEJPT0wgICAgbW92ZWQgPSBGQUxTRTsKICAgIERXT1JEICAgICBkd1BvaW50ID0gR2V0TWVzc2FnZVBvcyAoKTsKICAgIEJPT0wgRHJhZ0Z1bGxXaW5kb3dzID0gRkFMU0U7CiAgICBpbnQgaVduZHNMb2NrczsKICAgIAogICAgU3lzdGVtUGFyYW1ldGVyc0luZm9BKFNQSV9HRVREUkFHRlVMTFdJTkRPV1MsIDAsICZEcmFnRnVsbFdpbmRvd3MsIDApOwoKICAgIHB0LnggPSBTTE9XT1JEKGR3UG9pbnQpOwogICAgcHQueSA9IFNISVdPUkQoZHdQb2ludCk7CiAgICBjYXB0dXJlUG9pbnQgPSBwdDsKCiAgICBpZiAoSXNab29tZWQoaHduZCkgfHwgIUlzV2luZG93VmlzaWJsZShod25kKSB8fAogICAgICAgICh3bmRQdHItPmZsYWdzICYgV0lOX01BTkFHRUQpKSBnb3RvIEVORDsKCiAgICBpZiAoKHdQYXJhbSAmIDB4ZmZmMCkgPT0gU0NfTU9WRSkKICAgIHsKCWlmICghaGl0dGVzdCkgCgkgICAgIGhpdHRlc3QgPSBOQ19TdGFydFNpemVNb3ZlKCB3bmRQdHIsIHdQYXJhbSwgJmNhcHR1cmVQb2ludCApOwoJaWYgKCFoaXR0ZXN0KSBnb3RvIEVORDsKICAgIH0KICAgIGVsc2UgIC8qIFNDX1NJWkUgKi8KICAgIHsKCWlmICghdGhpY2tmcmFtZSkgZ290byBFTkQ7CglpZiAoIGhpdHRlc3QgJiYgaGl0dGVzdCAhPSBIVFNZU01FTlUgKSBoaXR0ZXN0ICs9IDI7CgllbHNlCgl7CgkgICAgU2V0Q2FwdHVyZShod25kKTsKCSAgICBoaXR0ZXN0ID0gTkNfU3RhcnRTaXplTW92ZSggd25kUHRyLCB3UGFyYW0sICZjYXB0dXJlUG9pbnQgKTsKCSAgICBpZiAoIWhpdHRlc3QpCgkgICAgewoJCVJlbGVhc2VDYXB0dXJlKCk7CgkJZ290byBFTkQ7CgkgICAgfQoJfQogICAgfQoKICAgICAgLyogR2V0IG1pbi9tYXggaW5mbyAqLwoKICAgIFdJTlBPU19HZXRNaW5NYXhJbmZvKCB3bmRQdHIsIE5VTEwsIE5VTEwsICZtaW5UcmFjaywgJm1heFRyYWNrICk7CiAgICBzaXppbmdSZWN0ID0gd25kUHRyLT5yZWN0V2luZG93OwogICAgb3JpZ1JlY3QgPSBzaXppbmdSZWN0OwogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NISUxEKQoJR2V0Q2xpZW50UmVjdCggd25kUHRyLT5wYXJlbnQtPmh3bmRTZWxmLCAmbW91c2VSZWN0ICk7CiAgICBlbHNlIAogICAgICAgIFNldFJlY3QoJm1vdXNlUmVjdCwgMCwgMCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTiksIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pKTsKICAgIGlmIChPTl9MRUZUX0JPUkRFUihoaXR0ZXN0KSkKICAgIHsKCW1vdXNlUmVjdC5sZWZ0ICA9IG1heCggbW91c2VSZWN0LmxlZnQsIHNpemluZ1JlY3QucmlnaHQtbWF4VHJhY2sueCApOwoJbW91c2VSZWN0LnJpZ2h0ID0gbWluKCBtb3VzZVJlY3QucmlnaHQsIHNpemluZ1JlY3QucmlnaHQtbWluVHJhY2sueCApOwogICAgfQogICAgZWxzZSBpZiAoT05fUklHSFRfQk9SREVSKGhpdHRlc3QpKQogICAgewoJbW91c2VSZWN0LmxlZnQgID0gbWF4KCBtb3VzZVJlY3QubGVmdCwgc2l6aW5nUmVjdC5sZWZ0K21pblRyYWNrLnggKTsKCW1vdXNlUmVjdC5yaWdodCA9IG1pbiggbW91c2VSZWN0LnJpZ2h0LCBzaXppbmdSZWN0LmxlZnQrbWF4VHJhY2sueCApOwogICAgfQogICAgaWYgKE9OX1RPUF9CT1JERVIoaGl0dGVzdCkpCiAgICB7Cgltb3VzZVJlY3QudG9wICAgID0gbWF4KCBtb3VzZVJlY3QudG9wLCBzaXppbmdSZWN0LmJvdHRvbS1tYXhUcmFjay55ICk7Cgltb3VzZVJlY3QuYm90dG9tID0gbWluKCBtb3VzZVJlY3QuYm90dG9tLHNpemluZ1JlY3QuYm90dG9tLW1pblRyYWNrLnkpOwogICAgfQogICAgZWxzZSBpZiAoT05fQk9UVE9NX0JPUkRFUihoaXR0ZXN0KSkKICAgIHsKCW1vdXNlUmVjdC50b3AgICAgPSBtYXgoIG1vdXNlUmVjdC50b3AsIHNpemluZ1JlY3QudG9wK21pblRyYWNrLnkgKTsKCW1vdXNlUmVjdC5ib3R0b20gPSBtaW4oIG1vdXNlUmVjdC5ib3R0b20sIHNpemluZ1JlY3QudG9wK21heFRyYWNrLnkgKTsKICAgIH0KICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19DSElMRCkKICAgIHsKCU1hcFdpbmRvd1BvaW50cyggd25kUHRyLT5wYXJlbnQtPmh3bmRTZWxmLCAwLCAKCQkoTFBQT0lOVCkmbW91c2VSZWN0LCAyICk7CiAgICB9CiAgICBTZW5kTWVzc2FnZUEoIGh3bmQsIFdNX0VOVEVSU0laRU1PVkUsIDAsIDAgKTsKCiAgICBpZiAoR2V0Q2FwdHVyZSgpICE9IGh3bmQpIFNldENhcHR1cmUoIGh3bmQgKTsgICAgCgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NISUxEKQogICAgewogICAgICAgICAgLyogUmV0cmlldmUgYSBkZWZhdWx0IGNhY2hlIERDICh3aXRob3V0IHVzaW5nIHRoZSB3aW5kb3cgc3R5bGUpICovCiAgICAgICAgaGRjID0gR2V0RENFeCggd25kUHRyLT5wYXJlbnQtPmh3bmRTZWxmLCAwLCBEQ1hfQ0FDSEUgKTsKICAgIH0KICAgIGVsc2UKICAgIHsgIC8qIEdyYWIgdGhlIHNlcnZlciBvbmx5IHdoZW4gbW92aW5nIHRvcC1sZXZlbCB3aW5kb3dzIHdpdGhvdXQgZGVza3RvcCAqLwoJaGRjID0gR2V0REMoIDAgKTsKICAgIH0KCiAgICB3bmRQdHItPnBEcml2ZXItPnBQcmVTaXplTW92ZSh3bmRQdHIpOwoKICAgIGlmKCBpY29uaWMgKSAvKiBjcmVhdGUgYSBjdXJzb3IgZm9yIGRyYWdnaW5nICovCiAgICB7CglISUNPTjE2IGhJY29uID0gR2V0Q2xhc3NXb3JkKHduZFB0ci0+aHduZFNlbGYsIEdDV19ISUNPTik7CglpZighaEljb24pIGhJY29uID0gKEhJQ09OMTYpIFNlbmRNZXNzYWdlMTYoIGh3bmQsIFdNX1FVRVJZRFJBR0lDT04sIDAsIDBMKTsKCWlmKCBoSWNvbiApIGhEcmFnQ3Vyc29yID0gIENVUlNPUklDT05fSWNvblRvQ3Vyc29yKCBoSWNvbiwgVFJVRSApOwoJaWYoICFoRHJhZ0N1cnNvciApIGljb25pYyA9IEZBTFNFOwogICAgfQoKICAgIC8qIGludmVydCBmcmFtZSBpZiBXSU4zMV9MT09LIHRvIGluZGljYXRlIG1vdXNlIGNsaWNrIG9uIGNhcHRpb24gKi8KICAgIGlmKCAhaWNvbmljICYmIFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0sgKQoJaWYoIURyYWdGdWxsV2luZG93cykKCU5DX0RyYXdNb3ZpbmdGcmFtZSggaGRjLCAmc2l6aW5nUmVjdCwgdGhpY2tmcmFtZSApOwoKICAgIHdoaWxlKDEpCiAgICB7CiAgICAgICAgaW50IGR4ID0gMCwgZHkgPSAwOwoKICAgICAgICBNU0dfSW50ZXJuYWxHZXRNZXNzYWdlKCBRTVNHX1dJTjMyQSwgJm1zZywgMCwgMCwgTVNHRl9TSVpFLCBQTV9SRU1PVkUsIEZBTFNFLCBOVUxMICk7CgoJICAvKiBFeGl0IG9uIGJ1dHRvbi11cCwgUmV0dXJuLCBvciBFc2MgKi8KCWlmICgobXNnLm1lc3NhZ2UgPT0gV01fTEJVVFRPTlVQKSB8fAoJICAgICgobXNnLm1lc3NhZ2UgPT0gV01fS0VZRE9XTikgJiYgCgkgICAgICgobXNnLndQYXJhbSA9PSBWS19SRVRVUk4pIHx8IChtc2cud1BhcmFtID09IFZLX0VTQ0FQRSkpKSkgYnJlYWs7CgogICAgICAgIGlmIChtc2cubWVzc2FnZSA9PSBXTV9QQUlOVCkKICAgICAgICB7CiAgICAgICAgICAgIGlmKCFpY29uaWMgJiYgIURyYWdGdWxsV2luZG93cykgTkNfRHJhd01vdmluZ0ZyYW1lKCBoZGMsICZzaXppbmdSZWN0LCB0aGlja2ZyYW1lICk7CiAgICAgICAgICAgIFVwZGF0ZVdpbmRvdyggbXNnLmh3bmQgKTsKICAgICAgICAgICAgaWYoIWljb25pYyAmJiAhRHJhZ0Z1bGxXaW5kb3dzKSBOQ19EcmF3TW92aW5nRnJhbWUoIGhkYywgJnNpemluZ1JlY3QsIHRoaWNrZnJhbWUgKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKCWlmICgobXNnLm1lc3NhZ2UgIT0gV01fS0VZRE9XTikgJiYgKG1zZy5tZXNzYWdlICE9IFdNX01PVVNFTU9WRSkpCgkgICAgY29udGludWU7ICAvKiBXZSBhcmUgbm90IGludGVyZXN0ZWQgaW4gb3RoZXIgbWVzc2FnZXMgKi8KCiAgICAgICAgcHQgPSBtc2cucHQ7CgkKCWlmIChtc2cubWVzc2FnZSA9PSBXTV9LRVlET1dOKSBzd2l0Y2gobXNnLndQYXJhbSkKCXsKCSAgICBjYXNlIFZLX1VQOiAgICBwdC55IC09IDg7IGJyZWFrOwoJICAgIGNhc2UgVktfRE9XTjogIHB0LnkgKz0gODsgYnJlYWs7CgkgICAgY2FzZSBWS19MRUZUOiAgcHQueCAtPSA4OyBicmVhazsKCSAgICBjYXNlIFZLX1JJR0hUOiBwdC54ICs9IDg7IGJyZWFrOwkJCgl9CgoJcHQueCA9IG1heCggcHQueCwgbW91c2VSZWN0LmxlZnQgKTsKCXB0LnggPSBtaW4oIHB0LngsIG1vdXNlUmVjdC5yaWdodCApOwoJcHQueSA9IG1heCggcHQueSwgbW91c2VSZWN0LnRvcCApOwoJcHQueSA9IG1pbiggcHQueSwgbW91c2VSZWN0LmJvdHRvbSApOwoKCWR4ID0gcHQueCAtIGNhcHR1cmVQb2ludC54OwoJZHkgPSBwdC55IC0gY2FwdHVyZVBvaW50Lnk7CgoJaWYgKGR4IHx8IGR5KQoJewoJICAgIGlmKCAhbW92ZWQgKQoJICAgIHsKCQltb3ZlZCA9IFRSVUU7CgoJCWlmKCBpY29uaWMgKSAvKiBvaywgbm8gc3lzdGVtIHBvcHVwIHRyYWNraW5nICovCgkJewoJCSAgICBoT2xkQ3Vyc29yID0gU2V0Q3Vyc29yKGhEcmFnQ3Vyc29yKTsKCQkgICAgU2hvd0N1cnNvciggVFJVRSApOwoJCSAgICBXSU5QT1NfU2hvd0ljb25UaXRsZSggd25kUHRyLCBGQUxTRSApOwoJCX0gZWxzZSBpZihUV0VBS19XaW5lTG9vayAhPSBXSU4zMV9MT09LKQogICAgICAgICAgICAgICAgewoJCSAgICBpZighRHJhZ0Z1bGxXaW5kb3dzKQoJCSAgICBOQ19EcmF3TW92aW5nRnJhbWUoIGhkYywgJnNpemluZ1JlY3QsIHRoaWNrZnJhbWUgKTsKICAgICAgICAgICAgICAgIH0KCSAgICB9CgoJICAgIGlmIChtc2cubWVzc2FnZSA9PSBXTV9LRVlET1dOKSBTZXRDdXJzb3JQb3MoIHB0LngsIHB0LnkgKTsKCSAgICBlbHNlCgkgICAgewoJCVJFQ1QgbmV3UmVjdCA9IHNpemluZ1JlY3Q7CiAgICAgICAgICAgICAgICBXUEFSQU0gd3BTaXppbmdIaXQgPSAwOwoKCQlpZiAoaGl0dGVzdCA9PSBIVENBUFRJT04pIE9mZnNldFJlY3QoICZuZXdSZWN0LCBkeCwgZHkgKTsKCQlpZiAoT05fTEVGVF9CT1JERVIoaGl0dGVzdCkpIG5ld1JlY3QubGVmdCArPSBkeDsKCQllbHNlIGlmIChPTl9SSUdIVF9CT1JERVIoaGl0dGVzdCkpIG5ld1JlY3QucmlnaHQgKz0gZHg7CgkJaWYgKE9OX1RPUF9CT1JERVIoaGl0dGVzdCkpIG5ld1JlY3QudG9wICs9IGR5OwoJCWVsc2UgaWYgKE9OX0JPVFRPTV9CT1JERVIoaGl0dGVzdCkpIG5ld1JlY3QuYm90dG9tICs9IGR5OwoJCWlmKCFpY29uaWMgJiYgIURyYWdGdWxsV2luZG93cykgTkNfRHJhd01vdmluZ0ZyYW1lKCBoZGMsICZzaXppbmdSZWN0LCB0aGlja2ZyYW1lICk7CgkJY2FwdHVyZVBvaW50ID0gcHQ7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8qIGRldGVybWluZSB0aGUgaGl0IGxvY2F0aW9uICovCiAgICAgICAgICAgICAgICBpZiAoaGl0dGVzdCA+PSBIVExFRlQgJiYgaGl0dGVzdCA8PSBIVEJPVFRPTVJJR0hUKQogICAgICAgICAgICAgICAgICAgIHdwU2l6aW5nSGl0ID0gV01TWl9MRUZUICsgKGhpdHRlc3QgLSBIVExFRlQpOwoJCVNlbmRNZXNzYWdlQSggaHduZCwgV01fU0laSU5HLCB3cFNpemluZ0hpdCwgKExQQVJBTSkmbmV3UmVjdCApOwoKCQlpZiAoIWljb25pYykKCQl7CgkJICAgIGlmKCFEcmFnRnVsbFdpbmRvd3MpCgkJCU5DX0RyYXdNb3ZpbmdGcmFtZSggaGRjLCAmbmV3UmVjdCwgdGhpY2tmcmFtZSApOwoJCSAgICBlbHNlIHsKCQkJLyogVG8gYXZvaWQgYW55IGRlYWRsb2NrcywgYWxsIHRoZSBsb2NrcyBvbiB0aGUgd2luZG93cwoJCQkgICBzdHJ1Y3R1cmVzIG11c3QgYmUgc3VzcGVuZGVkIGJlZm9yZSB0aGUgU2V0V2luZG93UG9zICovCgkJCWlXbmRzTG9ja3MgPSBXSU5fU3VzcGVuZFduZHNMb2NrKCk7CgkJCVNldFdpbmRvd1BvcyggaHduZCwgMCwgbmV3UmVjdC5sZWZ0LCBuZXdSZWN0LnRvcCwKCQkJICAgIG5ld1JlY3QucmlnaHQgLSBuZXdSZWN0LmxlZnQsCgkJCSAgICBuZXdSZWN0LmJvdHRvbSAtIG5ld1JlY3QudG9wLAoJCQkgICAgKCBoaXR0ZXN0ID09IEhUQ0FQVElPTiApID8gU1dQX05PU0laRSA6IDAgKTsKCQkJV0lOX1Jlc3RvcmVXbmRzTG9jayhpV25kc0xvY2tzKTsKCQkgICAgfQoJCX0KCQlzaXppbmdSZWN0ID0gbmV3UmVjdDsKCSAgICB9Cgl9CiAgICB9CgogICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgIGlmKCBpY29uaWMgKQogICAgewoJaWYoIG1vdmVkICkgLyogcmVzdG9yZSBjdXJzb3JzLCBzaG93IGljb24gdGl0bGUgbGF0ZXIgb24gKi8KCXsKCSAgICBTaG93Q3Vyc29yKCBGQUxTRSApOwoJICAgIFNldEN1cnNvciggaE9sZEN1cnNvciApOwoJfQogICAgICAgIERlc3Ryb3lDdXJzb3IoIGhEcmFnQ3Vyc29yICk7CiAgICB9CiAgICBlbHNlIGlmKG1vdmVkIHx8IFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCglpZighRHJhZ0Z1bGxXaW5kb3dzKQogICAgICAgIE5DX0RyYXdNb3ZpbmdGcmFtZSggaGRjLCAmc2l6aW5nUmVjdCwgdGhpY2tmcmFtZSApOwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19DSElMRCkKICAgICAgICBSZWxlYXNlREMoIHduZFB0ci0+cGFyZW50LT5od25kU2VsZiwgaGRjICk7CiAgICBlbHNlCiAgICAgICAgUmVsZWFzZURDKCAwLCBoZGMgKTsKCiAgICB3bmRQdHItPnBEcml2ZXItPnBQb3N0U2l6ZU1vdmUod25kUHRyKTsKCiAgICBpZiAoSE9PS19Jc0hvb2tlZCggV0hfQ0JUICkpCiAgICB7CglSRUNUMTYqIHByID0gU0VHUFRSX05FVyhSRUNUMTYpOwoJaWYoIHByICkKCXsKICAgICAgICAgICAgQ09OVl9SRUNUMzJUTzE2KCAmc2l6aW5nUmVjdCwgcHIgKTsKCSAgICBpZiggSE9PS19DYWxsSG9va3MxNiggV0hfQ0JULCBIQ0JUX01PVkVTSVpFLCBod25kLAoJCQkgICAgICAgIChMUEFSQU0pU0VHUFRSX0dFVChwcikpICkKCQlzaXppbmdSZWN0ID0gd25kUHRyLT5yZWN0V2luZG93OwoJICAgIGVsc2UKCQlDT05WX1JFQ1QxNlRPMzIoIHByLCAmc2l6aW5nUmVjdCApOwoJICAgIFNFR1BUUl9GUkVFKHByKTsKCX0KICAgIH0KICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fRVhJVFNJWkVNT1ZFLCAwLCAwICk7CiAgICBTZW5kTWVzc2FnZUEoIGh3bmQsIFdNX1NFVFZJU0lCTEUsICFJc0ljb25pYzE2KGh3bmQpLCAwTCk7CgogICAgLyogd2luZG93IG1vdmVkIG9yIHJlc2l6ZWQgKi8KICAgIGlmIChtb3ZlZCkKICAgIHsKCS8qIFRvIGF2b2lkIGFueSBkZWFkbG9ja3MsIGFsbCB0aGUgbG9ja3Mgb24gdGhlIHdpbmRvd3MKCSAgIHN0cnVjdHVyZXMgbXVzdCBiZSBzdXNwZW5kZWQgYmVmb3JlIHRoZSBTZXRXaW5kb3dQb3MgKi8KCWlXbmRzTG9ja3MgPSBXSU5fU3VzcGVuZFduZHNMb2NrKCk7CgogICAgICAgIC8qIGlmIHRoZSBtb3ZpbmcvcmVzaXppbmcgaXNuJ3QgY2FuY2VsZWQgY2FsbCBTZXRXaW5kb3dQb3MKICAgICAgICAgKiB3aXRoIHRoZSBuZXcgcG9zaXRpb24gb3IgdGhlIG5ldyBzaXplIG9mIHRoZSB3aW5kb3cKICAgICAgICAgKi8KICAgICAgICBpZiAoISgobXNnLm1lc3NhZ2UgPT0gV01fS0VZRE9XTikgJiYgKG1zZy53UGFyYW0gPT0gVktfRVNDQVBFKSkgKQogICAgICAgIHsKCS8qIE5PVEU6IFNXUF9OT0FDVElWQVRFIHByZXZlbnRzIGRvY3VtZW50IHdpbmRvdyBhY3RpdmF0aW9uIGluIFdvcmQgNiAqLwoJaWYoIURyYWdGdWxsV2luZG93cykKCVNldFdpbmRvd1BvcyggaHduZCwgMCwgc2l6aW5nUmVjdC5sZWZ0LCBzaXppbmdSZWN0LnRvcCwKCQkJc2l6aW5nUmVjdC5yaWdodCAtIHNpemluZ1JlY3QubGVmdCwKCQkJc2l6aW5nUmVjdC5ib3R0b20gLSBzaXppbmdSZWN0LnRvcCwKCQkgICAgICAoIGhpdHRlc3QgPT0gSFRDQVBUSU9OICkgPyBTV1BfTk9TSVpFIDogMCApOwogICAgICAgIH0KCWVsc2UgeyAvKiByZXN0b3JlIHByZXZpb3VzIHNpemUvcG9zaXRpb24gKi8KCSAgICBpZihEcmFnRnVsbFdpbmRvd3MpCgkJU2V0V2luZG93UG9zKCBod25kLCAwLCBvcmlnUmVjdC5sZWZ0LCBvcmlnUmVjdC50b3AsCgkJCW9yaWdSZWN0LnJpZ2h0IC0gb3JpZ1JlY3QubGVmdCwKCQkJb3JpZ1JlY3QuYm90dG9tIC0gb3JpZ1JlY3QudG9wLAoJCQkoIGhpdHRlc3QgPT0gSFRDQVBUSU9OICkgPyBTV1BfTk9TSVpFIDogMCApOwoJfQoKCVdJTl9SZXN0b3JlV25kc0xvY2soaVduZHNMb2Nrcyk7CiAgICB9CgogICAgaWYoIElzV2luZG93KGh3bmQpICkKCWlmKCB3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRSApCgl7CgkgICAgLyogU2luZ2xlIGNsaWNrIGJyaW5ncyB1cCB0aGUgc3lzdGVtIG1lbnUgd2hlbiBpY29uaXplZCAqLwoKCSAgICBpZiggIW1vdmVkICkgCgkgICAgewoJCSBpZiggd25kUHRyLT5kd1N0eWxlICYgV1NfU1lTTUVOVSApIAogICAgICAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZUEoIGh3bmQsIFdNX1NZU0NPTU1BTkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0NfTU9VU0VNRU5VICsgSFRTWVNNRU5VLCBNQUtFTE9ORyhwdC54LHB0LnkpKTsKCSAgICB9CgkgICAgZWxzZSBXSU5QT1NfU2hvd0ljb25UaXRsZSggd25kUHRyLCBUUlVFICk7Cgl9CgpFTkQ6CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19UcmFja01pbk1heEJveDk1CiAqCiAqIFRyYWNrIGEgbW91c2UgYnV0dG9uIHByZXNzIG9uIHRoZSBtaW5pbWl6ZSBvciBtYXhpbWl6ZSBib3guCiAqCiAqIFRoZSBiaWcgZGlmZmVyZW5jZSBiZXR3ZWVuIDMuMSBhbmQgOTUgaXMgdGhlIGRpc2FibGVkIGJ1dHRvbiBzdGF0ZS4KICogSW4gd2luOTUgdGhlIHN5c3RlbSBidXR0b24gY2FuIGJlIGRpc2FibGVkLCBzbyBpdCBjYW4gaWdub3JlIHRoZSBtb3VzZQogKiBldmVudC4KICoKICovCnN0YXRpYyB2b2lkIE5DX1RyYWNrTWluTWF4Qm94OTUoIEhXTkQgaHduZCwgV09SRCB3UGFyYW0gKQp7CiAgICBNU0cgbXNnOwogICAgSERDIGhkYyA9IEdldFdpbmRvd0RDKCBod25kICk7CiAgICBCT09MIHByZXNzZWQgPSBUUlVFOwogICAgVUlOVCBzdGF0ZTsKICAgIERXT1JEIHduZFN0eWxlID0gR2V0V2luZG93TG9uZ0EoIGh3bmQsIEdXTF9TVFlMRSk7CiAgICBITUVOVSBoU3lzTWVudSA9IEdldFN5c3RlbU1lbnUoaHduZCwgRkFMU0UpOwoKICAgIHZvaWQgICgqcGFpbnRCdXR0b24pKEhXTkQsIEhEQzE2LCBCT09MLCBCT09MKTsKCiAgICBpZiAod1BhcmFtID09IEhUTUlOQlVUVE9OKQogICAgewoJLyogSWYgdGhlIHN0eWxlIGlzIG5vdCBwcmVzZW50LCBkbyBub3RoaW5nICovCglpZiAoISh3bmRTdHlsZSAmIFdTX01JTklNSVpFQk9YKSkKCSAgICByZXR1cm47CgoJLyogQ2hlY2sgaWYgdGhlIHN5c21lbnUgaXRlbSBmb3IgbWluaW1pemUgaXMgdGhlcmUgICovCglzdGF0ZSA9IEdldE1lbnVTdGF0ZShoU3lzTWVudSwgU0NfTUlOSU1JWkUsIE1GX0JZQ09NTUFORCk7CgkKCXBhaW50QnV0dG9uID0gJk5DX0RyYXdNaW5CdXR0b245NTsKICAgIH0KICAgIGVsc2UKICAgIHsKCS8qIElmIHRoZSBzdHlsZSBpcyBub3QgcHJlc2VudCwgZG8gbm90aGluZyAqLwoJaWYgKCEod25kU3R5bGUgJiBXU19NQVhJTUlaRUJPWCkpCgkgICAgcmV0dXJuOwoKCS8qIENoZWNrIGlmIHRoZSBzeXNtZW51IGl0ZW0gZm9yIG1heGltaXplIGlzIHRoZXJlICAqLwoJc3RhdGUgPSBHZXRNZW51U3RhdGUoaFN5c01lbnUsIFNDX01BWElNSVpFLCBNRl9CWUNPTU1BTkQpOwoJCglwYWludEJ1dHRvbiA9ICZOQ19EcmF3TWF4QnV0dG9uOTU7CiAgICB9CgogICAgU2V0Q2FwdHVyZSggaHduZCApOwoKICAgICgqcGFpbnRCdXR0b24pKCBod25kLCBoZGMsIFRSVUUsIEZBTFNFKTsKCiAgICBkbwogICAgewoJQk9PTCBvbGRzdGF0ZSA9IHByZXNzZWQ7CiAgICAgICAgTVNHX0ludGVybmFsR2V0TWVzc2FnZSggUU1TR19XSU4zMkEsICZtc2csIDAsIDAsIDAsIFBNX1JFTU9WRSwgRkFMU0UsIE5VTEwgKTsKCglwcmVzc2VkID0gKE5DX0hhbmRsZU5DSGl0VGVzdCggaHduZCwgbXNnLnB0ICkgPT0gd1BhcmFtKTsKCWlmIChwcmVzc2VkICE9IG9sZHN0YXRlKQoJICAgKCpwYWludEJ1dHRvbikoIGh3bmQsIGhkYywgcHJlc3NlZCwgRkFMU0UpOwogICAgfSB3aGlsZSAobXNnLm1lc3NhZ2UgIT0gV01fTEJVVFRPTlVQKTsKCiAgICAoKnBhaW50QnV0dG9uKSggaHduZCwgaGRjLCBGQUxTRSwgRkFMU0UpOwoKICAgIFJlbGVhc2VDYXB0dXJlKCk7CiAgICBSZWxlYXNlREMoIGh3bmQsIGhkYyApOwoKICAgIC8qIElmIHRoZSBpdGVtIG1pbmltaXplIG9yIG1heGltaXplIG9mIHRoZSBzeXNtZW51IGFyZSBub3QgdGhlcmUgKi8KICAgIC8qIG9yIGlmIHRoZSBzdHlsZSBpcyBub3QgcHJlc2VudCwgZG8gbm90aGluZyAqLwogICAgaWYgKCghcHJlc3NlZCkgfHwgKHN0YXRlID09IDB4RkZGRkZGRkYpKQoJcmV0dXJuOwoKICAgIGlmICh3UGFyYW0gPT0gSFRNSU5CVVRUT04pIAogICAgICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfTUlOSU1JWkUsIE1BS0VMT05HKG1zZy5wdC54LG1zZy5wdC55KSApOwogICAgZWxzZQogICAgICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fU1lTQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgIElzWm9vbWVkKGh3bmQpID8gU0NfUkVTVE9SRTpTQ19NQVhJTUlaRSwgTUFLRUxPTkcobXNnLnB0LngsbXNnLnB0LnkpICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfVHJhY2tNaW5NYXhCb3gKICoKICogVHJhY2sgYSBtb3VzZSBidXR0b24gcHJlc3Mgb24gdGhlIG1pbmltaXplIG9yIG1heGltaXplIGJveC4KICovCnN0YXRpYyB2b2lkIE5DX1RyYWNrTWluTWF4Qm94KCBIV05EIGh3bmQsIFdPUkQgd1BhcmFtICkKewogICAgTVNHIG1zZzsKICAgIEhEQyBoZGMgPSBHZXRXaW5kb3dEQyggaHduZCApOwogICAgQk9PTCBwcmVzc2VkID0gVFJVRTsKICAgIHZvaWQgICgqcGFpbnRCdXR0b24pKEhXTkQsIEhEQzE2LCBCT09MKTsKCiAgICBTZXRDYXB0dXJlKCBod25kICk7CgogICAgaWYgKHdQYXJhbSA9PSBIVE1JTkJVVFRPTikKCXBhaW50QnV0dG9uID0gJk5DX0RyYXdNaW5CdXR0b247CiAgICBlbHNlCglwYWludEJ1dHRvbiA9ICZOQ19EcmF3TWF4QnV0dG9uOwoKICAgICgqcGFpbnRCdXR0b24pKCBod25kLCBoZGMsIFRSVUUpOwoKICAgIGRvCiAgICB7CglCT09MIG9sZHN0YXRlID0gcHJlc3NlZDsKICAgICAgICBNU0dfSW50ZXJuYWxHZXRNZXNzYWdlKCBRTVNHX1dJTjMyQSwgJm1zZywgMCwgMCwgMCwgUE1fUkVNT1ZFLCBGQUxTRSwgTlVMTCApOwoKCXByZXNzZWQgPSAoTkNfSGFuZGxlTkNIaXRUZXN0KCBod25kLCBtc2cucHQgKSA9PSB3UGFyYW0pOwoJaWYgKHByZXNzZWQgIT0gb2xkc3RhdGUpCgkgICAoKnBhaW50QnV0dG9uKSggaHduZCwgaGRjLCBwcmVzc2VkKTsKICAgIH0gd2hpbGUgKG1zZy5tZXNzYWdlICE9IFdNX0xCVVRUT05VUCk7CgogICAgKCpwYWludEJ1dHRvbikoIGh3bmQsIGhkYywgRkFMU0UpOwoKICAgIFJlbGVhc2VDYXB0dXJlKCk7CiAgICBSZWxlYXNlREMoIGh3bmQsIGhkYyApOwoKICAgIGlmICghcHJlc3NlZCkgcmV0dXJuOwoKICAgIGlmICh3UGFyYW0gPT0gSFRNSU5CVVRUT04pIAogICAgICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfTUlOSU1JWkUsIE1BS0VMT05HKG1zZy5wdC54LG1zZy5wdC55KSApOwogICAgZWxzZQogICAgICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fU1lTQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgIElzWm9vbWVkKGh3bmQpID8gU0NfUkVTVE9SRTpTQ19NQVhJTUlaRSwgTUFLRUxPTkcobXNnLnB0LngsbXNnLnB0LnkpICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTkNfVHJhY2tDbG9zZUJ1dHRvbjk1CiAqCiAqIFRyYWNrIGEgbW91c2UgYnV0dG9uIHByZXNzIG9uIHRoZSBXaW45NSBjbG9zZSBidXR0b24uCiAqLwpzdGF0aWMgdm9pZApOQ19UcmFja0Nsb3NlQnV0dG9uOTUgKEhXTkQgaHduZCwgV09SRCB3UGFyYW0pCnsKICAgIE1TRyBtc2c7CiAgICBIREMgaGRjOwogICAgQk9PTCBwcmVzc2VkID0gVFJVRTsKICAgIEhNRU5VIGhTeXNNZW51ID0gR2V0U3lzdGVtTWVudShod25kLCBGQUxTRSk7CiAgICBVSU5UIHN0YXRlOwoKICAgIGlmKGhTeXNNZW51ID09IDApCglyZXR1cm47CgogICAgc3RhdGUgPSBHZXRNZW51U3RhdGUoaFN5c01lbnUsIFNDX0NMT1NFLCBNRl9CWUNPTU1BTkQpOwoJICAgIAogICAgLyogSWYgdGhlIGl0ZW0gY2xvc2Ugb2YgdGhlIHN5c21lbnUgaXMgZGlzYWJsZWQgb3Igbm90IHRoZXJlIGRvIG5vdGhpbmcgKi8KICAgIGlmKChzdGF0ZSAmIE1GX0RJU0FCTEVEKSB8fCAoc3RhdGUgJiBNRl9HUkFZRUQpIHx8IChzdGF0ZSA9PSAweEZGRkZGRkZGKSkKCXJldHVybjsKCiAgICBoZGMgPSBHZXRXaW5kb3dEQyggaHduZCApOwoKICAgIFNldENhcHR1cmUoIGh3bmQgKTsKCiAgICBOQ19EcmF3Q2xvc2VCdXR0b245NSAoaHduZCwgaGRjLCBUUlVFLCBGQUxTRSk7CgogICAgZG8KICAgIHsKCUJPT0wgb2xkc3RhdGUgPSBwcmVzc2VkOwogICAgICAgIE1TR19JbnRlcm5hbEdldE1lc3NhZ2UoIFFNU0dfV0lOMzJBLCAmbXNnLCAwLCAwLCAwLCBQTV9SRU1PVkUsIEZBTFNFLCBOVUxMICk7CgoJcHJlc3NlZCA9IChOQ19IYW5kbGVOQ0hpdFRlc3QoIGh3bmQsIG1zZy5wdCApID09IHdQYXJhbSk7CglpZiAocHJlc3NlZCAhPSBvbGRzdGF0ZSkKCSAgIE5DX0RyYXdDbG9zZUJ1dHRvbjk1IChod25kLCBoZGMsIHByZXNzZWQsIEZBTFNFKTsKICAgIH0gd2hpbGUgKG1zZy5tZXNzYWdlICE9IFdNX0xCVVRUT05VUCk7CgogICAgTkNfRHJhd0Nsb3NlQnV0dG9uOTUgKGh3bmQsIGhkYywgRkFMU0UsIEZBTFNFKTsKCiAgICBSZWxlYXNlQ2FwdHVyZSgpOwogICAgUmVsZWFzZURDKCBod25kLCBoZGMgKTsKICAgIGlmICghcHJlc3NlZCkgcmV0dXJuOwoKICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfQ0xPU0UsIE1BS0VMT05HKG1zZy5wdC54LG1zZy5wdC55KSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19UcmFja1Njcm9sbEJhcgogKgogKiBUcmFjayBhIG1vdXNlIGJ1dHRvbiBwcmVzcyBvbiB0aGUgaG9yaXpvbnRhbCBvciB2ZXJ0aWNhbCBzY3JvbGwtYmFyLgogKi8Kc3RhdGljIHZvaWQgTkNfVHJhY2tTY3JvbGxCYXIoIEhXTkQgaHduZCwgV1BBUkFNIHdQYXJhbSwgUE9JTlQgcHQgKQp7CiAgICBNU0cxNiAqbXNnOwogICAgSU5UIHNjcm9sbGJhcjsKICAgIFdORCAqd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICBpZiAoKHdQYXJhbSAmIDB4ZmZmMCkgPT0gU0NfSFNDUk9MTCkKICAgIHsKCWlmICgod1BhcmFtICYgMHgwZikgIT0gSFRIU0NST0xMKSBnb3RvIEVORDsKCXNjcm9sbGJhciA9IFNCX0hPUlo7CiAgICB9CiAgICBlbHNlICAvKiBTQ19WU0NST0xMICovCiAgICB7CglpZiAoKHdQYXJhbSAmIDB4MGYpICE9IEhUVlNDUk9MTCkgZ290byBFTkQ7CglzY3JvbGxiYXIgPSBTQl9WRVJUOwogICAgfQoKICAgIGlmICghKG1zZyA9IFNFR1BUUl9ORVcoTVNHMTYpKSkgZ290byBFTkQ7CiAgICBwdC54IC09IHduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0OwogICAgcHQueSAtPSB3bmRQdHItPnJlY3RXaW5kb3cudG9wOwogICAgU2V0Q2FwdHVyZSggaHduZCApOwogICAgU0NST0xMX0hhbmRsZVNjcm9sbEV2ZW50KCBod25kLCBzY3JvbGxiYXIsIFdNX0xCVVRUT05ET1dOLCBwdCApOwoKICAgIGRvCiAgICB7CiAgICAgICAgR2V0TWVzc2FnZTE2KCBTRUdQVFJfR0VUKG1zZyksIDAsIDAsIDAgKTsKCXN3aXRjaChtc2ctPm1lc3NhZ2UpCgl7CgljYXNlIFdNX0xCVVRUT05VUDoKCWNhc2UgV01fTU9VU0VNT1ZFOgogICAgICAgIGNhc2UgV01fU1lTVElNRVI6CiAgICAgICAgICAgIHB0LnggPSBMT1dPUkQobXNnLT5sUGFyYW0pICsgd25kUHRyLT5yZWN0Q2xpZW50LmxlZnQgLSAKCSAgICAgIHduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0OwogICAgICAgICAgICBwdC55ID0gSElXT1JEKG1zZy0+bFBhcmFtKSArIHduZFB0ci0+cmVjdENsaWVudC50b3AgLSAKCSAgICAgIHduZFB0ci0+cmVjdFdpbmRvdy50b3A7CiAgICAgICAgICAgIFNDUk9MTF9IYW5kbGVTY3JvbGxFdmVudCggaHduZCwgc2Nyb2xsYmFyLCBtc2ctPm1lc3NhZ2UsIHB0ICk7CgkgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgVHJhbnNsYXRlTWVzc2FnZTE2KCBtc2cgKTsKICAgICAgICAgICAgRGlzcGF0Y2hNZXNzYWdlMTYoIG1zZyApOwogICAgICAgICAgICBicmVhazsKCX0KICAgICAgICBpZiAoIUlzV2luZG93KCBod25kICkpCiAgICAgICAgewogICAgICAgICAgICBSZWxlYXNlQ2FwdHVyZSgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9IHdoaWxlIChtc2ctPm1lc3NhZ2UgIT0gV01fTEJVVFRPTlVQKTsKICAgIFNFR1BUUl9GUkVFKG1zZyk7CkVORDoKICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfSGFuZGxlTkNMQnV0dG9uRG93bgogKgogKiBIYW5kbGUgYSBXTV9OQ0xCVVRUT05ET1dOIG1lc3NhZ2UuIENhbGxlZCBmcm9tIERlZldpbmRvd1Byb2MoKS4KICovCkxPTkcgTkNfSGFuZGxlTkNMQnV0dG9uRG93biggV05EKiBwV25kLCBXUEFSQU0xNiB3UGFyYW0sIExQQVJBTSBsUGFyYW0gKQp7CiAgICBIV05EIGh3bmQgPSBwV25kLT5od25kU2VsZjsKCiAgICBzd2l0Y2god1BhcmFtKSAgLyogSGl0IHRlc3QgKi8KICAgIHsKICAgIGNhc2UgSFRDQVBUSU9OOgoJIGh3bmQgPSBXSU5fR2V0VG9wUGFyZW50KGh3bmQpOwoKCSBpZiggV0lOUE9TX1NldEFjdGl2ZVdpbmRvdyhod25kLCBUUlVFLCBUUlVFKSB8fCAoR2V0QWN0aXZlV2luZG93KCkgPT0gaHduZCkgKQoJCVNlbmRNZXNzYWdlMTYoIHBXbmQtPmh3bmRTZWxmLCBXTV9TWVNDT01NQU5ELCBTQ19NT1ZFICsgSFRDQVBUSU9OLCBsUGFyYW0gKTsKCSBicmVhazsKCiAgICBjYXNlIEhUU1lTTUVOVToKCSBpZiggcFduZC0+ZHdTdHlsZSAmIFdTX1NZU01FTlUgKQoJIHsKCSAgICAgaWYoICEocFduZC0+ZHdTdHlsZSAmIFdTX01JTklNSVpFKSApCgkgICAgIHsKCQlIREMgaERDID0gR2V0V2luZG93REMoaHduZCk7CgkJaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCgkJICAgIE5DX0RyYXdTeXNCdXR0b24oIGh3bmQsIGhEQywgVFJVRSApOwoJCWVsc2UKCQkgICAgTkNfRHJhd1N5c0J1dHRvbjk1KCBod25kLCBoREMsIFRSVUUgKTsKCQlSZWxlYXNlREMoIGh3bmQsIGhEQyApOwoJICAgICB9CgkgICAgIFNlbmRNZXNzYWdlMTYoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX01PVVNFTUVOVSArIEhUU1lTTUVOVSwgbFBhcmFtICk7CgkgfQoJIGJyZWFrOwoKICAgIGNhc2UgSFRNRU5VOgoJU2VuZE1lc3NhZ2UxNiggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfTU9VU0VNRU5VLCBsUGFyYW0gKTsKCWJyZWFrOwoKICAgIGNhc2UgSFRIU0NST0xMOgoJU2VuZE1lc3NhZ2UxNiggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfSFNDUk9MTCArIEhUSFNDUk9MTCwgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUVlNDUk9MTDoKCVNlbmRNZXNzYWdlMTYoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX1ZTQ1JPTEwgKyBIVFZTQ1JPTEwsIGxQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBIVE1JTkJVVFRPTjoKICAgIGNhc2UgSFRNQVhCVVRUT046CglpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKCSAgICBOQ19UcmFja01pbk1heEJveCggaHduZCwgd1BhcmFtICk7CgllbHNlCgkgICAgTkNfVHJhY2tNaW5NYXhCb3g5NSggaHduZCwgd1BhcmFtICk7CSAgICAKCWJyZWFrOwoKICAgIGNhc2UgSFRDTE9TRToKCWlmIChUV0VBS19XaW5lTG9vayA+PSBXSU45NV9MT09LKQoJICAgIE5DX1RyYWNrQ2xvc2VCdXR0b245NSAoaHduZCwgd1BhcmFtKTsKCWJyZWFrOwoJCiAgICBjYXNlIEhUTEVGVDoKICAgIGNhc2UgSFRSSUdIVDoKICAgIGNhc2UgSFRUT1A6CiAgICBjYXNlIEhUVE9QTEVGVDoKICAgIGNhc2UgSFRUT1BSSUdIVDoKICAgIGNhc2UgSFRCT1RUT006CiAgICBjYXNlIEhUQk9UVE9NTEVGVDoKICAgIGNhc2UgSFRCT1RUT01SSUdIVDoKCS8qIG1ha2Ugc3VyZSBoaXR0ZXN0IGZpdHMgaW50byAweGYgYW5kIGRvZXNuJ3Qgb3ZlcmxhcCB3aXRoIEhUU1lTTUVOVSAqLwoJU2VuZE1lc3NhZ2UxNiggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfU0laRSArIHdQYXJhbSAtIDIsIGxQYXJhbSk7CglicmVhazsKCiAgICBjYXNlIEhUQk9SREVSOgoJYnJlYWs7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfSGFuZGxlTkNMQnV0dG9uRGJsQ2xrCiAqCiAqIEhhbmRsZSBhIFdNX05DTEJVVFRPTkRCTENMSyBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZU5DTEJ1dHRvbkRibENsayggV05EICpwV25kLCBXUEFSQU0xNiB3UGFyYW0sIExQQVJBTSBsUGFyYW0gKQp7CiAgICAvKgogICAgICogaWYgdGhpcyBpcyBhbiBpY29uLCBzZW5kIGEgcmVzdG9yZSBzaW5jZSB3ZSBhcmUgaGFuZGxpbmcKICAgICAqIGEgZG91YmxlIGNsaWNrCiAgICAgKi8KICAgIGlmIChwV25kLT5kd1N0eWxlICYgV1NfTUlOSU1JWkUpCiAgICB7CiAgICAgICAgU2VuZE1lc3NhZ2UxNiggcFduZC0+aHduZFNlbGYsIFdNX1NZU0NPTU1BTkQsIFNDX1JFU1RPUkUsIGxQYXJhbSApOwogICAgICAgIHJldHVybiAwOwogICAgfSAKCiAgICBzd2l0Y2god1BhcmFtKSAgLyogSGl0IHRlc3QgKi8KICAgIHsKICAgIGNhc2UgSFRDQVBUSU9OOgogICAgICAgIC8qIHN0b3AgcHJvY2Vzc2luZyBpZiBXU19NQVhJTUlaRUJPWCBpcyBtaXNzaW5nICovCiAgICAgICAgaWYgKHBXbmQtPmR3U3R5bGUgJiBXU19NQVhJTUlaRUJPWCkKICAgICAgICAgICAgU2VuZE1lc3NhZ2UxNiggcFduZC0+aHduZFNlbGYsIFdNX1NZU0NPTU1BTkQsCiAgICAgICAgICAgICAgICAgICAgICAocFduZC0+ZHdTdHlsZSAmIFdTX01BWElNSVpFKSA/IFNDX1JFU1RPUkUgOiBTQ19NQVhJTUlaRSwKICAgICAgICAgICAgICAgICAgICAgIGxQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBIVFNZU01FTlU6CiAgICAgICAgaWYgKCEoR2V0Q2xhc3NXb3JkKHBXbmQtPmh3bmRTZWxmLCBHQ1dfU1RZTEUpICYgQ1NfTk9DTE9TRSkpCiAgICAgICAgICAgIFNlbmRNZXNzYWdlMTYoIHBXbmQtPmh3bmRTZWxmLCBXTV9TWVNDT01NQU5ELCBTQ19DTE9TRSwgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUSFNDUk9MTDoKCVNlbmRNZXNzYWdlMTYoIHBXbmQtPmh3bmRTZWxmLCBXTV9TWVNDT01NQU5ELCBTQ19IU0NST0xMICsgSFRIU0NST0xMLAoJCSAgICAgICBsUGFyYW0gKTsKCWJyZWFrOwoKICAgIGNhc2UgSFRWU0NST0xMOgoJU2VuZE1lc3NhZ2UxNiggcFduZC0+aHduZFNlbGYsIFdNX1NZU0NPTU1BTkQsIFNDX1ZTQ1JPTEwgKyBIVFZTQ1JPTEwsCgkJICAgICAgIGxQYXJhbSApOwoJYnJlYWs7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfSGFuZGxlU3lzQ29tbWFuZAogKgogKiBIYW5kbGUgYSBXTV9TWVNDT01NQU5EIG1lc3NhZ2UuIENhbGxlZCBmcm9tIERlZldpbmRvd1Byb2MoKS4KICovCkxPTkcgTkNfSGFuZGxlU3lzQ29tbWFuZCggSFdORCBod25kLCBXUEFSQU0gd1BhcmFtLCBQT0lOVCBwdCApCnsKICAgIFdORCAqd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKICAgIFVJTlQxNiB1Q29tbWFuZCA9IHdQYXJhbSAmIDB4RkZGMDsKCiAgICBUUkFDRSgiSGFuZGxpbmcgV01fU1lTQ09NTUFORCAleCAlbGQsJWxkXG4iLCB3UGFyYW0sIHB0LngsIHB0LnkgKTsKCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfQ0hJTEQgJiYgdUNvbW1hbmQgIT0gU0NfS0VZTUVOVSApCiAgICAgICAgU2NyZWVuVG9DbGllbnQoIHduZFB0ci0+cGFyZW50LT5od25kU2VsZiwgJnB0ICk7CgogICAgc3dpdGNoICh1Q29tbWFuZCkKICAgIHsKICAgIGNhc2UgU0NfU0laRToKICAgIGNhc2UgU0NfTU9WRToKCU5DX0RvU2l6ZU1vdmUoIGh3bmQsIHdQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBTQ19NSU5JTUlaRToKICAgICAgICBpZiAoaHduZCA9PSBHZXRGb3JlZ3JvdW5kV2luZG93KCkpCiAgICAgICAgICAgIFNob3dPd25lZFBvcHVwcyhod25kLEZBTFNFKTsKCVNob3dXaW5kb3coIGh3bmQsIFNXX01JTklNSVpFICk7IAoJYnJlYWs7CgogICAgY2FzZSBTQ19NQVhJTUlaRToKICAgICAgICBpZiAoSXNJY29uaWMoaHduZCkgJiYgaHduZCA9PSBHZXRGb3JlZ3JvdW5kV2luZG93KCkpCiAgICAgICAgICAgIFNob3dPd25lZFBvcHVwcyhod25kLFRSVUUpOwoJU2hvd1dpbmRvdyggaHduZCwgU1dfTUFYSU1JWkUgKTsKCWJyZWFrOwoKICAgIGNhc2UgU0NfUkVTVE9SRToKICAgICAgICBpZiAoSXNJY29uaWMoaHduZCkgJiYgaHduZCA9PSBHZXRGb3JlZ3JvdW5kV2luZG93KCkpCiAgICAgICAgICAgIFNob3dPd25lZFBvcHVwcyhod25kLFRSVUUpOwoJU2hvd1dpbmRvdyggaHduZCwgU1dfUkVTVE9SRSApOwoJYnJlYWs7CgogICAgY2FzZSBTQ19DTE9TRToKICAgICAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwoJcmV0dXJuIFNlbmRNZXNzYWdlQSggaHduZCwgV01fQ0xPU0UsIDAsIDAgKTsKCiAgICBjYXNlIFNDX1ZTQ1JPTEw6CiAgICBjYXNlIFNDX0hTQ1JPTEw6CglOQ19UcmFja1Njcm9sbEJhciggaHduZCwgd1BhcmFtLCBwdCApOwoJYnJlYWs7CgogICAgY2FzZSBTQ19NT1VTRU1FTlU6CiAgICAgICAgTUVOVV9UcmFja01vdXNlTWVudUJhciggd25kUHRyLCB3UGFyYW0gJiAweDAwMEYsIHB0ICk7CglicmVhazsKCiAgICBjYXNlIFNDX0tFWU1FTlU6CglNRU5VX1RyYWNrS2JkTWVudUJhciggd25kUHRyICwgd1BhcmFtICwgcHQueCApOwoJYnJlYWs7CgkKICAgIGNhc2UgU0NfVEFTS0xJU1Q6CglXaW5FeGVjKCAidGFza21hbi5leGUiLCBTV19TSE9XTk9STUFMICk7IAoJYnJlYWs7CgogICAgY2FzZSBTQ19TQ1JFRU5TQVZFOgoJaWYgKHdQYXJhbSA9PSBTQ19BQk9VVFdJTkUpCiAgICAgICAgewogICAgICAgICAgICBITU9EVUxFIGhtb2R1bGUgPSBMb2FkTGlicmFyeUEoICJzaGVsbDMyLmRsbCIgKTsKICAgICAgICAgICAgaWYgKGhtb2R1bGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEZBUlBST0MgYWJvdXRwcm9jID0gR2V0UHJvY0FkZHJlc3MoIGhtb2R1bGUsICJTaGVsbEFib3V0QSIgKTsKICAgICAgICAgICAgICAgIGlmIChhYm91dHByb2MpIGFib3V0cHJvYyggaHduZCwgIldpbmUiLCBXSU5FX1JFTEVBU0VfSU5GTywgMCApOwogICAgICAgICAgICAgICAgRnJlZUxpYnJhcnkoIGhtb2R1bGUgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCWVsc2UgCgkgIGlmICh3UGFyYW0gPT0gU0NfUFVUTUFSSykKICAgICAgICAgICAgVFJBQ0VfKHNoZWxsKSgiTWFyayByZXF1ZXN0ZWQgYnkgdXNlclxuIik7CglicmVhazsKICAKICAgIGNhc2UgU0NfSE9US0VZOgogICAgY2FzZSBTQ19BUlJBTkdFOgogICAgY2FzZSBTQ19ORVhUV0lORE9XOgogICAgY2FzZSBTQ19QUkVWV0lORE9XOgogCUZJWE1FKCJ1bmltcGxlbWVudGVkIVxuIik7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogIE5DX0RyYXdHcmF5QnV0dG9uCioKKiBTdHViIGZvciB0aGUgZ3JheWVkIGJ1dHRvbiBvZiB0aGUgY2FwdGlvbgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpCT09MIE5DX0RyYXdHcmF5QnV0dG9uKEhEQyBoZGMsIGludCB4LCBpbnQgeSkKewogICAgSEJJVE1BUCBoTWFza0JtcDsKICAgIEhEQyBoZGNNYXNrID0gQ3JlYXRlQ29tcGF0aWJsZURDICgwKTsKICAgIEhCUlVTSCBoT2xkQnJ1c2g7CgogICAgaE1hc2tCbXAgPSBDcmVhdGVCaXRtYXAgKDEyLCAxMCwgMSwgMSwgbHBHcmF5TWFzayk7CiAgICAKICAgIGlmKGhNYXNrQm1wID09IDApCglyZXR1cm4gRkFMU0U7CiAgICAKICAgIFNlbGVjdE9iamVjdCAoaGRjTWFzaywgaE1hc2tCbXApOwogICAgCiAgICAvKiBEcmF3IHRoZSBncmF5ZWQgYml0bWFwIHVzaW5nIHRoZSBtYXNrICovCiAgICBoT2xkQnJ1c2ggPSBTZWxlY3RPYmplY3QgKGhkYywgUkdCKDEyOCwgMTI4LCAxMjgpKTsKICAgIEJpdEJsdCAoaGRjLCB4LCB5LCAxMiwgMTAsCgkgICAgaGRjTWFzaywgMCwgMCwgMHhCODA3NEEpOwogICAgCiAgICAvKiBDbGVhbiB1cCAqLwogICAgU2VsZWN0T2JqZWN0IChoZGMsIGhPbGRCcnVzaCk7CiAgICBEZWxldGVPYmplY3QoaE1hc2tCbXApOwogICAgRGVsZXRlREMgKGhkY01hc2spOwogICAgCiAgICByZXR1cm4gVFJVRTsKfQoKSElDT04xNiBOQ19JY29uRm9yV2luZG93KFdORCAqd25kUHRyKQp7CglISUNPTjE2IGhJY29uID0gKEhJQ09OKSBHZXRDbGFzc0xvbmdBKHduZFB0ci0+aHduZFNlbGYsIEdDTF9ISUNPTlNNKTsKCWlmKCFoSWNvbikgaEljb24gPSAoSElDT04pIEdldENsYXNzTG9uZ0Eod25kUHRyLT5od25kU2VsZiwgR0NMX0hJQ09OKTsKCgkvKiBJZiB0aGVyZSBpcyBubyBoSWNvbiBzcGVjaWZpZWQgYW5kIHRoaXMgaXMgYSBtb2RhbCBkaWFsb2csICovIAogICAgICAgIC8qIGdldCB0aGUgZGVmYXVsdCBvbmUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCWlmICghaEljb24gJiYgKHduZFB0ci0+ZHdTdHlsZSAmIERTX01PREFMRlJBTUUpKQoJCWhJY29uID0gTG9hZEltYWdlQSgwLCBNQUtFSU5UUkVTT1VSQ0VBKE9JQ19XSU5FSUNPTiksIElNQUdFX0lDT04sIDAsIDAsIExSX0RFRkFVTFRDT0xPUik7CgoJcmV0dXJuIGhJY29uOwp9Cg==