LyoKICogIE5vdGVwYWQKICoKICogIENvcHlyaWdodCAxOTk3LDk4IE1hcmNlbCBCYXVyIDxtYmF1ckBnMjYuZXRoei5jaD4KICogIENvcHlyaWdodCAxOTk4IEthcmwgQmFja3N0cvdtIDxrYXJsX2JAZ2VvY2l0aWVzLmNvbT4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIm1haW4uaCIKI2luY2x1ZGUgImxhbmd1YWdlLmgiCgojaWZkZWYgV0lORUxJQgojaW5jbHVkZSAib3B0aW9ucy5oIgojZW5kaWYKCkNIQVIgU1RSSU5HX01FTlVfWHhbXSAgICAgID0gIk1FTlVfWHgiOwpDSEFSIFNUUklOR19QQUdFU0VUVVBfWHhbXSA9ICJESUFMT0dfUEFHRVNFVFVQX1h4IjsKCnZvaWQgTEFOR1VBR0VfVXBkYXRlV2luZG93Q2FwdGlvbih2b2lkKSB7CiAgLyogU2V0cyB0aGUgY2FwdGlvbiBvZiB0aGUgbWFpbiB3aW5kb3cgYWNjb3JkaW5nIHRvIEdsb2JhbHMuc3pGaWxlTmFtZToKICAgICAgTm90ZXBhZCAtICh1bnRpdGxlZCkgICAgICBpZiBubyBmaWxlIGlzIG9wZW4KICAgICAgTm90ZXBhZCAtIFtmaWxlbmFtZV0gICAgICBpZiBhIGZpbGUgaXMgZ2l2ZW4KICAqLwogIAogIENIQVIgc3pDYXB0aW9uW01BWF9TVFJJTkdfTEVOXTsKICBDSEFSIHN6VW50aXRsZWRbTUFYX1NUUklOR19MRU5dOwoKICBMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBJRFNfTk9URVBBRCwgc3pDYXB0aW9uLCBzaXplb2Yoc3pDYXB0aW9uKSk7CiAgCiAgaWYgKHN0cmxlbihHbG9iYWxzLnN6RmlsZU5hbWUpPjApIHsKICAgICAgbHN0cmNhdChzekNhcHRpb24sICIgLSBbIik7CiAgICAgIGxzdHJjYXQoc3pDYXB0aW9uLCBHbG9iYWxzLnN6RmlsZU5hbWUpOwogICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgIl0iKTsKICB9CiAgZWxzZQogIHsKICAgICAgTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX1VOVElUTEVELCBzelVudGl0bGVkLCBzaXplb2Yoc3pVbnRpdGxlZCkpOwogICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgIiAtICIpOwogICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgc3pVbnRpdGxlZCk7CiAgfQogICAgCiAgU2V0V2luZG93VGV4dChHbG9iYWxzLmhNYWluV25kLCBzekNhcHRpb24pOwogIAp9CgoKCnN0YXRpYyBCT09MIExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihVSU5UIG51bSwgVUlOVCBpZHMsIExQU1RSIHN0ciwgVUlOVCBsZW4pCnsKICBpZHMgLT0gR2xvYmFscy53U3RyaW5nVGFibGVPZmZzZXQ7CiAgaWRzICs9IG51bSAqIDB4MTAwOwogIHJldHVybihMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBpZHMsIHN0ciwgbGVuKSk7Cn07CgoKClZPSUQgTEFOR1VBR0VfU2VsZWN0QnlOYW1lKExQQ1NUUiBsYW5nKQp7CiAgSU5UIGk7CiAgQ0hBUiBuZXdsYW5nWzNdOwoKICBmb3IgKGkgPSAwOyBpIDw9IE1BWF9MQU5HVUFHRV9OVU1CRVI7IGkrKykKICAgIGlmIChMQU5HVUFHRV9Mb2FkU3RyaW5nT3RoZXIoaSwgSURTX0xBTkdVQUdFX0lELCBuZXdsYW5nLCBzaXplb2YobmV3bGFuZykpICYmCiAgICAgICAgIWxzdHJjbXAobGFuZywgbmV3bGFuZykpCiAgICAgIHsKICAgICAgICBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcihpKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgLyogRmFsbGJhY2sgKi8KICAgIGZvciAoaSA9IDA7IGkgPD0gTUFYX0xBTkdVQUdFX05VTUJFUjsgaSsrKQogICAgaWYgKExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihpLCBJRFNfTEFOR1VBR0VfSUQsIG5ld2xhbmcsIHNpemVvZihuZXdsYW5nKSkpCiAgICAgIHsKICAgICAgICBMQU5HVUFHRV9TZWxlY3RCeU51bWJlcihpKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgTWVzc2FnZUJveChHbG9iYWxzLmhNYWluV25kLCAiTm8gbGFuZ3VhZ2UgZm91bmQiLCAiRkFUQUwgRVJST1IiLCBNQl9PSyk7CiAgUG9zdFF1aXRNZXNzYWdlKDEpOwp9CgpWT0lEIExBTkdVQUdFX1NlbGVjdEJ5TnVtYmVyKFVJTlQgbnVtKQp7CiAgSU5UICAgIGk7CiAgQ0hBUiAgIGxhbmdbM107CiAgQ0hBUiAgIGl0ZW1bTUFYX1NUUklOR19MRU5dOwogIEhNRU5VICBoTWFpbk1lbnU7CgogIC8qIFNlbGVjdCBzdHJpbmcgdGFibGUgKi8KICBHbG9iYWxzLndTdHJpbmdUYWJsZU9mZnNldCA9IG51bSAqIDB4MTAwOwoKICAvKiBHZXQgTGFuZ3VhZ2UgaWQgKi8KICBMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBJRFNfTEFOR1VBR0VfSUQsIGxhbmcsIHNpemVvZihsYW5nKSk7CiAgR2xvYmFscy5scHN6TGFuZ3VhZ2UgPSBsYW5nOwoKICAvKiBTZXQgZnJhbWUgY2FwdGlvbiAqLwogIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oKTsKICAKICAvKiBDaGFuZ2UgUmVzb3VyY2UgbmFtZXMgKi8KICBsc3RyY3B5bihTVFJJTkdfTUVOVV9YeCAgICAgICsgc2l6ZW9mKFNUUklOR19NRU5VX1h4KSAgICAgIC0gMywgbGFuZywgMyk7CiAgbHN0cmNweW4oU1RSSU5HX1BBR0VTRVRVUF9YeCArIHNpemVvZihTVFJJTkdfUEFHRVNFVFVQX1h4KSAtIDMsIGxhbmcsIDMpOwoKICAvKiBDcmVhdGUgbWVudSAqLwogIGhNYWluTWVudSA9IExvYWRNZW51KEdsb2JhbHMuaEluc3RhbmNlLCBTVFJJTkdfTUVOVV9YeCk7CiAgICBHbG9iYWxzLmhGaWxlTWVudSAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMCk7CiAgICBHbG9iYWxzLmhFZGl0TWVudSAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMSk7CiAgICBHbG9iYWxzLmhTZWFyY2hNZW51ICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMik7CiAgICBHbG9iYWxzLmhMYW5ndWFnZU1lbnUgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgMyk7CiAgICBHbG9iYWxzLmhIZWxwTWVudSAgICAgPSBHZXRTdWJNZW51KGhNYWluTWVudSwgNCk7CgogIC8qIFJlbW92ZSBkdW1teSBpdGVtICovCiAgUmVtb3ZlTWVudShHbG9iYWxzLmhMYW5ndWFnZU1lbnUsIDAsIE1GX0JZUE9TSVRJT04pOwogIC8qIEFkZCBsYW5ndWFnZSBpdGVtcyAqLwogIGZvciAoaSA9IDA7IGkgPD0gTUFYX0xBTkdVQUdFX05VTUJFUjsgaSsrKQogICAgaWYgKExBTkdVQUdFX0xvYWRTdHJpbmdPdGhlcihpLCBJRFNfTEFOR1VBR0VfTUVOVV9JVEVNLCBpdGVtLCBzaXplb2YoaXRlbSkpKQogICAgICBBcHBlbmRNZW51KEdsb2JhbHMuaExhbmd1YWdlTWVudSwgTUZfU1RSSU5HIHwgTUZfQllDT01NQU5ELAogICAgICAgICAgICAgICAgIE5QX0ZJUlNUX0xBTkdVQUdFICsgaSwgaXRlbSk7CgogIFNldE1lbnUoR2xvYmFscy5oTWFpblduZCwgaE1haW5NZW51KTsKCiAgLyogRGVzdHJveSBvbGQgbWVudSAqLwogIGlmIChHbG9iYWxzLmhNYWluTWVudSkgRGVzdHJveU1lbnUoR2xvYmFscy5oTWFpbk1lbnUpOwogIEdsb2JhbHMuaE1haW5NZW51ID0gaE1haW5NZW51OwoKI2lmZGVmIFdJTkVMSUIKICAvKiBVcGRhdGUgc3lzdGVtIG1lbnVzICovCiAgZm9yIChpID0gMDsgTGFuZ3VhZ2VzW2ldLm5hbWUgJiYgbHN0cmNtcChsYW5nLCBMYW5ndWFnZXNbaV0ubmFtZSk7KSBpKys7CiAgaWYgKExhbmd1YWdlc1tpXS5uYW1lKSBPcHRpb25zLmxhbmd1YWdlID0gaTsKCiNlbmRpZgp9CgpWT0lEIExBTkdVQUdFX0RlZmF1bHRIYW5kbGUoV1BBUkFNIHdQYXJhbSkKewogIGlmICgod1BhcmFtID49TlBfRklSU1RfTEFOR1VBR0UpICYmICh3UGFyYW08PU5QX0xBU1RfTEFOR1VBR0UpKQogICAgICAgICAgTEFOR1VBR0VfU2VsZWN0QnlOdW1iZXIod1BhcmFtIC0gTlBfRklSU1RfTEFOR1VBR0UpOwogICAgIGVsc2UgcHJpbnRmKCJVbmltcGxlbWVudGVkIG1lbnUgY29tbWFuZCAlaVxuIiwgd1BhcmFtKTsKfQoKVk9JRCBMQU5HVUFHRV9Jbml0KFZPSUQpCnsKICAjaWZkZWYgV0lORUxJQgogICBHbG9iYWxzLmxwc3pMYW5ndWFnZSA9IExhbmd1YWdlc1tPcHRpb25zLmxhbmd1YWdlXS5uYW1lOwogICNlbHNlCiAgQ0hBUiBidWZmZXJbTUFYX1BBVEhOQU1FX0xFTl0sICpwOwoKICAgIFBST0ZJTEVfR2V0V2luZUluaVN0cmluZygicHJvZ3JhbXMiLCAibGFuZ3VhZ2UiLCAibGFuZ3VhZ2UiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIsIHNpemVvZihidWZmZXIpKTsKICBHbG9iYWxzLmxwc3pMYW5ndWFnZSA9IHAgPSBMb2NhbExvY2soTG9jYWxBbGxvYyhMTUVNX0ZJWEVELCBsc3RybGVuKGJ1ZmZlcikrMSkpOwogIHN0cmNweShwLCBidWZmZXIpOwogIC8qIGhtZW1jcHkocCwgYnVmZmVyLCAxICsgbHN0cmxlbihidWZmZXIpKTsgKi8KICAjZW5kaWYKfQoKLyogTG9jYWwgVmFyaWFibGVzOiAgICAqLwovKiBjLWZpbGUtc3R5bGU6ICJHTlUiICovCi8qIEVuZDogICAgICAgICAgICAgICAgKi8KCg==