LyoNCglDb3B5cmlnaHQgKGMpIDIwMDYtMjAwNywgVGhlIFhvb2tpIHByb2plY3QNCglodHRwOi8veG9va2kuc291cmNlZm9yZ2UubmV0Lw0KDQogICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsNCiAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4NCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdA0KDQogICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wDQoNCiAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUNCiAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsDQogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4NCiAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQNCiAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLg0KCQ0KCVNvbWUgY29kZSBpcyBsYXJnZWx5IGluc3BpcmVkIGJ5IGNvZGUgZm91bmQgaW4gdGhlIGRvam8gdG9vbGtpdCwgDQoJc2VlIGh0dHA6Ly9kb2pvdG9vbGtpdC5vcmcvIGZvciBtb3JlIGluZm9ybWF0aW9uLg0KKi8NCg0KLyoNClRoaXMgc2NyaXB0IGNhbiBiZSBlaXRoZXIgZW1iZWRkZWQgaW4gYSB4b29raSBwYWdlIGZvciBpbiBicm93c2VyIHByb2Nlc3NpbmcsIG9yIHVzZWQgaW4gYmF0Y2ggdXNpbmcgcmhpbm8gb3IgamF2YSA2IGphdmFzY3JpcHQgdG9vbDoNCmpydW5zY3JpcHQgcGF0aC90by94b29raS5qcyBbLW5vZGR0cmVlXSBpbnB1dEZpbGVGcm9tWG9va2lTaXRlLmh0bWwgW3BhdGgvdG8vZGlyL3RvL3B1dC9nZW5lcmF0ZWQvZmlsZV0NCg0KQmUgc3VyZSB0byBiZSBpbiB0aGUgZGlyZWN0b3J5IHdoZXJlIHRoZSBodG1sIGlucHV0IHRvIHByb2Nlc3MgaXMgd2hlbiBydW5uaW5nIHRoaXMgY29tbWFuZC4NCiAqLw0KdmFyIGJhdGNoTW9kZSA9ICh0eXBlb2YgYXJndW1lbnRzICE9ICd1bmRlZmluZWQnKTsNCg0KdmFyIHhvb2tpID0ge307DQp4b29raS5jb25zb2xlID0gIiI7IC8vIHVzZWQgZm9yIGRlYnVnZ2luZyBwdXJwb3NlIG9ubHksIGFuZCBvbmx5IHdoZW4gdGhlIGRlYnVnIGRpdiBpcyBub3QgeWV0IGNyZWF0ZWQNCnhvb2tpLmNvbmZpZyA9IHt9Ow0KeG9va2kuYyA9IHhvb2tpLmNvbmZpZzsNCg0KZnVuY3Rpb24gdChtc2cpIHsNCiAgICAvLyByZXR1cm5zIHRoZSBpbnRlcm5hdGlvbmFsaXplZCB2ZXJzaW9uIG9mIHRoZSBtZXNzYWdlLCBvciB0aGUgbWVzc2FnZSBpZiBubyB0cmFuc2xhdGlvbiBpcyBhdmFpbGFibGUNCiAgICAvLyB0IHN0YW5kcyBmb3IgdHJhbnNsYXRlDQovLyBGSVhNRQ0KLy8gICAgaWYgKHR5cGVvZiB4b29raS5jID09ICJvYmplY3QiIA0KLy8gICAgICAgICYmIHR5cGVvZiB4b29raS5jLm1lc3NhZ2VzID09ICJvYmplY3QiIA0KLy8gICAgICAgICYmIHR5cGVvZiB4b29raS5jLm1lc3NhZ2VzW21zZ10gPT0gInN0cmluZyIpIHsNCi8vICAgICAgICBtc2cgPSB4b29raS5jLm1lc3NhZ2VzW21zZ107DQovLyAgICB9DQogICAgdmFyIGFyciA9IFtdOw0KICAgIGZvciAodmFyIGk9MTsgaTxhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgYXJyLnB1c2goYXJndW1lbnRzW2ldKTsNCiAgICB9DQogICAgcmV0dXJuIHhvb2tpLnN0cmluZy5zdWJzdGl0dXRlUGFyYW1zKG1zZywgYXJyKTsNCn0NCg0KZnVuY3Rpb24gY3NzKGNsc3MpIHsNCiAgICAvLyByZXR1cm5zIHRoZSBjc3MgY2xhc3Mgb3IgaWQgY29uZmlndXJlZCwgb3IgdGhlIGdpdmVuIGNsYXNzIChvciBpZCkgaWYgbm8gb25lIGlzIGNvbmZpZ3VyZWQNCiAgICBpZiAodHlwZW9mIHhvb2tpLmMuY3NzW2Nsc3NdICE9ICJ1bmRlZmluZWQiKSB7DQogICAgICAgIHJldHVybiB4b29raS5jLmNzc1tjbHNzXTsNCiAgICB9IGVsc2Ugew0KICAgICAgICByZXR1cm4gY2xzczsNCiAgICB9IA0KfQ0KZnVuY3Rpb24gdShwYXRoKSB7DQogIC8vIGNvbnZlcnQgYSBwYXRoIHJlbGF0aXZlIHRvIHRoZSByb290IHRvIGEgZnVsbCBVUkwNCiAgLy8gdSBzdGFuZHMgZm9yIFVybA0KICBpZiAoYmF0Y2hNb2RlKSB7DQoJcmV0dXJuIHhvb2tpLmMucmVsYXRpdmVSb290K3BhdGg7DQogIH0gZWxzZSB7DQoJcmV0dXJuIHhvb2tpLmMucm9vdCArIHBhdGg7DQogIH0NCn0NCmZ1bmN0aW9uIGN1KHVybENmZ1Byb3ApIHsNCiAgLy8gZ2V0IGEgcGF0aCBmcm9tIGEgY29uZmlndXJhdGlvbiBwYXRoIGFuZCBjb252ZXJ0IGl0IHRvIGFuIFVSTA0KICAvLyBjdSBzdGFuZHMgZm9yIENvbmZpZ3VyZWQgVXJsDQogIGlmICh0eXBlb2YgeG9va2kuYy5wYXRoW3VybENmZ1Byb3BdID09ICJ1bmRlZmluZWQiKSB7DQogICAgeG9va2kud2Fybih0KCJwYXRoIG5vdCBjb25maWd1cmVkIGluIHhvb2tpOiAnJHswfSciLCB1cmxDZmdQcm9wKSk7DQogICAgcmV0dXJuICIiOw0KICB9DQogIHJldHVybiB1KHhvb2tpLmMucGF0aFt1cmxDZmdQcm9wXSk7DQp9DQpmdW5jdGlvbiBwdShpZCkgew0KICAvLyByZXR1cm5zIHRoZSB1cmwgb2YgdGhlIHBhZ2UgaWRlbnRpZmllZCBieSBpZA0KICAvLyBwdSBzdGFuZHMgZm9yIFBhZ2UgVXJsDQogIHJldHVybiB1KGlkKyIuaHRtbCIpOw0KfQ0KeG9va2kucCA9IGZ1bmN0aW9uKHBhdGgpIHsNCiAgLy8gZ2V0IGEgeG9va2kgZnVsbCBwYXRoIGZyb20gYSB4b29raSByZWxhdGl2ZSBwYXRoDQogIC8vIHAgc3RhbmRzIGZvciBwYXRoDQogIHJldHVybiB4b29raS5jLnBhdGguaW5zdGFsbCsiLyIrcGF0aDsNCn0NCnhvb2tpLnUgPSBmdW5jdGlvbihwYXRoKSB7DQogIC8vIGNvbnZlcnQgYSBwYXRoIHJlbGF0aXZlIHRvIHRoZSB4b29raSBpbnN0YWxsYXRpb24gZGlyIHRvIGEgZnVsbCBVUkwNCiAgcmV0dXJuIHUoeG9va2kucChwYXRoKSk7DQp9DQp4b29raS5jdSA9IGZ1bmN0aW9uKHVybENmZ1Byb3ApIHsNCiAgLy8gZ2V0IGEgeG9va2kgcGF0aCBmcm9tIGEgY29uZmlndXJhdGlvbiBwYXRoIGFuZCBjb252ZXJ0IGl0IHRvIGFuIFVSTA0KICBpZiAodHlwZW9mIHhvb2tpLmMucGF0aFt1cmxDZmdQcm9wXSA9PSAidW5kZWZpbmVkIikgew0KICAgIHhvb2tpLndhcm4odCgicGF0aCBub3QgY29uZmlndXJlZCBpbiB4b29raTogJyR7MH0nIiwgdXJsQ2ZnUHJvcCkpOw0KICB9DQogIHJldHVybiB4b29raS51KHhvb2tpLmMucGF0aFt1cmxDZmdQcm9wXSk7DQp9DQoNCnhvb2tpLnV0aWwgPSB7DQogICAgaXNBcnJheTogZnVuY3Rpb24oaXQpIHsNCiAgICAJcmV0dXJuIChpdCAmJiBpdCBpbnN0YW5jZW9mIEFycmF5IHx8IHR5cGVvZiBpdCA9PSAiYXJyYXkiKTsgLy8gQm9vbGVhbg0KICAgIH0sDQogICAgbWl4OiBmdW5jdGlvbihzcmMsIGludG8sIG92ZXJyaWRlKSB7DQogICAgICAgIGlmICh0eXBlb2Ygb3ZlcnJpZGUgPT0gInVuZGVmaW5lZCIpIHsNCiAgICAgICAgICAgIG92ZXJyaWRlID0gdHJ1ZTsNCiAgICAgICAgfQ0KICAgICAgICBmb3IgKHZhciBrIGluIHNyYykgew0KICAgICAgICAgICAgaWYgKHR5cGVvZiBzcmNba10gPT0gIm9iamVjdCIgJiYgIXhvb2tpLnV0aWwuaXNBcnJheShzcmNba10pKSB7DQogICAgICAgICAgICAgICAgaWYgKG92ZXJyaWRlIHx8IHR5cGVvZiBpbnRvW2tdID09ICJvYmplY3QiIHx8IHR5cGVvZiBpbnRvW2tdID09ICJ1bmRlZmluZWQiKSB7DQogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaW50b1trXSAhPSAib2JqZWN0Iikgew0KICAgICAgICAgICAgICAgICAgICAgICAgaW50b1trXSA9IHt9Ow0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIHhvb2tpLnV0aWwubWl4KHNyY1trXSwgaW50b1trXSwgb3ZlcnJpZGUpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0gZWxzZSBpZiAob3ZlcnJpZGUgfHwgdHlwZW9mIGludG9ba10gPT0gInVuZGVmaW5lZCIpIHsNCiAgICAgICAgICAgICAgICBpbnRvW2tdID0gc3JjW2tdOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfQ0KfQ0KDQp4b29raS51cmwgPSB7DQogICAgICAgIG5ld1htbEh0dHBSZXF1ZXN0OiBmdW5jdGlvbigpIHsNCiAgICAgICAgLy8gd2UgZmlyc3QgdHJ5IHRvIHVzZSBBY3RpdmVYLCBiZWNhdXNlIElFNyBoYXMgYSBkaXJlY3Qgc3VwcG9ydCBmb3IgWG1sSHR0cFJlcXVlc3Qgb2JqZWN0LCANCiAgICAgICAgLy8gYnV0IHdoaWNoIGRvZXNuJ3Qgd29yayB3aXRoIGZpbGUgdXJscw0KICAgICAgICAJaWYod2luZG93LkFjdGl2ZVhPYmplY3QpDQogICAgICAgIAl7DQogICAgICAgIAkJdHJ5IHsgcmVxID0gbmV3IEFjdGl2ZVhPYmplY3QoIk1zeG1sMi5YTUxIVFRQIik7DQogICAgICAgIAkJfSBjYXRjaChlKSB7DQogICAgICAgIAkJCXRyeSB7IHJlcSA9IG5ldyBBY3RpdmVYT2JqZWN0KCJNaWNyb3NvZnQuWE1MSFRUUCIpOw0KICAgICAgICAJCQl9IGNhdGNoKGUpIHsgcmVxID0gZmFsc2U7IH0NCiAgICAgICAgCQl9DQogICAgICAgIAl9DQogICAgICAgIAllbHNlIGlmKHdpbmRvdy5YTUxIdHRwUmVxdWVzdCkgew0KICAgICAgICAJCXRyeSB7IHJlcSA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOw0KICAgICAgICAJCX0gY2F0Y2goZSkgeyByZXEgPSBmYWxzZTsgfQ0KICAgICAgICAJfQ0KICAgICAgICANCiAgICAgICAgCXJldHVybiByZXE7CQ0KICAgICAgICB9LA0KICAgICAgICAgICAgICAgIA0KICAgICAgICBsb2FkVVJMOiBmdW5jdGlvbiggdXJsICkgew0KICAgICAgICAJcmVxID0gdGhpcy5uZXdYbWxIdHRwUmVxdWVzdCgpOw0KICAgICAgICAJaWYocmVxKSB7DQogICAgICAgIAkJdHJ5IHsNCiAgICAgICAgCQkJcmVxLm9wZW4oIkdFVCIsIHVybCwgZmFsc2UpOw0KICAgICAgICAJCQlyZXEuc2VuZCgiIik7DQogICAgICAgIAkNCiAgICAgICAgCQkJcmV0dXJuIHJlcS5yZXNwb25zZVRleHQ7DQogICAgICAgIAkJfSBjYXRjaCAoZSkgew0KICAgICAgICAJCQl4b29raS5lcnJvcihlLCB0KCJwcm9ibGVtIHdoaWxlIGxvYWRpbmcgVVJMICR7MH0iLCB1cmwpKTsNCiAgICAgICAgICAgICAgICB9CQkNCiAgICAgICAgCX0NCiAgICAgICAgCXJldHVybiBudWxsOw0KICAgICAgICB9LA0KICAgICAgICANCiAgICAgICAgYXN5bmNMb2FkVVJMOiBmdW5jdGlvbiggdXJsLCBjYWxsYmFjaywgb2JqICkgew0KICAgICAgICAJdmFyIHJlcSA9IHRoaXMubmV3WG1sSHR0cFJlcXVlc3QoKTsNCiAgICAgICAgCWlmKHJlcSkgew0KICAgICAgICAJCXRyeSB7DQogICAgICAgIAkJCXJlcS5vcGVuKCJHRVQiLCB1cmwsIHRydWUpOw0KCQkJCSAgICByZXEub25yZWFkeXN0YXRlY2hhbmdlPWZ1bmN0aW9uKCkgew0KCQkJCSAgICAgICAgaWYgKHJlcS5yZWFkeVN0YXRlID09IDQpIHsNCgkJCQkgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09IDIwMCB8fCByZXEuc3RhdHVzID09IDApIHsNCgkJCQkgICAgICAgICAgICAgIGNhbGxiYWNrKHJlcS5yZXNwb25zZVRleHQsIG9iaik7DQoJCQkJICAgICAgICAgICB9DQoJCQkJICAgICAgICB9DQoJCQkJICAgICB9OyAgCQkJDQoJCQkJICAgICByZXEuc2VuZCgiIik7DQogICAgICAgIAkJfSBjYXRjaCAoZSkgew0KICAgICAgICAJCQl4b29raS5lcnJvcihlLCB0KCJwcm9ibGVtIHdoaWxlIGxvYWRpbmcgVVJMICR7MH0iLCB1cmwpKTsNCiAgICAgICAgICAgICAgICB9CQkNCiAgICAgICAgCX0NCiAgICAgICAgfSwNCg0KICAgICAgICBpbmNsdWRlOiBmdW5jdGlvbihzY3JpcHRfZmlsZW5hbWUpIHsNCiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKCc8JyArICdzY3JpcHQnKTsNCiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKCcgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiJyk7DQogICAgICAgICAgICBkb2N1bWVudC53cml0ZSgnIHR5cGU9InRleHQvamF2YXNjcmlwdCInKTsNCiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKCcgc3JjPSInICsgeG9va2kudShzY3JpcHRfZmlsZW5hbWUpICsgJyI+Jyk7DQogICAgICAgICAgICBkb2N1bWVudC53cml0ZSgnPC8nICsgJ3NjcmlwdCcgKyAnPicpOw0KICAgICAgICB9LA0KDQogICAgICAgIGFjdGlvbjogZnVuY3Rpb24oYWN0aW9uKSB7ICAgICAgICANCiAgICAgICAgICAgIC8vIHJldHVybnMgdGhlIHVybCBmb3IgYW4gYWN0aW9uIG9uIHRoZSBzYW1lIHBhZ2UNCiAgICAgICAgICAgIGxvYyA9IGJhdGNoTW9kZT8nJzp4b29raS5wYWdlVVJMOw0KICAgICAgICAgICAgaWYgKGxvYy5pbmRleE9mKCIjIikgIT0gLTEpIHsNCiAgICAgICAgICAgICAgICBsb2MgPSBsb2Muc3Vic3RyaW5nKDAsIGxvYy5pbmRleE9mKCIjIikpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIGxvYysiP2FjdGlvbj0iK2FjdGlvbjsNCiAgICAgICAgfQ0KDQogICAgfTsNCiAgICANCnhvb2tpLnN0cmluZyA9IHsNCg0KICAgIHN1YnN0aXR1dGVQYXJhbXM6IGZ1bmN0aW9uKC8qc3RyaW5nKi90ZW1wbGF0ZSwgLyogb2JqZWN0IC0gb3B0aW9uYWwgb3IgLi4uICovaGFzaCkgew0KICAgIC8vIGJvcnJvd2VkIGZyb20gZG9qbw0KICAgIC8vIHN1bW1hcnk6DQogICAgLy8JUGVyZm9ybXMgcGFyYW1ldGVyaXplZCBzdWJzdGl0dXRpb25zIG9uIGEgc3RyaW5nLiBUaHJvd3MgYW4gZXhjZXB0aW9uIGlmIGFueSBwYXJhbWV0ZXIgaXMgdW5tYXRjaGVkLg0KICAgIC8vDQogICAgLy8gZGVzY3JpcHRpb246DQogICAgLy8JRm9yIGV4YW1wbGUsDQogICAgLy8JCWRvam8uc3RyaW5nLnN1YnN0aXR1dGVQYXJhbXMoIkZpbGUgJyR7MH0nIGlzIG5vdCBmb3VuZCBpbiBkaXJlY3RvcnkgJyR7MX0nLiIsImZvby5odG1sIiwiL3RlbXAiKTsNCiAgICAvLwlyZXR1cm5zDQogICAgLy8JCSJGaWxlICdmb28uaHRtbCcgaXMgbm90IGZvdW5kIGluIGRpcmVjdG9yeSAnL3RlbXAnLiINCiAgICAvLw0KICAgIC8vIHRlbXBsYXRlOiB0aGUgb3JpZ2luYWwgc3RyaW5nIHRlbXBsYXRlIHdpdGggJHt2YWx1ZXN9IHRvIGJlIHJlcGxhY2VkDQogICAgLy8gaGFzaDogbmFtZS92YWx1ZSBwYWlycyAodHlwZSBvYmplY3QpIHRvIHByb3ZpZGUgc3Vic3RpdHV0aW9ucy4gIEFsdGVybmF0aXZlbHksIHN1YnN0aXR1dGlvbnMgbWF5IGJlDQogICAgLy8JaW5jbHVkZWQgYXMgYW4gYXJyYXkNCiAgICANCiAgICAgICAgdmFyIG1hcDsNCiAgICAgICAgaWYgKHR5cGVvZiBoYXNoID09ICJvYmplY3QiICYmIGhhc2gubGVuZ3RoKSB7IC8vIGFycmF5DQogICAgICAgICAgICBtYXAgPSB7fTsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gaGFzaCkgew0KICAgICAgICAgICAgICAgIG1hcFtpKyIiXSA9IGhhc2hbaV07DQogICAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBtYXAgPSBoYXNoOw0KICAgICAgICB9DQogICAgDQogICAgCXJldHVybiB0ZW1wbGF0ZS5yZXBsYWNlKC9cJFx7KFx3KylcfS9nLCBmdW5jdGlvbihtYXRjaCwga2V5KXsNCiAgICAJCWlmKHR5cGVvZihtYXBba2V5XSkgIT0gInVuZGVmaW5lZCIgJiYgbWFwW2tleV0gIT0gbnVsbCl7DQogICAgCQkJcmV0dXJuIG1hcFtrZXldOw0KICAgIAkJfQ0KICAgIAkJeG9va2kud2FybigiU3Vic3RpdHV0aW9uIG5vdCBmb3VuZDogIiArIGtleSk7DQogICAgCQlyZXR1cm4ga2V5Ow0KICAgIAl9KTsgLy8gc3RyaW5nDQoJfSwNCgkNCglwcm9jZXNzVGVtcGxhdGU6IGZ1bmN0aW9uKC8qc3RyaW5nKi90ZW1wbGF0ZSwgLyogb2JqZWN0ICovaGFzaCkgew0KCSAgIGlmICh0eXBlb2YgdGVtcGxhdGUucHJvY2VzcyA9PSAiZnVuY3Rpb24iKSB7DQoJICAgICAgIHJldHVybiB0ZW1wbGF0ZS5wcm9jZXNzKGhhc2gpOw0KICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICByZXR1cm4gdGhpcy5zdWJzdGl0dXRlUGFyYW1zKHRlbXBsYXRlLCBoYXNoKTsNCiAgICAgICB9DQogICAgfSwNCg0KICAgIGV4Y2VwdGlvblRleHQ6IGZ1bmN0aW9uKGUsIG1lc3NhZ2UpIHsNCiAgICAJdmFyIHMgPSBlLmRlc2NyaXB0aW9uID8gZS5kZXNjcmlwdGlvbiA6IGUudG9TdHJpbmcoKTsNCiAgICAJcmV0dXJuIG1lc3NhZ2UgPyBtZXNzYWdlKyI6XG4iK3MgOiBzOw0KICAgIH0sDQogICAgDQogICAgZmluZFhtbFNlY3Rpb246IGZ1bmN0aW9uKHN0ciwgZWxlbWVudCwgZnJvbSkgew0KICAgICAgICByZXR1cm4gdGhpcy5maW5kU2VjdGlvbihzdHIsIG5ldyBSZWdFeHAoJzwnK2VsZW1lbnQrJyhcXHMqXFx3Kz0iW1xcd1xcc10qIikqPicpLCBuZXcgUmVnRXhwKCc8LycrZWxlbWVudCsnPicpLCBmcm9tKTsNCiAgICB9LA0KICAgIA0KICAgIGZpbmQ6IGZ1bmN0aW9uKC8qc3RyaW5nKi9zdHIsIC8qc3RyaW5nIG9yIHJlZ2V4cCovZXhwLCAvKm51bWJlciwgb3B0aW9uYWwqL2Zyb20pIHsNCiAgICAgICAgLy8gZmluZCBhbiBleHByZXNzaW9uIChzdHJpbmcgb3IgcmVnZXhwKSBpbiBhIHN0cmluZywgZnJvbSBhbiBvcHRpb25hbCBpbmRleA0KICAgICAgICAvLyB0aGUgb2JqZWN0IHJldHVybmVkIGhhcyB0d28gcHJvcGVydGllczoNCiAgICAgICAgLy8gYmVnaW46IHRoZSBpbmRleCBpbiBzdHIgb2YgdGhlIG1hdGNoaW5nIGZpbmQNCiAgICAgICAgLy8gZW5kOiB0aGUgaW5kZXggaW4gc3RyIG9mIHRoZSBlbmQgb2YgdGhlIG1hdGNoaW5nIGZpbmQNCiAgICAgICAgLy8gcmV0dXJucyBudWxsIGlmIG5vIG1hdGNoIGlzIGZvdW5kDQogICAgICAgIGlmICh0eXBlb2YgZnJvbSAhPSAibnVtYmVyIikgew0KICAgICAgICAgICAgZnJvbSA9IDA7DQogICAgICAgIH0NCiAgICAgICAgaWYgKHR5cGVvZiBleHAgPT0gInN0cmluZyIpIHsNCiAgICAgICAgICAgIHZhciByZXN1bHQgPSB7fTsNCiAgICAgICAgICAgIHJlc3VsdC5iZWdpbiA9IHN0ci5pbmRleE9mKGV4cCxmcm9tKTsNCiAgICAgICAgICAgIGlmIChyZXN1bHQuYmVnaW4gPj0gMCkgew0KICAgICAgICAgICAgICAgIHJlc3VsdC5lbmQgPSByZXN1bHQuYmVnaW4gKyBleHAubGVuZ3RoOw0KICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7DQogICAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICB2YXIgbTsNCiAgICAgICAgICAgIGlmIChmcm9tID4gMCkgew0KICAgICAgICAgICAgICAgIC8vIEkgaGF2ZW4ndCBmb3VuZCBhbnkgb3RoZXIgd2F5IHRvIHN0YXJ0IGZyb20gdGhlIGdpdmVuIGluZGV4DQogICAgICAgICAgICAgICAgbSA9IGV4cC5leGVjKHN0ci5zdWJzdHJpbmcoZnJvbSkpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBtID0gZXhwLmV4ZWMoc3RyKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChtICE9IG51bGwpIHsgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHt9Ow0KICAgICAgICAgICAgICAgIHJlc3VsdC5iZWdpbiA9IG0uaW5kZXggKyBmcm9tOw0KICAgICAgICAgICAgICAgIHJlc3VsdC5lbmQgPSByZXN1bHQuYmVnaW4gKyBtWzBdLmxlbmd0aDsNCiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0Ow0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIHJldHVybiBudWxsOw0KICAgIH0sDQogICAgDQogICAgZmluZFNlY3Rpb246IGZ1bmN0aW9uKC8qc3RyaW5nKi9zdHIsIC8qc3RyaW5nIG9yIHJlZ2V4cCovb3BlbiwgLypzdHJpbmcgb3IgcmVnZXhwKi9jbG9zZSwgLypudW1iZXIsIG9wdGlvbmFsKi9mcm9tKSB7DQogICAgICAgIC8vIGZpbmRzIGEgc2VjdGlvbiBkZWxpbWl0ZWQgYnkgb3BlbiBhbmQgY2xvc2UgdG9rZW5zIGluIHRoZSBnaXZlbiBzdHJpbmcNCiAgICAgICAgLy8gdGhlIGFsZ29yaXRobSBsb29rcyBmb3IgbWF0Y2hpbmcgb3BlbiBhbmQgY2xvc2UgdG9rZW5zDQogICAgICAgIC8vIHRoZSByZXR1cm5lZCBvYmplY3QgaGFzIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczoNCiAgICAgICAgLy8gICBvdXRlclN0YXJ0OiB0aGUgaW5kZXggaW4gc3RyIHdoZXJlIHRoZSBmaXJzdCBvcGVuIHRva2VuIHdhcyBmb3VuZA0KICAgICAgICAvLyAgIGlubmVyU3RhcnQ6IHRoZSBpbmRleCBpbiBzdHIganVzdCBhZnRlciB0aGUgZm91bmQgb3BlbiB0b2tlbg0KICAgICAgICAvLyAgIGlubmVyRW5kOiB0aGUgaW5kZXggaW4gc3RyIHdoZXJlIHRoZSBtYXRjaGluZyBjbG9zZSB0b2tlbiB3YXMgZm91bmQNCiAgICAgICAgLy8gICBvdXRlckVuZDogdGhlIGluZGV4IGluIHN0ciBqdXN0IGFmdGVyIHRoZSBtYXRjaGluZyBjbG9zZSB0b2tlbg0KICAgICAgICAvLyAgIGNoaWxkcmVuOiBhbiBhcnJheSBvZiBzaW1pbGFyIG9iamVjdHMgaWYgbmVzdGVkIHNlY3Rpb25zIHdoZXJlIGZvdW5kDQogICAgICAgIC8vIGlmIG5vIHNlY3Rpb24gaXMgZm91bmQgKG5vIG9wZW4gdG9rZW4sIGFuIG9wZW4gdG9rZW4gd2l0aCBubyBtYXRjaGluZyANCiAgICAgICAgLy8gY2xvc2UgdG9rZW4sIG9yIGEgY2xvc2UgdG9rZW4gYmVmb3JlIGFuIG9wZW4gdG9rZW4pLCBudWxsIGlzIHJldHVybmVkDQogICAgICAgIC8vDQogICAgICAgIC8vIGZvciBpbnN0YW5jZSBpZiBvcGVuPT0nKCcgYW5kIGNsb3NlPT0nKScgdGhlbiB0aGUgc2VjdGlvbiB3aWxsIGZpbmQNCiAgICAgICAgLy8gYSBzZWN0aW9uIGRlbGltaXRlZCBieSB0aGUgZmlyc3QgZm91bmQgb3BlbiBwYXJlbnRoZXNpcyBhbmQgdGhlIG1hdGNoaW5nDQogICAgICAgIC8vIGNsb3NlIHBhcmVudGV0aGlzLCB0YWtpbmcgaW50byBhY2NvdW50IG90aGVyIG9wZW5pbmcgcGFyZW50ZXRoaXMNCiAgICAgICAgLy8gZXhhbXBsZXM6DQogICAgICAgIC8vIGZpbmRTZWN0aW9uKCJhKHRlc3QpYiIsICIoIiwgIikiKSA9PSB7b3V0ZXJTdGFydDogMSwgaW5uZXJTdGFydDoyLCBpbm5lckVuZDo2LCBvdXRlckVuZDo3LCBjaGlsZHJlbjpbXX0NCiAgICAgICAgLy8gZmluZFNlY3Rpb24oImEodGUocykodCkpYiIsICIoIiwgIikiKSA9PSB7b3V0ZXJTdGFydDogMSwgaW5uZXJTdGFydDoyLCBpbm5lckVuZDoxMCwgb3V0ZXJFbmQ6MTEsIA0KICAgICAgICAvLyAgICAgIGNoaWxkcmVuOlsNCiAgICAgICAgLy8gICAgICAgICAge291dGVyU3RhcnQ6IDQsIGlubmVyU3RhcnQ6NSwgaW5uZXJFbmQ6Niwgb3V0ZXJFbmQ6NywgY2hpbGRyZW46W119LA0KICAgICAgICAvLyAgICAgICAgICB7b3V0ZXJTdGFydDogNywgaW5uZXJTdGFydDo4LCBpbm5lckVuZDo5LCBvdXRlckVuZDoxMCwgY2hpbGRyZW46W119DQogICAgICAgIC8vICAgICAgXX0NCiAgICAgICAgDQogICAgICAgIHZhciBvcGVuUmVzdWx0ID0gdGhpcy5maW5kKHN0ciwgb3BlbiwgZnJvbSk7ICAgICAgICANCiAgICAgICAgaWYgKG9wZW5SZXN1bHQgPT0gbnVsbCkgew0KICAgICAgICAgICAgcmV0dXJuIG51bGw7DQogICAgICAgIH0NCiAgICAgICAgdmFyIGNsb3NlUmVzdWx0ID0gdGhpcy5maW5kKHN0ciwgY2xvc2UsIGZyb20pOyAgICAgICAgDQogICAgICAgIGlmIChjbG9zZVJlc3VsdCA9PSBudWxsIHx8IGNsb3NlUmVzdWx0LmJlZ2luIDwgb3BlblJlc3VsdC5lbmQpIHsNCiAgICAgICAgICAgIHJldHVybiBudWxsOw0KICAgICAgICB9DQogICAgICAgIGlmIChvcGVuUmVzdWx0LmVuZCA8PSBvcGVuUmVzdWx0LmJlZ2luIHx8IGNsb3NlUmVzdWx0LmVuZCA8PSBjbG9zZVJlc3VsdC5iZWdpbikgew0KICAgICAgICAgICAgLy8gZW1wdHkgbWF0Y2ggYXJlIG5vdCBhbGxvd2VkDQogICAgICAgICAgICByZXR1cm4gbnVsbDsNCiAgICAgICAgfQ0KICAgICAgICANCiAgICAgICAgdmFyIGNoaWxkcmVuID0gW107DQogICAgICAgIHZhciBjaGlsZCA9IHRoaXMuZmluZFNlY3Rpb24oc3RyLCBvcGVuLCBjbG9zZSwgb3BlblJlc3VsdC5lbmQpOw0KICAgICAgICB3aGlsZSAoY2hpbGQgIT0gbnVsbCkgew0KICAgICAgICAgICAgaWYgKGNoaWxkLm91dGVyRW5kID4gY2xvc2VSZXN1bHQuYmVnaW4pIHsNCiAgICAgICAgICAgICAgICBjbG9zZVJlc3VsdCA9IHRoaXMuZmluZChzdHIsIGNsb3NlLCBjaGlsZC5vdXRlckVuZCk7ICAgICAgICANCiAgICAgICAgICAgICAgICBpZiAoY2xvc2VSZXN1bHQgPT0gbnVsbCkgew0KICAgICAgICAgICAgICAgICAgICAvLyB1bm1hdGNoZWQgb3BlbiB0b2tlbg0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGNoaWxkKTsNCiAgICAgICAgICAgIGNoaWxkID0gdGhpcy5maW5kU2VjdGlvbihzdHIsIG9wZW4sIGNsb3NlLCBjaGlsZC5vdXRlckVuZCk7DQogICAgICAgIH0NCg0KICAgICAgICByZXR1cm4gew0KICAgICAgICAgICAgb3V0ZXJTdGFydDogb3BlblJlc3VsdC5iZWdpbiwNCiAgICAgICAgICAgIGlubmVyU3RhcnQ6IG9wZW5SZXN1bHQuZW5kLA0KICAgICAgICAgICAgaW5uZXJFbmQ6IGNsb3NlUmVzdWx0LmJlZ2luLA0KICAgICAgICAgICAgb3V0ZXJFbmQ6IGNsb3NlUmVzdWx0LmVuZCwNCiAgICAgICAgICAgIGNoaWxkcmVuOiBjaGlsZHJlbg0KICAgICAgICB9OyAgICAgICAgDQogICAgfQ0KfTsNCiAgICANCnhvb2tpLmpzb24gPSB7DQogICAgICAgIGV2YWxKc29uOiBmdW5jdGlvbiAoc3RyKSB7DQogICAgICAgICAgICB0cnkgew0KICAgICAgICAgICAgICAgIHJldHVybiBldmFsKCIoIitzdHIrIikiKTsNCiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsNCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfSwNCiAgICAgICAgDQogICAgICAgIGxvYWRVUkw6IGZ1bmN0aW9uICh1cmwpIHsNCiAgICAgICAgICAgIHJldHVybiB0aGlzLmV2YWxKc29uKHhvb2tpLnVybC5sb2FkVVJMKHVybCkpOw0KICAgICAgICB9DQogICAgfTsNCg0KLy8gRGlzcGxheXMgYW4gYWxlcnQgb2YgYW4gZXhjZXB0aW9uIGRlc2NyaXB0aW9uIHdpdGggb3B0aW9uYWwgbWVzc2FnZQ0KeG9va2kud2FybiA9IGZ1bmN0aW9uKGUsIG1lc3NhZ2UpIHsNCiAgICB4b29raS5kaXNwbGF5KHhvb2tpLnN0cmluZy5leGNlcHRpb25UZXh0KGUsIG1lc3NhZ2UpLCAiI2VlY2NjYyIpOw0KfQ0KDQovLyBEaXNwbGF5cyBhbiBhbGVydCBvZiBhbiBleGNlcHRpb24gZGVzY3JpcHRpb24gd2l0aCBvcHRpb25hbCBtZXNzYWdlDQp4b29raS5lcnJvciA9IGZ1bmN0aW9uKGUsIG1lc3NhZ2UpIHsNCiAgICB4b29raS5kaXNwbGF5KHhvb2tpLnN0cmluZy5leGNlcHRpb25UZXh0KGUsIG1lc3NhZ2UpLCAiI2ZmZGRkZCIpOw0KfQ0KDQp4b29raS5pbmZvID0gZnVuY3Rpb24obWVzc2FnZSkgew0KICAgIHhvb2tpLmRpc3BsYXkobWVzc2FnZSwgIiNkZGRkZmYiKTsNCn0NCg0KeG9va2kuZGlzcGxheSA9IGZ1bmN0aW9uKG1lc3NhZ2UsIGJhY2tncm91bmQpIHsNCiAgICB2YXIgbWVzc2FnZXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktbWVzc2FnZXMnKTsNCiAgICBpZiAobWVzc2FnZXMpIHsNCiAgICAgICAgbWVzc2FnZXMuaW5uZXJIVE1MID0gJzx0YWJsZSB3aWR0aD0iMTAwJSIgYm9yZGVyPSIwIj48dHI+PHRkIGFsaWduPSJjZW50ZXIiPicrbWVzc2FnZSsnPC90ZD48L3RyPjwvdGFibGU+JzsNCiAgICAgICAgbWVzc2FnZXMuc3R5bGUuYmFja2dyb3VuZCA9IGJhY2tncm91bmQ7DQogICAgICAgIG1lc3NhZ2VzLnN0eWxlLmRpc3BsYXkgPSAiaW5saW5lIjsNCiAgICB9IGVsc2Ugew0KICAgICAgICBhbGVydChtZXNzYWdlKTsNCiAgICB9DQp9DQoNCnhvb2tpLmRlYnVnID0gZnVuY3Rpb24obWVzc2FnZSkgew0KICAgIHZhciBjb25zb2xlID0gdHlwZW9mIGRvY3VtZW50ID09ICd1bmRlZmluZWQnID8gZmFsc2UgOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktY29uc29sZScpOw0KICAgIGlmIChjb25zb2xlKSB7DQogICAgICAgIGNvbnNvbGUudmFsdWUgKz0gbWVzc2FnZSArICJcbiI7DQogICAgfSBlbHNlIHsNCiAgICAgICAgeG9va2kuY29uc29sZSArPSBtZXNzYWdlICsgIlxuIjsNCiAgICB9DQp9DQoNCnhvb2tpLmRlYnVnU2hvd0RldGFpbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7DQogICAgdmFyIGRldGFpbCA9IHR5cGVvZiBkb2N1bWVudCA9PSAndW5kZWZpbmVkJyA/IGZhbHNlIDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3hvb2tpLWRlYnVnLWRldGFpbCcpOw0KICAgIGlmIChkZXRhaWwpIHsNCiAgICAgICAgZGV0YWlsLnZhbHVlPW1lc3NhZ2U7DQogICAgfSBlbHNlIHsNCiAgICAgICAgYWxlcnQobWVzc2FnZSk7DQogICAgfQ0KfQ0KDQoNCnhvb2tpLmh0bWwgPSB7DQogICAgaGlkZTogZnVuY3Rpb24oZGl2aWQpIHsNCgkgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChkaXZpZCkuc3R5bGUuZGlzcGxheSA9ICdub25lJzsNCiAgICB9LA0KDQogICAgc2hvdzogZnVuY3Rpb24gKGRpdmlkKSB7DQoJICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZGl2aWQpLnN0eWxlLmRpc3BsYXkgPSAnJzsNCiAgICB9LA0KICAgIA0KICAgIHBhZ2VMaW5rOiBmdW5jdGlvbihwYWdlKSB7DQogICAgCWlmIChwYWdlLmlzQWJzdHJhY3QpIHsNCiAgICAJCXJldHVybiBwYWdlLnRpdGxlOw0KICAgIAl9IGVsc2Ugew0KICAgIAkJcmV0dXJuICc8YSBocmVmPSInK3B1KHBhZ2UuaWQpKyciICcrKHBhZ2UuaWQgPT0geG9va2kucGFnZS5pZD8nY2xhc3M9ImN1cnJlbnQiJzonJykrJz4nK3BhZ2UudGl0bGUrJzwvYT4nOw0KICAgIAl9DQogICAgfSwNCgkNCgkvLyBpbnNlcnQgIHRoZSBnaXZlbiAgaGVhZGVyIGluIHRoZSBodG1sIGhlYWQNCgkvLyBjYW4gYmUgdXNlZCBvbmx5IHdoZW4gdGhlIGJyb3dzZXIgaXMgc3RpbGwgaW4gdGhlIGhlYWQgIQ0KCWFkZEhlYWRlcjogZnVuY3Rpb24oLyogc3RyaW5nICovIGhlYWQpIHsNCgkJZG9jdW1lbnQud3JpdGUoaGVhZCk7DQoJfSwNCgkNCglzZXRCb2R5OiBmdW5jdGlvbiggLyogc3RyaW5nICovIGJvZHkpIHsNCgkJZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPSBib2R5Ow0KCX0NCn07DQoNCnhvb2tpLmNvbXBvbmVudCA9IHsNCiAgICBjaGlsZHJlbkxpc3Q6IGZ1bmN0aW9uICgpIHsNCiAgICAJaWYgKHhvb2tpLnBhZ2UuY2hpbGRyZW4ubGVuZ3RoID4gMCkgew0KICAgIAkJY2hpbGRyZW5MaXN0ID0gJzx1bCBjbGFzcz0iJytjc3MoJ2NoaWxkcmVuTGlzdCcpKyciPic7DQogICAgCQlmb3IgKHZhciBpIGluIHhvb2tpLnBhZ2UuY2hpbGRyZW4pIHsNCiAgICAJCQljaGlsZHJlbkxpc3QrPSc8bGk+Jyt4b29raS5odG1sLnBhZ2VMaW5rKHhvb2tpLnBhZ2UuY2hpbGRyZW5baV0pKyc8L2xpPic7DQogICAgCQl9DQogICAgCQljaGlsZHJlbkxpc3QgKz0gIjwvdWw+IjsNCiAgICAJCXJldHVybiBjaGlsZHJlbkxpc3Q7DQogICAgCX0gZWxzZSB7DQogICAgCSAgIHJldHVybiAiIjsNCiAgICAgICAgfQ0KICAgIH0sDQogICAgDQogICAgbWVudTogZnVuY3Rpb24gKCkgew0KICAgIAl2YXIgbWVudSA9ICc8dWwgaWQ9IicrY3NzKCJ0cmVlbWVudSIpKyciIGNsYXNzPSJ0cmVldmlldyI+JzsNCiAgICAJbWVudSArPSAoZnVuY3Rpb24gKHBhZ2UpIHsNCiAgICAgICAgCXZhciBtZW51ID0gJyc7DQogICAgICAgIAlmb3IgKHZhciBpICBpbiBwYWdlLmNoaWxkcmVuKSB7DQogICAgICAgIAkJbWVudSArPSAnPGxpIGlkPSJ4b29raS0nK3BhZ2UuY2hpbGRyZW5baV0uaWQrJyI+Jyt4b29raS5odG1sLnBhZ2VMaW5rKHBhZ2UuY2hpbGRyZW5baV0pOw0KICAgICAgICAJCXNtZW51ID0gYXJndW1lbnRzLmNhbGxlZShwYWdlLmNoaWxkcmVuW2ldKTsNCiAgICAgICAgCQlpZiAoc21lbnUgIT0gJycpIHsNCiAgICAgICAgCQkJaWYgKHNtZW51LmluZGV4T2YoJ2lkPSJ4b29raS0nK3hvb2tpLnBhZ2UuaWQrJyInKSAhPSAtMSANCiAgICAgICAgCQkJCXx8IHBhZ2UuY2hpbGRyZW5baV0uaWQgPT0geG9va2kucGFnZS5pZCkgew0KICAgICAgICAJCQkJLy8gZWl0aGVyIGEgZGVzY2VuZGFudCBvciB0aGUgbm9kZSBwcm9jZXNzZWQgaXMgdGhlIGN1cnJlbnQgcGFnZSBub2RlDQogICAgICAgIAkJCQkvLyB3ZSBzcGVjaWZ5IHRoYXQgdGhlIG1lbnUgbXVzdCBiZSBvcGVuZWQgYnkgZGVmYXVsdA0KICAgICAgICAJCQkJbWVudSArPSAnPHVsIHJlbD0ib3BlbiInOw0KCSAgICAgICAgCQkJbWVudSArPSAnPicrc21lbnUrJzwvdWw+JzsNCiAgICAgICAgCQkJfSBlbHNlIGlmICh4b29raS5jLnVzZWRkdHJlZSkgew0KCQkJCQkJbWVudSArPSAnPHVsICc7DQoJICAgICAgICAJCQltZW51ICs9ICc+JytzbWVudSsnPC91bD4nOw0KCQkJCQl9DQogICAgICAgIAkJfSANCiAgICAgICAgCQltZW51ICs9ICc8L2xpPic7DQogICAgICAgIAl9DQogICAgICAgIAlyZXR1cm4gbWVudTsNCiAgICAgICAgfSkoeG9va2kudG9jKTsNCiAgICAJbWVudSArPSAnPC91bD4nOw0KICAgIAlyZXR1cm4gbWVudTsNCiAgICB9LA0KICAgIA0KICAgIG1lc3NhZ2VzOiBmdW5jdGlvbiAoKSB7DQogICAgICAgIHJldHVybiAnPGRpdiBpZD0ieG9va2ktbWVzc2FnZXMiIG9uY2xpY2s9Inhvb2tpLmh0bWwuaGlkZShcJ3hvb2tpLW1lc3NhZ2VzXCcpIiBzdHlsZT0iekluZGV4Ojk5OTtkaXNwbGF5Om5vbmU7cG9zaXRpb246YWJzb2x1dGU7dG9wOjMwcHg7cGFkZGluZzoxMHB4O2JvcmRlci1zdHlsZTpzb2xpZDtiYWNrZ3JvdW5kOiNlZWVlZWU7Ij48L2Rpdj4nOw0KICAgIH0sDQoNCiAgICBkZWJ1Z1BhbmVsOiBmdW5jdGlvbiAoKSB7DQogICAgICAgIHJldHVybiAnPGRpdiBpZD0ieG9va2ktZGVidWciIHN0eWxlPSJkaXNwbGF5Om5vbmU7bWFyZ2luLXRvcDoxNXB4O3BhZGRpbmc6MTBweDtib3JkZXItc3R5bGU6c29saWQ7YmFja2dyb3VuZDojZWVlZWVlOyI+PHN0cm9uZz5Yb29raSBDb25zb2xlPC9zdHJvbmc+PGJyLz48dGV4dGFyZWEgY29scz0iMTAwIiByb3dzPSIxNSIgaWQ9Inhvb2tpLWNvbnNvbGUiPicreG9va2kuY29uc29sZSsnPC90ZXh0YXJlYT48aHIvPjxhIGhyZWY9ImphdmFzY3JpcHQ6eG9va2kuZGVidWdTaG93RGV0YWlsKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwneG9va2ktYm9keVwnKS5pbm5lckhUTUwpIj5jb250ZW50PC9hPiA8YSBocmVmPSJqYXZhc2NyaXB0Onhvb2tpLmRlYnVnU2hvd0RldGFpbCh4b29raS5jLmJvZHkpIj54b29raSBib2R5PC9hPiA8YSBocmVmPSJqYXZhc2NyaXB0Onhvb2tpLmRlYnVnU2hvd0RldGFpbChkb2N1bWVudC5ib2R5LmlubmVySFRNTCkiPndob2xlIGJvZHk8L2E+IDxhIGhyZWY9ImphdmFzY3JpcHQ6eG9va2kuYWN0aW9uLmV2YWx1YXRlKCkiPmV2YWx1YXRlPC9hPjxici8+PHRleHRhcmVhIGNvbHM9IjEwMCIgcm93cz0iMTUiIGlkPSJ4b29raS1kZWJ1Zy1kZXRhaWwiPjwvdGV4dGFyZWE+PC9kaXY+JzsNCiAgICB9LA0KDQogICAgcHJpbnRlckZyaWVuZGx5TG9jYXRpb246IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgcmV0dXJuIHhvb2tpLnVybC5hY3Rpb24oInByaW50Iik7DQogICAgfSwNCg0KICAgIHByaW50ZXJGcmllbmRseUxpbms6IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgcmV0dXJuICc8YSBocmVmPSInK3RoaXMucHJpbnRlckZyaWVuZGx5TG9jYXRpb24oKSsnIj4nK3QoJ1ByaW50ZXIgRnJpZW5kbHknKSsnPC9hPic7DQogICAgfSwNCg0KICAgIGJyZWFkQ3J1bWI6IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgdmFyIGJyZWFkQ3J1bWIgPSAnPHNwYW4gY2xhc3M9ImJyZWFkQ3J1bWIiPic7DQoJCWJyZWFkQ3J1bWIgKz0gKGZ1bmN0aW9uIChwYWdlKSB7DQogICAgICAgIAl2YXIgYnJlYWRDcnVtYiA9IHhvb2tpLmh0bWwucGFnZUxpbmsocGFnZSk7DQoJCQlpZiAocGFnZS5tZXRhLmxldmVsID49IDEpIHsNCgkJCQlicmVhZENydW1iID0gYXJndW1lbnRzLmNhbGxlZShwYWdlLm1ldGEucGFyZW50KSArICIgJmd0OyAiICsgYnJlYWRDcnVtYjsNCgkJCX0NCiAgICAgICAgCXJldHVybiBicmVhZENydW1iOw0KICAgICAgICB9KSh4b29raS5wYWdlKTsNCgkJYnJlYWRDcnVtYiArPSAnPC9zcGFuPic7DQoJCXJldHVybiBicmVhZENydW1iOw0KICAgIH0NCn07DQoNCnhvb2tpLnJlbmRlciA9IHt9Ow0KeG9va2kucmVuZGVyLnByaW50ZXJGcmllbmRseUFzeW5jTG9hZGVyID0gZnVuY3Rpb24oc291cmNlLCBhcnIpIHsNCgl2YXIgcm9vdCA9IGFyclswXTsNCgl2YXIgcGFnZSA9IGFyclsxXTsNCiAgICBpZiAoc291cmNlID09IG51bGwpIHsNCiAgICAgICAgcmV0dXJuOw0KICAgIH0NCgl2YXIgbGV2ZWwgPSBwYWdlLm1ldGEubGV2ZWwgLSByb290Lm1ldGEubGV2ZWwgKyAxOw0KCQ0KICAgIC8vIGNvbXB1dGUgcHJpbnRlciBmcmllbmRseSBibG9jaw0KICAgIHZhciBiZWdpbkluZGV4ID0gc291cmNlLmluZGV4T2YoJzx0ZXh0YXJlYSBpZD0ieG9va2ktc291cmNlIj4nKTsNCiAgICBiZWdpbkluZGV4ICs9ICc8dGV4dGFyZWEgaWQ9Inhvb2tpLXNvdXJjZSI+Jy5sZW5ndGg7DQogICAgdmFyIGVuZEluZGV4ID0gc291cmNlLmxhc3RJbmRleE9mKCc8L3RleHRhcmVhPicpOw0KICAgIHNvdXJjZSA9IHNvdXJjZS5zdWJzdHJpbmcoYmVnaW5JbmRleCwgZW5kSW5kZXgpOw0KICAgIA0KICAgIHZhciBwcmludGVyRnJpZW5kbHkgPSAiPGgiK2xldmVsKyI+IitwYWdlLnRpdGxlKyI8L2giK2xldmVsKyI+IjsNCiAgICBwcmludGVyRnJpZW5kbHkgKz0geG9va2kuaW5wdXQuZm9ybWF0Lm1haW4oc291cmNlKSArICI8aHIvPiI7DQogICAgLy8gaW5qZWN0IGJsb2NrIGluIHBhZ2UNCiAgICB2YXIgcGYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktcHJpbnRlckZyaWVuZGx5Jyk7DQogICAgcGYuaW5uZXJIVE1MICs9IHByaW50ZXJGcmllbmRseTsgICAgDQogICAgDQogICAgLy8gY29udGludWUgcmVjdXJzaXZlIGxvYWRpbmcNCiAgIAl2YXIgbmV4dFBhZ2UgPSB4b29raS50b2MuZ2V0TmV4dFBhZ2UocGFnZSwgcm9vdCk7DQogICAJaWYgKG5leHRQYWdlICE9IG51bGwpIHsNCiAgICAJeG9va2kudXJsLmFzeW5jTG9hZFVSTChwdShuZXh0UGFnZS5pZCksIHhvb2tpLnJlbmRlci5wcmludGVyRnJpZW5kbHlBc3luY0xvYWRlciwgW3Jvb3QsIG5leHRQYWdlXSk7DQogICAJfQ0KfTsNCnhvb2tpLnJlbmRlci5wcmludGVyRnJpZW5kbHkgPSBmdW5jdGlvbigpIHsNCiAgICBmb3IgKHZhciBrIGluIHhvb2tpLmNvbXBvbmVudCkgew0KICAgICAgICB4b29raS5jW2tdID0geG9va2kuY29tcG9uZW50W2tdKCk7DQogICAgfQ0KICAgIA0KCXhvb2tpLmMuYm9keSA9IHhvb2tpLmMubWVzc2FnZXMNCgkrICI8ZGl2IGlkPSd4b29raS1wcmludGVyRnJpZW5kbHknPjwvZGl2PiIgLy8gZGl2IHdoZXJlIHByaW50ZXIgZnJpZW5kbHkgY29udGVudCB3aWxsIGJlIHB1dA0KICAgICsgeG9va2kuYy5kZWJ1Z1BhbmVsOw0KICAgIA0KICAgIGRvY3VtZW50LmJvZHkuaW5uZXJIVE1MID0geG9va2kuc3RyaW5nLnByb2Nlc3NUZW1wbGF0ZSh4b29raS50ZW1wbGF0ZS5ib2R5LCB4b29raS5jKTsNCiAgICANCiAgICAvLyBzdGFydCBhc3luYyBsb2FkaW5nIG9mIGNvbnRlbnQNCiAgICB4b29raS51cmwuYXN5bmNMb2FkVVJMKHB1KHhvb2tpLnBhZ2UuaWQpLCB4b29raS5yZW5kZXIucHJpbnRlckZyaWVuZGx5QXN5bmNMb2FkZXIsIFt4b29raS5wYWdlLCB4b29raS5wYWdlXSk7DQp9Ow0KDQp4b29raS5yZW5kZXIucGFnZSA9IGZ1bmN0aW9uKCkgew0KICAgIC8vIHJlYWxpemUgYWxsIGNvbXBvbmVudHMgYXZhaWxhYmxlDQogICAgZm9yICh2YXIgayBpbiB4b29raS5jb21wb25lbnQpIHsNCiAgICAgICAgeG9va2kuY1trXSA9IHhvb2tpLmNvbXBvbmVudFtrXSgpOw0KICAgIH0NCiAgICANCiAgICB4b29raS5pbnB1dC5zb3VyY2UoKTsNCiAgICANCiAgICBpZiAoeG9va2kuYy5hbGxvd0VkaXQpIHsNCiAgICAJeG9va2kuYy5ib2R5ID0geG9va2kuYy5tZXNzYWdlcw0KICAgICAgICAgICAgKyB4b29raS5jLnRvb2xiYXINCiAgICAgICAgICAgICsgJzxkaXYgaWQ9Inhvb2tpLWNvbnRlbnQiPicgDQogICAgICAgICAgICAgICAgKyAnPGRpdiBpZD0ieG9va2ktYm9keSI+PC9kaXY+Jw0KICAgICAgICAgICAgKyAnPC9kaXY+Jw0KICAgICAgICAgICAgKyB4b29raS5jLmVkaXRab25lDQogICAgICAgICAgICArIHhvb2tpLmMuZGVidWdQYW5lbDsNCiAgICB9IGVsc2Ugew0KICAgIAl4b29raS5jLmJvZHkgPSB4b29raS5jLm1lc3NhZ2VzDQogICAgICAgICAgICArICc8ZGl2IGlkPSJ4b29raS1jb250ZW50Ij4nIA0KICAgICAgICAgICAgICAgICsgJzxkaXYgaWQ9Inhvb2tpLWJvZHkiPjwvZGl2PicNCiAgICAgICAgICAgICsgJzwvZGl2PicNCiAgICAgICAgICAgICsgeG9va2kuYy5kZWJ1Z1BhbmVsOw0KICAgIH0NCg0KICAgIHhvb2tpLmh0bWwuc2V0Qm9keSh4b29raS5zdHJpbmcucHJvY2Vzc1RlbXBsYXRlKHhvb2tpLnRlbXBsYXRlLmJvZHksIHhvb2tpLmMpKTsNCiAgICANCiAgICB4b29raS5pbnB1dC5hcHBseUNoYW5nZXMoKTsNCiAgICANCglpZiAoeG9va2kuYy51c2VkZHRyZWUpIHsNCgkgICAgLy8gZW5hYmxlIGR5bmFtaWMgdHJlZSBtZW51IA0KCQlkZHRyZWVtZW51LmNyZWF0ZVRyZWUoY3NzKCJ0cmVlbWVudSIpLCBmYWxzZSk7DQoJfQ0KfTsNCg0KeG9va2kucmVuZGVyLm1haW4gPSBmdW5jdGlvbigpIHsNCiAgICBpZiAoeG9va2kuYy5hY3Rpb24gPT0gInByaW50Iikgew0KICAgICAgICAvLyByZW5kZXIgdGhlIHByaW50ZXIgZnJpZW5kbHkgdmVyc2lvbiBvZiB0aGUgcGFnZQ0KICAgICAgICB0aGlzLnByaW50ZXJGcmllbmRseSgpOw0KICAgIH0gZWxzZSB7DQogICAgICAgIC8vIHJlbmRlciB0aGUgcGFnZSBub3JtYWxseQ0KICAgICAgICB0aGlzLnBhZ2UoKTsNCiAgICB9DQp9Ow0KDQp4b29raS5pbnB1dCA9IHsNCiAgICBzb3VyY2U6IGZ1bmN0aW9uKCkgew0KICAgICAgICBpZiAodHlwZW9mIGRvY3VtZW50ICE9ICd1bmRlZmluZWQnICYmIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd4b29raS1zb3VyY2UnKSAhPSBudWxsKSB7DQogICAgICAgICAgICB0aGlzLl9zb3VyY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktc291cmNlJykudmFsdWU7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZTsNCiAgICB9LA0KICAgIHByb2Nlc3NlZDogZnVuY3Rpb24oKSB7DQogICAgICAgIHJldHVybiB0aGlzLmZvcm1hdC5tYWluKHRoaXMuc291cmNlKCkpOw0KICAgIH0sDQogICAgDQogICAgZm9ybWF0OiB7DQogICAgICAgIGdldElucHV0RmlsdGVyczogZnVuY3Rpb24gKGlucHV0Rm9ybWF0KSB7DQogICAgICAgICAgICByZXR1cm4geG9va2kuY1tpbnB1dEZvcm1hdCsiSW5wdXRGb3JtYXQiXTsNCiAgICAgICAgfSwNCiAgICAgICAgZGVmaW5lOiBmdW5jdGlvbiAoaW5wdXRGb3JtYXQsIGZpbHRlcnMpIHsNCiAgICAgICAgICAgIC8vIGRlZmluZSBhIG5ldyBpbnB1dEZvcm1hdA0KICAgICAgICAgICAgLy8gaW5wdXRGb3JtYXQ6IHRoZSBuZXcgaW5wdXQgZm9ybWF0IG5hbWUNCiAgICAgICAgICAgIC8vIGZpbHRlcnM6IGFuIGFycmF5IG9mIGlucHV0IGZpbHRlciBuYW1lcw0KICAgICAgICAgICAgeG9va2kuY1tpbnB1dEZvcm1hdCsiSW5wdXRGb3JtYXQiXSA9IGZpbHRlcnM7DQogICAgICAgIH0sDQogICAgICAgIG1haW46IGZ1bmN0aW9uKHNvdXJjZSkgew0KICAgICAgICAgICAgLy8gZm9ybWF0cyBhbiBpbnB1dCBzb3VyY2UNCiAgICAgICAgICAgIGlmICh4b29raS5jLmlucHV0Rm9ybWF0ICYmIHR5cGVvZiB0aGlzLmdldElucHV0RmlsdGVycyh4b29raS5jLmlucHV0Rm9ybWF0KSAhPSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgICAgIGZvcm1hdCA9IHhvb2tpLmMuaW5wdXRGb3JtYXQ7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIGZvcm1hdCA9IHhvb2tpLmMuZGVmYXVsdElucHV0Rm9ybWF0Ow0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZmlsdGVycyA9IHRoaXMuZ2V0SW5wdXRGaWx0ZXJzKGZvcm1hdCk7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGZpbHRlcnMpIHsNCgkJCQl4b29raS5kZWJ1ZygncHJvY2Vzc2luZyBmaWx0ZXIgJytmaWx0ZXJzW2ldKTsNCiAgICAgICAgICAgICAgICBmID0geG9va2kuaW5wdXQuZmlsdGVyc1tmaWx0ZXJzW2ldXTsNCiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGYgPT0gImZ1bmN0aW9uIikgew0KICAgICAgICAgICAgICAgIAl0cnkgew0KICAgICAgICAgICAgICAgICAgICAJc291cmNlID0gZihzb3VyY2UpOyAvLyBwcm9jZXNzIGZpbHRlcg0KICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7DQoJICAgICAgICAgICAgICAgICAgICB4b29raS5lcnJvcihlLCB0KCJlcnJvciBvY2N1cmVkIHdoaWxlIHByb2Nlc3NpbmcgZmlsdGVyICR7MH0iLCBmaWx0ZXJzW2ldKSk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICB4b29raS5lcnJvcih0KCJ1bmtub3duIGZpbHRlciAkezB9IHVzZWQgaW4gaW5wdXQgZm9ybWF0ICR7MX0iLCBmaWx0ZXJzW2ldLCBmb3JtYXQpKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gc291cmNlOw0KICAgICAgICB9DQogICAgfSwgDQogICAgDQogICAgZmlsdGVyczogew0KICAgICAgICB1cmw6IGZ1bmN0aW9uIChpbnB1dCkgew0KICAgICAgICAgICAgLy8gaGFuZGxlIHVybHMNCiAgICAgICAgICAgIHJldHVybiBpbnB1dC5yZXBsYWNlKG5ldyBSZWdFeHAoIig/OmZpbGV8aHR0cHxodHRwc3xtYWlsdG98ZnRwKTpbXlxccydcIl0rKD86L3xcXGIpIiwgImciKSwgZnVuY3Rpb24gKHN0ciwgb2Zmc2V0LCBzKSB7DQogICAgICAgICAgICAgICAgdmFyIGJlZm9yZSA9IHMuc3Vic3RyaW5nKDAsb2Zmc2V0KTsNCiAgICAgICAgICAgICAgICBpZiAoYmVmb3JlLm1hdGNoKC8oaHJlZnxzcmMpPSIkLykpIHsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0cjsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9Iicrc3RyKyciPicrc3RyKyc8L2E+JzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9KTsNCiAgICAgICAgfSwNCiAgICAgICAgDQogICAgICAgIHNob3J0Y3V0czogZnVuY3Rpb24gKGlucHV0KSB7DQogICAgICAgICAgICAvLyBoYW5kbGUgc2hvcnRjdXQgbGlua3MgbGlrZSB0aGlzOg0KICAgICAgICAgICAgLy8gICAgW1tzdm46YnVpbGQueG1sXV0gPT4gPGEgaHJlZj0iaHR0cHM6Ly94b29raS5zdm4uc291cmNlZm9yZ2UubmV0L3N2bnJvb3QveG9va2kvdHJ1bmsvYnVpbGQueG1sIj5idWlsZC54bWw8L2E+DQogICAgICAgICAgICAvLyAgICBbW3N2bjp0ZXN0L2V4YW1wbGUuanMgYSBnb29kIGV4YW1wbGVdXSA9PiA8YSBocmVmPSJodHRwczovL3hvb2tpLnN2bi5zb3VyY2Vmb3JnZS5uZXQvc3Zucm9vdC94b29raS90cnVuay90ZXN0L2V4YW1wbGUuanMiPmEgZ29vZCBleGFtcGxlPC9hPg0KICAgICAgICAgICAgLy8gbmVlZHMgdG8gYmUgY29uZmlndXJlZCBpbiB4b29raSBjb25maWcgbGlrZSB0aGlzDQogICAgICAgICAgICAvLyAgICAgIHhvb2tpLmMuc2hvcnRjdXRzLjxhbnkgc2hvcnRjdXQ+LnVybCA9IGJhc2UgdXJsIG9mIHRoZSBzaG9ydGN1dC4gDQogICAgICAgICAgICAvLyAgICAgIGV4OiB4b29raS5jLnNob3J0Y3V0cy5zdm4udXJsID0gaHR0cHM6Ly94b29raS5zdm4uc291cmNlZm9yZ2UubmV0L3N2bnJvb3QveG9va2kvdHJ1bmsvDQogICAgICAgICAgICByZXR1cm4gaW5wdXQucmVwbGFjZShuZXcgUmVnRXhwKCJcXFtcXFsoW146XSspOihbXlxcXV0rKVxcXVxcXSIsICJnIiksIGZ1bmN0aW9uIChzdHIsIHByZWZpeCwgY29kZSwgb2Zmc2V0LCBzKSB7DQogICAgICAgICAgICAJaWYgKHR5cGVvZiB4b29raS5jLnNob3J0Y3V0cyA9PSAidW5kZWZpbmVkIiB8fCB0eXBlb2YgeG9va2kuYy5zaG9ydGN1dHNbcHJlZml4XSA9PSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgCQlyZXR1cm4gc3RyOw0KICAgICAgICAgICAgCX0NCiAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBjb2RlLmluZGV4T2YoJyAnKTsNCiAgICAgICAgICAgICAgICB2YXIgcGF0aCA9IGluZGV4PjA/Y29kZS5zdWJzdHJpbmcoMCxpbmRleCk6Y29kZTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICB2YXIgdGl0bGUgPSBpbmRleD4wP2NvZGUuc3Vic3RyaW5nKGluZGV4KzEpOnBhdGg7DQogICAgICAgICAgICAgICAgdmFyIHByZSA9IHR5cGVvZiB4b29raS5jLnNob3J0Y3V0c1twcmVmaXhdLnByZSA9PSAidW5kZWZpbmVkIj8nJzp4b29raS5jLnNob3J0Y3V0c1twcmVmaXhdLnByZTsNCiAgICAgICAgICAgICAgICB2YXIgcG9zdCA9IHR5cGVvZiB4b29raS5jLnNob3J0Y3V0c1twcmVmaXhdLnBvc3QgPT0gInVuZGVmaW5lZCI/Jyc6eG9va2kuYy5zaG9ydGN1dHNbcHJlZml4XS5wb3N0Ow0KICAgICAgICAgICAgICAgIHJldHVybiAnPGEgaHJlZj0iJytwcmUrcGF0aCtwb3N0KyciPicrdGl0bGUrJzwvYT4nOw0KICAgICAgICAgICAgfSk7DQogICAgICAgIH0sDQogICAgICAgIA0KICAgICAgICB4b29raUxpbmtzOiBmdW5jdGlvbiAoaW5wdXQpIHsNCiAgICAgICAgICAgIC8vIGhhbmRsZSB4b29raSBsaW5rcyBsaWtlIHRoaXM6DQogICAgICAgICAgICAvLyAgICBbW3BhZ2UvaWRdXQ0KICAgICAgICAgICAgLy8gICAgW1twYWdlL2lkIE15IFRpdGxlXV0NCiAgICAgICAgICAgIHJldHVybiBpbnB1dC5yZXBsYWNlKG5ldyBSZWdFeHAoIlxcW1xcWyhbXlxcXV0rKVxcXVxcXSIsICJnIiksIGZ1bmN0aW9uIChzdHIsIGNvZGUsIG9mZnNldCwgcykgew0KICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IGNvZGUuaW5kZXhPZignICcpOw0KICAgICAgICAgICAgICAgIHZhciBpZCA9IGluZGV4PjA/Y29kZS5zdWJzdHJpbmcoMCxpbmRleCk6Y29kZTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICB2YXIgdGl0bGU7DQogICAgICAgICAgICAgICAgdmFyIHVybCA9IHB1KGlkKTsNCiAgICAgICAgICAgICAgICBpZiAoaW5kZXg+MCkgew0KICAgICAgICAgICAgICAgIAl0aXRsZSA9IGNvZGUuc3Vic3RyaW5nKGluZGV4KzEpOw0KICAgICAgICAgICAgICAgCX0gZWxzZSBpZiAodHlwZW9mIHhvb2tpLnRvYy5wYWdlc1tpZF0gIT0gInVuZGVmaW5lZCIpIHsNCiAgICAgICAgICAgICAgIAkgICAgdGl0bGUgPSB4b29raS50b2MucGFnZXNbaWRdLnRpdGxlOw0KICAgICAgICAgICAgICAgCX0gZWxzZSB7DQogICAgICAgICAgICAgICAJCXRpdGxlID0gY29kZTsNCiAgICAgICAgICAgICAgIAkJdXJsID0gdShjb2RlKTsNCiAgICAgICAgICAgICAgIAl9DQogICAgICAgICAgICAgICAgcmV0dXJuICc8YSBocmVmPSInK3VybCsnIj4nK3RpdGxlKyc8L2E+JzsNCiAgICAgICAgICAgIH0pOw0KICAgICAgICB9LA0KICAgICAgICANCiAgICAgICAgd2lraU1hcmt1cDogZnVuY3Rpb24gKGlucHV0KSB7IA0KICAgICAgICAgICAgLy8gaGFuZGxlIGJvbGQNCiAgICAgICAgICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZShuZXcgUmVnRXhwKCJcXCooW15cbl0rKVxcKiIsICJnIiksICI8Yj4kMTwvYj4iKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgLy8gaGFuZGxlIGl0YWxpYw0KICAgICAgICAgICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKG5ldyBSZWdFeHAoIlxcXyhbXlxuXSspXFxfIiwgImciKSwgIjxlbT4kMTwvZW0+Iik7DQogICAgICAgICAgICANCiAgICAgICAgICAgIHJldHVybiBpbnB1dDsNCiAgICAgICAgfSwNCiAgICAgICAgDQogICAgICAgIGppcmE6IGZ1bmN0aW9uIChpbnB1dCkgeyANCiAgICAgICAgICAgIC8vIGF1dG8gcmVwbGFjZSBqaXJhIGlzc3VlIGlkcyAobGlrZSBJVlktMTIpIGJ5IGEgbGluayB0byB0aGUgaXNzdWUNCiAgICAgICAgICAgIC8vIG5lZWRzIHRvIGJlIGNvbmZpZ3VyZWQgaW4geG9va2kgY29uZmlnIGxpa2UgdGhpcw0KICAgICAgICAgICAgLy8gICAgICB4b29raS5jLmppcmEuaWRzID0gYW4gYXJyYXkgb2YgamlyYSBwcm9qZWN0cyBpZHMgKGV4OiBbIklWWSIsICJBTlQiXSkNCiAgICAgICAgICAgIC8vICAgICAgeG9va2kuYy5qaXJhLnVybCA9IHRoZSB1cmwgb2YgdGhlIGppcmEgc2VydmVyIChleDogImh0dHA6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhIikNCiAgICAgICAgICAgIGlmICh0eXBlb2YgeG9va2kuYy5qaXJhICE9ICJvYmplY3QiKSB7DQogICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0Ow0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKG5ldyBSZWdFeHAoIigoIit4b29raS5jLmppcmEuaWRzLmpvaW4oInwiKSsiKS1cXGQrKShbXlwiXFxkXSkiLCAiZyIpLCAnPGEgaHJlZj0iJyt4b29raS5jLmppcmEudXJsKycvYnJvd3NlLyQxIj4kMTwvYT4kMycpOw0KICAgICAgICAgICAgDQogICAgICAgICAgICByZXR1cm4gaW5wdXQ7DQogICAgICAgIH0sDQogICAgICAgIA0KICAgICAgICBjb2RlOiBmdW5jdGlvbiAoaW5wdXQpIHsNCiAgICAgICAgICAgIGNvZGVTZWN0aW9uID0geG9va2kuc3RyaW5nLmZpbmRYbWxTZWN0aW9uKGlucHV0LCAiY29kZSIpOw0KICAgICAgICAgICAgZnJvbSA9IDA7DQogICAgICAgICAgICB3aGlsZSAoY29kZVNlY3Rpb24gIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgIHByb2Nlc3NlZFNlY3Rpb24gPSAiPHByZT4iIA0KICAgICAgICAgICAgICAgICAgICArIGlucHV0LnN1YnN0cmluZyhjb2RlU2VjdGlvbi5pbm5lclN0YXJ0LCBjb2RlU2VjdGlvbi5pbm5lckVuZCkucmVwbGFjZSgvPC9nLCAiJmx0OyIpLnJlcGxhY2UoLz4vZywgIiZndDsiKSAvLyAucmVwbGFjZSgvXG4vZywgIjxici8+IikNCiAgICAgICAgICAgICAgICAgICAgKyAiPC9wcmU+IjsNCiAgICAgICAgICAgICAgICBpbnB1dCA9IGlucHV0LnN1YnN0cmluZygwLCBjb2RlU2VjdGlvbi5vdXRlclN0YXJ0KQ0KICAgICAgICAgICAgICAgICAgICArIHByb2Nlc3NlZFNlY3Rpb24NCiAgICAgICAgICAgICAgICAgICAgKyBpbnB1dC5zdWJzdHJpbmcoY29kZVNlY3Rpb24ub3V0ZXJFbmQpOw0KICAgICAgICAgICAgICAgIGZyb20gPSBjb2RlU2VjdGlvbi5vdXRlclN0YXJ0ICsgcHJvY2Vzc2VkU2VjdGlvbi5sZW5ndGg7DQogICAgDQogICAgICAgICAgICAgICAgY29kZVNlY3Rpb24gPSB4b29raS5zdHJpbmcuZmluZFhtbFNlY3Rpb24oaW5wdXQsICJjb2RlIiwgZnJvbSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gaW5wdXQ7DQogICAgICAgIH0sDQogICAgICAgIA0KICAgICAgICBsaW5lQnJlYWs6IGZ1bmN0aW9uIChpbnB1dCkgew0KICAgICAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UobmV3IFJlZ0V4cCgiXHI/XG4iLCAiZyIpLCBmdW5jdGlvbiAoc3RyLCBvZmZzZXQsIHMpIHsNCiAgICAgICAgICAgICAgICB2YXIgYmVmb3JlID0gcy5zdWJzdHJpbmcoMCxvZmZzZXQpOw0KICAgICAgICAgICAgICAgIHZhciBhZnRlciA9IHMuc3Vic3RyaW5nKG9mZnNldCtzdHIubGVuZ3RoKTsNCiAgICAgICAgICAgICAgICBpZiAoYWZ0ZXIubWF0Y2goL148XC8/KHVsfHRhYmxlfGxpfHByZXxkaXYpKFxzKlx3Kz0iW14iXSsiKSpccyo+L2kpIHx8IChiZWZvcmUubWF0Y2goLzxcLz9cdysoXHMqXHcrPSJbXiJdKyIpKlxzKlwvPz5ccyokL2kpICYmICFiZWZvcmUubWF0Y2goLzxcLz8oYXxifHN0cm9uZ3xlbXxpfGJpZ3xiciBjbGFzcz0ieG9va2ktYnIiKShccypcdys9IlteIl0rIikqXHMqXC8/PlxzKiQvaSkpKSB7IA0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ1xuJzsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzxiciBjbGFzcz0ieG9va2ktYnIiLz4nOyAvLyB0aGUgY2xhc3MgaXMgbm90IHJlYWxseSBuZWNlc3NhcnkgYnV0IGFsbG93IHRvIGRpc3Rpbmd1aXNoIGdlbmVyYXRlZCBiciBmcm9tIGlucHV0IG9uZQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0pOw0KICAgICAgICB9DQogICAgfSwNCiAgICANCiAgICANCiAgICBhcHBseUNoYW5nZXM6IGZ1bmN0aW9uKCkgew0KICAgIAlkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktYm9keScpLmlubmVySFRNTCA9IHhvb2tpLmlucHV0LnByb2Nlc3NlZCgpOw0KICAgIH0NCn07DQoNCg0KeG9va2kucG9zdFByb2Nlc3MgPSBmdW5jdGlvbigpIHsNCgl4b29raS5yZW5kZXIubWFpbigpOw0KCXdpbmRvdy5vbmtleXByZXNzID0ga2V5Q3RybDsNCn07DQoNCg0KaWYgKHR5cGVvZiB4b29raS5pbyA9PSAidW5kZWZpbmVkIikgew0KICAgIHhvb2tpLmlvID0ge307DQp9DQoNCmlmIChiYXRjaE1vZGUpIHsNCglpbXBvcnRQYWNrYWdlKGphdmEuaW8pOw0KCQ0KCXhvb2tpLmlvLmxvYWRGaWxlID0gZnVuY3Rpb24oIHVybCApIHsNCgkgIHZhciBzdHIgPSAnJzsNCiAgICAgIHZhciByID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBGaWxlUmVhZGVyKHVybCkpOw0KCSAgbGluZSA9IHIucmVhZExpbmUoKTsNCgkgIHdoaWxlIChsaW5lICE9IG51bGwpIHsNCgkJc3RyICs9IGxpbmUgKyAnXG4nOw0KCQlsaW5lID0gci5yZWFkTGluZSgpOw0KCSAgfQ0KCSAgci5jbG9zZSgpOw0KCSAgcmV0dXJuIHN0cjsNCiAgICB9Ow0KCQ0KCXhvb2tpLmlvLnNhdmVGaWxlID0gZnVuY3Rpb24gKGZpbGVVcmwsIGNvbnRlbnQpIHsNCgkJcCA9IG5ldyBGaWxlKGZpbGVVcmwpLmdldFBhcmVudEZpbGUoKTsNCgkJaWYgKHAgIT0gbnVsbCkgew0KCQkJcC5ta2RpcnMoKTsNCgkJfQ0KCQlwdyA9IG5ldyBQcmludFdyaXRlcihuZXcgRmlsZVdyaXRlcihmaWxlVXJsKSk7DQoJCXB3LndyaXRlKGNvbnRlbnQpOw0KCQlwdy5jbG9zZSgpOw0KCQlyZXR1cm4gdHJ1ZTsNCgl9DQoNCiAgICB4b29raS51cmwubG9hZFVSTCA9IGZ1bmN0aW9uKCB1cmwgKSB7DQoJCXJldHVybiB4b29raS5pby5sb2FkRmlsZSh1cmwpOw0KCX07DQoJDQoJeG9va2kuaHRtbC5hZGRIZWFkZXIgPSBmdW5jdGlvbiAoaGVhZCkgew0KCQl4b29raS5wYWdlQ29udGVudCA9IHhvb2tpLnBhZ2VDb250ZW50LnJlcGxhY2UoLzxcL2hlYWQ+LywgaGVhZCsnXG48L2hlYWQ+Jyk7DQoJfTsNCgkNCgl4b29raS5odG1sLnNldEJvZHkgPSBmdW5jdGlvbihib2R5KSB7DQoJCXhvb2tpLnBhZ2VDb250ZW50ID0geG9va2kucGFnZUNvbnRlbnQucmVwbGFjZSgvPGJvZHk+KC58W14sXSkqPFwvYm9keT4vZ20sICc8Ym9keT4nK2JvZHkrJzwvYm9keT4nKTsNCgl9DQoJDQoJeG9va2kudXJsLmluY2x1ZGUgPSBmdW5jdGlvbihzY3JpcHRfZmlsZW5hbWUpIHsNCgkJeG9va2kuaHRtbC5hZGRIZWFkZXIoJzxzY3JpcHQgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSInK3hvb2tpLmMucmVsYXRpdmVSb290Kyd4b29raS8nK3NjcmlwdF9maWxlbmFtZSsnIj48L3NjcmlwdD4nKTsNCgl9Ow0KCQ0KCXhvb2tpLmlucHV0LnNvdXJjZSA9IGZ1bmN0aW9uKCkgew0KCQlpZiAodHlwZW9mIHRoaXMuX3NvdXJjZSA9PSAndW5kZWZpbmVkJykgew0KCQkJeG9va2kuZGVidWcoJ3NlYXJjaGluZyBzb3VyY2UnKTsNCgkJCXZhciBiZWcgPSB4b29raS5wYWdlQ29udGVudC5pbmRleE9mKCc8dGV4dGFyZWEgaWQ9Inhvb2tpLXNvdXJjZSI+Jyk7DQoJCQliZWcgKz0gJzx0ZXh0YXJlYSBpZD0ieG9va2ktc291cmNlIj4nLmxlbmd0aDsNCgkJCXZhciBlbmQgPSB4b29raS5wYWdlQ29udGVudC5sYXN0SW5kZXhPZignPC90ZXh0YXJlYT4nKTsNCgkJCXRoaXMuX3NvdXJjZSA9IHhvb2tpLnBhZ2VDb250ZW50LnN1YnN0cmluZyhiZWcsIGVuZCk7DQoJCQl4b29raS5kZWJ1Zygnc291cmNlIGZvdW5kJyk7DQoJCX0NCgkJcmV0dXJuIHRoaXMuX3NvdXJjZTsNCgl9DQoJDQoJeG9va2kucmVuZGVyLnBhZ2UgPSBmdW5jdGlvbigpIHsNCgkgICAgLy8gcmVhbGl6ZSBhbGwgY29tcG9uZW50cyBhdmFpbGFibGUNCgkJeG9va2kuZGVidWcoJ3JlYWxpemluZyBjb21wb25lbnRzJyk7DQoJICAgIGZvciAodmFyIGsgaW4geG9va2kuY29tcG9uZW50KSB7DQoJICAgICAgICB4b29raS5jW2tdID0geG9va2kuY29tcG9uZW50W2tdKCk7DQoJICAgIH0NCgkgICAgDQoJCXhvb2tpLmRlYnVnKCdwcm9jZXNzaW5nIGJvZHknKTsNCgkJeG9va2kuYy5ib2R5ID0geG9va2kuaW5wdXQucHJvY2Vzc2VkKCk7DQoNCgkJeG9va2kuZGVidWcoJ3VwZGF0aW5nIGJvZHknKTsNCgkJdmFyIGJvZHkgPSB4b29raS5zdHJpbmcucHJvY2Vzc1RlbXBsYXRlKHhvb2tpLnRlbXBsYXRlLmJvZHksIHhvb2tpLmMpOw0KCQlpZiAoeG9va2kuYy51c2VkZHRyZWUpIHsNCgkJCWJvZHkgKz0gJzxzY3JpcHQgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCI+ZGR0cmVlbWVudS5jcmVhdGVUcmVlKCInK2NzcygidHJlZW1lbnUiKSsnIiwgZmFsc2UpOzwvc2NyaXB0Pic7DQoJCX0NCgkgICAgeG9va2kuaHRtbC5zZXRCb2R5KGJvZHkpOw0KCX07DQoNCgl4b29raS5kaXNwbGF5ID0gZnVuY3Rpb24obWVzc2FnZSwgYmFja2dyb3VuZCkgew0KCQlwcmludChtZXNzYWdlKTsNCgl9Ow0KCQ0KCXhvb2tpLmRlYnVnID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHsNCgkJaWYgKHhvb2tpLmMuZGVidWcpIHsNCgkJCXByaW50KG1lc3NhZ2UrJ1xuJyk7DQoJCX0NCgl9Ow0KCXZhciBpPTA7DQoJaWYgKGFyZ3VtZW50cy5sZW5ndGggPiBpICYmIGFyZ3VtZW50c1swXSA9PSAnLW5vZGR0cmVlJykgew0KCQl4b29raS5jLnVzZWRkdHJlZSA9IGZhbHNlOw0KCQlpKys7DQoJfQ0KCQ0KCWlmIChhcmd1bWVudHMubGVuZ3RoID4gaSAmJiBhcmd1bWVudHNbMF0gPT0gJy1kZWJ1ZycpIHsNCgkJeG9va2kuYy5kZWJ1ZyA9IHRydWU7DQoJCWkrKzsNCgl9IGVsc2Ugew0KCQl4b29raS5jLmRlYnVnID0gZmFsc2U7DQoJfQ0KCQ0KCXZhciBmaWxlID0gJ2luZGV4Lmh0bWwnOw0KCWlmIChhcmd1bWVudHMubGVuZ3RoID4gaSkgew0KCQlmaWxlID0gYXJndW1lbnRzW2ldOw0KCQlpKys7DQoJfQ0KCXZhciBnZW5lcmF0ZVRvRGlyID0gImdlbiI7DQoJaWYgKGFyZ3VtZW50cy5sZW5ndGggPiBpKSB7DQoJCWdlbmVyYXRlVG9EaXIgPSBhcmd1bWVudHNbaV07DQoJCWkrKzsNCgl9DQoJDQoJcHJpbnQoJ3Byb2Nlc3NpbmcgJytmaWxlKycuLi5cbicpOw0KCXhvb2tpLnBhZ2VDb250ZW50ID0geG9va2kuaW8ubG9hZEZpbGUoZmlsZSk7DQoJDQoJdmFyIG0gPSAvdmFyIHhvb2tpQ29uZmlnID0gey4qfTsvLmV4ZWMoeG9va2kucGFnZUNvbnRlbnQpOw0KCWlmICh0eXBlb2YgbSAhPSAndW5kZWZpbmVkJyAmJiBtICE9IG51bGwpIHsNCgkJZXZhbChtWzBdKTsNCgl9DQp9DQoNCmlmIChiYXRjaE1vZGUpIHsNCgl4b29raS5wYWdlVVJMID0gbmV3IEZpbGUoZmlsZSkudG9VUkwoKS50b0V4dGVybmFsRm9ybSgpOw0KfSBlbHNlIHsNCgl4b29raS5wYWdlVVJMID0gd2luZG93LmxvY2F0aW9uLnRvU3RyaW5nKCk7DQp9DQoNCi8vIGluaXQgeG9va2kgZW5naW5lDQooZnVuY3Rpb24oKSB7DQogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLyBjb25maWcgaW5pdA0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCiAgICBpbml0Q29uZmlnUHJvcGVydHkgPSBmdW5jdGlvbihwcm9wLCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7DQogICAgICAgIGlmICh0eXBlb2YgdGhpc1twcm9wXSA9PSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgICAgIHRoaXNbcHJvcF0gPSBkZWZhdWx0VmFsdWU7DQogICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PSAiZnVuY3Rpb24iKSB7DQogICAgICAgICAgICAgICAgdGhpc1twcm9wXSA9IHZhbHVlKCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHRoaXNbcHJvcF0gPSB2YWx1ZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH07DQogICAgaWYgKHR5cGVvZiB4b29raUNvbmZpZyAhPSAidW5kZWZpbmVkIikge3hvb2tpLnV0aWwubWl4KHhvb2tpQ29uZmlnLCB4b29raS5jb25maWcpO30NCiAgICB4b29raS5jLmluaXRQcm9wZXJ0eSA9IGluaXRDb25maWdQcm9wZXJ0eTsNCiAgICB4b29raS5jLmluaXRQcm9wZXJ0eSgibGV2ZWwiLCAwKTsNCiAgICB4b29raS5jLmluaXRQcm9wZXJ0eSgicm9vdCIsIGZ1bmN0aW9uKCkgew0KICAgIAlyb290ID0geG9va2kucGFnZVVSTDsNCiAgICAJLy8gcmVtb3ZlIHRyYWlsaW5nIHBhcnRzIG9mIHRoZSBVUkwgdG8gZ28gdGhlIHJvb3QgZGVwZW5kaW5nIG9uIGxldmVsDQogICAgCWZvciAodmFyIGk9MDsgaSA8IHhvb2tpLmMubGV2ZWwgKyAxOyBpKyspIHsNCiAgICAJCXJvb3QgPSByb290LnN1YnN0cmluZygwLCByb290Lmxhc3RJbmRleE9mKCcvJykpOw0KICAgIAl9DQogICAgCXJldHVybiByb290ICsgJy8nOw0KICAgIH0pOw0KICAgIHhvb2tpLmMuaW5pdFByb3BlcnR5KCJyZWxhdGl2ZVJvb3QiLCBmdW5jdGlvbigpIHsNCiAgICAJcmVsYXRpdmVSb290ID0gJyc7DQogICAgCWZvciAodmFyIGk9MDsgaSA8IHhvb2tpLmMubGV2ZWw7IGkrKykgew0KICAgIAkJcmVsYXRpdmVSb290ICs9ICcuLi8nOw0KICAgIAl9DQogICAgCXJldHVybiByZWxhdGl2ZVJvb3Q7DQogICAgfSk7DQoNCiAgICB4b29raS5jLmluaXRQcm9wZXJ0eSgidXNlZGR0cmVlIiwgdHJ1ZSk7DQoNCiAgICB2YXIgZ2xvYmFsQ29uZmlnID0geG9va2kuanNvbi5sb2FkVVJMKHUoImNvbmZpZy5qc29uIikpOw0KICAgIGlmIChnbG9iYWxDb25maWcgIT0gbnVsbCkgew0KICAgICAgICB4b29raS51dGlsLm1peChnbG9iYWxDb25maWcsIHhvb2tpLmNvbmZpZywgZmFsc2UpOw0KICAgIH0NCg0KICAgIHhvb2tpLmMuaW5pdFByb3BlcnR5KCJkZWZhdWx0SW5wdXRGb3JtYXQiLCAieG9va2kiKTsNCiAgICB4b29raS5jLmluaXRQcm9wZXJ0eSgieG9va2lJbnB1dEZvcm1hdCIsIFsieG9va2kiXSk7DQogICAgeG9va2kuYy5pbml0UHJvcGVydHkoImFsbG93RWRpdCIsICFiYXRjaE1vZGUgJiYgeG9va2kucGFnZVVSTC5zdWJzdHIoMCw1KSA9PSAiZmlsZToiKTsNCiAgICANCiAgICB4b29raS5pbnB1dC5mb3JtYXQuZGVmaW5lKCJ4b29raSIsIFsiY29kZSIsICJzaG9ydGN1dHMiLCAidXJsIiwgInhvb2tpTGlua3MiLCAiamlyYSIsICJsaW5lQnJlYWsiXSk7DQogICAgDQogICAgeG9va2kuYy5wYXRoID0gKHR5cGVvZiB4b29raS5jLnBhdGggIT0gInVuZGVmaW5lZCIpP3hvb2tpLmMucGF0aDp7fTsNCiAgICB4b29raS5jLnBhdGguaW5pdFByb3BlcnR5ID0gaW5pdENvbmZpZ1Byb3BlcnR5Ow0KICAgIHhvb2tpLmMucGF0aC5pbml0UHJvcGVydHkoImluc3RhbGwiLCAieG9va2kiKTsNCiAgICB4b29raS5jLnBhdGguaW5pdFByb3BlcnR5KCJtZXNzYWdlcyIsIHhvb2tpLnAoIm1lc3NhZ2VzLmpzb24iKSk7DQogICAgeG9va2kuYy5wYXRoLmluaXRQcm9wZXJ0eSgidGVtcGxhdGUiLCAidGVtcGxhdGUuaHRtbCIpOw0KICAgIHhvb2tpLmMucGF0aC5pbml0UHJvcGVydHkoInByaW50VGVtcGxhdGUiLCAicHJpbnRUZW1wbGF0ZS5odG1sIik7DQogICAgeG9va2kuYy5wYXRoLmluaXRQcm9wZXJ0eSgidG9jIiwgInRvYy5qc29uIik7DQogICAgeG9va2kuYy5wYXRoLmluaXRQcm9wZXJ0eSgiYmxhbmtQYWdlVHBsIiwgeG9va2kucCgiYmxhbmtQYWdlVHBsLmh0bWwiKSk7DQogICAgDQogICAgDQogICAgeG9va2kuYy5jc3MgPSAodHlwZW9mIHhvb2tpLmMuY3NzICE9ICJ1bmRlZmluZWQiKT94b29raS5jLmNzczp7fTsgICAgDQogICAgICAgIA0KICAgIHhvb2tpLmMubWVzc2FnZXMgPSB4b29raS5qc29uLmxvYWRVUkwoY3UoIm1lc3NhZ2VzIikpOyANCglpZiAoIWJhdGNoTW9kZSkgew0KCSAgICB4b29raS5jLmJyb3dzZXIgPSB7DQoJICAgICAgICBOUzogKHdpbmRvdy5FdmVudCkgPyAxIDogMA0KCSAgICB9Ow0KICAgIA0KCSAgICAvLyBhY3Rpb24NCgkgICAgLy8gVE9ETzogYmV0dGVyIGhhbmRsZSBhY3Rpb24gZXh0cmFjdGlvbg0KCQl4b29raS5jLmFjdGlvbiA9IHdpbmRvdy5sb2NhdGlvbi5zZWFyY2ggPT0gJz9hY3Rpb249cHJpbnQnPydwcmludCc6eG9va2kuYy5hY3Rpb247DQoJfQ0KICAgIA0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8gVE9DIGluaXQNCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQogICAgeG9va2kudG9jID0geG9va2kuanNvbi5sb2FkVVJMKGN1KCJ0b2MiKSk7DQogICAgeG9va2kudG9jLnBhZ2VzID0ge307IC8vIHRvIHN0b3JlIGEgYnkgaWQgbWFwIG9mIHBhZ2VzIG9iamVjdHMNCg0KCS8vIHBvcHVsYXRlIG1ldGEgZGF0YQ0KCShmdW5jdGlvbihwYWdlLCBwYXJlbnQsIGluZGV4LCBsZXZlbCkgew0KICAgICAgICB4b29raS50b2MucGFnZXNbcGFnZS5pZF0gPSBwYWdlOw0KICAgICAgICANCiAgICAgICAgcGFnZS5tZXRhID0gew0KICAgICAgICAgICAgcGFyZW50OiBwYXJlbnQsDQogICAgICAgICAgICBpbmRleDogaW5kZXgsDQogICAgICAgICAgICBsZXZlbDogbGV2ZWwNCiAgICAgICAgfTsNCiAgICAgICAgaWYgKHR5cGVvZiBwYWdlLmNoaWxkcmVuID09ICd1bmRlZmluZWQnKSB7DQogICAgICAgICAgICBwYWdlLmNoaWxkcmVuID0gW107DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBmb3IgKHZhciBpPTA7IGk8cGFnZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykgew0KICAgICAgICAgICAgICAgIGFyZ3VtZW50cy5jYWxsZWUocGFnZS5jaGlsZHJlbltpXSwgcGFnZSwgaSwgbGV2ZWwrMSk7IC8vIHJlY3Vyc2UNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0pKHhvb2tpLnRvYywgbnVsbCwgMCwgLTEpOw0KICAgIA0KICAgIHhvb2tpLnRvYy5nZXROZXh0UGFnZSA9IGZ1bmN0aW9uKHBhZ2UsIHJvb3QpIHsNCiAgICAgICAgaWYgKHBhZ2UuY2hpbGRyZW4ubGVuZ3RoID4gMCkgew0KICAgICAgICAJcmV0dXJuIHBhZ2UuY2hpbGRyZW5bMF07DQogICAgICAgIH0gZWxzZSBpZiAocGFnZS5tZXRhLnBhcmVudCAhPSBudWxsKSB7DQogICAgICAgIAl2YXIgY3VyID0gcGFnZTsNCiAgICAgICAgCXZhciBuZXh0ID0geG9va2kudG9jLmdldE5leHRTaWJsaW5nKGN1cik7DQogICAgICAgIAl3aGlsZSAobmV4dCA9PSBudWxsKSB7DQogICAgICAgIAkJY3VyID0gY3VyLm1ldGEucGFyZW50Ow0KICAgICAgICAJCWlmIChjdXIgPT0gbnVsbCB8fCBjdXIgPT0gcm9vdCkgew0KICAgICAgICAJCQlyZXR1cm4gbnVsbDsNCiAgICAgICAgCQl9DQogICAgICAgIAkJbmV4dCA9IHhvb2tpLnRvYy5nZXROZXh0U2libGluZyhjdXIpOw0KICAgICAgICAJfQ0KICAgICAgIAkJcmV0dXJuIG5leHQ7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgIAlyZXR1cm4gbnVsbDsNCiAgICAgICAgfQ0KICAgIH07DQogICAgeG9va2kudG9jLmdldE5leHRTaWJsaW5nID0gZnVuY3Rpb24ocGFnZSkgew0KICAgIAlpZiAocGFnZS5tZXRhLnBhcmVudCA9PSBudWxsKSB7DQogICAgCQlyZXR1cm4gbnVsbDsNCiAgICAJfQ0KICAgICAgIAlpZiAocGFnZS5tZXRhLnBhcmVudC5jaGlsZHJlbi5sZW5ndGggPiBwYWdlLm1ldGEuaW5kZXgpIHsNCiAgICAgICAJCXJldHVybiBwYWdlLm1ldGEucGFyZW50LmNoaWxkcmVuW3BhZ2UubWV0YS5pbmRleCsxXTsNCiAgICAgICAJfSBlbHNlIHsNCiAgICAgICAJCXJldHVybiBudWxsOw0KICAgICAgIAl9DQogICAgfTsNCgkNCgl2YXIgbWF0Y2ggPSBuZXcgUmVnRXhwKCJeLipcXC8oKD86LipcXC8peyIreG9va2kuY29uZmlnLmxldmVsKyJ9W15cXC9dKikoPzpcXC5cXHcrKSg/OlxcPy4rKT8kIiwgImciKS5leGVjKHhvb2tpLnBhZ2VVUkwpOw0KCXZhciBjdXJQYWdlSWQ7DQoJaWYgKG1hdGNoID09IG51bGwgfHwgbWF0Y2hbMV0gPT0gJycpIHsNCgkJY3VyUGFnZUlkID0gImluZGV4IjsNCgl9IGVsc2Ugew0KCQljdXJQYWdlSWQgPSBtYXRjaFsxXTsNCgl9DQoJeG9va2kucGFnZSA9IHhvb2tpLnRvYy5wYWdlc1tjdXJQYWdlSWRdOw0KDQoJaWYgKHhvb2tpLnBhZ2UgPT0gbnVsbCkgew0KCQl4b29raS53YXJuKHQoJ3BhZ2UgaWQgbm90IGZvdW5kIGluIFRPQzogJHswfScsY3VyUGFnZUlkKSk7DQoJCXhvb2tpLnBhZ2UgPSB4b29raS50b2MuY2hpbGRyZW5bMF07DQoJfSANCglpZiAodHlwZW9mIHhvb2tpLmNvbmZpZy50aXRsZSA9PSAndW5kZWZpbmVkJykgew0KCQl4b29raS5jb25maWcudGl0bGUgPSB4b29raS5wYWdlLnRpdGxlOw0KCX0JCQ0KCXhvb2tpLmNvbmZpZy5wYWdlID0geG9va2kucGFnZTsNCgkNCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQogICAgLy8vLy8vLy8vLy8vLy8vLy8vIG1haW4gdGVtcGxhdGUgbG9hZGluZyArIGhlYWQgb3V0cHV0DQogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KCXhvb2tpLnRlbXBsYXRlID0ge307DQogICAgeG9va2kudGVtcGxhdGUuc291cmNlID0geG9va2kudXJsLmxvYWRVUkwoeG9va2kuYy5hY3Rpb24gPT0gInByaW50Ij9jdSgicHJpbnRUZW1wbGF0ZSIpOmN1KCJ0ZW1wbGF0ZSIpKTsNCglpZih4b29raS50ZW1wbGF0ZS5zb3VyY2UgIT0gbnVsbCkgew0KCQl4b29raS50ZW1wbGF0ZS5oZWFkID0geG9va2kudGVtcGxhdGUuc291cmNlLm1hdGNoKC88aGVhZD4oW16nXSopPFwvaGVhZD4vaW0pWzFdOw0KCQl2YXIgcm9vdCA9IGJhdGNoTW9kZT94b29raS5jLnJlbGF0aXZlUm9vdDp4b29raS5jLnJvb3Q7DQoJCQ0KICAgICAgICB2YXIgaGVhZCA9IHhvb2tpLnN0cmluZy5wcm9jZXNzVGVtcGxhdGUoeG9va2kudGVtcGxhdGUuaGVhZCwgeG9va2kuY29uZmlnKTsNCgkJaGVhZCA9IGhlYWQucmVwbGFjZSgvaHJlZj0iKFteXFwkOiJdKykiL2csICdocmVmPSInK3Jvb3QrJyQxIicpOw0KCQl4b29raS5odG1sLmFkZEhlYWRlcihoZWFkKTsNCg0KCQl2YXIgYm9keSA9IHhvb2tpLnRlbXBsYXRlLnNvdXJjZS5tYXRjaCgvPGJvZHk+KFtep10qKTxcL2JvZHk+L2ltKVsxXTsNCgkJYm9keSA9IGJvZHkucmVwbGFjZSgvaHJlZj0iKFteXFwkOiJdKykiL2csICdocmVmPSInK3Jvb3QrJyQxIicpOw0KCQl4b29raS50ZW1wbGF0ZS5ib2R5ID0gYm9keS5yZXBsYWNlKC9zcmM9IihbXlxcJDoiXSspIi9nLCAnc3JjPSInK3Jvb3QrJyQxIicpOwkJDQoJfQ0KCQ0KDQogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLyBpbmNsdWRlcw0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCglpZiAoYmF0Y2hNb2RlKSB7DQoJCXhvb2tpLmh0bWwuYWRkSGVhZGVyKCc8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPnhvb2tpID0ge3U6IGZ1bmN0aW9uKHVybCkge3JldHVybiAiJyt4b29raS5jLnJlbGF0aXZlUm9vdCsneG9va2kvIit1cmw7fX07PC9zY3JpcHQ+Jyk7DQoJfQ0KICAgIHhvb2tpLnVybC5pbmNsdWRlKCJ0cmVlL3NpbXBsZXRyZWVtZW51LmpzIik7DQogICAgaWYgKHhvb2tpLmMudXNlVHJpbVBhdGgpIHsNCiAgICAgICAgeG9va2kudXJsLmluY2x1ZGUoInRyaW1wYXRoL3RlbXBsYXRlLmpzIik7DQogICAgfQ0KICAgIGlmICh4b29raS5jLmFsbG93RWRpdCkgew0KICAgICAgICB4b29raS51cmwuaW5jbHVkZSgieG9va2lFZGl0LmpzIik7DQogICAgfQ0KDQogICAgZm9yICh2YXIgayBpbiB4b29raS5jKSB7DQogICAgICAgIGlmICh0eXBlb2YgeG9va2kuY1trXSA9PSAic3RyaW5nIiB8fCB0eXBlb2YgeG9va2kuY1trXSA9PSAibnVtYmVyIiB8fCB0eXBlb2YgeG9va2kuY1trXSA9PSAiYm9vbGVhbiIpIHsNCiAgICAgICAgICAgIHhvb2tpLmRlYnVnKGsrIjogIit4b29raS5jW2tdKTsNCiAgICAgICAgfQ0KICAgIH0NCn0pKCk7DQoNCnhvb2tpLmFjdGlvbiA9IHt9DQp4b29raS5hY3Rpb24udG9nZ2xlRGVidWcgPSBmdW5jdGlvbigpIHsNCiAgICBpZiAoeG9va2kuYy5kZWJ1Zykgew0KICAgIAlpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3hvb2tpLWRlYnVnJykuc3R5bGUuZGlzcGxheSA9PSAnbm9uZScpIHsNCiAgICAJCXhvb2tpLmh0bWwuc2hvdygneG9va2ktZGVidWcnKTsNCiAgICAJfSBlbHNlIHsNCiAgICAJCXhvb2tpLmh0bWwuaGlkZSgneG9va2ktZGVidWcnKTsNCiAgICAJfQ0KCX0NCn0NCnhvb2tpLmFjdGlvbi5ldmFsdWF0ZSA9IGZ1bmN0aW9uICgpIHsNCiAgICB2YXIgZXhwID0gcHJvbXB0KCJQbGVhc2UgZW50ZXIgamF2YXNjcmlwdCBleHByZXNzaW9uIHRvIGV2YWx1YXRlIik7DQogICAgeG9va2kuZGVidWdTaG93RGV0YWlsKGV2YWwoZXhwKSk7DQp9DQoNCi8vIFRPRE8sIHJldmlldyB1c2UgcmVnaXN0cmF0aW9uDQpmdW5jdGlvbiBrZXlDdHJsKGV2dCkgew0KCXZhciBjb2RlID0geG9va2kuYy5icm93c2VyLk5TID8gZXZ0LndoaWNoIDogZXZlbnQua2V5Q29kZTsNCgl2YXIgY3RybCA9IHhvb2tpLmMuYnJvd3Nlci5OUyA/IGV2dC5jdHJsS2V5IDogZXZlbnQuY3RybEtleTsNCiAgCXZhciBrZXkgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGUpOw0KCWlmICh4b29raS5jLmRlYnVnICYmIGN0cmwgJiYgImQiID09IGtleSkgew0KCQl4b29raS5hY3Rpb24udG9nZ2xlRGVidWcoKTsNCgkJcmV0dXJuIGZhbHNlOw0KCX0NCglpZiAoeG9va2kuYy5hbGxvd0VkaXQgJiYgY3RybCAmJiAicyIgPT0ga2V5KSB7DQoJCXhvb2tpLmFjdGlvbi5zYXZlQ2hhbmdlcygpOw0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KCWlmICh4b29raS5jLmFsbG93RWRpdCAmJiBjdHJsICYmICJlIiA9PSBrZXkpIHsNCgkJeG9va2kuYWN0aW9uLnRvZ2dsZUVkaXQoKTsNCgkJcmV0dXJuIGZhbHNlOw0KCX0NCn0NCg0KaWYgKGJhdGNoTW9kZSkgewkNCgl4b29raS5wYWdlQ29udGVudCA9IHhvb2tpLnBhZ2VDb250ZW50LnJlcGxhY2UoLzxzY3JpcHQgdHlwZT0idGV4dFwvamF2YXNjcmlwdCIgc3JjPSJbXiJdKnhvb2tpLmpzIj48XC9zY3JpcHQ+L2csICcnKTsNCgkNCgl4b29raS5yZW5kZXIucGFnZSgpOw0KDQoJcHJpbnQoJ2dlbmVyYXRpbmcgdG8gJytnZW5lcmF0ZVRvRGlyKycvJytmaWxlKTsNCgl4b29raS5pby5zYXZlRmlsZShnZW5lcmF0ZVRvRGlyKycvJytmaWxlLCB4b29raS5wYWdlQ29udGVudCk7DQp9DQoNCg==