ZGlmZiAtLWdpdCBhL3BvbS54bWwgYi9wb20ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhM2E4YmYKLS0tIC9kZXYvbnVsbAorKysgYi9wb20ueG1sCkBAIC0wLDAgKzEsMTUxIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJJU08tODg1OS0xIj8+Cis8IS0tCisgICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICAgIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICAgIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgICAgcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICAgIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAgICAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgICAgd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICAgIAorICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICAgIAorICAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAgICBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICAgICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICAgIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICAgIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAgICB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorPHByb2plY3QgeG1sbnM9Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMCIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAgaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvbWF2ZW4tdjRfMF8wLnhzZCI+CisKKyAgICA8bW9kZWxWZXJzaW9uPjQuMC4wPC9tb2RlbFZlcnNpb24+CisgICAgPHBhcmVudD4KKyAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5zbGluZzwvZ3JvdXBJZD4KKyAgICAgICAgPGFydGlmYWN0SWQ+c2xpbmc8L2FydGlmYWN0SWQ+CisgICAgICAgIDx2ZXJzaW9uPjEyPC92ZXJzaW9uPgorICAgICAgICA8cmVsYXRpdmVQYXRoPi4uLy4uLy4uL3BhcmVudC9wb20ueG1sPC9yZWxhdGl2ZVBhdGg+CisgICAgPC9wYXJlbnQ+CisKKyAgICA8YXJ0aWZhY3RJZD5vcmcuYXBhY2hlLnNsaW5nLnNjcmlwdGluZy5jb25zb2xlPC9hcnRpZmFjdElkPgorICAgIDx2ZXJzaW9uPjEuMC4wLVNOQVBTSE9UPC92ZXJzaW9uPgorICAgIDxwYWNrYWdpbmc+YnVuZGxlPC9wYWNrYWdpbmc+CisKKyAgICA8bmFtZT5BcGFjaGUgU2xpbmcgU2NyaXB0IENvbnNvbGU8L25hbWU+CisgICAgPGRlc2NyaXB0aW9uPldlYiBDb25zb2xlIHBsdWdpbiBmb3IgZXZhbHVhdGluZyBzY3JpcHRzPC9kZXNjcmlwdGlvbj4KKworICAgIDxzY20+CisgICAgICAgIDxjb25uZWN0aW9uPgorICAgICAgICAgICAgc2NtOnN2bjpodHRwOi8vc3ZuLmFwYWNoZS5vcmcvcmVwb3MvYXNmL3NsaW5nL3RydW5rL2NvbnRyaWIvc2NyaXB0aW5nL3NjcmlwdC1jb25zb2xlCisgICAgICAgIDwvY29ubmVjdGlvbj4KKyAgICAgICAgPGRldmVsb3BlckNvbm5lY3Rpb24+CisgICAgICAgICAgICBzY206c3ZuOmh0dHBzOi8vc3ZuLmFwYWNoZS5vcmcvcmVwb3MvYXNmL3NsaW5nL3RydW5rL2NvbnRyaWIvc2NyaXB0aW5nL3NjcmlwdC1jb25zb2xlCisgICAgICAgIDwvZGV2ZWxvcGVyQ29ubmVjdGlvbj4KKyAgICAgICAgPHVybD4KKyAgICAgICAgICAgIGh0dHA6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmMvc2xpbmcvdHJ1bmsvY29udHJpYi9zY3JpcHRpbmcvc2NyaXB0LWNvbnNvbGUKKyAgICAgICAgPC91cmw+CisgICAgPC9zY20+CisKKyAgICA8YnVpbGQ+CisgICAgICAgIDxwbHVnaW5zPgorICAgICAgICAgICAgPHBsdWdpbj4KKyAgICAgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLmZlbGl4PC9ncm91cElkPgorICAgICAgICAgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLXNjci1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8L3BsdWdpbj4KKyAgICAgICAgICAgIDxwbHVnaW4+CisgICAgICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5mZWxpeDwvZ3JvdXBJZD4KKyAgICAgICAgICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1idW5kbGUtcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgICAgIDxleHRlbnNpb25zPnRydWU8L2V4dGVuc2lvbnM+CisgICAgICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICAgICAgICAgIDxpbnN0cnVjdGlvbnM+CisgICAgICAgICAgICAgICAgICAgIDwvaW5zdHJ1Y3Rpb25zPgorICAgICAgICAgICAgICAgIDwvY29uZmlndXJhdGlvbj4KKyAgICAgICAgICAgIDwvcGx1Z2luPgorICAgICAgICA8L3BsdWdpbnM+CisgICAgPC9idWlsZD4KKyAgICA8cmVwb3J0aW5nPgorICAgICAgICA8cGx1Z2lucz4KKyAgICAgICAgICAgIDxwbHVnaW4+CisgICAgICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorICAgICAgICAgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLWphdmFkb2MtcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgICAgIDxjb25maWd1cmF0aW9uPgorICAgICAgICAgICAgICAgICAgPCEtLSBObyBqYXZhZG9jcyAtLT4KKyAgICAgICAgICAgICAgICAgICAgPGV4Y2x1ZGVQYWNrYWdlTmFtZXM+CisgICAgICAgICAgICAgICAgICAgICAgICBvcmcuYXBhY2hlLnNsaW5nLnNjcmlwdGluZworICAgICAgICAgICAgICAgICAgICA8L2V4Y2x1ZGVQYWNrYWdlTmFtZXM+CisgICAgICAgICAgICAgICAgPC9jb25maWd1cmF0aW9uPgorICAgICAgICAgICAgPC9wbHVnaW4+CisgICAgICAgIDwvcGx1Z2lucz4KKyAgICA8L3JlcG9ydGluZz4KKworICAgIDxkZXBlbmRlbmNpZXM+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLm9zZ2k8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5vcmcub3NnaS5jb3JlPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+NC4yLjA8L3ZlcnNpb24+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAJCTxkZXBlbmRlbmN5PgorCQkgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5mZWxpeDwvZ3JvdXBJZD4KKwkJICAgIDxhcnRpZmFjdElkPm9yZy5hcGFjaGUuZmVsaXguc2NyLmFubm90YXRpb25zPC9hcnRpZmFjdElkPgorCQk8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+amF2YXguc2VydmxldDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPnNlcnZsZXQtYXBpPC9hcnRpZmFjdElkPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+Y29tbW9ucy1sYW5nPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+Y29tbW9ucy1sYW5nPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+Mi40PC92ZXJzaW9uPgorICAgICAgICAgICAgPHNjb3BlPnByb3ZpZGVkPC9zY29wZT4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgPGdyb3VwSWQ+Y29tbW9ucy1maWxldXBsb2FkPC9ncm91cElkPgorICAgICAgICAgICA8YXJ0aWZhY3RJZD5jb21tb25zLWZpbGV1cGxvYWQ8L2FydGlmYWN0SWQ+CisgICAgICAgICAgIDx2ZXJzaW9uPjEuMS4xPC92ZXJzaW9uPgorICAgICAgICAgICA8c2NvcGU+cHJvdmlkZWQ8L3Njb3BlPgorICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgIDxncm91cElkPmNvbW1vbnMtaW88L2dyb3VwSWQ+CisgICAgICAgICAgIDxhcnRpZmFjdElkPmNvbW1vbnMtaW88L2FydGlmYWN0SWQ+CisgICAgICAgICAgIDx2ZXJzaW9uPjEuMTwvdmVyc2lvbj4KKyAgICAgICAgICAgPHNjb3BlPnByb3ZpZGVkPC9zY29wZT4KKyAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLmZlbGl4PC9ncm91cElkPgorICAgICAgICAgICA8YXJ0aWZhY3RJZD5vcmcuYXBhY2hlLmZlbGl4LndlYmNvbnNvbGU8L2FydGlmYWN0SWQ+CisgICAgICAgICAgIDx2ZXJzaW9uPjMuMC4wPC92ZXJzaW9uPgorICAgICAgICAgICA8c2NvcGU+cHJvdmlkZWQ8L3Njb3BlPgorICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUuc2xpbmc8L2dyb3VwSWQ+CisgICAgICAgICAgIDxhcnRpZmFjdElkPm9yZy5hcGFjaGUuc2xpbmcuYXBpPC9hcnRpZmFjdElkPgorICAgICAgICAgICA8dmVyc2lvbj4yLjEuMDwvdmVyc2lvbj4KKyAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5zbGluZzwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm9yZy5hcGFjaGUuc2xpbmcuc2NyaXB0aW5nLmFwaTwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjIuMS4wPC92ZXJzaW9uPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5zbGluZzwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm9yZy5hcGFjaGUuc2xpbmcuYWRhcHRlcjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjIuMC40PC92ZXJzaW9uPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5zbGluZzwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm9yZy5hcGFjaGUuc2xpbmcuY29tbW9ucy5qc29uPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+Mi4wLjY8L3ZlcnNpb24+CisgICAgICAgICAgICA8c2NvcGU+cHJvdmlkZWQ8L3Njb3BlPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLnNsZjRqPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+c2xmNGotYXBpPC9hcnRpZmFjdElkPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLnNsaW5nPC9ncm91cElkPgorICAgICAgICAgICA8YXJ0aWZhY3RJZD5vcmcuYXBhY2hlLnNsaW5nLnRlc3RpbmcudG9vbHM8L2FydGlmYWN0SWQ+CisgICAgICAgICAgIDx2ZXJzaW9uPjEuMC4yPC92ZXJzaW9uPgorICAgICAgICAgICA8c2NvcGU+dGVzdDwvc2NvcGU+CisgICAgICAgPC9kZXBlbmRlbmN5PgorICAgIDwvZGVwZW5kZW5jaWVzPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vYXBwZW5kZWQtcmVzb3VyY2VzL01FVEEtSU5GL0xJQ0VOU0UgYi9zcmMvbWFpbi9hcHBlbmRlZC1yZXNvdXJjZXMvTUVUQS1JTkYvTElDRU5TRQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OGMyYTdmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vYXBwZW5kZWQtcmVzb3VyY2VzL01FVEEtSU5GL0xJQ0VOU0UKQEAgLTAsMCArMSwzMyBAQAorCisKK0FQQUNIRSBTTElORyBTQ1JJUFRJTkcgQ09OU09MRSBTVUJDT01QT05FTlRTOiAKKworVGhlIEFwYWNoZSBTbGluZyBTY3JpcHQgQ29uc29sZSBpbmNsdWRlcyBhIG51bWJlciBvZiBzdWJjb21wb25lbnRzCit3aXRoIHNlcGFyYXRlIGNvcHlyaWdodCBub3RpY2VzIGFuZCBsaWNlbnNlIHRlcm1zLiBZb3VyIHVzZSBvZiB0aGUgc291cmNlCitjb2RlIGZvciB0aGUgdGhlc2Ugc3ViY29tcG9uZW50cyBpcyBzdWJqZWN0IHRvIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucworb2YgdGhlIGZvbGxvd2luZyBsaWNlbnNlcy4gCisKKworQ29weXJpZ2h0IChDKSAyMDEyIGJ5IE1hcmlqbiBIYXZlcmJla2UgPG1hcmlqbmhAZ21haWwuY29tPgorCitQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5CitvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAoraW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwordG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbAorY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCitmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgorCitUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgorYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCisKK1RIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCitJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKK0ZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQorQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgorTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKK09VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KK1RIRSBTT0ZUV0FSRS4KKworUGxlYXNlIG5vdGUgdGhhdCBzb21lIHN1YmRpcmVjdG9yaWVzIG9mIHRoZSBDb2RlTWlycm9yIGRpc3RyaWJ1dGlvbgoraW5jbHVkZSB0aGVpciBvd24gTElDRU5TRSBmaWxlcywgYW5kIGFyZSByZWxlYXNlZCB1bmRlciBkaWZmZXJlbnQKK2xpY2VuY2VzLgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL3NjcmlwdGluZy9jb25zb2xlL2ludGVybmFsL1J1bnRpbWVTY3JpcHRSZXNvdXJjZS5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL3NjcmlwdGluZy9jb25zb2xlL2ludGVybmFsL1J1bnRpbWVTY3JpcHRSZXNvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFlZjc2ZGYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvc2NyaXB0aW5nL2NvbnNvbGUvaW50ZXJuYWwvUnVudGltZVNjcmlwdFJlc291cmNlLmphdmEKQEAgLTAsMCArMSwxNzcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLnNsaW5nLnNjcmlwdGluZy5jb25zb2xlLmludGVybmFsOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworCitpbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5hZGFwdGVyLlNsaW5nQWRhcHRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuYXBpLnJlc291cmNlLlJlc291cmNlOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuYXBpLnJlc291cmNlLlJlc291cmNlTWV0YWRhdGE7CitpbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5hcGkucmVzb3VyY2UuUmVzb3VyY2VSZXNvbHZlcjsKKworLyoqCisgKiBVc2VyOiBjaGV0YW5tCisgKiBEYXRlOiA1LzEvMTIKKyAqIFRpbWU6IDEyOjIwIFBNCisgKi8KK2NsYXNzIFJ1bnRpbWVTY3JpcHRSZXNvdXJjZSBleHRlbmRzIFNsaW5nQWRhcHRhYmxlIGltcGxlbWVudHMgUmVzb3VyY2UgeworICAgIHByaXZhdGUgUmVzb3VyY2VNZXRhZGF0YSBtZXRhZGF0YSA9IG5ldyBSZXNvdXJjZU1ldGFkYXRhKCk7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZXh0ZW5zaW9uOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHBhdGg7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gc2NyaXB0Q29udGVudDsKKworICAgIHB1YmxpYyBSdW50aW1lU2NyaXB0UmVzb3VyY2UoU3RyaW5nIGV4dGVuc2lvbiwgU3RyaW5nIHNjcmlwdFRleHQpIHsKKyAgICAgICAgdGhpcy5leHRlbnNpb24gPSBleHRlbnNpb247CisgICAgICAgIHRoaXMuc2NyaXB0Q29udGVudCA9IGdldFNjcmlwdENvbnRlbnQoc2NyaXB0VGV4dCk7CisgICAgICAgIHRoaXMucGF0aCA9ICJzY3JpcHQuIiArIGV4dGVuc2lvbjsKKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgPEFkYXB0ZXJUeXBlPiBBZGFwdGVyVHlwZSBhZGFwdFRvKENsYXNzPEFkYXB0ZXJUeXBlPiB0eXBlKSB7CisgICAgICAgIGlmKElucHV0U3RyZWFtLmNsYXNzLmlzQXNzaWduYWJsZUZyb20odHlwZSkpeworICAgICAgICAgICAgcmV0dXJuIChBZGFwdGVyVHlwZSkgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHNjcmlwdENvbnRlbnQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzdXBlci5hZGFwdFRvKHR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFic29sdXRlIHBhdGggb2YgdGhpcyByZXNvdXJjZSBpbiB0aGUgcmVzb3VyY2UgdHJlZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFBhdGgoKSB7CisgICAgICAgIHJldHVybiBwYXRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyByZXNvdXJjZS4gVGhlIG5hbWUgb2YgYSByZXNvdXJjZSBpcyB0aGUgbGFzdAorICAgICAqIHNlZ21lbnQgb2YgdGhlIHtAbGluayAjZ2V0UGF0aCgpIHBhdGh9LgorICAgICAqCisgICAgICogQHNpbmNlIDIuMS4wCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gInNjcmlwdCI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGFyZW50IHJlc291cmNlIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgcmVzb3VyY2UKKyAgICAgKiByZXByZXNlbnRzIHRoZSByb290IG9mIHRoZSByZXNvdXJjZSB0cmVlLgorICAgICAqCisgICAgICogQHNpbmNlIDIuMS4wCisgICAgICovCisgICAgcHVibGljIFJlc291cmNlIGdldFBhcmVudCgpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpdGVyYXRvciBvZiB0aGUgZGlyZWN0IGNoaWxkcmVuIG9mIHRoaXMgcmVzb3VyY2UuCisgICAgICogPHAvPgorICAgICAqIFRoaXMgbWV0aG9kIGlzIGEgY29udmVuaWVuY2UgYW5kIHJldHVybnMgZXhhY3RseSB0aGUgc2FtZSByZXNvdXJjZXMgYXMKKyAgICAgKiBjYWxsaW5nIDxjb2RlPmdldFJlc291cmNlUmVzb2x2ZXIoKS5saXN0Q2hpbGRyZW4ocmVzb3VyY2UpPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5zbGluZy5hcGkucmVzb3VyY2UuUmVzb3VyY2VSZXNvbHZlciNsaXN0Q2hpbGRyZW4ob3JnLmFwYWNoZS5zbGluZy5hcGkucmVzb3VyY2UuUmVzb3VyY2UpCisgICAgICogQHNpbmNlIDIuMS4wCisgICAgICovCisgICAgcHVibGljIEl0ZXJhdG9yPFJlc291cmNlPiBsaXN0Q2hpbGRyZW4oKSB7CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy48UmVzb3VyY2U+ZW1wdHlMaXN0KCkuaXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjaGlsZCBhdCB0aGUgZ2l2ZW4gcmVsYXRpdmUgcGF0aCBvZiB0aGlzIHJlc291cmNlIG9yCisgICAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gc3VjaCBjaGlsZCBleGlzdHMuCisgICAgICogPHAvPgorICAgICAqIFRoaXMgbWV0aG9kIGlzIGEgY29udmVuaWVuY2UgYW5kIHJldHVybnMgZXhhY3RseSB0aGUgc2FtZSByZXNvdXJjZXMgYXMKKyAgICAgKiBjYWxsaW5nIDxjb2RlPmdldFJlc291cmNlUmVzb2x2ZXIoKS5nZXRSZXNvdXJjZShyZXNvdXJjZSwgcmVsUGF0aCk8L2NvZGU+LgorICAgICAqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmFwaS5yZXNvdXJjZS5SZXNvdXJjZVJlc29sdmVyI2dldFJlc291cmNlKG9yZy5hcGFjaGUuc2xpbmcuYXBpLnJlc291cmNlLlJlc291cmNlLCBTdHJpbmcpCisgICAgICogQHNpbmNlIDIuMS4wCisgICAgICovCisgICAgcHVibGljIFJlc291cmNlIGdldENoaWxkKFN0cmluZyByZWxQYXRoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSByZXNvdXJjZSB0eXBlIGlzIG1lYW50IHRvIHBvaW50IHRvIHJlbmRlcmluZy9wcm9jZXNzaW5nIHNjcmlwdHMsCisgICAgICogZWRpdGluZyBkaWFsb2dzLCBldGMuIEl0IGlzIHVzdWFsbHkgYSBwYXRoIGluIHRoZSByZXBvc2l0b3J5LCB3aGVyZQorICAgICAqIHNjcmlwdHMgYW5kIG90aGVyIHRvb2xzIGRlZmluaXRpb25zIGFyZSBmb3VuZCwgYnV0IHRoZQorICAgICAqIHtAbGluayBvcmcuYXBhY2hlLnNsaW5nLmFwaS5yZXNvdXJjZS5SZXNvdXJjZVJlc29sdmVyfSBpcyBmcmVlIHRvIHNldCB0aGlzIHRvIGFueSBzdWl0YWJsZSB2YWx1ZSBzdWNoCisgICAgICogYXMgdGhlIHByaW1hcnkgbm9kZSB0eXBlIG9mIHRoZSBKQ1Igbm9kZSBmcm9tIHdoaWNoIHRoZSByZXNvdXJjZSBpcworICAgICAqIGNyZWF0ZWQuCisgICAgICogPHAvPgorICAgICAqIElmIHRoZSByZXNvdXJjZSBpbnN0YW5jZSByZXByZXNlbnRzIGEgcmVzb3VyY2Ugd2hpY2ggaXMgbm90IGFjdHVhbGx5CisgICAgICogZXhpc3RpbmcsIHRoaXMgbWV0aG9kIHJldHVybnMge0BsaW5rICNSRVNPVVJDRV9UWVBFX05PTl9FWElTVElOR30uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRSZXNvdXJjZVR5cGUoKSB7CisgICAgICAgIHJldHVybiBSRVNPVVJDRV9UWVBFX05PTl9FWElTVElORzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdXBlciB0eXBlIG9mIHRoZSB0eXBlIG9mIHRoZSByZXNvdXJjZSBvciA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqIGlmIHRoZSB7QGxpbmsgI2dldFJlc291cmNlVHlwZSgpfSBoYXMgbm8gc3VwZXJ0eXBlLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UmVzb3VyY2VTdXBlclR5cGUoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlc291cmNlIHR5cGUgb3IgYW55IG9mIHRoZSByZXNvdXJjZSdzCisgICAgICogc3VwZXIgdHlwZShzKSBlcXVhbHMgdGhlIGdpdmVuIHJlc291cmNlIHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVzb3VyY2VUeXBlIFRoZSByZXNvdXJjZSB0eXBlIHRvIGNoZWNrIHRoaXMgcmVzb3VyY2UgYWdhaW5zdC4KKyAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSByZXNvdXJjZSB0eXBlIG9yIGFueSBvZiB0aGUgcmVzb3VyY2UncworICAgICAqICAgICAgICAgc3VwZXIgdHlwZShzKSBlcXVhbHMgdGhlIGdpdmVuIHJlc291cmNlIHR5cGUuIDxjb2RlPmZhbHNlPC9jb2RlPgorICAgICAqICAgICAgICAgaXMgYWxzbyByZXR1cm5lZCBpZiA8Y29kZT5yZXNvdXJjZVR5cGU8L2NvZGU+IGlzCisgICAgICogICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKiBAc2luY2UgMi4xLjAKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc1Jlc291cmNlVHlwZShTdHJpbmcgcmVzb3VyY2VUeXBlKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBtZXRhZGF0YSBvZiB0aGlzIHJlc291cmNlLiBUaGUgY29uY3JldGUgZGF0YSBjb250YWluZWQgaW4gdGhlCisgICAgICoge0BsaW5rIG9yZy5hcGFjaGUuc2xpbmcuYXBpLnJlc291cmNlLlJlc291cmNlTWV0YWRhdGF9IG9iamVjdCByZXR1cm5lZCBpcyBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYworICAgICAqIGV4Y2VwdCBmb3IgdGhlIHtAbGluayBvcmcuYXBhY2hlLnNsaW5nLmFwaS5yZXNvdXJjZS5SZXNvdXJjZU1ldGFkYXRhI1JFU09MVVRJT05fUEFUSH0gcHJvcGVydHkgd2hpY2ggaXMKKyAgICAgKiByZXF1aXJlZCB0byBiZSBzZXQgdG8gdGhlIHBhcnQgb2YgdGhlIHJlcXVlc3QgVVJJIHVzZWQgdG8gcmVzb2x2ZSB0aGUKKyAgICAgKiByZXNvdXJjZS4KKyAgICAgKgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5zbGluZy5hcGkucmVzb3VyY2UuUmVzb3VyY2VNZXRhZGF0YQorICAgICAqLworICAgIHB1YmxpYyBSZXNvdXJjZU1ldGFkYXRhIGdldFJlc291cmNlTWV0YWRhdGEoKSB7CisgICAgICAgIHJldHVybiBtZXRhZGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB7QGxpbmsgb3JnLmFwYWNoZS5zbGluZy5hcGkucmVzb3VyY2UuUmVzb3VyY2VSZXNvbHZlcn0gZnJvbSB3aGljaCB0aGlzIHJlc291cmNlIGhhcyBiZWVuCisgICAgICogcmV0cmlldmVkLgorICAgICAqLworICAgIHB1YmxpYyBSZXNvdXJjZVJlc29sdmVyIGdldFJlc291cmNlUmVzb2x2ZXIoKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgYnl0ZVtdIGdldFNjcmlwdENvbnRlbnQoU3RyaW5nIHNjcmlwdFRleHQpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzY3JpcHRUZXh0LmdldEJ5dGVzKCJ1dGYtOCIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL3NjcmlwdGluZy9jb25zb2xlL2ludGVybmFsL1NjcmlwdENvbnNvbGVQbHVnaW4uamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9zY3JpcHRpbmcvY29uc29sZS9pbnRlcm5hbC9TY3JpcHRDb25zb2xlUGx1Z2luLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWZjZmU5YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9zY3JpcHRpbmcvY29uc29sZS9pbnRlcm5hbC9TY3JpcHRDb25zb2xlUGx1Z2luLmphdmEKQEAgLTAsMCArMSwyNDYgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLnNsaW5nLnNjcmlwdGluZy5jb25zb2xlLmludGVybmFsOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZheC5zY3JpcHQuU2NyaXB0RW5naW5lRmFjdG9yeTsKK2ltcG9ydCBqYXZheC5zY3JpcHQuU2NyaXB0RW5naW5lTWFuYWdlcjsKK2ltcG9ydCBqYXZheC5zZXJ2bGV0LlNlcnZsZXRFeGNlcHRpb247CitpbXBvcnQgamF2YXguc2VydmxldC5odHRwLkh0dHBTZXJ2bGV0UmVxdWVzdDsKK2ltcG9ydCBqYXZheC5zZXJ2bGV0Lmh0dHAuSHR0cFNlcnZsZXRSZXNwb25zZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5maWxldXBsb2FkLkZpbGVJdGVtOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5pby5JT1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXguc2NyLmFubm90YXRpb25zLio7CitpbXBvcnQgb3JnLmFwYWNoZS5mZWxpeC53ZWJjb25zb2xlLkFic3RyYWN0V2ViQ29uc29sZVBsdWdpbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmZlbGl4LndlYmNvbnNvbGUuRGVmYXVsdFZhcmlhYmxlUmVzb2x2ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5mZWxpeC53ZWJjb25zb2xlLlNpbXBsZVdlYkNvbnNvbGVQbHVnaW47CitpbXBvcnQgb3JnLmFwYWNoZS5mZWxpeC53ZWJjb25zb2xlLldlYkNvbnNvbGVVdGlsOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuYXBpLnJlc291cmNlLlJlc291cmNlOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuYXBpLnNjcmlwdGluZy5TbGluZ0JpbmRpbmdzOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuYXBpLnNjcmlwdGluZy5TbGluZ1NjcmlwdDsKK2ltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmNvbW1vbnMuanNvbi5KU09ORXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuY29tbW9ucy5qc29uLmlvLkpTT05Xcml0ZXI7CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQ7CitpbXBvcnQgb3JnLnNsZjRqLkxvZ2dlcjsKK2ltcG9ydCBvcmcuc2xmNGouTG9nZ2VyRmFjdG9yeTsKKworLyoqCisgKiBVc2VyOiBjaGV0YW5tCisgKiBEYXRlOiA0LzMwLzEyCisgKiBUaW1lOiA5OjA2IFBNCisgKi8KK0BDb21wb25lbnQKK0BTZXJ2aWNlCitAUHJvcGVydHkobmFtZSA9ICJmZWxpeC53ZWJjb25zb2xlLmxhYmVsIiwgdmFsdWUgPSBTY3JpcHRDb25zb2xlUGx1Z2luLk5BTUUpCitwdWJsaWMgY2xhc3MgU2NyaXB0Q29uc29sZVBsdWdpbiBleHRlbmRzIFNpbXBsZVdlYkNvbnNvbGVQbHVnaW4geworICAgIHByaXZhdGUgTG9nZ2VyIGxvZyA9IExvZ2dlckZhY3RvcnkuZ2V0TG9nZ2VyKGdldENsYXNzKCkpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUUgPSAic2NyaXB0Y29uc29sZSI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRJVExFID0gIiVzY3JpcHQudGl0bGUiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIENTUyA9IHsiL3Jlcy91aS9jb2RlbWlycm9yL2xpYi9jb2RlbWlycm9yLmNzcyIsIi9yZXMvdWkvc2NyaXB0LWNvbnNvbGUuY3NzIn07CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgVEVNUExBVEU7CisgICAgcHJpdmF0ZSBCdW5kbGVDb250ZXh0IGJ1bmRsZUNvbnRleHQ7CisKKyAgICBAUmVmZXJlbmNlCisgICAgcHJpdmF0ZSBTY3JpcHRFbmdpbmVNYW5hZ2VyIHNjcmlwdEVuZ2luZU1hbmFnZXI7CisKKyAgICBwdWJsaWMgU2NyaXB0Q29uc29sZVBsdWdpbigpIHsKKyAgICAgICAgc3VwZXIoTkFNRSwgVElUTEUsIHByb2Nlc3NGaWxlTmFtZXMoQ1NTKSk7CisgICAgICAgIFRFTVBMQVRFID0gcmVhZFRlbXBsYXRlRmlsZSgiL3RlbXBsYXRlcy9zY3JpcHQtY29uc29sZS5odG1sIik7CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgcmVuZGVyQ29udGVudChIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpIHRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFByaW50V3JpdGVyIHB3ID0gcmVzcG9uc2UuZ2V0V3JpdGVyKCk7CisgICAgICAgIERlZmF1bHRWYXJpYWJsZVJlc29sdmVyIHZhclJlc29sdmVyID0gKERlZmF1bHRWYXJpYWJsZVJlc29sdmVyKSBXZWJDb25zb2xlVXRpbC5nZXRWYXJpYWJsZVJlc29sdmVyKHJlcXVlc3QpOworICAgICAgICB2YXJSZXNvbHZlci5wdXQoIl9fc2NyaXB0Q29uZmlnX18iLGdldFNjcmlwdENvbmZpZygpKTsKKyAgICAgICAgcHcucHJpbnRsbihURU1QTEFURSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZG9Qb3N0KEh0dHBTZXJ2bGV0UmVxdWVzdCByZXEsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcCkgdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUocmVxKTsKKyAgICAgICAgcmVzcC5zZXRDb250ZW50VHlwZShjb250ZW50VHlwZSk7CisgICAgICAgIGlmIChjb250ZW50VHlwZS5zdGFydHNXaXRoKCJ0ZXh0LyIpKSB7CisgICAgICAgICAgICByZXNwLnNldENoYXJhY3RlckVuY29kaW5nKCJVVEYtOCIpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIFN0cmluZyBzY3JpcHQgPSBnZXRDb2RlVmFsdWUocmVxKTsKKyAgICAgICAgZmluYWwgU2xpbmdCaW5kaW5ncyBiaW5kaW5ncyA9IG5ldyBTbGluZ0JpbmRpbmdzKCk7CisgICAgICAgIGZpbmFsIFByaW50V3JpdGVyIHB3ID0gcmVzcC5nZXRXcml0ZXIoKTsKKyAgICAgICAgLy9Qb3B1bGF0ZSBiaW5kaW5ncworICAgICAgICBiaW5kaW5ncy5wdXQoU2xpbmdCaW5kaW5ncy5SRVFVRVNULCByZXEpOworICAgICAgICBiaW5kaW5ncy5wdXQoU2xpbmdCaW5kaW5ncy5SRUFERVIsIG5ldyBTdHJpbmdSZWFkZXIoc2NyaXB0KSk7CisgICAgICAgIGJpbmRpbmdzLnB1dChTbGluZ0JpbmRpbmdzLlJFU1BPTlNFLCByZXNwKTsKKyAgICAgICAgYmluZGluZ3MucHV0KFNsaW5nQmluZGluZ3MuT1VULCBwdyk7CisKKyAgICAgICAgLy9BbHNvIGV4cG9zZSB0aGUgYnVuZGxlQ29udGV4dCB0byBzaW1wbGlmeSBzY3JpcHRzIGludGVyYWN0aW9uIHdpdGggdGhlCisgICAgICAgIC8vZW5jbG9zaW5nIE9TR2kgY29udGFpbmVyCisgICAgICAgIGJpbmRpbmdzLnB1dCgiYnVuZGxlQ29udGV4dCIsIGJ1bmRsZUNvbnRleHQpOworCisKKworICAgICAgICBmaW5hbCBTdHJpbmcgbGFuZyA9IFdlYkNvbnNvbGVVdGlsLmdldFBhcmFtZXRlcihyZXEsICJsYW5nIik7CisgICAgICAgIGZpbmFsIFJlc291cmNlIHJlc291cmNlID0gbmV3IFJ1bnRpbWVTY3JpcHRSZXNvdXJjZShsYW5nLCBzY3JpcHQpOworICAgICAgICBmaW5hbCBib29sZWFuIHdlYkNsaWVudCA9ICJ3ZWJjb25zb2xlIi5lcXVhbHMoV2ViQ29uc29sZVV0aWwuZ2V0UGFyYW1ldGVyKHJlcSwiY2xpZW50IikpOworCisgICAgICAgIFNsaW5nU2NyaXB0IHNsaW5nU2NyaXB0ID0gcmVzb3VyY2UuYWRhcHRUbyhTbGluZ1NjcmlwdC5jbGFzcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsb2cuZGVidWcoIkV4ZWN1dGluZyBzY3JpcHQge30iLHNjcmlwdCk7CisgICAgICAgICAgICBzbGluZ1NjcmlwdC5ldmFsKGJpbmRpbmdzKTsKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpeworICAgICAgICAgICAgaWYoIXdlYkNsaWVudCl7CisgICAgICAgICAgICAgICAgcmVzcC5zZXRTdGF0dXMoNTAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHB3LnByaW50bG4oZXhjZXB0aW9uVG9TdHJpbmcodCkpOworICAgICAgICAgICAgbG9nLndhcm4oIkVycm9yIGluIGV4ZWN1dGluZyBzY3JpcHQiLHQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0Q29kZVZhbHVlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBzY3JpcHQgPSBXZWJDb25zb2xlVXRpbC5nZXRQYXJhbWV0ZXIocmVxLCAiY29kZSIpOworICAgICAgICBpZihzY3JpcHQgPT0gbnVsbCl7CisgICAgICAgICAgICBzY3JpcHQgPSBnZXRDb250ZW50RnJvbUZpbGVQYXJ0KHJlcSwgImNvZGUiKTsKKyAgICAgICAgfQorICAgICAgICBpZihzY3JpcHQgPT0gbnVsbCl7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCInY29kZScgcGFyYW1ldGVyIG5vdCBwYXNzZWQiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2NyaXB0OworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGdldENvbnRlbnRUeXBlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXEpIHsKKyAgICAgICAgU3RyaW5nIHBhc3NlZENvbnRlbnRUeXBlID0gV2ViQ29uc29sZVV0aWwuZ2V0UGFyYW1ldGVyKHJlcSwicmVzcG9uc2VDb250ZW50VHlwZSIpOworICAgICAgICBpZihwYXNzZWRDb250ZW50VHlwZSAhPSBudWxsKXsKKyAgICAgICAgICAgIHJldHVybiBwYXNzZWRDb250ZW50VHlwZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVxLmdldFBhdGhJbmZvKCkuZW5kc1dpdGgoIi5qc29uIikgPyAiYXBwbGljYXRpb24vanNvbiIgOiAidGV4dC9wbGFpbiI7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgZXhjZXB0aW9uVG9TdHJpbmcoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgU3RyaW5nV3JpdGVyIHN3ID0gbmV3IFN0cmluZ1dyaXRlcigpOworICAgICAgICB0LnByaW50U3RhY2tUcmFjZShuZXcgUHJpbnRXcml0ZXIoc3cpKTsKKyAgICAgICAgcmV0dXJuIHN3LnRvU3RyaW5nKCk7CisgICAgfQorCisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBwcm9jZXNzRmlsZU5hbWVzKFN0cmluZ1tdIGNzc0ZpbGVzKSB7CisgICAgICAgIFN0cmluZ1tdIGNzcyA9IG5ldyBTdHJpbmdbY3NzRmlsZXMubGVuZ3RoXTsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGNzc0ZpbGVzLmxlbmd0aDsgaSsrKXsKKyAgICAgICAgICAgIGNzc1tpXSA9ICAnLycgKyBOQU1FICsgQ1NTW2ldOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjc3M7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0U2NyaXB0Q29uZmlnKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIGdldFNjcmlwdENvbmZpZzAoKTsKKyAgICAgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGdldFNjcmlwdENvbmZpZzAoKSB0aHJvd3MgSlNPTkV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1dyaXRlciBzdyA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKKyAgICAgICAgSlNPTldyaXRlciBqdyA9IG5ldyBKU09OV3JpdGVyKHN3KTsKKyAgICAgICAgancuc2V0VGlkeSh0cnVlKTsKKyAgICAgICAgancuYXJyYXkoKTsKKworICAgICAgICBmb3IoU2NyaXB0RW5naW5lRmFjdG9yeSBzZWYgOiBzY3JpcHRFbmdpbmVNYW5hZ2VyLmdldEVuZ2luZUZhY3RvcmllcygpKXsKKyAgICAgICAgICAgIGp3Lm9iamVjdCgpOworICAgICAgICAgICAgaWYoc2VmLmdldEV4dGVuc2lvbnMoKS5pc0VtcHR5KCkpeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgancua2V5KCJsYW5nTmFtZSIpLnZhbHVlKHNlZi5nZXRMYW5ndWFnZU5hbWUoKSk7CisgICAgICAgICAgICBqdy5rZXkoImxhbmdDb2RlIikudmFsdWUoc2VmLmdldEV4dGVuc2lvbnMoKS5nZXQoMCkpOworCisgICAgICAgICAgICAvL0xhbmd1YWdlIG1vZGUgYXMgcGVyIENvZGVNaXJyb3IgbmFtZXMKKyAgICAgICAgICAgIFN0cmluZyBtb2RlID0gZGV0ZXJtaW5lTW9kZShzZWYuZ2V0RXh0ZW5zaW9ucygpKTsKKyAgICAgICAgICAgIGlmKG1vZGUgIT0gbnVsbCl7CisgICAgICAgICAgICAgICAgancua2V5KCJtb2RlIikudmFsdWUobW9kZSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGp3LmVuZE9iamVjdCgpOworICAgICAgICB9CisKKyAgICAgICAgancuZW5kQXJyYXkoKTsKKyAgICAgICAgcmV0dXJuIHN3LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgZGV0ZXJtaW5lTW9kZShMaXN0PFN0cmluZz4gZXh0ZW5zaW9ucykgeworICAgICAgICBpZihleHRlbnNpb25zLmNvbnRhaW5zKCJncm9vdnkiKSl7CisgICAgICAgICAgICByZXR1cm4gImdyb292eSI7CisgICAgICAgIH1lbHNlIGlmIChleHRlbnNpb25zLmNvbnRhaW5zKCJlc3AiKSl7CisgICAgICAgICAgICByZXR1cm4gImphdmFzY3JpcHQiOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGdldENvbnRlbnRGcm9tRmlsZVBhcnQoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcSwgU3RyaW5nIHBhcmFtTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHZhbHVlID0gV2ViQ29uc29sZVV0aWwuZ2V0UGFyYW1ldGVyKHJlcSwgcGFyYW1OYW1lKTsKKyAgICAgICAgaWYodmFsdWUgIT0gbnVsbCl7CisgICAgICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgTWFwIHBhcmFtcyA9IChNYXApIHJlcS5nZXRBdHRyaWJ1dGUoIEFic3RyYWN0V2ViQ29uc29sZVBsdWdpbi5BVFRSX0ZJTEVVUExPQUQgKTsKKyAgICAgICAgaWYgKCBwYXJhbXMgPT0gbnVsbCApeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgRmlsZUl0ZW1bXSBjb2RlRmlsZSA9IGdldEZpbGVJdGVtcyhwYXJhbXMscGFyYW1OYW1lKTsKKyAgICAgICAgaWYoY29kZUZpbGUubGVuZ3RoID09IDApeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBudWxsOworICAgICAgICB0cnl7CisgICAgICAgICAgICBpcyA9IGNvZGVGaWxlWzBdLmdldElucHV0U3RyZWFtKCk7CisgICAgICAgICAgICBTdHJpbmdXcml0ZXIgc3cgPSBuZXcgU3RyaW5nV3JpdGVyKCk7CisgICAgICAgICAgICBJT1V0aWxzLmNvcHkoaXMsc3csInV0Zi04Iik7CisgICAgICAgICAgICByZXR1cm4gc3cudG9TdHJpbmcoKTsKKyAgICAgICAgfWZpbmFsbHl7CisgICAgICAgICAgICBJT1V0aWxzLmNsb3NlUXVpZXRseShpcyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIEZpbGVJdGVtW10gZ2V0RmlsZUl0ZW1zKE1hcCBwYXJhbXMsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIGZpbmFsIExpc3QgZmlsZXMgPSBuZXcgQXJyYXlMaXN0KCk7CisgICAgICAgIEZpbGVJdGVtW10gaXRlbXMgPSAoRmlsZUl0ZW1bXSkgcGFyYW1zLmdldChuYW1lKTsKKyAgICAgICAgaWYgKGl0ZW1zICE9IG51bGwpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoIWl0ZW1zW2ldLmlzRm9ybUZpZWxkKCkgJiYgaXRlbXNbaV0uZ2V0U2l6ZSgpID4gMCkgeworICAgICAgICAgICAgICAgICAgICBmaWxlcy5hZGQoaXRlbXNbaV0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKEZpbGVJdGVtW10pIGZpbGVzLnRvQXJyYXkobmV3IEZpbGVJdGVtW2ZpbGVzLnNpemUoKV0pOworICAgIH0KKworICAgIEBBY3RpdmF0ZQorICAgIHB1YmxpYyB2b2lkIGFjdGl2YXRlKEJ1bmRsZUNvbnRleHQgYnVuZGxlQ29udGV4dCkgeworICAgICAgICBzdXBlci5hY3RpdmF0ZShidW5kbGVDb250ZXh0KTsKKyAgICAgICAgdGhpcy5idW5kbGVDb250ZXh0ID0gYnVuZGxlQ29udGV4dDsKKyAgICB9CisKKyAgICBARGVhY3RpdmF0ZQorICAgIHB1YmxpYyB2b2lkIGRlYWN0aXZhdGUoKSB7CisgICAgICAgIHN1cGVyLmRlYWN0aXZhdGUoKTsKKyAgICB9CisKKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vcmVzb3VyY2VzL09TR0ktSU5GL2wxMG4vYnVuZGxlLnByb3BlcnRpZXMgYi9zcmMvbWFpbi9yZXNvdXJjZXMvT1NHSS1JTkYvbDEwbi9idW5kbGUucHJvcGVydGllcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNTRkZTMyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vcmVzb3VyY2VzL09TR0ktSU5GL2wxMG4vYnVuZGxlLnByb3BlcnRpZXMKQEAgLTAsMCArMSwyMCBAQAorIworIyBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyMgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisjIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyMgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyMgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyMgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyMKKworc2NyaXB0LnRpdGxlPVNjcmlwdCBDb25zb2xlCitjb25zb2xlLmV4ZWN1dGU9RXhlY3V0ZQorY29uc29sZS5sYW5nPUxhbmd1YWdlClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9jb2RlbWlycm9yL2xpYi9jb2RlbWlycm9yLmNzcyBiL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci9saWIvY29kZW1pcnJvci5jc3MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWM5YzI5YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci9saWIvY29kZW1pcnJvci5jc3MKQEAgLTAsMCArMSwxMTQgQEAKKy5Db2RlTWlycm9yIHsKKyAgbGluZS1oZWlnaHQ6IDFlbTsKKyAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsKK30KKworLkNvZGVNaXJyb3Itc2Nyb2xsIHsKKyAgb3ZlcmZsb3c6IGF1dG87CisgIGhlaWdodDogMzAwcHg7CisgIC8qIFRoaXMgaXMgbmVlZGVkIHRvIHByZXZlbnQgYW4gSUVbNjddIGJ1ZyB3aGVyZSB0aGUgc2Nyb2xsZWQgY29udGVudAorICAgICBpcyB2aXNpYmxlIG91dHNpZGUgb2YgdGhlIHNjcm9sbGluZyBib3guICovCisgIHBvc2l0aW9uOiByZWxhdGl2ZTsKKyAgb3V0bGluZTogbm9uZTsKK30KKworLkNvZGVNaXJyb3ItZ3V0dGVyIHsKKyAgcG9zaXRpb246IGFic29sdXRlOyBsZWZ0OiAwOyB0b3A6IDA7CisgIHotaW5kZXg6IDEwOworICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjdmN2Y3OworICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjZWVlOworICBtaW4td2lkdGg6IDJlbTsKKyAgaGVpZ2h0OiAxMDAlOworfQorLkNvZGVNaXJyb3ItZ3V0dGVyLXRleHQgeworICBjb2xvcjogI2FhYTsKKyAgdGV4dC1hbGlnbjogcmlnaHQ7CisgIHBhZGRpbmc6IC40ZW0gLjJlbSAuNGVtIC40ZW07CisgIHdoaXRlLXNwYWNlOiBwcmUgIWltcG9ydGFudDsKK30KKy5Db2RlTWlycm9yLWxpbmVzIHsKKyAgcGFkZGluZzogLjRlbTsKKyAgd2hpdGUtc3BhY2U6IHByZTsKK30KKworLkNvZGVNaXJyb3IgcHJlIHsKKyAgLW1vei1ib3JkZXItcmFkaXVzOiAwOworICAtd2Via2l0LWJvcmRlci1yYWRpdXM6IDA7CisgIC1vLWJvcmRlci1yYWRpdXM6IDA7CisgIGJvcmRlci1yYWRpdXM6IDA7CisgIGJvcmRlci13aWR0aDogMDsgbWFyZ2luOiAwOyBwYWRkaW5nOiAwOyBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsKKyAgZm9udC1mYW1pbHk6IGluaGVyaXQ7CisgIGZvbnQtc2l6ZTogaW5oZXJpdDsKKyAgcGFkZGluZzogMDsgbWFyZ2luOiAwOworICB3aGl0ZS1zcGFjZTogcHJlOworICB3b3JkLXdyYXA6IG5vcm1hbDsKKyAgbGluZS1oZWlnaHQ6IGluaGVyaXQ7Cit9CisKKy5Db2RlTWlycm9yLXdyYXAgcHJlIHsKKyAgd29yZC13cmFwOiBicmVhay13b3JkOworICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7CisgIHdvcmQtYnJlYWs6IG5vcm1hbDsKK30KKy5Db2RlTWlycm9yLXdyYXAgLkNvZGVNaXJyb3Itc2Nyb2xsIHsKKyAgb3ZlcmZsb3cteDogaGlkZGVuOworfQorCisuQ29kZU1pcnJvciB0ZXh0YXJlYSB7CisgIG91dGxpbmU6IG5vbmUgIWltcG9ydGFudDsKK30KKworLkNvZGVNaXJyb3IgcHJlLkNvZGVNaXJyb3ItY3Vyc29yIHsKKyAgei1pbmRleDogMTA7CisgIHBvc2l0aW9uOiBhYnNvbHV0ZTsKKyAgdmlzaWJpbGl0eTogaGlkZGVuOworICBib3JkZXItbGVmdDogMXB4IHNvbGlkIGJsYWNrOworICBib3JkZXItcmlnaHQ6bm9uZTsKKyAgd2lkdGg6MDsKK30KKy5Db2RlTWlycm9yIHByZS5Db2RlTWlycm9yLWN1cnNvci5Db2RlTWlycm9yLW92ZXJ3cml0ZSB7fQorLkNvZGVNaXJyb3ItZm9jdXNlZCBwcmUuQ29kZU1pcnJvci1jdXJzb3IgeworICB2aXNpYmlsaXR5OiB2aXNpYmxlOworfQorCitkaXYuQ29kZU1pcnJvci1zZWxlY3RlZCB7IGJhY2tncm91bmQ6ICNkOWQ5ZDk7IH0KKy5Db2RlTWlycm9yLWZvY3VzZWQgZGl2LkNvZGVNaXJyb3Itc2VsZWN0ZWQgeyBiYWNrZ3JvdW5kOiAjZDdkNGYwOyB9CisKKy5Db2RlTWlycm9yLXNlYXJjaGluZyB7CisgIGJhY2tncm91bmQ6ICNmZmE7CisgIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDAsIC40KTsKK30KKworLyogRGVmYXVsdCB0aGVtZSAqLworCisuY20tcy1kZWZhdWx0IHNwYW4uY20ta2V5d29yZCB7Y29sb3I6ICM3MDg7fQorLmNtLXMtZGVmYXVsdCBzcGFuLmNtLWF0b20ge2NvbG9yOiAjMjE5O30KKy5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1udW1iZXIge2NvbG9yOiAjMTY0O30KKy5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1kZWYge2NvbG9yOiAjMDBmO30KKy5jbS1zLWRlZmF1bHQgc3Bhbi5jbS12YXJpYWJsZSB7Y29sb3I6IGJsYWNrO30KKy5jbS1zLWRlZmF1bHQgc3Bhbi5jbS12YXJpYWJsZS0yIHtjb2xvcjogIzA1YTt9CisuY20tcy1kZWZhdWx0IHNwYW4uY20tdmFyaWFibGUtMyB7Y29sb3I6ICMwODU7fQorLmNtLXMtZGVmYXVsdCBzcGFuLmNtLXByb3BlcnR5IHtjb2xvcjogYmxhY2s7fQorLmNtLXMtZGVmYXVsdCBzcGFuLmNtLW9wZXJhdG9yIHtjb2xvcjogYmxhY2s7fQorLmNtLXMtZGVmYXVsdCBzcGFuLmNtLWNvbW1lbnQge2NvbG9yOiAjYTUwO30KKy5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1zdHJpbmcge2NvbG9yOiAjYTExO30KKy5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1zdHJpbmctMiB7Y29sb3I6ICNmNTA7fQorLmNtLXMtZGVmYXVsdCBzcGFuLmNtLW1ldGEge2NvbG9yOiAjNTU1O30KKy5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1lcnJvciB7Y29sb3I6ICNmMDA7fQorLmNtLXMtZGVmYXVsdCBzcGFuLmNtLXF1YWxpZmllciB7Y29sb3I6ICM1NTU7fQorLmNtLXMtZGVmYXVsdCBzcGFuLmNtLWJ1aWx0aW4ge2NvbG9yOiAjMzBhO30KKy5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1icmFja2V0IHtjb2xvcjogI2NjNzt9CisuY20tcy1kZWZhdWx0IHNwYW4uY20tdGFnIHtjb2xvcjogIzE3MDt9CisuY20tcy1kZWZhdWx0IHNwYW4uY20tYXR0cmlidXRlIHtjb2xvcjogIzAwYzt9CisuY20tcy1kZWZhdWx0IHNwYW4uY20taGVhZGVyIHtjb2xvcjogI2EwYTt9CisuY20tcy1kZWZhdWx0IHNwYW4uY20tcXVvdGUge2NvbG9yOiAjMDkwO30KKy5jbS1zLWRlZmF1bHQgc3Bhbi5jbS1ociB7Y29sb3I6ICM5OTk7fQorLmNtLXMtZGVmYXVsdCBzcGFuLmNtLWxpbmsge2NvbG9yOiAjMDBjO30KKworc3Bhbi5jbS1oZWFkZXIsIHNwYW4uY20tc3Ryb25nIHtmb250LXdlaWdodDogYm9sZDt9CitzcGFuLmNtLWVtIHtmb250LXN0eWxlOiBpdGFsaWM7fQorc3Bhbi5jbS1lbXN0cm9uZyB7Zm9udC1zdHlsZTogaXRhbGljOyBmb250LXdlaWdodDogYm9sZDt9CitzcGFuLmNtLWxpbmsge3RleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO30KKworZGl2LkNvZGVNaXJyb3Igc3Bhbi5Db2RlTWlycm9yLW1hdGNoaW5nYnJhY2tldCB7Y29sb3I6ICMwZjA7fQorZGl2LkNvZGVNaXJyb3Igc3Bhbi5Db2RlTWlycm9yLW5vbm1hdGNoaW5nYnJhY2tldCB7Y29sb3I6ICNmMjI7fQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9jb2RlbWlycm9yL2xpYi9jb2RlbWlycm9yLmpzIGIvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9jb2RlbWlycm9yL2xpYi9jb2RlbWlycm9yLmpzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5Zjg0NjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL2NvZGVtaXJyb3IvbGliL2NvZGVtaXJyb3IuanMKQEAgLTAsMCArMSwzMDQ3IEBACisvLyBDb2RlTWlycm9yIHZlcnNpb24gMi4yNAorLy8KKy8vIEFsbCBmdW5jdGlvbnMgdGhhdCBuZWVkIGFjY2VzcyB0byB0aGUgZWRpdG9yJ3Mgc3RhdGUgbGl2ZSBpbnNpZGUKKy8vIHRoZSBDb2RlTWlycm9yIGZ1bmN0aW9uLiBCZWxvdyB0aGF0LCBhdCB0aGUgYm90dG9tIG9mIHRoZSBmaWxlLAorLy8gc29tZSB1dGlsaXRpZXMgYXJlIGRlZmluZWQuCisKKy8vIENvZGVNaXJyb3IgaXMgdGhlIG9ubHkgZ2xvYmFsIHZhciB3ZSBjbGFpbQordmFyIENvZGVNaXJyb3IgPSAoZnVuY3Rpb24oKSB7CisgIC8vIFRoaXMgaXMgdGhlIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYW4gZWRpdG9yIGluc3RhbmNlLiBJdHMKKyAgLy8gY2xvc3VyZSBpcyB1c2VkIHRvIHN0b3JlIHRoZSBlZGl0b3Igc3RhdGUuCisgIGZ1bmN0aW9uIENvZGVNaXJyb3IocGxhY2UsIGdpdmVuT3B0aW9ucykgeworICAgIC8vIERldGVybWluZSBlZmZlY3RpdmUgb3B0aW9ucyBiYXNlZCBvbiBnaXZlbiB2YWx1ZXMgYW5kIGRlZmF1bHRzLgorICAgIHZhciBvcHRpb25zID0ge30sIGRlZmF1bHRzID0gQ29kZU1pcnJvci5kZWZhdWx0czsKKyAgICBmb3IgKHZhciBvcHQgaW4gZGVmYXVsdHMpCisgICAgICBpZiAoZGVmYXVsdHMuaGFzT3duUHJvcGVydHkob3B0KSkKKyAgICAgICAgb3B0aW9uc1tvcHRdID0gKGdpdmVuT3B0aW9ucyAmJiBnaXZlbk9wdGlvbnMuaGFzT3duUHJvcGVydHkob3B0KSA/IGdpdmVuT3B0aW9ucyA6IGRlZmF1bHRzKVtvcHRdOworCisgICAgLy8gVGhlIGVsZW1lbnQgaW4gd2hpY2ggdGhlIGVkaXRvciBsaXZlcy4KKyAgICB2YXIgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpOworICAgIHdyYXBwZXIuY2xhc3NOYW1lID0gIkNvZGVNaXJyb3IiICsgKG9wdGlvbnMubGluZVdyYXBwaW5nID8gIiBDb2RlTWlycm9yLXdyYXAiIDogIiIpOworICAgIC8vIFRoaXMgbWVzcyBjcmVhdGVzIHRoZSBiYXNlIERPTSBzdHJ1Y3R1cmUgZm9yIHRoZSBlZGl0b3IuCisgICAgd3JhcHBlci5pbm5lckhUTUwgPQorICAgICAgJzxkaXYgc3R5bGU9Im92ZXJmbG93OiBoaWRkZW47IHBvc2l0aW9uOiByZWxhdGl2ZTsgd2lkdGg6IDNweDsgaGVpZ2h0OiAwcHg7Ij4nICsgLy8gV3JhcHMgYW5kIGhpZGVzIGlucHV0IHRleHRhcmVhCisgICAgICAgICc8dGV4dGFyZWEgc3R5bGU9InBvc2l0aW9uOiBhYnNvbHV0ZTsgcGFkZGluZzogMDsgd2lkdGg6IDFweDsgaGVpZ2h0OiAxZW0iIHdyYXA9Im9mZiIgJyArCisgICAgICAgICAgJ2F1dG9jb3JyZWN0PSJvZmYiIGF1dG9jYXBpdGFsaXplPSJvZmYiPjwvdGV4dGFyZWE+PC9kaXY+JyArCisgICAgICAnPGRpdiBjbGFzcz0iQ29kZU1pcnJvci1zY3JvbGwiIHRhYmluZGV4PSItMSI+JyArCisgICAgICAgICc8ZGl2IHN0eWxlPSJwb3NpdGlvbjogcmVsYXRpdmUiPicgKyAvLyBTZXQgdG8gdGhlIGhlaWdodCBvZiB0aGUgdGV4dCwgY2F1c2VzIHNjcm9sbGluZworICAgICAgICAgICc8ZGl2IHN0eWxlPSJwb3NpdGlvbjogcmVsYXRpdmUiPicgKyAvLyBNb3ZlZCBhcm91bmQgaXRzIHBhcmVudCB0byBjb3ZlciB2aXNpYmxlIHZpZXcKKyAgICAgICAgICAgICc8ZGl2IGNsYXNzPSJDb2RlTWlycm9yLWd1dHRlciI+PGRpdiBjbGFzcz0iQ29kZU1pcnJvci1ndXR0ZXItdGV4dCI+PC9kaXY+PC9kaXY+JyArCisgICAgICAgICAgICAvLyBQcm92aWRlcyBwb3NpdGlvbmluZyByZWxhdGl2ZSB0byAodmlzaWJsZSkgdGV4dCBvcmlnaW4KKyAgICAgICAgICAgICc8ZGl2IGNsYXNzPSJDb2RlTWlycm9yLWxpbmVzIj48ZGl2IHN0eWxlPSJwb3NpdGlvbjogcmVsYXRpdmU7IHotaW5kZXg6IDAiPicgKworICAgICAgICAgICAgICAnPGRpdiBzdHlsZT0icG9zaXRpb246IGFic29sdXRlOyB3aWR0aDogMTAwJTsgaGVpZ2h0OiAwOyBvdmVyZmxvdzogaGlkZGVuOyB2aXNpYmlsaXR5OiBoaWRkZW47Ij48L2Rpdj4nICsKKyAgICAgICAgICAgICAgJzxwcmUgY2xhc3M9IkNvZGVNaXJyb3ItY3Vyc29yIj4mIzE2MDs8L3ByZT4nICsgLy8gQWJzb2x1dGVseSBwb3NpdGlvbmVkIGJsaW5reSBjdXJzb3IKKyAgICAgICAgICAgICAgJzxkaXYgc3R5bGU9InBvc2l0aW9uOiByZWxhdGl2ZTsgei1pbmRleDogLTEiPjwvZGl2PjxkaXY+PC9kaXY+JyArIC8vIERJVnMgY29udGFpbmluZyB0aGUgc2VsZWN0aW9uIGFuZCB0aGUgYWN0dWFsIGNvZGUKKyAgICAgICAgICAgICc8L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj4nOworICAgIGlmIChwbGFjZS5hcHBlbmRDaGlsZCkgcGxhY2UuYXBwZW5kQ2hpbGQod3JhcHBlcik7IGVsc2UgcGxhY2Uod3JhcHBlcik7CisgICAgLy8gSSd2ZSBuZXZlciBzZWVuIG1vcmUgZWxlZ2FudCBjb2RlIGluIG15IGxpZmUuCisgICAgdmFyIGlucHV0RGl2ID0gd3JhcHBlci5maXJzdENoaWxkLCBpbnB1dCA9IGlucHV0RGl2LmZpcnN0Q2hpbGQsCisgICAgICAgIHNjcm9sbGVyID0gd3JhcHBlci5sYXN0Q2hpbGQsIGNvZGUgPSBzY3JvbGxlci5maXJzdENoaWxkLAorICAgICAgICBtb3ZlciA9IGNvZGUuZmlyc3RDaGlsZCwgZ3V0dGVyID0gbW92ZXIuZmlyc3RDaGlsZCwgZ3V0dGVyVGV4dCA9IGd1dHRlci5maXJzdENoaWxkLAorICAgICAgICBsaW5lU3BhY2UgPSBndXR0ZXIubmV4dFNpYmxpbmcuZmlyc3RDaGlsZCwgbWVhc3VyZSA9IGxpbmVTcGFjZS5maXJzdENoaWxkLAorICAgICAgICBjdXJzb3IgPSBtZWFzdXJlLm5leHRTaWJsaW5nLCBzZWxlY3Rpb25EaXYgPSBjdXJzb3IubmV4dFNpYmxpbmcsCisgICAgICAgIGxpbmVEaXYgPSBzZWxlY3Rpb25EaXYubmV4dFNpYmxpbmc7CisgICAgdGhlbWVDaGFuZ2VkKCk7CisgICAgLy8gTmVlZGVkIHRvIGhpZGUgYmlnIGJsdWUgYmxpbmtpbmcgY3Vyc29yIG9uIE1vYmlsZSBTYWZhcmkKKyAgICBpZiAoaW9zKSBpbnB1dC5zdHlsZS53aWR0aCA9ICIwcHgiOworICAgIGlmICghd2Via2l0KSBsaW5lU3BhY2UuZHJhZ2dhYmxlID0gdHJ1ZTsKKyAgICBsaW5lU3BhY2Uuc3R5bGUub3V0bGluZSA9ICJub25lIjsKKyAgICBpZiAob3B0aW9ucy50YWJpbmRleCAhPSBudWxsKSBpbnB1dC50YWJJbmRleCA9IG9wdGlvbnMudGFiaW5kZXg7CisgICAgaWYgKG9wdGlvbnMuYXV0b2ZvY3VzKSBmb2N1c0lucHV0KCk7CisgICAgaWYgKCFvcHRpb25zLmd1dHRlciAmJiAhb3B0aW9ucy5saW5lTnVtYmVycykgZ3V0dGVyLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7CisgICAgLy8gTmVlZGVkIHRvIGhhbmRsZSBUYWIga2V5IGluIEtIVE1MCisgICAgaWYgKGtodG1sKSBpbnB1dERpdi5zdHlsZS5oZWlnaHQgPSAiMXB4IiwgaW5wdXREaXYuc3R5bGUucG9zaXRpb24gPSAiYWJzb2x1dGUiOworCisgICAgLy8gQ2hlY2sgZm9yIHByb2JsZW0gd2l0aCBJRSBpbm5lckhUTUwgbm90IHdvcmtpbmcgd2hlbiB3ZSBoYXZlIGEKKyAgICAvLyBQIChvciBzaW1pbGFyKSBwYXJlbnQgbm9kZS4KKyAgICB0cnkgeyBzdHJpbmdXaWR0aCgieCIpOyB9CisgICAgY2F0Y2ggKGUpIHsKKyAgICAgIGlmIChlLm1lc3NhZ2UubWF0Y2goL3J1bnRpbWUvaSkpCisgICAgICAgIGUgPSBuZXcgRXJyb3IoIkEgQ29kZU1pcnJvciBpbnNpZGUgYSBQLXN0eWxlIGVsZW1lbnQgZG9lcyBub3Qgd29yayBpbiBJbnRlcm5ldCBFeHBsb3Jlci4gKGlubmVySFRNTCBidWcpIik7CisgICAgICB0aHJvdyBlOworICAgIH0KKworICAgIC8vIERlbGF5ZWQgb2JqZWN0IHdyYXAgdGltZW91dHMsIG1ha2luZyBzdXJlIG9ubHkgb25lIGlzIGFjdGl2ZS4gYmxpbmtlciBob2xkcyBhbiBpbnRlcnZhbC4KKyAgICB2YXIgcG9sbCA9IG5ldyBEZWxheWVkKCksIGhpZ2hsaWdodCA9IG5ldyBEZWxheWVkKCksIGJsaW5rZXI7CisKKyAgICAvLyBtb2RlIGhvbGRzIGEgbW9kZSBBUEkgb2JqZWN0LiBkb2MgaXMgdGhlIHRyZWUgb2YgTGluZSBvYmplY3RzLAorICAgIC8vIHdvcmsgYW4gYXJyYXkgb2YgbGluZXMgdGhhdCBzaG91bGQgYmUgcGFyc2VkLCBhbmQgaGlzdG9yeSB0aGUKKyAgICAvLyB1bmRvIGhpc3RvcnkgKGluc3RhbmNlIG9mIEhpc3RvcnkgY29uc3RydWN0b3IpLgorICAgIHZhciBtb2RlLCBkb2MgPSBuZXcgQnJhbmNoQ2h1bmsoW25ldyBMZWFmQ2h1bmsoW25ldyBMaW5lKCIiKV0pXSksIHdvcmssIGZvY3VzZWQ7CisgICAgbG9hZE1vZGUoKTsKKyAgICAvLyBUaGUgc2VsZWN0aW9uLiBUaGVzZSBhcmUgYWx3YXlzIG1haW50YWluZWQgdG8gcG9pbnQgYXQgdmFsaWQKKyAgICAvLyBwb3NpdGlvbnMuIEludmVydGVkIGlzIHVzZWQgdG8gcmVtZW1iZXIgdGhhdCB0aGUgdXNlciBpcworICAgIC8vIHNlbGVjdGluZyBib3R0b20tdG8tdG9wLgorICAgIHZhciBzZWwgPSB7ZnJvbToge2xpbmU6IDAsIGNoOiAwfSwgdG86IHtsaW5lOiAwLCBjaDogMH0sIGludmVydGVkOiBmYWxzZX07CisgICAgLy8gU2VsZWN0aW9uLXJlbGF0ZWQgZmxhZ3MuIHNoaWZ0U2VsZWN0aW5nIG9idmlvdXNseSB0cmFja3MKKyAgICAvLyB3aGV0aGVyIHRoZSB1c2VyIGlzIGhvbGRpbmcgc2hpZnQuCisgICAgdmFyIHNoaWZ0U2VsZWN0aW5nLCBsYXN0Q2xpY2ssIGxhc3REb3VibGVDbGljaywgbGFzdFNjcm9sbFBvcyA9IDAsIGRyYWdnaW5nVGV4dCwKKyAgICAgICAgb3ZlcndyaXRlID0gZmFsc2UsIHN1cHByZXNzRWRpdHMgPSBmYWxzZTsKKyAgICAvLyBWYXJpYWJsZXMgdXNlZCBieSBzdGFydE9wZXJhdGlvbi9lbmRPcGVyYXRpb24gdG8gdHJhY2sgd2hhdAorICAgIC8vIGhhcHBlbmVkIGR1cmluZyB0aGUgb3BlcmF0aW9uLgorICAgIHZhciB1cGRhdGVJbnB1dCwgdXNlclNlbENoYW5nZSwgY2hhbmdlcywgdGV4dENoYW5nZWQsIHNlbGVjdGlvbkNoYW5nZWQsIGxlYXZlSW5wdXRBbG9uZSwKKyAgICAgICAgZ3V0dGVyRGlydHksIGNhbGxiYWNrczsKKyAgICAvLyBDdXJyZW50IHZpc2libGUgcmFuZ2UgKG1heSBiZSBiaWdnZXIgdGhhbiB0aGUgdmlldyB3aW5kb3cpLgorICAgIHZhciBkaXNwbGF5T2Zmc2V0ID0gMCwgc2hvd2luZ0Zyb20gPSAwLCBzaG93aW5nVG8gPSAwLCBsYXN0U2l6ZUMgPSAwOworICAgIC8vIGJyYWNrZXRIaWdobGlnaHRlZCBpcyB1c2VkIHRvIHJlbWVtYmVyIHRoYXQgYSBicmFja2V0IGhhcyBiZWVuCisgICAgLy8gbWFya2VkLgorICAgIHZhciBicmFja2V0SGlnaGxpZ2h0ZWQ7CisgICAgLy8gVHJhY2tzIHRoZSBtYXhpbXVtIGxpbmUgbGVuZ3RoIHNvIHRoYXQgdGhlIGhvcml6b250YWwgc2Nyb2xsYmFyCisgICAgLy8gY2FuIGJlIGtlcHQgc3RhdGljIHdoZW4gc2Nyb2xsaW5nLgorICAgIHZhciBtYXhMaW5lID0gIiIsIG1heFdpZHRoOworICAgIHZhciB0YWJDYWNoZSA9IHt9OworCisgICAgLy8gSW5pdGlhbGl6ZSB0aGUgY29udGVudC4KKyAgICBvcGVyYXRpb24oZnVuY3Rpb24oKXtzZXRWYWx1ZShvcHRpb25zLnZhbHVlIHx8ICIiKTsgdXBkYXRlSW5wdXQgPSBmYWxzZTt9KSgpOworICAgIHZhciBoaXN0b3J5ID0gbmV3IEhpc3RvcnkoKTsKKworICAgIC8vIFJlZ2lzdGVyIG91ciBldmVudCBoYW5kbGVycy4KKyAgICBjb25uZWN0KHNjcm9sbGVyLCAibW91c2Vkb3duIiwgb3BlcmF0aW9uKG9uTW91c2VEb3duKSk7CisgICAgY29ubmVjdChzY3JvbGxlciwgImRibGNsaWNrIiwgb3BlcmF0aW9uKG9uRG91YmxlQ2xpY2spKTsKKyAgICBjb25uZWN0KGxpbmVTcGFjZSwgInNlbGVjdHN0YXJ0IiwgZV9wcmV2ZW50RGVmYXVsdCk7CisgICAgLy8gR2Vja28gYnJvd3NlcnMgZmlyZSBjb250ZXh0bWVudSAqYWZ0ZXIqIG9wZW5pbmcgdGhlIG1lbnUsIGF0CisgICAgLy8gd2hpY2ggcG9pbnQgd2UgY2FuJ3QgbWVzcyB3aXRoIGl0IGFueW1vcmUuIENvbnRleHQgbWVudSBpcworICAgIC8vIGhhbmRsZWQgaW4gb25Nb3VzZURvd24gZm9yIEdlY2tvLgorICAgIGlmICghZ2Vja28pIGNvbm5lY3Qoc2Nyb2xsZXIsICJjb250ZXh0bWVudSIsIG9uQ29udGV4dE1lbnUpOworICAgIGNvbm5lY3Qoc2Nyb2xsZXIsICJzY3JvbGwiLCBmdW5jdGlvbigpIHsKKyAgICAgIGxhc3RTY3JvbGxQb3MgPSBzY3JvbGxlci5zY3JvbGxUb3A7CisgICAgICB1cGRhdGVEaXNwbGF5KFtdKTsKKyAgICAgIGlmIChvcHRpb25zLmZpeGVkR3V0dGVyKSBndXR0ZXIuc3R5bGUubGVmdCA9IHNjcm9sbGVyLnNjcm9sbExlZnQgKyAicHgiOworICAgICAgaWYgKG9wdGlvbnMub25TY3JvbGwpIG9wdGlvbnMub25TY3JvbGwoaW5zdGFuY2UpOworICAgIH0pOworICAgIGNvbm5lY3Qod2luZG93LCAicmVzaXplIiwgZnVuY3Rpb24oKSB7dXBkYXRlRGlzcGxheSh0cnVlKTt9KTsKKyAgICBjb25uZWN0KGlucHV0LCAia2V5dXAiLCBvcGVyYXRpb24ob25LZXlVcCkpOworICAgIGNvbm5lY3QoaW5wdXQsICJpbnB1dCIsIGZhc3RQb2xsKTsKKyAgICBjb25uZWN0KGlucHV0LCAia2V5ZG93biIsIG9wZXJhdGlvbihvbktleURvd24pKTsKKyAgICBjb25uZWN0KGlucHV0LCAia2V5cHJlc3MiLCBvcGVyYXRpb24ob25LZXlQcmVzcykpOworICAgIGNvbm5lY3QoaW5wdXQsICJmb2N1cyIsIG9uRm9jdXMpOworICAgIGNvbm5lY3QoaW5wdXQsICJibHVyIiwgb25CbHVyKTsKKworICAgIGlmIChvcHRpb25zLmRyYWdEcm9wKSB7CisgICAgICBjb25uZWN0KGxpbmVTcGFjZSwgImRyYWdzdGFydCIsIG9uRHJhZ1N0YXJ0KTsKKyAgICAgIGZ1bmN0aW9uIGRyYWdfKGUpIHsKKyAgICAgICAgaWYgKG9wdGlvbnMub25EcmFnRXZlbnQgJiYgb3B0aW9ucy5vbkRyYWdFdmVudChpbnN0YW5jZSwgYWRkU3RvcChlKSkpIHJldHVybjsKKyAgICAgICAgZV9zdG9wKGUpOworICAgICAgfQorICAgICAgY29ubmVjdChzY3JvbGxlciwgImRyYWdlbnRlciIsIGRyYWdfKTsKKyAgICAgIGNvbm5lY3Qoc2Nyb2xsZXIsICJkcmFnb3ZlciIsIGRyYWdfKTsKKyAgICAgIGNvbm5lY3Qoc2Nyb2xsZXIsICJkcm9wIiwgb3BlcmF0aW9uKG9uRHJvcCkpOworICAgIH0KKyAgICBjb25uZWN0KHNjcm9sbGVyLCAicGFzdGUiLCBmdW5jdGlvbigpe2ZvY3VzSW5wdXQoKTsgZmFzdFBvbGwoKTt9KTsKKyAgICBjb25uZWN0KGlucHV0LCAicGFzdGUiLCBmYXN0UG9sbCk7CisgICAgY29ubmVjdChpbnB1dCwgImN1dCIsIG9wZXJhdGlvbihmdW5jdGlvbigpeworICAgICAgaWYgKCFvcHRpb25zLnJlYWRPbmx5KSByZXBsYWNlU2VsZWN0aW9uKCIiKTsKKyAgICB9KSk7CisKKyAgICAvLyBOZWVkZWQgdG8gaGFuZGxlIFRhYiBrZXkgaW4gS0hUTUwKKyAgICBpZiAoa2h0bWwpIGNvbm5lY3QoY29kZSwgIm1vdXNldXAiLCBmdW5jdGlvbigpIHsKKyAgICAgICAgaWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT0gaW5wdXQpIGlucHV0LmJsdXIoKTsKKyAgICAgICAgZm9jdXNJbnB1dCgpOworICAgIH0pOworCisgICAgLy8gSUUgdGhyb3dzIHVuc3BlY2lmaWVkIGVycm9yIGluIGNlcnRhaW4gY2FzZXMsIHdoZW4KKyAgICAvLyB0cnlpbmcgdG8gYWNjZXNzIGFjdGl2ZUVsZW1lbnQgYmVmb3JlIG9ubG9hZAorICAgIHZhciBoYXNGb2N1czsgdHJ5IHsgaGFzRm9jdXMgPSAoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCA9PSBpbnB1dCk7IH0gY2F0Y2goZSkgeyB9CisgICAgaWYgKGhhc0ZvY3VzIHx8IG9wdGlvbnMuYXV0b2ZvY3VzKSBzZXRUaW1lb3V0KG9uRm9jdXMsIDIwKTsKKyAgICBlbHNlIG9uQmx1cigpOworCisgICAgZnVuY3Rpb24gaXNMaW5lKGwpIHtyZXR1cm4gbCA+PSAwICYmIGwgPCBkb2Muc2l6ZTt9CisgICAgLy8gVGhlIGluc3RhbmNlIG9iamVjdCB0aGF0IHdlJ2xsIHJldHVybi4gTW9zdGx5IGNhbGxzIG91dCB0bworICAgIC8vIGxvY2FsIGZ1bmN0aW9ucyBpbiB0aGUgQ29kZU1pcnJvciBmdW5jdGlvbi4gU29tZSBkbyBzb21lIGV4dHJhCisgICAgLy8gcmFuZ2UgY2hlY2tpbmcgYW5kL29yIGNsaXBwaW5nLiBvcGVyYXRpb24gaXMgdXNlZCB0byB3cmFwIHRoZQorICAgIC8vIGNhbGwgc28gdGhhdCBjaGFuZ2VzIGl0IG1ha2VzIGFyZSB0cmFja2VkLCBhbmQgdGhlIGRpc3BsYXkgaXMKKyAgICAvLyB1cGRhdGVkIGFmdGVyd2FyZHMuCisgICAgdmFyIGluc3RhbmNlID0gd3JhcHBlci5Db2RlTWlycm9yID0geworICAgICAgZ2V0VmFsdWU6IGdldFZhbHVlLAorICAgICAgc2V0VmFsdWU6IG9wZXJhdGlvbihzZXRWYWx1ZSksCisgICAgICBnZXRTZWxlY3Rpb246IGdldFNlbGVjdGlvbiwKKyAgICAgIHJlcGxhY2VTZWxlY3Rpb246IG9wZXJhdGlvbihyZXBsYWNlU2VsZWN0aW9uKSwKKyAgICAgIGZvY3VzOiBmdW5jdGlvbigpe3dpbmRvdy5mb2N1cygpOyBmb2N1c0lucHV0KCk7IG9uRm9jdXMoKTsgZmFzdFBvbGwoKTt9LAorICAgICAgc2V0T3B0aW9uOiBmdW5jdGlvbihvcHRpb24sIHZhbHVlKSB7CisgICAgICAgIHZhciBvbGRWYWwgPSBvcHRpb25zW29wdGlvbl07CisgICAgICAgIG9wdGlvbnNbb3B0aW9uXSA9IHZhbHVlOworICAgICAgICBpZiAob3B0aW9uID09ICJtb2RlIiB8fCBvcHRpb24gPT0gImluZGVudFVuaXQiKSBsb2FkTW9kZSgpOworICAgICAgICBlbHNlIGlmIChvcHRpb24gPT0gInJlYWRPbmx5IiAmJiB2YWx1ZSA9PSAibm9jdXJzb3IiKSB7b25CbHVyKCk7IGlucHV0LmJsdXIoKTt9CisgICAgICAgIGVsc2UgaWYgKG9wdGlvbiA9PSAicmVhZE9ubHkiICYmICF2YWx1ZSkge3Jlc2V0SW5wdXQodHJ1ZSk7fQorICAgICAgICBlbHNlIGlmIChvcHRpb24gPT0gInRoZW1lIikgdGhlbWVDaGFuZ2VkKCk7CisgICAgICAgIGVsc2UgaWYgKG9wdGlvbiA9PSAibGluZVdyYXBwaW5nIiAmJiBvbGRWYWwgIT0gdmFsdWUpIG9wZXJhdGlvbih3cmFwcGluZ0NoYW5nZWQpKCk7CisgICAgICAgIGVsc2UgaWYgKG9wdGlvbiA9PSAidGFiU2l6ZSIpIHVwZGF0ZURpc3BsYXkodHJ1ZSk7CisgICAgICAgIGlmIChvcHRpb24gPT0gImxpbmVOdW1iZXJzIiB8fCBvcHRpb24gPT0gImd1dHRlciIgfHwgb3B0aW9uID09ICJmaXJzdExpbmVOdW1iZXIiIHx8IG9wdGlvbiA9PSAidGhlbWUiKSB7CisgICAgICAgICAgZ3V0dGVyQ2hhbmdlZCgpOworICAgICAgICAgIHVwZGF0ZURpc3BsYXkodHJ1ZSk7CisgICAgICAgIH0KKyAgICAgIH0sCisgICAgICBnZXRPcHRpb246IGZ1bmN0aW9uKG9wdGlvbikge3JldHVybiBvcHRpb25zW29wdGlvbl07fSwKKyAgICAgIHVuZG86IG9wZXJhdGlvbih1bmRvKSwKKyAgICAgIHJlZG86IG9wZXJhdGlvbihyZWRvKSwKKyAgICAgIGluZGVudExpbmU6IG9wZXJhdGlvbihmdW5jdGlvbihuLCBkaXIpIHsKKyAgICAgICAgaWYgKHR5cGVvZiBkaXIgIT0gInN0cmluZyIpIHsKKyAgICAgICAgICBpZiAoZGlyID09IG51bGwpIGRpciA9IG9wdGlvbnMuc21hcnRJbmRlbnQgPyAic21hcnQiIDogInByZXYiOworICAgICAgICAgIGVsc2UgZGlyID0gZGlyID8gImFkZCIgOiAic3VidHJhY3QiOworICAgICAgICB9CisgICAgICAgIGlmIChpc0xpbmUobikpIGluZGVudExpbmUobiwgZGlyKTsKKyAgICAgIH0pLAorICAgICAgaW5kZW50U2VsZWN0aW9uOiBvcGVyYXRpb24oaW5kZW50U2VsZWN0ZWQpLAorICAgICAgaGlzdG9yeVNpemU6IGZ1bmN0aW9uKCkge3JldHVybiB7dW5kbzogaGlzdG9yeS5kb25lLmxlbmd0aCwgcmVkbzogaGlzdG9yeS51bmRvbmUubGVuZ3RofTt9LAorICAgICAgY2xlYXJIaXN0b3J5OiBmdW5jdGlvbigpIHtoaXN0b3J5ID0gbmV3IEhpc3RvcnkoKTt9LAorICAgICAgbWF0Y2hCcmFja2V0czogb3BlcmF0aW9uKGZ1bmN0aW9uKCl7bWF0Y2hCcmFja2V0cyh0cnVlKTt9KSwKKyAgICAgIGdldFRva2VuQXQ6IG9wZXJhdGlvbihmdW5jdGlvbihwb3MpIHsKKyAgICAgICAgcG9zID0gY2xpcFBvcyhwb3MpOworICAgICAgICByZXR1cm4gZ2V0TGluZShwb3MubGluZSkuZ2V0VG9rZW5BdChtb2RlLCBnZXRTdGF0ZUJlZm9yZShwb3MubGluZSksIHBvcy5jaCk7CisgICAgICB9KSwKKyAgICAgIGdldFN0YXRlQWZ0ZXI6IGZ1bmN0aW9uKGxpbmUpIHsKKyAgICAgICAgbGluZSA9IGNsaXBMaW5lKGxpbmUgPT0gbnVsbCA/IGRvYy5zaXplIC0gMTogbGluZSk7CisgICAgICAgIHJldHVybiBnZXRTdGF0ZUJlZm9yZShsaW5lICsgMSk7CisgICAgICB9LAorICAgICAgY3Vyc29yQ29vcmRzOiBmdW5jdGlvbihzdGFydCwgbW9kZSkgeworICAgICAgICBpZiAoc3RhcnQgPT0gbnVsbCkgc3RhcnQgPSBzZWwuaW52ZXJ0ZWQ7CisgICAgICAgIHJldHVybiB0aGlzLmNoYXJDb29yZHMoc3RhcnQgPyBzZWwuZnJvbSA6IHNlbC50bywgbW9kZSk7CisgICAgICB9LAorICAgICAgY2hhckNvb3JkczogZnVuY3Rpb24ocG9zLCBtb2RlKSB7CisgICAgICAgIHBvcyA9IGNsaXBQb3MocG9zKTsKKyAgICAgICAgaWYgKG1vZGUgPT0gImxvY2FsIikgcmV0dXJuIGxvY2FsQ29vcmRzKHBvcywgZmFsc2UpOworICAgICAgICBpZiAobW9kZSA9PSAiZGl2IikgcmV0dXJuIGxvY2FsQ29vcmRzKHBvcywgdHJ1ZSk7CisgICAgICAgIHJldHVybiBwYWdlQ29vcmRzKHBvcyk7CisgICAgICB9LAorICAgICAgY29vcmRzQ2hhcjogZnVuY3Rpb24oY29vcmRzKSB7CisgICAgICAgIHZhciBvZmYgPSBlbHRPZmZzZXQobGluZVNwYWNlKTsKKyAgICAgICAgcmV0dXJuIGNvb3Jkc0NoYXIoY29vcmRzLnggLSBvZmYubGVmdCwgY29vcmRzLnkgLSBvZmYudG9wKTsKKyAgICAgIH0sCisgICAgICBtYXJrVGV4dDogb3BlcmF0aW9uKG1hcmtUZXh0KSwKKyAgICAgIHNldEJvb2ttYXJrOiBzZXRCb29rbWFyaywKKyAgICAgIGZpbmRNYXJrc0F0OiBmaW5kTWFya3NBdCwKKyAgICAgIHNldE1hcmtlcjogb3BlcmF0aW9uKGFkZEd1dHRlck1hcmtlciksCisgICAgICBjbGVhck1hcmtlcjogb3BlcmF0aW9uKHJlbW92ZUd1dHRlck1hcmtlciksCisgICAgICBzZXRMaW5lQ2xhc3M6IG9wZXJhdGlvbihzZXRMaW5lQ2xhc3MpLAorICAgICAgaGlkZUxpbmU6IG9wZXJhdGlvbihmdW5jdGlvbihoKSB7cmV0dXJuIHNldExpbmVIaWRkZW4oaCwgdHJ1ZSk7fSksCisgICAgICBzaG93TGluZTogb3BlcmF0aW9uKGZ1bmN0aW9uKGgpIHtyZXR1cm4gc2V0TGluZUhpZGRlbihoLCBmYWxzZSk7fSksCisgICAgICBvbkRlbGV0ZUxpbmU6IGZ1bmN0aW9uKGxpbmUsIGYpIHsKKyAgICAgICAgaWYgKHR5cGVvZiBsaW5lID09ICJudW1iZXIiKSB7CisgICAgICAgICAgaWYgKCFpc0xpbmUobGluZSkpIHJldHVybiBudWxsOworICAgICAgICAgIGxpbmUgPSBnZXRMaW5lKGxpbmUpOworICAgICAgICB9CisgICAgICAgIChsaW5lLmhhbmRsZXJzIHx8IChsaW5lLmhhbmRsZXJzID0gW10pKS5wdXNoKGYpOworICAgICAgICByZXR1cm4gbGluZTsKKyAgICAgIH0sCisgICAgICBsaW5lSW5mbzogbGluZUluZm8sCisgICAgICBhZGRXaWRnZXQ6IGZ1bmN0aW9uKHBvcywgbm9kZSwgc2Nyb2xsLCB2ZXJ0LCBob3JpeikgeworICAgICAgICBwb3MgPSBsb2NhbENvb3JkcyhjbGlwUG9zKHBvcykpOworICAgICAgICB2YXIgdG9wID0gcG9zLnlCb3QsIGxlZnQgPSBwb3MueDsKKyAgICAgICAgbm9kZS5zdHlsZS5wb3NpdGlvbiA9ICJhYnNvbHV0ZSI7CisgICAgICAgIGNvZGUuYXBwZW5kQ2hpbGQobm9kZSk7CisgICAgICAgIGlmICh2ZXJ0ID09ICJvdmVyIikgdG9wID0gcG9zLnk7CisgICAgICAgIGVsc2UgaWYgKHZlcnQgPT0gIm5lYXIiKSB7CisgICAgICAgICAgdmFyIHZzcGFjZSA9IE1hdGgubWF4KHNjcm9sbGVyLm9mZnNldEhlaWdodCwgZG9jLmhlaWdodCAqIHRleHRIZWlnaHQoKSksCisgICAgICAgICAgICAgIGhzcGFjZSA9IE1hdGgubWF4KGNvZGUuY2xpZW50V2lkdGgsIGxpbmVTcGFjZS5jbGllbnRXaWR0aCkgLSBwYWRkaW5nTGVmdCgpOworICAgICAgICAgIGlmIChwb3MueUJvdCArIG5vZGUub2Zmc2V0SGVpZ2h0ID4gdnNwYWNlICYmIHBvcy55ID4gbm9kZS5vZmZzZXRIZWlnaHQpCisgICAgICAgICAgICB0b3AgPSBwb3MueSAtIG5vZGUub2Zmc2V0SGVpZ2h0OworICAgICAgICAgIGlmIChsZWZ0ICsgbm9kZS5vZmZzZXRXaWR0aCA+IGhzcGFjZSkKKyAgICAgICAgICAgIGxlZnQgPSBoc3BhY2UgLSBub2RlLm9mZnNldFdpZHRoOworICAgICAgICB9CisgICAgICAgIG5vZGUuc3R5bGUudG9wID0gKHRvcCArIHBhZGRpbmdUb3AoKSkgKyAicHgiOworICAgICAgICBub2RlLnN0eWxlLmxlZnQgPSBub2RlLnN0eWxlLnJpZ2h0ID0gIiI7CisgICAgICAgIGlmIChob3JpeiA9PSAicmlnaHQiKSB7CisgICAgICAgICAgbGVmdCA9IGNvZGUuY2xpZW50V2lkdGggLSBub2RlLm9mZnNldFdpZHRoOworICAgICAgICAgIG5vZGUuc3R5bGUucmlnaHQgPSAiMHB4IjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBpZiAoaG9yaXogPT0gImxlZnQiKSBsZWZ0ID0gMDsKKyAgICAgICAgICBlbHNlIGlmIChob3JpeiA9PSAibWlkZGxlIikgbGVmdCA9IChjb2RlLmNsaWVudFdpZHRoIC0gbm9kZS5vZmZzZXRXaWR0aCkgLyAyOworICAgICAgICAgIG5vZGUuc3R5bGUubGVmdCA9IChsZWZ0ICsgcGFkZGluZ0xlZnQoKSkgKyAicHgiOworICAgICAgICB9CisgICAgICAgIGlmIChzY3JvbGwpCisgICAgICAgICAgc2Nyb2xsSW50b1ZpZXcobGVmdCwgdG9wLCBsZWZ0ICsgbm9kZS5vZmZzZXRXaWR0aCwgdG9wICsgbm9kZS5vZmZzZXRIZWlnaHQpOworICAgICAgfSwKKworICAgICAgbGluZUNvdW50OiBmdW5jdGlvbigpIHtyZXR1cm4gZG9jLnNpemU7fSwKKyAgICAgIGNsaXBQb3M6IGNsaXBQb3MsCisgICAgICBnZXRDdXJzb3I6IGZ1bmN0aW9uKHN0YXJ0KSB7CisgICAgICAgIGlmIChzdGFydCA9PSBudWxsKSBzdGFydCA9IHNlbC5pbnZlcnRlZDsKKyAgICAgICAgcmV0dXJuIGNvcHlQb3Moc3RhcnQgPyBzZWwuZnJvbSA6IHNlbC50byk7CisgICAgICB9LAorICAgICAgc29tZXRoaW5nU2VsZWN0ZWQ6IGZ1bmN0aW9uKCkge3JldHVybiAhcG9zRXEoc2VsLmZyb20sIHNlbC50byk7fSwKKyAgICAgIHNldEN1cnNvcjogb3BlcmF0aW9uKGZ1bmN0aW9uKGxpbmUsIGNoLCB1c2VyKSB7CisgICAgICAgIGlmIChjaCA9PSBudWxsICYmIHR5cGVvZiBsaW5lLmxpbmUgPT0gIm51bWJlciIpIHNldEN1cnNvcihsaW5lLmxpbmUsIGxpbmUuY2gsIHVzZXIpOworICAgICAgICBlbHNlIHNldEN1cnNvcihsaW5lLCBjaCwgdXNlcik7CisgICAgICB9KSwKKyAgICAgIHNldFNlbGVjdGlvbjogb3BlcmF0aW9uKGZ1bmN0aW9uKGZyb20sIHRvLCB1c2VyKSB7CisgICAgICAgICh1c2VyID8gc2V0U2VsZWN0aW9uVXNlciA6IHNldFNlbGVjdGlvbikoY2xpcFBvcyhmcm9tKSwgY2xpcFBvcyh0byB8fCBmcm9tKSk7CisgICAgICB9KSwKKyAgICAgIGdldExpbmU6IGZ1bmN0aW9uKGxpbmUpIHtpZiAoaXNMaW5lKGxpbmUpKSByZXR1cm4gZ2V0TGluZShsaW5lKS50ZXh0O30sCisgICAgICBnZXRMaW5lSGFuZGxlOiBmdW5jdGlvbihsaW5lKSB7aWYgKGlzTGluZShsaW5lKSkgcmV0dXJuIGdldExpbmUobGluZSk7fSwKKyAgICAgIHNldExpbmU6IG9wZXJhdGlvbihmdW5jdGlvbihsaW5lLCB0ZXh0KSB7CisgICAgICAgIGlmIChpc0xpbmUobGluZSkpIHJlcGxhY2VSYW5nZSh0ZXh0LCB7bGluZTogbGluZSwgY2g6IDB9LCB7bGluZTogbGluZSwgY2g6IGdldExpbmUobGluZSkudGV4dC5sZW5ndGh9KTsKKyAgICAgIH0pLAorICAgICAgcmVtb3ZlTGluZTogb3BlcmF0aW9uKGZ1bmN0aW9uKGxpbmUpIHsKKyAgICAgICAgaWYgKGlzTGluZShsaW5lKSkgcmVwbGFjZVJhbmdlKCIiLCB7bGluZTogbGluZSwgY2g6IDB9LCBjbGlwUG9zKHtsaW5lOiBsaW5lKzEsIGNoOiAwfSkpOworICAgICAgfSksCisgICAgICByZXBsYWNlUmFuZ2U6IG9wZXJhdGlvbihyZXBsYWNlUmFuZ2UpLAorICAgICAgZ2V0UmFuZ2U6IGZ1bmN0aW9uKGZyb20sIHRvKSB7cmV0dXJuIGdldFJhbmdlKGNsaXBQb3MoZnJvbSksIGNsaXBQb3ModG8pKTt9LAorCisgICAgICB0cmlnZ2VyT25LZXlEb3duOiBvcGVyYXRpb24ob25LZXlEb3duKSwKKyAgICAgIGV4ZWNDb21tYW5kOiBmdW5jdGlvbihjbWQpIHtyZXR1cm4gY29tbWFuZHNbY21kXShpbnN0YW5jZSk7fSwKKyAgICAgIC8vIFN0dWZmIHVzZWQgYnkgY29tbWFuZHMsIHByb2JhYmx5IG5vdCBtdWNoIHVzZSB0byBvdXRzaWRlIGNvZGUuCisgICAgICBtb3ZlSDogb3BlcmF0aW9uKG1vdmVIKSwKKyAgICAgIGRlbGV0ZUg6IG9wZXJhdGlvbihkZWxldGVIKSwKKyAgICAgIG1vdmVWOiBvcGVyYXRpb24obW92ZVYpLAorICAgICAgdG9nZ2xlT3ZlcndyaXRlOiBmdW5jdGlvbigpIHsKKyAgICAgICAgaWYob3ZlcndyaXRlKXsKKyAgICAgICAgICBvdmVyd3JpdGUgPSBmYWxzZTsKKyAgICAgICAgICBjdXJzb3IuY2xhc3NOYW1lID0gY3Vyc29yLmNsYXNzTmFtZS5yZXBsYWNlKCIgQ29kZU1pcnJvci1vdmVyd3JpdGUiLCAiIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgb3ZlcndyaXRlID0gdHJ1ZTsKKyAgICAgICAgICBjdXJzb3IuY2xhc3NOYW1lICs9ICIgQ29kZU1pcnJvci1vdmVyd3JpdGUiOworICAgICAgICB9CisgICAgICB9LAorCisgICAgICBwb3NGcm9tSW5kZXg6IGZ1bmN0aW9uKG9mZikgeworICAgICAgICB2YXIgbGluZU5vID0gMCwgY2g7CisgICAgICAgIGRvYy5pdGVyKDAsIGRvYy5zaXplLCBmdW5jdGlvbihsaW5lKSB7CisgICAgICAgICAgdmFyIHN6ID0gbGluZS50ZXh0Lmxlbmd0aCArIDE7CisgICAgICAgICAgaWYgKHN6ID4gb2ZmKSB7IGNoID0gb2ZmOyByZXR1cm4gdHJ1ZTsgfQorICAgICAgICAgIG9mZiAtPSBzejsKKyAgICAgICAgICArK2xpbmVObzsKKyAgICAgICAgfSk7CisgICAgICAgIHJldHVybiBjbGlwUG9zKHtsaW5lOiBsaW5lTm8sIGNoOiBjaH0pOworICAgICAgfSwKKyAgICAgIGluZGV4RnJvbVBvczogZnVuY3Rpb24gKGNvb3JkcykgeworICAgICAgICBpZiAoY29vcmRzLmxpbmUgPCAwIHx8IGNvb3Jkcy5jaCA8IDApIHJldHVybiAwOworICAgICAgICB2YXIgaW5kZXggPSBjb29yZHMuY2g7CisgICAgICAgIGRvYy5pdGVyKDAsIGNvb3Jkcy5saW5lLCBmdW5jdGlvbiAobGluZSkgeworICAgICAgICAgIGluZGV4ICs9IGxpbmUudGV4dC5sZW5ndGggKyAxOworICAgICAgICB9KTsKKyAgICAgICAgcmV0dXJuIGluZGV4OworICAgICAgfSwKKyAgICAgIHNjcm9sbFRvOiBmdW5jdGlvbih4LCB5KSB7CisgICAgICAgIGlmICh4ICE9IG51bGwpIHNjcm9sbGVyLnNjcm9sbExlZnQgPSB4OworICAgICAgICBpZiAoeSAhPSBudWxsKSBzY3JvbGxlci5zY3JvbGxUb3AgPSB5OworICAgICAgICB1cGRhdGVEaXNwbGF5KFtdKTsKKyAgICAgIH0sCisKKyAgICAgIG9wZXJhdGlvbjogZnVuY3Rpb24oZil7cmV0dXJuIG9wZXJhdGlvbihmKSgpO30sCisgICAgICBjb21wb3VuZENoYW5nZTogZnVuY3Rpb24oZil7cmV0dXJuIGNvbXBvdW5kQ2hhbmdlKGYpO30sCisgICAgICByZWZyZXNoOiBmdW5jdGlvbigpeworICAgICAgICB1cGRhdGVEaXNwbGF5KHRydWUpOworICAgICAgICBpZiAoc2Nyb2xsZXIuc2Nyb2xsSGVpZ2h0ID4gbGFzdFNjcm9sbFBvcykKKyAgICAgICAgICBzY3JvbGxlci5zY3JvbGxUb3AgPSBsYXN0U2Nyb2xsUG9zOworICAgICAgfSwKKyAgICAgIGdldElucHV0RmllbGQ6IGZ1bmN0aW9uKCl7cmV0dXJuIGlucHV0O30sCisgICAgICBnZXRXcmFwcGVyRWxlbWVudDogZnVuY3Rpb24oKXtyZXR1cm4gd3JhcHBlcjt9LAorICAgICAgZ2V0U2Nyb2xsZXJFbGVtZW50OiBmdW5jdGlvbigpe3JldHVybiBzY3JvbGxlcjt9LAorICAgICAgZ2V0R3V0dGVyRWxlbWVudDogZnVuY3Rpb24oKXtyZXR1cm4gZ3V0dGVyO30KKyAgICB9OworCisgICAgZnVuY3Rpb24gZ2V0TGluZShuKSB7IHJldHVybiBnZXRMaW5lQXQoZG9jLCBuKTsgfQorICAgIGZ1bmN0aW9uIHVwZGF0ZUxpbmVIZWlnaHQobGluZSwgaGVpZ2h0KSB7CisgICAgICBndXR0ZXJEaXJ0eSA9IHRydWU7CisgICAgICB2YXIgZGlmZiA9IGhlaWdodCAtIGxpbmUuaGVpZ2h0OworICAgICAgZm9yICh2YXIgbiA9IGxpbmU7IG47IG4gPSBuLnBhcmVudCkgbi5oZWlnaHQgKz0gZGlmZjsKKyAgICB9CisKKyAgICBmdW5jdGlvbiBzZXRWYWx1ZShjb2RlKSB7CisgICAgICB2YXIgdG9wID0ge2xpbmU6IDAsIGNoOiAwfTsKKyAgICAgIHVwZGF0ZUxpbmVzKHRvcCwge2xpbmU6IGRvYy5zaXplIC0gMSwgY2g6IGdldExpbmUoZG9jLnNpemUtMSkudGV4dC5sZW5ndGh9LAorICAgICAgICAgICAgICAgICAgc3BsaXRMaW5lcyhjb2RlKSwgdG9wLCB0b3ApOworICAgICAgdXBkYXRlSW5wdXQgPSB0cnVlOworICAgIH0KKyAgICBmdW5jdGlvbiBnZXRWYWx1ZSgpIHsKKyAgICAgIHZhciB0ZXh0ID0gW107CisgICAgICBkb2MuaXRlcigwLCBkb2Muc2l6ZSwgZnVuY3Rpb24obGluZSkgeyB0ZXh0LnB1c2gobGluZS50ZXh0KTsgfSk7CisgICAgICByZXR1cm4gdGV4dC5qb2luKCJcbiIpOworICAgIH0KKworICAgIGZ1bmN0aW9uIG9uTW91c2VEb3duKGUpIHsKKyAgICAgIHNldFNoaWZ0KGVfcHJvcChlLCAic2hpZnRLZXkiKSk7CisgICAgICAvLyBDaGVjayB3aGV0aGVyIHRoaXMgaXMgYSBjbGljayBpbiBhIHdpZGdldAorICAgICAgZm9yICh2YXIgbiA9IGVfdGFyZ2V0KGUpOyBuICE9IHdyYXBwZXI7IG4gPSBuLnBhcmVudE5vZGUpCisgICAgICAgIGlmIChuLnBhcmVudE5vZGUgPT0gY29kZSAmJiBuICE9IG1vdmVyKSByZXR1cm47CisKKyAgICAgIC8vIFNlZSBpZiB0aGlzIGlzIGEgY2xpY2sgaW4gdGhlIGd1dHRlcgorICAgICAgZm9yICh2YXIgbiA9IGVfdGFyZ2V0KGUpOyBuICE9IHdyYXBwZXI7IG4gPSBuLnBhcmVudE5vZGUpCisgICAgICAgIGlmIChuLnBhcmVudE5vZGUgPT0gZ3V0dGVyVGV4dCkgeworICAgICAgICAgIGlmIChvcHRpb25zLm9uR3V0dGVyQ2xpY2spCisgICAgICAgICAgICBvcHRpb25zLm9uR3V0dGVyQ2xpY2soaW5zdGFuY2UsIGluZGV4T2YoZ3V0dGVyVGV4dC5jaGlsZE5vZGVzLCBuKSArIHNob3dpbmdGcm9tLCBlKTsKKyAgICAgICAgICByZXR1cm4gZV9wcmV2ZW50RGVmYXVsdChlKTsKKyAgICAgICAgfQorCisgICAgICB2YXIgc3RhcnQgPSBwb3NGcm9tTW91c2UoZSk7CisKKyAgICAgIHN3aXRjaCAoZV9idXR0b24oZSkpIHsKKyAgICAgIGNhc2UgMzoKKyAgICAgICAgaWYgKGdlY2tvICYmICFtYWMpIG9uQ29udGV4dE1lbnUoZSk7CisgICAgICAgIHJldHVybjsKKyAgICAgIGNhc2UgMjoKKyAgICAgICAgaWYgKHN0YXJ0KSBzZXRDdXJzb3Ioc3RhcnQubGluZSwgc3RhcnQuY2gsIHRydWUpOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICAvLyBGb3IgYnV0dG9uIDEsIGlmIGl0IHdhcyBjbGlja2VkIGluc2lkZSB0aGUgZWRpdG9yCisgICAgICAvLyAocG9zRnJvbU1vdXNlIHJldHVybmluZyBub24tbnVsbCksIHdlIGhhdmUgdG8gYWRqdXN0IHRoZQorICAgICAgLy8gc2VsZWN0aW9uLgorICAgICAgaWYgKCFzdGFydCkge2lmIChlX3RhcmdldChlKSA9PSBzY3JvbGxlcikgZV9wcmV2ZW50RGVmYXVsdChlKTsgcmV0dXJuO30KKworICAgICAgaWYgKCFmb2N1c2VkKSBvbkZvY3VzKCk7CisKKyAgICAgIHZhciBub3cgPSArbmV3IERhdGU7CisgICAgICBpZiAobGFzdERvdWJsZUNsaWNrICYmIGxhc3REb3VibGVDbGljay50aW1lID4gbm93IC0gNDAwICYmIHBvc0VxKGxhc3REb3VibGVDbGljay5wb3MsIHN0YXJ0KSkgeworICAgICAgICBlX3ByZXZlbnREZWZhdWx0KGUpOworICAgICAgICBzZXRUaW1lb3V0KGZvY3VzSW5wdXQsIDIwKTsKKyAgICAgICAgcmV0dXJuIHNlbGVjdExpbmUoc3RhcnQubGluZSk7CisgICAgICB9IGVsc2UgaWYgKGxhc3RDbGljayAmJiBsYXN0Q2xpY2sudGltZSA+IG5vdyAtIDQwMCAmJiBwb3NFcShsYXN0Q2xpY2sucG9zLCBzdGFydCkpIHsKKyAgICAgICAgbGFzdERvdWJsZUNsaWNrID0ge3RpbWU6IG5vdywgcG9zOiBzdGFydH07CisgICAgICAgIGVfcHJldmVudERlZmF1bHQoZSk7CisgICAgICAgIHJldHVybiBzZWxlY3RXb3JkQXQoc3RhcnQpOworICAgICAgfSBlbHNlIHsgbGFzdENsaWNrID0ge3RpbWU6IG5vdywgcG9zOiBzdGFydH07IH0KKworICAgICAgdmFyIGxhc3QgPSBzdGFydCwgZ29pbmc7CisgICAgICBpZiAob3B0aW9ucy5kcmFnRHJvcCAmJiBkcmFnQW5kRHJvcCAmJiAhb3B0aW9ucy5yZWFkT25seSAmJiAhcG9zRXEoc2VsLmZyb20sIHNlbC50bykgJiYKKyAgICAgICAgICAhcG9zTGVzcyhzdGFydCwgc2VsLmZyb20pICYmICFwb3NMZXNzKHNlbC50bywgc3RhcnQpKSB7CisgICAgICAgIC8vIExldCB0aGUgZHJhZyBoYW5kbGVyIGhhbmRsZSB0aGlzLgorICAgICAgICBpZiAod2Via2l0KSBsaW5lU3BhY2UuZHJhZ2dhYmxlID0gdHJ1ZTsKKyAgICAgICAgZnVuY3Rpb24gZHJhZ0VuZChlMikgeworICAgICAgICAgIGlmICh3ZWJraXQpIGxpbmVTcGFjZS5kcmFnZ2FibGUgPSBmYWxzZTsKKyAgICAgICAgICBkcmFnZ2luZ1RleHQgPSBmYWxzZTsKKyAgICAgICAgICB1cCgpOyBkcm9wKCk7CisgICAgICAgICAgaWYgKE1hdGguYWJzKGUuY2xpZW50WCAtIGUyLmNsaWVudFgpICsgTWF0aC5hYnMoZS5jbGllbnRZIC0gZTIuY2xpZW50WSkgPCAxMCkgeworICAgICAgICAgICAgZV9wcmV2ZW50RGVmYXVsdChlMik7CisgICAgICAgICAgICBzZXRDdXJzb3Ioc3RhcnQubGluZSwgc3RhcnQuY2gsIHRydWUpOworICAgICAgICAgICAgZm9jdXNJbnB1dCgpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB2YXIgdXAgPSBjb25uZWN0KGRvY3VtZW50LCAibW91c2V1cCIsIG9wZXJhdGlvbihkcmFnRW5kKSwgdHJ1ZSk7CisgICAgICAgIHZhciBkcm9wID0gY29ubmVjdChzY3JvbGxlciwgImRyb3AiLCBvcGVyYXRpb24oZHJhZ0VuZCksIHRydWUpOworICAgICAgICBkcmFnZ2luZ1RleHQgPSB0cnVlOworICAgICAgICAvLyBJRSdzIGFwcHJvYWNoIHRvIGRyYWdnYWJsZQorICAgICAgICBpZiAobGluZVNwYWNlLmRyYWdEcm9wKSBsaW5lU3BhY2UuZHJhZ0Ryb3AoKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgZV9wcmV2ZW50RGVmYXVsdChlKTsKKyAgICAgIHNldEN1cnNvcihzdGFydC5saW5lLCBzdGFydC5jaCwgdHJ1ZSk7CisKKyAgICAgIGZ1bmN0aW9uIGV4dGVuZChlKSB7CisgICAgICAgIHZhciBjdXIgPSBwb3NGcm9tTW91c2UoZSwgdHJ1ZSk7CisgICAgICAgIGlmIChjdXIgJiYgIXBvc0VxKGN1ciwgbGFzdCkpIHsKKyAgICAgICAgICBpZiAoIWZvY3VzZWQpIG9uRm9jdXMoKTsKKyAgICAgICAgICBsYXN0ID0gY3VyOworICAgICAgICAgIHNldFNlbGVjdGlvblVzZXIoc3RhcnQsIGN1cik7CisgICAgICAgICAgdXBkYXRlSW5wdXQgPSBmYWxzZTsKKyAgICAgICAgICB2YXIgdmlzaWJsZSA9IHZpc2libGVMaW5lcygpOworICAgICAgICAgIGlmIChjdXIubGluZSA+PSB2aXNpYmxlLnRvIHx8IGN1ci5saW5lIDwgdmlzaWJsZS5mcm9tKQorICAgICAgICAgICAgZ29pbmcgPSBzZXRUaW1lb3V0KG9wZXJhdGlvbihmdW5jdGlvbigpe2V4dGVuZChlKTt9KSwgMTUwKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBmdW5jdGlvbiBkb25lKGUpIHsKKyAgICAgICAgY2xlYXJUaW1lb3V0KGdvaW5nKTsKKyAgICAgICAgdmFyIGN1ciA9IHBvc0Zyb21Nb3VzZShlKTsKKyAgICAgICAgaWYgKGN1cikgc2V0U2VsZWN0aW9uVXNlcihzdGFydCwgY3VyKTsKKyAgICAgICAgZV9wcmV2ZW50RGVmYXVsdChlKTsKKyAgICAgICAgZm9jdXNJbnB1dCgpOworICAgICAgICB1cGRhdGVJbnB1dCA9IHRydWU7CisgICAgICAgIG1vdmUoKTsgdXAoKTsKKyAgICAgIH0KKyAgICAgIHZhciBtb3ZlID0gY29ubmVjdChkb2N1bWVudCwgIm1vdXNlbW92ZSIsIG9wZXJhdGlvbihmdW5jdGlvbihlKSB7CisgICAgICAgIGNsZWFyVGltZW91dChnb2luZyk7CisgICAgICAgIGVfcHJldmVudERlZmF1bHQoZSk7CisgICAgICAgIGlmICghaWUgJiYgIWVfYnV0dG9uKGUpKSBkb25lKGUpOworICAgICAgICBlbHNlIGV4dGVuZChlKTsKKyAgICAgIH0pLCB0cnVlKTsKKyAgICAgIHZhciB1cCA9IGNvbm5lY3QoZG9jdW1lbnQsICJtb3VzZXVwIiwgb3BlcmF0aW9uKGRvbmUpLCB0cnVlKTsKKyAgICB9CisgICAgZnVuY3Rpb24gb25Eb3VibGVDbGljayhlKSB7CisgICAgICBmb3IgKHZhciBuID0gZV90YXJnZXQoZSk7IG4gIT0gd3JhcHBlcjsgbiA9IG4ucGFyZW50Tm9kZSkKKyAgICAgICAgaWYgKG4ucGFyZW50Tm9kZSA9PSBndXR0ZXJUZXh0KSByZXR1cm4gZV9wcmV2ZW50RGVmYXVsdChlKTsKKyAgICAgIHZhciBzdGFydCA9IHBvc0Zyb21Nb3VzZShlKTsKKyAgICAgIGlmICghc3RhcnQpIHJldHVybjsKKyAgICAgIGxhc3REb3VibGVDbGljayA9IHt0aW1lOiArbmV3IERhdGUsIHBvczogc3RhcnR9OworICAgICAgZV9wcmV2ZW50RGVmYXVsdChlKTsKKyAgICAgIHNlbGVjdFdvcmRBdChzdGFydCk7CisgICAgfQorICAgIGZ1bmN0aW9uIG9uRHJvcChlKSB7CisgICAgICBpZiAob3B0aW9ucy5vbkRyYWdFdmVudCAmJiBvcHRpb25zLm9uRHJhZ0V2ZW50KGluc3RhbmNlLCBhZGRTdG9wKGUpKSkgcmV0dXJuOworICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOworICAgICAgdmFyIHBvcyA9IHBvc0Zyb21Nb3VzZShlLCB0cnVlKSwgZmlsZXMgPSBlLmRhdGFUcmFuc2Zlci5maWxlczsKKyAgICAgIGlmICghcG9zIHx8IG9wdGlvbnMucmVhZE9ubHkpIHJldHVybjsKKyAgICAgIGlmIChmaWxlcyAmJiBmaWxlcy5sZW5ndGggJiYgd2luZG93LkZpbGVSZWFkZXIgJiYgd2luZG93LkZpbGUpIHsKKyAgICAgICAgZnVuY3Rpb24gbG9hZEZpbGUoZmlsZSwgaSkgeworICAgICAgICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcjsKKyAgICAgICAgICByZWFkZXIub25sb2FkID0gZnVuY3Rpb24oKSB7CisgICAgICAgICAgICB0ZXh0W2ldID0gcmVhZGVyLnJlc3VsdDsKKyAgICAgICAgICAgIGlmICgrK3JlYWQgPT0gbikgeworICAgICAgICAgICAgICBwb3MgPSBjbGlwUG9zKHBvcyk7CisgICAgICAgICAgICAgIG9wZXJhdGlvbihmdW5jdGlvbigpIHsKKyAgICAgICAgICAgICAgICB2YXIgZW5kID0gcmVwbGFjZVJhbmdlKHRleHQuam9pbigiIiksIHBvcywgcG9zKTsKKyAgICAgICAgICAgICAgICBzZXRTZWxlY3Rpb25Vc2VyKHBvcywgZW5kKTsKKyAgICAgICAgICAgICAgfSkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9OworICAgICAgICAgIHJlYWRlci5yZWFkQXNUZXh0KGZpbGUpOworICAgICAgICB9CisgICAgICAgIHZhciBuID0gZmlsZXMubGVuZ3RoLCB0ZXh0ID0gQXJyYXkobiksIHJlYWQgPSAwOworICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSkgbG9hZEZpbGUoZmlsZXNbaV0sIGkpOworICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgdmFyIHRleHQgPSBlLmRhdGFUcmFuc2Zlci5nZXREYXRhKCJUZXh0Iik7CisgICAgICAgICAgaWYgKHRleHQpIHsKKyAgICAgICAgICAgIGNvbXBvdW5kQ2hhbmdlKGZ1bmN0aW9uKCkgeworICAgICAgICAgICAgICB2YXIgY3VyRnJvbSA9IHNlbC5mcm9tLCBjdXJUbyA9IHNlbC50bzsKKyAgICAgICAgICAgICAgc2V0U2VsZWN0aW9uVXNlcihwb3MsIHBvcyk7CisgICAgICAgICAgICAgIGlmIChkcmFnZ2luZ1RleHQpIHJlcGxhY2VSYW5nZSgiIiwgY3VyRnJvbSwgY3VyVG8pOworICAgICAgICAgICAgICByZXBsYWNlU2VsZWN0aW9uKHRleHQpOworICAgICAgICAgICAgICBmb2N1c0lucHV0KCk7CisgICAgICAgICAgICB9KTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY2F0Y2goZSl7fQorICAgICAgfQorICAgIH0KKyAgICBmdW5jdGlvbiBvbkRyYWdTdGFydChlKSB7CisgICAgICB2YXIgdHh0ID0gZ2V0U2VsZWN0aW9uKCk7CisgICAgICBlLmRhdGFUcmFuc2Zlci5zZXREYXRhKCJUZXh0IiwgdHh0KTsKKyAgICAgIAorICAgICAgLy8gVXNlIGR1bW15IGltYWdlIGluc3RlYWQgb2YgZGVmYXVsdCBicm93c2VycyBpbWFnZS4KKyAgICAgIGlmIChnZWNrbyB8fCBjaHJvbWUpIHsKKyAgICAgICAgdmFyIGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpOworICAgICAgICBpbWcuc2NyID0gJ2RhdGE6aW1hZ2UvZ2lmO2Jhc2U2NCxSMGxHT0RkaEFnQUNBSUFBQUFBQUFQLy8veXdBQUFBQUFnQUNBQUFDQW9SUkFEcz0nOyAvLzF4MSBpbWFnZQorICAgICAgICBlLmRhdGFUcmFuc2Zlci5zZXREcmFnSW1hZ2UoaW1nLCAwLCAwKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBmdW5jdGlvbiBkb0hhbmRsZUJpbmRpbmcoYm91bmQsIGRyb3BTaGlmdCkgeworICAgICAgaWYgKHR5cGVvZiBib3VuZCA9PSAic3RyaW5nIikgeworICAgICAgICBib3VuZCA9IGNvbW1hbmRzW2JvdW5kXTsKKyAgICAgICAgaWYgKCFib3VuZCkgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgdmFyIHByZXZTaGlmdCA9IHNoaWZ0U2VsZWN0aW5nOworICAgICAgdHJ5IHsKKyAgICAgICAgaWYgKG9wdGlvbnMucmVhZE9ubHkpIHN1cHByZXNzRWRpdHMgPSB0cnVlOworICAgICAgICBpZiAoZHJvcFNoaWZ0KSBzaGlmdFNlbGVjdGluZyA9IG51bGw7CisgICAgICAgIGJvdW5kKGluc3RhbmNlKTsKKyAgICAgIH0gY2F0Y2goZSkgeworICAgICAgICBpZiAoZSAhPSBQYXNzKSB0aHJvdyBlOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBzaGlmdFNlbGVjdGluZyA9IHByZXZTaGlmdDsKKyAgICAgICAgc3VwcHJlc3NFZGl0cyA9IGZhbHNlOworICAgICAgfQorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIGZ1bmN0aW9uIGhhbmRsZUtleUJpbmRpbmcoZSkgeworICAgICAgLy8gSGFuZGxlIGF1dG8ga2V5bWFwIHRyYW5zaXRpb25zCisgICAgICB2YXIgc3RhcnRNYXAgPSBnZXRLZXlNYXAob3B0aW9ucy5rZXlNYXApLCBuZXh0ID0gc3RhcnRNYXAuYXV0bzsKKyAgICAgIGNsZWFyVGltZW91dChtYXliZVRyYW5zaXRpb24pOworICAgICAgaWYgKG5leHQgJiYgIWlzTW9kaWZpZXJLZXkoZSkpIG1heWJlVHJhbnNpdGlvbiA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7CisgICAgICAgIGlmIChnZXRLZXlNYXAob3B0aW9ucy5rZXlNYXApID09IHN0YXJ0TWFwKSB7CisgICAgICAgICAgb3B0aW9ucy5rZXlNYXAgPSAobmV4dC5jYWxsID8gbmV4dC5jYWxsKG51bGwsIGluc3RhbmNlKSA6IG5leHQpOworICAgICAgICB9CisgICAgICB9LCA1MCk7CisKKyAgICAgIHZhciBuYW1lID0ga2V5TmFtZXNbZV9wcm9wKGUsICJrZXlDb2RlIildLCBoYW5kbGVkID0gZmFsc2U7CisgICAgICBpZiAobmFtZSA9PSBudWxsIHx8IGUuYWx0R3JhcGhLZXkpIHJldHVybiBmYWxzZTsKKyAgICAgIGlmIChlX3Byb3AoZSwgImFsdEtleSIpKSBuYW1lID0gIkFsdC0iICsgbmFtZTsKKyAgICAgIGlmIChlX3Byb3AoZSwgImN0cmxLZXkiKSkgbmFtZSA9ICJDdHJsLSIgKyBuYW1lOworICAgICAgaWYgKGVfcHJvcChlLCAibWV0YUtleSIpKSBuYW1lID0gIkNtZC0iICsgbmFtZTsKKworICAgICAgdmFyIHN0b3BwZWQgPSBmYWxzZTsKKyAgICAgIGZ1bmN0aW9uIHN0b3AoKSB7IHN0b3BwZWQgPSB0cnVlOyB9CisKKyAgICAgIGlmIChlX3Byb3AoZSwgInNoaWZ0S2V5IikpIHsKKyAgICAgICAgaGFuZGxlZCA9IGxvb2t1cEtleSgiU2hpZnQtIiArIG5hbWUsIG9wdGlvbnMuZXh0cmFLZXlzLCBvcHRpb25zLmtleU1hcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihiKSB7cmV0dXJuIGRvSGFuZGxlQmluZGluZyhiLCB0cnVlKTt9LCBzdG9wKQorICAgICAgICAgICAgICAgfHwgbG9va3VwS2V5KG5hbWUsIG9wdGlvbnMuZXh0cmFLZXlzLCBvcHRpb25zLmtleU1hcCwgZnVuY3Rpb24oYikgeworICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGIgPT0gInN0cmluZyIgJiYgL15nb1tBLVpdLy50ZXN0KGIpKSByZXR1cm4gZG9IYW5kbGVCaW5kaW5nKGIpOworICAgICAgICAgICAgICAgfSwgc3RvcCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBoYW5kbGVkID0gbG9va3VwS2V5KG5hbWUsIG9wdGlvbnMuZXh0cmFLZXlzLCBvcHRpb25zLmtleU1hcCwgZG9IYW5kbGVCaW5kaW5nLCBzdG9wKTsKKyAgICAgIH0KKyAgICAgIGlmIChzdG9wcGVkKSBoYW5kbGVkID0gZmFsc2U7CisgICAgICBpZiAoaGFuZGxlZCkgeworICAgICAgICBlX3ByZXZlbnREZWZhdWx0KGUpOworICAgICAgICBpZiAoaWUpIHsgZS5vbGRLZXlDb2RlID0gZS5rZXlDb2RlOyBlLmtleUNvZGUgPSAwOyB9CisgICAgICB9CisgICAgICByZXR1cm4gaGFuZGxlZDsKKyAgICB9CisgICAgZnVuY3Rpb24gaGFuZGxlQ2hhckJpbmRpbmcoZSwgY2gpIHsKKyAgICAgIHZhciBoYW5kbGVkID0gbG9va3VwS2V5KCInIiArIGNoICsgIiciLCBvcHRpb25zLmV4dHJhS2V5cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMua2V5TWFwLCBmdW5jdGlvbihiKSB7IHJldHVybiBkb0hhbmRsZUJpbmRpbmcoYiwgdHJ1ZSk7IH0pOworICAgICAgaWYgKGhhbmRsZWQpIGVfcHJldmVudERlZmF1bHQoZSk7CisgICAgICByZXR1cm4gaGFuZGxlZDsKKyAgICB9CisKKyAgICB2YXIgbGFzdFN0b3BwZWRLZXkgPSBudWxsLCBtYXliZVRyYW5zaXRpb247CisgICAgZnVuY3Rpb24gb25LZXlEb3duKGUpIHsKKyAgICAgIGlmICghZm9jdXNlZCkgb25Gb2N1cygpOworICAgICAgaWYgKGllICYmIGUua2V5Q29kZSA9PSAyNykgeyBlLnJldHVyblZhbHVlID0gZmFsc2U7IH0KKyAgICAgIGlmIChwb2xsaW5nRmFzdCkgeyBpZiAocmVhZElucHV0KCkpIHBvbGxpbmdGYXN0ID0gZmFsc2U7IH0KKyAgICAgIGlmIChvcHRpb25zLm9uS2V5RXZlbnQgJiYgb3B0aW9ucy5vbktleUV2ZW50KGluc3RhbmNlLCBhZGRTdG9wKGUpKSkgcmV0dXJuOworICAgICAgdmFyIGNvZGUgPSBlX3Byb3AoZSwgImtleUNvZGUiKTsKKyAgICAgIC8vIElFIGRvZXMgc3RyYW5nZSB0aGluZ3Mgd2l0aCBlc2NhcGUuCisgICAgICBzZXRTaGlmdChjb2RlID09IDE2IHx8IGVfcHJvcChlLCAic2hpZnRLZXkiKSk7CisgICAgICAvLyBGaXJzdCBnaXZlIG9uS2V5RXZlbnQgb3B0aW9uIGEgY2hhbmNlIHRvIGhhbmRsZSB0aGlzLgorICAgICAgdmFyIGhhbmRsZWQgPSBoYW5kbGVLZXlCaW5kaW5nKGUpOworICAgICAgaWYgKHdpbmRvdy5vcGVyYSkgeworICAgICAgICBsYXN0U3RvcHBlZEtleSA9IGhhbmRsZWQgPyBjb2RlIDogbnVsbDsKKyAgICAgICAgLy8gT3BlcmEgaGFzIG5vIGN1dCBldmVudC4uLiB3ZSB0cnkgdG8gYXQgbGVhc3QgY2F0Y2ggdGhlIGtleSBjb21ibworICAgICAgICBpZiAoIWhhbmRsZWQgJiYgY29kZSA9PSA4OCAmJiBlX3Byb3AoZSwgbWFjID8gIm1ldGFLZXkiIDogImN0cmxLZXkiKSkKKyAgICAgICAgICByZXBsYWNlU2VsZWN0aW9uKCIiKTsKKyAgICAgIH0KKyAgICB9CisgICAgZnVuY3Rpb24gb25LZXlQcmVzcyhlKSB7CisgICAgICBpZiAocG9sbGluZ0Zhc3QpIHJlYWRJbnB1dCgpOworICAgICAgaWYgKG9wdGlvbnMub25LZXlFdmVudCAmJiBvcHRpb25zLm9uS2V5RXZlbnQoaW5zdGFuY2UsIGFkZFN0b3AoZSkpKSByZXR1cm47CisgICAgICB2YXIga2V5Q29kZSA9IGVfcHJvcChlLCAia2V5Q29kZSIpLCBjaGFyQ29kZSA9IGVfcHJvcChlLCAiY2hhckNvZGUiKTsKKyAgICAgIGlmICh3aW5kb3cub3BlcmEgJiYga2V5Q29kZSA9PSBsYXN0U3RvcHBlZEtleSkge2xhc3RTdG9wcGVkS2V5ID0gbnVsbDsgZV9wcmV2ZW50RGVmYXVsdChlKTsgcmV0dXJuO30KKyAgICAgIGlmICgoKHdpbmRvdy5vcGVyYSAmJiAhZS53aGljaCkgfHwga2h0bWwpICYmIGhhbmRsZUtleUJpbmRpbmcoZSkpIHJldHVybjsKKyAgICAgIHZhciBjaCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hhckNvZGUgPT0gbnVsbCA/IGtleUNvZGUgOiBjaGFyQ29kZSk7CisgICAgICBpZiAob3B0aW9ucy5lbGVjdHJpY0NoYXJzICYmIG1vZGUuZWxlY3RyaWNDaGFycyAmJiBvcHRpb25zLnNtYXJ0SW5kZW50ICYmICFvcHRpb25zLnJlYWRPbmx5KSB7CisgICAgICAgIGlmIChtb2RlLmVsZWN0cmljQ2hhcnMuaW5kZXhPZihjaCkgPiAtMSkKKyAgICAgICAgICBzZXRUaW1lb3V0KG9wZXJhdGlvbihmdW5jdGlvbigpIHtpbmRlbnRMaW5lKHNlbC50by5saW5lLCAic21hcnQiKTt9KSwgNzUpOworICAgICAgfQorICAgICAgaWYgKGhhbmRsZUNoYXJCaW5kaW5nKGUsIGNoKSkgcmV0dXJuOworICAgICAgZmFzdFBvbGwoKTsKKyAgICB9CisgICAgZnVuY3Rpb24gb25LZXlVcChlKSB7CisgICAgICBpZiAob3B0aW9ucy5vbktleUV2ZW50ICYmIG9wdGlvbnMub25LZXlFdmVudChpbnN0YW5jZSwgYWRkU3RvcChlKSkpIHJldHVybjsKKyAgICAgIGlmIChlX3Byb3AoZSwgImtleUNvZGUiKSA9PSAxNikgc2hpZnRTZWxlY3RpbmcgPSBudWxsOworICAgIH0KKworICAgIGZ1bmN0aW9uIG9uRm9jdXMoKSB7CisgICAgICBpZiAob3B0aW9ucy5yZWFkT25seSA9PSAibm9jdXJzb3IiKSByZXR1cm47CisgICAgICBpZiAoIWZvY3VzZWQpIHsKKyAgICAgICAgaWYgKG9wdGlvbnMub25Gb2N1cykgb3B0aW9ucy5vbkZvY3VzKGluc3RhbmNlKTsKKyAgICAgICAgZm9jdXNlZCA9IHRydWU7CisgICAgICAgIGlmICh3cmFwcGVyLmNsYXNzTmFtZS5zZWFyY2goL1xiQ29kZU1pcnJvci1mb2N1c2VkXGIvKSA9PSAtMSkKKyAgICAgICAgICB3cmFwcGVyLmNsYXNzTmFtZSArPSAiIENvZGVNaXJyb3ItZm9jdXNlZCI7CisgICAgICAgIGlmICghbGVhdmVJbnB1dEFsb25lKSByZXNldElucHV0KHRydWUpOworICAgICAgfQorICAgICAgc2xvd1BvbGwoKTsKKyAgICAgIHJlc3RhcnRCbGluaygpOworICAgIH0KKyAgICBmdW5jdGlvbiBvbkJsdXIoKSB7CisgICAgICBpZiAoZm9jdXNlZCkgeworICAgICAgICBpZiAob3B0aW9ucy5vbkJsdXIpIG9wdGlvbnMub25CbHVyKGluc3RhbmNlKTsKKyAgICAgICAgZm9jdXNlZCA9IGZhbHNlOworICAgICAgICBpZiAoYnJhY2tldEhpZ2hsaWdodGVkKQorICAgICAgICAgIG9wZXJhdGlvbihmdW5jdGlvbigpeworICAgICAgICAgICAgaWYgKGJyYWNrZXRIaWdobGlnaHRlZCkgeyBicmFja2V0SGlnaGxpZ2h0ZWQoKTsgYnJhY2tldEhpZ2hsaWdodGVkID0gbnVsbDsgfQorICAgICAgICAgIH0pKCk7CisgICAgICAgIHdyYXBwZXIuY2xhc3NOYW1lID0gd3JhcHBlci5jbGFzc05hbWUucmVwbGFjZSgiIENvZGVNaXJyb3ItZm9jdXNlZCIsICIiKTsKKyAgICAgIH0KKyAgICAgIGNsZWFySW50ZXJ2YWwoYmxpbmtlcik7CisgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge2lmICghZm9jdXNlZCkgc2hpZnRTZWxlY3RpbmcgPSBudWxsO30sIDE1MCk7CisgICAgfQorCisgICAgLy8gUmVwbGFjZSB0aGUgcmFuZ2UgZnJvbSBmcm9tIHRvIHRvIGJ5IHRoZSBzdHJpbmdzIGluIG5ld1RleHQuCisgICAgLy8gQWZ0ZXJ3YXJkcywgc2V0IHRoZSBzZWxlY3Rpb24gdG8gc2VsRnJvbSwgc2VsVG8uCisgICAgZnVuY3Rpb24gdXBkYXRlTGluZXMoZnJvbSwgdG8sIG5ld1RleHQsIHNlbEZyb20sIHNlbFRvKSB7CisgICAgICBpZiAoc3VwcHJlc3NFZGl0cykgcmV0dXJuOworICAgICAgaWYgKGhpc3RvcnkpIHsKKyAgICAgICAgdmFyIG9sZCA9IFtdOworICAgICAgICBkb2MuaXRlcihmcm9tLmxpbmUsIHRvLmxpbmUgKyAxLCBmdW5jdGlvbihsaW5lKSB7IG9sZC5wdXNoKGxpbmUudGV4dCk7IH0pOworICAgICAgICBoaXN0b3J5LmFkZENoYW5nZShmcm9tLmxpbmUsIG5ld1RleHQubGVuZ3RoLCBvbGQpOworICAgICAgICB3aGlsZSAoaGlzdG9yeS5kb25lLmxlbmd0aCA+IG9wdGlvbnMudW5kb0RlcHRoKSBoaXN0b3J5LmRvbmUuc2hpZnQoKTsKKyAgICAgIH0KKyAgICAgIHVwZGF0ZUxpbmVzTm9VbmRvKGZyb20sIHRvLCBuZXdUZXh0LCBzZWxGcm9tLCBzZWxUbyk7CisgICAgfQorICAgIGZ1bmN0aW9uIHVucmVkb0hlbHBlcihmcm9tLCB0bykgeworICAgICAgaWYgKCFmcm9tLmxlbmd0aCkgcmV0dXJuOworICAgICAgdmFyIHNldCA9IGZyb20ucG9wKCksIG91dCA9IFtdOworICAgICAgZm9yICh2YXIgaSA9IHNldC5sZW5ndGggLSAxOyBpID49IDA7IGkgLT0gMSkgeworICAgICAgICB2YXIgY2hhbmdlID0gc2V0W2ldOworICAgICAgICB2YXIgcmVwbGFjZWQgPSBbXSwgZW5kID0gY2hhbmdlLnN0YXJ0ICsgY2hhbmdlLmFkZGVkOworICAgICAgICBkb2MuaXRlcihjaGFuZ2Uuc3RhcnQsIGVuZCwgZnVuY3Rpb24obGluZSkgeyByZXBsYWNlZC5wdXNoKGxpbmUudGV4dCk7IH0pOworICAgICAgICBvdXQucHVzaCh7c3RhcnQ6IGNoYW5nZS5zdGFydCwgYWRkZWQ6IGNoYW5nZS5vbGQubGVuZ3RoLCBvbGQ6IHJlcGxhY2VkfSk7CisgICAgICAgIHZhciBwb3MgPSBjbGlwUG9zKHtsaW5lOiBjaGFuZ2Uuc3RhcnQgKyBjaGFuZ2Uub2xkLmxlbmd0aCAtIDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjaDogZWRpdEVuZChyZXBsYWNlZFtyZXBsYWNlZC5sZW5ndGgtMV0sIGNoYW5nZS5vbGRbY2hhbmdlLm9sZC5sZW5ndGgtMV0pfSk7CisgICAgICAgIHVwZGF0ZUxpbmVzTm9VbmRvKHtsaW5lOiBjaGFuZ2Uuc3RhcnQsIGNoOiAwfSwge2xpbmU6IGVuZCAtIDEsIGNoOiBnZXRMaW5lKGVuZC0xKS50ZXh0Lmxlbmd0aH0sIGNoYW5nZS5vbGQsIHBvcywgcG9zKTsKKyAgICAgIH0KKyAgICAgIHVwZGF0ZUlucHV0ID0gdHJ1ZTsKKyAgICAgIHRvLnB1c2gob3V0KTsKKyAgICB9CisgICAgZnVuY3Rpb24gdW5kbygpIHt1bnJlZG9IZWxwZXIoaGlzdG9yeS5kb25lLCBoaXN0b3J5LnVuZG9uZSk7fQorICAgIGZ1bmN0aW9uIHJlZG8oKSB7dW5yZWRvSGVscGVyKGhpc3RvcnkudW5kb25lLCBoaXN0b3J5LmRvbmUpO30KKworICAgIGZ1bmN0aW9uIHVwZGF0ZUxpbmVzTm9VbmRvKGZyb20sIHRvLCBuZXdUZXh0LCBzZWxGcm9tLCBzZWxUbykgeworICAgICAgaWYgKHN1cHByZXNzRWRpdHMpIHJldHVybjsKKyAgICAgIHZhciByZWNvbXB1dGVNYXhMZW5ndGggPSBmYWxzZSwgbWF4TGluZUxlbmd0aCA9IG1heExpbmUubGVuZ3RoOworICAgICAgaWYgKCFvcHRpb25zLmxpbmVXcmFwcGluZykKKyAgICAgICAgZG9jLml0ZXIoZnJvbS5saW5lLCB0by5saW5lICsgMSwgZnVuY3Rpb24obGluZSkgeworICAgICAgICAgIGlmIChsaW5lLnRleHQubGVuZ3RoID09IG1heExpbmVMZW5ndGgpIHtyZWNvbXB1dGVNYXhMZW5ndGggPSB0cnVlOyByZXR1cm4gdHJ1ZTt9CisgICAgICAgIH0pOworICAgICAgaWYgKGZyb20ubGluZSAhPSB0by5saW5lIHx8IG5ld1RleHQubGVuZ3RoID4gMSkgZ3V0dGVyRGlydHkgPSB0cnVlOworCisgICAgICB2YXIgbmxpbmVzID0gdG8ubGluZSAtIGZyb20ubGluZSwgZmlyc3RMaW5lID0gZ2V0TGluZShmcm9tLmxpbmUpLCBsYXN0TGluZSA9IGdldExpbmUodG8ubGluZSk7CisgICAgICAvLyBGaXJzdCBhZGp1c3QgdGhlIGxpbmUgc3RydWN0dXJlLCB0YWtpbmcgc29tZSBjYXJlIHRvIGxlYXZlIGhpZ2hsaWdodGluZyBpbnRhY3QuCisgICAgICBpZiAoZnJvbS5jaCA9PSAwICYmIHRvLmNoID09IDAgJiYgbmV3VGV4dFtuZXdUZXh0Lmxlbmd0aCAtIDFdID09ICIiKSB7CisgICAgICAgIC8vIFRoaXMgaXMgYSB3aG9sZS1saW5lIHJlcGxhY2UuIFRyZWF0ZWQgc3BlY2lhbGx5IHRvIG1ha2UKKyAgICAgICAgLy8gc3VyZSBsaW5lIG9iamVjdHMgbW92ZSB0aGUgd2F5IHRoZXkgYXJlIHN1cHBvc2VkIHRvLgorICAgICAgICB2YXIgYWRkZWQgPSBbXSwgcHJldkxpbmUgPSBudWxsOworICAgICAgICBpZiAoZnJvbS5saW5lKSB7CisgICAgICAgICAgcHJldkxpbmUgPSBnZXRMaW5lKGZyb20ubGluZSAtIDEpOworICAgICAgICAgIHByZXZMaW5lLmZpeE1hcmtFbmRzKGxhc3RMaW5lKTsKKyAgICAgICAgfSBlbHNlIGxhc3RMaW5lLmZpeE1hcmtTdGFydHMoKTsKKyAgICAgICAgZm9yICh2YXIgaSA9IDAsIGUgPSBuZXdUZXh0Lmxlbmd0aCAtIDE7IGkgPCBlOyArK2kpCisgICAgICAgICAgYWRkZWQucHVzaChMaW5lLmluaGVyaXRNYXJrcyhuZXdUZXh0W2ldLCBwcmV2TGluZSkpOworICAgICAgICBpZiAobmxpbmVzKSBkb2MucmVtb3ZlKGZyb20ubGluZSwgbmxpbmVzLCBjYWxsYmFja3MpOworICAgICAgICBpZiAoYWRkZWQubGVuZ3RoKSBkb2MuaW5zZXJ0KGZyb20ubGluZSwgYWRkZWQpOworICAgICAgfSBlbHNlIGlmIChmaXJzdExpbmUgPT0gbGFzdExpbmUpIHsKKyAgICAgICAgaWYgKG5ld1RleHQubGVuZ3RoID09IDEpCisgICAgICAgICAgZmlyc3RMaW5lLnJlcGxhY2UoZnJvbS5jaCwgdG8uY2gsIG5ld1RleHRbMF0pOworICAgICAgICBlbHNlIHsKKyAgICAgICAgICBsYXN0TGluZSA9IGZpcnN0TGluZS5zcGxpdCh0by5jaCwgbmV3VGV4dFtuZXdUZXh0Lmxlbmd0aC0xXSk7CisgICAgICAgICAgZmlyc3RMaW5lLnJlcGxhY2UoZnJvbS5jaCwgbnVsbCwgbmV3VGV4dFswXSk7CisgICAgICAgICAgZmlyc3RMaW5lLmZpeE1hcmtFbmRzKGxhc3RMaW5lKTsKKyAgICAgICAgICB2YXIgYWRkZWQgPSBbXTsKKyAgICAgICAgICBmb3IgKHZhciBpID0gMSwgZSA9IG5ld1RleHQubGVuZ3RoIC0gMTsgaSA8IGU7ICsraSkKKyAgICAgICAgICAgIGFkZGVkLnB1c2goTGluZS5pbmhlcml0TWFya3MobmV3VGV4dFtpXSwgZmlyc3RMaW5lKSk7CisgICAgICAgICAgYWRkZWQucHVzaChsYXN0TGluZSk7CisgICAgICAgICAgZG9jLmluc2VydChmcm9tLmxpbmUgKyAxLCBhZGRlZCk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSBpZiAobmV3VGV4dC5sZW5ndGggPT0gMSkgeworICAgICAgICBmaXJzdExpbmUucmVwbGFjZShmcm9tLmNoLCBudWxsLCBuZXdUZXh0WzBdKTsKKyAgICAgICAgbGFzdExpbmUucmVwbGFjZShudWxsLCB0by5jaCwgIiIpOworICAgICAgICBmaXJzdExpbmUuYXBwZW5kKGxhc3RMaW5lKTsKKyAgICAgICAgZG9jLnJlbW92ZShmcm9tLmxpbmUgKyAxLCBubGluZXMsIGNhbGxiYWNrcyk7CisgICAgICB9IGVsc2UgeworICAgICAgICB2YXIgYWRkZWQgPSBbXTsKKyAgICAgICAgZmlyc3RMaW5lLnJlcGxhY2UoZnJvbS5jaCwgbnVsbCwgbmV3VGV4dFswXSk7CisgICAgICAgIGxhc3RMaW5lLnJlcGxhY2UobnVsbCwgdG8uY2gsIG5ld1RleHRbbmV3VGV4dC5sZW5ndGgtMV0pOworICAgICAgICBmaXJzdExpbmUuZml4TWFya0VuZHMobGFzdExpbmUpOworICAgICAgICBmb3IgKHZhciBpID0gMSwgZSA9IG5ld1RleHQubGVuZ3RoIC0gMTsgaSA8IGU7ICsraSkKKyAgICAgICAgICBhZGRlZC5wdXNoKExpbmUuaW5oZXJpdE1hcmtzKG5ld1RleHRbaV0sIGZpcnN0TGluZSkpOworICAgICAgICBpZiAobmxpbmVzID4gMSkgZG9jLnJlbW92ZShmcm9tLmxpbmUgKyAxLCBubGluZXMgLSAxLCBjYWxsYmFja3MpOworICAgICAgICBkb2MuaW5zZXJ0KGZyb20ubGluZSArIDEsIGFkZGVkKTsKKyAgICAgIH0KKyAgICAgIGlmIChvcHRpb25zLmxpbmVXcmFwcGluZykgeworICAgICAgICB2YXIgcGVyTGluZSA9IE1hdGgubWF4KDUsIHNjcm9sbGVyLmNsaWVudFdpZHRoIC8gY2hhcldpZHRoKCkgLSAzKTsKKyAgICAgICAgZG9jLml0ZXIoZnJvbS5saW5lLCBmcm9tLmxpbmUgKyBuZXdUZXh0Lmxlbmd0aCwgZnVuY3Rpb24obGluZSkgeworICAgICAgICAgIGlmIChsaW5lLmhpZGRlbikgcmV0dXJuOworICAgICAgICAgIHZhciBndWVzcyA9IE1hdGguY2VpbChsaW5lLnRleHQubGVuZ3RoIC8gcGVyTGluZSkgfHwgMTsKKyAgICAgICAgICBpZiAoZ3Vlc3MgIT0gbGluZS5oZWlnaHQpIHVwZGF0ZUxpbmVIZWlnaHQobGluZSwgZ3Vlc3MpOworICAgICAgICB9KTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGRvYy5pdGVyKGZyb20ubGluZSwgZnJvbS5saW5lICsgbmV3VGV4dC5sZW5ndGgsIGZ1bmN0aW9uKGxpbmUpIHsKKyAgICAgICAgICB2YXIgbCA9IGxpbmUudGV4dDsKKyAgICAgICAgICBpZiAobC5sZW5ndGggPiBtYXhMaW5lTGVuZ3RoKSB7CisgICAgICAgICAgICBtYXhMaW5lID0gbDsgbWF4TGluZUxlbmd0aCA9IGwubGVuZ3RoOyBtYXhXaWR0aCA9IG51bGw7CisgICAgICAgICAgICByZWNvbXB1dGVNYXhMZW5ndGggPSBmYWxzZTsKKyAgICAgICAgICB9CisgICAgICAgIH0pOworICAgICAgICBpZiAocmVjb21wdXRlTWF4TGVuZ3RoKSB7CisgICAgICAgICAgbWF4TGluZUxlbmd0aCA9IDA7IG1heExpbmUgPSAiIjsgbWF4V2lkdGggPSBudWxsOworICAgICAgICAgIGRvYy5pdGVyKDAsIGRvYy5zaXplLCBmdW5jdGlvbihsaW5lKSB7CisgICAgICAgICAgICB2YXIgbCA9IGxpbmUudGV4dDsKKyAgICAgICAgICAgIGlmIChsLmxlbmd0aCA+IG1heExpbmVMZW5ndGgpIHsKKyAgICAgICAgICAgICAgbWF4TGluZUxlbmd0aCA9IGwubGVuZ3RoOyBtYXhMaW5lID0gbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9KTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICAvLyBBZGQgdGhlc2UgbGluZXMgdG8gdGhlIHdvcmsgYXJyYXksIHNvIHRoYXQgdGhleSB3aWxsIGJlCisgICAgICAvLyBoaWdobGlnaHRlZC4gQWRqdXN0IHdvcmsgbGluZXMgaWYgbGluZXMgd2VyZSBhZGRlZC9yZW1vdmVkLgorICAgICAgdmFyIG5ld1dvcmsgPSBbXSwgbGVuZGlmZiA9IG5ld1RleHQubGVuZ3RoIC0gbmxpbmVzIC0gMTsKKyAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gd29yay5sZW5ndGg7IGkgPCBsOyArK2kpIHsKKyAgICAgICAgdmFyIHRhc2sgPSB3b3JrW2ldOworICAgICAgICBpZiAodGFzayA8IGZyb20ubGluZSkgbmV3V29yay5wdXNoKHRhc2spOworICAgICAgICBlbHNlIGlmICh0YXNrID4gdG8ubGluZSkgbmV3V29yay5wdXNoKHRhc2sgKyBsZW5kaWZmKTsKKyAgICAgIH0KKyAgICAgIHZhciBobEVuZCA9IGZyb20ubGluZSArIE1hdGgubWluKG5ld1RleHQubGVuZ3RoLCA1MDApOworICAgICAgaGlnaGxpZ2h0TGluZXMoZnJvbS5saW5lLCBobEVuZCk7CisgICAgICBuZXdXb3JrLnB1c2goaGxFbmQpOworICAgICAgd29yayA9IG5ld1dvcms7CisgICAgICBzdGFydFdvcmtlcigxMDApOworICAgICAgLy8gUmVtZW1iZXIgdGhhdCB0aGVzZSBsaW5lcyBjaGFuZ2VkLCBmb3IgdXBkYXRpbmcgdGhlIGRpc3BsYXkKKyAgICAgIGNoYW5nZXMucHVzaCh7ZnJvbTogZnJvbS5saW5lLCB0bzogdG8ubGluZSArIDEsIGRpZmY6IGxlbmRpZmZ9KTsKKyAgICAgIHZhciBjaGFuZ2VPYmogPSB7ZnJvbTogZnJvbSwgdG86IHRvLCB0ZXh0OiBuZXdUZXh0fTsKKyAgICAgIGlmICh0ZXh0Q2hhbmdlZCkgeworICAgICAgICBmb3IgKHZhciBjdXIgPSB0ZXh0Q2hhbmdlZDsgY3VyLm5leHQ7IGN1ciA9IGN1ci5uZXh0KSB7fQorICAgICAgICBjdXIubmV4dCA9IGNoYW5nZU9iajsKKyAgICAgIH0gZWxzZSB0ZXh0Q2hhbmdlZCA9IGNoYW5nZU9iajsKKworICAgICAgLy8gVXBkYXRlIHRoZSBzZWxlY3Rpb24KKyAgICAgIGZ1bmN0aW9uIHVwZGF0ZUxpbmUobikge3JldHVybiBuIDw9IE1hdGgubWluKHRvLmxpbmUsIHRvLmxpbmUgKyBsZW5kaWZmKSA/IG4gOiBuICsgbGVuZGlmZjt9CisgICAgICBzZXRTZWxlY3Rpb24oc2VsRnJvbSwgc2VsVG8sIHVwZGF0ZUxpbmUoc2VsLmZyb20ubGluZSksIHVwZGF0ZUxpbmUoc2VsLnRvLmxpbmUpKTsKKworICAgICAgLy8gTWFrZSBzdXJlIHRoZSBzY3JvbGwtc2l6ZSBkaXYgaGFzIHRoZSBjb3JyZWN0IGhlaWdodC4KKyAgICAgIGlmIChzY3JvbGxlci5jbGllbnRIZWlnaHQpCisgICAgICAgIGNvZGUuc3R5bGUuaGVpZ2h0ID0gKGRvYy5oZWlnaHQgKiB0ZXh0SGVpZ2h0KCkgKyAyICogcGFkZGluZ1RvcCgpKSArICJweCI7CisgICAgfQorCisgICAgZnVuY3Rpb24gcmVwbGFjZVJhbmdlKGNvZGUsIGZyb20sIHRvKSB7CisgICAgICBmcm9tID0gY2xpcFBvcyhmcm9tKTsKKyAgICAgIGlmICghdG8pIHRvID0gZnJvbTsgZWxzZSB0byA9IGNsaXBQb3ModG8pOworICAgICAgY29kZSA9IHNwbGl0TGluZXMoY29kZSk7CisgICAgICBmdW5jdGlvbiBhZGp1c3RQb3MocG9zKSB7CisgICAgICAgIGlmIChwb3NMZXNzKHBvcywgZnJvbSkpIHJldHVybiBwb3M7CisgICAgICAgIGlmICghcG9zTGVzcyh0bywgcG9zKSkgcmV0dXJuIGVuZDsKKyAgICAgICAgdmFyIGxpbmUgPSBwb3MubGluZSArIGNvZGUubGVuZ3RoIC0gKHRvLmxpbmUgLSBmcm9tLmxpbmUpIC0gMTsKKyAgICAgICAgdmFyIGNoID0gcG9zLmNoOworICAgICAgICBpZiAocG9zLmxpbmUgPT0gdG8ubGluZSkKKyAgICAgICAgICBjaCArPSBjb2RlW2NvZGUubGVuZ3RoLTFdLmxlbmd0aCAtICh0by5jaCAtICh0by5saW5lID09IGZyb20ubGluZSA/IGZyb20uY2ggOiAwKSk7CisgICAgICAgIHJldHVybiB7bGluZTogbGluZSwgY2g6IGNofTsKKyAgICAgIH0KKyAgICAgIHZhciBlbmQ7CisgICAgICByZXBsYWNlUmFuZ2UxKGNvZGUsIGZyb20sIHRvLCBmdW5jdGlvbihlbmQxKSB7CisgICAgICAgIGVuZCA9IGVuZDE7CisgICAgICAgIHJldHVybiB7ZnJvbTogYWRqdXN0UG9zKHNlbC5mcm9tKSwgdG86IGFkanVzdFBvcyhzZWwudG8pfTsKKyAgICAgIH0pOworICAgICAgcmV0dXJuIGVuZDsKKyAgICB9CisgICAgZnVuY3Rpb24gcmVwbGFjZVNlbGVjdGlvbihjb2RlLCBjb2xsYXBzZSkgeworICAgICAgcmVwbGFjZVJhbmdlMShzcGxpdExpbmVzKGNvZGUpLCBzZWwuZnJvbSwgc2VsLnRvLCBmdW5jdGlvbihlbmQpIHsKKyAgICAgICAgaWYgKGNvbGxhcHNlID09ICJlbmQiKSByZXR1cm4ge2Zyb206IGVuZCwgdG86IGVuZH07CisgICAgICAgIGVsc2UgaWYgKGNvbGxhcHNlID09ICJzdGFydCIpIHJldHVybiB7ZnJvbTogc2VsLmZyb20sIHRvOiBzZWwuZnJvbX07CisgICAgICAgIGVsc2UgcmV0dXJuIHtmcm9tOiBzZWwuZnJvbSwgdG86IGVuZH07CisgICAgICB9KTsKKyAgICB9CisgICAgZnVuY3Rpb24gcmVwbGFjZVJhbmdlMShjb2RlLCBmcm9tLCB0bywgY29tcHV0ZVNlbCkgeworICAgICAgdmFyIGVuZGNoID0gY29kZS5sZW5ndGggPT0gMSA/IGNvZGVbMF0ubGVuZ3RoICsgZnJvbS5jaCA6IGNvZGVbY29kZS5sZW5ndGgtMV0ubGVuZ3RoOworICAgICAgdmFyIG5ld1NlbCA9IGNvbXB1dGVTZWwoe2xpbmU6IGZyb20ubGluZSArIGNvZGUubGVuZ3RoIC0gMSwgY2g6IGVuZGNofSk7CisgICAgICB1cGRhdGVMaW5lcyhmcm9tLCB0bywgY29kZSwgbmV3U2VsLmZyb20sIG5ld1NlbC50byk7CisgICAgfQorCisgICAgZnVuY3Rpb24gZ2V0UmFuZ2UoZnJvbSwgdG8pIHsKKyAgICAgIHZhciBsMSA9IGZyb20ubGluZSwgbDIgPSB0by5saW5lOworICAgICAgaWYgKGwxID09IGwyKSByZXR1cm4gZ2V0TGluZShsMSkudGV4dC5zbGljZShmcm9tLmNoLCB0by5jaCk7CisgICAgICB2YXIgY29kZSA9IFtnZXRMaW5lKGwxKS50ZXh0LnNsaWNlKGZyb20uY2gpXTsKKyAgICAgIGRvYy5pdGVyKGwxICsgMSwgbDIsIGZ1bmN0aW9uKGxpbmUpIHsgY29kZS5wdXNoKGxpbmUudGV4dCk7IH0pOworICAgICAgY29kZS5wdXNoKGdldExpbmUobDIpLnRleHQuc2xpY2UoMCwgdG8uY2gpKTsKKyAgICAgIHJldHVybiBjb2RlLmpvaW4oIlxuIik7CisgICAgfQorICAgIGZ1bmN0aW9uIGdldFNlbGVjdGlvbigpIHsKKyAgICAgIHJldHVybiBnZXRSYW5nZShzZWwuZnJvbSwgc2VsLnRvKTsKKyAgICB9CisKKyAgICB2YXIgcG9sbGluZ0Zhc3QgPSBmYWxzZTsgLy8gRW5zdXJlcyBzbG93UG9sbCBkb2Vzbid0IGNhbmNlbCBmYXN0UG9sbAorICAgIGZ1bmN0aW9uIHNsb3dQb2xsKCkgeworICAgICAgaWYgKHBvbGxpbmdGYXN0KSByZXR1cm47CisgICAgICBwb2xsLnNldChvcHRpb25zLnBvbGxJbnRlcnZhbCwgZnVuY3Rpb24oKSB7CisgICAgICAgIHN0YXJ0T3BlcmF0aW9uKCk7CisgICAgICAgIHJlYWRJbnB1dCgpOworICAgICAgICBpZiAoZm9jdXNlZCkgc2xvd1BvbGwoKTsKKyAgICAgICAgZW5kT3BlcmF0aW9uKCk7CisgICAgICB9KTsKKyAgICB9CisgICAgZnVuY3Rpb24gZmFzdFBvbGwoKSB7CisgICAgICB2YXIgbWlzc2VkID0gZmFsc2U7CisgICAgICBwb2xsaW5nRmFzdCA9IHRydWU7CisgICAgICBmdW5jdGlvbiBwKCkgeworICAgICAgICBzdGFydE9wZXJhdGlvbigpOworICAgICAgICB2YXIgY2hhbmdlZCA9IHJlYWRJbnB1dCgpOworICAgICAgICBpZiAoIWNoYW5nZWQgJiYgIW1pc3NlZCkge21pc3NlZCA9IHRydWU7IHBvbGwuc2V0KDYwLCBwKTt9CisgICAgICAgIGVsc2Uge3BvbGxpbmdGYXN0ID0gZmFsc2U7IHNsb3dQb2xsKCk7fQorICAgICAgICBlbmRPcGVyYXRpb24oKTsKKyAgICAgIH0KKyAgICAgIHBvbGwuc2V0KDIwLCBwKTsKKyAgICB9CisKKyAgICAvLyBQcmV2aW5wdXQgaXMgYSBoYWNrIHRvIHdvcmsgd2l0aCBJTUUuIElmIHdlIHJlc2V0IHRoZSB0ZXh0YXJlYQorICAgIC8vIG9uIGV2ZXJ5IGNoYW5nZSwgdGhhdCBicmVha3MgSU1FLiBTbyB3ZSBsb29rIGZvciBjaGFuZ2VzCisgICAgLy8gY29tcGFyZWQgdG8gdGhlIHByZXZpb3VzIGNvbnRlbnQgaW5zdGVhZC4gKE1vZGVybiBicm93c2VycyBoYXZlCisgICAgLy8gZXZlbnRzIHRoYXQgaW5kaWNhdGUgSU1FIHRha2luZyBwbGFjZSwgYnV0IHRoZXNlIGFyZSBub3Qgd2lkZWx5CisgICAgLy8gc3VwcG9ydGVkIG9yIGNvbXBhdGlibGUgZW5vdWdoIHlldCB0byByZWx5IG9uLikKKyAgICB2YXIgcHJldklucHV0ID0gIiI7CisgICAgZnVuY3Rpb24gcmVhZElucHV0KCkgeworICAgICAgaWYgKGxlYXZlSW5wdXRBbG9uZSB8fCAhZm9jdXNlZCB8fCBoYXNTZWxlY3Rpb24oaW5wdXQpIHx8IG9wdGlvbnMucmVhZE9ubHkpIHJldHVybiBmYWxzZTsKKyAgICAgIHZhciB0ZXh0ID0gaW5wdXQudmFsdWU7CisgICAgICBpZiAodGV4dCA9PSBwcmV2SW5wdXQpIHJldHVybiBmYWxzZTsKKyAgICAgIHNoaWZ0U2VsZWN0aW5nID0gbnVsbDsKKyAgICAgIHZhciBzYW1lID0gMCwgbCA9IE1hdGgubWluKHByZXZJbnB1dC5sZW5ndGgsIHRleHQubGVuZ3RoKTsKKyAgICAgIHdoaWxlIChzYW1lIDwgbCAmJiBwcmV2SW5wdXRbc2FtZV0gPT0gdGV4dFtzYW1lXSkgKytzYW1lOworICAgICAgaWYgKHNhbWUgPCBwcmV2SW5wdXQubGVuZ3RoKQorICAgICAgICBzZWwuZnJvbSA9IHtsaW5lOiBzZWwuZnJvbS5saW5lLCBjaDogc2VsLmZyb20uY2ggLSAocHJldklucHV0Lmxlbmd0aCAtIHNhbWUpfTsKKyAgICAgIGVsc2UgaWYgKG92ZXJ3cml0ZSAmJiBwb3NFcShzZWwuZnJvbSwgc2VsLnRvKSkKKyAgICAgICAgc2VsLnRvID0ge2xpbmU6IHNlbC50by5saW5lLCBjaDogTWF0aC5taW4oZ2V0TGluZShzZWwudG8ubGluZSkudGV4dC5sZW5ndGgsIHNlbC50by5jaCArICh0ZXh0Lmxlbmd0aCAtIHNhbWUpKX07CisgICAgICByZXBsYWNlU2VsZWN0aW9uKHRleHQuc2xpY2Uoc2FtZSksICJlbmQiKTsKKyAgICAgIHByZXZJbnB1dCA9IHRleHQ7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgZnVuY3Rpb24gcmVzZXRJbnB1dCh1c2VyKSB7CisgICAgICBpZiAoIXBvc0VxKHNlbC5mcm9tLCBzZWwudG8pKSB7CisgICAgICAgIHByZXZJbnB1dCA9ICIiOworICAgICAgICBpbnB1dC52YWx1ZSA9IGdldFNlbGVjdGlvbigpOworICAgICAgICBzZWxlY3RJbnB1dChpbnB1dCk7CisgICAgICB9IGVsc2UgaWYgKHVzZXIpIHByZXZJbnB1dCA9IGlucHV0LnZhbHVlID0gIiI7CisgICAgfQorCisgICAgZnVuY3Rpb24gZm9jdXNJbnB1dCgpIHsKKyAgICAgIGlmIChvcHRpb25zLnJlYWRPbmx5ICE9ICJub2N1cnNvciIpIGlucHV0LmZvY3VzKCk7CisgICAgfQorCisgICAgZnVuY3Rpb24gc2Nyb2xsRWRpdG9ySW50b1ZpZXcoKSB7CisgICAgICBpZiAoIWN1cnNvci5nZXRCb3VuZGluZ0NsaWVudFJlY3QpIHJldHVybjsKKyAgICAgIHZhciByZWN0ID0gY3Vyc29yLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOworICAgICAgLy8gSUUgcmV0dXJucyBib2d1cyBjb29yZGluYXRlcyB3aGVuIHRoZSBpbnN0YW5jZSBzaXRzIGluc2lkZSBvZiBhbiBpZnJhbWUgYW5kIHRoZSBjdXJzb3IgaXMgaGlkZGVuCisgICAgICBpZiAoaWUgJiYgcmVjdC50b3AgPT0gcmVjdC5ib3R0b20pIHJldHVybjsKKyAgICAgIHZhciB3aW5IID0gd2luZG93LmlubmVySGVpZ2h0IHx8IE1hdGgubWF4KGRvY3VtZW50LmJvZHkub2Zmc2V0SGVpZ2h0LCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQub2Zmc2V0SGVpZ2h0KTsKKyAgICAgIGlmIChyZWN0LnRvcCA8IDAgfHwgcmVjdC5ib3R0b20gPiB3aW5IKSBjdXJzb3Iuc2Nyb2xsSW50b1ZpZXcoKTsKKyAgICB9CisgICAgZnVuY3Rpb24gc2Nyb2xsQ3Vyc29ySW50b1ZpZXcoKSB7CisgICAgICB2YXIgY3Vyc29yID0gbG9jYWxDb29yZHMoc2VsLmludmVydGVkID8gc2VsLmZyb20gOiBzZWwudG8pOworICAgICAgdmFyIHggPSBvcHRpb25zLmxpbmVXcmFwcGluZyA/IE1hdGgubWluKGN1cnNvci54LCBsaW5lU3BhY2Uub2Zmc2V0V2lkdGgpIDogY3Vyc29yLng7CisgICAgICByZXR1cm4gc2Nyb2xsSW50b1ZpZXcoeCwgY3Vyc29yLnksIHgsIGN1cnNvci55Qm90KTsKKyAgICB9CisgICAgZnVuY3Rpb24gc2Nyb2xsSW50b1ZpZXcoeDEsIHkxLCB4MiwgeTIpIHsKKyAgICAgIHZhciBwbCA9IHBhZGRpbmdMZWZ0KCksIHB0ID0gcGFkZGluZ1RvcCgpOworICAgICAgeTEgKz0gcHQ7IHkyICs9IHB0OyB4MSArPSBwbDsgeDIgKz0gcGw7CisgICAgICB2YXIgc2NyZWVuID0gc2Nyb2xsZXIuY2xpZW50SGVpZ2h0LCBzY3JlZW50b3AgPSBzY3JvbGxlci5zY3JvbGxUb3AsIHNjcm9sbGVkID0gZmFsc2UsIHJlc3VsdCA9IHRydWU7CisgICAgICBpZiAoeTEgPCBzY3JlZW50b3ApIHtzY3JvbGxlci5zY3JvbGxUb3AgPSBNYXRoLm1heCgwLCB5MSk7IHNjcm9sbGVkID0gdHJ1ZTt9CisgICAgICBlbHNlIGlmICh5MiA+IHNjcmVlbnRvcCArIHNjcmVlbikge3Njcm9sbGVyLnNjcm9sbFRvcCA9IHkyIC0gc2NyZWVuOyBzY3JvbGxlZCA9IHRydWU7fQorCisgICAgICB2YXIgc2NyZWVudyA9IHNjcm9sbGVyLmNsaWVudFdpZHRoLCBzY3JlZW5sZWZ0ID0gc2Nyb2xsZXIuc2Nyb2xsTGVmdDsKKyAgICAgIHZhciBndXR0ZXJ3ID0gb3B0aW9ucy5maXhlZEd1dHRlciA/IGd1dHRlci5jbGllbnRXaWR0aCA6IDA7CisgICAgICB2YXIgYXRMZWZ0ID0geDEgPCBndXR0ZXJ3ICsgcGwgKyAxMDsKKyAgICAgIGlmICh4MSA8IHNjcmVlbmxlZnQgKyBndXR0ZXJ3IHx8IGF0TGVmdCkgeworICAgICAgICBpZiAoYXRMZWZ0KSB4MSA9IDA7CisgICAgICAgIHNjcm9sbGVyLnNjcm9sbExlZnQgPSBNYXRoLm1heCgwLCB4MSAtIDEwIC0gZ3V0dGVydyk7CisgICAgICAgIHNjcm9sbGVkID0gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIGVsc2UgaWYgKHgyID4gc2NyZWVudyArIHNjcmVlbmxlZnQgLSAzKSB7CisgICAgICAgIHNjcm9sbGVyLnNjcm9sbExlZnQgPSB4MiArIDEwIC0gc2NyZWVudzsKKyAgICAgICAgc2Nyb2xsZWQgPSB0cnVlOworICAgICAgICBpZiAoeDIgPiBjb2RlLmNsaWVudFdpZHRoKSByZXN1bHQgPSBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGlmIChzY3JvbGxlZCAmJiBvcHRpb25zLm9uU2Nyb2xsKSBvcHRpb25zLm9uU2Nyb2xsKGluc3RhbmNlKTsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgZnVuY3Rpb24gdmlzaWJsZUxpbmVzKCkgeworICAgICAgdmFyIGxoID0gdGV4dEhlaWdodCgpLCB0b3AgPSBzY3JvbGxlci5zY3JvbGxUb3AgLSBwYWRkaW5nVG9wKCk7CisgICAgICB2YXIgZnJvbUhlaWdodCA9IE1hdGgubWF4KDAsIE1hdGguZmxvb3IodG9wIC8gbGgpKTsKKyAgICAgIHZhciB0b0hlaWdodCA9IE1hdGguY2VpbCgodG9wICsgc2Nyb2xsZXIuY2xpZW50SGVpZ2h0KSAvIGxoKTsKKyAgICAgIHJldHVybiB7ZnJvbTogbGluZUF0SGVpZ2h0KGRvYywgZnJvbUhlaWdodCksCisgICAgICAgICAgICAgIHRvOiBsaW5lQXRIZWlnaHQoZG9jLCB0b0hlaWdodCl9OworICAgIH0KKyAgICAvLyBVc2VzIGEgc2V0IG9mIGNoYW5nZXMgcGx1cyB0aGUgY3VycmVudCBzY3JvbGwgcG9zaXRpb24gdG8KKyAgICAvLyBkZXRlcm1pbmUgd2hpY2ggRE9NIHVwZGF0ZXMgaGF2ZSB0byBiZSBtYWRlLCBhbmQgbWFrZXMgdGhlCisgICAgLy8gdXBkYXRlcy4KKyAgICBmdW5jdGlvbiB1cGRhdGVEaXNwbGF5KGNoYW5nZXMsIHN1cHByZXNzQ2FsbGJhY2spIHsKKyAgICAgIGlmICghc2Nyb2xsZXIuY2xpZW50V2lkdGgpIHsKKyAgICAgICAgc2hvd2luZ0Zyb20gPSBzaG93aW5nVG8gPSBkaXNwbGF5T2Zmc2V0ID0gMDsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgLy8gQ29tcHV0ZSB0aGUgbmV3IHZpc2libGUgd2luZG93CisgICAgICB2YXIgdmlzaWJsZSA9IHZpc2libGVMaW5lcygpOworICAgICAgLy8gQmFpbCBvdXQgaWYgdGhlIHZpc2libGUgYXJlYSBpcyBhbHJlYWR5IHJlbmRlcmVkIGFuZCBub3RoaW5nIGNoYW5nZWQuCisgICAgICBpZiAoY2hhbmdlcyAhPT0gdHJ1ZSAmJiBjaGFuZ2VzLmxlbmd0aCA9PSAwICYmIHZpc2libGUuZnJvbSA+IHNob3dpbmdGcm9tICYmIHZpc2libGUudG8gPCBzaG93aW5nVG8pIHJldHVybjsKKyAgICAgIHZhciBmcm9tID0gTWF0aC5tYXgodmlzaWJsZS5mcm9tIC0gMTAwLCAwKSwgdG8gPSBNYXRoLm1pbihkb2Muc2l6ZSwgdmlzaWJsZS50byArIDEwMCk7CisgICAgICBpZiAoc2hvd2luZ0Zyb20gPCBmcm9tICYmIGZyb20gLSBzaG93aW5nRnJvbSA8IDIwKSBmcm9tID0gc2hvd2luZ0Zyb207CisgICAgICBpZiAoc2hvd2luZ1RvID4gdG8gJiYgc2hvd2luZ1RvIC0gdG8gPCAyMCkgdG8gPSBNYXRoLm1pbihkb2Muc2l6ZSwgc2hvd2luZ1RvKTsKKworICAgICAgLy8gQ3JlYXRlIGEgcmFuZ2Ugb2YgdGhlb3JldGljYWxseSBpbnRhY3QgbGluZXMsIGFuZCBwdW5jaCBob2xlcworICAgICAgLy8gaW4gdGhhdCB1c2luZyB0aGUgY2hhbmdlIGluZm8uCisgICAgICB2YXIgaW50YWN0ID0gY2hhbmdlcyA9PT0gdHJ1ZSA/IFtdIDoKKyAgICAgICAgY29tcHV0ZUludGFjdChbe2Zyb206IHNob3dpbmdGcm9tLCB0bzogc2hvd2luZ1RvLCBkb21TdGFydDogMH1dLCBjaGFuZ2VzKTsKKyAgICAgIC8vIENsaXAgb2ZmIHRoZSBwYXJ0cyB0aGF0IHdvbid0IGJlIHZpc2libGUKKyAgICAgIHZhciBpbnRhY3RMaW5lcyA9IDA7CisgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGludGFjdC5sZW5ndGg7ICsraSkgeworICAgICAgICB2YXIgcmFuZ2UgPSBpbnRhY3RbaV07CisgICAgICAgIGlmIChyYW5nZS5mcm9tIDwgZnJvbSkge3JhbmdlLmRvbVN0YXJ0ICs9IChmcm9tIC0gcmFuZ2UuZnJvbSk7IHJhbmdlLmZyb20gPSBmcm9tO30KKyAgICAgICAgaWYgKHJhbmdlLnRvID4gdG8pIHJhbmdlLnRvID0gdG87CisgICAgICAgIGlmIChyYW5nZS5mcm9tID49IHJhbmdlLnRvKSBpbnRhY3Quc3BsaWNlKGktLSwgMSk7CisgICAgICAgIGVsc2UgaW50YWN0TGluZXMgKz0gcmFuZ2UudG8gLSByYW5nZS5mcm9tOworICAgICAgfQorICAgICAgaWYgKGludGFjdExpbmVzID09IHRvIC0gZnJvbSAmJiBmcm9tID09IHNob3dpbmdGcm9tICYmIHRvID09IHNob3dpbmdUbykgcmV0dXJuOworICAgICAgaW50YWN0LnNvcnQoZnVuY3Rpb24oYSwgYikge3JldHVybiBhLmRvbVN0YXJ0IC0gYi5kb21TdGFydDt9KTsKKworICAgICAgdmFyIHRoID0gdGV4dEhlaWdodCgpLCBndXR0ZXJEaXNwbGF5ID0gZ3V0dGVyLnN0eWxlLmRpc3BsYXk7CisgICAgICBsaW5lRGl2LnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7CisgICAgICBwYXRjaERpc3BsYXkoZnJvbSwgdG8sIGludGFjdCk7CisgICAgICBsaW5lRGl2LnN0eWxlLmRpc3BsYXkgPSBndXR0ZXIuc3R5bGUuZGlzcGxheSA9ICIiOworCisgICAgICAvLyBQb3NpdGlvbiB0aGUgbW92ZXIgZGl2IHRvIGFsaWduIHdpdGggdGhlIGxpbmVzIGl0J3Mgc3VwcG9zZWQKKyAgICAgIC8vIHRvIGJlIHNob3dpbmcgKHdoaWNoIHdpbGwgY292ZXIgdGhlIHZpc2libGUgZGlzcGxheSkKKyAgICAgIHZhciBkaWZmZXJlbnQgPSBmcm9tICE9IHNob3dpbmdGcm9tIHx8IHRvICE9IHNob3dpbmdUbyB8fCBsYXN0U2l6ZUMgIT0gc2Nyb2xsZXIuY2xpZW50SGVpZ2h0ICsgdGg7CisgICAgICAvLyBUaGlzIGlzIGp1c3QgYSBib2d1cyBmb3JtdWxhIHRoYXQgZGV0ZWN0cyB3aGVuIHRoZSBlZGl0b3IgaXMKKyAgICAgIC8vIHJlc2l6ZWQgb3IgdGhlIGZvbnQgc2l6ZSBjaGFuZ2VzLgorICAgICAgaWYgKGRpZmZlcmVudCkgbGFzdFNpemVDID0gc2Nyb2xsZXIuY2xpZW50SGVpZ2h0ICsgdGg7CisgICAgICBzaG93aW5nRnJvbSA9IGZyb207IHNob3dpbmdUbyA9IHRvOworICAgICAgZGlzcGxheU9mZnNldCA9IGhlaWdodEF0TGluZShkb2MsIGZyb20pOworICAgICAgbW92ZXIuc3R5bGUudG9wID0gKGRpc3BsYXlPZmZzZXQgKiB0aCkgKyAicHgiOworICAgICAgaWYgKHNjcm9sbGVyLmNsaWVudEhlaWdodCkKKyAgICAgICAgY29kZS5zdHlsZS5oZWlnaHQgPSAoZG9jLmhlaWdodCAqIHRoICsgMiAqIHBhZGRpbmdUb3AoKSkgKyAicHgiOworCisgICAgICAvLyBTaW5jZSB0aGlzIGlzIGFsbCByYXRoZXIgZXJyb3IgcHJvbmUsIGl0IGlzIGhvbm91cmVkIHdpdGggdGhlCisgICAgICAvLyBvbmx5IGFzc2VydGlvbiBpbiB0aGUgd2hvbGUgZmlsZS4KKyAgICAgIGlmIChsaW5lRGl2LmNoaWxkTm9kZXMubGVuZ3RoICE9IHNob3dpbmdUbyAtIHNob3dpbmdGcm9tKQorICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkJBRCBQQVRDSCEgIiArIEpTT04uc3RyaW5naWZ5KGludGFjdCkgKyAiIHNpemU9IiArIChzaG93aW5nVG8gLSBzaG93aW5nRnJvbSkgKworICAgICAgICAgICAgICAgICAgICAgICAgIiBub2Rlcz0iICsgbGluZURpdi5jaGlsZE5vZGVzLmxlbmd0aCk7CisKKyAgICAgIGZ1bmN0aW9uIGNoZWNrSGVpZ2h0cygpIHsKKyAgICAgICAgbWF4V2lkdGggPSBzY3JvbGxlci5jbGllbnRXaWR0aDsKKyAgICAgICAgdmFyIGN1ck5vZGUgPSBsaW5lRGl2LmZpcnN0Q2hpbGQsIGhlaWdodENoYW5nZWQgPSBmYWxzZTsKKyAgICAgICAgZG9jLml0ZXIoc2hvd2luZ0Zyb20sIHNob3dpbmdUbywgZnVuY3Rpb24obGluZSkgeworICAgICAgICAgIGlmICghbGluZS5oaWRkZW4pIHsKKyAgICAgICAgICAgIHZhciBoZWlnaHQgPSBNYXRoLnJvdW5kKGN1ck5vZGUub2Zmc2V0SGVpZ2h0IC8gdGgpIHx8IDE7CisgICAgICAgICAgICBpZiAobGluZS5oZWlnaHQgIT0gaGVpZ2h0KSB7CisgICAgICAgICAgICAgIHVwZGF0ZUxpbmVIZWlnaHQobGluZSwgaGVpZ2h0KTsKKyAgICAgICAgICAgICAgZ3V0dGVyRGlydHkgPSBoZWlnaHRDaGFuZ2VkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgY3VyTm9kZSA9IGN1ck5vZGUubmV4dFNpYmxpbmc7CisgICAgICAgIH0pOworICAgICAgICBpZiAoaGVpZ2h0Q2hhbmdlZCkKKyAgICAgICAgICBjb2RlLnN0eWxlLmhlaWdodCA9IChkb2MuaGVpZ2h0ICogdGggKyAyICogcGFkZGluZ1RvcCgpKSArICJweCI7CisgICAgICAgIHJldHVybiBoZWlnaHRDaGFuZ2VkOworICAgICAgfQorCisgICAgICBpZiAob3B0aW9ucy5saW5lV3JhcHBpbmcpIHsKKyAgICAgICAgY2hlY2tIZWlnaHRzKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAobWF4V2lkdGggPT0gbnVsbCkgbWF4V2lkdGggPSBzdHJpbmdXaWR0aChtYXhMaW5lKTsKKyAgICAgICAgaWYgKG1heFdpZHRoID4gc2Nyb2xsZXIuY2xpZW50V2lkdGgpIHsKKyAgICAgICAgICBsaW5lU3BhY2Uuc3R5bGUud2lkdGggPSBtYXhXaWR0aCArICJweCI7CisgICAgICAgICAgLy8gTmVlZGVkIHRvIHByZXZlbnQgb2RkIHdyYXBwaW5nL2hpZGluZyBvZiB3aWRnZXRzIHBsYWNlZCBpbiBoZXJlLgorICAgICAgICAgIGNvZGUuc3R5bGUud2lkdGggPSAiIjsKKyAgICAgICAgICBjb2RlLnN0eWxlLndpZHRoID0gc2Nyb2xsZXIuc2Nyb2xsV2lkdGggKyAicHgiOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGxpbmVTcGFjZS5zdHlsZS53aWR0aCA9IGNvZGUuc3R5bGUud2lkdGggPSAiIjsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBndXR0ZXIuc3R5bGUuZGlzcGxheSA9IGd1dHRlckRpc3BsYXk7CisgICAgICBpZiAoZGlmZmVyZW50IHx8IGd1dHRlckRpcnR5KSB7CisgICAgICAgIC8vIElmIHRoZSBndXR0ZXIgZ3JldyBpbiBzaXplLCByZS1jaGVjayBoZWlnaHRzLiBJZiB0aG9zZSBjaGFuZ2VkLCByZS1kcmF3IGd1dHRlci4KKyAgICAgICAgdXBkYXRlR3V0dGVyKCkgJiYgb3B0aW9ucy5saW5lV3JhcHBpbmcgJiYgY2hlY2tIZWlnaHRzKCkgJiYgdXBkYXRlR3V0dGVyKCk7CisgICAgICB9CisgICAgICB1cGRhdGVTZWxlY3Rpb24oKTsKKyAgICAgIGlmICghc3VwcHJlc3NDYWxsYmFjayAmJiBvcHRpb25zLm9uVXBkYXRlKSBvcHRpb25zLm9uVXBkYXRlKGluc3RhbmNlKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIGZ1bmN0aW9uIGNvbXB1dGVJbnRhY3QoaW50YWN0LCBjaGFuZ2VzKSB7CisgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGNoYW5nZXMubGVuZ3RoIHx8IDA7IGkgPCBsOyArK2kpIHsKKyAgICAgICAgdmFyIGNoYW5nZSA9IGNoYW5nZXNbaV0sIGludGFjdDIgPSBbXSwgZGlmZiA9IGNoYW5nZS5kaWZmIHx8IDA7CisgICAgICAgIGZvciAodmFyIGogPSAwLCBsMiA9IGludGFjdC5sZW5ndGg7IGogPCBsMjsgKytqKSB7CisgICAgICAgICAgdmFyIHJhbmdlID0gaW50YWN0W2pdOworICAgICAgICAgIGlmIChjaGFuZ2UudG8gPD0gcmFuZ2UuZnJvbSAmJiBjaGFuZ2UuZGlmZikKKyAgICAgICAgICAgIGludGFjdDIucHVzaCh7ZnJvbTogcmFuZ2UuZnJvbSArIGRpZmYsIHRvOiByYW5nZS50byArIGRpZmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbVN0YXJ0OiByYW5nZS5kb21TdGFydH0pOworICAgICAgICAgIGVsc2UgaWYgKGNoYW5nZS50byA8PSByYW5nZS5mcm9tIHx8IGNoYW5nZS5mcm9tID49IHJhbmdlLnRvKQorICAgICAgICAgICAgaW50YWN0Mi5wdXNoKHJhbmdlKTsKKyAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGlmIChjaGFuZ2UuZnJvbSA+IHJhbmdlLmZyb20pCisgICAgICAgICAgICAgIGludGFjdDIucHVzaCh7ZnJvbTogcmFuZ2UuZnJvbSwgdG86IGNoYW5nZS5mcm9tLCBkb21TdGFydDogcmFuZ2UuZG9tU3RhcnR9KTsKKyAgICAgICAgICAgIGlmIChjaGFuZ2UudG8gPCByYW5nZS50bykKKyAgICAgICAgICAgICAgaW50YWN0Mi5wdXNoKHtmcm9tOiBjaGFuZ2UudG8gKyBkaWZmLCB0bzogcmFuZ2UudG8gKyBkaWZmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbVN0YXJ0OiByYW5nZS5kb21TdGFydCArIChjaGFuZ2UudG8gLSByYW5nZS5mcm9tKX0pOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpbnRhY3QgPSBpbnRhY3QyOworICAgICAgfQorICAgICAgcmV0dXJuIGludGFjdDsKKyAgICB9CisKKyAgICBmdW5jdGlvbiBwYXRjaERpc3BsYXkoZnJvbSwgdG8sIGludGFjdCkgeworICAgICAgLy8gVGhlIGZpcnN0IHBhc3MgcmVtb3ZlcyB0aGUgRE9NIG5vZGVzIHRoYXQgYXJlbid0IGludGFjdC4KKyAgICAgIGlmICghaW50YWN0Lmxlbmd0aCkgbGluZURpdi5pbm5lckhUTUwgPSAiIjsKKyAgICAgIGVsc2UgeworICAgICAgICBmdW5jdGlvbiBraWxsTm9kZShub2RlKSB7CisgICAgICAgICAgdmFyIHRtcCA9IG5vZGUubmV4dFNpYmxpbmc7CisgICAgICAgICAgbm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG5vZGUpOworICAgICAgICAgIHJldHVybiB0bXA7CisgICAgICAgIH0KKyAgICAgICAgdmFyIGRvbVBvcyA9IDAsIGN1ck5vZGUgPSBsaW5lRGl2LmZpcnN0Q2hpbGQsIG47CisgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW50YWN0Lmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgdmFyIGN1ciA9IGludGFjdFtpXTsKKyAgICAgICAgICB3aGlsZSAoY3VyLmRvbVN0YXJ0ID4gZG9tUG9zKSB7Y3VyTm9kZSA9IGtpbGxOb2RlKGN1ck5vZGUpOyBkb21Qb3MrKzt9CisgICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGUgPSBjdXIudG8gLSBjdXIuZnJvbTsgaiA8IGU7ICsraikge2N1ck5vZGUgPSBjdXJOb2RlLm5leHRTaWJsaW5nOyBkb21Qb3MrKzt9CisgICAgICAgIH0KKyAgICAgICAgd2hpbGUgKGN1ck5vZGUpIGN1ck5vZGUgPSBraWxsTm9kZShjdXJOb2RlKTsKKyAgICAgIH0KKyAgICAgIC8vIFRoaXMgcGFzcyBmaWxscyBpbiB0aGUgbGluZXMgdGhhdCBhY3R1YWxseSBjaGFuZ2VkLgorICAgICAgdmFyIG5leHRJbnRhY3QgPSBpbnRhY3Quc2hpZnQoKSwgY3VyTm9kZSA9IGxpbmVEaXYuZmlyc3RDaGlsZCwgaiA9IGZyb207CisgICAgICB2YXIgc2NyYXRjaCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpOworICAgICAgZG9jLml0ZXIoZnJvbSwgdG8sIGZ1bmN0aW9uKGxpbmUpIHsKKyAgICAgICAgaWYgKG5leHRJbnRhY3QgJiYgbmV4dEludGFjdC50byA9PSBqKSBuZXh0SW50YWN0ID0gaW50YWN0LnNoaWZ0KCk7CisgICAgICAgIGlmICghbmV4dEludGFjdCB8fCBuZXh0SW50YWN0LmZyb20gPiBqKSB7CisgICAgICAgICAgaWYgKGxpbmUuaGlkZGVuKSB2YXIgaHRtbCA9IHNjcmF0Y2guaW5uZXJIVE1MID0gIjxwcmU+PC9wcmU+IjsKKyAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIHZhciBodG1sID0gJzxwcmUnICsgKGxpbmUuY2xhc3NOYW1lID8gJyBjbGFzcz0iJyArIGxpbmUuY2xhc3NOYW1lICsgJyInIDogJycpICsgJz4nCisgICAgICAgICAgICAgICsgbGluZS5nZXRIVE1MKG1ha2VUYWIpICsgJzwvcHJlPic7CisgICAgICAgICAgICAvLyBLbHVkZ2UgdG8gbWFrZSBzdXJlIHRoZSBzdHlsZWQgZWxlbWVudCBsaWVzIGJlaGluZCB0aGUgc2VsZWN0aW9uIChieSB6LWluZGV4KQorICAgICAgICAgICAgaWYgKGxpbmUuYmdDbGFzc05hbWUpCisgICAgICAgICAgICAgIGh0bWwgPSAnPGRpdiBzdHlsZT0icG9zaXRpb246IHJlbGF0aXZlIj48cHJlIGNsYXNzPSInICsgbGluZS5iZ0NsYXNzTmFtZSArCisgICAgICAgICAgICAgICciIHN0eWxlPSJwb3NpdGlvbjogYWJzb2x1dGU7IGxlZnQ6IDA7IHJpZ2h0OiAwOyB0b3A6IDA7IGJvdHRvbTogMDsgei1pbmRleDogLTIiPiYjMTYwOzwvcHJlPicgKyBodG1sICsgIjwvZGl2PiI7CisgICAgICAgICAgfQorICAgICAgICAgIHNjcmF0Y2guaW5uZXJIVE1MID0gaHRtbDsKKyAgICAgICAgICBsaW5lRGl2Lmluc2VydEJlZm9yZShzY3JhdGNoLmZpcnN0Q2hpbGQsIGN1ck5vZGUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGN1ck5vZGUgPSBjdXJOb2RlLm5leHRTaWJsaW5nOworICAgICAgICB9CisgICAgICAgICsrajsKKyAgICAgIH0pOworICAgIH0KKworICAgIGZ1bmN0aW9uIHVwZGF0ZUd1dHRlcigpIHsKKyAgICAgIGlmICghb3B0aW9ucy5ndXR0ZXIgJiYgIW9wdGlvbnMubGluZU51bWJlcnMpIHJldHVybjsKKyAgICAgIHZhciBoVGV4dCA9IG1vdmVyLm9mZnNldEhlaWdodCwgaEVkaXRvciA9IHNjcm9sbGVyLmNsaWVudEhlaWdodDsKKyAgICAgIGd1dHRlci5zdHlsZS5oZWlnaHQgPSAoaFRleHQgLSBoRWRpdG9yIDwgMiA/IGhFZGl0b3IgOiBoVGV4dCkgKyAicHgiOworICAgICAgdmFyIGh0bWwgPSBbXSwgaSA9IHNob3dpbmdGcm9tLCBub3JtYWxOb2RlOworICAgICAgZG9jLml0ZXIoc2hvd2luZ0Zyb20sIE1hdGgubWF4KHNob3dpbmdUbywgc2hvd2luZ0Zyb20gKyAxKSwgZnVuY3Rpb24obGluZSkgeworICAgICAgICBpZiAobGluZS5oaWRkZW4pIHsKKyAgICAgICAgICBodG1sLnB1c2goIjxwcmU+PC9wcmU+Iik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgdmFyIG1hcmtlciA9IGxpbmUuZ3V0dGVyTWFya2VyOworICAgICAgICAgIHZhciB0ZXh0ID0gb3B0aW9ucy5saW5lTnVtYmVycyA/IGkgKyBvcHRpb25zLmZpcnN0TGluZU51bWJlciA6IG51bGw7CisgICAgICAgICAgaWYgKG1hcmtlciAmJiBtYXJrZXIudGV4dCkKKyAgICAgICAgICAgIHRleHQgPSBtYXJrZXIudGV4dC5yZXBsYWNlKCIlTiUiLCB0ZXh0ICE9IG51bGwgPyB0ZXh0IDogIiIpOworICAgICAgICAgIGVsc2UgaWYgKHRleHQgPT0gbnVsbCkKKyAgICAgICAgICAgIHRleHQgPSAiXHUwMGEwIjsKKyAgICAgICAgICBodG1sLnB1c2goKG1hcmtlciAmJiBtYXJrZXIuc3R5bGUgPyAnPHByZSBjbGFzcz0iJyArIG1hcmtlci5zdHlsZSArICciPicgOiAiPHByZT4iKSwgdGV4dCk7CisgICAgICAgICAgZm9yICh2YXIgaiA9IDE7IGogPCBsaW5lLmhlaWdodDsgKytqKSBodG1sLnB1c2goIjxici8+JiMxNjA7Iik7CisgICAgICAgICAgaHRtbC5wdXNoKCI8L3ByZT4iKTsKKyAgICAgICAgICBpZiAoIW1hcmtlcikgbm9ybWFsTm9kZSA9IGk7CisgICAgICAgIH0KKyAgICAgICAgKytpOworICAgICAgfSk7CisgICAgICBndXR0ZXIuc3R5bGUuZGlzcGxheSA9ICJub25lIjsKKyAgICAgIGd1dHRlclRleHQuaW5uZXJIVE1MID0gaHRtbC5qb2luKCIiKTsKKyAgICAgIC8vIE1ha2Ugc3VyZSBzY3JvbGxpbmcgZG9lc24ndCBjYXVzZSBudW1iZXIgZ3V0dGVyIHNpemUgdG8gcG9wCisgICAgICBpZiAobm9ybWFsTm9kZSAhPSBudWxsKSB7CisgICAgICAgIHZhciBub2RlID0gZ3V0dGVyVGV4dC5jaGlsZE5vZGVzW25vcm1hbE5vZGUgLSBzaG93aW5nRnJvbV07CisgICAgICAgIHZhciBtaW53aWR0aCA9IFN0cmluZyhkb2Muc2l6ZSkubGVuZ3RoLCB2YWwgPSBlbHRUZXh0KG5vZGUpLCBwYWQgPSAiIjsKKyAgICAgICAgd2hpbGUgKHZhbC5sZW5ndGggKyBwYWQubGVuZ3RoIDwgbWlud2lkdGgpIHBhZCArPSAiXHUwMGEwIjsKKyAgICAgICAgaWYgKHBhZCkgbm9kZS5pbnNlcnRCZWZvcmUoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUocGFkKSwgbm9kZS5maXJzdENoaWxkKTsKKyAgICAgIH0KKyAgICAgIGd1dHRlci5zdHlsZS5kaXNwbGF5ID0gIiI7CisgICAgICB2YXIgcmVzaXplZCA9IE1hdGguYWJzKChwYXJzZUludChsaW5lU3BhY2Uuc3R5bGUubWFyZ2luTGVmdCkgfHwgMCkgLSBndXR0ZXIub2Zmc2V0V2lkdGgpID4gMjsKKyAgICAgIGxpbmVTcGFjZS5zdHlsZS5tYXJnaW5MZWZ0ID0gZ3V0dGVyLm9mZnNldFdpZHRoICsgInB4IjsKKyAgICAgIGd1dHRlckRpcnR5ID0gZmFsc2U7CisgICAgICByZXR1cm4gcmVzaXplZDsKKyAgICB9CisgICAgZnVuY3Rpb24gdXBkYXRlU2VsZWN0aW9uKCkgeworICAgICAgdmFyIGNvbGxhcHNlZCA9IHBvc0VxKHNlbC5mcm9tLCBzZWwudG8pOworICAgICAgdmFyIGZyb21Qb3MgPSBsb2NhbENvb3JkcyhzZWwuZnJvbSwgdHJ1ZSk7CisgICAgICB2YXIgdG9Qb3MgPSBjb2xsYXBzZWQgPyBmcm9tUG9zIDogbG9jYWxDb29yZHMoc2VsLnRvLCB0cnVlKTsKKyAgICAgIHZhciBoZWFkUG9zID0gc2VsLmludmVydGVkID8gZnJvbVBvcyA6IHRvUG9zLCB0aCA9IHRleHRIZWlnaHQoKTsKKyAgICAgIHZhciB3cmFwT2ZmID0gZWx0T2Zmc2V0KHdyYXBwZXIpLCBsaW5lT2ZmID0gZWx0T2Zmc2V0KGxpbmVEaXYpOworICAgICAgaW5wdXREaXYuc3R5bGUudG9wID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oc2Nyb2xsZXIub2Zmc2V0SGVpZ2h0LCBoZWFkUG9zLnkgKyBsaW5lT2ZmLnRvcCAtIHdyYXBPZmYudG9wKSkgKyAicHgiOworICAgICAgaW5wdXREaXYuc3R5bGUubGVmdCA9IE1hdGgubWF4KDAsIE1hdGgubWluKHNjcm9sbGVyLm9mZnNldFdpZHRoLCBoZWFkUG9zLnggKyBsaW5lT2ZmLmxlZnQgLSB3cmFwT2ZmLmxlZnQpKSArICJweCI7CisgICAgICBpZiAoY29sbGFwc2VkKSB7CisgICAgICAgIGN1cnNvci5zdHlsZS50b3AgPSBoZWFkUG9zLnkgKyAicHgiOworICAgICAgICBjdXJzb3Iuc3R5bGUubGVmdCA9IChvcHRpb25zLmxpbmVXcmFwcGluZyA/IE1hdGgubWluKGhlYWRQb3MueCwgbGluZVNwYWNlLm9mZnNldFdpZHRoKSA6IGhlYWRQb3MueCkgKyAicHgiOworICAgICAgICBjdXJzb3Iuc3R5bGUuZGlzcGxheSA9ICIiOworICAgICAgICBzZWxlY3Rpb25EaXYuc3R5bGUuZGlzcGxheSA9ICJub25lIjsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHZhciBzYW1lTGluZSA9IGZyb21Qb3MueSA9PSB0b1Bvcy55LCBodG1sID0gIiI7CisgICAgICAgIHZhciBjbGllbnRXaWR0aCA9IGxpbmVTcGFjZS5jbGllbnRXaWR0aCB8fCBsaW5lU3BhY2Uub2Zmc2V0V2lkdGg7CisgICAgICAgIHZhciBjbGllbnRIZWlnaHQgPSBsaW5lU3BhY2UuY2xpZW50SGVpZ2h0IHx8IGxpbmVTcGFjZS5vZmZzZXRIZWlnaHQ7CisgICAgICAgIGZ1bmN0aW9uIGFkZChsZWZ0LCB0b3AsIHJpZ2h0LCBoZWlnaHQpIHsKKyAgICAgICAgICB2YXIgcnN0eWxlID0gcXVpcmtzTW9kZSA/ICJ3aWR0aDogIiArICghcmlnaHQgPyBjbGllbnRXaWR0aCA6IGNsaWVudFdpZHRoIC0gcmlnaHQgLSBsZWZ0KSArICJweCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICJyaWdodDogIiArIHJpZ2h0ICsgInB4IjsKKyAgICAgICAgICBodG1sICs9ICc8ZGl2IGNsYXNzPSJDb2RlTWlycm9yLXNlbGVjdGVkIiBzdHlsZT0icG9zaXRpb246IGFic29sdXRlOyBsZWZ0OiAnICsgbGVmdCArCisgICAgICAgICAgICAncHg7IHRvcDogJyArIHRvcCArICdweDsgJyArIHJzdHlsZSArICc7IGhlaWdodDogJyArIGhlaWdodCArICdweCI+PC9kaXY+JzsKKyAgICAgICAgfQorICAgICAgICBpZiAoc2VsLmZyb20uY2ggJiYgZnJvbVBvcy55ID49IDApIHsKKyAgICAgICAgICB2YXIgcmlnaHQgPSBzYW1lTGluZSA/IGNsaWVudFdpZHRoIC0gdG9Qb3MueCA6IDA7CisgICAgICAgICAgYWRkKGZyb21Qb3MueCwgZnJvbVBvcy55LCByaWdodCwgdGgpOworICAgICAgICB9CisgICAgICAgIHZhciBtaWRkbGVTdGFydCA9IE1hdGgubWF4KDAsIGZyb21Qb3MueSArIChzZWwuZnJvbS5jaCA/IHRoIDogMCkpOworICAgICAgICB2YXIgbWlkZGxlSGVpZ2h0ID0gTWF0aC5taW4odG9Qb3MueSwgY2xpZW50SGVpZ2h0KSAtIG1pZGRsZVN0YXJ0OworICAgICAgICBpZiAobWlkZGxlSGVpZ2h0ID4gMC4yICogdGgpCisgICAgICAgICAgYWRkKDAsIG1pZGRsZVN0YXJ0LCAwLCBtaWRkbGVIZWlnaHQpOworICAgICAgICBpZiAoKCFzYW1lTGluZSB8fCAhc2VsLmZyb20uY2gpICYmIHRvUG9zLnkgPCBjbGllbnRIZWlnaHQgLSAuNSAqIHRoKQorICAgICAgICAgIGFkZCgwLCB0b1Bvcy55LCBjbGllbnRXaWR0aCAtIHRvUG9zLngsIHRoKTsKKyAgICAgICAgc2VsZWN0aW9uRGl2LmlubmVySFRNTCA9IGh0bWw7CisgICAgICAgIGN1cnNvci5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOworICAgICAgICBzZWxlY3Rpb25EaXYuc3R5bGUuZGlzcGxheSA9ICIiOworICAgICAgfQorICAgIH0KKworICAgIGZ1bmN0aW9uIHNldFNoaWZ0KHZhbCkgeworICAgICAgaWYgKHZhbCkgc2hpZnRTZWxlY3RpbmcgPSBzaGlmdFNlbGVjdGluZyB8fCAoc2VsLmludmVydGVkID8gc2VsLnRvIDogc2VsLmZyb20pOworICAgICAgZWxzZSBzaGlmdFNlbGVjdGluZyA9IG51bGw7CisgICAgfQorICAgIGZ1bmN0aW9uIHNldFNlbGVjdGlvblVzZXIoZnJvbSwgdG8pIHsKKyAgICAgIHZhciBzaCA9IHNoaWZ0U2VsZWN0aW5nICYmIGNsaXBQb3Moc2hpZnRTZWxlY3RpbmcpOworICAgICAgaWYgKHNoKSB7CisgICAgICAgIGlmIChwb3NMZXNzKHNoLCBmcm9tKSkgZnJvbSA9IHNoOworICAgICAgICBlbHNlIGlmIChwb3NMZXNzKHRvLCBzaCkpIHRvID0gc2g7CisgICAgICB9CisgICAgICBzZXRTZWxlY3Rpb24oZnJvbSwgdG8pOworICAgICAgdXNlclNlbENoYW5nZSA9IHRydWU7CisgICAgfQorICAgIC8vIFVwZGF0ZSB0aGUgc2VsZWN0aW9uLiBMYXN0IHR3byBhcmdzIGFyZSBvbmx5IHVzZWQgYnkKKyAgICAvLyB1cGRhdGVMaW5lcywgc2luY2UgdGhleSBoYXZlIHRvIGJlIGV4cHJlc3NlZCBpbiB0aGUgbGluZQorICAgIC8vIG51bWJlcnMgYmVmb3JlIHRoZSB1cGRhdGUuCisgICAgZnVuY3Rpb24gc2V0U2VsZWN0aW9uKGZyb20sIHRvLCBvbGRGcm9tLCBvbGRUbykgeworICAgICAgZ29hbENvbHVtbiA9IG51bGw7CisgICAgICBpZiAob2xkRnJvbSA9PSBudWxsKSB7b2xkRnJvbSA9IHNlbC5mcm9tLmxpbmU7IG9sZFRvID0gc2VsLnRvLmxpbmU7fQorICAgICAgaWYgKHBvc0VxKHNlbC5mcm9tLCBmcm9tKSAmJiBwb3NFcShzZWwudG8sIHRvKSkgcmV0dXJuOworICAgICAgaWYgKHBvc0xlc3ModG8sIGZyb20pKSB7dmFyIHRtcCA9IHRvOyB0byA9IGZyb207IGZyb20gPSB0bXA7fQorCisgICAgICAvLyBTa2lwIG92ZXIgaGlkZGVuIGxpbmVzLgorICAgICAgaWYgKGZyb20ubGluZSAhPSBvbGRGcm9tKSB7CisgICAgICAgIHZhciBmcm9tMSA9IHNraXBIaWRkZW4oZnJvbSwgb2xkRnJvbSwgc2VsLmZyb20uY2gpOworICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBub24taGlkZGVuIGxpbmUgbGVmdCwgZm9yY2UgdmlzaWJpbGl0eSBvbiBjdXJyZW50IGxpbmUKKyAgICAgICAgaWYgKCFmcm9tMSkgc2V0TGluZUhpZGRlbihmcm9tLmxpbmUsIGZhbHNlKTsKKyAgICAgICAgZWxzZSBmcm9tID0gZnJvbTE7CisgICAgICB9CisgICAgICBpZiAodG8ubGluZSAhPSBvbGRUbykgdG8gPSBza2lwSGlkZGVuKHRvLCBvbGRUbywgc2VsLnRvLmNoKTsKKworICAgICAgaWYgKHBvc0VxKGZyb20sIHRvKSkgc2VsLmludmVydGVkID0gZmFsc2U7CisgICAgICBlbHNlIGlmIChwb3NFcShmcm9tLCBzZWwudG8pKSBzZWwuaW52ZXJ0ZWQgPSBmYWxzZTsKKyAgICAgIGVsc2UgaWYgKHBvc0VxKHRvLCBzZWwuZnJvbSkpIHNlbC5pbnZlcnRlZCA9IHRydWU7CisKKyAgICAgIGlmIChvcHRpb25zLmF1dG9DbGVhckVtcHR5TGluZXMgJiYgcG9zRXEoc2VsLmZyb20sIHNlbC50bykpIHsKKyAgICAgICAgdmFyIGhlYWQgPSBzZWwuaW52ZXJ0ZWQgPyBmcm9tIDogdG87CisgICAgICAgIGlmIChoZWFkLmxpbmUgIT0gc2VsLmZyb20ubGluZSAmJiBzZWwuZnJvbS5saW5lIDwgZG9jLnNpemUpIHsKKyAgICAgICAgICB2YXIgb2xkTGluZSA9IGdldExpbmUoc2VsLmZyb20ubGluZSk7CisgICAgICAgICAgaWYgKC9eXHMrJC8udGVzdChvbGRMaW5lLnRleHQpKQorICAgICAgICAgICAgc2V0VGltZW91dChvcGVyYXRpb24oZnVuY3Rpb24oKSB7CisgICAgICAgICAgICAgIGlmIChvbGRMaW5lLnBhcmVudCAmJiAvXlxzKyQvLnRlc3Qob2xkTGluZS50ZXh0KSkgeworICAgICAgICAgICAgICAgIHZhciBubyA9IGxpbmVObyhvbGRMaW5lKTsKKyAgICAgICAgICAgICAgICByZXBsYWNlUmFuZ2UoIiIsIHtsaW5lOiBubywgY2g6IDB9LCB7bGluZTogbm8sIGNoOiBvbGRMaW5lLnRleHQubGVuZ3RofSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0sIDEwKSk7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgc2VsLmZyb20gPSBmcm9tOyBzZWwudG8gPSB0bzsKKyAgICAgIHNlbGVjdGlvbkNoYW5nZWQgPSB0cnVlOworICAgIH0KKyAgICBmdW5jdGlvbiBza2lwSGlkZGVuKHBvcywgb2xkTGluZSwgb2xkQ2gpIHsKKyAgICAgIGZ1bmN0aW9uIGdldE5vbkhpZGRlbihkaXIpIHsKKyAgICAgICAgdmFyIGxObyA9IHBvcy5saW5lICsgZGlyLCBlbmQgPSBkaXIgPT0gMSA/IGRvYy5zaXplIDogLTE7CisgICAgICAgIHdoaWxlIChsTm8gIT0gZW5kKSB7CisgICAgICAgICAgdmFyIGxpbmUgPSBnZXRMaW5lKGxObyk7CisgICAgICAgICAgaWYgKCFsaW5lLmhpZGRlbikgeworICAgICAgICAgICAgdmFyIGNoID0gcG9zLmNoOworICAgICAgICAgICAgaWYgKHRvRW5kIHx8IGNoID4gb2xkQ2ggfHwgY2ggPiBsaW5lLnRleHQubGVuZ3RoKSBjaCA9IGxpbmUudGV4dC5sZW5ndGg7CisgICAgICAgICAgICByZXR1cm4ge2xpbmU6IGxObywgY2g6IGNofTsKKyAgICAgICAgICB9CisgICAgICAgICAgbE5vICs9IGRpcjsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgdmFyIGxpbmUgPSBnZXRMaW5lKHBvcy5saW5lKTsKKyAgICAgIHZhciB0b0VuZCA9IHBvcy5jaCA9PSBsaW5lLnRleHQubGVuZ3RoICYmIHBvcy5jaCAhPSBvbGRDaDsKKyAgICAgIGlmICghbGluZS5oaWRkZW4pIHJldHVybiBwb3M7CisgICAgICBpZiAocG9zLmxpbmUgPj0gb2xkTGluZSkgcmV0dXJuIGdldE5vbkhpZGRlbigxKSB8fCBnZXROb25IaWRkZW4oLTEpOworICAgICAgZWxzZSByZXR1cm4gZ2V0Tm9uSGlkZGVuKC0xKSB8fCBnZXROb25IaWRkZW4oMSk7CisgICAgfQorICAgIGZ1bmN0aW9uIHNldEN1cnNvcihsaW5lLCBjaCwgdXNlcikgeworICAgICAgdmFyIHBvcyA9IGNsaXBQb3Moe2xpbmU6IGxpbmUsIGNoOiBjaCB8fCAwfSk7CisgICAgICAodXNlciA/IHNldFNlbGVjdGlvblVzZXIgOiBzZXRTZWxlY3Rpb24pKHBvcywgcG9zKTsKKyAgICB9CisKKyAgICBmdW5jdGlvbiBjbGlwTGluZShuKSB7cmV0dXJuIE1hdGgubWF4KDAsIE1hdGgubWluKG4sIGRvYy5zaXplLTEpKTt9CisgICAgZnVuY3Rpb24gY2xpcFBvcyhwb3MpIHsKKyAgICAgIGlmIChwb3MubGluZSA8IDApIHJldHVybiB7bGluZTogMCwgY2g6IDB9OworICAgICAgaWYgKHBvcy5saW5lID49IGRvYy5zaXplKSByZXR1cm4ge2xpbmU6IGRvYy5zaXplLTEsIGNoOiBnZXRMaW5lKGRvYy5zaXplLTEpLnRleHQubGVuZ3RofTsKKyAgICAgIHZhciBjaCA9IHBvcy5jaCwgbGluZWxlbiA9IGdldExpbmUocG9zLmxpbmUpLnRleHQubGVuZ3RoOworICAgICAgaWYgKGNoID09IG51bGwgfHwgY2ggPiBsaW5lbGVuKSByZXR1cm4ge2xpbmU6IHBvcy5saW5lLCBjaDogbGluZWxlbn07CisgICAgICBlbHNlIGlmIChjaCA8IDApIHJldHVybiB7bGluZTogcG9zLmxpbmUsIGNoOiAwfTsKKyAgICAgIGVsc2UgcmV0dXJuIHBvczsKKyAgICB9CisKKyAgICBmdW5jdGlvbiBmaW5kUG9zSChkaXIsIHVuaXQpIHsKKyAgICAgIHZhciBlbmQgPSBzZWwuaW52ZXJ0ZWQgPyBzZWwuZnJvbSA6IHNlbC50bywgbGluZSA9IGVuZC5saW5lLCBjaCA9IGVuZC5jaDsKKyAgICAgIHZhciBsaW5lT2JqID0gZ2V0TGluZShsaW5lKTsKKyAgICAgIGZ1bmN0aW9uIGZpbmROZXh0TGluZSgpIHsKKyAgICAgICAgZm9yICh2YXIgbCA9IGxpbmUgKyBkaXIsIGUgPSBkaXIgPCAwID8gLTEgOiBkb2Muc2l6ZTsgbCAhPSBlOyBsICs9IGRpcikgeworICAgICAgICAgIHZhciBsbyA9IGdldExpbmUobCk7CisgICAgICAgICAgaWYgKCFsby5oaWRkZW4pIHsgbGluZSA9IGw7IGxpbmVPYmogPSBsbzsgcmV0dXJuIHRydWU7IH0KKyAgICAgICAgfQorICAgICAgfQorICAgICAgZnVuY3Rpb24gbW92ZU9uY2UoYm91bmRUb0xpbmUpIHsKKyAgICAgICAgaWYgKGNoID09IChkaXIgPCAwID8gMCA6IGxpbmVPYmoudGV4dC5sZW5ndGgpKSB7CisgICAgICAgICAgaWYgKCFib3VuZFRvTGluZSAmJiBmaW5kTmV4dExpbmUoKSkgY2ggPSBkaXIgPCAwID8gbGluZU9iai50ZXh0Lmxlbmd0aCA6IDA7CisgICAgICAgICAgZWxzZSByZXR1cm4gZmFsc2U7CisgICAgICAgIH0gZWxzZSBjaCArPSBkaXI7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgICAgaWYgKHVuaXQgPT0gImNoYXIiKSBtb3ZlT25jZSgpOworICAgICAgZWxzZSBpZiAodW5pdCA9PSAiY29sdW1uIikgbW92ZU9uY2UodHJ1ZSk7CisgICAgICBlbHNlIGlmICh1bml0ID09ICJ3b3JkIikgeworICAgICAgICB2YXIgc2F3V29yZCA9IGZhbHNlOworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgaWYgKGRpciA8IDApIGlmICghbW92ZU9uY2UoKSkgYnJlYWs7CisgICAgICAgICAgaWYgKGlzV29yZENoYXIobGluZU9iai50ZXh0LmNoYXJBdChjaCkpKSBzYXdXb3JkID0gdHJ1ZTsKKyAgICAgICAgICBlbHNlIGlmIChzYXdXb3JkKSB7aWYgKGRpciA8IDApIHtkaXIgPSAxOyBtb3ZlT25jZSgpO30gYnJlYWs7fQorICAgICAgICAgIGlmIChkaXIgPiAwKSBpZiAoIW1vdmVPbmNlKCkpIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4ge2xpbmU6IGxpbmUsIGNoOiBjaH07CisgICAgfQorICAgIGZ1bmN0aW9uIG1vdmVIKGRpciwgdW5pdCkgeworICAgICAgdmFyIHBvcyA9IGRpciA8IDAgPyBzZWwuZnJvbSA6IHNlbC50bzsKKyAgICAgIGlmIChzaGlmdFNlbGVjdGluZyB8fCBwb3NFcShzZWwuZnJvbSwgc2VsLnRvKSkgcG9zID0gZmluZFBvc0goZGlyLCB1bml0KTsKKyAgICAgIHNldEN1cnNvcihwb3MubGluZSwgcG9zLmNoLCB0cnVlKTsKKyAgICB9CisgICAgZnVuY3Rpb24gZGVsZXRlSChkaXIsIHVuaXQpIHsKKyAgICAgIGlmICghcG9zRXEoc2VsLmZyb20sIHNlbC50bykpIHJlcGxhY2VSYW5nZSgiIiwgc2VsLmZyb20sIHNlbC50byk7CisgICAgICBlbHNlIGlmIChkaXIgPCAwKSByZXBsYWNlUmFuZ2UoIiIsIGZpbmRQb3NIKGRpciwgdW5pdCksIHNlbC50byk7CisgICAgICBlbHNlIHJlcGxhY2VSYW5nZSgiIiwgc2VsLmZyb20sIGZpbmRQb3NIKGRpciwgdW5pdCkpOworICAgICAgdXNlclNlbENoYW5nZSA9IHRydWU7CisgICAgfQorICAgIHZhciBnb2FsQ29sdW1uID0gbnVsbDsKKyAgICBmdW5jdGlvbiBtb3ZlVihkaXIsIHVuaXQpIHsKKyAgICAgIHZhciBkaXN0ID0gMCwgcG9zID0gbG9jYWxDb29yZHMoc2VsLmludmVydGVkID8gc2VsLmZyb20gOiBzZWwudG8sIHRydWUpOworICAgICAgaWYgKGdvYWxDb2x1bW4gIT0gbnVsbCkgcG9zLnggPSBnb2FsQ29sdW1uOworICAgICAgaWYgKHVuaXQgPT0gInBhZ2UiKSBkaXN0ID0gTWF0aC5taW4oc2Nyb2xsZXIuY2xpZW50SGVpZ2h0LCB3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCk7CisgICAgICBlbHNlIGlmICh1bml0ID09ICJsaW5lIikgZGlzdCA9IHRleHRIZWlnaHQoKTsKKyAgICAgIHZhciB0YXJnZXQgPSBjb29yZHNDaGFyKHBvcy54LCBwb3MueSArIGRpc3QgKiBkaXIgKyAyKTsKKyAgICAgIGlmICh1bml0ID09ICJwYWdlIikgc2Nyb2xsZXIuc2Nyb2xsVG9wICs9IGxvY2FsQ29vcmRzKHRhcmdldCwgdHJ1ZSkueSAtIHBvcy55OworICAgICAgc2V0Q3Vyc29yKHRhcmdldC5saW5lLCB0YXJnZXQuY2gsIHRydWUpOworICAgICAgZ29hbENvbHVtbiA9IHBvcy54OworICAgIH0KKworICAgIGZ1bmN0aW9uIHNlbGVjdFdvcmRBdChwb3MpIHsKKyAgICAgIHZhciBsaW5lID0gZ2V0TGluZShwb3MubGluZSkudGV4dDsKKyAgICAgIHZhciBzdGFydCA9IHBvcy5jaCwgZW5kID0gcG9zLmNoOworICAgICAgd2hpbGUgKHN0YXJ0ID4gMCAmJiBpc1dvcmRDaGFyKGxpbmUuY2hhckF0KHN0YXJ0IC0gMSkpKSAtLXN0YXJ0OworICAgICAgd2hpbGUgKGVuZCA8IGxpbmUubGVuZ3RoICYmIGlzV29yZENoYXIobGluZS5jaGFyQXQoZW5kKSkpICsrZW5kOworICAgICAgc2V0U2VsZWN0aW9uVXNlcih7bGluZTogcG9zLmxpbmUsIGNoOiBzdGFydH0sIHtsaW5lOiBwb3MubGluZSwgY2g6IGVuZH0pOworICAgIH0KKyAgICBmdW5jdGlvbiBzZWxlY3RMaW5lKGxpbmUpIHsKKyAgICAgIHNldFNlbGVjdGlvblVzZXIoe2xpbmU6IGxpbmUsIGNoOiAwfSwgY2xpcFBvcyh7bGluZTogbGluZSArIDEsIGNoOiAwfSkpOworICAgIH0KKyAgICBmdW5jdGlvbiBpbmRlbnRTZWxlY3RlZChtb2RlKSB7CisgICAgICBpZiAocG9zRXEoc2VsLmZyb20sIHNlbC50bykpIHJldHVybiBpbmRlbnRMaW5lKHNlbC5mcm9tLmxpbmUsIG1vZGUpOworICAgICAgdmFyIGUgPSBzZWwudG8ubGluZSAtIChzZWwudG8uY2ggPyAwIDogMSk7CisgICAgICBmb3IgKHZhciBpID0gc2VsLmZyb20ubGluZTsgaSA8PSBlOyArK2kpIGluZGVudExpbmUoaSwgbW9kZSk7CisgICAgfQorCisgICAgZnVuY3Rpb24gaW5kZW50TGluZShuLCBob3cpIHsKKyAgICAgIGlmICghaG93KSBob3cgPSAiYWRkIjsKKyAgICAgIGlmIChob3cgPT0gInNtYXJ0IikgeworICAgICAgICBpZiAoIW1vZGUuaW5kZW50KSBob3cgPSAicHJldiI7CisgICAgICAgIGVsc2UgdmFyIHN0YXRlID0gZ2V0U3RhdGVCZWZvcmUobik7CisgICAgICB9CisKKyAgICAgIHZhciBsaW5lID0gZ2V0TGluZShuKSwgY3VyU3BhY2UgPSBsaW5lLmluZGVudGF0aW9uKG9wdGlvbnMudGFiU2l6ZSksCisgICAgICAgICAgY3VyU3BhY2VTdHJpbmcgPSBsaW5lLnRleHQubWF0Y2goL15ccyovKVswXSwgaW5kZW50YXRpb247CisgICAgICBpZiAoaG93ID09ICJwcmV2IikgeworICAgICAgICBpZiAobikgaW5kZW50YXRpb24gPSBnZXRMaW5lKG4tMSkuaW5kZW50YXRpb24ob3B0aW9ucy50YWJTaXplKTsKKyAgICAgICAgZWxzZSBpbmRlbnRhdGlvbiA9IDA7CisgICAgICB9CisgICAgICBlbHNlIGlmIChob3cgPT0gInNtYXJ0IikgaW5kZW50YXRpb24gPSBtb2RlLmluZGVudChzdGF0ZSwgbGluZS50ZXh0LnNsaWNlKGN1clNwYWNlU3RyaW5nLmxlbmd0aCksIGxpbmUudGV4dCk7CisgICAgICBlbHNlIGlmIChob3cgPT0gImFkZCIpIGluZGVudGF0aW9uID0gY3VyU3BhY2UgKyBvcHRpb25zLmluZGVudFVuaXQ7CisgICAgICBlbHNlIGlmIChob3cgPT0gInN1YnRyYWN0IikgaW5kZW50YXRpb24gPSBjdXJTcGFjZSAtIG9wdGlvbnMuaW5kZW50VW5pdDsKKyAgICAgIGluZGVudGF0aW9uID0gTWF0aC5tYXgoMCwgaW5kZW50YXRpb24pOworICAgICAgdmFyIGRpZmYgPSBpbmRlbnRhdGlvbiAtIGN1clNwYWNlOworCisgICAgICBpZiAoIWRpZmYpIHsKKyAgICAgICAgaWYgKHNlbC5mcm9tLmxpbmUgIT0gbiAmJiBzZWwudG8ubGluZSAhPSBuKSByZXR1cm47CisgICAgICAgIHZhciBpbmRlbnRTdHJpbmcgPSBjdXJTcGFjZVN0cmluZzsKKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICB2YXIgaW5kZW50U3RyaW5nID0gIiIsIHBvcyA9IDA7CisgICAgICAgIGlmIChvcHRpb25zLmluZGVudFdpdGhUYWJzKQorICAgICAgICAgIGZvciAodmFyIGkgPSBNYXRoLmZsb29yKGluZGVudGF0aW9uIC8gb3B0aW9ucy50YWJTaXplKTsgaTsgLS1pKSB7cG9zICs9IG9wdGlvbnMudGFiU2l6ZTsgaW5kZW50U3RyaW5nICs9ICJcdCI7fQorICAgICAgICB3aGlsZSAocG9zIDwgaW5kZW50YXRpb24pIHsrK3BvczsgaW5kZW50U3RyaW5nICs9ICIgIjt9CisgICAgICB9CisKKyAgICAgIHJlcGxhY2VSYW5nZShpbmRlbnRTdHJpbmcsIHtsaW5lOiBuLCBjaDogMH0sIHtsaW5lOiBuLCBjaDogY3VyU3BhY2VTdHJpbmcubGVuZ3RofSk7CisgICAgfQorCisgICAgZnVuY3Rpb24gbG9hZE1vZGUoKSB7CisgICAgICBtb2RlID0gQ29kZU1pcnJvci5nZXRNb2RlKG9wdGlvbnMsIG9wdGlvbnMubW9kZSk7CisgICAgICBkb2MuaXRlcigwLCBkb2Muc2l6ZSwgZnVuY3Rpb24obGluZSkgeyBsaW5lLnN0YXRlQWZ0ZXIgPSBudWxsOyB9KTsKKyAgICAgIHdvcmsgPSBbMF07CisgICAgICBzdGFydFdvcmtlcigpOworICAgIH0KKyAgICBmdW5jdGlvbiBndXR0ZXJDaGFuZ2VkKCkgeworICAgICAgdmFyIHZpc2libGUgPSBvcHRpb25zLmd1dHRlciB8fCBvcHRpb25zLmxpbmVOdW1iZXJzOworICAgICAgZ3V0dGVyLnN0eWxlLmRpc3BsYXkgPSB2aXNpYmxlID8gIiIgOiAibm9uZSI7CisgICAgICBpZiAodmlzaWJsZSkgZ3V0dGVyRGlydHkgPSB0cnVlOworICAgICAgZWxzZSBsaW5lRGl2LnBhcmVudE5vZGUuc3R5bGUubWFyZ2luTGVmdCA9IDA7CisgICAgfQorICAgIGZ1bmN0aW9uIHdyYXBwaW5nQ2hhbmdlZChmcm9tLCB0bykgeworICAgICAgaWYgKG9wdGlvbnMubGluZVdyYXBwaW5nKSB7CisgICAgICAgIHdyYXBwZXIuY2xhc3NOYW1lICs9ICIgQ29kZU1pcnJvci13cmFwIjsKKyAgICAgICAgdmFyIHBlckxpbmUgPSBzY3JvbGxlci5jbGllbnRXaWR0aCAvIGNoYXJXaWR0aCgpIC0gMzsKKyAgICAgICAgZG9jLml0ZXIoMCwgZG9jLnNpemUsIGZ1bmN0aW9uKGxpbmUpIHsKKyAgICAgICAgICBpZiAobGluZS5oaWRkZW4pIHJldHVybjsKKyAgICAgICAgICB2YXIgZ3Vlc3MgPSBNYXRoLmNlaWwobGluZS50ZXh0Lmxlbmd0aCAvIHBlckxpbmUpIHx8IDE7CisgICAgICAgICAgaWYgKGd1ZXNzICE9IDEpIHVwZGF0ZUxpbmVIZWlnaHQobGluZSwgZ3Vlc3MpOworICAgICAgICB9KTsKKyAgICAgICAgbGluZVNwYWNlLnN0eWxlLndpZHRoID0gY29kZS5zdHlsZS53aWR0aCA9ICIiOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgd3JhcHBlci5jbGFzc05hbWUgPSB3cmFwcGVyLmNsYXNzTmFtZS5yZXBsYWNlKCIgQ29kZU1pcnJvci13cmFwIiwgIiIpOworICAgICAgICBtYXhXaWR0aCA9IG51bGw7IG1heExpbmUgPSAiIjsKKyAgICAgICAgZG9jLml0ZXIoMCwgZG9jLnNpemUsIGZ1bmN0aW9uKGxpbmUpIHsKKyAgICAgICAgICBpZiAobGluZS5oZWlnaHQgIT0gMSAmJiAhbGluZS5oaWRkZW4pIHVwZGF0ZUxpbmVIZWlnaHQobGluZSwgMSk7CisgICAgICAgICAgaWYgKGxpbmUudGV4dC5sZW5ndGggPiBtYXhMaW5lLmxlbmd0aCkgbWF4TGluZSA9IGxpbmUudGV4dDsKKyAgICAgICAgfSk7CisgICAgICB9CisgICAgICBjaGFuZ2VzLnB1c2goe2Zyb206IDAsIHRvOiBkb2Muc2l6ZX0pOworICAgIH0KKyAgICBmdW5jdGlvbiBtYWtlVGFiKGNvbCkgeworICAgICAgdmFyIHcgPSBvcHRpb25zLnRhYlNpemUgLSBjb2wgJSBvcHRpb25zLnRhYlNpemUsIGNhY2hlZCA9IHRhYkNhY2hlW3ddOworICAgICAgaWYgKGNhY2hlZCkgcmV0dXJuIGNhY2hlZDsKKyAgICAgIGZvciAodmFyIHN0ciA9ICc8c3BhbiBjbGFzcz0iY20tdGFiIj4nLCBpID0gMDsgaSA8IHc7ICsraSkgc3RyICs9ICIgIjsKKyAgICAgIHJldHVybiAodGFiQ2FjaGVbd10gPSB7aHRtbDogc3RyICsgIjwvc3Bhbj4iLCB3aWR0aDogd30pOworICAgIH0KKyAgICBmdW5jdGlvbiB0aGVtZUNoYW5nZWQoKSB7CisgICAgICBzY3JvbGxlci5jbGFzc05hbWUgPSBzY3JvbGxlci5jbGFzc05hbWUucmVwbGFjZSgvXHMqY20tcy1cUysvZywgIiIpICsKKyAgICAgICAgb3B0aW9ucy50aGVtZS5yZXBsYWNlKC8oXnxccylccyovZywgIiBjbS1zLSIpOworICAgIH0KKworICAgIGZ1bmN0aW9uIFRleHRNYXJrZXIoKSB7IHRoaXMuc2V0ID0gW107IH0KKyAgICBUZXh0TWFya2VyLnByb3RvdHlwZS5jbGVhciA9IG9wZXJhdGlvbihmdW5jdGlvbigpIHsKKyAgICAgIHZhciBtaW4gPSBJbmZpbml0eSwgbWF4ID0gLUluZmluaXR5OworICAgICAgZm9yICh2YXIgaSA9IDAsIGUgPSB0aGlzLnNldC5sZW5ndGg7IGkgPCBlOyArK2kpIHsKKyAgICAgICAgdmFyIGxpbmUgPSB0aGlzLnNldFtpXSwgbWsgPSBsaW5lLm1hcmtlZDsKKyAgICAgICAgaWYgKCFtayB8fCAhbGluZS5wYXJlbnQpIGNvbnRpbnVlOworICAgICAgICB2YXIgbGluZU4gPSBsaW5lTm8obGluZSk7CisgICAgICAgIG1pbiA9IE1hdGgubWluKG1pbiwgbGluZU4pOyBtYXggPSBNYXRoLm1heChtYXgsIGxpbmVOKTsKKyAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtay5sZW5ndGg7ICsraikKKyAgICAgICAgICBpZiAobWtbal0ubWFya2VyID09IHRoaXMpIG1rLnNwbGljZShqLS0sIDEpOworICAgICAgfQorICAgICAgaWYgKG1pbiAhPSBJbmZpbml0eSkKKyAgICAgICAgY2hhbmdlcy5wdXNoKHtmcm9tOiBtaW4sIHRvOiBtYXggKyAxfSk7CisgICAgfSk7CisgICAgVGV4dE1hcmtlci5wcm90b3R5cGUuZmluZCA9IGZ1bmN0aW9uKCkgeworICAgICAgdmFyIGZyb20sIHRvOworICAgICAgZm9yICh2YXIgaSA9IDAsIGUgPSB0aGlzLnNldC5sZW5ndGg7IGkgPCBlOyArK2kpIHsKKyAgICAgICAgdmFyIGxpbmUgPSB0aGlzLnNldFtpXSwgbWsgPSBsaW5lLm1hcmtlZDsKKyAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtay5sZW5ndGg7ICsraikgeworICAgICAgICAgIHZhciBtYXJrID0gbWtbal07CisgICAgICAgICAgaWYgKG1hcmsubWFya2VyID09IHRoaXMpIHsKKyAgICAgICAgICAgIGlmIChtYXJrLmZyb20gIT0gbnVsbCB8fCBtYXJrLnRvICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgdmFyIGZvdW5kID0gbGluZU5vKGxpbmUpOworICAgICAgICAgICAgICBpZiAoZm91bmQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmIChtYXJrLmZyb20gIT0gbnVsbCkgZnJvbSA9IHtsaW5lOiBmb3VuZCwgY2g6IG1hcmsuZnJvbX07CisgICAgICAgICAgICAgICAgaWYgKG1hcmsudG8gIT0gbnVsbCkgdG8gPSB7bGluZTogZm91bmQsIGNoOiBtYXJrLnRvfTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgICAgcmV0dXJuIHtmcm9tOiBmcm9tLCB0bzogdG99OworICAgIH07CisKKyAgICBmdW5jdGlvbiBtYXJrVGV4dChmcm9tLCB0bywgY2xhc3NOYW1lKSB7CisgICAgICBmcm9tID0gY2xpcFBvcyhmcm9tKTsgdG8gPSBjbGlwUG9zKHRvKTsKKyAgICAgIHZhciB0bSA9IG5ldyBUZXh0TWFya2VyKCk7CisgICAgICBpZiAoIXBvc0xlc3MoZnJvbSwgdG8pKSByZXR1cm4gdG07CisgICAgICBmdW5jdGlvbiBhZGQobGluZSwgZnJvbSwgdG8sIGNsYXNzTmFtZSkgeworICAgICAgICBnZXRMaW5lKGxpbmUpLmFkZE1hcmsobmV3IE1hcmtlZFRleHQoZnJvbSwgdG8sIGNsYXNzTmFtZSwgdG0pKTsKKyAgICAgIH0KKyAgICAgIGlmIChmcm9tLmxpbmUgPT0gdG8ubGluZSkgYWRkKGZyb20ubGluZSwgZnJvbS5jaCwgdG8uY2gsIGNsYXNzTmFtZSk7CisgICAgICBlbHNlIHsKKyAgICAgICAgYWRkKGZyb20ubGluZSwgZnJvbS5jaCwgbnVsbCwgY2xhc3NOYW1lKTsKKyAgICAgICAgZm9yICh2YXIgaSA9IGZyb20ubGluZSArIDEsIGUgPSB0by5saW5lOyBpIDwgZTsgKytpKQorICAgICAgICAgIGFkZChpLCBudWxsLCBudWxsLCBjbGFzc05hbWUpOworICAgICAgICBhZGQodG8ubGluZSwgbnVsbCwgdG8uY2gsIGNsYXNzTmFtZSk7CisgICAgICB9CisgICAgICBjaGFuZ2VzLnB1c2goe2Zyb206IGZyb20ubGluZSwgdG86IHRvLmxpbmUgKyAxfSk7CisgICAgICByZXR1cm4gdG07CisgICAgfQorCisgICAgZnVuY3Rpb24gc2V0Qm9va21hcmsocG9zKSB7CisgICAgICBwb3MgPSBjbGlwUG9zKHBvcyk7CisgICAgICB2YXIgYm0gPSBuZXcgQm9va21hcmsocG9zLmNoKTsKKyAgICAgIGdldExpbmUocG9zLmxpbmUpLmFkZE1hcmsoYm0pOworICAgICAgcmV0dXJuIGJtOworICAgIH0KKworICAgIGZ1bmN0aW9uIGZpbmRNYXJrc0F0KHBvcykgeworICAgICAgcG9zID0gY2xpcFBvcyhwb3MpOworICAgICAgdmFyIG1hcmtlcnMgPSBbXSwgbWFya2VkID0gZ2V0TGluZShwb3MubGluZSkubWFya2VkOworICAgICAgaWYgKCFtYXJrZWQpIHJldHVybiBtYXJrZXJzOworICAgICAgZm9yICh2YXIgaSA9IDAsIGUgPSBtYXJrZWQubGVuZ3RoOyBpIDwgZTsgKytpKSB7CisgICAgICAgIHZhciBtID0gbWFya2VkW2ldOworICAgICAgICBpZiAoKG0uZnJvbSA9PSBudWxsIHx8IG0uZnJvbSA8PSBwb3MuY2gpICYmCisgICAgICAgICAgICAobS50byA9PSBudWxsIHx8IG0udG8gPj0gcG9zLmNoKSkKKyAgICAgICAgICBtYXJrZXJzLnB1c2gobS5tYXJrZXIgfHwgbSk7CisgICAgICB9CisgICAgICByZXR1cm4gbWFya2VyczsKKyAgICB9CisKKyAgICBmdW5jdGlvbiBhZGRHdXR0ZXJNYXJrZXIobGluZSwgdGV4dCwgY2xhc3NOYW1lKSB7CisgICAgICBpZiAodHlwZW9mIGxpbmUgPT0gIm51bWJlciIpIGxpbmUgPSBnZXRMaW5lKGNsaXBMaW5lKGxpbmUpKTsKKyAgICAgIGxpbmUuZ3V0dGVyTWFya2VyID0ge3RleHQ6IHRleHQsIHN0eWxlOiBjbGFzc05hbWV9OworICAgICAgZ3V0dGVyRGlydHkgPSB0cnVlOworICAgICAgcmV0dXJuIGxpbmU7CisgICAgfQorICAgIGZ1bmN0aW9uIHJlbW92ZUd1dHRlck1hcmtlcihsaW5lKSB7CisgICAgICBpZiAodHlwZW9mIGxpbmUgPT0gIm51bWJlciIpIGxpbmUgPSBnZXRMaW5lKGNsaXBMaW5lKGxpbmUpKTsKKyAgICAgIGxpbmUuZ3V0dGVyTWFya2VyID0gbnVsbDsKKyAgICAgIGd1dHRlckRpcnR5ID0gdHJ1ZTsKKyAgICB9CisKKyAgICBmdW5jdGlvbiBjaGFuZ2VMaW5lKGhhbmRsZSwgb3ApIHsKKyAgICAgIHZhciBubyA9IGhhbmRsZSwgbGluZSA9IGhhbmRsZTsKKyAgICAgIGlmICh0eXBlb2YgaGFuZGxlID09ICJudW1iZXIiKSBsaW5lID0gZ2V0TGluZShjbGlwTGluZShoYW5kbGUpKTsKKyAgICAgIGVsc2Ugbm8gPSBsaW5lTm8oaGFuZGxlKTsKKyAgICAgIGlmIChubyA9PSBudWxsKSByZXR1cm4gbnVsbDsKKyAgICAgIGlmIChvcChsaW5lLCBubykpIGNoYW5nZXMucHVzaCh7ZnJvbTogbm8sIHRvOiBubyArIDF9KTsKKyAgICAgIGVsc2UgcmV0dXJuIG51bGw7CisgICAgICByZXR1cm4gbGluZTsKKyAgICB9CisgICAgZnVuY3Rpb24gc2V0TGluZUNsYXNzKGhhbmRsZSwgY2xhc3NOYW1lLCBiZ0NsYXNzTmFtZSkgeworICAgICAgcmV0dXJuIGNoYW5nZUxpbmUoaGFuZGxlLCBmdW5jdGlvbihsaW5lKSB7CisgICAgICAgIGlmIChsaW5lLmNsYXNzTmFtZSAhPSBjbGFzc05hbWUgfHwgbGluZS5iZ0NsYXNzTmFtZSAhPSBiZ0NsYXNzTmFtZSkgeworICAgICAgICAgIGxpbmUuY2xhc3NOYW1lID0gY2xhc3NOYW1lOworICAgICAgICAgIGxpbmUuYmdDbGFzc05hbWUgPSBiZ0NsYXNzTmFtZTsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgfSk7CisgICAgfQorICAgIGZ1bmN0aW9uIHNldExpbmVIaWRkZW4oaGFuZGxlLCBoaWRkZW4pIHsKKyAgICAgIHJldHVybiBjaGFuZ2VMaW5lKGhhbmRsZSwgZnVuY3Rpb24obGluZSwgbm8pIHsKKyAgICAgICAgaWYgKGxpbmUuaGlkZGVuICE9IGhpZGRlbikgeworICAgICAgICAgIGxpbmUuaGlkZGVuID0gaGlkZGVuOworICAgICAgICAgIHVwZGF0ZUxpbmVIZWlnaHQobGluZSwgaGlkZGVuID8gMCA6IDEpOworICAgICAgICAgIHZhciBmbGluZSA9IHNlbC5mcm9tLmxpbmUsIHRsaW5lID0gc2VsLnRvLmxpbmU7CisgICAgICAgICAgaWYgKGhpZGRlbiAmJiAoZmxpbmUgPT0gbm8gfHwgdGxpbmUgPT0gbm8pKSB7CisgICAgICAgICAgICB2YXIgZnJvbSA9IGZsaW5lID09IG5vID8gc2tpcEhpZGRlbih7bGluZTogZmxpbmUsIGNoOiAwfSwgZmxpbmUsIDApIDogc2VsLmZyb207CisgICAgICAgICAgICB2YXIgdG8gPSB0bGluZSA9PSBubyA/IHNraXBIaWRkZW4oe2xpbmU6IHRsaW5lLCBjaDogMH0sIHRsaW5lLCAwKSA6IHNlbC50bzsKKyAgICAgICAgICAgIC8vIENhbid0IGhpZGUgdGhlIGxhc3QgdmlzaWJsZSBsaW5lLCB3ZSdkIGhhdmUgbm8gcGxhY2UgdG8gcHV0IHRoZSBjdXJzb3IKKyAgICAgICAgICAgIGlmICghdG8pIHJldHVybjsKKyAgICAgICAgICAgIHNldFNlbGVjdGlvbihmcm9tLCB0byk7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiAoZ3V0dGVyRGlydHkgPSB0cnVlKTsKKyAgICAgICAgfQorICAgICAgfSk7CisgICAgfQorCisgICAgZnVuY3Rpb24gbGluZUluZm8obGluZSkgeworICAgICAgaWYgKHR5cGVvZiBsaW5lID09ICJudW1iZXIiKSB7CisgICAgICAgIGlmICghaXNMaW5lKGxpbmUpKSByZXR1cm4gbnVsbDsKKyAgICAgICAgdmFyIG4gPSBsaW5lOworICAgICAgICBsaW5lID0gZ2V0TGluZShsaW5lKTsKKyAgICAgICAgaWYgKCFsaW5lKSByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICB2YXIgbiA9IGxpbmVObyhsaW5lKTsKKyAgICAgICAgaWYgKG4gPT0gbnVsbCkgcmV0dXJuIG51bGw7CisgICAgICB9CisgICAgICB2YXIgbWFya2VyID0gbGluZS5ndXR0ZXJNYXJrZXI7CisgICAgICByZXR1cm4ge2xpbmU6IG4sIGhhbmRsZTogbGluZSwgdGV4dDogbGluZS50ZXh0LCBtYXJrZXJUZXh0OiBtYXJrZXIgJiYgbWFya2VyLnRleHQsCisgICAgICAgICAgICAgIG1hcmtlckNsYXNzOiBtYXJrZXIgJiYgbWFya2VyLnN0eWxlLCBsaW5lQ2xhc3M6IGxpbmUuY2xhc3NOYW1lLCBiZ0NsYXNzOiBsaW5lLmJnQ2xhc3NOYW1lfTsKKyAgICB9CisKKyAgICBmdW5jdGlvbiBzdHJpbmdXaWR0aChzdHIpIHsKKyAgICAgIG1lYXN1cmUuaW5uZXJIVE1MID0gIjxwcmU+PHNwYW4+eDwvc3Bhbj48L3ByZT4iOworICAgICAgbWVhc3VyZS5maXJzdENoaWxkLmZpcnN0Q2hpbGQuZmlyc3RDaGlsZC5ub2RlVmFsdWUgPSBzdHI7CisgICAgICByZXR1cm4gbWVhc3VyZS5maXJzdENoaWxkLmZpcnN0Q2hpbGQub2Zmc2V0V2lkdGggfHwgMTA7CisgICAgfQorICAgIC8vIFRoZXNlIGFyZSB1c2VkIHRvIGdvIGZyb20gcGl4ZWwgcG9zaXRpb25zIHRvIGNoYXJhY3RlcgorICAgIC8vIHBvc2l0aW9ucywgdGFraW5nIHZhcnlpbmcgY2hhcmFjdGVyIHdpZHRocyBpbnRvIGFjY291bnQuCisgICAgZnVuY3Rpb24gY2hhckZyb21YKGxpbmUsIHgpIHsKKyAgICAgIGlmICh4IDw9IDApIHJldHVybiAwOworICAgICAgdmFyIGxpbmVPYmogPSBnZXRMaW5lKGxpbmUpLCB0ZXh0ID0gbGluZU9iai50ZXh0OworICAgICAgZnVuY3Rpb24gZ2V0WChsZW4pIHsKKyAgICAgICAgcmV0dXJuIG1lYXN1cmVMaW5lKGxpbmVPYmosIGxlbikubGVmdDsKKyAgICAgIH0KKyAgICAgIHZhciBmcm9tID0gMCwgZnJvbVggPSAwLCB0byA9IHRleHQubGVuZ3RoLCB0b1g7CisgICAgICAvLyBHdWVzcyBhIHN1aXRhYmxlIHVwcGVyIGJvdW5kIGZvciBvdXIgc2VhcmNoLgorICAgICAgdmFyIGVzdGltYXRlZCA9IE1hdGgubWluKHRvLCBNYXRoLmNlaWwoeCAvIGNoYXJXaWR0aCgpKSk7CisgICAgICBmb3IgKDs7KSB7CisgICAgICAgIHZhciBlc3RYID0gZ2V0WChlc3RpbWF0ZWQpOworICAgICAgICBpZiAoZXN0WCA8PSB4ICYmIGVzdGltYXRlZCA8IHRvKSBlc3RpbWF0ZWQgPSBNYXRoLm1pbih0bywgTWF0aC5jZWlsKGVzdGltYXRlZCAqIDEuMikpOworICAgICAgICBlbHNlIHt0b1ggPSBlc3RYOyB0byA9IGVzdGltYXRlZDsgYnJlYWs7fQorICAgICAgfQorICAgICAgaWYgKHggPiB0b1gpIHJldHVybiB0bzsKKyAgICAgIC8vIFRyeSB0byBndWVzcyBhIHN1aXRhYmxlIGxvd2VyIGJvdW5kIGFzIHdlbGwuCisgICAgICBlc3RpbWF0ZWQgPSBNYXRoLmZsb29yKHRvICogMC44KTsgZXN0WCA9IGdldFgoZXN0aW1hdGVkKTsKKyAgICAgIGlmIChlc3RYIDwgeCkge2Zyb20gPSBlc3RpbWF0ZWQ7IGZyb21YID0gZXN0WDt9CisgICAgICAvLyBEbyBhIGJpbmFyeSBzZWFyY2ggYmV0d2VlbiB0aGVzZSBib3VuZHMuCisgICAgICBmb3IgKDs7KSB7CisgICAgICAgIGlmICh0byAtIGZyb20gPD0gMSkgcmV0dXJuICh0b1ggLSB4ID4geCAtIGZyb21YKSA/IGZyb20gOiB0bzsKKyAgICAgICAgdmFyIG1pZGRsZSA9IE1hdGguY2VpbCgoZnJvbSArIHRvKSAvIDIpLCBtaWRkbGVYID0gZ2V0WChtaWRkbGUpOworICAgICAgICBpZiAobWlkZGxlWCA+IHgpIHt0byA9IG1pZGRsZTsgdG9YID0gbWlkZGxlWDt9CisgICAgICAgIGVsc2Uge2Zyb20gPSBtaWRkbGU7IGZyb21YID0gbWlkZGxlWDt9CisgICAgICB9CisgICAgfQorCisgICAgdmFyIHRlbXBJZCA9ICJDb2RlTWlycm9yLXRlbXAtIiArIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDB4ZmZmZmZmKS50b1N0cmluZygxNik7CisgICAgZnVuY3Rpb24gbWVhc3VyZUxpbmUobGluZSwgY2gpIHsKKyAgICAgIGlmIChjaCA9PSAwKSByZXR1cm4ge3RvcDogMCwgbGVmdDogMH07CisgICAgICB2YXIgd2JyID0gb3B0aW9ucy5saW5lV3JhcHBpbmcgJiYgY2ggPCBsaW5lLnRleHQubGVuZ3RoICYmCisgICAgICAgICAgICAgICAgc3BhbkFmZmVjdHNXcmFwcGluZy50ZXN0KGxpbmUudGV4dC5zbGljZShjaCAtIDEsIGNoICsgMSkpOworICAgICAgbWVhc3VyZS5pbm5lckhUTUwgPSAiPHByZT4iICsgbGluZS5nZXRIVE1MKG1ha2VUYWIsIGNoLCB0ZW1wSWQsIHdicikgKyAiPC9wcmU+IjsKKyAgICAgIHZhciBlbHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0ZW1wSWQpOworICAgICAgdmFyIHRvcCA9IGVsdC5vZmZzZXRUb3AsIGxlZnQgPSBlbHQub2Zmc2V0TGVmdDsKKyAgICAgIC8vIE9sZGVyIElFcyByZXBvcnQgemVybyBvZmZzZXRzIGZvciBzcGFucyBkaXJlY3RseSBhZnRlciBhIHdyYXAKKyAgICAgIGlmIChpZSAmJiB0b3AgPT0gMCAmJiBsZWZ0ID09IDApIHsKKyAgICAgICAgdmFyIGJhY2t1cCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKTsKKyAgICAgICAgYmFja3VwLmlubmVySFRNTCA9ICJ4IjsKKyAgICAgICAgZWx0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGJhY2t1cCwgZWx0Lm5leHRTaWJsaW5nKTsKKyAgICAgICAgdG9wID0gYmFja3VwLm9mZnNldFRvcDsKKyAgICAgIH0KKyAgICAgIHJldHVybiB7dG9wOiB0b3AsIGxlZnQ6IGxlZnR9OworICAgIH0KKyAgICBmdW5jdGlvbiBsb2NhbENvb3Jkcyhwb3MsIGluTGluZVdyYXApIHsKKyAgICAgIHZhciB4LCBsaCA9IHRleHRIZWlnaHQoKSwgeSA9IGxoICogKGhlaWdodEF0TGluZShkb2MsIHBvcy5saW5lKSAtIChpbkxpbmVXcmFwID8gZGlzcGxheU9mZnNldCA6IDApKTsKKyAgICAgIGlmIChwb3MuY2ggPT0gMCkgeCA9IDA7CisgICAgICBlbHNlIHsKKyAgICAgICAgdmFyIHNwID0gbWVhc3VyZUxpbmUoZ2V0TGluZShwb3MubGluZSksIHBvcy5jaCk7CisgICAgICAgIHggPSBzcC5sZWZ0OworICAgICAgICBpZiAob3B0aW9ucy5saW5lV3JhcHBpbmcpIHkgKz0gTWF0aC5tYXgoMCwgc3AudG9wKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiB7eDogeCwgeTogeSwgeUJvdDogeSArIGxofTsKKyAgICB9CisgICAgLy8gQ29vcmRzIG11c3QgYmUgbGluZVNwYWNlLWxvY2FsCisgICAgZnVuY3Rpb24gY29vcmRzQ2hhcih4LCB5KSB7CisgICAgICBpZiAoeSA8IDApIHkgPSAwOworICAgICAgdmFyIHRoID0gdGV4dEhlaWdodCgpLCBjdyA9IGNoYXJXaWR0aCgpLCBoZWlnaHRQb3MgPSBkaXNwbGF5T2Zmc2V0ICsgTWF0aC5mbG9vcih5IC8gdGgpOworICAgICAgdmFyIGxpbmVObyA9IGxpbmVBdEhlaWdodChkb2MsIGhlaWdodFBvcyk7CisgICAgICBpZiAobGluZU5vID49IGRvYy5zaXplKSByZXR1cm4ge2xpbmU6IGRvYy5zaXplIC0gMSwgY2g6IGdldExpbmUoZG9jLnNpemUgLSAxKS50ZXh0Lmxlbmd0aH07CisgICAgICB2YXIgbGluZU9iaiA9IGdldExpbmUobGluZU5vKSwgdGV4dCA9IGxpbmVPYmoudGV4dDsKKyAgICAgIHZhciB0dyA9IG9wdGlvbnMubGluZVdyYXBwaW5nLCBpbm5lck9mZiA9IHR3ID8gaGVpZ2h0UG9zIC0gaGVpZ2h0QXRMaW5lKGRvYywgbGluZU5vKSA6IDA7CisgICAgICBpZiAoeCA8PSAwICYmIGlubmVyT2ZmID09IDApIHJldHVybiB7bGluZTogbGluZU5vLCBjaDogMH07CisgICAgICBmdW5jdGlvbiBnZXRYKGxlbikgeworICAgICAgICB2YXIgc3AgPSBtZWFzdXJlTGluZShsaW5lT2JqLCBsZW4pOworICAgICAgICBpZiAodHcpIHsKKyAgICAgICAgICB2YXIgb2ZmID0gTWF0aC5yb3VuZChzcC50b3AgLyB0aCk7CisgICAgICAgICAgcmV0dXJuIE1hdGgubWF4KDAsIHNwLmxlZnQgKyAob2ZmIC0gaW5uZXJPZmYpICogc2Nyb2xsZXIuY2xpZW50V2lkdGgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBzcC5sZWZ0OworICAgICAgfQorICAgICAgdmFyIGZyb20gPSAwLCBmcm9tWCA9IDAsIHRvID0gdGV4dC5sZW5ndGgsIHRvWDsKKyAgICAgIC8vIEd1ZXNzIGEgc3VpdGFibGUgdXBwZXIgYm91bmQgZm9yIG91ciBzZWFyY2guCisgICAgICB2YXIgZXN0aW1hdGVkID0gTWF0aC5taW4odG8sIE1hdGguY2VpbCgoeCArIGlubmVyT2ZmICogc2Nyb2xsZXIuY2xpZW50V2lkdGggKiAuOSkgLyBjdykpOworICAgICAgZm9yICg7OykgeworICAgICAgICB2YXIgZXN0WCA9IGdldFgoZXN0aW1hdGVkKTsKKyAgICAgICAgaWYgKGVzdFggPD0geCAmJiBlc3RpbWF0ZWQgPCB0bykgZXN0aW1hdGVkID0gTWF0aC5taW4odG8sIE1hdGguY2VpbChlc3RpbWF0ZWQgKiAxLjIpKTsKKyAgICAgICAgZWxzZSB7dG9YID0gZXN0WDsgdG8gPSBlc3RpbWF0ZWQ7IGJyZWFrO30KKyAgICAgIH0KKyAgICAgIGlmICh4ID4gdG9YKSByZXR1cm4ge2xpbmU6IGxpbmVObywgY2g6IHRvfTsKKyAgICAgIC8vIFRyeSB0byBndWVzcyBhIHN1aXRhYmxlIGxvd2VyIGJvdW5kIGFzIHdlbGwuCisgICAgICBlc3RpbWF0ZWQgPSBNYXRoLmZsb29yKHRvICogMC44KTsgZXN0WCA9IGdldFgoZXN0aW1hdGVkKTsKKyAgICAgIGlmIChlc3RYIDwgeCkge2Zyb20gPSBlc3RpbWF0ZWQ7IGZyb21YID0gZXN0WDt9CisgICAgICAvLyBEbyBhIGJpbmFyeSBzZWFyY2ggYmV0d2VlbiB0aGVzZSBib3VuZHMuCisgICAgICBmb3IgKDs7KSB7CisgICAgICAgIGlmICh0byAtIGZyb20gPD0gMSkgcmV0dXJuIHtsaW5lOiBsaW5lTm8sIGNoOiAodG9YIC0geCA+IHggLSBmcm9tWCkgPyBmcm9tIDogdG99OworICAgICAgICB2YXIgbWlkZGxlID0gTWF0aC5jZWlsKChmcm9tICsgdG8pIC8gMiksIG1pZGRsZVggPSBnZXRYKG1pZGRsZSk7CisgICAgICAgIGlmIChtaWRkbGVYID4geCkge3RvID0gbWlkZGxlOyB0b1ggPSBtaWRkbGVYO30KKyAgICAgICAgZWxzZSB7ZnJvbSA9IG1pZGRsZTsgZnJvbVggPSBtaWRkbGVYO30KKyAgICAgIH0KKyAgICB9CisgICAgZnVuY3Rpb24gcGFnZUNvb3Jkcyhwb3MpIHsKKyAgICAgIHZhciBsb2NhbCA9IGxvY2FsQ29vcmRzKHBvcywgdHJ1ZSksIG9mZiA9IGVsdE9mZnNldChsaW5lU3BhY2UpOworICAgICAgcmV0dXJuIHt4OiBvZmYubGVmdCArIGxvY2FsLngsIHk6IG9mZi50b3AgKyBsb2NhbC55LCB5Qm90OiBvZmYudG9wICsgbG9jYWwueUJvdH07CisgICAgfQorCisgICAgdmFyIGNhY2hlZEhlaWdodCwgY2FjaGVkSGVpZ2h0Rm9yLCBtZWFzdXJlVGV4dDsKKyAgICBmdW5jdGlvbiB0ZXh0SGVpZ2h0KCkgeworICAgICAgaWYgKG1lYXN1cmVUZXh0ID09IG51bGwpIHsKKyAgICAgICAgbWVhc3VyZVRleHQgPSAiPHByZT4iOworICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ5OyArK2kpIG1lYXN1cmVUZXh0ICs9ICJ4PGJyLz4iOworICAgICAgICBtZWFzdXJlVGV4dCArPSAieDwvcHJlPiI7CisgICAgICB9CisgICAgICB2YXIgb2Zmc2V0SGVpZ2h0ID0gbGluZURpdi5jbGllbnRIZWlnaHQ7CisgICAgICBpZiAob2Zmc2V0SGVpZ2h0ID09IGNhY2hlZEhlaWdodEZvcikgcmV0dXJuIGNhY2hlZEhlaWdodDsKKyAgICAgIGNhY2hlZEhlaWdodEZvciA9IG9mZnNldEhlaWdodDsKKyAgICAgIG1lYXN1cmUuaW5uZXJIVE1MID0gbWVhc3VyZVRleHQ7CisgICAgICBjYWNoZWRIZWlnaHQgPSBtZWFzdXJlLmZpcnN0Q2hpbGQub2Zmc2V0SGVpZ2h0IC8gNTAgfHwgMTsKKyAgICAgIG1lYXN1cmUuaW5uZXJIVE1MID0gIiI7CisgICAgICByZXR1cm4gY2FjaGVkSGVpZ2h0OworICAgIH0KKyAgICB2YXIgY2FjaGVkV2lkdGgsIGNhY2hlZFdpZHRoRm9yID0gMDsKKyAgICBmdW5jdGlvbiBjaGFyV2lkdGgoKSB7CisgICAgICBpZiAoc2Nyb2xsZXIuY2xpZW50V2lkdGggPT0gY2FjaGVkV2lkdGhGb3IpIHJldHVybiBjYWNoZWRXaWR0aDsKKyAgICAgIGNhY2hlZFdpZHRoRm9yID0gc2Nyb2xsZXIuY2xpZW50V2lkdGg7CisgICAgICByZXR1cm4gKGNhY2hlZFdpZHRoID0gc3RyaW5nV2lkdGgoIngiKSk7CisgICAgfQorICAgIGZ1bmN0aW9uIHBhZGRpbmdUb3AoKSB7cmV0dXJuIGxpbmVTcGFjZS5vZmZzZXRUb3A7fQorICAgIGZ1bmN0aW9uIHBhZGRpbmdMZWZ0KCkge3JldHVybiBsaW5lU3BhY2Uub2Zmc2V0TGVmdDt9CisKKyAgICBmdW5jdGlvbiBwb3NGcm9tTW91c2UoZSwgbGliZXJhbCkgeworICAgICAgdmFyIG9mZlcgPSBlbHRPZmZzZXQoc2Nyb2xsZXIsIHRydWUpLCB4LCB5OworICAgICAgLy8gRmFpbHMgdW5wcmVkaWN0YWJseSBvbiBJRVs2N10gd2hlbiBtb3VzZSBpcyBkcmFnZ2VkIGFyb3VuZCBxdWlja2x5LgorICAgICAgdHJ5IHsgeCA9IGUuY2xpZW50WDsgeSA9IGUuY2xpZW50WTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gbnVsbDsgfQorICAgICAgLy8gVGhpcyBpcyBhIG1lc3Mgb2YgYSBoZXVyaXN0aWMgdG8gdHJ5IGFuZCBkZXRlcm1pbmUgd2hldGhlciBhCisgICAgICAvLyBzY3JvbGwtYmFyIHdhcyBjbGlja2VkIG9yIG5vdCwgYW5kIHRvIHJldHVybiBudWxsIGlmIG9uZSB3YXMKKyAgICAgIC8vIChhbmQgIWxpYmVyYWwpLgorICAgICAgaWYgKCFsaWJlcmFsICYmICh4IC0gb2ZmVy5sZWZ0ID4gc2Nyb2xsZXIuY2xpZW50V2lkdGggfHwgeSAtIG9mZlcudG9wID4gc2Nyb2xsZXIuY2xpZW50SGVpZ2h0KSkKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB2YXIgb2ZmTCA9IGVsdE9mZnNldChsaW5lU3BhY2UsIHRydWUpOworICAgICAgcmV0dXJuIGNvb3Jkc0NoYXIoeCAtIG9mZkwubGVmdCwgeSAtIG9mZkwudG9wKTsKKyAgICB9CisgICAgZnVuY3Rpb24gb25Db250ZXh0TWVudShlKSB7CisgICAgICB2YXIgcG9zID0gcG9zRnJvbU1vdXNlKGUpLCBzY3JvbGxQb3MgPSBzY3JvbGxlci5zY3JvbGxUb3A7CisgICAgICBpZiAoIXBvcyB8fCB3aW5kb3cub3BlcmEpIHJldHVybjsgLy8gT3BlcmEgaXMgZGlmZmljdWx0LgorICAgICAgaWYgKHBvc0VxKHNlbC5mcm9tLCBzZWwudG8pIHx8IHBvc0xlc3MocG9zLCBzZWwuZnJvbSkgfHwgIXBvc0xlc3MocG9zLCBzZWwudG8pKQorICAgICAgICBvcGVyYXRpb24oc2V0Q3Vyc29yKShwb3MubGluZSwgcG9zLmNoKTsKKworICAgICAgdmFyIG9sZENTUyA9IGlucHV0LnN0eWxlLmNzc1RleHQ7CisgICAgICBpbnB1dERpdi5zdHlsZS5wb3NpdGlvbiA9ICJhYnNvbHV0ZSI7CisgICAgICBpbnB1dC5zdHlsZS5jc3NUZXh0ID0gInBvc2l0aW9uOiBmaXhlZDsgd2lkdGg6IDMwcHg7IGhlaWdodDogMzBweDsgdG9wOiAiICsgKGUuY2xpZW50WSAtIDUpICsKKyAgICAgICAgInB4OyBsZWZ0OiAiICsgKGUuY2xpZW50WCAtIDUpICsgInB4OyB6LWluZGV4OiAxMDAwOyBiYWNrZ3JvdW5kOiB3aGl0ZTsgIiArCisgICAgICAgICJib3JkZXItd2lkdGg6IDA7IG91dGxpbmU6IG5vbmU7IG92ZXJmbG93OiBoaWRkZW47IG9wYWNpdHk6IC4wNTsgZmlsdGVyOiBhbHBoYShvcGFjaXR5PTUpOyI7CisgICAgICBsZWF2ZUlucHV0QWxvbmUgPSB0cnVlOworICAgICAgdmFyIHZhbCA9IGlucHV0LnZhbHVlID0gZ2V0U2VsZWN0aW9uKCk7CisgICAgICBmb2N1c0lucHV0KCk7CisgICAgICBzZWxlY3RJbnB1dChpbnB1dCk7CisgICAgICBmdW5jdGlvbiByZWhpZGUoKSB7CisgICAgICAgIHZhciBuZXdWYWwgPSBzcGxpdExpbmVzKGlucHV0LnZhbHVlKS5qb2luKCJcbiIpOworICAgICAgICBpZiAobmV3VmFsICE9IHZhbCkgb3BlcmF0aW9uKHJlcGxhY2VTZWxlY3Rpb24pKG5ld1ZhbCwgImVuZCIpOworICAgICAgICBpbnB1dERpdi5zdHlsZS5wb3NpdGlvbiA9ICJyZWxhdGl2ZSI7CisgICAgICAgIGlucHV0LnN0eWxlLmNzc1RleHQgPSBvbGRDU1M7CisgICAgICAgIGlmIChpZV9sdDkpIHNjcm9sbGVyLnNjcm9sbFRvcCA9IHNjcm9sbFBvczsKKyAgICAgICAgbGVhdmVJbnB1dEFsb25lID0gZmFsc2U7CisgICAgICAgIHJlc2V0SW5wdXQodHJ1ZSk7CisgICAgICAgIHNsb3dQb2xsKCk7CisgICAgICB9CisKKyAgICAgIGlmIChnZWNrbykgeworICAgICAgICBlX3N0b3AoZSk7CisgICAgICAgIHZhciBtb3VzZXVwID0gY29ubmVjdCh3aW5kb3csICJtb3VzZXVwIiwgZnVuY3Rpb24oKSB7CisgICAgICAgICAgbW91c2V1cCgpOworICAgICAgICAgIHNldFRpbWVvdXQocmVoaWRlLCAyMCk7CisgICAgICAgIH0sIHRydWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2V0VGltZW91dChyZWhpZGUsIDUwKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBDdXJzb3ItYmxpbmtpbmcKKyAgICBmdW5jdGlvbiByZXN0YXJ0QmxpbmsoKSB7CisgICAgICBjbGVhckludGVydmFsKGJsaW5rZXIpOworICAgICAgdmFyIG9uID0gdHJ1ZTsKKyAgICAgIGN1cnNvci5zdHlsZS52aXNpYmlsaXR5ID0gIiI7CisgICAgICBibGlua2VyID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7CisgICAgICAgIGN1cnNvci5zdHlsZS52aXNpYmlsaXR5ID0gKG9uID0gIW9uKSA/ICIiIDogImhpZGRlbiI7CisgICAgICB9LCA2NTApOworICAgIH0KKworICAgIHZhciBtYXRjaGluZyA9IHsiKCI6ICIpPiIsICIpIjogIig8IiwgIlsiOiAiXT4iLCAiXSI6ICJbPCIsICJ7IjogIn0+IiwgIn0iOiAiezwifTsKKyAgICBmdW5jdGlvbiBtYXRjaEJyYWNrZXRzKGF1dG9jbGVhcikgeworICAgICAgdmFyIGhlYWQgPSBzZWwuaW52ZXJ0ZWQgPyBzZWwuZnJvbSA6IHNlbC50bywgbGluZSA9IGdldExpbmUoaGVhZC5saW5lKSwgcG9zID0gaGVhZC5jaCAtIDE7CisgICAgICB2YXIgbWF0Y2ggPSAocG9zID49IDAgJiYgbWF0Y2hpbmdbbGluZS50ZXh0LmNoYXJBdChwb3MpXSkgfHwgbWF0Y2hpbmdbbGluZS50ZXh0LmNoYXJBdCgrK3BvcyldOworICAgICAgaWYgKCFtYXRjaCkgcmV0dXJuOworICAgICAgdmFyIGNoID0gbWF0Y2guY2hhckF0KDApLCBmb3J3YXJkID0gbWF0Y2guY2hhckF0KDEpID09ICI+IiwgZCA9IGZvcndhcmQgPyAxIDogLTEsIHN0ID0gbGluZS5zdHlsZXM7CisgICAgICBmb3IgKHZhciBvZmYgPSBwb3MgKyAxLCBpID0gMCwgZSA9IHN0Lmxlbmd0aDsgaSA8IGU7IGkrPTIpCisgICAgICAgIGlmICgob2ZmIC09IHN0W2ldLmxlbmd0aCkgPD0gMCkge3ZhciBzdHlsZSA9IHN0W2krMV07IGJyZWFrO30KKworICAgICAgdmFyIHN0YWNrID0gW2xpbmUudGV4dC5jaGFyQXQocG9zKV0sIHJlID0gL1soKXt9W1xdXS87CisgICAgICBmdW5jdGlvbiBzY2FuKGxpbmUsIGZyb20sIHRvKSB7CisgICAgICAgIGlmICghbGluZS50ZXh0KSByZXR1cm47CisgICAgICAgIHZhciBzdCA9IGxpbmUuc3R5bGVzLCBwb3MgPSBmb3J3YXJkID8gMCA6IGxpbmUudGV4dC5sZW5ndGggLSAxLCBjdXI7CisgICAgICAgIGZvciAodmFyIGkgPSBmb3J3YXJkID8gMCA6IHN0Lmxlbmd0aCAtIDIsIGUgPSBmb3J3YXJkID8gc3QubGVuZ3RoIDogLTI7IGkgIT0gZTsgaSArPSAyKmQpIHsKKyAgICAgICAgICB2YXIgdGV4dCA9IHN0W2ldOworICAgICAgICAgIGlmIChzdFtpKzFdICE9IG51bGwgJiYgc3RbaSsxXSAhPSBzdHlsZSkge3BvcyArPSBkICogdGV4dC5sZW5ndGg7IGNvbnRpbnVlO30KKyAgICAgICAgICBmb3IgKHZhciBqID0gZm9yd2FyZCA/IDAgOiB0ZXh0Lmxlbmd0aCAtIDEsIHRlID0gZm9yd2FyZCA/IHRleHQubGVuZ3RoIDogLTE7IGogIT0gdGU7IGogKz0gZCwgcG9zKz1kKSB7CisgICAgICAgICAgICBpZiAocG9zID49IGZyb20gJiYgcG9zIDwgdG8gJiYgcmUudGVzdChjdXIgPSB0ZXh0LmNoYXJBdChqKSkpIHsKKyAgICAgICAgICAgICAgdmFyIG1hdGNoID0gbWF0Y2hpbmdbY3VyXTsKKyAgICAgICAgICAgICAgaWYgKG1hdGNoLmNoYXJBdCgxKSA9PSAiPiIgPT0gZm9yd2FyZCkgc3RhY2sucHVzaChjdXIpOworICAgICAgICAgICAgICBlbHNlIGlmIChzdGFjay5wb3AoKSAhPSBtYXRjaC5jaGFyQXQoMCkpIHJldHVybiB7cG9zOiBwb3MsIG1hdGNoOiBmYWxzZX07CisgICAgICAgICAgICAgIGVsc2UgaWYgKCFzdGFjay5sZW5ndGgpIHJldHVybiB7cG9zOiBwb3MsIG1hdGNoOiB0cnVlfTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGZvciAodmFyIGkgPSBoZWFkLmxpbmUsIGUgPSBmb3J3YXJkID8gTWF0aC5taW4oaSArIDEwMCwgZG9jLnNpemUpIDogTWF0aC5tYXgoLTEsIGkgLSAxMDApOyBpICE9IGU7IGkrPWQpIHsKKyAgICAgICAgdmFyIGxpbmUgPSBnZXRMaW5lKGkpLCBmaXJzdCA9IGkgPT0gaGVhZC5saW5lOworICAgICAgICB2YXIgZm91bmQgPSBzY2FuKGxpbmUsIGZpcnN0ICYmIGZvcndhcmQgPyBwb3MgKyAxIDogMCwgZmlyc3QgJiYgIWZvcndhcmQgPyBwb3MgOiBsaW5lLnRleHQubGVuZ3RoKTsKKyAgICAgICAgaWYgKGZvdW5kKSBicmVhazsKKyAgICAgIH0KKyAgICAgIGlmICghZm91bmQpIGZvdW5kID0ge3BvczogbnVsbCwgbWF0Y2g6IGZhbHNlfTsKKyAgICAgIHZhciBzdHlsZSA9IGZvdW5kLm1hdGNoID8gIkNvZGVNaXJyb3ItbWF0Y2hpbmdicmFja2V0IiA6ICJDb2RlTWlycm9yLW5vbm1hdGNoaW5nYnJhY2tldCI7CisgICAgICB2YXIgb25lID0gbWFya1RleHQoe2xpbmU6IGhlYWQubGluZSwgY2g6IHBvc30sIHtsaW5lOiBoZWFkLmxpbmUsIGNoOiBwb3MrMX0sIHN0eWxlKSwKKyAgICAgICAgICB0d28gPSBmb3VuZC5wb3MgIT0gbnVsbCAmJiBtYXJrVGV4dCh7bGluZTogaSwgY2g6IGZvdW5kLnBvc30sIHtsaW5lOiBpLCBjaDogZm91bmQucG9zICsgMX0sIHN0eWxlKTsKKyAgICAgIHZhciBjbGVhciA9IG9wZXJhdGlvbihmdW5jdGlvbigpe29uZS5jbGVhcigpOyB0d28gJiYgdHdvLmNsZWFyKCk7fSk7CisgICAgICBpZiAoYXV0b2NsZWFyKSBzZXRUaW1lb3V0KGNsZWFyLCA4MDApOworICAgICAgZWxzZSBicmFja2V0SGlnaGxpZ2h0ZWQgPSBjbGVhcjsKKyAgICB9CisKKyAgICAvLyBGaW5kcyB0aGUgbGluZSB0byBzdGFydCB3aXRoIHdoZW4gc3RhcnRpbmcgYSBwYXJzZS4gVHJpZXMgdG8KKyAgICAvLyBmaW5kIGEgbGluZSB3aXRoIGEgc3RhdGVBZnRlciwgc28gdGhhdCBpdCBjYW4gc3RhcnQgd2l0aCBhCisgICAgLy8gdmFsaWQgc3RhdGUuIElmIHRoYXQgZmFpbHMsIGl0IHJldHVybnMgdGhlIGxpbmUgd2l0aCB0aGUKKyAgICAvLyBzbWFsbGVzdCBpbmRlbnRhdGlvbiwgd2hpY2ggdGVuZHMgdG8gbmVlZCB0aGUgbGVhc3QgY29udGV4dCB0bworICAgIC8vIHBhcnNlIGNvcnJlY3RseS4KKyAgICBmdW5jdGlvbiBmaW5kU3RhcnRMaW5lKG4pIHsKKyAgICAgIHZhciBtaW5pbmRlbnQsIG1pbmxpbmU7CisgICAgICBmb3IgKHZhciBzZWFyY2ggPSBuLCBsaW0gPSBuIC0gNDA7IHNlYXJjaCA+IGxpbTsgLS1zZWFyY2gpIHsKKyAgICAgICAgaWYgKHNlYXJjaCA9PSAwKSByZXR1cm4gMDsKKyAgICAgICAgdmFyIGxpbmUgPSBnZXRMaW5lKHNlYXJjaC0xKTsKKyAgICAgICAgaWYgKGxpbmUuc3RhdGVBZnRlcikgcmV0dXJuIHNlYXJjaDsKKyAgICAgICAgdmFyIGluZGVudGVkID0gbGluZS5pbmRlbnRhdGlvbihvcHRpb25zLnRhYlNpemUpOworICAgICAgICBpZiAobWlubGluZSA9PSBudWxsIHx8IG1pbmluZGVudCA+IGluZGVudGVkKSB7CisgICAgICAgICAgbWlubGluZSA9IHNlYXJjaCAtIDE7CisgICAgICAgICAgbWluaW5kZW50ID0gaW5kZW50ZWQ7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiBtaW5saW5lOworICAgIH0KKyAgICBmdW5jdGlvbiBnZXRTdGF0ZUJlZm9yZShuKSB7CisgICAgICB2YXIgc3RhcnQgPSBmaW5kU3RhcnRMaW5lKG4pLCBzdGF0ZSA9IHN0YXJ0ICYmIGdldExpbmUoc3RhcnQtMSkuc3RhdGVBZnRlcjsKKyAgICAgIGlmICghc3RhdGUpIHN0YXRlID0gc3RhcnRTdGF0ZShtb2RlKTsKKyAgICAgIGVsc2Ugc3RhdGUgPSBjb3B5U3RhdGUobW9kZSwgc3RhdGUpOworICAgICAgZG9jLml0ZXIoc3RhcnQsIG4sIGZ1bmN0aW9uKGxpbmUpIHsKKyAgICAgICAgbGluZS5oaWdobGlnaHQobW9kZSwgc3RhdGUsIG9wdGlvbnMudGFiU2l6ZSk7CisgICAgICAgIGxpbmUuc3RhdGVBZnRlciA9IGNvcHlTdGF0ZShtb2RlLCBzdGF0ZSk7CisgICAgICB9KTsKKyAgICAgIGlmIChzdGFydCA8IG4pIGNoYW5nZXMucHVzaCh7ZnJvbTogc3RhcnQsIHRvOiBufSk7CisgICAgICBpZiAobiA8IGRvYy5zaXplICYmICFnZXRMaW5lKG4pLnN0YXRlQWZ0ZXIpIHdvcmsucHVzaChuKTsKKyAgICAgIHJldHVybiBzdGF0ZTsKKyAgICB9CisgICAgZnVuY3Rpb24gaGlnaGxpZ2h0TGluZXMoc3RhcnQsIGVuZCkgeworICAgICAgdmFyIHN0YXRlID0gZ2V0U3RhdGVCZWZvcmUoc3RhcnQpOworICAgICAgZG9jLml0ZXIoc3RhcnQsIGVuZCwgZnVuY3Rpb24obGluZSkgeworICAgICAgICBsaW5lLmhpZ2hsaWdodChtb2RlLCBzdGF0ZSwgb3B0aW9ucy50YWJTaXplKTsKKyAgICAgICAgbGluZS5zdGF0ZUFmdGVyID0gY29weVN0YXRlKG1vZGUsIHN0YXRlKTsKKyAgICAgIH0pOworICAgIH0KKyAgICBmdW5jdGlvbiBoaWdobGlnaHRXb3JrZXIoKSB7CisgICAgICB2YXIgZW5kID0gK25ldyBEYXRlICsgb3B0aW9ucy53b3JrVGltZTsKKyAgICAgIHZhciBmb3VuZFdvcmsgPSB3b3JrLmxlbmd0aDsKKyAgICAgIHdoaWxlICh3b3JrLmxlbmd0aCkgeworICAgICAgICBpZiAoIWdldExpbmUoc2hvd2luZ0Zyb20pLnN0YXRlQWZ0ZXIpIHZhciB0YXNrID0gc2hvd2luZ0Zyb207CisgICAgICAgIGVsc2UgdmFyIHRhc2sgPSB3b3JrLnBvcCgpOworICAgICAgICBpZiAodGFzayA+PSBkb2Muc2l6ZSkgY29udGludWU7CisgICAgICAgIHZhciBzdGFydCA9IGZpbmRTdGFydExpbmUodGFzayksIHN0YXRlID0gc3RhcnQgJiYgZ2V0TGluZShzdGFydC0xKS5zdGF0ZUFmdGVyOworICAgICAgICBpZiAoc3RhdGUpIHN0YXRlID0gY29weVN0YXRlKG1vZGUsIHN0YXRlKTsKKyAgICAgICAgZWxzZSBzdGF0ZSA9IHN0YXJ0U3RhdGUobW9kZSk7CisKKyAgICAgICAgdmFyIHVuY2hhbmdlZCA9IDAsIGNvbXBhcmUgPSBtb2RlLmNvbXBhcmVTdGF0ZXMsIHJlYWxDaGFuZ2UgPSBmYWxzZSwKKyAgICAgICAgICAgIGkgPSBzdGFydCwgYmFpbCA9IGZhbHNlOworICAgICAgICBkb2MuaXRlcihpLCBkb2Muc2l6ZSwgZnVuY3Rpb24obGluZSkgeworICAgICAgICAgIHZhciBoYWRTdGF0ZSA9IGxpbmUuc3RhdGVBZnRlcjsKKyAgICAgICAgICBpZiAoK25ldyBEYXRlID4gZW5kKSB7CisgICAgICAgICAgICB3b3JrLnB1c2goaSk7CisgICAgICAgICAgICBzdGFydFdvcmtlcihvcHRpb25zLndvcmtEZWxheSk7CisgICAgICAgICAgICBpZiAocmVhbENoYW5nZSkgY2hhbmdlcy5wdXNoKHtmcm9tOiB0YXNrLCB0bzogaSArIDF9KTsKKyAgICAgICAgICAgIHJldHVybiAoYmFpbCA9IHRydWUpOworICAgICAgICAgIH0KKyAgICAgICAgICB2YXIgY2hhbmdlZCA9IGxpbmUuaGlnaGxpZ2h0KG1vZGUsIHN0YXRlLCBvcHRpb25zLnRhYlNpemUpOworICAgICAgICAgIGlmIChjaGFuZ2VkKSByZWFsQ2hhbmdlID0gdHJ1ZTsKKyAgICAgICAgICBsaW5lLnN0YXRlQWZ0ZXIgPSBjb3B5U3RhdGUobW9kZSwgc3RhdGUpOworICAgICAgICAgIHZhciBkb25lID0gbnVsbDsKKyAgICAgICAgICBpZiAoY29tcGFyZSkgeworICAgICAgICAgICAgdmFyIHNhbWUgPSBoYWRTdGF0ZSAmJiBjb21wYXJlKGhhZFN0YXRlLCBzdGF0ZSk7CisgICAgICAgICAgICBpZiAoc2FtZSAhPSBQYXNzKSBkb25lID0gISFzYW1lOworICAgICAgICAgIH0KKyAgICAgICAgICBpZiAoZG9uZSA9PSBudWxsKSB7CisgICAgICAgICAgICBpZiAoY2hhbmdlZCAhPT0gZmFsc2UgfHwgIWhhZFN0YXRlKSB1bmNoYW5nZWQgPSAwOworICAgICAgICAgICAgZWxzZSBpZiAoKyt1bmNoYW5nZWQgPiAzICYmICghbW9kZS5pbmRlbnQgfHwgbW9kZS5pbmRlbnQoaGFkU3RhdGUsICIiKSA9PSBtb2RlLmluZGVudChzdGF0ZSwgIiIpKSkKKyAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChkb25lKSByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICArK2k7CisgICAgICAgIH0pOworICAgICAgICBpZiAoYmFpbCkgcmV0dXJuOworICAgICAgICBpZiAocmVhbENoYW5nZSkgY2hhbmdlcy5wdXNoKHtmcm9tOiB0YXNrLCB0bzogaSArIDF9KTsKKyAgICAgIH0KKyAgICAgIGlmIChmb3VuZFdvcmsgJiYgb3B0aW9ucy5vbkhpZ2hsaWdodENvbXBsZXRlKQorICAgICAgICBvcHRpb25zLm9uSGlnaGxpZ2h0Q29tcGxldGUoaW5zdGFuY2UpOworICAgIH0KKyAgICBmdW5jdGlvbiBzdGFydFdvcmtlcih0aW1lKSB7CisgICAgICBpZiAoIXdvcmsubGVuZ3RoKSByZXR1cm47CisgICAgICBoaWdobGlnaHQuc2V0KHRpbWUsIG9wZXJhdGlvbihoaWdobGlnaHRXb3JrZXIpKTsKKyAgICB9CisKKyAgICAvLyBPcGVyYXRpb25zIGFyZSB1c2VkIHRvIHdyYXAgY2hhbmdlcyBpbiBzdWNoIGEgd2F5IHRoYXQgZWFjaAorICAgIC8vIGNoYW5nZSB3b24ndCBoYXZlIHRvIHVwZGF0ZSB0aGUgY3Vyc29yIGFuZCBkaXNwbGF5ICh3aGljaCB3b3VsZAorICAgIC8vIGJlIGF3a3dhcmQsIHNsb3csIGFuZCBlcnJvci1wcm9uZSksIGJ1dCBpbnN0ZWFkIHVwZGF0ZXMgYXJlCisgICAgLy8gYmF0Y2hlZCBhbmQgdGhlbiBhbGwgY29tYmluZWQgYW5kIGV4ZWN1dGVkIGF0IG9uY2UuCisgICAgZnVuY3Rpb24gc3RhcnRPcGVyYXRpb24oKSB7CisgICAgICB1cGRhdGVJbnB1dCA9IHVzZXJTZWxDaGFuZ2UgPSB0ZXh0Q2hhbmdlZCA9IG51bGw7CisgICAgICBjaGFuZ2VzID0gW107IHNlbGVjdGlvbkNoYW5nZWQgPSBmYWxzZTsgY2FsbGJhY2tzID0gW107CisgICAgfQorICAgIGZ1bmN0aW9uIGVuZE9wZXJhdGlvbigpIHsKKyAgICAgIHZhciByZVNjcm9sbCA9IGZhbHNlLCB1cGRhdGVkOworICAgICAgaWYgKHNlbGVjdGlvbkNoYW5nZWQpIHJlU2Nyb2xsID0gIXNjcm9sbEN1cnNvckludG9WaWV3KCk7CisgICAgICBpZiAoY2hhbmdlcy5sZW5ndGgpIHVwZGF0ZWQgPSB1cGRhdGVEaXNwbGF5KGNoYW5nZXMsIHRydWUpOworICAgICAgZWxzZSB7CisgICAgICAgIGlmIChzZWxlY3Rpb25DaGFuZ2VkKSB1cGRhdGVTZWxlY3Rpb24oKTsKKyAgICAgICAgaWYgKGd1dHRlckRpcnR5KSB1cGRhdGVHdXR0ZXIoKTsKKyAgICAgIH0KKyAgICAgIGlmIChyZVNjcm9sbCkgc2Nyb2xsQ3Vyc29ySW50b1ZpZXcoKTsKKyAgICAgIGlmIChzZWxlY3Rpb25DaGFuZ2VkKSB7c2Nyb2xsRWRpdG9ySW50b1ZpZXcoKTsgcmVzdGFydEJsaW5rKCk7fQorCisgICAgICBpZiAoZm9jdXNlZCAmJiAhbGVhdmVJbnB1dEFsb25lICYmCisgICAgICAgICAgKHVwZGF0ZUlucHV0ID09PSB0cnVlIHx8ICh1cGRhdGVJbnB1dCAhPT0gZmFsc2UgJiYgc2VsZWN0aW9uQ2hhbmdlZCkpKQorICAgICAgICByZXNldElucHV0KHVzZXJTZWxDaGFuZ2UpOworCisgICAgICBpZiAoc2VsZWN0aW9uQ2hhbmdlZCAmJiBvcHRpb25zLm1hdGNoQnJhY2tldHMpCisgICAgICAgIHNldFRpbWVvdXQob3BlcmF0aW9uKGZ1bmN0aW9uKCkgeworICAgICAgICAgIGlmIChicmFja2V0SGlnaGxpZ2h0ZWQpIHticmFja2V0SGlnaGxpZ2h0ZWQoKTsgYnJhY2tldEhpZ2hsaWdodGVkID0gbnVsbDt9CisgICAgICAgICAgaWYgKHBvc0VxKHNlbC5mcm9tLCBzZWwudG8pKSBtYXRjaEJyYWNrZXRzKGZhbHNlKTsKKyAgICAgICAgfSksIDIwKTsKKyAgICAgIHZhciB0YyA9IHRleHRDaGFuZ2VkLCBjYnMgPSBjYWxsYmFja3M7IC8vIHRoZXNlIGNhbiBiZSByZXNldCBieSBjYWxsYmFja3MKKyAgICAgIGlmIChzZWxlY3Rpb25DaGFuZ2VkICYmIG9wdGlvbnMub25DdXJzb3JBY3Rpdml0eSkKKyAgICAgICAgb3B0aW9ucy5vbkN1cnNvckFjdGl2aXR5KGluc3RhbmNlKTsKKyAgICAgIGlmICh0YyAmJiBvcHRpb25zLm9uQ2hhbmdlICYmIGluc3RhbmNlKQorICAgICAgICBvcHRpb25zLm9uQ2hhbmdlKGluc3RhbmNlLCB0Yyk7CisgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNicy5sZW5ndGg7ICsraSkgY2JzW2ldKGluc3RhbmNlKTsKKyAgICAgIGlmICh1cGRhdGVkICYmIG9wdGlvbnMub25VcGRhdGUpIG9wdGlvbnMub25VcGRhdGUoaW5zdGFuY2UpOworICAgIH0KKyAgICB2YXIgbmVzdGVkT3BlcmF0aW9uID0gMDsKKyAgICBmdW5jdGlvbiBvcGVyYXRpb24oZikgeworICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkgeworICAgICAgICBpZiAoIW5lc3RlZE9wZXJhdGlvbisrKSBzdGFydE9wZXJhdGlvbigpOworICAgICAgICB0cnkge3ZhciByZXN1bHQgPSBmLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7fQorICAgICAgICBmaW5hbGx5IHtpZiAoIS0tbmVzdGVkT3BlcmF0aW9uKSBlbmRPcGVyYXRpb24oKTt9CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICB9OworICAgIH0KKworICAgIGZ1bmN0aW9uIGNvbXBvdW5kQ2hhbmdlKGYpIHsKKyAgICAgIGhpc3Rvcnkuc3RhcnRDb21wb3VuZCgpOworICAgICAgdHJ5IHsgcmV0dXJuIGYoKTsgfSBmaW5hbGx5IHsgaGlzdG9yeS5lbmRDb21wb3VuZCgpOyB9CisgICAgfQorCisgICAgZm9yICh2YXIgZXh0IGluIGV4dGVuc2lvbnMpCisgICAgICBpZiAoZXh0ZW5zaW9ucy5wcm9wZXJ0eUlzRW51bWVyYWJsZShleHQpICYmCisgICAgICAgICAgIWluc3RhbmNlLnByb3BlcnR5SXNFbnVtZXJhYmxlKGV4dCkpCisgICAgICAgIGluc3RhbmNlW2V4dF0gPSBleHRlbnNpb25zW2V4dF07CisgICAgcmV0dXJuIGluc3RhbmNlOworICB9IC8vIChlbmQgb2YgZnVuY3Rpb24gQ29kZU1pcnJvcikKKworICAvLyBUaGUgZGVmYXVsdCBjb25maWd1cmF0aW9uIG9wdGlvbnMuCisgIENvZGVNaXJyb3IuZGVmYXVsdHMgPSB7CisgICAgdmFsdWU6ICIiLAorICAgIG1vZGU6IG51bGwsCisgICAgdGhlbWU6ICJkZWZhdWx0IiwKKyAgICBpbmRlbnRVbml0OiAyLAorICAgIGluZGVudFdpdGhUYWJzOiBmYWxzZSwKKyAgICBzbWFydEluZGVudDogdHJ1ZSwKKyAgICB0YWJTaXplOiA0LAorICAgIGtleU1hcDogImRlZmF1bHQiLAorICAgIGV4dHJhS2V5czogbnVsbCwKKyAgICBlbGVjdHJpY0NoYXJzOiB0cnVlLAorICAgIGF1dG9DbGVhckVtcHR5TGluZXM6IGZhbHNlLAorICAgIG9uS2V5RXZlbnQ6IG51bGwsCisgICAgb25EcmFnRXZlbnQ6IG51bGwsCisgICAgbGluZVdyYXBwaW5nOiBmYWxzZSwKKyAgICBsaW5lTnVtYmVyczogZmFsc2UsCisgICAgZ3V0dGVyOiBmYWxzZSwKKyAgICBmaXhlZEd1dHRlcjogZmFsc2UsCisgICAgZmlyc3RMaW5lTnVtYmVyOiAxLAorICAgIHJlYWRPbmx5OiBmYWxzZSwKKyAgICBkcmFnRHJvcDogdHJ1ZSwKKyAgICBvbkNoYW5nZTogbnVsbCwKKyAgICBvbkN1cnNvckFjdGl2aXR5OiBudWxsLAorICAgIG9uR3V0dGVyQ2xpY2s6IG51bGwsCisgICAgb25IaWdobGlnaHRDb21wbGV0ZTogbnVsbCwKKyAgICBvblVwZGF0ZTogbnVsbCwKKyAgICBvbkZvY3VzOiBudWxsLCBvbkJsdXI6IG51bGwsIG9uU2Nyb2xsOiBudWxsLAorICAgIG1hdGNoQnJhY2tldHM6IGZhbHNlLAorICAgIHdvcmtUaW1lOiAxMDAsCisgICAgd29ya0RlbGF5OiAyMDAsCisgICAgcG9sbEludGVydmFsOiAxMDAsCisgICAgdW5kb0RlcHRoOiA0MCwKKyAgICB0YWJpbmRleDogbnVsbCwKKyAgICBhdXRvZm9jdXM6IG51bGwKKyAgfTsKKworICB2YXIgaW9zID0gL0FwcGxlV2ViS2l0Ly50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpICYmIC9Nb2JpbGVcL1x3Ky8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTsKKyAgdmFyIG1hYyA9IGlvcyB8fCAvTWFjLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7CisgIHZhciB3aW4gPSAvV2luLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7CisKKyAgLy8gS25vd24gbW9kZXMsIGJ5IG5hbWUgYW5kIGJ5IE1JTUUKKyAgdmFyIG1vZGVzID0gQ29kZU1pcnJvci5tb2RlcyA9IHt9LCBtaW1lTW9kZXMgPSBDb2RlTWlycm9yLm1pbWVNb2RlcyA9IHt9OworICBDb2RlTWlycm9yLmRlZmluZU1vZGUgPSBmdW5jdGlvbihuYW1lLCBtb2RlKSB7CisgICAgaWYgKCFDb2RlTWlycm9yLmRlZmF1bHRzLm1vZGUgJiYgbmFtZSAhPSAibnVsbCIpIENvZGVNaXJyb3IuZGVmYXVsdHMubW9kZSA9IG5hbWU7CisgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAyKSB7CisgICAgICBtb2RlLmRlcGVuZGVuY2llcyA9IFtdOworICAgICAgZm9yICh2YXIgaSA9IDI7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyArK2kpIG1vZGUuZGVwZW5kZW5jaWVzLnB1c2goYXJndW1lbnRzW2ldKTsKKyAgICB9CisgICAgbW9kZXNbbmFtZV0gPSBtb2RlOworICB9OworICBDb2RlTWlycm9yLmRlZmluZU1JTUUgPSBmdW5jdGlvbihtaW1lLCBzcGVjKSB7CisgICAgbWltZU1vZGVzW21pbWVdID0gc3BlYzsKKyAgfTsKKyAgQ29kZU1pcnJvci5yZXNvbHZlTW9kZSA9IGZ1bmN0aW9uKHNwZWMpIHsKKyAgICBpZiAodHlwZW9mIHNwZWMgPT0gInN0cmluZyIgJiYgbWltZU1vZGVzLmhhc093blByb3BlcnR5KHNwZWMpKQorICAgICAgc3BlYyA9IG1pbWVNb2Rlc1tzcGVjXTsKKyAgICBlbHNlIGlmICh0eXBlb2Ygc3BlYyA9PSAic3RyaW5nIiAmJiAvXltcd1wtXStcL1tcd1wtXStcK3htbCQvLnRlc3Qoc3BlYykpCisgICAgICByZXR1cm4gQ29kZU1pcnJvci5yZXNvbHZlTW9kZSgiYXBwbGljYXRpb24veG1sIik7CisgICAgaWYgKHR5cGVvZiBzcGVjID09ICJzdHJpbmciKSByZXR1cm4ge25hbWU6IHNwZWN9OworICAgIGVsc2UgcmV0dXJuIHNwZWMgfHwge25hbWU6ICJudWxsIn07CisgIH07CisgIENvZGVNaXJyb3IuZ2V0TW9kZSA9IGZ1bmN0aW9uKG9wdGlvbnMsIHNwZWMpIHsKKyAgICB2YXIgc3BlYyA9IENvZGVNaXJyb3IucmVzb2x2ZU1vZGUoc3BlYyk7CisgICAgdmFyIG1mYWN0b3J5ID0gbW9kZXNbc3BlYy5uYW1lXTsKKyAgICBpZiAoIW1mYWN0b3J5KSByZXR1cm4gQ29kZU1pcnJvci5nZXRNb2RlKG9wdGlvbnMsICJ0ZXh0L3BsYWluIik7CisgICAgcmV0dXJuIG1mYWN0b3J5KG9wdGlvbnMsIHNwZWMpOworICB9OworICBDb2RlTWlycm9yLmxpc3RNb2RlcyA9IGZ1bmN0aW9uKCkgeworICAgIHZhciBsaXN0ID0gW107CisgICAgZm9yICh2YXIgbSBpbiBtb2RlcykKKyAgICAgIGlmIChtb2Rlcy5wcm9wZXJ0eUlzRW51bWVyYWJsZShtKSkgbGlzdC5wdXNoKG0pOworICAgIHJldHVybiBsaXN0OworICB9OworICBDb2RlTWlycm9yLmxpc3RNSU1FcyA9IGZ1bmN0aW9uKCkgeworICAgIHZhciBsaXN0ID0gW107CisgICAgZm9yICh2YXIgbSBpbiBtaW1lTW9kZXMpCisgICAgICBpZiAobWltZU1vZGVzLnByb3BlcnR5SXNFbnVtZXJhYmxlKG0pKSBsaXN0LnB1c2goe21pbWU6IG0sIG1vZGU6IG1pbWVNb2Rlc1ttXX0pOworICAgIHJldHVybiBsaXN0OworICB9OworCisgIHZhciBleHRlbnNpb25zID0gQ29kZU1pcnJvci5leHRlbnNpb25zID0ge307CisgIENvZGVNaXJyb3IuZGVmaW5lRXh0ZW5zaW9uID0gZnVuY3Rpb24obmFtZSwgZnVuYykgeworICAgIGV4dGVuc2lvbnNbbmFtZV0gPSBmdW5jOworICB9OworCisgIHZhciBjb21tYW5kcyA9IENvZGVNaXJyb3IuY29tbWFuZHMgPSB7CisgICAgc2VsZWN0QWxsOiBmdW5jdGlvbihjbSkge2NtLnNldFNlbGVjdGlvbih7bGluZTogMCwgY2g6IDB9LCB7bGluZTogY20ubGluZUNvdW50KCkgLSAxfSk7fSwKKyAgICBraWxsTGluZTogZnVuY3Rpb24oY20pIHsKKyAgICAgIHZhciBmcm9tID0gY20uZ2V0Q3Vyc29yKHRydWUpLCB0byA9IGNtLmdldEN1cnNvcihmYWxzZSksIHNlbCA9ICFwb3NFcShmcm9tLCB0byk7CisgICAgICBpZiAoIXNlbCAmJiBjbS5nZXRMaW5lKGZyb20ubGluZSkubGVuZ3RoID09IGZyb20uY2gpIGNtLnJlcGxhY2VSYW5nZSgiIiwgZnJvbSwge2xpbmU6IGZyb20ubGluZSArIDEsIGNoOiAwfSk7CisgICAgICBlbHNlIGNtLnJlcGxhY2VSYW5nZSgiIiwgZnJvbSwgc2VsID8gdG8gOiB7bGluZTogZnJvbS5saW5lfSk7CisgICAgfSwKKyAgICBkZWxldGVMaW5lOiBmdW5jdGlvbihjbSkge3ZhciBsID0gY20uZ2V0Q3Vyc29yKCkubGluZTsgY20ucmVwbGFjZVJhbmdlKCIiLCB7bGluZTogbCwgY2g6IDB9LCB7bGluZTogbH0pO30sCisgICAgdW5kbzogZnVuY3Rpb24oY20pIHtjbS51bmRvKCk7fSwKKyAgICByZWRvOiBmdW5jdGlvbihjbSkge2NtLnJlZG8oKTt9LAorICAgIGdvRG9jU3RhcnQ6IGZ1bmN0aW9uKGNtKSB7Y20uc2V0Q3Vyc29yKDAsIDAsIHRydWUpO30sCisgICAgZ29Eb2NFbmQ6IGZ1bmN0aW9uKGNtKSB7Y20uc2V0U2VsZWN0aW9uKHtsaW5lOiBjbS5saW5lQ291bnQoKSAtIDF9LCBudWxsLCB0cnVlKTt9LAorICAgIGdvTGluZVN0YXJ0OiBmdW5jdGlvbihjbSkge2NtLnNldEN1cnNvcihjbS5nZXRDdXJzb3IoKS5saW5lLCAwLCB0cnVlKTt9LAorICAgIGdvTGluZVN0YXJ0U21hcnQ6IGZ1bmN0aW9uKGNtKSB7CisgICAgICB2YXIgY3VyID0gY20uZ2V0Q3Vyc29yKCk7CisgICAgICB2YXIgdGV4dCA9IGNtLmdldExpbmUoY3VyLmxpbmUpLCBmaXJzdE5vbldTID0gTWF0aC5tYXgoMCwgdGV4dC5zZWFyY2goL1xTLykpOworICAgICAgY20uc2V0Q3Vyc29yKGN1ci5saW5lLCBjdXIuY2ggPD0gZmlyc3ROb25XUyAmJiBjdXIuY2ggPyAwIDogZmlyc3ROb25XUywgdHJ1ZSk7CisgICAgfSwKKyAgICBnb0xpbmVFbmQ6IGZ1bmN0aW9uKGNtKSB7Y20uc2V0U2VsZWN0aW9uKHtsaW5lOiBjbS5nZXRDdXJzb3IoKS5saW5lfSwgbnVsbCwgdHJ1ZSk7fSwKKyAgICBnb0xpbmVVcDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlVigtMSwgImxpbmUiKTt9LAorICAgIGdvTGluZURvd246IGZ1bmN0aW9uKGNtKSB7Y20ubW92ZVYoMSwgImxpbmUiKTt9LAorICAgIGdvUGFnZVVwOiBmdW5jdGlvbihjbSkge2NtLm1vdmVWKC0xLCAicGFnZSIpO30sCisgICAgZ29QYWdlRG93bjogZnVuY3Rpb24oY20pIHtjbS5tb3ZlVigxLCAicGFnZSIpO30sCisgICAgZ29DaGFyTGVmdDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlSCgtMSwgImNoYXIiKTt9LAorICAgIGdvQ2hhclJpZ2h0OiBmdW5jdGlvbihjbSkge2NtLm1vdmVIKDEsICJjaGFyIik7fSwKKyAgICBnb0NvbHVtbkxlZnQ6IGZ1bmN0aW9uKGNtKSB7Y20ubW92ZUgoLTEsICJjb2x1bW4iKTt9LAorICAgIGdvQ29sdW1uUmlnaHQ6IGZ1bmN0aW9uKGNtKSB7Y20ubW92ZUgoMSwgImNvbHVtbiIpO30sCisgICAgZ29Xb3JkTGVmdDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlSCgtMSwgIndvcmQiKTt9LAorICAgIGdvV29yZFJpZ2h0OiBmdW5jdGlvbihjbSkge2NtLm1vdmVIKDEsICJ3b3JkIik7fSwKKyAgICBkZWxDaGFyTGVmdDogZnVuY3Rpb24oY20pIHtjbS5kZWxldGVIKC0xLCAiY2hhciIpO30sCisgICAgZGVsQ2hhclJpZ2h0OiBmdW5jdGlvbihjbSkge2NtLmRlbGV0ZUgoMSwgImNoYXIiKTt9LAorICAgIGRlbFdvcmRMZWZ0OiBmdW5jdGlvbihjbSkge2NtLmRlbGV0ZUgoLTEsICJ3b3JkIik7fSwKKyAgICBkZWxXb3JkUmlnaHQ6IGZ1bmN0aW9uKGNtKSB7Y20uZGVsZXRlSCgxLCAid29yZCIpO30sCisgICAgaW5kZW50QXV0bzogZnVuY3Rpb24oY20pIHtjbS5pbmRlbnRTZWxlY3Rpb24oInNtYXJ0Iik7fSwKKyAgICBpbmRlbnRNb3JlOiBmdW5jdGlvbihjbSkge2NtLmluZGVudFNlbGVjdGlvbigiYWRkIik7fSwKKyAgICBpbmRlbnRMZXNzOiBmdW5jdGlvbihjbSkge2NtLmluZGVudFNlbGVjdGlvbigic3VidHJhY3QiKTt9LAorICAgIGluc2VydFRhYjogZnVuY3Rpb24oY20pIHtjbS5yZXBsYWNlU2VsZWN0aW9uKCJcdCIsICJlbmQiKTt9LAorICAgIHRyYW5zcG9zZUNoYXJzOiBmdW5jdGlvbihjbSkgeworICAgICAgdmFyIGN1ciA9IGNtLmdldEN1cnNvcigpLCBsaW5lID0gY20uZ2V0TGluZShjdXIubGluZSk7CisgICAgICBpZiAoY3VyLmNoID4gMCAmJiBjdXIuY2ggPCBsaW5lLmxlbmd0aCAtIDEpCisgICAgICAgIGNtLnJlcGxhY2VSYW5nZShsaW5lLmNoYXJBdChjdXIuY2gpICsgbGluZS5jaGFyQXQoY3VyLmNoIC0gMSksCisgICAgICAgICAgICAgICAgICAgICAgICB7bGluZTogY3VyLmxpbmUsIGNoOiBjdXIuY2ggLSAxfSwge2xpbmU6IGN1ci5saW5lLCBjaDogY3VyLmNoICsgMX0pOworICAgIH0sCisgICAgbmV3bGluZUFuZEluZGVudDogZnVuY3Rpb24oY20pIHsKKyAgICAgIGNtLnJlcGxhY2VTZWxlY3Rpb24oIlxuIiwgImVuZCIpOworICAgICAgY20uaW5kZW50TGluZShjbS5nZXRDdXJzb3IoKS5saW5lKTsKKyAgICB9LAorICAgIHRvZ2dsZU92ZXJ3cml0ZTogZnVuY3Rpb24oY20pIHtjbS50b2dnbGVPdmVyd3JpdGUoKTt9CisgIH07CisKKyAgdmFyIGtleU1hcCA9IENvZGVNaXJyb3Iua2V5TWFwID0ge307CisgIGtleU1hcC5iYXNpYyA9IHsKKyAgICAiTGVmdCI6ICJnb0NoYXJMZWZ0IiwgIlJpZ2h0IjogImdvQ2hhclJpZ2h0IiwgIlVwIjogImdvTGluZVVwIiwgIkRvd24iOiAiZ29MaW5lRG93biIsCisgICAgIkVuZCI6ICJnb0xpbmVFbmQiLCAiSG9tZSI6ICJnb0xpbmVTdGFydFNtYXJ0IiwgIlBhZ2VVcCI6ICJnb1BhZ2VVcCIsICJQYWdlRG93biI6ICJnb1BhZ2VEb3duIiwKKyAgICAiRGVsZXRlIjogImRlbENoYXJSaWdodCIsICJCYWNrc3BhY2UiOiAiZGVsQ2hhckxlZnQiLCAiVGFiIjogImluc2VydFRhYiIsICJTaGlmdC1UYWIiOiAiaW5kZW50QXV0byIsCisgICAgIkVudGVyIjogIm5ld2xpbmVBbmRJbmRlbnQiLCAiSW5zZXJ0IjogInRvZ2dsZU92ZXJ3cml0ZSIKKyAgfTsKKyAgLy8gTm90ZSB0aGF0IHRoZSBzYXZlIGFuZCBmaW5kLXJlbGF0ZWQgY29tbWFuZHMgYXJlbid0IGRlZmluZWQgYnkKKyAgLy8gZGVmYXVsdC4gVW5rbm93biBjb21tYW5kcyBhcmUgc2ltcGx5IGlnbm9yZWQuCisgIGtleU1hcC5wY0RlZmF1bHQgPSB7CisgICAgIkN0cmwtQSI6ICJzZWxlY3RBbGwiLCAiQ3RybC1EIjogImRlbGV0ZUxpbmUiLCAiQ3RybC1aIjogInVuZG8iLCAiU2hpZnQtQ3RybC1aIjogInJlZG8iLCAiQ3RybC1ZIjogInJlZG8iLAorICAgICJDdHJsLUhvbWUiOiAiZ29Eb2NTdGFydCIsICJBbHQtVXAiOiAiZ29Eb2NTdGFydCIsICJDdHJsLUVuZCI6ICJnb0RvY0VuZCIsICJDdHJsLURvd24iOiAiZ29Eb2NFbmQiLAorICAgICJDdHJsLUxlZnQiOiAiZ29Xb3JkTGVmdCIsICJDdHJsLVJpZ2h0IjogImdvV29yZFJpZ2h0IiwgIkFsdC1MZWZ0IjogImdvTGluZVN0YXJ0IiwgIkFsdC1SaWdodCI6ICJnb0xpbmVFbmQiLAorICAgICJDdHJsLUJhY2tzcGFjZSI6ICJkZWxXb3JkTGVmdCIsICJDdHJsLURlbGV0ZSI6ICJkZWxXb3JkUmlnaHQiLCAiQ3RybC1TIjogInNhdmUiLCAiQ3RybC1GIjogImZpbmQiLAorICAgICJDdHJsLUciOiAiZmluZE5leHQiLCAiU2hpZnQtQ3RybC1HIjogImZpbmRQcmV2IiwgIlNoaWZ0LUN0cmwtRiI6ICJyZXBsYWNlIiwgIlNoaWZ0LUN0cmwtUiI6ICJyZXBsYWNlQWxsIiwKKyAgICAiQ3RybC1bIjogImluZGVudExlc3MiLCAiQ3RybC1dIjogImluZGVudE1vcmUiLAorICAgIGZhbGx0aHJvdWdoOiAiYmFzaWMiCisgIH07CisgIGtleU1hcC5tYWNEZWZhdWx0ID0geworICAgICJDbWQtQSI6ICJzZWxlY3RBbGwiLCAiQ21kLUQiOiAiZGVsZXRlTGluZSIsICJDbWQtWiI6ICJ1bmRvIiwgIlNoaWZ0LUNtZC1aIjogInJlZG8iLCAiQ21kLVkiOiAicmVkbyIsCisgICAgIkNtZC1VcCI6ICJnb0RvY1N0YXJ0IiwgIkNtZC1FbmQiOiAiZ29Eb2NFbmQiLCAiQ21kLURvd24iOiAiZ29Eb2NFbmQiLCAiQWx0LUxlZnQiOiAiZ29Xb3JkTGVmdCIsCisgICAgIkFsdC1SaWdodCI6ICJnb1dvcmRSaWdodCIsICJDbWQtTGVmdCI6ICJnb0xpbmVTdGFydCIsICJDbWQtUmlnaHQiOiAiZ29MaW5lRW5kIiwgIkFsdC1CYWNrc3BhY2UiOiAiZGVsV29yZExlZnQiLAorICAgICJDdHJsLUFsdC1CYWNrc3BhY2UiOiAiZGVsV29yZFJpZ2h0IiwgIkFsdC1EZWxldGUiOiAiZGVsV29yZFJpZ2h0IiwgIkNtZC1TIjogInNhdmUiLCAiQ21kLUYiOiAiZmluZCIsCisgICAgIkNtZC1HIjogImZpbmROZXh0IiwgIlNoaWZ0LUNtZC1HIjogImZpbmRQcmV2IiwgIkNtZC1BbHQtRiI6ICJyZXBsYWNlIiwgIlNoaWZ0LUNtZC1BbHQtRiI6ICJyZXBsYWNlQWxsIiwKKyAgICAiQ21kLVsiOiAiaW5kZW50TGVzcyIsICJDbWQtXSI6ICJpbmRlbnRNb3JlIiwKKyAgICBmYWxsdGhyb3VnaDogWyJiYXNpYyIsICJlbWFjc3kiXQorICB9OworICBrZXlNYXBbImRlZmF1bHQiXSA9IG1hYyA/IGtleU1hcC5tYWNEZWZhdWx0IDoga2V5TWFwLnBjRGVmYXVsdDsKKyAga2V5TWFwLmVtYWNzeSA9IHsKKyAgICAiQ3RybC1GIjogImdvQ2hhclJpZ2h0IiwgIkN0cmwtQiI6ICJnb0NoYXJMZWZ0IiwgIkN0cmwtUCI6ICJnb0xpbmVVcCIsICJDdHJsLU4iOiAiZ29MaW5lRG93biIsCisgICAgIkFsdC1GIjogImdvV29yZFJpZ2h0IiwgIkFsdC1CIjogImdvV29yZExlZnQiLCAiQ3RybC1BIjogImdvTGluZVN0YXJ0IiwgIkN0cmwtRSI6ICJnb0xpbmVFbmQiLAorICAgICJDdHJsLVYiOiAiZ29QYWdlVXAiLCAiU2hpZnQtQ3RybC1WIjogImdvUGFnZURvd24iLCAiQ3RybC1EIjogImRlbENoYXJSaWdodCIsICJDdHJsLUgiOiAiZGVsQ2hhckxlZnQiLAorICAgICJBbHQtRCI6ICJkZWxXb3JkUmlnaHQiLCAiQWx0LUJhY2tzcGFjZSI6ICJkZWxXb3JkTGVmdCIsICJDdHJsLUsiOiAia2lsbExpbmUiLCAiQ3RybC1UIjogInRyYW5zcG9zZUNoYXJzIgorICB9OworCisgIGZ1bmN0aW9uIGdldEtleU1hcCh2YWwpIHsKKyAgICBpZiAodHlwZW9mIHZhbCA9PSAic3RyaW5nIikgcmV0dXJuIGtleU1hcFt2YWxdOworICAgIGVsc2UgcmV0dXJuIHZhbDsKKyAgfQorICBmdW5jdGlvbiBsb29rdXBLZXkobmFtZSwgZXh0cmFNYXAsIG1hcCwgaGFuZGxlLCBzdG9wKSB7CisgICAgZnVuY3Rpb24gbG9va3VwKG1hcCkgeworICAgICAgbWFwID0gZ2V0S2V5TWFwKG1hcCk7CisgICAgICB2YXIgZm91bmQgPSBtYXBbbmFtZV07CisgICAgICBpZiAoZm91bmQgIT0gbnVsbCAmJiBoYW5kbGUoZm91bmQpKSByZXR1cm4gdHJ1ZTsKKyAgICAgIGlmIChtYXAubm9mYWxsdGhyb3VnaCkgeworICAgICAgICBpZiAoc3RvcCkgc3RvcCgpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIHZhciBmYWxsdGhyb3VnaCA9IG1hcC5mYWxsdGhyb3VnaDsKKyAgICAgIGlmIChmYWxsdGhyb3VnaCA9PSBudWxsKSByZXR1cm4gZmFsc2U7CisgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGZhbGx0aHJvdWdoKSAhPSAiW29iamVjdCBBcnJheV0iKQorICAgICAgICByZXR1cm4gbG9va3VwKGZhbGx0aHJvdWdoKTsKKyAgICAgIGZvciAodmFyIGkgPSAwLCBlID0gZmFsbHRocm91Z2gubGVuZ3RoOyBpIDwgZTsgKytpKSB7CisgICAgICAgIGlmIChsb29rdXAoZmFsbHRocm91Z2hbaV0pKSByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKGV4dHJhTWFwICYmIGxvb2t1cChleHRyYU1hcCkpIHJldHVybiB0cnVlOworICAgIHJldHVybiBsb29rdXAobWFwKTsKKyAgfQorICBmdW5jdGlvbiBpc01vZGlmaWVyS2V5KGV2ZW50KSB7CisgICAgdmFyIG5hbWUgPSBrZXlOYW1lc1tlX3Byb3AoZXZlbnQsICJrZXlDb2RlIildOworICAgIHJldHVybiBuYW1lID09ICJDdHJsIiB8fCBuYW1lID09ICJBbHQiIHx8IG5hbWUgPT0gIlNoaWZ0IiB8fCBuYW1lID09ICJNb2QiOworICB9CisKKyAgQ29kZU1pcnJvci5mcm9tVGV4dEFyZWEgPSBmdW5jdGlvbih0ZXh0YXJlYSwgb3B0aW9ucykgeworICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9OworICAgIG9wdGlvbnMudmFsdWUgPSB0ZXh0YXJlYS52YWx1ZTsKKyAgICBpZiAoIW9wdGlvbnMudGFiaW5kZXggJiYgdGV4dGFyZWEudGFiaW5kZXgpCisgICAgICBvcHRpb25zLnRhYmluZGV4ID0gdGV4dGFyZWEudGFiaW5kZXg7CisgICAgaWYgKG9wdGlvbnMuYXV0b2ZvY3VzID09IG51bGwgJiYgdGV4dGFyZWEuZ2V0QXR0cmlidXRlKCJhdXRvZm9jdXMiKSAhPSBudWxsKQorICAgICAgb3B0aW9ucy5hdXRvZm9jdXMgPSB0cnVlOworCisgICAgZnVuY3Rpb24gc2F2ZSgpIHt0ZXh0YXJlYS52YWx1ZSA9IGluc3RhbmNlLmdldFZhbHVlKCk7fQorICAgIGlmICh0ZXh0YXJlYS5mb3JtKSB7CisgICAgICAvLyBEZXBsb3JhYmxlIGhhY2sgdG8gbWFrZSB0aGUgc3VibWl0IG1ldGhvZCBkbyB0aGUgcmlnaHQgdGhpbmcuCisgICAgICB2YXIgcm1TdWJtaXQgPSBjb25uZWN0KHRleHRhcmVhLmZvcm0sICJzdWJtaXQiLCBzYXZlLCB0cnVlKTsKKyAgICAgIGlmICh0eXBlb2YgdGV4dGFyZWEuZm9ybS5zdWJtaXQgPT0gImZ1bmN0aW9uIikgeworICAgICAgICB2YXIgcmVhbFN1Ym1pdCA9IHRleHRhcmVhLmZvcm0uc3VibWl0OworICAgICAgICBmdW5jdGlvbiB3cmFwcGVkU3VibWl0KCkgeworICAgICAgICAgIHNhdmUoKTsKKyAgICAgICAgICB0ZXh0YXJlYS5mb3JtLnN1Ym1pdCA9IHJlYWxTdWJtaXQ7CisgICAgICAgICAgdGV4dGFyZWEuZm9ybS5zdWJtaXQoKTsKKyAgICAgICAgICB0ZXh0YXJlYS5mb3JtLnN1Ym1pdCA9IHdyYXBwZWRTdWJtaXQ7CisgICAgICAgIH0KKyAgICAgICAgdGV4dGFyZWEuZm9ybS5zdWJtaXQgPSB3cmFwcGVkU3VibWl0OworICAgICAgfQorICAgIH0KKworICAgIHRleHRhcmVhLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7CisgICAgdmFyIGluc3RhbmNlID0gQ29kZU1pcnJvcihmdW5jdGlvbihub2RlKSB7CisgICAgICB0ZXh0YXJlYS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShub2RlLCB0ZXh0YXJlYS5uZXh0U2libGluZyk7CisgICAgfSwgb3B0aW9ucyk7CisgICAgaW5zdGFuY2Uuc2F2ZSA9IHNhdmU7CisgICAgaW5zdGFuY2UuZ2V0VGV4dEFyZWEgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRleHRhcmVhOyB9OworICAgIGluc3RhbmNlLnRvVGV4dEFyZWEgPSBmdW5jdGlvbigpIHsKKyAgICAgIHNhdmUoKTsKKyAgICAgIHRleHRhcmVhLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoaW5zdGFuY2UuZ2V0V3JhcHBlckVsZW1lbnQoKSk7CisgICAgICB0ZXh0YXJlYS5zdHlsZS5kaXNwbGF5ID0gIiI7CisgICAgICBpZiAodGV4dGFyZWEuZm9ybSkgeworICAgICAgICBybVN1Ym1pdCgpOworICAgICAgICBpZiAodHlwZW9mIHRleHRhcmVhLmZvcm0uc3VibWl0ID09ICJmdW5jdGlvbiIpCisgICAgICAgICAgdGV4dGFyZWEuZm9ybS5zdWJtaXQgPSByZWFsU3VibWl0OworICAgICAgfQorICAgIH07CisgICAgcmV0dXJuIGluc3RhbmNlOworICB9OworCisgIC8vIFV0aWxpdHkgZnVuY3Rpb25zIGZvciB3b3JraW5nIHdpdGggc3RhdGUuIEV4cG9ydGVkIGJlY2F1c2UgbW9kZXMKKyAgLy8gc29tZXRpbWVzIG5lZWQgdG8gZG8gdGhpcy4KKyAgZnVuY3Rpb24gY29weVN0YXRlKG1vZGUsIHN0YXRlKSB7CisgICAgaWYgKHN0YXRlID09PSB0cnVlKSByZXR1cm4gc3RhdGU7CisgICAgaWYgKG1vZGUuY29weVN0YXRlKSByZXR1cm4gbW9kZS5jb3B5U3RhdGUoc3RhdGUpOworICAgIHZhciBuc3RhdGUgPSB7fTsKKyAgICBmb3IgKHZhciBuIGluIHN0YXRlKSB7CisgICAgICB2YXIgdmFsID0gc3RhdGVbbl07CisgICAgICBpZiAodmFsIGluc3RhbmNlb2YgQXJyYXkpIHZhbCA9IHZhbC5jb25jYXQoW10pOworICAgICAgbnN0YXRlW25dID0gdmFsOworICAgIH0KKyAgICByZXR1cm4gbnN0YXRlOworICB9CisgIENvZGVNaXJyb3IuY29weVN0YXRlID0gY29weVN0YXRlOworICBmdW5jdGlvbiBzdGFydFN0YXRlKG1vZGUsIGExLCBhMikgeworICAgIHJldHVybiBtb2RlLnN0YXJ0U3RhdGUgPyBtb2RlLnN0YXJ0U3RhdGUoYTEsIGEyKSA6IHRydWU7CisgIH0KKyAgQ29kZU1pcnJvci5zdGFydFN0YXRlID0gc3RhcnRTdGF0ZTsKKworICAvLyBUaGUgY2hhcmFjdGVyIHN0cmVhbSB1c2VkIGJ5IGEgbW9kZSdzIHBhcnNlci4KKyAgZnVuY3Rpb24gU3RyaW5nU3RyZWFtKHN0cmluZywgdGFiU2l6ZSkgeworICAgIHRoaXMucG9zID0gdGhpcy5zdGFydCA9IDA7CisgICAgdGhpcy5zdHJpbmcgPSBzdHJpbmc7CisgICAgdGhpcy50YWJTaXplID0gdGFiU2l6ZSB8fCA4OworICB9CisgIFN0cmluZ1N0cmVhbS5wcm90b3R5cGUgPSB7CisgICAgZW9sOiBmdW5jdGlvbigpIHtyZXR1cm4gdGhpcy5wb3MgPj0gdGhpcy5zdHJpbmcubGVuZ3RoO30sCisgICAgc29sOiBmdW5jdGlvbigpIHtyZXR1cm4gdGhpcy5wb3MgPT0gMDt9LAorICAgIHBlZWs6IGZ1bmN0aW9uKCkge3JldHVybiB0aGlzLnN0cmluZy5jaGFyQXQodGhpcy5wb3MpO30sCisgICAgbmV4dDogZnVuY3Rpb24oKSB7CisgICAgICBpZiAodGhpcy5wb3MgPCB0aGlzLnN0cmluZy5sZW5ndGgpCisgICAgICAgIHJldHVybiB0aGlzLnN0cmluZy5jaGFyQXQodGhpcy5wb3MrKyk7CisgICAgfSwKKyAgICBlYXQ6IGZ1bmN0aW9uKG1hdGNoKSB7CisgICAgICB2YXIgY2ggPSB0aGlzLnN0cmluZy5jaGFyQXQodGhpcy5wb3MpOworICAgICAgaWYgKHR5cGVvZiBtYXRjaCA9PSAic3RyaW5nIikgdmFyIG9rID0gY2ggPT0gbWF0Y2g7CisgICAgICBlbHNlIHZhciBvayA9IGNoICYmIChtYXRjaC50ZXN0ID8gbWF0Y2gudGVzdChjaCkgOiBtYXRjaChjaCkpOworICAgICAgaWYgKG9rKSB7Kyt0aGlzLnBvczsgcmV0dXJuIGNoO30KKyAgICB9LAorICAgIGVhdFdoaWxlOiBmdW5jdGlvbihtYXRjaCkgeworICAgICAgdmFyIHN0YXJ0ID0gdGhpcy5wb3M7CisgICAgICB3aGlsZSAodGhpcy5lYXQobWF0Y2gpKXt9CisgICAgICByZXR1cm4gdGhpcy5wb3MgPiBzdGFydDsKKyAgICB9LAorICAgIGVhdFNwYWNlOiBmdW5jdGlvbigpIHsKKyAgICAgIHZhciBzdGFydCA9IHRoaXMucG9zOworICAgICAgd2hpbGUgKC9bXHNcdTAwYTBdLy50ZXN0KHRoaXMuc3RyaW5nLmNoYXJBdCh0aGlzLnBvcykpKSArK3RoaXMucG9zOworICAgICAgcmV0dXJuIHRoaXMucG9zID4gc3RhcnQ7CisgICAgfSwKKyAgICBza2lwVG9FbmQ6IGZ1bmN0aW9uKCkge3RoaXMucG9zID0gdGhpcy5zdHJpbmcubGVuZ3RoO30sCisgICAgc2tpcFRvOiBmdW5jdGlvbihjaCkgeworICAgICAgdmFyIGZvdW5kID0gdGhpcy5zdHJpbmcuaW5kZXhPZihjaCwgdGhpcy5wb3MpOworICAgICAgaWYgKGZvdW5kID4gLTEpIHt0aGlzLnBvcyA9IGZvdW5kOyByZXR1cm4gdHJ1ZTt9CisgICAgfSwKKyAgICBiYWNrVXA6IGZ1bmN0aW9uKG4pIHt0aGlzLnBvcyAtPSBuO30sCisgICAgY29sdW1uOiBmdW5jdGlvbigpIHtyZXR1cm4gY291bnRDb2x1bW4odGhpcy5zdHJpbmcsIHRoaXMuc3RhcnQsIHRoaXMudGFiU2l6ZSk7fSwKKyAgICBpbmRlbnRhdGlvbjogZnVuY3Rpb24oKSB7cmV0dXJuIGNvdW50Q29sdW1uKHRoaXMuc3RyaW5nLCBudWxsLCB0aGlzLnRhYlNpemUpO30sCisgICAgbWF0Y2g6IGZ1bmN0aW9uKHBhdHRlcm4sIGNvbnN1bWUsIGNhc2VJbnNlbnNpdGl2ZSkgeworICAgICAgaWYgKHR5cGVvZiBwYXR0ZXJuID09ICJzdHJpbmciKSB7CisgICAgICAgIGZ1bmN0aW9uIGNhc2VkKHN0cikge3JldHVybiBjYXNlSW5zZW5zaXRpdmUgPyBzdHIudG9Mb3dlckNhc2UoKSA6IHN0cjt9CisgICAgICAgIGlmIChjYXNlZCh0aGlzLnN0cmluZykuaW5kZXhPZihjYXNlZChwYXR0ZXJuKSwgdGhpcy5wb3MpID09IHRoaXMucG9zKSB7CisgICAgICAgICAgaWYgKGNvbnN1bWUgIT09IGZhbHNlKSB0aGlzLnBvcyArPSBwYXR0ZXJuLmxlbmd0aDsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIHZhciBtYXRjaCA9IHRoaXMuc3RyaW5nLnNsaWNlKHRoaXMucG9zKS5tYXRjaChwYXR0ZXJuKTsKKyAgICAgICAgaWYgKG1hdGNoICYmIGNvbnN1bWUgIT09IGZhbHNlKSB0aGlzLnBvcyArPSBtYXRjaFswXS5sZW5ndGg7CisgICAgICAgIHJldHVybiBtYXRjaDsKKyAgICAgIH0KKyAgICB9LAorICAgIGN1cnJlbnQ6IGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuc3RyaW5nLnNsaWNlKHRoaXMuc3RhcnQsIHRoaXMucG9zKTt9CisgIH07CisgIENvZGVNaXJyb3IuU3RyaW5nU3RyZWFtID0gU3RyaW5nU3RyZWFtOworCisgIGZ1bmN0aW9uIE1hcmtlZFRleHQoZnJvbSwgdG8sIGNsYXNzTmFtZSwgbWFya2VyKSB7CisgICAgdGhpcy5mcm9tID0gZnJvbTsgdGhpcy50byA9IHRvOyB0aGlzLnN0eWxlID0gY2xhc3NOYW1lOyB0aGlzLm1hcmtlciA9IG1hcmtlcjsKKyAgfQorICBNYXJrZWRUZXh0LnByb3RvdHlwZSA9IHsKKyAgICBhdHRhY2g6IGZ1bmN0aW9uKGxpbmUpIHsgdGhpcy5tYXJrZXIuc2V0LnB1c2gobGluZSk7IH0sCisgICAgZGV0YWNoOiBmdW5jdGlvbihsaW5lKSB7CisgICAgICB2YXIgaXggPSBpbmRleE9mKHRoaXMubWFya2VyLnNldCwgbGluZSk7CisgICAgICBpZiAoaXggPiAtMSkgdGhpcy5tYXJrZXIuc2V0LnNwbGljZShpeCwgMSk7CisgICAgfSwKKyAgICBzcGxpdDogZnVuY3Rpb24ocG9zLCBsZW5CZWZvcmUpIHsKKyAgICAgIGlmICh0aGlzLnRvIDw9IHBvcyAmJiB0aGlzLnRvICE9IG51bGwpIHJldHVybiBudWxsOworICAgICAgdmFyIGZyb20gPSB0aGlzLmZyb20gPCBwb3MgfHwgdGhpcy5mcm9tID09IG51bGwgPyBudWxsIDogdGhpcy5mcm9tIC0gcG9zICsgbGVuQmVmb3JlOworICAgICAgdmFyIHRvID0gdGhpcy50byA9PSBudWxsID8gbnVsbCA6IHRoaXMudG8gLSBwb3MgKyBsZW5CZWZvcmU7CisgICAgICByZXR1cm4gbmV3IE1hcmtlZFRleHQoZnJvbSwgdG8sIHRoaXMuc3R5bGUsIHRoaXMubWFya2VyKTsKKyAgICB9LAorICAgIGR1cDogZnVuY3Rpb24oKSB7IHJldHVybiBuZXcgTWFya2VkVGV4dChudWxsLCBudWxsLCB0aGlzLnN0eWxlLCB0aGlzLm1hcmtlcik7IH0sCisgICAgY2xpcFRvOiBmdW5jdGlvbihmcm9tT3BlbiwgZnJvbSwgdG9PcGVuLCB0bywgZGlmZikgeworICAgICAgaWYgKGZyb21PcGVuICYmIHRvID4gdGhpcy5mcm9tICYmICh0byA8IHRoaXMudG8gfHwgdGhpcy50byA9PSBudWxsKSkKKyAgICAgICAgdGhpcy5mcm9tID0gbnVsbDsKKyAgICAgIGVsc2UgaWYgKHRoaXMuZnJvbSAhPSBudWxsICYmIHRoaXMuZnJvbSA+PSBmcm9tKQorICAgICAgICB0aGlzLmZyb20gPSBNYXRoLm1heCh0bywgdGhpcy5mcm9tKSArIGRpZmY7CisgICAgICBpZiAodG9PcGVuICYmIChmcm9tIDwgdGhpcy50byB8fCB0aGlzLnRvID09IG51bGwpICYmIChmcm9tID4gdGhpcy5mcm9tIHx8IHRoaXMuZnJvbSA9PSBudWxsKSkKKyAgICAgICAgdGhpcy50byA9IG51bGw7CisgICAgICBlbHNlIGlmICh0aGlzLnRvICE9IG51bGwgJiYgdGhpcy50byA+IGZyb20pCisgICAgICAgIHRoaXMudG8gPSB0byA8IHRoaXMudG8gPyB0aGlzLnRvICsgZGlmZiA6IGZyb207CisgICAgfSwKKyAgICBpc0RlYWQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy5mcm9tICE9IG51bGwgJiYgdGhpcy50byAhPSBudWxsICYmIHRoaXMuZnJvbSA+PSB0aGlzLnRvOyB9LAorICAgIHNhbWVTZXQ6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHRoaXMubWFya2VyID09IHgubWFya2VyOyB9CisgIH07CisKKyAgZnVuY3Rpb24gQm9va21hcmsocG9zKSB7CisgICAgdGhpcy5mcm9tID0gcG9zOyB0aGlzLnRvID0gcG9zOyB0aGlzLmxpbmUgPSBudWxsOworICB9CisgIEJvb2ttYXJrLnByb3RvdHlwZSA9IHsKKyAgICBhdHRhY2g6IGZ1bmN0aW9uKGxpbmUpIHsgdGhpcy5saW5lID0gbGluZTsgfSwKKyAgICBkZXRhY2g6IGZ1bmN0aW9uKGxpbmUpIHsgaWYgKHRoaXMubGluZSA9PSBsaW5lKSB0aGlzLmxpbmUgPSBudWxsOyB9LAorICAgIHNwbGl0OiBmdW5jdGlvbihwb3MsIGxlbkJlZm9yZSkgeworICAgICAgaWYgKHBvcyA8IHRoaXMuZnJvbSkgeworICAgICAgICB0aGlzLmZyb20gPSB0aGlzLnRvID0gKHRoaXMuZnJvbSAtIHBvcykgKyBsZW5CZWZvcmU7CisgICAgICAgIHJldHVybiB0aGlzOworICAgICAgfQorICAgIH0sCisgICAgaXNEZWFkOiBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXMuZnJvbSA+IHRoaXMudG87IH0sCisgICAgY2xpcFRvOiBmdW5jdGlvbihmcm9tT3BlbiwgZnJvbSwgdG9PcGVuLCB0bywgZGlmZikgeworICAgICAgaWYgKChmcm9tT3BlbiB8fCBmcm9tIDwgdGhpcy5mcm9tKSAmJiAodG9PcGVuIHx8IHRvID4gdGhpcy50bykpIHsKKyAgICAgICAgdGhpcy5mcm9tID0gMDsgdGhpcy50byA9IC0xOworICAgICAgfSBlbHNlIGlmICh0aGlzLmZyb20gPiBmcm9tKSB7CisgICAgICAgIHRoaXMuZnJvbSA9IHRoaXMudG8gPSBNYXRoLm1heCh0bywgdGhpcy5mcm9tKSArIGRpZmY7CisgICAgICB9CisgICAgfSwKKyAgICBzYW1lU2V0OiBmdW5jdGlvbih4KSB7IHJldHVybiBmYWxzZTsgfSwKKyAgICBmaW5kOiBmdW5jdGlvbigpIHsKKyAgICAgIGlmICghdGhpcy5saW5lIHx8ICF0aGlzLmxpbmUucGFyZW50KSByZXR1cm4gbnVsbDsKKyAgICAgIHJldHVybiB7bGluZTogbGluZU5vKHRoaXMubGluZSksIGNoOiB0aGlzLmZyb219OworICAgIH0sCisgICAgY2xlYXI6IGZ1bmN0aW9uKCkgeworICAgICAgaWYgKHRoaXMubGluZSkgeworICAgICAgICB2YXIgZm91bmQgPSBpbmRleE9mKHRoaXMubGluZS5tYXJrZWQsIHRoaXMpOworICAgICAgICBpZiAoZm91bmQgIT0gLTEpIHRoaXMubGluZS5tYXJrZWQuc3BsaWNlKGZvdW5kLCAxKTsKKyAgICAgICAgdGhpcy5saW5lID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisgIH07CisKKyAgLy8gTGluZSBvYmplY3RzLiBUaGVzZSBob2xkIHN0YXRlIHJlbGF0ZWQgdG8gYSBsaW5lLCBpbmNsdWRpbmcKKyAgLy8gaGlnaGxpZ2h0aW5nIGluZm8gKHRoZSBzdHlsZXMgYXJyYXkpLgorICBmdW5jdGlvbiBMaW5lKHRleHQsIHN0eWxlcykgeworICAgIHRoaXMuc3R5bGVzID0gc3R5bGVzIHx8IFt0ZXh0LCBudWxsXTsKKyAgICB0aGlzLnRleHQgPSB0ZXh0OworICAgIHRoaXMuaGVpZ2h0ID0gMTsKKyAgICB0aGlzLm1hcmtlZCA9IHRoaXMuZ3V0dGVyTWFya2VyID0gdGhpcy5jbGFzc05hbWUgPSB0aGlzLmJnQ2xhc3NOYW1lID0gdGhpcy5oYW5kbGVycyA9IG51bGw7CisgICAgdGhpcy5zdGF0ZUFmdGVyID0gdGhpcy5wYXJlbnQgPSB0aGlzLmhpZGRlbiA9IG51bGw7CisgIH0KKyAgTGluZS5pbmhlcml0TWFya3MgPSBmdW5jdGlvbih0ZXh0LCBvcmlnKSB7CisgICAgdmFyIGxuID0gbmV3IExpbmUodGV4dCksIG1rID0gb3JpZyAmJiBvcmlnLm1hcmtlZDsKKyAgICBpZiAobWspIHsKKyAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWsubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgaWYgKG1rW2ldLnRvID09IG51bGwgJiYgbWtbaV0uc3R5bGUpIHsKKyAgICAgICAgICB2YXIgbmV3bWsgPSBsbi5tYXJrZWQgfHwgKGxuLm1hcmtlZCA9IFtdKSwgbWFyayA9IG1rW2ldOworICAgICAgICAgIHZhciBubWFyayA9IG1hcmsuZHVwKCk7IG5ld21rLnB1c2gobm1hcmspOyBubWFyay5hdHRhY2gobG4pOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBsbjsKKyAgfQorICBMaW5lLnByb3RvdHlwZSA9IHsKKyAgICAvLyBSZXBsYWNlIGEgcGllY2Ugb2YgYSBsaW5lLCBrZWVwaW5nIHRoZSBzdHlsZXMgYXJvdW5kIGl0IGludGFjdC4KKyAgICByZXBsYWNlOiBmdW5jdGlvbihmcm9tLCB0b18sIHRleHQpIHsKKyAgICAgIHZhciBzdCA9IFtdLCBtayA9IHRoaXMubWFya2VkLCB0byA9IHRvXyA9PSBudWxsID8gdGhpcy50ZXh0Lmxlbmd0aCA6IHRvXzsKKyAgICAgIGNvcHlTdHlsZXMoMCwgZnJvbSwgdGhpcy5zdHlsZXMsIHN0KTsKKyAgICAgIGlmICh0ZXh0KSBzdC5wdXNoKHRleHQsIG51bGwpOworICAgICAgY29weVN0eWxlcyh0bywgdGhpcy50ZXh0Lmxlbmd0aCwgdGhpcy5zdHlsZXMsIHN0KTsKKyAgICAgIHRoaXMuc3R5bGVzID0gc3Q7CisgICAgICB0aGlzLnRleHQgPSB0aGlzLnRleHQuc2xpY2UoMCwgZnJvbSkgKyB0ZXh0ICsgdGhpcy50ZXh0LnNsaWNlKHRvKTsKKyAgICAgIHRoaXMuc3RhdGVBZnRlciA9IG51bGw7CisgICAgICBpZiAobWspIHsKKyAgICAgICAgdmFyIGRpZmYgPSB0ZXh0Lmxlbmd0aCAtICh0byAtIGZyb20pOworICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1rLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgdmFyIG1hcmsgPSBta1tpXTsKKyAgICAgICAgICBtYXJrLmNsaXBUbyhmcm9tID09IG51bGwsIGZyb20gfHwgMCwgdG9fID09IG51bGwsIHRvLCBkaWZmKTsKKyAgICAgICAgICBpZiAobWFyay5pc0RlYWQoKSkge21hcmsuZGV0YWNoKHRoaXMpOyBtay5zcGxpY2UoaS0tLCAxKTt9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9LAorICAgIC8vIFNwbGl0IGEgcGFydCBvZmYgYSBsaW5lLCBrZWVwaW5nIHN0eWxlcyBhbmQgbWFya2VycyBpbnRhY3QuCisgICAgc3BsaXQ6IGZ1bmN0aW9uKHBvcywgdGV4dEJlZm9yZSkgeworICAgICAgdmFyIHN0ID0gW3RleHRCZWZvcmUsIG51bGxdLCBtayA9IHRoaXMubWFya2VkOworICAgICAgY29weVN0eWxlcyhwb3MsIHRoaXMudGV4dC5sZW5ndGgsIHRoaXMuc3R5bGVzLCBzdCk7CisgICAgICB2YXIgdGFrZW4gPSBuZXcgTGluZSh0ZXh0QmVmb3JlICsgdGhpcy50ZXh0LnNsaWNlKHBvcyksIHN0KTsKKyAgICAgIGlmIChtaykgeworICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1rLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgdmFyIG1hcmsgPSBta1tpXTsKKyAgICAgICAgICB2YXIgbmV3bWFyayA9IG1hcmsuc3BsaXQocG9zLCB0ZXh0QmVmb3JlLmxlbmd0aCk7CisgICAgICAgICAgaWYgKG5ld21hcmspIHsKKyAgICAgICAgICAgIGlmICghdGFrZW4ubWFya2VkKSB0YWtlbi5tYXJrZWQgPSBbXTsKKyAgICAgICAgICAgIHRha2VuLm1hcmtlZC5wdXNoKG5ld21hcmspOyBuZXdtYXJrLmF0dGFjaCh0YWtlbik7CisgICAgICAgICAgICBpZiAobmV3bWFyayA9PSBtYXJrKSBtay5zcGxpY2UoaS0tLCAxKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiB0YWtlbjsKKyAgICB9LAorICAgIGFwcGVuZDogZnVuY3Rpb24obGluZSkgeworICAgICAgdmFyIG15bGVuID0gdGhpcy50ZXh0Lmxlbmd0aCwgbWsgPSBsaW5lLm1hcmtlZCwgbXltayA9IHRoaXMubWFya2VkOworICAgICAgdGhpcy50ZXh0ICs9IGxpbmUudGV4dDsKKyAgICAgIGNvcHlTdHlsZXMoMCwgbGluZS50ZXh0Lmxlbmd0aCwgbGluZS5zdHlsZXMsIHRoaXMuc3R5bGVzKTsKKyAgICAgIGlmIChteW1rKSB7CisgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXltay5sZW5ndGg7ICsraSkKKyAgICAgICAgICBpZiAobXlta1tpXS50byA9PSBudWxsKSBteW1rW2ldLnRvID0gbXlsZW47CisgICAgICB9CisgICAgICBpZiAobWsgJiYgbWsubGVuZ3RoKSB7CisgICAgICAgIGlmICghbXltaykgdGhpcy5tYXJrZWQgPSBteW1rID0gW107CisgICAgICAgIG91dGVyOiBmb3IgKHZhciBpID0gMDsgaSA8IG1rLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgdmFyIG1hcmsgPSBta1tpXTsKKyAgICAgICAgICBpZiAoIW1hcmsuZnJvbSkgeworICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBteW1rLmxlbmd0aDsgKytqKSB7CisgICAgICAgICAgICAgIHZhciBteW1hcmsgPSBteW1rW2pdOworICAgICAgICAgICAgICBpZiAobXltYXJrLnRvID09IG15bGVuICYmIG15bWFyay5zYW1lU2V0KG1hcmspKSB7CisgICAgICAgICAgICAgICAgbXltYXJrLnRvID0gbWFyay50byA9PSBudWxsID8gbnVsbCA6IG1hcmsudG8gKyBteWxlbjsKKyAgICAgICAgICAgICAgICBpZiAobXltYXJrLmlzRGVhZCgpKSB7CisgICAgICAgICAgICAgICAgICBteW1hcmsuZGV0YWNoKHRoaXMpOworICAgICAgICAgICAgICAgICAgbWsuc3BsaWNlKGktLSwgMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIG15bWsucHVzaChtYXJrKTsKKyAgICAgICAgICBtYXJrLmF0dGFjaCh0aGlzKTsKKyAgICAgICAgICBtYXJrLmZyb20gKz0gbXlsZW47CisgICAgICAgICAgaWYgKG1hcmsudG8gIT0gbnVsbCkgbWFyay50byArPSBteWxlbjsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0sCisgICAgZml4TWFya0VuZHM6IGZ1bmN0aW9uKG90aGVyKSB7CisgICAgICB2YXIgbWsgPSB0aGlzLm1hcmtlZCwgb21rID0gb3RoZXIubWFya2VkOworICAgICAgaWYgKCFtaykgcmV0dXJuOworICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtay5sZW5ndGg7ICsraSkgeworICAgICAgICB2YXIgbWFyayA9IG1rW2ldLCBjbG9zZSA9IG1hcmsudG8gPT0gbnVsbDsKKyAgICAgICAgaWYgKGNsb3NlICYmIG9taykgeworICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgb21rLmxlbmd0aDsgKytqKQorICAgICAgICAgICAgaWYgKG9ta1tqXS5zYW1lU2V0KG1hcmspKSB7Y2xvc2UgPSBmYWxzZTsgYnJlYWs7fQorICAgICAgICB9CisgICAgICAgIGlmIChjbG9zZSkgbWFyay50byA9IHRoaXMudGV4dC5sZW5ndGg7CisgICAgICB9CisgICAgfSwKKyAgICBmaXhNYXJrU3RhcnRzOiBmdW5jdGlvbigpIHsKKyAgICAgIHZhciBtayA9IHRoaXMubWFya2VkOworICAgICAgaWYgKCFtaykgcmV0dXJuOworICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtay5sZW5ndGg7ICsraSkKKyAgICAgICAgaWYgKG1rW2ldLmZyb20gPT0gbnVsbCkgbWtbaV0uZnJvbSA9IDA7CisgICAgfSwKKyAgICBhZGRNYXJrOiBmdW5jdGlvbihtYXJrKSB7CisgICAgICBtYXJrLmF0dGFjaCh0aGlzKTsKKyAgICAgIGlmICh0aGlzLm1hcmtlZCA9PSBudWxsKSB0aGlzLm1hcmtlZCA9IFtdOworICAgICAgdGhpcy5tYXJrZWQucHVzaChtYXJrKTsKKyAgICAgIHRoaXMubWFya2VkLnNvcnQoZnVuY3Rpb24oYSwgYil7cmV0dXJuIChhLmZyb20gfHwgMCkgLSAoYi5mcm9tIHx8IDApO30pOworICAgIH0sCisgICAgLy8gUnVuIHRoZSBnaXZlbiBtb2RlJ3MgcGFyc2VyIG92ZXIgYSBsaW5lLCB1cGRhdGUgdGhlIHN0eWxlcworICAgIC8vIGFycmF5LCB3aGljaCBjb250YWlucyBhbHRlcm5hdGluZyBmcmFnbWVudHMgb2YgdGV4dCBhbmQgQ1NTCisgICAgLy8gY2xhc3Nlcy4KKyAgICBoaWdobGlnaHQ6IGZ1bmN0aW9uKG1vZGUsIHN0YXRlLCB0YWJTaXplKSB7CisgICAgICB2YXIgc3RyZWFtID0gbmV3IFN0cmluZ1N0cmVhbSh0aGlzLnRleHQsIHRhYlNpemUpLCBzdCA9IHRoaXMuc3R5bGVzLCBwb3MgPSAwOworICAgICAgdmFyIGNoYW5nZWQgPSBmYWxzZSwgY3VyV29yZCA9IHN0WzBdLCBwcmV2V29yZDsKKyAgICAgIGlmICh0aGlzLnRleHQgPT0gIiIgJiYgbW9kZS5ibGFua0xpbmUpIG1vZGUuYmxhbmtMaW5lKHN0YXRlKTsKKyAgICAgIHdoaWxlICghc3RyZWFtLmVvbCgpKSB7CisgICAgICAgIHZhciBzdHlsZSA9IG1vZGUudG9rZW4oc3RyZWFtLCBzdGF0ZSk7CisgICAgICAgIHZhciBzdWJzdHIgPSB0aGlzLnRleHQuc2xpY2Uoc3RyZWFtLnN0YXJ0LCBzdHJlYW0ucG9zKTsKKyAgICAgICAgc3RyZWFtLnN0YXJ0ID0gc3RyZWFtLnBvczsKKyAgICAgICAgaWYgKHBvcyAmJiBzdFtwb3MtMV0gPT0gc3R5bGUpCisgICAgICAgICAgc3RbcG9zLTJdICs9IHN1YnN0cjsKKyAgICAgICAgZWxzZSBpZiAoc3Vic3RyKSB7CisgICAgICAgICAgaWYgKCFjaGFuZ2VkICYmIChzdFtwb3MrMV0gIT0gc3R5bGUgfHwgKHBvcyAmJiBzdFtwb3MtMl0gIT0gcHJldldvcmQpKSkgY2hhbmdlZCA9IHRydWU7CisgICAgICAgICAgc3RbcG9zKytdID0gc3Vic3RyOyBzdFtwb3MrK10gPSBzdHlsZTsKKyAgICAgICAgICBwcmV2V29yZCA9IGN1cldvcmQ7IGN1cldvcmQgPSBzdFtwb3NdOworICAgICAgICB9CisgICAgICAgIC8vIEdpdmUgdXAgd2hlbiBsaW5lIGlzIHJpZGljdWxvdXNseSBsb25nCisgICAgICAgIGlmIChzdHJlYW0ucG9zID4gNTAwMCkgeworICAgICAgICAgIHN0W3BvcysrXSA9IHRoaXMudGV4dC5zbGljZShzdHJlYW0ucG9zKTsgc3RbcG9zKytdID0gbnVsbDsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgaWYgKHN0Lmxlbmd0aCAhPSBwb3MpIHtzdC5sZW5ndGggPSBwb3M7IGNoYW5nZWQgPSB0cnVlO30KKyAgICAgIGlmIChwb3MgJiYgc3RbcG9zLTJdICE9IHByZXZXb3JkKSBjaGFuZ2VkID0gdHJ1ZTsKKyAgICAgIC8vIFNob3J0IGxpbmVzIHdpdGggc2ltcGxlIGhpZ2hsaWdodHMgcmV0dXJuIG51bGwsIGFuZCBhcmUKKyAgICAgIC8vIGNvdW50ZWQgYXMgY2hhbmdlZCBieSB0aGUgZHJpdmVyIGJlY2F1c2UgdGhleSBhcmUgbGlrZWx5IHRvCisgICAgICAvLyBoaWdobGlnaHQgdGhlIHNhbWUgd2F5IGluIHZhcmlvdXMgY29udGV4dHMuCisgICAgICByZXR1cm4gY2hhbmdlZCB8fCAoc3QubGVuZ3RoIDwgNSAmJiB0aGlzLnRleHQubGVuZ3RoIDwgMTAgPyBudWxsIDogZmFsc2UpOworICAgIH0sCisgICAgLy8gRmV0Y2ggdGhlIHBhcnNlciB0b2tlbiBmb3IgYSBnaXZlbiBjaGFyYWN0ZXIuIFVzZWZ1bCBmb3IgaGFja3MKKyAgICAvLyB0aGF0IHdhbnQgdG8gaW5zcGVjdCB0aGUgbW9kZSBzdGF0ZSAoc2F5LCBmb3IgY29tcGxldGlvbikuCisgICAgZ2V0VG9rZW5BdDogZnVuY3Rpb24obW9kZSwgc3RhdGUsIGNoKSB7CisgICAgICB2YXIgdHh0ID0gdGhpcy50ZXh0LCBzdHJlYW0gPSBuZXcgU3RyaW5nU3RyZWFtKHR4dCk7CisgICAgICB3aGlsZSAoc3RyZWFtLnBvcyA8IGNoICYmICFzdHJlYW0uZW9sKCkpIHsKKyAgICAgICAgc3RyZWFtLnN0YXJ0ID0gc3RyZWFtLnBvczsKKyAgICAgICAgdmFyIHN0eWxlID0gbW9kZS50b2tlbihzdHJlYW0sIHN0YXRlKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiB7c3RhcnQ6IHN0cmVhbS5zdGFydCwKKyAgICAgICAgICAgICAgZW5kOiBzdHJlYW0ucG9zLAorICAgICAgICAgICAgICBzdHJpbmc6IHN0cmVhbS5jdXJyZW50KCksCisgICAgICAgICAgICAgIGNsYXNzTmFtZTogc3R5bGUgfHwgbnVsbCwKKyAgICAgICAgICAgICAgc3RhdGU6IHN0YXRlfTsKKyAgICB9LAorICAgIGluZGVudGF0aW9uOiBmdW5jdGlvbih0YWJTaXplKSB7cmV0dXJuIGNvdW50Q29sdW1uKHRoaXMudGV4dCwgbnVsbCwgdGFiU2l6ZSk7fSwKKyAgICAvLyBQcm9kdWNlcyBhbiBIVE1MIGZyYWdtZW50IGZvciB0aGUgbGluZSwgdGFraW5nIHNlbGVjdGlvbiwKKyAgICAvLyBtYXJraW5nLCBhbmQgaGlnaGxpZ2h0aW5nIGludG8gYWNjb3VudC4KKyAgICBnZXRIVE1MOiBmdW5jdGlvbihtYWtlVGFiLCB3cmFwQXQsIHdyYXBJZCwgd3JhcFdCUikgeworICAgICAgdmFyIGh0bWwgPSBbXSwgZmlyc3QgPSB0cnVlLCBjb2wgPSAwOworICAgICAgZnVuY3Rpb24gc3Bhbl8odGV4dCwgc3R5bGUpIHsKKyAgICAgICAgaWYgKCF0ZXh0KSByZXR1cm47CisgICAgICAgIC8vIFdvcmsgYXJvdW5kIGEgYnVnIHdoZXJlLCBpbiBzb21lIGNvbXBhdCBtb2RlcywgSUUgaWdub3JlcyBsZWFkaW5nIHNwYWNlcworICAgICAgICBpZiAoZmlyc3QgJiYgaWUgJiYgdGV4dC5jaGFyQXQoMCkgPT0gIiAiKSB0ZXh0ID0gIlx1MDBhMCIgKyB0ZXh0LnNsaWNlKDEpOworICAgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgICBpZiAodGV4dC5pbmRleE9mKCJcdCIpID09IC0xKSB7CisgICAgICAgICAgY29sICs9IHRleHQubGVuZ3RoOworICAgICAgICAgIHZhciBlc2NhcGVkID0gaHRtbEVzY2FwZSh0ZXh0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB2YXIgZXNjYXBlZCA9ICIiOworICAgICAgICAgIGZvciAodmFyIHBvcyA9IDA7OykgeworICAgICAgICAgICAgdmFyIGlkeCA9IHRleHQuaW5kZXhPZigiXHQiLCBwb3MpOworICAgICAgICAgICAgaWYgKGlkeCA9PSAtMSkgeworICAgICAgICAgICAgICBlc2NhcGVkICs9IGh0bWxFc2NhcGUodGV4dC5zbGljZShwb3MpKTsKKyAgICAgICAgICAgICAgY29sICs9IHRleHQubGVuZ3RoIC0gcG9zOworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgIGNvbCArPSBpZHggLSBwb3M7CisgICAgICAgICAgICAgIHZhciB0YWIgPSBtYWtlVGFiKGNvbCk7CisgICAgICAgICAgICAgIGVzY2FwZWQgKz0gaHRtbEVzY2FwZSh0ZXh0LnNsaWNlKHBvcywgaWR4KSkgKyB0YWIuaHRtbDsKKyAgICAgICAgICAgICAgY29sICs9IHRhYi53aWR0aDsKKyAgICAgICAgICAgICAgcG9zID0gaWR4ICsgMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKHN0eWxlKSBodG1sLnB1c2goJzxzcGFuIGNsYXNzPSInLCBzdHlsZSwgJyI+JywgZXNjYXBlZCwgIjwvc3Bhbj4iKTsKKyAgICAgICAgZWxzZSBodG1sLnB1c2goZXNjYXBlZCk7CisgICAgICB9CisgICAgICB2YXIgc3BhbiA9IHNwYW5fOworICAgICAgaWYgKHdyYXBBdCAhPSBudWxsKSB7CisgICAgICAgIHZhciBvdXRQb3MgPSAwLCBvcGVuID0gIjxzcGFuIGlkPVwiIiArIHdyYXBJZCArICJcIj4iOworICAgICAgICBzcGFuID0gZnVuY3Rpb24odGV4dCwgc3R5bGUpIHsKKyAgICAgICAgICB2YXIgbCA9IHRleHQubGVuZ3RoOworICAgICAgICAgIGlmICh3cmFwQXQgPj0gb3V0UG9zICYmIHdyYXBBdCA8IG91dFBvcyArIGwpIHsKKyAgICAgICAgICAgIGlmICh3cmFwQXQgPiBvdXRQb3MpIHsKKyAgICAgICAgICAgICAgc3Bhbl8odGV4dC5zbGljZSgwLCB3cmFwQXQgLSBvdXRQb3MpLCBzdHlsZSk7CisgICAgICAgICAgICAgIC8vIFNlZSBjb21tZW50IGF0IHRoZSBkZWZpbml0aW9uIG9mIHNwYW5BZmZlY3RzV3JhcHBpbmcKKyAgICAgICAgICAgICAgaWYgKHdyYXBXQlIpIGh0bWwucHVzaCgiPHdicj4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGh0bWwucHVzaChvcGVuKTsKKyAgICAgICAgICAgIHNwYW5fKHRleHQuc2xpY2Uod3JhcEF0IC0gb3V0UG9zKSwgc3R5bGUpOworICAgICAgICAgICAgaHRtbC5wdXNoKCI8L3NwYW4+Iik7CisgICAgICAgICAgICB3cmFwQXQtLTsKKyAgICAgICAgICAgIG91dFBvcyArPSBsOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBvdXRQb3MgKz0gbDsKKyAgICAgICAgICAgIHNwYW5fKHRleHQsIHN0eWxlKTsKKyAgICAgICAgICAgIC8vIE91dHB1dCBlbXB0eSB3cmFwcGVyIHdoZW4gYXQgZW5kIG9mIGxpbmUKKyAgICAgICAgICAgIGlmIChvdXRQb3MgPT0gd3JhcEF0ICYmIG91dFBvcyA9PSBsZW4pIGh0bWwucHVzaChvcGVuICsgIjwvc3Bhbj4iKTsKKyAgICAgICAgICAgIC8vIFN0b3Agb3V0cHV0dGluZyBIVE1MIHdoZW4gZ29uZSBzdWZmaWNpZW50bHkgZmFyIGJleW9uZCBtZWFzdXJlCisgICAgICAgICAgICBlbHNlIGlmIChvdXRQb3MgPiB3cmFwQXQgKyAxMCAmJiAvXHMvLnRlc3QodGV4dCkpIHNwYW4gPSBmdW5jdGlvbigpe307CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisKKyAgICAgIHZhciBzdCA9IHRoaXMuc3R5bGVzLCBhbGxUZXh0ID0gdGhpcy50ZXh0LCBtYXJrZWQgPSB0aGlzLm1hcmtlZDsKKyAgICAgIHZhciBsZW4gPSBhbGxUZXh0Lmxlbmd0aDsKKyAgICAgIGZ1bmN0aW9uIHN0eWxlVG9DbGFzcyhzdHlsZSkgeworICAgICAgICBpZiAoIXN0eWxlKSByZXR1cm4gbnVsbDsKKyAgICAgICAgcmV0dXJuICJjbS0iICsgc3R5bGUucmVwbGFjZSgvICsvZywgIiBjbS0iKTsKKyAgICAgIH0KKworICAgICAgaWYgKCFhbGxUZXh0ICYmIHdyYXBBdCA9PSBudWxsKSB7CisgICAgICAgIHNwYW4oIiAiKTsKKyAgICAgIH0gZWxzZSBpZiAoIW1hcmtlZCB8fCAhbWFya2VkLmxlbmd0aCkgeworICAgICAgICBmb3IgKHZhciBpID0gMCwgY2ggPSAwOyBjaCA8IGxlbjsgaSs9MikgeworICAgICAgICAgIHZhciBzdHIgPSBzdFtpXSwgc3R5bGUgPSBzdFtpKzFdLCBsID0gc3RyLmxlbmd0aDsKKyAgICAgICAgICBpZiAoY2ggKyBsID4gbGVuKSBzdHIgPSBzdHIuc2xpY2UoMCwgbGVuIC0gY2gpOworICAgICAgICAgIGNoICs9IGw7CisgICAgICAgICAgc3BhbihzdHIsIHN0eWxlVG9DbGFzcyhzdHlsZSkpOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICB2YXIgcG9zID0gMCwgaSA9IDAsIHRleHQgPSAiIiwgc3R5bGUsIHNnID0gMDsKKyAgICAgICAgdmFyIG5leHRDaGFuZ2UgPSBtYXJrZWRbMF0uZnJvbSB8fCAwLCBtYXJrcyA9IFtdLCBtYXJrcG9zID0gMDsKKyAgICAgICAgZnVuY3Rpb24gYWR2YW5jZU1hcmtzKCkgeworICAgICAgICAgIHZhciBtOworICAgICAgICAgIHdoaWxlIChtYXJrcG9zIDwgbWFya2VkLmxlbmd0aCAmJgorICAgICAgICAgICAgICAgICAoKG0gPSBtYXJrZWRbbWFya3Bvc10pLmZyb20gPT0gcG9zIHx8IG0uZnJvbSA9PSBudWxsKSkgeworICAgICAgICAgICAgaWYgKG0uc3R5bGUgIT0gbnVsbCkgbWFya3MucHVzaChtKTsKKyAgICAgICAgICAgICsrbWFya3BvczsKKyAgICAgICAgICB9CisgICAgICAgICAgbmV4dENoYW5nZSA9IG1hcmtwb3MgPCBtYXJrZWQubGVuZ3RoID8gbWFya2VkW21hcmtwb3NdLmZyb20gOiBJbmZpbml0eTsKKyAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1hcmtzLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICB2YXIgdG8gPSBtYXJrc1tpXS50byB8fCBJbmZpbml0eTsKKyAgICAgICAgICAgIGlmICh0byA9PSBwb3MpIG1hcmtzLnNwbGljZShpLS0sIDEpOworICAgICAgICAgICAgZWxzZSBuZXh0Q2hhbmdlID0gTWF0aC5taW4odG8sIG5leHRDaGFuZ2UpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB2YXIgbSA9IDA7CisgICAgICAgIHdoaWxlIChwb3MgPCBsZW4pIHsKKyAgICAgICAgICBpZiAobmV4dENoYW5nZSA9PSBwb3MpIGFkdmFuY2VNYXJrcygpOworICAgICAgICAgIHZhciB1cHRvID0gTWF0aC5taW4obGVuLCBuZXh0Q2hhbmdlKTsKKyAgICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgICAgaWYgKHRleHQpIHsKKyAgICAgICAgICAgICAgdmFyIGVuZCA9IHBvcyArIHRleHQubGVuZ3RoOworICAgICAgICAgICAgICB2YXIgYXBwbGllZFN0eWxlID0gc3R5bGU7CisgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWFya3MubGVuZ3RoOyArK2opCisgICAgICAgICAgICAgICAgYXBwbGllZFN0eWxlID0gKGFwcGxpZWRTdHlsZSA/IGFwcGxpZWRTdHlsZSArICIgIiA6ICIiKSArIG1hcmtzW2pdLnN0eWxlOworICAgICAgICAgICAgICBzcGFuKGVuZCA+IHVwdG8gPyB0ZXh0LnNsaWNlKDAsIHVwdG8gLSBwb3MpIDogdGV4dCwgYXBwbGllZFN0eWxlKTsKKyAgICAgICAgICAgICAgaWYgKGVuZCA+PSB1cHRvKSB7dGV4dCA9IHRleHQuc2xpY2UodXB0byAtIHBvcyk7IHBvcyA9IHVwdG87IGJyZWFrO30KKyAgICAgICAgICAgICAgcG9zID0gZW5kOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGV4dCA9IHN0W2krK107IHN0eWxlID0gc3R5bGVUb0NsYXNzKHN0W2krK10pOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgICAgcmV0dXJuIGh0bWwuam9pbigiIik7CisgICAgfSwKKyAgICBjbGVhblVwOiBmdW5jdGlvbigpIHsKKyAgICAgIHRoaXMucGFyZW50ID0gbnVsbDsKKyAgICAgIGlmICh0aGlzLm1hcmtlZCkKKyAgICAgICAgZm9yICh2YXIgaSA9IDAsIGUgPSB0aGlzLm1hcmtlZC5sZW5ndGg7IGkgPCBlOyArK2kpIHRoaXMubWFya2VkW2ldLmRldGFjaCh0aGlzKTsKKyAgICB9CisgIH07CisgIC8vIFV0aWxpdHkgdXNlZCBieSByZXBsYWNlIGFuZCBzcGxpdCBhYm92ZQorICBmdW5jdGlvbiBjb3B5U3R5bGVzKGZyb20sIHRvLCBzb3VyY2UsIGRlc3QpIHsKKyAgICBmb3IgKHZhciBpID0gMCwgcG9zID0gMCwgc3RhdGUgPSAwOyBwb3MgPCB0bzsgaSs9MikgeworICAgICAgdmFyIHBhcnQgPSBzb3VyY2VbaV0sIGVuZCA9IHBvcyArIHBhcnQubGVuZ3RoOworICAgICAgaWYgKHN0YXRlID09IDApIHsKKyAgICAgICAgaWYgKGVuZCA+IGZyb20pIGRlc3QucHVzaChwYXJ0LnNsaWNlKGZyb20gLSBwb3MsIE1hdGgubWluKHBhcnQubGVuZ3RoLCB0byAtIHBvcykpLCBzb3VyY2VbaSsxXSk7CisgICAgICAgIGlmIChlbmQgPj0gZnJvbSkgc3RhdGUgPSAxOworICAgICAgfQorICAgICAgZWxzZSBpZiAoc3RhdGUgPT0gMSkgeworICAgICAgICBpZiAoZW5kID4gdG8pIGRlc3QucHVzaChwYXJ0LnNsaWNlKDAsIHRvIC0gcG9zKSwgc291cmNlW2krMV0pOworICAgICAgICBlbHNlIGRlc3QucHVzaChwYXJ0LCBzb3VyY2VbaSsxXSk7CisgICAgICB9CisgICAgICBwb3MgPSBlbmQ7CisgICAgfQorICB9CisKKyAgLy8gRGF0YSBzdHJ1Y3R1cmUgdGhhdCBob2xkcyB0aGUgc2VxdWVuY2Ugb2YgbGluZXMuCisgIGZ1bmN0aW9uIExlYWZDaHVuayhsaW5lcykgeworICAgIHRoaXMubGluZXMgPSBsaW5lczsKKyAgICB0aGlzLnBhcmVudCA9IG51bGw7CisgICAgZm9yICh2YXIgaSA9IDAsIGUgPSBsaW5lcy5sZW5ndGgsIGhlaWdodCA9IDA7IGkgPCBlOyArK2kpIHsKKyAgICAgIGxpbmVzW2ldLnBhcmVudCA9IHRoaXM7CisgICAgICBoZWlnaHQgKz0gbGluZXNbaV0uaGVpZ2h0OworICAgIH0KKyAgICB0aGlzLmhlaWdodCA9IGhlaWdodDsKKyAgfQorICBMZWFmQ2h1bmsucHJvdG90eXBlID0geworICAgIGNodW5rU2l6ZTogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLmxpbmVzLmxlbmd0aDsgfSwKKyAgICByZW1vdmU6IGZ1bmN0aW9uKGF0LCBuLCBjYWxsYmFja3MpIHsKKyAgICAgIGZvciAodmFyIGkgPSBhdCwgZSA9IGF0ICsgbjsgaSA8IGU7ICsraSkgeworICAgICAgICB2YXIgbGluZSA9IHRoaXMubGluZXNbaV07CisgICAgICAgIHRoaXMuaGVpZ2h0IC09IGxpbmUuaGVpZ2h0OworICAgICAgICBsaW5lLmNsZWFuVXAoKTsKKyAgICAgICAgaWYgKGxpbmUuaGFuZGxlcnMpCisgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBsaW5lLmhhbmRsZXJzLmxlbmd0aDsgKytqKSBjYWxsYmFja3MucHVzaChsaW5lLmhhbmRsZXJzW2pdKTsKKyAgICAgIH0KKyAgICAgIHRoaXMubGluZXMuc3BsaWNlKGF0LCBuKTsKKyAgICB9LAorICAgIGNvbGxhcHNlOiBmdW5jdGlvbihsaW5lcykgeworICAgICAgbGluZXMuc3BsaWNlLmFwcGx5KGxpbmVzLCBbbGluZXMubGVuZ3RoLCAwXS5jb25jYXQodGhpcy5saW5lcykpOworICAgIH0sCisgICAgaW5zZXJ0SGVpZ2h0OiBmdW5jdGlvbihhdCwgbGluZXMsIGhlaWdodCkgeworICAgICAgdGhpcy5oZWlnaHQgKz0gaGVpZ2h0OworICAgICAgLy8gVGhlIHRyaWNrIGJlbG93IGlzIGFwcGFyZW50bHkgdG9vIGFkdmFuY2VkIGZvciBJRSwgd2hpY2gKKyAgICAgIC8vIG9jY2FzaW9uYWxseSBjb3JydXB0cyB0aGlzLmxpbmVzIChkdXBsaWNhdGluZyBlbGVtZW50cykgd2hlbgorICAgICAgLy8gaXQgaXMgdXNlZC4KKyAgICAgIGlmIChpZSkgdGhpcy5saW5lcyA9IHRoaXMubGluZXMuc2xpY2UoMCwgYXQpLmNvbmNhdChsaW5lcykuY29uY2F0KHRoaXMubGluZXMuc2xpY2UoYXQpKTsKKyAgICAgIGVsc2UgdGhpcy5saW5lcy5zcGxpY2UuYXBwbHkodGhpcy5saW5lcywgW2F0LCAwXS5jb25jYXQobGluZXMpKTsKKyAgICAgIGZvciAodmFyIGkgPSAwLCBlID0gbGluZXMubGVuZ3RoOyBpIDwgZTsgKytpKSBsaW5lc1tpXS5wYXJlbnQgPSB0aGlzOworICAgIH0sCisgICAgaXRlck46IGZ1bmN0aW9uKGF0LCBuLCBvcCkgeworICAgICAgZm9yICh2YXIgZSA9IGF0ICsgbjsgYXQgPCBlOyArK2F0KQorICAgICAgICBpZiAob3AodGhpcy5saW5lc1thdF0pKSByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH07CisgIGZ1bmN0aW9uIEJyYW5jaENodW5rKGNoaWxkcmVuKSB7CisgICAgdGhpcy5jaGlsZHJlbiA9IGNoaWxkcmVuOworICAgIHZhciBzaXplID0gMCwgaGVpZ2h0ID0gMDsKKyAgICBmb3IgKHZhciBpID0gMCwgZSA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IGU7ICsraSkgeworICAgICAgdmFyIGNoID0gY2hpbGRyZW5baV07CisgICAgICBzaXplICs9IGNoLmNodW5rU2l6ZSgpOyBoZWlnaHQgKz0gY2guaGVpZ2h0OworICAgICAgY2gucGFyZW50ID0gdGhpczsKKyAgICB9CisgICAgdGhpcy5zaXplID0gc2l6ZTsKKyAgICB0aGlzLmhlaWdodCA9IGhlaWdodDsKKyAgICB0aGlzLnBhcmVudCA9IG51bGw7CisgIH0KKyAgQnJhbmNoQ2h1bmsucHJvdG90eXBlID0geworICAgIGNodW5rU2l6ZTogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLnNpemU7IH0sCisgICAgcmVtb3ZlOiBmdW5jdGlvbihhdCwgbiwgY2FsbGJhY2tzKSB7CisgICAgICB0aGlzLnNpemUgLT0gbjsKKyAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5jaGlsZHJlbi5sZW5ndGg7ICsraSkgeworICAgICAgICB2YXIgY2hpbGQgPSB0aGlzLmNoaWxkcmVuW2ldLCBzeiA9IGNoaWxkLmNodW5rU2l6ZSgpOworICAgICAgICBpZiAoYXQgPCBzeikgeworICAgICAgICAgIHZhciBybSA9IE1hdGgubWluKG4sIHN6IC0gYXQpLCBvbGRIZWlnaHQgPSBjaGlsZC5oZWlnaHQ7CisgICAgICAgICAgY2hpbGQucmVtb3ZlKGF0LCBybSwgY2FsbGJhY2tzKTsKKyAgICAgICAgICB0aGlzLmhlaWdodCAtPSBvbGRIZWlnaHQgLSBjaGlsZC5oZWlnaHQ7CisgICAgICAgICAgaWYgKHN6ID09IHJtKSB7IHRoaXMuY2hpbGRyZW4uc3BsaWNlKGktLSwgMSk7IGNoaWxkLnBhcmVudCA9IG51bGw7IH0KKyAgICAgICAgICBpZiAoKG4gLT0gcm0pID09IDApIGJyZWFrOworICAgICAgICAgIGF0ID0gMDsKKyAgICAgICAgfSBlbHNlIGF0IC09IHN6OworICAgICAgfQorICAgICAgaWYgKHRoaXMuc2l6ZSAtIG4gPCAyNSkgeworICAgICAgICB2YXIgbGluZXMgPSBbXTsKKyAgICAgICAgdGhpcy5jb2xsYXBzZShsaW5lcyk7CisgICAgICAgIHRoaXMuY2hpbGRyZW4gPSBbbmV3IExlYWZDaHVuayhsaW5lcyldOworICAgICAgICB0aGlzLmNoaWxkcmVuWzBdLnBhcmVudCA9IHRoaXM7CisgICAgICB9CisgICAgfSwKKyAgICBjb2xsYXBzZTogZnVuY3Rpb24obGluZXMpIHsKKyAgICAgIGZvciAodmFyIGkgPSAwLCBlID0gdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGkgPCBlOyArK2kpIHRoaXMuY2hpbGRyZW5baV0uY29sbGFwc2UobGluZXMpOworICAgIH0sCisgICAgaW5zZXJ0OiBmdW5jdGlvbihhdCwgbGluZXMpIHsKKyAgICAgIHZhciBoZWlnaHQgPSAwOworICAgICAgZm9yICh2YXIgaSA9IDAsIGUgPSBsaW5lcy5sZW5ndGg7IGkgPCBlOyArK2kpIGhlaWdodCArPSBsaW5lc1tpXS5oZWlnaHQ7CisgICAgICB0aGlzLmluc2VydEhlaWdodChhdCwgbGluZXMsIGhlaWdodCk7CisgICAgfSwKKyAgICBpbnNlcnRIZWlnaHQ6IGZ1bmN0aW9uKGF0LCBsaW5lcywgaGVpZ2h0KSB7CisgICAgICB0aGlzLnNpemUgKz0gbGluZXMubGVuZ3RoOworICAgICAgdGhpcy5oZWlnaHQgKz0gaGVpZ2h0OworICAgICAgZm9yICh2YXIgaSA9IDAsIGUgPSB0aGlzLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGU7ICsraSkgeworICAgICAgICB2YXIgY2hpbGQgPSB0aGlzLmNoaWxkcmVuW2ldLCBzeiA9IGNoaWxkLmNodW5rU2l6ZSgpOworICAgICAgICBpZiAoYXQgPD0gc3opIHsKKyAgICAgICAgICBjaGlsZC5pbnNlcnRIZWlnaHQoYXQsIGxpbmVzLCBoZWlnaHQpOworICAgICAgICAgIGlmIChjaGlsZC5saW5lcyAmJiBjaGlsZC5saW5lcy5sZW5ndGggPiA1MCkgeworICAgICAgICAgICAgd2hpbGUgKGNoaWxkLmxpbmVzLmxlbmd0aCA+IDUwKSB7CisgICAgICAgICAgICAgIHZhciBzcGlsbGVkID0gY2hpbGQubGluZXMuc3BsaWNlKGNoaWxkLmxpbmVzLmxlbmd0aCAtIDI1LCAyNSk7CisgICAgICAgICAgICAgIHZhciBuZXdsZWFmID0gbmV3IExlYWZDaHVuayhzcGlsbGVkKTsKKyAgICAgICAgICAgICAgY2hpbGQuaGVpZ2h0IC09IG5ld2xlYWYuaGVpZ2h0OworICAgICAgICAgICAgICB0aGlzLmNoaWxkcmVuLnNwbGljZShpICsgMSwgMCwgbmV3bGVhZik7CisgICAgICAgICAgICAgIG5ld2xlYWYucGFyZW50ID0gdGhpczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMubWF5YmVTcGlsbCgpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBhdCAtPSBzejsKKyAgICAgIH0KKyAgICB9LAorICAgIG1heWJlU3BpbGw6IGZ1bmN0aW9uKCkgeworICAgICAgaWYgKHRoaXMuY2hpbGRyZW4ubGVuZ3RoIDw9IDEwKSByZXR1cm47CisgICAgICB2YXIgbWUgPSB0aGlzOworICAgICAgZG8geworICAgICAgICB2YXIgc3BpbGxlZCA9IG1lLmNoaWxkcmVuLnNwbGljZShtZS5jaGlsZHJlbi5sZW5ndGggLSA1LCA1KTsKKyAgICAgICAgdmFyIHNpYmxpbmcgPSBuZXcgQnJhbmNoQ2h1bmsoc3BpbGxlZCk7CisgICAgICAgIGlmICghbWUucGFyZW50KSB7IC8vIEJlY29tZSB0aGUgcGFyZW50IG5vZGUKKyAgICAgICAgICB2YXIgY29weSA9IG5ldyBCcmFuY2hDaHVuayhtZS5jaGlsZHJlbik7CisgICAgICAgICAgY29weS5wYXJlbnQgPSBtZTsKKyAgICAgICAgICBtZS5jaGlsZHJlbiA9IFtjb3B5LCBzaWJsaW5nXTsKKyAgICAgICAgICBtZSA9IGNvcHk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgbWUuc2l6ZSAtPSBzaWJsaW5nLnNpemU7CisgICAgICAgICAgbWUuaGVpZ2h0IC09IHNpYmxpbmcuaGVpZ2h0OworICAgICAgICAgIHZhciBteUluZGV4ID0gaW5kZXhPZihtZS5wYXJlbnQuY2hpbGRyZW4sIG1lKTsKKyAgICAgICAgICBtZS5wYXJlbnQuY2hpbGRyZW4uc3BsaWNlKG15SW5kZXggKyAxLCAwLCBzaWJsaW5nKTsKKyAgICAgICAgfQorICAgICAgICBzaWJsaW5nLnBhcmVudCA9IG1lLnBhcmVudDsKKyAgICAgIH0gd2hpbGUgKG1lLmNoaWxkcmVuLmxlbmd0aCA+IDEwKTsKKyAgICAgIG1lLnBhcmVudC5tYXliZVNwaWxsKCk7CisgICAgfSwKKyAgICBpdGVyOiBmdW5jdGlvbihmcm9tLCB0bywgb3ApIHsgdGhpcy5pdGVyTihmcm9tLCB0byAtIGZyb20sIG9wKTsgfSwKKyAgICBpdGVyTjogZnVuY3Rpb24oYXQsIG4sIG9wKSB7CisgICAgICBmb3IgKHZhciBpID0gMCwgZSA9IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgZTsgKytpKSB7CisgICAgICAgIHZhciBjaGlsZCA9IHRoaXMuY2hpbGRyZW5baV0sIHN6ID0gY2hpbGQuY2h1bmtTaXplKCk7CisgICAgICAgIGlmIChhdCA8IHN6KSB7CisgICAgICAgICAgdmFyIHVzZWQgPSBNYXRoLm1pbihuLCBzeiAtIGF0KTsKKyAgICAgICAgICBpZiAoY2hpbGQuaXRlck4oYXQsIHVzZWQsIG9wKSkgcmV0dXJuIHRydWU7CisgICAgICAgICAgaWYgKChuIC09IHVzZWQpID09IDApIGJyZWFrOworICAgICAgICAgIGF0ID0gMDsKKyAgICAgICAgfSBlbHNlIGF0IC09IHN6OworICAgICAgfQorICAgIH0KKyAgfTsKKworICBmdW5jdGlvbiBnZXRMaW5lQXQoY2h1bmssIG4pIHsKKyAgICB3aGlsZSAoIWNodW5rLmxpbmVzKSB7CisgICAgICBmb3IgKHZhciBpID0gMDs7ICsraSkgeworICAgICAgICB2YXIgY2hpbGQgPSBjaHVuay5jaGlsZHJlbltpXSwgc3ogPSBjaGlsZC5jaHVua1NpemUoKTsKKyAgICAgICAgaWYgKG4gPCBzeikgeyBjaHVuayA9IGNoaWxkOyBicmVhazsgfQorICAgICAgICBuIC09IHN6OworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gY2h1bmsubGluZXNbbl07CisgIH0KKyAgZnVuY3Rpb24gbGluZU5vKGxpbmUpIHsKKyAgICBpZiAobGluZS5wYXJlbnQgPT0gbnVsbCkgcmV0dXJuIG51bGw7CisgICAgdmFyIGN1ciA9IGxpbmUucGFyZW50LCBubyA9IGluZGV4T2YoY3VyLmxpbmVzLCBsaW5lKTsKKyAgICBmb3IgKHZhciBjaHVuayA9IGN1ci5wYXJlbnQ7IGNodW5rOyBjdXIgPSBjaHVuaywgY2h1bmsgPSBjaHVuay5wYXJlbnQpIHsKKyAgICAgIGZvciAodmFyIGkgPSAwLCBlID0gY2h1bmsuY2hpbGRyZW4ubGVuZ3RoOyA7ICsraSkgeworICAgICAgICBpZiAoY2h1bmsuY2hpbGRyZW5baV0gPT0gY3VyKSBicmVhazsKKyAgICAgICAgbm8gKz0gY2h1bmsuY2hpbGRyZW5baV0uY2h1bmtTaXplKCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBubzsKKyAgfQorICBmdW5jdGlvbiBsaW5lQXRIZWlnaHQoY2h1bmssIGgpIHsKKyAgICB2YXIgbiA9IDA7CisgICAgb3V0ZXI6IGRvIHsKKyAgICAgIGZvciAodmFyIGkgPSAwLCBlID0gY2h1bmsuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgZTsgKytpKSB7CisgICAgICAgIHZhciBjaGlsZCA9IGNodW5rLmNoaWxkcmVuW2ldLCBjaCA9IGNoaWxkLmhlaWdodDsKKyAgICAgICAgaWYgKGggPCBjaCkgeyBjaHVuayA9IGNoaWxkOyBjb250aW51ZSBvdXRlcjsgfQorICAgICAgICBoIC09IGNoOworICAgICAgICBuICs9IGNoaWxkLmNodW5rU2l6ZSgpOworICAgICAgfQorICAgICAgcmV0dXJuIG47CisgICAgfSB3aGlsZSAoIWNodW5rLmxpbmVzKTsKKyAgICBmb3IgKHZhciBpID0gMCwgZSA9IGNodW5rLmxpbmVzLmxlbmd0aDsgaSA8IGU7ICsraSkgeworICAgICAgdmFyIGxpbmUgPSBjaHVuay5saW5lc1tpXSwgbGggPSBsaW5lLmhlaWdodDsKKyAgICAgIGlmIChoIDwgbGgpIGJyZWFrOworICAgICAgaCAtPSBsaDsKKyAgICB9CisgICAgcmV0dXJuIG4gKyBpOworICB9CisgIGZ1bmN0aW9uIGhlaWdodEF0TGluZShjaHVuaywgbikgeworICAgIHZhciBoID0gMDsKKyAgICBvdXRlcjogZG8geworICAgICAgZm9yICh2YXIgaSA9IDAsIGUgPSBjaHVuay5jaGlsZHJlbi5sZW5ndGg7IGkgPCBlOyArK2kpIHsKKyAgICAgICAgdmFyIGNoaWxkID0gY2h1bmsuY2hpbGRyZW5baV0sIHN6ID0gY2hpbGQuY2h1bmtTaXplKCk7CisgICAgICAgIGlmIChuIDwgc3opIHsgY2h1bmsgPSBjaGlsZDsgY29udGludWUgb3V0ZXI7IH0KKyAgICAgICAgbiAtPSBzejsKKyAgICAgICAgaCArPSBjaGlsZC5oZWlnaHQ7CisgICAgICB9CisgICAgICByZXR1cm4gaDsKKyAgICB9IHdoaWxlICghY2h1bmsubGluZXMpOworICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKSBoICs9IGNodW5rLmxpbmVzW2ldLmhlaWdodDsKKyAgICByZXR1cm4gaDsKKyAgfQorCisgIC8vIFRoZSBoaXN0b3J5IG9iamVjdCAnY2h1bmtzJyBjaGFuZ2VzIHRoYXQgYXJlIG1hZGUgY2xvc2UgdG9nZXRoZXIKKyAgLy8gYW5kIGF0IGFsbW9zdCB0aGUgc2FtZSB0aW1lIGludG8gYmlnZ2VyIHVuZG9hYmxlIHVuaXRzLgorICBmdW5jdGlvbiBIaXN0b3J5KCkgeworICAgIHRoaXMudGltZSA9IDA7CisgICAgdGhpcy5kb25lID0gW107IHRoaXMudW5kb25lID0gW107CisgICAgdGhpcy5jb21wb3VuZCA9IDA7CisgICAgdGhpcy5jbG9zZWQgPSBmYWxzZTsKKyAgfQorICBIaXN0b3J5LnByb3RvdHlwZSA9IHsKKyAgICBhZGRDaGFuZ2U6IGZ1bmN0aW9uKHN0YXJ0LCBhZGRlZCwgb2xkKSB7CisgICAgICB0aGlzLnVuZG9uZS5sZW5ndGggPSAwOworICAgICAgdmFyIHRpbWUgPSArbmV3IERhdGUsIGN1ciA9IHRoaXMuZG9uZVt0aGlzLmRvbmUubGVuZ3RoIC0gMV0sIGxhc3QgPSBjdXIgJiYgY3VyW2N1ci5sZW5ndGggLSAxXTsKKyAgICAgIHZhciBkdGltZSA9IHRpbWUgLSB0aGlzLnRpbWU7CisKKyAgICAgIGlmICh0aGlzLmNvbXBvdW5kICYmIGN1ciAmJiAhdGhpcy5jbG9zZWQpIHsKKyAgICAgICAgY3VyLnB1c2goe3N0YXJ0OiBzdGFydCwgYWRkZWQ6IGFkZGVkLCBvbGQ6IG9sZH0pOworICAgICAgfSBlbHNlIGlmIChkdGltZSA+IDQwMCB8fCAhbGFzdCB8fCB0aGlzLmNsb3NlZCB8fAorICAgICAgICAgICAgICAgICBsYXN0LnN0YXJ0ID4gc3RhcnQgKyBvbGQubGVuZ3RoIHx8IGxhc3Quc3RhcnQgKyBsYXN0LmFkZGVkIDwgc3RhcnQpIHsKKyAgICAgICAgdGhpcy5kb25lLnB1c2goW3tzdGFydDogc3RhcnQsIGFkZGVkOiBhZGRlZCwgb2xkOiBvbGR9XSk7CisgICAgICAgIHRoaXMuY2xvc2VkID0gZmFsc2U7CisgICAgICB9IGVsc2UgeworICAgICAgICB2YXIgc3RhcnRCZWZvcmUgPSBNYXRoLm1heCgwLCBsYXN0LnN0YXJ0IC0gc3RhcnQpLAorICAgICAgICAgICAgZW5kQWZ0ZXIgPSBNYXRoLm1heCgwLCAoc3RhcnQgKyBvbGQubGVuZ3RoKSAtIChsYXN0LnN0YXJ0ICsgbGFzdC5hZGRlZCkpOworICAgICAgICBmb3IgKHZhciBpID0gc3RhcnRCZWZvcmU7IGkgPiAwOyAtLWkpIGxhc3Qub2xkLnVuc2hpZnQob2xkW2kgLSAxXSk7CisgICAgICAgIGZvciAodmFyIGkgPSBlbmRBZnRlcjsgaSA+IDA7IC0taSkgbGFzdC5vbGQucHVzaChvbGRbb2xkLmxlbmd0aCAtIGldKTsKKyAgICAgICAgaWYgKHN0YXJ0QmVmb3JlKSBsYXN0LnN0YXJ0ID0gc3RhcnQ7CisgICAgICAgIGxhc3QuYWRkZWQgKz0gYWRkZWQgLSAob2xkLmxlbmd0aCAtIHN0YXJ0QmVmb3JlIC0gZW5kQWZ0ZXIpOworICAgICAgfQorICAgICAgdGhpcy50aW1lID0gdGltZTsKKyAgICB9LAorICAgIHN0YXJ0Q29tcG91bmQ6IGZ1bmN0aW9uKCkgeworICAgICAgaWYgKCF0aGlzLmNvbXBvdW5kKyspIHRoaXMuY2xvc2VkID0gdHJ1ZTsKKyAgICB9LAorICAgIGVuZENvbXBvdW5kOiBmdW5jdGlvbigpIHsKKyAgICAgIGlmICghLS10aGlzLmNvbXBvdW5kKSB0aGlzLmNsb3NlZCA9IHRydWU7CisgICAgfQorICB9OworCisgIGZ1bmN0aW9uIHN0b3BNZXRob2QoKSB7ZV9zdG9wKHRoaXMpO30KKyAgLy8gRW5zdXJlIGFuIGV2ZW50IGhhcyBhIHN0b3AgbWV0aG9kLgorICBmdW5jdGlvbiBhZGRTdG9wKGV2ZW50KSB7CisgICAgaWYgKCFldmVudC5zdG9wKSBldmVudC5zdG9wID0gc3RvcE1ldGhvZDsKKyAgICByZXR1cm4gZXZlbnQ7CisgIH0KKworICBmdW5jdGlvbiBlX3ByZXZlbnREZWZhdWx0KGUpIHsKKyAgICBpZiAoZS5wcmV2ZW50RGVmYXVsdCkgZS5wcmV2ZW50RGVmYXVsdCgpOworICAgIGVsc2UgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlOworICB9CisgIGZ1bmN0aW9uIGVfc3RvcFByb3BhZ2F0aW9uKGUpIHsKKyAgICBpZiAoZS5zdG9wUHJvcGFnYXRpb24pIGUuc3RvcFByb3BhZ2F0aW9uKCk7CisgICAgZWxzZSBlLmNhbmNlbEJ1YmJsZSA9IHRydWU7CisgIH0KKyAgZnVuY3Rpb24gZV9zdG9wKGUpIHtlX3ByZXZlbnREZWZhdWx0KGUpOyBlX3N0b3BQcm9wYWdhdGlvbihlKTt9CisgIENvZGVNaXJyb3IuZV9zdG9wID0gZV9zdG9wOworICBDb2RlTWlycm9yLmVfcHJldmVudERlZmF1bHQgPSBlX3ByZXZlbnREZWZhdWx0OworICBDb2RlTWlycm9yLmVfc3RvcFByb3BhZ2F0aW9uID0gZV9zdG9wUHJvcGFnYXRpb247CisKKyAgZnVuY3Rpb24gZV90YXJnZXQoZSkge3JldHVybiBlLnRhcmdldCB8fCBlLnNyY0VsZW1lbnQ7fQorICBmdW5jdGlvbiBlX2J1dHRvbihlKSB7CisgICAgaWYgKGUud2hpY2gpIHJldHVybiBlLndoaWNoOworICAgIGVsc2UgaWYgKGUuYnV0dG9uICYgMSkgcmV0dXJuIDE7CisgICAgZWxzZSBpZiAoZS5idXR0b24gJiAyKSByZXR1cm4gMzsKKyAgICBlbHNlIGlmIChlLmJ1dHRvbiAmIDQpIHJldHVybiAyOworICB9CisKKyAgLy8gQWxsb3cgM3JkLXBhcnR5IGNvZGUgdG8gb3ZlcnJpZGUgZXZlbnQgcHJvcGVydGllcyBieSBhZGRpbmcgYW4gb3ZlcnJpZGUKKyAgLy8gb2JqZWN0IHRvIGFuIGV2ZW50IG9iamVjdC4KKyAgZnVuY3Rpb24gZV9wcm9wKGUsIHByb3ApIHsKKyAgICB2YXIgb3ZlcnJpZGRlbiA9IGUub3ZlcnJpZGUgJiYgZS5vdmVycmlkZS5oYXNPd25Qcm9wZXJ0eShwcm9wKTsKKyAgICByZXR1cm4gb3ZlcnJpZGRlbiA/IGUub3ZlcnJpZGVbcHJvcF0gOiBlW3Byb3BdOworICB9CisKKyAgLy8gRXZlbnQgaGFuZGxlciByZWdpc3RyYXRpb24uIElmIGRpc2Nvbm5lY3QgaXMgdHJ1ZSwgaXQnbGwgcmV0dXJuIGEKKyAgLy8gZnVuY3Rpb24gdGhhdCB1bnJlZ2lzdGVycyB0aGUgaGFuZGxlci4KKyAgZnVuY3Rpb24gY29ubmVjdChub2RlLCB0eXBlLCBoYW5kbGVyLCBkaXNjb25uZWN0KSB7CisgICAgaWYgKHR5cGVvZiBub2RlLmFkZEV2ZW50TGlzdGVuZXIgPT0gImZ1bmN0aW9uIikgeworICAgICAgbm9kZS5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGhhbmRsZXIsIGZhbHNlKTsKKyAgICAgIGlmIChkaXNjb25uZWN0KSByZXR1cm4gZnVuY3Rpb24oKSB7bm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGhhbmRsZXIsIGZhbHNlKTt9OworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIHZhciB3cmFwSGFuZGxlciA9IGZ1bmN0aW9uKGV2ZW50KSB7aGFuZGxlcihldmVudCB8fCB3aW5kb3cuZXZlbnQpO307CisgICAgICBub2RlLmF0dGFjaEV2ZW50KCJvbiIgKyB0eXBlLCB3cmFwSGFuZGxlcik7CisgICAgICBpZiAoZGlzY29ubmVjdCkgcmV0dXJuIGZ1bmN0aW9uKCkge25vZGUuZGV0YWNoRXZlbnQoIm9uIiArIHR5cGUsIHdyYXBIYW5kbGVyKTt9OworICAgIH0KKyAgfQorICBDb2RlTWlycm9yLmNvbm5lY3QgPSBjb25uZWN0OworCisgIGZ1bmN0aW9uIERlbGF5ZWQoKSB7dGhpcy5pZCA9IG51bGw7fQorICBEZWxheWVkLnByb3RvdHlwZSA9IHtzZXQ6IGZ1bmN0aW9uKG1zLCBmKSB7Y2xlYXJUaW1lb3V0KHRoaXMuaWQpOyB0aGlzLmlkID0gc2V0VGltZW91dChmLCBtcyk7fX07CisKKyAgdmFyIFBhc3MgPSBDb2RlTWlycm9yLlBhc3MgPSB7dG9TdHJpbmc6IGZ1bmN0aW9uKCl7cmV0dXJuICJDb2RlTWlycm9yLlBhc3MiO319OworCisgIHZhciBnZWNrbyA9IC9nZWNrb1wvXGR7N30vaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpOworICB2YXIgaWUgPSAvTVNJRSBcZC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTsKKyAgdmFyIGllX2x0OSA9IC9NU0lFIFsxLThdXGIvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7CisgIHZhciBxdWlya3NNb2RlID0gaWUgJiYgZG9jdW1lbnQuZG9jdW1lbnRNb2RlID09IDU7CisgIHZhciB3ZWJraXQgPSAvV2ViS2l0XC8vLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7CisgIHZhciBjaHJvbWUgPSAvQ2hyb21lXC8vLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7CisgIHZhciBzYWZhcmkgPSAvQXBwbGUgQ29tcHV0ZXIvLnRlc3QobmF2aWdhdG9yLnZlbmRvcik7CisgIHZhciBraHRtbCA9IC9LSFRNTFwvLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpOworCisgIC8vIERldGVjdCBkcmFnLWFuZC1kcm9wCisgIHZhciBkcmFnQW5kRHJvcCA9IGZ1bmN0aW9uKCkgeworICAgIC8vIFRoZXJlIGlzICpzb21lKiBraW5kIG9mIGRyYWctYW5kLWRyb3Agc3VwcG9ydCBpbiBJRTYtOCwgYnV0IEkKKyAgICAvLyBjb3VsZG4ndCBnZXQgaXQgdG8gd29yayB5ZXQuCisgICAgaWYgKGllX2x0OSkgcmV0dXJuIGZhbHNlOworICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKKyAgICByZXR1cm4gImRyYWdnYWJsZSIgaW4gZGl2IHx8ICJkcmFnRHJvcCIgaW4gZGl2OworICB9KCk7CisKKyAgLy8gRmVhdHVyZS1kZXRlY3Qgd2hldGhlciBuZXdsaW5lcyBpbiB0ZXh0YXJlYXMgYXJlIGNvbnZlcnRlZCB0byBcclxuCisgIHZhciBsaW5lU2VwID0gZnVuY3Rpb24gKCkgeworICAgIHZhciB0ZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRleHRhcmVhIik7CisgICAgdGUudmFsdWUgPSAiZm9vXG5iYXIiOworICAgIGlmICh0ZS52YWx1ZS5pbmRleE9mKCJcciIpID4gLTEpIHJldHVybiAiXHJcbiI7CisgICAgcmV0dXJuICJcbiI7CisgIH0oKTsKKworICAvLyBGb3IgYSByZWFzb24gSSBoYXZlIHlldCB0byBmaWd1cmUgb3V0LCBzb21lIGJyb3dzZXJzIGRpc2FsbG93CisgIC8vIHdvcmQgd3JhcHBpbmcgYmV0d2VlbiBjZXJ0YWluIGNoYXJhY3RlcnMgKm9ubHkqIGlmIGEgbmV3IGlubGluZQorICAvLyBlbGVtZW50IGlzIHN0YXJ0ZWQgYmV0d2VlbiB0aGVtLiBUaGlzIG1ha2VzIGl0IGhhcmQgdG8gcmVsaWFibHkKKyAgLy8gbWVhc3VyZSB0aGUgcG9zaXRpb24gb2YgdGhpbmdzLCBzaW5jZSB0aGF0IHJlcXVpcmVzIGluc2VydGluZyBhbgorICAvLyBleHRyYSBzcGFuLiBUaGlzIHRlcnJpYmx5IGZyYWdpbGUgc2V0IG9mIHJlZ2V4cHMgbWF0Y2hlcyB0aGUKKyAgLy8gY2hhcmFjdGVyIGNvbWJpbmF0aW9ucyB0aGF0IHN1ZmZlciBmcm9tIHRoaXMgcGhlbm9tZW5vbiBvbiB0aGUKKyAgLy8gdmFyaW91cyBicm93c2Vycy4KKyAgdmFyIHNwYW5BZmZlY3RzV3JhcHBpbmcgPSAvXiQvOyAvLyBXb24ndCBtYXRjaCBhbnkgdHdvLWNoYXJhY3RlciBzdHJpbmcKKyAgaWYgKGdlY2tvKSBzcGFuQWZmZWN0c1dyYXBwaW5nID0gLyQnLzsKKyAgZWxzZSBpZiAoc2FmYXJpKSBzcGFuQWZmZWN0c1dyYXBwaW5nID0gL1wtW14gXC0/XXxcP1teICEnXCJcKSwuXC1cLzo7XD9cXVx9XS87CisgIGVsc2UgaWYgKGNocm9tZSkgc3BhbkFmZmVjdHNXcmFwcGluZyA9IC9cLVteIFwtXC4/XXxcP1teIFwtXC4/XF1cfTo7ISdcIlwpLFwvXXxbXC4hXCIjJiVcKSorLDo7PT5cXXxcfX5dW1woXHtcWzxdfFwkJy87CisKKyAgLy8gQ291bnRzIHRoZSBjb2x1bW4gb2Zmc2V0IGluIGEgc3RyaW5nLCB0YWtpbmcgdGFicyBpbnRvIGFjY291bnQuCisgIC8vIFVzZWQgbW9zdGx5IHRvIGZpbmQgaW5kZW50YXRpb24uCisgIGZ1bmN0aW9uIGNvdW50Q29sdW1uKHN0cmluZywgZW5kLCB0YWJTaXplKSB7CisgICAgaWYgKGVuZCA9PSBudWxsKSB7CisgICAgICBlbmQgPSBzdHJpbmcuc2VhcmNoKC9bXlxzXHUwMGEwXS8pOworICAgICAgaWYgKGVuZCA9PSAtMSkgZW5kID0gc3RyaW5nLmxlbmd0aDsKKyAgICB9CisgICAgZm9yICh2YXIgaSA9IDAsIG4gPSAwOyBpIDwgZW5kOyArK2kpIHsKKyAgICAgIGlmIChzdHJpbmcuY2hhckF0KGkpID09ICJcdCIpIG4gKz0gdGFiU2l6ZSAtIChuICUgdGFiU2l6ZSk7CisgICAgICBlbHNlICsrbjsKKyAgICB9CisgICAgcmV0dXJuIG47CisgIH0KKworICBmdW5jdGlvbiBjb21wdXRlZFN0eWxlKGVsdCkgeworICAgIGlmIChlbHQuY3VycmVudFN0eWxlKSByZXR1cm4gZWx0LmN1cnJlbnRTdHlsZTsKKyAgICByZXR1cm4gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWx0LCBudWxsKTsKKyAgfQorCisgIC8vIEZpbmQgdGhlIHBvc2l0aW9uIG9mIGFuIGVsZW1lbnQgYnkgZm9sbG93aW5nIHRoZSBvZmZzZXRQYXJlbnQgY2hhaW4uCisgIC8vIElmIHNjcmVlbj09dHJ1ZSwgaXQgcmV0dXJucyBzY3JlZW4gKHJhdGhlciB0aGFuIHBhZ2UpIGNvb3JkaW5hdGVzLgorICBmdW5jdGlvbiBlbHRPZmZzZXQobm9kZSwgc2NyZWVuKSB7CisgICAgdmFyIGJvZCA9IG5vZGUub3duZXJEb2N1bWVudC5ib2R5OworICAgIHZhciB4ID0gMCwgeSA9IDAsIHNraXBCb2R5ID0gZmFsc2U7CisgICAgZm9yICh2YXIgbiA9IG5vZGU7IG47IG4gPSBuLm9mZnNldFBhcmVudCkgeworICAgICAgdmFyIG9sID0gbi5vZmZzZXRMZWZ0LCBvdCA9IG4ub2Zmc2V0VG9wOworICAgICAgLy8gRmlyZWZveCByZXBvcnRzIHdlaXJkIGludmVydGVkIG9mZnNldHMgd2hlbiB0aGUgYm9keSBoYXMgYSBib3JkZXIuCisgICAgICBpZiAobiA9PSBib2QpIHsgeCArPSBNYXRoLmFicyhvbCk7IHkgKz0gTWF0aC5hYnMob3QpOyB9CisgICAgICBlbHNlIHsgeCArPSBvbCwgeSArPSBvdDsgfQorICAgICAgaWYgKHNjcmVlbiAmJiBjb21wdXRlZFN0eWxlKG4pLnBvc2l0aW9uID09ICJmaXhlZCIpCisgICAgICAgIHNraXBCb2R5ID0gdHJ1ZTsKKyAgICB9CisgICAgdmFyIGUgPSBzY3JlZW4gJiYgIXNraXBCb2R5ID8gbnVsbCA6IGJvZDsKKyAgICBmb3IgKHZhciBuID0gbm9kZS5wYXJlbnROb2RlOyBuICE9IGU7IG4gPSBuLnBhcmVudE5vZGUpCisgICAgICBpZiAobi5zY3JvbGxMZWZ0ICE9IG51bGwpIHsgeCAtPSBuLnNjcm9sbExlZnQ7IHkgLT0gbi5zY3JvbGxUb3A7fQorICAgIHJldHVybiB7bGVmdDogeCwgdG9wOiB5fTsKKyAgfQorICAvLyBVc2UgdGhlIGZhc3RlciBhbmQgc2FuZXIgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IG1ldGhvZCB3aGVuIHBvc3NpYmxlLgorICBpZiAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCAhPSBudWxsKSBlbHRPZmZzZXQgPSBmdW5jdGlvbihub2RlLCBzY3JlZW4pIHsKKyAgICAvLyBUYWtlIHRoZSBwYXJ0cyBvZiBib3VuZGluZyBjbGllbnQgcmVjdCB0aGF0IHdlIGFyZSBpbnRlcmVzdGVkIGluIHNvIHdlIGFyZSBhYmxlIHRvIGVkaXQgaWYgbmVlZCBiZSwKKyAgICAvLyBzaW5jZSB0aGUgcmV0dXJuZWQgdmFsdWUgY2Fubm90IGJlIGNoYW5nZWQgZXh0ZXJuYWxseSAodGhleSBhcmUga2VwdCBpbiBzeW5jIGFzIHRoZSBlbGVtZW50IG1vdmVzIHdpdGhpbiB0aGUgcGFnZSkKKyAgICB0cnkgeyB2YXIgYm94ID0gbm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsgYm94ID0geyB0b3A6IGJveC50b3AsIGxlZnQ6IGJveC5sZWZ0IH07IH0KKyAgICBjYXRjaChlKSB7IGJveCA9IHt0b3A6IDAsIGxlZnQ6IDB9OyB9CisgICAgaWYgKCFzY3JlZW4pIHsKKyAgICAgIC8vIEdldCB0aGUgdG9wbGV2ZWwgc2Nyb2xsLCB3b3JraW5nIGFyb3VuZCBicm93c2VyIGRpZmZlcmVuY2VzLgorICAgICAgaWYgKHdpbmRvdy5wYWdlWU9mZnNldCA9PSBudWxsKSB7CisgICAgICAgIHZhciB0ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IHx8IGRvY3VtZW50LmJvZHkucGFyZW50Tm9kZTsKKyAgICAgICAgaWYgKHQuc2Nyb2xsVG9wID09IG51bGwpIHQgPSBkb2N1bWVudC5ib2R5OworICAgICAgICBib3gudG9wICs9IHQuc2Nyb2xsVG9wOyBib3gubGVmdCArPSB0LnNjcm9sbExlZnQ7CisgICAgICB9IGVsc2UgeworICAgICAgICBib3gudG9wICs9IHdpbmRvdy5wYWdlWU9mZnNldDsgYm94LmxlZnQgKz0gd2luZG93LnBhZ2VYT2Zmc2V0OworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gYm94OworICB9OworCisgIC8vIEdldCBhIG5vZGUncyB0ZXh0IGNvbnRlbnQuCisgIGZ1bmN0aW9uIGVsdFRleHQobm9kZSkgeworICAgIHJldHVybiBub2RlLnRleHRDb250ZW50IHx8IG5vZGUuaW5uZXJUZXh0IHx8IG5vZGUubm9kZVZhbHVlIHx8ICIiOworICB9CisgIGZ1bmN0aW9uIHNlbGVjdElucHV0KG5vZGUpIHsKKyAgICBpZiAoaW9zKSB7IC8vIE1vYmlsZSBTYWZhcmkgYXBwYXJlbnRseSBoYXMgYSBidWcgd2hlcmUgc2VsZWN0KCkgaXMgYnJva2VuLgorICAgICAgbm9kZS5zZWxlY3Rpb25TdGFydCA9IDA7CisgICAgICBub2RlLnNlbGVjdGlvbkVuZCA9IG5vZGUudmFsdWUubGVuZ3RoOworICAgIH0gZWxzZSBub2RlLnNlbGVjdCgpOworICB9CisKKyAgLy8gT3BlcmF0aW9ucyBvbiB7bGluZSwgY2h9IG9iamVjdHMuCisgIGZ1bmN0aW9uIHBvc0VxKGEsIGIpIHtyZXR1cm4gYS5saW5lID09IGIubGluZSAmJiBhLmNoID09IGIuY2g7fQorICBmdW5jdGlvbiBwb3NMZXNzKGEsIGIpIHtyZXR1cm4gYS5saW5lIDwgYi5saW5lIHx8IChhLmxpbmUgPT0gYi5saW5lICYmIGEuY2ggPCBiLmNoKTt9CisgIGZ1bmN0aW9uIGNvcHlQb3MoeCkge3JldHVybiB7bGluZTogeC5saW5lLCBjaDogeC5jaH07fQorCisgIHZhciBlc2NhcGVFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgicHJlIik7CisgIGZ1bmN0aW9uIGh0bWxFc2NhcGUoc3RyKSB7CisgICAgZXNjYXBlRWxlbWVudC50ZXh0Q29udGVudCA9IHN0cjsKKyAgICByZXR1cm4gZXNjYXBlRWxlbWVudC5pbm5lckhUTUw7CisgIH0KKyAgLy8gUmVjZW50IChsYXRlIDIwMTEpIE9wZXJhIGJldGFzIGluc2VydCBib2d1cyBuZXdsaW5lcyBhdCB0aGUgc3RhcnQKKyAgLy8gb2YgdGhlIHRleHRDb250ZW50LCBzbyB3ZSBzdHJpcCB0aG9zZS4KKyAgaWYgKGh0bWxFc2NhcGUoImEiKSA9PSAiXG5hIikKKyAgICBodG1sRXNjYXBlID0gZnVuY3Rpb24oc3RyKSB7CisgICAgICBlc2NhcGVFbGVtZW50LnRleHRDb250ZW50ID0gc3RyOworICAgICAgcmV0dXJuIGVzY2FwZUVsZW1lbnQuaW5uZXJIVE1MLnNsaWNlKDEpOworICAgIH07CisgIC8vIFNvbWUgSUVzIGRvbid0IHByZXNlcnZlIHRhYnMgdGhyb3VnaCBpbm5lckhUTUwKKyAgZWxzZSBpZiAoaHRtbEVzY2FwZSgiXHQiKSAhPSAiXHQiKQorICAgIGh0bWxFc2NhcGUgPSBmdW5jdGlvbihzdHIpIHsKKyAgICAgIGVzY2FwZUVsZW1lbnQuaW5uZXJIVE1MID0gIiI7CisgICAgICBlc2NhcGVFbGVtZW50LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN0cikpOworICAgICAgcmV0dXJuIGVzY2FwZUVsZW1lbnQuaW5uZXJIVE1MOworICAgIH07CisgIENvZGVNaXJyb3IuaHRtbEVzY2FwZSA9IGh0bWxFc2NhcGU7CisKKyAgLy8gVXNlZCB0byBwb3NpdGlvbiB0aGUgY3Vyc29yIGFmdGVyIGFuIHVuZG8vcmVkbyBieSBmaW5kaW5nIHRoZQorICAvLyBsYXN0IGVkaXRlZCBjaGFyYWN0ZXIuCisgIGZ1bmN0aW9uIGVkaXRFbmQoZnJvbSwgdG8pIHsKKyAgICBpZiAoIXRvKSByZXR1cm4gMDsKKyAgICBpZiAoIWZyb20pIHJldHVybiB0by5sZW5ndGg7CisgICAgZm9yICh2YXIgaSA9IGZyb20ubGVuZ3RoLCBqID0gdG8ubGVuZ3RoOyBpID49IDAgJiYgaiA+PSAwOyAtLWksIC0taikKKyAgICAgIGlmIChmcm9tLmNoYXJBdChpKSAhPSB0by5jaGFyQXQoaikpIGJyZWFrOworICAgIHJldHVybiBqICsgMTsKKyAgfQorCisgIGZ1bmN0aW9uIGluZGV4T2YoY29sbGVjdGlvbiwgZWx0KSB7CisgICAgaWYgKGNvbGxlY3Rpb24uaW5kZXhPZikgcmV0dXJuIGNvbGxlY3Rpb24uaW5kZXhPZihlbHQpOworICAgIGZvciAodmFyIGkgPSAwLCBlID0gY29sbGVjdGlvbi5sZW5ndGg7IGkgPCBlOyArK2kpCisgICAgICBpZiAoY29sbGVjdGlvbltpXSA9PSBlbHQpIHJldHVybiBpOworICAgIHJldHVybiAtMTsKKyAgfQorICBmdW5jdGlvbiBpc1dvcmRDaGFyKGNoKSB7CisgICAgcmV0dXJuIC9cdy8udGVzdChjaCkgfHwgY2gudG9VcHBlckNhc2UoKSAhPSBjaC50b0xvd2VyQ2FzZSgpOworICB9CisKKyAgLy8gU2VlIGlmICIiLnNwbGl0IGlzIHRoZSBicm9rZW4gSUUgdmVyc2lvbiwgaWYgc28sIHByb3ZpZGUgYW4KKyAgLy8gYWx0ZXJuYXRpdmUgd2F5IHRvIHNwbGl0IGxpbmVzLgorICB2YXIgc3BsaXRMaW5lcyA9ICJcblxuYiIuc3BsaXQoL1xuLykubGVuZ3RoICE9IDMgPyBmdW5jdGlvbihzdHJpbmcpIHsKKyAgICB2YXIgcG9zID0gMCwgbmwsIHJlc3VsdCA9IFtdOworICAgIHdoaWxlICgobmwgPSBzdHJpbmcuaW5kZXhPZigiXG4iLCBwb3MpKSA+IC0xKSB7CisgICAgICByZXN1bHQucHVzaChzdHJpbmcuc2xpY2UocG9zLCBzdHJpbmcuY2hhckF0KG5sLTEpID09ICJcciIgPyBubCAtIDEgOiBubCkpOworICAgICAgcG9zID0gbmwgKyAxOworICAgIH0KKyAgICByZXN1bHQucHVzaChzdHJpbmcuc2xpY2UocG9zKSk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfSA6IGZ1bmN0aW9uKHN0cmluZyl7cmV0dXJuIHN0cmluZy5zcGxpdCgvXHI/XG4vKTt9OworICBDb2RlTWlycm9yLnNwbGl0TGluZXMgPSBzcGxpdExpbmVzOworCisgIHZhciBoYXNTZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uID8gZnVuY3Rpb24odGUpIHsKKyAgICB0cnkgeyByZXR1cm4gdGUuc2VsZWN0aW9uU3RhcnQgIT0gdGUuc2VsZWN0aW9uRW5kOyB9CisgICAgY2F0Y2goZSkgeyByZXR1cm4gZmFsc2U7IH0KKyAgfSA6IGZ1bmN0aW9uKHRlKSB7CisgICAgdHJ5IHt2YXIgcmFuZ2UgPSB0ZS5vd25lckRvY3VtZW50LnNlbGVjdGlvbi5jcmVhdGVSYW5nZSgpO30KKyAgICBjYXRjaChlKSB7fQorICAgIGlmICghcmFuZ2UgfHwgcmFuZ2UucGFyZW50RWxlbWVudCgpICE9IHRlKSByZXR1cm4gZmFsc2U7CisgICAgcmV0dXJuIHJhbmdlLmNvbXBhcmVFbmRQb2ludHMoIlN0YXJ0VG9FbmQiLCByYW5nZSkgIT0gMDsKKyAgfTsKKworICBDb2RlTWlycm9yLmRlZmluZU1vZGUoIm51bGwiLCBmdW5jdGlvbigpIHsKKyAgICByZXR1cm4ge3Rva2VuOiBmdW5jdGlvbihzdHJlYW0pIHtzdHJlYW0uc2tpcFRvRW5kKCk7fX07CisgIH0pOworICBDb2RlTWlycm9yLmRlZmluZU1JTUUoInRleHQvcGxhaW4iLCAibnVsbCIpOworCisgIHZhciBrZXlOYW1lcyA9IHszOiAiRW50ZXIiLCA4OiAiQmFja3NwYWNlIiwgOTogIlRhYiIsIDEzOiAiRW50ZXIiLCAxNjogIlNoaWZ0IiwgMTc6ICJDdHJsIiwgMTg6ICJBbHQiLAorICAgICAgICAgICAgICAgICAgMTk6ICJQYXVzZSIsIDIwOiAiQ2Fwc0xvY2siLCAyNzogIkVzYyIsIDMyOiAiU3BhY2UiLCAzMzogIlBhZ2VVcCIsIDM0OiAiUGFnZURvd24iLCAzNTogIkVuZCIsCisgICAgICAgICAgICAgICAgICAzNjogIkhvbWUiLCAzNzogIkxlZnQiLCAzODogIlVwIiwgMzk6ICJSaWdodCIsIDQwOiAiRG93biIsIDQ0OiAiUHJpbnRTY3JuIiwgNDU6ICJJbnNlcnQiLAorICAgICAgICAgICAgICAgICAgNDY6ICJEZWxldGUiLCA1OTogIjsiLCA5MTogIk1vZCIsIDkyOiAiTW9kIiwgOTM6ICJNb2QiLCAxMjc6ICJEZWxldGUiLCAxODY6ICI7IiwgMTg3OiAiPSIsIDE4ODogIiwiLAorICAgICAgICAgICAgICAgICAgMTg5OiAiLSIsIDE5MDogIi4iLCAxOTE6ICIvIiwgMTkyOiAiYCIsIDIxOTogIlsiLCAyMjA6ICJcXCIsIDIyMTogIl0iLCAyMjI6ICInIiwgNjMyNzY6ICJQYWdlVXAiLAorICAgICAgICAgICAgICAgICAgNjMyNzc6ICJQYWdlRG93biIsIDYzMjc1OiAiRW5kIiwgNjMyNzM6ICJIb21lIiwgNjMyMzQ6ICJMZWZ0IiwgNjMyMzI6ICJVcCIsIDYzMjM1OiAiUmlnaHQiLAorICAgICAgICAgICAgICAgICAgNjMyMzM6ICJEb3duIiwgNjMzMDI6ICJJbnNlcnQiLCA2MzI3MjogIkRlbGV0ZSJ9OworICBDb2RlTWlycm9yLmtleU5hbWVzID0ga2V5TmFtZXM7CisgIChmdW5jdGlvbigpIHsKKyAgICAvLyBOdW1iZXIga2V5cworICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTA7IGkrKykga2V5TmFtZXNbaSArIDQ4XSA9IFN0cmluZyhpKTsKKyAgICAvLyBBbHBoYWJldGljIGtleXMKKyAgICBmb3IgKHZhciBpID0gNjU7IGkgPD0gOTA7IGkrKykga2V5TmFtZXNbaV0gPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGkpOworICAgIC8vIEZ1bmN0aW9uIGtleXMKKyAgICBmb3IgKHZhciBpID0gMTsgaSA8PSAxMjsgaSsrKSBrZXlOYW1lc1tpICsgMTExXSA9IGtleU5hbWVzW2kgKyA2MzIzNV0gPSAiRiIgKyBpOworICB9KSgpOworCisgIHJldHVybiBDb2RlTWlycm9yOworfSkoKTsKZGlmZiAtLWdpdCBhL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci9saWIvdXRpbC9sb2FkbW9kZS5qcyBiL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci9saWIvdXRpbC9sb2FkbW9kZS5qcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NWM0MDYxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9jb2RlbWlycm9yL2xpYi91dGlsL2xvYWRtb2RlLmpzCkBAIC0wLDAgKzEsNTAgQEAKKyhmdW5jdGlvbigpIHsKKyAgaWYgKCFDb2RlTWlycm9yLm1vZGVVUkwpIENvZGVNaXJyb3IubW9kZVVSTCA9ICIuLi9tb2RlLyVOLyVOLmpzIjsKKworICB2YXIgbG9hZGluZyA9IHt9OworICBmdW5jdGlvbiBzcGxpdENhbGxiYWNrKGNvbnQsIG4pIHsKKyAgICB2YXIgY291bnREb3duID0gbjsKKyAgICByZXR1cm4gZnVuY3Rpb24oKSB7IGlmICgtLWNvdW50RG93biA9PSAwKSBjb250KCk7IH0KKyAgfQorICBmdW5jdGlvbiBlbnN1cmVEZXBzKG1vZGUsIGNvbnQpIHsKKyAgICB2YXIgZGVwcyA9IENvZGVNaXJyb3IubW9kZXNbbW9kZV0uZGVwZW5kZW5jaWVzOworICAgIGlmICghZGVwcykgcmV0dXJuIGNvbnQoKTsKKyAgICB2YXIgbWlzc2luZyA9IFtdOworICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGVwcy5sZW5ndGg7ICsraSkgeworICAgICAgaWYgKCFDb2RlTWlycm9yLm1vZGVzLmhhc093blByb3BlcnR5KGRlcHNbaV0pKQorICAgICAgICBtaXNzaW5nLnB1c2goZGVwc1tpXSk7CisgICAgfQorICAgIGlmICghbWlzc2luZy5sZW5ndGgpIHJldHVybiBjb250KCk7CisgICAgdmFyIHNwbGl0ID0gc3BsaXRDYWxsYmFjayhjb250LCBtaXNzaW5nLmxlbmd0aCk7CisgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtaXNzaW5nLmxlbmd0aDsgKytpKQorICAgICAgQ29kZU1pcnJvci5yZXF1aXJlTW9kZShtaXNzaW5nW2ldLCBzcGxpdCk7CisgIH0KKworICBDb2RlTWlycm9yLnJlcXVpcmVNb2RlID0gZnVuY3Rpb24obW9kZSwgY29udCkgeworICAgIGlmIChDb2RlTWlycm9yLm1vZGVzLmhhc093blByb3BlcnR5KG1vZGUpKSByZXR1cm4gZW5zdXJlRGVwcyhtb2RlLCBjb250KCkpOworICAgIGlmIChsb2FkaW5nLmhhc093blByb3BlcnR5KG1vZGUpKSByZXR1cm4gbG9hZGluZ1ttb2RlXS5wdXNoKGNvbnQpOworCisgICAgdmFyIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNjcmlwdCIpOworICAgIHNjcmlwdC5zcmMgPSBDb2RlTWlycm9yLm1vZGVVUkwucmVwbGFjZSgvJU4vZywgbW9kZSk7CisgICAgdmFyIG90aGVycyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJzY3JpcHQiKVswXTsKKyAgICBvdGhlcnMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc2NyaXB0LCBvdGhlcnMpOworICAgIHZhciBsaXN0ID0gbG9hZGluZ1ttb2RlXSA9IFtjb250XTsKKyAgICB2YXIgY291bnQgPSAwLCBwb2xsID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7CisgICAgICBpZiAoKytjb3VudCA+IDEwMCkgcmV0dXJuIGNsZWFySW50ZXJ2YWwocG9sbCk7CisgICAgICBpZiAoQ29kZU1pcnJvci5tb2Rlcy5oYXNPd25Qcm9wZXJ0eShtb2RlKSkgeworICAgICAgICBjbGVhckludGVydmFsKHBvbGwpOworICAgICAgICBsb2FkaW5nW21vZGVdID0gbnVsbDsKKyAgICAgICAgZW5zdXJlRGVwcyhtb2RlLCBmdW5jdGlvbigpIHsKKyAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIGxpc3RbaV0oKTsKKyAgICAgICAgfSk7CisgICAgICB9CisgICAgfSwgMjAwKTsKKyAgfTsKKworICBDb2RlTWlycm9yLmF1dG9Mb2FkTW9kZSA9IGZ1bmN0aW9uKGluc3RhbmNlLCBtb2RlKSB7CisgICAgaWYgKCFDb2RlTWlycm9yLm1vZGVzLmhhc093blByb3BlcnR5KG1vZGUpKQorICAgICAgQ29kZU1pcnJvci5yZXF1aXJlTW9kZShtb2RlLCBmdW5jdGlvbigpIHsKKyAgICAgICAgaW5zdGFuY2Uuc2V0T3B0aW9uKCJtb2RlIiwgaW5zdGFuY2UuZ2V0T3B0aW9uKCJtb2RlIikpOworICAgICAgfSk7CisgIH07Cit9KCkpOwpkaWZmIC0tZ2l0IGEvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9jb2RlbWlycm9yL2xpYi91dGlsL3J1bm1vZGUuanMgYi9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL2NvZGVtaXJyb3IvbGliL3V0aWwvcnVubW9kZS5qcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYzU4ZDg1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9jb2RlbWlycm9yL2xpYi91dGlsL3J1bm1vZGUuanMKQEAgLTAsMCArMSw0OSBAQAorQ29kZU1pcnJvci5ydW5Nb2RlID0gZnVuY3Rpb24oc3RyaW5nLCBtb2Rlc3BlYywgY2FsbGJhY2ssIG9wdGlvbnMpIHsKKyAgdmFyIG1vZGUgPSBDb2RlTWlycm9yLmdldE1vZGUoQ29kZU1pcnJvci5kZWZhdWx0cywgbW9kZXNwZWMpOworICB2YXIgaXNOb2RlID0gY2FsbGJhY2subm9kZVR5cGUgPT0gMTsKKyAgdmFyIHRhYlNpemUgPSAob3B0aW9ucyAmJiBvcHRpb25zLnRhYlNpemUpIHx8IENvZGVNaXJyb3IuZGVmYXVsdHMudGFiU2l6ZTsKKyAgaWYgKGlzTm9kZSkgeworICAgIHZhciBub2RlID0gY2FsbGJhY2ssIGFjY3VtID0gW10sIGNvbCA9IDA7CisgICAgY2FsbGJhY2sgPSBmdW5jdGlvbih0ZXh0LCBzdHlsZSkgeworICAgICAgaWYgKHRleHQgPT0gIlxuIikgeworICAgICAgICBhY2N1bS5wdXNoKCI8YnI+Iik7CisgICAgICAgIGNvbCA9IDA7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIHZhciBlc2NhcGVkID0gIiI7CisgICAgICAvLyBIVE1MLWVzY2FwZSBhbmQgcmVwbGFjZSB0YWJzCisgICAgICBmb3IgKHZhciBwb3MgPSAwOzspIHsKKyAgICAgICAgdmFyIGlkeCA9IHRleHQuaW5kZXhPZigiXHQiLCBwb3MpOworICAgICAgICBpZiAoaWR4ID09IC0xKSB7CisgICAgICAgICAgZXNjYXBlZCArPSBDb2RlTWlycm9yLmh0bWxFc2NhcGUodGV4dC5zbGljZShwb3MpKTsKKyAgICAgICAgICBjb2wgKz0gdGV4dC5sZW5ndGggLSBwb3M7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgY29sICs9IGlkeCAtIHBvczsKKyAgICAgICAgICBlc2NhcGVkICs9IENvZGVNaXJyb3IuaHRtbEVzY2FwZSh0ZXh0LnNsaWNlKHBvcywgaWR4KSk7CisgICAgICAgICAgdmFyIHNpemUgPSB0YWJTaXplIC0gY29sICUgdGFiU2l6ZTsKKyAgICAgICAgICBjb2wgKz0gc2l6ZTsKKyAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7ICsraSkgZXNjYXBlZCArPSAiICI7CisgICAgICAgICAgcG9zID0gaWR4ICsgMTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBpZiAoc3R5bGUpIAorICAgICAgICBhY2N1bS5wdXNoKCI8c3BhbiBjbGFzcz1cImNtLSIgKyBDb2RlTWlycm9yLmh0bWxFc2NhcGUoc3R5bGUpICsgIlwiPiIgKyBlc2NhcGVkICsgIjwvc3Bhbj4iKTsKKyAgICAgIGVsc2UKKyAgICAgICAgYWNjdW0ucHVzaChlc2NhcGVkKTsKKyAgICB9CisgIH0KKyAgdmFyIGxpbmVzID0gQ29kZU1pcnJvci5zcGxpdExpbmVzKHN0cmluZyksIHN0YXRlID0gQ29kZU1pcnJvci5zdGFydFN0YXRlKG1vZGUpOworICBmb3IgKHZhciBpID0gMCwgZSA9IGxpbmVzLmxlbmd0aDsgaSA8IGU7ICsraSkgeworICAgIGlmIChpKSBjYWxsYmFjaygiXG4iKTsKKyAgICB2YXIgc3RyZWFtID0gbmV3IENvZGVNaXJyb3IuU3RyaW5nU3RyZWFtKGxpbmVzW2ldKTsKKyAgICB3aGlsZSAoIXN0cmVhbS5lb2woKSkgeworICAgICAgdmFyIHN0eWxlID0gbW9kZS50b2tlbihzdHJlYW0sIHN0YXRlKTsKKyAgICAgIGNhbGxiYWNrKHN0cmVhbS5jdXJyZW50KCksIHN0eWxlLCBpLCBzdHJlYW0uc3RhcnQpOworICAgICAgc3RyZWFtLnN0YXJ0ID0gc3RyZWFtLnBvczsKKyAgICB9CisgIH0KKyAgaWYgKGlzTm9kZSkKKyAgICBub2RlLmlubmVySFRNTCA9IGFjY3VtLmpvaW4oIiIpOworfTsKZGlmZiAtLWdpdCBhL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci9tb2RlL2dyb292eS9ncm9vdnkuanMgYi9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL2NvZGVtaXJyb3IvbW9kZS9ncm9vdnkvZ3Jvb3Z5LmpzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAyOWUwYzkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL2NvZGVtaXJyb3IvbW9kZS9ncm9vdnkvZ3Jvb3Z5LmpzCkBAIC0wLDAgKzEsMjEwIEBACitDb2RlTWlycm9yLmRlZmluZU1vZGUoImdyb292eSIsIGZ1bmN0aW9uKGNvbmZpZywgcGFyc2VyQ29uZmlnKSB7CisgIGZ1bmN0aW9uIHdvcmRzKHN0cikgeworICAgIHZhciBvYmogPSB7fSwgd29yZHMgPSBzdHIuc3BsaXQoIiAiKTsKKyAgICBmb3IgKHZhciBpID0gMDsgaSA8IHdvcmRzLmxlbmd0aDsgKytpKSBvYmpbd29yZHNbaV1dID0gdHJ1ZTsKKyAgICByZXR1cm4gb2JqOworICB9CisgIHZhciBrZXl3b3JkcyA9IHdvcmRzKAorICAgICJhYnN0cmFjdCBhcyBhc3NlcnQgYm9vbGVhbiBicmVhayBieXRlIGNhc2UgY2F0Y2ggY2hhciBjbGFzcyBjb25zdCBjb250aW51ZSBkZWYgZGVmYXVsdCAiICsKKyAgICAiZG8gZG91YmxlIGVsc2UgZW51bSBleHRlbmRzIGZpbmFsIGZpbmFsbHkgZmxvYXQgZm9yIGdvdG8gaWYgaW1wbGVtZW50cyBpbXBvcnQgaW4gIiArCisgICAgImluc3RhbmNlb2YgaW50IGludGVyZmFjZSBsb25nIG5hdGl2ZSBuZXcgcGFja2FnZSBwcml2YXRlIHByb3RlY3RlZCBwdWJsaWMgcmV0dXJuICIgKworICAgICJzaG9ydCBzdGF0aWMgc3RyaWN0ZnAgc3VwZXIgc3dpdGNoIHN5bmNocm9uaXplZCB0aHJlYWRzYWZlIHRocm93IHRocm93cyB0cmFuc2llbnQgIiArCisgICAgInRyeSB2b2lkIHZvbGF0aWxlIHdoaWxlIik7CisgIHZhciBibG9ja0tleXdvcmRzID0gd29yZHMoImNhdGNoIGNsYXNzIGRvIGVsc2UgZmluYWxseSBmb3IgaWYgc3dpdGNoIHRyeSB3aGlsZSBlbnVtIGludGVyZmFjZSBkZWYiKTsKKyAgdmFyIGF0b21zID0gd29yZHMoIm51bGwgdHJ1ZSBmYWxzZSB0aGlzIik7CisKKyAgdmFyIGN1clB1bmM7CisgIGZ1bmN0aW9uIHRva2VuQmFzZShzdHJlYW0sIHN0YXRlKSB7CisgICAgdmFyIGNoID0gc3RyZWFtLm5leHQoKTsKKyAgICBpZiAoY2ggPT0gJyInIHx8IGNoID09ICInIikgeworICAgICAgcmV0dXJuIHN0YXJ0U3RyaW5nKGNoLCBzdHJlYW0sIHN0YXRlKTsKKyAgICB9CisgICAgaWYgKC9bXFtcXXt9XChcKSw7XDpcLl0vLnRlc3QoY2gpKSB7CisgICAgICBjdXJQdW5jID0gY2g7CisgICAgICByZXR1cm4gbnVsbAorICAgIH0KKyAgICBpZiAoL1xkLy50ZXN0KGNoKSkgeworICAgICAgc3RyZWFtLmVhdFdoaWxlKC9bXHdcLl0vKTsKKyAgICAgIGlmIChzdHJlYW0uZWF0KC9lRS8pKSB7IHN0cmVhbS5lYXQoL1wrXC0vKTsgc3RyZWFtLmVhdFdoaWxlKC9cZC8pOyB9CisgICAgICByZXR1cm4gIm51bWJlciI7CisgICAgfQorICAgIGlmIChjaCA9PSAiLyIpIHsKKyAgICAgIGlmIChzdHJlYW0uZWF0KCIqIikpIHsKKyAgICAgICAgc3RhdGUudG9rZW5pemUucHVzaCh0b2tlbkNvbW1lbnQpOworICAgICAgICByZXR1cm4gdG9rZW5Db21tZW50KHN0cmVhbSwgc3RhdGUpOworICAgICAgfQorICAgICAgaWYgKHN0cmVhbS5lYXQoIi8iKSkgeworICAgICAgICBzdHJlYW0uc2tpcFRvRW5kKCk7CisgICAgICAgIHJldHVybiAiY29tbWVudCI7CisgICAgICB9CisgICAgICBpZiAoZXhwZWN0RXhwcmVzc2lvbihzdGF0ZS5sYXN0VG9rZW4pKSB7CisgICAgICAgIHJldHVybiBzdGFydFN0cmluZyhjaCwgc3RyZWFtLCBzdGF0ZSk7CisgICAgICB9CisgICAgfQorICAgIGlmIChjaCA9PSAiLSIgJiYgc3RyZWFtLmVhdCgiPiIpKSB7CisgICAgICBjdXJQdW5jID0gIi0+IjsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICBpZiAoL1srXC0qJiU9PD4hP3xcL35dLy50ZXN0KGNoKSkgeworICAgICAgc3RyZWFtLmVhdFdoaWxlKC9bK1wtKiYlPTw+fH5dLyk7CisgICAgICByZXR1cm4gIm9wZXJhdG9yIjsKKyAgICB9CisgICAgc3RyZWFtLmVhdFdoaWxlKC9bXHdcJF9dLyk7CisgICAgaWYgKGNoID09ICJAIikgeyBzdHJlYW0uZWF0V2hpbGUoL1tcd1wkX1wuXS8pOyByZXR1cm4gIm1ldGEiOyB9CisgICAgaWYgKHN0YXRlLmxhc3RUb2tlbiA9PSAiLiIpIHJldHVybiAicHJvcGVydHkiOworICAgIGlmIChzdHJlYW0uZWF0KCI6IikpIHsgY3VyUHVuYyA9ICJwcm9wbGFiZWwiOyByZXR1cm4gInByb3BlcnR5IjsgfQorICAgIHZhciBjdXIgPSBzdHJlYW0uY3VycmVudCgpOworICAgIGlmIChhdG9tcy5wcm9wZXJ0eUlzRW51bWVyYWJsZShjdXIpKSB7IHJldHVybiAiYXRvbSI7IH0KKyAgICBpZiAoa2V5d29yZHMucHJvcGVydHlJc0VudW1lcmFibGUoY3VyKSkgeworICAgICAgaWYgKGJsb2NrS2V5d29yZHMucHJvcGVydHlJc0VudW1lcmFibGUoY3VyKSkgY3VyUHVuYyA9ICJuZXdzdGF0ZW1lbnQiOworICAgICAgcmV0dXJuICJrZXl3b3JkIjsKKyAgICB9CisgICAgcmV0dXJuICJ3b3JkIjsKKyAgfQorICB0b2tlbkJhc2UuaXNCYXNlID0gdHJ1ZTsKKworICBmdW5jdGlvbiBzdGFydFN0cmluZyhxdW90ZSwgc3RyZWFtLCBzdGF0ZSkgeworICAgIHZhciB0cmlwbGVRdW90ZWQgPSBmYWxzZTsKKyAgICBpZiAocXVvdGUgIT0gIi8iICYmIHN0cmVhbS5lYXQocXVvdGUpKSB7CisgICAgICBpZiAoc3RyZWFtLmVhdChxdW90ZSkpIHRyaXBsZVF1b3RlZCA9IHRydWU7CisgICAgICBlbHNlIHJldHVybiAic3RyaW5nIjsKKyAgICB9CisgICAgZnVuY3Rpb24gdChzdHJlYW0sIHN0YXRlKSB7CisgICAgICB2YXIgZXNjYXBlZCA9IGZhbHNlLCBuZXh0LCBlbmQgPSAhdHJpcGxlUXVvdGVkOworICAgICAgd2hpbGUgKChuZXh0ID0gc3RyZWFtLm5leHQoKSkgIT0gbnVsbCkgeworICAgICAgICBpZiAobmV4dCA9PSBxdW90ZSAmJiAhZXNjYXBlZCkgeworICAgICAgICAgIGlmICghdHJpcGxlUXVvdGVkKSB7IGJyZWFrOyB9CisgICAgICAgICAgaWYgKHN0cmVhbS5tYXRjaChxdW90ZSArIHF1b3RlKSkgeyBlbmQgPSB0cnVlOyBicmVhazsgfQorICAgICAgICB9CisgICAgICAgIGlmIChxdW90ZSA9PSAnIicgJiYgbmV4dCA9PSAiJCIgJiYgIWVzY2FwZWQgJiYgc3RyZWFtLmVhdCgieyIpKSB7CisgICAgICAgICAgc3RhdGUudG9rZW5pemUucHVzaCh0b2tlbkJhc2VVbnRpbEJyYWNlKCkpOworICAgICAgICAgIHJldHVybiAic3RyaW5nIjsKKyAgICAgICAgfQorICAgICAgICBlc2NhcGVkID0gIWVzY2FwZWQgJiYgbmV4dCA9PSAiXFwiOworICAgICAgfQorICAgICAgaWYgKGVuZCkgc3RhdGUudG9rZW5pemUucG9wKCk7CisgICAgICByZXR1cm4gInN0cmluZyI7CisgICAgfQorICAgIHN0YXRlLnRva2VuaXplLnB1c2godCk7CisgICAgcmV0dXJuIHQoc3RyZWFtLCBzdGF0ZSk7CisgIH0KKworICBmdW5jdGlvbiB0b2tlbkJhc2VVbnRpbEJyYWNlKCkgeworICAgIHZhciBkZXB0aCA9IDE7CisgICAgZnVuY3Rpb24gdChzdHJlYW0sIHN0YXRlKSB7CisgICAgICBpZiAoc3RyZWFtLnBlZWsoKSA9PSAifSIpIHsKKyAgICAgICAgZGVwdGgtLTsKKyAgICAgICAgaWYgKGRlcHRoID09IDApIHsKKyAgICAgICAgICBzdGF0ZS50b2tlbml6ZS5wb3AoKTsKKyAgICAgICAgICByZXR1cm4gc3RhdGUudG9rZW5pemVbc3RhdGUudG9rZW5pemUubGVuZ3RoLTFdKHN0cmVhbSwgc3RhdGUpOworICAgICAgICB9CisgICAgICB9IGVsc2UgaWYgKHN0cmVhbS5wZWVrKCkgPT0gInsiKSB7CisgICAgICAgIGRlcHRoKys7CisgICAgICB9CisgICAgICByZXR1cm4gdG9rZW5CYXNlKHN0cmVhbSwgc3RhdGUpOworICAgIH0KKyAgICB0LmlzQmFzZSA9IHRydWU7CisgICAgcmV0dXJuIHQ7CisgIH0KKworICBmdW5jdGlvbiB0b2tlbkNvbW1lbnQoc3RyZWFtLCBzdGF0ZSkgeworICAgIHZhciBtYXliZUVuZCA9IGZhbHNlLCBjaDsKKyAgICB3aGlsZSAoY2ggPSBzdHJlYW0ubmV4dCgpKSB7CisgICAgICBpZiAoY2ggPT0gIi8iICYmIG1heWJlRW5kKSB7CisgICAgICAgIHN0YXRlLnRva2VuaXplLnBvcCgpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIG1heWJlRW5kID0gKGNoID09ICIqIik7CisgICAgfQorICAgIHJldHVybiAiY29tbWVudCI7CisgIH0KKworICBmdW5jdGlvbiBleHBlY3RFeHByZXNzaW9uKGxhc3QpIHsKKyAgICByZXR1cm4gIWxhc3QgfHwgbGFzdCA9PSAib3BlcmF0b3IiIHx8IGxhc3QgPT0gIi0+IiB8fCAvW1wuXFtce1woLDs6XS8udGVzdChsYXN0KSB8fAorICAgICAgbGFzdCA9PSAibmV3c3RhdGVtZW50IiB8fCBsYXN0ID09ICJrZXl3b3JkIiB8fCBsYXN0ID09ICJwcm9wbGFiZWwiOworICB9CisKKyAgZnVuY3Rpb24gQ29udGV4dChpbmRlbnRlZCwgY29sdW1uLCB0eXBlLCBhbGlnbiwgcHJldikgeworICAgIHRoaXMuaW5kZW50ZWQgPSBpbmRlbnRlZDsKKyAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKKyAgICB0aGlzLnR5cGUgPSB0eXBlOworICAgIHRoaXMuYWxpZ24gPSBhbGlnbjsKKyAgICB0aGlzLnByZXYgPSBwcmV2OworICB9CisgIGZ1bmN0aW9uIHB1c2hDb250ZXh0KHN0YXRlLCBjb2wsIHR5cGUpIHsKKyAgICByZXR1cm4gc3RhdGUuY29udGV4dCA9IG5ldyBDb250ZXh0KHN0YXRlLmluZGVudGVkLCBjb2wsIHR5cGUsIG51bGwsIHN0YXRlLmNvbnRleHQpOworICB9CisgIGZ1bmN0aW9uIHBvcENvbnRleHQoc3RhdGUpIHsKKyAgICB2YXIgdCA9IHN0YXRlLmNvbnRleHQudHlwZTsKKyAgICBpZiAodCA9PSAiKSIgfHwgdCA9PSAiXSIgfHwgdCA9PSAifSIpCisgICAgICBzdGF0ZS5pbmRlbnRlZCA9IHN0YXRlLmNvbnRleHQuaW5kZW50ZWQ7CisgICAgcmV0dXJuIHN0YXRlLmNvbnRleHQgPSBzdGF0ZS5jb250ZXh0LnByZXY7CisgIH0KKworICAvLyBJbnRlcmZhY2UKKworICByZXR1cm4geworICAgIHN0YXJ0U3RhdGU6IGZ1bmN0aW9uKGJhc2Vjb2x1bW4pIHsKKyAgICAgIHJldHVybiB7CisgICAgICAgIHRva2VuaXplOiBbdG9rZW5CYXNlXSwKKyAgICAgICAgY29udGV4dDogbmV3IENvbnRleHQoKGJhc2Vjb2x1bW4gfHwgMCkgLSBjb25maWcuaW5kZW50VW5pdCwgMCwgInRvcCIsIGZhbHNlKSwKKyAgICAgICAgaW5kZW50ZWQ6IDAsCisgICAgICAgIHN0YXJ0T2ZMaW5lOiB0cnVlLAorICAgICAgICBsYXN0VG9rZW46IG51bGwKKyAgICAgIH07CisgICAgfSwKKworICAgIHRva2VuOiBmdW5jdGlvbihzdHJlYW0sIHN0YXRlKSB7CisgICAgICB2YXIgY3R4ID0gc3RhdGUuY29udGV4dDsKKyAgICAgIGlmIChzdHJlYW0uc29sKCkpIHsKKyAgICAgICAgaWYgKGN0eC5hbGlnbiA9PSBudWxsKSBjdHguYWxpZ24gPSBmYWxzZTsKKyAgICAgICAgc3RhdGUuaW5kZW50ZWQgPSBzdHJlYW0uaW5kZW50YXRpb24oKTsKKyAgICAgICAgc3RhdGUuc3RhcnRPZkxpbmUgPSB0cnVlOworICAgICAgICAvLyBBdXRvbWF0aWMgc2VtaWNvbG9uIGluc2VydGlvbgorICAgICAgICBpZiAoY3R4LnR5cGUgPT0gInN0YXRlbWVudCIgJiYgIWV4cGVjdEV4cHJlc3Npb24oc3RhdGUubGFzdFRva2VuKSkgeworICAgICAgICAgIHBvcENvbnRleHQoc3RhdGUpOyBjdHggPSBzdGF0ZS5jb250ZXh0OworICAgICAgICB9CisgICAgICB9CisgICAgICBpZiAoc3RyZWFtLmVhdFNwYWNlKCkpIHJldHVybiBudWxsOworICAgICAgY3VyUHVuYyA9IG51bGw7CisgICAgICB2YXIgc3R5bGUgPSBzdGF0ZS50b2tlbml6ZVtzdGF0ZS50b2tlbml6ZS5sZW5ndGgtMV0oc3RyZWFtLCBzdGF0ZSk7CisgICAgICBpZiAoc3R5bGUgPT0gImNvbW1lbnQiKSByZXR1cm4gc3R5bGU7CisgICAgICBpZiAoY3R4LmFsaWduID09IG51bGwpIGN0eC5hbGlnbiA9IHRydWU7CisKKyAgICAgIGlmICgoY3VyUHVuYyA9PSAiOyIgfHwgY3VyUHVuYyA9PSAiOiIpICYmIGN0eC50eXBlID09ICJzdGF0ZW1lbnQiKSBwb3BDb250ZXh0KHN0YXRlKTsKKyAgICAgIC8vIEhhbmRsZSBpbmRlbnRhdGlvbiBmb3Ige3ggLT4gXG4gLi4uIH0KKyAgICAgIGVsc2UgaWYgKGN1clB1bmMgPT0gIi0+IiAmJiBjdHgudHlwZSA9PSAic3RhdGVtZW50IiAmJiBjdHgucHJldi50eXBlID09ICJ9IikgeworICAgICAgICBwb3BDb250ZXh0KHN0YXRlKTsKKyAgICAgICAgc3RhdGUuY29udGV4dC5hbGlnbiA9IGZhbHNlOworICAgICAgfQorICAgICAgZWxzZSBpZiAoY3VyUHVuYyA9PSAieyIpIHB1c2hDb250ZXh0KHN0YXRlLCBzdHJlYW0uY29sdW1uKCksICJ9Iik7CisgICAgICBlbHNlIGlmIChjdXJQdW5jID09ICJbIikgcHVzaENvbnRleHQoc3RhdGUsIHN0cmVhbS5jb2x1bW4oKSwgIl0iKTsKKyAgICAgIGVsc2UgaWYgKGN1clB1bmMgPT0gIigiKSBwdXNoQ29udGV4dChzdGF0ZSwgc3RyZWFtLmNvbHVtbigpLCAiKSIpOworICAgICAgZWxzZSBpZiAoY3VyUHVuYyA9PSAifSIpIHsKKyAgICAgICAgd2hpbGUgKGN0eC50eXBlID09ICJzdGF0ZW1lbnQiKSBjdHggPSBwb3BDb250ZXh0KHN0YXRlKTsKKyAgICAgICAgaWYgKGN0eC50eXBlID09ICJ9IikgY3R4ID0gcG9wQ29udGV4dChzdGF0ZSk7CisgICAgICAgIHdoaWxlIChjdHgudHlwZSA9PSAic3RhdGVtZW50IikgY3R4ID0gcG9wQ29udGV4dChzdGF0ZSk7CisgICAgICB9CisgICAgICBlbHNlIGlmIChjdXJQdW5jID09IGN0eC50eXBlKSBwb3BDb250ZXh0KHN0YXRlKTsKKyAgICAgIGVsc2UgaWYgKGN0eC50eXBlID09ICJ9IiB8fCBjdHgudHlwZSA9PSAidG9wIiB8fCAoY3R4LnR5cGUgPT0gInN0YXRlbWVudCIgJiYgY3VyUHVuYyA9PSAibmV3c3RhdGVtZW50IikpCisgICAgICAgIHB1c2hDb250ZXh0KHN0YXRlLCBzdHJlYW0uY29sdW1uKCksICJzdGF0ZW1lbnQiKTsKKyAgICAgIHN0YXRlLnN0YXJ0T2ZMaW5lID0gZmFsc2U7CisgICAgICBzdGF0ZS5sYXN0VG9rZW4gPSBjdXJQdW5jIHx8IHN0eWxlOworICAgICAgcmV0dXJuIHN0eWxlOworICAgIH0sCisKKyAgICBpbmRlbnQ6IGZ1bmN0aW9uKHN0YXRlLCB0ZXh0QWZ0ZXIpIHsKKyAgICAgIGlmICghc3RhdGUudG9rZW5pemVbc3RhdGUudG9rZW5pemUubGVuZ3RoLTFdLmlzQmFzZSkgcmV0dXJuIDA7CisgICAgICB2YXIgZmlyc3RDaGFyID0gdGV4dEFmdGVyICYmIHRleHRBZnRlci5jaGFyQXQoMCksIGN0eCA9IHN0YXRlLmNvbnRleHQ7CisgICAgICBpZiAoY3R4LnR5cGUgPT0gInN0YXRlbWVudCIgJiYgIWV4cGVjdEV4cHJlc3Npb24oc3RhdGUubGFzdFRva2VuKSkgY3R4ID0gY3R4LnByZXY7CisgICAgICB2YXIgY2xvc2luZyA9IGZpcnN0Q2hhciA9PSBjdHgudHlwZTsKKyAgICAgIGlmIChjdHgudHlwZSA9PSAic3RhdGVtZW50IikgcmV0dXJuIGN0eC5pbmRlbnRlZCArIChmaXJzdENoYXIgPT0gInsiID8gMCA6IGNvbmZpZy5pbmRlbnRVbml0KTsKKyAgICAgIGVsc2UgaWYgKGN0eC5hbGlnbikgcmV0dXJuIGN0eC5jb2x1bW4gKyAoY2xvc2luZyA/IDAgOiAxKTsKKyAgICAgIGVsc2UgcmV0dXJuIGN0eC5pbmRlbnRlZCArIChjbG9zaW5nID8gMCA6IGNvbmZpZy5pbmRlbnRVbml0KTsKKyAgICB9LAorCisgICAgZWxlY3RyaWNDaGFyczogInt9IgorICB9OworfSk7CisKK0NvZGVNaXJyb3IuZGVmaW5lTUlNRSgidGV4dC94LWdyb292eSIsICJncm9vdnkiKTsKZGlmZiAtLWdpdCBhL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci9tb2RlL2phdmFzY3JpcHQvamF2YXNjcmlwdC5qcyBiL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvY29kZW1pcnJvci9tb2RlL2phdmFzY3JpcHQvamF2YXNjcmlwdC5qcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MWY5NjA4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9jb2RlbWlycm9yL21vZGUvamF2YXNjcmlwdC9qYXZhc2NyaXB0LmpzCkBAIC0wLDAgKzEsMzYxIEBACitDb2RlTWlycm9yLmRlZmluZU1vZGUoImphdmFzY3JpcHQiLCBmdW5jdGlvbihjb25maWcsIHBhcnNlckNvbmZpZykgeworICB2YXIgaW5kZW50VW5pdCA9IGNvbmZpZy5pbmRlbnRVbml0OworICB2YXIganNvbk1vZGUgPSBwYXJzZXJDb25maWcuanNvbjsKKworICAvLyBUb2tlbml6ZXIKKworICB2YXIga2V5d29yZHMgPSBmdW5jdGlvbigpeworICAgIGZ1bmN0aW9uIGt3KHR5cGUpIHtyZXR1cm4ge3R5cGU6IHR5cGUsIHN0eWxlOiAia2V5d29yZCJ9O30KKyAgICB2YXIgQSA9IGt3KCJrZXl3b3JkIGEiKSwgQiA9IGt3KCJrZXl3b3JkIGIiKSwgQyA9IGt3KCJrZXl3b3JkIGMiKTsKKyAgICB2YXIgb3BlcmF0b3IgPSBrdygib3BlcmF0b3IiKSwgYXRvbSA9IHt0eXBlOiAiYXRvbSIsIHN0eWxlOiAiYXRvbSJ9OworICAgIHJldHVybiB7CisgICAgICAiaWYiOiBBLCAid2hpbGUiOiBBLCAid2l0aCI6IEEsICJlbHNlIjogQiwgImRvIjogQiwgInRyeSI6IEIsICJmaW5hbGx5IjogQiwKKyAgICAgICJyZXR1cm4iOiBDLCAiYnJlYWsiOiBDLCAiY29udGludWUiOiBDLCAibmV3IjogQywgImRlbGV0ZSI6IEMsICJ0aHJvdyI6IEMsCisgICAgICAidmFyIjoga3coInZhciIpLCAiY29uc3QiOiBrdygidmFyIiksICJsZXQiOiBrdygidmFyIiksCisgICAgICAiZnVuY3Rpb24iOiBrdygiZnVuY3Rpb24iKSwgImNhdGNoIjoga3coImNhdGNoIiksCisgICAgICAiZm9yIjoga3coImZvciIpLCAic3dpdGNoIjoga3coInN3aXRjaCIpLCAiY2FzZSI6IGt3KCJjYXNlIiksICJkZWZhdWx0Ijoga3coImRlZmF1bHQiKSwKKyAgICAgICJpbiI6IG9wZXJhdG9yLCAidHlwZW9mIjogb3BlcmF0b3IsICJpbnN0YW5jZW9mIjogb3BlcmF0b3IsCisgICAgICAidHJ1ZSI6IGF0b20sICJmYWxzZSI6IGF0b20sICJudWxsIjogYXRvbSwgInVuZGVmaW5lZCI6IGF0b20sICJOYU4iOiBhdG9tLCAiSW5maW5pdHkiOiBhdG9tCisgICAgfTsKKyAgfSgpOworCisgIHZhciBpc09wZXJhdG9yQ2hhciA9IC9bK1wtKiYlPTw+IT98XS87CisKKyAgZnVuY3Rpb24gY2hhaW4oc3RyZWFtLCBzdGF0ZSwgZikgeworICAgIHN0YXRlLnRva2VuaXplID0gZjsKKyAgICByZXR1cm4gZihzdHJlYW0sIHN0YXRlKTsKKyAgfQorCisgIGZ1bmN0aW9uIG5leHRVbnRpbFVuZXNjYXBlZChzdHJlYW0sIGVuZCkgeworICAgIHZhciBlc2NhcGVkID0gZmFsc2UsIG5leHQ7CisgICAgd2hpbGUgKChuZXh0ID0gc3RyZWFtLm5leHQoKSkgIT0gbnVsbCkgeworICAgICAgaWYgKG5leHQgPT0gZW5kICYmICFlc2NhcGVkKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBlc2NhcGVkID0gIWVzY2FwZWQgJiYgbmV4dCA9PSAiXFwiOworICAgIH0KKyAgICByZXR1cm4gZXNjYXBlZDsKKyAgfQorCisgIC8vIFVzZWQgYXMgc2NyYXRjaCB2YXJpYWJsZXMgdG8gY29tbXVuaWNhdGUgbXVsdGlwbGUgdmFsdWVzIHdpdGhvdXQKKyAgLy8gY29uc2luZyB1cCB0b25zIG9mIG9iamVjdHMuCisgIHZhciB0eXBlLCBjb250ZW50OworICBmdW5jdGlvbiByZXQodHAsIHN0eWxlLCBjb250KSB7CisgICAgdHlwZSA9IHRwOyBjb250ZW50ID0gY29udDsKKyAgICByZXR1cm4gc3R5bGU7CisgIH0KKworICBmdW5jdGlvbiBqc1Rva2VuQmFzZShzdHJlYW0sIHN0YXRlKSB7CisgICAgdmFyIGNoID0gc3RyZWFtLm5leHQoKTsKKyAgICBpZiAoY2ggPT0gJyInIHx8IGNoID09ICInIikKKyAgICAgIHJldHVybiBjaGFpbihzdHJlYW0sIHN0YXRlLCBqc1Rva2VuU3RyaW5nKGNoKSk7CisgICAgZWxzZSBpZiAoL1tcW1xde31cKFwpLDtcOlwuXS8udGVzdChjaCkpCisgICAgICByZXR1cm4gcmV0KGNoKTsKKyAgICBlbHNlIGlmIChjaCA9PSAiMCIgJiYgc3RyZWFtLmVhdCgveC9pKSkgeworICAgICAgc3RyZWFtLmVhdFdoaWxlKC9bXGRhLWZdL2kpOworICAgICAgcmV0dXJuIHJldCgibnVtYmVyIiwgIm51bWJlciIpOworICAgIH0gICAgICAKKyAgICBlbHNlIGlmICgvXGQvLnRlc3QoY2gpKSB7CisgICAgICBzdHJlYW0ubWF0Y2goL15cZCooPzpcLlxkKik/KD86W2VFXVsrXC1dP1xkKyk/Lyk7CisgICAgICByZXR1cm4gcmV0KCJudW1iZXIiLCAibnVtYmVyIik7CisgICAgfQorICAgIGVsc2UgaWYgKGNoID09ICIvIikgeworICAgICAgaWYgKHN0cmVhbS5lYXQoIioiKSkgeworICAgICAgICByZXR1cm4gY2hhaW4oc3RyZWFtLCBzdGF0ZSwganNUb2tlbkNvbW1lbnQpOworICAgICAgfQorICAgICAgZWxzZSBpZiAoc3RyZWFtLmVhdCgiLyIpKSB7CisgICAgICAgIHN0cmVhbS5za2lwVG9FbmQoKTsKKyAgICAgICAgcmV0dXJuIHJldCgiY29tbWVudCIsICJjb21tZW50Iik7CisgICAgICB9CisgICAgICBlbHNlIGlmIChzdGF0ZS5yZUFsbG93ZWQpIHsKKyAgICAgICAgbmV4dFVudGlsVW5lc2NhcGVkKHN0cmVhbSwgIi8iKTsKKyAgICAgICAgc3RyZWFtLmVhdFdoaWxlKC9bZ2lteV0vKTsgLy8gJ3knIGlzICJzdGlja3kiIG9wdGlvbiBpbiBNb3ppbGxhCisgICAgICAgIHJldHVybiByZXQoInJlZ2V4cCIsICJzdHJpbmctMiIpOworICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIHN0cmVhbS5lYXRXaGlsZShpc09wZXJhdG9yQ2hhcik7CisgICAgICAgIHJldHVybiByZXQoIm9wZXJhdG9yIiwgbnVsbCwgc3RyZWFtLmN1cnJlbnQoKSk7CisgICAgICB9CisgICAgfQorICAgIGVsc2UgaWYgKGNoID09ICIjIikgeworICAgICAgICBzdHJlYW0uc2tpcFRvRW5kKCk7CisgICAgICAgIHJldHVybiByZXQoImVycm9yIiwgImVycm9yIik7CisgICAgfQorICAgIGVsc2UgaWYgKGlzT3BlcmF0b3JDaGFyLnRlc3QoY2gpKSB7CisgICAgICBzdHJlYW0uZWF0V2hpbGUoaXNPcGVyYXRvckNoYXIpOworICAgICAgcmV0dXJuIHJldCgib3BlcmF0b3IiLCBudWxsLCBzdHJlYW0uY3VycmVudCgpKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICBzdHJlYW0uZWF0V2hpbGUoL1tcd1wkX10vKTsKKyAgICAgIHZhciB3b3JkID0gc3RyZWFtLmN1cnJlbnQoKSwga25vd24gPSBrZXl3b3Jkcy5wcm9wZXJ0eUlzRW51bWVyYWJsZSh3b3JkKSAmJiBrZXl3b3Jkc1t3b3JkXTsKKyAgICAgIHJldHVybiAoa25vd24gJiYgc3RhdGUua3dBbGxvd2VkKSA/IHJldChrbm93bi50eXBlLCBrbm93bi5zdHlsZSwgd29yZCkgOgorICAgICAgICAgICAgICAgICAgICAgcmV0KCJ2YXJpYWJsZSIsICJ2YXJpYWJsZSIsIHdvcmQpOworICAgIH0KKyAgfQorCisgIGZ1bmN0aW9uIGpzVG9rZW5TdHJpbmcocXVvdGUpIHsKKyAgICByZXR1cm4gZnVuY3Rpb24oc3RyZWFtLCBzdGF0ZSkgeworICAgICAgaWYgKCFuZXh0VW50aWxVbmVzY2FwZWQoc3RyZWFtLCBxdW90ZSkpCisgICAgICAgIHN0YXRlLnRva2VuaXplID0ganNUb2tlbkJhc2U7CisgICAgICByZXR1cm4gcmV0KCJzdHJpbmciLCAic3RyaW5nIik7CisgICAgfTsKKyAgfQorCisgIGZ1bmN0aW9uIGpzVG9rZW5Db21tZW50KHN0cmVhbSwgc3RhdGUpIHsKKyAgICB2YXIgbWF5YmVFbmQgPSBmYWxzZSwgY2g7CisgICAgd2hpbGUgKGNoID0gc3RyZWFtLm5leHQoKSkgeworICAgICAgaWYgKGNoID09ICIvIiAmJiBtYXliZUVuZCkgeworICAgICAgICBzdGF0ZS50b2tlbml6ZSA9IGpzVG9rZW5CYXNlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIG1heWJlRW5kID0gKGNoID09ICIqIik7CisgICAgfQorICAgIHJldHVybiByZXQoImNvbW1lbnQiLCAiY29tbWVudCIpOworICB9CisKKyAgLy8gUGFyc2VyCisKKyAgdmFyIGF0b21pY1R5cGVzID0geyJhdG9tIjogdHJ1ZSwgIm51bWJlciI6IHRydWUsICJ2YXJpYWJsZSI6IHRydWUsICJzdHJpbmciOiB0cnVlLCAicmVnZXhwIjogdHJ1ZX07CisKKyAgZnVuY3Rpb24gSlNMZXhpY2FsKGluZGVudGVkLCBjb2x1bW4sIHR5cGUsIGFsaWduLCBwcmV2LCBpbmZvKSB7CisgICAgdGhpcy5pbmRlbnRlZCA9IGluZGVudGVkOworICAgIHRoaXMuY29sdW1uID0gY29sdW1uOworICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgdGhpcy5wcmV2ID0gcHJldjsKKyAgICB0aGlzLmluZm8gPSBpbmZvOworICAgIGlmIChhbGlnbiAhPSBudWxsKSB0aGlzLmFsaWduID0gYWxpZ247CisgIH0KKworICBmdW5jdGlvbiBpblNjb3BlKHN0YXRlLCB2YXJuYW1lKSB7CisgICAgZm9yICh2YXIgdiA9IHN0YXRlLmxvY2FsVmFyczsgdjsgdiA9IHYubmV4dCkKKyAgICAgIGlmICh2Lm5hbWUgPT0gdmFybmFtZSkgcmV0dXJuIHRydWU7CisgIH0KKworICBmdW5jdGlvbiBwYXJzZUpTKHN0YXRlLCBzdHlsZSwgdHlwZSwgY29udGVudCwgc3RyZWFtKSB7CisgICAgdmFyIGNjID0gc3RhdGUuY2M7CisgICAgLy8gQ29tbXVuaWNhdGUgb3VyIGNvbnRleHQgdG8gdGhlIGNvbWJpbmF0b3JzLgorICAgIC8vIChMZXNzIHdhc3RlZnVsIHRoYW4gY29uc2luZyB1cCBhIGh1bmRyZWQgY2xvc3VyZXMgb24gZXZlcnkgY2FsbC4pCisgICAgY3guc3RhdGUgPSBzdGF0ZTsgY3guc3RyZWFtID0gc3RyZWFtOyBjeC5tYXJrZWQgPSBudWxsLCBjeC5jYyA9IGNjOworICAKKyAgICBpZiAoIXN0YXRlLmxleGljYWwuaGFzT3duUHJvcGVydHkoImFsaWduIikpCisgICAgICBzdGF0ZS5sZXhpY2FsLmFsaWduID0gdHJ1ZTsKKworICAgIHdoaWxlKHRydWUpIHsKKyAgICAgIHZhciBjb21iaW5hdG9yID0gY2MubGVuZ3RoID8gY2MucG9wKCkgOiBqc29uTW9kZSA/IGV4cHJlc3Npb24gOiBzdGF0ZW1lbnQ7CisgICAgICBpZiAoY29tYmluYXRvcih0eXBlLCBjb250ZW50KSkgeworICAgICAgICB3aGlsZShjYy5sZW5ndGggJiYgY2NbY2MubGVuZ3RoIC0gMV0ubGV4KQorICAgICAgICAgIGNjLnBvcCgpKCk7CisgICAgICAgIGlmIChjeC5tYXJrZWQpIHJldHVybiBjeC5tYXJrZWQ7CisgICAgICAgIGlmICh0eXBlID09ICJ2YXJpYWJsZSIgJiYgaW5TY29wZShzdGF0ZSwgY29udGVudCkpIHJldHVybiAidmFyaWFibGUtMiI7CisgICAgICAgIHJldHVybiBzdHlsZTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBDb21iaW5hdG9yIHV0aWxzCisKKyAgdmFyIGN4ID0ge3N0YXRlOiBudWxsLCBjb2x1bW46IG51bGwsIG1hcmtlZDogbnVsbCwgY2M6IG51bGx9OworICBmdW5jdGlvbiBwYXNzKCkgeworICAgIGZvciAodmFyIGkgPSBhcmd1bWVudHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGN4LmNjLnB1c2goYXJndW1lbnRzW2ldKTsKKyAgfQorICBmdW5jdGlvbiBjb250KCkgeworICAgIHBhc3MuYXBwbHkobnVsbCwgYXJndW1lbnRzKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICBmdW5jdGlvbiByZWdpc3Rlcih2YXJuYW1lKSB7CisgICAgdmFyIHN0YXRlID0gY3guc3RhdGU7CisgICAgaWYgKHN0YXRlLmNvbnRleHQpIHsKKyAgICAgIGN4Lm1hcmtlZCA9ICJkZWYiOworICAgICAgZm9yICh2YXIgdiA9IHN0YXRlLmxvY2FsVmFyczsgdjsgdiA9IHYubmV4dCkKKyAgICAgICAgaWYgKHYubmFtZSA9PSB2YXJuYW1lKSByZXR1cm47CisgICAgICBzdGF0ZS5sb2NhbFZhcnMgPSB7bmFtZTogdmFybmFtZSwgbmV4dDogc3RhdGUubG9jYWxWYXJzfTsKKyAgICB9CisgIH0KKworICAvLyBDb21iaW5hdG9ycworCisgIHZhciBkZWZhdWx0VmFycyA9IHtuYW1lOiAidGhpcyIsIG5leHQ6IHtuYW1lOiAiYXJndW1lbnRzIn19OworICBmdW5jdGlvbiBwdXNoY29udGV4dCgpIHsKKyAgICBpZiAoIWN4LnN0YXRlLmNvbnRleHQpIGN4LnN0YXRlLmxvY2FsVmFycyA9IGRlZmF1bHRWYXJzOworICAgIGN4LnN0YXRlLmNvbnRleHQgPSB7cHJldjogY3guc3RhdGUuY29udGV4dCwgdmFyczogY3guc3RhdGUubG9jYWxWYXJzfTsKKyAgfQorICBmdW5jdGlvbiBwb3Bjb250ZXh0KCkgeworICAgIGN4LnN0YXRlLmxvY2FsVmFycyA9IGN4LnN0YXRlLmNvbnRleHQudmFyczsKKyAgICBjeC5zdGF0ZS5jb250ZXh0ID0gY3guc3RhdGUuY29udGV4dC5wcmV2OworICB9CisgIGZ1bmN0aW9uIHB1c2hsZXgodHlwZSwgaW5mbykgeworICAgIHZhciByZXN1bHQgPSBmdW5jdGlvbigpIHsKKyAgICAgIHZhciBzdGF0ZSA9IGN4LnN0YXRlOworICAgICAgc3RhdGUubGV4aWNhbCA9IG5ldyBKU0xleGljYWwoc3RhdGUuaW5kZW50ZWQsIGN4LnN0cmVhbS5jb2x1bW4oKSwgdHlwZSwgbnVsbCwgc3RhdGUubGV4aWNhbCwgaW5mbykKKyAgICB9OworICAgIHJlc3VsdC5sZXggPSB0cnVlOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyAgZnVuY3Rpb24gcG9wbGV4KCkgeworICAgIHZhciBzdGF0ZSA9IGN4LnN0YXRlOworICAgIGlmIChzdGF0ZS5sZXhpY2FsLnByZXYpIHsKKyAgICAgIGlmIChzdGF0ZS5sZXhpY2FsLnR5cGUgPT0gIikiKQorICAgICAgICBzdGF0ZS5pbmRlbnRlZCA9IHN0YXRlLmxleGljYWwuaW5kZW50ZWQ7CisgICAgICBzdGF0ZS5sZXhpY2FsID0gc3RhdGUubGV4aWNhbC5wcmV2OworICAgIH0KKyAgfQorICBwb3BsZXgubGV4ID0gdHJ1ZTsKKworICBmdW5jdGlvbiBleHBlY3Qod2FudGVkKSB7CisgICAgcmV0dXJuIGZ1bmN0aW9uIGV4cGVjdGluZyh0eXBlKSB7CisgICAgICBpZiAodHlwZSA9PSB3YW50ZWQpIHJldHVybiBjb250KCk7CisgICAgICBlbHNlIGlmICh3YW50ZWQgPT0gIjsiKSByZXR1cm4gcGFzcygpOworICAgICAgZWxzZSByZXR1cm4gY29udChhcmd1bWVudHMuY2FsbGVlKTsKKyAgICB9OworICB9CisKKyAgZnVuY3Rpb24gc3RhdGVtZW50KHR5cGUpIHsKKyAgICBpZiAodHlwZSA9PSAidmFyIikgcmV0dXJuIGNvbnQocHVzaGxleCgidmFyZGVmIiksIHZhcmRlZjEsIGV4cGVjdCgiOyIpLCBwb3BsZXgpOworICAgIGlmICh0eXBlID09ICJrZXl3b3JkIGEiKSByZXR1cm4gY29udChwdXNobGV4KCJmb3JtIiksIGV4cHJlc3Npb24sIHN0YXRlbWVudCwgcG9wbGV4KTsKKyAgICBpZiAodHlwZSA9PSAia2V5d29yZCBiIikgcmV0dXJuIGNvbnQocHVzaGxleCgiZm9ybSIpLCBzdGF0ZW1lbnQsIHBvcGxleCk7CisgICAgaWYgKHR5cGUgPT0gInsiKSByZXR1cm4gY29udChwdXNobGV4KCJ9IiksIGJsb2NrLCBwb3BsZXgpOworICAgIGlmICh0eXBlID09ICI7IikgcmV0dXJuIGNvbnQoKTsKKyAgICBpZiAodHlwZSA9PSAiZnVuY3Rpb24iKSByZXR1cm4gY29udChmdW5jdGlvbmRlZik7CisgICAgaWYgKHR5cGUgPT0gImZvciIpIHJldHVybiBjb250KHB1c2hsZXgoImZvcm0iKSwgZXhwZWN0KCIoIiksIHB1c2hsZXgoIikiKSwgZm9yc3BlYzEsIGV4cGVjdCgiKSIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3BsZXgsIHN0YXRlbWVudCwgcG9wbGV4KTsKKyAgICBpZiAodHlwZSA9PSAidmFyaWFibGUiKSByZXR1cm4gY29udChwdXNobGV4KCJzdGF0IiksIG1heWJlbGFiZWwpOworICAgIGlmICh0eXBlID09ICJzd2l0Y2giKSByZXR1cm4gY29udChwdXNobGV4KCJmb3JtIiksIGV4cHJlc3Npb24sIHB1c2hsZXgoIn0iLCAic3dpdGNoIiksIGV4cGVjdCgieyIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBibG9jaywgcG9wbGV4LCBwb3BsZXgpOworICAgIGlmICh0eXBlID09ICJjYXNlIikgcmV0dXJuIGNvbnQoZXhwcmVzc2lvbiwgZXhwZWN0KCI6IikpOworICAgIGlmICh0eXBlID09ICJkZWZhdWx0IikgcmV0dXJuIGNvbnQoZXhwZWN0KCI6IikpOworICAgIGlmICh0eXBlID09ICJjYXRjaCIpIHJldHVybiBjb250KHB1c2hsZXgoImZvcm0iKSwgcHVzaGNvbnRleHQsIGV4cGVjdCgiKCIpLCBmdW5hcmcsIGV4cGVjdCgiKSIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudCwgcG9wbGV4LCBwb3Bjb250ZXh0KTsKKyAgICByZXR1cm4gcGFzcyhwdXNobGV4KCJzdGF0IiksIGV4cHJlc3Npb24sIGV4cGVjdCgiOyIpLCBwb3BsZXgpOworICB9CisgIGZ1bmN0aW9uIGV4cHJlc3Npb24odHlwZSkgeworICAgIGlmIChhdG9taWNUeXBlcy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkgcmV0dXJuIGNvbnQobWF5YmVvcGVyYXRvcik7CisgICAgaWYgKHR5cGUgPT0gImZ1bmN0aW9uIikgcmV0dXJuIGNvbnQoZnVuY3Rpb25kZWYpOworICAgIGlmICh0eXBlID09ICJrZXl3b3JkIGMiKSByZXR1cm4gY29udChtYXliZWV4cHJlc3Npb24pOworICAgIGlmICh0eXBlID09ICIoIikgcmV0dXJuIGNvbnQocHVzaGxleCgiKSIpLCBtYXliZWV4cHJlc3Npb24sIGV4cGVjdCgiKSIpLCBwb3BsZXgsIG1heWJlb3BlcmF0b3IpOworICAgIGlmICh0eXBlID09ICJvcGVyYXRvciIpIHJldHVybiBjb250KGV4cHJlc3Npb24pOworICAgIGlmICh0eXBlID09ICJbIikgcmV0dXJuIGNvbnQocHVzaGxleCgiXSIpLCBjb21tYXNlcChleHByZXNzaW9uLCAiXSIpLCBwb3BsZXgsIG1heWJlb3BlcmF0b3IpOworICAgIGlmICh0eXBlID09ICJ7IikgcmV0dXJuIGNvbnQocHVzaGxleCgifSIpLCBjb21tYXNlcChvYmpwcm9wLCAifSIpLCBwb3BsZXgsIG1heWJlb3BlcmF0b3IpOworICAgIHJldHVybiBjb250KCk7CisgIH0KKyAgZnVuY3Rpb24gbWF5YmVleHByZXNzaW9uKHR5cGUpIHsKKyAgICBpZiAodHlwZS5tYXRjaCgvWztcfVwpXF0sXS8pKSByZXR1cm4gcGFzcygpOworICAgIHJldHVybiBwYXNzKGV4cHJlc3Npb24pOworICB9CisgICAgCisgIGZ1bmN0aW9uIG1heWJlb3BlcmF0b3IodHlwZSwgdmFsdWUpIHsKKyAgICBpZiAodHlwZSA9PSAib3BlcmF0b3IiICYmIC9cK1wrfC0tLy50ZXN0KHZhbHVlKSkgcmV0dXJuIGNvbnQobWF5YmVvcGVyYXRvcik7CisgICAgaWYgKHR5cGUgPT0gIm9wZXJhdG9yIiB8fCB0eXBlID09ICI6IikgcmV0dXJuIGNvbnQoZXhwcmVzc2lvbik7CisgICAgaWYgKHR5cGUgPT0gIjsiKSByZXR1cm47CisgICAgaWYgKHR5cGUgPT0gIigiKSByZXR1cm4gY29udChwdXNobGV4KCIpIiksIGNvbW1hc2VwKGV4cHJlc3Npb24sICIpIiksIHBvcGxleCwgbWF5YmVvcGVyYXRvcik7CisgICAgaWYgKHR5cGUgPT0gIi4iKSByZXR1cm4gY29udChwcm9wZXJ0eSwgbWF5YmVvcGVyYXRvcik7CisgICAgaWYgKHR5cGUgPT0gIlsiKSByZXR1cm4gY29udChwdXNobGV4KCJdIiksIGV4cHJlc3Npb24sIGV4cGVjdCgiXSIpLCBwb3BsZXgsIG1heWJlb3BlcmF0b3IpOworICB9CisgIGZ1bmN0aW9uIG1heWJlbGFiZWwodHlwZSkgeworICAgIGlmICh0eXBlID09ICI6IikgcmV0dXJuIGNvbnQocG9wbGV4LCBzdGF0ZW1lbnQpOworICAgIHJldHVybiBwYXNzKG1heWJlb3BlcmF0b3IsIGV4cGVjdCgiOyIpLCBwb3BsZXgpOworICB9CisgIGZ1bmN0aW9uIHByb3BlcnR5KHR5cGUpIHsKKyAgICBpZiAodHlwZSA9PSAidmFyaWFibGUiKSB7Y3gubWFya2VkID0gInByb3BlcnR5IjsgcmV0dXJuIGNvbnQoKTt9CisgIH0KKyAgZnVuY3Rpb24gb2JqcHJvcCh0eXBlKSB7CisgICAgaWYgKHR5cGUgPT0gInZhcmlhYmxlIikgY3gubWFya2VkID0gInByb3BlcnR5IjsKKyAgICBpZiAoYXRvbWljVHlwZXMuaGFzT3duUHJvcGVydHkodHlwZSkpIHJldHVybiBjb250KGV4cGVjdCgiOiIpLCBleHByZXNzaW9uKTsKKyAgfQorICBmdW5jdGlvbiBjb21tYXNlcCh3aGF0LCBlbmQpIHsKKyAgICBmdW5jdGlvbiBwcm9jZWVkKHR5cGUpIHsKKyAgICAgIGlmICh0eXBlID09ICIsIikgcmV0dXJuIGNvbnQod2hhdCwgcHJvY2VlZCk7CisgICAgICBpZiAodHlwZSA9PSBlbmQpIHJldHVybiBjb250KCk7CisgICAgICByZXR1cm4gY29udChleHBlY3QoZW5kKSk7CisgICAgfQorICAgIHJldHVybiBmdW5jdGlvbiBjb21tYVNlcGFyYXRlZCh0eXBlKSB7CisgICAgICBpZiAodHlwZSA9PSBlbmQpIHJldHVybiBjb250KCk7CisgICAgICBlbHNlIHJldHVybiBwYXNzKHdoYXQsIHByb2NlZWQpOworICAgIH07CisgIH0KKyAgZnVuY3Rpb24gYmxvY2sodHlwZSkgeworICAgIGlmICh0eXBlID09ICJ9IikgcmV0dXJuIGNvbnQoKTsKKyAgICByZXR1cm4gcGFzcyhzdGF0ZW1lbnQsIGJsb2NrKTsKKyAgfQorICBmdW5jdGlvbiB2YXJkZWYxKHR5cGUsIHZhbHVlKSB7CisgICAgaWYgKHR5cGUgPT0gInZhcmlhYmxlIil7cmVnaXN0ZXIodmFsdWUpOyByZXR1cm4gY29udCh2YXJkZWYyKTt9CisgICAgcmV0dXJuIGNvbnQoKTsKKyAgfQorICBmdW5jdGlvbiB2YXJkZWYyKHR5cGUsIHZhbHVlKSB7CisgICAgaWYgKHZhbHVlID09ICI9IikgcmV0dXJuIGNvbnQoZXhwcmVzc2lvbiwgdmFyZGVmMik7CisgICAgaWYgKHR5cGUgPT0gIiwiKSByZXR1cm4gY29udCh2YXJkZWYxKTsKKyAgfQorICBmdW5jdGlvbiBmb3JzcGVjMSh0eXBlKSB7CisgICAgaWYgKHR5cGUgPT0gInZhciIpIHJldHVybiBjb250KHZhcmRlZjEsIGZvcnNwZWMyKTsKKyAgICBpZiAodHlwZSA9PSAiOyIpIHJldHVybiBwYXNzKGZvcnNwZWMyKTsKKyAgICBpZiAodHlwZSA9PSAidmFyaWFibGUiKSByZXR1cm4gY29udChmb3JtYXliZWluKTsKKyAgICByZXR1cm4gcGFzcyhmb3JzcGVjMik7CisgIH0KKyAgZnVuY3Rpb24gZm9ybWF5YmVpbih0eXBlLCB2YWx1ZSkgeworICAgIGlmICh2YWx1ZSA9PSAiaW4iKSByZXR1cm4gY29udChleHByZXNzaW9uKTsKKyAgICByZXR1cm4gY29udChtYXliZW9wZXJhdG9yLCBmb3JzcGVjMik7CisgIH0KKyAgZnVuY3Rpb24gZm9yc3BlYzIodHlwZSwgdmFsdWUpIHsKKyAgICBpZiAodHlwZSA9PSAiOyIpIHJldHVybiBjb250KGZvcnNwZWMzKTsKKyAgICBpZiAodmFsdWUgPT0gImluIikgcmV0dXJuIGNvbnQoZXhwcmVzc2lvbik7CisgICAgcmV0dXJuIGNvbnQoZXhwcmVzc2lvbiwgZXhwZWN0KCI7IiksIGZvcnNwZWMzKTsKKyAgfQorICBmdW5jdGlvbiBmb3JzcGVjMyh0eXBlKSB7CisgICAgaWYgKHR5cGUgIT0gIikiKSBjb250KGV4cHJlc3Npb24pOworICB9CisgIGZ1bmN0aW9uIGZ1bmN0aW9uZGVmKHR5cGUsIHZhbHVlKSB7CisgICAgaWYgKHR5cGUgPT0gInZhcmlhYmxlIikge3JlZ2lzdGVyKHZhbHVlKTsgcmV0dXJuIGNvbnQoZnVuY3Rpb25kZWYpO30KKyAgICBpZiAodHlwZSA9PSAiKCIpIHJldHVybiBjb250KHB1c2hsZXgoIikiKSwgcHVzaGNvbnRleHQsIGNvbW1hc2VwKGZ1bmFyZywgIikiKSwgcG9wbGV4LCBzdGF0ZW1lbnQsIHBvcGNvbnRleHQpOworICB9CisgIGZ1bmN0aW9uIGZ1bmFyZyh0eXBlLCB2YWx1ZSkgeworICAgIGlmICh0eXBlID09ICJ2YXJpYWJsZSIpIHtyZWdpc3Rlcih2YWx1ZSk7IHJldHVybiBjb250KCk7fQorICB9CisKKyAgLy8gSW50ZXJmYWNlCisKKyAgcmV0dXJuIHsKKyAgICBzdGFydFN0YXRlOiBmdW5jdGlvbihiYXNlY29sdW1uKSB7CisgICAgICByZXR1cm4geworICAgICAgICB0b2tlbml6ZToganNUb2tlbkJhc2UsCisgICAgICAgIHJlQWxsb3dlZDogdHJ1ZSwKKyAgICAgICAga3dBbGxvd2VkOiB0cnVlLAorICAgICAgICBjYzogW10sCisgICAgICAgIGxleGljYWw6IG5ldyBKU0xleGljYWwoKGJhc2Vjb2x1bW4gfHwgMCkgLSBpbmRlbnRVbml0LCAwLCAiYmxvY2siLCBmYWxzZSksCisgICAgICAgIGxvY2FsVmFyczogcGFyc2VyQ29uZmlnLmxvY2FsVmFycywKKyAgICAgICAgY29udGV4dDogcGFyc2VyQ29uZmlnLmxvY2FsVmFycyAmJiB7dmFyczogcGFyc2VyQ29uZmlnLmxvY2FsVmFyc30sCisgICAgICAgIGluZGVudGVkOiAwCisgICAgICB9OworICAgIH0sCisKKyAgICB0b2tlbjogZnVuY3Rpb24oc3RyZWFtLCBzdGF0ZSkgeworICAgICAgaWYgKHN0cmVhbS5zb2woKSkgeworICAgICAgICBpZiAoIXN0YXRlLmxleGljYWwuaGFzT3duUHJvcGVydHkoImFsaWduIikpCisgICAgICAgICAgc3RhdGUubGV4aWNhbC5hbGlnbiA9IGZhbHNlOworICAgICAgICBzdGF0ZS5pbmRlbnRlZCA9IHN0cmVhbS5pbmRlbnRhdGlvbigpOworICAgICAgfQorICAgICAgaWYgKHN0cmVhbS5lYXRTcGFjZSgpKSByZXR1cm4gbnVsbDsKKyAgICAgIHZhciBzdHlsZSA9IHN0YXRlLnRva2VuaXplKHN0cmVhbSwgc3RhdGUpOworICAgICAgaWYgKHR5cGUgPT0gImNvbW1lbnQiKSByZXR1cm4gc3R5bGU7CisgICAgICBzdGF0ZS5yZUFsbG93ZWQgPSAhISh0eXBlID09ICJvcGVyYXRvciIgfHwgdHlwZSA9PSAia2V5d29yZCBjIiB8fCB0eXBlLm1hdGNoKC9eW1xbe31cKCw7Ol0kLykpOworICAgICAgc3RhdGUua3dBbGxvd2VkID0gdHlwZSAhPSAnLic7CisgICAgICByZXR1cm4gcGFyc2VKUyhzdGF0ZSwgc3R5bGUsIHR5cGUsIGNvbnRlbnQsIHN0cmVhbSk7CisgICAgfSwKKworICAgIGluZGVudDogZnVuY3Rpb24oc3RhdGUsIHRleHRBZnRlcikgeworICAgICAgaWYgKHN0YXRlLnRva2VuaXplICE9IGpzVG9rZW5CYXNlKSByZXR1cm4gMDsKKyAgICAgIHZhciBmaXJzdENoYXIgPSB0ZXh0QWZ0ZXIgJiYgdGV4dEFmdGVyLmNoYXJBdCgwKSwgbGV4aWNhbCA9IHN0YXRlLmxleGljYWw7CisgICAgICBpZiAobGV4aWNhbC50eXBlID09ICJzdGF0IiAmJiBmaXJzdENoYXIgPT0gIn0iKSBsZXhpY2FsID0gbGV4aWNhbC5wcmV2OworICAgICAgdmFyIHR5cGUgPSBsZXhpY2FsLnR5cGUsIGNsb3NpbmcgPSBmaXJzdENoYXIgPT0gdHlwZTsKKyAgICAgIGlmICh0eXBlID09ICJ2YXJkZWYiKSByZXR1cm4gbGV4aWNhbC5pbmRlbnRlZCArIDQ7CisgICAgICBlbHNlIGlmICh0eXBlID09ICJmb3JtIiAmJiBmaXJzdENoYXIgPT0gInsiKSByZXR1cm4gbGV4aWNhbC5pbmRlbnRlZDsKKyAgICAgIGVsc2UgaWYgKHR5cGUgPT0gInN0YXQiIHx8IHR5cGUgPT0gImZvcm0iKSByZXR1cm4gbGV4aWNhbC5pbmRlbnRlZCArIGluZGVudFVuaXQ7CisgICAgICBlbHNlIGlmIChsZXhpY2FsLmluZm8gPT0gInN3aXRjaCIgJiYgIWNsb3NpbmcpCisgICAgICAgIHJldHVybiBsZXhpY2FsLmluZGVudGVkICsgKC9eKD86Y2FzZXxkZWZhdWx0KVxiLy50ZXN0KHRleHRBZnRlcikgPyBpbmRlbnRVbml0IDogMiAqIGluZGVudFVuaXQpOworICAgICAgZWxzZSBpZiAobGV4aWNhbC5hbGlnbikgcmV0dXJuIGxleGljYWwuY29sdW1uICsgKGNsb3NpbmcgPyAwIDogMSk7CisgICAgICBlbHNlIHJldHVybiBsZXhpY2FsLmluZGVudGVkICsgKGNsb3NpbmcgPyAwIDogaW5kZW50VW5pdCk7CisgICAgfSwKKworICAgIGVsZWN0cmljQ2hhcnM6ICI6e30iCisgIH07Cit9KTsKKworQ29kZU1pcnJvci5kZWZpbmVNSU1FKCJ0ZXh0L2phdmFzY3JpcHQiLCAiamF2YXNjcmlwdCIpOworQ29kZU1pcnJvci5kZWZpbmVNSU1FKCJhcHBsaWNhdGlvbi9qc29uIiwge25hbWU6ICJqYXZhc2NyaXB0IiwganNvbjogdHJ1ZX0pOwpkaWZmIC0tZ2l0IGEvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9zY3JpcHQtY29uc29sZS5jc3MgYi9zcmMvbWFpbi9yZXNvdXJjZXMvcmVzL3VpL3NjcmlwdC1jb25zb2xlLmNzcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMDA3ZGY4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9zY3JpcHQtY29uc29sZS5jc3MKQEAgLTAsMCArMSw0IEBACisuQ29kZU1pcnJvciB7CisgICAgLypib3JkZXItdG9wOiAxcHggc29saWQgYmxhY2s7Ki8KKyAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgYmxhY2s7Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vcmVzb3VyY2VzL3Jlcy91aS9zY3JpcHQtY29uc29sZS5qcyBiL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvc2NyaXB0LWNvbnNvbGUuanMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmVjZTY0NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL3Jlc291cmNlcy9yZXMvdWkvc2NyaXB0LWNvbnNvbGUuanMKQEAgLTAsMCArMSwxMDQgQEAKKy8vQ29kZW1pcnJvciBlZGl0b3IKK3ZhciBpbnB1dEVkaXRvcgordmFyIG91dHB1dEVkaXRvcgordmFyIE9VVFBVVF9TRVAgPSAnXG4tLS0tLS0tLS0tLS0tLS0tLS1cbicKKworZnVuY3Rpb24gc2VuZERhdGEodXJsLCBkYXRhKSB7CisgICAgJC5hamF4KHsKKyAgICAgICAgdHlwZToiUE9TVCIsCisgICAgICAgIHVybDp1cmwsCisgICAgICAgIGRhdGE6ZGF0YSwKKy8vICAgICAgICBkYXRhVHlwZToianNvbiIsCisgICAgICAgIHRpbWVvdXQ6MzAwMDAsIC8vSW4gbWlsbGlzCisgICAgICAgIGJlZm9yZVNlbmQ6ZnVuY3Rpb24gKCkgeworICAgICAgICAgICAgJCgnI2FqYXhTcGlubmVyJykuc2hvdygpOworICAgICAgICB9LAorICAgICAgICAvKiBlcnJvcjogZnVuY3Rpb24oKSB7CisgICAgICAgICAkKCcjc3RhdHVzJykudGV4dCgnVXBkYXRlIGZhaWxlZJd0cnkgYWdhaW4uJykuc2xpZGVEb3duKCdzbG93Jyk7CisgICAgICAgICB9LCovCisgICAgICAgIGNvbXBsZXRlOmZ1bmN0aW9uICgpIHsKKyAgICAgICAgICAgICQoJyNhamF4U3Bpbm5lcicpLmhpZGUoKTsKKyAgICAgICAgfSwKKyAgICAgICAgc3VjY2VzczpmdW5jdGlvbiAoZGF0YSkgeworICAgICAgICAgICAgcmVuZGVyRGF0YShkYXRhKQorICAgICAgICB9CisgICAgfSk7Cit9CisKK2Z1bmN0aW9uIHJlbmRlckRhdGEoZGF0YSl7CisgICAgJCgnI2NvZGUtb3V0cHV0Jykuc2hvdygpOworICAgIHZhciBjdXJyZW50RGF0YSA9IG91dHB1dEVkaXRvci5nZXRWYWx1ZSgpCisgICAgLy9JZiB3ZSBuZWVkIHRvIGFwcGVuZCB0aGUgZGF0YSB0aGVuIHVzZSBiZWxvdworICAgIC8vRm9yIG5vdyB3ZSBqdXN0IHJlcGxhY2UgdGhlIGV4aXN0aW5nIG91dHB1dAorICAgIC8vdmFyIG91dERhdGEgPSBkYXRhICsgT1VUUFVUX1NFUCsgY3VycmVudERhdGEKKworICAgIG91dHB1dEVkaXRvci5zZXRWYWx1ZShkYXRhKQorfQorCitmdW5jdGlvbiBzZXRVcENvZGVNaXJyb3IoKSB7CisgICAgQ29kZU1pcnJvci5tb2RlVVJMID0gcGx1Z2luUm9vdCArICIvcmVzL3VpL2NvZGVtaXJyb3IvbW9kZS8lTi8lTi5qcyI7CisgICAgaW5wdXRFZGl0b3IgPSBDb2RlTWlycm9yLmZyb21UZXh0QXJlYShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiY29kZSIpLCB7CisgICAgICAgIGxpbmVOdW1iZXJzOnRydWUsCisgICAgICAgIGV4dHJhS2V5czogeworICAgICAgICAgICAgJ0N0cmwtUSc6Y2xlYXJPdXRwdXQsCisgICAgICAgICAgICAnQ3RybC1YJzpleGVjdXRlU2NyaXB0CisgICAgICAgIH0KKyAgICB9KTsKKyAgICBvdXRwdXRFZGl0b3IgPSBDb2RlTWlycm9yLmZyb21UZXh0QXJlYShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicmVzdWx0IiksIHsKKyAgICAgICAgICAgIGxpbmVOdW1iZXJzOnRydWUsCisgICAgICAgICAgICByZWFkT25seToibm9jdXJzb3IiCisgICAgICAgIH0pOworfQorCitmdW5jdGlvbiB1cGRhdGVXaXRoT3B0aW9uKG9wdCl7CisgICAgc2V0TGFuZ01vZGUoaW5wdXRFZGl0b3Isb3B0LmF0dHIoJ2xhbmdNb2RlJykpCisgICAgJCgnW25hbWU9bGFuZ10nKS52YWwob3B0LnZhbCgpKQorfQorCitmdW5jdGlvbiBzZXRMYW5nTW9kZShlZGl0b3IsIG1vZGVOYW1lKSB7CisgICAgaWYoIW1vZGVOYW1lKXsKKyAgICAgICAgbW9kZU5hbWUgPSAidGV4dC9wbGFpbiIKKyAgICB9ZWxzZXsKKyAgICAgICAgQ29kZU1pcnJvci5hdXRvTG9hZE1vZGUoaW5wdXRFZGl0b3IsIG1vZGVOYW1lKTsKKyAgICB9CisgICAgZWRpdG9yLnNldE9wdGlvbigibW9kZSIsIG1vZGVOYW1lKTsKK30KKworZnVuY3Rpb24gc2V0VXBMYW5nT3B0aW9ucygpIHsKKyAgICB2YXIgY29kZUxhbmcgPSAkKCcjY29kZUxhbmcnKQorICAgIHZhciBvcHRpb25zID0gY29kZUxhbmcuYXR0cignb3B0aW9ucycpOworICAgIGNvZGVMYW5nLmVtcHR5KCkKKworICAgIGZvcih2YXIgaSBpbiBzY3JpcHRDb25maWcpeworICAgICAgICB2YXIgY29uZmlnID0gc2NyaXB0Q29uZmlnW2ldCisgICAgICAgIHZhciBvcHQgPSBuZXcgT3B0aW9uKGNvbmZpZy5sYW5nTmFtZSxjb25maWcubGFuZ0NvZGUpOworICAgICAgICBpZihjb25maWcubW9kZSl7CisgICAgICAgICAgICBvcHQubGFuZ01vZGUgPSBjb25maWcubW9kZTsKKyAgICAgICAgfQorICAgICAgICBvcHRpb25zW29wdGlvbnMubGVuZ3RoXSA9IG9wdAorICAgIH0KKyAgICAkKCcjY29kZUxhbmcnKS5jaGFuZ2UoZnVuY3Rpb24oKXsKKyAgICAgICAgdmFyIG9wdCA9ICQodGhpcykuZmluZCgiOnNlbGVjdGVkIik7CisgICAgICAgIHVwZGF0ZVdpdGhPcHRpb24ob3B0KQorICAgIH0pOworCisgICAgJCgnI2NvZGVMYW5nIG9wdGlvbjplcSgwKScpLmF0dHIoJ3NlbGVjdGVkJywnc2VsZWN0ZWQnKQorICAgIHVwZGF0ZVdpdGhPcHRpb24oJChvcHRpb25zWzBdKSkKK30KKworZnVuY3Rpb24gZXhlY3V0ZVNjcmlwdCgpeworICAgIGlucHV0RWRpdG9yLnNhdmUoKSAvL0NvcHkgdGhlIGNvbnRlbnRzIHRvIHRleHRhcmVhIGZvcm0gZmllbGQKKyAgICBzZW5kRGF0YShwbHVnaW5Sb290LCAkKCIjY29uc29sZUZvcm0iKS5zZXJpYWxpemUoKSk7Cit9CisKK2Z1bmN0aW9uIGNsZWFyT3V0cHV0KCl7CisgICAgb3V0cHV0RWRpdG9yLnNldFZhbHVlKCcnKQorfQorCiskKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbiAoKSB7CisgICAgJCgiI2V4ZWN1dGVCdXR0b24iKS5jbGljayhleGVjdXRlU2NyaXB0KTsKKyAgICAkKCcjYWpheFNwaW5uZXInKS5oaWRlKCk7CisgICAgJCgnI2NvZGUtb3V0cHV0JykuaGlkZSgpOworICAgIHNldFVwQ29kZU1pcnJvcigpOworICAgIHNldFVwTGFuZ09wdGlvbnMoKTsKK30pOwpkaWZmIC0tZ2l0IGEvc3JjL21haW4vcmVzb3VyY2VzL3RlbXBsYXRlcy9zY3JpcHQtY29uc29sZS5odG1sIGIvc3JjL21haW4vcmVzb3VyY2VzL3RlbXBsYXRlcy9zY3JpcHQtY29uc29sZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ5ZWIyNTAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9yZXNvdXJjZXMvdGVtcGxhdGVzL3NjcmlwdC1jb25zb2xlLmh0bWwKQEAgLTAsMCArMSwzNCBAQAorPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iJHtwbHVnaW5Sb290fS9yZXMvdWkvY29kZW1pcnJvci9saWIvY29kZW1pcnJvci5qcyI+PC9zY3JpcHQ+Cis8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSIke3BsdWdpblJvb3R9L3Jlcy91aS9jb2RlbWlycm9yL2xpYi91dGlsL3J1bm1vZGUuanMiPjwvc2NyaXB0PgorPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iJHtwbHVnaW5Sb290fS9yZXMvdWkvY29kZW1pcnJvci9saWIvdXRpbC9sb2FkbW9kZS5qcyI+PC9zY3JpcHQ+Cis8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSIke3BsdWdpblJvb3R9L3Jlcy91aS9zY3JpcHQtY29uc29sZS5qcyI+PC9zY3JpcHQ+Cis8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+CisvLyA8IVtDREFUQVsKK3ZhciBzY3JpcHRDb25maWcgPSAke19fc2NyaXB0Q29uZmlnX199OworLy8gXV0+Cis8L3NjcmlwdD4KKworPCEtLSBzdGF0dXMgbGluZSAtLT4KKzxwIGNsYXNzPSJzdGF0bGluZSI+Jm5ic3A7PC9wPgorPGRpdiBjbGFzcz0idWktd2lkZ2V0LWhlYWRlciAiPgorICAgIDxpbWcgaWQ9ImFqYXhTcGlubmVyIiBzcmM9IiR7YXBwUm9vdH0vcmVzL2ltZ3MvbG9hZGluZy5naWYiIHRpbGU9IldvcmtpbmcuLi4iIC8+CisgICAgPGJ1dHRvbiB0eXBlPSJidXR0b24iIGlkPSJleGVjdXRlQnV0dG9uIj4ke2NvbnNvbGUuZXhlY3V0ZX08L2J1dHRvbj4KKyAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgaWQ9ImxhbmdCdXR0b24iPiR7Y29uc29sZS5sYW5nfTwvYnV0dG9uPgorICAgIDxzZWxlY3QgaWQ9ImNvZGVMYW5nIj4KKyAgICAgICAgPG9wdGlvbj48L29wdGlvbj4KKyAgICA8L3NlbGVjdD4KKzwvZGl2PgorPGRpdiBpZD0ic3BsaXR0ZXIiID4KKyAgICA8ZGl2IGlkPSJjb2RlLWlucHV0Ij4KKyAgICAgICAgPGZvcm0gbWV0aG9kPSJwb3N0IiBhY3Rpb249IiR7cGx1Z2luUm9vdH0iIGlkPSJjb25zb2xlRm9ybSI+CisgICAgICAgICAgICA8dGV4dGFyZWEgaWQ9ImNvZGUiIG5hbWU9ImNvZGUiCisgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9IndpZHRoOiA5MCU7IGhlaWdodDogN2VtOyAiPjwvdGV4dGFyZWE+CisgICAgICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJjbGllbnQiIHZhbHVlPSJ3ZWJjb25zb2xlIiAvPgorICAgICAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0ibGFuZyIgdmFsdWU9IiIgLz4KKyAgICAgICAgPC9mb3JtPgorICAgIDwvZGl2PgorICAgIDxkaXYgaWQ9ImNvZGUtb3V0cHV0Ij4KKyAgICAgICAgPHRleHRhcmVhIGlkPSJyZXN1bHQiIHN0eWxlPSJ3aWR0aDogOTAlOyIgcmVhZG9ubHk9InllcyI+PC90ZXh0YXJlYT4KKyAgICA8L2Rpdj4KKzwvZGl2PgorCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvc2xpbmcvc2NyaXB0aW5nL2NvbnNvbGUvQ29uc29sZVRlc3RDbGllbnQuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9zbGluZy9zY3JpcHRpbmcvY29uc29sZS9Db25zb2xlVGVzdENsaWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzM2FhOTMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvc2xpbmcvc2NyaXB0aW5nL2NvbnNvbGUvQ29uc29sZVRlc3RDbGllbnQuamF2YQpAQCAtMCwwICsxLDQ2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5zbGluZy5zY3JpcHRpbmcuY29uc29sZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5lbnRpdHkubWltZS5NdWx0aXBhcnRFbnRpdHk7CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLmVudGl0eS5taW1lLmNvbnRlbnQuSW5wdXRTdHJlYW1Cb2R5OworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5lbnRpdHkubWltZS5jb250ZW50LlN0cmluZ0JvZHk7CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLmltcGwuY2xpZW50LkRlZmF1bHRIdHRwQ2xpZW50OworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcudGVzdGluZy50b29scy5odHRwLlJlcXVlc3RCdWlsZGVyOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcudGVzdGluZy50b29scy5odHRwLlJlcXVlc3RFeGVjdXRvcjsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworcHVibGljIGNsYXNzIENvbnNvbGVUZXN0Q2xpZW50IHsKKyAgICBwcml2YXRlIERlZmF1bHRIdHRwQ2xpZW50IGh0dHBDbGllbnQgPSBuZXcgRGVmYXVsdEh0dHBDbGllbnQoKTsKKyAgICBwcml2YXRlIFJlcXVlc3RFeGVjdXRvciBleGVjdXRvciA9IG5ldyBSZXF1ZXN0RXhlY3V0b3IoaHR0cENsaWVudCk7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZXNvdXJjZVJlc29sdmVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFJlcXVlc3RCdWlsZGVyIHJiID0gbmV3IFJlcXVlc3RCdWlsZGVyKCJodHRwOi8vbG9jYWxob3N0OjkwMDAiKTsKKworICAgICAgICBmaW5hbCBNdWx0aXBhcnRFbnRpdHkgZW50aXR5ID0gbmV3IE11bHRpcGFydEVudGl0eSgpOworICAgICAgICAvLyBBZGQgU2xpbmcgUE9TVCBvcHRpb25zCisgICAgICAgIGVudGl0eS5hZGRQYXJ0KCJsYW5nIiwgbmV3IFN0cmluZ0JvZHkoImVzcCIpKTsKKyAgICAgICAgZW50aXR5LmFkZFBhcnQoImNvZGUiLCBuZXcgSW5wdXRTdHJlYW1Cb2R5KGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgiL3Rlc3QuanMiKSwgInRlc3QuanMiKSk7CisgICAgICAgIGV4ZWN1dG9yLmV4ZWN1dGUoCisgICAgICAgICAgICAgICAgcmIuYnVpbGRQb3N0UmVxdWVzdCgiL3N5c3RlbS9jb25zb2xlL3NjcmlwdGNvbnNvbGUuanNvbiIpCisgICAgICAgICAgICAgICAgIC53aXRoRW50aXR5KGVudGl0eSkKKyAgICAgICAgICAgICAgICAgLndpdGhDcmVkZW50aWFscygiYWRtaW4iLCJhZG1pbiIpCisgICAgICAgICAgICApLmFzc2VydFN0YXR1cygyMDApOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0Lmdyb292eSBiL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0Lmdyb292eQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOGMwODFjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QuZ3Jvb3Z5CkBAIC0wLDAgKzEsMTAgQEAKK2ltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmFwaS5yZXNvdXJjZS5SZXNvdXJjZVJlc29sdmVyRmFjdG9yeQorCitkZWYgcmVzb3VyY2VSZXNvbHZlckZhY3RvcnkgPSBzbGluZy5nZXRTZXJ2aWNlKFJlc291cmNlUmVzb2x2ZXJGYWN0b3J5LmNsYXNzKTsKK2RlZiBhdXRoSW5mbyA9IFsKKyAgICAgICAgKFJlc291cmNlUmVzb2x2ZXJGYWN0b3J5LlVTRVIpOiJhZG1pbiIsCisgICAgICAgIChSZXNvdXJjZVJlc29sdmVyRmFjdG9yeS5QQVNTV09SRCk6ImFkbWluIiwKKyAgICAgICAgZm9vOiJiYXIiLAorXQorZGVmIHJlc291cmNlUmVzb2x2ZXIgPSByZXNvdXJjZVJlc29sdmVyRmFjdG9yeS5nZXRSZXNvdXJjZVJlc29sdmVyKGF1dGhJbmZvKQorYXNzZXJ0IHJlc291cmNlUmVzb2x2ZXIuZ2V0QXR0cmlidXRlKCJmb28iKSA9PSAiYmFyIgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0LmpzIGIvc3JjL3Rlc3QvcmVzb3VyY2VzL3Rlc3QuanMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmNiZGE3NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L3Jlc291cmNlcy90ZXN0LmpzCkBAIC0wLDAgKzEsMjQgQEAKKworZnVuY3Rpb24gQXNzZXJ0RXhjZXB0aW9uKG1lc3NhZ2UpIHsgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTsgfQorQXNzZXJ0RXhjZXB0aW9uLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHsKKyAgcmV0dXJuICdBc3NlcnRFeGNlcHRpb246ICcgKyB0aGlzLm1lc3NhZ2U7Cit9CisKK2Z1bmN0aW9uIGFzc2VydChleHAsIG1lc3NhZ2UpIHsKKyAgaWYgKCFleHApIHsKKyAgICB0aHJvdyBuZXcgQXNzZXJ0RXhjZXB0aW9uKG1lc3NhZ2UpOworICB9Cit9CisKKwordmFyIHJlc291cmNlUmVzb2x2ZXJGYWN0b3J5ID0gc2xpbmcuZ2V0U2VydmljZShQYWNrYWdlcy5vcmcuYXBhY2hlLnNsaW5nLmFwaS5yZXNvdXJjZS5SZXNvdXJjZVJlc29sdmVyRmFjdG9yeSk7Cit2YXIgYXV0aEluZm8gPSBuZXcgamF2YS51dGlsLkhhc2hNYXAoKQorYXV0aEluZm8ucHV0KCJ1c2VyLm5hbWUiLCJhZG1pbiIpCithdXRoSW5mby5wdXQoInVzZXIucGFzc3dvcmQiLG5ldyBqYXZhLmxhbmcuU3RyaW5nKCJhZG1pbiIpLnRvQ2hhckFycmF5KCkpCithdXRoSW5mby5wdXQoImZvbyIsImJhciIpCisKKworYXNzZXJ0KHJlc291cmNlUmVzb2x2ZXJGYWN0b3J5ICE9IG51bGwsICJGYWN0b3J5IGNhbm5vdCBiZSBudWxsIik7Cit2YXIgcmVzb3VyY2VSZXNvbHZlciA9IHJlc291cmNlUmVzb2x2ZXJGYWN0b3J5LmdldFJlc291cmNlUmVzb2x2ZXIoYXV0aEluZm8pCithc3NlcnQocmVzb3VyY2VSZXNvbHZlci5nZXRBdHRyaWJ1dGUoImZvbyIpID09ICJiYXIiLCAnT2JqZWN0IGlzIG51bGwnKTsKK291dC5wcmludGxuICgidGVzdCIpClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQo=