LyoNCglDb3B5cmlnaHQgKGMpIDIwMDYtMjAwNywgVGhlIFhvb2tpIHByb2plY3QNCglodHRwOi8veG9va2kuc291cmNlZm9yZ2UubmV0Lw0KDQogICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsNCiAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4NCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdA0KDQogICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wDQoNCiAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUNCiAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsDQogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4NCiAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQNCiAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLg0KCQ0KCVNvbWUgY29kZSBpcyBsYXJnZWx5IGluc3BpcmVkIGJ5IGNvZGUgZm91bmQgaW4gdGhlIGRvam8gdG9vbGtpdCwgDQoJc2VlIGh0dHA6Ly9kb2pvdG9vbGtpdC5vcmcvIGZvciBtb3JlIGluZm9ybWF0aW9uLg0KKi8NCg0KLyoNClRoaXMgc2NyaXB0IGNhbiBiZSBlaXRoZXIgZW1iZWRkZWQgaW4gYSB4b29raSBwYWdlIGZvciBpbiBicm93c2VyIHByb2Nlc3NpbmcsIG9yIHVzZWQgaW4gYmF0Y2ggdXNpbmcgcmhpbm8gb3IgamF2YSA2IGphdmFzY3JpcHQgdG9vbDoNCmpydW5zY3JpcHQgcGF0aC90by94b29raS5qcyBpbnB1dEZpbGVGcm9tWG9va2lTaXRlLmh0bWwgW3BhdGgvdG8vZGlyL3RvL3B1dC9nZW5lcmF0ZWQvZmlsZV0NCg0KQmUgc3VyZSB0byBiZSBpbiB0aGUgZGlyZWN0b3J5IHdoZXJlIHRoZSBodG1sIGlucHV0IHRvIHByb2Nlc3MgaXMgd2hlbiBydW5uaW5nIHRoaXMgY29tbWFuZC4NCiAqLw0KdmFyIGJhdGNoTW9kZSA9ICh0eXBlb2YgYXJndW1lbnRzICE9ICd1bmRlZmluZWQnKTsNCg0KdmFyIHhvb2tpID0ge307DQp4b29raS5jb25zb2xlID0gIiI7IC8vIHVzZWQgZm9yIGRlYnVnZ2luZyBwdXJwb3NlIG9ubHksIGFuZCBvbmx5IHdoZW4gdGhlIGRlYnVnIGRpdiBpcyBub3QgeWV0IGNyZWF0ZWQNCnhvb2tpLmNvbmZpZyA9IHt9Ow0KeG9va2kuYyA9IHhvb2tpLmNvbmZpZzsNCg0KZnVuY3Rpb24gdChtc2cpIHsNCiAgICAvLyByZXR1cm5zIHRoZSBpbnRlcm5hdGlvbmFsaXplZCB2ZXJzaW9uIG9mIHRoZSBtZXNzYWdlLCBvciB0aGUgbWVzc2FnZSBpZiBubyB0cmFuc2xhdGlvbiBpcyBhdmFpbGFibGUNCiAgICAvLyB0IHN0YW5kcyBmb3IgdHJhbnNsYXRlDQovLyBGSVhNRQ0KLy8gICAgaWYgKHR5cGVvZiB4b29raS5jID09ICJvYmplY3QiIA0KLy8gICAgICAgICYmIHR5cGVvZiB4b29raS5jLm1lc3NhZ2VzID09ICJvYmplY3QiIA0KLy8gICAgICAgICYmIHR5cGVvZiB4b29raS5jLm1lc3NhZ2VzW21zZ10gPT0gInN0cmluZyIpIHsNCi8vICAgICAgICBtc2cgPSB4b29raS5jLm1lc3NhZ2VzW21zZ107DQovLyAgICB9DQogICAgdmFyIGFyciA9IFtdOw0KICAgIGZvciAodmFyIGk9MTsgaTxhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgYXJyLnB1c2goYXJndW1lbnRzW2ldKTsNCiAgICB9DQogICAgcmV0dXJuIHhvb2tpLnN0cmluZy5zdWJzdGl0dXRlUGFyYW1zKG1zZywgYXJyKTsNCn0NCg0KZnVuY3Rpb24gY3NzKGNsc3MpIHsNCiAgICAvLyByZXR1cm5zIHRoZSBjc3MgY2xhc3Mgb3IgaWQgY29uZmlndXJlZCwgb3IgdGhlIGdpdmVuIGNsYXNzIChvciBpZCkgaWYgbm8gb25lIGlzIGNvbmZpZ3VyZWQNCiAgICBpZiAodHlwZW9mIHhvb2tpLmMuY3NzW2Nsc3NdICE9ICJ1bmRlZmluZWQiKSB7DQogICAgICAgIHJldHVybiB4b29raS5jLmNzc1tjbHNzXTsNCiAgICB9IGVsc2Ugew0KICAgICAgICByZXR1cm4gY2xzczsNCiAgICB9IA0KfQ0KZnVuY3Rpb24gdShwYXRoKSB7DQogIC8vIGNvbnZlcnQgYSBwYXRoIHJlbGF0aXZlIHRvIHRoZSByb290IHRvIGEgZnVsbCBVUkwNCiAgLy8gdSBzdGFuZHMgZm9yIFVybA0KICBpZiAoYmF0Y2hNb2RlKSB7DQoJcmV0dXJuIHhvb2tpLmMucmVsYXRpdmVSb290K3BhdGg7DQogIH0gZWxzZSB7DQoJcmV0dXJuIHhvb2tpLmMucm9vdCArIHBhdGg7DQogIH0NCn0NCmZ1bmN0aW9uIGx1KHBhdGgpIHsNCiAgLy8gY29udmVydCBhIHBhdGggcmVsYXRpdmUgdG8gdGhlIGxvY2FsIHJvb3QgdG8gYSBmdWxsIFVSTA0KICAvLyBsIHN0YW5kcyBmb3IgbG9jYWwsIHUgc3RhbmRzIGZvciBVcmwNCiAgaWYgKGJhdGNoTW9kZSkgew0KCXJldHVybiB4b29raS5jLmxvY2FsUmVsYXRpdmVSb290K3BhdGg7DQogIH0gZWxzZSB7DQoJcmV0dXJuIHhvb2tpLmMubG9jYWxSb290ICsgcGF0aDsNCiAgfQ0KfQ0KZnVuY3Rpb24gY3UodXJsQ2ZnUHJvcCkgew0KICAvLyBnZXQgYSBwYXRoIGZyb20gYSBjb25maWd1cmF0aW9uIHBhdGggYW5kIGNvbnZlcnQgaXQgdG8gYW4gVVJMDQogIC8vIGN1IHN0YW5kcyBmb3IgQ29uZmlndXJlZCBVcmwNCiAgaWYgKHR5cGVvZiB4b29raS5jLnBhdGhbdXJsQ2ZnUHJvcF0gPT0gInVuZGVmaW5lZCIpIHsNCiAgICB4b29raS53YXJuKHQoInBhdGggbm90IGNvbmZpZ3VyZWQgaW4geG9va2k6ICckezB9JyIsIHVybENmZ1Byb3ApKTsNCiAgICByZXR1cm4gIiI7DQogIH0NCiAgcmV0dXJuIHUoeG9va2kuYy5wYXRoW3VybENmZ1Byb3BdKTsNCn0NCmZ1bmN0aW9uIHB1KGlkKSB7DQogIC8vIHJldHVybnMgdGhlIHVybCBvZiB0aGUgcGFnZSBpZGVudGlmaWVkIGJ5IGlkDQogIC8vIHB1IHN0YW5kcyBmb3IgUGFnZSBVcmwNCiAgcmV0dXJuIHUoaWQrIi5odG1sIik7DQp9DQp4b29raS5wID0gZnVuY3Rpb24ocGF0aCkgew0KICAvLyBnZXQgYSB4b29raSBmdWxsIHBhdGggZnJvbSBhIHhvb2tpIHJlbGF0aXZlIHBhdGgNCiAgLy8gcCBzdGFuZHMgZm9yIHBhdGgNCiAgcmV0dXJuIHhvb2tpLmMucGF0aC5pbnN0YWxsKyIvIitwYXRoOw0KfQ0KeG9va2kudSA9IGZ1bmN0aW9uKHBhdGgpIHsNCiAgLy8gY29udmVydCBhIHBhdGggcmVsYXRpdmUgdG8gdGhlIHhvb2tpIGluc3RhbGxhdGlvbiBkaXIgdG8gYSBmdWxsIFVSTA0KICByZXR1cm4gdSh4b29raS5wKHBhdGgpKTsNCn0NCnhvb2tpLmN1ID0gZnVuY3Rpb24odXJsQ2ZnUHJvcCkgew0KICAvLyBnZXQgYSB4b29raSBwYXRoIGZyb20gYSBjb25maWd1cmF0aW9uIHBhdGggYW5kIGNvbnZlcnQgaXQgdG8gYW4gVVJMDQogIGlmICh0eXBlb2YgeG9va2kuYy5wYXRoW3VybENmZ1Byb3BdID09ICJ1bmRlZmluZWQiKSB7DQogICAgeG9va2kud2Fybih0KCJwYXRoIG5vdCBjb25maWd1cmVkIGluIHhvb2tpOiAnJHswfSciLCB1cmxDZmdQcm9wKSk7DQogIH0NCiAgcmV0dXJuIHhvb2tpLnUoeG9va2kuYy5wYXRoW3VybENmZ1Byb3BdKTsNCn0NCg0KeG9va2kudXRpbCA9IHsNCiAgICBpc0FycmF5OiBmdW5jdGlvbihpdCkgew0KICAgIAlyZXR1cm4gKGl0ICYmIGl0IGluc3RhbmNlb2YgQXJyYXkgfHwgdHlwZW9mIGl0ID09ICJhcnJheSIpOyAvLyBCb29sZWFuDQogICAgfSwNCiAgICBtaXg6IGZ1bmN0aW9uKHNyYywgaW50bywgb3ZlcnJpZGUpIHsNCiAgICAgICAgaWYgKHR5cGVvZiBvdmVycmlkZSA9PSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgb3ZlcnJpZGUgPSB0cnVlOw0KICAgICAgICB9DQogICAgICAgIGlmICh0eXBlb2YgaW50byA9PSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgaW50byA9IHt9Ow0KICAgICAgICB9DQogICAgICAgIGZvciAodmFyIGsgaW4gc3JjKSB7DQogICAgICAgICAgICBpZiAodHlwZW9mIHNyY1trXSA9PSAib2JqZWN0IiAmJiAheG9va2kudXRpbC5pc0FycmF5KHNyY1trXSkpIHsNCiAgICAgICAgICAgICAgICBpZiAob3ZlcnJpZGUgfHwgdHlwZW9mIGludG9ba10gPT0gIm9iamVjdCIgfHwgdHlwZW9mIGludG9ba10gPT0gInVuZGVmaW5lZCIpIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpbnRvW2tdICE9ICJvYmplY3QiKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBpbnRvW2tdID0ge307DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgeG9va2kudXRpbC5taXgoc3JjW2tdLCBpbnRvW2tdLCBvdmVycmlkZSk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSBlbHNlIGlmIChvdmVycmlkZSB8fCB0eXBlb2YgaW50b1trXSA9PSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgICAgIGludG9ba10gPSBzcmNba107DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIGludG87DQogICAgfSwNCiAgICBpbml0QXJyYXk6IGZ1bmN0aW9uKGEpIHsNCiAgICAgICAgaWYgKHRoaXMuaXNBcnJheShhKSkgcmV0dXJuIGE7DQogICAgICAgIGVsc2UgcmV0dXJuIHt9Ow0KICAgIH0NCn0NCg0KeG9va2kudXJsID0gew0KICAgICAgICBuZXdYbWxIdHRwUmVxdWVzdDogZnVuY3Rpb24oKSB7DQogICAgICAgIC8vIHdlIGZpcnN0IHRyeSB0byB1c2UgQWN0aXZlWCwgYmVjYXVzZSBJRTcgaGFzIGEgZGlyZWN0IHN1cHBvcnQgZm9yIFhtbEh0dHBSZXF1ZXN0IG9iamVjdCwgDQogICAgICAgIC8vIGJ1dCB3aGljaCBkb2Vzbid0IHdvcmsgd2l0aCBmaWxlIHVybHMNCiAgICAgICAgCWlmKHdpbmRvdy5BY3RpdmVYT2JqZWN0KQ0KICAgICAgICAJew0KICAgICAgICAJCXRyeSB7IHJlcSA9IG5ldyBBY3RpdmVYT2JqZWN0KCJNc3htbDIuWE1MSFRUUCIpOw0KICAgICAgICAJCX0gY2F0Y2goZSkgew0KICAgICAgICAJCQl0cnkgeyByZXEgPSBuZXcgQWN0aXZlWE9iamVjdCgiTWljcm9zb2Z0LlhNTEhUVFAiKTsNCiAgICAgICAgCQkJfSBjYXRjaChlKSB7IHJlcSA9IGZhbHNlOyB9DQogICAgICAgIAkJfQ0KICAgICAgICAJfQ0KICAgICAgICAJZWxzZSBpZih3aW5kb3cuWE1MSHR0cFJlcXVlc3QpIHsNCiAgICAgICAgCQl0cnkgeyByZXEgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTsNCiAgICAgICAgCQl9IGNhdGNoKGUpIHsgcmVxID0gZmFsc2U7IH0NCiAgICAgICAgCX0NCiAgICAgICAgDQogICAgICAgIAlyZXR1cm4gcmVxOwkNCiAgICAgICAgfSwNCiAgICAgICAgICAgICAgICANCiAgICAgICAgbG9hZFVSTDogZnVuY3Rpb24oIHVybCwgd2Fybk9uRXJyb3IgKSB7DQogICAgICAgIAlyZXEgPSB0aGlzLm5ld1htbEh0dHBSZXF1ZXN0KCk7DQogICAgICAgIAlpZihyZXEpIHsNCiAgICAgICAgCQl0cnkgew0KICAgICAgICAJCQlyZXEub3BlbigiR0VUIiwgdXJsLCBmYWxzZSk7DQogICAgICAgIAkJCXJlcS5zZW5kKCIiKTsNCiAgICAgICAgCQ0KICAgICAgICAJCQlyZXR1cm4gcmVxLnJlc3BvbnNlVGV4dDsNCiAgICAgICAgCQl9IGNhdGNoIChlKSB7DQogICAgICAgICAgICAgICAgICAgIGlmICh3YXJuT25FcnJvciAhPSBmYWxzZSkNCiAgICAgICAgICAgICAgICAgICAgICAgIHhvb2tpLmVycm9yKGUsIHQoInByb2JsZW0gd2hpbGUgbG9hZGluZyBVUkwgJHswfSIsIHVybCkpOw0KICAgICAgICAgICAgICAgICAgICBlbHNlDQogICAgICAgICAgICAgICAgICAgICAgICB4b29raS5kZWJ1Zyh0KCJwcm9ibGVtIHdoaWxlIGxvYWRpbmcgVVJMICR7MH06ICR7MX0iLCB1cmwsIGUpKTsNCiAgICAgICAgICAgICAgICB9CQkNCiAgICAgICAgCX0NCiAgICAgICAgCXJldHVybiBudWxsOw0KICAgICAgICB9LA0KICAgICAgICANCiAgICAgICAgYXN5bmNMb2FkVVJMOiBmdW5jdGlvbiggdXJsLCBjYWxsYmFjaywgb2JqICkgew0KICAgICAgICAJdmFyIHJlcSA9IHRoaXMubmV3WG1sSHR0cFJlcXVlc3QoKTsNCiAgICAgICAgCWlmKHJlcSkgew0KICAgICAgICAJCXRyeSB7DQogICAgICAgIAkJCXJlcS5vcGVuKCJHRVQiLCB1cmwsIHRydWUpOw0KCQkJCSAgICByZXEub25yZWFkeXN0YXRlY2hhbmdlPWZ1bmN0aW9uKCkgew0KCQkJCSAgICAgICAgaWYgKHJlcS5yZWFkeVN0YXRlID09IDQpIHsNCgkJCQkgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09IDIwMCB8fCByZXEuc3RhdHVzID09IDApIHsNCgkJCQkgICAgICAgICAgICAgIGNhbGxiYWNrKHJlcS5yZXNwb25zZVRleHQsIG9iaik7DQoJCQkJICAgICAgICAgICB9DQoJCQkJICAgICAgICB9DQoJCQkJICAgICB9OyAgCQkJDQoJCQkJICAgICByZXEuc2VuZCgiIik7DQogICAgICAgIAkJfSBjYXRjaCAoZSkgew0KICAgICAgICAJCQl4b29raS5lcnJvcihlLCB0KCJwcm9ibGVtIHdoaWxlIGxvYWRpbmcgVVJMICR7MH0iLCB1cmwpKTsNCiAgICAgICAgICAgICAgICB9CQkNCiAgICAgICAgCX0NCiAgICAgICAgfSwNCg0KICAgICAgICBpbmNsdWRlOiBmdW5jdGlvbihzY3JpcHRfZmlsZW5hbWUpIHsNCiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKCc8JyArICdzY3JpcHQnKTsNCiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKCcgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiJyk7DQogICAgICAgICAgICBkb2N1bWVudC53cml0ZSgnIHR5cGU9InRleHQvamF2YXNjcmlwdCInKTsNCiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKCcgc3JjPSInICsgeG9va2kudShzY3JpcHRfZmlsZW5hbWUpICsgJyI+Jyk7DQogICAgICAgICAgICBkb2N1bWVudC53cml0ZSgnPC8nICsgJ3NjcmlwdCcgKyAnPicpOw0KICAgICAgICB9LA0KICAgICAgICANCiAgICAgICAgZXZhbFVSTDogZnVuY3Rpb24oIHVybCwgd2Fybk9uRXJyb3JVcmwgKSB7DQogICAgICAgICAgICBzY3JpcHQgPSB0aGlzLmxvYWRVUkwodXJsLCB3YXJuT25FcnJvclVybCk7DQogICAgICAgICAgICBpZiAoc2NyaXB0ICE9IG51bGwpIHsNCiAgICAgICAgICAgICAgICB0cnkgew0KICAgICAgICAgICAgICAgICAgICBldmFsKHNjcmlwdCk7DQogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgew0KICAgICAgICAJCQl4b29raS5lcnJvcihlLCB0KCJlcnJvciB3aGlsZSBleGVjdXRpbmcgc2NyaXB0IGZyb20gVVJMICR7MH0iLCB1cmwpKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0sDQoNCiAgICAgICAgYWN0aW9uOiBmdW5jdGlvbihhY3Rpb24pIHsgICAgICAgIA0KICAgICAgICAgICAgLy8gcmV0dXJucyB0aGUgdXJsIGZvciBhbiBhY3Rpb24gb24gdGhlIHNhbWUgcGFnZQ0KICAgICAgICAgICAgbG9jID0gYmF0Y2hNb2RlPycnOnhvb2tpLnBhZ2VVUkw7DQogICAgICAgICAgICBpZiAobG9jLmluZGV4T2YoIiMiKSAhPSAtMSkgew0KICAgICAgICAgICAgICAgIGxvYyA9IGxvYy5zdWJzdHJpbmcoMCwgbG9jLmluZGV4T2YoIiMiKSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gbG9jKyI/YWN0aW9uPSIrYWN0aW9uOw0KICAgICAgICB9DQoNCiAgICB9Ow0KICAgIA0KeG9va2kuc3RyaW5nID0gew0KDQogICAgc3Vic3RpdHV0ZVBhcmFtczogZnVuY3Rpb24oLypzdHJpbmcqL3RlbXBsYXRlLCAvKiBvYmplY3QgLSBvcHRpb25hbCBvciAuLi4gKi9oYXNoKSB7DQogICAgLy8gYm9ycm93ZWQgZnJvbSBkb2pvDQogICAgLy8gc3VtbWFyeToNCiAgICAvLwlQZXJmb3JtcyBwYXJhbWV0ZXJpemVkIHN1YnN0aXR1dGlvbnMgb24gYSBzdHJpbmcuIFRocm93cyBhbiBleGNlcHRpb24gaWYgYW55IHBhcmFtZXRlciBpcyB1bm1hdGNoZWQuDQogICAgLy8NCiAgICAvLyBkZXNjcmlwdGlvbjoNCiAgICAvLwlGb3IgZXhhbXBsZSwNCiAgICAvLwkJZG9qby5zdHJpbmcuc3Vic3RpdHV0ZVBhcmFtcygiRmlsZSAnJHswfScgaXMgbm90IGZvdW5kIGluIGRpcmVjdG9yeSAnJHsxfScuIiwiZm9vLmh0bWwiLCIvdGVtcCIpOw0KICAgIC8vCXJldHVybnMNCiAgICAvLwkJIkZpbGUgJ2Zvby5odG1sJyBpcyBub3QgZm91bmQgaW4gZGlyZWN0b3J5ICcvdGVtcCcuIg0KICAgIC8vDQogICAgLy8gdGVtcGxhdGU6IHRoZSBvcmlnaW5hbCBzdHJpbmcgdGVtcGxhdGUgd2l0aCAke3ZhbHVlc30gdG8gYmUgcmVwbGFjZWQNCiAgICAvLyBoYXNoOiBuYW1lL3ZhbHVlIHBhaXJzICh0eXBlIG9iamVjdCkgdG8gcHJvdmlkZSBzdWJzdGl0dXRpb25zLiAgQWx0ZXJuYXRpdmVseSwgc3Vic3RpdHV0aW9ucyBtYXkgYmUNCiAgICAvLwlpbmNsdWRlZCBhcyBhbiBhcnJheQ0KICAgIA0KICAgICAgICB2YXIgbWFwOw0KICAgICAgICBpZiAodHlwZW9mIGhhc2ggPT0gIm9iamVjdCIgJiYgaGFzaC5sZW5ndGgpIHsgLy8gYXJyYXkNCiAgICAgICAgICAgIG1hcCA9IHt9Ow0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBoYXNoKSB7DQogICAgICAgICAgICAgICAgbWFwW2krIiJdID0gaGFzaFtpXTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIG1hcCA9IGhhc2g7DQogICAgICAgIH0NCiAgICANCiAgICAJcmV0dXJuIHRlbXBsYXRlLnJlcGxhY2UoL1wkXHsoXHcrKVx9L2csIGZ1bmN0aW9uKG1hdGNoLCBrZXkpew0KICAgIAkJaWYodHlwZW9mKG1hcFtrZXldKSAhPSAidW5kZWZpbmVkIiAmJiBtYXBba2V5XSAhPSBudWxsKXsNCiAgICAJCQlyZXR1cm4gbWFwW2tleV07DQogICAgCQl9DQogICAgCQl4b29raS53YXJuKCJTdWJzdGl0dXRpb24gbm90IGZvdW5kOiAiICsga2V5KTsNCiAgICAJCXJldHVybiBrZXk7DQogICAgCX0pOyAvLyBzdHJpbmcNCgl9LA0KCQ0KCXByb2Nlc3NUZW1wbGF0ZTogZnVuY3Rpb24oLypzdHJpbmcqL3RlbXBsYXRlLCAvKiBvYmplY3QgKi9oYXNoKSB7DQoJICAgaWYgKHR5cGVvZiB0ZW1wbGF0ZS5wcm9jZXNzID09ICJmdW5jdGlvbiIpIHsNCgkgICAgICAgcmV0dXJuIHRlbXBsYXRlLnByb2Nlc3MoaGFzaCk7DQogICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIHJldHVybiB0aGlzLnN1YnN0aXR1dGVQYXJhbXModGVtcGxhdGUsIGhhc2gpOw0KICAgICAgIH0NCiAgICB9LA0KDQogICAgZXhjZXB0aW9uVGV4dDogZnVuY3Rpb24oZSwgbWVzc2FnZSkgew0KICAgIAl2YXIgcyA9IGUuZGVzY3JpcHRpb24gPyBlLmRlc2NyaXB0aW9uIDogZS50b1N0cmluZygpOw0KICAgIAlyZXR1cm4gbWVzc2FnZSA/IG1lc3NhZ2UrIjpcbiIrcyA6IHM7DQogICAgfSwNCiAgICANCiAgICBmaW5kWG1sU2VjdGlvbjogZnVuY3Rpb24oc3RyLCBlbGVtZW50LCBmcm9tKSB7DQogICAgICAgIHJldHVybiB0aGlzLmZpbmRTZWN0aW9uKHN0ciwgbmV3IFJlZ0V4cCgnPCcrZWxlbWVudCsnKFxccypcXHcrPSJbXFx3XFxzXSoiKSo+JyksIG5ldyBSZWdFeHAoJzwvJytlbGVtZW50Kyc+JyksIGZyb20pOw0KICAgIH0sDQogICAgDQogICAgZmluZDogZnVuY3Rpb24oLypzdHJpbmcqL3N0ciwgLypzdHJpbmcgb3IgcmVnZXhwKi9leHAsIC8qbnVtYmVyLCBvcHRpb25hbCovZnJvbSkgew0KICAgICAgICAvLyBmaW5kIGFuIGV4cHJlc3Npb24gKHN0cmluZyBvciByZWdleHApIGluIGEgc3RyaW5nLCBmcm9tIGFuIG9wdGlvbmFsIGluZGV4DQogICAgICAgIC8vIHRoZSBvYmplY3QgcmV0dXJuZWQgaGFzIHR3byBwcm9wZXJ0aWVzOg0KICAgICAgICAvLyBiZWdpbjogdGhlIGluZGV4IGluIHN0ciBvZiB0aGUgbWF0Y2hpbmcgZmluZA0KICAgICAgICAvLyBlbmQ6IHRoZSBpbmRleCBpbiBzdHIgb2YgdGhlIGVuZCBvZiB0aGUgbWF0Y2hpbmcgZmluZA0KICAgICAgICAvLyByZXR1cm5zIG51bGwgaWYgbm8gbWF0Y2ggaXMgZm91bmQNCiAgICAgICAgaWYgKHR5cGVvZiBmcm9tICE9ICJudW1iZXIiKSB7DQogICAgICAgICAgICBmcm9tID0gMDsNCiAgICAgICAgfQ0KICAgICAgICBpZiAodHlwZW9mIGV4cCA9PSAic3RyaW5nIikgew0KICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHt9Ow0KICAgICAgICAgICAgcmVzdWx0LmJlZ2luID0gc3RyLmluZGV4T2YoZXhwLGZyb20pOw0KICAgICAgICAgICAgaWYgKHJlc3VsdC5iZWdpbiA+PSAwKSB7DQogICAgICAgICAgICAgICAgcmVzdWx0LmVuZCA9IHJlc3VsdC5iZWdpbiArIGV4cC5sZW5ndGg7DQogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIHZhciBtOw0KICAgICAgICAgICAgaWYgKGZyb20gPiAwKSB7DQogICAgICAgICAgICAgICAgLy8gSSBoYXZlbid0IGZvdW5kIGFueSBvdGhlciB3YXkgdG8gc3RhcnQgZnJvbSB0aGUgZ2l2ZW4gaW5kZXgNCiAgICAgICAgICAgICAgICBtID0gZXhwLmV4ZWMoc3RyLnN1YnN0cmluZyhmcm9tKSk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIG0gPSBleHAuZXhlYyhzdHIpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKG0gIT0gbnVsbCkgeyAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0ge307DQogICAgICAgICAgICAgICAgcmVzdWx0LmJlZ2luID0gbS5pbmRleCArIGZyb207DQogICAgICAgICAgICAgICAgcmVzdWx0LmVuZCA9IHJlc3VsdC5iZWdpbiArIG1bMF0ubGVuZ3RoOw0KICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIG51bGw7DQogICAgfSwNCiAgICANCiAgICBmaW5kU2VjdGlvbjogZnVuY3Rpb24oLypzdHJpbmcqL3N0ciwgLypzdHJpbmcgb3IgcmVnZXhwKi9vcGVuLCAvKnN0cmluZyBvciByZWdleHAqL2Nsb3NlLCAvKm51bWJlciwgb3B0aW9uYWwqL2Zyb20pIHsNCiAgICAgICAgLy8gZmluZHMgYSBzZWN0aW9uIGRlbGltaXRlZCBieSBvcGVuIGFuZCBjbG9zZSB0b2tlbnMgaW4gdGhlIGdpdmVuIHN0cmluZw0KICAgICAgICAvLyB0aGUgYWxnb3JpdGhtIGxvb2tzIGZvciBtYXRjaGluZyBvcGVuIGFuZCBjbG9zZSB0b2tlbnMNCiAgICAgICAgLy8gdGhlIHJldHVybmVkIG9iamVjdCBoYXMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOg0KICAgICAgICAvLyAgIG91dGVyU3RhcnQ6IHRoZSBpbmRleCBpbiBzdHIgd2hlcmUgdGhlIGZpcnN0IG9wZW4gdG9rZW4gd2FzIGZvdW5kDQogICAgICAgIC8vICAgaW5uZXJTdGFydDogdGhlIGluZGV4IGluIHN0ciBqdXN0IGFmdGVyIHRoZSBmb3VuZCBvcGVuIHRva2VuDQogICAgICAgIC8vICAgaW5uZXJFbmQ6IHRoZSBpbmRleCBpbiBzdHIgd2hlcmUgdGhlIG1hdGNoaW5nIGNsb3NlIHRva2VuIHdhcyBmb3VuZA0KICAgICAgICAvLyAgIG91dGVyRW5kOiB0aGUgaW5kZXggaW4gc3RyIGp1c3QgYWZ0ZXIgdGhlIG1hdGNoaW5nIGNsb3NlIHRva2VuDQogICAgICAgIC8vICAgY2hpbGRyZW46IGFuIGFycmF5IG9mIHNpbWlsYXIgb2JqZWN0cyBpZiBuZXN0ZWQgc2VjdGlvbnMgd2hlcmUgZm91bmQNCiAgICAgICAgLy8gaWYgbm8gc2VjdGlvbiBpcyBmb3VuZCAobm8gb3BlbiB0b2tlbiwgYW4gb3BlbiB0b2tlbiB3aXRoIG5vIG1hdGNoaW5nIA0KICAgICAgICAvLyBjbG9zZSB0b2tlbiwgb3IgYSBjbG9zZSB0b2tlbiBiZWZvcmUgYW4gb3BlbiB0b2tlbiksIG51bGwgaXMgcmV0dXJuZWQNCiAgICAgICAgLy8NCiAgICAgICAgLy8gZm9yIGluc3RhbmNlIGlmIG9wZW49PScoJyBhbmQgY2xvc2U9PScpJyB0aGVuIHRoZSBzZWN0aW9uIHdpbGwgZmluZA0KICAgICAgICAvLyBhIHNlY3Rpb24gZGVsaW1pdGVkIGJ5IHRoZSBmaXJzdCBmb3VuZCBvcGVuIHBhcmVudGhlc2lzIGFuZCB0aGUgbWF0Y2hpbmcNCiAgICAgICAgLy8gY2xvc2UgcGFyZW50ZXRoaXMsIHRha2luZyBpbnRvIGFjY291bnQgb3RoZXIgb3BlbmluZyBwYXJlbnRldGhpcw0KICAgICAgICAvLyBleGFtcGxlczoNCiAgICAgICAgLy8gZmluZFNlY3Rpb24oImEodGVzdCliIiwgIigiLCAiKSIpID09IHtvdXRlclN0YXJ0OiAxLCBpbm5lclN0YXJ0OjIsIGlubmVyRW5kOjYsIG91dGVyRW5kOjcsIGNoaWxkcmVuOltdfQ0KICAgICAgICAvLyBmaW5kU2VjdGlvbigiYSh0ZShzKSh0KSliIiwgIigiLCAiKSIpID09IHtvdXRlclN0YXJ0OiAxLCBpbm5lclN0YXJ0OjIsIGlubmVyRW5kOjEwLCBvdXRlckVuZDoxMSwgDQogICAgICAgIC8vICAgICAgY2hpbGRyZW46Ww0KICAgICAgICAvLyAgICAgICAgICB7b3V0ZXJTdGFydDogNCwgaW5uZXJTdGFydDo1LCBpbm5lckVuZDo2LCBvdXRlckVuZDo3LCBjaGlsZHJlbjpbXX0sDQogICAgICAgIC8vICAgICAgICAgIHtvdXRlclN0YXJ0OiA3LCBpbm5lclN0YXJ0OjgsIGlubmVyRW5kOjksIG91dGVyRW5kOjEwLCBjaGlsZHJlbjpbXX0NCiAgICAgICAgLy8gICAgICBdfQ0KICAgICAgICANCiAgICAgICAgdmFyIG9wZW5SZXN1bHQgPSB0aGlzLmZpbmQoc3RyLCBvcGVuLCBmcm9tKTsgICAgICAgIA0KICAgICAgICBpZiAob3BlblJlc3VsdCA9PSBudWxsKSB7DQogICAgICAgICAgICByZXR1cm4gbnVsbDsNCiAgICAgICAgfQ0KICAgICAgICB2YXIgY2xvc2VSZXN1bHQgPSB0aGlzLmZpbmQoc3RyLCBjbG9zZSwgZnJvbSk7ICAgICAgICANCiAgICAgICAgaWYgKGNsb3NlUmVzdWx0ID09IG51bGwgfHwgY2xvc2VSZXN1bHQuYmVnaW4gPCBvcGVuUmVzdWx0LmVuZCkgew0KICAgICAgICAgICAgcmV0dXJuIG51bGw7DQogICAgICAgIH0NCiAgICAgICAgaWYgKG9wZW5SZXN1bHQuZW5kIDw9IG9wZW5SZXN1bHQuYmVnaW4gfHwgY2xvc2VSZXN1bHQuZW5kIDw9IGNsb3NlUmVzdWx0LmJlZ2luKSB7DQogICAgICAgICAgICAvLyBlbXB0eSBtYXRjaCBhcmUgbm90IGFsbG93ZWQNCiAgICAgICAgICAgIHJldHVybiBudWxsOw0KICAgICAgICB9DQogICAgICAgIA0KICAgICAgICB2YXIgY2hpbGRyZW4gPSBbXTsNCiAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5maW5kU2VjdGlvbihzdHIsIG9wZW4sIGNsb3NlLCBvcGVuUmVzdWx0LmVuZCk7DQogICAgICAgIHdoaWxlIChjaGlsZCAhPSBudWxsKSB7DQogICAgICAgICAgICBpZiAoY2hpbGQub3V0ZXJFbmQgPiBjbG9zZVJlc3VsdC5iZWdpbikgew0KICAgICAgICAgICAgICAgIGNsb3NlUmVzdWx0ID0gdGhpcy5maW5kKHN0ciwgY2xvc2UsIGNoaWxkLm91dGVyRW5kKTsgICAgICAgIA0KICAgICAgICAgICAgICAgIGlmIChjbG9zZVJlc3VsdCA9PSBudWxsKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIHVubWF0Y2hlZCBvcGVuIHRva2VuDQogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goY2hpbGQpOw0KICAgICAgICAgICAgY2hpbGQgPSB0aGlzLmZpbmRTZWN0aW9uKHN0ciwgb3BlbiwgY2xvc2UsIGNoaWxkLm91dGVyRW5kKTsNCiAgICAgICAgfQ0KDQogICAgICAgIHJldHVybiB7DQogICAgICAgICAgICBvdXRlclN0YXJ0OiBvcGVuUmVzdWx0LmJlZ2luLA0KICAgICAgICAgICAgaW5uZXJTdGFydDogb3BlblJlc3VsdC5lbmQsDQogICAgICAgICAgICBpbm5lckVuZDogY2xvc2VSZXN1bHQuYmVnaW4sDQogICAgICAgICAgICBvdXRlckVuZDogY2xvc2VSZXN1bHQuZW5kLA0KICAgICAgICAgICAgY2hpbGRyZW46IGNoaWxkcmVuDQogICAgICAgIH07ICAgICAgICANCiAgICB9LA0KICAgIA0KICAgIG11bDogZnVuY3Rpb24gKC8qc3RyaW5nKi8gcywgLyppbnQqLyBuKSB7DQogICAgICAgIHIgPSAnJzsNCiAgICAgICAgZm9yICh2YXIgaT0wOyBpIDwgbjsgaSsrKSB7DQogICAgCQlyICs9IHM7DQogICAgCX0NCiAgICAgICAgcmV0dXJuIHI7DQogICAgfQ0KfTsNCiAgICANCnhvb2tpLmpzb24gPSB7DQogICAgICAgIGV2YWxKc29uOiBmdW5jdGlvbiAoc3RyKSB7DQogICAgICAgICAgICB0cnkgew0KICAgICAgICAgICAgICAgIHJldHVybiBldmFsKCIoIitzdHIrIikiKTsNCiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsNCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfSwNCiAgICAgICAgDQogICAgICAgIGxvYWRVUkw6IGZ1bmN0aW9uICh1cmwpIHsNCiAgICAgICAgICAgIHJldHVybiB0aGlzLmV2YWxKc29uKHhvb2tpLnVybC5sb2FkVVJMKHVybCkpOw0KICAgICAgICB9DQogICAgfTsNCg0KLy8gRGlzcGxheXMgYW4gYWxlcnQgb2YgYW4gZXhjZXB0aW9uIGRlc2NyaXB0aW9uIHdpdGggb3B0aW9uYWwgbWVzc2FnZQ0KeG9va2kud2FybiA9IGZ1bmN0aW9uKGUsIG1lc3NhZ2UpIHsNCiAgICB4b29raS5kaXNwbGF5KHhvb2tpLnN0cmluZy5leGNlcHRpb25UZXh0KGUsIG1lc3NhZ2UpLCAiI2VlY2NjYyIpOw0KfQ0KDQovLyBEaXNwbGF5cyBhbiBhbGVydCBvZiBhbiBleGNlcHRpb24gZGVzY3JpcHRpb24gd2l0aCBvcHRpb25hbCBtZXNzYWdlDQp4b29raS5lcnJvciA9IGZ1bmN0aW9uKGUsIG1lc3NhZ2UpIHsNCiAgICB4b29raS5kaXNwbGF5KHhvb2tpLnN0cmluZy5leGNlcHRpb25UZXh0KGUsIG1lc3NhZ2UpLCAiI2ZmZGRkZCIpOw0KfQ0KDQp4b29raS5pbmZvID0gZnVuY3Rpb24obWVzc2FnZSkgew0KICAgIHhvb2tpLmRpc3BsYXkobWVzc2FnZSwgIiNkZGRkZmYiKTsNCn0NCg0KeG9va2kuZGlzcGxheSA9IGZ1bmN0aW9uKG1lc3NhZ2UsIGJhY2tncm91bmQpIHsNCiAgICB2YXIgbWVzc2FnZXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktbWVzc2FnZXMnKTsNCiAgICBpZiAobWVzc2FnZXMpIHsNCiAgICAgICAgbWVzc2FnZXMuaW5uZXJIVE1MID0gJzx0YWJsZSB3aWR0aD0iMTAwJSIgYm9yZGVyPSIwIj48dHI+PHRkIGFsaWduPSJjZW50ZXIiPicrbWVzc2FnZSsnPC90ZD48L3RyPjwvdGFibGU+JzsNCiAgICAgICAgbWVzc2FnZXMuc3R5bGUuYmFja2dyb3VuZCA9IGJhY2tncm91bmQ7DQogICAgICAgIG1lc3NhZ2VzLnN0eWxlLmRpc3BsYXkgPSAiaW5saW5lIjsNCiAgICB9IGVsc2Ugew0KICAgICAgICBhbGVydChtZXNzYWdlKTsNCiAgICB9DQp9DQoNCnhvb2tpLmRlYnVnID0gZnVuY3Rpb24obWVzc2FnZSkgew0KICAgIHZhciBjb25zb2xlID0gdHlwZW9mIGRvY3VtZW50ID09ICd1bmRlZmluZWQnID8gZmFsc2UgOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktY29uc29sZScpOw0KICAgIGlmIChjb25zb2xlKSB7DQogICAgICAgIGNvbnNvbGUudmFsdWUgKz0gbWVzc2FnZSArICJcbiI7DQogICAgfSBlbHNlIHsNCiAgICAgICAgeG9va2kuY29uc29sZSArPSBtZXNzYWdlICsgIlxuIjsNCiAgICB9DQp9DQoNCnhvb2tpLmRlYnVnU2hvd0RldGFpbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7DQogICAgdmFyIGRldGFpbCA9IHR5cGVvZiBkb2N1bWVudCA9PSAndW5kZWZpbmVkJyA/IGZhbHNlIDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3hvb2tpLWRlYnVnLWRldGFpbCcpOw0KICAgIGlmIChkZXRhaWwpIHsNCiAgICAgICAgZGV0YWlsLnZhbHVlPW1lc3NhZ2U7DQogICAgfSBlbHNlIHsNCiAgICAgICAgYWxlcnQobWVzc2FnZSk7DQogICAgfQ0KfQ0KDQoNCnhvb2tpLmh0bWwgPSB7DQogICAgaGlkZTogZnVuY3Rpb24oZGl2aWQpIHsNCgkgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChkaXZpZCkuc3R5bGUuZGlzcGxheSA9ICdub25lJzsNCiAgICB9LA0KDQogICAgc2hvdzogZnVuY3Rpb24gKGRpdmlkKSB7DQoJICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZGl2aWQpLnN0eWxlLmRpc3BsYXkgPSAnJzsNCiAgICB9LA0KICAgIA0KICAgIHBhZ2VMaW5rOiBmdW5jdGlvbihwYWdlKSB7DQogICAgCWlmIChwYWdlLmlzQWJzdHJhY3QpIHsNCiAgICAJCXJldHVybiBwYWdlLnRpdGxlOw0KICAgIAl9IGVsc2Ugew0KICAgIAkJcmV0dXJuICc8YSBocmVmPSInK3B1KHBhZ2UuaWQpKyciICcrKHBhZ2UuaWQgPT0geG9va2kucGFnZS5pZD8nY2xhc3M9ImN1cnJlbnQiJzonJykrJz4nK3BhZ2UudGl0bGUrJzwvYT4nOw0KICAgIAl9DQogICAgfSwNCgkNCgkvLyBpbnNlcnQgIHRoZSBnaXZlbiAgaGVhZGVyIGluIHRoZSBodG1sIGhlYWQNCgkvLyBjYW4gYmUgdXNlZCBvbmx5IHdoZW4gdGhlIGJyb3dzZXIgaXMgc3RpbGwgaW4gdGhlIGhlYWQgIQ0KCWFkZEhlYWRlcjogZnVuY3Rpb24oLyogc3RyaW5nICovIGhlYWQpIHsNCgkJZG9jdW1lbnQud3JpdGUoaGVhZCk7DQoJfSwNCgkNCglzZXRCb2R5OiBmdW5jdGlvbiggLyogc3RyaW5nICovIGJvZHkpIHsNCgkJZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPSBib2R5Ow0KCX0NCn07DQoNCnhvb2tpLmNvbXBvbmVudCA9IHsNCiAgICBjaGlsZHJlbkxpc3Q6IGZ1bmN0aW9uICgpIHsNCiAgICAJaWYgKHhvb2tpLnBhZ2UuY2hpbGRyZW4ubGVuZ3RoID4gMCkgew0KICAgIAkJY2hpbGRyZW5MaXN0ID0gJzx1bCBjbGFzcz0iJytjc3MoJ2NoaWxkcmVuTGlzdCcpKyciPic7DQogICAgCQlmb3IgKHZhciBpIGluIHhvb2tpLnBhZ2UuY2hpbGRyZW4pIHsNCiAgICAJCQljaGlsZHJlbkxpc3QrPSc8bGk+Jyt4b29raS5odG1sLnBhZ2VMaW5rKHhvb2tpLnBhZ2UuY2hpbGRyZW5baV0pKyc8L2xpPic7DQogICAgCQl9DQogICAgCQljaGlsZHJlbkxpc3QgKz0gIjwvdWw+IjsNCiAgICAJCXJldHVybiBjaGlsZHJlbkxpc3Q7DQogICAgCX0gZWxzZSB7DQogICAgCSAgIHJldHVybiAiIjsNCiAgICAgICAgfQ0KICAgIH0sDQogICAgDQogICAgbWVudTogZnVuY3Rpb24gKCkgew0KICAgIAl2YXIgbWVudSA9ICc8dWwgaWQ9IicrY3NzKCJ0cmVlbWVudSIpKyciIGNsYXNzPSJ0cmVldmlldyI+JzsNCiAgICAJbWVudSArPSAoZnVuY3Rpb24gKHBhZ2UpIHsNCiAgICAgICAgCXZhciBtZW51ID0gJyc7DQogICAgICAgIAlmb3IgKHZhciBpIGluIHBhZ2UuY2hpbGRyZW4pIHsNCiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHBhZ2UuY2hpbGRyZW5baV0gPT0gJ29iamVjdCcpIHsNCiAgICAgICAgICAgIAkJc21lbnUgPSBhcmd1bWVudHMuY2FsbGVlKHBhZ2UuY2hpbGRyZW5baV0pOw0KICAgICAgICAgICAgCQlpZiAoc21lbnUgIT0gJycpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnUgKz0gJzxsaSBpZD0ieG9va2ktJytwYWdlLmNoaWxkcmVuW2ldLmlkKyciIGNsYXNzPSJzdWJtZW51Ij4nK3hvb2tpLmh0bWwucGFnZUxpbmsocGFnZS5jaGlsZHJlbltpXSk7DQogICAgICAgICAgICAJCQlpZiAoc21lbnUuaW5kZXhPZignaWQ9Inhvb2tpLScreG9va2kucGFnZS5pZCsnIicpICE9IC0xIA0KICAgICAgICAgICAgCQkJCXx8IHBhZ2UuY2hpbGRyZW5baV0uaWQgPT0geG9va2kucGFnZS5pZCkgew0KICAgICAgICAgICAgCQkJCS8vIGVpdGhlciBhIGRlc2NlbmRhbnQgb3IgdGhlIG5vZGUgcHJvY2Vzc2VkIGlzIHRoZSBjdXJyZW50IHBhZ2Ugbm9kZQ0KICAgICAgICAgICAgCQkJCS8vIHdlIHNwZWNpZnkgdGhhdCB0aGUgbWVudSBtdXN0IGJlIG9wZW5lZCBieSBkZWZhdWx0DQogICAgICAgICAgICAJCQkJbWVudSArPSAnPHVsIGNsYXNzPSJvcGVuIic7DQogICAgCSAgICAgICAgCQkJbWVudSArPSAnPicrc21lbnUrJzwvdWw+JzsNCiAgICAgICAgICAgIAkJCX0gZWxzZSB7DQogICAgCQkJCQkJbWVudSArPSAnPHVsIGNsYXNzPSJjbG9zZWQiJzsNCiAgICAJICAgICAgICAJCQltZW51ICs9ICc+JytzbWVudSsnPC91bD4nOw0KICAgIAkJCQkJfQ0KICAgICAgICAgICAgCQl9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgbWVudSArPSAnPGxpIGlkPSJ4b29raS0nK3BhZ2UuY2hpbGRyZW5baV0uaWQrJyI+Jyt4b29raS5odG1sLnBhZ2VMaW5rKHBhZ2UuY2hpbGRyZW5baV0pOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAJCW1lbnUgKz0gJzwvbGk+JzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgIAl9DQogICAgICAgIAlyZXR1cm4gbWVudTsNCiAgICAgICAgfSkoeG9va2kudG9jKTsNCiAgICAJbWVudSArPSAnPC91bD4nOw0KICAgIAlyZXR1cm4gbWVudTsNCiAgICB9LA0KICAgIA0KICAgIG1lc3NhZ2VzOiBmdW5jdGlvbiAoKSB7DQogICAgICAgIHJldHVybiAnPGRpdiBpZD0ieG9va2ktbWVzc2FnZXMiIG9uY2xpY2s9Inhvb2tpLmh0bWwuaGlkZShcJ3hvb2tpLW1lc3NhZ2VzXCcpIiBzdHlsZT0iekluZGV4Ojk5OTtkaXNwbGF5Om5vbmU7cG9zaXRpb246YWJzb2x1dGU7dG9wOjMwcHg7cGFkZGluZzoxMHB4O2JvcmRlci1zdHlsZTpzb2xpZDtiYWNrZ3JvdW5kOiNlZWVlZWU7Ij48L2Rpdj4nOw0KICAgIH0sDQoNCiAgICBkZWJ1Z1BhbmVsOiBmdW5jdGlvbiAoKSB7DQogICAgICAgIHJldHVybiAnPGRpdiBpZD0ieG9va2ktZGVidWciIHN0eWxlPSJkaXNwbGF5Om5vbmU7bWFyZ2luLXRvcDoxNXB4O3BhZGRpbmc6MTBweDtib3JkZXItc3R5bGU6c29saWQ7YmFja2dyb3VuZDojZWVlZWVlOyI+PHN0cm9uZz5Yb29raSBDb25zb2xlPC9zdHJvbmc+PGJyLz48dGV4dGFyZWEgY29scz0iMTAwIiByb3dzPSIxNSIgaWQ9Inhvb2tpLWNvbnNvbGUiPicreG9va2kuY29uc29sZSsnPC90ZXh0YXJlYT48aHIvPjxhIGhyZWY9ImphdmFzY3JpcHQ6eG9va2kuZGVidWdTaG93RGV0YWlsKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwneG9va2ktYm9keVwnKS5pbm5lckhUTUwpIj5jb250ZW50PC9hPiA8YSBocmVmPSJqYXZhc2NyaXB0Onhvb2tpLmRlYnVnU2hvd0RldGFpbCh4b29raS5jLmJvZHkpIj54b29raSBib2R5PC9hPiA8YSBocmVmPSJqYXZhc2NyaXB0Onhvb2tpLmRlYnVnU2hvd0RldGFpbChkb2N1bWVudC5ib2R5LmlubmVySFRNTCkiPndob2xlIGJvZHk8L2E+IDxhIGhyZWY9ImphdmFzY3JpcHQ6eG9va2kuYWN0aW9uLmV2YWx1YXRlKCkiPmV2YWx1YXRlPC9hPjxici8+PHRleHRhcmVhIGNvbHM9IjEwMCIgcm93cz0iMTUiIGlkPSJ4b29raS1kZWJ1Zy1kZXRhaWwiPjwvdGV4dGFyZWE+PC9kaXY+JzsNCiAgICB9LA0KDQogICAgcHJpbnRlckZyaWVuZGx5TG9jYXRpb246IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgcmV0dXJuIHhvb2tpLnVybC5hY3Rpb24oInByaW50Iik7DQogICAgfSwNCg0KICAgIHByaW50ZXJGcmllbmRseUxpbms6IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgcmV0dXJuICc8YSBocmVmPSInK3RoaXMucHJpbnRlckZyaWVuZGx5TG9jYXRpb24oKSsnIj4nK3QoJ1ByaW50ZXIgRnJpZW5kbHknKSsnPC9hPic7DQogICAgfSwNCg0KICAgIGJyZWFkQ3J1bWI6IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgdmFyIGJyZWFkQ3J1bWIgPSAnPHNwYW4gY2xhc3M9ImJyZWFkQ3J1bWIiPic7DQoJCWJyZWFkQ3J1bWIgKz0gKGZ1bmN0aW9uIChwYWdlKSB7DQogICAgICAgIAl2YXIgYnJlYWRDcnVtYiA9IHhvb2tpLmh0bWwucGFnZUxpbmsocGFnZSk7DQoJCQlpZiAocGFnZS5tZXRhLmxldmVsID49IDEpIHsNCgkJCQlicmVhZENydW1iID0gYXJndW1lbnRzLmNhbGxlZShwYWdlLm1ldGEucGFyZW50KSArICIgJmd0OyAiICsgYnJlYWRDcnVtYjsNCgkJCX0NCiAgICAgICAgCXJldHVybiBicmVhZENydW1iOw0KICAgICAgICB9KSh4b29raS5wYWdlKTsNCgkJYnJlYWRDcnVtYiArPSAnPC9zcGFuPic7DQoJCXJldHVybiBicmVhZENydW1iOw0KICAgIH0NCn07DQoNCnhvb2tpLnJlbmRlciA9IHt9Ow0KeG9va2kucmVuZGVyLnByaW50ZXJGcmllbmRseUFzeW5jTG9hZGVyID0gZnVuY3Rpb24oc291cmNlLCBhcnIpIHsNCgl2YXIgcm9vdCA9IGFyclswXTsNCgl2YXIgcGFnZSA9IGFyclsxXTsNCiAgICBpZiAoc291cmNlID09IG51bGwpIHsNCiAgICAgICAgcmV0dXJuOw0KICAgIH0NCgl2YXIgbGV2ZWwgPSBwYWdlLm1ldGEubGV2ZWwgLSByb290Lm1ldGEubGV2ZWwgKyAxOw0KCQ0KICAgIC8vIGNvbXB1dGUgcHJpbnRlciBmcmllbmRseSBibG9jaw0KICAgIHZhciBiZWdpbkluZGV4ID0gc291cmNlLmluZGV4T2YoJzx0ZXh0YXJlYSBpZD0ieG9va2ktc291cmNlIj4nKTsNCiAgICBiZWdpbkluZGV4ICs9ICc8dGV4dGFyZWEgaWQ9Inhvb2tpLXNvdXJjZSI+Jy5sZW5ndGg7DQogICAgdmFyIGVuZEluZGV4ID0gc291cmNlLmxhc3RJbmRleE9mKCc8L3RleHRhcmVhPicpOw0KICAgIHNvdXJjZSA9IHNvdXJjZS5zdWJzdHJpbmcoYmVnaW5JbmRleCwgZW5kSW5kZXgpOw0KICAgIA0KICAgIHZhciBwcmludGVyRnJpZW5kbHkgPSAiPGgiK2xldmVsKyI+IitwYWdlLnRpdGxlKyI8L2giK2xldmVsKyI+IjsNCiAgICBwcmludGVyRnJpZW5kbHkgKz0geG9va2kuaW5wdXQuZm9ybWF0Lm1haW4oc291cmNlKSArICI8aHIvPiI7DQogICAgLy8gaW5qZWN0IGJsb2NrIGluIHBhZ2UNCiAgICB2YXIgcGYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktcHJpbnRlckZyaWVuZGx5Jyk7DQogICAgcGYuaW5uZXJIVE1MICs9IHByaW50ZXJGcmllbmRseTsgICAgDQogICAgDQogICAgLy8gY29udGludWUgcmVjdXJzaXZlIGxvYWRpbmcNCiAgIAl2YXIgbmV4dFBhZ2UgPSB4b29raS50b2MuZ2V0TmV4dFBhZ2UocGFnZSwgcm9vdCk7DQogICAJaWYgKG5leHRQYWdlICE9IG51bGwpIHsNCiAgICAJeG9va2kudXJsLmFzeW5jTG9hZFVSTChwdShuZXh0UGFnZS5pZCksIHhvb2tpLnJlbmRlci5wcmludGVyRnJpZW5kbHlBc3luY0xvYWRlciwgW3Jvb3QsIG5leHRQYWdlXSk7DQogICAJfQ0KfTsNCnhvb2tpLnJlbmRlci5wcmludGVyRnJpZW5kbHkgPSBmdW5jdGlvbigpIHsNCiAgICBmb3IgKHZhciBrIGluIHhvb2tpLmNvbXBvbmVudCkgew0KICAgICAgICB4b29raS5jW2tdID0geG9va2kuY29tcG9uZW50W2tdKCk7DQogICAgfQ0KICAgIA0KCXhvb2tpLmMuYm9keSA9IHhvb2tpLmMubWVzc2FnZXMNCgkrICI8ZGl2IGlkPSd4b29raS1wcmludGVyRnJpZW5kbHknPjwvZGl2PiIgLy8gZGl2IHdoZXJlIHByaW50ZXIgZnJpZW5kbHkgY29udGVudCB3aWxsIGJlIHB1dA0KICAgICsgeG9va2kuYy5kZWJ1Z1BhbmVsOw0KICAgIA0KICAgIGRvY3VtZW50LmJvZHkuaW5uZXJIVE1MID0geG9va2kuc3RyaW5nLnByb2Nlc3NUZW1wbGF0ZSh4b29raS50ZW1wbGF0ZS5ib2R5LCB4b29raS5jKTsNCiAgICANCiAgICAvLyBzdGFydCBhc3luYyBsb2FkaW5nIG9mIGNvbnRlbnQNCiAgICB4b29raS51cmwuYXN5bmNMb2FkVVJMKHB1KHhvb2tpLnBhZ2UuaWQpLCB4b29raS5yZW5kZXIucHJpbnRlckZyaWVuZGx5QXN5bmNMb2FkZXIsIFt4b29raS5wYWdlLCB4b29raS5wYWdlXSk7DQp9Ow0KDQp4b29raS5yZW5kZXIucGFnZSA9IGZ1bmN0aW9uKCkgew0KICAgIC8vIHJlYWxpemUgYWxsIGNvbXBvbmVudHMgYXZhaWxhYmxlDQogICAgZm9yICh2YXIgayBpbiB4b29raS5jb21wb25lbnQpIHsNCiAgICAgICAgeG9va2kuY1trXSA9IHhvb2tpLmNvbXBvbmVudFtrXSgpOw0KICAgIH0NCiAgICANCiAgICB4b29raS5pbnB1dC5zb3VyY2UoKTsNCiAgICANCiAgICBpZiAoeG9va2kuYy5hbGxvd0VkaXQpIHsNCiAgICAJeG9va2kuYy5ib2R5ID0geG9va2kuYy5tZXNzYWdlcw0KICAgICAgICAgICAgKyB4b29raS5jLnRvb2xiYXINCiAgICAgICAgICAgICsgJzxkaXYgaWQ9Inhvb2tpLWNvbnRlbnQiPicgDQogICAgICAgICAgICAgICAgKyAnPGRpdiBpZD0ieG9va2ktYm9keSI+PC9kaXY+Jw0KICAgICAgICAgICAgKyAnPC9kaXY+Jw0KICAgICAgICAgICAgKyB4b29raS5jLmVkaXRab25lDQogICAgICAgICAgICArIHhvb2tpLmMuZGVidWdQYW5lbDsNCiAgICB9IGVsc2Ugew0KICAgIAl4b29raS5jLmJvZHkgPSB4b29raS5jLm1lc3NhZ2VzDQogICAgICAgICAgICArICc8ZGl2IGlkPSJ4b29raS1jb250ZW50Ij4nIA0KICAgICAgICAgICAgICAgICsgJzxkaXYgaWQ9Inhvb2tpLWJvZHkiPjwvZGl2PicNCiAgICAgICAgICAgICsgJzwvZGl2PicNCiAgICAgICAgICAgICsgeG9va2kuYy5kZWJ1Z1BhbmVsOw0KICAgIH0NCg0KICAgIHhvb2tpLmh0bWwuc2V0Qm9keSh4b29raS5zdHJpbmcucHJvY2Vzc1RlbXBsYXRlKHhvb2tpLnRlbXBsYXRlLmJvZHksIHhvb2tpLmMpKTsNCiAgICANCiAgICB4b29raS5pbnB1dC5hcHBseUNoYW5nZXMoKTsNCn07DQoNCnhvb2tpLnJlbmRlci5tYWluID0gZnVuY3Rpb24oKSB7DQogICAgaWYgKHhvb2tpLmMuYWN0aW9uID09ICJwcmludCIpIHsNCiAgICAgICAgLy8gcmVuZGVyIHRoZSBwcmludGVyIGZyaWVuZGx5IHZlcnNpb24gb2YgdGhlIHBhZ2UNCiAgICAgICAgdGhpcy5wcmludGVyRnJpZW5kbHkoKTsNCiAgICB9IGVsc2Ugew0KICAgICAgICAvLyByZW5kZXIgdGhlIHBhZ2Ugbm9ybWFsbHkNCiAgICAgICAgdGhpcy5wYWdlKCk7DQogICAgfQ0KfTsNCg0KeG9va2kuaW5wdXQgPSB7DQogICAgc291cmNlOiBmdW5jdGlvbigpIHsNCiAgICAgICAgaWYgKHR5cGVvZiBkb2N1bWVudCAhPSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktc291cmNlJykgIT0gbnVsbCkgew0KICAgICAgICAgICAgdGhpcy5fc291cmNlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3hvb2tpLXNvdXJjZScpLnZhbHVlOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiB0aGlzLl9zb3VyY2U7DQogICAgfSwNCiAgICBwcm9jZXNzZWQ6IGZ1bmN0aW9uKCkgew0KICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXQubWFpbih0aGlzLnNvdXJjZSgpKTsNCiAgICB9LA0KICAgIA0KICAgIGZvcm1hdDogew0KICAgICAgICBnZXRJbnB1dEZpbHRlcnM6IGZ1bmN0aW9uIChpbnB1dEZvcm1hdCkgew0KICAgICAgICAgICAgcmV0dXJuIHhvb2tpLmNbaW5wdXRGb3JtYXQrIklucHV0Rm9ybWF0Il07DQogICAgICAgIH0sDQogICAgICAgIGRlZmluZTogZnVuY3Rpb24gKGlucHV0Rm9ybWF0LCBmaWx0ZXJzKSB7DQogICAgICAgICAgICAvLyBkZWZpbmUgYSBuZXcgaW5wdXRGb3JtYXQNCiAgICAgICAgICAgIC8vIGlucHV0Rm9ybWF0OiB0aGUgbmV3IGlucHV0IGZvcm1hdCBuYW1lDQogICAgICAgICAgICAvLyBmaWx0ZXJzOiBhbiBhcnJheSBvZiBpbnB1dCBmaWx0ZXIgbmFtZXMNCiAgICAgICAgICAgIHhvb2tpLmNbaW5wdXRGb3JtYXQrIklucHV0Rm9ybWF0Il0gPSBmaWx0ZXJzOw0KICAgICAgICB9LA0KICAgICAgICBtYWluOiBmdW5jdGlvbihzb3VyY2UpIHsNCiAgICAgICAgICAgIC8vIGZvcm1hdHMgYW4gaW5wdXQgc291cmNlDQogICAgICAgICAgICBpZiAoeG9va2kuYy5pbnB1dEZvcm1hdCAmJiB0eXBlb2YgdGhpcy5nZXRJbnB1dEZpbHRlcnMoeG9va2kuYy5pbnB1dEZvcm1hdCkgIT0gInVuZGVmaW5lZCIpIHsNCiAgICAgICAgICAgICAgICBmb3JtYXQgPSB4b29raS5jLmlucHV0Rm9ybWF0Ow0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBmb3JtYXQgPSB4b29raS5jLmRlZmF1bHRJbnB1dEZvcm1hdDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGZpbHRlcnMgPSB0aGlzLmdldElucHV0RmlsdGVycyhmb3JtYXQpOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBmaWx0ZXJzKSB7DQogICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBmaWx0ZXJzW2ldID09ICdzdHJpbmcnKSB7DQogICAgCQkJCXhvb2tpLmRlYnVnKCdwcm9jZXNzaW5nIGZpbHRlciAnK2ZpbHRlcnNbaV0pOw0KICAgICAgICAgICAgICAgICAgICBmID0geG9va2kuaW5wdXQuZmlsdGVyc1tmaWx0ZXJzW2ldXTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBmID09ICJmdW5jdGlvbiIpIHsNCiAgICAgICAgICAgICAgICAgICAgCXRyeSB7DQogICAgICAgICAgICAgICAgICAgICAgICAJc291cmNlID0gZihzb3VyY2UpOyAvLyBwcm9jZXNzIGZpbHRlcg0KICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgew0KICAgIAkgICAgICAgICAgICAgICAgICAgIHhvb2tpLmVycm9yKGUsIHQoImVycm9yIG9jY3VyZWQgd2hpbGUgcHJvY2Vzc2luZyBmaWx0ZXIgJHswfSIsIGZpbHRlcnNbaV0pKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHhvb2tpLmVycm9yKHQoInVua25vd24gZmlsdGVyICR7MH0gdXNlZCBpbiBpbnB1dCBmb3JtYXQgJHsxfSIsIGZpbHRlcnNbaV0sIGZvcm1hdCkpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIHNvdXJjZTsNCiAgICAgICAgfQ0KICAgIH0sIA0KICAgIA0KICAgIGZpbHRlcnM6IHsNCiAgICAgICAgdXJsOiBmdW5jdGlvbiAoaW5wdXQpIHsNCiAgICAgICAgICAgIC8vIGhhbmRsZSB1cmxzDQogICAgICAgICAgICByZXR1cm4gaW5wdXQucmVwbGFjZShuZXcgUmVnRXhwKCIoPzpmaWxlfGh0dHB8aHR0cHN8bWFpbHRvfGZ0cCk6W15cXHMnXCJdKyg/Oi98XFxiKSIsICJnIiksIGZ1bmN0aW9uIChzdHIsIG9mZnNldCwgcykgew0KICAgICAgICAgICAgICAgIHZhciBiZWZvcmUgPSBzLnN1YnN0cmluZygwLG9mZnNldCk7DQogICAgICAgICAgICAgICAgaWYgKGJlZm9yZS5tYXRjaCgvKGhyZWZ8c3JjKT0iJC8pKSB7DQogICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHI7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICc8YSBocmVmPSInK3N0cisnIj4nK3N0cisnPC9hPic7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSk7DQogICAgICAgIH0sDQogICAgICAgIA0KICAgICAgICBzaG9ydGN1dHM6IGZ1bmN0aW9uIChpbnB1dCkgew0KICAgICAgICAgICAgLy8gaGFuZGxlIHNob3J0Y3V0IGxpbmtzIGxpa2UgdGhpczoNCiAgICAgICAgICAgIC8vICAgIFtbc3ZuOmJ1aWxkLnhtbF1dID0+IDxhIGhyZWY9Imh0dHBzOi8veG9va2kuc3ZuLnNvdXJjZWZvcmdlLm5ldC9zdm5yb290L3hvb2tpL3RydW5rL2J1aWxkLnhtbCI+YnVpbGQueG1sPC9hPg0KICAgICAgICAgICAgLy8gICAgW1tzdm46dGVzdC9leGFtcGxlLmpzIGEgZ29vZCBleGFtcGxlXV0gPT4gPGEgaHJlZj0iaHR0cHM6Ly94b29raS5zdm4uc291cmNlZm9yZ2UubmV0L3N2bnJvb3QveG9va2kvdHJ1bmsvdGVzdC9leGFtcGxlLmpzIj5hIGdvb2QgZXhhbXBsZTwvYT4NCiAgICAgICAgICAgIC8vIG5lZWRzIHRvIGJlIGNvbmZpZ3VyZWQgaW4geG9va2kgY29uZmlnIGxpa2UgdGhpcw0KICAgICAgICAgICAgLy8gICAgICB4b29raS5jLnNob3J0Y3V0cy48YW55IHNob3J0Y3V0Pi51cmwgPSBiYXNlIHVybCBvZiB0aGUgc2hvcnRjdXQuIA0KICAgICAgICAgICAgLy8gICAgICBleDogeG9va2kuYy5zaG9ydGN1dHMuc3ZuLnVybCA9IGh0dHBzOi8veG9va2kuc3ZuLnNvdXJjZWZvcmdlLm5ldC9zdm5yb290L3hvb2tpL3RydW5rLw0KICAgICAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UobmV3IFJlZ0V4cCgiXFxbXFxbKFteOlxuXSspOihbXlxcXVxuXSspXFxdXFxdIiwgImciKSwgZnVuY3Rpb24gKHN0ciwgcHJlZml4LCBjb2RlLCBvZmZzZXQsIHMpIHsNCiAgICAgICAgICAgIAlpZiAodHlwZW9mIHhvb2tpLmMuc2hvcnRjdXRzID09ICJ1bmRlZmluZWQiIHx8IHR5cGVvZiB4b29raS5jLnNob3J0Y3V0c1twcmVmaXhdID09ICJ1bmRlZmluZWQiKSB7DQogICAgICAgICAgICAgICAgICAgIHhvb2tpLmRlYnVnKCd1bmtub3duIHNob3J0Y3V0ICcrcHJlZml4KTsNCiAgICAgICAgICAgIAkJcmV0dXJuIHN0cjsNCiAgICAgICAgICAgIAl9DQogICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gY29kZS5pbmRleE9mKCcgJyk7DQogICAgICAgICAgICAgICAgdmFyIHBhdGggPSBpbmRleD4wP2NvZGUuc3Vic3RyaW5nKDAsaW5kZXgpOmNvZGU7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgdmFyIHRpdGxlID0gaW5kZXg+MD9jb2RlLnN1YnN0cmluZyhpbmRleCsxKTpwYXRoOw0KICAgICAgICAgICAgICAgIHZhciBwcmUgPSB0eXBlb2YgeG9va2kuYy5zaG9ydGN1dHNbcHJlZml4XS5wcmUgPT0gInVuZGVmaW5lZCI/Jyc6eG9va2kuYy5zaG9ydGN1dHNbcHJlZml4XS5wcmU7DQogICAgICAgICAgICAgICAgdmFyIHBvc3QgPSB0eXBlb2YgeG9va2kuYy5zaG9ydGN1dHNbcHJlZml4XS5wb3N0ID09ICJ1bmRlZmluZWQiPycnOnhvb2tpLmMuc2hvcnRjdXRzW3ByZWZpeF0ucG9zdDsNCiAgICAgICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9IicrcHJlK3BhdGgrcG9zdCsnIj4nK3RpdGxlKyc8L2E+JzsNCiAgICAgICAgICAgIH0pOw0KICAgICAgICB9LA0KICAgICAgICANCiAgICAgICAgeG9va2lMaW5rczogZnVuY3Rpb24gKGlucHV0KSB7DQogICAgICAgICAgICAvLyBoYW5kbGUgeG9va2kgbGlua3MgbGlrZSB0aGlzOg0KICAgICAgICAgICAgLy8gICAgW1twYWdlL2lkXV0NCiAgICAgICAgICAgIC8vICAgIFtbcGFnZS9pZCBNeSBUaXRsZV1dDQogICAgICAgICAgICByZXR1cm4gaW5wdXQucmVwbGFjZShuZXcgUmVnRXhwKCJcXFtcXFsoW15cXF1dKylcXF1cXF0iLCAiZyIpLCBmdW5jdGlvbiAoc3RyLCBjb2RlLCBvZmZzZXQsIHMpIHsNCiAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBjb2RlLmluZGV4T2YoJyAnKTsNCiAgICAgICAgICAgICAgICB2YXIgaWQgPSAoaW5kZXg+MD9jb2RlLnN1YnN0cmluZygwLGluZGV4KTpjb2RlKTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICB2YXIgdGl0bGU7DQogICAgICAgICAgICAgICAgdmFyIHVybDsNCiAgICAgICAgICAgICAgICB2YXIgaW52YWxpZCA9IGZhbHNlOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgeG9va2kudG9jLnBhZ2VzW3hvb2tpLnRvYy5pbXBvcnRSb290ICsgaWRdICE9ICJ1bmRlZmluZWQiKSB7DQogICAgICAgICAgICAgICAJICAgIHRpdGxlID0geG9va2kudG9jLnBhZ2VzW3hvb2tpLnRvYy5pbXBvcnRSb290ICsgaWRdLnRpdGxlOw0KICAgICAgICAgICAgICAgICAgICB1cmwgPSBwdSh4b29raS50b2MuaW1wb3J0Um9vdCArIGlkKTsNCiAgICAgICAgICAgICAgIAl9IGVsc2UgaWYgKHhvb2tpLnRvYy5pbXBvcnRSb290Lmxlbmd0aCA+IDAgJiYgdHlwZW9mIHhvb2tpLnRvYy5wYWdlc1tpZF0gIT0gInVuZGVmaW5lZCIpIHsNCiAgICAgICAgICAgICAgIAkgICAgdGl0bGUgPSB4b29raS50b2MucGFnZXNbaWRdLnRpdGxlOw0KICAgICAgICAgICAgICAgICAgICB1cmwgPSBwdShpZCk7DQogICAgICAgICAgICAgICAJfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgaW52YWxpZCA9IHRydWU7DQogICAgICAgICAgICAgICAJCXRpdGxlID0gY29kZTsNCiAgICAgICAgICAgICAgIAkJdXJsID0gdShpZCk7DQogICAgICAgICAgICAgICAJfQ0KICAgICAgICAgICAgICAgIGlmIChpbmRleD4wKSB7DQogICAgICAgICAgICAgICAgCXRpdGxlID0gY29kZS5zdWJzdHJpbmcoaW5kZXgrMSk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmIChpbnZhbGlkKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChiYXRjaE1vZGUpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdCBvdXRwdXQgaW52YWxpZCBsaW5rcyBhcyBsaW5rcyBpbiBiYXRjaCBtb2RlDQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGl0bGU7DQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGl0bGUrJzxhIGhyZWY9IicrdXJsKyciPj88L2E+JzsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIHJldHVybiAnPGEgaHJlZj0iJyt1cmwrJyI+Jyt0aXRsZSsnPC9hPic7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSk7DQogICAgICAgIH0sDQogICAgICAgIA0KICAgICAgICB3aWtpTWFya3VwOiBmdW5jdGlvbiAoaW5wdXQpIHsgDQogICAgICAgICAgICAvLyBoYW5kbGUgYm9sZA0KICAgICAgICAgICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKG5ldyBSZWdFeHAoIlxcKihbXlxuXSspXFwqIiwgImciKSwgIjxiPiQxPC9iPiIpOw0KICAgICAgICAgICAgDQogICAgICAgICAgICAvLyBoYW5kbGUgaXRhbGljDQogICAgICAgICAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UobmV3IFJlZ0V4cCgiXFxfKFteXG5dKylcXF8iLCAiZyIpLCAiPGVtPiQxPC9lbT4iKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgcmV0dXJuIGlucHV0Ow0KICAgICAgICB9LA0KICAgICAgICANCiAgICAgICAgamlyYTogZnVuY3Rpb24gKGlucHV0KSB7IA0KICAgICAgICAgICAgLy8gYXV0byByZXBsYWNlIGppcmEgaXNzdWUgaWRzIChsaWtlIElWWS0xMikgYnkgYSBsaW5rIHRvIHRoZSBpc3N1ZQ0KICAgICAgICAgICAgLy8gbmVlZHMgdG8gYmUgY29uZmlndXJlZCBpbiB4b29raSBjb25maWcgbGlrZSB0aGlzDQogICAgICAgICAgICAvLyAgICAgIHhvb2tpLmMuamlyYS5pZHMgPSBhbiBhcnJheSBvZiBqaXJhIHByb2plY3RzIGlkcyAoZXg6IFsiSVZZIiwgIkFOVCJdKQ0KICAgICAgICAgICAgLy8gICAgICB4b29raS5jLmppcmEudXJsID0gdGhlIHVybCBvZiB0aGUgamlyYSBzZXJ2ZXIgKGV4OiAiaHR0cDovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEiKQ0KICAgICAgICAgICAgaWYgKHR5cGVvZiB4b29raS5jLmppcmEgIT0gIm9iamVjdCIpIHsNCiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXQ7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UobmV3IFJlZ0V4cCgiKCgiK3hvb2tpLmMuamlyYS5pZHMuam9pbigifCIpKyIpLVxcZCspKFteXCJcXGRdKSIsICJnIiksICc8YSBocmVmPSInK3hvb2tpLmMuamlyYS51cmwrJy9icm93c2UvJDEiPiQxPC9hPiQzJyk7DQogICAgICAgICAgICANCiAgICAgICAgICAgIHJldHVybiBpbnB1dDsNCiAgICAgICAgfSwNCiAgICAgICAgDQogICAgICAgIGNvZGU6IGZ1bmN0aW9uIChpbnB1dCkgew0KICAgICAgICAgICAgY29kZVNlY3Rpb24gPSB4b29raS5zdHJpbmcuZmluZFhtbFNlY3Rpb24oaW5wdXQsICJjb2RlIik7DQogICAgICAgICAgICBmcm9tID0gMDsNCiAgICAgICAgICAgIHdoaWxlIChjb2RlU2VjdGlvbiAhPSBudWxsKSB7DQogICAgICAgICAgICAgICAgcHJvY2Vzc2VkU2VjdGlvbiA9ICI8cHJlPiIgDQogICAgICAgICAgICAgICAgICAgICsgaW5wdXQuc3Vic3RyaW5nKGNvZGVTZWN0aW9uLmlubmVyU3RhcnQsIGNvZGVTZWN0aW9uLmlubmVyRW5kKS5yZXBsYWNlKC88L2csICImbHQ7IikucmVwbGFjZSgvPi9nLCAiJmd0OyIpIC8vIC5yZXBsYWNlKC9cbi9nLCAiPGJyLz4iKQ0KICAgICAgICAgICAgICAgICAgICArICI8L3ByZT4iOw0KICAgICAgICAgICAgICAgIGlucHV0ID0gaW5wdXQuc3Vic3RyaW5nKDAsIGNvZGVTZWN0aW9uLm91dGVyU3RhcnQpDQogICAgICAgICAgICAgICAgICAgICsgcHJvY2Vzc2VkU2VjdGlvbg0KICAgICAgICAgICAgICAgICAgICArIGlucHV0LnN1YnN0cmluZyhjb2RlU2VjdGlvbi5vdXRlckVuZCk7DQogICAgICAgICAgICAgICAgZnJvbSA9IGNvZGVTZWN0aW9uLm91dGVyU3RhcnQgKyBwcm9jZXNzZWRTZWN0aW9uLmxlbmd0aDsNCiAgICANCiAgICAgICAgICAgICAgICBjb2RlU2VjdGlvbiA9IHhvb2tpLnN0cmluZy5maW5kWG1sU2VjdGlvbihpbnB1dCwgImNvZGUiLCBmcm9tKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHJldHVybiBpbnB1dDsNCiAgICAgICAgfSwNCiAgICAgICAgDQogICAgICAgIGxpbmVCcmVhazogZnVuY3Rpb24gKGlucHV0KSB7DQogICAgICAgICAgICByZXR1cm4gaW5wdXQucmVwbGFjZShuZXcgUmVnRXhwKCJccj9cbiIsICJnIiksIGZ1bmN0aW9uIChzdHIsIG9mZnNldCwgcykgew0KICAgICAgICAgICAgICAgIHZhciBiZWZvcmUgPSBzLnN1YnN0cmluZygwLG9mZnNldCk7DQogICAgICAgICAgICAgICAgdmFyIGFmdGVyID0gcy5zdWJzdHJpbmcob2Zmc2V0K3N0ci5sZW5ndGgpOw0KICAgICAgICAgICAgICAgIGlmIChhZnRlci5tYXRjaCgvXjxcLz8odWx8dGFibGV8bGl8cHJlfGRpdikoXHMqXHcrPSJbXiJdKyIpKlxzKj4vaSkgfHwgKGJlZm9yZS5tYXRjaCgvPFwvP1x3Kyhccypcdys9IlteIl0rIikqXHMqXC8/PlxzKiQvaSkgJiYgIWJlZm9yZS5tYXRjaCgvPFwvPyhhfGJ8c3Ryb25nfGVtfGl8YmlnfGJyIGNsYXNzPSJ4b29raS1iciIpKFxzKlx3Kz0iW14iXSsiKSpccypcLz8+XHMqJC9pKSkpIHsgDQogICAgICAgICAgICAgICAgICAgIHJldHVybiAnXG4nOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIHJldHVybiAnPGJyIGNsYXNzPSJ4b29raS1iciIvPic7IC8vIHRoZSBjbGFzcyBpcyBub3QgcmVhbGx5IG5lY2Vzc2FyeSBidXQgYWxsb3cgdG8gZGlzdGluZ3Vpc2ggZ2VuZXJhdGVkIGJyIGZyb20gaW5wdXQgb25lDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSk7DQogICAgICAgIH0sDQogICAgICAgIA0KICAgICAgICBpbmNsdWRlczogZnVuY3Rpb24gKGlucHV0KSB7DQoJICAgICAgICAvL1s8dXJsPl0gcmVwbGFjZWQgYnkgdGhlIGNvbnRlbnQgb2YgdGhlIHVybA0KCSAgICAgICAgcmVzdWx0ID0gIiI7DQoJICAgICAgICBsYXN0U3RhcnQgPSAwOw0KCSAgICAgICAgbmV4dFBvcyA9IGlucHV0LmluZGV4T2YoIls8IiAsIGxhc3RTdGFydCk7DQoJICAgICAgICB3aGlsZSggbmV4dFBvcyA+IDAgKSB7DQoJCSAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgaW5wdXQuc2xpY2UobGFzdFN0YXJ0LG5leHRQb3MpOw0KCQkgICAgICAgIGxhc3RTdGFydCA9IG5leHRQb3M7DQoJCSAgICAgICAgbmV4dFBvcyA9IGlucHV0LmluZGV4T2YoIj5dIiAsIGxhc3RTdGFydCk7DQoJCSAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgeG9va2kudXJsLmxvYWRVUkwobHUoaW5wdXQuc2xpY2UobGFzdFN0YXJ0KzIsbmV4dFBvcykpKTsNCgkJICAgICAgICBsYXN0U3RhcnQgPSBuZXh0UG9zICsgMjsNCgkJICAgICAgICBuZXh0UG9zID0gaW5wdXQuaW5kZXhPZigiWzwiICwgbGFzdFN0YXJ0KTsNCgkgICAgICAgIH0NCiAgICAgICAgICAgIHJldHVybiByZXN1bHQgKyBpbnB1dC5zbGljZShsYXN0U3RhcnQpOw0KICAgICAgICB9DQogICAgfSwNCiAgICANCiAgICANCiAgICBhcHBseUNoYW5nZXM6IGZ1bmN0aW9uKCkgew0KICAgIAlkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktYm9keScpLmlubmVySFRNTCA9IHhvb2tpLmlucHV0LnByb2Nlc3NlZCgpOw0KICAgIH0NCn07DQoNCg0KeG9va2kucG9zdFByb2Nlc3MgPSBmdW5jdGlvbigpIHsNCgl4b29raS5yZW5kZXIubWFpbigpOw0KCXdpbmRvdy5vbmtleXByZXNzID0ga2V5Q3RybDsNCn07DQoNCg0KaWYgKHR5cGVvZiB4b29raS5pbyA9PSAidW5kZWZpbmVkIikgew0KICAgIHhvb2tpLmlvID0ge307DQp9DQoNCg0KeG9va2kuYWN0aW9uID0ge30NCnhvb2tpLmFjdGlvbi50b2dnbGVEZWJ1ZyA9IGZ1bmN0aW9uKCkgew0KICAgIGlmICh4b29raS5jLmRlYnVnKSB7DQogICAgCWlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktZGVidWcnKS5zdHlsZS5kaXNwbGF5ID09ICdub25lJykgew0KICAgIAkJeG9va2kuaHRtbC5zaG93KCd4b29raS1kZWJ1ZycpOw0KICAgIAl9IGVsc2Ugew0KICAgIAkJeG9va2kuaHRtbC5oaWRlKCd4b29raS1kZWJ1ZycpOw0KICAgIAl9DQoJfQ0KfQ0KeG9va2kuYWN0aW9uLmV2YWx1YXRlID0gZnVuY3Rpb24gKCkgew0KICAgIHZhciBleHAgPSBwcm9tcHQoIlBsZWFzZSBlbnRlciBqYXZhc2NyaXB0IGV4cHJlc3Npb24gdG8gZXZhbHVhdGUiKTsNCiAgICB4b29raS5kZWJ1Z1Nob3dEZXRhaWwoZXZhbChleHApKTsNCn0NCg0KLy8gVE9ETywgcmV2aWV3IHVzZSByZWdpc3RyYXRpb24NCmZ1bmN0aW9uIGtleUN0cmwoZXZ0KSB7DQoJdmFyIGNvZGUgPSB4b29raS5jLmJyb3dzZXIuTlMgPyBldnQud2hpY2ggOiBldmVudC5rZXlDb2RlOw0KCXZhciBjdHJsID0geG9va2kuYy5icm93c2VyLk5TID8gZXZ0LmN0cmxLZXkgOiBldmVudC5jdHJsS2V5Ow0KICAJdmFyIGtleSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZSk7DQoJaWYgKHhvb2tpLmMuZGVidWcgJiYgY3RybCAmJiAiZCIgPT0ga2V5KSB7DQoJCXhvb2tpLmFjdGlvbi50b2dnbGVEZWJ1ZygpOw0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KCWlmICh4b29raS5jLmFsbG93RWRpdCAmJiBjdHJsICYmICJzIiA9PSBrZXkpIHsNCgkJeG9va2kuYWN0aW9uLnNhdmVDaGFuZ2VzKCk7DQoJCXJldHVybiBmYWxzZTsNCgl9DQoJaWYgKHhvb2tpLmMuYWxsb3dFZGl0ICYmIGN0cmwgJiYgImUiID09IGtleSkgew0KCQl4b29raS5hY3Rpb24udG9nZ2xlRWRpdCgpOw0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KfQ0KDQovLyB4b29raSBlbmdpbmUgaW5pdCBmdW5jdGlvbg0KeG9va2kuaW5pdCA9IGZ1bmN0aW9uKCkgew0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8gY29uZmlnIGluaXQNCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQogICAgaW5pdENvbmZpZ1Byb3BlcnR5ID0gZnVuY3Rpb24ocHJvcCwgdmFsdWUsIGRlZmF1bHRWYWx1ZSkgew0KICAgICAgICBpZiAodHlwZW9mIHRoaXNbcHJvcF0gPT0gInVuZGVmaW5lZCIpIHsNCiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gInVuZGVmaW5lZCIpIHsNCiAgICAgICAgICAgICAgICB0aGlzW3Byb3BdID0gZGVmYXVsdFZhbHVlOw0KICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT0gImZ1bmN0aW9uIikgew0KICAgICAgICAgICAgICAgIHRoaXNbcHJvcF0gPSB2YWx1ZSgpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICB0aGlzW3Byb3BdID0gdmFsdWU7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9Ow0KICAgIGlmICh0eXBlb2YgeG9va2lDb25maWcgIT0gInVuZGVmaW5lZCIpIHt4b29raS51dGlsLm1peCh4b29raUNvbmZpZywgeG9va2kuY29uZmlnKTt9DQogICAgeG9va2kuYy5pbml0UHJvcGVydHkgPSBpbml0Q29uZmlnUHJvcGVydHk7DQogICAgeG9va2kuYy5jb21wdXRlUm9vdCA9IGZ1bmN0aW9uKCkgew0KICAgIAlyb290ID0geG9va2kucGFnZVVSTDsNCiAgICAJLy8gcmVtb3ZlIHRyYWlsaW5nIHBhcnRzIG9mIHRoZSBVUkwgdG8gZ28gdGhlIHJvb3QgZGVwZW5kaW5nIG9uIGxldmVsDQogICAgCWZvciAodmFyIGk9MDsgaSA8IHhvb2tpLmMubGV2ZWwgKyAxOyBpKyspIHsNCiAgICAJCXJvb3QgPSByb290LnN1YnN0cmluZygwLCByb290Lmxhc3RJbmRleE9mKCcvJykpOw0KICAgIAl9DQogICAgCXJldHVybiByb290ICsgJy8nOw0KICAgIH07DQogICAgeG9va2kuYy5jb21wdXRlUmVsYXRpdmVSb290ID0gZnVuY3Rpb24oKSB7DQogICAgCXJldHVybiB4b29raS5zdHJpbmcubXVsKCcuLi8nLCB4b29raS5jLmxldmVsKTsNCiAgICB9Ow0KICAgIHhvb2tpLmMuc2V0SW1wb3J0TGV2ZWwgPSBmdW5jdGlvbihsZXZlbCkgew0KICAgICAgICAvLyBjb21wdXRlIHJvb3RzIHdpdGggb2xkIGxldmVsIHZhbHVlLCBmb3IgcGF0aHMgcmVsYXRpdmUgdG8gdGhlIGxvY2FsIChub24gaW1wb3J0ZWQpIHJvb3QNCiAgICAgICAgdGhpcy5sb2NhbFJvb3QgPSB0aGlzLmNvbXB1dGVSb290KCk7DQogICAgICAgIHRoaXMubG9jYWxSZWxhdGl2ZVJvb3QgPSB0aGlzLmNvbXB1dGVSZWxhdGl2ZVJvb3QoKTsNCiAgICAgICAgLy8gY2hhbmdlIGxldmVsIGFuZCB1cGRhdGUgcm9vdHMNCiAgICAgICAgdGhpcy5sZXZlbCs9bGV2ZWw7DQogICAgICAgIHRoaXMucm9vdCA9IHRoaXMuY29tcHV0ZVJvb3QoKTsNCiAgICAgICAgdGhpcy5yZWxhdGl2ZVJvb3QgPSB0aGlzLmNvbXB1dGVSZWxhdGl2ZVJvb3QoKTsNCiAgICB9Ow0KICAgIHhvb2tpLmMuaW5pdFByb3BlcnR5KCJsZXZlbCIsIDApOw0KICAgIHhvb2tpLmMuaW5pdFByb3BlcnR5KCJyb290IiwgeG9va2kuYy5jb21wdXRlUm9vdCk7DQogICAgeG9va2kuYy5pbml0UHJvcGVydHkoInJlbGF0aXZlUm9vdCIsIHhvb2tpLmMuY29tcHV0ZVJlbGF0aXZlUm9vdCk7DQogICAgZ2xvYmFsQ29uZmlnID0geG9va2kudXJsLmxvYWRVUkwodSgiY29uZmlnLmpzb24iKSwgZmFsc2UpOw0KICAgIGlmIChnbG9iYWxDb25maWcgIT0gbnVsbCkgDQogICAgICAgIHhvb2tpLnV0aWwubWl4KGdsb2JhbENvbmZpZywgeG9va2kuYywgZmFsc2UpOw0KICAgIHhvb2tpLnVybC5ldmFsVVJMKHUoImNvbmZpZy5qcyIpLCBmYWxzZSk7DQogICAgeG9va2kudXJsLmV2YWxVUkwodSgiY29uZmlnLmV4dHJhLmpzIiksIGZhbHNlKTsNCg0KDQogICAgeG9va2kuYy5pbml0UHJvcGVydHkoImRlZmF1bHRJbnB1dEZvcm1hdCIsICJ4b29raSIpOw0KICAgIHhvb2tpLmMuaW5pdFByb3BlcnR5KCJ4b29raUlucHV0Rm9ybWF0IiwgWyJ4b29raSJdKTsNCiAgICB4b29raS5jLmluaXRQcm9wZXJ0eSgiYWxsb3dFZGl0IiwgIWJhdGNoTW9kZSAmJiB4b29raS5wYWdlVVJMLnN1YnN0cigwLDUpID09ICJmaWxlOiIpOw0KICAgIA0KICAgIHhvb2tpLmlucHV0LmZvcm1hdC5kZWZpbmUoInhvb2tpIiwgWyJjb2RlIiwgInNob3J0Y3V0cyIsICJ1cmwiLCAieG9va2lMaW5rcyIsICJqaXJhIiwgImxpbmVCcmVhayIgLCAiaW5jbHVkZXMiXSk7DQogICAgDQogICAgeG9va2kuYy5wYXRoID0gKHR5cGVvZiB4b29raS5jLnBhdGggIT0gInVuZGVmaW5lZCIpP3hvb2tpLmMucGF0aDp7fTsNCiAgICB4b29raS5jLnBhdGguaW5pdFByb3BlcnR5ID0gaW5pdENvbmZpZ1Byb3BlcnR5Ow0KICAgIHhvb2tpLmMucGF0aC5pbml0UHJvcGVydHkoImluc3RhbGwiLCAieG9va2kiKTsNCiAgICB4b29raS5jLnBhdGguaW5pdFByb3BlcnR5KCJtZXNzYWdlcyIsIHhvb2tpLnAoIm1lc3NhZ2VzLmpzb24iKSk7DQogICAgeG9va2kuYy5wYXRoLmluaXRQcm9wZXJ0eSgidGVtcGxhdGUiLCAidGVtcGxhdGUuaHRtbCIpOw0KICAgIHhvb2tpLmMucGF0aC5pbml0UHJvcGVydHkoInByaW50VGVtcGxhdGUiLCAicHJpbnRUZW1wbGF0ZS5odG1sIik7DQogICAgeG9va2kuYy5wYXRoLmluaXRQcm9wZXJ0eSgidG9jIiwgInRvYy5qc29uIik7DQogICAgeG9va2kuYy5wYXRoLmluaXRQcm9wZXJ0eSgiYmxhbmtQYWdlVHBsIiwgeG9va2kucCgiYmxhbmtQYWdlVHBsLmh0bWwiKSk7DQogICAgDQogICAgDQogICAgeG9va2kuYy5jc3MgPSAodHlwZW9mIHhvb2tpLmMuY3NzICE9ICJ1bmRlZmluZWQiKT94b29raS5jLmNzczp7fTsgICAgDQogICAgICAgIA0KICAgIHhvb2tpLmMubWVzc2FnZXMgPSB4b29raS5qc29uLmxvYWRVUkwoY3UoIm1lc3NhZ2VzIikpOyANCglpZiAoIWJhdGNoTW9kZSkgew0KCSAgICB4b29raS5jLmJyb3dzZXIgPSB7DQoJICAgICAgICBOUzogKHdpbmRvdy5FdmVudCkgPyAxIDogMA0KCSAgICB9Ow0KICAgIA0KCSAgICAvLyBhY3Rpb24NCgkgICAgLy8gVE9ETzogYmV0dGVyIGhhbmRsZSBhY3Rpb24gZXh0cmFjdGlvbg0KCQl4b29raS5jLmFjdGlvbiA9IHdpbmRvdy5sb2NhdGlvbi5zZWFyY2ggPT0gJz9hY3Rpb249cHJpbnQnPydwcmludCc6eG9va2kuYy5hY3Rpb247DQoJfQ0KCQ0KCXZhciBtYXRjaCA9IG5ldyBSZWdFeHAoIl4uKlxcLygoPzouKlxcLyl7Iit4b29raS5jLmxldmVsKyJ9W15cXC9dKikoPzpcXC5cXHcrKSg/OlxcPy4rKT8kIiwgImciKS5leGVjKHhvb2tpLnBhZ2VVUkwpOw0KCWlmIChtYXRjaCA9PSBudWxsIHx8IG1hdGNoWzFdID09ICcnKSB7DQoJCXhvb2tpLmMuY3VyUGFnZUlkID0gImluZGV4IjsNCgl9IGVsc2Ugew0KCQl4b29raS5jLmN1clBhZ2VJZCA9IG1hdGNoWzFdOw0KCX0NCiAgICANCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQogICAgLy8vLy8vLy8vLy8vLy8vLy8vIFRPQyBpbml0DQogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KICAgIHhvb2tpLnRvYyA9IHhvb2tpLmpzb24ubG9hZFVSTChjdSgidG9jIikpOw0KICAgIHhvb2tpLnRvYy51cmwgPSBjdSgidG9jIik7DQogICAgeG9va2kudG9jLnBhZ2VzID0ge307IC8vIHRvIHN0b3JlIGEgYnkgaWQgbWFwIG9mIHBhZ2VzIG9iamVjdHMNCiAgICB4b29raS50b2MuaW1wb3J0Um9vdCA9ICcnOw0KICAgIHhvb2tpLnRvYy5hY3R1YWxSb290ID0geG9va2kudG9jOyAvLyB0aGlzIGlzIHRoZSByZWFsIHJvb3Qgb2YgdGhlIFRPQywgaW4gY2FzZSBvZiBhIFRPQyBpbXBvcnRlZCwgaXQgd2lsbCBwb2ludCB0byB0aGUgcm9vdCBvZiB0aGUgVE9DIG9uIHdoaWNoIGltcG9ydCBoYXMgYmVlbiBwZXJmb3JtZWQNCg0KCS8vIHBvcHVsYXRlIG1ldGEgZGF0YQ0KCShmdW5jdGlvbihwYWdlLCBwYXJlbnQsIGluZGV4LCBsZXZlbCwgcHJlZml4KSB7DQogICAgICAgIGlmIChwcmVmaXgubGVuZ3RoID4gMCkgew0KICAgICAgICAgICAgcGFnZS5tZXRhID0geG9va2kudXRpbC5taXgoe2lkOiBwYWdlLmlkfSwgcGFnZS5tZXRhKTsNCiAgICAgICAgICAgIHBhZ2UuaWQgPSBwcmVmaXggKyBwYWdlLmlkOw0KICAgICAgICB9DQogICAgICAgIHhvb2tpLnRvYy5wYWdlc1twYWdlLmlkXSA9IHBhZ2U7DQogICAgICAgIA0KICAgICAgICBwYWdlLm1ldGEgPSB4b29raS51dGlsLm1peCh7DQogICAgICAgICAgICBpbmRleDogaW5kZXgsDQogICAgICAgICAgICBsZXZlbDogbGV2ZWwsDQogICAgICAgICAgICBnZXRTZXJpYWxpemVWYWx1ZTogZnVuY3Rpb24obywgaykgew0KICAgICAgICAgICAgICAgIGlmIChrID09ICdpZCcgJiYgdHlwZW9mIHRoaXMuaWQgIT0gJ3VuZGVmaW5lZCcpIHsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaWQ7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9ba107DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9LCBwYWdlLm1ldGEpOw0KICAgICAgICBwYWdlLm1ldGEucGFyZW50ID0gcGFyZW50Ow0KICAgICAgICBpZiAodHlwZW9mIHBhZ2UuaW1wb3J0Tm9kZSAhPSAndW5kZWZpbmVkJyAmJiAhcGFnZS5pc0ltcG9ydGVkKSB7DQogICAgICAgICAgICAvLyB0aGlzIG5vZGUgcmVxdWlyZXMgdG8gaW1wb3J0IGFub3RoZXIgeG9va2kgVE9DDQogICAgICAgICAgICBpbXBvcnRlZFRvY1VybCA9IHUocGFnZS5pbXBvcnRSb290ICsgJy90b2MuanNvbicpOw0KICAgICAgICAgICAgaW1wb3J0ZWRUb2MgPSB4b29raS5qc29uLmxvYWRVUkwoaW1wb3J0ZWRUb2NVcmwpOw0KICAgICAgICAgICAgLy8gbG9vayBmb3IgdGhlIGltcG9ydGVkIG5vZGUgaW4gdGhlIGltcG9ydGVkVE9DIGFuZCBpbXBvcnQgaXQgaW4gbWFpbiBUT0MNCiAgICAgICAgICAgIChmdW5jdGlvbihwYWdlLCBwYXJlbnQsIGluZGV4LCBsZXZlbCwgcHJlZml4LCBpbXBvcnRlZFRvYywgbm9kZSwgaWQsIHBvcHVsYXRlRnVuY3Rpb24pIHsNCiAgICAgICAgICAgICAgICBpZiAobm9kZS5pZCA9PSBpZCkgew0KICAgICAgICAgICAgICAgICAgICB4b29raS51dGlsLm1peChub2RlLCBwYWdlLCBmYWxzZSk7DQogICAgICAgICAgICAgICAgICAgIHBhZ2UuaWQgPSBpZDsNCiAgICAgICAgICAgICAgICAgICAgcGFnZS5pc0ltcG9ydGVkID0gdHJ1ZTsNCiAgICAgICAgICAgICAgICAgICAgcGFnZS5tZXRhID0geG9va2kudXRpbC5taXgoew0KICAgICAgICAgICAgICAgICAgICAgICAgaXNUcmFuc2llbnQ6IGZ1bmN0aW9uKGspIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvbmx5IHRpdGxlLCBpbXBvcnRSb290IGFuZCBpbXBvcnROb2RlIHNob3VsZCBiZSBzZXJpYWxpemVkDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGsgIT0gJ3RpdGxlJyAmJiBrICE9ICdpbXBvcnRSb290JyAmJiBrICE9ICdpbXBvcnROb2RlJzsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfSwgcGFnZS5tZXRhKTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHhvb2tpLmMuY3VyUGFnZUlkLmluZGV4T2YocHJlZml4KSA9PSAwKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgY3VycmVudCBwYWdlIGlzIGluIHRoaXMgaW1wb3J0ZWQgVE9DDQogICAgICAgICAgICAgICAgICAgICAgICB4b29raS50b2MuYWN0dWFsUm9vdCA9IGltcG9ydGVkVG9jOw0KICAgICAgICAgICAgICAgICAgICAgICAgeG9va2kudG9jLnVybCA9IHUocGFnZS5pbXBvcnRSb290ICsgJy90b2MuanNvbicpOw0KICAgICAgICAgICAgICAgICAgICAgICAgeG9va2kudG9jLmltcG9ydFJvb3QgPSBwcmVmaXg7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgcG9wdWxhdGVGdW5jdGlvbihwYWdlLCBwYXJlbnQsIGluZGV4LCBsZXZlbCwgcHJlZml4KTsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7DQogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygbm9kZS5jaGlsZHJlbiAhPSAndW5kZWZpbmVkJykgew0KICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpPTA7IGk8bm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykgew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5jYWxsZWUocGFnZSwgcGFyZW50LCBpbmRleCwgbGV2ZWwsIHByZWZpeCwgaW1wb3J0ZWRUb2MsIG5vZGUuY2hpbGRyZW5baV0sIGlkLCBwb3B1bGF0ZUZ1bmN0aW9uKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgICAgIH0pKHBhZ2UsIHBhcmVudCwgaW5kZXgsIGxldmVsLCBwYWdlLmltcG9ydFJvb3QrJy8nLCBpbXBvcnRlZFRvYywgaW1wb3J0ZWRUb2MsIHBhZ2UuaW1wb3J0Tm9kZSwgYXJndW1lbnRzLmNhbGxlZSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKHR5cGVvZiBwYWdlLmNoaWxkcmVuID09ICd1bmRlZmluZWQnKSB7DQogICAgICAgICAgICBwYWdlLmNoaWxkcmVuID0gW107DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBmb3IgKHZhciBpPTA7IGk8cGFnZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykgew0KICAgICAgICAgICAgICAgIGFyZ3VtZW50cy5jYWxsZWUocGFnZS5jaGlsZHJlbltpXSwgcGFnZSwgaSwgbGV2ZWwrMSwgcHJlZml4KTsgLy8gcmVjdXJzZQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfSkoeG9va2kudG9jLCBudWxsLCAwLCAtMSwgJycpOw0KICAgIA0KICAgIHhvb2tpLnRvYy5nZXROZXh0UGFnZSA9IGZ1bmN0aW9uKHBhZ2UsIHJvb3QpIHsNCiAgICAgICAgaWYgKHBhZ2UuY2hpbGRyZW4ubGVuZ3RoID4gMCkgew0KICAgICAgICAJcmV0dXJuIHBhZ2UuY2hpbGRyZW5bMF07DQogICAgICAgIH0gZWxzZSBpZiAocGFnZS5tZXRhLnBhcmVudCAhPSBudWxsKSB7DQogICAgICAgIAl2YXIgY3VyID0gcGFnZTsNCiAgICAgICAgCXZhciBuZXh0ID0geG9va2kudG9jLmdldE5leHRTaWJsaW5nKGN1cik7DQogICAgICAgIAl3aGlsZSAobmV4dCA9PSBudWxsKSB7DQogICAgICAgIAkJY3VyID0gY3VyLm1ldGEucGFyZW50Ow0KICAgICAgICAJCWlmIChjdXIgPT0gbnVsbCB8fCBjdXIgPT0gcm9vdCkgew0KICAgICAgICAJCQlyZXR1cm4gbnVsbDsNCiAgICAgICAgCQl9DQogICAgICAgIAkJbmV4dCA9IHhvb2tpLnRvYy5nZXROZXh0U2libGluZyhjdXIpOw0KICAgICAgICAJfQ0KICAgICAgIAkJcmV0dXJuIG5leHQ7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgIAlyZXR1cm4gbnVsbDsNCiAgICAgICAgfQ0KICAgIH07DQogICAgeG9va2kudG9jLmdldE5leHRTaWJsaW5nID0gZnVuY3Rpb24ocGFnZSkgew0KICAgIAlpZiAocGFnZS5tZXRhLnBhcmVudCA9PSBudWxsKSB7DQogICAgCQlyZXR1cm4gbnVsbDsNCiAgICAJfQ0KICAgICAgIAlpZiAocGFnZS5tZXRhLnBhcmVudC5jaGlsZHJlbi5sZW5ndGggPiBwYWdlLm1ldGEuaW5kZXgpIHsNCiAgICAgICAJCXJldHVybiBwYWdlLm1ldGEucGFyZW50LmNoaWxkcmVuW3BhZ2UubWV0YS5pbmRleCsxXTsNCiAgICAgICAJfSBlbHNlIHsNCiAgICAgICAJCXJldHVybiBudWxsOw0KICAgICAgIAl9DQogICAgfTsNCgl4b29raS5wYWdlID0geG9va2kudG9jLnBhZ2VzW3hvb2tpLmMuY3VyUGFnZUlkXTsNCg0KCWlmICh4b29raS5wYWdlID09IG51bGwpIHsNCgkJeG9va2kud2Fybih0KCdwYWdlIGlkIG5vdCBmb3VuZCBpbiBUT0M6ICR7MH0nLHhvb2tpLmMuY3VyUGFnZUlkKSk7DQoJCXhvb2tpLnBhZ2UgPSB4b29raS50b2MuY2hpbGRyZW5bMF07DQoJfSANCglpZiAodHlwZW9mIHhvb2tpLmNvbmZpZy50aXRsZSA9PSAndW5kZWZpbmVkJykgew0KCQl4b29raS5jb25maWcudGl0bGUgPSB4b29raS5wYWdlLnRpdGxlOw0KCX0JCQ0KCXhvb2tpLmNvbmZpZy5wYWdlID0geG9va2kucGFnZTsNCgkNCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQogICAgLy8vLy8vLy8vLy8vLy8vLy8vIG1haW4gdGVtcGxhdGUgbG9hZGluZyArIGhlYWQgb3V0cHV0DQogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KCXhvb2tpLnRlbXBsYXRlID0ge307DQogICAgeG9va2kudGVtcGxhdGUuc291cmNlID0geG9va2kudXJsLmxvYWRVUkwoeG9va2kuYy5hY3Rpb24gPT0gInByaW50Ij9jdSgicHJpbnRUZW1wbGF0ZSIpOmN1KCJ0ZW1wbGF0ZSIpKTsNCglpZih4b29raS50ZW1wbGF0ZS5zb3VyY2UgIT0gbnVsbCkgew0KCQl4b29raS50ZW1wbGF0ZS5oZWFkID0geG9va2kudGVtcGxhdGUuc291cmNlLm1hdGNoKC88aGVhZD4oW16nXSopPFwvaGVhZD4vaW0pWzFdOw0KCQl2YXIgcm9vdCA9IGJhdGNoTW9kZT94b29raS5jLnJlbGF0aXZlUm9vdDp4b29raS5jLnJvb3Q7DQoJCQ0KICAgICAgICB2YXIgaGVhZCA9IHhvb2tpLnN0cmluZy5wcm9jZXNzVGVtcGxhdGUoeG9va2kudGVtcGxhdGUuaGVhZCwgeG9va2kuY29uZmlnKTsNCgkJaGVhZCA9IGhlYWQucmVwbGFjZSgvaHJlZj0iKFteXFwkOiJdKykiL2csICdocmVmPSInK3Jvb3QrJyQxIicpOw0KCQloZWFkID0gaGVhZC5yZXBsYWNlKC9zcmM9IihbXlxcJDoiXSspIi9nLCAnc3JjPSInK3Jvb3QrJyQxIicpOw0KCQl4b29raS5odG1sLmFkZEhlYWRlcihoZWFkKTsNCg0KCQl2YXIgYm9keSA9IHhvb2tpLnRlbXBsYXRlLnNvdXJjZS5tYXRjaCgvPGJvZHk+KFtep10qKTxcL2JvZHk+L2ltKVsxXTsNCgkJYm9keSA9IGJvZHkucmVwbGFjZSgvaHJlZj0iKFteXFwkOiJdKykiL2csICdocmVmPSInK3Jvb3QrJyQxIicpOw0KCQl4b29raS50ZW1wbGF0ZS5ib2R5ID0gYm9keS5yZXBsYWNlKC9zcmM9IihbXlxcJDoiXSspIi9nLCAnc3JjPSInK3Jvb3QrJyQxIicpOwkJDQoJfQ0KCQ0KDQogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLyBpbmNsdWRlcw0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCglpZiAoYmF0Y2hNb2RlKSB7DQoJCXhvb2tpLmh0bWwuYWRkSGVhZGVyKCc8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPnhvb2tpID0ge3U6IGZ1bmN0aW9uKHVybCkge3JldHVybiAiJyt4b29raS5jLnJlbGF0aXZlUm9vdCsneG9va2kvIit1cmw7fX07PC9zY3JpcHQ+Jyk7DQoJfQ0KICAgIGlmICh4b29raS5jLmFsbG93RWRpdCkgew0KICAgICAgICB4b29raS51cmwuaW5jbHVkZSgieG9va2lFZGl0LmpzIik7DQogICAgfQ0KDQogICAgZm9yICh2YXIgayBpbiB4b29raS5jKSB7DQogICAgICAgIGlmICh0eXBlb2YgeG9va2kuY1trXSA9PSAic3RyaW5nIiB8fCB0eXBlb2YgeG9va2kuY1trXSA9PSAibnVtYmVyIiB8fCB0eXBlb2YgeG9va2kuY1trXSA9PSAiYm9vbGVhbiIpIHsNCiAgICAgICAgICAgIHhvb2tpLmRlYnVnKGsrIjogIit4b29raS5jW2tdKTsNCiAgICAgICAgfQ0KICAgIH0NCn07DQoNCmlmIChiYXRjaE1vZGUpIHsNCglpbXBvcnRQYWNrYWdlKGphdmEuaW8pOw0KCQ0KCXhvb2tpLmlvLmxvYWRGaWxlID0gZnVuY3Rpb24oIHVybCwgd2Fybk9uRXJyb3IgKSB7DQoJICB2YXIgc3RyID0gJyc7DQoJICB0cnkgew0KICAgICAgdmFyIHIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IEZpbGVSZWFkZXIodXJsKSk7DQoJICBsaW5lID0gci5yZWFkTGluZSgpOw0KCSAgd2hpbGUgKGxpbmUgIT0gbnVsbCkgew0KCQlzdHIgKz0gbGluZSArICdcbic7DQoJCWxpbmUgPSByLnJlYWRMaW5lKCk7DQoJICB9DQoJICByLmNsb3NlKCk7DQoJICB9IGNhdGNoIChlKSB7DQoJICAJaWYgKHdhcm5PbkVycm9yKSB7DQoJICAJCXRocm93IGU7DQoJICAJfSBlbHNlIHsNCgkgIAkJeG9va2kuZGVidWcoImVycm9yIG9jY3VyZWQgd2hpbGUgbG9hZGluZyAiK3VybCk7DQoJICAJfQ0KCSAgfQ0KCSAgcmV0dXJuIHN0cjsNCiAgICB9Ow0KCQ0KCXhvb2tpLmlvLnNhdmVGaWxlID0gZnVuY3Rpb24gKGZpbGVVcmwsIGNvbnRlbnQpIHsNCgkJcCA9IG5ldyBGaWxlKGZpbGVVcmwpLmdldFBhcmVudEZpbGUoKTsNCgkJaWYgKHAgIT0gbnVsbCkgew0KCQkJcC5ta2RpcnMoKTsNCgkJfQ0KCQlwdyA9IG5ldyBQcmludFdyaXRlcihuZXcgRmlsZVdyaXRlcihmaWxlVXJsKSk7DQoJCXB3LndyaXRlKGNvbnRlbnQpOw0KCQlwdy5jbG9zZSgpOw0KCQlyZXR1cm4gdHJ1ZTsNCgl9DQoNCiAgICB4b29raS51cmwubG9hZFVSTCA9IGZ1bmN0aW9uKCB1cmwsIHdhcm5PbkVycm9yICkgew0KCQlyZXR1cm4geG9va2kuaW8ubG9hZEZpbGUodXJsLCB3YXJuT25FcnJvciApOw0KCX07DQoJDQoJeG9va2kuaHRtbC5hZGRIZWFkZXIgPSBmdW5jdGlvbiAoaGVhZCkgew0KCQl4b29raS5wYWdlQ29udGVudCA9IHhvb2tpLnBhZ2VDb250ZW50LnJlcGxhY2UoLzxcL2hlYWQ+LywgaGVhZCsnXG48L2hlYWQ+Jyk7DQoJfTsNCgkNCgl4b29raS5odG1sLnNldEJvZHkgPSBmdW5jdGlvbihib2R5KSB7DQoJCXhvb2tpLnBhZ2VDb250ZW50ID0geG9va2kucGFnZUNvbnRlbnQucmVwbGFjZSgvPGJvZHk+KC58W14sXSkqPFwvYm9keT4vZ20sICc8Ym9keT4nK2JvZHkrJzwvYm9keT4nKTsNCgl9DQoJDQoJeG9va2kudXJsLmluY2x1ZGUgPSBmdW5jdGlvbihzY3JpcHRfZmlsZW5hbWUpIHsNCgkJeG9va2kuaHRtbC5hZGRIZWFkZXIoJzxzY3JpcHQgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSInK3hvb2tpLmMucmVsYXRpdmVSb290Kyd4b29raS8nK3NjcmlwdF9maWxlbmFtZSsnIj48L3NjcmlwdD4nKTsNCgl9Ow0KCQ0KCXhvb2tpLmlucHV0LnNvdXJjZSA9IGZ1bmN0aW9uKCkgew0KCQlpZiAodHlwZW9mIHRoaXMuX3NvdXJjZSA9PSAndW5kZWZpbmVkJykgew0KCQkJeG9va2kuZGVidWcoJ3NlYXJjaGluZyBzb3VyY2UnKTsNCgkJCXZhciBiZWcgPSB4b29raS5wYWdlQ29udGVudC5pbmRleE9mKCc8dGV4dGFyZWEgaWQ9Inhvb2tpLXNvdXJjZSI+Jyk7DQoJCQliZWcgKz0gJzx0ZXh0YXJlYSBpZD0ieG9va2ktc291cmNlIj4nLmxlbmd0aDsNCgkJCXZhciBlbmQgPSB4b29raS5wYWdlQ29udGVudC5sYXN0SW5kZXhPZignPC90ZXh0YXJlYT4nKTsNCgkJCXRoaXMuX3NvdXJjZSA9IHhvb2tpLnBhZ2VDb250ZW50LnN1YnN0cmluZyhiZWcsIGVuZCk7DQoJCQl4b29raS5kZWJ1Zygnc291cmNlIGZvdW5kJyk7DQoJCX0NCgkJcmV0dXJuIHRoaXMuX3NvdXJjZTsNCgl9DQoJDQoJeG9va2kucmVuZGVyLnBhZ2UgPSBmdW5jdGlvbigpIHsNCgkgICAgLy8gcmVhbGl6ZSBhbGwgY29tcG9uZW50cyBhdmFpbGFibGUNCgkJeG9va2kuZGVidWcoJ3JlYWxpemluZyBjb21wb25lbnRzJyk7DQoJICAgIGZvciAodmFyIGsgaW4geG9va2kuY29tcG9uZW50KSB7DQoJICAgICAgICB4b29raS5jW2tdID0geG9va2kuY29tcG9uZW50W2tdKCk7DQoJICAgIH0NCgkgICAgDQoJCXhvb2tpLmRlYnVnKCdwcm9jZXNzaW5nIGJvZHknKTsNCgkJeG9va2kuYy5ib2R5ID0geG9va2kuaW5wdXQucHJvY2Vzc2VkKCk7DQoNCgkJeG9va2kuZGVidWcoJ3VwZGF0aW5nIGJvZHknKTsNCgkJdmFyIGJvZHkgPSB4b29raS5zdHJpbmcucHJvY2Vzc1RlbXBsYXRlKHhvb2tpLnRlbXBsYXRlLmJvZHksIHhvb2tpLmMpOw0KCSAgICB4b29raS5odG1sLnNldEJvZHkoYm9keSk7DQoJfTsNCg0KCXhvb2tpLmRpc3BsYXkgPSBmdW5jdGlvbihtZXNzYWdlLCBiYWNrZ3JvdW5kKSB7DQoJCXByaW50KG1lc3NhZ2UpOw0KCX07DQoJDQoJeG9va2kuZGVidWcgPSBmdW5jdGlvbiAobWVzc2FnZSkgew0KCQlpZiAoeG9va2kuYy5kZWJ1Zykgew0KCQkJcHJpbnQobWVzc2FnZSsnXG4nKTsNCgkJfQ0KCX07DQoJdmFyIGk9MDsNCglpZiAoYXJndW1lbnRzLmxlbmd0aCA+IGkgJiYgYXJndW1lbnRzWzBdID09ICctZGVidWcnKSB7DQoJCXhvb2tpLmMuZGVidWcgPSB0cnVlOw0KCQlpKys7DQoJfSBlbHNlIHsNCgkJeG9va2kuYy5kZWJ1ZyA9IGZhbHNlOw0KCX0NCgkNCgl2YXIgZmlsZSA9ICdpbmRleC5odG1sJzsNCglpZiAoYXJndW1lbnRzLmxlbmd0aCA+IGkpIHsNCgkJZmlsZSA9IGFyZ3VtZW50c1tpXTsNCgkJaSsrOw0KCX0NCgl2YXIgZ2VuZXJhdGVUb0RpciA9ICJnZW4iOw0KCWlmIChhcmd1bWVudHMubGVuZ3RoID4gaSkgew0KCQlnZW5lcmF0ZVRvRGlyID0gYXJndW1lbnRzW2ldOw0KCQlpKys7DQoJfQ0KDQoJeG9va2kucGFnZVVSTCA9IG5ldyBGaWxlKGZpbGUpLnRvVVJMKCkudG9FeHRlcm5hbEZvcm0oKTsNCgkNCglwcmludCgncHJvY2Vzc2luZyAnK25ldyBGaWxlKGZpbGUpLmdldEFic29sdXRlUGF0aCgpKycuLi5cbicpOw0KCXhvb2tpLnBhZ2VDb250ZW50ID0geG9va2kuaW8ubG9hZEZpbGUoZmlsZSk7DQogICAgDQogICAgaWYgKHhvb2tpLnBhZ2VDb250ZW50Lm1hdGNoKC88dGV4dGFyZWFccytpZD0ieG9va2lcLXNvdXJjZSI+LykgPT0gbnVsbCkgew0KICAgICAgICBwcmludChmaWxlICsgJyBpcyBub3QgYSB2YWxpZCB4b29raSBzb3VyY2UuIGlnbm9yZWQuJyk7DQogICAgfSBlbHNlIHsJDQogICAgCXZhciBtID0gL3ZhclxzK3hvb2tpQ29uZmlnXHMrPVxzK3suKn07Ly5leGVjKHhvb2tpLnBhZ2VDb250ZW50KTsNCiAgICAJaWYgKHR5cGVvZiBtICE9ICd1bmRlZmluZWQnICYmIG0gIT0gbnVsbCkgew0KICAgIAkJZXZhbChtWzBdKTsNCiAgICAJfQ0KDQogICAgICAgIHhvb2tpLmluaXQoKTsNCiAgICAgICAgDQogICAgCXhvb2tpLnBhZ2VDb250ZW50ID0geG9va2kucGFnZUNvbnRlbnQucmVwbGFjZSgvPHNjcmlwdCB0eXBlPSJ0ZXh0XC9qYXZhc2NyaXB0IiBzcmM9IlteIl0qeG9va2kuanMiPjxcL3NjcmlwdD4vZywgJycpOw0KICAgIAkNCiAgICAJeG9va2kucmVuZGVyLnBhZ2UoKTsNCg0KICAgIAlwcmludCgnZ2VuZXJhdGluZyB0byAnK2dlbmVyYXRlVG9EaXIrJy8nK2ZpbGUpOw0KICAgIAl4b29raS5pby5zYXZlRmlsZShnZW5lcmF0ZVRvRGlyKycvJytmaWxlLCB4b29raS5wYWdlQ29udGVudCk7DQogICAgfQ0KfSBlbHNlIHsNCgl4b29raS5wYWdlVVJMID0gd2luZG93LmxvY2F0aW9uLnRvU3RyaW5nKCk7DQogICAgeG9va2kuaW5pdCgpOw0KfQ0KDQo=