LyoKICogTm9uLWNsaWVudCBhcmVhIHdpbmRvdyBmdW5jdGlvbnMKICoKICogQ29weXJpZ2h0IDE5OTQgQWxleGFuZHJlIEp1bGxpYXJkCiAqCiAqLwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW5lL3dpbnVzZXIxNi5oIgojaW5jbHVkZSAidmVyc2lvbi5oIgojaW5jbHVkZSAid2luLmgiCiNpbmNsdWRlICJ1c2VyLmgiCiNpbmNsdWRlICJkY2UuaCIKI2luY2x1ZGUgImNvbnRyb2xzLmgiCiNpbmNsdWRlICJjdXJzb3JpY29uLmgiCiNpbmNsdWRlICJ3aW5wb3MuaCIKI2luY2x1ZGUgImhvb2suaCIKI2luY2x1ZGUgIm5vbmNsaWVudC5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgojaW5jbHVkZSAic2hlbGxhcGkuaCIKI2luY2x1ZGUgImJpdG1hcC5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKG5vbmNsaWVudCk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChzaGVsbCk7CgpCT09MIE5DX0RyYXdHcmF5QnV0dG9uKEhEQyBoZGMsIGludCB4LCBpbnQgeSk7CgpzdGF0aWMgSEJJVE1BUCBoYml0bWFwQ2xvc2U7CnN0YXRpYyBIQklUTUFQIGhiaXRtYXBNaW5pbWl6ZTsKc3RhdGljIEhCSVRNQVAgaGJpdG1hcE1pbmltaXplRDsKc3RhdGljIEhCSVRNQVAgaGJpdG1hcE1heGltaXplOwpzdGF0aWMgSEJJVE1BUCBoYml0bWFwTWF4aW1pemVEOwpzdGF0aWMgSEJJVE1BUCBoYml0bWFwUmVzdG9yZTsKc3RhdGljIEhCSVRNQVAgaGJpdG1hcFJlc3RvcmVEOwoKc3RhdGljIGNvbnN0IEJZVEUgbHBHcmF5TWFza1tdID0geyAweEFBLCAweEEwLAoJCSAgICAgIDB4NTUsIDB4NTAsICAKCQkgICAgICAweEFBLCAweEEwLAoJCSAgICAgIDB4NTUsIDB4NTAsICAKCQkgICAgICAweEFBLCAweEEwLAoJCSAgICAgIDB4NTUsIDB4NTAsICAKCQkgICAgICAweEFBLCAweEEwLAoJCSAgICAgIDB4NTUsIDB4NTAsICAKCQkgICAgICAweEFBLCAweEEwLAoJCSAgICAgIDB4NTUsIDB4NTB9OwoKI2RlZmluZSBTQ19BQk9VVFdJTkUgICAgCShTQ19TQ1JFRU5TQVZFKzEpCiNkZWZpbmUgU0NfUFVUTUFSSyAgICAgCQkoU0NfU0NSRUVOU0FWRSsyKQoKICAvKiBTb21lIHVzZWZ1bCBtYWNyb3MgKi8KI2RlZmluZSBIQVNfRExHRlJBTUUoc3R5bGUsZXhTdHlsZSkgXAogICAgKCgoZXhTdHlsZSkgJiBXU19FWF9ETEdNT0RBTEZSQU1FKSB8fCBcCiAgICAgKCgoc3R5bGUpICYgV1NfRExHRlJBTUUpICYmICEoKHN0eWxlKSAmIFdTX1RISUNLRlJBTUUpKSkKCiNkZWZpbmUgSEFTX1RISUNLRlJBTUUoc3R5bGUsZXhTdHlsZSkgXAogICAgKCgoc3R5bGUpICYgV1NfVEhJQ0tGUkFNRSkgJiYgXAogICAgICEoKChzdHlsZSkgJiAoV1NfRExHRlJBTUV8V1NfQk9SREVSKSkgPT0gV1NfRExHRlJBTUUpKQoKI2RlZmluZSBIQVNfVEhJTkZSQU1FKHN0eWxlKSBcCiAgICAoKChzdHlsZSkgJiBXU19CT1JERVIpIHx8ICEoKHN0eWxlKSAmIChXU19DSElMRCB8IFdTX1BPUFVQKSkpCgojZGVmaW5lIEhBU19CSUdGUkFNRShzdHlsZSxleFN0eWxlKSBcCiAgICAoKChzdHlsZSkgJiAoV1NfVEhJQ0tGUkFNRSB8IFdTX0RMR0ZSQU1FKSkgfHwgXAogICAgICgoZXhTdHlsZSkgJiBXU19FWF9ETEdNT0RBTEZSQU1FKSkKCiNkZWZpbmUgSEFTX1NUQVRJQ09VVEVSRlJBTUUoc3R5bGUsZXhTdHlsZSkgXAogICAgKCgoZXhTdHlsZSkgJiAoV1NfRVhfU1RBVElDRURHRXxXU19FWF9ETEdNT0RBTEZSQU1FKSkgPT0gXAogICAgIFdTX0VYX1NUQVRJQ0VER0UpCgojZGVmaW5lIEhBU19BTllGUkFNRShzdHlsZSxleFN0eWxlKSBcCiAgICAoKChzdHlsZSkgJiAoV1NfVEhJQ0tGUkFNRSB8IFdTX0RMR0ZSQU1FIHwgV1NfQk9SREVSKSkgfHwgXAogICAgICgoZXhTdHlsZSkgJiBXU19FWF9ETEdNT0RBTEZSQU1FKSB8fCBcCiAgICAgISgoc3R5bGUpICYgKFdTX0NISUxEIHwgV1NfUE9QVVApKSkKCiNkZWZpbmUgSEFTX01FTlUodykgICghKCh3KS0+ZHdTdHlsZSAmIFdTX0NISUxEKSAmJiAoKHcpLT53SURtZW51ICE9IDApKQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfQWRqdXN0UmVjdAogKgogKiBDb21wdXRlIHRoZSBzaXplIG9mIHRoZSB3aW5kb3cgcmVjdGFuZ2xlIGZyb20gdGhlIHNpemUgb2YgdGhlCiAqIGNsaWVudCByZWN0YW5nbGUuCiAqLwpzdGF0aWMgdm9pZCBOQ19BZGp1c3RSZWN0KCBMUFJFQ1QgcmVjdCwgRFdPUkQgc3R5bGUsIEJPT0wgbWVudSwgRFdPUkQgZXhTdHlsZSApCnsKICAgIGlmIChUV0VBS19XaW5lTG9vayA+IFdJTjMxX0xPT0spCglFUlIoIkNhbGxlZCBpbiBXaW45NSBtb2RlLiBBaWVlISBQbGVhc2UgcmVwb3J0IHRoaXMuXG4iICk7CgogICAgaWYoc3R5bGUgJiBXU19JQ09OSUMpIHJldHVybjsKCiAgICBpZiAoSEFTX1RISUNLRlJBTUUoIHN0eWxlLCBleFN0eWxlICkpCiAgICAgICAgSW5mbGF0ZVJlY3QoIHJlY3QsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSksIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lGUkFNRSkgKTsKICAgIGVsc2UgaWYgKEhBU19ETEdGUkFNRSggc3R5bGUsIGV4U3R5bGUgKSkKICAgICAgICBJbmZsYXRlUmVjdCggcmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWERMR0ZSQU1FKSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWURMR0ZSQU1FKSApOwogICAgZWxzZSBpZiAoSEFTX1RISU5GUkFNRSggc3R5bGUgKSkKICAgICAgICBJbmZsYXRlUmVjdCggcmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWEJPUkRFUiksIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpKTsKCiAgICBpZiAoKHN0eWxlICYgV1NfQ0FQVElPTikgPT0gV1NfQ0FQVElPTikKICAgICAgICByZWN0LT50b3AgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUik7CgogICAgaWYgKG1lbnUpIHJlY3QtPnRvcCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZTUVOVSkgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKTsKCiAgICBpZiAoc3R5bGUgJiBXU19WU0NST0xMKSB7CiAgICAgIHJlY3QtPnJpZ2h0ICArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCkgLSAxOwogICAgICBpZighSEFTX0FOWUZSQU1FKCBzdHlsZSwgZXhTdHlsZSApKQoJIHJlY3QtPnJpZ2h0Kys7CiAgICB9CgogICAgaWYgKHN0eWxlICYgV1NfSFNDUk9MTCkgewogICAgICByZWN0LT5ib3R0b20gKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpIC0gMTsKICAgICAgaWYoIUhBU19BTllGUkFNRSggc3R5bGUsIGV4U3R5bGUgKSkKCSByZWN0LT5ib3R0b20rKzsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTkNfQWRqdXN0UmVjdE91dGVyOTUKICoKICogQ29tcHV0ZXMgdGhlIHNpemUgb2YgdGhlICJvdXRzaWRlIiBwYXJ0cyBvZiB0aGUgd2luZG93IGJhc2VkIG9uIHRoZQogKiBwYXJhbWV0ZXJzIG9mIHRoZSBjbGllbnQgYXJlYS4KICoKICsgUEFSQU1TCiAqICAgICBMUFJFQ1QxNiAgcmVjdAogKiAgICAgRFdPUkQgIHN0eWxlCiAqICAgICBCT09MICBtZW51CiAqICAgICBEV09SRCAgZXhTdHlsZQogKgogKiBOT1RFUwogKiAgICAgIk91dGVyIiBwYXJ0cyBvZiBhIHdpbmRvdyBtZWFucyB0aGUgd2hvbGUgd2luZG93IGZyYW1lLCBjYXB0aW9uIGFuZAogKiAgICAgbWVudSBiYXIuIEl0IGRvZXMgbm90IGluY2x1ZGUgImlubmVyIiBwYXJ0cyBvZiB0aGUgZnJhbWUgbGlrZSBjbGllbnQKICogICAgIGVkZ2UsIHN0YXRpYyBlZGdlIG9yIHNjcm9sbCBiYXJzLgogKgogKiBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAwNS1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgIE9yaWdpbmFsIChOQ19BZGp1c3RSZWN0OTUpIGN1dCAmIHBhc3RlIGZyb20gTkNfQWRqdXN0UmVjdAogKgogKiAgICAgMjAtSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgIFNwbGl0IE5DX0FkanVzdFJlY3Q5NSBpbnRvIE5DX0FkanVzdFJlY3RPdXRlcjk1IGFuZAogKiAgICAgICAgTkNfQWRqdXN0UmVjdElubmVyOTUgYW5kIGFkZGVkIGhhbmRsaW5nIG9mIFdpbjk1IHN0eWxlcy4KICoKICogICAgIDI4LUp1bC0xOTk5IE92ZSBL5XZlbiAob3Zla0BhcmN0aWNuZXQubm8pCiAqICAgICAgICBTdHJlYW1saW5lZCB3aW5kb3cgc3R5bGUgY2hlY2tzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZApOQ19BZGp1c3RSZWN0T3V0ZXI5NSAoTFBSRUNUIHJlY3QsIERXT1JEIHN0eWxlLCBCT09MIG1lbnUsIERXT1JEIGV4U3R5bGUpCnsKICAgIGludCBhZGp1c3Q7CiAgICBpZihzdHlsZSAmIFdTX0lDT05JQykgcmV0dXJuOwoKICAgIGlmICgoZXhTdHlsZSAmIChXU19FWF9TVEFUSUNFREdFfFdTX0VYX0RMR01PREFMRlJBTUUpKSA9PSAKICAgICAgICBXU19FWF9TVEFUSUNFREdFKQogICAgewogICAgICAgIGFkanVzdCA9IDE7IC8qIGZvciB0aGUgb3V0ZXIgZnJhbWUgYWx3YXlzIHByZXNlbnQgKi8KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBhZGp1c3QgPSAwOwogICAgICAgIGlmICgoZXhTdHlsZSAmIFdTX0VYX0RMR01PREFMRlJBTUUpIHx8CiAgICAgICAgICAgIChzdHlsZSAmIChXU19USElDS0ZSQU1FfFdTX0RMR0ZSQU1FKSkpIGFkanVzdCA9IDI7IC8qIG91dGVyICovCiAgICB9CiAgICBpZiAoc3R5bGUgJiBXU19USElDS0ZSQU1FKQogICAgICAgIGFkanVzdCArPSAgKCBHZXRTeXN0ZW1NZXRyaWNzIChTTV9DWEZSQU1FKQogICAgICAgICAgICAgICAgICAgLSBHZXRTeXN0ZW1NZXRyaWNzIChTTV9DWERMR0ZSQU1FKSk7IC8qIFRoZSByZXNpemUgYm9yZGVyICovCiAgICBpZiAoKHN0eWxlICYgKFdTX0JPUkRFUnxXU19ETEdGUkFNRSkpIHx8IAogICAgICAgIChleFN0eWxlICYgV1NfRVhfRExHTU9EQUxGUkFNRSkpCiAgICAgICAgYWRqdXN0Kys7IC8qIFRoZSBvdGhlciBib3JkZXIgKi8KCiAgICBJbmZsYXRlUmVjdCAocmVjdCwgYWRqdXN0LCBhZGp1c3QpOwoKICAgIGlmICgoc3R5bGUgJiBXU19DQVBUSU9OKSA9PSBXU19DQVBUSU9OKQogICAgewogICAgICAgIGlmIChleFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykKICAgICAgICAgICAgcmVjdC0+dG9wIC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUNBUFRJT04pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmVjdC0+dG9wIC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKTsKICAgIH0KICAgIGlmIChtZW51KSByZWN0LT50b3AgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWU1FTlUpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBOQ19BZGp1c3RSZWN0SW5uZXI5NQogKgogKiBDb21wdXRlcyB0aGUgc2l6ZSBvZiB0aGUgImluc2lkZSIgcGFydCBvZiB0aGUgd2luZG93IGJhc2VkIG9uIHRoZQogKiBwYXJhbWV0ZXJzIG9mIHRoZSBjbGllbnQgYXJlYS4KICoKICsgUEFSQU1TCiAqICAgICBMUFJFQ1QxNiByZWN0CiAqICAgICBEV09SRCAgICBzdHlsZQogKiAgICAgRFdPUkQgICAgZXhTdHlsZQogKgogKiBOT1RFUwogKiAgICAgIklubmVyIiBwYXJ0IG9mIGEgd2luZG93IG1lYW5zIHRoZSB3aW5kb3cgZnJhbWUgaW5zaWRlIG9mIHRoZSBmbGF0CiAqICAgICB3aW5kb3cgZnJhbWUuIEl0IGluY2x1ZGVzIHRoZSBjbGllbnQgZWRnZSwgdGhlIHN0YXRpYyBlZGdlIGFuZCB0aGUKICogICAgIHNjcm9sbCBiYXJzLgogKgogKiBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAwNS1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgIE9yaWdpbmFsIChOQ19BZGp1c3RSZWN0OTUpIGN1dCAmIHBhc3RlIGZyb20gTkNfQWRqdXN0UmVjdAogKgogKiAgICAgMjAtSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgIFNwbGl0IE5DX0FkanVzdFJlY3Q5NSBpbnRvIE5DX0FkanVzdFJlY3RPdXRlcjk1IGFuZAogKiAgICAgICAgTkNfQWRqdXN0UmVjdElubmVyOTUgYW5kIGFkZGVkIGhhbmRsaW5nIG9mIFdpbjk1IHN0eWxlcy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHZvaWQKTkNfQWRqdXN0UmVjdElubmVyOTUgKExQUkVDVCByZWN0LCBEV09SRCBzdHlsZSwgRFdPUkQgZXhTdHlsZSkKewogICAgaWYoc3R5bGUgJiBXU19JQ09OSUMpIHJldHVybjsKCiAgICBpZiAoZXhTdHlsZSAmIFdTX0VYX0NMSUVOVEVER0UpCiAgICAgICAgSW5mbGF0ZVJlY3QocmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWEVER0UpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSkpOwoKICAgIGlmIChzdHlsZSAmIFdTX1ZTQ1JPTEwpIHJlY3QtPnJpZ2h0ICArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCk7CiAgICBpZiAoc3R5bGUgJiBXU19IU0NST0xMKSByZWN0LT5ib3R0b20gKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpOwp9CgoKCnN0YXRpYyBISUNPTiBOQ19JY29uRm9yV2luZG93KCBIV05EIGh3bmQgKQp7CiAgICBISUNPTiBoSWNvbiA9IChISUNPTikgR2V0Q2xhc3NMb25nQSggaHduZCwgR0NMX0hJQ09OU00gKTsKICAgIGlmICghaEljb24pIGhJY29uID0gKEhJQ09OKSBHZXRDbGFzc0xvbmdBKCBod25kLCBHQ0xfSElDT04gKTsKCiAgICAvKiBJZiB0aGVyZSBpcyBubyBoSWNvbiBzcGVjaWZpZWQgYW5kIHRoaXMgaXMgYSBtb2RhbCBkaWFsb2csCiAgICAgKiBnZXQgdGhlIGRlZmF1bHQgb25lLgogICAgICovCiAgICBpZiAoIWhJY29uICYmIChHZXRXaW5kb3dMb25nQSggaHduZCwgR1dMX1NUWUxFICkgJiBEU19NT0RBTEZSQU1FKSkKICAgICAgICBoSWNvbiA9IExvYWRJbWFnZUEoMCwgSURJX1dJTkxPR09BLCBJTUFHRV9JQ09OLCAwLCAwLCBMUl9ERUZBVUxUQ09MT1IpOwogICAgcmV0dXJuIGhJY29uOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURyYXdDYXB0aW9uIChVU0VSMzIuQCkgRHJhd3MgYSBjYXB0aW9uIGJhcgogKgogKiBQQVJBTVMKICogICAgIGh3bmQgICBbSV0KICogICAgIGhkYyAgICBbSV0KICogICAgIGxwUmVjdCBbSV0KICogICAgIHVGbGFncyBbSV0KICoKICogUkVUVVJOUwogKiAgICAgU3VjY2VzczoKICogICAgIEZhaWx1cmU6CiAqLwoKQk9PTCBXSU5BUEkKRHJhd0NhcHRpb24gKEhXTkQgaHduZCwgSERDIGhkYywgY29uc3QgUkVDVCAqbHBSZWN0LCBVSU5UIHVGbGFncykKewogICAgcmV0dXJuIERyYXdDYXB0aW9uVGVtcEEgKGh3bmQsIGhkYywgbHBSZWN0LCAwLCAwLCBOVUxMLCB1RmxhZ3MgJiAweDFGKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRHJhd0NhcHRpb25UZW1wQSAoVVNFUjMyLkApCiAqLwpCT09MIFdJTkFQSSBEcmF3Q2FwdGlvblRlbXBBIChIV05EIGh3bmQsIEhEQyBoZGMsIGNvbnN0IFJFQ1QgKnJlY3QsIEhGT05UIGhGb250LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBISUNPTiBoSWNvbiwgTFBDU1RSIHN0ciwgVUlOVCB1RmxhZ3MpCnsKICAgIExQV1NUUiBzdHJXOwogICAgSU5UIGxlbjsKICAgIEJPT0wgcmV0ID0gRkFMU0U7CgogICAgaWYgKCEodUZsYWdzICYgRENfVEVYVCkgfHwgIXN0cikKICAgICAgICByZXR1cm4gRHJhd0NhcHRpb25UZW1wVyggaHduZCwgaGRjLCByZWN0LCBoRm9udCwgaEljb24sIE5VTEwsIHVGbGFncyApOwoKICAgIGxlbiA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoIENQX0FDUCwgMCwgc3RyLCAtMSwgTlVMTCwgMCApOwogICAgaWYgKChzdHJXID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4gKiBzaXplb2YoV0NIQVIpICkpKQogICAgewogICAgICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoIENQX0FDUCwgMCwgc3RyLCAtMSwgc3RyVywgbGVuICk7CiAgICAgICAgcmV0ID0gRHJhd0NhcHRpb25UZW1wVyAoaHduZCwgaGRjLCByZWN0LCBoRm9udCwgaEljb24sIHN0clcsIHVGbGFncyk7CiAgICAgICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwICgpLCAwLCBzdHJXICk7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlEcmF3Q2FwdGlvblRlbXBXIChVU0VSMzIuQCkKICovCkJPT0wgV0lOQVBJIERyYXdDYXB0aW9uVGVtcFcgKEhXTkQgaHduZCwgSERDIGhkYywgY29uc3QgUkVDVCAqcmVjdCwgSEZPTlQgaEZvbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhJQ09OIGhJY29uLCBMUENXU1RSIHN0ciwgVUlOVCB1RmxhZ3MpCnsKICAgIFJFQ1QgICByYyA9ICpyZWN0OwoKICAgIFRSQUNFKCIoJTA4eCwlMDh4LCVwLCUwOHgsJTA4eCwlcywlMDh4KVxuIiwKICAgICAgICAgIGh3bmQsIGhkYywgcmVjdCwgaEZvbnQsIGhJY29uLCBkZWJ1Z3N0cl93KHN0ciksIHVGbGFncyk7CgogICAgLyogZHJhd2luZyBiYWNrZ3JvdW5kICovCiAgICBpZiAodUZsYWdzICYgRENfSU5CVVRUT04pIHsKCUZpbGxSZWN0IChoZGMsICZyYywgR2V0U3lzQ29sb3JCcnVzaCAoQ09MT1JfM0RGQUNFKSk7CgoJaWYgKHVGbGFncyAmIERDX0FDVElWRSkgewoJICAgIEhCUlVTSCBoYnIgPSBTZWxlY3RPYmplY3QgKGhkYywgQ0FDSEVfR2V0UGF0dGVybjU1QUFCcnVzaCAoKSk7CgkgICAgUGF0Qmx0IChoZGMsIHJjLmxlZnQsIHJjLnRvcCwKCQkgICAgICByYy5yaWdodC1yYy5sZWZ0LCByYy5ib3R0b20tcmMudG9wLCAweEZBMDA4OSk7CgkgICAgU2VsZWN0T2JqZWN0IChoZGMsIGhicik7Cgl9CiAgICB9CiAgICBlbHNlIHsKCUZpbGxSZWN0IChoZGMsICZyYywgR2V0U3lzQ29sb3JCcnVzaCAoKHVGbGFncyAmIERDX0FDVElWRSkgPwoJCSAgICBDT0xPUl9BQ1RJVkVDQVBUSU9OIDogQ09MT1JfSU5BQ1RJVkVDQVBUSU9OKSk7CiAgICB9CgoKICAgIC8qIGRyYXdpbmcgaWNvbiAqLwogICAgaWYgKCh1RmxhZ3MgJiBEQ19JQ09OKSAmJiAhKHVGbGFncyAmIERDX1NNQUxMQ0FQKSkgewoJUE9JTlQgcHQ7CgoJcHQueCA9IHJjLmxlZnQgKyAyOwoJcHQueSA9IChyYy5ib3R0b20gKyByYy50b3AgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01JQ09OKSkgLyAyOwoKICAgICAgICBpZiAoIWhJY29uKSBoSWNvbiA9IE5DX0ljb25Gb3JXaW5kb3coaHduZCk7CiAgICAgICAgRHJhd0ljb25FeCAoaGRjLCBwdC54LCBwdC55LCBoSWNvbiwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNNSUNPTiksCiAgICAgICAgICAgICAgICAgICAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNSUNPTiksIDAsIDAsIERJX05PUk1BTCk7CglyYy5sZWZ0ICs9IChyYy5ib3R0b20gLSByYy50b3ApOwogICAgfQoKICAgIC8qIGRyYXdpbmcgdGV4dCAqLwogICAgaWYgKHVGbGFncyAmIERDX1RFWFQpIHsKCUhGT05UIGhPbGRGb250OwoKCWlmICh1RmxhZ3MgJiBEQ19JTkJVVFRPTikKCSAgICBTZXRUZXh0Q29sb3IgKGhkYywgR2V0U3lzQ29sb3IgKENPTE9SX0JUTlRFWFQpKTsKCWVsc2UgaWYgKHVGbGFncyAmIERDX0FDVElWRSkKCSAgICBTZXRUZXh0Q29sb3IgKGhkYywgR2V0U3lzQ29sb3IgKENPTE9SX0NBUFRJT05URVhUKSk7CgllbHNlCgkgICAgU2V0VGV4dENvbG9yIChoZGMsIEdldFN5c0NvbG9yIChDT0xPUl9JTkFDVElWRUNBUFRJT05URVhUKSk7CgoJU2V0QmtNb2RlIChoZGMsIFRSQU5TUEFSRU5UKTsKCglpZiAoaEZvbnQpCgkgICAgaE9sZEZvbnQgPSBTZWxlY3RPYmplY3QgKGhkYywgaEZvbnQpOwoJZWxzZSB7CgkgICAgTk9OQ0xJRU5UTUVUUklDU0EgbmNsbTsKCSAgICBIRk9OVCBoTmV3Rm9udDsKCSAgICBuY2xtLmNiU2l6ZSA9IHNpemVvZihOT05DTElFTlRNRVRSSUNTQSk7CgkgICAgU3lzdGVtUGFyYW1ldGVyc0luZm9BIChTUElfR0VUTk9OQ0xJRU5UTUVUUklDUywgMCwgJm5jbG0sIDApOwoJICAgIGhOZXdGb250ID0gQ3JlYXRlRm9udEluZGlyZWN0QSAoKHVGbGFncyAmIERDX1NNQUxMQ0FQKSA/CgkJJm5jbG0ubGZTbUNhcHRpb25Gb250IDogJm5jbG0ubGZDYXB0aW9uRm9udCk7CgkgICAgaE9sZEZvbnQgPSBTZWxlY3RPYmplY3QgKGhkYywgaE5ld0ZvbnQpOwoJfQoKCWlmIChzdHIpCgkgICAgRHJhd1RleHRXIChoZGMsIHN0ciwgLTEsICZyYywKCQkJIERUX1NJTkdMRUxJTkUgfCBEVF9WQ0VOVEVSIHwgRFRfTk9QUkVGSVggfCBEVF9MRUZUKTsKCWVsc2UgewoJICAgIFdDSEFSIHN6VGV4dFsxMjhdOwoJICAgIElOVCBuTGVuOwoJICAgIG5MZW4gPSBHZXRXaW5kb3dUZXh0VyAoaHduZCwgc3pUZXh0LCAxMjgpOwoJICAgIERyYXdUZXh0VyAoaGRjLCBzelRleHQsIG5MZW4sICZyYywKCQkJIERUX1NJTkdMRUxJTkUgfCBEVF9WQ0VOVEVSIHwgRFRfTk9QUkVGSVggfCBEVF9MRUZUKTsKCX0KCglpZiAoaEZvbnQpCgkgICAgU2VsZWN0T2JqZWN0IChoZGMsIGhPbGRGb250KTsKCWVsc2UKCSAgICBEZWxldGVPYmplY3QgKFNlbGVjdE9iamVjdCAoaGRjLCBoT2xkRm9udCkpOwogICAgfQoKICAgIC8qIGRyYXdpbmcgZm9jdXMgPz8/ICovCiAgICBpZiAodUZsYWdzICYgMHgyMDAwKQoJRklYTUUoInVuZG9jdW1lbnRlZCBmbGFnICgweDIwMDApIVxuIik7CgogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFkanVzdFdpbmRvd1JlY3QgKFVTRVIuMTAyKQogKi8KQk9PTDE2IFdJTkFQSSBBZGp1c3RXaW5kb3dSZWN0MTYoIExQUkVDVDE2IHJlY3QsIERXT1JEIHN0eWxlLCBCT09MMTYgbWVudSApCnsKICAgIHJldHVybiBBZGp1c3RXaW5kb3dSZWN0RXgxNiggcmVjdCwgc3R5bGUsIG1lbnUsIDAgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQWRqdXN0V2luZG93UmVjdCAoVVNFUjMyLkApCiAqLwpCT09MIFdJTkFQSSBBZGp1c3RXaW5kb3dSZWN0KCBMUFJFQ1QgcmVjdCwgRFdPUkQgc3R5bGUsIEJPT0wgbWVudSApCnsKICAgIHJldHVybiBBZGp1c3RXaW5kb3dSZWN0RXgoIHJlY3QsIHN0eWxlLCBtZW51LCAwICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFkanVzdFdpbmRvd1JlY3RFeCAoVVNFUi40NTQpCiAqLwpCT09MMTYgV0lOQVBJIEFkanVzdFdpbmRvd1JlY3RFeDE2KCBMUFJFQ1QxNiByZWN0LCBEV09SRCBzdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTDE2IG1lbnUsIERXT1JEIGV4U3R5bGUgKQp7CiAgICBSRUNUIHJlY3QzMjsKICAgIEJPT0wgcmV0OwoKICAgIENPTlZfUkVDVDE2VE8zMiggcmVjdCwgJnJlY3QzMiApOwogICAgcmV0ID0gQWRqdXN0V2luZG93UmVjdEV4KCAmcmVjdDMyLCBzdHlsZSwgbWVudSwgZXhTdHlsZSApOwogICAgQ09OVl9SRUNUMzJUTzE2KCAmcmVjdDMyLCByZWN0ICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBZGp1c3RXaW5kb3dSZWN0RXggKFVTRVIzMi5AKQogKi8KQk9PTCBXSU5BUEkgQWRqdXN0V2luZG93UmVjdEV4KCBMUFJFQ1QgcmVjdCwgRFdPUkQgc3R5bGUsIEJPT0wgbWVudSwgRFdPUkQgZXhTdHlsZSApCnsKICAgIC8qIENvcnJlY3QgdGhlIHdpbmRvdyBzdHlsZSAqLwoKICAgIGlmICghKHN0eWxlICYgKFdTX1BPUFVQIHwgV1NfQ0hJTEQpKSkgc3R5bGUgfD0gV1NfQ0FQVElPTjsgLyogT3ZlcmxhcHBlZCB3aW5kb3cgKi8KICAgIHN0eWxlICY9IChXU19ETEdGUkFNRSB8IFdTX0JPUkRFUiB8IFdTX1RISUNLRlJBTUUgfCBXU19DSElMRCk7CiAgICBleFN0eWxlICY9IChXU19FWF9ETEdNT0RBTEZSQU1FIHwgV1NfRVhfQ0xJRU5URURHRSB8CiAgICAgICAgICAgICAgICBXU19FWF9TVEFUSUNFREdFIHwgV1NfRVhfVE9PTFdJTkRPVyk7CiAgICBpZiAoZXhTdHlsZSAmIFdTX0VYX0RMR01PREFMRlJBTUUpIHN0eWxlICY9IH5XU19USElDS0ZSQU1FOwoKICAgIFRSQUNFKCIoJWQsJWQpLSglZCwlZCkgJTA4bHggJWQgJTA4bHhcbiIsCiAgICAgICAgICByZWN0LT5sZWZ0LCByZWN0LT50b3AsIHJlY3QtPnJpZ2h0LCByZWN0LT5ib3R0b20sCiAgICAgICAgICBzdHlsZSwgbWVudSwgZXhTdHlsZSApOwoKICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQogICAgICAgIE5DX0FkanVzdFJlY3QoIHJlY3QsIHN0eWxlLCBtZW51LCBleFN0eWxlICk7CiAgICBlbHNlCiAgICB7CiAgICAgICAgTkNfQWRqdXN0UmVjdE91dGVyOTUoIHJlY3QsIHN0eWxlLCBtZW51LCBleFN0eWxlICk7CiAgICAgICAgTkNfQWRqdXN0UmVjdElubmVyOTUoIHJlY3QsIHN0eWxlLCBleFN0eWxlICk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfSGFuZGxlTkNDYWxjU2l6ZQogKgogKiBIYW5kbGUgYSBXTV9OQ0NBTENTSVpFIG1lc3NhZ2UuIENhbGxlZCBmcm9tIERlZldpbmRvd1Byb2MoKS4KICovCkxPTkcgTkNfSGFuZGxlTkNDYWxjU2l6ZSggSFdORCBod25kLCBSRUNUICp3aW5SZWN0ICkKewogICAgUkVDVCB0bXBSZWN0ID0geyAwLCAwLCAwLCAwIH07CiAgICBMT05HIHJlc3VsdCA9IDA7CiAgICBMT05HIGNsc19zdHlsZSA9IEdldENsYXNzTG9uZ0EoaHduZCwgR0NMX1NUWUxFKTsKICAgIExPTkcgc3R5bGUgPSBHZXRXaW5kb3dMb25nQSggaHduZCwgR1dMX1NUWUxFICk7CiAgICBMT05HIGV4U3R5bGUgPSBHZXRXaW5kb3dMb25nQSggaHduZCwgR1dMX0VYU1RZTEUgKTsKCiAgICBpZiAoY2xzX3N0eWxlICYgQ1NfVlJFRFJBVykgcmVzdWx0IHw9IFdWUl9WUkVEUkFXOwogICAgaWYgKGNsc19zdHlsZSAmIENTX0hSRURSQVcpIHJlc3VsdCB8PSBXVlJfSFJFRFJBVzsKCiAgICBpZiAoIUlzSWNvbmljKGh3bmQpKQogICAgewoJaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCgkgICAgTkNfQWRqdXN0UmVjdCggJnRtcFJlY3QsIHN0eWxlLCBGQUxTRSwgZXhTdHlsZSApOwoJZWxzZQoJICAgIE5DX0FkanVzdFJlY3RPdXRlcjk1KCAmdG1wUmVjdCwgc3R5bGUsIEZBTFNFLCBleFN0eWxlICk7CgoJd2luUmVjdC0+bGVmdCAgIC09IHRtcFJlY3QubGVmdDsKCXdpblJlY3QtPnRvcCAgICAtPSB0bXBSZWN0LnRvcDsKCXdpblJlY3QtPnJpZ2h0ICAtPSB0bXBSZWN0LnJpZ2h0OwoJd2luUmVjdC0+Ym90dG9tIC09IHRtcFJlY3QuYm90dG9tOwoKICAgICAgICBpZiAoIShzdHlsZSAmIFdTX0NISUxEKSAmJiBHZXRNZW51KGh3bmQpKQogICAgICAgIHsKCSAgICBUUkFDRSgiQ2FsbGluZyBHZXRNZW51QmFySGVpZ2h0IHdpdGggSFdORCAweCV4LCB3aWR0aCAlZCwgIgogICAgICAgICAgICAgICAgICAiYXQgKCVkLCAlZCkuXG4iLCBod25kLAogICAgICAgICAgICAgICAgICB3aW5SZWN0LT5yaWdodCAtIHdpblJlY3QtPmxlZnQsCiAgICAgICAgICAgICAgICAgIC10bXBSZWN0LmxlZnQsIC10bXBSZWN0LnRvcCApOwoKCSAgICB3aW5SZWN0LT50b3AgKz0KCQlNRU5VX0dldE1lbnVCYXJIZWlnaHQoIGh3bmQsCgkJCQkgICAgICAgd2luUmVjdC0+cmlnaHQgLSB3aW5SZWN0LT5sZWZ0LAoJCQkJICAgICAgIC10bXBSZWN0LmxlZnQsIC10bXBSZWN0LnRvcCApICsgMTsKCX0KCglpZiAoVFdFQUtfV2luZUxvb2sgPiBXSU4zMV9MT09LKSB7CgkgICAgU2V0UmVjdCgmdG1wUmVjdCwgMCwgMCwgMCwgMCk7CgkgICAgTkNfQWRqdXN0UmVjdElubmVyOTUgKCZ0bXBSZWN0LCBzdHlsZSwgZXhTdHlsZSk7CgkgICAgd2luUmVjdC0+bGVmdCAgIC09IHRtcFJlY3QubGVmdDsKCSAgICB3aW5SZWN0LT50b3AgICAgLT0gdG1wUmVjdC50b3A7CgkgICAgd2luUmVjdC0+cmlnaHQgIC09IHRtcFJlY3QucmlnaHQ7CgkgICAgd2luUmVjdC0+Ym90dG9tIC09IHRtcFJlY3QuYm90dG9tOwoJfQoKICAgICAgICBpZiAod2luUmVjdC0+dG9wID4gd2luUmVjdC0+Ym90dG9tKQogICAgICAgICAgICB3aW5SZWN0LT5ib3R0b20gPSB3aW5SZWN0LT50b3A7CgogICAgICAgIGlmICh3aW5SZWN0LT5sZWZ0ID4gd2luUmVjdC0+cmlnaHQpCiAgICAgICAgICAgIHdpblJlY3QtPnJpZ2h0ID0gd2luUmVjdC0+bGVmdDsKICAgIH0KICAgIHJldHVybiByZXN1bHQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0dldEluc2lkZVJlY3QKICoKICogR2V0IHRoZSAnaW5zaWRlJyByZWN0YW5nbGUgb2YgYSB3aW5kb3csIGkuZS4gdGhlIHdob2xlIHdpbmRvdyByZWN0YW5nbGUKICogYnV0IHdpdGhvdXQgdGhlIGJvcmRlcnMgKGlmIGFueSkuCiAqIFRoZSByZWN0YW5nbGUgaXMgaW4gd2luZG93IGNvb3JkaW5hdGVzIChmb3IgZHJhd2luZyB3aXRoIEdldFdpbmRvd0RDKCkpLgogKi8Kdm9pZCBOQ19HZXRJbnNpZGVSZWN0KCBIV05EIGh3bmQsIFJFQ1QgKnJlY3QgKQp7CiAgICBXTkQgKiB3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwoKICAgIHJlY3QtPnRvcCAgICA9IHJlY3QtPmxlZnQgPSAwOwogICAgcmVjdC0+cmlnaHQgID0gd25kUHRyLT5yZWN0V2luZG93LnJpZ2h0IC0gd25kUHRyLT5yZWN0V2luZG93LmxlZnQ7CiAgICByZWN0LT5ib3R0b20gPSB3bmRQdHItPnJlY3RXaW5kb3cuYm90dG9tIC0gd25kUHRyLT5yZWN0V2luZG93LnRvcDsKCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfSUNPTklDKSBnb3RvIEVORDsKCiAgICAvKiBSZW1vdmUgZnJhbWUgZnJvbSByZWN0YW5nbGUgKi8KICAgIGlmIChIQVNfVEhJQ0tGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKQogICAgewogICAgICAgIEluZmxhdGVSZWN0KCByZWN0LCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWEZSQU1FKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lGUkFNRSkgKTsKICAgIH0KICAgIGVsc2UgaWYgKEhBU19ETEdGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKQogICAgewogICAgICAgIEluZmxhdGVSZWN0KCByZWN0LCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWERMR0ZSQU1FKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lETEdGUkFNRSkpOwogICAgICAgIC8qIEZJWE1FOiB0aGlzIGlzbid0IGluIE5DX0FkanVzdFJlY3Q/IHdoeSBub3Q/ICovCiAgICAgICAgaWYgKChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKSAmJiAod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9ETEdNT0RBTEZSQU1FKSkKICAgICAgICAgICAgSW5mbGF0ZVJlY3QoIHJlY3QsIC0xLCAwICk7CiAgICB9CiAgICBlbHNlIGlmIChIQVNfVEhJTkZSQU1FKCB3bmRQdHItPmR3U3R5bGUgKSkKICAgIHsKICAgICAgICBJbmZsYXRlUmVjdCggcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikgKTsKICAgIH0KCiAgICAvKiBXZSBoYXZlIGFkZGl0aW9uYWwgYm9yZGVyIGluZm9ybWF0aW9uIGlmIHRoZSB3aW5kb3cKICAgICAqIGlzIGEgY2hpbGQgKGJ1dCBub3QgYW4gTURJIGNoaWxkKSAqLwogICAgaWYgKFRXRUFLX1dpbmVMb29rICE9IFdJTjMxX0xPT0spCiAgICB7CiAgICAgICAgaWYgKCAod25kUHRyLT5kd1N0eWxlICYgV1NfQ0hJTEQpICAmJgogICAgICAgICAgICAgKCAod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9NRElDSElMRCkgPT0gMCApICkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX0NMSUVOVEVER0UpCiAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCAocmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hFREdFKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lFREdFKSk7CiAgICAgICAgICAgIGlmICh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX1NUQVRJQ0VER0UpCiAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCAocmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikpOwogICAgICAgIH0KICAgIH0KCkVORDoKICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7CiAgICByZXR1cm47Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTkNfRG9OQ0hpdFRlc3QKICoKICogSGFuZGxlIGEgV01fTkNISVRURVNUIG1lc3NhZ2UuIENhbGxlZCBmcm9tIE5DX0hhbmRsZU5DSGl0VGVzdCgpLgogKi8KCnN0YXRpYyBMT05HIE5DX0RvTkNIaXRUZXN0IChXTkQgKnduZFB0ciwgUE9JTlQgcHQgKQp7CiAgICBSRUNUIHJlY3Q7CgogICAgVFJBQ0UoImh3bmQ9JTA0eCBwdD0lbGQsJWxkXG4iLCB3bmRQdHItPmh3bmRTZWxmLCBwdC54LCBwdC55ICk7CgogICAgR2V0V2luZG93UmVjdCh3bmRQdHItPmh3bmRTZWxmLCAmcmVjdCApOwogICAgaWYgKCFQdEluUmVjdCggJnJlY3QsIHB0ICkpIHJldHVybiBIVE5PV0hFUkU7CgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFKSByZXR1cm4gSFRDQVBUSU9OOwoKICAgIC8qIENoZWNrIGJvcmRlcnMgKi8KICAgIGlmIChIQVNfVEhJQ0tGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKQogICAgewogICAgICAgIEluZmxhdGVSZWN0KCAmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpICk7CiAgICAgICAgaWYgKCFQdEluUmVjdCggJnJlY3QsIHB0ICkpCiAgICAgICAgewogICAgICAgICAgICAvKiBDaGVjayB0b3Agc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICBpZiAocHQueSA8IHJlY3QudG9wKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVFRPUExFRlQ7CiAgICAgICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0LUdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSkgcmV0dXJuIEhUVE9QUklHSFQ7CiAgICAgICAgICAgICAgICByZXR1cm4gSFRUT1A7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogQ2hlY2sgYm90dG9tIHNpemluZyBib3JkZXIgKi8KICAgICAgICAgICAgaWYgKHB0LnkgPj0gcmVjdC5ib3R0b20pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwdC54IDwgcmVjdC5sZWZ0K0dldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSkgcmV0dXJuIEhUQk9UVE9NTEVGVDsKICAgICAgICAgICAgICAgIGlmIChwdC54ID49IHJlY3QucmlnaHQtR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpKSByZXR1cm4gSFRCT1RUT01SSUdIVDsKICAgICAgICAgICAgICAgIHJldHVybiBIVEJPVFRPTTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBDaGVjayBsZWZ0IHNpemluZyBib3JkZXIgKi8KICAgICAgICAgICAgaWYgKHB0LnggPCByZWN0LmxlZnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwdC55IDwgcmVjdC50b3ArR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRUT1BMRUZUOwogICAgICAgICAgICAgICAgaWYgKHB0LnkgPj0gcmVjdC5ib3R0b20tR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRCT1RUT01MRUZUOwogICAgICAgICAgICAgICAgcmV0dXJuIEhUTEVGVDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBDaGVjayByaWdodCBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgIGlmIChwdC54ID49IHJlY3QucmlnaHQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwdC55IDwgcmVjdC50b3ArR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRUT1BSSUdIVDsKICAgICAgICAgICAgICAgIGlmIChwdC55ID49IHJlY3QuYm90dG9tLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSkgcmV0dXJuIEhUQk9UVE9NUklHSFQ7CiAgICAgICAgICAgICAgICByZXR1cm4gSFRSSUdIVDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGVsc2UgIC8qIE5vIHRoaWNrIGZyYW1lICovCiAgICB7CiAgICAgICAgaWYgKEhBU19ETEdGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKQogICAgICAgICAgICBJbmZsYXRlUmVjdCgmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hETEdGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRExHRlJBTUUpKTsKICAgICAgICBlbHNlIGlmIChIQVNfVEhJTkZSQU1FKCB3bmRQdHItPmR3U3R5bGUgKSkKICAgICAgICAgICAgSW5mbGF0ZVJlY3QoJnJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYQk9SREVSKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpKTsKICAgICAgICBpZiAoIVB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUQk9SREVSOwogICAgfQoKICAgIC8qIENoZWNrIGNhcHRpb24gKi8KCiAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NBUFRJT04pID09IFdTX0NBUFRJT04pCiAgICB7CiAgICAgICAgcmVjdC50b3AgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUik7CiAgICAgICAgaWYgKCFQdEluUmVjdCggJnJlY3QsIHB0ICkpCiAgICAgICAgewogICAgICAgICAgICAvKiBDaGVjayBzeXN0ZW0gbWVudSAqLwogICAgICAgICAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1NZU01FTlUpICYmICEod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9UT09MV0lORE9XKSkKICAgICAgICAgICAgICAgIHJlY3QubGVmdCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSk7CiAgICAgICAgICAgIGlmIChwdC54IDw9IHJlY3QubGVmdCkgcmV0dXJuIEhUU1lTTUVOVTsKCiAgICAgICAgICAgIC8qIENoZWNrIG1heGltaXplIGJveCAqLwogICAgICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfTUFYSU1JWkVCT1gpCiAgICAgICAgICAgICAgICByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CgogICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0KSByZXR1cm4gSFRNQVhCVVRUT047CiAgICAgICAgICAgIC8qIENoZWNrIG1pbmltaXplIGJveCAqLwogICAgICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfTUlOSU1JWkVCT1gpCiAgICAgICAgICAgICAgICByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CiAgICAgICAgICAgIGlmIChwdC54ID49IHJlY3QucmlnaHQpIHJldHVybiBIVE1JTkJVVFRPTjsKICAgICAgICAgICAgcmV0dXJuIEhUQ0FQVElPTjsKICAgICAgICB9CiAgICB9CgogICAgICAvKiBDaGVjayBjbGllbnQgYXJlYSAqLwoKICAgIFNjcmVlblRvQ2xpZW50KCB3bmRQdHItPmh3bmRTZWxmLCAmcHQgKTsKICAgIEdldENsaWVudFJlY3QoIHduZFB0ci0+aHduZFNlbGYsICZyZWN0ICk7CiAgICBpZiAoUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFRDTElFTlQ7CgogICAgICAvKiBDaGVjayB2ZXJ0aWNhbCBzY3JvbGwgYmFyICovCgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpCiAgICB7CglyZWN0LnJpZ2h0ICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKTsKCWlmIChQdEluUmVjdCggJnJlY3QsIHB0ICkpIHJldHVybiBIVFZTQ1JPTEw7CiAgICB9CgogICAgICAvKiBDaGVjayBob3Jpem9udGFsIHNjcm9sbCBiYXIgKi8KCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfSFNDUk9MTCkKICAgIHsKCXJlY3QuYm90dG9tICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lIU0NST0xMKTsKCWlmIChQdEluUmVjdCggJnJlY3QsIHB0ICkpCgl7CgkgICAgICAvKiBDaGVjayBzaXplIGJveCAqLwoJICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfVlNDUk9MTCkgJiYKCQkocHQueCA+PSByZWN0LnJpZ2h0IC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpKSkKCQlyZXR1cm4gSFRTSVpFOwoJICAgIHJldHVybiBIVEhTQ1JPTEw7Cgl9CiAgICB9CgogICAgICAvKiBDaGVjayBtZW51IGJhciAqLwoKICAgIGlmIChIQVNfTUVOVSh3bmRQdHIpKQogICAgewoJaWYgKChwdC55IDwgMCkgJiYgKHB0LnggPj0gMCkgJiYgKHB0LnggPCByZWN0LnJpZ2h0KSkKCSAgICByZXR1cm4gSFRNRU5VOwogICAgfQoKICAgIC8qIEhhcyB0byByZXR1cm4gSFROT1dIRVJFIGlmIG5vdGhpbmcgd2FzIGZvdW5kICAKICAgICAgIENvdWxkIGhhcHBlbiB3aGVuIGEgd2luZG93IGhhcyBhIGN1c3RvbWl6ZWQgbm9uIGNsaWVudCBhcmVhICovCiAgICByZXR1cm4gSFROT1dIRVJFOyAgCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTkNfRG9OQ0hpdFRlc3Q5NQogKgogKiBIYW5kbGUgYSBXTV9OQ0hJVFRFU1QgbWVzc2FnZS4gQ2FsbGVkIGZyb20gTkNfSGFuZGxlTkNIaXRUZXN0KCkuCiAqCiAqIEZJWE1FOiAgSnVzdCBhIG1vZGlmaWVkIGNvcHkgb2YgdGhlIFdpbiAzLjEgdmVyc2lvbi4KICovCgpzdGF0aWMgTE9ORyBOQ19Eb05DSGl0VGVzdDk1IChXTkQgKnduZFB0ciwgUE9JTlQgcHQgKQp7CiAgICBSRUNUIHJlY3Q7CgogICAgVFJBQ0UoImh3bmQ9JTA0eCBwdD0lbGQsJWxkXG4iLCB3bmRQdHItPmh3bmRTZWxmLCBwdC54LCBwdC55ICk7CgogICAgR2V0V2luZG93UmVjdCh3bmRQdHItPmh3bmRTZWxmLCAmcmVjdCApOwogICAgaWYgKCFQdEluUmVjdCggJnJlY3QsIHB0ICkpIHJldHVybiBIVE5PV0hFUkU7CgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFKSByZXR1cm4gSFRDQVBUSU9OOwoKICAgIC8qIENoZWNrIGJvcmRlcnMgKi8KICAgIGlmIChIQVNfVEhJQ0tGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKQogICAgewogICAgICAgIEluZmxhdGVSZWN0KCAmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpICk7CiAgICAgICAgaWYgKCFQdEluUmVjdCggJnJlY3QsIHB0ICkpCiAgICAgICAgewogICAgICAgICAgICAvKiBDaGVjayB0b3Agc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICBpZiAocHQueSA8IHJlY3QudG9wKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVFRPUExFRlQ7CiAgICAgICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0LUdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSkgcmV0dXJuIEhUVE9QUklHSFQ7CiAgICAgICAgICAgICAgICByZXR1cm4gSFRUT1A7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogQ2hlY2sgYm90dG9tIHNpemluZyBib3JkZXIgKi8KICAgICAgICAgICAgaWYgKHB0LnkgPj0gcmVjdC5ib3R0b20pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwdC54IDwgcmVjdC5sZWZ0K0dldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSkgcmV0dXJuIEhUQk9UVE9NTEVGVDsKICAgICAgICAgICAgICAgIGlmIChwdC54ID49IHJlY3QucmlnaHQtR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpKSByZXR1cm4gSFRCT1RUT01SSUdIVDsKICAgICAgICAgICAgICAgIHJldHVybiBIVEJPVFRPTTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBDaGVjayBsZWZ0IHNpemluZyBib3JkZXIgKi8KICAgICAgICAgICAgaWYgKHB0LnggPCByZWN0LmxlZnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwdC55IDwgcmVjdC50b3ArR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRUT1BMRUZUOwogICAgICAgICAgICAgICAgaWYgKHB0LnkgPj0gcmVjdC5ib3R0b20tR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRCT1RUT01MRUZUOwogICAgICAgICAgICAgICAgcmV0dXJuIEhUTEVGVDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBDaGVjayByaWdodCBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgIGlmIChwdC54ID49IHJlY3QucmlnaHQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwdC55IDwgcmVjdC50b3ArR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRUT1BSSUdIVDsKICAgICAgICAgICAgICAgIGlmIChwdC55ID49IHJlY3QuYm90dG9tLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSkgcmV0dXJuIEhUQk9UVE9NUklHSFQ7CiAgICAgICAgICAgICAgICByZXR1cm4gSFRSSUdIVDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGVsc2UgIC8qIE5vIHRoaWNrIGZyYW1lICovCiAgICB7CiAgICAgICAgaWYgKEhBU19ETEdGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKQogICAgICAgICAgICBJbmZsYXRlUmVjdCgmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hETEdGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRExHRlJBTUUpKTsKICAgICAgICBlbHNlIGlmIChIQVNfVEhJTkZSQU1FKCB3bmRQdHItPmR3U3R5bGUgKSkKICAgICAgICAgICAgSW5mbGF0ZVJlY3QoJnJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYQk9SREVSKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpKTsKICAgICAgICBpZiAoIVB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUQk9SREVSOwogICAgfQoKICAgIC8qIENoZWNrIGNhcHRpb24gKi8KCiAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NBUFRJT04pID09IFdTX0NBUFRJT04pCiAgICB7CiAgICAgICAgaWYgKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykKICAgICAgICAgICAgcmVjdC50b3AgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNQ0FQVElPTikgLSAxOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmVjdC50b3AgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKICAgICAgICBpZiAoIVB0SW5SZWN0KCAmcmVjdCwgcHQgKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIENoZWNrIHN5c3RlbSBtZW51ICovCiAgICAgICAgICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfU1lTTUVOVSkgJiYgISh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX1RPT0xXSU5ET1cpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoTkNfSWNvbkZvcldpbmRvdyh3bmRQdHItPmh3bmRTZWxmKSkKICAgICAgICAgICAgICAgICAgICByZWN0LmxlZnQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCkgcmV0dXJuIEhUU1lTTUVOVTsKCiAgICAgICAgICAgIC8qIENoZWNrIGNsb3NlIGJ1dHRvbiAqLwogICAgICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfU1lTTUVOVSkKICAgICAgICAgICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKICAgICAgICAgICAgaWYgKHB0LnggPiByZWN0LnJpZ2h0KSByZXR1cm4gSFRDTE9TRTsKCiAgICAgICAgICAgIC8qIENoZWNrIG1heGltaXplIGJveCAqLwogICAgICAgICAgICAvKiBJbiB3aW45NSB0aGVyZSBpcyBhdXRvbWF0aWNhbGx5IGEgTWF4aW1pemUgYnV0dG9uIHdoZW4gdGhlcmUgaXMgYSBtaW5pbWl6ZSBvbmUqLwogICAgICAgICAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01BWElNSVpFQk9YKXx8ICh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRUJPWCkpCiAgICAgICAgICAgICAgICByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CiAgICAgICAgICAgIGlmIChwdC54ID4gcmVjdC5yaWdodCkgcmV0dXJuIEhUTUFYQlVUVE9OOwoKICAgICAgICAgICAgLyogQ2hlY2sgbWluaW1pemUgYm94ICovCiAgICAgICAgICAgIC8qIEluIHdpbjk1IHRoZXJlIGlzIGF1dG9tYXRpY2FsbHkgYSBNYXhpbWl6ZSBidXR0b24gd2hlbiB0aGVyZSBpcyBhIE1heGltaXplIG9uZSovCiAgICAgICAgICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfTUlOSU1JWkVCT1gpfHwod25kUHRyLT5kd1N0eWxlICYgV1NfTUFYSU1JWkVCT1gpKQogICAgICAgICAgICAgICAgcmVjdC5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwoKICAgICAgICAgICAgaWYgKHB0LnggPiByZWN0LnJpZ2h0KSByZXR1cm4gSFRNSU5CVVRUT047CiAgICAgICAgICAgIHJldHVybiBIVENBUFRJT047CiAgICAgICAgfQogICAgfQoKICAgICAgLyogQ2hlY2sgY2xpZW50IGFyZWEgKi8KCiAgICBTY3JlZW5Ub0NsaWVudCggd25kUHRyLT5od25kU2VsZiwgJnB0ICk7CiAgICBHZXRDbGllbnRSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmcmVjdCApOwogICAgaWYgKFB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUQ0xJRU5UOwoKICAgICAgLyogQ2hlY2sgdmVydGljYWwgc2Nyb2xsIGJhciAqLwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19WU0NST0xMKQogICAgewoJcmVjdC5yaWdodCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCk7CglpZiAoUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFRWU0NST0xMOwogICAgfQoKICAgICAgLyogQ2hlY2sgaG9yaXpvbnRhbCBzY3JvbGwgYmFyICovCgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0hTQ1JPTEwpCiAgICB7CglyZWN0LmJvdHRvbSArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCk7CglpZiAoUHRJblJlY3QoICZyZWN0LCBwdCApKQoJewoJICAgICAgLyogQ2hlY2sgc2l6ZSBib3ggKi8KCSAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpICYmCgkJKHB0LnggPj0gcmVjdC5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKSkpCgkJcmV0dXJuIEhUU0laRTsKCSAgICByZXR1cm4gSFRIU0NST0xMOwoJfQogICAgfQoKICAgICAgLyogQ2hlY2sgbWVudSBiYXIgKi8KCiAgICBpZiAoSEFTX01FTlUod25kUHRyKSkKICAgIHsKCWlmICgocHQueSA8IDApICYmIChwdC54ID49IDApICYmIChwdC54IDwgcmVjdC5yaWdodCkpCgkgICAgcmV0dXJuIEhUTUVOVTsKICAgIH0KCiAgICAvKiBIYXMgdG8gcmV0dXJuIEhUTk9XSEVSRSBpZiBub3RoaW5nIHdhcyBmb3VuZCAgCiAgICAgICBDb3VsZCBoYXBwZW4gd2hlbiBhIHdpbmRvdyBoYXMgYSBjdXN0b21pemVkIG5vbiBjbGllbnQgYXJlYSAqLwogICAgcmV0dXJuIEhUTk9XSEVSRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBOQ19IYW5kbGVOQ0hpdFRlc3QKICoKICogSGFuZGxlIGEgV01fTkNISVRURVNUIG1lc3NhZ2UuIENhbGxlZCBmcm9tIERlZldpbmRvd1Byb2MoKS4KICovCkxPTkcgTkNfSGFuZGxlTkNIaXRUZXN0IChIV05EIGh3bmQgLCBQT0lOVCBwdCkKewogICAgTE9ORyByZXR2YWx1ZTsKICAgIFdORCAqd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIgKGh3bmQpOwoKICAgIGlmICghd25kUHRyKQoJcmV0dXJuIEhURVJST1I7CgogICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCiAgICAgICAgcmV0dmFsdWUgPSBOQ19Eb05DSGl0VGVzdCAod25kUHRyLCBwdCk7CiAgICBlbHNlCiAgICAgICAgcmV0dmFsdWUgPSBOQ19Eb05DSGl0VGVzdDk1ICh3bmRQdHIsIHB0KTsKICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7CiAgICByZXR1cm4gcmV0dmFsdWU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0RyYXdTeXNCdXR0b24KICovCnZvaWQgTkNfRHJhd1N5c0J1dHRvbiggSFdORCBod25kLCBIREMgaGRjLCBCT09MIGRvd24gKQp7CiAgICBSRUNUIHJlY3Q7CiAgICBIREMgaGRjTWVtOwogICAgSEJJVE1BUCBoYml0bWFwOwoKICAgIE5DX0dldEluc2lkZVJlY3QoIGh3bmQsICZyZWN0ICk7CiAgICBoZGNNZW0gPSBDcmVhdGVDb21wYXRpYmxlREMoIGhkYyApOwogICAgaGJpdG1hcCA9IFNlbGVjdE9iamVjdCggaGRjTWVtLCBoYml0bWFwQ2xvc2UgKTsKICAgIEJpdEJsdChoZGMsIHJlY3QubGVmdCwgcmVjdC50b3AsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpLAogICAgICAgICAgIGhkY01lbSwgKEdldFdpbmRvd0xvbmdBKGh3bmQsR1dMX1NUWUxFKSAmIFdTX0NISUxEKSA/IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSA6IDAsIDAsCiAgICAgICAgICAgZG93biA/IE5PVFNSQ0NPUFkgOiBTUkNDT1BZICk7CiAgICBTZWxlY3RPYmplY3QoIGhkY01lbSwgaGJpdG1hcCApOwogICAgRGVsZXRlREMoIGhkY01lbSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3TWF4QnV0dG9uCiAqLwpzdGF0aWMgdm9pZCBOQ19EcmF3TWF4QnV0dG9uKCBIV05EIGh3bmQsIEhEQzE2IGhkYywgQk9PTCBkb3duICkKewogICAgUkVDVCByZWN0OwogICAgSERDIGhkY01lbTsKCiAgICBOQ19HZXRJbnNpZGVSZWN0KCBod25kLCAmcmVjdCApOwogICAgaGRjTWVtID0gQ3JlYXRlQ29tcGF0aWJsZURDKCBoZGMgKTsKICAgIFNlbGVjdE9iamVjdCggaGRjTWVtLCAgKElzWm9vbWVkKGh3bmQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IChkb3duID8gaGJpdG1hcFJlc3RvcmVEIDogaGJpdG1hcFJlc3RvcmUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IChkb3duID8gaGJpdG1hcE1heGltaXplRCA6IGhiaXRtYXBNYXhpbWl6ZSkpICk7CiAgICBCaXRCbHQoIGhkYywgcmVjdC5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSAtIDEsIHJlY3QudG9wLAogICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSksIGhkY01lbSwgMCwgMCwKICAgICAgICAgICAgU1JDQ09QWSApOwogICAgRGVsZXRlREMoIGhkY01lbSApOwoKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfRHJhd01pbkJ1dHRvbgogKi8Kc3RhdGljIHZvaWQgTkNfRHJhd01pbkJ1dHRvbiggSFdORCBod25kLCBIREMxNiBoZGMsIEJPT0wgZG93biApCnsKICAgIFJFQ1QgcmVjdDsKICAgIEhEQyBoZGNNZW07CgogICAgTkNfR2V0SW5zaWRlUmVjdCggaHduZCwgJnJlY3QgKTsKICAgIGhkY01lbSA9IENyZWF0ZUNvbXBhdGlibGVEQyggaGRjICk7CiAgICBTZWxlY3RPYmplY3QoIGhkY01lbSwgKGRvd24gPyBoYml0bWFwTWluaW1pemVEIDogaGJpdG1hcE1pbmltaXplKSApOwogICAgaWYgKEdldFdpbmRvd0xvbmdBKGh3bmQsR1dMX1NUWUxFKSAmIFdTX01BWElNSVpFQk9YKQogICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpKzE7CiAgICBCaXRCbHQoIGhkYywgcmVjdC5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSAtIDEsIHJlY3QudG9wLAogICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSksIGhkY01lbSwgMCwgMCwKICAgICAgICAgICAgU1JDQ09QWSApOwogICAgRGVsZXRlREMoIGhkY01lbSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIHZvaWQgIE5DX0RyYXdTeXNCdXR0b245NSgKICogICAgICBIV05EICBod25kLAogKiAgICAgIEhEQyAgaGRjLAogKiAgICAgIEJPT0wgIGRvd24gKQogKgogKiAgIERyYXdzIHRoZSBXaW45NSBzeXN0ZW0gaWNvbi4KICoKICogICBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAgICAwNS1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgICAgICAgT3JpZ2luYWwgaW1wbGVtZW50YXRpb24gZnJvbSBOQ19EcmF3U3lzQnV0dG9uIHNvdXJjZS4KICogICAgICAgIDExLUp1bi0xOTk4IEVyaWMgS29obCAoZWtvaGxAYWJvLnJoZWluLXplaXR1bmcuZGUpCiAqICAgICAgICAgICAgIEZpeGVkIG1vc3QgYnVncy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKQk9PTApOQ19EcmF3U3lzQnV0dG9uOTUgKEhXTkQgaHduZCwgSERDIGhkYywgQk9PTCBkb3duKQp7CiAgICBISUNPTiBoSWNvbiA9IE5DX0ljb25Gb3JXaW5kb3coIGh3bmQgKTsKCiAgICBpZiAoaEljb24pCiAgICB7CiAgICAgICAgUkVDVCByZWN0OwogICAgICAgIE5DX0dldEluc2lkZVJlY3QoIGh3bmQsICZyZWN0ICk7CiAgICAgICAgRHJhd0ljb25FeCAoaGRjLCByZWN0LmxlZnQgKyAyLCByZWN0LnRvcCArIDIsIGhJY29uLAogICAgICAgICAgICAgICAgICAgIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTTUlDT04pLAogICAgICAgICAgICAgICAgICAgIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUlDT04pLCAwLCAwLCBESV9OT1JNQUwpOwogICAgfQogICAgcmV0dXJuIChoSWNvbiAhPSAwKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICB2b2lkICBOQ19EcmF3Q2xvc2VCdXR0b245NSgKICogICAgICBIV05EICBod25kLAogKiAgICAgIEhEQyAgaGRjLAogKiAgICAgIEJPT0wgIGRvd24sCiAqICAgICAgQk9PTCAgICBiR3JheWVkICkKICoKICogICBEcmF3cyB0aGUgV2luOTUgY2xvc2UgYnV0dG9uLgogKgogKiAgIElmIGJHcmF5ZWQgaXMgdHJ1ZSwgdGhlbiBkcmF3IGEgZGlzYWJsZWQgQ2xvc2UgYnV0dG9uCiAqCiAqICAgUmV2aXNpb24gaGlzdG9yeQogKiAgICAgICAgMTEtSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgICAgICAgT3JpZ2luYWwgaW1wbGVtZW50YXRpb24gZnJvbSBOQ19EcmF3U3lzQnV0dG9uOTUgc291cmNlLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZCBOQ19EcmF3Q2xvc2VCdXR0b245NSAoSFdORCBod25kLCBIREMgaGRjLCBCT09MIGRvd24sIEJPT0wgYkdyYXllZCkKewogICAgUkVDVCByZWN0OwoKICAgIE5DX0dldEluc2lkZVJlY3QoIGh3bmQsICZyZWN0ICk7CgogICAgLyogQSB0b29sIHdpbmRvdyBoYXMgYSBzbWFsbGVyIENsb3NlIGJ1dHRvbiAqLwogICAgaWYgKEdldFdpbmRvd0xvbmdBKCBod25kLCBHV0xfRVhTVFlMRSApICYgV1NfRVhfVE9PTFdJTkRPVykKICAgIHsKICAgICAgICBJTlQgaUJtcEhlaWdodCA9IDExOyAvKiBXaW5kb3dzIGRvZXMgbm90IHVzZSBTTV9DWFNNU0laRSBhbmQgU01fQ1lTTVNJWkUgICAqLwogICAgICAgIElOVCBpQm1wV2lkdGggPSAxMTsgIC8qIGl0IHVzZXMgMTF4MTEgZm9yICB0aGUgY2xvc2UgYnV0dG9uIGluIHRvb2wgd2luZG93ICovCiAgICAgICAgSU5UIGlDYXB0aW9uSGVpZ2h0ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNQ0FQVElPTik7CgogICAgICAgIHJlY3QudG9wID0gcmVjdC50b3AgKyAoaUNhcHRpb25IZWlnaHQgLSAxIC0gaUJtcEhlaWdodCkgLyAyOwogICAgICAgIHJlY3QubGVmdCA9IHJlY3QucmlnaHQgLSAoaUNhcHRpb25IZWlnaHQgKyAxICsgaUJtcFdpZHRoKSAvIDI7CiAgICAgICAgcmVjdC5ib3R0b20gPSByZWN0LnRvcCArIGlCbXBIZWlnaHQ7CiAgICAgICAgcmVjdC5yaWdodCA9IHJlY3QubGVmdCArIGlCbXBXaWR0aDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZWN0LmxlZnQgPSByZWN0LnJpZ2h0IC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpIC0gMTsKICAgICAgICByZWN0LmJvdHRvbSA9IHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpIC0gMTsKICAgICAgICByZWN0LnRvcCArPSAyOwogICAgICAgIHJlY3QucmlnaHQgLT0gMjsKICAgIH0KICAgIERyYXdGcmFtZUNvbnRyb2woIGhkYywgJnJlY3QsIERGQ19DQVBUSU9OLAogICAgICAgICAgICAgICAgICAgICAgKERGQ1NfQ0FQVElPTkNMT1NFIHwKICAgICAgICAgICAgICAgICAgICAgICAoZG93biA/IERGQ1NfUFVTSEVEIDogMCkgfAogICAgICAgICAgICAgICAgICAgICAgIChiR3JheWVkID8gREZDU19JTkFDVElWRSA6IDApKSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgTkNfRHJhd01heEJ1dHRvbjk1CiAqCiAqICAgRHJhd3MgdGhlIG1heGltaXplIGJ1dHRvbiBmb3IgV2luOTUgc3R5bGUgd2luZG93cy4KICogICBJZiBiR3JheWVkIGlzIHRydWUsIHRoZW4gZHJhdyBhIGRpc2FibGVkIE1heGltaXplIGJ1dHRvbgogKi8Kc3RhdGljIHZvaWQgTkNfRHJhd01heEJ1dHRvbjk1KEhXTkQgaHduZCxIREMxNiBoZGMsQk9PTCBkb3duLCBCT09MIGJHcmF5ZWQpCnsKICAgIFJFQ1QgcmVjdDsKICAgIFVJTlQgZmxhZ3MgPSBJc1pvb21lZChod25kKSA/IERGQ1NfQ0FQVElPTlJFU1RPUkUgOiBERkNTX0NBUFRJT05NQVg7CgogICAgTkNfR2V0SW5zaWRlUmVjdCggaHduZCwgJnJlY3QgKTsKICAgIGlmIChHZXRXaW5kb3dMb25nQSggaHduZCwgR1dMX1NUWUxFKSAmIFdTX1NZU01FTlUpCiAgICAgICAgcmVjdC5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwogICAgcmVjdC5sZWZ0ID0gcmVjdC5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKTsKICAgIHJlY3QuYm90dG9tID0gcmVjdC50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkgLSAxOwogICAgcmVjdC50b3AgKz0gMjsKICAgIHJlY3QucmlnaHQgLT0gMjsKICAgIGlmIChkb3duKSBmbGFncyB8PSBERkNTX1BVU0hFRDsKICAgIGlmIChiR3JheWVkKSBmbGFncyB8PSBERkNTX0lOQUNUSVZFOwogICAgRHJhd0ZyYW1lQ29udHJvbCggaGRjLCAmcmVjdCwgREZDX0NBUFRJT04sIGZsYWdzICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICBOQ19EcmF3TWluQnV0dG9uOTUKICoKICogICBEcmF3cyB0aGUgbWluaW1pemUgYnV0dG9uIGZvciBXaW45NSBzdHlsZSB3aW5kb3dzLgogKiAgIElmIGJHcmF5ZWQgaXMgdHJ1ZSwgdGhlbiBkcmF3IGEgZGlzYWJsZWQgTWluaW1pemUgYnV0dG9uCiAqLwpzdGF0aWMgdm9pZCAgTkNfRHJhd01pbkJ1dHRvbjk1KEhXTkQgaHduZCxIREMxNiBoZGMsQk9PTCBkb3duLCBCT09MIGJHcmF5ZWQpCnsKICAgIFJFQ1QgcmVjdDsKICAgIFVJTlQgZmxhZ3MgPSBERkNTX0NBUFRJT05NSU47CiAgICBEV09SRCBzdHlsZSA9IEdldFdpbmRvd0xvbmdBKCBod25kLCBHV0xfU1RZTEUgKTsKCiAgICBOQ19HZXRJbnNpZGVSZWN0KCBod25kLCAmcmVjdCApOwogICAgaWYgKHN0eWxlICYgV1NfU1lTTUVOVSkKICAgICAgICByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CiAgICBpZiAoc3R5bGUgJiAoV1NfTUFYSU1JWkVCT1h8V1NfTUlOSU1JWkVCT1gpKQogICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpIC0gMjsKICAgIHJlY3QubGVmdCA9IHJlY3QucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSk7CiAgICByZWN0LmJvdHRvbSA9IHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpIC0gMTsKICAgIHJlY3QudG9wICs9IDI7CiAgICByZWN0LnJpZ2h0IC09IDI7CiAgICBpZiAoZG93bikgZmxhZ3MgfD0gREZDU19QVVNIRUQ7CiAgICBpZiAoYkdyYXllZCkgZmxhZ3MgfD0gREZDU19JTkFDVElWRTsKICAgIERyYXdGcmFtZUNvbnRyb2woIGhkYywgJnJlY3QsIERGQ19DQVBUSU9OLCBmbGFncyApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0RyYXdGcmFtZQogKgogKiBEcmF3IGEgd2luZG93IGZyYW1lIGluc2lkZSB0aGUgZ2l2ZW4gcmVjdGFuZ2xlLCBhbmQgdXBkYXRlIHRoZSByZWN0YW5nbGUuCiAqIFRoZSBjb3JyZWN0IHBlbiBmb3IgdGhlIGZyYW1lIG11c3QgYmUgc2VsZWN0ZWQgaW4gdGhlIERDLgogKi8Kc3RhdGljIHZvaWQgTkNfRHJhd0ZyYW1lKCBIREMgaGRjLCBSRUNUICpyZWN0LCBCT09MIGRsZ0ZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgYWN0aXZlICkKewogICAgSU5UIHdpZHRoLCBoZWlnaHQ7CgogICAgaWYgKFRXRUFLX1dpbmVMb29rICE9IFdJTjMxX0xPT0spCglFUlIoIkNhbGxlZCBpbiBXaW45NSBtb2RlLiBBaWVlISBQbGVhc2UgcmVwb3J0IHRoaXMuXG4iICk7CgogICAgaWYgKGRsZ0ZyYW1lKQogICAgewoJd2lkdGggPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRExHRlJBTUUpIC0gMTsKCWhlaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lETEdGUkFNRSkgLSAxOwogICAgICAgIFNlbGVjdE9iamVjdCggaGRjLCBHZXRTeXNDb2xvckJydXNoKGFjdGl2ZSA/IENPTE9SX0FDVElWRUNBUFRJT04gOgoJCQkJCQlDT0xPUl9JTkFDVElWRUNBUFRJT04pICk7CiAgICB9CiAgICBlbHNlCiAgICB7Cgl3aWR0aCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSkgLSAyOwoJaGVpZ2h0ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSAtIDI7CiAgICAgICAgU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN5c0NvbG9yQnJ1c2goYWN0aXZlID8gQ09MT1JfQUNUSVZFQk9SREVSIDoKCQkJCQkJQ09MT1JfSU5BQ1RJVkVCT1JERVIpICk7CiAgICB9CgogICAgICAvKiBEcmF3IGZyYW1lICovCiAgICBQYXRCbHQoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+dG9wLAogICAgICAgICAgICAgIHJlY3QtPnJpZ2h0IC0gcmVjdC0+bGVmdCwgaGVpZ2h0LCBQQVRDT1BZICk7CiAgICBQYXRCbHQoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+dG9wLAogICAgICAgICAgICAgIHdpZHRoLCByZWN0LT5ib3R0b20gLSByZWN0LT50b3AsIFBBVENPUFkgKTsKICAgIFBhdEJsdCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT5ib3R0b20gLSAxLAogICAgICAgICAgICAgIHJlY3QtPnJpZ2h0IC0gcmVjdC0+bGVmdCwgLWhlaWdodCwgUEFUQ09QWSApOwogICAgUGF0Qmx0KCBoZGMsIHJlY3QtPnJpZ2h0IC0gMSwgcmVjdC0+dG9wLAogICAgICAgICAgICAgIC13aWR0aCwgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLCBQQVRDT1BZICk7CgogICAgaWYgKGRsZ0ZyYW1lKQogICAgewoJSW5mbGF0ZVJlY3QoIHJlY3QsIC13aWR0aCwgLWhlaWdodCApOwogICAgfSAKICAgIGVsc2UKICAgIHsKICAgICAgICBJTlQgZGVjWU9mZiA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSkgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgLSAxOwoJSU5UIGRlY1hPZmYgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpIC0gMTsKCiAgICAgIC8qIERyYXcgaW5uZXIgcmVjdGFuZ2xlICovCgoJU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN0b2NrT2JqZWN0KE5VTExfQlJVU0gpICk7CglSZWN0YW5nbGUoIGhkYywgcmVjdC0+bGVmdCArIHdpZHRoLCByZWN0LT50b3AgKyBoZWlnaHQsCgkJICAgICByZWN0LT5yaWdodCAtIHdpZHRoICwgcmVjdC0+Ym90dG9tIC0gaGVpZ2h0ICk7CgogICAgICAvKiBEcmF3IHRoZSBkZWNvcmF0aW9ucyAqLwoKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCArIGRlY1lPZmYsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByZWN0LT5sZWZ0ICsgd2lkdGgsIHJlY3QtPnRvcCArIGRlY1lPZmYgKTsKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPnJpZ2h0IC0gMSwgcmVjdC0+dG9wICsgZGVjWU9mZiwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHJlY3QtPnJpZ2h0IC0gd2lkdGggLSAxLCByZWN0LT50b3AgKyBkZWNZT2ZmICk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT5ib3R0b20gLSBkZWNZT2ZmLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+bGVmdCArIHdpZHRoLCByZWN0LT5ib3R0b20gLSBkZWNZT2ZmICk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5yaWdodCAtIDEsIHJlY3QtPmJvdHRvbSAtIGRlY1lPZmYsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByZWN0LT5yaWdodCAtIHdpZHRoIC0gMSwgcmVjdC0+Ym90dG9tIC0gZGVjWU9mZiApOwoKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPmxlZnQgKyBkZWNYT2ZmLCByZWN0LT50b3AsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByZWN0LT5sZWZ0ICsgZGVjWE9mZiwgcmVjdC0+dG9wICsgaGVpZ2h0KTsKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPmxlZnQgKyBkZWNYT2ZmLCByZWN0LT5ib3R0b20gLSAxLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+bGVmdCArIGRlY1hPZmYsIHJlY3QtPmJvdHRvbSAtIGhlaWdodCAtIDEgKTsKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPnJpZ2h0IC0gZGVjWE9mZiwgcmVjdC0+dG9wLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+cmlnaHQgLSBkZWNYT2ZmLCByZWN0LT50b3AgKyBoZWlnaHQgKTsKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPnJpZ2h0IC0gZGVjWE9mZiwgcmVjdC0+Ym90dG9tIC0gMSwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHJlY3QtPnJpZ2h0IC0gZGVjWE9mZiwgcmVjdC0+Ym90dG9tIC0gaGVpZ2h0IC0gMSApOwoKCUluZmxhdGVSZWN0KCByZWN0LCAtd2lkdGggLSAxLCAtaGVpZ2h0IC0gMSApOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIHZvaWQgIE5DX0RyYXdGcmFtZTk1KAogKiAgICAgIEhEQyAgaGRjLAogKiAgICAgIFJFQ1QgICpyZWN0LAogKiAgICAgIEJPT0wgIGFjdGl2ZSwKICogICAgICBEV09SRCBzdHlsZSwKICogICAgICBEV09SRCBleFN0eWxlICkKICoKICogICBEcmF3IGEgd2luZG93IGZyYW1lIGluc2lkZSB0aGUgZ2l2ZW4gcmVjdGFuZ2xlLCBhbmQgdXBkYXRlIHRoZSByZWN0YW5nbGUuCiAqCiAqICAgQnVncwogKiAgICAgICAgTWFueS4gIEZpcnN0LCBqdXN0IHdoYXQgSVMgYSBmcmFtZSBpbiBXaW45NT8gIE5vdGUgdGhhdCB0aGUgM0QgbG9vawogKiAgICAgICAgb24gdGhlIG91dGVyIGVkZ2UgaXMgaGFuZGxlZCBieSBOQ19Eb05DUGFpbnQ5NS4gIEFzIGlzIHRoZSBpbm5lcgogKiAgICAgICAgZWRnZS4gIFRoZSBpbm5lciByZWN0YW5nbGUganVzdCBpbnNpZGUgdGhlIGZyYW1lIGlzIGhhbmRsZWQgYnkgdGhlCiAqICAgICAgICBDYXB0aW9uIGNvZGUuCiAqCiAqICAgICAgICBJbiBzaG9ydCwgZm9yIG1vc3QgcGVvcGxlLCB0aGlzIGZ1bmN0aW9uIHNob3VsZCBiZSBhIG5vcCAodW5sZXNzCiAqICAgICAgICB5b3UgTElLRSB0aGljayBib3JkZXJzIGluIFdpbjk1L05UNC4wIC0tIEkndmUgYmVlbiB3b3JraW5nIHdpdGgKICogICAgICAgIHRoZW0gbGF0ZWx5LCBidXQganVzdCB0byBnZXQgdGhpcyBjb2RlIHJpZ2h0KS4gIEV2ZW4gc28sIGl0IGRvZXNuJ3QKICogICAgICAgIGFwcGVhciB0byBiZSBzby4gIEl0J3MgYmVpbmcgd29ya2VkIG9uLi4uCiAqIAogKiAgIFJldmlzaW9uIGhpc3RvcnkKICogICAgICAgIDA2LUp1bC0xOTk3IERhdmUgQ3V0aGJlcnQgKGRhY3V0QGVjZS5jbXUuZWR1KQogKiAgICAgICAgICAgICBPcmlnaW5hbCBpbXBsZW1lbnRhdGlvbiAoYmFzZWQgb24gTkNfRHJhd0ZyYW1lKQogKiAgICAgICAgMDItSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgICAgICAgU29tZSBtaW5vciBmaXhlcy4KICogICAgICAgIDI5LUp1bi0xOTk5IE92ZSBL5XZlbiAob3Zla0BhcmN0aWNuZXQubm8pCiAqICAgICAgICAgICAgIEZpeGVkIGEgZml4IG9yIHNvbWV0aGluZy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHZvaWQgIE5DX0RyYXdGcmFtZTk1KAogICAgSERDICBoZGMsCiAgICBSRUNUICAqcmVjdCwKICAgIEJPT0wgIGFjdGl2ZSwKICAgIERXT1JEIHN0eWxlLAogICAgRFdPUkQgZXhTdHlsZSkKewogICAgSU5UIHdpZHRoLCBoZWlnaHQ7CgogICAgLyogRmlyc3RseSB0aGUgInRoaWNrIiBmcmFtZSAqLwogICAgaWYgKHN0eWxlICYgV1NfVEhJQ0tGUkFNRSkKICAgIHsKCXdpZHRoID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWEZSQU1FKSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hETEdGUkFNRSk7CgloZWlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWURMR0ZSQU1FKTsKCiAgICAgICAgU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN5c0NvbG9yQnJ1c2goYWN0aXZlID8gQ09MT1JfQUNUSVZFQk9SREVSIDoKCQkgICAgICBDT0xPUl9JTkFDVElWRUJPUkRFUikgKTsKICAgICAgICAvKiBEcmF3IGZyYW1lICovCiAgICAgICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAgICAgcmVjdC0+cmlnaHQgLSByZWN0LT5sZWZ0LCBoZWlnaHQsIFBBVENPUFkgKTsKICAgICAgICBQYXRCbHQoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+dG9wLAogICAgICAgICAgICAgICAgICB3aWR0aCwgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLCBQQVRDT1BZICk7CiAgICAgICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPmJvdHRvbSAtIDEsCiAgICAgICAgICAgICAgICAgIHJlY3QtPnJpZ2h0IC0gcmVjdC0+bGVmdCwgLWhlaWdodCwgUEFUQ09QWSApOwogICAgICAgIFBhdEJsdCggaGRjLCByZWN0LT5yaWdodCAtIDEsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAgICAgLXdpZHRoLCByZWN0LT5ib3R0b20gLSByZWN0LT50b3AsIFBBVENPUFkgKTsKCiAgICAgICAgSW5mbGF0ZVJlY3QoIHJlY3QsIC13aWR0aCwgLWhlaWdodCApOwogICAgfQoKICAgIC8qIE5vdyB0aGUgb3RoZXIgYml0IG9mIHRoZSBmcmFtZSAqLwogICAgaWYgKChzdHlsZSAmIChXU19CT1JERVJ8V1NfRExHRlJBTUUpKSB8fAogICAgICAgIChleFN0eWxlICYgV1NfRVhfRExHTU9EQUxGUkFNRSkpCiAgICB7CiAgICAgICAgd2lkdGggPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRExHRlJBTUUpIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWEVER0UpOwogICAgICAgIGhlaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lETEdGUkFNRSkgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSk7CiAgICAgICAgLyogVGhpcyBzaG91bGQgZ2l2ZSBhIHZhbHVlIG9mIDEgdGhhdCBzaG91bGQgYWxzbyB3b3JrIGZvciBhIGJvcmRlciAqLwoKICAgICAgICBTZWxlY3RPYmplY3QoIGhkYywgR2V0U3lzQ29sb3JCcnVzaCgKICAgICAgICAgICAgICAgICAgICAgIChleFN0eWxlICYgKFdTX0VYX0RMR01PREFMRlJBTUV8V1NfRVhfQ0xJRU5URURHRSkpID8KICAgICAgICAgICAgICAgICAgICAgICAgICBDT0xPUl8zREZBQ0UgOgogICAgICAgICAgICAgICAgICAgICAgKGV4U3R5bGUgJiBXU19FWF9TVEFUSUNFREdFKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgQ09MT1JfV0lORE9XRlJBTUUgOgogICAgICAgICAgICAgICAgICAgICAgKHN0eWxlICYgKFdTX0RMR0ZSQU1FfFdTX1RISUNLRlJBTUUpKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgQ09MT1JfM0RGQUNFIDoKICAgICAgICAgICAgICAgICAgICAgIC8qIGVsc2UgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICBDT0xPUl9XSU5ET1dGUkFNRSkpOwoKICAgICAgICAvKiBEcmF3IGZyYW1lICovCiAgICAgICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAgICAgcmVjdC0+cmlnaHQgLSByZWN0LT5sZWZ0LCBoZWlnaHQsIFBBVENPUFkgKTsKICAgICAgICBQYXRCbHQoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+dG9wLAogICAgICAgICAgICAgICAgICB3aWR0aCwgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLCBQQVRDT1BZICk7CiAgICAgICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPmJvdHRvbSAtIDEsCiAgICAgICAgICAgICAgICAgIHJlY3QtPnJpZ2h0IC0gcmVjdC0+bGVmdCwgLWhlaWdodCwgUEFUQ09QWSApOwogICAgICAgIFBhdEJsdCggaGRjLCByZWN0LT5yaWdodCAtIDEsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAgICAgLXdpZHRoLCByZWN0LT5ib3R0b20gLSByZWN0LT50b3AsIFBBVENPUFkgKTsKCiAgICAgICAgSW5mbGF0ZVJlY3QoIHJlY3QsIC13aWR0aCwgLWhlaWdodCApOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3Q2FwdGlvbgogKgogKiBEcmF3IHRoZSB3aW5kb3cgY2FwdGlvbi4KICogVGhlIGNvcnJlY3QgcGVuIGZvciB0aGUgd2luZG93IGZyYW1lIG11c3QgYmUgc2VsZWN0ZWQgaW4gdGhlIERDLgogKi8Kc3RhdGljIHZvaWQgTkNfRHJhd0NhcHRpb24oIEhEQyBoZGMsIFJFQ1QgKnJlY3QsIEhXTkQgaHduZCwKCQkJICAgIERXT1JEIHN0eWxlLCBCT09MIGFjdGl2ZSApCnsKICAgIFJFQ1QgciA9ICpyZWN0OwogICAgY2hhciBidWZmZXJbMjU2XTsKCiAgICBpZiAoIWhiaXRtYXBDbG9zZSkKICAgIHsKCWlmICghKGhiaXRtYXBDbG9zZSA9IExvYWRCaXRtYXBBKCAwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9DTE9TRSkgKSkpIHJldHVybjsKCWhiaXRtYXBNaW5pbWl6ZSAgPSBMb2FkQml0bWFwQSggMCwgTUFLRUlOVFJFU09VUkNFQShPQk1fUkVEVUNFKSApOwoJaGJpdG1hcE1pbmltaXplRCA9IExvYWRCaXRtYXBBKCAwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9SRURVQ0VEKSApOwoJaGJpdG1hcE1heGltaXplICA9IExvYWRCaXRtYXBBKCAwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9aT09NKSApOwoJaGJpdG1hcE1heGltaXplRCA9IExvYWRCaXRtYXBBKCAwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9aT09NRCkgKTsKCWhiaXRtYXBSZXN0b3JlICAgPSBMb2FkQml0bWFwQSggMCwgTUFLRUlOVFJFU09VUkNFQShPQk1fUkVTVE9SRSkgKTsKCWhiaXRtYXBSZXN0b3JlRCAgPSBMb2FkQml0bWFwQSggMCwgTUFLRUlOVFJFU09VUkNFQShPQk1fUkVTVE9SRUQpICk7CiAgICB9CiAgICAKICAgIGlmIChHZXRXaW5kb3dMb25nQSggaHduZCwgR1dMX0VYU1RZTEUpICYgV1NfRVhfRExHTU9EQUxGUkFNRSkKICAgIHsKICAgICAgICBIQlJVU0ggaGJydXNoT2xkID0gU2VsZWN0T2JqZWN0KGhkYywgR2V0U3lzQ29sb3JCcnVzaChDT0xPUl9XSU5ET1cpICk7CglQYXRCbHQoIGhkYywgci5sZWZ0LCByLnRvcCwgMSwgci5ib3R0b20tci50b3ArMSxQQVRDT1BZICk7CglQYXRCbHQoIGhkYywgci5yaWdodC0xLCByLnRvcCwgMSwgci5ib3R0b20tci50b3ArMSwgUEFUQ09QWSApOwoJUGF0Qmx0KCBoZGMsIHIubGVmdCwgci50b3AtMSwgci5yaWdodC1yLmxlZnQsIDEsIFBBVENPUFkgKTsKCXIubGVmdCsrOwoJci5yaWdodC0tOwoJU2VsZWN0T2JqZWN0KCBoZGMsIGhicnVzaE9sZCApOwogICAgfQogICAgTW92ZVRvRXgoIGhkYywgci5sZWZ0LCByLmJvdHRvbSwgTlVMTCApOwogICAgTGluZVRvKCBoZGMsIHIucmlnaHQsIHIuYm90dG9tICk7CgogICAgaWYgKHN0eWxlICYgV1NfU1lTTUVOVSkKICAgIHsKCU5DX0RyYXdTeXNCdXR0b24oIGh3bmQsIGhkYywgRkFMU0UgKTsKCXIubGVmdCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwoJTW92ZVRvRXgoIGhkYywgci5sZWZ0IC0gMSwgci50b3AsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByLmxlZnQgLSAxLCByLmJvdHRvbSApOwogICAgfQogICAgaWYgKHN0eWxlICYgV1NfTUFYSU1JWkVCT1gpCiAgICB7CglOQ19EcmF3TWF4QnV0dG9uKCBod25kLCBoZGMsIEZBTFNFICk7CglyLnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CiAgICB9CiAgICBpZiAoc3R5bGUgJiBXU19NSU5JTUlaRUJPWCkKICAgIHsKCU5DX0RyYXdNaW5CdXR0b24oIGh3bmQsIGhkYywgRkFMU0UgKTsKCXIucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKICAgIH0KCiAgICBGaWxsUmVjdCggaGRjLCAmciwgR2V0U3lzQ29sb3JCcnVzaChhY3RpdmUgPyBDT0xPUl9BQ1RJVkVDQVBUSU9OIDoKCQkJCQkgICAgQ09MT1JfSU5BQ1RJVkVDQVBUSU9OKSApOwoKICAgIGlmIChHZXRXaW5kb3dUZXh0QSggaHduZCwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSApKQogICAgewoJaWYgKGFjdGl2ZSkgU2V0VGV4dENvbG9yKCBoZGMsIEdldFN5c0NvbG9yKCBDT0xPUl9DQVBUSU9OVEVYVCApICk7CgllbHNlIFNldFRleHRDb2xvciggaGRjLCBHZXRTeXNDb2xvciggQ09MT1JfSU5BQ1RJVkVDQVBUSU9OVEVYVCApICk7CglTZXRCa01vZGUoIGhkYywgVFJBTlNQQVJFTlQgKTsKCURyYXdUZXh0QSggaGRjLCBidWZmZXIsIC0xLCAmciwKICAgICAgICAgICAgICAgICAgICAgRFRfU0lOR0xFTElORSB8IERUX0NFTlRFUiB8IERUX1ZDRU5URVIgfCBEVF9OT1BSRUZJWCApOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIE5DX0RyYXdDYXB0aW9uOTUoCiAqICAgICAgSERDICBoZGMsCiAqICAgICAgUkVDVCAqcmVjdCwKICogICAgICBIV05EIGh3bmQsCiAqICAgICAgRFdPUkQgIHN0eWxlLAogKiAgICAgIEJPT0wgYWN0aXZlICkKICoKICogICBEcmF3IHRoZSB3aW5kb3cgY2FwdGlvbiBmb3IgV2luOTUgc3R5bGUgd2luZG93cy4KICogICBUaGUgY29ycmVjdCBwZW4gZm9yIHRoZSB3aW5kb3cgZnJhbWUgbXVzdCBiZSBzZWxlY3RlZCBpbiB0aGUgREMuCiAqCiAqICAgQnVncwogKiAgICAgICAgSGV5LCBhIGZ1bmN0aW9uIHRoYXQgZmluYWxseSB3b3JrcyEgIFdlbGwsIGFsbW9zdC4KICogICAgICAgIEl0J3MgYmVpbmcgd29ya2VkIG9uLgogKgogKiAgIFJldmlzaW9uIGhpc3RvcnkKICogICAgICAgIDA1LUp1bC0xOTk3IERhdmUgQ3V0aGJlcnQgKGRhY3V0QGVjZS5jbXUuZWR1KQogKiAgICAgICAgICAgICBPcmlnaW5hbCBpbXBsZW1lbnRhdGlvbi4KICogICAgICAgIDAyLUp1bi0xOTk4IEVyaWMgS29obCAoZWtvaGxAYWJvLnJoZWluLXplaXR1bmcuZGUpCiAqICAgICAgICAgICAgIFNvbWUgbWlub3IgZml4ZXMuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkICBOQ19EcmF3Q2FwdGlvbjk1KAogICAgSERDICBoZGMsCiAgICBSRUNUICpyZWN0LAogICAgSFdORCBod25kLAogICAgRFdPUkQgIHN0eWxlLAogICAgRFdPUkQgIGV4U3R5bGUsCiAgICBCT09MIGFjdGl2ZSApCnsKICAgIFJFQ1QgIHIgPSAqcmVjdDsKICAgIGNoYXIgICAgYnVmZmVyWzI1Nl07CiAgICBIUEVOICBoUHJldlBlbjsKICAgIEhNRU5VIGhTeXNNZW51OwoKICAgIGhQcmV2UGVuID0gU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN5c0NvbG9yUGVuKAogICAgICAgICAgICAgICAgICAgICAoKGV4U3R5bGUgJiAoV1NfRVhfU1RBVElDRURHRXxXU19FWF9DTElFTlRFREdFfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXU19FWF9ETEdNT0RBTEZSQU1FKSkgPT0gV1NfRVhfU1RBVElDRURHRSkgPwogICAgICAgICAgICAgICAgICAgICAgQ09MT1JfV0lORE9XRlJBTUUgOiBDT0xPUl8zREZBQ0UpICk7CiAgICBNb3ZlVG9FeCggaGRjLCByLmxlZnQsIHIuYm90dG9tIC0gMSwgTlVMTCApOwogICAgTGluZVRvKCBoZGMsIHIucmlnaHQsIHIuYm90dG9tIC0gMSApOwogICAgU2VsZWN0T2JqZWN0KCBoZGMsIGhQcmV2UGVuICk7CiAgICByLmJvdHRvbS0tOwoKICAgIEZpbGxSZWN0KCBoZGMsICZyLCBHZXRTeXNDb2xvckJydXNoKGFjdGl2ZSA/IENPTE9SX0FDVElWRUNBUFRJT04gOgoJCQkJCSAgICBDT0xPUl9JTkFDVElWRUNBUFRJT04pICk7CgogICAgaWYgKChzdHlsZSAmIFdTX1NZU01FTlUpICYmICEoZXhTdHlsZSAmIFdTX0VYX1RPT0xXSU5ET1cpKSB7CglpZiAoTkNfRHJhd1N5c0J1dHRvbjk1IChod25kLCBoZGMsIEZBTFNFKSkKCSAgICByLmxlZnQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKICAgIH0KCiAgICBpZiAoc3R5bGUgJiBXU19TWVNNRU5VKSAKICAgIHsKCVVJTlQgc3RhdGU7CgoJLyogR28gZ2V0IHRoZSBzeXNtZW51ICovCgloU3lzTWVudSA9IEdldFN5c3RlbU1lbnUoaHduZCwgRkFMU0UpOwoJc3RhdGUgPSBHZXRNZW51U3RhdGUoaFN5c01lbnUsIFNDX0NMT1NFLCBNRl9CWUNPTU1BTkQpOwoKCS8qIERyYXcgYSBncmF5ZWQgY2xvc2UgYnV0dG9uIGlmIGRpc2FibGVkIGFuZCBhIG5vcm1hbCBvbmUgaWYgU0NfQ0xPU0UgaXMgbm90IHRoZXJlICovCglOQ19EcmF3Q2xvc2VCdXR0b245NSAoaHduZCwgaGRjLCBGQUxTRSwgCgkJCSAgICAgICgoKChzdGF0ZSAmIE1GX0RJU0FCTEVEKSB8fCAoc3RhdGUgJiBNRl9HUkFZRUQpKSkgJiYgKHN0YXRlICE9IDB4RkZGRkZGRkYpKSk7CglyLnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIDE7CgoJaWYgKChzdHlsZSAmIFdTX01BWElNSVpFQk9YKSB8fCAoc3R5bGUgJiBXU19NSU5JTUlaRUJPWCkpCgl7CgkgICAgLyogSW4gd2luOTUgdGhlIHR3byBidXR0b25zIGFyZSBhbHdheXMgdGhlcmUgKi8KCSAgICAvKiBCdXQgaWYgdGhlIG1lbnUgaXRlbSBpcyBub3QgaW4gdGhlIG1lbnUgdGhleSdyZSBkaXNhYmxlZCovCgoJICAgIE5DX0RyYXdNYXhCdXR0b245NSggaHduZCwgaGRjLCBGQUxTRSwgKCEoc3R5bGUgJiBXU19NQVhJTUlaRUJPWCkpKTsKCSAgICByLnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CgkgICAgCgkgICAgTkNfRHJhd01pbkJ1dHRvbjk1KCBod25kLCBoZGMsIEZBTFNFLCAgKCEoc3R5bGUgJiBXU19NSU5JTUlaRUJPWCkpKTsKCSAgICByLnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7Cgl9CiAgICB9CgogICAgaWYgKEdldFdpbmRvd1RleHRBKCBod25kLCBidWZmZXIsIHNpemVvZihidWZmZXIpICkpIHsKCU5PTkNMSUVOVE1FVFJJQ1NBIG5jbG07CglIRk9OVCBoRm9udCwgaE9sZEZvbnQ7CgluY2xtLmNiU2l6ZSA9IHNpemVvZihOT05DTElFTlRNRVRSSUNTQSk7CglTeXN0ZW1QYXJhbWV0ZXJzSW5mb0EgKFNQSV9HRVROT05DTElFTlRNRVRSSUNTLCAwLCAmbmNsbSwgMCk7CglpZiAoZXhTdHlsZSAmIFdTX0VYX1RPT0xXSU5ET1cpCgkgICAgaEZvbnQgPSBDcmVhdGVGb250SW5kaXJlY3RBICgmbmNsbS5sZlNtQ2FwdGlvbkZvbnQpOwoJZWxzZQoJICAgIGhGb250ID0gQ3JlYXRlRm9udEluZGlyZWN0QSAoJm5jbG0ubGZDYXB0aW9uRm9udCk7CgloT2xkRm9udCA9IFNlbGVjdE9iamVjdCAoaGRjLCBoRm9udCk7CglpZiAoYWN0aXZlKSBTZXRUZXh0Q29sb3IoIGhkYywgR2V0U3lzQ29sb3IoIENPTE9SX0NBUFRJT05URVhUICkgKTsKCWVsc2UgU2V0VGV4dENvbG9yKCBoZGMsIEdldFN5c0NvbG9yKCBDT0xPUl9JTkFDVElWRUNBUFRJT05URVhUICkgKTsKCVNldEJrTW9kZSggaGRjLCBUUkFOU1BBUkVOVCApOwoJci5sZWZ0ICs9IDI7CglEcmF3VGV4dEEoIGhkYywgYnVmZmVyLCAtMSwgJnIsCgkJICAgICBEVF9TSU5HTEVMSU5FIHwgRFRfVkNFTlRFUiB8IERUX05PUFJFRklYIHwgRFRfTEVGVCApOwoJRGVsZXRlT2JqZWN0IChTZWxlY3RPYmplY3QgKGhkYywgaE9sZEZvbnQpKTsKICAgIH0KfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0RvTkNQYWludAogKgogKiBQYWludCB0aGUgbm9uLWNsaWVudCBhcmVhLiBjbGlwIGlzIGN1cnJlbnRseSB1bnVzZWQuCiAqLwpzdGF0aWMgdm9pZCBOQ19Eb05DUGFpbnQoIEhXTkQgaHduZCwgSFJHTiBjbGlwLCBCT09MIHN1cHByZXNzX21lbnVwYWludCApCnsKICAgIEhEQyBoZGM7CiAgICBSRUNUIHJlY3Q7CiAgICBCT09MIGFjdGl2ZTsKICAgIFdORCAqd25kUHRyOwogICAgRFdPUkQgZHdTdHlsZSwgZHdFeFN0eWxlOwogICAgV09SRCBmbGFnczsKICAgIFJFQ1QgcmVjdENsaWVudCwgcmVjdFdpbmRvdzsKICAgIGludCBoYXNfbWVudTsKCiAgICBpZiAoISh3bmRQdHIgPSBXSU5fR2V0UHRyKCBod25kICkpIHx8IHduZFB0ciA9PSBXTkRfT1RIRVJfUFJPQ0VTUykgcmV0dXJuOwogICAgaGFzX21lbnUgPSBIQVNfTUVOVSh3bmRQdHIpOwogICAgZHdTdHlsZSA9IHduZFB0ci0+ZHdTdHlsZTsKICAgIGR3RXhTdHlsZSA9IHduZFB0ci0+ZHdFeFN0eWxlOyAgICAKICAgIGZsYWdzID0gd25kUHRyLT5mbGFnczsKICAgIHJlY3RDbGllbnQgPSB3bmRQdHItPnJlY3RDbGllbnQ7CiAgICByZWN0V2luZG93ID0gd25kUHRyLT5yZWN0V2luZG93OwogICAgV0lOX1JlbGVhc2VQdHIoIHduZFB0ciApOwoKICAgIGlmICggZHdTdHlsZSAmIFdTX01JTklNSVpFIHx8CiAgICAgICAgICFXSU5fSXNXaW5kb3dEcmF3YWJsZSggaHduZCwgMCApKSByZXR1cm47IC8qIE5vdGhpbmcgdG8gZG8gKi8KCiAgICBhY3RpdmUgID0gZmxhZ3MgJiBXSU5fTkNBQ1RJVkFURUQ7CgogICAgVFJBQ0UoIiUwNHggJWRcbiIsIGh3bmQsIGFjdGl2ZSApOwoKICAgIGlmICghKGhkYyA9IEdldERDRXgoIGh3bmQsIChjbGlwID4gMSkgPyBjbGlwIDogMCwgRENYX1VTRVNUWUxFIHwgRENYX1dJTkRPVyB8CgkJCSAgICAgICgoY2xpcCA+IDEpID8gKERDWF9JTlRFUlNFQ1RSR04gfCBEQ1hfS0VFUENMSVBSR04pOiAwKSApKSkgcmV0dXJuOwoKICAgIGlmIChFeGNsdWRlVmlzUmVjdDE2KCBoZGMsIHJlY3RDbGllbnQubGVmdC1yZWN0V2luZG93LmxlZnQsCgkJICAgICAgICByZWN0Q2xpZW50LnRvcC1yZWN0V2luZG93LnRvcCwKCQkgICAgICAgIHJlY3RDbGllbnQucmlnaHQtcmVjdFdpbmRvdy5sZWZ0LAoJCSAgICAgICAgcmVjdENsaWVudC5ib3R0b20tcmVjdFdpbmRvdy50b3AgKQoJPT0gTlVMTFJFR0lPTikKICAgIHsKCVJlbGVhc2VEQyggaHduZCwgaGRjICk7CglyZXR1cm47CiAgICB9CgogICAgcmVjdC50b3AgPSByZWN0LmxlZnQgPSAwOwogICAgcmVjdC5yaWdodCAgPSByZWN0V2luZG93LnJpZ2h0IC0gcmVjdFdpbmRvdy5sZWZ0OwogICAgcmVjdC5ib3R0b20gPSByZWN0V2luZG93LmJvdHRvbSAtIHJlY3RXaW5kb3cudG9wOwoKICAgIFNlbGVjdE9iamVjdCggaGRjLCBHZXRTeXNDb2xvclBlbihDT0xPUl9XSU5ET1dGUkFNRSkgKTsKCiAgICBpZiAoSEFTX0FOWUZSQU1FKCBkd1N0eWxlLCBkd0V4U3R5bGUgKSkKICAgIHsKICAgICAgICBTZWxlY3RPYmplY3QoIGhkYywgR2V0U3RvY2tPYmplY3QoTlVMTF9CUlVTSCkgKTsKICAgICAgICBSZWN0YW5nbGUoIGhkYywgMCwgMCwgcmVjdC5yaWdodCwgcmVjdC5ib3R0b20gKTsKICAgICAgICBJbmZsYXRlUmVjdCggJnJlY3QsIC0xLCAtMSApOwogICAgfQoKICAgIGlmIChIQVNfVEhJQ0tGUkFNRSggZHdTdHlsZSwgZHdFeFN0eWxlICkpCiAgICAgICAgTkNfRHJhd0ZyYW1lKGhkYywgJnJlY3QsIEZBTFNFLCBhY3RpdmUgKTsKICAgIGVsc2UgaWYgKEhBU19ETEdGUkFNRSggZHdTdHlsZSwgZHdFeFN0eWxlICkpCiAgICAgICAgTkNfRHJhd0ZyYW1lKCBoZGMsICZyZWN0LCBUUlVFLCBhY3RpdmUgKTsKCiAgICBpZiAoKGR3U3R5bGUgJiBXU19DQVBUSU9OKSA9PSBXU19DQVBUSU9OKQogICAgewogICAgICAgIFJFQ1QgciA9IHJlY3Q7CiAgICAgICAgci5ib3R0b20gPSByZWN0LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKTsKICAgICAgICByZWN0LnRvcCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKTsKICAgICAgICBOQ19EcmF3Q2FwdGlvbiggaGRjLCAmciwgaHduZCwgZHdTdHlsZSwgYWN0aXZlICk7CiAgICB9CgogICAgaWYgKGhhc19tZW51KQogICAgewoJUkVDVCByID0gcmVjdDsKCXIuYm90dG9tID0gcmVjdC50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZTUVOVSk7ICAvKiBkZWZhdWx0IGhlaWdodCAqLwoJcmVjdC50b3AgKz0gTUVOVV9EcmF3TWVudUJhciggaGRjLCAmciwgaHduZCwgc3VwcHJlc3NfbWVudXBhaW50ICk7CiAgICB9CgogICAgICAvKiBEcmF3IHRoZSBzY3JvbGwtYmFycyAqLwoKICAgIGlmIChkd1N0eWxlICYgV1NfVlNDUk9MTCkKICAgICAgICBTQ1JPTExfRHJhd1Njcm9sbEJhciggaHduZCwgaGRjLCBTQl9WRVJULCBUUlVFLCBUUlVFICk7CiAgICBpZiAoZHdTdHlsZSAmIFdTX0hTQ1JPTEwpCiAgICAgICAgU0NST0xMX0RyYXdTY3JvbGxCYXIoIGh3bmQsIGhkYywgU0JfSE9SWiwgVFJVRSwgVFJVRSApOwoKICAgICAgLyogRHJhdyB0aGUgInNpemUtYm94IiAqLwoKICAgIGlmICgoZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpICYmIChkd1N0eWxlICYgV1NfSFNDUk9MTCkpCiAgICB7CiAgICAgICAgUkVDVCByID0gcmVjdDsKICAgICAgICByLmxlZnQgPSByLnJpZ2h0IC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpICsgMTsKICAgICAgICByLnRvcCAgPSByLmJvdHRvbSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lIU0NST0xMKSArIDE7CglpZih3bmRQdHItPmR3U3R5bGUgJiBXU19CT1JERVIpIHsKCSAgci5sZWZ0Kys7CgkgIHIudG9wKys7Cgl9CiAgICAgICAgRmlsbFJlY3QoIGhkYywgJnIsIEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfU0NST0xMQkFSKSApOwogICAgfSAgICAKCiAgICBSZWxlYXNlREMoIGh3bmQsIGhkYyApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIHZvaWQgIE5DX0RvTkNQYWludDk1KAogKiAgICAgIEhXTkQgIGh3bmQsCiAqICAgICAgSFJHTiAgY2xpcCwKICogICAgICBCT09MICBzdXBwcmVzc19tZW51cGFpbnQgKQogKgogKiAgIFBhaW50IHRoZSBub24tY2xpZW50IGFyZWEgZm9yIFdpbjk1IHdpbmRvd3MuICBUaGUgY2xpcCByZWdpb24gaXMKICogICBjdXJyZW50bHkgaWdub3JlZC4KICoKICogICBCdWdzCiAqICAgICAgICBncmVwIC1FIC1BMTAgLUI1IFwoOTVcKVx8XChCdWdzXClcfFwoRklYTUVcKSB3aW5kb3dzL25vbmNsaWVudC5jIFwKICogICAgICAgICAgIG1pc2MvdHdlYWsuYyBjb250cm9scy9tZW51LmMgICMgOi0pCiAqCiAqICAgUmV2aXNpb24gaGlzdG9yeQogKiAgICAgICAgMDMtSnVsLTE5OTcgRGF2ZSBDdXRoYmVydCAoZGFjdXRAZWNlLmNtdS5lZHUpCiAqICAgICAgICAgICAgIE9yaWdpbmFsIGltcGxlbWVudGF0aW9uCiAqICAgICAgICAxMC1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgICAgICBGaXhlZCBzb21lIGJ1Z3MuCiAqICAgICAgICAyOS1KdW4tMTk5OSBPdmUgS+V2ZW4gKG92ZWtAYXJjdGljbmV0Lm5vKQogKiAgICAgICAgICAgICBTdHJlYW1saW5lZCB3aW5kb3cgc3R5bGUgY2hlY2tzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZCAgTkNfRG9OQ1BhaW50OTUoCiAgICBIV05EICBod25kLAogICAgSFJHTiAgY2xpcCwKICAgIEJPT0wgIHN1cHByZXNzX21lbnVwYWludCApCnsKICAgIEhEQyBoZGM7CiAgICBSRUNUIHJmdXp6LCByZWN0LCByZWN0Q2xpcDsKICAgIEJPT0wgYWN0aXZlOwogICAgV05EICp3bmRQdHI7CiAgICBEV09SRCBkd1N0eWxlLCBkd0V4U3R5bGU7CiAgICBXT1JEIGZsYWdzOwogICAgUkVDVCByZWN0Q2xpZW50LCByZWN0V2luZG93OwogICAgaW50IGhhc19tZW51OwoKICAgIGlmICghKHduZFB0ciA9IFdJTl9HZXRQdHIoIGh3bmQgKSkgfHwgd25kUHRyID09IFdORF9PVEhFUl9QUk9DRVNTKSByZXR1cm47CiAgICBoYXNfbWVudSA9IEhBU19NRU5VKHduZFB0cik7CiAgICBkd1N0eWxlID0gd25kUHRyLT5kd1N0eWxlOwogICAgZHdFeFN0eWxlID0gd25kUHRyLT5kd0V4U3R5bGU7ICAgIAogICAgZmxhZ3MgPSB3bmRQdHItPmZsYWdzOwogICAgcmVjdENsaWVudCA9IHduZFB0ci0+cmVjdENsaWVudDsKICAgIHJlY3RXaW5kb3cgPSB3bmRQdHItPnJlY3RXaW5kb3c7CiAgICBXSU5fUmVsZWFzZVB0ciggd25kUHRyICk7CgogICAgaWYgKCBkd1N0eWxlICYgV1NfTUlOSU1JWkUgfHwKICAgICAgICAgIVdJTl9Jc1dpbmRvd0RyYXdhYmxlKCBod25kLCAwICkpIHJldHVybjsgLyogTm90aGluZyB0byBkbyAqLwoKICAgIGFjdGl2ZSAgPSBmbGFncyAmIFdJTl9OQ0FDVElWQVRFRDsKCiAgICBUUkFDRSgiJTA0eCAlZFxuIiwgaHduZCwgYWN0aXZlICk7CgogICAgLyogTVNETiBkb2NzIGFyZSBwcmV0dHkgaWRpb3RpYyBoZXJlLCB0aGV5IHNheSBhcHAgQ0FOIHVzZSBjbGlwUmduIGluCiAgICAgICB0aGUgY2FsbCB0byBHZXREQ0V4IGltcGx5aW5nIHRoYXQgaXQgaXMgYWxsb3dlZCBub3QgdG8gdXNlIGl0IGVpdGhlci4KICAgICAgIEhvd2V2ZXIsIHRoZSBzdWdnZXN0ZWQgR2V0RENFeCggICAgLCBEQ1hfV0lORE9XIHwgRENYX0lOVEVSU0VDVFJHTikKICAgICAgIHdpbGwgY2F1c2UgY2xpcFJnbiB0byBiZSBkZWxldGVkIGFmdGVyIFJlbGVhc2VEQygpLgogICAgICAgTm93LCBob3cgaXMgdGhlICJzeXN0ZW0iIHN1cHBvc2VkIHRvIHRlbGwgd2hhdCBoYXBwZW5lZD8KICAgICAqLwoKICAgIGlmICghKGhkYyA9IEdldERDRXgoIGh3bmQsIChjbGlwID4gMSkgPyBjbGlwIDogMCwgRENYX1VTRVNUWUxFIHwgRENYX1dJTkRPVyB8CgkJCSAgICAgICgoY2xpcCA+IDEpID8oRENYX0lOVEVSU0VDVFJHTiB8IERDWF9LRUVQQ0xJUFJHTikgOiAwKSApKSkgcmV0dXJuOwoKCiAgICBpZiAoRXhjbHVkZVZpc1JlY3QxNiggaGRjLCByZWN0Q2xpZW50LmxlZnQtcmVjdFdpbmRvdy5sZWZ0LAoJCSAgICAgICAgcmVjdENsaWVudC50b3AtcmVjdFdpbmRvdy50b3AsCgkJICAgICAgICByZWN0Q2xpZW50LnJpZ2h0LXJlY3RXaW5kb3cubGVmdCwKCQkgICAgICAgIHJlY3RDbGllbnQuYm90dG9tLXJlY3RXaW5kb3cudG9wICkKCT09IE5VTExSRUdJT04pCiAgICB7CglSZWxlYXNlREMoIGh3bmQsIGhkYyApOwoJcmV0dXJuOwogICAgfQoKICAgIHJlY3QudG9wID0gcmVjdC5sZWZ0ID0gMDsKICAgIHJlY3QucmlnaHQgID0gcmVjdFdpbmRvdy5yaWdodCAtIHJlY3RXaW5kb3cubGVmdDsKICAgIHJlY3QuYm90dG9tID0gcmVjdFdpbmRvdy5ib3R0b20gLSByZWN0V2luZG93LnRvcDsKCiAgICBpZiggY2xpcCA+IDEgKQoJR2V0UmduQm94KCBjbGlwLCAmcmVjdENsaXAgKTsKICAgIGVsc2UKICAgIHsKCWNsaXAgPSAwOwoJcmVjdENsaXAgPSByZWN0OwogICAgfQoKICAgIFNlbGVjdE9iamVjdCggaGRjLCBHZXRTeXNDb2xvclBlbihDT0xPUl9XSU5ET1dGUkFNRSkgKTsKCiAgICBpZiAoSEFTX1NUQVRJQ09VVEVSRlJBTUUoZHdTdHlsZSwgZHdFeFN0eWxlKSkgewogICAgICAgIERyYXdFZGdlIChoZGMsICZyZWN0LCBCRFJfU1VOS0VOT1VURVIsIEJGX1JFQ1QgfCBCRl9BREpVU1QpOwogICAgfQogICAgZWxzZSBpZiAoSEFTX0JJR0ZSQU1FKCBkd1N0eWxlLCBkd0V4U3R5bGUpKSB7CiAgICAgICAgRHJhd0VkZ2UgKGhkYywgJnJlY3QsIEVER0VfUkFJU0VELCBCRl9SRUNUIHwgQkZfQURKVVNUKTsKICAgIH0KCiAgICBOQ19EcmF3RnJhbWU5NShoZGMsICZyZWN0LCBhY3RpdmUsIGR3U3R5bGUsIGR3RXhTdHlsZSApOwoKICAgIGlmICgoZHdTdHlsZSAmIFdTX0NBUFRJT04pID09IFdTX0NBUFRJT04pCiAgICB7CiAgICAgICAgUkVDVCAgciA9IHJlY3Q7CiAgICAgICAgaWYgKGR3RXhTdHlsZSAmIFdTX0VYX1RPT0xXSU5ET1cpIHsKICAgICAgICAgICAgci5ib3R0b20gPSByZWN0LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUNBUFRJT04pOwogICAgICAgICAgICByZWN0LnRvcCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01DQVBUSU9OKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHIuYm90dG9tID0gcmVjdC50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTik7CiAgICAgICAgICAgIHJlY3QudG9wICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKTsKICAgICAgICB9CiAgICAgICAgaWYoICFjbGlwIHx8IEludGVyc2VjdFJlY3QoICZyZnV6eiwgJnIsICZyZWN0Q2xpcCApICkKICAgICAgICAgICAgTkNfRHJhd0NhcHRpb245NSAoaGRjLCAmciwgaHduZCwgZHdTdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdFeFN0eWxlLCBhY3RpdmUpOwogICAgfQoKICAgIGlmIChoYXNfbWVudSkKICAgIHsKCVJFQ1QgciA9IHJlY3Q7CglyLmJvdHRvbSA9IHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWU1FTlUpOwoJCglUUkFDRSgiQ2FsbGluZyBEcmF3TWVudUJhciB3aXRoIHJlY3QgKCVkLCAlZCktKCVkLCAlZClcbiIsCiAgICAgICAgICAgICAgci5sZWZ0LCByLnRvcCwgci5yaWdodCwgci5ib3R0b20pOwoKCXJlY3QudG9wICs9IE1FTlVfRHJhd01lbnVCYXIoIGhkYywgJnIsIGh3bmQsIHN1cHByZXNzX21lbnVwYWludCApICsgMTsKICAgIH0KCiAgICBUUkFDRSgiQWZ0ZXIgTWVudUJhciwgcmVjdCBpcyAoJWQsICVkKS0oJWQsICVkKS5cbiIsCiAgICAgICAgICByZWN0LmxlZnQsIHJlY3QudG9wLCByZWN0LnJpZ2h0LCByZWN0LmJvdHRvbSApOwoKICAgIGlmIChkd0V4U3R5bGUgJiBXU19FWF9DTElFTlRFREdFKQoJRHJhd0VkZ2UgKGhkYywgJnJlY3QsIEVER0VfU1VOS0VOLCBCRl9SRUNUIHwgQkZfQURKVVNUKTsKCiAgICAvKiBEcmF3IHRoZSBzY3JvbGwtYmFycyAqLwoKICAgIGlmIChkd1N0eWxlICYgV1NfVlNDUk9MTCkKICAgICAgICBTQ1JPTExfRHJhd1Njcm9sbEJhciggaHduZCwgaGRjLCBTQl9WRVJULCBUUlVFLCBUUlVFICk7CiAgICBpZiAoZHdTdHlsZSAmIFdTX0hTQ1JPTEwpCiAgICAgICAgU0NST0xMX0RyYXdTY3JvbGxCYXIoIGh3bmQsIGhkYywgU0JfSE9SWiwgVFJVRSwgVFJVRSApOwoKICAgIC8qIERyYXcgdGhlICJzaXplLWJveCIgKi8KICAgIGlmICgoZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpICYmIChkd1N0eWxlICYgV1NfSFNDUk9MTCkpCiAgICB7CiAgICAgICAgUkVDVCByID0gcmVjdDsKICAgICAgICByLmxlZnQgPSByLnJpZ2h0IC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpICsgMTsKICAgICAgICByLnRvcCAgPSByLmJvdHRvbSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lIU0NST0xMKSArIDE7CiAgICAgICAgRmlsbFJlY3QoIGhkYywgJnIsICBHZXRTeXNDb2xvckJydXNoKENPTE9SX1NDUk9MTEJBUikgKTsKICAgIH0gICAgCgogICAgUmVsZWFzZURDKCBod25kLCBoZGMgKTsKfQoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19IYW5kbGVOQ1BhaW50CiAqCiAqIEhhbmRsZSBhIFdNX05DUEFJTlQgbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVOQ1BhaW50KCBIV05EIGh3bmQgLCBIUkdOIGNsaXApCnsKICAgIERXT1JEIGR3U3R5bGUgPSBHZXRXaW5kb3dMb25nVyggaHduZCwgR1dMX1NUWUxFICk7CgogICAgaWYoIGR3U3R5bGUgJiBXU19WSVNJQkxFICkKICAgIHsKCWlmKCBkd1N0eWxlICYgV1NfTUlOSU1JWkUgKQoJICAgIFdJTlBPU19SZWRyYXdJY29uVGl0bGUoIGh3bmQgKTsKCWVsc2UgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCgkgICAgTkNfRG9OQ1BhaW50KCBod25kLCBjbGlwLCBGQUxTRSApOwoJZWxzZQoJICAgIE5DX0RvTkNQYWludDk1KCBod25kLCBjbGlwLCBGQUxTRSApOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZU5DQWN0aXZhdGUKICoKICogSGFuZGxlIGEgV01fTkNBQ1RJVkFURSBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZU5DQWN0aXZhdGUoIEhXTkQgaHduZCwgV1BBUkFNIHdQYXJhbSApCnsKICAgIFdORCogd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICAvKiBMb3R1cyBOb3RlcyBkcmF3cyBtZW51IGRlc2NyaXB0aW9ucyBpbiB0aGUgY2FwdGlvbiBvZiBpdHMgbWFpbgogICAgICogd2luZG93LiBXaGVuIGl0IHdhbnRzIHRvIHJlc3RvcmUgb3JpZ2luYWwgInN5c3RlbSIgdmlldywgaXQganVzdAogICAgICogc2VuZHMgV01fTkNBQ1RJVkFURSBtZXNzYWdlIHRvIGl0c2VsZi4gQW55IG9wdGltaXphdGlvbnMgaGVyZSBpbgogICAgICogYXR0ZW1wdCB0byBtaW5pbWl6ZSByZWRyYXdpbmdzIGxlYWQgdG8gYSBub3QgcmVzdG9yZWQgY2FwdGlvbi4KICAgICAqLwogICAgaWYgKHduZFB0cikKICAgIHsKCWlmICh3UGFyYW0pIHduZFB0ci0+ZmxhZ3MgfD0gV0lOX05DQUNUSVZBVEVEOwoJZWxzZSB3bmRQdHItPmZsYWdzICY9IH5XSU5fTkNBQ1RJVkFURUQ7CiAgICAgICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKCglpZiAoSXNJY29uaWMoaHduZCkpIFdJTlBPU19SZWRyYXdJY29uVGl0bGUoIGh3bmQgKTsKCWVsc2UgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCgkgICAgTkNfRG9OQ1BhaW50KCBod25kLCAoSFJHTikxLCBGQUxTRSApOwoJZWxzZQoJICAgIE5DX0RvTkNQYWludDk1KCBod25kLCAoSFJHTikxLCBGQUxTRSApOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZVNldEN1cnNvcgogKgogKiBIYW5kbGUgYSBXTV9TRVRDVVJTT1IgbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVTZXRDdXJzb3IoIEhXTkQgaHduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSApCnsKICAgIGlmIChod25kICE9IFdJTl9HZXRGdWxsSGFuZGxlKCAoSFdORCl3UGFyYW0gKSkKICAgICAgICByZXR1cm4gMDsgIC8qIERvbid0IHNldCB0aGUgY3Vyc29yIGZvciBjaGlsZCB3aW5kb3dzICovCgogICAgc3dpdGNoKExPV09SRChsUGFyYW0pKQogICAgewogICAgY2FzZSBIVEVSUk9SOgoJewoJICAgIFdPUkQgbXNnID0gSElXT1JEKCBsUGFyYW0gKTsKCSAgICBpZiAoKG1zZyA9PSBXTV9MQlVUVE9ORE9XTikgfHwgKG1zZyA9PSBXTV9NQlVUVE9ORE9XTikgfHwKCQkobXNnID09IFdNX1JCVVRUT05ET1dOKSkKCQlNZXNzYWdlQmVlcCgwKTsKCX0KCWJyZWFrOwoKICAgIGNhc2UgSFRDTElFTlQ6Cgl7CgkgICAgSENVUlNPUiBoQ3Vyc29yID0gR2V0Q2xhc3NMb25nQShod25kLCBHQ0xfSENVUlNPUik7CgkgICAgaWYoaEN1cnNvcikgewoJCVNldEN1cnNvcihoQ3Vyc29yKTsKCQlyZXR1cm4gVFJVRTsKCSAgICB9CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCX0KCiAgICBjYXNlIEhUTEVGVDoKICAgIGNhc2UgSFRSSUdIVDoKCXJldHVybiAoTE9ORylTZXRDdXJzb3IoIExvYWRDdXJzb3JBKCAwLCBJRENfU0laRVdFQSApICk7CgogICAgY2FzZSBIVFRPUDoKICAgIGNhc2UgSFRCT1RUT006CglyZXR1cm4gKExPTkcpU2V0Q3Vyc29yKCBMb2FkQ3Vyc29yQSggMCwgSURDX1NJWkVOU0EgKSApOwoKICAgIGNhc2UgSFRUT1BMRUZUOgogICAgY2FzZSBIVEJPVFRPTVJJR0hUOgkKCXJldHVybiAoTE9ORylTZXRDdXJzb3IoIExvYWRDdXJzb3JBKCAwLCBJRENfU0laRU5XU0VBICkgKTsKCiAgICBjYXNlIEhUVE9QUklHSFQ6CiAgICBjYXNlIEhUQk9UVE9NTEVGVDoKCXJldHVybiAoTE9ORylTZXRDdXJzb3IoIExvYWRDdXJzb3JBKCAwLCBJRENfU0laRU5FU1dBICkgKTsKICAgIH0KCiAgICAvKiBEZWZhdWx0IGN1cnNvcjogYXJyb3cgKi8KICAgIHJldHVybiAoTE9ORylTZXRDdXJzb3IoIExvYWRDdXJzb3JBKCAwLCBJRENfQVJST1dBICkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19HZXRTeXNQb3B1cFBvcwogKi8Kdm9pZCBOQ19HZXRTeXNQb3B1cFBvcyggSFdORCBod25kLCBSRUNUKiByZWN0ICkKewogICAgaWYgKElzSWNvbmljKGh3bmQpKSBHZXRXaW5kb3dSZWN0KCBod25kLCByZWN0ICk7CiAgICBlbHNlCiAgICB7CiAgICAgICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwogICAgICAgIGlmICghd25kUHRyKSByZXR1cm47CgogICAgICAgIE5DX0dldEluc2lkZVJlY3QoIGh3bmQsIHJlY3QgKTsKICAgICAgICBPZmZzZXRSZWN0KCByZWN0LCB3bmRQdHItPnJlY3RXaW5kb3cubGVmdCwgd25kUHRyLT5yZWN0V2luZG93LnRvcCk7CiAgICAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NISUxEKQogICAgICAgICAgICBDbGllbnRUb1NjcmVlbiggR2V0UGFyZW50KGh3bmQpLCAoUE9JTlQgKilyZWN0ICk7CiAgICAgICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spIHsKICAgICAgICAgICAgcmVjdC0+cmlnaHQgPSByZWN0LT5sZWZ0ICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpOwogICAgICAgICAgICByZWN0LT5ib3R0b20gPSByZWN0LT50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICByZWN0LT5yaWdodCA9IHJlY3QtPmxlZnQgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSAxOwogICAgICAgICAgICByZWN0LT5ib3R0b20gPSByZWN0LT50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSAxOwogICAgICAgIH0KICAgICAgICBXSU5fUmVsZWFzZVduZFB0ciggd25kUHRyICk7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfVHJhY2tNaW5NYXhCb3g5NQogKgogKiBUcmFjayBhIG1vdXNlIGJ1dHRvbiBwcmVzcyBvbiB0aGUgbWluaW1pemUgb3IgbWF4aW1pemUgYm94LgogKgogKiBUaGUgYmlnIGRpZmZlcmVuY2UgYmV0d2VlbiAzLjEgYW5kIDk1IGlzIHRoZSBkaXNhYmxlZCBidXR0b24gc3RhdGUuCiAqIEluIHdpbjk1IHRoZSBzeXN0ZW0gYnV0dG9uIGNhbiBiZSBkaXNhYmxlZCwgc28gaXQgY2FuIGlnbm9yZSB0aGUgbW91c2UKICogZXZlbnQuCiAqCiAqLwpzdGF0aWMgdm9pZCBOQ19UcmFja01pbk1heEJveDk1KCBIV05EIGh3bmQsIFdPUkQgd1BhcmFtICkKewogICAgTVNHIG1zZzsKICAgIEhEQyBoZGMgPSBHZXRXaW5kb3dEQyggaHduZCApOwogICAgQk9PTCBwcmVzc2VkID0gVFJVRTsKICAgIFVJTlQgc3RhdGU7CiAgICBEV09SRCB3bmRTdHlsZSA9IEdldFdpbmRvd0xvbmdBKCBod25kLCBHV0xfU1RZTEUpOwogICAgSE1FTlUgaFN5c01lbnUgPSBHZXRTeXN0ZW1NZW51KGh3bmQsIEZBTFNFKTsKCiAgICB2b2lkICAoKnBhaW50QnV0dG9uKShIV05ELCBIREMxNiwgQk9PTCwgQk9PTCk7CgogICAgaWYgKHdQYXJhbSA9PSBIVE1JTkJVVFRPTikKICAgIHsKCS8qIElmIHRoZSBzdHlsZSBpcyBub3QgcHJlc2VudCwgZG8gbm90aGluZyAqLwoJaWYgKCEod25kU3R5bGUgJiBXU19NSU5JTUlaRUJPWCkpCgkgICAgcmV0dXJuOwoKCS8qIENoZWNrIGlmIHRoZSBzeXNtZW51IGl0ZW0gZm9yIG1pbmltaXplIGlzIHRoZXJlICAqLwoJc3RhdGUgPSBHZXRNZW51U3RhdGUoaFN5c01lbnUsIFNDX01JTklNSVpFLCBNRl9CWUNPTU1BTkQpOwoJCglwYWludEJ1dHRvbiA9ICZOQ19EcmF3TWluQnV0dG9uOTU7CiAgICB9CiAgICBlbHNlCiAgICB7CgkvKiBJZiB0aGUgc3R5bGUgaXMgbm90IHByZXNlbnQsIGRvIG5vdGhpbmcgKi8KCWlmICghKHduZFN0eWxlICYgV1NfTUFYSU1JWkVCT1gpKQoJICAgIHJldHVybjsKCgkvKiBDaGVjayBpZiB0aGUgc3lzbWVudSBpdGVtIGZvciBtYXhpbWl6ZSBpcyB0aGVyZSAgKi8KCXN0YXRlID0gR2V0TWVudVN0YXRlKGhTeXNNZW51LCBTQ19NQVhJTUlaRSwgTUZfQllDT01NQU5EKTsKCQoJcGFpbnRCdXR0b24gPSAmTkNfRHJhd01heEJ1dHRvbjk1OwogICAgfQoKICAgIFNldENhcHR1cmUoIGh3bmQgKTsKCiAgICAoKnBhaW50QnV0dG9uKSggaHduZCwgaGRjLCBUUlVFLCBGQUxTRSk7CgogICAgd2hpbGUoMSkKICAgIHsKCUJPT0wgb2xkc3RhdGUgPSBwcmVzc2VkOwoKICAgICAgICBpZiAoIUdldE1lc3NhZ2VXKCAmbXNnLCAwLCBXTV9NT1VTRUZJUlNULCBXTV9NT1VTRUxBU1QgKSkgYnJlYWs7CiAgICAgICAgaWYgKENhbGxNc2dGaWx0ZXJXKCAmbXNnLCBNU0dGX01BWCApKSBjb250aW51ZTsKCglpZihtc2cubWVzc2FnZSA9PSBXTV9MQlVUVE9OVVApCgkgICAgYnJlYWs7CgoJaWYobXNnLm1lc3NhZ2UgIT0gV01fTU9VU0VNT1ZFKQoJICAgIGNvbnRpbnVlOwoKCXByZXNzZWQgPSAoTkNfSGFuZGxlTkNIaXRUZXN0KCBod25kLCBtc2cucHQgKSA9PSB3UGFyYW0pOwoJaWYgKHByZXNzZWQgIT0gb2xkc3RhdGUpCgkgICAoKnBhaW50QnV0dG9uKSggaHduZCwgaGRjLCBwcmVzc2VkLCBGQUxTRSk7CiAgICB9CgogICAgaWYocHJlc3NlZCkKCSgqcGFpbnRCdXR0b24pKGh3bmQsIGhkYywgRkFMU0UsIEZBTFNFKTsKCiAgICBSZWxlYXNlQ2FwdHVyZSgpOwogICAgUmVsZWFzZURDKCBod25kLCBoZGMgKTsKCiAgICAvKiBJZiB0aGUgaXRlbSBtaW5pbWl6ZSBvciBtYXhpbWl6ZSBvZiB0aGUgc3lzbWVudSBhcmUgbm90IHRoZXJlICovCiAgICAvKiBvciBpZiB0aGUgc3R5bGUgaXMgbm90IHByZXNlbnQsIGRvIG5vdGhpbmcgKi8KICAgIGlmICgoIXByZXNzZWQpIHx8IChzdGF0ZSA9PSAweEZGRkZGRkZGKSkKCXJldHVybjsKCiAgICBpZiAod1BhcmFtID09IEhUTUlOQlVUVE9OKSAKICAgICAgICBTZW5kTWVzc2FnZUEoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX01JTklNSVpFLCBNQUtFTE9ORyhtc2cucHQueCxtc2cucHQueSkgKTsKICAgIGVsc2UKICAgICAgICBTZW5kTWVzc2FnZUEoIGh3bmQsIFdNX1NZU0NPTU1BTkQsCiAgICAgICAgICAgICAgICAgICAgICBJc1pvb21lZChod25kKSA/IFNDX1JFU1RPUkU6U0NfTUFYSU1JWkUsIE1BS0VMT05HKG1zZy5wdC54LG1zZy5wdC55KSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX1RyYWNrTWluTWF4Qm94CiAqCiAqIFRyYWNrIGEgbW91c2UgYnV0dG9uIHByZXNzIG9uIHRoZSBtaW5pbWl6ZSBvciBtYXhpbWl6ZSBib3guCiAqLwpzdGF0aWMgdm9pZCBOQ19UcmFja01pbk1heEJveCggSFdORCBod25kLCBXT1JEIHdQYXJhbSApCnsKICAgIE1TRyBtc2c7CiAgICBIREMgaGRjID0gR2V0V2luZG93REMoIGh3bmQgKTsKICAgIEJPT0wgcHJlc3NlZCA9IFRSVUU7CiAgICB2b2lkICAoKnBhaW50QnV0dG9uKShIV05ELCBIREMxNiwgQk9PTCk7CgogICAgU2V0Q2FwdHVyZSggaHduZCApOwoKICAgIGlmICh3UGFyYW0gPT0gSFRNSU5CVVRUT04pCglwYWludEJ1dHRvbiA9ICZOQ19EcmF3TWluQnV0dG9uOwogICAgZWxzZQoJcGFpbnRCdXR0b24gPSAmTkNfRHJhd01heEJ1dHRvbjsKCiAgICAoKnBhaW50QnV0dG9uKSggaHduZCwgaGRjLCBUUlVFKTsKCiAgICB3aGlsZSgxKQogICAgewoJQk9PTCBvbGRzdGF0ZSA9IHByZXNzZWQ7CgogICAgICAgIGlmICghR2V0TWVzc2FnZVcoICZtc2csIDAsIFdNX01PVVNFRklSU1QsIFdNX01PVVNFTEFTVCApKSBicmVhazsKICAgICAgICBpZiAoQ2FsbE1zZ0ZpbHRlclcoICZtc2csIE1TR0ZfTUFYICkpIGNvbnRpbnVlOwoKCWlmKG1zZy5tZXNzYWdlID09IFdNX0xCVVRUT05VUCkKCSAgICBicmVhazsKCglpZihtc2cubWVzc2FnZSAhPSBXTV9NT1VTRU1PVkUpCgkgICAgY29udGludWU7CgoJcHJlc3NlZCA9IChOQ19IYW5kbGVOQ0hpdFRlc3QoIGh3bmQsIG1zZy5wdCApID09IHdQYXJhbSk7CglpZiAocHJlc3NlZCAhPSBvbGRzdGF0ZSkKCSAgICgqcGFpbnRCdXR0b24pKCBod25kLCBoZGMsIHByZXNzZWQpOwogICAgfQoKICAgIGlmKHByZXNzZWQpCgkoKnBhaW50QnV0dG9uKSggaHduZCwgaGRjLCBGQUxTRSk7CgogICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgIFJlbGVhc2VEQyggaHduZCwgaGRjICk7CgogICAgaWYgKCFwcmVzc2VkKSByZXR1cm47CgogICAgaWYgKHdQYXJhbSA9PSBIVE1JTkJVVFRPTikgCiAgICAgICAgU2VuZE1lc3NhZ2VBKCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19NSU5JTUlaRSwgTUFLRUxPTkcobXNnLnB0LngsbXNnLnB0LnkpICk7CiAgICBlbHNlCiAgICAgICAgU2VuZE1lc3NhZ2VBKCBod25kLCBXTV9TWVNDT01NQU5ELAogICAgICAgICAgICAgICAgICAgICAgSXNab29tZWQoaHduZCkgPyBTQ19SRVNUT1JFOlNDX01BWElNSVpFLCBNQUtFTE9ORyhtc2cucHQueCxtc2cucHQueSkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBOQ19UcmFja0Nsb3NlQnV0dG9uOTUKICoKICogVHJhY2sgYSBtb3VzZSBidXR0b24gcHJlc3Mgb24gdGhlIFdpbjk1IGNsb3NlIGJ1dHRvbi4KICovCnN0YXRpYyB2b2lkCk5DX1RyYWNrQ2xvc2VCdXR0b245NSAoSFdORCBod25kLCBXT1JEIHdQYXJhbSkKewogICAgTVNHIG1zZzsKICAgIEhEQyBoZGM7CiAgICBCT09MIHByZXNzZWQgPSBUUlVFOwogICAgSE1FTlUgaFN5c01lbnUgPSBHZXRTeXN0ZW1NZW51KGh3bmQsIEZBTFNFKTsKICAgIFVJTlQgc3RhdGU7CgogICAgaWYoaFN5c01lbnUgPT0gMCkKCXJldHVybjsKCiAgICBzdGF0ZSA9IEdldE1lbnVTdGF0ZShoU3lzTWVudSwgU0NfQ0xPU0UsIE1GX0JZQ09NTUFORCk7CgkgICAgCiAgICAvKiBJZiB0aGUgaXRlbSBjbG9zZSBvZiB0aGUgc3lzbWVudSBpcyBkaXNhYmxlZCBvciBub3QgdGhlcmUgZG8gbm90aGluZyAqLwogICAgaWYoKHN0YXRlICYgTUZfRElTQUJMRUQpIHx8IChzdGF0ZSAmIE1GX0dSQVlFRCkgfHwgKHN0YXRlID09IDB4RkZGRkZGRkYpKQoJcmV0dXJuOwoKICAgIGhkYyA9IEdldFdpbmRvd0RDKCBod25kICk7CgogICAgU2V0Q2FwdHVyZSggaHduZCApOwoKICAgIE5DX0RyYXdDbG9zZUJ1dHRvbjk1IChod25kLCBoZGMsIFRSVUUsIEZBTFNFKTsKCiAgICB3aGlsZSgxKQogICAgewoJQk9PTCBvbGRzdGF0ZSA9IHByZXNzZWQ7CgogICAgICAgIGlmICghR2V0TWVzc2FnZVcoICZtc2csIDAsIFdNX01PVVNFRklSU1QsIFdNX01PVVNFTEFTVCApKSBicmVhazsKICAgICAgICBpZiAoQ2FsbE1zZ0ZpbHRlclcoICZtc2csIE1TR0ZfTUFYICkpIGNvbnRpbnVlOwoKCWlmKG1zZy5tZXNzYWdlID09IFdNX0xCVVRUT05VUCkKCSAgICBicmVhazsKCglpZihtc2cubWVzc2FnZSAhPSBXTV9NT1VTRU1PVkUpCgkgICAgY29udGludWU7CgoJcHJlc3NlZCA9IChOQ19IYW5kbGVOQ0hpdFRlc3QoIGh3bmQsIG1zZy5wdCApID09IHdQYXJhbSk7CglpZiAocHJlc3NlZCAhPSBvbGRzdGF0ZSkKCSAgIE5DX0RyYXdDbG9zZUJ1dHRvbjk1IChod25kLCBoZGMsIHByZXNzZWQsIEZBTFNFKTsKICAgIH0KCiAgICBpZihwcmVzc2VkKQoJTkNfRHJhd0Nsb3NlQnV0dG9uOTUgKGh3bmQsIGhkYywgRkFMU0UsIEZBTFNFKTsKCiAgICBSZWxlYXNlQ2FwdHVyZSgpOwogICAgUmVsZWFzZURDKCBod25kLCBoZGMgKTsKICAgIGlmICghcHJlc3NlZCkgcmV0dXJuOwoKICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfQ0xPU0UsIE1BS0VMT05HKG1zZy5wdC54LG1zZy5wdC55KSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19UcmFja1Njcm9sbEJhcgogKgogKiBUcmFjayBhIG1vdXNlIGJ1dHRvbiBwcmVzcyBvbiB0aGUgaG9yaXpvbnRhbCBvciB2ZXJ0aWNhbCBzY3JvbGwtYmFyLgogKi8Kc3RhdGljIHZvaWQgTkNfVHJhY2tTY3JvbGxCYXIoIEhXTkQgaHduZCwgV1BBUkFNIHdQYXJhbSwgUE9JTlQgcHQgKQp7CiAgICBJTlQgc2Nyb2xsYmFyOwoKICAgIGlmICgod1BhcmFtICYgMHhmZmYwKSA9PSBTQ19IU0NST0xMKQogICAgewogICAgICAgIGlmICgod1BhcmFtICYgMHgwZikgIT0gSFRIU0NST0xMKSByZXR1cm47CglzY3JvbGxiYXIgPSBTQl9IT1JaOwogICAgfQogICAgZWxzZSAgLyogU0NfVlNDUk9MTCAqLwogICAgewogICAgICAgIGlmICgod1BhcmFtICYgMHgwZikgIT0gSFRWU0NST0xMKSByZXR1cm47CglzY3JvbGxiYXIgPSBTQl9WRVJUOwogICAgfQogICAgU0NST0xMX1RyYWNrU2Nyb2xsQmFyKCBod25kLCBzY3JvbGxiYXIsIHB0ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZU5DTEJ1dHRvbkRvd24KICoKICogSGFuZGxlIGEgV01fTkNMQlVUVE9ORE9XTiBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZU5DTEJ1dHRvbkRvd24oIEhXTkQgaHduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSApCnsKICAgIExPTkcgc3R5bGUgPSBHZXRXaW5kb3dMb25nQSggaHduZCwgR1dMX1NUWUxFICk7CgogICAgc3dpdGNoKHdQYXJhbSkgIC8qIEhpdCB0ZXN0ICovCiAgICB7CiAgICBjYXNlIEhUQ0FQVElPTjoKICAgICAgICB7CiAgICAgICAgICAgIEhXTkQgdG9wID0gR2V0QW5jZXN0b3IoIGh3bmQsIEdBX1JPT1QgKTsKCiAgICAgICAgICAgIGlmKCBXSU5QT1NfU2V0QWN0aXZlV2luZG93KHRvcCwgVFJVRSwgVFJVRSkgfHwgKEdldEFjdGl2ZVdpbmRvdygpID09IHRvcCkgKQogICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VXKCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19NT1ZFICsgSFRDQVBUSU9OLCBsUGFyYW0gKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgIGNhc2UgSFRTWVNNRU5VOgoJIGlmKCBzdHlsZSAmIFdTX1NZU01FTlUgKQoJIHsKCSAgICAgaWYoICEoc3R5bGUgJiBXU19NSU5JTUlaRSkgKQoJICAgICB7CgkJSERDIGhEQyA9IEdldFdpbmRvd0RDKGh3bmQpOwoJCWlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQoJCSAgICBOQ19EcmF3U3lzQnV0dG9uKCBod25kLCBoREMsIFRSVUUgKTsKCQllbHNlCgkJICAgIE5DX0RyYXdTeXNCdXR0b245NSggaHduZCwgaERDLCBUUlVFICk7CgkJUmVsZWFzZURDKCBod25kLCBoREMgKTsKCSAgICAgfQoJICAgICBTZW5kTWVzc2FnZVcoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX01PVVNFTUVOVSArIEhUU1lTTUVOVSwgbFBhcmFtICk7CgkgfQoJIGJyZWFrOwoKICAgIGNhc2UgSFRNRU5VOgoJU2VuZE1lc3NhZ2VXKCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19NT1VTRU1FTlUsIGxQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBIVEhTQ1JPTEw6CglTZW5kTWVzc2FnZVcoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX0hTQ1JPTEwgKyBIVEhTQ1JPTEwsIGxQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBIVFZTQ1JPTEw6CglTZW5kTWVzc2FnZVcoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX1ZTQ1JPTEwgKyBIVFZTQ1JPTEwsIGxQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBIVE1JTkJVVFRPTjoKICAgIGNhc2UgSFRNQVhCVVRUT046CglpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKCSAgICBOQ19UcmFja01pbk1heEJveCggaHduZCwgd1BhcmFtICk7CgllbHNlCgkgICAgTkNfVHJhY2tNaW5NYXhCb3g5NSggaHduZCwgd1BhcmFtICk7CSAgICAKCWJyZWFrOwoKICAgIGNhc2UgSFRDTE9TRToKCWlmIChUV0VBS19XaW5lTG9vayA+PSBXSU45NV9MT09LKQoJICAgIE5DX1RyYWNrQ2xvc2VCdXR0b245NSAoaHduZCwgd1BhcmFtKTsKCWJyZWFrOwoJCiAgICBjYXNlIEhUTEVGVDoKICAgIGNhc2UgSFRSSUdIVDoKICAgIGNhc2UgSFRUT1A6CiAgICBjYXNlIEhUVE9QTEVGVDoKICAgIGNhc2UgSFRUT1BSSUdIVDoKICAgIGNhc2UgSFRCT1RUT006CiAgICBjYXNlIEhUQk9UVE9NTEVGVDoKICAgIGNhc2UgSFRCT1RUT01SSUdIVDoKCS8qIG1ha2Ugc3VyZSBoaXR0ZXN0IGZpdHMgaW50byAweGYgYW5kIGRvZXNuJ3Qgb3ZlcmxhcCB3aXRoIEhUU1lTTUVOVSAqLwoJU2VuZE1lc3NhZ2VXKCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19TSVpFICsgd1BhcmFtIC0gMiwgbFBhcmFtKTsKCWJyZWFrOwoKICAgIGNhc2UgSFRCT1JERVI6CglicmVhazsKICAgIH0KICAgIHJldHVybiAwOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19IYW5kbGVOQ0xCdXR0b25EYmxDbGsKICoKICogSGFuZGxlIGEgV01fTkNMQlVUVE9OREJMQ0xLIG1lc3NhZ2UuIENhbGxlZCBmcm9tIERlZldpbmRvd1Byb2MoKS4KICovCkxPTkcgTkNfSGFuZGxlTkNMQnV0dG9uRGJsQ2xrKCBIV05EIGh3bmQsIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0gKQp7CiAgICAvKgogICAgICogaWYgdGhpcyBpcyBhbiBpY29uLCBzZW5kIGEgcmVzdG9yZSBzaW5jZSB3ZSBhcmUgaGFuZGxpbmcKICAgICAqIGEgZG91YmxlIGNsaWNrCiAgICAgKi8KICAgIGlmIChJc0ljb25pYyhod25kKSkKICAgIHsKICAgICAgICBTZW5kTWVzc2FnZVcoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX1JFU1RPUkUsIGxQYXJhbSApOwogICAgICAgIHJldHVybiAwOwogICAgfSAKCiAgICBzd2l0Y2god1BhcmFtKSAgLyogSGl0IHRlc3QgKi8KICAgIHsKICAgIGNhc2UgSFRDQVBUSU9OOgogICAgICAgIC8qIHN0b3AgcHJvY2Vzc2luZyBpZiBXU19NQVhJTUlaRUJPWCBpcyBtaXNzaW5nICovCiAgICAgICAgaWYgKEdldFdpbmRvd0xvbmdBKCBod25kLCBHV0xfU1RZTEUgKSAmIFdTX01BWElNSVpFQk9YKQogICAgICAgICAgICBTZW5kTWVzc2FnZVcoIGh3bmQsIFdNX1NZU0NPTU1BTkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgSXNab29tZWQoaHduZCkgPyBTQ19SRVNUT1JFIDogU0NfTUFYSU1JWkUsIGxQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBIVFNZU01FTlU6CiAgICAgICAgaWYgKCEoR2V0Q2xhc3NMb25nVyhod25kLCBHQ0xfU1RZTEUpICYgQ1NfTk9DTE9TRSkpCiAgICAgICAgICAgIFNlbmRNZXNzYWdlVyggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfQ0xPU0UsIGxQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBIVEhTQ1JPTEw6CiAgICAgICAgU2VuZE1lc3NhZ2VXKCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19IU0NST0xMICsgSFRIU0NST0xMLCBsUGFyYW0gKTsKCWJyZWFrOwoKICAgIGNhc2UgSFRWU0NST0xMOgogICAgICAgIFNlbmRNZXNzYWdlVyggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfVlNDUk9MTCArIEhUVlNDUk9MTCwgbFBhcmFtICk7CglicmVhazsKICAgIH0KICAgIHJldHVybiAwOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19IYW5kbGVTeXNDb21tYW5kCiAqCiAqIEhhbmRsZSBhIFdNX1NZU0NPTU1BTkQgbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVTeXNDb21tYW5kKCBIV05EIGh3bmQsIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0gKQp7CiAgICBUUkFDRSgiSGFuZGxpbmcgV01fU1lTQ09NTUFORCAleCAlbHhcbiIsIHdQYXJhbSwgbFBhcmFtICk7CgogICAgc3dpdGNoICh3UGFyYW0gJiAweGZmZjApCiAgICB7CiAgICBjYXNlIFNDX1NJWkU6CiAgICBjYXNlIFNDX01PVkU6CiAgICAgICAgaWYgKFVTRVJfRHJpdmVyLnBTeXNDb21tYW5kU2l6ZU1vdmUpCiAgICAgICAgICAgIFVTRVJfRHJpdmVyLnBTeXNDb21tYW5kU2l6ZU1vdmUoIGh3bmQsIHdQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBTQ19NSU5JTUlaRToKICAgICAgICBpZiAoaHduZCA9PSBHZXRGb3JlZ3JvdW5kV2luZG93KCkpCiAgICAgICAgICAgIFNob3dPd25lZFBvcHVwcyhod25kLEZBTFNFKTsKCVNob3dXaW5kb3coIGh3bmQsIFNXX01JTklNSVpFICk7IAoJYnJlYWs7CgogICAgY2FzZSBTQ19NQVhJTUlaRToKICAgICAgICBpZiAoSXNJY29uaWMoaHduZCkgJiYgaHduZCA9PSBHZXRGb3JlZ3JvdW5kV2luZG93KCkpCiAgICAgICAgICAgIFNob3dPd25lZFBvcHVwcyhod25kLFRSVUUpOwoJU2hvd1dpbmRvdyggaHduZCwgU1dfTUFYSU1JWkUgKTsKCWJyZWFrOwoKICAgIGNhc2UgU0NfUkVTVE9SRToKICAgICAgICBpZiAoSXNJY29uaWMoaHduZCkgJiYgaHduZCA9PSBHZXRGb3JlZ3JvdW5kV2luZG93KCkpCiAgICAgICAgICAgIFNob3dPd25lZFBvcHVwcyhod25kLFRSVUUpOwoJU2hvd1dpbmRvdyggaHduZCwgU1dfUkVTVE9SRSApOwoJYnJlYWs7CgogICAgY2FzZSBTQ19DTE9TRToKCXJldHVybiBTZW5kTWVzc2FnZUEoIGh3bmQsIFdNX0NMT1NFLCAwLCAwICk7CgogICAgY2FzZSBTQ19WU0NST0xMOgogICAgY2FzZSBTQ19IU0NST0xMOgogICAgICAgIHsKICAgICAgICAgICAgUE9JTlQgcHQ7CiAgICAgICAgICAgIHB0LnggPSBTTE9XT1JEKGxQYXJhbSk7CiAgICAgICAgICAgIHB0LnkgPSBTSElXT1JEKGxQYXJhbSk7CiAgICAgICAgICAgIE5DX1RyYWNrU2Nyb2xsQmFyKCBod25kLCB3UGFyYW0sIHB0ICk7CiAgICAgICAgfQoJYnJlYWs7CgogICAgY2FzZSBTQ19NT1VTRU1FTlU6CiAgICAgICAgewogICAgICAgICAgICBQT0lOVCBwdDsKICAgICAgICAgICAgcHQueCA9IFNMT1dPUkQobFBhcmFtKTsKICAgICAgICAgICAgcHQueSA9IFNISVdPUkQobFBhcmFtKTsKICAgICAgICAgICAgTUVOVV9UcmFja01vdXNlTWVudUJhciggaHduZCwgd1BhcmFtICYgMHgwMDBGLCBwdCApOwogICAgICAgIH0KCWJyZWFrOwoKICAgIGNhc2UgU0NfS0VZTUVOVToKICAgICAgICBNRU5VX1RyYWNrS2JkTWVudUJhciggaHduZCwgd1BhcmFtLCBMT1dPUkQobFBhcmFtKSApOwoJYnJlYWs7CgogICAgY2FzZSBTQ19UQVNLTElTVDoKCVdpbkV4ZWMoICJ0YXNrbWFuLmV4ZSIsIFNXX1NIT1dOT1JNQUwgKTsgCglicmVhazsKCiAgICBjYXNlIFNDX1NDUkVFTlNBVkU6CglpZiAod1BhcmFtID09IFNDX0FCT1VUV0lORSkKICAgICAgICB7CiAgICAgICAgICAgIEhNT0RVTEUgaG1vZHVsZSA9IExvYWRMaWJyYXJ5QSggInNoZWxsMzIuZGxsIiApOwogICAgICAgICAgICBpZiAoaG1vZHVsZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRkFSUFJPQyBhYm91dHByb2MgPSBHZXRQcm9jQWRkcmVzcyggaG1vZHVsZSwgIlNoZWxsQWJvdXRBIiApOwogICAgICAgICAgICAgICAgaWYgKGFib3V0cHJvYykgYWJvdXRwcm9jKCBod25kLCAiV2luZSIsIFdJTkVfUkVMRUFTRV9JTkZPLCAwICk7CiAgICAgICAgICAgICAgICBGcmVlTGlicmFyeSggaG1vZHVsZSApOwogICAgICAgICAgICB9CiAgICAgICAgfQoJZWxzZSAKCSAgaWYgKHdQYXJhbSA9PSBTQ19QVVRNQVJLKQogICAgICAgICAgICBUUkFDRV8oc2hlbGwpKCJNYXJrIHJlcXVlc3RlZCBieSB1c2VyXG4iKTsKCWJyZWFrOwogIAogICAgY2FzZSBTQ19IT1RLRVk6CiAgICBjYXNlIFNDX0FSUkFOR0U6CiAgICBjYXNlIFNDX05FWFRXSU5ET1c6CiAgICBjYXNlIFNDX1BSRVZXSU5ET1c6CiAJRklYTUUoInVuaW1wbGVtZW50ZWQhXG4iKTsKICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICBOQ19EcmF3R3JheUJ1dHRvbgoqCiogU3R1YiBmb3IgdGhlIGdyYXllZCBidXR0b24gb2YgdGhlIGNhcHRpb24KKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKQk9PTCBOQ19EcmF3R3JheUJ1dHRvbihIREMgaGRjLCBpbnQgeCwgaW50IHkpCnsKICAgIEhCSVRNQVAgaE1hc2tCbXA7CiAgICBIREMgaGRjTWFzayA9IENyZWF0ZUNvbXBhdGlibGVEQyAoMCk7CiAgICBIQlJVU0ggaE9sZEJydXNoOwoKICAgIGhNYXNrQm1wID0gQ3JlYXRlQml0bWFwICgxMiwgMTAsIDEsIDEsIGxwR3JheU1hc2spOwogICAgCiAgICBpZihoTWFza0JtcCA9PSAwKQoJcmV0dXJuIEZBTFNFOwogICAgCiAgICBTZWxlY3RPYmplY3QgKGhkY01hc2ssIGhNYXNrQm1wKTsKICAgIAogICAgLyogRHJhdyB0aGUgZ3JheWVkIGJpdG1hcCB1c2luZyB0aGUgbWFzayAqLwogICAgaE9sZEJydXNoID0gU2VsZWN0T2JqZWN0IChoZGMsIFJHQigxMjgsIDEyOCwgMTI4KSk7CiAgICBCaXRCbHQgKGhkYywgeCwgeSwgMTIsIDEwLAoJICAgIGhkY01hc2ssIDAsIDAsIDB4QjgwNzRBKTsKICAgIAogICAgLyogQ2xlYW4gdXAgKi8KICAgIFNlbGVjdE9iamVjdCAoaGRjLCBoT2xkQnJ1c2gpOwogICAgRGVsZXRlT2JqZWN0KGhNYXNrQm1wKTsKICAgIERlbGV0ZURDIChoZGNNYXNrKTsKICAgIAogICAgcmV0dXJuIFRSVUU7Cn0K