cGFja2FnZSBjb20uaWJtLmljdS5kZXYudGVzdC5ub3JtYWxpemVyOwoKaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CmltcG9ydCBqYXZhLmlvLkZpbGVSZWFkZXI7CmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLkJpdFNldDsKaW1wb3J0IGNvbS5pYm0uaWN1LmRldi50ZXN0Lio7CgovKioKICogQnVpbGRzIHRoZSBub3JtYWxpemF0aW9uIHRhYmxlcy4gVGhpcyBpcyBhIHNlcGFyYXRlIGNsYXNzIHNvIHRoYXQgaXQKICogY2FuIGJlIHVubG9hZGVkIG9uY2Ugbm90IG5lZWRlZC48YnI+CiAqIENvcHlyaWdodCCpIDE5OTgtMjAwMiBVbmljb2RlLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuPGJyPgogKiBUaGUgVW5pY29kZSBDb25zb3J0aXVtIG1ha2VzIG5vIGV4cHJlc3NlZCBvciBpbXBsaWVkIHdhcnJhbnR5IG9mIGFueQogKiBraW5kLCBhbmQgYXNzdW1lcyBubyBsaWFiaWxpdHkgZm9yIGVycm9ycyBvciBvbWlzc2lvbnMuCiAqIE5vIGxpYWJpbGl0eSBpcyBhc3N1bWVkIGZvciBpbmNpZGVudGFsIGFuZCBjb25zZXF1ZW50aWFsIGRhbWFnZXMKICogaW4gY29ubmVjdGlvbiB3aXRoIG9yIGFyaXNpbmcgb3V0IG9mIHRoZSB1c2Ugb2YgdGhlIGluZm9ybWF0aW9uIGhlcmUuCiAqIEBhdXRob3IgTWFyayBEYXZpcwogKiBVcGRhdGVzIGZvciBzdXBwbGVtZW50YXJ5IGNvZGUgcG9pbnRzOiAKICogVmxhZGltaXIgV2VpbnN0ZWluICYgTWFya3VzIFNjaGVyZXIKICovCmNsYXNzIE5vcm1hbGl6ZXJCdWlsZGVyIHsKICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgY29weXJpZ2h0ID0gIkNvcHlyaWdodCCpIDE5OTgtMTk5OSBVbmljb2RlLCBJbmMuIjsKICAgIAogICAgLyoqCiAgICAgKiBUZXN0aW5nIGZsYWdzCiAgICAgKi8KICAgIAogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBHRU5FUkFUSU5HID0gZmFsc2U7CiAgICAKICAgIC8qKgogICAgICogQ29uc3RhbnRzIGZvciB0aGUgZGF0YSBmaWxlIHZlcnNpb24gdG8gdXNlLgogICAgICovCiAgICAvKnN0YXRpYyBmaW5hbCBib29sZWFuIE5FV19WRVJTSU9OID0gdHJ1ZTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBESVIgPSAiRDpcXFVuaWNvZGVEYXRhXFwiICsgKE5FV19WRVJTSU9OID8gIldvcmtpbmdHcm91cHNcXCIgOiAiIik7CiAgICAKICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgVU5JREFUQV9WRVJTSU9OID0gTkVXX1ZFUlNJT04gPyAiMy4wLjBkMTIiIDogIjIuMS45IjsKICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVhDTFVTSU9OU19WRVJTSU9OID0gTkVXX1ZFUlNJT04gPyAiMWQ0IiA6ICIxIjsKICAgIAogICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVU5JQ09ERV9EQVRBID0gRElSICsgIlVuaWNvZGVEYXRhLSIgKyBVTklEQVRBX1ZFUlNJT04gKyAiLnR4dCI7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDT01QT1NJVElPTl9FWENMVVNJT05TID0gRElSICsgIkNvbXBvc2l0aW9uRXhjbHVzaW9ucy0iICsgRVhDTFVTSU9OU19WRVJTSU9OICsiLnR4dCI7CiAgICAqLwoKICAgIC8qKgogICAgICogQ2FsbGVkIGV4YWN0bHkgb25jZSBieSBOb3JtYWxpemVyRGF0YSB0byBidWlsZCB0aGUgc3RhdGljIGRhdGEKICAgICAqLwogICAgCiAgICBzdGF0aWMgTm9ybWFsaXplckRhdGEgYnVpbGQoYm9vbGVhbiBmdWxsRGF0YSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIEludEhhc2h0YWJsZSBjYW5vbmljYWxDbGFzcyA9IG5ldyBJbnRIYXNodGFibGUoMCk7CiAgICAgICAgICAgIEludFN0cmluZ0hhc2h0YWJsZSBkZWNvbXBvc2UgPSBuZXcgSW50U3RyaW5nSGFzaHRhYmxlKG51bGwpOwogICAgICAgICAgICBMb25nSGFzaHRhYmxlIGNvbXBvc2UgPSBuZXcgTG9uZ0hhc2h0YWJsZShOb3JtYWxpemVyRGF0YS5OT1RfQ09NUE9TSVRFKTsKICAgICAgICAgICAgQml0U2V0IGlzQ29tcGF0aWJpbGl0eSA9IG5ldyBCaXRTZXQoKTsKICAgICAgICAgICAgQml0U2V0IGlzRXhjbHVkZWQgPSBuZXcgQml0U2V0KCk7CiAgICAgICAgICAgIGlmIChmdWxsRGF0YSkgewogICAgICAgICAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oIkJ1aWxkaW5nIE5vcm1hbGl6ZXIgRGF0YSBmcm9tIGZpbGUuIik7CiAgICAgICAgICAgICAgICByZWFkRXhjbHVzaW9uTGlzdChpc0V4Y2x1ZGVkKTsKICAgICAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKGlzRXhjbHVkZWQuZ2V0KDB4MDBDMCkpOwogICAgICAgICAgICAgICAgYnVpbGREZWNvbXBvc2l0aW9uVGFibGVzKGNhbm9uaWNhbENsYXNzLCBkZWNvbXBvc2UsIGNvbXBvc2UsIAogICAgICAgICAgICAgICAgICBpc0NvbXBhdGliaWxpdHksIGlzRXhjbHVkZWQpOwogICAgICAgICAgICB9IGVsc2UgeyAgICAvLyBmb3IgdXNlIGluIEFwcGxldHMKICAgICAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJCdWlsZGluZyBhYnJpZGdlZCBkYXRhLiIpOwogICAgICAgICAgICAgICAgc2V0TWluaW1hbERlY29tcChjYW5vbmljYWxDbGFzcywgZGVjb21wb3NlLCBjb21wb3NlLCAKICAgICAgICAgICAgICAgICAgaXNDb21wYXRpYmlsaXR5LCBpc0V4Y2x1ZGVkKTsgCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ldyBOb3JtYWxpemVyRGF0YShjYW5vbmljYWxDbGFzcywgZGVjb21wb3NlLCBjb21wb3NlLCAKICAgICAgICAgICAgICAgICAgaXNDb21wYXRpYmlsaXR5LCBpc0V4Y2x1ZGVkKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJDYW4ndCBsb2FkIGRhdGEgZmlsZS4iICsgZSArICIsICIgKyBlLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgIH0KCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gQnVpbGRpbmcgRGVjb21wb3NpdGlvbiBUYWJsZXMKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICAgIC8qKgogICAgICogUmVhZHMgZXhjbHVzaW9uIGxpc3QgYW5kIHN0b3JlcyB0aGUgZGF0YQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHJlYWRFeGNsdXNpb25MaXN0KEJpdFNldCBpc0V4Y2x1ZGVkKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIlJlYWRpbmcgRXhjbHVzaW9ucyIpOwogICAgICAgIC8vQnVmZmVyZWRSZWFkZXIgaW4gPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IEZpbGVSZWFkZXIoQ09NUE9TSVRJT05fRVhDTFVTSU9OUyksIDUqMTAyNCk7CiAgICAgICAgQnVmZmVyZWRSZWFkZXIgaW4gPSBudWxsOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGluID0gVGVzdFV0aWwuZ2V0RGF0YVJlYWRlcigidW5pY29kZS9Db21wb3NpdGlvbkV4Y2x1c2lvbnMudHh0Iik7CiAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJGYWlsIHRvIHJlYWQgdGhlIGZpbGUgQ29tcG9zaXRpb25FeGNsdXNpb25zLnR4dCEiKTsKICAgICAgICAgICAgU3lzdGVtLmV4aXQoMSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyByZWFkIGEgbGluZSwgZGlzY2FyZGluZyBjb21tZW50cyBhbmQgYmxhbmsgbGluZXMKICAgICAgICAgICAgCiAgICAgICAgICAgIFN0cmluZyBsaW5lID0gaW4ucmVhZExpbmUoKTsKICAgICAgICAgICAgaWYgKGxpbmUgPT0gbnVsbCkgYnJlYWs7CiAgICAgICAgICAgIGludCBjb21tZW50ID0gbGluZS5pbmRleE9mKCcjJyk7ICAgICAgICAgICAgICAgICAgICAvLyBzdHJpcCBjb21tZW50cwogICAgICAgICAgICBpZiAoY29tbWVudCAhPSAtMSkgbGluZSA9IGxpbmUuc3Vic3RyaW5nKDAsY29tbWVudCk7CiAgICAgICAgICAgIGlmIChsaW5lLmxlbmd0aCgpID09IDApIGNvbnRpbnVlOyAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgYmxhbmtzCiAgICAgICAgICAgIGlmKGxpbmUuaW5kZXhPZignICcpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBsaW5lID0gbGluZS5zdWJzdHJpbmcoMCwgbGluZS5pbmRleE9mKCcgJykpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIHN0b3JlIC0xIGluIHRoZSBleGNsdWRlZCB0YWJsZSBmb3IgZWFjaCBjaGFyYWN0ZXIgaGl0CiAgICAgICAgICAgIAogICAgICAgICAgICBpbnQgdmFsdWUgPSBJbnRlZ2VyLnBhcnNlSW50KGxpbmUsMTYpOwogICAgICAgICAgICBpc0V4Y2x1ZGVkLnNldCh2YWx1ZSk7CiAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJFeGNsdWRpbmcgIiArIGhleCh2YWx1ZSkpOwogICAgICAgIH0KICAgICAgICBpbi5jbG9zZSgpOwogICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJEb25lIHJlYWRpbmcgRXhjbHVzaW9ucyIpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEJ1aWxkcyBhIGRlY29tcG9zaXRpb24gdGFibGUgZnJvbSBhIFVuaWNvZGVEYXRhIGZpbGUKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBidWlsZERlY29tcG9zaXRpb25UYWJsZXMoCiAgICAgIEludEhhc2h0YWJsZSBjYW5vbmljYWxDbGFzcywgSW50U3RyaW5nSGFzaHRhYmxlIGRlY29tcG9zZSwgCiAgICAgIExvbmdIYXNodGFibGUgY29tcG9zZSwgQml0U2V0IGlzQ29tcGF0aWJpbGl0eSwgQml0U2V0IGlzRXhjbHVkZWQpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiUmVhZGluZyBVbmljb2RlIENoYXJhY3RlciBEYXRhYmFzZSIpOwogICAgICAgIC8vQnVmZmVyZWRSZWFkZXIgaW4gPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IEZpbGVSZWFkZXIoVU5JQ09ERV9EQVRBKSwgNjQqMTAyNCk7CiAgICAgICAgQnVmZmVyZWRSZWFkZXIgaW4gPSBudWxsOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGluID0gVGVzdFV0aWwuZ2V0RGF0YVJlYWRlcigidW5pY29kZS9Vbmljb2RlRGF0YS50eHQiKTsKICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewogICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkZhaWxlZCB0byByZWFkIFVuaWNvZGVEYXRhLnR4dCIpOwogICAgICAgICAgICBTeXN0ZW0uZXhpdCgxKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaW50IHZhbHVlOwogICAgICAgIGxvbmcgcGFpcjsKICAgICAgICBpbnQgY291bnRlciA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIHJlYWQgYSBsaW5lLCBkaXNjYXJkaW5nIGNvbW1lbnRzIGFuZCBibGFuayBsaW5lcwogICAgICAgICAgICAKICAgICAgICAgICAgU3RyaW5nIGxpbmUgPSBpbi5yZWFkTGluZSgpOwogICAgICAgICAgICBpZiAobGluZSA9PSBudWxsKSBicmVhazsKICAgICAgICAgICAgaW50IGNvbW1lbnQgPSBsaW5lLmluZGV4T2YoJyMnKTsgICAgICAgICAgICAgICAgICAgIC8vIHN0cmlwIGNvbW1lbnRzCiAgICAgICAgICAgIGlmIChjb21tZW50ICE9IC0xKSBsaW5lID0gbGluZS5zdWJzdHJpbmcoMCxjb21tZW50KTsKICAgICAgICAgICAgaWYgKGxpbmUubGVuZ3RoKCkgPT0gMCkgY29udGludWU7CiAgICAgICAgICAgIGlmIChERUJVRykgewogICAgICAgICAgICAgICAgY291bnRlcisrOwogICAgICAgICAgICAgICAgaWYgKChjb3VudGVyICYgMHhGRikgPT0gMCkgU3lzdGVtLm91dC5wcmludGxuKCJBdDogIiArIGxpbmUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBmaW5kIHRoZSB2YWx1ZXMgb2YgdGhlIHBhcnRpY3VsYXIgZmllbGRzIHRoYXQgd2UgbmVlZAogICAgICAgICAgICAvLyBTYW1wbGUgbGluZTogMDBDMDtMQVRJTiAuLi5BIEdSQVZFO0x1OzA7TDswMDQxIDAzMDA7Ozs7TjtMQVRJTiAuLi4gR1JBVkU7OzswMEUwOwogICAgICAgICAgICAKICAgICAgICAgICAgaW50IHN0YXJ0ID0gMDsKICAgICAgICAgICAgaW50IGVuZCA9IGxpbmUuaW5kZXhPZignOycpOyAvLyBjb2RlCiAgICAgICAgICAgIHZhbHVlID0gSW50ZWdlci5wYXJzZUludChsaW5lLnN1YnN0cmluZyhzdGFydCxlbmQpLDE2KTsKICAgICAgICAgICAgaWYgKHRydWUgJiYgdmFsdWUgPT0gJ1x1MDBjMCcpIHsKICAgICAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJkZWJ1ZzogIiArIGxpbmUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVuZCA9IGxpbmUuaW5kZXhPZignOycsc3RhcnQ9ZW5kKzEpOyAvLyBuYW1lCiAgICAgICAgICAgIFN0cmluZyBuYW1lID0gbGluZS5zdWJzdHJpbmcoc3RhcnQsZW5kKTsKICAgICAgICAgICAgZW5kID0gbGluZS5pbmRleE9mKCc7JyxzdGFydD1lbmQrMSk7IC8vIGdlbmVyYWwgY2F0ZWdvcnkKICAgICAgICAgICAgZW5kID0gbGluZS5pbmRleE9mKCc7JyxzdGFydD1lbmQrMSk7IC8vIGNhbm9uaWNhbCBjbGFzcwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gY2hlY2sgY29uc2lzdGVuY3k6IGNhbm9uaWNhbCBjbGFzc2VzIG11c3QgYmUgZnJvbSAwIHRvIDI1NQogICAgICAgICAgICAKICAgICAgICAgICAgaW50IGNjID0gSW50ZWdlci5wYXJzZUludChsaW5lLnN1YnN0cmluZyhzdGFydCxlbmQpKTsKICAgICAgICAgICAgaWYgKGNjICE9IChjYyAmIDB4RkYpKSBTeXN0ZW0uZXJyLnByaW50bG4oIkJhZCBjYW5vbmljYWwgY2xhc3MgYXQ6ICIgKyBsaW5lKTsKICAgICAgICAgICAgY2Fub25pY2FsQ2xhc3MucHV0KHZhbHVlLGNjKTsKICAgICAgICAgICAgZW5kID0gbGluZS5pbmRleE9mKCc7JyxzdGFydD1lbmQrMSk7IC8vIEJJREkKICAgICAgICAgICAgZW5kID0gbGluZS5pbmRleE9mKCc7JyxzdGFydD1lbmQrMSk7IC8vIGRlY29tcAogICAgICAgICAgICAKICAgICAgICAgICAgLy8gZGVjb21wIHJlcXVpcmVzIG1vcmUgcHJvY2Vzc2luZy4KICAgICAgICAgICAgLy8gc3RvcmUgd2hldGhlciBpdCBpcyBjYW5vbmljYWwgb3IgY29tcGF0aWJpbGl0eS4KICAgICAgICAgICAgLy8gc3RvcmUgdGhlIGRlY29tcCBpbiBvbmUgdGFibGUsIGFuZCB0aGUgcmV2ZXJzZSBtYXBwaW5nIChmcm9tIHBhaXJzKSBpbiBhbm90aGVyCiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoc3RhcnQgIT0gZW5kKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgc2VnbWVudCA9IGxpbmUuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBjb21wYXQgPSBzZWdtZW50LmNoYXJBdCgwKSA9PSAnPCc7CiAgICAgICAgICAgICAgICBpZiAoY29tcGF0KSBpc0NvbXBhdGliaWxpdHkuc2V0KHZhbHVlKTsKICAgICAgICAgICAgICAgIFN0cmluZyBkZWNvbXAgPSBmcm9tSGV4KHNlZ21lbnQpOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBhIHNtYWxsIHNuaXBwZXQgb2YgY29kZSB0byBnZW5lcmF0ZSB0aGUgQXBwbGV0IGRhdGEKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLyppZiAoR0VORVJBVElORykgewogICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA8IDB4RkYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlwiXFx1IiArIGhleCgoY2hhcil2YWx1ZSkgKyAiXCIsICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlwiXFx1IiArIGhleChkZWNvbXAsICJcXHUiKSArICJcIiwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAoY29tcGF0ID8gIlwiS1wiLCIgOiAiXCJcIiwiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiLy8gIiArIG5hbWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0qLwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBjaGVjayBjb25zaXN0ZW5jeTogYWxsIGNhbm9uIGRlY29tcHMgbXVzdCBiZSBzaW5nbGVzIG9yIHBhaXJzIQogICAgICAgICAgICAgICAgaW50IGRlY29tcExlbiA9IFVURjE2VXRpbC5jb3VudENvZGVQb2ludChkZWNvbXApOwogICAgICAgICAgICAgICAgaWYgKGRlY29tcExlbiA8IDEgfHwgZGVjb21wTGVuID4gMiAmJiAhY29tcGF0KSB7CiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJCYWQgZGVjb21wIGF0OiAiICsgbGluZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkZWNvbXBvc2UucHV0KHZhbHVlLCBkZWNvbXApOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBvbmx5IGNvbXBvc2l0aW9ucyBhcmUgY2Fub25pY2FsIHBhaXJzCiAgICAgICAgICAgICAgICAvLyBza2lwIGlmIHNjcmlwdCBleGNsdXNpb24KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKCFjb21wYXQgJiYgIWlzRXhjbHVkZWQuZ2V0KHZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgIGludCBmaXJzdCA9ICdcdTAwMDAnOwogICAgICAgICAgICAgICAgICAgIGludCBzZWNvbmQgPSBVVEYxNlV0aWwubmV4dENvZGVQb2ludChkZWNvbXAsIDApOwogICAgICAgICAgICAgICAgICAgIGlmIChkZWNvbXBMZW4gPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gc2Vjb25kOwogICAgICAgICAgICAgICAgICAgICAgICBzZWNvbmQgPSBVVEYxNlV0aWwubmV4dENvZGVQb2ludChkZWNvbXAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVVRGMTZVdGlsLmNvZGVQb2ludExlbmd0aChmaXJzdCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvLyBzdG9yZSBjb21wb3NpdGlvbiBwYWlyIGluIHNpbmdsZSBpbnRlZ2VyCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgcGFpciA9ICgobG9uZylmaXJzdCA8PCAzMikgfCBzZWNvbmQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHICYmIHZhbHVlID09ICdcdTAwQzAnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZGVidWcyOiAiICsgbGluZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNvbXBvc2UucHV0KHBhaXIsIHZhbHVlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoREVCVUcpIHsKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkV4Y2x1ZGluZzogIiArIGRlY29tcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW4uY2xvc2UoKTsKICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiRG9uZSByZWFkaW5nIFVuaWNvZGUgQ2hhcmFjdGVyIERhdGFiYXNlIik7CiAgICAgICAgCiAgICAgICAgLy8gYWRkIGFsZ29yaXRobWljIEhhbmd1bCBkZWNvbXBvc2l0aW9ucwogICAgICAgIC8vIHRoaXMgaXMgbW9yZSBjb21wYWN0IGlmIGRvbmUgYXQgcnVudGltZSwgYnV0IGZvciBzaW1wbGljaXR5IHdlCiAgICAgICAgLy8gZG8gaXQgdGhpcyB3YXkuCiAgICAgICAgCiAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIkFkZGluZyBIYW5ndWwiKTsKICAgICAgICAKICAgICAgICBmb3IgKGludCBTSW5kZXggPSAwOyBTSW5kZXggPCBTQ291bnQ7ICsrU0luZGV4KSB7CiAgICAgICAgICAgIGludCBUSW5kZXggPSBTSW5kZXggJSBUQ291bnQ7CiAgICAgICAgICAgIGNoYXIgZmlyc3QsIHNlY29uZDsKICAgICAgICAgICAgaWYgKFRJbmRleCAhPSAwKSB7IC8vIHRyaXBsZQogICAgICAgICAgICAgICAgZmlyc3QgPSAoY2hhcikoU0Jhc2UgKyBTSW5kZXggLSBUSW5kZXgpOwogICAgICAgICAgICAgICAgc2Vjb25kID0gKGNoYXIpKFRCYXNlICsgVEluZGV4KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGZpcnN0ID0gKGNoYXIpKExCYXNlICsgU0luZGV4IC8gTkNvdW50KTsKICAgICAgICAgICAgICAgIHNlY29uZCA9IChjaGFyKShWQmFzZSArIChTSW5kZXggJSBOQ291bnQpIC8gVENvdW50KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwYWlyID0gKChsb25nKWZpcnN0IDw8IDMyKSB8IHNlY29uZDsKICAgICAgICAgICAgdmFsdWUgPSBTSW5kZXggKyBTQmFzZTsKICAgICAgICAgICAgZGVjb21wb3NlLnB1dCh2YWx1ZSwgU3RyaW5nLnZhbHVlT2YoZmlyc3QpICsgc2Vjb25kKTsKICAgICAgICAgICAgY29tcG9zZS5wdXQocGFpciwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiRG9uZSBhZGRpbmcgSGFuZ3VsIik7CiAgICB9CgogICAgLyoqCiAgICAgKiBIYW5ndWwgY29tcG9zaXRpb24gY29uc3RhbnRzCiAgICAgKi8KICAgIHN0YXRpYyBmaW5hbCBpbnQgCiAgICAgICAgU0Jhc2UgPSAweEFDMDAsIExCYXNlID0gMHgxMTAwLCBWQmFzZSA9IDB4MTE2MSwgVEJhc2UgPSAweDExQTcsCiAgICAgICAgTENvdW50ID0gMTksIFZDb3VudCA9IDIxLCBUQ291bnQgPSAyOCwKICAgICAgICBOQ291bnQgPSBWQ291bnQgKiBUQ291bnQsICAgLy8gNTg4CiAgICAgICAgU0NvdW50ID0gTENvdW50ICogTkNvdW50OyAgIC8vIDExMTcyCiAgICAKICAgIC8qKgogICAgICogRm9yIHVzZSBpbiBhbiBhcHBsZXQ6IGp1c3QgbG9hZCBhIG1pbmltYWwgc2V0IG9mIGRhdGEuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIHZvaWQgc2V0TWluaW1hbERlY29tcChJbnRIYXNodGFibGUgY2Fub25pY2FsQ2xhc3MsIEludFN0cmluZ0hhc2h0YWJsZSBkZWNvbXBvc2UsIAogICAgICBMb25nSGFzaHRhYmxlIGNvbXBvc2UsIEJpdFNldCBpc0NvbXBhdGliaWxpdHksIEJpdFNldCBpc0V4Y2x1ZGVkKSB7CiAgICAgICAgU3RyaW5nW10gZGVjb21wb3NlRGF0YSA9IHsKICAgICAgICAgICAgIlx1MDA1RSIsICJcdTAwMjBcdTAzMDIiLCAiSyIsCiAgICAgICAgICAgICJcdTAwNUYiLCAiXHUwMDIwXHUwMzMyIiwgIksiLAogICAgICAgICAgICAiXHUwMDYwIiwgIlx1MDAyMFx1MDMwMCIsICJLIiwKICAgICAgICAgICAgIlx1MDBBMCIsICJcdTAwMjAiLCAiSyIsCiAgICAgICAgICAgICJcdTAwQTgiLCAiXHUwMDIwXHUwMzA4IiwgIksiLAogICAgICAgICAgICAiXHUwMEFBIiwgIlx1MDA2MSIsICJLIiwKICAgICAgICAgICAgIlx1MDBBRiIsICJcdTAwMjBcdTAzMDQiLCAiSyIsCiAgICAgICAgICAgICJcdTAwQjIiLCAiXHUwMDMyIiwgIksiLAogICAgICAgICAgICAiXHUwMEIzIiwgIlx1MDAzMyIsICJLIiwKICAgICAgICAgICAgIlx1MDBCNCIsICJcdTAwMjBcdTAzMDEiLCAiSyIsCiAgICAgICAgICAgICJcdTAwQjUiLCAiXHUwM0JDIiwgIksiLAogICAgICAgICAgICAiXHUwMEI4IiwgIlx1MDAyMFx1MDMyNyIsICJLIiwKICAgICAgICAgICAgIlx1MDBCOSIsICJcdTAwMzEiLCAiSyIsCiAgICAgICAgICAgICJcdTAwQkEiLCAiXHUwMDZGIiwgIksiLAogICAgICAgICAgICAiXHUwMEJDIiwgIlx1MDAzMVx1MjA0NFx1MDAzNCIsICJLIiwKICAgICAgICAgICAgIlx1MDBCRCIsICJcdTAwMzFcdTIwNDRcdTAwMzIiLCAiSyIsCiAgICAgICAgICAgICJcdTAwQkUiLCAiXHUwMDMzXHUyMDQ0XHUwMDM0IiwgIksiLAogICAgICAgICAgICAiXHUwMEMwIiwgIlx1MDA0MVx1MDMwMCIsICIiLAogICAgICAgICAgICAiXHUwMEMxIiwgIlx1MDA0MVx1MDMwMSIsICIiLAogICAgICAgICAgICAiXHUwMEMyIiwgIlx1MDA0MVx1MDMwMiIsICIiLAogICAgICAgICAgICAiXHUwMEMzIiwgIlx1MDA0MVx1MDMwMyIsICIiLAogICAgICAgICAgICAiXHUwMEM0IiwgIlx1MDA0MVx1MDMwOCIsICIiLAogICAgICAgICAgICAiXHUwMEM1IiwgIlx1MDA0MVx1MDMwQSIsICIiLAogICAgICAgICAgICAiXHUwMEM3IiwgIlx1MDA0M1x1MDMyNyIsICIiLAogICAgICAgICAgICAiXHUwMEM4IiwgIlx1MDA0NVx1MDMwMCIsICIiLAogICAgICAgICAgICAiXHUwMEM5IiwgIlx1MDA0NVx1MDMwMSIsICIiLAogICAgICAgICAgICAiXHUwMENBIiwgIlx1MDA0NVx1MDMwMiIsICIiLAogICAgICAgICAgICAiXHUwMENCIiwgIlx1MDA0NVx1MDMwOCIsICIiLAogICAgICAgICAgICAiXHUwMENDIiwgIlx1MDA0OVx1MDMwMCIsICIiLAogICAgICAgICAgICAiXHUwMENEIiwgIlx1MDA0OVx1MDMwMSIsICIiLAogICAgICAgICAgICAiXHUwMENFIiwgIlx1MDA0OVx1MDMwMiIsICIiLAogICAgICAgICAgICAiXHUwMENGIiwgIlx1MDA0OVx1MDMwOCIsICIiLAogICAgICAgICAgICAiXHUwMEQxIiwgIlx1MDA0RVx1MDMwMyIsICIiLAogICAgICAgICAgICAiXHUwMEQyIiwgIlx1MDA0Rlx1MDMwMCIsICIiLAogICAgICAgICAgICAiXHUwMEQzIiwgIlx1MDA0Rlx1MDMwMSIsICIiLAogICAgICAgICAgICAiXHUwMEQ0IiwgIlx1MDA0Rlx1MDMwMiIsICIiLAogICAgICAgICAgICAiXHUwMEQ1IiwgIlx1MDA0Rlx1MDMwMyIsICIiLAogICAgICAgICAgICAiXHUwMEQ2IiwgIlx1MDA0Rlx1MDMwOCIsICIiLAogICAgICAgICAgICAiXHUwMEQ5IiwgIlx1MDA1NVx1MDMwMCIsICIiLAogICAgICAgICAgICAiXHUwMERBIiwgIlx1MDA1NVx1MDMwMSIsICIiLAogICAgICAgICAgICAiXHUwMERCIiwgIlx1MDA1NVx1MDMwMiIsICIiLAogICAgICAgICAgICAiXHUwMERDIiwgIlx1MDA1NVx1MDMwOCIsICIiLAogICAgICAgICAgICAiXHUwMEREIiwgIlx1MDA1OVx1MDMwMSIsICIiLAogICAgICAgICAgICAiXHUwMEUwIiwgIlx1MDA2MVx1MDMwMCIsICIiLAogICAgICAgICAgICAiXHUwMEUxIiwgIlx1MDA2MVx1MDMwMSIsICIiLAogICAgICAgICAgICAiXHUwMEUyIiwgIlx1MDA2MVx1MDMwMiIsICIiLAogICAgICAgICAgICAiXHUwMEUzIiwgIlx1MDA2MVx1MDMwMyIsICIiLAogICAgICAgICAgICAiXHUwMEU0IiwgIlx1MDA2MVx1MDMwOCIsICIiLAogICAgICAgICAgICAiXHUwMEU1IiwgIlx1MDA2MVx1MDMwQSIsICIiLAogICAgICAgICAgICAiXHUwMEU3IiwgIlx1MDA2M1x1MDMyNyIsICIiLAogICAgICAgICAgICAiXHUwMEU4IiwgIlx1MDA2NVx1MDMwMCIsICIiLAogICAgICAgICAgICAiXHUwMEU5IiwgIlx1MDA2NVx1MDMwMSIsICIiLAogICAgICAgICAgICAiXHUwMEVBIiwgIlx1MDA2NVx1MDMwMiIsICIiLAogICAgICAgICAgICAiXHUwMEVCIiwgIlx1MDA2NVx1MDMwOCIsICIiLAogICAgICAgICAgICAiXHUwMEVDIiwgIlx1MDA2OVx1MDMwMCIsICIiLAogICAgICAgICAgICAiXHUwMEVEIiwgIlx1MDA2OVx1MDMwMSIsICIiLAogICAgICAgICAgICAiXHUwMEVFIiwgIlx1MDA2OVx1MDMwMiIsICIiLAogICAgICAgICAgICAiXHUwMEVGIiwgIlx1MDA2OVx1MDMwOCIsICIiLAogICAgICAgICAgICAiXHUwMEYxIiwgIlx1MDA2RVx1MDMwMyIsICIiLAogICAgICAgICAgICAiXHUwMEYyIiwgIlx1MDA2Rlx1MDMwMCIsICIiLAogICAgICAgICAgICAiXHUwMEYzIiwgIlx1MDA2Rlx1MDMwMSIsICIiLAogICAgICAgICAgICAiXHUwMEY0IiwgIlx1MDA2Rlx1MDMwMiIsICIiLAogICAgICAgICAgICAiXHUwMEY1IiwgIlx1MDA2Rlx1MDMwMyIsICIiLAogICAgICAgICAgICAiXHUwMEY2IiwgIlx1MDA2Rlx1MDMwOCIsICIiLAogICAgICAgICAgICAiXHUwMEY5IiwgIlx1MDA3NVx1MDMwMCIsICIiLAogICAgICAgICAgICAiXHUwMEZBIiwgIlx1MDA3NVx1MDMwMSIsICIiLAogICAgICAgICAgICAiXHUwMEZCIiwgIlx1MDA3NVx1MDMwMiIsICIiLAogICAgICAgICAgICAiXHUwMEZDIiwgIlx1MDA3NVx1MDMwOCIsICIiLAogICAgICAgICAgICAiXHUwMEZEIiwgIlx1MDA3OVx1MDMwMSIsICIiLAovLyBFWFRSQVMsIG91dHNpZGUgb2YgTGF0aW4gMQogICAgICAgICAgICAiXHUxRUE0IiwgIlx1MDBDMlx1MDMwMSIsICIiLAogICAgICAgICAgICAiXHUxRUE1IiwgIlx1MDBFMlx1MDMwMSIsICIiLAogICAgICAgICAgICAiXHUxRUE2IiwgIlx1MDBDMlx1MDMwMCIsICIiLAogICAgICAgICAgICAiXHUxRUE3IiwgIlx1MDBFMlx1MDMwMCIsICIiLAogICAgICAgIH07CgogICAgICAgIGludFtdIGNsYXNzRGF0YSA9IHsKICAgICAgICAgICAgMHgwMzAwLCAyMzAsCiAgICAgICAgICAgIDB4MDMwMSwgMjMwLAogICAgICAgICAgICAweDAzMDIsIDIzMCwKICAgICAgICAgICAgMHgwMzAzLCAyMzAsCiAgICAgICAgICAgIDB4MDMwNCwgMjMwLAogICAgICAgICAgICAweDAzMDUsIDIzMCwKICAgICAgICAgICAgMHgwMzA2LCAyMzAsCiAgICAgICAgICAgIDB4MDMwNywgMjMwLAogICAgICAgICAgICAweDAzMDgsIDIzMCwKICAgICAgICAgICAgMHgwMzA5LCAyMzAsCiAgICAgICAgICAgIDB4MDMwQSwgMjMwLAogICAgICAgICAgICAweDAzMEIsIDIzMCwKICAgICAgICAgICAgMHgwMzBDLCAyMzAsCiAgICAgICAgICAgIDB4MDMwRCwgMjMwLAogICAgICAgICAgICAweDAzMEUsIDIzMCwKICAgICAgICAgICAgMHgwMzBGLCAyMzAsCiAgICAgICAgICAgIDB4MDMxMCwgMjMwLAogICAgICAgICAgICAweDAzMTEsIDIzMCwKICAgICAgICAgICAgMHgwMzEyLCAyMzAsCiAgICAgICAgICAgIDB4MDMxMywgMjMwLAogICAgICAgICAgICAweDAzMTQsIDIzMCwKICAgICAgICAgICAgMHgwMzE1LCAyMzIsCiAgICAgICAgICAgIDB4MDMxNiwgMjIwLAogICAgICAgICAgICAweDAzMTcsIDIyMCwKICAgICAgICAgICAgMHgwMzE4LCAyMjAsCiAgICAgICAgICAgIDB4MDMxOSwgMjIwLAogICAgICAgICAgICAweDAzMUEsIDIzMiwKICAgICAgICAgICAgMHgwMzFCLCAyMTYsCiAgICAgICAgICAgIDB4MDMxQywgMjIwLAogICAgICAgICAgICAweDAzMUQsIDIyMCwKICAgICAgICAgICAgMHgwMzFFLCAyMjAsCiAgICAgICAgICAgIDB4MDMxRiwgMjIwLAogICAgICAgICAgICAweDAzMjAsIDIyMCwKICAgICAgICAgICAgMHgwMzIxLCAyMDIsCiAgICAgICAgICAgIDB4MDMyMiwgMjAyLAogICAgICAgICAgICAweDAzMjMsIDIyMCwKICAgICAgICAgICAgMHgwMzI0LCAyMjAsCiAgICAgICAgICAgIDB4MDMyNSwgMjIwLAogICAgICAgICAgICAweDAzMjYsIDIyMCwKICAgICAgICAgICAgMHgwMzI3LCAyMDIsCiAgICAgICAgICAgIDB4MDMyOCwgMjAyLAogICAgICAgICAgICAweDAzMjksIDIyMCwKICAgICAgICAgICAgMHgwMzJBLCAyMjAsCiAgICAgICAgICAgIDB4MDMyQiwgMjIwLAogICAgICAgICAgICAweDAzMkMsIDIyMCwKICAgICAgICAgICAgMHgwMzJELCAyMjAsCiAgICAgICAgICAgIDB4MDMyRSwgMjIwLAogICAgICAgICAgICAweDAzMkYsIDIyMCwKICAgICAgICAgICAgMHgwMzMwLCAyMjAsCiAgICAgICAgICAgIDB4MDMzMSwgMjIwLAogICAgICAgICAgICAweDAzMzIsIDIyMCwKICAgICAgICAgICAgMHgwMzMzLCAyMjAsCiAgICAgICAgICAgIDB4MDMzNCwgMSwKICAgICAgICAgICAgMHgwMzM1LCAxLAogICAgICAgICAgICAweDAzMzYsIDEsCiAgICAgICAgICAgIDB4MDMzNywgMSwKICAgICAgICAgICAgMHgwMzM4LCAxLAogICAgICAgICAgICAweDAzMzksIDIyMCwKICAgICAgICAgICAgMHgwMzNBLCAyMjAsCiAgICAgICAgICAgIDB4MDMzQiwgMjIwLAogICAgICAgICAgICAweDAzM0MsIDIyMCwKICAgICAgICAgICAgMHgwMzNELCAyMzAsCiAgICAgICAgICAgIDB4MDMzRSwgMjMwLAogICAgICAgICAgICAweDAzM0YsIDIzMCwKICAgICAgICAgICAgMHgwMzQwLCAyMzAsCiAgICAgICAgICAgIDB4MDM0MSwgMjMwLAogICAgICAgICAgICAweDAzNDIsIDIzMCwKICAgICAgICAgICAgMHgwMzQzLCAyMzAsCiAgICAgICAgICAgIDB4MDM0NCwgMjMwLAogICAgICAgICAgICAweDAzNDUsIDI0MCwKICAgICAgICAgICAgMHgwMzYwLCAyMzQsCiAgICAgICAgICAgIDB4MDM2MSwgMjM0CiAgICAgICAgfTsKICAgIAogICAgICAgIC8vIGJ1aWxkIHRoZSBzYW1lIHRhYmxlcyB3ZSB3b3VsZCBvdGhlcndpc2UgZ2V0IGZyb20gdGhlCiAgICAgICAgLy8gVW5pY29kZSBDaGFyYWN0ZXIgRGF0YWJhc2UsIGp1c3Qgd2l0aCBsaW1pdGVkIGRhdGEKICAgICAgICAgCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZWNvbXBvc2VEYXRhLmxlbmd0aDsgaSs9MykgewogICAgICAgICAgICBjaGFyIHZhbHVlID0gZGVjb21wb3NlRGF0YVtpXS5jaGFyQXQoMCk7CiAgICAgICAgICAgIFN0cmluZyBkZWNvbXAgPSBkZWNvbXBvc2VEYXRhW2krMV07CiAgICAgICAgICAgIGJvb2xlYW4gY29tcGF0ID0gZGVjb21wb3NlRGF0YVtpKzJdLmVxdWFscygiSyIpOwogICAgICAgICAgICBpZiAoY29tcGF0KSBpc0NvbXBhdGliaWxpdHkuc2V0KHZhbHVlKTsKICAgICAgICAgICAgZGVjb21wb3NlLnB1dCh2YWx1ZSwgZGVjb21wKTsKICAgICAgICAgICAgaWYgKCFjb21wYXQpIHsKICAgICAgICAgICAgICAgIGludCBmaXJzdCA9ICdcdTAwMDAnOwogICAgICAgICAgICAgICAgaW50IHNlY29uZCA9IFVURjE2VXRpbC5uZXh0Q29kZVBvaW50KGRlY29tcCwgMCk7CiAgICAgICAgICAgICAgICBpZiAoZGVjb21wLmxlbmd0aCgpID4gMSkgewogICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gc2Vjb25kOwogICAgICAgICAgICAgICAgICAgIHNlY29uZCA9IFVURjE2VXRpbC5uZXh0Q29kZVBvaW50KGRlY29tcCwgCiAgICAgICAgICAgICAgICAgICAgICAgIFVURjE2VXRpbC5jb2RlUG9pbnRMZW5ndGgoZmlyc3QpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxvbmcgcGFpciA9IChmaXJzdCA8PCAxNikgfCBzZWNvbmQ7CiAgICAgICAgICAgICAgICBjb21wb3NlLnB1dChwYWlyLCB2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjbGFzc0RhdGEubGVuZ3RoOykgewogICAgICAgICAgICBjYW5vbmljYWxDbGFzcy5wdXQoY2xhc3NEYXRhW2krK10sIGNsYXNzRGF0YVtpKytdKTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogVXRpbGl0eTogUGFyc2VzIGEgc2VxdWVuY2Ugb2YgaGV4IFVuaWNvZGUgY2hhcmFjdGVycyBzZXBhcmF0ZWQgYnkgc3BhY2VzCiAgICAgKi8KICAgIHN0YXRpYyBwdWJsaWMgU3RyaW5nIGZyb21IZXgoU3RyaW5nIHNvdXJjZSkgewogICAgICAgIFN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzb3VyY2UubGVuZ3RoKCk7ICsraSkgewogICAgICAgICAgICBjaGFyIGMgPSBzb3VyY2UuY2hhckF0KGkpOwogICAgICAgICAgICBzd2l0Y2ggKGMpIHsKICAgICAgICAgICAgICBjYXNlICcgJzogYnJlYWs7IC8vIGlnbm9yZQogICAgICAgICAgICAgIGNhc2UgJzAnOiBjYXNlICcxJzogY2FzZSAnMic6IGNhc2UgJzMnOiBjYXNlICc0JzogY2FzZSAnNSc6IGNhc2UgJzYnOiBjYXNlICc3JzogCiAgICAgICAgICAgICAgY2FzZSAnOCc6IGNhc2UgJzknOiBjYXNlICdBJzogY2FzZSAnQic6IGNhc2UgJ0MnOiBjYXNlICdEJzogY2FzZSAnRSc6IGNhc2UgJ0YnOiAKICAgICAgICAgICAgICBjYXNlICdhJzogY2FzZSAnYic6IGNhc2UgJ2MnOiBjYXNlICdkJzogY2FzZSAnZSc6IGNhc2UgJ2YnOgogICAgICAgICAgICAgICAgaW50IGVuZCA9IDA7CiAgICAgICAgICAgICAgICBpbnQgdmFsdWUgPSAwOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbihzb3VyY2Uuc3Vic3RyaW5nKGksIGkgKyA0KSArICIqKioqKioqKioqKioiICsgc291cmNlKTsKICAgICAgICAgICAgICAgICAgICBlbmQgPSBzb3VyY2UuaW5kZXhPZignICcsaSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVuZCA8IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgZW5kID0gc291cmNlLmxlbmd0aCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IEludGVnZXIucGFyc2VJbnQoc291cmNlLnN1YnN0cmluZyhpLCBlbmQpLDE2KTsKICAgICAgICAgICAgICAgICAgICBVVEYxNlV0aWwuYXBwZW5kQ29kZVBvaW50KHJlc3VsdCwgdmFsdWUpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImk6ICIgKyBpICsgIjtlbmQ6IiArIGVuZCArICJzb3VyY2U6IiArIHNvdXJjZSk7CiAgICAgICAgICAgICAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oc291cmNlLnN1YnN0cmluZyhpLCBpICsgNCkgKyAiKioqKioqKioqKioqIiArIHNvdXJjZSk7CiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmV4aXQoMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL2krPSAzOyAvLyBza2lwIHJlc3Qgb2YgbnVtYmVyCiAgICAgICAgICAgICAgICBpID0gZW5kOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAnPCc6IGludCBqID0gc291cmNlLmluZGV4T2YoJz4nLGkpOyAvLyBza2lwIDwuLi4+CiAgICAgICAgICAgICAgICBpZiAoaiA+IDApIHsKICAgICAgICAgICAgICAgICAgICBpID0gajsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZWxzZSBmYWxsIHRocm91Z2gtLWVycm9yCiAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkJhZCBoZXggdmFsdWUgaW4gIiArIHNvdXJjZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFV0aWxpdHk6IFN1cHBsaWVzIGEgemVyby1wYWRkZWQgaGV4IHJlcHJlc2VudGF0aW9uIG9mIGFuIGludGVnZXIgKHdpdGhvdXQgMHgpCiAgICAgKi8KICAgIHN0YXRpYyBwdWJsaWMgU3RyaW5nIGhleChpbnQgaSkgewogICAgICAgIFN0cmluZyByZXN1bHQgPSBMb25nLnRvU3RyaW5nKGkgJiAweEZGRkZGRkZGTCwgMTYpLnRvVXBwZXJDYXNlKCk7CiAgICAgICAgcmV0dXJuICIwMDAwMDAwMCIuc3Vic3RyaW5nKHJlc3VsdC5sZW5ndGgoKSw4KSArIHJlc3VsdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBVdGlsaXR5OiBTdXBwbGllcyBhIHplcm8tcGFkZGVkIGhleCByZXByZXNlbnRhdGlvbiBvZiBhIFVuaWNvZGUgY2hhcmFjdGVyICh3aXRob3V0IDB4LCBcXHUpCiAgICAgKi8KICAgIHN0YXRpYyBwdWJsaWMgU3RyaW5nIGhleChjaGFyIGkpIHsKICAgICAgICBTdHJpbmcgcmVzdWx0ID0gSW50ZWdlci50b1N0cmluZyhpLCAxNikudG9VcHBlckNhc2UoKTsKICAgICAgICByZXR1cm4gIjAwMDAiLnN1YnN0cmluZyhyZXN1bHQubGVuZ3RoKCksNCkgKyByZXN1bHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogVXRpbGl0eTogU3VwcGxpZXMgYSB6ZXJvLXBhZGRlZCBoZXggcmVwcmVzZW50YXRpb24gb2YgYSBVbmljb2RlIGNoYXJhY3RlciAod2l0aG91dCAweCwgXFx1KQogICAgICovCglwdWJsaWMgc3RhdGljIFN0cmluZyBoZXgoU3RyaW5nIHMsIFN0cmluZyBzZXApIHsKCSAgICBTdHJpbmdCdWZmZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOwoJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGgoKTsgKytpKSB7CgkgICAgICAgIGlmIChpICE9IDApIHJlc3VsdC5hcHBlbmQoc2VwKTsKCSAgICAgICAgcmVzdWx0LmFwcGVuZChoZXgocy5jaGFyQXQoaSkpKTsKCSAgICB9CgkgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwoJfQp9