Ly8gTW9yZ2VuR3JhdWVuIE1VRGxpYgovLwovLyB0aGluZy9jb21tYW5kcy5jIC0tIHRoaW5nIGRlc2NyaXB0aW9uCi8vCi8vICRJZDogY29tbWFuZHMuYyA5NTE0IDIwMTYtMDItMjMgMjA6MzM6MDlaIEdsb2luc29uICQKLy8KLy8gQXVzIFJlZ2VuYm9nZW4gTVVETGliCi8vIGF1cyBHdWVsZGVubGFuZC9XdW5kZXJsYW5kIE1VRGxpYiAoTW9yZ2VuZ3JhdWVuIE1VRGxpYikKLy8KLy8gUF9DT01NQU5EUyBkYXRhLXN0cnVjdHVyZToKLy8KLy8gQWRkQ21kKHZlcmIsZnVuMSwxKTsKLy8gQWRkQ21kKHZlcmIrc3luMWF8c3luMWImc3luMmF8c3luMmJ8c3luMmMsZnVuMiwKLy8gICAgICAgIGVycm9yMV9ub3RpZnl8ZXJyb3IyX25vdGlmeV5lcnJvcjJfd3JpdGUpOwovLyAtLT4KLy8gKFt2ZXJiOgovLyAgICAoe2Z1bjEsZnVuMn0pOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmdW5zCi8vICAgICh7MSwoe2Vycm9yMV9ub3RpZnksIGVycm9yMl93cml0ZV5lcnJvcjJfc2F5LCAxfSl9KTsgIC8vIGZsYWdzCi8vICAgICh7MCwoeyh7c3luMWEsc3luMWJ9KSwoe3N5bjJhLHN5bjJiLHN5bjJjfSl9KX0pOyAgICAgIC8vIHJ1bGVzCi8vICAgIDA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElEcwovLyAgICAoe2Nsb3N1cmUgYXVmIGZ1bjEsIGNsb3N1cmUgYXVmIGZ1bjJ9KSBdKSAgICAgICAgICAgICAvLyBDYWNoZQovLwovLyBGdW5zOiAgKHs8ZnVuMT4gLC4uLgovLyAgICAgICAgICAnZnVuJyBrYW5uIHNlaW46IENsb3N1cmUKLy8gICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmc6IE1ldGhvZGVubmFtZSAtIHdpcmQgZXR3YXMgZ2VwcnVlZnQKLy8gICAgICAgICAgICAgICAgICAgICAgICAgICBPYmpla3Q6IHdlbm4ga2VpbmUgTWV0aG9kZSwgdGhpc19vYmplY3QoKSBmdWVyCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcm4sIHByZXZpb3VzX29iamVjdCgpIGZ1ZXIgZXh0ZXJuCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAoZXJsb3NjaGVuZXMgZXh0ZXJuZXMgT2JqZWt0KQovLyBSdWxlczogKHs8UmVnZWxzYXR6IGZ1ZXIgZnVuMT4sICh7PDEuIFN5bm9ueW1ncnVwcGU+LAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDIuIFN5bm9ueW1ncnVwcGUsIC4uLn0pLCAuLi59KQovLyBGbGFnczogKHs8RmxhZyBmdWVyIGZ1bjE+LCAoezxGZWhsZXJtZWxkdW5nIDEuIFN5bm9ueW1ncnVwcGU+LCAuLi4gLAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFssIEluZGV4IGZ1ZXIgd3JpdGUgYW5zdGF0dCBub3RpZnlfZmFpbF19KSwKLy8gICAgICAgICAgICAuLi4gfSkKLy8gSURzOiAgIDAgb2RlciAoezxJRCBmdWVyIGZ1bjE+fSkgb2RlciAoezAsIDxJRCBmdWVyIGZ1bjI+fSkgLi4uCi8vIENhY2hlOiAoezxjbG9zdXJlIGZ1ZXIgZnVuMT4sIC4uLgovLyAgICAgICAgQ2FjaGUtQ2xvc3VyZXMgc2luZCBiZWkgRXhwb3J0IChRdWVyeVByb3ApIGltbWVyIGdlbnVsbHQKI3ByYWdtYSBzdHJpY3RfdHlwZXMKI3ByYWdtYSBzYXZlX3R5cGVzCiNwcmFnbWEgcmFuZ2VfY2hlY2sKI3ByYWdtYSBub19jbG9uZQojcHJhZ21hIHBlZGFudGljCgojaW5jbHVkZSA8bW92aW5nLmg+CiNpbmNsdWRlIDx0aGluZy9sYW5ndWFnZS5oPgojaW5jbHVkZSA8ZXhwbG9yYXRpb24uaD4KI2luY2x1ZGUgPGRlZmluZXMuaD4KI2luY2x1ZGUgPGxpdmluZy9jb21tLmg+CiNpbmNsdWRlIDxmdW5jdGlvbmxpc3QuaD4KCiNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCiNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CiNpbmNsdWRlIDx0aGluZy9kZXNjcmlwdGlvbi5oPgojaW5jbHVkZSA8dGhpbmcvY29tbWFuZHMuaD4KI3VuZGVmIE5FRURfUFJPVE9UWVBFUwoKI2RlZmluZSBDTURTX1dJRFRIIDUKLy8gTWFwcGluZy1JbmRpemVzCiNkZWZpbmUgQ01ESURYX0ZVTiAgIDAKI2RlZmluZSBDTURJRFhfRkxBRyAgMQojZGVmaW5lIENNRElEWF9SVUxFICAyCiNkZWZpbmUgQ01ESURYX0lEICAgIDMKI2RlZmluZSBDTURJRFhfQ0FDSEUgNAoKI2lmZGVmIERCRwojdW5kZWYgREJHCiNlbmRpZgojZGVmaW5lIERCRyh4KSBwcmludGYoIk9iamVjdCAlTyB0bXBzdHI9JXNcbiIsIGV4cGxvZGUob2JqZWN0X25hbWUodGhpc19vYmplY3QoKSksIiMiKVsxXSwgeCk7Cgpwcml2YXRlIG5vc2F2ZSBtYXBwaW5nIGFkZGVkX2NtZHM7Cgpwcm90ZWN0ZWQgaW50IF9jbWRfc3ludGF4aGVscChzdHJpbmcgc3RyLCBtaXhlZCAqYXJncykKewogIG1hcHBpbmd8Y2xvc3VyZSByZXN0cjsKICBtaXhlZCBoZWxwID0gUXVlcnlQcm9wKFBfU1lOVEFYX0hFTFApOwogIGlmIChwb2ludGVycChoZWxwKSkKICB7CiAgICByZXN0ciA9IGhlbHBbMV07CiAgICBoZWxwID0gaGVscFswXTsKICB9CiAgLy8gUmVzdHJpa3Rpb25lbiB2b3IgZGVtIEFuemVpZ2VuIHBydWVmZW4uCiAgaWYgKG1hcHBpbmdwKHJlc3RyKSkKICB7CiAgICBzdHJpbmcgcmVzID0gIi9zdGQvcmVzdHJpY3Rpb25fY2hlY2tlciItPmNoZWNrX3Jlc3RyaWN0aW9ucyhQTCxyZXN0cik7CiAgICBpZiAocmVzKQogICAgewogICAgICBQTC0+UmVjZWl2ZU1zZygiRnVlciAiICsgbmFtZShXRU4sMSkgKyAiIGRhcmZzdCBEdSAiCiAgICAgICAgICAgICAgICAgICAgICJkaWUgU3ludGF4aGlsZmUgKG5vY2gpIG5pY2h0IGxlc2VuOlxuIgogICAgICAgICAgICAgICAgICAgICArIHJlcywKICAgICAgICAgICAgICAgICAgICAgTVRfTk9USUZJQ0FUSU9OfE1TR19CU19MRUFWRV9MRlMsCiAgICAgICAgICAgICAgICAgICAgICJzeW50YXhoaWxmZSIsMCx0aGlzX29iamVjdCgpKTsKICAgICAgcmV0dXJuIDE7CiAgICB9CiAgfQogIGVsc2UgaWYgKGNsb3N1cmVwKHJlc3RyKSkKICB7CiAgICBzdHJpbmcgcmVzID0gZnVuY2FsbChyZXN0ciwgTUUpOwogICAgaWYgKHJlcykKICAgIHsKICAgICAgaWYgKGludHAocmVzKSkKICAgICAgICBQTC0+UmVjZWl2ZU1zZygiRnVlciAiICsgbmFtZShXRU4sMSkgKyAiIGRhcmZzdCBEdSAiCiAgICAgICAgICAgICAgICAgICAgICAgImRpZSBTeW50YXhoaWxmZSAobm9jaCkgbmljaHQgbGVzZW4uIiwKICAgICAgICAgICAgICAgICAgICAgICBNVF9OT1RJRklDQVRJT058TVNHX0JTX0xFQVZFX0xGUywKICAgICAgICAgICAgICAgICAgICAgICAic3ludGF4aGlsZmUiLDAsdGhpc19vYmplY3QoKSk7CiAgICAgIGVsc2UgaWYgKHN0cmluZ3AocmVzKSkKICAgICAgICBQTC0+UmVjZWl2ZU1zZyhyZXMsCiAgICAgICAgICAgICAgICAgICAgICAgTVRfTk9USUZJQ0FUSU9OfE1TR19CU19MRUFWRV9MRlMsCiAgICAgICAgICAgICAgICAgICAgICAgInN5bnRheGhpbGZlIiwwLHRoaXNfb2JqZWN0KCkpOwogICAgICByZXR1cm4gMTsKICAgIH0KICB9CgogIGlmIChzdHJpbmdwKGhlbHApKQogIHsKICAgIGhlbHAgPSAiRnVlciAiICsgbmFtZShXRU4sMSkgKyAiIGdpYnQgZXMgZm9sZ2VuZGUgU3ludGF4aGlsZmU6XG4iCiAgICAgICAgICAgKyBoZWxwOwogIH0KICBlbHNlIGlmIChjbG9zdXJlcChoZWxwKSkKICB7CiAgICBoZWxwID0gZnVuY2FsbChoZWxwLCB0aGlzX29iamVjdCgpKTsKICB9CiAgZWxzZQogIHsKICAgIC8vIHdlbm4gZGFzIE9iamVrdCBrZWluZSBTeW50YXhoaWxmZSBoYXQsIGJyYXVjaHQgZXMgZGFzIEtvbW1hbmRvIGF1Y2gKICAgIC8vIG5pY2h0LgogICAgbm90aWZ5X2ZhaWwoIkZ1ZXIgIiArIG5hbWUoV0VOLDEpCiAgICAgICAgICAgICAgICArICIgZ2lidCBlcyBrZWluZSBTeW50YXhoaWxmZS5cbiIpOwogICAgUmVtb3ZlQ21kKDAsMCwgIl9jbWRfc3ludGF4aGVscCIpOwogICAgcmV0dXJuIDA7CiAgfQogIGlmIChzdHJpbmdwKGhlbHApICYmIHNpemVvZihoZWxwKSkKICAgIFBMLT5SZWNlaXZlTXNnKGhlbHAsIE1UX05PVElGSUNBVElPTnxNU0dfQlNfTEVBVkVfTEZTLAogICAgICAgICAgICAgICAgICAgInN5bnRheGhpbGZlIiwwLHRoaXNfb2JqZWN0KCkpOwoKICByZXR1cm4gMTsKfQoKcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKewogIEFkZENtZCgic3ludGF4aGlsZmUmQElEIiwgIydfY21kX3N5bnRheGhlbHAsCiAgICAgICAgICJGdWVyIFdBUyBtb2VjaHRlc3QgRHUgZWluZSBTeW50YXhoaWxmZT9cbiIsCiAgICAgICAgICJfY21kX3N5bnRheGhlbHAiKTsKfQoKcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgewogIHNldF9uZXh0X3Jlc2V0KC0xKTsKfQoKcHJpdmF0ZSBjbG9zdXJlIF9jaGVja19zdHJpbmdtZXRob2QobWl4ZWQgZnVuYywgaW50IGV4LCBzdHJpbmcgcmVzcCkgewogIGNsb3N1cmUgY2w7CiAgaWYoIWZ1bmN0aW9uX2V4aXN0cyhmdW5jKSkKICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCiAgICAgIHJlc3ArInN0cmluZy1NZXRob2RlICclcycgZmVobHQgb2RlciBpc3QgcHJpdmF0ZS5cbiIsIGZ1bmMpKTsKCiAgLy8gZXh0ZXJuIGVyc3RlbGx0ZSBhdWYgU2ljaHRiYXJrZWl0IHBydWVmZW4gdW5kIGFiYnJlY2hlbi9kYXZvciB3YXJuZW4KICBpZihleCkgewogICAgbWl4ZWQgKmZsID0gZnVuY3Rpb25saXN0KHRoaXNfb2JqZWN0KCksIFJFVFVSTl9GVU5DVElPTl9OQU1FfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFVFVSTl9GVU5DVElPTl9GTEFHUyk7CiAgICBpbnQgaW5kZXggPSBtZW1iZXIoZmwsIGZ1bmMpKzE7CiAgICBpZihpbmRleDw9MCB8fCBzaXplb2YoZmwpPD1pbmRleCkKICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKICAgICAgICByZXNwKyJzdHJpbmctTWV0aG9kZSAnJXMnIG5pY2h0IGluIGZ1bmN0aW9ubGlzdC5cbiIsIGZ1bmMpKTsKICAgIGVsc2UgaWYoZmxbaW5kZXhdJlRZUEVfTU9EX1BST1RFQ1RFRCB8fCBmbFtpbmRleF0mVFlQRV9NT0RfU1RBVElDKQogICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAogICAgICAgIHJlc3ArInN0cmluZy1NZXRob2RlICclcycgaXN0IHByb3RlY3RlZC9zdGF0aWMuIEV4dGVybiAiCiAgICAgICAgImRlZmluaWVydGVzIEtvbW1hbmRvIGRhcmYgc28gZWluZSBNZXRob2RlIG5pY2h0IGF1ZnJ1ZmVuIVxuIiwKICAgICAgICBmdW5jKSk7CiAgfQoKICAvLyBhbnNvbnN0ZW4gTWV0aG9kZSBlcnN0bWFsIGNhY2hlbgogIGNsID0gc3ltYm9sX2Z1bmN0aW9uKGZ1bmMsIHRoaXNfb2JqZWN0KCkpOwogIGlmKCFjbCkKICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCiAgICAgIHJlc3ArInN0cmluZy1NZXRob2RlICclcycgbmljaHQgaW4gQ2xvc3VyZSB3YW5kZWxiYXI/XG4iLCBmdW5jKSk7CgogIHJldHVybiBjbDsKfQoKdmFyYXJncyB2b2lkIEFkZENtZChtaXhlZCBjbWQsIG1peGVkIGZ1bmMsIG1peGVkIGZsYWcsIG1peGVkIGNtZGlkKSB7CiBpbnQgaSxqOwogY2xvc3VyZSBjYWNoZWRjbDsKIG1peGVkICpydWxlOwoKIC8vIHBvdGVudGllbGxlIEFkZENtZCBtaXQgUmVnZWw/CiBpZihzdHJpbmdwKGNtZCkpIHsKICAvLyBlaW5lIFJlZ2VsPyAtIGF1ZnNwbGl0dGVuCiAgaWYoKGk9bWVtYmVyKGNtZCwnJicpKT4wKSB7CiAgIC8vIC4uLiBpbiBBcnJheSBtaXQgVmVya251ZXBmdW5nc2VsZW1lbnRlbgogICBydWxlPWV4cGxvZGUoY21kWyhpKzEpLi5dLCImIik7CiAgIGo9c2l6ZW9mKHJ1bGUpOwogICAvLyAuLi4gaW4gQXJyYXkgbWl0IEFycmF5cyBtaXQgQWx0ZXJuYXRpdmVsZW1lbnRlbjoKICAgLy8gInB8cSZyfHMiIC0+ICh7ICh7InAiLCJxIn0pLCAoeyJyIiwicyJ9fSB9KQogICB3aGlsZShqLS0pCiAgICBydWxlW2pdPWV4cGxvZGUocnVsZVtqXSwifCIpOwoKICAgLy8gUmVnZWxuIHZvbiBLb21tYW5kb3ZlcmJlbiBhYnNjaG5laWRlbgogICBjbWQ9Y21kWzAuLihpLTEpXTsKICB9CiAgLy8gS29tbWFuZG92ZXJiZW4gZXh0cmFoaWVyZW4KICBjbWQ9ZXhwbG9kZShjbWQsInwiKTsKCiAgLy8gU2F0eiB2b24gUmVnZWxuIGV4aXN0aWVydDogQXVmc3BsaXR0ZW4gdm9uIEZlaGxlcm1lbGR1bmdlbgogIGlmKHJ1bGUpCiAgIGlmKHN0cmluZ3AoZmxhZykpIHsKICAgIG1peGVkICpmYWlsOwogICAgLy8gaW4gZWluZmFjaGVzIEFycmF5IG1pdCBqZXdlaWxpZ2VuIEZlaGxlcm1lbGR1bmdlbgogICAgZmFpbD1leHBsb2RlKGZsYWcsInwiKTsKICAgIGo9MDsKICAgIGk9c2l6ZW9mKGZhaWwpOwogICAgd2hpbGUoajxpKSB7CiAgICAgLy8gd3JpdGUgLSBGZWhsZXJtZWxkdW5nIGVudGRlY2t0IC0gUG9zaXRpb24gZ2dmLiBlaW50cmFnZW4KICAgICBpZihtZW1iZXIoZmFpbFtqXSwnXicpPj0wICYmICFpbnRwKGZhaWxbPDFdKSkKICAgICAgZmFpbCs9KHtqfSk7CiAgICAgaWYobWVtYmVyKGZhaWxbal0sJ0AnKT49MCkgewogICAgICBpbnQgczsKICAgICAgZmxhZz1yZWdleHBsb2RlKGZhaWxbal0sICJAV0VbQS1TVV0qWzAtOV0iKTsKICAgICAgcz1zaXplb2YoZmxhZyk7CiAgICAgIHdoaWxlKChzLT0yKT4wKSB7CiAgICAgICBpbnQgdG1waW50OwogICAgICAgdG1waW50PWZsYWdbc11bPDFdLScxJzsKICAgICAgIGlmKHRtcGludDwwIHx8IHRtcGludD5qKQogICAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCiAgICAgICAgICJBZGRDbWQ6IGVycm9yLW1lc3NhZ2UgJWQgY29udGFpbnMgb3V0LW9mLWJvdW5kcyBAV0V4eC1ydWxlLlxuIixqKzEpKTsKICAgICAgfQogICAgIH0KICAgICBqKys7CiAgICB9CiAgICAvLyAiV2FzP3xXaWUgZGFzPyIgLT4gKHsiV2FzPyIsIldpZSBkYXM/In0pCiAgICAvLyAiV2FzP3xXaWUgZGFzP158V29taXQgZGFzP3xXb3JhdWYgZGFzP15AV0VSMSBtYWNodCB3YXMuIiAtPgogICAgLy8gICh7Ildhcz8iLAogICAgLy8gICAgIldpZSBkYXM/XldvbWl0IGRhcz8iLAogICAgLy8JICAiV29yYXVmIGRhcz9eQFdFUjEgbWFjaHQgd2FzLiIsMX0pCiAgICBmbGFnPXNpemVvZihmYWlsKTsKICAgIGlmKGZsYWcgJiYgZmxhZzxzaXplb2YocnVsZSkpCiAgICAgcmFpc2VfZXJyb3IoCiAgICAgICJBZGRDbWQ6IG51bWJlciBvZiBlcnJvci1tZXNzYWdlcyBkb2VzIG5vdCBtYXRjaCBudW1iZXIgb2YgcnVsZXMuXG4iKTsKICAgIGZsYWc9ZmFpbDsgLy8gdWViZXJzY2hyZWliZW4gbWl0IGRlbiBwYXJzZWZyZXVuZGxpY2hlbiBGb3JtYXQKICB9IGVsc2UgaWYoZmxhZykKICAgcmFpc2VfZXJyb3IoIkFkZENtZDogcnVsZXMgZXhpc3QgYnV0IGZsYWdzIGFyZSBub3QgYW4gZXJyb3Itc3RyaW5nLlxuIik7CiB9IC8vIGVuZCBpZihzdHJpbmdwKGNtZCkpIC4uLiBrZWluIFJlZ2Vsc3RyaW5nIHZvcmhhbmRlbgoKIC8vIGtlaW4gS29tbWFuZG9hcnJheSBnZXdlc2VuIG5vY2ggZXJ6ZXVndD8KIGlmKCFwb2ludGVycChjbWQpKQogICByYWlzZV9lcnJvcigiQWRkQ21kOiBtaXNzaW5nIHN0cmluZy9wb2ludGVyLXBhcmFtZXRlciBmb3IgY29tbWFuZC5cbiIpOwoKICAvLyBTdHJpbmctTWV0aG9kZSBhdWYgU2ljaHRiYXJrZWl0IHBydWVmZW4sIENhY2hlIGdsZWljaCBhbnBhc3NlbgogIHN3aXRjaCh0eXBlb2YoZnVuYykpIHsKICAgIGNhc2UgVF9TVFJJTkc6CiAgICAgIGNhY2hlZGNsPV9jaGVja19zdHJpbmdtZXRob2QoZnVuYywgZXh0ZXJuX2NhbGwoKSwgIkFkZENtZDogIik7CiAgICAgIGJyZWFrOwogICAgY2FzZSBUX0NMT1NVUkU6CiAgICAgIGNhY2hlZGNsPWZ1bmM7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgaWYoZXh0ZXJuX2NhbGwoKSkgZnVuYz1wcmV2aW91c19vYmplY3QoKTsKICAgICAgZWxzZSBmdW5jPXRoaXNfb2JqZWN0KCk7CiAgICAgIGJyZWFrOwogIH0KCiAgLy8gamVkZXMgZWluemVsbmUgVmVyYiBtaXQgc2VpbmVuIFJlZ2VsbiB1bmQgRnVua3Rpb25lbiBlaW50cmFnZW4KIGk9c2l6ZW9mKGNtZCk7CiBpZighYWRkZWRfY21kcykgYWRkZWRfY21kcz1tX2FsbG9jYXRlKGksIENNRFNfV0lEVEgpOwogd2hpbGUoaS0tKSB7CiAgc3RyaW5nIHN0cjsKICBzdHI9Y21kW2ldOwogIGlmKCFtZW1iZXIoYWRkZWRfY21kcyxzdHIpKQogICBhZGRlZF9jbWRzKz0oW3N0cjphbGxvY2F0ZSgwKTthbGxvY2F0ZSgwKTthbGxvY2F0ZSgwKTswO2FsbG9jYXRlKDApXSk7CiAgLy8gZXhpc3RpZXJlbmRlcyBWZXJiIGVyZ2FlbnplbgogIGFkZGVkX2NtZHNbc3RyLCBDTURJRFhfRlVOXSs9KHtmdW5jfSk7CiAgYWRkZWRfY21kc1tzdHIsIENNRElEWF9GTEFHXSs9KHtmbGFnfSk7CiAgYWRkZWRfY21kc1tzdHIsIENNRElEWF9SVUxFXSs9KHtydWxlfSk7CiAgYWRkZWRfY21kc1tzdHIsIENNRElEWF9DQUNIRV0rPSh7Y2FjaGVkY2x9KTsKICAvLyBnZ2YuIGlkIGluIGRhcyBJRC1NYXBwaW5nIGVpbnRyYWdlbgogIGlmKGNtZGlkKSB7CiAgIG1peGVkICp0bXA7CiAgIGo9c2l6ZW9mKChzdHJpbmcqKWFkZGVkX2NtZHNbc3RyLCBDTURJRFhfRlVOXSk7CiAgIHRtcD1hZGRlZF9jbWRzW3N0ciwgQ01ESURYX0lEXXx8YWxsb2NhdGUoaik7CiAgIGlmKHNpemVvZih0bXApPGopIHRtcCs9YWxsb2NhdGUoai1zaXplb2YodG1wKSk7CiAgIHRtcFs8MV09Y21kaWQ7CiAgIGFkZGVkX2NtZHNbc3RyLCBDTURJRFhfSURdPXRtcDsKICB9CiB9Cn0KCi8vIEF1c3dlcnR1bmcgZnVlciBlaW4gVmVyYiBsb2VzY2hlbgp2YXJhcmdzIGludCBSZW1vdmVDbWQobWl4ZWQgY21kLCBpbnQgZGVsX25vcnVsZSwgbWl4ZWQgb25seWlkKSB7CiBpbnQgcmV0OwoKIC8vIEZhbGxzIE1hZ2llciBkYXMgUmVtb3ZlQ21kIGZhbHNjaCBudXR6ZW4gKHouQi4gYW5hbG9nIHp1IEFkZENtZCkKIC8vIHdpcmQgZGFzIFJlZ2Vsc3lzdGVtIHZlcndpcnJ0LiBEYSBkYXMgZGVsX25vcnVsZSBudXIgaW50IHNlaW4gZGFyZiwKIC8vIGdpYnQgZXMgaGllciBlaW5lIGd1dGUgQ2hhbmNlIGRlbiBGZWhsZXIgYWJ3YWVydHNrb21wYXRpYmVsIHp1IGVudC0KIC8vIGRlY2tlbi4gRGFtaXQgU3BpZWxlciBkZW4gRmVobGVyIG5pY2h0IG1pdGJla29tbWVuLCB3aXJkIGhpZXIgYXVmCiAvLyBlaW4gcmFpc2VfZXJyb3IgdmVyemljaHRldCwgdW5kIHN0YXR0IGRlc3NlbiBpbiBlaW4gTG9nZmlsZSBnZS0KIC8vIHNjaHJpZWJlbi4KIGlmICghaW50cChkZWxfbm9ydWxlKSkKIHsKICAgbG9nX2ZpbGUoIlJFTU9WRV9DTUQiLAogICAgIHNwcmludGYoIlxuLS0gJXMgLS1cbklsbGVnYWwgUmVtb3ZlQ29tbWFuZCgpIGluIE9iamVjdCBbJU9dOlxuICVPXG4iLAogICAgICAgZHRpbWUodGltZSgpKSwgdGhpc19vYmplY3QoKSwgY21kKSk7CiAgIGRlbF9ub3J1bGU9MDsKICAgb25seWlkPTA7CiB9CiAKIGlmKCFhZGRlZF9jbWRzIHx8ICghY21kICYmICFkZWxfbm9ydWxlICYmICFvbmx5aWQpKQogIGFkZGVkX2NtZHM9KG1hcHBpbmcpMDsgCiBlbHNlIHsKICBpbnQgaSwgajsKICBtaXhlZCAqcnVsZSwgKmZsYWcsICpmdW4sICpkZWxydWxlLCAqaWRzLCAqY2FjaGVjbDsKCiAgaWYoc3RyaW5ncChjbWQpKSB7CiAgIC8vIFJlZ2VsbiBlbnRkZWNrdCAtIFplcmxlZ2VuICh3aWUgQWRkQ21kKQogICBpZigoaT1tZW1iZXIoY21kLCcmJykpPjApIHsKICAgIGRlbHJ1bGU9ZXhwbG9kZShjbWRbKGkrMSkuLl0sIiYiKTsKICAgIGo9c2l6ZW9mKGRlbHJ1bGUpOwogICAgd2hpbGUoai0tKQogICAgIGRlbHJ1bGVbal09ZXhwbG9kZShkZWxydWxlW2pdLCJ8Iik7CiAgICBjbWQ9Y21kWzAuLihpLTEpXTsKICAgfQogICBjbWQ9ZXhwbG9kZShjbWQsInwiKTsKICB9IGVsc2UgaWYoZGVsX25vcnVsZSB8fCBvbmx5aWQpIGNtZD1tX2luZGljZXMoYWRkZWRfY21kcyk7CgogIGlmKCFwb2ludGVycChjbWQpKQogICByYWlzZV9lcnJvcigiUmVtb3ZlQ21kOiBtaXNzaW5nIHN0cmluZy9wb2ludGVyLXBhcmFtZXRlci5cbiIpOwogIGk9c2l6ZW9mKGNtZCk7CgogIHdoaWxlKGktLSkgewogICAvLyBrZWluZSBSZWdlbG4gZGEgdW5kIFJlZ2VsbiBsb2VzY2hlbiBlcmxhdWJ0OiBhbGxlcyBsb2VzY2hlbgogICBpZighZGVscnVsZSAmJiAhZGVsX25vcnVsZSAmJiAhb25seWlkKSBtX2RlbGV0ZShhZGRlZF9jbWRzLGNtZFtpXSk7CiAgIGVsc2UgaWYobV9jb250YWlucygmZnVuLCAmZmxhZywgJnJ1bGUsICZpZHMsICZjYWNoZWNsLCBhZGRlZF9jbWRzLCBjbWRbaV0pKSB7CiAgICBqPXNpemVvZihmdW4pOwogICAgd2hpbGUoai0tKSB7CiAgICAgaW50IGs7CiAgICAgLy8gREJHKHJ1bGVbal0pOwogICAgCS8vIFJlZ2VsbiBuaWNodCBs9nNjaGVuIHVuZCBSZWdlbD8KICAgICBpZighKGRlbF9ub3J1bGUgJiYgcG9pbnRlcnAocnVsZVtqXSkpICYmCiAgICAgICAgLy8gbnVyIGJlc3RpbW10ZSBJRCBs9nNjaGVuIHVuZCBJRCBwYXNzdCBuaWNodD8KICAgICAgICAhKG9ubHlpZCAmJiAoIXBvaW50ZXJwKGlkcykgfHwgc2l6ZW9mKGlkcyk8PWogfHwgaWRzW2pdIT1vbmx5aWQpKSAmJgogICAgICAgIC8vIEz2c2NocmVnZWwgZXhpc3RpZXJ0IHVuZCBwYXNzdCBuaWNodCBhdWYgUmVnZWw/CiAgICAgICAgIShkZWxydWxlICYmIChrPXNpemVvZihydWxlW2pdKSkhPXNpemVvZihkZWxydWxlKSkpIHsKICAgICAgLy8gcGFydGllbGxlcyBUZXN0ZW4gZWluZXIgTPZzY2hyZWdlbCAuLi4KICAgICAgaWYoZGVscnVsZSkgewogICAgICAgd2hpbGUoay0tKQogICAgICAgIGlmKCFzaXplb2YocnVsZVtqXVtrXSZkZWxydWxlW2tdKSkgYnJlYWs7CiAgICAgICBpZihrPj0wKSBjb250aW51ZTsKICAgICAgfQogICAgICAvLyBhbGxlcyBrb3JyZWt0OiBM9nNjaGVuIQogICAgICAvLyAoQXJyYXliZXJlaWNoIGR1cmNoIGxlZXJlcyBBcnJheSBsb2VzY2hlbikKICAgICAgZmxhZ1tqLi5qXSAgICA9IGFsbG9jYXRlKDApOwogICAgICBmdW5bai4ual0gICAgID0gYWxsb2NhdGUoMCk7CiAgICAgIHJ1bGVbai4ual0gICAgPSBhbGxvY2F0ZSgwKTsKICAgICAgY2FjaGVjbFtqLi5qXSA9IGFsbG9jYXRlKDApOwogICAgICBpZihpZHMpIHsKICAgICAgIGlkc1tqLi5qXSA9IGFsbG9jYXRlKDApOwogICAgICAgaWYoIXNpemVvZihpZHMtYWxsb2NhdGUoMSkpKSBpZHM9KG1peGVkKikwOwogICAgICB9CiAgICAgIHJldCsrOwogICAgIH0KICAgIH0gLy8gZW5kIHdoaWxlKGotLSkgewogICB9CiAgIC8vIEZ1bmt0aW9ucy9SZWdlbGxpc3RlIHVwZGF0ZSBvZGVyIGdnZi4gS29tbWFuZG8gdm9lbGxpZyBsb2VzY2hlbgogICBpZihzaXplb2YocnVsZSkpIHsKICAgIGFkZGVkX2NtZHNbY21kW2ldLCBDTURJRFhfRlVOXT1mdW47CiAgICBhZGRlZF9jbWRzW2NtZFtpXSwgQ01ESURYX0ZMQUddPWZsYWc7CiAgICBhZGRlZF9jbWRzW2NtZFtpXSwgQ01ESURYX1JVTEVdPXJ1bGU7CiAgICBhZGRlZF9jbWRzW2NtZFtpXSwgQ01ESURYX0lEXT1pZHM7CiAgICBhZGRlZF9jbWRzW2NtZFtpXSwgQ01ESURYX0NBQ0hFXT1jYWNoZWNsOwogICB9IGVsc2UgbV9kZWxldGUoYWRkZWRfY21kcyxjbWRbaV0pOwogIH0KICBpZighc2l6ZW9mKGFkZGVkX2NtZHMpKSBhZGRlZF9jbWRzPShtYXBwaW5nKTA7CiB9CiByZXR1cm4gcmV0Owp9CgovLyBBdXNmdWVocmVuIHNhbXQgZ2VwYXJzdGVtIElucHV0c3RyaW5nIHVuZCBnZXRyaWdnZXJ0ZW4gUGFyc2VyZXJnZWJuaXNzZW4Kc3RhdGljIGludCBfZXhlY3V0ZShtaXhlZCBmdW4sIHN0cmluZyBzdHIsIG1peGVkICpwYXJzZWQpIHsKICBzd2l0Y2godHlwZW9mKGZ1bikpIHsKICAgIGNhc2UgVF9DTE9TVVJFOgogICAgICByZXR1cm4gKChpbnQpZnVuY2FsbChmdW4sc3RyLCZwYXJzZWQpKTsKICAgIGNhc2UgVF9TVFJJTkc6CiAgICAgIGludCByZXQ7CiAgICAgIGlmKCFjYWxsX3Jlc29sdmVkKCZyZXQsIHRoaXNfb2JqZWN0KCksIGZ1biwgc3RyLCAmcGFyc2VkKSkKICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAogICAgICAgICAgIkFkZENtZDogU3RyaW5nLU1ldGhvZGUgJyVzJyBpbiBLb21tYW5kbyAlI08gc2NoZWludCB6dSBmZWhsZW4gIgogICAgICAgICAgIm9kZXIgbmljaHQgenVncmVpZmJhciB6dSBzZWluLlxuIiwgZnVuLCBwYXJzZWQpKTsKICAgICAgcmV0dXJuIHJldDsKICAgIGRlZmF1bHQ6CiAgICAgIGJyZWFrOwogIH0KICByZXR1cm4gMDsKfQoKI2RlZmluZSBDSEVDS19QUkVTRU5UICAgICAxCiNkZWZpbmUgQ0hFQ0tfSUQgICAgICAgICAgMgojZGVmaW5lIENIRUNLX1BVVEdFVE5PTkUgIDQKI2RlZmluZSBDSEVDS19QVVRHRVREUk9QICA4CiNkZWZpbmUgQ0hFQ0tfUFVUR0VUVEFLRSAgMTYKI2RlZmluZSBDSEVDS19QVVRHRVQgICAgICAoQ0hFQ0tfUFVUR0VUTk9ORXxDSEVDS19QVVRHRVREUk9QfENIRUNLX1BVVEdFVFRBS0UpCgovLyBXZXJ0IGZ1ZXIgRmVobHNjaGxhZywgRmFsbGJhY2stV2VydCBkZXIgYmVudXR6dGVuIHdoaWxlLS0gLSBTY2hsZWlmZW4KI2RlZmluZSBOT01BVENIRk9VTkQgICAgICAtMQoKLy8gUmVnZWxuIGZ1ZXIgZWluIChudW4gdW53aWNodGlnZXMpIFZlcmIgdHJpZ2dlcm4Kc3RhdGljIGludCBfcHJvY2Vzc19jb21tYW5kKHN0cmluZyBzdHIsIHN0cmluZyAqbm9wYXJzZXN0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1peGVkIGZ1biwgbWl4ZWQgZmxhZywgbWl4ZWQgcnVsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1peGVkIGlkLCBtaXhlZCBjYWNoZWRjbCkgewogbWl4ZWQgKnBhcnNlZCwgKm9iam1hdGNoZXM7CgogLy8gZWluZSBSZWdlbCAuLi4gYXVzd2VydGVuIC4uLgogaWYocG9pbnRlcnAocnVsZSkpIHsKICBpbnQgbnJ1bDsKICBwYXJzZWQ9b2JqbWF0Y2hlcz1hbGxvY2F0ZSgwKTsKICBpbnQgbGFzdG1hdGNocG9zPU5PTUFUQ0hGT1VORDsKCiAgLy8gQWJnbGVpY2hlbiBkZXIgZ2VzcGxpdHRldGVuIEVpbmdhYmUgbWl0IFJlZ2VsbjoKICAvLyB2b3J3YWVydHMgZHVyY2ggZGllIFN5bm9ueW1ncnVwcGVuCiAgaW50IHJzPXNpemVvZihydWxlKTsKICB3aGlsZShucnVsPHJzKSB7CiAgIGludCBtYXRjaHBvczsKICAgc3RyaW5nICpzeW5vbnltOwogICBtaXhlZCBtYXRjaHN0cjsKCiAgIG1hdGNocG9zPU5PTUFUQ0hGT1VORDsKICAgbWF0Y2hzdHI9MDsKCiAgIC8vIFN5bm9ueW1lIGV4dHJhaGllcmVuCiAgIGludCBucnN5bm9ueW1zPXNpemVvZihzeW5vbnltPXJ1bGVbbnJ1bF0pOwoKICAgLy8gZWdhbCB3aWUgZHVyY2ggU3lub255bWUgYmlzIE1hdGNoIC0gQWJnbGVpY2ggbWl0IEVpbmdhYmUKICAgd2hpbGUobnJzeW5vbnltcy0tKSB7CiAgICBpbnQgdG1wcG9zID0gbWVtYmVyKG5vcGFyc2VzdHIsc3lub255bVtucnN5bm9ueW1zXSk7CiAgICAvLyBpc3QgU3lub255bSBpbSBFaW5nYWJlc3RyaW5nIHVuZCBrb21tdCBzcGFldGVyIGFscyB2b3JoZXJpZ2VzIFN5bm9ueW0/CiAgICBpZih0bXBwb3M+PTAgJiYgdG1wcG9zPmxhc3RtYXRjaHBvcykgewogICAgIC8vIEVyZm9sZzogbWVya2VuIGRlciBQb3NpdGlvbiBpbSBFaW5nYWJlc3RyaW5nIHVuZCBkZW4gbWF0Y2hlbmRlbiBTdHJpbmcKICAgICBtYXRjaHBvcz10bXBwb3M7CiAgICAgbWF0Y2hzdHI9bm9wYXJzZXN0clt0bXBwb3NdOwogICAgIGJyZWFrOwogICAgfQogICB9CgogICAvLyBrZWluIE1hdGNoIGR1cmNoIFN5bm9ueW1lPyBQcnVlZmUgZGllIEAtU3BlemlhbHZhcmlhYmxlbi4KICAgaWYobWF0Y2hwb3MgPT0gTk9NQVRDSEZPVU5EKSB7CiAgICBpbnQgY2hlY2tfcHJlc2VudDsKICAgIC8vIGlzdCBBYnBydWVmZW4gdm9uIElEL1BSRVNFTlQgaW4gZGVyIFN5bm9ueW1ncnVwcGUgdmVybGFuZ3QKICAgIC8vIGJlaSBwcmVzZW50KCkvZmluZF9vYnMgZ2xlaWNoIFZvcmF1c3NldHp1bmcgZ3VlbHRpZ2VyIFRQIG1pdHBydWZlbgogICAgaWYobWVtYmVyKHN5bm9ueW0sIkBJRCIpPj0wKSBjaGVja19wcmVzZW50PUNIRUNLX0lEOwogICAgaWYodGhpc19wbGF5ZXIoKSkgewogICAgIGlmKG1lbWJlcihzeW5vbnltLCJAUFJFU0VOVCIpPj0wKSBjaGVja19wcmVzZW50fD1DSEVDS19QUkVTRU5UOwogICAgIGVsc2UgaWYobWVtYmVyKHN5bm9ueW0sIkBQVVRfR0VUX05PTkUiKT49MCkKCQljaGVja19wcmVzZW50fD1DSEVDS19QVVRHRVROT05FOwogICAgIGVsc2UgaWYobWVtYmVyKHN5bm9ueW0sIkBQVVRfR0VUX1RBS0UiKT49MCkKCQljaGVja19wcmVzZW50fD1DSEVDS19QVVRHRVREUk9QOwogICAgIGVsc2UgaWYobWVtYmVyKHN5bm9ueW0sIkBQVVRfR0VUX0RST1AiKT49MCkKCQljaGVja19wcmVzZW50fD1DSEVDS19QVVRHRVRUQUtFOwogICAgfQoKICAgIGlmKGNoZWNrX3ByZXNlbnQpIHsKICAgICAvLyB3aXIgZmFuZ2VuIGhpbnRlciBkZW0gbGV0enRlbiBNYXRjaCBhbgogICAgIGludCBxX3N0YXJ0PWxhc3RtYXRjaHBvcysxOwogICAgIGludCByX2VuZD1zaXplb2Yobm9wYXJzZXN0ciktMTsKCiAgICAgaW50IHJhbmdlOwogICAgIHdoaWxlKChyYW5nZT1yX2VuZC1xX3N0YXJ0KT49MCkgewogICAgICBtaXhlZCB0bXBvYmo7CgogICAgICAvLyB3aWUgd2VpdCB3b2xsZW4gd2lyIHp1cvxja2dlaGVuPwogICAgICBpZihyYW5nZSkKICAgICAgICBpZighKGNoZWNrX3ByZXNlbnQmQ0hFQ0tfUFVUR0VUKSkKICAgICAgICAgIHJhbmdlPXJhbmdlPjI/MjpyYW5nZTsgLy8gMyBGcmFnbWVudGUgZnVlciBASUQvQFBSRVNFTlQgKEFkdmVyYi9OcikKICAgICAgICBlbHNlIGlmKHJhbmdlPjQpCiAgICAgICAgICByYW5nZT00OyAgICAgICAgICAgICAgIC8vIDUgRnJhZ21lbnRlIGZ1ZXIgQFBVVF9YWFggCgogICAgICAvLyB1bmQgamV0enQgZGllIFN1YnN0cmluZ3MgcHJ1ZWZlbgogICAgICB3aGlsZShyYW5nZT49MCAmJiAhbWF0Y2hzdHIpIHsKICAgICAgIHN0cmluZyB0bXBzdHI7CgogICAgICAgLy8genUgcHJ1ZWZlbmRlbiBTdHJpbmcgYXVzIGRlbiBUZWlsZW4genVzYW1tZW5zZXR6ZW4KICAgICAgIGlmKHJhbmdlKSB0bXBzdHI9aW1wbG9kZShub3BhcnNlc3RyW3Ffc3RhcnQuLihxX3N0YXJ0K3JhbmdlKV0sIiAiKTsKICAgICAgIGVsc2UgdG1wc3RyPW5vcGFyc2VzdHJbcV9zdGFydF07CgogICAgICAgLy9EQkcodG1wc3RyKTsKICAgICAgIGlmKGNoZWNrX3ByZXNlbnQmQ0hFQ0tfUFJFU0VOVCAmJgkJCS8vIFBSRVNFTlQgPwogICAgICAgICAgKCh0bXBvYmo9cHJlc2VudCh0bXBzdHIsdGhpc19wbGF5ZXIoKSkpIHx8CiAgICAgICAgICAgKHRtcG9iaj1wcmVzZW50KHRtcHN0cixlbnZpcm9ubWVudCh0aGlzX3BsYXllcigpKSkpKSkKICAgICAgICBtYXRjaHN0cj10bXBvYmo7CiAgICAgICBlbHNlIGlmKGNoZWNrX3ByZXNlbnQmQ0hFQ0tfSUQgJiYgaWQodG1wc3RyKSkJLy8gSUQgPwogICAgICAgIG1hdGNoc3RyPXRoaXNfb2JqZWN0KCk7CiAgICAgICBlbHNlIGlmKChjaGVja19wcmVzZW50JkNIRUNLX1BVVEdFVCkgJiYJLy8gUFVUX0dFVF8/Pz8gPwogICAgICAgICAgICAgICAodG1wb2JqPShvYmplY3QqKQogICAgICAgICAgICAgICAgICB0aGlzX3BsYXllcigpLT5maW5kX29icyh0bXBzdHIsCiAgICAgICAgICAgICAgICAgICAgICAoW0NIRUNLX1BVVEdFVE5PTkU6UFVUX0dFVF9OT05FLAogICAgICAgICAgICAgICAgICAgICAgICBDSEVDS19QVVRHRVREUk9QOlBVVF9HRVRfVEFLRSwKICAgICAgICAgICAgICAgICAgICAgICAgQ0hFQ0tfUFVUR0VUVEFLRTpQVVRfR0VUX0RST1BdKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW0NIRUNLX1BVVEdFVCZjaGVja19wcmVzZW50XSkpICYmCiAgICAgICAgICAgICAgIHNpemVvZih0bXBvYmopKSB7CiAgICAgICAgaWYoc2l6ZW9mKHRtcG9iaik9PTEpIG1hdGNoc3RyPXRtcG9ialswXTsKICAgICAgICBlbHNlIHsJLy8gQXJyYXlzIHdlcmRlbiB6d2lzY2hlbmdlc3BlaWNoZXJ0IC4uLgogICAgICAgICBvYmptYXRjaGVzKz0oe3NpemVvZihwYXJzZWQpLHRtcG9ian0pOwogICAgICAgICBtYXRjaHN0cj10bXBzdHI7CiAgICAgICAgfQogICAgICAgfSBlbHNlIHsgLy8gZGllc2VyIFN1YnN0cmluZyBoYXQgbmljaHQgZ2VtYXRjaHQKICAgICAgICAvLyBhYiB3ZW5pZ2VyIGFscyAzIFRlaWxlbiBpc3QgZGFzIE5pY2h0bWF0Y2hpbmcgZWluZXMgU3Vic3RyaW5ncyBtaXQKICAgICAgICAvLyBiZWVuZGVuZGVtIE51bWVyYWwgS3JpdGVyaXVtIGZ1ZXIgQWJicnVjaCAoIm9iamVrdCAyIiBzb2xsIG1hdGNoZW4pCiAgICAgICAgc3RyaW5nIG51bWVyYWxjaGVjazsKICAgICAgICBpZihyYW5nZSAmJiByYW5nZTw9MiAmJgogICAgICAgICAgIHNpemVvZihudW1lcmFsY2hlY2s9bm9wYXJzZXN0cltxX3N0YXJ0K3JhbmdlXSkgJiYKICAgICAgICAgICB0b19zdHJpbmcodG9faW50KG51bWVyYWxjaGVjaykpPT1udW1lcmFsY2hlY2spCiAgICAgICAgICBicmVhazsKCiAgICAgICAgLy8gU3Vic3RyaW5nbGFlbmdlIHZlcmt1ZXJ6ZW4gdW5kIHdlaXRlcgogICAgICAgIHJhbmdlLS07CiAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIE1hdGNoIGdlZnVuZGVuIQogICAgICBpZihtYXRjaHN0cikgewogICAgICAgbWF0Y2hwb3M9cmFuZ2UrcV9zdGFydDsKICAgICAgIC8vIERCRyhtYXRjaHBvcyk7CiAgICAgICBicmVhazsKICAgICAgfQogICAgICBxX3N0YXJ0Kys7CiAgICAgfSAvLyBlbmQgd2hpbGUKICAgIH0KICAgfQoKICAgLy8gRmVobGVybWVsZHVuZyBmdWVyIGRpZXNlIGZlaGxnZXNjaGxhZ2VuZSBTeW5vbnltZ3J1cHBlIHNldHplbgogICBpZihtYXRjaHBvcyA9PSBOT01BVENIRk9VTkQpIHsKICAgIC8vIEZlaGxlcm1lbGR1bmdlbiB1bmQgZWluIEVpbnRyYWcgYW4gZGVyIEZlaGxlcnN0ZWxsZT8KICAgIGlmKHBvaW50ZXJwKGZsYWcpICYmIHNpemVvZihmbGFnKT5ucnVsKSB7CgogICAgIG1hdGNoc3RyPWZsYWdbbnJ1bF07CgogICAgIGlmKHN0cmluZ3AobWF0Y2hzdHIpICYmIHNpemVvZihtYXRjaHN0cikpIHsKICAgICAgaWYobWVtYmVyKG1hdGNoc3RyLCdAJyk+PTApIHsKICAgICAgIG1hdGNoc3RyPXJlcGxhY2VfcGVyc29uYWwoJm1hdGNoc3RyLCh7dGhpc19wbGF5ZXIoKX0pK3BhcnNlZCwxKTsKICAgICAgIHN0cmluZyBzdGFtbT0oKHF1ZXJ5X3ZlcmIoKVs8MV1eJ2UnKT9xdWVyeV92ZXJiKCk6cXVlcnlfdmVyYigpWzAuLjwyXSk7CiAgICAgICBtYXRjaHN0cj1yZWdyZXBsYWNlKG1hdGNoc3RyLCJAVkVSQiIsY2FwaXRhbGl6ZShzdGFtbSksMSk7CiAgICAgICBtYXRjaHN0cj1yZWdyZXBsYWNlKG1hdGNoc3RyLCJAdmVyYiIsc3RhbW0sMSk7CiAgICAgIH0KCiAgICAgIC8vIGlzdCBGZWhsZXJtZWxkdW5nIGVpbiBXUklURT8KICAgICAgLy8gZGFubiByZXR1cm4gMSAhCiAgICAgIGlmKGludHAoZmxhZ1s8MV0pICYmIGZsYWdbPDFdPD1ucnVsKSB7CiAgICAgICBpZihtZW1iZXIobWF0Y2hzdHIsJ14nKT49MCkgewogICAgICAgIG1hdGNoc3RyPWV4cGxvZGUobWF0Y2hzdHIsIl4iKTsKICAgICAgICB3cml0ZShjYXBpdGFsaXplKGJyZWFrX3N0cmluZyhtYXRjaHN0clswXSw3OCwwLDEpKSk7CiAgICAgICAgaWYoc2l6ZW9mKG1hdGNoc3RyWzFdKSkKICAgICAgICAgc2F5KGNhcGl0YWxpemUoYnJlYWtfc3RyaW5nKG1hdGNoc3RyWzFdLDc4LDAsMSkpLCh7dGhpc19wbGF5ZXIoKX0pICk7CiAgICAgICB9IGVsc2Ugd3JpdGUoY2FwaXRhbGl6ZShicmVha19zdHJpbmcobWF0Y2hzdHIsNzgsMCwxKSkpOwogICAgICAgcmV0dXJuIDE7CiAgICAgIH0gZWxzZSBub3RpZnlfZmFpbChjYXBpdGFsaXplKGJyZWFrX3N0cmluZyhtYXRjaHN0ciw3OCwwLDEpKSk7CiAgICAgfQogICAgfQogICAgcmV0dXJuIDA7CiAgIH0KCiAgIC8vIFVwZGF0ZW4gZGVyIEhpbGZzdmFyaWFibGVuCiAgIHBhcnNlZCs9KHttYXRjaHN0cn0pOwogICBsYXN0bWF0Y2hwb3M9bWF0Y2hwb3M7CiAgIG5ydWwrKzsKICB9IC8vIGVuZCB3aGlsZShucnVsPHJzKSAuLi4gRXJmb2xnIC4uLiBhYiB6dW0gbmFlY2hzdGVuIFJlZ2VsdGVpbAogfQoKIC8vIEFycmF5cyBkZXIgQC1PYmplY3RtYXRjaGVzIGluIFBhcmFtZXRlciBmdWVyIE1ldGhvZGUgcmVzdWJzdGl0dWllcmVuCiBpbnQgb2Jqc2l6ZTsKIGlmKChvYmpzaXplPXNpemVvZihvYmptYXRjaGVzKSkpCiAgd2hpbGUoKG9ianNpemUtPTIpPj0wKQogICBwYXJzZWRbb2JqbWF0Y2hlc1tvYmpzaXplXV09b2JqbWF0Y2hlc1tvYmpzaXplKzFdOwoKIC8vIGVyZm9sZ3JlaWNoIE1ldGhvZGUgZ2VmdW5kZW4vZWluZSBSZWdlbCBiaXMgenVtIEVuZGUgZHVyY2hnZXBhcnN0OgogcmV0dXJuKF9leGVjdXRlKGNhY2hlZGNsfHxmdW4sIHN0ciwgJnBhcnNlZCkpOwp9CgovLyBBdXN3ZXJ0dW5nIC0gYWRkX2FjdGlvbi1GdW4gCnB1YmxpYyBpbnQgX2NsKHN0cmluZyBzdHIpIHsKIGludCBuaW5kZXg7CiBzdHJpbmcgKmtleXM7CiBtaXhlZCAqZmxhZzsKIC8vIFZlcmIgZXhpc3RpZXJ0LCBLb21tYW5kb3MgYXVjaCwgRWludHJhZyBmdWVyIFZlcmIgZ2VmdW5kZW4KIGlmKG1hcHBpbmdwKGFkZGVkX2NtZHMpICYmIHF1ZXJ5X3ZlcmIoKSkgewogIG1peGVkICpmdW4sICpydWxlLCAqaWRzLCAqY2FjaGVjbDsKCiAgLy8gaXN0IGRhcyBWZXJiIGVpbiBLZXkgaW0gS29tbWFuZG9tYXBwaW5nPwogIGlmKG1fY29udGFpbnMoJmZ1biwgJmZsYWcsICZydWxlLCAmaWRzLCAmY2FjaGVjbCwgYWRkZWRfY21kcywgcXVlcnlfdmVyYigpKSkgewogICBzdHJpbmcgKm5vcGFyc2VzdHI7CiAgIG5pbmRleD1zaXplb2YoZnVuKTsKICAgbm9wYXJzZXN0cj1leHBsb2RlKChzdHJ8fCIiKSwiICIpLSh7IiJ9KTsKICAgLy8gZGFubiBtYXRjaGUgdW5nZXBhcnN0ZW4gSW5wdXQgZ2VnZW4gZXR3YWlnZSBSZWdlbG4KICAgLy8gLS0gbmljaHQgYWVuZGVybjogbmV1ZSBLb21tYW5kb3Mgc29sbGVuIGFsdGUgInVlYmVyc2NocmVpYmVuIiBrb2VubmVuCiAgIHdoaWxlKG5pbmRleC0tKQogICB7CiAgICBtaXhlZCBjbWRfaWQgPSAocG9pbnRlcnAoaWRzKSAmJiBzaXplb2YoaWRzKT5uaW5kZXgpID8gaWRzW25pbmRleF0gOiAwOwogICAgaWYoX3Byb2Nlc3NfY29tbWFuZCgmc3RyLCBub3BhcnNlc3RyLCBmdW5bbmluZGV4XSwgZmxhZ1tuaW5kZXhdLAogICAgICAgICAgICAgICAgICAgICAgICBydWxlW25pbmRleF0sIGNtZF9pZCwgY2FjaGVjbFtuaW5kZXhdKSkgewogICAgICBHaXZlRVAoRVBfQ01ELCBxdWVyeV92ZXJiKCkpOwogICAgICByZXR1cm4gMTsKICAgIH0KICAgfQogIH0KCiAgLy8ga2VpbmUgUmVnZWwgcGFzc3RlLCB1bnNjaGFyZmUgQXVzd2VydHVuZyBhdWYgYWxsZQogIC8vIEFkZENtZHZlcmJlbiBhdXNkZWhuZW4KICBrZXlzPW1faW5kaWNlcyhhZGRlZF9jbWRzKTsKICBuaW5kZXg9c2l6ZW9mKGtleXMpOwogIHdoaWxlKG5pbmRleC0tKQogICBpZighc3Ryc3RyKHF1ZXJ5X3ZlcmIoKSxrZXlzW25pbmRleF0pICYmCiAgICAgIG1lbWJlcigoZmxhZz1hZGRlZF9jbWRzW2tleXNbbmluZGV4XSwgQ01ESURYX0ZMQUddKSwxKT49MCkgewogICAgaW50IGkscmV0OwogICAgaT1zaXplb2YoZmxhZyk7CiAgICAvLyBSZWloZW5mb2xnZSBuaWNodCBhZW5kZXJuICEKICAgIHdoaWxlKGktLSkKICAgICAgaWYoZmxhZ1tpXT09MSkgewogICAgICAgIG1peGVkICpmdXp6eWZ1bnMgICA9IGFkZGVkX2NtZHNba2V5c1tuaW5kZXhdLCBDTURJRFhfRlVOXTsKICAgICAgICBtaXhlZCAqZnV6enljYWNoZSAgPSBhZGRlZF9jbWRzW2tleXNbbmluZGV4XSwgQ01ESURYX0NBQ0hFXTsKICAgICAgICBpZighcG9pbnRlcnAoZnV6enlmdW5zKSB8fCBzaXplb2YoZnV6enlmdW5zKTw9aSkKICAgICAgICAgIGNhdGNoKHJhaXNlX2Vycm9yKAogICAgICAgICAgICAiQWRkQ21kLUF1c3dlcnR1bmc6IENhdGNoQWxsLUtvbW1hbmRvIFwiIitrZXlzW25pbmRleF0rIlwiIgogICAgICAgICAgICAiIHd1cmRlIHdhZWhyZW5kIGRlciBBdXNmdWVocnVuZyB2ZXJhZW5kZXJ0IG9kZXIgZ2Vsb2VzY2h0LiAiCiAgICAgICAgICAgICJLbGFydGV4dDogRGFzIGlzdCBzY2hsZWNodC4gU3VjaHQgZWluIFJlbW92ZUNtZD8gIik7CiAgICAgICAgICAgIHB1Ymxpc2gpOwogICAgICAgIGVsc2UgaWYoX2V4ZWN1dGUoZnV6enljYWNoZVtpXXx8ZnV6enlmdW5zW2ldLCBzdHIsIDApKSB7CiAgICAgICAgICBHaXZlRVAoRVBfQ01ELCBxdWVyeV92ZXJiKCkpOwogICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgICB9CiAgIH0KIH0KIHJldHVybiAwOwp9Cgp2b2lkIGluaXQoKSB7CiBhZGRfYWN0aW9uKCJfY2wiLCIiLDEpOwp9CgoKcHJpdmF0ZSB2b2lkIF9jaGVja19pbXBvcnRlbnRyeShzdHJpbmcgaW5kLCBtaXhlZCAqZnVuLCBtaXhlZCAqZmxhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaXhlZCAqcnVsZSwgaW50fG1peGVkIGlkLCBtaXhlZCAqY2FjaGVkY2wpIHsKICAvLyBDaGVjayBkZXIgU3RyaW5nbWV0aG9kZW46IEZlaGxlciB3ZXJkZW4gYWJnZWZhbmdlbiwgdW0gZ2VuZXJlbGxlcwogIC8vIEtvcGllcmVuIHp1IGVybW9lZ2xpY2hlbi4gRXMga29lbm5lbiBhYmVyIEtvbW1hbmRvbWV0aG9kZW4gdmVybG9yZW4gZ2VoZW4uCiAgY2FjaGVkY2wgPSBtYXAoZnVuLCBmdW5jdGlvbiBpbnR8Y2xvc3VyZShzdHJpbmcgY2xmdW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2xvc3VyZSByZXQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoKHJldD1fY2hlY2tfc3RyaW5nbWV0aG9kKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGZ1biwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIldhcm51bmcgU2V0UHJvcChQX0NPTU1BTkRTKTogIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2gpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgICAgICAgICAgICAgfSk7CiAgaWYoc2l6ZW9mKGZ1bikhPXNpemVvZihmbGFnKSB8fCBzaXplb2YoZnVuKSE9c2l6ZW9mKHJ1bGUpKQogICAgcmFpc2VfZXJyb3IoIlNldFByb3AoUF9DT01NQU5EUyk6IGNvcnJ1cHQgY29tbWFuZHMtbWFwcGluZy5cbiIpOwp9Cgpwcml2YXRlIHZvaWQgX2NsZWFudXBfZXhwb3J0Y2woc3RyaW5nIGluZCwgbWl4ZWQgKmZ1biwgbWl4ZWQgKmZsYWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaXhlZCAqcnVsZSwgaW50fG1peGVkIGlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWl4ZWQgKmNhY2hlZGNsKSB7CiAgY2FjaGVkY2wgPSBhbGxvY2F0ZShzaXplb2YoZnVuKSk7Cn0KCnN0YXRpYyBtYXBwaW5nIF9xdWVyeV9jb21tYW5kcygpIHsKICBtYXBwaW5nIHJldDsKICBpZihtYXBwaW5ncChhZGRlZF9jbWRzKSkgewogICAgcmV0ID0gZGVlcF9jb3B5KGFkZGVkX2NtZHMpOwogICAgLy8gQ2xvc3VyZXMgaW0gQ2FjaGUgd2VyZGVuIGltbWVyIGdlbG9lc2NodCwgZGEgc29uc3QgdmVyc2VoZW50bGljaAogICAgLy8gZG9jaCBleHBvcnRpZXJ0IHdlcmRlbiBrb2VubnRlCiAgICB3YWxrX21hcHBpbmcocmV0LCAjJ19jbGVhbnVwX2V4cG9ydGNsKTsKICB9CiAgcmV0dXJuIHJldDsKfQoKc3RhdGljIG1hcHBpbmcgX3NldF9jb21tYW5kcyhtYXBwaW5nIGNvbW1hbmRzKSB7CiAgaWYoIWNvbW1hbmRzKSBhZGRlZF9jbWRzPShtYXBwaW5nKTA7CiAgZWxzZSBpZihtYXBwaW5ncChjb21tYW5kcykpIHsKICAgIGlmKHdpZHRob2YoY29tbWFuZHMpICE9IENNRFNfV0lEVEgpCiAgICAgIHJhaXNlX2Vycm9yKCJTZXRQcm9wKFBfQ09NTUFORFMpOiBjb3JydXB0IGNvbW1hbmRzLW1hcHBpbmcuXG4iKTsKICAgIG1hcHBpbmcgdG1wID0gZGVlcF9jb3B5KGNvbW1hbmRzKTsKICAgIHdhbGtfbWFwcGluZyh0bXAsICMnX2NoZWNrX2ltcG9ydGVudHJ5KTsKICAgIGFkZGVkX2NvbW1hbmRzID0gdG1wOwogIH0KICByZXR1cm4gX3F1ZXJ5X2NvbW1hbmRzKCk7Cn0K