IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMgLSotIGNvZGluZzogaXNvLTg4NTktMSAtKi0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlLnB5CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ29weXJpZ2h0IChDKSAyMDAyIExhcnMgR3VzdORiZWwgPGxhcnNAZ3VzdGFlYmVsLmRlPgojIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMKIyBQZXJtaXNzaW9uICBpcyAgaGVyZWJ5IGdyYW50ZWQsICBmcmVlICBvZiBjaGFyZ2UsICB0byAgYW55IHBlcnNvbgojIG9idGFpbmluZyBhICBjb3B5IG9mICB0aGlzIHNvZnR3YXJlICBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uCiMgZmlsZXMgICh0aGUgICJTb2Z0d2FyZSIpLCAgdG8gICBkZWFsICBpbiAgdGhlICBTb2Z0d2FyZSAgIHdpdGhvdXQKIyByZXN0cmljdGlvbiwgIGluY2x1ZGluZyAgd2l0aG91dCBsaW1pdGF0aW9uICB0aGUgIHJpZ2h0cyB0byAgdXNlLAojIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiMgY29waWVzICBvZiAgdGhlICBTb2Z0d2FyZSwgIGFuZCB0byAgcGVybWl0ICBwZXJzb25zICB0byAgd2hvbSB0aGUKIyBTb2Z0d2FyZSAgaXMgIGZ1cm5pc2hlZCAgdG8gIGRvICBzbywgIHN1YmplY3QgIHRvICB0aGUgIGZvbGxvd2luZwojIGNvbmRpdGlvbnM6CiMKIyBUaGUgYWJvdmUgY29weXJpZ2h0ICBub3RpY2UgYW5kIHRoaXMgIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsICBiZQojIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgojCiMgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyAgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSAgS0lORCwKIyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyAgQlVUIE5PVCBMSU1JVEVEIFRPICBUSEUgV0FSUkFOVElFUwojIE9GICBNRVJDSEFOVEFCSUxJVFksICBGSVRORVNTICAgRk9SICBBICBQQVJUSUNVTEFSICAgUFVSUE9TRSAgQU5ECiMgTk9OSU5GUklOR0VNRU5ULiAgSU4gIE5PICBFVkVOVCBTSEFMTCAgVEhFICBBVVRIT1JTICBPUiBDT1BZUklHSFQKIyBIT0xERVJTICBCRSBMSUFCTEUgIEZPUiBBTlkgIENMQUlNLCBEQU1BR0VTICBPUiBPVEhFUiAgTElBQklMSVRZLAojIFdIRVRIRVIgIElOIEFOICBBQ1RJT04gT0YgIENPTlRSQUNULCBUT1JUICBPUiBPVEhFUldJU0UsICBBUklTSU5HCiMgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUgojIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KIwoiIiJSZWFkIGZyb20gYW5kIHdyaXRlIHRvIHRhciBmb3JtYXQgYXJjaGl2ZXMuCiIiIgoKX192ZXJzaW9uX18gPSAiJFJldmlzaW9uJCIKIyAkU291cmNlJAoKdmVyc2lvbiAgICAgPSAiMC42LjQiCl9fYXV0aG9yX18gID0gIkxhcnMgR3VzdORiZWwgKGxhcnNAZ3VzdGFlYmVsLmRlKSIKX19kYXRlX18gICAgPSAiJERhdGUkIgpfX2N2c2lkX18gICA9ICIkSWQkIgpfX2NyZWRpdHNfXyA9ICJHdXN0YXZvIE5pZW1leWVyLCBOaWVscyBHdXN05GJlbCwgUmljaGFyZCBUb3duc2VuZC4iCgojLS0tLS0tLS0tCiMgSW1wb3J0cwojLS0tLS0tLS0tCmltcG9ydCBzeXMKaW1wb3J0IG9zCmltcG9ydCBzaHV0aWwKaW1wb3J0IHN0YXQKaW1wb3J0IGVycm5vCmltcG9ydCB0aW1lCmltcG9ydCBzdHJ1Y3QKCmlmIHN5cy5wbGF0Zm9ybSA9PSAnbWFjJzoKICAgICMgVGhpcyBtb2R1bGUgbmVlZHMgd29yayBmb3IgTWFjT1M5LCBlc3BlY2lhbGx5IGluIHRoZSBhcmVhIG9mIHBhdGhuYW1lCiAgICAjIGhhbmRsaW5nLiBJbiBtYW55IHBsYWNlcyBpdCBpcyBhc3N1bWVkIGEgc2ltcGxlIHN1YnN0aXR1dGlvbiBvZiAvIGJ5IHRoZQogICAgIyBsb2NhbCBvcy5wYXRoLnNlcCBpcyBnb29kIGVub3VnaCB0byBjb252ZXJ0IHBhdGhuYW1lcywgYnV0IHRoaXMgZG9lcyBub3QKICAgICMgd29yayB3aXRoIHRoZSBtYWMgcm9vdGVkOnBhdGg6bmFtZSB2ZXJzdXMgOm5vbnJvb3RlZDpwYXRoOm5hbWUgc3ludGF4CiAgICByYWlzZSBJbXBvcnRFcnJvciwgInRhcmZpbGUgZG9lcyBub3Qgd29yayBmb3IgcGxhdGZvcm09PW1hYyIKCnRyeToKICAgIGltcG9ydCBncnAsIHB3ZApleGNlcHQgSW1wb3J0RXJyb3I6CiAgICBncnAgPSBwd2QgPSBOb25lCgojIGZyb20gdGFyZmlsZSBpbXBvcnQgKgpfX2FsbF9fID0gWyJUYXJGaWxlIiwgIlRhckluZm8iLCAiaXNfdGFyZmlsZSIsICJUYXJFcnJvciJdCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgdGFyIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk5VTCAgICAgICAgPSAiXDAiICAgICAgICAgICAgICAgIyB0aGUgbnVsbCBjaGFyYWN0ZXIKQkxPQ0tTSVpFICA9IDUxMiAgICAgICAgICAgICAgICAjIGxlbmd0aCBvZiBwcm9jZXNzaW5nIGJsb2NrcwpSRUNPUkRTSVpFID0gQkxPQ0tTSVpFICogMjAgICAgICMgbGVuZ3RoIG9mIHJlY29yZHMKTUFHSUMgICAgICA9ICJ1c3RhciIgICAgICAgICAgICAjIG1hZ2ljIHRhciBzdHJpbmcKVkVSU0lPTiAgICA9ICIwMCIgICAgICAgICAgICAgICAjIHZlcnNpb24gbnVtYmVyCgpMRU5HVEhfTkFNRSAgICA9IDEwMCAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBmaWxlbmFtZQpMRU5HVEhfTElOSyAgICA9IDEwMCAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBsaW5rbmFtZQpMRU5HVEhfUFJFRklYICA9IDE1NSAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgdGhlIHByZWZpeCBmaWVsZApNQVhTSVpFX01FTUJFUiA9IDA3Nzc3Nzc3Nzc3N0wgICMgbWF4aW11bSBzaXplIG9mIGEgZmlsZSAoMTEgb2N0YWwgZGlnaXRzKQoKUkVHVFlQRSAgPSAiMCIgICAgICAgICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZQpBUkVHVFlQRSA9ICJcMCIgICAgICAgICAgICAgICAgICMgcmVndWxhciBmaWxlCkxOS1RZUEUgID0gIjEiICAgICAgICAgICAgICAgICAgIyBsaW5rIChpbnNpZGUgdGFyZmlsZSkKU1lNVFlQRSAgPSAiMiIgICAgICAgICAgICAgICAgICAjIHN5bWJvbGljIGxpbmsKQ0hSVFlQRSAgPSAiMyIgICAgICAgICAgICAgICAgICAjIGNoYXJhY3RlciBzcGVjaWFsIGRldmljZQpCTEtUWVBFICA9ICI0IiAgICAgICAgICAgICAgICAgICMgYmxvY2sgc3BlY2lhbCBkZXZpY2UKRElSVFlQRSAgPSAiNSIgICAgICAgICAgICAgICAgICAjIGRpcmVjdG9yeQpGSUZPVFlQRSA9ICI2IiAgICAgICAgICAgICAgICAgICMgZmlmbyBzcGVjaWFsIGRldmljZQpDT05UVFlQRSA9ICI3IiAgICAgICAgICAgICAgICAgICMgY29udGlndW91cyBmaWxlCgpHTlVUWVBFX0xPTkdOQU1FID0gIkwiICAgICAgICAgICMgR05VIHRhciBleHRlbnNpb24gZm9yIGxvbmduYW1lcwpHTlVUWVBFX0xPTkdMSU5LID0gIksiICAgICAgICAgICMgR05VIHRhciBleHRlbnNpb24gZm9yIGxvbmdsaW5rCkdOVVRZUEVfU1BBUlNFICAgPSAiUyIgICAgICAgICAgIyBHTlUgdGFyIGV4dGVuc2lvbiBmb3Igc3BhcnNlIGZpbGUKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNVUFBPUlRFRF9UWVBFUyA9IChSRUdUWVBFLCBBUkVHVFlQRSwgTE5LVFlQRSwgICMgZmlsZSB0eXBlcyB0aGF0IHRhcmZpbGUKICAgICAgICAgICAgICAgICAgIFNZTVRZUEUsIERJUlRZUEUsIEZJRk9UWVBFLCAgIyBjYW4gY29wZSB3aXRoLgogICAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIENIUlRZUEUsIEJMS1RZUEUsCiAgICAgICAgICAgICAgICAgICBHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LLAogICAgICAgICAgICAgICAgICAgR05VVFlQRV9TUEFSU0UpCgpSRUdVTEFSX1RZUEVTID0gKFJFR1RZUEUsIEFSRUdUWVBFLCAgICAgICAgICAgICAjIGZpbGUgdHlwZXMgdGhhdCBzb21laG93CiAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIEdOVVRZUEVfU1BBUlNFKSAgICAgICMgcmVwcmVzZW50IHJlZ3VsYXIgZmlsZXMKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBCaXRzIHVzZWQgaW4gdGhlIG1vZGUgZmllbGQsIHZhbHVlcyBpbiBvY3RhbC4KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTX0lGTE5LID0gMDEyMDAwMCAgICAgICAgIyBzeW1ib2xpYyBsaW5rClNfSUZSRUcgPSAwMTAwMDAwICAgICAgICAjIHJlZ3VsYXIgZmlsZQpTX0lGQkxLID0gMDA2MDAwMCAgICAgICAgIyBibG9jayBkZXZpY2UKU19JRkRJUiA9IDAwNDAwMDAgICAgICAgICMgZGlyZWN0b3J5ClNfSUZDSFIgPSAwMDIwMDAwICAgICAgICAjIGNoYXJhY3RlciBkZXZpY2UKU19JRklGTyA9IDAwMTAwMDAgICAgICAgICMgZmlmbwoKVFNVSUQgICA9IDA0MDAwICAgICAgICAgICMgc2V0IFVJRCBvbiBleGVjdXRpb24KVFNHSUQgICA9IDAyMDAwICAgICAgICAgICMgc2V0IEdJRCBvbiBleGVjdXRpb24KVFNWVFggICA9IDAxMDAwICAgICAgICAgICMgcmVzZXJ2ZWQKClRVUkVBRCAgPSAwNDAwICAgICAgICAgICAjIHJlYWQgYnkgb3duZXIKVFVXUklURSA9IDAyMDAgICAgICAgICAgICMgd3JpdGUgYnkgb3duZXIKVFVFWEVDICA9IDAxMDAgICAgICAgICAgICMgZXhlY3V0ZS9zZWFyY2ggYnkgb3duZXIKVEdSRUFEICA9IDAwNDAgICAgICAgICAgICMgcmVhZCBieSBncm91cApUR1dSSVRFID0gMDAyMCAgICAgICAgICAgIyB3cml0ZSBieSBncm91cApUR0VYRUMgID0gMDAxMCAgICAgICAgICAgIyBleGVjdXRlL3NlYXJjaCBieSBncm91cApUT1JFQUQgID0gMDAwNCAgICAgICAgICAgIyByZWFkIGJ5IG90aGVyClRPV1JJVEUgPSAwMDAyICAgICAgICAgICAjIHdyaXRlIGJ5IG90aGVyClRPRVhFQyAgPSAwMDAxICAgICAgICAgICAjIGV4ZWN1dGUvc2VhcmNoIGJ5IG90aGVyCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU29tZSB1c2VmdWwgZnVuY3Rpb25zCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZGVmIG50cyhzKToKICAgICIiIkNvbnZlcnQgYSBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nIGJ1ZmZlciB0byBhIHB5dGhvbiBzdHJpbmcuCiAgICAiIiIKICAgIHJldHVybiBzLnJzdHJpcChOVUwpCgpkZWYgY2FsY19jaGtzdW0oYnVmKToKICAgICIiIkNhbGN1bGF0ZSB0aGUgY2hlY2tzdW0gZm9yIGEgbWVtYmVyJ3MgaGVhZGVyLiBJdCdzIGEgc2ltcGxlIGFkZGl0aW9uCiAgICAgICBvZiBhbGwgYnl0ZXMsIHRyZWF0aW5nIHRoZSBjaGtzdW0gZmllbGQgYXMgaWYgZmlsbGVkIHdpdGggc3BhY2VzLgogICAgICAgYnVmIGlzIGEgNTEyIGJ5dGUgbG9uZyBzdHJpbmcgYnVmZmVyIHdoaWNoIGhvbGRzIHRoZSBoZWFkZXIuCiAgICAiIiIKICAgIGNoayA9IDI1NiAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY2hrc3VtIGZpZWxkIGlzIHRyZWF0ZWQgYXMgYmxhbmtzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzbyB0aGUgaW5pdGlhbCB2YWx1ZSBpcyA4ICogb3JkKCIgIikKICAgIGZvciBjIGluIGJ1Zls6MTQ4XTogY2hrICs9IG9yZChjKSAgICMgc3VtIHVwIGFsbCBieXRlcyBiZWZvcmUgY2hrc3VtCiAgICBmb3IgYyBpbiBidWZbMTU2Ol06IGNoayArPSBvcmQoYykgICAjIHN1bSB1cCBhbGwgYnl0ZXMgYWZ0ZXIgY2hrc3VtCiAgICByZXR1cm4gY2hrCgpkZWYgY29weWZpbGVvYmooc3JjLCBkc3QsIGxlbmd0aD1Ob25lKToKICAgICIiIkNvcHkgbGVuZ3RoIGJ5dGVzIGZyb20gZmlsZW9iaiBzcmMgdG8gZmlsZW9iaiBkc3QuCiAgICAgICBJZiBsZW5ndGggaXMgTm9uZSwgY29weSB0aGUgZW50aXJlIGNvbnRlbnQuCiAgICAiIiIKICAgIGlmIGxlbmd0aCA9PSAwOgogICAgICAgIHJldHVybgogICAgaWYgbGVuZ3RoIGlzIE5vbmU6CiAgICAgICAgc2h1dGlsLmNvcHlmaWxlb2JqKHNyYywgZHN0KQogICAgICAgIHJldHVybgoKICAgIEJVRlNJWkUgPSAxNiAqIDEwMjQKICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGxlbmd0aCwgQlVGU0laRSkKICAgIGZvciBiIGluIHhyYW5nZShibG9ja3MpOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKEJVRlNJWkUpCiAgICAgICAgaWYgbGVuKGJ1ZikgPCBCVUZTSVpFOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yLCAiZW5kIG9mIGZpbGUgcmVhY2hlZCIKICAgICAgICBkc3Qud3JpdGUoYnVmKQoKICAgIGlmIHJlbWFpbmRlciAhPSAwOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKHJlbWFpbmRlcikKICAgICAgICBpZiBsZW4oYnVmKSA8IHJlbWFpbmRlcjoKICAgICAgICAgICAgcmFpc2UgSU9FcnJvciwgImVuZCBvZiBmaWxlIHJlYWNoZWQiCiAgICAgICAgZHN0LndyaXRlKGJ1ZikKICAgIHJldHVybgoKZmlsZW1vZGVfdGFibGUgPSAoCiAgICAoKFNfSUZMTkssICAgICAgImwiKSwKICAgICAoU19JRlJFRywgICAgICAiLSIpLAogICAgIChTX0lGQkxLLCAgICAgICJiIiksCiAgICAgKFNfSUZESVIsICAgICAgImQiKSwKICAgICAoU19JRkNIUiwgICAgICAiYyIpLAogICAgIChTX0lGSUZPLCAgICAgICJwIikpLAoKICAgICgoVFVSRUFELCAgICAgICAiciIpLCksCiAgICAoKFRVV1JJVEUsICAgICAgInciKSwpLAogICAgKChUVUVYRUN8VFNVSUQsICJzIiksCiAgICAgKFRTVUlELCAgICAgICAgIlMiKSwKICAgICAoVFVFWEVDLCAgICAgICAieCIpKSwKCiAgICAoKFRHUkVBRCwgICAgICAgInIiKSwpLAogICAgKChUR1dSSVRFLCAgICAgICJ3IiksKSwKICAgICgoVEdFWEVDfFRTR0lELCAicyIpLAogICAgIChUU0dJRCwgICAgICAgICJTIiksCiAgICAgKFRHRVhFQywgICAgICAgIngiKSksCgogICAgKChUT1JFQUQsICAgICAgICJyIiksKSwKICAgICgoVE9XUklURSwgICAgICAidyIpLCksCiAgICAoKFRPRVhFQ3xUU1ZUWCwgInQiKSwKICAgICAoVFNWVFgsICAgICAgICAiVCIpLAogICAgIChUT0VYRUMsICAgICAgICJ4IikpCikKCmRlZiBmaWxlbW9kZShtb2RlKToKICAgICIiIkNvbnZlcnQgYSBmaWxlJ3MgbW9kZSB0byBhIHN0cmluZyBvZiB0aGUgZm9ybQogICAgICAgLXJ3eHJ3eHJ3eC4KICAgICAgIFVzZWQgYnkgVGFyRmlsZS5saXN0KCkKICAgICIiIgogICAgcGVybSA9IFtdCiAgICBmb3IgdGFibGUgaW4gZmlsZW1vZGVfdGFibGU6CiAgICAgICAgZm9yIGJpdCwgY2hhciBpbiB0YWJsZToKICAgICAgICAgICAgaWYgbW9kZSAmIGJpdCA9PSBiaXQ6CiAgICAgICAgICAgICAgICBwZXJtLmFwcGVuZChjaGFyKQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBlbHNlOgogICAgICAgICAgICBwZXJtLmFwcGVuZCgiLSIpCiAgICByZXR1cm4gIiIuam9pbihwZXJtKQoKaWYgb3Muc2VwICE9ICIvIjoKICAgIG5vcm1wYXRoID0gbGFtYmRhIHBhdGg6IG9zLnBhdGgubm9ybXBhdGgocGF0aCkucmVwbGFjZShvcy5zZXAsICIvIikKZWxzZToKICAgIG5vcm1wYXRoID0gb3MucGF0aC5ub3JtcGF0aAoKY2xhc3MgVGFyRXJyb3IoRXhjZXB0aW9uKToKICAgICIiIkJhc2UgZXhjZXB0aW9uLiIiIgogICAgcGFzcwpjbGFzcyBFeHRyYWN0RXJyb3IoVGFyRXJyb3IpOgogICAgIiIiR2VuZXJhbCBleGNlcHRpb24gZm9yIGV4dHJhY3QgZXJyb3JzLiIiIgogICAgcGFzcwpjbGFzcyBSZWFkRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bnJlYWRibGUgdGFyIGFyY2hpdmVzLiIiIgogICAgcGFzcwpjbGFzcyBDb21wcmVzc2lvbkVycm9yKFRhckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgdW5hdmFpbGFibGUgY29tcHJlc3Npb24gbWV0aG9kcy4iIiIKICAgIHBhc3MKY2xhc3MgU3RyZWFtRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bnN1cHBvcnRlZCBvcGVyYXRpb25zIG9uIHN0cmVhbS1saWtlIFRhckZpbGVzLiIiIgogICAgcGFzcwoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIGludGVybmFsIHN0cmVhbSBpbnRlcmZhY2UKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBfTG93TGV2ZWxGaWxlOgogICAgIiIiTG93LWxldmVsIGZpbGUgb2JqZWN0LiBTdXBwb3J0cyByZWFkaW5nIGFuZCB3cml0aW5nLgogICAgICAgSXQgaXMgdXNlZCBpbnN0ZWFkIG9mIGEgcmVndWxhciBmaWxlIG9iamVjdCBmb3Igc3RyZWFtaW5nCiAgICAgICBhY2Nlc3MuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSk6CiAgICAgICAgbW9kZSA9IHsKICAgICAgICAgICAgInIiOiBvcy5PX1JET05MWSwKICAgICAgICAgICAgInciOiBvcy5PX1dST05MWSB8IG9zLk9fQ1JFQVQgfCBvcy5PX1RSVU5DLAogICAgICAgIH1bbW9kZV0KICAgICAgICBpZiBoYXNhdHRyKG9zLCAiT19CSU5BUlkiKToKICAgICAgICAgICAgbW9kZSB8PSBvcy5PX0JJTkFSWQogICAgICAgIHNlbGYuZmQgPSBvcy5vcGVuKG5hbWUsIG1vZGUpCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIG9zLmNsb3NlKHNlbGYuZmQpCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgcmV0dXJuIG9zLnJlYWQoc2VsZi5mZCwgc2l6ZSkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgb3Mud3JpdGUoc2VsZi5mZCwgcykKCmNsYXNzIF9TdHJlYW06CiAgICAiIiJDbGFzcyB0aGF0IHNlcnZlcyBhcyBhbiBhZGFwdGVyIGJldHdlZW4gVGFyRmlsZSBhbmQKICAgICAgIGEgc3RyZWFtLWxpa2Ugb2JqZWN0LiAgVGhlIHN0cmVhbS1saWtlIG9iamVjdCBvbmx5CiAgICAgICBuZWVkcyB0byBoYXZlIGEgcmVhZCgpIG9yIHdyaXRlKCkgbWV0aG9kIGFuZCBpcyBhY2Nlc3NlZAogICAgICAgYmxvY2t3aXNlLiAgVXNlIG9mIGd6aXAgb3IgYnppcDIgY29tcHJlc3Npb24gaXMgcG9zc2libGUuCiAgICAgICBBIHN0cmVhbS1saWtlIG9iamVjdCBjb3VsZCBiZSBmb3IgZXhhbXBsZTogc3lzLnN0ZGluLAogICAgICAgc3lzLnN0ZG91dCwgYSBzb2NrZXQsIGEgdGFwZSBkZXZpY2UgZXRjLgoKICAgICAgIF9TdHJlYW0gaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbmx5IGludGVybmFsbHkuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSwgdHlwZSwgZmlsZW9iaiwgYnVmc2l6ZSk6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgX1N0cmVhbSBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fZXh0ZmlsZW9iaiA9IFRydWUKICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6CiAgICAgICAgICAgIGZpbGVvYmogPSBfTG93TGV2ZWxGaWxlKG5hbWUsIG1vZGUpCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBGYWxzZQoKICAgICAgICBzZWxmLm5hbWUgICAgPSBuYW1lIG9yICIiCiAgICAgICAgc2VsZi5tb2RlICAgID0gbW9kZQogICAgICAgIHNlbGYudHlwZSAgICA9IHR5cGUKICAgICAgICBzZWxmLmZpbGVvYmogPSBmaWxlb2JqCiAgICAgICAgc2VsZi5idWZzaXplID0gYnVmc2l6ZQogICAgICAgIHNlbGYuYnVmICAgICA9ICIiCiAgICAgICAgc2VsZi5wb3MgICAgID0gMEwKICAgICAgICBzZWxmLmNsb3NlZCAgPSBGYWxzZQoKICAgICAgICBpZiB0eXBlID09ICJneiI6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGltcG9ydCB6bGliCiAgICAgICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgICAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IsICJ6bGliIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIgogICAgICAgICAgICBzZWxmLnpsaWIgPSB6bGliCiAgICAgICAgICAgIHNlbGYuY3JjID0gemxpYi5jcmMzMigiIikKICAgICAgICAgICAgaWYgbW9kZSA9PSAiciI6CiAgICAgICAgICAgICAgICBzZWxmLl9pbml0X3JlYWRfZ3ooKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5faW5pdF93cml0ZV9neigpCgogICAgICAgIGlmIHR5cGUgPT0gImJ6MiI6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGltcG9ydCBiejIKICAgICAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvciwgImJ6MiBtb2R1bGUgaXMgbm90IGF2YWlsYWJsZSIKICAgICAgICAgICAgaWYgbW9kZSA9PSAiciI6CiAgICAgICAgICAgICAgICBzZWxmLmRidWYgPSAiIgogICAgICAgICAgICAgICAgc2VsZi5jbXAgPSBiejIuQloyRGVjb21wcmVzc29yKCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuY21wID0gYnoyLkJaMkNvbXByZXNzb3IoKQoKICAgIGRlZiBfX2RlbF9fKHNlbGYpOgogICAgICAgIGlmIG5vdCBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgc2VsZi5jbG9zZSgpCgogICAgZGVmIF9pbml0X3dyaXRlX2d6KHNlbGYpOgogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uLgogICAgICAgICIiIgogICAgICAgIHNlbGYuY21wID0gc2VsZi56bGliLmNvbXByZXNzb2JqKDksIHNlbGYuemxpYi5ERUZMQVRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtc2VsZi56bGliLk1BWF9XQklUUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpsaWIuREVGX01FTV9MRVZFTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKQogICAgICAgIHRpbWVzdGFtcCA9IHN0cnVjdC5wYWNrKCI8TCIsIGxvbmcodGltZS50aW1lKCkpKQogICAgICAgIHNlbGYuX193cml0ZSgiXDAzN1wyMTNcMDEwXDAxMCVzXDAwMlwzNzciICUgdGltZXN0YW1wKQogICAgICAgIGlmIHNlbGYubmFtZS5lbmRzd2l0aCgiLmd6Iik6CiAgICAgICAgICAgIHNlbGYubmFtZSA9IHNlbGYubmFtZVs6LTNdCiAgICAgICAgc2VsZi5fX3dyaXRlKHNlbGYubmFtZSArIE5VTCkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgIiIiV3JpdGUgc3RyaW5nIHMgdG8gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLnR5cGUgPT0gImd6IjoKICAgICAgICAgICAgc2VsZi5jcmMgPSBzZWxmLnpsaWIuY3JjMzIocywgc2VsZi5jcmMpCiAgICAgICAgc2VsZi5wb3MgKz0gbGVuKHMpCiAgICAgICAgaWYgc2VsZi50eXBlICE9ICJ0YXIiOgogICAgICAgICAgICBzID0gc2VsZi5jbXAuY29tcHJlc3MocykKICAgICAgICBzZWxmLl9fd3JpdGUocykKCiAgICBkZWYgX193cml0ZShzZWxmLCBzKToKICAgICAgICAiIiJXcml0ZSBzdHJpbmcgcyB0byB0aGUgc3RyZWFtIGlmIGEgd2hvbGUgbmV3IGJsb2NrCiAgICAgICAgICAgaXMgcmVhZHkgdG8gYmUgd3JpdHRlbi4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmJ1ZiArPSBzCiAgICAgICAgd2hpbGUgbGVuKHNlbGYuYnVmKSA+IHNlbGYuYnVmc2l6ZToKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHNlbGYuYnVmWzpzZWxmLmJ1ZnNpemVdKQogICAgICAgICAgICBzZWxmLmJ1ZiA9IHNlbGYuYnVmW3NlbGYuYnVmc2l6ZTpdCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgICIiIkNsb3NlIHRoZSBfU3RyZWFtIG9iamVjdC4gTm8gb3BlcmF0aW9uIHNob3VsZCBiZQogICAgICAgICAgIGRvbmUgb24gaXQgYWZ0ZXJ3YXJkcy4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIGlmIHNlbGYubW9kZSA9PSAidyIgYW5kIHNlbGYudHlwZSAhPSAidGFyIjoKICAgICAgICAgICAgc2VsZi5idWYgKz0gc2VsZi5jbXAuZmx1c2goKQogICAgICAgIGlmIHNlbGYubW9kZSA9PSAidyIgYW5kIHNlbGYuYnVmOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWYpCiAgICAgICAgICAgIHNlbGYuYnVmID0gIiIKICAgICAgICAgICAgaWYgc2VsZi50eXBlID09ICJneiI6CiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc3RydWN0LnBhY2soIjxsIiwgc2VsZi5jcmMpKQogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHN0cnVjdC5wYWNrKCI8TCIsIHNlbGYucG9zICYgMHhmZmZmRkZGRkwpKQoKICAgICAgICBpZiBub3Qgc2VsZi5fZXh0ZmlsZW9iajoKICAgICAgICAgICAgc2VsZi5maWxlb2JqLmNsb3NlKCkKCiAgICAgICAgc2VsZi5jbG9zZWQgPSBUcnVlCgogICAgZGVmIF9pbml0X3JlYWRfZ3ooc2VsZik6CiAgICAgICAgIiIiSW5pdGlhbGl6ZSBmb3IgcmVhZGluZyBhIGd6aXAgY29tcHJlc3NlZCBmaWxlb2JqLgogICAgICAgICIiIgogICAgICAgIHNlbGYuY21wID0gc2VsZi56bGliLmRlY29tcHJlc3NvYmooLXNlbGYuemxpYi5NQVhfV0JJVFMpCiAgICAgICAgc2VsZi5kYnVmID0gIiIKCiAgICAgICAgIyB0YWtlbiBmcm9tIGd6aXAuR3ppcEZpbGUgd2l0aCBzb21lIGFsdGVyYXRpb25zCiAgICAgICAgaWYgc2VsZi5fX3JlYWQoMikgIT0gIlwwMzdcMjEzIjoKICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yLCAibm90IGEgZ3ppcCBmaWxlIgogICAgICAgIGlmIHNlbGYuX19yZWFkKDEpICE9ICJcMDEwIjoKICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvciwgInVuc3VwcG9ydGVkIGNvbXByZXNzaW9uIG1ldGhvZCIKCiAgICAgICAgZmxhZyA9IG9yZChzZWxmLl9fcmVhZCgxKSkKICAgICAgICBzZWxmLl9fcmVhZCg2KQoKICAgICAgICBpZiBmbGFnICYgNDoKICAgICAgICAgICAgeGxlbiA9IG9yZChzZWxmLl9fcmVhZCgxKSkgKyAyNTYgKiBvcmQoc2VsZi5fX3JlYWQoMSkpCiAgICAgICAgICAgIHNlbGYucmVhZCh4bGVuKQogICAgICAgIGlmIGZsYWcgJiA4OgogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgcyA9IHNlbGYuX19yZWFkKDEpCiAgICAgICAgICAgICAgICBpZiBub3QgcyBvciBzID09IE5VTDoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgIGlmIGZsYWcgJiAxNjoKICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIHMgPSBzZWxmLl9fcmVhZCgxKQogICAgICAgICAgICAgICAgaWYgbm90IHMgb3IgcyA9PSBOVUw6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBpZiBmbGFnICYgMjoKICAgICAgICAgICAgc2VsZi5fX3JlYWQoMikKCiAgICBkZWYgdGVsbChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIHN0cmVhbSdzIGZpbGUgcG9pbnRlciBwb3NpdGlvbi4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZi5wb3MKCiAgICBkZWYgc2VlayhzZWxmLCBwb3M9MCk6CiAgICAgICAgIiIiU2V0IHRoZSBzdHJlYW0ncyBmaWxlIHBvaW50ZXIgdG8gcG9zLiBOZWdhdGl2ZSBzZWVraW5nCiAgICAgICAgICAgaXMgZm9yYmlkZGVuLgogICAgICAgICIiIgogICAgICAgIGlmIHBvcyAtIHNlbGYucG9zID49IDA6CiAgICAgICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKHBvcyAtIHNlbGYucG9zLCBzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIGZvciBpIGluIHhyYW5nZShibG9ja3MpOgogICAgICAgICAgICAgICAgc2VsZi5yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgc2VsZi5yZWFkKHJlbWFpbmRlcikKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBTdHJlYW1FcnJvciwgInNlZWtpbmcgYmFja3dhcmRzIGlzIG5vdCBhbGxvd2VkIgogICAgICAgIHJldHVybiBzZWxmLnBvcwoKICAgIGRlZiByZWFkKHNlbGYsIHNpemU9Tm9uZSk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IHNpemUgbnVtYmVyIG9mIGJ5dGVzIGZyb20gdGhlIHN0cmVhbS4KICAgICAgICAgICBJZiBzaXplIGlzIG5vdCBkZWZpbmVkLCByZXR1cm4gYWxsIGJ5dGVzIG9mIHRoZSBzdHJlYW0KICAgICAgICAgICB1cCB0byBFT0YuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2l6ZSBpcyBOb25lOgogICAgICAgICAgICB0ID0gW10KICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX3JlYWQoc2VsZi5idWZzaXplKQogICAgICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgdC5hcHBlbmQoYnVmKQogICAgICAgICAgICBidWYgPSAiIi5qb2luKHQpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYnVmID0gc2VsZi5fcmVhZChzaXplKQogICAgICAgIHNlbGYucG9zICs9IGxlbihidWYpCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiBfcmVhZChzZWxmLCBzaXplKToKICAgICAgICAiIiJSZXR1cm4gc2l6ZSBieXRlcyBmcm9tIHRoZSBzdHJlYW0uCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi50eXBlID09ICJ0YXIiOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX3JlYWQoc2l6ZSkKCiAgICAgICAgYyA9IGxlbihzZWxmLmRidWYpCiAgICAgICAgdCA9IFtzZWxmLmRidWZdCiAgICAgICAgd2hpbGUgYyA8IHNpemU6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX19yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuY21wLmRlY29tcHJlc3MoYnVmKQogICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGMgKz0gbGVuKGJ1ZikKICAgICAgICB0ID0gIiIuam9pbih0KQogICAgICAgIHNlbGYuZGJ1ZiA9IHRbc2l6ZTpdCiAgICAgICAgcmV0dXJuIHRbOnNpemVdCgogICAgZGVmIF9fcmVhZChzZWxmLCBzaXplKToKICAgICAgICAiIiJSZXR1cm4gc2l6ZSBieXRlcyBmcm9tIHN0cmVhbS4gSWYgaW50ZXJuYWwgYnVmZmVyIGlzIGVtcHR5LAogICAgICAgICAgIHJlYWQgYW5vdGhlciBibG9jayBmcm9tIHRoZSBzdHJlYW0uCiAgICAgICAgIiIiCiAgICAgICAgYyA9IGxlbihzZWxmLmJ1ZikKICAgICAgICB0ID0gW3NlbGYuYnVmXQogICAgICAgIHdoaWxlIGMgPCBzaXplOgogICAgICAgICAgICBidWYgPSBzZWxmLmZpbGVvYmoucmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGMgKz0gbGVuKGJ1ZikKICAgICAgICB0ID0gIiIuam9pbih0KQogICAgICAgIHNlbGYuYnVmID0gdFtzaXplOl0KICAgICAgICByZXR1cm4gdFs6c2l6ZV0KIyBjbGFzcyBfU3RyZWFtCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgRXh0cmFjdGlvbiBmaWxlIG9iamVjdAojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmNsYXNzIEV4RmlsZU9iamVjdChvYmplY3QpOgogICAgIiIiRmlsZS1saWtlIG9iamVjdCBmb3IgcmVhZGluZyBhbiBhcmNoaXZlIG1lbWJlci4KICAgICAgIElzIHJldHVybmVkIGJ5IFRhckZpbGUuZXh0cmFjdGZpbGUoKS4gU3VwcG9ydCBmb3IKICAgICAgIHNwYXJzZSBmaWxlcyBpbmNsdWRlZC4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCB0YXJmaWxlLCB0YXJpbmZvKToKICAgICAgICBzZWxmLmZpbGVvYmogPSB0YXJmaWxlLmZpbGVvYmoKICAgICAgICBzZWxmLm5hbWUgICAgPSB0YXJpbmZvLm5hbWUKICAgICAgICBzZWxmLm1vZGUgICAgPSAiciIKICAgICAgICBzZWxmLmNsb3NlZCAgPSBGYWxzZQogICAgICAgIHNlbGYub2Zmc2V0ICA9IHRhcmluZm8ub2Zmc2V0X2RhdGEKICAgICAgICBzZWxmLnNpemUgICAgPSB0YXJpbmZvLnNpemUKICAgICAgICBzZWxmLnBvcyAgICAgPSAwTAogICAgICAgIHNlbGYubGluZWJ1ZmZlciA9ICIiCiAgICAgICAgaWYgdGFyaW5mby5pc3NwYXJzZSgpOgogICAgICAgICAgICBzZWxmLnNwYXJzZSA9IHRhcmluZm8uc3BhcnNlCiAgICAgICAgICAgIHNlbGYucmVhZCA9IHNlbGYuX3JlYWRzcGFyc2UKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLnJlYWQgPSBzZWxmLl9yZWFkbm9ybWFsCgogICAgZGVmIF9fcmVhZChzZWxmLCBzaXplKToKICAgICAgICAiIiJPdmVybG9hZGFibGUgcmVhZCBtZXRob2QuCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iai5yZWFkKHNpemUpCgogICAgZGVmIHJlYWRsaW5lKHNlbGYsIHNpemU9LTEpOgogICAgICAgICIiIlJlYWQgYSBsaW5lIHdpdGggYXBwcm94LiBzaXplLiBJZiBzaXplIGlzIG5lZ2F0aXZlLAogICAgICAgICAgIHJlYWQgYSB3aG9sZSBsaW5lLiByZWFkbGluZSgpIGFuZCByZWFkKCkgbXVzdCBub3QKICAgICAgICAgICBiZSBtaXhlZCB1cCAoISkuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2l6ZSA8IDA6CiAgICAgICAgICAgIHNpemUgPSBzeXMubWF4aW50CgogICAgICAgIG5sID0gc2VsZi5saW5lYnVmZmVyLmZpbmQoIlxuIikKICAgICAgICBpZiBubCA+PSAwOgogICAgICAgICAgICBubCA9IG1pbihubCwgc2l6ZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzaXplIC09IGxlbihzZWxmLmxpbmVidWZmZXIpCiAgICAgICAgICAgIHdoaWxlIChubCA8IDAgYW5kIHNpemUgPiAwKToKICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYucmVhZChtaW4oc2l6ZSwgMTAwKSkKICAgICAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIHNlbGYubGluZWJ1ZmZlciArPSBidWYKICAgICAgICAgICAgICAgIHNpemUgLT0gbGVuKGJ1ZikKICAgICAgICAgICAgICAgIG5sID0gc2VsZi5saW5lYnVmZmVyLmZpbmQoIlxuIikKICAgICAgICAgICAgaWYgbmwgPT0gLTE6CiAgICAgICAgICAgICAgICBzID0gc2VsZi5saW5lYnVmZmVyCiAgICAgICAgICAgICAgICBzZWxmLmxpbmVidWZmZXIgPSAiIgogICAgICAgICAgICAgICAgcmV0dXJuIHMKICAgICAgICBidWYgPSBzZWxmLmxpbmVidWZmZXJbOm5sXQogICAgICAgIHNlbGYubGluZWJ1ZmZlciA9IHNlbGYubGluZWJ1ZmZlcltubCArIDE6XQogICAgICAgIHdoaWxlIGJ1ZlstMTpdID09ICJcciI6CiAgICAgICAgICAgIGJ1ZiA9IGJ1Zls6LTFdCiAgICAgICAgcmV0dXJuIGJ1ZiArICJcbiIKCiAgICBkZWYgcmVhZGxpbmVzKHNlbGYpOgogICAgICAgICIiIlJldHVybiBhIGxpc3Qgd2l0aCBhbGwgKGZvbGxvd2luZykgbGluZXMuCiAgICAgICAgIiIiCiAgICAgICAgcmVzdWx0ID0gW10KICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBsaW5lID0gc2VsZi5yZWFkbGluZSgpCiAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgICAgICByZXN1bHQuYXBwZW5kKGxpbmUpCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBfcmVhZG5vcm1hbChzZWxmLCBzaXplPU5vbmUpOgogICAgICAgICIiIlJlYWQgb3BlcmF0aW9uIGZvciByZWd1bGFyIGZpbGVzLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAiZmlsZSBpcyBjbG9zZWQiCiAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5vZmZzZXQgKyBzZWxmLnBvcykKICAgICAgICBieXRlc2xlZnQgPSBzZWxmLnNpemUgLSBzZWxmLnBvcwogICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgYnl0ZXN0b3JlYWQgPSBieXRlc2xlZnQKICAgICAgICBlbHNlOgogICAgICAgICAgICBieXRlc3RvcmVhZCA9IG1pbihzaXplLCBieXRlc2xlZnQpCiAgICAgICAgc2VsZi5wb3MgKz0gYnl0ZXN0b3JlYWQKICAgICAgICByZXR1cm4gc2VsZi5fX3JlYWQoYnl0ZXN0b3JlYWQpCgogICAgZGVmIF9yZWFkc3BhcnNlKHNlbGYsIHNpemU9Tm9uZSk6CiAgICAgICAgIiIiUmVhZCBvcGVyYXRpb24gZm9yIHNwYXJzZSBmaWxlcy4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgImZpbGUgaXMgY2xvc2VkIgoKICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgIHNpemUgPSBzZWxmLnNpemUgLSBzZWxmLnBvcwoKICAgICAgICBkYXRhID0gW10KICAgICAgICB3aGlsZSBzaXplID4gMDoKICAgICAgICAgICAgYnVmID0gc2VsZi5fcmVhZHNwYXJzZXNlY3Rpb24oc2l6ZSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHNpemUgLT0gbGVuKGJ1ZikKICAgICAgICAgICAgZGF0YS5hcHBlbmQoYnVmKQogICAgICAgIHJldHVybiAiIi5qb2luKGRhdGEpCgogICAgZGVmIF9yZWFkc3BhcnNlc2VjdGlvbihzZWxmLCBzaXplKToKICAgICAgICAiIiJSZWFkIGEgc2luZ2xlIHNlY3Rpb24gb2YgYSBzcGFyc2UgZmlsZS4KICAgICAgICAiIiIKICAgICAgICBzZWN0aW9uID0gc2VsZi5zcGFyc2UuZmluZChzZWxmLnBvcykKCiAgICAgICAgaWYgc2VjdGlvbiBpcyBOb25lOgogICAgICAgICAgICByZXR1cm4gIiIKCiAgICAgICAgdG9yZWFkID0gbWluKHNpemUsIHNlY3Rpb24ub2Zmc2V0ICsgc2VjdGlvbi5zaXplIC0gc2VsZi5wb3MpCiAgICAgICAgaWYgaXNpbnN0YW5jZShzZWN0aW9uLCBfZGF0YSk6CiAgICAgICAgICAgIHJlYWxwb3MgPSBzZWN0aW9uLnJlYWxwb3MgKyBzZWxmLnBvcyAtIHNlY3Rpb24ub2Zmc2V0CiAgICAgICAgICAgIHNlbGYucG9zICs9IHRvcmVhZAogICAgICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCArIHJlYWxwb3MpCiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fcmVhZCh0b3JlYWQpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5wb3MgKz0gdG9yZWFkCiAgICAgICAgICAgIHJldHVybiBOVUwgKiB0b3JlYWQKCiAgICBkZWYgdGVsbChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIGN1cnJlbnQgZmlsZSBwb3NpdGlvbi4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZi5wb3MKCiAgICBkZWYgc2VlayhzZWxmLCBwb3MsIHdoZW5jZT0wKToKICAgICAgICAiIiJTZWVrIHRvIGEgcG9zaXRpb24gaW4gdGhlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5saW5lYnVmZmVyID0gIiIKICAgICAgICBpZiB3aGVuY2UgPT0gMDoKICAgICAgICAgICAgc2VsZi5wb3MgPSBtaW4obWF4KHBvcywgMCksIHNlbGYuc2l6ZSkKICAgICAgICBpZiB3aGVuY2UgPT0gMToKICAgICAgICAgICAgaWYgcG9zIDwgMDoKICAgICAgICAgICAgICAgIHNlbGYucG9zID0gbWF4KHNlbGYucG9zICsgcG9zLCAwKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5wb3MgPSBtaW4oc2VsZi5wb3MgKyBwb3MsIHNlbGYuc2l6ZSkKICAgICAgICBpZiB3aGVuY2UgPT0gMjoKICAgICAgICAgICAgc2VsZi5wb3MgPSBtYXgobWluKHNlbGYuc2l6ZSArIHBvcywgc2VsZi5zaXplKSwgMCkKCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIGZpbGUgb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQojY2xhc3MgRXhGaWxlT2JqZWN0CgojLS0tLS0tLS0tLS0tLS0tLS0tCiMgRXhwb3J0ZWQgQ2xhc3NlcwojLS0tLS0tLS0tLS0tLS0tLS0tCmNsYXNzIFRhckluZm8ob2JqZWN0KToKICAgICIiIkluZm9ybWF0aW9uYWwgY2xhc3Mgd2hpY2ggaG9sZHMgdGhlIGRldGFpbHMgYWJvdXQgYW4KICAgICAgIGFyY2hpdmUgbWVtYmVyIGdpdmVuIGJ5IGEgdGFyIGhlYWRlciBibG9jay4KICAgICAgIFRhckluZm8gb2JqZWN0cyBhcmUgcmV0dXJuZWQgYnkgVGFyRmlsZS5nZXRtZW1iZXIoKSwKICAgICAgIFRhckZpbGUuZ2V0bWVtYmVycygpIGFuZCBUYXJGaWxlLmdldHRhcmluZm8oKSBhbmQgYXJlCiAgICAgICB1c3VhbGx5IGNyZWF0ZWQgaW50ZXJuYWxseS4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lPSIiKToKICAgICAgICAiIiJDb25zdHJ1Y3QgYSBUYXJJbmZvIG9iamVjdC4gbmFtZSBpcyB0aGUgb3B0aW9uYWwgbmFtZQogICAgICAgICAgIG9mIHRoZSBtZW1iZXIuCiAgICAgICAgIiIiCgogICAgICAgIHNlbGYubmFtZSAgICAgPSBuYW1lICAgICAgICMgbWVtYmVyIG5hbWUgKGRpcm5hbWVzIG11c3QgZW5kIHdpdGggJy8nKQogICAgICAgIHNlbGYubW9kZSAgICAgPSAwNjY2ICAgICAgICMgZmlsZSBwZXJtaXNzaW9ucwogICAgICAgIHNlbGYudWlkICAgICAgPSAwICAgICAgICAgICMgdXNlciBpZAogICAgICAgIHNlbGYuZ2lkICAgICAgPSAwICAgICAgICAgICMgZ3JvdXAgaWQKICAgICAgICBzZWxmLnNpemUgICAgID0gMCAgICAgICAgICAjIGZpbGUgc2l6ZQogICAgICAgIHNlbGYubXRpbWUgICAgPSAwICAgICAgICAgICMgbW9kaWZpY2F0aW9uIHRpbWUKICAgICAgICBzZWxmLmNoa3N1bSAgID0gMCAgICAgICAgICAjIGhlYWRlciBjaGVja3N1bQogICAgICAgIHNlbGYudHlwZSAgICAgPSBSRUdUWVBFICAgICMgbWVtYmVyIHR5cGUKICAgICAgICBzZWxmLmxpbmtuYW1lID0gIiIgICAgICAgICAjIGxpbmsgbmFtZQogICAgICAgIHNlbGYudW5hbWUgICAgPSAidXNlciIgICAgICMgdXNlciBuYW1lCiAgICAgICAgc2VsZi5nbmFtZSAgICA9ICJncm91cCIgICAgIyBncm91cCBuYW1lCiAgICAgICAgc2VsZi5kZXZtYWpvciA9IDAgICAgICAgICAgIy0KICAgICAgICBzZWxmLmRldm1pbm9yID0gMCAgICAgICAgICAjLWZvciB1c2Ugd2l0aCBDSFJUWVBFIGFuZCBCTEtUWVBFCiAgICAgICAgc2VsZi5wcmVmaXggICA9ICIiICAgICAgICAgIyBwcmVmaXggdG8gZmlsZW5hbWUgb3IgaG9sZGluZyBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYWJvdXQgc3BhcnNlIGZpbGVzCgogICAgICAgIHNlbGYub2Zmc2V0ICAgPSAwICAgICAgICAgICMgdGhlIHRhciBoZWFkZXIgc3RhcnRzIGhlcmUKICAgICAgICBzZWxmLm9mZnNldF9kYXRhID0gMCAgICAgICAjIHRoZSBmaWxlJ3MgZGF0YSBzdGFydHMgaGVyZQoKICAgIGRlZiBfX3JlcHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gIjwlcyAlciBhdCAlI3g+IiAlIChzZWxmLl9fY2xhc3NfXy5fX25hbWVfXyxzZWxmLm5hbWUsaWQoc2VsZikpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZnJvbWJ1ZihjbHMsIGJ1Zik6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySW5mbyBvYmplY3QgZnJvbSBhIDUxMiBieXRlIHN0cmluZyBidWZmZXIuCiAgICAgICAgIiIiCiAgICAgICAgdGFyaW5mbyA9IGNscygpCiAgICAgICAgdGFyaW5mby5uYW1lICAgPSBudHMoYnVmWzA6MTAwXSkKICAgICAgICB0YXJpbmZvLm1vZGUgICA9IGludChidWZbMTAwOjEwOF0sIDgpCiAgICAgICAgdGFyaW5mby51aWQgICAgPSBpbnQoYnVmWzEwODoxMTZdLDgpCiAgICAgICAgdGFyaW5mby5naWQgICAgPSBpbnQoYnVmWzExNjoxMjRdLDgpCgogICAgICAgICMgVGhlcmUgYXJlIHR3byBwb3NzaWJsZSBjb2RpbmdzIGZvciB0aGUgc2l6ZSBmaWVsZCB3ZQogICAgICAgICMgaGF2ZSB0byBkaXNjcmltaW5hdGUsIHNlZSBjb21tZW50IGluIHRvYnVmKCkgYmVsb3cuCiAgICAgICAgaWYgYnVmWzEyNF0gIT0gY2hyKDAyMDApOgogICAgICAgICAgICB0YXJpbmZvLnNpemUgPSBsb25nKGJ1ZlsxMjQ6MTM2XSwgOCkKICAgICAgICBlbHNlOgogICAgICAgICAgICB0YXJpbmZvLnNpemUgPSAwTAogICAgICAgICAgICBmb3IgaSBpbiByYW5nZSgxMSk6CiAgICAgICAgICAgICAgICB0YXJpbmZvLnNpemUgPDw9IDgKICAgICAgICAgICAgICAgIHRhcmluZm8uc2l6ZSArPSBvcmQoYnVmWzEyNSArIGldKQoKICAgICAgICB0YXJpbmZvLm10aW1lICA9IGxvbmcoYnVmWzEzNjoxNDhdLCA4KQogICAgICAgIHRhcmluZm8uY2hrc3VtID0gaW50KGJ1ZlsxNDg6MTU2XSwgOCkKICAgICAgICB0YXJpbmZvLnR5cGUgICA9IGJ1ZlsxNTY6MTU3XQogICAgICAgIHRhcmluZm8ubGlua25hbWUgPSBudHMoYnVmWzE1NzoyNTddKQogICAgICAgIHRhcmluZm8udW5hbWUgID0gbnRzKGJ1ZlsyNjU6Mjk3XSkKICAgICAgICB0YXJpbmZvLmduYW1lICA9IG50cyhidWZbMjk3OjMyOV0pCiAgICAgICAgdHJ5OgogICAgICAgICAgICB0YXJpbmZvLmRldm1ham9yID0gaW50KGJ1ZlszMjk6MzM3XSwgOCkKICAgICAgICAgICAgdGFyaW5mby5kZXZtaW5vciA9IGludChidWZbMzM3OjM0NV0sIDgpCiAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgIHRhcmluZm8uZGV2bWFqb3IgPSB0YXJpbmZvLmRldm1ham9yID0gMAogICAgICAgIHRhcmluZm8ucHJlZml4ID0gYnVmWzM0NTo1MDBdCgogICAgICAgICMgVGhlIHByZWZpeCBmaWVsZCBpcyB1c2VkIGZvciBmaWxlbmFtZXMgPiAxMDAgaW4KICAgICAgICAjIHRoZSBQT1NJWCBzdGFuZGFyZC4KICAgICAgICAjIG5hbWUgPSBwcmVmaXggKyAnLycgKyBuYW1lCiAgICAgICAgaWYgdGFyaW5mby50eXBlICE9IEdOVVRZUEVfU1BBUlNFOgogICAgICAgICAgICB0YXJpbmZvLm5hbWUgPSBub3JtcGF0aChvcy5wYXRoLmpvaW4obnRzKHRhcmluZm8ucHJlZml4KSwgdGFyaW5mby5uYW1lKSkKCiAgICAgICAgIyBEaXJlY3RvcnkgbmFtZXMgc2hvdWxkIGhhdmUgYSAnLycgYXQgdGhlIGVuZC4KICAgICAgICBpZiB0YXJpbmZvLmlzZGlyKCkgYW5kIHRhcmluZm8ubmFtZVstMTpdICE9ICIvIjoKICAgICAgICAgICAgdGFyaW5mby5uYW1lICs9ICIvIgogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgZGVmIHRvYnVmKHNlbGYpOgogICAgICAgICIiIlJldHVybiBhIHRhciBoZWFkZXIgYmxvY2sgYXMgYSA1MTIgYnl0ZSBzdHJpbmcuCiAgICAgICAgIiIiCiAgICAgICAgIyBQcmVmZXIgdGhlIHNpemUgdG8gYmUgZW5jb2RlZCBhcyAxMSBvY3RhbCBhc2NpaSBkaWdpdHMKICAgICAgICAjIHdoaWNoIGlzIHRoZSBtb3N0IHBvcnRhYmxlLiBJZiB0aGUgc2l6ZSBleGNlZWRzIHRoaXMKICAgICAgICAjIGxpbWl0ICg+PSA4IEdCKSwgZW5jb2RlIGl0IGFzIGFuIDg4LWJpdCB2YWx1ZSB3aGljaCBpcwogICAgICAgICMgYSBHTlUgdGFyIGZlYXR1cmUuCiAgICAgICAgaWYgc2VsZi5zaXplIDw9IE1BWFNJWkVfTUVNQkVSOgogICAgICAgICAgICBzaXplID0gIiUwMTFvIiAlIHNlbGYuc2l6ZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHMgPSBzZWxmLnNpemUKICAgICAgICAgICAgc2l6ZSA9ICIiCiAgICAgICAgICAgIGZvciBpIGluIHJhbmdlKDExKToKICAgICAgICAgICAgICAgIHNpemUgPSBjaHIocyAmIDAzNzcpICsgc2l6ZQogICAgICAgICAgICAgICAgcyA+Pj0gOAogICAgICAgICAgICBzaXplID0gY2hyKDAyMDApICsgc2l6ZQoKICAgICAgICAjIFRoZSBmb2xsb3dpbmcgY29kZSB3YXMgY29udHJpYnV0ZWQgYnkgRGV0bGVmIExhbm5lcnQuCiAgICAgICAgcGFydHMgPSBbXQogICAgICAgIGZvciB2YWx1ZSwgZmllbGRzaXplIGluICgKICAgICAgICAgICAgICAgIChzZWxmLm5hbWUsIDEwMCksCiAgICAgICAgICAgICAgICAoIiUwN28iICUgKHNlbGYubW9kZSAmIDA3Nzc3KSwgOCksCiAgICAgICAgICAgICAgICAoIiUwN28iICUgc2VsZi51aWQsIDgpLAogICAgICAgICAgICAgICAgKCIlMDdvIiAlIHNlbGYuZ2lkLCA4KSwKICAgICAgICAgICAgICAgIChzaXplLCAxMiksCiAgICAgICAgICAgICAgICAoIiUwMTFvIiAlIHNlbGYubXRpbWUsIDEyKSwKICAgICAgICAgICAgICAgICgiICAgICAgICAiLCA4KSwKICAgICAgICAgICAgICAgIChzZWxmLnR5cGUsIDEpLAogICAgICAgICAgICAgICAgKHNlbGYubGlua25hbWUsIDEwMCksCiAgICAgICAgICAgICAgICAoTUFHSUMsIDYpLAogICAgICAgICAgICAgICAgKFZFUlNJT04sIDIpLAogICAgICAgICAgICAgICAgKHNlbGYudW5hbWUsIDMyKSwKICAgICAgICAgICAgICAgIChzZWxmLmduYW1lLCAzMiksCiAgICAgICAgICAgICAgICAoIiUwN28iICUgc2VsZi5kZXZtYWpvciwgOCksCiAgICAgICAgICAgICAgICAoIiUwN28iICUgc2VsZi5kZXZtaW5vciwgOCksCiAgICAgICAgICAgICAgICAoc2VsZi5wcmVmaXgsIDE1NSkKICAgICAgICAgICAgKToKICAgICAgICAgICAgbCA9IGxlbih2YWx1ZSkKICAgICAgICAgICAgcGFydHMuYXBwZW5kKHZhbHVlWzpmaWVsZHNpemVdICsgKGZpZWxkc2l6ZSAtIGwpICogTlVMKQoKICAgICAgICBidWYgPSAiIi5qb2luKHBhcnRzKQogICAgICAgIGNoa3N1bSA9IGNhbGNfY2hrc3VtKGJ1ZikKICAgICAgICBidWYgPSBidWZbOjE0OF0gKyAiJTA2b1wwIiAlIGNoa3N1bSArIGJ1ZlsxNTU6XQogICAgICAgIGJ1ZiArPSAoQkxPQ0tTSVpFIC0gbGVuKGJ1ZikpICogTlVMCiAgICAgICAgc2VsZi5idWYgPSBidWYKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIGlzcmVnKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgaW4gUkVHVUxBUl9UWVBFUwogICAgZGVmIGlzZmlsZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5pc3JlZygpCiAgICBkZWYgaXNkaXIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBESVJUWVBFCiAgICBkZWYgaXNzeW0oc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBTWU1UWVBFCiAgICBkZWYgaXNsbmsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBMTktUWVBFCiAgICBkZWYgaXNjaHIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBDSFJUWVBFCiAgICBkZWYgaXNibGsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBCTEtUWVBFCiAgICBkZWYgaXNmaWZvKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gRklGT1RZUEUKICAgIGRlZiBpc3NwYXJzZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEdOVVRZUEVfU1BBUlNFCiAgICBkZWYgaXNkZXYoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSBpbiAoQ0hSVFlQRSwgQkxLVFlQRSwgRklGT1RZUEUpCiMgY2xhc3MgVGFySW5mbwoKY2xhc3MgVGFyRmlsZShvYmplY3QpOgogICAgIiIiVGhlIFRhckZpbGUgQ2xhc3MgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIHRvIHRhciBhcmNoaXZlcy4KICAgICIiIgoKICAgIGRlYnVnID0gMCAgICAgICAgICAgICAgICAgICAjIE1heSBiZSBzZXQgZnJvbSAwIChubyBtc2dzKSB0byAzIChhbGwgbXNncykKCiAgICBkZXJlZmVyZW5jZSA9IEZhbHNlICAgICAgICAgIyBJZiB0cnVlLCBhZGQgY29udGVudCBvZiBsaW5rZWQgZmlsZSB0byB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRhciBmaWxlLCBlbHNlIHRoZSBsaW5rLgoKICAgIGlnbm9yZV96ZXJvcyA9IEZhbHNlICAgICAgICAjIElmIHRydWUsIHNraXBzIGVtcHR5IG9yIGludmFsaWQgYmxvY2tzIGFuZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY29udGludWVzIHByb2Nlc3NpbmcuCgogICAgZXJyb3JsZXZlbCA9IDAgICAgICAgICAgICAgICMgSWYgMCwgZmF0YWwgZXJyb3JzIG9ubHkgYXBwZWFyIGluIGRlYnVnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtZXNzYWdlcyAoaWYgZGVidWcgPj0gMCkuIElmID4gMCwgZXJyb3JzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhcmUgcGFzc2VkIHRvIHRoZSBjYWxsZXIgYXMgZXhjZXB0aW9ucy4KCiAgICBwb3NpeCA9IEZhbHNlICAgICAgICAgICAgICAgIyBJZiBUcnVlLCBnZW5lcmF0ZXMgUE9TSVguMS0xOTkwLWNvbXBsaWFudAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJjaGl2ZXMgKG5vIEdOVSBleHRlbnNpb25zISkKCiAgICBmaWxlb2JqZWN0ID0gRXhGaWxlT2JqZWN0CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWU9Tm9uZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiT3BlbiBhbiAodW5jb21wcmVzc2VkKSB0YXIgYXJjaGl2ZSBgbmFtZScuIGBtb2RlJyBpcyBlaXRoZXIgJ3InIHRvCiAgICAgICAgICAgcmVhZCBmcm9tIGFuIGV4aXN0aW5nIGFyY2hpdmUsICdhJyB0byBhcHBlbmQgZGF0YSB0byBhbiBleGlzdGluZwogICAgICAgICAgIGZpbGUgb3IgJ3cnIHRvIGNyZWF0ZSBhIG5ldyBmaWxlIG92ZXJ3cml0aW5nIGFuIGV4aXN0aW5nIG9uZS4gYG1vZGUnCiAgICAgICAgICAgZGVmYXVsdHMgdG8gJ3InLgogICAgICAgICAgIElmIGBmaWxlb2JqJyBpcyBnaXZlbiwgaXQgaXMgdXNlZCBmb3IgcmVhZGluZyBvciB3cml0aW5nIGRhdGEuIElmIGl0CiAgICAgICAgICAgY2FuIGJlIGRldGVybWluZWQsIGBtb2RlJyBpcyBvdmVycmlkZGVuIGJ5IGBmaWxlb2JqJ3MgbW9kZS4KICAgICAgICAgICBgZmlsZW9iaicgaXMgbm90IGNsb3NlZCwgd2hlbiBUYXJGaWxlIGlzIGNsb3NlZC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLm5hbWUgPSBuYW1lCgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJhdyI6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJtb2RlIG11c3QgYmUgJ3InLCAnYScgb3IgJ3cnIgogICAgICAgIHNlbGYuX21vZGUgPSBtb2RlCiAgICAgICAgc2VsZi5tb2RlID0geyJyIjogInJiIiwgImEiOiAicitiIiwgInciOiAid2IifVttb2RlXQoKICAgICAgICBpZiBub3QgZmlsZW9iajoKICAgICAgICAgICAgZmlsZW9iaiA9IGZpbGUoc2VsZi5uYW1lLCBzZWxmLm1vZGUpCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIHNlbGYubmFtZSBpcyBOb25lIGFuZCBoYXNhdHRyKGZpbGVvYmosICJuYW1lIik6CiAgICAgICAgICAgICAgICBzZWxmLm5hbWUgPSBmaWxlb2JqLm5hbWUKICAgICAgICAgICAgaWYgaGFzYXR0cihmaWxlb2JqLCAibW9kZSIpOgogICAgICAgICAgICAgICAgc2VsZi5tb2RlID0gZmlsZW9iai5tb2RlCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagoKICAgICAgICAjIEluaXQgZGF0YXN0cnVjdHVyZXMKICAgICAgICBzZWxmLmNsb3NlZCAgICAgID0gRmFsc2UKICAgICAgICBzZWxmLm1lbWJlcnMgICAgID0gW10gICAgICAgIyBsaXN0IG9mIG1lbWJlcnMgYXMgVGFySW5mbyBvYmplY3RzCiAgICAgICAgc2VsZi5fbG9hZGVkICAgICA9IEZhbHNlICAgICMgZmxhZyBpZiBhbGwgbWVtYmVycyBoYXZlIGJlZW4gcmVhZAogICAgICAgIHNlbGYub2Zmc2V0ICAgICAgPSAwTCAgICAgICAjIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIGFyY2hpdmUgZmlsZQogICAgICAgIHNlbGYuaW5vZGVzICAgICAgPSB7fSAgICAgICAjIGRpY3Rpb25hcnkgY2FjaGluZyB0aGUgaW5vZGVzIG9mCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJjaGl2ZSBtZW1iZXJzIGFscmVhZHkgYWRkZWQKCiAgICAgICAgaWYgc2VsZi5fbW9kZSA9PSAiciI6CiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBzZWxmLm5leHQoKQoKICAgICAgICBpZiBzZWxmLl9tb2RlID09ICJhIjoKICAgICAgICAgICAgIyBNb3ZlIHRvIHRoZSBlbmQgb2YgdGhlIGFyY2hpdmUsCiAgICAgICAgICAgICMgYmVmb3JlIHRoZSBmaXJzdCBlbXB0eSBibG9jay4KICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IE5vbmUKICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5uZXh0KCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBSZWFkRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoMCkKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKC0gQkxPQ0tTSVpFLCAxKQogICAgICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgIGlmIHNlbGYuX21vZGUgaW4gImF3IjoKICAgICAgICAgICAgc2VsZi5fbG9hZGVkID0gVHJ1ZQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBCZWxvdyBhcmUgdGhlIGNsYXNzbWV0aG9kcyB3aGljaCBhY3QgYXMgYWx0ZXJuYXRlIGNvbnN0cnVjdG9ycyB0byB0aGUKICAgICMgVGFyRmlsZSBjbGFzcy4gVGhlIG9wZW4oKSBtZXRob2QgaXMgdGhlIG9ubHkgb25lIHRoYXQgaXMgbmVlZGVkIGZvcgogICAgIyBwdWJsaWMgdXNlOyBpdCBpcyB0aGUgInN1cGVyIi1jb25zdHJ1Y3RvciBhbmQgaXMgYWJsZSB0byBzZWxlY3QgYW4KICAgICMgYWRlcXVhdGUgInN1YiItY29uc3RydWN0b3IgZm9yIGEgcGFydGljdWxhciBjb21wcmVzc2lvbiB1c2luZyB0aGUgbWFwcGluZwogICAgIyBmcm9tIE9QRU5fTUVUSC4KICAgICMKICAgICMgVGhpcyBjb25jZXB0IGFsbG93cyBvbmUgdG8gc3ViY2xhc3MgVGFyRmlsZSB3aXRob3V0IGxvc2luZyB0aGUgY29tZm9ydCBvZgogICAgIyB0aGUgc3VwZXItY29uc3RydWN0b3IuIEEgc3ViLWNvbnN0cnVjdG9yIGlzIHJlZ2lzdGVyZWQgYW5kIG1hZGUgYXZhaWxhYmxlCiAgICAjIGJ5IGFkZGluZyBpdCB0byB0aGUgbWFwcGluZyBpbiBPUEVOX01FVEguCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgb3BlbihjbHMsIG5hbWU9Tm9uZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgYnVmc2l6ZT0yMCo1MTIpOgogICAgICAgICIiIk9wZW4gYSB0YXIgYXJjaGl2ZSBmb3IgcmVhZGluZywgd3JpdGluZyBvciBhcHBlbmRpbmcuIFJldHVybgogICAgICAgICAgIGFuIGFwcHJvcHJpYXRlIFRhckZpbGUgY2xhc3MuCgogICAgICAgICAgIG1vZGU6CiAgICAgICAgICAgJ3InICAgICAgICAgIG9wZW4gZm9yIHJlYWRpbmcgd2l0aCB0cmFuc3BhcmVudCBjb21wcmVzc2lvbgogICAgICAgICAgICdyOicgICAgICAgICBvcGVuIGZvciByZWFkaW5nIGV4Y2x1c2l2ZWx5IHVuY29tcHJlc3NlZAogICAgICAgICAgICdyOmd6JyAgICAgICBvcGVuIGZvciByZWFkaW5nIHdpdGggZ3ppcCBjb21wcmVzc2lvbgogICAgICAgICAgICdyOmJ6MicgICAgICBvcGVuIGZvciByZWFkaW5nIHdpdGggYnppcDIgY29tcHJlc3Npb24KICAgICAgICAgICAnYScgb3IgJ2E6JyAgb3BlbiBmb3IgYXBwZW5kaW5nCiAgICAgICAgICAgJ3cnIG9yICd3OicgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aG91dCBjb21wcmVzc2lvbgogICAgICAgICAgICd3Omd6JyAgICAgICBvcGVuIGZvciB3cml0aW5nIHdpdGggZ3ppcCBjb21wcmVzc2lvbgogICAgICAgICAgICd3OmJ6MicgICAgICBvcGVuIGZvciB3cml0aW5nIHdpdGggYnppcDIgY29tcHJlc3Npb24KICAgICAgICAgICAncnwnICAgICAgICAgb3BlbiBhbiB1bmNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MgZm9yIHJlYWRpbmcKICAgICAgICAgICAncnxneicgICAgICAgb3BlbiBhIGd6aXAgY29tcHJlc3NlZCBzdHJlYW0gb2YgdGFyIGJsb2NrcwogICAgICAgICAgICdyfGJ6MicgICAgICBvcGVuIGEgYnppcDIgY29tcHJlc3NlZCBzdHJlYW0gb2YgdGFyIGJsb2NrcwogICAgICAgICAgICd3fCcgICAgICAgICBvcGVuIGFuIHVuY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcKICAgICAgICAgICAnd3xneicgICAgICAgb3BlbiBhIGd6aXAgY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcKICAgICAgICAgICAnd3xiejInICAgICAgb3BlbiBhIGJ6aXAyIGNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCiAgICAgICAgIiIiCgogICAgICAgIGlmIG5vdCBuYW1lIGFuZCBub3QgZmlsZW9iajoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgIm5vdGhpbmcgdG8gb3BlbiIKCiAgICAgICAgaWYgIjoiIGluIG1vZGU6CiAgICAgICAgICAgIGZpbGVtb2RlLCBjb21wdHlwZSA9IG1vZGUuc3BsaXQoIjoiLCAxKQogICAgICAgICAgICBmaWxlbW9kZSA9IGZpbGVtb2RlIG9yICJyIgogICAgICAgICAgICBjb21wdHlwZSA9IGNvbXB0eXBlIG9yICJ0YXIiCgogICAgICAgICAgICAjIFNlbGVjdCB0aGUgKm9wZW4oKSBmdW5jdGlvbiBhY2NvcmRpbmcgdG8KICAgICAgICAgICAgIyBnaXZlbiBjb21wcmVzc2lvbi4KICAgICAgICAgICAgaWYgY29tcHR5cGUgaW4gY2xzLk9QRU5fTUVUSDoKICAgICAgICAgICAgICAgIGZ1bmMgPSBnZXRhdHRyKGNscywgY2xzLk9QRU5fTUVUSFtjb21wdHlwZV0pCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yLCAidW5rbm93biBjb21wcmVzc2lvbiB0eXBlICVyIiAlIGNvbXB0eXBlCiAgICAgICAgICAgIHJldHVybiBmdW5jKG5hbWUsIGZpbGVtb2RlLCBmaWxlb2JqKQoKICAgICAgICBlbGlmICJ8IiBpbiBtb2RlOgogICAgICAgICAgICBmaWxlbW9kZSwgY29tcHR5cGUgPSBtb2RlLnNwbGl0KCJ8IiwgMSkKICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciIKICAgICAgICAgICAgY29tcHR5cGUgPSBjb21wdHlwZSBvciAidGFyIgoKICAgICAgICAgICAgaWYgZmlsZW1vZGUgbm90IGluICJydyI6CiAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAibW9kZSBtdXN0IGJlICdyJyBvciAndyciCgogICAgICAgICAgICB0ID0gY2xzKG5hbWUsIGZpbGVtb2RlLAogICAgICAgICAgICAgICAgICAgIF9TdHJlYW0obmFtZSwgZmlsZW1vZGUsIGNvbXB0eXBlLCBmaWxlb2JqLCBidWZzaXplKSkKICAgICAgICAgICAgdC5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgICAgIHJldHVybiB0CgogICAgICAgIGVsaWYgbW9kZSA9PSAiciI6CiAgICAgICAgICAgICMgRmluZCBvdXQgd2hpY2ggKm9wZW4oKSBpcyBhcHByb3ByaWF0ZSBmb3Igb3BlbmluZyB0aGUgZmlsZS4KICAgICAgICAgICAgZm9yIGNvbXB0eXBlIGluIGNscy5PUEVOX01FVEg6CiAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cihjbHMsIGNscy5PUEVOX01FVEhbY29tcHR5cGVdKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jKG5hbWUsICJyIiwgZmlsZW9iaikKICAgICAgICAgICAgICAgIGV4Y2VwdCAoUmVhZEVycm9yLCBDb21wcmVzc2lvbkVycm9yKToKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IsICJmaWxlIGNvdWxkIG5vdCBiZSBvcGVuZWQgc3VjY2Vzc2Z1bGx5IgoKICAgICAgICBlbGlmIG1vZGUgaW4gImF3IjoKICAgICAgICAgICAgcmV0dXJuIGNscy50YXJvcGVuKG5hbWUsIG1vZGUsIGZpbGVvYmopCgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJ1bmRpc2Nlcm5pYmxlIG1vZGUiCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgdGFyb3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUpOgogICAgICAgICIiIk9wZW4gdW5jb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAiIiIKICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJyYXciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAibW9kZSBtdXN0IGJlICdyJywgJ2EnIG9yICd3JyIKICAgICAgICByZXR1cm4gY2xzKG5hbWUsIG1vZGUsIGZpbGVvYmopCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZ3pvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgY29tcHJlc3NsZXZlbD05KToKICAgICAgICAiIiJPcGVuIGd6aXAgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgIm1vZGUgbXVzdCBiZSAncicgb3IgJ3cnIgoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBnemlwCiAgICAgICAgICAgIGd6aXAuR3ppcEZpbGUKICAgICAgICBleGNlcHQgKEltcG9ydEVycm9yLCBBdHRyaWJ1dGVFcnJvcik6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IsICJnemlwIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIgoKICAgICAgICBwcmUsIGV4dCA9IG9zLnBhdGguc3BsaXRleHQobmFtZSkKICAgICAgICBwcmUgPSBvcy5wYXRoLmJhc2VuYW1lKHByZSkKICAgICAgICBpZiBleHQgPT0gIi50Z3oiOgogICAgICAgICAgICBleHQgPSAiLnRhciIKICAgICAgICBpZiBleHQgPT0gIi5neiI6CiAgICAgICAgICAgIGV4dCA9ICIiCiAgICAgICAgdGFybmFtZSA9IHByZSArIGV4dAoKICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6CiAgICAgICAgICAgIGZpbGVvYmogPSBmaWxlKG5hbWUsIG1vZGUgKyAiYiIpCgogICAgICAgIGlmIG1vZGUgIT0gInIiOgogICAgICAgICAgICBuYW1lID0gdGFybmFtZQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHQgPSBjbHMudGFyb3Blbih0YXJuYW1lLCBtb2RlLAogICAgICAgICAgICAgICAgZ3ppcC5HemlwRmlsZShuYW1lLCBtb2RlLCBjb21wcmVzc2xldmVsLCBmaWxlb2JqKQogICAgICAgICAgICApCiAgICAgICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvciwgIm5vdCBhIGd6aXAgZmlsZSIKICAgICAgICB0Ll9leHRmaWxlb2JqID0gRmFsc2UKICAgICAgICByZXR1cm4gdAoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIGJ6Mm9wZW4oY2xzLCBuYW1lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCBjb21wcmVzc2xldmVsPTkpOgogICAgICAgICIiIk9wZW4gYnppcDIgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgIm1vZGUgbXVzdCBiZSAncicgb3IgJ3cnLiIKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpbXBvcnQgYnoyCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yLCAiYnoyIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIgoKICAgICAgICBwcmUsIGV4dCA9IG9zLnBhdGguc3BsaXRleHQobmFtZSkKICAgICAgICBwcmUgPSBvcy5wYXRoLmJhc2VuYW1lKHByZSkKICAgICAgICBpZiBleHQgPT0gIi50YnoyIjoKICAgICAgICAgICAgZXh0ID0gIi50YXIiCiAgICAgICAgaWYgZXh0ID09ICIuYnoyIjoKICAgICAgICAgICAgZXh0ID0gIiIKICAgICAgICB0YXJuYW1lID0gcHJlICsgZXh0CgogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJubyBzdXBwb3J0IGZvciBleHRlcm5hbCBmaWxlIG9iamVjdHMiCgogICAgICAgIHRyeToKICAgICAgICAgICAgdCA9IGNscy50YXJvcGVuKHRhcm5hbWUsIG1vZGUsIGJ6Mi5CWjJGaWxlKG5hbWUsIG1vZGUsIGNvbXByZXNzbGV2ZWw9Y29tcHJlc3NsZXZlbCkpCiAgICAgICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvciwgIm5vdCBhIGJ6aXAyIGZpbGUiCiAgICAgICAgdC5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgcmV0dXJuIHQKCiAgICAjIEFsbCAqb3BlbigpIG1ldGhvZHMgYXJlIHJlZ2lzdGVyZWQgaGVyZS4KICAgIE9QRU5fTUVUSCA9IHsKICAgICAgICAidGFyIjogInRhcm9wZW4iLCAgICMgdW5jb21wcmVzc2VkIHRhcgogICAgICAgICJneiI6ICAiZ3pvcGVuIiwgICAgIyBnemlwIGNvbXByZXNzZWQgdGFyCiAgICAgICAgImJ6MiI6ICJiejJvcGVuIiAgICAjIGJ6aXAyIGNvbXByZXNzZWQgdGFyCiAgICB9CgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIFRoZSBwdWJsaWMgbWV0aG9kcyB3aGljaCBUYXJGaWxlIHByb3ZpZGVzOgoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICAiIiJDbG9zZSB0aGUgVGFyRmlsZS4gSW4gd3JpdGUtbW9kZSwgdHdvIGZpbmlzaGluZyB6ZXJvIGJsb2NrcyBhcmUKICAgICAgICAgICBhcHBlbmRlZCB0byB0aGUgYXJjaGl2ZS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIGlmIHNlbGYuX21vZGUgaW4gImF3IjoKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChCTE9DS1NJWkUgKiAyKSkKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gKEJMT0NLU0laRSAqIDIpCiAgICAgICAgICAgICMgZmlsbCB1cCB0aGUgZW5kIHdpdGggemVyby1ibG9ja3MKICAgICAgICAgICAgIyAobGlrZSBvcHRpb24gLWIyMCBmb3IgdGFyIGRvZXMpCiAgICAgICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKHNlbGYub2Zmc2V0LCBSRUNPUkRTSVpFKQogICAgICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChSRUNPUkRTSVpFIC0gcmVtYWluZGVyKSkKCiAgICAgICAgaWYgbm90IHNlbGYuX2V4dGZpbGVvYmo6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCiAgICAgICAgc2VsZi5jbG9zZWQgPSBUcnVlCgogICAgZGVmIGdldG1lbWJlcihzZWxmLCBuYW1lKToKICAgICAgICAiIiJSZXR1cm4gYSBUYXJJbmZvIG9iamVjdCBmb3IgbWVtYmVyIGBuYW1lJy4gSWYgYG5hbWUnIGNhbiBub3QgYmUKICAgICAgICAgICBmb3VuZCBpbiB0aGUgYXJjaGl2ZSwgS2V5RXJyb3IgaXMgcmFpc2VkLiBJZiBhIG1lbWJlciBvY2N1cnMgbW9yZQogICAgICAgICAgIHRoYW4gb25jZSBpbiB0aGUgYXJjaGl2ZSwgaXRzIGxhc3Qgb2NjdXJlbmNlIGlzIGFzc3VtZWQgdG8gYmUgdGhlCiAgICAgICAgICAgbW9zdCB1cC10by1kYXRlIHZlcnNpb24uCiAgICAgICAgIiIiCiAgICAgICAgdGFyaW5mbyA9IHNlbGYuX2dldG1lbWJlcihuYW1lKQogICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgcmFpc2UgS2V5RXJyb3IsICJmaWxlbmFtZSAlciBub3QgZm91bmQiICUgbmFtZQogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgZGVmIGdldG1lbWJlcnMoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBtZW1iZXJzIG9mIHRoZSBhcmNoaXZlIGFzIGEgbGlzdCBvZiBUYXJJbmZvIG9iamVjdHMuIFRoZQogICAgICAgICAgIGxpc3QgaGFzIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBtZW1iZXJzIGluIHRoZSBhcmNoaXZlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCkKICAgICAgICBpZiBub3Qgc2VsZi5fbG9hZGVkOiAgICAjIGlmIHdlIHdhbnQgdG8gb2J0YWluIGEgbGlzdCBvZgogICAgICAgICAgICBzZWxmLl9sb2FkKCkgICAgICAgICMgYWxsIG1lbWJlcnMsIHdlIGZpcnN0IGhhdmUgdG8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNjYW4gdGhlIHdob2xlIGFyY2hpdmUuCiAgICAgICAgcmV0dXJuIHNlbGYubWVtYmVycwoKICAgIGRlZiBnZXRuYW1lcyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG1lbWJlcnMgb2YgdGhlIGFyY2hpdmUgYXMgYSBsaXN0IG9mIHRoZWlyIG5hbWVzLiBJdCBoYXMKICAgICAgICAgICB0aGUgc2FtZSBvcmRlciBhcyB0aGUgbGlzdCByZXR1cm5lZCBieSBnZXRtZW1iZXJzKCkuCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIFt0YXJpbmZvLm5hbWUgZm9yIHRhcmluZm8gaW4gc2VsZi5nZXRtZW1iZXJzKCldCgogICAgZGVmIGdldHRhcmluZm8oc2VsZiwgbmFtZT1Ob25lLCBhcmNuYW1lPU5vbmUsIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiQ3JlYXRlIGEgVGFySW5mbyBvYmplY3QgZm9yIGVpdGhlciB0aGUgZmlsZSBgbmFtZScgb3IgdGhlIGZpbGUKICAgICAgICAgICBvYmplY3QgYGZpbGVvYmonICh1c2luZyBvcy5mc3RhdCBvbiBpdHMgZmlsZSBkZXNjcmlwdG9yKS4gWW91IGNhbgogICAgICAgICAgIG1vZGlmeSBzb21lIG9mIHRoZSBUYXJJbmZvJ3MgYXR0cmlidXRlcyBiZWZvcmUgeW91IGFkZCBpdCB1c2luZwogICAgICAgICAgIGFkZGZpbGUoKS4gSWYgZ2l2ZW4sIGBhcmNuYW1lJyBzcGVjaWZpZXMgYW4gYWx0ZXJuYXRpdmUgbmFtZSBmb3IgdGhlCiAgICAgICAgICAgZmlsZSBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiYXciKQoKICAgICAgICAjIFdoZW4gZmlsZW9iaiBpcyBnaXZlbiwgcmVwbGFjZSBuYW1lIGJ5CiAgICAgICAgIyBmaWxlb2JqJ3MgcmVhbCBuYW1lLgogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgIG5hbWUgPSBmaWxlb2JqLm5hbWUKCiAgICAgICAgIyBCdWlsZGluZyB0aGUgbmFtZSBvZiB0aGUgbWVtYmVyIGluIHRoZSBhcmNoaXZlLgogICAgICAgICMgQmFja3dhcmQgc2xhc2hlcyBhcmUgY29udmVydGVkIHRvIGZvcndhcmQgc2xhc2hlcywKICAgICAgICAjIEFic29sdXRlIHBhdGhzIGFyZSB0dXJuZWQgdG8gcmVsYXRpdmUgcGF0aHMuCiAgICAgICAgaWYgYXJjbmFtZSBpcyBOb25lOgogICAgICAgICAgICBhcmNuYW1lID0gbmFtZQogICAgICAgIGFyY25hbWUgPSBub3JtcGF0aChhcmNuYW1lKQogICAgICAgIGRydiwgYXJjbmFtZSA9IG9zLnBhdGguc3BsaXRkcml2ZShhcmNuYW1lKQogICAgICAgIHdoaWxlIGFyY25hbWVbMDoxXSA9PSAiLyI6CiAgICAgICAgICAgIGFyY25hbWUgPSBhcmNuYW1lWzE6XQoKICAgICAgICAjIE5vdywgZmlsbCB0aGUgVGFySW5mbyBvYmplY3Qgd2l0aAogICAgICAgICMgaW5mb3JtYXRpb24gc3BlY2lmaWMgZm9yIHRoZSBmaWxlLgogICAgICAgIHRhcmluZm8gPSBUYXJJbmZvKCkKCiAgICAgICAgIyBVc2Ugb3Muc3RhdCBvciBvcy5sc3RhdCwgZGVwZW5kaW5nIG9uIHBsYXRmb3JtCiAgICAgICAgIyBhbmQgaWYgc3ltbGlua3Mgc2hhbGwgYmUgcmVzb2x2ZWQuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBOb25lOgogICAgICAgICAgICBpZiBoYXNhdHRyKG9zLCAibHN0YXQiKSBhbmQgbm90IHNlbGYuZGVyZWZlcmVuY2U6CiAgICAgICAgICAgICAgICBzdGF0cmVzID0gb3MubHN0YXQobmFtZSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHN0YXRyZXMgPSBvcy5zdGF0KG5hbWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc3RhdHJlcyA9IG9zLmZzdGF0KGZpbGVvYmouZmlsZW5vKCkpCiAgICAgICAgbGlua25hbWUgPSAiIgoKICAgICAgICBzdG1kID0gc3RhdHJlcy5zdF9tb2RlCiAgICAgICAgaWYgc3RhdC5TX0lTUkVHKHN0bWQpOgogICAgICAgICAgICBpbm9kZSA9IChzdGF0cmVzLnN0X2lubywgc3RhdHJlcy5zdF9kZXYpCiAgICAgICAgICAgIGlmIGlub2RlIGluIHNlbGYuaW5vZGVzIGFuZCBub3Qgc2VsZi5kZXJlZmVyZW5jZToKICAgICAgICAgICAgICAgICMgSXMgaXQgYSBoYXJkbGluayB0byBhbiBhbHJlYWR5CiAgICAgICAgICAgICAgICAjIGFyY2hpdmVkIGZpbGU/CiAgICAgICAgICAgICAgICB0eXBlID0gTE5LVFlQRQogICAgICAgICAgICAgICAgbGlua25hbWUgPSBzZWxmLmlub2Rlc1tpbm9kZV0KICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgVGhlIGlub2RlIGlzIGFkZGVkIG9ubHkgaWYgaXRzIHZhbGlkLgogICAgICAgICAgICAgICAgIyBGb3Igd2luMzIgaXQgaXMgYWx3YXlzIDAuCiAgICAgICAgICAgICAgICB0eXBlID0gUkVHVFlQRQogICAgICAgICAgICAgICAgaWYgaW5vZGVbMF06CiAgICAgICAgICAgICAgICAgICAgc2VsZi5pbm9kZXNbaW5vZGVdID0gYXJjbmFtZQogICAgICAgIGVsaWYgc3RhdC5TX0lTRElSKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gRElSVFlQRQogICAgICAgICAgICBpZiBhcmNuYW1lWy0xOl0gIT0gIi8iOgogICAgICAgICAgICAgICAgYXJjbmFtZSArPSAiLyIKICAgICAgICBlbGlmIHN0YXQuU19JU0ZJRk8oc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBGSUZPVFlQRQogICAgICAgIGVsaWYgc3RhdC5TX0lTTE5LKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gU1lNVFlQRQogICAgICAgICAgICBsaW5rbmFtZSA9IG9zLnJlYWRsaW5rKG5hbWUpCiAgICAgICAgZWxpZiBzdGF0LlNfSVNDSFIoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBDSFJUWVBFCiAgICAgICAgZWxpZiBzdGF0LlNfSVNCTEsoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBCTEtUWVBFCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgIyBGaWxsIHRoZSBUYXJJbmZvIG9iamVjdCB3aXRoIGFsbAogICAgICAgICMgaW5mb3JtYXRpb24gd2UgY2FuIGdldC4KICAgICAgICB0YXJpbmZvLm5hbWUgID0gYXJjbmFtZQogICAgICAgIHRhcmluZm8ubW9kZSAgPSBzdG1kCiAgICAgICAgdGFyaW5mby51aWQgICA9IHN0YXRyZXMuc3RfdWlkCiAgICAgICAgdGFyaW5mby5naWQgICA9IHN0YXRyZXMuc3RfZ2lkCiAgICAgICAgaWYgc3RhdC5TX0lTRElSKHN0bWQpOgogICAgICAgICAgICAjIEZvciBhIGRpcmVjdG9yeSwgdGhlIHNpemUgbXVzdCBiZSAwCiAgICAgICAgICAgIHRhcmluZm8uc2l6ZSAgPSAwCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mby5zaXplID0gc3RhdHJlcy5zdF9zaXplCiAgICAgICAgdGFyaW5mby5tdGltZSA9IHN0YXRyZXMuc3RfbXRpbWUKICAgICAgICB0YXJpbmZvLnR5cGUgID0gdHlwZQogICAgICAgIHRhcmluZm8ubGlua25hbWUgPSBsaW5rbmFtZQogICAgICAgIGlmIHB3ZDoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mby51bmFtZSA9IHB3ZC5nZXRwd3VpZCh0YXJpbmZvLnVpZClbMF0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgIGlmIGdycDoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mby5nbmFtZSA9IGdycC5nZXRncmdpZCh0YXJpbmZvLmdpZClbMF0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICBpZiB0eXBlIGluIChDSFJUWVBFLCBCTEtUWVBFKToKICAgICAgICAgICAgaWYgaGFzYXR0cihvcywgIm1ham9yIikgYW5kIGhhc2F0dHIob3MsICJtaW5vciIpOgogICAgICAgICAgICAgICAgdGFyaW5mby5kZXZtYWpvciA9IG9zLm1ham9yKHN0YXRyZXMuc3RfcmRldikKICAgICAgICAgICAgICAgIHRhcmluZm8uZGV2bWlub3IgPSBvcy5taW5vcihzdGF0cmVzLnN0X3JkZXYpCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBkZWYgbGlzdChzZWxmLCB2ZXJib3NlPVRydWUpOgogICAgICAgICIiIlByaW50IGEgdGFibGUgb2YgY29udGVudHMgdG8gc3lzLnN0ZG91dC4gSWYgYHZlcmJvc2UnIGlzIEZhbHNlLCBvbmx5CiAgICAgICAgICAgdGhlIG5hbWVzIG9mIHRoZSBtZW1iZXJzIGFyZSBwcmludGVkLiBJZiBpdCBpcyBUcnVlLCBhbiBgbHMgLWwnLWxpa2UKICAgICAgICAgICBvdXRwdXQgaXMgcHJvZHVjZWQuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soKQoKICAgICAgICBmb3IgdGFyaW5mbyBpbiBzZWxmOgogICAgICAgICAgICBpZiB2ZXJib3NlOgogICAgICAgICAgICAgICAgcHJpbnQgZmlsZW1vZGUodGFyaW5mby5tb2RlKSwKICAgICAgICAgICAgICAgIHByaW50ICIlcy8lcyIgJSAodGFyaW5mby51bmFtZSBvciB0YXJpbmZvLnVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mby5nbmFtZSBvciB0YXJpbmZvLmdpZCksCiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzY2hyKCkgb3IgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICIlMTBzIiAlICgiJWQsJWQiIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJSAodGFyaW5mby5kZXZtYWpvciwgdGFyaW5mby5kZXZtaW5vcikpLAogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBwcmludCAiJTEwZCIgJSB0YXJpbmZvLnNpemUsCiAgICAgICAgICAgICAgICBwcmludCAiJWQtJTAyZC0lMDJkICUwMmQ6JTAyZDolMDJkIiBcCiAgICAgICAgICAgICAgICAgICAgICAlIHRpbWUubG9jYWx0aW1lKHRhcmluZm8ubXRpbWUpWzo2XSwKCiAgICAgICAgICAgIHByaW50IHRhcmluZm8ubmFtZSwKCiAgICAgICAgICAgIGlmIHZlcmJvc2U6CiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIi0+IiwgdGFyaW5mby5saW5rbmFtZSwKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNsbmsoKToKICAgICAgICAgICAgICAgICAgICBwcmludCAibGluayB0byIsIHRhcmluZm8ubGlua25hbWUsCiAgICAgICAgICAgIHByaW50CgogICAgZGVmIGFkZChzZWxmLCBuYW1lLCBhcmNuYW1lPU5vbmUsIHJlY3Vyc2l2ZT1UcnVlKToKICAgICAgICAiIiJBZGQgdGhlIGZpbGUgYG5hbWUnIHRvIHRoZSBhcmNoaXZlLiBgbmFtZScgbWF5IGJlIGFueSB0eXBlIG9mIGZpbGUKICAgICAgICAgICAoZGlyZWN0b3J5LCBmaWZvLCBzeW1ib2xpYyBsaW5rLCBldGMuKS4gSWYgZ2l2ZW4sIGBhcmNuYW1lJwogICAgICAgICAgIHNwZWNpZmllcyBhbiBhbHRlcm5hdGl2ZSBuYW1lIGZvciB0aGUgZmlsZSBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAgICBEaXJlY3RvcmllcyBhcmUgYWRkZWQgcmVjdXJzaXZlbHkgYnkgZGVmYXVsdC4gVGhpcyBjYW4gYmUgYXZvaWRlZCBieQogICAgICAgICAgIHNldHRpbmcgYHJlY3Vyc2l2ZScgdG8gRmFsc2UuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soImF3IikKCiAgICAgICAgaWYgYXJjbmFtZSBpcyBOb25lOgogICAgICAgICAgICBhcmNuYW1lID0gbmFtZQoKICAgICAgICAjIFNraXAgaWYgc29tZWJvZHkgdHJpZXMgdG8gYXJjaGl2ZSB0aGUgYXJjaGl2ZS4uLgogICAgICAgIGlmIHNlbGYubmFtZSBpcyBub3QgTm9uZSBcCiAgICAgICAgICAgIGFuZCBvcy5wYXRoLmFic3BhdGgobmFtZSkgPT0gb3MucGF0aC5hYnNwYXRoKHNlbGYubmFtZSk6CiAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogU2tpcHBlZCAlciIgJSBuYW1lKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgIyBTcGVjaWFsIGNhc2U6IFRoZSB1c2VyIHdhbnRzIHRvIGFkZCB0aGUgY3VycmVudAogICAgICAgICMgd29ya2luZyBkaXJlY3RvcnkuCiAgICAgICAgaWYgbmFtZSA9PSAiLiI6CiAgICAgICAgICAgIGlmIHJlY3Vyc2l2ZToKICAgICAgICAgICAgICAgIGlmIGFyY25hbWUgPT0gIi4iOgogICAgICAgICAgICAgICAgICAgIGFyY25hbWUgPSAiIgogICAgICAgICAgICAgICAgZm9yIGYgaW4gb3MubGlzdGRpcigiLiIpOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYWRkKGYsIG9zLnBhdGguam9pbihhcmNuYW1lLCBmKSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIHNlbGYuX2RiZygxLCBuYW1lKQoKICAgICAgICAjIENyZWF0ZSBhIFRhckluZm8gb2JqZWN0IGZyb20gdGhlIGZpbGUuCiAgICAgICAgdGFyaW5mbyA9IHNlbGYuZ2V0dGFyaW5mbyhuYW1lLCBhcmNuYW1lKQoKICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogVW5zdXBwb3J0ZWQgdHlwZSAlciIgJSBuYW1lKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgIyBBcHBlbmQgdGhlIHRhciBoZWFkZXIgYW5kIGRhdGEgdG8gdGhlIGFyY2hpdmUuCiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpOgogICAgICAgICAgICBmID0gZmlsZShuYW1lLCAicmIiKQogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbywgZikKICAgICAgICAgICAgZi5jbG9zZSgpCgogICAgICAgIGlmIHRhcmluZm8udHlwZSBpbiAoTE5LVFlQRSwgU1lNVFlQRSwgRklGT1RZUEUsIENIUlRZUEUsIEJMS1RZUEUpOgogICAgICAgICAgICB0YXJpbmZvLnNpemUgPSAwTAogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbykKCiAgICAgICAgaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbykKICAgICAgICAgICAgaWYgcmVjdXJzaXZlOgogICAgICAgICAgICAgICAgZm9yIGYgaW4gb3MubGlzdGRpcihuYW1lKToKICAgICAgICAgICAgICAgICAgICBzZWxmLmFkZChvcy5wYXRoLmpvaW4obmFtZSwgZiksIG9zLnBhdGguam9pbihhcmNuYW1lLCBmKSkKCiAgICBkZWYgYWRkZmlsZShzZWxmLCB0YXJpbmZvLCBmaWxlb2JqPU5vbmUpOgogICAgICAgICIiIkFkZCB0aGUgVGFySW5mbyBvYmplY3QgYHRhcmluZm8nIHRvIHRoZSBhcmNoaXZlLiBJZiBgZmlsZW9iaicgaXMKICAgICAgICAgICBnaXZlbiwgdGFyaW5mby5zaXplIGJ5dGVzIGFyZSByZWFkIGZyb20gaXQgYW5kIGFkZGVkIHRvIHRoZSBhcmNoaXZlLgogICAgICAgICAgIFlvdSBjYW4gY3JlYXRlIFRhckluZm8gb2JqZWN0cyB1c2luZyBnZXR0YXJpbmZvKCkuCiAgICAgICAgICAgT24gV2luZG93cyBwbGF0Zm9ybXMsIGBmaWxlb2JqJyBzaG91bGQgYWx3YXlzIGJlIG9wZW5lZCB3aXRoIG1vZGUKICAgICAgICAgICAncmInIHRvIGF2b2lkIGlycml0YXRpb24gYWJvdXQgdGhlIGZpbGUgc2l6ZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiYXciKQoKICAgICAgICB0YXJpbmZvLm5hbWUgPSBub3JtcGF0aCh0YXJpbmZvLm5hbWUpCiAgICAgICAgaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICAjIGRpcmVjdG9yaWVzIHNob3VsZCBlbmQgd2l0aCAnLycKICAgICAgICAgICAgdGFyaW5mby5uYW1lICs9ICIvIgoKICAgICAgICBpZiB0YXJpbmZvLmxpbmtuYW1lOgogICAgICAgICAgICB0YXJpbmZvLmxpbmtuYW1lID0gbm9ybXBhdGgodGFyaW5mby5saW5rbmFtZSkKCiAgICAgICAgaWYgdGFyaW5mby5zaXplID4gTUFYU0laRV9NRU1CRVI6CiAgICAgICAgICAgIGlmIHNlbGYucG9zaXg6CiAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAiZmlsZSBpcyB0b28gbGFyZ2UgKD49IDggR0IpIgogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5fZGJnKDIsICJ0YXJmaWxlOiBDcmVhdGVkIEdOVSB0YXIgbGFyZ2VmaWxlIGhlYWRlciIpCgoKICAgICAgICBpZiBsZW4odGFyaW5mby5saW5rbmFtZSkgPiBMRU5HVEhfTElOSzoKICAgICAgICAgICAgaWYgc2VsZi5wb3NpeDoKICAgICAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJsaW5rbmFtZSBpcyB0b28gbG9uZyAoPiVkKSIgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJSAoTEVOR1RIX0xJTkspCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLl9jcmVhdGVfZ251bG9uZyh0YXJpbmZvLmxpbmtuYW1lLCBHTlVUWVBFX0xPTkdMSU5LKQogICAgICAgICAgICAgICAgdGFyaW5mby5saW5rbmFtZSA9IHRhcmluZm8ubGlua25hbWVbOkxFTkdUSF9MSU5LIC0xXQogICAgICAgICAgICAgICAgc2VsZi5fZGJnKDIsICJ0YXJmaWxlOiBDcmVhdGVkIEdOVSB0YXIgZXh0ZW5zaW9uIExPTkdMSU5LIikKCiAgICAgICAgaWYgbGVuKHRhcmluZm8ubmFtZSkgPiBMRU5HVEhfTkFNRToKICAgICAgICAgICAgaWYgc2VsZi5wb3NpeDoKICAgICAgICAgICAgICAgIHByZWZpeCA9IHRhcmluZm8ubmFtZVs6TEVOR1RIX1BSRUZJWCArIDFdCiAgICAgICAgICAgICAgICB3aGlsZSBwcmVmaXggYW5kIHByZWZpeFstMV0gIT0gIi8iOgogICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IHByZWZpeFs6LTFdCgogICAgICAgICAgICAgICAgbmFtZSA9IHRhcmluZm8ubmFtZVtsZW4ocHJlZml4KTpdCiAgICAgICAgICAgICAgICBwcmVmaXggPSBwcmVmaXhbOi0xXQoKICAgICAgICAgICAgICAgIGlmIG5vdCBwcmVmaXggb3IgbGVuKG5hbWUpID4gTEVOR1RIX05BTUU6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgIm5hbWUgaXMgdG9vIGxvbmcgKD4lZCkiIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAlIChMRU5HVEhfTkFNRSkKCiAgICAgICAgICAgICAgICB0YXJpbmZvLm5hbWUgICA9IG5hbWUKICAgICAgICAgICAgICAgIHRhcmluZm8ucHJlZml4ID0gcHJlZml4CiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLl9jcmVhdGVfZ251bG9uZyh0YXJpbmZvLm5hbWUsIEdOVVRZUEVfTE9OR05BTUUpCiAgICAgICAgICAgICAgICB0YXJpbmZvLm5hbWUgPSB0YXJpbmZvLm5hbWVbOkxFTkdUSF9OQU1FIC0gMV0KICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogQ3JlYXRlZCBHTlUgdGFyIGV4dGVuc2lvbiBMT05HTkFNRSIpCgogICAgICAgIHNlbGYuZmlsZW9iai53cml0ZSh0YXJpbmZvLnRvYnVmKCkpCiAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCgogICAgICAgICMgSWYgdGhlcmUncyBkYXRhIHRvIGZvbGxvdywgYXBwZW5kIGl0LgogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgIGNvcHlmaWxlb2JqKGZpbGVvYmosIHNlbGYuZmlsZW9iaiwgdGFyaW5mby5zaXplKQogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZCh0YXJpbmZvLnNpemUsIEJMT0NLU0laRSkKICAgICAgICAgICAgaWYgcmVtYWluZGVyID4gMDoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShOVUwgKiAoQkxPQ0tTSVpFIC0gcmVtYWluZGVyKSkKICAgICAgICAgICAgICAgIGJsb2NrcyArPSAxCiAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IGJsb2NrcyAqIEJMT0NLU0laRQoKICAgICAgICBzZWxmLm1lbWJlcnMuYXBwZW5kKHRhcmluZm8pCgogICAgZGVmIGV4dHJhY3Qoc2VsZiwgbWVtYmVyLCBwYXRoPSIiKToKICAgICAgICAiIiJFeHRyYWN0IGEgbWVtYmVyIGZyb20gdGhlIGFyY2hpdmUgdG8gdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnksCiAgICAgICAgICAgdXNpbmcgaXRzIGZ1bGwgbmFtZS4gSXRzIGZpbGUgaW5mb3JtYXRpb24gaXMgZXh0cmFjdGVkIGFzIGFjY3VyYXRlbHkKICAgICAgICAgICBhcyBwb3NzaWJsZS4gYG1lbWJlcicgbWF5IGJlIGEgZmlsZW5hbWUgb3IgYSBUYXJJbmZvIG9iamVjdC4gWW91IGNhbgogICAgICAgICAgIHNwZWNpZnkgYSBkaWZmZXJlbnQgZGlyZWN0b3J5IHVzaW5nIGBwYXRoJy4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiciIpCgogICAgICAgIGlmIGlzaW5zdGFuY2UobWVtYmVyLCBUYXJJbmZvKToKICAgICAgICAgICAgdGFyaW5mbyA9IG1lbWJlcgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLmdldG1lbWJlcihtZW1iZXIpCgogICAgICAgICMgUHJlcGFyZSB0aGUgbGluayB0YXJnZXQgZm9yIG1ha2VsaW5rKCkuCiAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpOgogICAgICAgICAgICB0YXJpbmZvLl9saW5rX3RhcmdldCA9IG9zLnBhdGguam9pbihwYXRoLCB0YXJpbmZvLmxpbmtuYW1lKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYuX2V4dHJhY3RfbWVtYmVyKHRhcmluZm8sIG9zLnBhdGguam9pbihwYXRoLCB0YXJpbmZvLm5hbWUpKQogICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICBpZiBzZWxmLmVycm9ybGV2ZWwgPiAwOgogICAgICAgICAgICAgICAgcmFpc2UKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGlmIGUuZmlsZW5hbWUgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzIiAlIGUuc3RyZXJyb3IpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMgJXIiICUgKGUuc3RyZXJyb3IsIGUuZmlsZW5hbWUpKQogICAgICAgIGV4Y2VwdCBFeHRyYWN0RXJyb3IsIGU6CiAgICAgICAgICAgIGlmIHNlbGYuZXJyb3JsZXZlbCA+IDE6CiAgICAgICAgICAgICAgICByYWlzZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyIgJSBlKQoKICAgIGRlZiBleHRyYWN0ZmlsZShzZWxmLCBtZW1iZXIpOgogICAgICAgICIiIkV4dHJhY3QgYSBtZW1iZXIgZnJvbSB0aGUgYXJjaGl2ZSBhcyBhIGZpbGUgb2JqZWN0LiBgbWVtYmVyJyBtYXkgYmUKICAgICAgICAgICBhIGZpbGVuYW1lIG9yIGEgVGFySW5mbyBvYmplY3QuIElmIGBtZW1iZXInIGlzIGEgcmVndWxhciBmaWxlLCBhCiAgICAgICAgICAgZmlsZS1saWtlIG9iamVjdCBpcyByZXR1cm5lZC4gSWYgYG1lbWJlcicgaXMgYSBsaW5rLCBhIGZpbGUtbGlrZQogICAgICAgICAgIG9iamVjdCBpcyBjb25zdHJ1Y3RlZCBmcm9tIHRoZSBsaW5rJ3MgdGFyZ2V0LiBJZiBgbWVtYmVyJyBpcyBub25lIG9mCiAgICAgICAgICAgdGhlIGFib3ZlLCBOb25lIGlzIHJldHVybmVkLgogICAgICAgICAgIFRoZSBmaWxlLWxpa2Ugb2JqZWN0IGlzIHJlYWQtb25seSBhbmQgcHJvdmlkZXMgdGhlIGZvbGxvd2luZwogICAgICAgICAgIG1ldGhvZHM6IHJlYWQoKSwgcmVhZGxpbmUoKSwgcmVhZGxpbmVzKCksIHNlZWsoKSBhbmQgdGVsbCgpCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soInIiKQoKICAgICAgICBpZiBpc2luc3RhbmNlKG1lbWJlciwgVGFySW5mbyk6CiAgICAgICAgICAgIHRhcmluZm8gPSBtZW1iZXIKICAgICAgICBlbHNlOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5nZXRtZW1iZXIobWVtYmVyKQoKICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmplY3Qoc2VsZiwgdGFyaW5mbykKCiAgICAgICAgZWxpZiB0YXJpbmZvLnR5cGUgbm90IGluIFNVUFBPUlRFRF9UWVBFUzoKICAgICAgICAgICAgIyBJZiBhIG1lbWJlcidzIHR5cGUgaXMgdW5rbm93biwgaXQgaXMgdHJlYXRlZCBhcyBhCiAgICAgICAgICAgICMgcmVndWxhciBmaWxlLgogICAgICAgICAgICByZXR1cm4gc2VsZi5maWxlb2JqZWN0KHNlbGYsIHRhcmluZm8pCgogICAgICAgIGVsaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShzZWxmLmZpbGVvYmosIF9TdHJlYW0pOgogICAgICAgICAgICAgICAgIyBBIHNtYWxsIGJ1dCB1Z2x5IHdvcmthcm91bmQgZm9yIHRoZSBjYXNlIHRoYXQgc29tZW9uZSB0cmllcwogICAgICAgICAgICAgICAgIyB0byBleHRyYWN0IGEgKHN5bSlsaW5rIGFzIGEgZmlsZS1vYmplY3QgZnJvbSBhIG5vbi1zZWVrYWJsZQogICAgICAgICAgICAgICAgIyBzdHJlYW0gb2YgdGFyIGJsb2Nrcy4KICAgICAgICAgICAgICAgIHJhaXNlIFN0cmVhbUVycm9yLCAiY2Fubm90IGV4dHJhY3QgKHN5bSlsaW5rIGFzIGZpbGUgb2JqZWN0IgogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyBBIChzeW0pbGluaydzIGZpbGUgb2JqZWN0IGlzIGl0J3MgdGFyZ2V0J3MgZmlsZSBvYmplY3QuCiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5leHRyYWN0ZmlsZShzZWxmLl9nZXRtZW1iZXIodGFyaW5mby5saW5rbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICAjIElmIHRoZXJlJ3Mgbm8gZGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIG1lbWJlciAoZGlyZWN0b3J5LCBjaHJkZXYsCiAgICAgICAgICAgICMgYmxrZGV2LCBldGMuKSwgcmV0dXJuIE5vbmUgaW5zdGVhZCBvZiBhIGZpbGUgb2JqZWN0LgogICAgICAgICAgICByZXR1cm4gTm9uZQoKICAgIGRlZiBfZXh0cmFjdF9tZW1iZXIoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiRXh0cmFjdCB0aGUgVGFySW5mbyBvYmplY3QgdGFyaW5mbyB0byBhIHBoeXNpY2FsCiAgICAgICAgICAgZmlsZSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICAjIEZldGNoIHRoZSBUYXJJbmZvIG9iamVjdCBmb3IgdGhlIGdpdmVuIG5hbWUKICAgICAgICAjIGFuZCBidWlsZCB0aGUgZGVzdGluYXRpb24gcGF0aG5hbWUsIHJlcGxhY2luZwogICAgICAgICMgZm9yd2FyZCBzbGFzaGVzIHRvIHBsYXRmb3JtIHNwZWNpZmljIHNlcGFyYXRvcnMuCiAgICAgICAgaWYgdGFyZ2V0cGF0aFstMTpdID09ICIvIjoKICAgICAgICAgICAgdGFyZ2V0cGF0aCA9IHRhcmdldHBhdGhbOi0xXQogICAgICAgIHRhcmdldHBhdGggPSBvcy5wYXRoLm5vcm1wYXRoKHRhcmdldHBhdGgpCgogICAgICAgICMgQ3JlYXRlIGFsbCB1cHBlciBkaXJlY3Rvcmllcy4KICAgICAgICB1cHBlcmRpcnMgPSBvcy5wYXRoLmRpcm5hbWUodGFyZ2V0cGF0aCkKICAgICAgICBpZiB1cHBlcmRpcnMgYW5kIG5vdCBvcy5wYXRoLmV4aXN0cyh1cHBlcmRpcnMpOgogICAgICAgICAgICB0aSA9IFRhckluZm8oKQogICAgICAgICAgICB0aS5uYW1lICA9IHVwcGVyZGlycwogICAgICAgICAgICB0aS50eXBlICA9IERJUlRZUEUKICAgICAgICAgICAgdGkubW9kZSAgPSAwNzc3CiAgICAgICAgICAgIHRpLm10aW1lID0gdGFyaW5mby5tdGltZQogICAgICAgICAgICB0aS51aWQgICA9IHRhcmluZm8udWlkCiAgICAgICAgICAgIHRpLmdpZCAgID0gdGFyaW5mby5naWQKICAgICAgICAgICAgdGkudW5hbWUgPSB0YXJpbmZvLnVuYW1lCiAgICAgICAgICAgIHRpLmduYW1lID0gdGFyaW5mby5nbmFtZQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWxmLl9leHRyYWN0X21lbWJlcih0aSwgdGkubmFtZSkKICAgICAgICAgICAgZXhjZXB0OgogICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICBpZiB0YXJpbmZvLmlzbG5rKCkgb3IgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgIiVzIC0+ICVzIiAlICh0YXJpbmZvLm5hbWUsIHRhcmluZm8ubGlua25hbWUpKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuX2RiZygxLCB0YXJpbmZvLm5hbWUpCgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKICAgICAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICBzZWxmLm1ha2VkaXIodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNmaWZvKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWZpZm8odGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNjaHIoKSBvciB0YXJpbmZvLmlzYmxrKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWRldih0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgc2VsZi5tYWtlbGluayh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby50eXBlIG5vdCBpbiBTVVBQT1JURURfVFlQRVM6CiAgICAgICAgICAgIHNlbGYubWFrZXVua25vd24odGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLm1ha2VmaWxlKHRhcmluZm8sIHRhcmdldHBhdGgpCgogICAgICAgIHNlbGYuY2hvd24odGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBpZiBub3QgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBzZWxmLmNobW9kKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgICAgIHNlbGYudXRpbWUodGFyaW5mbywgdGFyZ2V0cGF0aCkKCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgQmVsb3cgYXJlIHRoZSBkaWZmZXJlbnQgZmlsZSBtZXRob2RzLiBUaGV5IGFyZSBjYWxsZWQgdmlhCiAgICAjIF9leHRyYWN0X21lbWJlcigpIHdoZW4gZXh0cmFjdCgpIGlzIGNhbGxlZC4gVGhleSBjYW4gYmUgcmVwbGFjZWQgaW4gYQogICAgIyBzdWJjbGFzcyB0byBpbXBsZW1lbnQgb3RoZXIgZnVuY3Rpb25hbGl0eS4KCiAgICBkZWYgbWFrZWRpcihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZGlyZWN0b3J5IGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIHRyeToKICAgICAgICAgICAgb3MubWtkaXIodGFyZ2V0cGF0aCkKICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgaWYgZS5lcnJubyAhPSBlcnJuby5FRVhJU1Q6CiAgICAgICAgICAgICAgICByYWlzZQoKICAgIGRlZiBtYWtlZmlsZShzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlsZSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBzb3VyY2UgPSBzZWxmLmV4dHJhY3RmaWxlKHRhcmluZm8pCiAgICAgICAgdGFyZ2V0ID0gZmlsZSh0YXJnZXRwYXRoLCAid2IiKQogICAgICAgIGNvcHlmaWxlb2JqKHNvdXJjZSwgdGFyZ2V0KQogICAgICAgIHNvdXJjZS5jbG9zZSgpCiAgICAgICAgdGFyZ2V0LmNsb3NlKCkKCiAgICBkZWYgbWFrZXVua25vd24oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGZpbGUgZnJvbSBhIFRhckluZm8gb2JqZWN0IHdpdGggYW4gdW5rbm93biB0eXBlCiAgICAgICAgICAgYXQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLm1ha2VmaWxlKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiBVbmtub3duIGZpbGUgdHlwZSAlciwgIiBcCiAgICAgICAgICAgICAgICAgICAgICJleHRyYWN0ZWQgYXMgcmVndWxhciBmaWxlLiIgJSB0YXJpbmZvLnR5cGUpCgogICAgZGVmIG1ha2VmaWZvKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBmaWZvIGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIGlmIGhhc2F0dHIob3MsICJta2ZpZm8iKToKICAgICAgICAgICAgb3MubWtmaWZvKHRhcmdldHBhdGgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yLCAiZmlmbyBub3Qgc3VwcG9ydGVkIGJ5IHN5c3RlbSIKCiAgICBkZWYgbWFrZWRldihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgY2hhcmFjdGVyIG9yIGJsb2NrIGRldmljZSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBpZiBub3QgaGFzYXR0cihvcywgIm1rbm9kIikgb3Igbm90IGhhc2F0dHIob3MsICJtYWtlZGV2Iik6CiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvciwgInNwZWNpYWwgZGV2aWNlcyBub3Qgc3VwcG9ydGVkIGJ5IHN5c3RlbSIKCiAgICAgICAgbW9kZSA9IHRhcmluZm8ubW9kZQogICAgICAgIGlmIHRhcmluZm8uaXNibGsoKToKICAgICAgICAgICAgbW9kZSB8PSBzdGF0LlNfSUZCTEsKICAgICAgICBlbHNlOgogICAgICAgICAgICBtb2RlIHw9IHN0YXQuU19JRkNIUgoKICAgICAgICBvcy5ta25vZCh0YXJnZXRwYXRoLCBtb2RlLAogICAgICAgICAgICAgICAgIG9zLm1ha2VkZXYodGFyaW5mby5kZXZtYWpvciwgdGFyaW5mby5kZXZtaW5vcikpCgogICAgZGVmIG1ha2VsaW5rKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSAoc3ltYm9saWMpIGxpbmsgY2FsbGVkIHRhcmdldHBhdGguIElmIGl0IGNhbm5vdCBiZSBjcmVhdGVkCiAgICAgICAgICAocGxhdGZvcm0gbGltaXRhdGlvbiksIHdlIHRyeSB0byBtYWtlIGEgY29weSBvZiB0aGUgcmVmZXJlbmNlZCBmaWxlCiAgICAgICAgICBpbnN0ZWFkIG9mIGEgbGluay4KICAgICAgICAiIiIKICAgICAgICBsaW5rcGF0aCA9IHRhcmluZm8ubGlua25hbWUKICAgICAgICB0cnk6CiAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgICAgIG9zLnN5bWxpbmsobGlua3BhdGgsIHRhcmdldHBhdGgpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIFNlZSBleHRyYWN0KCkuCiAgICAgICAgICAgICAgICBvcy5saW5rKHRhcmluZm8uX2xpbmtfdGFyZ2V0LCB0YXJnZXRwYXRoKQogICAgICAgIGV4Y2VwdCBBdHRyaWJ1dGVFcnJvcjoKICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICAgICAgbGlua3BhdGggPSBvcy5wYXRoLmpvaW4ob3MucGF0aC5kaXJuYW1lKHRhcmluZm8ubmFtZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5rcGF0aCkKICAgICAgICAgICAgICAgIGxpbmtwYXRoID0gbm9ybXBhdGgobGlua3BhdGgpCgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWxmLl9leHRyYWN0X21lbWJlcihzZWxmLmdldG1lbWJlcihsaW5rcGF0aCksIHRhcmdldHBhdGgpCiAgICAgICAgICAgIGV4Y2VwdCAoRW52aXJvbm1lbnRFcnJvciwgS2V5RXJyb3IpLCBlOgogICAgICAgICAgICAgICAgbGlua3BhdGggPSBvcy5wYXRoLm5vcm1wYXRoKGxpbmtwYXRoKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHNodXRpbC5jb3B5MihsaW5rcGF0aCwgdGFyZ2V0cGF0aCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIElPRXJyb3IsICJsaW5rIGNvdWxkIG5vdCBiZSBjcmVhdGVkIgoKICAgIGRlZiBjaG93bihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJTZXQgb3duZXIgb2YgdGFyZ2V0cGF0aCBhY2NvcmRpbmcgdG8gdGFyaW5mby4KICAgICAgICAiIiIKICAgICAgICBpZiBwd2QgYW5kIGhhc2F0dHIob3MsICJnZXRldWlkIikgYW5kIG9zLmdldGV1aWQoKSA9PSAwOgogICAgICAgICAgICAjIFdlIGhhdmUgdG8gYmUgcm9vdCB0byBkbyBzby4KICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgZyA9IGdycC5nZXRncm5hbSh0YXJpbmZvLmduYW1lKVsyXQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgZyA9IGdycC5nZXRncmdpZCh0YXJpbmZvLmdpZClbMl0KICAgICAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgICAgICBnID0gb3MuZ2V0Z2lkKCkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdSA9IHB3ZC5nZXRwd25hbSh0YXJpbmZvLnVuYW1lKVsyXQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgdSA9IHB3ZC5nZXRwd3VpZCh0YXJpbmZvLnVpZClbMl0KICAgICAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgICAgICB1ID0gb3MuZ2V0dWlkKCkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpIGFuZCBoYXNhdHRyKG9zLCAibGNob3duIik6CiAgICAgICAgICAgICAgICAgICAgb3MubGNob3duKHRhcmdldHBhdGgsIHUsIGcpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIGlmIHN5cy5wbGF0Zm9ybSAhPSAib3MyZW14IjoKICAgICAgICAgICAgICAgICAgICAgICAgb3MuY2hvd24odGFyZ2V0cGF0aCwgdSwgZykKICAgICAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IsICJjb3VsZCBub3QgY2hhbmdlIG93bmVyIgoKICAgIGRlZiBjaG1vZChzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJTZXQgZmlsZSBwZXJtaXNzaW9ucyBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgogICAgICAgICIiIgogICAgICAgIGlmIGhhc2F0dHIob3MsICdjaG1vZCcpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBvcy5jaG1vZCh0YXJnZXRwYXRoLCB0YXJpbmZvLm1vZGUpCiAgICAgICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yLCAiY291bGQgbm90IGNoYW5nZSBtb2RlIgoKICAgIGRlZiB1dGltZShzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJTZXQgbW9kaWZpY2F0aW9uIHRpbWUgb2YgdGFyZ2V0cGF0aCBhY2NvcmRpbmcgdG8gdGFyaW5mby4KICAgICAgICAiIiIKICAgICAgICBpZiBub3QgaGFzYXR0cihvcywgJ3V0aW1lJyk6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAid2luMzIiIGFuZCB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgICMgQWNjb3JkaW5nIHRvIG1zZG4ubWljcm9zb2Z0LmNvbSwgaXQgaXMgYW4gZXJyb3IgKEVBQ0NFUykKICAgICAgICAgICAgIyB0byB1c2UgdXRpbWUoKSBvbiBkaXJlY3Rvcmllcy4KICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgdHJ5OgogICAgICAgICAgICBvcy51dGltZSh0YXJnZXRwYXRoLCAodGFyaW5mby5tdGltZSwgdGFyaW5mby5tdGltZSkpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvciwgImNvdWxkIG5vdCBjaGFuZ2UgbW9kaWZpY2F0aW9uIHRpbWUiCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgZGVmIG5leHQoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IG1lbWJlciBvZiB0aGUgYXJjaGl2ZSBhcyBhIFRhckluZm8gb2JqZWN0LCB3aGVuCiAgICAgICAgICAgVGFyRmlsZSBpcyBvcGVuZWQgZm9yIHJlYWRpbmcuIFJldHVybiBOb25lIGlmIHRoZXJlIGlzIG5vIG1vcmUKICAgICAgICAgICBhdmFpbGFibGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soInJhIikKICAgICAgICBpZiBzZWxmLmZpcnN0bWVtYmVyIGlzIG5vdCBOb25lOgogICAgICAgICAgICBtID0gc2VsZi5maXJzdG1lbWJlcgogICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gTm9uZQogICAgICAgICAgICByZXR1cm4gbQoKICAgICAgICAjIFJlYWQgdGhlIG5leHQgYmxvY2suCiAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5vZmZzZXQpCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQogICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mbyA9IFRhckluZm8uZnJvbWJ1ZihidWYpCiAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgaWYgc2VsZi5pZ25vcmVfemVyb3M6CiAgICAgICAgICAgICAgICAgICAgaWYgYnVmLmNvdW50KE5VTCkgPT0gQkxPQ0tTSVpFOgogICAgICAgICAgICAgICAgICAgICAgICBhZGogPSAiZW1wdHkiCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgYWRqID0gImludmFsaWQiCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDIsICIweCVYOiAlcyBibG9jayIgJSAoc2VsZi5vZmZzZXQsIGFkaikpCiAgICAgICAgICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgIyBCbG9jayBpcyBlbXB0eSBvciB1bnJlYWRhYmxlLgogICAgICAgICAgICAgICAgICAgIGlmIHNlbGYub2Zmc2V0ID09IDA6CiAgICAgICAgICAgICAgICAgICAgICAgICMgSWYgdGhlIGZpcnN0IGJsb2NrIGlzIGludmFsaWQuIFRoYXQgZG9lcyBub3QKICAgICAgICAgICAgICAgICAgICAgICAgIyBsb29rIGxpa2UgYSB0YXIgYXJjaGl2ZSB3ZSBjYW4gaGFuZGxlLgogICAgICAgICAgICAgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IsImVtcHR5LCB1bnJlYWRhYmxlIG9yIGNvbXByZXNzZWQgZmlsZSIKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgICAgICBicmVhawoKICAgICAgICAjIFdlIHNob3VsZG4ndCByZWx5IG9uIHRoaXMgY2hlY2tzdW0sIGJlY2F1c2Ugc29tZSB0YXIgcHJvZ3JhbXMKICAgICAgICAjIGNhbGN1bGF0ZSBpdCBkaWZmZXJlbnRseSBhbmQgaXQgaXMgbWVyZWx5IHZhbGlkYXRpbmcgdGhlCiAgICAgICAgIyBoZWFkZXIgYmxvY2suIFdlIGNvdWxkIGp1c3QgYXMgd2VsbCBza2lwIHRoaXMgcGFydCwgd2hpY2ggd291bGQKICAgICAgICAjIGhhdmUgYSBzbGlnaHQgZWZmZWN0IG9uIHBlcmZvcm1hbmNlLi4uCiAgICAgICAgaWYgdGFyaW5mby5jaGtzdW0gIT0gY2FsY19jaGtzdW0oYnVmKToKICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiBCYWQgQ2hlY2tzdW0gJXIiICUgdGFyaW5mby5uYW1lKQoKICAgICAgICAjIFNldCB0aGUgVGFySW5mbyBvYmplY3QncyBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gb2YgdGhlCiAgICAgICAgIyBUYXJGaWxlIGFuZCBzZXQgc2VsZi5vZmZzZXQgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBkYXRhIGJsb2NrcwogICAgICAgICMgc2hvdWxkIGJlZ2luLgogICAgICAgIHRhcmluZm8ub2Zmc2V0ID0gc2VsZi5vZmZzZXQKICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKCiAgICAgICAgIyBDaGVjayBpZiB0aGUgVGFySW5mbyBvYmplY3QgaGFzIGEgdHlwZWZsYWcgZm9yIHdoaWNoIGEgY2FsbGJhY2sKICAgICAgICAjIG1ldGhvZCBpcyByZWdpc3RlcmVkIGluIHRoZSBUWVBFX01FVEguIElmIHNvLCB0aGVuIGNhbGwgaXQuCiAgICAgICAgaWYgdGFyaW5mby50eXBlIGluIHNlbGYuVFlQRV9NRVRIOgogICAgICAgICAgICByZXR1cm4gc2VsZi5UWVBFX01FVEhbdGFyaW5mby50eXBlXShzZWxmLCB0YXJpbmZvKQoKICAgICAgICB0YXJpbmZvLm9mZnNldF9kYXRhID0gc2VsZi5vZmZzZXQKICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCkgb3IgdGFyaW5mby50eXBlIG5vdCBpbiBTVVBQT1JURURfVFlQRVM6CiAgICAgICAgICAgICMgU2tpcCB0aGUgZm9sbG93aW5nIGRhdGEgYmxvY2tzLgogICAgICAgICAgICBzZWxmLm9mZnNldCArPSBzZWxmLl9ibG9jayh0YXJpbmZvLnNpemUpCgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKSBhbmQgdGFyaW5mby5uYW1lWzotMV0gPT0gIi8iOgogICAgICAgICAgICAjIHNvbWUgb2xkIHRhciBwcm9ncmFtcyBkb24ndCBrbm93IERJUlRZUEUKICAgICAgICAgICAgdGFyaW5mby50eXBlID0gRElSVFlQRQoKICAgICAgICBzZWxmLm1lbWJlcnMuYXBwZW5kKHRhcmluZm8pCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgQmVsb3cgYXJlIHNvbWUgbWV0aG9kcyB3aGljaCBhcmUgY2FsbGVkIGZvciBzcGVjaWFsIHR5cGVmbGFncyBpbiB0aGUKICAgICMgbmV4dCgpIG1ldGhvZCwgZS5nLiBmb3IgdW53cmFwcGluZyBHTlUgbG9uZ25hbWUvbG9uZ2xpbmsgYmxvY2tzLiBUaGV5CiAgICAjIGFyZSByZWdpc3RlcmVkIGluIFRZUEVfTUVUSCBiZWxvdy4gWW91IGNhbiByZWdpc3RlciB5b3VyIG93biBtZXRob2RzCiAgICAjIHdpdGggdGhpcyBtYXBwaW5nLgogICAgIyBBIHJlZ2lzdGVyZWQgbWV0aG9kIGlzIGNhbGxlZCB3aXRoIGEgVGFySW5mbyBvYmplY3QgYXMgb25seSBhcmd1bWVudC4KICAgICMKICAgICMgRHVyaW5nIGl0cyBleGVjdXRpb24gdGhlIG1ldGhvZCBNVVNUIHBlcmZvcm0gdGhlIGZvbGxvd2luZyB0YXNrczoKICAgICMgMS4gc2V0IHRhcmluZm8ub2Zmc2V0X2RhdGEgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBkYXRhIGJsb2NrcyBiZWdpbiwKICAgICMgICAgaWYgdGhlcmUgaXMgZGF0YSB0byBmb2xsb3cuCiAgICAjIDIuIHNldCBzZWxmLm9mZnNldCB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIG5leHQgbWVtYmVyJ3MgaGVhZGVyIHdpbGwKICAgICMgICAgYmVnaW4uCiAgICAjIDMuIGFwcGVuZCB0aGUgdGFyaW5mbyBvYmplY3QgdG8gc2VsZi5tZW1iZXJzLCBpZiBpdCBpcyBzdXBwb3NlZCB0byBhcHBlYXIKICAgICMgICAgYXMgYSBtZW1iZXIgb2YgdGhlIFRhckZpbGUgb2JqZWN0LgogICAgIyA0LiByZXR1cm4gdGFyaW5mbyBvciBhbm90aGVyIHZhbGlkIFRhckluZm8gb2JqZWN0LgoKICAgIGRlZiBwcm9jX2dudWxvbmcoc2VsZiwgdGFyaW5mbyk6CiAgICAgICAgIiIiRXZhbHVhdGUgdGhlIGJsb2NrcyB0aGF0IGhvbGQgYSBHTlUgbG9uZ25hbWUKICAgICAgICAgICBvciBsb25nbGluayBtZW1iZXIuCiAgICAgICAgIiIiCiAgICAgICAgYnVmID0gIiIKICAgICAgICBjb3VudCA9IHRhcmluZm8uc2l6ZQogICAgICAgIHdoaWxlIGNvdW50ID4gMDoKICAgICAgICAgICAgYmxvY2sgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCiAgICAgICAgICAgIGJ1ZiArPSBibG9jawogICAgICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKICAgICAgICAgICAgY291bnQgLT0gQkxPQ0tTSVpFCgogICAgICAgICMgRmV0Y2ggdGhlIG5leHQgaGVhZGVyCiAgICAgICAgbmV4dCA9IHNlbGYubmV4dCgpCgogICAgICAgIG5leHQub2Zmc2V0ID0gdGFyaW5mby5vZmZzZXQKICAgICAgICBpZiB0YXJpbmZvLnR5cGUgPT0gR05VVFlQRV9MT05HTkFNRToKICAgICAgICAgICAgbmV4dC5uYW1lID0gbnRzKGJ1ZikKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSA9PSBHTlVUWVBFX0xPTkdMSU5LOgogICAgICAgICAgICBuZXh0LmxpbmtuYW1lID0gbnRzKGJ1ZikKCiAgICAgICAgcmV0dXJuIG5leHQKCiAgICBkZWYgcHJvY19zcGFyc2Uoc2VsZiwgdGFyaW5mbyk6CiAgICAgICAgIiIiQW5hbHl6ZSBhIEdOVSBzcGFyc2UgaGVhZGVyIHBsdXMgZXh0cmEgaGVhZGVycy4KICAgICAgICAiIiIKICAgICAgICBidWYgPSB0YXJpbmZvLnRvYnVmKCkKICAgICAgICBzcCA9IF9yaW5nYnVmZmVyKCkKICAgICAgICBwb3MgPSAzODYKICAgICAgICBsYXN0cG9zID0gMEwKICAgICAgICByZWFscG9zID0gMEwKICAgICAgICAjIFRoZXJlIGFyZSA0IHBvc3NpYmxlIHNwYXJzZSBzdHJ1Y3RzIGluIHRoZQogICAgICAgICMgZmlyc3QgaGVhZGVyLgogICAgICAgIGZvciBpIGluIHhyYW5nZSg0KToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb2Zmc2V0ID0gaW50KGJ1Zltwb3M6cG9zICsgMTJdLCA4KQogICAgICAgICAgICAgICAgbnVtYnl0ZXMgPSBpbnQoYnVmW3BvcyArIDEyOnBvcyArIDI0XSwgOCkKICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBpZiBvZmZzZXQgPiBsYXN0cG9zOgogICAgICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9mZnNldCAtIGxhc3Rwb3MpKQogICAgICAgICAgICBzcC5hcHBlbmQoX2RhdGEob2Zmc2V0LCBudW1ieXRlcywgcmVhbHBvcykpCiAgICAgICAgICAgIHJlYWxwb3MgKz0gbnVtYnl0ZXMKICAgICAgICAgICAgbGFzdHBvcyA9IG9mZnNldCArIG51bWJ5dGVzCiAgICAgICAgICAgIHBvcyArPSAyNAoKICAgICAgICBpc2V4dGVuZGVkID0gb3JkKGJ1Zls0ODJdKQogICAgICAgIG9yaWdzaXplID0gaW50KGJ1Zls0ODM6NDk1XSwgOCkKCiAgICAgICAgIyBJZiB0aGUgaXNleHRlbmRlZCBmbGFnIGlzIGdpdmVuLAogICAgICAgICMgdGhlcmUgYXJlIGV4dHJhIGhlYWRlcnMgdG8gcHJvY2Vzcy4KICAgICAgICB3aGlsZSBpc2V4dGVuZGVkID09IDE6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCiAgICAgICAgICAgIHBvcyA9IDAKICAgICAgICAgICAgZm9yIGkgaW4geHJhbmdlKDIxKToKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBpbnQoYnVmW3Bvczpwb3MgKyAxMl0sIDgpCiAgICAgICAgICAgICAgICAgICAgbnVtYnl0ZXMgPSBpbnQoYnVmW3BvcyArIDEyOnBvcyArIDI0XSwgOCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBpZiBvZmZzZXQgPiBsYXN0cG9zOgogICAgICAgICAgICAgICAgICAgIHNwLmFwcGVuZChfaG9sZShsYXN0cG9zLCBvZmZzZXQgLSBsYXN0cG9zKSkKICAgICAgICAgICAgICAgIHNwLmFwcGVuZChfZGF0YShvZmZzZXQsIG51bWJ5dGVzLCByZWFscG9zKSkKICAgICAgICAgICAgICAgIHJlYWxwb3MgKz0gbnVtYnl0ZXMKICAgICAgICAgICAgICAgIGxhc3Rwb3MgPSBvZmZzZXQgKyBudW1ieXRlcwogICAgICAgICAgICAgICAgcG9zICs9IDI0CiAgICAgICAgICAgIGlzZXh0ZW5kZWQgPSBvcmQoYnVmWzUwNF0pCgogICAgICAgIGlmIGxhc3Rwb3MgPCBvcmlnc2l6ZToKICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9yaWdzaXplIC0gbGFzdHBvcykpCgogICAgICAgIHRhcmluZm8uc3BhcnNlID0gc3AKCiAgICAgICAgdGFyaW5mby5vZmZzZXRfZGF0YSA9IHNlbGYub2Zmc2V0CiAgICAgICAgc2VsZi5vZmZzZXQgKz0gc2VsZi5fYmxvY2sodGFyaW5mby5zaXplKQogICAgICAgIHRhcmluZm8uc2l6ZSA9IG9yaWdzaXplCgogICAgICAgIHNlbGYubWVtYmVycy5hcHBlbmQodGFyaW5mbykKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgICMgVGhlIHR5cGUgbWFwcGluZyBmb3IgdGhlIG5leHQoKSBtZXRob2QuIFRoZSBrZXlzIGFyZSBzaW5nbGUgY2hhcmFjdGVyCiAgICAjIHN0cmluZ3MsIHRoZSB0eXBlZmxhZy4gVGhlIHZhbHVlcyBhcmUgbWV0aG9kcyB3aGljaCBhcmUgY2FsbGVkIHdoZW4KICAgICMgbmV4dCgpIGVuY291bnRlcnMgc3VjaCBhIHR5cGVmbGFnLgogICAgVFlQRV9NRVRIID0gewogICAgICAgIEdOVVRZUEVfTE9OR05BTUU6IHByb2NfZ251bG9uZywKICAgICAgICBHTlVUWVBFX0xPTkdMSU5LOiBwcm9jX2dudWxvbmcsCiAgICAgICAgR05VVFlQRV9TUEFSU0U6ICAgcHJvY19zcGFyc2UKICAgIH0KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgTGl0dGxlIGhlbHBlciBtZXRob2RzOgoKICAgIGRlZiBfYmxvY2soc2VsZiwgY291bnQpOgogICAgICAgICIiIlJvdW5kIHVwIGEgYnl0ZSBjb3VudCBieSBCTE9DS1NJWkUgYW5kIHJldHVybiBpdCwKICAgICAgICAgICBlLmcuIF9ibG9jayg4MzQpID0+IDEwMjQuCiAgICAgICAgIiIiCiAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QoY291bnQsIEJMT0NLU0laRSkKICAgICAgICBpZiByZW1haW5kZXI6CiAgICAgICAgICAgIGJsb2NrcyArPSAxCiAgICAgICAgcmV0dXJuIGJsb2NrcyAqIEJMT0NLU0laRQoKICAgIGRlZiBfZ2V0bWVtYmVyKHNlbGYsIG5hbWUsIHRhcmluZm89Tm9uZSk6CiAgICAgICAgIiIiRmluZCBhbiBhcmNoaXZlIG1lbWJlciBieSBuYW1lIGZyb20gYm90dG9tIHRvIHRvcC4KICAgICAgICAgICBJZiB0YXJpbmZvIGlzIGdpdmVuLCBpdCBpcyB1c2VkIGFzIHRoZSBzdGFydGluZyBwb2ludC4KICAgICAgICAiIiIKICAgICAgICAjIEVuc3VyZSB0aGF0IGFsbCBtZW1iZXJzIGhhdmUgYmVlbiBsb2FkZWQuCiAgICAgICAgbWVtYmVycyA9IHNlbGYuZ2V0bWVtYmVycygpCgogICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgZW5kID0gbGVuKG1lbWJlcnMpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZW5kID0gbWVtYmVycy5pbmRleCh0YXJpbmZvKQoKICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoZW5kIC0gMSwgLTEsIC0xKToKICAgICAgICAgICAgaWYgbmFtZSA9PSBtZW1iZXJzW2ldLm5hbWU6CiAgICAgICAgICAgICAgICByZXR1cm4gbWVtYmVyc1tpXQoKICAgIGRlZiBfbG9hZChzZWxmKToKICAgICAgICAiIiJSZWFkIHRocm91Z2ggdGhlIGVudGlyZSBhcmNoaXZlIGZpbGUgYW5kIGxvb2sgZm9yIHJlYWRhYmxlCiAgICAgICAgICAgbWVtYmVycy4KICAgICAgICAiIiIKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5uZXh0KCkKICAgICAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBzZWxmLl9sb2FkZWQgPSBUcnVlCgogICAgZGVmIF9jaGVjayhzZWxmLCBtb2RlPU5vbmUpOgogICAgICAgICIiIkNoZWNrIGlmIFRhckZpbGUgaXMgc3RpbGwgb3BlbiwgYW5kIGlmIHRoZSBvcGVyYXRpb24ncyBtb2RlCiAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gVGFyRmlsZSdzIG1vZGUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IsICIlcyBpcyBjbG9zZWQiICUgc2VsZi5fX2NsYXNzX18uX19uYW1lX18KICAgICAgICBpZiBtb2RlIGlzIG5vdCBOb25lIGFuZCBzZWxmLl9tb2RlIG5vdCBpbiBtb2RlOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yLCAiYmFkIG9wZXJhdGlvbiBmb3IgbW9kZSAlciIgJSBzZWxmLl9tb2RlCgogICAgZGVmIF9faXRlcl9fKHNlbGYpOgogICAgICAgICIiIlByb3ZpZGUgYW4gaXRlcmF0b3Igb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuX2xvYWRlZDoKICAgICAgICAgICAgcmV0dXJuIGl0ZXIoc2VsZi5tZW1iZXJzKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBUYXJJdGVyKHNlbGYpCgogICAgZGVmIF9jcmVhdGVfZ251bG9uZyhzZWxmLCBuYW1lLCB0eXBlKToKICAgICAgICAiIiJXcml0ZSBhIEdOVSBsb25nbmFtZS9sb25nbGluayBtZW1iZXIgdG8gdGhlIFRhckZpbGUuCiAgICAgICAgICAgSXQgY29uc2lzdHMgb2YgYW4gZXh0ZW5kZWQgdGFyIGhlYWRlciwgd2l0aCB0aGUgbGVuZ3RoCiAgICAgICAgICAgb2YgdGhlIGxvbmduYW1lIGFzIHNpemUsIGZvbGxvd2VkIGJ5IGRhdGEgYmxvY2tzLAogICAgICAgICAgIHdoaWNoIGNvbnRhaW4gdGhlIGxvbmduYW1lIGFzIGEgbnVsbCB0ZXJtaW5hdGVkIHN0cmluZy4KICAgICAgICAiIiIKICAgICAgICBuYW1lICs9IE5VTAoKICAgICAgICB0YXJpbmZvID0gVGFySW5mbygpCiAgICAgICAgdGFyaW5mby5uYW1lID0gIi4vLi9ATG9uZ0xpbmsiCiAgICAgICAgdGFyaW5mby50eXBlID0gdHlwZQogICAgICAgIHRhcmluZm8ubW9kZSA9IDAKICAgICAgICB0YXJpbmZvLnNpemUgPSBsZW4obmFtZSkKCiAgICAgICAgIyB3cml0ZSBleHRlbmRlZCBoZWFkZXIKICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUodGFyaW5mby50b2J1ZigpKQogICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQogICAgICAgICMgd3JpdGUgbmFtZSBibG9ja3MKICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUobmFtZSkKICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZCh0YXJpbmZvLnNpemUsIEJMT0NLU0laRSkKICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKEJMT0NLU0laRSAtIHJlbWFpbmRlcikpCiAgICAgICAgICAgIGJsb2NrcyArPSAxCiAgICAgICAgc2VsZi5vZmZzZXQgKz0gYmxvY2tzICogQkxPQ0tTSVpFCgogICAgZGVmIF9kYmcoc2VsZiwgbGV2ZWwsIG1zZyk6CiAgICAgICAgIiIiV3JpdGUgZGVidWdnaW5nIG91dHB1dCB0byBzeXMuc3RkZXJyLgogICAgICAgICIiIgogICAgICAgIGlmIGxldmVsIDw9IHNlbGYuZGVidWc6CiAgICAgICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsIG1zZwojIGNsYXNzIFRhckZpbGUKCmNsYXNzIFRhckl0ZXI6CiAgICAiIiJJdGVyYXRvciBDbGFzcy4KCiAgICAgICBmb3IgdGFyaW5mbyBpbiBUYXJGaWxlKC4uLik6CiAgICAgICAgICAgc3VpdGUuLi4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCB0YXJmaWxlKToKICAgICAgICAiIiJDb25zdHJ1Y3QgYSBUYXJJdGVyIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLnRhcmZpbGUgPSB0YXJmaWxlCiAgICBkZWYgX19pdGVyX18oc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIGl0ZXJhdG9yIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZgogICAgZGVmIG5leHQoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IGl0ZW0gdXNpbmcgVGFyRmlsZSdzIG5leHQoKSBtZXRob2QuCiAgICAgICAgICAgV2hlbiBhbGwgbWVtYmVycyBoYXZlIGJlZW4gcmVhZCwgc2V0IFRhckZpbGUgYXMgX2xvYWRlZC4KICAgICAgICAiIiIKICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJmaWxlLm5leHQoKQogICAgICAgIGlmIG5vdCB0YXJpbmZvOgogICAgICAgICAgICBzZWxmLnRhcmZpbGUuX2xvYWRlZCA9IFRydWUKICAgICAgICAgICAgcmFpc2UgU3RvcEl0ZXJhdGlvbgogICAgICAgIHJldHVybiB0YXJpbmZvCgojIEhlbHBlciBjbGFzc2VzIGZvciBzcGFyc2UgZmlsZSBzdXBwb3J0CmNsYXNzIF9zZWN0aW9uOgogICAgIiIiQmFzZSBjbGFzcyBmb3IgX2RhdGEgYW5kIF9ob2xlLgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgb2Zmc2V0LCBzaXplKToKICAgICAgICBzZWxmLm9mZnNldCA9IG9mZnNldAogICAgICAgIHNlbGYuc2l6ZSA9IHNpemUKICAgIGRlZiBfX2NvbnRhaW5zX18oc2VsZiwgb2Zmc2V0KToKICAgICAgICByZXR1cm4gc2VsZi5vZmZzZXQgPD0gb2Zmc2V0IDwgc2VsZi5vZmZzZXQgKyBzZWxmLnNpemUKCmNsYXNzIF9kYXRhKF9zZWN0aW9uKToKICAgICIiIlJlcHJlc2VudCBhIGRhdGEgc2VjdGlvbiBpbiBhIHNwYXJzZSBmaWxlLgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgb2Zmc2V0LCBzaXplLCByZWFscG9zKToKICAgICAgICBfc2VjdGlvbi5fX2luaXRfXyhzZWxmLCBvZmZzZXQsIHNpemUpCiAgICAgICAgc2VsZi5yZWFscG9zID0gcmVhbHBvcwoKY2xhc3MgX2hvbGUoX3NlY3Rpb24pOgogICAgIiIiUmVwcmVzZW50IGEgaG9sZSBzZWN0aW9uIGluIGEgc3BhcnNlIGZpbGUuCiAgICAiIiIKICAgIHBhc3MKCmNsYXNzIF9yaW5nYnVmZmVyKGxpc3QpOgogICAgIiIiUmluZ2J1ZmZlciBjbGFzcyB3aGljaCBpbmNyZWFzZXMgcGVyZm9ybWFuY2UKICAgICAgIG92ZXIgYSByZWd1bGFyIGxpc3QuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBzZWxmLmlkeCA9IDAKICAgIGRlZiBmaW5kKHNlbGYsIG9mZnNldCk6CiAgICAgICAgaWR4ID0gc2VsZi5pZHgKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBpdGVtID0gc2VsZltpZHhdCiAgICAgICAgICAgIGlmIG9mZnNldCBpbiBpdGVtOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgaWR4ICs9IDEKICAgICAgICAgICAgaWYgaWR4ID09IGxlbihzZWxmKToKICAgICAgICAgICAgICAgIGlkeCA9IDAKICAgICAgICAgICAgaWYgaWR4ID09IHNlbGYuaWR4OgogICAgICAgICAgICAgICAgIyBFbmQgb2YgRmlsZQogICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICBzZWxmLmlkeCA9IGlkeAogICAgICAgIHJldHVybiBpdGVtCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgemlwZmlsZSBjb21wYXRpYmxlIFRhckZpbGUgY2xhc3MKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpUQVJfUExBSU4gPSAwICAgICAgICAgICAjIHppcGZpbGUuWklQX1NUT1JFRApUQVJfR1pJUFBFRCA9IDggICAgICAgICAjIHppcGZpbGUuWklQX0RFRkxBVEVECmNsYXNzIFRhckZpbGVDb21wYXQ6CiAgICAiIiJUYXJGaWxlIGNsYXNzIGNvbXBhdGlibGUgd2l0aCBzdGFuZGFyZCBtb2R1bGUgemlwZmlsZSdzCiAgICAgICBaaXBGaWxlIGNsYXNzLgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZSwgbW9kZT0iciIsIGNvbXByZXNzaW9uPVRBUl9QTEFJTik6CiAgICAgICAgaWYgY29tcHJlc3Npb24gPT0gVEFSX1BMQUlOOgogICAgICAgICAgICBzZWxmLnRhcmZpbGUgPSBUYXJGaWxlLnRhcm9wZW4oZmlsZSwgbW9kZSkKICAgICAgICBlbGlmIGNvbXByZXNzaW9uID09IFRBUl9HWklQUEVEOgogICAgICAgICAgICBzZWxmLnRhcmZpbGUgPSBUYXJGaWxlLmd6b3BlbihmaWxlLCBtb2RlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJ1bmtub3duIGNvbXByZXNzaW9uIGNvbnN0YW50IgogICAgICAgIGlmIG1vZGVbMDoxXSA9PSAiciI6CiAgICAgICAgICAgIG1lbWJlcnMgPSBzZWxmLnRhcmZpbGUuZ2V0bWVtYmVycygpCiAgICAgICAgICAgIGZvciBpIGluIHhyYW5nZShsZW4obWVtYmVycykpOgogICAgICAgICAgICAgICAgbSA9IG1lbWJlcnNbaV0KICAgICAgICAgICAgICAgIG0uZmlsZW5hbWUgPSBtLm5hbWUKICAgICAgICAgICAgICAgIG0uZmlsZV9zaXplID0gbS5zaXplCiAgICAgICAgICAgICAgICBtLmRhdGVfdGltZSA9IHRpbWUuZ210aW1lKG0ubXRpbWUpWzo2XQogICAgZGVmIG5hbWVsaXN0KHNlbGYpOgogICAgICAgIHJldHVybiBtYXAobGFtYmRhIG06IG0ubmFtZSwgc2VsZi5pbmZvbGlzdCgpKQogICAgZGVmIGluZm9saXN0KHNlbGYpOgogICAgICAgIHJldHVybiBmaWx0ZXIobGFtYmRhIG06IG0udHlwZSBpbiBSRUdVTEFSX1RZUEVTLAogICAgICAgICAgICAgICAgICAgICAgc2VsZi50YXJmaWxlLmdldG1lbWJlcnMoKSkKICAgIGRlZiBwcmludGRpcihzZWxmKToKICAgICAgICBzZWxmLnRhcmZpbGUubGlzdCgpCiAgICBkZWYgdGVzdHppcChzZWxmKToKICAgICAgICByZXR1cm4KICAgIGRlZiBnZXRpbmZvKHNlbGYsIG5hbWUpOgogICAgICAgIHJldHVybiBzZWxmLnRhcmZpbGUuZ2V0bWVtYmVyKG5hbWUpCiAgICBkZWYgcmVhZChzZWxmLCBuYW1lKToKICAgICAgICByZXR1cm4gc2VsZi50YXJmaWxlLmV4dHJhY3RmaWxlKHNlbGYudGFyZmlsZS5nZXRtZW1iZXIobmFtZSkpLnJlYWQoKQogICAgZGVmIHdyaXRlKHNlbGYsIGZpbGVuYW1lLCBhcmNuYW1lPU5vbmUsIGNvbXByZXNzX3R5cGU9Tm9uZSk6CiAgICAgICAgc2VsZi50YXJmaWxlLmFkZChmaWxlbmFtZSwgYXJjbmFtZSkKICAgIGRlZiB3cml0ZXN0cihzZWxmLCB6aW5mbywgYnl0ZXMpOgogICAgICAgIHRyeToKICAgICAgICAgICAgZnJvbSBjU3RyaW5nSU8gaW1wb3J0IFN0cmluZ0lPCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICBmcm9tIFN0cmluZ0lPIGltcG9ydCBTdHJpbmdJTwogICAgICAgIGltcG9ydCBjYWxlbmRhcgogICAgICAgIHppbmZvLm5hbWUgPSB6aW5mby5maWxlbmFtZQogICAgICAgIHppbmZvLnNpemUgPSB6aW5mby5maWxlX3NpemUKICAgICAgICB6aW5mby5tdGltZSA9IGNhbGVuZGFyLnRpbWVnbSh6aW5mby5kYXRlX3RpbWUpCiAgICAgICAgc2VsZi50YXJmaWxlLmFkZGZpbGUoemluZm8sIFN0cmluZ0lPKGJ5dGVzKSkKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICBzZWxmLnRhcmZpbGUuY2xvc2UoKQojY2xhc3MgVGFyRmlsZUNvbXBhdAoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgZXhwb3J0ZWQgZnVuY3Rpb25zCiMtLS0tLS0tLS0tLS0tLS0tLS0tLQpkZWYgaXNfdGFyZmlsZShuYW1lKToKICAgICIiIlJldHVybiBUcnVlIGlmIG5hbWUgcG9pbnRzIHRvIGEgdGFyIGFyY2hpdmUgdGhhdCB3ZQogICAgICAgYXJlIGFibGUgdG8gaGFuZGxlLCBlbHNlIHJldHVybiBGYWxzZS4KICAgICIiIgogICAgdHJ5OgogICAgICAgIHQgPSBvcGVuKG5hbWUpCiAgICAgICAgdC5jbG9zZSgpCiAgICAgICAgcmV0dXJuIFRydWUKICAgIGV4Y2VwdCBUYXJFcnJvcjoKICAgICAgICByZXR1cm4gRmFsc2UKCm9wZW4gPSBUYXJGaWxlLm9wZW4K