ICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBZb3UgbWF5IGFtZW5kIGFuZCBkaXN0cmlidXRlIGFzIHlvdSBsaWtlLCBidXQgZG9uJ3QgcmVtb3ZlIHRoaXMgaGVhZGVyIQogKgogKiBFUFBsdXMgcHJvdmlkZXMgc2VydmVyLXNpZGUgZ2VuZXJhdGlvbiBvZiBFeGNlbCAyMDA3LzIwMTAgc3ByZWFkc2hlZXRzLgogKiBTZWUgaHR0cDovL3d3dy5jb2RlcGxleC5jb20vRVBQbHVzIGZvciBkZXRhaWxzLgogKgogKiBDb3B5cmlnaHQgKEMpIDIwMTEgIEphbiBL5GxsbWFuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgCiAqIFNlZSB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgY2FuIGJlIHZpZXdlZCBhdCBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL2xncGwtbGljZW5zZS5waHAKICogSWYgeW91IHVuZmFtaWxpYXIgd2l0aCB0aGlzIGxpY2Vuc2Ugb3IgaGF2ZSBxdWVzdGlvbnMgYWJvdXQgaXQsIGhlcmUgaXMgYW4gaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC1mYXEuaHRtbAogKgogKiBBbGwgY29kZSBhbmQgZXhlY3V0YWJsZXMgYXJlIHByb3ZpZGVkICJhcyBpcyIgd2l0aCBubyB3YXJyYW50eSBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKICogVGhlIGF1dGhvciBhY2NlcHRzIG5vIGxpYWJpbGl0eSBmb3IgYW55IGRhbWFnZSBvciBsb3NzIG9mIGJ1c2luZXNzIHRoYXQgdGhpcyBwcm9kdWN0IG1heSBjYXVzZS4KICoKICogQ29kZSBjaGFuZ2Ugbm90ZXM6CiAqIAogKiBBdXRob3IJCQkJCQkJQ2hhbmdlCQkJCQkJRGF0ZQogKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSmFuIEvkbGxtYW4JCSAgICBJbml0aWFsIFJlbGVhc2UJCSAgICAgICAgMjAxMS0xMS0wMgogKiBKYW4gS+RsbG1hbiAgICAgICAgICBUb3RhbCByZXdyaXRlICAgICAgICAgICAgICAgMjAxMC0wMy0wMQogKiBKYW4gS+RsbG1hbgkJICAgIExpY2Vuc2UgY2hhbmdlZCBHUEwtLT5MR1BMICAyMDExLTEyLTI3CiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp1c2luZyBTeXN0ZW07CnVzaW5nIFN5c3RlbS5YbWw7CnVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwp1c2luZyBTeXN0ZW0uSU87CnVzaW5nIFN5c3RlbS5Db25maWd1cmF0aW9uOwp1c2luZyBPZmZpY2VPcGVuWG1sLkRyYXdpbmc7CnVzaW5nIFN5c3RlbS5EaWFnbm9zdGljczsKdXNpbmcgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZy5FeGNlbC5GdW5jdGlvbnMuTG9naWNhbDsKdXNpbmcgT2ZmaWNlT3BlblhtbC5TdHlsZTsKdXNpbmcgU3lzdGVtLkdsb2JhbGl6YXRpb247CnVzaW5nIFN5c3RlbS5UZXh0Owp1c2luZyBTeXN0ZW0uU2VjdXJpdHk7CnVzaW5nIE9mZmljZU9wZW5YbWwuRHJhd2luZy5DaGFydDsKdXNpbmcgT2ZmaWNlT3BlblhtbC5TdHlsZS5YbWxBY2Nlc3M7CnVzaW5nIFN5c3RlbS5UZXh0LlJlZ3VsYXJFeHByZXNzaW9uczsKdXNpbmcgT2ZmaWNlT3BlblhtbC5EcmF3aW5nLlZtbDsKdXNpbmcgT2ZmaWNlT3BlblhtbC5UYWJsZTsKdXNpbmcgT2ZmaWNlT3BlblhtbC5EYXRhVmFsaWRhdGlvbjsKdXNpbmcgT2ZmaWNlT3BlblhtbC5UYWJsZS5QaXZvdFRhYmxlOwp1c2luZyBTeXN0ZW0uQ29tcG9uZW50TW9kZWw7CnVzaW5nIFN5c3RlbS5EcmF3aW5nOwp1c2luZyBPZmZpY2VPcGVuWG1sLkNvbmRpdGlvbmFsRm9ybWF0dGluZzsKdXNpbmcgT2ZmaWNlT3BlblhtbC5VdGlsczsKdXNpbmcgSW9uaWMuWmlwOwp1c2luZyBPZmZpY2VPcGVuWG1sLkZvcm11bGFQYXJzaW5nLkxleGljYWxBbmFseXNpczsKdXNpbmcgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZzsKdXNpbmcgT2ZmaWNlT3BlblhtbC5QYWNrYWdpbmcuSW9uaWMuWmlwOwpuYW1lc3BhY2UgT2ZmaWNlT3BlblhtbAp7CiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gV29ya3NoZWV0IGhpZGRlbiBlbnVtZXJhdGlvbgogICAgLy8vIDwvc3VtbWFyeT4KICAgIHB1YmxpYyBlbnVtIGVXb3JrU2hlZXRIaWRkZW4KICAgIHsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSB3b3Jrc2hlZXQgaXMgdmlzaWJsZQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgVmlzaWJsZSwKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSB3b3Jrc2hlZXQgaXMgaGlkZGVuIGJ1dCBjYW4gYmUgc2hvd24gYnkgdGhlIHVzZXIgdmlhIHRoZSB1c2VyIGludGVyZmFjZQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgSGlkZGVuLAogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVGhlIHdvcmtzaGVldCBpcyBoaWRkZW4gYW5kIGNhbm5vdCBiZSBzaG93biBieSB0aGUgdXNlciB2aWEgdGhlIHVzZXIgaW50ZXJmYWNlCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBWZXJ5SGlkZGVuCiAgICB9CiAgICBbRmxhZ3NdCiAgICBpbnRlcm5hbCBlbnVtIENlbGxGbGFncwogICAgewogICAgICAgIC8vTWVyZ2VkID0gMHgxLAogICAgICAgIFJpY2hUZXh0ID0gMHgyLAogICAgICAgIFNoYXJlZEZvcm11bGEgPSAweDQsCiAgICAgICAgQXJyYXlGb3JtdWxhID0gMHg4CiAgICB9CiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gUmVwcmVzZW50cyBhbiBFeGNlbCBDaGFydHNoZWV0IGFuZCBwcm92aWRlcyBhY2Nlc3MgdG8gaXRzIHByb3BlcnRpZXMgYW5kIG1ldGhvZHMKICAgIC8vLyA8L3N1bW1hcnk+CiAgICBwdWJsaWMgY2xhc3MgRXhjZWxDaGFydHNoZWV0IDogRXhjZWxXb3Jrc2hlZXQKICAgIHsKICAgICAgICAvL0V4Y2VsRHJhd2luZ3MgZHJhd3M7CiAgICAgICAgcHVibGljIEV4Y2VsQ2hhcnRzaGVldChYbWxOYW1lc3BhY2VNYW5hZ2VyIG5zLCBFeGNlbFBhY2thZ2UgcGNrLCBzdHJpbmcgcmVsSUQsIFVyaSB1cmlXb3Jrc2hlZXQsIHN0cmluZyBzaGVldE5hbWUsIGludCBzaGVldElELCBpbnQgcG9zaXRpb25JRCwgZVdvcmtTaGVldEhpZGRlbiBoaWRkZW4sIGVDaGFydFR5cGUgY2hhcnRUeXBlKSA6CiAgICAgICAgICAgIGJhc2UobnMsIHBjaywgcmVsSUQsIHVyaVdvcmtzaGVldCwgc2hlZXROYW1lLCBzaGVldElELCBwb3NpdGlvbklELCBoaWRkZW4pCiAgICAgICAgewogICAgICAgICAgICB0aGlzLkRyYXdpbmdzLkFkZENoYXJ0KCJDaGFydCAxIiwgY2hhcnRUeXBlKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIEV4Y2VsQ2hhcnRzaGVldChYbWxOYW1lc3BhY2VNYW5hZ2VyIG5zLCBFeGNlbFBhY2thZ2UgcGNrLCBzdHJpbmcgcmVsSUQsIFVyaSB1cmlXb3Jrc2hlZXQsIHN0cmluZyBzaGVldE5hbWUsIGludCBzaGVldElELCBpbnQgcG9zaXRpb25JRCwgZVdvcmtTaGVldEhpZGRlbiBoaWRkZW4pIDoKICAgICAgICAgICAgYmFzZShucywgcGNrLCByZWxJRCwgdXJpV29ya3NoZWV0LCBzaGVldE5hbWUsIHNoZWV0SUQsIHBvc2l0aW9uSUQsIGhpZGRlbikKICAgICAgICB7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBFeGNlbENoYXJ0IENoYXJ0IAogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAoRXhjZWxDaGFydClEcmF3aW5nc1swXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIC8vLyA8c3VtbWFyeT4KCS8vLyBSZXByZXNlbnRzIGFuIEV4Y2VsIHdvcmtzaGVldCBhbmQgcHJvdmlkZXMgYWNjZXNzIHRvIGl0cyBwcm9wZXJ0aWVzIGFuZCBtZXRob2RzCgkvLy8gPC9zdW1tYXJ5PgogICAgcHVibGljIGNsYXNzIEV4Y2VsV29ya3NoZWV0IDogWG1sSGVscGVyLCBJRXF1YWxpdHlDb21wYXJlcjxFeGNlbFdvcmtzaGVldD4sIElEaXNwb3NhYmxlCgl7CiAgICAgICAgaW50ZXJuYWwgY2xhc3MgRm9ybXVsYXMKICAgICAgICB7CiAgICAgICAgICAgIHB1YmxpYyBGb3JtdWxhcyhJU291cmNlQ29kZVRva2VuaXplciB0b2tlbml6ZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF90b2tlbml6ZXIgPSB0b2tlbml6ZXI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyBzdGF0aWMgc3RyaW5nIFJlbW92ZUR1bW15RnVuY3Rpb24oc3RyaW5nIGZvcm11bGEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyBEdW1teUZ1bmN0aW9uUHJlZml4ID0gIklGRVJST1IoX194bHVkZi5EVU1NWUZVTkNUSU9OKFwiIjsKICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyBEdW1teUZ1bmN0aW9uU3VmZml4ID0gIlwiKSxcIiI7CgogICAgICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGZvcm11bGEpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmb3JtdWxhOwoKICAgICAgICAgICAgICAgIC8vIExvb2sgZm9yIFByZWZpeAogICAgICAgICAgICAgICAgaWYgKCFmb3JtdWxhLlN0YXJ0c1dpdGgoRHVtbXlGdW5jdGlvblByZWZpeCkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZvcm11bGE7CgogICAgICAgICAgICAgICAgLy8gTG9vayBmb3IgU3VmZml4CiAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSBmb3JtdWxhLkxhc3RJbmRleE9mKER1bW15RnVuY3Rpb25TdWZmaXgpOwogICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgMCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZm9ybXVsYTsKCiAgICAgICAgICAgICAgICAvLyBUcmltIFN1ZmZpeAogICAgICAgICAgICAgICAgZm9ybXVsYSA9IGZvcm11bGEuU3Vic3RyaW5nKDAsIGluZGV4KTsKCiAgICAgICAgICAgICAgICAvLyBUcmltIFByZWZpeAogICAgICAgICAgICAgICAgZm9ybXVsYSA9IGZvcm11bGEuUmVwbGFjZShEdW1teUZ1bmN0aW9uUHJlZml4LCAiIik7CgogICAgICAgICAgICAgICAgLy8gUmVwbGFjZSBkb3VibGVkIHF1b3RlcyB3aXRoIHNpbmdsZSBxdW90ZQogICAgICAgICAgICAgICAgZm9ybXVsYSA9IGZvcm11bGEuUmVwbGFjZSgiXCJcIiIsICJcIiIpOwoKICAgICAgICAgICAgICAgIC8vIFJldHVybiBmb3JtdWxhCiAgICAgICAgICAgICAgICByZXR1cm4gZm9ybXVsYTsKICAgICAgICAgICAgfQoJCQkKICAgICAgICAgICBwcml2YXRlIElTb3VyY2VDb2RlVG9rZW5pemVyIF90b2tlbml6ZXI7CiAgICAgICAgICAgIGludGVybmFsIGludCBJbmRleCB7IGdldDsgc2V0OyB9CiAgICAgICAgICAgIGludGVybmFsIHN0cmluZyBBZGRyZXNzIHsgZ2V0OyBzZXQ7IH0KICAgICAgICAgICAgaW50ZXJuYWwgYm9vbCBJc0FycmF5IHsgZ2V0OyBzZXQ7IH0KICAgICAgICAgICAgcHVibGljIHN0cmluZyBGb3JtdWxhIHsgZ2V0OyBzZXQ7IH0KICAgICAgICAgICAgcHVibGljIGludCBTdGFydFJvdyB7IGdldDsgc2V0OyB9CiAgICAgICAgICAgIHB1YmxpYyBpbnQgU3RhcnRDb2wgeyBnZXQ7IHNldDsgfQoKICAgICAgICAgICAgcHJpdmF0ZSBJRW51bWVyYWJsZTxUb2tlbj4gVG9rZW5zIHtnZXQ7IHNldDt9CiAgICAgICAgICAgCgogICAgICAgICAgICBpbnRlcm5hbCBzdHJpbmcgR2V0Rm9ybXVsYShpbnQgcm93LCBpbnQgY29sdW1uLCBzdHJpbmcgd29ya3NoZWV0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoKFN0YXJ0Um93ID09IHJvdyAmJiBTdGFydENvbCA9PSBjb2x1bW4pIHx8IElzQXJyYXkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFJlbW92ZUR1bW15RnVuY3Rpb24oRm9ybXVsYSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKFRva2VucyA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRva2VucyA9IF90b2tlbml6ZXIuVG9rZW5pemUoUmVtb3ZlRHVtbXlGdW5jdGlvbihGb3JtdWxhKSwgd29ya3NoZWV0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgc3RyaW5nIGYgPSAiIjsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0b2tlbiBpbiBUb2tlbnMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRva2VuLlRva2VuVHlwZSA9PSBUb2tlblR5cGUuRXhjZWxBZGRyZXNzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGEgPSBuZXcgRXhjZWxGb3JtdWxhQWRkcmVzcyh0b2tlbi5WYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGYgKz0gYS5HZXRPZmZzZXQocm93IC0gU3RhcnRSb3csIGNvbHVtbiAtIFN0YXJ0Q29sKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZiArPSB0b2tlbi5WYWx1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIENvbGxlY3Rpb24gY29udGFpbmluZyBtZXJnZWQgY2VsbCBhZGRyZXNzZXMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBjbGFzcyBNZXJnZUNlbGxzQ29sbGVjdGlvbiA6IElFbnVtZXJhYmxlPHN0cmluZz4KICAgICAgICB7CiAgICAgICAgICAgIGludGVybmFsIE1lcmdlQ2VsbHNDb2xsZWN0aW9uKCkKICAgICAgICAgICAgewoKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnRlcm5hbCBDZWxsU3RvcmU8aW50PiBfY2VsbHMgPSBuZXcgQ2VsbFN0b3JlPGludD4oKTsKICAgICAgICAgICAgTGlzdDxzdHJpbmc+IF9saXN0ID0gbmV3IExpc3Q8c3RyaW5nPigpOwogICAgICAgICAgICBpbnRlcm5hbCBMaXN0PHN0cmluZz4gTGlzdCB7IGdldCB7cmV0dXJuIF9saXN0O30gfQogICAgICAgICAgICBwdWJsaWMgc3RyaW5nIHRoaXNbaW50IHJvdywgaW50IGNvbHVtbl0KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaW50IGl4PS0xOwogICAgICAgICAgICAgICAgICAgIGlmIChfY2VsbHMuRXhpc3RzKHJvdywgY29sdW1uLCByZWYgaXgpICYmIGl4ID49IDAgJiYgaXggPCBMaXN0LkNvdW50KSAgLy9GaXhlcyBpc3N1ZSAxNTA3NQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIExpc3RbaXhdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHVibGljIHN0cmluZyB0aGlzW2ludCBpbmRleF0KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9saXN0W2luZGV4XTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpbnRlcm5hbCB2b2lkIEFkZChFeGNlbEFkZHJlc3NCYXNlIGFkZHJlc3MsIGJvb2wgZG9WYWxpZGF0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IGl4PTA7CgogICAgICAgICAgICAgICAgLy9WYWxpZGF0ZQogICAgICAgICAgICAgICAgaWYgKGRvVmFsaWRhdGUgJiYgVmFsaWRhdGUoYWRkcmVzcykgPT0gZmFsc2UpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cobmV3IEFyZ3VtZW50RXhjZXB0aW9uKCJDYW4ndCBtZXJnZSBhbmQgYWxyZWFkeSBtZXJnZWQgcmFuZ2UiKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsb2NrKHRoaXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaXggPSBfbGlzdC5Db3VudDsKICAgICAgICAgICAgICAgICAgICBfbGlzdC5BZGQoYWRkcmVzcy5BZGRyZXNzKTsKICAgICAgICAgICAgICAgICAgICBTZXRJbmRleChhZGRyZXNzLCBpeCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgYm9vbCBWYWxpZGF0ZShFeGNlbEFkZHJlc3NCYXNlIGFkZHJlc3MpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCBpeD0wOwogICAgICAgICAgICAgICAgaWYoX2NlbGxzLkV4aXN0cyhhZGRyZXNzLl9mcm9tUm93LCBhZGRyZXNzLl9mcm9tQ29sLCByZWYgaXgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChpeD49MCAmJiBpeCA8IF9saXN0LkNvdW50ICYmIF9saXN0W2l4XSE9bnVsbCAmJiBhZGRyZXNzLkFkZHJlc3MgPT0gX2xpc3RbaXhdKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8aW50PihfY2VsbHMsIGFkZHJlc3MuX2Zyb21Sb3csIGFkZHJlc3MuX2Zyb21Db2wsIGFkZHJlc3MuX3RvUm93LCBhZGRyZXNzLl90b0NvbCk7CiAgICAgICAgICAgICAgICAvL2NlbGxzCiAgICAgICAgICAgICAgICB3aGlsZShjc2UuTmV4dCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vRW50aXJlIGNvbHVtbgogICAgICAgICAgICAgICAgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPGludD4oX2NlbGxzLCAwLCBhZGRyZXNzLl9mcm9tQ29sLCAwLCBhZGRyZXNzLl90b0NvbCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoY3NlLk5leHQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL0VudGlyZSByb3cKICAgICAgICAgICAgICAgIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxpbnQ+KF9jZWxscywgYWRkcmVzcy5fZnJvbVJvdywgMCwgYWRkcmVzcy5fdG9Sb3csIDApOwogICAgICAgICAgICAgICAgd2hpbGUgKGNzZS5OZXh0KCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGludGVybmFsIHZvaWQgU2V0SW5kZXgoRXhjZWxBZGRyZXNzQmFzZSBhZGRyZXNzLCBpbnQgaXgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChhZGRyZXNzLl9mcm9tUm93ID09IDEgJiYgYWRkcmVzcy5fdG9Sb3cgPT0gRXhjZWxQYWNrYWdlLk1heFJvd3MpIC8vRW50aXJlIHJvdwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGNvbCA9IGFkZHJlc3MuX2Zyb21Db2w7IGNvbCA8PSBhZGRyZXNzLl90b0NvbDsgY29sKyspCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfY2VsbHMuU2V0VmFsdWUoMCwgY29sLCBpeCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoYWRkcmVzcy5fZnJvbUNvbCA9PSAxICYmIGFkZHJlc3MuX3RvQ29sID09IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKSAvL0VudGlyZSByb3cKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKGludCByb3cgPSBhZGRyZXNzLl9mcm9tUm93OyByb3cgPD0gYWRkcmVzcy5fdG9Sb3c7IHJvdysrKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX2NlbGxzLlNldFZhbHVlKHJvdywgMCwgaXgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBjb2wgPSBhZGRyZXNzLl9mcm9tQ29sOyBjb2wgPD0gYWRkcmVzcy5fdG9Db2w7IGNvbCsrKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgcm93ID0gYWRkcmVzcy5fZnJvbVJvdzsgcm93IDw9IGFkZHJlc3MuX3RvUm93OyByb3crKykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NlbGxzLlNldFZhbHVlKHJvdywgY29sLCBpeCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHVibGljIGludCBDb3VudAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBnZXQKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2xpc3QuQ291bnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50ZXJuYWwgdm9pZCBSZW1vdmUoc3RyaW5nIEl0ZW0pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF9saXN0LlJlbW92ZShJdGVtKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAjcmVnaW9uIElFbnVtZXJhYmxlPHN0cmluZz4gTWVtYmVycwoKICAgICAgICAgICAgcHVibGljIElFbnVtZXJhdG9yPHN0cmluZz4gR2V0RW51bWVyYXRvcigpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBfbGlzdC5HZXRFbnVtZXJhdG9yKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICNlbmRyZWdpb24KCiAgICAgICAgICAgICNyZWdpb24gSUVudW1lcmFibGUgTWVtYmVycwoKICAgICAgICAgICAgU3lzdGVtLkNvbGxlY3Rpb25zLklFbnVtZXJhdG9yIFN5c3RlbS5Db2xsZWN0aW9ucy5JRW51bWVyYWJsZS5HZXRFbnVtZXJhdG9yKCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIF9saXN0LkdldEVudW1lcmF0b3IoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgI2VuZHJlZ2lvbgogICAgICAgICAgICBpbnRlcm5hbCB2b2lkIENsZWFyKEV4Y2VsQWRkcmVzc0Jhc2UgRGVzdGluYXRpb24pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8aW50PihfY2VsbHMsIERlc3RpbmF0aW9uLl9mcm9tUm93LCBEZXN0aW5hdGlvbi5fZnJvbUNvbCwgRGVzdGluYXRpb24uX3RvUm93LCBEZXN0aW5hdGlvbi5fdG9Db2wpOwogICAgICAgICAgICAgICAgdmFyIHVzZWQ9bmV3IEhhc2hTZXQ8aW50PigpOwogICAgICAgICAgICAgICAgd2hpbGUoY3NlLk5leHQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdj1jc2UuVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKCF1c2VkLkNvbnRhaW5zKHYpICYmIF9saXN0W3ZdIT1udWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFkcj1uZXcgRXhjZWxBZGRyZXNzQmFzZShfbGlzdFt2XSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKERlc3RpbmF0aW9uLkNvbGxpZGUoYWRyKSA9PSBFeGNlbEFkZHJlc3NCYXNlLmVBZGRyZXNzQ29sbGl0aW9uLkluc2lkZSB8fCBEZXN0aW5hdGlvbi5Db2xsaWRlKGFkcik9PUV4Y2VsQWRkcmVzc0Jhc2UuZUFkZHJlc3NDb2xsaXRpb24uRXF1YWwpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyhuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbihzdHJpbmcuRm9ybWF0KCJDYW4ndCBkZWxldGUgbWVyZ2VkIGNlbGxzLiBBIHJhbmdlIGlzIHBhcnRseSBtZXJnZWQgd2l0aCB0aGUgZGVsZXRlZCByYW5nZS4gezB9IiwgYWRyLl9hZGRyZXNzKSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHVzZWQuQWRkKHYpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBfY2VsbHMuQ2xlYXIoRGVzdGluYXRpb24uX2Zyb21Sb3csIERlc3RpbmF0aW9uLl9mcm9tQ29sLCBEZXN0aW5hdGlvbi5fdG9Sb3cgLSBEZXN0aW5hdGlvbi5fZnJvbVJvdyArIDEsIERlc3RpbmF0aW9uLl90b0NvbCAtIERlc3RpbmF0aW9uLl9mcm9tQ29sICsgMSk7CiAgICAgICAgICAgICAgICBmb3JlYWNoKHZhciBpIGluIHVzZWQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX2xpc3RbaV0gPSBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIENlbGxTdG9yZTxvYmplY3Q+IF92YWx1ZXM7CiAgICAgICAgaW50ZXJuYWwgQ2VsbFN0b3JlPHN0cmluZz4gX3R5cGVzOwogICAgICAgIGludGVybmFsIENlbGxTdG9yZTxpbnQ+IF9zdHlsZXM7CiAgICAgICAgaW50ZXJuYWwgQ2VsbFN0b3JlPG9iamVjdD4gX2Zvcm11bGFzOwogICAgICAgIGludGVybmFsIEZsYWdDZWxsU3RvcmUgX2ZsYWdzOwogICAgICAgIGludGVybmFsIENlbGxTdG9yZTxMaXN0PFRva2VuPj4gX2Zvcm11bGFUb2tlbnM7CgogICAgICAgIGludGVybmFsIENlbGxTdG9yZTxVcmk+IF9oeXBlckxpbmtzOwogICAgICAgIGludGVybmFsIENlbGxTdG9yZTxFeGNlbENvbW1lbnQ+IF9jb21tZW50c1N0b3JlOwoKICAgICAgICBpbnRlcm5hbCBEaWN0aW9uYXJ5PGludCwgRm9ybXVsYXM+IF9zaGFyZWRGb3JtdWxhcyA9IG5ldyBEaWN0aW9uYXJ5PGludCwgRm9ybXVsYXM+KCk7CiAgICAgICAgaW50ZXJuYWwgaW50IF9taW5Db2wgPSBFeGNlbFBhY2thZ2UuTWF4Q29sdW1uczsKICAgICAgICBpbnRlcm5hbCBpbnQgX21heENvbCA9IDA7CiAgICAgICAgI3JlZ2lvbiBXb3Jrc2hlZXQgUHJpdmF0ZSBQcm9wZXJ0aWVzCiAgICAgICAgaW50ZXJuYWwgRXhjZWxQYWNrYWdlIF9wYWNrYWdlOwoJCXByaXZhdGUgVXJpIF93b3Jrc2hlZXRVcmk7CgkJcHJpdmF0ZSBzdHJpbmcgX25hbWU7CgkJcHJpdmF0ZSBpbnQgX3NoZWV0SUQ7CiAgICAgICAgcHJpdmF0ZSBpbnQgX3Bvc2l0aW9uSUQ7CgkJcHJpdmF0ZSBzdHJpbmcgX3JlbGF0aW9uc2hpcElEOwoJCXByaXZhdGUgWG1sRG9jdW1lbnQgX3dvcmtzaGVldFhtbDsKICAgICAgICBpbnRlcm5hbCBFeGNlbFdvcmtzaGVldFZpZXcgX3NoZWV0VmlldzsKCQlpbnRlcm5hbCBFeGNlbEhlYWRlckZvb3RlciBfaGVhZGVyRm9vdGVyOwogICAgICAgICNlbmRyZWdpb24KICAgICAgICAjcmVnaW9uIEV4Y2VsV29ya3NoZWV0IENvbnN0cnVjdG9yCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBBIHdvcmtzaGVldAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJucyI+TmFtZXNwYWNlbWFuYWdlcjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJleGNlbFBhY2thZ2UiPlBhY2thZ2U8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icmVsSUQiPlJlbGF0aW9uc2hpcCBJRDwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJ1cmlXb3Jrc2hlZXQiPlVSSTwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzaGVldE5hbWUiPk5hbWUgb2YgdGhlIHNoZWV0PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNoZWV0SUQiPlNoZWV0IGlkPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InBvc2l0aW9uSUQiPlBvc2l0aW9uPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImhpZGUiPmhpZGU8L3BhcmFtPgogICAgICAgIHB1YmxpYyBFeGNlbFdvcmtzaGVldChYbWxOYW1lc3BhY2VNYW5hZ2VyIG5zLCBFeGNlbFBhY2thZ2UgZXhjZWxQYWNrYWdlLCBzdHJpbmcgcmVsSUQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVcmkgdXJpV29ya3NoZWV0LCBzdHJpbmcgc2hlZXROYW1lLCBpbnQgc2hlZXRJRCwgaW50IHBvc2l0aW9uSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVXb3JrU2hlZXRIaWRkZW4gaGlkZSkgOgogICAgICAgICAgICBiYXNlKG5zLCBudWxsKQogICAgICAgIHsKICAgICAgICAgICAgU2NoZW1hTm9kZU9yZGVyID0gbmV3IHN0cmluZ1tdIHsgInNoZWV0UHIiLCAidGFiQ29sb3IiLCAib3V0bGluZVByIiwgInBhZ2VTZXRVcFByIiwgImRpbWVuc2lvbiIsICJzaGVldFZpZXdzIiwgInNoZWV0Rm9ybWF0UHIiLCAiY29scyIsICJzaGVldERhdGEiLCAic2hlZXRQcm90ZWN0aW9uIiwgInByb3RlY3RlZFJhbmdlcyIsInNjZW5hcmlvcyIsICJhdXRvRmlsdGVyIiwgInNvcnRTdGF0ZSIsICJkYXRhQ29uc29saWRhdGUiLCAiY3VzdG9tU2hlZXRWaWV3cyIsICJjdXN0b21TaGVldFZpZXdzIiwgIm1lcmdlQ2VsbHMiLCAicGhvbmV0aWNQciIsICJjb25kaXRpb25hbEZvcm1hdHRpbmciLCAiZGF0YVZhbGlkYXRpb25zIiwgImh5cGVybGlua3MiLCAicHJpbnRPcHRpb25zIiwgInBhZ2VNYXJnaW5zIiwgInBhZ2VTZXR1cCIsICJoZWFkZXJGb290ZXIiLCAibGluZVByaW50IiwgInJvd0JyZWFrcyIsICJjb2xCcmVha3MiLCAiY3VzdG9tUHJvcGVydGllcyIsICJjZWxsV2F0Y2hlcyIsICJpZ25vcmVkRXJyb3JzIiwgInNtYXJ0VGFncyIsICJkcmF3aW5nIiwgImxlZ2FjeURyYXdpbmciLCAibGVnYWN5RHJhd2luZ0hGIiwgInBpY3R1cmUiLCAib2xlT2JqZWN0cyIsICJhY3RpdmVYQ29udHJvbHMiLCAid2ViUHVibGlzaEl0ZW1zIiwgInRhYmxlUGFydHMiICwgImV4dExzdCIgfTsKICAgICAgICAgICAgX3BhY2thZ2UgPSBleGNlbFBhY2thZ2U7ICAgCiAgICAgICAgICAgIF9yZWxhdGlvbnNoaXBJRCA9IHJlbElEOwogICAgICAgICAgICBfd29ya3NoZWV0VXJpID0gdXJpV29ya3NoZWV0OwogICAgICAgICAgICBfbmFtZSA9IHNoZWV0TmFtZTsKICAgICAgICAgICAgX3NoZWV0SUQgPSBzaGVldElEOwogICAgICAgICAgICBfcG9zaXRpb25JRCA9IHBvc2l0aW9uSUQ7CiAgICAgICAgICAgIEhpZGRlbiA9IGhpZGU7CiAgICAgICAgICAgCiAgICAgICAgICAgIC8qKioqIENlbGxzdG9yZSAqKioqLwogICAgICAgICAgICBfdmFsdWVzPW5ldyBDZWxsU3RvcmU8b2JqZWN0PigpOwogICAgICAgICAgICBfdHlwZXMgPSBuZXcgQ2VsbFN0b3JlPHN0cmluZz4oKTsKICAgICAgICAgICAgX3N0eWxlcyA9IG5ldyBDZWxsU3RvcmU8aW50PigpOwogICAgICAgICAgICBfZm9ybXVsYXMgPSBuZXcgQ2VsbFN0b3JlPG9iamVjdD4oKTsKICAgICAgICAgICAgX2ZsYWdzID0gbmV3IEZsYWdDZWxsU3RvcmUoKTsKICAgICAgICAgICAgX2NvbW1lbnRzU3RvcmUgPSBuZXcgQ2VsbFN0b3JlPEV4Y2VsQ29tbWVudD4oKTsKICAgICAgICAgICAgX2h5cGVyTGlua3MgPSBuZXcgQ2VsbFN0b3JlPFVyaT4oKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIF9uYW1lcyA9IG5ldyBFeGNlbE5hbWVkUmFuZ2VDb2xsZWN0aW9uKFdvcmtib29rLHRoaXMpOwoKICAgICAgICAgICAgQ3JlYXRlWG1sKCk7CiAgICAgICAgICAgIFRvcE5vZGUgPSBfd29ya3NoZWV0WG1sLkRvY3VtZW50RWxlbWVudDsKICAgICAgICB9CgogICAgICAgICNlbmRyZWdpb24KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBVcmkgdG8gdGhlIHdvcmtzaGVldCB3aXRoaW4gdGhlIHBhY2thZ2UKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIGludGVybmFsIFVyaSBXb3Jrc2hlZXRVcmkgeyBnZXQgeyByZXR1cm4gKF93b3Jrc2hlZXRVcmkpOyB9IH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBaaXAuWmlwUGFja2FnZVBhcnQgZm9yIHRoZSB3b3Jrc2hlZXQgd2l0aGluIHRoZSBwYWNrYWdlCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBpbnRlcm5hbCBQYWNrYWdpbmcuWmlwUGFja2FnZVBhcnQgUGFydCB7IGdldCB7IHJldHVybiAoX3BhY2thZ2UuUGFja2FnZS5HZXRQYXJ0KFdvcmtzaGVldFVyaSkpOyB9IH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBJRCBmb3IgdGhlIHdvcmtzaGVldCdzIHJlbGF0aW9uc2hpcCB3aXRoIHRoZSB3b3JrYm9vayBpbiB0aGUgcGFja2FnZQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgaW50ZXJuYWwgc3RyaW5nIFJlbGF0aW9uc2hpcElEIHsgZ2V0IHsgcmV0dXJuIChfcmVsYXRpb25zaGlwSUQpOyB9IH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIHdvcmtzaGVldC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIGludGVybmFsIGludCBTaGVldElEIHsgZ2V0IHsgcmV0dXJuIChfc2hlZXRJRCk7IH0gfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVGhlIHBvc2l0aW9uIG9mIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBpbnRlcm5hbCBpbnQgUG9zaXRpb25JRCB7IGdldCB7IHJldHVybiAoX3Bvc2l0aW9uSUQpOyB9IHNldCB7IF9wb3NpdGlvbklEID0gdmFsdWU7IH0gfQoJCSNyZWdpb24gV29ya3NoZWV0IFB1YmxpYyBQcm9wZXJ0aWVzCiAgICAJLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgaW5kZXggaW4gdGhlIHdvcmtzaGVldHMgY29sbGVjdGlvbgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIGludCBJbmRleCB7IGdldCB7IHJldHVybiAoX3Bvc2l0aW9uSUQpOyB9IH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEFkZHJlc3MgZm9yIGF1dG9maWx0ZXIKICAgICAgICAvLy8gPHNlZWFsc28gY3JlZj0iRXhjZWxSYW5nZUJhc2UuQXV0b0ZpbHRlciIgLz4gICAgICAgIAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsQWRkcmVzc0Jhc2UgQXV0b0ZpbHRlckFkZHJlc3MKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgc3RyaW5nIGFkZHJlc3MgPSBHZXRYbWxOb2RlU3RyaW5nKCJkOmF1dG9GaWx0ZXIvQHJlZiIpOwogICAgICAgICAgICAgICAgaWYgKGFkZHJlc3MgPT0gIiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBFeGNlbEFkZHJlc3NCYXNlKGFkZHJlc3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGludGVybmFsIHNldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiZDphdXRvRmlsdGVyL0ByZWYiLCB2YWx1ZS5BZGRyZXNzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50ZXJuYWwgdm9pZCBDaGVja1NoZWV0VHlwZSgpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcyBpcyBFeGNlbENoYXJ0c2hlZXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IChuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJUaGlzIHByb3BlcnR5IG9yIG1ldGhvZCBpcyBub3Qgc3VwcG9ydGVkIGZvciBhIENoYXJ0c2hlZXQiKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gUmV0dXJucyBhIEV4Y2VsV29ya3NoZWV0VmlldyBvYmplY3QgdGhhdCBhbGxvd3MgeW91IHRvIHNldCB0aGUgdmlldyBzdGF0ZSBwcm9wZXJ0aWVzIG9mIHRoZSB3b3Jrc2hlZXQKCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBFeGNlbFdvcmtzaGVldFZpZXcgVmlldwoJCXsKCQkJZ2V0CgkJCXsKCQkJCWlmIChfc2hlZXRWaWV3ID09IG51bGwpCgkJCQl7CiAgICAgICAgICAgICAgICAgICAgWG1sTm9kZSBub2RlID0gVG9wTm9kZS5TZWxlY3RTaW5nbGVOb2RlKCJkOnNoZWV0Vmlld3MvZDpzaGVldFZpZXciLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgQ3JlYXRlTm9kZSgiZDpzaGVldFZpZXdzL2Q6c2hlZXRWaWV3Iik7IC8vdGhpcyBvbmUgc2hvdWxzIGFsd2F5cyBleGlzdC4gYnV0IGNoZWNrIGFueXdheQogICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gVG9wTm9kZS5TZWxlY3RTaW5nbGVOb2RlKCJkOnNoZWV0Vmlld3MvZDpzaGVldFZpZXciLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgX3NoZWV0VmlldyA9IG5ldyBFeGNlbFdvcmtzaGVldFZpZXcoTmFtZVNwYWNlTWFuYWdlciwgbm9kZSwgdGhpcyk7CgkJCQl9CgkJCQlyZXR1cm4gKF9zaGVldFZpZXcpOwoJCQl9CgkJfQoKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFRoZSB3b3Jrc2hlZXQncyBkaXNwbGF5IG5hbWUgYXMgaXQgYXBwZWFycyBvbiB0aGUgdGFiCgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgc3RyaW5nIE5hbWUKCQl7CgkJCWdldCB7IHJldHVybiAoX25hbWUpOyB9CgkJCXNldAoJCQl7CiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gX25hbWUpIHJldHVybjsKICAgICAgICAgICAgICAgIHZhbHVlPV9wYWNrYWdlLldvcmtib29rLldvcmtzaGVldHMuVmFsaWRhdGVGaXhTaGVldE5hbWUodmFsdWUpOwogICAgICAgICAgICAgICAgZm9yZWFjaCh2YXIgd3MgaW4gV29ya2Jvb2suV29ya3NoZWV0cykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZih3cy5Qb3NpdGlvbklEIT1Qb3NpdGlvbklEICYmIHdzLk5hbWUuRXF1YWxzKHZhbHVlLFN0cmluZ0NvbXBhcmlzb24uSW52YXJpYW50Q3VsdHVyZUlnbm9yZUNhc2UpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudEV4Y2VwdGlvbigiV29ya3NoZWV0IG5hbWUgbXVzdCBiZSB1bmlxdWUiKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgX3BhY2thZ2UuV29ya2Jvb2suU2V0WG1sTm9kZVN0cmluZyhzdHJpbmcuRm9ybWF0KCJkOnNoZWV0cy9kOnNoZWV0W0BzaGVldElkPXswfV0vQG5hbWUiLCBfc2hlZXRJRCksIHZhbHVlKTsKICAgICAgICAgICAgICAgIENoYW5nZU5hbWVzKHZhbHVlKTsKCiAgICAgICAgICAgICAgICBfbmFtZSA9IHZhbHVlOwogICAgICAgICAgICB9CgkJfQoKICAgICAgICBwcml2YXRlIHZvaWQgQ2hhbmdlTmFtZXMoc3RyaW5nIHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgLy9SZW5hbWVzIG5hbWUgaW4gdGhpcyBXb3Jrc2hlZXQ7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBuIGluIFdvcmtib29rLk5hbWVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoc3RyaW5nLklzTnVsbE9yRW1wdHkobi5OYW1lRm9ybXVsYSkgJiYgbi5OYW1lVmFsdWU9PW51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbi5DaGFuZ2VXb3Jrc2hlZXQoX25hbWUsIHZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoICh2YXIgd3MgaW4gV29ya2Jvb2suV29ya3NoZWV0cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCEod3MgaXMgRXhjZWxDaGFydHNoZWV0KSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgbiBpbiB3cy5OYW1lcykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eShuLk5hbWVGb3JtdWxhKSAmJiBuLk5hbWVWYWx1ZSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuLkNoYW5nZVdvcmtzaGVldChfbmFtZSwgdmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIEV4Y2VsTmFtZWRSYW5nZUNvbGxlY3Rpb24gX25hbWVzOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gUHJvdmlkZXMgYWNjZXNzIHRvIG5hbWVkIHJhbmdlcwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsTmFtZWRSYW5nZUNvbGxlY3Rpb24gTmFtZXMgCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiBfbmFtZXM7CiAgICAgICAgICAgIH0KICAgICAgICB9CgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBJbmRpY2F0ZXMgaWYgdGhlIHdvcmtzaGVldCBpcyBoaWRkZW4gaW4gdGhlIHdvcmtib29rCgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgZVdvcmtTaGVldEhpZGRlbiBIaWRkZW4KCQl7CgkJCWdldCAKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyaW5nIHN0YXRlPV9wYWNrYWdlLldvcmtib29rLkdldFhtbE5vZGVTdHJpbmcoc3RyaW5nLkZvcm1hdCgiZDpzaGVldHMvZDpzaGVldFtAc2hlZXRJZD17MH1dL0BzdGF0ZSIsIF9zaGVldElEKSk7CiAgICAgICAgICAgICAgICBpZiAoc3RhdGUgPT0gImhpZGRlbiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVXb3JrU2hlZXRIaWRkZW4uSGlkZGVuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoc3RhdGUgPT0gInZlcnlIaWRkZW4iKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBlV29ya1NoZWV0SGlkZGVuLlZlcnlIaWRkZW47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZVdvcmtTaGVldEhpZGRlbi5WaXNpYmxlOwogICAgICAgICAgICB9CgkJCXNldAoJCQl7CiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IGVXb3JrU2hlZXRIaWRkZW4uVmlzaWJsZSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9wYWNrYWdlLldvcmtib29rLkRlbGV0ZU5vZGUoc3RyaW5nLkZvcm1hdCgiZDpzaGVldHMvZDpzaGVldFtAc2hlZXRJZD17MH1dL0BzdGF0ZSIsIF9zaGVldElEKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyB2OwogICAgICAgICAgICAgICAgICAgICAgICB2PXZhbHVlLlRvU3RyaW5nKCk7ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIHY9di5TdWJzdHJpbmcoMCwxKS5Ub0xvd2VyKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpK3YuU3Vic3RyaW5nKDEpOwogICAgICAgICAgICAgICAgICAgICAgICBfcGFja2FnZS5Xb3JrYm9vay5TZXRYbWxOb2RlU3RyaW5nKHN0cmluZy5Gb3JtYXQoImQ6c2hlZXRzL2Q6c2hlZXRbQHNoZWV0SWQ9ezB9XS9Ac3RhdGUiLCBfc2hlZXRJRCksdiApOwogICAgICAgICAgICAgICAgICAgIH0KCQkgICAgfQoJCX0KICAgICAgICBkb3VibGUgX2RlZmF1bHRSb3dIZWlnaHQgPSBkb3VibGUuTmFOOwogICAgICAgIC8vLyA8c3VtbWFyeT4KCQkvLy8gR2V0L3NldCB0aGUgZGVmYXVsdCBoZWlnaHQgb2YgYWxsIHJvd3MgaW4gdGhlIHdvcmtzaGVldAoJCS8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIGRvdWJsZSBEZWZhdWx0Um93SGVpZ2h0CgkJewoJCQlnZXQgCgkJCXsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBpZiAoZG91YmxlLklzTmFOKF9kZWZhdWx0Um93SGVpZ2h0KSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfZGVmYXVsdFJvd0hlaWdodCA9IEdldFhtbE5vZGVEb3VibGUoImQ6c2hlZXRGb3JtYXRQci9AZGVmYXVsdFJvd0hlaWdodCIpOwogICAgICAgICAgICAgICAgICAgIGlmKGRvdWJsZS5Jc05hTihfZGVmYXVsdFJvd0hlaWdodCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfZGVmYXVsdFJvd0hlaWdodCA9IDE1OyAvLyBFeGNlbCBkZWZhdWx0IGhlaWdodAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCQkJCXJldHVybiBfZGVmYXVsdFJvd0hlaWdodDsKCQkJfQoJCQlzZXQKCQkJewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIF9kZWZhdWx0Um93SGVpZ2h0ID0gdmFsdWU7CiAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJkOnNoZWV0Rm9ybWF0UHIvQGRlZmF1bHRSb3dIZWlnaHQiLCB2YWx1ZS5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSk7CiAgICAgICAgICAgICAgICBTZXRYbWxOb2RlQm9vbCgiZDpzaGVldEZvcm1hdFByL0BjdXN0b21IZWlnaHQiLCB2YWx1ZSAhPSAxNSk7CgogICAgICAgICAgICAgICAgaWYgKGRvdWJsZS5Jc05hTihHZXRYbWxOb2RlRG91YmxlKCJkOnNoZWV0Rm9ybWF0UHIvQGRlZmF1bHRDb2xXaWR0aCIpKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBEZWZhdWx0Q29sV2lkdGggPSA5LjE0MDYyNTsKICAgICAgICAgICAgICAgIH0KCQkJfQoJCX0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldC9zZXQgdGhlIGRlZmF1bHQgd2lkdGggb2YgYWxsIHJvd3MgaW4gdGhlIHdvcmtzaGVldAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIGRvdWJsZSBEZWZhdWx0Q29sV2lkdGgKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgZG91YmxlIHJldCA9IEdldFhtbE5vZGVEb3VibGUoImQ6c2hlZXRGb3JtYXRQci9AZGVmYXVsdENvbFdpZHRoIik7CiAgICAgICAgICAgICAgICBpZiAoZG91YmxlLklzTmFOKHJldCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gOS4xNDA2MjU7IC8vIEV4Y2VsJ3MgZGVmYXVsdCB3aWR0aAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoImQ6c2hlZXRGb3JtYXRQci9AZGVmYXVsdENvbFdpZHRoIiwgdmFsdWUuVG9TdHJpbmcoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkpOwoKICAgICAgICAgICAgICAgIGlmIChkb3VibGUuSXNOYU4oR2V0WG1sTm9kZURvdWJsZSgiZDpzaGVldEZvcm1hdFByL0BkZWZhdWx0Um93SGVpZ2h0IikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIERlZmF1bHRSb3dIZWlnaHQgPSAxNTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKiogPG91dGxpbmVQciBhcHBseVN0eWxlcz0iMSIgc3VtbWFyeUJlbG93PSIwIiBzdW1tYXJ5UmlnaHQ9IjAiIC8+ICoqLwogICAgICAgIGNvbnN0IHN0cmluZyBvdXRMaW5lU3VtbWFyeUJlbG93UGF0aCA9ICJkOnNoZWV0UHIvZDpvdXRsaW5lUHIvQHN1bW1hcnlCZWxvdyI7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBTdW1tYXJ5IHJvd3MgYmVsb3cgZGV0YWlscyAKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBib29sIE91dExpbmVTdW1tYXJ5QmVsb3cKICAgICAgICB7IAogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiBHZXRYbWxOb2RlQm9vbChvdXRMaW5lU3VtbWFyeUJlbG93UGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKG91dExpbmVTdW1tYXJ5QmVsb3dQYXRoLCB2YWx1ZSA/ICIxIiA6ICIwIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY29uc3Qgc3RyaW5nIG91dExpbmVTdW1tYXJ5UmlnaHRQYXRoID0gImQ6c2hlZXRQci9kOm91dGxpbmVQci9Ac3VtbWFyeVJpZ2h0IjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFN1bW1hcnkgcm93cyB0byByaWdodCBvZiBkZXRhaWxzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgYm9vbCBPdXRMaW5lU3VtbWFyeVJpZ2h0CiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiBHZXRYbWxOb2RlQm9vbChvdXRMaW5lU3VtbWFyeVJpZ2h0UGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKG91dExpbmVTdW1tYXJ5UmlnaHRQYXRoLCB2YWx1ZSA/ICIxIiA6ICIwIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY29uc3Qgc3RyaW5nIG91dExpbmVBcHBseVN0eWxlUGF0aCA9ICJkOnNoZWV0UHIvZDpvdXRsaW5lUHIvQGFwcGx5U3R5bGVzIjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEF1dG9tYXRpYyBzdHlsZXMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBib29sIE91dExpbmVBcHBseVN0eWxlCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiBHZXRYbWxOb2RlQm9vbChvdXRMaW5lQXBwbHlTdHlsZVBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZyhvdXRMaW5lQXBwbHlTdHlsZVBhdGgsIHZhbHVlID8gIjEiIDogIjAiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb25zdCBzdHJpbmcgdGFiQ29sb3JQYXRoID0gImQ6c2hlZXRQci9kOnRhYkNvbG9yL0ByZ2IiOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ29sb3Igb2YgdGhlIHNoZWV0IHRhYgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIENvbG9yIFRhYkNvbG9yCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyaW5nIGNvbCA9IEdldFhtbE5vZGVTdHJpbmcodGFiQ29sb3JQYXRoKTsKICAgICAgICAgICAgICAgIGlmIChjb2wgPT0gIiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvbG9yLkVtcHR5OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBDb2xvci5Gcm9tQXJnYihpbnQuUGFyc2UoY29sLCBTeXN0ZW0uR2xvYmFsaXphdGlvbi5OdW1iZXJTdHlsZXMuQWxsb3dIZXhTcGVjaWZpZXIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBzZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZyh0YWJDb2xvclBhdGgsIHZhbHVlLlRvQXJnYigpLlRvU3RyaW5nKCJYIikpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvbnN0IHN0cmluZyBjb2RlTW9kdWxlTmFtZVBhdGggPSAiZDpzaGVldFByL0Bjb2RlTmFtZSI7CiAgICAgICAgaW50ZXJuYWwgc3RyaW5nIENvZGVNb2R1bGVOYW1lCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIEdldFhtbE5vZGVTdHJpbmcoY29kZU1vZHVsZU5hbWVQYXRoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZyhjb2RlTW9kdWxlTmFtZVBhdGgsIHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbCB2b2lkIENvZGVOYW1lQ2hhbmdlKHN0cmluZyB2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIENvZGVNb2R1bGVOYW1lID0gdmFsdWU7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBWQkEuRXhjZWxWQkFNb2R1bGUgQ29kZU1vZHVsZQogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfcGFja2FnZS5Xb3JrYm9vay5WYmFQcm9qZWN0ICE9IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9wYWNrYWdlLldvcmtib29rLlZiYVByb2plY3QuTW9kdWxlc1tDb2RlTW9kdWxlTmFtZV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgI3JlZ2lvbiBXb3Jrc2hlZXRYbWwKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFRoZSBYTUwgZG9jdW1lbnQgaG9sZGluZyB0aGUgd29ya3NoZWV0IGRhdGEuCiAgICAgICAgLy8vIEFsbCBjb2x1bW4sIHJvdywgY2VsbCwgcGFnZWJyZWFrLCBtZXJnZWQgY2VsbCBhbmQgaHlwZXJsaW5rLWRhdGEgYXJlIGxvYWRlZCBpbnRvIG1lbW9yeSBhbmQgcmVtb3ZlZCBmcm9tIHRoZSBkb2N1bWVudCB3aGVuIGxvYWRpbmcgdGhlIGRvY3VtZW50LiAgICAgICAgCgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgWG1sRG9jdW1lbnQgV29ya3NoZWV0WG1sCgkJewoJCQlnZXQKCQkJewoJCQkJcmV0dXJuIChfd29ya3NoZWV0WG1sKTsKCQkJfQoJCX0KICAgICAgICBpbnRlcm5hbCBFeGNlbFZtbERyYXdpbmdDb21tZW50Q29sbGVjdGlvbiBfdm1sRHJhd2luZ3MgPSBudWxsOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVm1sIGRyYXdpbmdzLiB1bmRlcmxheWluZyBvYmplY3QgZm9yIGNvbW1lbnRzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBpbnRlcm5hbCBFeGNlbFZtbERyYXdpbmdDb21tZW50Q29sbGVjdGlvbiBWbWxEcmF3aW5nc0NvbW1lbnRzCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF92bWxEcmF3aW5ncyA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIENyZWF0ZVZtbENvbGxlY3Rpb24oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfdm1sRHJhd2luZ3M7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgRXhjZWxDb21tZW50Q29sbGVjdGlvbiBfY29tbWVudHMgPSBudWxsOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ29sbGVjdGlvbiBvZiBjb21tZW50cwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsQ29tbWVudENvbGxlY3Rpb24gQ29tbWVudHMKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgaWYgKF9jb21tZW50cyA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIENyZWF0ZVZtbENvbGxlY3Rpb24oKTsKICAgICAgICAgICAgICAgICAgICBfY29tbWVudHMgPSBuZXcgRXhjZWxDb21tZW50Q29sbGVjdGlvbihfcGFja2FnZSwgdGhpcywgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbW1lbnRzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBDcmVhdGVWbWxDb2xsZWN0aW9uKCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciB2bWxOb2RlID0gX3dvcmtzaGVldFhtbC5Eb2N1bWVudEVsZW1lbnQuU2VsZWN0U2luZ2xlTm9kZSgiZDpsZWdhY3lEcmF3aW5nL0ByOmlkIiwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgIGlmICh2bWxOb2RlID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF92bWxEcmF3aW5ncyA9IG5ldyBFeGNlbFZtbERyYXdpbmdDb21tZW50Q29sbGVjdGlvbihfcGFja2FnZSwgdGhpcywgbnVsbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoUGFydC5SZWxhdGlvbnNoaXBFeGlzdHModm1sTm9kZS5WYWx1ZSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHJlbCA9IFBhcnQuR2V0UmVsYXRpb25zaGlwKHZtbE5vZGUuVmFsdWUpOwogICAgICAgICAgICAgICAgICAgIHZhciB2bWxVcmkgPSBVcmlIZWxwZXIuUmVzb2x2ZVBhcnRVcmkocmVsLlNvdXJjZVVyaSwgcmVsLlRhcmdldFVyaSk7CgogICAgICAgICAgICAgICAgICAgIF92bWxEcmF3aW5ncyA9IG5ldyBFeGNlbFZtbERyYXdpbmdDb21tZW50Q29sbGVjdGlvbihfcGFja2FnZSwgdGhpcywgdm1sVXJpKTsKICAgICAgICAgICAgICAgICAgICBfdm1sRHJhd2luZ3MuUmVsSWQgPSByZWwuSWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBDcmVhdGVYbWwoKQogICAgICAgIHsKICAgICAgICAgICAgX3dvcmtzaGVldFhtbCA9IG5ldyBYbWxEb2N1bWVudCgpOwogICAgICAgICAgICBfd29ya3NoZWV0WG1sLlByZXNlcnZlV2hpdGVzcGFjZSA9IEV4Y2VsUGFja2FnZS5wcmVzZXJ2ZVdoaXRlc3BhY2U7CiAgICAgICAgICAgIFBhY2thZ2luZy5aaXBQYWNrYWdlUGFydCBwYWNrUGFydCA9IF9wYWNrYWdlLlBhY2thZ2UuR2V0UGFydChXb3Jrc2hlZXRVcmkpOwogICAgICAgICAgICBzdHJpbmcgeG1sID0gIiI7CgogICAgICAgICAgICAvLyBGaXJzdCBDb2x1bW5zLCByb3dzLCBjZWxscywgbWVyZ2VjZWxscywgaHlwZXJsaW5rcyBhbmQgcGFnZWJyZWFrZXMgYXJlIGxvYWRlZCBmcm9tIGEgeG1sc3RyZWFtIHRvIG9wdGltaXplIHNwZWVkLi4uCiAgICAgICAgICAgIGJvb2wgZG9BZGp1c3QgPSBfcGFja2FnZS5Eb0FkanVzdERyYXdpbmdzOwogICAgICAgICAgICBfcGFja2FnZS5Eb0FkanVzdERyYXdpbmdzID0gZmFsc2U7CiAgICAgICAgICAgIFN0cmVhbSBzdHJlYW0gPSBwYWNrUGFydC5HZXRTdHJlYW0oKTsKCiAgICAgICAgICAgIFhtbFRleHRSZWFkZXIgeHIgPSBuZXcgWG1sVGV4dFJlYWRlcihzdHJlYW0pOwogICAgICAgICAgICB4ci5Qcm9oaWJpdER0ZCA9IHRydWU7CiAgICAgICAgICAgIHhyLldoaXRlc3BhY2VIYW5kbGluZyA9IFdoaXRlc3BhY2VIYW5kbGluZy5Ob25lOwogICAgICAgICAgICBMb2FkQ29sdW1ucyh4cik7ICAgIC8vY29sdW1uWG1sCiAgICAgICAgICAgIGxvbmcgc3RhcnQgPSBzdHJlYW0uUG9zaXRpb247CiAgICAgICAgICAgIExvYWRDZWxscyh4cik7CiAgICAgICAgICAgIHZhciBuZXh0RWxlbWVudExlbmd0aCA9IEdldEF0dHJpYnV0ZUxlbmd0aCh4cik7CiAgICAgICAgICAgIGxvbmcgZW5kID0gc3RyZWFtLlBvc2l0aW9uIC0gbmV4dEVsZW1lbnRMZW5ndGg7CiAgICAgICAgICAgIExvYWRNZXJnZUNlbGxzKHhyKTsKICAgICAgICAgICAgTG9hZEh5cGVyTGlua3MoeHIpOwogICAgICAgICAgICBMb2FkUm93UGFnZUJyZWFrZXMoeHIpOwogICAgICAgICAgICBMb2FkQ29sUGFnZUJyZWFrZXMoeHIpOwogICAgICAgICAgICAvLy4uLnRoZW4gdGhlIHJlc3Qgb2YgdGhlIFhtbCBpcyBleHRyYWN0ZWQgYW5kIGxvYWRlZCBpbnRvIHRoZSBXb3Jrc2hlZXRYbWwgZG9jdW1lbnQuCiAgICAgICAgICAgIHN0cmVhbS5TZWVrKDAsIFNlZWtPcmlnaW4uQmVnaW4pOwogICAgICAgICAgICBFbmNvZGluZyBlbmNvZGluZzsKICAgICAgICAgICAgeG1sID0gR2V0V29ya1NoZWV0WG1sKHN0cmVhbSwgc3RhcnQsIGVuZCwgb3V0IGVuY29kaW5nKTsKCiAgICAgICAgICAgIC8vZmlyc3QgY2hhciBpcyBpbnZhbGlkIHNvbWV0aW1lcz8/IAogICAgICAgICAgICBpZiAoeG1sWzBdICE9ICc8JykKICAgICAgICAgICAgICAgIExvYWRYbWxTYWZlKF93b3Jrc2hlZXRYbWwsIHhtbC5TdWJzdHJpbmcoMSwgeG1sLkxlbmd0aCAtIDEpLCBlbmNvZGluZyk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIExvYWRYbWxTYWZlKF93b3Jrc2hlZXRYbWwsIHhtbCwgZW5jb2RpbmcpOwoKICAgICAgICAgICAgX3BhY2thZ2UuRG9BZGp1c3REcmF3aW5ncyA9IGRvQWRqdXN0OwogICAgICAgICAgICBDbGVhck5vZGVzKCk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0IHRoZSBsZW50aCBvZiB0aGUgYXR0cmlidXRlcwogICAgICAgIC8vLyBDb25kaXRpb25hbCBmb3JtYXR0aW5nIGF0dHJpYnV0ZXMgY2FuIGJlIGV4dHJlbWx5IGxvbmcgc29tIGdldCBsZW5ndGggb2YgdGhlIGF0dHJpYnV0ZXMgdG8gZmluZXR1bmUgcG9zaXRpb24uCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InhyIj48L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+CiAgICAgICAgcHJpdmF0ZSBpbnQgR2V0QXR0cmlidXRlTGVuZ3RoKFhtbFRleHRSZWFkZXIgeHIpCiAgICAgICAgewogICAgICAgICAgICBpZiAoeHIuTm9kZVR5cGUgIT0gWG1sTm9kZVR5cGUuRWxlbWVudCkgcmV0dXJuIDA7CiAgICAgICAgICAgIHZhciBsZW5ndGggPSAwOwogICAgICAgICAgICAKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB4ci5BdHRyaWJ1dGVDb3VudDsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgYT14ci5HZXRBdHRyaWJ1dGUoaSk7CiAgICAgICAgICAgICAgICBsZW5ndGggKz0gc3RyaW5nLklzTnVsbE9yRW1wdHkoYSkgPyAwIDogYS5MZW5ndGg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGxlbmd0aDsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIExvYWRSb3dQYWdlQnJlYWtlcyhYbWxUZXh0UmVhZGVyIHhyKQogICAgICAgIHsKICAgICAgICAgICAgaWYoIVJlYWRVbnRpbCh4ciwgInJvd0JyZWFrcyIsImNvbEJyZWFrcyIpKSByZXR1cm47CiAgICAgICAgICAgIHdoaWxlICh4ci5SZWFkKCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh4ci5Mb2NhbE5hbWUgPT0gImJyayIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHhyLk5vZGVUeXBlID09IFhtbE5vZGVUeXBlLkVsZW1lbnQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpbnQgaWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnQuVHJ5UGFyc2UoeHIuR2V0QXR0cmlidXRlKCJpZCIpLCBvdXQgaWQpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSb3coaWQpLlBhZ2VCcmVhayA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gICAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIExvYWRDb2xQYWdlQnJlYWtlcyhYbWxUZXh0UmVhZGVyIHhyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFSZWFkVW50aWwoeHIsICJjb2xCcmVha3MiKSkgcmV0dXJuOwogICAgICAgICAgICB3aGlsZSAoeHIuUmVhZCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoeHIuTG9jYWxOYW1lID09ICJicmsiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh4ci5Ob2RlVHlwZSA9PSBYbWxOb2RlVHlwZS5FbGVtZW50KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGlkOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW50LlRyeVBhcnNlKHhyLkdldEF0dHJpYnV0ZSgiaWQiKSwgb3V0IGlkKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sdW1uKGlkKS5QYWdlQnJlYWsgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgQ2xlYXJOb2RlcygpCiAgICAgICAgewogICAgICAgICAgICBpZiAoX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6Y29scyIsIE5hbWVTcGFjZU1hbmFnZXIpIT1udWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpjb2xzIiwgTmFtZVNwYWNlTWFuYWdlcikuUmVtb3ZlQWxsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKF93b3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOm1lcmdlQ2VsbHMiLCBOYW1lU3BhY2VNYW5hZ2VyKSAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDptZXJnZUNlbGxzIiwgTmFtZVNwYWNlTWFuYWdlcikuUmVtb3ZlQWxsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKF93b3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOmh5cGVybGlua3MiLCBOYW1lU3BhY2VNYW5hZ2VyKSAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpoeXBlcmxpbmtzIiwgTmFtZVNwYWNlTWFuYWdlcikuUmVtb3ZlQWxsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKF93b3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOnJvd0JyZWFrcyIsIE5hbWVTcGFjZU1hbmFnZXIpICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF93b3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOnJvd0JyZWFrcyIsIE5hbWVTcGFjZU1hbmFnZXIpLlJlbW92ZUFsbCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpjb2xCcmVha3MiLCBOYW1lU3BhY2VNYW5hZ2VyKSAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpjb2xCcmVha3MiLCBOYW1lU3BhY2VNYW5hZ2VyKS5SZW1vdmVBbGwoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb25zdCBpbnQgQkxPQ0tTSVpFPTgxOTI7CiAgICAgICAgcHJpdmF0ZSBzdHJpbmcgR2V0V29ya1NoZWV0WG1sKFN0cmVhbSBzdHJlYW0sIGxvbmcgc3RhcnQsIGxvbmcgZW5kLCBvdXQgRW5jb2RpbmcgZW5jb2RpbmcpCiAgICAgICAgewogICAgICAgICAgICBTdHJlYW1SZWFkZXIgc3IgPSBuZXcgU3RyZWFtUmVhZGVyKHN0cmVhbSk7CiAgICAgICAgICAgIGludCBsZW5ndGggPSAwOwogICAgICAgICAgICBjaGFyW10gYmxvY2s7CiAgICAgICAgICAgIGludCBwb3M7CiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOyAgICAgICAgICAgIAogICAgICAgICAgICBNYXRjaCBzdGFydG1NYXRjaCwgZW5kTWF0Y2g7CiAgICAgICAgICAgIGRvCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCBzaXplID0gc3RyZWFtLkxlbmd0aCA8IEJMT0NLU0laRSA/IChpbnQpc3RyZWFtLkxlbmd0aCA6IEJMT0NLU0laRTsKICAgICAgICAgICAgICAgIGJsb2NrID0gbmV3IGNoYXJbc2l6ZV07CiAgICAgICAgICAgICAgICBwb3MgPSBzci5SZWFkQmxvY2soYmxvY2ssIDAsIHNpemUpOyAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgc2IuQXBwZW5kKGJsb2NrLDAscG9zKTsKICAgICAgICAgICAgICAgIGxlbmd0aCArPSBzaXplOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHdoaWxlIChsZW5ndGggPCBzdGFydCArIDIwICYmIGxlbmd0aCA8IGVuZCk7CiAgICAgICAgICAgIHN0YXJ0bU1hdGNoID0gUmVnZXguTWF0Y2goc2IuVG9TdHJpbmcoKSwgc3RyaW5nLkZvcm1hdCgiKDxbXj5dKnswfVtePl0qPikiLCAic2hlZXREYXRhIikpOwogICAgICAgICAgICBpZiAoIXN0YXJ0bU1hdGNoLlN1Y2Nlc3MpIC8vTm90IGZvdW5kCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGVuY29kaW5nID0gc3IuQ3VycmVudEVuY29kaW5nOwogICAgICAgICAgICAgICAgcmV0dXJuIHNiLlRvU3RyaW5nKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJpbmcgcyA9IHNiLlRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICBzdHJpbmcgeG1sID0gcy5TdWJzdHJpbmcoMCwgc3RhcnRtTWF0Y2guSW5kZXgpOyAKICAgICAgICAgICAgICAgIGlmKHN0YXJ0bU1hdGNoLlZhbHVlLkVuZHNXaXRoKCIvPiIpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHhtbCArPSBzLlN1YnN0cmluZyhzdGFydG1NYXRjaC5JbmRleCwgcy5MZW5ndGggLSBzdGFydG1NYXRjaC5JbmRleCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNyLlBlZWsoKSAhPSAtMSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qKioqIEZpeGVzIGlzc3VlIDE0Nzg4LiBGaXggYnkgUGhpbGlwIEdhcnJldHQgKioqKi8KICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBlbmRTZWVrU3RhcnQgPSBlbmQ7CgogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZW5kU2Vla1N0YXJ0ID49IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZFNlZWtTdGFydCA9IE1hdGguTWF4KGVuZFNlZWtTdGFydCAtIEJMT0NLU0laRSwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2l6ZSA9IChpbnQpKGVuZCAtIGVuZFNlZWtTdGFydCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uU2VlayhlbmRTZWVrU3RhcnQsIFNlZWtPcmlnaW4uQmVnaW4pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2sgPSBuZXcgY2hhcltzaXplXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyID0gbmV3IFN0cmVhbVJlYWRlcihzdHJlYW0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zID0gc3IuUmVhZEJsb2NrKGJsb2NrLCAwLCBzaXplKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNiLkFwcGVuZChibG9jaywgMCwgcG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBzYi5Ub1N0cmluZygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kTWF0Y2ggPSBSZWdleC5NYXRjaChzLCBzdHJpbmcuRm9ybWF0KCIoPC9bXj5dKnswfVtePl0qPikiLCAic2hlZXREYXRhIikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVuZE1hdGNoLlN1Y2Nlc3MpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZW5kTWF0Y2ggPSBSZWdleC5NYXRjaChzLCBzdHJpbmcuRm9ybWF0KCIoPC9bXj5dKnswfVtePl0qPikiLCAic2hlZXREYXRhIikpOwogICAgICAgICAgICAgICAgICAgIHhtbCArPSAiPHNoZWV0RGF0YS8+IiArIHMuU3Vic3RyaW5nKGVuZE1hdGNoLkluZGV4ICsgZW5kTWF0Y2guTGVuZ3RoLCBzLkxlbmd0aCAtIChlbmRNYXRjaC5JbmRleCArIGVuZE1hdGNoLkxlbmd0aCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHNyLlBlZWsoKSA+IC0xKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHhtbCArPSBzci5SZWFkVG9FbmQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgZW5jb2RpbmcgPSBzci5DdXJyZW50RW5jb2Rpbmc7CiAgICAgICAgICAgICAgICByZXR1cm4geG1sOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBHZXRCbG9ja1BvcyhzdHJpbmcgeG1sLCBzdHJpbmcgdGFnLCByZWYgaW50IHN0YXJ0LCByZWYgaW50IGVuZCkKICAgICAgICB7CiAgICAgICAgICAgIE1hdGNoIHN0YXJ0bU1hdGNoLCBlbmRNYXRjaDsKICAgICAgICAgICAgc3RhcnRtTWF0Y2ggPSBSZWdleC5NYXRjaCh4bWwuU3Vic3RyaW5nKHN0YXJ0KSwgc3RyaW5nLkZvcm1hdCgiKDxbXj5dKnswfVtePl0qPikiLCB0YWcpKTsgLy8iPFthLXpBLVo6XSoiICsgdGFnICsgIls/XSo+Iik7CgogICAgICAgICAgICBpZiAoIXN0YXJ0bU1hdGNoLlN1Y2Nlc3MpIC8vTm90IGZvdW5kCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0YXJ0ID0gLTE7CiAgICAgICAgICAgICAgICBlbmQgPSAtMTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgc3RhcnRQb3M9c3RhcnRtTWF0Y2guSW5kZXgrc3RhcnQ7CiAgICAgICAgICAgIGlmKHN0YXJ0bU1hdGNoLlZhbHVlLlN1YnN0cmluZyhzdGFydG1NYXRjaC5WYWx1ZS5MZW5ndGgtMiwxKT09Ii8iKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlbmQgPSBzdGFydFBvcyArIHN0YXJ0bU1hdGNoLkxlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGVuZE1hdGNoID0gUmVnZXguTWF0Y2goeG1sLlN1YnN0cmluZyhzdGFydCksIHN0cmluZy5Gb3JtYXQoIig8L1tePl0qezB9W14+XSo+KSIsIHRhZykpOwogICAgICAgICAgICAgICAgaWYgKGVuZE1hdGNoLlN1Y2Nlc3MpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZW5kID0gZW5kTWF0Y2guSW5kZXggKyBlbmRNYXRjaC5MZW5ndGggKyBzdGFydDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBzdGFydCA9IHN0YXJ0UG9zOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGJvb2wgUmVhZFVudGlsKFhtbFRleHRSZWFkZXIgeHIscGFyYW1zIHN0cmluZ1tdIHRhZ05hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoeHIuRU9GKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghQXJyYXkuRXhpc3RzKHRhZ05hbWUsIHRhZyA9PiB4ci5Mb2NhbE5hbWUuRW5kc1dpdGgodGFnKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHhyLlJlYWQoKTsKICAgICAgICAgICAgICAgIGlmICh4ci5FT0YpIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gKHhyLkxvY2FsTmFtZS5FbmRzV2l0aCh0YWdOYW1lWzBdKSk7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBMb2FkQ29sdW1ucyAoWG1sVGV4dFJlYWRlciB4cikvLyhzdHJpbmcgeG1sKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGNvbExpc3QgPSBuZXcgTGlzdDxJUmFuZ2VJRD4oKTsKICAgICAgICAgICAgaWYgKFJlYWRVbnRpbCh4ciwgImNvbHMiLCAic2hlZXREYXRhIikpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgLy9pZiAoeG1sICE9ICIiKQogICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgIC8vdmFyIHhyPW5ldyBYbWxUZXh0UmVhZGVyKG5ldyBTdHJpbmdSZWFkZXIoeG1sKSk7CiAgICAgICAgICAgICAgICB3aGlsZSh4ci5SZWFkKCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHhyLk5vZGVUeXBlID09IFhtbE5vZGVUeXBlLldoaXRlc3BhY2UpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIGlmICh4ci5Mb2NhbE5hbWUgIT0gImNvbCIpIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGlmICh4ci5Ob2RlVHlwZSA9PSBYbWxOb2RlVHlwZS5FbGVtZW50KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1pbiA9IGludC5QYXJzZSh4ci5HZXRBdHRyaWJ1dGUoIm1pbiIpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VsQ29sdW1uIGNvbCA9IG5ldyBFeGNlbENvbHVtbih0aGlzLCBtaW4pOwoKICAgICAgICAgICAgICAgICAgICAgICAgY29sLkNvbHVtbk1heCA9IGludC5QYXJzZSh4ci5HZXRBdHRyaWJ1dGUoIm1heCIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29sLldpZHRoID0geHIuR2V0QXR0cmlidXRlKCJ3aWR0aCIpID09IG51bGwgPyAwIDogZG91YmxlLlBhcnNlKHhyLkdldEF0dHJpYnV0ZSgid2lkdGgiKSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuQmVzdEZpdCA9IHhyLkdldEF0dHJpYnV0ZSgiYmVzdEZpdCIpICE9IG51bGwgJiYgeHIuR2V0QXR0cmlidXRlKCJiZXN0Rml0IikgPT0gIjEiID8gdHJ1ZSA6IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLkNvbGxhcHNlZCA9IHhyLkdldEF0dHJpYnV0ZSgiY29sbGFwc2VkIikgIT0gbnVsbCAmJiB4ci5HZXRBdHRyaWJ1dGUoImNvbGxhcHNlZCIpID09ICIxIiA/IHRydWUgOiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5QaG9uZXRpYyA9IHhyLkdldEF0dHJpYnV0ZSgicGhvbmV0aWMiKSAhPSBudWxsICYmIHhyLkdldEF0dHJpYnV0ZSgicGhvbmV0aWMiKSA9PSAiMSIgPyB0cnVlIDogZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5PdXRsaW5lTGV2ZWwgPSAoc2hvcnQpKHhyLkdldEF0dHJpYnV0ZSgib3V0bGluZUxldmVsIikgPT0gbnVsbCA/IDAgOiBpbnQuUGFyc2UoeHIuR2V0QXR0cmlidXRlKCJvdXRsaW5lTGV2ZWwiKSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLkhpZGRlbiA9IHhyLkdldEF0dHJpYnV0ZSgiaGlkZGVuIikgIT0gbnVsbCAmJiB4ci5HZXRBdHRyaWJ1dGUoImhpZGRlbiIpID09ICIxIiA/IHRydWUgOiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZSgwLCBtaW4sIGNvbCk7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdHlsZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoeHIuR2V0QXR0cmlidXRlKCJzdHlsZSIpID09IG51bGwgfHwgIWludC5UcnlQYXJzZSh4ci5HZXRBdHRyaWJ1dGUoInN0eWxlIiksIG91dCBzdHlsZSkpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc3R5bGVzLlNldFZhbHVlKDAsIG1pbiwgc3R5bGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gUmVhZCB1bnRpbCB0aGUgbm9kZSBpcyBmb3VuZC4gSWYgbm90IGZvdW5kIHRoZSB4bWxyZWFkZXIgaXMgcmVzZXRlZC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ieHIiPlRoZSByZWFkZXI8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibm9kZVRleHQiPlRleHQgdG8gc2VhcmNoIGZvcjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJhbHROb2RlIj5BbHRlcm5hdGl2ZSB0ZXh0IHRvIHNlYXJjaCBmb3I8L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbCBSZWFkWG1sUmVhZGVyVW50aWwoWG1sVGV4dFJlYWRlciB4ciwgc3RyaW5nIG5vZGVUZXh0LCBzdHJpbmcgYWx0Tm9kZSkKICAgICAgICB7CiAgICAgICAgICAgIGRvCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh4ci5Mb2NhbE5hbWUgPT0gbm9kZVRleHQgfHwgeHIuTG9jYWxOYW1lID09IGFsdE5vZGUpIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHdoaWxlKHhyLlJlYWQoKSk7CiAgICAgICAgICAgIHhyLkNsb3NlKCk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBMb2FkIEh5cGVybGlua3MKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ieHIiPlRoZSByZWFkZXI8L3BhcmFtPgogICAgICAgIHByaXZhdGUgdm9pZCBMb2FkSHlwZXJMaW5rcyhYbWxUZXh0UmVhZGVyIHhyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFSZWFkVW50aWwoeHIsICJoeXBlcmxpbmtzIiwgInJvd0JyZWFrcyIsICJjb2xCcmVha3MiKSkgcmV0dXJuOwogICAgICAgICAgICB3aGlsZSAoeHIuUmVhZCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoeHIuTG9jYWxOYW1lID09ICJoeXBlcmxpbmsiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGludCBmcm9tUm93LCBmcm9tQ29sLCB0b1JvdywgdG9Db2w7CiAgICAgICAgICAgICAgICAgICAgRXhjZWxDZWxsQmFzZS5HZXRSb3dDb2xGcm9tQWRkcmVzcyh4ci5HZXRBdHRyaWJ1dGUoInJlZiIpLCBvdXQgZnJvbVJvdywgb3V0IGZyb21Db2wsIG91dCB0b1Jvdywgb3V0IHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICBFeGNlbEh5cGVyTGluayBobCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgaWYgKHhyLkdldEF0dHJpYnV0ZSgiaWQiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcykgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBySWQgPSB4ci5HZXRBdHRyaWJ1dGUoImlkIiwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdXJpID0gUGFydC5HZXRSZWxhdGlvbnNoaXAocklkKS5UYXJnZXRVcmk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBHZXQgTG9jYXRpb24sIGlmIGFueS4gIEVQUGx1cyBCdWcgMTU1MTcKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxvY2F0aW9uID0geHIuR2V0QXR0cmlidXRlKCJsb2NhdGlvbiIpOwogICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbiA9IChzdHJpbmcuSXNOdWxsT3JFbXB0eShsb2NhdGlvbikpID8gIiIgOiAiIyIgKyBsb2NhdGlvbjsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1cmkuSXNBYnNvbHV0ZVVyaSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGwgPSBuZXcgRXhjZWxIeXBlckxpbmsodXJpLkFic29sdXRlVXJpICsgbG9jYXRpb24pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2gKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBobCA9IG5ldyBFeGNlbEh5cGVyTGluayh1cmkuT3JpZ2luYWxTdHJpbmcgKyBsb2NhdGlvbiwgVXJpS2luZC5BYnNvbHV0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBobCA9IG5ldyBFeGNlbEh5cGVyTGluayh1cmkuT3JpZ2luYWxTdHJpbmcgKyBsb2NhdGlvbiwgVXJpS2luZC5SZWxhdGl2ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGhsLlJJZCA9IHJJZDsKICAgICAgICAgICAgICAgICAgICAgICAgUGFydC5EZWxldGVSZWxhdGlvbnNoaXAocklkKTsgLy9EZWxldGUgdGhlIHJlbGF0aW9uc2hpcCwgaXQgaXMgcmVjcmVhdGVkIHdoZW4gd2Ugc2F2ZSB0aGUgcGFja2FnZS4KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoeHIuR2V0QXR0cmlidXRlKCJsb2NhdGlvbiIpICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBobCA9IG5ldyBFeGNlbEh5cGVyTGluayh4ci5HZXRBdHRyaWJ1dGUoImxvY2F0aW9uIiksIHhyLkdldEF0dHJpYnV0ZSgiZGlzcGxheSIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgaGwuUm93U3Bhbm4gPSB0b1JvdyAtIGZyb21Sb3c7CiAgICAgICAgICAgICAgICAgICAgICAgIGhsLkNvbFNwYW5uID0gdG9Db2wgLSBmcm9tQ29sOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgc3RyaW5nIHR0ID0geHIuR2V0QXR0cmlidXRlKCJ0b29sdGlwIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eSh0dCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBobC5Ub29sVGlwID0gdHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF9oeXBlckxpbmtzLlNldFZhbHVlKGZyb21Sb3csIGZyb21Db2wsIGhsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIExvYWQgY2VsbHMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ieHIiPlRoZSByZWFkZXI8L3BhcmFtPgogICAgICAgIHByaXZhdGUgdm9pZCBMb2FkQ2VsbHMoWG1sVGV4dFJlYWRlciB4cikKICAgICAgICB7CiAgICAgICAgICAgIC8vdmFyIGNlbGxMaXN0PW5ldyBMaXN0PElSYW5nZUlEPigpOwogICAgICAgICAgICAvL3ZhciByb3dMaXN0ID0gbmV3IExpc3Q8SVJhbmdlSUQ+KCk7CiAgICAgICAgICAgIC8vdmFyIGZvcm11bGFMaXN0ID0gbmV3IExpc3Q8SVJhbmdlSUQ+KCk7CiAgICAgICAgICAgIFJlYWRVbnRpbCh4ciwgInNoZWV0RGF0YSIsICJtZXJnZUNlbGxzIiwgImh5cGVybGlua3MiLCAicm93QnJlYWtzIiwgImNvbEJyZWFrcyIpOwogICAgICAgICAgICBFeGNlbEFkZHJlc3NCYXNlIGFkZHJlc3M9bnVsbDsKICAgICAgICAgICAgc3RyaW5nIHR5cGU9IiI7CiAgICAgICAgICAgIGludCBzdHlsZT0wOwogICAgICAgICAgICBpbnQgcm93ID0gMDsKICAgICAgICAgICAgaW50IGNvbCA9IDA7CiAgICAgICAgICAgIHhyLlJlYWQoKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHdoaWxlICgheHIuRU9GKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB3aGlsZSAoeHIuTm9kZVR5cGUgPT0gWG1sTm9kZVR5cGUuRW5kRWxlbWVudCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4ci5SZWFkKCk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKHhyLkxvY2FsTmFtZSA9PSAicm93IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgciA9IHhyLkdldEF0dHJpYnV0ZSgiciIpOwogICAgICAgICAgICAgICAgICAgIGlmIChyID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByb3crKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcm93ID0gQ29udmVydC5Ub0ludDMyKHIpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKERvQWRkUm93KHhyKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCAwLCBBZGRSb3coeHIsIHJvdykpOwogICAgICAgICAgICAgICAgICAgICAgICBpZih4ci5HZXRBdHRyaWJ1dGUoInMiKSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc3R5bGVzLlNldFZhbHVlKHJvdywgMCwgaW50LlBhcnNlKHhyLkdldEF0dHJpYnV0ZSgicyIpLCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgeHIuUmVhZCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoeHIuTG9jYWxOYW1lID09ICJjIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvL2lmIChjZWxsICE9IG51bGwpIGNlbGxMaXN0LkFkZChjZWxsKTsKICAgICAgICAgICAgICAgICAgICAvL2NlbGwgPSBuZXcgRXhjZWxDZWxsKHRoaXMsIHhyLkdldEF0dHJpYnV0ZSgiciIpKTsKICAgICAgICAgICAgICAgICAgICB2YXIgciA9IHhyLkdldEF0dHJpYnV0ZSgiciIpOwogICAgICAgICAgICAgICAgICAgIGlmIChyID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvL0hhbmRsZSBjZWxscyB3aXRoIG5vIHJlZmVyZW5jZQogICAgICAgICAgICAgICAgICAgICAgICBjb2wrKzsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzcyA9IG5ldyBFeGNlbEFkZHJlc3NCYXNlKHJvdywgY29sLCByb3csIGNvbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkZHJlc3MgPSBuZXcgRXhjZWxBZGRyZXNzQmFzZShyKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29sID0gYWRkcmVzcy5fZnJvbUNvbDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vRGF0ZXR5cGUKICAgICAgICAgICAgICAgICAgICBpZiAoeHIuR2V0QXR0cmlidXRlKCJ0IikgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9eHIuR2V0QXR0cmlidXRlKCJ0Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIF90eXBlcy5TZXRWYWx1ZShhZGRyZXNzLl9mcm9tUm93LCBhZGRyZXNzLl9mcm9tQ29sLCB0eXBlKTsgCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9IiI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vU3R5bGUKICAgICAgICAgICAgICAgICAgICBpZih4ci5HZXRBdHRyaWJ1dGUoInMiKSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9aW50LlBhcnNlKHhyLkdldEF0dHJpYnV0ZSgicyIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgX3N0eWxlcy5TZXRWYWx1ZShhZGRyZXNzLl9mcm9tUm93LCBhZGRyZXNzLl9mcm9tQ29sLCBzdHlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgbnVsbCk7IC8vVE9ETzpCZXR0ZXIgUGVyZm9ybWFuY2UgPz8KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSAwOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB4ci5SZWFkKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICh4ci5Mb2NhbE5hbWUgPT0gInYiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFNldFZhbHVlRnJvbVhtbCh4ciwgdHlwZSwgc3R5bGUsIGFkZHJlc3MuX2Zyb21Sb3csIGFkZHJlc3MuX2Zyb21Db2wpOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIHhyLlJlYWQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHhyLkxvY2FsTmFtZSA9PSAiZiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RyaW5nIHQgPSB4ci5HZXRBdHRyaWJ1dGUoInQiKTsKICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX2Zvcm11bGFzLlNldFZhbHVlKGFkZHJlc3MuX2Zyb21Sb3csIGFkZHJlc3MuX2Zyb21Db2wsIHhyLlJlYWRFbGVtZW50Q29udGVudEFzU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKGFkZHJlc3MuX2Zyb21Sb3csIGFkZHJlc3MuX2Zyb21Db2wsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICAvL2Zvcm11bGFMaXN0LkFkZChjZWxsKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodCA9PSAic2hhcmVkIikKICAgICAgICAgICAgICAgICAgICB7CgogICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgc2kgPSB4ci5HZXRBdHRyaWJ1dGUoInNpIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2ZJbmRleCA9IGludC5QYXJzZShzaSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZm9ybXVsYXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgc2ZJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKGFkZHJlc3MuX2Zyb21Sb3csIGFkZHJlc3MuX2Zyb21Db2wsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGZBZGRyZXNzID0geHIuR2V0QXR0cmlidXRlKCJyZWYiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBmb3JtdWxhID0gQ29udmVydFV0aWwuRXhjZWxEZWNvZGVTdHJpbmcoeHIuUmVhZEVsZW1lbnRDb250ZW50QXNTdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZm9ybXVsYSAhPSAiIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2hhcmVkRm9ybXVsYXMuQWRkKHNmSW5kZXgsIG5ldyBGb3JtdWxhcyhTb3VyY2VDb2RlVG9rZW5pemVyLkRlZmF1bHQpIHsgSW5kZXggPSBzZkluZGV4LCBGb3JtdWxhID0gZm9ybXVsYSwgQWRkcmVzcyA9IGZBZGRyZXNzLCBTdGFydFJvdyA9IGFkZHJlc3MuX2Zyb21Sb3csIFN0YXJ0Q29sID0gYWRkcmVzcy5fZnJvbUNvbCB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhyLlJlYWQoKTsgIC8vU29tZXRoaW5nIGlzIHdyb25nIGluIHRoZSBzaGVldCwgcmVhZCBuZXh0CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodCA9PSAiYXJyYXkiKSAvL1RPRE86IEFycmF5IGZ1bmN0aW9ucyBhcmUgbm90IHN1cHBvcnQgeWV0LiBSZWFkIHRoZSBmb3JtdWxhIGZvciB0aGUgc3RhcnQgY2VsbCBvbmx5LgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGFBZGRyZXNzID0geHIuR2V0QXR0cmlidXRlKCJyZWYiKTsKICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxSYW5nZSBhZGRyZXNzUmFuZ2UgPSBuZXcgRXhjZWxSYW5nZSh0aGlzLCBhQWRkcmVzcyk7ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgZm9ybXVsYSA9IHhyLlJlYWRFbGVtZW50Q29udGVudEFzU3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNJbmRleE1hdGNoRm9ybXVsYSA9IFJlZ2V4LklzTWF0Y2goZm9ybXVsYSwgQCJJTkRFWFwoIiwgUmVnZXhPcHRpb25zLklnbm9yZUNhc2UpICYmIFJlZ2V4LklzTWF0Y2goZm9ybXVsYSwgQCJNQVRDSFwoIiwgUmVnZXhPcHRpb25zLklnbm9yZUNhc2UpICYmICFhQWRkcmVzcy5Db250YWlucygiOiIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNJbmRleE1hdGNoRm9ybXVsYSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzc1JhbmdlLklzQXJyYXlGb3JtdWxhID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBjb2xJbmRleCA9IGFkZHJlc3NSYW5nZS5TdGFydC5Db2x1bW47IGNvbEluZGV4IDw9IGFkZHJlc3NSYW5nZS5FbmQuQ29sdW1uOyBjb2xJbmRleCsrKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHJvd0luZGV4ID0gYWRkcmVzc1JhbmdlLlN0YXJ0LlJvdzsgcm93SW5kZXggPD0gYWRkcmVzc1JhbmdlLkVuZC5Sb3c7IHJvd0luZGV4KyspCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWZJbmRleCA9IEdldE1heFNoYXJlRnVuY3Rpb25JbmRleCh0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Zvcm11bGFzLlNldFZhbHVlKHJvd0luZGV4LCBjb2xJbmRleCwgYWZJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93SW5kZXgsIGNvbEluZGV4LCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzLkFkZChhZkluZGV4LCBuZXcgRm9ybXVsYXMoU291cmNlQ29kZVRva2VuaXplci5EZWZhdWx0KSB7IEluZGV4ID0gYWZJbmRleCwgRm9ybXVsYSA9IGZvcm11bGEsIEFkZHJlc3MgPSBhQWRkcmVzcywgU3RhcnRSb3cgPSBhZGRyZXNzLl9mcm9tUm93LCBTdGFydENvbCA9IGFkZHJlc3MuX2Zyb21Db2wsIElzQXJyYXkgPSBmYWxzZSB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRyZXNzUmFuZ2UuSXNBcnJheUZvcm11bGEgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFmSW5kZXggPSBHZXRNYXhTaGFyZUZ1bmN0aW9uSW5kZXgodHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBjb2xJbmRleCA9IGFkZHJlc3NSYW5nZS5TdGFydC5Db2x1bW47IGNvbEluZGV4IDw9IGFkZHJlc3NSYW5nZS5FbmQuQ29sdW1uOyBjb2xJbmRleCsrKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHJvd0luZGV4ID0gYWRkcmVzc1JhbmdlLlN0YXJ0LlJvdzsgcm93SW5kZXggPD0gYWRkcmVzc1JhbmdlLkVuZC5Sb3c7IHJvd0luZGV4KyspCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZm9ybXVsYXMuU2V0VmFsdWUocm93SW5kZXgsIGNvbEluZGV4LCBhZkluZGV4KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3dJbmRleCwgY29sSW5kZXgsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zaGFyZWRGb3JtdWxhcy5BZGQoYWZJbmRleCwgbmV3IEZvcm11bGFzKFNvdXJjZUNvZGVUb2tlbml6ZXIuRGVmYXVsdCkgeyBJbmRleCA9IGFmSW5kZXgsIEZvcm11bGEgPSBmb3JtdWxhLCBBZGRyZXNzID0gYUFkZHJlc3MsIFN0YXJ0Um93ID0gYWRkcmVzcy5fZnJvbVJvdywgU3RhcnRDb2wgPSBhZGRyZXNzLl9mcm9tQ29sLCBJc0FycmF5ID0gdHJ1ZSB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIC8vID8/PyBzb21lIG90aGVyIHR5cGUKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhyLlJlYWQoKTsgIC8vU29tZXRoaW5nIGlzIHdyb25nIGluIHRoZSBzaGVldCwgcmVhZCBuZXh0CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHhyLkxvY2FsTmFtZSA9PSAiaXMiKSAgIC8vSW5saW5lIHN0cmluZwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHhyLlJlYWQoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoeHIuTG9jYWxOYW1lID09ICJ0IikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgQ29udmVydFV0aWwuRXhjZWxEZWNvZGVTdHJpbmcoeHIuUmVhZEVsZW1lbnRDb250ZW50QXNTdHJpbmcoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICAvL2NlbGwuX3ZhbHVlID0geHIuUmVhZElubmVyWG1sKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgeHIuUmVhZE91dGVyWG1sKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBfdHlwZXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgInJ0Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIF9mbGFncy5TZXRGbGFnVmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgdHJ1ZSwgQ2VsbEZsYWdzLlJpY2hUZXh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgLy9jZWxsLklzUmljaFRleHQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvL2lmIChjZWxsICE9IG51bGwpIGNlbGxMaXN0LkFkZChjZWxsKTsKCiAgICAgICAgICAgIC8vX2NlbGxzID0gbmV3IFJhbmdlQ29sbGVjdGlvbihjZWxsTGlzdCk7CiAgICAgICAgICAgIC8vX3Jvd3MgPSBuZXcgUmFuZ2VDb2xsZWN0aW9uKHJvd0xpc3QpOwogICAgICAgICAgICAvL19mb3JtdWxhQ2VsbHMgPSBuZXcgUmFuZ2VDb2xsZWN0aW9uKGZvcm11bGFMaXN0KTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgYm9vbCBEb0FkZFJvdyhYbWxUZXh0UmVhZGVyIHhyKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGMgPSB4ci5HZXRBdHRyaWJ1dGUoInIiKT09bnVsbCA/IDA6MTsKICAgICAgICAgICAgaWYgKHhyLkdldEF0dHJpYnV0ZSgic3BhbnMiKSAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHhyLkF0dHJpYnV0ZUNvdW50ID4gYzsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBMb2FkIG1lcmdlZCBjZWxscwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJ4ciI+PC9wYXJhbT4KICAgICAgICBwcml2YXRlIHZvaWQgTG9hZE1lcmdlQ2VsbHMoWG1sVGV4dFJlYWRlciB4cikKICAgICAgICB7CiAgICAgICAgICAgIGlmKFJlYWRVbnRpbCh4ciwgIm1lcmdlQ2VsbHMiLCAiaHlwZXJsaW5rcyIsICJyb3dCcmVha3MiLCAiY29sQnJlYWtzIikgJiYgIXhyLkVPRikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgd2hpbGUgKHhyLlJlYWQoKSkKICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICh4ci5Mb2NhbE5hbWUgIT0gIm1lcmdlQ2VsbCIpIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGlmICh4ci5Ob2RlVHlwZSA9PSBYbWxOb2RlVHlwZS5FbGVtZW50KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGFkZHJlc3MgPSB4ci5HZXRBdHRyaWJ1dGUoInJlZiIpOwogICAgICAgICAgICAgICAgICAgICAgICAvL2ludCBmcm9tUm93LCBmcm9tQ29sLCB0b1JvdywgdG9Db2w7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vRXhjZWxDZWxsQmFzZS5HZXRSb3dDb2xGcm9tQWRkcmVzcyhhZGRyZXNzLCBvdXQgZnJvbVJvdywgb3V0IGZyb21Db2wsIG91dCB0b1Jvdywgb3V0IHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy9mb3IgKGludCByb3cgPSBmcm9tUm93OyByb3cgPD0gdG9Sb3c7IHJvdysrKQogICAgICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgZm9yIChpbnQgY29sID0gZnJvbUNvbDsgY29sIDw9IHRvQ29sOyBjb2wrKykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgX2ZsYWdzLlNldEZsYWdWYWx1ZShyb3csIGNvbCwgdHJ1ZSxDZWxsRmxhZ3MuTWVyZ2VkKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgfQogICAgICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgICAgICAgICAgLy9fbWVyZ2VkQ2VsbHMuTGlzdC5BZGQoYWRkcmVzcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9tZXJnZWRDZWxscy5BZGQobmV3IEV4Y2VsQWRkcmVzcyhhZGRyZXNzKSwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFVwZGF0ZSBtZXJnZWQgY2VsbHMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic3ciPlRoZSB3cml0ZXI8L3BhcmFtPgogICAgICAgIHByaXZhdGUgdm9pZCBVcGRhdGVNZXJnZWRDZWxscyhTdHJlYW1Xcml0ZXIgc3cpCiAgICAgICAgewogICAgICAgICAgICBzdy5Xcml0ZSgiPG1lcmdlQ2VsbHM+Iik7CiAgICAgICAgICAgIGZvcmVhY2ggKHN0cmluZyBhZGRyZXNzIGluIF9tZXJnZWRDZWxscykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3cuV3JpdGUoIjxtZXJnZUNlbGwgcmVmPVwiezB9XCIgLz4iLCBhZGRyZXNzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdy5Xcml0ZSgiPC9tZXJnZUNlbGxzPiIpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFJlYWRzIGEgcm93IGZyb20gdGhlIFhNTCByZWFkZXIKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ieHIiPlRoZSByZWFkZXI8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icm93Ij5UaGUgcm93IG51bWJlcjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBwcml2YXRlIFJvd0ludGVybmFsIEFkZFJvdyhYbWxUZXh0UmVhZGVyIHhyLCBpbnQgcm93KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSb3dJbnRlcm5hbCgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENvbGxhcHNlZD0oeHIuR2V0QXR0cmlidXRlKCJjb2xsYXBzZWQiKSAhPSBudWxsICYmIHhyLkdldEF0dHJpYnV0ZSgiY29sbGFwc2VkIik9PSAiMSIgPyB0cnVlIDogZmFsc2UpLAogICAgICAgICAgICAgICAgT3V0bGluZUxldmVsID0gKHhyLkdldEF0dHJpYnV0ZSgib3V0bGluZUxldmVsIikgPT0gbnVsbCA/IChzaG9ydCkwIDogc2hvcnQuUGFyc2UoeHIuR2V0QXR0cmlidXRlKCJvdXRsaW5lTGV2ZWwiKSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkpLAogICAgICAgICAgICAgICAgSGVpZ2h0ID0gKHhyLkdldEF0dHJpYnV0ZSgiaHQiKSA9PSBudWxsID8gLTEgOiBkb3VibGUuUGFyc2UoeHIuR2V0QXR0cmlidXRlKCJodCIpLCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSksCiAgICAgICAgICAgICAgICBIaWRkZW4gPSAoeHIuR2V0QXR0cmlidXRlKCJoaWRkZW4iKSAhPSBudWxsICYmIHhyLkdldEF0dHJpYnV0ZSgiaGlkZGVuIikgPT0gIjEiID8gdHJ1ZSA6IGZhbHNlKSwKICAgICAgICAgICAgICAgIFBob25ldGljID0geHIuR2V0QXR0cmlidXRlKCJwaCIpICE9IG51bGwgJiYgeHIuR2V0QXR0cmlidXRlKCJwaCIpID09ICIxIiA/IHRydWUgOiBmYWxzZSwKICAgICAgICAgICAgICAgIEN1c3RvbUhlaWdodCA9IHhyLkdldEF0dHJpYnV0ZSgiY3VzdG9tSGVpZ2h0IikgPT0gbnVsbCA/IGZhbHNlIDogeHIuR2V0QXR0cmlidXRlKCJjdXN0b21IZWlnaHQiKT09IjEiCiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIERhdGVUaW1lIER1cmF0aW9uRnJvbU9BRGF0ZShkb3VibGUgdmFsdWUpCiAgICAgICAgewogICAgICAgICAgICAvLyBDb252ZXJ0IHRoZSBEdXJhdGlvbiB2YWx1ZSBpbnRvIHRoZSBjb3JyZXNwb25kaW5nIERhdGVUaW1lIHZhbHVlLgogICAgICAgICAgICAvLyBUaGUgRHVyYXRpb24gdmFsdWUgaXMgcGFzc2VkIGluIGFzIGEgZnJhY3Rpb25hbCBPZmZpY2UgQXV0b21hdGlvbiBkb3VibGUgdmFsdWVzIHdoZXJlIHRoZSAKICAgICAgICAgICAgLy8gd2hvbGUgcG9ydGlvbiBpcyB0aGUgbnVtYmVyIG9mIGRheXMgYW5kIHRoZSBmcmFjdGlvbmFsIHBvcnRpb24gb2YgdGhlIG51bWJlciBpcyB0aGUgaG91cnMuCiAgICAgICAgICAgIC8vIEZvciBleGFtcGxlLCB0aGUgRHVyYXRpb24gdmFsdWUgLTEuNSByZXByZXNlbnRzIGEgbmVnYXRpdmUgZHVyYXRpb24gb2Ygb25lIGRheSBhbmQgMTIgaG91cnMuCiAgICAgICAgICAgIC8vIFdlIHVzZSB0aGlzIHRlY2huaXF1ZSByYXRoZXIgdGhhbiBjYWxsaW5nIHRoZSAnRGF0ZVRpbWUuRnJvbU9BRGF0ZSgpJyBtZXRob2QsIGJlY2F1c2UKICAgICAgICAgICAgLy8gdGhpcyB0ZWNobmlxdWUgd29ya3MgZm9yIGJvdGggcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIGR1cmF0aW9uIHZhbHVlcy4gdW5saWtlICdEYXRlVGltZS5Gcm9tT0FEYXRlKCknCiAgICAgICAgICAgIC8vIHdoaWNoIHlpZWxkcyB0aGUgd3JvbmcgcmVzdWx0IGZvciBuZWdhdGl2ZSBEdXJhdGlvbiB2YWx1ZXMuCiAgICAgICAgICAgIHJldHVybiBuZXcgRGF0ZVRpbWUoMTg5OSwgMTIsIDMwKSArIFRpbWVTcGFuLkZyb21EYXlzKHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBTZXRWYWx1ZUZyb21YbWwoWG1sVGV4dFJlYWRlciB4ciwgc3RyaW5nIHR5cGUsIGludCBzdHlsZUlELCBpbnQgcm93LCBpbnQgY29sKQogICAgICAgIHsKICAgICAgICAgICAgLy9YbWxOb2RlIHZub2RlID0gY29sTm9kZS5TZWxlY3RTaW5nbGVOb2RlKCJkOnYiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgLy9pZiAodm5vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIGlmICh0eXBlID09ICJzIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IGl4ID0geHIuUmVhZEVsZW1lbnRDb250ZW50QXNJbnQoKTsKCiAgICAgICAgICAgICAgICAvLyBUZW1wb3JhcnkgZGVidWdnaW5nIGNvZGUgdG8gbG9jYXRlIGludGVybWl0dGVudCAnSW5kZXggd2FzIG91dCBvZiByYW5nZScgZXhjZXB0aW9uLgogICAgICAgICAgICAgICAgaWYgKGl4IDwgMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKHN0cmluZy5Gb3JtYXQoIlJlYWRFbGVtZW50Q29udGVudEFzSW50IHJldHVybmVkIHZhbHVlICd7MH0nIHdoaWNoIGlzIGxlc3MgdGhhbiB6ZXJvLiIsIGl4KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXggPj0gX3BhY2thZ2UuV29ya2Jvb2suX3NoYXJlZFN0cmluZ3NMaXN0LkNvdW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiUmVhZEVsZW1lbnRDb250ZW50QXNJbnQgcmV0dXJuZWQgaW5kZXggdmFsdWUgJ3swfScgd2hpY2ggaXMgZ3JlYXRlciB0aGFuIF9zaGFyZWRTdHJpbmdzTGlzdCBjb3VudCBvZiB7MX0uIiwgaXgsIF9wYWNrYWdlLldvcmtib29rLl9zaGFyZWRTdHJpbmdzTGlzdC5Db3VudCkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIF9wYWNrYWdlLldvcmtib29rLl9zaGFyZWRTdHJpbmdzTGlzdFtpeF0uVGV4dCk7CiAgICAgICAgICAgICAgICBpZiAoX3BhY2thZ2UuV29ya2Jvb2suX3NoYXJlZFN0cmluZ3NMaXN0W2l4XS5pc1JpY2hUZXh0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF9mbGFncy5TZXRGbGFnVmFsdWUocm93LCBjb2wsIHRydWUsIENlbGxGbGFncy5SaWNoVGV4dCk7CiAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gInN0ciIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIENvbnZlcnRVdGlsLkV4Y2VsRGVjb2RlU3RyaW5nKHhyLlJlYWRFbGVtZW50Q29udGVudEFzU3RyaW5nKCkpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh0eXBlID09ICJiIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgKHhyLlJlYWRFbGVtZW50Q29udGVudEFzU3RyaW5nKCkhPSIwIikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gImUiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCBHZXRFcnJvclR5cGUoeHIuUmVhZEVsZW1lbnRDb250ZW50QXNTdHJpbmcoKSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyaW5nIHYgPSB4ci5SZWFkRWxlbWVudENvbnRlbnRBc1N0cmluZygpOwogICAgICAgICAgICAgICAgdmFyIG5mID0gV29ya2Jvb2suU3R5bGVzLkNlbGxYZnNbc3R5bGVJRF0uTnVtYmVyRm9ybWF0SWQ7CiAgICAgICAgICAgICAgICBpZiAoKG5mID49IDIwICYmIG5mIDw9IDIxKSB8fCAobmYgPj0gNDUgJiYgbmYgPD0gNDcpKSAgLy8gRHVyYXRpb24KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkb3VibGUgcmVzOwogICAgICAgICAgICAgICAgICAgIGlmIChkb3VibGUuVHJ5UGFyc2UodiwgTnVtYmVyU3R5bGVzLkFueSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSwgb3V0IHJlcykpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoV29ya2Jvb2suRGF0ZTE5MDQpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcyArPSBFeGNlbFdvcmtib29rLmRhdGUxOTA0T2Zmc2V0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXMgPj0gLTY1NzQzNS4wICYmIHJlcyA8IDI5NTg0NjUuOTk5OTk5OSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBEdXJhdGlvbiB2YWx1ZSBleHByZXNzZWQgYXMgYSBEYXRlVGltZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIER1cmF0aW9uRnJvbU9BRGF0ZShyZXMpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsICIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgIiIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKChuZiA+PSAxNCAmJiBuZiA8PSAxOSkgfHwgKG5mID09IDIyKSkgICAvLyBEYXRlVGltZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRvdWJsZSByZXM7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRvdWJsZS5UcnlQYXJzZSh2LCBOdW1iZXJTdHlsZXMuQW55LCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlLCBvdXQgcmVzKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChXb3JrYm9vay5EYXRlMTkwNCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzICs9IEV4Y2VsV29ya2Jvb2suZGF0ZTE5MDRPZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcyA+PSAtNjU3NDM1LjAgJiYgcmVzIDwgMjk1ODQ2NS45OTk5OTk5KQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCBEYXRlVGltZS5Gcm9tT0FEYXRlKHJlcykpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsICIiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZG91YmxlIGQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRvdWJsZS5UcnlQYXJzZSh2LCBOdW1iZXJTdHlsZXMuQW55LCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlLCBvdXQgZCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCBkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgZG91YmxlLk5hTik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIG9iamVjdCBHZXRFcnJvclR5cGUoc3RyaW5nIHYpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRXhjZWxFcnJvclZhbHVlLlBhcnNlKHYuVG9VcHBlcihDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSk7CiAgICAgICAgICAgIC8vc3dpdGNoKHYuVG9VcHBlcigpKQogICAgICAgICAgICAvL3sKICAgICAgICAgICAgLy8gICAgY2FzZSAiI0RJVi8wISI6CiAgICAgICAgICAgIC8vICAgICAgICByZXR1cm4gbmV3IEV4Y2VsRXJyb3JWYWx1ZS5jcmUoZUVycm9yVHlwZS5EaXYwKTsKICAgICAgICAgICAgLy8gICAgY2FzZSAiI1JFRiEiOgogICAgICAgICAgICAvLyAgICAgICAgcmV0dXJuIG5ldyBFeGNlbEVycm9yVmFsdWUoZUVycm9yVHlwZS5SZWYpOwogICAgICAgICAgICAvLyAgICBjYXNlICIjTi9BIjoKICAgICAgICAgICAgLy8gICAgICAgIHJldHVybiBuZXcgRXhjZWxFcnJvclZhbHVlKGVFcnJvclR5cGUuTkEpOwogICAgICAgICAgICAvLyAgICBjYXNlICIjTkFNRT8iOgogICAgICAgICAgICAvLyAgICAgICAgcmV0dXJuIG5ldyBFeGNlbEVycm9yVmFsdWUoZUVycm9yVHlwZS5OYW1lKTsKICAgICAgICAgICAgLy8gICAgY2FzZSAiI05VTEwhIjoKICAgICAgICAgICAgLy8gICAgICAgIHJldHVybiBuZXcgRXhjZWxFcnJvclZhbHVlKGVFcnJvclR5cGUuTnVsbCk7CiAgICAgICAgICAgIC8vICAgIGNhc2UgIiNOVU0hIjoKICAgICAgICAgICAgLy8gICAgICAgIHJldHVybiBuZXcgRXhjZWxFcnJvclZhbHVlKGVFcnJvclR5cGUuTnVtKTsKICAgICAgICAgICAgLy8gICAgZGVmYXVsdDoKICAgICAgICAgICAgLy8gICAgICAgIHJldHVybiBuZXcgRXhjZWxFcnJvclZhbHVlKGVFcnJvclR5cGUuVmFsdWUpOwogICAgICAgICAgICAvL30KICAgICAgICB9CiAgICAgICAgLy9wcml2YXRlIHN0cmluZyBHZXRTaGFyZWRTdHJpbmcoaW50IHN0cmluZ0lEKQogICAgICAgIC8vewogICAgICAgIC8vICAgIHN0cmluZyByZXRWYWx1ZSA9IG51bGw7CiAgICAgICAgLy8gICAgWG1sTm9kZUxpc3Qgc3RyaW5nTm9kZXMgPSB4bFBhY2thZ2UuV29ya2Jvb2suU2hhcmVkU3RyaW5nc1htbC5TZWxlY3ROb2RlcyhzdHJpbmcuRm9ybWF0KCIvL2Q6c2kiLCBzdHJpbmdJRCksIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgIC8vICAgIFhtbE5vZGUgc3RyaW5nTm9kZSA9IHN0cmluZ05vZGVzW3N0cmluZ0lEXTsKICAgICAgICAvLyAgICBpZiAoc3RyaW5nTm9kZSAhPSBudWxsKQogICAgICAgIC8vICAgICAgICByZXRWYWx1ZSA9IHN0cmluZ05vZGUuSW5uZXJUZXh0OwogICAgICAgIC8vICAgIHJldHVybiAocmV0VmFsdWUpOwogICAgICAgIC8vfQogICAgICAgICNlbmRyZWdpb24KCQkjcmVnaW9uIEhlYWRlckZvb3RlcgoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gQSByZWZlcmVuY2UgdG8gdGhlIGhlYWRlciBhbmQgZm9vdGVyIGNsYXNzIHdoaWNoIGFsbG93cyB5b3UgdG8gCgkJLy8vIHNldCB0aGUgaGVhZGVyIGFuZCBmb290ZXIgZm9yIGFsbCBvZGQsIGV2ZW4gYW5kIGZpcnN0IHBhZ2VzIG9mIHRoZSB3b3Jrc2hlZXQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cmVtYXJrcz4KICAgICAgICAvLy8gVG8gZm9ybWF0IHRoZSB0ZXh0IHlvdSBjYW4gdXNlIHRoZSBmb2xsb3dpbmcgZm9ybWF0CiAgICAgICAgLy8vIDxsaXN0IHR5cGU9InRhYmxlIj4KICAgICAgICAvLy8gPGxpc3RoZWFkZXI+PHRlcm0+UHJlZml4PC90ZXJtPjxkZXNjcmlwdGlvbj5EZXNjcmlwdGlvbjwvZGVzY3JpcHRpb24+PC9saXN0aGVhZGVyPgogICAgICAgIC8vLyA8aXRlbT48dGVybT4mYW1wO1U8L3Rlcm0+PGRlc2NyaXB0aW9uPlVuZGVybGluZWQ8L2Rlc2NyaXB0aW9uPjwvaXRlbT4KICAgICAgICAvLy8gPGl0ZW0+PHRlcm0+JmFtcDtFPC90ZXJtPjxkZXNjcmlwdGlvbj5Eb3VibGUgVW5kZXJsaW5lPC9kZXNjcmlwdGlvbj48L2l0ZW0+CiAgICAgICAgLy8vIDxpdGVtPjx0ZXJtPiZhbXA7Szp4eHh4eHg8L3Rlcm0+PGRlc2NyaXB0aW9uPkNvbG9yLiBleCAmYW1wO0s6RkYwMDAwIGZvciByZWQ8L2Rlc2NyaXB0aW9uPjwvaXRlbT4KICAgICAgICAvLy8gPGl0ZW0+PHRlcm0+JmFtcDsiRm9udCxSZWd1bGFyIEJvbGQgSXRhbGljIjwvdGVybT48ZGVzY3JpcHRpb24+Q2hhbmdlcyB0aGUgZm9udC4gUmVndWxhciBvciBCb2xkIG9yIEl0YWxpYyBvciBCb2xkIEl0YWxpYyBjYW4gYmUgdXNlZC4gZXggJmFtcDsiQXJpYWwsQm9sZCBJdGFsaWMiPC9kZXNjcmlwdGlvbj48L2l0ZW0+CiAgICAgICAgLy8vIDxpdGVtPjx0ZXJtPiZhbXA7bm48L3Rlcm0+PGRlc2NyaXB0aW9uPkNoYW5nZSBmb250IHNpemUuIG5uIGlzIGFuIGludGVnZXIuIGV4ICZhbXA7MjQ8L2Rlc2NyaXB0aW9uPjwvaXRlbT4KICAgICAgICAvLy8gPGl0ZW0+PHRlcm0+JmFtcDtHPC90ZXJtPjxkZXNjcmlwdGlvbj5QbGFjZWhvbGRlciBmb3IgaW1hZ2VzLiBJbWFnZXMgY2FuIG5vdCBiZSBhZGRlZCBieSB0aGUgbGlicmFyeSwgYnV0IGl0cyBwb3NzaWJsZSB0byB1c2UgaW4gYSB0ZW1wbGF0ZS48L2Rlc2NyaXB0aW9uPjwvaXRlbT4KICAgICAgICAvLy8gPC9saXN0PgogICAgICAgIC8vLyA8L3JlbWFya3M+CiAgICAgICAgcHVibGljIEV4Y2VsSGVhZGVyRm9vdGVyIEhlYWRlckZvb3RlcgoJCXsKCQkJZ2V0CgkJCXsKCQkJCWlmIChfaGVhZGVyRm9vdGVyID09IG51bGwpCgkJCQl7CiAgICAgICAgICAgICAgICAgICAgWG1sTm9kZSBoZWFkZXJGb290ZXJOb2RlID0gVG9wTm9kZS5TZWxlY3RTaW5nbGVOb2RlKCJkOmhlYWRlckZvb3RlciIsIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICAgICAgICAgIGlmIChoZWFkZXJGb290ZXJOb2RlID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlckZvb3Rlck5vZGU9IENyZWF0ZU5vZGUoImQ6aGVhZGVyRm9vdGVyIik7CiAgICAgICAgICAgICAgICAgICAgX2hlYWRlckZvb3RlciA9IG5ldyBFeGNlbEhlYWRlckZvb3RlcihOYW1lU3BhY2VNYW5hZ2VyLCBoZWFkZXJGb290ZXJOb2RlLCB0aGlzKTsKCQkJCX0gICAgICAgICAgICAgICAgCgkJCQlyZXR1cm4gKF9oZWFkZXJGb290ZXIpOwoJCQl9CgkJfQoJCSNlbmRyZWdpb24KCiAgICAgICAgI3JlZ2lvbiAiUHJpbnRlclNldHRpbmdzIgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gUHJpbnRlciBzZXR0aW5ncwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsUHJpbnRlclNldHRpbmdzIFByaW50ZXJTZXR0aW5ncwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBwcyA9IG5ldyBFeGNlbFByaW50ZXJTZXR0aW5ncyhOYW1lU3BhY2VNYW5hZ2VyLCBUb3BOb2RlLCB0aGlzKTsKICAgICAgICAgICAgICAgIHBzLlNjaGVtYU5vZGVPcmRlciA9IFNjaGVtYU5vZGVPcmRlcjsKICAgICAgICAgICAgICAgIHJldHVybiBwczsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAjZW5kcmVnaW9uCgoJCSNlbmRyZWdpb24gLy8gRU5EIFdvcmtzaGVldCBQdWJsaWMgUHJvcGVydGllcwoKCQkjcmVnaW9uIFdvcmtzaGVldCBQdWJsaWMgTWV0aG9kcwogICAgICAgIAogICAgICAgIC8vLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLy8vIFByb3ZpZGVzIGFjY2VzcyB0byBhbiBpbmRpdmlkdWFsIGNlbGwgd2l0aGluIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLy8vIDxwYXJhbSBuYW1lPSJyb3ciPlRoZSByb3cgbnVtYmVyIGluIHRoZSB3b3Jrc2hlZXQ8L3BhcmFtPgogICAgICAgIC8vLy8vIDxwYXJhbSBuYW1lPSJjb2wiPlRoZSBjb2x1bW4gbnVtYmVyIGluIHRoZSB3b3Jrc2hlZXQ8L3BhcmFtPgogICAgICAgIC8vLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4JCQogICAgICAgIC8vaW50ZXJuYWwgRXhjZWxDZWxsIENlbGwoaW50IHJvdywgaW50IGNvbCkKICAgICAgICAvL3sKICAgICAgICAvLyAgICByZXR1cm4gbmV3IEV4Y2VsQ2VsbChfdmFsdWVzLCByb3csIGNvbCk7CiAgICAgICAgLy99CiAgICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAgLy8vIFByb3ZpZGVzIGFjY2VzcyB0byBhIHJhbmdlIG9mIGNlbGxzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4gIAogICAgICAgIHB1YmxpYyBFeGNlbFJhbmdlIENlbGxzCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRXhjZWxSYW5nZSh0aGlzLCAxLCAxLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gUHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBzZWxlY3RlZCByYW5nZSBvZiBjZWxscwogICAgICAgIC8vLyA8L3N1bW1hcnk+ICAKICAgICAgICBwdWJsaWMgRXhjZWxSYW5nZSBTZWxlY3RlZFJhbmdlCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRXhjZWxSYW5nZSh0aGlzLCBWaWV3LlNlbGVjdGVkUmFuZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIE1lcmdlQ2VsbHNDb2xsZWN0aW9uIF9tZXJnZWRDZWxscyA9IG5ldyBNZXJnZUNlbGxzQ29sbGVjdGlvbigpOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQWRkcmVzc2VzIHRvIG1lcmdlZCByYW5nZXMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBNZXJnZUNlbGxzQ29sbGVjdGlvbiBNZXJnZWRDZWxscwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gX21lcmdlZENlbGxzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KCQkvLy8gUHJvdmlkZXMgYWNjZXNzIHRvIGFuIGluZGl2aWR1YWwgcm93IHdpdGhpbiB0aGUgd29ya3NoZWV0IHNvIHlvdSBjYW4gc2V0IGl0cyBwcm9wZXJ0aWVzLgoJCS8vLyA8L3N1bW1hcnk+CgkJLy8vIDxwYXJhbSBuYW1lPSJyb3ciPlRoZSByb3cgbnVtYmVyIGluIHRoZSB3b3Jrc2hlZXQ8L3BhcmFtPgoJCS8vLyA8cmV0dXJucz48L3JldHVybnM+CgkJcHVibGljIEV4Y2VsUm93IFJvdyhpbnQgcm93KQoJCXsKICAgICAgICAgICAgLy9FeGNlbFJvdyByOwogICAgICAgICAgICAvL3Vsb25nIGlkID0gRXhjZWxSb3cuR2V0Um93SUQoX3NoZWV0SUQsIHJvdyk7CiAgICAgICAgICAgIC8vVE9ETzogRml4YS4KICAgICAgICAgICAgLy92YXIgdiA9IF92YWx1ZXMuR2V0VmFsdWUocm93LCAwKTsKICAgICAgICAgICAgLy9pZiAodiE9bnVsbCkKICAgICAgICAgICAgLy97CiAgICAgICAgICAgIC8vICAgIHZhciByaT0oUm93SW50ZXJuYWwpdjsKICAgICAgICAgICAgLy8gICAgciA9IG5ldyBFeGNlbFJvdyh0aGlzLCByb3cpCiAgICAgICAgICAgIC8vfQogICAgICAgICAgICAvL2Vsc2UKICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAvL3IgPSBuZXcgRXhjZWxSb3codGhpcywgcm93KTsKICAgICAgICAgICAgICAgIC8vX3ZhbHVlcy5TZXRWYWx1ZShyb3csIDAsIHIpOwogICAgICAgICAgICAgICAgLy9fcm93cy5BZGQocik7CiAgICAgICAgICAgIC8vfQogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpZiAocm93IDwgMSB8fCByb3cgPiBFeGNlbFBhY2thZ2UuTWF4Um93cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudEV4Y2VwdGlvbigiUm93IG51bWJlciBvdXQgb2YgYm91bmRzIikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuZXcgRXhjZWxSb3codGhpcywgcm93KTsKICAgICAgICAgICAgLy9yZXR1cm4gcjsKCQl9CgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBQcm92aWRlcyBhY2Nlc3MgdG8gYW4gaW5kaXZpZHVhbCBjb2x1bW4gd2l0aGluIHRoZSB3b3Jrc2hlZXQgc28geW91IGNhbiBzZXQgaXRzIHByb3BlcnRpZXMuCgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9ImNvbCI+VGhlIGNvbHVtbiBudW1iZXIgaW4gdGhlIHdvcmtzaGVldDwvcGFyYW0+CgkJLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KCQlwdWJsaWMgRXhjZWxDb2x1bW4gQ29sdW1uKGludCBjb2wpCgkJeyAgICAgICAgICAgIAogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpZiAoY29sIDwgMSB8fCBjb2wgPiBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudEV4Y2VwdGlvbigiQ29sdW1uIG51bWJlciBvdXQgb2YgYm91bmRzIikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBjb2x1bW4gPSBfdmFsdWVzLkdldFZhbHVlKDAsIGNvbCkgYXMgRXhjZWxDb2x1bW47CiAgICAgICAgICAgIGlmIChjb2x1bW4hPW51bGwpCiAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmIChjb2x1bW4uQ29sdW1uTWluICE9IGNvbHVtbi5Db2x1bW5NYXgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaW50IG1heENvbCA9IGNvbHVtbi5Db2x1bW5NYXg7CiAgICAgICAgICAgICAgICAgICAgY29sdW1uLkNvbHVtbk1heCA9IGNvbDsKICAgICAgICAgICAgICAgICAgICBFeGNlbENvbHVtbiBjb3B5ID0gQ29weUNvbHVtbihjb2x1bW4sIGNvbCArIDEsIG1heENvbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgcj0wLCBjPWNvbDsKICAgICAgICAgICAgICAgIGlmIChfdmFsdWVzLlByZXZDZWxsKHJlZiByLCByZWYgYykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY29sdW1uID0gX3ZhbHVlcy5HZXRWYWx1ZSgwLCBjKSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgICAgICAgICBpbnQgbWF4Q29sID0gY29sdW1uLkNvbHVtbk1heDsKICAgICAgICAgICAgICAgICAgICBpZiAobWF4Q29sID49IGNvbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbi5Db2x1bW5NYXggPSBjb2wtMTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1heENvbCA+IGNvbCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxDb2x1bW4gbmV3QyA9IENvcHlDb2x1bW4oY29sdW1uLCBjb2wgKyAxLCBtYXhDb2wpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDb3B5Q29sdW1uKGNvbHVtbiwgY29sLCBjb2wpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vZm9yZWFjaCAoRXhjZWxDb2x1bW4gY2hlY2tDb2x1bW4gaW4gX2NvbHVtbnMpCiAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgIC8vICAgIGlmIChjb2wgPiBjaGVja0NvbHVtbi5Db2x1bW5NaW4gJiYgY29sIDw9IGNoZWNrQ29sdW1uLkNvbHVtbk1heCkKICAgICAgICAgICAgICAgIC8vICAgIHsKICAgICAgICAgICAgICAgIC8vICAgICAgICBpbnQgbWF4Q29sID0gY2hlY2tDb2x1bW4uQ29sdW1uTWF4OwogICAgICAgICAgICAgICAgLy8gICAgICAgIGNoZWNrQ29sdW1uLkNvbHVtbk1heCA9IGNvbCAtIDE7CiAgICAgICAgICAgICAgICAvLyAgICAgICAgaWYgKG1heENvbCA+IGNvbCkKICAgICAgICAgICAgICAgIC8vICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgIEV4Y2VsQ29sdW1uIG5ld0MgPSBDb3B5Q29sdW1uKGNoZWNrQ29sdW1uLCBjb2wgKyAxLCBtYXhDb2wpOwogICAgICAgICAgICAgICAgLy8gICAgICAgIH0KICAgICAgICAgICAgICAgIC8vICAgICAgICByZXR1cm4gQ29weUNvbHVtbihjaGVja0NvbHVtbiwgY29sLGNvbCk7ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyAgICB9CiAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgIGNvbHVtbiA9IG5ldyBFeGNlbENvbHVtbih0aGlzLCBjb2wpOwogICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZSgwLCBjb2wsIGNvbHVtbik7CiAgICAgICAgICAgICAgICAvL19jb2x1bW5zLkFkZChjb2x1bW4pOwogICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY29sdW1uOwoJCX0KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSB3b3Jrc2hlZXQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgbmFtZSBvZiB0aGUgd29ya3NoZWV0PC9yZXR1cm5zPgogICAgICAgIHB1YmxpYyBvdmVycmlkZSBzdHJpbmcgVG9TdHJpbmcoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIE5hbWU7CiAgICAgICAgfQogICAgICAgIGludGVybmFsIEV4Y2VsQ29sdW1uIENvcHlDb2x1bW4oRXhjZWxDb2x1bW4gYywgaW50IGNvbCwgaW50IG1heENvbCkKICAgICAgICB7CiAgICAgICAgICAgIEV4Y2VsQ29sdW1uIG5ld0MgPSBuZXcgRXhjZWxDb2x1bW4odGhpcywgY29sKTsKICAgICAgICAgICAgbmV3Qy5Db2x1bW5NYXggPSBtYXhDb2wgPCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyA/IG1heENvbCA6IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zOwogICAgICAgICAgICBpZiAoYy5TdHlsZU5hbWUgIT0gIiIpCiAgICAgICAgICAgICAgICBuZXdDLlN0eWxlTmFtZSA9IGMuU3R5bGVOYW1lOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBuZXdDLlN0eWxlSUQgPSBjLlN0eWxlSUQ7CgogICAgICAgICAgICBuZXdDLk91dGxpbmVMZXZlbCA9IGMuT3V0bGluZUxldmVsOwogICAgICAgICAgICBuZXdDLlBob25ldGljID0gYy5QaG9uZXRpYzsKICAgICAgICAgICAgbmV3Qy5CZXN0Rml0ID0gYy5CZXN0Rml0OwogICAgICAgICAgICAvL19jb2x1bW5zLkFkZChuZXdDKTsKICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZSgwLCBjb2wsIG5ld0MpOwogICAgICAgICAgICBuZXdDLl93aWR0aCA9IGMuX3dpZHRoOwogICAgICAgICAgICBuZXdDLl9oaWRkZW4gPSBjLl9oaWRkZW47CiAgICAgICAgICAgIHJldHVybiBuZXdDOwogICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gTWFrZSB0aGUgY3VycmVudCB3b3Jrc2hlZXQgYWN0aXZlLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIHZvaWQgU2VsZWN0KCkKICAgICAgICB7CiAgICAgICAgICAgIFZpZXcuVGFiU2VsZWN0ZWQgPSB0cnVlOwogICAgICAgICAgICAvL1NlbGVjdChBZGRyZXNzLCB0cnVlKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBTZWxlY3RzIGEgcmFuZ2UgaW4gdGhlIHdvcmtzaGVldC4gVGhlIGFjdGl2ZSBjZWxsIGlzIHRoZSB0b3Btb3N0IGNlbGwuCiAgICAgICAgLy8vIE1ha2UgdGhlIGN1cnJlbnQgd29ya3NoZWV0IGFjdGl2ZS4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iQWRkcmVzcyI+QW4gYWRkcmVzcyByYW5nZTwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgU2VsZWN0KHN0cmluZyBBZGRyZXNzKQogICAgICAgIHsKICAgICAgICAgICAgU2VsZWN0KEFkZHJlc3MsIHRydWUpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNlbGVjdHMgYSByYW5nZSBpbiB0aGUgd29ya3NoZWV0LiBUaGUgYWN0aWNlIGNlbGwgaXMgdGhlIHRvcG1vc3QgY2VsbC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iQWRkcmVzcyI+QSByYW5nZSBvZiBjZWxsczwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJTZWxlY3RTaGVldCI+TWFrZSB0aGUgc2hlZXQgYWN0aXZlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTZWxlY3Qoc3RyaW5nIEFkZHJlc3MsIGJvb2wgU2VsZWN0U2hlZXQpCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpbnQgZnJvbUNvbCwgZnJvbVJvdywgdG9Db2wsIHRvUm93OwogICAgICAgICAgICAvL0dldCByb3dzIGFuZCBjb2x1bW5zIGFuZCB2YWxpZGF0ZSBhcyB3ZWxsCiAgICAgICAgICAgIEV4Y2VsQ2VsbEJhc2UuR2V0Um93Q29sRnJvbUFkZHJlc3MoQWRkcmVzcywgb3V0IGZyb21Sb3csIG91dCBmcm9tQ29sLCBvdXQgdG9Sb3csIG91dCB0b0NvbCk7CgogICAgICAgICAgICBpZiAoU2VsZWN0U2hlZXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFZpZXcuVGFiU2VsZWN0ZWQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFZpZXcuU2VsZWN0ZWRSYW5nZSA9IEFkZHJlc3M7CiAgICAgICAgICAgIFZpZXcuQWN0aXZlQ2VsbCA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhmcm9tUm93LCBmcm9tQ29sKTsgICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBTZWxlY3RzIGEgcmFuZ2UgaW4gdGhlIHdvcmtzaGVldC4gVGhlIGFjdGl2ZSBjZWxsIGlzIHRoZSB0b3Btb3N0IGNlbGwgb2YgdGhlIGZpcnN0IGFkZHJlc3MuCiAgICAgICAgLy8vIE1ha2UgdGhlIGN1cnJlbnQgd29ya3NoZWV0IGFjdGl2ZS4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iQWRkcmVzcyI+QW4gYWRkcmVzcyByYW5nZTwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgU2VsZWN0KEV4Y2VsQWRkcmVzcyBBZGRyZXNzKQogICAgICAgIHsKICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgU2VsZWN0KEFkZHJlc3MsIHRydWUpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNlbGVjdHMgYSByYW5nZSBpbiB0aGUgd29ya3NoZWV0LiBUaGUgYWN0aXZlIGNlbGwgaXMgdGhlIHRvcG1vc3QgY2VsbCBvZiB0aGUgZmlyc3QgYWRkcmVzcy4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iQWRkcmVzcyI+QSByYW5nZSBvZiBjZWxsczwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJTZWxlY3RTaGVldCI+TWFrZSB0aGUgc2hlZXQgYWN0aXZlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTZWxlY3QoRXhjZWxBZGRyZXNzIEFkZHJlc3MsIGJvb2wgU2VsZWN0U2hlZXQpCiAgICAgICAgewoKICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgaWYgKFNlbGVjdFNoZWV0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBWaWV3LlRhYlNlbGVjdGVkID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdHJpbmcgc2VsQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhBZGRyZXNzLlN0YXJ0LlJvdywgQWRkcmVzcy5TdGFydC5Db2x1bW4pICsgIjoiICsgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKEFkZHJlc3MuRW5kLlJvdywgQWRkcmVzcy5FbmQuQ29sdW1uKTsKICAgICAgICAgICAgaWYgKEFkZHJlc3MuQWRkcmVzc2VzICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBhIGluIEFkZHJlc3MuQWRkcmVzc2VzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNlbEFkZHJlc3MgKz0gIiAiICsgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGEuU3RhcnQuUm93LCBhLlN0YXJ0LkNvbHVtbikgKyAiOiIgKyBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoYS5FbmQuUm93LCBhLkVuZC5Db2x1bW4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIFZpZXcuU2VsZWN0ZWRSYW5nZSA9IHNlbEFkZHJlc3M7CiAgICAgICAgICAgIFZpZXcuQWN0aXZlQ2VsbCA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhBZGRyZXNzLlN0YXJ0LlJvdywgQWRkcmVzcy5TdGFydC5Db2x1bW4pOwogICAgICAgIH0KCgkJI3JlZ2lvbiBJbnNlcnRSb3cKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEluc2VydHMgYSBuZXcgcm93IGludG8gdGhlIHNwcmVhZHNoZWV0LiAgRXhpc3Rpbmcgcm93cyBiZWxvdyB0aGUgcG9zaXRpb24gYXJlIAogICAgICAgIC8vLyBzaGlmdGVkIGRvd24uICBBbGwgZm9ybXVsYSBhcmUgdXBkYXRlZCB0byB0YWtlIGFjY291bnQgb2YgdGhlIG5ldyByb3cuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd0Zyb20iPlRoZSBwb3NpdGlvbiBvZiB0aGUgbmV3IHJvdzwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dzIj5OdW1iZXIgb2Ygcm93cyB0byBpbnNlcnQ8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIEluc2VydFJvdyhpbnQgcm93RnJvbSwgaW50IHJvd3MpCiAgICAgICAgewogICAgICAgICAgICBJbnNlcnRSb3cocm93RnJvbSwgcm93cywgMCk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KCQkvLy8gSW5zZXJ0cyBhIG5ldyByb3cgaW50byB0aGUgc3ByZWFkc2hlZXQuICBFeGlzdGluZyByb3dzIGJlbG93IHRoZSBwb3NpdGlvbiBhcmUgCgkJLy8vIHNoaWZ0ZWQgZG93bi4gIEFsbCBmb3JtdWxhIGFyZSB1cGRhdGVkIHRvIHRha2UgYWNjb3VudCBvZiB0aGUgbmV3IHJvdy4KCQkvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icm93RnJvbSI+VGhlIHBvc2l0aW9uIG9mIHRoZSBuZXcgcm93PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd3MiPk51bWJlciBvZiByb3dzIHRvIGluc2VydC48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29weVN0eWxlc0Zyb21Sb3ciPkNvcHkgU3R5bGVzIGZyb20gdGhpcyByb3cuIEFwcGxpZWQgdG8gYWxsIGluc2VydGVkIHJvd3M8L3BhcmFtPgoJCXB1YmxpYyB2b2lkICBJbnNlcnRSb3coaW50IHJvd0Zyb20sIGludCByb3dzLCBpbnQgY29weVN0eWxlc0Zyb21Sb3cpCgkJewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgdmFyIGQgPSBEaW1lbnNpb247CgogICAgICAgICAgICBpZiAocm93RnJvbSA8IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IChuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCJyb3dGcm9tIGNhbid0IGJlIGxlc3NlciB0aGF0IDEiKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vQ2hlY2sgdGhhdCBjZWxscyBhcmVuJ3Qgc2hpZnRlZCBvdXRzaWRlIHRoZSBib3VuZHJpZXMKICAgICAgICAgICAgaWYgKGQgIT0gbnVsbCAmJiBkLkVuZC5Sb3cgPiByb3dGcm9tICYmIGQuRW5kLlJvdyArIHJvd3MgPiBFeGNlbFBhY2thZ2UuTWF4Um93cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24oIkNhbid0IGluc2VydC4gUm93cyB3aWxsIGJlIHNoaWZ0ZWQgb3V0c2lkZSB0aGUgYm91bmRyaWVzIG9mIHRoZSB3b3Jrc2hlZXQuIikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsb2NrICh0aGlzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdmFsdWVzLkluc2VydChyb3dGcm9tLCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgIF9mb3JtdWxhcy5JbnNlcnQocm93RnJvbSwgMCwgcm93cywgMCk7CiAgICAgICAgICAgICAgICBfc3R5bGVzLkluc2VydChyb3dGcm9tLCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgIF90eXBlcy5JbnNlcnQocm93RnJvbSwgMCwgcm93cywgMCk7CiAgICAgICAgICAgICAgICBfY29tbWVudHNTdG9yZS5JbnNlcnQocm93RnJvbSwgMCwgcm93cywgMCk7CiAgICAgICAgICAgICAgICBfaHlwZXJMaW5rcy5JbnNlcnQocm93RnJvbSwgMCwgcm93cywgMCk7CiAgICAgICAgICAgICAgICBfZmxhZ3MuSW5zZXJ0KHJvd0Zyb20sIDAsIHJvd3MsIDApOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBmIGluIF9zaGFyZWRGb3JtdWxhcy5WYWx1ZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGYuU3RhcnRSb3cgPj0gcm93RnJvbSkgZi5TdGFydFJvdyArPSByb3dzOwogICAgICAgICAgICAgICAgICAgIHZhciBhID0gbmV3IEV4Y2VsQWRkcmVzc0Jhc2UoZi5BZGRyZXNzKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYS5fZnJvbVJvdyA+PSByb3dGcm9tKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYS5fZnJvbVJvdyArPSByb3dzOwogICAgICAgICAgICAgICAgICAgICAgICBhLl90b1JvdyArPSByb3dzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChhLl90b1JvdyA+PSByb3dGcm9tKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYS5fdG9Sb3cgKz0gcm93czsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZi5BZGRyZXNzID0gRXhjZWxBZGRyZXNzQmFzZS5HZXRBZGRyZXNzKGEuX2Zyb21Sb3csIGEuX2Zyb21Db2wsIGEuX3RvUm93LCBhLl90b0NvbCk7CiAgICAgICAgICAgICAgICAgICAgZi5Gb3JtdWxhID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhmLkZvcm11bGEsIHJvd3MsIDAsIHJvd0Zyb20sIDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF9mb3JtdWxhcyk7CiAgICAgICAgICAgICAgICB3aGlsZSAoY3NlLk5leHQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY3NlLlZhbHVlIGlzIHN0cmluZykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzZS5WYWx1ZSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoY3NlLlZhbHVlLlRvU3RyaW5nKCksIHJvd3MsIDAsIHJvd0Zyb20sIDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBGaXhNZXJnZWRDZWxsc1Jvdyhyb3dGcm9tLCByb3dzLCBmYWxzZSk7CiAgICAgICAgICAgICAgICBpZiAoY29weVN0eWxlc0Zyb21Sb3cgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciBjc2VTID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPGludD4oX3N0eWxlcywgY29weVN0eWxlc0Zyb21Sb3csIDAsIGNvcHlTdHlsZXNGcm9tUm93LCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7IC8vRml4ZXMgaXNzdWUgMTUwNjggLCAxNTA5MAogICAgICAgICAgICAgICAgICAgIHdoaWxlKGNzZVMuTmV4dCgpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgciA9IDA7IHIgPCByb3dzOyByKyspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zdHlsZXMuU2V0VmFsdWUocm93RnJvbSArIHIsIGNzZVMuQ29sdW1uLCBjc2VTLlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0YmwgaW4gVGFibGVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRibC5BZGRyZXNzID0gdGJsLkFkZHJlc3MuQWRkUm93KHJvd0Zyb20sIHJvd3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gSW5zZXJ0cyBhIG5ldyBjb2x1bW4gaW50byB0aGUgc3ByZWFkc2hlZXQuICBFeGlzdGluZyBjb2x1bW5zIGJlbG93IHRoZSBwb3NpdGlvbiBhcmUgCiAgICAgICAgLy8vIHNoaWZ0ZWQgZG93bi4gIEFsbCBmb3JtdWxhIGFyZSB1cGRhdGVkIHRvIHRha2UgYWNjb3VudCBvZiB0aGUgbmV3IGNvbHVtbi4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1uRnJvbSI+VGhlIHBvc2l0aW9uIG9mIHRoZSBuZXcgY29sdW1uPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvbHVtbnMiPk51bWJlciBvZiBjb2x1bW5zIHRvIGluc2VydDwvcGFyYW0+ICAgICAgICAKICAgICAgICBwdWJsaWMgdm9pZCBJbnNlcnRDb2x1bW4oaW50IGNvbHVtbkZyb20sIGludCBjb2x1bW5zKQogICAgICAgIHsKICAgICAgICAgICAgSW5zZXJ0Q29sdW1uKGNvbHVtbkZyb20sIGNvbHVtbnMsIDApOwogICAgICAgIH0KICAgICAgICAvLy88c3VtbWFyeT4KICAgICAgICAvLy8gSW5zZXJ0cyBhIG5ldyBjb2x1bW4gaW50byB0aGUgc3ByZWFkc2hlZXQuICBFeGlzdGluZyBjb2x1bW4gdG8gdGhlIGxlZnQgYXJlIAogICAgICAgIC8vLyBzaGlmdGVkLiAgQWxsIGZvcm11bGEgYXJlIHVwZGF0ZWQgdG8gdGFrZSBhY2NvdW50IG9mIHRoZSBuZXcgY29sdW1uLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW5Gcm9tIj5UaGUgcG9zaXRpb24gb2YgdGhlIG5ldyBjb2x1bW48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1ucyI+TnVtYmVyIG9mIGNvbHVtbnMgdG8gaW5zZXJ0LjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb3B5U3R5bGVzRnJvbUNvbHVtbiI+Q29weSBTdHlsZXMgZnJvbSB0aGlzIGNvbHVtbi4gQXBwbGllZCB0byBhbGwgaW5zZXJ0ZWQgY29sdW1uczwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgSW5zZXJ0Q29sdW1uKGludCBjb2x1bW5Gcm9tLCBpbnQgY29sdW1ucywgaW50IGNvcHlTdHlsZXNGcm9tQ29sdW1uKQogICAgICAgIHsKICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgdmFyIGQgPSBEaW1lbnNpb247CgogICAgICAgICAgICBpZiAoY29sdW1uRnJvbSA8IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IChuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCJjb2x1bW5Gcm9tIGNhbid0IGJlIGxlc3NlciB0aGF0IDEiKSk7CiAgICAgICAgICAgIH0gICAgICAgICAgICAKICAgICAgICAgICAgLy9DaGVjayB0aGF0IGNlbGxzIGFyZW4ndCBzaGlmdGVkIG91dHNpZGUgdGhlIGJvdW5kcmllcwogICAgICAgICAgICBpZiAoZCAhPSBudWxsICYmIGQuRW5kLkNvbHVtbiA+IGNvbHVtbkZyb20gJiYgZC5FbmQuQ29sdW1uICsgY29sdW1ucyA+IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbigiQ2FuJ3QgaW5zZXJ0LiBDb2x1bW5zIHdpbGwgYmUgc2hpZnRlZCBvdXRzaWRlIHRoZSBib3VuZHJpZXMgb2YgdGhlIHdvcmtzaGVldC4iKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxvY2sgKHRoaXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF92YWx1ZXMuSW5zZXJ0KDAsIGNvbHVtbkZyb20sIDAsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2Zvcm11bGFzLkluc2VydCgwLCBjb2x1bW5Gcm9tLCAwLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9zdHlsZXMuSW5zZXJ0KDAsIGNvbHVtbkZyb20sIDAsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX3R5cGVzLkluc2VydCgwLCBjb2x1bW5Gcm9tLCAwLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9jb21tZW50c1N0b3JlLkluc2VydCgwLCBjb2x1bW5Gcm9tLCAwLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9oeXBlckxpbmtzLkluc2VydCgwLCBjb2x1bW5Gcm9tLCAwLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9mbGFncy5JbnNlcnQoMCwgY29sdW1uRnJvbSwgMCwgY29sdW1ucyk7CgogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGYgaW4gX3NoYXJlZEZvcm11bGFzLlZhbHVlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZi5TdGFydENvbCA+PSBjb2x1bW5Gcm9tKSBmLlN0YXJ0Q29sICs9IGNvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgdmFyIGEgPSBuZXcgRXhjZWxBZGRyZXNzQmFzZShmLkFkZHJlc3MpOwogICAgICAgICAgICAgICAgICAgIGlmIChhLl9mcm9tQ29sID49IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhLl9mcm9tQ29sICs9IGNvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgICAgIGEuX3RvQ29sICs9IGNvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGEuX3RvQ29sID49IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhLl90b0NvbCArPSBjb2x1bW5zOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBmLkFkZHJlc3MgPSBFeGNlbEFkZHJlc3NCYXNlLkdldEFkZHJlc3MoYS5fZnJvbVJvdywgYS5fZnJvbUNvbCwgYS5fdG9Sb3csIGEuX3RvQ29sKTsKICAgICAgICAgICAgICAgICAgICBmLkZvcm11bGEgPSBFeGNlbENlbGxCYXNlLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKGYuRm9ybXVsYSwgMCwgY29sdW1ucywgMCwgY29sdW1uRnJvbSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF9mb3JtdWxhcyk7CiAgICAgICAgICAgICAgICB3aGlsZSAoY3NlLk5leHQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY3NlLlZhbHVlIGlzIHN0cmluZykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzZS5WYWx1ZSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoY3NlLlZhbHVlLlRvU3RyaW5nKCksIDAsIGNvbHVtbnMsIDAsIGNvbHVtbkZyb20pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBGaXhNZXJnZWRDZWxsc0NvbHVtbihjb2x1bW5Gcm9tLCBjb2x1bW5zLCBmYWxzZSk7CgogICAgICAgICAgICAgICAgdmFyIGNzZWMgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfdmFsdWVzLCAwLCAxLCAwLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgICAgICB2YXIgbHN0ID0gbmV3IExpc3Q8RXhjZWxDb2x1bW4+KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgY29sIGluIGNzZWMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbCBpcyBFeGNlbENvbHVtbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxzdC5BZGQoKEV4Y2VsQ29sdW1uKWNvbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBsc3QuQ291bnQtMTsgaSA+PSAwOyBpLS0pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGMgPSBsc3RbaV07CiAgICAgICAgICAgICAgICAgICAgaWYgKGMuX2NvbHVtbk1pbiA+PSBjb2x1bW5Gcm9tKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMuX2NvbHVtbk1pbiArIGNvbHVtbnMgPD0gRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuX2NvbHVtbk1pbiArPSBjb2x1bW5zOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5fY29sdW1uTWluID0gRXhjZWxQYWNrYWdlLk1heENvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjLl9jb2x1bW5NYXggKyBjb2x1bW5zIDw9IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLl9jb2x1bW5NYXggKz0gY29sdW1uczsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuX2NvbHVtbk1heCA9IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGMuX2NvbHVtbk1heCA+PSBjb2x1bW5Gcm9tKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNjID0gYy5fY29sdW1uTWF4IC0gY29sdW1uRnJvbTsKICAgICAgICAgICAgICAgICAgICAgICAgYy5fY29sdW1uTWF4ID0gY29sdW1uRnJvbSAtIDE7CiAgICAgICAgICAgICAgICAgICAgICAgIENvcHlDb2x1bW4oYywgY29sdW1uRnJvbSArIGNvbHVtbnMsIGNvbHVtbkZyb20gKyBjb2x1bW5zICsgY2MpOwogICAgICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICBpZiAoY29weVN0eWxlc0Zyb21Db2x1bW4gPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGMgPSAwOyBjIDwgY29sdW1uczsgYysrKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbCA9IHRoaXMuQ29sdW1uKGNvbHVtbkZyb20gKyBjKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29sLlN0eWxlSUQgPSB0aGlzLkNvbHVtbihjb3B5U3R5bGVzRnJvbUNvbHVtbikuU3R5bGVJRDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL0FkanVzdCB0YWJsZXMKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0YmwgaW4gVGFibGVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjb2x1bW5Gcm9tID4gdGJsLkFkZHJlc3MuU3RhcnQuQ29sdW1uICYmIGNvbHVtbkZyb20gPD0gdGJsLkFkZHJlc3MuRW5kLkNvbHVtbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIEluc2VydFRhYmxlQ29sdW1ucyhjb2x1bW5Gcm9tLCBjb2x1bW5zLCB0YmwpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGJsLkFkZHJlc3M9dGJsLkFkZHJlc3MuQWRkQ29sdW1uKGNvbHVtbkZyb20sIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHN0YXRpYyB2b2lkIEluc2VydFRhYmxlQ29sdW1ucyhpbnQgY29sdW1uRnJvbSwgaW50IGNvbHVtbnMsIEV4Y2VsVGFibGUgdGJsKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIG5vZGUgPSB0YmwuQ29sdW1uc1swXS5Ub3BOb2RlLlBhcmVudE5vZGU7CiAgICAgICAgICAgIHZhciBpeCA9IGNvbHVtbkZyb20gLSB0YmwuQWRkcmVzcy5TdGFydC5Db2x1bW4gLSAxOwogICAgICAgICAgICB2YXIgaW5zUG9zID0gbm9kZS5DaGlsZE5vZGVzW2l4XTsKICAgICAgICAgICAgaXggKz0gMjsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb2x1bW5zOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBuYW1lID0KICAgICAgICAgICAgICAgICAgICB0YmwuQ29sdW1ucy5HZXRVbmlxdWVOYW1lKHN0cmluZy5Gb3JtYXQoIkNvbHVtbnswfSIsCiAgICAgICAgICAgICAgICAgICAgICAgIChpeCsrKS5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSkpOwogICAgICAgICAgICAgICAgWG1sRWxlbWVudCB0YWJsZUNvbHVtbiA9CiAgICAgICAgICAgICAgICAgICAgKFhtbEVsZW1lbnQpIHRibC5UYWJsZVhtbC5DcmVhdGVOb2RlKFhtbE5vZGVUeXBlLkVsZW1lbnQsICJ0YWJsZUNvbHVtbiIsIEV4Y2VsUGFja2FnZS5zY2hlbWFNYWluKTsKICAgICAgICAgICAgICAgIHRhYmxlQ29sdW1uLlNldEF0dHJpYnV0ZSgiaWQiLCAodGJsLkNvbHVtbnMuQ291bnQgKyBpICsgMSkuVG9TdHJpbmcoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkpOwogICAgICAgICAgICAgICAgdGFibGVDb2x1bW4uU2V0QXR0cmlidXRlKCJuYW1lIiwgbmFtZSk7CiAgICAgICAgICAgICAgICBpbnNQb3MgPSBub2RlLkluc2VydEFmdGVyKHRhYmxlQ29sdW1uLCBpbnNQb3MpOwogICAgICAgICAgICB9IC8vQ3JlYXRlIHRibCBDb2x1bW4KICAgICAgICAgICAgdGJsLl9jb2xzID0gbmV3IEV4Y2VsVGFibGVDb2x1bW5Db2xsZWN0aW9uKHRibCk7CiAgICAgICAgfQoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEFkZHMgYSB2YWx1ZSB0byB0aGUgcm93IG9mIG1lcmdlZCBjZWxscyB0byBmaXggZm9yIGluc2VydHMgb3IgZGVsZXRlcwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3ciPjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dzIj48L3BhcmFtPiAKICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlbGV0ZSI+PC9wYXJhbT4KICAgICAgICBwcml2YXRlIHZvaWQgRml4TWVyZ2VkQ2VsbHNSb3coaW50IHJvdywgaW50IHJvd3MsIGJvb2wgZGVsZXRlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGRlbGV0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLl9jZWxscy5EZWxldGUocm93LCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF9tZXJnZWRDZWxscy5fY2VsbHMuSW5zZXJ0KHJvdywgMCwgcm93cywgMCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIExpc3Q8aW50PiByZW1vdmVJbmRleCA9IG5ldyBMaXN0PGludD4oKTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBfbWVyZ2VkQ2VsbHMuQ291bnQ7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eSggX21lcmdlZENlbGxzW2ldKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFeGNlbEFkZHJlc3NCYXNlIGFkZHIgPSBuZXcgRXhjZWxBZGRyZXNzQmFzZShfbWVyZ2VkQ2VsbHNbaV0pLCBuZXdBZGRyOwogICAgICAgICAgICAgICAgICAgIGlmIChkZWxldGUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdBZGRyID0gYWRkci5EZWxldGVSb3cocm93LCByb3dzKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0FkZHIgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlSW5kZXguQWRkKGkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3QWRkciA9IGFkZHIuQWRkUm93KHJvdywgcm93cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdBZGRyLkFkZHJlc3MgIT0gYWRkci5BZGRyZXNzKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgIF9tZXJnZWRDZWxscy5fY2VsbHMuSW5zZXJ0KHJvdywgMCwgcm93cywgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuU2V0SW5kZXgobmV3QWRkciwgaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChuZXdBZGRyLkFkZHJlc3MgIT0gYWRkci5BZGRyZXNzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLkxpc3RbaV0gPSBuZXdBZGRyLl9hZGRyZXNzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGludCBpID0gcmVtb3ZlSW5kZXguQ291bnQgLSAxOyBpID49IDA7IGktLSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLkxpc3QuUmVtb3ZlQXQocmVtb3ZlSW5kZXhbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQWRkcyBhIHZhbHVlIHRvIHRoZSByb3cgb2YgbWVyZ2VkIGNlbGxzIHRvIGZpeCBmb3IgaW5zZXJ0cyBvciBkZWxldGVzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvbHVtbiI+PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvbHVtbnMiPjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZWxldGUiPjwvcGFyYW0+CiAgICAgICAgcHJpdmF0ZSB2b2lkIEZpeE1lcmdlZENlbGxzQ29sdW1uKGludCBjb2x1bW4sIGludCBjb2x1bW5zLCBib29sIGRlbGV0ZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChkZWxldGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF9tZXJnZWRDZWxscy5fY2VsbHMuRGVsZXRlKDAsIGNvbHVtbiwgMCwgY29sdW1ucyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuX2NlbGxzLkluc2VydCgwLCBjb2x1bW4sIDAsIGNvbHVtbnMpOyAgICAgICAgICAgICAgICAKICAgICAgICAgICAgfQogICAgICAgICAgICBMaXN0PGludD4gcmVtb3ZlSW5kZXggPSBuZXcgTGlzdDxpbnQ+KCk7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgX21lcmdlZENlbGxzLkNvdW50OyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghc3RyaW5nLklzTnVsbE9yRW1wdHkoX21lcmdlZENlbGxzW2ldKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFeGNlbEFkZHJlc3NCYXNlIGFkZHIgPSBuZXcgRXhjZWxBZGRyZXNzQmFzZShfbWVyZ2VkQ2VsbHNbaV0pLCBuZXdBZGRyOwogICAgICAgICAgICAgICAgICAgIGlmIChkZWxldGUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdBZGRyID0gYWRkci5EZWxldGVDb2x1bW4oY29sdW1uLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0FkZHIgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlSW5kZXguQWRkKGkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3QWRkciA9IGFkZHIuQWRkQ29sdW1uKGNvbHVtbiwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdBZGRyLkFkZHJlc3MgIT0gYWRkci5BZGRyZXNzKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuU2V0SW5kZXgobmV3QWRkciwgaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChuZXdBZGRyLkFkZHJlc3MgIT0gYWRkci5BZGRyZXNzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLkxpc3RbaV0gPSBuZXdBZGRyLl9hZGRyZXNzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGludCBpID0gcmVtb3ZlSW5kZXguQ291bnQgLSAxOyBpID49IDA7IGktLSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLkxpc3QuUmVtb3ZlQXQocmVtb3ZlSW5kZXhbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBGaXhTaGFyZWRGb3JtdWxhc1Jvd3MoaW50IHBvc2l0aW9uLCBpbnQgcm93cykKICAgICAgICB7CiAgICAgICAgICAgIExpc3Q8Rm9ybXVsYXM+IGFkZGVkID0gbmV3IExpc3Q8Rm9ybXVsYXM+KCk7CiAgICAgICAgICAgIExpc3Q8Rm9ybXVsYXM+IGRlbGV0ZWQgPSBuZXcgTGlzdDxGb3JtdWxhcz4oKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKGludCBpZCBpbiBfc2hhcmVkRm9ybXVsYXMuS2V5cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGYgPSBfc2hhcmVkRm9ybXVsYXNbaWRdOwogICAgICAgICAgICAgICAgaW50IGZyb21Db2wsIGZyb21Sb3csIHRvQ29sLCB0b1JvdzsKCiAgICAgICAgICAgICAgICBFeGNlbENlbGxCYXNlLkdldFJvd0NvbEZyb21BZGRyZXNzKGYuQWRkcmVzcywgb3V0IGZyb21Sb3csIG91dCBmcm9tQ29sLCBvdXQgdG9Sb3csIG91dCB0b0NvbCk7CiAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPj0gZnJvbVJvdyAmJiBwb3NpdGlvbisoTWF0aC5BYnMocm93cykpIDw9IHRvUm93KSAvL0luc2VydC9kZWxldGUgaXMgd2hpdGhpbiB0aGUgc2hhcmUgZm9ybXVsYSBhZGRyZXNzCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJvd3MgPiAwKSAvL0luc2VydAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZi5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZyb21Sb3csIGZyb21Db2wpICsgIjoiICsgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKHBvc2l0aW9uIC0gMSwgdG9Db2wpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodG9Sb3cgIT0gZnJvbVJvdykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybXVsYXMgbmV3RiA9IG5ldyBGb3JtdWxhcyhTb3VyY2VDb2RlVG9rZW5pemVyLkRlZmF1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Ri5TdGFydENvbCA9IGYuU3RhcnRDb2w7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGLlN0YXJ0Um93ID0gcG9zaXRpb24gKyByb3dzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Ri5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKHBvc2l0aW9uICsgcm93cywgZnJvbUNvbCkgKyAiOiIgKyBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3ModG9Sb3cgKyByb3dzLCB0b0NvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGLkZvcm11bGEgPSBFeGNlbENlbGxCYXNlLlRyYW5zbGF0ZUZyb21SMUMxKEV4Y2VsQ2VsbEJhc2UuVHJhbnNsYXRlVG9SMUMxKGYuRm9ybXVsYSwgZi5TdGFydFJvdywgZi5TdGFydENvbCksIHBvc2l0aW9uLCBmLlN0YXJ0Q29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZGVkLkFkZChuZXdGKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZnJvbVJvdyAtIHJvd3MgPCB0b1JvdykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZi5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZyb21Sb3csIGZyb21Db2wsIHRvUm93K3Jvd3MsIHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYuQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhmcm9tUm93LCBmcm9tQ29sKSArICI6IiArIEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyh0b1JvdyArIHJvd3MsIHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBvc2l0aW9uIDw9IHRvUm93KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChyb3dzID4gMCkgLy9JbnNlcnQgYmVmb3JlIHNoaWZ0IGRvd24KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGYuU3RhcnRSb3cgKz0gcm93czsKICAgICAgICAgICAgICAgICAgICAgICAgLy9mLkZvcm11bGEgPSBFeGNlbENlbGwuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoZi5Gb3JtdWxhLCByb3dzLCAwLCBwb3NpdGlvbiwgMCk7IC8vUmVjYWxjIHRoZSBjZWxscyBwb3NpdGlvbnMKICAgICAgICAgICAgICAgICAgICAgICAgZi5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZyb21Sb3cgKyByb3dzLCBmcm9tQ29sKSArICI6IiArIEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyh0b1JvdyArIHJvd3MsIHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9DZWxsc1tmLkFkZHJlc3NdLlNldFNoYXJlZEZvcm11bGFJRChpbnQuTWluVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPD0gZnJvbVJvdyAmJiBwb3NpdGlvbiArIE1hdGguQWJzKHJvd3MpID4gdG9Sb3cpICAvL0RlbGV0ZSB0aGUgZm9ybXVsYSAKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlZC5BZGQoZik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1JvdyA9IHRvUm93ICsgcm93cyA8IHBvc2l0aW9uIC0gMSA/IHBvc2l0aW9uIC0gMSA6IHRvUm93ICsgcm93czsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA8PSBmcm9tUm93KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21Sb3cgPSBmcm9tUm93ICsgcm93cyA8IHBvc2l0aW9uID8gcG9zaXRpb24gOiBmcm9tUm93ICsgcm93czsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoZnJvbVJvdywgZnJvbUNvbCwgdG9Sb3csIHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIENlbGxzW2YuQWRkcmVzc10uU2V0U2hhcmVkRm9ybXVsYUlEKGYuSW5kZXgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9mLlN0YXJ0Um93ID0gZnJvbVJvdzsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2YuRm9ybXVsYSA9IEV4Y2VsQ2VsbC5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhmLkZvcm11bGEsIHJvd3MsIDAsIHBvc2l0aW9uLCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgQWRkRm9ybXVsYXMoYWRkZWQsIHBvc2l0aW9uLCByb3dzKTsKCiAgICAgICAgICAgIC8vUmVtb3ZlIGZvcm11bGFzCiAgICAgICAgICAgIGZvcmVhY2ggKEZvcm11bGFzIGYgaW4gZGVsZXRlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzLlJlbW92ZShmLkluZGV4KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9GaXggRm9ybXVsYXMKICAgICAgICAgICAgYWRkZWQgPSBuZXcgTGlzdDxGb3JtdWxhcz4oKTsKICAgICAgICAgICAgZm9yZWFjaCAoaW50IGlkIGluIF9zaGFyZWRGb3JtdWxhcy5LZXlzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgZiA9IF9zaGFyZWRGb3JtdWxhc1tpZF07CiAgICAgICAgICAgICAgICBVcGRhdGVTaGFyZWRGb3JtdWxhUm93KHJlZiBmLCBwb3NpdGlvbiwgcm93cywgcmVmIGFkZGVkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBBZGRGb3JtdWxhcyhhZGRlZCwgcG9zaXRpb24sIHJvd3MpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIEFkZEZvcm11bGFzKExpc3Q8Rm9ybXVsYXM+IGFkZGVkLCBpbnQgcG9zaXRpb24sIGludCByb3dzKQogICAgICAgIHsKICAgICAgICAgICAgLy9BZGQgbmV3IGZvcm11bGFzCiAgICAgICAgICAgIGZvcmVhY2ggKEZvcm11bGFzIGYgaW4gYWRkZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGYuSW5kZXggPSBHZXRNYXhTaGFyZUZ1bmN0aW9uSW5kZXgoZmFsc2UpOwogICAgICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzLkFkZChmLkluZGV4LCBmKTsKICAgICAgICAgICAgICAgIENlbGxzW2YuQWRkcmVzc10uU2V0U2hhcmVkRm9ybXVsYUlEKGYuSW5kZXgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgVXBkYXRlU2hhcmVkRm9ybXVsYVJvdyhyZWYgRm9ybXVsYXMgZm9ybXVsYSwgaW50IHN0YXJ0Um93LCBpbnQgcm93cywgcmVmIExpc3Q8Rm9ybXVsYXM+IG5ld0Zvcm11bGFzKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGZyb21Sb3csZnJvbUNvbCwgdG9Sb3csIHRvQ29sOwogICAgICAgICAgICBpbnQgbmV3Rm9ybXVsYXNDb3VudCA9IG5ld0Zvcm11bGFzLkNvdW50OwogICAgICAgICAgICBFeGNlbENlbGxCYXNlLkdldFJvd0NvbEZyb21BZGRyZXNzKGZvcm11bGEuQWRkcmVzcywgb3V0IGZyb21Sb3csIG91dCBmcm9tQ29sLCBvdXQgdG9Sb3csIG91dCB0b0NvbCk7CiAgICAgICAgICAgIC8vaW50IHJlZlNwbGl0cyA9IFJlZ2V4LlNwbGl0KGZvcm11bGEuRm9ybXVsYSwgIiNSRUYhIikuR2V0VXBwZXJCb3VuZCgwKTsKICAgICAgICAgICAgc3RyaW5nIGZvcm11YWxSMUMxOwogICAgICAgICAgICBpZiAocm93cyA+IDAgfHwgZnJvbVJvdyA8PSBzdGFydFJvdykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9ybXVhbFIxQzEgPSBFeGNlbFJhbmdlQmFzZS5UcmFuc2xhdGVUb1IxQzEoZm9ybXVsYS5Gb3JtdWxhLCBmb3JtdWxhLlN0YXJ0Um93LCBmb3JtdWxhLlN0YXJ0Q29sKTsKICAgICAgICAgICAgICAgIGZvcm11bGEuRm9ybXVsYSA9IEV4Y2VsUmFuZ2VCYXNlLlRyYW5zbGF0ZUZyb21SMUMxKGZvcm11YWxSMUMxLCBmcm9tUm93LCBmb3JtdWxhLlN0YXJ0Q29sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvcm11YWxSMUMxID0gRXhjZWxSYW5nZUJhc2UuVHJhbnNsYXRlVG9SMUMxKGZvcm11bGEuRm9ybXVsYSwgZm9ybXVsYS5TdGFydFJvdy1yb3dzLCBmb3JtdWxhLlN0YXJ0Q29sKTsKICAgICAgICAgICAgICAgIGZvcm11bGEuRm9ybXVsYSA9IEV4Y2VsUmFuZ2VCYXNlLlRyYW5zbGF0ZUZyb21SMUMxKGZvcm11YWxSMUMxLCBmb3JtdWxhLlN0YXJ0Um93LCBmb3JtdWxhLlN0YXJ0Q29sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL2Jvb2wgaXNSZWYgPSBmYWxzZTsKICAgICAgICAgICAgLy9Gb3JtdWxhcyByZXN0Rm9ybXVsYT1mb3JtdWxhOwogICAgICAgICAgICBzdHJpbmcgcHJldkZvcm11YWxSMUMxID0gZm9ybXVhbFIxQzE7CiAgICAgICAgICAgIGZvciAoaW50IHJvdyA9IGZyb21Sb3c7IHJvdyA8PSB0b1Jvdzsgcm93KyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGNvbCA9IGZyb21Db2w7IGNvbCA8PSB0b0NvbDsgY29sKyspCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RyaW5nIG5ld0Zvcm11bGE7CiAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGN1cnJlbnRGb3JtdWxhUjFDMTsKICAgICAgICAgICAgICAgICAgICBpZiAocm93cyA+IDAgfHwgcm93IDwgc3RhcnRSb3cpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdGb3JtdWxhID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhFeGNlbENlbGxCYXNlLlRyYW5zbGF0ZUZyb21SMUMxKGZvcm11YWxSMUMxLCByb3csIGNvbCksIHJvd3MsIDAsIHN0YXJ0Um93LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudEZvcm11bGFSMUMxID0gRXhjZWxSYW5nZUJhc2UuVHJhbnNsYXRlVG9SMUMxKG5ld0Zvcm11bGEsIHJvdywgY29sKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3Rm9ybXVsYSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoRXhjZWxDZWxsQmFzZS5UcmFuc2xhdGVGcm9tUjFDMShmb3JtdWFsUjFDMSwgcm93LXJvd3MsIGNvbCksIHJvd3MsIDAsIHN0YXJ0Um93LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudEZvcm11bGFSMUMxID0gRXhjZWxSYW5nZUJhc2UuVHJhbnNsYXRlVG9SMUMxKG5ld0Zvcm11bGEsIHJvdywgY29sKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRGb3JtdWxhUjFDMSAhPSBwcmV2Rm9ybXVhbFIxQzEpIC8vbmV3Rm9ybXVsYS5Db250YWlucygiI1JFRiEiKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgKHJlZlNwbGl0cyA9PSAwIHx8IFJlZ2V4LlNwbGl0KG5ld0Zvcm11bGEsICIjUkVGISIpLkdldFVwcGVyQm91bmQoMCkgIT0gcmVmU3BsaXRzKQogICAgICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAgICAgLy9pc1JlZiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyb3cgPT0gZnJvbVJvdyAmJiBjb2wgPT0gZnJvbUNvbCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybXVsYS5Gb3JtdWxhID0gbmV3Rm9ybXVsYTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdGb3JtdWxhcy5Db3VudCA9PSBuZXdGb3JtdWxhc0NvdW50KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm11bGEuQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhmb3JtdWxhLlN0YXJ0Um93LCBmb3JtdWxhLlN0YXJ0Q29sLCByb3cgLSAxLCBjb2wpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0Zvcm11bGFzW25ld0Zvcm11bGFzLkNvdW50IC0gMV0uQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLlN0YXJ0Um93LCBuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLlN0YXJ0Q29sLCByb3cgLSAxLCBjb2wpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlZkZvcm11bGEgPSBuZXcgRm9ybXVsYXMoU291cmNlQ29kZVRva2VuaXplci5EZWZhdWx0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZkZvcm11bGEuRm9ybXVsYSA9IG5ld0Zvcm11bGE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZGb3JtdWxhLlN0YXJ0Um93ID0gcm93OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmRm9ybXVsYS5TdGFydENvbCA9IGNvbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0Zvcm11bGFzLkFkZChyZWZGb3JtdWxhKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc3RGb3JtdWxhID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZGb3JtdWFsUjFDMSA9IGN1cnJlbnRGb3JtdWxhUjFDMTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gICAgZWxzZQogICAgICAgICAgICAgICAgICAgIC8vICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgaXNSZWYgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAvLyAgICB9CiAgICAgICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgICAgICAgICAgLy9lbHNlCiAgICAgICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAgICAgLy8gICAgaXNSZWYgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgICAgICAvL2lmIChyZXN0Rm9ybXVsYT09bnVsbCkKICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiAobmV3Rm9ybXVsYXMuQ291bnQgPT0gbmV3Rm9ybXVsYXNDb3VudCkKICAgICAgICAgICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgIGZvcm11bGEuQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhmb3JtdWxhLlN0YXJ0Um93LCBmb3JtdWxhLlN0YXJ0Q29sLCByb3cgLSAxLCBjb2wpOwogICAgICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgICAgICAgICAgLy9lbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIC8vewovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MobmV3Rm9ybXVsYXNbbmV3Rm9ybXVsYXMuQ291bnQgLSAxXS5TdGFydFJvdywgbmV3Rm9ybXVsYXNbMF0uU3RhcnRDb2wsIHJvdyAtIDEsIGNvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy9yZXN0Rm9ybXVsYSA9IG5ldyBGb3JtdWxhcygpOwogICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc3RGb3JtdWxhLkZvcm11bGEgPSBuZXdGb3JtdWxhOwogICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc3RGb3JtdWxhLlN0YXJ0Um93ID0gcm93OwogICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc3RGb3JtdWxhLlN0YXJ0Q29sID0gY29sOwogICAgICAgICAgICAgICAgICAgICAgICAvL25ld0Zvcm11bGFzLkFkZChyZXN0Rm9ybXVsYSk7CiAgICAgICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJvd3MgPCAwICYmIGZvcm11bGEuU3RhcnRSb3cgPiBzdGFydFJvdykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGZvcm11bGEuU3RhcnRSb3cgKyByb3dzIDwgc3RhcnRSb3cpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9ybXVsYS5TdGFydFJvdyA9IHN0YXJ0Um93OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvcm11bGEuU3RhcnRSb3cgKz0gcm93czsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobmV3Rm9ybXVsYXMuQ291bnQgPiBuZXdGb3JtdWxhc0NvdW50KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MobmV3Rm9ybXVsYXNbbmV3Rm9ybXVsYXMuQ291bnQgLSAxXS5TdGFydFJvdywgbmV3Rm9ybXVsYXNbbmV3Rm9ybXVsYXMuQ291bnQgLSAxXS5TdGFydENvbCwgdG9Sb3csIHRvQ29sKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAjZW5kcmVnaW9uCgogICAgICAgICNyZWdpb24gRGVsZXRlUm93CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBEZWxldGUgdGhlIHNwZWNpZmllZCByb3cgZnJvbSB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3ciPkEgcm93IHRvIGJlIGRlbGV0ZWQ8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIERlbGV0ZVJvdyhpbnQgcm93KQogICAgICAgIHsKICAgICAgICAgICAgRGVsZXRlUm93KHJvdywgMSk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRGVsZXRlIHRoZSBzcGVjaWZpZWQgcm93IGZyb20gdGhlIHdvcmtzaGVldC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icm93RnJvbSI+VGhlIHN0YXJ0IHJvdzwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dzIj5OdW1iZXIgb2Ygcm93cyB0byBkZWxldGU8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIERlbGV0ZVJvdyhpbnQgcm93RnJvbSwgaW50IHJvd3MpCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpZiAocm93RnJvbSA8IDEgfHwgcm93RnJvbSArIHJvd3MgPiBFeGNlbFBhY2thZ2UuTWF4Um93cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cobmV3IEFyZ3VtZW50RXhjZXB0aW9uKCJSb3cgb3V0IG9mIHJhbmdlLiBTcGFucyBmcm9tIDEgdG8gIiArIEV4Y2VsUGFja2FnZS5NYXhSb3dzLlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbG9jayAodGhpcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3ZhbHVlcy5EZWxldGUocm93RnJvbSwgMCwgcm93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAgICAgX3R5cGVzLkRlbGV0ZShyb3dGcm9tLCAwLCByb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgICAgICBfZm9ybXVsYXMuRGVsZXRlKHJvd0Zyb20sIDAsIHJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9zdHlsZXMuRGVsZXRlKHJvd0Zyb20sIDAsIHJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9mbGFncy5EZWxldGUocm93RnJvbSwgMCwgcm93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAgICAgX2NvbW1lbnRzU3RvcmUuRGVsZXRlKHJvd0Zyb20sIDAsIHJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9oeXBlckxpbmtzLkRlbGV0ZShyb3dGcm9tLCAwLCByb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CgogICAgICAgICAgICAgICAgQWRqdXN0Rm9ybXVsYXNSb3cocm93RnJvbSwgcm93cyk7CiAgICAgICAgICAgICAgICBGaXhNZXJnZWRDZWxsc1Jvdyhyb3dGcm9tLCByb3dzLCB0cnVlKTsKCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgdGJsIGluIFRhYmxlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0YmwuQWRkcmVzcyA9IHRibC5BZGRyZXNzLkRlbGV0ZVJvdyhyb3dGcm9tLCByb3dzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIERlbGV0ZSB0aGUgc3BlY2lmaWVkIGNvbHVtbiBmcm9tIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvbHVtbiI+VGhlIGNvbHVtbiB0byBiZSBkZWxldGVkPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBEZWxldGVDb2x1bW4oaW50IGNvbHVtbikKICAgICAgICB7CiAgICAgICAgICAgIERlbGV0ZUNvbHVtbihjb2x1bW4sMSk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRGVsZXRlIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZyb20gdGhlIHdvcmtzaGVldC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1uRnJvbSI+VGhlIHN0YXJ0IGNvbHVtbjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW5zIj5OdW1iZXIgb2YgY29sdW1ucyB0byBkZWxldGU8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIERlbGV0ZUNvbHVtbihpbnQgY29sdW1uRnJvbSwgaW50IGNvbHVtbnMpCiAgICAgICAgewogICAgICAgICAgICBpZiAoY29sdW1uRnJvbSA8IDEgfHwgY29sdW1uRnJvbSArIGNvbHVtbnMgPiBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudEV4Y2VwdGlvbigiQ29sdW1uIG91dCBvZiByYW5nZS4gU3BhbnMgZnJvbSAxIHRvICIgKyBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucy5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxvY2sgKHRoaXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBjb2wgPSBfdmFsdWVzLkdldFZhbHVlKDAsIGNvbHVtbkZyb20pIGFzIEV4Y2VsQ29sdW1uOwogICAgICAgICAgICAgICAgaWYgKGNvbCA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciByID0gMDsgCiAgICAgICAgICAgICAgICAgICAgdmFyIGMgPSBjb2x1bW5Gcm9tOwogICAgICAgICAgICAgICAgICAgIGlmKF92YWx1ZXMuUHJldkNlbGwocmVmIHIscmVmIGMpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29sID0gX3ZhbHVlcy5HZXRWYWx1ZSgwLCBjKSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoY29sLl9jb2x1bW5NYXggPj0gY29sdW1uRnJvbSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLkNvbHVtbk1heD1jb2x1bW5Gcm9tLTE7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgX3ZhbHVlcy5EZWxldGUoMCwgY29sdW1uRnJvbSwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX3R5cGVzLkRlbGV0ZSgwLCBjb2x1bW5Gcm9tLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgY29sdW1ucyk7CiAgICAgICAgICAgICAgICBfZm9ybXVsYXMuRGVsZXRlKDAsIGNvbHVtbkZyb20sIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9zdHlsZXMuRGVsZXRlKDAsIGNvbHVtbkZyb20sIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9mbGFncy5EZWxldGUoMCwgY29sdW1uRnJvbSwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2NvbW1lbnRzU3RvcmUuRGVsZXRlKDAsIGNvbHVtbkZyb20sIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9oeXBlckxpbmtzLkRlbGV0ZSgwLCBjb2x1bW5Gcm9tLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgY29sdW1ucyk7CgogICAgICAgICAgICAgICAgQWRqdXN0Rm9ybXVsYXNDb2x1bW4oY29sdW1uRnJvbSwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICBGaXhNZXJnZWRDZWxsc0NvbHVtbihjb2x1bW5Gcm9tLCBjb2x1bW5zLCB0cnVlKTsKCiAgICAgICAgICAgICAgICB2YXIgY3NlYyA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF92YWx1ZXMsIDAsIGNvbHVtbkZyb20sIDAsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBjb2x1bW4gaW4gY3NlYykgICAgCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbHVtbiBpcyBFeGNlbENvbHVtbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjID0gKEV4Y2VsQ29sdW1uKWNvbHVtbjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMuX2NvbHVtbk1pbiA+PSBjb2x1bW5Gcm9tKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLl9jb2x1bW5NaW4gLT0gY29sdW1uczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuX2NvbHVtbk1heCAtPSBjb2x1bW5zOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0YmwgaW4gVGFibGVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjb2x1bW5Gcm9tID49IHRibC5BZGRyZXNzLlN0YXJ0LkNvbHVtbiAmJiBjb2x1bW5Gcm9tIDw9IHRibC5BZGRyZXNzLkVuZC5Db2x1bW4pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZSA9IHRibC5Db2x1bW5zWzBdLlRvcE5vZGUuUGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGl4ID0gY29sdW1uRnJvbSAtIHRibC5BZGRyZXNzLlN0YXJ0LkNvbHVtbjsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb2x1bW5zOyBpKyspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlLkNoaWxkTm9kZXMuQ291bnQgPiBpeCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLlJlbW92ZUNoaWxkKG5vZGUuQ2hpbGROb2Rlc1tpeF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9IAogICAgICAgICAgICAgICAgICAgICAgICB0YmwuX2NvbHMgPSBuZXcgRXhjZWxUYWJsZUNvbHVtbkNvbGxlY3Rpb24odGJsKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRibC5BZGRyZXNzID0gdGJsLkFkZHJlc3MuRGVsZXRlQ29sdW1uKGNvbHVtbkZyb20sIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHZvaWQgQWRqdXN0Rm9ybXVsYXNSb3coaW50IHJvd0Zyb20sIGludCByb3dzKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGRlbFNGID0gbmV3IExpc3Q8aW50PigpOwogICAgICAgICAgICBmb3JlYWNoICh2YXIgc2YgaW4gX3NoYXJlZEZvcm11bGFzLlZhbHVlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGEgPSBuZXcgRXhjZWxBZGRyZXNzKHNmLkFkZHJlc3MpLkRlbGV0ZVJvdyhyb3dGcm9tLCByb3dzKTsKICAgICAgICAgICAgICAgIGlmIChhPT1udWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRlbFNGLkFkZChzZi5JbmRleCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc2YuQWRkcmVzcyA9IGEuQWRkcmVzczsKICAgICAgICAgICAgICAgICAgICBpZiAoc2YuU3RhcnRSb3cgPiByb3dGcm9tKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHIgPSBNYXRoLk1pbihzZi5TdGFydFJvdyAtIHJvd0Zyb20sIHJvd3MpOwogICAgICAgICAgICAgICAgICAgICAgICBzZi5Gb3JtdWxhID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhzZi5Gb3JtdWxhLCAtciwgMCwgcm93RnJvbSwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNmLlN0YXJ0Um93IC09IHI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBpeCBpbiBkZWxTRikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzLlJlbW92ZShpeCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVsU0YgPSBudWxsOwogICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX2Zvcm11bGFzLCAxLCAxLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICB3aGlsZSAoY3NlLk5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGNzZS5WYWx1ZSBpcyBzdHJpbmcpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY3NlLlZhbHVlID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhjc2UuVmFsdWUuVG9TdHJpbmcoKSwgLXJvd3MsIDAsIHJvd0Zyb20sIDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHZvaWQgQWRqdXN0Rm9ybXVsYXNDb2x1bW4oaW50IGNvbHVtbkZyb20sIGludCBjb2x1bW5zKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGRlbFNGID0gbmV3IExpc3Q8aW50PigpOwogICAgICAgICAgICBmb3JlYWNoICh2YXIgc2YgaW4gX3NoYXJlZEZvcm11bGFzLlZhbHVlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGEgPSBuZXcgRXhjZWxBZGRyZXNzKHNmLkFkZHJlc3MpLkRlbGV0ZUNvbHVtbihjb2x1bW5Gcm9tLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIGlmIChhID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGVsU0YuQWRkKHNmLkluZGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzZi5BZGRyZXNzID0gYS5BZGRyZXNzOwogICAgICAgICAgICAgICAgICAgIC8vc2YuRm9ybXVsYSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoc2YuRm9ybXVsYSwgMCwgLWNvbHVtbnMsIDAsIGNvbHVtbkZyb20pOwogICAgICAgICAgICAgICAgICAgIGlmIChzZi5TdGFydENvbCA+IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IE1hdGguTWluKHNmLlN0YXJ0Q29sIC0gY29sdW1uRnJvbSwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNmLkZvcm11bGEgPSBFeGNlbENlbGxCYXNlLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKHNmLkZvcm11bGEsIDAsIC1jLCAwLCAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2YuU3RhcnRDb2wtPSBjOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy9zZi5BZGRyZXNzID0gYS5BZGRyZXNzOwogICAgICAgICAgICAgICAgICAgIC8vc2YuRm9ybXVsYSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoc2YuRm9ybXVsYSwgMCwtY29sdW1ucywwLCBjb2x1bW5Gcm9tKTsKICAgICAgICAgICAgICAgICAgICAvL2lmIChzZi5TdGFydENvbCA+PSBjb2x1bW5Gcm9tKQogICAgICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgICAgIC8vICAgIHNmLlN0YXJ0Q29sIC09IHNmLlN0YXJ0Q29sOwogICAgICAgICAgICAgICAgICAgIC8vfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBpeCBpbiBkZWxTRikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzLlJlbW92ZShpeCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVsU0YgPSBudWxsOwogICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX2Zvcm11bGFzLCAxLCAxLCAgRXhjZWxQYWNrYWdlLk1heFJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgd2hpbGUgKGNzZS5OZXh0KCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChjc2UuVmFsdWUgaXMgc3RyaW5nKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNzZS5WYWx1ZSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoY3NlLlZhbHVlLlRvU3RyaW5nKCksIDAsIC1jb2x1bW5zLCAwLCBjb2x1bW5Gcm9tKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIERlbGV0ZXMgdGhlIHNwZWNpZmllZCByb3cgZnJvbSB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dGcm9tIj5UaGUgbnVtYmVyIG9mIHRoZSBzdGFydCByb3cgdG8gYmUgZGVsZXRlZDwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dzIj5OdW1iZXIgb2Ygcm93cyB0byBkZWxldGU8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic2hpZnRPdGhlclJvd3NVcCI+Tm90IHVzZWQuIFJvd3MgYXJlIGFsd2F5cyBzaGlmdGVkPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBEZWxldGVSb3coaW50IHJvd0Zyb20sIGludCByb3dzLCBib29sIHNoaWZ0T3RoZXJSb3dzVXApCgkJewogICAgICAgICAgICBEZWxldGVSb3cocm93RnJvbSwgcm93cyk7CiAgICAgICAgfQoJCSNlbmRyZWdpb24KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldCB0aGUgY2VsbCB2YWx1ZSBmcm9tIHRodyB3b3Jrc2hlZXQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iUm93Ij5UaGUgcm93IG51bWJlcjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJDb2x1bW4iPlRoZSByb3cgbnVtYmVyPC9wYXJhbT4KICAgICAgICAvLy8gPHJldHVybnM+VGhlIHZhbHVlPC9yZXR1cm5zPgogICAgICAgIHB1YmxpYyBvYmplY3QgR2V0VmFsdWUoaW50IFJvdywgaW50IENvbHVtbikKICAgICAgICB7CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIC8vdWxvbmcgY2VsbElEID0gRXhjZWxDZWxsQmFzZS5HZXRDZWxsSUQoU2hlZXRJRCwgUm93LCBDb2x1bW4pOwogICAgICAgICAgICB2YXIgdiA9IF92YWx1ZXMuR2V0VmFsdWUoUm93LCBDb2x1bW4pOwogICAgICAgICAgICBpZiAodiE9bnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy92YXIgY2VsbCA9ICgoRXhjZWxDZWxsKV9jZWxsc1tjZWxsSURdKTsKICAgICAgICAgICAgICAgIGlmIChfZmxhZ3MuR2V0RmxhZ1ZhbHVlKFJvdywgQ29sdW1uLCBDZWxsRmxhZ3MuUmljaFRleHQpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAob2JqZWN0KUNlbGxzW1JvdywgQ29sdW1uXS5SaWNoVGV4dC5UZXh0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB2OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0IGEgc3Ryb25nbHkgdHlwZWQgY2VsbCB2YWx1ZSBmcm9tIHRoZSB3b3Jrc2hlZXQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8dHlwZXBhcmFtIG5hbWU9IlQiPlRoZSB0eXBlPC90eXBlcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJSb3ciPlRoZSByb3cgbnVtYmVyPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IkNvbHVtbiI+VGhlIHJvdyBudW1iZXI8L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdmFsdWUuIElmIHRoZSB2YWx1ZSBjYW4ndCBiZSBjb252ZXJ0ZWQgdG8gdGhlIHNwZWNpZmllZCB0eXBlLCB0aGUgZGVmYXVsdCB2YWx1ZSB3aWxsIGJlIHJldHVybmVkPC9yZXR1cm5zPgogICAgICAgIHB1YmxpYyBUIEdldFZhbHVlPFQ+KGludCBSb3csIGludCBDb2x1bW4pCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAvL3Vsb25nIGNlbGxJRD1FeGNlbENlbGxCYXNlLkdldENlbGxJRChTaGVldElELCBSb3csIENvbHVtbik7CiAgICAgICAgICAgIHZhciB2ID0gX3ZhbHVlcy5HZXRWYWx1ZShSb3csIENvbHVtbik7ICAgICAgICAgICAKICAgICAgICAgICAgaWYgKHY9PW51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0KFQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvL3ZhciBjZWxsPSgoRXhjZWxDZWxsKV9jZWxsc1tjZWxsSURdKTsKICAgICAgICAgICAgaWYgKF9mbGFncy5HZXRGbGFnVmFsdWUoUm93LCBDb2x1bW4sIENlbGxGbGFncy5SaWNoVGV4dCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAoVCkob2JqZWN0KUNlbGxzW1JvdywgQ29sdW1uXS5SaWNoVGV4dC5UZXh0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIEdldFR5cGVkVmFsdWU8VD4odik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy9UaGFua3MgdG8gTWljaGFlbCBUcmFuIGZvciBwYXJ0cyBvZiB0aGlzIG1ldGhvZAogICAgICAgIGludGVybmFsIFQgR2V0VHlwZWRWYWx1ZTxUPihvYmplY3QgdikKICAgICAgICB7CiAgICAgICAgICAgIGlmICh2ID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0KFQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFR5cGUgZnJvbVR5cGUgPSB2LkdldFR5cGUoKTsKICAgICAgICAgICAgVHlwZSB0b1R5cGUgPSB0eXBlb2YoVCk7CiAgICAgICAgICAgIGlmIChmcm9tVHlwZSA9PSB0b1R5cGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAoVCl2OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBjbnYgPSBUeXBlRGVzY3JpcHRvci5HZXRDb252ZXJ0ZXIoZnJvbVR5cGUpOwogICAgICAgICAgICBpZiAodG9UeXBlID09IHR5cGVvZihEYXRlVGltZSkpICAgIC8vSGFuZGxlIGRhdGVzCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChmcm9tVHlwZSA9PSB0eXBlb2YoVGltZVNwYW4pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAoKFQpKG9iamVjdCkobmV3IERhdGVUaW1lKCgoVGltZVNwYW4pdikuVGlja3MpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChmcm9tVHlwZSA9PSB0eXBlb2Yoc3RyaW5nKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBEYXRlVGltZSBkdDsKICAgICAgICAgICAgICAgICAgICBpZiAoRGF0ZVRpbWUuVHJ5UGFyc2Uodi5Ub1N0cmluZygpLCBvdXQgZHQpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChUKShvYmplY3QpKGR0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY252LkNhbkNvbnZlcnRUbyh0eXBlb2YoZG91YmxlKSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpKG9iamVjdCkoRGF0ZVRpbWUuRnJvbU9BRGF0ZSgoZG91YmxlKWNudi5Db252ZXJ0VG8odiwgdHlwZW9mKGRvdWJsZSkpKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0KFQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh0b1R5cGUgPT0gdHlwZW9mKFRpbWVTcGFuKSkgICAgLy9IYW5kbGUgdGltZXNwYW4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGZyb21UeXBlID09IHR5cGVvZihEYXRlVGltZSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgoVCkob2JqZWN0KShuZXcgVGltZVNwYW4oKChEYXRlVGltZSl2KS5UaWNrcykpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZyb21UeXBlID09IHR5cGVvZihzdHJpbmcpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRpbWVTcGFuIHRzOwogICAgICAgICAgICAgICAgICAgIGlmIChUaW1lU3Bhbi5UcnlQYXJzZSh2LlRvU3RyaW5nKCksIG91dCB0cykpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpKG9iamVjdCkodHMpOyAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjbnYuQ2FuQ29udmVydFRvKHR5cGVvZihkb3VibGUpKSkKICAgICAgICAgICAgICAgICAgICB7CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpKG9iamVjdCkobmV3IFRpbWVTcGFuKERhdGVUaW1lLkZyb21PQURhdGUoKGRvdWJsZSljbnYuQ29udmVydFRvKHYsIHR5cGVvZihkb3VibGUpKSkuVGlja3MpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElzc3VlIDE0NjgyIC0tICJHZXRWYWx1ZTxkZWNpbWFsPigpIHdvbid0IGNvbnZlcnQgc3RyaW5ncyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFzIHN1Z2dlc3RlZCwgYWZ0ZXIgYWxsIHNwZWNpYWwgY2FzZXMsIGFsbCAuTkVUIHRvIGRvIGl0J3MgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwcmVmZXJyZWQgY29udmVyc2lvbiByYXRoZXIgdGhhbiBzaW1wbHkgcmV0dXJuaW5nIHRoZSBkZWZhdWx0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpQ29udmVydC5DaGFuZ2VUeXBlKHYsIHR5cGVvZihUKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyB3YXMgdGhlIHByZXZpb3VzIGJlaGF2aW91ciAtLSBubyBjb252ZXJzaW9uIGlzIGF2YWlsYWJsZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0KFQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGNudi5DYW5Db252ZXJ0VG8odG9UeXBlKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpY252LkNvbnZlcnRUbyh2LCB0eXBlb2YoVCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0b1R5cGUuSXNHZW5lcmljVHlwZSAmJiB0b1R5cGUuR2V0R2VuZXJpY1R5cGVEZWZpbml0aW9uKCkuRXF1YWxzKHR5cGVvZihOdWxsYWJsZTw+KSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0b1R5cGUgPSBOdWxsYWJsZS5HZXRVbmRlcmx5aW5nVHlwZSh0b1R5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY252LkNhbkNvbnZlcnRUbyh0b1R5cGUpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpY252LkNvbnZlcnRUbyh2LCB0eXBlb2YoVCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZihmcm9tVHlwZT09dHlwZW9mKGRvdWJsZSkgJiYgdG9UeXBlPT10eXBlb2YoZGVjaW1hbCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpKG9iamVjdClDb252ZXJ0LlRvRGVjaW1hbCh2KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZnJvbVR5cGUgPT0gdHlwZW9mKGRlY2ltYWwpICYmIHRvVHlwZSA9PSB0eXBlb2YoZG91YmxlKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCkob2JqZWN0KUNvbnZlcnQuVG9Eb3VibGUodik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0KFQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNldCB0aGUgdmFsdWUgb2YgYSBjZWxsCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlJvdyI+VGhlIHJvdyBudW1iZXI8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iQ29sdW1uIj5UaGUgY29sdW1uIG51bWJlcjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJWYWx1ZSI+VGhlIHZhbHVlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTZXRWYWx1ZShpbnQgUm93LCBpbnQgQ29sdW1uLCBvYmplY3QgVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpZiAoUm93IDwgMSB8fCBDb2x1bW4gPCAxIHx8IFJvdyA+IEV4Y2VsUGFja2FnZS5NYXhSb3dzICYmIENvbHVtbiA+IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCJSb3cgb3IgQ29sdW1uIG91dCBvZiByYW5nZSIpOwogICAgICAgICAgICB9ICAgICAgICAgICAgCiAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUoUm93LCBDb2x1bW4sIFZhbHVlKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBTZXQgdGhlIHZhbHVlIG9mIGEgY2VsbAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJBZGRyZXNzIj5UaGUgRXhjZWwgYWRkcmVzczwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJWYWx1ZSI+VGhlIHZhbHVlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTZXRWYWx1ZShzdHJpbmcgQWRkcmVzcywgb2JqZWN0IFZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgaW50IHJvdywgY29sOwogICAgICAgICAgICBFeGNlbEFkZHJlc3NCYXNlLkdldFJvd0NvbChBZGRyZXNzLCBvdXQgcm93LCBvdXQgY29sLCB0cnVlKTsKICAgICAgICAgICAgaWYgKHJvdyA8IDEgfHwgY29sIDwgMSB8fCByb3cgPiBFeGNlbFBhY2thZ2UuTWF4Um93cyAmJiBjb2wgPiBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbigiQWRkcmVzcyBpcyBpbnZhbGlkIG9yIG91dCBvZiByYW5nZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIFZhbHVlKTsgICAgICAgICAgIAogICAgICAgIH0KCiAgICAgICAgI3JlZ2lvbiBNZXJnZUNlbGxJZAoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldCBNZXJnZUNlbGwgSW5kZXggTm8KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icm93Ij48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1uIj48L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+CiAgICAgICAgcHVibGljIGludCBHZXRNZXJnZUNlbGxJZChpbnQgcm93LCBpbnQgY29sdW1uKQogICAgICAgIHsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBfbWVyZ2VkQ2VsbHMuQ291bnQ7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICBpZighc3RyaW5nLklzTnVsbE9yRW1wdHkoIF9tZXJnZWRDZWxsc1tpXSkpCiAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFeGNlbFJhbmdlIHJhbmdlID0gQ2VsbHNbX21lcmdlZENlbGxzW2ldXTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHJhbmdlLlN0YXJ0LlJvdyA8PSByb3cgJiYgcm93IDw9IHJhbmdlLkVuZC5Sb3cpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmFuZ2UuU3RhcnQuQ29sdW1uIDw9IGNvbHVtbiAmJiBjb2x1bW4gPD0gcmFuZ2UuRW5kLkNvbHVtbikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGkgKyAxOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgI2VuZHJlZ2lvbgoJCSNlbmRyZWdpb24gLy8gRU5EIFdvcmtzaGVldCBQdWJsaWMgTWV0aG9kcwoKCQkjcmVnaW9uIFdvcmtzaGVldCBQcml2YXRlIE1ldGhvZHMKCgkJI3JlZ2lvbiBXb3Jrc2hlZXQgU2F2ZQogICAgICAgIGludGVybmFsIHZvaWQgU2F2ZSgpCiAgICAgICAgewogICAgICAgICAgICAgICAgRGVsZXRlUHJpbnRlclNldHRpbmdzKCk7CgogICAgICAgICAgICAgICAgaWYgKF93b3Jrc2hlZXRYbWwgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCEodGhpcyBpcyBFeGNlbENoYXJ0c2hlZXQpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2F2ZSB0aGUgaGVhZGVyICYgZm9vdGVyIChpZiBkZWZpbmVkKQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2hlYWRlckZvb3RlciAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgSGVhZGVyRm9vdGVyLlNhdmUoKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkID0gRGltZW5zaW9uOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZCA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLkRlbGV0ZUFsbE5vZGUoImQ6ZGltZW5zaW9uL0ByZWYiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuU2V0WG1sTm9kZVN0cmluZygiZDpkaW1lbnNpb24vQHJlZiIsIGQuQWRkcmVzcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoRHJhd2luZ3MuQ291bnQgPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9SZW1vdmUgbm9kZSBpZiBubyBkcmF3aW5ncyBleGlzdHMuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWxldGVOb2RlKCJkOmRyYXdpbmciKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgU2F2ZUNvbW1lbnRzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEhlYWRlckZvb3Rlci5TYXZlSGVhZGVyRm9vdGVySW1hZ2VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFNhdmVUYWJsZXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgU2F2ZVBpdm90VGFibGVzKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChEcmF3aW5ncy5VcmlEcmF3aW5nIT1udWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChEcmF3aW5ncy5Db3VudCA9PSAwKQogICAgICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBQYXJ0LkRlbGV0ZVJlbGF0aW9uc2hpcChEcmF3aW5ncy5fZHJhd2luZ1JlbGF0aW9uLklkKTsKICAgICAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UuUGFja2FnZS5EZWxldGVQYXJ0KERyYXdpbmdzLlVyaURyYXdpbmcpOyAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFBhY2thZ2luZy5aaXBQYWNrYWdlUGFydCBwYXJ0UGFjayA9IERyYXdpbmdzLlBhcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIERyYXdpbmdzLkRyYXdpbmdYbWwuU2F2ZShwYXJ0UGFjay5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKEV4Y2VsRHJhd2luZyBkIGluIERyYXdpbmdzKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZCBpcyBFeGNlbENoYXJ0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VsQ2hhcnQgYyA9IChFeGNlbENoYXJ0KWQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5DaGFydFhtbC5TYXZlKGMuUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHZvaWQgU2F2ZUhhbmRsZXIoWmlwT3V0cHV0U3RyZWFtIHN0cmVhbSwgQ29tcHJlc3Npb25MZXZlbCBjb21wcmVzc2lvbkxldmVsLCBzdHJpbmcgZmlsZU5hbWUpCiAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vSW5pdCBaaXAKICAgICAgICAgICAgICAgICAgICBzdHJlYW0uQ29kZWNCdWZmZXJTaXplID0gODA5NjsKICAgICAgICAgICAgICAgICAgICBzdHJlYW0uQ29tcHJlc3Npb25MZXZlbCA9IChPZmZpY2VPcGVuWG1sLlBhY2thZ2luZy5Jb25pYy5abGliLkNvbXByZXNzaW9uTGV2ZWwpY29tcHJlc3Npb25MZXZlbDsKICAgICAgICAgICAgICAgICAgICBzdHJlYW0uUHV0TmV4dEVudHJ5KGZpbGVOYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgU2F2ZVhtbChzdHJlYW0pOwogICAgICAgIH0KCiAgICAgICAgCgogICAgICAgIC8vLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLy8vIFNhdmVzIHRoZSB3b3Jrc2hlZXQgdG8gdGhlIHBhY2thZ2UuCiAgICAgICAgLy8vLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vaW50ZXJuYWwgdm9pZCBTYXZlKCkgIC8vIFdvcmtzaGVldCBTYXZlCiAgICAgICAgLy97CiAgICAgICAgLy8gICAgRGVsZXRlUHJpbnRlclNldHRpbmdzKCk7CgogICAgICAgIC8vICAgIGlmIChfd29ya3NoZWV0WG1sICE9IG51bGwpCiAgICAgICAgLy8gICAgewogICAgICAgICAgICAgICAgCiAgICAgICAgLy8gICAgICAgIC8vIHNhdmUgdGhlIGhlYWRlciAmIGZvb3RlciAoaWYgZGVmaW5lZCkKICAgICAgICAvLyAgICAgICAgaWYgKF9oZWFkZXJGb290ZXIgIT0gbnVsbCkKICAgICAgICAvLyAgICAgICAgICAgIEhlYWRlckZvb3Rlci5TYXZlKCk7CgogICAgICAgIC8vICAgICAgICB2YXIgZCA9IERpbWVuc2lvbjsKICAgICAgICAvLyAgICAgICAgaWYgKGQgPT0gbnVsbCkKICAgICAgICAvLyAgICAgICAgewogICAgICAgIC8vICAgICAgICAgICAgdGhpcy5EZWxldGVBbGxOb2RlKCJkOmRpbWVuc2lvbi9AcmVmIik7CiAgICAgICAgLy8gICAgICAgIH0KICAgICAgICAvLyAgICAgICAgZWxzZQogICAgICAgIC8vICAgICAgICB7CiAgICAgICAgLy8gICAgICAgICAgICB0aGlzLlNldFhtbE5vZGVTdHJpbmcoImQ6ZGltZW5zaW9uL0ByZWYiLCBkLkFkZHJlc3MpOwogICAgICAgIC8vICAgICAgICB9CiAgICAgICAgICAgICAgICAKCiAgICAgICAgLy8gICAgICAgIGlmIChfZHJhd2luZ3MgIT0gbnVsbCAmJiBfZHJhd2luZ3MuQ291bnQgPT0gMCkKICAgICAgICAvLyAgICAgICAgewogICAgICAgIC8vICAgICAgICAgICAgLy9SZW1vdmUgbm9kZSBpZiBubyBkcmF3aW5ncyBleGlzdHMuCiAgICAgICAgLy8gICAgICAgICAgICBEZWxldGVOb2RlKCJkOmRyYXdpbmciKTsKICAgICAgICAvLyAgICAgICAgfQoKICAgICAgICAvLyAgICAgICAgU2F2ZUNvbW1lbnRzKCk7CiAgICAgICAgLy8gICAgICAgIEhlYWRlckZvb3Rlci5TYXZlSGVhZGVyRm9vdGVySW1hZ2VzKCk7CiAgICAgICAgLy8gICAgICAgIFNhdmVUYWJsZXMoKTsKICAgICAgICAvLyAgICAgICAgU2F2ZVBpdm90VGFibGVzKCk7CiAgICAgICAgLy8gICAgICAgIFNhdmVYbWwoKTsKICAgICAgICAvLyAgICB9CiAgICAgICAgICAgIAogICAgICAgIC8vICAgIGlmIChEcmF3aW5ncy5VcmlEcmF3aW5nIT1udWxsKQogICAgICAgIC8vICAgIHsKICAgICAgICAvLyAgICAgICAgaWYgKERyYXdpbmdzLkNvdW50ID09IDApCiAgICAgICAgLy8gICAgICAgIHsgICAgICAgICAgICAgICAgICAgIAogICAgICAgIC8vICAgICAgICAgICAgUGFydC5EZWxldGVSZWxhdGlvbnNoaXAoRHJhd2luZ3MuX2RyYXdpbmdSZWxhdGlvbi5JZCk7CiAgICAgICAgLy8gICAgICAgICAgICBfcGFja2FnZS5QYWNrYWdlLkRlbGV0ZVBhcnQoRHJhd2luZ3MuVXJpRHJhd2luZyk7ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAvLyAgICAgICAgfQogICAgICAgIC8vICAgICAgICBlbHNlCiAgICAgICAgLy8gICAgICAgIHsKICAgICAgICAvLyAgICAgICAgICAgIFBhY2thZ2luZy5aaXBQYWNrYWdlUGFydCBwYXJ0UGFjayA9IERyYXdpbmdzLlBhcnQ7CiAgICAgICAgLy8gICAgICAgICAgICBEcmF3aW5ncy5EcmF3aW5nWG1sLlNhdmUocGFydFBhY2suR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSkpOwogICAgICAgIC8vICAgICAgICAgICAgZm9yZWFjaCAoRXhjZWxEcmF3aW5nIGQgaW4gRHJhd2luZ3MpCiAgICAgICAgLy8gICAgICAgICAgICB7CiAgICAgICAgLy8gICAgICAgICAgICAgICAgaWYgKGQgaXMgRXhjZWxDaGFydCkKICAgICAgICAvLyAgICAgICAgICAgICAgICB7CiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgIEV4Y2VsQ2hhcnQgYyA9IChFeGNlbENoYXJ0KWQ7CiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgIGMuQ2hhcnRYbWwuU2F2ZShjLlBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSkpOwogICAgICAgIC8vICAgICAgICAgICAgICAgIH0KICAgICAgICAvLyAgICAgICAgICAgIH0KICAgICAgICAvLyAgICAgICAgfQogICAgICAgIC8vICAgIH0KICAgICAgICAvL30KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBEZWxldGUgdGhlIHByaW50ZXJzZXR0aW5ncyByZWxhdGlvbnNoaXAgYW5kIHBhcnQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwcml2YXRlIHZvaWQgRGVsZXRlUHJpbnRlclNldHRpbmdzKCkKICAgICAgICB7CiAgICAgICAgICAgIC8vRGVsZXRlIHRoZSByZWxhdGlvbnNoaXAgZnJvbSB0aGUgcGFnZVNldHVwIHRhZwogICAgICAgICAgICBYbWxBdHRyaWJ1dGUgYXR0ciA9IChYbWxBdHRyaWJ1dGUpV29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpwYWdlU2V0dXAvQHI6aWQiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgaWYgKGF0dHIgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyaW5nIHJlbElEID0gYXR0ci5WYWx1ZTsKICAgICAgICAgICAgICAgIC8vRmlyc3QgZGVsZXRlIHRoZSBhdHRyaWJ1dGUgZnJvbSB0aGUgWE1MCiAgICAgICAgICAgICAgICBhdHRyLk93bmVyRWxlbWVudC5BdHRyaWJ1dGVzLlJlbW92ZShhdHRyKTsKICAgICAgICAgICAgICAgIGlmKFBhcnQuUmVsYXRpb25zaGlwRXhpc3RzKHJlbElEKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcmVsID0gUGFydC5HZXRSZWxhdGlvbnNoaXAocmVsSUQpOwogICAgICAgICAgICAgICAgICAgIFVyaSBwcmludGVyU2V0dGluZ3NVcmkgPSBVcmlIZWxwZXIuUmVzb2x2ZVBhcnRVcmkocmVsLlNvdXJjZVVyaSwgcmVsLlRhcmdldFVyaSk7CiAgICAgICAgICAgICAgICAgICAgUGFydC5EZWxldGVSZWxhdGlvbnNoaXAocmVsLklkKTsKCiAgICAgICAgICAgICAgICAgICAgLy9EZWxldGUgdGhlIHBhcnQgZnJvbSB0aGUgcGFja2FnZQogICAgICAgICAgICAgICAgICAgIGlmKF9wYWNrYWdlLlBhY2thZ2UuUGFydEV4aXN0cyhwcmludGVyU2V0dGluZ3NVcmkpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UuUGFja2FnZS5EZWxldGVQYXJ0KHByaW50ZXJTZXR0aW5nc1VyaSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBTYXZlQ29tbWVudHMoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKF9jb21tZW50cyAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX2NvbW1lbnRzLkNvdW50ID09IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKF9jb21tZW50cy5VcmkgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFBhcnQuRGVsZXRlUmVsYXRpb25zaGlwKF9jb21tZW50cy5SZWxJZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9wYWNrYWdlLlBhY2thZ2UuRGVsZXRlUGFydChfY29tbWVudHMuVXJpKTsgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgUmVtb3ZlTGVnYWN5RHJhd2luZ1JlbChWbWxEcmF3aW5nc0NvbW1lbnRzLlJlbElkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoX2NvbW1lbnRzLlVyaSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX2NvbW1lbnRzLlVyaT1uZXcgVXJpKHN0cmluZy5Gb3JtYXQoQCIveGwvY29tbWVudHN7MH0ueG1sIiwgU2hlZXRJRCksIFVyaUtpbmQuUmVsYXRpdmUpOyAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZihfY29tbWVudHMuUGFydD09bnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9jb21tZW50cy5QYXJ0ID0gX3BhY2thZ2UuUGFja2FnZS5DcmVhdGVQYXJ0KF9jb21tZW50cy5VcmksICJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5jb21tZW50cyt4bWwiLCBfcGFja2FnZS5Db21wcmVzc2lvbik7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWwgPSBQYXJ0LkNyZWF0ZVJlbGF0aW9uc2hpcChVcmlIZWxwZXIuR2V0UmVsYXRpdmVVcmkoV29ya3NoZWV0VXJpLCBfY29tbWVudHMuVXJpKSwgUGFja2FnaW5nLlRhcmdldE1vZGUuSW50ZXJuYWwsIEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzKyIvY29tbWVudHMiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgX2NvbW1lbnRzLkNvbW1lbnRYbWwuU2F2ZShfY29tbWVudHMuUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChfdm1sRHJhd2luZ3MgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF92bWxEcmF3aW5ncy5Db3VudCA9PSAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChfdm1sRHJhd2luZ3MuVXJpICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBQYXJ0LkRlbGV0ZVJlbGF0aW9uc2hpcChfdm1sRHJhd2luZ3MuUmVsSWQpOwogICAgICAgICAgICAgICAgICAgICAgICBfcGFja2FnZS5QYWNrYWdlLkRlbGV0ZVBhcnQoX3ZtbERyYXdpbmdzLlVyaSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChfdm1sRHJhd2luZ3MuVXJpID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfdm1sRHJhd2luZ3MuVXJpID0gWG1sSGVscGVyLkdldE5ld1VyaShfcGFja2FnZS5QYWNrYWdlLCBAIi94bC9kcmF3aW5ncy92bWxEcmF3aW5nezB9LnZtbCIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoX3ZtbERyYXdpbmdzLlBhcnQgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92bWxEcmF3aW5ncy5QYXJ0ID0gX3BhY2thZ2UuUGFja2FnZS5DcmVhdGVQYXJ0KF92bWxEcmF3aW5ncy5VcmksICJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQudm1sRHJhd2luZyIsIF9wYWNrYWdlLkNvbXByZXNzaW9uKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlbCA9IFBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaShXb3Jrc2hlZXRVcmksIF92bWxEcmF3aW5ncy5VcmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMgKyAiL3ZtbERyYXdpbmciKTsKICAgICAgICAgICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiZDpsZWdhY3lEcmF3aW5nL0ByOmlkIiwgcmVsLklkKTsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZtbERyYXdpbmdzLlJlbElkID0gcmVsLklkOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBfdm1sRHJhd2luZ3MuVm1sRHJhd2luZ1htbC5TYXZlKF92bWxEcmF3aW5ncy5QYXJ0LkdldFN0cmVhbSgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNhdmUgYWxsIHRhYmxlIGRhdGEKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHByaXZhdGUgdm9pZCBTYXZlVGFibGVzKCkKICAgICAgICB7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0YmwgaW4gVGFibGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGJsLlNob3dIZWFkZXIgfHwgdGJsLlNob3dUb3RhbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnQgY29sTnVtID0gdGJsLkFkZHJlc3MuX2Zyb21Db2w7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbFZhbCA9IG5ldyBIYXNoU2V0PHN0cmluZz4oKTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgY29sIGluIHRibC5Db2x1bW5zKQogICAgICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIG49Y29sLk5hbWUuVG9Mb3dlcihDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRibC5TaG93SGVhZGVyKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuID0gdGJsLldvcmtTaGVldC5HZXRWYWx1ZTxzdHJpbmc+KHRibC5BZGRyZXNzLl9mcm9tUm93LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRibC5BZGRyZXNzLl9mcm9tQ29sICsgY29sLlBvc2l0aW9uKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eShuKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuID0gY29sLk5hbWUuVG9Mb3dlcihDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuTmFtZSA9IG47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuID0gY29sLk5hbWUuVG9Mb3dlcihDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBpZihjb2xWYWwuQ29udGFpbnMobikpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93KG5ldyBJbnZhbGlkRGF0YUV4Y2VwdGlvbihzdHJpbmcuRm9ybWF0KCJUYWJsZSB7MH0gQ29sdW1uIHsxfSBkb2VzIG5vdCBoYXZlIGEgdW5pcXVlIG5hbWUuIiwgdGJsLk5hbWUsIGNvbC5OYW1lKSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbFZhbC5BZGQobik7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5OYW1lID0gQ29udmVydFV0aWwuRXhjZWxFbmNvZGVTdHJpbmcoY29sLk5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGJsLlNob3dIZWFkZXIpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUodGJsLkFkZHJlc3MuX2Zyb21Sb3csIGNvbE51bSwgY29sLk5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YmwuU2hvd1RvdGFsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXRUYWJsZVRvdGFsRnVuY3Rpb24odGJsLCBjb2wsIGNvbE51bSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShjb2wuQ2FsY3VsYXRlZENvbHVtbkZvcm11bGEpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZnJvbVJvdyA9IHRibC5TaG93SGVhZGVyID8gdGJsLkFkZHJlc3MuX2Zyb21Sb3cgKyAxIDogdGJsLkFkZHJlc3MuX2Zyb21Sb3c7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdG9Sb3cgPSB0YmwuU2hvd1RvdGFsID8gdGJsLkFkZHJlc3MuX3RvUm93IC0gMSA6IHRibC5BZGRyZXNzLl90b1JvdzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHJvdyA9IGZyb21Sb3c7IHJvdyA8PSB0b1Jvdzsgcm93KyspCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9DZWxsKHJvdywgY29sTnVtKS5Gb3JtdWxhID0gY29sLkNhbGN1bGF0ZWRDb2x1bW5Gb3JtdWxhOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldEZvcm11bGEocm93LCBjb2xOdW0sIGNvbC5DYWxjdWxhdGVkQ29sdW1uRm9ybXVsYSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbE51bSsrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAodGJsLlBhcnQgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0YmwuVGFibGVVcmkgPSBHZXROZXdVcmkoX3BhY2thZ2UuUGFja2FnZSwgQCIveGwvdGFibGVzL3RhYmxlezB9LnhtbCIsIHRibC5JZCk7CiAgICAgICAgICAgICAgICAgICAgdGJsLlBhcnQgPSBfcGFja2FnZS5QYWNrYWdlLkNyZWF0ZVBhcnQodGJsLlRhYmxlVXJpLCAiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwudGFibGUreG1sIiwgV29ya2Jvb2suX3BhY2thZ2UuQ29tcHJlc3Npb24pOwogICAgICAgICAgICAgICAgICAgIHZhciBzdHJlYW0gPSB0YmwuUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlKTsKICAgICAgICAgICAgICAgICAgICB0YmwuVGFibGVYbWwuU2F2ZShzdHJlYW0pOwogICAgICAgICAgICAgICAgICAgIHZhciByZWwgPSBQYXJ0LkNyZWF0ZVJlbGF0aW9uc2hpcChVcmlIZWxwZXIuR2V0UmVsYXRpdmVVcmkoV29ya3NoZWV0VXJpLCB0YmwuVGFibGVVcmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMgKyAiL3RhYmxlIik7CiAgICAgICAgICAgICAgICAgICAgdGJsLlJlbGF0aW9uc2hpcElEID0gcmVsLklkOwoKICAgICAgICAgICAgICAgICAgICBDcmVhdGVOb2RlKCJkOnRhYmxlUGFydHMiKTsKICAgICAgICAgICAgICAgICAgICBYbWxOb2RlIHRibHMgPSBUb3BOb2RlLlNlbGVjdFNpbmdsZU5vZGUoImQ6dGFibGVQYXJ0cyIsTmFtZVNwYWNlTWFuYWdlcik7CgogICAgICAgICAgICAgICAgICAgIHZhciB0YmxOb2RlID0gdGJscy5Pd25lckRvY3VtZW50LkNyZWF0ZUVsZW1lbnQoInRhYmxlUGFydCIsRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwogICAgICAgICAgICAgICAgICAgIHRibHMuQXBwZW5kQ2hpbGQodGJsTm9kZSk7CiAgICAgICAgICAgICAgICAgICAgdGJsTm9kZS5TZXRBdHRyaWJ1dGUoImlkIixFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcywgcmVsLklkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgc3RyZWFtID0gdGJsLlBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSk7CiAgICAgICAgICAgICAgICAgICAgdGJsLlRhYmxlWG1sLlNhdmUoc3RyZWFtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50ZXJuYWwgdm9pZCBTZXRUYWJsZVRvdGFsRnVuY3Rpb24oRXhjZWxUYWJsZSB0YmwsIEV4Y2VsVGFibGVDb2x1bW4gY29sLCBpbnQgY29sTnVtPS0xKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRibC5TaG93VG90YWwgPT0gZmFsc2UpIHJldHVybjsKICAgICAgICAgICAgaWYgKGNvbE51bSA9PSAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0YmwuQ29sdW1ucy5Db3VudDsgaSsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0YmwuQ29sdW1uc1tpXS5OYW1lID09IGNvbC5OYW1lKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29sTnVtID0gdGJsLkFkZHJlc3MuX2Zyb21Db2wgKyBpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY29sLlRvdGFsc1Jvd0Z1bmN0aW9uID09IFJvd0Z1bmN0aW9ucy5DdXN0b20pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNldEZvcm11bGEodGJsLkFkZHJlc3MuX3RvUm93LCBjb2xOdW0sIGNvbC5Ub3RhbHNSb3dGb3JtdWxhKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChjb2wuVG90YWxzUm93RnVuY3Rpb24gIT0gUm93RnVuY3Rpb25zLk5vbmUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoY29sLlRvdGFsc1Jvd0Z1bmN0aW9uKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLkF2ZXJhZ2U6CiAgICAgICAgICAgICAgICAgICAgICAgIFNldEZvcm11bGEodGJsLkFkZHJlc3MuX3RvUm93LCBjb2xOdW0sIEdldFRvdGFsRnVuY3Rpb24oY29sLCAiMTAxIikpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIFJvd0Z1bmN0aW9ucy5Db3VudDoKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDIiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLkNvdW50TnVtczoKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDMiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLk1heDoKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDQiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLk1pbjoKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDUiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLlN0ZERldjoKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDciKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLlZhcjoKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMTAiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLlN1bToKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDkiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IChuZXcgRXhjZXB0aW9uKCJVbmtub3duIFJvd0Z1bmN0aW9uIGVudW0iKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBjb2wuVG90YWxzUm93TGFiZWwpOwoKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50ZXJuYWwgdm9pZCBTZXRGb3JtdWxhKGludCByb3csIGludCBjb2wsIG9iamVjdCB2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIF9mb3JtdWxhcy5TZXRWYWx1ZShyb3csIGNvbCwgdmFsdWUpOwogICAgICAgICAgICBpZiAoIV92YWx1ZXMuRXhpc3RzKHJvdywgY29sKSkgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgbnVsbCk7CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHZvaWQgU2V0U3R5bGUoaW50IHJvdywgaW50IGNvbCwgaW50IHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgX3N0eWxlcy5TZXRWYWx1ZShyb3csIGNvbCwgdmFsdWUpOwogICAgICAgICAgICBpZighX3ZhbHVlcy5FeGlzdHMocm93LGNvbCkpIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIG51bGwpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBwcml2YXRlIHZvaWQgU2F2ZVBpdm90VGFibGVzKCkKICAgICAgICB7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBwdCBpbiBQaXZvdFRhYmxlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHB0LkRhdGFGaWVsZHMuQ291bnQgPiAxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFhtbEVsZW1lbnQgcGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICBpZihwdC5EYXRhT25Sb3dzPT10cnVlKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9ICBwdC5QaXZvdFRhYmxlWG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpyb3dGaWVsZHMiLCBwdC5OYW1lU3BhY2VNYW5hZ2VyKSBhcyBYbWxFbGVtZW50OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50Tm9kZSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdC5DcmVhdGVOb2RlKCJkOnJvd0ZpZWxkcyIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9IHB0LlBpdm90VGFibGVYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOnJvd0ZpZWxkcyIsIHB0Lk5hbWVTcGFjZU1hbmFnZXIpIGFzIFhtbEVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9ICBwdC5QaXZvdFRhYmxlWG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpjb2xGaWVsZHMiLCBwdC5OYW1lU3BhY2VNYW5hZ2VyKSBhcyBYbWxFbGVtZW50OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50Tm9kZSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdC5DcmVhdGVOb2RlKCJkOmNvbEZpZWxkcyIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9IHB0LlBpdm90VGFibGVYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOmNvbEZpZWxkcyIsIHB0Lk5hbWVTcGFjZU1hbmFnZXIpIGFzIFhtbEVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnROb2RlLlNlbGVjdFNpbmdsZU5vZGUoImQ6ZmllbGRbQCB4PSBcIi0yXCJdIiwgcHQuTmFtZVNwYWNlTWFuYWdlcikgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFhtbEVsZW1lbnQgZmllbGROb2RlID0gcHQuUGl2b3RUYWJsZVhtbC5DcmVhdGVFbGVtZW50KCJmaWVsZCIsIEV4Y2VsUGFja2FnZS5zY2hlbWFNYWluKTsKICAgICAgICAgICAgICAgICAgICAgICAgZmllbGROb2RlLlNldEF0dHJpYnV0ZSgieCIsICItMiIpOwogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlLkFwcGVuZENoaWxkKGZpZWxkTm9kZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHdzID0gV29ya2Jvb2suV29ya3NoZWV0c1twdC5DYWNoZURlZmluaXRpb24uU291cmNlUmFuZ2UuV29ya1NoZWV0XTsKICAgICAgICAgICAgICAgIHZhciB0ID0gd3MuVGFibGVzLkdldEZyb21SYW5nZShwdC5DYWNoZURlZmluaXRpb24uU291cmNlUmFuZ2UpOwogICAgICAgICAgICAgICAgdmFyIGZpZWxkcyA9CiAgICAgICAgICAgICAgICAgICAgcHQuQ2FjaGVEZWZpbml0aW9uLkNhY2hlRGVmaW5pdGlvblhtbC5TZWxlY3ROb2RlcygKICAgICAgICAgICAgICAgICAgICAgICAgImQ6cGl2b3RDYWNoZURlZmluaXRpb24vZDpjYWNoZUZpZWxkcy9kOmNhY2hlRmllbGQiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgICAgIGludCBpeCA9IDA7CiAgICAgICAgICAgICAgICBpZiAoZmllbGRzICE9IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGZsZHMgPSBuZXcgSGFzaFNldDxzdHJpbmc+KCk7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoWG1sRWxlbWVudCBub2RlIGluIGZpZWxkcykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpeCA+PSBwdC5DYWNoZURlZmluaXRpb24uU291cmNlUmFuZ2UuQ29sdW1ucykgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmbGROYW1lID0gbm9kZS5HZXRBdHRyaWJ1dGUoIm5hbWUiKTsgICAgICAgICAgICAgICAgICAgICAgICAvL0ZpeGVzIGlzc3VlIDE1Mjk1IGR1cCBuYW1lIGVycm9yCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eShmbGROYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxkTmFtZSA9ICh0ID09IG51bGwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHB0LkNhY2hlRGVmaW5pdGlvbi5Tb3VyY2VSYW5nZS5PZmZzZXQoMCwgaXgrKywgMSwgMSkuVmFsdWUuVG9TdHJpbmcoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdC5Db2x1bW5zW2l4KytdLk5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmbGRzLkNvbnRhaW5zKGZsZE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxkTmFtZSA9IEdldE5ld05hbWUoZmxkcywgZmxkTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZmxkcy5BZGQoZmxkTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuU2V0QXR0cmlidXRlKCJuYW1lIiwgZmxkTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBkZiBpbiBwdC5EYXRhRmllbGRzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGRmLk5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgbmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZi5GdW5jdGlvbiA9PSBEYXRhRmllbGRGdW5jdGlvbnMuTm9uZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gZGYuRmllbGQuTmFtZTsgLy9OYW1lIG11c3QgYmUgc2V0IG9yIEV4Y2VsIHdpbGwgY3Jhc2ggb24gcmVuYW1lLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGRmLkZ1bmN0aW9uLlRvU3RyaW5nKCkgKyAiIG9mICIgKyBkZi5GaWVsZC5OYW1lOyAvL05hbWUgbXVzdCBiZSBzZXQgb3IgRXhjZWwgd2lsbCBjcmFzaCBvbiByZW5hbWUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL01ha2Ugc3VyZSBuYW1lIGlzIHVuaXF1ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld05hbWUgPSBuYW1lOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHB0LkRhdGFGaWVsZHMuRXhpc3RzRGZOYW1lKG5ld05hbWUsIGRmKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdOYW1lID0gbmFtZSArIChpKyspLlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGYuTmFtZSA9IG5ld05hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwdC5QaXZvdFRhYmxlWG1sLlNhdmUocHQuUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlKSk7CiAgICAgICAgICAgICAgICBwdC5DYWNoZURlZmluaXRpb24uQ2FjaGVEZWZpbml0aW9uWG1sLlNhdmUocHQuQ2FjaGVEZWZpbml0aW9uLlBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHN0cmluZyBHZXROZXdOYW1lKEhhc2hTZXQ8c3RyaW5nPiBmbGRzLCBzdHJpbmcgZmxkTmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGludCBpeCA9IDI7CiAgICAgICAgICAgIHdoaWxlIChmbGRzLkNvbnRhaW5zKGZsZE5hbWUgKyBpeC5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGl4Kys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZsZE5hbWUgKyBpeC5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgc3RhdGljIHN0cmluZyBHZXRUb3RhbEZ1bmN0aW9uKEV4Y2VsVGFibGVDb2x1bW4gY29sLHN0cmluZyBGdW5jdGlvbk51bSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBzdHJpbmcuRm9ybWF0KCJTVUJUT1RBTCh7MH0sezF9W3syfV0pIiwgRnVuY3Rpb25OdW0sIGNvbC5fdGJsLk5hbWUsIGNvbC5OYW1lKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIFNhdmVYbWwoU3RyZWFtIHN0cmVhbSkKICAgICAgICB7CiAgICAgICAgICAgIC8vQ3JlYXRlIHRoZSBub2RlcyBpZiB0aGV5IGRvIG5vdCBleGlzdC4KICAgICAgICAgICAgU3RyZWFtV3JpdGVyIHN3ID0gbmV3IFN0cmVhbVdyaXRlcihzdHJlYW0sIFN5c3RlbS5UZXh0LkVuY29kaW5nLlVURjgsIDY1NTM2KTsKICAgICAgICAgICAgaWYgKHRoaXMgaXMgRXhjZWxDaGFydHNoZWV0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdy5Xcml0ZShfd29ya3NoZWV0WG1sLk91dGVyWG1sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENyZWF0ZU5vZGUoImQ6Y29scyIpOwogICAgICAgICAgICAgICAgQ3JlYXRlTm9kZSgiZDpzaGVldERhdGEiKTsKICAgICAgICAgICAgICAgIENyZWF0ZU5vZGUoImQ6bWVyZ2VDZWxscyIpOwogICAgICAgICAgICAgICAgQ3JlYXRlTm9kZSgiZDpoeXBlcmxpbmtzIik7CiAgICAgICAgICAgICAgICBDcmVhdGVOb2RlKCJkOnJvd0JyZWFrcyIpOwogICAgICAgICAgICAgICAgQ3JlYXRlTm9kZSgiZDpjb2xCcmVha3MiKTsKCiAgICAgICAgICAgICAgICAvL1N0cmVhbVdyaXRlciBzdz1uZXcgU3RyZWFtV3JpdGVyKFBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSkpOwogICAgICAgICAgICAgICAgdmFyIHhtbCA9IF93b3Jrc2hlZXRYbWwuT3V0ZXJYbWw7CiAgICAgICAgICAgICAgICBpbnQgY29sU3RhcnQgPSAwLCBjb2xFbmQgPSAwOwogICAgICAgICAgICAgICAgR2V0QmxvY2tQb3MoeG1sLCAiY29scyIsIHJlZiBjb2xTdGFydCwgcmVmIGNvbEVuZCk7CgogICAgICAgICAgICAgICAgc3cuV3JpdGUoeG1sLlN1YnN0cmluZygwLCBjb2xTdGFydCkpOwogICAgICAgICAgICAgICAgdmFyIGNvbEJyZWFrcyA9IG5ldyBMaXN0PGludD4oKTsKICAgICAgICAgICAgICAgIC8vaWYgKF9jb2x1bW5zLkNvdW50ID4gMCkKICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgVXBkYXRlQ29sdW1uRGF0YShzdyk7CiAgICAgICAgICAgICAgICAvL30KCiAgICAgICAgICAgICAgICBpbnQgY2VsbFN0YXJ0ID0gY29sRW5kLCBjZWxsRW5kID0gY29sRW5kOwogICAgICAgICAgICAgICAgR2V0QmxvY2tQb3MoeG1sLCAic2hlZXREYXRhIiwgcmVmIGNlbGxTdGFydCwgcmVmIGNlbGxFbmQpOwoKICAgICAgICAgICAgICAgIHN3LldyaXRlKHhtbC5TdWJzdHJpbmcoY29sRW5kLCBjZWxsU3RhcnQgLSBjb2xFbmQpKTsKICAgICAgICAgICAgICAgIHZhciByb3dCcmVha3MgPSBuZXcgTGlzdDxpbnQ+KCk7CiAgICAgICAgICAgICAgICBVcGRhdGVSb3dDZWxsRGF0YShzdyk7CgogICAgICAgICAgICAgICAgaW50IG1lcmdlU3RhcnQgPSBjZWxsRW5kLCBtZXJnZUVuZCA9IGNlbGxFbmQ7CgogICAgICAgICAgICAgICAgR2V0QmxvY2tQb3MoeG1sLCAibWVyZ2VDZWxscyIsIHJlZiBtZXJnZVN0YXJ0LCByZWYgbWVyZ2VFbmQpOwogICAgICAgICAgICAgICAgc3cuV3JpdGUoeG1sLlN1YnN0cmluZyhjZWxsRW5kLCBtZXJnZVN0YXJ0IC0gY2VsbEVuZCkpOwoKICAgICAgICAgICAgICAgIENsZWFudXBNZXJnZWRDZWxscyhfbWVyZ2VkQ2VsbHMpOwogICAgICAgICAgICAgICAgaWYgKF9tZXJnZWRDZWxscy5Db3VudCA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVXBkYXRlTWVyZ2VkQ2VsbHMoc3cpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGludCBoeXBlclN0YXJ0ID0gbWVyZ2VFbmQsIGh5cGVyRW5kID0gbWVyZ2VFbmQ7CiAgICAgICAgICAgICAgICBHZXRCbG9ja1Bvcyh4bWwsICJoeXBlcmxpbmtzIiwgcmVmIGh5cGVyU3RhcnQsIHJlZiBoeXBlckVuZCk7CiAgICAgICAgICAgICAgICBzdy5Xcml0ZSh4bWwuU3Vic3RyaW5nKG1lcmdlRW5kLCBoeXBlclN0YXJ0IC0gbWVyZ2VFbmQpKTsKICAgICAgICAgICAgICAgIC8vaWYgKF9oeXBlckxpbmtDZWxscy5Db3VudCA+IDApCiAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgIFVwZGF0ZUh5cGVyTGlua3Moc3cpOwogICAgICAgICAgICAgICAgLy8gfQoKICAgICAgICAgICAgICAgIGludCByb3dCcmVha1N0YXJ0ID0gaHlwZXJFbmQsIHJvd0JyZWFrRW5kID0gaHlwZXJFbmQ7CiAgICAgICAgICAgICAgICBHZXRCbG9ja1Bvcyh4bWwsICJyb3dCcmVha3MiLCByZWYgcm93QnJlYWtTdGFydCwgcmVmIHJvd0JyZWFrRW5kKTsKICAgICAgICAgICAgICAgIHN3LldyaXRlKHhtbC5TdWJzdHJpbmcoaHlwZXJFbmQsIHJvd0JyZWFrU3RhcnQgLSBoeXBlckVuZCkpOwogICAgICAgICAgICAgICAgLy9pZiAocm93QnJlYWtzLkNvdW50ID4gMCkKICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgVXBkYXRlUm93QnJlYWtzKHN3KTsKICAgICAgICAgICAgICAgIC8vfQoKICAgICAgICAgICAgICAgIGludCBjb2xCcmVha1N0YXJ0ID0gcm93QnJlYWtFbmQsIGNvbEJyZWFrRW5kID0gcm93QnJlYWtFbmQ7CiAgICAgICAgICAgICAgICBHZXRCbG9ja1Bvcyh4bWwsICJjb2xCcmVha3MiLCByZWYgY29sQnJlYWtTdGFydCwgcmVmIGNvbEJyZWFrRW5kKTsKICAgICAgICAgICAgICAgIHN3LldyaXRlKHhtbC5TdWJzdHJpbmcocm93QnJlYWtFbmQsIGNvbEJyZWFrU3RhcnQgLSByb3dCcmVha0VuZCkpOwogICAgICAgICAgICAgICAgLy9pZiAoY29sQnJlYWtzLkNvdW50ID4gMCkKICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgVXBkYXRlQ29sQnJlYWtzKHN3KTsKICAgICAgICAgICAgICAgIC8vfQogICAgICAgICAgICAgICAgc3cuV3JpdGUoeG1sLlN1YnN0cmluZyhjb2xCcmVha0VuZCwgeG1sLkxlbmd0aCAtIGNvbEJyZWFrRW5kKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3cuRmx1c2goKTsKICAgICAgICAgICAgLy9zdy5DbG9zZSgpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIENsZWFudXBNZXJnZWRDZWxscyhNZXJnZUNlbGxzQ29sbGVjdGlvbiBfbWVyZ2VkQ2VsbHMpCiAgICAgICAgewogICAgICAgICAgICBpbnQgaT0wOwogICAgICAgICAgICB3aGlsZSAoaSA8IF9tZXJnZWRDZWxscy5MaXN0LkNvdW50KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX21lcmdlZENlbGxzW2ldID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLkxpc3QuUmVtb3ZlQXQoaSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaSsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBVcGRhdGVDb2xCcmVha3MoU3RyZWFtV3JpdGVyIHN3KQogICAgICAgIHsKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBicmVha3MgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBpbnQgY291bnQgPSAwOwogICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX3ZhbHVlcywgMCwgMCwgMCwgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAvL2ZvcmVhY2ggKEV4Y2VsQ29sdW1uIGNvbCBpbiBfY29sdW1ucykKICAgICAgICAgICAgd2hpbGUoY3NlLk5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGNvbD1jc2UuVmFsdWUgYXMgRXhjZWxDb2x1bW47CiAgICAgICAgICAgICAgICBpZiAoY29sICE9IG51bGwgJiYgY29sLlBhZ2VCcmVhaykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBicmVha3MuQXBwZW5kRm9ybWF0KCI8YnJrIGlkPVwiezB9XCIgbWF4PVwiMTYzODNcIiBtYW49XCIxXCIgLz4iLCBjc2UuQ29sdW1uKTsKICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjb3VudCA+IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3LldyaXRlKHN0cmluZy5Gb3JtYXQoIjxjb2xCcmVha3MgY291bnQ9XCJ7MH1cIiBtYW51YWxCcmVha0NvdW50PVwiezB9XCI+ezF9PC9jb2xCcmVha3M+IiwgY291bnQsIGJyZWFrcy5Ub1N0cmluZygpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBVcGRhdGVSb3dCcmVha3MoU3RyZWFtV3JpdGVyIHN3KQogICAgICAgIHsKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBicmVha3M9bmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgaW50IGNvdW50ID0gMDsKICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF92YWx1ZXMsIDAsIDAsIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCAwKTsKICAgICAgICAgICAgLy9mb3JlYWNoKEV4Y2VsUm93IHJvdyBpbiBfcm93cykgICAgICAgICAgICAKICAgICAgICAgICAgd2hpbGUoY3NlLk5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIHJvdz1jc2UuVmFsdWUgYXMgUm93SW50ZXJuYWw7CiAgICAgICAgICAgICAgICBpZiAocm93ICE9IG51bGwgJiYgcm93LlBhZ2VCcmVhaykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBicmVha3MuQXBwZW5kRm9ybWF0KCI8YnJrIGlkPVwiezB9XCIgbWF4PVwiMTA0ODU3NVwiIG1hbj1cIjFcIiAvPiIsIGNzZS5Sb3cpOwogICAgICAgICAgICAgICAgICAgIGNvdW50Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNvdW50PjApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3LldyaXRlKHN0cmluZy5Gb3JtYXQoIjxyb3dCcmVha3MgY291bnQ9XCJ7MH1cIiBtYW51YWxCcmVha0NvdW50PVwiezB9XCI+ezF9PC9yb3dCcmVha3M+IiwgY291bnQsIGJyZWFrcy5Ub1N0cmluZygpKSk7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gSW5zZXJ0cyB0aGUgY29scyBjb2xsZWN0aW9uIGludG8gdGhlIFhNTCBkb2N1bWVudAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHJpdmF0ZSB2b2lkIFVwZGF0ZUNvbHVtbkRhdGEoU3RyZWFtV3JpdGVyIHN3KQogICAgICAgIHsKICAgICAgICAgICAgLy9FeGNlbENvbHVtbiBwcmV2Q29sID0gbnVsbDsgICAvL2NvbW1lbnRlZCBvdXQgMTEvMS0xMiBKSyAKICAgICAgICAgICAgLy9mb3JlYWNoIChFeGNlbENvbHVtbiBjb2wgaW4gX2NvbHVtbnMpCiAgICAgICAgICAgIC8veyAgICAgICAgICAgICAgICAKICAgICAgICAgICAgLy8gICAgaWYgKHByZXZDb2wgIT0gbnVsbCkKICAgICAgICAgICAgLy8gICAgewogICAgICAgICAgICAvLyAgICAgICAgaWYocHJldkNvbC5Db2x1bW5NYXggIT0gY29sLkNvbHVtbk1pbi0xKQogICAgICAgICAgICAvLyAgICAgICAgewogICAgICAgICAgICAvLyAgICAgICAgICAgIHByZXZDb2wuX2NvbHVtbk1heD1jb2wuQ29sdW1uTWluLTE7CiAgICAgICAgICAgIC8vICAgICAgICB9CiAgICAgICAgICAgIC8vICAgIH0KICAgICAgICAgICAgLy8gICAgcHJldkNvbCA9IGNvbDsKICAgICAgICAgICAgLy99CiAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfdmFsdWVzLCAwLCAxLCAwLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgIC8vc3cuV3JpdGUoIjxjb2xzPiIpOwogICAgICAgICAgICAvL2ZvcmVhY2ggKEV4Y2VsQ29sdW1uIGNvbCBpbiBfY29sdW1ucykKICAgICAgICAgICAgYm9vbCBmaXJzdCA9IHRydWU7CiAgICAgICAgICAgIHdoaWxlKGNzZS5OZXh0KCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChmaXJzdCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiPGNvbHM+Iik7CiAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciBjb2wgPSBjc2UuVmFsdWUgYXMgRXhjZWxDb2x1bW47CiAgICAgICAgICAgICAgICBFeGNlbFN0eWxlQ29sbGVjdGlvbjxFeGNlbFhmcz4gY2VsbFhmcyA9IF9wYWNrYWdlLldvcmtib29rLlN0eWxlcy5DZWxsWGZzOwoKICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8Y29sIG1pbj1cInswfVwiIG1heD1cInsxfVwiIiwgY29sLkNvbHVtbk1pbiwgY29sLkNvbHVtbk1heCk7CiAgICAgICAgICAgICAgICBpZiAoY29sLkhpZGRlbiA9PSB0cnVlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vc2JYbWwuQXBwZW5kKCIgd2lkdGg9XCIwXCIgaGlkZGVuPVwiMVwiIGN1c3RvbVdpZHRoPVwiMVwiIik7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBoaWRkZW49XCIxXCIiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbC5CZXN0Rml0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCIgYmVzdEZpdD1cIjFcIiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc3cuV3JpdGUoc3RyaW5nLkZvcm1hdChDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlLCAiIHdpZHRoPVwiezB9XCIgY3VzdG9tV2lkdGg9XCIxXCIiLCBjb2wuV2lkdGgpKTsKICAgICAgICAgICAgICAgIGlmIChjb2wuT3V0bGluZUxldmVsID4gMCkKICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCIgb3V0bGluZUxldmVsPVwiezB9XCIgIiwgY29sLk91dGxpbmVMZXZlbCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbC5Db2xsYXBzZWQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29sLkhpZGRlbikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBjb2xsYXBzZWQ9XCIxXCIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCIgY29sbGFwc2VkPVwiMVwiIGhpZGRlbj1cIjFcIiIpOyAvL0Fsd2F5cyBoaWRkZW4KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChjb2wuUGhvbmV0aWMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBwaG9uZXRpYz1cIjFcIiIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBzdHlsZUlEID0gY29sLlN0eWxlSUQgPj0gMCA/IGNlbGxYZnNbY29sLlN0eWxlSURdLm5ld0lEIDogY29sLlN0eWxlSUQ7CiAgICAgICAgICAgICAgICBpZiAoc3R5bGVJRCA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBzdHlsZT1cInswfVwiIiwgc3R5bGVJRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIC8+Iik7CgogICAgICAgICAgICAgICAgLy9pZiAoY29sLlBhZ2VCcmVhaykKICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgLy8gICAgY29sQnJlYWtzLkFkZChjb2wuQ29sdW1uTWluKTsKICAgICAgICAgICAgICAgIC8vfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghZmlyc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8L2NvbHM+Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBJbnNlcnQgcm93IGFuZCBjZWxscyBpbnRvIHRoZSBYTUwgZG9jdW1lbnQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHByaXZhdGUgdm9pZCBVcGRhdGVSb3dDZWxsRGF0YShTdHJlYW1Xcml0ZXIgc3cpCiAgICAgICAgewogICAgICAgICAgICBFeGNlbFN0eWxlQ29sbGVjdGlvbjxFeGNlbFhmcz4gY2VsbFhmcyA9IF9wYWNrYWdlLldvcmtib29rLlN0eWxlcy5DZWxsWGZzOwogICAgICAgICAgICAKICAgICAgICAgICAgaW50IHJvdyA9IC0xOwoKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYlhtbCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgIHZhciBzcyA9IF9wYWNrYWdlLldvcmtib29rLl9zaGFyZWRTdHJpbmdzOwogICAgICAgICAgICB2YXIgc3R5bGVzID0gX3BhY2thZ2UuV29ya2Jvb2suU3R5bGVzOwogICAgICAgICAgICB2YXIgY2FjaGUgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBjYWNoZS5BcHBlbmQoIjxzaGVldERhdGE+Iik7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL1NldCBhIHZhbHVlIGZvciBjZWxscyB3aXRoIHN0eWxlIGFuZCBubyB2YWx1ZSBzZXQuCiAgICAgICAgICAgIHZhciBjc2VTdHlsZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxpbnQ+KF9zdHlsZXMsIDAsIDAsIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBzIGluIGNzZVN0eWxlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZighX3ZhbHVlcy5FeGlzdHMoY3NlU3R5bGUuUm93LCBjc2VTdHlsZS5Db2x1bW4pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUoY3NlU3R5bGUuUm93LCBjc2VTdHlsZS5Db2x1bW4sIG51bGwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX3ZhbHVlcywgMSwgMCwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgLy9mb3JlYWNoIChJUmFuZ2VJRCByIGluIF9jZWxscykKICAgICAgICAgICAgd2hpbGUoY3NlLk5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGNzZS5Db2x1bW4+MCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnQgc3R5bGVJRCA9IGNlbGxYZnNbc3R5bGVzLkdldFN0eWxlSWQodGhpcywgY3NlLlJvdywgY3NlLkNvbHVtbildLm5ld0lEOwogICAgICAgICAgICAgICAgICAgIC8vQWRkIHRoZSByb3cgZWxlbWVudCBpZiBpdCdzIGEgbmV3IHJvdwogICAgICAgICAgICAgICAgICAgIGlmIChjc2UuUm93ICE9IHJvdykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFdyaXRlUm93KGNhY2hlLCBjZWxsWGZzLCByb3csIGNzZS5Sb3cpOwogICAgICAgICAgICAgICAgICAgICAgICByb3cgPSBjc2UuUm93OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBvYmplY3QgdiA9IGNzZS5WYWx1ZTsKICAgICAgICAgICAgICAgICAgICBvYmplY3QgZm9ybXVsYSA9IF9mb3JtdWxhcy5HZXRWYWx1ZShjc2UuUm93LCBjc2UuQ29sdW1uKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZm9ybXVsYSBpcyBpbnQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2ZJZCA9IChpbnQpZm9ybXVsYTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGYgPSBfc2hhcmVkRm9ybXVsYXNbKGludClzZklkXTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGYuQWRkcmVzcy5JbmRleE9mKCc6JykgPiAwKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZi5TdGFydENvbCA9PSBjc2UuQ29sdW1uICYmIGYuU3RhcnRSb3cgPT0gY3NlLlJvdykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZi5Jc0FycmF5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiezV9PjxmIHJlZj1cInsyfVwiIHQ9XCJhcnJheVwiPnszfTwvZj57NH08L2M+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlELCBmLkFkZHJlc3MsIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoZi5Gb3JtdWxhKSwgR2V0Rm9ybXVsYVZhbHVlKHYpLCBHZXRDZWxsVHlwZSh2LHRydWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiezZ9PjxmIHJlZj1cInsyfVwiIHQ9XCJzaGFyZWRcIiAgc2k9XCJ7M31cIj57NH08L2Y+ezV9PC9jPiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCwgZi5BZGRyZXNzLCBzZklkLCBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGYuRm9ybXVsYSksIEdldEZvcm11bGFWYWx1ZSh2KSwgR2V0Q2VsbFR5cGUodix0cnVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGYuSXNBcnJheSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxjIHI9XCJ7MH1cIiBzPVwiezF9XCIgLz4iLCBjc2UuQ2VsbEFkZHJlc3MsIHN0eWxlSUQgPCAwID8gMCA6IHN0eWxlSUQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGMgcj1cInswfVwiIHM9XCJ7MX1cIns0fT48ZiB0PVwic2hhcmVkXCIgc2k9XCJ7Mn1cIiAvPnszfTwvYz4iLCBjc2UuQ2VsbEFkZHJlc3MsIHN0eWxlSUQgPCAwID8gMCA6IHN0eWxlSUQsIHNmSWQsIEdldEZvcm11bGFWYWx1ZSh2KSwgR2V0Q2VsbFR5cGUodix0cnVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBjYW4gYWxzbyBoYXZlIGEgc2luZ2xlIGNlbGwgYXJyYXkgZm9ybXVsYQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZi5Jc0FycmF5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGMgcj1cInswfVwiIHM9XCJ7MX1cIns1fT48ZiByZWY9XCJ7Mn1cIiB0PVwiYXJyYXlcIj57M308L2Y+ezR9PC9jPiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCwgc3RyaW5nLkZvcm1hdCgiezB9OnsxfSIsIGYuQWRkcmVzcywgZi5BZGRyZXNzKSwgU2VjdXJpdHlFbGVtZW50LkVzY2FwZShmLkZvcm11bGEpLCBHZXRGb3JtdWxhVmFsdWUodiksIEdldENlbGxUeXBlKHYsdHJ1ZSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGMgcj1cInswfVwiIHM9XCJ7MX1cIj4iLCBmLkFkZHJlc3MsIHN0eWxlSUQgPCAwID8gMCA6IHN0eWxlSUQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGY+ezB9PC9mPnsxfTwvYz4iLCBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGYuRm9ybXVsYSksIEdldEZvcm11bGFWYWx1ZSh2KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZm9ybXVsYSE9bnVsbCAmJiBmb3JtdWxhLlRvU3RyaW5nKCkhPSIiKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiezJ9PiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCwgR2V0Q2VsbFR5cGUodix0cnVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGY+ezB9PC9mPnsxfTwvYz4iLCBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGZvcm11bGEuVG9TdHJpbmcoKSksIEdldEZvcm11bGFWYWx1ZSh2KSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2ID09IG51bGwgJiYgc3R5bGVJRCA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGMgcj1cInswfVwiIHM9XCJ7MX1cIiAvPiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih2ICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgodi5HZXRUeXBlKCkuSXNQcmltaXRpdmUgfHwgdiBpcyBkb3VibGUgfHwgdiBpcyBkZWNpbWFsIHx8IHYgaXMgRGF0ZVRpbWUgfHwgdiBpcyBUaW1lU3BhbikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9zdHJpbmcgc3YgPSBHZXRWYWx1ZUZvclhtbCh2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxjIHI9XCJ7MH1cIiBzPVwiezF9XCIgezJ9PiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCwgR2V0Q2VsbFR5cGUodikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiezB9PC9jPiIsIEdldEZvcm11bGFWYWx1ZSh2KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGl4OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc3MuQ29udGFpbnNLZXkodi5Ub1N0cmluZygpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl4ID0gc3MuQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNzLkFkZCh2LlRvU3RyaW5nKCksIG5ldyBFeGNlbFdvcmtib29rLlNoYXJlZFN0cmluZ0l0ZW0oKSB7IGlzUmljaFRleHQgPSBfZmxhZ3MuR2V0RmxhZ1ZhbHVlKGNzZS5Sb3csY3NlLkNvbHVtbixDZWxsRmxhZ3MuUmljaFRleHQpLCBwb3MgPSBpeCB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXggPSBzc1t2LlRvU3RyaW5nKCldLnBvczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiIHQ9XCJzXCI+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlEKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjx2PnswfTwvdj48L2M+IiwgaXgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vLy9VcGRhdGUgaHlwZXJsaW5rcy4KICAgICAgICAgICAgICAgICAgIC8vaWYgKGNlbGwuSHlwZXJsaW5rICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAgICAgLy8gICAgX2h5cGVyTGlua0NlbGxzLkFkZChjZWxsLkNlbGxJRCk7CiAgICAgICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlICAvL0V4Y2VsUm93CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy9pbnQgbmV3Um93PSgoRXhjZWxSb3cpY3NlLlZhbHVlKS5Sb3c7CiAgICAgICAgICAgICAgICAgICAgV3JpdGVSb3coY2FjaGUsIGNlbGxYZnMsIHJvdywgY3NlLlJvdyk7CiAgICAgICAgICAgICAgICAgICAgcm93ID0gY3NlLlJvdzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChjYWNoZS5MZW5ndGggPiAweDYwMDAwMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZShjYWNoZS5Ub1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICBjYWNoZSA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChyb3cgIT0gLTEpIGNhY2hlLkFwcGVuZCgiPC9yb3c+Iik7CiAgICAgICAgICAgIGNhY2hlLkFwcGVuZCgiPC9zaGVldERhdGE+Iik7CiAgICAgICAgICAgIHN3LldyaXRlKGNhY2hlLlRvU3RyaW5nKCkpOwogICAgICAgICAgICBzdy5GbHVzaCgpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBvYmplY3QgR2V0Rm9ybXVsYVZhbHVlKG9iamVjdCB2KQogICAgICAgIHsKICAgICAgICAgICAgLy9pZiAoX3BhY2thZ2UuV29ya2Jvb2suX2lzQ2FsY3VsYXRlZCkKICAgICAgICAgICAgLy97ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgaWYgKHYgIT0gbnVsbCAmJiB2LlRvU3RyaW5nKCkhPSIiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIjx2PiIgKyBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKEdldFZhbHVlRm9yWG1sKHYpKSArICI8L3Y+IjsgLy9GaXhlcyBpc3N1ZSAxNTA3MQogICAgICAgICAgICB9ICAgICAgICAgICAgCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHN0cmluZyBHZXRDZWxsVHlwZShvYmplY3QgdiwgYm9vbCBhbGxvd1N0cj1mYWxzZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh2IGlzIGJvb2wpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIHQ9XCJiXCIiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKCh2IGlzIGRvdWJsZSAmJiBkb3VibGUuSXNJbmZpbml0eSgoZG91YmxlKXYpKSB8fCB2IGlzIEV4Y2VsRXJyb3JWYWx1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuICIgdD1cImVcIiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZihhbGxvd1N0ciAmJiB2IT1udWxsICYmICEodi5HZXRUeXBlKCkuSXNQcmltaXRpdmUgfHwgdiBpcyBkb3VibGUgfHwgdiBpcyBkZWNpbWFsIHx8IHYgaXMgRGF0ZVRpbWUgfHwgdiBpcyBUaW1lU3BhbikpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIHQ9XCJzdHJcIiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgc3RyaW5nIEdldFZhbHVlRm9yWG1sKG9iamVjdCB2KQogICAgICAgIHsKICAgICAgICAgICAgc3RyaW5nIHM7CiAgICAgICAgICAgIHRyeQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodiBpcyBEYXRlVGltZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkb3VibGUgc2R2ID0gKChEYXRlVGltZSl2KS5Ub09BRGF0ZSgpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoV29ya2Jvb2suRGF0ZTE5MDQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzZHYgLT0gRXhjZWxXb3JrYm9vay5kYXRlMTkwNE9mZnNldDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHMgPSBzZHYuVG9TdHJpbmcoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICh2IGlzIFRpbWVTcGFuKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHMgPSBuZXcgRGF0ZVRpbWUoKChUaW1lU3Bhbil2KS5UaWNrcykuVG9PQURhdGUoKS5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsgOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZih2LkdldFR5cGUoKS5Jc1ByaW1pdGl2ZSB8fCB2IGlzIGRvdWJsZSB8fCB2IGlzIGRlY2ltYWwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHYgaXMgZG91YmxlICYmIGRvdWJsZS5Jc05hTigoZG91YmxlKXYpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcyA9ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh2IGlzIGRvdWJsZSAmJiBkb3VibGUuSXNJbmZpbml0eSgoZG91YmxlKXYpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcyA9ICIjTlVNISI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBDb252ZXJ0LlRvRG91YmxlKHYsIEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpLlRvU3RyaW5nKCJSMTUiLCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcyA9IHYuVG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgY2F0Y2gKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcyA9ICIwIjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIFdyaXRlUm93KFN0cmluZ0J1aWxkZXIgY2FjaGUsIEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsWGZzPiBjZWxsWGZzLCBpbnQgcHJldlJvdywgaW50IHJvdykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwcmV2Um93ICE9IC0xKSBjYWNoZS5BcHBlbmQoIjwvcm93PiIpOwogICAgICAgICAgICAvL3Vsb25nIHJvd0lEID0gRXhjZWxSb3cuR2V0Um93SUQoU2hlZXRJRCwgcm93KTsKICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8cm93IHI9XCJ7MH1cIiAiLCByb3cpOwogICAgICAgICAgICBSb3dJbnRlcm5hbCBjdXJyUm93ID0gX3ZhbHVlcy5HZXRWYWx1ZShyb3csIDApIGFzIFJvd0ludGVybmFsOwogICAgICAgICAgICBpZiAoY3VyclJvdyAhPSBudWxsKQogICAgICAgICAgICB7CgogICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuSGlkZGVuID09IHRydWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kKCJodD1cIjBcIiBoaWRkZW49XCIxXCIgIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChjdXJyUm93LkhlaWdodCAhPSBEZWZhdWx0Um93SGVpZ2h0ICYmIGN1cnJSb3cuSGVpZ2h0Pj0wKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdChzdHJpbmcuRm9ybWF0KEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUsICJodD1cInswfVwiICIsIGN1cnJSb3cuSGVpZ2h0KSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuQ3VzdG9tSGVpZ2h0KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kKCJjdXN0b21IZWlnaHQ9XCIxXCIgIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChjdXJyUm93Lk91dGxpbmVMZXZlbCA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCJvdXRsaW5lTGV2ZWwgPVwiezB9XCIgIiwgY3VyclJvdy5PdXRsaW5lTGV2ZWwpOwogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LkNvbGxhcHNlZCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LkhpZGRlbikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kKCIgY29sbGFwc2VkPVwiMVwiICIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kKCIgY29sbGFwc2VkPVwiMVwiIGhpZGRlbj1cIjFcIiAiKTsgLy9BbHdheXMgaGlkZGVuCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoY3VyclJvdy5QaG9uZXRpYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoInBoPVwiMVwiICIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBzID0gX3N0eWxlcy5HZXRWYWx1ZShyb3csIDApOwogICAgICAgICAgICBpZiAocyA+IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgicz1cInswfVwiIGN1c3RvbUZvcm1hdD1cIjFcIiIsIGNlbGxYZnNbc10ubmV3SUQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhY2hlLkFwcGVuZCgiPiIpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgV3JpdGVSb3coU3RyZWFtV3JpdGVyIHN3LCBFeGNlbFN0eWxlQ29sbGVjdGlvbjxFeGNlbFhmcz4gY2VsbFhmcywgaW50IHByZXZSb3csIGludCByb3cpCiAgICAgICAgewogICAgICAgICAgICBpZiAocHJldlJvdyAhPSAtMSkgc3cuV3JpdGUoIjwvcm93PiIpOwogICAgICAgICAgICAvL3Vsb25nIHJvd0lEID0gRXhjZWxSb3cuR2V0Um93SUQoU2hlZXRJRCwgcm93KTsKICAgICAgICAgICAgc3cuV3JpdGUoIjxyb3cgcj1cInswfVwiICIsIHJvdyk7CiAgICAgICAgICAgIFJvd0ludGVybmFsIGN1cnJSb3cgPSBfdmFsdWVzLkdldFZhbHVlKHJvdywgMCkgYXMgUm93SW50ZXJuYWw7CiAgICAgICAgICAgIGlmIChjdXJyUm93IT1udWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LkhpZGRlbiA9PSB0cnVlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCJodD1cIjBcIiBoaWRkZW49XCIxXCIgIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChjdXJyUm93LkhlaWdodCAhPSBEZWZhdWx0Um93SGVpZ2h0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKHN0cmluZy5Gb3JtYXQoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSwgImh0PVwiezB9XCIgIiwgY3VyclJvdy5IZWlnaHQpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY3VyclJvdy5DdXN0b21IZWlnaHQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiY3VzdG9tSGVpZ2h0PVwiMVwiICIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoY3VyclJvdy5PdXRsaW5lTGV2ZWwgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCJvdXRsaW5lTGV2ZWwgPVwiezB9XCIgIiwgY3VyclJvdy5PdXRsaW5lTGV2ZWwpOwogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LkNvbGxhcHNlZCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LkhpZGRlbikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBjb2xsYXBzZWQ9XCIxXCIgIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIGNvbGxhcHNlZD1cIjFcIiBoaWRkZW49XCIxXCIgIik7IC8vQWx3YXlzIGhpZGRlbgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuUGhvbmV0aWMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoInBoPVwiMVwiICIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBzID0gX3N0eWxlcy5HZXRWYWx1ZShyb3csIDApOwogICAgICAgICAgICBpZiAocyA+IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3LldyaXRlKCJzPVwiezB9XCIgY3VzdG9tRm9ybWF0PVwiMVwiIiwgY2VsbFhmc1tzXS5uZXdJRCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3cuV3JpdGUoIj4iKTsKICAgICAgICB9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVXBkYXRlIHhtbCB3aXRoIGh5cGVybGlua3MgCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InN3Ij5UaGUgc3RyZWFtPC9wYXJhbT4KICAgICAgICBwcml2YXRlIHZvaWQgVXBkYXRlSHlwZXJMaW5rcyhTdHJlYW1Xcml0ZXIgc3cpCiAgICAgICAgewogICAgICAgICAgICAgICAgRGljdGlvbmFyeTxzdHJpbmcsIHN0cmluZz4gaHlwcyA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPigpOwogICAgICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxVcmk+KF9oeXBlckxpbmtzKTsKICAgICAgICAgICAgICAgIGJvb2wgZmlyc3QgPSB0cnVlOwogICAgICAgICAgICAgICAgLy9mb3JlYWNoICh1bG9uZyBjZWxsIGluIF9oeXBlckxpbmtzKQogICAgICAgICAgICAgICAgd2hpbGUoY3NlLk5leHQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3QpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiPGh5cGVybGlua3M+Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vaW50IHJvdywgY29sOwogICAgICAgICAgICAgICAgICAgIHZhciB1cmkgPSBfaHlwZXJMaW5rcy5HZXRWYWx1ZShjc2UuUm93LCBjc2UuQ29sdW1uKTsKICAgICAgICAgICAgICAgICAgICAvL0V4Y2VsQ2VsbCBjZWxsID0gX2NlbGxzW2NlbGxJZF0gYXMgRXhjZWxDZWxsOwogICAgICAgICAgICAgICAgICAgIGlmICh1cmkgaXMgRXhjZWxIeXBlckxpbmsgJiYgIXN0cmluZy5Jc051bGxPckVtcHR5KCh1cmkgYXMgRXhjZWxIeXBlckxpbmspLlJlZmVyZW5jZUFkZHJlc3MpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxIeXBlckxpbmsgaGwgPSB1cmkgYXMgRXhjZWxIeXBlckxpbms7CiAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8aHlwZXJsaW5rIHJlZj1cInswfVwiIGxvY2F0aW9uPVwiezF9XCIgezJ9ezN9Lz4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENlbGxzW2NzZS5Sb3csIGNzZS5Db2x1bW4sIGNzZS5Sb3cgKyBobC5Sb3dTcGFubiwgY3NlLkNvbHVtbiArIGhsLkNvbFNwYW5uXS5BZGRyZXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeGNlbENlbGxCYXNlLkdldEZ1bGxBZGRyZXNzKFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoTmFtZSksIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoaGwuUmVmZXJlbmNlQWRkcmVzcykpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcuSXNOdWxsT3JFbXB0eShobC5EaXNwbGF5KSA/ICIiIDogImRpc3BsYXk9XCIiICsgU2VjdXJpdHlFbGVtZW50LkVzY2FwZShobC5EaXNwbGF5KSArICJcIiAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcuSXNOdWxsT3JFbXB0eShobC5Ub29sVGlwKSA/ICIiIDogInRvb2x0aXA9XCIiICsgU2VjdXJpdHlFbGVtZW50LkVzY2FwZShobC5Ub29sVGlwKSArICJcIiAiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiggdXJpIT1udWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGlkOwogICAgICAgICAgICAgICAgICAgICAgICBVcmkgaHlwOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodXJpIGlzIEV4Y2VsSHlwZXJMaW5rKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoeXAgPSAoKEV4Y2VsSHlwZXJMaW5rKXVyaSkuT3JpZ2luYWxVcmk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoeXAgPSB1cmk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh5cHMuQ29udGFpbnNLZXkoaHlwLk9yaWdpbmFsU3RyaW5nKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQgPSBoeXBzW2h5cC5PcmlnaW5hbFN0cmluZ107CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVsYXRpb25zaGlwID0gUGFydC5DcmVhdGVSZWxhdGlvbnNoaXAoaHlwLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5FeHRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYUh5cGVybGluayk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXJpIGlzIEV4Y2VsSHlwZXJMaW5rKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VsSHlwZXJMaW5rIGhsID0gdXJpIGFzIEV4Y2VsSHlwZXJMaW5rOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8aHlwZXJsaW5rIHJlZj1cInswfVwiIHsyfXszfXI6aWQ9XCJ7MX1cIiAvPiIsIEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhjc2UuUm93LCBjc2UuQ29sdW1uKSwgcmVsYXRpb25zaGlwLklkLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZy5Jc051bGxPckVtcHR5KGhsLkRpc3BsYXkpID8gIiIgOiAiZGlzcGxheT1cIiIgKyBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGhsLkRpc3BsYXkpICsgIlwiICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZy5Jc051bGxPckVtcHR5KGhsLlRvb2xUaXApID8gIiIgOiAidG9vbHRpcD1cIiIgKyBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGhsLlRvb2xUaXApICsgIlwiICIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8aHlwZXJsaW5rIHJlZj1cInswfVwiIHI6aWQ9XCJ7MX1cIiAvPiIsIEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhjc2UuUm93LCBjc2UuQ29sdW1uKSwgcmVsYXRpb25zaGlwLklkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkID0gcmVsYXRpb25zaGlwLklkOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vY2VsbC5IeXBlckxpbmtSSWQgPSBpZDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWZpcnN0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8L2h5cGVybGlua3M+Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ3JlYXRlIHRoZSBoeXBlcmxpbmtzIG5vZGUgaW4gdGhlIFhNTAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBwcml2YXRlIFhtbE5vZGUgQ3JlYXRlSHlwZXJMaW5rQ29sbGVjdGlvbigpCiAgICAgICAgewogICAgICAgICAgICBYbWxFbGVtZW50IGhsPV93b3Jrc2hlZXRYbWwuQ3JlYXRlRWxlbWVudCgiaHlwZXJsaW5rcyIsRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwogICAgICAgICAgICBYbWxOb2RlIHByZXZOb2RlID0gX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6Y29uZGl0aW9uYWxGb3JtYXR0aW5nIiwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgIGlmIChwcmV2Tm9kZSA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwcmV2Tm9kZSA9IF93b3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOm1lcmdlQ2VsbHMiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgICAgIGlmIChwcmV2Tm9kZSA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHByZXZOb2RlID0gX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6c2hlZXREYXRhIiwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIF93b3Jrc2hlZXRYbWwuRG9jdW1lbnRFbGVtZW50Lkluc2VydEFmdGVyKGhsLCBwcmV2Tm9kZSk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRGltZW5zaW9uIGFkZHJlc3MgZm9yIHRoZSB3b3Jrc2hlZXQuIAogICAgICAgIC8vLyBUb3AgbGVmdCBjZWxsIHRvIEJvdHRvbSByaWdodC4KICAgICAgICAvLy8gSWYgdGhlIHdvcmtzaGVldCBoYXMgbm8gY2VsbHMsIG51bGwgaXMgcmV0dXJuZWQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBFeGNlbEFkZHJlc3NCYXNlIERpbWVuc2lvbgogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBpbnQgZnJvbVJvdywgZnJvbUNvbCwgdG9Sb3csIHRvQ29sOwogICAgICAgICAgICAgICAgaWYgKF92YWx1ZXMuR2V0RGltZW5zaW9uKG91dCBmcm9tUm93LCBvdXQgZnJvbUNvbCwgb3V0IHRvUm93LCBvdXQgdG9Db2wpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciBhZGRyID0gbmV3IEV4Y2VsQWRkcmVzc0Jhc2UoZnJvbVJvdywgZnJvbUNvbCwgdG9Sb3csIHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICBhZGRyLl93cyA9IE5hbWU7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFkZHI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgRXhjZWxTaGVldFByb3RlY3Rpb24gX3Byb3RlY3Rpb249bnVsbDsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEFjY2VzcyB0byBzaGVldCBwcm90ZWN0aW9uIHByb3BlcnRpZXMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBFeGNlbFNoZWV0UHJvdGVjdGlvbiBQcm90ZWN0aW9uCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF9wcm90ZWN0aW9uID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX3Byb3RlY3Rpb24gPSBuZXcgRXhjZWxTaGVldFByb3RlY3Rpb24oTmFtZVNwYWNlTWFuYWdlciwgVG9wTm9kZSwgdGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX3Byb3RlY3Rpb247CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgRXhjZWxQcm90ZWN0ZWRSYW5nZUNvbGxlY3Rpb24gX3Byb3RlY3RlZFJhbmdlczsKICAgICAgICBwdWJsaWMgRXhjZWxQcm90ZWN0ZWRSYW5nZUNvbGxlY3Rpb24gUHJvdGVjdGVkUmFuZ2VzCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF9wcm90ZWN0ZWRSYW5nZXMgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBfcHJvdGVjdGVkUmFuZ2VzID0gbmV3IEV4Y2VsUHJvdGVjdGVkUmFuZ2VDb2xsZWN0aW9uKE5hbWVTcGFjZU1hbmFnZXIsIFRvcE5vZGUsIHRoaXMpOwogICAgICAgICAgICAgICAgcmV0dXJuIF9wcm90ZWN0ZWRSYW5nZXM7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICNyZWdpb24gRHJhd2luZwogICAgICAgIEV4Y2VsRHJhd2luZ3MgX2RyYXdpbmdzID0gbnVsbDsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIENvbGxlY3Rpb24gb2YgZHJhd2luZy1vYmplY3RzIGxpa2Ugc2hhcGVzLCBpbWFnZXMgYW5kIGNoYXJ0cwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsRHJhd2luZ3MgRHJhd2luZ3MKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX2RyYXdpbmdzID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX2RyYXdpbmdzID0gbmV3IEV4Y2VsRHJhd2luZ3MoX3BhY2thZ2UsIHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF9kcmF3aW5nczsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAjZW5kcmVnaW9uCiAgICAgICAgRXhjZWxUYWJsZUNvbGxlY3Rpb24gX3RhYmxlcyA9IG51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUYWJsZXMgZGVmaW5lZCBpbiB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsVGFibGVDb2xsZWN0aW9uIFRhYmxlcwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBpZiAoV29ya2Jvb2suX25leHRUYWJsZUlEID09IGludC5NaW5WYWx1ZSkgV29ya2Jvb2suUmVhZEFsbFRhYmxlcygpOwogICAgICAgICAgICAgICAgaWYgKF90YWJsZXMgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfdGFibGVzID0gbmV3IEV4Y2VsVGFibGVDb2xsZWN0aW9uKHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF90YWJsZXM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgRXhjZWxQaXZvdFRhYmxlQ29sbGVjdGlvbiBfcGl2b3RUYWJsZXMgPSBudWxsOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gUGl2b3R0YWJsZXMgZGVmaW5lZCBpbiB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsUGl2b3RUYWJsZUNvbGxlY3Rpb24gUGl2b3RUYWJsZXMKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgaWYgKF9waXZvdFRhYmxlcyA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChXb3JrYm9vay5fbmV4dFBpdm90VGFibGVJRCA9PSBpbnQuTWluVmFsdWUpIFdvcmtib29rLlJlYWRBbGxUYWJsZXMoKTsKICAgICAgICAgICAgICAgICAgICBfcGl2b3RUYWJsZXMgPSBuZXcgRXhjZWxQaXZvdFRhYmxlQ29sbGVjdGlvbih0aGlzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfcGl2b3RUYWJsZXM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBFeGNlbENvbmRpdGlvbmFsRm9ybWF0dGluZ0NvbGxlY3Rpb24gX2NvbmRpdGlvbmFsRm9ybWF0dGluZyA9IG51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBDb25kaXRpb25hbEZvcm1hdHRpbmcgZGVmaW5lZCBpbiB0aGUgd29ya3NoZWV0LiBVc2UgdGhlIEFkZCBtZXRob2RzIHRvIGNyZWF0ZSBDb25kaXRpb25hbEZvcm1hdHRpbmcgYW5kIGFkZCB0aGVtIHRvIHRoZSB3b3Jrc2hlZXQuIFRoZW4KICAgICAgICAvLy8gc2V0IHRoZSBwcm9wZXJ0aWVzIG9uIHRoZSBpbnN0YW5jZSByZXR1cm5lZC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8c2VlYWxzbyBjcmVmPSJFeGNlbENvbmRpdGlvbmFsRm9ybWF0dGluZ0NvbGxlY3Rpb24iLz4KICAgICAgICBwdWJsaWMgRXhjZWxDb25kaXRpb25hbEZvcm1hdHRpbmdDb2xsZWN0aW9uIENvbmRpdGlvbmFsRm9ybWF0dGluZwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBpZiAoX2NvbmRpdGlvbmFsRm9ybWF0dGluZyA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF9jb25kaXRpb25hbEZvcm1hdHRpbmcgPSBuZXcgRXhjZWxDb25kaXRpb25hbEZvcm1hdHRpbmdDb2xsZWN0aW9uKHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF9jb25kaXRpb25hbEZvcm1hdHRpbmc7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBFeGNlbERhdGFWYWxpZGF0aW9uQ29sbGVjdGlvbiBfZGF0YVZhbGlkYXRpb24gPSBudWxsOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRGF0YVZhbGlkYXRpb24gZGVmaW5lZCBpbiB0aGUgd29ya3NoZWV0LiBVc2UgdGhlIEFkZCBtZXRob2RzIHRvIGNyZWF0ZSBEYXRhVmFsaWRhdGlvbnMgYW5kIGFkZCB0aGVtIHRvIHRoZSB3b3Jrc2hlZXQuIFRoZW4KICAgICAgICAvLy8gc2V0IHRoZSBwcm9wZXJ0aWVzIG9uIHRoZSBpbnN0YW5jZSByZXR1cm5lZC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8c2VlYWxzbyBjcmVmPSJFeGNlbERhdGFWYWxpZGF0aW9uQ29sbGVjdGlvbiIvPgogICAgICAgIHB1YmxpYyBFeGNlbERhdGFWYWxpZGF0aW9uQ29sbGVjdGlvbiBEYXRhVmFsaWRhdGlvbnMKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgaWYgKF9kYXRhVmFsaWRhdGlvbiA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF9kYXRhVmFsaWRhdGlvbiA9IG5ldyBFeGNlbERhdGFWYWxpZGF0aW9uQ29sbGVjdGlvbih0aGlzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfZGF0YVZhbGlkYXRpb247CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgRXhjZWxCYWNrZ3JvdW5kSW1hZ2UgX2JhY2tncm91bmRJbWFnZSA9IG51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBBbiBpbWFnZSBkaXNwbGF5ZWQgYXMgdGhlIGJhY2tncm91bmQgb2YgdGhlIHdvcmtzaGVldC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBFeGNlbEJhY2tncm91bmRJbWFnZSBCYWNrZ3JvdW5kSW1hZ2UKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX2JhY2tncm91bmRJbWFnZSA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF9iYWNrZ3JvdW5kSW1hZ2UgPSBuZXcgRXhjZWxCYWNrZ3JvdW5kSW1hZ2UoTmFtZVNwYWNlTWFuYWdlciwgVG9wTm9kZSwgdGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX2JhY2tncm91bmRJbWFnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CgkJLy8vIFJldHVybnMgdGhlIHN0eWxlIElEIGdpdmVuIGEgc3R5bGUgbmFtZS4gIAoJCS8vLyBUaGUgc3R5bGUgSUQgd2lsbCBiZSBjcmVhdGVkIGlmIG5vdCBmb3VuZCwgYnV0IG9ubHkgaWYgdGhlIHN0eWxlIG5hbWUgZXhpc3RzIQoJCS8vLyA8L3N1bW1hcnk+CgkJLy8vIDxwYXJhbSBuYW1lPSJTdHlsZU5hbWUiPjwvcGFyYW0+CgkJLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KCQlpbnRlcm5hbCBpbnQgR2V0U3R5bGVJRChzdHJpbmcgU3R5bGVOYW1lKQoJCXsKCQkJRXhjZWxOYW1lZFN0eWxlWG1sIG5hbWVkU3R5bGU9bnVsbDsKICAgICAgICAgICAgV29ya2Jvb2suU3R5bGVzLk5hbWVkU3R5bGVzLkZpbmRCeUlEKFN0eWxlTmFtZSwgcmVmIG5hbWVkU3R5bGUpOwogICAgICAgICAgICBpZiAobmFtZWRTdHlsZS5YZklkID09IGludC5NaW5WYWx1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbmFtZWRTdHlsZS5YZklkPVdvcmtib29rLlN0eWxlcy5DZWxsWGZzLkZpbmRJbmRleEJ5SUQobmFtZWRTdHlsZS5TdHlsZS5JZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5hbWVkU3R5bGUuWGZJZDsKCQl9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgd29ya2Jvb2sgb2JqZWN0CiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxXb3JrYm9vayBXb3JrYm9vawogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBfcGFja2FnZS5Xb3JrYm9vazsKICAgICAgICAgICAgfQogICAgICAgIH0KCQkjZW5kcmVnaW9uCiAgICAgICAgI2VuZHJlZ2lvbiAgLy8gRU5EIFdvcmtzaGVldCBQcml2YXRlIE1ldGhvZHMKCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBHZXQgdGhlIG5leHQgSUQgZnJvbSBhIHNoYXJlZCBmb3JtdWxhIG9yIGFuIEFycmF5IGZvcm11bGEKICAgICAgICAvLy8gU2hhcmVkZm9ydW1sYXMgd2lsbCBoYXZlIGFuIGlkIGZyb20gMC14LiBBcnJheSBmb3JtdWxhIGlkcyBzdGFydCBmcm9tIDB4NDAwMDAwMS0uIAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJpc0FycmF5Ij5JZiB0aGUgZm9ybXVsYSBpcyBhbiBhcnJheSBmb3JtdWxhPC9wYXJhbT4KICAgICAgICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPgogICAgICAgIGludGVybmFsIGludCBHZXRNYXhTaGFyZUZ1bmN0aW9uSW5kZXgoYm9vbCBpc0FycmF5KQogICAgICAgIHsKICAgICAgICAgICAgaW50IGk9X3NoYXJlZEZvcm11bGFzLkNvdW50ICsgMTsKICAgICAgICAgICAgaWYgKGlzQXJyYXkpCiAgICAgICAgICAgICAgICBpIHw9IDB4NDAwMDAwMDA7CgogICAgICAgICAgICB3aGlsZShfc2hhcmVkRm9ybXVsYXMuQ29udGFpbnNLZXkoaSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBTZXRIRkxlZ2FjeURyYXdpbmdSZWwoc3RyaW5nIHJlbElEKQogICAgICAgIHsKICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiZDpsZWdhY3lEcmF3aW5nSEYvQHI6aWQiLCByZWxJRCk7CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHZvaWQgUmVtb3ZlTGVnYWN5RHJhd2luZ1JlbChzdHJpbmcgcmVsSUQpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbiA9IFdvcmtzaGVldFhtbC5Eb2N1bWVudEVsZW1lbnQuU2VsZWN0U2luZ2xlTm9kZShzdHJpbmcuRm9ybWF0KCJkOmxlZ2FjeURyYXdpbmdbQHI6aWQ9XCJ7MH1cIl0iLCByZWxJRCksIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICBpZiAobiAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBuLlBhcmVudE5vZGUuUmVtb3ZlQ2hpbGQobik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGludGVybmFsIHZvaWQgVXBkYXRlQ2VsbHNXaXRoRGF0ZTE5MDRTZXR0aW5nKCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfdmFsdWVzKTsKICAgICAgICAgICAgdmFyIG9mZnNldCA9IFdvcmtib29rLkRhdGUxOTA0ID8gLUV4Y2VsV29ya2Jvb2suZGF0ZTE5MDRPZmZzZXQgOiBFeGNlbFdvcmtib29rLmRhdGUxOTA0T2Zmc2V0OwogICAgICAgICAgICB3aGlsZShjc2UuTW92ZU5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGNzZS5WYWx1ZSBpcyBEYXRlVGltZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBzZHYgPSAoKERhdGVUaW1lKWNzZS5WYWx1ZSkuVG9PQURhdGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2R2ICs9IG9mZnNldDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNzZS5WYWx1ZSA9IERhdGVUaW1lLkZyb21PQURhdGUoc2R2KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2F0Y2gKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHN0cmluZyBHZXRGb3JtdWxhKGludCByb3csIGludCBjb2wpCiAgICAgICAgewogICAgICAgICAgICB2YXIgdiA9IF9mb3JtdWxhcy5HZXRWYWx1ZShyb3csIGNvbCk7CiAgICAgICAgICAgIGlmICh2IGlzIGludCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIF9zaGFyZWRGb3JtdWxhc1soaW50KXZdLkdldEZvcm11bGEocm93LGNvbCwgTmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodiAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdi5Ub1N0cmluZygpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHN0cmluZyBHZXRGb3JtdWxhUjFDMShpbnQgcm93LCBpbnQgY29sKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHYgPSBfZm9ybXVsYXMuR2V0VmFsdWUocm93LCBjb2wpOwogICAgICAgICAgICBpZiAodiBpcyBpbnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBzZiA9IF9zaGFyZWRGb3JtdWxhc1soaW50KXZdOwogICAgICAgICAgICAgICAgcmV0dXJuIEV4Y2VsQ2VsbEJhc2UuVHJhbnNsYXRlVG9SMUMxKEZvcm11bGFzLlJlbW92ZUR1bW15RnVuY3Rpb24oc2YuRm9ybXVsYSksIHNmLlN0YXJ0Um93LCBzZi5TdGFydENvbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodiAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gRXhjZWxDZWxsQmFzZS5UcmFuc2xhdGVUb1IxQzEodi5Ub1N0cmluZygpLCByb3csIGNvbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgc3RyaW5nIEdldEFycmF5Rm9ybXVsYUFkZHJlc3MoaW50IHJvdywgaW50IGNvbCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciB2ID0gX2Zvcm11bGFzLkdldFZhbHVlKHJvdywgY29sKTsKICAgICAgICAgICAgaWYgKCh2IGlzIGludCkgJiYgKF9zaGFyZWRGb3JtdWxhc1soaW50KXZdLklzQXJyYXkpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3NoYXJlZEZvcm11bGFzWyhpbnQpdl0uQWRkcmVzczsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIERpc3Bvc2VJbnRlcm5hbChJRGlzcG9zYWJsZSBjYW5kaWRhdGVEaXNwb3NhYmxlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZURpc3Bvc2FibGUgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FuZGlkYXRlRGlzcG9zYWJsZS5EaXNwb3NlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoKICAgICAgICBwdWJsaWMgdm9pZCBEaXNwb3NlKCkKICAgICAgICB7CiAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfdmFsdWVzKTsKICAgICAgICAgICAgRGlzcG9zZUludGVybmFsKF9mb3JtdWxhcyk7CiAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfZmxhZ3MpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX2h5cGVyTGlua3MpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX3N0eWxlcyk7CiAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfdHlwZXMpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX2NvbW1lbnRzU3RvcmUpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX2Zvcm11bGFUb2tlbnMpOwoKICAgICAgICAgICAgX3ZhbHVlcyA9IG51bGw7CiAgICAgICAgICAgIF9mb3JtdWxhcyA9IG51bGw7CiAgICAgICAgICAgIF9mbGFncyA9IG51bGw7CiAgICAgICAgICAgIF9oeXBlckxpbmtzID0gbnVsbDsKICAgICAgICAgICAgX3N0eWxlcyA9IG51bGw7CiAgICAgICAgICAgIF90eXBlcyA9IG51bGw7CiAgICAgICAgICAgIF9jb21tZW50c1N0b3JlID0gbnVsbDsKICAgICAgICAgICAgX2Zvcm11bGFUb2tlbnMgPSBudWxsOwoKICAgICAgICAgICAgX3BhY2thZ2UgPSBudWxsOwogICAgICAgICAgICBfcGl2b3RUYWJsZXMgPSBudWxsOwogICAgICAgICAgICBfcHJvdGVjdGlvbiA9IG51bGw7CiAgICAgICAgICAgIGlmKF9zaGFyZWRGb3JtdWxhcyAhPSBudWxsKSBfc2hhcmVkRm9ybXVsYXMuQ2xlYXIoKTsKICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzID0gbnVsbDsKICAgICAgICAgICAgX3NoZWV0VmlldyA9IG51bGw7CiAgICAgICAgICAgIF90YWJsZXMgPSBudWxsOwogICAgICAgICAgICBfdm1sRHJhd2luZ3MgPSBudWxsOwogICAgICAgICAgICBfY29uZGl0aW9uYWxGb3JtYXR0aW5nID0gbnVsbDsKICAgICAgICAgICAgX2RhdGFWYWxpZGF0aW9uID0gbnVsbDsKICAgICAgICAgICAgX2RyYXdpbmdzID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0IHRoZSBFeGNlbENvbHVtbiBmb3IgY29sdW1uIChzcGFuIENvbHVtbk1pbiBhbmQgQ29sdW1uTWF4KQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW4iPjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBpbnRlcm5hbCBFeGNlbENvbHVtbiBHZXRDb2x1bW4oaW50IGNvbHVtbikKICAgICAgICB7CiAgICAgICAgICAgIHZhciBjID0gX3ZhbHVlcy5HZXRWYWx1ZSgwLCBjb2x1bW4pIGFzIEV4Y2VsQ29sdW1uOwogICAgICAgICAgICBpZiAoYyA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgcm93ID0gMCwgY29sID0gY29sdW1uOwogICAgICAgICAgICAgICAgaWYgKF92YWx1ZXMuUHJldkNlbGwocmVmIHJvdywgcmVmIGNvbCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYyA9IF92YWx1ZXMuR2V0VmFsdWUoMCwgY29sKSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgICAgICAgICBpZiAoYyAhPSBudWxsICYmIGMuQ29sdW1uTWF4ID49IGNvbHVtbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYzsKCiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbCBFcXVhbHMoRXhjZWxXb3Jrc2hlZXQgeCwgRXhjZWxXb3Jrc2hlZXQgeSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB4Lk5hbWUgPT0geS5OYW1lICYmIHguU2hlZXRJRCA9PSB5LlNoZWV0SUQgJiYgeC5Xb3Jrc2hlZXRYbWwuT3V0ZXJYbWwgPT0geS5Xb3Jrc2hlZXRYbWwuT3V0ZXJYbWw7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgaW50IEdldEhhc2hDb2RlKEV4Y2VsV29ya3NoZWV0IG9iaikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBvYmouV29ya3NoZWV0WG1sLk91dGVyWG1sLkdldEhhc2hDb2RlKCk7CiAgICAgICAgfQoJfSAgLy8gRU5EIGNsYXNzIFdvcmtzaGVldAp9Cg==