LyoKICogTm9uLWNsaWVudCBhcmVhIHdpbmRvdyBmdW5jdGlvbnMKICoKICogQ29weXJpZ2h0IDE5OTQgQWxleGFuZHJlIEp1bGxpYXJkCiAqCiAqLwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW5lL3dpbnVzZXIxNi5oIgojaW5jbHVkZSAidmVyc2lvbi5oIgojaW5jbHVkZSAid2luLmgiCiNpbmNsdWRlICJ1c2VyLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJkY2UuaCIKI2luY2x1ZGUgImNvbnRyb2xzLmgiCiNpbmNsdWRlICJjdXJzb3JpY29uLmgiCiNpbmNsdWRlICJ3aW5wb3MuaCIKI2luY2x1ZGUgImhvb2suaCIKI2luY2x1ZGUgIm5vbmNsaWVudC5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgojaW5jbHVkZSAic2hlbGxhcGkuaCIKI2luY2x1ZGUgImJpdG1hcC5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKG5vbmNsaWVudCk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChzaGVsbCk7CgpCT09MIE5DX0RyYXdHcmF5QnV0dG9uKEhEQyBoZGMsIGludCB4LCBpbnQgeSk7CgpzdGF0aWMgSEJJVE1BUCBoYml0bWFwQ2xvc2U7CnN0YXRpYyBIQklUTUFQIGhiaXRtYXBNaW5pbWl6ZTsKc3RhdGljIEhCSVRNQVAgaGJpdG1hcE1pbmltaXplRDsKc3RhdGljIEhCSVRNQVAgaGJpdG1hcE1heGltaXplOwpzdGF0aWMgSEJJVE1BUCBoYml0bWFwTWF4aW1pemVEOwpzdGF0aWMgSEJJVE1BUCBoYml0bWFwUmVzdG9yZTsKc3RhdGljIEhCSVRNQVAgaGJpdG1hcFJlc3RvcmVEOwoKc3RhdGljIGNvbnN0IEJZVEUgbHBHcmF5TWFza1tdID0geyAweEFBLCAweEEwLAoJCSAgICAgIDB4NTUsIDB4NTAsICAKCQkgICAgICAweEFBLCAweEEwLAoJCSAgICAgIDB4NTUsIDB4NTAsICAKCQkgICAgICAweEFBLCAweEEwLAoJCSAgICAgIDB4NTUsIDB4NTAsICAKCQkgICAgICAweEFBLCAweEEwLAoJCSAgICAgIDB4NTUsIDB4NTAsICAKCQkgICAgICAweEFBLCAweEEwLAoJCSAgICAgIDB4NTUsIDB4NTB9OwoKI2RlZmluZSBTQ19BQk9VVFdJTkUgICAgCShTQ19TQ1JFRU5TQVZFKzEpCiNkZWZpbmUgU0NfUFVUTUFSSyAgICAgCQkoU0NfU0NSRUVOU0FWRSsyKQoKICAvKiBTb21lIHVzZWZ1bCBtYWNyb3MgKi8KI2RlZmluZSBIQVNfRExHRlJBTUUoc3R5bGUsZXhTdHlsZSkgXAogICAgKCgoZXhTdHlsZSkgJiBXU19FWF9ETEdNT0RBTEZSQU1FKSB8fCBcCiAgICAgKCgoc3R5bGUpICYgV1NfRExHRlJBTUUpICYmICEoKHN0eWxlKSAmIFdTX1RISUNLRlJBTUUpKSkKCiNkZWZpbmUgSEFTX1RISUNLRlJBTUUoc3R5bGUsZXhTdHlsZSkgXAogICAgKCgoc3R5bGUpICYgV1NfVEhJQ0tGUkFNRSkgJiYgXAogICAgICEoKChzdHlsZSkgJiAoV1NfRExHRlJBTUV8V1NfQk9SREVSKSkgPT0gV1NfRExHRlJBTUUpKQoKI2RlZmluZSBIQVNfVEhJTkZSQU1FKHN0eWxlKSBcCiAgICAoKChzdHlsZSkgJiBXU19CT1JERVIpIHx8ICEoKHN0eWxlKSAmIChXU19DSElMRCB8IFdTX1BPUFVQKSkpCgojZGVmaW5lIEhBU19CSUdGUkFNRShzdHlsZSxleFN0eWxlKSBcCiAgICAoKChzdHlsZSkgJiAoV1NfVEhJQ0tGUkFNRSB8IFdTX0RMR0ZSQU1FKSkgfHwgXAogICAgICgoZXhTdHlsZSkgJiBXU19FWF9ETEdNT0RBTEZSQU1FKSkKCiNkZWZpbmUgSEFTX1NUQVRJQ09VVEVSRlJBTUUoc3R5bGUsZXhTdHlsZSkgXAogICAgKCgoZXhTdHlsZSkgJiAoV1NfRVhfU1RBVElDRURHRXxXU19FWF9ETEdNT0RBTEZSQU1FKSkgPT0gXAogICAgIFdTX0VYX1NUQVRJQ0VER0UpCgojZGVmaW5lIEhBU19BTllGUkFNRShzdHlsZSxleFN0eWxlKSBcCiAgICAoKChzdHlsZSkgJiAoV1NfVEhJQ0tGUkFNRSB8IFdTX0RMR0ZSQU1FIHwgV1NfQk9SREVSKSkgfHwgXAogICAgICgoZXhTdHlsZSkgJiBXU19FWF9ETEdNT0RBTEZSQU1FKSB8fCBcCiAgICAgISgoc3R5bGUpICYgKFdTX0NISUxEIHwgV1NfUE9QVVApKSkKCiNkZWZpbmUgSEFTX01FTlUodykgICghKCh3KS0+ZHdTdHlsZSAmIFdTX0NISUxEKSAmJiAoKHcpLT53SURtZW51ICE9IDApKQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfQWRqdXN0UmVjdAogKgogKiBDb21wdXRlIHRoZSBzaXplIG9mIHRoZSB3aW5kb3cgcmVjdGFuZ2xlIGZyb20gdGhlIHNpemUgb2YgdGhlCiAqIGNsaWVudCByZWN0YW5nbGUuCiAqLwpzdGF0aWMgdm9pZCBOQ19BZGp1c3RSZWN0KCBMUFJFQ1QgcmVjdCwgRFdPUkQgc3R5bGUsIEJPT0wgbWVudSwgRFdPUkQgZXhTdHlsZSApCnsKICAgIGlmIChUV0VBS19XaW5lTG9vayA+IFdJTjMxX0xPT0spCglFUlIoIkNhbGxlZCBpbiBXaW45NSBtb2RlLiBBaWVlISBQbGVhc2UgcmVwb3J0IHRoaXMuXG4iICk7CgogICAgaWYoc3R5bGUgJiBXU19JQ09OSUMpIHJldHVybjsKCiAgICBpZiAoSEFTX1RISUNLRlJBTUUoIHN0eWxlLCBleFN0eWxlICkpCiAgICAgICAgSW5mbGF0ZVJlY3QoIHJlY3QsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSksIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lGUkFNRSkgKTsKICAgIGVsc2UgaWYgKEhBU19ETEdGUkFNRSggc3R5bGUsIGV4U3R5bGUgKSkKICAgICAgICBJbmZsYXRlUmVjdCggcmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWERMR0ZSQU1FKSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWURMR0ZSQU1FKSApOwogICAgZWxzZSBpZiAoSEFTX1RISU5GUkFNRSggc3R5bGUgKSkKICAgICAgICBJbmZsYXRlUmVjdCggcmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWEJPUkRFUiksIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpKTsKCiAgICBpZiAoKHN0eWxlICYgV1NfQ0FQVElPTikgPT0gV1NfQ0FQVElPTikKICAgICAgICByZWN0LT50b3AgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUik7CgogICAgaWYgKG1lbnUpIHJlY3QtPnRvcCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZTUVOVSkgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKTsKCiAgICBpZiAoc3R5bGUgJiBXU19WU0NST0xMKSB7CiAgICAgIHJlY3QtPnJpZ2h0ICArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCkgLSAxOwogICAgICBpZighSEFTX0FOWUZSQU1FKCBzdHlsZSwgZXhTdHlsZSApKQoJIHJlY3QtPnJpZ2h0Kys7CiAgICB9CgogICAgaWYgKHN0eWxlICYgV1NfSFNDUk9MTCkgewogICAgICByZWN0LT5ib3R0b20gKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpIC0gMTsKICAgICAgaWYoIUhBU19BTllGUkFNRSggc3R5bGUsIGV4U3R5bGUgKSkKCSByZWN0LT5ib3R0b20rKzsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTkNfQWRqdXN0UmVjdE91dGVyOTUKICoKICogQ29tcHV0ZXMgdGhlIHNpemUgb2YgdGhlICJvdXRzaWRlIiBwYXJ0cyBvZiB0aGUgd2luZG93IGJhc2VkIG9uIHRoZQogKiBwYXJhbWV0ZXJzIG9mIHRoZSBjbGllbnQgYXJlYS4KICoKICsgUEFSQU1TCiAqICAgICBMUFJFQ1QxNiAgcmVjdAogKiAgICAgRFdPUkQgIHN0eWxlCiAqICAgICBCT09MICBtZW51CiAqICAgICBEV09SRCAgZXhTdHlsZQogKgogKiBOT1RFUwogKiAgICAgIk91dGVyIiBwYXJ0cyBvZiBhIHdpbmRvdyBtZWFucyB0aGUgd2hvbGUgd2luZG93IGZyYW1lLCBjYXB0aW9uIGFuZAogKiAgICAgbWVudSBiYXIuIEl0IGRvZXMgbm90IGluY2x1ZGUgImlubmVyIiBwYXJ0cyBvZiB0aGUgZnJhbWUgbGlrZSBjbGllbnQKICogICAgIGVkZ2UsIHN0YXRpYyBlZGdlIG9yIHNjcm9sbCBiYXJzLgogKgogKiBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAwNS1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgIE9yaWdpbmFsIChOQ19BZGp1c3RSZWN0OTUpIGN1dCAmIHBhc3RlIGZyb20gTkNfQWRqdXN0UmVjdAogKgogKiAgICAgMjAtSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgIFNwbGl0IE5DX0FkanVzdFJlY3Q5NSBpbnRvIE5DX0FkanVzdFJlY3RPdXRlcjk1IGFuZAogKiAgICAgICAgTkNfQWRqdXN0UmVjdElubmVyOTUgYW5kIGFkZGVkIGhhbmRsaW5nIG9mIFdpbjk1IHN0eWxlcy4KICoKICogICAgIDI4LUp1bC0xOTk5IE92ZSBL5XZlbiAob3Zla0BhcmN0aWNuZXQubm8pCiAqICAgICAgICBTdHJlYW1saW5lZCB3aW5kb3cgc3R5bGUgY2hlY2tzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZApOQ19BZGp1c3RSZWN0T3V0ZXI5NSAoTFBSRUNUIHJlY3QsIERXT1JEIHN0eWxlLCBCT09MIG1lbnUsIERXT1JEIGV4U3R5bGUpCnsKICAgIGludCBhZGp1c3Q7CiAgICBpZihzdHlsZSAmIFdTX0lDT05JQykgcmV0dXJuOwoKICAgIGlmICgoZXhTdHlsZSAmIChXU19FWF9TVEFUSUNFREdFfFdTX0VYX0RMR01PREFMRlJBTUUpKSA9PSAKICAgICAgICBXU19FWF9TVEFUSUNFREdFKQogICAgewogICAgICAgIGFkanVzdCA9IDE7IC8qIGZvciB0aGUgb3V0ZXIgZnJhbWUgYWx3YXlzIHByZXNlbnQgKi8KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBhZGp1c3QgPSAwOwogICAgICAgIGlmICgoZXhTdHlsZSAmIFdTX0VYX0RMR01PREFMRlJBTUUpIHx8CiAgICAgICAgICAgIChzdHlsZSAmIChXU19USElDS0ZSQU1FfFdTX0RMR0ZSQU1FKSkpIGFkanVzdCA9IDI7IC8qIG91dGVyICovCiAgICB9CiAgICBpZiAoc3R5bGUgJiBXU19USElDS0ZSQU1FKQogICAgICAgIGFkanVzdCArPSAgKCBHZXRTeXN0ZW1NZXRyaWNzIChTTV9DWEZSQU1FKQogICAgICAgICAgICAgICAgICAgLSBHZXRTeXN0ZW1NZXRyaWNzIChTTV9DWERMR0ZSQU1FKSk7IC8qIFRoZSByZXNpemUgYm9yZGVyICovCiAgICBpZiAoKHN0eWxlICYgKFdTX0JPUkRFUnxXU19ETEdGUkFNRSkpIHx8IAogICAgICAgIChleFN0eWxlICYgV1NfRVhfRExHTU9EQUxGUkFNRSkpCiAgICAgICAgYWRqdXN0Kys7IC8qIFRoZSBvdGhlciBib3JkZXIgKi8KCiAgICBJbmZsYXRlUmVjdCAocmVjdCwgYWRqdXN0LCBhZGp1c3QpOwoKICAgIGlmICgoc3R5bGUgJiBXU19DQVBUSU9OKSA9PSBXU19DQVBUSU9OKQogICAgewogICAgICAgIGlmIChleFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykKICAgICAgICAgICAgcmVjdC0+dG9wIC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUNBUFRJT04pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmVjdC0+dG9wIC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKTsKICAgIH0KICAgIGlmIChtZW51KSByZWN0LT50b3AgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWU1FTlUpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBOQ19BZGp1c3RSZWN0SW5uZXI5NQogKgogKiBDb21wdXRlcyB0aGUgc2l6ZSBvZiB0aGUgImluc2lkZSIgcGFydCBvZiB0aGUgd2luZG93IGJhc2VkIG9uIHRoZQogKiBwYXJhbWV0ZXJzIG9mIHRoZSBjbGllbnQgYXJlYS4KICoKICsgUEFSQU1TCiAqICAgICBMUFJFQ1QxNiByZWN0CiAqICAgICBEV09SRCAgICBzdHlsZQogKiAgICAgRFdPUkQgICAgZXhTdHlsZQogKgogKiBOT1RFUwogKiAgICAgIklubmVyIiBwYXJ0IG9mIGEgd2luZG93IG1lYW5zIHRoZSB3aW5kb3cgZnJhbWUgaW5zaWRlIG9mIHRoZSBmbGF0CiAqICAgICB3aW5kb3cgZnJhbWUuIEl0IGluY2x1ZGVzIHRoZSBjbGllbnQgZWRnZSwgdGhlIHN0YXRpYyBlZGdlIGFuZCB0aGUKICogICAgIHNjcm9sbCBiYXJzLgogKgogKiBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAwNS1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgIE9yaWdpbmFsIChOQ19BZGp1c3RSZWN0OTUpIGN1dCAmIHBhc3RlIGZyb20gTkNfQWRqdXN0UmVjdAogKgogKiAgICAgMjAtSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgIFNwbGl0IE5DX0FkanVzdFJlY3Q5NSBpbnRvIE5DX0FkanVzdFJlY3RPdXRlcjk1IGFuZAogKiAgICAgICAgTkNfQWRqdXN0UmVjdElubmVyOTUgYW5kIGFkZGVkIGhhbmRsaW5nIG9mIFdpbjk1IHN0eWxlcy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHZvaWQKTkNfQWRqdXN0UmVjdElubmVyOTUgKExQUkVDVCByZWN0LCBEV09SRCBzdHlsZSwgRFdPUkQgZXhTdHlsZSkKewogICAgaWYoc3R5bGUgJiBXU19JQ09OSUMpIHJldHVybjsKCiAgICBpZiAoZXhTdHlsZSAmIFdTX0VYX0NMSUVOVEVER0UpCiAgICAgICAgSW5mbGF0ZVJlY3QocmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWEVER0UpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSkpOwoKICAgIGlmIChzdHlsZSAmIFdTX1ZTQ1JPTEwpIHJlY3QtPnJpZ2h0ICArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCk7CiAgICBpZiAoc3R5bGUgJiBXU19IU0NST0xMKSByZWN0LT5ib3R0b20gKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpOwp9CgoKCnN0YXRpYyBISUNPTiBOQ19JY29uRm9yV2luZG93KCBIV05EIGh3bmQgKQp7CiAgICBISUNPTiBoSWNvbiA9IChISUNPTikgR2V0Q2xhc3NMb25nQSggaHduZCwgR0NMX0hJQ09OU00gKTsKICAgIGlmICghaEljb24pIGhJY29uID0gKEhJQ09OKSBHZXRDbGFzc0xvbmdBKCBod25kLCBHQ0xfSElDT04gKTsKCiAgICAvKiBJZiB0aGVyZSBpcyBubyBoSWNvbiBzcGVjaWZpZWQgYW5kIHRoaXMgaXMgYSBtb2RhbCBkaWFsb2csCiAgICAgKiBnZXQgdGhlIGRlZmF1bHQgb25lLgogICAgICovCiAgICBpZiAoIWhJY29uICYmIChHZXRXaW5kb3dMb25nQSggaHduZCwgR1dMX1NUWUxFICkgJiBEU19NT0RBTEZSQU1FKSkKICAgICAgICBoSWNvbiA9IExvYWRJbWFnZUEoMCwgSURJX1dJTkxPR09BLCBJTUFHRV9JQ09OLCAwLCAwLCBMUl9ERUZBVUxUQ09MT1IpOwogICAgcmV0dXJuIGhJY29uOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURyYXdDYXB0aW9uIChVU0VSLjY2MCkgRHJhd3MgYSBjYXB0aW9uIGJhcgogKgogKiBQQVJBTVMKICogICAgIGh3bmQgICBbSV0KICogICAgIGhkYyAgICBbSV0KICogICAgIGxwUmVjdCBbSV0KICogICAgIHVGbGFncyBbSV0KICoKICogUkVUVVJOUwogKiAgICAgU3VjY2VzczoKICogICAgIEZhaWx1cmU6CiAqLwoKQk9PTDE2IFdJTkFQSQpEcmF3Q2FwdGlvbjE2IChIV05EMTYgaHduZCwgSERDMTYgaGRjLCBjb25zdCBSRUNUMTYgKnJlY3QsIFVJTlQxNiB1RmxhZ3MpCnsKICAgIFJFQ1QgcmVjdDMyOwoKICAgIGlmIChyZWN0KQoJQ09OVl9SRUNUMTZUTzMyIChyZWN0LCAmcmVjdDMyKTsKCiAgICByZXR1cm4gKEJPT0wxNilEcmF3Q2FwdGlvblRlbXBBIChod25kLCBoZGMsIHJlY3QgPyAmcmVjdDMyIDogTlVMTCwKCQkJCSAgICAgICAwLCAwLCBOVUxMLCB1RmxhZ3MgJiAweDFGKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRHJhd0NhcHRpb24gKFVTRVIzMi5AKSBEcmF3cyBhIGNhcHRpb24gYmFyCiAqCiAqIFBBUkFNUwogKiAgICAgaHduZCAgIFtJXQogKiAgICAgaGRjICAgIFtJXQogKiAgICAgbHBSZWN0IFtJXQogKiAgICAgdUZsYWdzIFtJXQogKgogKiBSRVRVUk5TCiAqICAgICBTdWNjZXNzOgogKiAgICAgRmFpbHVyZToKICovCgpCT09MIFdJTkFQSQpEcmF3Q2FwdGlvbiAoSFdORCBod25kLCBIREMgaGRjLCBjb25zdCBSRUNUICpscFJlY3QsIFVJTlQgdUZsYWdzKQp7CiAgICByZXR1cm4gRHJhd0NhcHRpb25UZW1wQSAoaHduZCwgaGRjLCBscFJlY3QsIDAsIDAsIE5VTEwsIHVGbGFncyAmIDB4MUYpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlEcmF3Q2FwdGlvblRlbXAgKFVTRVIuNjU3KQogKgogKiBQQVJBTVMKICoKICogUkVUVVJOUwogKiAgICAgU3VjY2VzczoKICogICAgIEZhaWx1cmU6CiAqLwoKQk9PTDE2IFdJTkFQSQpEcmF3Q2FwdGlvblRlbXAxNiAoSFdORDE2IGh3bmQsIEhEQzE2IGhkYywgY29uc3QgUkVDVDE2ICpyZWN0LCBIRk9OVDE2IGhGb250LAoJCSAgIEhJQ09OMTYgaEljb24sIExQQ1NUUiBzdHIsIFVJTlQxNiB1RmxhZ3MpCnsKICAgIFJFQ1QgcmVjdDMyOwoKICAgIGlmIChyZWN0KQoJQ09OVl9SRUNUMTZUTzMyKHJlY3QsJnJlY3QzMik7CgogICAgcmV0dXJuIChCT09MMTYpRHJhd0NhcHRpb25UZW1wQSAoaHduZCwgaGRjLCByZWN0PyZyZWN0MzI6TlVMTCwgaEZvbnQsCgkJCQkgICAgICAgaEljb24sIHN0ciwgdUZsYWdzICYgMHgxRik7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURyYXdDYXB0aW9uVGVtcEEgKFVTRVIzMi5AKQogKgogKiBQQVJBTVMKICoKICogUkVUVVJOUwogKiAgICAgU3VjY2VzczoKICogICAgIEZhaWx1cmU6CiAqLwoKQk9PTCBXSU5BUEkKRHJhd0NhcHRpb25UZW1wQSAoSFdORCBod25kLCBIREMgaGRjLCBjb25zdCBSRUNUICpyZWN0LCBIRk9OVCBoRm9udCwKCQkgICAgSElDT04gaEljb24sIExQQ1NUUiBzdHIsIFVJTlQgdUZsYWdzKQp7CiAgICBSRUNUICAgcmMgPSAqcmVjdDsKCiAgICBUUkFDRSgiKCUwOHgsJTA4eCwlcCwlMDh4LCUwOHgsXCIlc1wiLCUwOHgpXG4iLAogICAgICAgICAgaHduZCwgaGRjLCByZWN0LCBoRm9udCwgaEljb24sIHN0ciwgdUZsYWdzKTsKCiAgICAvKiBkcmF3aW5nIGJhY2tncm91bmQgKi8KICAgIGlmICh1RmxhZ3MgJiBEQ19JTkJVVFRPTikgewoJRmlsbFJlY3QgKGhkYywgJnJjLCBHZXRTeXNDb2xvckJydXNoIChDT0xPUl8zREZBQ0UpKTsKCglpZiAodUZsYWdzICYgRENfQUNUSVZFKSB7CgkgICAgSEJSVVNIIGhiciA9IFNlbGVjdE9iamVjdCAoaGRjLCBDQUNIRV9HZXRQYXR0ZXJuNTVBQUJydXNoICgpKTsKCSAgICBQYXRCbHQgKGhkYywgcmMubGVmdCwgcmMudG9wLAoJCSAgICAgIHJjLnJpZ2h0LXJjLmxlZnQsIHJjLmJvdHRvbS1yYy50b3AsIDB4RkEwMDg5KTsKCSAgICBTZWxlY3RPYmplY3QgKGhkYywgaGJyKTsKCX0KICAgIH0KICAgIGVsc2UgewoJRmlsbFJlY3QgKGhkYywgJnJjLCBHZXRTeXNDb2xvckJydXNoICgodUZsYWdzICYgRENfQUNUSVZFKSA/CgkJICAgIENPTE9SX0FDVElWRUNBUFRJT04gOiBDT0xPUl9JTkFDVElWRUNBUFRJT04pKTsKICAgIH0KCgogICAgLyogZHJhd2luZyBpY29uICovCiAgICBpZiAoKHVGbGFncyAmIERDX0lDT04pICYmICEodUZsYWdzICYgRENfU01BTExDQVApKSB7CglQT0lOVCBwdDsKCglwdC54ID0gcmMubGVmdCArIDI7CglwdC55ID0gKHJjLmJvdHRvbSArIHJjLnRvcCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUlDT04pKSAvIDI7CgogICAgICAgIGlmICghaEljb24pIGhJY29uID0gTkNfSWNvbkZvcldpbmRvdyhod25kKTsKICAgICAgICBEcmF3SWNvbkV4IChoZGMsIHB0LngsIHB0LnksIGhJY29uLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU01JQ09OKSwKICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01JQ09OKSwgMCwgMCwgRElfTk9STUFMKTsKCXJjLmxlZnQgKz0gKHJjLmJvdHRvbSAtIHJjLnRvcCk7CiAgICB9CgogICAgLyogZHJhd2luZyB0ZXh0ICovCiAgICBpZiAodUZsYWdzICYgRENfVEVYVCkgewoJSEZPTlQgaE9sZEZvbnQ7CgoJaWYgKHVGbGFncyAmIERDX0lOQlVUVE9OKQoJICAgIFNldFRleHRDb2xvciAoaGRjLCBHZXRTeXNDb2xvciAoQ09MT1JfQlROVEVYVCkpOwoJZWxzZSBpZiAodUZsYWdzICYgRENfQUNUSVZFKQoJICAgIFNldFRleHRDb2xvciAoaGRjLCBHZXRTeXNDb2xvciAoQ09MT1JfQ0FQVElPTlRFWFQpKTsKCWVsc2UKCSAgICBTZXRUZXh0Q29sb3IgKGhkYywgR2V0U3lzQ29sb3IgKENPTE9SX0lOQUNUSVZFQ0FQVElPTlRFWFQpKTsKCglTZXRCa01vZGUgKGhkYywgVFJBTlNQQVJFTlQpOwoKCWlmIChoRm9udCkKCSAgICBoT2xkRm9udCA9IFNlbGVjdE9iamVjdCAoaGRjLCBoRm9udCk7CgllbHNlIHsKCSAgICBOT05DTElFTlRNRVRSSUNTQSBuY2xtOwoJICAgIEhGT05UIGhOZXdGb250OwoJICAgIG5jbG0uY2JTaXplID0gc2l6ZW9mKE5PTkNMSUVOVE1FVFJJQ1NBKTsKCSAgICBTeXN0ZW1QYXJhbWV0ZXJzSW5mb0EgKFNQSV9HRVROT05DTElFTlRNRVRSSUNTLCAwLCAmbmNsbSwgMCk7CgkgICAgaE5ld0ZvbnQgPSBDcmVhdGVGb250SW5kaXJlY3RBICgodUZsYWdzICYgRENfU01BTExDQVApID8KCQkmbmNsbS5sZlNtQ2FwdGlvbkZvbnQgOiAmbmNsbS5sZkNhcHRpb25Gb250KTsKCSAgICBoT2xkRm9udCA9IFNlbGVjdE9iamVjdCAoaGRjLCBoTmV3Rm9udCk7Cgl9CgoJaWYgKHN0cikKCSAgICBEcmF3VGV4dEEgKGhkYywgc3RyLCAtMSwgJnJjLAoJCQkgRFRfU0lOR0xFTElORSB8IERUX1ZDRU5URVIgfCBEVF9OT1BSRUZJWCB8IERUX0xFRlQpOwoJZWxzZSB7CgkgICAgQ0hBUiBzelRleHRbMTI4XTsKCSAgICBJTlQgbkxlbjsKCSAgICBuTGVuID0gR2V0V2luZG93VGV4dEEgKGh3bmQsIHN6VGV4dCwgMTI4KTsKCSAgICBEcmF3VGV4dEEgKGhkYywgc3pUZXh0LCBuTGVuLCAmcmMsCgkJCSBEVF9TSU5HTEVMSU5FIHwgRFRfVkNFTlRFUiB8IERUX05PUFJFRklYIHwgRFRfTEVGVCk7Cgl9CgoJaWYgKGhGb250KQoJICAgIFNlbGVjdE9iamVjdCAoaGRjLCBoT2xkRm9udCk7CgllbHNlCgkgICAgRGVsZXRlT2JqZWN0IChTZWxlY3RPYmplY3QgKGhkYywgaE9sZEZvbnQpKTsKICAgIH0KCiAgICAvKiBkcmF3aW5nIGZvY3VzID8/PyAqLwogICAgaWYgKHVGbGFncyAmIDB4MjAwMCkKCUZJWE1FKCJ1bmRvY3VtZW50ZWQgZmxhZyAoMHgyMDAwKSFcbiIpOwoKICAgIHJldHVybiAwOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlEcmF3Q2FwdGlvblRlbXBXIChVU0VSMzIuQCkKICoKICogUEFSQU1TCiAqCiAqIFJFVFVSTlMKICogICAgIFN1Y2Nlc3M6CiAqICAgICBGYWlsdXJlOgogKi8KCkJPT0wgV0lOQVBJCkRyYXdDYXB0aW9uVGVtcFcgKEhXTkQgaHduZCwgSERDIGhkYywgY29uc3QgUkVDVCAqcmVjdCwgSEZPTlQgaEZvbnQsCgkJICAgIEhJQ09OIGhJY29uLCBMUENXU1RSIHN0ciwgVUlOVCB1RmxhZ3MpCnsKICAgIExQU1RSIHAgPSBIRUFQX3N0cmR1cFd0b0EgKEdldFByb2Nlc3NIZWFwICgpLCAwLCBzdHIpOwogICAgQk9PTCByZXMgPSBEcmF3Q2FwdGlvblRlbXBBIChod25kLCBoZGMsIHJlY3QsIGhGb250LCBoSWNvbiwgcCwgdUZsYWdzKTsKICAgIEhlYXBGcmVlIChHZXRQcm9jZXNzSGVhcCAoKSwgMCwgcCk7CiAgICByZXR1cm4gcmVzOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBZGp1c3RXaW5kb3dSZWN0IChVU0VSLjEwMikKICovCkJPT0wxNiBXSU5BUEkgQWRqdXN0V2luZG93UmVjdDE2KCBMUFJFQ1QxNiByZWN0LCBEV09SRCBzdHlsZSwgQk9PTDE2IG1lbnUgKQp7CiAgICByZXR1cm4gQWRqdXN0V2luZG93UmVjdEV4MTYoIHJlY3QsIHN0eWxlLCBtZW51LCAwICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFkanVzdFdpbmRvd1JlY3QgKFVTRVIzMi5AKQogKi8KQk9PTCBXSU5BUEkgQWRqdXN0V2luZG93UmVjdCggTFBSRUNUIHJlY3QsIERXT1JEIHN0eWxlLCBCT09MIG1lbnUgKQp7CiAgICByZXR1cm4gQWRqdXN0V2luZG93UmVjdEV4KCByZWN0LCBzdHlsZSwgbWVudSwgMCApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBZGp1c3RXaW5kb3dSZWN0RXggKFVTRVIuNDU0KQogKi8KQk9PTDE2IFdJTkFQSSBBZGp1c3RXaW5kb3dSZWN0RXgxNiggTFBSRUNUMTYgcmVjdCwgRFdPUkQgc3R5bGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wxNiBtZW51LCBEV09SRCBleFN0eWxlICkKewogICAgUkVDVCByZWN0MzI7CiAgICBCT09MIHJldDsKCiAgICBDT05WX1JFQ1QxNlRPMzIoIHJlY3QsICZyZWN0MzIgKTsKICAgIHJldCA9IEFkanVzdFdpbmRvd1JlY3RFeCggJnJlY3QzMiwgc3R5bGUsIG1lbnUsIGV4U3R5bGUgKTsKICAgIENPTlZfUkVDVDMyVE8xNiggJnJlY3QzMiwgcmVjdCApOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQWRqdXN0V2luZG93UmVjdEV4IChVU0VSMzIuQCkKICovCkJPT0wgV0lOQVBJIEFkanVzdFdpbmRvd1JlY3RFeCggTFBSRUNUIHJlY3QsIERXT1JEIHN0eWxlLCBCT09MIG1lbnUsIERXT1JEIGV4U3R5bGUgKQp7CiAgICAvKiBDb3JyZWN0IHRoZSB3aW5kb3cgc3R5bGUgKi8KCiAgICBpZiAoIShzdHlsZSAmIChXU19QT1BVUCB8IFdTX0NISUxEKSkpIHN0eWxlIHw9IFdTX0NBUFRJT047IC8qIE92ZXJsYXBwZWQgd2luZG93ICovCiAgICBzdHlsZSAmPSAoV1NfRExHRlJBTUUgfCBXU19CT1JERVIgfCBXU19USElDS0ZSQU1FIHwgV1NfQ0hJTEQpOwogICAgZXhTdHlsZSAmPSAoV1NfRVhfRExHTU9EQUxGUkFNRSB8IFdTX0VYX0NMSUVOVEVER0UgfAogICAgICAgICAgICAgICAgV1NfRVhfU1RBVElDRURHRSB8IFdTX0VYX1RPT0xXSU5ET1cpOwogICAgaWYgKGV4U3R5bGUgJiBXU19FWF9ETEdNT0RBTEZSQU1FKSBzdHlsZSAmPSB+V1NfVEhJQ0tGUkFNRTsKCiAgICBUUkFDRSgiKCVkLCVkKS0oJWQsJWQpICUwOGx4ICVkICUwOGx4XG4iLAogICAgICAgICAgcmVjdC0+bGVmdCwgcmVjdC0+dG9wLCByZWN0LT5yaWdodCwgcmVjdC0+Ym90dG9tLAogICAgICAgICAgc3R5bGUsIG1lbnUsIGV4U3R5bGUgKTsKCiAgICBpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKICAgICAgICBOQ19BZGp1c3RSZWN0KCByZWN0LCBzdHlsZSwgbWVudSwgZXhTdHlsZSApOwogICAgZWxzZQogICAgewogICAgICAgIE5DX0FkanVzdFJlY3RPdXRlcjk1KCByZWN0LCBzdHlsZSwgbWVudSwgZXhTdHlsZSApOwogICAgICAgIE5DX0FkanVzdFJlY3RJbm5lcjk1KCByZWN0LCBzdHlsZSwgZXhTdHlsZSApOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZU5DQ2FsY1NpemUKICoKICogSGFuZGxlIGEgV01fTkNDQUxDU0laRSBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZU5DQ2FsY1NpemUoIEhXTkQgaHduZCwgUkVDVCAqd2luUmVjdCApCnsKICAgIFJFQ1QgdG1wUmVjdCA9IHsgMCwgMCwgMCwgMCB9OwogICAgTE9ORyByZXN1bHQgPSAwOwogICAgTE9ORyBjbHNfc3R5bGUgPSBHZXRDbGFzc0xvbmdBKGh3bmQsIEdDTF9TVFlMRSk7CiAgICBMT05HIHN0eWxlID0gR2V0V2luZG93TG9uZ0EoIGh3bmQsIEdXTF9TVFlMRSApOwogICAgTE9ORyBleFN0eWxlID0gR2V0V2luZG93TG9uZ0EoIGh3bmQsIEdXTF9FWFNUWUxFICk7CgogICAgaWYgKGNsc19zdHlsZSAmIENTX1ZSRURSQVcpIHJlc3VsdCB8PSBXVlJfVlJFRFJBVzsKICAgIGlmIChjbHNfc3R5bGUgJiBDU19IUkVEUkFXKSByZXN1bHQgfD0gV1ZSX0hSRURSQVc7CgogICAgaWYgKCFJc0ljb25pYyhod25kKSkKICAgIHsKCWlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQoJICAgIE5DX0FkanVzdFJlY3QoICZ0bXBSZWN0LCBzdHlsZSwgRkFMU0UsIGV4U3R5bGUgKTsKCWVsc2UKCSAgICBOQ19BZGp1c3RSZWN0T3V0ZXI5NSggJnRtcFJlY3QsIHN0eWxlLCBGQUxTRSwgZXhTdHlsZSApOwoKCXdpblJlY3QtPmxlZnQgICAtPSB0bXBSZWN0LmxlZnQ7Cgl3aW5SZWN0LT50b3AgICAgLT0gdG1wUmVjdC50b3A7Cgl3aW5SZWN0LT5yaWdodCAgLT0gdG1wUmVjdC5yaWdodDsKCXdpblJlY3QtPmJvdHRvbSAtPSB0bXBSZWN0LmJvdHRvbTsKCiAgICAgICAgaWYgKCEoc3R5bGUgJiBXU19DSElMRCkgJiYgR2V0TWVudShod25kKSkKICAgICAgICB7CgkgICAgVFJBQ0UoIkNhbGxpbmcgR2V0TWVudUJhckhlaWdodCB3aXRoIEhXTkQgMHgleCwgd2lkdGggJWQsICIKICAgICAgICAgICAgICAgICAgImF0ICglZCwgJWQpLlxuIiwgaHduZCwKICAgICAgICAgICAgICAgICAgd2luUmVjdC0+cmlnaHQgLSB3aW5SZWN0LT5sZWZ0LAogICAgICAgICAgICAgICAgICAtdG1wUmVjdC5sZWZ0LCAtdG1wUmVjdC50b3AgKTsKCgkgICAgd2luUmVjdC0+dG9wICs9CgkJTUVOVV9HZXRNZW51QmFySGVpZ2h0KCBod25kLAoJCQkJICAgICAgIHdpblJlY3QtPnJpZ2h0IC0gd2luUmVjdC0+bGVmdCwKCQkJCSAgICAgICAtdG1wUmVjdC5sZWZ0LCAtdG1wUmVjdC50b3AgKSArIDE7Cgl9CgoJaWYgKFRXRUFLX1dpbmVMb29rID4gV0lOMzFfTE9PSykgewoJICAgIFNldFJlY3QoJnRtcFJlY3QsIDAsIDAsIDAsIDApOwoJICAgIE5DX0FkanVzdFJlY3RJbm5lcjk1ICgmdG1wUmVjdCwgc3R5bGUsIGV4U3R5bGUpOwoJICAgIHdpblJlY3QtPmxlZnQgICAtPSB0bXBSZWN0LmxlZnQ7CgkgICAgd2luUmVjdC0+dG9wICAgIC09IHRtcFJlY3QudG9wOwoJICAgIHdpblJlY3QtPnJpZ2h0ICAtPSB0bXBSZWN0LnJpZ2h0OwoJICAgIHdpblJlY3QtPmJvdHRvbSAtPSB0bXBSZWN0LmJvdHRvbTsKCX0KCiAgICAgICAgaWYgKHdpblJlY3QtPnRvcCA+IHdpblJlY3QtPmJvdHRvbSkKICAgICAgICAgICAgd2luUmVjdC0+Ym90dG9tID0gd2luUmVjdC0+dG9wOwoKICAgICAgICBpZiAod2luUmVjdC0+bGVmdCA+IHdpblJlY3QtPnJpZ2h0KQogICAgICAgICAgICB3aW5SZWN0LT5yaWdodCA9IHdpblJlY3QtPmxlZnQ7CiAgICB9CiAgICByZXR1cm4gcmVzdWx0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19HZXRJbnNpZGVSZWN0CiAqCiAqIEdldCB0aGUgJ2luc2lkZScgcmVjdGFuZ2xlIG9mIGEgd2luZG93LCBpLmUuIHRoZSB3aG9sZSB3aW5kb3cgcmVjdGFuZ2xlCiAqIGJ1dCB3aXRob3V0IHRoZSBib3JkZXJzIChpZiBhbnkpLgogKiBUaGUgcmVjdGFuZ2xlIGlzIGluIHdpbmRvdyBjb29yZGluYXRlcyAoZm9yIGRyYXdpbmcgd2l0aCBHZXRXaW5kb3dEQygpKS4KICovCnZvaWQgTkNfR2V0SW5zaWRlUmVjdCggSFdORCBod25kLCBSRUNUICpyZWN0ICkKewogICAgV05EICogd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICByZWN0LT50b3AgICAgPSByZWN0LT5sZWZ0ID0gMDsKICAgIHJlY3QtPnJpZ2h0ICA9IHduZFB0ci0+cmVjdFdpbmRvdy5yaWdodCAtIHduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0OwogICAgcmVjdC0+Ym90dG9tID0gd25kUHRyLT5yZWN0V2luZG93LmJvdHRvbSAtIHduZFB0ci0+cmVjdFdpbmRvdy50b3A7CgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0lDT05JQykgZ290byBFTkQ7CgogICAgLyogUmVtb3ZlIGZyYW1lIGZyb20gcmVjdGFuZ2xlICovCiAgICBpZiAoSEFTX1RISUNLRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgIHsKICAgICAgICBJbmZsYXRlUmVjdCggcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpICk7CiAgICB9CiAgICBlbHNlIGlmIChIQVNfRExHRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgIHsKICAgICAgICBJbmZsYXRlUmVjdCggcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hETEdGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRExHRlJBTUUpKTsKICAgICAgICAvKiBGSVhNRTogdGhpcyBpc24ndCBpbiBOQ19BZGp1c3RSZWN0PyB3aHkgbm90PyAqLwogICAgICAgIGlmICgoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykgJiYgKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfRExHTU9EQUxGUkFNRSkpCiAgICAgICAgICAgIEluZmxhdGVSZWN0KCByZWN0LCAtMSwgMCApOwogICAgfQogICAgZWxzZSBpZiAoSEFTX1RISU5GUkFNRSggd25kUHRyLT5kd1N0eWxlICkpCiAgICB7CiAgICAgICAgSW5mbGF0ZVJlY3QoIHJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYQk9SREVSKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpICk7CiAgICB9CgogICAgLyogV2UgaGF2ZSBhZGRpdGlvbmFsIGJvcmRlciBpbmZvcm1hdGlvbiBpZiB0aGUgd2luZG93CiAgICAgKiBpcyBhIGNoaWxkIChidXQgbm90IGFuIE1ESSBjaGlsZCkgKi8KICAgIGlmIChUV0VBS19XaW5lTG9vayAhPSBXSU4zMV9MT09LKQogICAgewogICAgICAgIGlmICggKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NISUxEKSAgJiYKICAgICAgICAgICAgICggKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfTURJQ0hJTEQpID09IDAgKSApCiAgICAgICAgewogICAgICAgICAgICBpZiAod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9DTElFTlRFREdFKQogICAgICAgICAgICAgICAgSW5mbGF0ZVJlY3QgKHJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRURHRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSkpOwogICAgICAgICAgICBpZiAod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9TVEFUSUNFREdFKQogICAgICAgICAgICAgICAgSW5mbGF0ZVJlY3QgKHJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYQk9SREVSKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpKTsKICAgICAgICB9CiAgICB9CgpFTkQ6CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE5DX0RvTkNIaXRUZXN0CiAqCiAqIEhhbmRsZSBhIFdNX05DSElUVEVTVCBtZXNzYWdlLiBDYWxsZWQgZnJvbSBOQ19IYW5kbGVOQ0hpdFRlc3QoKS4KICovCgpzdGF0aWMgTE9ORyBOQ19Eb05DSGl0VGVzdCAoV05EICp3bmRQdHIsIFBPSU5UIHB0ICkKewogICAgUkVDVCByZWN0OwoKICAgIFRSQUNFKCJod25kPSUwNHggcHQ9JWxkLCVsZFxuIiwgd25kUHRyLT5od25kU2VsZiwgcHQueCwgcHQueSApOwoKICAgIEdldFdpbmRvd1JlY3Qod25kUHRyLT5od25kU2VsZiwgJnJlY3QgKTsKICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFROT1dIRVJFOwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRSkgcmV0dXJuIEhUQ0FQVElPTjsKCiAgICAvKiBDaGVjayBib3JkZXJzICovCiAgICBpZiAoSEFTX1RISUNLRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgIHsKICAgICAgICBJbmZsYXRlUmVjdCggJnJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRlJBTUUpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSApOwogICAgICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgIHsKICAgICAgICAgICAgLyogQ2hlY2sgdG9wIHNpemluZyBib3JkZXIgKi8KICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHB0LnggPCByZWN0LmxlZnQrR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpKSByZXR1cm4gSFRUT1BMRUZUOwogICAgICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVFRPUFJJR0hUOwogICAgICAgICAgICAgICAgcmV0dXJuIEhUVE9QOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIENoZWNrIGJvdHRvbSBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgIGlmIChwdC55ID49IHJlY3QuYm90dG9tKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVEJPVFRPTUxFRlQ7CiAgICAgICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0LUdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSkgcmV0dXJuIEhUQk9UVE9NUklHSFQ7CiAgICAgICAgICAgICAgICByZXR1cm4gSFRCT1RUT007CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogQ2hlY2sgbGVmdCBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgIGlmIChwdC54IDwgcmVjdC5sZWZ0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocHQueSA8IHJlY3QudG9wK0dldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSkgcmV0dXJuIEhUVE9QTEVGVDsKICAgICAgICAgICAgICAgIGlmIChwdC55ID49IHJlY3QuYm90dG9tLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSkgcmV0dXJuIEhUQk9UVE9NTEVGVDsKICAgICAgICAgICAgICAgIHJldHVybiBIVExFRlQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogQ2hlY2sgcmlnaHQgc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocHQueSA8IHJlY3QudG9wK0dldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSkgcmV0dXJuIEhUVE9QUklHSFQ7CiAgICAgICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbS1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVEJPVFRPTVJJR0hUOwogICAgICAgICAgICAgICAgcmV0dXJuIEhUUklHSFQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBlbHNlICAvKiBObyB0aGljayBmcmFtZSAqLwogICAgewogICAgICAgIGlmIChIQVNfRExHRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgICAgICAgICAgSW5mbGF0ZVJlY3QoJnJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRExHRlJBTUUpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWURMR0ZSQU1FKSk7CiAgICAgICAgZWxzZSBpZiAoSEFTX1RISU5GUkFNRSggd25kUHRyLT5kd1N0eWxlICkpCiAgICAgICAgICAgIEluZmxhdGVSZWN0KCZyZWN0LCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWEJPUkRFUiksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKSk7CiAgICAgICAgaWYgKCFQdEluUmVjdCggJnJlY3QsIHB0ICkpIHJldHVybiBIVEJPUkRFUjsKICAgIH0KCiAgICAvKiBDaGVjayBjYXB0aW9uICovCgogICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19DQVBUSU9OKSA9PSBXU19DQVBUSU9OKQogICAgewogICAgICAgIHJlY3QudG9wICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpOwogICAgICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgIHsKICAgICAgICAgICAgLyogQ2hlY2sgc3lzdGVtIG1lbnUgKi8KICAgICAgICAgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19TWVNNRU5VKSAmJiAhKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykpCiAgICAgICAgICAgICAgICByZWN0LmxlZnQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpOwogICAgICAgICAgICBpZiAocHQueCA8PSByZWN0LmxlZnQpIHJldHVybiBIVFNZU01FTlU7CgogICAgICAgICAgICAvKiBDaGVjayBtYXhpbWl6ZSBib3ggKi8KICAgICAgICAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01BWElNSVpFQk9YKQogICAgICAgICAgICAgICAgcmVjdC5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwoKICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodCkgcmV0dXJuIEhUTUFYQlVUVE9OOwogICAgICAgICAgICAvKiBDaGVjayBtaW5pbWl6ZSBib3ggKi8KICAgICAgICAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFQk9YKQogICAgICAgICAgICAgICAgcmVjdC5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwogICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0KSByZXR1cm4gSFRNSU5CVVRUT047CiAgICAgICAgICAgIHJldHVybiBIVENBUFRJT047CiAgICAgICAgfQogICAgfQoKICAgICAgLyogQ2hlY2sgY2xpZW50IGFyZWEgKi8KCiAgICBTY3JlZW5Ub0NsaWVudCggd25kUHRyLT5od25kU2VsZiwgJnB0ICk7CiAgICBHZXRDbGllbnRSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmcmVjdCApOwogICAgaWYgKFB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUQ0xJRU5UOwoKICAgICAgLyogQ2hlY2sgdmVydGljYWwgc2Nyb2xsIGJhciAqLwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19WU0NST0xMKQogICAgewoJcmVjdC5yaWdodCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCk7CglpZiAoUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFRWU0NST0xMOwogICAgfQoKICAgICAgLyogQ2hlY2sgaG9yaXpvbnRhbCBzY3JvbGwgYmFyICovCgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0hTQ1JPTEwpCiAgICB7CglyZWN0LmJvdHRvbSArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCk7CglpZiAoUHRJblJlY3QoICZyZWN0LCBwdCApKQoJewoJICAgICAgLyogQ2hlY2sgc2l6ZSBib3ggKi8KCSAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpICYmCgkJKHB0LnggPj0gcmVjdC5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKSkpCgkJcmV0dXJuIEhUU0laRTsKCSAgICByZXR1cm4gSFRIU0NST0xMOwoJfQogICAgfQoKICAgICAgLyogQ2hlY2sgbWVudSBiYXIgKi8KCiAgICBpZiAoSEFTX01FTlUod25kUHRyKSkKICAgIHsKCWlmICgocHQueSA8IDApICYmIChwdC54ID49IDApICYmIChwdC54IDwgcmVjdC5yaWdodCkpCgkgICAgcmV0dXJuIEhUTUVOVTsKICAgIH0KCiAgICAvKiBIYXMgdG8gcmV0dXJuIEhUTk9XSEVSRSBpZiBub3RoaW5nIHdhcyBmb3VuZCAgCiAgICAgICBDb3VsZCBoYXBwZW4gd2hlbiBhIHdpbmRvdyBoYXMgYSBjdXN0b21pemVkIG5vbiBjbGllbnQgYXJlYSAqLwogICAgcmV0dXJuIEhUTk9XSEVSRTsgIAp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE5DX0RvTkNIaXRUZXN0OTUKICoKICogSGFuZGxlIGEgV01fTkNISVRURVNUIG1lc3NhZ2UuIENhbGxlZCBmcm9tIE5DX0hhbmRsZU5DSGl0VGVzdCgpLgogKgogKiBGSVhNRTogIEp1c3QgYSBtb2RpZmllZCBjb3B5IG9mIHRoZSBXaW4gMy4xIHZlcnNpb24uCiAqLwoKc3RhdGljIExPTkcgTkNfRG9OQ0hpdFRlc3Q5NSAoV05EICp3bmRQdHIsIFBPSU5UIHB0ICkKewogICAgUkVDVCByZWN0OwoKICAgIFRSQUNFKCJod25kPSUwNHggcHQ9JWxkLCVsZFxuIiwgd25kUHRyLT5od25kU2VsZiwgcHQueCwgcHQueSApOwoKICAgIEdldFdpbmRvd1JlY3Qod25kUHRyLT5od25kU2VsZiwgJnJlY3QgKTsKICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFROT1dIRVJFOwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRSkgcmV0dXJuIEhUQ0FQVElPTjsKCiAgICAvKiBDaGVjayBib3JkZXJzICovCiAgICBpZiAoSEFTX1RISUNLRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgIHsKICAgICAgICBJbmZsYXRlUmVjdCggJnJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRlJBTUUpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSApOwogICAgICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgIHsKICAgICAgICAgICAgLyogQ2hlY2sgdG9wIHNpemluZyBib3JkZXIgKi8KICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHB0LnggPCByZWN0LmxlZnQrR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpKSByZXR1cm4gSFRUT1BMRUZUOwogICAgICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVFRPUFJJR0hUOwogICAgICAgICAgICAgICAgcmV0dXJuIEhUVE9QOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIENoZWNrIGJvdHRvbSBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgIGlmIChwdC55ID49IHJlY3QuYm90dG9tKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVEJPVFRPTUxFRlQ7CiAgICAgICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0LUdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSkgcmV0dXJuIEhUQk9UVE9NUklHSFQ7CiAgICAgICAgICAgICAgICByZXR1cm4gSFRCT1RUT007CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogQ2hlY2sgbGVmdCBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgIGlmIChwdC54IDwgcmVjdC5sZWZ0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocHQueSA8IHJlY3QudG9wK0dldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSkgcmV0dXJuIEhUVE9QTEVGVDsKICAgICAgICAgICAgICAgIGlmIChwdC55ID49IHJlY3QuYm90dG9tLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSkgcmV0dXJuIEhUQk9UVE9NTEVGVDsKICAgICAgICAgICAgICAgIHJldHVybiBIVExFRlQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogQ2hlY2sgcmlnaHQgc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocHQueSA8IHJlY3QudG9wK0dldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSkgcmV0dXJuIEhUVE9QUklHSFQ7CiAgICAgICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbS1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVEJPVFRPTVJJR0hUOwogICAgICAgICAgICAgICAgcmV0dXJuIEhUUklHSFQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBlbHNlICAvKiBObyB0aGljayBmcmFtZSAqLwogICAgewogICAgICAgIGlmIChIQVNfRExHRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgICAgICAgICAgSW5mbGF0ZVJlY3QoJnJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRExHRlJBTUUpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWURMR0ZSQU1FKSk7CiAgICAgICAgZWxzZSBpZiAoSEFTX1RISU5GUkFNRSggd25kUHRyLT5kd1N0eWxlICkpCiAgICAgICAgICAgIEluZmxhdGVSZWN0KCZyZWN0LCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWEJPUkRFUiksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKSk7CiAgICAgICAgaWYgKCFQdEluUmVjdCggJnJlY3QsIHB0ICkpIHJldHVybiBIVEJPUkRFUjsKICAgIH0KCiAgICAvKiBDaGVjayBjYXB0aW9uICovCgogICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19DQVBUSU9OKSA9PSBXU19DQVBUSU9OKQogICAgewogICAgICAgIGlmICh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX1RPT0xXSU5ET1cpCiAgICAgICAgICAgIHJlY3QudG9wICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUNBUFRJT04pIC0gMTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJlY3QudG9wICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIDE7CiAgICAgICAgaWYgKCFQdEluUmVjdCggJnJlY3QsIHB0ICkpCiAgICAgICAgewogICAgICAgICAgICAvKiBDaGVjayBzeXN0ZW0gbWVudSAqLwogICAgICAgICAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1NZU01FTlUpICYmICEod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9UT09MV0lORE9XKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKE5DX0ljb25Gb3JXaW5kb3cod25kUHRyLT5od25kU2VsZikpCiAgICAgICAgICAgICAgICAgICAgcmVjdC5sZWZ0ICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHB0LnggPCByZWN0LmxlZnQpIHJldHVybiBIVFNZU01FTlU7CgogICAgICAgICAgICAvKiBDaGVjayBjbG9zZSBidXR0b24gKi8KICAgICAgICAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1NZU01FTlUpCiAgICAgICAgICAgICAgICByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIDE7CiAgICAgICAgICAgIGlmIChwdC54ID4gcmVjdC5yaWdodCkgcmV0dXJuIEhUQ0xPU0U7CgogICAgICAgICAgICAvKiBDaGVjayBtYXhpbWl6ZSBib3ggKi8KICAgICAgICAgICAgLyogSW4gd2luOTUgdGhlcmUgaXMgYXV0b21hdGljYWxseSBhIE1heGltaXplIGJ1dHRvbiB3aGVuIHRoZXJlIGlzIGEgbWluaW1pemUgb25lKi8KICAgICAgICAgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19NQVhJTUlaRUJPWCl8fCAod25kUHRyLT5kd1N0eWxlICYgV1NfTUlOSU1JWkVCT1gpKQogICAgICAgICAgICAgICAgcmVjdC5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwogICAgICAgICAgICBpZiAocHQueCA+IHJlY3QucmlnaHQpIHJldHVybiBIVE1BWEJVVFRPTjsKCiAgICAgICAgICAgIC8qIENoZWNrIG1pbmltaXplIGJveCAqLwogICAgICAgICAgICAvKiBJbiB3aW45NSB0aGVyZSBpcyBhdXRvbWF0aWNhbGx5IGEgTWF4aW1pemUgYnV0dG9uIHdoZW4gdGhlcmUgaXMgYSBNYXhpbWl6ZSBvbmUqLwogICAgICAgICAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFQk9YKXx8KHduZFB0ci0+ZHdTdHlsZSAmIFdTX01BWElNSVpFQk9YKSkKICAgICAgICAgICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKCiAgICAgICAgICAgIGlmIChwdC54ID4gcmVjdC5yaWdodCkgcmV0dXJuIEhUTUlOQlVUVE9OOwogICAgICAgICAgICByZXR1cm4gSFRDQVBUSU9OOwogICAgICAgIH0KICAgIH0KCiAgICAgIC8qIENoZWNrIGNsaWVudCBhcmVhICovCgogICAgU2NyZWVuVG9DbGllbnQoIHduZFB0ci0+aHduZFNlbGYsICZwdCApOwogICAgR2V0Q2xpZW50UmVjdCggd25kUHRyLT5od25kU2VsZiwgJnJlY3QgKTsKICAgIGlmIChQdEluUmVjdCggJnJlY3QsIHB0ICkpIHJldHVybiBIVENMSUVOVDsKCiAgICAgIC8qIENoZWNrIHZlcnRpY2FsIHNjcm9sbCBiYXIgKi8KCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfVlNDUk9MTCkKICAgIHsKCXJlY3QucmlnaHQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpOwoJaWYgKFB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUVlNDUk9MTDsKICAgIH0KCiAgICAgIC8qIENoZWNrIGhvcml6b250YWwgc2Nyb2xsIGJhciAqLwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19IU0NST0xMKQogICAgewoJcmVjdC5ib3R0b20gKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpOwoJaWYgKFB0SW5SZWN0KCAmcmVjdCwgcHQgKSkKCXsKCSAgICAgIC8qIENoZWNrIHNpemUgYm94ICovCgkgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19WU0NST0xMKSAmJgoJCShwdC54ID49IHJlY3QucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCkpKQoJCXJldHVybiBIVFNJWkU7CgkgICAgcmV0dXJuIEhUSFNDUk9MTDsKCX0KICAgIH0KCiAgICAgIC8qIENoZWNrIG1lbnUgYmFyICovCgogICAgaWYgKEhBU19NRU5VKHduZFB0cikpCiAgICB7CglpZiAoKHB0LnkgPCAwKSAmJiAocHQueCA+PSAwKSAmJiAocHQueCA8IHJlY3QucmlnaHQpKQoJICAgIHJldHVybiBIVE1FTlU7CiAgICB9CgogICAgLyogSGFzIHRvIHJldHVybiBIVE5PV0hFUkUgaWYgbm90aGluZyB3YXMgZm91bmQgIAogICAgICAgQ291bGQgaGFwcGVuIHdoZW4gYSB3aW5kb3cgaGFzIGEgY3VzdG9taXplZCBub24gY2xpZW50IGFyZWEgKi8KICAgIHJldHVybiBIVE5PV0hFUkU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTkNfSGFuZGxlTkNIaXRUZXN0CiAqCiAqIEhhbmRsZSBhIFdNX05DSElUVEVTVCBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZU5DSGl0VGVzdCAoSFdORCBod25kICwgUE9JTlQgcHQpCnsKICAgIExPTkcgcmV0dmFsdWU7CiAgICBXTkQgKnduZFB0ciA9IFdJTl9GaW5kV25kUHRyIChod25kKTsKCiAgICBpZiAoIXduZFB0cikKCXJldHVybiBIVEVSUk9SOwoKICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQogICAgICAgIHJldHZhbHVlID0gTkNfRG9OQ0hpdFRlc3QgKHduZFB0ciwgcHQpOwogICAgZWxzZQogICAgICAgIHJldHZhbHVlID0gTkNfRG9OQ0hpdFRlc3Q5NSAod25kUHRyLCBwdCk7CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuIHJldHZhbHVlOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3U3lzQnV0dG9uCiAqLwp2b2lkIE5DX0RyYXdTeXNCdXR0b24oIEhXTkQgaHduZCwgSERDIGhkYywgQk9PTCBkb3duICkKewogICAgUkVDVCByZWN0OwogICAgSERDIGhkY01lbTsKICAgIEhCSVRNQVAgaGJpdG1hcDsKCiAgICBOQ19HZXRJbnNpZGVSZWN0KCBod25kLCAmcmVjdCApOwogICAgaGRjTWVtID0gQ3JlYXRlQ29tcGF0aWJsZURDKCBoZGMgKTsKICAgIGhiaXRtYXAgPSBTZWxlY3RPYmplY3QoIGhkY01lbSwgaGJpdG1hcENsb3NlICk7CiAgICBCaXRCbHQoaGRjLCByZWN0LmxlZnQsIHJlY3QudG9wLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSksIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSwKICAgICAgICAgICBoZGNNZW0sIChHZXRXaW5kb3dMb25nQShod25kLEdXTF9TVFlMRSkgJiBXU19DSElMRCkgPyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgOiAwLCAwLAogICAgICAgICAgIGRvd24gPyBOT1RTUkNDT1BZIDogU1JDQ09QWSApOwogICAgU2VsZWN0T2JqZWN0KCBoZGNNZW0sIGhiaXRtYXAgKTsKICAgIERlbGV0ZURDKCBoZGNNZW0gKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfRHJhd01heEJ1dHRvbgogKi8Kc3RhdGljIHZvaWQgTkNfRHJhd01heEJ1dHRvbiggSFdORCBod25kLCBIREMxNiBoZGMsIEJPT0wgZG93biApCnsKICAgIFJFQ1QgcmVjdDsKICAgIEhEQyBoZGNNZW07CgogICAgTkNfR2V0SW5zaWRlUmVjdCggaHduZCwgJnJlY3QgKTsKICAgIGhkY01lbSA9IENyZWF0ZUNvbXBhdGlibGVEQyggaGRjICk7CiAgICBTZWxlY3RPYmplY3QoIGhkY01lbSwgIChJc1pvb21lZChod25kKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAoZG93biA/IGhiaXRtYXBSZXN0b3JlRCA6IGhiaXRtYXBSZXN0b3JlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAoZG93biA/IGhiaXRtYXBNYXhpbWl6ZUQgOiBoYml0bWFwTWF4aW1pemUpKSApOwogICAgQml0Qmx0KCBoZGMsIHJlY3QucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgLSAxLCByZWN0LnRvcCwKICAgICAgICAgICAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpLCBoZGNNZW0sIDAsIDAsCiAgICAgICAgICAgIFNSQ0NPUFkgKTsKICAgIERlbGV0ZURDKCBoZGNNZW0gKTsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0RyYXdNaW5CdXR0b24KICovCnN0YXRpYyB2b2lkIE5DX0RyYXdNaW5CdXR0b24oIEhXTkQgaHduZCwgSERDMTYgaGRjLCBCT09MIGRvd24gKQp7CiAgICBSRUNUIHJlY3Q7CiAgICBIREMgaGRjTWVtOwoKICAgIE5DX0dldEluc2lkZVJlY3QoIGh3bmQsICZyZWN0ICk7CiAgICBoZGNNZW0gPSBDcmVhdGVDb21wYXRpYmxlREMoIGhkYyApOwogICAgU2VsZWN0T2JqZWN0KCBoZGNNZW0sIChkb3duID8gaGJpdG1hcE1pbmltaXplRCA6IGhiaXRtYXBNaW5pbWl6ZSkgKTsKICAgIGlmIChHZXRXaW5kb3dMb25nQShod25kLEdXTF9TVFlMRSkgJiBXU19NQVhJTUlaRUJPWCkKICAgICAgICByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSsxOwogICAgQml0Qmx0KCBoZGMsIHJlY3QucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgLSAxLCByZWN0LnRvcCwKICAgICAgICAgICAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpLCBoZGNNZW0sIDAsIDAsCiAgICAgICAgICAgIFNSQ0NPUFkgKTsKICAgIERlbGV0ZURDKCBoZGNNZW0gKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICB2b2lkICBOQ19EcmF3U3lzQnV0dG9uOTUoCiAqICAgICAgSFdORCAgaHduZCwKICogICAgICBIREMgIGhkYywKICogICAgICBCT09MICBkb3duICkKICoKICogICBEcmF3cyB0aGUgV2luOTUgc3lzdGVtIGljb24uCiAqCiAqICAgUmV2aXNpb24gaGlzdG9yeQogKiAgICAgICAgMDUtSnVsLTE5OTcgRGF2ZSBDdXRoYmVydCAoZGFjdXRAZWNlLmNtdS5lZHUpCiAqICAgICAgICAgICAgIE9yaWdpbmFsIGltcGxlbWVudGF0aW9uIGZyb20gTkNfRHJhd1N5c0J1dHRvbiBzb3VyY2UuCiAqICAgICAgICAxMS1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgICAgICBGaXhlZCBtb3N0IGJ1Z3MuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCkJPT0wKTkNfRHJhd1N5c0J1dHRvbjk1IChIV05EIGh3bmQsIEhEQyBoZGMsIEJPT0wgZG93bikKewogICAgSElDT04gaEljb24gPSBOQ19JY29uRm9yV2luZG93KCBod25kICk7CgogICAgaWYgKGhJY29uKQogICAgewogICAgICAgIFJFQ1QgcmVjdDsKICAgICAgICBOQ19HZXRJbnNpZGVSZWN0KCBod25kLCAmcmVjdCApOwogICAgICAgIERyYXdJY29uRXggKGhkYywgcmVjdC5sZWZ0ICsgMiwgcmVjdC50b3AgKyAyLCBoSWNvbiwKICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU01JQ09OKSwKICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01JQ09OKSwgMCwgMCwgRElfTk9STUFMKTsKICAgIH0KICAgIHJldHVybiAoaEljb24gIT0gMCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqICAgdm9pZCAgTkNfRHJhd0Nsb3NlQnV0dG9uOTUoCiAqICAgICAgSFdORCAgaHduZCwKICogICAgICBIREMgIGhkYywKICogICAgICBCT09MICBkb3duLAogKiAgICAgIEJPT0wgICAgYkdyYXllZCApCiAqCiAqICAgRHJhd3MgdGhlIFdpbjk1IGNsb3NlIGJ1dHRvbi4KICoKICogICBJZiBiR3JheWVkIGlzIHRydWUsIHRoZW4gZHJhdyBhIGRpc2FibGVkIENsb3NlIGJ1dHRvbgogKgogKiAgIFJldmlzaW9uIGhpc3RvcnkKICogICAgICAgIDExLUp1bi0xOTk4IEVyaWMgS29obCAoZWtvaGxAYWJvLnJoZWluLXplaXR1bmcuZGUpCiAqICAgICAgICAgICAgIE9yaWdpbmFsIGltcGxlbWVudGF0aW9uIGZyb20gTkNfRHJhd1N5c0J1dHRvbjk1IHNvdXJjZS4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHZvaWQgTkNfRHJhd0Nsb3NlQnV0dG9uOTUgKEhXTkQgaHduZCwgSERDIGhkYywgQk9PTCBkb3duLCBCT09MIGJHcmF5ZWQpCnsKICAgIFJFQ1QgcmVjdDsKCiAgICBOQ19HZXRJbnNpZGVSZWN0KCBod25kLCAmcmVjdCApOwoKICAgIC8qIEEgdG9vbCB3aW5kb3cgaGFzIGEgc21hbGxlciBDbG9zZSBidXR0b24gKi8KICAgIGlmIChHZXRXaW5kb3dMb25nQSggaHduZCwgR1dMX0VYU1RZTEUgKSAmIFdTX0VYX1RPT0xXSU5ET1cpCiAgICB7CiAgICAgICAgSU5UIGlCbXBIZWlnaHQgPSAxMTsgLyogV2luZG93cyBkb2VzIG5vdCB1c2UgU01fQ1hTTVNJWkUgYW5kIFNNX0NZU01TSVpFICAgKi8KICAgICAgICBJTlQgaUJtcFdpZHRoID0gMTE7ICAvKiBpdCB1c2VzIDExeDExIGZvciAgdGhlIGNsb3NlIGJ1dHRvbiBpbiB0b29sIHdpbmRvdyAqLwogICAgICAgIElOVCBpQ2FwdGlvbkhlaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUNBUFRJT04pOwoKICAgICAgICByZWN0LnRvcCA9IHJlY3QudG9wICsgKGlDYXB0aW9uSGVpZ2h0IC0gMSAtIGlCbXBIZWlnaHQpIC8gMjsKICAgICAgICByZWN0LmxlZnQgPSByZWN0LnJpZ2h0IC0gKGlDYXB0aW9uSGVpZ2h0ICsgMSArIGlCbXBXaWR0aCkgLyAyOwogICAgICAgIHJlY3QuYm90dG9tID0gcmVjdC50b3AgKyBpQm1wSGVpZ2h0OwogICAgICAgIHJlY3QucmlnaHQgPSByZWN0LmxlZnQgKyBpQm1wV2lkdGg7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgcmVjdC5sZWZ0ID0gcmVjdC5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSAtIDE7CiAgICAgICAgcmVjdC5ib3R0b20gPSByZWN0LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSAtIDE7CiAgICAgICAgcmVjdC50b3AgKz0gMjsKICAgICAgICByZWN0LnJpZ2h0IC09IDI7CiAgICB9CiAgICBEcmF3RnJhbWVDb250cm9sKCBoZGMsICZyZWN0LCBERkNfQ0FQVElPTiwKICAgICAgICAgICAgICAgICAgICAgIChERkNTX0NBUFRJT05DTE9TRSB8CiAgICAgICAgICAgICAgICAgICAgICAgKGRvd24gPyBERkNTX1BVU0hFRCA6IDApIHwKICAgICAgICAgICAgICAgICAgICAgICAoYkdyYXllZCA/IERGQ1NfSU5BQ1RJVkUgOiAwKSkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgIE5DX0RyYXdNYXhCdXR0b245NQogKgogKiAgIERyYXdzIHRoZSBtYXhpbWl6ZSBidXR0b24gZm9yIFdpbjk1IHN0eWxlIHdpbmRvd3MuCiAqICAgSWYgYkdyYXllZCBpcyB0cnVlLCB0aGVuIGRyYXcgYSBkaXNhYmxlZCBNYXhpbWl6ZSBidXR0b24KICovCnN0YXRpYyB2b2lkIE5DX0RyYXdNYXhCdXR0b245NShIV05EIGh3bmQsSERDMTYgaGRjLEJPT0wgZG93biwgQk9PTCBiR3JheWVkKQp7CiAgICBSRUNUIHJlY3Q7CiAgICBVSU5UIGZsYWdzID0gSXNab29tZWQoaHduZCkgPyBERkNTX0NBUFRJT05SRVNUT1JFIDogREZDU19DQVBUSU9OTUFYOwoKICAgIE5DX0dldEluc2lkZVJlY3QoIGh3bmQsICZyZWN0ICk7CiAgICBpZiAoR2V0V2luZG93TG9uZ0EoIGh3bmQsIEdXTF9TVFlMRSkgJiBXU19TWVNNRU5VKQogICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKICAgIHJlY3QubGVmdCA9IHJlY3QucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSk7CiAgICByZWN0LmJvdHRvbSA9IHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpIC0gMTsKICAgIHJlY3QudG9wICs9IDI7CiAgICByZWN0LnJpZ2h0IC09IDI7CiAgICBpZiAoZG93bikgZmxhZ3MgfD0gREZDU19QVVNIRUQ7CiAgICBpZiAoYkdyYXllZCkgZmxhZ3MgfD0gREZDU19JTkFDVElWRTsKICAgIERyYXdGcmFtZUNvbnRyb2woIGhkYywgJnJlY3QsIERGQ19DQVBUSU9OLCBmbGFncyApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgTkNfRHJhd01pbkJ1dHRvbjk1CiAqCiAqICAgRHJhd3MgdGhlIG1pbmltaXplIGJ1dHRvbiBmb3IgV2luOTUgc3R5bGUgd2luZG93cy4KICogICBJZiBiR3JheWVkIGlzIHRydWUsIHRoZW4gZHJhdyBhIGRpc2FibGVkIE1pbmltaXplIGJ1dHRvbgogKi8Kc3RhdGljIHZvaWQgIE5DX0RyYXdNaW5CdXR0b245NShIV05EIGh3bmQsSERDMTYgaGRjLEJPT0wgZG93biwgQk9PTCBiR3JheWVkKQp7CiAgICBSRUNUIHJlY3Q7CiAgICBVSU5UIGZsYWdzID0gREZDU19DQVBUSU9OTUlOOwogICAgRFdPUkQgc3R5bGUgPSBHZXRXaW5kb3dMb25nQSggaHduZCwgR1dMX1NUWUxFICk7CgogICAgTkNfR2V0SW5zaWRlUmVjdCggaHduZCwgJnJlY3QgKTsKICAgIGlmIChzdHlsZSAmIFdTX1NZU01FTlUpCiAgICAgICAgcmVjdC5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwogICAgaWYgKHN0eWxlICYgKFdTX01BWElNSVpFQk9YfFdTX01JTklNSVpFQk9YKSkKICAgICAgICByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSAtIDI7CiAgICByZWN0LmxlZnQgPSByZWN0LnJpZ2h0IC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpOwogICAgcmVjdC5ib3R0b20gPSByZWN0LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSAtIDE7CiAgICByZWN0LnRvcCArPSAyOwogICAgcmVjdC5yaWdodCAtPSAyOwogICAgaWYgKGRvd24pIGZsYWdzIHw9IERGQ1NfUFVTSEVEOwogICAgaWYgKGJHcmF5ZWQpIGZsYWdzIHw9IERGQ1NfSU5BQ1RJVkU7CiAgICBEcmF3RnJhbWVDb250cm9sKCBoZGMsICZyZWN0LCBERkNfQ0FQVElPTiwgZmxhZ3MgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3RnJhbWUKICoKICogRHJhdyBhIHdpbmRvdyBmcmFtZSBpbnNpZGUgdGhlIGdpdmVuIHJlY3RhbmdsZSwgYW5kIHVwZGF0ZSB0aGUgcmVjdGFuZ2xlLgogKiBUaGUgY29ycmVjdCBwZW4gZm9yIHRoZSBmcmFtZSBtdXN0IGJlIHNlbGVjdGVkIGluIHRoZSBEQy4KICovCnN0YXRpYyB2b2lkIE5DX0RyYXdGcmFtZSggSERDIGhkYywgUkVDVCAqcmVjdCwgQk9PTCBkbGdGcmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIGFjdGl2ZSApCnsKICAgIElOVCB3aWR0aCwgaGVpZ2h0OwoKICAgIGlmIChUV0VBS19XaW5lTG9vayAhPSBXSU4zMV9MT09LKQoJRVJSKCJDYWxsZWQgaW4gV2luOTUgbW9kZS4gQWllZSEgUGxlYXNlIHJlcG9ydCB0aGlzLlxuIiApOwoKICAgIGlmIChkbGdGcmFtZSkKICAgIHsKCXdpZHRoID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWERMR0ZSQU1FKSAtIDE7CgloZWlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRExHRlJBTUUpIC0gMTsKICAgICAgICBTZWxlY3RPYmplY3QoIGhkYywgR2V0U3lzQ29sb3JCcnVzaChhY3RpdmUgPyBDT0xPUl9BQ1RJVkVDQVBUSU9OIDoKCQkJCQkJQ09MT1JfSU5BQ1RJVkVDQVBUSU9OKSApOwogICAgfQogICAgZWxzZQogICAgewoJd2lkdGggPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRlJBTUUpIC0gMjsKCWhlaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lGUkFNRSkgLSAyOwogICAgICAgIFNlbGVjdE9iamVjdCggaGRjLCBHZXRTeXNDb2xvckJydXNoKGFjdGl2ZSA/IENPTE9SX0FDVElWRUJPUkRFUiA6CgkJCQkJCUNPTE9SX0lOQUNUSVZFQk9SREVSKSApOwogICAgfQoKICAgICAgLyogRHJhdyBmcmFtZSAqLwogICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICByZWN0LT5yaWdodCAtIHJlY3QtPmxlZnQsIGhlaWdodCwgUEFUQ09QWSApOwogICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICB3aWR0aCwgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLCBQQVRDT1BZICk7CiAgICBQYXRCbHQoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+Ym90dG9tIC0gMSwKICAgICAgICAgICAgICByZWN0LT5yaWdodCAtIHJlY3QtPmxlZnQsIC1oZWlnaHQsIFBBVENPUFkgKTsKICAgIFBhdEJsdCggaGRjLCByZWN0LT5yaWdodCAtIDEsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAtd2lkdGgsIHJlY3QtPmJvdHRvbSAtIHJlY3QtPnRvcCwgUEFUQ09QWSApOwoKICAgIGlmIChkbGdGcmFtZSkKICAgIHsKCUluZmxhdGVSZWN0KCByZWN0LCAtd2lkdGgsIC1oZWlnaHQgKTsKICAgIH0gCiAgICBlbHNlCiAgICB7CiAgICAgICAgSU5UIGRlY1lPZmYgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRlJBTUUpICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpIC0gMTsKCUlOVCBkZWNYT2ZmID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSAtIDE7CgogICAgICAvKiBEcmF3IGlubmVyIHJlY3RhbmdsZSAqLwoKCVNlbGVjdE9iamVjdCggaGRjLCBHZXRTdG9ja09iamVjdChOVUxMX0JSVVNIKSApOwoJUmVjdGFuZ2xlKCBoZGMsIHJlY3QtPmxlZnQgKyB3aWR0aCwgcmVjdC0+dG9wICsgaGVpZ2h0LAoJCSAgICAgcmVjdC0+cmlnaHQgLSB3aWR0aCAsIHJlY3QtPmJvdHRvbSAtIGhlaWdodCApOwoKICAgICAgLyogRHJhdyB0aGUgZGVjb3JhdGlvbnMgKi8KCglNb3ZlVG9FeCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT50b3AgKyBkZWNZT2ZmLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+bGVmdCArIHdpZHRoLCByZWN0LT50b3AgKyBkZWNZT2ZmICk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5yaWdodCAtIDEsIHJlY3QtPnRvcCArIGRlY1lPZmYsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByZWN0LT5yaWdodCAtIHdpZHRoIC0gMSwgcmVjdC0+dG9wICsgZGVjWU9mZiApOwoJTW92ZVRvRXgoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+Ym90dG9tIC0gZGVjWU9mZiwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHJlY3QtPmxlZnQgKyB3aWR0aCwgcmVjdC0+Ym90dG9tIC0gZGVjWU9mZiApOwoJTW92ZVRvRXgoIGhkYywgcmVjdC0+cmlnaHQgLSAxLCByZWN0LT5ib3R0b20gLSBkZWNZT2ZmLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+cmlnaHQgLSB3aWR0aCAtIDEsIHJlY3QtPmJvdHRvbSAtIGRlY1lPZmYgKTsKCglNb3ZlVG9FeCggaGRjLCByZWN0LT5sZWZ0ICsgZGVjWE9mZiwgcmVjdC0+dG9wLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+bGVmdCArIGRlY1hPZmYsIHJlY3QtPnRvcCArIGhlaWdodCk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5sZWZ0ICsgZGVjWE9mZiwgcmVjdC0+Ym90dG9tIC0gMSwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHJlY3QtPmxlZnQgKyBkZWNYT2ZmLCByZWN0LT5ib3R0b20gLSBoZWlnaHQgLSAxICk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5yaWdodCAtIGRlY1hPZmYsIHJlY3QtPnRvcCwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHJlY3QtPnJpZ2h0IC0gZGVjWE9mZiwgcmVjdC0+dG9wICsgaGVpZ2h0ICk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5yaWdodCAtIGRlY1hPZmYsIHJlY3QtPmJvdHRvbSAtIDEsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByZWN0LT5yaWdodCAtIGRlY1hPZmYsIHJlY3QtPmJvdHRvbSAtIGhlaWdodCAtIDEgKTsKCglJbmZsYXRlUmVjdCggcmVjdCwgLXdpZHRoIC0gMSwgLWhlaWdodCAtIDEgKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICB2b2lkICBOQ19EcmF3RnJhbWU5NSgKICogICAgICBIREMgIGhkYywKICogICAgICBSRUNUICAqcmVjdCwKICogICAgICBCT09MICBhY3RpdmUsCiAqICAgICAgRFdPUkQgc3R5bGUsCiAqICAgICAgRFdPUkQgZXhTdHlsZSApCiAqCiAqICAgRHJhdyBhIHdpbmRvdyBmcmFtZSBpbnNpZGUgdGhlIGdpdmVuIHJlY3RhbmdsZSwgYW5kIHVwZGF0ZSB0aGUgcmVjdGFuZ2xlLgogKgogKiAgIEJ1Z3MKICogICAgICAgIE1hbnkuICBGaXJzdCwganVzdCB3aGF0IElTIGEgZnJhbWUgaW4gV2luOTU/ICBOb3RlIHRoYXQgdGhlIDNEIGxvb2sKICogICAgICAgIG9uIHRoZSBvdXRlciBlZGdlIGlzIGhhbmRsZWQgYnkgTkNfRG9OQ1BhaW50OTUuICBBcyBpcyB0aGUgaW5uZXIKICogICAgICAgIGVkZ2UuICBUaGUgaW5uZXIgcmVjdGFuZ2xlIGp1c3QgaW5zaWRlIHRoZSBmcmFtZSBpcyBoYW5kbGVkIGJ5IHRoZQogKiAgICAgICAgQ2FwdGlvbiBjb2RlLgogKgogKiAgICAgICAgSW4gc2hvcnQsIGZvciBtb3N0IHBlb3BsZSwgdGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgYSBub3AgKHVubGVzcwogKiAgICAgICAgeW91IExJS0UgdGhpY2sgYm9yZGVycyBpbiBXaW45NS9OVDQuMCAtLSBJJ3ZlIGJlZW4gd29ya2luZyB3aXRoCiAqICAgICAgICB0aGVtIGxhdGVseSwgYnV0IGp1c3QgdG8gZ2V0IHRoaXMgY29kZSByaWdodCkuICBFdmVuIHNvLCBpdCBkb2Vzbid0CiAqICAgICAgICBhcHBlYXIgdG8gYmUgc28uICBJdCdzIGJlaW5nIHdvcmtlZCBvbi4uLgogKiAKICogICBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAgICAwNi1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgICAgICAgT3JpZ2luYWwgaW1wbGVtZW50YXRpb24gKGJhc2VkIG9uIE5DX0RyYXdGcmFtZSkKICogICAgICAgIDAyLUp1bi0xOTk4IEVyaWMgS29obCAoZWtvaGxAYWJvLnJoZWluLXplaXR1bmcuZGUpCiAqICAgICAgICAgICAgIFNvbWUgbWlub3IgZml4ZXMuCiAqICAgICAgICAyOS1KdW4tMTk5OSBPdmUgS+V2ZW4gKG92ZWtAYXJjdGljbmV0Lm5vKQogKiAgICAgICAgICAgICBGaXhlZCBhIGZpeCBvciBzb21ldGhpbmcuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkICBOQ19EcmF3RnJhbWU5NSgKICAgIEhEQyAgaGRjLAogICAgUkVDVCAgKnJlY3QsCiAgICBCT09MICBhY3RpdmUsCiAgICBEV09SRCBzdHlsZSwKICAgIERXT1JEIGV4U3R5bGUpCnsKICAgIElOVCB3aWR0aCwgaGVpZ2h0OwoKICAgIC8qIEZpcnN0bHkgdGhlICJ0aGljayIgZnJhbWUgKi8KICAgIGlmIChzdHlsZSAmIFdTX1RISUNLRlJBTUUpCiAgICB7Cgl3aWR0aCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSkgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRExHRlJBTUUpOwoJaGVpZ2h0ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lETEdGUkFNRSk7CgogICAgICAgIFNlbGVjdE9iamVjdCggaGRjLCBHZXRTeXNDb2xvckJydXNoKGFjdGl2ZSA/IENPTE9SX0FDVElWRUJPUkRFUiA6CgkJICAgICAgQ09MT1JfSU5BQ1RJVkVCT1JERVIpICk7CiAgICAgICAgLyogRHJhdyBmcmFtZSAqLwogICAgICAgIFBhdEJsdCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT50b3AsCiAgICAgICAgICAgICAgICAgIHJlY3QtPnJpZ2h0IC0gcmVjdC0+bGVmdCwgaGVpZ2h0LCBQQVRDT1BZICk7CiAgICAgICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAgICAgd2lkdGgsIHJlY3QtPmJvdHRvbSAtIHJlY3QtPnRvcCwgUEFUQ09QWSApOwogICAgICAgIFBhdEJsdCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT5ib3R0b20gLSAxLAogICAgICAgICAgICAgICAgICByZWN0LT5yaWdodCAtIHJlY3QtPmxlZnQsIC1oZWlnaHQsIFBBVENPUFkgKTsKICAgICAgICBQYXRCbHQoIGhkYywgcmVjdC0+cmlnaHQgLSAxLCByZWN0LT50b3AsCiAgICAgICAgICAgICAgICAgIC13aWR0aCwgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLCBQQVRDT1BZICk7CgogICAgICAgIEluZmxhdGVSZWN0KCByZWN0LCAtd2lkdGgsIC1oZWlnaHQgKTsKICAgIH0KCiAgICAvKiBOb3cgdGhlIG90aGVyIGJpdCBvZiB0aGUgZnJhbWUgKi8KICAgIGlmICgoc3R5bGUgJiAoV1NfQk9SREVSfFdTX0RMR0ZSQU1FKSkgfHwKICAgICAgICAoZXhTdHlsZSAmIFdTX0VYX0RMR01PREFMRlJBTUUpKQogICAgewogICAgICAgIHdpZHRoID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWERMR0ZSQU1FKSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hFREdFKTsKICAgICAgICBoZWlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRExHRlJBTUUpIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUVER0UpOwogICAgICAgIC8qIFRoaXMgc2hvdWxkIGdpdmUgYSB2YWx1ZSBvZiAxIHRoYXQgc2hvdWxkIGFsc28gd29yayBmb3IgYSBib3JkZXIgKi8KCiAgICAgICAgU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN5c0NvbG9yQnJ1c2goCiAgICAgICAgICAgICAgICAgICAgICAoZXhTdHlsZSAmIChXU19FWF9ETEdNT0RBTEZSQU1FfFdTX0VYX0NMSUVOVEVER0UpKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgQ09MT1JfM0RGQUNFIDoKICAgICAgICAgICAgICAgICAgICAgIChleFN0eWxlICYgV1NfRVhfU1RBVElDRURHRSkgPwogICAgICAgICAgICAgICAgICAgICAgICAgIENPTE9SX1dJTkRPV0ZSQU1FIDoKICAgICAgICAgICAgICAgICAgICAgIChzdHlsZSAmIChXU19ETEdGUkFNRXxXU19USElDS0ZSQU1FKSkgPwogICAgICAgICAgICAgICAgICAgICAgICAgIENPTE9SXzNERkFDRSA6CiAgICAgICAgICAgICAgICAgICAgICAvKiBlbHNlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgQ09MT1JfV0lORE9XRlJBTUUpKTsKCiAgICAgICAgLyogRHJhdyBmcmFtZSAqLwogICAgICAgIFBhdEJsdCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT50b3AsCiAgICAgICAgICAgICAgICAgIHJlY3QtPnJpZ2h0IC0gcmVjdC0+bGVmdCwgaGVpZ2h0LCBQQVRDT1BZICk7CiAgICAgICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAgICAgd2lkdGgsIHJlY3QtPmJvdHRvbSAtIHJlY3QtPnRvcCwgUEFUQ09QWSApOwogICAgICAgIFBhdEJsdCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT5ib3R0b20gLSAxLAogICAgICAgICAgICAgICAgICByZWN0LT5yaWdodCAtIHJlY3QtPmxlZnQsIC1oZWlnaHQsIFBBVENPUFkgKTsKICAgICAgICBQYXRCbHQoIGhkYywgcmVjdC0+cmlnaHQgLSAxLCByZWN0LT50b3AsCiAgICAgICAgICAgICAgICAgIC13aWR0aCwgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLCBQQVRDT1BZICk7CgogICAgICAgIEluZmxhdGVSZWN0KCByZWN0LCAtd2lkdGgsIC1oZWlnaHQgKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfRHJhd0NhcHRpb24KICoKICogRHJhdyB0aGUgd2luZG93IGNhcHRpb24uCiAqIFRoZSBjb3JyZWN0IHBlbiBmb3IgdGhlIHdpbmRvdyBmcmFtZSBtdXN0IGJlIHNlbGVjdGVkIGluIHRoZSBEQy4KICovCnN0YXRpYyB2b2lkIE5DX0RyYXdDYXB0aW9uKCBIREMgaGRjLCBSRUNUICpyZWN0LCBIV05EIGh3bmQsCgkJCSAgICBEV09SRCBzdHlsZSwgQk9PTCBhY3RpdmUgKQp7CiAgICBSRUNUIHIgPSAqcmVjdDsKICAgIGNoYXIgYnVmZmVyWzI1Nl07CgogICAgaWYgKCFoYml0bWFwQ2xvc2UpCiAgICB7CglpZiAoIShoYml0bWFwQ2xvc2UgPSBMb2FkQml0bWFwQSggMCwgTUFLRUlOVFJFU09VUkNFQShPQk1fQ0xPU0UpICkpKSByZXR1cm47CgloYml0bWFwTWluaW1pemUgID0gTG9hZEJpdG1hcEEoIDAsIE1BS0VJTlRSRVNPVVJDRUEoT0JNX1JFRFVDRSkgKTsKCWhiaXRtYXBNaW5pbWl6ZUQgPSBMb2FkQml0bWFwQSggMCwgTUFLRUlOVFJFU09VUkNFQShPQk1fUkVEVUNFRCkgKTsKCWhiaXRtYXBNYXhpbWl6ZSAgPSBMb2FkQml0bWFwQSggMCwgTUFLRUlOVFJFU09VUkNFQShPQk1fWk9PTSkgKTsKCWhiaXRtYXBNYXhpbWl6ZUQgPSBMb2FkQml0bWFwQSggMCwgTUFLRUlOVFJFU09VUkNFQShPQk1fWk9PTUQpICk7CgloYml0bWFwUmVzdG9yZSAgID0gTG9hZEJpdG1hcEEoIDAsIE1BS0VJTlRSRVNPVVJDRUEoT0JNX1JFU1RPUkUpICk7CgloYml0bWFwUmVzdG9yZUQgID0gTG9hZEJpdG1hcEEoIDAsIE1BS0VJTlRSRVNPVVJDRUEoT0JNX1JFU1RPUkVEKSApOwogICAgfQogICAgCiAgICBpZiAoR2V0V2luZG93TG9uZ0EoIGh3bmQsIEdXTF9FWFNUWUxFKSAmIFdTX0VYX0RMR01PREFMRlJBTUUpCiAgICB7CiAgICAgICAgSEJSVVNIIGhicnVzaE9sZCA9IFNlbGVjdE9iamVjdChoZGMsIEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfV0lORE9XKSApOwoJUGF0Qmx0KCBoZGMsIHIubGVmdCwgci50b3AsIDEsIHIuYm90dG9tLXIudG9wKzEsUEFUQ09QWSApOwoJUGF0Qmx0KCBoZGMsIHIucmlnaHQtMSwgci50b3AsIDEsIHIuYm90dG9tLXIudG9wKzEsIFBBVENPUFkgKTsKCVBhdEJsdCggaGRjLCByLmxlZnQsIHIudG9wLTEsIHIucmlnaHQtci5sZWZ0LCAxLCBQQVRDT1BZICk7CglyLmxlZnQrKzsKCXIucmlnaHQtLTsKCVNlbGVjdE9iamVjdCggaGRjLCBoYnJ1c2hPbGQgKTsKICAgIH0KICAgIE1vdmVUb0V4KCBoZGMsIHIubGVmdCwgci5ib3R0b20sIE5VTEwgKTsKICAgIExpbmVUbyggaGRjLCByLnJpZ2h0LCByLmJvdHRvbSApOwoKICAgIGlmIChzdHlsZSAmIFdTX1NZU01FTlUpCiAgICB7CglOQ19EcmF3U3lzQnV0dG9uKCBod25kLCBoZGMsIEZBTFNFICk7CglyLmxlZnQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKCU1vdmVUb0V4KCBoZGMsIHIubGVmdCAtIDEsIHIudG9wLCBOVUxMICk7CglMaW5lVG8oIGhkYywgci5sZWZ0IC0gMSwgci5ib3R0b20gKTsKICAgIH0KICAgIGlmIChzdHlsZSAmIFdTX01BWElNSVpFQk9YKQogICAgewoJTkNfRHJhd01heEJ1dHRvbiggaHduZCwgaGRjLCBGQUxTRSApOwoJci5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwogICAgfQogICAgaWYgKHN0eWxlICYgV1NfTUlOSU1JWkVCT1gpCiAgICB7CglOQ19EcmF3TWluQnV0dG9uKCBod25kLCBoZGMsIEZBTFNFICk7CglyLnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CiAgICB9CgogICAgRmlsbFJlY3QoIGhkYywgJnIsIEdldFN5c0NvbG9yQnJ1c2goYWN0aXZlID8gQ09MT1JfQUNUSVZFQ0FQVElPTiA6CgkJCQkJICAgIENPTE9SX0lOQUNUSVZFQ0FQVElPTikgKTsKCiAgICBpZiAoR2V0V2luZG93VGV4dEEoIGh3bmQsIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikgKSkKICAgIHsKCWlmIChhY3RpdmUpIFNldFRleHRDb2xvciggaGRjLCBHZXRTeXNDb2xvciggQ09MT1JfQ0FQVElPTlRFWFQgKSApOwoJZWxzZSBTZXRUZXh0Q29sb3IoIGhkYywgR2V0U3lzQ29sb3IoIENPTE9SX0lOQUNUSVZFQ0FQVElPTlRFWFQgKSApOwoJU2V0QmtNb2RlKCBoZGMsIFRSQU5TUEFSRU5UICk7CglEcmF3VGV4dEEoIGhkYywgYnVmZmVyLCAtMSwgJnIsCiAgICAgICAgICAgICAgICAgICAgIERUX1NJTkdMRUxJTkUgfCBEVF9DRU5URVIgfCBEVF9WQ0VOVEVSIHwgRFRfTk9QUkVGSVggKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICBOQ19EcmF3Q2FwdGlvbjk1KAogKiAgICAgIEhEQyAgaGRjLAogKiAgICAgIFJFQ1QgKnJlY3QsCiAqICAgICAgSFdORCBod25kLAogKiAgICAgIERXT1JEICBzdHlsZSwKICogICAgICBCT09MIGFjdGl2ZSApCiAqCiAqICAgRHJhdyB0aGUgd2luZG93IGNhcHRpb24gZm9yIFdpbjk1IHN0eWxlIHdpbmRvd3MuCiAqICAgVGhlIGNvcnJlY3QgcGVuIGZvciB0aGUgd2luZG93IGZyYW1lIG11c3QgYmUgc2VsZWN0ZWQgaW4gdGhlIERDLgogKgogKiAgIEJ1Z3MKICogICAgICAgIEhleSwgYSBmdW5jdGlvbiB0aGF0IGZpbmFsbHkgd29ya3MhICBXZWxsLCBhbG1vc3QuCiAqICAgICAgICBJdCdzIGJlaW5nIHdvcmtlZCBvbi4KICoKICogICBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAgICAwNS1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgICAgICAgT3JpZ2luYWwgaW1wbGVtZW50YXRpb24uCiAqICAgICAgICAwMi1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgICAgICBTb21lIG1pbm9yIGZpeGVzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZCAgTkNfRHJhd0NhcHRpb245NSgKICAgIEhEQyAgaGRjLAogICAgUkVDVCAqcmVjdCwKICAgIEhXTkQgaHduZCwKICAgIERXT1JEICBzdHlsZSwKICAgIERXT1JEICBleFN0eWxlLAogICAgQk9PTCBhY3RpdmUgKQp7CiAgICBSRUNUICByID0gKnJlY3Q7CiAgICBjaGFyICAgIGJ1ZmZlclsyNTZdOwogICAgSFBFTiAgaFByZXZQZW47CiAgICBITUVOVSBoU3lzTWVudTsKCiAgICBoUHJldlBlbiA9IFNlbGVjdE9iamVjdCggaGRjLCBHZXRTeXNDb2xvclBlbigKICAgICAgICAgICAgICAgICAgICAgKChleFN0eWxlICYgKFdTX0VYX1NUQVRJQ0VER0V8V1NfRVhfQ0xJRU5URURHRXwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1NfRVhfRExHTU9EQUxGUkFNRSkpID09IFdTX0VYX1NUQVRJQ0VER0UpID8KICAgICAgICAgICAgICAgICAgICAgIENPTE9SX1dJTkRPV0ZSQU1FIDogQ09MT1JfM0RGQUNFKSApOwogICAgTW92ZVRvRXgoIGhkYywgci5sZWZ0LCByLmJvdHRvbSAtIDEsIE5VTEwgKTsKICAgIExpbmVUbyggaGRjLCByLnJpZ2h0LCByLmJvdHRvbSAtIDEgKTsKICAgIFNlbGVjdE9iamVjdCggaGRjLCBoUHJldlBlbiApOwogICAgci5ib3R0b20tLTsKCiAgICBGaWxsUmVjdCggaGRjLCAmciwgR2V0U3lzQ29sb3JCcnVzaChhY3RpdmUgPyBDT0xPUl9BQ1RJVkVDQVBUSU9OIDoKCQkJCQkgICAgQ09MT1JfSU5BQ1RJVkVDQVBUSU9OKSApOwoKICAgIGlmICgoc3R5bGUgJiBXU19TWVNNRU5VKSAmJiAhKGV4U3R5bGUgJiBXU19FWF9UT09MV0lORE9XKSkgewoJaWYgKE5DX0RyYXdTeXNCdXR0b245NSAoaHduZCwgaGRjLCBGQUxTRSkpCgkgICAgci5sZWZ0ICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIDE7CiAgICB9CgogICAgaWYgKHN0eWxlICYgV1NfU1lTTUVOVSkgCiAgICB7CglVSU5UIHN0YXRlOwoKCS8qIEdvIGdldCB0aGUgc3lzbWVudSAqLwoJaFN5c01lbnUgPSBHZXRTeXN0ZW1NZW51KGh3bmQsIEZBTFNFKTsKCXN0YXRlID0gR2V0TWVudVN0YXRlKGhTeXNNZW51LCBTQ19DTE9TRSwgTUZfQllDT01NQU5EKTsKCgkvKiBEcmF3IGEgZ3JheWVkIGNsb3NlIGJ1dHRvbiBpZiBkaXNhYmxlZCBhbmQgYSBub3JtYWwgb25lIGlmIFNDX0NMT1NFIGlzIG5vdCB0aGVyZSAqLwoJTkNfRHJhd0Nsb3NlQnV0dG9uOTUgKGh3bmQsIGhkYywgRkFMU0UsIAoJCQkgICAgICAoKCgoc3RhdGUgJiBNRl9ESVNBQkxFRCkgfHwgKHN0YXRlICYgTUZfR1JBWUVEKSkpICYmIChzdGF0ZSAhPSAweEZGRkZGRkZGKSkpOwoJci5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSAxOwoKCWlmICgoc3R5bGUgJiBXU19NQVhJTUlaRUJPWCkgfHwgKHN0eWxlICYgV1NfTUlOSU1JWkVCT1gpKQoJewoJICAgIC8qIEluIHdpbjk1IHRoZSB0d28gYnV0dG9ucyBhcmUgYWx3YXlzIHRoZXJlICovCgkgICAgLyogQnV0IGlmIHRoZSBtZW51IGl0ZW0gaXMgbm90IGluIHRoZSBtZW51IHRoZXkncmUgZGlzYWJsZWQqLwoKCSAgICBOQ19EcmF3TWF4QnV0dG9uOTUoIGh3bmQsIGhkYywgRkFMU0UsICghKHN0eWxlICYgV1NfTUFYSU1JWkVCT1gpKSk7CgkgICAgci5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwoJICAgIAoJICAgIE5DX0RyYXdNaW5CdXR0b245NSggaHduZCwgaGRjLCBGQUxTRSwgICghKHN0eWxlICYgV1NfTUlOSU1JWkVCT1gpKSk7CgkgICAgci5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwoJfQogICAgfQoKICAgIGlmIChHZXRXaW5kb3dUZXh0QSggaHduZCwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSApKSB7CglOT05DTElFTlRNRVRSSUNTQSBuY2xtOwoJSEZPTlQgaEZvbnQsIGhPbGRGb250OwoJbmNsbS5jYlNpemUgPSBzaXplb2YoTk9OQ0xJRU5UTUVUUklDU0EpOwoJU3lzdGVtUGFyYW1ldGVyc0luZm9BIChTUElfR0VUTk9OQ0xJRU5UTUVUUklDUywgMCwgJm5jbG0sIDApOwoJaWYgKGV4U3R5bGUgJiBXU19FWF9UT09MV0lORE9XKQoJICAgIGhGb250ID0gQ3JlYXRlRm9udEluZGlyZWN0QSAoJm5jbG0ubGZTbUNhcHRpb25Gb250KTsKCWVsc2UKCSAgICBoRm9udCA9IENyZWF0ZUZvbnRJbmRpcmVjdEEgKCZuY2xtLmxmQ2FwdGlvbkZvbnQpOwoJaE9sZEZvbnQgPSBTZWxlY3RPYmplY3QgKGhkYywgaEZvbnQpOwoJaWYgKGFjdGl2ZSkgU2V0VGV4dENvbG9yKCBoZGMsIEdldFN5c0NvbG9yKCBDT0xPUl9DQVBUSU9OVEVYVCApICk7CgllbHNlIFNldFRleHRDb2xvciggaGRjLCBHZXRTeXNDb2xvciggQ09MT1JfSU5BQ1RJVkVDQVBUSU9OVEVYVCApICk7CglTZXRCa01vZGUoIGhkYywgVFJBTlNQQVJFTlQgKTsKCXIubGVmdCArPSAyOwoJRHJhd1RleHRBKCBoZGMsIGJ1ZmZlciwgLTEsICZyLAoJCSAgICAgRFRfU0lOR0xFTElORSB8IERUX1ZDRU5URVIgfCBEVF9OT1BSRUZJWCB8IERUX0xFRlQgKTsKCURlbGV0ZU9iamVjdCAoU2VsZWN0T2JqZWN0IChoZGMsIGhPbGRGb250KSk7CiAgICB9Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19Eb05DUGFpbnQKICoKICogUGFpbnQgdGhlIG5vbi1jbGllbnQgYXJlYS4gY2xpcCBpcyBjdXJyZW50bHkgdW51c2VkLgogKi8Kc3RhdGljIHZvaWQgTkNfRG9OQ1BhaW50KCBXTkQqIHduZFB0ciwgSFJHTiBjbGlwLCBCT09MIHN1cHByZXNzX21lbnVwYWludCApCnsKICAgIEhEQyBoZGM7CiAgICBSRUNUIHJlY3Q7CiAgICBCT09MIGFjdGl2ZTsKICAgIEhXTkQgaHduZCA9IHduZFB0ci0+aHduZFNlbGY7CgogICAgaWYgKCB3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRSB8fAoJIVdJTl9Jc1dpbmRvd0RyYXdhYmxlKCB3bmRQdHIsIDAgKSkgcmV0dXJuOyAvKiBOb3RoaW5nIHRvIGRvICovCgogICAgYWN0aXZlICA9IHduZFB0ci0+ZmxhZ3MgJiBXSU5fTkNBQ1RJVkFURUQ7CgogICAgVFJBQ0UoIiUwNHggJWRcbiIsIGh3bmQsIGFjdGl2ZSApOwoKICAgIGlmICghKGhkYyA9IEdldERDRXgoIGh3bmQsIChjbGlwID4gMSkgPyBjbGlwIDogMCwgRENYX1VTRVNUWUxFIHwgRENYX1dJTkRPVyB8CgkJCSAgICAgICgoY2xpcCA+IDEpID8gKERDWF9JTlRFUlNFQ1RSR04gfCBEQ1hfS0VFUENMSVBSR04pOiAwKSApKSkgcmV0dXJuOwoKICAgIGlmIChFeGNsdWRlVmlzUmVjdDE2KCBoZGMsIHduZFB0ci0+cmVjdENsaWVudC5sZWZ0LXduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0LAoJCSAgICAgICAgd25kUHRyLT5yZWN0Q2xpZW50LnRvcC13bmRQdHItPnJlY3RXaW5kb3cudG9wLAoJCSAgICAgICAgd25kUHRyLT5yZWN0Q2xpZW50LnJpZ2h0LXduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0LAoJCSAgICAgICAgd25kUHRyLT5yZWN0Q2xpZW50LmJvdHRvbS13bmRQdHItPnJlY3RXaW5kb3cudG9wICkKCT09IE5VTExSRUdJT04pCiAgICB7CglSZWxlYXNlREMoIGh3bmQsIGhkYyApOwoJcmV0dXJuOwogICAgfQoKICAgIHJlY3QudG9wID0gcmVjdC5sZWZ0ID0gMDsKICAgIHJlY3QucmlnaHQgID0gd25kUHRyLT5yZWN0V2luZG93LnJpZ2h0IC0gd25kUHRyLT5yZWN0V2luZG93LmxlZnQ7CiAgICByZWN0LmJvdHRvbSA9IHduZFB0ci0+cmVjdFdpbmRvdy5ib3R0b20gLSB3bmRQdHItPnJlY3RXaW5kb3cudG9wOwoKICAgIFNlbGVjdE9iamVjdCggaGRjLCBHZXRTeXNDb2xvclBlbihDT0xPUl9XSU5ET1dGUkFNRSkgKTsKCiAgICBpZiAoSEFTX0FOWUZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICkpCiAgICB7CiAgICAgICAgU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN0b2NrT2JqZWN0KE5VTExfQlJVU0gpICk7CiAgICAgICAgUmVjdGFuZ2xlKCBoZGMsIDAsIDAsIHJlY3QucmlnaHQsIHJlY3QuYm90dG9tICk7CiAgICAgICAgSW5mbGF0ZVJlY3QoICZyZWN0LCAtMSwgLTEgKTsKICAgIH0KCiAgICBpZiAoSEFTX1RISUNLRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgICAgICBOQ19EcmF3RnJhbWUoaGRjLCAmcmVjdCwgRkFMU0UsIGFjdGl2ZSApOwogICAgZWxzZSBpZiAoSEFTX0RMR0ZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICkpCiAgICAgICAgTkNfRHJhd0ZyYW1lKCBoZGMsICZyZWN0LCBUUlVFLCBhY3RpdmUgKTsKCiAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NBUFRJT04pID09IFdTX0NBUFRJT04pCiAgICB7CiAgICAgICAgUkVDVCByID0gcmVjdDsKICAgICAgICByLmJvdHRvbSA9IHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpOwogICAgICAgIHJlY3QudG9wICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpOwogICAgICAgIE5DX0RyYXdDYXB0aW9uKCBoZGMsICZyLCBod25kLCB3bmRQdHItPmR3U3R5bGUsIGFjdGl2ZSApOwogICAgfQoKICAgIGlmIChIQVNfTUVOVSh3bmRQdHIpKQogICAgewoJUkVDVCByID0gcmVjdDsKCXIuYm90dG9tID0gcmVjdC50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZTUVOVSk7ICAvKiBkZWZhdWx0IGhlaWdodCAqLwoJcmVjdC50b3AgKz0gTUVOVV9EcmF3TWVudUJhciggaGRjLCAmciwgaHduZCwgc3VwcHJlc3NfbWVudXBhaW50ICk7CiAgICB9CgogICAgICAvKiBEcmF3IHRoZSBzY3JvbGwtYmFycyAqLwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19WU0NST0xMKQogICAgICAgIFNDUk9MTF9EcmF3U2Nyb2xsQmFyKCBod25kLCBoZGMsIFNCX1ZFUlQsIFRSVUUsIFRSVUUgKTsKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19IU0NST0xMKQogICAgICAgIFNDUk9MTF9EcmF3U2Nyb2xsQmFyKCBod25kLCBoZGMsIFNCX0hPUlosIFRSVUUsIFRSVUUgKTsKCiAgICAgIC8qIERyYXcgdGhlICJzaXplLWJveCIgKi8KCiAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpICYmICh3bmRQdHItPmR3U3R5bGUgJiBXU19IU0NST0xMKSkKICAgIHsKICAgICAgICBSRUNUIHIgPSByZWN0OwogICAgICAgIHIubGVmdCA9IHIucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCkgKyAxOwogICAgICAgIHIudG9wICA9IHIuYm90dG9tIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpICsgMTsKCWlmKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0JPUkRFUikgewoJICByLmxlZnQrKzsKCSAgci50b3ArKzsKCX0KICAgICAgICBGaWxsUmVjdCggaGRjLCAmciwgR2V0U3lzQ29sb3JCcnVzaChDT0xPUl9TQ1JPTExCQVIpICk7CiAgICB9ICAgIAoKICAgIFJlbGVhc2VEQyggaHduZCwgaGRjICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqICAgdm9pZCAgTkNfRG9OQ1BhaW50OTUoCiAqICAgICAgV05EICAqd25kUHRyLAogKiAgICAgIEhSR04gIGNsaXAsCiAqICAgICAgQk9PTCAgc3VwcHJlc3NfbWVudXBhaW50ICkKICoKICogICBQYWludCB0aGUgbm9uLWNsaWVudCBhcmVhIGZvciBXaW45NSB3aW5kb3dzLiAgVGhlIGNsaXAgcmVnaW9uIGlzCiAqICAgY3VycmVudGx5IGlnbm9yZWQuCiAqCiAqICAgQnVncwogKiAgICAgICAgZ3JlcCAtRSAtQTEwIC1CNSBcKDk1XClcfFwoQnVnc1wpXHxcKEZJWE1FXCkgd2luZG93cy9ub25jbGllbnQuYyBcCiAqICAgICAgICAgICBtaXNjL3R3ZWFrLmMgY29udHJvbHMvbWVudS5jICAjIDotKQogKgogKiAgIFJldmlzaW9uIGhpc3RvcnkKICogICAgICAgIDAzLUp1bC0xOTk3IERhdmUgQ3V0aGJlcnQgKGRhY3V0QGVjZS5jbXUuZWR1KQogKiAgICAgICAgICAgICBPcmlnaW5hbCBpbXBsZW1lbnRhdGlvbgogKiAgICAgICAgMTAtSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgICAgICAgRml4ZWQgc29tZSBidWdzLgogKiAgICAgICAgMjktSnVuLTE5OTkgT3ZlIEvldmVuIChvdmVrQGFyY3RpY25ldC5ubykKICogICAgICAgICAgICAgU3RyZWFtbGluZWQgd2luZG93IHN0eWxlIGNoZWNrcy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHZvaWQgIE5DX0RvTkNQYWludDk1KAogICAgV05EICAqd25kUHRyLAogICAgSFJHTiAgY2xpcCwKICAgIEJPT0wgIHN1cHByZXNzX21lbnVwYWludCApCnsKICAgIEhEQyBoZGM7CiAgICBSRUNUIHJmdXp6LCByZWN0LCByZWN0Q2xpcDsKICAgIEJPT0wgYWN0aXZlOwogICAgSFdORCBod25kID0gd25kUHRyLT5od25kU2VsZjsKCiAgICBpZiAoIHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFIHx8CgkhV0lOX0lzV2luZG93RHJhd2FibGUoIHduZFB0ciwgMCApKSByZXR1cm47IC8qIE5vdGhpbmcgdG8gZG8gKi8KCiAgICBhY3RpdmUgID0gd25kUHRyLT5mbGFncyAmIFdJTl9OQ0FDVElWQVRFRDsKCiAgICBUUkFDRSgiJTA0eCAlZFxuIiwgaHduZCwgYWN0aXZlICk7CgogICAgLyogTVNETiBkb2NzIGFyZSBwcmV0dHkgaWRpb3RpYyBoZXJlLCB0aGV5IHNheSBhcHAgQ0FOIHVzZSBjbGlwUmduIGluCiAgICAgICB0aGUgY2FsbCB0byBHZXREQ0V4IGltcGx5aW5nIHRoYXQgaXQgaXMgYWxsb3dlZCBub3QgdG8gdXNlIGl0IGVpdGhlci4KICAgICAgIEhvd2V2ZXIsIHRoZSBzdWdnZXN0ZWQgR2V0RENFeCggICAgLCBEQ1hfV0lORE9XIHwgRENYX0lOVEVSU0VDVFJHTikKICAgICAgIHdpbGwgY2F1c2UgY2xpcFJnbiB0byBiZSBkZWxldGVkIGFmdGVyIFJlbGVhc2VEQygpLgogICAgICAgTm93LCBob3cgaXMgdGhlICJzeXN0ZW0iIHN1cHBvc2VkIHRvIHRlbGwgd2hhdCBoYXBwZW5lZD8KICAgICAqLwoKICAgIGlmICghKGhkYyA9IEdldERDRXgoIGh3bmQsIChjbGlwID4gMSkgPyBjbGlwIDogMCwgRENYX1VTRVNUWUxFIHwgRENYX1dJTkRPVyB8CgkJCSAgICAgICgoY2xpcCA+IDEpID8oRENYX0lOVEVSU0VDVFJHTiB8IERDWF9LRUVQQ0xJUFJHTikgOiAwKSApKSkgcmV0dXJuOwoKCiAgICBpZiAoRXhjbHVkZVZpc1JlY3QxNiggaGRjLCB3bmRQdHItPnJlY3RDbGllbnQubGVmdC13bmRQdHItPnJlY3RXaW5kb3cubGVmdCwKCQkgICAgICAgIHduZFB0ci0+cmVjdENsaWVudC50b3Atd25kUHRyLT5yZWN0V2luZG93LnRvcCwKCQkgICAgICAgIHduZFB0ci0+cmVjdENsaWVudC5yaWdodC13bmRQdHItPnJlY3RXaW5kb3cubGVmdCwKCQkgICAgICAgIHduZFB0ci0+cmVjdENsaWVudC5ib3R0b20td25kUHRyLT5yZWN0V2luZG93LnRvcCApCgk9PSBOVUxMUkVHSU9OKQogICAgewoJUmVsZWFzZURDKCBod25kLCBoZGMgKTsKCXJldHVybjsKICAgIH0KCiAgICByZWN0LnRvcCA9IHJlY3QubGVmdCA9IDA7CiAgICByZWN0LnJpZ2h0ICA9IHduZFB0ci0+cmVjdFdpbmRvdy5yaWdodCAtIHduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0OwogICAgcmVjdC5ib3R0b20gPSB3bmRQdHItPnJlY3RXaW5kb3cuYm90dG9tIC0gd25kUHRyLT5yZWN0V2luZG93LnRvcDsKCiAgICBpZiggY2xpcCA+IDEgKQoJR2V0UmduQm94KCBjbGlwLCAmcmVjdENsaXAgKTsKICAgIGVsc2UKICAgIHsKCWNsaXAgPSAwOwoJcmVjdENsaXAgPSByZWN0OwogICAgfQoKICAgIFNlbGVjdE9iamVjdCggaGRjLCBHZXRTeXNDb2xvclBlbihDT0xPUl9XSU5ET1dGUkFNRSkgKTsKCiAgICBpZiAoSEFTX1NUQVRJQ09VVEVSRlJBTUUod25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSkpIHsKICAgICAgICBEcmF3RWRnZSAoaGRjLCAmcmVjdCwgQkRSX1NVTktFTk9VVEVSLCBCRl9SRUNUIHwgQkZfQURKVVNUKTsKICAgIH0KICAgIGVsc2UgaWYgKEhBU19CSUdGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSkpIHsKICAgICAgICBEcmF3RWRnZSAoaGRjLCAmcmVjdCwgRURHRV9SQUlTRUQsIEJGX1JFQ1QgfCBCRl9BREpVU1QpOwogICAgfQoKICAgIE5DX0RyYXdGcmFtZTk1KGhkYywgJnJlY3QsIGFjdGl2ZSwgd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApOwoKICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfQ0FQVElPTikgPT0gV1NfQ0FQVElPTikKICAgIHsKICAgICAgICBSRUNUICByID0gcmVjdDsKICAgICAgICBpZiAod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9UT09MV0lORE9XKSB7CiAgICAgICAgICAgIHIuYm90dG9tID0gcmVjdC50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01DQVBUSU9OKTsKICAgICAgICAgICAgcmVjdC50b3AgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNQ0FQVElPTik7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICByLmJvdHRvbSA9IHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pOwogICAgICAgICAgICByZWN0LnRvcCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTik7CiAgICAgICAgfQogICAgICAgIGlmKCAhY2xpcCB8fCBJbnRlcnNlY3RSZWN0KCAmcmZ1enosICZyLCAmcmVjdENsaXAgKSApCiAgICAgICAgICAgIE5DX0RyYXdDYXB0aW9uOTUgKGhkYywgJnIsIGh3bmQsIHduZFB0ci0+ZHdTdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd25kUHRyLT5kd0V4U3R5bGUsIGFjdGl2ZSk7CiAgICB9CgogICAgaWYgKEhBU19NRU5VKHduZFB0cikpCiAgICB7CglSRUNUIHIgPSByZWN0OwoJci5ib3R0b20gPSByZWN0LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lNRU5VKTsKCQoJVFJBQ0UoIkNhbGxpbmcgRHJhd01lbnVCYXIgd2l0aCByZWN0ICglZCwgJWQpLSglZCwgJWQpXG4iLAogICAgICAgICAgICAgIHIubGVmdCwgci50b3AsIHIucmlnaHQsIHIuYm90dG9tKTsKCglyZWN0LnRvcCArPSBNRU5VX0RyYXdNZW51QmFyKCBoZGMsICZyLCBod25kLCBzdXBwcmVzc19tZW51cGFpbnQgKSArIDE7CiAgICB9CgogICAgVFJBQ0UoIkFmdGVyIE1lbnVCYXIsIHJlY3QgaXMgKCVkLCAlZCktKCVkLCAlZCkuXG4iLAogICAgICAgICAgcmVjdC5sZWZ0LCByZWN0LnRvcCwgcmVjdC5yaWdodCwgcmVjdC5ib3R0b20gKTsKCiAgICBpZiAod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9DTElFTlRFREdFKQoJRHJhd0VkZ2UgKGhkYywgJnJlY3QsIEVER0VfU1VOS0VOLCBCRl9SRUNUIHwgQkZfQURKVVNUKTsKCiAgICAvKiBEcmF3IHRoZSBzY3JvbGwtYmFycyAqLwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19WU0NST0xMKQogICAgICAgIFNDUk9MTF9EcmF3U2Nyb2xsQmFyKCBod25kLCBoZGMsIFNCX1ZFUlQsIFRSVUUsIFRSVUUgKTsKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19IU0NST0xMKQogICAgICAgIFNDUk9MTF9EcmF3U2Nyb2xsQmFyKCBod25kLCBoZGMsIFNCX0hPUlosIFRSVUUsIFRSVUUgKTsKCiAgICAvKiBEcmF3IHRoZSAic2l6ZS1ib3giICovCiAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpICYmICh3bmRQdHItPmR3U3R5bGUgJiBXU19IU0NST0xMKSkKICAgIHsKICAgICAgICBSRUNUIHIgPSByZWN0OwogICAgICAgIHIubGVmdCA9IHIucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCkgKyAxOwogICAgICAgIHIudG9wICA9IHIuYm90dG9tIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpICsgMTsKICAgICAgICBGaWxsUmVjdCggaGRjLCAmciwgIEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfU0NST0xMQkFSKSApOwogICAgfSAgICAKCiAgICBSZWxlYXNlREMoIGh3bmQsIGhkYyApOwp9CgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZU5DUGFpbnQKICoKICogSGFuZGxlIGEgV01fTkNQQUlOVCBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZU5DUGFpbnQoIEhXTkQgaHduZCAsIEhSR04gY2xpcCkKewogICAgV05EKiB3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwoKICAgIGlmKCB3bmRQdHIgJiYgd25kUHRyLT5kd1N0eWxlICYgV1NfVklTSUJMRSApCiAgICB7CglpZiggd25kUHRyLT5kd1N0eWxlICYgV1NfTUlOSU1JWkUgKQoJICAgIFdJTlBPU19SZWRyYXdJY29uVGl0bGUoIGh3bmQgKTsKCWVsc2UgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCgkgICAgTkNfRG9OQ1BhaW50KCB3bmRQdHIsIGNsaXAsIEZBTFNFICk7CgllbHNlCgkgICAgTkNfRG9OQ1BhaW50OTUoIHduZFB0ciwgY2xpcCwgRkFMU0UgKTsKICAgIH0KICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7CiAgICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfSGFuZGxlTkNBY3RpdmF0ZQogKgogKiBIYW5kbGUgYSBXTV9OQ0FDVElWQVRFIG1lc3NhZ2UuIENhbGxlZCBmcm9tIERlZldpbmRvd1Byb2MoKS4KICovCkxPTkcgTkNfSGFuZGxlTkNBY3RpdmF0ZSggSFdORCBod25kLCBXUEFSQU0gd1BhcmFtICkKewogICAgV05EKiB3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwoKICAgIC8qIExvdHVzIE5vdGVzIGRyYXdzIG1lbnUgZGVzY3JpcHRpb25zIGluIHRoZSBjYXB0aW9uIG9mIGl0cyBtYWluCiAgICAgKiB3aW5kb3cuIFdoZW4gaXQgd2FudHMgdG8gcmVzdG9yZSBvcmlnaW5hbCAic3lzdGVtIiB2aWV3LCBpdCBqdXN0CiAgICAgKiBzZW5kcyBXTV9OQ0FDVElWQVRFIG1lc3NhZ2UgdG8gaXRzZWxmLiBBbnkgb3B0aW1pemF0aW9ucyBoZXJlIGluCiAgICAgKiBhdHRlbXB0IHRvIG1pbmltaXplIHJlZHJhd2luZ3MgbGVhZCB0byBhIG5vdCByZXN0b3JlZCBjYXB0aW9uLgogICAgICovCiAgICBpZiAod25kUHRyKQogICAgewoJaWYgKHdQYXJhbSkgd25kUHRyLT5mbGFncyB8PSBXSU5fTkNBQ1RJVkFURUQ7CgllbHNlIHduZFB0ci0+ZmxhZ3MgJj0gfldJTl9OQ0FDVElWQVRFRDsKCglpZiAoSXNJY29uaWMoaHduZCkpIFdJTlBPU19SZWRyYXdJY29uVGl0bGUoIGh3bmQgKTsKCWVsc2UgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCgkgICAgTkNfRG9OQ1BhaW50KCB3bmRQdHIsIChIUkdOKTEsIEZBTFNFICk7CgllbHNlCgkgICAgTkNfRG9OQ1BhaW50OTUoIHduZFB0ciwgKEhSR04pMSwgRkFMU0UgKTsKICAgICAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZVNldEN1cnNvcgogKgogKiBIYW5kbGUgYSBXTV9TRVRDVVJTT1IgbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVTZXRDdXJzb3IoIEhXTkQgaHduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSApCnsKICAgIGlmIChod25kICE9IChIV05EKXdQYXJhbSkgcmV0dXJuIDA7ICAvKiBEb24ndCBzZXQgdGhlIGN1cnNvciBmb3IgY2hpbGQgd2luZG93cyAqLwoKICAgIHN3aXRjaChMT1dPUkQobFBhcmFtKSkKICAgIHsKICAgIGNhc2UgSFRFUlJPUjoKCXsKCSAgICBXT1JEIG1zZyA9IEhJV09SRCggbFBhcmFtICk7CgkgICAgaWYgKChtc2cgPT0gV01fTEJVVFRPTkRPV04pIHx8IChtc2cgPT0gV01fTUJVVFRPTkRPV04pIHx8CgkJKG1zZyA9PSBXTV9SQlVUVE9ORE9XTikpCgkJTWVzc2FnZUJlZXAoMCk7Cgl9CglicmVhazsKCiAgICBjYXNlIEhUQ0xJRU5UOgoJewoJICAgIEhDVVJTT1IgaEN1cnNvciA9IEdldENsYXNzTG9uZ0EoaHduZCwgR0NMX0hDVVJTT1IpOwoJICAgIGlmKGhDdXJzb3IpIHsKCQlTZXRDdXJzb3IoaEN1cnNvcik7CgkJcmV0dXJuIFRSVUU7CgkgICAgfQogICAgICAgICAgICByZXR1cm4gRkFMU0U7Cgl9CgogICAgY2FzZSBIVExFRlQ6CiAgICBjYXNlIEhUUklHSFQ6CglyZXR1cm4gKExPTkcpU2V0Q3Vyc29yKCBMb2FkQ3Vyc29yQSggMCwgSURDX1NJWkVXRUEgKSApOwoKICAgIGNhc2UgSFRUT1A6CiAgICBjYXNlIEhUQk9UVE9NOgoJcmV0dXJuIChMT05HKVNldEN1cnNvciggTG9hZEN1cnNvckEoIDAsIElEQ19TSVpFTlNBICkgKTsKCiAgICBjYXNlIEhUVE9QTEVGVDoKICAgIGNhc2UgSFRCT1RUT01SSUdIVDoJCglyZXR1cm4gKExPTkcpU2V0Q3Vyc29yKCBMb2FkQ3Vyc29yQSggMCwgSURDX1NJWkVOV1NFQSApICk7CgogICAgY2FzZSBIVFRPUFJJR0hUOgogICAgY2FzZSBIVEJPVFRPTUxFRlQ6CglyZXR1cm4gKExPTkcpU2V0Q3Vyc29yKCBMb2FkQ3Vyc29yQSggMCwgSURDX1NJWkVORVNXQSApICk7CiAgICB9CgogICAgLyogRGVmYXVsdCBjdXJzb3I6IGFycm93ICovCiAgICByZXR1cm4gKExPTkcpU2V0Q3Vyc29yKCBMb2FkQ3Vyc29yQSggMCwgSURDX0FSUk9XQSApICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfR2V0U3lzUG9wdXBQb3MKICovCnZvaWQgTkNfR2V0U3lzUG9wdXBQb3MoIEhXTkQgaHduZCwgUkVDVCogcmVjdCApCnsKICAgIGlmIChJc0ljb25pYyhod25kKSkgR2V0V2luZG93UmVjdCggaHduZCwgcmVjdCApOwogICAgZWxzZQogICAgewogICAgICAgIFdORCAqd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKICAgICAgICBpZiAoIXduZFB0cikgcmV0dXJuOwoKICAgICAgICBOQ19HZXRJbnNpZGVSZWN0KCBod25kLCByZWN0ICk7CiAgICAgICAgT2Zmc2V0UmVjdCggcmVjdCwgd25kUHRyLT5yZWN0V2luZG93LmxlZnQsIHduZFB0ci0+cmVjdFdpbmRvdy50b3ApOwogICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19DSElMRCkKICAgICAgICAgICAgQ2xpZW50VG9TY3JlZW4oIHduZFB0ci0+cGFyZW50LT5od25kU2VsZiwgKFBPSU5UICopcmVjdCApOwogICAgICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKSB7CiAgICAgICAgICAgIHJlY3QtPnJpZ2h0ID0gcmVjdC0+bGVmdCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKTsKICAgICAgICAgICAgcmVjdC0+Ym90dG9tID0gcmVjdC0+dG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcmVjdC0+cmlnaHQgPSByZWN0LT5sZWZ0ICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKICAgICAgICAgICAgcmVjdC0+Ym90dG9tID0gcmVjdC0+dG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKICAgICAgICB9CiAgICAgICAgV0lOX1JlbGVhc2VXbmRQdHIoIHduZFB0ciApOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX1RyYWNrTWluTWF4Qm94OTUKICoKICogVHJhY2sgYSBtb3VzZSBidXR0b24gcHJlc3Mgb24gdGhlIG1pbmltaXplIG9yIG1heGltaXplIGJveC4KICoKICogVGhlIGJpZyBkaWZmZXJlbmNlIGJldHdlZW4gMy4xIGFuZCA5NSBpcyB0aGUgZGlzYWJsZWQgYnV0dG9uIHN0YXRlLgogKiBJbiB3aW45NSB0aGUgc3lzdGVtIGJ1dHRvbiBjYW4gYmUgZGlzYWJsZWQsIHNvIGl0IGNhbiBpZ25vcmUgdGhlIG1vdXNlCiAqIGV2ZW50LgogKgogKi8Kc3RhdGljIHZvaWQgTkNfVHJhY2tNaW5NYXhCb3g5NSggSFdORCBod25kLCBXT1JEIHdQYXJhbSApCnsKICAgIE1TRyBtc2c7CiAgICBIREMgaGRjID0gR2V0V2luZG93REMoIGh3bmQgKTsKICAgIEJPT0wgcHJlc3NlZCA9IFRSVUU7CiAgICBVSU5UIHN0YXRlOwogICAgRFdPUkQgd25kU3R5bGUgPSBHZXRXaW5kb3dMb25nQSggaHduZCwgR1dMX1NUWUxFKTsKICAgIEhNRU5VIGhTeXNNZW51ID0gR2V0U3lzdGVtTWVudShod25kLCBGQUxTRSk7CgogICAgdm9pZCAgKCpwYWludEJ1dHRvbikoSFdORCwgSERDMTYsIEJPT0wsIEJPT0wpOwoKICAgIGlmICh3UGFyYW0gPT0gSFRNSU5CVVRUT04pCiAgICB7CgkvKiBJZiB0aGUgc3R5bGUgaXMgbm90IHByZXNlbnQsIGRvIG5vdGhpbmcgKi8KCWlmICghKHduZFN0eWxlICYgV1NfTUlOSU1JWkVCT1gpKQoJICAgIHJldHVybjsKCgkvKiBDaGVjayBpZiB0aGUgc3lzbWVudSBpdGVtIGZvciBtaW5pbWl6ZSBpcyB0aGVyZSAgKi8KCXN0YXRlID0gR2V0TWVudVN0YXRlKGhTeXNNZW51LCBTQ19NSU5JTUlaRSwgTUZfQllDT01NQU5EKTsKCQoJcGFpbnRCdXR0b24gPSAmTkNfRHJhd01pbkJ1dHRvbjk1OwogICAgfQogICAgZWxzZQogICAgewoJLyogSWYgdGhlIHN0eWxlIGlzIG5vdCBwcmVzZW50LCBkbyBub3RoaW5nICovCglpZiAoISh3bmRTdHlsZSAmIFdTX01BWElNSVpFQk9YKSkKCSAgICByZXR1cm47CgoJLyogQ2hlY2sgaWYgdGhlIHN5c21lbnUgaXRlbSBmb3IgbWF4aW1pemUgaXMgdGhlcmUgICovCglzdGF0ZSA9IEdldE1lbnVTdGF0ZShoU3lzTWVudSwgU0NfTUFYSU1JWkUsIE1GX0JZQ09NTUFORCk7CgkKCXBhaW50QnV0dG9uID0gJk5DX0RyYXdNYXhCdXR0b245NTsKICAgIH0KCiAgICBTZXRDYXB0dXJlKCBod25kICk7CgogICAgKCpwYWludEJ1dHRvbikoIGh3bmQsIGhkYywgVFJVRSwgRkFMU0UpOwoKICAgIHdoaWxlKDEpCiAgICB7CglCT09MIG9sZHN0YXRlID0gcHJlc3NlZDsKCiAgICAgICAgaWYgKCFHZXRNZXNzYWdlVyggJm1zZywgMCwgV01fTU9VU0VGSVJTVCwgV01fTU9VU0VMQVNUICkpIGJyZWFrOwogICAgICAgIGlmIChDYWxsTXNnRmlsdGVyVyggJm1zZywgTVNHRl9NQVggKSkgY29udGludWU7CgoJaWYobXNnLm1lc3NhZ2UgPT0gV01fTEJVVFRPTlVQKQoJICAgIGJyZWFrOwoKCWlmKG1zZy5tZXNzYWdlICE9IFdNX01PVVNFTU9WRSkKCSAgICBjb250aW51ZTsKCglwcmVzc2VkID0gKE5DX0hhbmRsZU5DSGl0VGVzdCggaHduZCwgbXNnLnB0ICkgPT0gd1BhcmFtKTsKCWlmIChwcmVzc2VkICE9IG9sZHN0YXRlKQoJICAgKCpwYWludEJ1dHRvbikoIGh3bmQsIGhkYywgcHJlc3NlZCwgRkFMU0UpOwogICAgfQoKICAgIGlmKHByZXNzZWQpCgkoKnBhaW50QnV0dG9uKShod25kLCBoZGMsIEZBTFNFLCBGQUxTRSk7CgogICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgIFJlbGVhc2VEQyggaHduZCwgaGRjICk7CgogICAgLyogSWYgdGhlIGl0ZW0gbWluaW1pemUgb3IgbWF4aW1pemUgb2YgdGhlIHN5c21lbnUgYXJlIG5vdCB0aGVyZSAqLwogICAgLyogb3IgaWYgdGhlIHN0eWxlIGlzIG5vdCBwcmVzZW50LCBkbyBub3RoaW5nICovCiAgICBpZiAoKCFwcmVzc2VkKSB8fCAoc3RhdGUgPT0gMHhGRkZGRkZGRikpCglyZXR1cm47CgogICAgaWYgKHdQYXJhbSA9PSBIVE1JTkJVVFRPTikgCiAgICAgICAgU2VuZE1lc3NhZ2VBKCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19NSU5JTUlaRSwgTUFLRUxPTkcobXNnLnB0LngsbXNnLnB0LnkpICk7CiAgICBlbHNlCiAgICAgICAgU2VuZE1lc3NhZ2VBKCBod25kLCBXTV9TWVNDT01NQU5ELAogICAgICAgICAgICAgICAgICAgICAgSXNab29tZWQoaHduZCkgPyBTQ19SRVNUT1JFOlNDX01BWElNSVpFLCBNQUtFTE9ORyhtc2cucHQueCxtc2cucHQueSkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19UcmFja01pbk1heEJveAogKgogKiBUcmFjayBhIG1vdXNlIGJ1dHRvbiBwcmVzcyBvbiB0aGUgbWluaW1pemUgb3IgbWF4aW1pemUgYm94LgogKi8Kc3RhdGljIHZvaWQgTkNfVHJhY2tNaW5NYXhCb3goIEhXTkQgaHduZCwgV09SRCB3UGFyYW0gKQp7CiAgICBNU0cgbXNnOwogICAgSERDIGhkYyA9IEdldFdpbmRvd0RDKCBod25kICk7CiAgICBCT09MIHByZXNzZWQgPSBUUlVFOwogICAgdm9pZCAgKCpwYWludEJ1dHRvbikoSFdORCwgSERDMTYsIEJPT0wpOwoKICAgIFNldENhcHR1cmUoIGh3bmQgKTsKCiAgICBpZiAod1BhcmFtID09IEhUTUlOQlVUVE9OKQoJcGFpbnRCdXR0b24gPSAmTkNfRHJhd01pbkJ1dHRvbjsKICAgIGVsc2UKCXBhaW50QnV0dG9uID0gJk5DX0RyYXdNYXhCdXR0b247CgogICAgKCpwYWludEJ1dHRvbikoIGh3bmQsIGhkYywgVFJVRSk7CgogICAgd2hpbGUoMSkKICAgIHsKCUJPT0wgb2xkc3RhdGUgPSBwcmVzc2VkOwoKICAgICAgICBpZiAoIUdldE1lc3NhZ2VXKCAmbXNnLCAwLCBXTV9NT1VTRUZJUlNULCBXTV9NT1VTRUxBU1QgKSkgYnJlYWs7CiAgICAgICAgaWYgKENhbGxNc2dGaWx0ZXJXKCAmbXNnLCBNU0dGX01BWCApKSBjb250aW51ZTsKCglpZihtc2cubWVzc2FnZSA9PSBXTV9MQlVUVE9OVVApCgkgICAgYnJlYWs7CgoJaWYobXNnLm1lc3NhZ2UgIT0gV01fTU9VU0VNT1ZFKQoJICAgIGNvbnRpbnVlOwoKCXByZXNzZWQgPSAoTkNfSGFuZGxlTkNIaXRUZXN0KCBod25kLCBtc2cucHQgKSA9PSB3UGFyYW0pOwoJaWYgKHByZXNzZWQgIT0gb2xkc3RhdGUpCgkgICAoKnBhaW50QnV0dG9uKSggaHduZCwgaGRjLCBwcmVzc2VkKTsKICAgIH0KCiAgICBpZihwcmVzc2VkKQoJKCpwYWludEJ1dHRvbikoIGh3bmQsIGhkYywgRkFMU0UpOwoKICAgIFJlbGVhc2VDYXB0dXJlKCk7CiAgICBSZWxlYXNlREMoIGh3bmQsIGhkYyApOwoKICAgIGlmICghcHJlc3NlZCkgcmV0dXJuOwoKICAgIGlmICh3UGFyYW0gPT0gSFRNSU5CVVRUT04pIAogICAgICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfTUlOSU1JWkUsIE1BS0VMT05HKG1zZy5wdC54LG1zZy5wdC55KSApOwogICAgZWxzZQogICAgICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fU1lTQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgIElzWm9vbWVkKGh3bmQpID8gU0NfUkVTVE9SRTpTQ19NQVhJTUlaRSwgTUFLRUxPTkcobXNnLnB0LngsbXNnLnB0LnkpICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTkNfVHJhY2tDbG9zZUJ1dHRvbjk1CiAqCiAqIFRyYWNrIGEgbW91c2UgYnV0dG9uIHByZXNzIG9uIHRoZSBXaW45NSBjbG9zZSBidXR0b24uCiAqLwpzdGF0aWMgdm9pZApOQ19UcmFja0Nsb3NlQnV0dG9uOTUgKEhXTkQgaHduZCwgV09SRCB3UGFyYW0pCnsKICAgIE1TRyBtc2c7CiAgICBIREMgaGRjOwogICAgQk9PTCBwcmVzc2VkID0gVFJVRTsKICAgIEhNRU5VIGhTeXNNZW51ID0gR2V0U3lzdGVtTWVudShod25kLCBGQUxTRSk7CiAgICBVSU5UIHN0YXRlOwoKICAgIGlmKGhTeXNNZW51ID09IDApCglyZXR1cm47CgogICAgc3RhdGUgPSBHZXRNZW51U3RhdGUoaFN5c01lbnUsIFNDX0NMT1NFLCBNRl9CWUNPTU1BTkQpOwoJICAgIAogICAgLyogSWYgdGhlIGl0ZW0gY2xvc2Ugb2YgdGhlIHN5c21lbnUgaXMgZGlzYWJsZWQgb3Igbm90IHRoZXJlIGRvIG5vdGhpbmcgKi8KICAgIGlmKChzdGF0ZSAmIE1GX0RJU0FCTEVEKSB8fCAoc3RhdGUgJiBNRl9HUkFZRUQpIHx8IChzdGF0ZSA9PSAweEZGRkZGRkZGKSkKCXJldHVybjsKCiAgICBoZGMgPSBHZXRXaW5kb3dEQyggaHduZCApOwoKICAgIFNldENhcHR1cmUoIGh3bmQgKTsKCiAgICBOQ19EcmF3Q2xvc2VCdXR0b245NSAoaHduZCwgaGRjLCBUUlVFLCBGQUxTRSk7CgogICAgd2hpbGUoMSkKICAgIHsKCUJPT0wgb2xkc3RhdGUgPSBwcmVzc2VkOwoKICAgICAgICBpZiAoIUdldE1lc3NhZ2VXKCAmbXNnLCAwLCBXTV9NT1VTRUZJUlNULCBXTV9NT1VTRUxBU1QgKSkgYnJlYWs7CiAgICAgICAgaWYgKENhbGxNc2dGaWx0ZXJXKCAmbXNnLCBNU0dGX01BWCApKSBjb250aW51ZTsKCglpZihtc2cubWVzc2FnZSA9PSBXTV9MQlVUVE9OVVApCgkgICAgYnJlYWs7CgoJaWYobXNnLm1lc3NhZ2UgIT0gV01fTU9VU0VNT1ZFKQoJICAgIGNvbnRpbnVlOwoKCXByZXNzZWQgPSAoTkNfSGFuZGxlTkNIaXRUZXN0KCBod25kLCBtc2cucHQgKSA9PSB3UGFyYW0pOwoJaWYgKHByZXNzZWQgIT0gb2xkc3RhdGUpCgkgICBOQ19EcmF3Q2xvc2VCdXR0b245NSAoaHduZCwgaGRjLCBwcmVzc2VkLCBGQUxTRSk7CiAgICB9CgogICAgaWYocHJlc3NlZCkKCU5DX0RyYXdDbG9zZUJ1dHRvbjk1IChod25kLCBoZGMsIEZBTFNFLCBGQUxTRSk7CgogICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgIFJlbGVhc2VEQyggaHduZCwgaGRjICk7CiAgICBpZiAoIXByZXNzZWQpIHJldHVybjsKCiAgICBTZW5kTWVzc2FnZUEoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX0NMT1NFLCBNQUtFTE9ORyhtc2cucHQueCxtc2cucHQueSkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfVHJhY2tTY3JvbGxCYXIKICoKICogVHJhY2sgYSBtb3VzZSBidXR0b24gcHJlc3Mgb24gdGhlIGhvcml6b250YWwgb3IgdmVydGljYWwgc2Nyb2xsLWJhci4KICovCnN0YXRpYyB2b2lkIE5DX1RyYWNrU2Nyb2xsQmFyKCBIV05EIGh3bmQsIFdQQVJBTSB3UGFyYW0sIFBPSU5UIHB0ICkKewogICAgTVNHIG1zZzsKICAgIElOVCBzY3JvbGxiYXI7CiAgICBXTkQgKnduZFB0ciA9IFdJTl9GaW5kV25kUHRyKCBod25kICk7CgogICAgaWYgKCh3UGFyYW0gJiAweGZmZjApID09IFNDX0hTQ1JPTEwpCiAgICB7CglpZiAoKHdQYXJhbSAmIDB4MGYpICE9IEhUSFNDUk9MTCkgZ290byBFTkQ7CglzY3JvbGxiYXIgPSBTQl9IT1JaOwogICAgfQogICAgZWxzZSAgLyogU0NfVlNDUk9MTCAqLwogICAgewoJaWYgKCh3UGFyYW0gJiAweDBmKSAhPSBIVFZTQ1JPTEwpIGdvdG8gRU5EOwoJc2Nyb2xsYmFyID0gU0JfVkVSVDsKICAgIH0KCiAgICBwdC54IC09IHduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0OwogICAgcHQueSAtPSB3bmRQdHItPnJlY3RXaW5kb3cudG9wOwogICAgU2V0Q2FwdHVyZSggaHduZCApOwogICAgU0NST0xMX0hhbmRsZVNjcm9sbEV2ZW50KCBod25kLCBzY3JvbGxiYXIsIFdNX0xCVVRUT05ET1dOLCBwdCApOwoKICAgIGRvCiAgICB7CiAgICAgICAgaWYgKCFHZXRNZXNzYWdlVyggJm1zZywgMCwgMCwgMCApKSBicmVhazsKICAgICAgICBpZiAoQ2FsbE1zZ0ZpbHRlclcoICZtc2csIE1TR0ZfU0NST0xMQkFSICkpIGNvbnRpbnVlOwoJc3dpdGNoKG1zZy5tZXNzYWdlKQoJewoJY2FzZSBXTV9MQlVUVE9OVVA6CgljYXNlIFdNX01PVVNFTU9WRToKICAgICAgICBjYXNlIFdNX1NZU1RJTUVSOgogICAgICAgICAgICBwdC54ID0gTE9XT1JEKG1zZy5sUGFyYW0pICsgd25kUHRyLT5yZWN0Q2xpZW50LmxlZnQgLSB3bmRQdHItPnJlY3RXaW5kb3cubGVmdDsKICAgICAgICAgICAgcHQueSA9IEhJV09SRChtc2cubFBhcmFtKSArIHduZFB0ci0+cmVjdENsaWVudC50b3AgLSB3bmRQdHItPnJlY3RXaW5kb3cudG9wOwogICAgICAgICAgICBTQ1JPTExfSGFuZGxlU2Nyb2xsRXZlbnQoIGh3bmQsIHNjcm9sbGJhciwgbXNnLm1lc3NhZ2UsIHB0ICk7CgkgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgVHJhbnNsYXRlTWVzc2FnZSggJm1zZyApOwogICAgICAgICAgICBEaXNwYXRjaE1lc3NhZ2VXKCAmbXNnICk7CiAgICAgICAgICAgIGJyZWFrOwoJfQogICAgICAgIGlmICghSXNXaW5kb3coIGh3bmQgKSkKICAgICAgICB7CiAgICAgICAgICAgIFJlbGVhc2VDYXB0dXJlKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0gd2hpbGUgKG1zZy5tZXNzYWdlICE9IFdNX0xCVVRUT05VUCk7CkVORDoKICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfSGFuZGxlTkNMQnV0dG9uRG93bgogKgogKiBIYW5kbGUgYSBXTV9OQ0xCVVRUT05ET1dOIG1lc3NhZ2UuIENhbGxlZCBmcm9tIERlZldpbmRvd1Byb2MoKS4KICovCkxPTkcgTkNfSGFuZGxlTkNMQnV0dG9uRG93biggSFdORCBod25kLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtICkKewogICAgTE9ORyBzdHlsZSA9IEdldFdpbmRvd0xvbmdBKCBod25kLCBHV0xfU1RZTEUgKTsKCiAgICBzd2l0Y2god1BhcmFtKSAgLyogSGl0IHRlc3QgKi8KICAgIHsKICAgIGNhc2UgSFRDQVBUSU9OOgogICAgICAgIHsKICAgICAgICAgICAgSFdORCB0b3AgPSBXSU5fR2V0VG9wUGFyZW50KGh3bmQpOwoKICAgICAgICAgICAgaWYoIFdJTlBPU19TZXRBY3RpdmVXaW5kb3codG9wLCBUUlVFLCBUUlVFKSB8fCAoR2V0QWN0aXZlV2luZG93KCkgPT0gdG9wKSApCiAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZVcoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX01PVkUgKyBIVENBUFRJT04sIGxQYXJhbSApOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgY2FzZSBIVFNZU01FTlU6CgkgaWYoIHN0eWxlICYgV1NfU1lTTUVOVSApCgkgewoJICAgICBpZiggIShzdHlsZSAmIFdTX01JTklNSVpFKSApCgkgICAgIHsKCQlIREMgaERDID0gR2V0V2luZG93REMoaHduZCk7CgkJaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCgkJICAgIE5DX0RyYXdTeXNCdXR0b24oIGh3bmQsIGhEQywgVFJVRSApOwoJCWVsc2UKCQkgICAgTkNfRHJhd1N5c0J1dHRvbjk1KCBod25kLCBoREMsIFRSVUUgKTsKCQlSZWxlYXNlREMoIGh3bmQsIGhEQyApOwoJICAgICB9CgkgICAgIFNlbmRNZXNzYWdlVyggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfTU9VU0VNRU5VICsgSFRTWVNNRU5VLCBsUGFyYW0gKTsKCSB9CgkgYnJlYWs7CgogICAgY2FzZSBIVE1FTlU6CglTZW5kTWVzc2FnZVcoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX01PVVNFTUVOVSwgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUSFNDUk9MTDoKCVNlbmRNZXNzYWdlVyggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfSFNDUk9MTCArIEhUSFNDUk9MTCwgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUVlNDUk9MTDoKCVNlbmRNZXNzYWdlVyggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfVlNDUk9MTCArIEhUVlNDUk9MTCwgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUTUlOQlVUVE9OOgogICAgY2FzZSBIVE1BWEJVVFRPTjoKCWlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQoJICAgIE5DX1RyYWNrTWluTWF4Qm94KCBod25kLCB3UGFyYW0gKTsKCWVsc2UKCSAgICBOQ19UcmFja01pbk1heEJveDk1KCBod25kLCB3UGFyYW0gKTsJICAgIAoJYnJlYWs7CgogICAgY2FzZSBIVENMT1NFOgoJaWYgKFRXRUFLX1dpbmVMb29rID49IFdJTjk1X0xPT0spCgkgICAgTkNfVHJhY2tDbG9zZUJ1dHRvbjk1IChod25kLCB3UGFyYW0pOwoJYnJlYWs7CgkKICAgIGNhc2UgSFRMRUZUOgogICAgY2FzZSBIVFJJR0hUOgogICAgY2FzZSBIVFRPUDoKICAgIGNhc2UgSFRUT1BMRUZUOgogICAgY2FzZSBIVFRPUFJJR0hUOgogICAgY2FzZSBIVEJPVFRPTToKICAgIGNhc2UgSFRCT1RUT01MRUZUOgogICAgY2FzZSBIVEJPVFRPTVJJR0hUOgoJLyogbWFrZSBzdXJlIGhpdHRlc3QgZml0cyBpbnRvIDB4ZiBhbmQgZG9lc24ndCBvdmVybGFwIHdpdGggSFRTWVNNRU5VICovCglTZW5kTWVzc2FnZVcoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX1NJWkUgKyB3UGFyYW0gLSAyLCBsUGFyYW0pOwoJYnJlYWs7CgogICAgY2FzZSBIVEJPUkRFUjoKCWJyZWFrOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZU5DTEJ1dHRvbkRibENsawogKgogKiBIYW5kbGUgYSBXTV9OQ0xCVVRUT05EQkxDTEsgbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVOQ0xCdXR0b25EYmxDbGsoIEhXTkQgaHduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSApCnsKICAgIC8qCiAgICAgKiBpZiB0aGlzIGlzIGFuIGljb24sIHNlbmQgYSByZXN0b3JlIHNpbmNlIHdlIGFyZSBoYW5kbGluZwogICAgICogYSBkb3VibGUgY2xpY2sKICAgICAqLwogICAgaWYgKElzSWNvbmljKGh3bmQpKQogICAgewogICAgICAgIFNlbmRNZXNzYWdlVyggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfUkVTVE9SRSwgbFBhcmFtICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9IAoKICAgIHN3aXRjaCh3UGFyYW0pICAvKiBIaXQgdGVzdCAqLwogICAgewogICAgY2FzZSBIVENBUFRJT046CiAgICAgICAgLyogc3RvcCBwcm9jZXNzaW5nIGlmIFdTX01BWElNSVpFQk9YIGlzIG1pc3NpbmcgKi8KICAgICAgICBpZiAoR2V0V2luZG93TG9uZ0EoIGh3bmQsIEdXTF9TVFlMRSApICYgV1NfTUFYSU1JWkVCT1gpCiAgICAgICAgICAgIFNlbmRNZXNzYWdlVyggaHduZCwgV01fU1lTQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgICAgICBJc1pvb21lZChod25kKSA/IFNDX1JFU1RPUkUgOiBTQ19NQVhJTUlaRSwgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUU1lTTUVOVToKICAgICAgICBpZiAoIShHZXRDbGFzc0xvbmdXKGh3bmQsIEdDTF9TVFlMRSkgJiBDU19OT0NMT1NFKSkKICAgICAgICAgICAgU2VuZE1lc3NhZ2VXKCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19DTE9TRSwgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUSFNDUk9MTDoKICAgICAgICBTZW5kTWVzc2FnZVcoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX0hTQ1JPTEwgKyBIVEhTQ1JPTEwsIGxQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBIVFZTQ1JPTEw6CiAgICAgICAgU2VuZE1lc3NhZ2VXKCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19WU0NST0xMICsgSFRWU0NST0xMLCBsUGFyYW0gKTsKCWJyZWFrOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZVN5c0NvbW1hbmQKICoKICogSGFuZGxlIGEgV01fU1lTQ09NTUFORCBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZVN5c0NvbW1hbmQoIEhXTkQgaHduZCwgV1BBUkFNIHdQYXJhbSwgUE9JTlQgcHQgKQp7CiAgICBXTkQgKnduZFB0ciA9IFdJTl9GaW5kV25kUHRyKCBod25kICk7CiAgICBVSU5UMTYgdUNvbW1hbmQgPSB3UGFyYW0gJiAweEZGRjA7CgogICAgVFJBQ0UoIkhhbmRsaW5nIFdNX1NZU0NPTU1BTkQgJXggJWxkLCVsZFxuIiwgd1BhcmFtLCBwdC54LCBwdC55ICk7CgogICAgaWYgKHduZFB0ci0+cGFyZW50ICYmICh1Q29tbWFuZCAhPSBTQ19LRVlNRU5VKSkKICAgICAgICBTY3JlZW5Ub0NsaWVudCggd25kUHRyLT5wYXJlbnQtPmh3bmRTZWxmLCAmcHQgKTsKCiAgICBzd2l0Y2ggKHVDb21tYW5kKQogICAgewogICAgY2FzZSBTQ19TSVpFOgogICAgY2FzZSBTQ19NT1ZFOgogICAgICAgIGlmIChVU0VSX0RyaXZlci5wU3lzQ29tbWFuZFNpemVNb3ZlKQogICAgICAgICAgICBVU0VSX0RyaXZlci5wU3lzQ29tbWFuZFNpemVNb3ZlKCBod25kLCB3UGFyYW0gKTsKCWJyZWFrOwoKICAgIGNhc2UgU0NfTUlOSU1JWkU6CiAgICAgICAgaWYgKGh3bmQgPT0gR2V0Rm9yZWdyb3VuZFdpbmRvdygpKQogICAgICAgICAgICBTaG93T3duZWRQb3B1cHMoaHduZCxGQUxTRSk7CglTaG93V2luZG93KCBod25kLCBTV19NSU5JTUlaRSApOyAKCWJyZWFrOwoKICAgIGNhc2UgU0NfTUFYSU1JWkU6CiAgICAgICAgaWYgKElzSWNvbmljKGh3bmQpICYmIGh3bmQgPT0gR2V0Rm9yZWdyb3VuZFdpbmRvdygpKQogICAgICAgICAgICBTaG93T3duZWRQb3B1cHMoaHduZCxUUlVFKTsKCVNob3dXaW5kb3coIGh3bmQsIFNXX01BWElNSVpFICk7CglicmVhazsKCiAgICBjYXNlIFNDX1JFU1RPUkU6CiAgICAgICAgaWYgKElzSWNvbmljKGh3bmQpICYmIGh3bmQgPT0gR2V0Rm9yZWdyb3VuZFdpbmRvdygpKQogICAgICAgICAgICBTaG93T3duZWRQb3B1cHMoaHduZCxUUlVFKTsKCVNob3dXaW5kb3coIGh3bmQsIFNXX1JFU1RPUkUgKTsKCWJyZWFrOwoKICAgIGNhc2UgU0NfQ0xPU0U6CiAgICAgICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKCXJldHVybiBTZW5kTWVzc2FnZUEoIGh3bmQsIFdNX0NMT1NFLCAwLCAwICk7CgogICAgY2FzZSBTQ19WU0NST0xMOgogICAgY2FzZSBTQ19IU0NST0xMOgoJTkNfVHJhY2tTY3JvbGxCYXIoIGh3bmQsIHdQYXJhbSwgcHQgKTsKCWJyZWFrOwoKICAgIGNhc2UgU0NfTU9VU0VNRU5VOgogICAgICAgIE1FTlVfVHJhY2tNb3VzZU1lbnVCYXIoIGh3bmQsIHdQYXJhbSAmIDB4MDAwRiwgcHQgKTsKCWJyZWFrOwoKICAgIGNhc2UgU0NfS0VZTUVOVToKCU1FTlVfVHJhY2tLYmRNZW51QmFyKCBod25kLCB3UGFyYW0gLCBwdC54ICk7CglicmVhazsKCQogICAgY2FzZSBTQ19UQVNLTElTVDoKCVdpbkV4ZWMoICJ0YXNrbWFuLmV4ZSIsIFNXX1NIT1dOT1JNQUwgKTsgCglicmVhazsKCiAgICBjYXNlIFNDX1NDUkVFTlNBVkU6CglpZiAod1BhcmFtID09IFNDX0FCT1VUV0lORSkKICAgICAgICB7CiAgICAgICAgICAgIEhNT0RVTEUgaG1vZHVsZSA9IExvYWRMaWJyYXJ5QSggInNoZWxsMzIuZGxsIiApOwogICAgICAgICAgICBpZiAoaG1vZHVsZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRkFSUFJPQyBhYm91dHByb2MgPSBHZXRQcm9jQWRkcmVzcyggaG1vZHVsZSwgIlNoZWxsQWJvdXRBIiApOwogICAgICAgICAgICAgICAgaWYgKGFib3V0cHJvYykgYWJvdXRwcm9jKCBod25kLCAiV2luZSIsIFdJTkVfUkVMRUFTRV9JTkZPLCAwICk7CiAgICAgICAgICAgICAgICBGcmVlTGlicmFyeSggaG1vZHVsZSApOwogICAgICAgICAgICB9CiAgICAgICAgfQoJZWxzZSAKCSAgaWYgKHdQYXJhbSA9PSBTQ19QVVRNQVJLKQogICAgICAgICAgICBUUkFDRV8oc2hlbGwpKCJNYXJrIHJlcXVlc3RlZCBieSB1c2VyXG4iKTsKCWJyZWFrOwogIAogICAgY2FzZSBTQ19IT1RLRVk6CiAgICBjYXNlIFNDX0FSUkFOR0U6CiAgICBjYXNlIFNDX05FWFRXSU5ET1c6CiAgICBjYXNlIFNDX1BSRVZXSU5ET1c6CiAJRklYTUUoInVuaW1wbGVtZW50ZWQhXG4iKTsKICAgICAgICBicmVhazsKICAgIH0KICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiAgTkNfRHJhd0dyYXlCdXR0b24KKgoqIFN0dWIgZm9yIHRoZSBncmF5ZWQgYnV0dG9uIG9mIHRoZSBjYXB0aW9uCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCkJPT0wgTkNfRHJhd0dyYXlCdXR0b24oSERDIGhkYywgaW50IHgsIGludCB5KQp7CiAgICBIQklUTUFQIGhNYXNrQm1wOwogICAgSERDIGhkY01hc2sgPSBDcmVhdGVDb21wYXRpYmxlREMgKDApOwogICAgSEJSVVNIIGhPbGRCcnVzaDsKCiAgICBoTWFza0JtcCA9IENyZWF0ZUJpdG1hcCAoMTIsIDEwLCAxLCAxLCBscEdyYXlNYXNrKTsKICAgIAogICAgaWYoaE1hc2tCbXAgPT0gMCkKCXJldHVybiBGQUxTRTsKICAgIAogICAgU2VsZWN0T2JqZWN0IChoZGNNYXNrLCBoTWFza0JtcCk7CiAgICAKICAgIC8qIERyYXcgdGhlIGdyYXllZCBiaXRtYXAgdXNpbmcgdGhlIG1hc2sgKi8KICAgIGhPbGRCcnVzaCA9IFNlbGVjdE9iamVjdCAoaGRjLCBSR0IoMTI4LCAxMjgsIDEyOCkpOwogICAgQml0Qmx0IChoZGMsIHgsIHksIDEyLCAxMCwKCSAgICBoZGNNYXNrLCAwLCAwLCAweEI4MDc0QSk7CiAgICAKICAgIC8qIENsZWFuIHVwICovCiAgICBTZWxlY3RPYmplY3QgKGhkYywgaE9sZEJydXNoKTsKICAgIERlbGV0ZU9iamVjdChoTWFza0JtcCk7CiAgICBEZWxldGVEQyAoaGRjTWFzayk7CiAgICAKICAgIHJldHVybiBUUlVFOwp9Cg==