CiMgcmVncmVzc2lvbiB0ZXN0IGZvciBTQVggMi4wCiMgJElkJAoKZnJvbSB4bWwuc2F4LnNheHV0aWxzIGltcG9ydCBYTUxHZW5lcmF0b3IsIGVzY2FwZSwgWE1MRmlsdGVyQmFzZQpmcm9tIHhtbC5zYXguZXhwYXRyZWFkZXIgaW1wb3J0IGNyZWF0ZV9wYXJzZXIKZnJvbSB4bWwuc2F4LnhtbHJlYWRlciBpbXBvcnQgQXR0cmlidXRlc0ltcGwsIEF0dHJpYnV0ZXNOU0ltcGwKZnJvbSB4bWwuc2F4LmhhbmRsZXIgaW1wb3J0IENvbnRlbnRIYW5kbGVyCmZyb20gY1N0cmluZ0lPIGltcG9ydCBTdHJpbmdJTwpmcm9tIHRlc3Rfc3VwcG9ydCBpbXBvcnQgdmVyYm9zZSwgVGVzdEZhaWxlZAoKIyA9PT09PSBVdGlsaXRpZXMKCnRlc3RzID0gMApmYWlscyA9IDAKCmRlZiBjb25maXJtKG91dGNvbWUsIG5hbWUpOgogICAgZ2xvYmFsIHRlc3RzLCBmYWlscwoKICAgIHRlc3RzID0gdGVzdHMgKyAxCiAgICBpZiBvdXRjb21lOgogICAgICAgIHByaW50ICJQYXNzZWQiLCBuYW1lCiAgICBlbHNlOgogICAgICAgIHByaW50ICJGYWlsZWQiLCBuYW1lCiAgICAgICAgZmFpbHMgPSBmYWlscyArIDEKCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiMKIyAgIHNheHV0aWxzIHRlc3RzCiMKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiMgPT09PT0gZXNjYXBlCgpkZWYgdGVzdF9lc2NhcGVfYmFzaWMoKToKICAgIHJldHVybiBlc2NhcGUoIkRvbmFsZCBEdWNrICYgQ28iKSA9PSAiRG9uYWxkIER1Y2sgJmFtcDsgQ28iCgpkZWYgdGVzdF9lc2NhcGVfYWxsKCk6CiAgICByZXR1cm4gZXNjYXBlKCI8RG9uYWxkIER1Y2sgJiBDbz4iKSA9PSAiJmx0O0RvbmFsZCBEdWNrICZhbXA7IENvJmd0OyIKCmRlZiB0ZXN0X2VzY2FwZV9leHRyYSgpOgogICAgcmV0dXJuIGVzY2FwZSgiSGVpIHDlIGRlZyIsIHsi5SIgOiAiJmFyaW5nOyJ9KSA9PSAiSGVpIHAmYXJpbmc7IGRlZyIKCiMgPT09PT0gWE1MR2VuZXJhdG9yCgpzdGFydCA9ICc8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJpc28tODg1OS0xIj8+XG4nCgpkZWYgdGVzdF94bWxnZW5fYmFzaWMoKToKICAgIHJlc3VsdCA9IFN0cmluZ0lPKCkKICAgIGdlbiA9IFhNTEdlbmVyYXRvcihyZXN1bHQpCiAgICBnZW4uc3RhcnREb2N1bWVudCgpCiAgICBnZW4uc3RhcnRFbGVtZW50KCJkb2MiLCB7fSkKICAgIGdlbi5lbmRFbGVtZW50KCJkb2MiKQogICAgZ2VuLmVuZERvY3VtZW50KCkKCiAgICByZXR1cm4gcmVzdWx0LmdldHZhbHVlKCkgPT0gc3RhcnQgKyAiPGRvYz48L2RvYz4iCgpkZWYgdGVzdF94bWxnZW5fY29udGVudCgpOgogICAgcmVzdWx0ID0gU3RyaW5nSU8oKQogICAgZ2VuID0gWE1MR2VuZXJhdG9yKHJlc3VsdCkKICAgIAogICAgZ2VuLnN0YXJ0RG9jdW1lbnQoKQogICAgZ2VuLnN0YXJ0RWxlbWVudCgiZG9jIiwge30pCiAgICBnZW4uY2hhcmFjdGVycygiaHVoZWkiKQogICAgZ2VuLmVuZEVsZW1lbnQoImRvYyIpCiAgICBnZW4uZW5kRG9jdW1lbnQoKQoKICAgIHJldHVybiByZXN1bHQuZ2V0dmFsdWUoKSA9PSBzdGFydCArICI8ZG9jPmh1aGVpPC9kb2M+IgoKZGVmIHRlc3RfeG1sZ2VuX3BpKCk6CiAgICByZXN1bHQgPSBTdHJpbmdJTygpCiAgICBnZW4gPSBYTUxHZW5lcmF0b3IocmVzdWx0KQogICAgCiAgICBnZW4uc3RhcnREb2N1bWVudCgpCiAgICBnZW4ucHJvY2Vzc2luZ0luc3RydWN0aW9uKCJ0ZXN0IiwgImRhdGEiKQogICAgZ2VuLnN0YXJ0RWxlbWVudCgiZG9jIiwge30pCiAgICBnZW4uZW5kRWxlbWVudCgiZG9jIikKICAgIGdlbi5lbmREb2N1bWVudCgpCgogICAgcmV0dXJuIHJlc3VsdC5nZXR2YWx1ZSgpID09IHN0YXJ0ICsgIjw/dGVzdCBkYXRhPz48ZG9jPjwvZG9jPiIKCmRlZiB0ZXN0X3htbGdlbl9jb250ZW50X2VzY2FwZSgpOgogICAgcmVzdWx0ID0gU3RyaW5nSU8oKQogICAgZ2VuID0gWE1MR2VuZXJhdG9yKHJlc3VsdCkKICAgIAogICAgZ2VuLnN0YXJ0RG9jdW1lbnQoKQogICAgZ2VuLnN0YXJ0RWxlbWVudCgiZG9jIiwge30pCiAgICBnZW4uY2hhcmFjdGVycygiPGh1aGVpJiIpCiAgICBnZW4uZW5kRWxlbWVudCgiZG9jIikKICAgIGdlbi5lbmREb2N1bWVudCgpCgogICAgcmV0dXJuIHJlc3VsdC5nZXR2YWx1ZSgpID09IHN0YXJ0ICsgIjxkb2M+Jmx0O2h1aGVpJmFtcDs8L2RvYz4iCgpkZWYgdGVzdF94bWxnZW5faWdub3JhYmxlKCk6CiAgICByZXN1bHQgPSBTdHJpbmdJTygpCiAgICBnZW4gPSBYTUxHZW5lcmF0b3IocmVzdWx0KQogICAgCiAgICBnZW4uc3RhcnREb2N1bWVudCgpCiAgICBnZW4uc3RhcnRFbGVtZW50KCJkb2MiLCB7fSkKICAgIGdlbi5pZ25vcmFibGVXaGl0ZXNwYWNlKCIgIikKICAgIGdlbi5lbmRFbGVtZW50KCJkb2MiKQogICAgZ2VuLmVuZERvY3VtZW50KCkKCiAgICByZXR1cm4gcmVzdWx0LmdldHZhbHVlKCkgPT0gc3RhcnQgKyAiPGRvYz4gPC9kb2M+IgoKbnNfdXJpID0gImh0dHA6Ly93d3cucHl0aG9uLm9yZy94bWwtbnMvc2F4dGVzdC8iCgpkZWYgdGVzdF94bWxnZW5fbnMoKToKICAgIHJlc3VsdCA9IFN0cmluZ0lPKCkKICAgIGdlbiA9IFhNTEdlbmVyYXRvcihyZXN1bHQpCiAgICAKICAgIGdlbi5zdGFydERvY3VtZW50KCkKICAgIGdlbi5zdGFydFByZWZpeE1hcHBpbmcoIm5zMSIsIG5zX3VyaSkKICAgIGdlbi5zdGFydEVsZW1lbnROUygobnNfdXJpLCAiZG9jIiksICJuczpkb2MiLCB7fSkKICAgIGdlbi5lbmRFbGVtZW50TlMoKG5zX3VyaSwgImRvYyIpLCAibnM6ZG9jIikKICAgIGdlbi5lbmRQcmVmaXhNYXBwaW5nKCJuczEiKQogICAgZ2VuLmVuZERvY3VtZW50KCkKCiAgICByZXR1cm4gcmVzdWx0LmdldHZhbHVlKCkgPT0gc3RhcnQgKyAoJzxuczE6ZG9jIHhtbG5zOm5zMT0iJXMiPjwvbnMxOmRvYz4nICUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuc191cmkpCgojID09PT09IFhNTEZpbHRlckJhc2UKCmRlZiB0ZXN0X2ZpbHRlcl9iYXNpYygpOgogICAgcmVzdWx0ID0gU3RyaW5nSU8oKQogICAgZ2VuID0gWE1MR2VuZXJhdG9yKHJlc3VsdCkKICAgIGZpbHRlciA9IFhNTEZpbHRlckJhc2UoKQogICAgZmlsdGVyLnNldENvbnRlbnRIYW5kbGVyKGdlbikKICAgIAogICAgZmlsdGVyLnN0YXJ0RG9jdW1lbnQoKQogICAgZmlsdGVyLnN0YXJ0RWxlbWVudCgiZG9jIiwge30pCiAgICBmaWx0ZXIuY2hhcmFjdGVycygiY29udGVudCIpCiAgICBmaWx0ZXIuaWdub3JhYmxlV2hpdGVzcGFjZSgiICIpCiAgICBmaWx0ZXIuZW5kRWxlbWVudCgiZG9jIikKICAgIGZpbHRlci5lbmREb2N1bWVudCgpCgogICAgcmV0dXJuIHJlc3VsdC5nZXR2YWx1ZSgpID09IHN0YXJ0ICsgIjxkb2M+Y29udGVudCA8L2RvYz4iCgojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQojCiMgICBleHBhdHJlYWRlciB0ZXN0cwojCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojID09PT09IERUREhhbmRsZXIgc3VwcG9ydAoKY2xhc3MgVGVzdERUREhhbmRsZXI6CgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHNlbGYuX25vdGF0aW9ucyA9IFtdCiAgICAgICAgc2VsZi5fZW50aXRpZXMgID0gW10KICAgIAogICAgZGVmIG5vdGF0aW9uRGVjbChzZWxmLCBuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOgogICAgICAgIHNlbGYuX25vdGF0aW9ucy5hcHBlbmQoKG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCkpCgogICAgZGVmIHVucGFyc2VkRW50aXR5RGVjbChzZWxmLCBuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQsIG5kYXRhKToKICAgICAgICBzZWxmLl9lbnRpdGllcy5hcHBlbmQoKG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCwgbmRhdGEpKQoKIyAgZGVmIHRlc3RfZXhwYXRfZHRkaGFuZGxlcigpOgojICAgICAgcGFyc2VyID0gY3JlYXRlX3BhcnNlcigpCiMgICAgICBoYW5kbGVyID0gVGVzdERUREhhbmRsZXIoKQojICAgICAgcGFyc2VyLnNldERUREhhbmRsZXIoaGFuZGxlcikKCiMgICAgICBwYXJzZXIuZmVlZCgnPCFET0NUWVBFIGRvYyBbXG4nKQojICAgICAgcGFyc2VyLmZlZWQoJyAgPCFFTlRJVFkgaW1nIFNZU1RFTSAiZXhwYXQuZ2lmIiBOREFUQSBHSUY+XG4nKQojICAgICAgcGFyc2VyLmZlZWQoJyAgPCFOT1RBVElPTiBHSUYgUFVCTElDICItLy9Db21wdVNlcnZlLy9OT1RBVElPTiBHcmFwaGljcyBJbnRlcmNoYW5nZSBGb3JtYXQgODlhLy9FTiI+XG4nKQojICAgICAgcGFyc2VyLmZlZWQoJ10+XG4nKQojICAgICAgcGFyc2VyLmZlZWQoJzxkb2M+PC9kb2M+JykKIyAgICAgIHBhcnNlci5jbG9zZSgpCgojICAgICAgcmV0dXJuIGhhbmRsZXIuX25vdGF0aW9ucyA9PSBbKCJHSUYiLCAiLS8vQ29tcHVTZXJ2ZS8vTk9UQVRJT04gR3JhcGhpY3MgSW50ZXJjaGFuZ2UgRm9ybWF0IDg5YS8vRU4iLCBOb25lKV0gYW5kIFwKIyAgICAgICAgICAgICBoYW5kbGVyLl9lbnRpdGllcyA9PSBbKCJpbWciLCBOb25lLCAiZXhwYXQuZ2lmIiwgIkdJRiIpXQoKIyA9PT09PSBFbnRpdHlSZXNvbHZlciBzdXBwb3J0CgojIGNhbid0IHRlc3QgdGhpcyB1bnRpbCBJbnB1dFNvdXJjZSBpcyBpbiBwbGFjZQoKIyA9PT09PSBBdHRyaWJ1dGVzIHN1cHBvcnQKCmNsYXNzIEF0dHJHYXRoZXJlcihDb250ZW50SGFuZGxlcik6CgogICAgZGVmIHN0YXJ0RWxlbWVudChzZWxmLCBuYW1lLCBhdHRycyk6CiAgICAgICAgc2VsZi5fYXR0cnMgPSBhdHRycwoKICAgIGRlZiBzdGFydEVsZW1lbnROUyhzZWxmLCBuYW1lLCBxbmFtZSwgYXR0cnMpOgogICAgICAgIHNlbGYuX2F0dHJzID0gYXR0cnMKICAgICAgICAKZGVmIHRlc3RfZXhwYXRfYXR0cnNfZW1wdHkoKToKICAgIHBhcnNlciA9IGNyZWF0ZV9wYXJzZXIoKQogICAgZ2F0aGVyID0gQXR0ckdhdGhlcmVyKCkKICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcihnYXRoZXIpCgogICAgcGFyc2VyLmZlZWQoIjxkb2MvPiIpCiAgICBwYXJzZXIuY2xvc2UoKQoKICAgIHJldHVybiB2ZXJpZnlfZW1wdHlfYXR0cnMoZ2F0aGVyLl9hdHRycykKCmRlZiB0ZXN0X2V4cGF0X2F0dHJzX3dhdHRyKCk6CiAgICBwYXJzZXIgPSBjcmVhdGVfcGFyc2VyKCkKICAgIGdhdGhlciA9IEF0dHJHYXRoZXJlcigpCiAgICBwYXJzZXIuc2V0Q29udGVudEhhbmRsZXIoZ2F0aGVyKQoKICAgIHBhcnNlci5mZWVkKCI8ZG9jIGF0dHI9J3ZhbCcvPiIpCiAgICBwYXJzZXIuY2xvc2UoKQoKICAgIHJldHVybiB2ZXJpZnlfYXR0cnNfd2F0dHIoZ2F0aGVyLl9hdHRycykKCmRlZiB0ZXN0X2V4cGF0X25zYXR0cnNfZW1wdHkoKToKICAgIHBhcnNlciA9IGNyZWF0ZV9wYXJzZXIoMSkKICAgIGdhdGhlciA9IEF0dHJHYXRoZXJlcigpCiAgICBwYXJzZXIuc2V0Q29udGVudEhhbmRsZXIoZ2F0aGVyKQoKICAgIHBhcnNlci5mZWVkKCI8ZG9jLz4iKQogICAgcGFyc2VyLmNsb3NlKCkKCiAgICByZXR1cm4gdmVyaWZ5X2VtcHR5X25zYXR0cnMoZ2F0aGVyLl9hdHRycykKCmRlZiB0ZXN0X2V4cGF0X25zYXR0cnNfd2F0dHIoKToKICAgIHBhcnNlciA9IGNyZWF0ZV9wYXJzZXIoMSkKICAgIGdhdGhlciA9IEF0dHJHYXRoZXJlcigpCiAgICBwYXJzZXIuc2V0Q29udGVudEhhbmRsZXIoZ2F0aGVyKQoKICAgIHBhcnNlci5mZWVkKCI8ZG9jIHhtbG5zOm5zPSclcycgbnM6YXR0cj0ndmFsJy8+IiAlIG5zX3VyaSkKICAgIHBhcnNlci5jbG9zZSgpCgogICAgYXR0cnMgPSBnYXRoZXIuX2F0dHJzCiAgICAKICAgIHJldHVybiBhdHRycy5nZXRMZW5ndGgoKSA9PSAxIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0TmFtZXMoKSA9PSBbKG5zX3VyaSwgImF0dHIiKV0gYW5kIFwKICAgICAgICAgICBhdHRycy5nZXRRTmFtZXMoKSA9PSBbXSBhbmQgXAogICAgICAgICAgIGxlbihhdHRycykgPT0gMSBhbmQgXAogICAgICAgICAgIGF0dHJzLmhhc19rZXkoKG5zX3VyaSwgImF0dHIiKSkgYW5kIFwKICAgICAgICAgICBhdHRycy5rZXlzKCkgPT0gWyhuc191cmksICJhdHRyIildIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0KChuc191cmksICJhdHRyIikpID09ICJ2YWwiIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0KChuc191cmksICJhdHRyIiksIDI1KSA9PSAidmFsIiBhbmQgXAogICAgICAgICAgIGF0dHJzLml0ZW1zKCkgPT0gWygobnNfdXJpLCAiYXR0ciIpLCAidmFsIildIGFuZCBcCiAgICAgICAgICAgYXR0cnMudmFsdWVzKCkgPT0gWyJ2YWwiXSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldFZhbHVlKChuc191cmksICJhdHRyIikpID09ICJ2YWwiIGFuZCBcCiAgICAgICAgICAgYXR0cnNbKG5zX3VyaSwgImF0dHIiKV0gPT0gInZhbCIKCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiMKIyAgIHhtbHJlYWRlciB0ZXN0cwojCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojID09PT09IEF0dHJpYnV0ZXNJbXBsCgpkZWYgdmVyaWZ5X2VtcHR5X2F0dHJzKGF0dHJzKToKICAgIHRyeToKICAgICAgICBhdHRycy5nZXRWYWx1ZSgiYXR0ciIpCiAgICAgICAgZ3ZrID0gMAogICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgIGd2ayA9IDEKCiAgICB0cnk6CiAgICAgICAgYXR0cnMuZ2V0VmFsdWVCeVFOYW1lKCJhdHRyIikKICAgICAgICBndnFrID0gMAogICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgIGd2cWsgPSAxCgogICAgdHJ5OgogICAgICAgIGF0dHJzLmdldE5hbWVCeVFOYW1lKCJhdHRyIikKICAgICAgICBnbnFrID0gMAogICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgIGducWsgPSAxCgogICAgdHJ5OgogICAgICAgIGF0dHJzLmdldFFOYW1lQnlOYW1lKCJhdHRyIikKICAgICAgICBncW5rID0gMAogICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgIGdxbmsgPSAxCiAgICAgICAgCiAgICB0cnk6CiAgICAgICAgYXR0cnNbImF0dHIiXQogICAgICAgIGdpayA9IDAKICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICBnaWsgPSAxCiAgICAgICAgCiAgICByZXR1cm4gYXR0cnMuZ2V0TGVuZ3RoKCkgPT0gMCBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldE5hbWVzKCkgPT0gW10gYW5kIFwKICAgICAgICAgICBhdHRycy5nZXRRTmFtZXMoKSA9PSBbXSBhbmQgXAogICAgICAgICAgIGxlbihhdHRycykgPT0gMCBhbmQgXAogICAgICAgICAgIG5vdCBhdHRycy5oYXNfa2V5KCJhdHRyIikgYW5kIFwKICAgICAgICAgICBhdHRycy5rZXlzKCkgPT0gW10gYW5kIFwKICAgICAgICAgICBhdHRycy5nZXQoImF0dHJzIikgPT0gTm9uZSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldCgiYXR0cnMiLCAyNSkgPT0gMjUgYW5kIFwKICAgICAgICAgICBhdHRycy5pdGVtcygpID09IFtdIGFuZCBcCiAgICAgICAgICAgYXR0cnMudmFsdWVzKCkgPT0gW10gYW5kIFwKICAgICAgICAgICBndmsgYW5kIGd2cWsgYW5kIGducWsgYW5kIGdpayBhbmQgZ3FuawoKZGVmIHZlcmlmeV9hdHRyc193YXR0cihhdHRycyk6CiAgICByZXR1cm4gYXR0cnMuZ2V0TGVuZ3RoKCkgPT0gMSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldE5hbWVzKCkgPT0gWyJhdHRyIl0gYW5kIFwKICAgICAgICAgICBhdHRycy5nZXRRTmFtZXMoKSA9PSBbImF0dHIiXSBhbmQgXAogICAgICAgICAgIGxlbihhdHRycykgPT0gMSBhbmQgXAogICAgICAgICAgIGF0dHJzLmhhc19rZXkoImF0dHIiKSBhbmQgXAogICAgICAgICAgIGF0dHJzLmtleXMoKSA9PSBbImF0dHIiXSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldCgiYXR0ciIpID09ICJ2YWwiIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0KCJhdHRyIiwgMjUpID09ICJ2YWwiIGFuZCBcCiAgICAgICAgICAgYXR0cnMuaXRlbXMoKSA9PSBbKCJhdHRyIiwgInZhbCIpXSBhbmQgXAogICAgICAgICAgIGF0dHJzLnZhbHVlcygpID09IFsidmFsIl0gYW5kIFwKICAgICAgICAgICBhdHRycy5nZXRWYWx1ZSgiYXR0ciIpID09ICJ2YWwiIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0VmFsdWVCeVFOYW1lKCJhdHRyIikgPT0gInZhbCIgYW5kIFwKICAgICAgICAgICBhdHRycy5nZXROYW1lQnlRTmFtZSgiYXR0ciIpID09ICJhdHRyIiBhbmQgXAogICAgICAgICAgIGF0dHJzWyJhdHRyIl0gPT0gInZhbCIgYW5kIFwKICAgICAgICAgICBhdHRycy5nZXRRTmFtZUJ5TmFtZSgiYXR0ciIpID09ICJhdHRyIgoKZGVmIHRlc3RfYXR0cnNfZW1wdHkoKToKICAgIHJldHVybiB2ZXJpZnlfZW1wdHlfYXR0cnMoQXR0cmlidXRlc0ltcGwoe30pKQoKZGVmIHRlc3RfYXR0cnNfd2F0dHIoKToKICAgIHJldHVybiB2ZXJpZnlfYXR0cnNfd2F0dHIoQXR0cmlidXRlc0ltcGwoeyJhdHRyIiA6ICJ2YWwifSkpCgojID09PT09IEF0dHJpYnV0ZXNJbXBsCgpkZWYgdmVyaWZ5X2VtcHR5X25zYXR0cnMoYXR0cnMpOgogICAgdHJ5OgogICAgICAgIGF0dHJzLmdldFZhbHVlKChuc191cmksICJhdHRyIikpCiAgICAgICAgZ3ZrID0gMAogICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgIGd2ayA9IDEKCiAgICB0cnk6CiAgICAgICAgYXR0cnMuZ2V0VmFsdWVCeVFOYW1lKCJuczphdHRyIikKICAgICAgICBndnFrID0gMAogICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgIGd2cWsgPSAxCgogICAgdHJ5OgogICAgICAgIGF0dHJzLmdldE5hbWVCeVFOYW1lKCJuczphdHRyIikKICAgICAgICBnbnFrID0gMAogICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgIGducWsgPSAxCgogICAgdHJ5OgogICAgICAgIGF0dHJzLmdldFFOYW1lQnlOYW1lKChuc191cmksICJhdHRyIikpCiAgICAgICAgZ3FuayA9IDAKICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICBncW5rID0gMQogICAgICAgIAogICAgdHJ5OgogICAgICAgIGF0dHJzWyhuc191cmksICJhdHRyIildCiAgICAgICAgZ2lrID0gMAogICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgIGdpayA9IDEKICAgICAgICAKICAgIHJldHVybiBhdHRycy5nZXRMZW5ndGgoKSA9PSAwIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0TmFtZXMoKSA9PSBbXSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldFFOYW1lcygpID09IFtdIGFuZCBcCiAgICAgICAgICAgbGVuKGF0dHJzKSA9PSAwIGFuZCBcCiAgICAgICAgICAgbm90IGF0dHJzLmhhc19rZXkoKG5zX3VyaSwgImF0dHIiKSkgYW5kIFwKICAgICAgICAgICBhdHRycy5rZXlzKCkgPT0gW10gYW5kIFwKICAgICAgICAgICBhdHRycy5nZXQoKG5zX3VyaSwgImF0dHIiKSkgPT0gTm9uZSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldCgobnNfdXJpLCAiYXR0ciIpLCAyNSkgPT0gMjUgYW5kIFwKICAgICAgICAgICBhdHRycy5pdGVtcygpID09IFtdIGFuZCBcCiAgICAgICAgICAgYXR0cnMudmFsdWVzKCkgPT0gW10gYW5kIFwKICAgICAgICAgICBndmsgYW5kIGd2cWsgYW5kIGducWsgYW5kIGdpayBhbmQgZ3FuawoKZGVmIHRlc3RfbnNhdHRyc19lbXB0eSgpOgogICAgcmV0dXJuIHZlcmlmeV9lbXB0eV9uc2F0dHJzKEF0dHJpYnV0ZXNOU0ltcGwoe30sIHt9KSkKCmRlZiB0ZXN0X25zYXR0cnNfd2F0dHIoKToKICAgIGF0dHJzID0gQXR0cmlidXRlc05TSW1wbCh7KG5zX3VyaSwgImF0dHIiKSA6ICJ2YWwifSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7KG5zX3VyaSwgImF0dHIiKSA6ICJuczphdHRyIn0pCiAgICAKICAgIHJldHVybiBhdHRycy5nZXRMZW5ndGgoKSA9PSAxIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0TmFtZXMoKSA9PSBbKG5zX3VyaSwgImF0dHIiKV0gYW5kIFwKICAgICAgICAgICBhdHRycy5nZXRRTmFtZXMoKSA9PSBbIm5zOmF0dHIiXSBhbmQgXAogICAgICAgICAgIGxlbihhdHRycykgPT0gMSBhbmQgXAogICAgICAgICAgIGF0dHJzLmhhc19rZXkoKG5zX3VyaSwgImF0dHIiKSkgYW5kIFwKICAgICAgICAgICBhdHRycy5rZXlzKCkgPT0gWyhuc191cmksICJhdHRyIildIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0KChuc191cmksICJhdHRyIikpID09ICJ2YWwiIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0KChuc191cmksICJhdHRyIiksIDI1KSA9PSAidmFsIiBhbmQgXAogICAgICAgICAgIGF0dHJzLml0ZW1zKCkgPT0gWygobnNfdXJpLCAiYXR0ciIpLCAidmFsIildIGFuZCBcCiAgICAgICAgICAgYXR0cnMudmFsdWVzKCkgPT0gWyJ2YWwiXSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldFZhbHVlKChuc191cmksICJhdHRyIikpID09ICJ2YWwiIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0VmFsdWVCeVFOYW1lKCJuczphdHRyIikgPT0gInZhbCIgYW5kIFwKICAgICAgICAgICBhdHRycy5nZXROYW1lQnlRTmFtZSgibnM6YXR0ciIpID09IChuc191cmksICJhdHRyIikgYW5kIFwKICAgICAgICAgICBhdHRyc1sobnNfdXJpLCAiYXR0ciIpXSA9PSAidmFsIiBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldFFOYW1lQnlOYW1lKChuc191cmksICJhdHRyIikpID09ICJuczphdHRyIgogICAgICAgIAoKIyA9PT09PSBNYWluIHByb2dyYW0KCml0ZW1zID0gbG9jYWxzKCkuaXRlbXMoKQppdGVtcy5zb3J0KCkKZm9yIChuYW1lLCB2YWx1ZSkgaW4gaXRlbXM6CiAgICBpZiBuYW1lWyA6IDVdID09ICJ0ZXN0XyI6CiAgICAgICAgY29uZmlybSh2YWx1ZSgpLCBuYW1lKQoKcHJpbnQgIiVkIHRlc3RzLCAlZCBmYWlsdXJlcyIgJSAodGVzdHMsIGZhaWxzKQppZiBmYWlscyAhPSAwOgogICAgcmFpc2UgVGVzdEZhaWxlZCwgIiVkIG9mICVkIHRlc3RzIGZhaWxlZCIgJSAoZmFpbHMsIHRlc3RzKQo=