ZGlmZiAtLWdpdCBhL0xpYi90YXJmaWxlLnB5IGIvTGliL3RhcmZpbGUucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2UzMzRiZQotLS0gL2Rldi9udWxsCisrKyBiL0xpYi90YXJmaWxlLnB5CkBAIC0wLDAgKzEsMTkyNyBAQAorIyEvdXNyL2Jpbi9lbnYgcHl0aG9uCisjIC0qLSBjb2Rpbmc6IGlzby04ODU5LTEgLSotCisjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIyB0YXJmaWxlLnB5CisjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIyBDb3B5cmlnaHQgKEMpIDIwMDIgTGFycyBHdXN05GJlbCA8bGFyc0BndXN0YWViZWwuZGU+CisjIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjCisjIFBlcm1pc3Npb24gIGlzICBoZXJlYnkgZ3JhbnRlZCwgIGZyZWUgIG9mIGNoYXJnZSwgIHRvICBhbnkgcGVyc29uCisjIG9idGFpbmluZyBhICBjb3B5IG9mICB0aGlzIHNvZnR3YXJlICBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uCisjIGZpbGVzICAodGhlICAiU29mdHdhcmUiKSwgIHRvICAgZGVhbCAgaW4gIHRoZSAgU29mdHdhcmUgICB3aXRob3V0CisjIHJlc3RyaWN0aW9uLCAgaW5jbHVkaW5nICB3aXRob3V0IGxpbWl0YXRpb24gIHRoZSAgcmlnaHRzIHRvICB1c2UsCisjIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCisjIGNvcGllcyAgb2YgIHRoZSAgU29mdHdhcmUsICBhbmQgdG8gIHBlcm1pdCAgcGVyc29ucyAgdG8gIHdob20gdGhlCisjIFNvZnR3YXJlICBpcyAgZnVybmlzaGVkICB0byAgZG8gIHNvLCAgc3ViamVjdCAgdG8gIHRoZSAgZm9sbG93aW5nCisjIGNvbmRpdGlvbnM6CisjCisjIFRoZSBhYm92ZSBjb3B5cmlnaHQgIG5vdGljZSBhbmQgdGhpcyAgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgIGJlCisjIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgorIworIyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTICBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZICBLSU5ELAorIyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyAgQlVUIE5PVCBMSU1JVEVEIFRPICBUSEUgV0FSUkFOVElFUworIyBPRiAgTUVSQ0hBTlRBQklMSVRZLCAgRklUTkVTUyAgIEZPUiAgQSAgUEFSVElDVUxBUiAgIFBVUlBPU0UgIEFORAorIyBOT05JTkZSSU5HRU1FTlQuICBJTiAgTk8gIEVWRU5UIFNIQUxMICBUSEUgIEFVVEhPUlMgIE9SIENPUFlSSUdIVAorIyBIT0xERVJTICBCRSBMSUFCTEUgIEZPUiBBTlkgIENMQUlNLCBEQU1BR0VTICBPUiBPVEhFUiAgTElBQklMSVRZLAorIyBXSEVUSEVSICBJTiBBTiAgQUNUSU9OIE9GICBDT05UUkFDVCwgVE9SVCAgT1IgT1RIRVJXSVNFLCAgQVJJU0lORworIyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SCisjIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KKyMKKyIiIlJlYWQgZnJvbSBhbmQgd3JpdGUgdG8gdGFyIGZvcm1hdCBhcmNoaXZlcy4KKyIiIgorCitfX3ZlcnNpb25fXyA9ICIkUmV2aXNpb24kIgorIyAkU291cmNlJAorCit2ZXJzaW9uICAgICA9ICIwLjYuNCIKK19fYXV0aG9yX18gID0gIkxhcnMgR3VzdORiZWwgKGxhcnNAZ3VzdGFlYmVsLmRlKSIKK19fZGF0ZV9fICAgID0gIiREYXRlJCIKK19fY3ZzaWRfXyAgID0gIiRJZCQiCitfX2NyZWRpdHNfXyA9ICJHdXN0YXZvIE5pZW1leWVyLCBOaWVscyBHdXN05GJlbCwgUmljaGFyZCBUb3duc2VuZC4iCisKKyMtLS0tLS0tLS0KKyMgSW1wb3J0cworIy0tLS0tLS0tLQoraW1wb3J0IHN5cworaW1wb3J0IG9zCitpbXBvcnQgc2h1dGlsCitpbXBvcnQgc3RhdAoraW1wb3J0IGVycm5vCitpbXBvcnQgdGltZQoraW1wb3J0IHN0cnVjdAorCit0cnk6CisgICAgaW1wb3J0IGdycCwgcHdkCitleGNlcHQgSW1wb3J0RXJyb3I6CisgICAgZ3JwID0gcHdkID0gTm9uZQorCisjIGZyb20gdGFyZmlsZSBpbXBvcnQgKgorX19hbGxfXyA9IFsiVGFyRmlsZSIsICJUYXJJbmZvIiwgImlzX3RhcmZpbGUiLCAiVGFyRXJyb3IiXQorCisjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjIHRhciBjb25zdGFudHMKKyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK05VTCAgICAgICAgPSAiXDAiICAgICAgICAgICAgICAgIyB0aGUgbnVsbCBjaGFyYWN0ZXIKK0JMT0NLU0laRSAgPSA1MTIgICAgICAgICAgICAgICAgIyBsZW5ndGggb2YgcHJvY2Vzc2luZyBibG9ja3MKK1JFQ09SRFNJWkUgPSBCTE9DS1NJWkUgKiAyMCAgICAgIyBsZW5ndGggb2YgcmVjb3JkcworTUFHSUMgICAgICA9ICJ1c3RhciIgICAgICAgICAgICAjIG1hZ2ljIHRhciBzdHJpbmcKK1ZFUlNJT04gICAgPSAiMDAiICAgICAgICAgICAgICAgIyB2ZXJzaW9uIG51bWJlcgorCitMRU5HVEhfTkFNRSAgICA9IDEwMCAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBmaWxlbmFtZQorTEVOR1RIX0xJTksgICAgPSAxMDAgICAgICAgICAgICAjIG1heGltdW0gbGVuZ3RoIG9mIGEgbGlua25hbWUKK0xFTkdUSF9QUkVGSVggID0gMTU1ICAgICAgICAgICAgIyBtYXhpbXVtIGxlbmd0aCBvZiB0aGUgcHJlZml4IGZpZWxkCitNQVhTSVpFX01FTUJFUiA9IDA3Nzc3Nzc3Nzc3N0wgICMgbWF4aW11bSBzaXplIG9mIGEgZmlsZSAoMTEgb2N0YWwgZGlnaXRzKQorCitSRUdUWVBFICA9ICIwIiAgICAgICAgICAgICAgICAgICMgcmVndWxhciBmaWxlCitBUkVHVFlQRSA9ICJcMCIgICAgICAgICAgICAgICAgICMgcmVndWxhciBmaWxlCitMTktUWVBFICA9ICIxIiAgICAgICAgICAgICAgICAgICMgbGluayAoaW5zaWRlIHRhcmZpbGUpCitTWU1UWVBFICA9ICIyIiAgICAgICAgICAgICAgICAgICMgc3ltYm9saWMgbGluaworQ0hSVFlQRSAgPSAiMyIgICAgICAgICAgICAgICAgICAjIGNoYXJhY3RlciBzcGVjaWFsIGRldmljZQorQkxLVFlQRSAgPSAiNCIgICAgICAgICAgICAgICAgICAjIGJsb2NrIHNwZWNpYWwgZGV2aWNlCitESVJUWVBFICA9ICI1IiAgICAgICAgICAgICAgICAgICMgZGlyZWN0b3J5CitGSUZPVFlQRSA9ICI2IiAgICAgICAgICAgICAgICAgICMgZmlmbyBzcGVjaWFsIGRldmljZQorQ09OVFRZUEUgPSAiNyIgICAgICAgICAgICAgICAgICAjIGNvbnRpZ3VvdXMgZmlsZQorCitHTlVUWVBFX0xPTkdOQU1FID0gIkwiICAgICAgICAgICMgR05VIHRhciBleHRlbnNpb24gZm9yIGxvbmduYW1lcworR05VVFlQRV9MT05HTElOSyA9ICJLIiAgICAgICAgICAjIEdOVSB0YXIgZXh0ZW5zaW9uIGZvciBsb25nbGluaworR05VVFlQRV9TUEFSU0UgICA9ICJTIiAgICAgICAgICAjIEdOVSB0YXIgZXh0ZW5zaW9uIGZvciBzcGFyc2UgZmlsZQorCisjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjIHRhcmZpbGUgY29uc3RhbnRzCisjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitTVVBQT1JURURfVFlQRVMgPSAoUkVHVFlQRSwgQVJFR1RZUEUsIExOS1RZUEUsICAjIGZpbGUgdHlwZXMgdGhhdCB0YXJmaWxlCisgICAgICAgICAgICAgICAgICAgU1lNVFlQRSwgRElSVFlQRSwgRklGT1RZUEUsICAjIGNhbiBjb3BlIHdpdGguCisgICAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIENIUlRZUEUsIEJMS1RZUEUsCisgICAgICAgICAgICAgICAgICAgR05VVFlQRV9MT05HTkFNRSwgR05VVFlQRV9MT05HTElOSywKKyAgICAgICAgICAgICAgICAgICBHTlVUWVBFX1NQQVJTRSkKKworUkVHVUxBUl9UWVBFUyA9IChSRUdUWVBFLCBBUkVHVFlQRSwgICAgICAgICAgICAgIyBmaWxlIHR5cGVzIHRoYXQgc29tZWhvdworICAgICAgICAgICAgICAgICBDT05UVFlQRSwgR05VVFlQRV9TUEFSU0UpICAgICAgIyByZXByZXNlbnQgcmVndWxhciBmaWxlcworCisjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisjIEJpdHMgdXNlZCBpbiB0aGUgbW9kZSBmaWVsZCwgdmFsdWVzIGluIG9jdGFsLgorIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorU19JRkxOSyA9IDAxMjAwMDAgICAgICAgICMgc3ltYm9saWMgbGluaworU19JRlJFRyA9IDAxMDAwMDAgICAgICAgICMgcmVndWxhciBmaWxlCitTX0lGQkxLID0gMDA2MDAwMCAgICAgICAgIyBibG9jayBkZXZpY2UKK1NfSUZESVIgPSAwMDQwMDAwICAgICAgICAjIGRpcmVjdG9yeQorU19JRkNIUiA9IDAwMjAwMDAgICAgICAgICMgY2hhcmFjdGVyIGRldmljZQorU19JRklGTyA9IDAwMTAwMDAgICAgICAgICMgZmlmbworCitUU1VJRCAgID0gMDQwMDAgICAgICAgICAgIyBzZXQgVUlEIG9uIGV4ZWN1dGlvbgorVFNHSUQgICA9IDAyMDAwICAgICAgICAgICMgc2V0IEdJRCBvbiBleGVjdXRpb24KK1RTVlRYICAgPSAwMTAwMCAgICAgICAgICAjIHJlc2VydmVkCisKK1RVUkVBRCAgPSAwNDAwICAgICAgICAgICAjIHJlYWQgYnkgb3duZXIKK1RVV1JJVEUgPSAwMjAwICAgICAgICAgICAjIHdyaXRlIGJ5IG93bmVyCitUVUVYRUMgID0gMDEwMCAgICAgICAgICAgIyBleGVjdXRlL3NlYXJjaCBieSBvd25lcgorVEdSRUFEICA9IDAwNDAgICAgICAgICAgICMgcmVhZCBieSBncm91cAorVEdXUklURSA9IDAwMjAgICAgICAgICAgICMgd3JpdGUgYnkgZ3JvdXAKK1RHRVhFQyAgPSAwMDEwICAgICAgICAgICAjIGV4ZWN1dGUvc2VhcmNoIGJ5IGdyb3VwCitUT1JFQUQgID0gMDAwNCAgICAgICAgICAgIyByZWFkIGJ5IG90aGVyCitUT1dSSVRFID0gMDAwMiAgICAgICAgICAgIyB3cml0ZSBieSBvdGhlcgorVE9FWEVDICA9IDAwMDEgICAgICAgICAgICMgZXhlY3V0ZS9zZWFyY2ggYnkgb3RoZXIKKworIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIyBTb21lIHVzZWZ1bCBmdW5jdGlvbnMKKyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK2RlZiBudHMocyk6CisgICAgIiIiQ29udmVydCBhIG51bGwtdGVybWluYXRlZCBzdHJpbmcgYnVmZmVyIHRvIGEgcHl0aG9uIHN0cmluZy4KKyAgICAiIiIKKyAgICByZXR1cm4gcy5zcGxpdChOVUwsIDEpWzBdCisKK2RlZiBjYWxjX2Noa3N1bShidWYpOgorICAgICIiIkNhbGN1bGF0ZSB0aGUgY2hlY2tzdW0gZm9yIGEgbWVtYmVyJ3MgaGVhZGVyLiBJdCdzIGEgc2ltcGxlIGFkZGl0aW9uCisgICAgICAgb2YgYWxsIGJ5dGVzLCB0cmVhdGluZyB0aGUgY2hrc3VtIGZpZWxkIGFzIGlmIGZpbGxlZCB3aXRoIHNwYWNlcy4KKyAgICAgICBidWYgaXMgYSA1MTIgYnl0ZSBsb25nIHN0cmluZyBidWZmZXIgd2hpY2ggaG9sZHMgdGhlIGhlYWRlci4KKyAgICAiIiIKKyAgICBjaGsgPSAyNTYgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGNoa3N1bSBmaWVsZCBpcyB0cmVhdGVkIGFzIGJsYW5rcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNvIHRoZSBpbml0aWFsIHZhbHVlIGlzIDggKiBvcmQoIiAiKQorICAgIGZvciBjIGluIGJ1Zls6MTQ4XTogY2hrICs9IG9yZChjKSAgICMgc3VtIHVwIGFsbCBieXRlcyBiZWZvcmUgY2hrc3VtCisgICAgZm9yIGMgaW4gYnVmWzE1NjpdOiBjaGsgKz0gb3JkKGMpICAgIyBzdW0gdXAgYWxsIGJ5dGVzIGFmdGVyIGNoa3N1bQorICAgIHJldHVybiBjaGsKKworZGVmIGNvcHlmaWxlb2JqKHNyYywgZHN0LCBsZW5ndGg9Tm9uZSk6CisgICAgIiIiQ29weSBsZW5ndGggYnl0ZXMgZnJvbSBmaWxlb2JqIHNyYyB0byBmaWxlb2JqIGRzdC4KKyAgICAgICBJZiBsZW5ndGggaXMgTm9uZSwgY29weSB0aGUgZW50aXJlIGNvbnRlbnQuCisgICAgIiIiCisgICAgaWYgbGVuZ3RoID09IDA6CisgICAgICAgIHJldHVybgorICAgIGlmIGxlbmd0aCBpcyBOb25lOgorICAgICAgICBzaHV0aWwuY29weWZpbGVvYmooc3JjLCBkc3QpCisgICAgICAgIHJldHVybgorCisgICAgQlVGU0laRSA9IDE2ICogMTAyNAorICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGxlbmd0aCwgQlVGU0laRSkKKyAgICBmb3IgYiBpbiB4cmFuZ2UoYmxvY2tzKToKKyAgICAgICAgYnVmID0gc3JjLnJlYWQoQlVGU0laRSkKKyAgICAgICAgaWYgbGVuKGJ1ZikgPCBCVUZTSVpFOgorICAgICAgICAgICAgcmFpc2UgSU9FcnJvciwgImVuZCBvZiBmaWxlIHJlYWNoZWQiCisgICAgICAgIGRzdC53cml0ZShidWYpCisKKyAgICBpZiByZW1haW5kZXIgIT0gMDoKKyAgICAgICAgYnVmID0gc3JjLnJlYWQocmVtYWluZGVyKQorICAgICAgICBpZiBsZW4oYnVmKSA8IHJlbWFpbmRlcjoKKyAgICAgICAgICAgIHJhaXNlIElPRXJyb3IsICJlbmQgb2YgZmlsZSByZWFjaGVkIgorICAgICAgICBkc3Qud3JpdGUoYnVmKQorICAgIHJldHVybgorCitmaWxlbW9kZV90YWJsZSA9ICgKKyAgICAoU19JRkxOSywgImwiLAorICAgICBTX0lGUkVHLCAiLSIsCisgICAgIFNfSUZCTEssICJiIiwKKyAgICAgU19JRkRJUiwgImQiLAorICAgICBTX0lGQ0hSLCAiYyIsCisgICAgIFNfSUZJRk8sICJwIiksCisgICAgKFRVUkVBRCwgICJyIiksCisgICAgKFRVV1JJVEUsICJ3IiksCisgICAgKFRVRVhFQywgICJ4IiwgVFNVSUQsICJTIiwgVFVFWEVDfFRTVUlELCAicyIpLAorICAgIChUR1JFQUQsICAiciIpLAorICAgIChUR1dSSVRFLCAidyIpLAorICAgIChUR0VYRUMsICAieCIsIFRTR0lELCAiUyIsIFRHRVhFQ3xUU0dJRCwgInMiKSwKKyAgICAoVE9SRUFELCAgInIiKSwKKyAgICAoVE9XUklURSwgInciKSwKKyAgICAoVE9FWEVDLCAgIngiLCBUU1ZUWCwgIlQiLCBUT0VYRUN8VFNWVFgsICJ0IikpCisKK2RlZiBmaWxlbW9kZShtb2RlKToKKyAgICAiIiJDb252ZXJ0IGEgZmlsZSdzIG1vZGUgdG8gYSBzdHJpbmcgb2YgdGhlIGZvcm0KKyAgICAgICAtcnd4cnd4cnd4LgorICAgICAgIFVzZWQgYnkgVGFyRmlsZS5saXN0KCkKKyAgICAiIiIKKyAgICBzID0gIiIKKyAgICBmb3IgdCBpbiBmaWxlbW9kZV90YWJsZToKKyAgICAgICAgd2hpbGUgVHJ1ZToKKyAgICAgICAgICAgIGlmIG1vZGUgJiB0WzBdID09IHRbMF06CisgICAgICAgICAgICAgICAgcyArPSB0WzFdCisgICAgICAgICAgICBlbGlmIGxlbih0KSA+IDI6CisgICAgICAgICAgICAgICAgdCA9IHRbMjpdCisgICAgICAgICAgICAgICAgY29udGludWUKKyAgICAgICAgICAgIGVsc2U6CisgICAgICAgICAgICAgICAgcyArPSAiLSIKKyAgICAgICAgICAgIGJyZWFrCisgICAgcmV0dXJuIHMKKworaWYgb3Muc2VwICE9ICIvIjoKKyAgICBub3JtcGF0aCA9IGxhbWJkYSBwYXRoOiBvcy5wYXRoLm5vcm1wYXRoKHBhdGgpLnJlcGxhY2Uob3Muc2VwLCAiLyIpCitlbHNlOgorICAgIG5vcm1wYXRoID0gb3MucGF0aC5ub3JtcGF0aAorCitjbGFzcyBUYXJFcnJvcihFeGNlcHRpb24pOgorICAgICIiIkJhc2UgZXhjZXB0aW9uLiIiIgorICAgIHBhc3MKK2NsYXNzIEV4dHJhY3RFcnJvcihUYXJFcnJvcik6CisgICAgIiIiR2VuZXJhbCBleGNlcHRpb24gZm9yIGV4dHJhY3QgZXJyb3JzLiIiIgorICAgIHBhc3MKK2NsYXNzIFJlYWRFcnJvcihUYXJFcnJvcik6CisgICAgIiIiRXhjZXB0aW9uIGZvciB1bnJlYWRibGUgdGFyIGFyY2hpdmVzLiIiIgorICAgIHBhc3MKK2NsYXNzIENvbXByZXNzaW9uRXJyb3IoVGFyRXJyb3IpOgorICAgICIiIkV4Y2VwdGlvbiBmb3IgdW5hdmFpbGFibGUgY29tcHJlc3Npb24gbWV0aG9kcy4iIiIKKyAgICBwYXNzCitjbGFzcyBTdHJlYW1FcnJvcihUYXJFcnJvcik6CisgICAgIiIiRXhjZXB0aW9uIGZvciB1bnN1cHBvcnRlZCBvcGVyYXRpb25zIG9uIHN0cmVhbS1saWtlIFRhckZpbGVzLiIiIgorICAgIHBhc3MKKworIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIyBpbnRlcm5hbCBzdHJlYW0gaW50ZXJmYWNlCisjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitjbGFzcyBfTG93TGV2ZWxGaWxlOgorICAgICIiIkxvdy1sZXZlbCBmaWxlIG9iamVjdC4gU3VwcG9ydHMgcmVhZGluZyBhbmQgd3JpdGluZy4KKyAgICAgICBJdCBpcyB1c2VkIGluc3RlYWQgb2YgYSByZWd1bGFyIGZpbGUgb2JqZWN0IGZvciBzdHJlYW1pbmcKKyAgICAgICBhY2Nlc3MuCisgICAgIiIiCisKKyAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSk6CisgICAgICAgIG1vZGUgPSB7CisgICAgICAgICAgICAiciI6IG9zLk9fUkRPTkxZLAorICAgICAgICAgICAgInciOiBvcy5PX1dST05MWSB8IG9zLk9fQ1JFQVQgfCBvcy5PX1RSVU5DLAorICAgICAgICB9W21vZGVdCisgICAgICAgIGlmIGhhc2F0dHIob3MsICJPX0JJTkFSWSIpOgorICAgICAgICAgICAgbW9kZSB8PSBvcy5PX0JJTkFSWQorICAgICAgICBzZWxmLmZkID0gb3Mub3BlbihuYW1lLCBtb2RlKQorCisgICAgZGVmIGNsb3NlKHNlbGYpOgorICAgICAgICBvcy5jbG9zZShzZWxmLmZkKQorCisgICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CisgICAgICAgIHJldHVybiBvcy5yZWFkKHNlbGYuZmQsIHNpemUpCisKKyAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CisgICAgICAgIG9zLndyaXRlKHNlbGYuZmQsIHMpCisKK2NsYXNzIF9TdHJlYW06CisgICAgIiIiQ2xhc3MgdGhhdCBzZXJ2ZXMgYXMgYW4gYWRhcHRlciBiZXR3ZWVuIFRhckZpbGUgYW5kCisgICAgICAgYSBzdHJlYW0tbGlrZSBvYmplY3QuICBUaGUgc3RyZWFtLWxpa2Ugb2JqZWN0IG9ubHkKKyAgICAgICBuZWVkcyB0byBoYXZlIGEgcmVhZCgpIG9yIHdyaXRlKCkgbWV0aG9kIGFuZCBpcyBhY2Nlc3NlZAorICAgICAgIGJsb2Nrd2lzZS4gIFVzZSBvZiBnemlwIG9yIGJ6aXAyIGNvbXByZXNzaW9uIGlzIHBvc3NpYmxlLgorICAgICAgIEEgc3RyZWFtLWxpa2Ugb2JqZWN0IGNvdWxkIGJlIGZvciBleGFtcGxlOiBzeXMuc3RkaW4sCisgICAgICAgc3lzLnN0ZG91dCwgYSBzb2NrZXQsIGEgdGFwZSBkZXZpY2UgZXRjLgorCisgICAgICAgX1N0cmVhbSBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIG9ubHkgaW50ZXJuYWxseS4KKyAgICAiIiIKKworICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lLCBtb2RlLCB0eXBlLCBmaWxlb2JqLCBidWZzaXplKToKKyAgICAgICAgIiIiQ29uc3RydWN0IGEgX1N0cmVhbSBvYmplY3QuCisgICAgICAgICIiIgorICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gVHJ1ZQorICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6CisgICAgICAgICAgICBmaWxlb2JqID0gX0xvd0xldmVsRmlsZShuYW1lLCBtb2RlKQorICAgICAgICAgICAgc2VsZi5fZXh0ZmlsZW9iaiA9IEZhbHNlCisKKyAgICAgICAgc2VsZi5uYW1lICAgID0gbmFtZSBvciAiIgorICAgICAgICBzZWxmLm1vZGUgICAgPSBtb2RlCisgICAgICAgIHNlbGYudHlwZSAgICA9IHR5cGUKKyAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagorICAgICAgICBzZWxmLmJ1ZnNpemUgPSBidWZzaXplCisgICAgICAgIHNlbGYuYnVmICAgICA9ICIiCisgICAgICAgIHNlbGYucG9zICAgICA9IDBMCisgICAgICAgIHNlbGYuY2xvc2VkICA9IEZhbHNlCisKKyAgICAgICAgaWYgdHlwZSA9PSAiZ3oiOgorICAgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgICAgIGltcG9ydCB6bGliCisgICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CisgICAgICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvciwgInpsaWIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiCisgICAgICAgICAgICBzZWxmLnpsaWIgPSB6bGliCisgICAgICAgICAgICBzZWxmLmNyYyA9IHpsaWIuY3JjMzIoIiIpCisgICAgICAgICAgICBpZiBtb2RlID09ICJyIjoKKyAgICAgICAgICAgICAgICBzZWxmLl9pbml0X3JlYWRfZ3ooKQorICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICBzZWxmLl9pbml0X3dyaXRlX2d6KCkKKworICAgICAgICBpZiB0eXBlID09ICJiejIiOgorICAgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgICAgIGltcG9ydCBiejIKKyAgICAgICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoKKyAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yLCAiYnoyIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIgorICAgICAgICAgICAgaWYgbW9kZSA9PSAiciI6CisgICAgICAgICAgICAgICAgc2VsZi5kYnVmID0gIiIKKyAgICAgICAgICAgICAgICBzZWxmLmNtcCA9IGJ6Mi5CWjJEZWNvbXByZXNzb3IoKQorICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICBzZWxmLmNtcCA9IGJ6Mi5CWjJDb21wcmVzc29yKCkKKworICAgIGRlZiBfX2RlbF9fKHNlbGYpOgorICAgICAgICBpZiBub3Qgc2VsZi5jbG9zZWQ6CisgICAgICAgICAgICBzZWxmLmNsb3NlKCkKKworICAgIGRlZiBfaW5pdF93cml0ZV9neihzZWxmKToKKyAgICAgICAgIiIiSW5pdGlhbGl6ZSBmb3Igd3JpdGluZyB3aXRoIGd6aXAgY29tcHJlc3Npb24uCisgICAgICAgICIiIgorICAgICAgICBzZWxmLmNtcCA9IHNlbGYuemxpYi5jb21wcmVzc29iaig5LCBzZWxmLnpsaWIuREVGTEFURUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC1zZWxmLnpsaWIuTUFYX1dCSVRTLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpsaWIuREVGX01FTV9MRVZFTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCkKKyAgICAgICAgdGltZXN0YW1wID0gc3RydWN0LnBhY2soIjxMIiwgbG9uZyh0aW1lLnRpbWUoKSkpCisgICAgICAgIHNlbGYuX193cml0ZSgiXDAzN1wyMTNcMDEwXDAxMCVzXDAwMlwzNzciICUgdGltZXN0YW1wKQorICAgICAgICBpZiBzZWxmLm5hbWUuZW5kc3dpdGgoIi5neiIpOgorICAgICAgICAgICAgc2VsZi5uYW1lID0gc2VsZi5uYW1lWzotM10KKyAgICAgICAgc2VsZi5fX3dyaXRlKHNlbGYubmFtZSArIE5VTCkKKworICAgIGRlZiB3cml0ZShzZWxmLCBzKToKKyAgICAgICAgIiIiV3JpdGUgc3RyaW5nIHMgdG8gdGhlIHN0cmVhbS4KKyAgICAgICAgIiIiCisgICAgICAgIGlmIHNlbGYudHlwZSA9PSAiZ3oiOgorICAgICAgICAgICAgc2VsZi5jcmMgPSBzZWxmLnpsaWIuY3JjMzIocywgc2VsZi5jcmMpCisgICAgICAgIHNlbGYucG9zICs9IGxlbihzKQorICAgICAgICBpZiBzZWxmLnR5cGUgIT0gInRhciI6CisgICAgICAgICAgICBzID0gc2VsZi5jbXAuY29tcHJlc3MocykKKyAgICAgICAgc2VsZi5fX3dyaXRlKHMpCisKKyAgICBkZWYgX193cml0ZShzZWxmLCBzKToKKyAgICAgICAgIiIiV3JpdGUgc3RyaW5nIHMgdG8gdGhlIHN0cmVhbSBpZiBhIHdob2xlIG5ldyBibG9jaworICAgICAgICAgICBpcyByZWFkeSB0byBiZSB3cml0dGVuLgorICAgICAgICAiIiIKKyAgICAgICAgc2VsZi5idWYgKz0gcworICAgICAgICB3aGlsZSBsZW4oc2VsZi5idWYpID4gc2VsZi5idWZzaXplOgorICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHNlbGYuYnVmWzpzZWxmLmJ1ZnNpemVdKQorICAgICAgICAgICAgc2VsZi5idWYgPSBzZWxmLmJ1ZltzZWxmLmJ1ZnNpemU6XQorCisgICAgZGVmIGNsb3NlKHNlbGYpOgorICAgICAgICAiIiJDbG9zZSB0aGUgX1N0cmVhbSBvYmplY3QuIE5vIG9wZXJhdGlvbiBzaG91bGQgYmUKKyAgICAgICAgICAgZG9uZSBvbiBpdCBhZnRlcndhcmRzLgorICAgICAgICAiIiIKKyAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CisgICAgICAgICAgICByZXR1cm4KKworICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInciIGFuZCBzZWxmLmJ1ZjoKKyAgICAgICAgICAgIGlmIHNlbGYudHlwZSAhPSAidGFyIjoKKyAgICAgICAgICAgICAgICBzZWxmLmJ1ZiArPSBzZWxmLmNtcC5mbHVzaCgpCisgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWYpCisgICAgICAgICAgICBzZWxmLmJ1ZiA9ICIiCisgICAgICAgICAgICBpZiBzZWxmLnR5cGUgPT0gImd6IjoKKyAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc3RydWN0LnBhY2soIjxsIiwgc2VsZi5jcmMpKQorICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzdHJ1Y3QucGFjaygiPEwiLCBzZWxmLnBvcykpCisKKyAgICAgICAgaWYgbm90IHNlbGYuX2V4dGZpbGVvYmo6CisgICAgICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQorCisgICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQorCisgICAgZGVmIF9pbml0X3JlYWRfZ3ooc2VsZik6CisgICAgICAgICIiIkluaXRpYWxpemUgZm9yIHJlYWRpbmcgYSBnemlwIGNvbXByZXNzZWQgZmlsZW9iai4KKyAgICAgICAgIiIiCisgICAgICAgIHNlbGYuY21wID0gc2VsZi56bGliLmRlY29tcHJlc3NvYmooLXNlbGYuemxpYi5NQVhfV0JJVFMpCisgICAgICAgIHNlbGYuZGJ1ZiA9ICIiCisKKyAgICAgICAgIyB0YWtlbiBmcm9tIGd6aXAuR3ppcEZpbGUgd2l0aCBzb21lIGFsdGVyYXRpb25zCisgICAgICAgIGlmIHNlbGYuX19yZWFkKDIpICE9ICJcMDM3XDIxMyI6CisgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IsICJub3QgYSBnemlwIGZpbGUiCisgICAgICAgIGlmIHNlbGYuX19yZWFkKDEpICE9ICJcMDEwIjoKKyAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IsICJ1bnN1cHBvcnRlZCBjb21wcmVzc2lvbiBtZXRob2QiCisKKyAgICAgICAgZmxhZyA9IG9yZChzZWxmLl9fcmVhZCgxKSkKKyAgICAgICAgc2VsZi5fX3JlYWQoNikKKworICAgICAgICBpZiBmbGFnICYgNDoKKyAgICAgICAgICAgIHhsZW4gPSBvcmQoc2VsZi5fX3JlYWQoMSkpICsgMjU2ICogb3JkKHNlbGYuX19yZWFkKDEpKQorICAgICAgICAgICAgc2VsZi5yZWFkKHhsZW4pCisgICAgICAgIGlmIGZsYWcgJiA4OgorICAgICAgICAgICAgd2hpbGUgVHJ1ZToKKyAgICAgICAgICAgICAgICBzID0gc2VsZi5fX3JlYWQoMSkKKyAgICAgICAgICAgICAgICBpZiBub3QgcyBvciBzID09IE5VTDoKKyAgICAgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgaWYgZmxhZyAmIDE2OgorICAgICAgICAgICAgd2hpbGUgVHJ1ZToKKyAgICAgICAgICAgICAgICBzID0gc2VsZi5fX3JlYWQoMSkKKyAgICAgICAgICAgICAgICBpZiBub3QgcyBvciBzID09IE5VTDoKKyAgICAgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgaWYgZmxhZyAmIDI6CisgICAgICAgICAgICBzZWxmLl9fcmVhZCgyKQorCisgICAgZGVmIHRlbGwoc2VsZik6CisgICAgICAgICIiIlJldHVybiB0aGUgc3RyZWFtJ3MgZmlsZSBwb2ludGVyIHBvc2l0aW9uLgorICAgICAgICAiIiIKKyAgICAgICAgcmV0dXJuIHNlbGYucG9zCisKKyAgICBkZWYgc2VlayhzZWxmLCBwb3M9MCk6CisgICAgICAgICIiIlNldCB0aGUgc3RyZWFtJ3MgZmlsZSBwb2ludGVyIHRvIHBvcy4gTmVnYXRpdmUgc2Vla2luZworICAgICAgICAgICBpcyBmb3JiaWRkZW4uCisgICAgICAgICIiIgorICAgICAgICBpZiBwb3MgLSBzZWxmLnBvcyA+PSAwOgorICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QocG9zIC0gc2VsZi5wb3MsIHNlbGYuYnVmc2l6ZSkKKyAgICAgICAgICAgIGZvciBpIGluIHhyYW5nZShibG9ja3MpOgorICAgICAgICAgICAgICAgIHNlbGYucmVhZChzZWxmLmJ1ZnNpemUpCisgICAgICAgICAgICBzZWxmLnJlYWQocmVtYWluZGVyKQorICAgICAgICBlbHNlOgorICAgICAgICAgICAgcmFpc2UgU3RyZWFtRXJyb3IsICJzZWVraW5nIGJhY2t3YXJkcyBpcyBub3QgYWxsb3dlZCIKKyAgICAgICAgcmV0dXJuIHNlbGYucG9zCisKKyAgICBkZWYgcmVhZChzZWxmLCBzaXplPU5vbmUpOgorICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgc2l6ZSBudW1iZXIgb2YgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtLgorICAgICAgICAgICBJZiBzaXplIGlzIG5vdCBkZWZpbmVkLCByZXR1cm4gYWxsIGJ5dGVzIG9mIHRoZSBzdHJlYW0KKyAgICAgICAgICAgdXAgdG8gRU9GLgorICAgICAgICAiIiIKKyAgICAgICAgaWYgc2l6ZSBpcyBOb25lOgorICAgICAgICAgICAgdCA9IFtdCisgICAgICAgICAgICB3aGlsZSBUcnVlOgorICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX3JlYWQoc2VsZi5idWZzaXplKQorICAgICAgICAgICAgICAgIGlmIG5vdCBidWY6CisgICAgICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgICAgICAgICAgdC5hcHBlbmQoYnVmKQorICAgICAgICAgICAgYnVmID0gIiIuam9pbih0KQorICAgICAgICBlbHNlOgorICAgICAgICAgICAgYnVmID0gc2VsZi5fcmVhZChzaXplKQorICAgICAgICBzZWxmLnBvcyArPSBsZW4oYnVmKQorICAgICAgICByZXR1cm4gYnVmCisKKyAgICBkZWYgX3JlYWQoc2VsZiwgc2l6ZSk6CisgICAgICAgICIiIlJldHVybiBzaXplIGJ5dGVzIGZyb20gdGhlIHN0cmVhbS4KKyAgICAgICAgIiIiCisgICAgICAgIGlmIHNlbGYudHlwZSA9PSAidGFyIjoKKyAgICAgICAgICAgIHJldHVybiBzZWxmLl9fcmVhZChzaXplKQorCisgICAgICAgIGMgPSBsZW4oc2VsZi5kYnVmKQorICAgICAgICB0ID0gW3NlbGYuZGJ1Zl0KKyAgICAgICAgd2hpbGUgYyA8IHNpemU6CisgICAgICAgICAgICBidWYgPSBzZWxmLl9fcmVhZChzZWxmLmJ1ZnNpemUpCisgICAgICAgICAgICBpZiBub3QgYnVmOgorICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgICAgICBidWYgPSBzZWxmLmNtcC5kZWNvbXByZXNzKGJ1ZikKKyAgICAgICAgICAgIHQuYXBwZW5kKGJ1ZikKKyAgICAgICAgICAgIGMgKz0gbGVuKGJ1ZikKKyAgICAgICAgdCA9ICIiLmpvaW4odCkKKyAgICAgICAgc2VsZi5kYnVmID0gdFtzaXplOl0KKyAgICAgICAgcmV0dXJuIHRbOnNpemVdCisKKyAgICBkZWYgX19yZWFkKHNlbGYsIHNpemUpOgorICAgICAgICAiIiJSZXR1cm4gc2l6ZSBieXRlcyBmcm9tIHN0cmVhbS4gSWYgaW50ZXJuYWwgYnVmZmVyIGlzIGVtcHR5LAorICAgICAgICAgICByZWFkIGFub3RoZXIgYmxvY2sgZnJvbSB0aGUgc3RyZWFtLgorICAgICAgICAiIiIKKyAgICAgICAgYyA9IGxlbihzZWxmLmJ1ZikKKyAgICAgICAgdCA9IFtzZWxmLmJ1Zl0KKyAgICAgICAgd2hpbGUgYyA8IHNpemU6CisgICAgICAgICAgICBidWYgPSBzZWxmLmZpbGVvYmoucmVhZChzZWxmLmJ1ZnNpemUpCisgICAgICAgICAgICBpZiBub3QgYnVmOgorICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgICAgICB0LmFwcGVuZChidWYpCisgICAgICAgICAgICBjICs9IGxlbihidWYpCisgICAgICAgIHQgPSAiIi5qb2luKHQpCisgICAgICAgIHNlbGYuYnVmID0gdFtzaXplOl0KKyAgICAgICAgcmV0dXJuIHRbOnNpemVdCisjIGNsYXNzIF9TdHJlYW0KKworIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIyBFeHRyYWN0aW9uIGZpbGUgb2JqZWN0CisjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitjbGFzcyBFeEZpbGVPYmplY3Qob2JqZWN0KToKKyAgICAiIiJGaWxlLWxpa2Ugb2JqZWN0IGZvciByZWFkaW5nIGFuIGFyY2hpdmUgbWVtYmVyLgorICAgICAgIElzIHJldHVybmVkIGJ5IFRhckZpbGUuZXh0cmFjdGZpbGUoKS4gU3VwcG9ydCBmb3IKKyAgICAgICBzcGFyc2UgZmlsZXMgaW5jbHVkZWQuCisgICAgIiIiCisKKyAgICBkZWYgX19pbml0X18oc2VsZiwgdGFyZmlsZSwgdGFyaW5mbyk6CisgICAgICAgIHNlbGYuZmlsZW9iaiA9IHRhcmZpbGUuZmlsZW9iagorICAgICAgICBzZWxmLm5hbWUgICAgPSB0YXJpbmZvLm5hbWUKKyAgICAgICAgc2VsZi5tb2RlICAgID0gInIiCisgICAgICAgIHNlbGYuY2xvc2VkICA9IEZhbHNlCisgICAgICAgIHNlbGYub2Zmc2V0ICA9IHRhcmluZm8ub2Zmc2V0X2RhdGEKKyAgICAgICAgc2VsZi5zaXplICAgID0gdGFyaW5mby5zaXplCisgICAgICAgIHNlbGYucG9zICAgICA9IDBMCisgICAgICAgIHNlbGYubGluZWJ1ZmZlciA9ICIiCisgICAgICAgIGlmIHRhcmluZm8uaXNzcGFyc2UoKToKKyAgICAgICAgICAgIHNlbGYuc3BhcnNlID0gdGFyaW5mby5zcGFyc2UKKyAgICAgICAgICAgIHNlbGYucmVhZCA9IHNlbGYuX3JlYWRzcGFyc2UKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHNlbGYucmVhZCA9IHNlbGYuX3JlYWRub3JtYWwKKworICAgIGRlZiBfX3JlYWQoc2VsZiwgc2l6ZSk6CisgICAgICAgICIiIk92ZXJsb2FkYWJsZSByZWFkIG1ldGhvZC4KKyAgICAgICAgIiIiCisgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmoucmVhZChzaXplKQorCisgICAgZGVmIHJlYWRsaW5lKHNlbGYsIHNpemU9LTEpOgorICAgICAgICAiIiJSZWFkIGEgbGluZSB3aXRoIGFwcHJveC4gc2l6ZS4gSWYgc2l6ZSBpcyBuZWdhdGl2ZSwKKyAgICAgICAgICAgcmVhZCBhIHdob2xlIGxpbmUuIHJlYWRsaW5lKCkgYW5kIHJlYWQoKSBtdXN0IG5vdAorICAgICAgICAgICBiZSBtaXhlZCB1cCAoISkuCisgICAgICAgICIiIgorICAgICAgICBpZiBzaXplIDwgMDoKKyAgICAgICAgICAgIHNpemUgPSBzeXMubWF4aW50CisKKyAgICAgICAgbmwgPSBzZWxmLmxpbmVidWZmZXIuZmluZCgiXG4iKQorICAgICAgICBpZiBubCA+PSAwOgorICAgICAgICAgICAgbmwgPSBtaW4obmwsIHNpemUpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICBzaXplIC09IGxlbihzZWxmLmxpbmVidWZmZXIpCisgICAgICAgICAgICB3aGlsZSBubCA8IDA6CisgICAgICAgICAgICAgICAgYnVmID0gc2VsZi5yZWFkKG1pbihzaXplLCAxMDApKQorICAgICAgICAgICAgICAgIGlmIG5vdCBidWY6CisgICAgICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgICAgICAgICAgc2VsZi5saW5lYnVmZmVyICs9IGJ1ZgorICAgICAgICAgICAgICAgIHNpemUgLT0gbGVuKGJ1ZikKKyAgICAgICAgICAgICAgICBpZiBzaXplIDw9IDA6CisgICAgICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgICAgICAgICAgbmwgPSBzZWxmLmxpbmVidWZmZXIuZmluZCgiXG4iKQorICAgICAgICAgICAgaWYgbmwgPT0gLTE6CisgICAgICAgICAgICAgICAgcyA9IHNlbGYubGluZWJ1ZmZlcgorICAgICAgICAgICAgICAgIHNlbGYubGluZWJ1ZmZlciA9ICIiCisgICAgICAgICAgICAgICAgcmV0dXJuIHMKKyAgICAgICAgYnVmID0gc2VsZi5saW5lYnVmZmVyWzpubF0KKyAgICAgICAgc2VsZi5saW5lYnVmZmVyID0gc2VsZi5saW5lYnVmZmVyW25sICsgMTpdCisgICAgICAgIHdoaWxlIGJ1ZlstMTpdID09ICJcciI6CisgICAgICAgICAgICBidWYgPSBidWZbOi0xXQorICAgICAgICByZXR1cm4gYnVmICsgIlxuIgorCisgICAgZGVmIHJlYWRsaW5lcyhzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuIGEgbGlzdCB3aXRoIGFsbCAoZm9sbG93aW5nKSBsaW5lcy4KKyAgICAgICAgIiIiCisgICAgICAgIHJlc3VsdCA9IFtdCisgICAgICAgIHdoaWxlIFRydWU6CisgICAgICAgICAgICBsaW5lID0gc2VsZi5yZWFkbGluZSgpCisgICAgICAgICAgICBpZiBub3QgbGluZTogYnJlYWsKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQobGluZSkKKyAgICAgICAgcmV0dXJuIHJlc3VsdAorCisgICAgZGVmIF9yZWFkbm9ybWFsKHNlbGYsIHNpemU9Tm9uZSk6CisgICAgICAgICIiIlJlYWQgb3BlcmF0aW9uIGZvciByZWd1bGFyIGZpbGVzLgorICAgICAgICAiIiIKKyAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CisgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAiZmlsZSBpcyBjbG9zZWQiCisgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0ICsgc2VsZi5wb3MpCisgICAgICAgIGJ5dGVzbGVmdCA9IHNlbGYuc2l6ZSAtIHNlbGYucG9zCisgICAgICAgIGlmIHNpemUgaXMgTm9uZToKKyAgICAgICAgICAgIGJ5dGVzdG9yZWFkID0gYnl0ZXNsZWZ0CisgICAgICAgIGVsc2U6CisgICAgICAgICAgICBieXRlc3RvcmVhZCA9IG1pbihzaXplLCBieXRlc2xlZnQpCisgICAgICAgIHNlbGYucG9zICs9IGJ5dGVzdG9yZWFkCisgICAgICAgIHJldHVybiBzZWxmLl9fcmVhZChieXRlc3RvcmVhZCkKKworICAgIGRlZiBfcmVhZHNwYXJzZShzZWxmLCBzaXplPU5vbmUpOgorICAgICAgICAiIiJSZWFkIG9wZXJhdGlvbiBmb3Igc3BhcnNlIGZpbGVzLgorICAgICAgICAiIiIKKyAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CisgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAiZmlsZSBpcyBjbG9zZWQiCisKKyAgICAgICAgaWYgc2l6ZSBpcyBOb25lOgorICAgICAgICAgICAgc2l6ZSA9IHNlbGYuc2l6ZSAtIHNlbGYucG9zCisKKyAgICAgICAgZGF0YSA9IFtdCisgICAgICAgIHdoaWxlIHNpemUgPiAwOgorICAgICAgICAgICAgYnVmID0gc2VsZi5fcmVhZHNwYXJzZXNlY3Rpb24oc2l6ZSkKKyAgICAgICAgICAgIGlmIG5vdCBidWY6CisgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgICAgIHNpemUgLT0gbGVuKGJ1ZikKKyAgICAgICAgICAgIGRhdGEuYXBwZW5kKGJ1ZikKKyAgICAgICAgcmV0dXJuICIiLmpvaW4oZGF0YSkKKworICAgIGRlZiBfcmVhZHNwYXJzZXNlY3Rpb24oc2VsZiwgc2l6ZSk6CisgICAgICAgICIiIlJlYWQgYSBzaW5nbGUgc2VjdGlvbiBvZiBhIHNwYXJzZSBmaWxlLgorICAgICAgICAiIiIKKyAgICAgICAgc2VjdGlvbiA9IHNlbGYuc3BhcnNlLmZpbmQoc2VsZi5wb3MpCisKKyAgICAgICAgaWYgc2VjdGlvbiBpcyBOb25lOgorICAgICAgICAgICAgcmV0dXJuICIiCisKKyAgICAgICAgdG9yZWFkID0gbWluKHNpemUsIHNlY3Rpb24ub2Zmc2V0ICsgc2VjdGlvbi5zaXplIC0gc2VsZi5wb3MpCisgICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VjdGlvbiwgX2RhdGEpOgorICAgICAgICAgICAgcmVhbHBvcyA9IHNlY3Rpb24ucmVhbHBvcyArIHNlbGYucG9zIC0gc2VjdGlvbi5vZmZzZXQKKyAgICAgICAgICAgIHNlbGYucG9zICs9IHRvcmVhZAorICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5vZmZzZXQgKyByZWFscG9zKQorICAgICAgICAgICAgcmV0dXJuIHNlbGYuX19yZWFkKHRvcmVhZCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHNlbGYucG9zICs9IHRvcmVhZAorICAgICAgICAgICAgcmV0dXJuIE5VTCAqIHRvcmVhZAorCisgICAgZGVmIHRlbGwoc2VsZik6CisgICAgICAgICIiIlJldHVybiB0aGUgY3VycmVudCBmaWxlIHBvc2l0aW9uLgorICAgICAgICAiIiIKKyAgICAgICAgcmV0dXJuIHNlbGYucG9zCisKKyAgICBkZWYgc2VlayhzZWxmLCBwb3MsIHdoZW5jZT0wKToKKyAgICAgICAgIiIiU2VlayB0byBhIHBvc2l0aW9uIGluIHRoZSBmaWxlLgorICAgICAgICAiIiIKKyAgICAgICAgc2VsZi5saW5lYnVmZmVyID0gIiIKKyAgICAgICAgaWYgd2hlbmNlID09IDA6CisgICAgICAgICAgICBzZWxmLnBvcyA9IG1pbihtYXgocG9zLCAwKSwgc2VsZi5zaXplKQorICAgICAgICBpZiB3aGVuY2UgPT0gMToKKyAgICAgICAgICAgIGlmIHBvcyA8IDA6CisgICAgICAgICAgICAgICAgc2VsZi5wb3MgPSBtYXgoc2VsZi5wb3MgKyBwb3MsIDApCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIHNlbGYucG9zID0gbWluKHNlbGYucG9zICsgcG9zLCBzZWxmLnNpemUpCisgICAgICAgIGlmIHdoZW5jZSA9PSAyOgorICAgICAgICAgICAgc2VsZi5wb3MgPSBtYXgobWluKHNlbGYuc2l6ZSArIHBvcywgc2VsZi5zaXplKSwgMCkKKworICAgIGRlZiBjbG9zZShzZWxmKToKKyAgICAgICAgIiIiQ2xvc2UgdGhlIGZpbGUgb2JqZWN0LgorICAgICAgICAiIiIKKyAgICAgICAgc2VsZi5jbG9zZWQgPSBUcnVlCisjY2xhc3MgRXhGaWxlT2JqZWN0CisKKyMtLS0tLS0tLS0tLS0tLS0tLS0KKyMgRXhwb3J0ZWQgQ2xhc3NlcworIy0tLS0tLS0tLS0tLS0tLS0tLQorY2xhc3MgVGFySW5mbyhvYmplY3QpOgorICAgICIiIkluZm9ybWF0aW9uYWwgY2xhc3Mgd2hpY2ggaG9sZHMgdGhlIGRldGFpbHMgYWJvdXQgYW4KKyAgICAgICBhcmNoaXZlIG1lbWJlciBnaXZlbiBieSBhIHRhciBoZWFkZXIgYmxvY2suCisgICAgICAgVGFySW5mbyBvYmplY3RzIGFyZSByZXR1cm5lZCBieSBUYXJGaWxlLmdldG1lbWJlcigpLAorICAgICAgIFRhckZpbGUuZ2V0bWVtYmVycygpIGFuZCBUYXJGaWxlLmdldHRhcmluZm8oKSBhbmQgYXJlCisgICAgICAgdXN1YWxseSBjcmVhdGVkIGludGVybmFsbHkuCisgICAgIiIiCisKKyAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZT0iIik6CisgICAgICAgICIiIkNvbnN0cnVjdCBhIFRhckluZm8gb2JqZWN0LiBuYW1lIGlzIHRoZSBvcHRpb25hbCBuYW1lCisgICAgICAgICAgIG9mIHRoZSBtZW1iZXIuCisgICAgICAgICIiIgorCisgICAgICAgIHNlbGYubmFtZSAgICAgPSBuYW1lICAgICAgICMgbWVtYmVyIG5hbWUgKGRpcm5hbWVzIG11c3QgZW5kIHdpdGggJy8nKQorICAgICAgICBzZWxmLm1vZGUgICAgID0gMDY2NiAgICAgICAjIGZpbGUgcGVybWlzc2lvbnMKKyAgICAgICAgc2VsZi51aWQgICAgICA9IDAgICAgICAgICAgIyB1c2VyIGlkCisgICAgICAgIHNlbGYuZ2lkICAgICAgPSAwICAgICAgICAgICMgZ3JvdXAgaWQKKyAgICAgICAgc2VsZi5zaXplICAgICA9IDAgICAgICAgICAgIyBmaWxlIHNpemUKKyAgICAgICAgc2VsZi5tdGltZSAgICA9IDAgICAgICAgICAgIyBtb2RpZmljYXRpb24gdGltZQorICAgICAgICBzZWxmLmNoa3N1bSAgID0gMCAgICAgICAgICAjIGhlYWRlciBjaGVja3N1bQorICAgICAgICBzZWxmLnR5cGUgICAgID0gUkVHVFlQRSAgICAjIG1lbWJlciB0eXBlCisgICAgICAgIHNlbGYubGlua25hbWUgPSAiIiAgICAgICAgICMgbGluayBuYW1lCisgICAgICAgIHNlbGYudW5hbWUgICAgPSAidXNlciIgICAgICMgdXNlciBuYW1lCisgICAgICAgIHNlbGYuZ25hbWUgICAgPSAiZ3JvdXAiICAgICMgZ3JvdXAgbmFtZQorICAgICAgICBzZWxmLmRldm1ham9yID0gMCAgICAgICAgICAjLQorICAgICAgICBzZWxmLmRldm1pbm9yID0gMCAgICAgICAgICAjLWZvciB1c2Ugd2l0aCBDSFJUWVBFIGFuZCBCTEtUWVBFCisgICAgICAgIHNlbGYucHJlZml4ICAgPSAiIiAgICAgICAgICMgcHJlZml4IHRvIGZpbGVuYW1lIG9yIGhvbGRpbmcgaW5mb3JtYXRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhYm91dCBzcGFyc2UgZmlsZXMKKworICAgICAgICBzZWxmLm9mZnNldCAgID0gMCAgICAgICAgICAjIHRoZSB0YXIgaGVhZGVyIHN0YXJ0cyBoZXJlCisgICAgICAgIHNlbGYub2Zmc2V0X2RhdGEgPSAwICAgICAgICMgdGhlIGZpbGUncyBkYXRhIHN0YXJ0cyBoZXJlCisKKyAgICBkZWYgX19yZXByX18oc2VsZik6CisgICAgICAgIHJldHVybiAiPCVzICVyIGF0ICUjeD4iICUgKHNlbGYuX19jbGFzc19fLl9fbmFtZV9fLHNlbGYubmFtZSxpZChzZWxmKSkKKworICAgIGRlZiBmcm9tYnVmKGNscywgYnVmKToKKyAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySW5mbyBvYmplY3QgZnJvbSBhIDUxMiBieXRlIHN0cmluZyBidWZmZXIuCisgICAgICAgICIiIgorICAgICAgICB0YXJpbmZvID0gY2xzKCkKKyAgICAgICAgdGFyaW5mby5uYW1lICAgPSAgbnRzKGJ1ZlswOjEwMF0pCisgICAgICAgIHRhcmluZm8ubW9kZSAgID0gaW50KGJ1ZlsxMDA6MTA4XSwgOCkKKyAgICAgICAgdGFyaW5mby51aWQgICAgPSBpbnQoYnVmWzEwODoxMTZdLDgpCisgICAgICAgIHRhcmluZm8uZ2lkICAgID0gaW50KGJ1ZlsxMTY6MTI0XSw4KQorICAgICAgICB0YXJpbmZvLnNpemUgICA9IGxvbmcoYnVmWzEyNDoxMzZdLCA4KQorICAgICAgICB0YXJpbmZvLm10aW1lICA9IGxvbmcoYnVmWzEzNjoxNDhdLCA4KQorICAgICAgICB0YXJpbmZvLmNoa3N1bSA9IGludChidWZbMTQ4OjE1Nl0sIDgpCisgICAgICAgIHRhcmluZm8udHlwZSAgID0gYnVmWzE1NjoxNTddCisgICAgICAgIHRhcmluZm8ubGlua25hbWUgPSBudHMoYnVmWzE1NzoyNTddKQorICAgICAgICB0YXJpbmZvLnVuYW1lICA9IG50cyhidWZbMjY1OjI5N10pCisgICAgICAgIHRhcmluZm8uZ25hbWUgID0gbnRzKGJ1ZlsyOTc6MzI5XSkKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgdGFyaW5mby5kZXZtYWpvciA9IGludChidWZbMzI5OjMzN10sIDgpCisgICAgICAgICAgICB0YXJpbmZvLmRldm1pbm9yID0gaW50KGJ1ZlszMzc6MzQ1XSwgOCkKKyAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CisgICAgICAgICAgICB0YXJpbmZvLmRldm1ham9yID0gdGFyaW5mby5kZXZtYWpvciA9IDAKKworICAgICAgICAjIFRoZSBwcmVmaXggZmllbGQgaXMgdXNlZCBmb3IgZmlsZW5hbWVzID4gMTAwIGluCisgICAgICAgICMgdGhlIFBPU0lYIHN0YW5kYXJkLgorICAgICAgICAjIG5hbWUgPSBwcmVmaXggKyAiLyIgKyBuYW1lCisgICAgICAgIHByZWZpeCA9IGJ1ZlszNDU6NTAwXQorICAgICAgICB3aGlsZSBwcmVmaXggYW5kIHByZWZpeFstMV0gPT0gTlVMOgorICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4WzotMV0KKyAgICAgICAgaWYgbGVuKHByZWZpeC5zcGxpdChOVUwpKSA9PSAxOgorICAgICAgICAgICAgdGFyaW5mby5wcmVmaXggPSBwcmVmaXgKKyAgICAgICAgICAgIHRhcmluZm8ubmFtZSA9IG5vcm1wYXRoKG9zLnBhdGguam9pbih0YXJpbmZvLnByZWZpeCwgdGFyaW5mby5uYW1lKSkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHRhcmluZm8ucHJlZml4ID0gYnVmWzM0NTo1MDBdCisKKyAgICAgICAgIyBEaXJlY3RvcnkgbmFtZXMgc2hvdWxkIGhhdmUgYSAnLycgYXQgdGhlIGVuZC4KKyAgICAgICAgaWYgdGFyaW5mby5pc2RpcigpIGFuZCB0YXJpbmZvLm5hbWVbLTE6XSAhPSAiLyI6CisgICAgICAgICAgICB0YXJpbmZvLm5hbWUgKz0gIi8iCisgICAgICAgIHJldHVybiB0YXJpbmZvCisKKyAgICBmcm9tYnVmID0gY2xhc3NtZXRob2QoZnJvbWJ1ZikKKworICAgIGRlZiB0b2J1ZihzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuIGEgdGFyIGhlYWRlciBibG9jayBhcyBhIDUxMiBieXRlIHN0cmluZy4KKyAgICAgICAgIiIiCisgICAgICAgIG5hbWUgPSBzZWxmLm5hbWUKKworICAgICAgICAjIFRoZSBmb2xsb3dpbmcgY29kZSB3YXMgY29udHJpYnV0ZWQgYnkgRGV0bGVmIExhbm5lcnQuCisgICAgICAgIHBhcnRzID0gW10KKyAgICAgICAgZm9yIHZhbHVlLCBmaWVsZHNpemUgaW4gKAorICAgICAgICAgICAgICAgIChuYW1lLCAxMDApLAorICAgICAgICAgICAgICAgICgiJTA3byIgJSAoc2VsZi5tb2RlICYgMDc3NzcpLCA4KSwKKyAgICAgICAgICAgICAgICAoIiUwN28iICUgc2VsZi51aWQsIDgpLAorICAgICAgICAgICAgICAgICgiJTA3byIgJSBzZWxmLmdpZCwgOCksCisgICAgICAgICAgICAgICAgKCIlMDExbyIgJSBzZWxmLnNpemUsIDEyKSwKKyAgICAgICAgICAgICAgICAoIiUwMTFvIiAlIHNlbGYubXRpbWUsIDEyKSwKKyAgICAgICAgICAgICAgICAoIiAgICAgICAgIiwgOCksCisgICAgICAgICAgICAgICAgKHNlbGYudHlwZSwgMSksCisgICAgICAgICAgICAgICAgKHNlbGYubGlua25hbWUsIDEwMCksCisgICAgICAgICAgICAgICAgKE1BR0lDLCA2KSwKKyAgICAgICAgICAgICAgICAoVkVSU0lPTiwgMiksCisgICAgICAgICAgICAgICAgKHNlbGYudW5hbWUsIDMyKSwKKyAgICAgICAgICAgICAgICAoc2VsZi5nbmFtZSwgMzIpLAorICAgICAgICAgICAgICAgICgiJTA3byIgJSBzZWxmLmRldm1ham9yLCA4KSwKKyAgICAgICAgICAgICAgICAoIiUwN28iICUgc2VsZi5kZXZtaW5vciwgOCksCisgICAgICAgICAgICAgICAgKHNlbGYucHJlZml4LCAxNTUpCisgICAgICAgICAgICApOgorICAgICAgICAgICAgbCA9IGxlbih2YWx1ZSkKKyAgICAgICAgICAgIHBhcnRzLmFwcGVuZCh2YWx1ZSArIChmaWVsZHNpemUgLSBsKSAqIE5VTCkKKworICAgICAgICBidWYgPSAiIi5qb2luKHBhcnRzKQorICAgICAgICBjaGtzdW0gPSBjYWxjX2Noa3N1bShidWYpCisgICAgICAgIGJ1ZiA9IGJ1Zls6MTQ4XSArICIlMDZvXDAiICUgY2hrc3VtICsgYnVmWzE1NTpdCisgICAgICAgIGJ1ZiArPSAoQkxPQ0tTSVpFIC0gbGVuKGJ1ZikpICogTlVMCisgICAgICAgIHNlbGYuYnVmID0gYnVmCisgICAgICAgIHJldHVybiBidWYKKworICAgIGRlZiBpc3JlZyhzZWxmKToKKyAgICAgICAgcmV0dXJuIHNlbGYudHlwZSBpbiBSRUdVTEFSX1RZUEVTCisgICAgZGVmIGlzZmlsZShzZWxmKToKKyAgICAgICAgcmV0dXJuIHNlbGYuaXNyZWcoKQorICAgIGRlZiBpc2RpcihzZWxmKToKKyAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBESVJUWVBFCisgICAgZGVmIGlzc3ltKHNlbGYpOgorICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IFNZTVRZUEUKKyAgICBkZWYgaXNsbmsoc2VsZik6CisgICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gTE5LVFlQRQorICAgIGRlZiBpc2NocihzZWxmKToKKyAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBDSFJUWVBFCisgICAgZGVmIGlzYmxrKHNlbGYpOgorICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEJMS1RZUEUKKyAgICBkZWYgaXNmaWZvKHNlbGYpOgorICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEZJRk9UWVBFCisgICAgZGVmIGlzc3BhcnNlKHNlbGYpOgorICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEdOVVRZUEVfU1BBUlNFCisgICAgZGVmIGlzZGV2KHNlbGYpOgorICAgICAgICByZXR1cm4gc2VsZi50eXBlIGluIChDSFJUWVBFLCBCTEtUWVBFLCBGSUZPVFlQRSkKKyMgY2xhc3MgVGFySW5mbworCitjbGFzcyBUYXJGaWxlKG9iamVjdCk6CisgICAgIiIiVGhlIFRhckZpbGUgQ2xhc3MgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIHRvIHRhciBhcmNoaXZlcy4KKyAgICAiIiIKKworICAgIGRlYnVnID0gMCAgICAgICAgICAgICAgICAgICAjIE1heSBiZSBzZXQgZnJvbSAwIChubyBtc2dzKSB0byAzIChhbGwgbXNncykKKworICAgIGRlcmVmZXJlbmNlID0gRmFsc2UgICAgICAgICAjIElmIHRydWUsIGFkZCBjb250ZW50IG9mIGxpbmtlZCBmaWxlIHRvIHRoZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRhciBmaWxlLCBlbHNlIHRoZSBsaW5rLgorCisgICAgaWdub3JlX3plcm9zID0gRmFsc2UgICAgICAgICMgSWYgdHJ1ZSwgc2tpcHMgZW1wdHkgb3IgaW52YWxpZCBibG9ja3MgYW5kCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY29udGludWVzIHByb2Nlc3NpbmcuCisKKyAgICBlcnJvcmxldmVsID0gMCAgICAgICAgICAgICAgIyBJZiAwLCBmYXRhbCBlcnJvcnMgb25seSBhcHBlYXIgaW4gZGVidWcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtZXNzYWdlcyAoaWYgZGVidWcgPj0gMCkuIElmID4gMCwgZXJyb3JzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJlIHBhc3NlZCB0byB0aGUgY2FsbGVyIGFzIGV4Y2VwdGlvbnMuCisKKyAgICBwb3NpeCA9IFRydWUgICAgICAgICAgICAgICAgIyBJZiBUcnVlLCBnZW5lcmF0ZXMgUE9TSVguMS0xOTkwLWNvbXBsaWFudAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFyY2hpdmVzIChubyBHTlUgZXh0ZW5zaW9ucyEpCisKKyAgICBmaWxlb2JqZWN0ID0gRXhGaWxlT2JqZWN0CisKKyAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZT1Ob25lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lKToKKyAgICAgICAgIiIiT3BlbiBhbiAodW5jb21wcmVzc2VkKSB0YXIgYXJjaGl2ZSBgbmFtZScuIGBtb2RlJyBpcyBlaXRoZXIgJ3InIHRvCisgICAgICAgICAgIHJlYWQgZnJvbSBhbiBleGlzdGluZyBhcmNoaXZlLCAnYScgdG8gYXBwZW5kIGRhdGEgdG8gYW4gZXhpc3RpbmcKKyAgICAgICAgICAgZmlsZSBvciAndycgdG8gY3JlYXRlIGEgbmV3IGZpbGUgb3ZlcndyaXRpbmcgYW4gZXhpc3Rpbmcgb25lLiBgbW9kZScKKyAgICAgICAgICAgZGVmYXVsdHMgdG8gJ3InLgorICAgICAgICAgICBJZiBgZmlsZW9iaicgaXMgZ2l2ZW4sIGl0IGlzIHVzZWQgZm9yIHJlYWRpbmcgb3Igd3JpdGluZyBkYXRhLiBJZiBpdAorICAgICAgICAgICBjYW4gYmUgZGV0ZXJtaW5lZCwgYG1vZGUnIGlzIG92ZXJyaWRkZW4gYnkgYGZpbGVvYmoncyBtb2RlLgorICAgICAgICAgICBgZmlsZW9iaicgaXMgbm90IGNsb3NlZCwgd2hlbiBUYXJGaWxlIGlzIGNsb3NlZC4KKyAgICAgICAgIiIiCisgICAgICAgIHNlbGYubmFtZSA9IG5hbWUKKworICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJyYXciOgorICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgIm1vZGUgbXVzdCBiZSAncicsICdhJyBvciAndyciCisgICAgICAgIHNlbGYuX21vZGUgPSBtb2RlCisgICAgICAgIHNlbGYubW9kZSA9IHsiciI6ICJyYiIsICJhIjogInIrYiIsICJ3IjogIndiIn1bbW9kZV0KKworICAgICAgICBpZiBub3QgZmlsZW9iajoKKyAgICAgICAgICAgIGZpbGVvYmogPSBmaWxlKHNlbGYubmFtZSwgc2VsZi5tb2RlKQorICAgICAgICAgICAgc2VsZi5fZXh0ZmlsZW9iaiA9IEZhbHNlCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICBpZiBzZWxmLm5hbWUgaXMgTm9uZSBhbmQgaGFzYXR0cihmaWxlb2JqLCAibmFtZSIpOgorICAgICAgICAgICAgICAgIHNlbGYubmFtZSA9IGZpbGVvYmoubmFtZQorICAgICAgICAgICAgaWYgaGFzYXR0cihmaWxlb2JqLCAibW9kZSIpOgorICAgICAgICAgICAgICAgIHNlbGYubW9kZSA9IGZpbGVvYmoubW9kZQorICAgICAgICAgICAgc2VsZi5fZXh0ZmlsZW9iaiA9IFRydWUKKyAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagorCisgICAgICAgICMgSW5pdCBkYXRhc3RydWN0dXJlcworICAgICAgICBzZWxmLmNsb3NlZCAgICAgID0gRmFsc2UKKyAgICAgICAgc2VsZi5tZW1iZXJzICAgICA9IFtdICAgICAgICMgbGlzdCBvZiBtZW1iZXJzIGFzIFRhckluZm8gb2JqZWN0cworICAgICAgICBzZWxmLm1lbWJlcm5hbWVzID0gW10gICAgICAgIyBuYW1lcyBvZiBtZW1iZXJzCisgICAgICAgIHNlbGYuY2h1bmtzICAgICAgPSBbMF0gICAgICAjIGNodW5rIGNhY2hlCisgICAgICAgIHNlbGYuX2xvYWRlZCAgICAgPSBGYWxzZSAgICAjIGZsYWcgaWYgYWxsIG1lbWJlcnMgaGF2ZSBiZWVuIHJlYWQKKyAgICAgICAgc2VsZi5vZmZzZXQgICAgICA9IDBMICAgICAgICMgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgYXJjaGl2ZSBmaWxlCisgICAgICAgIHNlbGYuaW5vZGVzICAgICAgPSB7fSAgICAgICAjIGRpY3Rpb25hcnkgY2FjaGluZyB0aGUgaW5vZGVzIG9mCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFyY2hpdmUgbWVtYmVycyBhbHJlYWR5IGFkZGVkCisKKyAgICAgICAgaWYgc2VsZi5fbW9kZSA9PSAiciI6CisgICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gTm9uZQorICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IHNlbGYubmV4dCgpCisKKyAgICAgICAgaWYgc2VsZi5fbW9kZSA9PSAiYSI6CisgICAgICAgICAgICAjIE1vdmUgdG8gdGhlIGVuZCBvZiB0aGUgYXJjaGl2ZSwKKyAgICAgICAgICAgICMgYmVmb3JlIHRoZSBmaXJzdCBlbXB0eSBibG9jay4KKyAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCisgICAgICAgICAgICB3aGlsZSBUcnVlOgorICAgICAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYubmV4dCgpCisgICAgICAgICAgICAgICAgZXhjZXB0IFJlYWRFcnJvcjoKKyAgICAgICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoMCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CisgICAgICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKC0gQkxPQ0tTSVpFLCAxKQorICAgICAgICAgICAgICAgICAgICBicmVhaworCisgICAgICAgIGlmIHNlbGYuX21vZGUgaW4gImF3IjoKKyAgICAgICAgICAgIHNlbGYuX2xvYWRlZCA9IFRydWUKKworICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICMgQmVsb3cgYXJlIHRoZSBjbGFzc21ldGhvZHMgd2hpY2ggYWN0IGFzIGFsdGVybmF0ZSBjb25zdHJ1Y3RvcnMgdG8gdGhlCisgICAgIyBUYXJGaWxlIGNsYXNzLiBUaGUgb3BlbigpIG1ldGhvZCBpcyB0aGUgb25seSBvbmUgdGhhdCBpcyBuZWVkZWQgZm9yCisgICAgIyBwdWJsaWMgdXNlOyBpdCBpcyB0aGUgInN1cGVyIi1jb25zdHJ1Y3RvciBhbmQgaXMgYWJsZSB0byBzZWxlY3QgYW4KKyAgICAjIGFkZXF1YXRlICJzdWIiLWNvbnN0cnVjdG9yIGZvciBhIHBhcnRpY3VsYXIgY29tcHJlc3Npb24gdXNpbmcgdGhlIG1hcHBpbmcKKyAgICAjIGZyb20gT1BFTl9NRVRILgorICAgICMKKyAgICAjIFRoaXMgY29uY2VwdCBhbGxvd3Mgb25lIHRvIHN1YmNsYXNzIFRhckZpbGUgd2l0aG91dCBsb3NpbmcgdGhlIGNvbWZvcnQgb2YKKyAgICAjIHRoZSBzdXBlci1jb25zdHJ1Y3Rvci4gQSBzdWItY29uc3RydWN0b3IgaXMgcmVnaXN0ZXJlZCBhbmQgbWFkZSBhdmFpbGFibGUKKyAgICAjIGJ5IGFkZGluZyBpdCB0byB0aGUgbWFwcGluZyBpbiBPUEVOX01FVEguCisKKyAgICBkZWYgb3BlbihjbHMsIG5hbWU9Tm9uZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgYnVmc2l6ZT0yMCo1MTIpOgorICAgICAgICAiIiJPcGVuIGEgdGFyIGFyY2hpdmUgZm9yIHJlYWRpbmcsIHdyaXRpbmcgb3IgYXBwZW5kaW5nLiBSZXR1cm4KKyAgICAgICAgICAgYW4gYXBwcm9wcmlhdGUgVGFyRmlsZSBjbGFzcy4KKworICAgICAgICAgICBtb2RlOgorICAgICAgICAgICAncicgICAgICAgICAgb3BlbiBmb3IgcmVhZGluZyB3aXRoIHRyYW5zcGFyZW50IGNvbXByZXNzaW9uCisgICAgICAgICAgICdyOicgICAgICAgICBvcGVuIGZvciByZWFkaW5nIGV4Y2x1c2l2ZWx5IHVuY29tcHJlc3NlZAorICAgICAgICAgICAncjpneicgICAgICAgb3BlbiBmb3IgcmVhZGluZyB3aXRoIGd6aXAgY29tcHJlc3Npb24KKyAgICAgICAgICAgJ3I6YnoyJyAgICAgIG9wZW4gZm9yIHJlYWRpbmcgd2l0aCBiemlwMiBjb21wcmVzc2lvbgorICAgICAgICAgICAnYScgb3IgJ2E6JyAgb3BlbiBmb3IgYXBwZW5kaW5nCisgICAgICAgICAgICd3JyBvciAndzonICBvcGVuIGZvciB3cml0aW5nIHdpdGhvdXQgY29tcHJlc3Npb24KKyAgICAgICAgICAgJ3c6Z3onICAgICAgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uCisgICAgICAgICAgICd3OmJ6MicgICAgICBvcGVuIGZvciB3cml0aW5nIHdpdGggYnppcDIgY29tcHJlc3Npb24KKyAgICAgICAgICAgJ3J8JyAgICAgICAgIG9wZW4gYW4gdW5jb21wcmVzc2VkIHN0cmVhbSBvZiB0YXIgYmxvY2tzIGZvciByZWFkaW5nCisgICAgICAgICAgICdyfGd6JyAgICAgICBvcGVuIGEgZ3ppcCBjb21wcmVzc2VkIHN0cmVhbSBvZiB0YXIgYmxvY2tzCisgICAgICAgICAgICdyfGJ6MicgICAgICBvcGVuIGEgYnppcDIgY29tcHJlc3NlZCBzdHJlYW0gb2YgdGFyIGJsb2NrcworICAgICAgICAgICAnd3wnICAgICAgICAgb3BlbiBhbiB1bmNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCisgICAgICAgICAgICd3fGd6JyAgICAgICBvcGVuIGEgZ3ppcCBjb21wcmVzc2VkIHN0cmVhbSBmb3Igd3JpdGluZworICAgICAgICAgICAnd3xiejInICAgICAgb3BlbiBhIGJ6aXAyIGNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCisgICAgICAgICIiIgorCisgICAgICAgIGlmIG5vdCBuYW1lIGFuZCBub3QgZmlsZW9iajoKKyAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJub3RoaW5nIHRvIG9wZW4iCisKKyAgICAgICAgaWYgIjoiIGluIG1vZGU6CisgICAgICAgICAgICBmaWxlbW9kZSwgY29tcHR5cGUgPSBtb2RlLnNwbGl0KCI6IiwgMSkKKyAgICAgICAgICAgIGZpbGVtb2RlID0gZmlsZW1vZGUgb3IgInIiCisgICAgICAgICAgICBjb21wdHlwZSA9IGNvbXB0eXBlIG9yICJ0YXIiCisKKyAgICAgICAgICAgICMgU2VsZWN0IHRoZSAqb3BlbigpIGZ1bmN0aW9uIGFjY29yZGluZyB0bworICAgICAgICAgICAgIyBnaXZlbiBjb21wcmVzc2lvbi4KKyAgICAgICAgICAgIGlmIGNvbXB0eXBlIGluIGNscy5PUEVOX01FVEg6CisgICAgICAgICAgICAgICAgZnVuYyA9IGdldGF0dHIoY2xzLCBjbHMuT1BFTl9NRVRIW2NvbXB0eXBlXSkKKyAgICAgICAgICAgIGVsc2U6CisgICAgICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvciwgInVua25vd24gY29tcHJlc3Npb24gdHlwZSAlciIgJSBjb21wdHlwZQorICAgICAgICAgICAgcmV0dXJuIGZ1bmMobmFtZSwgZmlsZW1vZGUsIGZpbGVvYmopCisKKyAgICAgICAgZWxpZiAifCIgaW4gbW9kZToKKyAgICAgICAgICAgIGZpbGVtb2RlLCBjb21wdHlwZSA9IG1vZGUuc3BsaXQoInwiLCAxKQorICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciIKKyAgICAgICAgICAgIGNvbXB0eXBlID0gY29tcHR5cGUgb3IgInRhciIKKworICAgICAgICAgICAgaWYgZmlsZW1vZGUgbm90IGluICJydyI6CisgICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgIm1vZGUgbXVzdCBiZSAncicgb3IgJ3cnIgorCisgICAgICAgICAgICB0ID0gY2xzKG5hbWUsIGZpbGVtb2RlLAorICAgICAgICAgICAgICAgICAgICBfU3RyZWFtKG5hbWUsIGZpbGVtb2RlLCBjb21wdHlwZSwgZmlsZW9iaiwgYnVmc2l6ZSkpCisgICAgICAgICAgICB0Ll9leHRmaWxlb2JqID0gRmFsc2UKKyAgICAgICAgICAgIHJldHVybiB0CisKKyAgICAgICAgZWxpZiBtb2RlID09ICJyIjoKKyAgICAgICAgICAgICMgRmluZCBvdXQgd2hpY2ggKm9wZW4oKSBpcyBhcHByb3ByaWF0ZSBmb3Igb3BlbmluZyB0aGUgZmlsZS4KKyAgICAgICAgICAgIGZvciBjb21wdHlwZSBpbiBjbHMuT1BFTl9NRVRIOgorICAgICAgICAgICAgICAgIGZ1bmMgPSBnZXRhdHRyKGNscywgY2xzLk9QRU5fTUVUSFtjb21wdHlwZV0pCisgICAgICAgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnVuYyhuYW1lLCAiciIsIGZpbGVvYmopCisgICAgICAgICAgICAgICAgZXhjZXB0IChSZWFkRXJyb3IsIENvbXByZXNzaW9uRXJyb3IpOgorICAgICAgICAgICAgICAgICAgICBjb250aW51ZQorICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yLCAiZmlsZSBjb3VsZCBub3QgYmUgb3BlbmVkIHN1Y2Nlc3NmdWxseSIKKworICAgICAgICBlbGlmIG1vZGUgaW4gImF3IjoKKyAgICAgICAgICAgIHJldHVybiBjbHMudGFyb3BlbihuYW1lLCBtb2RlLCBmaWxlb2JqKQorCisgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJ1bmRpc2Nlcm5pYmxlIG1vZGUiCisKKyAgICBvcGVuID0gY2xhc3NtZXRob2Qob3BlbikKKworICAgIGRlZiB0YXJvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSk6CisgICAgICAgICIiIk9wZW4gdW5jb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KKyAgICAgICAgIiIiCisgICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJhdyI6CisgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAibW9kZSBtdXN0IGJlICdyJywgJ2EnIG9yICd3JyIKKyAgICAgICAgcmV0dXJuIGNscyhuYW1lLCBtb2RlLCBmaWxlb2JqKQorCisgICAgdGFyb3BlbiA9IGNsYXNzbWV0aG9kKHRhcm9wZW4pCisKKyAgICBkZWYgZ3pvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgY29tcHJlc3NsZXZlbD05KToKKyAgICAgICAgIiIiT3BlbiBnemlwIGNvbXByZXNzZWQgdGFyIGFyY2hpdmUgbmFtZSBmb3IgcmVhZGluZyBvciB3cml0aW5nLgorICAgICAgICAgICBBcHBlbmRpbmcgaXMgbm90IGFsbG93ZWQuCisgICAgICAgICIiIgorICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJydyI6CisgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAibW9kZSBtdXN0IGJlICdyJyBvciAndyciCisKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgaW1wb3J0IGd6aXAKKyAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgorICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvciwgImd6aXAgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiCisKKyAgICAgICAgcHJlLCBleHQgPSBvcy5wYXRoLnNwbGl0ZXh0KG5hbWUpCisgICAgICAgIHByZSA9IG9zLnBhdGguYmFzZW5hbWUocHJlKQorICAgICAgICBpZiBleHQgPT0gIi50Z3oiOgorICAgICAgICAgICAgZXh0ID0gIi50YXIiCisgICAgICAgIGlmIGV4dCA9PSAiLmd6IjoKKyAgICAgICAgICAgIGV4dCA9ICIiCisgICAgICAgIHRhcm5hbWUgPSBwcmUgKyBleHQKKworICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6CisgICAgICAgICAgICBmaWxlb2JqID0gZmlsZShuYW1lLCBtb2RlICsgImIiKQorCisgICAgICAgIGlmIG1vZGUgIT0gInIiOgorICAgICAgICAgICAgbmFtZSA9IHRhcm5hbWUKKworICAgICAgICB0cnk6CisgICAgICAgICAgICB0ID0gY2xzLnRhcm9wZW4odGFybmFtZSwgbW9kZSwKKyAgICAgICAgICAgICAgICBnemlwLkd6aXBGaWxlKG5hbWUsIG1vZGUsIGNvbXByZXNzbGV2ZWwsIGZpbGVvYmopCisgICAgICAgICAgICApCisgICAgICAgIGV4Y2VwdCBJT0Vycm9yOgorICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yLCAibm90IGEgZ3ppcCBmaWxlIgorICAgICAgICB0Ll9leHRmaWxlb2JqID0gRmFsc2UKKyAgICAgICAgcmV0dXJuIHQKKworICAgIGd6b3BlbiA9IGNsYXNzbWV0aG9kKGd6b3BlbikKKworICAgIGRlZiBiejJvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgY29tcHJlc3NsZXZlbD05KToKKyAgICAgICAgIiIiT3BlbiBiemlwMiBjb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KKyAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgorICAgICAgICAiIiIKKyAgICAgICAgaWYgbGVuKG1vZGUpID4gMSBvciBtb2RlIG5vdCBpbiAicnciOgorICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgIm1vZGUgbXVzdCBiZSAncicgb3IgJ3cnLiIKKworICAgICAgICB0cnk6CisgICAgICAgICAgICBpbXBvcnQgYnoyCisgICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoKKyAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IsICJiejIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiCisKKyAgICAgICAgcHJlLCBleHQgPSBvcy5wYXRoLnNwbGl0ZXh0KG5hbWUpCisgICAgICAgIHByZSA9IG9zLnBhdGguYmFzZW5hbWUocHJlKQorICAgICAgICBpZiBleHQgPT0gIi50YnoyIjoKKyAgICAgICAgICAgIGV4dCA9ICIudGFyIgorICAgICAgICBpZiBleHQgPT0gIi5iejIiOgorICAgICAgICAgICAgZXh0ID0gIiIKKyAgICAgICAgdGFybmFtZSA9IHByZSArIGV4dAorCisgICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CisgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAibm8gc3VwcG9ydCBmb3IgZXh0ZXJuYWwgZmlsZSBvYmplY3RzIgorCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIHQgPSBjbHMudGFyb3Blbih0YXJuYW1lLCBtb2RlLCBiejIuQloyRmlsZShuYW1lLCBtb2RlLCBjb21wcmVzc2xldmVsPWNvbXByZXNzbGV2ZWwpKQorICAgICAgICBleGNlcHQgSU9FcnJvcjoKKyAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvciwgIm5vdCBhIGJ6aXAyIGZpbGUiCisgICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQorICAgICAgICByZXR1cm4gdAorCisgICAgYnoyb3BlbiA9IGNsYXNzbWV0aG9kKGJ6Mm9wZW4pCisKKyAgICAjIEFsbCAqb3BlbigpIG1ldGhvZHMgYXJlIHJlZ2lzdGVyZWQgaGVyZS4KKyAgICBPUEVOX01FVEggPSB7CisgICAgICAgICJ0YXIiOiAidGFyb3BlbiIsICAgIyB1bmNvbXByZXNzZWQgdGFyCisgICAgICAgICJneiI6ICAiZ3pvcGVuIiwgICAgIyBnemlwIGNvbXByZXNzZWQgdGFyCisgICAgICAgICJiejIiOiAiYnoyb3BlbiIgICAgIyBiemlwMiBjb21wcmVzc2VkIHRhcgorICAgIH0KKworICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICMgVGhlIHB1YmxpYyBtZXRob2RzIHdoaWNoIFRhckZpbGUgcHJvdmlkZXM6CisKKyAgICBkZWYgY2xvc2Uoc2VsZik6CisgICAgICAgICIiIkNsb3NlIHRoZSBUYXJGaWxlLiBJbiB3cml0ZS1tb2RlLCB0d28gZmluaXNoaW5nIHplcm8gYmxvY2tzIGFyZQorICAgICAgICAgICBhcHBlbmRlZCB0byB0aGUgYXJjaGl2ZS4KKyAgICAgICAgIiIiCisgICAgICAgIGlmIHNlbGYuY2xvc2VkOgorICAgICAgICAgICAgcmV0dXJuCisKKyAgICAgICAgaWYgc2VsZi5fbW9kZSBpbiAiYXciOgorICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChCTE9DS1NJWkUgKiAyKSkKKyAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IChCTE9DS1NJWkUgKiAyKQorICAgICAgICAgICAgIyBmaWxsIHVwIHRoZSBlbmQgd2l0aCB6ZXJvLWJsb2NrcworICAgICAgICAgICAgIyAobGlrZSBvcHRpb24gLWIyMCBmb3IgdGFyIGRvZXMpCisgICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChzZWxmLm9mZnNldCwgUkVDT1JEU0laRSkKKyAgICAgICAgICAgIGlmIHJlbWFpbmRlciA+IDA6CisgICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChSRUNPUkRTSVpFIC0gcmVtYWluZGVyKSkKKworICAgICAgICBpZiBub3Qgc2VsZi5fZXh0ZmlsZW9iajoKKyAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCisgICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQorCisgICAgZGVmIGdldG1lbWJlcihzZWxmLCBuYW1lKToKKyAgICAgICAgIiIiUmV0dXJuIGEgVGFySW5mbyBvYmplY3QgZm9yIG1lbWJlciBgbmFtZScuIElmIGBuYW1lJyBjYW4gbm90IGJlCisgICAgICAgICAgIGZvdW5kIGluIHRoZSBhcmNoaXZlLCBLZXlFcnJvciBpcyByYWlzZWQuIElmIGEgbWVtYmVyIG9jY3VycyBtb3JlCisgICAgICAgICAgIHRoYW4gb25jZSBpbiB0aGUgYXJjaGl2ZSwgaXRzIGxhc3Qgb2NjdXJlbmNlIGlzIGFzc3VtZWQgdG8gYmUgdGhlCisgICAgICAgICAgIG1vc3QgdXAtdG8tZGF0ZSB2ZXJzaW9uLgorICAgICAgICAiIiIKKyAgICAgICAgc2VsZi5fY2hlY2soKQorICAgICAgICBpZiBuYW1lIG5vdCBpbiBzZWxmLm1lbWJlcm5hbWVzIGFuZCBub3Qgc2VsZi5fbG9hZGVkOgorICAgICAgICAgICAgc2VsZi5fbG9hZCgpCisgICAgICAgIGlmIG5hbWUgbm90IGluIHNlbGYubWVtYmVybmFtZXM6CisgICAgICAgICAgICByYWlzZSBLZXlFcnJvciwgImZpbGVuYW1lICVyIG5vdCBmb3VuZCIgJSBuYW1lCisgICAgICAgIHJldHVybiBzZWxmLl9nZXRtZW1iZXIobmFtZSkKKworICAgIGRlZiBnZXRtZW1iZXJzKHNlbGYpOgorICAgICAgICAiIiJSZXR1cm4gdGhlIG1lbWJlcnMgb2YgdGhlIGFyY2hpdmUgYXMgYSBsaXN0IG9mIFRhckluZm8gb2JqZWN0cy4gVGhlCisgICAgICAgICAgIGxpc3QgaGFzIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBtZW1iZXJzIGluIHRoZSBhcmNoaXZlLgorICAgICAgICAiIiIKKyAgICAgICAgc2VsZi5fY2hlY2soKQorICAgICAgICBpZiBub3Qgc2VsZi5fbG9hZGVkOiAgICAjIGlmIHdlIHdhbnQgdG8gb2J0YWluIGEgbGlzdCBvZgorICAgICAgICAgICAgc2VsZi5fbG9hZCgpICAgICAgICAjIGFsbCBtZW1iZXJzLCB3ZSBmaXJzdCBoYXZlIHRvCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc2NhbiB0aGUgd2hvbGUgYXJjaGl2ZS4KKyAgICAgICAgcmV0dXJuIHNlbGYubWVtYmVycworCisgICAgZGVmIGdldG5hbWVzKHNlbGYpOgorICAgICAgICAiIiJSZXR1cm4gdGhlIG1lbWJlcnMgb2YgdGhlIGFyY2hpdmUgYXMgYSBsaXN0IG9mIHRoZWlyIG5hbWVzLiBJdCBoYXMKKyAgICAgICAgICAgdGhlIHNhbWUgb3JkZXIgYXMgdGhlIGxpc3QgcmV0dXJuZWQgYnkgZ2V0bWVtYmVycygpLgorICAgICAgICAiIiIKKyAgICAgICAgc2VsZi5fY2hlY2soKQorICAgICAgICBpZiBub3Qgc2VsZi5fbG9hZGVkOgorICAgICAgICAgICAgc2VsZi5fbG9hZCgpCisgICAgICAgIHJldHVybiBzZWxmLm1lbWJlcm5hbWVzCisKKyAgICBkZWYgZ2V0dGFyaW5mbyhzZWxmLCBuYW1lPU5vbmUsIGFyY25hbWU9Tm9uZSwgZmlsZW9iaj1Ob25lKToKKyAgICAgICAgIiIiQ3JlYXRlIGEgVGFySW5mbyBvYmplY3QgZm9yIGVpdGhlciB0aGUgZmlsZSBgbmFtZScgb3IgdGhlIGZpbGUKKyAgICAgICAgICAgb2JqZWN0IGBmaWxlb2JqJyAodXNpbmcgb3MuZnN0YXQgb24gaXRzIGZpbGUgZGVzY3JpcHRvcikuIFlvdSBjYW4KKyAgICAgICAgICAgbW9kaWZ5IHNvbWUgb2YgdGhlIFRhckluZm8ncyBhdHRyaWJ1dGVzIGJlZm9yZSB5b3UgYWRkIGl0IHVzaW5nCisgICAgICAgICAgIGFkZGZpbGUoKS4gSWYgZ2l2ZW4sIGBhcmNuYW1lJyBzcGVjaWZpZXMgYW4gYWx0ZXJuYXRpdmUgbmFtZSBmb3IgdGhlCisgICAgICAgICAgIGZpbGUgaW4gdGhlIGFyY2hpdmUuCisgICAgICAgICIiIgorICAgICAgICBzZWxmLl9jaGVjaygiYXciKQorCisgICAgICAgICMgV2hlbiBmaWxlb2JqIGlzIGdpdmVuLCByZXBsYWNlIG5hbWUgYnkKKyAgICAgICAgIyBmaWxlb2JqJ3MgcmVhbCBuYW1lLgorICAgICAgICBpZiBmaWxlb2JqIGlzIG5vdCBOb25lOgorICAgICAgICAgICAgbmFtZSA9IGZpbGVvYmoubmFtZQorCisgICAgICAgICMgQnVpbGRpbmcgdGhlIG5hbWUgb2YgdGhlIG1lbWJlciBpbiB0aGUgYXJjaGl2ZS4KKyAgICAgICAgIyBCYWNrd2FyZCBzbGFzaGVzIGFyZSBjb252ZXJ0ZWQgdG8gZm9yd2FyZCBzbGFzaGVzLAorICAgICAgICAjIEFic29sdXRlIHBhdGhzIGFyZSB0dXJuZWQgdG8gcmVsYXRpdmUgcGF0aHMuCisgICAgICAgIGlmIGFyY25hbWUgaXMgTm9uZToKKyAgICAgICAgICAgIGFyY25hbWUgPSBuYW1lCisgICAgICAgIGFyY25hbWUgPSBub3JtcGF0aChhcmNuYW1lKQorICAgICAgICBkcnYsIGFyY25hbWUgPSBvcy5wYXRoLnNwbGl0ZHJpdmUoYXJjbmFtZSkKKyAgICAgICAgd2hpbGUgYXJjbmFtZVswOjFdID09ICIvIjoKKyAgICAgICAgICAgIGFyY25hbWUgPSBhcmNuYW1lWzE6XQorCisgICAgICAgICMgTm93LCBmaWxsIHRoZSBUYXJJbmZvIG9iamVjdCB3aXRoCisgICAgICAgICMgaW5mb3JtYXRpb24gc3BlY2lmaWMgZm9yIHRoZSBmaWxlLgorICAgICAgICB0YXJpbmZvID0gVGFySW5mbygpCisKKyAgICAgICAgIyBVc2Ugb3Muc3RhdCBvciBvcy5sc3RhdCwgZGVwZW5kaW5nIG9uIHBsYXRmb3JtCisgICAgICAgICMgYW5kIGlmIHN5bWxpbmtzIHNoYWxsIGJlIHJlc29sdmVkLgorICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6CisgICAgICAgICAgICBpZiBoYXNhdHRyKG9zLCAibHN0YXQiKSBhbmQgbm90IHNlbGYuZGVyZWZlcmVuY2U6CisgICAgICAgICAgICAgICAgc3RhdHJlcyA9IG9zLmxzdGF0KG5hbWUpCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIHN0YXRyZXMgPSBvcy5zdGF0KG5hbWUpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICBzdGF0cmVzID0gb3MuZnN0YXQoZmlsZW9iai5maWxlbm8oKSkKKyAgICAgICAgbGlua25hbWUgPSAiIgorCisgICAgICAgIHN0bWQgPSBzdGF0cmVzLnN0X21vZGUKKyAgICAgICAgaWYgc3RhdC5TX0lTUkVHKHN0bWQpOgorICAgICAgICAgICAgaW5vZGUgPSAoc3RhdHJlcy5zdF9pbm8sIHN0YXRyZXMuc3RfZGV2KQorICAgICAgICAgICAgaWYgaW5vZGUgaW4gc2VsZi5pbm9kZXMgYW5kIG5vdCBzZWxmLmRlcmVmZXJlbmNlOgorICAgICAgICAgICAgICAgICMgSXMgaXQgYSBoYXJkbGluayB0byBhbiBhbHJlYWR5CisgICAgICAgICAgICAgICAgIyBhcmNoaXZlZCBmaWxlPworICAgICAgICAgICAgICAgIHR5cGUgPSBMTktUWVBFCisgICAgICAgICAgICAgICAgbGlua25hbWUgPSBzZWxmLmlub2Rlc1tpbm9kZV0KKyAgICAgICAgICAgIGVsc2U6CisgICAgICAgICAgICAgICAgIyBUaGUgaW5vZGUgaXMgYWRkZWQgb25seSBpZiBpdHMgdmFsaWQuCisgICAgICAgICAgICAgICAgIyBGb3Igd2luMzIgaXQgaXMgYWx3YXlzIDAuCisgICAgICAgICAgICAgICAgdHlwZSA9IFJFR1RZUEUKKyAgICAgICAgICAgICAgICBpZiBpbm9kZVswXToKKyAgICAgICAgICAgICAgICAgICAgc2VsZi5pbm9kZXNbaW5vZGVdID0gYXJjbmFtZQorICAgICAgICBlbGlmIHN0YXQuU19JU0RJUihzdG1kKToKKyAgICAgICAgICAgIHR5cGUgPSBESVJUWVBFCisgICAgICAgICAgICBpZiBhcmNuYW1lWy0xOl0gIT0gIi8iOgorICAgICAgICAgICAgICAgIGFyY25hbWUgKz0gIi8iCisgICAgICAgIGVsaWYgc3RhdC5TX0lTRklGTyhzdG1kKToKKyAgICAgICAgICAgIHR5cGUgPSBGSUZPVFlQRQorICAgICAgICBlbGlmIHN0YXQuU19JU0xOSyhzdG1kKToKKyAgICAgICAgICAgIHR5cGUgPSBTWU1UWVBFCisgICAgICAgICAgICBsaW5rbmFtZSA9IG9zLnJlYWRsaW5rKG5hbWUpCisgICAgICAgIGVsaWYgc3RhdC5TX0lTQ0hSKHN0bWQpOgorICAgICAgICAgICAgdHlwZSA9IENIUlRZUEUKKyAgICAgICAgZWxpZiBzdGF0LlNfSVNCTEsoc3RtZCk6CisgICAgICAgICAgICB0eXBlID0gQkxLVFlQRQorICAgICAgICBlbHNlOgorICAgICAgICAgICAgcmV0dXJuIE5vbmUKKworICAgICAgICAjIEZpbGwgdGhlIFRhckluZm8gb2JqZWN0IHdpdGggYWxsCisgICAgICAgICMgaW5mb3JtYXRpb24gd2UgY2FuIGdldC4KKyAgICAgICAgdGFyaW5mby5uYW1lICA9IGFyY25hbWUKKyAgICAgICAgdGFyaW5mby5tb2RlICA9IHN0bWQKKyAgICAgICAgdGFyaW5mby51aWQgICA9IHN0YXRyZXMuc3RfdWlkCisgICAgICAgIHRhcmluZm8uZ2lkICAgPSBzdGF0cmVzLnN0X2dpZAorICAgICAgICB0YXJpbmZvLnNpemUgID0gc3RhdHJlcy5zdF9zaXplCisgICAgICAgIHRhcmluZm8ubXRpbWUgPSBzdGF0cmVzLnN0X210aW1lCisgICAgICAgIHRhcmluZm8udHlwZSAgPSB0eXBlCisgICAgICAgIHRhcmluZm8ubGlua25hbWUgPSBsaW5rbmFtZQorICAgICAgICBpZiBwd2Q6CisgICAgICAgICAgICB0cnk6CisgICAgICAgICAgICAgICAgdGFyaW5mby51bmFtZSA9IHB3ZC5nZXRwd3VpZCh0YXJpbmZvLnVpZClbMF0KKyAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKKyAgICAgICAgICAgICAgICBwYXNzCisgICAgICAgIGlmIGdycDoKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICB0YXJpbmZvLmduYW1lID0gZ3JwLmdldGdyZ2lkKHRhcmluZm8uZ2lkKVswXQorICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgorICAgICAgICAgICAgICAgIHBhc3MKKworICAgICAgICBpZiB0eXBlIGluIChDSFJUWVBFLCBCTEtUWVBFKToKKyAgICAgICAgICAgIGlmIGhhc2F0dHIob3MsICJtYWpvciIpIGFuZCBoYXNhdHRyKG9zLCAibWlub3IiKToKKyAgICAgICAgICAgICAgICB0YXJpbmZvLmRldm1ham9yID0gb3MubWFqb3Ioc3RhdHJlcy5zdF9yZGV2KQorICAgICAgICAgICAgICAgIHRhcmluZm8uZGV2bWlub3IgPSBvcy5taW5vcihzdGF0cmVzLnN0X3JkZXYpCisgICAgICAgIHJldHVybiB0YXJpbmZvCisKKyAgICBkZWYgbGlzdChzZWxmLCB2ZXJib3NlPVRydWUpOgorICAgICAgICAiIiJQcmludCBhIHRhYmxlIG9mIGNvbnRlbnRzIHRvIHN5cy5zdGRvdXQuIElmIGB2ZXJib3NlJyBpcyBGYWxzZSwgb25seQorICAgICAgICAgICB0aGUgbmFtZXMgb2YgdGhlIG1lbWJlcnMgYXJlIHByaW50ZWQuIElmIGl0IGlzIFRydWUsIGFuIGBscyAtbCctbGlrZQorICAgICAgICAgICBvdXRwdXQgaXMgcHJvZHVjZWQuCisgICAgICAgICIiIgorICAgICAgICBzZWxmLl9jaGVjaygpCisKKyAgICAgICAgZm9yIHRhcmluZm8gaW4gc2VsZjoKKyAgICAgICAgICAgIGlmIHZlcmJvc2U6CisgICAgICAgICAgICAgICAgcHJpbnQgZmlsZW1vZGUodGFyaW5mby5tb2RlKSwKKyAgICAgICAgICAgICAgICBwcmludCAiJXMvJXMiICUgKHRhcmluZm8udW5hbWUgb3IgdGFyaW5mby51aWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvLmduYW1lIG9yIHRhcmluZm8uZ2lkKSwKKyAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzY2hyKCkgb3IgdGFyaW5mby5pc2JsaygpOgorICAgICAgICAgICAgICAgICAgICBwcmludCAiJTEwcyIgJSAoIiVkLCVkIiBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAlICh0YXJpbmZvLmRldm1ham9yLCB0YXJpbmZvLmRldm1pbm9yKSksCisgICAgICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICAgICAgcHJpbnQgIiUxMGQiICUgdGFyaW5mby5zaXplLAorICAgICAgICAgICAgICAgIHByaW50ICIlZC0lMDJkLSUwMmQgJTAyZDolMDJkOiUwMmQiIFwKKyAgICAgICAgICAgICAgICAgICAgICAlIHRpbWUubG9jYWx0aW1lKHRhcmluZm8ubXRpbWUpWzo2XSwKKworICAgICAgICAgICAgcHJpbnQgdGFyaW5mby5uYW1lLAorCisgICAgICAgICAgICBpZiB2ZXJib3NlOgorICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKToKKyAgICAgICAgICAgICAgICAgICAgcHJpbnQgIi0+IiwgdGFyaW5mby5saW5rbmFtZSwKKyAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzbG5rKCk6CisgICAgICAgICAgICAgICAgICAgIHByaW50ICJsaW5rIHRvIiwgdGFyaW5mby5saW5rbmFtZSwKKyAgICAgICAgICAgIHByaW50CisKKyAgICBkZWYgYWRkKHNlbGYsIG5hbWUsIGFyY25hbWU9Tm9uZSwgcmVjdXJzaXZlPVRydWUpOgorICAgICAgICAiIiJBZGQgdGhlIGZpbGUgYG5hbWUnIHRvIHRoZSBhcmNoaXZlLiBgbmFtZScgbWF5IGJlIGFueSB0eXBlIG9mIGZpbGUKKyAgICAgICAgICAgKGRpcmVjdG9yeSwgZmlmbywgc3ltYm9saWMgbGluaywgZXRjLikuIElmIGdpdmVuLCBgYXJjbmFtZScKKyAgICAgICAgICAgc3BlY2lmaWVzIGFuIGFsdGVybmF0aXZlIG5hbWUgZm9yIHRoZSBmaWxlIGluIHRoZSBhcmNoaXZlLgorICAgICAgICAgICBEaXJlY3RvcmllcyBhcmUgYWRkZWQgcmVjdXJzaXZlbHkgYnkgZGVmYXVsdC4gVGhpcyBjYW4gYmUgYXZvaWRlZCBieQorICAgICAgICAgICBzZXR0aW5nIGByZWN1cnNpdmUnIHRvIEZhbHNlLgorICAgICAgICAiIiIKKyAgICAgICAgc2VsZi5fY2hlY2soImF3IikKKworICAgICAgICBpZiBhcmNuYW1lIGlzIE5vbmU6CisgICAgICAgICAgICBhcmNuYW1lID0gbmFtZQorCisgICAgICAgICMgU2tpcCBpZiBzb21lYm9keSB0cmllcyB0byBhcmNoaXZlIHRoZSBhcmNoaXZlLi4uCisgICAgICAgIGlmIHNlbGYubmFtZSBpcyBub3QgTm9uZSBcCisgICAgICAgICAgICBhbmQgb3MucGF0aC5hYnNwYXRoKG5hbWUpID09IG9zLnBhdGguYWJzcGF0aChzZWxmLm5hbWUpOgorICAgICAgICAgICAgc2VsZi5fZGJnKDIsICJ0YXJmaWxlOiBTa2lwcGVkICVyIiAlIG5hbWUpCisgICAgICAgICAgICByZXR1cm4KKworICAgICAgICAjIFNwZWNpYWwgY2FzZTogVGhlIHVzZXIgd2FudHMgdG8gYWRkIHRoZSBjdXJyZW50CisgICAgICAgICMgd29ya2luZyBkaXJlY3RvcnkuCisgICAgICAgIGlmIG5hbWUgPT0gIi4iOgorICAgICAgICAgICAgaWYgcmVjdXJzaXZlOgorICAgICAgICAgICAgICAgIGlmIGFyY25hbWUgPT0gIi4iOgorICAgICAgICAgICAgICAgICAgICBhcmNuYW1lID0gIiIKKyAgICAgICAgICAgICAgICBmb3IgZiBpbiBvcy5saXN0ZGlyKCIuIik6CisgICAgICAgICAgICAgICAgICAgIHNlbGYuYWRkKGYsIG9zLnBhdGguam9pbihhcmNuYW1lLCBmKSkKKyAgICAgICAgICAgIHJldHVybgorCisgICAgICAgIHNlbGYuX2RiZygxLCBuYW1lKQorCisgICAgICAgICMgQ3JlYXRlIGEgVGFySW5mbyBvYmplY3QgZnJvbSB0aGUgZmlsZS4KKyAgICAgICAgdGFyaW5mbyA9IHNlbGYuZ2V0dGFyaW5mbyhuYW1lLCBhcmNuYW1lKQorCisgICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKKyAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogVW5zdXBwb3J0ZWQgdHlwZSAlciIgJSBuYW1lKQorICAgICAgICAgICAgcmV0dXJuCisKKyAgICAgICAgIyBBcHBlbmQgdGhlIHRhciBoZWFkZXIgYW5kIGRhdGEgdG8gdGhlIGFyY2hpdmUuCisgICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKKyAgICAgICAgICAgIGYgPSBmaWxlKG5hbWUsICJyYiIpCisgICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbywgZikKKyAgICAgICAgICAgIGYuY2xvc2UoKQorCisgICAgICAgIGlmIHRhcmluZm8udHlwZSBpbiAoTE5LVFlQRSwgU1lNVFlQRSwgRklGT1RZUEUsIENIUlRZUEUsIEJMS1RZUEUpOgorICAgICAgICAgICAgdGFyaW5mby5zaXplID0gMEwKKyAgICAgICAgICAgIHNlbGYuYWRkZmlsZSh0YXJpbmZvKQorCisgICAgICAgIGlmIHRhcmluZm8uaXNkaXIoKToKKyAgICAgICAgICAgIHNlbGYuYWRkZmlsZSh0YXJpbmZvKQorICAgICAgICAgICAgaWYgcmVjdXJzaXZlOgorICAgICAgICAgICAgICAgIGZvciBmIGluIG9zLmxpc3RkaXIobmFtZSk6CisgICAgICAgICAgICAgICAgICAgIHNlbGYuYWRkKG9zLnBhdGguam9pbihuYW1lLCBmKSwgb3MucGF0aC5qb2luKGFyY25hbWUsIGYpKQorCisgICAgZGVmIGFkZGZpbGUoc2VsZiwgdGFyaW5mbywgZmlsZW9iaj1Ob25lKToKKyAgICAgICAgIiIiQWRkIHRoZSBUYXJJbmZvIG9iamVjdCBgdGFyaW5mbycgdG8gdGhlIGFyY2hpdmUuIElmIGBmaWxlb2JqJyBpcworICAgICAgICAgICBnaXZlbiwgdGFyaW5mby5zaXplIGJ5dGVzIGFyZSByZWFkIGZyb20gaXQgYW5kIGFkZGVkIHRvIHRoZSBhcmNoaXZlLgorICAgICAgICAgICBZb3UgY2FuIGNyZWF0ZSBUYXJJbmZvIG9iamVjdHMgdXNpbmcgZ2V0dGFyaW5mbygpLgorICAgICAgICAgICBPbiBXaW5kb3dzIHBsYXRmb3JtcywgYGZpbGVvYmonIHNob3VsZCBhbHdheXMgYmUgb3BlbmVkIHdpdGggbW9kZQorICAgICAgICAgICAncmInIHRvIGF2b2lkIGlycml0YXRpb24gYWJvdXQgdGhlIGZpbGUgc2l6ZS4KKyAgICAgICAgIiIiCisgICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpCisKKyAgICAgICAgdGFyaW5mby5uYW1lID0gbm9ybXBhdGgodGFyaW5mby5uYW1lKQorICAgICAgICBpZiB0YXJpbmZvLmlzZGlyKCk6CisgICAgICAgICAgICAjIGRpcmVjdG9yaWVzIHNob3VsZCBlbmQgd2l0aCAnLycKKyAgICAgICAgICAgIHRhcmluZm8ubmFtZSArPSAiLyIKKworICAgICAgICBpZiB0YXJpbmZvLmxpbmtuYW1lOgorICAgICAgICAgICAgdGFyaW5mby5saW5rbmFtZSA9IG5vcm1wYXRoKHRhcmluZm8ubGlua25hbWUpCisKKyAgICAgICAgaWYgdGFyaW5mby5zaXplID4gTUFYU0laRV9NRU1CRVI6CisgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAiZmlsZSBpcyB0b28gbGFyZ2UgKD44R0IpIgorCisgICAgICAgIGlmIGxlbih0YXJpbmZvLmxpbmtuYW1lKSA+IExFTkdUSF9MSU5LOgorICAgICAgICAgICAgaWYgc2VsZi5wb3NpeDoKKyAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAibGlua25hbWUgaXMgdG9vIGxvbmcgKD4lZCkiIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAlIChMRU5HVEhfTElOSykKKyAgICAgICAgICAgIGVsc2U6CisgICAgICAgICAgICAgICAgc2VsZi5fY3JlYXRlX2dudWxvbmcodGFyaW5mby5saW5rbmFtZSwgR05VVFlQRV9MT05HTElOSykKKyAgICAgICAgICAgICAgICB0YXJpbmZvLmxpbmtuYW1lID0gdGFyaW5mby5saW5rbmFtZVs6TEVOR1RIX0xJTksgLTFdCisgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDIsICJ0YXJmaWxlOiBDcmVhdGVkIEdOVSB0YXIgZXh0ZW5zaW9uIExPTkdMSU5LIikKKworICAgICAgICBpZiBsZW4odGFyaW5mby5uYW1lKSA+IExFTkdUSF9OQU1FOgorICAgICAgICAgICAgaWYgc2VsZi5wb3NpeDoKKyAgICAgICAgICAgICAgICBwcmVmaXggPSB0YXJpbmZvLm5hbWVbOkxFTkdUSF9QUkVGSVggKyAxXQorICAgICAgICAgICAgICAgIHdoaWxlIHByZWZpeCBhbmQgcHJlZml4Wy0xXSAhPSAiLyI6CisgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBwcmVmaXhbOi0xXQorCisgICAgICAgICAgICAgICAgbmFtZSA9IHRhcmluZm8ubmFtZVtsZW4ocHJlZml4KTpdCisgICAgICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4WzotMV0KKworICAgICAgICAgICAgICAgIGlmIG5vdCBwcmVmaXggb3IgbGVuKG5hbWUpID4gTEVOR1RIX05BTUU6CisgICAgICAgICAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJuYW1lIGlzIHRvbyBsb25nICg+JWQpIiBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICUgKExFTkdUSF9OQU1FKQorCisgICAgICAgICAgICAgICAgdGFyaW5mby5uYW1lICAgPSBuYW1lCisgICAgICAgICAgICAgICAgdGFyaW5mby5wcmVmaXggPSBwcmVmaXgKKyAgICAgICAgICAgIGVsc2U6CisgICAgICAgICAgICAgICAgc2VsZi5fY3JlYXRlX2dudWxvbmcodGFyaW5mby5uYW1lLCBHTlVUWVBFX0xPTkdOQU1FKQorICAgICAgICAgICAgICAgIHRhcmluZm8ubmFtZSA9IHRhcmluZm8ubmFtZVs6TEVOR1RIX05BTUUgLSAxXQorICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogQ3JlYXRlZCBHTlUgdGFyIGV4dGVuc2lvbiBMT05HTkFNRSIpCisKKyAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHRhcmluZm8udG9idWYoKSkKKyAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCisKKyAgICAgICAgIyBJZiB0aGVyZSdzIGRhdGEgdG8gZm9sbG93LCBhcHBlbmQgaXQuCisgICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CisgICAgICAgICAgICBjb3B5ZmlsZW9iaihmaWxlb2JqLCBzZWxmLmZpbGVvYmosIHRhcmluZm8uc2l6ZSkKKyAgICAgICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKHRhcmluZm8uc2l6ZSwgQkxPQ0tTSVpFKQorICAgICAgICAgICAgaWYgcmVtYWluZGVyID4gMDoKKyAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKEJMT0NLU0laRSAtIHJlbWFpbmRlcikpCisgICAgICAgICAgICAgICAgYmxvY2tzICs9IDEKKyAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IGJsb2NrcyAqIEJMT0NLU0laRQorCisgICAgICAgIHNlbGYubWVtYmVycy5hcHBlbmQodGFyaW5mbykKKyAgICAgICAgc2VsZi5tZW1iZXJuYW1lcy5hcHBlbmQodGFyaW5mby5uYW1lKQorICAgICAgICBzZWxmLmNodW5rcy5hcHBlbmQoc2VsZi5vZmZzZXQpCisKKyAgICBkZWYgZXh0cmFjdChzZWxmLCBtZW1iZXIsIHBhdGg9IiIpOgorICAgICAgICAiIiJFeHRyYWN0IGEgbWVtYmVyIGZyb20gdGhlIGFyY2hpdmUgdG8gdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnksCisgICAgICAgICAgIHVzaW5nIGl0cyBmdWxsIG5hbWUuIEl0cyBmaWxlIGluZm9ybWF0aW9uIGlzIGV4dHJhY3RlZCBhcyBhY2N1cmF0ZWx5CisgICAgICAgICAgIGFzIHBvc3NpYmxlLiBgbWVtYmVyJyBtYXkgYmUgYSBmaWxlbmFtZSBvciBhIFRhckluZm8gb2JqZWN0LiBZb3UgY2FuCisgICAgICAgICAgIHNwZWNpZnkgYSBkaWZmZXJlbnQgZGlyZWN0b3J5IHVzaW5nIGBwYXRoJy4KKyAgICAgICAgIiIiCisgICAgICAgIHNlbGYuX2NoZWNrKCJyIikKKworICAgICAgICBpZiBpc2luc3RhbmNlKG1lbWJlciwgVGFySW5mbyk6CisgICAgICAgICAgICB0YXJpbmZvID0gbWVtYmVyCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5nZXRtZW1iZXIobWVtYmVyKQorCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIHNlbGYuX2V4dHJhY3RfbWVtYmVyKHRhcmluZm8sIG9zLnBhdGguam9pbihwYXRoLCB0YXJpbmZvLm5hbWUpKQorICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKKyAgICAgICAgICAgIGlmIHNlbGYuZXJyb3JsZXZlbCA+IDA6CisgICAgICAgICAgICAgICAgcmFpc2UKKyAgICAgICAgICAgIGVsc2U6CisgICAgICAgICAgICAgICAgaWYgZS5maWxlbmFtZSBpcyBOb25lOgorICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzIiAlIGUuc3RyZXJyb3IpCisgICAgICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyAlciIgJSAoZS5zdHJlcnJvciwgZS5maWxlbmFtZSkpCisgICAgICAgIGV4Y2VwdCBFeHRyYWN0RXJyb3IsIGU6CisgICAgICAgICAgICBpZiBzZWxmLmVycm9ybGV2ZWwgPiAxOgorICAgICAgICAgICAgICAgIHJhaXNlCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZSkKKworICAgIGRlZiBleHRyYWN0ZmlsZShzZWxmLCBtZW1iZXIpOgorICAgICAgICAiIiJFeHRyYWN0IGEgbWVtYmVyIGZyb20gdGhlIGFyY2hpdmUgYXMgYSBmaWxlIG9iamVjdC4gYG1lbWJlcicgbWF5IGJlCisgICAgICAgICAgIGEgZmlsZW5hbWUgb3IgYSBUYXJJbmZvIG9iamVjdC4gSWYgYG1lbWJlcicgaXMgYSByZWd1bGFyIGZpbGUsIGEKKyAgICAgICAgICAgZmlsZS1saWtlIG9iamVjdCBpcyByZXR1cm5lZC4gSWYgYG1lbWJlcicgaXMgYSBsaW5rLCBhIGZpbGUtbGlrZQorICAgICAgICAgICBvYmplY3QgaXMgY29uc3RydWN0ZWQgZnJvbSB0aGUgbGluaydzIHRhcmdldC4gSWYgYG1lbWJlcicgaXMgbm9uZSBvZgorICAgICAgICAgICB0aGUgYWJvdmUsIE5vbmUgaXMgcmV0dXJuZWQuCisgICAgICAgICAgIFRoZSBmaWxlLWxpa2Ugb2JqZWN0IGlzIHJlYWQtb25seSBhbmQgcHJvdmlkZXMgdGhlIGZvbGxvd2luZworICAgICAgICAgICBtZXRob2RzOiByZWFkKCksIHJlYWRsaW5lKCksIHJlYWRsaW5lcygpLCBzZWVrKCkgYW5kIHRlbGwoKQorICAgICAgICAiIiIKKyAgICAgICAgc2VsZi5fY2hlY2soInIiKQorCisgICAgICAgIGlmIGlzaW5zdGFuY2UobWVtYmVyLCBUYXJJbmZvKToKKyAgICAgICAgICAgIHRhcmluZm8gPSBtZW1iZXIKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLmdldG1lbWJlcihtZW1iZXIpCisKKyAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpOgorICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iamVjdChzZWxmLCB0YXJpbmZvKQorCisgICAgICAgIGVsaWYgdGFyaW5mby50eXBlIG5vdCBpbiBTVVBQT1JURURfVFlQRVM6CisgICAgICAgICAgICAjIElmIGEgbWVtYmVyJ3MgdHlwZSBpcyB1bmtub3duLCBpdCBpcyB0cmVhdGVkIGFzIGEKKyAgICAgICAgICAgICMgcmVndWxhciBmaWxlLgorICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iamVjdChzZWxmLCB0YXJpbmZvKQorCisgICAgICAgIGVsaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKKyAgICAgICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VsZi5maWxlb2JqLCBfU3RyZWFtKToKKyAgICAgICAgICAgICAgICAjIEEgc21hbGwgYnV0IHVnbHkgd29ya2Fyb3VuZCBmb3IgdGhlIGNhc2UgdGhhdCBzb21lb25lIHRyaWVzCisgICAgICAgICAgICAgICAgIyB0byBleHRyYWN0IGEgKHN5bSlsaW5rIGFzIGEgZmlsZS1vYmplY3QgZnJvbSBhIG5vbi1zZWVrYWJsZQorICAgICAgICAgICAgICAgICMgc3RyZWFtIG9mIHRhciBibG9ja3MuCisgICAgICAgICAgICAgICAgcmFpc2UgU3RyZWFtRXJyb3IsICJjYW5ub3QgZXh0cmFjdCAoc3ltKWxpbmsgYXMgZmlsZSBvYmplY3QiCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgICMgQSAoc3ltKWxpbmsncyBmaWxlIG9iamVjdCBpcyBpdCdzIHRhcmdldCdzIGZpbGUgb2JqZWN0LgorICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLmV4dHJhY3RmaWxlKHNlbGYuX2dldG1lbWJlcih0YXJpbmZvLmxpbmtuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvKSkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgICMgSWYgdGhlcmUncyBubyBkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgbWVtYmVyIChkaXJlY3RvcnksIGNocmRldiwKKyAgICAgICAgICAgICMgYmxrZGV2LCBldGMuKSwgcmV0dXJuIE5vbmUgaW5zdGVhZCBvZiBhIGZpbGUgb2JqZWN0LgorICAgICAgICAgICAgcmV0dXJuIE5vbmUKKworICAgIGRlZiBfZXh0cmFjdF9tZW1iZXIoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CisgICAgICAgICIiIkV4dHJhY3QgdGhlIFRhckluZm8gb2JqZWN0IHRhcmluZm8gdG8gYSBwaHlzaWNhbAorICAgICAgICAgICBmaWxlIGNhbGxlZCB0YXJnZXRwYXRoLgorICAgICAgICAiIiIKKyAgICAgICAgIyBGZXRjaCB0aGUgVGFySW5mbyBvYmplY3QgZm9yIHRoZSBnaXZlbiBuYW1lCisgICAgICAgICMgYW5kIGJ1aWxkIHRoZSBkZXN0aW5hdGlvbiBwYXRobmFtZSwgcmVwbGFjaW5nCisgICAgICAgICMgZm9yd2FyZCBzbGFzaGVzIHRvIHBsYXRmb3JtIHNwZWNpZmljIHNlcGFyYXRvcnMuCisgICAgICAgIGlmIHRhcmdldHBhdGhbLTE6XSA9PSAiLyI6CisgICAgICAgICAgICB0YXJnZXRwYXRoID0gdGFyZ2V0cGF0aFs6LTFdCisgICAgICAgIHRhcmdldHBhdGggPSBvcy5wYXRoLm5vcm1wYXRoKHRhcmdldHBhdGgpCisKKyAgICAgICAgIyBDcmVhdGUgYWxsIHVwcGVyIGRpcmVjdG9yaWVzLgorICAgICAgICB1cHBlcmRpcnMgPSBvcy5wYXRoLmRpcm5hbWUodGFyZ2V0cGF0aCkKKyAgICAgICAgaWYgdXBwZXJkaXJzIGFuZCBub3Qgb3MucGF0aC5leGlzdHModXBwZXJkaXJzKToKKyAgICAgICAgICAgIHRpID0gVGFySW5mbygpCisgICAgICAgICAgICB0aS5uYW1lICA9IHVwcGVyZGlycworICAgICAgICAgICAgdGkudHlwZSAgPSBESVJUWVBFCisgICAgICAgICAgICB0aS5tb2RlICA9IDA3NzcKKyAgICAgICAgICAgIHRpLm10aW1lID0gdGFyaW5mby5tdGltZQorICAgICAgICAgICAgdGkudWlkICAgPSB0YXJpbmZvLnVpZAorICAgICAgICAgICAgdGkuZ2lkICAgPSB0YXJpbmZvLmdpZAorICAgICAgICAgICAgdGkudW5hbWUgPSB0YXJpbmZvLnVuYW1lCisgICAgICAgICAgICB0aS5nbmFtZSA9IHRhcmluZm8uZ25hbWUKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICBzZWxmLl9leHRyYWN0X21lbWJlcih0aSwgdGkubmFtZSkKKyAgICAgICAgICAgIGV4Y2VwdDoKKyAgICAgICAgICAgICAgICBwYXNzCisKKyAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKKyAgICAgICAgICAgIHNlbGYuX2RiZygxLCAiJXMgLT4gJXMiICUgKHRhcmluZm8ubmFtZSwgdGFyaW5mby5saW5rbmFtZSkpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICBzZWxmLl9kYmcoMSwgdGFyaW5mby5uYW1lKQorCisgICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKKyAgICAgICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKKyAgICAgICAgZWxpZiB0YXJpbmZvLmlzZGlyKCk6CisgICAgICAgICAgICBzZWxmLm1ha2VkaXIodGFyaW5mbywgdGFyZ2V0cGF0aCkKKyAgICAgICAgZWxpZiB0YXJpbmZvLmlzZmlmbygpOgorICAgICAgICAgICAgc2VsZi5tYWtlZmlmbyh0YXJpbmZvLCB0YXJnZXRwYXRoKQorICAgICAgICBlbGlmIHRhcmluZm8uaXNjaHIoKSBvciB0YXJpbmZvLmlzYmxrKCk6CisgICAgICAgICAgICBzZWxmLm1ha2VkZXYodGFyaW5mbywgdGFyZ2V0cGF0aCkKKyAgICAgICAgZWxpZiB0YXJpbmZvLmlzbG5rKCkgb3IgdGFyaW5mby5pc3N5bSgpOgorICAgICAgICAgICAgc2VsZi5tYWtlbGluayh0YXJpbmZvLCB0YXJnZXRwYXRoKQorICAgICAgICBlbGlmIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgorICAgICAgICAgICAgc2VsZi5tYWtldW5rbm93bih0YXJpbmZvLCB0YXJnZXRwYXRoKQorICAgICAgICBlbHNlOgorICAgICAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQorCisgICAgICAgIHNlbGYuY2hvd24odGFyaW5mbywgdGFyZ2V0cGF0aCkKKyAgICAgICAgaWYgbm90IHRhcmluZm8uaXNzeW0oKToKKyAgICAgICAgICAgIHNlbGYuY2htb2QodGFyaW5mbywgdGFyZ2V0cGF0aCkKKyAgICAgICAgICAgIHNlbGYudXRpbWUodGFyaW5mbywgdGFyZ2V0cGF0aCkKKworICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICMgQmVsb3cgYXJlIHRoZSBkaWZmZXJlbnQgZmlsZSBtZXRob2RzLiBUaGV5IGFyZSBjYWxsZWQgdmlhCisgICAgIyBfZXh0cmFjdF9tZW1iZXIoKSB3aGVuIGV4dHJhY3QoKSBpcyBjYWxsZWQuIFRoZXkgY2FuIGJlIHJlcGxhY2VkIGluIGEKKyAgICAjIHN1YmNsYXNzIHRvIGltcGxlbWVudCBvdGhlciBmdW5jdGlvbmFsaXR5LgorCisgICAgZGVmIG1ha2VkaXIoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CisgICAgICAgICIiIk1ha2UgYSBkaXJlY3RvcnkgY2FsbGVkIHRhcmdldHBhdGguCisgICAgICAgICIiIgorICAgICAgICB0cnk6CisgICAgICAgICAgICBvcy5ta2Rpcih0YXJnZXRwYXRoKQorICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKKyAgICAgICAgICAgIGlmIGUuZXJybm8gIT0gZXJybm8uRUVYSVNUOgorICAgICAgICAgICAgICAgIHJhaXNlCisKKyAgICBkZWYgbWFrZWZpbGUoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CisgICAgICAgICIiIk1ha2UgYSBmaWxlIGNhbGxlZCB0YXJnZXRwYXRoLgorICAgICAgICAiIiIKKyAgICAgICAgc291cmNlID0gc2VsZi5leHRyYWN0ZmlsZSh0YXJpbmZvKQorICAgICAgICB0YXJnZXQgPSBmaWxlKHRhcmdldHBhdGgsICJ3YiIpCisgICAgICAgIGNvcHlmaWxlb2JqKHNvdXJjZSwgdGFyZ2V0KQorICAgICAgICBzb3VyY2UuY2xvc2UoKQorICAgICAgICB0YXJnZXQuY2xvc2UoKQorCisgICAgZGVmIG1ha2V1bmtub3duKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgorICAgICAgICAiIiJNYWtlIGEgZmlsZSBmcm9tIGEgVGFySW5mbyBvYmplY3Qgd2l0aCBhbiB1bmtub3duIHR5cGUKKyAgICAgICAgICAgYXQgdGFyZ2V0cGF0aC4KKyAgICAgICAgIiIiCisgICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKKyAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiBVbmtub3duIGZpbGUgdHlwZSAlciwgIiBcCisgICAgICAgICAgICAgICAgICAgICAiZXh0cmFjdGVkIGFzIHJlZ3VsYXIgZmlsZS4iICUgdGFyaW5mby50eXBlKQorCisgICAgZGVmIG1ha2VmaWZvKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgorICAgICAgICAiIiJNYWtlIGEgZmlmbyBjYWxsZWQgdGFyZ2V0cGF0aC4KKyAgICAgICAgIiIiCisgICAgICAgIGlmIGhhc2F0dHIob3MsICJta2ZpZm8iKToKKyAgICAgICAgICAgIG9zLm1rZmlmbyh0YXJnZXRwYXRoKQorICAgICAgICBlbHNlOgorICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yLCAiZmlmbyBub3Qgc3VwcG9ydGVkIGJ5IHN5c3RlbSIKKworICAgIGRlZiBtYWtlZGV2KHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgorICAgICAgICAiIiJNYWtlIGEgY2hhcmFjdGVyIG9yIGJsb2NrIGRldmljZSBjYWxsZWQgdGFyZ2V0cGF0aC4KKyAgICAgICAgIiIiCisgICAgICAgIGlmIG5vdCBoYXNhdHRyKG9zLCAibWtub2QiKSBvciBub3QgaGFzYXR0cihvcywgIm1ha2VkZXYiKToKKyAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvciwgInNwZWNpYWwgZGV2aWNlcyBub3Qgc3VwcG9ydGVkIGJ5IHN5c3RlbSIKKworICAgICAgICBtb2RlID0gdGFyaW5mby5tb2RlCisgICAgICAgIGlmIHRhcmluZm8uaXNibGsoKToKKyAgICAgICAgICAgIG1vZGUgfD0gc3RhdC5TX0lGQkxLCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICBtb2RlIHw9IHN0YXQuU19JRkNIUgorCisgICAgICAgIG9zLm1rbm9kKHRhcmdldHBhdGgsIG1vZGUsCisgICAgICAgICAgICAgICAgIG9zLm1ha2VkZXYodGFyaW5mby5kZXZtYWpvciwgdGFyaW5mby5kZXZtaW5vcikpCisKKyAgICBkZWYgbWFrZWxpbmsoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CisgICAgICAgICIiIk1ha2UgYSAoc3ltYm9saWMpIGxpbmsgY2FsbGVkIHRhcmdldHBhdGguIElmIGl0IGNhbm5vdCBiZSBjcmVhdGVkCisgICAgICAgICAgKHBsYXRmb3JtIGxpbWl0YXRpb24pLCB3ZSB0cnkgdG8gbWFrZSBhIGNvcHkgb2YgdGhlIHJlZmVyZW5jZWQgZmlsZQorICAgICAgICAgIGluc3RlYWQgb2YgYSBsaW5rLgorICAgICAgICAiIiIKKyAgICAgICAgbGlua3BhdGggPSB0YXJpbmZvLmxpbmtuYW1lCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKToKKyAgICAgICAgICAgICAgICBvcy5zeW1saW5rKGxpbmtwYXRoLCB0YXJnZXRwYXRoKQorICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICBvcy5saW5rKGxpbmtwYXRoLCB0YXJnZXRwYXRoKQorICAgICAgICBleGNlcHQgQXR0cmlidXRlRXJyb3I6CisgICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CisgICAgICAgICAgICAgICAgbGlua3BhdGggPSBvcy5wYXRoLmpvaW4ob3MucGF0aC5kaXJuYW1lKHRhcmluZm8ubmFtZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlua3BhdGgpCisgICAgICAgICAgICAgICAgbGlua3BhdGggPSBub3JtcGF0aChsaW5rcGF0aCkKKworICAgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgICAgIHNlbGYuX2V4dHJhY3RfbWVtYmVyKHNlbGYuZ2V0bWVtYmVyKGxpbmtwYXRoKSwgdGFyZ2V0cGF0aCkKKyAgICAgICAgICAgIGV4Y2VwdCAoRW52aXJvbm1lbnRFcnJvciwgS2V5RXJyb3IpLCBlOgorICAgICAgICAgICAgICAgIGxpbmtwYXRoID0gb3MucGF0aC5ub3JtcGF0aChsaW5rcGF0aCkKKyAgICAgICAgICAgICAgICB0cnk6CisgICAgICAgICAgICAgICAgICAgIHNodXRpbC5jb3B5MihsaW5rcGF0aCwgdGFyZ2V0cGF0aCkKKyAgICAgICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKKyAgICAgICAgICAgICAgICAgICAgcmFpc2UgSU9FcnJvciwgImxpbmsgY291bGQgbm90IGJlIGNyZWF0ZWQiCisKKyAgICBkZWYgY2hvd24oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CisgICAgICAgICIiIlNldCBvd25lciBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgorICAgICAgICAiIiIKKyAgICAgICAgaWYgcHdkIGFuZCBoYXNhdHRyKG9zLCAiZ2V0ZXVpZCIpIGFuZCBvcy5nZXRldWlkKCkgPT0gMDoKKyAgICAgICAgICAgICMgV2UgaGF2ZSB0byBiZSByb290IHRvIGRvIHNvLgorICAgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgICAgIGcgPSBncnAuZ2V0Z3JuYW0odGFyaW5mby5nbmFtZSlbMl0KKyAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKKyAgICAgICAgICAgICAgICB0cnk6CisgICAgICAgICAgICAgICAgICAgIGcgPSBncnAuZ2V0Z3JnaWQodGFyaW5mby5naWQpWzJdCisgICAgICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgorICAgICAgICAgICAgICAgICAgICBnID0gb3MuZ2V0Z2lkKCkKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICB1ID0gcHdkLmdldHB3bmFtKHRhcmluZm8udW5hbWUpWzJdCisgICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CisgICAgICAgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgICAgICAgICB1ID0gcHdkLmdldHB3dWlkKHRhcmluZm8udWlkKVsyXQorICAgICAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKKyAgICAgICAgICAgICAgICAgICAgdSA9IG9zLmdldHVpZCgpCisgICAgICAgICAgICB0cnk6CisgICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpIGFuZCBoYXNhdHRyKG9zLCAibGNob3duIik6CisgICAgICAgICAgICAgICAgICAgIG9zLmxjaG93bih0YXJnZXRwYXRoLCB1LCBnKQorICAgICAgICAgICAgICAgIGVsc2U6CisgICAgICAgICAgICAgICAgICAgIG9zLmNob3duKHRhcmdldHBhdGgsIHUsIGcpCisgICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKKyAgICAgICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IsICJjb3VsZCBub3QgY2hhbmdlIG93bmVyIgorCisgICAgZGVmIGNobW9kKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgorICAgICAgICAiIiJTZXQgZmlsZSBwZXJtaXNzaW9ucyBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgorICAgICAgICAiIiIKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgb3MuY2htb2QodGFyZ2V0cGF0aCwgdGFyaW5mby5tb2RlKQorICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKKyAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvciwgImNvdWxkIG5vdCBjaGFuZ2UgbW9kZSIKKworICAgIGRlZiB1dGltZShzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKKyAgICAgICAgIiIiU2V0IG1vZGlmaWNhdGlvbiB0aW1lIG9mIHRhcmdldHBhdGggYWNjb3JkaW5nIHRvIHRhcmluZm8uCisgICAgICAgICIiIgorICAgICAgICBpZiBzeXMucGxhdGZvcm0gPT0gIndpbjMyIiBhbmQgdGFyaW5mby5pc2RpcigpOgorICAgICAgICAgICAgIyBBY2NvcmRpbmcgdG8gbXNkbi5taWNyb3NvZnQuY29tLCBpdCBpcyBhbiBlcnJvciAoRUFDQ0VTKQorICAgICAgICAgICAgIyB0byB1c2UgdXRpbWUoKSBvbiBkaXJlY3Rvcmllcy4KKyAgICAgICAgICAgIHJldHVybgorICAgICAgICB0cnk6CisgICAgICAgICAgICBvcy51dGltZSh0YXJnZXRwYXRoLCAodGFyaW5mby5tdGltZSwgdGFyaW5mby5tdGltZSkpCisgICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgorICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yLCAiY291bGQgbm90IGNoYW5nZSBtb2RpZmljYXRpb24gdGltZSIKKworICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgZGVmIG5leHQoc2VsZik6CisgICAgICAgICIiIlJldHVybiB0aGUgbmV4dCBtZW1iZXIgb2YgdGhlIGFyY2hpdmUgYXMgYSBUYXJJbmZvIG9iamVjdCwgd2hlbgorICAgICAgICAgICBUYXJGaWxlIGlzIG9wZW5lZCBmb3IgcmVhZGluZy4gUmV0dXJuIE5vbmUgaWYgdGhlcmUgaXMgbm8gbW9yZQorICAgICAgICAgICBhdmFpbGFibGUuCisgICAgICAgICIiIgorICAgICAgICBzZWxmLl9jaGVjaygicmEiKQorICAgICAgICBpZiBzZWxmLmZpcnN0bWVtYmVyIGlzIG5vdCBOb25lOgorICAgICAgICAgICAgbSA9IHNlbGYuZmlyc3RtZW1iZXIKKyAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCisgICAgICAgICAgICByZXR1cm4gbQorCisgICAgICAgICMgUmVhZCB0aGUgbmV4dCBibG9jay4KKyAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5jaHVua3NbLTFdKQorICAgICAgICB3aGlsZSBUcnVlOgorICAgICAgICAgICAgYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQorICAgICAgICAgICAgaWYgbm90IGJ1ZjoKKyAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQorICAgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgICAgIHRhcmluZm8gPSBUYXJJbmZvLmZyb21idWYoYnVmKQorICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CisgICAgICAgICAgICAgICAgaWYgc2VsZi5pZ25vcmVfemVyb3M6CisgICAgICAgICAgICAgICAgICAgIGlmIGJ1Zi5jb3VudChOVUwpID09IEJMT0NLU0laRToKKyAgICAgICAgICAgICAgICAgICAgICAgIGFkaiA9ICJlbXB0eSIKKyAgICAgICAgICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICAgICAgICAgIGFkaiA9ICJpbnZhbGlkIgorICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMiwgIjB4JVg6ICVzIGJsb2NrIiAlIChzZWxmLm9mZnNldCwgYWRqKSkKKyAgICAgICAgICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCisgICAgICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICAgICAgIyBCbG9jayBpcyBlbXB0eSBvciB1bnJlYWRhYmxlLgorICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLmNodW5rc1stMV0gPT0gMDoKKyAgICAgICAgICAgICAgICAgICAgICAgICMgSWYgdGhlIGZpcnN0IGJsb2NrIGlzIGludmFsaWQuIFRoYXQgZG9lcyBub3QKKyAgICAgICAgICAgICAgICAgICAgICAgICMgbG9vayBsaWtlIGEgdGFyIGFyY2hpdmUgd2UgY2FuIGhhbmRsZS4KKyAgICAgICAgICAgICAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvciwiZW1wdHksIHVucmVhZGFibGUgb3IgY29tcHJlc3NlZCBmaWxlIgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQorICAgICAgICAgICAgYnJlYWsKKworICAgICAgICAjIFdlIHNob3VsZG4ndCByZWx5IG9uIHRoaXMgY2hlY2tzdW0sIGJlY2F1c2Ugc29tZSB0YXIgcHJvZ3JhbXMKKyAgICAgICAgIyBjYWxjdWxhdGUgaXQgZGlmZmVyZW50bHkgYW5kIGl0IGlzIG1lcmVseSB2YWxpZGF0aW5nIHRoZQorICAgICAgICAjIGhlYWRlciBibG9jay4gV2UgY291bGQganVzdCBhcyB3ZWxsIHNraXAgdGhpcyBwYXJ0LCB3aGljaCB3b3VsZAorICAgICAgICAjIGhhdmUgYSBzbGlnaHQgZWZmZWN0IG9uIHBlcmZvcm1hbmNlLi4uCisgICAgICAgIGlmIHRhcmluZm8uY2hrc3VtICE9IGNhbGNfY2hrc3VtKGJ1Zik6CisgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IEJhZCBDaGVja3N1bSAlciIgJSB0YXJpbmZvLm5hbWUpCisKKyAgICAgICAgIyBTZXQgdGhlIFRhckluZm8gb2JqZWN0J3Mgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZQorICAgICAgICAjIFRhckZpbGUgYW5kIHNldCBzZWxmLm9mZnNldCB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIGRhdGEgYmxvY2tzCisgICAgICAgICMgc2hvdWxkIGJlZ2luLgorICAgICAgICB0YXJpbmZvLm9mZnNldCA9IHNlbGYub2Zmc2V0CisgICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQorCisgICAgICAgICMgQ2hlY2sgaWYgdGhlIFRhckluZm8gb2JqZWN0IGhhcyBhIHR5cGVmbGFnIGZvciB3aGljaCBhIGNhbGxiYWNrCisgICAgICAgICMgbWV0aG9kIGlzIHJlZ2lzdGVyZWQgaW4gdGhlIFRZUEVfTUVUSC4gSWYgc28sIHRoZW4gY2FsbCBpdC4KKyAgICAgICAgaWYgdGFyaW5mby50eXBlIGluIHNlbGYuVFlQRV9NRVRIOgorICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYuVFlQRV9NRVRIW3RhcmluZm8udHlwZV0oc2VsZiwgdGFyaW5mbykKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHRhcmluZm8ub2Zmc2V0X2RhdGEgPSBzZWxmLm9mZnNldAorICAgICAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpIG9yIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgorICAgICAgICAgICAgICAgICMgU2tpcCB0aGUgZm9sbG93aW5nIGRhdGEgYmxvY2tzLgorICAgICAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IHNlbGYuX2Jsb2NrKHRhcmluZm8uc2l6ZSkKKworICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCkgYW5kIHRhcmluZm8ubmFtZVs6LTFdID09ICIvIjoKKyAgICAgICAgICAgICMgc29tZSBvbGQgdGFyIHByb2dyYW1zIGRvbid0IGtub3cgRElSVFlQRQorICAgICAgICAgICAgdGFyaW5mby50eXBlID0gRElSVFlQRQorCisgICAgICAgIHNlbGYubWVtYmVycy5hcHBlbmQodGFyaW5mbykKKyAgICAgICAgc2VsZi5tZW1iZXJuYW1lcy5hcHBlbmQodGFyaW5mby5uYW1lKQorICAgICAgICBzZWxmLmNodW5rcy5hcHBlbmQoc2VsZi5vZmZzZXQpCisgICAgICAgIHJldHVybiB0YXJpbmZvCisKKyAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAjIEJlbG93IGFyZSBzb21lIG1ldGhvZHMgd2hpY2ggYXJlIGNhbGxlZCBmb3Igc3BlY2lhbCB0eXBlZmxhZ3MgaW4gdGhlCisgICAgIyBuZXh0KCkgbWV0aG9kLCBlLmcuIGZvciB1bndyYXBwaW5nIEdOVSBsb25nbmFtZS9sb25nbGluayBibG9ja3MuIFRoZXkKKyAgICAjIGFyZSByZWdpc3RlcmVkIGluIFRZUEVfTUVUSCBiZWxvdy4gWW91IGNhbiByZWdpc3RlciB5b3VyIG93biBtZXRob2RzCisgICAgIyB3aXRoIHRoaXMgbWFwcGluZy4KKyAgICAjIEEgcmVnaXN0ZXJlZCBtZXRob2QgaXMgY2FsbGVkIHdpdGggYSBUYXJJbmZvIG9iamVjdCBhcyBvbmx5IGFyZ3VtZW50LgorICAgICMKKyAgICAjIER1cmluZyBpdHMgZXhlY3V0aW9uIHRoZSBtZXRob2QgTVVTVCBwZXJmb3JtIHRoZSBmb2xsb3dpbmcgdGFza3M6CisgICAgIyAxLiBzZXQgdGFyaW5mby5vZmZzZXRfZGF0YSB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIGRhdGEgYmxvY2tzIGJlZ2luLAorICAgICMgICAgaWYgdGhlcmUgaXMgZGF0YSB0byBmb2xsb3cuCisgICAgIyAyLiBzZXQgc2VsZi5vZmZzZXQgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBuZXh0IG1lbWJlcidzIGhlYWRlciB3aWxsCisgICAgIyAgICBiZWdpbi4KKyAgICAjIDMuIHJldHVybiBhIHZhbGlkIFRhckluZm8gb2JqZWN0LgorCisgICAgZGVmIHByb2NfZ251bG9uZyhzZWxmLCB0YXJpbmZvKToKKyAgICAgICAgIiIiRXZhbHVhdGUgdGhlIGJsb2NrcyB0aGF0IGhvbGQgYSBHTlUgbG9uZ25hbWUKKyAgICAgICAgICAgb3IgbG9uZ2xpbmsgbWVtYmVyLgorICAgICAgICAiIiIKKyAgICAgICAgYnVmID0gIiIKKyAgICAgICAgbmFtZSA9IE5vbmUKKyAgICAgICAgbGlua25hbWUgPSBOb25lCisgICAgICAgIGNvdW50ID0gdGFyaW5mby5zaXplCisgICAgICAgIHdoaWxlIGNvdW50ID4gMDoKKyAgICAgICAgICAgIGJsb2NrID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQorICAgICAgICAgICAgYnVmICs9IGJsb2NrCisgICAgICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKKyAgICAgICAgICAgIGNvdW50IC09IEJMT0NLU0laRQorCisgICAgICAgIGlmIHRhcmluZm8udHlwZSA9PSBHTlVUWVBFX0xPTkdOQU1FOgorICAgICAgICAgICAgbmFtZSA9IG50cyhidWYpCisgICAgICAgIGlmIHRhcmluZm8udHlwZSA9PSBHTlVUWVBFX0xPTkdMSU5LOgorICAgICAgICAgICAgbGlua25hbWUgPSBudHMoYnVmKQorCisgICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKKworICAgICAgICB0YXJpbmZvID0gVGFySW5mby5mcm9tYnVmKGJ1ZikKKyAgICAgICAgdGFyaW5mby5vZmZzZXQgPSBzZWxmLm9mZnNldAorICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKKyAgICAgICAgdGFyaW5mby5vZmZzZXRfZGF0YSA9IHNlbGYub2Zmc2V0CisgICAgICAgIHRhcmluZm8ubmFtZSA9IG5hbWUgb3IgdGFyaW5mby5uYW1lCisgICAgICAgIHRhcmluZm8ubGlua25hbWUgPSBsaW5rbmFtZSBvciB0YXJpbmZvLmxpbmtuYW1lCisKKyAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpIG9yIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgorICAgICAgICAgICAgIyBTa2lwIHRoZSBmb2xsb3dpbmcgZGF0YSBibG9ja3MuCisgICAgICAgICAgICBzZWxmLm9mZnNldCArPSBzZWxmLl9ibG9jayh0YXJpbmZvLnNpemUpCisgICAgICAgIHJldHVybiB0YXJpbmZvCisKKyAgICBkZWYgcHJvY19zcGFyc2Uoc2VsZiwgdGFyaW5mbyk6CisgICAgICAgICIiIkFuYWx5emUgYSBHTlUgc3BhcnNlIGhlYWRlciBwbHVzIGV4dHJhIGhlYWRlcnMuCisgICAgICAgICIiIgorICAgICAgICBidWYgPSB0YXJpbmZvLnRvYnVmKCkKKyAgICAgICAgc3AgPSBfcmluZ2J1ZmZlcigpCisgICAgICAgIHBvcyA9IDM4NgorICAgICAgICBsYXN0cG9zID0gMEwKKyAgICAgICAgcmVhbHBvcyA9IDBMCisgICAgICAgICMgVGhlcmUgYXJlIDQgcG9zc2libGUgc3BhcnNlIHN0cnVjdHMgaW4gdGhlCisgICAgICAgICMgZmlyc3QgaGVhZGVyLgorICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoNCk6CisgICAgICAgICAgICB0cnk6CisgICAgICAgICAgICAgICAgb2Zmc2V0ID0gaW50KGJ1Zltwb3M6cG9zICsgMTJdLCA4KQorICAgICAgICAgICAgICAgIG51bWJ5dGVzID0gaW50KGJ1Zltwb3MgKyAxMjpwb3MgKyAyNF0sIDgpCisgICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKKyAgICAgICAgICAgICAgICBicmVhaworICAgICAgICAgICAgaWYgb2Zmc2V0ID4gbGFzdHBvczoKKyAgICAgICAgICAgICAgICBzcC5hcHBlbmQoX2hvbGUobGFzdHBvcywgb2Zmc2V0IC0gbGFzdHBvcykpCisgICAgICAgICAgICBzcC5hcHBlbmQoX2RhdGEob2Zmc2V0LCBudW1ieXRlcywgcmVhbHBvcykpCisgICAgICAgICAgICByZWFscG9zICs9IG51bWJ5dGVzCisgICAgICAgICAgICBsYXN0cG9zID0gb2Zmc2V0ICsgbnVtYnl0ZXMKKyAgICAgICAgICAgIHBvcyArPSAyNAorCisgICAgICAgIGlzZXh0ZW5kZWQgPSBvcmQoYnVmWzQ4Ml0pCisgICAgICAgIG9yaWdzaXplID0gaW50KGJ1Zls0ODM6NDk1XSwgOCkKKworICAgICAgICAjIElmIHRoZSBpc2V4dGVuZGVkIGZsYWcgaXMgZ2l2ZW4sCisgICAgICAgICMgdGhlcmUgYXJlIGV4dHJhIGhlYWRlcnMgdG8gcHJvY2Vzcy4KKyAgICAgICAgd2hpbGUgaXNleHRlbmRlZCA9PSAxOgorICAgICAgICAgICAgYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQorICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCisgICAgICAgICAgICBwb3MgPSAwCisgICAgICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoMjEpOgorICAgICAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gaW50KGJ1Zltwb3M6cG9zICsgMTJdLCA4KQorICAgICAgICAgICAgICAgICAgICBudW1ieXRlcyA9IGludChidWZbcG9zICsgMTI6cG9zICsgMjRdLCA4KQorICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgorICAgICAgICAgICAgICAgICAgICBicmVhaworICAgICAgICAgICAgICAgIGlmIG9mZnNldCA+IGxhc3Rwb3M6CisgICAgICAgICAgICAgICAgICAgIHNwLmFwcGVuZChfaG9sZShsYXN0cG9zLCBvZmZzZXQgLSBsYXN0cG9zKSkKKyAgICAgICAgICAgICAgICBzcC5hcHBlbmQoX2RhdGEob2Zmc2V0LCBudW1ieXRlcywgcmVhbHBvcykpCisgICAgICAgICAgICAgICAgcmVhbHBvcyArPSBudW1ieXRlcworICAgICAgICAgICAgICAgIGxhc3Rwb3MgPSBvZmZzZXQgKyBudW1ieXRlcworICAgICAgICAgICAgICAgIHBvcyArPSAyNAorICAgICAgICAgICAgaXNleHRlbmRlZCA9IG9yZChidWZbNTA0XSkKKworICAgICAgICBpZiBsYXN0cG9zIDwgb3JpZ3NpemU6CisgICAgICAgICAgICBzcC5hcHBlbmQoX2hvbGUobGFzdHBvcywgb3JpZ3NpemUgLSBsYXN0cG9zKSkKKworICAgICAgICB0YXJpbmZvLnNwYXJzZSA9IHNwCisKKyAgICAgICAgdGFyaW5mby5vZmZzZXRfZGF0YSA9IHNlbGYub2Zmc2V0CisgICAgICAgIHNlbGYub2Zmc2V0ICs9IHNlbGYuX2Jsb2NrKHRhcmluZm8uc2l6ZSkKKyAgICAgICAgdGFyaW5mby5zaXplID0gb3JpZ3NpemUKKyAgICAgICAgcmV0dXJuIHRhcmluZm8KKworICAgICMgVGhlIHR5cGUgbWFwcGluZyBmb3IgdGhlIG5leHQoKSBtZXRob2QuIFRoZSBrZXlzIGFyZSBzaW5nbGUgY2hhcmFjdGVyCisgICAgIyBzdHJpbmdzLCB0aGUgdHlwZWZsYWcuIFRoZSB2YWx1ZXMgYXJlIG1ldGhvZHMgd2hpY2ggYXJlIGNhbGxlZCB3aGVuCisgICAgIyBuZXh0KCkgZW5jb3VudGVycyBzdWNoIGEgdHlwZWZsYWcuCisgICAgVFlQRV9NRVRIID0geworICAgICAgICBHTlVUWVBFX0xPTkdOQU1FOiBwcm9jX2dudWxvbmcsCisgICAgICAgIEdOVVRZUEVfTE9OR0xJTks6IHByb2NfZ251bG9uZywKKyAgICAgICAgR05VVFlQRV9TUEFSU0U6ICAgcHJvY19zcGFyc2UKKyAgICB9CisKKyAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAjIExpdHRsZSBoZWxwZXIgbWV0aG9kczoKKworICAgIGRlZiBfYmxvY2soc2VsZiwgY291bnQpOgorICAgICAgICAiIiJSb3VuZCB1cCBhIGJ5dGUgY291bnQgYnkgQkxPQ0tTSVpFIGFuZCByZXR1cm4gaXQsCisgICAgICAgICAgIGUuZy4gX2Jsb2NrKDgzNCkgPT4gMTAyNC4KKyAgICAgICAgIiIiCisgICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGNvdW50LCBCTE9DS1NJWkUpCisgICAgICAgIGlmIHJlbWFpbmRlcjoKKyAgICAgICAgICAgIGJsb2NrcyArPSAxCisgICAgICAgIHJldHVybiBibG9ja3MgKiBCTE9DS1NJWkUKKworICAgIGRlZiBfZ2V0bWVtYmVyKHNlbGYsIG5hbWUsIHRhcmluZm89Tm9uZSk6CisgICAgICAgICIiIkZpbmQgYW4gYXJjaGl2ZSBtZW1iZXIgYnkgbmFtZSBmcm9tIGJvdHRvbSB0byB0b3AuCisgICAgICAgICAgIElmIHRhcmluZm8gaXMgZ2l2ZW4sIGl0IGlzIHVzZWQgYXMgdGhlIHN0YXJ0aW5nIHBvaW50LgorICAgICAgICAiIiIKKyAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgorICAgICAgICAgICAgZW5kID0gbGVuKHNlbGYubWVtYmVycykKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIGVuZCA9IHNlbGYubWVtYmVycy5pbmRleCh0YXJpbmZvKQorCisgICAgICAgIGZvciBpIGluIHhyYW5nZShlbmQgLSAxLCAtMSwgLTEpOgorICAgICAgICAgICAgaWYgbmFtZSA9PSBzZWxmLm1lbWJlcm5hbWVzW2ldOgorICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLm1lbWJlcnNbaV0KKworICAgIGRlZiBfbG9hZChzZWxmKToKKyAgICAgICAgIiIiUmVhZCB0aHJvdWdoIHRoZSBlbnRpcmUgYXJjaGl2ZSBmaWxlIGFuZCBsb29rIGZvciByZWFkYWJsZQorICAgICAgICAgICBtZW1iZXJzLgorICAgICAgICAiIiIKKyAgICAgICAgd2hpbGUgVHJ1ZToKKyAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLm5leHQoKQorICAgICAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgorICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgIHNlbGYuX2xvYWRlZCA9IFRydWUKKworICAgIGRlZiBfY2hlY2soc2VsZiwgbW9kZT1Ob25lKToKKyAgICAgICAgIiIiQ2hlY2sgaWYgVGFyRmlsZSBpcyBzdGlsbCBvcGVuLCBhbmQgaWYgdGhlIG9wZXJhdGlvbidzIG1vZGUKKyAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gVGFyRmlsZSdzIG1vZGUuCisgICAgICAgICIiIgorICAgICAgICBpZiBzZWxmLmNsb3NlZDoKKyAgICAgICAgICAgIHJhaXNlIElPRXJyb3IsICIlcyBpcyBjbG9zZWQiICUgc2VsZi5fX2NsYXNzX18uX19uYW1lX18KKyAgICAgICAgaWYgbW9kZSBpcyBub3QgTm9uZSBhbmQgc2VsZi5fbW9kZSBub3QgaW4gbW9kZToKKyAgICAgICAgICAgIHJhaXNlIElPRXJyb3IsICJiYWQgb3BlcmF0aW9uIGZvciBtb2RlICVyIiAlIHNlbGYuX21vZGUKKworICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKKyAgICAgICAgIiIiUHJvdmlkZSBhbiBpdGVyYXRvciBvYmplY3QuCisgICAgICAgICIiIgorICAgICAgICBpZiBzZWxmLl9sb2FkZWQ6CisgICAgICAgICAgICByZXR1cm4gaXRlcihzZWxmLm1lbWJlcnMpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICByZXR1cm4gVGFySXRlcihzZWxmKQorCisgICAgZGVmIF9jcmVhdGVfZ251bG9uZyhzZWxmLCBuYW1lLCB0eXBlKToKKyAgICAgICAgIiIiV3JpdGUgYSBHTlUgbG9uZ25hbWUvbG9uZ2xpbmsgbWVtYmVyIHRvIHRoZSBUYXJGaWxlLgorICAgICAgICAgICBJdCBjb25zaXN0cyBvZiBhbiBleHRlbmRlZCB0YXIgaGVhZGVyLCB3aXRoIHRoZSBsZW5ndGgKKyAgICAgICAgICAgb2YgdGhlIGxvbmduYW1lIGFzIHNpemUsIGZvbGxvd2VkIGJ5IGRhdGEgYmxvY2tzLAorICAgICAgICAgICB3aGljaCBjb250YWluIHRoZSBsb25nbmFtZSBhcyBhIG51bGwgdGVybWluYXRlZCBzdHJpbmcuCisgICAgICAgICIiIgorICAgICAgICB0YXJpbmZvID0gVGFySW5mbygpCisgICAgICAgIHRhcmluZm8ubmFtZSA9ICIuLy4vQExvbmdMaW5rIgorICAgICAgICB0YXJpbmZvLnR5cGUgPSB0eXBlCisgICAgICAgIHRhcmluZm8ubW9kZSA9IDAKKyAgICAgICAgdGFyaW5mby5zaXplID0gbGVuKG5hbWUpCisKKyAgICAgICAgIyB3cml0ZSBleHRlbmRlZCBoZWFkZXIKKyAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHRhcmluZm8udG9idWYoKSkKKyAgICAgICAgIyB3cml0ZSBuYW1lIGJsb2NrcworICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUobmFtZSkKKyAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QodGFyaW5mby5zaXplLCBCTE9DS1NJWkUpCisgICAgICAgIGlmIHJlbWFpbmRlciA+IDA6CisgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKEJMT0NLU0laRSAtIHJlbWFpbmRlcikpCisgICAgICAgICAgICBibG9ja3MgKz0gMQorICAgICAgICBzZWxmLm9mZnNldCArPSBibG9ja3MgKiBCTE9DS1NJWkUKKworICAgIGRlZiBfZGJnKHNlbGYsIGxldmVsLCBtc2cpOgorICAgICAgICAiIiJXcml0ZSBkZWJ1Z2dpbmcgb3V0cHV0IHRvIHN5cy5zdGRlcnIuCisgICAgICAgICIiIgorICAgICAgICBpZiBsZXZlbCA8PSBzZWxmLmRlYnVnOgorICAgICAgICAgICAgcHJpbnQgPj4gc3lzLnN0ZGVyciwgbXNnCisjIGNsYXNzIFRhckZpbGUKKworY2xhc3MgVGFySXRlcjoKKyAgICAiIiJJdGVyYXRvciBDbGFzcy4KKworICAgICAgIGZvciB0YXJpbmZvIGluIFRhckZpbGUoLi4uKToKKyAgICAgICAgICAgc3VpdGUuLi4KKyAgICAiIiIKKworICAgIGRlZiBfX2luaXRfXyhzZWxmLCB0YXJmaWxlKToKKyAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySXRlciBvYmplY3QuCisgICAgICAgICIiIgorICAgICAgICBzZWxmLnRhcmZpbGUgPSB0YXJmaWxlCisgICAgZGVmIF9faXRlcl9fKHNlbGYpOgorICAgICAgICAiIiJSZXR1cm4gaXRlcmF0b3Igb2JqZWN0LgorICAgICAgICAiIiIKKyAgICAgICAgcmV0dXJuIHNlbGYKKyAgICBkZWYgbmV4dChzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IGl0ZW0gdXNpbmcgVGFyRmlsZSdzIG5leHQoKSBtZXRob2QuCisgICAgICAgICAgIFdoZW4gYWxsIG1lbWJlcnMgaGF2ZSBiZWVuIHJlYWQsIHNldCBUYXJGaWxlIGFzIF9sb2FkZWQuCisgICAgICAgICIiIgorICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJmaWxlLm5leHQoKQorICAgICAgICBpZiBub3QgdGFyaW5mbzoKKyAgICAgICAgICAgIHNlbGYudGFyZmlsZS5fbG9hZGVkID0gVHJ1ZQorICAgICAgICAgICAgcmFpc2UgU3RvcEl0ZXJhdGlvbgorICAgICAgICByZXR1cm4gdGFyaW5mbworCisjIEhlbHBlciBjbGFzc2VzIGZvciBzcGFyc2UgZmlsZSBzdXBwb3J0CitjbGFzcyBfc2VjdGlvbjoKKyAgICAiIiJCYXNlIGNsYXNzIGZvciBfZGF0YSBhbmQgX2hvbGUuCisgICAgIiIiCisgICAgZGVmIF9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSk6CisgICAgICAgIHNlbGYub2Zmc2V0ID0gb2Zmc2V0CisgICAgICAgIHNlbGYuc2l6ZSA9IHNpemUKKyAgICBkZWYgX19jb250YWluc19fKHNlbGYsIG9mZnNldCk6CisgICAgICAgIHJldHVybiBzZWxmLm9mZnNldCA8PSBvZmZzZXQgPCBzZWxmLm9mZnNldCArIHNlbGYuc2l6ZQorCitjbGFzcyBfZGF0YShfc2VjdGlvbik6CisgICAgIiIiUmVwcmVzZW50IGEgZGF0YSBzZWN0aW9uIGluIGEgc3BhcnNlIGZpbGUuCisgICAgIiIiCisgICAgZGVmIF9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSwgcmVhbHBvcyk6CisgICAgICAgIF9zZWN0aW9uLl9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSkKKyAgICAgICAgc2VsZi5yZWFscG9zID0gcmVhbHBvcworCitjbGFzcyBfaG9sZShfc2VjdGlvbik6CisgICAgIiIiUmVwcmVzZW50IGEgaG9sZSBzZWN0aW9uIGluIGEgc3BhcnNlIGZpbGUuCisgICAgIiIiCisgICAgcGFzcworCitjbGFzcyBfcmluZ2J1ZmZlcihsaXN0KToKKyAgICAiIiJSaW5nYnVmZmVyIGNsYXNzIHdoaWNoIGluY3JlYXNlcyBwZXJmb3JtYW5jZQorICAgICAgIG92ZXIgYSByZWd1bGFyIGxpc3QuCisgICAgIiIiCisgICAgZGVmIF9faW5pdF9fKHNlbGYpOgorICAgICAgICBzZWxmLmlkeCA9IDAKKyAgICBkZWYgZmluZChzZWxmLCBvZmZzZXQpOgorICAgICAgICBpZHggPSBzZWxmLmlkeAorICAgICAgICB3aGlsZSBUcnVlOgorICAgICAgICAgICAgaXRlbSA9IHNlbGZbaWR4XQorICAgICAgICAgICAgaWYgb2Zmc2V0IGluIGl0ZW06CisgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgICAgIGlkeCArPSAxCisgICAgICAgICAgICBpZiBpZHggPT0gbGVuKHNlbGYpOgorICAgICAgICAgICAgICAgIGlkeCA9IDAKKyAgICAgICAgICAgIGlmIGlkeCA9PSBzZWxmLmlkeDoKKyAgICAgICAgICAgICAgICAjIEVuZCBvZiBGaWxlCisgICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKKyAgICAgICAgc2VsZi5pZHggPSBpZHgKKyAgICAgICAgcmV0dXJuIGl0ZW0KKworIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIyB6aXBmaWxlIGNvbXBhdGlibGUgVGFyRmlsZSBjbGFzcworIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorVEFSX1BMQUlOID0gMCAgICAgICAgICAgIyB6aXBmaWxlLlpJUF9TVE9SRUQKK1RBUl9HWklQUEVEID0gOCAgICAgICAgICMgemlwZmlsZS5aSVBfREVGTEFURUQKK2NsYXNzIFRhckZpbGVDb21wYXQ6CisgICAgIiIiVGFyRmlsZSBjbGFzcyBjb21wYXRpYmxlIHdpdGggc3RhbmRhcmQgbW9kdWxlIHppcGZpbGUncworICAgICAgIFppcEZpbGUgY2xhc3MuCisgICAgIiIiCisgICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGUsIG1vZGU9InIiLCBjb21wcmVzc2lvbj1UQVJfUExBSU4pOgorICAgICAgICBpZiBjb21wcmVzc2lvbiA9PSBUQVJfUExBSU46CisgICAgICAgICAgICBzZWxmLnRhcmZpbGUgPSBUYXJGaWxlLnRhcm9wZW4oZmlsZSwgbW9kZSkKKyAgICAgICAgZWxpZiBjb21wcmVzc2lvbiA9PSBUQVJfR1pJUFBFRDoKKyAgICAgICAgICAgIHNlbGYudGFyZmlsZSA9IFRhckZpbGUuZ3pvcGVuKGZpbGUsIG1vZGUpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAidW5rbm93biBjb21wcmVzc2lvbiBjb25zdGFudCIKKyAgICAgICAgaWYgbW9kZVswOjFdID09ICJyIjoKKyAgICAgICAgICAgIG1lbWJlcnMgPSBzZWxmLnRhcmZpbGUuZ2V0bWVtYmVycygpCisgICAgICAgICAgICBmb3IgaSBpbiB4cmFuZ2UobGVuKG1lbWJlcnMpKToKKyAgICAgICAgICAgICAgICBtID0gbWVtYmVyc1tpXQorICAgICAgICAgICAgICAgIG0uZmlsZW5hbWUgPSBtLm5hbWUKKyAgICAgICAgICAgICAgICBtLmZpbGVfc2l6ZSA9IG0uc2l6ZQorICAgICAgICAgICAgICAgIG0uZGF0ZV90aW1lID0gdGltZS5nbXRpbWUobS5tdGltZSlbOjZdCisgICAgZGVmIG5hbWVsaXN0KHNlbGYpOgorICAgICAgICByZXR1cm4gbWFwKGxhbWJkYSBtOiBtLm5hbWUsIHNlbGYuaW5mb2xpc3QoKSkKKyAgICBkZWYgaW5mb2xpc3Qoc2VsZik6CisgICAgICAgIHJldHVybiBmaWx0ZXIobGFtYmRhIG06IG0udHlwZSBpbiBSRUdVTEFSX1RZUEVTLAorICAgICAgICAgICAgICAgICAgICAgIHNlbGYudGFyZmlsZS5nZXRtZW1iZXJzKCkpCisgICAgZGVmIHByaW50ZGlyKHNlbGYpOgorICAgICAgICBzZWxmLnRhcmZpbGUubGlzdCgpCisgICAgZGVmIHRlc3R6aXAoc2VsZik6CisgICAgICAgIHJldHVybgorICAgIGRlZiBnZXRpbmZvKHNlbGYsIG5hbWUpOgorICAgICAgICByZXR1cm4gc2VsZi50YXJmaWxlLmdldG1lbWJlcihuYW1lKQorICAgIGRlZiByZWFkKHNlbGYsIG5hbWUpOgorICAgICAgICByZXR1cm4gc2VsZi50YXJmaWxlLmV4dHJhY3RmaWxlKHNlbGYudGFyZmlsZS5nZXRtZW1iZXIobmFtZSkpLnJlYWQoKQorICAgIGRlZiB3cml0ZShzZWxmLCBmaWxlbmFtZSwgYXJjbmFtZT1Ob25lLCBjb21wcmVzc190eXBlPU5vbmUpOgorICAgICAgICBzZWxmLnRhcmZpbGUuYWRkKGZpbGVuYW1lLCBhcmNuYW1lKQorICAgIGRlZiB3cml0ZXN0cihzZWxmLCB6aW5mbywgYnl0ZXMpOgorICAgICAgICBpbXBvcnQgU3RyaW5nSU8KKyAgICAgICAgaW1wb3J0IGNhbGVuZGFyCisgICAgICAgIHppbmZvLm5hbWUgPSB6aW5mby5maWxlbmFtZQorICAgICAgICB6aW5mby5zaXplID0gemluZm8uZmlsZV9zaXplCisgICAgICAgIHppbmZvLm10aW1lID0gY2FsZW5kYXIudGltZWdtKHppbmZvLmRhdGVfdGltZSkKKyAgICAgICAgc2VsZi50YXJmaWxlLmFkZGZpbGUoemluZm8sIFN0cmluZ0lPLlN0cmluZ0lPKGJ5dGVzKSkKKyAgICBkZWYgY2xvc2Uoc2VsZik6CisgICAgICAgIHNlbGYudGFyZmlsZS5jbG9zZSgpCisjY2xhc3MgVGFyRmlsZUNvbXBhdAorCisjLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyMgZXhwb3J0ZWQgZnVuY3Rpb25zCisjLS0tLS0tLS0tLS0tLS0tLS0tLS0KK2RlZiBpc190YXJmaWxlKG5hbWUpOgorICAgICIiIlJldHVybiBUcnVlIGlmIG5hbWUgcG9pbnRzIHRvIGEgdGFyIGFyY2hpdmUgdGhhdCB3ZQorICAgICAgIGFyZSBhYmxlIHRvIGhhbmRsZSwgZWxzZSByZXR1cm4gRmFsc2UuCisgICAgIiIiCisgICAgdHJ5OgorICAgICAgICB0ID0gb3BlbihuYW1lKQorICAgICAgICB0LmNsb3NlKCkKKyAgICAgICAgcmV0dXJuIFRydWUKKyAgICBleGNlcHQgVGFyRXJyb3I6CisgICAgICAgIHJldHVybiBGYWxzZQorCitvcGVuID0gVGFyRmlsZS5vcGVuCmRpZmYgLS1naXQgYS9MaWIvdGVzdC90ZXN0X3RhcmZpbGUucHkgYi9MaWIvdGVzdC90ZXN0X3RhcmZpbGUucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmRjMDZlYQotLS0gL2Rldi9udWxsCisrKyBiL0xpYi90ZXN0L3Rlc3RfdGFyZmlsZS5weQpAQCAtMCwwICsxLDI1MyBAQAoraW1wb3J0IHN5cworaW1wb3J0IG9zCitpbXBvcnQgc2h1dGlsCisKK2ltcG9ydCB1bml0dGVzdAoraW1wb3J0IHRhcmZpbGUKKworZnJvbSB0ZXN0IGltcG9ydCB0ZXN0X3N1cHBvcnQKKworIyBDaGVjayBmb3Igb3VyIGNvbXByZXNzaW9uIG1vZHVsZXMuCit0cnk6CisgICAgaW1wb3J0IGd6aXAKK2V4Y2VwdCBJbXBvcnRFcnJvcjoKKyAgICBnemlwID0gTm9uZQordHJ5OgorICAgIGltcG9ydCBiejIKK2V4Y2VwdCBJbXBvcnRFcnJvcjoKKyAgICBiejIgPSBOb25lCisKK2RlZiBwYXRoKHBhdGgpOgorICAgIHJldHVybiB0ZXN0X3N1cHBvcnQuZmluZGZpbGUocGF0aCkKKwordGVzdHRhciA9IHBhdGgoInRlc3R0YXIudGFyIikKK3RlbXBkaXIgPSBwYXRoKCJ0ZXN0dGFyLmRpciIpCit0ZW1wbmFtZSA9IHBhdGgoInRlc3R0YXIudG1wIikKK21lbWJlcmNvdW50ID0gMTAKKworZGVmIHRhcm5hbWUoY29tcD0iIik6CisgICAgaWYgbm90IGNvbXA6CisgICAgICAgIHJldHVybiB0ZXN0dGFyCisgICAgcmV0dXJuICIlcy4lcyIgJSAodGVzdHRhciwgY29tcCkKKworZGVmIGRpcm5hbWUoKToKKyAgICBpZiBub3Qgb3MucGF0aC5leGlzdHModGVtcGRpcik6CisgICAgICAgIG9zLm1rZGlyKHRlbXBkaXIpCisgICAgcmV0dXJuIHRlbXBkaXIKKworZGVmIHRtcG5hbWUoKToKKyAgICByZXR1cm4gdGVtcG5hbWUKKworCitjbGFzcyBCYXNlVGVzdCh1bml0dGVzdC5UZXN0Q2FzZSk6CisgICAgY29tcCA9ICcnCisgICAgbW9kZSA9ICdyJworICAgIHNlcCA9ICc6JworCisgICAgZGVmIHNldFVwKHNlbGYpOgorICAgICAgICBtb2RlID0gc2VsZi5tb2RlICsgc2VsZi5zZXAgKyBzZWxmLmNvbXAKKyAgICAgICAgc2VsZi50YXIgPSB0YXJmaWxlLm9wZW4odGFybmFtZShzZWxmLmNvbXApLCBtb2RlKQorCisgICAgZGVmIHRlYXJEb3duKHNlbGYpOgorICAgICAgICBzZWxmLnRhci5jbG9zZSgpCisKK2NsYXNzIFJlYWRUZXN0KEJhc2VUZXN0KToKKworICAgIGRlZiB0ZXN0KHNlbGYpOgorICAgICAgICAiIiJUZXN0IG1lbWJlciBleHRyYWN0aW9uLgorICAgICAgICAiIiIKKyAgICAgICAgbWVtYmVycyA9IDAKKyAgICAgICAgZm9yIHRhcmluZm8gaW4gc2VsZi50YXI6CisgICAgICAgICAgICBtZW1iZXJzICs9IDEKKyAgICAgICAgICAgIGlmIG5vdCB0YXJpbmZvLmlzcmVnKCk6CisgICAgICAgICAgICAgICAgY29udGludWUKKyAgICAgICAgICAgIGYgPSBzZWxmLnRhci5leHRyYWN0ZmlsZSh0YXJpbmZvKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihmLnJlYWQoKSkgPT0gdGFyaW5mby5zaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICJzaXplIHJlYWQgZG9lcyBub3QgbWF0Y2ggZXhwZWN0ZWQgc2l6ZSIpCisgICAgICAgICAgICBmLmNsb3NlKCkKKworICAgICAgICBzZWxmLmFzc2VydF8obWVtYmVycyA9PSBtZW1iZXJjb3VudCwKKyAgICAgICAgICAgICAgICAgICAgICJjb3VsZCBub3QgZmluZCBhbGwgbWVtYmVycyIpCisKKyAgICBkZWYgdGVzdF9zcGFyc2Uoc2VsZik6CisgICAgICAgICIiIlRlc3Qgc3BhcnNlIG1lbWJlciBleHRyYWN0aW9uLgorICAgICAgICAiIiIKKyAgICAgICAgaWYgc2VsZi5zZXAgIT0gInwiOgorICAgICAgICAgICAgZjEgPSBzZWxmLnRhci5leHRyYWN0ZmlsZSgiUy1TUEFSU0UiKQorICAgICAgICAgICAgZjIgPSBzZWxmLnRhci5leHRyYWN0ZmlsZSgiUy1TUEFSU0UtV0lUSC1OVUxMUyIpCisgICAgICAgICAgICBzZWxmLmFzc2VydF8oZjEucmVhZCgpID09IGYyLnJlYWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiX0ZpbGVPYmplY3QgZmFpbGVkIG9uIHNwYXJzZSBmaWxlIG1lbWJlciIpCisKKyAgICBkZWYgdGVzdF9yZWFkbGluZXMoc2VsZik6CisgICAgICAgICIiIlRlc3QgcmVhZGxpbmVzKCkgbWV0aG9kIG9mIF9GaWxlT2JqZWN0LgorICAgICAgICAiIiIKKyAgICAgICAgaWYgc2VsZi5zZXAgIT0gInwiOgorICAgICAgICAgICAgZmlsZW5hbWUgPSAiMC1SRUdUWVBFLVRFWFQiCisgICAgICAgICAgICBzZWxmLnRhci5leHRyYWN0KGZpbGVuYW1lLCBkaXJuYW1lKCkpCisgICAgICAgICAgICBsaW5lczEgPSBmaWxlKG9zLnBhdGguam9pbihkaXJuYW1lKCksIGZpbGVuYW1lKSwgInIiKS5yZWFkbGluZXMoKQorICAgICAgICAgICAgbGluZXMyID0gc2VsZi50YXIuZXh0cmFjdGZpbGUoZmlsZW5hbWUpLnJlYWRsaW5lcygpCisgICAgICAgICAgICBzZWxmLmFzc2VydF8obGluZXMxID09IGxpbmVzMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiX0ZpbGVPYmplY3QucmVhZGxpbmUoKSBkb2VzIG5vdCB3b3JrIGNvcnJlY3RseSIpCisKKyAgICBkZWYgdGVzdF9zZWVrKHNlbGYpOgorICAgICAgICAiIiJUZXN0IHNlZWsoKSBtZXRob2Qgb2YgX0ZpbGVPYmplY3QsIGluY2wuIHJhbmRvbSByZWFkaW5nLgorICAgICAgICAiIiIKKyAgICAgICAgaWYgc2VsZi5zZXAgIT0gInwiOgorICAgICAgICAgICAgZmlsZW5hbWUgPSAiMC1SRUdUWVBFIgorICAgICAgICAgICAgc2VsZi50YXIuZXh0cmFjdChmaWxlbmFtZSwgZGlybmFtZSgpKQorICAgICAgICAgICAgZGF0YSA9IGZpbGUob3MucGF0aC5qb2luKGRpcm5hbWUoKSwgZmlsZW5hbWUpLCAicmIiKS5yZWFkKCkKKworICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyLmdldG1lbWJlcihmaWxlbmFtZSkKKyAgICAgICAgICAgIGZvYmogPSBzZWxmLnRhci5leHRyYWN0ZmlsZSh0YXJpbmZvKQorCisgICAgICAgICAgICB0ZXh0ID0gZm9iai5yZWFkKCkKKyAgICAgICAgICAgIGZvYmouc2VlaygwKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKDAgPT0gZm9iai50ZWxsKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgInNlZWsoKSB0byBmaWxlJ3Mgc3RhcnQgZmFpbGVkIikKKyAgICAgICAgICAgIGZvYmouc2VlaygyMDQ4LCAwKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKDIwNDggPT0gZm9iai50ZWxsKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgInNlZWsoKSB0byBhYnNvbHV0ZSBwb3NpdGlvbiBmYWlsZWQiKQorICAgICAgICAgICAgZm9iai5zZWVrKC0xMDI0LCAxKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKDEwMjQgPT0gZm9iai50ZWxsKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgInNlZWsoKSB0byBuZWdhdGl2ZSByZWxhdGl2ZSBwb3NpdGlvbiBmYWlsZWQiKQorICAgICAgICAgICAgZm9iai5zZWVrKDEwMjQsIDEpCisgICAgICAgICAgICBzZWxmLmFzc2VydF8oMjA0OCA9PSBmb2JqLnRlbGwoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAic2VlaygpIHRvIHBvc2l0aXZlIHJlbGF0aXZlIHBvc2l0aW9uIGZhaWxlZCIpCisgICAgICAgICAgICBzID0gZm9iai5yZWFkKDEwKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKHMgPT0gZGF0YVsyMDQ4OjIwNThdLAorICAgICAgICAgICAgICAgICAgICAgICAgICJyZWFkKCkgYWZ0ZXIgc2VlayBmYWlsZWQiKQorICAgICAgICAgICAgZm9iai5zZWVrKDAsIDIpCisgICAgICAgICAgICBzZWxmLmFzc2VydF8odGFyaW5mby5zaXplID09IGZvYmoudGVsbCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICJzZWVrKCkgdG8gZmlsZSdzIGVuZCBmYWlsZWQiKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKGZvYmoucmVhZCgpID09ICIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICJyZWFkKCkgYXQgZmlsZSdzIGVuZCBkaWQgbm90IHJldHVybiBlbXB0eSBzdHJpbmciKQorICAgICAgICAgICAgZm9iai5zZWVrKC10YXJpbmZvLnNpemUsIDIpCisgICAgICAgICAgICBzZWxmLmFzc2VydF8oMCA9PSBmb2JqLnRlbGwoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAicmVsYXRpdmUgc2VlaygpIHRvIGZpbGUncyBzdGFydCBmYWlsZWQiKQorICAgICAgICAgICAgZm9iai5zZWVrKDUxMikKKyAgICAgICAgICAgIHMxID0gZm9iai5yZWFkbGluZXMoKQorICAgICAgICAgICAgZm9iai5zZWVrKDUxMikKKyAgICAgICAgICAgIHMyID0gZm9iai5yZWFkbGluZXMoKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKHMxID09IHMyLAorICAgICAgICAgICAgICAgICAgICAgICAgICJyZWFkbGluZXMoKSBhZnRlciBzZWVrIGZhaWxlZCIpCisgICAgICAgICAgICBmb2JqLmNsb3NlKCkKKworY2xhc3MgUmVhZFN0cmVhbVRlc3QoUmVhZFRlc3QpOgorICAgIHNlcCA9ICJ8IgorCisgICAgZGVmIHRlc3Qoc2VsZik6CisgICAgICAgICIiIlRlc3QgbWVtYmVyIGV4dHJhY3Rpb24sIGFuZCBmb3IgU3RyZWFtRXJyb3Igd2hlbgorICAgICAgICAgICBzZWVraW5nIGJhY2t3YXJkcy4KKyAgICAgICAgIiIiCisgICAgICAgIFJlYWRUZXN0LnRlc3Qoc2VsZikKKyAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyLmdldG1lbWJlcnMoKVswXQorICAgICAgICBmID0gc2VsZi50YXIuZXh0cmFjdGZpbGUodGFyaW5mbykKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXModGFyZmlsZS5TdHJlYW1FcnJvciwgZi5yZWFkKQorCisgICAgZGVmIHRlc3Rfc3RyZWFtKHNlbGYpOgorICAgICAgICAiIiJDb21wYXJlIHRoZSBub3JtYWwgdGFyIGFuZCB0aGUgc3RyZWFtIHRhci4KKyAgICAgICAgIiIiCisgICAgICAgIHN0cmVhbSA9IHNlbGYudGFyCisgICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0YXJuYW1lKCksICdyJykKKworICAgICAgICB3aGlsZSAxOgorICAgICAgICAgICAgdDEgPSB0YXIubmV4dCgpCisgICAgICAgICAgICB0MiA9IHN0cmVhbS5uZXh0KCkKKyAgICAgICAgICAgIGlmIHQxIGlzIE5vbmU6CisgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0Xyh0MiBpcyBub3QgTm9uZSwgInN0cmVhbS5uZXh0KCkgZmFpbGVkLiIpCisKKyAgICAgICAgICAgIGlmIHQyLmlzbG5rKCkgb3IgdDIuaXNzeW0oKToKKyAgICAgICAgICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyh0YXJmaWxlLlN0cmVhbUVycm9yLCBzdHJlYW0uZXh0cmFjdGZpbGUsIHQyKQorICAgICAgICAgICAgICAgIGNvbnRpbnVlCisgICAgICAgICAgICB2MSA9IHRhci5leHRyYWN0ZmlsZSh0MSkKKyAgICAgICAgICAgIHYyID0gc3RyZWFtLmV4dHJhY3RmaWxlKHQyKQorICAgICAgICAgICAgaWYgdjEgaXMgTm9uZToKKyAgICAgICAgICAgICAgICBjb250aW51ZQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKHYyIGlzIG5vdCBOb25lLCAic3RyZWFtLmV4dHJhY3RmaWxlKCkgZmFpbGVkIikKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0Xyh2MS5yZWFkKCkgPT0gdjIucmVhZCgpLCAic3RyZWFtIGV4dHJhY3Rpb24gZmFpbGVkIikKKworICAgICAgICBzdHJlYW0uY2xvc2UoKQorCitjbGFzcyBXcml0ZVRlc3QoQmFzZVRlc3QpOgorICAgIG1vZGUgPSAndycKKworICAgIGRlZiBzZXRVcChzZWxmKToKKyAgICAgICAgbW9kZSA9IHNlbGYubW9kZSArIHNlbGYuc2VwICsgc2VsZi5jb21wCisgICAgICAgIHNlbGYuc3JjID0gdGFyZmlsZS5vcGVuKHRhcm5hbWUoc2VsZi5jb21wKSwgJ3InKQorICAgICAgICBzZWxmLmRzdCA9IHRhcmZpbGUub3Blbih0bXBuYW1lKCksIG1vZGUpCisKKyAgICBkZWYgdGVhckRvd24oc2VsZik6CisgICAgICAgIHNlbGYuc3JjLmNsb3NlKCkKKyAgICAgICAgc2VsZi5kc3QuY2xvc2UoKQorCisgICAgZGVmIHRlc3RfcG9zaXgoc2VsZik6CisgICAgICAgIHNlbGYuZHN0LnBvc2l4ID0gMQorICAgICAgICBzZWxmLl90ZXN0KCkKKworICAgIGRlZiB0ZXN0X25vbnBvc2l4KHNlbGYpOgorICAgICAgICBzZWxmLmRzdC5wb3NpeCA9IDAKKyAgICAgICAgc2VsZi5fdGVzdCgpCisKKyAgICBkZWYgX3Rlc3Qoc2VsZik6CisgICAgICAgIGZvciB0YXJpbmZvIGluIHNlbGYuc3JjOgorICAgICAgICAgICAgaWYgbm90IHRhcmluZm8uaXNyZWcoKToKKyAgICAgICAgICAgICAgICBjb250aW51ZQorICAgICAgICAgICAgZiA9IHNlbGYuc3JjLmV4dHJhY3RmaWxlKHRhcmluZm8pCisgICAgICAgICAgICBpZiBzZWxmLmRzdC5wb3NpeCBhbmQgbGVuKHRhcmluZm8ubmFtZSkgPiB0YXJmaWxlLkxFTkdUSF9OQU1FOgorICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIHNlbGYuZHN0LmFkZGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvLCBmKQorICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICBzZWxmLmRzdC5hZGRmaWxlKHRhcmluZm8sIGYpCisKK2NsYXNzIFdyaXRlU3RyZWFtVGVzdChXcml0ZVRlc3QpOgorICAgIHNlcCA9ICd8JworCisjIEd6aXAgVGVzdENhc2VzCitjbGFzcyBSZWFkVGVzdEd6aXAoUmVhZFRlc3QpOgorICAgIGNvbXAgPSAiZ3oiCitjbGFzcyBSZWFkU3RyZWFtVGVzdEd6aXAoUmVhZFN0cmVhbVRlc3QpOgorICAgIGNvbXAgPSAiZ3oiCitjbGFzcyBXcml0ZVRlc3RHemlwKFdyaXRlVGVzdCk6CisgICAgY29tcCA9ICJneiIKK2NsYXNzIFdyaXRlU3RyZWFtVGVzdEd6aXAoV3JpdGVTdHJlYW1UZXN0KToKKyAgICBjb21wID0gImd6IgorCitpZiBiejI6CisgICAgIyBCemlwMiBUZXN0Q2FzZXMKKyAgICBjbGFzcyBSZWFkVGVzdEJ6aXAyKFJlYWRUZXN0R3ppcCk6CisgICAgICAgIGNvbXAgPSAiYnoyIgorICAgIGNsYXNzIFJlYWRTdHJlYW1UZXN0QnppcDIoUmVhZFN0cmVhbVRlc3RHemlwKToKKyAgICAgICAgY29tcCA9ICJiejIiCisgICAgY2xhc3MgV3JpdGVUZXN0QnppcDIoV3JpdGVUZXN0KToKKyAgICAgICAgY29tcCA9ICJiejIiCisgICAgY2xhc3MgV3JpdGVTdHJlYW1UZXN0QnppcDIoV3JpdGVTdHJlYW1UZXN0R3ppcCk6CisgICAgICAgIGNvbXAgPSAiYnoyIgorCisjIElmIGltcG9ydGluZyBnemlwIGZhaWxlZCwgZGlzY2FyZCB0aGUgR3ppcCBUZXN0Q2FzZXMuCitpZiBub3QgZ3ppcDoKKyAgICBkZWwgUmVhZFRlc3RHemlwCisgICAgZGVsIFJlYWRTdHJlYW1UZXN0R3ppcAorICAgIGRlbCBXcml0ZVRlc3RHemlwCisgICAgZGVsIFdyaXRlU3RyZWFtVGVzdEd6aXAKKworaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKKyAgICBpZiBnemlwOgorICAgICAgICAjIGNyZWF0ZSB0ZXN0dGFyLnRhci5negorICAgICAgICBnemlwLm9wZW4odGFybmFtZSgiZ3oiKSwgIndiIikud3JpdGUoZmlsZSh0YXJuYW1lKCksICJyYiIpLnJlYWQoKSkKKyAgICBpZiBiejI6CisgICAgICAgICMgY3JlYXRlIHRlc3R0YXIudGFyLmJ6MgorICAgICAgICBiejIuQloyRmlsZSh0YXJuYW1lKCJiejIiKSwgIndiIikud3JpdGUoZmlsZSh0YXJuYW1lKCksICJyYiIpLnJlYWQoKSkKKworICAgIHRyeToKKyAgICAgICAgdW5pdHRlc3QubWFpbigpCisgICAgZmluYWxseToKKyAgICAgICAgaWYgZ3ppcDoKKyAgICAgICAgICAgIG9zLnJlbW92ZSh0YXJuYW1lKCJneiIpKQorICAgICAgICBpZiBiejI6CisgICAgICAgICAgICBvcy5yZW1vdmUodGFybmFtZSgiYnoyIikpCisgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHRlbXBkaXIpOgorICAgICAgICAgICAgc2h1dGlsLnJtdHJlZSh0ZW1wZGlyKQorICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyh0ZW1wbmFtZSk6CisgICAgICAgICAgICBvcy5yZW1vdmUodGVtcG5hbWUpCisKZGlmZiAtLWdpdCBhL0xpYi90ZXN0L3Rlc3R0YXIudGFyIGIvTGliL3Rlc3QvdGVzdHRhci50YXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDAxMjViMwotLS0gL2Rldi9udWxsCisrKyBiL0xpYi90ZXN0L3Rlc3R0YXIudGFyCkJpbmFyeSBmaWxlcyBkaWZmZXIK