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/IGZhbHNlIDogeHIuR2V0QXR0cmlidXRlKCJjdXN0b21IZWlnaHQiKT09IjEiCiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIERhdGVUaW1lIER1cmF0aW9uRnJvbU9BRGF0ZShkb3VibGUgdmFsdWUpCiAgICAgICAgewogICAgICAgICAgICAvLyBDb252ZXJ0IHRoZSBEdXJhdGlvbiB2YWx1ZSBpbnRvIHRoZSBjb3JyZXNwb25kaW5nIERhdGVUaW1lIHZhbHVlLgogICAgICAgICAgICAvLyBUaGUgRHVyYXRpb24gdmFsdWUgaXMgcGFzc2VkIGluIGFzIGEgZnJhY3Rpb25hbCBPZmZpY2UgQXV0b21hdGlvbiBkb3VibGUgdmFsdWVzIHdoZXJlIHRoZSAKICAgICAgICAgICAgLy8gd2hvbGUgcG9ydGlvbiBpcyB0aGUgbnVtYmVyIG9mIGRheXMgYW5kIHRoZSBmcmFjdGlvbmFsIHBvcnRpb24gb2YgdGhlIG51bWJlciBpcyB0aGUgaG91cnMuCiAgICAgICAgICAgIC8vIEZvciBleGFtcGxlLCB0aGUgRHVyYXRpb24gdmFsdWUgLTEuNSByZXByZXNlbnRzIGEgbmVnYXRpdmUgZHVyYXRpb24gb2Ygb25lIGRheSBhbmQgMTIgaG91cnMuCiAgICAgICAgICAgIC8vIFdlIHVzZSB0aGlzIHRlY2huaXF1ZSByYXRoZXIgdGhhbiBjYWxsaW5nIHRoZSAnRGF0ZVRpbWUuRnJvbU9BRGF0ZSgpJyBtZXRob2QsIGJlY2F1c2UKICAgICAgICAgICAgLy8gdGhpcyB0ZWNobmlxdWUgd29ya3MgZm9yIGJvdGggcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIGR1cmF0aW9uIHZhbHVlcy4gdW5saWtlICdEYXRlVGltZS5Gcm9tT0FEYXRlKCknCiAgICAgICAgICAgIC8vIHdoaWNoIHlpZWxkcyB0aGUgd3JvbmcgcmVzdWx0IGZvciBuZWdhdGl2ZSBEdXJhdGlvbiB2YWx1ZXMuCiAgICAgICAgICAgIHJldHVybiBuZXcgRGF0ZVRpbWUoMTg5OSwgMTIsIDMwKSArIFRpbWVTcGFuLkZyb21EYXlzKHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBTZXRWYWx1ZUZyb21YbWwoWG1sVGV4dFJlYWRlciB4ciwgc3RyaW5nIHR5cGUsIGludCBzdHlsZUlELCBpbnQgcm93LCBpbnQgY29sKQogICAgICAgIHsKICAgICAgICAgICAgLy9YbWxOb2RlIHZub2RlID0gY29sTm9kZS5TZWxlY3RTaW5nbGVOb2RlKCJkOnYiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgLy9pZiAodm5vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIGlmICh0eXBlID09ICJzIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IGl4ID0geHIuUmVhZEVsZW1lbnRDb250ZW50QXNJbnQoKTsKCiAgICAgICAgICAgICAgICAvLyBUZW1wb3JhcnkgZGVidWdnaW5nIGNvZGUgdG8gbG9jYXRlIGludGVybWl0dGVudCAnSW5kZXggd2FzIG91dCBvZiByYW5nZScgZXhjZXB0aW9uLgogICAgICAgICAgICAgICAgaWYgKGl4IDwgMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKHN0cmluZy5Gb3JtYXQoIlJlYWRFbGVtZW50Q29udGVudEFzSW50IHJldHVybmVkIHZhbHVlICd7MH0nIHdoaWNoIGlzIGxlc3MgdGhhbiB6ZXJvLiIsIGl4KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXggPj0gX3BhY2thZ2UuV29ya2Jvb2suX3NoYXJlZFN0cmluZ3NMaXN0LkNvdW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiUmVhZEVsZW1lbnRDb250ZW50QXNJbnQgcmV0dXJuZWQgaW5kZXggdmFsdWUgJ3swfScgd2hpY2ggaXMgZ3JlYXRlciB0aGFuIF9zaGFyZWRTdHJpbmdzTGlzdCBjb3VudCBvZiB7MX0uIiwgaXgsIF9wYWNrYWdlLldvcmtib29rLl9zaGFyZWRTdHJpbmdzTGlzdC5Db3VudCkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIF9wYWNrYWdlLldvcmtib29rLl9zaGFyZWRTdHJpbmdzTGlzdFtpeF0uVGV4dCk7CiAgICAgICAgICAgICAgICBpZiAoX3BhY2thZ2UuV29ya2Jvb2suX3NoYXJlZFN0cmluZ3NMaXN0W2l4XS5pc1JpY2hUZXh0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF9mbGFncy5TZXRGbGFnVmFsdWUocm93LCBjb2wsIHRydWUsIENlbGxGbGFncy5SaWNoVGV4dCk7CiAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gInN0ciIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIENvbnZlcnRVdGlsLkV4Y2VsRGVjb2RlU3RyaW5nKHhyLlJlYWRFbGVtZW50Q29udGVudEFzU3RyaW5nKCkpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh0eXBlID09ICJiIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgKHhyLlJlYWRFbGVtZW50Q29udGVudEFzU3RyaW5nKCkhPSIwIikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gImUiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCBHZXRFcnJvclR5cGUoeHIuUmVhZEVsZW1lbnRDb250ZW50QXNTdHJpbmcoKSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyaW5nIHYgPSB4ci5SZWFkRWxlbWVudENvbnRlbnRBc1N0cmluZygpOwogICAgICAgICAgICAgICAgdmFyIG5mID0gV29ya2Jvb2suU3R5bGVzLkNlbGxYZnNbc3R5bGVJRF0uTnVtYmVyRm9ybWF0SWQ7CiAgICAgICAgICAgICAgICBpZiAoKG5mID49IDIwICYmIG5mIDw9IDIxKSB8fCAobmYgPj0gNDUgJiYgbmYgPD0gNDcpKSAgLy8gRHVyYXRpb24KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkb3VibGUgcmVzOwogICAgICAgICAgICAgICAgICAgIGlmIChkb3VibGUuVHJ5UGFyc2UodiwgTnVtYmVyU3R5bGVzLkFueSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSwgb3V0IHJlcykpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoV29ya2Jvb2suRGF0ZTE5MDQpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcyArPSBFeGNlbFdvcmtib29rLmRhdGUxOTA0T2Zmc2V0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXMgPj0gLTY1NzQzNS4wICYmIHJlcyA8IDI5NTg0NjUuOTk5OTk5OSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBEdXJhdGlvbiB2YWx1ZSBleHByZXNzZWQgYXMgYSBEYXRlVGltZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIER1cmF0aW9uRnJvbU9BRGF0ZShyZXMpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvcGUgd2l0aCBHb29nbGUgU2hlZXRzIGV4cG9ydCBvZiBjZWxscyBoYXZpbmcgYSBmb3JtdWxhLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmF0aGVyIHRoYW4gZXhwb3J0aW5nIHRoZSBuYXRpdmUgdmFsdWUsIHRoZXkgZXhwb3J0IHRoZSBmb3JtYXR0ZWQgdmFsdWUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCB2KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29wZSB3aXRoIEdvb2dsZSBTaGVldHMgZXhwb3J0IG9mIGNlbGxzIGhhdmluZyBhIGZvcm11bGEuCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJhdGhlciB0aGFuIGV4cG9ydGluZyB0aGUgbmF0aXZlIHZhbHVlLCB0aGV5IGV4cG9ydCB0aGUgZm9ybWF0dGVkIHZhbHVlLgogICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCB2KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICgobmYgPj0gMTQgJiYgbmYgPD0gMTkpIHx8IChuZiA9PSAyMikpICAgLy8gRGF0ZVRpbWUKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkb3VibGUgcmVzOwogICAgICAgICAgICAgICAgICAgIGlmIChkb3VibGUuVHJ5UGFyc2UodiwgTnVtYmVyU3R5bGVzLkFueSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSwgb3V0IHJlcykpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoV29ya2Jvb2suRGF0ZTE5MDQpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcyArPSBFeGNlbFdvcmtib29rLmRhdGUxOTA0T2Zmc2V0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXMgPj0gLTY1NzQzNS4wICYmIHJlcyA8IDI5NTg0NjUuOTk5OTk5OSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgRGF0ZVRpbWUuRnJvbU9BRGF0ZShyZXMpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvcGUgd2l0aCBHb29nbGUgU2hlZXRzIGV4cG9ydCBvZiBjZWxscyBoYXZpbmcgYSBmb3JtdWxhLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmF0aGVyIHRoYW4gZXhwb3J0aW5nIHRoZSBuYXRpdmUgdmFsdWUsIHRoZXkgZXhwb3J0IHRoZSBmb3JtYXR0ZWQgdmFsdWUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCB2KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBDb3BlIHdpdGggR29vZ2xlIFNoZWV0cyBleHBvcnQgb2YgY2VsbHMgaGF2aW5nIGEgZm9ybXVsYS4KICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmF0aGVyIHRoYW4gZXhwb3J0aW5nIHRoZSBuYXRpdmUgdmFsdWUsIHRoZXkgZXhwb3J0IHRoZSBmb3JtYXR0ZWQgdmFsdWUuCiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIHYpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkb3VibGUgZDsKICAgICAgICAgICAgICAgICAgICBpZiAoZG91YmxlLlRyeVBhcnNlKHYsIE51bWJlclN0eWxlcy5BbnksIEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUsIG91dCBkKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIGQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBDb3BlIHdpdGggR29vZ2xlIFNoZWV0cyBleHBvcnQgb2YgY2VsbHMgaGF2aW5nIGEgZm9ybXVsYS4KICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmF0aGVyIHRoYW4gZXhwb3J0aW5nIHRoZSBuYXRpdmUgdmFsdWUsIHRoZXkgZXhwb3J0IHRoZSBmb3JtYXR0ZWQgdmFsdWUuCiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIHYpOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy9fdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCBkb3VibGUuTmFOKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgb2JqZWN0IEdldEVycm9yVHlwZShzdHJpbmcgdikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBFeGNlbEVycm9yVmFsdWUuUGFyc2Uodi5Ub1VwcGVyKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpKTsKICAgICAgICAgICAgLy9zd2l0Y2godi5Ub1VwcGVyKCkpCiAgICAgICAgICAgIC8vewogICAgICAgICAgICAvLyAgICBjYXNlICIjRElWLzAhIjoKICAgICAgICAgICAgLy8gICAgICAgIHJldHVybiBuZXcgRXhjZWxFcnJvclZhbHVlLmNyZShlRXJyb3JUeXBlLkRpdjApOwogICAgICAgICAgICAvLyAgICBjYXNlICIjUkVGISI6CiAgICAgICAgICAgIC8vICAgICAgICByZXR1cm4gbmV3IEV4Y2VsRXJyb3JWYWx1ZShlRXJyb3JUeXBlLlJlZik7CiAgICAgICAgICAgIC8vICAgIGNhc2UgIiNOL0EiOgogICAgICAgICAgICAvLyAgICAgICAgcmV0dXJuIG5ldyBFeGNlbEVycm9yVmFsdWUoZUVycm9yVHlwZS5OQSk7CiAgICAgICAgICAgIC8vICAgIGNhc2UgIiNOQU1FPyI6CiAgICAgICAgICAgIC8vICAgICAgICByZXR1cm4gbmV3IEV4Y2VsRXJyb3JWYWx1ZShlRXJyb3JUeXBlLk5hbWUpOwogICAgICAgICAgICAvLyAgICBjYXNlICIjTlVMTCEiOgogICAgICAgICAgICAvLyAgICAgICAgcmV0dXJuIG5ldyBFeGNlbEVycm9yVmFsdWUoZUVycm9yVHlwZS5OdWxsKTsKICAgICAgICAgICAgLy8gICAgY2FzZSAiI05VTSEiOgogICAgICAgICAgICAvLyAgICAgICAgcmV0dXJuIG5ldyBFeGNlbEVycm9yVmFsdWUoZUVycm9yVHlwZS5OdW0pOwogICAgICAgICAgICAvLyAgICBkZWZhdWx0OgogICAgICAgICAgICAvLyAgICAgICAgcmV0dXJuIG5ldyBFeGNlbEVycm9yVmFsdWUoZUVycm9yVHlwZS5WYWx1ZSk7CiAgICAgICAgICAgIC8vfQogICAgICAgIH0KICAgICAgICAvL3ByaXZhdGUgc3RyaW5nIEdldFNoYXJlZFN0cmluZyhpbnQgc3RyaW5nSUQpCiAgICAgICAgLy97CiAgICAgICAgLy8gICAgc3RyaW5nIHJldFZhbHVlID0gbnVsbDsKICAgICAgICAvLyAgICBYbWxOb2RlTGlzdCBzdHJpbmdOb2RlcyA9IHhsUGFja2FnZS5Xb3JrYm9vay5TaGFyZWRTdHJpbmdzWG1sLlNlbGVjdE5vZGVzKHN0cmluZy5Gb3JtYXQoIi8vZDpzaSIsIHN0cmluZ0lEKSwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgLy8gICAgWG1sTm9kZSBzdHJpbmdOb2RlID0gc3RyaW5nTm9kZXNbc3RyaW5nSURdOwogICAgICAgIC8vICAgIGlmIChzdHJpbmdOb2RlICE9IG51bGwpCiAgICAgICAgLy8gICAgICAgIHJldFZhbHVlID0gc3RyaW5nTm9kZS5Jbm5lclRleHQ7CiAgICAgICAgLy8gICAgcmV0dXJuIChyZXRWYWx1ZSk7CiAgICAgICAgLy99CiAgICAgICAgI2VuZHJlZ2lvbgoJCSNyZWdpb24gSGVhZGVyRm9vdGVyCgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBBIHJlZmVyZW5jZSB0byB0aGUgaGVhZGVyIGFuZCBmb290ZXIgY2xhc3Mgd2hpY2ggYWxsb3dzIHlvdSB0byAKCQkvLy8gc2V0IHRoZSBoZWFkZXIgYW5kIGZvb3RlciBmb3IgYWxsIG9kZCwgZXZlbiBhbmQgZmlyc3QgcGFnZXMgb2YgdGhlIHdvcmtzaGVldAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxyZW1hcmtzPgogICAgICAgIC8vLyBUbyBmb3JtYXQgdGhlIHRleHQgeW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBmb3JtYXQKICAgICAgICAvLy8gPGxpc3QgdHlwZT0idGFibGUiPgogICAgICAgIC8vLyA8bGlzdGhlYWRlcj48dGVybT5QcmVmaXg8L3Rlcm0+PGRlc2NyaXB0aW9uPkRlc2NyaXB0aW9uPC9kZXNjcmlwdGlvbj48L2xpc3RoZWFkZXI+CiAgICAgICAgLy8vIDxpdGVtPjx0ZXJtPiZhbXA7VTwvdGVybT48ZGVzY3JpcHRpb24+VW5kZXJsaW5lZDwvZGVzY3JpcHRpb24+PC9pdGVtPgogICAgICAgIC8vLyA8aXRlbT48dGVybT4mYW1wO0U8L3Rlcm0+PGRlc2NyaXB0aW9uPkRvdWJsZSBVbmRlcmxpbmU8L2Rlc2NyaXB0aW9uPjwvaXRlbT4KICAgICAgICAvLy8gPGl0ZW0+PHRlcm0+JmFtcDtLOnh4eHh4eDwvdGVybT48ZGVzY3JpcHRpb24+Q29sb3IuIGV4ICZhbXA7SzpGRjAwMDAgZm9yIHJlZDwvZGVzY3JpcHRpb24+PC9pdGVtPgogICAgICAgIC8vLyA8aXRlbT48dGVybT4mYW1wOyJGb250LFJlZ3VsYXIgQm9sZCBJdGFsaWMiPC90ZXJtPjxkZXNjcmlwdGlvbj5DaGFuZ2VzIHRoZSBmb250LiBSZWd1bGFyIG9yIEJvbGQgb3IgSXRhbGljIG9yIEJvbGQgSXRhbGljIGNhbiBiZSB1c2VkLiBleCAmYW1wOyJBcmlhbCxCb2xkIEl0YWxpYyI8L2Rlc2NyaXB0aW9uPjwvaXRlbT4KICAgICAgICAvLy8gPGl0ZW0+PHRlcm0+JmFtcDtubjwvdGVybT48ZGVzY3JpcHRpb24+Q2hhbmdlIGZvbnQgc2l6ZS4gbm4gaXMgYW4gaW50ZWdlci4gZXggJmFtcDsyNDwvZGVzY3JpcHRpb24+PC9pdGVtPgogICAgICAgIC8vLyA8aXRlbT48dGVybT4mYW1wO0c8L3Rlcm0+PGRlc2NyaXB0aW9uPlBsYWNlaG9sZGVyIGZvciBpbWFnZXMuIEltYWdlcyBjYW4gbm90IGJlIGFkZGVkIGJ5IHRoZSBsaWJyYXJ5LCBidXQgaXRzIHBvc3NpYmxlIHRvIHVzZSBpbiBhIHRlbXBsYXRlLjwvZGVzY3JpcHRpb24+PC9pdGVtPgogICAgICAgIC8vLyA8L2xpc3Q+CiAgICAgICAgLy8vIDwvcmVtYXJrcz4KICAgICAgICBwdWJsaWMgRXhjZWxIZWFkZXJGb290ZXIgSGVhZGVyRm9vdGVyCgkJewoJCQlnZXQKCQkJewoJCQkJaWYgKF9oZWFkZXJGb290ZXIgPT0gbnVsbCkKCQkJCXsKICAgICAgICAgICAgICAgICAgICBYbWxOb2RlIGhlYWRlckZvb3Rlck5vZGUgPSBUb3BOb2RlLlNlbGVjdFNpbmdsZU5vZGUoImQ6aGVhZGVyRm9vdGVyIiwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgICAgICAgICAgaWYgKGhlYWRlckZvb3Rlck5vZGUgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyRm9vdGVyTm9kZT0gQ3JlYXRlTm9kZSgiZDpoZWFkZXJGb290ZXIiKTsKICAgICAgICAgICAgICAgICAgICBfaGVhZGVyRm9vdGVyID0gbmV3IEV4Y2VsSGVhZGVyRm9vdGVyKE5hbWVTcGFjZU1hbmFnZXIsIGhlYWRlckZvb3Rlck5vZGUsIHRoaXMpOwoJCQkJfSAgICAgICAgICAgICAgICAKCQkJCXJldHVybiAoX2hlYWRlckZvb3Rlcik7CgkJCX0KCQl9CgkJI2VuZHJlZ2lvbgoKICAgICAgICAjcmVnaW9uICJQcmludGVyU2V0dGluZ3MiCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBQcmludGVyIHNldHRpbmdzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxQcmludGVyU2V0dGluZ3MgUHJpbnRlclNldHRpbmdzCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIHBzID0gbmV3IEV4Y2VsUHJpbnRlclNldHRpbmdzKE5hbWVTcGFjZU1hbmFnZXIsIFRvcE5vZGUsIHRoaXMpOwogICAgICAgICAgICAgICAgcHMuU2NoZW1hTm9kZU9yZGVyID0gU2NoZW1hTm9kZU9yZGVyOwogICAgICAgICAgICAgICAgcmV0dXJuIHBzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICNlbmRyZWdpb24KCgkJI2VuZHJlZ2lvbiAvLyBFTkQgV29ya3NoZWV0IFB1YmxpYyBQcm9wZXJ0aWVzCgoJCSNyZWdpb24gV29ya3NoZWV0IFB1YmxpYyBNZXRob2RzCiAgICAgICAgCiAgICAgICAgLy8vLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vLy8gUHJvdmlkZXMgYWNjZXNzIHRvIGFuIGluZGl2aWR1YWwgY2VsbCB3aXRoaW4gdGhlIHdvcmtzaGVldC4KICAgICAgICAvLy8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vLy8gPHBhcmFtIG5hbWU9InJvdyI+VGhlIHJvdyBudW1iZXIgaW4gdGhlIHdvcmtzaGVldDwvcGFyYW0+CiAgICAgICAgLy8vLy8gPHBhcmFtIG5hbWU9ImNvbCI+VGhlIGNvbHVtbiBudW1iZXIgaW4gdGhlIHdvcmtzaGVldDwvcGFyYW0+CiAgICAgICAgLy8vLy8gPHJldHVybnM+PC9yZXR1cm5zPgkJCiAgICAgICAgLy9pbnRlcm5hbCBFeGNlbENlbGwgQ2VsbChpbnQgcm93LCBpbnQgY29sKQogICAgICAgIC8vewogICAgICAgIC8vICAgIHJldHVybiBuZXcgRXhjZWxDZWxsKF92YWx1ZXMsIHJvdywgY29sKTsKICAgICAgICAvL30KICAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgICAvLy8gUHJvdmlkZXMgYWNjZXNzIHRvIGEgcmFuZ2Ugb2YgY2VsbHMKICAgICAgICAvLy8gPC9zdW1tYXJ5PiAgCiAgICAgICAgcHVibGljIEV4Y2VsUmFuZ2UgQ2VsbHMKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBFeGNlbFJhbmdlKHRoaXMsIDEsIDEsIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBQcm92aWRlcyBhY2Nlc3MgdG8gdGhlIHNlbGVjdGVkIHJhbmdlIG9mIGNlbGxzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4gIAogICAgICAgIHB1YmxpYyBFeGNlbFJhbmdlIFNlbGVjdGVkUmFuZ2UKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBFeGNlbFJhbmdlKHRoaXMsIFZpZXcuU2VsZWN0ZWRSYW5nZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgTWVyZ2VDZWxsc0NvbGxlY3Rpb24gX21lcmdlZENlbGxzID0gbmV3IE1lcmdlQ2VsbHNDb2xsZWN0aW9uKCk7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBBZGRyZXNzZXMgdG8gbWVyZ2VkIHJhbmdlcwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIE1lcmdlQ2VsbHNDb2xsZWN0aW9uIE1lcmdlZENlbGxzCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiBfbWVyZ2VkQ2VsbHM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgoJCS8vLyBQcm92aWRlcyBhY2Nlc3MgdG8gYW4gaW5kaXZpZHVhbCByb3cgd2l0aGluIHRoZSB3b3Jrc2hlZXQgc28geW91IGNhbiBzZXQgaXRzIHByb3BlcnRpZXMuCgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9InJvdyI+VGhlIHJvdyBudW1iZXIgaW4gdGhlIHdvcmtzaGVldDwvcGFyYW0+CgkJLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KCQlwdWJsaWMgRXhjZWxSb3cgUm93KGludCByb3cpCgkJewogICAgICAgICAgICAvL0V4Y2VsUm93IHI7CiAgICAgICAgICAgIC8vdWxvbmcgaWQgPSBFeGNlbFJvdy5HZXRSb3dJRChfc2hlZXRJRCwgcm93KTsKICAgICAgICAgICAgLy9UT0RPOiBGaXhhLgogICAgICAgICAgICAvL3ZhciB2ID0gX3ZhbHVlcy5HZXRWYWx1ZShyb3csIDApOwogICAgICAgICAgICAvL2lmICh2IT1udWxsKQogICAgICAgICAgICAvL3sKICAgICAgICAgICAgLy8gICAgdmFyIHJpPShSb3dJbnRlcm5hbCl2OwogICAgICAgICAgICAvLyAgICByID0gbmV3IEV4Y2VsUm93KHRoaXMsIHJvdykKICAgICAgICAgICAgLy99CiAgICAgICAgICAgIC8vZWxzZQogICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgIC8vciA9IG5ldyBFeGNlbFJvdyh0aGlzLCByb3cpOwogICAgICAgICAgICAgICAgLy9fdmFsdWVzLlNldFZhbHVlKHJvdywgMCwgcik7CiAgICAgICAgICAgICAgICAvL19yb3dzLkFkZChyKTsKICAgICAgICAgICAgLy99CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIGlmIChyb3cgPCAxIHx8IHJvdyA+IEV4Y2VsUGFja2FnZS5NYXhSb3dzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEFyZ3VtZW50RXhjZXB0aW9uKCJSb3cgbnVtYmVyIG91dCBvZiBib3VuZHMiKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ldyBFeGNlbFJvdyh0aGlzLCByb3cpOwogICAgICAgICAgICAvL3JldHVybiByOwoJCX0KCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFByb3ZpZGVzIGFjY2VzcyB0byBhbiBpbmRpdmlkdWFsIGNvbHVtbiB3aXRoaW4gdGhlIHdvcmtzaGVldCBzbyB5b3UgY2FuIHNldCBpdHMgcHJvcGVydGllcy4KCQkvLy8gPC9zdW1tYXJ5PgoJCS8vLyA8cGFyYW0gbmFtZT0iY29sIj5UaGUgY29sdW1uIG51bWJlciBpbiB0aGUgd29ya3NoZWV0PC9wYXJhbT4KCQkvLy8gPHJldHVybnM+PC9yZXR1cm5zPgoJCXB1YmxpYyBFeGNlbENvbHVtbiBDb2x1bW4oaW50IGNvbCkKCQl7ICAgICAgICAgICAgCiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIGlmIChjb2wgPCAxIHx8IGNvbCA+IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEFyZ3VtZW50RXhjZXB0aW9uKCJDb2x1bW4gbnVtYmVyIG91dCBvZiBib3VuZHMiKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGNvbHVtbiA9IF92YWx1ZXMuR2V0VmFsdWUoMCwgY29sKSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgaWYgKGNvbHVtbiE9bnVsbCkKICAgICAgICAgICAgeyAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKGNvbHVtbi5Db2x1bW5NaW4gIT0gY29sdW1uLkNvbHVtbk1heCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnQgbWF4Q29sID0gY29sdW1uLkNvbHVtbk1heDsKICAgICAgICAgICAgICAgICAgICBjb2x1bW4uQ29sdW1uTWF4ID0gY29sOwogICAgICAgICAgICAgICAgICAgIEV4Y2VsQ29sdW1uIGNvcHkgPSBDb3B5Q29sdW1uKGNvbHVtbiwgY29sICsgMSwgbWF4Q29sKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCByPTAsIGM9Y29sOwogICAgICAgICAgICAgICAgaWYgKF92YWx1ZXMuUHJldkNlbGwocmVmIHIsIHJlZiBjKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjb2x1bW4gPSBfdmFsdWVzLkdldFZhbHVlKDAsIGMpIGFzIEV4Y2VsQ29sdW1uOwogICAgICAgICAgICAgICAgICAgIGludCBtYXhDb2wgPSBjb2x1bW4uQ29sdW1uTWF4OwogICAgICAgICAgICAgICAgICAgIGlmIChtYXhDb2wgPj0gY29sKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uLkNvbHVtbk1heCA9IGNvbC0xOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF4Q29sID4gY29sKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeGNlbENvbHVtbiBuZXdDID0gQ29weUNvbHVtbihjb2x1bW4sIGNvbCArIDEsIG1heENvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvcHlDb2x1bW4oY29sdW1uLCBjb2wsIGNvbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy9mb3JlYWNoIChFeGNlbENvbHVtbiBjaGVja0NvbHVtbiBpbiBfY29sdW1ucykKICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgLy8gICAgaWYgKGNvbCA+IGNoZWNrQ29sdW1uLkNvbHVtbk1pbiAmJiBjb2wgPD0gY2hlY2tDb2x1bW4uQ29sdW1uTWF4KQogICAgICAgICAgICAgICAgLy8gICAgewogICAgICAgICAgICAgICAgLy8gICAgICAgIGludCBtYXhDb2wgPSBjaGVja0NvbHVtbi5Db2x1bW5NYXg7CiAgICAgICAgICAgICAgICAvLyAgICAgICAgY2hlY2tDb2x1bW4uQ29sdW1uTWF4ID0gY29sIC0gMTsKICAgICAgICAgICAgICAgIC8vICAgICAgICBpZiAobWF4Q29sID4gY29sKQogICAgICAgICAgICAgICAgLy8gICAgICAgIHsKICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgRXhjZWxDb2x1bW4gbmV3QyA9IENvcHlDb2x1bW4oY2hlY2tDb2x1bW4sIGNvbCArIDEsIG1heENvbCk7CiAgICAgICAgICAgICAgICAvLyAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gICAgICAgIHJldHVybiBDb3B5Q29sdW1uKGNoZWNrQ29sdW1uLCBjb2wsY29sKTsgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vICAgIH0KICAgICAgICAgICAgICAgIC8vfQogICAgICAgICAgICAgICAgY29sdW1uID0gbmV3IEV4Y2VsQ29sdW1uKHRoaXMsIGNvbCk7CiAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKDAsIGNvbCwgY29sdW1uKTsKICAgICAgICAgICAgICAgIC8vX2NvbHVtbnMuQWRkKGNvbHVtbik7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBjb2x1bW47CgkJfQoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHdvcmtzaGVldAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxyZXR1cm5zPlRoZSBuYW1lIG9mIHRoZSB3b3Jrc2hlZXQ8L3JldHVybnM+CiAgICAgICAgcHVibGljIG92ZXJyaWRlIHN0cmluZyBUb1N0cmluZygpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gTmFtZTsKICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgRXhjZWxDb2x1bW4gQ29weUNvbHVtbihFeGNlbENvbHVtbiBjLCBpbnQgY29sLCBpbnQgbWF4Q29sKQogICAgICAgIHsKICAgICAgICAgICAgRXhjZWxDb2x1bW4gbmV3QyA9IG5ldyBFeGNlbENvbHVtbih0aGlzLCBjb2wpOwogICAgICAgICAgICBuZXdDLkNvbHVtbk1heCA9IG1heENvbCA8IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zID8gbWF4Q29sIDogRXhjZWxQYWNrYWdlLk1heENvbHVtbnM7CiAgICAgICAgICAgIGlmIChjLlN0eWxlTmFtZSAhPSAiIikKICAgICAgICAgICAgICAgIG5ld0MuU3R5bGVOYW1lID0gYy5TdHlsZU5hbWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIG5ld0MuU3R5bGVJRCA9IGMuU3R5bGVJRDsKCiAgICAgICAgICAgIG5ld0MuT3V0bGluZUxldmVsID0gYy5PdXRsaW5lTGV2ZWw7CiAgICAgICAgICAgIG5ld0MuUGhvbmV0aWMgPSBjLlBob25ldGljOwogICAgICAgICAgICBuZXdDLkJlc3RGaXQgPSBjLkJlc3RGaXQ7CiAgICAgICAgICAgIC8vX2NvbHVtbnMuQWRkKG5ld0MpOwogICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKDAsIGNvbCwgbmV3Qyk7CiAgICAgICAgICAgIG5ld0MuX3dpZHRoID0gYy5fd2lkdGg7CiAgICAgICAgICAgIG5ld0MuX2hpZGRlbiA9IGMuX2hpZGRlbjsKICAgICAgICAgICAgcmV0dXJuIG5ld0M7CiAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBNYWtlIHRoZSBjdXJyZW50IHdvcmtzaGVldCBhY3RpdmUuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgdm9pZCBTZWxlY3QoKQogICAgICAgIHsKICAgICAgICAgICAgVmlldy5UYWJTZWxlY3RlZCA9IHRydWU7CiAgICAgICAgICAgIC8vU2VsZWN0KEFkZHJlc3MsIHRydWUpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNlbGVjdHMgYSByYW5nZSBpbiB0aGUgd29ya3NoZWV0LiBUaGUgYWN0aXZlIGNlbGwgaXMgdGhlIHRvcG1vc3QgY2VsbC4KICAgICAgICAvLy8gTWFrZSB0aGUgY3VycmVudCB3b3Jrc2hlZXQgYWN0aXZlLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJBZGRyZXNzIj5BbiBhZGRyZXNzIHJhbmdlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTZWxlY3Qoc3RyaW5nIEFkZHJlc3MpCiAgICAgICAgewogICAgICAgICAgICBTZWxlY3QoQWRkcmVzcywgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gU2VsZWN0cyBhIHJhbmdlIGluIHRoZSB3b3Jrc2hlZXQuIFRoZSBhY3RpY2UgY2VsbCBpcyB0aGUgdG9wbW9zdCBjZWxsLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJBZGRyZXNzIj5BIHJhbmdlIG9mIGNlbGxzPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlNlbGVjdFNoZWV0Ij5NYWtlIHRoZSBzaGVldCBhY3RpdmU8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIFNlbGVjdChzdHJpbmcgQWRkcmVzcywgYm9vbCBTZWxlY3RTaGVldCkKICAgICAgICB7CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIGludCBmcm9tQ29sLCBmcm9tUm93LCB0b0NvbCwgdG9Sb3c7CiAgICAgICAgICAgIC8vR2V0IHJvd3MgYW5kIGNvbHVtbnMgYW5kIHZhbGlkYXRlIGFzIHdlbGwKICAgICAgICAgICAgRXhjZWxDZWxsQmFzZS5HZXRSb3dDb2xGcm9tQWRkcmVzcyhBZGRyZXNzLCBvdXQgZnJvbVJvdywgb3V0IGZyb21Db2wsIG91dCB0b1Jvdywgb3V0IHRvQ29sKTsKCiAgICAgICAgICAgIGlmIChTZWxlY3RTaGVldCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVmlldy5UYWJTZWxlY3RlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgVmlldy5TZWxlY3RlZFJhbmdlID0gQWRkcmVzczsKICAgICAgICAgICAgVmlldy5BY3RpdmVDZWxsID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZyb21Sb3csIGZyb21Db2wpOyAgICAgICAgICAgIAogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNlbGVjdHMgYSByYW5nZSBpbiB0aGUgd29ya3NoZWV0LiBUaGUgYWN0aXZlIGNlbGwgaXMgdGhlIHRvcG1vc3QgY2VsbCBvZiB0aGUgZmlyc3QgYWRkcmVzcy4KICAgICAgICAvLy8gTWFrZSB0aGUgY3VycmVudCB3b3Jrc2hlZXQgYWN0aXZlLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJBZGRyZXNzIj5BbiBhZGRyZXNzIHJhbmdlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTZWxlY3QoRXhjZWxBZGRyZXNzIEFkZHJlc3MpCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBTZWxlY3QoQWRkcmVzcywgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gU2VsZWN0cyBhIHJhbmdlIGluIHRoZSB3b3Jrc2hlZXQuIFRoZSBhY3RpdmUgY2VsbCBpcyB0aGUgdG9wbW9zdCBjZWxsIG9mIHRoZSBmaXJzdCBhZGRyZXNzLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJBZGRyZXNzIj5BIHJhbmdlIG9mIGNlbGxzPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlNlbGVjdFNoZWV0Ij5NYWtlIHRoZSBzaGVldCBhY3RpdmU8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIFNlbGVjdChFeGNlbEFkZHJlc3MgQWRkcmVzcywgYm9vbCBTZWxlY3RTaGVldCkKICAgICAgICB7CgogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpZiAoU2VsZWN0U2hlZXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFZpZXcuVGFiU2VsZWN0ZWQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN0cmluZyBzZWxBZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKEFkZHJlc3MuU3RhcnQuUm93LCBBZGRyZXNzLlN0YXJ0LkNvbHVtbikgKyAiOiIgKyBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoQWRkcmVzcy5FbmQuUm93LCBBZGRyZXNzLkVuZC5Db2x1bW4pOwogICAgICAgICAgICBpZiAoQWRkcmVzcy5BZGRyZXNzZXMgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGEgaW4gQWRkcmVzcy5BZGRyZXNzZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc2VsQWRkcmVzcyArPSAiICIgKyBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoYS5TdGFydC5Sb3csIGEuU3RhcnQuQ29sdW1uKSArICI6IiArIEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhhLkVuZC5Sb3csIGEuRW5kLkNvbHVtbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgVmlldy5TZWxlY3RlZFJhbmdlID0gc2VsQWRkcmVzczsKICAgICAgICAgICAgVmlldy5BY3RpdmVDZWxsID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKEFkZHJlc3MuU3RhcnQuUm93LCBBZGRyZXNzLlN0YXJ0LkNvbHVtbik7CiAgICAgICAgfQoKCQkjcmVnaW9uIEluc2VydFJvdwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gSW5zZXJ0cyBhIG5ldyByb3cgaW50byB0aGUgc3ByZWFkc2hlZXQuICBFeGlzdGluZyByb3dzIGJlbG93IHRoZSBwb3NpdGlvbiBhcmUgCiAgICAgICAgLy8vIHNoaWZ0ZWQgZG93bi4gIEFsbCBmb3JtdWxhIGFyZSB1cGRhdGVkIHRvIHRha2UgYWNjb3VudCBvZiB0aGUgbmV3IHJvdy4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icm93RnJvbSI+VGhlIHBvc2l0aW9uIG9mIHRoZSBuZXcgcm93PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd3MiPk51bWJlciBvZiByb3dzIHRvIGluc2VydDwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgSW5zZXJ0Um93KGludCByb3dGcm9tLCBpbnQgcm93cykKICAgICAgICB7CiAgICAgICAgICAgIEluc2VydFJvdyhyb3dGcm9tLCByb3dzLCAwKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgoJCS8vLyBJbnNlcnRzIGEgbmV3IHJvdyBpbnRvIHRoZSBzcHJlYWRzaGVldC4gIEV4aXN0aW5nIHJvd3MgYmVsb3cgdGhlIHBvc2l0aW9uIGFyZSAKCQkvLy8gc2hpZnRlZCBkb3duLiAgQWxsIGZvcm11bGEgYXJlIHVwZGF0ZWQgdG8gdGFrZSBhY2NvdW50IG9mIHRoZSBuZXcgcm93LgoJCS8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dGcm9tIj5UaGUgcG9zaXRpb24gb2YgdGhlIG5ldyByb3c8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icm93cyI+TnVtYmVyIG9mIHJvd3MgdG8gaW5zZXJ0LjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb3B5U3R5bGVzRnJvbVJvdyI+Q29weSBTdHlsZXMgZnJvbSB0aGlzIHJvdy4gQXBwbGllZCB0byBhbGwgaW5zZXJ0ZWQgcm93czwvcGFyYW0+CgkJcHVibGljIHZvaWQgIEluc2VydFJvdyhpbnQgcm93RnJvbSwgaW50IHJvd3MsIGludCBjb3B5U3R5bGVzRnJvbVJvdykKCQl7CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICB2YXIgZCA9IERpbWVuc2lvbjsKCiAgICAgICAgICAgIGlmIChyb3dGcm9tIDwgMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24oInJvd0Zyb20gY2FuJ3QgYmUgbGVzc2VyIHRoYXQgMSIpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9DaGVjayB0aGF0IGNlbGxzIGFyZW4ndCBzaGlmdGVkIG91dHNpZGUgdGhlIGJvdW5kcmllcwogICAgICAgICAgICBpZiAoZCAhPSBudWxsICYmIGQuRW5kLlJvdyA+IHJvd0Zyb20gJiYgZC5FbmQuUm93ICsgcm93cyA+IEV4Y2VsUGFja2FnZS5NYXhSb3dzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbigiQ2FuJ3QgaW5zZXJ0LiBSb3dzIHdpbGwgYmUgc2hpZnRlZCBvdXRzaWRlIHRoZSBib3VuZHJpZXMgb2YgdGhlIHdvcmtzaGVldC4iKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxvY2sgKHRoaXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF92YWx1ZXMuSW5zZXJ0KHJvd0Zyb20sIDAsIHJvd3MsIDApOwogICAgICAgICAgICAgICAgX2Zvcm11bGFzLkluc2VydChyb3dGcm9tLCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgIF9zdHlsZXMuSW5zZXJ0KHJvd0Zyb20sIDAsIHJvd3MsIDApOwogICAgICAgICAgICAgICAgX3R5cGVzLkluc2VydChyb3dGcm9tLCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgIF9jb21tZW50c1N0b3JlLkluc2VydChyb3dGcm9tLCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgIF9oeXBlckxpbmtzLkluc2VydChyb3dGcm9tLCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgIF9mbGFncy5JbnNlcnQocm93RnJvbSwgMCwgcm93cywgMCk7CgogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGYgaW4gX3NoYXJlZEZvcm11bGFzLlZhbHVlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZi5TdGFydFJvdyA+PSByb3dGcm9tKSBmLlN0YXJ0Um93ICs9IHJvd3M7CiAgICAgICAgICAgICAgICAgICAgdmFyIGEgPSBuZXcgRXhjZWxBZGRyZXNzQmFzZShmLkFkZHJlc3MpOwogICAgICAgICAgICAgICAgICAgIGlmIChhLl9mcm9tUm93ID49IHJvd0Zyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhLl9mcm9tUm93ICs9IHJvd3M7CiAgICAgICAgICAgICAgICAgICAgICAgIGEuX3RvUm93ICs9IHJvd3M7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGEuX3RvUm93ID49IHJvd0Zyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhLl90b1JvdyArPSByb3dzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBmLkFkZHJlc3MgPSBFeGNlbEFkZHJlc3NCYXNlLkdldEFkZHJlc3MoYS5fZnJvbVJvdywgYS5fZnJvbUNvbCwgYS5fdG9Sb3csIGEuX3RvQ29sKTsKICAgICAgICAgICAgICAgICAgICBmLkZvcm11bGEgPSBFeGNlbENlbGxCYXNlLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKGYuRm9ybXVsYSwgcm93cywgMCwgcm93RnJvbSwgMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX2Zvcm11bGFzKTsKICAgICAgICAgICAgICAgIHdoaWxlIChjc2UuTmV4dCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjc2UuVmFsdWUgaXMgc3RyaW5nKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3NlLlZhbHVlID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhjc2UuVmFsdWUuVG9TdHJpbmcoKSwgcm93cywgMCwgcm93RnJvbSwgMCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEZpeE1lcmdlZENlbGxzUm93KHJvd0Zyb20sIHJvd3MsIGZhbHNlKTsKICAgICAgICAgICAgICAgIGlmIChjb3B5U3R5bGVzRnJvbVJvdyA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNzZVMgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8aW50Pihfc3R5bGVzLCBjb3B5U3R5bGVzRnJvbVJvdywgMCwgY29weVN0eWxlc0Zyb21Sb3csIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsgLy9GaXhlcyBpc3N1ZSAxNTA2OCAsIDE1MDkwCiAgICAgICAgICAgICAgICAgICAgd2hpbGUoY3NlUy5OZXh0KCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciByID0gMDsgciA8IHJvd3M7IHIrKykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3N0eWxlcy5TZXRWYWx1ZShyb3dGcm9tICsgciwgY3NlUy5Db2x1bW4sIGNzZVMuVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRibCBpbiBUYWJsZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGJsLkFkZHJlc3MgPSB0YmwuQWRkcmVzcy5BZGRSb3cocm93RnJvbSwgcm93cyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBJbnNlcnRzIGEgbmV3IGNvbHVtbiBpbnRvIHRoZSBzcHJlYWRzaGVldC4gIEV4aXN0aW5nIGNvbHVtbnMgYmVsb3cgdGhlIHBvc2l0aW9uIGFyZSAKICAgICAgICAvLy8gc2hpZnRlZCBkb3duLiAgQWxsIGZvcm11bGEgYXJlIHVwZGF0ZWQgdG8gdGFrZSBhY2NvdW50IG9mIHRoZSBuZXcgY29sdW1uLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW5Gcm9tIj5UaGUgcG9zaXRpb24gb2YgdGhlIG5ldyBjb2x1bW48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1ucyI+TnVtYmVyIG9mIGNvbHVtbnMgdG8gaW5zZXJ0PC9wYXJhbT4gICAgICAgIAogICAgICAgIHB1YmxpYyB2b2lkIEluc2VydENvbHVtbihpbnQgY29sdW1uRnJvbSwgaW50IGNvbHVtbnMpCiAgICAgICAgewogICAgICAgICAgICBJbnNlcnRDb2x1bW4oY29sdW1uRnJvbSwgY29sdW1ucywgMCk7CiAgICAgICAgfQogICAgICAgIC8vLzxzdW1tYXJ5PgogICAgICAgIC8vLyBJbnNlcnRzIGEgbmV3IGNvbHVtbiBpbnRvIHRoZSBzcHJlYWRzaGVldC4gIEV4aXN0aW5nIGNvbHVtbiB0byB0aGUgbGVmdCBhcmUgCiAgICAgICAgLy8vIHNoaWZ0ZWQuICBBbGwgZm9ybXVsYSBhcmUgdXBkYXRlZCB0byB0YWtlIGFjY291bnQgb2YgdGhlIG5ldyBjb2x1bW4uCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvbHVtbkZyb20iPlRoZSBwb3NpdGlvbiBvZiB0aGUgbmV3IGNvbHVtbjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW5zIj5OdW1iZXIgb2YgY29sdW1ucyB0byBpbnNlcnQuPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvcHlTdHlsZXNGcm9tQ29sdW1uIj5Db3B5IFN0eWxlcyBmcm9tIHRoaXMgY29sdW1uLiBBcHBsaWVkIHRvIGFsbCBpbnNlcnRlZCBjb2x1bW5zPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBJbnNlcnRDb2x1bW4oaW50IGNvbHVtbkZyb20sIGludCBjb2x1bW5zLCBpbnQgY29weVN0eWxlc0Zyb21Db2x1bW4pCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICB2YXIgZCA9IERpbWVuc2lvbjsKCiAgICAgICAgICAgIGlmIChjb2x1bW5Gcm9tIDwgMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24oImNvbHVtbkZyb20gY2FuJ3QgYmUgbGVzc2VyIHRoYXQgMSIpKTsKICAgICAgICAgICAgfSAgICAgICAgICAgIAogICAgICAgICAgICAvL0NoZWNrIHRoYXQgY2VsbHMgYXJlbid0IHNoaWZ0ZWQgb3V0c2lkZSB0aGUgYm91bmRyaWVzCiAgICAgICAgICAgIGlmIChkICE9IG51bGwgJiYgZC5FbmQuQ29sdW1uID4gY29sdW1uRnJvbSAmJiBkLkVuZC5Db2x1bW4gKyBjb2x1bW5zID4gRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IChuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCJDYW4ndCBpbnNlcnQuIENvbHVtbnMgd2lsbCBiZSBzaGlmdGVkIG91dHNpZGUgdGhlIGJvdW5kcmllcyBvZiB0aGUgd29ya3NoZWV0LiIpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbG9jayAodGhpcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3ZhbHVlcy5JbnNlcnQoMCwgY29sdW1uRnJvbSwgMCwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICBfZm9ybXVsYXMuSW5zZXJ0KDAsIGNvbHVtbkZyb20sIDAsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX3N0eWxlcy5JbnNlcnQoMCwgY29sdW1uRnJvbSwgMCwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICBfdHlwZXMuSW5zZXJ0KDAsIGNvbHVtbkZyb20sIDAsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2NvbW1lbnRzU3RvcmUuSW5zZXJ0KDAsIGNvbHVtbkZyb20sIDAsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2h5cGVyTGlua3MuSW5zZXJ0KDAsIGNvbHVtbkZyb20sIDAsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2ZsYWdzLkluc2VydCgwLCBjb2x1bW5Gcm9tLCAwLCBjb2x1bW5zKTsKCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgZiBpbiBfc2hhcmVkRm9ybXVsYXMuVmFsdWVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChmLlN0YXJ0Q29sID49IGNvbHVtbkZyb20pIGYuU3RhcnRDb2wgKz0gY29sdW1uczsKICAgICAgICAgICAgICAgICAgICB2YXIgYSA9IG5ldyBFeGNlbEFkZHJlc3NCYXNlKGYuQWRkcmVzcyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGEuX2Zyb21Db2wgPj0gY29sdW1uRnJvbSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGEuX2Zyb21Db2wgKz0gY29sdW1uczsKICAgICAgICAgICAgICAgICAgICAgICAgYS5fdG9Db2wgKz0gY29sdW1uczsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYS5fdG9Db2wgPj0gY29sdW1uRnJvbSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGEuX3RvQ29sICs9IGNvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGYuQWRkcmVzcyA9IEV4Y2VsQWRkcmVzc0Jhc2UuR2V0QWRkcmVzcyhhLl9mcm9tUm93LCBhLl9mcm9tQ29sLCBhLl90b1JvdywgYS5fdG9Db2wpOwogICAgICAgICAgICAgICAgICAgIGYuRm9ybXVsYSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoZi5Gb3JtdWxhLCAwLCBjb2x1bW5zLCAwLCBjb2x1bW5Gcm9tKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX2Zvcm11bGFzKTsKICAgICAgICAgICAgICAgIHdoaWxlIChjc2UuTmV4dCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjc2UuVmFsdWUgaXMgc3RyaW5nKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3NlLlZhbHVlID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhjc2UuVmFsdWUuVG9TdHJpbmcoKSwgMCwgY29sdW1ucywgMCwgY29sdW1uRnJvbSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEZpeE1lcmdlZENlbGxzQ29sdW1uKGNvbHVtbkZyb20sIGNvbHVtbnMsIGZhbHNlKTsKCiAgICAgICAgICAgICAgICB2YXIgY3NlYyA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF92YWx1ZXMsIDAsIDEsIDAsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgICAgIHZhciBsc3QgPSBuZXcgTGlzdDxFeGNlbENvbHVtbj4oKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBjb2wgaW4gY3NlYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY29sIGlzIEV4Y2VsQ29sdW1uKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbHN0LkFkZCgoRXhjZWxDb2x1bW4pY29sKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGxzdC5Db3VudC0xOyBpID49IDA7IGktLSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IGxzdFtpXTsKICAgICAgICAgICAgICAgICAgICBpZiAoYy5fY29sdW1uTWluID49IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYy5fY29sdW1uTWluICsgY29sdW1ucyA8PSBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5fY29sdW1uTWluICs9IGNvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLl9jb2x1bW5NaW4gPSBFeGNlbFBhY2thZ2UuTWF4Q29sdW1uczsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMuX2NvbHVtbk1heCArIGNvbHVtbnMgPD0gRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuX2NvbHVtbk1heCArPSBjb2x1bW5zOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5fY29sdW1uTWF4ID0gRXhjZWxQYWNrYWdlLk1heENvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYy5fY29sdW1uTWF4ID49IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2MgPSBjLl9jb2x1bW5NYXggLSBjb2x1bW5Gcm9tOwogICAgICAgICAgICAgICAgICAgICAgICBjLl9jb2x1bW5NYXggPSBjb2x1bW5Gcm9tIC0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgQ29weUNvbHVtbihjLCBjb2x1bW5Gcm9tICsgY29sdW1ucywgY29sdW1uRnJvbSArIGNvbHVtbnMgKyBjYyk7CiAgICAgICAgICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB9CgoKICAgICAgICAgICAgICAgIGlmIChjb3B5U3R5bGVzRnJvbUNvbHVtbiA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgYyA9IDA7IGMgPCBjb2x1bW5zOyBjKyspCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29sID0gdGhpcy5Db2x1bW4oY29sdW1uRnJvbSArIGMpOwogICAgICAgICAgICAgICAgICAgICAgICBjb2wuU3R5bGVJRCA9IHRoaXMuQ29sdW1uKGNvcHlTdHlsZXNGcm9tQ29sdW1uKS5TdHlsZUlEOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vQWRqdXN0IHRhYmxlcwogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRibCBpbiBUYWJsZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbHVtbkZyb20gPiB0YmwuQWRkcmVzcy5TdGFydC5Db2x1bW4gJiYgY29sdW1uRnJvbSA8PSB0YmwuQWRkcmVzcy5FbmQuQ29sdW1uKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgSW5zZXJ0VGFibGVDb2x1bW5zKGNvbHVtbkZyb20sIGNvbHVtbnMsIHRibCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB0YmwuQWRkcmVzcz10YmwuQWRkcmVzcy5BZGRDb2x1bW4oY29sdW1uRnJvbSwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgc3RhdGljIHZvaWQgSW5zZXJ0VGFibGVDb2x1bW5zKGludCBjb2x1bW5Gcm9tLCBpbnQgY29sdW1ucywgRXhjZWxUYWJsZSB0YmwpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbm9kZSA9IHRibC5Db2x1bW5zWzBdLlRvcE5vZGUuUGFyZW50Tm9kZTsKICAgICAgICAgICAgdmFyIGl4ID0gY29sdW1uRnJvbSAtIHRibC5BZGRyZXNzLlN0YXJ0LkNvbHVtbiAtIDE7CiAgICAgICAgICAgIHZhciBpbnNQb3MgPSBub2RlLkNoaWxkTm9kZXNbaXhdOwogICAgICAgICAgICBpeCArPSAyOwogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbHVtbnM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIG5hbWUgPQogICAgICAgICAgICAgICAgICAgIHRibC5Db2x1bW5zLkdldFVuaXF1ZU5hbWUoc3RyaW5nLkZvcm1hdCgiQ29sdW1uezB9IiwKICAgICAgICAgICAgICAgICAgICAgICAgKGl4KyspLlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpKSk7CiAgICAgICAgICAgICAgICBYbWxFbGVtZW50IHRhYmxlQ29sdW1uID0KICAgICAgICAgICAgICAgICAgICAoWG1sRWxlbWVudCkgdGJsLlRhYmxlWG1sLkNyZWF0ZU5vZGUoWG1sTm9kZVR5cGUuRWxlbWVudCwgInRhYmxlQ29sdW1uIiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwogICAgICAgICAgICAgICAgdGFibGVDb2x1bW4uU2V0QXR0cmlidXRlKCJpZCIsICh0YmwuQ29sdW1ucy5Db3VudCArIGkgKyAxKS5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSk7CiAgICAgICAgICAgICAgICB0YWJsZUNvbHVtbi5TZXRBdHRyaWJ1dGUoIm5hbWUiLCBuYW1lKTsKICAgICAgICAgICAgICAgIGluc1BvcyA9IG5vZGUuSW5zZXJ0QWZ0ZXIodGFibGVDb2x1bW4sIGluc1Bvcyk7CiAgICAgICAgICAgIH0gLy9DcmVhdGUgdGJsIENvbHVtbgogICAgICAgICAgICB0YmwuX2NvbHMgPSBuZXcgRXhjZWxUYWJsZUNvbHVtbkNvbGxlY3Rpb24odGJsKTsKICAgICAgICB9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQWRkcyBhIHZhbHVlIHRvIHRoZSByb3cgb2YgbWVyZ2VkIGNlbGxzIHRvIGZpeCBmb3IgaW5zZXJ0cyBvciBkZWxldGVzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvdyI+PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd3MiPjwvcGFyYW0+IAogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVsZXRlIj48L3BhcmFtPgogICAgICAgIHByaXZhdGUgdm9pZCBGaXhNZXJnZWRDZWxsc1JvdyhpbnQgcm93LCBpbnQgcm93cywgYm9vbCBkZWxldGUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoZGVsZXRlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuX2NlbGxzLkRlbGV0ZShyb3csIDAsIHJvd3MsIDApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLl9jZWxscy5JbnNlcnQocm93LCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgTGlzdDxpbnQ+IHJlbW92ZUluZGV4ID0gbmV3IExpc3Q8aW50PigpOwogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9tZXJnZWRDZWxscy5Db3VudDsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KCBfbWVyZ2VkQ2VsbHNbaV0pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEV4Y2VsQWRkcmVzc0Jhc2UgYWRkciA9IG5ldyBFeGNlbEFkZHJlc3NCYXNlKF9tZXJnZWRDZWxsc1tpXSksIG5ld0FkZHI7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGV0ZSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0FkZHIgPSBhZGRyLkRlbGV0ZVJvdyhyb3csIHJvd3MpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3QWRkciA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVJbmRleC5BZGQoaSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdBZGRyID0gYWRkci5BZGRSb3cocm93LCByb3dzKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0FkZHIuQWRkcmVzcyAhPSBhZGRyLkFkZHJlc3MpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgX21lcmdlZENlbGxzLl9jZWxscy5JbnNlcnQocm93LCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9tZXJnZWRDZWxscy5TZXRJbmRleChuZXdBZGRyLCBpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0FkZHIuQWRkcmVzcyAhPSBhZGRyLkFkZHJlc3MpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuTGlzdFtpXSA9IG5ld0FkZHIuX2FkZHJlc3M7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoaW50IGkgPSByZW1vdmVJbmRleC5Db3VudCAtIDE7IGkgPj0gMDsgaS0tKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuTGlzdC5SZW1vdmVBdChyZW1vdmVJbmRleFtpXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBBZGRzIGEgdmFsdWUgdG8gdGhlIHJvdyBvZiBtZXJnZWQgY2VsbHMgdG8gZml4IGZvciBpbnNlcnRzIG9yIGRlbGV0ZXMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1uIj48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1ucyI+PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlbGV0ZSI+PC9wYXJhbT4KICAgICAgICBwcml2YXRlIHZvaWQgRml4TWVyZ2VkQ2VsbHNDb2x1bW4oaW50IGNvbHVtbiwgaW50IGNvbHVtbnMsIGJvb2wgZGVsZXRlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGRlbGV0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLl9jZWxscy5EZWxldGUoMCwgY29sdW1uLCAwLCBjb2x1bW5zKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF9tZXJnZWRDZWxscy5fY2VsbHMuSW5zZXJ0KDAsIGNvbHVtbiwgMCwgY29sdW1ucyk7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgICAgIExpc3Q8aW50PiByZW1vdmVJbmRleCA9IG5ldyBMaXN0PGludD4oKTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBfbWVyZ2VkQ2VsbHMuQ291bnQ7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShfbWVyZ2VkQ2VsbHNbaV0pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEV4Y2VsQWRkcmVzc0Jhc2UgYWRkciA9IG5ldyBFeGNlbEFkZHJlc3NCYXNlKF9tZXJnZWRDZWxsc1tpXSksIG5ld0FkZHI7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGV0ZSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0FkZHIgPSBhZGRyLkRlbGV0ZUNvbHVtbihjb2x1bW4sIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3QWRkciA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVJbmRleC5BZGQoaSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdBZGRyID0gYWRkci5BZGRDb2x1bW4oY29sdW1uLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0FkZHIuQWRkcmVzcyAhPSBhZGRyLkFkZHJlc3MpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9tZXJnZWRDZWxscy5TZXRJbmRleChuZXdBZGRyLCBpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0FkZHIuQWRkcmVzcyAhPSBhZGRyLkFkZHJlc3MpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuTGlzdFtpXSA9IG5ld0FkZHIuX2FkZHJlc3M7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoaW50IGkgPSByZW1vdmVJbmRleC5Db3VudCAtIDE7IGkgPj0gMDsgaS0tKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuTGlzdC5SZW1vdmVBdChyZW1vdmVJbmRleFtpXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIEZpeFNoYXJlZEZvcm11bGFzUm93cyhpbnQgcG9zaXRpb24sIGludCByb3dzKQogICAgICAgIHsKICAgICAgICAgICAgTGlzdDxGb3JtdWxhcz4gYWRkZWQgPSBuZXcgTGlzdDxGb3JtdWxhcz4oKTsKICAgICAgICAgICAgTGlzdDxGb3JtdWxhcz4gZGVsZXRlZCA9IG5ldyBMaXN0PEZvcm11bGFzPigpOwoKICAgICAgICAgICAgZm9yZWFjaCAoaW50IGlkIGluIF9zaGFyZWRGb3JtdWxhcy5LZXlzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgZiA9IF9zaGFyZWRGb3JtdWxhc1tpZF07CiAgICAgICAgICAgICAgICBpbnQgZnJvbUNvbCwgZnJvbVJvdywgdG9Db2wsIHRvUm93OwoKICAgICAgICAgICAgICAgIEV4Y2VsQ2VsbEJhc2UuR2V0Um93Q29sRnJvbUFkZHJlc3MoZi5BZGRyZXNzLCBvdXQgZnJvbVJvdywgb3V0IGZyb21Db2wsIG91dCB0b1Jvdywgb3V0IHRvQ29sKTsKICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA+PSBmcm9tUm93ICYmIHBvc2l0aW9uKyhNYXRoLkFicyhyb3dzKSkgPD0gdG9Sb3cpIC8vSW5zZXJ0L2RlbGV0ZSBpcyB3aGl0aGluIHRoZSBzaGFyZSBmb3JtdWxhIGFkZHJlc3MKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocm93cyA+IDApIC8vSW5zZXJ0CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoZnJvbVJvdywgZnJvbUNvbCkgKyAiOiIgKyBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MocG9zaXRpb24gLSAxLCB0b0NvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0b1JvdyAhPSBmcm9tUm93KQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGb3JtdWxhcyBuZXdGID0gbmV3IEZvcm11bGFzKFNvdXJjZUNvZGVUb2tlbml6ZXIuRGVmYXVsdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGLlN0YXJ0Q29sID0gZi5TdGFydENvbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0YuU3RhcnRSb3cgPSBwb3NpdGlvbiArIHJvd3M7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MocG9zaXRpb24gKyByb3dzLCBmcm9tQ29sKSArICI6IiArIEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyh0b1JvdyArIHJvd3MsIHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0YuRm9ybXVsYSA9IEV4Y2VsQ2VsbEJhc2UuVHJhbnNsYXRlRnJvbVIxQzEoRXhjZWxDZWxsQmFzZS5UcmFuc2xhdGVUb1IxQzEoZi5Gb3JtdWxhLCBmLlN0YXJ0Um93LCBmLlN0YXJ0Q29sKSwgcG9zaXRpb24sIGYuU3RhcnRDb2wpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkZWQuQWRkKG5ld0YpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmcm9tUm93IC0gcm93cyA8IHRvUm93KQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoZnJvbVJvdywgZnJvbUNvbCwgdG9Sb3crcm93cywgdG9Db2wpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZi5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZyb21Sb3csIGZyb21Db2wpICsgIjoiICsgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKHRvUm93ICsgcm93cywgdG9Db2wpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAocG9zaXRpb24gPD0gdG9Sb3cpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJvd3MgPiAwKSAvL0luc2VydCBiZWZvcmUgc2hpZnQgZG93bgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZi5TdGFydFJvdyArPSByb3dzOwogICAgICAgICAgICAgICAgICAgICAgICAvL2YuRm9ybXVsYSA9IEV4Y2VsQ2VsbC5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhmLkZvcm11bGEsIHJvd3MsIDAsIHBvc2l0aW9uLCAwKTsgLy9SZWNhbGMgdGhlIGNlbGxzIHBvc2l0aW9ucwogICAgICAgICAgICAgICAgICAgICAgICBmLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoZnJvbVJvdyArIHJvd3MsIGZyb21Db2wpICsgIjoiICsgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKHRvUm93ICsgcm93cywgdG9Db2wpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvL0NlbGxzW2YuQWRkcmVzc10uU2V0U2hhcmVkRm9ybXVsYUlEKGludC5NaW5WYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA8PSBmcm9tUm93ICYmIHBvc2l0aW9uICsgTWF0aC5BYnMocm93cykgPiB0b1JvdykgIC8vRGVsZXRlIHRoZSBmb3JtdWxhIAogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGVkLkFkZChmKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvUm93ID0gdG9Sb3cgKyByb3dzIDwgcG9zaXRpb24gLSAxID8gcG9zaXRpb24gLSAxIDogdG9Sb3cgKyByb3dzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uIDw9IGZyb21Sb3cpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbVJvdyA9IGZyb21Sb3cgKyByb3dzIDwgcG9zaXRpb24gPyBwb3NpdGlvbiA6IGZyb21Sb3cgKyByb3dzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYuQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhmcm9tUm93LCBmcm9tQ29sLCB0b1JvdywgdG9Db2wpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2VsbHNbZi5BZGRyZXNzXS5TZXRTaGFyZWRGb3JtdWxhSUQoZi5JbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2YuU3RhcnRSb3cgPSBmcm9tUm93OwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZi5Gb3JtdWxhID0gRXhjZWxDZWxsLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKGYuRm9ybXVsYSwgcm93cywgMCwgcG9zaXRpb24sIDApOwogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBBZGRGb3JtdWxhcyhhZGRlZCwgcG9zaXRpb24sIHJvd3MpOwoKICAgICAgICAgICAgLy9SZW1vdmUgZm9ybXVsYXMKICAgICAgICAgICAgZm9yZWFjaCAoRm9ybXVsYXMgZiBpbiBkZWxldGVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfc2hhcmVkRm9ybXVsYXMuUmVtb3ZlKGYuSW5kZXgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvL0ZpeCBGb3JtdWxhcwogICAgICAgICAgICBhZGRlZCA9IG5ldyBMaXN0PEZvcm11bGFzPigpOwogICAgICAgICAgICBmb3JlYWNoIChpbnQgaWQgaW4gX3NoYXJlZEZvcm11bGFzLktleXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBmID0gX3NoYXJlZEZvcm11bGFzW2lkXTsKICAgICAgICAgICAgICAgIFVwZGF0ZVNoYXJlZEZvcm11bGFSb3cocmVmIGYsIHBvc2l0aW9uLCByb3dzLCByZWYgYWRkZWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEFkZEZvcm11bGFzKGFkZGVkLCBwb3NpdGlvbiwgcm93cyk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgQWRkRm9ybXVsYXMoTGlzdDxGb3JtdWxhcz4gYWRkZWQsIGludCBwb3NpdGlvbiwgaW50IHJvd3MpCiAgICAgICAgewogICAgICAgICAgICAvL0FkZCBuZXcgZm9ybXVsYXMKICAgICAgICAgICAgZm9yZWFjaCAoRm9ybXVsYXMgZiBpbiBhZGRlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZi5JbmRleCA9IEdldE1heFNoYXJlRnVuY3Rpb25JbmRleChmYWxzZSk7CiAgICAgICAgICAgICAgICBfc2hhcmVkRm9ybXVsYXMuQWRkKGYuSW5kZXgsIGYpOwogICAgICAgICAgICAgICAgQ2VsbHNbZi5BZGRyZXNzXS5TZXRTaGFyZWRGb3JtdWxhSUQoZi5JbmRleCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBVcGRhdGVTaGFyZWRGb3JtdWxhUm93KHJlZiBGb3JtdWxhcyBmb3JtdWxhLCBpbnQgc3RhcnRSb3csIGludCByb3dzLCByZWYgTGlzdDxGb3JtdWxhcz4gbmV3Rm9ybXVsYXMpCiAgICAgICAgewogICAgICAgICAgICBpbnQgZnJvbVJvdyxmcm9tQ29sLCB0b1JvdywgdG9Db2w7CiAgICAgICAgICAgIGludCBuZXdGb3JtdWxhc0NvdW50ID0gbmV3Rm9ybXVsYXMuQ291bnQ7CiAgICAgICAgICAgIEV4Y2VsQ2VsbEJhc2UuR2V0Um93Q29sRnJvbUFkZHJlc3MoZm9ybXVsYS5BZGRyZXNzLCBvdXQgZnJvbVJvdywgb3V0IGZyb21Db2wsIG91dCB0b1Jvdywgb3V0IHRvQ29sKTsKICAgICAgICAgICAgLy9pbnQgcmVmU3BsaXRzID0gUmVnZXguU3BsaXQoZm9ybXVsYS5Gb3JtdWxhLCAiI1JFRiEiKS5HZXRVcHBlckJvdW5kKDApOwogICAgICAgICAgICBzdHJpbmcgZm9ybXVhbFIxQzE7CiAgICAgICAgICAgIGlmIChyb3dzID4gMCB8fCBmcm9tUm93IDw9IHN0YXJ0Um93KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3JtdWFsUjFDMSA9IEV4Y2VsUmFuZ2VCYXNlLlRyYW5zbGF0ZVRvUjFDMShmb3JtdWxhLkZvcm11bGEsIGZvcm11bGEuU3RhcnRSb3csIGZvcm11bGEuU3RhcnRDb2wpOwogICAgICAgICAgICAgICAgZm9ybXVsYS5Gb3JtdWxhID0gRXhjZWxSYW5nZUJhc2UuVHJhbnNsYXRlRnJvbVIxQzEoZm9ybXVhbFIxQzEsIGZyb21Sb3csIGZvcm11bGEuU3RhcnRDb2wpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9ybXVhbFIxQzEgPSBFeGNlbFJhbmdlQmFzZS5UcmFuc2xhdGVUb1IxQzEoZm9ybXVsYS5Gb3JtdWxhLCBmb3JtdWxhLlN0YXJ0Um93LXJvd3MsIGZvcm11bGEuU3RhcnRDb2wpOwogICAgICAgICAgICAgICAgZm9ybXVsYS5Gb3JtdWxhID0gRXhjZWxSYW5nZUJhc2UuVHJhbnNsYXRlRnJvbVIxQzEoZm9ybXVhbFIxQzEsIGZvcm11bGEuU3RhcnRSb3csIGZvcm11bGEuU3RhcnRDb2wpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vYm9vbCBpc1JlZiA9IGZhbHNlOwogICAgICAgICAgICAvL0Zvcm11bGFzIHJlc3RGb3JtdWxhPWZvcm11bGE7CiAgICAgICAgICAgIHN0cmluZyBwcmV2Rm9ybXVhbFIxQzEgPSBmb3JtdWFsUjFDMTsKICAgICAgICAgICAgZm9yIChpbnQgcm93ID0gZnJvbVJvdzsgcm93IDw9IHRvUm93OyByb3crKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChpbnQgY29sID0gZnJvbUNvbDsgY29sIDw9IHRvQ29sOyBjb2wrKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdHJpbmcgbmV3Rm9ybXVsYTsKICAgICAgICAgICAgICAgICAgICBzdHJpbmcgY3VycmVudEZvcm11bGFSMUMxOwogICAgICAgICAgICAgICAgICAgIGlmIChyb3dzID4gMCB8fCByb3cgPCBzdGFydFJvdykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0Zvcm11bGEgPSBFeGNlbENlbGxCYXNlLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKEV4Y2VsQ2VsbEJhc2UuVHJhbnNsYXRlRnJvbVIxQzEoZm9ybXVhbFIxQzEsIHJvdywgY29sKSwgcm93cywgMCwgc3RhcnRSb3csIDApOwogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Rm9ybXVsYVIxQzEgPSBFeGNlbFJhbmdlQmFzZS5UcmFuc2xhdGVUb1IxQzEobmV3Rm9ybXVsYSwgcm93LCBjb2wpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdGb3JtdWxhID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhFeGNlbENlbGxCYXNlLlRyYW5zbGF0ZUZyb21SMUMxKGZvcm11YWxSMUMxLCByb3ctcm93cywgY29sKSwgcm93cywgMCwgc3RhcnRSb3csIDApOwogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Rm9ybXVsYVIxQzEgPSBFeGNlbFJhbmdlQmFzZS5UcmFuc2xhdGVUb1IxQzEobmV3Rm9ybXVsYSwgcm93LCBjb2wpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudEZvcm11bGFSMUMxICE9IHByZXZGb3JtdWFsUjFDMSkgLy9uZXdGb3JtdWxhLkNvbnRhaW5zKCIjUkVGISIpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiAocmVmU3BsaXRzID09IDAgfHwgUmVnZXguU3BsaXQobmV3Rm9ybXVsYSwgIiNSRUYhIikuR2V0VXBwZXJCb3VuZCgwKSAhPSByZWZTcGxpdHMpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgICAgICAgICAvL2lzUmVmID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJvdyA9PSBmcm9tUm93ICYmIGNvbCA9PSBmcm9tQ29sKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtdWxhLkZvcm11bGEgPSBuZXdGb3JtdWxhOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0Zvcm11bGFzLkNvdW50ID09IG5ld0Zvcm11bGFzQ291bnQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybXVsYS5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZvcm11bGEuU3RhcnRSb3csIGZvcm11bGEuU3RhcnRDb2wsIHJvdyAtIDEsIGNvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Rm9ybXVsYXNbbmV3Rm9ybXVsYXMuQ291bnQgLSAxXS5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKG5ld0Zvcm11bGFzW25ld0Zvcm11bGFzLkNvdW50IC0gMV0uU3RhcnRSb3csIG5ld0Zvcm11bGFzW25ld0Zvcm11bGFzLkNvdW50IC0gMV0uU3RhcnRDb2wsIHJvdyAtIDEsIGNvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVmRm9ybXVsYSA9IG5ldyBGb3JtdWxhcyhTb3VyY2VDb2RlVG9rZW5pemVyLkRlZmF1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmRm9ybXVsYS5Gb3JtdWxhID0gbmV3Rm9ybXVsYTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZkZvcm11bGEuU3RhcnRSb3cgPSByb3c7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZGb3JtdWxhLlN0YXJ0Q29sID0gY29sOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Rm9ybXVsYXMuQWRkKHJlZkZvcm11bGEpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVzdEZvcm11bGEgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldkZvcm11YWxSMUMxID0gY3VycmVudEZvcm11bGFSMUMxOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgLy8gICAgewogICAgICAgICAgICAgICAgICAgIC8vICAgICAgICBpc1JlZiA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIC8vICAgIH0KICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgICAgICAvL2Vsc2UKICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAvLyAgICBpc1JlZiA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIC8vfQogICAgICAgICAgICAgICAgICAgIC8vaWYgKHJlc3RGb3JtdWxhPT1udWxsKQogICAgICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgICAgICAgICAvL2lmIChuZXdGb3JtdWxhcy5Db3VudCA9PSBuZXdGb3JtdWxhc0NvdW50KQogICAgICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgZm9ybXVsYS5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZvcm11bGEuU3RhcnRSb3csIGZvcm11bGEuU3RhcnRDb2wsIHJvdyAtIDEsIGNvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vfQogICAgICAgICAgICAgICAgICAgICAgICAvL2Vsc2UKICAgICAgICAgICAgICAgICAgICAgICAgLy97Ci8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0Zvcm11bGFzW25ld0Zvcm11bGFzLkNvdW50IC0gMV0uQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLlN0YXJ0Um93LCBuZXdGb3JtdWxhc1swXS5TdGFydENvbCwgcm93IC0gMSwgY29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy99CgogICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc3RGb3JtdWxhID0gbmV3IEZvcm11bGFzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVzdEZvcm11bGEuRm9ybXVsYSA9IG5ld0Zvcm11bGE7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVzdEZvcm11bGEuU3RhcnRSb3cgPSByb3c7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVzdEZvcm11bGEuU3RhcnRDb2wgPSBjb2w7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vbmV3Rm9ybXVsYXMuQWRkKHJlc3RGb3JtdWxhKTsKICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocm93cyA8IDAgJiYgZm9ybXVsYS5TdGFydFJvdyA+IHN0YXJ0Um93KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZm9ybXVsYS5TdGFydFJvdyArIHJvd3MgPCBzdGFydFJvdykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3JtdWxhLlN0YXJ0Um93ID0gc3RhcnRSb3c7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9ybXVsYS5TdGFydFJvdyArPSByb3dzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChuZXdGb3JtdWxhcy5Db3VudCA+IG5ld0Zvcm11bGFzQ291bnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG5ld0Zvcm11bGFzW25ld0Zvcm11bGFzLkNvdW50IC0gMV0uQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLlN0YXJ0Um93LCBuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLlN0YXJ0Q29sLCB0b1JvdywgdG9Db2wpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICNlbmRyZWdpb24KCiAgICAgICAgI3JlZ2lvbiBEZWxldGVSb3cKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIERlbGV0ZSB0aGUgc3BlY2lmaWVkIHJvdyBmcm9tIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvdyI+QSByb3cgdG8gYmUgZGVsZXRlZDwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgRGVsZXRlUm93KGludCByb3cpCiAgICAgICAgewogICAgICAgICAgICBEZWxldGVSb3cocm93LCAxKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBEZWxldGUgdGhlIHNwZWNpZmllZCByb3cgZnJvbSB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dGcm9tIj5UaGUgc3RhcnQgcm93PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd3MiPk51bWJlciBvZiByb3dzIHRvIGRlbGV0ZTwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgRGVsZXRlUm93KGludCByb3dGcm9tLCBpbnQgcm93cykKICAgICAgICB7CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIGlmIChyb3dGcm9tIDwgMSB8fCByb3dGcm9tICsgcm93cyA+IEV4Y2VsUGFja2FnZS5NYXhSb3dzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyhuZXcgQXJndW1lbnRFeGNlcHRpb24oIlJvdyBvdXQgb2YgcmFuZ2UuIFNwYW5zIGZyb20gMSB0byAiICsgRXhjZWxQYWNrYWdlLk1heFJvd3MuVG9TdHJpbmcoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsb2NrICh0aGlzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdmFsdWVzLkRlbGV0ZShyb3dGcm9tLCAwLCByb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgICAgICBfdHlwZXMuRGVsZXRlKHJvd0Zyb20sIDAsIHJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9mb3JtdWxhcy5EZWxldGUocm93RnJvbSwgMCwgcm93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAgICAgX3N0eWxlcy5EZWxldGUocm93RnJvbSwgMCwgcm93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAgICAgX2ZsYWdzLkRlbGV0ZShyb3dGcm9tLCAwLCByb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgICAgICBfY29tbWVudHNTdG9yZS5EZWxldGUocm93RnJvbSwgMCwgcm93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAgICAgX2h5cGVyTGlua3MuRGVsZXRlKHJvd0Zyb20sIDAsIHJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKCiAgICAgICAgICAgICAgICBBZGp1c3RGb3JtdWxhc1Jvdyhyb3dGcm9tLCByb3dzKTsKICAgICAgICAgICAgICAgIEZpeE1lcmdlZENlbGxzUm93KHJvd0Zyb20sIHJvd3MsIHRydWUpOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0YmwgaW4gVGFibGVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRibC5BZGRyZXNzID0gdGJsLkFkZHJlc3MuRGVsZXRlUm93KHJvd0Zyb20sIHJvd3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRGVsZXRlIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZyb20gdGhlIHdvcmtzaGVldC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1uIj5UaGUgY29sdW1uIHRvIGJlIGRlbGV0ZWQ8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIERlbGV0ZUNvbHVtbihpbnQgY29sdW1uKQogICAgICAgIHsKICAgICAgICAgICAgRGVsZXRlQ29sdW1uKGNvbHVtbiwxKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBEZWxldGUgdGhlIHNwZWNpZmllZCBjb2x1bW4gZnJvbSB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW5Gcm9tIj5UaGUgc3RhcnQgY29sdW1uPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvbHVtbnMiPk51bWJlciBvZiBjb2x1bW5zIHRvIGRlbGV0ZTwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgRGVsZXRlQ29sdW1uKGludCBjb2x1bW5Gcm9tLCBpbnQgY29sdW1ucykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb2x1bW5Gcm9tIDwgMSB8fCBjb2x1bW5Gcm9tICsgY29sdW1ucyA+IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEFyZ3VtZW50RXhjZXB0aW9uKCJDb2x1bW4gb3V0IG9mIHJhbmdlLiBTcGFucyBmcm9tIDEgdG8gIiArIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zLlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbG9jayAodGhpcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGNvbCA9IF92YWx1ZXMuR2V0VmFsdWUoMCwgY29sdW1uRnJvbSkgYXMgRXhjZWxDb2x1bW47CiAgICAgICAgICAgICAgICBpZiAoY29sID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHIgPSAwOyAKICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IGNvbHVtbkZyb207CiAgICAgICAgICAgICAgICAgICAgaWYoX3ZhbHVlcy5QcmV2Q2VsbChyZWYgcixyZWYgYykpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb2wgPSBfdmFsdWVzLkdldFZhbHVlKDAsIGMpIGFzIEV4Y2VsQ29sdW1uOwogICAgICAgICAgICAgICAgICAgICAgICBpZihjb2wuX2NvbHVtbk1heCA+PSBjb2x1bW5Gcm9tKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuQ29sdW1uTWF4PWNvbHVtbkZyb20tMTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBfdmFsdWVzLkRlbGV0ZSgwLCBjb2x1bW5Gcm9tLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgY29sdW1ucyk7CiAgICAgICAgICAgICAgICBfdHlwZXMuRGVsZXRlKDAsIGNvbHVtbkZyb20sIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9mb3JtdWxhcy5EZWxldGUoMCwgY29sdW1uRnJvbSwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX3N0eWxlcy5EZWxldGUoMCwgY29sdW1uRnJvbSwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2ZsYWdzLkRlbGV0ZSgwLCBjb2x1bW5Gcm9tLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgY29sdW1ucyk7CiAgICAgICAgICAgICAgICBfY29tbWVudHNTdG9yZS5EZWxldGUoMCwgY29sdW1uRnJvbSwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2h5cGVyTGlua3MuRGVsZXRlKDAsIGNvbHVtbkZyb20sIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBjb2x1bW5zKTsKCiAgICAgICAgICAgICAgICBBZGp1c3RGb3JtdWxhc0NvbHVtbihjb2x1bW5Gcm9tLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIEZpeE1lcmdlZENlbGxzQ29sdW1uKGNvbHVtbkZyb20sIGNvbHVtbnMsIHRydWUpOwoKICAgICAgICAgICAgICAgIHZhciBjc2VjID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX3ZhbHVlcywgMCwgY29sdW1uRnJvbSwgMCwgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGNvbHVtbiBpbiBjc2VjKSAgICAKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY29sdW1uIGlzIEV4Y2VsQ29sdW1uKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGMgPSAoRXhjZWxDb2x1bW4pY29sdW1uOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYy5fY29sdW1uTWluID49IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuX2NvbHVtbk1pbiAtPSBjb2x1bW5zOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5fY29sdW1uTWF4IC09IGNvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRibCBpbiBUYWJsZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbHVtbkZyb20gPj0gdGJsLkFkZHJlc3MuU3RhcnQuQ29sdW1uICYmIGNvbHVtbkZyb20gPD0gdGJsLkFkZHJlc3MuRW5kLkNvbHVtbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlID0gdGJsLkNvbHVtbnNbMF0uVG9wTm9kZS5QYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXggPSBjb2x1bW5Gcm9tIC0gdGJsLkFkZHJlc3MuU3RhcnQuQ29sdW1uOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbHVtbnM7IGkrKykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUuQ2hpbGROb2Rlcy5Db3VudCA+IGl4KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuUmVtb3ZlQ2hpbGQobm9kZS5DaGlsZE5vZGVzW2l4XSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gCiAgICAgICAgICAgICAgICAgICAgICAgIHRibC5fY29scyA9IG5ldyBFeGNlbFRhYmxlQ29sdW1uQ29sbGVjdGlvbih0YmwpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGJsLkFkZHJlc3MgPSB0YmwuQWRkcmVzcy5EZWxldGVDb2x1bW4oY29sdW1uRnJvbSwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBBZGp1c3RGb3JtdWxhc1JvdyhpbnQgcm93RnJvbSwgaW50IHJvd3MpCiAgICAgICAgewogICAgICAgICAgICB2YXIgZGVsU0YgPSBuZXcgTGlzdDxpbnQ+KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBzZiBpbiBfc2hhcmVkRm9ybXVsYXMuVmFsdWVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgYSA9IG5ldyBFeGNlbEFkZHJlc3Moc2YuQWRkcmVzcykuRGVsZXRlUm93KHJvd0Zyb20sIHJvd3MpOwogICAgICAgICAgICAgICAgaWYgKGE9PW51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGVsU0YuQWRkKHNmLkluZGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzZi5BZGRyZXNzID0gYS5BZGRyZXNzOwogICAgICAgICAgICAgICAgICAgIGlmIChzZi5TdGFydFJvdyA+IHJvd0Zyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgciA9IE1hdGguTWluKHNmLlN0YXJ0Um93IC0gcm93RnJvbSwgcm93cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNmLkZvcm11bGEgPSBFeGNlbENlbGxCYXNlLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKHNmLkZvcm11bGEsIC1yLCAwLCByb3dGcm9tLCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2YuU3RhcnRSb3cgLT0gcjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAodmFyIGl4IGluIGRlbFNGKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfc2hhcmVkRm9ybXVsYXMuUmVtb3ZlKGl4KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkZWxTRiA9IG51bGw7CiAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfZm9ybXVsYXMsIDEsIDEsIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgIHdoaWxlIChjc2UuTmV4dCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoY3NlLlZhbHVlIGlzIHN0cmluZykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjc2UuVmFsdWUgPSBFeGNlbENlbGxCYXNlLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKGNzZS5WYWx1ZS5Ub1N0cmluZygpLCAtcm93cywgMCwgcm93RnJvbSwgMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBBZGp1c3RGb3JtdWxhc0NvbHVtbihpbnQgY29sdW1uRnJvbSwgaW50IGNvbHVtbnMpCiAgICAgICAgewogICAgICAgICAgICB2YXIgZGVsU0YgPSBuZXcgTGlzdDxpbnQ+KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBzZiBpbiBfc2hhcmVkRm9ybXVsYXMuVmFsdWVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgYSA9IG5ldyBFeGNlbEFkZHJlc3Moc2YuQWRkcmVzcykuRGVsZXRlQ29sdW1uKGNvbHVtbkZyb20sIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgaWYgKGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkZWxTRi5BZGQoc2YuSW5kZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNmLkFkZHJlc3MgPSBhLkFkZHJlc3M7CiAgICAgICAgICAgICAgICAgICAgLy9zZi5Gb3JtdWxhID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhzZi5Gb3JtdWxhLCAwLCAtY29sdW1ucywgMCwgY29sdW1uRnJvbSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNmLlN0YXJ0Q29sID4gY29sdW1uRnJvbSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjID0gTWF0aC5NaW4oc2YuU3RhcnRDb2wgLSBjb2x1bW5Gcm9tLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2YuRm9ybXVsYSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoc2YuRm9ybXVsYSwgMCwgLWMsIDAsIDEpOwogICAgICAgICAgICAgICAgICAgICAgICBzZi5TdGFydENvbC09IGM7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvL3NmLkFkZHJlc3MgPSBhLkFkZHJlc3M7CiAgICAgICAgICAgICAgICAgICAgLy9zZi5Gb3JtdWxhID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhzZi5Gb3JtdWxhLCAwLC1jb2x1bW5zLDAsIGNvbHVtbkZyb20pOwogICAgICAgICAgICAgICAgICAgIC8vaWYgKHNmLlN0YXJ0Q29sID49IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAgICAgLy8gICAgc2YuU3RhcnRDb2wgLT0gc2YuU3RhcnRDb2w7CiAgICAgICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAodmFyIGl4IGluIGRlbFNGKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfc2hhcmVkRm9ybXVsYXMuUmVtb3ZlKGl4KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkZWxTRiA9IG51bGw7CiAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfZm9ybXVsYXMsIDEsIDEsICBFeGNlbFBhY2thZ2UuTWF4Um93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICB3aGlsZSAoY3NlLk5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGNzZS5WYWx1ZSBpcyBzdHJpbmcpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY3NlLlZhbHVlID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhjc2UuVmFsdWUuVG9TdHJpbmcoKSwgMCwgLWNvbHVtbnMsIDAsIGNvbHVtbkZyb20pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRGVsZXRlcyB0aGUgc3BlY2lmaWVkIHJvdyBmcm9tIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd0Zyb20iPlRoZSBudW1iZXIgb2YgdGhlIHN0YXJ0IHJvdyB0byBiZSBkZWxldGVkPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd3MiPk51bWJlciBvZiByb3dzIHRvIGRlbGV0ZTwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzaGlmdE90aGVyUm93c1VwIj5Ob3QgdXNlZC4gUm93cyBhcmUgYWx3YXlzIHNoaWZ0ZWQ8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIERlbGV0ZVJvdyhpbnQgcm93RnJvbSwgaW50IHJvd3MsIGJvb2wgc2hpZnRPdGhlclJvd3NVcCkKCQl7CiAgICAgICAgICAgIERlbGV0ZVJvdyhyb3dGcm9tLCByb3dzKTsKICAgICAgICB9CgkJI2VuZHJlZ2lvbgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0IHRoZSBjZWxsIHZhbHVlIGZyb20gdGh3IHdvcmtzaGVldAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJSb3ciPlRoZSByb3cgbnVtYmVyPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IkNvbHVtbiI+VGhlIHJvdyBudW1iZXI8L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdmFsdWU8L3JldHVybnM+CiAgICAgICAgcHVibGljIG9iamVjdCBHZXRWYWx1ZShpbnQgUm93LCBpbnQgQ29sdW1uKQogICAgICAgIHsKICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgLy91bG9uZyBjZWxsSUQgPSBFeGNlbENlbGxCYXNlLkdldENlbGxJRChTaGVldElELCBSb3csIENvbHVtbik7CiAgICAgICAgICAgIHZhciB2ID0gX3ZhbHVlcy5HZXRWYWx1ZShSb3csIENvbHVtbik7CiAgICAgICAgICAgIGlmICh2IT1udWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvL3ZhciBjZWxsID0gKChFeGNlbENlbGwpX2NlbGxzW2NlbGxJRF0pOwogICAgICAgICAgICAgICAgaWYgKF9mbGFncy5HZXRGbGFnVmFsdWUoUm93LCBDb2x1bW4sIENlbGxGbGFncy5SaWNoVGV4dCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChvYmplY3QpQ2VsbHNbUm93LCBDb2x1bW5dLlJpY2hUZXh0LlRleHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHY7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBHZXQgYSBzdHJvbmdseSB0eXBlZCBjZWxsIHZhbHVlIGZyb20gdGhlIHdvcmtzaGVldAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDx0eXBlcGFyYW0gbmFtZT0iVCI+VGhlIHR5cGU8L3R5cGVwYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlJvdyI+VGhlIHJvdyBudW1iZXI8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iQ29sdW1uIj5UaGUgcm93IG51bWJlcjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPlRoZSB2YWx1ZS4gSWYgdGhlIHZhbHVlIGNhbid0IGJlIGNvbnZlcnRlZCB0byB0aGUgc3BlY2lmaWVkIHR5cGUsIHRoZSBkZWZhdWx0IHZhbHVlIHdpbGwgYmUgcmV0dXJuZWQ8L3JldHVybnM+CiAgICAgICAgcHVibGljIFQgR2V0VmFsdWU8VD4oaW50IFJvdywgaW50IENvbHVtbikKICAgICAgICB7CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIC8vdWxvbmcgY2VsbElEPUV4Y2VsQ2VsbEJhc2UuR2V0Q2VsbElEKFNoZWV0SUQsIFJvdywgQ29sdW1uKTsKICAgICAgICAgICAgdmFyIHYgPSBfdmFsdWVzLkdldFZhbHVlKFJvdywgQ29sdW1uKTsgICAgICAgICAgIAogICAgICAgICAgICBpZiAodj09bnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vdmFyIGNlbGw9KChFeGNlbENlbGwpX2NlbGxzW2NlbGxJRF0pOwogICAgICAgICAgICBpZiAoX2ZsYWdzLkdldEZsYWdWYWx1ZShSb3csIENvbHVtbiwgQ2VsbEZsYWdzLlJpY2hUZXh0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIChUKShvYmplY3QpQ2VsbHNbUm93LCBDb2x1bW5dLlJpY2hUZXh0LlRleHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gR2V0VHlwZWRWYWx1ZTxUPih2KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvL1RoYW5rcyB0byBNaWNoYWVsIFRyYW4gZm9yIHBhcnRzIG9mIHRoaXMgbWV0aG9kCiAgICAgICAgaW50ZXJuYWwgVCBHZXRUeXBlZFZhbHVlPFQ+KG9iamVjdCB2KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHYgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgVHlwZSBmcm9tVHlwZSA9IHYuR2V0VHlwZSgpOwogICAgICAgICAgICBUeXBlIHRvVHlwZSA9IHR5cGVvZihUKTsKICAgICAgICAgICAgaWYgKGZyb21UeXBlID09IHRvVHlwZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIChUKXY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGNudiA9IFR5cGVEZXNjcmlwdG9yLkdldENvbnZlcnRlcihmcm9tVHlwZSk7CiAgICAgICAgICAgIGlmICh0b1R5cGUgPT0gdHlwZW9mKERhdGVUaW1lKSkgICAgLy9IYW5kbGUgZGF0ZXMKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGZyb21UeXBlID09IHR5cGVvZihUaW1lU3BhbikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgoVCkob2JqZWN0KShuZXcgRGF0ZVRpbWUoKChUaW1lU3Bhbil2KS5UaWNrcykpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZyb21UeXBlID09IHR5cGVvZihzdHJpbmcpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIERhdGVUaW1lIGR0OwogICAgICAgICAgICAgICAgICAgIGlmIChEYXRlVGltZS5UcnlQYXJzZSh2LlRvU3RyaW5nKCksIG91dCBkdCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpKG9iamVjdCkoZHQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVmYXVsdChUKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjbnYuQ2FuQ29udmVydFRvKHR5cGVvZihkb3VibGUpKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCkob2JqZWN0KShEYXRlVGltZS5Gcm9tT0FEYXRlKChkb3VibGUpY252LkNvbnZlcnRUbyh2LCB0eXBlb2YoZG91YmxlKSkpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHRvVHlwZSA9PSB0eXBlb2YoVGltZVNwYW4pKSAgICAvL0hhbmRsZSB0aW1lc3BhbgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZnJvbVR5cGUgPT0gdHlwZW9mKERhdGVUaW1lKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChUKShvYmplY3QpKG5ldyBUaW1lU3BhbigoKERhdGVUaW1lKXYpLlRpY2tzKSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoZnJvbVR5cGUgPT0gdHlwZW9mKHN0cmluZykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVGltZVNwYW4gdHM7CiAgICAgICAgICAgICAgICAgICAgaWYgKFRpbWVTcGFuLlRyeVBhcnNlKHYuVG9TdHJpbmcoKSwgb3V0IHRzKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCkob2JqZWN0KSh0cyk7IAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVmYXVsdChUKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNudi5DYW5Db252ZXJ0VG8odHlwZW9mKGRvdWJsZSkpKQogICAgICAgICAgICAgICAgICAgIHsKCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCkob2JqZWN0KShuZXcgVGltZVNwYW4oRGF0ZVRpbWUuRnJvbU9BRGF0ZSgoZG91YmxlKWNudi5Db252ZXJ0VG8odiwgdHlwZW9mKGRvdWJsZSkpKS5UaWNrcykpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXNzdWUgMTQ2ODIgLS0gIkdldFZhbHVlPGRlY2ltYWw+KCkgd29uJ3QgY29udmVydCBzdHJpbmdzIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXMgc3VnZ2VzdGVkLCBhZnRlciBhbGwgc3BlY2lhbCBjYXNlcywgYWxsIC5ORVQgdG8gZG8gaXQncyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByZWZlcnJlZCBjb252ZXJzaW9uIHJhdGhlciB0aGFuIHNpbXBseSByZXR1cm5pbmcgdGhlIGRlZmF1bHQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVClDb252ZXJ0LkNoYW5nZVR5cGUodiwgdHlwZW9mKFQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIHdhcyB0aGUgcHJldmlvdXMgYmVoYXZpb3VyIC0tIG5vIGNvbnZlcnNpb24gaXMgYXZhaWxhYmxlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoY252LkNhbkNvbnZlcnRUbyh0b1R5cGUpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCljbnYuQ29udmVydFRvKHYsIHR5cGVvZihUKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRvVHlwZS5Jc0dlbmVyaWNUeXBlICYmIHRvVHlwZS5HZXRHZW5lcmljVHlwZURlZmluaXRpb24oKS5FcXVhbHModHlwZW9mKE51bGxhYmxlPD4pKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRvVHlwZSA9IE51bGxhYmxlLkdldFVuZGVybHlpbmdUeXBlKHRvVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjbnYuQ2FuQ29udmVydFRvKHRvVHlwZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCljbnYuQ29udmVydFRvKHYsIHR5cGVvZihUKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmKGZyb21UeXBlPT10eXBlb2YoZG91YmxlKSAmJiB0b1R5cGU9PXR5cGVvZihkZWNpbWFsKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCkob2JqZWN0KUNvbnZlcnQuVG9EZWNpbWFsKHYpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChmcm9tVHlwZSA9PSB0eXBlb2YoZGVjaW1hbCkgJiYgdG9UeXBlID09IHR5cGVvZihkb3VibGUpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChUKShvYmplY3QpQ29udmVydC5Ub0RvdWJsZSh2KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gU2V0IHRoZSB2YWx1ZSBvZiBhIGNlbGwKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iUm93Ij5UaGUgcm93IG51bWJlcjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJDb2x1bW4iPlRoZSBjb2x1bW4gbnVtYmVyPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlZhbHVlIj5UaGUgdmFsdWU8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIFNldFZhbHVlKGludCBSb3csIGludCBDb2x1bW4sIG9iamVjdCBWYWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIGlmIChSb3cgPCAxIHx8IENvbHVtbiA8IDEgfHwgUm93ID4gRXhjZWxQYWNrYWdlLk1heFJvd3MgJiYgQ29sdW1uID4gRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24oIlJvdyBvciBDb2x1bW4gb3V0IG9mIHJhbmdlIik7CiAgICAgICAgICAgIH0gICAgICAgICAgICAKICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShSb3csIENvbHVtbiwgVmFsdWUpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNldCB0aGUgdmFsdWUgb2YgYSBjZWxsCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IkFkZHJlc3MiPlRoZSBFeGNlbCBhZGRyZXNzPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlZhbHVlIj5UaGUgdmFsdWU8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIFNldFZhbHVlKHN0cmluZyBBZGRyZXNzLCBvYmplY3QgVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpbnQgcm93LCBjb2w7CiAgICAgICAgICAgIEV4Y2VsQWRkcmVzc0Jhc2UuR2V0Um93Q29sKEFkZHJlc3MsIG91dCByb3csIG91dCBjb2wsIHRydWUpOwogICAgICAgICAgICBpZiAocm93IDwgMSB8fCBjb2wgPCAxIHx8IHJvdyA+IEV4Y2VsUGFja2FnZS5NYXhSb3dzICYmIGNvbCA+IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCJBZGRyZXNzIGlzIGludmFsaWQgb3Igb3V0IG9mIHJhbmdlIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgVmFsdWUpOyAgICAgICAgICAgCiAgICAgICAgfQoKICAgICAgICAjcmVnaW9uIE1lcmdlQ2VsbElkCgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0IE1lcmdlQ2VsbCBJbmRleCBObwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3ciPjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW4iPjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBwdWJsaWMgaW50IEdldE1lcmdlQ2VsbElkKGludCByb3csIGludCBjb2x1bW4pCiAgICAgICAgewogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9tZXJnZWRDZWxscy5Db3VudDsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIGlmKCFzdHJpbmcuSXNOdWxsT3JFbXB0eSggX21lcmdlZENlbGxzW2ldKSkKICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEV4Y2VsUmFuZ2UgcmFuZ2UgPSBDZWxsc1tfbWVyZ2VkQ2VsbHNbaV1dOwoKICAgICAgICAgICAgICAgICAgICBpZiAocmFuZ2UuU3RhcnQuUm93IDw9IHJvdyAmJiByb3cgPD0gcmFuZ2UuRW5kLlJvdykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyYW5nZS5TdGFydC5Db2x1bW4gPD0gY29sdW1uICYmIGNvbHVtbiA8PSByYW5nZS5FbmQuQ29sdW1uKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaSArIDE7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAjZW5kcmVnaW9uCgkJI2VuZHJlZ2lvbiAvLyBFTkQgV29ya3NoZWV0IFB1YmxpYyBNZXRob2RzCgoJCSNyZWdpb24gV29ya3NoZWV0IFByaXZhdGUgTWV0aG9kcwoKCQkjcmVnaW9uIFdvcmtzaGVldCBTYXZlCiAgICAgICAgaW50ZXJuYWwgdm9pZCBTYXZlKCkKICAgICAgICB7CiAgICAgICAgICAgICAgICBEZWxldGVQcmludGVyU2V0dGluZ3MoKTsKCiAgICAgICAgICAgICAgICBpZiAoX3dvcmtzaGVldFhtbCAhPSBudWxsKQogICAgICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgICAgICBpZiAoISh0aGlzIGlzIEV4Y2VsQ2hhcnRzaGVldCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBzYXZlIHRoZSBoZWFkZXIgJiBmb290ZXIgKGlmIGRlZmluZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaGVhZGVyRm9vdGVyICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIZWFkZXJGb290ZXIuU2F2ZSgpOwoKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGQgPSBEaW1lbnNpb247CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuRGVsZXRlQWxsTm9kZSgiZDpkaW1lbnNpb24vQHJlZiIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5TZXRYbWxOb2RlU3RyaW5nKCJkOmRpbWVuc2lvbi9AcmVmIiwgZC5BZGRyZXNzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChEcmF3aW5ncy5Db3VudCA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1JlbW92ZSBub2RlIGlmIG5vIGRyYXdpbmdzIGV4aXN0cy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZU5vZGUoImQ6ZHJhd2luZyIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBTYXZlQ29tbWVudHMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgSGVhZGVyRm9vdGVyLlNhdmVIZWFkZXJGb290ZXJJbWFnZXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgU2F2ZVRhYmxlcygpOwogICAgICAgICAgICAgICAgICAgICAgICBTYXZlUGl2b3RUYWJsZXMoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKERyYXdpbmdzLlVyaURyYXdpbmchPW51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKERyYXdpbmdzLkNvdW50ID09IDApCiAgICAgICAgICAgICAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIFBhcnQuRGVsZXRlUmVsYXRpb25zaGlwKERyYXdpbmdzLl9kcmF3aW5nUmVsYXRpb24uSWQpOwogICAgICAgICAgICAgICAgICAgICAgICBfcGFja2FnZS5QYWNrYWdlLkRlbGV0ZVBhcnQoRHJhd2luZ3MuVXJpRHJhd2luZyk7ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IHBhcnRQYWNrID0gRHJhd2luZ3MuUGFydDsKICAgICAgICAgICAgICAgICAgICAgICAgRHJhd2luZ3MuRHJhd2luZ1htbC5TYXZlKHBhcnRQYWNrLkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuV3JpdGUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoRXhjZWxEcmF3aW5nIGQgaW4gRHJhd2luZ3MpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkIGlzIEV4Y2VsQ2hhcnQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxDaGFydCBjID0gKEV4Y2VsQ2hhcnQpZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLkNoYXJ0WG1sLlNhdmUoYy5QYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuV3JpdGUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBTYXZlSGFuZGxlcihaaXBPdXRwdXRTdHJlYW0gc3RyZWFtLCBDb21wcmVzc2lvbkxldmVsIGNvbXByZXNzaW9uTGV2ZWwsIHN0cmluZyBmaWxlTmFtZSkKICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy9Jbml0IFppcAogICAgICAgICAgICAgICAgICAgIHN0cmVhbS5Db2RlY0J1ZmZlclNpemUgPSA4MDk2OwogICAgICAgICAgICAgICAgICAgIHN0cmVhbS5Db21wcmVzc2lvbkxldmVsID0gKE9mZmljZU9wZW5YbWwuUGFja2FnaW5nLklvbmljLlpsaWIuQ29tcHJlc3Npb25MZXZlbCljb21wcmVzc2lvbkxldmVsOwogICAgICAgICAgICAgICAgICAgIHN0cmVhbS5QdXROZXh0RW50cnkoZmlsZU5hbWUpOwoKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICBTYXZlWG1sKHN0cmVhbSk7CiAgICAgICAgfQoKICAgICAgICAKCiAgICAgICAgLy8vLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vLy8gU2F2ZXMgdGhlIHdvcmtzaGVldCB0byB0aGUgcGFja2FnZS4KICAgICAgICAvLy8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy9pbnRlcm5hbCB2b2lkIFNhdmUoKSAgLy8gV29ya3NoZWV0IFNhdmUKICAgICAgICAvL3sKICAgICAgICAvLyAgICBEZWxldGVQcmludGVyU2V0dGluZ3MoKTsKCiAgICAgICAgLy8gICAgaWYgKF93b3Jrc2hlZXRYbWwgIT0gbnVsbCkKICAgICAgICAvLyAgICB7CiAgICAgICAgICAgICAgICAKICAgICAgICAvLyAgICAgICAgLy8gc2F2ZSB0aGUgaGVhZGVyICYgZm9vdGVyIChpZiBkZWZpbmVkKQogICAgICAgIC8vICAgICAgICBpZiAoX2hlYWRlckZvb3RlciAhPSBudWxsKQogICAgICAgIC8vICAgICAgICAgICAgSGVhZGVyRm9vdGVyLlNhdmUoKTsKCiAgICAgICAgLy8gICAgICAgIHZhciBkID0gRGltZW5zaW9uOwogICAgICAgIC8vICAgICAgICBpZiAoZCA9PSBudWxsKQogICAgICAgIC8vICAgICAgICB7CiAgICAgICAgLy8gICAgICAgICAgICB0aGlzLkRlbGV0ZUFsbE5vZGUoImQ6ZGltZW5zaW9uL0ByZWYiKTsKICAgICAgICAvLyAgICAgICAgfQogICAgICAgIC8vICAgICAgICBlbHNlCiAgICAgICAgLy8gICAgICAgIHsKICAgICAgICAvLyAgICAgICAgICAgIHRoaXMuU2V0WG1sTm9kZVN0cmluZygiZDpkaW1lbnNpb24vQHJlZiIsIGQuQWRkcmVzcyk7CiAgICAgICAgLy8gICAgICAgIH0KICAgICAgICAgICAgICAgIAoKICAgICAgICAvLyAgICAgICAgaWYgKF9kcmF3aW5ncyAhPSBudWxsICYmIF9kcmF3aW5ncy5Db3VudCA9PSAwKQogICAgICAgIC8vICAgICAgICB7CiAgICAgICAgLy8gICAgICAgICAgICAvL1JlbW92ZSBub2RlIGlmIG5vIGRyYXdpbmdzIGV4aXN0cy4KICAgICAgICAvLyAgICAgICAgICAgIERlbGV0ZU5vZGUoImQ6ZHJhd2luZyIpOwogICAgICAgIC8vICAgICAgICB9CgogICAgICAgIC8vICAgICAgICBTYXZlQ29tbWVudHMoKTsKICAgICAgICAvLyAgICAgICAgSGVhZGVyRm9vdGVyLlNhdmVIZWFkZXJGb290ZXJJbWFnZXMoKTsKICAgICAgICAvLyAgICAgICAgU2F2ZVRhYmxlcygpOwogICAgICAgIC8vICAgICAgICBTYXZlUGl2b3RUYWJsZXMoKTsKICAgICAgICAvLyAgICAgICAgU2F2ZVhtbCgpOwogICAgICAgIC8vICAgIH0KICAgICAgICAgICAgCiAgICAgICAgLy8gICAgaWYgKERyYXdpbmdzLlVyaURyYXdpbmchPW51bGwpCiAgICAgICAgLy8gICAgewogICAgICAgIC8vICAgICAgICBpZiAoRHJhd2luZ3MuQ291bnQgPT0gMCkKICAgICAgICAvLyAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgLy8gICAgICAgICAgICBQYXJ0LkRlbGV0ZVJlbGF0aW9uc2hpcChEcmF3aW5ncy5fZHJhd2luZ1JlbGF0aW9uLklkKTsKICAgICAgICAvLyAgICAgICAgICAgIF9wYWNrYWdlLlBhY2thZ2UuRGVsZXRlUGFydChEcmF3aW5ncy5VcmlEcmF3aW5nKTsgICAgICAgICAgICAgICAgICAgIAogICAgICAgIC8vICAgICAgICB9CiAgICAgICAgLy8gICAgICAgIGVsc2UKICAgICAgICAvLyAgICAgICAgewogICAgICAgIC8vICAgICAgICAgICAgUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IHBhcnRQYWNrID0gRHJhd2luZ3MuUGFydDsKICAgICAgICAvLyAgICAgICAgICAgIERyYXdpbmdzLkRyYXdpbmdYbWwuU2F2ZShwYXJ0UGFjay5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgLy8gICAgICAgICAgICBmb3JlYWNoIChFeGNlbERyYXdpbmcgZCBpbiBEcmF3aW5ncykKICAgICAgICAvLyAgICAgICAgICAgIHsKICAgICAgICAvLyAgICAgICAgICAgICAgICBpZiAoZCBpcyBFeGNlbENoYXJ0KQogICAgICAgIC8vICAgICAgICAgICAgICAgIHsKICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgRXhjZWxDaGFydCBjID0gKEV4Y2VsQ2hhcnQpZDsKICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgYy5DaGFydFhtbC5TYXZlKGMuUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgLy8gICAgICAgICAgICAgICAgfQogICAgICAgIC8vICAgICAgICAgICAgfQogICAgICAgIC8vICAgICAgICB9CiAgICAgICAgLy8gICAgfQogICAgICAgIC8vfQoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIERlbGV0ZSB0aGUgcHJpbnRlcnNldHRpbmdzIHJlbGF0aW9uc2hpcCBhbmQgcGFydC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHByaXZhdGUgdm9pZCBEZWxldGVQcmludGVyU2V0dGluZ3MoKQogICAgICAgIHsKICAgICAgICAgICAgLy9EZWxldGUgdGhlIHJlbGF0aW9uc2hpcCBmcm9tIHRoZSBwYWdlU2V0dXAgdGFnCiAgICAgICAgICAgIFhtbEF0dHJpYnV0ZSBhdHRyID0gKFhtbEF0dHJpYnV0ZSlXb3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOnBhZ2VTZXR1cC9AcjppZCIsIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICBpZiAoYXR0ciAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJpbmcgcmVsSUQgPSBhdHRyLlZhbHVlOwogICAgICAgICAgICAgICAgLy9GaXJzdCBkZWxldGUgdGhlIGF0dHJpYnV0ZSBmcm9tIHRoZSBYTUwKICAgICAgICAgICAgICAgIGF0dHIuT3duZXJFbGVtZW50LkF0dHJpYnV0ZXMuUmVtb3ZlKGF0dHIpOwogICAgICAgICAgICAgICAgaWYoUGFydC5SZWxhdGlvbnNoaXBFeGlzdHMocmVsSUQpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciByZWwgPSBQYXJ0LkdldFJlbGF0aW9uc2hpcChyZWxJRCk7CiAgICAgICAgICAgICAgICAgICAgVXJpIHByaW50ZXJTZXR0aW5nc1VyaSA9IFVyaUhlbHBlci5SZXNvbHZlUGFydFVyaShyZWwuU291cmNlVXJpLCByZWwuVGFyZ2V0VXJpKTsKICAgICAgICAgICAgICAgICAgICBQYXJ0LkRlbGV0ZVJlbGF0aW9uc2hpcChyZWwuSWQpOwoKICAgICAgICAgICAgICAgICAgICAvL0RlbGV0ZSB0aGUgcGFydCBmcm9tIHRoZSBwYWNrYWdlCiAgICAgICAgICAgICAgICAgICAgaWYoX3BhY2thZ2UuUGFja2FnZS5QYXJ0RXhpc3RzKHByaW50ZXJTZXR0aW5nc1VyaSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfcGFja2FnZS5QYWNrYWdlLkRlbGV0ZVBhcnQocHJpbnRlclNldHRpbmdzVXJpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIFNhdmVDb21tZW50cygpCiAgICAgICAgewogICAgICAgICAgICBpZiAoX2NvbW1lbnRzICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfY29tbWVudHMuQ291bnQgPT0gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoX2NvbW1lbnRzLlVyaSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgUGFydC5EZWxldGVSZWxhdGlvbnNoaXAoX2NvbW1lbnRzLlJlbElkKTsKICAgICAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UuUGFja2FnZS5EZWxldGVQYXJ0KF9jb21tZW50cy5VcmkpOyAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBSZW1vdmVMZWdhY3lEcmF3aW5nUmVsKFZtbERyYXdpbmdzQ29tbWVudHMuUmVsSWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChfY29tbWVudHMuVXJpID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfY29tbWVudHMuVXJpPW5ldyBVcmkoc3RyaW5nLkZvcm1hdChAIi94bC9jb21tZW50c3swfS54bWwiLCBTaGVldElEKSwgVXJpS2luZC5SZWxhdGl2ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmKF9jb21tZW50cy5QYXJ0PT1udWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX2NvbW1lbnRzLlBhcnQgPSBfcGFja2FnZS5QYWNrYWdlLkNyZWF0ZVBhcnQoX2NvbW1lbnRzLlVyaSwgImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLmNvbW1lbnRzK3htbCIsIF9wYWNrYWdlLkNvbXByZXNzaW9uKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlbCA9IFBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaShXb3Jrc2hlZXRVcmksIF9jb21tZW50cy5VcmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMrIi9jb21tZW50cyIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBfY29tbWVudHMuQ29tbWVudFhtbC5TYXZlKF9jb21tZW50cy5QYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKF92bWxEcmF3aW5ncyAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX3ZtbERyYXdpbmdzLkNvdW50ID09IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKF92bWxEcmF3aW5ncy5VcmkgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFBhcnQuRGVsZXRlUmVsYXRpb25zaGlwKF92bWxEcmF3aW5ncy5SZWxJZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9wYWNrYWdlLlBhY2thZ2UuRGVsZXRlUGFydChfdm1sRHJhd2luZ3MuVXJpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKF92bWxEcmF3aW5ncy5VcmkgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92bWxEcmF3aW5ncy5VcmkgPSBYbWxIZWxwZXIuR2V0TmV3VXJpKF9wYWNrYWdlLlBhY2thZ2UsIEAiL3hsL2RyYXdpbmdzL3ZtbERyYXdpbmd7MH0udm1sIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChfdm1sRHJhd2luZ3MuUGFydCA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZtbERyYXdpbmdzLlBhcnQgPSBfcGFja2FnZS5QYWNrYWdlLkNyZWF0ZVBhcnQoX3ZtbERyYXdpbmdzLlVyaSwgImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC52bWxEcmF3aW5nIiwgX3BhY2thZ2UuQ29tcHJlc3Npb24pOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVsID0gUGFydC5DcmVhdGVSZWxhdGlvbnNoaXAoVXJpSGVscGVyLkdldFJlbGF0aXZlVXJpKFdvcmtzaGVldFVyaSwgX3ZtbERyYXdpbmdzLlVyaSksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcyArICIvdm1sRHJhd2luZyIpOwogICAgICAgICAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJkOmxlZ2FjeURyYXdpbmcvQHI6aWQiLCByZWwuSWQpOwogICAgICAgICAgICAgICAgICAgICAgICBfdm1sRHJhd2luZ3MuUmVsSWQgPSByZWwuSWQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF92bWxEcmF3aW5ncy5WbWxEcmF3aW5nWG1sLlNhdmUoX3ZtbERyYXdpbmdzLlBhcnQuR2V0U3RyZWFtKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gU2F2ZSBhbGwgdGFibGUgZGF0YQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHJpdmF0ZSB2b2lkIFNhdmVUYWJsZXMoKQogICAgICAgIHsKICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRibCBpbiBUYWJsZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0YmwuU2hvd0hlYWRlciB8fCB0YmwuU2hvd1RvdGFsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGludCBjb2xOdW0gPSB0YmwuQWRkcmVzcy5fZnJvbUNvbDsKICAgICAgICAgICAgICAgICAgICB2YXIgY29sVmFsID0gbmV3IEhhc2hTZXQ8c3RyaW5nPigpOwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBjb2wgaW4gdGJsLkNvbHVtbnMpCiAgICAgICAgICAgICAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgbj1jb2wuTmFtZS5Ub0xvd2VyKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGJsLlNob3dIZWFkZXIpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4gPSB0YmwuV29ya1NoZWV0LkdldFZhbHVlPHN0cmluZz4odGJsLkFkZHJlc3MuX2Zyb21Sb3csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJsLkFkZHJlc3MuX2Zyb21Db2wgKyBjb2wuUG9zaXRpb24pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KG4pKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4gPSBjb2wuTmFtZS5Ub0xvd2VyKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5OYW1lID0gbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4gPSBjb2wuTmFtZS5Ub0xvd2VyKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNvbFZhbC5Db250YWlucyhuKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cobmV3IEludmFsaWREYXRhRXhjZXB0aW9uKHN0cmluZy5Gb3JtYXQoIlRhYmxlIHswfSBDb2x1bW4gezF9IGRvZXMgbm90IGhhdmUgYSB1bmlxdWUgbmFtZS4iLCB0YmwuTmFtZSwgY29sLk5hbWUpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgY29sVmFsLkFkZChuKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29sLk5hbWUgPSBDb252ZXJ0VXRpbC5FeGNlbEVuY29kZVN0cmluZyhjb2wuTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YmwuU2hvd0hlYWRlcikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZSh0YmwuQWRkcmVzcy5fZnJvbVJvdywgY29sTnVtLCBjb2wuTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRibC5TaG93VG90YWwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldFRhYmxlVG90YWxGdW5jdGlvbih0YmwsIGNvbCwgY29sTnVtKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KGNvbC5DYWxjdWxhdGVkQ29sdW1uRm9ybXVsYSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmcm9tUm93ID0gdGJsLlNob3dIZWFkZXIgPyB0YmwuQWRkcmVzcy5fZnJvbVJvdyArIDEgOiB0YmwuQWRkcmVzcy5fZnJvbVJvdzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB0b1JvdyA9IHRibC5TaG93VG90YWwgPyB0YmwuQWRkcmVzcy5fdG9Sb3cgLSAxIDogdGJsLkFkZHJlc3MuX3RvUm93OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgcm93ID0gZnJvbVJvdzsgcm93IDw9IHRvUm93OyByb3crKykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0NlbGwocm93LCBjb2xOdW0pLkZvcm11bGEgPSBjb2wuQ2FsY3VsYXRlZENvbHVtbkZvcm11bGE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYShyb3csIGNvbE51bSwgY29sLkNhbGN1bGF0ZWRDb2x1bW5Gb3JtdWxhKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgY29sTnVtKys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmICh0YmwuUGFydCA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRibC5UYWJsZVVyaSA9IEdldE5ld1VyaShfcGFja2FnZS5QYWNrYWdlLCBAIi94bC90YWJsZXMvdGFibGV7MH0ueG1sIiwgdGJsLklkKTsKICAgICAgICAgICAgICAgICAgICB0YmwuUGFydCA9IF9wYWNrYWdlLlBhY2thZ2UuQ3JlYXRlUGFydCh0YmwuVGFibGVVcmksICJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC50YWJsZSt4bWwiLCBXb3JrYm9vay5fcGFja2FnZS5Db21wcmVzc2lvbik7CiAgICAgICAgICAgICAgICAgICAgdmFyIHN0cmVhbSA9IHRibC5QYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUpOwogICAgICAgICAgICAgICAgICAgIHRibC5UYWJsZVhtbC5TYXZlKHN0cmVhbSk7CiAgICAgICAgICAgICAgICAgICAgdmFyIHJlbCA9IFBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaShXb3Jrc2hlZXRVcmksIHRibC5UYWJsZVVyaSksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcyArICIvdGFibGUiKTsKICAgICAgICAgICAgICAgICAgICB0YmwuUmVsYXRpb25zaGlwSUQgPSByZWwuSWQ7CgogICAgICAgICAgICAgICAgICAgIENyZWF0ZU5vZGUoImQ6dGFibGVQYXJ0cyIpOwogICAgICAgICAgICAgICAgICAgIFhtbE5vZGUgdGJscyA9IFRvcE5vZGUuU2VsZWN0U2luZ2xlTm9kZSgiZDp0YWJsZVBhcnRzIixOYW1lU3BhY2VNYW5hZ2VyKTsKCiAgICAgICAgICAgICAgICAgICAgdmFyIHRibE5vZGUgPSB0YmxzLk93bmVyRG9jdW1lbnQuQ3JlYXRlRWxlbWVudCgidGFibGVQYXJ0IixFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CiAgICAgICAgICAgICAgICAgICAgdGJscy5BcHBlbmRDaGlsZCh0YmxOb2RlKTsKICAgICAgICAgICAgICAgICAgICB0YmxOb2RlLlNldEF0dHJpYnV0ZSgiaWQiLEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzLCByZWwuSWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciBzdHJlYW0gPSB0YmwuUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlKTsKICAgICAgICAgICAgICAgICAgICB0YmwuVGFibGVYbWwuU2F2ZShzdHJlYW0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpbnRlcm5hbCB2b2lkIFNldFRhYmxlVG90YWxGdW5jdGlvbihFeGNlbFRhYmxlIHRibCwgRXhjZWxUYWJsZUNvbHVtbiBjb2wsIGludCBjb2xOdW09LTEpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGJsLlNob3dUb3RhbCA9PSBmYWxzZSkgcmV0dXJuOwogICAgICAgICAgICBpZiAoY29sTnVtID09IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRibC5Db2x1bW5zLkNvdW50OyBpKyspCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRibC5Db2x1bW5zW2ldLk5hbWUgPT0gY29sLk5hbWUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb2xOdW0gPSB0YmwuQWRkcmVzcy5fZnJvbUNvbCArIGk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjb2wuVG90YWxzUm93RnVuY3Rpb24gPT0gUm93RnVuY3Rpb25zLkN1c3RvbSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgY29sLlRvdGFsc1Jvd0Zvcm11bGEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGNvbC5Ub3RhbHNSb3dGdW5jdGlvbiAhPSBSb3dGdW5jdGlvbnMuTm9uZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3dpdGNoIChjb2wuVG90YWxzUm93RnVuY3Rpb24pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuQXZlcmFnZToKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDEiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLkNvdW50OgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjEwMiIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuQ291bnROdW1zOgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjEwMyIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuTWF4OgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjEwNCIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuTWluOgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjEwNSIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuU3RkRGV2OgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjEwNyIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuVmFyOgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjExMCIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuU3VtOgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjEwOSIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBFeGNlcHRpb24oIlVua25vd24gUm93RnVuY3Rpb24gZW51bSIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUodGJsLkFkZHJlc3MuX3RvUm93LCBjb2xOdW0sIGNvbC5Ub3RhbHNSb3dMYWJlbCk7CgogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpbnRlcm5hbCB2b2lkIFNldEZvcm11bGEoaW50IHJvdywgaW50IGNvbCwgb2JqZWN0IHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgX2Zvcm11bGFzLlNldFZhbHVlKHJvdywgY29sLCB2YWx1ZSk7CiAgICAgICAgICAgIGlmICghX3ZhbHVlcy5FeGlzdHMocm93LCBjb2wpKSBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCBudWxsKTsKICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBTZXRTdHlsZShpbnQgcm93LCBpbnQgY29sLCBpbnQgdmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBfc3R5bGVzLlNldFZhbHVlKHJvdywgY29sLCB2YWx1ZSk7CiAgICAgICAgICAgIGlmKCFfdmFsdWVzLkV4aXN0cyhyb3csY29sKSkgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgbnVsbCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHByaXZhdGUgdm9pZCBTYXZlUGl2b3RUYWJsZXMoKQogICAgICAgIHsKICAgICAgICAgICAgZm9yZWFjaCAodmFyIHB0IGluIFBpdm90VGFibGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocHQuRGF0YUZpZWxkcy5Db3VudCA+IDEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgWG1sRWxlbWVudCBwYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIGlmKHB0LkRhdGFPblJvd3M9PXRydWUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gIHB0LlBpdm90VGFibGVYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOnJvd0ZpZWxkcyIsIHB0Lk5hbWVTcGFjZU1hbmFnZXIpIGFzIFhtbEVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnROb2RlID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB0LkNyZWF0ZU5vZGUoImQ6cm93RmllbGRzIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gcHQuUGl2b3RUYWJsZVhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6cm93RmllbGRzIiwgcHQuTmFtZVNwYWNlTWFuYWdlcikgYXMgWG1sRWxlbWVudDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gIHB0LlBpdm90VGFibGVYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOmNvbEZpZWxkcyIsIHB0Lk5hbWVTcGFjZU1hbmFnZXIpIGFzIFhtbEVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnROb2RlID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB0LkNyZWF0ZU5vZGUoImQ6Y29sRmllbGRzIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gcHQuUGl2b3RUYWJsZVhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6Y29sRmllbGRzIiwgcHQuTmFtZVNwYWNlTWFuYWdlcikgYXMgWG1sRWxlbWVudDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudE5vZGUuU2VsZWN0U2luZ2xlTm9kZSgiZDpmaWVsZFtAIHg9IFwiLTJcIl0iLCBwdC5OYW1lU3BhY2VNYW5hZ2VyKSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgWG1sRWxlbWVudCBmaWVsZE5vZGUgPSBwdC5QaXZvdFRhYmxlWG1sLkNyZWF0ZUVsZW1lbnQoImZpZWxkIiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwogICAgICAgICAgICAgICAgICAgICAgICBmaWVsZE5vZGUuU2V0QXR0cmlidXRlKCJ4IiwgIi0yIik7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUuQXBwZW5kQ2hpbGQoZmllbGROb2RlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgd3MgPSBXb3JrYm9vay5Xb3Jrc2hlZXRzW3B0LkNhY2hlRGVmaW5pdGlvbi5Tb3VyY2VSYW5nZS5Xb3JrU2hlZXRdOwogICAgICAgICAgICAgICAgdmFyIHQgPSB3cy5UYWJsZXMuR2V0RnJvbVJhbmdlKHB0LkNhY2hlRGVmaW5pdGlvbi5Tb3VyY2VSYW5nZSk7CiAgICAgICAgICAgICAgICB2YXIgZmllbGRzID0KICAgICAgICAgICAgICAgICAgICBwdC5DYWNoZURlZmluaXRpb24uQ2FjaGVEZWZpbml0aW9uWG1sLlNlbGVjdE5vZGVzKAogICAgICAgICAgICAgICAgICAgICAgICAiZDpwaXZvdENhY2hlRGVmaW5pdGlvbi9kOmNhY2hlRmllbGRzL2Q6Y2FjaGVGaWVsZCIsIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICAgICAgaW50IGl4ID0gMDsKICAgICAgICAgICAgICAgIGlmIChmaWVsZHMgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZmxkcyA9IG5ldyBIYXNoU2V0PHN0cmluZz4oKTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoIChYbWxFbGVtZW50IG5vZGUgaW4gZmllbGRzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl4ID49IHB0LkNhY2hlRGVmaW5pdGlvbi5Tb3VyY2VSYW5nZS5Db2x1bW5zKSBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZsZE5hbWUgPSBub2RlLkdldEF0dHJpYnV0ZSgibmFtZSIpOyAgICAgICAgICAgICAgICAgICAgICAgIC8vRml4ZXMgaXNzdWUgMTUyOTUgZHVwIG5hbWUgZXJyb3IKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGZsZE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGROYW1lID0gKHQgPT0gbnVsbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gcHQuQ2FjaGVEZWZpbml0aW9uLlNvdXJjZVJhbmdlLk9mZnNldCgwLCBpeCsrLCAxLCAxKS5WYWx1ZS5Ub1N0cmluZygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB0LkNvbHVtbnNbaXgrK10uTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZsZHMuQ29udGFpbnMoZmxkTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGROYW1lID0gR2V0TmV3TmFtZShmbGRzLCBmbGROYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBmbGRzLkFkZChmbGROYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5TZXRBdHRyaWJ1dGUoIm5hbWUiLCBmbGROYW1lKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGRmIGluIHB0LkRhdGFGaWVsZHMpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RyaW5nLklzTnVsbE9yRW1wdHkoZGYuTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBuYW1lOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRmLkZ1bmN0aW9uID09IERhdGFGaWVsZEZ1bmN0aW9ucy5Ob25lKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBkZi5GaWVsZC5OYW1lOyAvL05hbWUgbXVzdCBiZSBzZXQgb3IgRXhjZWwgd2lsbCBjcmFzaCBvbiByZW5hbWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gZGYuRnVuY3Rpb24uVG9TdHJpbmcoKSArICIgb2YgIiArIGRmLkZpZWxkLk5hbWU7IC8vTmFtZSBtdXN0IGJlIHNldCBvciBFeGNlbCB3aWxsIGNyYXNoIG9uIHJlbmFtZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vTWFrZSBzdXJlIG5hbWUgaXMgdW5pcXVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3TmFtZSA9IG5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocHQuRGF0YUZpZWxkcy5FeGlzdHNEZk5hbWUobmV3TmFtZSwgZGYpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld05hbWUgPSBuYW1lICsgKGkrKykuVG9TdHJpbmcoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZi5OYW1lID0gbmV3TmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHB0LlBpdm90VGFibGVYbWwuU2F2ZShwdC5QYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUpKTsKICAgICAgICAgICAgICAgIHB0LkNhY2hlRGVmaW5pdGlvbi5DYWNoZURlZmluaXRpb25YbWwuU2F2ZShwdC5DYWNoZURlZmluaXRpb24uUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgc3RyaW5nIEdldE5ld05hbWUoSGFzaFNldDxzdHJpbmc+IGZsZHMsIHN0cmluZyBmbGROYW1lKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGl4ID0gMjsKICAgICAgICAgICAgd2hpbGUgKGZsZHMuQ29udGFpbnMoZmxkTmFtZSArIGl4LlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaXgrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmxkTmFtZSArIGl4LlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgc3RyaW5nIEdldFRvdGFsRnVuY3Rpb24oRXhjZWxUYWJsZUNvbHVtbiBjb2wsc3RyaW5nIEZ1bmN0aW9uTnVtKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHN0cmluZy5Gb3JtYXQoIlNVQlRPVEFMKHswfSx7MX1bezJ9XSkiLCBGdW5jdGlvbk51bSwgY29sLl90YmwuTmFtZSwgY29sLk5hbWUpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgU2F2ZVhtbChTdHJlYW0gc3RyZWFtKQogICAgICAgIHsKICAgICAgICAgICAgLy9DcmVhdGUgdGhlIG5vZGVzIGlmIHRoZXkgZG8gbm90IGV4aXN0LgogICAgICAgICAgICBTdHJlYW1Xcml0ZXIgc3cgPSBuZXcgU3RyZWFtV3JpdGVyKHN0cmVhbSwgU3lzdGVtLlRleHQuRW5jb2RpbmcuVVRGOCwgNjU1MzYpOwogICAgICAgICAgICBpZiAodGhpcyBpcyBFeGNlbENoYXJ0c2hlZXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3LldyaXRlKF93b3Jrc2hlZXRYbWwuT3V0ZXJYbWwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ3JlYXRlTm9kZSgiZDpjb2xzIik7CiAgICAgICAgICAgICAgICBDcmVhdGVOb2RlKCJkOnNoZWV0RGF0YSIpOwogICAgICAgICAgICAgICAgQ3JlYXRlTm9kZSgiZDptZXJnZUNlbGxzIik7CiAgICAgICAgICAgICAgICBDcmVhdGVOb2RlKCJkOmh5cGVybGlua3MiKTsKICAgICAgICAgICAgICAgIENyZWF0ZU5vZGUoImQ6cm93QnJlYWtzIik7CiAgICAgICAgICAgICAgICBDcmVhdGVOb2RlKCJkOmNvbEJyZWFrcyIpOwoKICAgICAgICAgICAgICAgIC8vU3RyZWFtV3JpdGVyIHN3PW5ldyBTdHJlYW1Xcml0ZXIoUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgICAgICAgICB2YXIgeG1sID0gX3dvcmtzaGVldFhtbC5PdXRlclhtbDsKICAgICAgICAgICAgICAgIGludCBjb2xTdGFydCA9IDAsIGNvbEVuZCA9IDA7CiAgICAgICAgICAgICAgICBHZXRCbG9ja1Bvcyh4bWwsICJjb2xzIiwgcmVmIGNvbFN0YXJ0LCByZWYgY29sRW5kKTsKCiAgICAgICAgICAgICAgICBzdy5Xcml0ZSh4bWwuU3Vic3RyaW5nKDAsIGNvbFN0YXJ0KSk7CiAgICAgICAgICAgICAgICB2YXIgY29sQnJlYWtzID0gbmV3IExpc3Q8aW50PigpOwogICAgICAgICAgICAgICAgLy9pZiAoX2NvbHVtbnMuQ291bnQgPiAwKQogICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICBVcGRhdGVDb2x1bW5EYXRhKHN3KTsKICAgICAgICAgICAgICAgIC8vfQoKICAgICAgICAgICAgICAgIGludCBjZWxsU3RhcnQgPSBjb2xFbmQsIGNlbGxFbmQgPSBjb2xFbmQ7CiAgICAgICAgICAgICAgICBHZXRCbG9ja1Bvcyh4bWwsICJzaGVldERhdGEiLCByZWYgY2VsbFN0YXJ0LCByZWYgY2VsbEVuZCk7CgogICAgICAgICAgICAgICAgc3cuV3JpdGUoeG1sLlN1YnN0cmluZyhjb2xFbmQsIGNlbGxTdGFydCAtIGNvbEVuZCkpOwogICAgICAgICAgICAgICAgdmFyIHJvd0JyZWFrcyA9IG5ldyBMaXN0PGludD4oKTsKICAgICAgICAgICAgICAgIFVwZGF0ZVJvd0NlbGxEYXRhKHN3KTsKCiAgICAgICAgICAgICAgICBpbnQgbWVyZ2VTdGFydCA9IGNlbGxFbmQsIG1lcmdlRW5kID0gY2VsbEVuZDsKCiAgICAgICAgICAgICAgICBHZXRCbG9ja1Bvcyh4bWwsICJtZXJnZUNlbGxzIiwgcmVmIG1lcmdlU3RhcnQsIHJlZiBtZXJnZUVuZCk7CiAgICAgICAgICAgICAgICBzdy5Xcml0ZSh4bWwuU3Vic3RyaW5nKGNlbGxFbmQsIG1lcmdlU3RhcnQgLSBjZWxsRW5kKSk7CgogICAgICAgICAgICAgICAgQ2xlYW51cE1lcmdlZENlbGxzKF9tZXJnZWRDZWxscyk7CiAgICAgICAgICAgICAgICBpZiAoX21lcmdlZENlbGxzLkNvdW50ID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBVcGRhdGVNZXJnZWRDZWxscyhzdyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaW50IGh5cGVyU3RhcnQgPSBtZXJnZUVuZCwgaHlwZXJFbmQgPSBtZXJnZUVuZDsKICAgICAgICAgICAgICAgIEdldEJsb2NrUG9zKHhtbCwgImh5cGVybGlua3MiLCByZWYgaHlwZXJTdGFydCwgcmVmIGh5cGVyRW5kKTsKICAgICAgICAgICAgICAgIHN3LldyaXRlKHhtbC5TdWJzdHJpbmcobWVyZ2VFbmQsIGh5cGVyU3RhcnQgLSBtZXJnZUVuZCkpOwogICAgICAgICAgICAgICAgLy9pZiAoX2h5cGVyTGlua0NlbGxzLkNvdW50ID4gMCkKICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgVXBkYXRlSHlwZXJMaW5rcyhzdyk7CiAgICAgICAgICAgICAgICAvLyB9CgogICAgICAgICAgICAgICAgaW50IHJvd0JyZWFrU3RhcnQgPSBoeXBlckVuZCwgcm93QnJlYWtFbmQgPSBoeXBlckVuZDsKICAgICAgICAgICAgICAgIEdldEJsb2NrUG9zKHhtbCwgInJvd0JyZWFrcyIsIHJlZiByb3dCcmVha1N0YXJ0LCByZWYgcm93QnJlYWtFbmQpOwogICAgICAgICAgICAgICAgc3cuV3JpdGUoeG1sLlN1YnN0cmluZyhoeXBlckVuZCwgcm93QnJlYWtTdGFydCAtIGh5cGVyRW5kKSk7CiAgICAgICAgICAgICAgICAvL2lmIChyb3dCcmVha3MuQ291bnQgPiAwKQogICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICBVcGRhdGVSb3dCcmVha3Moc3cpOwogICAgICAgICAgICAgICAgLy99CgogICAgICAgICAgICAgICAgaW50IGNvbEJyZWFrU3RhcnQgPSByb3dCcmVha0VuZCwgY29sQnJlYWtFbmQgPSByb3dCcmVha0VuZDsKICAgICAgICAgICAgICAgIEdldEJsb2NrUG9zKHhtbCwgImNvbEJyZWFrcyIsIHJlZiBjb2xCcmVha1N0YXJ0LCByZWYgY29sQnJlYWtFbmQpOwogICAgICAgICAgICAgICAgc3cuV3JpdGUoeG1sLlN1YnN0cmluZyhyb3dCcmVha0VuZCwgY29sQnJlYWtTdGFydCAtIHJvd0JyZWFrRW5kKSk7CiAgICAgICAgICAgICAgICAvL2lmIChjb2xCcmVha3MuQ291bnQgPiAwKQogICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICBVcGRhdGVDb2xCcmVha3Moc3cpOwogICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgICAgICBzdy5Xcml0ZSh4bWwuU3Vic3RyaW5nKGNvbEJyZWFrRW5kLCB4bWwuTGVuZ3RoIC0gY29sQnJlYWtFbmQpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdy5GbHVzaCgpOwogICAgICAgICAgICAvL3N3LkNsb3NlKCk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgQ2xlYW51cE1lcmdlZENlbGxzKE1lcmdlQ2VsbHNDb2xsZWN0aW9uIF9tZXJnZWRDZWxscykKICAgICAgICB7CiAgICAgICAgICAgIGludCBpPTA7CiAgICAgICAgICAgIHdoaWxlIChpIDwgX21lcmdlZENlbGxzLkxpc3QuQ291bnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfbWVyZ2VkQ2VsbHNbaV0gPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuTGlzdC5SZW1vdmVBdChpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIFVwZGF0ZUNvbEJyZWFrcyhTdHJlYW1Xcml0ZXIgc3cpCiAgICAgICAgewogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIGJyZWFrcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgIGludCBjb3VudCA9IDA7CiAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfdmFsdWVzLCAwLCAwLCAwLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgIC8vZm9yZWFjaCAoRXhjZWxDb2x1bW4gY29sIGluIF9jb2x1bW5zKQogICAgICAgICAgICB3aGlsZShjc2UuTmV4dCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgY29sPWNzZS5WYWx1ZSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgICAgIGlmIChjb2wgIT0gbnVsbCAmJiBjb2wuUGFnZUJyZWFrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGJyZWFrcy5BcHBlbmRGb3JtYXQoIjxicmsgaWQ9XCJ7MH1cIiBtYXg9XCIxNjM4M1wiIG1hbj1cIjFcIiAvPiIsIGNzZS5Db2x1bW4pOwogICAgICAgICAgICAgICAgICAgIGNvdW50Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNvdW50ID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3cuV3JpdGUoc3RyaW5nLkZvcm1hdCgiPGNvbEJyZWFrcyBjb3VudD1cInswfVwiIG1hbnVhbEJyZWFrQ291bnQ9XCJ7MH1cIj57MX08L2NvbEJyZWFrcz4iLCBjb3VudCwgYnJlYWtzLlRvU3RyaW5nKCkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIFVwZGF0ZVJvd0JyZWFrcyhTdHJlYW1Xcml0ZXIgc3cpCiAgICAgICAgewogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIGJyZWFrcz1uZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBpbnQgY291bnQgPSAwOwogICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX3ZhbHVlcywgMCwgMCwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIDApOwogICAgICAgICAgICAvL2ZvcmVhY2goRXhjZWxSb3cgcm93IGluIF9yb3dzKSAgICAgICAgICAgIAogICAgICAgICAgICB3aGlsZShjc2UuTmV4dCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgcm93PWNzZS5WYWx1ZSBhcyBSb3dJbnRlcm5hbDsKICAgICAgICAgICAgICAgIGlmIChyb3cgIT0gbnVsbCAmJiByb3cuUGFnZUJyZWFrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGJyZWFrcy5BcHBlbmRGb3JtYXQoIjxicmsgaWQ9XCJ7MH1cIiBtYXg9XCIxMDQ4NTc1XCIgbWFuPVwiMVwiIC8+IiwgY3NlLlJvdyk7CiAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY291bnQ+MCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3cuV3JpdGUoc3RyaW5nLkZvcm1hdCgiPHJvd0JyZWFrcyBjb3VudD1cInswfVwiIG1hbnVhbEJyZWFrQ291bnQ9XCJ7MH1cIj57MX08L3Jvd0JyZWFrcz4iLCBjb3VudCwgYnJlYWtzLlRvU3RyaW5nKCkpKTsgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBJbnNlcnRzIHRoZSBjb2xzIGNvbGxlY3Rpb24gaW50byB0aGUgWE1MIGRvY3VtZW50CiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwcml2YXRlIHZvaWQgVXBkYXRlQ29sdW1uRGF0YShTdHJlYW1Xcml0ZXIgc3cpCiAgICAgICAgewogICAgICAgICAgICAvL0V4Y2VsQ29sdW1uIHByZXZDb2wgPSBudWxsOyAgIC8vY29tbWVudGVkIG91dCAxMS8xLTEyIEpLIAogICAgICAgICAgICAvL2ZvcmVhY2ggKEV4Y2VsQ29sdW1uIGNvbCBpbiBfY29sdW1ucykKICAgICAgICAgICAgLy97ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAvLyAgICBpZiAocHJldkNvbCAhPSBudWxsKQogICAgICAgICAgICAvLyAgICB7CiAgICAgICAgICAgIC8vICAgICAgICBpZihwcmV2Q29sLkNvbHVtbk1heCAhPSBjb2wuQ29sdW1uTWluLTEpCiAgICAgICAgICAgIC8vICAgICAgICB7CiAgICAgICAgICAgIC8vICAgICAgICAgICAgcHJldkNvbC5fY29sdW1uTWF4PWNvbC5Db2x1bW5NaW4tMTsKICAgICAgICAgICAgLy8gICAgICAgIH0KICAgICAgICAgICAgLy8gICAgfQogICAgICAgICAgICAvLyAgICBwcmV2Q29sID0gY29sOwogICAgICAgICAgICAvL30KICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF92YWx1ZXMsIDAsIDEsIDAsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgLy9zdy5Xcml0ZSgiPGNvbHM+Iik7CiAgICAgICAgICAgIC8vZm9yZWFjaCAoRXhjZWxDb2x1bW4gY29sIGluIF9jb2x1bW5zKQogICAgICAgICAgICBib29sIGZpcnN0ID0gdHJ1ZTsKICAgICAgICAgICAgd2hpbGUoY3NlLk5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGZpcnN0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8Y29scz4iKTsKICAgICAgICAgICAgICAgICAgICBmaXJzdCA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGNvbCA9IGNzZS5WYWx1ZSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgICAgIEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsWGZzPiBjZWxsWGZzID0gX3BhY2thZ2UuV29ya2Jvb2suU3R5bGVzLkNlbGxYZnM7CgogICAgICAgICAgICAgICAgc3cuV3JpdGUoIjxjb2wgbWluPVwiezB9XCIgbWF4PVwiezF9XCIiLCBjb2wuQ29sdW1uTWluLCBjb2wuQ29sdW1uTWF4KTsKICAgICAgICAgICAgICAgIGlmIChjb2wuSGlkZGVuID09IHRydWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy9zYlhtbC5BcHBlbmQoIiB3aWR0aD1cIjBcIiBoaWRkZW49XCIxXCIgY3VzdG9tV2lkdGg9XCIxXCIiKTsKICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIGhpZGRlbj1cIjFcIiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoY29sLkJlc3RGaXQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBiZXN0Rml0PVwiMVwiIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdy5Xcml0ZShzdHJpbmcuRm9ybWF0KEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUsICIgd2lkdGg9XCJ7MH1cIiBjdXN0b21XaWR0aD1cIjFcIiIsIGNvbC5XaWR0aCkpOwogICAgICAgICAgICAgICAgaWYgKGNvbC5PdXRsaW5lTGV2ZWwgPiAwKQogICAgICAgICAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBvdXRsaW5lTGV2ZWw9XCJ7MH1cIiAiLCBjb2wuT3V0bGluZUxldmVsKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY29sLkNvbGxhcHNlZCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2wuSGlkZGVuKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIGNvbGxhcHNlZD1cIjFcIiIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBjb2xsYXBzZWQ9XCIxXCIgaGlkZGVuPVwiMVwiIik7IC8vQWx3YXlzIGhpZGRlbgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGNvbC5QaG9uZXRpYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIHBob25ldGljPVwiMVwiIik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyIHN0eWxlSUQgPSBjb2wuU3R5bGVJRCA+PSAwID8gY2VsbFhmc1tjb2wuU3R5bGVJRF0ubmV3SUQgOiBjb2wuU3R5bGVJRDsKICAgICAgICAgICAgICAgIGlmIChzdHlsZUlEID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIHN0eWxlPVwiezB9XCIiLCBzdHlsZUlEKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHN3LldyaXRlKCIgLz4iKTsKCiAgICAgICAgICAgICAgICAvL2lmIChjb2wuUGFnZUJyZWFrKQogICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAvLyAgICBjb2xCcmVha3MuQWRkKGNvbC5Db2x1bW5NaW4pOwogICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFmaXJzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3cuV3JpdGUoIjwvY29scz4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEluc2VydCByb3cgYW5kIGNlbGxzIGludG8gdGhlIFhNTCBkb2N1bWVudAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHJpdmF0ZSB2b2lkIFVwZGF0ZVJvd0NlbGxEYXRhKFN0cmVhbVdyaXRlciBzdykKICAgICAgICB7CiAgICAgICAgICAgIEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsWGZzPiBjZWxsWGZzID0gX3BhY2thZ2UuV29ya2Jvb2suU3R5bGVzLkNlbGxYZnM7CiAgICAgICAgICAgIAogICAgICAgICAgICBpbnQgcm93ID0gLTE7CgogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiWG1sID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgdmFyIHNzID0gX3BhY2thZ2UuV29ya2Jvb2suX3NoYXJlZFN0cmluZ3M7CiAgICAgICAgICAgIHZhciBzdHlsZXMgPSBfcGFja2FnZS5Xb3JrYm9vay5TdHlsZXM7CiAgICAgICAgICAgIHZhciBjYWNoZSA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgIGNhY2hlLkFwcGVuZCgiPHNoZWV0RGF0YT4iKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vU2V0IGEgdmFsdWUgZm9yIGNlbGxzIHdpdGggc3R5bGUgYW5kIG5vIHZhbHVlIHNldC4KICAgICAgICAgICAgdmFyIGNzZVN0eWxlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPGludD4oX3N0eWxlcywgMCwgMCwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgZm9yZWFjaCAodmFyIHMgaW4gY3NlU3R5bGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKCFfdmFsdWVzLkV4aXN0cyhjc2VTdHlsZS5Sb3csIGNzZVN0eWxlLkNvbHVtbikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShjc2VTdHlsZS5Sb3csIGNzZVN0eWxlLkNvbHVtbiwgbnVsbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfdmFsdWVzLCAxLCAwLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAvL2ZvcmVhY2ggKElSYW5nZUlEIHIgaW4gX2NlbGxzKQogICAgICAgICAgICB3aGlsZShjc2UuTmV4dCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoY3NlLkNvbHVtbj4wKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGludCBzdHlsZUlEID0gY2VsbFhmc1tzdHlsZXMuR2V0U3R5bGVJZCh0aGlzLCBjc2UuUm93LCBjc2UuQ29sdW1uKV0ubmV3SUQ7CiAgICAgICAgICAgICAgICAgICAgLy9BZGQgdGhlIHJvdyBlbGVtZW50IGlmIGl0J3MgYSBuZXcgcm93CiAgICAgICAgICAgICAgICAgICAgaWYgKGNzZS5Sb3cgIT0gcm93KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgV3JpdGVSb3coY2FjaGUsIGNlbGxYZnMsIHJvdywgY3NlLlJvdyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJvdyA9IGNzZS5Sb3c7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG9iamVjdCB2ID0gY3NlLlZhbHVlOwogICAgICAgICAgICAgICAgICAgIG9iamVjdCBmb3JtdWxhID0gX2Zvcm11bGFzLkdldFZhbHVlKGNzZS5Sb3csIGNzZS5Db2x1bW4pOwogICAgICAgICAgICAgICAgICAgIGlmIChmb3JtdWxhIGlzIGludCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBzZklkID0gKGludClmb3JtdWxhOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZiA9IF9zaGFyZWRGb3JtdWxhc1soaW50KXNmSWRdOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZi5BZGRyZXNzLkluZGV4T2YoJzonKSA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmLlN0YXJ0Q29sID09IGNzZS5Db2x1bW4gJiYgZi5TdGFydFJvdyA9PSBjc2UuUm93KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmLklzQXJyYXkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxjIHI9XCJ7MH1cIiBzPVwiezF9XCJ7NX0+PGYgcmVmPVwiezJ9XCIgdD1cImFycmF5XCI+ezN9PC9mPns0fTwvYz4iLCBjc2UuQ2VsbEFkZHJlc3MsIHN0eWxlSUQgPCAwID8gMCA6IHN0eWxlSUQsIGYuQWRkcmVzcywgU2VjdXJpdHlFbGVtZW50LkVzY2FwZShmLkZvcm11bGEpLCBHZXRGb3JtdWxhVmFsdWUodiksIEdldENlbGxUeXBlKHYsdHJ1ZSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxjIHI9XCJ7MH1cIiBzPVwiezF9XCJ7Nn0+PGYgcmVmPVwiezJ9XCIgdD1cInNoYXJlZFwiICBzaT1cInszfVwiPns0fTwvZj57NX08L2M+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlELCBmLkFkZHJlc3MsIHNmSWQsIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoZi5Gb3JtdWxhKSwgR2V0Rm9ybXVsYVZhbHVlKHYpLCBHZXRDZWxsVHlwZSh2LHRydWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZi5Jc0FycmF5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGMgcj1cInswfVwiIHM9XCJ7MX1cIiAvPiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiezR9PjxmIHQ9XCJzaGFyZWRcIiBzaT1cInsyfVwiIC8+ezN9PC9jPiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCwgc2ZJZCwgR2V0Rm9ybXVsYVZhbHVlKHYpLCBHZXRDZWxsVHlwZSh2LHRydWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGNhbiBhbHNvIGhhdmUgYSBzaW5nbGUgY2VsbCBhcnJheSBmb3JtdWxhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihmLklzQXJyYXkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiezV9PjxmIHJlZj1cInsyfVwiIHQ9XCJhcnJheVwiPnszfTwvZj57NH08L2M+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlELCBzdHJpbmcuRm9ybWF0KCJ7MH06ezF9IiwgZi5BZGRyZXNzLCBmLkFkZHJlc3MpLCBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGYuRm9ybXVsYSksIEdldEZvcm11bGFWYWx1ZSh2KSwgR2V0Q2VsbFR5cGUodix0cnVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiPiIsIGYuQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8Zj57MH08L2Y+ezF9PC9jPiIsIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoZi5Gb3JtdWxhKSwgR2V0Rm9ybXVsYVZhbHVlKHYpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChmb3JtdWxhIT1udWxsICYmIGZvcm11bGEuVG9TdHJpbmcoKSE9IiIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxjIHI9XCJ7MH1cIiBzPVwiezF9XCJ7Mn0+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlELCBHZXRDZWxsVHlwZSh2LHRydWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8Zj57MH08L2Y+ezF9PC9jPiIsIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoZm9ybXVsYS5Ub1N0cmluZygpKSwgR2V0Rm9ybXVsYVZhbHVlKHYpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHYgPT0gbnVsbCAmJiBzdHlsZUlEID4gMCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiIC8+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlEKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKHYgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCh2LkdldFR5cGUoKS5Jc1ByaW1pdGl2ZSB8fCB2IGlzIGRvdWJsZSB8fCB2IGlzIGRlY2ltYWwgfHwgdiBpcyBEYXRlVGltZSB8fCB2IGlzIFRpbWVTcGFuKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3N0cmluZyBzdiA9IEdldFZhbHVlRm9yWG1sKHYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGMgcj1cInswfVwiIHM9XCJ7MX1cIiB7Mn0+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlELCBHZXRDZWxsVHlwZSh2KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCJ7MH08L2M+IiwgR2V0Rm9ybXVsYVZhbHVlKHYpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaXg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzcy5Db250YWluc0tleSh2LlRvU3RyaW5nKCkpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXggPSBzcy5Db3VudDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3MuQWRkKHYuVG9TdHJpbmcoKSwgbmV3IEV4Y2VsV29ya2Jvb2suU2hhcmVkU3RyaW5nSXRlbSgpIHsgaXNSaWNoVGV4dCA9IF9mbGFncy5HZXRGbGFnVmFsdWUoY3NlLlJvdyxjc2UuQ29sdW1uLENlbGxGbGFncy5SaWNoVGV4dCksIHBvcyA9IGl4IH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpeCA9IHNzW3YuVG9TdHJpbmcoKV0ucG9zOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxjIHI9XCJ7MH1cIiBzPVwiezF9XCIgdD1cInNcIj4iLCBjc2UuQ2VsbEFkZHJlc3MsIHN0eWxlSUQgPCAwID8gMCA6IHN0eWxlSUQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPHY+ezB9PC92PjwvYz4iLCBpeCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8vL1VwZGF0ZSBoeXBlcmxpbmtzLgogICAgICAgICAgICAgICAgICAgLy9pZiAoY2VsbC5IeXBlcmxpbmsgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAvLyAgICBfaHlwZXJMaW5rQ2VsbHMuQWRkKGNlbGwuQ2VsbElEKTsKICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgIC8vRXhjZWxSb3cKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvL2ludCBuZXdSb3c9KChFeGNlbFJvdyljc2UuVmFsdWUpLlJvdzsKICAgICAgICAgICAgICAgICAgICBXcml0ZVJvdyhjYWNoZSwgY2VsbFhmcywgcm93LCBjc2UuUm93KTsKICAgICAgICAgICAgICAgICAgICByb3cgPSBjc2UuUm93OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGNhY2hlLkxlbmd0aCA+IDB4NjAwMDAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKGNhY2hlLlRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgIGNhY2hlID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHJvdyAhPSAtMSkgY2FjaGUuQXBwZW5kKCI8L3Jvdz4iKTsKICAgICAgICAgICAgY2FjaGUuQXBwZW5kKCI8L3NoZWV0RGF0YT4iKTsKICAgICAgICAgICAgc3cuV3JpdGUoY2FjaGUuVG9TdHJpbmcoKSk7CiAgICAgICAgICAgIHN3LkZsdXNoKCk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIG9iamVjdCBHZXRGb3JtdWxhVmFsdWUob2JqZWN0IHYpCiAgICAgICAgewogICAgICAgICAgICAvL2lmIChfcGFja2FnZS5Xb3JrYm9vay5faXNDYWxjdWxhdGVkKQogICAgICAgICAgICAvL3sgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICBpZiAodiAhPSBudWxsICYmIHYuVG9TdHJpbmcoKSE9IiIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiPHY+IiArIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoR2V0VmFsdWVGb3JYbWwodikpICsgIjwvdj4iOyAvL0ZpeGVzIGlzc3VlIDE1MDcxCiAgICAgICAgICAgIH0gICAgICAgICAgICAKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgc3RyaW5nIEdldENlbGxUeXBlKG9iamVjdCB2LCBib29sIGFsbG93U3RyPWZhbHNlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHYgaXMgYm9vbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuICIgdD1cImJcIiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoKHYgaXMgZG91YmxlICYmIGRvdWJsZS5Jc0luZmluaXR5KChkb3VibGUpdikpIHx8IHYgaXMgRXhjZWxFcnJvclZhbHVlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiB0PVwiZVwiIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKGFsbG93U3RyICYmIHYhPW51bGwgJiYgISh2LkdldFR5cGUoKS5Jc1ByaW1pdGl2ZSB8fCB2IGlzIGRvdWJsZSB8fCB2IGlzIGRlY2ltYWwgfHwgdiBpcyBEYXRlVGltZSB8fCB2IGlzIFRpbWVTcGFuKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuICIgdD1cInN0clwiIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBzdHJpbmcgR2V0VmFsdWVGb3JYbWwob2JqZWN0IHYpCiAgICAgICAgewogICAgICAgICAgICBzdHJpbmcgczsKICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh2IGlzIERhdGVUaW1lKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRvdWJsZSBzZHYgPSAoKERhdGVUaW1lKXYpLlRvT0FEYXRlKCk7CgogICAgICAgICAgICAgICAgICAgIGlmIChXb3JrYm9vay5EYXRlMTkwNCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNkdiAtPSBFeGNlbFdvcmtib29rLmRhdGUxOTA0T2Zmc2V0OwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcyA9IHNkdi5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHYgaXMgVGltZVNwYW4pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcyA9IG5ldyBEYXRlVGltZSgoKFRpbWVTcGFuKXYpLlRpY2tzKS5Ub09BRGF0ZSgpLlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOyA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKHYuR2V0VHlwZSgpLklzUHJpbWl0aXZlIHx8IHYgaXMgZG91YmxlIHx8IHYgaXMgZGVjaW1hbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAodiBpcyBkb3VibGUgJiYgZG91YmxlLklzTmFOKChkb3VibGUpdikpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzID0gIiI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHYgaXMgZG91YmxlICYmIGRvdWJsZS5Jc0luZmluaXR5KChkb3VibGUpdikpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzID0gIiNOVU0hIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcyA9IENvbnZlcnQuVG9Eb3VibGUodiwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkuVG9TdHJpbmcoIlIxNSIsIEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzID0gdi5Ub1N0cmluZygpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBjYXRjaAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzID0gIjAiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgV3JpdGVSb3coU3RyaW5nQnVpbGRlciBjYWNoZSwgRXhjZWxTdHlsZUNvbGxlY3Rpb248RXhjZWxYZnM+IGNlbGxYZnMsIGludCBwcmV2Um93LCBpbnQgcm93KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHByZXZSb3cgIT0gLTEpIGNhY2hlLkFwcGVuZCgiPC9yb3c+Iik7CiAgICAgICAgICAgIC8vdWxvbmcgcm93SUQgPSBFeGNlbFJvdy5HZXRSb3dJRChTaGVldElELCByb3cpOwogICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxyb3cgcj1cInswfVwiICIsIHJvdyk7CiAgICAgICAgICAgIFJvd0ludGVybmFsIGN1cnJSb3cgPSBfdmFsdWVzLkdldFZhbHVlKHJvdywgMCkgYXMgUm93SW50ZXJuYWw7CiAgICAgICAgICAgIGlmIChjdXJyUm93ICE9IG51bGwpCiAgICAgICAgICAgIHsKCiAgICAgICAgICAgICAgICBpZiAoY3VyclJvdy5IaWRkZW4gPT0gdHJ1ZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoImh0PVwiMFwiIGhpZGRlbj1cIjFcIiAiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJSb3cuSGVpZ2h0ICE9IERlZmF1bHRSb3dIZWlnaHQgJiYgY3VyclJvdy5IZWlnaHQ+PTApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KHN0cmluZy5Gb3JtYXQoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSwgImh0PVwiezB9XCIgIiwgY3VyclJvdy5IZWlnaHQpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY3VyclJvdy5DdXN0b21IZWlnaHQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoImN1c3RvbUhlaWdodD1cIjFcIiAiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuT3V0bGluZUxldmVsID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIm91dGxpbmVMZXZlbCA9XCJ7MH1cIiAiLCBjdXJyUm93Lk91dGxpbmVMZXZlbCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuQ29sbGFwc2VkKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuSGlkZGVuKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoIiBjb2xsYXBzZWQ9XCIxXCIgIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoIiBjb2xsYXBzZWQ9XCIxXCIgaGlkZGVuPVwiMVwiICIpOyAvL0Fsd2F5cyBoaWRkZW4KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LlBob25ldGljKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZCgicGg9XCIxXCIgIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHMgPSBfc3R5bGVzLkdldFZhbHVlKHJvdywgMCk7CiAgICAgICAgICAgIGlmIChzID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCJzPVwiezB9XCIgY3VzdG9tRm9ybWF0PVwiMVwiIiwgY2VsbFhmc1tzXS5uZXdJRCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FjaGUuQXBwZW5kKCI+Iik7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBXcml0ZVJvdyhTdHJlYW1Xcml0ZXIgc3csIEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsWGZzPiBjZWxsWGZzLCBpbnQgcHJldlJvdywgaW50IHJvdykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwcmV2Um93ICE9IC0xKSBzdy5Xcml0ZSgiPC9yb3c+Iik7CiAgICAgICAgICAgIC8vdWxvbmcgcm93SUQgPSBFeGNlbFJvdy5HZXRSb3dJRChTaGVldElELCByb3cpOwogICAgICAgICAgICBzdy5Xcml0ZSgiPHJvdyByPVwiezB9XCIgIiwgcm93KTsKICAgICAgICAgICAgUm93SW50ZXJuYWwgY3VyclJvdyA9IF92YWx1ZXMuR2V0VmFsdWUocm93LCAwKSBhcyBSb3dJbnRlcm5hbDsKICAgICAgICAgICAgaWYgKGN1cnJSb3chPW51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuSGlkZGVuID09IHRydWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoImh0PVwiMFwiIGhpZGRlbj1cIjFcIiAiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJSb3cuSGVpZ2h0ICE9IERlZmF1bHRSb3dIZWlnaHQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoc3RyaW5nLkZvcm1hdChDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlLCAiaHQ9XCJ7MH1cIiAiLCBjdXJyUm93LkhlaWdodCkpOwogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LkN1c3RvbUhlaWdodCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCJjdXN0b21IZWlnaHQ9XCIxXCIgIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChjdXJyUm93Lk91dGxpbmVMZXZlbCA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIm91dGxpbmVMZXZlbCA9XCJ7MH1cIiAiLCBjdXJyUm93Lk91dGxpbmVMZXZlbCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuQ29sbGFwc2VkKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuSGlkZGVuKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIGNvbGxhcHNlZD1cIjFcIiAiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCIgY29sbGFwc2VkPVwiMVwiIGhpZGRlbj1cIjFcIiAiKTsgLy9BbHdheXMgaGlkZGVuCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoY3VyclJvdy5QaG9uZXRpYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgicGg9XCIxXCIgIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHMgPSBfc3R5bGVzLkdldFZhbHVlKHJvdywgMCk7CiAgICAgICAgICAgIGlmIChzID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3cuV3JpdGUoInM9XCJ7MH1cIiBjdXN0b21Gb3JtYXQ9XCIxXCIiLCBjZWxsWGZzW3NdLm5ld0lEKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdy5Xcml0ZSgiPiIpOwogICAgICAgIH0KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBVcGRhdGUgeG1sIHdpdGggaHlwZXJsaW5rcyAKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic3ciPlRoZSBzdHJlYW08L3BhcmFtPgogICAgICAgIHByaXZhdGUgdm9pZCBVcGRhdGVIeXBlckxpbmtzKFN0cmVhbVdyaXRlciBzdykKICAgICAgICB7CiAgICAgICAgICAgICAgICBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPiBoeXBzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc+KCk7CiAgICAgICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPFVyaT4oX2h5cGVyTGlua3MpOwogICAgICAgICAgICAgICAgYm9vbCBmaXJzdCA9IHRydWU7CiAgICAgICAgICAgICAgICAvL2ZvcmVhY2ggKHVsb25nIGNlbGwgaW4gX2h5cGVyTGlua3MpCiAgICAgICAgICAgICAgICB3aGlsZShjc2UuTmV4dCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8aHlwZXJsaW5rcz4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy9pbnQgcm93LCBjb2w7CiAgICAgICAgICAgICAgICAgICAgdmFyIHVyaSA9IF9oeXBlckxpbmtzLkdldFZhbHVlKGNzZS5Sb3csIGNzZS5Db2x1bW4pOwogICAgICAgICAgICAgICAgICAgIC8vRXhjZWxDZWxsIGNlbGwgPSBfY2VsbHNbY2VsbElkXSBhcyBFeGNlbENlbGw7CiAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSBpcyBFeGNlbEh5cGVyTGluayAmJiAhc3RyaW5nLklzTnVsbE9yRW1wdHkoKHVyaSBhcyBFeGNlbEh5cGVyTGluaykuUmVmZXJlbmNlQWRkcmVzcykpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBFeGNlbEh5cGVyTGluayBobCA9IHVyaSBhcyBFeGNlbEh5cGVyTGluazsKICAgICAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIjxoeXBlcmxpbmsgcmVmPVwiezB9XCIgbG9jYXRpb249XCJ7MX1cIiB7Mn17M30vPiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2VsbHNbY3NlLlJvdywgY3NlLkNvbHVtbiwgY3NlLlJvdyArIGhsLlJvd1NwYW5uLCBjc2UuQ29sdW1uICsgaGwuQ29sU3Bhbm5dLkFkZHJlc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VsQ2VsbEJhc2UuR2V0RnVsbEFkZHJlc3MoU2VjdXJpdHlFbGVtZW50LkVzY2FwZShOYW1lKSwgU2VjdXJpdHlFbGVtZW50LkVzY2FwZShobC5SZWZlcmVuY2VBZGRyZXNzKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZy5Jc051bGxPckVtcHR5KGhsLkRpc3BsYXkpID8gIiIgOiAiZGlzcGxheT1cIiIgKyBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGhsLkRpc3BsYXkpICsgIlwiICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZy5Jc051bGxPckVtcHR5KGhsLlRvb2xUaXApID8gIiIgOiAidG9vbHRpcD1cIiIgKyBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGhsLlRvb2xUaXApICsgIlwiICIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKCB1cmkhPW51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgaWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIFVyaSBoeXA7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1cmkgaXMgRXhjZWxIeXBlckxpbmspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5cCA9ICgoRXhjZWxIeXBlckxpbmspdXJpKS5PcmlnaW5hbFVyaTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5cCA9IHVyaTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaHlwcy5Db250YWluc0tleShoeXAuT3JpZ2luYWxTdHJpbmcpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZCA9IGh5cHNbaHlwLk9yaWdpbmFsU3RyaW5nXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWxhdGlvbnNoaXAgPSBQYXJ0LkNyZWF0ZVJlbGF0aW9uc2hpcChoeXAsIFBhY2thZ2luZy5UYXJnZXRNb2RlLkV4dGVybmFsLCBFeGNlbFBhY2thZ2Uuc2NoZW1hSHlwZXJsaW5rKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1cmkgaXMgRXhjZWxIeXBlckxpbmspCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxIeXBlckxpbmsgaGwgPSB1cmkgYXMgRXhjZWxIeXBlckxpbms7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIjxoeXBlcmxpbmsgcmVmPVwiezB9XCIgezJ9ezN9cjppZD1cInsxfVwiIC8+IiwgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGNzZS5Sb3csIGNzZS5Db2x1bW4pLCByZWxhdGlvbnNoaXAuSWQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nLklzTnVsbE9yRW1wdHkoaGwuRGlzcGxheSkgPyAiIiA6ICJkaXNwbGF5PVwiIiArIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoaGwuRGlzcGxheSkgKyAiXCIgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nLklzTnVsbE9yRW1wdHkoaGwuVG9vbFRpcCkgPyAiIiA6ICJ0b29sdGlwPVwiIiArIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoaGwuVG9vbFRpcCkgKyAiXCIgIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIjxoeXBlcmxpbmsgcmVmPVwiezB9XCIgcjppZD1cInsxfVwiIC8+IiwgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGNzZS5Sb3csIGNzZS5Db2x1bW4pLCByZWxhdGlvbnNoaXAuSWQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQgPSByZWxhdGlvbnNoaXAuSWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLy9jZWxsLkh5cGVyTGlua1JJZCA9IGlkOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghZmlyc3QpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIjwvaHlwZXJsaW5rcz4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBDcmVhdGUgdGhlIGh5cGVybGlua3Mgbm9kZSBpbiB0aGUgWE1MCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPgogICAgICAgIHByaXZhdGUgWG1sTm9kZSBDcmVhdGVIeXBlckxpbmtDb2xsZWN0aW9uKCkKICAgICAgICB7CiAgICAgICAgICAgIFhtbEVsZW1lbnQgaGw9X3dvcmtzaGVldFhtbC5DcmVhdGVFbGVtZW50KCJoeXBlcmxpbmtzIixFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CiAgICAgICAgICAgIFhtbE5vZGUgcHJldk5vZGUgPSBfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpjb25kaXRpb25hbEZvcm1hdHRpbmciLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgaWYgKHByZXZOb2RlID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHByZXZOb2RlID0gX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6bWVyZ2VDZWxscyIsIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICAgICAgaWYgKHByZXZOb2RlID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcHJldk5vZGUgPSBfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpzaGVldERhdGEiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gX3dvcmtzaGVldFhtbC5Eb2N1bWVudEVsZW1lbnQuSW5zZXJ0QWZ0ZXIoaGwsIHByZXZOb2RlKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBEaW1lbnNpb24gYWRkcmVzcyBmb3IgdGhlIHdvcmtzaGVldC4gCiAgICAgICAgLy8vIFRvcCBsZWZ0IGNlbGwgdG8gQm90dG9tIHJpZ2h0LgogICAgICAgIC8vLyBJZiB0aGUgd29ya3NoZWV0IGhhcyBubyBjZWxscywgbnVsbCBpcyByZXR1cm5lZAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsQWRkcmVzc0Jhc2UgRGltZW5zaW9uCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIGludCBmcm9tUm93LCBmcm9tQ29sLCB0b1JvdywgdG9Db2w7CiAgICAgICAgICAgICAgICBpZiAoX3ZhbHVlcy5HZXREaW1lbnNpb24ob3V0IGZyb21Sb3csIG91dCBmcm9tQ29sLCBvdXQgdG9Sb3csIG91dCB0b0NvbCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGFkZHIgPSBuZXcgRXhjZWxBZGRyZXNzQmFzZShmcm9tUm93LCBmcm9tQ29sLCB0b1JvdywgdG9Db2wpOwogICAgICAgICAgICAgICAgICAgIGFkZHIuX3dzID0gTmFtZTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWRkcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBFeGNlbFNoZWV0UHJvdGVjdGlvbiBfcHJvdGVjdGlvbj1udWxsOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQWNjZXNzIHRvIHNoZWV0IHByb3RlY3Rpb24gcHJvcGVydGllcwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsU2hlZXRQcm90ZWN0aW9uIFByb3RlY3Rpb24KICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX3Byb3RlY3Rpb24gPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfcHJvdGVjdGlvbiA9IG5ldyBFeGNlbFNoZWV0UHJvdGVjdGlvbihOYW1lU3BhY2VNYW5hZ2VyLCBUb3BOb2RlLCB0aGlzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfcHJvdGVjdGlvbjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBFeGNlbFByb3RlY3RlZFJhbmdlQ29sbGVjdGlvbiBfcHJvdGVjdGVkUmFuZ2VzOwogICAgICAgIHB1YmxpYyBFeGNlbFByb3RlY3RlZFJhbmdlQ29sbGVjdGlvbiBQcm90ZWN0ZWRSYW5nZXMKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX3Byb3RlY3RlZFJhbmdlcyA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIF9wcm90ZWN0ZWRSYW5nZXMgPSBuZXcgRXhjZWxQcm90ZWN0ZWRSYW5nZUNvbGxlY3Rpb24oTmFtZVNwYWNlTWFuYWdlciwgVG9wTm9kZSwgdGhpcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gX3Byb3RlY3RlZFJhbmdlczsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgI3JlZ2lvbiBEcmF3aW5nCiAgICAgICAgRXhjZWxEcmF3aW5ncyBfZHJhd2luZ3MgPSBudWxsOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ29sbGVjdGlvbiBvZiBkcmF3aW5nLW9iamVjdHMgbGlrZSBzaGFwZXMsIGltYWdlcyBhbmQgY2hhcnRzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxEcmF3aW5ncyBEcmF3aW5ncwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfZHJhd2luZ3MgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfZHJhd2luZ3MgPSBuZXcgRXhjZWxEcmF3aW5ncyhfcGFja2FnZSwgdGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX2RyYXdpbmdzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICNlbmRyZWdpb24KICAgICAgICBFeGNlbFRhYmxlQ29sbGVjdGlvbiBfdGFibGVzID0gbnVsbDsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRhYmxlcyBkZWZpbmVkIGluIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxUYWJsZUNvbGxlY3Rpb24gVGFibGVzCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIGlmIChXb3JrYm9vay5fbmV4dFRhYmxlSUQgPT0gaW50Lk1pblZhbHVlKSBXb3JrYm9vay5SZWFkQWxsVGFibGVzKCk7CiAgICAgICAgICAgICAgICBpZiAoX3RhYmxlcyA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF90YWJsZXMgPSBuZXcgRXhjZWxUYWJsZUNvbGxlY3Rpb24odGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX3RhYmxlczsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBFeGNlbFBpdm90VGFibGVDb2xsZWN0aW9uIF9waXZvdFRhYmxlcyA9IG51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBQaXZvdHRhYmxlcyBkZWZpbmVkIGluIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxQaXZvdFRhYmxlQ29sbGVjdGlvbiBQaXZvdFRhYmxlcwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBpZiAoX3Bpdm90VGFibGVzID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKFdvcmtib29rLl9uZXh0UGl2b3RUYWJsZUlEID09IGludC5NaW5WYWx1ZSkgV29ya2Jvb2suUmVhZEFsbFRhYmxlcygpOwogICAgICAgICAgICAgICAgICAgIF9waXZvdFRhYmxlcyA9IG5ldyBFeGNlbFBpdm90VGFibGVDb2xsZWN0aW9uKHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF9waXZvdFRhYmxlczsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcml2YXRlIEV4Y2VsQ29uZGl0aW9uYWxGb3JtYXR0aW5nQ29sbGVjdGlvbiBfY29uZGl0aW9uYWxGb3JtYXR0aW5nID0gbnVsbDsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIENvbmRpdGlvbmFsRm9ybWF0dGluZyBkZWZpbmVkIGluIHRoZSB3b3Jrc2hlZXQuIFVzZSB0aGUgQWRkIG1ldGhvZHMgdG8gY3JlYXRlIENvbmRpdGlvbmFsRm9ybWF0dGluZyBhbmQgYWRkIHRoZW0gdG8gdGhlIHdvcmtzaGVldC4gVGhlbgogICAgICAgIC8vLyBzZXQgdGhlIHByb3BlcnRpZXMgb24gdGhlIGluc3RhbmNlIHJldHVybmVkLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxzZWVhbHNvIGNyZWY9IkV4Y2VsQ29uZGl0aW9uYWxGb3JtYXR0aW5nQ29sbGVjdGlvbiIvPgogICAgICAgIHB1YmxpYyBFeGNlbENvbmRpdGlvbmFsRm9ybWF0dGluZ0NvbGxlY3Rpb24gQ29uZGl0aW9uYWxGb3JtYXR0aW5nCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIGlmIChfY29uZGl0aW9uYWxGb3JtYXR0aW5nID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX2NvbmRpdGlvbmFsRm9ybWF0dGluZyA9IG5ldyBFeGNlbENvbmRpdGlvbmFsRm9ybWF0dGluZ0NvbGxlY3Rpb24odGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbmRpdGlvbmFsRm9ybWF0dGluZzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcml2YXRlIEV4Y2VsRGF0YVZhbGlkYXRpb25Db2xsZWN0aW9uIF9kYXRhVmFsaWRhdGlvbiA9IG51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBEYXRhVmFsaWRhdGlvbiBkZWZpbmVkIGluIHRoZSB3b3Jrc2hlZXQuIFVzZSB0aGUgQWRkIG1ldGhvZHMgdG8gY3JlYXRlIERhdGFWYWxpZGF0aW9ucyBhbmQgYWRkIHRoZW0gdG8gdGhlIHdvcmtzaGVldC4gVGhlbgogICAgICAgIC8vLyBzZXQgdGhlIHByb3BlcnRpZXMgb24gdGhlIGluc3RhbmNlIHJldHVybmVkLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxzZWVhbHNvIGNyZWY9IkV4Y2VsRGF0YVZhbGlkYXRpb25Db2xsZWN0aW9uIi8+CiAgICAgICAgcHVibGljIEV4Y2VsRGF0YVZhbGlkYXRpb25Db2xsZWN0aW9uIERhdGFWYWxpZGF0aW9ucwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBpZiAoX2RhdGFWYWxpZGF0aW9uID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX2RhdGFWYWxpZGF0aW9uID0gbmV3IEV4Y2VsRGF0YVZhbGlkYXRpb25Db2xsZWN0aW9uKHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF9kYXRhVmFsaWRhdGlvbjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBFeGNlbEJhY2tncm91bmRJbWFnZSBfYmFja2dyb3VuZEltYWdlID0gbnVsbDsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEFuIGltYWdlIGRpc3BsYXllZCBhcyB0aGUgYmFja2dyb3VuZCBvZiB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsQmFja2dyb3VuZEltYWdlIEJhY2tncm91bmRJbWFnZQogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfYmFja2dyb3VuZEltYWdlID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX2JhY2tncm91bmRJbWFnZSA9IG5ldyBFeGNlbEJhY2tncm91bmRJbWFnZShOYW1lU3BhY2VNYW5hZ2VyLCBUb3BOb2RlLCB0aGlzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfYmFja2dyb3VuZEltYWdlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KCQkvLy8gUmV0dXJucyB0aGUgc3R5bGUgSUQgZ2l2ZW4gYSBzdHlsZSBuYW1lLiAgCgkJLy8vIFRoZSBzdHlsZSBJRCB3aWxsIGJlIGNyZWF0ZWQgaWYgbm90IGZvdW5kLCBidXQgb25seSBpZiB0aGUgc3R5bGUgbmFtZSBleGlzdHMhCgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9IlN0eWxlTmFtZSI+PC9wYXJhbT4KCQkvLy8gPHJldHVybnM+PC9yZXR1cm5zPgoJCWludGVybmFsIGludCBHZXRTdHlsZUlEKHN0cmluZyBTdHlsZU5hbWUpCgkJewoJCQlFeGNlbE5hbWVkU3R5bGVYbWwgbmFtZWRTdHlsZT1udWxsOwogICAgICAgICAgICBXb3JrYm9vay5TdHlsZXMuTmFtZWRTdHlsZXMuRmluZEJ5SUQoU3R5bGVOYW1lLCByZWYgbmFtZWRTdHlsZSk7CiAgICAgICAgICAgIGlmIChuYW1lZFN0eWxlLlhmSWQgPT0gaW50Lk1pblZhbHVlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBuYW1lZFN0eWxlLlhmSWQ9V29ya2Jvb2suU3R5bGVzLkNlbGxYZnMuRmluZEluZGV4QnlJRChuYW1lZFN0eWxlLlN0eWxlLklkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmFtZWRTdHlsZS5YZklkOwoJCX0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSB3b3JrYm9vayBvYmplY3QKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBFeGNlbFdvcmtib29rIFdvcmtib29rCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIF9wYWNrYWdlLldvcmtib29rOwogICAgICAgICAgICB9CiAgICAgICAgfQoJCSNlbmRyZWdpb24KICAgICAgICAjZW5kcmVnaW9uICAvLyBFTkQgV29ya3NoZWV0IFByaXZhdGUgTWV0aG9kcwoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldCB0aGUgbmV4dCBJRCBmcm9tIGEgc2hhcmVkIGZvcm11bGEgb3IgYW4gQXJyYXkgZm9ybXVsYQogICAgICAgIC8vLyBTaGFyZWRmb3J1bWxhcyB3aWxsIGhhdmUgYW4gaWQgZnJvbSAwLXguIEFycmF5IGZvcm11bGEgaWRzIHN0YXJ0IGZyb20gMHg0MDAwMDAxLS4gCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImlzQXJyYXkiPklmIHRoZSBmb3JtdWxhIGlzIGFuIGFycmF5IGZvcm11bGE8L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+CiAgICAgICAgaW50ZXJuYWwgaW50IEdldE1heFNoYXJlRnVuY3Rpb25JbmRleChib29sIGlzQXJyYXkpCiAgICAgICAgewogICAgICAgICAgICBpbnQgaT1fc2hhcmVkRm9ybXVsYXMuQ291bnQgKyAxOwogICAgICAgICAgICBpZiAoaXNBcnJheSkKICAgICAgICAgICAgICAgIGkgfD0gMHg0MDAwMDAwMDsKCiAgICAgICAgICAgIHdoaWxlKF9zaGFyZWRGb3JtdWxhcy5Db250YWluc0tleShpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaSsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgIH0KICAgICAgICBpbnRlcm5hbCB2b2lkIFNldEhGTGVnYWN5RHJhd2luZ1JlbChzdHJpbmcgcmVsSUQpCiAgICAgICAgewogICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJkOmxlZ2FjeURyYXdpbmdIRi9AcjppZCIsIHJlbElEKTsKICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBSZW1vdmVMZWdhY3lEcmF3aW5nUmVsKHN0cmluZyByZWxJRCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBuID0gV29ya3NoZWV0WG1sLkRvY3VtZW50RWxlbWVudC5TZWxlY3RTaW5nbGVOb2RlKHN0cmluZy5Gb3JtYXQoImQ6bGVnYWN5RHJhd2luZ1tAcjppZD1cInswfVwiXSIsIHJlbElEKSwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgIGlmIChuICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG4uUGFyZW50Tm9kZS5SZW1vdmVDaGlsZChuKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50ZXJuYWwgdm9pZCBVcGRhdGVDZWxsc1dpdGhEYXRlMTkwNFNldHRpbmcoKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF92YWx1ZXMpOwogICAgICAgICAgICB2YXIgb2Zmc2V0ID0gV29ya2Jvb2suRGF0ZTE5MDQgPyAtRXhjZWxXb3JrYm9vay5kYXRlMTkwNE9mZnNldCA6IEV4Y2VsV29ya2Jvb2suZGF0ZTE5MDRPZmZzZXQ7CiAgICAgICAgICAgIHdoaWxlKGNzZS5Nb3ZlTmV4dCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoY3NlLlZhbHVlIGlzIERhdGVUaW1lKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRyeQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIHNkdiA9ICgoRGF0ZVRpbWUpY3NlLlZhbHVlKS5Ub09BRGF0ZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBzZHYgKz0gb2Zmc2V0OwoKICAgICAgICAgICAgICAgICAgICAgICAgY3NlLlZhbHVlID0gRGF0ZVRpbWUuRnJvbU9BRGF0ZShzZHYpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXRjaAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgc3RyaW5nIEdldEZvcm11bGEoaW50IHJvdywgaW50IGNvbCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciB2ID0gX2Zvcm11bGFzLkdldFZhbHVlKHJvdywgY29sKTsKICAgICAgICAgICAgaWYgKHYgaXMgaW50KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3NoYXJlZEZvcm11bGFzWyhpbnQpdl0uR2V0Rm9ybXVsYShyb3csY29sLCBOYW1lKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh2ICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB2LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgc3RyaW5nIEdldEZvcm11bGFSMUMxKGludCByb3csIGludCBjb2wpCiAgICAgICAgewogICAgICAgICAgICB2YXIgdiA9IF9mb3JtdWxhcy5HZXRWYWx1ZShyb3csIGNvbCk7CiAgICAgICAgICAgIGlmICh2IGlzIGludCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIHNmID0gX3NoYXJlZEZvcm11bGFzWyhpbnQpdl07CiAgICAgICAgICAgICAgICByZXR1cm4gRXhjZWxDZWxsQmFzZS5UcmFuc2xhdGVUb1IxQzEoRm9ybXVsYXMuUmVtb3ZlRHVtbXlGdW5jdGlvbihzZi5Gb3JtdWxhKSwgc2YuU3RhcnRSb3csIHNmLlN0YXJ0Q29sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh2ICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBFeGNlbENlbGxCYXNlLlRyYW5zbGF0ZVRvUjFDMShGb3JtdWxhcy5SZW1vdmVEdW1teUZ1bmN0aW9uKHYuVG9TdHJpbmcoKSksIHJvdywgY29sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50ZXJuYWwgc3RyaW5nIEdldEZvcm11bGFSMUMxX1YxKGludCByb3csIGludCBjb2wpCiAgICAgICAgewogICAgICAgICAgICB2YXIgdiA9IF9mb3JtdWxhcy5HZXRWYWx1ZShyb3csIGNvbCk7CiAgICAgICAgICAgIGlmICh2IGlzIGludCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIHNmID0gX3NoYXJlZEZvcm11bGFzWyhpbnQpdl07CiAgICAgICAgICAgICAgICByZXR1cm4gRXhjZWxDZWxsQmFzZS5UcmFuc2xhdGVUb1IxQzFfVjEoRm9ybXVsYXMuUmVtb3ZlRHVtbXlGdW5jdGlvbihzZi5Gb3JtdWxhKSwgc2YuU3RhcnRSb3csIHNmLlN0YXJ0Q29sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh2ICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBFeGNlbENlbGxCYXNlLlRyYW5zbGF0ZVRvUjFDMV9WMShGb3JtdWxhcy5SZW1vdmVEdW1teUZ1bmN0aW9uKHYuVG9TdHJpbmcoKSksIHJvdywgY29sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50ZXJuYWwgc3RyaW5nIEdldEFycmF5Rm9ybXVsYUFkZHJlc3MoaW50IHJvdywgaW50IGNvbCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciB2ID0gX2Zvcm11bGFzLkdldFZhbHVlKHJvdywgY29sKTsKICAgICAgICAgICAgaWYgKCh2IGlzIGludCkgJiYgKF9zaGFyZWRGb3JtdWxhc1soaW50KXZdLklzQXJyYXkpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3NoYXJlZEZvcm11bGFzWyhpbnQpdl0uQWRkcmVzczsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIERpc3Bvc2VJbnRlcm5hbChJRGlzcG9zYWJsZSBjYW5kaWRhdGVEaXNwb3NhYmxlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZURpc3Bvc2FibGUgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FuZGlkYXRlRGlzcG9zYWJsZS5EaXNwb3NlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoKICAgICAgICBwdWJsaWMgdm9pZCBEaXNwb3NlKCkKICAgICAgICB7CiAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfdmFsdWVzKTsKICAgICAgICAgICAgRGlzcG9zZUludGVybmFsKF9mb3JtdWxhcyk7CiAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfZmxhZ3MpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX2h5cGVyTGlua3MpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX3N0eWxlcyk7CiAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfdHlwZXMpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX2NvbW1lbnRzU3RvcmUpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX2Zvcm11bGFUb2tlbnMpOwoKICAgICAgICAgICAgX3ZhbHVlcyA9IG51bGw7CiAgICAgICAgICAgIF9mb3JtdWxhcyA9IG51bGw7CiAgICAgICAgICAgIF9mbGFncyA9IG51bGw7CiAgICAgICAgICAgIF9oeXBlckxpbmtzID0gbnVsbDsKICAgICAgICAgICAgX3N0eWxlcyA9IG51bGw7CiAgICAgICAgICAgIF90eXBlcyA9IG51bGw7CiAgICAgICAgICAgIF9jb21tZW50c1N0b3JlID0gbnVsbDsKICAgICAgICAgICAgX2Zvcm11bGFUb2tlbnMgPSBudWxsOwoKICAgICAgICAgICAgX3BhY2thZ2UgPSBudWxsOwogICAgICAgICAgICBfcGl2b3RUYWJsZXMgPSBudWxsOwogICAgICAgICAgICBfcHJvdGVjdGlvbiA9IG51bGw7CiAgICAgICAgICAgIGlmKF9zaGFyZWRGb3JtdWxhcyAhPSBudWxsKSBfc2hhcmVkRm9ybXVsYXMuQ2xlYXIoKTsKICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzID0gbnVsbDsKICAgICAgICAgICAgX3NoZWV0VmlldyA9IG51bGw7CiAgICAgICAgICAgIF90YWJsZXMgPSBudWxsOwogICAgICAgICAgICBfdm1sRHJhd2luZ3MgPSBudWxsOwogICAgICAgICAgICBfY29uZGl0aW9uYWxGb3JtYXR0aW5nID0gbnVsbDsKICAgICAgICAgICAgX2RhdGFWYWxpZGF0aW9uID0gbnVsbDsKICAgICAgICAgICAgX2RyYXdpbmdzID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0IHRoZSBFeGNlbENvbHVtbiBmb3IgY29sdW1uIChzcGFuIENvbHVtbk1pbiBhbmQgQ29sdW1uTWF4KQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW4iPjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBpbnRlcm5hbCBFeGNlbENvbHVtbiBHZXRDb2x1bW4oaW50IGNvbHVtbikKICAgICAgICB7CiAgICAgICAgICAgIHZhciBjID0gX3ZhbHVlcy5HZXRWYWx1ZSgwLCBjb2x1bW4pIGFzIEV4Y2VsQ29sdW1uOwogICAgICAgICAgICBpZiAoYyA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgcm93ID0gMCwgY29sID0gY29sdW1uOwogICAgICAgICAgICAgICAgaWYgKF92YWx1ZXMuUHJldkNlbGwocmVmIHJvdywgcmVmIGNvbCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYyA9IF92YWx1ZXMuR2V0VmFsdWUoMCwgY29sKSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgICAgICAgICBpZiAoYyAhPSBudWxsICYmIGMuQ29sdW1uTWF4ID49IGNvbHVtbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYzsKCiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbCBFcXVhbHMoRXhjZWxXb3Jrc2hlZXQgeCwgRXhjZWxXb3Jrc2hlZXQgeSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB4Lk5hbWUgPT0geS5OYW1lICYmIHguU2hlZXRJRCA9PSB5LlNoZWV0SUQgJiYgeC5Xb3Jrc2hlZXRYbWwuT3V0ZXJYbWwgPT0geS5Xb3Jrc2hlZXRYbWwuT3V0ZXJYbWw7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgaW50IEdldEhhc2hDb2RlKEV4Y2VsV29ya3NoZWV0IG9iaikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBvYmouV29ya3NoZWV0WG1sLk91dGVyWG1sLkdldEhhc2hDb2RlKCk7CiAgICAgICAgfQoJfSAgLy8gRU5EIGNsYXNzIFdvcmtzaGVldAp9Cg==