PCEtLQogICAgCiAgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKICAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAogICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgogICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKICAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCiAgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogICAgCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICAgIAogICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCgotLT4KPGh0bWw+CjxoZWFkPgo8dGl0bGU+U2VydmljZU1peCA0IENYRi1XUy1TRUNVUklUWS1PU0dpIEV4YW1wbGU8L3RpdGxlPgo8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+CnZhciB1cmxUb09wZW4gPSAiaHR0cDovL2xvY2FsaG9zdDo4MTgxL2N4Zi9IZWxsb1dvcmxkU2VjdXJpdHkiOyAvL2RlZmF1bHQgVVJMIHRvIG9wZW4KCmZ1bmN0aW9uIGdldEhUVFBPYmplY3QoKSB7CiAgdmFyIHhtbGh0dHAgPSBmYWxzZTsKCiAgLyogQ29tcGlsYXRpb24gY29uZGl0aW9ubmVsbGUgZCdJRSAqLwogIC8qIENoZWNrIGlmIHdlIGFyZSB1c2luZyBJRSAqLwogIC8qQGNjX29uCiAgQGlmIChAX2pzY3JpcHRfdmVyc2lvbiA+PSA1KQogICAgIHRyeSB7CiAgICAgICAgeG1saHR0cCA9IG5ldyBBY3RpdmVYT2JqZWN0KCJNc3htbDIuWE1MSFRUUCIpOwogICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgIHhtbGh0dHAgPSBuZXcgQWN0aXZlWE9iamVjdCgiTWljcm9zb2Z0LlhNTEhUVFAiKTsKICAgICAgICB9IGNhdGNoIChFKSB7CiAgICAgICAgICAgeG1saHR0cCA9IGZhbHNlOwogICAgICAgIH0KICAgICB9CiAgQGVsc2UKICAgICB4bWxodHRwID0gZmFsc2U7CiAgQGVuZCBAKi8KCiAgLyogb24gZXNzYWllIGRlIGNy6WVyIGwnb2JqZXQgc2kgY2Ugbidlc3QgcGFzIGTpauAgZmFpdCAqLwogIC8qIENyZWF0ZSB0aGUgeG1saHR0cCBvYmplY3QgaWYgaXQgaXMgbm90IHlldCBkZWZpbmVkICovCiAgaWYgKCF4bWxodHRwICYmIHR5cGVvZiBYTUxIdHRwUmVxdWVzdCAhPSAndW5kZWZpbmVkJykgewogICAgIHRyeSB7CiAgICAgICAgeG1saHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOwogICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICB4bWxodHRwID0gZmFsc2U7CiAgICAgfQogIH0KCiAgaWYgKHhtbGh0dHApIHsKICAgICAvKiBvbiBk6WZpbml0IGNlIHF1aSBkb2l0IHNlIHBhc3NlciBxdWFuZCBsYSBwYWdlIHLpcG9uZHJhICovCiAgICAgLyogRGVmaW5lIHRoZSBjYWxsYmFjayBmdW5jdGlvbiBmb3IgdGhlIHJlc3BvbnNlICovCiAgICAgeG1saHR0cC5vbnJlYWR5c3RhdGVjaGFuZ2U9ZnVuY3Rpb24oKSB7CiAgICAgICAgaWYgKHhtbGh0dHAucmVhZHlTdGF0ZSA9PSA0KSB7IC8qIDQgOiDpdGF0ICJjb21wbGV0ZSIgKi8KICAgICAgICAgICB2YXIgcmVzcG9uc2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicmVzcG9uc2UiKTsKICAgICAgICAgICB2YXIgcmVzcG9uc2VTdGF0dXMgPSAiIjsKICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgcmVzcG9uc2VTdGF0dXMgPSB4bWxodHRwLnN0YXR1cyArICIiOwogICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgIHJlc3BvbnNlU3RhdHVzID0gIkVSUk9SIFdISUxFIFJFVFJJRVZJTkcgU1RBVFVTOyBNQVlCRSBVTkFCTEUgVE8gQ09OTkVDVC4iOwogICAgICAgICAgIH0KICAgICAgICAgICByZXNwb25zZS52YWx1ZSA9ICJTVEFUVVM6ICIgKyByZXNwb25zZVN0YXR1cyArICJcbiIgKyB4bWxodHRwLnJlc3BvbnNlVGV4dDsKICAgICAgICB9CiAgICAgfQogIH0KICByZXR1cm4geG1saHR0cDsKfQoKZnVuY3Rpb24gc2VuZCgpIHsKICBpZiAoKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ1cmxUb09wZW4iKS52YWx1ZSAhPSB1cmxUb09wZW4pICYmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgidXJsVG9PcGVuIikudmFsdWUgIT0gIiIpKSB7CiAgICAvLyB1c2UgdXNlciBlbnRyeSBpZiBpdCBpcyBub3QgdGhlIGVtcHR5IHN0cmluZwogICAgdXJsVG9PcGVuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInVybFRvT3BlbiIpLnZhbHVlOwogIH0gIAogIHZhciB4bWxodHRwID0gZ2V0SFRUUE9iamVjdCgpOwogIGlmICgheG1saHR0cCkgewogICAgYWxlcnQoJ2NvdW5kIG5vdCBjcmVhdGUgWE1MSHR0cFJlcXVlc3Qgb2JqZWN0Jyk7CiAgICByZXR1cm47CiAgfQogIHZhciByZXF1ZXN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInJlcXVlc3QiKTsKICB2YXIgcmVzcG9uc2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicmVzcG9uc2UiKTsKICB0cnkgewogICAgbmV0c2NhcGUuc2VjdXJpdHkuUHJpdmlsZWdlTWFuYWdlci5lbmFibGVQcml2aWxlZ2UoIlVuaXZlcnNhbEJyb3dzZXJSZWFkIFVuaXZlcnNhbEJyb3dzZXJXcml0ZSIpOwogIH0gY2F0Y2ggKGUpIHsKICB9CiAgdHJ5IHsKICAgIHhtbGh0dHAub3BlbigiUE9TVCIsIHVybFRvT3BlbiwgdHJ1ZSk7CiAgfSBjYXRjaCAoZSkgewogICAgYWxlcnQoJ2Vycm9yIG9wZW5pbmcnKTsKICB9CiAgeG1saHR0cC5zZW5kKHJlcXVlc3QudmFsdWUpOwp9Cgo8L3NjcmlwdD4KPC9oZWFkPgoKPGJvZHk+Cgo8aDE+U2VydmljZU1peCA0IENYRi1XUy1TRUNVUklUWS1PU0dpIEV4YW1wbGU8L2gxPgoKPHA+V2VsY29tZSB0byB0aGUgQ1hGLVdTLVNFQ1VSSVRZLU9TR2kgZXhhbXBsZSBmb3IgU2VydmljZU1peCA0PC9wPgoKPHA+UGVyZm9ybSBhIFBPU1QgaW50byB0aGUgSFRUUCBiaW5kaW5nLiBUaGlzIHJlcXVpcmVzIEphdmFTY3JpcHQuPC9wPiAKPHA+VGFyZ2V0OiA8aW5wdXQgdHlwZT0idGV4dCIgc2l6ZT0iNTAiIGlkPSJ1cmxUb09wZW4iIHZhbHVlPSIiPjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij5kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgidXJsVG9PcGVuIikudmFsdWUgPSB1cmxUb09wZW47PC9zY3JpcHQ+LjwvcD4KICAKPHRhYmxlPgogIDx0cj4KICAgIDx0ZD4KICA8dGV4dGFyZWEgaWQ9InJlcXVlc3QiIHN0eWxlPSJ3aWR0aDo2MDBweDtoZWlnaHQ6NDAwcHgiPjw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+CiAgPHNvYXA6RW52ZWxvcGUgeG1sbnM6c29hcD0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvc29hcC9lbnZlbG9wZS8iPgogICAgPHNvYXA6SGVhZGVyPgogICAgICAgIDx3c3NlOlNlY3VyaXR5IHhtbG5zOndzc2U9Imh0dHA6Ly9kb2NzLm9hc2lzLW9wZW4ub3JnL3dzcy8yMDA0LzAxL29hc2lzLTIwMDQwMS13c3Mtd3NzZWN1cml0eS1zZWNleHQtMS4wLnhzZCI+CiAgICAgICAgICAgIDx3c3NlOlVzZXJuYW1lVG9rZW4gPgogICAgICAgICAgICAgICAgPHdzc2U6VXNlcm5hbWU+c214PC93c3NlOlVzZXJuYW1lPgogICAgICAgICAgICAgICAgPHdzc2U6UGFzc3dvcmQgVHlwZT0iaHR0cDovL2RvY3Mub2FzaXMtb3Blbi5vcmcvd3NzLzIwMDQvMDEvb2FzaXMtMjAwNDAxLXdzcy11c2VybmFtZS10b2tlbi1wcm9maWxlLTEuMCNQYXNzd29yZFRleHQiPnNteDwvd3NzZTpQYXNzd29yZD4KICAgICAgICAgICAgPC93c3NlOlVzZXJuYW1lVG9rZW4+CiAgICAgICAgPC93c3NlOlNlY3VyaXR5PgogICAgPC9zb2FwOkhlYWRlcj4KICAgIDxzb2FwOkJvZHk+CiAgICAgICAgPG5zMjpzYXlIaSB4bWxuczpuczI9Imh0dHA6Ly9jeGYuZXhhbXBsZXMuc2VydmljZW1peC5hcGFjaGUub3JnLyI+CiAgICAgICAgICAgIDxhcmcwPkpvaG4gRG9lPC9hcmcwPgogICAgICAgIDwvbnMyOnNheUhpPgogICAgPC9zb2FwOkJvZHk+Cjwvc29hcDpFbnZlbG9wZT4KCiAgPC90ZXh0YXJlYT4KICAgIDwvdGQ+CiAgICA8dGQ+CiAgPHRleHRhcmVhIGlkPSJyZXNwb25zZSIgc3R5bGU9IndpZHRoOjYwMHB4O2hlaWdodDo0MDBweCI+CiAgPC90ZXh0YXJlYT4KICAgIDwvdGQ+CiAgPC90cj4KICA8dHI+CiAgICA8dGQgY29sc3Bhbj0yPgogIDxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJTZW5kIiBvbkNsaWNrPSJzZW5kKCk7Ii8+CiAgICA8L3RkPgogIDwvdHI+CjwvdGFibGU+CjwvYm9keT4KPC9odG1sPgo=