LyoKICogQ2xvY2sKICoKICogQ29weXJpZ2h0IDE5OTggTWFyY2VsIEJhdXIgPG1iYXVyQGcyNi5ldGh6LmNoPgogKiBDb3B5cmlnaHQgMTk5OCBLYXJsIEJhY2tzdHL2bSA8a2FybF9iQGdlb2NpdGllcy5jb20+CiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJtYWluLmgiCiNpbmNsdWRlICJsYW5ndWFnZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpZmRlZiBXSU5FTElCCiNpbmNsdWRlICJvcHRpb25zLmgiCiNlbmRpZgoKQ0hBUiBTVFJJTkdfTUVOVV9YeFtdICAgICAgPSAiTUVOVV9YeCI7CgpWT0lEIExBTkdVQUdFX1VwZGF0ZU1lbnVDaGVja21hcmtzKFZPSUQpIHsKCiAgICBpZihHbG9iYWxzLmJBbmFsb2cgPT0gVFJVRSkgewogICAgCiAgICAgICAgLyogYW5hbG9nIGNsb2NrICovCiAgICAgICAgCiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfQU5BTE9HLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfQ0hFQ0tFRCk7CiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfRElHSVRBTCwgXAogICAgICAgICAgICAgICAgICAgICAgIE1GX0JZQ09NTUFORCB8IE1GX1VOQ0hFQ0tFRCk7CiAgICAgICAgRW5hYmxlTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIENMX0ZPTlQsIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9HUkFZRUQpOwogICAgfQogICAgICAgIGVsc2UgCiAgICB7CiAgICAKICAgICAgICAvKiBkaWdpdGFsIGNsb2NrICovCiAgICAgICAgCiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfQU5BTE9HLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfVU5DSEVDS0VEKTsKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCBDTF9ESUdJVEFMLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfQ0hFQ0tFRCk7CiAgICB9CiAgICAKICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIENMX1dJVEhPVVRfVElUTEUsIE1GX0JZQ09NTUFORCB8IFwKICAgICAgICAgICAgICAgICAoR2xvYmFscy5iV2l0aG91dFRpdGxlID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfT05fVE9QLCBNRl9CWUNPTU1BTkQgfCBcCiAgICAgICAgICAgICAgICAgKEdsb2JhbHMuYkFsd2F5c09uVG9wID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfU0VDT05EUywgTUZfQllDT01NQU5EIHwgXAogICAgICAgICAgICAgICAgIChHbG9iYWxzLmJTZWNvbmRzID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfREFURSwgTUZfQllDT01NQU5EIHwgXAogICAgICAgICAgICAgICAgIChHbG9iYWxzLmJEYXRlID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwp9CgpWT0lEIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oVk9JRCkgewoKICBDSEFSIHN6Q2FwdGlvbltNQVhfU1RSSU5HX0xFTl07CiAgQ0hBUiBzekRhdGVbTUFYX1NUUklOR19MRU5dOwogIAogIExQU1RSIGRhdGUgPSBzekRhdGU7CiAgCiAgU1lTVEVNVElNRSBzdDsKICBMUFNZU1RFTVRJTUUgbHBzdCA9ICZzdDsKCiAgR2V0TG9jYWxUaW1lKCZzdCk7CiAgR2V0RGF0ZUZvcm1hdChMT0NBTEVfVVNFUl9ERUZBVUxULCBMT0NBTEVfU0xPTkdEQVRFLCBscHN0LCBOVUxMLCBkYXRlLAogICAgICAgICAgICAgICAgTUFYX1NUUklOR19MRU4pOwoKICAvKiBTZXQgZnJhbWUgY2FwdGlvbiAqLwogIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19DTE9DSywgc3pDYXB0aW9uLCBzaXplb2Yoc3pDYXB0aW9uKSk7CiAgaWYgKEdsb2JhbHMuYkRhdGUpIHsKICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgIiAtICIpOwogICAgIGxzdHJjYXQoc3pDYXB0aW9uLCBzekRhdGUpOwogIH0KICBTZXRXaW5kb3dUZXh0KEdsb2JhbHMuaE1haW5XbmQsIHN6Q2FwdGlvbik7Cgp9CgoKCnN0YXRpYyBCT09MIExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihVSU5UIG51bSwgVUlOVCBpZHMsIExQU1RSIHN0ciwgVUlOVCBsZW4pCnsKICBpZHMgLT0gR2xvYmFscy53U3RyaW5nVGFibGVPZmZzZXQ7CiAgaWRzICs9IG51bSAqIDB4MTAwOwogIHJldHVybihMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBpZHMsIHN0ciwgbGVuKSk7Cn07CgpWT0lEIExBTkdVQUdFX1NlbGVjdEJ5TmFtZShMUENTVFIgbGFuZykKewogIElOVCBpOwogIENIQVIgbmV3bGFuZ1szXTsKCiAgZm9yIChpID0gMDsgaSA8PSBNQVhfTEFOR1VBR0VfTlVNQkVSOyBpKyspCiAgICBpZiAoTEFOR1VBR0VfTG9hZFN0cmluZ090aGVyKGksIElEU19MQU5HVUFHRV9JRCwgbmV3bGFuZywgc2l6ZW9mKG5ld2xhbmcpKSAmJgogICAgICAgICFsc3RyY21wKGxhbmcsIG5ld2xhbmcpKQogICAgICB7CiAgICAgICAgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIoaSk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogIC8qIEZhbGxiYWNrICovCiAgICBmb3IgKGkgPSAwOyBpIDw9IE1BWF9MQU5HVUFHRV9OVU1CRVI7IGkrKykKICAgIGlmIChMQU5HVUFHRV9Mb2FkU3RyaW5nT3RoZXIoaSwgSURTX0xBTkdVQUdFX0lELCBuZXdsYW5nLCBzaXplb2YobmV3bGFuZykpKQogICAgICB7CiAgICAgICAgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIoaSk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogIE1lc3NhZ2VCb3goR2xvYmFscy5oTWFpblduZCwgIk5vIGxhbmd1YWdlIGZvdW5kIiwgIkZBVEFMIEVSUk9SIiwgTUJfT0spOwogIFBvc3RRdWl0TWVzc2FnZSgxKTsKfQoKVk9JRCBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcihVSU5UIG51bSkKewogIElOVCAgICBpOwogIENIQVIgICBsYW5nWzNdOwoKICBDSEFSICAgaXRlbVtNQVhfU1RSSU5HX0xFTl07CiAgSE1FTlUgIGhNYWluTWVudTsKCiAgLyogU2VsZWN0IHN0cmluZyB0YWJsZSAqLwogIEdsb2JhbHMud1N0cmluZ1RhYmxlT2Zmc2V0ID0gbnVtICogMHgxMDA7CgogIC8qIEdldCBMYW5ndWFnZSBpZCAqLwogIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19MQU5HVUFHRV9JRCwgbGFuZywgc2l6ZW9mKGxhbmcpKTsKICBHbG9iYWxzLmxwc3pMYW5ndWFnZSA9IGxhbmc7CgogIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oKTsKCiAgLyogQ2hhbmdlIFJlc291cmNlIG5hbWVzICovCiAgbHN0cmNweW4oU1RSSU5HX01FTlVfWHggICAgKyBzaXplb2YoU1RSSU5HX01FTlVfWHgpICAgIC0gMywgbGFuZywgMyk7CgogIC8qIENyZWF0ZSBtZW51ICovCiAgaE1haW5NZW51ID0gTG9hZE1lbnUoR2xvYmFscy5oSW5zdGFuY2UsIFNUUklOR19NRU5VX1h4KTsKICAgIEdsb2JhbHMuaFByb3BlcnRpZXNNZW51ICAgICA9IEdldFN1Yk1lbnUoaE1haW5NZW51LCAwKTsKICAgIEdsb2JhbHMuaExhbmd1YWdlTWVudSAgICAgICA9IEdldFN1Yk1lbnUoaE1haW5NZW51LCAxKTsKICAgIEdsb2JhbHMuaEluZm9NZW51ICAgICAgICAgICA9IEdldFN1Yk1lbnUoaE1haW5NZW51LCAyKTsKCiAgLyogUmVtb3ZlIGR1bW15IGl0ZW0gKi8KICBSZW1vdmVNZW51KEdsb2JhbHMuaExhbmd1YWdlTWVudSwgMCwgTUZfQllQT1NJVElPTik7CiAgLyogQWRkIGxhbmd1YWdlIGl0ZW1zICovCiAgZm9yIChpID0gMDsgaSA8PSBNQVhfTEFOR1VBR0VfTlVNQkVSOyBpKyspCiAgICBpZiAoTEFOR1VBR0VfTG9hZFN0cmluZ090aGVyKGksIElEU19MQU5HVUFHRV9NRU5VX0lURU0sIGl0ZW0sIHNpemVvZihpdGVtKSkpCiAgICAgIEFwcGVuZE1lbnUoR2xvYmFscy5oTGFuZ3VhZ2VNZW51LCBNRl9TVFJJTkcgfCBNRl9CWUNPTU1BTkQsCiAgICAgICAgICAgICAgICAgQ0xfRklSU1RfTEFOR1VBR0UgKyBpLCBpdGVtKTsKCiAgU2V0TWVudShHbG9iYWxzLmhNYWluV25kLCBoTWFpbk1lbnUpOwoKICAvKiBEZXN0cm95IG9sZCBtZW51ICovCiAgaWYgKEdsb2JhbHMuaE1haW5NZW51KSBEZXN0cm95TWVudShHbG9iYWxzLmhNYWluTWVudSk7CiAgR2xvYmFscy5oTWFpbk1lbnUgPSBoTWFpbk1lbnU7CgojaWZkZWYgV0lORUxJQgogIC8qIFVwZGF0ZSBzeXN0ZW0gbWVudXMgKi8KICBmb3IgKGkgPSAwOyBMYW5ndWFnZXNbaV0ubmFtZSAmJiBsc3RyY21wKGxhbmcsIExhbmd1YWdlc1tpXS5uYW1lKTspIGkrKzsKICBpZiAoTGFuZ3VhZ2VzW2ldLm5hbWUpIE9wdGlvbnMubGFuZ3VhZ2UgPSBpOwojZW5kaWYKCiAgIC8qIHNwZWNpZmljIGZvciBDbG9jazogKi8KCiAgIExBTkdVQUdFX1VwZGF0ZU1lbnVDaGVja21hcmtzKCk7Cn0KClZPSUQgTEFOR1VBR0VfRGVmYXVsdEhhbmRsZShXUEFSQU0gd1BhcmFtKQp7CiAgaWYgKCh3UGFyYW0gPj1DTF9GSVJTVF9MQU5HVUFHRSkgJiYgKHdQYXJhbTw9Q0xfTEFTVF9MQU5HVUFHRSkpCiAgICAgICAgICBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcih3UGFyYW0gLSBDTF9GSVJTVF9MQU5HVUFHRSk7CiAgICAgZWxzZSBwcmludGYoIlVuaW1wbGVtZW50ZWQgbWVudSBjb21tYW5kICVpXG4iLCB3UGFyYW0pOwp9CgpWT0lEIExBTkdVQUdFX0luaXQoVk9JRCkKewogIENIQVIgc3pCdWZmZXJbTUFYX1BBVEhOQU1FX0xFTl07CgogICNpZmRlZiBXSU5FTElCCiAgIEdsb2JhbHMubHBzekxhbmd1YWdlID0gTGFuZ3VhZ2VzW09wdGlvbnMubGFuZ3VhZ2VdLm5hbWU7CiAgI2VuZGlmCiAgCiAgaWYgKEdsb2JhbHMubHBzekxhbmd1YWdlID09ICJFbiIpIHsKICAgICAgICBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoInByb2dyYW1zIiwgImxhbmd1YWdlIiwgIkVuIiwgc3pCdWZmZXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN6QnVmZmVyKSk7ICAgICAgIAogICAgICAgIEdsb2JhbHMubHBzekxhbmd1YWdlID0gTG9jYWxMb2NrKExvY2FsQWxsb2MoTE1FTV9GSVhFRCwgbHN0cmxlbihzekJ1ZmZlcikpKTsKCiAgICAgICAgaG1lbWNweShHbG9iYWxzLmxwc3pMYW5ndWFnZSwgc3pCdWZmZXIsIDErbHN0cmxlbihzekJ1ZmZlcikpOyAKICB9Cn0KCi8qIExvY2FsIFZhcmlhYmxlczogICAgKi8KLyogYy1maWxlLXN0eWxlOiAiR05VIiAqLwovKiBFbmQ6ICAgICAgICAgICAgICAgICovCg==