ZGlmZiAtLWdpdCBhLy5hc2YueWFtbCBiLy5hc2YueWFtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYzFiZTA1Ci0tLSAvZGV2L251bGwKKysrIGIvLmFzZi55YW1sCkBAIC0wLDAgKzEsNyBAQAorZ2l0aHViOgorICBkZXNjcmlwdGlvbjogIkFwYWNoZSBTbGluZyBTY3JpcHQgQ29uc29sZSAoZGVwcmVjYXRlZCkiCisgIGhvbWVwYWdlOiAiaHR0cHM6Ly9zbGluZy5hcGFjaGUub3JnIgorICBsYWJlbHM6CisgICAgLSBqYXZhCisgICAgLSBzbGluZworICAgIC0gZGVwcmVjYXRlZApkaWZmIC0tZ2l0IGEvSmVua2luc2ZpbGUgYi9KZW5raW5zZmlsZQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjU4MjUxOS4uMDAwMDAwMAotLS0gYS9KZW5raW5zZmlsZQorKysgL2Rldi9udWxsCkBAIC0xLDIwICswLDAgQEAKLS8qKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQotICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCi0gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgotICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQotICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQotICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQotICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAotICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KLSAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQotICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCi0gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCi0gKiB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1zbGluZ09zZ2lCdW5kbGVCdWlsZCgpCmRpZmYgLS1naXQgYS9SRUFETUUubWQgYi9SRUFETUUubWQKaW5kZXggNDIwZDQyZi4uNDVkMDI2NCAxMDA2NDQKLS0tIGEvUkVBRE1FLm1kCisrKyBiL1JFQURNRS5tZApAQCAtNCw4ICs0LDEwIEBACiAKICMgQXBhY2hlIFNsaW5nIFNjcmlwdCBDb25zb2xlCiAKLVRoaXMgbW9kdWxlIGlzIHBhcnQgb2YgdGhlIFtBcGFjaGUgU2xpbmddKGh0dHBzOi8vc2xpbmcuYXBhY2hlLm9yZykgcHJvamVjdC4KK1RoaXMgbW9kdWxlIGlzIHBhcnQgb2YgdGhlIFtBcGFjaGUgU2xpbmddKGh0dHBzOi8vc2xpbmcuYXBhY2hlLm9yZykgcHJvamVjdCwgYnV0IGl0IGlzIG5vIGxvbmdlciBtYWludGFpbmVkLgogCiBJdCBpcyBub3cgZGVwcmVjYXRlZCBpbiBmYXZvciBvZiB0aGUgc2ltaWxhciBidXQgaW1wcm92ZWQgW0FwYWNoZSBGZWxpeCBTY3JpcHQgQ29uc29sZSBQbHVnaW5dKGh0dHA6Ly9mZWxpeC5hcGFjaGUub3JnL2RvY3VtZW50YXRpb24vc3VicHJvamVjdHMvYXBhY2hlLWZlbGl4LXNjcmlwdC1jb25zb2xlLXBsdWdpbi5odG1sKS4KIAotVE9ETzogYWRkIGEgImRlcHJlY2F0ZWQiIGJhZGdlIGhlcmUuCitGb3IgcmVmZXJlbmNlIG9yIHBvdGVudGlhbCBidWdmaXggcmVsZWFzZXMgcGxlYXNlIHVzZSB0aGUKK1tgbWFpbnRlbmFuY2VgXShodHRwczovL2dpdGh1Yi5jb20vYXBhY2hlL3NsaW5nLW9yZy1hcGFjaGUtc2xpbmctc2NyaXB0aW5nLWNvbnNvbGUvdHJlZS9tYWludGVuYW5jZSkKK2JyYW5jaC4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9wb20ueG1sIGIvcG9tLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWVkNjllNC4uMDAwMDAwMAotLS0gYS9wb20ueG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTYxICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KLTwhLS0KLSAgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCi0gICAgb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCi0gICAgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KLSAgICByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCi0gICAgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQotICAgICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKLSAgICB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gICAgCi0gICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gICAgCi0gICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAotICAgIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCi0gICAgIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCi0gICAgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCi0gICAgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucwotICAgIHVuZGVyIHRoZSBMaWNlbnNlLgotLS0+Ci08cHJvamVjdCB4bWxucz0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6c2NoZW1hTG9jYXRpb249Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMCBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9tYXZlbi12NF8wXzAueHNkIj4KLQotICAgIDxtb2RlbFZlcnNpb24+NC4wLjA8L21vZGVsVmVyc2lvbj4KLSAgICA8cGFyZW50PgotICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLnNsaW5nPC9ncm91cElkPgotICAgICAgICA8YXJ0aWZhY3RJZD5zbGluZzwvYXJ0aWZhY3RJZD4KLSAgICAgICAgPHZlcnNpb24+MjY8L3ZlcnNpb24+Ci0gICAgICAgIDxyZWxhdGl2ZVBhdGgvPgotICAgIDwvcGFyZW50PgotCi0gICAgPGFydGlmYWN0SWQ+b3JnLmFwYWNoZS5zbGluZy5zY3JpcHRpbmcuY29uc29sZTwvYXJ0aWZhY3RJZD4KLSAgICA8dmVyc2lvbj4xLjAuMS1TTkFQU0hPVDwvdmVyc2lvbj4KLSAgICA8cGFja2FnaW5nPmJ1bmRsZTwvcGFja2FnaW5nPgotCi0gICAgPG5hbWU+QXBhY2hlIFNsaW5nIFNjcmlwdCBDb25zb2xlPC9uYW1lPgotICAgIDxkZXNjcmlwdGlvbj5XZWIgQ29uc29sZSBwbHVnaW4gZm9yIGV2YWx1YXRpbmcgc2NyaXB0czwvZGVzY3JpcHRpb24+Ci0KLSAgICA8c2NtPgotICAgICAgICA8Y29ubmVjdGlvbj5zY206Z2l0Omh0dHBzOi8vZ2l0Ym94LmFwYWNoZS5vcmcvcmVwb3MvYXNmL3NsaW5nLW9yZy1hcGFjaGUtc2xpbmctc2NyaXB0aW5nLWNvbnNvbGUuZ2l0PC9jb25uZWN0aW9uPgotICAgICAgICA8ZGV2ZWxvcGVyQ29ubmVjdGlvbj5zY206Z2l0Omh0dHBzOi8vZ2l0Ym94LmFwYWNoZS5vcmcvcmVwb3MvYXNmL3NsaW5nLW9yZy1hcGFjaGUtc2xpbmctc2NyaXB0aW5nLWNvbnNvbGUuZ2l0PC9kZXZlbG9wZXJDb25uZWN0aW9uPgotICAgICAgICA8dXJsPmh0dHBzOi8vZ2l0Ym94LmFwYWNoZS5vcmcvcmVwb3MvYXNmP3A9c2xpbmctb3JnLWFwYWNoZS1zbGluZy1zY3JpcHRpbmctY29uc29sZS5naXQ8L3VybD4KLSAgICA8L3NjbT4KLQotICAgIDxidWlsZD4KLSAgICAgICAgPHBsdWdpbnM+Ci0gICAgICAgICAgICA8cGx1Z2luPgotICAgICAgICAgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUuZmVsaXg8L2dyb3VwSWQ+Ci0gICAgICAgICAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tc2NyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KLSAgICAgICAgICAgIDwvcGx1Z2luPgotICAgICAgICAgICAgPHBsdWdpbj4KLSAgICAgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLmZlbGl4PC9ncm91cElkPgotICAgICAgICAgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLWJ1bmRsZS1wbHVnaW48L2FydGlmYWN0SWQ+Ci0gICAgICAgICAgICAgICAgPGV4dGVuc2lvbnM+dHJ1ZTwvZXh0ZW5zaW9ucz4KLSAgICAgICAgICAgICAgICA8Y29uZmlndXJhdGlvbj4KLSAgICAgICAgICAgICAgICAgICAgPGluc3RydWN0aW9ucz4KLSAgICAgICAgICAgICAgICAgICAgICAgIDxFbWJlZC1EZXBlbmRlbmN5PgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmcuYXBhY2hlLmZlbGl4LnV0aWxzO2lubGluZT1vcmcvYXBhY2hlL2ZlbGl4L3V0aWxzL2pzb24vSlNPTldyaXRlci5jbGFzcwotICAgICAgICAgICAgICAgICAgICAgICAgPC9FbWJlZC1EZXBlbmRlbmN5PgotICAgICAgICAgICAgICAgICAgICA8L2luc3RydWN0aW9ucz4KLSAgICAgICAgICAgICAgICA8L2NvbmZpZ3VyYXRpb24+Ci0gICAgICAgICAgICA8L3BsdWdpbj4KLSAgICAgICAgICAgIDxwbHVnaW4+Ci0gICAgICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5yYXQ8L2dyb3VwSWQ+Ci0gICAgICAgICAgICAgICAgPGFydGlmYWN0SWQ+YXBhY2hlLXJhdC1wbHVnaW48L2FydGlmYWN0SWQ+Ci0gICAgICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+Ci0gICAgICAgICAgICAgICAgICAgIDxleGNsdWRlcz4KLSAgICAgICAgICAgICAgICAgICAgICAgIDxleGNsdWRlPnNyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci8qKjwvZXhjbHVkZT4KLSAgICAgICAgICAgICAgICAgICAgICAgIDxleGNsdWRlPnNyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci9saWIvdXRpbC9ydW5tb2RlLmpzPC9leGNsdWRlPgotICAgICAgICAgICAgICAgICAgICAgICAgPGV4Y2x1ZGU+c3JjL21haW4vcmVzb3VyY2VzL3RlbXBsYXRlcy9zY3JpcHQtY29uc29sZS5odG1sPC9leGNsdWRlPgotICAgICAgICAgICAgICAgICAgICAgICAgPGV4Y2x1ZGU+c3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QuZ3Jvb3Z5PC9leGNsdWRlPgotICAgICAgICAgICAgICAgICAgICAgICAgPGV4Y2x1ZGU+c3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QuanM8L2V4Y2x1ZGU+Ci0gICAgICAgICAgICAgICAgICAgIDwvZXhjbHVkZXM+Ci0gICAgICAgICAgICAgICAgPC9jb25maWd1cmF0aW9uPgotICAgICAgICAgICAgPC9wbHVnaW4+Ci0gICAgICAgIDwvcGx1Z2lucz4KLSAgICA8L2J1aWxkPgotICAgIDxyZXBvcnRpbmc+Ci0gICAgICAgIDxwbHVnaW5zPgotICAgICAgICAgICAgPHBsdWdpbj4KLSAgICAgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLm1hdmVuLnBsdWdpbnM8L2dyb3VwSWQ+Ci0gICAgICAgICAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tamF2YWRvYy1wbHVnaW48L2FydGlmYWN0SWQ+Ci0gICAgICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+Ci0gICAgICAgICAgICAgICAgICA8IS0tIE5vIGphdmFkb2NzIC0tPgotICAgICAgICAgICAgICAgICAgICA8ZXhjbHVkZVBhY2thZ2VOYW1lcz4KLSAgICAgICAgICAgICAgICAgICAgICAgIG9yZy5hcGFjaGUuc2xpbmcuc2NyaXB0aW5nCi0gICAgICAgICAgICAgICAgICAgIDwvZXhjbHVkZVBhY2thZ2VOYW1lcz4KLSAgICAgICAgICAgICAgICA8L2NvbmZpZ3VyYXRpb24+Ci0gICAgICAgICAgICA8L3BsdWdpbj4KLSAgICAgICAgPC9wbHVnaW5zPgotICAgIDwvcmVwb3J0aW5nPgotCi0gICAgPGRlcGVuZGVuY2llcz4KLSAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5mZWxpeDwvZ3JvdXBJZD4KLSAgICAgICAgPGFydGlmYWN0SWQ+b3JnLmFwYWNoZS5mZWxpeC51dGlsczwvYXJ0aWZhY3RJZD4KLSAgICAgICAgPHZlcnNpb24+MS45LjA8L3ZlcnNpb24+Ci0gICAgICAgIDxzY29wZT5wcm92aWRlZDwvc2NvcGU+Ci0gICAgPC9kZXBlbmRlbmN5PgotICAgICAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgICAgIDxncm91cElkPm9yZy5vc2dpPC9ncm91cElkPgotICAgICAgICAgICAgPGFydGlmYWN0SWQ+b3JnLm9zZ2kuY29yZTwvYXJ0aWZhY3RJZD4KLSAgICAgICAgICAgIDx2ZXJzaW9uPjQuMi4wPC92ZXJzaW9uPgotICAgICAgICA8L2RlcGVuZGVuY3k+Ci0gICAgICAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUuZmVsaXg8L2dyb3VwSWQ+Ci0gICAgICAgICAgICA8YXJ0aWZhY3RJZD5vcmcuYXBhY2hlLmZlbGl4LnNjci5hbm5vdGF0aW9uczwvYXJ0aWZhY3RJZD4KLSAgICAgICAgPC9kZXBlbmRlbmN5PgotICAgICAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgICAgIDxncm91cElkPmphdmF4LnNlcnZsZXQ8L2dyb3VwSWQ+Ci0gICAgICAgICAgICA8YXJ0aWZhY3RJZD5zZXJ2bGV0LWFwaTwvYXJ0aWZhY3RJZD4KLSAgICAgICAgPC9kZXBlbmRlbmN5PgotICAgICAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgICAgIDxncm91cElkPmNvbW1vbnMtbGFuZzwvZ3JvdXBJZD4KLSAgICAgICAgICAgIDxhcnRpZmFjdElkPmNvbW1vbnMtbGFuZzwvYXJ0aWZhY3RJZD4KLSAgICAgICAgICAgIDx2ZXJzaW9uPjIuNDwvdmVyc2lvbj4KLSAgICAgICAgICAgIDxzY29wZT5wcm92aWRlZDwvc2NvcGU+Ci0gICAgICAgIDwvZGVwZW5kZW5jeT4KLSAgICAgICAgPGRlcGVuZGVuY3k+Ci0gICAgICAgICAgIDxncm91cElkPmNvbW1vbnMtZmlsZXVwbG9hZDwvZ3JvdXBJZD4KLSAgICAgICAgICAgPGFydGlmYWN0SWQ+Y29tbW9ucy1maWxldXBsb2FkPC9hcnRpZmFjdElkPgotICAgICAgICAgICA8dmVyc2lvbj4xLjMuMTwvdmVyc2lvbj4KLSAgICAgICAgICAgPHNjb3BlPnByb3ZpZGVkPC9zY29wZT4KLSAgICAgICA8L2RlcGVuZGVuY3k+Ci0gICAgICAgIDxkZXBlbmRlbmN5PgotICAgICAgICAgICA8Z3JvdXBJZD5jb21tb25zLWlvPC9ncm91cElkPgotICAgICAgICAgICA8YXJ0aWZhY3RJZD5jb21tb25zLWlvPC9hcnRpZmFjdElkPgotICAgICAgICAgICA8dmVyc2lvbj4xLjE8L3ZlcnNpb24+Ci0gICAgICAgICAgIDxzY29wZT5wcm92aWRlZDwvc2NvcGU+Ci0gICAgICAgPC9kZXBlbmRlbmN5PgotICAgICAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5mZWxpeDwvZ3JvdXBJZD4KLSAgICAgICAgICAgPGFydGlmYWN0SWQ+b3JnLmFwYWNoZS5mZWxpeC53ZWJjb25zb2xlPC9hcnRpZmFjdElkPgotICAgICAgICAgICA8dmVyc2lvbj4zLjAuMDwvdmVyc2lvbj4KLSAgICAgICAgICAgPHNjb3BlPnByb3ZpZGVkPC9zY29wZT4KLSAgICAgICA8L2RlcGVuZGVuY3k+Ci0gICAgICAgIDxkZXBlbmRlbmN5PgotICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLnNsaW5nPC9ncm91cElkPgotICAgICAgICAgICA8YXJ0aWZhY3RJZD5vcmcuYXBhY2hlLnNsaW5nLmFwaTwvYXJ0aWZhY3RJZD4KLSAgICAgICAgICAgPHZlcnNpb24+Mi4xLjA8L3ZlcnNpb24+Ci0gICAgICAgPC9kZXBlbmRlbmN5PgotICAgICAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUuc2xpbmc8L2dyb3VwSWQ+Ci0gICAgICAgICAgICA8YXJ0aWZhY3RJZD5vcmcuYXBhY2hlLnNsaW5nLnNjcmlwdGluZy5hcGk8L2FydGlmYWN0SWQ+Ci0gICAgICAgICAgICA8dmVyc2lvbj4yLjEuMDwvdmVyc2lvbj4KLSAgICAgICAgPC9kZXBlbmRlbmN5PgotICAgICAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUuc2xpbmc8L2dyb3VwSWQ+Ci0gICAgICAgICAgICA8YXJ0aWZhY3RJZD5vcmcuYXBhY2hlLnNsaW5nLmFkYXB0ZXI8L2FydGlmYWN0SWQ+Ci0gICAgICAgICAgICA8dmVyc2lvbj4yLjAuNDwvdmVyc2lvbj4KLSAgICAgICAgPC9kZXBlbmRlbmN5PgotICAgICAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgICAgIDxncm91cElkPm9yZy5zbGY0ajwvZ3JvdXBJZD4KLSAgICAgICAgICAgIDxhcnRpZmFjdElkPnNsZjRqLWFwaTwvYXJ0aWZhY3RJZD4KLSAgICAgICAgPC9kZXBlbmRlbmN5PgotICAgICAgICA8ZGVwZW5kZW5jeT4KLSAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5zbGluZzwvZ3JvdXBJZD4KLSAgICAgICAgICAgPGFydGlmYWN0SWQ+b3JnLmFwYWNoZS5zbGluZy50ZXN0aW5nLnRvb2xzPC9hcnRpZmFjdElkPgotICAgICAgICAgICA8dmVyc2lvbj4xLjAuMjwvdmVyc2lvbj4KLSAgICAgICAgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgotICAgICAgIDwvZGVwZW5kZW5jeT4KLSAgICA8L2RlcGVuZGVuY2llcz4KLTwvcHJvamVjdD4KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2FwcGVuZGVkLXJlc291cmNlcy9NRVRBLUlORi9MSUNFTlNFIGIvc3JjL21haW4vYXBwZW5kZWQtcmVzb3VyY2VzL01FVEEtSU5GL0xJQ0VOU0UKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDg4YzJhN2YuLjAwMDAwMDAKLS0tIGEvc3JjL21haW4vYXBwZW5kZWQtcmVzb3VyY2VzL01FVEEtSU5GL0xJQ0VOU0UKKysrIC9kZXYvbnVsbApAQCAtMSwzMyArMCwwIEBACi0KLQotQVBBQ0hFIFNMSU5HIFNDUklQVElORyBDT05TT0xFIFNVQkNPTVBPTkVOVFM6IAotCi1UaGUgQXBhY2hlIFNsaW5nIFNjcmlwdCBDb25zb2xlIGluY2x1ZGVzIGEgbnVtYmVyIG9mIHN1YmNvbXBvbmVudHMKLXdpdGggc2VwYXJhdGUgY29weXJpZ2h0IG5vdGljZXMgYW5kIGxpY2Vuc2UgdGVybXMuIFlvdXIgdXNlIG9mIHRoZSBzb3VyY2UKLWNvZGUgZm9yIHRoZSB0aGVzZSBzdWJjb21wb25lbnRzIGlzIHN1YmplY3QgdG8gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zCi1vZiB0aGUgZm9sbG93aW5nIGxpY2Vuc2VzLiAKLQotCi1Db3B5cmlnaHQgKEMpIDIwMTIgYnkgTWFyaWpuIEhhdmVyYmVrZSA8bWFyaWpuaEBnbWFpbC5jb20+Ci0KLVBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKLW9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCi1pbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCi10byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCi1jb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKLWZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6Ci0KLVRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCi1hbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KLQotVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKLUlNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAotRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCi1BVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCi1MSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAotT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgotVEhFIFNPRlRXQVJFLgotCi1QbGVhc2Ugbm90ZSB0aGF0IHNvbWUgc3ViZGlyZWN0b3JpZXMgb2YgdGhlIENvZGVNaXJyb3IgZGlzdHJpYnV0aW9uCi1pbmNsdWRlIHRoZWlyIG93biBMSUNFTlNFIGZpbGVzLCBhbmQgYXJlIHJlbGVhc2VkIHVuZGVyIGRpZmZlcmVudAotbGljZW5jZXMuCmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvc2NyaXB0aW5nL2NvbnNvbGUvaW50ZXJuYWwvUnVudGltZVNjcmlwdFJlc291cmNlLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvc2NyaXB0aW5nL2NvbnNvbGUvaW50ZXJuYWwvUnVudGltZVNjcmlwdFJlc291cmNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI0OTU4N2MuLjAwMDAwMDAKLS0tIGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL3NjcmlwdGluZy9jb25zb2xlL2ludGVybmFsL1J1bnRpbWVTY3JpcHRSZXNvdXJjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTcwICswLDAgQEAKLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS5zbGluZy5zY3JpcHRpbmcuY29uc29sZS5pbnRlcm5hbDsKLQotaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuYXBpLnJlc291cmNlLkFic3RyYWN0UmVzb3VyY2U7Ci1pbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5hcGkucmVzb3VyY2UuUmVzb3VyY2U7Ci1pbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5hcGkucmVzb3VyY2UuUmVzb3VyY2VNZXRhZGF0YTsKLWltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmFwaS5yZXNvdXJjZS5SZXNvdXJjZVJlc29sdmVyOwotCi1jbGFzcyBSdW50aW1lU2NyaXB0UmVzb3VyY2UgZXh0ZW5kcyBBYnN0cmFjdFJlc291cmNlIGltcGxlbWVudHMgUmVzb3VyY2UgewotCi0gICAgcHJpdmF0ZSBSZXNvdXJjZU1ldGFkYXRhIG1ldGFkYXRhID0gbmV3IFJlc291cmNlTWV0YWRhdGEoKTsKLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBwYXRoOwotICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIHNjcmlwdENvbnRlbnQ7Ci0KLSAgICBwdWJsaWMgUnVudGltZVNjcmlwdFJlc291cmNlKFN0cmluZyBleHRlbnNpb24sIFN0cmluZyBzY3JpcHRUZXh0KSB7Ci0gICAgICAgIHRoaXMuc2NyaXB0Q29udGVudCA9IGdldFNjcmlwdENvbnRlbnQoc2NyaXB0VGV4dCk7Ci0gICAgICAgIHRoaXMucGF0aCA9ICJzY3JpcHQuIiArIGV4dGVuc2lvbjsKLSAgICB9Ci0KLSAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgPEFkYXB0ZXJUeXBlPiBBZGFwdGVyVHlwZSBhZGFwdFRvKENsYXNzPEFkYXB0ZXJUeXBlPiB0eXBlKSB7Ci0gICAgICAgIGlmKElucHV0U3RyZWFtLmNsYXNzLmlzQXNzaWduYWJsZUZyb20odHlwZSkpewotICAgICAgICAgICAgcmV0dXJuIChBZGFwdGVyVHlwZSkgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHNjcmlwdENvbnRlbnQpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdXBlci5hZGFwdFRvKHR5cGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGFic29sdXRlIHBhdGggb2YgdGhpcyByZXNvdXJjZSBpbiB0aGUgcmVzb3VyY2UgdHJlZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFBhdGgoKSB7Ci0gICAgICAgIHJldHVybiBwYXRoOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyByZXNvdXJjZS4gVGhlIG5hbWUgb2YgYSByZXNvdXJjZSBpcyB0aGUgbGFzdAotICAgICAqIHNlZ21lbnQgb2YgdGhlIHtAbGluayAjZ2V0UGF0aCgpIHBhdGh9LgotICAgICAqCi0gICAgICogQHNpbmNlIDIuMS4wCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gInNjcmlwdCI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcGFyZW50IHJlc291cmNlIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgcmVzb3VyY2UKLSAgICAgKiByZXByZXNlbnRzIHRoZSByb290IG9mIHRoZSByZXNvdXJjZSB0cmVlLgotICAgICAqCi0gICAgICogQHNpbmNlIDIuMS4wCi0gICAgICovCi0gICAgcHVibGljIFJlc291cmNlIGdldFBhcmVudCgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhbiBpdGVyYXRvciBvZiB0aGUgZGlyZWN0IGNoaWxkcmVuIG9mIHRoaXMgcmVzb3VyY2UuCi0gICAgICogPHAvPgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGEgY29udmVuaWVuY2UgYW5kIHJldHVybnMgZXhhY3RseSB0aGUgc2FtZSByZXNvdXJjZXMgYXMKLSAgICAgKiBjYWxsaW5nIDxjb2RlPmdldFJlc291cmNlUmVzb2x2ZXIoKS5saXN0Q2hpbGRyZW4ocmVzb3VyY2UpPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLmFwYWNoZS5zbGluZy5hcGkucmVzb3VyY2UuUmVzb3VyY2VSZXNvbHZlciNsaXN0Q2hpbGRyZW4ob3JnLmFwYWNoZS5zbGluZy5hcGkucmVzb3VyY2UuUmVzb3VyY2UpCi0gICAgICogQHNpbmNlIDIuMS4wCi0gICAgICovCi0gICAgcHVibGljIEl0ZXJhdG9yPFJlc291cmNlPiBsaXN0Q2hpbGRyZW4oKSB7Ci0gICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy48UmVzb3VyY2U+ZW1wdHlMaXN0KCkuaXRlcmF0b3IoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBjaGlsZCBhdCB0aGUgZ2l2ZW4gcmVsYXRpdmUgcGF0aCBvZiB0aGlzIHJlc291cmNlIG9yCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gc3VjaCBjaGlsZCBleGlzdHMuCi0gICAgICogPHAvPgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGEgY29udmVuaWVuY2UgYW5kIHJldHVybnMgZXhhY3RseSB0aGUgc2FtZSByZXNvdXJjZXMgYXMKLSAgICAgKiBjYWxsaW5nIDxjb2RlPmdldFJlc291cmNlUmVzb2x2ZXIoKS5nZXRSZXNvdXJjZShyZXNvdXJjZSwgcmVsUGF0aCk8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmFwaS5yZXNvdXJjZS5SZXNvdXJjZVJlc29sdmVyI2dldFJlc291cmNlKG9yZy5hcGFjaGUuc2xpbmcuYXBpLnJlc291cmNlLlJlc291cmNlLCBTdHJpbmcpCi0gICAgICogQHNpbmNlIDIuMS4wCi0gICAgICovCi0gICAgcHVibGljIFJlc291cmNlIGdldENoaWxkKFN0cmluZyByZWxQYXRoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSByZXNvdXJjZSB0eXBlIGlzIG1lYW50IHRvIHBvaW50IHRvIHJlbmRlcmluZy9wcm9jZXNzaW5nIHNjcmlwdHMsCi0gICAgICogZWRpdGluZyBkaWFsb2dzLCBldGMuIEl0IGlzIHVzdWFsbHkgYSBwYXRoIGluIHRoZSByZXBvc2l0b3J5LCB3aGVyZQotICAgICAqIHNjcmlwdHMgYW5kIG90aGVyIHRvb2xzIGRlZmluaXRpb25zIGFyZSBmb3VuZCwgYnV0IHRoZQotICAgICAqIHtAbGluayBvcmcuYXBhY2hlLnNsaW5nLmFwaS5yZXNvdXJjZS5SZXNvdXJjZVJlc29sdmVyfSBpcyBmcmVlIHRvIHNldCB0aGlzIHRvIGFueSBzdWl0YWJsZSB2YWx1ZSBzdWNoCi0gICAgICogYXMgdGhlIHByaW1hcnkgbm9kZSB0eXBlIG9mIHRoZSBKQ1Igbm9kZSBmcm9tIHdoaWNoIHRoZSByZXNvdXJjZSBpcwotICAgICAqIGNyZWF0ZWQuCi0gICAgICogPHAvPgotICAgICAqIElmIHRoZSByZXNvdXJjZSBpbnN0YW5jZSByZXByZXNlbnRzIGEgcmVzb3VyY2Ugd2hpY2ggaXMgbm90IGFjdHVhbGx5Ci0gICAgICogZXhpc3RpbmcsIHRoaXMgbWV0aG9kIHJldHVybnMge0BsaW5rICNSRVNPVVJDRV9UWVBFX05PTl9FWElTVElOR30uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRSZXNvdXJjZVR5cGUoKSB7Ci0gICAgICAgIHJldHVybiBSRVNPVVJDRV9UWVBFX05PTl9FWElTVElORzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzdXBlciB0eXBlIG9mIHRoZSB0eXBlIG9mIHRoZSByZXNvdXJjZSBvciA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqIGlmIHRoZSB7QGxpbmsgI2dldFJlc291cmNlVHlwZSgpfSBoYXMgbm8gc3VwZXJ0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UmVzb3VyY2VTdXBlclR5cGUoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlc291cmNlIHR5cGUgb3IgYW55IG9mIHRoZSByZXNvdXJjZSdzCi0gICAgICogc3VwZXIgdHlwZShzKSBlcXVhbHMgdGhlIGdpdmVuIHJlc291cmNlIHR5cGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVzb3VyY2VUeXBlIFRoZSByZXNvdXJjZSB0eXBlIHRvIGNoZWNrIHRoaXMgcmVzb3VyY2UgYWdhaW5zdC4KLSAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSByZXNvdXJjZSB0eXBlIG9yIGFueSBvZiB0aGUgcmVzb3VyY2UncwotICAgICAqICAgICAgICAgc3VwZXIgdHlwZShzKSBlcXVhbHMgdGhlIGdpdmVuIHJlc291cmNlIHR5cGUuIDxjb2RlPmZhbHNlPC9jb2RlPgotICAgICAqICAgICAgICAgaXMgYWxzbyByZXR1cm5lZCBpZiA8Y29kZT5yZXNvdXJjZVR5cGU8L2NvZGU+IGlzCi0gICAgICogICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAc2luY2UgMi4xLjAKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1Jlc291cmNlVHlwZShTdHJpbmcgcmVzb3VyY2VUeXBlKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBtZXRhZGF0YSBvZiB0aGlzIHJlc291cmNlLiBUaGUgY29uY3JldGUgZGF0YSBjb250YWluZWQgaW4gdGhlCi0gICAgICoge0BsaW5rIG9yZy5hcGFjaGUuc2xpbmcuYXBpLnJlc291cmNlLlJlc291cmNlTWV0YWRhdGF9IG9iamVjdCByZXR1cm5lZCBpcyBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYwotICAgICAqIGV4Y2VwdCBmb3IgdGhlIHtAbGluayBvcmcuYXBhY2hlLnNsaW5nLmFwaS5yZXNvdXJjZS5SZXNvdXJjZU1ldGFkYXRhI1JFU09MVVRJT05fUEFUSH0gcHJvcGVydHkgd2hpY2ggaXMKLSAgICAgKiByZXF1aXJlZCB0byBiZSBzZXQgdG8gdGhlIHBhcnQgb2YgdGhlIHJlcXVlc3QgVVJJIHVzZWQgdG8gcmVzb2x2ZSB0aGUKLSAgICAgKiByZXNvdXJjZS4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLmFwYWNoZS5zbGluZy5hcGkucmVzb3VyY2UuUmVzb3VyY2VNZXRhZGF0YQotICAgICAqLwotICAgIHB1YmxpYyBSZXNvdXJjZU1ldGFkYXRhIGdldFJlc291cmNlTWV0YWRhdGEoKSB7Ci0gICAgICAgIHJldHVybiBtZXRhZGF0YTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSB7QGxpbmsgb3JnLmFwYWNoZS5zbGluZy5hcGkucmVzb3VyY2UuUmVzb3VyY2VSZXNvbHZlcn0gZnJvbSB3aGljaCB0aGlzIHJlc291cmNlIGhhcyBiZWVuCi0gICAgICogcmV0cmlldmVkLgotICAgICAqLwotICAgIHB1YmxpYyBSZXNvdXJjZVJlc29sdmVyIGdldFJlc291cmNlUmVzb2x2ZXIoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHByaXZhdGUgYnl0ZVtdIGdldFNjcmlwdENvbnRlbnQoU3RyaW5nIHNjcmlwdFRleHQpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBzY3JpcHRUZXh0LmdldEJ5dGVzKCJ1dGYtOCIpOwotICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL3NjcmlwdGluZy9jb25zb2xlL2ludGVybmFsL1NjcmlwdENvbnNvbGVQbHVnaW4uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9zY3JpcHRpbmcvY29uc29sZS9pbnRlcm5hbC9TY3JpcHRDb25zb2xlUGx1Z2luLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ0Mjk0Y2MuLjAwMDAwMDAKLS0tIGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL3NjcmlwdGluZy9jb25zb2xlL2ludGVybmFsL1NjcmlwdENvbnNvbGVQbHVnaW4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0NSArMCwwIEBACi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUuc2xpbmcuc2NyaXB0aW5nLmNvbnNvbGUuaW50ZXJuYWw7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKLWltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKLWltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5MaXN0OwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci0KLWltcG9ydCBqYXZheC5zY3JpcHQuU2NyaXB0RW5naW5lRmFjdG9yeTsKLWltcG9ydCBqYXZheC5zY3JpcHQuU2NyaXB0RW5naW5lTWFuYWdlcjsKLWltcG9ydCBqYXZheC5zZXJ2bGV0LlNlcnZsZXRFeGNlcHRpb247Ci1pbXBvcnQgamF2YXguc2VydmxldC5odHRwLkh0dHBTZXJ2bGV0UmVxdWVzdDsKLWltcG9ydCBqYXZheC5zZXJ2bGV0Lmh0dHAuSHR0cFNlcnZsZXRSZXNwb25zZTsKLQotaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5maWxldXBsb2FkLkZpbGVJdGVtOwotaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5pby5JT1V0aWxzOwotaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXguc2NyLmFubm90YXRpb25zLkFjdGl2YXRlOwotaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXguc2NyLmFubm90YXRpb25zLkNvbXBvbmVudDsKLWltcG9ydCBvcmcuYXBhY2hlLmZlbGl4LnNjci5hbm5vdGF0aW9ucy5EZWFjdGl2YXRlOwotaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXguc2NyLmFubm90YXRpb25zLlByb3BlcnR5OwotaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXguc2NyLmFubm90YXRpb25zLlJlZmVyZW5jZTsKLWltcG9ydCBvcmcuYXBhY2hlLmZlbGl4LnNjci5hbm5vdGF0aW9ucy5TZXJ2aWNlOwotaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXgudXRpbHMuanNvbi5KU09OV3JpdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXgud2ViY29uc29sZS5BYnN0cmFjdFdlYkNvbnNvbGVQbHVnaW47Ci1pbXBvcnQgb3JnLmFwYWNoZS5mZWxpeC53ZWJjb25zb2xlLkRlZmF1bHRWYXJpYWJsZVJlc29sdmVyOwotaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXgud2ViY29uc29sZS5TaW1wbGVXZWJDb25zb2xlUGx1Z2luOwotaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXgud2ViY29uc29sZS5XZWJDb25zb2xlVXRpbDsKLWltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmFwaS5yZXNvdXJjZS5SZXNvdXJjZTsKLWltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmFwaS5zY3JpcHRpbmcuU2xpbmdCaW5kaW5nczsKLWltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmFwaS5zY3JpcHRpbmcuU2xpbmdTY3JpcHQ7Ci1pbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQ7Ci1pbXBvcnQgb3JnLnNsZjRqLkxvZ2dlcjsKLWltcG9ydCBvcmcuc2xmNGouTG9nZ2VyRmFjdG9yeTsKLQotQENvbXBvbmVudAotQFNlcnZpY2UKLUBQcm9wZXJ0eShuYW1lID0gImZlbGl4LndlYmNvbnNvbGUubGFiZWwiLCB2YWx1ZSA9IFNjcmlwdENvbnNvbGVQbHVnaW4uTkFNRSkKLXB1YmxpYyBjbGFzcyBTY3JpcHRDb25zb2xlUGx1Z2luIGV4dGVuZHMgU2ltcGxlV2ViQ29uc29sZVBsdWdpbiB7Ci0KLSAgICBwcml2YXRlIExvZ2dlciBsb2cgPSBMb2dnZXJGYWN0b3J5LmdldExvZ2dlcihnZXRDbGFzcygpKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FID0gInNjcmlwdGNvbnNvbGUiOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUSVRMRSA9ICIlc2NyaXB0LnRpdGxlIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBDU1MgPSB7Ii9yZXMvdWkvY29kZW1pcnJvci9saWIvY29kZW1pcnJvci5jc3MiLCIvcmVzL3VpL3NjcmlwdC1jb25zb2xlLmNzcyJ9OwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIFRFTVBMQVRFOwotICAgIHByaXZhdGUgQnVuZGxlQ29udGV4dCBidW5kbGVDb250ZXh0OwotCi0gICAgQFJlZmVyZW5jZQotICAgIHByaXZhdGUgU2NyaXB0RW5naW5lTWFuYWdlciBzY3JpcHRFbmdpbmVNYW5hZ2VyOwotCi0gICAgcHVibGljIFNjcmlwdENvbnNvbGVQbHVnaW4oKSB7Ci0gICAgICAgIHN1cGVyKE5BTUUsIFRJVExFLCBwcm9jZXNzRmlsZU5hbWVzKENTUykpOwotICAgICAgICBURU1QTEFURSA9IHJlYWRUZW1wbGF0ZUZpbGUoIi90ZW1wbGF0ZXMvc2NyaXB0LWNvbnNvbGUuaHRtbCIpOwotICAgIH0KLQotICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQotICAgIEBPdmVycmlkZQotICAgIHByb3RlY3RlZCB2b2lkIHJlbmRlckNvbnRlbnQoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKSB0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICBmaW5hbCBQcmludFdyaXRlciBwdyA9IHJlc3BvbnNlLmdldFdyaXRlcigpOwotICAgICAgICBEZWZhdWx0VmFyaWFibGVSZXNvbHZlciB2YXJSZXNvbHZlciA9IChEZWZhdWx0VmFyaWFibGVSZXNvbHZlcikgV2ViQ29uc29sZVV0aWwuZ2V0VmFyaWFibGVSZXNvbHZlcihyZXF1ZXN0KTsKLSAgICAgICAgdmFyUmVzb2x2ZXIucHV0KCJfX3NjcmlwdENvbmZpZ19fIixnZXRTY3JpcHRDb25maWcoKSk7Ci0gICAgICAgIHB3LnByaW50bG4oVEVNUExBVEUpOwotICAgIH0KLQotICAgIEBPdmVycmlkZQotICAgIHByb3RlY3RlZCB2b2lkIGRvUG9zdChIdHRwU2VydmxldFJlcXVlc3QgcmVxLCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3ApIHRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKHJlcSk7Ci0gICAgICAgIHJlc3Auc2V0Q29udGVudFR5cGUoY29udGVudFR5cGUpOwotICAgICAgICBpZiAoY29udGVudFR5cGUuc3RhcnRzV2l0aCgidGV4dC8iKSkgewotICAgICAgICAgICAgcmVzcC5zZXRDaGFyYWN0ZXJFbmNvZGluZygiVVRGLTgiKTsKLSAgICAgICAgfQotICAgICAgICBmaW5hbCBTdHJpbmcgc2NyaXB0ID0gZ2V0Q29kZVZhbHVlKHJlcSk7Ci0gICAgICAgIGZpbmFsIFNsaW5nQmluZGluZ3MgYmluZGluZ3MgPSBuZXcgU2xpbmdCaW5kaW5ncygpOwotICAgICAgICBmaW5hbCBQcmludFdyaXRlciBwdyA9IHJlc3AuZ2V0V3JpdGVyKCk7Ci0gICAgICAgIC8vUG9wdWxhdGUgYmluZGluZ3MKLSAgICAgICAgYmluZGluZ3MucHV0KFNsaW5nQmluZGluZ3MuUkVRVUVTVCwgcmVxKTsKLSAgICAgICAgYmluZGluZ3MucHV0KFNsaW5nQmluZGluZ3MuUkVBREVSLCBuZXcgU3RyaW5nUmVhZGVyKHNjcmlwdCkpOwotICAgICAgICBiaW5kaW5ncy5wdXQoU2xpbmdCaW5kaW5ncy5SRVNQT05TRSwgcmVzcCk7Ci0gICAgICAgIGJpbmRpbmdzLnB1dChTbGluZ0JpbmRpbmdzLk9VVCwgcHcpOwotCi0gICAgICAgIC8vQWxzbyBleHBvc2UgdGhlIGJ1bmRsZUNvbnRleHQgdG8gc2ltcGxpZnkgc2NyaXB0cyBpbnRlcmFjdGlvbiB3aXRoIHRoZQotICAgICAgICAvL2VuY2xvc2luZyBPU0dpIGNvbnRhaW5lcgotICAgICAgICBiaW5kaW5ncy5wdXQoImJ1bmRsZUNvbnRleHQiLCBidW5kbGVDb250ZXh0KTsKLQotICAgICAgICBmaW5hbCBTdHJpbmcgbGFuZyA9IFdlYkNvbnNvbGVVdGlsLmdldFBhcmFtZXRlcihyZXEsICJsYW5nIik7Ci0gICAgICAgIGZpbmFsIFJlc291cmNlIHJlc291cmNlID0gbmV3IFJ1bnRpbWVTY3JpcHRSZXNvdXJjZShsYW5nLCBzY3JpcHQpOwotICAgICAgICBmaW5hbCBib29sZWFuIHdlYkNsaWVudCA9ICJ3ZWJjb25zb2xlIi5lcXVhbHMoV2ViQ29uc29sZVV0aWwuZ2V0UGFyYW1ldGVyKHJlcSwiY2xpZW50IikpOwotCi0gICAgICAgIFNsaW5nU2NyaXB0IHNsaW5nU2NyaXB0ID0gcmVzb3VyY2UuYWRhcHRUbyhTbGluZ1NjcmlwdC5jbGFzcyk7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBsb2cuZGVidWcoIkV4ZWN1dGluZyBzY3JpcHQge30iLHNjcmlwdCk7Ci0gICAgICAgICAgICBzbGluZ1NjcmlwdC5ldmFsKGJpbmRpbmdzKTsKLSAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpewotICAgICAgICAgICAgaWYoIXdlYkNsaWVudCl7Ci0gICAgICAgICAgICAgICAgcmVzcC5zZXRTdGF0dXMoNTAwKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHB3LnByaW50bG4oZXhjZXB0aW9uVG9TdHJpbmcodCkpOwotICAgICAgICAgICAgbG9nLndhcm4oIkVycm9yIGluIGV4ZWN1dGluZyBzY3JpcHQiLHQpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0Q29kZVZhbHVlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXEpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIFN0cmluZyBzY3JpcHQgPSBXZWJDb25zb2xlVXRpbC5nZXRQYXJhbWV0ZXIocmVxLCAiY29kZSIpOwotICAgICAgICBpZihzY3JpcHQgPT0gbnVsbCl7Ci0gICAgICAgICAgICBzY3JpcHQgPSBnZXRDb250ZW50RnJvbUZpbGVQYXJ0KHJlcSwgImNvZGUiKTsKLSAgICAgICAgfQotICAgICAgICBpZihzY3JpcHQgPT0gbnVsbCl7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCInY29kZScgcGFyYW1ldGVyIG5vdCBwYXNzZWQiKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc2NyaXB0OwotICAgIH0KLQotICAgIHByaXZhdGUgU3RyaW5nIGdldENvbnRlbnRUeXBlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXEpIHsKLSAgICAgICAgU3RyaW5nIHBhc3NlZENvbnRlbnRUeXBlID0gV2ViQ29uc29sZVV0aWwuZ2V0UGFyYW1ldGVyKHJlcSwicmVzcG9uc2VDb250ZW50VHlwZSIpOwotICAgICAgICBpZihwYXNzZWRDb250ZW50VHlwZSAhPSBudWxsKXsKLSAgICAgICAgICAgIHJldHVybiBwYXNzZWRDb250ZW50VHlwZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcmVxLmdldFBhdGhJbmZvKCkuZW5kc1dpdGgoIi5qc29uIikgPyAiYXBwbGljYXRpb24vanNvbiIgOiAidGV4dC9wbGFpbiI7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgZXhjZXB0aW9uVG9TdHJpbmcoVGhyb3dhYmxlIHQpIHsKLSAgICAgICAgU3RyaW5nV3JpdGVyIHN3ID0gbmV3IFN0cmluZ1dyaXRlcigpOwotICAgICAgICB0LnByaW50U3RhY2tUcmFjZShuZXcgUHJpbnRXcml0ZXIoc3cpKTsKLSAgICAgICAgcmV0dXJuIHN3LnRvU3RyaW5nKCk7Ci0gICAgfQotCi0KLSAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBwcm9jZXNzRmlsZU5hbWVzKFN0cmluZ1tdIGNzc0ZpbGVzKSB7Ci0gICAgICAgIFN0cmluZ1tdIGNzcyA9IG5ldyBTdHJpbmdbY3NzRmlsZXMubGVuZ3RoXTsKLSAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGNzc0ZpbGVzLmxlbmd0aDsgaSsrKXsKLSAgICAgICAgICAgIGNzc1tpXSA9ICAnLycgKyBOQU1FICsgQ1NTW2ldOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBjc3M7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0U2NyaXB0Q29uZmlnKCkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIGdldFNjcmlwdENvbmZpZzAoKTsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIFN0cmluZyBnZXRTY3JpcHRDb25maWcwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgU3RyaW5nV3JpdGVyIHN3ID0gbmV3IFN0cmluZ1dyaXRlcigpOwotICAgICAgICBKU09OV3JpdGVyIGp3ID0gbmV3IEpTT05Xcml0ZXIoc3cpOwotICAgICAgICBqdy5hcnJheSgpOwotCi0gICAgICAgIGZvcihTY3JpcHRFbmdpbmVGYWN0b3J5IHNlZiA6IHNjcmlwdEVuZ2luZU1hbmFnZXIuZ2V0RW5naW5lRmFjdG9yaWVzKCkpewotICAgICAgICAgICAgancub2JqZWN0KCk7Ci0gICAgICAgICAgICBpZihzZWYuZ2V0RXh0ZW5zaW9ucygpLmlzRW1wdHkoKSl7Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBqdy5rZXkoImxhbmdOYW1lIikudmFsdWUoc2VmLmdldExhbmd1YWdlTmFtZSgpKTsKLSAgICAgICAgICAgIGp3LmtleSgibGFuZ0NvZGUiKS52YWx1ZShzZWYuZ2V0RXh0ZW5zaW9ucygpLmdldCgwKSk7Ci0KLSAgICAgICAgICAgIC8vTGFuZ3VhZ2UgbW9kZSBhcyBwZXIgQ29kZU1pcnJvciBuYW1lcwotICAgICAgICAgICAgU3RyaW5nIG1vZGUgPSBkZXRlcm1pbmVNb2RlKHNlZi5nZXRFeHRlbnNpb25zKCkpOwotICAgICAgICAgICAgaWYobW9kZSAhPSBudWxsKXsKLSAgICAgICAgICAgICAgICBqdy5rZXkoIm1vZGUiKS52YWx1ZShtb2RlKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgancuZW5kT2JqZWN0KCk7Ci0gICAgICAgIH0KLQotICAgICAgICBqdy5lbmRBcnJheSgpOwotICAgICAgICByZXR1cm4gc3cudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIFN0cmluZyBkZXRlcm1pbmVNb2RlKExpc3Q8U3RyaW5nPiBleHRlbnNpb25zKSB7Ci0gICAgICAgIGlmKGV4dGVuc2lvbnMuY29udGFpbnMoImdyb292eSIpKXsKLSAgICAgICAgICAgIHJldHVybiAiZ3Jvb3Z5IjsKLSAgICAgICAgfWVsc2UgaWYgKGV4dGVuc2lvbnMuY29udGFpbnMoImVzcCIpKXsKLSAgICAgICAgICAgIHJldHVybiAiamF2YXNjcmlwdCI7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0Q29udGVudEZyb21GaWxlUGFydChIdHRwU2VydmxldFJlcXVlc3QgcmVxLCBTdHJpbmcgcGFyYW1OYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBTdHJpbmcgdmFsdWUgPSBXZWJDb25zb2xlVXRpbC5nZXRQYXJhbWV0ZXIocmVxLCBwYXJhbU5hbWUpOwotICAgICAgICBpZih2YWx1ZSAhPSBudWxsKXsKLSAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKLSAgICAgICAgfQotICAgICAgICBmaW5hbCBNYXAgcGFyYW1zID0gKE1hcCkgcmVxLmdldEF0dHJpYnV0ZSggQWJzdHJhY3RXZWJDb25zb2xlUGx1Z2luLkFUVFJfRklMRVVQTE9BRCApOwotICAgICAgICBpZiAoIHBhcmFtcyA9PSBudWxsICl7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBGaWxlSXRlbVtdIGNvZGVGaWxlID0gZ2V0RmlsZUl0ZW1zKHBhcmFtcyxwYXJhbU5hbWUpOwotICAgICAgICBpZihjb2RlRmlsZS5sZW5ndGggPT0gMCl7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG51bGw7Ci0gICAgICAgIHRyeXsKLSAgICAgICAgICAgIGlzID0gY29kZUZpbGVbMF0uZ2V0SW5wdXRTdHJlYW0oKTsKLSAgICAgICAgICAgIFN0cmluZ1dyaXRlciBzdyA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKLSAgICAgICAgICAgIElPVXRpbHMuY29weShpcyxzdywidXRmLTgiKTsKLSAgICAgICAgICAgIHJldHVybiBzdy50b1N0cmluZygpOwotICAgICAgICB9ZmluYWxseXsKLSAgICAgICAgICAgIElPVXRpbHMuY2xvc2VRdWlldGx5KGlzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgRmlsZUl0ZW1bXSBnZXRGaWxlSXRlbXMoTWFwIHBhcmFtcywgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgZmluYWwgTGlzdCBmaWxlcyA9IG5ldyBBcnJheUxpc3QoKTsKLSAgICAgICAgRmlsZUl0ZW1bXSBpdGVtcyA9IChGaWxlSXRlbVtdKSBwYXJhbXMuZ2V0KG5hbWUpOwotICAgICAgICBpZiAoaXRlbXMgIT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIGlmICghaXRlbXNbaV0uaXNGb3JtRmllbGQoKSAmJiBpdGVtc1tpXS5nZXRTaXplKCkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbGVzLmFkZChpdGVtc1tpXSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAoRmlsZUl0ZW1bXSkgZmlsZXMudG9BcnJheShuZXcgRmlsZUl0ZW1bZmlsZXMuc2l6ZSgpXSk7Ci0gICAgfQotCi0gICAgQEFjdGl2YXRlCi0gICAgcHVibGljIHZvaWQgYWN0aXZhdGUoQnVuZGxlQ29udGV4dCBidW5kbGVDb250ZXh0KSB7Ci0gICAgICAgIHN1cGVyLmFjdGl2YXRlKGJ1bmRsZUNvbnRleHQpOwotICAgICAgICB0aGlzLmJ1bmRsZUNvbnRleHQgPSBidW5kbGVDb250ZXh0OwotICAgIH0KLQotICAgIEBEZWFjdGl2YXRlCi0gICAgcHVibGljIHZvaWQgZGVhY3RpdmF0ZSgpIHsKLSAgICAgICAgc3VwZXIuZGVhY3RpdmF0ZSgpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9tYWluL3Jlc291cmNlcy9PU0dJLUlORi9sMTBuL2J1bmRsZS5wcm9wZXJ0aWVzIGIvc3JjL21haW4vcmVzb3VyY2VzL09TR0ktSU5GL2wxMG4vYnVuZGxlLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM1NGRlMzIuLjAwMDAwMDAKLS0tIGEvc3JjL21haW4vcmVzb3VyY2VzL09TR0ktSU5GL2wxMG4vYnVuZGxlLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwyMCArMCwwIEBACi0jCi0jIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotIyBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSMgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotIyBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotIyAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotIyB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotIwotIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotIwotIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0jIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0jIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0jIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotIwotCi1zY3JpcHQudGl0bGU9U2NyaXB0IENvbnNvbGUKLWNvbnNvbGUuZXhlY3V0ZT1FeGVjdXRlCi1jb25zb2xlLmxhbmc9TGFuZ3VhZ2UKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL2NvZGVtaXJyb3IvbGliL2NvZGVtaXJyb3IuY3NzIGIvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9jb2RlbWlycm9yL2xpYi9jb2RlbWlycm9yLmNzcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWM5YzI5YS4uMDAwMDAwMAotLS0gYS9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL2NvZGVtaXJyb3IvbGliL2NvZGVtaXJyb3IuY3NzCisrKyAvZGV2L251bGwKQEAgLTEsMTE0ICswLDAgQEAKLS5Db2RlTWlycm9yIHsKLSAgbGluZS1oZWlnaHQ6IDFlbTsKLSAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsKLX0KLQotLkNvZGVNaXJyb3Itc2Nyb2xsIHsKLSAgb3ZlcmZsb3c6IGF1dG87Ci0gIGhlaWdodDogMzAwcHg7Ci0gIC8qIFRoaXMgaXMgbmVlZGVkIHRvIHByZXZlbnQgYW4gSUVbNjddIGJ1ZyB3aGVyZSB0aGUgc2Nyb2xsZWQgY29udGVudAotICAgICBpcyB2aXNpYmxlIG91dHNpZGUgb2YgdGhlIHNjcm9sbGluZyBib3guICovCi0gIHBvc2l0aW9uOiByZWxhdGl2ZTsKLSAgb3V0bGluZTogbm9uZTsKLX0KLQotLkNvZGVNaXJyb3ItZ3V0dGVyIHsKLSAgcG9zaXRpb246IGFic29sdXRlOyBsZWZ0OiAwOyB0b3A6IDA7Ci0gIHotaW5kZXg6IDEwOwotICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjdmN2Y3OwotICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjZWVlOwotICBtaW4td2lkdGg6IDJlbTsKLSAgaGVpZ2h0OiAxMDAlOwotfQotLkNvZGVNaXJyb3ItZ3V0dGVyLXRleHQgewotICBjb2xvcjogI2FhYTsKLSAgdGV4dC1hbGlnbjogcmlnaHQ7Ci0gIHBhZGRpbmc6IC40ZW0gLjJlbSAuNGVtIC40ZW07Ci0gIHdoaXRlLXNwYWNlOiBwcmUgIWltcG9ydGFudDsKLX0KLS5Db2RlTWlycm9yLWxpbmVzIHsKLSAgcGFkZGluZzogLjRlbTsKLSAgd2hpdGUtc3BhY2U6IHByZTsKLX0KLQotLkNvZGVNaXJyb3IgcHJlIHsKLSAgLW1vei1ib3JkZXItcmFkaXVzOiAwOwotICAtd2Via2l0LWJvcmRlci1yYWRpdXM6IDA7Ci0gIC1vLWJvcmRlci1yYWRpdXM6IDA7Ci0gIGJvcmRlci1yYWRpdXM6IDA7Ci0gIGJvcmRlci13aWR0aDogMDsgbWFyZ2luOiAwOyBwYWRkaW5nOiAwOyBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsKLSAgZm9udC1mYW1pbHk6IGluaGVyaXQ7Ci0gIGZvbnQtc2l6ZTogaW5oZXJpdDsKLSAgcGFkZGluZzogMDsgbWFyZ2luOiAwOwotICB3aGl0ZS1zcGFjZTogcHJlOwotICB3b3JkLXdyYXA6IG5vcm1hbDsKLSAgbGluZS1oZWlnaHQ6IGluaGVyaXQ7Ci19Ci0KLS5Db2RlTWlycm9yLXdyYXAgcHJlIHsKLSAgd29yZC13cmFwOiBicmVhay13b3JkOwotICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7Ci0gIHdvcmQtYnJlYWs6IG5vcm1hbDsKLX0KLS5Db2RlTWlycm9yLXdyYXAgLkNvZGVNaXJyb3Itc2Nyb2xsIHsKLSAgb3ZlcmZsb3cteDogaGlkZGVuOwotfQotCi0uQ29kZU1pcnJvciB0ZXh0YXJlYSB7Ci0gIG91dGxpbmU6IG5vbmUgIWltcG9ydGFudDsKLX0KLQotLkNvZGVNaXJyb3IgcHJlLkNvZGVNaXJyb3ItY3Vyc29yIHsKLSAgei1pbmRleDogMTA7Ci0gIHBvc2l0aW9uOiBhYnNvbHV0ZTsKLSAgdmlzaWJpbGl0eTogaGlkZGVuOwotICBib3JkZXItbGVmdDogMXB4IHNvbGlkIGJsYWNrOwotICBib3JkZXItcmlnaHQ6bm9uZTsKLSAgd2lkdGg6MDsKLX0KLS5Db2RlTWlycm9yIHByZS5Db2RlTWlycm9yLWN1cnNvci5Db2RlTWlycm9yLW92ZXJ3cml0ZSB7fQotLkNvZGVNaXJyb3ItZm9jdXNlZCBwcmUuQ29kZU1pcnJvci1jdXJzb3IgewotICB2aXNpYmlsaXR5OiB2aXNpYmxlOwotfQotCi1kaXYuQ29kZU1pcnJvci1zZWxlY3RlZCB7IGJhY2tncm91bmQ6ICNkOWQ5ZDk7IH0KLS5Db2RlTWlycm9yLWZvY3VzZWQgZGl2LkNvZGVNaXJyb3Itc2VsZWN0ZWQgeyBiYWNrZ3JvdW5kOiAjZDdkNGYwOyB9Ci0KLS5Db2RlTWlycm9yLXNlYXJjaGluZyB7Ci0gIGJhY2tncm91bmQ6ICNmZmE7Ci0gIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDAsIC40KTsKLX0KLQotLyogRGVmYXVsdCB0aGVtZSAqLwotCi0uY20tcy1kZWZhdWx0IHNwYW4uY20ta2V5d29yZCB7Y29sb3I6ICM3MDg7fQotLmNtLXMtZGVmYXVsdCBzcGFuLmNtLWF0b20ge2NvbG9yOiAjMjE5O30KLS5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1udW1iZXIge2NvbG9yOiAjMTY0O30KLS5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1kZWYge2NvbG9yOiAjMDBmO30KLS5jbS1zLWRlZmF1bHQgc3Bhbi5jbS12YXJpYWJsZSB7Y29sb3I6IGJsYWNrO30KLS5jbS1zLWRlZmF1bHQgc3Bhbi5jbS12YXJpYWJsZS0yIHtjb2xvcjogIzA1YTt9Ci0uY20tcy1kZWZhdWx0IHNwYW4uY20tdmFyaWFibGUtMyB7Y29sb3I6ICMwODU7fQotLmNtLXMtZGVmYXVsdCBzcGFuLmNtLXByb3BlcnR5IHtjb2xvcjogYmxhY2s7fQotLmNtLXMtZGVmYXVsdCBzcGFuLmNtLW9wZXJhdG9yIHtjb2xvcjogYmxhY2s7fQotLmNtLXMtZGVmYXVsdCBzcGFuLmNtLWNvbW1lbnQge2NvbG9yOiAjYTUwO30KLS5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1zdHJpbmcge2NvbG9yOiAjYTExO30KLS5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1zdHJpbmctMiB7Y29sb3I6ICNmNTA7fQotLmNtLXMtZGVmYXVsdCBzcGFuLmNtLW1ldGEge2NvbG9yOiAjNTU1O30KLS5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1lcnJvciB7Y29sb3I6ICNmMDA7fQotLmNtLXMtZGVmYXVsdCBzcGFuLmNtLXF1YWxpZmllciB7Y29sb3I6ICM1NTU7fQotLmNtLXMtZGVmYXVsdCBzcGFuLmNtLWJ1aWx0aW4ge2NvbG9yOiAjMzBhO30KLS5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1icmFja2V0IHtjb2xvcjogI2NjNzt9Ci0uY20tcy1kZWZhdWx0IHNwYW4uY20tdGFnIHtjb2xvcjogIzE3MDt9Ci0uY20tcy1kZWZhdWx0IHNwYW4uY20tYXR0cmlidXRlIHtjb2xvcjogIzAwYzt9Ci0uY20tcy1kZWZhdWx0IHNwYW4uY20taGVhZGVyIHtjb2xvcjogI2EwYTt9Ci0uY20tcy1kZWZhdWx0IHNwYW4uY20tcXVvdGUge2NvbG9yOiAjMDkwO30KLS5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1ociB7Y29sb3I6ICM5OTk7fQotLmNtLXMtZGVmYXVsdCBzcGFuLmNtLWxpbmsge2NvbG9yOiAjMDBjO30KLQotc3Bhbi5jbS1oZWFkZXIsIHNwYW4uY20tc3Ryb25nIHtmb250LXdlaWdodDogYm9sZDt9Ci1zcGFuLmNtLWVtIHtmb250LXN0eWxlOiBpdGFsaWM7fQotc3Bhbi5jbS1lbXN0cm9uZyB7Zm9udC1zdHlsZTogaXRhbGljOyBmb250LXdlaWdodDogYm9sZDt9Ci1zcGFuLmNtLWxpbmsge3RleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO30KLQotZGl2LkNvZGVNaXJyb3Igc3Bhbi5Db2RlTWlycm9yLW1hdGNoaW5nYnJhY2tldCB7Y29sb3I6ICMwZjA7fQotZGl2LkNvZGVNaXJyb3Igc3Bhbi5Db2RlTWlycm9yLW5vbm1hdGNoaW5nYnJhY2tldCB7Y29sb3I6ICNmMjI7fQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9jb2RlbWlycm9yL2xpYi9jb2RlbWlycm9yLmpzIGIvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9jb2RlbWlycm9yL2xpYi9jb2RlbWlycm9yLmpzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1OWY4NDY1Li4wMDAwMDAwCi0tLSBhL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci9saWIvY29kZW1pcnJvci5qcworKysgL2Rldi9udWxsCkBAIC0xLDMwNDcgKzAsMCBAQAotLy8gQ29kZU1pcnJvciB2ZXJzaW9uIDIuMjQKLS8vCi0vLyBBbGwgZnVuY3Rpb25zIHRoYXQgbmVlZCBhY2Nlc3MgdG8gdGhlIGVkaXRvcidzIHN0YXRlIGxpdmUgaW5zaWRlCi0vLyB0aGUgQ29kZU1pcnJvciBmdW5jdGlvbi4gQmVsb3cgdGhhdCwgYXQgdGhlIGJvdHRvbSBvZiB0aGUgZmlsZSwKLS8vIHNvbWUgdXRpbGl0aWVzIGFyZSBkZWZpbmVkLgotCi0vLyBDb2RlTWlycm9yIGlzIHRoZSBvbmx5IGdsb2JhbCB2YXIgd2UgY2xhaW0KLXZhciBDb2RlTWlycm9yID0gKGZ1bmN0aW9uKCkgewotICAvLyBUaGlzIGlzIHRoZSBmdW5jdGlvbiB0aGF0IHByb2R1Y2VzIGFuIGVkaXRvciBpbnN0YW5jZS4gSXRzCi0gIC8vIGNsb3N1cmUgaXMgdXNlZCB0byBzdG9yZSB0aGUgZWRpdG9yIHN0YXRlLgotICBmdW5jdGlvbiBDb2RlTWlycm9yKHBsYWNlLCBnaXZlbk9wdGlvbnMpIHsKLSAgICAvLyBEZXRlcm1pbmUgZWZmZWN0aXZlIG9wdGlvbnMgYmFzZWQgb24gZ2l2ZW4gdmFsdWVzIGFuZCBkZWZhdWx0cy4KLSAgICB2YXIgb3B0aW9ucyA9IHt9LCBkZWZhdWx0cyA9IENvZGVNaXJyb3IuZGVmYXVsdHM7Ci0gICAgZm9yICh2YXIgb3B0IGluIGRlZmF1bHRzKQotICAgICAgaWYgKGRlZmF1bHRzLmhhc093blByb3BlcnR5KG9wdCkpCi0gICAgICAgIG9wdGlvbnNbb3B0XSA9IChnaXZlbk9wdGlvbnMgJiYgZ2l2ZW5PcHRpb25zLmhhc093blByb3BlcnR5KG9wdCkgPyBnaXZlbk9wdGlvbnMgOiBkZWZhdWx0cylbb3B0XTsKLQotICAgIC8vIFRoZSBlbGVtZW50IGluIHdoaWNoIHRoZSBlZGl0b3IgbGl2ZXMuCi0gICAgdmFyIHdyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKLSAgICB3cmFwcGVyLmNsYXNzTmFtZSA9ICJDb2RlTWlycm9yIiArIChvcHRpb25zLmxpbmVXcmFwcGluZyA/ICIgQ29kZU1pcnJvci13cmFwIiA6ICIiKTsKLSAgICAvLyBUaGlzIG1lc3MgY3JlYXRlcyB0aGUgYmFzZSBET00gc3RydWN0dXJlIGZvciB0aGUgZWRpdG9yLgotICAgIHdyYXBwZXIuaW5uZXJIVE1MID0KLSAgICAgICc8ZGl2IHN0eWxlPSJvdmVyZmxvdzogaGlkZGVuOyBwb3NpdGlvbjogcmVsYXRpdmU7IHdpZHRoOiAzcHg7IGhlaWdodDogMHB4OyI+JyArIC8vIFdyYXBzIGFuZCBoaWRlcyBpbnB1dCB0ZXh0YXJlYQotICAgICAgICAnPHRleHRhcmVhIHN0eWxlPSJwb3NpdGlvbjogYWJzb2x1dGU7IHBhZGRpbmc6IDA7IHdpZHRoOiAxcHg7IGhlaWdodDogMWVtIiB3cmFwPSJvZmYiICcgKwotICAgICAgICAgICdhdXRvY29ycmVjdD0ib2ZmIiBhdXRvY2FwaXRhbGl6ZT0ib2ZmIj48L3RleHRhcmVhPjwvZGl2PicgKwotICAgICAgJzxkaXYgY2xhc3M9IkNvZGVNaXJyb3Itc2Nyb2xsIiB0YWJpbmRleD0iLTEiPicgKwotICAgICAgICAnPGRpdiBzdHlsZT0icG9zaXRpb246IHJlbGF0aXZlIj4nICsgLy8gU2V0IHRvIHRoZSBoZWlnaHQgb2YgdGhlIHRleHQsIGNhdXNlcyBzY3JvbGxpbmcKLSAgICAgICAgICAnPGRpdiBzdHlsZT0icG9zaXRpb246IHJlbGF0aXZlIj4nICsgLy8gTW92ZWQgYXJvdW5kIGl0cyBwYXJlbnQgdG8gY292ZXIgdmlzaWJsZSB2aWV3Ci0gICAgICAgICAgICAnPGRpdiBjbGFzcz0iQ29kZU1pcnJvci1ndXR0ZXIiPjxkaXYgY2xhc3M9IkNvZGVNaXJyb3ItZ3V0dGVyLXRleHQiPjwvZGl2PjwvZGl2PicgKwotICAgICAgICAgICAgLy8gUHJvdmlkZXMgcG9zaXRpb25pbmcgcmVsYXRpdmUgdG8gKHZpc2libGUpIHRleHQgb3JpZ2luCi0gICAgICAgICAgICAnPGRpdiBjbGFzcz0iQ29kZU1pcnJvci1saW5lcyI+PGRpdiBzdHlsZT0icG9zaXRpb246IHJlbGF0aXZlOyB6LWluZGV4OiAwIj4nICsKLSAgICAgICAgICAgICAgJzxkaXYgc3R5bGU9InBvc2l0aW9uOiBhYnNvbHV0ZTsgd2lkdGg6IDEwMCU7IGhlaWdodDogMDsgb3ZlcmZsb3c6IGhpZGRlbjsgdmlzaWJpbGl0eTogaGlkZGVuOyI+PC9kaXY+JyArCi0gICAgICAgICAgICAgICc8cHJlIGNsYXNzPSJDb2RlTWlycm9yLWN1cnNvciI+JiMxNjA7PC9wcmU+JyArIC8vIEFic29sdXRlbHkgcG9zaXRpb25lZCBibGlua3kgY3Vyc29yCi0gICAgICAgICAgICAgICc8ZGl2IHN0eWxlPSJwb3NpdGlvbjogcmVsYXRpdmU7IHotaW5kZXg6IC0xIj48L2Rpdj48ZGl2PjwvZGl2PicgKyAvLyBESVZzIGNvbnRhaW5pbmcgdGhlIHNlbGVjdGlvbiBhbmQgdGhlIGFjdHVhbCBjb2RlCi0gICAgICAgICAgICAnPC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+JzsKLSAgICBpZiAocGxhY2UuYXBwZW5kQ2hpbGQpIHBsYWNlLmFwcGVuZENoaWxkKHdyYXBwZXIpOyBlbHNlIHBsYWNlKHdyYXBwZXIpOwotICAgIC8vIEkndmUgbmV2ZXIgc2VlbiBtb3JlIGVsZWdhbnQgY29kZSBpbiBteSBsaWZlLgotICAgIHZhciBpbnB1dERpdiA9IHdyYXBwZXIuZmlyc3RDaGlsZCwgaW5wdXQgPSBpbnB1dERpdi5maXJzdENoaWxkLAotICAgICAgICBzY3JvbGxlciA9IHdyYXBwZXIubGFzdENoaWxkLCBjb2RlID0gc2Nyb2xsZXIuZmlyc3RDaGlsZCwKLSAgICAgICAgbW92ZXIgPSBjb2RlLmZpcnN0Q2hpbGQsIGd1dHRlciA9IG1vdmVyLmZpcnN0Q2hpbGQsIGd1dHRlclRleHQgPSBndXR0ZXIuZmlyc3RDaGlsZCwKLSAgICAgICAgbGluZVNwYWNlID0gZ3V0dGVyLm5leHRTaWJsaW5nLmZpcnN0Q2hpbGQsIG1lYXN1cmUgPSBsaW5lU3BhY2UuZmlyc3RDaGlsZCwKLSAgICAgICAgY3Vyc29yID0gbWVhc3VyZS5uZXh0U2libGluZywgc2VsZWN0aW9uRGl2ID0gY3Vyc29yLm5leHRTaWJsaW5nLAotICAgICAgICBsaW5lRGl2ID0gc2VsZWN0aW9uRGl2Lm5leHRTaWJsaW5nOwotICAgIHRoZW1lQ2hhbmdlZCgpOwotICAgIC8vIE5lZWRlZCB0byBoaWRlIGJpZyBibHVlIGJsaW5raW5nIGN1cnNvciBvbiBNb2JpbGUgU2FmYXJpCi0gICAgaWYgKGlvcykgaW5wdXQuc3R5bGUud2lkdGggPSAiMHB4IjsKLSAgICBpZiAoIXdlYmtpdCkgbGluZVNwYWNlLmRyYWdnYWJsZSA9IHRydWU7Ci0gICAgbGluZVNwYWNlLnN0eWxlLm91dGxpbmUgPSAibm9uZSI7Ci0gICAgaWYgKG9wdGlvbnMudGFiaW5kZXggIT0gbnVsbCkgaW5wdXQudGFiSW5kZXggPSBvcHRpb25zLnRhYmluZGV4OwotICAgIGlmIChvcHRpb25zLmF1dG9mb2N1cykgZm9jdXNJbnB1dCgpOwotICAgIGlmICghb3B0aW9ucy5ndXR0ZXIgJiYgIW9wdGlvbnMubGluZU51bWJlcnMpIGd1dHRlci5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwotICAgIC8vIE5lZWRlZCB0byBoYW5kbGUgVGFiIGtleSBpbiBLSFRNTAotICAgIGlmIChraHRtbCkgaW5wdXREaXYuc3R5bGUuaGVpZ2h0ID0gIjFweCIsIGlucHV0RGl2LnN0eWxlLnBvc2l0aW9uID0gImFic29sdXRlIjsKLQotICAgIC8vIENoZWNrIGZvciBwcm9ibGVtIHdpdGggSUUgaW5uZXJIVE1MIG5vdCB3b3JraW5nIHdoZW4gd2UgaGF2ZSBhCi0gICAgLy8gUCAob3Igc2ltaWxhcikgcGFyZW50IG5vZGUuCi0gICAgdHJ5IHsgc3RyaW5nV2lkdGgoIngiKTsgfQotICAgIGNhdGNoIChlKSB7Ci0gICAgICBpZiAoZS5tZXNzYWdlLm1hdGNoKC9ydW50aW1lL2kpKQotICAgICAgICBlID0gbmV3IEVycm9yKCJBIENvZGVNaXJyb3IgaW5zaWRlIGEgUC1zdHlsZSBlbGVtZW50IGRvZXMgbm90IHdvcmsgaW4gSW50ZXJuZXQgRXhwbG9yZXIuIChpbm5lckhUTUwgYnVnKSIpOwotICAgICAgdGhyb3cgZTsKLSAgICB9Ci0KLSAgICAvLyBEZWxheWVkIG9iamVjdCB3cmFwIHRpbWVvdXRzLCBtYWtpbmcgc3VyZSBvbmx5IG9uZSBpcyBhY3RpdmUuIGJsaW5rZXIgaG9sZHMgYW4gaW50ZXJ2YWwuCi0gICAgdmFyIHBvbGwgPSBuZXcgRGVsYXllZCgpLCBoaWdobGlnaHQgPSBuZXcgRGVsYXllZCgpLCBibGlua2VyOwotCi0gICAgLy8gbW9kZSBob2xkcyBhIG1vZGUgQVBJIG9iamVjdC4gZG9jIGlzIHRoZSB0cmVlIG9mIExpbmUgb2JqZWN0cywKLSAgICAvLyB3b3JrIGFuIGFycmF5IG9mIGxpbmVzIHRoYXQgc2hvdWxkIGJlIHBhcnNlZCwgYW5kIGhpc3RvcnkgdGhlCi0gICAgLy8gdW5kbyBoaXN0b3J5IChpbnN0YW5jZSBvZiBIaXN0b3J5IGNvbnN0cnVjdG9yKS4KLSAgICB2YXIgbW9kZSwgZG9jID0gbmV3IEJyYW5jaENodW5rKFtuZXcgTGVhZkNodW5rKFtuZXcgTGluZSgiIildKV0pLCB3b3JrLCBmb2N1c2VkOwotICAgIGxvYWRNb2RlKCk7Ci0gICAgLy8gVGhlIHNlbGVjdGlvbi4gVGhlc2UgYXJlIGFsd2F5cyBtYWludGFpbmVkIHRvIHBvaW50IGF0IHZhbGlkCi0gICAgLy8gcG9zaXRpb25zLiBJbnZlcnRlZCBpcyB1c2VkIHRvIHJlbWVtYmVyIHRoYXQgdGhlIHVzZXIgaXMKLSAgICAvLyBzZWxlY3RpbmcgYm90dG9tLXRvLXRvcC4KLSAgICB2YXIgc2VsID0ge2Zyb206IHtsaW5lOiAwLCBjaDogMH0sIHRvOiB7bGluZTogMCwgY2g6IDB9LCBpbnZlcnRlZDogZmFsc2V9OwotICAgIC8vIFNlbGVjdGlvbi1yZWxhdGVkIGZsYWdzLiBzaGlmdFNlbGVjdGluZyBvYnZpb3VzbHkgdHJhY2tzCi0gICAgLy8gd2hldGhlciB0aGUgdXNlciBpcyBob2xkaW5nIHNoaWZ0LgotICAgIHZhciBzaGlmdFNlbGVjdGluZywgbGFzdENsaWNrLCBsYXN0RG91YmxlQ2xpY2ssIGxhc3RTY3JvbGxQb3MgPSAwLCBkcmFnZ2luZ1RleHQsCi0gICAgICAgIG92ZXJ3cml0ZSA9IGZhbHNlLCBzdXBwcmVzc0VkaXRzID0gZmFsc2U7Ci0gICAgLy8gVmFyaWFibGVzIHVzZWQgYnkgc3RhcnRPcGVyYXRpb24vZW5kT3BlcmF0aW9uIHRvIHRyYWNrIHdoYXQKLSAgICAvLyBoYXBwZW5lZCBkdXJpbmcgdGhlIG9wZXJhdGlvbi4KLSAgICB2YXIgdXBkYXRlSW5wdXQsIHVzZXJTZWxDaGFuZ2UsIGNoYW5nZXMsIHRleHRDaGFuZ2VkLCBzZWxlY3Rpb25DaGFuZ2VkLCBsZWF2ZUlucHV0QWxvbmUsCi0gICAgICAgIGd1dHRlckRpcnR5LCBjYWxsYmFja3M7Ci0gICAgLy8gQ3VycmVudCB2aXNpYmxlIHJhbmdlIChtYXkgYmUgYmlnZ2VyIHRoYW4gdGhlIHZpZXcgd2luZG93KS4KLSAgICB2YXIgZGlzcGxheU9mZnNldCA9IDAsIHNob3dpbmdGcm9tID0gMCwgc2hvd2luZ1RvID0gMCwgbGFzdFNpemVDID0gMDsKLSAgICAvLyBicmFja2V0SGlnaGxpZ2h0ZWQgaXMgdXNlZCB0byByZW1lbWJlciB0aGF0IGEgYnJhY2tldCBoYXMgYmVlbgotICAgIC8vIG1hcmtlZC4KLSAgICB2YXIgYnJhY2tldEhpZ2hsaWdodGVkOwotICAgIC8vIFRyYWNrcyB0aGUgbWF4aW11bSBsaW5lIGxlbmd0aCBzbyB0aGF0IHRoZSBob3Jpem9udGFsIHNjcm9sbGJhcgotICAgIC8vIGNhbiBiZSBrZXB0IHN0YXRpYyB3aGVuIHNjcm9sbGluZy4KLSAgICB2YXIgbWF4TGluZSA9ICIiLCBtYXhXaWR0aDsKLSAgICB2YXIgdGFiQ2FjaGUgPSB7fTsKLQotICAgIC8vIEluaXRpYWxpemUgdGhlIGNvbnRlbnQuCi0gICAgb3BlcmF0aW9uKGZ1bmN0aW9uKCl7c2V0VmFsdWUob3B0aW9ucy52YWx1ZSB8fCAiIik7IHVwZGF0ZUlucHV0ID0gZmFsc2U7fSkoKTsKLSAgICB2YXIgaGlzdG9yeSA9IG5ldyBIaXN0b3J5KCk7Ci0KLSAgICAvLyBSZWdpc3RlciBvdXIgZXZlbnQgaGFuZGxlcnMuCi0gICAgY29ubmVjdChzY3JvbGxlciwgIm1vdXNlZG93biIsIG9wZXJhdGlvbihvbk1vdXNlRG93bikpOwotICAgIGNvbm5lY3Qoc2Nyb2xsZXIsICJkYmxjbGljayIsIG9wZXJhdGlvbihvbkRvdWJsZUNsaWNrKSk7Ci0gICAgY29ubmVjdChsaW5lU3BhY2UsICJzZWxlY3RzdGFydCIsIGVfcHJldmVudERlZmF1bHQpOwotICAgIC8vIEdlY2tvIGJyb3dzZXJzIGZpcmUgY29udGV4dG1lbnUgKmFmdGVyKiBvcGVuaW5nIHRoZSBtZW51LCBhdAotICAgIC8vIHdoaWNoIHBvaW50IHdlIGNhbid0IG1lc3Mgd2l0aCBpdCBhbnltb3JlLiBDb250ZXh0IG1lbnUgaXMKLSAgICAvLyBoYW5kbGVkIGluIG9uTW91c2VEb3duIGZvciBHZWNrby4KLSAgICBpZiAoIWdlY2tvKSBjb25uZWN0KHNjcm9sbGVyLCAiY29udGV4dG1lbnUiLCBvbkNvbnRleHRNZW51KTsKLSAgICBjb25uZWN0KHNjcm9sbGVyLCAic2Nyb2xsIiwgZnVuY3Rpb24oKSB7Ci0gICAgICBsYXN0U2Nyb2xsUG9zID0gc2Nyb2xsZXIuc2Nyb2xsVG9wOwotICAgICAgdXBkYXRlRGlzcGxheShbXSk7Ci0gICAgICBpZiAob3B0aW9ucy5maXhlZEd1dHRlcikgZ3V0dGVyLnN0eWxlLmxlZnQgPSBzY3JvbGxlci5zY3JvbGxMZWZ0ICsgInB4IjsKLSAgICAgIGlmIChvcHRpb25zLm9uU2Nyb2xsKSBvcHRpb25zLm9uU2Nyb2xsKGluc3RhbmNlKTsKLSAgICB9KTsKLSAgICBjb25uZWN0KHdpbmRvdywgInJlc2l6ZSIsIGZ1bmN0aW9uKCkge3VwZGF0ZURpc3BsYXkodHJ1ZSk7fSk7Ci0gICAgY29ubmVjdChpbnB1dCwgImtleXVwIiwgb3BlcmF0aW9uKG9uS2V5VXApKTsKLSAgICBjb25uZWN0KGlucHV0LCAiaW5wdXQiLCBmYXN0UG9sbCk7Ci0gICAgY29ubmVjdChpbnB1dCwgImtleWRvd24iLCBvcGVyYXRpb24ob25LZXlEb3duKSk7Ci0gICAgY29ubmVjdChpbnB1dCwgImtleXByZXNzIiwgb3BlcmF0aW9uKG9uS2V5UHJlc3MpKTsKLSAgICBjb25uZWN0KGlucHV0LCAiZm9jdXMiLCBvbkZvY3VzKTsKLSAgICBjb25uZWN0KGlucHV0LCAiYmx1ciIsIG9uQmx1cik7Ci0KLSAgICBpZiAob3B0aW9ucy5kcmFnRHJvcCkgewotICAgICAgY29ubmVjdChsaW5lU3BhY2UsICJkcmFnc3RhcnQiLCBvbkRyYWdTdGFydCk7Ci0gICAgICBmdW5jdGlvbiBkcmFnXyhlKSB7Ci0gICAgICAgIGlmIChvcHRpb25zLm9uRHJhZ0V2ZW50ICYmIG9wdGlvbnMub25EcmFnRXZlbnQoaW5zdGFuY2UsIGFkZFN0b3AoZSkpKSByZXR1cm47Ci0gICAgICAgIGVfc3RvcChlKTsKLSAgICAgIH0KLSAgICAgIGNvbm5lY3Qoc2Nyb2xsZXIsICJkcmFnZW50ZXIiLCBkcmFnXyk7Ci0gICAgICBjb25uZWN0KHNjcm9sbGVyLCAiZHJhZ292ZXIiLCBkcmFnXyk7Ci0gICAgICBjb25uZWN0KHNjcm9sbGVyLCAiZHJvcCIsIG9wZXJhdGlvbihvbkRyb3ApKTsKLSAgICB9Ci0gICAgY29ubmVjdChzY3JvbGxlciwgInBhc3RlIiwgZnVuY3Rpb24oKXtmb2N1c0lucHV0KCk7IGZhc3RQb2xsKCk7fSk7Ci0gICAgY29ubmVjdChpbnB1dCwgInBhc3RlIiwgZmFzdFBvbGwpOwotICAgIGNvbm5lY3QoaW5wdXQsICJjdXQiLCBvcGVyYXRpb24oZnVuY3Rpb24oKXsKLSAgICAgIGlmICghb3B0aW9ucy5yZWFkT25seSkgcmVwbGFjZVNlbGVjdGlvbigiIik7Ci0gICAgfSkpOwotCi0gICAgLy8gTmVlZGVkIHRvIGhhbmRsZSBUYWIga2V5IGluIEtIVE1MCi0gICAgaWYgKGtodG1sKSBjb25uZWN0KGNvZGUsICJtb3VzZXVwIiwgZnVuY3Rpb24oKSB7Ci0gICAgICAgIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09IGlucHV0KSBpbnB1dC5ibHVyKCk7Ci0gICAgICAgIGZvY3VzSW5wdXQoKTsKLSAgICB9KTsKLQotICAgIC8vIElFIHRocm93cyB1bnNwZWNpZmllZCBlcnJvciBpbiBjZXJ0YWluIGNhc2VzLCB3aGVuCi0gICAgLy8gdHJ5aW5nIHRvIGFjY2VzcyBhY3RpdmVFbGVtZW50IGJlZm9yZSBvbmxvYWQKLSAgICB2YXIgaGFzRm9jdXM7IHRyeSB7IGhhc0ZvY3VzID0gKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT0gaW5wdXQpOyB9IGNhdGNoKGUpIHsgfQotICAgIGlmIChoYXNGb2N1cyB8fCBvcHRpb25zLmF1dG9mb2N1cykgc2V0VGltZW91dChvbkZvY3VzLCAyMCk7Ci0gICAgZWxzZSBvbkJsdXIoKTsKLQotICAgIGZ1bmN0aW9uIGlzTGluZShsKSB7cmV0dXJuIGwgPj0gMCAmJiBsIDwgZG9jLnNpemU7fQotICAgIC8vIFRoZSBpbnN0YW5jZSBvYmplY3QgdGhhdCB3ZSdsbCByZXR1cm4uIE1vc3RseSBjYWxscyBvdXQgdG8KLSAgICAvLyBsb2NhbCBmdW5jdGlvbnMgaW4gdGhlIENvZGVNaXJyb3IgZnVuY3Rpb24uIFNvbWUgZG8gc29tZSBleHRyYQotICAgIC8vIHJhbmdlIGNoZWNraW5nIGFuZC9vciBjbGlwcGluZy4gb3BlcmF0aW9uIGlzIHVzZWQgdG8gd3JhcCB0aGUKLSAgICAvLyBjYWxsIHNvIHRoYXQgY2hhbmdlcyBpdCBtYWtlcyBhcmUgdHJhY2tlZCwgYW5kIHRoZSBkaXNwbGF5IGlzCi0gICAgLy8gdXBkYXRlZCBhZnRlcndhcmRzLgotICAgIHZhciBpbnN0YW5jZSA9IHdyYXBwZXIuQ29kZU1pcnJvciA9IHsKLSAgICAgIGdldFZhbHVlOiBnZXRWYWx1ZSwKLSAgICAgIHNldFZhbHVlOiBvcGVyYXRpb24oc2V0VmFsdWUpLAotICAgICAgZ2V0U2VsZWN0aW9uOiBnZXRTZWxlY3Rpb24sCi0gICAgICByZXBsYWNlU2VsZWN0aW9uOiBvcGVyYXRpb24ocmVwbGFjZVNlbGVjdGlvbiksCi0gICAgICBmb2N1czogZnVuY3Rpb24oKXt3aW5kb3cuZm9jdXMoKTsgZm9jdXNJbnB1dCgpOyBvbkZvY3VzKCk7IGZhc3RQb2xsKCk7fSwKLSAgICAgIHNldE9wdGlvbjogZnVuY3Rpb24ob3B0aW9uLCB2YWx1ZSkgewotICAgICAgICB2YXIgb2xkVmFsID0gb3B0aW9uc1tvcHRpb25dOwotICAgICAgICBvcHRpb25zW29wdGlvbl0gPSB2YWx1ZTsKLSAgICAgICAgaWYgKG9wdGlvbiA9PSAibW9kZSIgfHwgb3B0aW9uID09ICJpbmRlbnRVbml0IikgbG9hZE1vZGUoKTsKLSAgICAgICAgZWxzZSBpZiAob3B0aW9uID09ICJyZWFkT25seSIgJiYgdmFsdWUgPT0gIm5vY3Vyc29yIikge29uQmx1cigpOyBpbnB1dC5ibHVyKCk7fQotICAgICAgICBlbHNlIGlmIChvcHRpb24gPT0gInJlYWRPbmx5IiAmJiAhdmFsdWUpIHtyZXNldElucHV0KHRydWUpO30KLSAgICAgICAgZWxzZSBpZiAob3B0aW9uID09ICJ0aGVtZSIpIHRoZW1lQ2hhbmdlZCgpOwotICAgICAgICBlbHNlIGlmIChvcHRpb24gPT0gImxpbmVXcmFwcGluZyIgJiYgb2xkVmFsICE9IHZhbHVlKSBvcGVyYXRpb24od3JhcHBpbmdDaGFuZ2VkKSgpOwotICAgICAgICBlbHNlIGlmIChvcHRpb24gPT0gInRhYlNpemUiKSB1cGRhdGVEaXNwbGF5KHRydWUpOwotICAgICAgICBpZiAob3B0aW9uID09ICJsaW5lTnVtYmVycyIgfHwgb3B0aW9uID09ICJndXR0ZXIiIHx8IG9wdGlvbiA9PSAiZmlyc3RMaW5lTnVtYmVyIiB8fCBvcHRpb24gPT0gInRoZW1lIikgewotICAgICAgICAgIGd1dHRlckNoYW5nZWQoKTsKLSAgICAgICAgICB1cGRhdGVEaXNwbGF5KHRydWUpOwotICAgICAgICB9Ci0gICAgICB9LAotICAgICAgZ2V0T3B0aW9uOiBmdW5jdGlvbihvcHRpb24pIHtyZXR1cm4gb3B0aW9uc1tvcHRpb25dO30sCi0gICAgICB1bmRvOiBvcGVyYXRpb24odW5kbyksCi0gICAgICByZWRvOiBvcGVyYXRpb24ocmVkbyksCi0gICAgICBpbmRlbnRMaW5lOiBvcGVyYXRpb24oZnVuY3Rpb24obiwgZGlyKSB7Ci0gICAgICAgIGlmICh0eXBlb2YgZGlyICE9ICJzdHJpbmciKSB7Ci0gICAgICAgICAgaWYgKGRpciA9PSBudWxsKSBkaXIgPSBvcHRpb25zLnNtYXJ0SW5kZW50ID8gInNtYXJ0IiA6ICJwcmV2IjsKLSAgICAgICAgICBlbHNlIGRpciA9IGRpciA/ICJhZGQiIDogInN1YnRyYWN0IjsKLSAgICAgICAgfQotICAgICAgICBpZiAoaXNMaW5lKG4pKSBpbmRlbnRMaW5lKG4sIGRpcik7Ci0gICAgICB9KSwKLSAgICAgIGluZGVudFNlbGVjdGlvbjogb3BlcmF0aW9uKGluZGVudFNlbGVjdGVkKSwKLSAgICAgIGhpc3RvcnlTaXplOiBmdW5jdGlvbigpIHtyZXR1cm4ge3VuZG86IGhpc3RvcnkuZG9uZS5sZW5ndGgsIHJlZG86IGhpc3RvcnkudW5kb25lLmxlbmd0aH07fSwKLSAgICAgIGNsZWFySGlzdG9yeTogZnVuY3Rpb24oKSB7aGlzdG9yeSA9IG5ldyBIaXN0b3J5KCk7fSwKLSAgICAgIG1hdGNoQnJhY2tldHM6IG9wZXJhdGlvbihmdW5jdGlvbigpe21hdGNoQnJhY2tldHModHJ1ZSk7fSksCi0gICAgICBnZXRUb2tlbkF0OiBvcGVyYXRpb24oZnVuY3Rpb24ocG9zKSB7Ci0gICAgICAgIHBvcyA9IGNsaXBQb3MocG9zKTsKLSAgICAgICAgcmV0dXJuIGdldExpbmUocG9zLmxpbmUpLmdldFRva2VuQXQobW9kZSwgZ2V0U3RhdGVCZWZvcmUocG9zLmxpbmUpLCBwb3MuY2gpOwotICAgICAgfSksCi0gICAgICBnZXRTdGF0ZUFmdGVyOiBmdW5jdGlvbihsaW5lKSB7Ci0gICAgICAgIGxpbmUgPSBjbGlwTGluZShsaW5lID09IG51bGwgPyBkb2Muc2l6ZSAtIDE6IGxpbmUpOwotICAgICAgICByZXR1cm4gZ2V0U3RhdGVCZWZvcmUobGluZSArIDEpOwotICAgICAgfSwKLSAgICAgIGN1cnNvckNvb3JkczogZnVuY3Rpb24oc3RhcnQsIG1vZGUpIHsKLSAgICAgICAgaWYgKHN0YXJ0ID09IG51bGwpIHN0YXJ0ID0gc2VsLmludmVydGVkOwotICAgICAgICByZXR1cm4gdGhpcy5jaGFyQ29vcmRzKHN0YXJ0ID8gc2VsLmZyb20gOiBzZWwudG8sIG1vZGUpOwotICAgICAgfSwKLSAgICAgIGNoYXJDb29yZHM6IGZ1bmN0aW9uKHBvcywgbW9kZSkgewotICAgICAgICBwb3MgPSBjbGlwUG9zKHBvcyk7Ci0gICAgICAgIGlmIChtb2RlID09ICJsb2NhbCIpIHJldHVybiBsb2NhbENvb3Jkcyhwb3MsIGZhbHNlKTsKLSAgICAgICAgaWYgKG1vZGUgPT0gImRpdiIpIHJldHVybiBsb2NhbENvb3Jkcyhwb3MsIHRydWUpOwotICAgICAgICByZXR1cm4gcGFnZUNvb3Jkcyhwb3MpOwotICAgICAgfSwKLSAgICAgIGNvb3Jkc0NoYXI6IGZ1bmN0aW9uKGNvb3JkcykgewotICAgICAgICB2YXIgb2ZmID0gZWx0T2Zmc2V0KGxpbmVTcGFjZSk7Ci0gICAgICAgIHJldHVybiBjb29yZHNDaGFyKGNvb3Jkcy54IC0gb2ZmLmxlZnQsIGNvb3Jkcy55IC0gb2ZmLnRvcCk7Ci0gICAgICB9LAotICAgICAgbWFya1RleHQ6IG9wZXJhdGlvbihtYXJrVGV4dCksCi0gICAgICBzZXRCb29rbWFyazogc2V0Qm9va21hcmssCi0gICAgICBmaW5kTWFya3NBdDogZmluZE1hcmtzQXQsCi0gICAgICBzZXRNYXJrZXI6IG9wZXJhdGlvbihhZGRHdXR0ZXJNYXJrZXIpLAotICAgICAgY2xlYXJNYXJrZXI6IG9wZXJhdGlvbihyZW1vdmVHdXR0ZXJNYXJrZXIpLAotICAgICAgc2V0TGluZUNsYXNzOiBvcGVyYXRpb24oc2V0TGluZUNsYXNzKSwKLSAgICAgIGhpZGVMaW5lOiBvcGVyYXRpb24oZnVuY3Rpb24oaCkge3JldHVybiBzZXRMaW5lSGlkZGVuKGgsIHRydWUpO30pLAotICAgICAgc2hvd0xpbmU6IG9wZXJhdGlvbihmdW5jdGlvbihoKSB7cmV0dXJuIHNldExpbmVIaWRkZW4oaCwgZmFsc2UpO30pLAotICAgICAgb25EZWxldGVMaW5lOiBmdW5jdGlvbihsaW5lLCBmKSB7Ci0gICAgICAgIGlmICh0eXBlb2YgbGluZSA9PSAibnVtYmVyIikgewotICAgICAgICAgIGlmICghaXNMaW5lKGxpbmUpKSByZXR1cm4gbnVsbDsKLSAgICAgICAgICBsaW5lID0gZ2V0TGluZShsaW5lKTsKLSAgICAgICAgfQotICAgICAgICAobGluZS5oYW5kbGVycyB8fCAobGluZS5oYW5kbGVycyA9IFtdKSkucHVzaChmKTsKLSAgICAgICAgcmV0dXJuIGxpbmU7Ci0gICAgICB9LAotICAgICAgbGluZUluZm86IGxpbmVJbmZvLAotICAgICAgYWRkV2lkZ2V0OiBmdW5jdGlvbihwb3MsIG5vZGUsIHNjcm9sbCwgdmVydCwgaG9yaXopIHsKLSAgICAgICAgcG9zID0gbG9jYWxDb29yZHMoY2xpcFBvcyhwb3MpKTsKLSAgICAgICAgdmFyIHRvcCA9IHBvcy55Qm90LCBsZWZ0ID0gcG9zLng7Ci0gICAgICAgIG5vZGUuc3R5bGUucG9zaXRpb24gPSAiYWJzb2x1dGUiOwotICAgICAgICBjb2RlLmFwcGVuZENoaWxkKG5vZGUpOwotICAgICAgICBpZiAodmVydCA9PSAib3ZlciIpIHRvcCA9IHBvcy55OwotICAgICAgICBlbHNlIGlmICh2ZXJ0ID09ICJuZWFyIikgewotICAgICAgICAgIHZhciB2c3BhY2UgPSBNYXRoLm1heChzY3JvbGxlci5vZmZzZXRIZWlnaHQsIGRvYy5oZWlnaHQgKiB0ZXh0SGVpZ2h0KCkpLAotICAgICAgICAgICAgICBoc3BhY2UgPSBNYXRoLm1heChjb2RlLmNsaWVudFdpZHRoLCBsaW5lU3BhY2UuY2xpZW50V2lkdGgpIC0gcGFkZGluZ0xlZnQoKTsKLSAgICAgICAgICBpZiAocG9zLnlCb3QgKyBub2RlLm9mZnNldEhlaWdodCA+IHZzcGFjZSAmJiBwb3MueSA+IG5vZGUub2Zmc2V0SGVpZ2h0KQotICAgICAgICAgICAgdG9wID0gcG9zLnkgLSBub2RlLm9mZnNldEhlaWdodDsKLSAgICAgICAgICBpZiAobGVmdCArIG5vZGUub2Zmc2V0V2lkdGggPiBoc3BhY2UpCi0gICAgICAgICAgICBsZWZ0ID0gaHNwYWNlIC0gbm9kZS5vZmZzZXRXaWR0aDsKLSAgICAgICAgfQotICAgICAgICBub2RlLnN0eWxlLnRvcCA9ICh0b3AgKyBwYWRkaW5nVG9wKCkpICsgInB4IjsKLSAgICAgICAgbm9kZS5zdHlsZS5sZWZ0ID0gbm9kZS5zdHlsZS5yaWdodCA9ICIiOwotICAgICAgICBpZiAoaG9yaXogPT0gInJpZ2h0IikgewotICAgICAgICAgIGxlZnQgPSBjb2RlLmNsaWVudFdpZHRoIC0gbm9kZS5vZmZzZXRXaWR0aDsKLSAgICAgICAgICBub2RlLnN0eWxlLnJpZ2h0ID0gIjBweCI7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgaWYgKGhvcml6ID09ICJsZWZ0IikgbGVmdCA9IDA7Ci0gICAgICAgICAgZWxzZSBpZiAoaG9yaXogPT0gIm1pZGRsZSIpIGxlZnQgPSAoY29kZS5jbGllbnRXaWR0aCAtIG5vZGUub2Zmc2V0V2lkdGgpIC8gMjsKLSAgICAgICAgICBub2RlLnN0eWxlLmxlZnQgPSAobGVmdCArIHBhZGRpbmdMZWZ0KCkpICsgInB4IjsKLSAgICAgICAgfQotICAgICAgICBpZiAoc2Nyb2xsKQotICAgICAgICAgIHNjcm9sbEludG9WaWV3KGxlZnQsIHRvcCwgbGVmdCArIG5vZGUub2Zmc2V0V2lkdGgsIHRvcCArIG5vZGUub2Zmc2V0SGVpZ2h0KTsKLSAgICAgIH0sCi0KLSAgICAgIGxpbmVDb3VudDogZnVuY3Rpb24oKSB7cmV0dXJuIGRvYy5zaXplO30sCi0gICAgICBjbGlwUG9zOiBjbGlwUG9zLAotICAgICAgZ2V0Q3Vyc29yOiBmdW5jdGlvbihzdGFydCkgewotICAgICAgICBpZiAoc3RhcnQgPT0gbnVsbCkgc3RhcnQgPSBzZWwuaW52ZXJ0ZWQ7Ci0gICAgICAgIHJldHVybiBjb3B5UG9zKHN0YXJ0ID8gc2VsLmZyb20gOiBzZWwudG8pOwotICAgICAgfSwKLSAgICAgIHNvbWV0aGluZ1NlbGVjdGVkOiBmdW5jdGlvbigpIHtyZXR1cm4gIXBvc0VxKHNlbC5mcm9tLCBzZWwudG8pO30sCi0gICAgICBzZXRDdXJzb3I6IG9wZXJhdGlvbihmdW5jdGlvbihsaW5lLCBjaCwgdXNlcikgewotICAgICAgICBpZiAoY2ggPT0gbnVsbCAmJiB0eXBlb2YgbGluZS5saW5lID09ICJudW1iZXIiKSBzZXRDdXJzb3IobGluZS5saW5lLCBsaW5lLmNoLCB1c2VyKTsKLSAgICAgICAgZWxzZSBzZXRDdXJzb3IobGluZSwgY2gsIHVzZXIpOwotICAgICAgfSksCi0gICAgICBzZXRTZWxlY3Rpb246IG9wZXJhdGlvbihmdW5jdGlvbihmcm9tLCB0bywgdXNlcikgewotICAgICAgICAodXNlciA/IHNldFNlbGVjdGlvblVzZXIgOiBzZXRTZWxlY3Rpb24pKGNsaXBQb3MoZnJvbSksIGNsaXBQb3ModG8gfHwgZnJvbSkpOwotICAgICAgfSksCi0gICAgICBnZXRMaW5lOiBmdW5jdGlvbihsaW5lKSB7aWYgKGlzTGluZShsaW5lKSkgcmV0dXJuIGdldExpbmUobGluZSkudGV4dDt9LAotICAgICAgZ2V0TGluZUhhbmRsZTogZnVuY3Rpb24obGluZSkge2lmIChpc0xpbmUobGluZSkpIHJldHVybiBnZXRMaW5lKGxpbmUpO30sCi0gICAgICBzZXRMaW5lOiBvcGVyYXRpb24oZnVuY3Rpb24obGluZSwgdGV4dCkgewotICAgICAgICBpZiAoaXNMaW5lKGxpbmUpKSByZXBsYWNlUmFuZ2UodGV4dCwge2xpbmU6IGxpbmUsIGNoOiAwfSwge2xpbmU6IGxpbmUsIGNoOiBnZXRMaW5lKGxpbmUpLnRleHQubGVuZ3RofSk7Ci0gICAgICB9KSwKLSAgICAgIHJlbW92ZUxpbmU6IG9wZXJhdGlvbihmdW5jdGlvbihsaW5lKSB7Ci0gICAgICAgIGlmIChpc0xpbmUobGluZSkpIHJlcGxhY2VSYW5nZSgiIiwge2xpbmU6IGxpbmUsIGNoOiAwfSwgY2xpcFBvcyh7bGluZTogbGluZSsxLCBjaDogMH0pKTsKLSAgICAgIH0pLAotICAgICAgcmVwbGFjZVJhbmdlOiBvcGVyYXRpb24ocmVwbGFjZVJhbmdlKSwKLSAgICAgIGdldFJhbmdlOiBmdW5jdGlvbihmcm9tLCB0bykge3JldHVybiBnZXRSYW5nZShjbGlwUG9zKGZyb20pLCBjbGlwUG9zKHRvKSk7fSwKLQotICAgICAgdHJpZ2dlck9uS2V5RG93bjogb3BlcmF0aW9uKG9uS2V5RG93biksCi0gICAgICBleGVjQ29tbWFuZDogZnVuY3Rpb24oY21kKSB7cmV0dXJuIGNvbW1hbmRzW2NtZF0oaW5zdGFuY2UpO30sCi0gICAgICAvLyBTdHVmZiB1c2VkIGJ5IGNvbW1hbmRzLCBwcm9iYWJseSBub3QgbXVjaCB1c2UgdG8gb3V0c2lkZSBjb2RlLgotICAgICAgbW92ZUg6IG9wZXJhdGlvbihtb3ZlSCksCi0gICAgICBkZWxldGVIOiBvcGVyYXRpb24oZGVsZXRlSCksCi0gICAgICBtb3ZlVjogb3BlcmF0aW9uKG1vdmVWKSwKLSAgICAgIHRvZ2dsZU92ZXJ3cml0ZTogZnVuY3Rpb24oKSB7Ci0gICAgICAgIGlmKG92ZXJ3cml0ZSl7Ci0gICAgICAgICAgb3ZlcndyaXRlID0gZmFsc2U7Ci0gICAgICAgICAgY3Vyc29yLmNsYXNzTmFtZSA9IGN1cnNvci5jbGFzc05hbWUucmVwbGFjZSgiIENvZGVNaXJyb3Itb3ZlcndyaXRlIiwgIiIpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgIG92ZXJ3cml0ZSA9IHRydWU7Ci0gICAgICAgICAgY3Vyc29yLmNsYXNzTmFtZSArPSAiIENvZGVNaXJyb3Itb3ZlcndyaXRlIjsKLSAgICAgICAgfQotICAgICAgfSwKLQotICAgICAgcG9zRnJvbUluZGV4OiBmdW5jdGlvbihvZmYpIHsKLSAgICAgICAgdmFyIGxpbmVObyA9IDAsIGNoOwotICAgICAgICBkb2MuaXRlcigwLCBkb2Muc2l6ZSwgZnVuY3Rpb24obGluZSkgewotICAgICAgICAgIHZhciBzeiA9IGxpbmUudGV4dC5sZW5ndGggKyAxOwotICAgICAgICAgIGlmIChzeiA+IG9mZikgeyBjaCA9IG9mZjsgcmV0dXJuIHRydWU7IH0KLSAgICAgICAgICBvZmYgLT0gc3o7Ci0gICAgICAgICAgKytsaW5lTm87Ci0gICAgICAgIH0pOwotICAgICAgICByZXR1cm4gY2xpcFBvcyh7bGluZTogbGluZU5vLCBjaDogY2h9KTsKLSAgICAgIH0sCi0gICAgICBpbmRleEZyb21Qb3M6IGZ1bmN0aW9uIChjb29yZHMpIHsKLSAgICAgICAgaWYgKGNvb3Jkcy5saW5lIDwgMCB8fCBjb29yZHMuY2ggPCAwKSByZXR1cm4gMDsKLSAgICAgICAgdmFyIGluZGV4ID0gY29vcmRzLmNoOwotICAgICAgICBkb2MuaXRlcigwLCBjb29yZHMubGluZSwgZnVuY3Rpb24gKGxpbmUpIHsKLSAgICAgICAgICBpbmRleCArPSBsaW5lLnRleHQubGVuZ3RoICsgMTsKLSAgICAgICAgfSk7Ci0gICAgICAgIHJldHVybiBpbmRleDsKLSAgICAgIH0sCi0gICAgICBzY3JvbGxUbzogZnVuY3Rpb24oeCwgeSkgewotICAgICAgICBpZiAoeCAhPSBudWxsKSBzY3JvbGxlci5zY3JvbGxMZWZ0ID0geDsKLSAgICAgICAgaWYgKHkgIT0gbnVsbCkgc2Nyb2xsZXIuc2Nyb2xsVG9wID0geTsKLSAgICAgICAgdXBkYXRlRGlzcGxheShbXSk7Ci0gICAgICB9LAotCi0gICAgICBvcGVyYXRpb246IGZ1bmN0aW9uKGYpe3JldHVybiBvcGVyYXRpb24oZikoKTt9LAotICAgICAgY29tcG91bmRDaGFuZ2U6IGZ1bmN0aW9uKGYpe3JldHVybiBjb21wb3VuZENoYW5nZShmKTt9LAotICAgICAgcmVmcmVzaDogZnVuY3Rpb24oKXsKLSAgICAgICAgdXBkYXRlRGlzcGxheSh0cnVlKTsKLSAgICAgICAgaWYgKHNjcm9sbGVyLnNjcm9sbEhlaWdodCA+IGxhc3RTY3JvbGxQb3MpCi0gICAgICAgICAgc2Nyb2xsZXIuc2Nyb2xsVG9wID0gbGFzdFNjcm9sbFBvczsKLSAgICAgIH0sCi0gICAgICBnZXRJbnB1dEZpZWxkOiBmdW5jdGlvbigpe3JldHVybiBpbnB1dDt9LAotICAgICAgZ2V0V3JhcHBlckVsZW1lbnQ6IGZ1bmN0aW9uKCl7cmV0dXJuIHdyYXBwZXI7fSwKLSAgICAgIGdldFNjcm9sbGVyRWxlbWVudDogZnVuY3Rpb24oKXtyZXR1cm4gc2Nyb2xsZXI7fSwKLSAgICAgIGdldEd1dHRlckVsZW1lbnQ6IGZ1bmN0aW9uKCl7cmV0dXJuIGd1dHRlcjt9Ci0gICAgfTsKLQotICAgIGZ1bmN0aW9uIGdldExpbmUobikgeyByZXR1cm4gZ2V0TGluZUF0KGRvYywgbik7IH0KLSAgICBmdW5jdGlvbiB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIGhlaWdodCkgewotICAgICAgZ3V0dGVyRGlydHkgPSB0cnVlOwotICAgICAgdmFyIGRpZmYgPSBoZWlnaHQgLSBsaW5lLmhlaWdodDsKLSAgICAgIGZvciAodmFyIG4gPSBsaW5lOyBuOyBuID0gbi5wYXJlbnQpIG4uaGVpZ2h0ICs9IGRpZmY7Ci0gICAgfQotCi0gICAgZnVuY3Rpb24gc2V0VmFsdWUoY29kZSkgewotICAgICAgdmFyIHRvcCA9IHtsaW5lOiAwLCBjaDogMH07Ci0gICAgICB1cGRhdGVMaW5lcyh0b3AsIHtsaW5lOiBkb2Muc2l6ZSAtIDEsIGNoOiBnZXRMaW5lKGRvYy5zaXplLTEpLnRleHQubGVuZ3RofSwKLSAgICAgICAgICAgICAgICAgIHNwbGl0TGluZXMoY29kZSksIHRvcCwgdG9wKTsKLSAgICAgIHVwZGF0ZUlucHV0ID0gdHJ1ZTsKLSAgICB9Ci0gICAgZnVuY3Rpb24gZ2V0VmFsdWUoKSB7Ci0gICAgICB2YXIgdGV4dCA9IFtdOwotICAgICAgZG9jLml0ZXIoMCwgZG9jLnNpemUsIGZ1bmN0aW9uKGxpbmUpIHsgdGV4dC5wdXNoKGxpbmUudGV4dCk7IH0pOwotICAgICAgcmV0dXJuIHRleHQuam9pbigiXG4iKTsKLSAgICB9Ci0KLSAgICBmdW5jdGlvbiBvbk1vdXNlRG93bihlKSB7Ci0gICAgICBzZXRTaGlmdChlX3Byb3AoZSwgInNoaWZ0S2V5IikpOwotICAgICAgLy8gQ2hlY2sgd2hldGhlciB0aGlzIGlzIGEgY2xpY2sgaW4gYSB3aWRnZXQKLSAgICAgIGZvciAodmFyIG4gPSBlX3RhcmdldChlKTsgbiAhPSB3cmFwcGVyOyBuID0gbi5wYXJlbnROb2RlKQotICAgICAgICBpZiAobi5wYXJlbnROb2RlID09IGNvZGUgJiYgbiAhPSBtb3ZlcikgcmV0dXJuOwotCi0gICAgICAvLyBTZWUgaWYgdGhpcyBpcyBhIGNsaWNrIGluIHRoZSBndXR0ZXIKLSAgICAgIGZvciAodmFyIG4gPSBlX3RhcmdldChlKTsgbiAhPSB3cmFwcGVyOyBuID0gbi5wYXJlbnROb2RlKQotICAgICAgICBpZiAobi5wYXJlbnROb2RlID09IGd1dHRlclRleHQpIHsKLSAgICAgICAgICBpZiAob3B0aW9ucy5vbkd1dHRlckNsaWNrKQotICAgICAgICAgICAgb3B0aW9ucy5vbkd1dHRlckNsaWNrKGluc3RhbmNlLCBpbmRleE9mKGd1dHRlclRleHQuY2hpbGROb2RlcywgbikgKyBzaG93aW5nRnJvbSwgZSk7Ci0gICAgICAgICAgcmV0dXJuIGVfcHJldmVudERlZmF1bHQoZSk7Ci0gICAgICAgIH0KLQotICAgICAgdmFyIHN0YXJ0ID0gcG9zRnJvbU1vdXNlKGUpOwotCi0gICAgICBzd2l0Y2ggKGVfYnV0dG9uKGUpKSB7Ci0gICAgICBjYXNlIDM6Ci0gICAgICAgIGlmIChnZWNrbyAmJiAhbWFjKSBvbkNvbnRleHRNZW51KGUpOwotICAgICAgICByZXR1cm47Ci0gICAgICBjYXNlIDI6Ci0gICAgICAgIGlmIChzdGFydCkgc2V0Q3Vyc29yKHN0YXJ0LmxpbmUsIHN0YXJ0LmNoLCB0cnVlKTsKLSAgICAgICAgcmV0dXJuOwotICAgICAgfQotICAgICAgLy8gRm9yIGJ1dHRvbiAxLCBpZiBpdCB3YXMgY2xpY2tlZCBpbnNpZGUgdGhlIGVkaXRvcgotICAgICAgLy8gKHBvc0Zyb21Nb3VzZSByZXR1cm5pbmcgbm9uLW51bGwpLCB3ZSBoYXZlIHRvIGFkanVzdCB0aGUKLSAgICAgIC8vIHNlbGVjdGlvbi4KLSAgICAgIGlmICghc3RhcnQpIHtpZiAoZV90YXJnZXQoZSkgPT0gc2Nyb2xsZXIpIGVfcHJldmVudERlZmF1bHQoZSk7IHJldHVybjt9Ci0KLSAgICAgIGlmICghZm9jdXNlZCkgb25Gb2N1cygpOwotCi0gICAgICB2YXIgbm93ID0gK25ldyBEYXRlOwotICAgICAgaWYgKGxhc3REb3VibGVDbGljayAmJiBsYXN0RG91YmxlQ2xpY2sudGltZSA+IG5vdyAtIDQwMCAmJiBwb3NFcShsYXN0RG91YmxlQ2xpY2sucG9zLCBzdGFydCkpIHsKLSAgICAgICAgZV9wcmV2ZW50RGVmYXVsdChlKTsKLSAgICAgICAgc2V0VGltZW91dChmb2N1c0lucHV0LCAyMCk7Ci0gICAgICAgIHJldHVybiBzZWxlY3RMaW5lKHN0YXJ0LmxpbmUpOwotICAgICAgfSBlbHNlIGlmIChsYXN0Q2xpY2sgJiYgbGFzdENsaWNrLnRpbWUgPiBub3cgLSA0MDAgJiYgcG9zRXEobGFzdENsaWNrLnBvcywgc3RhcnQpKSB7Ci0gICAgICAgIGxhc3REb3VibGVDbGljayA9IHt0aW1lOiBub3csIHBvczogc3RhcnR9OwotICAgICAgICBlX3ByZXZlbnREZWZhdWx0KGUpOwotICAgICAgICByZXR1cm4gc2VsZWN0V29yZEF0KHN0YXJ0KTsKLSAgICAgIH0gZWxzZSB7IGxhc3RDbGljayA9IHt0aW1lOiBub3csIHBvczogc3RhcnR9OyB9Ci0KLSAgICAgIHZhciBsYXN0ID0gc3RhcnQsIGdvaW5nOwotICAgICAgaWYgKG9wdGlvbnMuZHJhZ0Ryb3AgJiYgZHJhZ0FuZERyb3AgJiYgIW9wdGlvbnMucmVhZE9ubHkgJiYgIXBvc0VxKHNlbC5mcm9tLCBzZWwudG8pICYmCi0gICAgICAgICAgIXBvc0xlc3Moc3RhcnQsIHNlbC5mcm9tKSAmJiAhcG9zTGVzcyhzZWwudG8sIHN0YXJ0KSkgewotICAgICAgICAvLyBMZXQgdGhlIGRyYWcgaGFuZGxlciBoYW5kbGUgdGhpcy4KLSAgICAgICAgaWYgKHdlYmtpdCkgbGluZVNwYWNlLmRyYWdnYWJsZSA9IHRydWU7Ci0gICAgICAgIGZ1bmN0aW9uIGRyYWdFbmQoZTIpIHsKLSAgICAgICAgICBpZiAod2Via2l0KSBsaW5lU3BhY2UuZHJhZ2dhYmxlID0gZmFsc2U7Ci0gICAgICAgICAgZHJhZ2dpbmdUZXh0ID0gZmFsc2U7Ci0gICAgICAgICAgdXAoKTsgZHJvcCgpOwotICAgICAgICAgIGlmIChNYXRoLmFicyhlLmNsaWVudFggLSBlMi5jbGllbnRYKSArIE1hdGguYWJzKGUuY2xpZW50WSAtIGUyLmNsaWVudFkpIDwgMTApIHsKLSAgICAgICAgICAgIGVfcHJldmVudERlZmF1bHQoZTIpOwotICAgICAgICAgICAgc2V0Q3Vyc29yKHN0YXJ0LmxpbmUsIHN0YXJ0LmNoLCB0cnVlKTsKLSAgICAgICAgICAgIGZvY3VzSW5wdXQoKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgdmFyIHVwID0gY29ubmVjdChkb2N1bWVudCwgIm1vdXNldXAiLCBvcGVyYXRpb24oZHJhZ0VuZCksIHRydWUpOwotICAgICAgICB2YXIgZHJvcCA9IGNvbm5lY3Qoc2Nyb2xsZXIsICJkcm9wIiwgb3BlcmF0aW9uKGRyYWdFbmQpLCB0cnVlKTsKLSAgICAgICAgZHJhZ2dpbmdUZXh0ID0gdHJ1ZTsKLSAgICAgICAgLy8gSUUncyBhcHByb2FjaCB0byBkcmFnZ2FibGUKLSAgICAgICAgaWYgKGxpbmVTcGFjZS5kcmFnRHJvcCkgbGluZVNwYWNlLmRyYWdEcm9wKCk7Ci0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLSAgICAgIGVfcHJldmVudERlZmF1bHQoZSk7Ci0gICAgICBzZXRDdXJzb3Ioc3RhcnQubGluZSwgc3RhcnQuY2gsIHRydWUpOwotCi0gICAgICBmdW5jdGlvbiBleHRlbmQoZSkgewotICAgICAgICB2YXIgY3VyID0gcG9zRnJvbU1vdXNlKGUsIHRydWUpOwotICAgICAgICBpZiAoY3VyICYmICFwb3NFcShjdXIsIGxhc3QpKSB7Ci0gICAgICAgICAgaWYgKCFmb2N1c2VkKSBvbkZvY3VzKCk7Ci0gICAgICAgICAgbGFzdCA9IGN1cjsKLSAgICAgICAgICBzZXRTZWxlY3Rpb25Vc2VyKHN0YXJ0LCBjdXIpOwotICAgICAgICAgIHVwZGF0ZUlucHV0ID0gZmFsc2U7Ci0gICAgICAgICAgdmFyIHZpc2libGUgPSB2aXNpYmxlTGluZXMoKTsKLSAgICAgICAgICBpZiAoY3VyLmxpbmUgPj0gdmlzaWJsZS50byB8fCBjdXIubGluZSA8IHZpc2libGUuZnJvbSkKLSAgICAgICAgICAgIGdvaW5nID0gc2V0VGltZW91dChvcGVyYXRpb24oZnVuY3Rpb24oKXtleHRlbmQoZSk7fSksIDE1MCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgZnVuY3Rpb24gZG9uZShlKSB7Ci0gICAgICAgIGNsZWFyVGltZW91dChnb2luZyk7Ci0gICAgICAgIHZhciBjdXIgPSBwb3NGcm9tTW91c2UoZSk7Ci0gICAgICAgIGlmIChjdXIpIHNldFNlbGVjdGlvblVzZXIoc3RhcnQsIGN1cik7Ci0gICAgICAgIGVfcHJldmVudERlZmF1bHQoZSk7Ci0gICAgICAgIGZvY3VzSW5wdXQoKTsKLSAgICAgICAgdXBkYXRlSW5wdXQgPSB0cnVlOwotICAgICAgICBtb3ZlKCk7IHVwKCk7Ci0gICAgICB9Ci0gICAgICB2YXIgbW92ZSA9IGNvbm5lY3QoZG9jdW1lbnQsICJtb3VzZW1vdmUiLCBvcGVyYXRpb24oZnVuY3Rpb24oZSkgewotICAgICAgICBjbGVhclRpbWVvdXQoZ29pbmcpOwotICAgICAgICBlX3ByZXZlbnREZWZhdWx0KGUpOwotICAgICAgICBpZiAoIWllICYmICFlX2J1dHRvbihlKSkgZG9uZShlKTsKLSAgICAgICAgZWxzZSBleHRlbmQoZSk7Ci0gICAgICB9KSwgdHJ1ZSk7Ci0gICAgICB2YXIgdXAgPSBjb25uZWN0KGRvY3VtZW50LCAibW91c2V1cCIsIG9wZXJhdGlvbihkb25lKSwgdHJ1ZSk7Ci0gICAgfQotICAgIGZ1bmN0aW9uIG9uRG91YmxlQ2xpY2soZSkgewotICAgICAgZm9yICh2YXIgbiA9IGVfdGFyZ2V0KGUpOyBuICE9IHdyYXBwZXI7IG4gPSBuLnBhcmVudE5vZGUpCi0gICAgICAgIGlmIChuLnBhcmVudE5vZGUgPT0gZ3V0dGVyVGV4dCkgcmV0dXJuIGVfcHJldmVudERlZmF1bHQoZSk7Ci0gICAgICB2YXIgc3RhcnQgPSBwb3NGcm9tTW91c2UoZSk7Ci0gICAgICBpZiAoIXN0YXJ0KSByZXR1cm47Ci0gICAgICBsYXN0RG91YmxlQ2xpY2sgPSB7dGltZTogK25ldyBEYXRlLCBwb3M6IHN0YXJ0fTsKLSAgICAgIGVfcHJldmVudERlZmF1bHQoZSk7Ci0gICAgICBzZWxlY3RXb3JkQXQoc3RhcnQpOwotICAgIH0KLSAgICBmdW5jdGlvbiBvbkRyb3AoZSkgewotICAgICAgaWYgKG9wdGlvbnMub25EcmFnRXZlbnQgJiYgb3B0aW9ucy5vbkRyYWdFdmVudChpbnN0YW5jZSwgYWRkU3RvcChlKSkpIHJldHVybjsKLSAgICAgIGUucHJldmVudERlZmF1bHQoKTsKLSAgICAgIHZhciBwb3MgPSBwb3NGcm9tTW91c2UoZSwgdHJ1ZSksIGZpbGVzID0gZS5kYXRhVHJhbnNmZXIuZmlsZXM7Ci0gICAgICBpZiAoIXBvcyB8fCBvcHRpb25zLnJlYWRPbmx5KSByZXR1cm47Ci0gICAgICBpZiAoZmlsZXMgJiYgZmlsZXMubGVuZ3RoICYmIHdpbmRvdy5GaWxlUmVhZGVyICYmIHdpbmRvdy5GaWxlKSB7Ci0gICAgICAgIGZ1bmN0aW9uIGxvYWRGaWxlKGZpbGUsIGkpIHsKLSAgICAgICAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXI7Ci0gICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKCkgewotICAgICAgICAgICAgdGV4dFtpXSA9IHJlYWRlci5yZXN1bHQ7Ci0gICAgICAgICAgICBpZiAoKytyZWFkID09IG4pIHsKLSAgICAgICAgICAgICAgcG9zID0gY2xpcFBvcyhwb3MpOwotICAgICAgICAgICAgICBvcGVyYXRpb24oZnVuY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgdmFyIGVuZCA9IHJlcGxhY2VSYW5nZSh0ZXh0LmpvaW4oIiIpLCBwb3MsIHBvcyk7Ci0gICAgICAgICAgICAgICAgc2V0U2VsZWN0aW9uVXNlcihwb3MsIGVuZCk7Ci0gICAgICAgICAgICAgIH0pKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfTsKLSAgICAgICAgICByZWFkZXIucmVhZEFzVGV4dChmaWxlKTsKLSAgICAgICAgfQotICAgICAgICB2YXIgbiA9IGZpbGVzLmxlbmd0aCwgdGV4dCA9IEFycmF5KG4pLCByZWFkID0gMDsKLSAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyArK2kpIGxvYWRGaWxlKGZpbGVzW2ldLCBpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgewotICAgICAgICB0cnkgewotICAgICAgICAgIHZhciB0ZXh0ID0gZS5kYXRhVHJhbnNmZXIuZ2V0RGF0YSgiVGV4dCIpOwotICAgICAgICAgIGlmICh0ZXh0KSB7Ci0gICAgICAgICAgICBjb21wb3VuZENoYW5nZShmdW5jdGlvbigpIHsKLSAgICAgICAgICAgICAgdmFyIGN1ckZyb20gPSBzZWwuZnJvbSwgY3VyVG8gPSBzZWwudG87Ci0gICAgICAgICAgICAgIHNldFNlbGVjdGlvblVzZXIocG9zLCBwb3MpOwotICAgICAgICAgICAgICBpZiAoZHJhZ2dpbmdUZXh0KSByZXBsYWNlUmFuZ2UoIiIsIGN1ckZyb20sIGN1clRvKTsKLSAgICAgICAgICAgICAgcmVwbGFjZVNlbGVjdGlvbih0ZXh0KTsKLSAgICAgICAgICAgICAgZm9jdXNJbnB1dCgpOwotICAgICAgICAgICAgfSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoKGUpe30KLSAgICAgIH0KLSAgICB9Ci0gICAgZnVuY3Rpb24gb25EcmFnU3RhcnQoZSkgewotICAgICAgdmFyIHR4dCA9IGdldFNlbGVjdGlvbigpOwotICAgICAgZS5kYXRhVHJhbnNmZXIuc2V0RGF0YSgiVGV4dCIsIHR4dCk7Ci0gICAgICAKLSAgICAgIC8vIFVzZSBkdW1teSBpbWFnZSBpbnN0ZWFkIG9mIGRlZmF1bHQgYnJvd3NlcnMgaW1hZ2UuCi0gICAgICBpZiAoZ2Vja28gfHwgY2hyb21lKSB7Ci0gICAgICAgIHZhciBpbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTsKLSAgICAgICAgaW1nLnNjciA9ICdkYXRhOmltYWdlL2dpZjtiYXNlNjQsUjBsR09EZGhBZ0FDQUlBQUFBQUFBUC8vL3l3QUFBQUFBZ0FDQUFBQ0FvUlJBRHM9JzsgLy8xeDEgaW1hZ2UKLSAgICAgICAgZS5kYXRhVHJhbnNmZXIuc2V0RHJhZ0ltYWdlKGltZywgMCwgMCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgZnVuY3Rpb24gZG9IYW5kbGVCaW5kaW5nKGJvdW5kLCBkcm9wU2hpZnQpIHsKLSAgICAgIGlmICh0eXBlb2YgYm91bmQgPT0gInN0cmluZyIpIHsKLSAgICAgICAgYm91bmQgPSBjb21tYW5kc1tib3VuZF07Ci0gICAgICAgIGlmICghYm91bmQpIHJldHVybiBmYWxzZTsKLSAgICAgIH0KLSAgICAgIHZhciBwcmV2U2hpZnQgPSBzaGlmdFNlbGVjdGluZzsKLSAgICAgIHRyeSB7Ci0gICAgICAgIGlmIChvcHRpb25zLnJlYWRPbmx5KSBzdXBwcmVzc0VkaXRzID0gdHJ1ZTsKLSAgICAgICAgaWYgKGRyb3BTaGlmdCkgc2hpZnRTZWxlY3RpbmcgPSBudWxsOwotICAgICAgICBib3VuZChpbnN0YW5jZSk7Ci0gICAgICB9IGNhdGNoKGUpIHsKLSAgICAgICAgaWYgKGUgIT0gUGFzcykgdGhyb3cgZTsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgfSBmaW5hbGx5IHsKLSAgICAgICAgc2hpZnRTZWxlY3RpbmcgPSBwcmV2U2hpZnQ7Ci0gICAgICAgIHN1cHByZXNzRWRpdHMgPSBmYWxzZTsKLSAgICAgIH0KLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLSAgICBmdW5jdGlvbiBoYW5kbGVLZXlCaW5kaW5nKGUpIHsKLSAgICAgIC8vIEhhbmRsZSBhdXRvIGtleW1hcCB0cmFuc2l0aW9ucwotICAgICAgdmFyIHN0YXJ0TWFwID0gZ2V0S2V5TWFwKG9wdGlvbnMua2V5TWFwKSwgbmV4dCA9IHN0YXJ0TWFwLmF1dG87Ci0gICAgICBjbGVhclRpbWVvdXQobWF5YmVUcmFuc2l0aW9uKTsKLSAgICAgIGlmIChuZXh0ICYmICFpc01vZGlmaWVyS2V5KGUpKSBtYXliZVRyYW5zaXRpb24gPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewotICAgICAgICBpZiAoZ2V0S2V5TWFwKG9wdGlvbnMua2V5TWFwKSA9PSBzdGFydE1hcCkgewotICAgICAgICAgIG9wdGlvbnMua2V5TWFwID0gKG5leHQuY2FsbCA/IG5leHQuY2FsbChudWxsLCBpbnN0YW5jZSkgOiBuZXh0KTsKLSAgICAgICAgfQotICAgICAgfSwgNTApOwotCi0gICAgICB2YXIgbmFtZSA9IGtleU5hbWVzW2VfcHJvcChlLCAia2V5Q29kZSIpXSwgaGFuZGxlZCA9IGZhbHNlOwotICAgICAgaWYgKG5hbWUgPT0gbnVsbCB8fCBlLmFsdEdyYXBoS2V5KSByZXR1cm4gZmFsc2U7Ci0gICAgICBpZiAoZV9wcm9wKGUsICJhbHRLZXkiKSkgbmFtZSA9ICJBbHQtIiArIG5hbWU7Ci0gICAgICBpZiAoZV9wcm9wKGUsICJjdHJsS2V5IikpIG5hbWUgPSAiQ3RybC0iICsgbmFtZTsKLSAgICAgIGlmIChlX3Byb3AoZSwgIm1ldGFLZXkiKSkgbmFtZSA9ICJDbWQtIiArIG5hbWU7Ci0KLSAgICAgIHZhciBzdG9wcGVkID0gZmFsc2U7Ci0gICAgICBmdW5jdGlvbiBzdG9wKCkgeyBzdG9wcGVkID0gdHJ1ZTsgfQotCi0gICAgICBpZiAoZV9wcm9wKGUsICJzaGlmdEtleSIpKSB7Ci0gICAgICAgIGhhbmRsZWQgPSBsb29rdXBLZXkoIlNoaWZ0LSIgKyBuYW1lLCBvcHRpb25zLmV4dHJhS2V5cywgb3B0aW9ucy5rZXlNYXAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oYikge3JldHVybiBkb0hhbmRsZUJpbmRpbmcoYiwgdHJ1ZSk7fSwgc3RvcCkKLSAgICAgICAgICAgICAgIHx8IGxvb2t1cEtleShuYW1lLCBvcHRpb25zLmV4dHJhS2V5cywgb3B0aW9ucy5rZXlNYXAsIGZ1bmN0aW9uKGIpIHsKLSAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBiID09ICJzdHJpbmciICYmIC9eZ29bQS1aXS8udGVzdChiKSkgcmV0dXJuIGRvSGFuZGxlQmluZGluZyhiKTsKLSAgICAgICAgICAgICAgIH0sIHN0b3ApOwotICAgICAgfSBlbHNlIHsKLSAgICAgICAgaGFuZGxlZCA9IGxvb2t1cEtleShuYW1lLCBvcHRpb25zLmV4dHJhS2V5cywgb3B0aW9ucy5rZXlNYXAsIGRvSGFuZGxlQmluZGluZywgc3RvcCk7Ci0gICAgICB9Ci0gICAgICBpZiAoc3RvcHBlZCkgaGFuZGxlZCA9IGZhbHNlOwotICAgICAgaWYgKGhhbmRsZWQpIHsKLSAgICAgICAgZV9wcmV2ZW50RGVmYXVsdChlKTsKLSAgICAgICAgaWYgKGllKSB7IGUub2xkS2V5Q29kZSA9IGUua2V5Q29kZTsgZS5rZXlDb2RlID0gMDsgfQotICAgICAgfQotICAgICAgcmV0dXJuIGhhbmRsZWQ7Ci0gICAgfQotICAgIGZ1bmN0aW9uIGhhbmRsZUNoYXJCaW5kaW5nKGUsIGNoKSB7Ci0gICAgICB2YXIgaGFuZGxlZCA9IGxvb2t1cEtleSgiJyIgKyBjaCArICInIiwgb3B0aW9ucy5leHRyYUtleXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmtleU1hcCwgZnVuY3Rpb24oYikgeyByZXR1cm4gZG9IYW5kbGVCaW5kaW5nKGIsIHRydWUpOyB9KTsKLSAgICAgIGlmIChoYW5kbGVkKSBlX3ByZXZlbnREZWZhdWx0KGUpOwotICAgICAgcmV0dXJuIGhhbmRsZWQ7Ci0gICAgfQotCi0gICAgdmFyIGxhc3RTdG9wcGVkS2V5ID0gbnVsbCwgbWF5YmVUcmFuc2l0aW9uOwotICAgIGZ1bmN0aW9uIG9uS2V5RG93bihlKSB7Ci0gICAgICBpZiAoIWZvY3VzZWQpIG9uRm9jdXMoKTsKLSAgICAgIGlmIChpZSAmJiBlLmtleUNvZGUgPT0gMjcpIHsgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlOyB9Ci0gICAgICBpZiAocG9sbGluZ0Zhc3QpIHsgaWYgKHJlYWRJbnB1dCgpKSBwb2xsaW5nRmFzdCA9IGZhbHNlOyB9Ci0gICAgICBpZiAob3B0aW9ucy5vbktleUV2ZW50ICYmIG9wdGlvbnMub25LZXlFdmVudChpbnN0YW5jZSwgYWRkU3RvcChlKSkpIHJldHVybjsKLSAgICAgIHZhciBjb2RlID0gZV9wcm9wKGUsICJrZXlDb2RlIik7Ci0gICAgICAvLyBJRSBkb2VzIHN0cmFuZ2UgdGhpbmdzIHdpdGggZXNjYXBlLgotICAgICAgc2V0U2hpZnQoY29kZSA9PSAxNiB8fCBlX3Byb3AoZSwgInNoaWZ0S2V5IikpOwotICAgICAgLy8gRmlyc3QgZ2l2ZSBvbktleUV2ZW50IG9wdGlvbiBhIGNoYW5jZSB0byBoYW5kbGUgdGhpcy4KLSAgICAgIHZhciBoYW5kbGVkID0gaGFuZGxlS2V5QmluZGluZyhlKTsKLSAgICAgIGlmICh3aW5kb3cub3BlcmEpIHsKLSAgICAgICAgbGFzdFN0b3BwZWRLZXkgPSBoYW5kbGVkID8gY29kZSA6IG51bGw7Ci0gICAgICAgIC8vIE9wZXJhIGhhcyBubyBjdXQgZXZlbnQuLi4gd2UgdHJ5IHRvIGF0IGxlYXN0IGNhdGNoIHRoZSBrZXkgY29tYm8KLSAgICAgICAgaWYgKCFoYW5kbGVkICYmIGNvZGUgPT0gODggJiYgZV9wcm9wKGUsIG1hYyA/ICJtZXRhS2V5IiA6ICJjdHJsS2V5IikpCi0gICAgICAgICAgcmVwbGFjZVNlbGVjdGlvbigiIik7Ci0gICAgICB9Ci0gICAgfQotICAgIGZ1bmN0aW9uIG9uS2V5UHJlc3MoZSkgewotICAgICAgaWYgKHBvbGxpbmdGYXN0KSByZWFkSW5wdXQoKTsKLSAgICAgIGlmIChvcHRpb25zLm9uS2V5RXZlbnQgJiYgb3B0aW9ucy5vbktleUV2ZW50KGluc3RhbmNlLCBhZGRTdG9wKGUpKSkgcmV0dXJuOwotICAgICAgdmFyIGtleUNvZGUgPSBlX3Byb3AoZSwgImtleUNvZGUiKSwgY2hhckNvZGUgPSBlX3Byb3AoZSwgImNoYXJDb2RlIik7Ci0gICAgICBpZiAod2luZG93Lm9wZXJhICYmIGtleUNvZGUgPT0gbGFzdFN0b3BwZWRLZXkpIHtsYXN0U3RvcHBlZEtleSA9IG51bGw7IGVfcHJldmVudERlZmF1bHQoZSk7IHJldHVybjt9Ci0gICAgICBpZiAoKCh3aW5kb3cub3BlcmEgJiYgIWUud2hpY2gpIHx8IGtodG1sKSAmJiBoYW5kbGVLZXlCaW5kaW5nKGUpKSByZXR1cm47Ci0gICAgICB2YXIgY2ggPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNoYXJDb2RlID09IG51bGwgPyBrZXlDb2RlIDogY2hhckNvZGUpOwotICAgICAgaWYgKG9wdGlvbnMuZWxlY3RyaWNDaGFycyAmJiBtb2RlLmVsZWN0cmljQ2hhcnMgJiYgb3B0aW9ucy5zbWFydEluZGVudCAmJiAhb3B0aW9ucy5yZWFkT25seSkgewotICAgICAgICBpZiAobW9kZS5lbGVjdHJpY0NoYXJzLmluZGV4T2YoY2gpID4gLTEpCi0gICAgICAgICAgc2V0VGltZW91dChvcGVyYXRpb24oZnVuY3Rpb24oKSB7aW5kZW50TGluZShzZWwudG8ubGluZSwgInNtYXJ0Iik7fSksIDc1KTsKLSAgICAgIH0KLSAgICAgIGlmIChoYW5kbGVDaGFyQmluZGluZyhlLCBjaCkpIHJldHVybjsKLSAgICAgIGZhc3RQb2xsKCk7Ci0gICAgfQotICAgIGZ1bmN0aW9uIG9uS2V5VXAoZSkgewotICAgICAgaWYgKG9wdGlvbnMub25LZXlFdmVudCAmJiBvcHRpb25zLm9uS2V5RXZlbnQoaW5zdGFuY2UsIGFkZFN0b3AoZSkpKSByZXR1cm47Ci0gICAgICBpZiAoZV9wcm9wKGUsICJrZXlDb2RlIikgPT0gMTYpIHNoaWZ0U2VsZWN0aW5nID0gbnVsbDsKLSAgICB9Ci0KLSAgICBmdW5jdGlvbiBvbkZvY3VzKCkgewotICAgICAgaWYgKG9wdGlvbnMucmVhZE9ubHkgPT0gIm5vY3Vyc29yIikgcmV0dXJuOwotICAgICAgaWYgKCFmb2N1c2VkKSB7Ci0gICAgICAgIGlmIChvcHRpb25zLm9uRm9jdXMpIG9wdGlvbnMub25Gb2N1cyhpbnN0YW5jZSk7Ci0gICAgICAgIGZvY3VzZWQgPSB0cnVlOwotICAgICAgICBpZiAod3JhcHBlci5jbGFzc05hbWUuc2VhcmNoKC9cYkNvZGVNaXJyb3ItZm9jdXNlZFxiLykgPT0gLTEpCi0gICAgICAgICAgd3JhcHBlci5jbGFzc05hbWUgKz0gIiBDb2RlTWlycm9yLWZvY3VzZWQiOwotICAgICAgICBpZiAoIWxlYXZlSW5wdXRBbG9uZSkgcmVzZXRJbnB1dCh0cnVlKTsKLSAgICAgIH0KLSAgICAgIHNsb3dQb2xsKCk7Ci0gICAgICByZXN0YXJ0QmxpbmsoKTsKLSAgICB9Ci0gICAgZnVuY3Rpb24gb25CbHVyKCkgewotICAgICAgaWYgKGZvY3VzZWQpIHsKLSAgICAgICAgaWYgKG9wdGlvbnMub25CbHVyKSBvcHRpb25zLm9uQmx1cihpbnN0YW5jZSk7Ci0gICAgICAgIGZvY3VzZWQgPSBmYWxzZTsKLSAgICAgICAgaWYgKGJyYWNrZXRIaWdobGlnaHRlZCkKLSAgICAgICAgICBvcGVyYXRpb24oZnVuY3Rpb24oKXsKLSAgICAgICAgICAgIGlmIChicmFja2V0SGlnaGxpZ2h0ZWQpIHsgYnJhY2tldEhpZ2hsaWdodGVkKCk7IGJyYWNrZXRIaWdobGlnaHRlZCA9IG51bGw7IH0KLSAgICAgICAgICB9KSgpOwotICAgICAgICB3cmFwcGVyLmNsYXNzTmFtZSA9IHdyYXBwZXIuY2xhc3NOYW1lLnJlcGxhY2UoIiBDb2RlTWlycm9yLWZvY3VzZWQiLCAiIik7Ci0gICAgICB9Ci0gICAgICBjbGVhckludGVydmFsKGJsaW5rZXIpOwotICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtpZiAoIWZvY3VzZWQpIHNoaWZ0U2VsZWN0aW5nID0gbnVsbDt9LCAxNTApOwotICAgIH0KLQotICAgIC8vIFJlcGxhY2UgdGhlIHJhbmdlIGZyb20gZnJvbSB0byB0byBieSB0aGUgc3RyaW5ncyBpbiBuZXdUZXh0LgotICAgIC8vIEFmdGVyd2FyZHMsIHNldCB0aGUgc2VsZWN0aW9uIHRvIHNlbEZyb20sIHNlbFRvLgotICAgIGZ1bmN0aW9uIHVwZGF0ZUxpbmVzKGZyb20sIHRvLCBuZXdUZXh0LCBzZWxGcm9tLCBzZWxUbykgewotICAgICAgaWYgKHN1cHByZXNzRWRpdHMpIHJldHVybjsKLSAgICAgIGlmIChoaXN0b3J5KSB7Ci0gICAgICAgIHZhciBvbGQgPSBbXTsKLSAgICAgICAgZG9jLml0ZXIoZnJvbS5saW5lLCB0by5saW5lICsgMSwgZnVuY3Rpb24obGluZSkgeyBvbGQucHVzaChsaW5lLnRleHQpOyB9KTsKLSAgICAgICAgaGlzdG9yeS5hZGRDaGFuZ2UoZnJvbS5saW5lLCBuZXdUZXh0Lmxlbmd0aCwgb2xkKTsKLSAgICAgICAgd2hpbGUgKGhpc3RvcnkuZG9uZS5sZW5ndGggPiBvcHRpb25zLnVuZG9EZXB0aCkgaGlzdG9yeS5kb25lLnNoaWZ0KCk7Ci0gICAgICB9Ci0gICAgICB1cGRhdGVMaW5lc05vVW5kbyhmcm9tLCB0bywgbmV3VGV4dCwgc2VsRnJvbSwgc2VsVG8pOwotICAgIH0KLSAgICBmdW5jdGlvbiB1bnJlZG9IZWxwZXIoZnJvbSwgdG8pIHsKLSAgICAgIGlmICghZnJvbS5sZW5ndGgpIHJldHVybjsKLSAgICAgIHZhciBzZXQgPSBmcm9tLnBvcCgpLCBvdXQgPSBbXTsKLSAgICAgIGZvciAodmFyIGkgPSBzZXQubGVuZ3RoIC0gMTsgaSA+PSAwOyBpIC09IDEpIHsKLSAgICAgICAgdmFyIGNoYW5nZSA9IHNldFtpXTsKLSAgICAgICAgdmFyIHJlcGxhY2VkID0gW10sIGVuZCA9IGNoYW5nZS5zdGFydCArIGNoYW5nZS5hZGRlZDsKLSAgICAgICAgZG9jLml0ZXIoY2hhbmdlLnN0YXJ0LCBlbmQsIGZ1bmN0aW9uKGxpbmUpIHsgcmVwbGFjZWQucHVzaChsaW5lLnRleHQpOyB9KTsKLSAgICAgICAgb3V0LnB1c2goe3N0YXJ0OiBjaGFuZ2Uuc3RhcnQsIGFkZGVkOiBjaGFuZ2Uub2xkLmxlbmd0aCwgb2xkOiByZXBsYWNlZH0pOwotICAgICAgICB2YXIgcG9zID0gY2xpcFBvcyh7bGluZTogY2hhbmdlLnN0YXJ0ICsgY2hhbmdlLm9sZC5sZW5ndGggLSAxLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgY2g6IGVkaXRFbmQocmVwbGFjZWRbcmVwbGFjZWQubGVuZ3RoLTFdLCBjaGFuZ2Uub2xkW2NoYW5nZS5vbGQubGVuZ3RoLTFdKX0pOwotICAgICAgICB1cGRhdGVMaW5lc05vVW5kbyh7bGluZTogY2hhbmdlLnN0YXJ0LCBjaDogMH0sIHtsaW5lOiBlbmQgLSAxLCBjaDogZ2V0TGluZShlbmQtMSkudGV4dC5sZW5ndGh9LCBjaGFuZ2Uub2xkLCBwb3MsIHBvcyk7Ci0gICAgICB9Ci0gICAgICB1cGRhdGVJbnB1dCA9IHRydWU7Ci0gICAgICB0by5wdXNoKG91dCk7Ci0gICAgfQotICAgIGZ1bmN0aW9uIHVuZG8oKSB7dW5yZWRvSGVscGVyKGhpc3RvcnkuZG9uZSwgaGlzdG9yeS51bmRvbmUpO30KLSAgICBmdW5jdGlvbiByZWRvKCkge3VucmVkb0hlbHBlcihoaXN0b3J5LnVuZG9uZSwgaGlzdG9yeS5kb25lKTt9Ci0KLSAgICBmdW5jdGlvbiB1cGRhdGVMaW5lc05vVW5kbyhmcm9tLCB0bywgbmV3VGV4dCwgc2VsRnJvbSwgc2VsVG8pIHsKLSAgICAgIGlmIChzdXBwcmVzc0VkaXRzKSByZXR1cm47Ci0gICAgICB2YXIgcmVjb21wdXRlTWF4TGVuZ3RoID0gZmFsc2UsIG1heExpbmVMZW5ndGggPSBtYXhMaW5lLmxlbmd0aDsKLSAgICAgIGlmICghb3B0aW9ucy5saW5lV3JhcHBpbmcpCi0gICAgICAgIGRvYy5pdGVyKGZyb20ubGluZSwgdG8ubGluZSArIDEsIGZ1bmN0aW9uKGxpbmUpIHsKLSAgICAgICAgICBpZiAobGluZS50ZXh0Lmxlbmd0aCA9PSBtYXhMaW5lTGVuZ3RoKSB7cmVjb21wdXRlTWF4TGVuZ3RoID0gdHJ1ZTsgcmV0dXJuIHRydWU7fQotICAgICAgICB9KTsKLSAgICAgIGlmIChmcm9tLmxpbmUgIT0gdG8ubGluZSB8fCBuZXdUZXh0Lmxlbmd0aCA+IDEpIGd1dHRlckRpcnR5ID0gdHJ1ZTsKLQotICAgICAgdmFyIG5saW5lcyA9IHRvLmxpbmUgLSBmcm9tLmxpbmUsIGZpcnN0TGluZSA9IGdldExpbmUoZnJvbS5saW5lKSwgbGFzdExpbmUgPSBnZXRMaW5lKHRvLmxpbmUpOwotICAgICAgLy8gRmlyc3QgYWRqdXN0IHRoZSBsaW5lIHN0cnVjdHVyZSwgdGFraW5nIHNvbWUgY2FyZSB0byBsZWF2ZSBoaWdobGlnaHRpbmcgaW50YWN0LgotICAgICAgaWYgKGZyb20uY2ggPT0gMCAmJiB0by5jaCA9PSAwICYmIG5ld1RleHRbbmV3VGV4dC5sZW5ndGggLSAxXSA9PSAiIikgewotICAgICAgICAvLyBUaGlzIGlzIGEgd2hvbGUtbGluZSByZXBsYWNlLiBUcmVhdGVkIHNwZWNpYWxseSB0byBtYWtlCi0gICAgICAgIC8vIHN1cmUgbGluZSBvYmplY3RzIG1vdmUgdGhlIHdheSB0aGV5IGFyZSBzdXBwb3NlZCB0by4KLSAgICAgICAgdmFyIGFkZGVkID0gW10sIHByZXZMaW5lID0gbnVsbDsKLSAgICAgICAgaWYgKGZyb20ubGluZSkgewotICAgICAgICAgIHByZXZMaW5lID0gZ2V0TGluZShmcm9tLmxpbmUgLSAxKTsKLSAgICAgICAgICBwcmV2TGluZS5maXhNYXJrRW5kcyhsYXN0TGluZSk7Ci0gICAgICAgIH0gZWxzZSBsYXN0TGluZS5maXhNYXJrU3RhcnRzKCk7Ci0gICAgICAgIGZvciAodmFyIGkgPSAwLCBlID0gbmV3VGV4dC5sZW5ndGggLSAxOyBpIDwgZTsgKytpKQotICAgICAgICAgIGFkZGVkLnB1c2goTGluZS5pbmhlcml0TWFya3MobmV3VGV4dFtpXSwgcHJldkxpbmUpKTsKLSAgICAgICAgaWYgKG5saW5lcykgZG9jLnJlbW92ZShmcm9tLmxpbmUsIG5saW5lcywgY2FsbGJhY2tzKTsKLSAgICAgICAgaWYgKGFkZGVkLmxlbmd0aCkgZG9jLmluc2VydChmcm9tLmxpbmUsIGFkZGVkKTsKLSAgICAgIH0gZWxzZSBpZiAoZmlyc3RMaW5lID09IGxhc3RMaW5lKSB7Ci0gICAgICAgIGlmIChuZXdUZXh0Lmxlbmd0aCA9PSAxKQotICAgICAgICAgIGZpcnN0TGluZS5yZXBsYWNlKGZyb20uY2gsIHRvLmNoLCBuZXdUZXh0WzBdKTsKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgbGFzdExpbmUgPSBmaXJzdExpbmUuc3BsaXQodG8uY2gsIG5ld1RleHRbbmV3VGV4dC5sZW5ndGgtMV0pOwotICAgICAgICAgIGZpcnN0TGluZS5yZXBsYWNlKGZyb20uY2gsIG51bGwsIG5ld1RleHRbMF0pOwotICAgICAgICAgIGZpcnN0TGluZS5maXhNYXJrRW5kcyhsYXN0TGluZSk7Ci0gICAgICAgICAgdmFyIGFkZGVkID0gW107Ci0gICAgICAgICAgZm9yICh2YXIgaSA9IDEsIGUgPSBuZXdUZXh0Lmxlbmd0aCAtIDE7IGkgPCBlOyArK2kpCi0gICAgICAgICAgICBhZGRlZC5wdXNoKExpbmUuaW5oZXJpdE1hcmtzKG5ld1RleHRbaV0sIGZpcnN0TGluZSkpOwotICAgICAgICAgIGFkZGVkLnB1c2gobGFzdExpbmUpOwotICAgICAgICAgIGRvYy5pbnNlcnQoZnJvbS5saW5lICsgMSwgYWRkZWQpOwotICAgICAgICB9Ci0gICAgICB9IGVsc2UgaWYgKG5ld1RleHQubGVuZ3RoID09IDEpIHsKLSAgICAgICAgZmlyc3RMaW5lLnJlcGxhY2UoZnJvbS5jaCwgbnVsbCwgbmV3VGV4dFswXSk7Ci0gICAgICAgIGxhc3RMaW5lLnJlcGxhY2UobnVsbCwgdG8uY2gsICIiKTsKLSAgICAgICAgZmlyc3RMaW5lLmFwcGVuZChsYXN0TGluZSk7Ci0gICAgICAgIGRvYy5yZW1vdmUoZnJvbS5saW5lICsgMSwgbmxpbmVzLCBjYWxsYmFja3MpOwotICAgICAgfSBlbHNlIHsKLSAgICAgICAgdmFyIGFkZGVkID0gW107Ci0gICAgICAgIGZpcnN0TGluZS5yZXBsYWNlKGZyb20uY2gsIG51bGwsIG5ld1RleHRbMF0pOwotICAgICAgICBsYXN0TGluZS5yZXBsYWNlKG51bGwsIHRvLmNoLCBuZXdUZXh0W25ld1RleHQubGVuZ3RoLTFdKTsKLSAgICAgICAgZmlyc3RMaW5lLmZpeE1hcmtFbmRzKGxhc3RMaW5lKTsKLSAgICAgICAgZm9yICh2YXIgaSA9IDEsIGUgPSBuZXdUZXh0Lmxlbmd0aCAtIDE7IGkgPCBlOyArK2kpCi0gICAgICAgICAgYWRkZWQucHVzaChMaW5lLmluaGVyaXRNYXJrcyhuZXdUZXh0W2ldLCBmaXJzdExpbmUpKTsKLSAgICAgICAgaWYgKG5saW5lcyA+IDEpIGRvYy5yZW1vdmUoZnJvbS5saW5lICsgMSwgbmxpbmVzIC0gMSwgY2FsbGJhY2tzKTsKLSAgICAgICAgZG9jLmluc2VydChmcm9tLmxpbmUgKyAxLCBhZGRlZCk7Ci0gICAgICB9Ci0gICAgICBpZiAob3B0aW9ucy5saW5lV3JhcHBpbmcpIHsKLSAgICAgICAgdmFyIHBlckxpbmUgPSBNYXRoLm1heCg1LCBzY3JvbGxlci5jbGllbnRXaWR0aCAvIGNoYXJXaWR0aCgpIC0gMyk7Ci0gICAgICAgIGRvYy5pdGVyKGZyb20ubGluZSwgZnJvbS5saW5lICsgbmV3VGV4dC5sZW5ndGgsIGZ1bmN0aW9uKGxpbmUpIHsKLSAgICAgICAgICBpZiAobGluZS5oaWRkZW4pIHJldHVybjsKLSAgICAgICAgICB2YXIgZ3Vlc3MgPSBNYXRoLmNlaWwobGluZS50ZXh0Lmxlbmd0aCAvIHBlckxpbmUpIHx8IDE7Ci0gICAgICAgICAgaWYgKGd1ZXNzICE9IGxpbmUuaGVpZ2h0KSB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIGd1ZXNzKTsKLSAgICAgICAgfSk7Ci0gICAgICB9IGVsc2UgewotICAgICAgICBkb2MuaXRlcihmcm9tLmxpbmUsIGZyb20ubGluZSArIG5ld1RleHQubGVuZ3RoLCBmdW5jdGlvbihsaW5lKSB7Ci0gICAgICAgICAgdmFyIGwgPSBsaW5lLnRleHQ7Ci0gICAgICAgICAgaWYgKGwubGVuZ3RoID4gbWF4TGluZUxlbmd0aCkgewotICAgICAgICAgICAgbWF4TGluZSA9IGw7IG1heExpbmVMZW5ndGggPSBsLmxlbmd0aDsgbWF4V2lkdGggPSBudWxsOwotICAgICAgICAgICAgcmVjb21wdXRlTWF4TGVuZ3RoID0gZmFsc2U7Ci0gICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICAgICAgaWYgKHJlY29tcHV0ZU1heExlbmd0aCkgewotICAgICAgICAgIG1heExpbmVMZW5ndGggPSAwOyBtYXhMaW5lID0gIiI7IG1heFdpZHRoID0gbnVsbDsKLSAgICAgICAgICBkb2MuaXRlcigwLCBkb2Muc2l6ZSwgZnVuY3Rpb24obGluZSkgewotICAgICAgICAgICAgdmFyIGwgPSBsaW5lLnRleHQ7Ci0gICAgICAgICAgICBpZiAobC5sZW5ndGggPiBtYXhMaW5lTGVuZ3RoKSB7Ci0gICAgICAgICAgICAgIG1heExpbmVMZW5ndGggPSBsLmxlbmd0aDsgbWF4TGluZSA9IGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgLy8gQWRkIHRoZXNlIGxpbmVzIHRvIHRoZSB3b3JrIGFycmF5LCBzbyB0aGF0IHRoZXkgd2lsbCBiZQotICAgICAgLy8gaGlnaGxpZ2h0ZWQuIEFkanVzdCB3b3JrIGxpbmVzIGlmIGxpbmVzIHdlcmUgYWRkZWQvcmVtb3ZlZC4KLSAgICAgIHZhciBuZXdXb3JrID0gW10sIGxlbmRpZmYgPSBuZXdUZXh0Lmxlbmd0aCAtIG5saW5lcyAtIDE7Ci0gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHdvcmsubGVuZ3RoOyBpIDwgbDsgKytpKSB7Ci0gICAgICAgIHZhciB0YXNrID0gd29ya1tpXTsKLSAgICAgICAgaWYgKHRhc2sgPCBmcm9tLmxpbmUpIG5ld1dvcmsucHVzaCh0YXNrKTsKLSAgICAgICAgZWxzZSBpZiAodGFzayA+IHRvLmxpbmUpIG5ld1dvcmsucHVzaCh0YXNrICsgbGVuZGlmZik7Ci0gICAgICB9Ci0gICAgICB2YXIgaGxFbmQgPSBmcm9tLmxpbmUgKyBNYXRoLm1pbihuZXdUZXh0Lmxlbmd0aCwgNTAwKTsKLSAgICAgIGhpZ2hsaWdodExpbmVzKGZyb20ubGluZSwgaGxFbmQpOwotICAgICAgbmV3V29yay5wdXNoKGhsRW5kKTsKLSAgICAgIHdvcmsgPSBuZXdXb3JrOwotICAgICAgc3RhcnRXb3JrZXIoMTAwKTsKLSAgICAgIC8vIFJlbWVtYmVyIHRoYXQgdGhlc2UgbGluZXMgY2hhbmdlZCwgZm9yIHVwZGF0aW5nIHRoZSBkaXNwbGF5Ci0gICAgICBjaGFuZ2VzLnB1c2goe2Zyb206IGZyb20ubGluZSwgdG86IHRvLmxpbmUgKyAxLCBkaWZmOiBsZW5kaWZmfSk7Ci0gICAgICB2YXIgY2hhbmdlT2JqID0ge2Zyb206IGZyb20sIHRvOiB0bywgdGV4dDogbmV3VGV4dH07Ci0gICAgICBpZiAodGV4dENoYW5nZWQpIHsKLSAgICAgICAgZm9yICh2YXIgY3VyID0gdGV4dENoYW5nZWQ7IGN1ci5uZXh0OyBjdXIgPSBjdXIubmV4dCkge30KLSAgICAgICAgY3VyLm5leHQgPSBjaGFuZ2VPYmo7Ci0gICAgICB9IGVsc2UgdGV4dENoYW5nZWQgPSBjaGFuZ2VPYmo7Ci0KLSAgICAgIC8vIFVwZGF0ZSB0aGUgc2VsZWN0aW9uCi0gICAgICBmdW5jdGlvbiB1cGRhdGVMaW5lKG4pIHtyZXR1cm4gbiA8PSBNYXRoLm1pbih0by5saW5lLCB0by5saW5lICsgbGVuZGlmZikgPyBuIDogbiArIGxlbmRpZmY7fQotICAgICAgc2V0U2VsZWN0aW9uKHNlbEZyb20sIHNlbFRvLCB1cGRhdGVMaW5lKHNlbC5mcm9tLmxpbmUpLCB1cGRhdGVMaW5lKHNlbC50by5saW5lKSk7Ci0KLSAgICAgIC8vIE1ha2Ugc3VyZSB0aGUgc2Nyb2xsLXNpemUgZGl2IGhhcyB0aGUgY29ycmVjdCBoZWlnaHQuCi0gICAgICBpZiAoc2Nyb2xsZXIuY2xpZW50SGVpZ2h0KQotICAgICAgICBjb2RlLnN0eWxlLmhlaWdodCA9IChkb2MuaGVpZ2h0ICogdGV4dEhlaWdodCgpICsgMiAqIHBhZGRpbmdUb3AoKSkgKyAicHgiOwotICAgIH0KLQotICAgIGZ1bmN0aW9uIHJlcGxhY2VSYW5nZShjb2RlLCBmcm9tLCB0bykgewotICAgICAgZnJvbSA9IGNsaXBQb3MoZnJvbSk7Ci0gICAgICBpZiAoIXRvKSB0byA9IGZyb207IGVsc2UgdG8gPSBjbGlwUG9zKHRvKTsKLSAgICAgIGNvZGUgPSBzcGxpdExpbmVzKGNvZGUpOwotICAgICAgZnVuY3Rpb24gYWRqdXN0UG9zKHBvcykgewotICAgICAgICBpZiAocG9zTGVzcyhwb3MsIGZyb20pKSByZXR1cm4gcG9zOwotICAgICAgICBpZiAoIXBvc0xlc3ModG8sIHBvcykpIHJldHVybiBlbmQ7Ci0gICAgICAgIHZhciBsaW5lID0gcG9zLmxpbmUgKyBjb2RlLmxlbmd0aCAtICh0by5saW5lIC0gZnJvbS5saW5lKSAtIDE7Ci0gICAgICAgIHZhciBjaCA9IHBvcy5jaDsKLSAgICAgICAgaWYgKHBvcy5saW5lID09IHRvLmxpbmUpCi0gICAgICAgICAgY2ggKz0gY29kZVtjb2RlLmxlbmd0aC0xXS5sZW5ndGggLSAodG8uY2ggLSAodG8ubGluZSA9PSBmcm9tLmxpbmUgPyBmcm9tLmNoIDogMCkpOwotICAgICAgICByZXR1cm4ge2xpbmU6IGxpbmUsIGNoOiBjaH07Ci0gICAgICB9Ci0gICAgICB2YXIgZW5kOwotICAgICAgcmVwbGFjZVJhbmdlMShjb2RlLCBmcm9tLCB0bywgZnVuY3Rpb24oZW5kMSkgewotICAgICAgICBlbmQgPSBlbmQxOwotICAgICAgICByZXR1cm4ge2Zyb206IGFkanVzdFBvcyhzZWwuZnJvbSksIHRvOiBhZGp1c3RQb3Moc2VsLnRvKX07Ci0gICAgICB9KTsKLSAgICAgIHJldHVybiBlbmQ7Ci0gICAgfQotICAgIGZ1bmN0aW9uIHJlcGxhY2VTZWxlY3Rpb24oY29kZSwgY29sbGFwc2UpIHsKLSAgICAgIHJlcGxhY2VSYW5nZTEoc3BsaXRMaW5lcyhjb2RlKSwgc2VsLmZyb20sIHNlbC50bywgZnVuY3Rpb24oZW5kKSB7Ci0gICAgICAgIGlmIChjb2xsYXBzZSA9PSAiZW5kIikgcmV0dXJuIHtmcm9tOiBlbmQsIHRvOiBlbmR9OwotICAgICAgICBlbHNlIGlmIChjb2xsYXBzZSA9PSAic3RhcnQiKSByZXR1cm4ge2Zyb206IHNlbC5mcm9tLCB0bzogc2VsLmZyb219OwotICAgICAgICBlbHNlIHJldHVybiB7ZnJvbTogc2VsLmZyb20sIHRvOiBlbmR9OwotICAgICAgfSk7Ci0gICAgfQotICAgIGZ1bmN0aW9uIHJlcGxhY2VSYW5nZTEoY29kZSwgZnJvbSwgdG8sIGNvbXB1dGVTZWwpIHsKLSAgICAgIHZhciBlbmRjaCA9IGNvZGUubGVuZ3RoID09IDEgPyBjb2RlWzBdLmxlbmd0aCArIGZyb20uY2ggOiBjb2RlW2NvZGUubGVuZ3RoLTFdLmxlbmd0aDsKLSAgICAgIHZhciBuZXdTZWwgPSBjb21wdXRlU2VsKHtsaW5lOiBmcm9tLmxpbmUgKyBjb2RlLmxlbmd0aCAtIDEsIGNoOiBlbmRjaH0pOwotICAgICAgdXBkYXRlTGluZXMoZnJvbSwgdG8sIGNvZGUsIG5ld1NlbC5mcm9tLCBuZXdTZWwudG8pOwotICAgIH0KLQotICAgIGZ1bmN0aW9uIGdldFJhbmdlKGZyb20sIHRvKSB7Ci0gICAgICB2YXIgbDEgPSBmcm9tLmxpbmUsIGwyID0gdG8ubGluZTsKLSAgICAgIGlmIChsMSA9PSBsMikgcmV0dXJuIGdldExpbmUobDEpLnRleHQuc2xpY2UoZnJvbS5jaCwgdG8uY2gpOwotICAgICAgdmFyIGNvZGUgPSBbZ2V0TGluZShsMSkudGV4dC5zbGljZShmcm9tLmNoKV07Ci0gICAgICBkb2MuaXRlcihsMSArIDEsIGwyLCBmdW5jdGlvbihsaW5lKSB7IGNvZGUucHVzaChsaW5lLnRleHQpOyB9KTsKLSAgICAgIGNvZGUucHVzaChnZXRMaW5lKGwyKS50ZXh0LnNsaWNlKDAsIHRvLmNoKSk7Ci0gICAgICByZXR1cm4gY29kZS5qb2luKCJcbiIpOwotICAgIH0KLSAgICBmdW5jdGlvbiBnZXRTZWxlY3Rpb24oKSB7Ci0gICAgICByZXR1cm4gZ2V0UmFuZ2Uoc2VsLmZyb20sIHNlbC50byk7Ci0gICAgfQotCi0gICAgdmFyIHBvbGxpbmdGYXN0ID0gZmFsc2U7IC8vIEVuc3VyZXMgc2xvd1BvbGwgZG9lc24ndCBjYW5jZWwgZmFzdFBvbGwKLSAgICBmdW5jdGlvbiBzbG93UG9sbCgpIHsKLSAgICAgIGlmIChwb2xsaW5nRmFzdCkgcmV0dXJuOwotICAgICAgcG9sbC5zZXQob3B0aW9ucy5wb2xsSW50ZXJ2YWwsIGZ1bmN0aW9uKCkgewotICAgICAgICBzdGFydE9wZXJhdGlvbigpOwotICAgICAgICByZWFkSW5wdXQoKTsKLSAgICAgICAgaWYgKGZvY3VzZWQpIHNsb3dQb2xsKCk7Ci0gICAgICAgIGVuZE9wZXJhdGlvbigpOwotICAgICAgfSk7Ci0gICAgfQotICAgIGZ1bmN0aW9uIGZhc3RQb2xsKCkgewotICAgICAgdmFyIG1pc3NlZCA9IGZhbHNlOwotICAgICAgcG9sbGluZ0Zhc3QgPSB0cnVlOwotICAgICAgZnVuY3Rpb24gcCgpIHsKLSAgICAgICAgc3RhcnRPcGVyYXRpb24oKTsKLSAgICAgICAgdmFyIGNoYW5nZWQgPSByZWFkSW5wdXQoKTsKLSAgICAgICAgaWYgKCFjaGFuZ2VkICYmICFtaXNzZWQpIHttaXNzZWQgPSB0cnVlOyBwb2xsLnNldCg2MCwgcCk7fQotICAgICAgICBlbHNlIHtwb2xsaW5nRmFzdCA9IGZhbHNlOyBzbG93UG9sbCgpO30KLSAgICAgICAgZW5kT3BlcmF0aW9uKCk7Ci0gICAgICB9Ci0gICAgICBwb2xsLnNldCgyMCwgcCk7Ci0gICAgfQotCi0gICAgLy8gUHJldmlucHV0IGlzIGEgaGFjayB0byB3b3JrIHdpdGggSU1FLiBJZiB3ZSByZXNldCB0aGUgdGV4dGFyZWEKLSAgICAvLyBvbiBldmVyeSBjaGFuZ2UsIHRoYXQgYnJlYWtzIElNRS4gU28gd2UgbG9vayBmb3IgY2hhbmdlcwotICAgIC8vIGNvbXBhcmVkIHRvIHRoZSBwcmV2aW91cyBjb250ZW50IGluc3RlYWQuIChNb2Rlcm4gYnJvd3NlcnMgaGF2ZQotICAgIC8vIGV2ZW50cyB0aGF0IGluZGljYXRlIElNRSB0YWtpbmcgcGxhY2UsIGJ1dCB0aGVzZSBhcmUgbm90IHdpZGVseQotICAgIC8vIHN1cHBvcnRlZCBvciBjb21wYXRpYmxlIGVub3VnaCB5ZXQgdG8gcmVseSBvbi4pCi0gICAgdmFyIHByZXZJbnB1dCA9ICIiOwotICAgIGZ1bmN0aW9uIHJlYWRJbnB1dCgpIHsKLSAgICAgIGlmIChsZWF2ZUlucHV0QWxvbmUgfHwgIWZvY3VzZWQgfHwgaGFzU2VsZWN0aW9uKGlucHV0KSB8fCBvcHRpb25zLnJlYWRPbmx5KSByZXR1cm4gZmFsc2U7Ci0gICAgICB2YXIgdGV4dCA9IGlucHV0LnZhbHVlOwotICAgICAgaWYgKHRleHQgPT0gcHJldklucHV0KSByZXR1cm4gZmFsc2U7Ci0gICAgICBzaGlmdFNlbGVjdGluZyA9IG51bGw7Ci0gICAgICB2YXIgc2FtZSA9IDAsIGwgPSBNYXRoLm1pbihwcmV2SW5wdXQubGVuZ3RoLCB0ZXh0Lmxlbmd0aCk7Ci0gICAgICB3aGlsZSAoc2FtZSA8IGwgJiYgcHJldklucHV0W3NhbWVdID09IHRleHRbc2FtZV0pICsrc2FtZTsKLSAgICAgIGlmIChzYW1lIDwgcHJldklucHV0Lmxlbmd0aCkKLSAgICAgICAgc2VsLmZyb20gPSB7bGluZTogc2VsLmZyb20ubGluZSwgY2g6IHNlbC5mcm9tLmNoIC0gKHByZXZJbnB1dC5sZW5ndGggLSBzYW1lKX07Ci0gICAgICBlbHNlIGlmIChvdmVyd3JpdGUgJiYgcG9zRXEoc2VsLmZyb20sIHNlbC50bykpCi0gICAgICAgIHNlbC50byA9IHtsaW5lOiBzZWwudG8ubGluZSwgY2g6IE1hdGgubWluKGdldExpbmUoc2VsLnRvLmxpbmUpLnRleHQubGVuZ3RoLCBzZWwudG8uY2ggKyAodGV4dC5sZW5ndGggLSBzYW1lKSl9OwotICAgICAgcmVwbGFjZVNlbGVjdGlvbih0ZXh0LnNsaWNlKHNhbWUpLCAiZW5kIik7Ci0gICAgICBwcmV2SW5wdXQgPSB0ZXh0OwotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotICAgIGZ1bmN0aW9uIHJlc2V0SW5wdXQodXNlcikgewotICAgICAgaWYgKCFwb3NFcShzZWwuZnJvbSwgc2VsLnRvKSkgewotICAgICAgICBwcmV2SW5wdXQgPSAiIjsKLSAgICAgICAgaW5wdXQudmFsdWUgPSBnZXRTZWxlY3Rpb24oKTsKLSAgICAgICAgc2VsZWN0SW5wdXQoaW5wdXQpOwotICAgICAgfSBlbHNlIGlmICh1c2VyKSBwcmV2SW5wdXQgPSBpbnB1dC52YWx1ZSA9ICIiOwotICAgIH0KLQotICAgIGZ1bmN0aW9uIGZvY3VzSW5wdXQoKSB7Ci0gICAgICBpZiAob3B0aW9ucy5yZWFkT25seSAhPSAibm9jdXJzb3IiKSBpbnB1dC5mb2N1cygpOwotICAgIH0KLQotICAgIGZ1bmN0aW9uIHNjcm9sbEVkaXRvckludG9WaWV3KCkgewotICAgICAgaWYgKCFjdXJzb3IuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KSByZXR1cm47Ci0gICAgICB2YXIgcmVjdCA9IGN1cnNvci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKLSAgICAgIC8vIElFIHJldHVybnMgYm9ndXMgY29vcmRpbmF0ZXMgd2hlbiB0aGUgaW5zdGFuY2Ugc2l0cyBpbnNpZGUgb2YgYW4gaWZyYW1lIGFuZCB0aGUgY3Vyc29yIGlzIGhpZGRlbgotICAgICAgaWYgKGllICYmIHJlY3QudG9wID09IHJlY3QuYm90dG9tKSByZXR1cm47Ci0gICAgICB2YXIgd2luSCA9IHdpbmRvdy5pbm5lckhlaWdodCB8fCBNYXRoLm1heChkb2N1bWVudC5ib2R5Lm9mZnNldEhlaWdodCwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50Lm9mZnNldEhlaWdodCk7Ci0gICAgICBpZiAocmVjdC50b3AgPCAwIHx8IHJlY3QuYm90dG9tID4gd2luSCkgY3Vyc29yLnNjcm9sbEludG9WaWV3KCk7Ci0gICAgfQotICAgIGZ1bmN0aW9uIHNjcm9sbEN1cnNvckludG9WaWV3KCkgewotICAgICAgdmFyIGN1cnNvciA9IGxvY2FsQ29vcmRzKHNlbC5pbnZlcnRlZCA/IHNlbC5mcm9tIDogc2VsLnRvKTsKLSAgICAgIHZhciB4ID0gb3B0aW9ucy5saW5lV3JhcHBpbmcgPyBNYXRoLm1pbihjdXJzb3IueCwgbGluZVNwYWNlLm9mZnNldFdpZHRoKSA6IGN1cnNvci54OwotICAgICAgcmV0dXJuIHNjcm9sbEludG9WaWV3KHgsIGN1cnNvci55LCB4LCBjdXJzb3IueUJvdCk7Ci0gICAgfQotICAgIGZ1bmN0aW9uIHNjcm9sbEludG9WaWV3KHgxLCB5MSwgeDIsIHkyKSB7Ci0gICAgICB2YXIgcGwgPSBwYWRkaW5nTGVmdCgpLCBwdCA9IHBhZGRpbmdUb3AoKTsKLSAgICAgIHkxICs9IHB0OyB5MiArPSBwdDsgeDEgKz0gcGw7IHgyICs9IHBsOwotICAgICAgdmFyIHNjcmVlbiA9IHNjcm9sbGVyLmNsaWVudEhlaWdodCwgc2NyZWVudG9wID0gc2Nyb2xsZXIuc2Nyb2xsVG9wLCBzY3JvbGxlZCA9IGZhbHNlLCByZXN1bHQgPSB0cnVlOwotICAgICAgaWYgKHkxIDwgc2NyZWVudG9wKSB7c2Nyb2xsZXIuc2Nyb2xsVG9wID0gTWF0aC5tYXgoMCwgeTEpOyBzY3JvbGxlZCA9IHRydWU7fQotICAgICAgZWxzZSBpZiAoeTIgPiBzY3JlZW50b3AgKyBzY3JlZW4pIHtzY3JvbGxlci5zY3JvbGxUb3AgPSB5MiAtIHNjcmVlbjsgc2Nyb2xsZWQgPSB0cnVlO30KLQotICAgICAgdmFyIHNjcmVlbncgPSBzY3JvbGxlci5jbGllbnRXaWR0aCwgc2NyZWVubGVmdCA9IHNjcm9sbGVyLnNjcm9sbExlZnQ7Ci0gICAgICB2YXIgZ3V0dGVydyA9IG9wdGlvbnMuZml4ZWRHdXR0ZXIgPyBndXR0ZXIuY2xpZW50V2lkdGggOiAwOwotICAgICAgdmFyIGF0TGVmdCA9IHgxIDwgZ3V0dGVydyArIHBsICsgMTA7Ci0gICAgICBpZiAoeDEgPCBzY3JlZW5sZWZ0ICsgZ3V0dGVydyB8fCBhdExlZnQpIHsKLSAgICAgICAgaWYgKGF0TGVmdCkgeDEgPSAwOwotICAgICAgICBzY3JvbGxlci5zY3JvbGxMZWZ0ID0gTWF0aC5tYXgoMCwgeDEgLSAxMCAtIGd1dHRlcncpOwotICAgICAgICBzY3JvbGxlZCA9IHRydWU7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICh4MiA+IHNjcmVlbncgKyBzY3JlZW5sZWZ0IC0gMykgewotICAgICAgICBzY3JvbGxlci5zY3JvbGxMZWZ0ID0geDIgKyAxMCAtIHNjcmVlbnc7Ci0gICAgICAgIHNjcm9sbGVkID0gdHJ1ZTsKLSAgICAgICAgaWYgKHgyID4gY29kZS5jbGllbnRXaWR0aCkgcmVzdWx0ID0gZmFsc2U7Ci0gICAgICB9Ci0gICAgICBpZiAoc2Nyb2xsZWQgJiYgb3B0aW9ucy5vblNjcm9sbCkgb3B0aW9ucy5vblNjcm9sbChpbnN0YW5jZSk7Ci0gICAgICByZXR1cm4gcmVzdWx0OwotICAgIH0KLQotICAgIGZ1bmN0aW9uIHZpc2libGVMaW5lcygpIHsKLSAgICAgIHZhciBsaCA9IHRleHRIZWlnaHQoKSwgdG9wID0gc2Nyb2xsZXIuc2Nyb2xsVG9wIC0gcGFkZGluZ1RvcCgpOwotICAgICAgdmFyIGZyb21IZWlnaHQgPSBNYXRoLm1heCgwLCBNYXRoLmZsb29yKHRvcCAvIGxoKSk7Ci0gICAgICB2YXIgdG9IZWlnaHQgPSBNYXRoLmNlaWwoKHRvcCArIHNjcm9sbGVyLmNsaWVudEhlaWdodCkgLyBsaCk7Ci0gICAgICByZXR1cm4ge2Zyb206IGxpbmVBdEhlaWdodChkb2MsIGZyb21IZWlnaHQpLAotICAgICAgICAgICAgICB0bzogbGluZUF0SGVpZ2h0KGRvYywgdG9IZWlnaHQpfTsKLSAgICB9Ci0gICAgLy8gVXNlcyBhIHNldCBvZiBjaGFuZ2VzIHBsdXMgdGhlIGN1cnJlbnQgc2Nyb2xsIHBvc2l0aW9uIHRvCi0gICAgLy8gZGV0ZXJtaW5lIHdoaWNoIERPTSB1cGRhdGVzIGhhdmUgdG8gYmUgbWFkZSwgYW5kIG1ha2VzIHRoZQotICAgIC8vIHVwZGF0ZXMuCi0gICAgZnVuY3Rpb24gdXBkYXRlRGlzcGxheShjaGFuZ2VzLCBzdXBwcmVzc0NhbGxiYWNrKSB7Ci0gICAgICBpZiAoIXNjcm9sbGVyLmNsaWVudFdpZHRoKSB7Ci0gICAgICAgIHNob3dpbmdGcm9tID0gc2hvd2luZ1RvID0gZGlzcGxheU9mZnNldCA9IDA7Ci0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLSAgICAgIC8vIENvbXB1dGUgdGhlIG5ldyB2aXNpYmxlIHdpbmRvdwotICAgICAgdmFyIHZpc2libGUgPSB2aXNpYmxlTGluZXMoKTsKLSAgICAgIC8vIEJhaWwgb3V0IGlmIHRoZSB2aXNpYmxlIGFyZWEgaXMgYWxyZWFkeSByZW5kZXJlZCBhbmQgbm90aGluZyBjaGFuZ2VkLgotICAgICAgaWYgKGNoYW5nZXMgIT09IHRydWUgJiYgY2hhbmdlcy5sZW5ndGggPT0gMCAmJiB2aXNpYmxlLmZyb20gPiBzaG93aW5nRnJvbSAmJiB2aXNpYmxlLnRvIDwgc2hvd2luZ1RvKSByZXR1cm47Ci0gICAgICB2YXIgZnJvbSA9IE1hdGgubWF4KHZpc2libGUuZnJvbSAtIDEwMCwgMCksIHRvID0gTWF0aC5taW4oZG9jLnNpemUsIHZpc2libGUudG8gKyAxMDApOwotICAgICAgaWYgKHNob3dpbmdGcm9tIDwgZnJvbSAmJiBmcm9tIC0gc2hvd2luZ0Zyb20gPCAyMCkgZnJvbSA9IHNob3dpbmdGcm9tOwotICAgICAgaWYgKHNob3dpbmdUbyA+IHRvICYmIHNob3dpbmdUbyAtIHRvIDwgMjApIHRvID0gTWF0aC5taW4oZG9jLnNpemUsIHNob3dpbmdUbyk7Ci0KLSAgICAgIC8vIENyZWF0ZSBhIHJhbmdlIG9mIHRoZW9yZXRpY2FsbHkgaW50YWN0IGxpbmVzLCBhbmQgcHVuY2ggaG9sZXMKLSAgICAgIC8vIGluIHRoYXQgdXNpbmcgdGhlIGNoYW5nZSBpbmZvLgotICAgICAgdmFyIGludGFjdCA9IGNoYW5nZXMgPT09IHRydWUgPyBbXSA6Ci0gICAgICAgIGNvbXB1dGVJbnRhY3QoW3tmcm9tOiBzaG93aW5nRnJvbSwgdG86IHNob3dpbmdUbywgZG9tU3RhcnQ6IDB9XSwgY2hhbmdlcyk7Ci0gICAgICAvLyBDbGlwIG9mZiB0aGUgcGFydHMgdGhhdCB3b24ndCBiZSB2aXNpYmxlCi0gICAgICB2YXIgaW50YWN0TGluZXMgPSAwOwotICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbnRhY3QubGVuZ3RoOyArK2kpIHsKLSAgICAgICAgdmFyIHJhbmdlID0gaW50YWN0W2ldOwotICAgICAgICBpZiAocmFuZ2UuZnJvbSA8IGZyb20pIHtyYW5nZS5kb21TdGFydCArPSAoZnJvbSAtIHJhbmdlLmZyb20pOyByYW5nZS5mcm9tID0gZnJvbTt9Ci0gICAgICAgIGlmIChyYW5nZS50byA+IHRvKSByYW5nZS50byA9IHRvOwotICAgICAgICBpZiAocmFuZ2UuZnJvbSA+PSByYW5nZS50bykgaW50YWN0LnNwbGljZShpLS0sIDEpOwotICAgICAgICBlbHNlIGludGFjdExpbmVzICs9IHJhbmdlLnRvIC0gcmFuZ2UuZnJvbTsKLSAgICAgIH0KLSAgICAgIGlmIChpbnRhY3RMaW5lcyA9PSB0byAtIGZyb20gJiYgZnJvbSA9PSBzaG93aW5nRnJvbSAmJiB0byA9PSBzaG93aW5nVG8pIHJldHVybjsKLSAgICAgIGludGFjdC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtyZXR1cm4gYS5kb21TdGFydCAtIGIuZG9tU3RhcnQ7fSk7Ci0KLSAgICAgIHZhciB0aCA9IHRleHRIZWlnaHQoKSwgZ3V0dGVyRGlzcGxheSA9IGd1dHRlci5zdHlsZS5kaXNwbGF5OwotICAgICAgbGluZURpdi5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwotICAgICAgcGF0Y2hEaXNwbGF5KGZyb20sIHRvLCBpbnRhY3QpOwotICAgICAgbGluZURpdi5zdHlsZS5kaXNwbGF5ID0gZ3V0dGVyLnN0eWxlLmRpc3BsYXkgPSAiIjsKLQotICAgICAgLy8gUG9zaXRpb24gdGhlIG1vdmVyIGRpdiB0byBhbGlnbiB3aXRoIHRoZSBsaW5lcyBpdCdzIHN1cHBvc2VkCi0gICAgICAvLyB0byBiZSBzaG93aW5nICh3aGljaCB3aWxsIGNvdmVyIHRoZSB2aXNpYmxlIGRpc3BsYXkpCi0gICAgICB2YXIgZGlmZmVyZW50ID0gZnJvbSAhPSBzaG93aW5nRnJvbSB8fCB0byAhPSBzaG93aW5nVG8gfHwgbGFzdFNpemVDICE9IHNjcm9sbGVyLmNsaWVudEhlaWdodCArIHRoOwotICAgICAgLy8gVGhpcyBpcyBqdXN0IGEgYm9ndXMgZm9ybXVsYSB0aGF0IGRldGVjdHMgd2hlbiB0aGUgZWRpdG9yIGlzCi0gICAgICAvLyByZXNpemVkIG9yIHRoZSBmb250IHNpemUgY2hhbmdlcy4KLSAgICAgIGlmIChkaWZmZXJlbnQpIGxhc3RTaXplQyA9IHNjcm9sbGVyLmNsaWVudEhlaWdodCArIHRoOwotICAgICAgc2hvd2luZ0Zyb20gPSBmcm9tOyBzaG93aW5nVG8gPSB0bzsKLSAgICAgIGRpc3BsYXlPZmZzZXQgPSBoZWlnaHRBdExpbmUoZG9jLCBmcm9tKTsKLSAgICAgIG1vdmVyLnN0eWxlLnRvcCA9IChkaXNwbGF5T2Zmc2V0ICogdGgpICsgInB4IjsKLSAgICAgIGlmIChzY3JvbGxlci5jbGllbnRIZWlnaHQpCi0gICAgICAgIGNvZGUuc3R5bGUuaGVpZ2h0ID0gKGRvYy5oZWlnaHQgKiB0aCArIDIgKiBwYWRkaW5nVG9wKCkpICsgInB4IjsKLQotICAgICAgLy8gU2luY2UgdGhpcyBpcyBhbGwgcmF0aGVyIGVycm9yIHByb25lLCBpdCBpcyBob25vdXJlZCB3aXRoIHRoZQotICAgICAgLy8gb25seSBhc3NlcnRpb24gaW4gdGhlIHdob2xlIGZpbGUuCi0gICAgICBpZiAobGluZURpdi5jaGlsZE5vZGVzLmxlbmd0aCAhPSBzaG93aW5nVG8gLSBzaG93aW5nRnJvbSkKLSAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJCQUQgUEFUQ0ghICIgKyBKU09OLnN0cmluZ2lmeShpbnRhY3QpICsgIiBzaXplPSIgKyAoc2hvd2luZ1RvIC0gc2hvd2luZ0Zyb20pICsKLSAgICAgICAgICAgICAgICAgICAgICAgICIgbm9kZXM9IiArIGxpbmVEaXYuY2hpbGROb2Rlcy5sZW5ndGgpOwotCi0gICAgICBmdW5jdGlvbiBjaGVja0hlaWdodHMoKSB7Ci0gICAgICAgIG1heFdpZHRoID0gc2Nyb2xsZXIuY2xpZW50V2lkdGg7Ci0gICAgICAgIHZhciBjdXJOb2RlID0gbGluZURpdi5maXJzdENoaWxkLCBoZWlnaHRDaGFuZ2VkID0gZmFsc2U7Ci0gICAgICAgIGRvYy5pdGVyKHNob3dpbmdGcm9tLCBzaG93aW5nVG8sIGZ1bmN0aW9uKGxpbmUpIHsKLSAgICAgICAgICBpZiAoIWxpbmUuaGlkZGVuKSB7Ci0gICAgICAgICAgICB2YXIgaGVpZ2h0ID0gTWF0aC5yb3VuZChjdXJOb2RlLm9mZnNldEhlaWdodCAvIHRoKSB8fCAxOwotICAgICAgICAgICAgaWYgKGxpbmUuaGVpZ2h0ICE9IGhlaWdodCkgewotICAgICAgICAgICAgICB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIGhlaWdodCk7Ci0gICAgICAgICAgICAgIGd1dHRlckRpcnR5ID0gaGVpZ2h0Q2hhbmdlZCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICAgIGN1ck5vZGUgPSBjdXJOb2RlLm5leHRTaWJsaW5nOwotICAgICAgICB9KTsKLSAgICAgICAgaWYgKGhlaWdodENoYW5nZWQpCi0gICAgICAgICAgY29kZS5zdHlsZS5oZWlnaHQgPSAoZG9jLmhlaWdodCAqIHRoICsgMiAqIHBhZGRpbmdUb3AoKSkgKyAicHgiOwotICAgICAgICByZXR1cm4gaGVpZ2h0Q2hhbmdlZDsKLSAgICAgIH0KLQotICAgICAgaWYgKG9wdGlvbnMubGluZVdyYXBwaW5nKSB7Ci0gICAgICAgIGNoZWNrSGVpZ2h0cygpOwotICAgICAgfSBlbHNlIHsKLSAgICAgICAgaWYgKG1heFdpZHRoID09IG51bGwpIG1heFdpZHRoID0gc3RyaW5nV2lkdGgobWF4TGluZSk7Ci0gICAgICAgIGlmIChtYXhXaWR0aCA+IHNjcm9sbGVyLmNsaWVudFdpZHRoKSB7Ci0gICAgICAgICAgbGluZVNwYWNlLnN0eWxlLndpZHRoID0gbWF4V2lkdGggKyAicHgiOwotICAgICAgICAgIC8vIE5lZWRlZCB0byBwcmV2ZW50IG9kZCB3cmFwcGluZy9oaWRpbmcgb2Ygd2lkZ2V0cyBwbGFjZWQgaW4gaGVyZS4KLSAgICAgICAgICBjb2RlLnN0eWxlLndpZHRoID0gIiI7Ci0gICAgICAgICAgY29kZS5zdHlsZS53aWR0aCA9IHNjcm9sbGVyLnNjcm9sbFdpZHRoICsgInB4IjsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICBsaW5lU3BhY2Uuc3R5bGUud2lkdGggPSBjb2RlLnN0eWxlLndpZHRoID0gIiI7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgZ3V0dGVyLnN0eWxlLmRpc3BsYXkgPSBndXR0ZXJEaXNwbGF5OwotICAgICAgaWYgKGRpZmZlcmVudCB8fCBndXR0ZXJEaXJ0eSkgewotICAgICAgICAvLyBJZiB0aGUgZ3V0dGVyIGdyZXcgaW4gc2l6ZSwgcmUtY2hlY2sgaGVpZ2h0cy4gSWYgdGhvc2UgY2hhbmdlZCwgcmUtZHJhdyBndXR0ZXIuCi0gICAgICAgIHVwZGF0ZUd1dHRlcigpICYmIG9wdGlvbnMubGluZVdyYXBwaW5nICYmIGNoZWNrSGVpZ2h0cygpICYmIHVwZGF0ZUd1dHRlcigpOwotICAgICAgfQotICAgICAgdXBkYXRlU2VsZWN0aW9uKCk7Ci0gICAgICBpZiAoIXN1cHByZXNzQ2FsbGJhY2sgJiYgb3B0aW9ucy5vblVwZGF0ZSkgb3B0aW9ucy5vblVwZGF0ZShpbnN0YW5jZSk7Ci0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICBmdW5jdGlvbiBjb21wdXRlSW50YWN0KGludGFjdCwgY2hhbmdlcykgewotICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjaGFuZ2VzLmxlbmd0aCB8fCAwOyBpIDwgbDsgKytpKSB7Ci0gICAgICAgIHZhciBjaGFuZ2UgPSBjaGFuZ2VzW2ldLCBpbnRhY3QyID0gW10sIGRpZmYgPSBjaGFuZ2UuZGlmZiB8fCAwOwotICAgICAgICBmb3IgKHZhciBqID0gMCwgbDIgPSBpbnRhY3QubGVuZ3RoOyBqIDwgbDI7ICsraikgewotICAgICAgICAgIHZhciByYW5nZSA9IGludGFjdFtqXTsKLSAgICAgICAgICBpZiAoY2hhbmdlLnRvIDw9IHJhbmdlLmZyb20gJiYgY2hhbmdlLmRpZmYpCi0gICAgICAgICAgICBpbnRhY3QyLnB1c2goe2Zyb206IHJhbmdlLmZyb20gKyBkaWZmLCB0bzogcmFuZ2UudG8gKyBkaWZmLAotICAgICAgICAgICAgICAgICAgICAgICAgICBkb21TdGFydDogcmFuZ2UuZG9tU3RhcnR9KTsKLSAgICAgICAgICBlbHNlIGlmIChjaGFuZ2UudG8gPD0gcmFuZ2UuZnJvbSB8fCBjaGFuZ2UuZnJvbSA+PSByYW5nZS50bykKLSAgICAgICAgICAgIGludGFjdDIucHVzaChyYW5nZSk7Ci0gICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAoY2hhbmdlLmZyb20gPiByYW5nZS5mcm9tKQotICAgICAgICAgICAgICBpbnRhY3QyLnB1c2goe2Zyb206IHJhbmdlLmZyb20sIHRvOiBjaGFuZ2UuZnJvbSwgZG9tU3RhcnQ6IHJhbmdlLmRvbVN0YXJ0fSk7Ci0gICAgICAgICAgICBpZiAoY2hhbmdlLnRvIDwgcmFuZ2UudG8pCi0gICAgICAgICAgICAgIGludGFjdDIucHVzaCh7ZnJvbTogY2hhbmdlLnRvICsgZGlmZiwgdG86IHJhbmdlLnRvICsgZGlmZiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb21TdGFydDogcmFuZ2UuZG9tU3RhcnQgKyAoY2hhbmdlLnRvIC0gcmFuZ2UuZnJvbSl9KTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaW50YWN0ID0gaW50YWN0MjsKLSAgICAgIH0KLSAgICAgIHJldHVybiBpbnRhY3Q7Ci0gICAgfQotCi0gICAgZnVuY3Rpb24gcGF0Y2hEaXNwbGF5KGZyb20sIHRvLCBpbnRhY3QpIHsKLSAgICAgIC8vIFRoZSBmaXJzdCBwYXNzIHJlbW92ZXMgdGhlIERPTSBub2RlcyB0aGF0IGFyZW4ndCBpbnRhY3QuCi0gICAgICBpZiAoIWludGFjdC5sZW5ndGgpIGxpbmVEaXYuaW5uZXJIVE1MID0gIiI7Ci0gICAgICBlbHNlIHsKLSAgICAgICAgZnVuY3Rpb24ga2lsbE5vZGUobm9kZSkgewotICAgICAgICAgIHZhciB0bXAgPSBub2RlLm5leHRTaWJsaW5nOwotICAgICAgICAgIG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChub2RlKTsKLSAgICAgICAgICByZXR1cm4gdG1wOwotICAgICAgICB9Ci0gICAgICAgIHZhciBkb21Qb3MgPSAwLCBjdXJOb2RlID0gbGluZURpdi5maXJzdENoaWxkLCBuOwotICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGludGFjdC5sZW5ndGg7ICsraSkgewotICAgICAgICAgIHZhciBjdXIgPSBpbnRhY3RbaV07Ci0gICAgICAgICAgd2hpbGUgKGN1ci5kb21TdGFydCA+IGRvbVBvcykge2N1ck5vZGUgPSBraWxsTm9kZShjdXJOb2RlKTsgZG9tUG9zKys7fQotICAgICAgICAgIGZvciAodmFyIGogPSAwLCBlID0gY3VyLnRvIC0gY3VyLmZyb207IGogPCBlOyArK2opIHtjdXJOb2RlID0gY3VyTm9kZS5uZXh0U2libGluZzsgZG9tUG9zKys7fQotICAgICAgICB9Ci0gICAgICAgIHdoaWxlIChjdXJOb2RlKSBjdXJOb2RlID0ga2lsbE5vZGUoY3VyTm9kZSk7Ci0gICAgICB9Ci0gICAgICAvLyBUaGlzIHBhc3MgZmlsbHMgaW4gdGhlIGxpbmVzIHRoYXQgYWN0dWFsbHkgY2hhbmdlZC4KLSAgICAgIHZhciBuZXh0SW50YWN0ID0gaW50YWN0LnNoaWZ0KCksIGN1ck5vZGUgPSBsaW5lRGl2LmZpcnN0Q2hpbGQsIGogPSBmcm9tOwotICAgICAgdmFyIHNjcmF0Y2ggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKLSAgICAgIGRvYy5pdGVyKGZyb20sIHRvLCBmdW5jdGlvbihsaW5lKSB7Ci0gICAgICAgIGlmIChuZXh0SW50YWN0ICYmIG5leHRJbnRhY3QudG8gPT0gaikgbmV4dEludGFjdCA9IGludGFjdC5zaGlmdCgpOwotICAgICAgICBpZiAoIW5leHRJbnRhY3QgfHwgbmV4dEludGFjdC5mcm9tID4gaikgewotICAgICAgICAgIGlmIChsaW5lLmhpZGRlbikgdmFyIGh0bWwgPSBzY3JhdGNoLmlubmVySFRNTCA9ICI8cHJlPjwvcHJlPiI7Ci0gICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICB2YXIgaHRtbCA9ICc8cHJlJyArIChsaW5lLmNsYXNzTmFtZSA/ICcgY2xhc3M9IicgKyBsaW5lLmNsYXNzTmFtZSArICciJyA6ICcnKSArICc+JwotICAgICAgICAgICAgICArIGxpbmUuZ2V0SFRNTChtYWtlVGFiKSArICc8L3ByZT4nOwotICAgICAgICAgICAgLy8gS2x1ZGdlIHRvIG1ha2Ugc3VyZSB0aGUgc3R5bGVkIGVsZW1lbnQgbGllcyBiZWhpbmQgdGhlIHNlbGVjdGlvbiAoYnkgei1pbmRleCkKLSAgICAgICAgICAgIGlmIChsaW5lLmJnQ2xhc3NOYW1lKQotICAgICAgICAgICAgICBodG1sID0gJzxkaXYgc3R5bGU9InBvc2l0aW9uOiByZWxhdGl2ZSI+PHByZSBjbGFzcz0iJyArIGxpbmUuYmdDbGFzc05hbWUgKwotICAgICAgICAgICAgICAnIiBzdHlsZT0icG9zaXRpb246IGFic29sdXRlOyBsZWZ0OiAwOyByaWdodDogMDsgdG9wOiAwOyBib3R0b206IDA7IHotaW5kZXg6IC0yIj4mIzE2MDs8L3ByZT4nICsgaHRtbCArICI8L2Rpdj4iOwotICAgICAgICAgIH0KLSAgICAgICAgICBzY3JhdGNoLmlubmVySFRNTCA9IGh0bWw7Ci0gICAgICAgICAgbGluZURpdi5pbnNlcnRCZWZvcmUoc2NyYXRjaC5maXJzdENoaWxkLCBjdXJOb2RlKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICBjdXJOb2RlID0gY3VyTm9kZS5uZXh0U2libGluZzsKLSAgICAgICAgfQotICAgICAgICArK2o7Ci0gICAgICB9KTsKLSAgICB9Ci0KLSAgICBmdW5jdGlvbiB1cGRhdGVHdXR0ZXIoKSB7Ci0gICAgICBpZiAoIW9wdGlvbnMuZ3V0dGVyICYmICFvcHRpb25zLmxpbmVOdW1iZXJzKSByZXR1cm47Ci0gICAgICB2YXIgaFRleHQgPSBtb3Zlci5vZmZzZXRIZWlnaHQsIGhFZGl0b3IgPSBzY3JvbGxlci5jbGllbnRIZWlnaHQ7Ci0gICAgICBndXR0ZXIuc3R5bGUuaGVpZ2h0ID0gKGhUZXh0IC0gaEVkaXRvciA8IDIgPyBoRWRpdG9yIDogaFRleHQpICsgInB4IjsKLSAgICAgIHZhciBodG1sID0gW10sIGkgPSBzaG93aW5nRnJvbSwgbm9ybWFsTm9kZTsKLSAgICAgIGRvYy5pdGVyKHNob3dpbmdGcm9tLCBNYXRoLm1heChzaG93aW5nVG8sIHNob3dpbmdGcm9tICsgMSksIGZ1bmN0aW9uKGxpbmUpIHsKLSAgICAgICAgaWYgKGxpbmUuaGlkZGVuKSB7Ci0gICAgICAgICAgaHRtbC5wdXNoKCI8cHJlPjwvcHJlPiIpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgIHZhciBtYXJrZXIgPSBsaW5lLmd1dHRlck1hcmtlcjsKLSAgICAgICAgICB2YXIgdGV4dCA9IG9wdGlvbnMubGluZU51bWJlcnMgPyBpICsgb3B0aW9ucy5maXJzdExpbmVOdW1iZXIgOiBudWxsOwotICAgICAgICAgIGlmIChtYXJrZXIgJiYgbWFya2VyLnRleHQpCi0gICAgICAgICAgICB0ZXh0ID0gbWFya2VyLnRleHQucmVwbGFjZSgiJU4lIiwgdGV4dCAhPSBudWxsID8gdGV4dCA6ICIiKTsKLSAgICAgICAgICBlbHNlIGlmICh0ZXh0ID09IG51bGwpCi0gICAgICAgICAgICB0ZXh0ID0gIlx1MDBhMCI7Ci0gICAgICAgICAgaHRtbC5wdXNoKChtYXJrZXIgJiYgbWFya2VyLnN0eWxlID8gJzxwcmUgY2xhc3M9IicgKyBtYXJrZXIuc3R5bGUgKyAnIj4nIDogIjxwcmU+IiksIHRleHQpOwotICAgICAgICAgIGZvciAodmFyIGogPSAxOyBqIDwgbGluZS5oZWlnaHQ7ICsraikgaHRtbC5wdXNoKCI8YnIvPiYjMTYwOyIpOwotICAgICAgICAgIGh0bWwucHVzaCgiPC9wcmU+Iik7Ci0gICAgICAgICAgaWYgKCFtYXJrZXIpIG5vcm1hbE5vZGUgPSBpOwotICAgICAgICB9Ci0gICAgICAgICsraTsKLSAgICAgIH0pOwotICAgICAgZ3V0dGVyLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7Ci0gICAgICBndXR0ZXJUZXh0LmlubmVySFRNTCA9IGh0bWwuam9pbigiIik7Ci0gICAgICAvLyBNYWtlIHN1cmUgc2Nyb2xsaW5nIGRvZXNuJ3QgY2F1c2UgbnVtYmVyIGd1dHRlciBzaXplIHRvIHBvcAotICAgICAgaWYgKG5vcm1hbE5vZGUgIT0gbnVsbCkgewotICAgICAgICB2YXIgbm9kZSA9IGd1dHRlclRleHQuY2hpbGROb2Rlc1tub3JtYWxOb2RlIC0gc2hvd2luZ0Zyb21dOwotICAgICAgICB2YXIgbWlud2lkdGggPSBTdHJpbmcoZG9jLnNpemUpLmxlbmd0aCwgdmFsID0gZWx0VGV4dChub2RlKSwgcGFkID0gIiI7Ci0gICAgICAgIHdoaWxlICh2YWwubGVuZ3RoICsgcGFkLmxlbmd0aCA8IG1pbndpZHRoKSBwYWQgKz0gIlx1MDBhMCI7Ci0gICAgICAgIGlmIChwYWQpIG5vZGUuaW5zZXJ0QmVmb3JlKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHBhZCksIG5vZGUuZmlyc3RDaGlsZCk7Ci0gICAgICB9Ci0gICAgICBndXR0ZXIuc3R5bGUuZGlzcGxheSA9ICIiOwotICAgICAgdmFyIHJlc2l6ZWQgPSBNYXRoLmFicygocGFyc2VJbnQobGluZVNwYWNlLnN0eWxlLm1hcmdpbkxlZnQpIHx8IDApIC0gZ3V0dGVyLm9mZnNldFdpZHRoKSA+IDI7Ci0gICAgICBsaW5lU3BhY2Uuc3R5bGUubWFyZ2luTGVmdCA9IGd1dHRlci5vZmZzZXRXaWR0aCArICJweCI7Ci0gICAgICBndXR0ZXJEaXJ0eSA9IGZhbHNlOwotICAgICAgcmV0dXJuIHJlc2l6ZWQ7Ci0gICAgfQotICAgIGZ1bmN0aW9uIHVwZGF0ZVNlbGVjdGlvbigpIHsKLSAgICAgIHZhciBjb2xsYXBzZWQgPSBwb3NFcShzZWwuZnJvbSwgc2VsLnRvKTsKLSAgICAgIHZhciBmcm9tUG9zID0gbG9jYWxDb29yZHMoc2VsLmZyb20sIHRydWUpOwotICAgICAgdmFyIHRvUG9zID0gY29sbGFwc2VkID8gZnJvbVBvcyA6IGxvY2FsQ29vcmRzKHNlbC50bywgdHJ1ZSk7Ci0gICAgICB2YXIgaGVhZFBvcyA9IHNlbC5pbnZlcnRlZCA/IGZyb21Qb3MgOiB0b1BvcywgdGggPSB0ZXh0SGVpZ2h0KCk7Ci0gICAgICB2YXIgd3JhcE9mZiA9IGVsdE9mZnNldCh3cmFwcGVyKSwgbGluZU9mZiA9IGVsdE9mZnNldChsaW5lRGl2KTsKLSAgICAgIGlucHV0RGl2LnN0eWxlLnRvcCA9IE1hdGgubWF4KDAsIE1hdGgubWluKHNjcm9sbGVyLm9mZnNldEhlaWdodCwgaGVhZFBvcy55ICsgbGluZU9mZi50b3AgLSB3cmFwT2ZmLnRvcCkpICsgInB4IjsKLSAgICAgIGlucHV0RGl2LnN0eWxlLmxlZnQgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihzY3JvbGxlci5vZmZzZXRXaWR0aCwgaGVhZFBvcy54ICsgbGluZU9mZi5sZWZ0IC0gd3JhcE9mZi5sZWZ0KSkgKyAicHgiOwotICAgICAgaWYgKGNvbGxhcHNlZCkgewotICAgICAgICBjdXJzb3Iuc3R5bGUudG9wID0gaGVhZFBvcy55ICsgInB4IjsKLSAgICAgICAgY3Vyc29yLnN0eWxlLmxlZnQgPSAob3B0aW9ucy5saW5lV3JhcHBpbmcgPyBNYXRoLm1pbihoZWFkUG9zLngsIGxpbmVTcGFjZS5vZmZzZXRXaWR0aCkgOiBoZWFkUG9zLngpICsgInB4IjsKLSAgICAgICAgY3Vyc29yLnN0eWxlLmRpc3BsYXkgPSAiIjsKLSAgICAgICAgc2VsZWN0aW9uRGl2LnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7Ci0gICAgICB9IGVsc2UgewotICAgICAgICB2YXIgc2FtZUxpbmUgPSBmcm9tUG9zLnkgPT0gdG9Qb3MueSwgaHRtbCA9ICIiOwotICAgICAgICB2YXIgY2xpZW50V2lkdGggPSBsaW5lU3BhY2UuY2xpZW50V2lkdGggfHwgbGluZVNwYWNlLm9mZnNldFdpZHRoOwotICAgICAgICB2YXIgY2xpZW50SGVpZ2h0ID0gbGluZVNwYWNlLmNsaWVudEhlaWdodCB8fCBsaW5lU3BhY2Uub2Zmc2V0SGVpZ2h0OwotICAgICAgICBmdW5jdGlvbiBhZGQobGVmdCwgdG9wLCByaWdodCwgaGVpZ2h0KSB7Ci0gICAgICAgICAgdmFyIHJzdHlsZSA9IHF1aXJrc01vZGUgPyAid2lkdGg6ICIgKyAoIXJpZ2h0ID8gY2xpZW50V2lkdGggOiBjbGllbnRXaWR0aCAtIHJpZ2h0IC0gbGVmdCkgKyAicHgiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAicmlnaHQ6ICIgKyByaWdodCArICJweCI7Ci0gICAgICAgICAgaHRtbCArPSAnPGRpdiBjbGFzcz0iQ29kZU1pcnJvci1zZWxlY3RlZCIgc3R5bGU9InBvc2l0aW9uOiBhYnNvbHV0ZTsgbGVmdDogJyArIGxlZnQgKwotICAgICAgICAgICAgJ3B4OyB0b3A6ICcgKyB0b3AgKyAncHg7ICcgKyByc3R5bGUgKyAnOyBoZWlnaHQ6ICcgKyBoZWlnaHQgKyAncHgiPjwvZGl2Pic7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHNlbC5mcm9tLmNoICYmIGZyb21Qb3MueSA+PSAwKSB7Ci0gICAgICAgICAgdmFyIHJpZ2h0ID0gc2FtZUxpbmUgPyBjbGllbnRXaWR0aCAtIHRvUG9zLnggOiAwOwotICAgICAgICAgIGFkZChmcm9tUG9zLngsIGZyb21Qb3MueSwgcmlnaHQsIHRoKTsKLSAgICAgICAgfQotICAgICAgICB2YXIgbWlkZGxlU3RhcnQgPSBNYXRoLm1heCgwLCBmcm9tUG9zLnkgKyAoc2VsLmZyb20uY2ggPyB0aCA6IDApKTsKLSAgICAgICAgdmFyIG1pZGRsZUhlaWdodCA9IE1hdGgubWluKHRvUG9zLnksIGNsaWVudEhlaWdodCkgLSBtaWRkbGVTdGFydDsKLSAgICAgICAgaWYgKG1pZGRsZUhlaWdodCA+IDAuMiAqIHRoKQotICAgICAgICAgIGFkZCgwLCBtaWRkbGVTdGFydCwgMCwgbWlkZGxlSGVpZ2h0KTsKLSAgICAgICAgaWYgKCghc2FtZUxpbmUgfHwgIXNlbC5mcm9tLmNoKSAmJiB0b1Bvcy55IDwgY2xpZW50SGVpZ2h0IC0gLjUgKiB0aCkKLSAgICAgICAgICBhZGQoMCwgdG9Qb3MueSwgY2xpZW50V2lkdGggLSB0b1Bvcy54LCB0aCk7Ci0gICAgICAgIHNlbGVjdGlvbkRpdi5pbm5lckhUTUwgPSBodG1sOwotICAgICAgICBjdXJzb3Iuc3R5bGUuZGlzcGxheSA9ICJub25lIjsKLSAgICAgICAgc2VsZWN0aW9uRGl2LnN0eWxlLmRpc3BsYXkgPSAiIjsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBmdW5jdGlvbiBzZXRTaGlmdCh2YWwpIHsKLSAgICAgIGlmICh2YWwpIHNoaWZ0U2VsZWN0aW5nID0gc2hpZnRTZWxlY3RpbmcgfHwgKHNlbC5pbnZlcnRlZCA/IHNlbC50byA6IHNlbC5mcm9tKTsKLSAgICAgIGVsc2Ugc2hpZnRTZWxlY3RpbmcgPSBudWxsOwotICAgIH0KLSAgICBmdW5jdGlvbiBzZXRTZWxlY3Rpb25Vc2VyKGZyb20sIHRvKSB7Ci0gICAgICB2YXIgc2ggPSBzaGlmdFNlbGVjdGluZyAmJiBjbGlwUG9zKHNoaWZ0U2VsZWN0aW5nKTsKLSAgICAgIGlmIChzaCkgewotICAgICAgICBpZiAocG9zTGVzcyhzaCwgZnJvbSkpIGZyb20gPSBzaDsKLSAgICAgICAgZWxzZSBpZiAocG9zTGVzcyh0bywgc2gpKSB0byA9IHNoOwotICAgICAgfQotICAgICAgc2V0U2VsZWN0aW9uKGZyb20sIHRvKTsKLSAgICAgIHVzZXJTZWxDaGFuZ2UgPSB0cnVlOwotICAgIH0KLSAgICAvLyBVcGRhdGUgdGhlIHNlbGVjdGlvbi4gTGFzdCB0d28gYXJncyBhcmUgb25seSB1c2VkIGJ5Ci0gICAgLy8gdXBkYXRlTGluZXMsIHNpbmNlIHRoZXkgaGF2ZSB0byBiZSBleHByZXNzZWQgaW4gdGhlIGxpbmUKLSAgICAvLyBudW1iZXJzIGJlZm9yZSB0aGUgdXBkYXRlLgotICAgIGZ1bmN0aW9uIHNldFNlbGVjdGlvbihmcm9tLCB0bywgb2xkRnJvbSwgb2xkVG8pIHsKLSAgICAgIGdvYWxDb2x1bW4gPSBudWxsOwotICAgICAgaWYgKG9sZEZyb20gPT0gbnVsbCkge29sZEZyb20gPSBzZWwuZnJvbS5saW5lOyBvbGRUbyA9IHNlbC50by5saW5lO30KLSAgICAgIGlmIChwb3NFcShzZWwuZnJvbSwgZnJvbSkgJiYgcG9zRXEoc2VsLnRvLCB0bykpIHJldHVybjsKLSAgICAgIGlmIChwb3NMZXNzKHRvLCBmcm9tKSkge3ZhciB0bXAgPSB0bzsgdG8gPSBmcm9tOyBmcm9tID0gdG1wO30KLQotICAgICAgLy8gU2tpcCBvdmVyIGhpZGRlbiBsaW5lcy4KLSAgICAgIGlmIChmcm9tLmxpbmUgIT0gb2xkRnJvbSkgewotICAgICAgICB2YXIgZnJvbTEgPSBza2lwSGlkZGVuKGZyb20sIG9sZEZyb20sIHNlbC5mcm9tLmNoKTsKLSAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gbm9uLWhpZGRlbiBsaW5lIGxlZnQsIGZvcmNlIHZpc2liaWxpdHkgb24gY3VycmVudCBsaW5lCi0gICAgICAgIGlmICghZnJvbTEpIHNldExpbmVIaWRkZW4oZnJvbS5saW5lLCBmYWxzZSk7Ci0gICAgICAgIGVsc2UgZnJvbSA9IGZyb20xOwotICAgICAgfQotICAgICAgaWYgKHRvLmxpbmUgIT0gb2xkVG8pIHRvID0gc2tpcEhpZGRlbih0bywgb2xkVG8sIHNlbC50by5jaCk7Ci0KLSAgICAgIGlmIChwb3NFcShmcm9tLCB0bykpIHNlbC5pbnZlcnRlZCA9IGZhbHNlOwotICAgICAgZWxzZSBpZiAocG9zRXEoZnJvbSwgc2VsLnRvKSkgc2VsLmludmVydGVkID0gZmFsc2U7Ci0gICAgICBlbHNlIGlmIChwb3NFcSh0bywgc2VsLmZyb20pKSBzZWwuaW52ZXJ0ZWQgPSB0cnVlOwotCi0gICAgICBpZiAob3B0aW9ucy5hdXRvQ2xlYXJFbXB0eUxpbmVzICYmIHBvc0VxKHNlbC5mcm9tLCBzZWwudG8pKSB7Ci0gICAgICAgIHZhciBoZWFkID0gc2VsLmludmVydGVkID8gZnJvbSA6IHRvOwotICAgICAgICBpZiAoaGVhZC5saW5lICE9IHNlbC5mcm9tLmxpbmUgJiYgc2VsLmZyb20ubGluZSA8IGRvYy5zaXplKSB7Ci0gICAgICAgICAgdmFyIG9sZExpbmUgPSBnZXRMaW5lKHNlbC5mcm9tLmxpbmUpOwotICAgICAgICAgIGlmICgvXlxzKyQvLnRlc3Qob2xkTGluZS50ZXh0KSkKLSAgICAgICAgICAgIHNldFRpbWVvdXQob3BlcmF0aW9uKGZ1bmN0aW9uKCkgewotICAgICAgICAgICAgICBpZiAob2xkTGluZS5wYXJlbnQgJiYgL15ccyskLy50ZXN0KG9sZExpbmUudGV4dCkpIHsKLSAgICAgICAgICAgICAgICB2YXIgbm8gPSBsaW5lTm8ob2xkTGluZSk7Ci0gICAgICAgICAgICAgICAgcmVwbGFjZVJhbmdlKCIiLCB7bGluZTogbm8sIGNoOiAwfSwge2xpbmU6IG5vLCBjaDogb2xkTGluZS50ZXh0Lmxlbmd0aH0pOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9LCAxMCkpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIHNlbC5mcm9tID0gZnJvbTsgc2VsLnRvID0gdG87Ci0gICAgICBzZWxlY3Rpb25DaGFuZ2VkID0gdHJ1ZTsKLSAgICB9Ci0gICAgZnVuY3Rpb24gc2tpcEhpZGRlbihwb3MsIG9sZExpbmUsIG9sZENoKSB7Ci0gICAgICBmdW5jdGlvbiBnZXROb25IaWRkZW4oZGlyKSB7Ci0gICAgICAgIHZhciBsTm8gPSBwb3MubGluZSArIGRpciwgZW5kID0gZGlyID09IDEgPyBkb2Muc2l6ZSA6IC0xOwotICAgICAgICB3aGlsZSAobE5vICE9IGVuZCkgewotICAgICAgICAgIHZhciBsaW5lID0gZ2V0TGluZShsTm8pOwotICAgICAgICAgIGlmICghbGluZS5oaWRkZW4pIHsKLSAgICAgICAgICAgIHZhciBjaCA9IHBvcy5jaDsKLSAgICAgICAgICAgIGlmICh0b0VuZCB8fCBjaCA+IG9sZENoIHx8IGNoID4gbGluZS50ZXh0Lmxlbmd0aCkgY2ggPSBsaW5lLnRleHQubGVuZ3RoOwotICAgICAgICAgICAgcmV0dXJuIHtsaW5lOiBsTm8sIGNoOiBjaH07Ci0gICAgICAgICAgfQotICAgICAgICAgIGxObyArPSBkaXI7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIHZhciBsaW5lID0gZ2V0TGluZShwb3MubGluZSk7Ci0gICAgICB2YXIgdG9FbmQgPSBwb3MuY2ggPT0gbGluZS50ZXh0Lmxlbmd0aCAmJiBwb3MuY2ggIT0gb2xkQ2g7Ci0gICAgICBpZiAoIWxpbmUuaGlkZGVuKSByZXR1cm4gcG9zOwotICAgICAgaWYgKHBvcy5saW5lID49IG9sZExpbmUpIHJldHVybiBnZXROb25IaWRkZW4oMSkgfHwgZ2V0Tm9uSGlkZGVuKC0xKTsKLSAgICAgIGVsc2UgcmV0dXJuIGdldE5vbkhpZGRlbigtMSkgfHwgZ2V0Tm9uSGlkZGVuKDEpOwotICAgIH0KLSAgICBmdW5jdGlvbiBzZXRDdXJzb3IobGluZSwgY2gsIHVzZXIpIHsKLSAgICAgIHZhciBwb3MgPSBjbGlwUG9zKHtsaW5lOiBsaW5lLCBjaDogY2ggfHwgMH0pOwotICAgICAgKHVzZXIgPyBzZXRTZWxlY3Rpb25Vc2VyIDogc2V0U2VsZWN0aW9uKShwb3MsIHBvcyk7Ci0gICAgfQotCi0gICAgZnVuY3Rpb24gY2xpcExpbmUobikge3JldHVybiBNYXRoLm1heCgwLCBNYXRoLm1pbihuLCBkb2Muc2l6ZS0xKSk7fQotICAgIGZ1bmN0aW9uIGNsaXBQb3MocG9zKSB7Ci0gICAgICBpZiAocG9zLmxpbmUgPCAwKSByZXR1cm4ge2xpbmU6IDAsIGNoOiAwfTsKLSAgICAgIGlmIChwb3MubGluZSA+PSBkb2Muc2l6ZSkgcmV0dXJuIHtsaW5lOiBkb2Muc2l6ZS0xLCBjaDogZ2V0TGluZShkb2Muc2l6ZS0xKS50ZXh0Lmxlbmd0aH07Ci0gICAgICB2YXIgY2ggPSBwb3MuY2gsIGxpbmVsZW4gPSBnZXRMaW5lKHBvcy5saW5lKS50ZXh0Lmxlbmd0aDsKLSAgICAgIGlmIChjaCA9PSBudWxsIHx8IGNoID4gbGluZWxlbikgcmV0dXJuIHtsaW5lOiBwb3MubGluZSwgY2g6IGxpbmVsZW59OwotICAgICAgZWxzZSBpZiAoY2ggPCAwKSByZXR1cm4ge2xpbmU6IHBvcy5saW5lLCBjaDogMH07Ci0gICAgICBlbHNlIHJldHVybiBwb3M7Ci0gICAgfQotCi0gICAgZnVuY3Rpb24gZmluZFBvc0goZGlyLCB1bml0KSB7Ci0gICAgICB2YXIgZW5kID0gc2VsLmludmVydGVkID8gc2VsLmZyb20gOiBzZWwudG8sIGxpbmUgPSBlbmQubGluZSwgY2ggPSBlbmQuY2g7Ci0gICAgICB2YXIgbGluZU9iaiA9IGdldExpbmUobGluZSk7Ci0gICAgICBmdW5jdGlvbiBmaW5kTmV4dExpbmUoKSB7Ci0gICAgICAgIGZvciAodmFyIGwgPSBsaW5lICsgZGlyLCBlID0gZGlyIDwgMCA/IC0xIDogZG9jLnNpemU7IGwgIT0gZTsgbCArPSBkaXIpIHsKLSAgICAgICAgICB2YXIgbG8gPSBnZXRMaW5lKGwpOwotICAgICAgICAgIGlmICghbG8uaGlkZGVuKSB7IGxpbmUgPSBsOyBsaW5lT2JqID0gbG87IHJldHVybiB0cnVlOyB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGZ1bmN0aW9uIG1vdmVPbmNlKGJvdW5kVG9MaW5lKSB7Ci0gICAgICAgIGlmIChjaCA9PSAoZGlyIDwgMCA/IDAgOiBsaW5lT2JqLnRleHQubGVuZ3RoKSkgewotICAgICAgICAgIGlmICghYm91bmRUb0xpbmUgJiYgZmluZE5leHRMaW5lKCkpIGNoID0gZGlyIDwgMCA/IGxpbmVPYmoudGV4dC5sZW5ndGggOiAwOwotICAgICAgICAgIGVsc2UgcmV0dXJuIGZhbHNlOwotICAgICAgICB9IGVsc2UgY2ggKz0gZGlyOwotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgIH0KLSAgICAgIGlmICh1bml0ID09ICJjaGFyIikgbW92ZU9uY2UoKTsKLSAgICAgIGVsc2UgaWYgKHVuaXQgPT0gImNvbHVtbiIpIG1vdmVPbmNlKHRydWUpOwotICAgICAgZWxzZSBpZiAodW5pdCA9PSAid29yZCIpIHsKLSAgICAgICAgdmFyIHNhd1dvcmQgPSBmYWxzZTsKLSAgICAgICAgZm9yICg7OykgewotICAgICAgICAgIGlmIChkaXIgPCAwKSBpZiAoIW1vdmVPbmNlKCkpIGJyZWFrOwotICAgICAgICAgIGlmIChpc1dvcmRDaGFyKGxpbmVPYmoudGV4dC5jaGFyQXQoY2gpKSkgc2F3V29yZCA9IHRydWU7Ci0gICAgICAgICAgZWxzZSBpZiAoc2F3V29yZCkge2lmIChkaXIgPCAwKSB7ZGlyID0gMTsgbW92ZU9uY2UoKTt9IGJyZWFrO30KLSAgICAgICAgICBpZiAoZGlyID4gMCkgaWYgKCFtb3ZlT25jZSgpKSBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgcmV0dXJuIHtsaW5lOiBsaW5lLCBjaDogY2h9OwotICAgIH0KLSAgICBmdW5jdGlvbiBtb3ZlSChkaXIsIHVuaXQpIHsKLSAgICAgIHZhciBwb3MgPSBkaXIgPCAwID8gc2VsLmZyb20gOiBzZWwudG87Ci0gICAgICBpZiAoc2hpZnRTZWxlY3RpbmcgfHwgcG9zRXEoc2VsLmZyb20sIHNlbC50bykpIHBvcyA9IGZpbmRQb3NIKGRpciwgdW5pdCk7Ci0gICAgICBzZXRDdXJzb3IocG9zLmxpbmUsIHBvcy5jaCwgdHJ1ZSk7Ci0gICAgfQotICAgIGZ1bmN0aW9uIGRlbGV0ZUgoZGlyLCB1bml0KSB7Ci0gICAgICBpZiAoIXBvc0VxKHNlbC5mcm9tLCBzZWwudG8pKSByZXBsYWNlUmFuZ2UoIiIsIHNlbC5mcm9tLCBzZWwudG8pOwotICAgICAgZWxzZSBpZiAoZGlyIDwgMCkgcmVwbGFjZVJhbmdlKCIiLCBmaW5kUG9zSChkaXIsIHVuaXQpLCBzZWwudG8pOwotICAgICAgZWxzZSByZXBsYWNlUmFuZ2UoIiIsIHNlbC5mcm9tLCBmaW5kUG9zSChkaXIsIHVuaXQpKTsKLSAgICAgIHVzZXJTZWxDaGFuZ2UgPSB0cnVlOwotICAgIH0KLSAgICB2YXIgZ29hbENvbHVtbiA9IG51bGw7Ci0gICAgZnVuY3Rpb24gbW92ZVYoZGlyLCB1bml0KSB7Ci0gICAgICB2YXIgZGlzdCA9IDAsIHBvcyA9IGxvY2FsQ29vcmRzKHNlbC5pbnZlcnRlZCA/IHNlbC5mcm9tIDogc2VsLnRvLCB0cnVlKTsKLSAgICAgIGlmIChnb2FsQ29sdW1uICE9IG51bGwpIHBvcy54ID0gZ29hbENvbHVtbjsKLSAgICAgIGlmICh1bml0ID09ICJwYWdlIikgZGlzdCA9IE1hdGgubWluKHNjcm9sbGVyLmNsaWVudEhlaWdodCwgd2luZG93LmlubmVySGVpZ2h0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQpOwotICAgICAgZWxzZSBpZiAodW5pdCA9PSAibGluZSIpIGRpc3QgPSB0ZXh0SGVpZ2h0KCk7Ci0gICAgICB2YXIgdGFyZ2V0ID0gY29vcmRzQ2hhcihwb3MueCwgcG9zLnkgKyBkaXN0ICogZGlyICsgMik7Ci0gICAgICBpZiAodW5pdCA9PSAicGFnZSIpIHNjcm9sbGVyLnNjcm9sbFRvcCArPSBsb2NhbENvb3Jkcyh0YXJnZXQsIHRydWUpLnkgLSBwb3MueTsKLSAgICAgIHNldEN1cnNvcih0YXJnZXQubGluZSwgdGFyZ2V0LmNoLCB0cnVlKTsKLSAgICAgIGdvYWxDb2x1bW4gPSBwb3MueDsKLSAgICB9Ci0KLSAgICBmdW5jdGlvbiBzZWxlY3RXb3JkQXQocG9zKSB7Ci0gICAgICB2YXIgbGluZSA9IGdldExpbmUocG9zLmxpbmUpLnRleHQ7Ci0gICAgICB2YXIgc3RhcnQgPSBwb3MuY2gsIGVuZCA9IHBvcy5jaDsKLSAgICAgIHdoaWxlIChzdGFydCA+IDAgJiYgaXNXb3JkQ2hhcihsaW5lLmNoYXJBdChzdGFydCAtIDEpKSkgLS1zdGFydDsKLSAgICAgIHdoaWxlIChlbmQgPCBsaW5lLmxlbmd0aCAmJiBpc1dvcmRDaGFyKGxpbmUuY2hhckF0KGVuZCkpKSArK2VuZDsKLSAgICAgIHNldFNlbGVjdGlvblVzZXIoe2xpbmU6IHBvcy5saW5lLCBjaDogc3RhcnR9LCB7bGluZTogcG9zLmxpbmUsIGNoOiBlbmR9KTsKLSAgICB9Ci0gICAgZnVuY3Rpb24gc2VsZWN0TGluZShsaW5lKSB7Ci0gICAgICBzZXRTZWxlY3Rpb25Vc2VyKHtsaW5lOiBsaW5lLCBjaDogMH0sIGNsaXBQb3Moe2xpbmU6IGxpbmUgKyAxLCBjaDogMH0pKTsKLSAgICB9Ci0gICAgZnVuY3Rpb24gaW5kZW50U2VsZWN0ZWQobW9kZSkgewotICAgICAgaWYgKHBvc0VxKHNlbC5mcm9tLCBzZWwudG8pKSByZXR1cm4gaW5kZW50TGluZShzZWwuZnJvbS5saW5lLCBtb2RlKTsKLSAgICAgIHZhciBlID0gc2VsLnRvLmxpbmUgLSAoc2VsLnRvLmNoID8gMCA6IDEpOwotICAgICAgZm9yICh2YXIgaSA9IHNlbC5mcm9tLmxpbmU7IGkgPD0gZTsgKytpKSBpbmRlbnRMaW5lKGksIG1vZGUpOwotICAgIH0KLQotICAgIGZ1bmN0aW9uIGluZGVudExpbmUobiwgaG93KSB7Ci0gICAgICBpZiAoIWhvdykgaG93ID0gImFkZCI7Ci0gICAgICBpZiAoaG93ID09ICJzbWFydCIpIHsKLSAgICAgICAgaWYgKCFtb2RlLmluZGVudCkgaG93ID0gInByZXYiOwotICAgICAgICBlbHNlIHZhciBzdGF0ZSA9IGdldFN0YXRlQmVmb3JlKG4pOwotICAgICAgfQotCi0gICAgICB2YXIgbGluZSA9IGdldExpbmUobiksIGN1clNwYWNlID0gbGluZS5pbmRlbnRhdGlvbihvcHRpb25zLnRhYlNpemUpLAotICAgICAgICAgIGN1clNwYWNlU3RyaW5nID0gbGluZS50ZXh0Lm1hdGNoKC9eXHMqLylbMF0sIGluZGVudGF0aW9uOwotICAgICAgaWYgKGhvdyA9PSAicHJldiIpIHsKLSAgICAgICAgaWYgKG4pIGluZGVudGF0aW9uID0gZ2V0TGluZShuLTEpLmluZGVudGF0aW9uKG9wdGlvbnMudGFiU2l6ZSk7Ci0gICAgICAgIGVsc2UgaW5kZW50YXRpb24gPSAwOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoaG93ID09ICJzbWFydCIpIGluZGVudGF0aW9uID0gbW9kZS5pbmRlbnQoc3RhdGUsIGxpbmUudGV4dC5zbGljZShjdXJTcGFjZVN0cmluZy5sZW5ndGgpLCBsaW5lLnRleHQpOwotICAgICAgZWxzZSBpZiAoaG93ID09ICJhZGQiKSBpbmRlbnRhdGlvbiA9IGN1clNwYWNlICsgb3B0aW9ucy5pbmRlbnRVbml0OwotICAgICAgZWxzZSBpZiAoaG93ID09ICJzdWJ0cmFjdCIpIGluZGVudGF0aW9uID0gY3VyU3BhY2UgLSBvcHRpb25zLmluZGVudFVuaXQ7Ci0gICAgICBpbmRlbnRhdGlvbiA9IE1hdGgubWF4KDAsIGluZGVudGF0aW9uKTsKLSAgICAgIHZhciBkaWZmID0gaW5kZW50YXRpb24gLSBjdXJTcGFjZTsKLQotICAgICAgaWYgKCFkaWZmKSB7Ci0gICAgICAgIGlmIChzZWwuZnJvbS5saW5lICE9IG4gJiYgc2VsLnRvLmxpbmUgIT0gbikgcmV0dXJuOwotICAgICAgICB2YXIgaW5kZW50U3RyaW5nID0gY3VyU3BhY2VTdHJpbmc7Ci0gICAgICB9Ci0gICAgICBlbHNlIHsKLSAgICAgICAgdmFyIGluZGVudFN0cmluZyA9ICIiLCBwb3MgPSAwOwotICAgICAgICBpZiAob3B0aW9ucy5pbmRlbnRXaXRoVGFicykKLSAgICAgICAgICBmb3IgKHZhciBpID0gTWF0aC5mbG9vcihpbmRlbnRhdGlvbiAvIG9wdGlvbnMudGFiU2l6ZSk7IGk7IC0taSkge3BvcyArPSBvcHRpb25zLnRhYlNpemU7IGluZGVudFN0cmluZyArPSAiXHQiO30KLSAgICAgICAgd2hpbGUgKHBvcyA8IGluZGVudGF0aW9uKSB7Kytwb3M7IGluZGVudFN0cmluZyArPSAiICI7fQotICAgICAgfQotCi0gICAgICByZXBsYWNlUmFuZ2UoaW5kZW50U3RyaW5nLCB7bGluZTogbiwgY2g6IDB9LCB7bGluZTogbiwgY2g6IGN1clNwYWNlU3RyaW5nLmxlbmd0aH0pOwotICAgIH0KLQotICAgIGZ1bmN0aW9uIGxvYWRNb2RlKCkgewotICAgICAgbW9kZSA9IENvZGVNaXJyb3IuZ2V0TW9kZShvcHRpb25zLCBvcHRpb25zLm1vZGUpOwotICAgICAgZG9jLml0ZXIoMCwgZG9jLnNpemUsIGZ1bmN0aW9uKGxpbmUpIHsgbGluZS5zdGF0ZUFmdGVyID0gbnVsbDsgfSk7Ci0gICAgICB3b3JrID0gWzBdOwotICAgICAgc3RhcnRXb3JrZXIoKTsKLSAgICB9Ci0gICAgZnVuY3Rpb24gZ3V0dGVyQ2hhbmdlZCgpIHsKLSAgICAgIHZhciB2aXNpYmxlID0gb3B0aW9ucy5ndXR0ZXIgfHwgb3B0aW9ucy5saW5lTnVtYmVyczsKLSAgICAgIGd1dHRlci5zdHlsZS5kaXNwbGF5ID0gdmlzaWJsZSA/ICIiIDogIm5vbmUiOwotICAgICAgaWYgKHZpc2libGUpIGd1dHRlckRpcnR5ID0gdHJ1ZTsKLSAgICAgIGVsc2UgbGluZURpdi5wYXJlbnROb2RlLnN0eWxlLm1hcmdpbkxlZnQgPSAwOwotICAgIH0KLSAgICBmdW5jdGlvbiB3cmFwcGluZ0NoYW5nZWQoZnJvbSwgdG8pIHsKLSAgICAgIGlmIChvcHRpb25zLmxpbmVXcmFwcGluZykgewotICAgICAgICB3cmFwcGVyLmNsYXNzTmFtZSArPSAiIENvZGVNaXJyb3Itd3JhcCI7Ci0gICAgICAgIHZhciBwZXJMaW5lID0gc2Nyb2xsZXIuY2xpZW50V2lkdGggLyBjaGFyV2lkdGgoKSAtIDM7Ci0gICAgICAgIGRvYy5pdGVyKDAsIGRvYy5zaXplLCBmdW5jdGlvbihsaW5lKSB7Ci0gICAgICAgICAgaWYgKGxpbmUuaGlkZGVuKSByZXR1cm47Ci0gICAgICAgICAgdmFyIGd1ZXNzID0gTWF0aC5jZWlsKGxpbmUudGV4dC5sZW5ndGggLyBwZXJMaW5lKSB8fCAxOwotICAgICAgICAgIGlmIChndWVzcyAhPSAxKSB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIGd1ZXNzKTsKLSAgICAgICAgfSk7Ci0gICAgICAgIGxpbmVTcGFjZS5zdHlsZS53aWR0aCA9IGNvZGUuc3R5bGUud2lkdGggPSAiIjsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIHdyYXBwZXIuY2xhc3NOYW1lID0gd3JhcHBlci5jbGFzc05hbWUucmVwbGFjZSgiIENvZGVNaXJyb3Itd3JhcCIsICIiKTsKLSAgICAgICAgbWF4V2lkdGggPSBudWxsOyBtYXhMaW5lID0gIiI7Ci0gICAgICAgIGRvYy5pdGVyKDAsIGRvYy5zaXplLCBmdW5jdGlvbihsaW5lKSB7Ci0gICAgICAgICAgaWYgKGxpbmUuaGVpZ2h0ICE9IDEgJiYgIWxpbmUuaGlkZGVuKSB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIDEpOwotICAgICAgICAgIGlmIChsaW5lLnRleHQubGVuZ3RoID4gbWF4TGluZS5sZW5ndGgpIG1heExpbmUgPSBsaW5lLnRleHQ7Ci0gICAgICAgIH0pOwotICAgICAgfQotICAgICAgY2hhbmdlcy5wdXNoKHtmcm9tOiAwLCB0bzogZG9jLnNpemV9KTsKLSAgICB9Ci0gICAgZnVuY3Rpb24gbWFrZVRhYihjb2wpIHsKLSAgICAgIHZhciB3ID0gb3B0aW9ucy50YWJTaXplIC0gY29sICUgb3B0aW9ucy50YWJTaXplLCBjYWNoZWQgPSB0YWJDYWNoZVt3XTsKLSAgICAgIGlmIChjYWNoZWQpIHJldHVybiBjYWNoZWQ7Ci0gICAgICBmb3IgKHZhciBzdHIgPSAnPHNwYW4gY2xhc3M9ImNtLXRhYiI+JywgaSA9IDA7IGkgPCB3OyArK2kpIHN0ciArPSAiICI7Ci0gICAgICByZXR1cm4gKHRhYkNhY2hlW3ddID0ge2h0bWw6IHN0ciArICI8L3NwYW4+Iiwgd2lkdGg6IHd9KTsKLSAgICB9Ci0gICAgZnVuY3Rpb24gdGhlbWVDaGFuZ2VkKCkgewotICAgICAgc2Nyb2xsZXIuY2xhc3NOYW1lID0gc2Nyb2xsZXIuY2xhc3NOYW1lLnJlcGxhY2UoL1xzKmNtLXMtXFMrL2csICIiKSArCi0gICAgICAgIG9wdGlvbnMudGhlbWUucmVwbGFjZSgvKF58XHMpXHMqL2csICIgY20tcy0iKTsKLSAgICB9Ci0KLSAgICBmdW5jdGlvbiBUZXh0TWFya2VyKCkgeyB0aGlzLnNldCA9IFtdOyB9Ci0gICAgVGV4dE1hcmtlci5wcm90b3R5cGUuY2xlYXIgPSBvcGVyYXRpb24oZnVuY3Rpb24oKSB7Ci0gICAgICB2YXIgbWluID0gSW5maW5pdHksIG1heCA9IC1JbmZpbml0eTsKLSAgICAgIGZvciAodmFyIGkgPSAwLCBlID0gdGhpcy5zZXQubGVuZ3RoOyBpIDwgZTsgKytpKSB7Ci0gICAgICAgIHZhciBsaW5lID0gdGhpcy5zZXRbaV0sIG1rID0gbGluZS5tYXJrZWQ7Ci0gICAgICAgIGlmICghbWsgfHwgIWxpbmUucGFyZW50KSBjb250aW51ZTsKLSAgICAgICAgdmFyIGxpbmVOID0gbGluZU5vKGxpbmUpOwotICAgICAgICBtaW4gPSBNYXRoLm1pbihtaW4sIGxpbmVOKTsgbWF4ID0gTWF0aC5tYXgobWF4LCBsaW5lTik7Ci0gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWsubGVuZ3RoOyArK2opCi0gICAgICAgICAgaWYgKG1rW2pdLm1hcmtlciA9PSB0aGlzKSBtay5zcGxpY2Uoai0tLCAxKTsKLSAgICAgIH0KLSAgICAgIGlmIChtaW4gIT0gSW5maW5pdHkpCi0gICAgICAgIGNoYW5nZXMucHVzaCh7ZnJvbTogbWluLCB0bzogbWF4ICsgMX0pOwotICAgIH0pOwotICAgIFRleHRNYXJrZXIucHJvdG90eXBlLmZpbmQgPSBmdW5jdGlvbigpIHsKLSAgICAgIHZhciBmcm9tLCB0bzsKLSAgICAgIGZvciAodmFyIGkgPSAwLCBlID0gdGhpcy5zZXQubGVuZ3RoOyBpIDwgZTsgKytpKSB7Ci0gICAgICAgIHZhciBsaW5lID0gdGhpcy5zZXRbaV0sIG1rID0gbGluZS5tYXJrZWQ7Ci0gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWsubGVuZ3RoOyArK2opIHsKLSAgICAgICAgICB2YXIgbWFyayA9IG1rW2pdOwotICAgICAgICAgIGlmIChtYXJrLm1hcmtlciA9PSB0aGlzKSB7Ci0gICAgICAgICAgICBpZiAobWFyay5mcm9tICE9IG51bGwgfHwgbWFyay50byAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgIHZhciBmb3VuZCA9IGxpbmVObyhsaW5lKTsKLSAgICAgICAgICAgICAgaWYgKGZvdW5kICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAobWFyay5mcm9tICE9IG51bGwpIGZyb20gPSB7bGluZTogZm91bmQsIGNoOiBtYXJrLmZyb219OwotICAgICAgICAgICAgICAgIGlmIChtYXJrLnRvICE9IG51bGwpIHRvID0ge2xpbmU6IGZvdW5kLCBjaDogbWFyay50b307Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIHJldHVybiB7ZnJvbTogZnJvbSwgdG86IHRvfTsKLSAgICB9OwotCi0gICAgZnVuY3Rpb24gbWFya1RleHQoZnJvbSwgdG8sIGNsYXNzTmFtZSkgewotICAgICAgZnJvbSA9IGNsaXBQb3MoZnJvbSk7IHRvID0gY2xpcFBvcyh0byk7Ci0gICAgICB2YXIgdG0gPSBuZXcgVGV4dE1hcmtlcigpOwotICAgICAgaWYgKCFwb3NMZXNzKGZyb20sIHRvKSkgcmV0dXJuIHRtOwotICAgICAgZnVuY3Rpb24gYWRkKGxpbmUsIGZyb20sIHRvLCBjbGFzc05hbWUpIHsKLSAgICAgICAgZ2V0TGluZShsaW5lKS5hZGRNYXJrKG5ldyBNYXJrZWRUZXh0KGZyb20sIHRvLCBjbGFzc05hbWUsIHRtKSk7Ci0gICAgICB9Ci0gICAgICBpZiAoZnJvbS5saW5lID09IHRvLmxpbmUpIGFkZChmcm9tLmxpbmUsIGZyb20uY2gsIHRvLmNoLCBjbGFzc05hbWUpOwotICAgICAgZWxzZSB7Ci0gICAgICAgIGFkZChmcm9tLmxpbmUsIGZyb20uY2gsIG51bGwsIGNsYXNzTmFtZSk7Ci0gICAgICAgIGZvciAodmFyIGkgPSBmcm9tLmxpbmUgKyAxLCBlID0gdG8ubGluZTsgaSA8IGU7ICsraSkKLSAgICAgICAgICBhZGQoaSwgbnVsbCwgbnVsbCwgY2xhc3NOYW1lKTsKLSAgICAgICAgYWRkKHRvLmxpbmUsIG51bGwsIHRvLmNoLCBjbGFzc05hbWUpOwotICAgICAgfQotICAgICAgY2hhbmdlcy5wdXNoKHtmcm9tOiBmcm9tLmxpbmUsIHRvOiB0by5saW5lICsgMX0pOwotICAgICAgcmV0dXJuIHRtOwotICAgIH0KLQotICAgIGZ1bmN0aW9uIHNldEJvb2ttYXJrKHBvcykgewotICAgICAgcG9zID0gY2xpcFBvcyhwb3MpOwotICAgICAgdmFyIGJtID0gbmV3IEJvb2ttYXJrKHBvcy5jaCk7Ci0gICAgICBnZXRMaW5lKHBvcy5saW5lKS5hZGRNYXJrKGJtKTsKLSAgICAgIHJldHVybiBibTsKLSAgICB9Ci0KLSAgICBmdW5jdGlvbiBmaW5kTWFya3NBdChwb3MpIHsKLSAgICAgIHBvcyA9IGNsaXBQb3MocG9zKTsKLSAgICAgIHZhciBtYXJrZXJzID0gW10sIG1hcmtlZCA9IGdldExpbmUocG9zLmxpbmUpLm1hcmtlZDsKLSAgICAgIGlmICghbWFya2VkKSByZXR1cm4gbWFya2VyczsKLSAgICAgIGZvciAodmFyIGkgPSAwLCBlID0gbWFya2VkLmxlbmd0aDsgaSA8IGU7ICsraSkgewotICAgICAgICB2YXIgbSA9IG1hcmtlZFtpXTsKLSAgICAgICAgaWYgKChtLmZyb20gPT0gbnVsbCB8fCBtLmZyb20gPD0gcG9zLmNoKSAmJgotICAgICAgICAgICAgKG0udG8gPT0gbnVsbCB8fCBtLnRvID49IHBvcy5jaCkpCi0gICAgICAgICAgbWFya2Vycy5wdXNoKG0ubWFya2VyIHx8IG0pOwotICAgICAgfQotICAgICAgcmV0dXJuIG1hcmtlcnM7Ci0gICAgfQotCi0gICAgZnVuY3Rpb24gYWRkR3V0dGVyTWFya2VyKGxpbmUsIHRleHQsIGNsYXNzTmFtZSkgewotICAgICAgaWYgKHR5cGVvZiBsaW5lID09ICJudW1iZXIiKSBsaW5lID0gZ2V0TGluZShjbGlwTGluZShsaW5lKSk7Ci0gICAgICBsaW5lLmd1dHRlck1hcmtlciA9IHt0ZXh0OiB0ZXh0LCBzdHlsZTogY2xhc3NOYW1lfTsKLSAgICAgIGd1dHRlckRpcnR5ID0gdHJ1ZTsKLSAgICAgIHJldHVybiBsaW5lOwotICAgIH0KLSAgICBmdW5jdGlvbiByZW1vdmVHdXR0ZXJNYXJrZXIobGluZSkgewotICAgICAgaWYgKHR5cGVvZiBsaW5lID09ICJudW1iZXIiKSBsaW5lID0gZ2V0TGluZShjbGlwTGluZShsaW5lKSk7Ci0gICAgICBsaW5lLmd1dHRlck1hcmtlciA9IG51bGw7Ci0gICAgICBndXR0ZXJEaXJ0eSA9IHRydWU7Ci0gICAgfQotCi0gICAgZnVuY3Rpb24gY2hhbmdlTGluZShoYW5kbGUsIG9wKSB7Ci0gICAgICB2YXIgbm8gPSBoYW5kbGUsIGxpbmUgPSBoYW5kbGU7Ci0gICAgICBpZiAodHlwZW9mIGhhbmRsZSA9PSAibnVtYmVyIikgbGluZSA9IGdldExpbmUoY2xpcExpbmUoaGFuZGxlKSk7Ci0gICAgICBlbHNlIG5vID0gbGluZU5vKGhhbmRsZSk7Ci0gICAgICBpZiAobm8gPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0gICAgICBpZiAob3AobGluZSwgbm8pKSBjaGFuZ2VzLnB1c2goe2Zyb206IG5vLCB0bzogbm8gKyAxfSk7Ci0gICAgICBlbHNlIHJldHVybiBudWxsOwotICAgICAgcmV0dXJuIGxpbmU7Ci0gICAgfQotICAgIGZ1bmN0aW9uIHNldExpbmVDbGFzcyhoYW5kbGUsIGNsYXNzTmFtZSwgYmdDbGFzc05hbWUpIHsKLSAgICAgIHJldHVybiBjaGFuZ2VMaW5lKGhhbmRsZSwgZnVuY3Rpb24obGluZSkgewotICAgICAgICBpZiAobGluZS5jbGFzc05hbWUgIT0gY2xhc3NOYW1lIHx8IGxpbmUuYmdDbGFzc05hbWUgIT0gYmdDbGFzc05hbWUpIHsKLSAgICAgICAgICBsaW5lLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTsKLSAgICAgICAgICBsaW5lLmJnQ2xhc3NOYW1lID0gYmdDbGFzc05hbWU7Ci0gICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgIH0pOwotICAgIH0KLSAgICBmdW5jdGlvbiBzZXRMaW5lSGlkZGVuKGhhbmRsZSwgaGlkZGVuKSB7Ci0gICAgICByZXR1cm4gY2hhbmdlTGluZShoYW5kbGUsIGZ1bmN0aW9uKGxpbmUsIG5vKSB7Ci0gICAgICAgIGlmIChsaW5lLmhpZGRlbiAhPSBoaWRkZW4pIHsKLSAgICAgICAgICBsaW5lLmhpZGRlbiA9IGhpZGRlbjsKLSAgICAgICAgICB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIGhpZGRlbiA/IDAgOiAxKTsKLSAgICAgICAgICB2YXIgZmxpbmUgPSBzZWwuZnJvbS5saW5lLCB0bGluZSA9IHNlbC50by5saW5lOwotICAgICAgICAgIGlmIChoaWRkZW4gJiYgKGZsaW5lID09IG5vIHx8IHRsaW5lID09IG5vKSkgewotICAgICAgICAgICAgdmFyIGZyb20gPSBmbGluZSA9PSBubyA/IHNraXBIaWRkZW4oe2xpbmU6IGZsaW5lLCBjaDogMH0sIGZsaW5lLCAwKSA6IHNlbC5mcm9tOwotICAgICAgICAgICAgdmFyIHRvID0gdGxpbmUgPT0gbm8gPyBza2lwSGlkZGVuKHtsaW5lOiB0bGluZSwgY2g6IDB9LCB0bGluZSwgMCkgOiBzZWwudG87Ci0gICAgICAgICAgICAvLyBDYW4ndCBoaWRlIHRoZSBsYXN0IHZpc2libGUgbGluZSwgd2UnZCBoYXZlIG5vIHBsYWNlIHRvIHB1dCB0aGUgY3Vyc29yCi0gICAgICAgICAgICBpZiAoIXRvKSByZXR1cm47Ci0gICAgICAgICAgICBzZXRTZWxlY3Rpb24oZnJvbSwgdG8pOwotICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gKGd1dHRlckRpcnR5ID0gdHJ1ZSk7Ci0gICAgICAgIH0KLSAgICAgIH0pOwotICAgIH0KLQotICAgIGZ1bmN0aW9uIGxpbmVJbmZvKGxpbmUpIHsKLSAgICAgIGlmICh0eXBlb2YgbGluZSA9PSAibnVtYmVyIikgewotICAgICAgICBpZiAoIWlzTGluZShsaW5lKSkgcmV0dXJuIG51bGw7Ci0gICAgICAgIHZhciBuID0gbGluZTsKLSAgICAgICAgbGluZSA9IGdldExpbmUobGluZSk7Ci0gICAgICAgIGlmICghbGluZSkgcmV0dXJuIG51bGw7Ci0gICAgICB9Ci0gICAgICBlbHNlIHsKLSAgICAgICAgdmFyIG4gPSBsaW5lTm8obGluZSk7Ci0gICAgICAgIGlmIChuID09IG51bGwpIHJldHVybiBudWxsOwotICAgICAgfQotICAgICAgdmFyIG1hcmtlciA9IGxpbmUuZ3V0dGVyTWFya2VyOwotICAgICAgcmV0dXJuIHtsaW5lOiBuLCBoYW5kbGU6IGxpbmUsIHRleHQ6IGxpbmUudGV4dCwgbWFya2VyVGV4dDogbWFya2VyICYmIG1hcmtlci50ZXh0LAotICAgICAgICAgICAgICBtYXJrZXJDbGFzczogbWFya2VyICYmIG1hcmtlci5zdHlsZSwgbGluZUNsYXNzOiBsaW5lLmNsYXNzTmFtZSwgYmdDbGFzczogbGluZS5iZ0NsYXNzTmFtZX07Ci0gICAgfQotCi0gICAgZnVuY3Rpb24gc3RyaW5nV2lkdGgoc3RyKSB7Ci0gICAgICBtZWFzdXJlLmlubmVySFRNTCA9ICI8cHJlPjxzcGFuPng8L3NwYW4+PC9wcmU+IjsKLSAgICAgIG1lYXN1cmUuZmlyc3RDaGlsZC5maXJzdENoaWxkLmZpcnN0Q2hpbGQubm9kZVZhbHVlID0gc3RyOwotICAgICAgcmV0dXJuIG1lYXN1cmUuZmlyc3RDaGlsZC5maXJzdENoaWxkLm9mZnNldFdpZHRoIHx8IDEwOwotICAgIH0KLSAgICAvLyBUaGVzZSBhcmUgdXNlZCB0byBnbyBmcm9tIHBpeGVsIHBvc2l0aW9ucyB0byBjaGFyYWN0ZXIKLSAgICAvLyBwb3NpdGlvbnMsIHRha2luZyB2YXJ5aW5nIGNoYXJhY3RlciB3aWR0aHMgaW50byBhY2NvdW50LgotICAgIGZ1bmN0aW9uIGNoYXJGcm9tWChsaW5lLCB4KSB7Ci0gICAgICBpZiAoeCA8PSAwKSByZXR1cm4gMDsKLSAgICAgIHZhciBsaW5lT2JqID0gZ2V0TGluZShsaW5lKSwgdGV4dCA9IGxpbmVPYmoudGV4dDsKLSAgICAgIGZ1bmN0aW9uIGdldFgobGVuKSB7Ci0gICAgICAgIHJldHVybiBtZWFzdXJlTGluZShsaW5lT2JqLCBsZW4pLmxlZnQ7Ci0gICAgICB9Ci0gICAgICB2YXIgZnJvbSA9IDAsIGZyb21YID0gMCwgdG8gPSB0ZXh0Lmxlbmd0aCwgdG9YOwotICAgICAgLy8gR3Vlc3MgYSBzdWl0YWJsZSB1cHBlciBib3VuZCBmb3Igb3VyIHNlYXJjaC4KLSAgICAgIHZhciBlc3RpbWF0ZWQgPSBNYXRoLm1pbih0bywgTWF0aC5jZWlsKHggLyBjaGFyV2lkdGgoKSkpOwotICAgICAgZm9yICg7OykgewotICAgICAgICB2YXIgZXN0WCA9IGdldFgoZXN0aW1hdGVkKTsKLSAgICAgICAgaWYgKGVzdFggPD0geCAmJiBlc3RpbWF0ZWQgPCB0bykgZXN0aW1hdGVkID0gTWF0aC5taW4odG8sIE1hdGguY2VpbChlc3RpbWF0ZWQgKiAxLjIpKTsKLSAgICAgICAgZWxzZSB7dG9YID0gZXN0WDsgdG8gPSBlc3RpbWF0ZWQ7IGJyZWFrO30KLSAgICAgIH0KLSAgICAgIGlmICh4ID4gdG9YKSByZXR1cm4gdG87Ci0gICAgICAvLyBUcnkgdG8gZ3Vlc3MgYSBzdWl0YWJsZSBsb3dlciBib3VuZCBhcyB3ZWxsLgotICAgICAgZXN0aW1hdGVkID0gTWF0aC5mbG9vcih0byAqIDAuOCk7IGVzdFggPSBnZXRYKGVzdGltYXRlZCk7Ci0gICAgICBpZiAoZXN0WCA8IHgpIHtmcm9tID0gZXN0aW1hdGVkOyBmcm9tWCA9IGVzdFg7fQotICAgICAgLy8gRG8gYSBiaW5hcnkgc2VhcmNoIGJldHdlZW4gdGhlc2UgYm91bmRzLgotICAgICAgZm9yICg7OykgewotICAgICAgICBpZiAodG8gLSBmcm9tIDw9IDEpIHJldHVybiAodG9YIC0geCA+IHggLSBmcm9tWCkgPyBmcm9tIDogdG87Ci0gICAgICAgIHZhciBtaWRkbGUgPSBNYXRoLmNlaWwoKGZyb20gKyB0bykgLyAyKSwgbWlkZGxlWCA9IGdldFgobWlkZGxlKTsKLSAgICAgICAgaWYgKG1pZGRsZVggPiB4KSB7dG8gPSBtaWRkbGU7IHRvWCA9IG1pZGRsZVg7fQotICAgICAgICBlbHNlIHtmcm9tID0gbWlkZGxlOyBmcm9tWCA9IG1pZGRsZVg7fQotICAgICAgfQotICAgIH0KLQotICAgIHZhciB0ZW1wSWQgPSAiQ29kZU1pcnJvci10ZW1wLSIgKyBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAweGZmZmZmZikudG9TdHJpbmcoMTYpOwotICAgIGZ1bmN0aW9uIG1lYXN1cmVMaW5lKGxpbmUsIGNoKSB7Ci0gICAgICBpZiAoY2ggPT0gMCkgcmV0dXJuIHt0b3A6IDAsIGxlZnQ6IDB9OwotICAgICAgdmFyIHdiciA9IG9wdGlvbnMubGluZVdyYXBwaW5nICYmIGNoIDwgbGluZS50ZXh0Lmxlbmd0aCAmJgotICAgICAgICAgICAgICAgIHNwYW5BZmZlY3RzV3JhcHBpbmcudGVzdChsaW5lLnRleHQuc2xpY2UoY2ggLSAxLCBjaCArIDEpKTsKLSAgICAgIG1lYXN1cmUuaW5uZXJIVE1MID0gIjxwcmU+IiArIGxpbmUuZ2V0SFRNTChtYWtlVGFiLCBjaCwgdGVtcElkLCB3YnIpICsgIjwvcHJlPiI7Ci0gICAgICB2YXIgZWx0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGVtcElkKTsKLSAgICAgIHZhciB0b3AgPSBlbHQub2Zmc2V0VG9wLCBsZWZ0ID0gZWx0Lm9mZnNldExlZnQ7Ci0gICAgICAvLyBPbGRlciBJRXMgcmVwb3J0IHplcm8gb2Zmc2V0cyBmb3Igc3BhbnMgZGlyZWN0bHkgYWZ0ZXIgYSB3cmFwCi0gICAgICBpZiAoaWUgJiYgdG9wID09IDAgJiYgbGVmdCA9PSAwKSB7Ci0gICAgICAgIHZhciBiYWNrdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzcGFuIik7Ci0gICAgICAgIGJhY2t1cC5pbm5lckhUTUwgPSAieCI7Ci0gICAgICAgIGVsdC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShiYWNrdXAsIGVsdC5uZXh0U2libGluZyk7Ci0gICAgICAgIHRvcCA9IGJhY2t1cC5vZmZzZXRUb3A7Ci0gICAgICB9Ci0gICAgICByZXR1cm4ge3RvcDogdG9wLCBsZWZ0OiBsZWZ0fTsKLSAgICB9Ci0gICAgZnVuY3Rpb24gbG9jYWxDb29yZHMocG9zLCBpbkxpbmVXcmFwKSB7Ci0gICAgICB2YXIgeCwgbGggPSB0ZXh0SGVpZ2h0KCksIHkgPSBsaCAqIChoZWlnaHRBdExpbmUoZG9jLCBwb3MubGluZSkgLSAoaW5MaW5lV3JhcCA/IGRpc3BsYXlPZmZzZXQgOiAwKSk7Ci0gICAgICBpZiAocG9zLmNoID09IDApIHggPSAwOwotICAgICAgZWxzZSB7Ci0gICAgICAgIHZhciBzcCA9IG1lYXN1cmVMaW5lKGdldExpbmUocG9zLmxpbmUpLCBwb3MuY2gpOwotICAgICAgICB4ID0gc3AubGVmdDsKLSAgICAgICAgaWYgKG9wdGlvbnMubGluZVdyYXBwaW5nKSB5ICs9IE1hdGgubWF4KDAsIHNwLnRvcCk7Ci0gICAgICB9Ci0gICAgICByZXR1cm4ge3g6IHgsIHk6IHksIHlCb3Q6IHkgKyBsaH07Ci0gICAgfQotICAgIC8vIENvb3JkcyBtdXN0IGJlIGxpbmVTcGFjZS1sb2NhbAotICAgIGZ1bmN0aW9uIGNvb3Jkc0NoYXIoeCwgeSkgewotICAgICAgaWYgKHkgPCAwKSB5ID0gMDsKLSAgICAgIHZhciB0aCA9IHRleHRIZWlnaHQoKSwgY3cgPSBjaGFyV2lkdGgoKSwgaGVpZ2h0UG9zID0gZGlzcGxheU9mZnNldCArIE1hdGguZmxvb3IoeSAvIHRoKTsKLSAgICAgIHZhciBsaW5lTm8gPSBsaW5lQXRIZWlnaHQoZG9jLCBoZWlnaHRQb3MpOwotICAgICAgaWYgKGxpbmVObyA+PSBkb2Muc2l6ZSkgcmV0dXJuIHtsaW5lOiBkb2Muc2l6ZSAtIDEsIGNoOiBnZXRMaW5lKGRvYy5zaXplIC0gMSkudGV4dC5sZW5ndGh9OwotICAgICAgdmFyIGxpbmVPYmogPSBnZXRMaW5lKGxpbmVObyksIHRleHQgPSBsaW5lT2JqLnRleHQ7Ci0gICAgICB2YXIgdHcgPSBvcHRpb25zLmxpbmVXcmFwcGluZywgaW5uZXJPZmYgPSB0dyA/IGhlaWdodFBvcyAtIGhlaWdodEF0TGluZShkb2MsIGxpbmVObykgOiAwOwotICAgICAgaWYgKHggPD0gMCAmJiBpbm5lck9mZiA9PSAwKSByZXR1cm4ge2xpbmU6IGxpbmVObywgY2g6IDB9OwotICAgICAgZnVuY3Rpb24gZ2V0WChsZW4pIHsKLSAgICAgICAgdmFyIHNwID0gbWVhc3VyZUxpbmUobGluZU9iaiwgbGVuKTsKLSAgICAgICAgaWYgKHR3KSB7Ci0gICAgICAgICAgdmFyIG9mZiA9IE1hdGgucm91bmQoc3AudG9wIC8gdGgpOwotICAgICAgICAgIHJldHVybiBNYXRoLm1heCgwLCBzcC5sZWZ0ICsgKG9mZiAtIGlubmVyT2ZmKSAqIHNjcm9sbGVyLmNsaWVudFdpZHRoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3AubGVmdDsKLSAgICAgIH0KLSAgICAgIHZhciBmcm9tID0gMCwgZnJvbVggPSAwLCB0byA9IHRleHQubGVuZ3RoLCB0b1g7Ci0gICAgICAvLyBHdWVzcyBhIHN1aXRhYmxlIHVwcGVyIGJvdW5kIGZvciBvdXIgc2VhcmNoLgotICAgICAgdmFyIGVzdGltYXRlZCA9IE1hdGgubWluKHRvLCBNYXRoLmNlaWwoKHggKyBpbm5lck9mZiAqIHNjcm9sbGVyLmNsaWVudFdpZHRoICogLjkpIC8gY3cpKTsKLSAgICAgIGZvciAoOzspIHsKLSAgICAgICAgdmFyIGVzdFggPSBnZXRYKGVzdGltYXRlZCk7Ci0gICAgICAgIGlmIChlc3RYIDw9IHggJiYgZXN0aW1hdGVkIDwgdG8pIGVzdGltYXRlZCA9IE1hdGgubWluKHRvLCBNYXRoLmNlaWwoZXN0aW1hdGVkICogMS4yKSk7Ci0gICAgICAgIGVsc2Uge3RvWCA9IGVzdFg7IHRvID0gZXN0aW1hdGVkOyBicmVhazt9Ci0gICAgICB9Ci0gICAgICBpZiAoeCA+IHRvWCkgcmV0dXJuIHtsaW5lOiBsaW5lTm8sIGNoOiB0b307Ci0gICAgICAvLyBUcnkgdG8gZ3Vlc3MgYSBzdWl0YWJsZSBsb3dlciBib3VuZCBhcyB3ZWxsLgotICAgICAgZXN0aW1hdGVkID0gTWF0aC5mbG9vcih0byAqIDAuOCk7IGVzdFggPSBnZXRYKGVzdGltYXRlZCk7Ci0gICAgICBpZiAoZXN0WCA8IHgpIHtmcm9tID0gZXN0aW1hdGVkOyBmcm9tWCA9IGVzdFg7fQotICAgICAgLy8gRG8gYSBiaW5hcnkgc2VhcmNoIGJldHdlZW4gdGhlc2UgYm91bmRzLgotICAgICAgZm9yICg7OykgewotICAgICAgICBpZiAodG8gLSBmcm9tIDw9IDEpIHJldHVybiB7bGluZTogbGluZU5vLCBjaDogKHRvWCAtIHggPiB4IC0gZnJvbVgpID8gZnJvbSA6IHRvfTsKLSAgICAgICAgdmFyIG1pZGRsZSA9IE1hdGguY2VpbCgoZnJvbSArIHRvKSAvIDIpLCBtaWRkbGVYID0gZ2V0WChtaWRkbGUpOwotICAgICAgICBpZiAobWlkZGxlWCA+IHgpIHt0byA9IG1pZGRsZTsgdG9YID0gbWlkZGxlWDt9Ci0gICAgICAgIGVsc2Uge2Zyb20gPSBtaWRkbGU7IGZyb21YID0gbWlkZGxlWDt9Ci0gICAgICB9Ci0gICAgfQotICAgIGZ1bmN0aW9uIHBhZ2VDb29yZHMocG9zKSB7Ci0gICAgICB2YXIgbG9jYWwgPSBsb2NhbENvb3Jkcyhwb3MsIHRydWUpLCBvZmYgPSBlbHRPZmZzZXQobGluZVNwYWNlKTsKLSAgICAgIHJldHVybiB7eDogb2ZmLmxlZnQgKyBsb2NhbC54LCB5OiBvZmYudG9wICsgbG9jYWwueSwgeUJvdDogb2ZmLnRvcCArIGxvY2FsLnlCb3R9OwotICAgIH0KLQotICAgIHZhciBjYWNoZWRIZWlnaHQsIGNhY2hlZEhlaWdodEZvciwgbWVhc3VyZVRleHQ7Ci0gICAgZnVuY3Rpb24gdGV4dEhlaWdodCgpIHsKLSAgICAgIGlmIChtZWFzdXJlVGV4dCA9PSBudWxsKSB7Ci0gICAgICAgIG1lYXN1cmVUZXh0ID0gIjxwcmU+IjsKLSAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OTsgKytpKSBtZWFzdXJlVGV4dCArPSAieDxici8+IjsKLSAgICAgICAgbWVhc3VyZVRleHQgKz0gIng8L3ByZT4iOwotICAgICAgfQotICAgICAgdmFyIG9mZnNldEhlaWdodCA9IGxpbmVEaXYuY2xpZW50SGVpZ2h0OwotICAgICAgaWYgKG9mZnNldEhlaWdodCA9PSBjYWNoZWRIZWlnaHRGb3IpIHJldHVybiBjYWNoZWRIZWlnaHQ7Ci0gICAgICBjYWNoZWRIZWlnaHRGb3IgPSBvZmZzZXRIZWlnaHQ7Ci0gICAgICBtZWFzdXJlLmlubmVySFRNTCA9IG1lYXN1cmVUZXh0OwotICAgICAgY2FjaGVkSGVpZ2h0ID0gbWVhc3VyZS5maXJzdENoaWxkLm9mZnNldEhlaWdodCAvIDUwIHx8IDE7Ci0gICAgICBtZWFzdXJlLmlubmVySFRNTCA9ICIiOwotICAgICAgcmV0dXJuIGNhY2hlZEhlaWdodDsKLSAgICB9Ci0gICAgdmFyIGNhY2hlZFdpZHRoLCBjYWNoZWRXaWR0aEZvciA9IDA7Ci0gICAgZnVuY3Rpb24gY2hhcldpZHRoKCkgewotICAgICAgaWYgKHNjcm9sbGVyLmNsaWVudFdpZHRoID09IGNhY2hlZFdpZHRoRm9yKSByZXR1cm4gY2FjaGVkV2lkdGg7Ci0gICAgICBjYWNoZWRXaWR0aEZvciA9IHNjcm9sbGVyLmNsaWVudFdpZHRoOwotICAgICAgcmV0dXJuIChjYWNoZWRXaWR0aCA9IHN0cmluZ1dpZHRoKCJ4IikpOwotICAgIH0KLSAgICBmdW5jdGlvbiBwYWRkaW5nVG9wKCkge3JldHVybiBsaW5lU3BhY2Uub2Zmc2V0VG9wO30KLSAgICBmdW5jdGlvbiBwYWRkaW5nTGVmdCgpIHtyZXR1cm4gbGluZVNwYWNlLm9mZnNldExlZnQ7fQotCi0gICAgZnVuY3Rpb24gcG9zRnJvbU1vdXNlKGUsIGxpYmVyYWwpIHsKLSAgICAgIHZhciBvZmZXID0gZWx0T2Zmc2V0KHNjcm9sbGVyLCB0cnVlKSwgeCwgeTsKLSAgICAgIC8vIEZhaWxzIHVucHJlZGljdGFibHkgb24gSUVbNjddIHdoZW4gbW91c2UgaXMgZHJhZ2dlZCBhcm91bmQgcXVpY2tseS4KLSAgICAgIHRyeSB7IHggPSBlLmNsaWVudFg7IHkgPSBlLmNsaWVudFk7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIG51bGw7IH0KLSAgICAgIC8vIFRoaXMgaXMgYSBtZXNzIG9mIGEgaGV1cmlzdGljIHRvIHRyeSBhbmQgZGV0ZXJtaW5lIHdoZXRoZXIgYQotICAgICAgLy8gc2Nyb2xsLWJhciB3YXMgY2xpY2tlZCBvciBub3QsIGFuZCB0byByZXR1cm4gbnVsbCBpZiBvbmUgd2FzCi0gICAgICAvLyAoYW5kICFsaWJlcmFsKS4KLSAgICAgIGlmICghbGliZXJhbCAmJiAoeCAtIG9mZlcubGVmdCA+IHNjcm9sbGVyLmNsaWVudFdpZHRoIHx8IHkgLSBvZmZXLnRvcCA+IHNjcm9sbGVyLmNsaWVudEhlaWdodCkpCi0gICAgICAgIHJldHVybiBudWxsOwotICAgICAgdmFyIG9mZkwgPSBlbHRPZmZzZXQobGluZVNwYWNlLCB0cnVlKTsKLSAgICAgIHJldHVybiBjb29yZHNDaGFyKHggLSBvZmZMLmxlZnQsIHkgLSBvZmZMLnRvcCk7Ci0gICAgfQotICAgIGZ1bmN0aW9uIG9uQ29udGV4dE1lbnUoZSkgewotICAgICAgdmFyIHBvcyA9IHBvc0Zyb21Nb3VzZShlKSwgc2Nyb2xsUG9zID0gc2Nyb2xsZXIuc2Nyb2xsVG9wOwotICAgICAgaWYgKCFwb3MgfHwgd2luZG93Lm9wZXJhKSByZXR1cm47IC8vIE9wZXJhIGlzIGRpZmZpY3VsdC4KLSAgICAgIGlmIChwb3NFcShzZWwuZnJvbSwgc2VsLnRvKSB8fCBwb3NMZXNzKHBvcywgc2VsLmZyb20pIHx8ICFwb3NMZXNzKHBvcywgc2VsLnRvKSkKLSAgICAgICAgb3BlcmF0aW9uKHNldEN1cnNvcikocG9zLmxpbmUsIHBvcy5jaCk7Ci0KLSAgICAgIHZhciBvbGRDU1MgPSBpbnB1dC5zdHlsZS5jc3NUZXh0OwotICAgICAgaW5wdXREaXYuc3R5bGUucG9zaXRpb24gPSAiYWJzb2x1dGUiOwotICAgICAgaW5wdXQuc3R5bGUuY3NzVGV4dCA9ICJwb3NpdGlvbjogZml4ZWQ7IHdpZHRoOiAzMHB4OyBoZWlnaHQ6IDMwcHg7IHRvcDogIiArIChlLmNsaWVudFkgLSA1KSArCi0gICAgICAgICJweDsgbGVmdDogIiArIChlLmNsaWVudFggLSA1KSArICJweDsgei1pbmRleDogMTAwMDsgYmFja2dyb3VuZDogd2hpdGU7ICIgKwotICAgICAgICAiYm9yZGVyLXdpZHRoOiAwOyBvdXRsaW5lOiBub25lOyBvdmVyZmxvdzogaGlkZGVuOyBvcGFjaXR5OiAuMDU7IGZpbHRlcjogYWxwaGEob3BhY2l0eT01KTsiOwotICAgICAgbGVhdmVJbnB1dEFsb25lID0gdHJ1ZTsKLSAgICAgIHZhciB2YWwgPSBpbnB1dC52YWx1ZSA9IGdldFNlbGVjdGlvbigpOwotICAgICAgZm9jdXNJbnB1dCgpOwotICAgICAgc2VsZWN0SW5wdXQoaW5wdXQpOwotICAgICAgZnVuY3Rpb24gcmVoaWRlKCkgewotICAgICAgICB2YXIgbmV3VmFsID0gc3BsaXRMaW5lcyhpbnB1dC52YWx1ZSkuam9pbigiXG4iKTsKLSAgICAgICAgaWYgKG5ld1ZhbCAhPSB2YWwpIG9wZXJhdGlvbihyZXBsYWNlU2VsZWN0aW9uKShuZXdWYWwsICJlbmQiKTsKLSAgICAgICAgaW5wdXREaXYuc3R5bGUucG9zaXRpb24gPSAicmVsYXRpdmUiOwotICAgICAgICBpbnB1dC5zdHlsZS5jc3NUZXh0ID0gb2xkQ1NTOwotICAgICAgICBpZiAoaWVfbHQ5KSBzY3JvbGxlci5zY3JvbGxUb3AgPSBzY3JvbGxQb3M7Ci0gICAgICAgIGxlYXZlSW5wdXRBbG9uZSA9IGZhbHNlOwotICAgICAgICByZXNldElucHV0KHRydWUpOwotICAgICAgICBzbG93UG9sbCgpOwotICAgICAgfQotCi0gICAgICBpZiAoZ2Vja28pIHsKLSAgICAgICAgZV9zdG9wKGUpOwotICAgICAgICB2YXIgbW91c2V1cCA9IGNvbm5lY3Qod2luZG93LCAibW91c2V1cCIsIGZ1bmN0aW9uKCkgewotICAgICAgICAgIG1vdXNldXAoKTsKLSAgICAgICAgICBzZXRUaW1lb3V0KHJlaGlkZSwgMjApOwotICAgICAgICB9LCB0cnVlKTsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIHNldFRpbWVvdXQocmVoaWRlLCA1MCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gQ3Vyc29yLWJsaW5raW5nCi0gICAgZnVuY3Rpb24gcmVzdGFydEJsaW5rKCkgewotICAgICAgY2xlYXJJbnRlcnZhbChibGlua2VyKTsKLSAgICAgIHZhciBvbiA9IHRydWU7Ci0gICAgICBjdXJzb3Iuc3R5bGUudmlzaWJpbGl0eSA9ICIiOwotICAgICAgYmxpbmtlciA9IHNldEludGVydmFsKGZ1bmN0aW9uKCkgewotICAgICAgICBjdXJzb3Iuc3R5bGUudmlzaWJpbGl0eSA9IChvbiA9ICFvbikgPyAiIiA6ICJoaWRkZW4iOwotICAgICAgfSwgNjUwKTsKLSAgICB9Ci0KLSAgICB2YXIgbWF0Y2hpbmcgPSB7IigiOiAiKT4iLCAiKSI6ICIoPCIsICJbIjogIl0+IiwgIl0iOiAiWzwiLCAieyI6ICJ9PiIsICJ9IjogIns8In07Ci0gICAgZnVuY3Rpb24gbWF0Y2hCcmFja2V0cyhhdXRvY2xlYXIpIHsKLSAgICAgIHZhciBoZWFkID0gc2VsLmludmVydGVkID8gc2VsLmZyb20gOiBzZWwudG8sIGxpbmUgPSBnZXRMaW5lKGhlYWQubGluZSksIHBvcyA9IGhlYWQuY2ggLSAxOwotICAgICAgdmFyIG1hdGNoID0gKHBvcyA+PSAwICYmIG1hdGNoaW5nW2xpbmUudGV4dC5jaGFyQXQocG9zKV0pIHx8IG1hdGNoaW5nW2xpbmUudGV4dC5jaGFyQXQoKytwb3MpXTsKLSAgICAgIGlmICghbWF0Y2gpIHJldHVybjsKLSAgICAgIHZhciBjaCA9IG1hdGNoLmNoYXJBdCgwKSwgZm9yd2FyZCA9IG1hdGNoLmNoYXJBdCgxKSA9PSAiPiIsIGQgPSBmb3J3YXJkID8gMSA6IC0xLCBzdCA9IGxpbmUuc3R5bGVzOwotICAgICAgZm9yICh2YXIgb2ZmID0gcG9zICsgMSwgaSA9IDAsIGUgPSBzdC5sZW5ndGg7IGkgPCBlOyBpKz0yKQotICAgICAgICBpZiAoKG9mZiAtPSBzdFtpXS5sZW5ndGgpIDw9IDApIHt2YXIgc3R5bGUgPSBzdFtpKzFdOyBicmVhazt9Ci0KLSAgICAgIHZhciBzdGFjayA9IFtsaW5lLnRleHQuY2hhckF0KHBvcyldLCByZSA9IC9bKCl7fVtcXV0vOwotICAgICAgZnVuY3Rpb24gc2NhbihsaW5lLCBmcm9tLCB0bykgewotICAgICAgICBpZiAoIWxpbmUudGV4dCkgcmV0dXJuOwotICAgICAgICB2YXIgc3QgPSBsaW5lLnN0eWxlcywgcG9zID0gZm9yd2FyZCA/IDAgOiBsaW5lLnRleHQubGVuZ3RoIC0gMSwgY3VyOwotICAgICAgICBmb3IgKHZhciBpID0gZm9yd2FyZCA/IDAgOiBzdC5sZW5ndGggLSAyLCBlID0gZm9yd2FyZCA/IHN0Lmxlbmd0aCA6IC0yOyBpICE9IGU7IGkgKz0gMipkKSB7Ci0gICAgICAgICAgdmFyIHRleHQgPSBzdFtpXTsKLSAgICAgICAgICBpZiAoc3RbaSsxXSAhPSBudWxsICYmIHN0W2krMV0gIT0gc3R5bGUpIHtwb3MgKz0gZCAqIHRleHQubGVuZ3RoOyBjb250aW51ZTt9Ci0gICAgICAgICAgZm9yICh2YXIgaiA9IGZvcndhcmQgPyAwIDogdGV4dC5sZW5ndGggLSAxLCB0ZSA9IGZvcndhcmQgPyB0ZXh0Lmxlbmd0aCA6IC0xOyBqICE9IHRlOyBqICs9IGQsIHBvcys9ZCkgewotICAgICAgICAgICAgaWYgKHBvcyA+PSBmcm9tICYmIHBvcyA8IHRvICYmIHJlLnRlc3QoY3VyID0gdGV4dC5jaGFyQXQoaikpKSB7Ci0gICAgICAgICAgICAgIHZhciBtYXRjaCA9IG1hdGNoaW5nW2N1cl07Ci0gICAgICAgICAgICAgIGlmIChtYXRjaC5jaGFyQXQoMSkgPT0gIj4iID09IGZvcndhcmQpIHN0YWNrLnB1c2goY3VyKTsKLSAgICAgICAgICAgICAgZWxzZSBpZiAoc3RhY2sucG9wKCkgIT0gbWF0Y2guY2hhckF0KDApKSByZXR1cm4ge3BvczogcG9zLCBtYXRjaDogZmFsc2V9OwotICAgICAgICAgICAgICBlbHNlIGlmICghc3RhY2subGVuZ3RoKSByZXR1cm4ge3BvczogcG9zLCBtYXRjaDogdHJ1ZX07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBmb3IgKHZhciBpID0gaGVhZC5saW5lLCBlID0gZm9yd2FyZCA/IE1hdGgubWluKGkgKyAxMDAsIGRvYy5zaXplKSA6IE1hdGgubWF4KC0xLCBpIC0gMTAwKTsgaSAhPSBlOyBpKz1kKSB7Ci0gICAgICAgIHZhciBsaW5lID0gZ2V0TGluZShpKSwgZmlyc3QgPSBpID09IGhlYWQubGluZTsKLSAgICAgICAgdmFyIGZvdW5kID0gc2NhbihsaW5lLCBmaXJzdCAmJiBmb3J3YXJkID8gcG9zICsgMSA6IDAsIGZpcnN0ICYmICFmb3J3YXJkID8gcG9zIDogbGluZS50ZXh0Lmxlbmd0aCk7Ci0gICAgICAgIGlmIChmb3VuZCkgYnJlYWs7Ci0gICAgICB9Ci0gICAgICBpZiAoIWZvdW5kKSBmb3VuZCA9IHtwb3M6IG51bGwsIG1hdGNoOiBmYWxzZX07Ci0gICAgICB2YXIgc3R5bGUgPSBmb3VuZC5tYXRjaCA/ICJDb2RlTWlycm9yLW1hdGNoaW5nYnJhY2tldCIgOiAiQ29kZU1pcnJvci1ub25tYXRjaGluZ2JyYWNrZXQiOwotICAgICAgdmFyIG9uZSA9IG1hcmtUZXh0KHtsaW5lOiBoZWFkLmxpbmUsIGNoOiBwb3N9LCB7bGluZTogaGVhZC5saW5lLCBjaDogcG9zKzF9LCBzdHlsZSksCi0gICAgICAgICAgdHdvID0gZm91bmQucG9zICE9IG51bGwgJiYgbWFya1RleHQoe2xpbmU6IGksIGNoOiBmb3VuZC5wb3N9LCB7bGluZTogaSwgY2g6IGZvdW5kLnBvcyArIDF9LCBzdHlsZSk7Ci0gICAgICB2YXIgY2xlYXIgPSBvcGVyYXRpb24oZnVuY3Rpb24oKXtvbmUuY2xlYXIoKTsgdHdvICYmIHR3by5jbGVhcigpO30pOwotICAgICAgaWYgKGF1dG9jbGVhcikgc2V0VGltZW91dChjbGVhciwgODAwKTsKLSAgICAgIGVsc2UgYnJhY2tldEhpZ2hsaWdodGVkID0gY2xlYXI7Ci0gICAgfQotCi0gICAgLy8gRmluZHMgdGhlIGxpbmUgdG8gc3RhcnQgd2l0aCB3aGVuIHN0YXJ0aW5nIGEgcGFyc2UuIFRyaWVzIHRvCi0gICAgLy8gZmluZCBhIGxpbmUgd2l0aCBhIHN0YXRlQWZ0ZXIsIHNvIHRoYXQgaXQgY2FuIHN0YXJ0IHdpdGggYQotICAgIC8vIHZhbGlkIHN0YXRlLiBJZiB0aGF0IGZhaWxzLCBpdCByZXR1cm5zIHRoZSBsaW5lIHdpdGggdGhlCi0gICAgLy8gc21hbGxlc3QgaW5kZW50YXRpb24sIHdoaWNoIHRlbmRzIHRvIG5lZWQgdGhlIGxlYXN0IGNvbnRleHQgdG8KLSAgICAvLyBwYXJzZSBjb3JyZWN0bHkuCi0gICAgZnVuY3Rpb24gZmluZFN0YXJ0TGluZShuKSB7Ci0gICAgICB2YXIgbWluaW5kZW50LCBtaW5saW5lOwotICAgICAgZm9yICh2YXIgc2VhcmNoID0gbiwgbGltID0gbiAtIDQwOyBzZWFyY2ggPiBsaW07IC0tc2VhcmNoKSB7Ci0gICAgICAgIGlmIChzZWFyY2ggPT0gMCkgcmV0dXJuIDA7Ci0gICAgICAgIHZhciBsaW5lID0gZ2V0TGluZShzZWFyY2gtMSk7Ci0gICAgICAgIGlmIChsaW5lLnN0YXRlQWZ0ZXIpIHJldHVybiBzZWFyY2g7Ci0gICAgICAgIHZhciBpbmRlbnRlZCA9IGxpbmUuaW5kZW50YXRpb24ob3B0aW9ucy50YWJTaXplKTsKLSAgICAgICAgaWYgKG1pbmxpbmUgPT0gbnVsbCB8fCBtaW5pbmRlbnQgPiBpbmRlbnRlZCkgewotICAgICAgICAgIG1pbmxpbmUgPSBzZWFyY2ggLSAxOwotICAgICAgICAgIG1pbmluZGVudCA9IGluZGVudGVkOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICByZXR1cm4gbWlubGluZTsKLSAgICB9Ci0gICAgZnVuY3Rpb24gZ2V0U3RhdGVCZWZvcmUobikgewotICAgICAgdmFyIHN0YXJ0ID0gZmluZFN0YXJ0TGluZShuKSwgc3RhdGUgPSBzdGFydCAmJiBnZXRMaW5lKHN0YXJ0LTEpLnN0YXRlQWZ0ZXI7Ci0gICAgICBpZiAoIXN0YXRlKSBzdGF0ZSA9IHN0YXJ0U3RhdGUobW9kZSk7Ci0gICAgICBlbHNlIHN0YXRlID0gY29weVN0YXRlKG1vZGUsIHN0YXRlKTsKLSAgICAgIGRvYy5pdGVyKHN0YXJ0LCBuLCBmdW5jdGlvbihsaW5lKSB7Ci0gICAgICAgIGxpbmUuaGlnaGxpZ2h0KG1vZGUsIHN0YXRlLCBvcHRpb25zLnRhYlNpemUpOwotICAgICAgICBsaW5lLnN0YXRlQWZ0ZXIgPSBjb3B5U3RhdGUobW9kZSwgc3RhdGUpOwotICAgICAgfSk7Ci0gICAgICBpZiAoc3RhcnQgPCBuKSBjaGFuZ2VzLnB1c2goe2Zyb206IHN0YXJ0LCB0bzogbn0pOwotICAgICAgaWYgKG4gPCBkb2Muc2l6ZSAmJiAhZ2V0TGluZShuKS5zdGF0ZUFmdGVyKSB3b3JrLnB1c2gobik7Ci0gICAgICByZXR1cm4gc3RhdGU7Ci0gICAgfQotICAgIGZ1bmN0aW9uIGhpZ2hsaWdodExpbmVzKHN0YXJ0LCBlbmQpIHsKLSAgICAgIHZhciBzdGF0ZSA9IGdldFN0YXRlQmVmb3JlKHN0YXJ0KTsKLSAgICAgIGRvYy5pdGVyKHN0YXJ0LCBlbmQsIGZ1bmN0aW9uKGxpbmUpIHsKLSAgICAgICAgbGluZS5oaWdobGlnaHQobW9kZSwgc3RhdGUsIG9wdGlvbnMudGFiU2l6ZSk7Ci0gICAgICAgIGxpbmUuc3RhdGVBZnRlciA9IGNvcHlTdGF0ZShtb2RlLCBzdGF0ZSk7Ci0gICAgICB9KTsKLSAgICB9Ci0gICAgZnVuY3Rpb24gaGlnaGxpZ2h0V29ya2VyKCkgewotICAgICAgdmFyIGVuZCA9ICtuZXcgRGF0ZSArIG9wdGlvbnMud29ya1RpbWU7Ci0gICAgICB2YXIgZm91bmRXb3JrID0gd29yay5sZW5ndGg7Ci0gICAgICB3aGlsZSAod29yay5sZW5ndGgpIHsKLSAgICAgICAgaWYgKCFnZXRMaW5lKHNob3dpbmdGcm9tKS5zdGF0ZUFmdGVyKSB2YXIgdGFzayA9IHNob3dpbmdGcm9tOwotICAgICAgICBlbHNlIHZhciB0YXNrID0gd29yay5wb3AoKTsKLSAgICAgICAgaWYgKHRhc2sgPj0gZG9jLnNpemUpIGNvbnRpbnVlOwotICAgICAgICB2YXIgc3RhcnQgPSBmaW5kU3RhcnRMaW5lKHRhc2spLCBzdGF0ZSA9IHN0YXJ0ICYmIGdldExpbmUoc3RhcnQtMSkuc3RhdGVBZnRlcjsKLSAgICAgICAgaWYgKHN0YXRlKSBzdGF0ZSA9IGNvcHlTdGF0ZShtb2RlLCBzdGF0ZSk7Ci0gICAgICAgIGVsc2Ugc3RhdGUgPSBzdGFydFN0YXRlKG1vZGUpOwotCi0gICAgICAgIHZhciB1bmNoYW5nZWQgPSAwLCBjb21wYXJlID0gbW9kZS5jb21wYXJlU3RhdGVzLCByZWFsQ2hhbmdlID0gZmFsc2UsCi0gICAgICAgICAgICBpID0gc3RhcnQsIGJhaWwgPSBmYWxzZTsKLSAgICAgICAgZG9jLml0ZXIoaSwgZG9jLnNpemUsIGZ1bmN0aW9uKGxpbmUpIHsKLSAgICAgICAgICB2YXIgaGFkU3RhdGUgPSBsaW5lLnN0YXRlQWZ0ZXI7Ci0gICAgICAgICAgaWYgKCtuZXcgRGF0ZSA+IGVuZCkgewotICAgICAgICAgICAgd29yay5wdXNoKGkpOwotICAgICAgICAgICAgc3RhcnRXb3JrZXIob3B0aW9ucy53b3JrRGVsYXkpOwotICAgICAgICAgICAgaWYgKHJlYWxDaGFuZ2UpIGNoYW5nZXMucHVzaCh7ZnJvbTogdGFzaywgdG86IGkgKyAxfSk7Ci0gICAgICAgICAgICByZXR1cm4gKGJhaWwgPSB0cnVlKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgdmFyIGNoYW5nZWQgPSBsaW5lLmhpZ2hsaWdodChtb2RlLCBzdGF0ZSwgb3B0aW9ucy50YWJTaXplKTsKLSAgICAgICAgICBpZiAoY2hhbmdlZCkgcmVhbENoYW5nZSA9IHRydWU7Ci0gICAgICAgICAgbGluZS5zdGF0ZUFmdGVyID0gY29weVN0YXRlKG1vZGUsIHN0YXRlKTsKLSAgICAgICAgICB2YXIgZG9uZSA9IG51bGw7Ci0gICAgICAgICAgaWYgKGNvbXBhcmUpIHsKLSAgICAgICAgICAgIHZhciBzYW1lID0gaGFkU3RhdGUgJiYgY29tcGFyZShoYWRTdGF0ZSwgc3RhdGUpOwotICAgICAgICAgICAgaWYgKHNhbWUgIT0gUGFzcykgZG9uZSA9ICEhc2FtZTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgaWYgKGRvbmUgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGNoYW5nZWQgIT09IGZhbHNlIHx8ICFoYWRTdGF0ZSkgdW5jaGFuZ2VkID0gMDsKLSAgICAgICAgICAgIGVsc2UgaWYgKCsrdW5jaGFuZ2VkID4gMyAmJiAoIW1vZGUuaW5kZW50IHx8IG1vZGUuaW5kZW50KGhhZFN0YXRlLCAiIikgPT0gbW9kZS5pbmRlbnQoc3RhdGUsICIiKSkpCi0gICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwotICAgICAgICAgIH0KLSAgICAgICAgICBpZiAoZG9uZSkgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgKytpOwotICAgICAgICB9KTsKLSAgICAgICAgaWYgKGJhaWwpIHJldHVybjsKLSAgICAgICAgaWYgKHJlYWxDaGFuZ2UpIGNoYW5nZXMucHVzaCh7ZnJvbTogdGFzaywgdG86IGkgKyAxfSk7Ci0gICAgICB9Ci0gICAgICBpZiAoZm91bmRXb3JrICYmIG9wdGlvbnMub25IaWdobGlnaHRDb21wbGV0ZSkKLSAgICAgICAgb3B0aW9ucy5vbkhpZ2hsaWdodENvbXBsZXRlKGluc3RhbmNlKTsKLSAgICB9Ci0gICAgZnVuY3Rpb24gc3RhcnRXb3JrZXIodGltZSkgewotICAgICAgaWYgKCF3b3JrLmxlbmd0aCkgcmV0dXJuOwotICAgICAgaGlnaGxpZ2h0LnNldCh0aW1lLCBvcGVyYXRpb24oaGlnaGxpZ2h0V29ya2VyKSk7Ci0gICAgfQotCi0gICAgLy8gT3BlcmF0aW9ucyBhcmUgdXNlZCB0byB3cmFwIGNoYW5nZXMgaW4gc3VjaCBhIHdheSB0aGF0IGVhY2gKLSAgICAvLyBjaGFuZ2Ugd29uJ3QgaGF2ZSB0byB1cGRhdGUgdGhlIGN1cnNvciBhbmQgZGlzcGxheSAod2hpY2ggd291bGQKLSAgICAvLyBiZSBhd2t3YXJkLCBzbG93LCBhbmQgZXJyb3ItcHJvbmUpLCBidXQgaW5zdGVhZCB1cGRhdGVzIGFyZQotICAgIC8vIGJhdGNoZWQgYW5kIHRoZW4gYWxsIGNvbWJpbmVkIGFuZCBleGVjdXRlZCBhdCBvbmNlLgotICAgIGZ1bmN0aW9uIHN0YXJ0T3BlcmF0aW9uKCkgewotICAgICAgdXBkYXRlSW5wdXQgPSB1c2VyU2VsQ2hhbmdlID0gdGV4dENoYW5nZWQgPSBudWxsOwotICAgICAgY2hhbmdlcyA9IFtdOyBzZWxlY3Rpb25DaGFuZ2VkID0gZmFsc2U7IGNhbGxiYWNrcyA9IFtdOwotICAgIH0KLSAgICBmdW5jdGlvbiBlbmRPcGVyYXRpb24oKSB7Ci0gICAgICB2YXIgcmVTY3JvbGwgPSBmYWxzZSwgdXBkYXRlZDsKLSAgICAgIGlmIChzZWxlY3Rpb25DaGFuZ2VkKSByZVNjcm9sbCA9ICFzY3JvbGxDdXJzb3JJbnRvVmlldygpOwotICAgICAgaWYgKGNoYW5nZXMubGVuZ3RoKSB1cGRhdGVkID0gdXBkYXRlRGlzcGxheShjaGFuZ2VzLCB0cnVlKTsKLSAgICAgIGVsc2UgewotICAgICAgICBpZiAoc2VsZWN0aW9uQ2hhbmdlZCkgdXBkYXRlU2VsZWN0aW9uKCk7Ci0gICAgICAgIGlmIChndXR0ZXJEaXJ0eSkgdXBkYXRlR3V0dGVyKCk7Ci0gICAgICB9Ci0gICAgICBpZiAocmVTY3JvbGwpIHNjcm9sbEN1cnNvckludG9WaWV3KCk7Ci0gICAgICBpZiAoc2VsZWN0aW9uQ2hhbmdlZCkge3Njcm9sbEVkaXRvckludG9WaWV3KCk7IHJlc3RhcnRCbGluaygpO30KLQotICAgICAgaWYgKGZvY3VzZWQgJiYgIWxlYXZlSW5wdXRBbG9uZSAmJgotICAgICAgICAgICh1cGRhdGVJbnB1dCA9PT0gdHJ1ZSB8fCAodXBkYXRlSW5wdXQgIT09IGZhbHNlICYmIHNlbGVjdGlvbkNoYW5nZWQpKSkKLSAgICAgICAgcmVzZXRJbnB1dCh1c2VyU2VsQ2hhbmdlKTsKLQotICAgICAgaWYgKHNlbGVjdGlvbkNoYW5nZWQgJiYgb3B0aW9ucy5tYXRjaEJyYWNrZXRzKQotICAgICAgICBzZXRUaW1lb3V0KG9wZXJhdGlvbihmdW5jdGlvbigpIHsKLSAgICAgICAgICBpZiAoYnJhY2tldEhpZ2hsaWdodGVkKSB7YnJhY2tldEhpZ2hsaWdodGVkKCk7IGJyYWNrZXRIaWdobGlnaHRlZCA9IG51bGw7fQotICAgICAgICAgIGlmIChwb3NFcShzZWwuZnJvbSwgc2VsLnRvKSkgbWF0Y2hCcmFja2V0cyhmYWxzZSk7Ci0gICAgICAgIH0pLCAyMCk7Ci0gICAgICB2YXIgdGMgPSB0ZXh0Q2hhbmdlZCwgY2JzID0gY2FsbGJhY2tzOyAvLyB0aGVzZSBjYW4gYmUgcmVzZXQgYnkgY2FsbGJhY2tzCi0gICAgICBpZiAoc2VsZWN0aW9uQ2hhbmdlZCAmJiBvcHRpb25zLm9uQ3Vyc29yQWN0aXZpdHkpCi0gICAgICAgIG9wdGlvbnMub25DdXJzb3JBY3Rpdml0eShpbnN0YW5jZSk7Ci0gICAgICBpZiAodGMgJiYgb3B0aW9ucy5vbkNoYW5nZSAmJiBpbnN0YW5jZSkKLSAgICAgICAgb3B0aW9ucy5vbkNoYW5nZShpbnN0YW5jZSwgdGMpOwotICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYnMubGVuZ3RoOyArK2kpIGNic1tpXShpbnN0YW5jZSk7Ci0gICAgICBpZiAodXBkYXRlZCAmJiBvcHRpb25zLm9uVXBkYXRlKSBvcHRpb25zLm9uVXBkYXRlKGluc3RhbmNlKTsKLSAgICB9Ci0gICAgdmFyIG5lc3RlZE9wZXJhdGlvbiA9IDA7Ci0gICAgZnVuY3Rpb24gb3BlcmF0aW9uKGYpIHsKLSAgICAgIHJldHVybiBmdW5jdGlvbigpIHsKLSAgICAgICAgaWYgKCFuZXN0ZWRPcGVyYXRpb24rKykgc3RhcnRPcGVyYXRpb24oKTsKLSAgICAgICAgdHJ5IHt2YXIgcmVzdWx0ID0gZi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO30KLSAgICAgICAgZmluYWxseSB7aWYgKCEtLW5lc3RlZE9wZXJhdGlvbikgZW5kT3BlcmF0aW9uKCk7fQotICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgfTsKLSAgICB9Ci0KLSAgICBmdW5jdGlvbiBjb21wb3VuZENoYW5nZShmKSB7Ci0gICAgICBoaXN0b3J5LnN0YXJ0Q29tcG91bmQoKTsKLSAgICAgIHRyeSB7IHJldHVybiBmKCk7IH0gZmluYWxseSB7IGhpc3RvcnkuZW5kQ29tcG91bmQoKTsgfQotICAgIH0KLQotICAgIGZvciAodmFyIGV4dCBpbiBleHRlbnNpb25zKQotICAgICAgaWYgKGV4dGVuc2lvbnMucHJvcGVydHlJc0VudW1lcmFibGUoZXh0KSAmJgotICAgICAgICAgICFpbnN0YW5jZS5wcm9wZXJ0eUlzRW51bWVyYWJsZShleHQpKQotICAgICAgICBpbnN0YW5jZVtleHRdID0gZXh0ZW5zaW9uc1tleHRdOwotICAgIHJldHVybiBpbnN0YW5jZTsKLSAgfSAvLyAoZW5kIG9mIGZ1bmN0aW9uIENvZGVNaXJyb3IpCi0KLSAgLy8gVGhlIGRlZmF1bHQgY29uZmlndXJhdGlvbiBvcHRpb25zLgotICBDb2RlTWlycm9yLmRlZmF1bHRzID0gewotICAgIHZhbHVlOiAiIiwKLSAgICBtb2RlOiBudWxsLAotICAgIHRoZW1lOiAiZGVmYXVsdCIsCi0gICAgaW5kZW50VW5pdDogMiwKLSAgICBpbmRlbnRXaXRoVGFiczogZmFsc2UsCi0gICAgc21hcnRJbmRlbnQ6IHRydWUsCi0gICAgdGFiU2l6ZTogNCwKLSAgICBrZXlNYXA6ICJkZWZhdWx0IiwKLSAgICBleHRyYUtleXM6IG51bGwsCi0gICAgZWxlY3RyaWNDaGFyczogdHJ1ZSwKLSAgICBhdXRvQ2xlYXJFbXB0eUxpbmVzOiBmYWxzZSwKLSAgICBvbktleUV2ZW50OiBudWxsLAotICAgIG9uRHJhZ0V2ZW50OiBudWxsLAotICAgIGxpbmVXcmFwcGluZzogZmFsc2UsCi0gICAgbGluZU51bWJlcnM6IGZhbHNlLAotICAgIGd1dHRlcjogZmFsc2UsCi0gICAgZml4ZWRHdXR0ZXI6IGZhbHNlLAotICAgIGZpcnN0TGluZU51bWJlcjogMSwKLSAgICByZWFkT25seTogZmFsc2UsCi0gICAgZHJhZ0Ryb3A6IHRydWUsCi0gICAgb25DaGFuZ2U6IG51bGwsCi0gICAgb25DdXJzb3JBY3Rpdml0eTogbnVsbCwKLSAgICBvbkd1dHRlckNsaWNrOiBudWxsLAotICAgIG9uSGlnaGxpZ2h0Q29tcGxldGU6IG51bGwsCi0gICAgb25VcGRhdGU6IG51bGwsCi0gICAgb25Gb2N1czogbnVsbCwgb25CbHVyOiBudWxsLCBvblNjcm9sbDogbnVsbCwKLSAgICBtYXRjaEJyYWNrZXRzOiBmYWxzZSwKLSAgICB3b3JrVGltZTogMTAwLAotICAgIHdvcmtEZWxheTogMjAwLAotICAgIHBvbGxJbnRlcnZhbDogMTAwLAotICAgIHVuZG9EZXB0aDogNDAsCi0gICAgdGFiaW5kZXg6IG51bGwsCi0gICAgYXV0b2ZvY3VzOiBudWxsCi0gIH07Ci0KLSAgdmFyIGlvcyA9IC9BcHBsZVdlYktpdC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSAmJiAvTW9iaWxlXC9cdysvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7Ci0gIHZhciBtYWMgPSBpb3MgfHwgL01hYy8udGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pOwotICB2YXIgd2luID0gL1dpbi8udGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pOwotCi0gIC8vIEtub3duIG1vZGVzLCBieSBuYW1lIGFuZCBieSBNSU1FCi0gIHZhciBtb2RlcyA9IENvZGVNaXJyb3IubW9kZXMgPSB7fSwgbWltZU1vZGVzID0gQ29kZU1pcnJvci5taW1lTW9kZXMgPSB7fTsKLSAgQ29kZU1pcnJvci5kZWZpbmVNb2RlID0gZnVuY3Rpb24obmFtZSwgbW9kZSkgewotICAgIGlmICghQ29kZU1pcnJvci5kZWZhdWx0cy5tb2RlICYmIG5hbWUgIT0gIm51bGwiKSBDb2RlTWlycm9yLmRlZmF1bHRzLm1vZGUgPSBuYW1lOwotICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikgewotICAgICAgbW9kZS5kZXBlbmRlbmNpZXMgPSBbXTsKLSAgICAgIGZvciAodmFyIGkgPSAyOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgKytpKSBtb2RlLmRlcGVuZGVuY2llcy5wdXNoKGFyZ3VtZW50c1tpXSk7Ci0gICAgfQotICAgIG1vZGVzW25hbWVdID0gbW9kZTsKLSAgfTsKLSAgQ29kZU1pcnJvci5kZWZpbmVNSU1FID0gZnVuY3Rpb24obWltZSwgc3BlYykgewotICAgIG1pbWVNb2Rlc1ttaW1lXSA9IHNwZWM7Ci0gIH07Ci0gIENvZGVNaXJyb3IucmVzb2x2ZU1vZGUgPSBmdW5jdGlvbihzcGVjKSB7Ci0gICAgaWYgKHR5cGVvZiBzcGVjID09ICJzdHJpbmciICYmIG1pbWVNb2Rlcy5oYXNPd25Qcm9wZXJ0eShzcGVjKSkKLSAgICAgIHNwZWMgPSBtaW1lTW9kZXNbc3BlY107Ci0gICAgZWxzZSBpZiAodHlwZW9mIHNwZWMgPT0gInN0cmluZyIgJiYgL15bXHdcLV0rXC9bXHdcLV0rXCt4bWwkLy50ZXN0KHNwZWMpKQotICAgICAgcmV0dXJuIENvZGVNaXJyb3IucmVzb2x2ZU1vZGUoImFwcGxpY2F0aW9uL3htbCIpOwotICAgIGlmICh0eXBlb2Ygc3BlYyA9PSAic3RyaW5nIikgcmV0dXJuIHtuYW1lOiBzcGVjfTsKLSAgICBlbHNlIHJldHVybiBzcGVjIHx8IHtuYW1lOiAibnVsbCJ9OwotICB9OwotICBDb2RlTWlycm9yLmdldE1vZGUgPSBmdW5jdGlvbihvcHRpb25zLCBzcGVjKSB7Ci0gICAgdmFyIHNwZWMgPSBDb2RlTWlycm9yLnJlc29sdmVNb2RlKHNwZWMpOwotICAgIHZhciBtZmFjdG9yeSA9IG1vZGVzW3NwZWMubmFtZV07Ci0gICAgaWYgKCFtZmFjdG9yeSkgcmV0dXJuIENvZGVNaXJyb3IuZ2V0TW9kZShvcHRpb25zLCAidGV4dC9wbGFpbiIpOwotICAgIHJldHVybiBtZmFjdG9yeShvcHRpb25zLCBzcGVjKTsKLSAgfTsKLSAgQ29kZU1pcnJvci5saXN0TW9kZXMgPSBmdW5jdGlvbigpIHsKLSAgICB2YXIgbGlzdCA9IFtdOwotICAgIGZvciAodmFyIG0gaW4gbW9kZXMpCi0gICAgICBpZiAobW9kZXMucHJvcGVydHlJc0VudW1lcmFibGUobSkpIGxpc3QucHVzaChtKTsKLSAgICByZXR1cm4gbGlzdDsKLSAgfTsKLSAgQ29kZU1pcnJvci5saXN0TUlNRXMgPSBmdW5jdGlvbigpIHsKLSAgICB2YXIgbGlzdCA9IFtdOwotICAgIGZvciAodmFyIG0gaW4gbWltZU1vZGVzKQotICAgICAgaWYgKG1pbWVNb2Rlcy5wcm9wZXJ0eUlzRW51bWVyYWJsZShtKSkgbGlzdC5wdXNoKHttaW1lOiBtLCBtb2RlOiBtaW1lTW9kZXNbbV19KTsKLSAgICByZXR1cm4gbGlzdDsKLSAgfTsKLQotICB2YXIgZXh0ZW5zaW9ucyA9IENvZGVNaXJyb3IuZXh0ZW5zaW9ucyA9IHt9OwotICBDb2RlTWlycm9yLmRlZmluZUV4dGVuc2lvbiA9IGZ1bmN0aW9uKG5hbWUsIGZ1bmMpIHsKLSAgICBleHRlbnNpb25zW25hbWVdID0gZnVuYzsKLSAgfTsKLQotICB2YXIgY29tbWFuZHMgPSBDb2RlTWlycm9yLmNvbW1hbmRzID0gewotICAgIHNlbGVjdEFsbDogZnVuY3Rpb24oY20pIHtjbS5zZXRTZWxlY3Rpb24oe2xpbmU6IDAsIGNoOiAwfSwge2xpbmU6IGNtLmxpbmVDb3VudCgpIC0gMX0pO30sCi0gICAga2lsbExpbmU6IGZ1bmN0aW9uKGNtKSB7Ci0gICAgICB2YXIgZnJvbSA9IGNtLmdldEN1cnNvcih0cnVlKSwgdG8gPSBjbS5nZXRDdXJzb3IoZmFsc2UpLCBzZWwgPSAhcG9zRXEoZnJvbSwgdG8pOwotICAgICAgaWYgKCFzZWwgJiYgY20uZ2V0TGluZShmcm9tLmxpbmUpLmxlbmd0aCA9PSBmcm9tLmNoKSBjbS5yZXBsYWNlUmFuZ2UoIiIsIGZyb20sIHtsaW5lOiBmcm9tLmxpbmUgKyAxLCBjaDogMH0pOwotICAgICAgZWxzZSBjbS5yZXBsYWNlUmFuZ2UoIiIsIGZyb20sIHNlbCA/IHRvIDoge2xpbmU6IGZyb20ubGluZX0pOwotICAgIH0sCi0gICAgZGVsZXRlTGluZTogZnVuY3Rpb24oY20pIHt2YXIgbCA9IGNtLmdldEN1cnNvcigpLmxpbmU7IGNtLnJlcGxhY2VSYW5nZSgiIiwge2xpbmU6IGwsIGNoOiAwfSwge2xpbmU6IGx9KTt9LAotICAgIHVuZG86IGZ1bmN0aW9uKGNtKSB7Y20udW5kbygpO30sCi0gICAgcmVkbzogZnVuY3Rpb24oY20pIHtjbS5yZWRvKCk7fSwKLSAgICBnb0RvY1N0YXJ0OiBmdW5jdGlvbihjbSkge2NtLnNldEN1cnNvcigwLCAwLCB0cnVlKTt9LAotICAgIGdvRG9jRW5kOiBmdW5jdGlvbihjbSkge2NtLnNldFNlbGVjdGlvbih7bGluZTogY20ubGluZUNvdW50KCkgLSAxfSwgbnVsbCwgdHJ1ZSk7fSwKLSAgICBnb0xpbmVTdGFydDogZnVuY3Rpb24oY20pIHtjbS5zZXRDdXJzb3IoY20uZ2V0Q3Vyc29yKCkubGluZSwgMCwgdHJ1ZSk7fSwKLSAgICBnb0xpbmVTdGFydFNtYXJ0OiBmdW5jdGlvbihjbSkgewotICAgICAgdmFyIGN1ciA9IGNtLmdldEN1cnNvcigpOwotICAgICAgdmFyIHRleHQgPSBjbS5nZXRMaW5lKGN1ci5saW5lKSwgZmlyc3ROb25XUyA9IE1hdGgubWF4KDAsIHRleHQuc2VhcmNoKC9cUy8pKTsKLSAgICAgIGNtLnNldEN1cnNvcihjdXIubGluZSwgY3VyLmNoIDw9IGZpcnN0Tm9uV1MgJiYgY3VyLmNoID8gMCA6IGZpcnN0Tm9uV1MsIHRydWUpOwotICAgIH0sCi0gICAgZ29MaW5lRW5kOiBmdW5jdGlvbihjbSkge2NtLnNldFNlbGVjdGlvbih7bGluZTogY20uZ2V0Q3Vyc29yKCkubGluZX0sIG51bGwsIHRydWUpO30sCi0gICAgZ29MaW5lVXA6IGZ1bmN0aW9uKGNtKSB7Y20ubW92ZVYoLTEsICJsaW5lIik7fSwKLSAgICBnb0xpbmVEb3duOiBmdW5jdGlvbihjbSkge2NtLm1vdmVWKDEsICJsaW5lIik7fSwKLSAgICBnb1BhZ2VVcDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlVigtMSwgInBhZ2UiKTt9LAotICAgIGdvUGFnZURvd246IGZ1bmN0aW9uKGNtKSB7Y20ubW92ZVYoMSwgInBhZ2UiKTt9LAotICAgIGdvQ2hhckxlZnQ6IGZ1bmN0aW9uKGNtKSB7Y20ubW92ZUgoLTEsICJjaGFyIik7fSwKLSAgICBnb0NoYXJSaWdodDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlSCgxLCAiY2hhciIpO30sCi0gICAgZ29Db2x1bW5MZWZ0OiBmdW5jdGlvbihjbSkge2NtLm1vdmVIKC0xLCAiY29sdW1uIik7fSwKLSAgICBnb0NvbHVtblJpZ2h0OiBmdW5jdGlvbihjbSkge2NtLm1vdmVIKDEsICJjb2x1bW4iKTt9LAotICAgIGdvV29yZExlZnQ6IGZ1bmN0aW9uKGNtKSB7Y20ubW92ZUgoLTEsICJ3b3JkIik7fSwKLSAgICBnb1dvcmRSaWdodDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlSCgxLCAid29yZCIpO30sCi0gICAgZGVsQ2hhckxlZnQ6IGZ1bmN0aW9uKGNtKSB7Y20uZGVsZXRlSCgtMSwgImNoYXIiKTt9LAotICAgIGRlbENoYXJSaWdodDogZnVuY3Rpb24oY20pIHtjbS5kZWxldGVIKDEsICJjaGFyIik7fSwKLSAgICBkZWxXb3JkTGVmdDogZnVuY3Rpb24oY20pIHtjbS5kZWxldGVIKC0xLCAid29yZCIpO30sCi0gICAgZGVsV29yZFJpZ2h0OiBmdW5jdGlvbihjbSkge2NtLmRlbGV0ZUgoMSwgIndvcmQiKTt9LAotICAgIGluZGVudEF1dG86IGZ1bmN0aW9uKGNtKSB7Y20uaW5kZW50U2VsZWN0aW9uKCJzbWFydCIpO30sCi0gICAgaW5kZW50TW9yZTogZnVuY3Rpb24oY20pIHtjbS5pbmRlbnRTZWxlY3Rpb24oImFkZCIpO30sCi0gICAgaW5kZW50TGVzczogZnVuY3Rpb24oY20pIHtjbS5pbmRlbnRTZWxlY3Rpb24oInN1YnRyYWN0Iik7fSwKLSAgICBpbnNlcnRUYWI6IGZ1bmN0aW9uKGNtKSB7Y20ucmVwbGFjZVNlbGVjdGlvbigiXHQiLCAiZW5kIik7fSwKLSAgICB0cmFuc3Bvc2VDaGFyczogZnVuY3Rpb24oY20pIHsKLSAgICAgIHZhciBjdXIgPSBjbS5nZXRDdXJzb3IoKSwgbGluZSA9IGNtLmdldExpbmUoY3VyLmxpbmUpOwotICAgICAgaWYgKGN1ci5jaCA+IDAgJiYgY3VyLmNoIDwgbGluZS5sZW5ndGggLSAxKQotICAgICAgICBjbS5yZXBsYWNlUmFuZ2UobGluZS5jaGFyQXQoY3VyLmNoKSArIGxpbmUuY2hhckF0KGN1ci5jaCAtIDEpLAotICAgICAgICAgICAgICAgICAgICAgICAge2xpbmU6IGN1ci5saW5lLCBjaDogY3VyLmNoIC0gMX0sIHtsaW5lOiBjdXIubGluZSwgY2g6IGN1ci5jaCArIDF9KTsKLSAgICB9LAotICAgIG5ld2xpbmVBbmRJbmRlbnQ6IGZ1bmN0aW9uKGNtKSB7Ci0gICAgICBjbS5yZXBsYWNlU2VsZWN0aW9uKCJcbiIsICJlbmQiKTsKLSAgICAgIGNtLmluZGVudExpbmUoY20uZ2V0Q3Vyc29yKCkubGluZSk7Ci0gICAgfSwKLSAgICB0b2dnbGVPdmVyd3JpdGU6IGZ1bmN0aW9uKGNtKSB7Y20udG9nZ2xlT3ZlcndyaXRlKCk7fQotICB9OwotCi0gIHZhciBrZXlNYXAgPSBDb2RlTWlycm9yLmtleU1hcCA9IHt9OwotICBrZXlNYXAuYmFzaWMgPSB7Ci0gICAgIkxlZnQiOiAiZ29DaGFyTGVmdCIsICJSaWdodCI6ICJnb0NoYXJSaWdodCIsICJVcCI6ICJnb0xpbmVVcCIsICJEb3duIjogImdvTGluZURvd24iLAotICAgICJFbmQiOiAiZ29MaW5lRW5kIiwgIkhvbWUiOiAiZ29MaW5lU3RhcnRTbWFydCIsICJQYWdlVXAiOiAiZ29QYWdlVXAiLCAiUGFnZURvd24iOiAiZ29QYWdlRG93biIsCi0gICAgIkRlbGV0ZSI6ICJkZWxDaGFyUmlnaHQiLCAiQmFja3NwYWNlIjogImRlbENoYXJMZWZ0IiwgIlRhYiI6ICJpbnNlcnRUYWIiLCAiU2hpZnQtVGFiIjogImluZGVudEF1dG8iLAotICAgICJFbnRlciI6ICJuZXdsaW5lQW5kSW5kZW50IiwgIkluc2VydCI6ICJ0b2dnbGVPdmVyd3JpdGUiCi0gIH07Ci0gIC8vIE5vdGUgdGhhdCB0aGUgc2F2ZSBhbmQgZmluZC1yZWxhdGVkIGNvbW1hbmRzIGFyZW4ndCBkZWZpbmVkIGJ5Ci0gIC8vIGRlZmF1bHQuIFVua25vd24gY29tbWFuZHMgYXJlIHNpbXBseSBpZ25vcmVkLgotICBrZXlNYXAucGNEZWZhdWx0ID0gewotICAgICJDdHJsLUEiOiAic2VsZWN0QWxsIiwgIkN0cmwtRCI6ICJkZWxldGVMaW5lIiwgIkN0cmwtWiI6ICJ1bmRvIiwgIlNoaWZ0LUN0cmwtWiI6ICJyZWRvIiwgIkN0cmwtWSI6ICJyZWRvIiwKLSAgICAiQ3RybC1Ib21lIjogImdvRG9jU3RhcnQiLCAiQWx0LVVwIjogImdvRG9jU3RhcnQiLCAiQ3RybC1FbmQiOiAiZ29Eb2NFbmQiLCAiQ3RybC1Eb3duIjogImdvRG9jRW5kIiwKLSAgICAiQ3RybC1MZWZ0IjogImdvV29yZExlZnQiLCAiQ3RybC1SaWdodCI6ICJnb1dvcmRSaWdodCIsICJBbHQtTGVmdCI6ICJnb0xpbmVTdGFydCIsICJBbHQtUmlnaHQiOiAiZ29MaW5lRW5kIiwKLSAgICAiQ3RybC1CYWNrc3BhY2UiOiAiZGVsV29yZExlZnQiLCAiQ3RybC1EZWxldGUiOiAiZGVsV29yZFJpZ2h0IiwgIkN0cmwtUyI6ICJzYXZlIiwgIkN0cmwtRiI6ICJmaW5kIiwKLSAgICAiQ3RybC1HIjogImZpbmROZXh0IiwgIlNoaWZ0LUN0cmwtRyI6ICJmaW5kUHJldiIsICJTaGlmdC1DdHJsLUYiOiAicmVwbGFjZSIsICJTaGlmdC1DdHJsLVIiOiAicmVwbGFjZUFsbCIsCi0gICAgIkN0cmwtWyI6ICJpbmRlbnRMZXNzIiwgIkN0cmwtXSI6ICJpbmRlbnRNb3JlIiwKLSAgICBmYWxsdGhyb3VnaDogImJhc2ljIgotICB9OwotICBrZXlNYXAubWFjRGVmYXVsdCA9IHsKLSAgICAiQ21kLUEiOiAic2VsZWN0QWxsIiwgIkNtZC1EIjogImRlbGV0ZUxpbmUiLCAiQ21kLVoiOiAidW5kbyIsICJTaGlmdC1DbWQtWiI6ICJyZWRvIiwgIkNtZC1ZIjogInJlZG8iLAotICAgICJDbWQtVXAiOiAiZ29Eb2NTdGFydCIsICJDbWQtRW5kIjogImdvRG9jRW5kIiwgIkNtZC1Eb3duIjogImdvRG9jRW5kIiwgIkFsdC1MZWZ0IjogImdvV29yZExlZnQiLAotICAgICJBbHQtUmlnaHQiOiAiZ29Xb3JkUmlnaHQiLCAiQ21kLUxlZnQiOiAiZ29MaW5lU3RhcnQiLCAiQ21kLVJpZ2h0IjogImdvTGluZUVuZCIsICJBbHQtQmFja3NwYWNlIjogImRlbFdvcmRMZWZ0IiwKLSAgICAiQ3RybC1BbHQtQmFja3NwYWNlIjogImRlbFdvcmRSaWdodCIsICJBbHQtRGVsZXRlIjogImRlbFdvcmRSaWdodCIsICJDbWQtUyI6ICJzYXZlIiwgIkNtZC1GIjogImZpbmQiLAotICAgICJDbWQtRyI6ICJmaW5kTmV4dCIsICJTaGlmdC1DbWQtRyI6ICJmaW5kUHJldiIsICJDbWQtQWx0LUYiOiAicmVwbGFjZSIsICJTaGlmdC1DbWQtQWx0LUYiOiAicmVwbGFjZUFsbCIsCi0gICAgIkNtZC1bIjogImluZGVudExlc3MiLCAiQ21kLV0iOiAiaW5kZW50TW9yZSIsCi0gICAgZmFsbHRocm91Z2g6IFsiYmFzaWMiLCAiZW1hY3N5Il0KLSAgfTsKLSAga2V5TWFwWyJkZWZhdWx0Il0gPSBtYWMgPyBrZXlNYXAubWFjRGVmYXVsdCA6IGtleU1hcC5wY0RlZmF1bHQ7Ci0gIGtleU1hcC5lbWFjc3kgPSB7Ci0gICAgIkN0cmwtRiI6ICJnb0NoYXJSaWdodCIsICJDdHJsLUIiOiAiZ29DaGFyTGVmdCIsICJDdHJsLVAiOiAiZ29MaW5lVXAiLCAiQ3RybC1OIjogImdvTGluZURvd24iLAotICAgICJBbHQtRiI6ICJnb1dvcmRSaWdodCIsICJBbHQtQiI6ICJnb1dvcmRMZWZ0IiwgIkN0cmwtQSI6ICJnb0xpbmVTdGFydCIsICJDdHJsLUUiOiAiZ29MaW5lRW5kIiwKLSAgICAiQ3RybC1WIjogImdvUGFnZVVwIiwgIlNoaWZ0LUN0cmwtViI6ICJnb1BhZ2VEb3duIiwgIkN0cmwtRCI6ICJkZWxDaGFyUmlnaHQiLCAiQ3RybC1IIjogImRlbENoYXJMZWZ0IiwKLSAgICAiQWx0LUQiOiAiZGVsV29yZFJpZ2h0IiwgIkFsdC1CYWNrc3BhY2UiOiAiZGVsV29yZExlZnQiLCAiQ3RybC1LIjogImtpbGxMaW5lIiwgIkN0cmwtVCI6ICJ0cmFuc3Bvc2VDaGFycyIKLSAgfTsKLQotICBmdW5jdGlvbiBnZXRLZXlNYXAodmFsKSB7Ci0gICAgaWYgKHR5cGVvZiB2YWwgPT0gInN0cmluZyIpIHJldHVybiBrZXlNYXBbdmFsXTsKLSAgICBlbHNlIHJldHVybiB2YWw7Ci0gIH0KLSAgZnVuY3Rpb24gbG9va3VwS2V5KG5hbWUsIGV4dHJhTWFwLCBtYXAsIGhhbmRsZSwgc3RvcCkgewotICAgIGZ1bmN0aW9uIGxvb2t1cChtYXApIHsKLSAgICAgIG1hcCA9IGdldEtleU1hcChtYXApOwotICAgICAgdmFyIGZvdW5kID0gbWFwW25hbWVdOwotICAgICAgaWYgKGZvdW5kICE9IG51bGwgJiYgaGFuZGxlKGZvdW5kKSkgcmV0dXJuIHRydWU7Ci0gICAgICBpZiAobWFwLm5vZmFsbHRocm91Z2gpIHsKLSAgICAgICAgaWYgKHN0b3ApIHN0b3AoKTsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICB9Ci0gICAgICB2YXIgZmFsbHRocm91Z2ggPSBtYXAuZmFsbHRocm91Z2g7Ci0gICAgICBpZiAoZmFsbHRocm91Z2ggPT0gbnVsbCkgcmV0dXJuIGZhbHNlOwotICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChmYWxsdGhyb3VnaCkgIT0gIltvYmplY3QgQXJyYXldIikKLSAgICAgICAgcmV0dXJuIGxvb2t1cChmYWxsdGhyb3VnaCk7Ci0gICAgICBmb3IgKHZhciBpID0gMCwgZSA9IGZhbGx0aHJvdWdoLmxlbmd0aDsgaSA8IGU7ICsraSkgewotICAgICAgICBpZiAobG9va3VwKGZhbGx0aHJvdWdoW2ldKSkgcmV0dXJuIHRydWU7Ci0gICAgICB9Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotICAgIGlmIChleHRyYU1hcCAmJiBsb29rdXAoZXh0cmFNYXApKSByZXR1cm4gdHJ1ZTsKLSAgICByZXR1cm4gbG9va3VwKG1hcCk7Ci0gIH0KLSAgZnVuY3Rpb24gaXNNb2RpZmllcktleShldmVudCkgewotICAgIHZhciBuYW1lID0ga2V5TmFtZXNbZV9wcm9wKGV2ZW50LCAia2V5Q29kZSIpXTsKLSAgICByZXR1cm4gbmFtZSA9PSAiQ3RybCIgfHwgbmFtZSA9PSAiQWx0IiB8fCBuYW1lID09ICJTaGlmdCIgfHwgbmFtZSA9PSAiTW9kIjsKLSAgfQotCi0gIENvZGVNaXJyb3IuZnJvbVRleHRBcmVhID0gZnVuY3Rpb24odGV4dGFyZWEsIG9wdGlvbnMpIHsKLSAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTsKLSAgICBvcHRpb25zLnZhbHVlID0gdGV4dGFyZWEudmFsdWU7Ci0gICAgaWYgKCFvcHRpb25zLnRhYmluZGV4ICYmIHRleHRhcmVhLnRhYmluZGV4KQotICAgICAgb3B0aW9ucy50YWJpbmRleCA9IHRleHRhcmVhLnRhYmluZGV4OwotICAgIGlmIChvcHRpb25zLmF1dG9mb2N1cyA9PSBudWxsICYmIHRleHRhcmVhLmdldEF0dHJpYnV0ZSgiYXV0b2ZvY3VzIikgIT0gbnVsbCkKLSAgICAgIG9wdGlvbnMuYXV0b2ZvY3VzID0gdHJ1ZTsKLQotICAgIGZ1bmN0aW9uIHNhdmUoKSB7dGV4dGFyZWEudmFsdWUgPSBpbnN0YW5jZS5nZXRWYWx1ZSgpO30KLSAgICBpZiAodGV4dGFyZWEuZm9ybSkgewotICAgICAgLy8gRGVwbG9yYWJsZSBoYWNrIHRvIG1ha2UgdGhlIHN1Ym1pdCBtZXRob2QgZG8gdGhlIHJpZ2h0IHRoaW5nLgotICAgICAgdmFyIHJtU3VibWl0ID0gY29ubmVjdCh0ZXh0YXJlYS5mb3JtLCAic3VibWl0Iiwgc2F2ZSwgdHJ1ZSk7Ci0gICAgICBpZiAodHlwZW9mIHRleHRhcmVhLmZvcm0uc3VibWl0ID09ICJmdW5jdGlvbiIpIHsKLSAgICAgICAgdmFyIHJlYWxTdWJtaXQgPSB0ZXh0YXJlYS5mb3JtLnN1Ym1pdDsKLSAgICAgICAgZnVuY3Rpb24gd3JhcHBlZFN1Ym1pdCgpIHsKLSAgICAgICAgICBzYXZlKCk7Ci0gICAgICAgICAgdGV4dGFyZWEuZm9ybS5zdWJtaXQgPSByZWFsU3VibWl0OwotICAgICAgICAgIHRleHRhcmVhLmZvcm0uc3VibWl0KCk7Ci0gICAgICAgICAgdGV4dGFyZWEuZm9ybS5zdWJtaXQgPSB3cmFwcGVkU3VibWl0OwotICAgICAgICB9Ci0gICAgICAgIHRleHRhcmVhLmZvcm0uc3VibWl0ID0gd3JhcHBlZFN1Ym1pdDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICB0ZXh0YXJlYS5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwotICAgIHZhciBpbnN0YW5jZSA9IENvZGVNaXJyb3IoZnVuY3Rpb24obm9kZSkgewotICAgICAgdGV4dGFyZWEucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobm9kZSwgdGV4dGFyZWEubmV4dFNpYmxpbmcpOwotICAgIH0sIG9wdGlvbnMpOwotICAgIGluc3RhbmNlLnNhdmUgPSBzYXZlOwotICAgIGluc3RhbmNlLmdldFRleHRBcmVhID0gZnVuY3Rpb24oKSB7IHJldHVybiB0ZXh0YXJlYTsgfTsKLSAgICBpbnN0YW5jZS50b1RleHRBcmVhID0gZnVuY3Rpb24oKSB7Ci0gICAgICBzYXZlKCk7Ci0gICAgICB0ZXh0YXJlYS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGluc3RhbmNlLmdldFdyYXBwZXJFbGVtZW50KCkpOwotICAgICAgdGV4dGFyZWEuc3R5bGUuZGlzcGxheSA9ICIiOwotICAgICAgaWYgKHRleHRhcmVhLmZvcm0pIHsKLSAgICAgICAgcm1TdWJtaXQoKTsKLSAgICAgICAgaWYgKHR5cGVvZiB0ZXh0YXJlYS5mb3JtLnN1Ym1pdCA9PSAiZnVuY3Rpb24iKQotICAgICAgICAgIHRleHRhcmVhLmZvcm0uc3VibWl0ID0gcmVhbFN1Ym1pdDsKLSAgICAgIH0KLSAgICB9OwotICAgIHJldHVybiBpbnN0YW5jZTsKLSAgfTsKLQotICAvLyBVdGlsaXR5IGZ1bmN0aW9ucyBmb3Igd29ya2luZyB3aXRoIHN0YXRlLiBFeHBvcnRlZCBiZWNhdXNlIG1vZGVzCi0gIC8vIHNvbWV0aW1lcyBuZWVkIHRvIGRvIHRoaXMuCi0gIGZ1bmN0aW9uIGNvcHlTdGF0ZShtb2RlLCBzdGF0ZSkgewotICAgIGlmIChzdGF0ZSA9PT0gdHJ1ZSkgcmV0dXJuIHN0YXRlOwotICAgIGlmIChtb2RlLmNvcHlTdGF0ZSkgcmV0dXJuIG1vZGUuY29weVN0YXRlKHN0YXRlKTsKLSAgICB2YXIgbnN0YXRlID0ge307Ci0gICAgZm9yICh2YXIgbiBpbiBzdGF0ZSkgewotICAgICAgdmFyIHZhbCA9IHN0YXRlW25dOwotICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIEFycmF5KSB2YWwgPSB2YWwuY29uY2F0KFtdKTsKLSAgICAgIG5zdGF0ZVtuXSA9IHZhbDsKLSAgICB9Ci0gICAgcmV0dXJuIG5zdGF0ZTsKLSAgfQotICBDb2RlTWlycm9yLmNvcHlTdGF0ZSA9IGNvcHlTdGF0ZTsKLSAgZnVuY3Rpb24gc3RhcnRTdGF0ZShtb2RlLCBhMSwgYTIpIHsKLSAgICByZXR1cm4gbW9kZS5zdGFydFN0YXRlID8gbW9kZS5zdGFydFN0YXRlKGExLCBhMikgOiB0cnVlOwotICB9Ci0gIENvZGVNaXJyb3Iuc3RhcnRTdGF0ZSA9IHN0YXJ0U3RhdGU7Ci0KLSAgLy8gVGhlIGNoYXJhY3RlciBzdHJlYW0gdXNlZCBieSBhIG1vZGUncyBwYXJzZXIuCi0gIGZ1bmN0aW9uIFN0cmluZ1N0cmVhbShzdHJpbmcsIHRhYlNpemUpIHsKLSAgICB0aGlzLnBvcyA9IHRoaXMuc3RhcnQgPSAwOwotICAgIHRoaXMuc3RyaW5nID0gc3RyaW5nOwotICAgIHRoaXMudGFiU2l6ZSA9IHRhYlNpemUgfHwgODsKLSAgfQotICBTdHJpbmdTdHJlYW0ucHJvdG90eXBlID0gewotICAgIGVvbDogZnVuY3Rpb24oKSB7cmV0dXJuIHRoaXMucG9zID49IHRoaXMuc3RyaW5nLmxlbmd0aDt9LAotICAgIHNvbDogZnVuY3Rpb24oKSB7cmV0dXJuIHRoaXMucG9zID09IDA7fSwKLSAgICBwZWVrOiBmdW5jdGlvbigpIHtyZXR1cm4gdGhpcy5zdHJpbmcuY2hhckF0KHRoaXMucG9zKTt9LAotICAgIG5leHQ6IGZ1bmN0aW9uKCkgewotICAgICAgaWYgKHRoaXMucG9zIDwgdGhpcy5zdHJpbmcubGVuZ3RoKQotICAgICAgICByZXR1cm4gdGhpcy5zdHJpbmcuY2hhckF0KHRoaXMucG9zKyspOwotICAgIH0sCi0gICAgZWF0OiBmdW5jdGlvbihtYXRjaCkgewotICAgICAgdmFyIGNoID0gdGhpcy5zdHJpbmcuY2hhckF0KHRoaXMucG9zKTsKLSAgICAgIGlmICh0eXBlb2YgbWF0Y2ggPT0gInN0cmluZyIpIHZhciBvayA9IGNoID09IG1hdGNoOwotICAgICAgZWxzZSB2YXIgb2sgPSBjaCAmJiAobWF0Y2gudGVzdCA/IG1hdGNoLnRlc3QoY2gpIDogbWF0Y2goY2gpKTsKLSAgICAgIGlmIChvaykgeysrdGhpcy5wb3M7IHJldHVybiBjaDt9Ci0gICAgfSwKLSAgICBlYXRXaGlsZTogZnVuY3Rpb24obWF0Y2gpIHsKLSAgICAgIHZhciBzdGFydCA9IHRoaXMucG9zOwotICAgICAgd2hpbGUgKHRoaXMuZWF0KG1hdGNoKSl7fQotICAgICAgcmV0dXJuIHRoaXMucG9zID4gc3RhcnQ7Ci0gICAgfSwKLSAgICBlYXRTcGFjZTogZnVuY3Rpb24oKSB7Ci0gICAgICB2YXIgc3RhcnQgPSB0aGlzLnBvczsKLSAgICAgIHdoaWxlICgvW1xzXHUwMGEwXS8udGVzdCh0aGlzLnN0cmluZy5jaGFyQXQodGhpcy5wb3MpKSkgKyt0aGlzLnBvczsKLSAgICAgIHJldHVybiB0aGlzLnBvcyA+IHN0YXJ0OwotICAgIH0sCi0gICAgc2tpcFRvRW5kOiBmdW5jdGlvbigpIHt0aGlzLnBvcyA9IHRoaXMuc3RyaW5nLmxlbmd0aDt9LAotICAgIHNraXBUbzogZnVuY3Rpb24oY2gpIHsKLSAgICAgIHZhciBmb3VuZCA9IHRoaXMuc3RyaW5nLmluZGV4T2YoY2gsIHRoaXMucG9zKTsKLSAgICAgIGlmIChmb3VuZCA+IC0xKSB7dGhpcy5wb3MgPSBmb3VuZDsgcmV0dXJuIHRydWU7fQotICAgIH0sCi0gICAgYmFja1VwOiBmdW5jdGlvbihuKSB7dGhpcy5wb3MgLT0gbjt9LAotICAgIGNvbHVtbjogZnVuY3Rpb24oKSB7cmV0dXJuIGNvdW50Q29sdW1uKHRoaXMuc3RyaW5nLCB0aGlzLnN0YXJ0LCB0aGlzLnRhYlNpemUpO30sCi0gICAgaW5kZW50YXRpb246IGZ1bmN0aW9uKCkge3JldHVybiBjb3VudENvbHVtbih0aGlzLnN0cmluZywgbnVsbCwgdGhpcy50YWJTaXplKTt9LAotICAgIG1hdGNoOiBmdW5jdGlvbihwYXR0ZXJuLCBjb25zdW1lLCBjYXNlSW5zZW5zaXRpdmUpIHsKLSAgICAgIGlmICh0eXBlb2YgcGF0dGVybiA9PSAic3RyaW5nIikgewotICAgICAgICBmdW5jdGlvbiBjYXNlZChzdHIpIHtyZXR1cm4gY2FzZUluc2Vuc2l0aXZlID8gc3RyLnRvTG93ZXJDYXNlKCkgOiBzdHI7fQotICAgICAgICBpZiAoY2FzZWQodGhpcy5zdHJpbmcpLmluZGV4T2YoY2FzZWQocGF0dGVybiksIHRoaXMucG9zKSA9PSB0aGlzLnBvcykgewotICAgICAgICAgIGlmIChjb25zdW1lICE9PSBmYWxzZSkgdGhpcy5wb3MgKz0gcGF0dGVybi5sZW5ndGg7Ci0gICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UgewotICAgICAgICB2YXIgbWF0Y2ggPSB0aGlzLnN0cmluZy5zbGljZSh0aGlzLnBvcykubWF0Y2gocGF0dGVybik7Ci0gICAgICAgIGlmIChtYXRjaCAmJiBjb25zdW1lICE9PSBmYWxzZSkgdGhpcy5wb3MgKz0gbWF0Y2hbMF0ubGVuZ3RoOwotICAgICAgICByZXR1cm4gbWF0Y2g7Ci0gICAgICB9Ci0gICAgfSwKLSAgICBjdXJyZW50OiBmdW5jdGlvbigpe3JldHVybiB0aGlzLnN0cmluZy5zbGljZSh0aGlzLnN0YXJ0LCB0aGlzLnBvcyk7fQotICB9OwotICBDb2RlTWlycm9yLlN0cmluZ1N0cmVhbSA9IFN0cmluZ1N0cmVhbTsKLQotICBmdW5jdGlvbiBNYXJrZWRUZXh0KGZyb20sIHRvLCBjbGFzc05hbWUsIG1hcmtlcikgewotICAgIHRoaXMuZnJvbSA9IGZyb207IHRoaXMudG8gPSB0bzsgdGhpcy5zdHlsZSA9IGNsYXNzTmFtZTsgdGhpcy5tYXJrZXIgPSBtYXJrZXI7Ci0gIH0KLSAgTWFya2VkVGV4dC5wcm90b3R5cGUgPSB7Ci0gICAgYXR0YWNoOiBmdW5jdGlvbihsaW5lKSB7IHRoaXMubWFya2VyLnNldC5wdXNoKGxpbmUpOyB9LAotICAgIGRldGFjaDogZnVuY3Rpb24obGluZSkgewotICAgICAgdmFyIGl4ID0gaW5kZXhPZih0aGlzLm1hcmtlci5zZXQsIGxpbmUpOwotICAgICAgaWYgKGl4ID4gLTEpIHRoaXMubWFya2VyLnNldC5zcGxpY2UoaXgsIDEpOwotICAgIH0sCi0gICAgc3BsaXQ6IGZ1bmN0aW9uKHBvcywgbGVuQmVmb3JlKSB7Ci0gICAgICBpZiAodGhpcy50byA8PSBwb3MgJiYgdGhpcy50byAhPSBudWxsKSByZXR1cm4gbnVsbDsKLSAgICAgIHZhciBmcm9tID0gdGhpcy5mcm9tIDwgcG9zIHx8IHRoaXMuZnJvbSA9PSBudWxsID8gbnVsbCA6IHRoaXMuZnJvbSAtIHBvcyArIGxlbkJlZm9yZTsKLSAgICAgIHZhciB0byA9IHRoaXMudG8gPT0gbnVsbCA/IG51bGwgOiB0aGlzLnRvIC0gcG9zICsgbGVuQmVmb3JlOwotICAgICAgcmV0dXJuIG5ldyBNYXJrZWRUZXh0KGZyb20sIHRvLCB0aGlzLnN0eWxlLCB0aGlzLm1hcmtlcik7Ci0gICAgfSwKLSAgICBkdXA6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbmV3IE1hcmtlZFRleHQobnVsbCwgbnVsbCwgdGhpcy5zdHlsZSwgdGhpcy5tYXJrZXIpOyB9LAotICAgIGNsaXBUbzogZnVuY3Rpb24oZnJvbU9wZW4sIGZyb20sIHRvT3BlbiwgdG8sIGRpZmYpIHsKLSAgICAgIGlmIChmcm9tT3BlbiAmJiB0byA+IHRoaXMuZnJvbSAmJiAodG8gPCB0aGlzLnRvIHx8IHRoaXMudG8gPT0gbnVsbCkpCi0gICAgICAgIHRoaXMuZnJvbSA9IG51bGw7Ci0gICAgICBlbHNlIGlmICh0aGlzLmZyb20gIT0gbnVsbCAmJiB0aGlzLmZyb20gPj0gZnJvbSkKLSAgICAgICAgdGhpcy5mcm9tID0gTWF0aC5tYXgodG8sIHRoaXMuZnJvbSkgKyBkaWZmOwotICAgICAgaWYgKHRvT3BlbiAmJiAoZnJvbSA8IHRoaXMudG8gfHwgdGhpcy50byA9PSBudWxsKSAmJiAoZnJvbSA+IHRoaXMuZnJvbSB8fCB0aGlzLmZyb20gPT0gbnVsbCkpCi0gICAgICAgIHRoaXMudG8gPSBudWxsOwotICAgICAgZWxzZSBpZiAodGhpcy50byAhPSBudWxsICYmIHRoaXMudG8gPiBmcm9tKQotICAgICAgICB0aGlzLnRvID0gdG8gPCB0aGlzLnRvID8gdGhpcy50byArIGRpZmYgOiBmcm9tOwotICAgIH0sCi0gICAgaXNEZWFkOiBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXMuZnJvbSAhPSBudWxsICYmIHRoaXMudG8gIT0gbnVsbCAmJiB0aGlzLmZyb20gPj0gdGhpcy50bzsgfSwKLSAgICBzYW1lU2V0OiBmdW5jdGlvbih4KSB7IHJldHVybiB0aGlzLm1hcmtlciA9PSB4Lm1hcmtlcjsgfQotICB9OwotCi0gIGZ1bmN0aW9uIEJvb2ttYXJrKHBvcykgewotICAgIHRoaXMuZnJvbSA9IHBvczsgdGhpcy50byA9IHBvczsgdGhpcy5saW5lID0gbnVsbDsKLSAgfQotICBCb29rbWFyay5wcm90b3R5cGUgPSB7Ci0gICAgYXR0YWNoOiBmdW5jdGlvbihsaW5lKSB7IHRoaXMubGluZSA9IGxpbmU7IH0sCi0gICAgZGV0YWNoOiBmdW5jdGlvbihsaW5lKSB7IGlmICh0aGlzLmxpbmUgPT0gbGluZSkgdGhpcy5saW5lID0gbnVsbDsgfSwKLSAgICBzcGxpdDogZnVuY3Rpb24ocG9zLCBsZW5CZWZvcmUpIHsKLSAgICAgIGlmIChwb3MgPCB0aGlzLmZyb20pIHsKLSAgICAgICAgdGhpcy5mcm9tID0gdGhpcy50byA9ICh0aGlzLmZyb20gLSBwb3MpICsgbGVuQmVmb3JlOwotICAgICAgICByZXR1cm4gdGhpczsKLSAgICAgIH0KLSAgICB9LAotICAgIGlzRGVhZDogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLmZyb20gPiB0aGlzLnRvOyB9LAotICAgIGNsaXBUbzogZnVuY3Rpb24oZnJvbU9wZW4sIGZyb20sIHRvT3BlbiwgdG8sIGRpZmYpIHsKLSAgICAgIGlmICgoZnJvbU9wZW4gfHwgZnJvbSA8IHRoaXMuZnJvbSkgJiYgKHRvT3BlbiB8fCB0byA+IHRoaXMudG8pKSB7Ci0gICAgICAgIHRoaXMuZnJvbSA9IDA7IHRoaXMudG8gPSAtMTsKLSAgICAgIH0gZWxzZSBpZiAodGhpcy5mcm9tID4gZnJvbSkgewotICAgICAgICB0aGlzLmZyb20gPSB0aGlzLnRvID0gTWF0aC5tYXgodG8sIHRoaXMuZnJvbSkgKyBkaWZmOwotICAgICAgfQotICAgIH0sCi0gICAgc2FtZVNldDogZnVuY3Rpb24oeCkgeyByZXR1cm4gZmFsc2U7IH0sCi0gICAgZmluZDogZnVuY3Rpb24oKSB7Ci0gICAgICBpZiAoIXRoaXMubGluZSB8fCAhdGhpcy5saW5lLnBhcmVudCkgcmV0dXJuIG51bGw7Ci0gICAgICByZXR1cm4ge2xpbmU6IGxpbmVObyh0aGlzLmxpbmUpLCBjaDogdGhpcy5mcm9tfTsKLSAgICB9LAotICAgIGNsZWFyOiBmdW5jdGlvbigpIHsKLSAgICAgIGlmICh0aGlzLmxpbmUpIHsKLSAgICAgICAgdmFyIGZvdW5kID0gaW5kZXhPZih0aGlzLmxpbmUubWFya2VkLCB0aGlzKTsKLSAgICAgICAgaWYgKGZvdW5kICE9IC0xKSB0aGlzLmxpbmUubWFya2VkLnNwbGljZShmb3VuZCwgMSk7Ci0gICAgICAgIHRoaXMubGluZSA9IG51bGw7Ci0gICAgICB9Ci0gICAgfQotICB9OwotCi0gIC8vIExpbmUgb2JqZWN0cy4gVGhlc2UgaG9sZCBzdGF0ZSByZWxhdGVkIHRvIGEgbGluZSwgaW5jbHVkaW5nCi0gIC8vIGhpZ2hsaWdodGluZyBpbmZvICh0aGUgc3R5bGVzIGFycmF5KS4KLSAgZnVuY3Rpb24gTGluZSh0ZXh0LCBzdHlsZXMpIHsKLSAgICB0aGlzLnN0eWxlcyA9IHN0eWxlcyB8fCBbdGV4dCwgbnVsbF07Ci0gICAgdGhpcy50ZXh0ID0gdGV4dDsKLSAgICB0aGlzLmhlaWdodCA9IDE7Ci0gICAgdGhpcy5tYXJrZWQgPSB0aGlzLmd1dHRlck1hcmtlciA9IHRoaXMuY2xhc3NOYW1lID0gdGhpcy5iZ0NsYXNzTmFtZSA9IHRoaXMuaGFuZGxlcnMgPSBudWxsOwotICAgIHRoaXMuc3RhdGVBZnRlciA9IHRoaXMucGFyZW50ID0gdGhpcy5oaWRkZW4gPSBudWxsOwotICB9Ci0gIExpbmUuaW5oZXJpdE1hcmtzID0gZnVuY3Rpb24odGV4dCwgb3JpZykgewotICAgIHZhciBsbiA9IG5ldyBMaW5lKHRleHQpLCBtayA9IG9yaWcgJiYgb3JpZy5tYXJrZWQ7Ci0gICAgaWYgKG1rKSB7Ci0gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1rLmxlbmd0aDsgKytpKSB7Ci0gICAgICAgIGlmIChta1tpXS50byA9PSBudWxsICYmIG1rW2ldLnN0eWxlKSB7Ci0gICAgICAgICAgdmFyIG5ld21rID0gbG4ubWFya2VkIHx8IChsbi5tYXJrZWQgPSBbXSksIG1hcmsgPSBta1tpXTsKLSAgICAgICAgICB2YXIgbm1hcmsgPSBtYXJrLmR1cCgpOyBuZXdtay5wdXNoKG5tYXJrKTsgbm1hcmsuYXR0YWNoKGxuKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICByZXR1cm4gbG47Ci0gIH0KLSAgTGluZS5wcm90b3R5cGUgPSB7Ci0gICAgLy8gUmVwbGFjZSBhIHBpZWNlIG9mIGEgbGluZSwga2VlcGluZyB0aGUgc3R5bGVzIGFyb3VuZCBpdCBpbnRhY3QuCi0gICAgcmVwbGFjZTogZnVuY3Rpb24oZnJvbSwgdG9fLCB0ZXh0KSB7Ci0gICAgICB2YXIgc3QgPSBbXSwgbWsgPSB0aGlzLm1hcmtlZCwgdG8gPSB0b18gPT0gbnVsbCA/IHRoaXMudGV4dC5sZW5ndGggOiB0b187Ci0gICAgICBjb3B5U3R5bGVzKDAsIGZyb20sIHRoaXMuc3R5bGVzLCBzdCk7Ci0gICAgICBpZiAodGV4dCkgc3QucHVzaCh0ZXh0LCBudWxsKTsKLSAgICAgIGNvcHlTdHlsZXModG8sIHRoaXMudGV4dC5sZW5ndGgsIHRoaXMuc3R5bGVzLCBzdCk7Ci0gICAgICB0aGlzLnN0eWxlcyA9IHN0OwotICAgICAgdGhpcy50ZXh0ID0gdGhpcy50ZXh0LnNsaWNlKDAsIGZyb20pICsgdGV4dCArIHRoaXMudGV4dC5zbGljZSh0byk7Ci0gICAgICB0aGlzLnN0YXRlQWZ0ZXIgPSBudWxsOwotICAgICAgaWYgKG1rKSB7Ci0gICAgICAgIHZhciBkaWZmID0gdGV4dC5sZW5ndGggLSAodG8gLSBmcm9tKTsKLSAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtay5sZW5ndGg7ICsraSkgewotICAgICAgICAgIHZhciBtYXJrID0gbWtbaV07Ci0gICAgICAgICAgbWFyay5jbGlwVG8oZnJvbSA9PSBudWxsLCBmcm9tIHx8IDAsIHRvXyA9PSBudWxsLCB0bywgZGlmZik7Ci0gICAgICAgICAgaWYgKG1hcmsuaXNEZWFkKCkpIHttYXJrLmRldGFjaCh0aGlzKTsgbWsuc3BsaWNlKGktLSwgMSk7fQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfSwKLSAgICAvLyBTcGxpdCBhIHBhcnQgb2ZmIGEgbGluZSwga2VlcGluZyBzdHlsZXMgYW5kIG1hcmtlcnMgaW50YWN0LgotICAgIHNwbGl0OiBmdW5jdGlvbihwb3MsIHRleHRCZWZvcmUpIHsKLSAgICAgIHZhciBzdCA9IFt0ZXh0QmVmb3JlLCBudWxsXSwgbWsgPSB0aGlzLm1hcmtlZDsKLSAgICAgIGNvcHlTdHlsZXMocG9zLCB0aGlzLnRleHQubGVuZ3RoLCB0aGlzLnN0eWxlcywgc3QpOwotICAgICAgdmFyIHRha2VuID0gbmV3IExpbmUodGV4dEJlZm9yZSArIHRoaXMudGV4dC5zbGljZShwb3MpLCBzdCk7Ci0gICAgICBpZiAobWspIHsKLSAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtay5sZW5ndGg7ICsraSkgewotICAgICAgICAgIHZhciBtYXJrID0gbWtbaV07Ci0gICAgICAgICAgdmFyIG5ld21hcmsgPSBtYXJrLnNwbGl0KHBvcywgdGV4dEJlZm9yZS5sZW5ndGgpOwotICAgICAgICAgIGlmIChuZXdtYXJrKSB7Ci0gICAgICAgICAgICBpZiAoIXRha2VuLm1hcmtlZCkgdGFrZW4ubWFya2VkID0gW107Ci0gICAgICAgICAgICB0YWtlbi5tYXJrZWQucHVzaChuZXdtYXJrKTsgbmV3bWFyay5hdHRhY2godGFrZW4pOwotICAgICAgICAgICAgaWYgKG5ld21hcmsgPT0gbWFyaykgbWsuc3BsaWNlKGktLSwgMSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICByZXR1cm4gdGFrZW47Ci0gICAgfSwKLSAgICBhcHBlbmQ6IGZ1bmN0aW9uKGxpbmUpIHsKLSAgICAgIHZhciBteWxlbiA9IHRoaXMudGV4dC5sZW5ndGgsIG1rID0gbGluZS5tYXJrZWQsIG15bWsgPSB0aGlzLm1hcmtlZDsKLSAgICAgIHRoaXMudGV4dCArPSBsaW5lLnRleHQ7Ci0gICAgICBjb3B5U3R5bGVzKDAsIGxpbmUudGV4dC5sZW5ndGgsIGxpbmUuc3R5bGVzLCB0aGlzLnN0eWxlcyk7Ci0gICAgICBpZiAobXltaykgewotICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG15bWsubGVuZ3RoOyArK2kpCi0gICAgICAgICAgaWYgKG15bWtbaV0udG8gPT0gbnVsbCkgbXlta1tpXS50byA9IG15bGVuOwotICAgICAgfQotICAgICAgaWYgKG1rICYmIG1rLmxlbmd0aCkgewotICAgICAgICBpZiAoIW15bWspIHRoaXMubWFya2VkID0gbXltayA9IFtdOwotICAgICAgICBvdXRlcjogZm9yICh2YXIgaSA9IDA7IGkgPCBtay5sZW5ndGg7ICsraSkgewotICAgICAgICAgIHZhciBtYXJrID0gbWtbaV07Ci0gICAgICAgICAgaWYgKCFtYXJrLmZyb20pIHsKLSAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbXltay5sZW5ndGg7ICsraikgewotICAgICAgICAgICAgICB2YXIgbXltYXJrID0gbXlta1tqXTsKLSAgICAgICAgICAgICAgaWYgKG15bWFyay50byA9PSBteWxlbiAmJiBteW1hcmsuc2FtZVNldChtYXJrKSkgewotICAgICAgICAgICAgICAgIG15bWFyay50byA9IG1hcmsudG8gPT0gbnVsbCA/IG51bGwgOiBtYXJrLnRvICsgbXlsZW47Ci0gICAgICAgICAgICAgICAgaWYgKG15bWFyay5pc0RlYWQoKSkgewotICAgICAgICAgICAgICAgICAgbXltYXJrLmRldGFjaCh0aGlzKTsKLSAgICAgICAgICAgICAgICAgIG1rLnNwbGljZShpLS0sIDEpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjb250aW51ZSBvdXRlcjsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBteW1rLnB1c2gobWFyayk7Ci0gICAgICAgICAgbWFyay5hdHRhY2godGhpcyk7Ci0gICAgICAgICAgbWFyay5mcm9tICs9IG15bGVuOwotICAgICAgICAgIGlmIChtYXJrLnRvICE9IG51bGwpIG1hcmsudG8gKz0gbXlsZW47Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9LAotICAgIGZpeE1hcmtFbmRzOiBmdW5jdGlvbihvdGhlcikgewotICAgICAgdmFyIG1rID0gdGhpcy5tYXJrZWQsIG9tayA9IG90aGVyLm1hcmtlZDsKLSAgICAgIGlmICghbWspIHJldHVybjsKLSAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWsubGVuZ3RoOyArK2kpIHsKLSAgICAgICAgdmFyIG1hcmsgPSBta1tpXSwgY2xvc2UgPSBtYXJrLnRvID09IG51bGw7Ci0gICAgICAgIGlmIChjbG9zZSAmJiBvbWspIHsKLSAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG9tay5sZW5ndGg7ICsraikKLSAgICAgICAgICAgIGlmIChvbWtbal0uc2FtZVNldChtYXJrKSkge2Nsb3NlID0gZmFsc2U7IGJyZWFrO30KLSAgICAgICAgfQotICAgICAgICBpZiAoY2xvc2UpIG1hcmsudG8gPSB0aGlzLnRleHQubGVuZ3RoOwotICAgICAgfQotICAgIH0sCi0gICAgZml4TWFya1N0YXJ0czogZnVuY3Rpb24oKSB7Ci0gICAgICB2YXIgbWsgPSB0aGlzLm1hcmtlZDsKLSAgICAgIGlmICghbWspIHJldHVybjsKLSAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWsubGVuZ3RoOyArK2kpCi0gICAgICAgIGlmIChta1tpXS5mcm9tID09IG51bGwpIG1rW2ldLmZyb20gPSAwOwotICAgIH0sCi0gICAgYWRkTWFyazogZnVuY3Rpb24obWFyaykgewotICAgICAgbWFyay5hdHRhY2godGhpcyk7Ci0gICAgICBpZiAodGhpcy5tYXJrZWQgPT0gbnVsbCkgdGhpcy5tYXJrZWQgPSBbXTsKLSAgICAgIHRoaXMubWFya2VkLnB1c2gobWFyayk7Ci0gICAgICB0aGlzLm1hcmtlZC5zb3J0KGZ1bmN0aW9uKGEsIGIpe3JldHVybiAoYS5mcm9tIHx8IDApIC0gKGIuZnJvbSB8fCAwKTt9KTsKLSAgICB9LAotICAgIC8vIFJ1biB0aGUgZ2l2ZW4gbW9kZSdzIHBhcnNlciBvdmVyIGEgbGluZSwgdXBkYXRlIHRoZSBzdHlsZXMKLSAgICAvLyBhcnJheSwgd2hpY2ggY29udGFpbnMgYWx0ZXJuYXRpbmcgZnJhZ21lbnRzIG9mIHRleHQgYW5kIENTUwotICAgIC8vIGNsYXNzZXMuCi0gICAgaGlnaGxpZ2h0OiBmdW5jdGlvbihtb2RlLCBzdGF0ZSwgdGFiU2l6ZSkgewotICAgICAgdmFyIHN0cmVhbSA9IG5ldyBTdHJpbmdTdHJlYW0odGhpcy50ZXh0LCB0YWJTaXplKSwgc3QgPSB0aGlzLnN0eWxlcywgcG9zID0gMDsKLSAgICAgIHZhciBjaGFuZ2VkID0gZmFsc2UsIGN1cldvcmQgPSBzdFswXSwgcHJldldvcmQ7Ci0gICAgICBpZiAodGhpcy50ZXh0ID09ICIiICYmIG1vZGUuYmxhbmtMaW5lKSBtb2RlLmJsYW5rTGluZShzdGF0ZSk7Ci0gICAgICB3aGlsZSAoIXN0cmVhbS5lb2woKSkgewotICAgICAgICB2YXIgc3R5bGUgPSBtb2RlLnRva2VuKHN0cmVhbSwgc3RhdGUpOwotICAgICAgICB2YXIgc3Vic3RyID0gdGhpcy50ZXh0LnNsaWNlKHN0cmVhbS5zdGFydCwgc3RyZWFtLnBvcyk7Ci0gICAgICAgIHN0cmVhbS5zdGFydCA9IHN0cmVhbS5wb3M7Ci0gICAgICAgIGlmIChwb3MgJiYgc3RbcG9zLTFdID09IHN0eWxlKQotICAgICAgICAgIHN0W3Bvcy0yXSArPSBzdWJzdHI7Ci0gICAgICAgIGVsc2UgaWYgKHN1YnN0cikgewotICAgICAgICAgIGlmICghY2hhbmdlZCAmJiAoc3RbcG9zKzFdICE9IHN0eWxlIHx8IChwb3MgJiYgc3RbcG9zLTJdICE9IHByZXZXb3JkKSkpIGNoYW5nZWQgPSB0cnVlOwotICAgICAgICAgIHN0W3BvcysrXSA9IHN1YnN0cjsgc3RbcG9zKytdID0gc3R5bGU7Ci0gICAgICAgICAgcHJldldvcmQgPSBjdXJXb3JkOyBjdXJXb3JkID0gc3RbcG9zXTsKLSAgICAgICAgfQotICAgICAgICAvLyBHaXZlIHVwIHdoZW4gbGluZSBpcyByaWRpY3Vsb3VzbHkgbG9uZwotICAgICAgICBpZiAoc3RyZWFtLnBvcyA+IDUwMDApIHsKLSAgICAgICAgICBzdFtwb3MrK10gPSB0aGlzLnRleHQuc2xpY2Uoc3RyZWFtLnBvcyk7IHN0W3BvcysrXSA9IG51bGw7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGlmIChzdC5sZW5ndGggIT0gcG9zKSB7c3QubGVuZ3RoID0gcG9zOyBjaGFuZ2VkID0gdHJ1ZTt9Ci0gICAgICBpZiAocG9zICYmIHN0W3Bvcy0yXSAhPSBwcmV2V29yZCkgY2hhbmdlZCA9IHRydWU7Ci0gICAgICAvLyBTaG9ydCBsaW5lcyB3aXRoIHNpbXBsZSBoaWdobGlnaHRzIHJldHVybiBudWxsLCBhbmQgYXJlCi0gICAgICAvLyBjb3VudGVkIGFzIGNoYW5nZWQgYnkgdGhlIGRyaXZlciBiZWNhdXNlIHRoZXkgYXJlIGxpa2VseSB0bwotICAgICAgLy8gaGlnaGxpZ2h0IHRoZSBzYW1lIHdheSBpbiB2YXJpb3VzIGNvbnRleHRzLgotICAgICAgcmV0dXJuIGNoYW5nZWQgfHwgKHN0Lmxlbmd0aCA8IDUgJiYgdGhpcy50ZXh0Lmxlbmd0aCA8IDEwID8gbnVsbCA6IGZhbHNlKTsKLSAgICB9LAotICAgIC8vIEZldGNoIHRoZSBwYXJzZXIgdG9rZW4gZm9yIGEgZ2l2ZW4gY2hhcmFjdGVyLiBVc2VmdWwgZm9yIGhhY2tzCi0gICAgLy8gdGhhdCB3YW50IHRvIGluc3BlY3QgdGhlIG1vZGUgc3RhdGUgKHNheSwgZm9yIGNvbXBsZXRpb24pLgotICAgIGdldFRva2VuQXQ6IGZ1bmN0aW9uKG1vZGUsIHN0YXRlLCBjaCkgewotICAgICAgdmFyIHR4dCA9IHRoaXMudGV4dCwgc3RyZWFtID0gbmV3IFN0cmluZ1N0cmVhbSh0eHQpOwotICAgICAgd2hpbGUgKHN0cmVhbS5wb3MgPCBjaCAmJiAhc3RyZWFtLmVvbCgpKSB7Ci0gICAgICAgIHN0cmVhbS5zdGFydCA9IHN0cmVhbS5wb3M7Ci0gICAgICAgIHZhciBzdHlsZSA9IG1vZGUudG9rZW4oc3RyZWFtLCBzdGF0ZSk7Ci0gICAgICB9Ci0gICAgICByZXR1cm4ge3N0YXJ0OiBzdHJlYW0uc3RhcnQsCi0gICAgICAgICAgICAgIGVuZDogc3RyZWFtLnBvcywKLSAgICAgICAgICAgICAgc3RyaW5nOiBzdHJlYW0uY3VycmVudCgpLAotICAgICAgICAgICAgICBjbGFzc05hbWU6IHN0eWxlIHx8IG51bGwsCi0gICAgICAgICAgICAgIHN0YXRlOiBzdGF0ZX07Ci0gICAgfSwKLSAgICBpbmRlbnRhdGlvbjogZnVuY3Rpb24odGFiU2l6ZSkge3JldHVybiBjb3VudENvbHVtbih0aGlzLnRleHQsIG51bGwsIHRhYlNpemUpO30sCi0gICAgLy8gUHJvZHVjZXMgYW4gSFRNTCBmcmFnbWVudCBmb3IgdGhlIGxpbmUsIHRha2luZyBzZWxlY3Rpb24sCi0gICAgLy8gbWFya2luZywgYW5kIGhpZ2hsaWdodGluZyBpbnRvIGFjY291bnQuCi0gICAgZ2V0SFRNTDogZnVuY3Rpb24obWFrZVRhYiwgd3JhcEF0LCB3cmFwSWQsIHdyYXBXQlIpIHsKLSAgICAgIHZhciBodG1sID0gW10sIGZpcnN0ID0gdHJ1ZSwgY29sID0gMDsKLSAgICAgIGZ1bmN0aW9uIHNwYW5fKHRleHQsIHN0eWxlKSB7Ci0gICAgICAgIGlmICghdGV4dCkgcmV0dXJuOwotICAgICAgICAvLyBXb3JrIGFyb3VuZCBhIGJ1ZyB3aGVyZSwgaW4gc29tZSBjb21wYXQgbW9kZXMsIElFIGlnbm9yZXMgbGVhZGluZyBzcGFjZXMKLSAgICAgICAgaWYgKGZpcnN0ICYmIGllICYmIHRleHQuY2hhckF0KDApID09ICIgIikgdGV4dCA9ICJcdTAwYTAiICsgdGV4dC5zbGljZSgxKTsKLSAgICAgICAgZmlyc3QgPSBmYWxzZTsKLSAgICAgICAgaWYgKHRleHQuaW5kZXhPZigiXHQiKSA9PSAtMSkgewotICAgICAgICAgIGNvbCArPSB0ZXh0Lmxlbmd0aDsKLSAgICAgICAgICB2YXIgZXNjYXBlZCA9IGh0bWxFc2NhcGUodGV4dCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgdmFyIGVzY2FwZWQgPSAiIjsKLSAgICAgICAgICBmb3IgKHZhciBwb3MgPSAwOzspIHsKLSAgICAgICAgICAgIHZhciBpZHggPSB0ZXh0LmluZGV4T2YoIlx0IiwgcG9zKTsKLSAgICAgICAgICAgIGlmIChpZHggPT0gLTEpIHsKLSAgICAgICAgICAgICAgZXNjYXBlZCArPSBodG1sRXNjYXBlKHRleHQuc2xpY2UocG9zKSk7Ci0gICAgICAgICAgICAgIGNvbCArPSB0ZXh0Lmxlbmd0aCAtIHBvczsKLSAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICBjb2wgKz0gaWR4IC0gcG9zOwotICAgICAgICAgICAgICB2YXIgdGFiID0gbWFrZVRhYihjb2wpOwotICAgICAgICAgICAgICBlc2NhcGVkICs9IGh0bWxFc2NhcGUodGV4dC5zbGljZShwb3MsIGlkeCkpICsgdGFiLmh0bWw7Ci0gICAgICAgICAgICAgIGNvbCArPSB0YWIud2lkdGg7Ci0gICAgICAgICAgICAgIHBvcyA9IGlkeCArIDE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChzdHlsZSkgaHRtbC5wdXNoKCc8c3BhbiBjbGFzcz0iJywgc3R5bGUsICciPicsIGVzY2FwZWQsICI8L3NwYW4+Iik7Ci0gICAgICAgIGVsc2UgaHRtbC5wdXNoKGVzY2FwZWQpOwotICAgICAgfQotICAgICAgdmFyIHNwYW4gPSBzcGFuXzsKLSAgICAgIGlmICh3cmFwQXQgIT0gbnVsbCkgewotICAgICAgICB2YXIgb3V0UG9zID0gMCwgb3BlbiA9ICI8c3BhbiBpZD1cIiIgKyB3cmFwSWQgKyAiXCI+IjsKLSAgICAgICAgc3BhbiA9IGZ1bmN0aW9uKHRleHQsIHN0eWxlKSB7Ci0gICAgICAgICAgdmFyIGwgPSB0ZXh0Lmxlbmd0aDsKLSAgICAgICAgICBpZiAod3JhcEF0ID49IG91dFBvcyAmJiB3cmFwQXQgPCBvdXRQb3MgKyBsKSB7Ci0gICAgICAgICAgICBpZiAod3JhcEF0ID4gb3V0UG9zKSB7Ci0gICAgICAgICAgICAgIHNwYW5fKHRleHQuc2xpY2UoMCwgd3JhcEF0IC0gb3V0UG9zKSwgc3R5bGUpOwotICAgICAgICAgICAgICAvLyBTZWUgY29tbWVudCBhdCB0aGUgZGVmaW5pdGlvbiBvZiBzcGFuQWZmZWN0c1dyYXBwaW5nCi0gICAgICAgICAgICAgIGlmICh3cmFwV0JSKSBodG1sLnB1c2goIjx3YnI+Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBodG1sLnB1c2gob3Blbik7Ci0gICAgICAgICAgICBzcGFuXyh0ZXh0LnNsaWNlKHdyYXBBdCAtIG91dFBvcyksIHN0eWxlKTsKLSAgICAgICAgICAgIGh0bWwucHVzaCgiPC9zcGFuPiIpOwotICAgICAgICAgICAgd3JhcEF0LS07Ci0gICAgICAgICAgICBvdXRQb3MgKz0gbDsKLSAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgb3V0UG9zICs9IGw7Ci0gICAgICAgICAgICBzcGFuXyh0ZXh0LCBzdHlsZSk7Ci0gICAgICAgICAgICAvLyBPdXRwdXQgZW1wdHkgd3JhcHBlciB3aGVuIGF0IGVuZCBvZiBsaW5lCi0gICAgICAgICAgICBpZiAob3V0UG9zID09IHdyYXBBdCAmJiBvdXRQb3MgPT0gbGVuKSBodG1sLnB1c2gob3BlbiArICI8L3NwYW4+Iik7Ci0gICAgICAgICAgICAvLyBTdG9wIG91dHB1dHRpbmcgSFRNTCB3aGVuIGdvbmUgc3VmZmljaWVudGx5IGZhciBiZXlvbmQgbWVhc3VyZQotICAgICAgICAgICAgZWxzZSBpZiAob3V0UG9zID4gd3JhcEF0ICsgMTAgJiYgL1xzLy50ZXN0KHRleHQpKSBzcGFuID0gZnVuY3Rpb24oKXt9OwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICB2YXIgc3QgPSB0aGlzLnN0eWxlcywgYWxsVGV4dCA9IHRoaXMudGV4dCwgbWFya2VkID0gdGhpcy5tYXJrZWQ7Ci0gICAgICB2YXIgbGVuID0gYWxsVGV4dC5sZW5ndGg7Ci0gICAgICBmdW5jdGlvbiBzdHlsZVRvQ2xhc3Moc3R5bGUpIHsKLSAgICAgICAgaWYgKCFzdHlsZSkgcmV0dXJuIG51bGw7Ci0gICAgICAgIHJldHVybiAiY20tIiArIHN0eWxlLnJlcGxhY2UoLyArL2csICIgY20tIik7Ci0gICAgICB9Ci0KLSAgICAgIGlmICghYWxsVGV4dCAmJiB3cmFwQXQgPT0gbnVsbCkgewotICAgICAgICBzcGFuKCIgIik7Ci0gICAgICB9IGVsc2UgaWYgKCFtYXJrZWQgfHwgIW1hcmtlZC5sZW5ndGgpIHsKLSAgICAgICAgZm9yICh2YXIgaSA9IDAsIGNoID0gMDsgY2ggPCBsZW47IGkrPTIpIHsKLSAgICAgICAgICB2YXIgc3RyID0gc3RbaV0sIHN0eWxlID0gc3RbaSsxXSwgbCA9IHN0ci5sZW5ndGg7Ci0gICAgICAgICAgaWYgKGNoICsgbCA+IGxlbikgc3RyID0gc3RyLnNsaWNlKDAsIGxlbiAtIGNoKTsKLSAgICAgICAgICBjaCArPSBsOwotICAgICAgICAgIHNwYW4oc3RyLCBzdHlsZVRvQ2xhc3Moc3R5bGUpKTsKLSAgICAgICAgfQotICAgICAgfSBlbHNlIHsKLSAgICAgICAgdmFyIHBvcyA9IDAsIGkgPSAwLCB0ZXh0ID0gIiIsIHN0eWxlLCBzZyA9IDA7Ci0gICAgICAgIHZhciBuZXh0Q2hhbmdlID0gbWFya2VkWzBdLmZyb20gfHwgMCwgbWFya3MgPSBbXSwgbWFya3BvcyA9IDA7Ci0gICAgICAgIGZ1bmN0aW9uIGFkdmFuY2VNYXJrcygpIHsKLSAgICAgICAgICB2YXIgbTsKLSAgICAgICAgICB3aGlsZSAobWFya3BvcyA8IG1hcmtlZC5sZW5ndGggJiYKLSAgICAgICAgICAgICAgICAgKChtID0gbWFya2VkW21hcmtwb3NdKS5mcm9tID09IHBvcyB8fCBtLmZyb20gPT0gbnVsbCkpIHsKLSAgICAgICAgICAgIGlmIChtLnN0eWxlICE9IG51bGwpIG1hcmtzLnB1c2gobSk7Ci0gICAgICAgICAgICArK21hcmtwb3M7Ci0gICAgICAgICAgfQotICAgICAgICAgIG5leHRDaGFuZ2UgPSBtYXJrcG9zIDwgbWFya2VkLmxlbmd0aCA/IG1hcmtlZFttYXJrcG9zXS5mcm9tIDogSW5maW5pdHk7Ci0gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXJrcy5sZW5ndGg7ICsraSkgewotICAgICAgICAgICAgdmFyIHRvID0gbWFya3NbaV0udG8gfHwgSW5maW5pdHk7Ci0gICAgICAgICAgICBpZiAodG8gPT0gcG9zKSBtYXJrcy5zcGxpY2UoaS0tLCAxKTsKLSAgICAgICAgICAgIGVsc2UgbmV4dENoYW5nZSA9IE1hdGgubWluKHRvLCBuZXh0Q2hhbmdlKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgdmFyIG0gPSAwOwotICAgICAgICB3aGlsZSAocG9zIDwgbGVuKSB7Ci0gICAgICAgICAgaWYgKG5leHRDaGFuZ2UgPT0gcG9zKSBhZHZhbmNlTWFya3MoKTsKLSAgICAgICAgICB2YXIgdXB0byA9IE1hdGgubWluKGxlbiwgbmV4dENoYW5nZSk7Ci0gICAgICAgICAgd2hpbGUgKHRydWUpIHsKLSAgICAgICAgICAgIGlmICh0ZXh0KSB7Ci0gICAgICAgICAgICAgIHZhciBlbmQgPSBwb3MgKyB0ZXh0Lmxlbmd0aDsKLSAgICAgICAgICAgICAgdmFyIGFwcGxpZWRTdHlsZSA9IHN0eWxlOwotICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1hcmtzLmxlbmd0aDsgKytqKQotICAgICAgICAgICAgICAgIGFwcGxpZWRTdHlsZSA9IChhcHBsaWVkU3R5bGUgPyBhcHBsaWVkU3R5bGUgKyAiICIgOiAiIikgKyBtYXJrc1tqXS5zdHlsZTsKLSAgICAgICAgICAgICAgc3BhbihlbmQgPiB1cHRvID8gdGV4dC5zbGljZSgwLCB1cHRvIC0gcG9zKSA6IHRleHQsIGFwcGxpZWRTdHlsZSk7Ci0gICAgICAgICAgICAgIGlmIChlbmQgPj0gdXB0bykge3RleHQgPSB0ZXh0LnNsaWNlKHVwdG8gLSBwb3MpOyBwb3MgPSB1cHRvOyBicmVhazt9Ci0gICAgICAgICAgICAgIHBvcyA9IGVuZDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRleHQgPSBzdFtpKytdOyBzdHlsZSA9IHN0eWxlVG9DbGFzcyhzdFtpKytdKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIHJldHVybiBodG1sLmpvaW4oIiIpOwotICAgIH0sCi0gICAgY2xlYW5VcDogZnVuY3Rpb24oKSB7Ci0gICAgICB0aGlzLnBhcmVudCA9IG51bGw7Ci0gICAgICBpZiAodGhpcy5tYXJrZWQpCi0gICAgICAgIGZvciAodmFyIGkgPSAwLCBlID0gdGhpcy5tYXJrZWQubGVuZ3RoOyBpIDwgZTsgKytpKSB0aGlzLm1hcmtlZFtpXS5kZXRhY2godGhpcyk7Ci0gICAgfQotICB9OwotICAvLyBVdGlsaXR5IHVzZWQgYnkgcmVwbGFjZSBhbmQgc3BsaXQgYWJvdmUKLSAgZnVuY3Rpb24gY29weVN0eWxlcyhmcm9tLCB0bywgc291cmNlLCBkZXN0KSB7Ci0gICAgZm9yICh2YXIgaSA9IDAsIHBvcyA9IDAsIHN0YXRlID0gMDsgcG9zIDwgdG87IGkrPTIpIHsKLSAgICAgIHZhciBwYXJ0ID0gc291cmNlW2ldLCBlbmQgPSBwb3MgKyBwYXJ0Lmxlbmd0aDsKLSAgICAgIGlmIChzdGF0ZSA9PSAwKSB7Ci0gICAgICAgIGlmIChlbmQgPiBmcm9tKSBkZXN0LnB1c2gocGFydC5zbGljZShmcm9tIC0gcG9zLCBNYXRoLm1pbihwYXJ0Lmxlbmd0aCwgdG8gLSBwb3MpKSwgc291cmNlW2krMV0pOwotICAgICAgICBpZiAoZW5kID49IGZyb20pIHN0YXRlID0gMTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKHN0YXRlID09IDEpIHsKLSAgICAgICAgaWYgKGVuZCA+IHRvKSBkZXN0LnB1c2gocGFydC5zbGljZSgwLCB0byAtIHBvcyksIHNvdXJjZVtpKzFdKTsKLSAgICAgICAgZWxzZSBkZXN0LnB1c2gocGFydCwgc291cmNlW2krMV0pOwotICAgICAgfQotICAgICAgcG9zID0gZW5kOwotICAgIH0KLSAgfQotCi0gIC8vIERhdGEgc3RydWN0dXJlIHRoYXQgaG9sZHMgdGhlIHNlcXVlbmNlIG9mIGxpbmVzLgotICBmdW5jdGlvbiBMZWFmQ2h1bmsobGluZXMpIHsKLSAgICB0aGlzLmxpbmVzID0gbGluZXM7Ci0gICAgdGhpcy5wYXJlbnQgPSBudWxsOwotICAgIGZvciAodmFyIGkgPSAwLCBlID0gbGluZXMubGVuZ3RoLCBoZWlnaHQgPSAwOyBpIDwgZTsgKytpKSB7Ci0gICAgICBsaW5lc1tpXS5wYXJlbnQgPSB0aGlzOwotICAgICAgaGVpZ2h0ICs9IGxpbmVzW2ldLmhlaWdodDsKLSAgICB9Ci0gICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7Ci0gIH0KLSAgTGVhZkNodW5rLnByb3RvdHlwZSA9IHsKLSAgICBjaHVua1NpemU6IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy5saW5lcy5sZW5ndGg7IH0sCi0gICAgcmVtb3ZlOiBmdW5jdGlvbihhdCwgbiwgY2FsbGJhY2tzKSB7Ci0gICAgICBmb3IgKHZhciBpID0gYXQsIGUgPSBhdCArIG47IGkgPCBlOyArK2kpIHsKLSAgICAgICAgdmFyIGxpbmUgPSB0aGlzLmxpbmVzW2ldOwotICAgICAgICB0aGlzLmhlaWdodCAtPSBsaW5lLmhlaWdodDsKLSAgICAgICAgbGluZS5jbGVhblVwKCk7Ci0gICAgICAgIGlmIChsaW5lLmhhbmRsZXJzKQotICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbGluZS5oYW5kbGVycy5sZW5ndGg7ICsraikgY2FsbGJhY2tzLnB1c2gobGluZS5oYW5kbGVyc1tqXSk7Ci0gICAgICB9Ci0gICAgICB0aGlzLmxpbmVzLnNwbGljZShhdCwgbik7Ci0gICAgfSwKLSAgICBjb2xsYXBzZTogZnVuY3Rpb24obGluZXMpIHsKLSAgICAgIGxpbmVzLnNwbGljZS5hcHBseShsaW5lcywgW2xpbmVzLmxlbmd0aCwgMF0uY29uY2F0KHRoaXMubGluZXMpKTsKLSAgICB9LAotICAgIGluc2VydEhlaWdodDogZnVuY3Rpb24oYXQsIGxpbmVzLCBoZWlnaHQpIHsKLSAgICAgIHRoaXMuaGVpZ2h0ICs9IGhlaWdodDsKLSAgICAgIC8vIFRoZSB0cmljayBiZWxvdyBpcyBhcHBhcmVudGx5IHRvbyBhZHZhbmNlZCBmb3IgSUUsIHdoaWNoCi0gICAgICAvLyBvY2Nhc2lvbmFsbHkgY29ycnVwdHMgdGhpcy5saW5lcyAoZHVwbGljYXRpbmcgZWxlbWVudHMpIHdoZW4KLSAgICAgIC8vIGl0IGlzIHVzZWQuCi0gICAgICBpZiAoaWUpIHRoaXMubGluZXMgPSB0aGlzLmxpbmVzLnNsaWNlKDAsIGF0KS5jb25jYXQobGluZXMpLmNvbmNhdCh0aGlzLmxpbmVzLnNsaWNlKGF0KSk7Ci0gICAgICBlbHNlIHRoaXMubGluZXMuc3BsaWNlLmFwcGx5KHRoaXMubGluZXMsIFthdCwgMF0uY29uY2F0KGxpbmVzKSk7Ci0gICAgICBmb3IgKHZhciBpID0gMCwgZSA9IGxpbmVzLmxlbmd0aDsgaSA8IGU7ICsraSkgbGluZXNbaV0ucGFyZW50ID0gdGhpczsKLSAgICB9LAotICAgIGl0ZXJOOiBmdW5jdGlvbihhdCwgbiwgb3ApIHsKLSAgICAgIGZvciAodmFyIGUgPSBhdCArIG47IGF0IDwgZTsgKythdCkKLSAgICAgICAgaWYgKG9wKHRoaXMubGluZXNbYXRdKSkgcmV0dXJuIHRydWU7Ci0gICAgfQotICB9OwotICBmdW5jdGlvbiBCcmFuY2hDaHVuayhjaGlsZHJlbikgewotICAgIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjsKLSAgICB2YXIgc2l6ZSA9IDAsIGhlaWdodCA9IDA7Ci0gICAgZm9yICh2YXIgaSA9IDAsIGUgPSBjaGlsZHJlbi5sZW5ndGg7IGkgPCBlOyArK2kpIHsKLSAgICAgIHZhciBjaCA9IGNoaWxkcmVuW2ldOwotICAgICAgc2l6ZSArPSBjaC5jaHVua1NpemUoKTsgaGVpZ2h0ICs9IGNoLmhlaWdodDsKLSAgICAgIGNoLnBhcmVudCA9IHRoaXM7Ci0gICAgfQotICAgIHRoaXMuc2l6ZSA9IHNpemU7Ci0gICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7Ci0gICAgdGhpcy5wYXJlbnQgPSBudWxsOwotICB9Ci0gIEJyYW5jaENodW5rLnByb3RvdHlwZSA9IHsKLSAgICBjaHVua1NpemU6IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy5zaXplOyB9LAotICAgIHJlbW92ZTogZnVuY3Rpb24oYXQsIG4sIGNhbGxiYWNrcykgewotICAgICAgdGhpcy5zaXplIC09IG47Ci0gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyArK2kpIHsKLSAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5jaGlsZHJlbltpXSwgc3ogPSBjaGlsZC5jaHVua1NpemUoKTsKLSAgICAgICAgaWYgKGF0IDwgc3opIHsKLSAgICAgICAgICB2YXIgcm0gPSBNYXRoLm1pbihuLCBzeiAtIGF0KSwgb2xkSGVpZ2h0ID0gY2hpbGQuaGVpZ2h0OwotICAgICAgICAgIGNoaWxkLnJlbW92ZShhdCwgcm0sIGNhbGxiYWNrcyk7Ci0gICAgICAgICAgdGhpcy5oZWlnaHQgLT0gb2xkSGVpZ2h0IC0gY2hpbGQuaGVpZ2h0OwotICAgICAgICAgIGlmIChzeiA9PSBybSkgeyB0aGlzLmNoaWxkcmVuLnNwbGljZShpLS0sIDEpOyBjaGlsZC5wYXJlbnQgPSBudWxsOyB9Ci0gICAgICAgICAgaWYgKChuIC09IHJtKSA9PSAwKSBicmVhazsKLSAgICAgICAgICBhdCA9IDA7Ci0gICAgICAgIH0gZWxzZSBhdCAtPSBzejsKLSAgICAgIH0KLSAgICAgIGlmICh0aGlzLnNpemUgLSBuIDwgMjUpIHsKLSAgICAgICAgdmFyIGxpbmVzID0gW107Ci0gICAgICAgIHRoaXMuY29sbGFwc2UobGluZXMpOwotICAgICAgICB0aGlzLmNoaWxkcmVuID0gW25ldyBMZWFmQ2h1bmsobGluZXMpXTsKLSAgICAgICAgdGhpcy5jaGlsZHJlblswXS5wYXJlbnQgPSB0aGlzOwotICAgICAgfQotICAgIH0sCi0gICAgY29sbGFwc2U6IGZ1bmN0aW9uKGxpbmVzKSB7Ci0gICAgICBmb3IgKHZhciBpID0gMCwgZSA9IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgZTsgKytpKSB0aGlzLmNoaWxkcmVuW2ldLmNvbGxhcHNlKGxpbmVzKTsKLSAgICB9LAotICAgIGluc2VydDogZnVuY3Rpb24oYXQsIGxpbmVzKSB7Ci0gICAgICB2YXIgaGVpZ2h0ID0gMDsKLSAgICAgIGZvciAodmFyIGkgPSAwLCBlID0gbGluZXMubGVuZ3RoOyBpIDwgZTsgKytpKSBoZWlnaHQgKz0gbGluZXNbaV0uaGVpZ2h0OwotICAgICAgdGhpcy5pbnNlcnRIZWlnaHQoYXQsIGxpbmVzLCBoZWlnaHQpOwotICAgIH0sCi0gICAgaW5zZXJ0SGVpZ2h0OiBmdW5jdGlvbihhdCwgbGluZXMsIGhlaWdodCkgewotICAgICAgdGhpcy5zaXplICs9IGxpbmVzLmxlbmd0aDsKLSAgICAgIHRoaXMuaGVpZ2h0ICs9IGhlaWdodDsKLSAgICAgIGZvciAodmFyIGkgPSAwLCBlID0gdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGkgPCBlOyArK2kpIHsKLSAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5jaGlsZHJlbltpXSwgc3ogPSBjaGlsZC5jaHVua1NpemUoKTsKLSAgICAgICAgaWYgKGF0IDw9IHN6KSB7Ci0gICAgICAgICAgY2hpbGQuaW5zZXJ0SGVpZ2h0KGF0LCBsaW5lcywgaGVpZ2h0KTsKLSAgICAgICAgICBpZiAoY2hpbGQubGluZXMgJiYgY2hpbGQubGluZXMubGVuZ3RoID4gNTApIHsKLSAgICAgICAgICAgIHdoaWxlIChjaGlsZC5saW5lcy5sZW5ndGggPiA1MCkgewotICAgICAgICAgICAgICB2YXIgc3BpbGxlZCA9IGNoaWxkLmxpbmVzLnNwbGljZShjaGlsZC5saW5lcy5sZW5ndGggLSAyNSwgMjUpOwotICAgICAgICAgICAgICB2YXIgbmV3bGVhZiA9IG5ldyBMZWFmQ2h1bmsoc3BpbGxlZCk7Ci0gICAgICAgICAgICAgIGNoaWxkLmhlaWdodCAtPSBuZXdsZWFmLmhlaWdodDsKLSAgICAgICAgICAgICAgdGhpcy5jaGlsZHJlbi5zcGxpY2UoaSArIDEsIDAsIG5ld2xlYWYpOwotICAgICAgICAgICAgICBuZXdsZWFmLnBhcmVudCA9IHRoaXM7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aGlzLm1heWJlU3BpbGwoKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgICAgYXQgLT0gc3o7Ci0gICAgICB9Ci0gICAgfSwKLSAgICBtYXliZVNwaWxsOiBmdW5jdGlvbigpIHsKLSAgICAgIGlmICh0aGlzLmNoaWxkcmVuLmxlbmd0aCA8PSAxMCkgcmV0dXJuOwotICAgICAgdmFyIG1lID0gdGhpczsKLSAgICAgIGRvIHsKLSAgICAgICAgdmFyIHNwaWxsZWQgPSBtZS5jaGlsZHJlbi5zcGxpY2UobWUuY2hpbGRyZW4ubGVuZ3RoIC0gNSwgNSk7Ci0gICAgICAgIHZhciBzaWJsaW5nID0gbmV3IEJyYW5jaENodW5rKHNwaWxsZWQpOwotICAgICAgICBpZiAoIW1lLnBhcmVudCkgeyAvLyBCZWNvbWUgdGhlIHBhcmVudCBub2RlCi0gICAgICAgICAgdmFyIGNvcHkgPSBuZXcgQnJhbmNoQ2h1bmsobWUuY2hpbGRyZW4pOwotICAgICAgICAgIGNvcHkucGFyZW50ID0gbWU7Ci0gICAgICAgICAgbWUuY2hpbGRyZW4gPSBbY29weSwgc2libGluZ107Ci0gICAgICAgICAgbWUgPSBjb3B5OwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgIG1lLnNpemUgLT0gc2libGluZy5zaXplOwotICAgICAgICAgIG1lLmhlaWdodCAtPSBzaWJsaW5nLmhlaWdodDsKLSAgICAgICAgICB2YXIgbXlJbmRleCA9IGluZGV4T2YobWUucGFyZW50LmNoaWxkcmVuLCBtZSk7Ci0gICAgICAgICAgbWUucGFyZW50LmNoaWxkcmVuLnNwbGljZShteUluZGV4ICsgMSwgMCwgc2libGluZyk7Ci0gICAgICAgIH0KLSAgICAgICAgc2libGluZy5wYXJlbnQgPSBtZS5wYXJlbnQ7Ci0gICAgICB9IHdoaWxlIChtZS5jaGlsZHJlbi5sZW5ndGggPiAxMCk7Ci0gICAgICBtZS5wYXJlbnQubWF5YmVTcGlsbCgpOwotICAgIH0sCi0gICAgaXRlcjogZnVuY3Rpb24oZnJvbSwgdG8sIG9wKSB7IHRoaXMuaXRlck4oZnJvbSwgdG8gLSBmcm9tLCBvcCk7IH0sCi0gICAgaXRlck46IGZ1bmN0aW9uKGF0LCBuLCBvcCkgewotICAgICAgZm9yICh2YXIgaSA9IDAsIGUgPSB0aGlzLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGU7ICsraSkgewotICAgICAgICB2YXIgY2hpbGQgPSB0aGlzLmNoaWxkcmVuW2ldLCBzeiA9IGNoaWxkLmNodW5rU2l6ZSgpOwotICAgICAgICBpZiAoYXQgPCBzeikgewotICAgICAgICAgIHZhciB1c2VkID0gTWF0aC5taW4obiwgc3ogLSBhdCk7Ci0gICAgICAgICAgaWYgKGNoaWxkLml0ZXJOKGF0LCB1c2VkLCBvcCkpIHJldHVybiB0cnVlOwotICAgICAgICAgIGlmICgobiAtPSB1c2VkKSA9PSAwKSBicmVhazsKLSAgICAgICAgICBhdCA9IDA7Ci0gICAgICAgIH0gZWxzZSBhdCAtPSBzejsKLSAgICAgIH0KLSAgICB9Ci0gIH07Ci0KLSAgZnVuY3Rpb24gZ2V0TGluZUF0KGNodW5rLCBuKSB7Ci0gICAgd2hpbGUgKCFjaHVuay5saW5lcykgewotICAgICAgZm9yICh2YXIgaSA9IDA7OyArK2kpIHsKLSAgICAgICAgdmFyIGNoaWxkID0gY2h1bmsuY2hpbGRyZW5baV0sIHN6ID0gY2hpbGQuY2h1bmtTaXplKCk7Ci0gICAgICAgIGlmIChuIDwgc3opIHsgY2h1bmsgPSBjaGlsZDsgYnJlYWs7IH0KLSAgICAgICAgbiAtPSBzejsKLSAgICAgIH0KLSAgICB9Ci0gICAgcmV0dXJuIGNodW5rLmxpbmVzW25dOwotICB9Ci0gIGZ1bmN0aW9uIGxpbmVObyhsaW5lKSB7Ci0gICAgaWYgKGxpbmUucGFyZW50ID09IG51bGwpIHJldHVybiBudWxsOwotICAgIHZhciBjdXIgPSBsaW5lLnBhcmVudCwgbm8gPSBpbmRleE9mKGN1ci5saW5lcywgbGluZSk7Ci0gICAgZm9yICh2YXIgY2h1bmsgPSBjdXIucGFyZW50OyBjaHVuazsgY3VyID0gY2h1bmssIGNodW5rID0gY2h1bmsucGFyZW50KSB7Ci0gICAgICBmb3IgKHZhciBpID0gMCwgZSA9IGNodW5rLmNoaWxkcmVuLmxlbmd0aDsgOyArK2kpIHsKLSAgICAgICAgaWYgKGNodW5rLmNoaWxkcmVuW2ldID09IGN1cikgYnJlYWs7Ci0gICAgICAgIG5vICs9IGNodW5rLmNoaWxkcmVuW2ldLmNodW5rU2l6ZSgpOwotICAgICAgfQotICAgIH0KLSAgICByZXR1cm4gbm87Ci0gIH0KLSAgZnVuY3Rpb24gbGluZUF0SGVpZ2h0KGNodW5rLCBoKSB7Ci0gICAgdmFyIG4gPSAwOwotICAgIG91dGVyOiBkbyB7Ci0gICAgICBmb3IgKHZhciBpID0gMCwgZSA9IGNodW5rLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGU7ICsraSkgewotICAgICAgICB2YXIgY2hpbGQgPSBjaHVuay5jaGlsZHJlbltpXSwgY2ggPSBjaGlsZC5oZWlnaHQ7Ci0gICAgICAgIGlmIChoIDwgY2gpIHsgY2h1bmsgPSBjaGlsZDsgY29udGludWUgb3V0ZXI7IH0KLSAgICAgICAgaCAtPSBjaDsKLSAgICAgICAgbiArPSBjaGlsZC5jaHVua1NpemUoKTsKLSAgICAgIH0KLSAgICAgIHJldHVybiBuOwotICAgIH0gd2hpbGUgKCFjaHVuay5saW5lcyk7Ci0gICAgZm9yICh2YXIgaSA9IDAsIGUgPSBjaHVuay5saW5lcy5sZW5ndGg7IGkgPCBlOyArK2kpIHsKLSAgICAgIHZhciBsaW5lID0gY2h1bmsubGluZXNbaV0sIGxoID0gbGluZS5oZWlnaHQ7Ci0gICAgICBpZiAoaCA8IGxoKSBicmVhazsKLSAgICAgIGggLT0gbGg7Ci0gICAgfQotICAgIHJldHVybiBuICsgaTsKLSAgfQotICBmdW5jdGlvbiBoZWlnaHRBdExpbmUoY2h1bmssIG4pIHsKLSAgICB2YXIgaCA9IDA7Ci0gICAgb3V0ZXI6IGRvIHsKLSAgICAgIGZvciAodmFyIGkgPSAwLCBlID0gY2h1bmsuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgZTsgKytpKSB7Ci0gICAgICAgIHZhciBjaGlsZCA9IGNodW5rLmNoaWxkcmVuW2ldLCBzeiA9IGNoaWxkLmNodW5rU2l6ZSgpOwotICAgICAgICBpZiAobiA8IHN6KSB7IGNodW5rID0gY2hpbGQ7IGNvbnRpbnVlIG91dGVyOyB9Ci0gICAgICAgIG4gLT0gc3o7Ci0gICAgICAgIGggKz0gY2hpbGQuaGVpZ2h0OwotICAgICAgfQotICAgICAgcmV0dXJuIGg7Ci0gICAgfSB3aGlsZSAoIWNodW5rLmxpbmVzKTsKLSAgICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSkgaCArPSBjaHVuay5saW5lc1tpXS5oZWlnaHQ7Ci0gICAgcmV0dXJuIGg7Ci0gIH0KLQotICAvLyBUaGUgaGlzdG9yeSBvYmplY3QgJ2NodW5rcycgY2hhbmdlcyB0aGF0IGFyZSBtYWRlIGNsb3NlIHRvZ2V0aGVyCi0gIC8vIGFuZCBhdCBhbG1vc3QgdGhlIHNhbWUgdGltZSBpbnRvIGJpZ2dlciB1bmRvYWJsZSB1bml0cy4KLSAgZnVuY3Rpb24gSGlzdG9yeSgpIHsKLSAgICB0aGlzLnRpbWUgPSAwOwotICAgIHRoaXMuZG9uZSA9IFtdOyB0aGlzLnVuZG9uZSA9IFtdOwotICAgIHRoaXMuY29tcG91bmQgPSAwOwotICAgIHRoaXMuY2xvc2VkID0gZmFsc2U7Ci0gIH0KLSAgSGlzdG9yeS5wcm90b3R5cGUgPSB7Ci0gICAgYWRkQ2hhbmdlOiBmdW5jdGlvbihzdGFydCwgYWRkZWQsIG9sZCkgewotICAgICAgdGhpcy51bmRvbmUubGVuZ3RoID0gMDsKLSAgICAgIHZhciB0aW1lID0gK25ldyBEYXRlLCBjdXIgPSB0aGlzLmRvbmVbdGhpcy5kb25lLmxlbmd0aCAtIDFdLCBsYXN0ID0gY3VyICYmIGN1cltjdXIubGVuZ3RoIC0gMV07Ci0gICAgICB2YXIgZHRpbWUgPSB0aW1lIC0gdGhpcy50aW1lOwotCi0gICAgICBpZiAodGhpcy5jb21wb3VuZCAmJiBjdXIgJiYgIXRoaXMuY2xvc2VkKSB7Ci0gICAgICAgIGN1ci5wdXNoKHtzdGFydDogc3RhcnQsIGFkZGVkOiBhZGRlZCwgb2xkOiBvbGR9KTsKLSAgICAgIH0gZWxzZSBpZiAoZHRpbWUgPiA0MDAgfHwgIWxhc3QgfHwgdGhpcy5jbG9zZWQgfHwKLSAgICAgICAgICAgICAgICAgbGFzdC5zdGFydCA+IHN0YXJ0ICsgb2xkLmxlbmd0aCB8fCBsYXN0LnN0YXJ0ICsgbGFzdC5hZGRlZCA8IHN0YXJ0KSB7Ci0gICAgICAgIHRoaXMuZG9uZS5wdXNoKFt7c3RhcnQ6IHN0YXJ0LCBhZGRlZDogYWRkZWQsIG9sZDogb2xkfV0pOwotICAgICAgICB0aGlzLmNsb3NlZCA9IGZhbHNlOwotICAgICAgfSBlbHNlIHsKLSAgICAgICAgdmFyIHN0YXJ0QmVmb3JlID0gTWF0aC5tYXgoMCwgbGFzdC5zdGFydCAtIHN0YXJ0KSwKLSAgICAgICAgICAgIGVuZEFmdGVyID0gTWF0aC5tYXgoMCwgKHN0YXJ0ICsgb2xkLmxlbmd0aCkgLSAobGFzdC5zdGFydCArIGxhc3QuYWRkZWQpKTsKLSAgICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0QmVmb3JlOyBpID4gMDsgLS1pKSBsYXN0Lm9sZC51bnNoaWZ0KG9sZFtpIC0gMV0pOwotICAgICAgICBmb3IgKHZhciBpID0gZW5kQWZ0ZXI7IGkgPiAwOyAtLWkpIGxhc3Qub2xkLnB1c2gob2xkW29sZC5sZW5ndGggLSBpXSk7Ci0gICAgICAgIGlmIChzdGFydEJlZm9yZSkgbGFzdC5zdGFydCA9IHN0YXJ0OwotICAgICAgICBsYXN0LmFkZGVkICs9IGFkZGVkIC0gKG9sZC5sZW5ndGggLSBzdGFydEJlZm9yZSAtIGVuZEFmdGVyKTsKLSAgICAgIH0KLSAgICAgIHRoaXMudGltZSA9IHRpbWU7Ci0gICAgfSwKLSAgICBzdGFydENvbXBvdW5kOiBmdW5jdGlvbigpIHsKLSAgICAgIGlmICghdGhpcy5jb21wb3VuZCsrKSB0aGlzLmNsb3NlZCA9IHRydWU7Ci0gICAgfSwKLSAgICBlbmRDb21wb3VuZDogZnVuY3Rpb24oKSB7Ci0gICAgICBpZiAoIS0tdGhpcy5jb21wb3VuZCkgdGhpcy5jbG9zZWQgPSB0cnVlOwotICAgIH0KLSAgfTsKLQotICBmdW5jdGlvbiBzdG9wTWV0aG9kKCkge2Vfc3RvcCh0aGlzKTt9Ci0gIC8vIEVuc3VyZSBhbiBldmVudCBoYXMgYSBzdG9wIG1ldGhvZC4KLSAgZnVuY3Rpb24gYWRkU3RvcChldmVudCkgewotICAgIGlmICghZXZlbnQuc3RvcCkgZXZlbnQuc3RvcCA9IHN0b3BNZXRob2Q7Ci0gICAgcmV0dXJuIGV2ZW50OwotICB9Ci0KLSAgZnVuY3Rpb24gZV9wcmV2ZW50RGVmYXVsdChlKSB7Ci0gICAgaWYgKGUucHJldmVudERlZmF1bHQpIGUucHJldmVudERlZmF1bHQoKTsKLSAgICBlbHNlIGUucmV0dXJuVmFsdWUgPSBmYWxzZTsKLSAgfQotICBmdW5jdGlvbiBlX3N0b3BQcm9wYWdhdGlvbihlKSB7Ci0gICAgaWYgKGUuc3RvcFByb3BhZ2F0aW9uKSBlLnN0b3BQcm9wYWdhdGlvbigpOwotICAgIGVsc2UgZS5jYW5jZWxCdWJibGUgPSB0cnVlOwotICB9Ci0gIGZ1bmN0aW9uIGVfc3RvcChlKSB7ZV9wcmV2ZW50RGVmYXVsdChlKTsgZV9zdG9wUHJvcGFnYXRpb24oZSk7fQotICBDb2RlTWlycm9yLmVfc3RvcCA9IGVfc3RvcDsKLSAgQ29kZU1pcnJvci5lX3ByZXZlbnREZWZhdWx0ID0gZV9wcmV2ZW50RGVmYXVsdDsKLSAgQ29kZU1pcnJvci5lX3N0b3BQcm9wYWdhdGlvbiA9IGVfc3RvcFByb3BhZ2F0aW9uOwotCi0gIGZ1bmN0aW9uIGVfdGFyZ2V0KGUpIHtyZXR1cm4gZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50O30KLSAgZnVuY3Rpb24gZV9idXR0b24oZSkgewotICAgIGlmIChlLndoaWNoKSByZXR1cm4gZS53aGljaDsKLSAgICBlbHNlIGlmIChlLmJ1dHRvbiAmIDEpIHJldHVybiAxOwotICAgIGVsc2UgaWYgKGUuYnV0dG9uICYgMikgcmV0dXJuIDM7Ci0gICAgZWxzZSBpZiAoZS5idXR0b24gJiA0KSByZXR1cm4gMjsKLSAgfQotCi0gIC8vIEFsbG93IDNyZC1wYXJ0eSBjb2RlIHRvIG92ZXJyaWRlIGV2ZW50IHByb3BlcnRpZXMgYnkgYWRkaW5nIGFuIG92ZXJyaWRlCi0gIC8vIG9iamVjdCB0byBhbiBldmVudCBvYmplY3QuCi0gIGZ1bmN0aW9uIGVfcHJvcChlLCBwcm9wKSB7Ci0gICAgdmFyIG92ZXJyaWRkZW4gPSBlLm92ZXJyaWRlICYmIGUub3ZlcnJpZGUuaGFzT3duUHJvcGVydHkocHJvcCk7Ci0gICAgcmV0dXJuIG92ZXJyaWRkZW4gPyBlLm92ZXJyaWRlW3Byb3BdIDogZVtwcm9wXTsKLSAgfQotCi0gIC8vIEV2ZW50IGhhbmRsZXIgcmVnaXN0cmF0aW9uLiBJZiBkaXNjb25uZWN0IGlzIHRydWUsIGl0J2xsIHJldHVybiBhCi0gIC8vIGZ1bmN0aW9uIHRoYXQgdW5yZWdpc3RlcnMgdGhlIGhhbmRsZXIuCi0gIGZ1bmN0aW9uIGNvbm5lY3Qobm9kZSwgdHlwZSwgaGFuZGxlciwgZGlzY29ubmVjdCkgewotICAgIGlmICh0eXBlb2Ygbm9kZS5hZGRFdmVudExpc3RlbmVyID09ICJmdW5jdGlvbiIpIHsKLSAgICAgIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBoYW5kbGVyLCBmYWxzZSk7Ci0gICAgICBpZiAoZGlzY29ubmVjdCkgcmV0dXJuIGZ1bmN0aW9uKCkge25vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBoYW5kbGVyLCBmYWxzZSk7fTsKLSAgICB9Ci0gICAgZWxzZSB7Ci0gICAgICB2YXIgd3JhcEhhbmRsZXIgPSBmdW5jdGlvbihldmVudCkge2hhbmRsZXIoZXZlbnQgfHwgd2luZG93LmV2ZW50KTt9OwotICAgICAgbm9kZS5hdHRhY2hFdmVudCgib24iICsgdHlwZSwgd3JhcEhhbmRsZXIpOwotICAgICAgaWYgKGRpc2Nvbm5lY3QpIHJldHVybiBmdW5jdGlvbigpIHtub2RlLmRldGFjaEV2ZW50KCJvbiIgKyB0eXBlLCB3cmFwSGFuZGxlcik7fTsKLSAgICB9Ci0gIH0KLSAgQ29kZU1pcnJvci5jb25uZWN0ID0gY29ubmVjdDsKLQotICBmdW5jdGlvbiBEZWxheWVkKCkge3RoaXMuaWQgPSBudWxsO30KLSAgRGVsYXllZC5wcm90b3R5cGUgPSB7c2V0OiBmdW5jdGlvbihtcywgZikge2NsZWFyVGltZW91dCh0aGlzLmlkKTsgdGhpcy5pZCA9IHNldFRpbWVvdXQoZiwgbXMpO319OwotCi0gIHZhciBQYXNzID0gQ29kZU1pcnJvci5QYXNzID0ge3RvU3RyaW5nOiBmdW5jdGlvbigpe3JldHVybiAiQ29kZU1pcnJvci5QYXNzIjt9fTsKLQotICB2YXIgZ2Vja28gPSAvZ2Vja29cL1xkezd9L2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTsKLSAgdmFyIGllID0gL01TSUUgXGQvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7Ci0gIHZhciBpZV9sdDkgPSAvTVNJRSBbMS04XVxiLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpOwotICB2YXIgcXVpcmtzTW9kZSA9IGllICYmIGRvY3VtZW50LmRvY3VtZW50TW9kZSA9PSA1OwotICB2YXIgd2Via2l0ID0gL1dlYktpdFwvLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpOwotICB2YXIgY2hyb21lID0gL0Nocm9tZVwvLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpOwotICB2YXIgc2FmYXJpID0gL0FwcGxlIENvbXB1dGVyLy50ZXN0KG5hdmlnYXRvci52ZW5kb3IpOwotICB2YXIga2h0bWwgPSAvS0hUTUxcLy8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTsKLQotICAvLyBEZXRlY3QgZHJhZy1hbmQtZHJvcAotICB2YXIgZHJhZ0FuZERyb3AgPSBmdW5jdGlvbigpIHsKLSAgICAvLyBUaGVyZSBpcyAqc29tZSoga2luZCBvZiBkcmFnLWFuZC1kcm9wIHN1cHBvcnQgaW4gSUU2LTgsIGJ1dCBJCi0gICAgLy8gY291bGRuJ3QgZ2V0IGl0IHRvIHdvcmsgeWV0LgotICAgIGlmIChpZV9sdDkpIHJldHVybiBmYWxzZTsKLSAgICB2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7Ci0gICAgcmV0dXJuICJkcmFnZ2FibGUiIGluIGRpdiB8fCAiZHJhZ0Ryb3AiIGluIGRpdjsKLSAgfSgpOwotCi0gIC8vIEZlYXR1cmUtZGV0ZWN0IHdoZXRoZXIgbmV3bGluZXMgaW4gdGV4dGFyZWFzIGFyZSBjb252ZXJ0ZWQgdG8gXHJcbgotICB2YXIgbGluZVNlcCA9IGZ1bmN0aW9uICgpIHsKLSAgICB2YXIgdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJ0ZXh0YXJlYSIpOwotICAgIHRlLnZhbHVlID0gImZvb1xuYmFyIjsKLSAgICBpZiAodGUudmFsdWUuaW5kZXhPZigiXHIiKSA+IC0xKSByZXR1cm4gIlxyXG4iOwotICAgIHJldHVybiAiXG4iOwotICB9KCk7Ci0KLSAgLy8gRm9yIGEgcmVhc29uIEkgaGF2ZSB5ZXQgdG8gZmlndXJlIG91dCwgc29tZSBicm93c2VycyBkaXNhbGxvdwotICAvLyB3b3JkIHdyYXBwaW5nIGJldHdlZW4gY2VydGFpbiBjaGFyYWN0ZXJzICpvbmx5KiBpZiBhIG5ldyBpbmxpbmUKLSAgLy8gZWxlbWVudCBpcyBzdGFydGVkIGJldHdlZW4gdGhlbS4gVGhpcyBtYWtlcyBpdCBoYXJkIHRvIHJlbGlhYmx5Ci0gIC8vIG1lYXN1cmUgdGhlIHBvc2l0aW9uIG9mIHRoaW5ncywgc2luY2UgdGhhdCByZXF1aXJlcyBpbnNlcnRpbmcgYW4KLSAgLy8gZXh0cmEgc3Bhbi4gVGhpcyB0ZXJyaWJseSBmcmFnaWxlIHNldCBvZiByZWdleHBzIG1hdGNoZXMgdGhlCi0gIC8vIGNoYXJhY3RlciBjb21iaW5hdGlvbnMgdGhhdCBzdWZmZXIgZnJvbSB0aGlzIHBoZW5vbWVub24gb24gdGhlCi0gIC8vIHZhcmlvdXMgYnJvd3NlcnMuCi0gIHZhciBzcGFuQWZmZWN0c1dyYXBwaW5nID0gL14kLzsgLy8gV29uJ3QgbWF0Y2ggYW55IHR3by1jaGFyYWN0ZXIgc3RyaW5nCi0gIGlmIChnZWNrbykgc3BhbkFmZmVjdHNXcmFwcGluZyA9IC8kJy87Ci0gIGVsc2UgaWYgKHNhZmFyaSkgc3BhbkFmZmVjdHNXcmFwcGluZyA9IC9cLVteIFwtP118XD9bXiAhJ1wiXCksLlwtXC86O1w/XF1cfV0vOwotICBlbHNlIGlmIChjaHJvbWUpIHNwYW5BZmZlY3RzV3JhcHBpbmcgPSAvXC1bXiBcLVwuP118XD9bXiBcLVwuP1xdXH06OyEnXCJcKSxcL118W1wuIVwiIyYlXCkqKyw6Oz0+XF18XH1+XVtcKFx7XFs8XXxcJCcvOwotCi0gIC8vIENvdW50cyB0aGUgY29sdW1uIG9mZnNldCBpbiBhIHN0cmluZywgdGFraW5nIHRhYnMgaW50byBhY2NvdW50LgotICAvLyBVc2VkIG1vc3RseSB0byBmaW5kIGluZGVudGF0aW9uLgotICBmdW5jdGlvbiBjb3VudENvbHVtbihzdHJpbmcsIGVuZCwgdGFiU2l6ZSkgewotICAgIGlmIChlbmQgPT0gbnVsbCkgewotICAgICAgZW5kID0gc3RyaW5nLnNlYXJjaCgvW15cc1x1MDBhMF0vKTsKLSAgICAgIGlmIChlbmQgPT0gLTEpIGVuZCA9IHN0cmluZy5sZW5ndGg7Ci0gICAgfQotICAgIGZvciAodmFyIGkgPSAwLCBuID0gMDsgaSA8IGVuZDsgKytpKSB7Ci0gICAgICBpZiAoc3RyaW5nLmNoYXJBdChpKSA9PSAiXHQiKSBuICs9IHRhYlNpemUgLSAobiAlIHRhYlNpemUpOwotICAgICAgZWxzZSArK247Ci0gICAgfQotICAgIHJldHVybiBuOwotICB9Ci0KLSAgZnVuY3Rpb24gY29tcHV0ZWRTdHlsZShlbHQpIHsKLSAgICBpZiAoZWx0LmN1cnJlbnRTdHlsZSkgcmV0dXJuIGVsdC5jdXJyZW50U3R5bGU7Ci0gICAgcmV0dXJuIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsdCwgbnVsbCk7Ci0gIH0KLQotICAvLyBGaW5kIHRoZSBwb3NpdGlvbiBvZiBhbiBlbGVtZW50IGJ5IGZvbGxvd2luZyB0aGUgb2Zmc2V0UGFyZW50IGNoYWluLgotICAvLyBJZiBzY3JlZW49PXRydWUsIGl0IHJldHVybnMgc2NyZWVuIChyYXRoZXIgdGhhbiBwYWdlKSBjb29yZGluYXRlcy4KLSAgZnVuY3Rpb24gZWx0T2Zmc2V0KG5vZGUsIHNjcmVlbikgewotICAgIHZhciBib2QgPSBub2RlLm93bmVyRG9jdW1lbnQuYm9keTsKLSAgICB2YXIgeCA9IDAsIHkgPSAwLCBza2lwQm9keSA9IGZhbHNlOwotICAgIGZvciAodmFyIG4gPSBub2RlOyBuOyBuID0gbi5vZmZzZXRQYXJlbnQpIHsKLSAgICAgIHZhciBvbCA9IG4ub2Zmc2V0TGVmdCwgb3QgPSBuLm9mZnNldFRvcDsKLSAgICAgIC8vIEZpcmVmb3ggcmVwb3J0cyB3ZWlyZCBpbnZlcnRlZCBvZmZzZXRzIHdoZW4gdGhlIGJvZHkgaGFzIGEgYm9yZGVyLgotICAgICAgaWYgKG4gPT0gYm9kKSB7IHggKz0gTWF0aC5hYnMob2wpOyB5ICs9IE1hdGguYWJzKG90KTsgfQotICAgICAgZWxzZSB7IHggKz0gb2wsIHkgKz0gb3Q7IH0KLSAgICAgIGlmIChzY3JlZW4gJiYgY29tcHV0ZWRTdHlsZShuKS5wb3NpdGlvbiA9PSAiZml4ZWQiKQotICAgICAgICBza2lwQm9keSA9IHRydWU7Ci0gICAgfQotICAgIHZhciBlID0gc2NyZWVuICYmICFza2lwQm9keSA/IG51bGwgOiBib2Q7Ci0gICAgZm9yICh2YXIgbiA9IG5vZGUucGFyZW50Tm9kZTsgbiAhPSBlOyBuID0gbi5wYXJlbnROb2RlKQotICAgICAgaWYgKG4uc2Nyb2xsTGVmdCAhPSBudWxsKSB7IHggLT0gbi5zY3JvbGxMZWZ0OyB5IC09IG4uc2Nyb2xsVG9wO30KLSAgICByZXR1cm4ge2xlZnQ6IHgsIHRvcDogeX07Ci0gIH0KLSAgLy8gVXNlIHRoZSBmYXN0ZXIgYW5kIHNhbmVyIGdldEJvdW5kaW5nQ2xpZW50UmVjdCBtZXRob2Qgd2hlbiBwb3NzaWJsZS4KLSAgaWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QgIT0gbnVsbCkgZWx0T2Zmc2V0ID0gZnVuY3Rpb24obm9kZSwgc2NyZWVuKSB7Ci0gICAgLy8gVGFrZSB0aGUgcGFydHMgb2YgYm91bmRpbmcgY2xpZW50IHJlY3QgdGhhdCB3ZSBhcmUgaW50ZXJlc3RlZCBpbiBzbyB3ZSBhcmUgYWJsZSB0byBlZGl0IGlmIG5lZWQgYmUsCi0gICAgLy8gc2luY2UgdGhlIHJldHVybmVkIHZhbHVlIGNhbm5vdCBiZSBjaGFuZ2VkIGV4dGVybmFsbHkgKHRoZXkgYXJlIGtlcHQgaW4gc3luYyBhcyB0aGUgZWxlbWVudCBtb3ZlcyB3aXRoaW4gdGhlIHBhZ2UpCi0gICAgdHJ5IHsgdmFyIGJveCA9IG5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7IGJveCA9IHsgdG9wOiBib3gudG9wLCBsZWZ0OiBib3gubGVmdCB9OyB9Ci0gICAgY2F0Y2goZSkgeyBib3ggPSB7dG9wOiAwLCBsZWZ0OiAwfTsgfQotICAgIGlmICghc2NyZWVuKSB7Ci0gICAgICAvLyBHZXQgdGhlIHRvcGxldmVsIHNjcm9sbCwgd29ya2luZyBhcm91bmQgYnJvd3NlciBkaWZmZXJlbmNlcy4KLSAgICAgIGlmICh3aW5kb3cucGFnZVlPZmZzZXQgPT0gbnVsbCkgewotICAgICAgICB2YXIgdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCB8fCBkb2N1bWVudC5ib2R5LnBhcmVudE5vZGU7Ci0gICAgICAgIGlmICh0LnNjcm9sbFRvcCA9PSBudWxsKSB0ID0gZG9jdW1lbnQuYm9keTsKLSAgICAgICAgYm94LnRvcCArPSB0LnNjcm9sbFRvcDsgYm94LmxlZnQgKz0gdC5zY3JvbGxMZWZ0OwotICAgICAgfSBlbHNlIHsKLSAgICAgICAgYm94LnRvcCArPSB3aW5kb3cucGFnZVlPZmZzZXQ7IGJveC5sZWZ0ICs9IHdpbmRvdy5wYWdlWE9mZnNldDsKLSAgICAgIH0KLSAgICB9Ci0gICAgcmV0dXJuIGJveDsKLSAgfTsKLQotICAvLyBHZXQgYSBub2RlJ3MgdGV4dCBjb250ZW50LgotICBmdW5jdGlvbiBlbHRUZXh0KG5vZGUpIHsKLSAgICByZXR1cm4gbm9kZS50ZXh0Q29udGVudCB8fCBub2RlLmlubmVyVGV4dCB8fCBub2RlLm5vZGVWYWx1ZSB8fCAiIjsKLSAgfQotICBmdW5jdGlvbiBzZWxlY3RJbnB1dChub2RlKSB7Ci0gICAgaWYgKGlvcykgeyAvLyBNb2JpbGUgU2FmYXJpIGFwcGFyZW50bHkgaGFzIGEgYnVnIHdoZXJlIHNlbGVjdCgpIGlzIGJyb2tlbi4KLSAgICAgIG5vZGUuc2VsZWN0aW9uU3RhcnQgPSAwOwotICAgICAgbm9kZS5zZWxlY3Rpb25FbmQgPSBub2RlLnZhbHVlLmxlbmd0aDsKLSAgICB9IGVsc2Ugbm9kZS5zZWxlY3QoKTsKLSAgfQotCi0gIC8vIE9wZXJhdGlvbnMgb24ge2xpbmUsIGNofSBvYmplY3RzLgotICBmdW5jdGlvbiBwb3NFcShhLCBiKSB7cmV0dXJuIGEubGluZSA9PSBiLmxpbmUgJiYgYS5jaCA9PSBiLmNoO30KLSAgZnVuY3Rpb24gcG9zTGVzcyhhLCBiKSB7cmV0dXJuIGEubGluZSA8IGIubGluZSB8fCAoYS5saW5lID09IGIubGluZSAmJiBhLmNoIDwgYi5jaCk7fQotICBmdW5jdGlvbiBjb3B5UG9zKHgpIHtyZXR1cm4ge2xpbmU6IHgubGluZSwgY2g6IHguY2h9O30KLQotICB2YXIgZXNjYXBlRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInByZSIpOwotICBmdW5jdGlvbiBodG1sRXNjYXBlKHN0cikgewotICAgIGVzY2FwZUVsZW1lbnQudGV4dENvbnRlbnQgPSBzdHI7Ci0gICAgcmV0dXJuIGVzY2FwZUVsZW1lbnQuaW5uZXJIVE1MOwotICB9Ci0gIC8vIFJlY2VudCAobGF0ZSAyMDExKSBPcGVyYSBiZXRhcyBpbnNlcnQgYm9ndXMgbmV3bGluZXMgYXQgdGhlIHN0YXJ0Ci0gIC8vIG9mIHRoZSB0ZXh0Q29udGVudCwgc28gd2Ugc3RyaXAgdGhvc2UuCi0gIGlmIChodG1sRXNjYXBlKCJhIikgPT0gIlxuYSIpCi0gICAgaHRtbEVzY2FwZSA9IGZ1bmN0aW9uKHN0cikgewotICAgICAgZXNjYXBlRWxlbWVudC50ZXh0Q29udGVudCA9IHN0cjsKLSAgICAgIHJldHVybiBlc2NhcGVFbGVtZW50LmlubmVySFRNTC5zbGljZSgxKTsKLSAgICB9OwotICAvLyBTb21lIElFcyBkb24ndCBwcmVzZXJ2ZSB0YWJzIHRocm91Z2ggaW5uZXJIVE1MCi0gIGVsc2UgaWYgKGh0bWxFc2NhcGUoIlx0IikgIT0gIlx0IikKLSAgICBodG1sRXNjYXBlID0gZnVuY3Rpb24oc3RyKSB7Ci0gICAgICBlc2NhcGVFbGVtZW50LmlubmVySFRNTCA9ICIiOwotICAgICAgZXNjYXBlRWxlbWVudC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzdHIpKTsKLSAgICAgIHJldHVybiBlc2NhcGVFbGVtZW50LmlubmVySFRNTDsKLSAgICB9OwotICBDb2RlTWlycm9yLmh0bWxFc2NhcGUgPSBodG1sRXNjYXBlOwotCi0gIC8vIFVzZWQgdG8gcG9zaXRpb24gdGhlIGN1cnNvciBhZnRlciBhbiB1bmRvL3JlZG8gYnkgZmluZGluZyB0aGUKLSAgLy8gbGFzdCBlZGl0ZWQgY2hhcmFjdGVyLgotICBmdW5jdGlvbiBlZGl0RW5kKGZyb20sIHRvKSB7Ci0gICAgaWYgKCF0bykgcmV0dXJuIDA7Ci0gICAgaWYgKCFmcm9tKSByZXR1cm4gdG8ubGVuZ3RoOwotICAgIGZvciAodmFyIGkgPSBmcm9tLmxlbmd0aCwgaiA9IHRvLmxlbmd0aDsgaSA+PSAwICYmIGogPj0gMDsgLS1pLCAtLWopCi0gICAgICBpZiAoZnJvbS5jaGFyQXQoaSkgIT0gdG8uY2hhckF0KGopKSBicmVhazsKLSAgICByZXR1cm4gaiArIDE7Ci0gIH0KLQotICBmdW5jdGlvbiBpbmRleE9mKGNvbGxlY3Rpb24sIGVsdCkgewotICAgIGlmIChjb2xsZWN0aW9uLmluZGV4T2YpIHJldHVybiBjb2xsZWN0aW9uLmluZGV4T2YoZWx0KTsKLSAgICBmb3IgKHZhciBpID0gMCwgZSA9IGNvbGxlY3Rpb24ubGVuZ3RoOyBpIDwgZTsgKytpKQotICAgICAgaWYgKGNvbGxlY3Rpb25baV0gPT0gZWx0KSByZXR1cm4gaTsKLSAgICByZXR1cm4gLTE7Ci0gIH0KLSAgZnVuY3Rpb24gaXNXb3JkQ2hhcihjaCkgewotICAgIHJldHVybiAvXHcvLnRlc3QoY2gpIHx8IGNoLnRvVXBwZXJDYXNlKCkgIT0gY2gudG9Mb3dlckNhc2UoKTsKLSAgfQotCi0gIC8vIFNlZSBpZiAiIi5zcGxpdCBpcyB0aGUgYnJva2VuIElFIHZlcnNpb24sIGlmIHNvLCBwcm92aWRlIGFuCi0gIC8vIGFsdGVybmF0aXZlIHdheSB0byBzcGxpdCBsaW5lcy4KLSAgdmFyIHNwbGl0TGluZXMgPSAiXG5cbmIiLnNwbGl0KC9cbi8pLmxlbmd0aCAhPSAzID8gZnVuY3Rpb24oc3RyaW5nKSB7Ci0gICAgdmFyIHBvcyA9IDAsIG5sLCByZXN1bHQgPSBbXTsKLSAgICB3aGlsZSAoKG5sID0gc3RyaW5nLmluZGV4T2YoIlxuIiwgcG9zKSkgPiAtMSkgewotICAgICAgcmVzdWx0LnB1c2goc3RyaW5nLnNsaWNlKHBvcywgc3RyaW5nLmNoYXJBdChubC0xKSA9PSAiXHIiID8gbmwgLSAxIDogbmwpKTsKLSAgICAgIHBvcyA9IG5sICsgMTsKLSAgICB9Ci0gICAgcmVzdWx0LnB1c2goc3RyaW5nLnNsaWNlKHBvcykpOwotICAgIHJldHVybiByZXN1bHQ7Ci0gIH0gOiBmdW5jdGlvbihzdHJpbmcpe3JldHVybiBzdHJpbmcuc3BsaXQoL1xyP1xuLyk7fTsKLSAgQ29kZU1pcnJvci5zcGxpdExpbmVzID0gc3BsaXRMaW5lczsKLQotICB2YXIgaGFzU2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbiA/IGZ1bmN0aW9uKHRlKSB7Ci0gICAgdHJ5IHsgcmV0dXJuIHRlLnNlbGVjdGlvblN0YXJ0ICE9IHRlLnNlbGVjdGlvbkVuZDsgfQotICAgIGNhdGNoKGUpIHsgcmV0dXJuIGZhbHNlOyB9Ci0gIH0gOiBmdW5jdGlvbih0ZSkgewotICAgIHRyeSB7dmFyIHJhbmdlID0gdGUub3duZXJEb2N1bWVudC5zZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTt9Ci0gICAgY2F0Y2goZSkge30KLSAgICBpZiAoIXJhbmdlIHx8IHJhbmdlLnBhcmVudEVsZW1lbnQoKSAhPSB0ZSkgcmV0dXJuIGZhbHNlOwotICAgIHJldHVybiByYW5nZS5jb21wYXJlRW5kUG9pbnRzKCJTdGFydFRvRW5kIiwgcmFuZ2UpICE9IDA7Ci0gIH07Ci0KLSAgQ29kZU1pcnJvci5kZWZpbmVNb2RlKCJudWxsIiwgZnVuY3Rpb24oKSB7Ci0gICAgcmV0dXJuIHt0b2tlbjogZnVuY3Rpb24oc3RyZWFtKSB7c3RyZWFtLnNraXBUb0VuZCgpO319OwotICB9KTsKLSAgQ29kZU1pcnJvci5kZWZpbmVNSU1FKCJ0ZXh0L3BsYWluIiwgIm51bGwiKTsKLQotICB2YXIga2V5TmFtZXMgPSB7MzogIkVudGVyIiwgODogIkJhY2tzcGFjZSIsIDk6ICJUYWIiLCAxMzogIkVudGVyIiwgMTY6ICJTaGlmdCIsIDE3OiAiQ3RybCIsIDE4OiAiQWx0IiwKLSAgICAgICAgICAgICAgICAgIDE5OiAiUGF1c2UiLCAyMDogIkNhcHNMb2NrIiwgMjc6ICJFc2MiLCAzMjogIlNwYWNlIiwgMzM6ICJQYWdlVXAiLCAzNDogIlBhZ2VEb3duIiwgMzU6ICJFbmQiLAotICAgICAgICAgICAgICAgICAgMzY6ICJIb21lIiwgMzc6ICJMZWZ0IiwgMzg6ICJVcCIsIDM5OiAiUmlnaHQiLCA0MDogIkRvd24iLCA0NDogIlByaW50U2NybiIsIDQ1OiAiSW5zZXJ0IiwKLSAgICAgICAgICAgICAgICAgIDQ2OiAiRGVsZXRlIiwgNTk6ICI7IiwgOTE6ICJNb2QiLCA5MjogIk1vZCIsIDkzOiAiTW9kIiwgMTI3OiAiRGVsZXRlIiwgMTg2OiAiOyIsIDE4NzogIj0iLCAxODg6ICIsIiwKLSAgICAgICAgICAgICAgICAgIDE4OTogIi0iLCAxOTA6ICIuIiwgMTkxOiAiLyIsIDE5MjogImAiLCAyMTk6ICJbIiwgMjIwOiAiXFwiLCAyMjE6ICJdIiwgMjIyOiAiJyIsIDYzMjc2OiAiUGFnZVVwIiwKLSAgICAgICAgICAgICAgICAgIDYzMjc3OiAiUGFnZURvd24iLCA2MzI3NTogIkVuZCIsIDYzMjczOiAiSG9tZSIsIDYzMjM0OiAiTGVmdCIsIDYzMjMyOiAiVXAiLCA2MzIzNTogIlJpZ2h0IiwKLSAgICAgICAgICAgICAgICAgIDYzMjMzOiAiRG93biIsIDYzMzAyOiAiSW5zZXJ0IiwgNjMyNzI6ICJEZWxldGUifTsKLSAgQ29kZU1pcnJvci5rZXlOYW1lcyA9IGtleU5hbWVzOwotICAoZnVuY3Rpb24oKSB7Ci0gICAgLy8gTnVtYmVyIGtleXMKLSAgICBmb3IgKHZhciBpID0gMDsgaSA8IDEwOyBpKyspIGtleU5hbWVzW2kgKyA0OF0gPSBTdHJpbmcoaSk7Ci0gICAgLy8gQWxwaGFiZXRpYyBrZXlzCi0gICAgZm9yICh2YXIgaSA9IDY1OyBpIDw9IDkwOyBpKyspIGtleU5hbWVzW2ldID0gU3RyaW5nLmZyb21DaGFyQ29kZShpKTsKLSAgICAvLyBGdW5jdGlvbiBrZXlzCi0gICAgZm9yICh2YXIgaSA9IDE7IGkgPD0gMTI7IGkrKykga2V5TmFtZXNbaSArIDExMV0gPSBrZXlOYW1lc1tpICsgNjMyMzVdID0gIkYiICsgaTsKLSAgfSkoKTsKLQotICByZXR1cm4gQ29kZU1pcnJvcjsKLX0pKCk7CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL2NvZGVtaXJyb3IvbGliL3V0aWwvbG9hZG1vZGUuanMgYi9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL2NvZGVtaXJyb3IvbGliL3V0aWwvbG9hZG1vZGUuanMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk1YzQwNjEuLjAwMDAwMDAKLS0tIGEvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9jb2RlbWlycm9yL2xpYi91dGlsL2xvYWRtb2RlLmpzCisrKyAvZGV2L251bGwKQEAgLTEsNTAgKzAsMCBAQAotKGZ1bmN0aW9uKCkgewotICBpZiAoIUNvZGVNaXJyb3IubW9kZVVSTCkgQ29kZU1pcnJvci5tb2RlVVJMID0gIi4uL21vZGUvJU4vJU4uanMiOwotCi0gIHZhciBsb2FkaW5nID0ge307Ci0gIGZ1bmN0aW9uIHNwbGl0Q2FsbGJhY2soY29udCwgbikgewotICAgIHZhciBjb3VudERvd24gPSBuOwotICAgIHJldHVybiBmdW5jdGlvbigpIHsgaWYgKC0tY291bnREb3duID09IDApIGNvbnQoKTsgfQotICB9Ci0gIGZ1bmN0aW9uIGVuc3VyZURlcHMobW9kZSwgY29udCkgewotICAgIHZhciBkZXBzID0gQ29kZU1pcnJvci5tb2Rlc1ttb2RlXS5kZXBlbmRlbmNpZXM7Ci0gICAgaWYgKCFkZXBzKSByZXR1cm4gY29udCgpOwotICAgIHZhciBtaXNzaW5nID0gW107Ci0gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkZXBzLmxlbmd0aDsgKytpKSB7Ci0gICAgICBpZiAoIUNvZGVNaXJyb3IubW9kZXMuaGFzT3duUHJvcGVydHkoZGVwc1tpXSkpCi0gICAgICAgIG1pc3NpbmcucHVzaChkZXBzW2ldKTsKLSAgICB9Ci0gICAgaWYgKCFtaXNzaW5nLmxlbmd0aCkgcmV0dXJuIGNvbnQoKTsKLSAgICB2YXIgc3BsaXQgPSBzcGxpdENhbGxiYWNrKGNvbnQsIG1pc3NpbmcubGVuZ3RoKTsKLSAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1pc3NpbmcubGVuZ3RoOyArK2kpCi0gICAgICBDb2RlTWlycm9yLnJlcXVpcmVNb2RlKG1pc3NpbmdbaV0sIHNwbGl0KTsKLSAgfQotCi0gIENvZGVNaXJyb3IucmVxdWlyZU1vZGUgPSBmdW5jdGlvbihtb2RlLCBjb250KSB7Ci0gICAgaWYgKENvZGVNaXJyb3IubW9kZXMuaGFzT3duUHJvcGVydHkobW9kZSkpIHJldHVybiBlbnN1cmVEZXBzKG1vZGUsIGNvbnQoKSk7Ci0gICAgaWYgKGxvYWRpbmcuaGFzT3duUHJvcGVydHkobW9kZSkpIHJldHVybiBsb2FkaW5nW21vZGVdLnB1c2goY29udCk7Ci0KLSAgICB2YXIgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7Ci0gICAgc2NyaXB0LnNyYyA9IENvZGVNaXJyb3IubW9kZVVSTC5yZXBsYWNlKC8lTi9nLCBtb2RlKTsKLSAgICB2YXIgb3RoZXJzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInNjcmlwdCIpWzBdOwotICAgIG90aGVycy5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzY3JpcHQsIG90aGVycyk7Ci0gICAgdmFyIGxpc3QgPSBsb2FkaW5nW21vZGVdID0gW2NvbnRdOwotICAgIHZhciBjb3VudCA9IDAsIHBvbGwgPSBzZXRJbnRlcnZhbChmdW5jdGlvbigpIHsKLSAgICAgIGlmICgrK2NvdW50ID4gMTAwKSByZXR1cm4gY2xlYXJJbnRlcnZhbChwb2xsKTsKLSAgICAgIGlmIChDb2RlTWlycm9yLm1vZGVzLmhhc093blByb3BlcnR5KG1vZGUpKSB7Ci0gICAgICAgIGNsZWFySW50ZXJ2YWwocG9sbCk7Ci0gICAgICAgIGxvYWRpbmdbbW9kZV0gPSBudWxsOwotICAgICAgICBlbnN1cmVEZXBzKG1vZGUsIGZ1bmN0aW9uKCkgewotICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkgbGlzdFtpXSgpOwotICAgICAgICB9KTsKLSAgICAgIH0KLSAgICB9LCAyMDApOwotICB9OwotCi0gIENvZGVNaXJyb3IuYXV0b0xvYWRNb2RlID0gZnVuY3Rpb24oaW5zdGFuY2UsIG1vZGUpIHsKLSAgICBpZiAoIUNvZGVNaXJyb3IubW9kZXMuaGFzT3duUHJvcGVydHkobW9kZSkpCi0gICAgICBDb2RlTWlycm9yLnJlcXVpcmVNb2RlKG1vZGUsIGZ1bmN0aW9uKCkgewotICAgICAgICBpbnN0YW5jZS5zZXRPcHRpb24oIm1vZGUiLCBpbnN0YW5jZS5nZXRPcHRpb24oIm1vZGUiKSk7Ci0gICAgICB9KTsKLSAgfTsKLX0oKSk7CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL2NvZGVtaXJyb3IvbGliL3V0aWwvcnVubW9kZS5qcyBiL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci9saWIvdXRpbC9ydW5tb2RlLmpzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYzU4ZDg1Li4wMDAwMDAwCi0tLSBhL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci9saWIvdXRpbC9ydW5tb2RlLmpzCisrKyAvZGV2L251bGwKQEAgLTEsNDkgKzAsMCBAQAotQ29kZU1pcnJvci5ydW5Nb2RlID0gZnVuY3Rpb24oc3RyaW5nLCBtb2Rlc3BlYywgY2FsbGJhY2ssIG9wdGlvbnMpIHsKLSAgdmFyIG1vZGUgPSBDb2RlTWlycm9yLmdldE1vZGUoQ29kZU1pcnJvci5kZWZhdWx0cywgbW9kZXNwZWMpOwotICB2YXIgaXNOb2RlID0gY2FsbGJhY2subm9kZVR5cGUgPT0gMTsKLSAgdmFyIHRhYlNpemUgPSAob3B0aW9ucyAmJiBvcHRpb25zLnRhYlNpemUpIHx8IENvZGVNaXJyb3IuZGVmYXVsdHMudGFiU2l6ZTsKLSAgaWYgKGlzTm9kZSkgewotICAgIHZhciBub2RlID0gY2FsbGJhY2ssIGFjY3VtID0gW10sIGNvbCA9IDA7Ci0gICAgY2FsbGJhY2sgPSBmdW5jdGlvbih0ZXh0LCBzdHlsZSkgewotICAgICAgaWYgKHRleHQgPT0gIlxuIikgewotICAgICAgICBhY2N1bS5wdXNoKCI8YnI+Iik7Ci0gICAgICAgIGNvbCA9IDA7Ci0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLSAgICAgIHZhciBlc2NhcGVkID0gIiI7Ci0gICAgICAvLyBIVE1MLWVzY2FwZSBhbmQgcmVwbGFjZSB0YWJzCi0gICAgICBmb3IgKHZhciBwb3MgPSAwOzspIHsKLSAgICAgICAgdmFyIGlkeCA9IHRleHQuaW5kZXhPZigiXHQiLCBwb3MpOwotICAgICAgICBpZiAoaWR4ID09IC0xKSB7Ci0gICAgICAgICAgZXNjYXBlZCArPSBDb2RlTWlycm9yLmh0bWxFc2NhcGUodGV4dC5zbGljZShwb3MpKTsKLSAgICAgICAgICBjb2wgKz0gdGV4dC5sZW5ndGggLSBwb3M7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgY29sICs9IGlkeCAtIHBvczsKLSAgICAgICAgICBlc2NhcGVkICs9IENvZGVNaXJyb3IuaHRtbEVzY2FwZSh0ZXh0LnNsaWNlKHBvcywgaWR4KSk7Ci0gICAgICAgICAgdmFyIHNpemUgPSB0YWJTaXplIC0gY29sICUgdGFiU2l6ZTsKLSAgICAgICAgICBjb2wgKz0gc2l6ZTsKLSAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7ICsraSkgZXNjYXBlZCArPSAiICI7Ci0gICAgICAgICAgcG9zID0gaWR4ICsgMTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAoc3R5bGUpIAotICAgICAgICBhY2N1bS5wdXNoKCI8c3BhbiBjbGFzcz1cImNtLSIgKyBDb2RlTWlycm9yLmh0bWxFc2NhcGUoc3R5bGUpICsgIlwiPiIgKyBlc2NhcGVkICsgIjwvc3Bhbj4iKTsKLSAgICAgIGVsc2UKLSAgICAgICAgYWNjdW0ucHVzaChlc2NhcGVkKTsKLSAgICB9Ci0gIH0KLSAgdmFyIGxpbmVzID0gQ29kZU1pcnJvci5zcGxpdExpbmVzKHN0cmluZyksIHN0YXRlID0gQ29kZU1pcnJvci5zdGFydFN0YXRlKG1vZGUpOwotICBmb3IgKHZhciBpID0gMCwgZSA9IGxpbmVzLmxlbmd0aDsgaSA8IGU7ICsraSkgewotICAgIGlmIChpKSBjYWxsYmFjaygiXG4iKTsKLSAgICB2YXIgc3RyZWFtID0gbmV3IENvZGVNaXJyb3IuU3RyaW5nU3RyZWFtKGxpbmVzW2ldKTsKLSAgICB3aGlsZSAoIXN0cmVhbS5lb2woKSkgewotICAgICAgdmFyIHN0eWxlID0gbW9kZS50b2tlbihzdHJlYW0sIHN0YXRlKTsKLSAgICAgIGNhbGxiYWNrKHN0cmVhbS5jdXJyZW50KCksIHN0eWxlLCBpLCBzdHJlYW0uc3RhcnQpOwotICAgICAgc3RyZWFtLnN0YXJ0ID0gc3RyZWFtLnBvczsKLSAgICB9Ci0gIH0KLSAgaWYgKGlzTm9kZSkKLSAgICBub2RlLmlubmVySFRNTCA9IGFjY3VtLmpvaW4oIiIpOwotfTsKZGlmZiAtLWdpdCBhL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci9tb2RlL2dyb292eS9ncm9vdnkuanMgYi9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL2NvZGVtaXJyb3IvbW9kZS9ncm9vdnkvZ3Jvb3Z5LmpzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMjllMGM5Li4wMDAwMDAwCi0tLSBhL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci9tb2RlL2dyb292eS9ncm9vdnkuanMKKysrIC9kZXYvbnVsbApAQCAtMSwyMTAgKzAsMCBAQAotQ29kZU1pcnJvci5kZWZpbmVNb2RlKCJncm9vdnkiLCBmdW5jdGlvbihjb25maWcsIHBhcnNlckNvbmZpZykgewotICBmdW5jdGlvbiB3b3JkcyhzdHIpIHsKLSAgICB2YXIgb2JqID0ge30sIHdvcmRzID0gc3RyLnNwbGl0KCIgIik7Ci0gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB3b3Jkcy5sZW5ndGg7ICsraSkgb2JqW3dvcmRzW2ldXSA9IHRydWU7Ci0gICAgcmV0dXJuIG9iajsKLSAgfQotICB2YXIga2V5d29yZHMgPSB3b3JkcygKLSAgICAiYWJzdHJhY3QgYXMgYXNzZXJ0IGJvb2xlYW4gYnJlYWsgYnl0ZSBjYXNlIGNhdGNoIGNoYXIgY2xhc3MgY29uc3QgY29udGludWUgZGVmIGRlZmF1bHQgIiArCi0gICAgImRvIGRvdWJsZSBlbHNlIGVudW0gZXh0ZW5kcyBmaW5hbCBmaW5hbGx5IGZsb2F0IGZvciBnb3RvIGlmIGltcGxlbWVudHMgaW1wb3J0IGluICIgKwotICAgICJpbnN0YW5jZW9mIGludCBpbnRlcmZhY2UgbG9uZyBuYXRpdmUgbmV3IHBhY2thZ2UgcHJpdmF0ZSBwcm90ZWN0ZWQgcHVibGljIHJldHVybiAiICsKLSAgICAic2hvcnQgc3RhdGljIHN0cmljdGZwIHN1cGVyIHN3aXRjaCBzeW5jaHJvbml6ZWQgdGhyZWFkc2FmZSB0aHJvdyB0aHJvd3MgdHJhbnNpZW50ICIgKwotICAgICJ0cnkgdm9pZCB2b2xhdGlsZSB3aGlsZSIpOwotICB2YXIgYmxvY2tLZXl3b3JkcyA9IHdvcmRzKCJjYXRjaCBjbGFzcyBkbyBlbHNlIGZpbmFsbHkgZm9yIGlmIHN3aXRjaCB0cnkgd2hpbGUgZW51bSBpbnRlcmZhY2UgZGVmIik7Ci0gIHZhciBhdG9tcyA9IHdvcmRzKCJudWxsIHRydWUgZmFsc2UgdGhpcyIpOwotCi0gIHZhciBjdXJQdW5jOwotICBmdW5jdGlvbiB0b2tlbkJhc2Uoc3RyZWFtLCBzdGF0ZSkgewotICAgIHZhciBjaCA9IHN0cmVhbS5uZXh0KCk7Ci0gICAgaWYgKGNoID09ICciJyB8fCBjaCA9PSAiJyIpIHsKLSAgICAgIHJldHVybiBzdGFydFN0cmluZyhjaCwgc3RyZWFtLCBzdGF0ZSk7Ci0gICAgfQotICAgIGlmICgvW1xbXF17fVwoXCksO1w6XC5dLy50ZXN0KGNoKSkgewotICAgICAgY3VyUHVuYyA9IGNoOwotICAgICAgcmV0dXJuIG51bGwKLSAgICB9Ci0gICAgaWYgKC9cZC8udGVzdChjaCkpIHsKLSAgICAgIHN0cmVhbS5lYXRXaGlsZSgvW1x3XC5dLyk7Ci0gICAgICBpZiAoc3RyZWFtLmVhdCgvZUUvKSkgeyBzdHJlYW0uZWF0KC9cK1wtLyk7IHN0cmVhbS5lYXRXaGlsZSgvXGQvKTsgfQotICAgICAgcmV0dXJuICJudW1iZXIiOwotICAgIH0KLSAgICBpZiAoY2ggPT0gIi8iKSB7Ci0gICAgICBpZiAoc3RyZWFtLmVhdCgiKiIpKSB7Ci0gICAgICAgIHN0YXRlLnRva2VuaXplLnB1c2godG9rZW5Db21tZW50KTsKLSAgICAgICAgcmV0dXJuIHRva2VuQ29tbWVudChzdHJlYW0sIHN0YXRlKTsKLSAgICAgIH0KLSAgICAgIGlmIChzdHJlYW0uZWF0KCIvIikpIHsKLSAgICAgICAgc3RyZWFtLnNraXBUb0VuZCgpOwotICAgICAgICByZXR1cm4gImNvbW1lbnQiOwotICAgICAgfQotICAgICAgaWYgKGV4cGVjdEV4cHJlc3Npb24oc3RhdGUubGFzdFRva2VuKSkgewotICAgICAgICByZXR1cm4gc3RhcnRTdHJpbmcoY2gsIHN0cmVhbSwgc3RhdGUpOwotICAgICAgfQotICAgIH0KLSAgICBpZiAoY2ggPT0gIi0iICYmIHN0cmVhbS5lYXQoIj4iKSkgewotICAgICAgY3VyUHVuYyA9ICItPiI7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgaWYgKC9bK1wtKiYlPTw+IT98XC9+XS8udGVzdChjaCkpIHsKLSAgICAgIHN0cmVhbS5lYXRXaGlsZSgvWytcLSomJT08Pnx+XS8pOwotICAgICAgcmV0dXJuICJvcGVyYXRvciI7Ci0gICAgfQotICAgIHN0cmVhbS5lYXRXaGlsZSgvW1x3XCRfXS8pOwotICAgIGlmIChjaCA9PSAiQCIpIHsgc3RyZWFtLmVhdFdoaWxlKC9bXHdcJF9cLl0vKTsgcmV0dXJuICJtZXRhIjsgfQotICAgIGlmIChzdGF0ZS5sYXN0VG9rZW4gPT0gIi4iKSByZXR1cm4gInByb3BlcnR5IjsKLSAgICBpZiAoc3RyZWFtLmVhdCgiOiIpKSB7IGN1clB1bmMgPSAicHJvcGxhYmVsIjsgcmV0dXJuICJwcm9wZXJ0eSI7IH0KLSAgICB2YXIgY3VyID0gc3RyZWFtLmN1cnJlbnQoKTsKLSAgICBpZiAoYXRvbXMucHJvcGVydHlJc0VudW1lcmFibGUoY3VyKSkgeyByZXR1cm4gImF0b20iOyB9Ci0gICAgaWYgKGtleXdvcmRzLnByb3BlcnR5SXNFbnVtZXJhYmxlKGN1cikpIHsKLSAgICAgIGlmIChibG9ja0tleXdvcmRzLnByb3BlcnR5SXNFbnVtZXJhYmxlKGN1cikpIGN1clB1bmMgPSAibmV3c3RhdGVtZW50IjsKLSAgICAgIHJldHVybiAia2V5d29yZCI7Ci0gICAgfQotICAgIHJldHVybiAid29yZCI7Ci0gIH0KLSAgdG9rZW5CYXNlLmlzQmFzZSA9IHRydWU7Ci0KLSAgZnVuY3Rpb24gc3RhcnRTdHJpbmcocXVvdGUsIHN0cmVhbSwgc3RhdGUpIHsKLSAgICB2YXIgdHJpcGxlUXVvdGVkID0gZmFsc2U7Ci0gICAgaWYgKHF1b3RlICE9ICIvIiAmJiBzdHJlYW0uZWF0KHF1b3RlKSkgewotICAgICAgaWYgKHN0cmVhbS5lYXQocXVvdGUpKSB0cmlwbGVRdW90ZWQgPSB0cnVlOwotICAgICAgZWxzZSByZXR1cm4gInN0cmluZyI7Ci0gICAgfQotICAgIGZ1bmN0aW9uIHQoc3RyZWFtLCBzdGF0ZSkgewotICAgICAgdmFyIGVzY2FwZWQgPSBmYWxzZSwgbmV4dCwgZW5kID0gIXRyaXBsZVF1b3RlZDsKLSAgICAgIHdoaWxlICgobmV4dCA9IHN0cmVhbS5uZXh0KCkpICE9IG51bGwpIHsKLSAgICAgICAgaWYgKG5leHQgPT0gcXVvdGUgJiYgIWVzY2FwZWQpIHsKLSAgICAgICAgICBpZiAoIXRyaXBsZVF1b3RlZCkgeyBicmVhazsgfQotICAgICAgICAgIGlmIChzdHJlYW0ubWF0Y2gocXVvdGUgKyBxdW90ZSkpIHsgZW5kID0gdHJ1ZTsgYnJlYWs7IH0KLSAgICAgICAgfQotICAgICAgICBpZiAocXVvdGUgPT0gJyInICYmIG5leHQgPT0gIiQiICYmICFlc2NhcGVkICYmIHN0cmVhbS5lYXQoInsiKSkgewotICAgICAgICAgIHN0YXRlLnRva2VuaXplLnB1c2godG9rZW5CYXNlVW50aWxCcmFjZSgpKTsKLSAgICAgICAgICByZXR1cm4gInN0cmluZyI7Ci0gICAgICAgIH0KLSAgICAgICAgZXNjYXBlZCA9ICFlc2NhcGVkICYmIG5leHQgPT0gIlxcIjsKLSAgICAgIH0KLSAgICAgIGlmIChlbmQpIHN0YXRlLnRva2VuaXplLnBvcCgpOwotICAgICAgcmV0dXJuICJzdHJpbmciOwotICAgIH0KLSAgICBzdGF0ZS50b2tlbml6ZS5wdXNoKHQpOwotICAgIHJldHVybiB0KHN0cmVhbSwgc3RhdGUpOwotICB9Ci0KLSAgZnVuY3Rpb24gdG9rZW5CYXNlVW50aWxCcmFjZSgpIHsKLSAgICB2YXIgZGVwdGggPSAxOwotICAgIGZ1bmN0aW9uIHQoc3RyZWFtLCBzdGF0ZSkgewotICAgICAgaWYgKHN0cmVhbS5wZWVrKCkgPT0gIn0iKSB7Ci0gICAgICAgIGRlcHRoLS07Ci0gICAgICAgIGlmIChkZXB0aCA9PSAwKSB7Ci0gICAgICAgICAgc3RhdGUudG9rZW5pemUucG9wKCk7Ci0gICAgICAgICAgcmV0dXJuIHN0YXRlLnRva2VuaXplW3N0YXRlLnRva2VuaXplLmxlbmd0aC0xXShzdHJlYW0sIHN0YXRlKTsKLSAgICAgICAgfQotICAgICAgfSBlbHNlIGlmIChzdHJlYW0ucGVlaygpID09ICJ7IikgewotICAgICAgICBkZXB0aCsrOwotICAgICAgfQotICAgICAgcmV0dXJuIHRva2VuQmFzZShzdHJlYW0sIHN0YXRlKTsKLSAgICB9Ci0gICAgdC5pc0Jhc2UgPSB0cnVlOwotICAgIHJldHVybiB0OwotICB9Ci0KLSAgZnVuY3Rpb24gdG9rZW5Db21tZW50KHN0cmVhbSwgc3RhdGUpIHsKLSAgICB2YXIgbWF5YmVFbmQgPSBmYWxzZSwgY2g7Ci0gICAgd2hpbGUgKGNoID0gc3RyZWFtLm5leHQoKSkgewotICAgICAgaWYgKGNoID09ICIvIiAmJiBtYXliZUVuZCkgewotICAgICAgICBzdGF0ZS50b2tlbml6ZS5wb3AoKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgICBtYXliZUVuZCA9IChjaCA9PSAiKiIpOwotICAgIH0KLSAgICByZXR1cm4gImNvbW1lbnQiOwotICB9Ci0KLSAgZnVuY3Rpb24gZXhwZWN0RXhwcmVzc2lvbihsYXN0KSB7Ci0gICAgcmV0dXJuICFsYXN0IHx8IGxhc3QgPT0gIm9wZXJhdG9yIiB8fCBsYXN0ID09ICItPiIgfHwgL1tcLlxbXHtcKCw7Ol0vLnRlc3QobGFzdCkgfHwKLSAgICAgIGxhc3QgPT0gIm5ld3N0YXRlbWVudCIgfHwgbGFzdCA9PSAia2V5d29yZCIgfHwgbGFzdCA9PSAicHJvcGxhYmVsIjsKLSAgfQotCi0gIGZ1bmN0aW9uIENvbnRleHQoaW5kZW50ZWQsIGNvbHVtbiwgdHlwZSwgYWxpZ24sIHByZXYpIHsKLSAgICB0aGlzLmluZGVudGVkID0gaW5kZW50ZWQ7Ci0gICAgdGhpcy5jb2x1bW4gPSBjb2x1bW47Ci0gICAgdGhpcy50eXBlID0gdHlwZTsKLSAgICB0aGlzLmFsaWduID0gYWxpZ247Ci0gICAgdGhpcy5wcmV2ID0gcHJldjsKLSAgfQotICBmdW5jdGlvbiBwdXNoQ29udGV4dChzdGF0ZSwgY29sLCB0eXBlKSB7Ci0gICAgcmV0dXJuIHN0YXRlLmNvbnRleHQgPSBuZXcgQ29udGV4dChzdGF0ZS5pbmRlbnRlZCwgY29sLCB0eXBlLCBudWxsLCBzdGF0ZS5jb250ZXh0KTsKLSAgfQotICBmdW5jdGlvbiBwb3BDb250ZXh0KHN0YXRlKSB7Ci0gICAgdmFyIHQgPSBzdGF0ZS5jb250ZXh0LnR5cGU7Ci0gICAgaWYgKHQgPT0gIikiIHx8IHQgPT0gIl0iIHx8IHQgPT0gIn0iKQotICAgICAgc3RhdGUuaW5kZW50ZWQgPSBzdGF0ZS5jb250ZXh0LmluZGVudGVkOwotICAgIHJldHVybiBzdGF0ZS5jb250ZXh0ID0gc3RhdGUuY29udGV4dC5wcmV2OwotICB9Ci0KLSAgLy8gSW50ZXJmYWNlCi0KLSAgcmV0dXJuIHsKLSAgICBzdGFydFN0YXRlOiBmdW5jdGlvbihiYXNlY29sdW1uKSB7Ci0gICAgICByZXR1cm4gewotICAgICAgICB0b2tlbml6ZTogW3Rva2VuQmFzZV0sCi0gICAgICAgIGNvbnRleHQ6IG5ldyBDb250ZXh0KChiYXNlY29sdW1uIHx8IDApIC0gY29uZmlnLmluZGVudFVuaXQsIDAsICJ0b3AiLCBmYWxzZSksCi0gICAgICAgIGluZGVudGVkOiAwLAotICAgICAgICBzdGFydE9mTGluZTogdHJ1ZSwKLSAgICAgICAgbGFzdFRva2VuOiBudWxsCi0gICAgICB9OwotICAgIH0sCi0KLSAgICB0b2tlbjogZnVuY3Rpb24oc3RyZWFtLCBzdGF0ZSkgewotICAgICAgdmFyIGN0eCA9IHN0YXRlLmNvbnRleHQ7Ci0gICAgICBpZiAoc3RyZWFtLnNvbCgpKSB7Ci0gICAgICAgIGlmIChjdHguYWxpZ24gPT0gbnVsbCkgY3R4LmFsaWduID0gZmFsc2U7Ci0gICAgICAgIHN0YXRlLmluZGVudGVkID0gc3RyZWFtLmluZGVudGF0aW9uKCk7Ci0gICAgICAgIHN0YXRlLnN0YXJ0T2ZMaW5lID0gdHJ1ZTsKLSAgICAgICAgLy8gQXV0b21hdGljIHNlbWljb2xvbiBpbnNlcnRpb24KLSAgICAgICAgaWYgKGN0eC50eXBlID09ICJzdGF0ZW1lbnQiICYmICFleHBlY3RFeHByZXNzaW9uKHN0YXRlLmxhc3RUb2tlbikpIHsKLSAgICAgICAgICBwb3BDb250ZXh0KHN0YXRlKTsgY3R4ID0gc3RhdGUuY29udGV4dDsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgaWYgKHN0cmVhbS5lYXRTcGFjZSgpKSByZXR1cm4gbnVsbDsKLSAgICAgIGN1clB1bmMgPSBudWxsOwotICAgICAgdmFyIHN0eWxlID0gc3RhdGUudG9rZW5pemVbc3RhdGUudG9rZW5pemUubGVuZ3RoLTFdKHN0cmVhbSwgc3RhdGUpOwotICAgICAgaWYgKHN0eWxlID09ICJjb21tZW50IikgcmV0dXJuIHN0eWxlOwotICAgICAgaWYgKGN0eC5hbGlnbiA9PSBudWxsKSBjdHguYWxpZ24gPSB0cnVlOwotCi0gICAgICBpZiAoKGN1clB1bmMgPT0gIjsiIHx8IGN1clB1bmMgPT0gIjoiKSAmJiBjdHgudHlwZSA9PSAic3RhdGVtZW50IikgcG9wQ29udGV4dChzdGF0ZSk7Ci0gICAgICAvLyBIYW5kbGUgaW5kZW50YXRpb24gZm9yIHt4IC0+IFxuIC4uLiB9Ci0gICAgICBlbHNlIGlmIChjdXJQdW5jID09ICItPiIgJiYgY3R4LnR5cGUgPT0gInN0YXRlbWVudCIgJiYgY3R4LnByZXYudHlwZSA9PSAifSIpIHsKLSAgICAgICAgcG9wQ29udGV4dChzdGF0ZSk7Ci0gICAgICAgIHN0YXRlLmNvbnRleHQuYWxpZ24gPSBmYWxzZTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKGN1clB1bmMgPT0gInsiKSBwdXNoQ29udGV4dChzdGF0ZSwgc3RyZWFtLmNvbHVtbigpLCAifSIpOwotICAgICAgZWxzZSBpZiAoY3VyUHVuYyA9PSAiWyIpIHB1c2hDb250ZXh0KHN0YXRlLCBzdHJlYW0uY29sdW1uKCksICJdIik7Ci0gICAgICBlbHNlIGlmIChjdXJQdW5jID09ICIoIikgcHVzaENvbnRleHQoc3RhdGUsIHN0cmVhbS5jb2x1bW4oKSwgIikiKTsKLSAgICAgIGVsc2UgaWYgKGN1clB1bmMgPT0gIn0iKSB7Ci0gICAgICAgIHdoaWxlIChjdHgudHlwZSA9PSAic3RhdGVtZW50IikgY3R4ID0gcG9wQ29udGV4dChzdGF0ZSk7Ci0gICAgICAgIGlmIChjdHgudHlwZSA9PSAifSIpIGN0eCA9IHBvcENvbnRleHQoc3RhdGUpOwotICAgICAgICB3aGlsZSAoY3R4LnR5cGUgPT0gInN0YXRlbWVudCIpIGN0eCA9IHBvcENvbnRleHQoc3RhdGUpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoY3VyUHVuYyA9PSBjdHgudHlwZSkgcG9wQ29udGV4dChzdGF0ZSk7Ci0gICAgICBlbHNlIGlmIChjdHgudHlwZSA9PSAifSIgfHwgY3R4LnR5cGUgPT0gInRvcCIgfHwgKGN0eC50eXBlID09ICJzdGF0ZW1lbnQiICYmIGN1clB1bmMgPT0gIm5ld3N0YXRlbWVudCIpKQotICAgICAgICBwdXNoQ29udGV4dChzdGF0ZSwgc3RyZWFtLmNvbHVtbigpLCAic3RhdGVtZW50Iik7Ci0gICAgICBzdGF0ZS5zdGFydE9mTGluZSA9IGZhbHNlOwotICAgICAgc3RhdGUubGFzdFRva2VuID0gY3VyUHVuYyB8fCBzdHlsZTsKLSAgICAgIHJldHVybiBzdHlsZTsKLSAgICB9LAotCi0gICAgaW5kZW50OiBmdW5jdGlvbihzdGF0ZSwgdGV4dEFmdGVyKSB7Ci0gICAgICBpZiAoIXN0YXRlLnRva2VuaXplW3N0YXRlLnRva2VuaXplLmxlbmd0aC0xXS5pc0Jhc2UpIHJldHVybiAwOwotICAgICAgdmFyIGZpcnN0Q2hhciA9IHRleHRBZnRlciAmJiB0ZXh0QWZ0ZXIuY2hhckF0KDApLCBjdHggPSBzdGF0ZS5jb250ZXh0OwotICAgICAgaWYgKGN0eC50eXBlID09ICJzdGF0ZW1lbnQiICYmICFleHBlY3RFeHByZXNzaW9uKHN0YXRlLmxhc3RUb2tlbikpIGN0eCA9IGN0eC5wcmV2OwotICAgICAgdmFyIGNsb3NpbmcgPSBmaXJzdENoYXIgPT0gY3R4LnR5cGU7Ci0gICAgICBpZiAoY3R4LnR5cGUgPT0gInN0YXRlbWVudCIpIHJldHVybiBjdHguaW5kZW50ZWQgKyAoZmlyc3RDaGFyID09ICJ7IiA/IDAgOiBjb25maWcuaW5kZW50VW5pdCk7Ci0gICAgICBlbHNlIGlmIChjdHguYWxpZ24pIHJldHVybiBjdHguY29sdW1uICsgKGNsb3NpbmcgPyAwIDogMSk7Ci0gICAgICBlbHNlIHJldHVybiBjdHguaW5kZW50ZWQgKyAoY2xvc2luZyA/IDAgOiBjb25maWcuaW5kZW50VW5pdCk7Ci0gICAgfSwKLQotICAgIGVsZWN0cmljQ2hhcnM6ICJ7fSIKLSAgfTsKLX0pOwotCi1Db2RlTWlycm9yLmRlZmluZU1JTUUoInRleHQveC1ncm9vdnkiLCAiZ3Jvb3Z5Iik7CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL2NvZGVtaXJyb3IvbW9kZS9qYXZhc2NyaXB0L2phdmFzY3JpcHQuanMgYi9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL2NvZGVtaXJyb3IvbW9kZS9qYXZhc2NyaXB0L2phdmFzY3JpcHQuanMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYxZjk2MDguLjAwMDAwMDAKLS0tIGEvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9jb2RlbWlycm9yL21vZGUvamF2YXNjcmlwdC9qYXZhc2NyaXB0LmpzCisrKyAvZGV2L251bGwKQEAgLTEsMzYxICswLDAgQEAKLUNvZGVNaXJyb3IuZGVmaW5lTW9kZSgiamF2YXNjcmlwdCIsIGZ1bmN0aW9uKGNvbmZpZywgcGFyc2VyQ29uZmlnKSB7Ci0gIHZhciBpbmRlbnRVbml0ID0gY29uZmlnLmluZGVudFVuaXQ7Ci0gIHZhciBqc29uTW9kZSA9IHBhcnNlckNvbmZpZy5qc29uOwotCi0gIC8vIFRva2VuaXplcgotCi0gIHZhciBrZXl3b3JkcyA9IGZ1bmN0aW9uKCl7Ci0gICAgZnVuY3Rpb24ga3codHlwZSkge3JldHVybiB7dHlwZTogdHlwZSwgc3R5bGU6ICJrZXl3b3JkIn07fQotICAgIHZhciBBID0ga3coImtleXdvcmQgYSIpLCBCID0ga3coImtleXdvcmQgYiIpLCBDID0ga3coImtleXdvcmQgYyIpOwotICAgIHZhciBvcGVyYXRvciA9IGt3KCJvcGVyYXRvciIpLCBhdG9tID0ge3R5cGU6ICJhdG9tIiwgc3R5bGU6ICJhdG9tIn07Ci0gICAgcmV0dXJuIHsKLSAgICAgICJpZiI6IEEsICJ3aGlsZSI6IEEsICJ3aXRoIjogQSwgImVsc2UiOiBCLCAiZG8iOiBCLCAidHJ5IjogQiwgImZpbmFsbHkiOiBCLAotICAgICAgInJldHVybiI6IEMsICJicmVhayI6IEMsICJjb250aW51ZSI6IEMsICJuZXciOiBDLCAiZGVsZXRlIjogQywgInRocm93IjogQywKLSAgICAgICJ2YXIiOiBrdygidmFyIiksICJjb25zdCI6IGt3KCJ2YXIiKSwgImxldCI6IGt3KCJ2YXIiKSwKLSAgICAgICJmdW5jdGlvbiI6IGt3KCJmdW5jdGlvbiIpLCAiY2F0Y2giOiBrdygiY2F0Y2giKSwKLSAgICAgICJmb3IiOiBrdygiZm9yIiksICJzd2l0Y2giOiBrdygic3dpdGNoIiksICJjYXNlIjoga3coImNhc2UiKSwgImRlZmF1bHQiOiBrdygiZGVmYXVsdCIpLAotICAgICAgImluIjogb3BlcmF0b3IsICJ0eXBlb2YiOiBvcGVyYXRvciwgImluc3RhbmNlb2YiOiBvcGVyYXRvciwKLSAgICAgICJ0cnVlIjogYXRvbSwgImZhbHNlIjogYXRvbSwgIm51bGwiOiBhdG9tLCAidW5kZWZpbmVkIjogYXRvbSwgIk5hTiI6IGF0b20sICJJbmZpbml0eSI6IGF0b20KLSAgICB9OwotICB9KCk7Ci0KLSAgdmFyIGlzT3BlcmF0b3JDaGFyID0gL1srXC0qJiU9PD4hP3xdLzsKLQotICBmdW5jdGlvbiBjaGFpbihzdHJlYW0sIHN0YXRlLCBmKSB7Ci0gICAgc3RhdGUudG9rZW5pemUgPSBmOwotICAgIHJldHVybiBmKHN0cmVhbSwgc3RhdGUpOwotICB9Ci0KLSAgZnVuY3Rpb24gbmV4dFVudGlsVW5lc2NhcGVkKHN0cmVhbSwgZW5kKSB7Ci0gICAgdmFyIGVzY2FwZWQgPSBmYWxzZSwgbmV4dDsKLSAgICB3aGlsZSAoKG5leHQgPSBzdHJlYW0ubmV4dCgpKSAhPSBudWxsKSB7Ci0gICAgICBpZiAobmV4dCA9PSBlbmQgJiYgIWVzY2FwZWQpCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIGVzY2FwZWQgPSAhZXNjYXBlZCAmJiBuZXh0ID09ICJcXCI7Ci0gICAgfQotICAgIHJldHVybiBlc2NhcGVkOwotICB9Ci0KLSAgLy8gVXNlZCBhcyBzY3JhdGNoIHZhcmlhYmxlcyB0byBjb21tdW5pY2F0ZSBtdWx0aXBsZSB2YWx1ZXMgd2l0aG91dAotICAvLyBjb25zaW5nIHVwIHRvbnMgb2Ygb2JqZWN0cy4KLSAgdmFyIHR5cGUsIGNvbnRlbnQ7Ci0gIGZ1bmN0aW9uIHJldCh0cCwgc3R5bGUsIGNvbnQpIHsKLSAgICB0eXBlID0gdHA7IGNvbnRlbnQgPSBjb250OwotICAgIHJldHVybiBzdHlsZTsKLSAgfQotCi0gIGZ1bmN0aW9uIGpzVG9rZW5CYXNlKHN0cmVhbSwgc3RhdGUpIHsKLSAgICB2YXIgY2ggPSBzdHJlYW0ubmV4dCgpOwotICAgIGlmIChjaCA9PSAnIicgfHwgY2ggPT0gIiciKQotICAgICAgcmV0dXJuIGNoYWluKHN0cmVhbSwgc3RhdGUsIGpzVG9rZW5TdHJpbmcoY2gpKTsKLSAgICBlbHNlIGlmICgvW1xbXF17fVwoXCksO1w6XC5dLy50ZXN0KGNoKSkKLSAgICAgIHJldHVybiByZXQoY2gpOwotICAgIGVsc2UgaWYgKGNoID09ICIwIiAmJiBzdHJlYW0uZWF0KC94L2kpKSB7Ci0gICAgICBzdHJlYW0uZWF0V2hpbGUoL1tcZGEtZl0vaSk7Ci0gICAgICByZXR1cm4gcmV0KCJudW1iZXIiLCAibnVtYmVyIik7Ci0gICAgfSAgICAgIAotICAgIGVsc2UgaWYgKC9cZC8udGVzdChjaCkpIHsKLSAgICAgIHN0cmVhbS5tYXRjaCgvXlxkKig/OlwuXGQqKT8oPzpbZUVdWytcLV0/XGQrKT8vKTsKLSAgICAgIHJldHVybiByZXQoIm51bWJlciIsICJudW1iZXIiKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoY2ggPT0gIi8iKSB7Ci0gICAgICBpZiAoc3RyZWFtLmVhdCgiKiIpKSB7Ci0gICAgICAgIHJldHVybiBjaGFpbihzdHJlYW0sIHN0YXRlLCBqc1Rva2VuQ29tbWVudCk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChzdHJlYW0uZWF0KCIvIikpIHsKLSAgICAgICAgc3RyZWFtLnNraXBUb0VuZCgpOwotICAgICAgICByZXR1cm4gcmV0KCJjb21tZW50IiwgImNvbW1lbnQiKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKHN0YXRlLnJlQWxsb3dlZCkgewotICAgICAgICBuZXh0VW50aWxVbmVzY2FwZWQoc3RyZWFtLCAiLyIpOwotICAgICAgICBzdHJlYW0uZWF0V2hpbGUoL1tnaW15XS8pOyAvLyAneScgaXMgInN0aWNreSIgb3B0aW9uIGluIE1vemlsbGEKLSAgICAgICAgcmV0dXJuIHJldCgicmVnZXhwIiwgInN0cmluZy0yIik7Ci0gICAgICB9Ci0gICAgICBlbHNlIHsKLSAgICAgICAgc3RyZWFtLmVhdFdoaWxlKGlzT3BlcmF0b3JDaGFyKTsKLSAgICAgICAgcmV0dXJuIHJldCgib3BlcmF0b3IiLCBudWxsLCBzdHJlYW0uY3VycmVudCgpKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSBpZiAoY2ggPT0gIiMiKSB7Ci0gICAgICAgIHN0cmVhbS5za2lwVG9FbmQoKTsKLSAgICAgICAgcmV0dXJuIHJldCgiZXJyb3IiLCAiZXJyb3IiKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoaXNPcGVyYXRvckNoYXIudGVzdChjaCkpIHsKLSAgICAgIHN0cmVhbS5lYXRXaGlsZShpc09wZXJhdG9yQ2hhcik7Ci0gICAgICByZXR1cm4gcmV0KCJvcGVyYXRvciIsIG51bGwsIHN0cmVhbS5jdXJyZW50KCkpOwotICAgIH0KLSAgICBlbHNlIHsKLSAgICAgIHN0cmVhbS5lYXRXaGlsZSgvW1x3XCRfXS8pOwotICAgICAgdmFyIHdvcmQgPSBzdHJlYW0uY3VycmVudCgpLCBrbm93biA9IGtleXdvcmRzLnByb3BlcnR5SXNFbnVtZXJhYmxlKHdvcmQpICYmIGtleXdvcmRzW3dvcmRdOwotICAgICAgcmV0dXJuIChrbm93biAmJiBzdGF0ZS5rd0FsbG93ZWQpID8gcmV0KGtub3duLnR5cGUsIGtub3duLnN0eWxlLCB3b3JkKSA6Ci0gICAgICAgICAgICAgICAgICAgICByZXQoInZhcmlhYmxlIiwgInZhcmlhYmxlIiwgd29yZCk7Ci0gICAgfQotICB9Ci0KLSAgZnVuY3Rpb24ganNUb2tlblN0cmluZyhxdW90ZSkgewotICAgIHJldHVybiBmdW5jdGlvbihzdHJlYW0sIHN0YXRlKSB7Ci0gICAgICBpZiAoIW5leHRVbnRpbFVuZXNjYXBlZChzdHJlYW0sIHF1b3RlKSkKLSAgICAgICAgc3RhdGUudG9rZW5pemUgPSBqc1Rva2VuQmFzZTsKLSAgICAgIHJldHVybiByZXQoInN0cmluZyIsICJzdHJpbmciKTsKLSAgICB9OwotICB9Ci0KLSAgZnVuY3Rpb24ganNUb2tlbkNvbW1lbnQoc3RyZWFtLCBzdGF0ZSkgewotICAgIHZhciBtYXliZUVuZCA9IGZhbHNlLCBjaDsKLSAgICB3aGlsZSAoY2ggPSBzdHJlYW0ubmV4dCgpKSB7Ci0gICAgICBpZiAoY2ggPT0gIi8iICYmIG1heWJlRW5kKSB7Ci0gICAgICAgIHN0YXRlLnRva2VuaXplID0ganNUb2tlbkJhc2U7Ci0gICAgICAgIGJyZWFrOwotICAgICAgfQotICAgICAgbWF5YmVFbmQgPSAoY2ggPT0gIioiKTsKLSAgICB9Ci0gICAgcmV0dXJuIHJldCgiY29tbWVudCIsICJjb21tZW50Iik7Ci0gIH0KLQotICAvLyBQYXJzZXIKLQotICB2YXIgYXRvbWljVHlwZXMgPSB7ImF0b20iOiB0cnVlLCAibnVtYmVyIjogdHJ1ZSwgInZhcmlhYmxlIjogdHJ1ZSwgInN0cmluZyI6IHRydWUsICJyZWdleHAiOiB0cnVlfTsKLQotICBmdW5jdGlvbiBKU0xleGljYWwoaW5kZW50ZWQsIGNvbHVtbiwgdHlwZSwgYWxpZ24sIHByZXYsIGluZm8pIHsKLSAgICB0aGlzLmluZGVudGVkID0gaW5kZW50ZWQ7Ci0gICAgdGhpcy5jb2x1bW4gPSBjb2x1bW47Ci0gICAgdGhpcy50eXBlID0gdHlwZTsKLSAgICB0aGlzLnByZXYgPSBwcmV2OwotICAgIHRoaXMuaW5mbyA9IGluZm87Ci0gICAgaWYgKGFsaWduICE9IG51bGwpIHRoaXMuYWxpZ24gPSBhbGlnbjsKLSAgfQotCi0gIGZ1bmN0aW9uIGluU2NvcGUoc3RhdGUsIHZhcm5hbWUpIHsKLSAgICBmb3IgKHZhciB2ID0gc3RhdGUubG9jYWxWYXJzOyB2OyB2ID0gdi5uZXh0KQotICAgICAgaWYgKHYubmFtZSA9PSB2YXJuYW1lKSByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIGZ1bmN0aW9uIHBhcnNlSlMoc3RhdGUsIHN0eWxlLCB0eXBlLCBjb250ZW50LCBzdHJlYW0pIHsKLSAgICB2YXIgY2MgPSBzdGF0ZS5jYzsKLSAgICAvLyBDb21tdW5pY2F0ZSBvdXIgY29udGV4dCB0byB0aGUgY29tYmluYXRvcnMuCi0gICAgLy8gKExlc3Mgd2FzdGVmdWwgdGhhbiBjb25zaW5nIHVwIGEgaHVuZHJlZCBjbG9zdXJlcyBvbiBldmVyeSBjYWxsLikKLSAgICBjeC5zdGF0ZSA9IHN0YXRlOyBjeC5zdHJlYW0gPSBzdHJlYW07IGN4Lm1hcmtlZCA9IG51bGwsIGN4LmNjID0gY2M7Ci0gIAotICAgIGlmICghc3RhdGUubGV4aWNhbC5oYXNPd25Qcm9wZXJ0eSgiYWxpZ24iKSkKLSAgICAgIHN0YXRlLmxleGljYWwuYWxpZ24gPSB0cnVlOwotCi0gICAgd2hpbGUodHJ1ZSkgewotICAgICAgdmFyIGNvbWJpbmF0b3IgPSBjYy5sZW5ndGggPyBjYy5wb3AoKSA6IGpzb25Nb2RlID8gZXhwcmVzc2lvbiA6IHN0YXRlbWVudDsKLSAgICAgIGlmIChjb21iaW5hdG9yKHR5cGUsIGNvbnRlbnQpKSB7Ci0gICAgICAgIHdoaWxlKGNjLmxlbmd0aCAmJiBjY1tjYy5sZW5ndGggLSAxXS5sZXgpCi0gICAgICAgICAgY2MucG9wKCkoKTsKLSAgICAgICAgaWYgKGN4Lm1hcmtlZCkgcmV0dXJuIGN4Lm1hcmtlZDsKLSAgICAgICAgaWYgKHR5cGUgPT0gInZhcmlhYmxlIiAmJiBpblNjb3BlKHN0YXRlLCBjb250ZW50KSkgcmV0dXJuICJ2YXJpYWJsZS0yIjsKLSAgICAgICAgcmV0dXJuIHN0eWxlOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8vIENvbWJpbmF0b3IgdXRpbHMKLQotICB2YXIgY3ggPSB7c3RhdGU6IG51bGwsIGNvbHVtbjogbnVsbCwgbWFya2VkOiBudWxsLCBjYzogbnVsbH07Ci0gIGZ1bmN0aW9uIHBhc3MoKSB7Ci0gICAgZm9yICh2YXIgaSA9IGFyZ3VtZW50cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgY3guY2MucHVzaChhcmd1bWVudHNbaV0pOwotICB9Ci0gIGZ1bmN0aW9uIGNvbnQoKSB7Ci0gICAgcGFzcy5hcHBseShudWxsLCBhcmd1bWVudHMpOwotICAgIHJldHVybiB0cnVlOwotICB9Ci0gIGZ1bmN0aW9uIHJlZ2lzdGVyKHZhcm5hbWUpIHsKLSAgICB2YXIgc3RhdGUgPSBjeC5zdGF0ZTsKLSAgICBpZiAoc3RhdGUuY29udGV4dCkgewotICAgICAgY3gubWFya2VkID0gImRlZiI7Ci0gICAgICBmb3IgKHZhciB2ID0gc3RhdGUubG9jYWxWYXJzOyB2OyB2ID0gdi5uZXh0KQotICAgICAgICBpZiAodi5uYW1lID09IHZhcm5hbWUpIHJldHVybjsKLSAgICAgIHN0YXRlLmxvY2FsVmFycyA9IHtuYW1lOiB2YXJuYW1lLCBuZXh0OiBzdGF0ZS5sb2NhbFZhcnN9OwotICAgIH0KLSAgfQotCi0gIC8vIENvbWJpbmF0b3JzCi0KLSAgdmFyIGRlZmF1bHRWYXJzID0ge25hbWU6ICJ0aGlzIiwgbmV4dDoge25hbWU6ICJhcmd1bWVudHMifX07Ci0gIGZ1bmN0aW9uIHB1c2hjb250ZXh0KCkgewotICAgIGlmICghY3guc3RhdGUuY29udGV4dCkgY3guc3RhdGUubG9jYWxWYXJzID0gZGVmYXVsdFZhcnM7Ci0gICAgY3guc3RhdGUuY29udGV4dCA9IHtwcmV2OiBjeC5zdGF0ZS5jb250ZXh0LCB2YXJzOiBjeC5zdGF0ZS5sb2NhbFZhcnN9OwotICB9Ci0gIGZ1bmN0aW9uIHBvcGNvbnRleHQoKSB7Ci0gICAgY3guc3RhdGUubG9jYWxWYXJzID0gY3guc3RhdGUuY29udGV4dC52YXJzOwotICAgIGN4LnN0YXRlLmNvbnRleHQgPSBjeC5zdGF0ZS5jb250ZXh0LnByZXY7Ci0gIH0KLSAgZnVuY3Rpb24gcHVzaGxleCh0eXBlLCBpbmZvKSB7Ci0gICAgdmFyIHJlc3VsdCA9IGZ1bmN0aW9uKCkgewotICAgICAgdmFyIHN0YXRlID0gY3guc3RhdGU7Ci0gICAgICBzdGF0ZS5sZXhpY2FsID0gbmV3IEpTTGV4aWNhbChzdGF0ZS5pbmRlbnRlZCwgY3guc3RyZWFtLmNvbHVtbigpLCB0eXBlLCBudWxsLCBzdGF0ZS5sZXhpY2FsLCBpbmZvKQotICAgIH07Ci0gICAgcmVzdWx0LmxleCA9IHRydWU7Ci0gICAgcmV0dXJuIHJlc3VsdDsKLSAgfQotICBmdW5jdGlvbiBwb3BsZXgoKSB7Ci0gICAgdmFyIHN0YXRlID0gY3guc3RhdGU7Ci0gICAgaWYgKHN0YXRlLmxleGljYWwucHJldikgewotICAgICAgaWYgKHN0YXRlLmxleGljYWwudHlwZSA9PSAiKSIpCi0gICAgICAgIHN0YXRlLmluZGVudGVkID0gc3RhdGUubGV4aWNhbC5pbmRlbnRlZDsKLSAgICAgIHN0YXRlLmxleGljYWwgPSBzdGF0ZS5sZXhpY2FsLnByZXY7Ci0gICAgfQotICB9Ci0gIHBvcGxleC5sZXggPSB0cnVlOwotCi0gIGZ1bmN0aW9uIGV4cGVjdCh3YW50ZWQpIHsKLSAgICByZXR1cm4gZnVuY3Rpb24gZXhwZWN0aW5nKHR5cGUpIHsKLSAgICAgIGlmICh0eXBlID09IHdhbnRlZCkgcmV0dXJuIGNvbnQoKTsKLSAgICAgIGVsc2UgaWYgKHdhbnRlZCA9PSAiOyIpIHJldHVybiBwYXNzKCk7Ci0gICAgICBlbHNlIHJldHVybiBjb250KGFyZ3VtZW50cy5jYWxsZWUpOwotICAgIH07Ci0gIH0KLQotICBmdW5jdGlvbiBzdGF0ZW1lbnQodHlwZSkgewotICAgIGlmICh0eXBlID09ICJ2YXIiKSByZXR1cm4gY29udChwdXNobGV4KCJ2YXJkZWYiKSwgdmFyZGVmMSwgZXhwZWN0KCI7IiksIHBvcGxleCk7Ci0gICAgaWYgKHR5cGUgPT0gImtleXdvcmQgYSIpIHJldHVybiBjb250KHB1c2hsZXgoImZvcm0iKSwgZXhwcmVzc2lvbiwgc3RhdGVtZW50LCBwb3BsZXgpOwotICAgIGlmICh0eXBlID09ICJrZXl3b3JkIGIiKSByZXR1cm4gY29udChwdXNobGV4KCJmb3JtIiksIHN0YXRlbWVudCwgcG9wbGV4KTsKLSAgICBpZiAodHlwZSA9PSAieyIpIHJldHVybiBjb250KHB1c2hsZXgoIn0iKSwgYmxvY2ssIHBvcGxleCk7Ci0gICAgaWYgKHR5cGUgPT0gIjsiKSByZXR1cm4gY29udCgpOwotICAgIGlmICh0eXBlID09ICJmdW5jdGlvbiIpIHJldHVybiBjb250KGZ1bmN0aW9uZGVmKTsKLSAgICBpZiAodHlwZSA9PSAiZm9yIikgcmV0dXJuIGNvbnQocHVzaGxleCgiZm9ybSIpLCBleHBlY3QoIigiKSwgcHVzaGxleCgiKSIpLCBmb3JzcGVjMSwgZXhwZWN0KCIpIiksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcGxleCwgc3RhdGVtZW50LCBwb3BsZXgpOwotICAgIGlmICh0eXBlID09ICJ2YXJpYWJsZSIpIHJldHVybiBjb250KHB1c2hsZXgoInN0YXQiKSwgbWF5YmVsYWJlbCk7Ci0gICAgaWYgKHR5cGUgPT0gInN3aXRjaCIpIHJldHVybiBjb250KHB1c2hsZXgoImZvcm0iKSwgZXhwcmVzc2lvbiwgcHVzaGxleCgifSIsICJzd2l0Y2giKSwgZXhwZWN0KCJ7IiksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrLCBwb3BsZXgsIHBvcGxleCk7Ci0gICAgaWYgKHR5cGUgPT0gImNhc2UiKSByZXR1cm4gY29udChleHByZXNzaW9uLCBleHBlY3QoIjoiKSk7Ci0gICAgaWYgKHR5cGUgPT0gImRlZmF1bHQiKSByZXR1cm4gY29udChleHBlY3QoIjoiKSk7Ci0gICAgaWYgKHR5cGUgPT0gImNhdGNoIikgcmV0dXJuIGNvbnQocHVzaGxleCgiZm9ybSIpLCBwdXNoY29udGV4dCwgZXhwZWN0KCIoIiksIGZ1bmFyZywgZXhwZWN0KCIpIiksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LCBwb3BsZXgsIHBvcGNvbnRleHQpOwotICAgIHJldHVybiBwYXNzKHB1c2hsZXgoInN0YXQiKSwgZXhwcmVzc2lvbiwgZXhwZWN0KCI7IiksIHBvcGxleCk7Ci0gIH0KLSAgZnVuY3Rpb24gZXhwcmVzc2lvbih0eXBlKSB7Ci0gICAgaWYgKGF0b21pY1R5cGVzLmhhc093blByb3BlcnR5KHR5cGUpKSByZXR1cm4gY29udChtYXliZW9wZXJhdG9yKTsKLSAgICBpZiAodHlwZSA9PSAiZnVuY3Rpb24iKSByZXR1cm4gY29udChmdW5jdGlvbmRlZik7Ci0gICAgaWYgKHR5cGUgPT0gImtleXdvcmQgYyIpIHJldHVybiBjb250KG1heWJlZXhwcmVzc2lvbik7Ci0gICAgaWYgKHR5cGUgPT0gIigiKSByZXR1cm4gY29udChwdXNobGV4KCIpIiksIG1heWJlZXhwcmVzc2lvbiwgZXhwZWN0KCIpIiksIHBvcGxleCwgbWF5YmVvcGVyYXRvcik7Ci0gICAgaWYgKHR5cGUgPT0gIm9wZXJhdG9yIikgcmV0dXJuIGNvbnQoZXhwcmVzc2lvbik7Ci0gICAgaWYgKHR5cGUgPT0gIlsiKSByZXR1cm4gY29udChwdXNobGV4KCJdIiksIGNvbW1hc2VwKGV4cHJlc3Npb24sICJdIiksIHBvcGxleCwgbWF5YmVvcGVyYXRvcik7Ci0gICAgaWYgKHR5cGUgPT0gInsiKSByZXR1cm4gY29udChwdXNobGV4KCJ9IiksIGNvbW1hc2VwKG9ianByb3AsICJ9IiksIHBvcGxleCwgbWF5YmVvcGVyYXRvcik7Ci0gICAgcmV0dXJuIGNvbnQoKTsKLSAgfQotICBmdW5jdGlvbiBtYXliZWV4cHJlc3Npb24odHlwZSkgewotICAgIGlmICh0eXBlLm1hdGNoKC9bO1x9XClcXSxdLykpIHJldHVybiBwYXNzKCk7Ci0gICAgcmV0dXJuIHBhc3MoZXhwcmVzc2lvbik7Ci0gIH0KLSAgICAKLSAgZnVuY3Rpb24gbWF5YmVvcGVyYXRvcih0eXBlLCB2YWx1ZSkgewotICAgIGlmICh0eXBlID09ICJvcGVyYXRvciIgJiYgL1wrXCt8LS0vLnRlc3QodmFsdWUpKSByZXR1cm4gY29udChtYXliZW9wZXJhdG9yKTsKLSAgICBpZiAodHlwZSA9PSAib3BlcmF0b3IiIHx8IHR5cGUgPT0gIjoiKSByZXR1cm4gY29udChleHByZXNzaW9uKTsKLSAgICBpZiAodHlwZSA9PSAiOyIpIHJldHVybjsKLSAgICBpZiAodHlwZSA9PSAiKCIpIHJldHVybiBjb250KHB1c2hsZXgoIikiKSwgY29tbWFzZXAoZXhwcmVzc2lvbiwgIikiKSwgcG9wbGV4LCBtYXliZW9wZXJhdG9yKTsKLSAgICBpZiAodHlwZSA9PSAiLiIpIHJldHVybiBjb250KHByb3BlcnR5LCBtYXliZW9wZXJhdG9yKTsKLSAgICBpZiAodHlwZSA9PSAiWyIpIHJldHVybiBjb250KHB1c2hsZXgoIl0iKSwgZXhwcmVzc2lvbiwgZXhwZWN0KCJdIiksIHBvcGxleCwgbWF5YmVvcGVyYXRvcik7Ci0gIH0KLSAgZnVuY3Rpb24gbWF5YmVsYWJlbCh0eXBlKSB7Ci0gICAgaWYgKHR5cGUgPT0gIjoiKSByZXR1cm4gY29udChwb3BsZXgsIHN0YXRlbWVudCk7Ci0gICAgcmV0dXJuIHBhc3MobWF5YmVvcGVyYXRvciwgZXhwZWN0KCI7IiksIHBvcGxleCk7Ci0gIH0KLSAgZnVuY3Rpb24gcHJvcGVydHkodHlwZSkgewotICAgIGlmICh0eXBlID09ICJ2YXJpYWJsZSIpIHtjeC5tYXJrZWQgPSAicHJvcGVydHkiOyByZXR1cm4gY29udCgpO30KLSAgfQotICBmdW5jdGlvbiBvYmpwcm9wKHR5cGUpIHsKLSAgICBpZiAodHlwZSA9PSAidmFyaWFibGUiKSBjeC5tYXJrZWQgPSAicHJvcGVydHkiOwotICAgIGlmIChhdG9taWNUeXBlcy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkgcmV0dXJuIGNvbnQoZXhwZWN0KCI6IiksIGV4cHJlc3Npb24pOwotICB9Ci0gIGZ1bmN0aW9uIGNvbW1hc2VwKHdoYXQsIGVuZCkgewotICAgIGZ1bmN0aW9uIHByb2NlZWQodHlwZSkgewotICAgICAgaWYgKHR5cGUgPT0gIiwiKSByZXR1cm4gY29udCh3aGF0LCBwcm9jZWVkKTsKLSAgICAgIGlmICh0eXBlID09IGVuZCkgcmV0dXJuIGNvbnQoKTsKLSAgICAgIHJldHVybiBjb250KGV4cGVjdChlbmQpKTsKLSAgICB9Ci0gICAgcmV0dXJuIGZ1bmN0aW9uIGNvbW1hU2VwYXJhdGVkKHR5cGUpIHsKLSAgICAgIGlmICh0eXBlID09IGVuZCkgcmV0dXJuIGNvbnQoKTsKLSAgICAgIGVsc2UgcmV0dXJuIHBhc3Mod2hhdCwgcHJvY2VlZCk7Ci0gICAgfTsKLSAgfQotICBmdW5jdGlvbiBibG9jayh0eXBlKSB7Ci0gICAgaWYgKHR5cGUgPT0gIn0iKSByZXR1cm4gY29udCgpOwotICAgIHJldHVybiBwYXNzKHN0YXRlbWVudCwgYmxvY2spOwotICB9Ci0gIGZ1bmN0aW9uIHZhcmRlZjEodHlwZSwgdmFsdWUpIHsKLSAgICBpZiAodHlwZSA9PSAidmFyaWFibGUiKXtyZWdpc3Rlcih2YWx1ZSk7IHJldHVybiBjb250KHZhcmRlZjIpO30KLSAgICByZXR1cm4gY29udCgpOwotICB9Ci0gIGZ1bmN0aW9uIHZhcmRlZjIodHlwZSwgdmFsdWUpIHsKLSAgICBpZiAodmFsdWUgPT0gIj0iKSByZXR1cm4gY29udChleHByZXNzaW9uLCB2YXJkZWYyKTsKLSAgICBpZiAodHlwZSA9PSAiLCIpIHJldHVybiBjb250KHZhcmRlZjEpOwotICB9Ci0gIGZ1bmN0aW9uIGZvcnNwZWMxKHR5cGUpIHsKLSAgICBpZiAodHlwZSA9PSAidmFyIikgcmV0dXJuIGNvbnQodmFyZGVmMSwgZm9yc3BlYzIpOwotICAgIGlmICh0eXBlID09ICI7IikgcmV0dXJuIHBhc3MoZm9yc3BlYzIpOwotICAgIGlmICh0eXBlID09ICJ2YXJpYWJsZSIpIHJldHVybiBjb250KGZvcm1heWJlaW4pOwotICAgIHJldHVybiBwYXNzKGZvcnNwZWMyKTsKLSAgfQotICBmdW5jdGlvbiBmb3JtYXliZWluKHR5cGUsIHZhbHVlKSB7Ci0gICAgaWYgKHZhbHVlID09ICJpbiIpIHJldHVybiBjb250KGV4cHJlc3Npb24pOwotICAgIHJldHVybiBjb250KG1heWJlb3BlcmF0b3IsIGZvcnNwZWMyKTsKLSAgfQotICBmdW5jdGlvbiBmb3JzcGVjMih0eXBlLCB2YWx1ZSkgewotICAgIGlmICh0eXBlID09ICI7IikgcmV0dXJuIGNvbnQoZm9yc3BlYzMpOwotICAgIGlmICh2YWx1ZSA9PSAiaW4iKSByZXR1cm4gY29udChleHByZXNzaW9uKTsKLSAgICByZXR1cm4gY29udChleHByZXNzaW9uLCBleHBlY3QoIjsiKSwgZm9yc3BlYzMpOwotICB9Ci0gIGZ1bmN0aW9uIGZvcnNwZWMzKHR5cGUpIHsKLSAgICBpZiAodHlwZSAhPSAiKSIpIGNvbnQoZXhwcmVzc2lvbik7Ci0gIH0KLSAgZnVuY3Rpb24gZnVuY3Rpb25kZWYodHlwZSwgdmFsdWUpIHsKLSAgICBpZiAodHlwZSA9PSAidmFyaWFibGUiKSB7cmVnaXN0ZXIodmFsdWUpOyByZXR1cm4gY29udChmdW5jdGlvbmRlZik7fQotICAgIGlmICh0eXBlID09ICIoIikgcmV0dXJuIGNvbnQocHVzaGxleCgiKSIpLCBwdXNoY29udGV4dCwgY29tbWFzZXAoZnVuYXJnLCAiKSIpLCBwb3BsZXgsIHN0YXRlbWVudCwgcG9wY29udGV4dCk7Ci0gIH0KLSAgZnVuY3Rpb24gZnVuYXJnKHR5cGUsIHZhbHVlKSB7Ci0gICAgaWYgKHR5cGUgPT0gInZhcmlhYmxlIikge3JlZ2lzdGVyKHZhbHVlKTsgcmV0dXJuIGNvbnQoKTt9Ci0gIH0KLQotICAvLyBJbnRlcmZhY2UKLQotICByZXR1cm4gewotICAgIHN0YXJ0U3RhdGU6IGZ1bmN0aW9uKGJhc2Vjb2x1bW4pIHsKLSAgICAgIHJldHVybiB7Ci0gICAgICAgIHRva2VuaXplOiBqc1Rva2VuQmFzZSwKLSAgICAgICAgcmVBbGxvd2VkOiB0cnVlLAotICAgICAgICBrd0FsbG93ZWQ6IHRydWUsCi0gICAgICAgIGNjOiBbXSwKLSAgICAgICAgbGV4aWNhbDogbmV3IEpTTGV4aWNhbCgoYmFzZWNvbHVtbiB8fCAwKSAtIGluZGVudFVuaXQsIDAsICJibG9jayIsIGZhbHNlKSwKLSAgICAgICAgbG9jYWxWYXJzOiBwYXJzZXJDb25maWcubG9jYWxWYXJzLAotICAgICAgICBjb250ZXh0OiBwYXJzZXJDb25maWcubG9jYWxWYXJzICYmIHt2YXJzOiBwYXJzZXJDb25maWcubG9jYWxWYXJzfSwKLSAgICAgICAgaW5kZW50ZWQ6IDAKLSAgICAgIH07Ci0gICAgfSwKLQotICAgIHRva2VuOiBmdW5jdGlvbihzdHJlYW0sIHN0YXRlKSB7Ci0gICAgICBpZiAoc3RyZWFtLnNvbCgpKSB7Ci0gICAgICAgIGlmICghc3RhdGUubGV4aWNhbC5oYXNPd25Qcm9wZXJ0eSgiYWxpZ24iKSkKLSAgICAgICAgICBzdGF0ZS5sZXhpY2FsLmFsaWduID0gZmFsc2U7Ci0gICAgICAgIHN0YXRlLmluZGVudGVkID0gc3RyZWFtLmluZGVudGF0aW9uKCk7Ci0gICAgICB9Ci0gICAgICBpZiAoc3RyZWFtLmVhdFNwYWNlKCkpIHJldHVybiBudWxsOwotICAgICAgdmFyIHN0eWxlID0gc3RhdGUudG9rZW5pemUoc3RyZWFtLCBzdGF0ZSk7Ci0gICAgICBpZiAodHlwZSA9PSAiY29tbWVudCIpIHJldHVybiBzdHlsZTsKLSAgICAgIHN0YXRlLnJlQWxsb3dlZCA9ICEhKHR5cGUgPT0gIm9wZXJhdG9yIiB8fCB0eXBlID09ICJrZXl3b3JkIGMiIHx8IHR5cGUubWF0Y2goL15bXFt7fVwoLDs6XSQvKSk7Ci0gICAgICBzdGF0ZS5rd0FsbG93ZWQgPSB0eXBlICE9ICcuJzsKLSAgICAgIHJldHVybiBwYXJzZUpTKHN0YXRlLCBzdHlsZSwgdHlwZSwgY29udGVudCwgc3RyZWFtKTsKLSAgICB9LAotCi0gICAgaW5kZW50OiBmdW5jdGlvbihzdGF0ZSwgdGV4dEFmdGVyKSB7Ci0gICAgICBpZiAoc3RhdGUudG9rZW5pemUgIT0ganNUb2tlbkJhc2UpIHJldHVybiAwOwotICAgICAgdmFyIGZpcnN0Q2hhciA9IHRleHRBZnRlciAmJiB0ZXh0QWZ0ZXIuY2hhckF0KDApLCBsZXhpY2FsID0gc3RhdGUubGV4aWNhbDsKLSAgICAgIGlmIChsZXhpY2FsLnR5cGUgPT0gInN0YXQiICYmIGZpcnN0Q2hhciA9PSAifSIpIGxleGljYWwgPSBsZXhpY2FsLnByZXY7Ci0gICAgICB2YXIgdHlwZSA9IGxleGljYWwudHlwZSwgY2xvc2luZyA9IGZpcnN0Q2hhciA9PSB0eXBlOwotICAgICAgaWYgKHR5cGUgPT0gInZhcmRlZiIpIHJldHVybiBsZXhpY2FsLmluZGVudGVkICsgNDsKLSAgICAgIGVsc2UgaWYgKHR5cGUgPT0gImZvcm0iICYmIGZpcnN0Q2hhciA9PSAieyIpIHJldHVybiBsZXhpY2FsLmluZGVudGVkOwotICAgICAgZWxzZSBpZiAodHlwZSA9PSAic3RhdCIgfHwgdHlwZSA9PSAiZm9ybSIpIHJldHVybiBsZXhpY2FsLmluZGVudGVkICsgaW5kZW50VW5pdDsKLSAgICAgIGVsc2UgaWYgKGxleGljYWwuaW5mbyA9PSAic3dpdGNoIiAmJiAhY2xvc2luZykKLSAgICAgICAgcmV0dXJuIGxleGljYWwuaW5kZW50ZWQgKyAoL14oPzpjYXNlfGRlZmF1bHQpXGIvLnRlc3QodGV4dEFmdGVyKSA/IGluZGVudFVuaXQgOiAyICogaW5kZW50VW5pdCk7Ci0gICAgICBlbHNlIGlmIChsZXhpY2FsLmFsaWduKSByZXR1cm4gbGV4aWNhbC5jb2x1bW4gKyAoY2xvc2luZyA/IDAgOiAxKTsKLSAgICAgIGVsc2UgcmV0dXJuIGxleGljYWwuaW5kZW50ZWQgKyAoY2xvc2luZyA/IDAgOiBpbmRlbnRVbml0KTsKLSAgICB9LAotCi0gICAgZWxlY3RyaWNDaGFyczogIjp7fSIKLSAgfTsKLX0pOwotCi1Db2RlTWlycm9yLmRlZmluZU1JTUUoInRleHQvamF2YXNjcmlwdCIsICJqYXZhc2NyaXB0Iik7Ci1Db2RlTWlycm9yLmRlZmluZU1JTUUoImFwcGxpY2F0aW9uL2pzb24iLCB7bmFtZTogImphdmFzY3JpcHQiLCBqc29uOiB0cnVlfSk7CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL3NjcmlwdC1jb25zb2xlLmNzcyBiL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvc2NyaXB0LWNvbnNvbGUuY3NzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzODA1YzE5Li4wMDAwMDAwCi0tLSBhL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvc2NyaXB0LWNvbnNvbGUuY3NzCisrKyAvZGV2L251bGwKQEAgLTEsMjAgKzAsMCBAQAotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLkNvZGVNaXJyb3IgewotICAgIC8qYm9yZGVyLXRvcDogMXB4IHNvbGlkIGJsYWNrOyovCi0gICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIGJsYWNrOwotfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvc2NyaXB0LWNvbnNvbGUuanMgYi9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL3NjcmlwdC1jb25zb2xlLmpzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzZTQwYTRhLi4wMDAwMDAwCi0tLSBhL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvc2NyaXB0LWNvbnNvbGUuanMKKysrIC9kZXYvbnVsbApAQCAtMSwxMjAgKzAsMCBAQAotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICoJICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLy9Db2RlbWlycm9yIGVkaXRvcgotdmFyIGlucHV0RWRpdG9yCi12YXIgb3V0cHV0RWRpdG9yCi12YXIgT1VUUFVUX1NFUCA9ICdcbi0tLS0tLS0tLS0tLS0tLS0tLVxuJwotCi1mdW5jdGlvbiBzZW5kRGF0YSh1cmwsIGRhdGEpIHsKLSAgICAkLmFqYXgoewotICAgICAgICB0eXBlOiJQT1NUIiwKLSAgICAgICAgdXJsOnVybCwKLSAgICAgICAgZGF0YTpkYXRhLAotLy8gICAgICAgIGRhdGFUeXBlOiJqc29uIiwKLSAgICAgICAgdGltZW91dDozMDAwMCwgLy9JbiBtaWxsaXMKLSAgICAgICAgYmVmb3JlU2VuZDpmdW5jdGlvbiAoKSB7Ci0gICAgICAgICAgICAkKCcjYWpheFNwaW5uZXInKS5zaG93KCk7Ci0gICAgICAgIH0sCi0gICAgICAgIC8qIGVycm9yOiBmdW5jdGlvbigpIHsKLSAgICAgICAgICQoJyNzdGF0dXMnKS50ZXh0KCdVcGRhdGUgZmFpbGVkl3RyeSBhZ2Fpbi4nKS5zbGlkZURvd24oJ3Nsb3cnKTsKLSAgICAgICAgIH0sKi8KLSAgICAgICAgY29tcGxldGU6ZnVuY3Rpb24gKCkgewotICAgICAgICAgICAgJCgnI2FqYXhTcGlubmVyJykuaGlkZSgpOwotICAgICAgICB9LAotICAgICAgICBzdWNjZXNzOmZ1bmN0aW9uIChkYXRhKSB7Ci0gICAgICAgICAgICByZW5kZXJEYXRhKGRhdGEpCi0gICAgICAgIH0KLSAgICB9KTsKLX0KLQotZnVuY3Rpb24gcmVuZGVyRGF0YShkYXRhKXsKLSAgICAkKCcjY29kZS1vdXRwdXQnKS5zaG93KCk7Ci0gICAgdmFyIGN1cnJlbnREYXRhID0gb3V0cHV0RWRpdG9yLmdldFZhbHVlKCkKLSAgICAvL0lmIHdlIG5lZWQgdG8gYXBwZW5kIHRoZSBkYXRhIHRoZW4gdXNlIGJlbG93Ci0gICAgLy9Gb3Igbm93IHdlIGp1c3QgcmVwbGFjZSB0aGUgZXhpc3Rpbmcgb3V0cHV0Ci0gICAgLy92YXIgb3V0RGF0YSA9IGRhdGEgKyBPVVRQVVRfU0VQKyBjdXJyZW50RGF0YQotCi0gICAgb3V0cHV0RWRpdG9yLnNldFZhbHVlKGRhdGEpCi19Ci0KLWZ1bmN0aW9uIHNldFVwQ29kZU1pcnJvcigpIHsKLSAgICBDb2RlTWlycm9yLm1vZGVVUkwgPSBwbHVnaW5Sb290ICsgIi9yZXMvdWkvY29kZW1pcnJvci9tb2RlLyVOLyVOLmpzIjsKLSAgICBpbnB1dEVkaXRvciA9IENvZGVNaXJyb3IuZnJvbVRleHRBcmVhKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjb2RlIiksIHsKLSAgICAgICAgbGluZU51bWJlcnM6dHJ1ZSwKLSAgICAgICAgZXh0cmFLZXlzOiB7Ci0gICAgICAgICAgICAnQ3RybC1RJzpjbGVhck91dHB1dCwKLSAgICAgICAgICAgICdDdHJsLVgnOmV4ZWN1dGVTY3JpcHQKLSAgICAgICAgfQotICAgIH0pOwotICAgIG91dHB1dEVkaXRvciA9IENvZGVNaXJyb3IuZnJvbVRleHRBcmVhKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJyZXN1bHQiKSwgewotICAgICAgICAgICAgbGluZU51bWJlcnM6dHJ1ZSwKLSAgICAgICAgICAgIHJlYWRPbmx5OiJub2N1cnNvciIKLSAgICAgICAgfSk7Ci19Ci0KLWZ1bmN0aW9uIHVwZGF0ZVdpdGhPcHRpb24ob3B0KXsKLSAgICBzZXRMYW5nTW9kZShpbnB1dEVkaXRvcixvcHQuYXR0cignbGFuZ01vZGUnKSkKLSAgICAkKCdbbmFtZT1sYW5nXScpLnZhbChvcHQudmFsKCkpCi19Ci0KLWZ1bmN0aW9uIHNldExhbmdNb2RlKGVkaXRvciwgbW9kZU5hbWUpIHsKLSAgICBpZighbW9kZU5hbWUpewotICAgICAgICBtb2RlTmFtZSA9ICJ0ZXh0L3BsYWluIgotICAgIH1lbHNlewotICAgICAgICBDb2RlTWlycm9yLmF1dG9Mb2FkTW9kZShpbnB1dEVkaXRvciwgbW9kZU5hbWUpOwotICAgIH0KLSAgICBlZGl0b3Iuc2V0T3B0aW9uKCJtb2RlIiwgbW9kZU5hbWUpOwotfQotCi1mdW5jdGlvbiBzZXRVcExhbmdPcHRpb25zKCkgewotICAgIHZhciBjb2RlTGFuZyA9ICQoJyNjb2RlTGFuZycpCi0gICAgdmFyIG9wdGlvbnMgPSBjb2RlTGFuZy5wcm9wID8gY29kZUxhbmcucHJvcCgnb3B0aW9ucycpIDogY29kZUxhbmcuYXR0cignb3B0aW9ucycpOwotICAgIGNvZGVMYW5nLmVtcHR5KCkKLQotICAgIGZvcih2YXIgaSBpbiBzY3JpcHRDb25maWcpewotICAgICAgICB2YXIgY29uZmlnID0gc2NyaXB0Q29uZmlnW2ldCi0gICAgICAgIHZhciBvcHQgPSBuZXcgT3B0aW9uKGNvbmZpZy5sYW5nTmFtZSxjb25maWcubGFuZ0NvZGUpOwotICAgICAgICBpZihjb25maWcubW9kZSl7Ci0gICAgICAgICAgICBvcHQubGFuZ01vZGUgPSBjb25maWcubW9kZTsKLSAgICAgICAgfQotICAgICAgICBvcHRpb25zW29wdGlvbnMubGVuZ3RoXSA9IG9wdAotICAgIH0KLSAgICAkKCcjY29kZUxhbmcnKS5jaGFuZ2UoZnVuY3Rpb24oKXsKLSAgICAgICAgdmFyIG9wdCA9ICQodGhpcykuZmluZCgiOnNlbGVjdGVkIik7Ci0gICAgICAgIHVwZGF0ZVdpdGhPcHRpb24ob3B0KQotICAgIH0pOwotCi0gICAgJCgnI2NvZGVMYW5nIG9wdGlvbjplcSgwKScpLmF0dHIoJ3NlbGVjdGVkJywnc2VsZWN0ZWQnKQotICAgIHVwZGF0ZVdpdGhPcHRpb24oJChvcHRpb25zWzBdKSkKLX0KLQotZnVuY3Rpb24gZXhlY3V0ZVNjcmlwdCgpewotICAgIGlucHV0RWRpdG9yLnNhdmUoKSAvL0NvcHkgdGhlIGNvbnRlbnRzIHRvIHRleHRhcmVhIGZvcm0gZmllbGQKLSAgICBzZW5kRGF0YShwbHVnaW5Sb290LCAkKCIjY29uc29sZUZvcm0iKS5zZXJpYWxpemUoKSk7Ci19Ci0KLWZ1bmN0aW9uIGNsZWFyT3V0cHV0KCl7Ci0gICAgb3V0cHV0RWRpdG9yLnNldFZhbHVlKCcnKQotfQotCi0kKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbiAoKSB7Ci0gICAgJCgiI2V4ZWN1dGVCdXR0b24iKS5jbGljayhleGVjdXRlU2NyaXB0KTsKLSAgICAkKCcjYWpheFNwaW5uZXInKS5oaWRlKCk7Ci0gICAgJCgnI2NvZGUtb3V0cHV0JykuaGlkZSgpOwotICAgIHNldFVwQ29kZU1pcnJvcigpOwotICAgIHNldFVwTGFuZ09wdGlvbnMoKTsKLX0pOwpkaWZmIC0tZ2l0IGEvc3JjL21haW4vcmVzb3VyY2VzL3RlbXBsYXRlcy9zY3JpcHQtY29uc29sZS5odG1sIGIvc3JjL21haW4vcmVzb3VyY2VzL3RlbXBsYXRlcy9zY3JpcHQtY29uc29sZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkOWViMjUwLi4wMDAwMDAwCi0tLSBhL3NyYy9tYWluL3Jlc291cmNlcy90ZW1wbGF0ZXMvc2NyaXB0LWNvbnNvbGUuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDM0ICswLDAgQEAKLTxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9IiR7cGx1Z2luUm9vdH0vcmVzL3VpL2NvZGVtaXJyb3IvbGliL2NvZGVtaXJyb3IuanMiPjwvc2NyaXB0PgotPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iJHtwbHVnaW5Sb290fS9yZXMvdWkvY29kZW1pcnJvci9saWIvdXRpbC9ydW5tb2RlLmpzIj48L3NjcmlwdD4KLTxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9IiR7cGx1Z2luUm9vdH0vcmVzL3VpL2NvZGVtaXJyb3IvbGliL3V0aWwvbG9hZG1vZGUuanMiPjwvc2NyaXB0PgotPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iJHtwbHVnaW5Sb290fS9yZXMvdWkvc2NyaXB0LWNvbnNvbGUuanMiPjwvc2NyaXB0PgotPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgotLy8gPCFbQ0RBVEFbCi12YXIgc2NyaXB0Q29uZmlnID0gJHtfX3NjcmlwdENvbmZpZ19ffTsKLS8vIF1dPgotPC9zY3JpcHQ+Ci0KLTwhLS0gc3RhdHVzIGxpbmUgLS0+Ci08cCBjbGFzcz0ic3RhdGxpbmUiPiZuYnNwOzwvcD4KLTxkaXYgY2xhc3M9InVpLXdpZGdldC1oZWFkZXIgIj4KLSAgICA8aW1nIGlkPSJhamF4U3Bpbm5lciIgc3JjPSIke2FwcFJvb3R9L3Jlcy9pbWdzL2xvYWRpbmcuZ2lmIiB0aWxlPSJXb3JraW5nLi4uIiAvPgotICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBpZD0iZXhlY3V0ZUJ1dHRvbiI+JHtjb25zb2xlLmV4ZWN1dGV9PC9idXR0b24+Ci0gICAgPGJ1dHRvbiB0eXBlPSJidXR0b24iIGlkPSJsYW5nQnV0dG9uIj4ke2NvbnNvbGUubGFuZ308L2J1dHRvbj4KLSAgICA8c2VsZWN0IGlkPSJjb2RlTGFuZyI+Ci0gICAgICAgIDxvcHRpb24+PC9vcHRpb24+Ci0gICAgPC9zZWxlY3Q+Ci08L2Rpdj4KLTxkaXYgaWQ9InNwbGl0dGVyIiA+Ci0gICAgPGRpdiBpZD0iY29kZS1pbnB1dCI+Ci0gICAgICAgIDxmb3JtIG1ldGhvZD0icG9zdCIgYWN0aW9uPSIke3BsdWdpblJvb3R9IiBpZD0iY29uc29sZUZvcm0iPgotICAgICAgICAgICAgPHRleHRhcmVhIGlkPSJjb2RlIiBuYW1lPSJjb2RlIgotICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPSJ3aWR0aDogOTAlOyBoZWlnaHQ6IDdlbTsgIj48L3RleHRhcmVhPgotICAgICAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iY2xpZW50IiB2YWx1ZT0id2ViY29uc29sZSIgLz4KLSAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImxhbmciIHZhbHVlPSIiIC8+Ci0gICAgICAgIDwvZm9ybT4KLSAgICA8L2Rpdj4KLSAgICA8ZGl2IGlkPSJjb2RlLW91dHB1dCI+Ci0gICAgICAgIDx0ZXh0YXJlYSBpZD0icmVzdWx0IiBzdHlsZT0id2lkdGg6IDkwJTsiIHJlYWRvbmx5PSJ5ZXMiPjwvdGV4dGFyZWE+Ci0gICAgPC9kaXY+Ci08L2Rpdj4KLQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL3NsaW5nL3NjcmlwdGluZy9jb25zb2xlL0NvbnNvbGVUZXN0Q2xpZW50LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvc2xpbmcvc2NyaXB0aW5nL2NvbnNvbGUvQ29uc29sZVRlc3RDbGllbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjMzYWE5My4uMDAwMDAwMAotLS0gYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvc2xpbmcvc2NyaXB0aW5nL2NvbnNvbGUvQ29uc29sZVRlc3RDbGllbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ2ICswLDAgQEAKLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnNsaW5nLnNjcmlwdGluZy5jb25zb2xlOwotCi1pbXBvcnQgb3JnLmFwYWNoZS5odHRwLmVudGl0eS5taW1lLk11bHRpcGFydEVudGl0eTsKLWltcG9ydCBvcmcuYXBhY2hlLmh0dHAuZW50aXR5Lm1pbWUuY29udGVudC5JbnB1dFN0cmVhbUJvZHk7Ci1pbXBvcnQgb3JnLmFwYWNoZS5odHRwLmVudGl0eS5taW1lLmNvbnRlbnQuU3RyaW5nQm9keTsKLWltcG9ydCBvcmcuYXBhY2hlLmh0dHAuaW1wbC5jbGllbnQuRGVmYXVsdEh0dHBDbGllbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS5zbGluZy50ZXN0aW5nLnRvb2xzLmh0dHAuUmVxdWVzdEJ1aWxkZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS5zbGluZy50ZXN0aW5nLnRvb2xzLmh0dHAuUmVxdWVzdEV4ZWN1dG9yOwotaW1wb3J0IG9yZy5qdW5pdC5UZXN0OwotCi1wdWJsaWMgY2xhc3MgQ29uc29sZVRlc3RDbGllbnQgewotICAgIHByaXZhdGUgRGVmYXVsdEh0dHBDbGllbnQgaHR0cENsaWVudCA9IG5ldyBEZWZhdWx0SHR0cENsaWVudCgpOwotICAgIHByaXZhdGUgUmVxdWVzdEV4ZWN1dG9yIGV4ZWN1dG9yID0gbmV3IFJlcXVlc3RFeGVjdXRvcihodHRwQ2xpZW50KTsKLQotICAgIEBUZXN0Ci0gICAgcHVibGljIHZvaWQgdGVzdFJlc291cmNlUmVzb2x2ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKLSAgICAgICAgUmVxdWVzdEJ1aWxkZXIgcmIgPSBuZXcgUmVxdWVzdEJ1aWxkZXIoImh0dHA6Ly9sb2NhbGhvc3Q6OTAwMCIpOwotCi0gICAgICAgIGZpbmFsIE11bHRpcGFydEVudGl0eSBlbnRpdHkgPSBuZXcgTXVsdGlwYXJ0RW50aXR5KCk7Ci0gICAgICAgIC8vIEFkZCBTbGluZyBQT1NUIG9wdGlvbnMKLSAgICAgICAgZW50aXR5LmFkZFBhcnQoImxhbmciLCBuZXcgU3RyaW5nQm9keSgiZXNwIikpOwotICAgICAgICBlbnRpdHkuYWRkUGFydCgiY29kZSIsIG5ldyBJbnB1dFN0cmVhbUJvZHkoZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvdGVzdC5qcyIpLCAidGVzdC5qcyIpKTsKLSAgICAgICAgZXhlY3V0b3IuZXhlY3V0ZSgKLSAgICAgICAgICAgICAgICByYi5idWlsZFBvc3RSZXF1ZXN0KCIvc3lzdGVtL2NvbnNvbGUvc2NyaXB0Y29uc29sZS5qc29uIikKLSAgICAgICAgICAgICAgICAgLndpdGhFbnRpdHkoZW50aXR5KQotICAgICAgICAgICAgICAgICAud2l0aENyZWRlbnRpYWxzKCJhZG1pbiIsImFkbWluIikKLSAgICAgICAgICAgICkuYXNzZXJ0U3RhdHVzKDIwMCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QuZ3Jvb3Z5IGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QuZ3Jvb3Z5CmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhOGMwODFjLi4wMDAwMDAwCi0tLSBhL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0Lmdyb292eQorKysgL2Rldi9udWxsCkBAIC0xLDEwICswLDAgQEAKLWltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmFwaS5yZXNvdXJjZS5SZXNvdXJjZVJlc29sdmVyRmFjdG9yeQotCi1kZWYgcmVzb3VyY2VSZXNvbHZlckZhY3RvcnkgPSBzbGluZy5nZXRTZXJ2aWNlKFJlc291cmNlUmVzb2x2ZXJGYWN0b3J5LmNsYXNzKTsKLWRlZiBhdXRoSW5mbyA9IFsKLSAgICAgICAgKFJlc291cmNlUmVzb2x2ZXJGYWN0b3J5LlVTRVIpOiJhZG1pbiIsCi0gICAgICAgIChSZXNvdXJjZVJlc29sdmVyRmFjdG9yeS5QQVNTV09SRCk6ImFkbWluIiwKLSAgICAgICAgZm9vOiJiYXIiLAotXQotZGVmIHJlc291cmNlUmVzb2x2ZXIgPSByZXNvdXJjZVJlc29sdmVyRmFjdG9yeS5nZXRSZXNvdXJjZVJlc29sdmVyKGF1dGhJbmZvKQotYXNzZXJ0IHJlc291cmNlUmVzb2x2ZXIuZ2V0QXR0cmlidXRlKCJmb28iKSA9PSAiYmFyIgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0LmpzIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QuanMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJjYmRhNzcuLjAwMDAwMDAKLS0tIGEvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QuanMKKysrIC9kZXYvbnVsbApAQCAtMSwyNCArMCwwIEBACi0KLWZ1bmN0aW9uIEFzc2VydEV4Y2VwdGlvbihtZXNzYWdlKSB7IHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7IH0KLUFzc2VydEV4Y2VwdGlvbi5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7Ci0gIHJldHVybiAnQXNzZXJ0RXhjZXB0aW9uOiAnICsgdGhpcy5tZXNzYWdlOwotfQotCi1mdW5jdGlvbiBhc3NlcnQoZXhwLCBtZXNzYWdlKSB7Ci0gIGlmICghZXhwKSB7Ci0gICAgdGhyb3cgbmV3IEFzc2VydEV4Y2VwdGlvbihtZXNzYWdlKTsKLSAgfQotfQotCi0KLXZhciByZXNvdXJjZVJlc29sdmVyRmFjdG9yeSA9IHNsaW5nLmdldFNlcnZpY2UoUGFja2FnZXMub3JnLmFwYWNoZS5zbGluZy5hcGkucmVzb3VyY2UuUmVzb3VyY2VSZXNvbHZlckZhY3RvcnkpOwotdmFyIGF1dGhJbmZvID0gbmV3IGphdmEudXRpbC5IYXNoTWFwKCkKLWF1dGhJbmZvLnB1dCgidXNlci5uYW1lIiwiYWRtaW4iKQotYXV0aEluZm8ucHV0KCJ1c2VyLnBhc3N3b3JkIixuZXcgamF2YS5sYW5nLlN0cmluZygiYWRtaW4iKS50b0NoYXJBcnJheSgpKQotYXV0aEluZm8ucHV0KCJmb28iLCJiYXIiKQotCi0KLWFzc2VydChyZXNvdXJjZVJlc29sdmVyRmFjdG9yeSAhPSBudWxsLCAiRmFjdG9yeSBjYW5ub3QgYmUgbnVsbCIpOwotdmFyIHJlc291cmNlUmVzb2x2ZXIgPSByZXNvdXJjZVJlc29sdmVyRmFjdG9yeS5nZXRSZXNvdXJjZVJlc29sdmVyKGF1dGhJbmZvKQotYXNzZXJ0KHJlc291cmNlUmVzb2x2ZXIuZ2V0QXR0cmlidXRlKCJmb28iKSA9PSAiYmFyIiwgJ09iamVjdCBpcyBudWxsJyk7Ci1vdXQucHJpbnRsbiAoInRlc3QiKQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUK