IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMgLSotIGNvZGluZzogaXNvLTg4NTktMSAtKi0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlLnB5CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ29weXJpZ2h0IChDKSAyMDAyIExhcnMgR3VzdORiZWwgPGxhcnNAZ3VzdGFlYmVsLmRlPgojIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMKIyBQZXJtaXNzaW9uICBpcyAgaGVyZWJ5IGdyYW50ZWQsICBmcmVlICBvZiBjaGFyZ2UsICB0byAgYW55IHBlcnNvbgojIG9idGFpbmluZyBhICBjb3B5IG9mICB0aGlzIHNvZnR3YXJlICBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uCiMgZmlsZXMgICh0aGUgICJTb2Z0d2FyZSIpLCAgdG8gICBkZWFsICBpbiAgdGhlICBTb2Z0d2FyZSAgIHdpdGhvdXQKIyByZXN0cmljdGlvbiwgIGluY2x1ZGluZyAgd2l0aG91dCBsaW1pdGF0aW9uICB0aGUgIHJpZ2h0cyB0byAgdXNlLAojIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiMgY29waWVzICBvZiAgdGhlICBTb2Z0d2FyZSwgIGFuZCB0byAgcGVybWl0ICBwZXJzb25zICB0byAgd2hvbSB0aGUKIyBTb2Z0d2FyZSAgaXMgIGZ1cm5pc2hlZCAgdG8gIGRvICBzbywgIHN1YmplY3QgIHRvICB0aGUgIGZvbGxvd2luZwojIGNvbmRpdGlvbnM6CiMKIyBUaGUgYWJvdmUgY29weXJpZ2h0ICBub3RpY2UgYW5kIHRoaXMgIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsICBiZQojIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgojCiMgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyAgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSAgS0lORCwKIyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyAgQlVUIE5PVCBMSU1JVEVEIFRPICBUSEUgV0FSUkFOVElFUwojIE9GICBNRVJDSEFOVEFCSUxJVFksICBGSVRORVNTICAgRk9SICBBICBQQVJUSUNVTEFSICAgUFVSUE9TRSAgQU5ECiMgTk9OSU5GUklOR0VNRU5ULiAgSU4gIE5PICBFVkVOVCBTSEFMTCAgVEhFICBBVVRIT1JTICBPUiBDT1BZUklHSFQKIyBIT0xERVJTICBCRSBMSUFCTEUgIEZPUiBBTlkgIENMQUlNLCBEQU1BR0VTICBPUiBPVEhFUiAgTElBQklMSVRZLAojIFdIRVRIRVIgIElOIEFOICBBQ1RJT04gT0YgIENPTlRSQUNULCBUT1JUICBPUiBPVEhFUldJU0UsICBBUklTSU5HCiMgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUgojIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KIwoiIiJSZWFkIGZyb20gYW5kIHdyaXRlIHRvIHRhciBmb3JtYXQgYXJjaGl2ZXMuCiIiIgoKX192ZXJzaW9uX18gPSAiJFJldmlzaW9uJCIKIyAkU291cmNlJAoKdmVyc2lvbiAgICAgPSAiMC45LjAiCl9fYXV0aG9yX18gID0gIkxhcnMgR3VzdORiZWwgKGxhcnNAZ3VzdGFlYmVsLmRlKSIKX19kYXRlX18gICAgPSAiJERhdGUkIgpfX2N2c2lkX18gICA9ICIkSWQkIgpfX2NyZWRpdHNfXyA9ICJHdXN0YXZvIE5pZW1leWVyLCBOaWVscyBHdXN05GJlbCwgUmljaGFyZCBUb3duc2VuZC4iCgojLS0tLS0tLS0tCiMgSW1wb3J0cwojLS0tLS0tLS0tCmltcG9ydCBzeXMKaW1wb3J0IG9zCmltcG9ydCBzaHV0aWwKaW1wb3J0IHN0YXQKaW1wb3J0IGVycm5vCmltcG9ydCB0aW1lCmltcG9ydCBzdHJ1Y3QKaW1wb3J0IGNvcHkKaW1wb3J0IHJlCgppZiBzeXMucGxhdGZvcm0gPT0gJ21hYyc6CiAgICAjIFRoaXMgbW9kdWxlIG5lZWRzIHdvcmsgZm9yIE1hY09TOSwgZXNwZWNpYWxseSBpbiB0aGUgYXJlYSBvZiBwYXRobmFtZQogICAgIyBoYW5kbGluZy4gSW4gbWFueSBwbGFjZXMgaXQgaXMgYXNzdW1lZCBhIHNpbXBsZSBzdWJzdGl0dXRpb24gb2YgLyBieSB0aGUKICAgICMgbG9jYWwgb3MucGF0aC5zZXAgaXMgZ29vZCBlbm91Z2ggdG8gY29udmVydCBwYXRobmFtZXMsIGJ1dCB0aGlzIGRvZXMgbm90CiAgICAjIHdvcmsgd2l0aCB0aGUgbWFjIHJvb3RlZDpwYXRoOm5hbWUgdmVyc3VzIDpub25yb290ZWQ6cGF0aDpuYW1lIHN5bnRheAogICAgcmFpc2UgSW1wb3J0RXJyb3IsICJ0YXJmaWxlIGRvZXMgbm90IHdvcmsgZm9yIHBsYXRmb3JtPT1tYWMiCgp0cnk6CiAgICBpbXBvcnQgZ3JwLCBwd2QKZXhjZXB0IEltcG9ydEVycm9yOgogICAgZ3JwID0gcHdkID0gTm9uZQoKIyBmcm9tIHRhcmZpbGUgaW1wb3J0ICoKX19hbGxfXyA9IFsiVGFyRmlsZSIsICJUYXJJbmZvIiwgImlzX3RhcmZpbGUiLCAiVGFyRXJyb3IiXQoKZnJvbSBfX2J1aWx0aW5fXyBpbXBvcnQgb3BlbiBhcyBfb3BlbiAjIFNpbmNlICdvcGVuJyBpcyBUYXJGaWxlLm9wZW4KCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXIgY29uc3RhbnRzCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KTlVMID0gIlwwIiAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBudWxsIGNoYXJhY3RlcgpCTE9DS1NJWkUgPSA1MTIgICAgICAgICAgICAgICAgICMgbGVuZ3RoIG9mIHByb2Nlc3NpbmcgYmxvY2tzClJFQ09SRFNJWkUgPSBCTE9DS1NJWkUgKiAyMCAgICAgIyBsZW5ndGggb2YgcmVjb3JkcwpHTlVfTUFHSUMgPSAidXN0YXIgIFwwIiAgICAgICAgICMgbWFnaWMgZ251IHRhciBzdHJpbmcKUE9TSVhfTUFHSUMgPSAidXN0YXJceDAwMDAiICAgICAjIG1hZ2ljIHBvc2l4IHRhciBzdHJpbmcKCkxFTkdUSF9OQU1FID0gMTAwICAgICAgICAgICAgICAgIyBtYXhpbXVtIGxlbmd0aCBvZiBhIGZpbGVuYW1lCkxFTkdUSF9MSU5LID0gMTAwICAgICAgICAgICAgICAgIyBtYXhpbXVtIGxlbmd0aCBvZiBhIGxpbmtuYW1lCkxFTkdUSF9QUkVGSVggPSAxNTUgICAgICAgICAgICAgIyBtYXhpbXVtIGxlbmd0aCBvZiB0aGUgcHJlZml4IGZpZWxkCgpSRUdUWVBFID0gIjAiICAgICAgICAgICAgICAgICAgICMgcmVndWxhciBmaWxlCkFSRUdUWVBFID0gIlwwIiAgICAgICAgICAgICAgICAgIyByZWd1bGFyIGZpbGUKTE5LVFlQRSA9ICIxIiAgICAgICAgICAgICAgICAgICAjIGxpbmsgKGluc2lkZSB0YXJmaWxlKQpTWU1UWVBFID0gIjIiICAgICAgICAgICAgICAgICAgICMgc3ltYm9saWMgbGluawpDSFJUWVBFID0gIjMiICAgICAgICAgICAgICAgICAgICMgY2hhcmFjdGVyIHNwZWNpYWwgZGV2aWNlCkJMS1RZUEUgPSAiNCIgICAgICAgICAgICAgICAgICAgIyBibG9jayBzcGVjaWFsIGRldmljZQpESVJUWVBFID0gIjUiICAgICAgICAgICAgICAgICAgICMgZGlyZWN0b3J5CkZJRk9UWVBFID0gIjYiICAgICAgICAgICAgICAgICAgIyBmaWZvIHNwZWNpYWwgZGV2aWNlCkNPTlRUWVBFID0gIjciICAgICAgICAgICAgICAgICAgIyBjb250aWd1b3VzIGZpbGUKCkdOVVRZUEVfTE9OR05BTUUgPSAiTCIgICAgICAgICAgIyBHTlUgdGFyIGxvbmduYW1lCkdOVVRZUEVfTE9OR0xJTksgPSAiSyIgICAgICAgICAgIyBHTlUgdGFyIGxvbmdsaW5rCkdOVVRZUEVfU1BBUlNFID0gIlMiICAgICAgICAgICAgIyBHTlUgdGFyIHNwYXJzZSBmaWxlCgpYSERUWVBFID0gIngiICAgICAgICAgICAgICAgICAgICMgUE9TSVguMS0yMDAxIGV4dGVuZGVkIGhlYWRlcgpYR0xUWVBFID0gImciICAgICAgICAgICAgICAgICAgICMgUE9TSVguMS0yMDAxIGdsb2JhbCBoZWFkZXIKU09MQVJJU19YSERUWVBFID0gIlgiICAgICAgICAgICAjIFNvbGFyaXMgZXh0ZW5kZWQgaGVhZGVyCgpVU1RBUl9GT1JNQVQgPSAwICAgICAgICAgICAgICAgICMgUE9TSVguMS0xOTg4ICh1c3RhcikgZm9ybWF0CkdOVV9GT1JNQVQgPSAxICAgICAgICAgICAgICAgICAgIyBHTlUgdGFyIGZvcm1hdApQQVhfRk9STUFUID0gMiAgICAgICAgICAgICAgICAgICMgUE9TSVguMS0yMDAxIChwYXgpIGZvcm1hdApERUZBVUxUX0ZPUk1BVCA9IEdOVV9GT1JNQVQKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgRmlsZSB0eXBlcyB0aGF0IHRhcmZpbGUgc3VwcG9ydHM6ClNVUFBPUlRFRF9UWVBFUyA9IChSRUdUWVBFLCBBUkVHVFlQRSwgTE5LVFlQRSwKICAgICAgICAgICAgICAgICAgIFNZTVRZUEUsIERJUlRZUEUsIEZJRk9UWVBFLAogICAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIENIUlRZUEUsIEJMS1RZUEUsCiAgICAgICAgICAgICAgICAgICBHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LLAogICAgICAgICAgICAgICAgICAgR05VVFlQRV9TUEFSU0UpCgojIEZpbGUgdHlwZXMgdGhhdCB3aWxsIGJlIHRyZWF0ZWQgYXMgYSByZWd1bGFyIGZpbGUuClJFR1VMQVJfVFlQRVMgPSAoUkVHVFlQRSwgQVJFR1RZUEUsCiAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIEdOVVRZUEVfU1BBUlNFKQoKIyBGaWxlIHR5cGVzIHRoYXQgYXJlIHBhcnQgb2YgdGhlIEdOVSB0YXIgZm9ybWF0LgpHTlVfVFlQRVMgPSAoR05VVFlQRV9MT05HTkFNRSwgR05VVFlQRV9MT05HTElOSywKICAgICAgICAgICAgIEdOVVRZUEVfU1BBUlNFKQoKIyBGaWVsZHMgZnJvbSBhIHBheCBoZWFkZXIgdGhhdCBvdmVycmlkZSBhIFRhckluZm8gYXR0cmlidXRlLgpQQVhfRklFTERTID0gKCJwYXRoIiwgImxpbmtwYXRoIiwgInNpemUiLCAibXRpbWUiLAogICAgICAgICAgICAgICJ1aWQiLCAiZ2lkIiwgInVuYW1lIiwgImduYW1lIikKCiMgRmllbGRzIGluIGEgcGF4IGhlYWRlciB0aGF0IGFyZSBudW1iZXJzLCBhbGwgb3RoZXIgZmllbGRzCiMgYXJlIHRyZWF0ZWQgYXMgc3RyaW5ncy4KUEFYX05VTUJFUl9GSUVMRFMgPSB7CiAgICAiYXRpbWUiOiBmbG9hdCwKICAgICJjdGltZSI6IGZsb2F0LAogICAgIm10aW1lIjogZmxvYXQsCiAgICAidWlkIjogaW50LAogICAgImdpZCI6IGludCwKICAgICJzaXplIjogaW50Cn0KCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBCaXRzIHVzZWQgaW4gdGhlIG1vZGUgZmllbGQsIHZhbHVlcyBpbiBvY3RhbC4KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTX0lGTE5LID0gMG8xMjAwMDAgICAgICAgICMgc3ltYm9saWMgbGluawpTX0lGUkVHID0gMG8xMDAwMDAgICAgICAgICMgcmVndWxhciBmaWxlClNfSUZCTEsgPSAwbzA2MDAwMCAgICAgICAgIyBibG9jayBkZXZpY2UKU19JRkRJUiA9IDBvMDQwMDAwICAgICAgICAjIGRpcmVjdG9yeQpTX0lGQ0hSID0gMG8wMjAwMDAgICAgICAgICMgY2hhcmFjdGVyIGRldmljZQpTX0lGSUZPID0gMG8wMTAwMDAgICAgICAgICMgZmlmbwoKVFNVSUQgICA9IDBvNDAwMCAgICAgICAgICAjIHNldCBVSUQgb24gZXhlY3V0aW9uClRTR0lEICAgPSAwbzIwMDAgICAgICAgICAgIyBzZXQgR0lEIG9uIGV4ZWN1dGlvbgpUU1ZUWCAgID0gMG8xMDAwICAgICAgICAgICMgcmVzZXJ2ZWQKClRVUkVBRCAgPSAwbzQwMCAgICAgICAgICAgIyByZWFkIGJ5IG93bmVyClRVV1JJVEUgPSAwbzIwMCAgICAgICAgICAgIyB3cml0ZSBieSBvd25lcgpUVUVYRUMgID0gMG8xMDAgICAgICAgICAgICMgZXhlY3V0ZS9zZWFyY2ggYnkgb3duZXIKVEdSRUFEICA9IDBvMDQwICAgICAgICAgICAjIHJlYWQgYnkgZ3JvdXAKVEdXUklURSA9IDBvMDIwICAgICAgICAgICAjIHdyaXRlIGJ5IGdyb3VwClRHRVhFQyAgPSAwbzAxMCAgICAgICAgICAgIyBleGVjdXRlL3NlYXJjaCBieSBncm91cApUT1JFQUQgID0gMG8wMDQgICAgICAgICAgICMgcmVhZCBieSBvdGhlcgpUT1dSSVRFID0gMG8wMDIgICAgICAgICAgICMgd3JpdGUgYnkgb3RoZXIKVE9FWEVDICA9IDBvMDAxICAgICAgICAgICAjIGV4ZWN1dGUvc2VhcmNoIGJ5IG90aGVyCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgaW5pdGlhbGl6YXRpb24KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpFTkNPRElORyA9IHN5cy5nZXRmaWxlc3lzdGVtZW5jb2RpbmcoKQppZiBFTkNPRElORyBpcyBOb25lOgogICAgRU5DT0RJTkcgPSBzeXMuZ2V0ZGVmYXVsdGVuY29kaW5nKCkKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBTb21lIHVzZWZ1bCBmdW5jdGlvbnMKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKZGVmIHN0bihzLCBsZW5ndGgpOgogICAgIiIiQ29udmVydCBhIHB5dGhvbiBzdHJpbmcgdG8gYSBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nIGJ1ZmZlci4KICAgICIiIgogICAgcmV0dXJuIHNbOmxlbmd0aF0gKyAobGVuZ3RoIC0gbGVuKHMpKSAqIE5VTAoKZGVmIG50cyhzKToKICAgICIiIkNvbnZlcnQgYSBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nIGZpZWxkIHRvIGEgcHl0aG9uIHN0cmluZy4KICAgICIiIgogICAgIyBVc2UgdGhlIHN0cmluZyB1cCB0byB0aGUgZmlyc3QgbnVsbCBjaGFyLgogICAgcCA9IHMuZmluZCgiXDAiKQogICAgaWYgcCA9PSAtMToKICAgICAgICByZXR1cm4gcwogICAgcmV0dXJuIHNbOnBdCgpkZWYgbnRpKHMpOgogICAgIiIiQ29udmVydCBhIG51bWJlciBmaWVsZCB0byBhIHB5dGhvbiBudW1iZXIuCiAgICAiIiIKICAgICMgVGhlcmUgYXJlIHR3byBwb3NzaWJsZSBlbmNvZGluZ3MgZm9yIGEgbnVtYmVyIGZpZWxkLCBzZWUKICAgICMgaXRuKCkgYmVsb3cuCiAgICBpZiBzWzBdICE9IGNocigwbzIwMCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBuID0gaW50KG50cyhzKSBvciAiMCIsIDgpCiAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgIHJhaXNlIEhlYWRlckVycm9yKCJpbnZhbGlkIGhlYWRlciIpCiAgICBlbHNlOgogICAgICAgIG4gPSAwCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UobGVuKHMpIC0gMSk6CiAgICAgICAgICAgIG4gPDw9IDgKICAgICAgICAgICAgbiArPSBvcmQoc1tpICsgMV0pCiAgICByZXR1cm4gbgoKZGVmIGl0bihuLCBkaWdpdHM9OCwgZm9ybWF0PURFRkFVTFRfRk9STUFUKToKICAgICIiIkNvbnZlcnQgYSBweXRob24gbnVtYmVyIHRvIGEgbnVtYmVyIGZpZWxkLgogICAgIiIiCiAgICAjIFBPU0lYIDEwMDMuMS0xOTg4IHJlcXVpcmVzIG51bWJlcnMgdG8gYmUgZW5jb2RlZCBhcyBhIHN0cmluZyBvZgogICAgIyBvY3RhbCBkaWdpdHMgZm9sbG93ZWQgYnkgYSBudWxsLWJ5dGUsIHRoaXMgYWxsb3dzIHZhbHVlcyB1cCB0bwogICAgIyAoOCoqKGRpZ2l0cy0xKSktMS4gR05VIHRhciBhbGxvd3Mgc3RvcmluZyBudW1iZXJzIGdyZWF0ZXIgdGhhbgogICAgIyB0aGF0IGlmIG5lY2Vzc2FyeS4gQSBsZWFkaW5nIDBvMjAwIGJ5dGUgaW5kaWNhdGVzIHRoaXMgcGFydGljdWxhcgogICAgIyBlbmNvZGluZywgdGhlIGZvbGxvd2luZyBkaWdpdHMtMSBieXRlcyBhcmUgYSBiaWctZW5kaWFuCiAgICAjIHJlcHJlc2VudGF0aW9uLiBUaGlzIGFsbG93cyB2YWx1ZXMgdXAgdG8gKDI1NioqKGRpZ2l0cy0xKSktMS4KICAgIGlmIDAgPD0gbiA8IDggKiogKGRpZ2l0cyAtIDEpOgogICAgICAgIHMgPSAiJTAqbyIgJSAoZGlnaXRzIC0gMSwgbikgKyBOVUwKICAgIGVsc2U6CiAgICAgICAgaWYgZm9ybWF0ICE9IEdOVV9GT1JNQVQgb3IgbiA+PSAyNTYgKiogKGRpZ2l0cyAtIDEpOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJvdmVyZmxvdyBpbiBudW1iZXIgZmllbGQiKQoKICAgICAgICBpZiBuIDwgMDoKICAgICAgICAgICAgIyBYWFggV2UgbWltaWMgR05VIHRhcidzIGJlaGF2aW91ciB3aXRoIG5lZ2F0aXZlIG51bWJlcnMsCiAgICAgICAgICAgICMgdGhpcyBjb3VsZCByYWlzZSBPdmVyZmxvd0Vycm9yLgogICAgICAgICAgICBuID0gc3RydWN0LnVucGFjaygiTCIsIHN0cnVjdC5wYWNrKCJsIiwgbikpWzBdCgogICAgICAgIHMgPSAiIgogICAgICAgIGZvciBpIGluIHJhbmdlKGRpZ2l0cyAtIDEpOgogICAgICAgICAgICBzID0gY2hyKG4gJiAwbzM3NykgKyBzCiAgICAgICAgICAgIG4gPj49IDgKICAgICAgICBzID0gY2hyKDBvMjAwKSArIHMKICAgIHJldHVybiBzCgpkZWYgdXRzKHMsIGVuY29kaW5nLCBlcnJvcnMpOgogICAgIiIiQ29udmVydCBhIHVuaWNvZGUgb2JqZWN0IHRvIGEgc3RyaW5nLgogICAgIiIiCiAgICBpZiBlcnJvcnMgPT0gInV0Zi04IjoKICAgICAgICAjIEFuIGV4dHJhIGVycm9yIGhhbmRsZXIgc2ltaWxhciB0byB0aGUgLW8gaW52YWxpZD1VVEYtOCBvcHRpb24KICAgICAgICAjIGluIFBPU0lYLjEtMjAwMS4gUmVwbGFjZSB1bnRyYW5zbGF0YWJsZSBjaGFyYWN0ZXJzIHdpdGggdGhlaXIKICAgICAgICAjIFVURi04IHJlcHJlc2VudGF0aW9uLgogICAgICAgIHRyeToKICAgICAgICAgICAgcmV0dXJuIHMuZW5jb2RlKGVuY29kaW5nLCAic3RyaWN0IikKICAgICAgICBleGNlcHQgVW5pY29kZUVuY29kZUVycm9yOgogICAgICAgICAgICB4ID0gW10KICAgICAgICAgICAgZm9yIGMgaW4gczoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICB4LmFwcGVuZChjLmVuY29kZShlbmNvZGluZywgInN0cmljdCIpKQogICAgICAgICAgICAgICAgZXhjZXB0IFVuaWNvZGVFbmNvZGVFcnJvcjoKICAgICAgICAgICAgICAgICAgICB4LmFwcGVuZChjLmVuY29kZSgidXRmOCIpKQogICAgICAgICAgICByZXR1cm4gIiIuam9pbih4KQogICAgZWxzZToKICAgICAgICByZXR1cm4gcy5lbmNvZGUoZW5jb2RpbmcsIGVycm9ycykKCmRlZiBjYWxjX2Noa3N1bXMoYnVmKToKICAgICIiIkNhbGN1bGF0ZSB0aGUgY2hlY2tzdW0gZm9yIGEgbWVtYmVyJ3MgaGVhZGVyIGJ5IHN1bW1pbmcgdXAgYWxsCiAgICAgICBjaGFyYWN0ZXJzIGV4Y2VwdCBmb3IgdGhlIGNoa3N1bSBmaWVsZCB3aGljaCBpcyB0cmVhdGVkIGFzIGlmCiAgICAgICBpdCB3YXMgZmlsbGVkIHdpdGggc3BhY2VzLiBBY2NvcmRpbmcgdG8gdGhlIEdOVSB0YXIgc291cmNlcywKICAgICAgIHNvbWUgdGFycyAoU3VuIGFuZCBOZVhUKSBjYWxjdWxhdGUgY2hrc3VtIHdpdGggc2lnbmVkIGNoYXIsCiAgICAgICB3aGljaCB3aWxsIGJlIGRpZmZlcmVudCBpZiB0aGVyZSBhcmUgY2hhcnMgaW4gdGhlIGJ1ZmZlciB3aXRoCiAgICAgICB0aGUgaGlnaCBiaXQgc2V0LiBTbyB3ZSBjYWxjdWxhdGUgdHdvIGNoZWNrc3VtcywgdW5zaWduZWQgYW5kCiAgICAgICBzaWduZWQuCiAgICAiIiIKICAgIHVuc2lnbmVkX2Noa3N1bSA9IDI1NiArIHN1bShzdHJ1Y3QudW5wYWNrKCIxNDhCIiwgYnVmWzoxNDhdKSArIHN0cnVjdC51bnBhY2soIjM1NkIiLCBidWZbMTU2OjUxMl0pKQogICAgc2lnbmVkX2Noa3N1bSA9IDI1NiArIHN1bShzdHJ1Y3QudW5wYWNrKCIxNDhiIiwgYnVmWzoxNDhdKSArIHN0cnVjdC51bnBhY2soIjM1NmIiLCBidWZbMTU2OjUxMl0pKQogICAgcmV0dXJuIHVuc2lnbmVkX2Noa3N1bSwgc2lnbmVkX2Noa3N1bQoKZGVmIGNvcHlmaWxlb2JqKHNyYywgZHN0LCBsZW5ndGg9Tm9uZSk6CiAgICAiIiJDb3B5IGxlbmd0aCBieXRlcyBmcm9tIGZpbGVvYmogc3JjIHRvIGZpbGVvYmogZHN0LgogICAgICAgSWYgbGVuZ3RoIGlzIE5vbmUsIGNvcHkgdGhlIGVudGlyZSBjb250ZW50LgogICAgIiIiCiAgICBpZiBsZW5ndGggPT0gMDoKICAgICAgICByZXR1cm4KICAgIGlmIGxlbmd0aCBpcyBOb25lOgogICAgICAgIHNodXRpbC5jb3B5ZmlsZW9iaihzcmMsIGRzdCkKICAgICAgICByZXR1cm4KCiAgICBCVUZTSVpFID0gMTYgKiAxMDI0CiAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChsZW5ndGgsIEJVRlNJWkUpCiAgICBmb3IgYiBpbiByYW5nZShibG9ja3MpOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKEJVRlNJWkUpCiAgICAgICAgaWYgbGVuKGJ1ZikgPCBCVUZTSVpFOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yKCJlbmQgb2YgZmlsZSByZWFjaGVkIikKICAgICAgICBkc3Qud3JpdGUoYnVmKQoKICAgIGlmIHJlbWFpbmRlciAhPSAwOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKHJlbWFpbmRlcikKICAgICAgICBpZiBsZW4oYnVmKSA8IHJlbWFpbmRlcjoKICAgICAgICAgICAgcmFpc2UgSU9FcnJvcigiZW5kIG9mIGZpbGUgcmVhY2hlZCIpCiAgICAgICAgZHN0LndyaXRlKGJ1ZikKICAgIHJldHVybgoKZmlsZW1vZGVfdGFibGUgPSAoCiAgICAoKFNfSUZMTkssICAgICAgImwiKSwKICAgICAoU19JRlJFRywgICAgICAiLSIpLAogICAgIChTX0lGQkxLLCAgICAgICJiIiksCiAgICAgKFNfSUZESVIsICAgICAgImQiKSwKICAgICAoU19JRkNIUiwgICAgICAiYyIpLAogICAgIChTX0lGSUZPLCAgICAgICJwIikpLAoKICAgICgoVFVSRUFELCAgICAgICAiciIpLCksCiAgICAoKFRVV1JJVEUsICAgICAgInciKSwpLAogICAgKChUVUVYRUN8VFNVSUQsICJzIiksCiAgICAgKFRTVUlELCAgICAgICAgIlMiKSwKICAgICAoVFVFWEVDLCAgICAgICAieCIpKSwKCiAgICAoKFRHUkVBRCwgICAgICAgInIiKSwpLAogICAgKChUR1dSSVRFLCAgICAgICJ3IiksKSwKICAgICgoVEdFWEVDfFRTR0lELCAicyIpLAogICAgIChUU0dJRCwgICAgICAgICJTIiksCiAgICAgKFRHRVhFQywgICAgICAgIngiKSksCgogICAgKChUT1JFQUQsICAgICAgICJyIiksKSwKICAgICgoVE9XUklURSwgICAgICAidyIpLCksCiAgICAoKFRPRVhFQ3xUU1ZUWCwgInQiKSwKICAgICAoVFNWVFgsICAgICAgICAiVCIpLAogICAgIChUT0VYRUMsICAgICAgICJ4IikpCikKCmRlZiBmaWxlbW9kZShtb2RlKToKICAgICIiIkNvbnZlcnQgYSBmaWxlJ3MgbW9kZSB0byBhIHN0cmluZyBvZiB0aGUgZm9ybQogICAgICAgLXJ3eHJ3eHJ3eC4KICAgICAgIFVzZWQgYnkgVGFyRmlsZS5saXN0KCkKICAgICIiIgogICAgcGVybSA9IFtdCiAgICBmb3IgdGFibGUgaW4gZmlsZW1vZGVfdGFibGU6CiAgICAgICAgZm9yIGJpdCwgY2hhciBpbiB0YWJsZToKICAgICAgICAgICAgaWYgbW9kZSAmIGJpdCA9PSBiaXQ6CiAgICAgICAgICAgICAgICBwZXJtLmFwcGVuZChjaGFyKQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBlbHNlOgogICAgICAgICAgICBwZXJtLmFwcGVuZCgiLSIpCiAgICByZXR1cm4gIiIuam9pbihwZXJtKQoKaWYgb3Muc2VwICE9ICIvIjoKICAgIG5vcm1wYXRoID0gbGFtYmRhIHBhdGg6IG9zLnBhdGgubm9ybXBhdGgocGF0aCkucmVwbGFjZShvcy5zZXAsICIvIikKZWxzZToKICAgIG5vcm1wYXRoID0gb3MucGF0aC5ub3JtcGF0aAoKY2xhc3MgVGFyRXJyb3IoRXhjZXB0aW9uKToKICAgICIiIkJhc2UgZXhjZXB0aW9uLiIiIgogICAgcGFzcwpjbGFzcyBFeHRyYWN0RXJyb3IoVGFyRXJyb3IpOgogICAgIiIiR2VuZXJhbCBleGNlcHRpb24gZm9yIGV4dHJhY3QgZXJyb3JzLiIiIgogICAgcGFzcwpjbGFzcyBSZWFkRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bnJlYWRibGUgdGFyIGFyY2hpdmVzLiIiIgogICAgcGFzcwpjbGFzcyBDb21wcmVzc2lvbkVycm9yKFRhckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgdW5hdmFpbGFibGUgY29tcHJlc3Npb24gbWV0aG9kcy4iIiIKICAgIHBhc3MKY2xhc3MgU3RyZWFtRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bnN1cHBvcnRlZCBvcGVyYXRpb25zIG9uIHN0cmVhbS1saWtlIFRhckZpbGVzLiIiIgogICAgcGFzcwpjbGFzcyBIZWFkZXJFcnJvcihUYXJFcnJvcik6CiAgICAiIiJFeGNlcHRpb24gZm9yIGludmFsaWQgaGVhZGVycy4iIiIKICAgIHBhc3MKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBpbnRlcm5hbCBzdHJlYW0gaW50ZXJmYWNlCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY2xhc3MgX0xvd0xldmVsRmlsZToKICAgICIiIkxvdy1sZXZlbCBmaWxlIG9iamVjdC4gU3VwcG9ydHMgcmVhZGluZyBhbmQgd3JpdGluZy4KICAgICAgIEl0IGlzIHVzZWQgaW5zdGVhZCBvZiBhIHJlZ3VsYXIgZmlsZSBvYmplY3QgZm9yIHN0cmVhbWluZwogICAgICAgYWNjZXNzLgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIG1vZGUpOgogICAgICAgIG1vZGUgPSB7CiAgICAgICAgICAgICJyIjogb3MuT19SRE9OTFksCiAgICAgICAgICAgICJ3Ijogb3MuT19XUk9OTFkgfCBvcy5PX0NSRUFUIHwgb3MuT19UUlVOQywKICAgICAgICB9W21vZGVdCiAgICAgICAgaWYgaGFzYXR0cihvcywgIk9fQklOQVJZIik6CiAgICAgICAgICAgIG1vZGUgfD0gb3MuT19CSU5BUlkKICAgICAgICBzZWxmLmZkID0gb3Mub3BlbihuYW1lLCBtb2RlKQoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICBvcy5jbG9zZShzZWxmLmZkKQoKICAgIGRlZiByZWFkKHNlbGYsIHNpemUpOgogICAgICAgIHJldHVybiBvcy5yZWFkKHNlbGYuZmQsIHNpemUpCgogICAgZGVmIHdyaXRlKHNlbGYsIHMpOgogICAgICAgIG9zLndyaXRlKHNlbGYuZmQsIHMpCgpjbGFzcyBfU3RyZWFtOgogICAgIiIiQ2xhc3MgdGhhdCBzZXJ2ZXMgYXMgYW4gYWRhcHRlciBiZXR3ZWVuIFRhckZpbGUgYW5kCiAgICAgICBhIHN0cmVhbS1saWtlIG9iamVjdC4gIFRoZSBzdHJlYW0tbGlrZSBvYmplY3Qgb25seQogICAgICAgbmVlZHMgdG8gaGF2ZSBhIHJlYWQoKSBvciB3cml0ZSgpIG1ldGhvZCBhbmQgaXMgYWNjZXNzZWQKICAgICAgIGJsb2Nrd2lzZS4gIFVzZSBvZiBnemlwIG9yIGJ6aXAyIGNvbXByZXNzaW9uIGlzIHBvc3NpYmxlLgogICAgICAgQSBzdHJlYW0tbGlrZSBvYmplY3QgY291bGQgYmUgZm9yIGV4YW1wbGU6IHN5cy5zdGRpbiwKICAgICAgIHN5cy5zdGRvdXQsIGEgc29ja2V0LCBhIHRhcGUgZGV2aWNlIGV0Yy4KCiAgICAgICBfU3RyZWFtIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgb25seSBpbnRlcm5hbGx5LgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIG1vZGUsIGNvbXB0eXBlLCBmaWxlb2JqLCBidWZzaXplKToKICAgICAgICAiIiJDb25zdHJ1Y3QgYSBfU3RyZWFtIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gVHJ1ZQogICAgICAgIGlmIGZpbGVvYmogaXMgTm9uZToKICAgICAgICAgICAgZmlsZW9iaiA9IF9Mb3dMZXZlbEZpbGUobmFtZSwgbW9kZSkKICAgICAgICAgICAgc2VsZi5fZXh0ZmlsZW9iaiA9IEZhbHNlCgogICAgICAgIGlmIGNvbXB0eXBlID09ICcqJzoKICAgICAgICAgICAgIyBFbmFibGUgdHJhbnNwYXJlbnQgY29tcHJlc3Npb24gZGV0ZWN0aW9uIGZvciB0aGUKICAgICAgICAgICAgIyBzdHJlYW0gaW50ZXJmYWNlCiAgICAgICAgICAgIGZpbGVvYmogPSBfU3RyZWFtUHJveHkoZmlsZW9iaikKICAgICAgICAgICAgY29tcHR5cGUgPSBmaWxlb2JqLmdldGNvbXB0eXBlKCkKCiAgICAgICAgc2VsZi5uYW1lICAgICA9IG5hbWUgb3IgIiIKICAgICAgICBzZWxmLm1vZGUgICAgID0gbW9kZQogICAgICAgIHNlbGYuY29tcHR5cGUgPSBjb21wdHlwZQogICAgICAgIHNlbGYuZmlsZW9iaiAgPSBmaWxlb2JqCiAgICAgICAgc2VsZi5idWZzaXplICA9IGJ1ZnNpemUKICAgICAgICBzZWxmLmJ1ZiAgICAgID0gIiIKICAgICAgICBzZWxmLnBvcyAgICAgID0gMAogICAgICAgIHNlbGYuY2xvc2VkICAgPSBGYWxzZQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiZ3oiOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgemxpYgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJ6bGliIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIikKICAgICAgICAgICAgc2VsZi56bGliID0gemxpYgogICAgICAgICAgICBzZWxmLmNyYyA9IHpsaWIuY3JjMzIoIiIpCiAgICAgICAgICAgIGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICAgICAgc2VsZi5faW5pdF9yZWFkX2d6KCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2luaXRfd3JpdGVfZ3ooKQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiYnoyIjoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaW1wb3J0IGJ6MgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJiejIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQogICAgICAgICAgICBpZiBtb2RlID09ICJyIjoKICAgICAgICAgICAgICAgIHNlbGYuZGJ1ZiA9ICIiCiAgICAgICAgICAgICAgICBzZWxmLmNtcCA9IGJ6Mi5CWjJEZWNvbXByZXNzb3IoKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5jbXAgPSBiejIuQloyQ29tcHJlc3NvcigpCgogICAgZGVmIF9fZGVsX18oc2VsZik6CiAgICAgICAgaWYgaGFzYXR0cihzZWxmLCAiY2xvc2VkIikgYW5kIG5vdCBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgc2VsZi5jbG9zZSgpCgogICAgZGVmIF9pbml0X3dyaXRlX2d6KHNlbGYpOgogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uLgogICAgICAgICIiIgogICAgICAgIHNlbGYuY21wID0gc2VsZi56bGliLmNvbXByZXNzb2JqKDksIHNlbGYuemxpYi5ERUZMQVRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtc2VsZi56bGliLk1BWF9XQklUUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpsaWIuREVGX01FTV9MRVZFTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKQogICAgICAgIHRpbWVzdGFtcCA9IHN0cnVjdC5wYWNrKCI8TCIsIGludCh0aW1lLnRpbWUoKSkpCiAgICAgICAgc2VsZi5fX3dyaXRlKCJcMDM3XDIxM1wwMTBcMDEwJXNcMDAyXDM3NyIgJSB0aW1lc3RhbXApCiAgICAgICAgaWYgc2VsZi5uYW1lLmVuZHN3aXRoKCIuZ3oiKToKICAgICAgICAgICAgc2VsZi5uYW1lID0gc2VsZi5uYW1lWzotM10KICAgICAgICBzZWxmLl9fd3JpdGUoc2VsZi5uYW1lICsgTlVMKQoKICAgIGRlZiB3cml0ZShzZWxmLCBzKToKICAgICAgICAiIiJXcml0ZSBzdHJpbmcgcyB0byB0aGUgc3RyZWFtLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY29tcHR5cGUgPT0gImd6IjoKICAgICAgICAgICAgc2VsZi5jcmMgPSBzZWxmLnpsaWIuY3JjMzIocywgc2VsZi5jcmMpCiAgICAgICAgc2VsZi5wb3MgKz0gbGVuKHMpCiAgICAgICAgaWYgc2VsZi5jb21wdHlwZSAhPSAidGFyIjoKICAgICAgICAgICAgcyA9IHNlbGYuY21wLmNvbXByZXNzKHMpCiAgICAgICAgc2VsZi5fX3dyaXRlKHMpCgogICAgZGVmIF9fd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgIiIiV3JpdGUgc3RyaW5nIHMgdG8gdGhlIHN0cmVhbSBpZiBhIHdob2xlIG5ldyBibG9jawogICAgICAgICAgIGlzIHJlYWR5IHRvIGJlIHdyaXR0ZW4uCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5idWYgKz0gcwogICAgICAgIHdoaWxlIGxlbihzZWxmLmJ1ZikgPiBzZWxmLmJ1ZnNpemU6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzZWxmLmJ1Zls6c2VsZi5idWZzaXplXSkKICAgICAgICAgICAgc2VsZi5idWYgPSBzZWxmLmJ1ZltzZWxmLmJ1ZnNpemU6XQoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICAiIiJDbG9zZSB0aGUgX1N0cmVhbSBvYmplY3QuIE5vIG9wZXJhdGlvbiBzaG91bGQgYmUKICAgICAgICAgICBkb25lIG9uIGl0IGFmdGVyd2FyZHMuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInciIGFuZCBzZWxmLmNvbXB0eXBlICE9ICJ0YXIiOgogICAgICAgICAgICBzZWxmLmJ1ZiArPSBzZWxmLmNtcC5mbHVzaCgpCgogICAgICAgIGlmIHNlbGYubW9kZSA9PSAidyIgYW5kIHNlbGYuYnVmOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWYpCiAgICAgICAgICAgIHNlbGYuYnVmID0gIiIKICAgICAgICAgICAgaWYgc2VsZi5jb21wdHlwZSA9PSAiZ3oiOgogICAgICAgICAgICAgICAgIyBUaGUgbmF0aXZlIHpsaWIgY3JjIGlzIGFuIHVuc2lnbmVkIDMyLWJpdCBpbnRlZ2VyLCBidXQKICAgICAgICAgICAgICAgICMgdGhlIFB5dGhvbiB3cmFwcGVyIGltcGxpY2l0bHkgY2FzdHMgdGhhdCB0byBhIHNpZ25lZCBDCiAgICAgICAgICAgICAgICAjIGxvbmcuICBTbywgb24gYSAzMi1iaXQgYm94IHNlbGYuY3JjIG1heSAibG9vayBuZWdhdGl2ZSIsCiAgICAgICAgICAgICAgICAjIHdoaWxlIHRoZSBzYW1lIGNyYyBvbiBhIDY0LWJpdCBib3ggbWF5ICJsb29rIHBvc2l0aXZlIi4KICAgICAgICAgICAgICAgICMgVG8gYXZvaWQgaXJrc29tZSB3YXJuaW5ncyBmcm9tIHRoZSBgc3RydWN0YCBtb2R1bGUsIGZvcmNlCiAgICAgICAgICAgICAgICAjIGl0IHRvIGxvb2sgcG9zaXRpdmUgb24gYWxsIGJveGVzLgogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHN0cnVjdC5wYWNrKCI8TCIsIHNlbGYuY3JjICYgMHhmZmZmZmZmZikpCiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc3RydWN0LnBhY2soIjxMIiwgc2VsZi5wb3MgJiAweGZmZmZGRkZGKSkKCiAgICAgICAgaWYgbm90IHNlbGYuX2V4dGZpbGVvYmo6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCgogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQoKICAgIGRlZiBfaW5pdF9yZWFkX2d6KHNlbGYpOgogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHJlYWRpbmcgYSBnemlwIGNvbXByZXNzZWQgZmlsZW9iai4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmNtcCA9IHNlbGYuemxpYi5kZWNvbXByZXNzb2JqKC1zZWxmLnpsaWIuTUFYX1dCSVRTKQogICAgICAgIHNlbGYuZGJ1ZiA9ICIiCgogICAgICAgICMgdGFrZW4gZnJvbSBnemlwLkd6aXBGaWxlIHdpdGggc29tZSBhbHRlcmF0aW9ucwogICAgICAgIGlmIHNlbGYuX19yZWFkKDIpICE9ICJcMDM3XDIxMyI6CiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigibm90IGEgZ3ppcCBmaWxlIikKICAgICAgICBpZiBzZWxmLl9fcmVhZCgxKSAhPSAiXDAxMCI6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoInVuc3VwcG9ydGVkIGNvbXByZXNzaW9uIG1ldGhvZCIpCgogICAgICAgIGZsYWcgPSBvcmQoc2VsZi5fX3JlYWQoMSkpCiAgICAgICAgc2VsZi5fX3JlYWQoNikKCiAgICAgICAgaWYgZmxhZyAmIDQ6CiAgICAgICAgICAgIHhsZW4gPSBvcmQoc2VsZi5fX3JlYWQoMSkpICsgMjU2ICogb3JkKHNlbGYuX19yZWFkKDEpKQogICAgICAgICAgICBzZWxmLnJlYWQoeGxlbikKICAgICAgICBpZiBmbGFnICYgODoKICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIHMgPSBzZWxmLl9fcmVhZCgxKQogICAgICAgICAgICAgICAgaWYgbm90IHMgb3IgcyA9PSBOVUw6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBpZiBmbGFnICYgMTY6CiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBzID0gc2VsZi5fX3JlYWQoMSkKICAgICAgICAgICAgICAgIGlmIG5vdCBzIG9yIHMgPT0gTlVMOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgaWYgZmxhZyAmIDI6CiAgICAgICAgICAgIHNlbGYuX19yZWFkKDIpCgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBzdHJlYW0ncyBmaWxlIHBvaW50ZXIgcG9zaXRpb24uCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHNlZWsoc2VsZiwgcG9zPTApOgogICAgICAgICIiIlNldCB0aGUgc3RyZWFtJ3MgZmlsZSBwb2ludGVyIHRvIHBvcy4gTmVnYXRpdmUgc2Vla2luZwogICAgICAgICAgIGlzIGZvcmJpZGRlbi4KICAgICAgICAiIiIKICAgICAgICBpZiBwb3MgLSBzZWxmLnBvcyA+PSAwOgogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChwb3MgLSBzZWxmLnBvcywgc2VsZi5idWZzaXplKQogICAgICAgICAgICBmb3IgaSBpbiByYW5nZShibG9ja3MpOgogICAgICAgICAgICAgICAgc2VsZi5yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgc2VsZi5yZWFkKHJlbWFpbmRlcikKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBTdHJlYW1FcnJvcigic2Vla2luZyBiYWNrd2FyZHMgaXMgbm90IGFsbG93ZWQiKQogICAgICAgIHJldHVybiBzZWxmLnBvcwoKICAgIGRlZiByZWFkKHNlbGYsIHNpemU9Tm9uZSk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IHNpemUgbnVtYmVyIG9mIGJ5dGVzIGZyb20gdGhlIHN0cmVhbS4KICAgICAgICAgICBJZiBzaXplIGlzIG5vdCBkZWZpbmVkLCByZXR1cm4gYWxsIGJ5dGVzIG9mIHRoZSBzdHJlYW0KICAgICAgICAgICB1cCB0byBFT0YuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2l6ZSBpcyBOb25lOgogICAgICAgICAgICB0ID0gW10KICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX3JlYWQoc2VsZi5idWZzaXplKQogICAgICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgdC5hcHBlbmQoYnVmKQogICAgICAgICAgICBidWYgPSAiIi5qb2luKHQpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYnVmID0gc2VsZi5fcmVhZChzaXplKQogICAgICAgIHNlbGYucG9zICs9IGxlbihidWYpCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiBfcmVhZChzZWxmLCBzaXplKToKICAgICAgICAiIiJSZXR1cm4gc2l6ZSBieXRlcyBmcm9tIHRoZSBzdHJlYW0uCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jb21wdHlwZSA9PSAidGFyIjoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX19yZWFkKHNpemUpCgogICAgICAgIGMgPSBsZW4oc2VsZi5kYnVmKQogICAgICAgIHQgPSBbc2VsZi5kYnVmXQogICAgICAgIHdoaWxlIGMgPCBzaXplOgogICAgICAgICAgICBidWYgPSBzZWxmLl9fcmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLmNtcC5kZWNvbXByZXNzKGJ1ZikKICAgICAgICAgICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoImludmFsaWQgY29tcHJlc3NlZCBkYXRhIikKICAgICAgICAgICAgdC5hcHBlbmQoYnVmKQogICAgICAgICAgICBjICs9IGxlbihidWYpCiAgICAgICAgdCA9ICIiLmpvaW4odCkKICAgICAgICBzZWxmLmRidWYgPSB0W3NpemU6XQogICAgICAgIHJldHVybiB0WzpzaXplXQoKICAgIGRlZiBfX3JlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmV0dXJuIHNpemUgYnl0ZXMgZnJvbSBzdHJlYW0uIElmIGludGVybmFsIGJ1ZmZlciBpcyBlbXB0eSwKICAgICAgICAgICByZWFkIGFub3RoZXIgYmxvY2sgZnJvbSB0aGUgc3RyZWFtLgogICAgICAgICIiIgogICAgICAgIGMgPSBsZW4oc2VsZi5idWYpCiAgICAgICAgdCA9IFtzZWxmLmJ1Zl0KICAgICAgICB3aGlsZSBjIDwgc2l6ZToKICAgICAgICAgICAgYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoc2VsZi5idWZzaXplKQogICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgdC5hcHBlbmQoYnVmKQogICAgICAgICAgICBjICs9IGxlbihidWYpCiAgICAgICAgdCA9ICIiLmpvaW4odCkKICAgICAgICBzZWxmLmJ1ZiA9IHRbc2l6ZTpdCiAgICAgICAgcmV0dXJuIHRbOnNpemVdCiMgY2xhc3MgX1N0cmVhbQoKY2xhc3MgX1N0cmVhbVByb3h5KG9iamVjdCk6CiAgICAiIiJTbWFsbCBwcm94eSBjbGFzcyB0aGF0IGVuYWJsZXMgdHJhbnNwYXJlbnQgY29tcHJlc3Npb24KICAgICAgIGRldGVjdGlvbiBmb3IgdGhlIFN0cmVhbSBpbnRlcmZhY2UgKG1vZGUgJ3J8KicpLgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGVvYmopOgogICAgICAgIHNlbGYuZmlsZW9iaiA9IGZpbGVvYmoKICAgICAgICBzZWxmLmJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKCiAgICBkZWYgcmVhZChzZWxmLCBzaXplKToKICAgICAgICBzZWxmLnJlYWQgPSBzZWxmLmZpbGVvYmoucmVhZAogICAgICAgIHJldHVybiBzZWxmLmJ1ZgoKICAgIGRlZiBnZXRjb21wdHlwZShzZWxmKToKICAgICAgICBpZiBzZWxmLmJ1Zi5zdGFydHN3aXRoKCJcMDM3XDIxM1wwMTAiKToKICAgICAgICAgICAgcmV0dXJuICJneiIKICAgICAgICBpZiBzZWxmLmJ1Zi5zdGFydHN3aXRoKCJCWmg5MSIpOgogICAgICAgICAgICByZXR1cm4gImJ6MiIKICAgICAgICByZXR1cm4gInRhciIKCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgc2VsZi5maWxlb2JqLmNsb3NlKCkKIyBjbGFzcyBTdHJlYW1Qcm94eQoKY2xhc3MgX0JaMlByb3h5KG9iamVjdCk6CiAgICAiIiJTbWFsbCBwcm94eSBjbGFzcyB0aGF0IGVuYWJsZXMgZXh0ZXJuYWwgZmlsZSBvYmplY3QKICAgICAgIHN1cHBvcnQgZm9yICJyOmJ6MiIgYW5kICJ3OmJ6MiIgbW9kZXMuIFRoaXMgaXMgYWN0dWFsbHkKICAgICAgIGEgd29ya2Fyb3VuZCBmb3IgYSBsaW1pdGF0aW9uIGluIGJ6MiBtb2R1bGUncyBCWjJGaWxlCiAgICAgICBjbGFzcyB3aGljaCAodW5saWtlIGd6aXAuR3ppcEZpbGUpIGhhcyBubyBzdXBwb3J0IGZvcgogICAgICAgYSBmaWxlIG9iamVjdCBhcmd1bWVudC4KICAgICIiIgoKICAgIGJsb2Nrc2l6ZSA9IDE2ICogMTAyNAoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmaWxlb2JqLCBtb2RlKToKICAgICAgICBzZWxmLmZpbGVvYmogPSBmaWxlb2JqCiAgICAgICAgc2VsZi5tb2RlID0gbW9kZQogICAgICAgIHNlbGYubmFtZSA9IGdldGF0dHIoc2VsZi5maWxlb2JqLCAibmFtZSIsIE5vbmUpCiAgICAgICAgc2VsZi5pbml0KCkKCiAgICBkZWYgaW5pdChzZWxmKToKICAgICAgICBpbXBvcnQgYnoyCiAgICAgICAgc2VsZi5wb3MgPSAwCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJyIjoKICAgICAgICAgICAgc2VsZi5iejJvYmogPSBiejIuQloyRGVjb21wcmVzc29yKCkKICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoMCkKICAgICAgICAgICAgc2VsZi5idWYgPSAiIgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuYnoyb2JqID0gYnoyLkJaMkNvbXByZXNzb3IoKQoKICAgIGRlZiByZWFkKHNlbGYsIHNpemUpOgogICAgICAgIGIgPSBbc2VsZi5idWZdCiAgICAgICAgeCA9IGxlbihzZWxmLmJ1ZikKICAgICAgICB3aGlsZSB4IDwgc2l6ZToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgcmF3ID0gc2VsZi5maWxlb2JqLnJlYWQoc2VsZi5ibG9ja3NpemUpCiAgICAgICAgICAgICAgICBkYXRhID0gc2VsZi5iejJvYmouZGVjb21wcmVzcyhyYXcpCiAgICAgICAgICAgICAgICBiLmFwcGVuZChkYXRhKQogICAgICAgICAgICBleGNlcHQgRU9GRXJyb3I6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICB4ICs9IGxlbihkYXRhKQogICAgICAgIHNlbGYuYnVmID0gIiIuam9pbihiKQoKICAgICAgICBidWYgPSBzZWxmLmJ1Zls6c2l6ZV0KICAgICAgICBzZWxmLmJ1ZiA9IHNlbGYuYnVmW3NpemU6XQogICAgICAgIHNlbGYucG9zICs9IGxlbihidWYpCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiBzZWVrKHNlbGYsIHBvcyk6CiAgICAgICAgaWYgcG9zIDwgc2VsZi5wb3M6CiAgICAgICAgICAgIHNlbGYuaW5pdCgpCiAgICAgICAgc2VsZi5yZWFkKHBvcyAtIHNlbGYucG9zKQoKICAgIGRlZiB0ZWxsKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnBvcwoKICAgIGRlZiB3cml0ZShzZWxmLCBkYXRhKToKICAgICAgICBzZWxmLnBvcyArPSBsZW4oZGF0YSkKICAgICAgICByYXcgPSBzZWxmLmJ6Mm9iai5jb21wcmVzcyhkYXRhKQogICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShyYXcpCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIGlmIHNlbGYubW9kZSA9PSAidyI6CiAgICAgICAgICAgIHJhdyA9IHNlbGYuYnoyb2JqLmZsdXNoKCkKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHJhdykKICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQojIGNsYXNzIF9CWjJQcm94eQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEV4dHJhY3Rpb24gZmlsZSBvYmplY3QKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBfRmlsZUluRmlsZShvYmplY3QpOgogICAgIiIiQSB0aGluIHdyYXBwZXIgYXJvdW5kIGFuIGV4aXN0aW5nIGZpbGUgb2JqZWN0IHRoYXQKICAgICAgIHByb3ZpZGVzIGEgcGFydCBvZiBpdHMgZGF0YSBhcyBhbiBpbmRpdmlkdWFsIGZpbGUKICAgICAgIG9iamVjdC4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmaWxlb2JqLCBvZmZzZXQsIHNpemUsIHNwYXJzZT1Ob25lKToKICAgICAgICBzZWxmLmZpbGVvYmogPSBmaWxlb2JqCiAgICAgICAgc2VsZi5vZmZzZXQgPSBvZmZzZXQKICAgICAgICBzZWxmLnNpemUgPSBzaXplCiAgICAgICAgc2VsZi5zcGFyc2UgPSBzcGFyc2UKICAgICAgICBzZWxmLnBvc2l0aW9uID0gMAoKICAgIGRlZiB0ZWxsKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgY3VycmVudCBmaWxlIHBvc2l0aW9uLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBzZWxmLnBvc2l0aW9uCgogICAgZGVmIHNlZWsoc2VsZiwgcG9zaXRpb24pOgogICAgICAgICIiIlNlZWsgdG8gYSBwb3NpdGlvbiBpbiB0aGUgZmlsZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLnBvc2l0aW9uID0gcG9zaXRpb24KCiAgICBkZWYgcmVhZChzZWxmLCBzaXplPU5vbmUpOgogICAgICAgICIiIlJlYWQgZGF0YSBmcm9tIHRoZSBmaWxlLgogICAgICAgICIiIgogICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgc2l6ZSA9IHNlbGYuc2l6ZSAtIHNlbGYucG9zaXRpb24KICAgICAgICBlbHNlOgogICAgICAgICAgICBzaXplID0gbWluKHNpemUsIHNlbGYuc2l6ZSAtIHNlbGYucG9zaXRpb24pCgogICAgICAgIGlmIHNlbGYuc3BhcnNlIGlzIE5vbmU6CiAgICAgICAgICAgIHJldHVybiBzZWxmLnJlYWRub3JtYWwoc2l6ZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gc2VsZi5yZWFkc3BhcnNlKHNpemUpCgogICAgZGVmIHJlYWRub3JtYWwoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmVhZCBvcGVyYXRpb24gZm9yIHJlZ3VsYXIgZmlsZXMuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5vZmZzZXQgKyBzZWxmLnBvc2l0aW9uKQogICAgICAgIHNlbGYucG9zaXRpb24gKz0gc2l6ZQogICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmoucmVhZChzaXplKQoKICAgIGRlZiByZWFkc3BhcnNlKHNlbGYsIHNpemUpOgogICAgICAgICIiIlJlYWQgb3BlcmF0aW9uIGZvciBzcGFyc2UgZmlsZXMuCiAgICAgICAgIiIiCiAgICAgICAgZGF0YSA9IFtdCiAgICAgICAgd2hpbGUgc2l6ZSA+IDA6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYucmVhZHNwYXJzZXNlY3Rpb24oc2l6ZSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHNpemUgLT0gbGVuKGJ1ZikKICAgICAgICAgICAgZGF0YS5hcHBlbmQoYnVmKQogICAgICAgIHJldHVybiAiIi5qb2luKGRhdGEpCgogICAgZGVmIHJlYWRzcGFyc2VzZWN0aW9uKHNlbGYsIHNpemUpOgogICAgICAgICIiIlJlYWQgYSBzaW5nbGUgc2VjdGlvbiBvZiBhIHNwYXJzZSBmaWxlLgogICAgICAgICIiIgogICAgICAgIHNlY3Rpb24gPSBzZWxmLnNwYXJzZS5maW5kKHNlbGYucG9zaXRpb24pCgogICAgICAgIGlmIHNlY3Rpb24gaXMgTm9uZToKICAgICAgICAgICAgcmV0dXJuICIiCgogICAgICAgIHNpemUgPSBtaW4oc2l6ZSwgc2VjdGlvbi5vZmZzZXQgKyBzZWN0aW9uLnNpemUgLSBzZWxmLnBvc2l0aW9uKQoKICAgICAgICBpZiBpc2luc3RhbmNlKHNlY3Rpb24sIF9kYXRhKToKICAgICAgICAgICAgcmVhbHBvcyA9IHNlY3Rpb24ucmVhbHBvcyArIHNlbGYucG9zaXRpb24gLSBzZWN0aW9uLm9mZnNldAogICAgICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCArIHJlYWxwb3MpCiAgICAgICAgICAgIHNlbGYucG9zaXRpb24gKz0gc2l6ZQogICAgICAgICAgICByZXR1cm4gc2VsZi5maWxlb2JqLnJlYWQoc2l6ZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLnBvc2l0aW9uICs9IHNpemUKICAgICAgICAgICAgcmV0dXJuIE5VTCAqIHNpemUKI2NsYXNzIF9GaWxlSW5GaWxlCgoKY2xhc3MgRXhGaWxlT2JqZWN0KG9iamVjdCk6CiAgICAiIiJGaWxlLWxpa2Ugb2JqZWN0IGZvciByZWFkaW5nIGFuIGFyY2hpdmUgbWVtYmVyLgogICAgICAgSXMgcmV0dXJuZWQgYnkgVGFyRmlsZS5leHRyYWN0ZmlsZSgpLgogICAgIiIiCiAgICBibG9ja3NpemUgPSAxMDI0CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIHRhcmZpbGUsIHRhcmluZm8pOgogICAgICAgIHNlbGYuZmlsZW9iaiA9IF9GaWxlSW5GaWxlKHRhcmZpbGUuZmlsZW9iaiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvLm9mZnNldF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmluZm8uc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRhdHRyKHRhcmluZm8sICJzcGFyc2UiLCBOb25lKSkKICAgICAgICBzZWxmLm5hbWUgPSB0YXJpbmZvLm5hbWUKICAgICAgICBzZWxmLm1vZGUgPSAiciIKICAgICAgICBzZWxmLmNsb3NlZCA9IEZhbHNlCiAgICAgICAgc2VsZi5zaXplID0gdGFyaW5mby5zaXplCgogICAgICAgIHNlbGYucG9zaXRpb24gPSAwCiAgICAgICAgc2VsZi5idWZmZXIgPSAiIgoKICAgIGRlZiByZWFkKHNlbGYsIHNpemU9Tm9uZSk6CiAgICAgICAgIiIiUmVhZCBhdCBtb3N0IHNpemUgYnl0ZXMgZnJvbSB0aGUgZmlsZS4gSWYgc2l6ZSBpcyBub3QKICAgICAgICAgICBwcmVzZW50IG9yIE5vbmUsIHJlYWQgYWxsIGRhdGEgdW50aWwgRU9GIGlzIHJlYWNoZWQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkkvTyBvcGVyYXRpb24gb24gY2xvc2VkIGZpbGUiKQoKICAgICAgICBidWYgPSAiIgogICAgICAgIGlmIHNlbGYuYnVmZmVyOgogICAgICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLmJ1ZmZlcgogICAgICAgICAgICAgICAgc2VsZi5idWZmZXIgPSAiIgogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5idWZmZXJbOnNpemVdCiAgICAgICAgICAgICAgICBzZWxmLmJ1ZmZlciA9IHNlbGYuYnVmZmVyW3NpemU6XQoKICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgIGJ1ZiArPSBzZWxmLmZpbGVvYmoucmVhZCgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYnVmICs9IHNlbGYuZmlsZW9iai5yZWFkKHNpemUgLSBsZW4oYnVmKSkKCiAgICAgICAgc2VsZi5wb3NpdGlvbiArPSBsZW4oYnVmKQogICAgICAgIHJldHVybiBidWYKCiAgICBkZWYgcmVhZGxpbmUoc2VsZiwgc2l6ZT0tMSk6CiAgICAgICAgIiIiUmVhZCBvbmUgZW50aXJlIGxpbmUgZnJvbSB0aGUgZmlsZS4gSWYgc2l6ZSBpcyBwcmVzZW50CiAgICAgICAgICAgYW5kIG5vbi1uZWdhdGl2ZSwgcmV0dXJuIGEgc3RyaW5nIHdpdGggYXQgbW9zdCB0aGF0CiAgICAgICAgICAgc2l6ZSwgd2hpY2ggbWF5IGJlIGFuIGluY29tcGxldGUgbGluZS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiSS9PIG9wZXJhdGlvbiBvbiBjbG9zZWQgZmlsZSIpCgogICAgICAgIGlmICJcbiIgaW4gc2VsZi5idWZmZXI6CiAgICAgICAgICAgIHBvcyA9IHNlbGYuYnVmZmVyLmZpbmQoIlxuIikgKyAxCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYnVmZmVycyA9IFtzZWxmLmJ1ZmZlcl0KICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKHNlbGYuYmxvY2tzaXplKQogICAgICAgICAgICAgICAgYnVmZmVycy5hcHBlbmQoYnVmKQogICAgICAgICAgICAgICAgaWYgbm90IGJ1ZiBvciAiXG4iIGluIGJ1ZjoKICAgICAgICAgICAgICAgICAgICBzZWxmLmJ1ZmZlciA9ICIiLmpvaW4oYnVmZmVycykKICAgICAgICAgICAgICAgICAgICBwb3MgPSBzZWxmLmJ1ZmZlci5maW5kKCJcbiIpICsgMQogICAgICAgICAgICAgICAgICAgIGlmIHBvcyA9PSAwOgogICAgICAgICAgICAgICAgICAgICAgICAjIG5vIG5ld2xpbmUgZm91bmQuCiAgICAgICAgICAgICAgICAgICAgICAgIHBvcyA9IGxlbihzZWxmLmJ1ZmZlcikKICAgICAgICAgICAgICAgICAgICBicmVhawoKICAgICAgICBpZiBzaXplICE9IC0xOgogICAgICAgICAgICBwb3MgPSBtaW4oc2l6ZSwgcG9zKQoKICAgICAgICBidWYgPSBzZWxmLmJ1ZmZlcls6cG9zXQogICAgICAgIHNlbGYuYnVmZmVyID0gc2VsZi5idWZmZXJbcG9zOl0KICAgICAgICBzZWxmLnBvc2l0aW9uICs9IGxlbihidWYpCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiByZWFkbGluZXMoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIGEgbGlzdCB3aXRoIGFsbCByZW1haW5pbmcgbGluZXMuCiAgICAgICAgIiIiCiAgICAgICAgcmVzdWx0ID0gW10KICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBsaW5lID0gc2VsZi5yZWFkbGluZSgpCiAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgICAgICByZXN1bHQuYXBwZW5kKGxpbmUpCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiB0ZWxsKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgY3VycmVudCBmaWxlIHBvc2l0aW9uLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJJL08gb3BlcmF0aW9uIG9uIGNsb3NlZCBmaWxlIikKCiAgICAgICAgcmV0dXJuIHNlbGYucG9zaXRpb24KCiAgICBkZWYgc2VlayhzZWxmLCBwb3MsIHdoZW5jZT1vcy5TRUVLX1NFVCk6CiAgICAgICAgIiIiU2VlayB0byBhIHBvc2l0aW9uIGluIHRoZSBmaWxlLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJJL08gb3BlcmF0aW9uIG9uIGNsb3NlZCBmaWxlIikKCiAgICAgICAgaWYgd2hlbmNlID09IG9zLlNFRUtfU0VUOgogICAgICAgICAgICBzZWxmLnBvc2l0aW9uID0gbWluKG1heChwb3MsIDApLCBzZWxmLnNpemUpCiAgICAgICAgZWxpZiB3aGVuY2UgPT0gb3MuU0VFS19DVVI6CiAgICAgICAgICAgIGlmIHBvcyA8IDA6CiAgICAgICAgICAgICAgICBzZWxmLnBvc2l0aW9uID0gbWF4KHNlbGYucG9zaXRpb24gKyBwb3MsIDApCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLnBvc2l0aW9uID0gbWluKHNlbGYucG9zaXRpb24gKyBwb3MsIHNlbGYuc2l6ZSkKICAgICAgICBlbGlmIHdoZW5jZSA9PSBvcy5TRUVLX0VORDoKICAgICAgICAgICAgc2VsZi5wb3NpdGlvbiA9IG1heChtaW4oc2VsZi5zaXplICsgcG9zLCBzZWxmLnNpemUpLCAwKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkludmFsaWQgYXJndW1lbnQiKQoKICAgICAgICBzZWxmLmJ1ZmZlciA9ICIiCiAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5wb3NpdGlvbikKCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIGZpbGUgb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQoKICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKICAgICAgICAiIiJHZXQgYW4gaXRlcmF0b3Igb3ZlciB0aGUgZmlsZSdzIGxpbmVzLgogICAgICAgICIiIgogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGxpbmUgPSBzZWxmLnJlYWRsaW5lKCkKICAgICAgICAgICAgaWYgbm90IGxpbmU6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICB5aWVsZCBsaW5lCiNjbGFzcyBFeEZpbGVPYmplY3QKCiMtLS0tLS0tLS0tLS0tLS0tLS0KIyBFeHBvcnRlZCBDbGFzc2VzCiMtLS0tLS0tLS0tLS0tLS0tLS0KY2xhc3MgVGFySW5mbyhvYmplY3QpOgogICAgIiIiSW5mb3JtYXRpb25hbCBjbGFzcyB3aGljaCBob2xkcyB0aGUgZGV0YWlscyBhYm91dCBhbgogICAgICAgYXJjaGl2ZSBtZW1iZXIgZ2l2ZW4gYnkgYSB0YXIgaGVhZGVyIGJsb2NrLgogICAgICAgVGFySW5mbyBvYmplY3RzIGFyZSByZXR1cm5lZCBieSBUYXJGaWxlLmdldG1lbWJlcigpLAogICAgICAgVGFyRmlsZS5nZXRtZW1iZXJzKCkgYW5kIFRhckZpbGUuZ2V0dGFyaW5mbygpIGFuZCBhcmUKICAgICAgIHVzdWFsbHkgY3JlYXRlZCBpbnRlcm5hbGx5LgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWU9IiIpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIFRhckluZm8gb2JqZWN0LiBuYW1lIGlzIHRoZSBvcHRpb25hbCBuYW1lCiAgICAgICAgICAgb2YgdGhlIG1lbWJlci4KICAgICAgICAiIiIKICAgICAgICBzZWxmLm5hbWUgPSBuYW1lICAgICAgICAjIG1lbWJlciBuYW1lCiAgICAgICAgc2VsZi5tb2RlID0gMG82NDQgICAgICAgIyBmaWxlIHBlcm1pc3Npb25zCiAgICAgICAgc2VsZi51aWQgPSAwICAgICAgICAgICAgIyB1c2VyIGlkCiAgICAgICAgc2VsZi5naWQgPSAwICAgICAgICAgICAgIyBncm91cCBpZAogICAgICAgIHNlbGYuc2l6ZSA9IDAgICAgICAgICAgICMgZmlsZSBzaXplCiAgICAgICAgc2VsZi5tdGltZSA9IDAgICAgICAgICAgIyBtb2RpZmljYXRpb24gdGltZQogICAgICAgIHNlbGYuY2hrc3VtID0gMCAgICAgICAgICMgaGVhZGVyIGNoZWNrc3VtCiAgICAgICAgc2VsZi50eXBlID0gUkVHVFlQRSAgICAgIyBtZW1iZXIgdHlwZQogICAgICAgIHNlbGYubGlua25hbWUgPSAiIiAgICAgICMgbGluayBuYW1lCiAgICAgICAgc2VsZi51bmFtZSA9ICJyb290IiAgICAgIyB1c2VyIG5hbWUKICAgICAgICBzZWxmLmduYW1lID0gInJvb3QiICAgICAjIGdyb3VwIG5hbWUKICAgICAgICBzZWxmLmRldm1ham9yID0gMCAgICAgICAjIGRldmljZSBtYWpvciBudW1iZXIKICAgICAgICBzZWxmLmRldm1pbm9yID0gMCAgICAgICAjIGRldmljZSBtaW5vciBudW1iZXIKCiAgICAgICAgc2VsZi5vZmZzZXQgPSAwICAgICAgICAgIyB0aGUgdGFyIGhlYWRlciBzdGFydHMgaGVyZQogICAgICAgIHNlbGYub2Zmc2V0X2RhdGEgPSAwICAgICMgdGhlIGZpbGUncyBkYXRhIHN0YXJ0cyBoZXJlCgogICAgICAgIHNlbGYucGF4X2hlYWRlcnMgPSB7fSAgICMgcGF4IGhlYWRlciBpbmZvcm1hdGlvbgoKICAgICMgSW4gcGF4IGhlYWRlcnMgdGhlICJuYW1lIiBhbmQgImxpbmtuYW1lIiBmaWVsZCBhcmUgY2FsbGVkCiAgICAjICJwYXRoIiBhbmQgImxpbmtwYXRoIi4KICAgIGRlZiBfZ2V0cGF0aChzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5uYW1lCiAgICBkZWYgX3NldHBhdGgoc2VsZiwgbmFtZSk6CiAgICAgICAgc2VsZi5uYW1lID0gbmFtZQogICAgcGF0aCA9IHByb3BlcnR5KF9nZXRwYXRoLCBfc2V0cGF0aCkKCiAgICBkZWYgX2dldGxpbmtwYXRoKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLmxpbmtuYW1lCiAgICBkZWYgX3NldGxpbmtwYXRoKHNlbGYsIGxpbmtuYW1lKToKICAgICAgICBzZWxmLmxpbmtuYW1lID0gbGlua25hbWUKICAgIGxpbmtwYXRoID0gcHJvcGVydHkoX2dldGxpbmtwYXRoLCBfc2V0bGlua3BhdGgpCgogICAgZGVmIF9fcmVwcl9fKHNlbGYpOgogICAgICAgIHJldHVybiAiPCVzICVyIGF0ICUjeD4iICUgKHNlbGYuX19jbGFzc19fLl9fbmFtZV9fLHNlbGYubmFtZSxpZChzZWxmKSkKCiAgICBkZWYgZ2V0X2luZm8oc2VsZiwgZW5jb2RpbmcsIGVycm9ycyk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBUYXJJbmZvJ3MgYXR0cmlidXRlcyBhcyBhIGRpY3Rpb25hcnkuCiAgICAgICAgIiIiCiAgICAgICAgaW5mbyA9IHsKICAgICAgICAgICAgIm5hbWUiOiAgICAgbm9ybXBhdGgoc2VsZi5uYW1lKSwKICAgICAgICAgICAgIm1vZGUiOiAgICAgc2VsZi5tb2RlICYgMG83Nzc3LAogICAgICAgICAgICAidWlkIjogICAgICBzZWxmLnVpZCwKICAgICAgICAgICAgImdpZCI6ICAgICAgc2VsZi5naWQsCiAgICAgICAgICAgICJzaXplIjogICAgIHNlbGYuc2l6ZSwKICAgICAgICAgICAgIm10aW1lIjogICAgc2VsZi5tdGltZSwKICAgICAgICAgICAgImNoa3N1bSI6ICAgc2VsZi5jaGtzdW0sCiAgICAgICAgICAgICJ0eXBlIjogICAgIHNlbGYudHlwZSwKICAgICAgICAgICAgImxpbmtuYW1lIjogbm9ybXBhdGgoc2VsZi5saW5rbmFtZSkgaWYgc2VsZi5saW5rbmFtZSBlbHNlICIiLAogICAgICAgICAgICAidW5hbWUiOiAgICBzZWxmLnVuYW1lLAogICAgICAgICAgICAiZ25hbWUiOiAgICBzZWxmLmduYW1lLAogICAgICAgICAgICAiZGV2bWFqb3IiOiBzZWxmLmRldm1ham9yLAogICAgICAgICAgICAiZGV2bWlub3IiOiBzZWxmLmRldm1pbm9yCiAgICAgICAgfQoKICAgICAgICBpZiBpbmZvWyJ0eXBlIl0gPT0gRElSVFlQRSBhbmQgbm90IGluZm9bIm5hbWUiXS5lbmRzd2l0aCgiLyIpOgogICAgICAgICAgICBpbmZvWyJuYW1lIl0gKz0gIi8iCgogICAgICAgIGZvciBrZXkgaW4gKCJuYW1lIiwgImxpbmtuYW1lIiwgInVuYW1lIiwgImduYW1lIik6CiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UoaW5mb1trZXldLCBzdHIpOgogICAgICAgICAgICAgICAgaW5mb1trZXldID0gaW5mb1trZXldLmVuY29kZShlbmNvZGluZywgZXJyb3JzKQoKICAgICAgICByZXR1cm4gaW5mbwoKICAgIGRlZiB0b2J1ZihzZWxmLCBmb3JtYXQ9REVGQVVMVF9GT1JNQVQsIGVuY29kaW5nPUVOQ09ESU5HLCBlcnJvcnM9InN0cmljdCIpOgogICAgICAgICIiIlJldHVybiBhIHRhciBoZWFkZXIgYXMgYSBzdHJpbmcgb2YgNTEyIGJ5dGUgYmxvY2tzLgogICAgICAgICIiIgogICAgICAgIGluZm8gPSBzZWxmLmdldF9pbmZvKGVuY29kaW5nLCBlcnJvcnMpCgogICAgICAgIGlmIGZvcm1hdCA9PSBVU1RBUl9GT1JNQVQ6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmNyZWF0ZV91c3Rhcl9oZWFkZXIoaW5mbykKICAgICAgICBlbGlmIGZvcm1hdCA9PSBHTlVfRk9STUFUOgogICAgICAgICAgICByZXR1cm4gc2VsZi5jcmVhdGVfZ251X2hlYWRlcihpbmZvKQogICAgICAgIGVsaWYgZm9ybWF0ID09IFBBWF9GT1JNQVQ6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmNyZWF0ZV9wYXhfaGVhZGVyKGluZm8sIGVuY29kaW5nLCBlcnJvcnMpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiaW52YWxpZCBmb3JtYXQiKQoKICAgIGRlZiBjcmVhdGVfdXN0YXJfaGVhZGVyKHNlbGYsIGluZm8pOgogICAgICAgICIiIlJldHVybiB0aGUgb2JqZWN0IGFzIGEgdXN0YXIgaGVhZGVyIGJsb2NrLgogICAgICAgICIiIgogICAgICAgIGluZm9bIm1hZ2ljIl0gPSBQT1NJWF9NQUdJQwoKICAgICAgICBpZiBsZW4oaW5mb1sibGlua25hbWUiXSkgPiBMRU5HVEhfTElOSzoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibGlua25hbWUgaXMgdG9vIGxvbmciKQoKICAgICAgICBpZiBsZW4oaW5mb1sibmFtZSJdKSA+IExFTkdUSF9OQU1FOgogICAgICAgICAgICBpbmZvWyJwcmVmaXgiXSwgaW5mb1sibmFtZSJdID0gc2VsZi5fcG9zaXhfc3BsaXRfbmFtZShpbmZvWyJuYW1lIl0pCgogICAgICAgIHJldHVybiBzZWxmLl9jcmVhdGVfaGVhZGVyKGluZm8sIFVTVEFSX0ZPUk1BVCkKCiAgICBkZWYgY3JlYXRlX2dudV9oZWFkZXIoc2VsZiwgaW5mbyk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBvYmplY3QgYXMgYSBHTlUgaGVhZGVyIGJsb2NrIHNlcXVlbmNlLgogICAgICAgICIiIgogICAgICAgIGluZm9bIm1hZ2ljIl0gPSBHTlVfTUFHSUMKCiAgICAgICAgYnVmID0gIiIKICAgICAgICBpZiBsZW4oaW5mb1sibGlua25hbWUiXSkgPiBMRU5HVEhfTElOSzoKICAgICAgICAgICAgYnVmICs9IHNlbGYuX2NyZWF0ZV9nbnVfbG9uZ19oZWFkZXIoaW5mb1sibGlua25hbWUiXSwgR05VVFlQRV9MT05HTElOSykKCiAgICAgICAgaWYgbGVuKGluZm9bIm5hbWUiXSkgPiBMRU5HVEhfTkFNRToKICAgICAgICAgICAgYnVmICs9IHNlbGYuX2NyZWF0ZV9nbnVfbG9uZ19oZWFkZXIoaW5mb1sibmFtZSJdLCBHTlVUWVBFX0xPTkdOQU1FKQoKICAgICAgICByZXR1cm4gYnVmICsgc2VsZi5fY3JlYXRlX2hlYWRlcihpbmZvLCBHTlVfRk9STUFUKQoKICAgIGRlZiBjcmVhdGVfcGF4X2hlYWRlcihzZWxmLCBpbmZvLCBlbmNvZGluZywgZXJyb3JzKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG9iamVjdCBhcyBhIHVzdGFyIGhlYWRlciBibG9jay4gSWYgaXQgY2Fubm90IGJlCiAgICAgICAgICAgcmVwcmVzZW50ZWQgdGhpcyB3YXksIHByZXBlbmQgYSBwYXggZXh0ZW5kZWQgaGVhZGVyIHNlcXVlbmNlCiAgICAgICAgICAgd2l0aCBzdXBwbGVtZW50IGluZm9ybWF0aW9uLgogICAgICAgICIiIgogICAgICAgIGluZm9bIm1hZ2ljIl0gPSBQT1NJWF9NQUdJQwogICAgICAgIHBheF9oZWFkZXJzID0gc2VsZi5wYXhfaGVhZGVycy5jb3B5KCkKCiAgICAgICAgIyBUZXN0IHN0cmluZyBmaWVsZHMgZm9yIHZhbHVlcyB0aGF0IGV4Y2VlZCB0aGUgZmllbGQgbGVuZ3RoIG9yIGNhbm5vdAogICAgICAgICMgYmUgcmVwcmVzZW50ZWQgaW4gQVNDSUkgZW5jb2RpbmcuCiAgICAgICAgZm9yIG5hbWUsIGhuYW1lLCBsZW5ndGggaW4gKAogICAgICAgICAgICAgICAgKCJuYW1lIiwgInBhdGgiLCBMRU5HVEhfTkFNRSksICgibGlua25hbWUiLCAibGlua3BhdGgiLCBMRU5HVEhfTElOSyksCiAgICAgICAgICAgICAgICAoInVuYW1lIiwgInVuYW1lIiwgMzIpLCAoImduYW1lIiwgImduYW1lIiwgMzIpKToKCiAgICAgICAgICAgIGlmIGhuYW1lIGluIHBheF9oZWFkZXJzOgogICAgICAgICAgICAgICAgIyBUaGUgcGF4IGhlYWRlciBoYXMgcHJpb3JpdHkuCiAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgdmFsID0gaW5mb1tuYW1lXS5kZWNvZGUoZW5jb2RpbmcsIGVycm9ycykKCiAgICAgICAgICAgICMgVHJ5IHRvIGVuY29kZSB0aGUgc3RyaW5nIGFzIEFTQ0lJLgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB2YWwuZW5jb2RlKCJhc2NpaSIpCiAgICAgICAgICAgIGV4Y2VwdCBVbmljb2RlRW5jb2RlRXJyb3I6CiAgICAgICAgICAgICAgICBwYXhfaGVhZGVyc1tobmFtZV0gPSB2YWwKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICBpZiBsZW4oaW5mb1tuYW1lXSkgPiBsZW5ndGg6CiAgICAgICAgICAgICAgICBwYXhfaGVhZGVyc1tobmFtZV0gPSB2YWwKCiAgICAgICAgIyBUZXN0IG51bWJlciBmaWVsZHMgZm9yIHZhbHVlcyB0aGF0IGV4Y2VlZCB0aGUgZmllbGQgbGltaXQgb3IgdmFsdWVzCiAgICAgICAgIyB0aGF0IGxpa2UgdG8gYmUgc3RvcmVkIGFzIGZsb2F0LgogICAgICAgIGZvciBuYW1lLCBkaWdpdHMgaW4gKCgidWlkIiwgOCksICgiZ2lkIiwgOCksICgic2l6ZSIsIDEyKSwgKCJtdGltZSIsIDEyKSk6CiAgICAgICAgICAgIGlmIG5hbWUgaW4gcGF4X2hlYWRlcnM6CiAgICAgICAgICAgICAgICAjIFRoZSBwYXggaGVhZGVyIGhhcyBwcmlvcml0eS4gQXZvaWQgb3ZlcmZsb3cuCiAgICAgICAgICAgICAgICBpbmZvW25hbWVdID0gMAogICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgIHZhbCA9IGluZm9bbmFtZV0KICAgICAgICAgICAgaWYgbm90IDAgPD0gdmFsIDwgOCAqKiAoZGlnaXRzIC0gMSkgb3IgaXNpbnN0YW5jZSh2YWwsIGZsb2F0KToKICAgICAgICAgICAgICAgIHBheF9oZWFkZXJzW25hbWVdID0gc3RyKHZhbCkKICAgICAgICAgICAgICAgIGluZm9bbmFtZV0gPSAwCgogICAgICAgICMgQ3JlYXRlIGEgcGF4IGV4dGVuZGVkIGhlYWRlciBpZiBuZWNlc3NhcnkuCiAgICAgICAgaWYgcGF4X2hlYWRlcnM6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX2NyZWF0ZV9wYXhfZ2VuZXJpY19oZWFkZXIocGF4X2hlYWRlcnMpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYnVmID0gIiIKCiAgICAgICAgcmV0dXJuIGJ1ZiArIHNlbGYuX2NyZWF0ZV9oZWFkZXIoaW5mbywgVVNUQVJfRk9STUFUKQoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIGNyZWF0ZV9wYXhfZ2xvYmFsX2hlYWRlcihjbHMsIHBheF9oZWFkZXJzKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG9iamVjdCBhcyBhIHBheCBnbG9iYWwgaGVhZGVyIGJsb2NrIHNlcXVlbmNlLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBjbHMuX2NyZWF0ZV9wYXhfZ2VuZXJpY19oZWFkZXIocGF4X2hlYWRlcnMsIHR5cGU9WEdMVFlQRSkKCiAgICBkZWYgX3Bvc2l4X3NwbGl0X25hbWUoc2VsZiwgbmFtZSk6CiAgICAgICAgIiIiU3BsaXQgYSBuYW1lIGxvbmdlciB0aGFuIDEwMCBjaGFycyBpbnRvIGEgcHJlZml4CiAgICAgICAgICAgYW5kIGEgbmFtZSBwYXJ0LgogICAgICAgICIiIgogICAgICAgIHByZWZpeCA9IG5hbWVbOkxFTkdUSF9QUkVGSVggKyAxXQogICAgICAgIHdoaWxlIHByZWZpeCBhbmQgcHJlZml4Wy0xXSAhPSAiLyI6CiAgICAgICAgICAgIHByZWZpeCA9IHByZWZpeFs6LTFdCgogICAgICAgIG5hbWUgPSBuYW1lW2xlbihwcmVmaXgpOl0KICAgICAgICBwcmVmaXggPSBwcmVmaXhbOi0xXQoKICAgICAgICBpZiBub3QgcHJlZml4IG9yIGxlbihuYW1lKSA+IExFTkdUSF9OQU1FOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJuYW1lIGlzIHRvbyBsb25nIikKICAgICAgICByZXR1cm4gcHJlZml4LCBuYW1lCgogICAgQHN0YXRpY21ldGhvZAogICAgZGVmIF9jcmVhdGVfaGVhZGVyKGluZm8sIGZvcm1hdCk6CiAgICAgICAgIiIiUmV0dXJuIGEgaGVhZGVyIGJsb2NrLiBpbmZvIGlzIGEgZGljdGlvbmFyeSB3aXRoIGZpbGUKICAgICAgICAgICBpbmZvcm1hdGlvbiwgZm9ybWF0IG11c3QgYmUgb25lIG9mIHRoZSAqX0ZPUk1BVCBjb25zdGFudHMuCiAgICAgICAgIiIiCiAgICAgICAgcGFydHMgPSBbCiAgICAgICAgICAgIHN0bihpbmZvLmdldCgibmFtZSIsICIiKSwgMTAwKSwKICAgICAgICAgICAgaXRuKGluZm8uZ2V0KCJtb2RlIiwgMCkgJiAwbzc3NzcsIDgsIGZvcm1hdCksCiAgICAgICAgICAgIGl0bihpbmZvLmdldCgidWlkIiwgMCksIDgsIGZvcm1hdCksCiAgICAgICAgICAgIGl0bihpbmZvLmdldCgiZ2lkIiwgMCksIDgsIGZvcm1hdCksCiAgICAgICAgICAgIGl0bihpbmZvLmdldCgic2l6ZSIsIDApLCAxMiwgZm9ybWF0KSwKICAgICAgICAgICAgaXRuKGluZm8uZ2V0KCJtdGltZSIsIDApLCAxMiwgZm9ybWF0KSwKICAgICAgICAgICAgIiAgICAgICAgIiwgIyBjaGVja3N1bSBmaWVsZAogICAgICAgICAgICBpbmZvLmdldCgidHlwZSIsIFJFR1RZUEUpLAogICAgICAgICAgICBzdG4oaW5mby5nZXQoImxpbmtuYW1lIiwgIiIpLCAxMDApLAogICAgICAgICAgICBzdG4oaW5mby5nZXQoIm1hZ2ljIiwgUE9TSVhfTUFHSUMpLCA4KSwKICAgICAgICAgICAgc3RuKGluZm8uZ2V0KCJ1bmFtZSIsICJyb290IiksIDMyKSwKICAgICAgICAgICAgc3RuKGluZm8uZ2V0KCJnbmFtZSIsICJyb290IiksIDMyKSwKICAgICAgICAgICAgaXRuKGluZm8uZ2V0KCJkZXZtYWpvciIsIDApLCA4LCBmb3JtYXQpLAogICAgICAgICAgICBpdG4oaW5mby5nZXQoImRldm1pbm9yIiwgMCksIDgsIGZvcm1hdCksCiAgICAgICAgICAgIHN0bihpbmZvLmdldCgicHJlZml4IiwgIiIpLCAxNTUpCiAgICAgICAgXQoKICAgICAgICBidWYgPSBzdHJ1Y3QucGFjaygiJWRzIiAlIEJMT0NLU0laRSwgIiIuam9pbihwYXJ0cykpCiAgICAgICAgY2hrc3VtID0gY2FsY19jaGtzdW1zKGJ1ZlstQkxPQ0tTSVpFOl0pWzBdCiAgICAgICAgYnVmID0gYnVmWzotMzY0XSArICIlMDZvXDAiICUgY2hrc3VtICsgYnVmWy0zNTc6XQogICAgICAgIHJldHVybiBidWYKCiAgICBAc3RhdGljbWV0aG9kCiAgICBkZWYgX2NyZWF0ZV9wYXlsb2FkKHBheWxvYWQpOgogICAgICAgICIiIlJldHVybiB0aGUgc3RyaW5nIHBheWxvYWQgZmlsbGVkIHdpdGggemVybyBieXRlcwogICAgICAgICAgIHVwIHRvIHRoZSBuZXh0IDUxMiBieXRlIGJvcmRlci4KICAgICAgICAiIiIKICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChsZW4ocGF5bG9hZCksIEJMT0NLU0laRSkKICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICBwYXlsb2FkICs9IChCTE9DS1NJWkUgLSByZW1haW5kZXIpICogTlVMCiAgICAgICAgcmV0dXJuIHBheWxvYWQKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBfY3JlYXRlX2dudV9sb25nX2hlYWRlcihjbHMsIG5hbWUsIHR5cGUpOgogICAgICAgICIiIlJldHVybiBhIEdOVVRZUEVfTE9OR05BTUUgb3IgR05VVFlQRV9MT05HTElOSyBzZXF1ZW5jZQogICAgICAgICAgIGZvciBuYW1lLgogICAgICAgICIiIgogICAgICAgIG5hbWUgKz0gTlVMCgogICAgICAgIGluZm8gPSB7fQogICAgICAgIGluZm9bIm5hbWUiXSA9ICIuLy4vQExvbmdMaW5rIgogICAgICAgIGluZm9bInR5cGUiXSA9IHR5cGUKICAgICAgICBpbmZvWyJzaXplIl0gPSBsZW4obmFtZSkKICAgICAgICBpbmZvWyJtYWdpYyJdID0gR05VX01BR0lDCgogICAgICAgICMgY3JlYXRlIGV4dGVuZGVkIGhlYWRlciArIG5hbWUgYmxvY2tzLgogICAgICAgIHJldHVybiBjbHMuX2NyZWF0ZV9oZWFkZXIoaW5mbywgVVNUQVJfRk9STUFUKSArIFwKICAgICAgICAgICAgICAgIGNscy5fY3JlYXRlX3BheWxvYWQobmFtZSkKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBfY3JlYXRlX3BheF9nZW5lcmljX2hlYWRlcihjbHMsIHBheF9oZWFkZXJzLCB0eXBlPVhIRFRZUEUpOgogICAgICAgICIiIlJldHVybiBhIFBPU0lYLjEtMjAwMSBleHRlbmRlZCBvciBnbG9iYWwgaGVhZGVyIHNlcXVlbmNlCiAgICAgICAgICAgdGhhdCBjb250YWlucyBhIGxpc3Qgb2Yga2V5d29yZCwgdmFsdWUgcGFpcnMuIFRoZSB2YWx1ZXMKICAgICAgICAgICBtdXN0IGJlIHVuaWNvZGUgb2JqZWN0cy4KICAgICAgICAiIiIKICAgICAgICByZWNvcmRzID0gW10KICAgICAgICBmb3Iga2V5d29yZCwgdmFsdWUgaW4gcGF4X2hlYWRlcnMuaXRlbXMoKToKICAgICAgICAgICAga2V5d29yZCA9IGtleXdvcmQuZW5jb2RlKCJ1dGY4IikKICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5lbmNvZGUoInV0ZjgiKQogICAgICAgICAgICBsID0gbGVuKGtleXdvcmQpICsgbGVuKHZhbHVlKSArIDMgICAjICcgJyArICc9JyArICdcbicKICAgICAgICAgICAgbiA9IHAgPSAwCiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBuID0gbCArIGxlbihzdHIocCkpCiAgICAgICAgICAgICAgICBpZiBuID09IHA6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIHAgPSBuCiAgICAgICAgICAgIHJlY29yZHMuYXBwZW5kKCIlZCAlcz0lc1xuIiAlIChwLCBrZXl3b3JkLCB2YWx1ZSkpCiAgICAgICAgcmVjb3JkcyA9ICIiLmpvaW4ocmVjb3JkcykKCiAgICAgICAgIyBXZSB1c2UgYSBoYXJkY29kZWQgIi4vLi9AUGF4SGVhZGVyIiBuYW1lIGxpa2Ugc3RhciBkb2VzCiAgICAgICAgIyBpbnN0ZWFkIG9mIHRoZSBvbmUgdGhhdCBQT1NJWCByZWNvbW1lbmRzLgogICAgICAgIGluZm8gPSB7fQogICAgICAgIGluZm9bIm5hbWUiXSA9ICIuLy4vQFBheEhlYWRlciIKICAgICAgICBpbmZvWyJ0eXBlIl0gPSB0eXBlCiAgICAgICAgaW5mb1sic2l6ZSJdID0gbGVuKHJlY29yZHMpCiAgICAgICAgaW5mb1sibWFnaWMiXSA9IFBPU0lYX01BR0lDCgogICAgICAgICMgQ3JlYXRlIHBheCBoZWFkZXIgKyByZWNvcmQgYmxvY2tzLgogICAgICAgIHJldHVybiBjbHMuX2NyZWF0ZV9oZWFkZXIoaW5mbywgVVNUQVJfRk9STUFUKSArIFwKICAgICAgICAgICAgICAgIGNscy5fY3JlYXRlX3BheWxvYWQocmVjb3JkcykKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBmcm9tYnVmKGNscywgYnVmKToKICAgICAgICAiIiJDb25zdHJ1Y3QgYSBUYXJJbmZvIG9iamVjdCBmcm9tIGEgNTEyIGJ5dGUgc3RyaW5nIGJ1ZmZlci4KICAgICAgICAiIiIKICAgICAgICBpZiBsZW4oYnVmKSAhPSBCTE9DS1NJWkU6CiAgICAgICAgICAgIHJhaXNlIEhlYWRlckVycm9yKCJ0cnVuY2F0ZWQgaGVhZGVyIikKICAgICAgICBpZiBidWYuY291bnQoTlVMKSA9PSBCTE9DS1NJWkU6CiAgICAgICAgICAgIHJhaXNlIEhlYWRlckVycm9yKCJlbXB0eSBoZWFkZXIiKQoKICAgICAgICBjaGtzdW0gPSBudGkoYnVmWzE0ODoxNTZdKQogICAgICAgIGlmIGNoa3N1bSBub3QgaW4gY2FsY19jaGtzdW1zKGJ1Zik6CiAgICAgICAgICAgIHJhaXNlIEhlYWRlckVycm9yKCJiYWQgY2hlY2tzdW0iKQoKICAgICAgICBvYmogPSBjbHMoKQogICAgICAgIG9iai5idWYgPSBidWYKICAgICAgICBvYmoubmFtZSA9IG50cyhidWZbMDoxMDBdKQogICAgICAgIG9iai5tb2RlID0gbnRpKGJ1ZlsxMDA6MTA4XSkKICAgICAgICBvYmoudWlkID0gbnRpKGJ1ZlsxMDg6MTE2XSkKICAgICAgICBvYmouZ2lkID0gbnRpKGJ1ZlsxMTY6MTI0XSkKICAgICAgICBvYmouc2l6ZSA9IG50aShidWZbMTI0OjEzNl0pCiAgICAgICAgb2JqLm10aW1lID0gbnRpKGJ1ZlsxMzY6MTQ4XSkKICAgICAgICBvYmouY2hrc3VtID0gY2hrc3VtCiAgICAgICAgb2JqLnR5cGUgPSBidWZbMTU2OjE1N10KICAgICAgICBvYmoubGlua25hbWUgPSBudHMoYnVmWzE1NzoyNTddKQogICAgICAgIG9iai51bmFtZSA9IG50cyhidWZbMjY1OjI5N10pCiAgICAgICAgb2JqLmduYW1lID0gbnRzKGJ1ZlsyOTc6MzI5XSkKICAgICAgICBvYmouZGV2bWFqb3IgPSBudGkoYnVmWzMyOTozMzddKQogICAgICAgIG9iai5kZXZtaW5vciA9IG50aShidWZbMzM3OjM0NV0pCiAgICAgICAgcHJlZml4ID0gbnRzKGJ1ZlszNDU6NTAwXSkKCiAgICAgICAgIyBPbGQgVjcgdGFyIGZvcm1hdCByZXByZXNlbnRzIGEgZGlyZWN0b3J5IGFzIGEgcmVndWxhcgogICAgICAgICMgZmlsZSB3aXRoIGEgdHJhaWxpbmcgc2xhc2guCiAgICAgICAgaWYgb2JqLnR5cGUgPT0gQVJFR1RZUEUgYW5kIG9iai5uYW1lLmVuZHN3aXRoKCIvIik6CiAgICAgICAgICAgIG9iai50eXBlID0gRElSVFlQRQoKICAgICAgICAjIFJlbW92ZSByZWR1bmRhbnQgc2xhc2hlcyBmcm9tIGRpcmVjdG9yaWVzLgogICAgICAgIGlmIG9iai5pc2RpcigpOgogICAgICAgICAgICBvYmoubmFtZSA9IG9iai5uYW1lLnJzdHJpcCgiLyIpCgogICAgICAgICMgUmVjb25zdHJ1Y3QgYSB1c3RhciBsb25nbmFtZS4KICAgICAgICBpZiBwcmVmaXggYW5kIG9iai50eXBlIG5vdCBpbiBHTlVfVFlQRVM6CiAgICAgICAgICAgIG9iai5uYW1lID0gcHJlZml4ICsgIi8iICsgb2JqLm5hbWUKICAgICAgICByZXR1cm4gb2JqCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZnJvbXRhcmZpbGUoY2xzLCB0YXJmaWxlKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgVGFySW5mbyBvYmplY3QgZnJvbSBUYXJGaWxlIG9iamVjdAogICAgICAgICAgIHRhcmZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgYnVmID0gdGFyZmlsZS5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQogICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIG9iaiA9IGNscy5mcm9tYnVmKGJ1ZikKICAgICAgICBvYmoub2Zmc2V0ID0gdGFyZmlsZS5maWxlb2JqLnRlbGwoKSAtIEJMT0NLU0laRQogICAgICAgIHJldHVybiBvYmouX3Byb2NfbWVtYmVyKHRhcmZpbGUpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIFRoZSBmb2xsb3dpbmcgYXJlIG1ldGhvZHMgdGhhdCBhcmUgY2FsbGVkIGRlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiBhCiAgICAjIG1lbWJlci4gVGhlIGVudHJ5IHBvaW50IGlzIF9wcm9jX21lbWJlcigpIHdoaWNoIGNhbiBiZSBvdmVycmlkZGVuIGluIGEKICAgICMgc3ViY2xhc3MgdG8gYWRkIGN1c3RvbSBfcHJvY18qKCkgbWV0aG9kcy4gQSBfcHJvY18qKCkgbWV0aG9kIE1VU1QKICAgICMgaW1wbGVtZW50IHRoZSBmb2xsb3dpbmcKICAgICMgb3BlcmF0aW9uczoKICAgICMgMS4gU2V0IHNlbGYub2Zmc2V0X2RhdGEgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBkYXRhIGJsb2NrcyBiZWdpbiwKICAgICMgICAgaWYgdGhlcmUgaXMgZGF0YSB0aGF0IGZvbGxvd3MuCiAgICAjIDIuIFNldCB0YXJmaWxlLm9mZnNldCB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIG5leHQgbWVtYmVyJ3MgaGVhZGVyIHdpbGwKICAgICMgICAgYmVnaW4uCiAgICAjIDMuIFJldHVybiBzZWxmIG9yIGFub3RoZXIgdmFsaWQgVGFySW5mbyBvYmplY3QuCiAgICBkZWYgX3Byb2NfbWVtYmVyKHNlbGYsIHRhcmZpbGUpOgogICAgICAgICIiIkNob29zZSB0aGUgcmlnaHQgcHJvY2Vzc2luZyBtZXRob2QgZGVwZW5kaW5nIG9uCiAgICAgICAgICAgdGhlIHR5cGUgYW5kIGNhbGwgaXQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi50eXBlIGluIChHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX3Byb2NfZ251bG9uZyh0YXJmaWxlKQogICAgICAgIGVsaWYgc2VsZi50eXBlID09IEdOVVRZUEVfU1BBUlNFOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fcHJvY19zcGFyc2UodGFyZmlsZSkKICAgICAgICBlbGlmIHNlbGYudHlwZSBpbiAoWEhEVFlQRSwgWEdMVFlQRSwgU09MQVJJU19YSERUWVBFKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX3Byb2NfcGF4KHRhcmZpbGUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX3Byb2NfYnVpbHRpbih0YXJmaWxlKQoKICAgIGRlZiBfcHJvY19idWlsdGluKHNlbGYsIHRhcmZpbGUpOgogICAgICAgICIiIlByb2Nlc3MgYSBidWlsdGluIHR5cGUgb3IgYW4gdW5rbm93biB0eXBlIHdoaWNoCiAgICAgICAgICAgd2lsbCBiZSB0cmVhdGVkIGFzIGEgcmVndWxhciBmaWxlLgogICAgICAgICIiIgogICAgICAgIHNlbGYub2Zmc2V0X2RhdGEgPSB0YXJmaWxlLmZpbGVvYmoudGVsbCgpCiAgICAgICAgb2Zmc2V0ID0gc2VsZi5vZmZzZXRfZGF0YQogICAgICAgIGlmIHNlbGYuaXNyZWcoKSBvciBzZWxmLnR5cGUgbm90IGluIFNVUFBPUlRFRF9UWVBFUzoKICAgICAgICAgICAgIyBTa2lwIHRoZSBmb2xsb3dpbmcgZGF0YSBibG9ja3MuCiAgICAgICAgICAgIG9mZnNldCArPSBzZWxmLl9ibG9jayhzZWxmLnNpemUpCiAgICAgICAgdGFyZmlsZS5vZmZzZXQgPSBvZmZzZXQKCiAgICAgICAgIyBQYXRjaCB0aGUgVGFySW5mbyBvYmplY3Qgd2l0aCBzYXZlZCBnbG9iYWwKICAgICAgICAjIGhlYWRlciBpbmZvcm1hdGlvbi4KICAgICAgICBzZWxmLl9hcHBseV9wYXhfaW5mbyh0YXJmaWxlLnBheF9oZWFkZXJzLCB0YXJmaWxlLmVuY29kaW5nLCB0YXJmaWxlLmVycm9ycykKCiAgICAgICAgcmV0dXJuIHNlbGYKCiAgICBkZWYgX3Byb2NfZ251bG9uZyhzZWxmLCB0YXJmaWxlKToKICAgICAgICAiIiJQcm9jZXNzIHRoZSBibG9ja3MgdGhhdCBob2xkIGEgR05VIGxvbmduYW1lCiAgICAgICAgICAgb3IgbG9uZ2xpbmsgbWVtYmVyLgogICAgICAgICIiIgogICAgICAgIGJ1ZiA9IHRhcmZpbGUuZmlsZW9iai5yZWFkKHNlbGYuX2Jsb2NrKHNlbGYuc2l6ZSkpCgogICAgICAgICMgRmV0Y2ggdGhlIG5leHQgaGVhZGVyIGFuZCBwcm9jZXNzIGl0LgogICAgICAgIG5leHQgPSBzZWxmLmZyb210YXJmaWxlKHRhcmZpbGUpCiAgICAgICAgaWYgbmV4dCBpcyBOb25lOgogICAgICAgICAgICByYWlzZSBIZWFkZXJFcnJvcigibWlzc2luZyBzdWJzZXF1ZW50IGhlYWRlciIpCgogICAgICAgICMgUGF0Y2ggdGhlIFRhckluZm8gb2JqZWN0IGZyb20gdGhlIG5leHQgaGVhZGVyIHdpdGgKICAgICAgICAjIHRoZSBsb25nbmFtZSBpbmZvcm1hdGlvbi4KICAgICAgICBuZXh0Lm9mZnNldCA9IHNlbGYub2Zmc2V0CiAgICAgICAgaWYgc2VsZi50eXBlID09IEdOVVRZUEVfTE9OR05BTUU6CiAgICAgICAgICAgIG5leHQubmFtZSA9IG50cyhidWYpCiAgICAgICAgZWxpZiBzZWxmLnR5cGUgPT0gR05VVFlQRV9MT05HTElOSzoKICAgICAgICAgICAgbmV4dC5saW5rbmFtZSA9IG50cyhidWYpCgogICAgICAgIHJldHVybiBuZXh0CgogICAgZGVmIF9wcm9jX3NwYXJzZShzZWxmLCB0YXJmaWxlKToKICAgICAgICAiIiJQcm9jZXNzIGEgR05VIHNwYXJzZSBoZWFkZXIgcGx1cyBleHRyYSBoZWFkZXJzLgogICAgICAgICIiIgogICAgICAgIGJ1ZiA9IHNlbGYuYnVmCiAgICAgICAgc3AgPSBfcmluZ2J1ZmZlcigpCiAgICAgICAgcG9zID0gMzg2CiAgICAgICAgbGFzdHBvcyA9IDAKICAgICAgICByZWFscG9zID0gMAogICAgICAgICMgVGhlcmUgYXJlIDQgcG9zc2libGUgc3BhcnNlIHN0cnVjdHMgaW4gdGhlCiAgICAgICAgIyBmaXJzdCBoZWFkZXIuCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoNCk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG9mZnNldCA9IG50aShidWZbcG9zOnBvcyArIDEyXSkKICAgICAgICAgICAgICAgIG51bWJ5dGVzID0gbnRpKGJ1Zltwb3MgKyAxMjpwb3MgKyAyNF0pCiAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgaWYgb2Zmc2V0ID4gbGFzdHBvczoKICAgICAgICAgICAgICAgIHNwLmFwcGVuZChfaG9sZShsYXN0cG9zLCBvZmZzZXQgLSBsYXN0cG9zKSkKICAgICAgICAgICAgc3AuYXBwZW5kKF9kYXRhKG9mZnNldCwgbnVtYnl0ZXMsIHJlYWxwb3MpKQogICAgICAgICAgICByZWFscG9zICs9IG51bWJ5dGVzCiAgICAgICAgICAgIGxhc3Rwb3MgPSBvZmZzZXQgKyBudW1ieXRlcwogICAgICAgICAgICBwb3MgKz0gMjQKCiAgICAgICAgaXNleHRlbmRlZCA9IG9yZChidWZbNDgyXSkKICAgICAgICBvcmlnc2l6ZSA9IG50aShidWZbNDgzOjQ5NV0pCgogICAgICAgICMgSWYgdGhlIGlzZXh0ZW5kZWQgZmxhZyBpcyBnaXZlbiwKICAgICAgICAjIHRoZXJlIGFyZSBleHRyYSBoZWFkZXJzIHRvIHByb2Nlc3MuCiAgICAgICAgd2hpbGUgaXNleHRlbmRlZCA9PSAxOgogICAgICAgICAgICBidWYgPSB0YXJmaWxlLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCiAgICAgICAgICAgIHBvcyA9IDAKICAgICAgICAgICAgZm9yIGkgaW4gcmFuZ2UoMjEpOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IG50aShidWZbcG9zOnBvcyArIDEyXSkKICAgICAgICAgICAgICAgICAgICBudW1ieXRlcyA9IG50aShidWZbcG9zICsgMTI6cG9zICsgMjRdKQogICAgICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIGlmIG9mZnNldCA+IGxhc3Rwb3M6CiAgICAgICAgICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9mZnNldCAtIGxhc3Rwb3MpKQogICAgICAgICAgICAgICAgc3AuYXBwZW5kKF9kYXRhKG9mZnNldCwgbnVtYnl0ZXMsIHJlYWxwb3MpKQogICAgICAgICAgICAgICAgcmVhbHBvcyArPSBudW1ieXRlcwogICAgICAgICAgICAgICAgbGFzdHBvcyA9IG9mZnNldCArIG51bWJ5dGVzCiAgICAgICAgICAgICAgICBwb3MgKz0gMjQKICAgICAgICAgICAgaXNleHRlbmRlZCA9IG9yZChidWZbNTA0XSkKCiAgICAgICAgaWYgbGFzdHBvcyA8IG9yaWdzaXplOgogICAgICAgICAgICBzcC5hcHBlbmQoX2hvbGUobGFzdHBvcywgb3JpZ3NpemUgLSBsYXN0cG9zKSkKCiAgICAgICAgc2VsZi5zcGFyc2UgPSBzcAoKICAgICAgICBzZWxmLm9mZnNldF9kYXRhID0gdGFyZmlsZS5maWxlb2JqLnRlbGwoKQogICAgICAgIHRhcmZpbGUub2Zmc2V0ID0gc2VsZi5vZmZzZXRfZGF0YSArIHNlbGYuX2Jsb2NrKHNlbGYuc2l6ZSkKICAgICAgICBzZWxmLnNpemUgPSBvcmlnc2l6ZQoKICAgICAgICByZXR1cm4gc2VsZgoKICAgIGRlZiBfcHJvY19wYXgoc2VsZiwgdGFyZmlsZSk6CiAgICAgICAgIiIiUHJvY2VzcyBhbiBleHRlbmRlZCBvciBnbG9iYWwgaGVhZGVyIGFzIGRlc2NyaWJlZCBpbgogICAgICAgICAgIFBPU0lYLjEtMjAwMS4KICAgICAgICAiIiIKICAgICAgICAjIFJlYWQgdGhlIGhlYWRlciBpbmZvcm1hdGlvbi4KICAgICAgICBidWYgPSB0YXJmaWxlLmZpbGVvYmoucmVhZChzZWxmLl9ibG9jayhzZWxmLnNpemUpKQoKICAgICAgICAjIEEgcGF4IGhlYWRlciBzdG9yZXMgc3VwcGxlbWVudGFsIGluZm9ybWF0aW9uIGZvciBlaXRoZXIKICAgICAgICAjIHRoZSBmb2xsb3dpbmcgZmlsZSAoZXh0ZW5kZWQpIG9yIGFsbCBmb2xsb3dpbmcgZmlsZXMKICAgICAgICAjIChnbG9iYWwpLgogICAgICAgIGlmIHNlbGYudHlwZSA9PSBYR0xUWVBFOgogICAgICAgICAgICBwYXhfaGVhZGVycyA9IHRhcmZpbGUucGF4X2hlYWRlcnMKICAgICAgICBlbHNlOgogICAgICAgICAgICBwYXhfaGVhZGVycyA9IHRhcmZpbGUucGF4X2hlYWRlcnMuY29weSgpCgogICAgICAgICMgUGFyc2UgcGF4IGhlYWRlciBpbmZvcm1hdGlvbi4gQSByZWNvcmQgbG9va3MgbGlrZSB0aGF0OgogICAgICAgICMgIiVkICVzPSVzXG4iICUgKGxlbmd0aCwga2V5d29yZCwgdmFsdWUpLiBsZW5ndGggaXMgdGhlIHNpemUKICAgICAgICAjIG9mIHRoZSBjb21wbGV0ZSByZWNvcmQgaW5jbHVkaW5nIHRoZSBsZW5ndGggZmllbGQgaXRzZWxmIGFuZAogICAgICAgICMgdGhlIG5ld2xpbmUuIGtleXdvcmQgYW5kIHZhbHVlIGFyZSBib3RoIFVURi04IGVuY29kZWQgc3RyaW5ncy4KICAgICAgICByZWdleCA9IHJlLmNvbXBpbGUociIoXGQrKSAoW149XSspPSIsIHJlLlUpCiAgICAgICAgcG9zID0gMAogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIG1hdGNoID0gcmVnZXgubWF0Y2goYnVmLCBwb3MpCiAgICAgICAgICAgIGlmIG5vdCBtYXRjaDoKICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgICAgICBsZW5ndGgsIGtleXdvcmQgPSBtYXRjaC5ncm91cHMoKQogICAgICAgICAgICBsZW5ndGggPSBpbnQobGVuZ3RoKQogICAgICAgICAgICB2YWx1ZSA9IGJ1ZlttYXRjaC5lbmQoMikgKyAxOm1hdGNoLnN0YXJ0KDEpICsgbGVuZ3RoIC0gMV0KCiAgICAgICAgICAgIGtleXdvcmQgPSBrZXl3b3JkLmRlY29kZSgidXRmOCIpCiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuZGVjb2RlKCJ1dGY4IikKCiAgICAgICAgICAgIHBheF9oZWFkZXJzW2tleXdvcmRdID0gdmFsdWUKICAgICAgICAgICAgcG9zICs9IGxlbmd0aAoKICAgICAgICAjIEZldGNoIHRoZSBuZXh0IGhlYWRlci4KICAgICAgICBuZXh0ID0gc2VsZi5mcm9tdGFyZmlsZSh0YXJmaWxlKQoKICAgICAgICBpZiBzZWxmLnR5cGUgaW4gKFhIRFRZUEUsIFNPTEFSSVNfWEhEVFlQRSk6CiAgICAgICAgICAgIGlmIG5leHQgaXMgTm9uZToKICAgICAgICAgICAgICAgIHJhaXNlIEhlYWRlckVycm9yKCJtaXNzaW5nIHN1YnNlcXVlbnQgaGVhZGVyIikKCiAgICAgICAgICAgICMgUGF0Y2ggdGhlIFRhckluZm8gb2JqZWN0IHdpdGggdGhlIGV4dGVuZGVkIGhlYWRlciBpbmZvLgogICAgICAgICAgICBuZXh0Ll9hcHBseV9wYXhfaW5mbyhwYXhfaGVhZGVycywgdGFyZmlsZS5lbmNvZGluZywgdGFyZmlsZS5lcnJvcnMpCiAgICAgICAgICAgIG5leHQub2Zmc2V0ID0gc2VsZi5vZmZzZXQKCiAgICAgICAgICAgIGlmICJzaXplIiBpbiBwYXhfaGVhZGVyczoKICAgICAgICAgICAgICAgICMgSWYgdGhlIGV4dGVuZGVkIGhlYWRlciByZXBsYWNlcyB0aGUgc2l6ZSBmaWVsZCwKICAgICAgICAgICAgICAgICMgd2UgbmVlZCB0byByZWNhbGN1bGF0ZSB0aGUgb2Zmc2V0IHdoZXJlIHRoZSBuZXh0CiAgICAgICAgICAgICAgICAjIGhlYWRlciBzdGFydHMuCiAgICAgICAgICAgICAgICBvZmZzZXQgPSBuZXh0Lm9mZnNldF9kYXRhCiAgICAgICAgICAgICAgICBpZiBuZXh0LmlzcmVnKCkgb3IgbmV4dC50eXBlIG5vdCBpbiBTVVBQT1JURURfVFlQRVM6CiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IG5leHQuX2Jsb2NrKG5leHQuc2l6ZSkKICAgICAgICAgICAgICAgIHRhcmZpbGUub2Zmc2V0ID0gb2Zmc2V0CgogICAgICAgIHJldHVybiBuZXh0CgogICAgZGVmIF9hcHBseV9wYXhfaW5mbyhzZWxmLCBwYXhfaGVhZGVycywgZW5jb2RpbmcsIGVycm9ycyk6CiAgICAgICAgIiIiUmVwbGFjZSBmaWVsZHMgd2l0aCBzdXBwbGVtZW50YWwgaW5mb3JtYXRpb24gZnJvbSBhIHByZXZpb3VzCiAgICAgICAgICAgcGF4IGV4dGVuZGVkIG9yIGdsb2JhbCBoZWFkZXIuCiAgICAgICAgIiIiCiAgICAgICAgZm9yIGtleXdvcmQsIHZhbHVlIGluIHBheF9oZWFkZXJzLml0ZW1zKCk6CiAgICAgICAgICAgIGlmIGtleXdvcmQgbm90IGluIFBBWF9GSUVMRFM6CiAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgaWYga2V5d29yZCA9PSAicGF0aCI6CiAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnJzdHJpcCgiLyIpCgogICAgICAgICAgICBpZiBrZXl3b3JkIGluIFBBWF9OVU1CRVJfRklFTERTOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHZhbHVlID0gUEFYX05VTUJFUl9GSUVMRFNba2V5d29yZF0odmFsdWUpCiAgICAgICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IDAKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHZhbHVlID0gdXRzKHZhbHVlLCBlbmNvZGluZywgZXJyb3JzKQoKICAgICAgICAgICAgc2V0YXR0cihzZWxmLCBrZXl3b3JkLCB2YWx1ZSkKCiAgICAgICAgc2VsZi5wYXhfaGVhZGVycyA9IHBheF9oZWFkZXJzLmNvcHkoKQoKICAgIGRlZiBfYmxvY2soc2VsZiwgY291bnQpOgogICAgICAgICIiIlJvdW5kIHVwIGEgYnl0ZSBjb3VudCBieSBCTE9DS1NJWkUgYW5kIHJldHVybiBpdCwKICAgICAgICAgICBlLmcuIF9ibG9jayg4MzQpID0+IDEwMjQuCiAgICAgICAgIiIiCiAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QoY291bnQsIEJMT0NLU0laRSkKICAgICAgICBpZiByZW1haW5kZXI6CiAgICAgICAgICAgIGJsb2NrcyArPSAxCiAgICAgICAgcmV0dXJuIGJsb2NrcyAqIEJMT0NLU0laRQoKICAgIGRlZiBpc3JlZyhzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlIGluIFJFR1VMQVJfVFlQRVMKICAgIGRlZiBpc2ZpbGUoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuaXNyZWcoKQogICAgZGVmIGlzZGlyKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gRElSVFlQRQogICAgZGVmIGlzc3ltKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gU1lNVFlQRQogICAgZGVmIGlzbG5rKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gTE5LVFlQRQogICAgZGVmIGlzY2hyKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gQ0hSVFlQRQogICAgZGVmIGlzYmxrKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gQkxLVFlQRQogICAgZGVmIGlzZmlmbyhzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEZJRk9UWVBFCiAgICBkZWYgaXNzcGFyc2Uoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBHTlVUWVBFX1NQQVJTRQogICAgZGVmIGlzZGV2KHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgaW4gKENIUlRZUEUsIEJMS1RZUEUsIEZJRk9UWVBFKQojIGNsYXNzIFRhckluZm8KCmNsYXNzIFRhckZpbGUob2JqZWN0KToKICAgICIiIlRoZSBUYXJGaWxlIENsYXNzIHByb3ZpZGVzIGFuIGludGVyZmFjZSB0byB0YXIgYXJjaGl2ZXMuCiAgICAiIiIKCiAgICBkZWJ1ZyA9IDAgICAgICAgICAgICAgICAgICAgIyBNYXkgYmUgc2V0IGZyb20gMCAobm8gbXNncykgdG8gMyAoYWxsIG1zZ3MpCgogICAgZGVyZWZlcmVuY2UgPSBGYWxzZSAgICAgICAgICMgSWYgdHJ1ZSwgYWRkIGNvbnRlbnQgb2YgbGlua2VkIGZpbGUgdG8gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0YXIgZmlsZSwgZWxzZSB0aGUgbGluay4KCiAgICBpZ25vcmVfemVyb3MgPSBGYWxzZSAgICAgICAgIyBJZiB0cnVlLCBza2lwcyBlbXB0eSBvciBpbnZhbGlkIGJsb2NrcyBhbmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGNvbnRpbnVlcyBwcm9jZXNzaW5nLgoKICAgIGVycm9ybGV2ZWwgPSAwICAgICAgICAgICAgICAjIElmIDAsIGZhdGFsIGVycm9ycyBvbmx5IGFwcGVhciBpbiBkZWJ1ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbWVzc2FnZXMgKGlmIGRlYnVnID49IDApLiBJZiA+IDAsIGVycm9ycwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJlIHBhc3NlZCB0byB0aGUgY2FsbGVyIGFzIGV4Y2VwdGlvbnMuCgogICAgZm9ybWF0ID0gREVGQVVMVF9GT1JNQVQgICAgICMgVGhlIGZvcm1hdCB0byB1c2Ugd2hlbiBjcmVhdGluZyBhbiBhcmNoaXZlLgoKICAgIGVuY29kaW5nID0gRU5DT0RJTkcgICAgICAgICAjIEVuY29kaW5nIGZvciA4LWJpdCBjaGFyYWN0ZXIgc3RyaW5ncy4KCiAgICBlcnJvcnMgPSBOb25lICAgICAgICAgICAgICAgIyBFcnJvciBoYW5kbGVyIGZvciB1bmljb2RlIGNvbnZlcnNpb24uCgogICAgdGFyaW5mbyA9IFRhckluZm8gICAgICAgICAgICMgVGhlIGRlZmF1bHQgVGFySW5mbyBjbGFzcyB0byB1c2UuCgogICAgZmlsZW9iamVjdCA9IEV4RmlsZU9iamVjdCAgICMgVGhlIGRlZmF1bHQgRXhGaWxlT2JqZWN0IGNsYXNzIHRvIHVzZS4KCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZT1Ob25lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCBmb3JtYXQ9Tm9uZSwKICAgICAgICAgICAgdGFyaW5mbz1Ob25lLCBkZXJlZmVyZW5jZT1Ob25lLCBpZ25vcmVfemVyb3M9Tm9uZSwgZW5jb2Rpbmc9Tm9uZSwKICAgICAgICAgICAgZXJyb3JzPU5vbmUsIHBheF9oZWFkZXJzPU5vbmUsIGRlYnVnPU5vbmUsIGVycm9ybGV2ZWw9Tm9uZSk6CiAgICAgICAgIiIiT3BlbiBhbiAodW5jb21wcmVzc2VkKSB0YXIgYXJjaGl2ZSBgbmFtZScuIGBtb2RlJyBpcyBlaXRoZXIgJ3InIHRvCiAgICAgICAgICAgcmVhZCBmcm9tIGFuIGV4aXN0aW5nIGFyY2hpdmUsICdhJyB0byBhcHBlbmQgZGF0YSB0byBhbiBleGlzdGluZwogICAgICAgICAgIGZpbGUgb3IgJ3cnIHRvIGNyZWF0ZSBhIG5ldyBmaWxlIG92ZXJ3cml0aW5nIGFuIGV4aXN0aW5nIG9uZS4gYG1vZGUnCiAgICAgICAgICAgZGVmYXVsdHMgdG8gJ3InLgogICAgICAgICAgIElmIGBmaWxlb2JqJyBpcyBnaXZlbiwgaXQgaXMgdXNlZCBmb3IgcmVhZGluZyBvciB3cml0aW5nIGRhdGEuIElmIGl0CiAgICAgICAgICAgY2FuIGJlIGRldGVybWluZWQsIGBtb2RlJyBpcyBvdmVycmlkZGVuIGJ5IGBmaWxlb2JqJ3MgbW9kZS4KICAgICAgICAgICBgZmlsZW9iaicgaXMgbm90IGNsb3NlZCwgd2hlbiBUYXJGaWxlIGlzIGNsb3NlZC4KICAgICAgICAiIiIKICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJyYXciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InLCAnYScgb3IgJ3cnIikKICAgICAgICBzZWxmLm1vZGUgPSBtb2RlCiAgICAgICAgc2VsZi5fbW9kZSA9IHsiciI6ICJyYiIsICJhIjogInIrYiIsICJ3IjogIndiIn1bbW9kZV0KCiAgICAgICAgaWYgbm90IGZpbGVvYmo6CiAgICAgICAgICAgIGlmIHNlbGYubW9kZSA9PSAiYSIgYW5kIG5vdCBvcy5wYXRoLmV4aXN0cyhuYW1lKToKICAgICAgICAgICAgICAgICMgQ3JlYXRlIG5vbmV4aXN0ZW50IGZpbGVzIGluIGFwcGVuZCBtb2RlLgogICAgICAgICAgICAgICAgc2VsZi5tb2RlID0gInciCiAgICAgICAgICAgICAgICBzZWxmLl9tb2RlID0gIndiIgogICAgICAgICAgICBmaWxlb2JqID0gYmx0bl9vcGVuKG5hbWUsIHNlbGYuX21vZGUpCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIG5hbWUgaXMgTm9uZSBhbmQgaGFzYXR0cihmaWxlb2JqLCAibmFtZSIpOgogICAgICAgICAgICAgICAgbmFtZSA9IGZpbGVvYmoubmFtZQogICAgICAgICAgICBpZiBoYXNhdHRyKGZpbGVvYmosICJtb2RlIik6CiAgICAgICAgICAgICAgICBzZWxmLl9tb2RlID0gZmlsZW9iai5tb2RlCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgc2VsZi5uYW1lID0gb3MucGF0aC5hYnNwYXRoKG5hbWUpCiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagoKICAgICAgICAjIEluaXQgYXR0cmlidXRlcy4KICAgICAgICBpZiBmb3JtYXQgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuZm9ybWF0ID0gZm9ybWF0CiAgICAgICAgaWYgdGFyaW5mbyBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi50YXJpbmZvID0gdGFyaW5mbwogICAgICAgIGlmIGRlcmVmZXJlbmNlIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLmRlcmVmZXJlbmNlID0gZGVyZWZlcmVuY2UKICAgICAgICBpZiBpZ25vcmVfemVyb3MgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuaWdub3JlX3plcm9zID0gaWdub3JlX3plcm9zCiAgICAgICAgaWYgZW5jb2RpbmcgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuZW5jb2RpbmcgPSBlbmNvZGluZwoKICAgICAgICBpZiBlcnJvcnMgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuZXJyb3JzID0gZXJyb3JzCiAgICAgICAgZWxpZiBtb2RlID09ICJyIjoKICAgICAgICAgICAgc2VsZi5lcnJvcnMgPSAidXRmLTgiCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5lcnJvcnMgPSAic3RyaWN0IgoKICAgICAgICBpZiBwYXhfaGVhZGVycyBpcyBub3QgTm9uZSBhbmQgc2VsZi5mb3JtYXQgPT0gUEFYX0ZPUk1BVDoKICAgICAgICAgICAgc2VsZi5wYXhfaGVhZGVycyA9IHBheF9oZWFkZXJzCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5wYXhfaGVhZGVycyA9IHt9CgogICAgICAgIGlmIGRlYnVnIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLmRlYnVnID0gZGVidWcKICAgICAgICBpZiBlcnJvcmxldmVsIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLmVycm9ybGV2ZWwgPSBlcnJvcmxldmVsCgogICAgICAgICMgSW5pdCBkYXRhc3RydWN0dXJlcy4KICAgICAgICBzZWxmLmNsb3NlZCA9IEZhbHNlCiAgICAgICAgc2VsZi5tZW1iZXJzID0gW10gICAgICAgIyBsaXN0IG9mIG1lbWJlcnMgYXMgVGFySW5mbyBvYmplY3RzCiAgICAgICAgc2VsZi5fbG9hZGVkID0gRmFsc2UgICAgIyBmbGFnIGlmIGFsbCBtZW1iZXJzIGhhdmUgYmVlbiByZWFkCiAgICAgICAgc2VsZi5vZmZzZXQgPSAwICAgICAgICAjIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIGFyY2hpdmUgZmlsZQogICAgICAgIHNlbGYuaW5vZGVzID0ge30gICAgICAgICMgZGljdGlvbmFyeSBjYWNoaW5nIHRoZSBpbm9kZXMgb2YKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFyY2hpdmUgbWVtYmVycyBhbHJlYWR5IGFkZGVkCgogICAgICAgIGlmIHNlbGYubW9kZSA9PSAiciI6CiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBzZWxmLm5leHQoKQoKICAgICAgICBpZiBzZWxmLm1vZGUgPT0gImEiOgogICAgICAgICAgICAjIE1vdmUgdG8gdGhlIGVuZCBvZiB0aGUgYXJjaGl2ZSwKICAgICAgICAgICAgIyBiZWZvcmUgdGhlIGZpcnN0IGVtcHR5IGJsb2NrLgogICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gTm9uZQogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgaWYgc2VsZi5uZXh0KCkgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLm9mZnNldCA+IDA6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKC0gQkxPQ0tTSVpFLCAxKQogICAgICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgIGlmIHNlbGYubW9kZSBpbiAiYXciOgogICAgICAgICAgICBzZWxmLl9sb2FkZWQgPSBUcnVlCgogICAgICAgICAgICBpZiBzZWxmLnBheF9oZWFkZXJzOgogICAgICAgICAgICAgICAgYnVmID0gc2VsZi50YXJpbmZvLmNyZWF0ZV9wYXhfZ2xvYmFsX2hlYWRlcihzZWxmLnBheF9oZWFkZXJzLmNvcHkoKSkKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShidWYpCiAgICAgICAgICAgICAgICBzZWxmLm9mZnNldCArPSBsZW4oYnVmKQoKICAgIGRlZiBfZ2V0cG9zaXgoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuZm9ybWF0ID09IFVTVEFSX0ZPUk1BVAogICAgZGVmIF9zZXRwb3NpeChzZWxmLCB2YWx1ZSk6CiAgICAgICAgaW1wb3J0IHdhcm5pbmdzCiAgICAgICAgd2FybmluZ3Mud2FybigidXNlIHRoZSBmb3JtYXQgYXR0cmlidXRlIGluc3RlYWQiLCBEZXByZWNhdGlvbldhcm5pbmcpCiAgICAgICAgaWYgdmFsdWU6CiAgICAgICAgICAgIHNlbGYuZm9ybWF0ID0gVVNUQVJfRk9STUFUCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5mb3JtYXQgPSBHTlVfRk9STUFUCiAgICBwb3NpeCA9IHByb3BlcnR5KF9nZXRwb3NpeCwgX3NldHBvc2l4KQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBCZWxvdyBhcmUgdGhlIGNsYXNzbWV0aG9kcyB3aGljaCBhY3QgYXMgYWx0ZXJuYXRlIGNvbnN0cnVjdG9ycyB0byB0aGUKICAgICMgVGFyRmlsZSBjbGFzcy4gVGhlIG9wZW4oKSBtZXRob2QgaXMgdGhlIG9ubHkgb25lIHRoYXQgaXMgbmVlZGVkIGZvcgogICAgIyBwdWJsaWMgdXNlOyBpdCBpcyB0aGUgInN1cGVyIi1jb25zdHJ1Y3RvciBhbmQgaXMgYWJsZSB0byBzZWxlY3QgYW4KICAgICMgYWRlcXVhdGUgInN1YiItY29uc3RydWN0b3IgZm9yIGEgcGFydGljdWxhciBjb21wcmVzc2lvbiB1c2luZyB0aGUgbWFwcGluZwogICAgIyBmcm9tIE9QRU5fTUVUSC4KICAgICMKICAgICMgVGhpcyBjb25jZXB0IGFsbG93cyBvbmUgdG8gc3ViY2xhc3MgVGFyRmlsZSB3aXRob3V0IGxvc2luZyB0aGUgY29tZm9ydCBvZgogICAgIyB0aGUgc3VwZXItY29uc3RydWN0b3IuIEEgc3ViLWNvbnN0cnVjdG9yIGlzIHJlZ2lzdGVyZWQgYW5kIG1hZGUgYXZhaWxhYmxlCiAgICAjIGJ5IGFkZGluZyBpdCB0byB0aGUgbWFwcGluZyBpbiBPUEVOX01FVEguCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgb3BlbihjbHMsIG5hbWU9Tm9uZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgYnVmc2l6ZT1SRUNPUkRTSVpFLCAqKmt3YXJncyk6CiAgICAgICAgIiIiT3BlbiBhIHRhciBhcmNoaXZlIGZvciByZWFkaW5nLCB3cml0aW5nIG9yIGFwcGVuZGluZy4gUmV0dXJuCiAgICAgICAgICAgYW4gYXBwcm9wcmlhdGUgVGFyRmlsZSBjbGFzcy4KCiAgICAgICAgICAgbW9kZToKICAgICAgICAgICAncicgb3IgJ3I6Kicgb3BlbiBmb3IgcmVhZGluZyB3aXRoIHRyYW5zcGFyZW50IGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3I6JyAgICAgICAgIG9wZW4gZm9yIHJlYWRpbmcgZXhjbHVzaXZlbHkgdW5jb21wcmVzc2VkCiAgICAgICAgICAgJ3I6Z3onICAgICAgIG9wZW4gZm9yIHJlYWRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3I6YnoyJyAgICAgIG9wZW4gZm9yIHJlYWRpbmcgd2l0aCBiemlwMiBjb21wcmVzc2lvbgogICAgICAgICAgICdhJyBvciAnYTonICBvcGVuIGZvciBhcHBlbmRpbmcsIGNyZWF0aW5nIHRoZSBmaWxlIGlmIG5lY2Vzc2FyeQogICAgICAgICAgICd3JyBvciAndzonICBvcGVuIGZvciB3cml0aW5nIHdpdGhvdXQgY29tcHJlc3Npb24KICAgICAgICAgICAndzpneicgICAgICAgb3BlbiBmb3Igd3JpdGluZyB3aXRoIGd6aXAgY29tcHJlc3Npb24KICAgICAgICAgICAndzpiejInICAgICAgb3BlbiBmb3Igd3JpdGluZyB3aXRoIGJ6aXAyIGNvbXByZXNzaW9uCgogICAgICAgICAgICdyfConICAgICAgICBvcGVuIGEgc3RyZWFtIG9mIHRhciBibG9ja3Mgd2l0aCB0cmFuc3BhcmVudCBjb21wcmVzc2lvbgogICAgICAgICAgICdyfCcgICAgICAgICBvcGVuIGFuIHVuY29tcHJlc3NlZCBzdHJlYW0gb2YgdGFyIGJsb2NrcyBmb3IgcmVhZGluZwogICAgICAgICAgICdyfGd6JyAgICAgICBvcGVuIGEgZ3ppcCBjb21wcmVzc2VkIHN0cmVhbSBvZiB0YXIgYmxvY2tzCiAgICAgICAgICAgJ3J8YnoyJyAgICAgIG9wZW4gYSBiemlwMiBjb21wcmVzc2VkIHN0cmVhbSBvZiB0YXIgYmxvY2tzCiAgICAgICAgICAgJ3d8JyAgICAgICAgIG9wZW4gYW4gdW5jb21wcmVzc2VkIHN0cmVhbSBmb3Igd3JpdGluZwogICAgICAgICAgICd3fGd6JyAgICAgICBvcGVuIGEgZ3ppcCBjb21wcmVzc2VkIHN0cmVhbSBmb3Igd3JpdGluZwogICAgICAgICAgICd3fGJ6MicgICAgICBvcGVuIGEgYnppcDIgY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcKICAgICAgICAiIiIKCiAgICAgICAgaWYgbm90IG5hbWUgYW5kIG5vdCBmaWxlb2JqOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJub3RoaW5nIHRvIG9wZW4iKQoKICAgICAgICBpZiBtb2RlIGluICgiciIsICJyOioiKToKICAgICAgICAgICAgIyBGaW5kIG91dCB3aGljaCAqb3BlbigpIGlzIGFwcHJvcHJpYXRlIGZvciBvcGVuaW5nIHRoZSBmaWxlLgogICAgICAgICAgICBmb3IgY29tcHR5cGUgaW4gY2xzLk9QRU5fTUVUSDoKICAgICAgICAgICAgICAgIGZ1bmMgPSBnZXRhdHRyKGNscywgY2xzLk9QRU5fTUVUSFtjb21wdHlwZV0pCiAgICAgICAgICAgICAgICBpZiBmaWxlb2JqIGlzIG5vdCBOb25lOgogICAgICAgICAgICAgICAgICAgIHNhdmVkX3BvcyA9IGZpbGVvYmoudGVsbCgpCiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmMobmFtZSwgInIiLCBmaWxlb2JqLCAqKmt3YXJncykKICAgICAgICAgICAgICAgIGV4Y2VwdCAoUmVhZEVycm9yLCBDb21wcmVzc2lvbkVycm9yKSBhcyBlOgogICAgICAgICAgICAgICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVvYmouc2VlayhzYXZlZF9wb3MpCiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKCJmaWxlIGNvdWxkIG5vdCBiZSBvcGVuZWQgc3VjY2Vzc2Z1bGx5IikKCiAgICAgICAgZWxpZiAiOiIgaW4gbW9kZToKICAgICAgICAgICAgZmlsZW1vZGUsIGNvbXB0eXBlID0gbW9kZS5zcGxpdCgiOiIsIDEpCiAgICAgICAgICAgIGZpbGVtb2RlID0gZmlsZW1vZGUgb3IgInIiCiAgICAgICAgICAgIGNvbXB0eXBlID0gY29tcHR5cGUgb3IgInRhciIKCiAgICAgICAgICAgICMgU2VsZWN0IHRoZSAqb3BlbigpIGZ1bmN0aW9uIGFjY29yZGluZyB0bwogICAgICAgICAgICAjIGdpdmVuIGNvbXByZXNzaW9uLgogICAgICAgICAgICBpZiBjb21wdHlwZSBpbiBjbHMuT1BFTl9NRVRIOgogICAgICAgICAgICAgICAgZnVuYyA9IGdldGF0dHIoY2xzLCBjbHMuT1BFTl9NRVRIW2NvbXB0eXBlXSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoInVua25vd24gY29tcHJlc3Npb24gdHlwZSAlciIgJSBjb21wdHlwZSkKICAgICAgICAgICAgcmV0dXJuIGZ1bmMobmFtZSwgZmlsZW1vZGUsIGZpbGVvYmosICoqa3dhcmdzKQoKICAgICAgICBlbGlmICJ8IiBpbiBtb2RlOgogICAgICAgICAgICBmaWxlbW9kZSwgY29tcHR5cGUgPSBtb2RlLnNwbGl0KCJ8IiwgMSkKICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciIKICAgICAgICAgICAgY29tcHR5cGUgPSBjb21wdHlwZSBvciAidGFyIgoKICAgICAgICAgICAgaWYgZmlsZW1vZGUgbm90IGluICJydyI6CiAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InIG9yICd3JyIpCgogICAgICAgICAgICB0ID0gY2xzKG5hbWUsIGZpbGVtb2RlLAogICAgICAgICAgICAgICAgICAgIF9TdHJlYW0obmFtZSwgZmlsZW1vZGUsIGNvbXB0eXBlLCBmaWxlb2JqLCBidWZzaXplKSwKICAgICAgICAgICAgICAgICAgICAqKmt3YXJncykKICAgICAgICAgICAgdC5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgICAgIHJldHVybiB0CgogICAgICAgIGVsaWYgbW9kZSBpbiAiYXciOgogICAgICAgICAgICByZXR1cm4gY2xzLnRhcm9wZW4obmFtZSwgbW9kZSwgZmlsZW9iaiwgKiprd2FyZ3MpCgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoInVuZGlzY2VybmlibGUgbW9kZSIpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgdGFyb3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsICoqa3dhcmdzKToKICAgICAgICAiIiJPcGVuIHVuY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKG1vZGUpID4gMSBvciBtb2RlIG5vdCBpbiAicmF3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJywgJ2EnIG9yICd3JyIpCiAgICAgICAgcmV0dXJuIGNscyhuYW1lLCBtb2RlLCBmaWxlb2JqLCAqKmt3YXJncykKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBnem9wZW4oY2xzLCBuYW1lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCBjb21wcmVzc2xldmVsPTksICoqa3dhcmdzKToKICAgICAgICAiIiJPcGVuIGd6aXAgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndyciKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBnemlwCiAgICAgICAgICAgIGd6aXAuR3ppcEZpbGUKICAgICAgICBleGNlcHQgKEltcG9ydEVycm9yLCBBdHRyaWJ1dGVFcnJvcik6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoImd6aXAgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQoKICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6CiAgICAgICAgICAgIGZpbGVvYmogPSBibHRuX29wZW4obmFtZSwgbW9kZSArICJiIikKCiAgICAgICAgdHJ5OgogICAgICAgICAgICB0ID0gY2xzLnRhcm9wZW4obmFtZSwgbW9kZSwKICAgICAgICAgICAgICAgIGd6aXAuR3ppcEZpbGUobmFtZSwgbW9kZSwgY29tcHJlc3NsZXZlbCwgZmlsZW9iaiksCiAgICAgICAgICAgICAgICAqKmt3YXJncykKICAgICAgICBleGNlcHQgSU9FcnJvcjoKICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKCJub3QgYSBnemlwIGZpbGUiKQogICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgIHJldHVybiB0CgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgYnoyb3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGNvbXByZXNzbGV2ZWw9OSwgKiprd2FyZ3MpOgogICAgICAgICIiIk9wZW4gYnppcDIgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndycuIikKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpbXBvcnQgYnoyCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJiejIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQoKICAgICAgICBpZiBmaWxlb2JqIGlzIG5vdCBOb25lOgogICAgICAgICAgICBmaWxlb2JqID0gX0JaMlByb3h5KGZpbGVvYmosIG1vZGUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZmlsZW9iaiA9IGJ6Mi5CWjJGaWxlKG5hbWUsIG1vZGUsIGNvbXByZXNzbGV2ZWw9Y29tcHJlc3NsZXZlbCkKCiAgICAgICAgdHJ5OgogICAgICAgICAgICB0ID0gY2xzLnRhcm9wZW4obmFtZSwgbW9kZSwgZmlsZW9iaiwgKiprd2FyZ3MpCiAgICAgICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigibm90IGEgYnppcDIgZmlsZSIpCiAgICAgICAgdC5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgcmV0dXJuIHQKCiAgICAjIEFsbCAqb3BlbigpIG1ldGhvZHMgYXJlIHJlZ2lzdGVyZWQgaGVyZS4KICAgIE9QRU5fTUVUSCA9IHsKICAgICAgICAidGFyIjogInRhcm9wZW4iLCAgICMgdW5jb21wcmVzc2VkIHRhcgogICAgICAgICJneiI6ICAiZ3pvcGVuIiwgICAgIyBnemlwIGNvbXByZXNzZWQgdGFyCiAgICAgICAgImJ6MiI6ICJiejJvcGVuIiAgICAjIGJ6aXAyIGNvbXByZXNzZWQgdGFyCiAgICB9CgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIFRoZSBwdWJsaWMgbWV0aG9kcyB3aGljaCBUYXJGaWxlIHByb3ZpZGVzOgoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICAiIiJDbG9zZSB0aGUgVGFyRmlsZS4gSW4gd3JpdGUtbW9kZSwgdHdvIGZpbmlzaGluZyB6ZXJvIGJsb2NrcyBhcmUKICAgICAgICAgICBhcHBlbmRlZCB0byB0aGUgYXJjaGl2ZS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIGlmIHNlbGYubW9kZSBpbiAiYXciOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKEJMT0NLU0laRSAqIDIpKQogICAgICAgICAgICBzZWxmLm9mZnNldCArPSAoQkxPQ0tTSVpFICogMikKICAgICAgICAgICAgIyBmaWxsIHVwIHRoZSBlbmQgd2l0aCB6ZXJvLWJsb2NrcwogICAgICAgICAgICAjIChsaWtlIG9wdGlvbiAtYjIwIGZvciB0YXIgZG9lcykKICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2Qoc2VsZi5vZmZzZXQsIFJFQ09SRFNJWkUpCiAgICAgICAgICAgIGlmIHJlbWFpbmRlciA+IDA6CiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKFJFQ09SRFNJWkUgLSByZW1haW5kZXIpKQoKICAgICAgICBpZiBub3Qgc2VsZi5fZXh0ZmlsZW9iajoKICAgICAgICAgICAgc2VsZi5maWxlb2JqLmNsb3NlKCkKICAgICAgICBzZWxmLmNsb3NlZCA9IFRydWUKCiAgICBkZWYgZ2V0bWVtYmVyKHNlbGYsIG5hbWUpOgogICAgICAgICIiIlJldHVybiBhIFRhckluZm8gb2JqZWN0IGZvciBtZW1iZXIgYG5hbWUnLiBJZiBgbmFtZScgY2FuIG5vdCBiZQogICAgICAgICAgIGZvdW5kIGluIHRoZSBhcmNoaXZlLCBLZXlFcnJvciBpcyByYWlzZWQuIElmIGEgbWVtYmVyIG9jY3VycyBtb3JlCiAgICAgICAgICAgdGhhbiBvbmNlIGluIHRoZSBhcmNoaXZlLCBpdHMgbGFzdCBvY2N1cmVuY2UgaXMgYXNzdW1lZCB0byBiZSB0aGUKICAgICAgICAgICBtb3N0IHVwLXRvLWRhdGUgdmVyc2lvbi4KICAgICAgICAiIiIKICAgICAgICB0YXJpbmZvID0gc2VsZi5fZ2V0bWVtYmVyKG5hbWUpCiAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICByYWlzZSBLZXlFcnJvcigiZmlsZW5hbWUgJXIgbm90IGZvdW5kIiAlIG5hbWUpCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBkZWYgZ2V0bWVtYmVycyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG1lbWJlcnMgb2YgdGhlIGFyY2hpdmUgYXMgYSBsaXN0IG9mIFRhckluZm8gb2JqZWN0cy4gVGhlCiAgICAgICAgICAgbGlzdCBoYXMgdGhlIHNhbWUgb3JkZXIgYXMgdGhlIG1lbWJlcnMgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soKQogICAgICAgIGlmIG5vdCBzZWxmLl9sb2FkZWQ6ICAgICMgaWYgd2Ugd2FudCB0byBvYnRhaW4gYSBsaXN0IG9mCiAgICAgICAgICAgIHNlbGYuX2xvYWQoKSAgICAgICAgIyBhbGwgbWVtYmVycywgd2UgZmlyc3QgaGF2ZSB0bwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc2NhbiB0aGUgd2hvbGUgYXJjaGl2ZS4KICAgICAgICByZXR1cm4gc2VsZi5tZW1iZXJzCgogICAgZGVmIGdldG5hbWVzKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgbWVtYmVycyBvZiB0aGUgYXJjaGl2ZSBhcyBhIGxpc3Qgb2YgdGhlaXIgbmFtZXMuIEl0IGhhcwogICAgICAgICAgIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBsaXN0IHJldHVybmVkIGJ5IGdldG1lbWJlcnMoKS4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gW3RhcmluZm8ubmFtZSBmb3IgdGFyaW5mbyBpbiBzZWxmLmdldG1lbWJlcnMoKV0KCiAgICBkZWYgZ2V0dGFyaW5mbyhzZWxmLCBuYW1lPU5vbmUsIGFyY25hbWU9Tm9uZSwgZmlsZW9iaj1Ob25lKToKICAgICAgICAiIiJDcmVhdGUgYSBUYXJJbmZvIG9iamVjdCBmb3IgZWl0aGVyIHRoZSBmaWxlIGBuYW1lJyBvciB0aGUgZmlsZQogICAgICAgICAgIG9iamVjdCBgZmlsZW9iaicgKHVzaW5nIG9zLmZzdGF0IG9uIGl0cyBmaWxlIGRlc2NyaXB0b3IpLiBZb3UgY2FuCiAgICAgICAgICAgbW9kaWZ5IHNvbWUgb2YgdGhlIFRhckluZm8ncyBhdHRyaWJ1dGVzIGJlZm9yZSB5b3UgYWRkIGl0IHVzaW5nCiAgICAgICAgICAgYWRkZmlsZSgpLiBJZiBnaXZlbiwgYGFyY25hbWUnIHNwZWNpZmllcyBhbiBhbHRlcm5hdGl2ZSBuYW1lIGZvciB0aGUKICAgICAgICAgICBmaWxlIGluIHRoZSBhcmNoaXZlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpCgogICAgICAgICMgV2hlbiBmaWxlb2JqIGlzIGdpdmVuLCByZXBsYWNlIG5hbWUgYnkKICAgICAgICAjIGZpbGVvYmoncyByZWFsIG5hbWUuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgbmFtZSA9IGZpbGVvYmoubmFtZQoKICAgICAgICAjIEJ1aWxkaW5nIHRoZSBuYW1lIG9mIHRoZSBtZW1iZXIgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgIyBCYWNrd2FyZCBzbGFzaGVzIGFyZSBjb252ZXJ0ZWQgdG8gZm9yd2FyZCBzbGFzaGVzLAogICAgICAgICMgQWJzb2x1dGUgcGF0aHMgYXJlIHR1cm5lZCB0byByZWxhdGl2ZSBwYXRocy4KICAgICAgICBpZiBhcmNuYW1lIGlzIE5vbmU6CiAgICAgICAgICAgIGFyY25hbWUgPSBuYW1lCiAgICAgICAgYXJjbmFtZSA9IG5vcm1wYXRoKGFyY25hbWUpCiAgICAgICAgZHJ2LCBhcmNuYW1lID0gb3MucGF0aC5zcGxpdGRyaXZlKGFyY25hbWUpCiAgICAgICAgd2hpbGUgYXJjbmFtZVswOjFdID09ICIvIjoKICAgICAgICAgICAgYXJjbmFtZSA9IGFyY25hbWVbMTpdCgogICAgICAgICMgTm93LCBmaWxsIHRoZSBUYXJJbmZvIG9iamVjdCB3aXRoCiAgICAgICAgIyBpbmZvcm1hdGlvbiBzcGVjaWZpYyBmb3IgdGhlIGZpbGUuCiAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyaW5mbygpCiAgICAgICAgdGFyaW5mby50YXJmaWxlID0gc2VsZgoKICAgICAgICAjIFVzZSBvcy5zdGF0IG9yIG9zLmxzdGF0LCBkZXBlbmRpbmcgb24gcGxhdGZvcm0KICAgICAgICAjIGFuZCBpZiBzeW1saW5rcyBzaGFsbCBiZSByZXNvbHZlZC4KICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6CiAgICAgICAgICAgIGlmIGhhc2F0dHIob3MsICJsc3RhdCIpIGFuZCBub3Qgc2VsZi5kZXJlZmVyZW5jZToKICAgICAgICAgICAgICAgIHN0YXRyZXMgPSBvcy5sc3RhdChuYW1lKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc3RhdHJlcyA9IG9zLnN0YXQobmFtZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzdGF0cmVzID0gb3MuZnN0YXQoZmlsZW9iai5maWxlbm8oKSkKICAgICAgICBsaW5rbmFtZSA9ICIiCgogICAgICAgIHN0bWQgPSBzdGF0cmVzLnN0X21vZGUKICAgICAgICBpZiBzdGF0LlNfSVNSRUcoc3RtZCk6CiAgICAgICAgICAgIGlub2RlID0gKHN0YXRyZXMuc3RfaW5vLCBzdGF0cmVzLnN0X2RldikKICAgICAgICAgICAgaWYgbm90IHNlbGYuZGVyZWZlcmVuY2UgYW5kIHN0YXRyZXMuc3RfbmxpbmsgPiAxIGFuZCBcCiAgICAgICAgICAgICAgICAgICAgaW5vZGUgaW4gc2VsZi5pbm9kZXMgYW5kIGFyY25hbWUgIT0gc2VsZi5pbm9kZXNbaW5vZGVdOgogICAgICAgICAgICAgICAgIyBJcyBpdCBhIGhhcmRsaW5rIHRvIGFuIGFscmVhZHkKICAgICAgICAgICAgICAgICMgYXJjaGl2ZWQgZmlsZT8KICAgICAgICAgICAgICAgIHR5cGUgPSBMTktUWVBFCiAgICAgICAgICAgICAgICBsaW5rbmFtZSA9IHNlbGYuaW5vZGVzW2lub2RlXQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyBUaGUgaW5vZGUgaXMgYWRkZWQgb25seSBpZiBpdHMgdmFsaWQuCiAgICAgICAgICAgICAgICAjIEZvciB3aW4zMiBpdCBpcyBhbHdheXMgMC4KICAgICAgICAgICAgICAgIHR5cGUgPSBSRUdUWVBFCiAgICAgICAgICAgICAgICBpZiBpbm9kZVswXToKICAgICAgICAgICAgICAgICAgICBzZWxmLmlub2Rlc1tpbm9kZV0gPSBhcmNuYW1lCiAgICAgICAgZWxpZiBzdGF0LlNfSVNESVIoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBESVJUWVBFCiAgICAgICAgZWxpZiBzdGF0LlNfSVNGSUZPKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gRklGT1RZUEUKICAgICAgICBlbGlmIHN0YXQuU19JU0xOSyhzdG1kKToKICAgICAgICAgICAgdHlwZSA9IFNZTVRZUEUKICAgICAgICAgICAgbGlua25hbWUgPSBvcy5yZWFkbGluayhuYW1lKQogICAgICAgIGVsaWYgc3RhdC5TX0lTQ0hSKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gQ0hSVFlQRQogICAgICAgIGVsaWYgc3RhdC5TX0lTQkxLKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gQkxLVFlQRQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgICAgICMgRmlsbCB0aGUgVGFySW5mbyBvYmplY3Qgd2l0aCBhbGwKICAgICAgICAjIGluZm9ybWF0aW9uIHdlIGNhbiBnZXQuCiAgICAgICAgdGFyaW5mby5uYW1lID0gYXJjbmFtZQogICAgICAgIHRhcmluZm8ubW9kZSA9IHN0bWQKICAgICAgICB0YXJpbmZvLnVpZCA9IHN0YXRyZXMuc3RfdWlkCiAgICAgICAgdGFyaW5mby5naWQgPSBzdGF0cmVzLnN0X2dpZAogICAgICAgIGlmIHN0YXQuU19JU1JFRyhzdG1kKToKICAgICAgICAgICAgdGFyaW5mby5zaXplID0gc3RhdHJlcy5zdF9zaXplCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mby5zaXplID0gMAogICAgICAgIHRhcmluZm8ubXRpbWUgPSBzdGF0cmVzLnN0X210aW1lCiAgICAgICAgdGFyaW5mby50eXBlID0gdHlwZQogICAgICAgIHRhcmluZm8ubGlua25hbWUgPSBsaW5rbmFtZQogICAgICAgIGlmIHB3ZDoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mby51bmFtZSA9IHB3ZC5nZXRwd3VpZCh0YXJpbmZvLnVpZClbMF0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgIGlmIGdycDoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mby5nbmFtZSA9IGdycC5nZXRncmdpZCh0YXJpbmZvLmdpZClbMF0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICBpZiB0eXBlIGluIChDSFJUWVBFLCBCTEtUWVBFKToKICAgICAgICAgICAgaWYgaGFzYXR0cihvcywgIm1ham9yIikgYW5kIGhhc2F0dHIob3MsICJtaW5vciIpOgogICAgICAgICAgICAgICAgdGFyaW5mby5kZXZtYWpvciA9IG9zLm1ham9yKHN0YXRyZXMuc3RfcmRldikKICAgICAgICAgICAgICAgIHRhcmluZm8uZGV2bWlub3IgPSBvcy5taW5vcihzdGF0cmVzLnN0X3JkZXYpCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBkZWYgbGlzdChzZWxmLCB2ZXJib3NlPVRydWUpOgogICAgICAgICIiIlByaW50IGEgdGFibGUgb2YgY29udGVudHMgdG8gc3lzLnN0ZG91dC4gSWYgYHZlcmJvc2UnIGlzIEZhbHNlLCBvbmx5CiAgICAgICAgICAgdGhlIG5hbWVzIG9mIHRoZSBtZW1iZXJzIGFyZSBwcmludGVkLiBJZiBpdCBpcyBUcnVlLCBhbiBgbHMgLWwnLWxpa2UKICAgICAgICAgICBvdXRwdXQgaXMgcHJvZHVjZWQuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soKQoKICAgICAgICBmb3IgdGFyaW5mbyBpbiBzZWxmOgogICAgICAgICAgICBpZiB2ZXJib3NlOgogICAgICAgICAgICAgICAgcHJpbnQoZmlsZW1vZGUodGFyaW5mby5tb2RlKSwgZW5kPScgJykKICAgICAgICAgICAgICAgIHByaW50KCIlcy8lcyIgJSAodGFyaW5mby51bmFtZSBvciB0YXJpbmZvLnVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mby5nbmFtZSBvciB0YXJpbmZvLmdpZCksIGVuZD0nICcpCiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzY2hyKCkgb3IgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICAgICAgICAgIHByaW50KCIlMTBzIiAlICgiJWQsJWQiIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJSAodGFyaW5mby5kZXZtYWpvciwgdGFyaW5mby5kZXZtaW5vcikpLCBlbmQ9JyAnKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBwcmludCgiJTEwZCIgJSB0YXJpbmZvLnNpemUsIGVuZD0nICcpCiAgICAgICAgICAgICAgICBwcmludCgiJWQtJTAyZC0lMDJkICUwMmQ6JTAyZDolMDJkIiBcCiAgICAgICAgICAgICAgICAgICAgICAlIHRpbWUubG9jYWx0aW1lKHRhcmluZm8ubXRpbWUpWzo2XSwgZW5kPScgJykKCiAgICAgICAgICAgIHByaW50KHRhcmluZm8ubmFtZSArICgiLyIgaWYgdGFyaW5mby5pc2RpcigpIGVsc2UgIiIpLCBlbmQ9JyAnKQoKICAgICAgICAgICAgaWYgdmVyYm9zZToKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgICAgICAgICBwcmludCgiLT4iLCB0YXJpbmZvLmxpbmtuYW1lLCBlbmQ9JyAnKQogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpOgogICAgICAgICAgICAgICAgICAgIHByaW50KCJsaW5rIHRvIiwgdGFyaW5mby5saW5rbmFtZSwgZW5kPScgJykKICAgICAgICAgICAgcHJpbnQoKQoKICAgIGRlZiBhZGQoc2VsZiwgbmFtZSwgYXJjbmFtZT1Ob25lLCByZWN1cnNpdmU9VHJ1ZSwgZXhjbHVkZT1Ob25lKToKICAgICAgICAiIiJBZGQgdGhlIGZpbGUgYG5hbWUnIHRvIHRoZSBhcmNoaXZlLiBgbmFtZScgbWF5IGJlIGFueSB0eXBlIG9mIGZpbGUKICAgICAgICAgICAoZGlyZWN0b3J5LCBmaWZvLCBzeW1ib2xpYyBsaW5rLCBldGMuKS4gSWYgZ2l2ZW4sIGBhcmNuYW1lJwogICAgICAgICAgIHNwZWNpZmllcyBhbiBhbHRlcm5hdGl2ZSBuYW1lIGZvciB0aGUgZmlsZSBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAgICBEaXJlY3RvcmllcyBhcmUgYWRkZWQgcmVjdXJzaXZlbHkgYnkgZGVmYXVsdC4gVGhpcyBjYW4gYmUgYXZvaWRlZCBieQogICAgICAgICAgIHNldHRpbmcgYHJlY3Vyc2l2ZScgdG8gRmFsc2UuIGBleGNsdWRlJyBpcyBhIGZ1bmN0aW9uIHRoYXQgc2hvdWxkCiAgICAgICAgICAgcmV0dXJuIFRydWUgZm9yIGVhY2ggZmlsZW5hbWUgdG8gYmUgZXhjbHVkZWQuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soImF3IikKCiAgICAgICAgaWYgYXJjbmFtZSBpcyBOb25lOgogICAgICAgICAgICBhcmNuYW1lID0gbmFtZQoKICAgICAgICAjIEV4Y2x1ZGUgcGF0aG5hbWVzLgogICAgICAgIGlmIGV4Y2x1ZGUgaXMgbm90IE5vbmUgYW5kIGV4Y2x1ZGUobmFtZSk6CiAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogRXhjbHVkZWQgJXIiICUgbmFtZSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgICMgU2tpcCBpZiBzb21lYm9keSB0cmllcyB0byBhcmNoaXZlIHRoZSBhcmNoaXZlLi4uCiAgICAgICAgaWYgc2VsZi5uYW1lIGlzIG5vdCBOb25lIGFuZCBvcy5wYXRoLmFic3BhdGgobmFtZSkgPT0gc2VsZi5uYW1lOgogICAgICAgICAgICBzZWxmLl9kYmcoMiwgInRhcmZpbGU6IFNraXBwZWQgJXIiICUgbmFtZSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgICMgU3BlY2lhbCBjYXNlOiBUaGUgdXNlciB3YW50cyB0byBhZGQgdGhlIGN1cnJlbnQKICAgICAgICAjIHdvcmtpbmcgZGlyZWN0b3J5LgogICAgICAgIGlmIG5hbWUgPT0gIi4iOgogICAgICAgICAgICBpZiByZWN1cnNpdmU6CiAgICAgICAgICAgICAgICBpZiBhcmNuYW1lID09ICIuIjoKICAgICAgICAgICAgICAgICAgICBhcmNuYW1lID0gIiIKICAgICAgICAgICAgICAgIGZvciBmIGluIG9zLmxpc3RkaXIobmFtZSk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5hZGQoZiwgb3MucGF0aC5qb2luKGFyY25hbWUsIGYpLCByZWN1cnNpdmUsIGV4Y2x1ZGUpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBzZWxmLl9kYmcoMSwgbmFtZSkKCiAgICAgICAgIyBDcmVhdGUgYSBUYXJJbmZvIG9iamVjdCBmcm9tIHRoZSBmaWxlLgogICAgICAgIHRhcmluZm8gPSBzZWxmLmdldHRhcmluZm8obmFtZSwgYXJjbmFtZSkKCiAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IFVuc3VwcG9ydGVkIHR5cGUgJXIiICUgbmFtZSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgICMgQXBwZW5kIHRoZSB0YXIgaGVhZGVyIGFuZCBkYXRhIHRvIHRoZSBhcmNoaXZlLgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKICAgICAgICAgICAgZiA9IGJsdG5fb3BlbihuYW1lLCAicmIiKQogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbywgZikKICAgICAgICAgICAgZi5jbG9zZSgpCgogICAgICAgIGVsaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbykKICAgICAgICAgICAgaWYgcmVjdXJzaXZlOgogICAgICAgICAgICAgICAgZm9yIGYgaW4gb3MubGlzdGRpcihuYW1lKToKICAgICAgICAgICAgICAgICAgICBzZWxmLmFkZChvcy5wYXRoLmpvaW4obmFtZSwgZiksIG9zLnBhdGguam9pbihhcmNuYW1lLCBmKSwgcmVjdXJzaXZlLCBleGNsdWRlKQoKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbykKCiAgICBkZWYgYWRkZmlsZShzZWxmLCB0YXJpbmZvLCBmaWxlb2JqPU5vbmUpOgogICAgICAgICIiIkFkZCB0aGUgVGFySW5mbyBvYmplY3QgYHRhcmluZm8nIHRvIHRoZSBhcmNoaXZlLiBJZiBgZmlsZW9iaicgaXMKICAgICAgICAgICBnaXZlbiwgdGFyaW5mby5zaXplIGJ5dGVzIGFyZSByZWFkIGZyb20gaXQgYW5kIGFkZGVkIHRvIHRoZSBhcmNoaXZlLgogICAgICAgICAgIFlvdSBjYW4gY3JlYXRlIFRhckluZm8gb2JqZWN0cyB1c2luZyBnZXR0YXJpbmZvKCkuCiAgICAgICAgICAgT24gV2luZG93cyBwbGF0Zm9ybXMsIGBmaWxlb2JqJyBzaG91bGQgYWx3YXlzIGJlIG9wZW5lZCB3aXRoIG1vZGUKICAgICAgICAgICAncmInIHRvIGF2b2lkIGlycml0YXRpb24gYWJvdXQgdGhlIGZpbGUgc2l6ZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiYXciKQoKICAgICAgICB0YXJpbmZvID0gY29weS5jb3B5KHRhcmluZm8pCgogICAgICAgIGJ1ZiA9IHRhcmluZm8udG9idWYoc2VsZi5mb3JtYXQsIHNlbGYuZW5jb2RpbmcsIHNlbGYuZXJyb3JzKQogICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShidWYpCiAgICAgICAgc2VsZi5vZmZzZXQgKz0gbGVuKGJ1ZikKCiAgICAgICAgIyBJZiB0aGVyZSdzIGRhdGEgdG8gZm9sbG93LCBhcHBlbmQgaXQuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgY29weWZpbGVvYmooZmlsZW9iaiwgc2VsZi5maWxlb2JqLCB0YXJpbmZvLnNpemUpCiAgICAgICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKHRhcmluZm8uc2l6ZSwgQkxPQ0tTSVpFKQogICAgICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChCTE9DS1NJWkUgLSByZW1haW5kZXIpKQogICAgICAgICAgICAgICAgYmxvY2tzICs9IDEKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gYmxvY2tzICogQkxPQ0tTSVpFCgogICAgICAgIHNlbGYubWVtYmVycy5hcHBlbmQodGFyaW5mbykKCiAgICBkZWYgZXh0cmFjdGFsbChzZWxmLCBwYXRoPSIuIiwgbWVtYmVycz1Ob25lKToKICAgICAgICAiIiJFeHRyYWN0IGFsbCBtZW1iZXJzIGZyb20gdGhlIGFyY2hpdmUgdG8gdGhlIGN1cnJlbnQgd29ya2luZwogICAgICAgICAgIGRpcmVjdG9yeSBhbmQgc2V0IG93bmVyLCBtb2RpZmljYXRpb24gdGltZSBhbmQgcGVybWlzc2lvbnMgb24KICAgICAgICAgICBkaXJlY3RvcmllcyBhZnRlcndhcmRzLiBgcGF0aCcgc3BlY2lmaWVzIGEgZGlmZmVyZW50IGRpcmVjdG9yeQogICAgICAgICAgIHRvIGV4dHJhY3QgdG8uIGBtZW1iZXJzJyBpcyBvcHRpb25hbCBhbmQgbXVzdCBiZSBhIHN1YnNldCBvZiB0aGUKICAgICAgICAgICBsaXN0IHJldHVybmVkIGJ5IGdldG1lbWJlcnMoKS4KICAgICAgICAiIiIKICAgICAgICBkaXJlY3RvcmllcyA9IFtdCgogICAgICAgIGlmIG1lbWJlcnMgaXMgTm9uZToKICAgICAgICAgICAgbWVtYmVycyA9IHNlbGYKCiAgICAgICAgZm9yIHRhcmluZm8gaW4gbWVtYmVyczoKICAgICAgICAgICAgaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICAgICAgIyBFeHRyYWN0IGRpcmVjdG9yeSB3aXRoIGEgc2FmZSBtb2RlLCBzbyB0aGF0CiAgICAgICAgICAgICAgICAjIGFsbCBmaWxlcyBiZWxvdyBjYW4gYmUgZXh0cmFjdGVkIGFzIHdlbGwuCiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgb3MubWFrZWRpcnMob3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubmFtZSksIDBvNzAwKQogICAgICAgICAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3I6CiAgICAgICAgICAgICAgICAgICAgcGFzcwogICAgICAgICAgICAgICAgZGlyZWN0b3JpZXMuYXBwZW5kKHRhcmluZm8pCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLmV4dHJhY3QodGFyaW5mbywgcGF0aCkKCiAgICAgICAgIyBSZXZlcnNlIHNvcnQgZGlyZWN0b3JpZXMuCiAgICAgICAgZGlyZWN0b3JpZXMuc29ydChsYW1iZGEgYSwgYjogY21wKGEubmFtZSwgYi5uYW1lKSkKICAgICAgICBkaXJlY3Rvcmllcy5yZXZlcnNlKCkKCiAgICAgICAgIyBTZXQgY29ycmVjdCBvd25lciwgbXRpbWUgYW5kIGZpbGVtb2RlIG9uIGRpcmVjdG9yaWVzLgogICAgICAgIGZvciB0YXJpbmZvIGluIGRpcmVjdG9yaWVzOgogICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubmFtZSkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2VsZi5jaG93bih0YXJpbmZvLCBwYXRoKQogICAgICAgICAgICAgICAgc2VsZi51dGltZSh0YXJpbmZvLCBwYXRoKQogICAgICAgICAgICAgICAgc2VsZi5jaG1vZCh0YXJpbmZvLCBwYXRoKQogICAgICAgICAgICBleGNlcHQgRXh0cmFjdEVycm9yIGFzIGU6CiAgICAgICAgICAgICAgICBpZiBzZWxmLmVycm9ybGV2ZWwgPiAxOgogICAgICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZSkKCiAgICBkZWYgZXh0cmFjdChzZWxmLCBtZW1iZXIsIHBhdGg9IiIpOgogICAgICAgICIiIkV4dHJhY3QgYSBtZW1iZXIgZnJvbSB0aGUgYXJjaGl2ZSB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSwKICAgICAgICAgICB1c2luZyBpdHMgZnVsbCBuYW1lLiBJdHMgZmlsZSBpbmZvcm1hdGlvbiBpcyBleHRyYWN0ZWQgYXMgYWNjdXJhdGVseQogICAgICAgICAgIGFzIHBvc3NpYmxlLiBgbWVtYmVyJyBtYXkgYmUgYSBmaWxlbmFtZSBvciBhIFRhckluZm8gb2JqZWN0LiBZb3UgY2FuCiAgICAgICAgICAgc3BlY2lmeSBhIGRpZmZlcmVudCBkaXJlY3RvcnkgdXNpbmcgYHBhdGgnLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJyIikKCiAgICAgICAgaWYgaXNpbnN0YW5jZShtZW1iZXIsIGJhc2VzdHJpbmcpOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5nZXRtZW1iZXIobWVtYmVyKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRhcmluZm8gPSBtZW1iZXIKCiAgICAgICAgIyBQcmVwYXJlIHRoZSBsaW5rIHRhcmdldCBmb3IgbWFrZWxpbmsoKS4KICAgICAgICBpZiB0YXJpbmZvLmlzbG5rKCk6CiAgICAgICAgICAgIHRhcmluZm8uX2xpbmtfdGFyZ2V0ID0gb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubGlua25hbWUpCgogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi5fZXh0cmFjdF9tZW1iZXIodGFyaW5mbywgb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubmFtZSkpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IgYXMgZToKICAgICAgICAgICAgaWYgc2VsZi5lcnJvcmxldmVsID4gMDoKICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBpZiBlLmZpbGVuYW1lIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyIgJSBlLnN0cmVycm9yKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzICVyIiAlIChlLnN0cmVycm9yLCBlLmZpbGVuYW1lKSkKICAgICAgICBleGNlcHQgRXh0cmFjdEVycm9yIGFzIGU6CiAgICAgICAgICAgIGlmIHNlbGYuZXJyb3JsZXZlbCA+IDE6CiAgICAgICAgICAgICAgICByYWlzZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyIgJSBlKQoKICAgIGRlZiBleHRyYWN0ZmlsZShzZWxmLCBtZW1iZXIpOgogICAgICAgICIiIkV4dHJhY3QgYSBtZW1iZXIgZnJvbSB0aGUgYXJjaGl2ZSBhcyBhIGZpbGUgb2JqZWN0LiBgbWVtYmVyJyBtYXkgYmUKICAgICAgICAgICBhIGZpbGVuYW1lIG9yIGEgVGFySW5mbyBvYmplY3QuIElmIGBtZW1iZXInIGlzIGEgcmVndWxhciBmaWxlLCBhCiAgICAgICAgICAgZmlsZS1saWtlIG9iamVjdCBpcyByZXR1cm5lZC4gSWYgYG1lbWJlcicgaXMgYSBsaW5rLCBhIGZpbGUtbGlrZQogICAgICAgICAgIG9iamVjdCBpcyBjb25zdHJ1Y3RlZCBmcm9tIHRoZSBsaW5rJ3MgdGFyZ2V0LiBJZiBgbWVtYmVyJyBpcyBub25lIG9mCiAgICAgICAgICAgdGhlIGFib3ZlLCBOb25lIGlzIHJldHVybmVkLgogICAgICAgICAgIFRoZSBmaWxlLWxpa2Ugb2JqZWN0IGlzIHJlYWQtb25seSBhbmQgcHJvdmlkZXMgdGhlIGZvbGxvd2luZwogICAgICAgICAgIG1ldGhvZHM6IHJlYWQoKSwgcmVhZGxpbmUoKSwgcmVhZGxpbmVzKCksIHNlZWsoKSBhbmQgdGVsbCgpCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soInIiKQoKICAgICAgICBpZiBpc2luc3RhbmNlKG1lbWJlciwgYmFzZXN0cmluZyk6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLmdldG1lbWJlcihtZW1iZXIpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mbyA9IG1lbWJlcgoKICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmplY3Qoc2VsZiwgdGFyaW5mbykKCiAgICAgICAgZWxpZiB0YXJpbmZvLnR5cGUgbm90IGluIFNVUFBPUlRFRF9UWVBFUzoKICAgICAgICAgICAgIyBJZiBhIG1lbWJlcidzIHR5cGUgaXMgdW5rbm93biwgaXQgaXMgdHJlYXRlZCBhcyBhCiAgICAgICAgICAgICMgcmVndWxhciBmaWxlLgogICAgICAgICAgICByZXR1cm4gc2VsZi5maWxlb2JqZWN0KHNlbGYsIHRhcmluZm8pCgogICAgICAgIGVsaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShzZWxmLmZpbGVvYmosIF9TdHJlYW0pOgogICAgICAgICAgICAgICAgIyBBIHNtYWxsIGJ1dCB1Z2x5IHdvcmthcm91bmQgZm9yIHRoZSBjYXNlIHRoYXQgc29tZW9uZSB0cmllcwogICAgICAgICAgICAgICAgIyB0byBleHRyYWN0IGEgKHN5bSlsaW5rIGFzIGEgZmlsZS1vYmplY3QgZnJvbSBhIG5vbi1zZWVrYWJsZQogICAgICAgICAgICAgICAgIyBzdHJlYW0gb2YgdGFyIGJsb2Nrcy4KICAgICAgICAgICAgICAgIHJhaXNlIFN0cmVhbUVycm9yKCJjYW5ub3QgZXh0cmFjdCAoc3ltKWxpbmsgYXMgZmlsZSBvYmplY3QiKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyBBIChzeW0pbGluaydzIGZpbGUgb2JqZWN0IGlzIGl0cyB0YXJnZXQncyBmaWxlIG9iamVjdC4KICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLmV4dHJhY3RmaWxlKHNlbGYuX2dldG1lbWJlcih0YXJpbmZvLmxpbmtuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmluZm8pKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgICMgSWYgdGhlcmUncyBubyBkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgbWVtYmVyIChkaXJlY3RvcnksIGNocmRldiwKICAgICAgICAgICAgIyBibGtkZXYsIGV0Yy4pLCByZXR1cm4gTm9uZSBpbnN0ZWFkIG9mIGEgZmlsZSBvYmplY3QuCiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgZGVmIF9leHRyYWN0X21lbWJlcihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJFeHRyYWN0IHRoZSBUYXJJbmZvIG9iamVjdCB0YXJpbmZvIHRvIGEgcGh5c2ljYWwKICAgICAgICAgICBmaWxlIGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgICMgRmV0Y2ggdGhlIFRhckluZm8gb2JqZWN0IGZvciB0aGUgZ2l2ZW4gbmFtZQogICAgICAgICMgYW5kIGJ1aWxkIHRoZSBkZXN0aW5hdGlvbiBwYXRobmFtZSwgcmVwbGFjaW5nCiAgICAgICAgIyBmb3J3YXJkIHNsYXNoZXMgdG8gcGxhdGZvcm0gc3BlY2lmaWMgc2VwYXJhdG9ycy4KICAgICAgICBpZiB0YXJnZXRwYXRoWy0xOl0gPT0gIi8iOgogICAgICAgICAgICB0YXJnZXRwYXRoID0gdGFyZ2V0cGF0aFs6LTFdCiAgICAgICAgdGFyZ2V0cGF0aCA9IG9zLnBhdGgubm9ybXBhdGgodGFyZ2V0cGF0aCkKCiAgICAgICAgIyBDcmVhdGUgYWxsIHVwcGVyIGRpcmVjdG9yaWVzLgogICAgICAgIHVwcGVyZGlycyA9IG9zLnBhdGguZGlybmFtZSh0YXJnZXRwYXRoKQogICAgICAgIGlmIHVwcGVyZGlycyBhbmQgbm90IG9zLnBhdGguZXhpc3RzKHVwcGVyZGlycyk6CiAgICAgICAgICAgIG9zLm1ha2VkaXJzKHVwcGVyZGlycykKCiAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgc2VsZi5fZGJnKDEsICIlcyAtPiAlcyIgJSAodGFyaW5mby5uYW1lLCB0YXJpbmZvLmxpbmtuYW1lKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgdGFyaW5mby5uYW1lKQoKICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgc2VsZi5tYWtlZGlyKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzZmlmbygpOgogICAgICAgICAgICBzZWxmLm1ha2VmaWZvKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzY2hyKCkgb3IgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICBzZWxmLm1ha2VkZXYodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNsbmsoKSBvciB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWxpbmsodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICBzZWxmLm1ha2V1bmtub3duKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQoKICAgICAgICBzZWxmLmNob3duKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgaWYgbm90IHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgc2VsZi5jaG1vZCh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgICAgICBzZWxmLnV0aW1lKHRhcmluZm8sIHRhcmdldHBhdGgpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIEJlbG93IGFyZSB0aGUgZGlmZmVyZW50IGZpbGUgbWV0aG9kcy4gVGhleSBhcmUgY2FsbGVkIHZpYQogICAgIyBfZXh0cmFjdF9tZW1iZXIoKSB3aGVuIGV4dHJhY3QoKSBpcyBjYWxsZWQuIFRoZXkgY2FuIGJlIHJlcGxhY2VkIGluIGEKICAgICMgc3ViY2xhc3MgdG8gaW1wbGVtZW50IG90aGVyIGZ1bmN0aW9uYWxpdHkuCgogICAgZGVmIG1ha2VkaXIoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGRpcmVjdG9yeSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICB0cnk6CiAgICAgICAgICAgIG9zLm1rZGlyKHRhcmdldHBhdGgpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IgYXMgZToKICAgICAgICAgICAgaWYgZS5lcnJubyAhPSBlcnJuby5FRVhJU1Q6CiAgICAgICAgICAgICAgICByYWlzZQoKICAgIGRlZiBtYWtlZmlsZShzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlsZSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBzb3VyY2UgPSBzZWxmLmV4dHJhY3RmaWxlKHRhcmluZm8pCiAgICAgICAgdGFyZ2V0ID0gYmx0bl9vcGVuKHRhcmdldHBhdGgsICJ3YiIpCiAgICAgICAgY29weWZpbGVvYmooc291cmNlLCB0YXJnZXQpCiAgICAgICAgc291cmNlLmNsb3NlKCkKICAgICAgICB0YXJnZXQuY2xvc2UoKQoKICAgIGRlZiBtYWtldW5rbm93bihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlsZSBmcm9tIGEgVGFySW5mbyBvYmplY3Qgd2l0aCBhbiB1bmtub3duIHR5cGUKICAgICAgICAgICBhdCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IFVua25vd24gZmlsZSB0eXBlICVyLCAiIFwKICAgICAgICAgICAgICAgICAgICAgImV4dHJhY3RlZCBhcyByZWd1bGFyIGZpbGUuIiAlIHRhcmluZm8udHlwZSkKCiAgICBkZWYgbWFrZWZpZm8oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGZpZm8gY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgaWYgaGFzYXR0cihvcywgIm1rZmlmbyIpOgogICAgICAgICAgICBvcy5ta2ZpZm8odGFyZ2V0cGF0aCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoImZpZm8gbm90IHN1cHBvcnRlZCBieSBzeXN0ZW0iKQoKICAgIGRlZiBtYWtlZGV2KHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBjaGFyYWN0ZXIgb3IgYmxvY2sgZGV2aWNlIGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIGlmIG5vdCBoYXNhdHRyKG9zLCAibWtub2QiKSBvciBub3QgaGFzYXR0cihvcywgIm1ha2VkZXYiKToKICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yKCJzcGVjaWFsIGRldmljZXMgbm90IHN1cHBvcnRlZCBieSBzeXN0ZW0iKQoKICAgICAgICBtb2RlID0gdGFyaW5mby5tb2RlCiAgICAgICAgaWYgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICBtb2RlIHw9IHN0YXQuU19JRkJMSwogICAgICAgIGVsc2U6CiAgICAgICAgICAgIG1vZGUgfD0gc3RhdC5TX0lGQ0hSCgogICAgICAgIG9zLm1rbm9kKHRhcmdldHBhdGgsIG1vZGUsCiAgICAgICAgICAgICAgICAgb3MubWFrZWRldih0YXJpbmZvLmRldm1ham9yLCB0YXJpbmZvLmRldm1pbm9yKSkKCiAgICBkZWYgbWFrZWxpbmsoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIChzeW1ib2xpYykgbGluayBjYWxsZWQgdGFyZ2V0cGF0aC4gSWYgaXQgY2Fubm90IGJlIGNyZWF0ZWQKICAgICAgICAgIChwbGF0Zm9ybSBsaW1pdGF0aW9uKSwgd2UgdHJ5IHRvIG1ha2UgYSBjb3B5IG9mIHRoZSByZWZlcmVuY2VkIGZpbGUKICAgICAgICAgIGluc3RlYWQgb2YgYSBsaW5rLgogICAgICAgICIiIgogICAgICAgIGxpbmtwYXRoID0gdGFyaW5mby5saW5rbmFtZQogICAgICAgIHRyeToKICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICAgICAgb3Muc3ltbGluayhsaW5rcGF0aCwgdGFyZ2V0cGF0aCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgU2VlIGV4dHJhY3QoKS4KICAgICAgICAgICAgICAgIG9zLmxpbmsodGFyaW5mby5fbGlua190YXJnZXQsIHRhcmdldHBhdGgpCiAgICAgICAgZXhjZXB0IEF0dHJpYnV0ZUVycm9yOgogICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICAgICBsaW5rcGF0aCA9IG9zLnBhdGguam9pbihvcy5wYXRoLmRpcm5hbWUodGFyaW5mby5uYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmtwYXRoKQogICAgICAgICAgICAgICAgbGlua3BhdGggPSBub3JtcGF0aChsaW5rcGF0aCkKCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHNlbGYuX2V4dHJhY3RfbWVtYmVyKHNlbGYuZ2V0bWVtYmVyKGxpbmtwYXRoKSwgdGFyZ2V0cGF0aCkKICAgICAgICAgICAgZXhjZXB0IChFbnZpcm9ubWVudEVycm9yLCBLZXlFcnJvcikgYXMgZToKICAgICAgICAgICAgICAgIGxpbmtwYXRoID0gb3MucGF0aC5ub3JtcGF0aChsaW5rcGF0aCkKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBzaHV0aWwuY29weTIobGlua3BhdGgsIHRhcmdldHBhdGgpCiAgICAgICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciBhcyBlOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoImxpbmsgY291bGQgbm90IGJlIGNyZWF0ZWQiKQoKICAgIGRlZiBjaG93bihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJTZXQgb3duZXIgb2YgdGFyZ2V0cGF0aCBhY2NvcmRpbmcgdG8gdGFyaW5mby4KICAgICAgICAiIiIKICAgICAgICBpZiBwd2QgYW5kIGhhc2F0dHIob3MsICJnZXRldWlkIikgYW5kIG9zLmdldGV1aWQoKSA9PSAwOgogICAgICAgICAgICAjIFdlIGhhdmUgdG8gYmUgcm9vdCB0byBkbyBzby4KICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgZyA9IGdycC5nZXRncm5hbSh0YXJpbmZvLmduYW1lKVsyXQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgZyA9IGdycC5nZXRncmdpZCh0YXJpbmZvLmdpZClbMl0KICAgICAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgICAgICBnID0gb3MuZ2V0Z2lkKCkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdSA9IHB3ZC5nZXRwd25hbSh0YXJpbmZvLnVuYW1lKVsyXQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgdSA9IHB3ZC5nZXRwd3VpZCh0YXJpbmZvLnVpZClbMl0KICAgICAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgICAgICB1ID0gb3MuZ2V0dWlkKCkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpIGFuZCBoYXNhdHRyKG9zLCAibGNob3duIik6CiAgICAgICAgICAgICAgICAgICAgb3MubGNob3duKHRhcmdldHBhdGgsIHUsIGcpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIGlmIHN5cy5wbGF0Zm9ybSAhPSAib3MyZW14IjoKICAgICAgICAgICAgICAgICAgICAgICAgb3MuY2hvd24odGFyZ2V0cGF0aCwgdSwgZykKICAgICAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IgYXMgZToKICAgICAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBvd25lciIpCgogICAgZGVmIGNobW9kKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIlNldCBmaWxlIHBlcm1pc3Npb25zIG9mIHRhcmdldHBhdGggYWNjb3JkaW5nIHRvIHRhcmluZm8uCiAgICAgICAgIiIiCiAgICAgICAgaWYgaGFzYXR0cihvcywgJ2NobW9kJyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG9zLmNobW9kKHRhcmdldHBhdGgsIHRhcmluZm8ubW9kZSkKICAgICAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IgYXMgZToKICAgICAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBtb2RlIikKCiAgICBkZWYgdXRpbWUoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiU2V0IG1vZGlmaWNhdGlvbiB0aW1lIG9mIHRhcmdldHBhdGggYWNjb3JkaW5nIHRvIHRhcmluZm8uCiAgICAgICAgIiIiCiAgICAgICAgaWYgbm90IGhhc2F0dHIob3MsICd1dGltZScpOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBpZiBzeXMucGxhdGZvcm0gPT0gIndpbjMyIiBhbmQgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICAjIEFjY29yZGluZyB0byBtc2RuLm1pY3Jvc29mdC5jb20sIGl0IGlzIGFuIGVycm9yIChFQUNDRVMpCiAgICAgICAgICAgICMgdG8gdXNlIHV0aW1lKCkgb24gZGlyZWN0b3JpZXMuCiAgICAgICAgICAgIHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgb3MudXRpbWUodGFyZ2V0cGF0aCwgKHRhcmluZm8ubXRpbWUsIHRhcmluZm8ubXRpbWUpKQogICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yIGFzIGU6CiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBtb2RpZmljYXRpb24gdGltZSIpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBkZWYgbmV4dChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgbWVtYmVyIG9mIHRoZSBhcmNoaXZlIGFzIGEgVGFySW5mbyBvYmplY3QsIHdoZW4KICAgICAgICAgICBUYXJGaWxlIGlzIG9wZW5lZCBmb3IgcmVhZGluZy4gUmV0dXJuIE5vbmUgaWYgdGhlcmUgaXMgbm8gbW9yZQogICAgICAgICAgIGF2YWlsYWJsZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygicmEiKQogICAgICAgIGlmIHNlbGYuZmlyc3RtZW1iZXIgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIG0gPSBzZWxmLmZpcnN0bWVtYmVyCiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCiAgICAgICAgICAgIHJldHVybiBtCgogICAgICAgICMgUmVhZCB0aGUgbmV4dCBibG9jay4KICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCkKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJpbmZvLmZyb210YXJmaWxlKHNlbGYpCiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICBzZWxmLm1lbWJlcnMuYXBwZW5kKHRhcmluZm8pCgogICAgICAgICAgICBleGNlcHQgSGVhZGVyRXJyb3IgYXMgZToKICAgICAgICAgICAgICAgIGlmIHNlbGYuaWdub3JlX3plcm9zOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAiMHglWDogJXMiICUgKHNlbGYub2Zmc2V0LCBlKSkKICAgICAgICAgICAgICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLm9mZnNldCA9PSAwOgogICAgICAgICAgICAgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3Ioc3RyKGUpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgICAgIGJyZWFrCgogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIExpdHRsZSBoZWxwZXIgbWV0aG9kczoKCiAgICBkZWYgX2dldG1lbWJlcihzZWxmLCBuYW1lLCB0YXJpbmZvPU5vbmUpOgogICAgICAgICIiIkZpbmQgYW4gYXJjaGl2ZSBtZW1iZXIgYnkgbmFtZSBmcm9tIGJvdHRvbSB0byB0b3AuCiAgICAgICAgICAgSWYgdGFyaW5mbyBpcyBnaXZlbiwgaXQgaXMgdXNlZCBhcyB0aGUgc3RhcnRpbmcgcG9pbnQuCiAgICAgICAgIiIiCiAgICAgICAgIyBFbnN1cmUgdGhhdCBhbGwgbWVtYmVycyBoYXZlIGJlZW4gbG9hZGVkLgogICAgICAgIG1lbWJlcnMgPSBzZWxmLmdldG1lbWJlcnMoKQoKICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgIGVuZCA9IGxlbihtZW1iZXJzKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGVuZCA9IG1lbWJlcnMuaW5kZXgodGFyaW5mbykKCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoZW5kIC0gMSwgLTEsIC0xKToKICAgICAgICAgICAgaWYgbmFtZSA9PSBtZW1iZXJzW2ldLm5hbWU6CiAgICAgICAgICAgICAgICByZXR1cm4gbWVtYmVyc1tpXQoKICAgIGRlZiBfbG9hZChzZWxmKToKICAgICAgICAiIiJSZWFkIHRocm91Z2ggdGhlIGVudGlyZSBhcmNoaXZlIGZpbGUgYW5kIGxvb2sgZm9yIHJlYWRhYmxlCiAgICAgICAgICAgbWVtYmVycy4KICAgICAgICAiIiIKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5uZXh0KCkKICAgICAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBzZWxmLl9sb2FkZWQgPSBUcnVlCgogICAgZGVmIF9jaGVjayhzZWxmLCBtb2RlPU5vbmUpOgogICAgICAgICIiIkNoZWNrIGlmIFRhckZpbGUgaXMgc3RpbGwgb3BlbiwgYW5kIGlmIHRoZSBvcGVyYXRpb24ncyBtb2RlCiAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gVGFyRmlsZSdzIG1vZGUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoIiVzIGlzIGNsb3NlZCIgJSBzZWxmLl9fY2xhc3NfXy5fX25hbWVfXykKICAgICAgICBpZiBtb2RlIGlzIG5vdCBOb25lIGFuZCBzZWxmLm1vZGUgbm90IGluIG1vZGU6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoImJhZCBvcGVyYXRpb24gZm9yIG1vZGUgJXIiICUgc2VsZi5tb2RlKQoKICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKICAgICAgICAiIiJQcm92aWRlIGFuIGl0ZXJhdG9yIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLl9sb2FkZWQ6CiAgICAgICAgICAgIHJldHVybiBpdGVyKHNlbGYubWVtYmVycykKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gVGFySXRlcihzZWxmKQoKICAgIGRlZiBfZGJnKHNlbGYsIGxldmVsLCBtc2cpOgogICAgICAgICIiIldyaXRlIGRlYnVnZ2luZyBvdXRwdXQgdG8gc3lzLnN0ZGVyci4KICAgICAgICAiIiIKICAgICAgICBpZiBsZXZlbCA8PSBzZWxmLmRlYnVnOgogICAgICAgICAgICBwcmludChtc2csIGZpbGU9c3lzLnN0ZGVycikKIyBjbGFzcyBUYXJGaWxlCgpjbGFzcyBUYXJJdGVyOgogICAgIiIiSXRlcmF0b3IgQ2xhc3MuCgogICAgICAgZm9yIHRhcmluZm8gaW4gVGFyRmlsZSguLi4pOgogICAgICAgICAgIHN1aXRlLi4uCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgdGFyZmlsZSk6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySXRlciBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi50YXJmaWxlID0gdGFyZmlsZQogICAgICAgIHNlbGYuaW5kZXggPSAwCiAgICBkZWYgX19pdGVyX18oc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIGl0ZXJhdG9yIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZgogICAgZGVmIF9fbmV4dF9fKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgbmV4dCBpdGVtIHVzaW5nIFRhckZpbGUncyBuZXh0KCkgbWV0aG9kLgogICAgICAgICAgIFdoZW4gYWxsIG1lbWJlcnMgaGF2ZSBiZWVuIHJlYWQsIHNldCBUYXJGaWxlIGFzIF9sb2FkZWQuCiAgICAgICAgIiIiCiAgICAgICAgIyBGaXggZm9yIFNGICMxMTAwNDI5OiBVbmRlciByYXJlIGNpcmN1bXN0YW5jZXMgaXQgY2FuCiAgICAgICAgIyBoYXBwZW4gdGhhdCBnZXRtZW1iZXJzKCkgaXMgY2FsbGVkIGR1cmluZyBpdGVyYXRpb24sCiAgICAgICAgIyB3aGljaCB3aWxsIGNhdXNlIFRhckl0ZXIgdG8gc3RvcCBwcmVtYXR1cmVseS4KICAgICAgICBpZiBub3Qgc2VsZi50YXJmaWxlLl9sb2FkZWQ6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLnRhcmZpbGUubmV4dCgpCiAgICAgICAgICAgIGlmIG5vdCB0YXJpbmZvOgogICAgICAgICAgICAgICAgc2VsZi50YXJmaWxlLl9sb2FkZWQgPSBUcnVlCiAgICAgICAgICAgICAgICByYWlzZSBTdG9wSXRlcmF0aW9uCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyZmlsZS5tZW1iZXJzW3NlbGYuaW5kZXhdCiAgICAgICAgICAgIGV4Y2VwdCBJbmRleEVycm9yOgogICAgICAgICAgICAgICAgcmFpc2UgU3RvcEl0ZXJhdGlvbgogICAgICAgIHNlbGYuaW5kZXggKz0gMQogICAgICAgIHJldHVybiB0YXJpbmZvCgojIEhlbHBlciBjbGFzc2VzIGZvciBzcGFyc2UgZmlsZSBzdXBwb3J0CmNsYXNzIF9zZWN0aW9uOgogICAgIiIiQmFzZSBjbGFzcyBmb3IgX2RhdGEgYW5kIF9ob2xlLgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgb2Zmc2V0LCBzaXplKToKICAgICAgICBzZWxmLm9mZnNldCA9IG9mZnNldAogICAgICAgIHNlbGYuc2l6ZSA9IHNpemUKICAgIGRlZiBfX2NvbnRhaW5zX18oc2VsZiwgb2Zmc2V0KToKICAgICAgICByZXR1cm4gc2VsZi5vZmZzZXQgPD0gb2Zmc2V0IDwgc2VsZi5vZmZzZXQgKyBzZWxmLnNpemUKCmNsYXNzIF9kYXRhKF9zZWN0aW9uKToKICAgICIiIlJlcHJlc2VudCBhIGRhdGEgc2VjdGlvbiBpbiBhIHNwYXJzZSBmaWxlLgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgb2Zmc2V0LCBzaXplLCByZWFscG9zKToKICAgICAgICBfc2VjdGlvbi5fX2luaXRfXyhzZWxmLCBvZmZzZXQsIHNpemUpCiAgICAgICAgc2VsZi5yZWFscG9zID0gcmVhbHBvcwoKY2xhc3MgX2hvbGUoX3NlY3Rpb24pOgogICAgIiIiUmVwcmVzZW50IGEgaG9sZSBzZWN0aW9uIGluIGEgc3BhcnNlIGZpbGUuCiAgICAiIiIKICAgIHBhc3MKCmNsYXNzIF9yaW5nYnVmZmVyKGxpc3QpOgogICAgIiIiUmluZ2J1ZmZlciBjbGFzcyB3aGljaCBpbmNyZWFzZXMgcGVyZm9ybWFuY2UKICAgICAgIG92ZXIgYSByZWd1bGFyIGxpc3QuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBzZWxmLmlkeCA9IDAKICAgIGRlZiBmaW5kKHNlbGYsIG9mZnNldCk6CiAgICAgICAgaWR4ID0gc2VsZi5pZHgKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBpdGVtID0gc2VsZltpZHhdCiAgICAgICAgICAgIGlmIG9mZnNldCBpbiBpdGVtOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgaWR4ICs9IDEKICAgICAgICAgICAgaWYgaWR4ID09IGxlbihzZWxmKToKICAgICAgICAgICAgICAgIGlkeCA9IDAKICAgICAgICAgICAgaWYgaWR4ID09IHNlbGYuaWR4OgogICAgICAgICAgICAgICAgIyBFbmQgb2YgRmlsZQogICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICBzZWxmLmlkeCA9IGlkeAogICAgICAgIHJldHVybiBpdGVtCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgemlwZmlsZSBjb21wYXRpYmxlIFRhckZpbGUgY2xhc3MKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpUQVJfUExBSU4gPSAwICAgICAgICAgICAjIHppcGZpbGUuWklQX1NUT1JFRApUQVJfR1pJUFBFRCA9IDggICAgICAgICAjIHppcGZpbGUuWklQX0RFRkxBVEVECmNsYXNzIFRhckZpbGVDb21wYXQ6CiAgICAiIiJUYXJGaWxlIGNsYXNzIGNvbXBhdGlibGUgd2l0aCBzdGFuZGFyZCBtb2R1bGUgemlwZmlsZSdzCiAgICAgICBaaXBGaWxlIGNsYXNzLgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZSwgbW9kZT0iciIsIGNvbXByZXNzaW9uPVRBUl9QTEFJTik6CiAgICAgICAgaWYgY29tcHJlc3Npb24gPT0gVEFSX1BMQUlOOgogICAgICAgICAgICBzZWxmLnRhcmZpbGUgPSBUYXJGaWxlLnRhcm9wZW4oZmlsZSwgbW9kZSkKICAgICAgICBlbGlmIGNvbXByZXNzaW9uID09IFRBUl9HWklQUEVEOgogICAgICAgICAgICBzZWxmLnRhcmZpbGUgPSBUYXJGaWxlLmd6b3BlbihmaWxlLCBtb2RlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoInVua25vd24gY29tcHJlc3Npb24gY29uc3RhbnQiKQogICAgICAgIGlmIG1vZGVbMDoxXSA9PSAiciI6CiAgICAgICAgICAgIG1lbWJlcnMgPSBzZWxmLnRhcmZpbGUuZ2V0bWVtYmVycygpCiAgICAgICAgICAgIGZvciBtIGluIG1lbWJlcnM6CiAgICAgICAgICAgICAgICBtLmZpbGVuYW1lID0gbS5uYW1lCiAgICAgICAgICAgICAgICBtLmZpbGVfc2l6ZSA9IG0uc2l6ZQogICAgICAgICAgICAgICAgbS5kYXRlX3RpbWUgPSB0aW1lLmdtdGltZShtLm10aW1lKVs6Nl0KICAgIGRlZiBuYW1lbGlzdChzZWxmKToKICAgICAgICByZXR1cm4gbWFwKGxhbWJkYSBtOiBtLm5hbWUsIHNlbGYuaW5mb2xpc3QoKSkKICAgIGRlZiBpbmZvbGlzdChzZWxmKToKICAgICAgICByZXR1cm4gZmlsdGVyKGxhbWJkYSBtOiBtLnR5cGUgaW4gUkVHVUxBUl9UWVBFUywKICAgICAgICAgICAgICAgICAgICAgIHNlbGYudGFyZmlsZS5nZXRtZW1iZXJzKCkpCiAgICBkZWYgcHJpbnRkaXIoc2VsZik6CiAgICAgICAgc2VsZi50YXJmaWxlLmxpc3QoKQogICAgZGVmIHRlc3R6aXAoc2VsZik6CiAgICAgICAgcmV0dXJuCiAgICBkZWYgZ2V0aW5mbyhzZWxmLCBuYW1lKToKICAgICAgICByZXR1cm4gc2VsZi50YXJmaWxlLmdldG1lbWJlcihuYW1lKQogICAgZGVmIHJlYWQoc2VsZiwgbmFtZSk6CiAgICAgICAgcmV0dXJuIHNlbGYudGFyZmlsZS5leHRyYWN0ZmlsZShzZWxmLnRhcmZpbGUuZ2V0bWVtYmVyKG5hbWUpKS5yZWFkKCkKICAgIGRlZiB3cml0ZShzZWxmLCBmaWxlbmFtZSwgYXJjbmFtZT1Ob25lLCBjb21wcmVzc190eXBlPU5vbmUpOgogICAgICAgIHNlbGYudGFyZmlsZS5hZGQoZmlsZW5hbWUsIGFyY25hbWUpCiAgICBkZWYgd3JpdGVzdHIoc2VsZiwgemluZm8sIGJ5dGVzKToKICAgICAgICBmcm9tIGlvIGltcG9ydCBTdHJpbmdJTwogICAgICAgIGltcG9ydCBjYWxlbmRhcgogICAgICAgIHppbmZvLm5hbWUgPSB6aW5mby5maWxlbmFtZQogICAgICAgIHppbmZvLnNpemUgPSB6aW5mby5maWxlX3NpemUKICAgICAgICB6aW5mby5tdGltZSA9IGNhbGVuZGFyLnRpbWVnbSh6aW5mby5kYXRlX3RpbWUpCiAgICAgICAgc2VsZi50YXJmaWxlLmFkZGZpbGUoemluZm8sIFN0cmluZ0lPKGJ5dGVzKSkKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICBzZWxmLnRhcmZpbGUuY2xvc2UoKQojY2xhc3MgVGFyRmlsZUNvbXBhdAoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgZXhwb3J0ZWQgZnVuY3Rpb25zCiMtLS0tLS0tLS0tLS0tLS0tLS0tLQpkZWYgaXNfdGFyZmlsZShuYW1lKToKICAgICIiIlJldHVybiBUcnVlIGlmIG5hbWUgcG9pbnRzIHRvIGEgdGFyIGFyY2hpdmUgdGhhdCB3ZQogICAgICAgYXJlIGFibGUgdG8gaGFuZGxlLCBlbHNlIHJldHVybiBGYWxzZS4KICAgICIiIgogICAgdHJ5OgogICAgICAgIHQgPSBvcGVuKG5hbWUpCiAgICAgICAgdC5jbG9zZSgpCiAgICAgICAgcmV0dXJuIFRydWUKICAgIGV4Y2VwdCBUYXJFcnJvcjoKICAgICAgICByZXR1cm4gRmFsc2UKCmJsdG5fb3BlbiA9IG9wZW4Kb3BlbiA9IFRhckZpbGUub3Blbgo=