IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMgLSotIGNvZGluZzogaXNvLTg4NTktMSAtKi0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlLnB5CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ29weXJpZ2h0IChDKSAyMDAyIExhcnMgR3VzdORiZWwgPGxhcnNAZ3VzdGFlYmVsLmRlPgojIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMKIyBQZXJtaXNzaW9uICBpcyAgaGVyZWJ5IGdyYW50ZWQsICBmcmVlICBvZiBjaGFyZ2UsICB0byAgYW55IHBlcnNvbgojIG9idGFpbmluZyBhICBjb3B5IG9mICB0aGlzIHNvZnR3YXJlICBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uCiMgZmlsZXMgICh0aGUgICJTb2Z0d2FyZSIpLCAgdG8gICBkZWFsICBpbiAgdGhlICBTb2Z0d2FyZSAgIHdpdGhvdXQKIyByZXN0cmljdGlvbiwgIGluY2x1ZGluZyAgd2l0aG91dCBsaW1pdGF0aW9uICB0aGUgIHJpZ2h0cyB0byAgdXNlLAojIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiMgY29waWVzICBvZiAgdGhlICBTb2Z0d2FyZSwgIGFuZCB0byAgcGVybWl0ICBwZXJzb25zICB0byAgd2hvbSB0aGUKIyBTb2Z0d2FyZSAgaXMgIGZ1cm5pc2hlZCAgdG8gIGRvICBzbywgIHN1YmplY3QgIHRvICB0aGUgIGZvbGxvd2luZwojIGNvbmRpdGlvbnM6CiMKIyBUaGUgYWJvdmUgY29weXJpZ2h0ICBub3RpY2UgYW5kIHRoaXMgIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsICBiZQojIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgojCiMgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyAgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSAgS0lORCwKIyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyAgQlVUIE5PVCBMSU1JVEVEIFRPICBUSEUgV0FSUkFOVElFUwojIE9GICBNRVJDSEFOVEFCSUxJVFksICBGSVRORVNTICAgRk9SICBBICBQQVJUSUNVTEFSICAgUFVSUE9TRSAgQU5ECiMgTk9OSU5GUklOR0VNRU5ULiAgSU4gIE5PICBFVkVOVCBTSEFMTCAgVEhFICBBVVRIT1JTICBPUiBDT1BZUklHSFQKIyBIT0xERVJTICBCRSBMSUFCTEUgIEZPUiBBTlkgIENMQUlNLCBEQU1BR0VTICBPUiBPVEhFUiAgTElBQklMSVRZLAojIFdIRVRIRVIgIElOIEFOICBBQ1RJT04gT0YgIENPTlRSQUNULCBUT1JUICBPUiBPVEhFUldJU0UsICBBUklTSU5HCiMgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUgojIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KIwoiIiJSZWFkIGZyb20gYW5kIHdyaXRlIHRvIHRhciBmb3JtYXQgYXJjaGl2ZXMuCiIiIgoKX192ZXJzaW9uX18gPSAiJFJldmlzaW9uJCIKIyAkU291cmNlJAoKdmVyc2lvbiAgICAgPSAiMC42LjQiCl9fYXV0aG9yX18gID0gIkxhcnMgR3VzdORiZWwgKGxhcnNAZ3VzdGFlYmVsLmRlKSIKX19kYXRlX18gICAgPSAiJERhdGUkIgpfX2N2c2lkX18gICA9ICIkSWQkIgpfX2NyZWRpdHNfXyA9ICJHdXN0YXZvIE5pZW1leWVyLCBOaWVscyBHdXN05GJlbCwgUmljaGFyZCBUb3duc2VuZC4iCgojLS0tLS0tLS0tCiMgSW1wb3J0cwojLS0tLS0tLS0tCmltcG9ydCBzeXMKaW1wb3J0IG9zCmltcG9ydCBzaHV0aWwKaW1wb3J0IHN0YXQKaW1wb3J0IGVycm5vCmltcG9ydCB0aW1lCmltcG9ydCBzdHJ1Y3QKCnRyeToKICAgIGltcG9ydCBncnAsIHB3ZApleGNlcHQgSW1wb3J0RXJyb3I6CiAgICBncnAgPSBwd2QgPSBOb25lCgojIGZyb20gdGFyZmlsZSBpbXBvcnQgKgpfX2FsbF9fID0gWyJUYXJGaWxlIiwgIlRhckluZm8iLCAiaXNfdGFyZmlsZSIsICJUYXJFcnJvciJdCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgdGFyIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk5VTCAgICAgICAgPSAiXDAiICAgICAgICAgICAgICAgIyB0aGUgbnVsbCBjaGFyYWN0ZXIKQkxPQ0tTSVpFICA9IDUxMiAgICAgICAgICAgICAgICAjIGxlbmd0aCBvZiBwcm9jZXNzaW5nIGJsb2NrcwpSRUNPUkRTSVpFID0gQkxPQ0tTSVpFICogMjAgICAgICMgbGVuZ3RoIG9mIHJlY29yZHMKTUFHSUMgICAgICA9ICJ1c3RhciIgICAgICAgICAgICAjIG1hZ2ljIHRhciBzdHJpbmcKVkVSU0lPTiAgICA9ICIwMCIgICAgICAgICAgICAgICAjIHZlcnNpb24gbnVtYmVyCgpMRU5HVEhfTkFNRSAgICA9IDEwMCAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBmaWxlbmFtZQpMRU5HVEhfTElOSyAgICA9IDEwMCAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBsaW5rbmFtZQpMRU5HVEhfUFJFRklYICA9IDE1NSAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgdGhlIHByZWZpeCBmaWVsZApNQVhTSVpFX01FTUJFUiA9IDA3Nzc3Nzc3Nzc3N0wgICMgbWF4aW11bSBzaXplIG9mIGEgZmlsZSAoMTEgb2N0YWwgZGlnaXRzKQoKUkVHVFlQRSAgPSAiMCIgICAgICAgICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZQpBUkVHVFlQRSA9ICJcMCIgICAgICAgICAgICAgICAgICMgcmVndWxhciBmaWxlCkxOS1RZUEUgID0gIjEiICAgICAgICAgICAgICAgICAgIyBsaW5rIChpbnNpZGUgdGFyZmlsZSkKU1lNVFlQRSAgPSAiMiIgICAgICAgICAgICAgICAgICAjIHN5bWJvbGljIGxpbmsKQ0hSVFlQRSAgPSAiMyIgICAgICAgICAgICAgICAgICAjIGNoYXJhY3RlciBzcGVjaWFsIGRldmljZQpCTEtUWVBFICA9ICI0IiAgICAgICAgICAgICAgICAgICMgYmxvY2sgc3BlY2lhbCBkZXZpY2UKRElSVFlQRSAgPSAiNSIgICAgICAgICAgICAgICAgICAjIGRpcmVjdG9yeQpGSUZPVFlQRSA9ICI2IiAgICAgICAgICAgICAgICAgICMgZmlmbyBzcGVjaWFsIGRldmljZQpDT05UVFlQRSA9ICI3IiAgICAgICAgICAgICAgICAgICMgY29udGlndW91cyBmaWxlCgpHTlVUWVBFX0xPTkdOQU1FID0gIkwiICAgICAgICAgICMgR05VIHRhciBleHRlbnNpb24gZm9yIGxvbmduYW1lcwpHTlVUWVBFX0xPTkdMSU5LID0gIksiICAgICAgICAgICMgR05VIHRhciBleHRlbnNpb24gZm9yIGxvbmdsaW5rCkdOVVRZUEVfU1BBUlNFICAgPSAiUyIgICAgICAgICAgIyBHTlUgdGFyIGV4dGVuc2lvbiBmb3Igc3BhcnNlIGZpbGUKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNVUFBPUlRFRF9UWVBFUyA9IChSRUdUWVBFLCBBUkVHVFlQRSwgTE5LVFlQRSwgICMgZmlsZSB0eXBlcyB0aGF0IHRhcmZpbGUKICAgICAgICAgICAgICAgICAgIFNZTVRZUEUsIERJUlRZUEUsIEZJRk9UWVBFLCAgIyBjYW4gY29wZSB3aXRoLgogICAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIENIUlRZUEUsIEJMS1RZUEUsCiAgICAgICAgICAgICAgICAgICBHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LLAogICAgICAgICAgICAgICAgICAgR05VVFlQRV9TUEFSU0UpCgpSRUdVTEFSX1RZUEVTID0gKFJFR1RZUEUsIEFSRUdUWVBFLCAgICAgICAgICAgICAjIGZpbGUgdHlwZXMgdGhhdCBzb21laG93CiAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIEdOVVRZUEVfU1BBUlNFKSAgICAgICMgcmVwcmVzZW50IHJlZ3VsYXIgZmlsZXMKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBCaXRzIHVzZWQgaW4gdGhlIG1vZGUgZmllbGQsIHZhbHVlcyBpbiBvY3RhbC4KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTX0lGTE5LID0gMDEyMDAwMCAgICAgICAgIyBzeW1ib2xpYyBsaW5rClNfSUZSRUcgPSAwMTAwMDAwICAgICAgICAjIHJlZ3VsYXIgZmlsZQpTX0lGQkxLID0gMDA2MDAwMCAgICAgICAgIyBibG9jayBkZXZpY2UKU19JRkRJUiA9IDAwNDAwMDAgICAgICAgICMgZGlyZWN0b3J5ClNfSUZDSFIgPSAwMDIwMDAwICAgICAgICAjIGNoYXJhY3RlciBkZXZpY2UKU19JRklGTyA9IDAwMTAwMDAgICAgICAgICMgZmlmbwoKVFNVSUQgICA9IDA0MDAwICAgICAgICAgICMgc2V0IFVJRCBvbiBleGVjdXRpb24KVFNHSUQgICA9IDAyMDAwICAgICAgICAgICMgc2V0IEdJRCBvbiBleGVjdXRpb24KVFNWVFggICA9IDAxMDAwICAgICAgICAgICMgcmVzZXJ2ZWQKClRVUkVBRCAgPSAwNDAwICAgICAgICAgICAjIHJlYWQgYnkgb3duZXIKVFVXUklURSA9IDAyMDAgICAgICAgICAgICMgd3JpdGUgYnkgb3duZXIKVFVFWEVDICA9IDAxMDAgICAgICAgICAgICMgZXhlY3V0ZS9zZWFyY2ggYnkgb3duZXIKVEdSRUFEICA9IDAwNDAgICAgICAgICAgICMgcmVhZCBieSBncm91cApUR1dSSVRFID0gMDAyMCAgICAgICAgICAgIyB3cml0ZSBieSBncm91cApUR0VYRUMgID0gMDAxMCAgICAgICAgICAgIyBleGVjdXRlL3NlYXJjaCBieSBncm91cApUT1JFQUQgID0gMDAwNCAgICAgICAgICAgIyByZWFkIGJ5IG90aGVyClRPV1JJVEUgPSAwMDAyICAgICAgICAgICAjIHdyaXRlIGJ5IG90aGVyClRPRVhFQyAgPSAwMDAxICAgICAgICAgICAjIGV4ZWN1dGUvc2VhcmNoIGJ5IG90aGVyCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU29tZSB1c2VmdWwgZnVuY3Rpb25zCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZGVmIG50cyhzKToKICAgICIiIkNvbnZlcnQgYSBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nIGJ1ZmZlciB0byBhIHB5dGhvbiBzdHJpbmcuCiAgICAiIiIKICAgIHJldHVybiBzLnNwbGl0KE5VTCwgMSlbMF0KCmRlZiBjYWxjX2Noa3N1bShidWYpOgogICAgIiIiQ2FsY3VsYXRlIHRoZSBjaGVja3N1bSBmb3IgYSBtZW1iZXIncyBoZWFkZXIuIEl0J3MgYSBzaW1wbGUgYWRkaXRpb24KICAgICAgIG9mIGFsbCBieXRlcywgdHJlYXRpbmcgdGhlIGNoa3N1bSBmaWVsZCBhcyBpZiBmaWxsZWQgd2l0aCBzcGFjZXMuCiAgICAgICBidWYgaXMgYSA1MTIgYnl0ZSBsb25nIHN0cmluZyBidWZmZXIgd2hpY2ggaG9sZHMgdGhlIGhlYWRlci4KICAgICIiIgogICAgY2hrID0gMjU2ICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBjaGtzdW0gZmllbGQgaXMgdHJlYXRlZCBhcyBibGFua3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNvIHRoZSBpbml0aWFsIHZhbHVlIGlzIDggKiBvcmQoIiAiKQogICAgZm9yIGMgaW4gYnVmWzoxNDhdOiBjaGsgKz0gb3JkKGMpICAgIyBzdW0gdXAgYWxsIGJ5dGVzIGJlZm9yZSBjaGtzdW0KICAgIGZvciBjIGluIGJ1ZlsxNTY6XTogY2hrICs9IG9yZChjKSAgICMgc3VtIHVwIGFsbCBieXRlcyBhZnRlciBjaGtzdW0KICAgIHJldHVybiBjaGsKCmRlZiBjb3B5ZmlsZW9iaihzcmMsIGRzdCwgbGVuZ3RoPU5vbmUpOgogICAgIiIiQ29weSBsZW5ndGggYnl0ZXMgZnJvbSBmaWxlb2JqIHNyYyB0byBmaWxlb2JqIGRzdC4KICAgICAgIElmIGxlbmd0aCBpcyBOb25lLCBjb3B5IHRoZSBlbnRpcmUgY29udGVudC4KICAgICIiIgogICAgaWYgbGVuZ3RoID09IDA6CiAgICAgICAgcmV0dXJuCiAgICBpZiBsZW5ndGggaXMgTm9uZToKICAgICAgICBzaHV0aWwuY29weWZpbGVvYmooc3JjLCBkc3QpCiAgICAgICAgcmV0dXJuCgogICAgQlVGU0laRSA9IDE2ICogMTAyNAogICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QobGVuZ3RoLCBCVUZTSVpFKQogICAgZm9yIGIgaW4geHJhbmdlKGJsb2Nrcyk6CiAgICAgICAgYnVmID0gc3JjLnJlYWQoQlVGU0laRSkKICAgICAgICBpZiBsZW4oYnVmKSA8IEJVRlNJWkU6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IsICJlbmQgb2YgZmlsZSByZWFjaGVkIgogICAgICAgIGRzdC53cml0ZShidWYpCgogICAgaWYgcmVtYWluZGVyICE9IDA6CiAgICAgICAgYnVmID0gc3JjLnJlYWQocmVtYWluZGVyKQogICAgICAgIGlmIGxlbihidWYpIDwgcmVtYWluZGVyOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yLCAiZW5kIG9mIGZpbGUgcmVhY2hlZCIKICAgICAgICBkc3Qud3JpdGUoYnVmKQogICAgcmV0dXJuCgpmaWxlbW9kZV90YWJsZSA9ICgKICAgIChTX0lGTE5LLCAibCIsCiAgICAgU19JRlJFRywgIi0iLAogICAgIFNfSUZCTEssICJiIiwKICAgICBTX0lGRElSLCAiZCIsCiAgICAgU19JRkNIUiwgImMiLAogICAgIFNfSUZJRk8sICJwIiksCiAgICAoVFVSRUFELCAgInIiKSwKICAgIChUVVdSSVRFLCAidyIpLAogICAgKFRVRVhFQywgICJ4IiwgVFNVSUQsICJTIiwgVFVFWEVDfFRTVUlELCAicyIpLAogICAgKFRHUkVBRCwgICJyIiksCiAgICAoVEdXUklURSwgInciKSwKICAgIChUR0VYRUMsICAieCIsIFRTR0lELCAiUyIsIFRHRVhFQ3xUU0dJRCwgInMiKSwKICAgIChUT1JFQUQsICAiciIpLAogICAgKFRPV1JJVEUsICJ3IiksCiAgICAoVE9FWEVDLCAgIngiLCBUU1ZUWCwgIlQiLCBUT0VYRUN8VFNWVFgsICJ0IikpCgpkZWYgZmlsZW1vZGUobW9kZSk6CiAgICAiIiJDb252ZXJ0IGEgZmlsZSdzIG1vZGUgdG8gYSBzdHJpbmcgb2YgdGhlIGZvcm0KICAgICAgIC1yd3hyd3hyd3guCiAgICAgICBVc2VkIGJ5IFRhckZpbGUubGlzdCgpCiAgICAiIiIKICAgIHMgPSAiIgogICAgZm9yIHQgaW4gZmlsZW1vZGVfdGFibGU6CiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgaWYgbW9kZSAmIHRbMF0gPT0gdFswXToKICAgICAgICAgICAgICAgIHMgKz0gdFsxXQogICAgICAgICAgICBlbGlmIGxlbih0KSA+IDI6CiAgICAgICAgICAgICAgICB0ID0gdFsyOl0KICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzICs9ICItIgogICAgICAgICAgICBicmVhawogICAgcmV0dXJuIHMKCmlmIG9zLnNlcCAhPSAiLyI6CiAgICBub3JtcGF0aCA9IGxhbWJkYSBwYXRoOiBvcy5wYXRoLm5vcm1wYXRoKHBhdGgpLnJlcGxhY2Uob3Muc2VwLCAiLyIpCmVsc2U6CiAgICBub3JtcGF0aCA9IG9zLnBhdGgubm9ybXBhdGgKCmNsYXNzIFRhckVycm9yKEV4Y2VwdGlvbik6CiAgICAiIiJCYXNlIGV4Y2VwdGlvbi4iIiIKICAgIHBhc3MKY2xhc3MgRXh0cmFjdEVycm9yKFRhckVycm9yKToKICAgICIiIkdlbmVyYWwgZXhjZXB0aW9uIGZvciBleHRyYWN0IGVycm9ycy4iIiIKICAgIHBhc3MKY2xhc3MgUmVhZEVycm9yKFRhckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgdW5yZWFkYmxlIHRhciBhcmNoaXZlcy4iIiIKICAgIHBhc3MKY2xhc3MgQ29tcHJlc3Npb25FcnJvcihUYXJFcnJvcik6CiAgICAiIiJFeGNlcHRpb24gZm9yIHVuYXZhaWxhYmxlIGNvbXByZXNzaW9uIG1ldGhvZHMuIiIiCiAgICBwYXNzCmNsYXNzIFN0cmVhbUVycm9yKFRhckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgdW5zdXBwb3J0ZWQgb3BlcmF0aW9ucyBvbiBzdHJlYW0tbGlrZSBUYXJGaWxlcy4iIiIKICAgIHBhc3MKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBpbnRlcm5hbCBzdHJlYW0gaW50ZXJmYWNlCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY2xhc3MgX0xvd0xldmVsRmlsZToKICAgICIiIkxvdy1sZXZlbCBmaWxlIG9iamVjdC4gU3VwcG9ydHMgcmVhZGluZyBhbmQgd3JpdGluZy4KICAgICAgIEl0IGlzIHVzZWQgaW5zdGVhZCBvZiBhIHJlZ3VsYXIgZmlsZSBvYmplY3QgZm9yIHN0cmVhbWluZwogICAgICAgYWNjZXNzLgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIG1vZGUpOgogICAgICAgIG1vZGUgPSB7CiAgICAgICAgICAgICJyIjogb3MuT19SRE9OTFksCiAgICAgICAgICAgICJ3Ijogb3MuT19XUk9OTFkgfCBvcy5PX0NSRUFUIHwgb3MuT19UUlVOQywKICAgICAgICB9W21vZGVdCiAgICAgICAgaWYgaGFzYXR0cihvcywgIk9fQklOQVJZIik6CiAgICAgICAgICAgIG1vZGUgfD0gb3MuT19CSU5BUlkKICAgICAgICBzZWxmLmZkID0gb3Mub3BlbihuYW1lLCBtb2RlKQoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICBvcy5jbG9zZShzZWxmLmZkKQoKICAgIGRlZiByZWFkKHNlbGYsIHNpemUpOgogICAgICAgIHJldHVybiBvcy5yZWFkKHNlbGYuZmQsIHNpemUpCgogICAgZGVmIHdyaXRlKHNlbGYsIHMpOgogICAgICAgIG9zLndyaXRlKHNlbGYuZmQsIHMpCgpjbGFzcyBfU3RyZWFtOgogICAgIiIiQ2xhc3MgdGhhdCBzZXJ2ZXMgYXMgYW4gYWRhcHRlciBiZXR3ZWVuIFRhckZpbGUgYW5kCiAgICAgICBhIHN0cmVhbS1saWtlIG9iamVjdC4gIFRoZSBzdHJlYW0tbGlrZSBvYmplY3Qgb25seQogICAgICAgbmVlZHMgdG8gaGF2ZSBhIHJlYWQoKSBvciB3cml0ZSgpIG1ldGhvZCBhbmQgaXMgYWNjZXNzZWQKICAgICAgIGJsb2Nrd2lzZS4gIFVzZSBvZiBnemlwIG9yIGJ6aXAyIGNvbXByZXNzaW9uIGlzIHBvc3NpYmxlLgogICAgICAgQSBzdHJlYW0tbGlrZSBvYmplY3QgY291bGQgYmUgZm9yIGV4YW1wbGU6IHN5cy5zdGRpbiwKICAgICAgIHN5cy5zdGRvdXQsIGEgc29ja2V0LCBhIHRhcGUgZGV2aWNlIGV0Yy4KCiAgICAgICBfU3RyZWFtIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgb25seSBpbnRlcm5hbGx5LgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIG1vZGUsIHR5cGUsIGZpbGVvYmosIGJ1ZnNpemUpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIF9TdHJlYW0gb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgaWYgZmlsZW9iaiBpcyBOb25lOgogICAgICAgICAgICBmaWxlb2JqID0gX0xvd0xldmVsRmlsZShuYW1lLCBtb2RlKQogICAgICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gRmFsc2UKCiAgICAgICAgc2VsZi5uYW1lICAgID0gbmFtZSBvciAiIgogICAgICAgIHNlbGYubW9kZSAgICA9IG1vZGUKICAgICAgICBzZWxmLnR5cGUgICAgPSB0eXBlCiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagogICAgICAgIHNlbGYuYnVmc2l6ZSA9IGJ1ZnNpemUKICAgICAgICBzZWxmLmJ1ZiAgICAgPSAiIgogICAgICAgIHNlbGYucG9zICAgICA9IDBMCiAgICAgICAgc2VsZi5jbG9zZWQgID0gRmFsc2UKCiAgICAgICAgaWYgdHlwZSA9PSAiZ3oiOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgemxpYgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yLCAiemxpYiBtb2R1bGUgaXMgbm90IGF2YWlsYWJsZSIKICAgICAgICAgICAgc2VsZi56bGliID0gemxpYgogICAgICAgICAgICBzZWxmLmNyYyA9IHpsaWIuY3JjMzIoIiIpCiAgICAgICAgICAgIGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICAgICAgc2VsZi5faW5pdF9yZWFkX2d6KCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2luaXRfd3JpdGVfZ3ooKQoKICAgICAgICBpZiB0eXBlID09ICJiejIiOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgYnoyCiAgICAgICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgICAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IsICJiejIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiCiAgICAgICAgICAgIGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICAgICAgc2VsZi5kYnVmID0gIiIKICAgICAgICAgICAgICAgIHNlbGYuY21wID0gYnoyLkJaMkRlY29tcHJlc3NvcigpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLmNtcCA9IGJ6Mi5CWjJDb21wcmVzc29yKCkKCiAgICBkZWYgX19kZWxfXyhzZWxmKToKICAgICAgICBpZiBub3Qgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHNlbGYuY2xvc2UoKQoKICAgIGRlZiBfaW5pdF93cml0ZV9neihzZWxmKToKICAgICAgICAiIiJJbml0aWFsaXplIGZvciB3cml0aW5nIHdpdGggZ3ppcCBjb21wcmVzc2lvbi4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmNtcCA9IHNlbGYuemxpYi5jb21wcmVzc29iaig5LCBzZWxmLnpsaWIuREVGTEFURUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLXNlbGYuemxpYi5NQVhfV0JJVFMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56bGliLkRFRl9NRU1fTEVWRUwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCkKICAgICAgICB0aW1lc3RhbXAgPSBzdHJ1Y3QucGFjaygiPEwiLCBsb25nKHRpbWUudGltZSgpKSkKICAgICAgICBzZWxmLl9fd3JpdGUoIlwwMzdcMjEzXDAxMFwwMTAlc1wwMDJcMzc3IiAlIHRpbWVzdGFtcCkKICAgICAgICBpZiBzZWxmLm5hbWUuZW5kc3dpdGgoIi5neiIpOgogICAgICAgICAgICBzZWxmLm5hbWUgPSBzZWxmLm5hbWVbOi0zXQogICAgICAgIHNlbGYuX193cml0ZShzZWxmLm5hbWUgKyBOVUwpCgogICAgZGVmIHdyaXRlKHNlbGYsIHMpOgogICAgICAgICIiIldyaXRlIHN0cmluZyBzIHRvIHRoZSBzdHJlYW0uCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi50eXBlID09ICJneiI6CiAgICAgICAgICAgIHNlbGYuY3JjID0gc2VsZi56bGliLmNyYzMyKHMsIHNlbGYuY3JjKQogICAgICAgIHNlbGYucG9zICs9IGxlbihzKQogICAgICAgIGlmIHNlbGYudHlwZSAhPSAidGFyIjoKICAgICAgICAgICAgcyA9IHNlbGYuY21wLmNvbXByZXNzKHMpCiAgICAgICAgc2VsZi5fX3dyaXRlKHMpCgogICAgZGVmIF9fd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgIiIiV3JpdGUgc3RyaW5nIHMgdG8gdGhlIHN0cmVhbSBpZiBhIHdob2xlIG5ldyBibG9jawogICAgICAgICAgIGlzIHJlYWR5IHRvIGJlIHdyaXR0ZW4uCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5idWYgKz0gcwogICAgICAgIHdoaWxlIGxlbihzZWxmLmJ1ZikgPiBzZWxmLmJ1ZnNpemU6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzZWxmLmJ1Zls6c2VsZi5idWZzaXplXSkKICAgICAgICAgICAgc2VsZi5idWYgPSBzZWxmLmJ1ZltzZWxmLmJ1ZnNpemU6XQoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICAiIiJDbG9zZSB0aGUgX1N0cmVhbSBvYmplY3QuIE5vIG9wZXJhdGlvbiBzaG91bGQgYmUKICAgICAgICAgICBkb25lIG9uIGl0IGFmdGVyd2FyZHMuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInciIGFuZCBzZWxmLmJ1ZjoKICAgICAgICAgICAgaWYgc2VsZi50eXBlICE9ICJ0YXIiOgogICAgICAgICAgICAgICAgc2VsZi5idWYgKz0gc2VsZi5jbXAuZmx1c2goKQogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWYpCiAgICAgICAgICAgIHNlbGYuYnVmID0gIiIKICAgICAgICAgICAgaWYgc2VsZi50eXBlID09ICJneiI6CiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc3RydWN0LnBhY2soIjxsIiwgc2VsZi5jcmMpKQogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHN0cnVjdC5wYWNrKCI8TCIsIHNlbGYucG9zKSkKCiAgICAgICAgaWYgbm90IHNlbGYuX2V4dGZpbGVvYmo6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCgogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQoKICAgIGRlZiBfaW5pdF9yZWFkX2d6KHNlbGYpOgogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHJlYWRpbmcgYSBnemlwIGNvbXByZXNzZWQgZmlsZW9iai4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmNtcCA9IHNlbGYuemxpYi5kZWNvbXByZXNzb2JqKC1zZWxmLnpsaWIuTUFYX1dCSVRTKQogICAgICAgIHNlbGYuZGJ1ZiA9ICIiCgogICAgICAgICMgdGFrZW4gZnJvbSBnemlwLkd6aXBGaWxlIHdpdGggc29tZSBhbHRlcmF0aW9ucwogICAgICAgIGlmIHNlbGYuX19yZWFkKDIpICE9ICJcMDM3XDIxMyI6CiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvciwgIm5vdCBhIGd6aXAgZmlsZSIKICAgICAgICBpZiBzZWxmLl9fcmVhZCgxKSAhPSAiXDAxMCI6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IsICJ1bnN1cHBvcnRlZCBjb21wcmVzc2lvbiBtZXRob2QiCgogICAgICAgIGZsYWcgPSBvcmQoc2VsZi5fX3JlYWQoMSkpCiAgICAgICAgc2VsZi5fX3JlYWQoNikKCiAgICAgICAgaWYgZmxhZyAmIDQ6CiAgICAgICAgICAgIHhsZW4gPSBvcmQoc2VsZi5fX3JlYWQoMSkpICsgMjU2ICogb3JkKHNlbGYuX19yZWFkKDEpKQogICAgICAgICAgICBzZWxmLnJlYWQoeGxlbikKICAgICAgICBpZiBmbGFnICYgODoKICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIHMgPSBzZWxmLl9fcmVhZCgxKQogICAgICAgICAgICAgICAgaWYgbm90IHMgb3IgcyA9PSBOVUw6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBpZiBmbGFnICYgMTY6CiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBzID0gc2VsZi5fX3JlYWQoMSkKICAgICAgICAgICAgICAgIGlmIG5vdCBzIG9yIHMgPT0gTlVMOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgaWYgZmxhZyAmIDI6CiAgICAgICAgICAgIHNlbGYuX19yZWFkKDIpCgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBzdHJlYW0ncyBmaWxlIHBvaW50ZXIgcG9zaXRpb24uCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHNlZWsoc2VsZiwgcG9zPTApOgogICAgICAgICIiIlNldCB0aGUgc3RyZWFtJ3MgZmlsZSBwb2ludGVyIHRvIHBvcy4gTmVnYXRpdmUgc2Vla2luZwogICAgICAgICAgIGlzIGZvcmJpZGRlbi4KICAgICAgICAiIiIKICAgICAgICBpZiBwb3MgLSBzZWxmLnBvcyA+PSAwOgogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChwb3MgLSBzZWxmLnBvcywgc2VsZi5idWZzaXplKQogICAgICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoYmxvY2tzKToKICAgICAgICAgICAgICAgIHNlbGYucmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIHNlbGYucmVhZChyZW1haW5kZXIpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgU3RyZWFtRXJyb3IsICJzZWVraW5nIGJhY2t3YXJkcyBpcyBub3QgYWxsb3dlZCIKICAgICAgICByZXR1cm4gc2VsZi5wb3MKCiAgICBkZWYgcmVhZChzZWxmLCBzaXplPU5vbmUpOgogICAgICAgICIiIlJldHVybiB0aGUgbmV4dCBzaXplIG51bWJlciBvZiBieXRlcyBmcm9tIHRoZSBzdHJlYW0uCiAgICAgICAgICAgSWYgc2l6ZSBpcyBub3QgZGVmaW5lZCwgcmV0dXJuIGFsbCBieXRlcyBvZiB0aGUgc3RyZWFtCiAgICAgICAgICAgdXAgdG8gRU9GLgogICAgICAgICIiIgogICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgdCA9IFtdCiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLl9yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIHQuYXBwZW5kKGJ1ZikKICAgICAgICAgICAgYnVmID0gIiIuam9pbih0KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX3JlYWQoc2l6ZSkKICAgICAgICBzZWxmLnBvcyArPSBsZW4oYnVmKQogICAgICAgIHJldHVybiBidWYKCiAgICBkZWYgX3JlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmV0dXJuIHNpemUgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYudHlwZSA9PSAidGFyIjoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX19yZWFkKHNpemUpCgogICAgICAgIGMgPSBsZW4oc2VsZi5kYnVmKQogICAgICAgIHQgPSBbc2VsZi5kYnVmXQogICAgICAgIHdoaWxlIGMgPCBzaXplOgogICAgICAgICAgICBidWYgPSBzZWxmLl9fcmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBidWYgPSBzZWxmLmNtcC5kZWNvbXByZXNzKGJ1ZikKICAgICAgICAgICAgdC5hcHBlbmQoYnVmKQogICAgICAgICAgICBjICs9IGxlbihidWYpCiAgICAgICAgdCA9ICIiLmpvaW4odCkKICAgICAgICBzZWxmLmRidWYgPSB0W3NpemU6XQogICAgICAgIHJldHVybiB0WzpzaXplXQoKICAgIGRlZiBfX3JlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmV0dXJuIHNpemUgYnl0ZXMgZnJvbSBzdHJlYW0uIElmIGludGVybmFsIGJ1ZmZlciBpcyBlbXB0eSwKICAgICAgICAgICByZWFkIGFub3RoZXIgYmxvY2sgZnJvbSB0aGUgc3RyZWFtLgogICAgICAgICIiIgogICAgICAgIGMgPSBsZW4oc2VsZi5idWYpCiAgICAgICAgdCA9IFtzZWxmLmJ1Zl0KICAgICAgICB3aGlsZSBjIDwgc2l6ZToKICAgICAgICAgICAgYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoc2VsZi5idWZzaXplKQogICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgdC5hcHBlbmQoYnVmKQogICAgICAgICAgICBjICs9IGxlbihidWYpCiAgICAgICAgdCA9ICIiLmpvaW4odCkKICAgICAgICBzZWxmLmJ1ZiA9IHRbc2l6ZTpdCiAgICAgICAgcmV0dXJuIHRbOnNpemVdCiMgY2xhc3MgX1N0cmVhbQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEV4dHJhY3Rpb24gZmlsZSBvYmplY3QKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBFeEZpbGVPYmplY3Qob2JqZWN0KToKICAgICIiIkZpbGUtbGlrZSBvYmplY3QgZm9yIHJlYWRpbmcgYW4gYXJjaGl2ZSBtZW1iZXIuCiAgICAgICBJcyByZXR1cm5lZCBieSBUYXJGaWxlLmV4dHJhY3RmaWxlKCkuIFN1cHBvcnQgZm9yCiAgICAgICBzcGFyc2UgZmlsZXMgaW5jbHVkZWQuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgdGFyZmlsZSwgdGFyaW5mbyk6CiAgICAgICAgc2VsZi5maWxlb2JqID0gdGFyZmlsZS5maWxlb2JqCiAgICAgICAgc2VsZi5uYW1lICAgID0gdGFyaW5mby5uYW1lCiAgICAgICAgc2VsZi5tb2RlICAgID0gInIiCiAgICAgICAgc2VsZi5jbG9zZWQgID0gRmFsc2UKICAgICAgICBzZWxmLm9mZnNldCAgPSB0YXJpbmZvLm9mZnNldF9kYXRhCiAgICAgICAgc2VsZi5zaXplICAgID0gdGFyaW5mby5zaXplCiAgICAgICAgc2VsZi5wb3MgICAgID0gMEwKICAgICAgICBzZWxmLmxpbmVidWZmZXIgPSAiIgogICAgICAgIGlmIHRhcmluZm8uaXNzcGFyc2UoKToKICAgICAgICAgICAgc2VsZi5zcGFyc2UgPSB0YXJpbmZvLnNwYXJzZQogICAgICAgICAgICBzZWxmLnJlYWQgPSBzZWxmLl9yZWFkc3BhcnNlCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5yZWFkID0gc2VsZi5fcmVhZG5vcm1hbAoKICAgIGRlZiBfX3JlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiT3ZlcmxvYWRhYmxlIHJlYWQgbWV0aG9kLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmoucmVhZChzaXplKQoKICAgIGRlZiByZWFkbGluZShzZWxmLCBzaXplPS0xKToKICAgICAgICAiIiJSZWFkIGEgbGluZSB3aXRoIGFwcHJveC4gc2l6ZS4gSWYgc2l6ZSBpcyBuZWdhdGl2ZSwKICAgICAgICAgICByZWFkIGEgd2hvbGUgbGluZS4gcmVhZGxpbmUoKSBhbmQgcmVhZCgpIG11c3Qgbm90CiAgICAgICAgICAgYmUgbWl4ZWQgdXAgKCEpLgogICAgICAgICIiIgogICAgICAgIGlmIHNpemUgPCAwOgogICAgICAgICAgICBzaXplID0gc3lzLm1heGludAoKICAgICAgICBubCA9IHNlbGYubGluZWJ1ZmZlci5maW5kKCJcbiIpCiAgICAgICAgaWYgbmwgPj0gMDoKICAgICAgICAgICAgbmwgPSBtaW4obmwsIHNpemUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2l6ZSAtPSBsZW4oc2VsZi5saW5lYnVmZmVyKQogICAgICAgICAgICB3aGlsZSBubCA8IDA6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLnJlYWQobWluKHNpemUsIDEwMCkpCiAgICAgICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBzZWxmLmxpbmVidWZmZXIgKz0gYnVmCiAgICAgICAgICAgICAgICBzaXplIC09IGxlbihidWYpCiAgICAgICAgICAgICAgICBpZiBzaXplIDw9IDA6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIG5sID0gc2VsZi5saW5lYnVmZmVyLmZpbmQoIlxuIikKICAgICAgICAgICAgaWYgbmwgPT0gLTE6CiAgICAgICAgICAgICAgICBzID0gc2VsZi5saW5lYnVmZmVyCiAgICAgICAgICAgICAgICBzZWxmLmxpbmVidWZmZXIgPSAiIgogICAgICAgICAgICAgICAgcmV0dXJuIHMKICAgICAgICBidWYgPSBzZWxmLmxpbmVidWZmZXJbOm5sXQogICAgICAgIHNlbGYubGluZWJ1ZmZlciA9IHNlbGYubGluZWJ1ZmZlcltubCArIDE6XQogICAgICAgIHdoaWxlIGJ1ZlstMTpdID09ICJcciI6CiAgICAgICAgICAgIGJ1ZiA9IGJ1Zls6LTFdCiAgICAgICAgcmV0dXJuIGJ1ZiArICJcbiIKCiAgICBkZWYgcmVhZGxpbmVzKHNlbGYpOgogICAgICAgICIiIlJldHVybiBhIGxpc3Qgd2l0aCBhbGwgKGZvbGxvd2luZykgbGluZXMuCiAgICAgICAgIiIiCiAgICAgICAgcmVzdWx0ID0gW10KICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBsaW5lID0gc2VsZi5yZWFkbGluZSgpCiAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgICAgICByZXN1bHQuYXBwZW5kKGxpbmUpCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBfcmVhZG5vcm1hbChzZWxmLCBzaXplPU5vbmUpOgogICAgICAgICIiIlJlYWQgb3BlcmF0aW9uIGZvciByZWd1bGFyIGZpbGVzLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAiZmlsZSBpcyBjbG9zZWQiCiAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5vZmZzZXQgKyBzZWxmLnBvcykKICAgICAgICBieXRlc2xlZnQgPSBzZWxmLnNpemUgLSBzZWxmLnBvcwogICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgYnl0ZXN0b3JlYWQgPSBieXRlc2xlZnQKICAgICAgICBlbHNlOgogICAgICAgICAgICBieXRlc3RvcmVhZCA9IG1pbihzaXplLCBieXRlc2xlZnQpCiAgICAgICAgc2VsZi5wb3MgKz0gYnl0ZXN0b3JlYWQKICAgICAgICByZXR1cm4gc2VsZi5fX3JlYWQoYnl0ZXN0b3JlYWQpCgogICAgZGVmIF9yZWFkc3BhcnNlKHNlbGYsIHNpemU9Tm9uZSk6CiAgICAgICAgIiIiUmVhZCBvcGVyYXRpb24gZm9yIHNwYXJzZSBmaWxlcy4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgImZpbGUgaXMgY2xvc2VkIgoKICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgIHNpemUgPSBzZWxmLnNpemUgLSBzZWxmLnBvcwoKICAgICAgICBkYXRhID0gW10KICAgICAgICB3aGlsZSBzaXplID4gMDoKICAgICAgICAgICAgYnVmID0gc2VsZi5fcmVhZHNwYXJzZXNlY3Rpb24oc2l6ZSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHNpemUgLT0gbGVuKGJ1ZikKICAgICAgICAgICAgZGF0YS5hcHBlbmQoYnVmKQogICAgICAgIHJldHVybiAiIi5qb2luKGRhdGEpCgogICAgZGVmIF9yZWFkc3BhcnNlc2VjdGlvbihzZWxmLCBzaXplKToKICAgICAgICAiIiJSZWFkIGEgc2luZ2xlIHNlY3Rpb24gb2YgYSBzcGFyc2UgZmlsZS4KICAgICAgICAiIiIKICAgICAgICBzZWN0aW9uID0gc2VsZi5zcGFyc2UuZmluZChzZWxmLnBvcykKCiAgICAgICAgaWYgc2VjdGlvbiBpcyBOb25lOgogICAgICAgICAgICByZXR1cm4gIiIKCiAgICAgICAgdG9yZWFkID0gbWluKHNpemUsIHNlY3Rpb24ub2Zmc2V0ICsgc2VjdGlvbi5zaXplIC0gc2VsZi5wb3MpCiAgICAgICAgaWYgaXNpbnN0YW5jZShzZWN0aW9uLCBfZGF0YSk6CiAgICAgICAgICAgIHJlYWxwb3MgPSBzZWN0aW9uLnJlYWxwb3MgKyBzZWxmLnBvcyAtIHNlY3Rpb24ub2Zmc2V0CiAgICAgICAgICAgIHNlbGYucG9zICs9IHRvcmVhZAogICAgICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCArIHJlYWxwb3MpCiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fcmVhZCh0b3JlYWQpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5wb3MgKz0gdG9yZWFkCiAgICAgICAgICAgIHJldHVybiBOVUwgKiB0b3JlYWQKCiAgICBkZWYgdGVsbChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIGN1cnJlbnQgZmlsZSBwb3NpdGlvbi4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZi5wb3MKCiAgICBkZWYgc2VlayhzZWxmLCBwb3MsIHdoZW5jZT0wKToKICAgICAgICAiIiJTZWVrIHRvIGEgcG9zaXRpb24gaW4gdGhlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5saW5lYnVmZmVyID0gIiIKICAgICAgICBpZiB3aGVuY2UgPT0gMDoKICAgICAgICAgICAgc2VsZi5wb3MgPSBtaW4obWF4KHBvcywgMCksIHNlbGYuc2l6ZSkKICAgICAgICBpZiB3aGVuY2UgPT0gMToKICAgICAgICAgICAgaWYgcG9zIDwgMDoKICAgICAgICAgICAgICAgIHNlbGYucG9zID0gbWF4KHNlbGYucG9zICsgcG9zLCAwKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5wb3MgPSBtaW4oc2VsZi5wb3MgKyBwb3MsIHNlbGYuc2l6ZSkKICAgICAgICBpZiB3aGVuY2UgPT0gMjoKICAgICAgICAgICAgc2VsZi5wb3MgPSBtYXgobWluKHNlbGYuc2l6ZSArIHBvcywgc2VsZi5zaXplKSwgMCkKCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIGZpbGUgb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQojY2xhc3MgRXhGaWxlT2JqZWN0CgojLS0tLS0tLS0tLS0tLS0tLS0tCiMgRXhwb3J0ZWQgQ2xhc3NlcwojLS0tLS0tLS0tLS0tLS0tLS0tCmNsYXNzIFRhckluZm8ob2JqZWN0KToKICAgICIiIkluZm9ybWF0aW9uYWwgY2xhc3Mgd2hpY2ggaG9sZHMgdGhlIGRldGFpbHMgYWJvdXQgYW4KICAgICAgIGFyY2hpdmUgbWVtYmVyIGdpdmVuIGJ5IGEgdGFyIGhlYWRlciBibG9jay4KICAgICAgIFRhckluZm8gb2JqZWN0cyBhcmUgcmV0dXJuZWQgYnkgVGFyRmlsZS5nZXRtZW1iZXIoKSwKICAgICAgIFRhckZpbGUuZ2V0bWVtYmVycygpIGFuZCBUYXJGaWxlLmdldHRhcmluZm8oKSBhbmQgYXJlCiAgICAgICB1c3VhbGx5IGNyZWF0ZWQgaW50ZXJuYWxseS4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lPSIiKToKICAgICAgICAiIiJDb25zdHJ1Y3QgYSBUYXJJbmZvIG9iamVjdC4gbmFtZSBpcyB0aGUgb3B0aW9uYWwgbmFtZQogICAgICAgICAgIG9mIHRoZSBtZW1iZXIuCiAgICAgICAgIiIiCgogICAgICAgIHNlbGYubmFtZSAgICAgPSBuYW1lICAgICAgICMgbWVtYmVyIG5hbWUgKGRpcm5hbWVzIG11c3QgZW5kIHdpdGggJy8nKQogICAgICAgIHNlbGYubW9kZSAgICAgPSAwNjY2ICAgICAgICMgZmlsZSBwZXJtaXNzaW9ucwogICAgICAgIHNlbGYudWlkICAgICAgPSAwICAgICAgICAgICMgdXNlciBpZAogICAgICAgIHNlbGYuZ2lkICAgICAgPSAwICAgICAgICAgICMgZ3JvdXAgaWQKICAgICAgICBzZWxmLnNpemUgICAgID0gMCAgICAgICAgICAjIGZpbGUgc2l6ZQogICAgICAgIHNlbGYubXRpbWUgICAgPSAwICAgICAgICAgICMgbW9kaWZpY2F0aW9uIHRpbWUKICAgICAgICBzZWxmLmNoa3N1bSAgID0gMCAgICAgICAgICAjIGhlYWRlciBjaGVja3N1bQogICAgICAgIHNlbGYudHlwZSAgICAgPSBSRUdUWVBFICAgICMgbWVtYmVyIHR5cGUKICAgICAgICBzZWxmLmxpbmtuYW1lID0gIiIgICAgICAgICAjIGxpbmsgbmFtZQogICAgICAgIHNlbGYudW5hbWUgICAgPSAidXNlciIgICAgICMgdXNlciBuYW1lCiAgICAgICAgc2VsZi5nbmFtZSAgICA9ICJncm91cCIgICAgIyBncm91cCBuYW1lCiAgICAgICAgc2VsZi5kZXZtYWpvciA9IDAgICAgICAgICAgIy0KICAgICAgICBzZWxmLmRldm1pbm9yID0gMCAgICAgICAgICAjLWZvciB1c2Ugd2l0aCBDSFJUWVBFIGFuZCBCTEtUWVBFCiAgICAgICAgc2VsZi5wcmVmaXggICA9ICIiICAgICAgICAgIyBwcmVmaXggdG8gZmlsZW5hbWUgb3IgaG9sZGluZyBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYWJvdXQgc3BhcnNlIGZpbGVzCgogICAgICAgIHNlbGYub2Zmc2V0ICAgPSAwICAgICAgICAgICMgdGhlIHRhciBoZWFkZXIgc3RhcnRzIGhlcmUKICAgICAgICBzZWxmLm9mZnNldF9kYXRhID0gMCAgICAgICAjIHRoZSBmaWxlJ3MgZGF0YSBzdGFydHMgaGVyZQoKICAgIGRlZiBfX3JlcHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gIjwlcyAlciBhdCAlI3g+IiAlIChzZWxmLl9fY2xhc3NfXy5fX25hbWVfXyxzZWxmLm5hbWUsaWQoc2VsZikpCgogICAgZGVmIGZyb21idWYoY2xzLCBidWYpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIFRhckluZm8gb2JqZWN0IGZyb20gYSA1MTIgYnl0ZSBzdHJpbmcgYnVmZmVyLgogICAgICAgICIiIgogICAgICAgIHRhcmluZm8gPSBjbHMoKQogICAgICAgIHRhcmluZm8ubmFtZSAgID0gIG50cyhidWZbMDoxMDBdKQogICAgICAgIHRhcmluZm8ubW9kZSAgID0gaW50KGJ1ZlsxMDA6MTA4XSwgOCkKICAgICAgICB0YXJpbmZvLnVpZCAgICA9IGludChidWZbMTA4OjExNl0sOCkKICAgICAgICB0YXJpbmZvLmdpZCAgICA9IGludChidWZbMTE2OjEyNF0sOCkKICAgICAgICB0YXJpbmZvLnNpemUgICA9IGxvbmcoYnVmWzEyNDoxMzZdLCA4KQogICAgICAgIHRhcmluZm8ubXRpbWUgID0gbG9uZyhidWZbMTM2OjE0OF0sIDgpCiAgICAgICAgdGFyaW5mby5jaGtzdW0gPSBpbnQoYnVmWzE0ODoxNTZdLCA4KQogICAgICAgIHRhcmluZm8udHlwZSAgID0gYnVmWzE1NjoxNTddCiAgICAgICAgdGFyaW5mby5saW5rbmFtZSA9IG50cyhidWZbMTU3OjI1N10pCiAgICAgICAgdGFyaW5mby51bmFtZSAgPSBudHMoYnVmWzI2NToyOTddKQogICAgICAgIHRhcmluZm8uZ25hbWUgID0gbnRzKGJ1ZlsyOTc6MzI5XSkKICAgICAgICB0cnk6CiAgICAgICAgICAgIHRhcmluZm8uZGV2bWFqb3IgPSBpbnQoYnVmWzMyOTozMzddLCA4KQogICAgICAgICAgICB0YXJpbmZvLmRldm1pbm9yID0gaW50KGJ1ZlszMzc6MzQ1XSwgOCkKICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgdGFyaW5mby5kZXZtYWpvciA9IHRhcmluZm8uZGV2bWFqb3IgPSAwCgogICAgICAgICMgVGhlIHByZWZpeCBmaWVsZCBpcyB1c2VkIGZvciBmaWxlbmFtZXMgPiAxMDAgaW4KICAgICAgICAjIHRoZSBQT1NJWCBzdGFuZGFyZC4KICAgICAgICAjIG5hbWUgPSBwcmVmaXggKyAiLyIgKyBuYW1lCiAgICAgICAgcHJlZml4ID0gYnVmWzM0NTo1MDBdCiAgICAgICAgd2hpbGUgcHJlZml4IGFuZCBwcmVmaXhbLTFdID09IE5VTDoKICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4WzotMV0KICAgICAgICBpZiBsZW4ocHJlZml4LnNwbGl0KE5VTCkpID09IDE6CiAgICAgICAgICAgIHRhcmluZm8ucHJlZml4ID0gcHJlZml4CiAgICAgICAgICAgIHRhcmluZm8ubmFtZSA9IG5vcm1wYXRoKG9zLnBhdGguam9pbih0YXJpbmZvLnByZWZpeCwgdGFyaW5mby5uYW1lKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICB0YXJpbmZvLnByZWZpeCA9IGJ1ZlszNDU6NTAwXQoKICAgICAgICAjIERpcmVjdG9yeSBuYW1lcyBzaG91bGQgaGF2ZSBhICcvJyBhdCB0aGUgZW5kLgogICAgICAgIGlmIHRhcmluZm8uaXNkaXIoKSBhbmQgdGFyaW5mby5uYW1lWy0xOl0gIT0gIi8iOgogICAgICAgICAgICB0YXJpbmZvLm5hbWUgKz0gIi8iCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBmcm9tYnVmID0gY2xhc3NtZXRob2QoZnJvbWJ1ZikKCiAgICBkZWYgdG9idWYoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIGEgdGFyIGhlYWRlciBibG9jayBhcyBhIDUxMiBieXRlIHN0cmluZy4KICAgICAgICAiIiIKICAgICAgICBuYW1lID0gc2VsZi5uYW1lCgogICAgICAgICMgVGhlIGZvbGxvd2luZyBjb2RlIHdhcyBjb250cmlidXRlZCBieSBEZXRsZWYgTGFubmVydC4KICAgICAgICBwYXJ0cyA9IFtdCiAgICAgICAgZm9yIHZhbHVlLCBmaWVsZHNpemUgaW4gKAogICAgICAgICAgICAgICAgKG5hbWUsIDEwMCksCiAgICAgICAgICAgICAgICAoIiUwN28iICUgKHNlbGYubW9kZSAmIDA3Nzc3KSwgOCksCiAgICAgICAgICAgICAgICAoIiUwN28iICUgc2VsZi51aWQsIDgpLAogICAgICAgICAgICAgICAgKCIlMDdvIiAlIHNlbGYuZ2lkLCA4KSwKICAgICAgICAgICAgICAgICgiJTAxMW8iICUgc2VsZi5zaXplLCAxMiksCiAgICAgICAgICAgICAgICAoIiUwMTFvIiAlIHNlbGYubXRpbWUsIDEyKSwKICAgICAgICAgICAgICAgICgiICAgICAgICAiLCA4KSwKICAgICAgICAgICAgICAgIChzZWxmLnR5cGUsIDEpLAogICAgICAgICAgICAgICAgKHNlbGYubGlua25hbWUsIDEwMCksCiAgICAgICAgICAgICAgICAoTUFHSUMsIDYpLAogICAgICAgICAgICAgICAgKFZFUlNJT04sIDIpLAogICAgICAgICAgICAgICAgKHNlbGYudW5hbWUsIDMyKSwKICAgICAgICAgICAgICAgIChzZWxmLmduYW1lLCAzMiksCiAgICAgICAgICAgICAgICAoIiUwN28iICUgc2VsZi5kZXZtYWpvciwgOCksCiAgICAgICAgICAgICAgICAoIiUwN28iICUgc2VsZi5kZXZtaW5vciwgOCksCiAgICAgICAgICAgICAgICAoc2VsZi5wcmVmaXgsIDE1NSkKICAgICAgICAgICAgKToKICAgICAgICAgICAgbCA9IGxlbih2YWx1ZSkKICAgICAgICAgICAgcGFydHMuYXBwZW5kKHZhbHVlICsgKGZpZWxkc2l6ZSAtIGwpICogTlVMKQoKICAgICAgICBidWYgPSAiIi5qb2luKHBhcnRzKQogICAgICAgIGNoa3N1bSA9IGNhbGNfY2hrc3VtKGJ1ZikKICAgICAgICBidWYgPSBidWZbOjE0OF0gKyAiJTA2b1wwIiAlIGNoa3N1bSArIGJ1ZlsxNTU6XQogICAgICAgIGJ1ZiArPSAoQkxPQ0tTSVpFIC0gbGVuKGJ1ZikpICogTlVMCiAgICAgICAgc2VsZi5idWYgPSBidWYKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIGlzcmVnKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgaW4gUkVHVUxBUl9UWVBFUwogICAgZGVmIGlzZmlsZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5pc3JlZygpCiAgICBkZWYgaXNkaXIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBESVJUWVBFCiAgICBkZWYgaXNzeW0oc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBTWU1UWVBFCiAgICBkZWYgaXNsbmsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBMTktUWVBFCiAgICBkZWYgaXNjaHIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBDSFJUWVBFCiAgICBkZWYgaXNibGsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBCTEtUWVBFCiAgICBkZWYgaXNmaWZvKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gRklGT1RZUEUKICAgIGRlZiBpc3NwYXJzZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEdOVVRZUEVfU1BBUlNFCiAgICBkZWYgaXNkZXYoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSBpbiAoQ0hSVFlQRSwgQkxLVFlQRSwgRklGT1RZUEUpCiMgY2xhc3MgVGFySW5mbwoKY2xhc3MgVGFyRmlsZShvYmplY3QpOgogICAgIiIiVGhlIFRhckZpbGUgQ2xhc3MgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIHRvIHRhciBhcmNoaXZlcy4KICAgICIiIgoKICAgIGRlYnVnID0gMCAgICAgICAgICAgICAgICAgICAjIE1heSBiZSBzZXQgZnJvbSAwIChubyBtc2dzKSB0byAzIChhbGwgbXNncykKCiAgICBkZXJlZmVyZW5jZSA9IEZhbHNlICAgICAgICAgIyBJZiB0cnVlLCBhZGQgY29udGVudCBvZiBsaW5rZWQgZmlsZSB0byB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRhciBmaWxlLCBlbHNlIHRoZSBsaW5rLgoKICAgIGlnbm9yZV96ZXJvcyA9IEZhbHNlICAgICAgICAjIElmIHRydWUsIHNraXBzIGVtcHR5IG9yIGludmFsaWQgYmxvY2tzIGFuZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY29udGludWVzIHByb2Nlc3NpbmcuCgogICAgZXJyb3JsZXZlbCA9IDAgICAgICAgICAgICAgICMgSWYgMCwgZmF0YWwgZXJyb3JzIG9ubHkgYXBwZWFyIGluIGRlYnVnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtZXNzYWdlcyAoaWYgZGVidWcgPj0gMCkuIElmID4gMCwgZXJyb3JzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhcmUgcGFzc2VkIHRvIHRoZSBjYWxsZXIgYXMgZXhjZXB0aW9ucy4KCiAgICBwb3NpeCA9IFRydWUgICAgICAgICAgICAgICAgIyBJZiBUcnVlLCBnZW5lcmF0ZXMgUE9TSVguMS0xOTkwLWNvbXBsaWFudAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJjaGl2ZXMgKG5vIEdOVSBleHRlbnNpb25zISkKCiAgICBmaWxlb2JqZWN0ID0gRXhGaWxlT2JqZWN0CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWU9Tm9uZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiT3BlbiBhbiAodW5jb21wcmVzc2VkKSB0YXIgYXJjaGl2ZSBgbmFtZScuIGBtb2RlJyBpcyBlaXRoZXIgJ3InIHRvCiAgICAgICAgICAgcmVhZCBmcm9tIGFuIGV4aXN0aW5nIGFyY2hpdmUsICdhJyB0byBhcHBlbmQgZGF0YSB0byBhbiBleGlzdGluZwogICAgICAgICAgIGZpbGUgb3IgJ3cnIHRvIGNyZWF0ZSBhIG5ldyBmaWxlIG92ZXJ3cml0aW5nIGFuIGV4aXN0aW5nIG9uZS4gYG1vZGUnCiAgICAgICAgICAgZGVmYXVsdHMgdG8gJ3InLgogICAgICAgICAgIElmIGBmaWxlb2JqJyBpcyBnaXZlbiwgaXQgaXMgdXNlZCBmb3IgcmVhZGluZyBvciB3cml0aW5nIGRhdGEuIElmIGl0CiAgICAgICAgICAgY2FuIGJlIGRldGVybWluZWQsIGBtb2RlJyBpcyBvdmVycmlkZGVuIGJ5IGBmaWxlb2JqJ3MgbW9kZS4KICAgICAgICAgICBgZmlsZW9iaicgaXMgbm90IGNsb3NlZCwgd2hlbiBUYXJGaWxlIGlzIGNsb3NlZC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLm5hbWUgPSBuYW1lCgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJhdyI6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJtb2RlIG11c3QgYmUgJ3InLCAnYScgb3IgJ3cnIgogICAgICAgIHNlbGYuX21vZGUgPSBtb2RlCiAgICAgICAgc2VsZi5tb2RlID0geyJyIjogInJiIiwgImEiOiAicitiIiwgInciOiAid2IifVttb2RlXQoKICAgICAgICBpZiBub3QgZmlsZW9iajoKICAgICAgICAgICAgZmlsZW9iaiA9IGZpbGUoc2VsZi5uYW1lLCBzZWxmLm1vZGUpCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIHNlbGYubmFtZSBpcyBOb25lIGFuZCBoYXNhdHRyKGZpbGVvYmosICJuYW1lIik6CiAgICAgICAgICAgICAgICBzZWxmLm5hbWUgPSBmaWxlb2JqLm5hbWUKICAgICAgICAgICAgaWYgaGFzYXR0cihmaWxlb2JqLCAibW9kZSIpOgogICAgICAgICAgICAgICAgc2VsZi5tb2RlID0gZmlsZW9iai5tb2RlCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagoKICAgICAgICAjIEluaXQgZGF0YXN0cnVjdHVyZXMKICAgICAgICBzZWxmLmNsb3NlZCAgICAgID0gRmFsc2UKICAgICAgICBzZWxmLm1lbWJlcnMgICAgID0gW10gICAgICAgIyBsaXN0IG9mIG1lbWJlcnMgYXMgVGFySW5mbyBvYmplY3RzCiAgICAgICAgc2VsZi5tZW1iZXJuYW1lcyA9IFtdICAgICAgICMgbmFtZXMgb2YgbWVtYmVycwogICAgICAgIHNlbGYuY2h1bmtzICAgICAgPSBbMF0gICAgICAjIGNodW5rIGNhY2hlCiAgICAgICAgc2VsZi5fbG9hZGVkICAgICA9IEZhbHNlICAgICMgZmxhZyBpZiBhbGwgbWVtYmVycyBoYXZlIGJlZW4gcmVhZAogICAgICAgIHNlbGYub2Zmc2V0ICAgICAgPSAwTCAgICAgICAjIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIGFyY2hpdmUgZmlsZQogICAgICAgIHNlbGYuaW5vZGVzICAgICAgPSB7fSAgICAgICAjIGRpY3Rpb25hcnkgY2FjaGluZyB0aGUgaW5vZGVzIG9mCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJjaGl2ZSBtZW1iZXJzIGFscmVhZHkgYWRkZWQKCiAgICAgICAgaWYgc2VsZi5fbW9kZSA9PSAiciI6CiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBzZWxmLm5leHQoKQoKICAgICAgICBpZiBzZWxmLl9tb2RlID09ICJhIjoKICAgICAgICAgICAgIyBNb3ZlIHRvIHRoZSBlbmQgb2YgdGhlIGFyY2hpdmUsCiAgICAgICAgICAgICMgYmVmb3JlIHRoZSBmaXJzdCBlbXB0eSBibG9jay4KICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IE5vbmUKICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5uZXh0KCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBSZWFkRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoMCkKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKC0gQkxPQ0tTSVpFLCAxKQogICAgICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgIGlmIHNlbGYuX21vZGUgaW4gImF3IjoKICAgICAgICAgICAgc2VsZi5fbG9hZGVkID0gVHJ1ZQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBCZWxvdyBhcmUgdGhlIGNsYXNzbWV0aG9kcyB3aGljaCBhY3QgYXMgYWx0ZXJuYXRlIGNvbnN0cnVjdG9ycyB0byB0aGUKICAgICMgVGFyRmlsZSBjbGFzcy4gVGhlIG9wZW4oKSBtZXRob2QgaXMgdGhlIG9ubHkgb25lIHRoYXQgaXMgbmVlZGVkIGZvcgogICAgIyBwdWJsaWMgdXNlOyBpdCBpcyB0aGUgInN1cGVyIi1jb25zdHJ1Y3RvciBhbmQgaXMgYWJsZSB0byBzZWxlY3QgYW4KICAgICMgYWRlcXVhdGUgInN1YiItY29uc3RydWN0b3IgZm9yIGEgcGFydGljdWxhciBjb21wcmVzc2lvbiB1c2luZyB0aGUgbWFwcGluZwogICAgIyBmcm9tIE9QRU5fTUVUSC4KICAgICMKICAgICMgVGhpcyBjb25jZXB0IGFsbG93cyBvbmUgdG8gc3ViY2xhc3MgVGFyRmlsZSB3aXRob3V0IGxvc2luZyB0aGUgY29tZm9ydCBvZgogICAgIyB0aGUgc3VwZXItY29uc3RydWN0b3IuIEEgc3ViLWNvbnN0cnVjdG9yIGlzIHJlZ2lzdGVyZWQgYW5kIG1hZGUgYXZhaWxhYmxlCiAgICAjIGJ5IGFkZGluZyBpdCB0byB0aGUgbWFwcGluZyBpbiBPUEVOX01FVEguCgogICAgZGVmIG9wZW4oY2xzLCBuYW1lPU5vbmUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGJ1ZnNpemU9MjAqNTEyKToKICAgICAgICAiIiJPcGVuIGEgdGFyIGFyY2hpdmUgZm9yIHJlYWRpbmcsIHdyaXRpbmcgb3IgYXBwZW5kaW5nLiBSZXR1cm4KICAgICAgICAgICBhbiBhcHByb3ByaWF0ZSBUYXJGaWxlIGNsYXNzLgoKICAgICAgICAgICBtb2RlOgogICAgICAgICAgICdyJyAgICAgICAgICBvcGVuIGZvciByZWFkaW5nIHdpdGggdHJhbnNwYXJlbnQgY29tcHJlc3Npb24KICAgICAgICAgICAncjonICAgICAgICAgb3BlbiBmb3IgcmVhZGluZyBleGNsdXNpdmVseSB1bmNvbXByZXNzZWQKICAgICAgICAgICAncjpneicgICAgICAgb3BlbiBmb3IgcmVhZGluZyB3aXRoIGd6aXAgY29tcHJlc3Npb24KICAgICAgICAgICAncjpiejInICAgICAgb3BlbiBmb3IgcmVhZGluZyB3aXRoIGJ6aXAyIGNvbXByZXNzaW9uCiAgICAgICAgICAgJ2EnIG9yICdhOicgIG9wZW4gZm9yIGFwcGVuZGluZwogICAgICAgICAgICd3JyBvciAndzonICBvcGVuIGZvciB3cml0aW5nIHdpdGhvdXQgY29tcHJlc3Npb24KICAgICAgICAgICAndzpneicgICAgICAgb3BlbiBmb3Igd3JpdGluZyB3aXRoIGd6aXAgY29tcHJlc3Npb24KICAgICAgICAgICAndzpiejInICAgICAgb3BlbiBmb3Igd3JpdGluZyB3aXRoIGJ6aXAyIGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3J8JyAgICAgICAgIG9wZW4gYW4gdW5jb21wcmVzc2VkIHN0cmVhbSBvZiB0YXIgYmxvY2tzIGZvciByZWFkaW5nCiAgICAgICAgICAgJ3J8Z3onICAgICAgIG9wZW4gYSBnemlwIGNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MKICAgICAgICAgICAncnxiejInICAgICAgb3BlbiBhIGJ6aXAyIGNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MKICAgICAgICAgICAnd3wnICAgICAgICAgb3BlbiBhbiB1bmNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCiAgICAgICAgICAgJ3d8Z3onICAgICAgIG9wZW4gYSBnemlwIGNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCiAgICAgICAgICAgJ3d8YnoyJyAgICAgIG9wZW4gYSBiemlwMiBjb21wcmVzc2VkIHN0cmVhbSBmb3Igd3JpdGluZwogICAgICAgICIiIgoKICAgICAgICBpZiBub3QgbmFtZSBhbmQgbm90IGZpbGVvYmo6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJub3RoaW5nIHRvIG9wZW4iCgogICAgICAgIGlmICI6IiBpbiBtb2RlOgogICAgICAgICAgICBmaWxlbW9kZSwgY29tcHR5cGUgPSBtb2RlLnNwbGl0KCI6IiwgMSkKICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciIKICAgICAgICAgICAgY29tcHR5cGUgPSBjb21wdHlwZSBvciAidGFyIgoKICAgICAgICAgICAgIyBTZWxlY3QgdGhlICpvcGVuKCkgZnVuY3Rpb24gYWNjb3JkaW5nIHRvCiAgICAgICAgICAgICMgZ2l2ZW4gY29tcHJlc3Npb24uCiAgICAgICAgICAgIGlmIGNvbXB0eXBlIGluIGNscy5PUEVOX01FVEg6CiAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cihjbHMsIGNscy5PUEVOX01FVEhbY29tcHR5cGVdKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvciwgInVua25vd24gY29tcHJlc3Npb24gdHlwZSAlciIgJSBjb21wdHlwZQogICAgICAgICAgICByZXR1cm4gZnVuYyhuYW1lLCBmaWxlbW9kZSwgZmlsZW9iaikKCiAgICAgICAgZWxpZiAifCIgaW4gbW9kZToKICAgICAgICAgICAgZmlsZW1vZGUsIGNvbXB0eXBlID0gbW9kZS5zcGxpdCgifCIsIDEpCiAgICAgICAgICAgIGZpbGVtb2RlID0gZmlsZW1vZGUgb3IgInIiCiAgICAgICAgICAgIGNvbXB0eXBlID0gY29tcHR5cGUgb3IgInRhciIKCiAgICAgICAgICAgIGlmIGZpbGVtb2RlIG5vdCBpbiAicnciOgogICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgIm1vZGUgbXVzdCBiZSAncicgb3IgJ3cnIgoKICAgICAgICAgICAgdCA9IGNscyhuYW1lLCBmaWxlbW9kZSwKICAgICAgICAgICAgICAgICAgICBfU3RyZWFtKG5hbWUsIGZpbGVtb2RlLCBjb21wdHlwZSwgZmlsZW9iaiwgYnVmc2l6ZSkpCiAgICAgICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgICAgICByZXR1cm4gdAoKICAgICAgICBlbGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICAjIEZpbmQgb3V0IHdoaWNoICpvcGVuKCkgaXMgYXBwcm9wcmlhdGUgZm9yIG9wZW5pbmcgdGhlIGZpbGUuCiAgICAgICAgICAgIGZvciBjb21wdHlwZSBpbiBjbHMuT1BFTl9NRVRIOgogICAgICAgICAgICAgICAgZnVuYyA9IGdldGF0dHIoY2xzLCBjbHMuT1BFTl9NRVRIW2NvbXB0eXBlXSkKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnVuYyhuYW1lLCAiciIsIGZpbGVvYmopCiAgICAgICAgICAgICAgICBleGNlcHQgKFJlYWRFcnJvciwgQ29tcHJlc3Npb25FcnJvcik6CiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yLCAiZmlsZSBjb3VsZCBub3QgYmUgb3BlbmVkIHN1Y2Nlc3NmdWxseSIKCiAgICAgICAgZWxpZiBtb2RlIGluICJhdyI6CiAgICAgICAgICAgIHJldHVybiBjbHMudGFyb3BlbihuYW1lLCBtb2RlLCBmaWxlb2JqKQoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAidW5kaXNjZXJuaWJsZSBtb2RlIgoKICAgIG9wZW4gPSBjbGFzc21ldGhvZChvcGVuKQoKICAgIGRlZiB0YXJvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiT3BlbiB1bmNvbXByZXNzZWQgdGFyIGFyY2hpdmUgbmFtZSBmb3IgcmVhZGluZyBvciB3cml0aW5nLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJhdyI6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJtb2RlIG11c3QgYmUgJ3InLCAnYScgb3IgJ3cnIgogICAgICAgIHJldHVybiBjbHMobmFtZSwgbW9kZSwgZmlsZW9iaikKCiAgICB0YXJvcGVuID0gY2xhc3NtZXRob2QodGFyb3BlbikKCiAgICBkZWYgZ3pvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgY29tcHJlc3NsZXZlbD05KToKICAgICAgICAiIiJPcGVuIGd6aXAgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgIm1vZGUgbXVzdCBiZSAncicgb3IgJ3cnIgoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBnemlwCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yLCAiZ3ppcCBtb2R1bGUgaXMgbm90IGF2YWlsYWJsZSIKCiAgICAgICAgcHJlLCBleHQgPSBvcy5wYXRoLnNwbGl0ZXh0KG5hbWUpCiAgICAgICAgcHJlID0gb3MucGF0aC5iYXNlbmFtZShwcmUpCiAgICAgICAgaWYgZXh0ID09ICIudGd6IjoKICAgICAgICAgICAgZXh0ID0gIi50YXIiCiAgICAgICAgaWYgZXh0ID09ICIuZ3oiOgogICAgICAgICAgICBleHQgPSAiIgogICAgICAgIHRhcm5hbWUgPSBwcmUgKyBleHQKCiAgICAgICAgaWYgZmlsZW9iaiBpcyBOb25lOgogICAgICAgICAgICBmaWxlb2JqID0gZmlsZShuYW1lLCBtb2RlICsgImIiKQoKICAgICAgICBpZiBtb2RlICE9ICJyIjoKICAgICAgICAgICAgbmFtZSA9IHRhcm5hbWUKCiAgICAgICAgdHJ5OgogICAgICAgICAgICB0ID0gY2xzLnRhcm9wZW4odGFybmFtZSwgbW9kZSwKICAgICAgICAgICAgICAgIGd6aXAuR3ppcEZpbGUobmFtZSwgbW9kZSwgY29tcHJlc3NsZXZlbCwgZmlsZW9iaikKICAgICAgICAgICAgKQogICAgICAgIGV4Y2VwdCBJT0Vycm9yOgogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IsICJub3QgYSBnemlwIGZpbGUiCiAgICAgICAgdC5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgcmV0dXJuIHQKCiAgICBnem9wZW4gPSBjbGFzc21ldGhvZChnem9wZW4pCgogICAgZGVmIGJ6Mm9wZW4oY2xzLCBuYW1lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCBjb21wcmVzc2xldmVsPTkpOgogICAgICAgICIiIk9wZW4gYnppcDIgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgIm1vZGUgbXVzdCBiZSAncicgb3IgJ3cnLiIKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpbXBvcnQgYnoyCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yLCAiYnoyIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIgoKICAgICAgICBwcmUsIGV4dCA9IG9zLnBhdGguc3BsaXRleHQobmFtZSkKICAgICAgICBwcmUgPSBvcy5wYXRoLmJhc2VuYW1lKHByZSkKICAgICAgICBpZiBleHQgPT0gIi50YnoyIjoKICAgICAgICAgICAgZXh0ID0gIi50YXIiCiAgICAgICAgaWYgZXh0ID09ICIuYnoyIjoKICAgICAgICAgICAgZXh0ID0gIiIKICAgICAgICB0YXJuYW1lID0gcHJlICsgZXh0CgogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJubyBzdXBwb3J0IGZvciBleHRlcm5hbCBmaWxlIG9iamVjdHMiCgogICAgICAgIHRyeToKICAgICAgICAgICAgdCA9IGNscy50YXJvcGVuKHRhcm5hbWUsIG1vZGUsIGJ6Mi5CWjJGaWxlKG5hbWUsIG1vZGUsIGNvbXByZXNzbGV2ZWw9Y29tcHJlc3NsZXZlbCkpCiAgICAgICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvciwgIm5vdCBhIGJ6aXAyIGZpbGUiCiAgICAgICAgdC5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgcmV0dXJuIHQKCiAgICBiejJvcGVuID0gY2xhc3NtZXRob2QoYnoyb3BlbikKCiAgICAjIEFsbCAqb3BlbigpIG1ldGhvZHMgYXJlIHJlZ2lzdGVyZWQgaGVyZS4KICAgIE9QRU5fTUVUSCA9IHsKICAgICAgICAidGFyIjogInRhcm9wZW4iLCAgICMgdW5jb21wcmVzc2VkIHRhcgogICAgICAgICJneiI6ICAiZ3pvcGVuIiwgICAgIyBnemlwIGNvbXByZXNzZWQgdGFyCiAgICAgICAgImJ6MiI6ICJiejJvcGVuIiAgICAjIGJ6aXAyIGNvbXByZXNzZWQgdGFyCiAgICB9CgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIFRoZSBwdWJsaWMgbWV0aG9kcyB3aGljaCBUYXJGaWxlIHByb3ZpZGVzOgoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICAiIiJDbG9zZSB0aGUgVGFyRmlsZS4gSW4gd3JpdGUtbW9kZSwgdHdvIGZpbmlzaGluZyB6ZXJvIGJsb2NrcyBhcmUKICAgICAgICAgICBhcHBlbmRlZCB0byB0aGUgYXJjaGl2ZS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIGlmIHNlbGYuX21vZGUgaW4gImF3IjoKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChCTE9DS1NJWkUgKiAyKSkKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gKEJMT0NLU0laRSAqIDIpCiAgICAgICAgICAgICMgZmlsbCB1cCB0aGUgZW5kIHdpdGggemVyby1ibG9ja3MKICAgICAgICAgICAgIyAobGlrZSBvcHRpb24gLWIyMCBmb3IgdGFyIGRvZXMpCiAgICAgICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKHNlbGYub2Zmc2V0LCBSRUNPUkRTSVpFKQogICAgICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChSRUNPUkRTSVpFIC0gcmVtYWluZGVyKSkKCiAgICAgICAgaWYgbm90IHNlbGYuX2V4dGZpbGVvYmo6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCiAgICAgICAgc2VsZi5jbG9zZWQgPSBUcnVlCgogICAgZGVmIGdldG1lbWJlcihzZWxmLCBuYW1lKToKICAgICAgICAiIiJSZXR1cm4gYSBUYXJJbmZvIG9iamVjdCBmb3IgbWVtYmVyIGBuYW1lJy4gSWYgYG5hbWUnIGNhbiBub3QgYmUKICAgICAgICAgICBmb3VuZCBpbiB0aGUgYXJjaGl2ZSwgS2V5RXJyb3IgaXMgcmFpc2VkLiBJZiBhIG1lbWJlciBvY2N1cnMgbW9yZQogICAgICAgICAgIHRoYW4gb25jZSBpbiB0aGUgYXJjaGl2ZSwgaXRzIGxhc3Qgb2NjdXJlbmNlIGlzIGFzc3VtZWQgdG8gYmUgdGhlCiAgICAgICAgICAgbW9zdCB1cC10by1kYXRlIHZlcnNpb24uCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soKQogICAgICAgIGlmIG5hbWUgbm90IGluIHNlbGYubWVtYmVybmFtZXMgYW5kIG5vdCBzZWxmLl9sb2FkZWQ6CiAgICAgICAgICAgIHNlbGYuX2xvYWQoKQogICAgICAgIGlmIG5hbWUgbm90IGluIHNlbGYubWVtYmVybmFtZXM6CiAgICAgICAgICAgIHJhaXNlIEtleUVycm9yLCAiZmlsZW5hbWUgJXIgbm90IGZvdW5kIiAlIG5hbWUKICAgICAgICByZXR1cm4gc2VsZi5fZ2V0bWVtYmVyKG5hbWUpCgogICAgZGVmIGdldG1lbWJlcnMoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBtZW1iZXJzIG9mIHRoZSBhcmNoaXZlIGFzIGEgbGlzdCBvZiBUYXJJbmZvIG9iamVjdHMuIFRoZQogICAgICAgICAgIGxpc3QgaGFzIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBtZW1iZXJzIGluIHRoZSBhcmNoaXZlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCkKICAgICAgICBpZiBub3Qgc2VsZi5fbG9hZGVkOiAgICAjIGlmIHdlIHdhbnQgdG8gb2J0YWluIGEgbGlzdCBvZgogICAgICAgICAgICBzZWxmLl9sb2FkKCkgICAgICAgICMgYWxsIG1lbWJlcnMsIHdlIGZpcnN0IGhhdmUgdG8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNjYW4gdGhlIHdob2xlIGFyY2hpdmUuCiAgICAgICAgcmV0dXJuIHNlbGYubWVtYmVycwoKICAgIGRlZiBnZXRuYW1lcyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG1lbWJlcnMgb2YgdGhlIGFyY2hpdmUgYXMgYSBsaXN0IG9mIHRoZWlyIG5hbWVzLiBJdCBoYXMKICAgICAgICAgICB0aGUgc2FtZSBvcmRlciBhcyB0aGUgbGlzdCByZXR1cm5lZCBieSBnZXRtZW1iZXJzKCkuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soKQogICAgICAgIGlmIG5vdCBzZWxmLl9sb2FkZWQ6CiAgICAgICAgICAgIHNlbGYuX2xvYWQoKQogICAgICAgIHJldHVybiBzZWxmLm1lbWJlcm5hbWVzCgogICAgZGVmIGdldHRhcmluZm8oc2VsZiwgbmFtZT1Ob25lLCBhcmNuYW1lPU5vbmUsIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiQ3JlYXRlIGEgVGFySW5mbyBvYmplY3QgZm9yIGVpdGhlciB0aGUgZmlsZSBgbmFtZScgb3IgdGhlIGZpbGUKICAgICAgICAgICBvYmplY3QgYGZpbGVvYmonICh1c2luZyBvcy5mc3RhdCBvbiBpdHMgZmlsZSBkZXNjcmlwdG9yKS4gWW91IGNhbgogICAgICAgICAgIG1vZGlmeSBzb21lIG9mIHRoZSBUYXJJbmZvJ3MgYXR0cmlidXRlcyBiZWZvcmUgeW91IGFkZCBpdCB1c2luZwogICAgICAgICAgIGFkZGZpbGUoKS4gSWYgZ2l2ZW4sIGBhcmNuYW1lJyBzcGVjaWZpZXMgYW4gYWx0ZXJuYXRpdmUgbmFtZSBmb3IgdGhlCiAgICAgICAgICAgZmlsZSBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiYXciKQoKICAgICAgICAjIFdoZW4gZmlsZW9iaiBpcyBnaXZlbiwgcmVwbGFjZSBuYW1lIGJ5CiAgICAgICAgIyBmaWxlb2JqJ3MgcmVhbCBuYW1lLgogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgIG5hbWUgPSBmaWxlb2JqLm5hbWUKCiAgICAgICAgIyBCdWlsZGluZyB0aGUgbmFtZSBvZiB0aGUgbWVtYmVyIGluIHRoZSBhcmNoaXZlLgogICAgICAgICMgQmFja3dhcmQgc2xhc2hlcyBhcmUgY29udmVydGVkIHRvIGZvcndhcmQgc2xhc2hlcywKICAgICAgICAjIEFic29sdXRlIHBhdGhzIGFyZSB0dXJuZWQgdG8gcmVsYXRpdmUgcGF0aHMuCiAgICAgICAgaWYgYXJjbmFtZSBpcyBOb25lOgogICAgICAgICAgICBhcmNuYW1lID0gbmFtZQogICAgICAgIGFyY25hbWUgPSBub3JtcGF0aChhcmNuYW1lKQogICAgICAgIGRydiwgYXJjbmFtZSA9IG9zLnBhdGguc3BsaXRkcml2ZShhcmNuYW1lKQogICAgICAgIHdoaWxlIGFyY25hbWVbMDoxXSA9PSAiLyI6CiAgICAgICAgICAgIGFyY25hbWUgPSBhcmNuYW1lWzE6XQoKICAgICAgICAjIE5vdywgZmlsbCB0aGUgVGFySW5mbyBvYmplY3Qgd2l0aAogICAgICAgICMgaW5mb3JtYXRpb24gc3BlY2lmaWMgZm9yIHRoZSBmaWxlLgogICAgICAgIHRhcmluZm8gPSBUYXJJbmZvKCkKCiAgICAgICAgIyBVc2Ugb3Muc3RhdCBvciBvcy5sc3RhdCwgZGVwZW5kaW5nIG9uIHBsYXRmb3JtCiAgICAgICAgIyBhbmQgaWYgc3ltbGlua3Mgc2hhbGwgYmUgcmVzb2x2ZWQuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBOb25lOgogICAgICAgICAgICBpZiBoYXNhdHRyKG9zLCAibHN0YXQiKSBhbmQgbm90IHNlbGYuZGVyZWZlcmVuY2U6CiAgICAgICAgICAgICAgICBzdGF0cmVzID0gb3MubHN0YXQobmFtZSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHN0YXRyZXMgPSBvcy5zdGF0KG5hbWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc3RhdHJlcyA9IG9zLmZzdGF0KGZpbGVvYmouZmlsZW5vKCkpCiAgICAgICAgbGlua25hbWUgPSAiIgoKICAgICAgICBzdG1kID0gc3RhdHJlcy5zdF9tb2RlCiAgICAgICAgaWYgc3RhdC5TX0lTUkVHKHN0bWQpOgogICAgICAgICAgICBpbm9kZSA9IChzdGF0cmVzLnN0X2lubywgc3RhdHJlcy5zdF9kZXYpCiAgICAgICAgICAgIGlmIGlub2RlIGluIHNlbGYuaW5vZGVzIGFuZCBub3Qgc2VsZi5kZXJlZmVyZW5jZToKICAgICAgICAgICAgICAgICMgSXMgaXQgYSBoYXJkbGluayB0byBhbiBhbHJlYWR5CiAgICAgICAgICAgICAgICAjIGFyY2hpdmVkIGZpbGU/CiAgICAgICAgICAgICAgICB0eXBlID0gTE5LVFlQRQogICAgICAgICAgICAgICAgbGlua25hbWUgPSBzZWxmLmlub2Rlc1tpbm9kZV0KICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgVGhlIGlub2RlIGlzIGFkZGVkIG9ubHkgaWYgaXRzIHZhbGlkLgogICAgICAgICAgICAgICAgIyBGb3Igd2luMzIgaXQgaXMgYWx3YXlzIDAuCiAgICAgICAgICAgICAgICB0eXBlID0gUkVHVFlQRQogICAgICAgICAgICAgICAgaWYgaW5vZGVbMF06CiAgICAgICAgICAgICAgICAgICAgc2VsZi5pbm9kZXNbaW5vZGVdID0gYXJjbmFtZQogICAgICAgIGVsaWYgc3RhdC5TX0lTRElSKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gRElSVFlQRQogICAgICAgICAgICBpZiBhcmNuYW1lWy0xOl0gIT0gIi8iOgogICAgICAgICAgICAgICAgYXJjbmFtZSArPSAiLyIKICAgICAgICBlbGlmIHN0YXQuU19JU0ZJRk8oc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBGSUZPVFlQRQogICAgICAgIGVsaWYgc3RhdC5TX0lTTE5LKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gU1lNVFlQRQogICAgICAgICAgICBsaW5rbmFtZSA9IG9zLnJlYWRsaW5rKG5hbWUpCiAgICAgICAgZWxpZiBzdGF0LlNfSVNDSFIoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBDSFJUWVBFCiAgICAgICAgZWxpZiBzdGF0LlNfSVNCTEsoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBCTEtUWVBFCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgIyBGaWxsIHRoZSBUYXJJbmZvIG9iamVjdCB3aXRoIGFsbAogICAgICAgICMgaW5mb3JtYXRpb24gd2UgY2FuIGdldC4KICAgICAgICB0YXJpbmZvLm5hbWUgID0gYXJjbmFtZQogICAgICAgIHRhcmluZm8ubW9kZSAgPSBzdG1kCiAgICAgICAgdGFyaW5mby51aWQgICA9IHN0YXRyZXMuc3RfdWlkCiAgICAgICAgdGFyaW5mby5naWQgICA9IHN0YXRyZXMuc3RfZ2lkCiAgICAgICAgdGFyaW5mby5zaXplICA9IHN0YXRyZXMuc3Rfc2l6ZQogICAgICAgIHRhcmluZm8ubXRpbWUgPSBzdGF0cmVzLnN0X210aW1lCiAgICAgICAgdGFyaW5mby50eXBlICA9IHR5cGUKICAgICAgICB0YXJpbmZvLmxpbmtuYW1lID0gbGlua25hbWUKICAgICAgICBpZiBwd2Q6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhcmluZm8udW5hbWUgPSBwd2QuZ2V0cHd1aWQodGFyaW5mby51aWQpWzBdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICBpZiBncnA6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhcmluZm8uZ25hbWUgPSBncnAuZ2V0Z3JnaWQodGFyaW5mby5naWQpWzBdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHBhc3MKCiAgICAgICAgaWYgdHlwZSBpbiAoQ0hSVFlQRSwgQkxLVFlQRSk6CiAgICAgICAgICAgIGlmIGhhc2F0dHIob3MsICJtYWpvciIpIGFuZCBoYXNhdHRyKG9zLCAibWlub3IiKToKICAgICAgICAgICAgICAgIHRhcmluZm8uZGV2bWFqb3IgPSBvcy5tYWpvcihzdGF0cmVzLnN0X3JkZXYpCiAgICAgICAgICAgICAgICB0YXJpbmZvLmRldm1pbm9yID0gb3MubWlub3Ioc3RhdHJlcy5zdF9yZGV2KQogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgZGVmIGxpc3Qoc2VsZiwgdmVyYm9zZT1UcnVlKToKICAgICAgICAiIiJQcmludCBhIHRhYmxlIG9mIGNvbnRlbnRzIHRvIHN5cy5zdGRvdXQuIElmIGB2ZXJib3NlJyBpcyBGYWxzZSwgb25seQogICAgICAgICAgIHRoZSBuYW1lcyBvZiB0aGUgbWVtYmVycyBhcmUgcHJpbnRlZC4gSWYgaXQgaXMgVHJ1ZSwgYW4gYGxzIC1sJy1saWtlCiAgICAgICAgICAgb3V0cHV0IGlzIHByb2R1Y2VkLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCkKCiAgICAgICAgZm9yIHRhcmluZm8gaW4gc2VsZjoKICAgICAgICAgICAgaWYgdmVyYm9zZToKICAgICAgICAgICAgICAgIHByaW50IGZpbGVtb2RlKHRhcmluZm8ubW9kZSksCiAgICAgICAgICAgICAgICBwcmludCAiJXMvJXMiICUgKHRhcmluZm8udW5hbWUgb3IgdGFyaW5mby51aWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmluZm8uZ25hbWUgb3IgdGFyaW5mby5naWQpLAogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc2NocigpIG9yIHRhcmluZm8uaXNibGsoKToKICAgICAgICAgICAgICAgICAgICBwcmludCAiJTEwcyIgJSAoIiVkLCVkIiBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICUgKHRhcmluZm8uZGV2bWFqb3IsIHRhcmluZm8uZGV2bWlub3IpKSwKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIiUxMGQiICUgdGFyaW5mby5zaXplLAogICAgICAgICAgICAgICAgcHJpbnQgIiVkLSUwMmQtJTAyZCAlMDJkOiUwMmQ6JTAyZCIgXAogICAgICAgICAgICAgICAgICAgICAgJSB0aW1lLmxvY2FsdGltZSh0YXJpbmZvLm10aW1lKVs6Nl0sCgogICAgICAgICAgICBwcmludCB0YXJpbmZvLm5hbWUsCgogICAgICAgICAgICBpZiB2ZXJib3NlOgogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICItPiIsIHRhcmluZm8ubGlua25hbWUsCiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzbG5rKCk6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgImxpbmsgdG8iLCB0YXJpbmZvLmxpbmtuYW1lLAogICAgICAgICAgICBwcmludAoKICAgIGRlZiBhZGQoc2VsZiwgbmFtZSwgYXJjbmFtZT1Ob25lLCByZWN1cnNpdmU9VHJ1ZSk6CiAgICAgICAgIiIiQWRkIHRoZSBmaWxlIGBuYW1lJyB0byB0aGUgYXJjaGl2ZS4gYG5hbWUnIG1heSBiZSBhbnkgdHlwZSBvZiBmaWxlCiAgICAgICAgICAgKGRpcmVjdG9yeSwgZmlmbywgc3ltYm9saWMgbGluaywgZXRjLikuIElmIGdpdmVuLCBgYXJjbmFtZScKICAgICAgICAgICBzcGVjaWZpZXMgYW4gYWx0ZXJuYXRpdmUgbmFtZSBmb3IgdGhlIGZpbGUgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgICAgRGlyZWN0b3JpZXMgYXJlIGFkZGVkIHJlY3Vyc2l2ZWx5IGJ5IGRlZmF1bHQuIFRoaXMgY2FuIGJlIGF2b2lkZWQgYnkKICAgICAgICAgICBzZXR0aW5nIGByZWN1cnNpdmUnIHRvIEZhbHNlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpCgogICAgICAgIGlmIGFyY25hbWUgaXMgTm9uZToKICAgICAgICAgICAgYXJjbmFtZSA9IG5hbWUKCiAgICAgICAgIyBTa2lwIGlmIHNvbWVib2R5IHRyaWVzIHRvIGFyY2hpdmUgdGhlIGFyY2hpdmUuLi4KICAgICAgICBpZiBzZWxmLm5hbWUgaXMgbm90IE5vbmUgXAogICAgICAgICAgICBhbmQgb3MucGF0aC5hYnNwYXRoKG5hbWUpID09IG9zLnBhdGguYWJzcGF0aChzZWxmLm5hbWUpOgogICAgICAgICAgICBzZWxmLl9kYmcoMiwgInRhcmZpbGU6IFNraXBwZWQgJXIiICUgbmFtZSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgICMgU3BlY2lhbCBjYXNlOiBUaGUgdXNlciB3YW50cyB0byBhZGQgdGhlIGN1cnJlbnQKICAgICAgICAjIHdvcmtpbmcgZGlyZWN0b3J5LgogICAgICAgIGlmIG5hbWUgPT0gIi4iOgogICAgICAgICAgICBpZiByZWN1cnNpdmU6CiAgICAgICAgICAgICAgICBpZiBhcmNuYW1lID09ICIuIjoKICAgICAgICAgICAgICAgICAgICBhcmNuYW1lID0gIiIKICAgICAgICAgICAgICAgIGZvciBmIGluIG9zLmxpc3RkaXIoIi4iKToKICAgICAgICAgICAgICAgICAgICBzZWxmLmFkZChmLCBvcy5wYXRoLmpvaW4oYXJjbmFtZSwgZikpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBzZWxmLl9kYmcoMSwgbmFtZSkKCiAgICAgICAgIyBDcmVhdGUgYSBUYXJJbmZvIG9iamVjdCBmcm9tIHRoZSBmaWxlLgogICAgICAgIHRhcmluZm8gPSBzZWxmLmdldHRhcmluZm8obmFtZSwgYXJjbmFtZSkKCiAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IFVuc3VwcG9ydGVkIHR5cGUgJXIiICUgbmFtZSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgICMgQXBwZW5kIHRoZSB0YXIgaGVhZGVyIGFuZCBkYXRhIHRvIHRoZSBhcmNoaXZlLgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKICAgICAgICAgICAgZiA9IGZpbGUobmFtZSwgInJiIikKICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8sIGYpCiAgICAgICAgICAgIGYuY2xvc2UoKQoKICAgICAgICBpZiB0YXJpbmZvLnR5cGUgaW4gKExOS1RZUEUsIFNZTVRZUEUsIEZJRk9UWVBFLCBDSFJUWVBFLCBCTEtUWVBFKToKICAgICAgICAgICAgdGFyaW5mby5zaXplID0gMEwKICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8pCgogICAgICAgIGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8pCiAgICAgICAgICAgIGlmIHJlY3Vyc2l2ZToKICAgICAgICAgICAgICAgIGZvciBmIGluIG9zLmxpc3RkaXIobmFtZSk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5hZGQob3MucGF0aC5qb2luKG5hbWUsIGYpLCBvcy5wYXRoLmpvaW4oYXJjbmFtZSwgZikpCgogICAgZGVmIGFkZGZpbGUoc2VsZiwgdGFyaW5mbywgZmlsZW9iaj1Ob25lKToKICAgICAgICAiIiJBZGQgdGhlIFRhckluZm8gb2JqZWN0IGB0YXJpbmZvJyB0byB0aGUgYXJjaGl2ZS4gSWYgYGZpbGVvYmonIGlzCiAgICAgICAgICAgZ2l2ZW4sIHRhcmluZm8uc2l6ZSBieXRlcyBhcmUgcmVhZCBmcm9tIGl0IGFuZCBhZGRlZCB0byB0aGUgYXJjaGl2ZS4KICAgICAgICAgICBZb3UgY2FuIGNyZWF0ZSBUYXJJbmZvIG9iamVjdHMgdXNpbmcgZ2V0dGFyaW5mbygpLgogICAgICAgICAgIE9uIFdpbmRvd3MgcGxhdGZvcm1zLCBgZmlsZW9iaicgc2hvdWxkIGFsd2F5cyBiZSBvcGVuZWQgd2l0aCBtb2RlCiAgICAgICAgICAgJ3JiJyB0byBhdm9pZCBpcnJpdGF0aW9uIGFib3V0IHRoZSBmaWxlIHNpemUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soImF3IikKCiAgICAgICAgdGFyaW5mby5uYW1lID0gbm9ybXBhdGgodGFyaW5mby5uYW1lKQogICAgICAgIGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgIyBkaXJlY3RvcmllcyBzaG91bGQgZW5kIHdpdGggJy8nCiAgICAgICAgICAgIHRhcmluZm8ubmFtZSArPSAiLyIKCiAgICAgICAgaWYgdGFyaW5mby5saW5rbmFtZToKICAgICAgICAgICAgdGFyaW5mby5saW5rbmFtZSA9IG5vcm1wYXRoKHRhcmluZm8ubGlua25hbWUpCgogICAgICAgIGlmIHRhcmluZm8uc2l6ZSA+IE1BWFNJWkVfTUVNQkVSOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAiZmlsZSBpcyB0b28gbGFyZ2UgKD44R0IpIgoKICAgICAgICBpZiBsZW4odGFyaW5mby5saW5rbmFtZSkgPiBMRU5HVEhfTElOSzoKICAgICAgICAgICAgaWYgc2VsZi5wb3NpeDoKICAgICAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJsaW5rbmFtZSBpcyB0b28gbG9uZyAoPiVkKSIgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJSAoTEVOR1RIX0xJTkspCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLl9jcmVhdGVfZ251bG9uZyh0YXJpbmZvLmxpbmtuYW1lLCBHTlVUWVBFX0xPTkdMSU5LKQogICAgICAgICAgICAgICAgdGFyaW5mby5saW5rbmFtZSA9IHRhcmluZm8ubGlua25hbWVbOkxFTkdUSF9MSU5LIC0xXQogICAgICAgICAgICAgICAgc2VsZi5fZGJnKDIsICJ0YXJmaWxlOiBDcmVhdGVkIEdOVSB0YXIgZXh0ZW5zaW9uIExPTkdMSU5LIikKCiAgICAgICAgaWYgbGVuKHRhcmluZm8ubmFtZSkgPiBMRU5HVEhfTkFNRToKICAgICAgICAgICAgaWYgc2VsZi5wb3NpeDoKICAgICAgICAgICAgICAgIHByZWZpeCA9IHRhcmluZm8ubmFtZVs6TEVOR1RIX1BSRUZJWCArIDFdCiAgICAgICAgICAgICAgICB3aGlsZSBwcmVmaXggYW5kIHByZWZpeFstMV0gIT0gIi8iOgogICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBwcmVmaXhbOi0xXQoKICAgICAgICAgICAgICAgIG5hbWUgPSB0YXJpbmZvLm5hbWVbbGVuKHByZWZpeCk6XQogICAgICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4WzotMV0KCiAgICAgICAgICAgICAgICBpZiBub3QgcHJlZml4IG9yIGxlbihuYW1lKSA+IExFTkdUSF9OQU1FOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJuYW1lIGlzIHRvbyBsb25nICg+JWQpIiBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJSAoTEVOR1RIX05BTUUpCgogICAgICAgICAgICAgICAgdGFyaW5mby5uYW1lICAgPSBuYW1lCiAgICAgICAgICAgICAgICB0YXJpbmZvLnByZWZpeCA9IHByZWZpeAogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5fY3JlYXRlX2dudWxvbmcodGFyaW5mby5uYW1lLCBHTlVUWVBFX0xPTkdOQU1FKQogICAgICAgICAgICAgICAgdGFyaW5mby5uYW1lID0gdGFyaW5mby5uYW1lWzpMRU5HVEhfTkFNRSAtIDFdCiAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMiwgInRhcmZpbGU6IENyZWF0ZWQgR05VIHRhciBleHRlbnNpb24gTE9OR05BTUUiKQoKICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUodGFyaW5mby50b2J1ZigpKQogICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQoKICAgICAgICAjIElmIHRoZXJlJ3MgZGF0YSB0byBmb2xsb3csIGFwcGVuZCBpdC4KICAgICAgICBpZiBmaWxlb2JqIGlzIG5vdCBOb25lOgogICAgICAgICAgICBjb3B5ZmlsZW9iaihmaWxlb2JqLCBzZWxmLmZpbGVvYmosIHRhcmluZm8uc2l6ZSkKICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QodGFyaW5mby5zaXplLCBCTE9DS1NJWkUpCiAgICAgICAgICAgIGlmIHJlbWFpbmRlciA+IDA6CiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKEJMT0NLU0laRSAtIHJlbWFpbmRlcikpCiAgICAgICAgICAgICAgICBibG9ja3MgKz0gMQogICAgICAgICAgICBzZWxmLm9mZnNldCArPSBibG9ja3MgKiBCTE9DS1NJWkUKCiAgICAgICAgc2VsZi5tZW1iZXJzLmFwcGVuZCh0YXJpbmZvKQogICAgICAgIHNlbGYubWVtYmVybmFtZXMuYXBwZW5kKHRhcmluZm8ubmFtZSkKICAgICAgICBzZWxmLmNodW5rcy5hcHBlbmQoc2VsZi5vZmZzZXQpCgogICAgZGVmIGV4dHJhY3Qoc2VsZiwgbWVtYmVyLCBwYXRoPSIiKToKICAgICAgICAiIiJFeHRyYWN0IGEgbWVtYmVyIGZyb20gdGhlIGFyY2hpdmUgdG8gdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnksCiAgICAgICAgICAgdXNpbmcgaXRzIGZ1bGwgbmFtZS4gSXRzIGZpbGUgaW5mb3JtYXRpb24gaXMgZXh0cmFjdGVkIGFzIGFjY3VyYXRlbHkKICAgICAgICAgICBhcyBwb3NzaWJsZS4gYG1lbWJlcicgbWF5IGJlIGEgZmlsZW5hbWUgb3IgYSBUYXJJbmZvIG9iamVjdC4gWW91IGNhbgogICAgICAgICAgIHNwZWNpZnkgYSBkaWZmZXJlbnQgZGlyZWN0b3J5IHVzaW5nIGBwYXRoJy4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiciIpCgogICAgICAgIGlmIGlzaW5zdGFuY2UobWVtYmVyLCBUYXJJbmZvKToKICAgICAgICAgICAgdGFyaW5mbyA9IG1lbWJlcgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLmdldG1lbWJlcihtZW1iZXIpCgogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi5fZXh0cmFjdF9tZW1iZXIodGFyaW5mbywgb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubmFtZSkpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgIGlmIHNlbGYuZXJyb3JsZXZlbCA+IDA6CiAgICAgICAgICAgICAgICByYWlzZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgZS5maWxlbmFtZSBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZS5zdHJlcnJvcikKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyAlciIgJSAoZS5zdHJlcnJvciwgZS5maWxlbmFtZSkpCiAgICAgICAgZXhjZXB0IEV4dHJhY3RFcnJvciwgZToKICAgICAgICAgICAgaWYgc2VsZi5lcnJvcmxldmVsID4gMToKICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzIiAlIGUpCgogICAgZGVmIGV4dHJhY3RmaWxlKHNlbGYsIG1lbWJlcik6CiAgICAgICAgIiIiRXh0cmFjdCBhIG1lbWJlciBmcm9tIHRoZSBhcmNoaXZlIGFzIGEgZmlsZSBvYmplY3QuIGBtZW1iZXInIG1heSBiZQogICAgICAgICAgIGEgZmlsZW5hbWUgb3IgYSBUYXJJbmZvIG9iamVjdC4gSWYgYG1lbWJlcicgaXMgYSByZWd1bGFyIGZpbGUsIGEKICAgICAgICAgICBmaWxlLWxpa2Ugb2JqZWN0IGlzIHJldHVybmVkLiBJZiBgbWVtYmVyJyBpcyBhIGxpbmssIGEgZmlsZS1saWtlCiAgICAgICAgICAgb2JqZWN0IGlzIGNvbnN0cnVjdGVkIGZyb20gdGhlIGxpbmsncyB0YXJnZXQuIElmIGBtZW1iZXInIGlzIG5vbmUgb2YKICAgICAgICAgICB0aGUgYWJvdmUsIE5vbmUgaXMgcmV0dXJuZWQuCiAgICAgICAgICAgVGhlIGZpbGUtbGlrZSBvYmplY3QgaXMgcmVhZC1vbmx5IGFuZCBwcm92aWRlcyB0aGUgZm9sbG93aW5nCiAgICAgICAgICAgbWV0aG9kczogcmVhZCgpLCByZWFkbGluZSgpLCByZWFkbGluZXMoKSwgc2VlaygpIGFuZCB0ZWxsKCkKICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiciIpCgogICAgICAgIGlmIGlzaW5zdGFuY2UobWVtYmVyLCBUYXJJbmZvKToKICAgICAgICAgICAgdGFyaW5mbyA9IG1lbWJlcgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLmdldG1lbWJlcihtZW1iZXIpCgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iamVjdChzZWxmLCB0YXJpbmZvKQoKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICAjIElmIGEgbWVtYmVyJ3MgdHlwZSBpcyB1bmtub3duLCBpdCBpcyB0cmVhdGVkIGFzIGEKICAgICAgICAgICAgIyByZWd1bGFyIGZpbGUuCiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmplY3Qoc2VsZiwgdGFyaW5mbykKCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzbG5rKCkgb3IgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHNlbGYuZmlsZW9iaiwgX1N0cmVhbSk6CiAgICAgICAgICAgICAgICAjIEEgc21hbGwgYnV0IHVnbHkgd29ya2Fyb3VuZCBmb3IgdGhlIGNhc2UgdGhhdCBzb21lb25lIHRyaWVzCiAgICAgICAgICAgICAgICAjIHRvIGV4dHJhY3QgYSAoc3ltKWxpbmsgYXMgYSBmaWxlLW9iamVjdCBmcm9tIGEgbm9uLXNlZWthYmxlCiAgICAgICAgICAgICAgICAjIHN0cmVhbSBvZiB0YXIgYmxvY2tzLgogICAgICAgICAgICAgICAgcmFpc2UgU3RyZWFtRXJyb3IsICJjYW5ub3QgZXh0cmFjdCAoc3ltKWxpbmsgYXMgZmlsZSBvYmplY3QiCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIEEgKHN5bSlsaW5rJ3MgZmlsZSBvYmplY3QgaXMgaXQncyB0YXJnZXQncyBmaWxlIG9iamVjdC4KICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLmV4dHJhY3RmaWxlKHNlbGYuX2dldG1lbWJlcih0YXJpbmZvLmxpbmtuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmluZm8pKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgICMgSWYgdGhlcmUncyBubyBkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgbWVtYmVyIChkaXJlY3RvcnksIGNocmRldiwKICAgICAgICAgICAgIyBibGtkZXYsIGV0Yy4pLCByZXR1cm4gTm9uZSBpbnN0ZWFkIG9mIGEgZmlsZSBvYmplY3QuCiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgZGVmIF9leHRyYWN0X21lbWJlcihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJFeHRyYWN0IHRoZSBUYXJJbmZvIG9iamVjdCB0YXJpbmZvIHRvIGEgcGh5c2ljYWwKICAgICAgICAgICBmaWxlIGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgICMgRmV0Y2ggdGhlIFRhckluZm8gb2JqZWN0IGZvciB0aGUgZ2l2ZW4gbmFtZQogICAgICAgICMgYW5kIGJ1aWxkIHRoZSBkZXN0aW5hdGlvbiBwYXRobmFtZSwgcmVwbGFjaW5nCiAgICAgICAgIyBmb3J3YXJkIHNsYXNoZXMgdG8gcGxhdGZvcm0gc3BlY2lmaWMgc2VwYXJhdG9ycy4KICAgICAgICBpZiB0YXJnZXRwYXRoWy0xOl0gPT0gIi8iOgogICAgICAgICAgICB0YXJnZXRwYXRoID0gdGFyZ2V0cGF0aFs6LTFdCiAgICAgICAgdGFyZ2V0cGF0aCA9IG9zLnBhdGgubm9ybXBhdGgodGFyZ2V0cGF0aCkKCiAgICAgICAgIyBDcmVhdGUgYWxsIHVwcGVyIGRpcmVjdG9yaWVzLgogICAgICAgIHVwcGVyZGlycyA9IG9zLnBhdGguZGlybmFtZSh0YXJnZXRwYXRoKQogICAgICAgIGlmIHVwcGVyZGlycyBhbmQgbm90IG9zLnBhdGguZXhpc3RzKHVwcGVyZGlycyk6CiAgICAgICAgICAgIHRpID0gVGFySW5mbygpCiAgICAgICAgICAgIHRpLm5hbWUgID0gdXBwZXJkaXJzCiAgICAgICAgICAgIHRpLnR5cGUgID0gRElSVFlQRQogICAgICAgICAgICB0aS5tb2RlICA9IDA3NzcKICAgICAgICAgICAgdGkubXRpbWUgPSB0YXJpbmZvLm10aW1lCiAgICAgICAgICAgIHRpLnVpZCAgID0gdGFyaW5mby51aWQKICAgICAgICAgICAgdGkuZ2lkICAgPSB0YXJpbmZvLmdpZAogICAgICAgICAgICB0aS51bmFtZSA9IHRhcmluZm8udW5hbWUKICAgICAgICAgICAgdGkuZ25hbWUgPSB0YXJpbmZvLmduYW1lCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHNlbGYuX2V4dHJhY3RfbWVtYmVyKHRpLCB0aS5uYW1lKQogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBwYXNzCgogICAgICAgIGlmIHRhcmluZm8uaXNsbmsoKSBvciB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgIHNlbGYuX2RiZygxLCAiJXMgLT4gJXMiICUgKHRhcmluZm8ubmFtZSwgdGFyaW5mby5saW5rbmFtZSkpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5fZGJnKDEsIHRhcmluZm8ubmFtZSkKCiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpOgogICAgICAgICAgICBzZWxmLm1ha2VmaWxlKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWRpcih0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby5pc2ZpZm8oKToKICAgICAgICAgICAgc2VsZi5tYWtlZmlmbyh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby5pc2NocigpIG9yIHRhcmluZm8uaXNibGsoKToKICAgICAgICAgICAgc2VsZi5tYWtlZGV2KHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzbG5rKCkgb3IgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBzZWxmLm1ha2VsaW5rKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLnR5cGUgbm90IGluIFNVUFBPUlRFRF9UWVBFUzoKICAgICAgICAgICAgc2VsZi5tYWtldW5rbm93bih0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKCiAgICAgICAgc2VsZi5jaG93bih0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGlmIG5vdCB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgIHNlbGYuY2htb2QodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICAgICAgc2VsZi51dGltZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBCZWxvdyBhcmUgdGhlIGRpZmZlcmVudCBmaWxlIG1ldGhvZHMuIFRoZXkgYXJlIGNhbGxlZCB2aWEKICAgICMgX2V4dHJhY3RfbWVtYmVyKCkgd2hlbiBleHRyYWN0KCkgaXMgY2FsbGVkLiBUaGV5IGNhbiBiZSByZXBsYWNlZCBpbiBhCiAgICAjIHN1YmNsYXNzIHRvIGltcGxlbWVudCBvdGhlciBmdW5jdGlvbmFsaXR5LgoKICAgIGRlZiBtYWtlZGlyKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBkaXJlY3RvcnkgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgdHJ5OgogICAgICAgICAgICBvcy5ta2Rpcih0YXJnZXRwYXRoKQogICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICBpZiBlLmVycm5vICE9IGVycm5vLkVFWElTVDoKICAgICAgICAgICAgICAgIHJhaXNlCgogICAgZGVmIG1ha2VmaWxlKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBmaWxlIGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIHNvdXJjZSA9IHNlbGYuZXh0cmFjdGZpbGUodGFyaW5mbykKICAgICAgICB0YXJnZXQgPSBmaWxlKHRhcmdldHBhdGgsICJ3YiIpCiAgICAgICAgY29weWZpbGVvYmooc291cmNlLCB0YXJnZXQpCiAgICAgICAgc291cmNlLmNsb3NlKCkKICAgICAgICB0YXJnZXQuY2xvc2UoKQoKICAgIGRlZiBtYWtldW5rbm93bihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlsZSBmcm9tIGEgVGFySW5mbyBvYmplY3Qgd2l0aCBhbiB1bmtub3duIHR5cGUKICAgICAgICAgICBhdCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IFVua25vd24gZmlsZSB0eXBlICVyLCAiIFwKICAgICAgICAgICAgICAgICAgICAgImV4dHJhY3RlZCBhcyByZWd1bGFyIGZpbGUuIiAlIHRhcmluZm8udHlwZSkKCiAgICBkZWYgbWFrZWZpZm8oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGZpZm8gY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgaWYgaGFzYXR0cihvcywgIm1rZmlmbyIpOgogICAgICAgICAgICBvcy5ta2ZpZm8odGFyZ2V0cGF0aCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IsICJmaWZvIG5vdCBzdXBwb3J0ZWQgYnkgc3lzdGVtIgoKICAgIGRlZiBtYWtlZGV2KHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBjaGFyYWN0ZXIgb3IgYmxvY2sgZGV2aWNlIGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIGlmIG5vdCBoYXNhdHRyKG9zLCAibWtub2QiKSBvciBub3QgaGFzYXR0cihvcywgIm1ha2VkZXYiKToKICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yLCAic3BlY2lhbCBkZXZpY2VzIG5vdCBzdXBwb3J0ZWQgYnkgc3lzdGVtIgoKICAgICAgICBtb2RlID0gdGFyaW5mby5tb2RlCiAgICAgICAgaWYgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICBtb2RlIHw9IHN0YXQuU19JRkJMSwogICAgICAgIGVsc2U6CiAgICAgICAgICAgIG1vZGUgfD0gc3RhdC5TX0lGQ0hSCgogICAgICAgIG9zLm1rbm9kKHRhcmdldHBhdGgsIG1vZGUsCiAgICAgICAgICAgICAgICAgb3MubWFrZWRldih0YXJpbmZvLmRldm1ham9yLCB0YXJpbmZvLmRldm1pbm9yKSkKCiAgICBkZWYgbWFrZWxpbmsoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIChzeW1ib2xpYykgbGluayBjYWxsZWQgdGFyZ2V0cGF0aC4gSWYgaXQgY2Fubm90IGJlIGNyZWF0ZWQKICAgICAgICAgIChwbGF0Zm9ybSBsaW1pdGF0aW9uKSwgd2UgdHJ5IHRvIG1ha2UgYSBjb3B5IG9mIHRoZSByZWZlcmVuY2VkIGZpbGUKICAgICAgICAgIGluc3RlYWQgb2YgYSBsaW5rLgogICAgICAgICIiIgogICAgICAgIGxpbmtwYXRoID0gdGFyaW5mby5saW5rbmFtZQogICAgICAgIHRyeToKICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICAgICAgb3Muc3ltbGluayhsaW5rcGF0aCwgdGFyZ2V0cGF0aCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIG9zLmxpbmsobGlua3BhdGgsIHRhcmdldHBhdGgpCiAgICAgICAgZXhjZXB0IEF0dHJpYnV0ZUVycm9yOgogICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICAgICBsaW5rcGF0aCA9IG9zLnBhdGguam9pbihvcy5wYXRoLmRpcm5hbWUodGFyaW5mby5uYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmtwYXRoKQogICAgICAgICAgICAgICAgbGlua3BhdGggPSBub3JtcGF0aChsaW5rcGF0aCkKCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHNlbGYuX2V4dHJhY3RfbWVtYmVyKHNlbGYuZ2V0bWVtYmVyKGxpbmtwYXRoKSwgdGFyZ2V0cGF0aCkKICAgICAgICAgICAgZXhjZXB0IChFbnZpcm9ubWVudEVycm9yLCBLZXlFcnJvciksIGU6CiAgICAgICAgICAgICAgICBsaW5rcGF0aCA9IG9zLnBhdGgubm9ybXBhdGgobGlua3BhdGgpCiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgc2h1dGlsLmNvcHkyKGxpbmtwYXRoLCB0YXJnZXRwYXRoKQogICAgICAgICAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgSU9FcnJvciwgImxpbmsgY291bGQgbm90IGJlIGNyZWF0ZWQiCgogICAgZGVmIGNob3duKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIlNldCBvd25lciBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgogICAgICAgICIiIgogICAgICAgIGlmIHB3ZCBhbmQgaGFzYXR0cihvcywgImdldGV1aWQiKSBhbmQgb3MuZ2V0ZXVpZCgpID09IDA6CiAgICAgICAgICAgICMgV2UgaGF2ZSB0byBiZSByb290IHRvIGRvIHNvLgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBnID0gZ3JwLmdldGdybmFtKHRhcmluZm8uZ25hbWUpWzJdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBnID0gZ3JwLmdldGdyZ2lkKHRhcmluZm8uZ2lkKVsyXQogICAgICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgICAgIGcgPSBvcy5nZXRnaWQoKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB1ID0gcHdkLmdldHB3bmFtKHRhcmluZm8udW5hbWUpWzJdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICB1ID0gcHdkLmdldHB3dWlkKHRhcmluZm8udWlkKVsyXQogICAgICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgICAgIHUgPSBvcy5nZXR1aWQoKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCkgYW5kIGhhc2F0dHIob3MsICJsY2hvd24iKToKICAgICAgICAgICAgICAgICAgICBvcy5sY2hvd24odGFyZ2V0cGF0aCwgdSwgZykKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgb3MuY2hvd24odGFyZ2V0cGF0aCwgdSwgZykKICAgICAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IsICJjb3VsZCBub3QgY2hhbmdlIG93bmVyIgoKICAgIGRlZiBjaG1vZChzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJTZXQgZmlsZSBwZXJtaXNzaW9ucyBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgogICAgICAgICIiIgogICAgICAgIHRyeToKICAgICAgICAgICAgb3MuY2htb2QodGFyZ2V0cGF0aCwgdGFyaW5mby5tb2RlKQogICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IsICJjb3VsZCBub3QgY2hhbmdlIG1vZGUiCgogICAgZGVmIHV0aW1lKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIlNldCBtb2RpZmljYXRpb24gdGltZSBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgogICAgICAgICIiIgogICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAid2luMzIiIGFuZCB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgICMgQWNjb3JkaW5nIHRvIG1zZG4ubWljcm9zb2Z0LmNvbSwgaXQgaXMgYW4gZXJyb3IgKEVBQ0NFUykKICAgICAgICAgICAgIyB0byB1c2UgdXRpbWUoKSBvbiBkaXJlY3Rvcmllcy4KICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgdHJ5OgogICAgICAgICAgICBvcy51dGltZSh0YXJnZXRwYXRoLCAodGFyaW5mby5tdGltZSwgdGFyaW5mby5tdGltZSkpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvciwgImNvdWxkIG5vdCBjaGFuZ2UgbW9kaWZpY2F0aW9uIHRpbWUiCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgZGVmIG5leHQoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IG1lbWJlciBvZiB0aGUgYXJjaGl2ZSBhcyBhIFRhckluZm8gb2JqZWN0LCB3aGVuCiAgICAgICAgICAgVGFyRmlsZSBpcyBvcGVuZWQgZm9yIHJlYWRpbmcuIFJldHVybiBOb25lIGlmIHRoZXJlIGlzIG5vIG1vcmUKICAgICAgICAgICBhdmFpbGFibGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soInJhIikKICAgICAgICBpZiBzZWxmLmZpcnN0bWVtYmVyIGlzIG5vdCBOb25lOgogICAgICAgICAgICBtID0gc2VsZi5maXJzdG1lbWJlcgogICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gTm9uZQogICAgICAgICAgICByZXR1cm4gbQoKICAgICAgICAjIFJlYWQgdGhlIG5leHQgYmxvY2suCiAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5jaHVua3NbLTFdKQogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhcmluZm8gPSBUYXJJbmZvLmZyb21idWYoYnVmKQogICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgIGlmIHNlbGYuaWdub3JlX3plcm9zOgogICAgICAgICAgICAgICAgICAgIGlmIGJ1Zi5jb3VudChOVUwpID09IEJMT0NLU0laRToKICAgICAgICAgICAgICAgICAgICAgICAgYWRqID0gImVtcHR5IgogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIGFkaiA9ICJpbnZhbGlkIgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAiMHglWDogJXMgYmxvY2siICUgKHNlbGYub2Zmc2V0LCBhZGopKQogICAgICAgICAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICMgQmxvY2sgaXMgZW1wdHkgb3IgdW5yZWFkYWJsZS4KICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLmNodW5rc1stMV0gPT0gMDoKICAgICAgICAgICAgICAgICAgICAgICAgIyBJZiB0aGUgZmlyc3QgYmxvY2sgaXMgaW52YWxpZC4gVGhhdCBkb2VzIG5vdAogICAgICAgICAgICAgICAgICAgICAgICAjIGxvb2sgbGlrZSBhIHRhciBhcmNoaXZlIHdlIGNhbiBoYW5kbGUuCiAgICAgICAgICAgICAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvciwiZW1wdHksIHVucmVhZGFibGUgb3IgY29tcHJlc3NlZCBmaWxlIgogICAgICAgICAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgICAgIGJyZWFrCgogICAgICAgICMgV2Ugc2hvdWxkbid0IHJlbHkgb24gdGhpcyBjaGVja3N1bSwgYmVjYXVzZSBzb21lIHRhciBwcm9ncmFtcwogICAgICAgICMgY2FsY3VsYXRlIGl0IGRpZmZlcmVudGx5IGFuZCBpdCBpcyBtZXJlbHkgdmFsaWRhdGluZyB0aGUKICAgICAgICAjIGhlYWRlciBibG9jay4gV2UgY291bGQganVzdCBhcyB3ZWxsIHNraXAgdGhpcyBwYXJ0LCB3aGljaCB3b3VsZAogICAgICAgICMgaGF2ZSBhIHNsaWdodCBlZmZlY3Qgb24gcGVyZm9ybWFuY2UuLi4KICAgICAgICBpZiB0YXJpbmZvLmNoa3N1bSAhPSBjYWxjX2Noa3N1bShidWYpOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IEJhZCBDaGVja3N1bSAlciIgJSB0YXJpbmZvLm5hbWUpCgogICAgICAgICMgU2V0IHRoZSBUYXJJbmZvIG9iamVjdCdzIG9mZnNldCB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBvZiB0aGUKICAgICAgICAjIFRhckZpbGUgYW5kIHNldCBzZWxmLm9mZnNldCB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIGRhdGEgYmxvY2tzCiAgICAgICAgIyBzaG91bGQgYmVnaW4uCiAgICAgICAgdGFyaW5mby5vZmZzZXQgPSBzZWxmLm9mZnNldAogICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQoKICAgICAgICAjIENoZWNrIGlmIHRoZSBUYXJJbmZvIG9iamVjdCBoYXMgYSB0eXBlZmxhZyBmb3Igd2hpY2ggYSBjYWxsYmFjawogICAgICAgICMgbWV0aG9kIGlzIHJlZ2lzdGVyZWQgaW4gdGhlIFRZUEVfTUVUSC4gSWYgc28sIHRoZW4gY2FsbCBpdC4KICAgICAgICBpZiB0YXJpbmZvLnR5cGUgaW4gc2VsZi5UWVBFX01FVEg6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLlRZUEVfTUVUSFt0YXJpbmZvLnR5cGVdKHNlbGYsIHRhcmluZm8pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mby5vZmZzZXRfZGF0YSA9IHNlbGYub2Zmc2V0CiAgICAgICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKSBvciB0YXJpbmZvLnR5cGUgbm90IGluIFNVUFBPUlRFRF9UWVBFUzoKICAgICAgICAgICAgICAgICMgU2tpcCB0aGUgZm9sbG93aW5nIGRhdGEgYmxvY2tzLgogICAgICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gc2VsZi5fYmxvY2sodGFyaW5mby5zaXplKQoKICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCkgYW5kIHRhcmluZm8ubmFtZVs6LTFdID09ICIvIjoKICAgICAgICAgICAgIyBzb21lIG9sZCB0YXIgcHJvZ3JhbXMgZG9uJ3Qga25vdyBESVJUWVBFCiAgICAgICAgICAgIHRhcmluZm8udHlwZSA9IERJUlRZUEUKCiAgICAgICAgc2VsZi5tZW1iZXJzLmFwcGVuZCh0YXJpbmZvKQogICAgICAgIHNlbGYubWVtYmVybmFtZXMuYXBwZW5kKHRhcmluZm8ubmFtZSkKICAgICAgICBzZWxmLmNodW5rcy5hcHBlbmQoc2VsZi5vZmZzZXQpCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgQmVsb3cgYXJlIHNvbWUgbWV0aG9kcyB3aGljaCBhcmUgY2FsbGVkIGZvciBzcGVjaWFsIHR5cGVmbGFncyBpbiB0aGUKICAgICMgbmV4dCgpIG1ldGhvZCwgZS5nLiBmb3IgdW53cmFwcGluZyBHTlUgbG9uZ25hbWUvbG9uZ2xpbmsgYmxvY2tzLiBUaGV5CiAgICAjIGFyZSByZWdpc3RlcmVkIGluIFRZUEVfTUVUSCBiZWxvdy4gWW91IGNhbiByZWdpc3RlciB5b3VyIG93biBtZXRob2RzCiAgICAjIHdpdGggdGhpcyBtYXBwaW5nLgogICAgIyBBIHJlZ2lzdGVyZWQgbWV0aG9kIGlzIGNhbGxlZCB3aXRoIGEgVGFySW5mbyBvYmplY3QgYXMgb25seSBhcmd1bWVudC4KICAgICMKICAgICMgRHVyaW5nIGl0cyBleGVjdXRpb24gdGhlIG1ldGhvZCBNVVNUIHBlcmZvcm0gdGhlIGZvbGxvd2luZyB0YXNrczoKICAgICMgMS4gc2V0IHRhcmluZm8ub2Zmc2V0X2RhdGEgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBkYXRhIGJsb2NrcyBiZWdpbiwKICAgICMgICAgaWYgdGhlcmUgaXMgZGF0YSB0byBmb2xsb3cuCiAgICAjIDIuIHNldCBzZWxmLm9mZnNldCB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIG5leHQgbWVtYmVyJ3MgaGVhZGVyIHdpbGwKICAgICMgICAgYmVnaW4uCiAgICAjIDMuIHJldHVybiBhIHZhbGlkIFRhckluZm8gb2JqZWN0LgoKICAgIGRlZiBwcm9jX2dudWxvbmcoc2VsZiwgdGFyaW5mbyk6CiAgICAgICAgIiIiRXZhbHVhdGUgdGhlIGJsb2NrcyB0aGF0IGhvbGQgYSBHTlUgbG9uZ25hbWUKICAgICAgICAgICBvciBsb25nbGluayBtZW1iZXIuCiAgICAgICAgIiIiCiAgICAgICAgYnVmID0gIiIKICAgICAgICBuYW1lID0gTm9uZQogICAgICAgIGxpbmtuYW1lID0gTm9uZQogICAgICAgIGNvdW50ID0gdGFyaW5mby5zaXplCiAgICAgICAgd2hpbGUgY291bnQgPiAwOgogICAgICAgICAgICBibG9jayA9IHNlbGYuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKICAgICAgICAgICAgYnVmICs9IGJsb2NrCiAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQogICAgICAgICAgICBjb3VudCAtPSBCTE9DS1NJWkUKCiAgICAgICAgaWYgdGFyaW5mby50eXBlID09IEdOVVRZUEVfTE9OR05BTUU6CiAgICAgICAgICAgIG5hbWUgPSBudHMoYnVmKQogICAgICAgIGlmIHRhcmluZm8udHlwZSA9PSBHTlVUWVBFX0xPTkdMSU5LOgogICAgICAgICAgICBsaW5rbmFtZSA9IG50cyhidWYpCgogICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKCiAgICAgICAgdGFyaW5mbyA9IFRhckluZm8uZnJvbWJ1ZihidWYpCiAgICAgICAgdGFyaW5mby5vZmZzZXQgPSBzZWxmLm9mZnNldAogICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQogICAgICAgIHRhcmluZm8ub2Zmc2V0X2RhdGEgPSBzZWxmLm9mZnNldAogICAgICAgIHRhcmluZm8ubmFtZSA9IG5hbWUgb3IgdGFyaW5mby5uYW1lCiAgICAgICAgdGFyaW5mby5saW5rbmFtZSA9IGxpbmtuYW1lIG9yIHRhcmluZm8ubGlua25hbWUKCiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpIG9yIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICAjIFNraXAgdGhlIGZvbGxvd2luZyBkYXRhIGJsb2Nrcy4KICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gc2VsZi5fYmxvY2sodGFyaW5mby5zaXplKQogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgZGVmIHByb2Nfc3BhcnNlKHNlbGYsIHRhcmluZm8pOgogICAgICAgICIiIkFuYWx5emUgYSBHTlUgc3BhcnNlIGhlYWRlciBwbHVzIGV4dHJhIGhlYWRlcnMuCiAgICAgICAgIiIiCiAgICAgICAgYnVmID0gdGFyaW5mby50b2J1ZigpCiAgICAgICAgc3AgPSBfcmluZ2J1ZmZlcigpCiAgICAgICAgcG9zID0gMzg2CiAgICAgICAgbGFzdHBvcyA9IDBMCiAgICAgICAgcmVhbHBvcyA9IDBMCiAgICAgICAgIyBUaGVyZSBhcmUgNCBwb3NzaWJsZSBzcGFyc2Ugc3RydWN0cyBpbiB0aGUKICAgICAgICAjIGZpcnN0IGhlYWRlci4KICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoNCk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG9mZnNldCA9IGludChidWZbcG9zOnBvcyArIDEyXSwgOCkKICAgICAgICAgICAgICAgIG51bWJ5dGVzID0gaW50KGJ1Zltwb3MgKyAxMjpwb3MgKyAyNF0sIDgpCiAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgaWYgb2Zmc2V0ID4gbGFzdHBvczoKICAgICAgICAgICAgICAgIHNwLmFwcGVuZChfaG9sZShsYXN0cG9zLCBvZmZzZXQgLSBsYXN0cG9zKSkKICAgICAgICAgICAgc3AuYXBwZW5kKF9kYXRhKG9mZnNldCwgbnVtYnl0ZXMsIHJlYWxwb3MpKQogICAgICAgICAgICByZWFscG9zICs9IG51bWJ5dGVzCiAgICAgICAgICAgIGxhc3Rwb3MgPSBvZmZzZXQgKyBudW1ieXRlcwogICAgICAgICAgICBwb3MgKz0gMjQKCiAgICAgICAgaXNleHRlbmRlZCA9IG9yZChidWZbNDgyXSkKICAgICAgICBvcmlnc2l6ZSA9IGludChidWZbNDgzOjQ5NV0sIDgpCgogICAgICAgICMgSWYgdGhlIGlzZXh0ZW5kZWQgZmxhZyBpcyBnaXZlbiwKICAgICAgICAjIHRoZXJlIGFyZSBleHRyYSBoZWFkZXJzIHRvIHByb2Nlc3MuCiAgICAgICAgd2hpbGUgaXNleHRlbmRlZCA9PSAxOgogICAgICAgICAgICBidWYgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCiAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQogICAgICAgICAgICBwb3MgPSAwCiAgICAgICAgICAgIGZvciBpIGluIHhyYW5nZSgyMSk6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gaW50KGJ1Zltwb3M6cG9zICsgMTJdLCA4KQogICAgICAgICAgICAgICAgICAgIG51bWJ5dGVzID0gaW50KGJ1Zltwb3MgKyAxMjpwb3MgKyAyNF0sIDgpCiAgICAgICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgaWYgb2Zmc2V0ID4gbGFzdHBvczoKICAgICAgICAgICAgICAgICAgICBzcC5hcHBlbmQoX2hvbGUobGFzdHBvcywgb2Zmc2V0IC0gbGFzdHBvcykpCiAgICAgICAgICAgICAgICBzcC5hcHBlbmQoX2RhdGEob2Zmc2V0LCBudW1ieXRlcywgcmVhbHBvcykpCiAgICAgICAgICAgICAgICByZWFscG9zICs9IG51bWJ5dGVzCiAgICAgICAgICAgICAgICBsYXN0cG9zID0gb2Zmc2V0ICsgbnVtYnl0ZXMKICAgICAgICAgICAgICAgIHBvcyArPSAyNAogICAgICAgICAgICBpc2V4dGVuZGVkID0gb3JkKGJ1Zls1MDRdKQoKICAgICAgICBpZiBsYXN0cG9zIDwgb3JpZ3NpemU6CiAgICAgICAgICAgIHNwLmFwcGVuZChfaG9sZShsYXN0cG9zLCBvcmlnc2l6ZSAtIGxhc3Rwb3MpKQoKICAgICAgICB0YXJpbmZvLnNwYXJzZSA9IHNwCgogICAgICAgIHRhcmluZm8ub2Zmc2V0X2RhdGEgPSBzZWxmLm9mZnNldAogICAgICAgIHNlbGYub2Zmc2V0ICs9IHNlbGYuX2Jsb2NrKHRhcmluZm8uc2l6ZSkKICAgICAgICB0YXJpbmZvLnNpemUgPSBvcmlnc2l6ZQogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgIyBUaGUgdHlwZSBtYXBwaW5nIGZvciB0aGUgbmV4dCgpIG1ldGhvZC4gVGhlIGtleXMgYXJlIHNpbmdsZSBjaGFyYWN0ZXIKICAgICMgc3RyaW5ncywgdGhlIHR5cGVmbGFnLiBUaGUgdmFsdWVzIGFyZSBtZXRob2RzIHdoaWNoIGFyZSBjYWxsZWQgd2hlbgogICAgIyBuZXh0KCkgZW5jb3VudGVycyBzdWNoIGEgdHlwZWZsYWcuCiAgICBUWVBFX01FVEggPSB7CiAgICAgICAgR05VVFlQRV9MT05HTkFNRTogcHJvY19nbnVsb25nLAogICAgICAgIEdOVVRZUEVfTE9OR0xJTks6IHByb2NfZ251bG9uZywKICAgICAgICBHTlVUWVBFX1NQQVJTRTogICBwcm9jX3NwYXJzZQogICAgfQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBMaXR0bGUgaGVscGVyIG1ldGhvZHM6CgogICAgZGVmIF9ibG9jayhzZWxmLCBjb3VudCk6CiAgICAgICAgIiIiUm91bmQgdXAgYSBieXRlIGNvdW50IGJ5IEJMT0NLU0laRSBhbmQgcmV0dXJuIGl0LAogICAgICAgICAgIGUuZy4gX2Jsb2NrKDgzNCkgPT4gMTAyNC4KICAgICAgICAiIiIKICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChjb3VudCwgQkxPQ0tTSVpFKQogICAgICAgIGlmIHJlbWFpbmRlcjoKICAgICAgICAgICAgYmxvY2tzICs9IDEKICAgICAgICByZXR1cm4gYmxvY2tzICogQkxPQ0tTSVpFCgogICAgZGVmIF9nZXRtZW1iZXIoc2VsZiwgbmFtZSwgdGFyaW5mbz1Ob25lKToKICAgICAgICAiIiJGaW5kIGFuIGFyY2hpdmUgbWVtYmVyIGJ5IG5hbWUgZnJvbSBib3R0b20gdG8gdG9wLgogICAgICAgICAgIElmIHRhcmluZm8gaXMgZ2l2ZW4sIGl0IGlzIHVzZWQgYXMgdGhlIHN0YXJ0aW5nIHBvaW50LgogICAgICAgICIiIgogICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgZW5kID0gbGVuKHNlbGYubWVtYmVycykKICAgICAgICBlbHNlOgogICAgICAgICAgICBlbmQgPSBzZWxmLm1lbWJlcnMuaW5kZXgodGFyaW5mbykKCiAgICAgICAgZm9yIGkgaW4geHJhbmdlKGVuZCAtIDEsIC0xLCAtMSk6CiAgICAgICAgICAgIGlmIG5hbWUgPT0gc2VsZi5tZW1iZXJuYW1lc1tpXToKICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLm1lbWJlcnNbaV0KCiAgICBkZWYgX2xvYWQoc2VsZik6CiAgICAgICAgIiIiUmVhZCB0aHJvdWdoIHRoZSBlbnRpcmUgYXJjaGl2ZSBmaWxlIGFuZCBsb29rIGZvciByZWFkYWJsZQogICAgICAgICAgIG1lbWJlcnMuCiAgICAgICAgIiIiCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYubmV4dCgpCiAgICAgICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgc2VsZi5fbG9hZGVkID0gVHJ1ZQoKICAgIGRlZiBfY2hlY2soc2VsZiwgbW9kZT1Ob25lKToKICAgICAgICAiIiJDaGVjayBpZiBUYXJGaWxlIGlzIHN0aWxsIG9wZW4sIGFuZCBpZiB0aGUgb3BlcmF0aW9uJ3MgbW9kZQogICAgICAgICAgIGNvcnJlc3BvbmRzIHRvIFRhckZpbGUncyBtb2RlLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yLCAiJXMgaXMgY2xvc2VkIiAlIHNlbGYuX19jbGFzc19fLl9fbmFtZV9fCiAgICAgICAgaWYgbW9kZSBpcyBub3QgTm9uZSBhbmQgc2VsZi5fbW9kZSBub3QgaW4gbW9kZToKICAgICAgICAgICAgcmFpc2UgSU9FcnJvciwgImJhZCBvcGVyYXRpb24gZm9yIG1vZGUgJXIiICUgc2VsZi5fbW9kZQoKICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKICAgICAgICAiIiJQcm92aWRlIGFuIGl0ZXJhdG9yIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLl9sb2FkZWQ6CiAgICAgICAgICAgIHJldHVybiBpdGVyKHNlbGYubWVtYmVycykKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gVGFySXRlcihzZWxmKQoKICAgIGRlZiBfY3JlYXRlX2dudWxvbmcoc2VsZiwgbmFtZSwgdHlwZSk6CiAgICAgICAgIiIiV3JpdGUgYSBHTlUgbG9uZ25hbWUvbG9uZ2xpbmsgbWVtYmVyIHRvIHRoZSBUYXJGaWxlLgogICAgICAgICAgIEl0IGNvbnNpc3RzIG9mIGFuIGV4dGVuZGVkIHRhciBoZWFkZXIsIHdpdGggdGhlIGxlbmd0aAogICAgICAgICAgIG9mIHRoZSBsb25nbmFtZSBhcyBzaXplLCBmb2xsb3dlZCBieSBkYXRhIGJsb2NrcywKICAgICAgICAgICB3aGljaCBjb250YWluIHRoZSBsb25nbmFtZSBhcyBhIG51bGwgdGVybWluYXRlZCBzdHJpbmcuCiAgICAgICAgIiIiCiAgICAgICAgdGFyaW5mbyA9IFRhckluZm8oKQogICAgICAgIHRhcmluZm8ubmFtZSA9ICIuLy4vQExvbmdMaW5rIgogICAgICAgIHRhcmluZm8udHlwZSA9IHR5cGUKICAgICAgICB0YXJpbmZvLm1vZGUgPSAwCiAgICAgICAgdGFyaW5mby5zaXplID0gbGVuKG5hbWUpCgogICAgICAgICMgd3JpdGUgZXh0ZW5kZWQgaGVhZGVyCiAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHRhcmluZm8udG9idWYoKSkKICAgICAgICAjIHdyaXRlIG5hbWUgYmxvY2tzCiAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKG5hbWUpCiAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QodGFyaW5mby5zaXplLCBCTE9DS1NJWkUpCiAgICAgICAgaWYgcmVtYWluZGVyID4gMDoKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChCTE9DS1NJWkUgLSByZW1haW5kZXIpKQogICAgICAgICAgICBibG9ja3MgKz0gMQogICAgICAgIHNlbGYub2Zmc2V0ICs9IGJsb2NrcyAqIEJMT0NLU0laRQoKICAgIGRlZiBfZGJnKHNlbGYsIGxldmVsLCBtc2cpOgogICAgICAgICIiIldyaXRlIGRlYnVnZ2luZyBvdXRwdXQgdG8gc3lzLnN0ZGVyci4KICAgICAgICAiIiIKICAgICAgICBpZiBsZXZlbCA8PSBzZWxmLmRlYnVnOgogICAgICAgICAgICBwcmludCA+PiBzeXMuc3RkZXJyLCBtc2cKIyBjbGFzcyBUYXJGaWxlCgpjbGFzcyBUYXJJdGVyOgogICAgIiIiSXRlcmF0b3IgQ2xhc3MuCgogICAgICAgZm9yIHRhcmluZm8gaW4gVGFyRmlsZSguLi4pOgogICAgICAgICAgIHN1aXRlLi4uCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgdGFyZmlsZSk6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySXRlciBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi50YXJmaWxlID0gdGFyZmlsZQogICAgZGVmIF9faXRlcl9fKHNlbGYpOgogICAgICAgICIiIlJldHVybiBpdGVyYXRvciBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYKICAgIGRlZiBuZXh0KHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgbmV4dCBpdGVtIHVzaW5nIFRhckZpbGUncyBuZXh0KCkgbWV0aG9kLgogICAgICAgICAgIFdoZW4gYWxsIG1lbWJlcnMgaGF2ZSBiZWVuIHJlYWQsIHNldCBUYXJGaWxlIGFzIF9sb2FkZWQuCiAgICAgICAgIiIiCiAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyZmlsZS5uZXh0KCkKICAgICAgICBpZiBub3QgdGFyaW5mbzoKICAgICAgICAgICAgc2VsZi50YXJmaWxlLl9sb2FkZWQgPSBUcnVlCiAgICAgICAgICAgIHJhaXNlIFN0b3BJdGVyYXRpb24KICAgICAgICByZXR1cm4gdGFyaW5mbwoKIyBIZWxwZXIgY2xhc3NlcyBmb3Igc3BhcnNlIGZpbGUgc3VwcG9ydApjbGFzcyBfc2VjdGlvbjoKICAgICIiIkJhc2UgY2xhc3MgZm9yIF9kYXRhIGFuZCBfaG9sZS4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSk6CiAgICAgICAgc2VsZi5vZmZzZXQgPSBvZmZzZXQKICAgICAgICBzZWxmLnNpemUgPSBzaXplCiAgICBkZWYgX19jb250YWluc19fKHNlbGYsIG9mZnNldCk6CiAgICAgICAgcmV0dXJuIHNlbGYub2Zmc2V0IDw9IG9mZnNldCA8IHNlbGYub2Zmc2V0ICsgc2VsZi5zaXplCgpjbGFzcyBfZGF0YShfc2VjdGlvbik6CiAgICAiIiJSZXByZXNlbnQgYSBkYXRhIHNlY3Rpb24gaW4gYSBzcGFyc2UgZmlsZS4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSwgcmVhbHBvcyk6CiAgICAgICAgX3NlY3Rpb24uX19pbml0X18oc2VsZiwgb2Zmc2V0LCBzaXplKQogICAgICAgIHNlbGYucmVhbHBvcyA9IHJlYWxwb3MKCmNsYXNzIF9ob2xlKF9zZWN0aW9uKToKICAgICIiIlJlcHJlc2VudCBhIGhvbGUgc2VjdGlvbiBpbiBhIHNwYXJzZSBmaWxlLgogICAgIiIiCiAgICBwYXNzCgpjbGFzcyBfcmluZ2J1ZmZlcihsaXN0KToKICAgICIiIlJpbmdidWZmZXIgY2xhc3Mgd2hpY2ggaW5jcmVhc2VzIHBlcmZvcm1hbmNlCiAgICAgICBvdmVyIGEgcmVndWxhciBsaXN0LgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgc2VsZi5pZHggPSAwCiAgICBkZWYgZmluZChzZWxmLCBvZmZzZXQpOgogICAgICAgIGlkeCA9IHNlbGYuaWR4CiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgaXRlbSA9IHNlbGZbaWR4XQogICAgICAgICAgICBpZiBvZmZzZXQgaW4gaXRlbToKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGlkeCArPSAxCiAgICAgICAgICAgIGlmIGlkeCA9PSBsZW4oc2VsZik6CiAgICAgICAgICAgICAgICBpZHggPSAwCiAgICAgICAgICAgIGlmIGlkeCA9PSBzZWxmLmlkeDoKICAgICAgICAgICAgICAgICMgRW5kIG9mIEZpbGUKICAgICAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgc2VsZi5pZHggPSBpZHgKICAgICAgICByZXR1cm4gaXRlbQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIHppcGZpbGUgY29tcGF0aWJsZSBUYXJGaWxlIGNsYXNzCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KVEFSX1BMQUlOID0gMCAgICAgICAgICAgIyB6aXBmaWxlLlpJUF9TVE9SRUQKVEFSX0daSVBQRUQgPSA4ICAgICAgICAgIyB6aXBmaWxlLlpJUF9ERUZMQVRFRApjbGFzcyBUYXJGaWxlQ29tcGF0OgogICAgIiIiVGFyRmlsZSBjbGFzcyBjb21wYXRpYmxlIHdpdGggc3RhbmRhcmQgbW9kdWxlIHppcGZpbGUncwogICAgICAgWmlwRmlsZSBjbGFzcy4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGUsIG1vZGU9InIiLCBjb21wcmVzc2lvbj1UQVJfUExBSU4pOgogICAgICAgIGlmIGNvbXByZXNzaW9uID09IFRBUl9QTEFJTjoKICAgICAgICAgICAgc2VsZi50YXJmaWxlID0gVGFyRmlsZS50YXJvcGVuKGZpbGUsIG1vZGUpCiAgICAgICAgZWxpZiBjb21wcmVzc2lvbiA9PSBUQVJfR1pJUFBFRDoKICAgICAgICAgICAgc2VsZi50YXJmaWxlID0gVGFyRmlsZS5nem9wZW4oZmlsZSwgbW9kZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAidW5rbm93biBjb21wcmVzc2lvbiBjb25zdGFudCIKICAgICAgICBpZiBtb2RlWzA6MV0gPT0gInIiOgogICAgICAgICAgICBtZW1iZXJzID0gc2VsZi50YXJmaWxlLmdldG1lbWJlcnMoKQogICAgICAgICAgICBmb3IgaSBpbiB4cmFuZ2UobGVuKG1lbWJlcnMpKToKICAgICAgICAgICAgICAgIG0gPSBtZW1iZXJzW2ldCiAgICAgICAgICAgICAgICBtLmZpbGVuYW1lID0gbS5uYW1lCiAgICAgICAgICAgICAgICBtLmZpbGVfc2l6ZSA9IG0uc2l6ZQogICAgICAgICAgICAgICAgbS5kYXRlX3RpbWUgPSB0aW1lLmdtdGltZShtLm10aW1lKVs6Nl0KICAgIGRlZiBuYW1lbGlzdChzZWxmKToKICAgICAgICByZXR1cm4gbWFwKGxhbWJkYSBtOiBtLm5hbWUsIHNlbGYuaW5mb2xpc3QoKSkKICAgIGRlZiBpbmZvbGlzdChzZWxmKToKICAgICAgICByZXR1cm4gZmlsdGVyKGxhbWJkYSBtOiBtLnR5cGUgaW4gUkVHVUxBUl9UWVBFUywKICAgICAgICAgICAgICAgICAgICAgIHNlbGYudGFyZmlsZS5nZXRtZW1iZXJzKCkpCiAgICBkZWYgcHJpbnRkaXIoc2VsZik6CiAgICAgICAgc2VsZi50YXJmaWxlLmxpc3QoKQogICAgZGVmIHRlc3R6aXAoc2VsZik6CiAgICAgICAgcmV0dXJuCiAgICBkZWYgZ2V0aW5mbyhzZWxmLCBuYW1lKToKICAgICAgICByZXR1cm4gc2VsZi50YXJmaWxlLmdldG1lbWJlcihuYW1lKQogICAgZGVmIHJlYWQoc2VsZiwgbmFtZSk6CiAgICAgICAgcmV0dXJuIHNlbGYudGFyZmlsZS5leHRyYWN0ZmlsZShzZWxmLnRhcmZpbGUuZ2V0bWVtYmVyKG5hbWUpKS5yZWFkKCkKICAgIGRlZiB3cml0ZShzZWxmLCBmaWxlbmFtZSwgYXJjbmFtZT1Ob25lLCBjb21wcmVzc190eXBlPU5vbmUpOgogICAgICAgIHNlbGYudGFyZmlsZS5hZGQoZmlsZW5hbWUsIGFyY25hbWUpCiAgICBkZWYgd3JpdGVzdHIoc2VsZiwgemluZm8sIGJ5dGVzKToKICAgICAgICBpbXBvcnQgU3RyaW5nSU8KICAgICAgICBpbXBvcnQgY2FsZW5kYXIKICAgICAgICB6aW5mby5uYW1lID0gemluZm8uZmlsZW5hbWUKICAgICAgICB6aW5mby5zaXplID0gemluZm8uZmlsZV9zaXplCiAgICAgICAgemluZm8ubXRpbWUgPSBjYWxlbmRhci50aW1lZ20oemluZm8uZGF0ZV90aW1lKQogICAgICAgIHNlbGYudGFyZmlsZS5hZGRmaWxlKHppbmZvLCBTdHJpbmdJTy5TdHJpbmdJTyhieXRlcykpCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgc2VsZi50YXJmaWxlLmNsb3NlKCkKI2NsYXNzIFRhckZpbGVDb21wYXQKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLQojIGV4cG9ydGVkIGZ1bmN0aW9ucwojLS0tLS0tLS0tLS0tLS0tLS0tLS0KZGVmIGlzX3RhcmZpbGUobmFtZSk6CiAgICAiIiJSZXR1cm4gVHJ1ZSBpZiBuYW1lIHBvaW50cyB0byBhIHRhciBhcmNoaXZlIHRoYXQgd2UKICAgICAgIGFyZSBhYmxlIHRvIGhhbmRsZSwgZWxzZSByZXR1cm4gRmFsc2UuCiAgICAiIiIKICAgIHRyeToKICAgICAgICB0ID0gb3BlbihuYW1lKQogICAgICAgIHQuY2xvc2UoKQogICAgICAgIHJldHVybiBUcnVlCiAgICBleGNlcHQgVGFyRXJyb3I6CiAgICAgICAgcmV0dXJuIEZhbHNlCgpvcGVuID0gVGFyRmlsZS5vcGVuCg==