LyoKICogQ2xvY2sKICoKICogQ29weXJpZ2h0IDE5OTggTWFyY2VsIEJhdXIgPG1iYXVyQGcyNi5ldGh6LmNoPgogKiBDb3B5cmlnaHQgMTk5OCBLYXJsIEJhY2tzdHL2bSA8a2FybF9iQGdlb2NpdGllcy5jb20+CiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJtYWluLmgiCiNpbmNsdWRlICJsYW5ndWFnZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpZmRlZiBXSU5FTElCCiNpbmNsdWRlICJvcHRpb25zLmgiCiNlbmRpZgoKQ0hBUiBTVFJJTkdfTUVOVV9YeFtdICAgICAgPSAiTUVOVV9YeCI7CgpWT0lEIExBTkdVQUdFX1VwZGF0ZU1lbnVDaGVja21hcmtzKFZPSUQpIHsKCiAgICBpZihHbG9iYWxzLmJBbmFsb2cgPT0gVFJVRSkgewogICAgCiAgICAgICAgLyogYW5hbG9nIGNsb2NrICovCiAgICAgICAgCiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfQU5BTE9HLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfQ0hFQ0tFRCk7CiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfRElHSVRBTCwgXAogICAgICAgICAgICAgICAgICAgICAgIE1GX0JZQ09NTUFORCB8IE1GX1VOQ0hFQ0tFRCk7CiAgICAgICAgRW5hYmxlTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIENMX0ZPTlQsIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9HUkFZRUQpOwogICAgfQogICAgICAgIGVsc2UgCiAgICB7CiAgICAKICAgICAgICAvKiBkaWdpdGFsIGNsb2NrICovCiAgICAgICAgCiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfQU5BTE9HLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfVU5DSEVDS0VEKTsKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCBDTF9ESUdJVEFMLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfQ0hFQ0tFRCk7CiAgICAgICAgRW5hYmxlTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIENMX0ZPTlQsIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQpOwogICAgICAgICAgICAgICAgICAgICAgIAogICAgfQogICAgCiAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCBDTF9XSVRIT1VUX1RJVExFLCBNRl9CWUNPTU1BTkQgfCBcCiAgICAgICAgICAgICAgICAgKEdsb2JhbHMuYldpdGhvdXRUaXRsZSA/IE1GX0NIRUNLRUQgOiBNRl9VTkNIRUNLRUQpKTsKICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oU3lzdGVtTWVudSwgQ0xfT05fVE9QLCBNRl9CWUNPTU1BTkQgfCBcCiAgICAgICAgICAgICAgICAgKEdsb2JhbHMuYkFsd2F5c09uVG9wID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfU0VDT05EUywgTUZfQllDT01NQU5EIHwgXAogICAgICAgICAgICAgICAgIChHbG9iYWxzLmJTZWNvbmRzID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfREFURSwgTUZfQllDT01NQU5EIHwgXAogICAgICAgICAgICAgICAgIChHbG9iYWxzLmJEYXRlID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwp9CgpWT0lEIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oVk9JRCkgewoKICBDSEFSIHN6Q2FwdGlvbltNQVhfU1RSSU5HX0xFTl07CiAgQ0hBUiBzekRhdGVbTUFYX1NUUklOR19MRU5dOwogIAogIExQU1RSIGRhdGUgPSBzekRhdGU7CiAgCiAgU1lTVEVNVElNRSBzdDsKICBMUFNZU1RFTVRJTUUgbHBzdCA9ICZzdDsKCiAgR2V0TG9jYWxUaW1lKCZzdCk7CiAgR2V0RGF0ZUZvcm1hdChMT0NBTEVfVVNFUl9ERUZBVUxULCBMT0NBTEVfU0xPTkdEQVRFLCBscHN0LCBOVUxMLCBkYXRlLAogICAgICAgICAgICAgICAgTUFYX1NUUklOR19MRU4pOwoKICAvKiBTZXQgZnJhbWUgY2FwdGlvbiAqLwogIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19DTE9DSywgc3pDYXB0aW9uLCBzaXplb2Yoc3pDYXB0aW9uKSk7CiAgaWYgKEdsb2JhbHMuYkRhdGUpIHsKICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgIiAtICIpOwogICAgIGxzdHJjYXQoc3pDYXB0aW9uLCBzekRhdGUpOwogIH0KICBTZXRXaW5kb3dUZXh0KEdsb2JhbHMuaE1haW5XbmQsIHN6Q2FwdGlvbik7Cgp9CgoKCnN0YXRpYyBCT09MIExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihVSU5UIG51bSwgVUlOVCBpZHMsIExQU1RSIHN0ciwgVUlOVCBsZW4pCnsKICBpZHMgLT0gR2xvYmFscy53U3RyaW5nVGFibGVPZmZzZXQ7CiAgaWRzICs9IG51bSAqIDB4MTAwOwogIHJldHVybihMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBpZHMsIHN0ciwgbGVuKSk7Cn07CgpWT0lEIExBTkdVQUdFX1NlbGVjdEJ5TmFtZShMUENTVFIgbGFuZykKewogIElOVCBpOwogIENIQVIgc3pOZXdMYW5nWzNdOwoKICBmb3IgKGkgPSAwOyBpIDw9IE1BWF9MQU5HVUFHRV9OVU1CRVI7IGkrKykKICAgIGlmIChMQU5HVUFHRV9Mb2FkU3RyaW5nT3RoZXIoaSwgSURTX0xBTkdVQUdFX0lELCBzek5ld0xhbmcsIAogICAgICAgICAgICAgICAgc2l6ZW9mKHN6TmV3TGFuZykpICYmICFsc3RyY21wKGxhbmcsIHN6TmV3TGFuZykpCiAgICAgIHsKICAgICAgICBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcihpKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgLyogRmFsbGJhY2sgKi8KICAgIGZvciAoaSA9IDA7IGkgPD0gTUFYX0xBTkdVQUdFX05VTUJFUjsgaSsrKQogICAgaWYgKExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihpLCBJRFNfTEFOR1VBR0VfSUQsIHN6TmV3TGFuZywgc2l6ZW9mKHN6TmV3TGFuZykpKQogICAgICB7CiAgICAgICAgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIoaSk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgTWVzc2FnZUJveChHbG9iYWxzLmhNYWluV25kLCAiTm8gbGFuZ3VhZ2UgZm91bmQiLCAiRkFUQUwgRVJST1IiLCBNQl9PSyk7CiAgICBQb3N0UXVpdE1lc3NhZ2UoMSk7Cn0KClZPSUQgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIoVUlOVCBudW0pCnsKICBJTlQgICAgaTsKICBDSEFSICAgc3pMYW5ndWFnZVszXTsKCiAgQ0hBUiAgIHN6SXRlbVtNQVhfU1RSSU5HX0xFTl07CiAgSE1FTlUgIGhNYWluTWVudTsKCiAgLyogU2VsZWN0IHN0cmluZyB0YWJsZSAqLwogIEdsb2JhbHMud1N0cmluZ1RhYmxlT2Zmc2V0ID0gbnVtICogMHgxMDA7CgogIC8qIEdldCBMYW5ndWFnZSBpZCAqLwogIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19MQU5HVUFHRV9JRCwgc3pMYW5ndWFnZSwgc2l6ZW9mKHN6TGFuZ3VhZ2UpKTsKICBHbG9iYWxzLmxwc3pMYW5ndWFnZSA9IHN6TGFuZ3VhZ2U7CgogIC8qIENoYW5nZSBSZXNvdXJjZSBuYW1lcyAqLwogIGxzdHJjcHluKFNUUklOR19NRU5VX1h4ICsgc2l6ZW9mKFNUUklOR19NRU5VX1h4KSAtIDMsIHN6TGFuZ3VhZ2UsIDMpOwoKICAvKiBDcmVhdGUgbWVudSAqLwogIGhNYWluTWVudSA9IExvYWRNZW51KEdsb2JhbHMuaEluc3RhbmNlLCBTVFJJTkdfTUVOVV9YeCk7CiAgICBHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMCk7CiAgICBHbG9iYWxzLmhMYW5ndWFnZU1lbnUgICAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMSk7CiAgICBHbG9iYWxzLmhJbmZvTWVudSAgICAgICAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMik7CgogIC8qIFJlbW92ZSBkdW1teSBpdGVtICovCiAgUmVtb3ZlTWVudShHbG9iYWxzLmhMYW5ndWFnZU1lbnUsIDAsIE1GX0JZUE9TSVRJT04pOwogIC8qIEFkZCBsYW5ndWFnZSBpdGVtcyAqLwogIGZvciAoaSA9IDA7IGkgPD0gTUFYX0xBTkdVQUdFX05VTUJFUjsgaSsrKQogICAgaWYgKExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihpLCBJRFNfTEFOR1VBR0VfTUVOVV9JVEVNLCBzekl0ZW0sIHNpemVvZihzekl0ZW0pKSkKICAgICAgICAgICAgIEFwcGVuZE1lbnUoR2xvYmFscy5oTGFuZ3VhZ2VNZW51LCBNRl9TVFJJTkcgfCBNRl9CWUNPTU1BTkQsCiAgICAgICAgICAgICAgICAgICAgICAgIENMX0ZJUlNUX0xBTkdVQUdFICsgaSwgc3pJdGVtKTsKICBFbmFibGVNZW51SXRlbShHbG9iYWxzLmhMYW5ndWFnZU1lbnUsIENMX0ZJUlNUX0xBTkdVQUdFICsgbnVtLCBNRl9CWUNPTU1BTkQgfCBNRl9DSEVDS0VEKTsKCiAgU2V0TWVudShHbG9iYWxzLmhNYWluV25kLCBoTWFpbk1lbnUpOwoKICAvKiBEZXN0cm95IG9sZCBtZW51ICovCiAgaWYgKEdsb2JhbHMuaE1haW5NZW51KSBEZXN0cm95TWVudShHbG9iYWxzLmhNYWluTWVudSk7CiAgR2xvYmFscy5oTWFpbk1lbnUgPSBoTWFpbk1lbnU7CgojaWZkZWYgV0lORUxJQgogIC8qIFVwZGF0ZSBzeXN0ZW0gbWVudXMgKi8KICBmb3IgKGkgPSAwOyBMYW5ndWFnZXNbaV0ubmFtZSAmJiBsc3RyY21wKHN6TGFuZ3VhZ2UsIExhbmd1YWdlc1tpXS5uYW1lKTspIGkrKzsKICBpZiAoTGFuZ3VhZ2VzW2ldLm5hbWUpIE9wdGlvbnMubGFuZ3VhZ2UgPSBpOwojZW5kaWYKCiAgLyogc3BlY2lmaWMgZm9yIENsb2NrOiAqLwoKICBMQU5HVUFHRV9VcGRhdGVNZW51Q2hlY2ttYXJrcygpOwogIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oKTsgICAKCiAgR2xvYmFscy5oU3lzdGVtTWVudSA9IEdldFN5c3RlbU1lbnUoR2xvYmFscy5oTWFpblduZCwgVFJVRSk7CgogIC8qIEZJWE1FOiBBcHBlbmQgYSBTRVBBUkFUT1IgdG8gR2xvYmFscy5oU3lzdGVtTWVudSBoZXJlICovCgogIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19NRU5VX09OX1RPUCwgc3pJdGVtLCBzaXplb2Yoc3pJdGVtKSk7CiAgQXBwZW5kTWVudShHbG9iYWxzLmhTeXN0ZW1NZW51LCBNRl9TVFJJTkcgfCBNRl9CWUNPTU1BTkQsIDEwMDAsIHN6SXRlbSk7Cn0KClZPSUQgTEFOR1VBR0VfRGVmYXVsdEhhbmRsZShXUEFSQU0gd1BhcmFtKQp7CiAgaWYgKCh3UGFyYW0gPj1DTF9GSVJTVF9MQU5HVUFHRSkgJiYgKHdQYXJhbTw9Q0xfTEFTVF9MQU5HVUFHRSkpCiAgICAgICAgICBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcih3UGFyYW0gLSBDTF9GSVJTVF9MQU5HVUFHRSk7CiAgICAgZWxzZSBwcmludGYoIlVuaW1wbGVtZW50ZWQgbWVudSBjb21tYW5kICVpXG4iLCB3UGFyYW0pOwp9CgpWT0lEIExBTkdVQUdFX0luaXQoVk9JRCkKewogIENIQVIgc3pCdWZmZXJbTUFYX1BBVEhOQU1FX0xFTl07CgogICNpZmRlZiBXSU5FTElCCiAgIEdsb2JhbHMubHBzekxhbmd1YWdlID0gTGFuZ3VhZ2VzW09wdGlvbnMubGFuZ3VhZ2VdLm5hbWU7CiAgI2VuZGlmCiAgCiAgaWYgKEdsb2JhbHMubHBzekxhbmd1YWdlID09ICJFbiIpIHsKICAgICAgICBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoInByb2dyYW1zIiwgImxhbmd1YWdlIiwgIkVuIiwgc3pCdWZmZXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN6QnVmZmVyKSk7ICAgICAgIAogICAgICAgIEdsb2JhbHMubHBzekxhbmd1YWdlID0gTG9jYWxMb2NrKExvY2FsQWxsb2MoTE1FTV9GSVhFRCwgbHN0cmxlbihzekJ1ZmZlcikrMSkpOwoKLyogICAgICAgIGhtZW1jcHkoR2xvYmFscy5scHN6TGFuZ3VhZ2UsIHN6QnVmZmVyLCAxK2xzdHJsZW4oc3pCdWZmZXIpKTsgICovCiAgICAgICAgbHN0cmNweW4oR2xvYmFscy5scHN6TGFuZ3VhZ2UsIHN6QnVmZmVyLCBzdHJsZW4oc3pCdWZmZXIpKzEpOyAKICB9Cn0KCi8qIExvY2FsIFZhcmlhYmxlczogICAgKi8KLyogYy1maWxlLXN0eWxlOiAiR05VIiAqLwovKiBFbmQ6ICAgICAgICAgICAgICAgICovCg==