LyoKICogQ2xvY2sKICoKICogQ29weXJpZ2h0IDE5OTggTWFyY2VsIEJhdXIgPG1iYXVyQGcyNi5ldGh6LmNoPgogKiBDb3B5cmlnaHQgMTk5OCBLYXJsIEJhY2tzdHL2bSA8a2FybF9iQGdlb2NpdGllcy5jb20+CiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJtYWluLmgiCiNpbmNsdWRlICJsYW5ndWFnZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpZmRlZiBXSU5FTElCCiNpbmNsdWRlICJvcHRpb25zLmgiCiNlbmRpZgoKQ0hBUiBTVFJJTkdfTUVOVV9YeFtdICAgICAgPSAiTUVOVV9YeCI7CgpWT0lEIExBTkdVQUdFX1VwZGF0ZU1lbnVDaGVja21hcmtzKFZPSUQpIHsKCiAgICBpZihHbG9iYWxzLmJBbmFsb2cgPT0gVFJVRSkgewogICAgCiAgICAgICAgLyogYW5hbG9nIGNsb2NrICovCiAgICAgICAgCiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfQU5BTE9HLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfQ0hFQ0tFRCk7CiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfRElHSVRBTCwgXAogICAgICAgICAgICAgICAgICAgICAgIE1GX0JZQ09NTUFORCB8IE1GX1VOQ0hFQ0tFRCk7CiAgICAgICAgRW5hYmxlTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIENMX0ZPTlQsIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9HUkFZRUQpOwogICAgfQogICAgICAgIGVsc2UgCiAgICB7CiAgICAKICAgICAgICAvKiBkaWdpdGFsIGNsb2NrICovCiAgICAgICAgCiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfQU5BTE9HLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfVU5DSEVDS0VEKTsKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCBDTF9ESUdJVEFMLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfQ0hFQ0tFRCk7CiAgICAgICAgRW5hYmxlTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIENMX0ZPTlQsIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQpOwogICAgICAgICAgICAgICAgICAgICAgIAogICAgfQogICAgCiAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCBDTF9XSVRIT1VUX1RJVExFLCBNRl9CWUNPTU1BTkQgfCBcCiAgICAgICAgICAgICAgICAgKEdsb2JhbHMuYldpdGhvdXRUaXRsZSA/IE1GX0NIRUNLRUQgOiBNRl9VTkNIRUNLRUQpKTsKICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oU3lzdGVtTWVudSwgQ0xfT05fVE9QLCBNRl9CWUNPTU1BTkQgfCBcCiAgICAgICAgICAgICAgICAgKEdsb2JhbHMuYkFsd2F5c09uVG9wID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfU0VDT05EUywgTUZfQllDT01NQU5EIHwgXAogICAgICAgICAgICAgICAgIChHbG9iYWxzLmJTZWNvbmRzID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfREFURSwgTUZfQllDT01NQU5EIHwgXAogICAgICAgICAgICAgICAgIChHbG9iYWxzLmJEYXRlID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwp9CgpWT0lEIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oVk9JRCkgewoKICBDSEFSIHN6Q2FwdGlvbltNQVhfU1RSSU5HX0xFTl07CiAgQ0hBUiBzekRhdGVbTUFYX1NUUklOR19MRU5dOwogIAogIExQU1RSIGRhdGUgPSBzekRhdGU7CiAgCiAgU1lTVEVNVElNRSBzdDsKICBMUFNZU1RFTVRJTUUgbHBzdCA9ICZzdDsKCiAgR2V0TG9jYWxUaW1lKCZzdCk7CiAgR2V0RGF0ZUZvcm1hdChMT0NBTEVfVVNFUl9ERUZBVUxULCBMT0NBTEVfU0xPTkdEQVRFLCBscHN0LCBOVUxMLCBkYXRlLAogICAgICAgICAgICAgICAgTUFYX1NUUklOR19MRU4pOwoKICAvKiBTZXQgZnJhbWUgY2FwdGlvbiAqLwogIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19DTE9DSywgc3pDYXB0aW9uLCBzaXplb2Yoc3pDYXB0aW9uKSk7CiAgaWYgKEdsb2JhbHMuYkRhdGUpIHsKICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgIiAtICIpOwogICAgIGxzdHJjYXQoc3pDYXB0aW9uLCBzekRhdGUpOwogIH0KICBTZXRXaW5kb3dUZXh0KEdsb2JhbHMuaE1haW5XbmQsIHN6Q2FwdGlvbik7Cgp9CgoKCnN0YXRpYyBCT09MIExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihVSU5UIG51bSwgVUlOVCBpZHMsIExQU1RSIHN0ciwgVUlOVCBsZW4pCnsKICBpZHMgLT0gR2xvYmFscy53U3RyaW5nVGFibGVPZmZzZXQ7CiAgaWRzICs9IG51bSAqIDB4MTAwOwogIHJldHVybihMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBpZHMsIHN0ciwgbGVuKSk7Cn07CgpWT0lEIExBTkdVQUdFX1NlbGVjdEJ5TmFtZShMUENTVFIgbGFuZykKewogIElOVCBpOwogIENIQVIgc3pOZXdMYW5nWzNdOwoKICBmb3IgKGkgPSAwOyBpIDw9IE1BWF9MQU5HVUFHRV9OVU1CRVI7IGkrKykKICAgIGlmIChMQU5HVUFHRV9Mb2FkU3RyaW5nT3RoZXIoaSwgSURTX0xBTkdVQUdFX0lELCBzek5ld0xhbmcsIAogICAgICAgICAgICAgICAgc2l6ZW9mKHN6TmV3TGFuZykpICYmICFsc3RyY21wKGxhbmcsIHN6TmV3TGFuZykpCiAgICAgIHsKICAgICAgICBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcihpKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgLyogRmFsbGJhY2sgKi8KICAgIGZvciAoaSA9IDA7IGkgPD0gTUFYX0xBTkdVQUdFX05VTUJFUjsgaSsrKQogICAgaWYgKExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihpLCBJRFNfTEFOR1VBR0VfSUQsIHN6TmV3TGFuZywgc2l6ZW9mKHN6TmV3TGFuZykpKQogICAgICB7CiAgICAgICAgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIoaSk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgTWVzc2FnZUJveChHbG9iYWxzLmhNYWluV25kLCAiTm8gbGFuZ3VhZ2UgZm91bmQiLCAiRkFUQUwgRVJST1IiLCBNQl9PSyk7CiAgICBQb3N0UXVpdE1lc3NhZ2UoMSk7Cn0KClZPSUQgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIoVUlOVCBudW0pCnsKICBJTlQgICAgaTsKICBDSEFSICAgc3pMYW5ndWFnZVszXTsKCiAgQ0hBUiAgIHN6SXRlbVtNQVhfU1RSSU5HX0xFTl07CiAgSE1FTlUgIGhNYWluTWVudTsKCiAgLyogU2VsZWN0IHN0cmluZyB0YWJsZSAqLwogIEdsb2JhbHMud1N0cmluZ1RhYmxlT2Zmc2V0ID0gbnVtICogMHgxMDA7CgogIC8qIEdldCBMYW5ndWFnZSBpZCAqLwogIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19MQU5HVUFHRV9JRCwgc3pMYW5ndWFnZSwgc2l6ZW9mKHN6TGFuZ3VhZ2UpKTsKICBHbG9iYWxzLmxwc3pMYW5ndWFnZSA9IHN6TGFuZ3VhZ2U7CgogIC8qIENoYW5nZSBSZXNvdXJjZSBuYW1lcyAqLwogIGxzdHJjcHluKFNUUklOR19NRU5VX1h4ICsgc2l6ZW9mKFNUUklOR19NRU5VX1h4KSAtIDMsIHN6TGFuZ3VhZ2UsIDMpOwoKICAvKiBDcmVhdGUgbWVudSAqLwogIGhNYWluTWVudSA9IExvYWRNZW51KEdsb2JhbHMuaEluc3RhbmNlLCBTVFJJTkdfTUVOVV9YeCk7CiAgICBHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMCk7CiAgICBHbG9iYWxzLmhMYW5ndWFnZU1lbnUgICAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMSk7CiAgICBHbG9iYWxzLmhJbmZvTWVudSAgICAgICAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMik7CgogIC8qIFJlbW92ZSBkdW1teSBpdGVtICovCiAgUmVtb3ZlTWVudShHbG9iYWxzLmhMYW5ndWFnZU1lbnUsIDAsIE1GX0JZUE9TSVRJT04pOwogIC8qIEFkZCBsYW5ndWFnZSBpdGVtcyAqLwogIGZvciAoaSA9IDA7IGkgPD0gTUFYX0xBTkdVQUdFX05VTUJFUjsgaSsrKQogICAgaWYgKExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihpLCBJRFNfTEFOR1VBR0VfTUVOVV9JVEVNLCBzekl0ZW0sIHNpemVvZihzekl0ZW0pKSkKICAgICAgICAgICAgIEFwcGVuZE1lbnUoR2xvYmFscy5oTGFuZ3VhZ2VNZW51LCBNRl9TVFJJTkcgfCBNRl9CWUNPTU1BTkQsCiAgICAgICAgICAgICAgICAgICAgICAgIENMX0ZJUlNUX0xBTkdVQUdFICsgaSwgc3pJdGVtKTsKICBFbmFibGVNZW51SXRlbShHbG9iYWxzLmhMYW5ndWFnZU1lbnUsIENMX0ZJUlNUX0xBTkdVQUdFICsgbnVtLCBNRl9CWUNPTU1BTkQgfCBNRl9DSEVDS0VEKTsKCiAgU2V0TWVudShHbG9iYWxzLmhNYWluV25kLCBoTWFpbk1lbnUpOwoKICAvKiBEZXN0cm95IG9sZCBtZW51ICovCiAgaWYgKEdsb2JhbHMuaE1haW5NZW51KSBEZXN0cm95TWVudShHbG9iYWxzLmhNYWluTWVudSk7CiAgR2xvYmFscy5oTWFpbk1lbnUgPSBoTWFpbk1lbnU7CgogIC8qIHNwZWNpZmljIGZvciBDbG9jazogKi8KCiAgTEFOR1VBR0VfVXBkYXRlTWVudUNoZWNrbWFya3MoKTsKICBMQU5HVUFHRV9VcGRhdGVXaW5kb3dDYXB0aW9uKCk7ICAgCgogIEdsb2JhbHMuaFN5c3RlbU1lbnUgPSBHZXRTeXN0ZW1NZW51KEdsb2JhbHMuaE1haW5XbmQsIFRSVUUpOwoKICAvKiBGSVhNRTogQXBwZW5kIGEgU0VQQVJBVE9SIHRvIEdsb2JhbHMuaFN5c3RlbU1lbnUgaGVyZSAqLwoKICBMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBJRFNfTUVOVV9PTl9UT1AsIHN6SXRlbSwgc2l6ZW9mKHN6SXRlbSkpOwogIEFwcGVuZE1lbnUoR2xvYmFscy5oU3lzdGVtTWVudSwgTUZfU1RSSU5HIHwgTUZfQllDT01NQU5ELCAxMDAwLCBzekl0ZW0pOwp9CgpWT0lEIExBTkdVQUdFX0RlZmF1bHRIYW5kbGUoV1BBUkFNIHdQYXJhbSkKewogIGlmICgod1BhcmFtID49Q0xfRklSU1RfTEFOR1VBR0UpICYmICh3UGFyYW08PUNMX0xBU1RfTEFOR1VBR0UpKQogICAgICAgICAgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIod1BhcmFtIC0gQ0xfRklSU1RfTEFOR1VBR0UpOwogICAgIGVsc2UgcHJpbnRmKCJVbmltcGxlbWVudGVkIG1lbnUgY29tbWFuZCAlaVxuIiwgd1BhcmFtKTsKfQoKVk9JRCBMQU5HVUFHRV9Jbml0KFZPSUQpCnsKICBDSEFSIHN6QnVmZmVyW01BWF9QQVRITkFNRV9MRU5dOwoKICBpZiAoR2xvYmFscy5scHN6TGFuZ3VhZ2UgPT0gIkVuIikgewogICAgICAgIFBST0ZJTEVfR2V0V2luZUluaVN0cmluZygicHJvZ3JhbXMiLCAibGFuZ3VhZ2UiLCAiRW4iLCBzekJ1ZmZlciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3pCdWZmZXIpKTsgICAgICAgCiAgICAgICAgR2xvYmFscy5scHN6TGFuZ3VhZ2UgPSBMb2NhbExvY2soTG9jYWxBbGxvYyhMTUVNX0ZJWEVELCBsc3RybGVuKHN6QnVmZmVyKSsxKSk7CgovKiAgICAgICAgaG1lbWNweShHbG9iYWxzLmxwc3pMYW5ndWFnZSwgc3pCdWZmZXIsIDErbHN0cmxlbihzekJ1ZmZlcikpOyAgKi8KICAgICAgICBsc3RyY3B5bihHbG9iYWxzLmxwc3pMYW5ndWFnZSwgc3pCdWZmZXIsIHN0cmxlbihzekJ1ZmZlcikrMSk7IAogIH0KfQoKLyogTG9jYWwgVmFyaWFibGVzOiAgICAqLwovKiBjLWZpbGUtc3R5bGU6ICJHTlUiICovCi8qIEVuZDogICAgICAgICAgICAgICAgKi8K