LyoKICogQ2xvY2sKICoKICogQ29weXJpZ2h0IDE5OTggTWFyY2VsIEJhdXIgPG1iYXVyQGcyNi5ldGh6LmNoPgogKiBDb3B5cmlnaHQgMTk5OCBLYXJsIEJhY2tzdHL2bSA8a2FybF9iQGdlb2NpdGllcy5jb20+CiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJtYWluLmgiCiNpbmNsdWRlICJsYW5ndWFnZS5oIgojaWZkZWYgV0lORUxJQgojaW5jbHVkZSAib3B0aW9ucy5oIgojZW5kaWYKCkNIQVIgU1RSSU5HX01FTlVfWHhbXSAgICAgID0gIk1FTlVfWHgiOwoKc3RhdGljIEJPT0wgTEFOR1VBR0VfTG9hZFN0cmluZ090aGVyTGFuZ3VhZ2UoVUlOVCBudW0sIFVJTlQgaWRzLCBMUFNUUiBzdHIsIFVJTlQgbGVuKQp7CiAgaWRzIC09IEdsb2JhbHMud1N0cmluZ1RhYmxlT2Zmc2V0OwogIGlkcyArPSBudW0gKiAweDEwMDsKICByZXR1cm4oTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgaWRzLCBzdHIsIGxlbikpOwp9OwoKVk9JRCBMQU5HVUFHRV9TZWxlY3RMYW5ndWFnZUJ5TmFtZShMUENTVFIgbGFuZykKewogIElOVCBpOwogIENIQVIgbmV3bGFuZ1szXTsKCiAgZm9yIChpID0gMDsgaSA8PSBNQVhfTEFOR1VBR0VfTlVNQkVSOyBpKyspCiAgICBpZiAoTEFOR1VBR0VfTG9hZFN0cmluZ090aGVyTGFuZ3VhZ2UoaSwgSURTX0xBTkdVQUdFX0lELCBuZXdsYW5nLCBzaXplb2YobmV3bGFuZykpICYmCgkhbHN0cmNtcChsYW5nLCBuZXdsYW5nKSkKICAgICAgewogICAgICAgIExBTkdVQUdFX1NlbGVjdExhbmd1YWdlQnlOdW1iZXIoaSk7CglyZXR1cm47CiAgICAgIH0KCiAgLyogRmFsbGJhY2sgKi8KICAgIGZvciAoaSA9IDA7IGkgPD0gTUFYX0xBTkdVQUdFX05VTUJFUjsgaSsrKQogICAgaWYgKExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlckxhbmd1YWdlKGksIElEU19MQU5HVUFHRV9JRCwgbmV3bGFuZywgc2l6ZW9mKG5ld2xhbmcpKSkKICAgICAgewoJTEFOR1VBR0VfU2VsZWN0TGFuZ3VhZ2VCeU51bWJlcihpKTsKCXJldHVybjsKICAgICAgfQoKICBNZXNzYWdlQm94KEdsb2JhbHMuaE1haW5XbmQsICJObyBsYW5ndWFnZSBmb3VuZCIsICJGQVRBTCBFUlJPUiIsIE1CX09LKTsKICBQb3N0UXVpdE1lc3NhZ2UoMSk7Cn0KClZPSUQgTEFOR1VBR0VfU2VsZWN0TGFuZ3VhZ2VCeU51bWJlcihVSU5UIG51bSkKewogIElOVCAgICBpOwogIENIQVIgICBsYW5nWzNdOwogIENIQVIgICBjYXB0aW9uW01BWF9TVFJJTkdfTEVOXTsKICBDSEFSICAgaXRlbVtNQVhfU1RSSU5HX0xFTl07CiAgSE1FTlUgIGhNYWluTWVudTsKCiAgLyogU2VsZWN0IHN0cmluZyB0YWJsZSAqLwogIEdsb2JhbHMud1N0cmluZ1RhYmxlT2Zmc2V0ID0gbnVtICogMHgxMDA7CgogIC8qIEdldCBMYW5ndWFnZSBpZCAqLwogIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19MQU5HVUFHRV9JRCwgbGFuZywgc2l6ZW9mKGxhbmcpKTsKICBHbG9iYWxzLmxwc3pMYW5ndWFnZSA9IGxhbmc7CiAgcHJpbnRmKCIgR2xvYmFscy5scHN6TGFuZ3VhZ2U6ICVzXG4iLCBHbG9iYWxzLmxwc3pMYW5ndWFnZSk7CgogIC8qIFNldCBmcmFtZSBjYXB0aW9uICovCiAgTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX0NMT0NLLCBjYXB0aW9uLCBzaXplb2YoY2FwdGlvbikpOwogIFNldFdpbmRvd1RleHQoR2xvYmFscy5oTWFpblduZCwgY2FwdGlvbik7CgogIC8qIENoYW5nZSBSZXNvdXJjZSBuYW1lcyAqLwogIGxzdHJjcHluKFNUUklOR19NRU5VX1h4ICAgICsgc2l6ZW9mKFNUUklOR19NRU5VX1h4KSAgICAtIDMsIGxhbmcsIDMpOwoKICAvKiBDcmVhdGUgbWVudSAqLwogIGhNYWluTWVudSA9IExvYWRNZW51KEdsb2JhbHMuaEluc3RhbmNlLCBTVFJJTkdfTUVOVV9YeCk7CiAgICBHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMCk7CiAgICBHbG9iYWxzLmhMYW5ndWFnZU1lbnUgCT0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDEpOwogICAgR2xvYmFscy5oSW5mb01lbnUgICAgIAk9IEdldFN1Yk1lbnUoaE1haW5NZW51LCAyKTsKCiAgLyogUmVtb3ZlIGR1bW15IGl0ZW0gKi8KICBSZW1vdmVNZW51KEdsb2JhbHMuaExhbmd1YWdlTWVudSwgMCwgTUZfQllQT1NJVElPTik7CiAgLyogQWRkIGxhbmd1YWdlIGl0ZW1zICovCiAgZm9yIChpID0gMDsgaSA8PSBNQVhfTEFOR1VBR0VfTlVNQkVSOyBpKyspCiAgICBpZiAoTEFOR1VBR0VfTG9hZFN0cmluZ090aGVyTGFuZ3VhZ2UoaSwgSURTX0xBTkdVQUdFX01FTlVfSVRFTSwgaXRlbSwgc2l6ZW9mKGl0ZW0pKSkKICAgICAgQXBwZW5kTWVudShHbG9iYWxzLmhMYW5ndWFnZU1lbnUsIE1GX1NUUklORyB8IE1GX0JZQ09NTUFORCwKCQkgQ0xfRklSU1RfTEFOR1VBR0UgKyBpLCBpdGVtKTsKCiAgU2V0TWVudShHbG9iYWxzLmhNYWluV25kLCBoTWFpbk1lbnUpOwoKICAvKiBEZXN0cm95IG9sZCBtZW51ICovCiAgaWYgKEdsb2JhbHMuaE1haW5NZW51KSBEZXN0cm95TWVudShHbG9iYWxzLmhNYWluTWVudSk7CiAgR2xvYmFscy5oTWFpbk1lbnUgPSBoTWFpbk1lbnU7CgojaWZkZWYgV0lORUxJQgogIC8qIFVwZGF0ZSBzeXN0ZW0gbWVudXMgKi8KICBmb3IgKGkgPSAwOyBMYW5ndWFnZXNbaV0ubmFtZSAmJiBsc3RyY21wKGxhbmcsIExhbmd1YWdlc1tpXS5uYW1lKTspIGkrKzsKICBpZiAoTGFuZ3VhZ2VzW2ldLm5hbWUpIE9wdGlvbnMubGFuZ3VhZ2UgPSBpOwoKI2VuZGlmCgovKiBTcGVjaWZpYyBmb3IgY2xvY2sgKi8KaWYoR2xvYmFscy5iQW5hbG9nID09IFRSVUUpIHsKCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIENMX0FOQUxPRywgXAogICAgICAgICAgICAgICAgICAgICAgIE1GX0JZQ09NTUFORCB8IE1GX0NIRUNLRUQpOwogICAgICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIENMX0RJR0lUQUwsIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9VTkNIRUNLRUQpOwp9CmVsc2UgewoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfQU5BTE9HLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfVU5DSEVDS0VEKTsKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCBDTF9ESUdJVEFMLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfQ0hFQ0tFRCk7Cn0KCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIENMX1dJVEhPVVRfVElUTEUsIE1GX0JZQ09NTUFORCB8IFwKCSAgICAgICAgICAgICAgICAgICAgIChHbG9iYWxzLmJXaXRob3V0VGl0bGUgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEKSk7CglDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCBDTF9PTl9UT1AsIE1GX0JZQ09NTUFORCB8IFwKCSAgICAgICAgICAgICAgICAgICAgIChHbG9iYWxzLmJBbHdheXNPblRvcCA/IE1GX0NIRUNLRUQgOiBNRl9VTkNIRUNLRUQpKTsKCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIENMX1NFQ09ORFMsIE1GX0JZQ09NTUFORCB8IFwKCSAgICAgICAgICAgICAgICAgICAgIChHbG9iYWxzLmJTZWNvbmRzID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgQ0xfREFURSwgTUZfQllDT01NQU5EIHwgXAoJICAgICAgICAgICAgICAgICAgICAgKEdsb2JhbHMuYkRhdGUgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEKSk7Cn0KClZPSUQgTEFOR1VBR0VfRGVmYXVsdExhbmd1YWdlSGFuZGxlKFdQQVJBTSB3UGFyYW0pCnsKICBpZiAoKHdQYXJhbSA+PUNMX0ZJUlNUX0xBTkdVQUdFKSAmJiAod1BhcmFtPD1DTF9MQVNUX0xBTkdVQUdFKSkKICAgICAgICAgIExBTkdVQUdFX1NlbGVjdExhbmd1YWdlQnlOdW1iZXIod1BhcmFtIC0gQ0xfRklSU1RfTEFOR1VBR0UpOwogICAgIGVsc2UgcHJpbnRmKCJVbmltcGxlbWVudGVkIG1lbnUgY29tbWFuZCAlaVxuIiwgd1BhcmFtKTsKfQoKVk9JRCBMQU5HVUFHRV9Jbml0TGFuZ3VhZ2UoVk9JRCkKewogICNpZmRlZiBXSU5FTElCCiAgIEdsb2JhbHMubHBzekxhbmd1YWdlID0gTGFuZ3VhZ2VzW09wdGlvbnMubGFuZ3VhZ2VdLm5hbWU7CiAgI2Vsc2UKICBDSEFSIGJ1ZmZlcltNQVhfUEFUSE5BTUVfTEVOXSwgKnA7CgogICAgUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCJwcm9ncmFtcyIsICJsYW5ndWFnZSIsICJsYW5ndWFnZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpOwogIEdsb2JhbHMubHBzekxhbmd1YWdlID0gcCA9IExvY2FsTG9jayhMb2NhbEFsbG9jKExNRU1fRklYRUQsIGxzdHJsZW4oYnVmZmVyKSkpOwogIGhtZW1jcHkocCwgYnVmZmVyLCAxICsgbHN0cmxlbihidWZmZXIpKTsKICAjZW5kaWYKfQoKLyogTG9jYWwgVmFyaWFibGVzOiAgICAqLwovKiBjLWZpbGUtc3R5bGU6ICJHTlUiICovCi8qIEVuZDogICAgICAgICAgICAgICAgKi8K