IyEvdXNyL2Jpbi9lbnYgcHl0aG9uDQojIC0qLSBjb2Rpbmc6IGlzby04ODU5LTEgLSotDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyB0YXJmaWxlLnB5DQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBDb3B5cmlnaHQgKEMpIDIwMDIgTGFycyBHdXN05GJlbCA8bGFyc0BndXN0YWViZWwuZGU+DQojIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQojDQojIFBlcm1pc3Npb24gIGlzICBoZXJlYnkgZ3JhbnRlZCwgIGZyZWUgIG9mIGNoYXJnZSwgIHRvICBhbnkgcGVyc29uDQojIG9idGFpbmluZyBhICBjb3B5IG9mICB0aGlzIHNvZnR3YXJlICBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uDQojIGZpbGVzICAodGhlICAiU29mdHdhcmUiKSwgIHRvICAgZGVhbCAgaW4gIHRoZSAgU29mdHdhcmUgICB3aXRob3V0DQojIHJlc3RyaWN0aW9uLCAgaW5jbHVkaW5nICB3aXRob3V0IGxpbWl0YXRpb24gIHRoZSAgcmlnaHRzIHRvICB1c2UsDQojIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsDQojIGNvcGllcyAgb2YgIHRoZSAgU29mdHdhcmUsICBhbmQgdG8gIHBlcm1pdCAgcGVyc29ucyAgdG8gIHdob20gdGhlDQojIFNvZnR3YXJlICBpcyAgZnVybmlzaGVkICB0byAgZG8gIHNvLCAgc3ViamVjdCAgdG8gIHRoZSAgZm9sbG93aW5nDQojIGNvbmRpdGlvbnM6DQojDQojIFRoZSBhYm92ZSBjb3B5cmlnaHQgIG5vdGljZSBhbmQgdGhpcyAgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgIGJlDQojIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLg0KIw0KIyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTICBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZICBLSU5ELA0KIyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyAgQlVUIE5PVCBMSU1JVEVEIFRPICBUSEUgV0FSUkFOVElFUw0KIyBPRiAgTUVSQ0hBTlRBQklMSVRZLCAgRklUTkVTUyAgIEZPUiAgQSAgUEFSVElDVUxBUiAgIFBVUlBPU0UgIEFORA0KIyBOT05JTkZSSU5HRU1FTlQuICBJTiAgTk8gIEVWRU5UIFNIQUxMICBUSEUgIEFVVEhPUlMgIE9SIENPUFlSSUdIVA0KIyBIT0xERVJTICBCRSBMSUFCTEUgIEZPUiBBTlkgIENMQUlNLCBEQU1BR0VTICBPUiBPVEhFUiAgTElBQklMSVRZLA0KIyBXSEVUSEVSICBJTiBBTiAgQUNUSU9OIE9GICBDT05UUkFDVCwgVE9SVCAgT1IgT1RIRVJXSVNFLCAgQVJJU0lORw0KIyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SDQojIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4NCiMNCiIiIlJlYWQgZnJvbSBhbmQgd3JpdGUgdG8gdGFyIGZvcm1hdCBhcmNoaXZlcy4NCiIiIg0KDQpfX3ZlcnNpb25fXyA9ICIkUmV2aXNpb24kIg0KIyAkU291cmNlJA0KDQp2ZXJzaW9uICAgICA9ICIwLjkuMCINCl9fYXV0aG9yX18gID0gIkxhcnMgR3VzdORiZWwgKGxhcnNAZ3VzdGFlYmVsLmRlKSINCl9fZGF0ZV9fICAgID0gIiREYXRlJCINCl9fY3ZzaWRfXyAgID0gIiRJZCQiDQpfX2NyZWRpdHNfXyA9ICJHdXN0YXZvIE5pZW1leWVyLCBOaWVscyBHdXN05GJlbCwgUmljaGFyZCBUb3duc2VuZC4iDQoNCiMtLS0tLS0tLS0NCiMgSW1wb3J0cw0KIy0tLS0tLS0tLQ0KaW1wb3J0IHN5cw0KaW1wb3J0IG9zDQppbXBvcnQgc2h1dGlsDQppbXBvcnQgc3RhdA0KaW1wb3J0IGVycm5vDQppbXBvcnQgdGltZQ0KaW1wb3J0IHN0cnVjdA0KaW1wb3J0IGNvcHkNCmltcG9ydCByZQ0KaW1wb3J0IG9wZXJhdG9yDQoNCnRyeToNCiAgICBpbXBvcnQgZ3JwLCBwd2QNCmV4Y2VwdCBJbXBvcnRFcnJvcjoNCiAgICBncnAgPSBwd2QgPSBOb25lDQoNCiMgZnJvbSB0YXJmaWxlIGltcG9ydCAqDQpfX2FsbF9fID0gWyJUYXJGaWxlIiwgIlRhckluZm8iLCAiaXNfdGFyZmlsZSIsICJUYXJFcnJvciJdDQoNCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgdGFyIGNvbnN0YW50cw0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KTlVMID0gIlwwIiAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBudWxsIGNoYXJhY3Rlcg0KQkxPQ0tTSVpFID0gNTEyICAgICAgICAgICAgICAgICAjIGxlbmd0aCBvZiBwcm9jZXNzaW5nIGJsb2Nrcw0KUkVDT1JEU0laRSA9IEJMT0NLU0laRSAqIDIwICAgICAjIGxlbmd0aCBvZiByZWNvcmRzDQpHTlVfTUFHSUMgPSAidXN0YXIgIFwwIiAgICAgICAgICMgbWFnaWMgZ251IHRhciBzdHJpbmcNClBPU0lYX01BR0lDID0gInVzdGFyXHgwMDAwIiAgICAgIyBtYWdpYyBwb3NpeCB0YXIgc3RyaW5nDQoNCkxFTkdUSF9OQU1FID0gMTAwICAgICAgICAgICAgICAgIyBtYXhpbXVtIGxlbmd0aCBvZiBhIGZpbGVuYW1lDQpMRU5HVEhfTElOSyA9IDEwMCAgICAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBsaW5rbmFtZQ0KTEVOR1RIX1BSRUZJWCA9IDE1NSAgICAgICAgICAgICAjIG1heGltdW0gbGVuZ3RoIG9mIHRoZSBwcmVmaXggZmllbGQNCg0KUkVHVFlQRSA9ICIwIiAgICAgICAgICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZQ0KQVJFR1RZUEUgPSAiXDAiICAgICAgICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZQ0KTE5LVFlQRSA9ICIxIiAgICAgICAgICAgICAgICAgICAjIGxpbmsgKGluc2lkZSB0YXJmaWxlKQ0KU1lNVFlQRSA9ICIyIiAgICAgICAgICAgICAgICAgICAjIHN5bWJvbGljIGxpbmsNCkNIUlRZUEUgPSAiMyIgICAgICAgICAgICAgICAgICAgIyBjaGFyYWN0ZXIgc3BlY2lhbCBkZXZpY2UNCkJMS1RZUEUgPSAiNCIgICAgICAgICAgICAgICAgICAgIyBibG9jayBzcGVjaWFsIGRldmljZQ0KRElSVFlQRSA9ICI1IiAgICAgICAgICAgICAgICAgICAjIGRpcmVjdG9yeQ0KRklGT1RZUEUgPSAiNiIgICAgICAgICAgICAgICAgICAjIGZpZm8gc3BlY2lhbCBkZXZpY2UNCkNPTlRUWVBFID0gIjciICAgICAgICAgICAgICAgICAgIyBjb250aWd1b3VzIGZpbGUNCg0KR05VVFlQRV9MT05HTkFNRSA9ICJMIiAgICAgICAgICAjIEdOVSB0YXIgbG9uZ25hbWUNCkdOVVRZUEVfTE9OR0xJTksgPSAiSyIgICAgICAgICAgIyBHTlUgdGFyIGxvbmdsaW5rDQpHTlVUWVBFX1NQQVJTRSA9ICJTIiAgICAgICAgICAgICMgR05VIHRhciBzcGFyc2UgZmlsZQ0KDQpYSERUWVBFID0gIngiICAgICAgICAgICAgICAgICAgICMgUE9TSVguMS0yMDAxIGV4dGVuZGVkIGhlYWRlcg0KWEdMVFlQRSA9ICJnIiAgICAgICAgICAgICAgICAgICAjIFBPU0lYLjEtMjAwMSBnbG9iYWwgaGVhZGVyDQpTT0xBUklTX1hIRFRZUEUgPSAiWCIgICAgICAgICAgICMgU29sYXJpcyBleHRlbmRlZCBoZWFkZXINCg0KVVNUQVJfRk9STUFUID0gMCAgICAgICAgICAgICAgICAjIFBPU0lYLjEtMTk4OCAodXN0YXIpIGZvcm1hdA0KR05VX0ZPUk1BVCA9IDEgICAgICAgICAgICAgICAgICAjIEdOVSB0YXIgZm9ybWF0DQpQQVhfRk9STUFUID0gMiAgICAgICAgICAgICAgICAgICMgUE9TSVguMS0yMDAxIChwYXgpIGZvcm1hdA0KREVGQVVMVF9GT1JNQVQgPSBHTlVfRk9STUFUDQoNCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgdGFyZmlsZSBjb25zdGFudHMNCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgRmlsZSB0eXBlcyB0aGF0IHRhcmZpbGUgc3VwcG9ydHM6DQpTVVBQT1JURURfVFlQRVMgPSAoUkVHVFlQRSwgQVJFR1RZUEUsIExOS1RZUEUsDQogICAgICAgICAgICAgICAgICAgU1lNVFlQRSwgRElSVFlQRSwgRklGT1RZUEUsDQogICAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIENIUlRZUEUsIEJMS1RZUEUsDQogICAgICAgICAgICAgICAgICAgR05VVFlQRV9MT05HTkFNRSwgR05VVFlQRV9MT05HTElOSywNCiAgICAgICAgICAgICAgICAgICBHTlVUWVBFX1NQQVJTRSkNCg0KIyBGaWxlIHR5cGVzIHRoYXQgd2lsbCBiZSB0cmVhdGVkIGFzIGEgcmVndWxhciBmaWxlLg0KUkVHVUxBUl9UWVBFUyA9IChSRUdUWVBFLCBBUkVHVFlQRSwNCiAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIEdOVVRZUEVfU1BBUlNFKQ0KDQojIEZpbGUgdHlwZXMgdGhhdCBhcmUgcGFydCBvZiB0aGUgR05VIHRhciBmb3JtYXQuDQpHTlVfVFlQRVMgPSAoR05VVFlQRV9MT05HTkFNRSwgR05VVFlQRV9MT05HTElOSywNCiAgICAgICAgICAgICBHTlVUWVBFX1NQQVJTRSkNCg0KIyBGaWVsZHMgZnJvbSBhIHBheCBoZWFkZXIgdGhhdCBvdmVycmlkZSBhIFRhckluZm8gYXR0cmlidXRlLg0KUEFYX0ZJRUxEUyA9ICgicGF0aCIsICJsaW5rcGF0aCIsICJzaXplIiwgIm10aW1lIiwNCiAgICAgICAgICAgICAgInVpZCIsICJnaWQiLCAidW5hbWUiLCAiZ25hbWUiKQ0KDQojIEZpZWxkcyBpbiBhIHBheCBoZWFkZXIgdGhhdCBhcmUgbnVtYmVycywgYWxsIG90aGVyIGZpZWxkcw0KIyBhcmUgdHJlYXRlZCBhcyBzdHJpbmdzLg0KUEFYX05VTUJFUl9GSUVMRFMgPSB7DQogICAgImF0aW1lIjogZmxvYXQsDQogICAgImN0aW1lIjogZmxvYXQsDQogICAgIm10aW1lIjogZmxvYXQsDQogICAgInVpZCI6IGludCwNCiAgICAiZ2lkIjogaW50LA0KICAgICJzaXplIjogaW50DQp9DQoNCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgQml0cyB1c2VkIGluIHRoZSBtb2RlIGZpZWxkLCB2YWx1ZXMgaW4gb2N0YWwuDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpTX0lGTE5LID0gMDEyMDAwMCAgICAgICAgIyBzeW1ib2xpYyBsaW5rDQpTX0lGUkVHID0gMDEwMDAwMCAgICAgICAgIyByZWd1bGFyIGZpbGUNClNfSUZCTEsgPSAwMDYwMDAwICAgICAgICAjIGJsb2NrIGRldmljZQ0KU19JRkRJUiA9IDAwNDAwMDAgICAgICAgICMgZGlyZWN0b3J5DQpTX0lGQ0hSID0gMDAyMDAwMCAgICAgICAgIyBjaGFyYWN0ZXIgZGV2aWNlDQpTX0lGSUZPID0gMDAxMDAwMCAgICAgICAgIyBmaWZvDQoNClRTVUlEICAgPSAwNDAwMCAgICAgICAgICAjIHNldCBVSUQgb24gZXhlY3V0aW9uDQpUU0dJRCAgID0gMDIwMDAgICAgICAgICAgIyBzZXQgR0lEIG9uIGV4ZWN1dGlvbg0KVFNWVFggICA9IDAxMDAwICAgICAgICAgICMgcmVzZXJ2ZWQNCg0KVFVSRUFEICA9IDA0MDAgICAgICAgICAgICMgcmVhZCBieSBvd25lcg0KVFVXUklURSA9IDAyMDAgICAgICAgICAgICMgd3JpdGUgYnkgb3duZXINClRVRVhFQyAgPSAwMTAwICAgICAgICAgICAjIGV4ZWN1dGUvc2VhcmNoIGJ5IG93bmVyDQpUR1JFQUQgID0gMDA0MCAgICAgICAgICAgIyByZWFkIGJ5IGdyb3VwDQpUR1dSSVRFID0gMDAyMCAgICAgICAgICAgIyB3cml0ZSBieSBncm91cA0KVEdFWEVDICA9IDAwMTAgICAgICAgICAgICMgZXhlY3V0ZS9zZWFyY2ggYnkgZ3JvdXANClRPUkVBRCAgPSAwMDA0ICAgICAgICAgICAjIHJlYWQgYnkgb3RoZXINClRPV1JJVEUgPSAwMDAyICAgICAgICAgICAjIHdyaXRlIGJ5IG90aGVyDQpUT0VYRUMgID0gMDAwMSAgICAgICAgICAgIyBleGVjdXRlL3NlYXJjaCBieSBvdGhlcg0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIGluaXRpYWxpemF0aW9uDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpFTkNPRElORyA9IHN5cy5nZXRmaWxlc3lzdGVtZW5jb2RpbmcoKQ0KaWYgRU5DT0RJTkcgaXMgTm9uZToNCiAgICBFTkNPRElORyA9IHN5cy5nZXRkZWZhdWx0ZW5jb2RpbmcoKQ0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIFNvbWUgdXNlZnVsIGZ1bmN0aW9ucw0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpkZWYgc3RuKHMsIGxlbmd0aCk6DQogICAgIiIiQ29udmVydCBhIHB5dGhvbiBzdHJpbmcgdG8gYSBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nIGJ1ZmZlci4NCiAgICAiIiINCiAgICByZXR1cm4gc1s6bGVuZ3RoXSArIChsZW5ndGggLSBsZW4ocykpICogTlVMDQoNCmRlZiBudHMocyk6DQogICAgIiIiQ29udmVydCBhIG51bGwtdGVybWluYXRlZCBzdHJpbmcgZmllbGQgdG8gYSBweXRob24gc3RyaW5nLg0KICAgICIiIg0KICAgICMgVXNlIHRoZSBzdHJpbmcgdXAgdG8gdGhlIGZpcnN0IG51bGwgY2hhci4NCiAgICBwID0gcy5maW5kKCJcMCIpDQogICAgaWYgcCA9PSAtMToNCiAgICAgICAgcmV0dXJuIHMNCiAgICByZXR1cm4gc1s6cF0NCg0KZGVmIG50aShzKToNCiAgICAiIiJDb252ZXJ0IGEgbnVtYmVyIGZpZWxkIHRvIGEgcHl0aG9uIG51bWJlci4NCiAgICAiIiINCiAgICAjIFRoZXJlIGFyZSB0d28gcG9zc2libGUgZW5jb2RpbmdzIGZvciBhIG51bWJlciBmaWVsZCwgc2VlDQogICAgIyBpdG4oKSBiZWxvdy4NCiAgICBpZiBzWzBdICE9IGNocigwMjAwKToNCiAgICAgICAgdHJ5Og0KICAgICAgICAgICAgbiA9IGludChudHMocykgb3IgIjAiLCA4KQ0KICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoNCiAgICAgICAgICAgIHJhaXNlIEludmFsaWRIZWFkZXJFcnJvcigiaW52YWxpZCBoZWFkZXIiKQ0KICAgIGVsc2U6DQogICAgICAgIG4gPSAwTA0KICAgICAgICBmb3IgaSBpbiB4cmFuZ2UobGVuKHMpIC0gMSk6DQogICAgICAgICAgICBuIDw8PSA4DQogICAgICAgICAgICBuICs9IG9yZChzW2kgKyAxXSkNCiAgICByZXR1cm4gbg0KDQpkZWYgaXRuKG4sIGRpZ2l0cz04LCBmb3JtYXQ9REVGQVVMVF9GT1JNQVQpOg0KICAgICIiIkNvbnZlcnQgYSBweXRob24gbnVtYmVyIHRvIGEgbnVtYmVyIGZpZWxkLg0KICAgICIiIg0KICAgICMgUE9TSVggMTAwMy4xLTE5ODggcmVxdWlyZXMgbnVtYmVycyB0byBiZSBlbmNvZGVkIGFzIGEgc3RyaW5nIG9mDQogICAgIyBvY3RhbCBkaWdpdHMgZm9sbG93ZWQgYnkgYSBudWxsLWJ5dGUsIHRoaXMgYWxsb3dzIHZhbHVlcyB1cCB0bw0KICAgICMgKDgqKihkaWdpdHMtMSkpLTEuIEdOVSB0YXIgYWxsb3dzIHN0b3JpbmcgbnVtYmVycyBncmVhdGVyIHRoYW4NCiAgICAjIHRoYXQgaWYgbmVjZXNzYXJ5LiBBIGxlYWRpbmcgMDIwMCBieXRlIGluZGljYXRlcyB0aGlzIHBhcnRpY3VsYXINCiAgICAjIGVuY29kaW5nLCB0aGUgZm9sbG93aW5nIGRpZ2l0cy0xIGJ5dGVzIGFyZSBhIGJpZy1lbmRpYW4NCiAgICAjIHJlcHJlc2VudGF0aW9uLiBUaGlzIGFsbG93cyB2YWx1ZXMgdXAgdG8gKDI1NioqKGRpZ2l0cy0xKSktMS4NCiAgICBpZiAwIDw9IG4gPCA4ICoqIChkaWdpdHMgLSAxKToNCiAgICAgICAgcyA9ICIlMCpvIiAlIChkaWdpdHMgLSAxLCBuKSArIE5VTA0KICAgIGVsc2U6DQogICAgICAgIGlmIGZvcm1hdCAhPSBHTlVfRk9STUFUIG9yIG4gPj0gMjU2ICoqIChkaWdpdHMgLSAxKToNCiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm92ZXJmbG93IGluIG51bWJlciBmaWVsZCIpDQoNCiAgICAgICAgaWYgbiA8IDA6DQogICAgICAgICAgICAjIFhYWCBXZSBtaW1pYyBHTlUgdGFyJ3MgYmVoYXZpb3VyIHdpdGggbmVnYXRpdmUgbnVtYmVycywNCiAgICAgICAgICAgICMgdGhpcyBjb3VsZCByYWlzZSBPdmVyZmxvd0Vycm9yLg0KICAgICAgICAgICAgbiA9IHN0cnVjdC51bnBhY2soIkwiLCBzdHJ1Y3QucGFjaygibCIsIG4pKVswXQ0KDQogICAgICAgIHMgPSAiIg0KICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoZGlnaXRzIC0gMSk6DQogICAgICAgICAgICBzID0gY2hyKG4gJiAwMzc3KSArIHMNCiAgICAgICAgICAgIG4gPj49IDgNCiAgICAgICAgcyA9IGNocigwMjAwKSArIHMNCiAgICByZXR1cm4gcw0KDQpkZWYgdXRzKHMsIGVuY29kaW5nLCBlcnJvcnMpOg0KICAgICIiIkNvbnZlcnQgYSB1bmljb2RlIG9iamVjdCB0byBhIHN0cmluZy4NCiAgICAiIiINCiAgICBpZiBlcnJvcnMgPT0gInV0Zi04IjoNCiAgICAgICAgIyBBbiBleHRyYSBlcnJvciBoYW5kbGVyIHNpbWlsYXIgdG8gdGhlIC1vIGludmFsaWQ9VVRGLTggb3B0aW9uDQogICAgICAgICMgaW4gUE9TSVguMS0yMDAxLiBSZXBsYWNlIHVudHJhbnNsYXRhYmxlIGNoYXJhY3RlcnMgd2l0aCB0aGVpcg0KICAgICAgICAjIFVURi04IHJlcHJlc2VudGF0aW9uLg0KICAgICAgICB0cnk6DQogICAgICAgICAgICByZXR1cm4gcy5lbmNvZGUoZW5jb2RpbmcsICJzdHJpY3QiKQ0KICAgICAgICBleGNlcHQgVW5pY29kZUVuY29kZUVycm9yOg0KICAgICAgICAgICAgeCA9IFtdDQogICAgICAgICAgICBmb3IgYyBpbiBzOg0KICAgICAgICAgICAgICAgIHRyeToNCiAgICAgICAgICAgICAgICAgICAgeC5hcHBlbmQoYy5lbmNvZGUoZW5jb2RpbmcsICJzdHJpY3QiKSkNCiAgICAgICAgICAgICAgICBleGNlcHQgVW5pY29kZUVuY29kZUVycm9yOg0KICAgICAgICAgICAgICAgICAgICB4LmFwcGVuZChjLmVuY29kZSgidXRmOCIpKQ0KICAgICAgICAgICAgcmV0dXJuICIiLmpvaW4oeCkNCiAgICBlbHNlOg0KICAgICAgICByZXR1cm4gcy5lbmNvZGUoZW5jb2RpbmcsIGVycm9ycykNCg0KZGVmIGNhbGNfY2hrc3VtcyhidWYpOg0KICAgICIiIkNhbGN1bGF0ZSB0aGUgY2hlY2tzdW0gZm9yIGEgbWVtYmVyJ3MgaGVhZGVyIGJ5IHN1bW1pbmcgdXAgYWxsDQogICAgICAgY2hhcmFjdGVycyBleGNlcHQgZm9yIHRoZSBjaGtzdW0gZmllbGQgd2hpY2ggaXMgdHJlYXRlZCBhcyBpZg0KICAgICAgIGl0IHdhcyBmaWxsZWQgd2l0aCBzcGFjZXMuIEFjY29yZGluZyB0byB0aGUgR05VIHRhciBzb3VyY2VzLA0KICAgICAgIHNvbWUgdGFycyAoU3VuIGFuZCBOZVhUKSBjYWxjdWxhdGUgY2hrc3VtIHdpdGggc2lnbmVkIGNoYXIsDQogICAgICAgd2hpY2ggd2lsbCBiZSBkaWZmZXJlbnQgaWYgdGhlcmUgYXJlIGNoYXJzIGluIHRoZSBidWZmZXIgd2l0aA0KICAgICAgIHRoZSBoaWdoIGJpdCBzZXQuIFNvIHdlIGNhbGN1bGF0ZSB0d28gY2hlY2tzdW1zLCB1bnNpZ25lZCBhbmQNCiAgICAgICBzaWduZWQuDQogICAgIiIiDQogICAgdW5zaWduZWRfY2hrc3VtID0gMjU2ICsgc3VtKHN0cnVjdC51bnBhY2soIjE0OEIiLCBidWZbOjE0OF0pICsgc3RydWN0LnVucGFjaygiMzU2QiIsIGJ1ZlsxNTY6NTEyXSkpDQogICAgc2lnbmVkX2Noa3N1bSA9IDI1NiArIHN1bShzdHJ1Y3QudW5wYWNrKCIxNDhiIiwgYnVmWzoxNDhdKSArIHN0cnVjdC51bnBhY2soIjM1NmIiLCBidWZbMTU2OjUxMl0pKQ0KICAgIHJldHVybiB1bnNpZ25lZF9jaGtzdW0sIHNpZ25lZF9jaGtzdW0NCg0KZGVmIGNvcHlmaWxlb2JqKHNyYywgZHN0LCBsZW5ndGg9Tm9uZSk6DQogICAgIiIiQ29weSBsZW5ndGggYnl0ZXMgZnJvbSBmaWxlb2JqIHNyYyB0byBmaWxlb2JqIGRzdC4NCiAgICAgICBJZiBsZW5ndGggaXMgTm9uZSwgY29weSB0aGUgZW50aXJlIGNvbnRlbnQuDQogICAgIiIiDQogICAgaWYgbGVuZ3RoID09IDA6DQogICAgICAgIHJldHVybg0KICAgIGlmIGxlbmd0aCBpcyBOb25lOg0KICAgICAgICBzaHV0aWwuY29weWZpbGVvYmooc3JjLCBkc3QpDQogICAgICAgIHJldHVybg0KDQogICAgQlVGU0laRSA9IDE2ICogMTAyNA0KICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGxlbmd0aCwgQlVGU0laRSkNCiAgICBmb3IgYiBpbiB4cmFuZ2UoYmxvY2tzKToNCiAgICAgICAgYnVmID0gc3JjLnJlYWQoQlVGU0laRSkNCiAgICAgICAgaWYgbGVuKGJ1ZikgPCBCVUZTSVpFOg0KICAgICAgICAgICAgcmFpc2UgSU9FcnJvcigiZW5kIG9mIGZpbGUgcmVhY2hlZCIpDQogICAgICAgIGRzdC53cml0ZShidWYpDQoNCiAgICBpZiByZW1haW5kZXIgIT0gMDoNCiAgICAgICAgYnVmID0gc3JjLnJlYWQocmVtYWluZGVyKQ0KICAgICAgICBpZiBsZW4oYnVmKSA8IHJlbWFpbmRlcjoNCiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoImVuZCBvZiBmaWxlIHJlYWNoZWQiKQ0KICAgICAgICBkc3Qud3JpdGUoYnVmKQ0KICAgIHJldHVybg0KDQpmaWxlbW9kZV90YWJsZSA9ICgNCiAgICAoKFNfSUZMTkssICAgICAgImwiKSwNCiAgICAgKFNfSUZSRUcsICAgICAgIi0iKSwNCiAgICAgKFNfSUZCTEssICAgICAgImIiKSwNCiAgICAgKFNfSUZESVIsICAgICAgImQiKSwNCiAgICAgKFNfSUZDSFIsICAgICAgImMiKSwNCiAgICAgKFNfSUZJRk8sICAgICAgInAiKSksDQoNCiAgICAoKFRVUkVBRCwgICAgICAgInIiKSwpLA0KICAgICgoVFVXUklURSwgICAgICAidyIpLCksDQogICAgKChUVUVYRUN8VFNVSUQsICJzIiksDQogICAgIChUU1VJRCwgICAgICAgICJTIiksDQogICAgIChUVUVYRUMsICAgICAgICJ4IikpLA0KDQogICAgKChUR1JFQUQsICAgICAgICJyIiksKSwNCiAgICAoKFRHV1JJVEUsICAgICAgInciKSwpLA0KICAgICgoVEdFWEVDfFRTR0lELCAicyIpLA0KICAgICAoVFNHSUQsICAgICAgICAiUyIpLA0KICAgICAoVEdFWEVDLCAgICAgICAieCIpKSwNCg0KICAgICgoVE9SRUFELCAgICAgICAiciIpLCksDQogICAgKChUT1dSSVRFLCAgICAgICJ3IiksKSwNCiAgICAoKFRPRVhFQ3xUU1ZUWCwgInQiKSwNCiAgICAgKFRTVlRYLCAgICAgICAgIlQiKSwNCiAgICAgKFRPRVhFQywgICAgICAgIngiKSkNCikNCg0KZGVmIGZpbGVtb2RlKG1vZGUpOg0KICAgICIiIkNvbnZlcnQgYSBmaWxlJ3MgbW9kZSB0byBhIHN0cmluZyBvZiB0aGUgZm9ybQ0KICAgICAgIC1yd3hyd3hyd3guDQogICAgICAgVXNlZCBieSBUYXJGaWxlLmxpc3QoKQ0KICAgICIiIg0KICAgIHBlcm0gPSBbXQ0KICAgIGZvciB0YWJsZSBpbiBmaWxlbW9kZV90YWJsZToNCiAgICAgICAgZm9yIGJpdCwgY2hhciBpbiB0YWJsZToNCiAgICAgICAgICAgIGlmIG1vZGUgJiBiaXQgPT0gYml0Og0KICAgICAgICAgICAgICAgIHBlcm0uYXBwZW5kKGNoYXIpDQogICAgICAgICAgICAgICAgYnJlYWsNCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIHBlcm0uYXBwZW5kKCItIikNCiAgICByZXR1cm4gIiIuam9pbihwZXJtKQ0KDQpjbGFzcyBUYXJFcnJvcihFeGNlcHRpb24pOg0KICAgICIiIkJhc2UgZXhjZXB0aW9uLiIiIg0KICAgIHBhc3MNCmNsYXNzIEV4dHJhY3RFcnJvcihUYXJFcnJvcik6DQogICAgIiIiR2VuZXJhbCBleGNlcHRpb24gZm9yIGV4dHJhY3QgZXJyb3JzLiIiIg0KICAgIHBhc3MNCmNsYXNzIFJlYWRFcnJvcihUYXJFcnJvcik6DQogICAgIiIiRXhjZXB0aW9uIGZvciB1bnJlYWRibGUgdGFyIGFyY2hpdmVzLiIiIg0KICAgIHBhc3MNCmNsYXNzIENvbXByZXNzaW9uRXJyb3IoVGFyRXJyb3IpOg0KICAgICIiIkV4Y2VwdGlvbiBmb3IgdW5hdmFpbGFibGUgY29tcHJlc3Npb24gbWV0aG9kcy4iIiINCiAgICBwYXNzDQpjbGFzcyBTdHJlYW1FcnJvcihUYXJFcnJvcik6DQogICAgIiIiRXhjZXB0aW9uIGZvciB1bnN1cHBvcnRlZCBvcGVyYXRpb25zIG9uIHN0cmVhbS1saWtlIFRhckZpbGVzLiIiIg0KICAgIHBhc3MNCmNsYXNzIEhlYWRlckVycm9yKFRhckVycm9yKToNCiAgICAiIiJCYXNlIGV4Y2VwdGlvbiBmb3IgaGVhZGVyIGVycm9ycy4iIiINCiAgICBwYXNzDQpjbGFzcyBFbXB0eUhlYWRlckVycm9yKEhlYWRlckVycm9yKToNCiAgICAiIiJFeGNlcHRpb24gZm9yIGVtcHR5IGhlYWRlcnMuIiIiDQogICAgcGFzcw0KY2xhc3MgVHJ1bmNhdGVkSGVhZGVyRXJyb3IoSGVhZGVyRXJyb3IpOg0KICAgICIiIkV4Y2VwdGlvbiBmb3IgdHJ1bmNhdGVkIGhlYWRlcnMuIiIiDQogICAgcGFzcw0KY2xhc3MgRU9GSGVhZGVyRXJyb3IoSGVhZGVyRXJyb3IpOg0KICAgICIiIkV4Y2VwdGlvbiBmb3IgZW5kIG9mIGZpbGUgaGVhZGVycy4iIiINCiAgICBwYXNzDQpjbGFzcyBJbnZhbGlkSGVhZGVyRXJyb3IoSGVhZGVyRXJyb3IpOg0KICAgICIiIkV4Y2VwdGlvbiBmb3IgaW52YWxpZCBoZWFkZXJzLiIiIg0KICAgIHBhc3MNCmNsYXNzIFN1YnNlcXVlbnRIZWFkZXJFcnJvcihIZWFkZXJFcnJvcik6DQogICAgIiIiRXhjZXB0aW9uIGZvciBtaXNzaW5nIGFuZCBpbnZhbGlkIGV4dGVuZGVkIGhlYWRlcnMuIiIiDQogICAgcGFzcw0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIGludGVybmFsIHN0cmVhbSBpbnRlcmZhY2UNCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCmNsYXNzIF9Mb3dMZXZlbEZpbGU6DQogICAgIiIiTG93LWxldmVsIGZpbGUgb2JqZWN0LiBTdXBwb3J0cyByZWFkaW5nIGFuZCB3cml0aW5nLg0KICAgICAgIEl0IGlzIHVzZWQgaW5zdGVhZCBvZiBhIHJlZ3VsYXIgZmlsZSBvYmplY3QgZm9yIHN0cmVhbWluZw0KICAgICAgIGFjY2Vzcy4NCiAgICAiIiINCg0KICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lLCBtb2RlKToNCiAgICAgICAgbW9kZSA9IHsNCiAgICAgICAgICAgICJyIjogb3MuT19SRE9OTFksDQogICAgICAgICAgICAidyI6IG9zLk9fV1JPTkxZIHwgb3MuT19DUkVBVCB8IG9zLk9fVFJVTkMsDQogICAgICAgIH1bbW9kZV0NCiAgICAgICAgaWYgaGFzYXR0cihvcywgIk9fQklOQVJZIik6DQogICAgICAgICAgICBtb2RlIHw9IG9zLk9fQklOQVJZDQogICAgICAgIHNlbGYuZmQgPSBvcy5vcGVuKG5hbWUsIG1vZGUsIDA2NjYpDQoNCiAgICBkZWYgY2xvc2Uoc2VsZik6DQogICAgICAgIG9zLmNsb3NlKHNlbGYuZmQpDQoNCiAgICBkZWYgcmVhZChzZWxmLCBzaXplKToNCiAgICAgICAgcmV0dXJuIG9zLnJlYWQoc2VsZi5mZCwgc2l6ZSkNCg0KICAgIGRlZiB3cml0ZShzZWxmLCBzKToNCiAgICAgICAgb3Mud3JpdGUoc2VsZi5mZCwgcykNCg0KY2xhc3MgX1N0cmVhbToNCiAgICAiIiJDbGFzcyB0aGF0IHNlcnZlcyBhcyBhbiBhZGFwdGVyIGJldHdlZW4gVGFyRmlsZSBhbmQNCiAgICAgICBhIHN0cmVhbS1saWtlIG9iamVjdC4gIFRoZSBzdHJlYW0tbGlrZSBvYmplY3Qgb25seQ0KICAgICAgIG5lZWRzIHRvIGhhdmUgYSByZWFkKCkgb3Igd3JpdGUoKSBtZXRob2QgYW5kIGlzIGFjY2Vzc2VkDQogICAgICAgYmxvY2t3aXNlLiAgVXNlIG9mIGd6aXAgb3IgYnppcDIgY29tcHJlc3Npb24gaXMgcG9zc2libGUuDQogICAgICAgQSBzdHJlYW0tbGlrZSBvYmplY3QgY291bGQgYmUgZm9yIGV4YW1wbGU6IHN5cy5zdGRpbiwNCiAgICAgICBzeXMuc3Rkb3V0LCBhIHNvY2tldCwgYSB0YXBlIGRldmljZSBldGMuDQoNCiAgICAgICBfU3RyZWFtIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgb25seSBpbnRlcm5hbGx5Lg0KICAgICIiIg0KDQogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIG1vZGUsIGNvbXB0eXBlLCBmaWxlb2JqLCBidWZzaXplKToNCiAgICAgICAgIiIiQ29uc3RydWN0IGEgX1N0cmVhbSBvYmplY3QuDQogICAgICAgICIiIg0KICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gVHJ1ZQ0KICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6DQogICAgICAgICAgICBmaWxlb2JqID0gX0xvd0xldmVsRmlsZShuYW1lLCBtb2RlKQ0KICAgICAgICAgICAgc2VsZi5fZXh0ZmlsZW9iaiA9IEZhbHNlDQoNCiAgICAgICAgaWYgY29tcHR5cGUgPT0gJyonOg0KICAgICAgICAgICAgIyBFbmFibGUgdHJhbnNwYXJlbnQgY29tcHJlc3Npb24gZGV0ZWN0aW9uIGZvciB0aGUNCiAgICAgICAgICAgICMgc3RyZWFtIGludGVyZmFjZQ0KICAgICAgICAgICAgZmlsZW9iaiA9IF9TdHJlYW1Qcm94eShmaWxlb2JqKQ0KICAgICAgICAgICAgY29tcHR5cGUgPSBmaWxlb2JqLmdldGNvbXB0eXBlKCkNCg0KICAgICAgICBzZWxmLm5hbWUgICAgID0gbmFtZSBvciAiIg0KICAgICAgICBzZWxmLm1vZGUgICAgID0gbW9kZQ0KICAgICAgICBzZWxmLmNvbXB0eXBlID0gY29tcHR5cGUNCiAgICAgICAgc2VsZi5maWxlb2JqICA9IGZpbGVvYmoNCiAgICAgICAgc2VsZi5idWZzaXplICA9IGJ1ZnNpemUNCiAgICAgICAgc2VsZi5idWYgICAgICA9ICIiDQogICAgICAgIHNlbGYucG9zICAgICAgPSAwTA0KICAgICAgICBzZWxmLmNsb3NlZCAgID0gRmFsc2UNCg0KICAgICAgICBpZiBjb21wdHlwZSA9PSAiZ3oiOg0KICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgIGltcG9ydCB6bGliDQogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6DQogICAgICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigiemxpYiBtb2R1bGUgaXMgbm90IGF2YWlsYWJsZSIpDQogICAgICAgICAgICBzZWxmLnpsaWIgPSB6bGliDQogICAgICAgICAgICBzZWxmLmNyYyA9IHpsaWIuY3JjMzIoIiIpICYgMHhmZmZmZmZmZkwNCiAgICAgICAgICAgIGlmIG1vZGUgPT0gInIiOg0KICAgICAgICAgICAgICAgIHNlbGYuX2luaXRfcmVhZF9neigpDQogICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgIHNlbGYuX2luaXRfd3JpdGVfZ3ooKQ0KDQogICAgICAgIGlmIGNvbXB0eXBlID09ICJiejIiOg0KICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgIGltcG9ydCBiejINCiAgICAgICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoNCiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJiejIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQ0KICAgICAgICAgICAgaWYgbW9kZSA9PSAiciI6DQogICAgICAgICAgICAgICAgc2VsZi5kYnVmID0gIiINCiAgICAgICAgICAgICAgICBzZWxmLmNtcCA9IGJ6Mi5CWjJEZWNvbXByZXNzb3IoKQ0KICAgICAgICAgICAgZWxzZToNCiAgICAgICAgICAgICAgICBzZWxmLmNtcCA9IGJ6Mi5CWjJDb21wcmVzc29yKCkNCg0KICAgIGRlZiBfX2RlbF9fKHNlbGYpOg0KICAgICAgICBpZiBoYXNhdHRyKHNlbGYsICJjbG9zZWQiKSBhbmQgbm90IHNlbGYuY2xvc2VkOg0KICAgICAgICAgICAgc2VsZi5jbG9zZSgpDQoNCiAgICBkZWYgX2luaXRfd3JpdGVfZ3ooc2VsZik6DQogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uLg0KICAgICAgICAiIiINCiAgICAgICAgc2VsZi5jbXAgPSBzZWxmLnpsaWIuY29tcHJlc3NvYmooOSwgc2VsZi56bGliLkRFRkxBVEVELA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtc2VsZi56bGliLk1BWF9XQklUUywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56bGliLkRFRl9NRU1fTEVWRUwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApDQogICAgICAgIHRpbWVzdGFtcCA9IHN0cnVjdC5wYWNrKCI8TCIsIGxvbmcodGltZS50aW1lKCkpKQ0KICAgICAgICBzZWxmLl9fd3JpdGUoIlwwMzdcMjEzXDAxMFwwMTAlc1wwMDJcMzc3IiAlIHRpbWVzdGFtcCkNCiAgICAgICAgaWYgc2VsZi5uYW1lLmVuZHN3aXRoKCIuZ3oiKToNCiAgICAgICAgICAgIHNlbGYubmFtZSA9IHNlbGYubmFtZVs6LTNdDQogICAgICAgIHNlbGYuX193cml0ZShzZWxmLm5hbWUgKyBOVUwpDQoNCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6DQogICAgICAgICIiIldyaXRlIHN0cmluZyBzIHRvIHRoZSBzdHJlYW0uDQogICAgICAgICIiIg0KICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJneiI6DQogICAgICAgICAgICBzZWxmLmNyYyA9IHNlbGYuemxpYi5jcmMzMihzLCBzZWxmLmNyYykgJiAweGZmZmZmZmZmTA0KICAgICAgICBzZWxmLnBvcyArPSBsZW4ocykNCiAgICAgICAgaWYgc2VsZi5jb21wdHlwZSAhPSAidGFyIjoNCiAgICAgICAgICAgIHMgPSBzZWxmLmNtcC5jb21wcmVzcyhzKQ0KICAgICAgICBzZWxmLl9fd3JpdGUocykNCg0KICAgIGRlZiBfX3dyaXRlKHNlbGYsIHMpOg0KICAgICAgICAiIiJXcml0ZSBzdHJpbmcgcyB0byB0aGUgc3RyZWFtIGlmIGEgd2hvbGUgbmV3IGJsb2NrDQogICAgICAgICAgIGlzIHJlYWR5IHRvIGJlIHdyaXR0ZW4uDQogICAgICAgICIiIg0KICAgICAgICBzZWxmLmJ1ZiArPSBzDQogICAgICAgIHdoaWxlIGxlbihzZWxmLmJ1ZikgPiBzZWxmLmJ1ZnNpemU6DQogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWZbOnNlbGYuYnVmc2l6ZV0pDQogICAgICAgICAgICBzZWxmLmJ1ZiA9IHNlbGYuYnVmW3NlbGYuYnVmc2l6ZTpdDQoNCiAgICBkZWYgY2xvc2Uoc2VsZik6DQogICAgICAgICIiIkNsb3NlIHRoZSBfU3RyZWFtIG9iamVjdC4gTm8gb3BlcmF0aW9uIHNob3VsZCBiZQ0KICAgICAgICAgICBkb25lIG9uIGl0IGFmdGVyd2FyZHMuDQogICAgICAgICIiIg0KICAgICAgICBpZiBzZWxmLmNsb3NlZDoNCiAgICAgICAgICAgIHJldHVybg0KDQogICAgICAgIGlmIHNlbGYubW9kZSA9PSAidyIgYW5kIHNlbGYuY29tcHR5cGUgIT0gInRhciI6DQogICAgICAgICAgICBzZWxmLmJ1ZiArPSBzZWxmLmNtcC5mbHVzaCgpDQoNCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJ3IiBhbmQgc2VsZi5idWY6DQogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWYpDQogICAgICAgICAgICBzZWxmLmJ1ZiA9ICIiDQogICAgICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJneiI6DQogICAgICAgICAgICAgICAgIyBUaGUgbmF0aXZlIHpsaWIgY3JjIGlzIGFuIHVuc2lnbmVkIDMyLWJpdCBpbnRlZ2VyLCBidXQNCiAgICAgICAgICAgICAgICAjIHRoZSBQeXRob24gd3JhcHBlciBpbXBsaWNpdGx5IGNhc3RzIHRoYXQgdG8gYSBzaWduZWQgQw0KICAgICAgICAgICAgICAgICMgbG9uZy4gIFNvLCBvbiBhIDMyLWJpdCBib3ggc2VsZi5jcmMgbWF5ICJsb29rIG5lZ2F0aXZlIiwNCiAgICAgICAgICAgICAgICAjIHdoaWxlIHRoZSBzYW1lIGNyYyBvbiBhIDY0LWJpdCBib3ggbWF5ICJsb29rIHBvc2l0aXZlIi4NCiAgICAgICAgICAgICAgICAjIFRvIGF2b2lkIGlya3NvbWUgd2FybmluZ3MgZnJvbSB0aGUgYHN0cnVjdGAgbW9kdWxlLCBmb3JjZQ0KICAgICAgICAgICAgICAgICMgaXQgdG8gbG9vayBwb3NpdGl2ZSBvbiBhbGwgYm94ZXMuDQogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHN0cnVjdC5wYWNrKCI8TCIsIHNlbGYuY3JjICYgMHhmZmZmZmZmZkwpKQ0KICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzdHJ1Y3QucGFjaygiPEwiLCBzZWxmLnBvcyAmIDB4ZmZmZkZGRkZMKSkNCg0KICAgICAgICBpZiBub3Qgc2VsZi5fZXh0ZmlsZW9iajoNCiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpDQoNCiAgICAgICAgc2VsZi5jbG9zZWQgPSBUcnVlDQoNCiAgICBkZWYgX2luaXRfcmVhZF9neihzZWxmKToNCiAgICAgICAgIiIiSW5pdGlhbGl6ZSBmb3IgcmVhZGluZyBhIGd6aXAgY29tcHJlc3NlZCBmaWxlb2JqLg0KICAgICAgICAiIiINCiAgICAgICAgc2VsZi5jbXAgPSBzZWxmLnpsaWIuZGVjb21wcmVzc29iaigtc2VsZi56bGliLk1BWF9XQklUUykNCiAgICAgICAgc2VsZi5kYnVmID0gIiINCg0KICAgICAgICAjIHRha2VuIGZyb20gZ3ppcC5HemlwRmlsZSB3aXRoIHNvbWUgYWx0ZXJhdGlvbnMNCiAgICAgICAgaWYgc2VsZi5fX3JlYWQoMikgIT0gIlwwMzdcMjEzIjoNCiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigibm90IGEgZ3ppcCBmaWxlIikNCiAgICAgICAgaWYgc2VsZi5fX3JlYWQoMSkgIT0gIlwwMTAiOg0KICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigidW5zdXBwb3J0ZWQgY29tcHJlc3Npb24gbWV0aG9kIikNCg0KICAgICAgICBmbGFnID0gb3JkKHNlbGYuX19yZWFkKDEpKQ0KICAgICAgICBzZWxmLl9fcmVhZCg2KQ0KDQogICAgICAgIGlmIGZsYWcgJiA0Og0KICAgICAgICAgICAgeGxlbiA9IG9yZChzZWxmLl9fcmVhZCgxKSkgKyAyNTYgKiBvcmQoc2VsZi5fX3JlYWQoMSkpDQogICAgICAgICAgICBzZWxmLnJlYWQoeGxlbikNCiAgICAgICAgaWYgZmxhZyAmIDg6DQogICAgICAgICAgICB3aGlsZSBUcnVlOg0KICAgICAgICAgICAgICAgIHMgPSBzZWxmLl9fcmVhZCgxKQ0KICAgICAgICAgICAgICAgIGlmIG5vdCBzIG9yIHMgPT0gTlVMOg0KICAgICAgICAgICAgICAgICAgICBicmVhaw0KICAgICAgICBpZiBmbGFnICYgMTY6DQogICAgICAgICAgICB3aGlsZSBUcnVlOg0KICAgICAgICAgICAgICAgIHMgPSBzZWxmLl9fcmVhZCgxKQ0KICAgICAgICAgICAgICAgIGlmIG5vdCBzIG9yIHMgPT0gTlVMOg0KICAgICAgICAgICAgICAgICAgICBicmVhaw0KICAgICAgICBpZiBmbGFnICYgMjoNCiAgICAgICAgICAgIHNlbGYuX19yZWFkKDIpDQoNCiAgICBkZWYgdGVsbChzZWxmKToNCiAgICAgICAgIiIiUmV0dXJuIHRoZSBzdHJlYW0ncyBmaWxlIHBvaW50ZXIgcG9zaXRpb24uDQogICAgICAgICIiIg0KICAgICAgICByZXR1cm4gc2VsZi5wb3MNCg0KICAgIGRlZiBzZWVrKHNlbGYsIHBvcz0wKToNCiAgICAgICAgIiIiU2V0IHRoZSBzdHJlYW0ncyBmaWxlIHBvaW50ZXIgdG8gcG9zLiBOZWdhdGl2ZSBzZWVraW5nDQogICAgICAgICAgIGlzIGZvcmJpZGRlbi4NCiAgICAgICAgIiIiDQogICAgICAgIGlmIHBvcyAtIHNlbGYucG9zID49IDA6DQogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChwb3MgLSBzZWxmLnBvcywgc2VsZi5idWZzaXplKQ0KICAgICAgICAgICAgZm9yIGkgaW4geHJhbmdlKGJsb2Nrcyk6DQogICAgICAgICAgICAgICAgc2VsZi5yZWFkKHNlbGYuYnVmc2l6ZSkNCiAgICAgICAgICAgIHNlbGYucmVhZChyZW1haW5kZXIpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICByYWlzZSBTdHJlYW1FcnJvcigic2Vla2luZyBiYWNrd2FyZHMgaXMgbm90IGFsbG93ZWQiKQ0KICAgICAgICByZXR1cm4gc2VsZi5wb3MNCg0KICAgIGRlZiByZWFkKHNlbGYsIHNpemU9Tm9uZSk6DQogICAgICAgICIiIlJldHVybiB0aGUgbmV4dCBzaXplIG51bWJlciBvZiBieXRlcyBmcm9tIHRoZSBzdHJlYW0uDQogICAgICAgICAgIElmIHNpemUgaXMgbm90IGRlZmluZWQsIHJldHVybiBhbGwgYnl0ZXMgb2YgdGhlIHN0cmVhbQ0KICAgICAgICAgICB1cCB0byBFT0YuDQogICAgICAgICIiIg0KICAgICAgICBpZiBzaXplIGlzIE5vbmU6DQogICAgICAgICAgICB0ID0gW10NCiAgICAgICAgICAgIHdoaWxlIFRydWU6DQogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5fcmVhZChzZWxmLmJ1ZnNpemUpDQogICAgICAgICAgICAgICAgaWYgbm90IGJ1ZjoNCiAgICAgICAgICAgICAgICAgICAgYnJlYWsNCiAgICAgICAgICAgICAgICB0LmFwcGVuZChidWYpDQogICAgICAgICAgICBidWYgPSAiIi5qb2luKHQpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICBidWYgPSBzZWxmLl9yZWFkKHNpemUpDQogICAgICAgIHNlbGYucG9zICs9IGxlbihidWYpDQogICAgICAgIHJldHVybiBidWYNCg0KICAgIGRlZiBfcmVhZChzZWxmLCBzaXplKToNCiAgICAgICAgIiIiUmV0dXJuIHNpemUgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtLg0KICAgICAgICAiIiINCiAgICAgICAgaWYgc2VsZi5jb21wdHlwZSA9PSAidGFyIjoNCiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fcmVhZChzaXplKQ0KDQogICAgICAgIGMgPSBsZW4oc2VsZi5kYnVmKQ0KICAgICAgICB0ID0gW3NlbGYuZGJ1Zl0NCiAgICAgICAgd2hpbGUgYyA8IHNpemU6DQogICAgICAgICAgICBidWYgPSBzZWxmLl9fcmVhZChzZWxmLmJ1ZnNpemUpDQogICAgICAgICAgICBpZiBub3QgYnVmOg0KICAgICAgICAgICAgICAgIGJyZWFrDQogICAgICAgICAgICB0cnk6DQogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5jbXAuZGVjb21wcmVzcyhidWYpDQogICAgICAgICAgICBleGNlcHQgSU9FcnJvcjoNCiAgICAgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoImludmFsaWQgY29tcHJlc3NlZCBkYXRhIikNCiAgICAgICAgICAgIHQuYXBwZW5kKGJ1ZikNCiAgICAgICAgICAgIGMgKz0gbGVuKGJ1ZikNCiAgICAgICAgdCA9ICIiLmpvaW4odCkNCiAgICAgICAgc2VsZi5kYnVmID0gdFtzaXplOl0NCiAgICAgICAgcmV0dXJuIHRbOnNpemVdDQoNCiAgICBkZWYgX19yZWFkKHNlbGYsIHNpemUpOg0KICAgICAgICAiIiJSZXR1cm4gc2l6ZSBieXRlcyBmcm9tIHN0cmVhbS4gSWYgaW50ZXJuYWwgYnVmZmVyIGlzIGVtcHR5LA0KICAgICAgICAgICByZWFkIGFub3RoZXIgYmxvY2sgZnJvbSB0aGUgc3RyZWFtLg0KICAgICAgICAiIiINCiAgICAgICAgYyA9IGxlbihzZWxmLmJ1ZikNCiAgICAgICAgdCA9IFtzZWxmLmJ1Zl0NCiAgICAgICAgd2hpbGUgYyA8IHNpemU6DQogICAgICAgICAgICBidWYgPSBzZWxmLmZpbGVvYmoucmVhZChzZWxmLmJ1ZnNpemUpDQogICAgICAgICAgICBpZiBub3QgYnVmOg0KICAgICAgICAgICAgICAgIGJyZWFrDQogICAgICAgICAgICB0LmFwcGVuZChidWYpDQogICAgICAgICAgICBjICs9IGxlbihidWYpDQogICAgICAgIHQgPSAiIi5qb2luKHQpDQogICAgICAgIHNlbGYuYnVmID0gdFtzaXplOl0NCiAgICAgICAgcmV0dXJuIHRbOnNpemVdDQojIGNsYXNzIF9TdHJlYW0NCg0KY2xhc3MgX1N0cmVhbVByb3h5KG9iamVjdCk6DQogICAgIiIiU21hbGwgcHJveHkgY2xhc3MgdGhhdCBlbmFibGVzIHRyYW5zcGFyZW50IGNvbXByZXNzaW9uDQogICAgICAgZGV0ZWN0aW9uIGZvciB0aGUgU3RyZWFtIGludGVyZmFjZSAobW9kZSAncnwqJykuDQogICAgIiIiDQoNCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW9iaik6DQogICAgICAgIHNlbGYuZmlsZW9iaiA9IGZpbGVvYmoNCiAgICAgICAgc2VsZi5idWYgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpDQoNCiAgICBkZWYgcmVhZChzZWxmLCBzaXplKToNCiAgICAgICAgc2VsZi5yZWFkID0gc2VsZi5maWxlb2JqLnJlYWQNCiAgICAgICAgcmV0dXJuIHNlbGYuYnVmDQoNCiAgICBkZWYgZ2V0Y29tcHR5cGUoc2VsZik6DQogICAgICAgIGlmIHNlbGYuYnVmLnN0YXJ0c3dpdGgoIlwwMzdcMjEzXDAxMCIpOg0KICAgICAgICAgICAgcmV0dXJuICJneiINCiAgICAgICAgaWYgc2VsZi5idWYuc3RhcnRzd2l0aCgiQlpoOTEiKToNCiAgICAgICAgICAgIHJldHVybiAiYnoyIg0KICAgICAgICByZXR1cm4gInRhciINCg0KICAgIGRlZiBjbG9zZShzZWxmKToNCiAgICAgICAgc2VsZi5maWxlb2JqLmNsb3NlKCkNCiMgY2xhc3MgU3RyZWFtUHJveHkNCg0KY2xhc3MgX0JaMlByb3h5KG9iamVjdCk6DQogICAgIiIiU21hbGwgcHJveHkgY2xhc3MgdGhhdCBlbmFibGVzIGV4dGVybmFsIGZpbGUgb2JqZWN0DQogICAgICAgc3VwcG9ydCBmb3IgInI6YnoyIiBhbmQgInc6YnoyIiBtb2Rlcy4gVGhpcyBpcyBhY3R1YWxseQ0KICAgICAgIGEgd29ya2Fyb3VuZCBmb3IgYSBsaW1pdGF0aW9uIGluIGJ6MiBtb2R1bGUncyBCWjJGaWxlDQogICAgICAgY2xhc3Mgd2hpY2ggKHVubGlrZSBnemlwLkd6aXBGaWxlKSBoYXMgbm8gc3VwcG9ydCBmb3INCiAgICAgICBhIGZpbGUgb2JqZWN0IGFyZ3VtZW50Lg0KICAgICIiIg0KDQogICAgYmxvY2tzaXplID0gMTYgKiAxMDI0DQoNCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW9iaiwgbW9kZSk6DQogICAgICAgIHNlbGYuZmlsZW9iaiA9IGZpbGVvYmoNCiAgICAgICAgc2VsZi5tb2RlID0gbW9kZQ0KICAgICAgICBzZWxmLm5hbWUgPSBnZXRhdHRyKHNlbGYuZmlsZW9iaiwgIm5hbWUiLCBOb25lKQ0KICAgICAgICBzZWxmLmluaXQoKQ0KDQogICAgZGVmIGluaXQoc2VsZik6DQogICAgICAgIGltcG9ydCBiejINCiAgICAgICAgc2VsZi5wb3MgPSAwDQogICAgICAgIGlmIHNlbGYubW9kZSA9PSAiciI6DQogICAgICAgICAgICBzZWxmLmJ6Mm9iaiA9IGJ6Mi5CWjJEZWNvbXByZXNzb3IoKQ0KICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoMCkNCiAgICAgICAgICAgIHNlbGYuYnVmID0gIiINCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIHNlbGYuYnoyb2JqID0gYnoyLkJaMkNvbXByZXNzb3IoKQ0KDQogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6DQogICAgICAgIGIgPSBbc2VsZi5idWZdDQogICAgICAgIHggPSBsZW4oc2VsZi5idWYpDQogICAgICAgIHdoaWxlIHggPCBzaXplOg0KICAgICAgICAgICAgcmF3ID0gc2VsZi5maWxlb2JqLnJlYWQoc2VsZi5ibG9ja3NpemUpDQogICAgICAgICAgICBpZiBub3QgcmF3Og0KICAgICAgICAgICAgICAgIGJyZWFrDQogICAgICAgICAgICBkYXRhID0gc2VsZi5iejJvYmouZGVjb21wcmVzcyhyYXcpDQogICAgICAgICAgICBiLmFwcGVuZChkYXRhKQ0KICAgICAgICAgICAgeCArPSBsZW4oZGF0YSkNCiAgICAgICAgc2VsZi5idWYgPSAiIi5qb2luKGIpDQoNCiAgICAgICAgYnVmID0gc2VsZi5idWZbOnNpemVdDQogICAgICAgIHNlbGYuYnVmID0gc2VsZi5idWZbc2l6ZTpdDQogICAgICAgIHNlbGYucG9zICs9IGxlbihidWYpDQogICAgICAgIHJldHVybiBidWYNCg0KICAgIGRlZiBzZWVrKHNlbGYsIHBvcyk6DQogICAgICAgIGlmIHBvcyA8IHNlbGYucG9zOg0KICAgICAgICAgICAgc2VsZi5pbml0KCkNCiAgICAgICAgc2VsZi5yZWFkKHBvcyAtIHNlbGYucG9zKQ0KDQogICAgZGVmIHRlbGwoc2VsZik6DQogICAgICAgIHJldHVybiBzZWxmLnBvcw0KDQogICAgZGVmIHdyaXRlKHNlbGYsIGRhdGEpOg0KICAgICAgICBzZWxmLnBvcyArPSBsZW4oZGF0YSkNCiAgICAgICAgcmF3ID0gc2VsZi5iejJvYmouY29tcHJlc3MoZGF0YSkNCiAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHJhdykNCg0KICAgIGRlZiBjbG9zZShzZWxmKToNCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJ3IjoNCiAgICAgICAgICAgIHJhdyA9IHNlbGYuYnoyb2JqLmZsdXNoKCkNCiAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShyYXcpDQojIGNsYXNzIF9CWjJQcm94eQ0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIEV4dHJhY3Rpb24gZmlsZSBvYmplY3QNCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCmNsYXNzIF9GaWxlSW5GaWxlKG9iamVjdCk6DQogICAgIiIiQSB0aGluIHdyYXBwZXIgYXJvdW5kIGFuIGV4aXN0aW5nIGZpbGUgb2JqZWN0IHRoYXQNCiAgICAgICBwcm92aWRlcyBhIHBhcnQgb2YgaXRzIGRhdGEgYXMgYW4gaW5kaXZpZHVhbCBmaWxlDQogICAgICAgb2JqZWN0Lg0KICAgICIiIg0KDQogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGVvYmosIG9mZnNldCwgc2l6ZSwgc3BhcnNlPU5vbmUpOg0KICAgICAgICBzZWxmLmZpbGVvYmogPSBmaWxlb2JqDQogICAgICAgIHNlbGYub2Zmc2V0ID0gb2Zmc2V0DQogICAgICAgIHNlbGYuc2l6ZSA9IHNpemUNCiAgICAgICAgc2VsZi5zcGFyc2UgPSBzcGFyc2UNCiAgICAgICAgc2VsZi5wb3NpdGlvbiA9IDANCg0KICAgIGRlZiB0ZWxsKHNlbGYpOg0KICAgICAgICAiIiJSZXR1cm4gdGhlIGN1cnJlbnQgZmlsZSBwb3NpdGlvbi4NCiAgICAgICAgIiIiDQogICAgICAgIHJldHVybiBzZWxmLnBvc2l0aW9uDQoNCiAgICBkZWYgc2VlayhzZWxmLCBwb3NpdGlvbik6DQogICAgICAgICIiIlNlZWsgdG8gYSBwb3NpdGlvbiBpbiB0aGUgZmlsZS4NCiAgICAgICAgIiIiDQogICAgICAgIHNlbGYucG9zaXRpb24gPSBwb3NpdGlvbg0KDQogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZT1Ob25lKToNCiAgICAgICAgIiIiUmVhZCBkYXRhIGZyb20gdGhlIGZpbGUuDQogICAgICAgICIiIg0KICAgICAgICBpZiBzaXplIGlzIE5vbmU6DQogICAgICAgICAgICBzaXplID0gc2VsZi5zaXplIC0gc2VsZi5wb3NpdGlvbg0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgc2l6ZSA9IG1pbihzaXplLCBzZWxmLnNpemUgLSBzZWxmLnBvc2l0aW9uKQ0KDQogICAgICAgIGlmIHNlbGYuc3BhcnNlIGlzIE5vbmU6DQogICAgICAgICAgICByZXR1cm4gc2VsZi5yZWFkbm9ybWFsKHNpemUpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICByZXR1cm4gc2VsZi5yZWFkc3BhcnNlKHNpemUpDQoNCiAgICBkZWYgcmVhZG5vcm1hbChzZWxmLCBzaXplKToNCiAgICAgICAgIiIiUmVhZCBvcGVyYXRpb24gZm9yIHJlZ3VsYXIgZmlsZXMuDQogICAgICAgICIiIg0KICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCArIHNlbGYucG9zaXRpb24pDQogICAgICAgIHNlbGYucG9zaXRpb24gKz0gc2l6ZQ0KICAgICAgICByZXR1cm4gc2VsZi5maWxlb2JqLnJlYWQoc2l6ZSkNCg0KICAgIGRlZiByZWFkc3BhcnNlKHNlbGYsIHNpemUpOg0KICAgICAgICAiIiJSZWFkIG9wZXJhdGlvbiBmb3Igc3BhcnNlIGZpbGVzLg0KICAgICAgICAiIiINCiAgICAgICAgZGF0YSA9IFtdDQogICAgICAgIHdoaWxlIHNpemUgPiAwOg0KICAgICAgICAgICAgYnVmID0gc2VsZi5yZWFkc3BhcnNlc2VjdGlvbihzaXplKQ0KICAgICAgICAgICAgaWYgbm90IGJ1ZjoNCiAgICAgICAgICAgICAgICBicmVhaw0KICAgICAgICAgICAgc2l6ZSAtPSBsZW4oYnVmKQ0KICAgICAgICAgICAgZGF0YS5hcHBlbmQoYnVmKQ0KICAgICAgICByZXR1cm4gIiIuam9pbihkYXRhKQ0KDQogICAgZGVmIHJlYWRzcGFyc2VzZWN0aW9uKHNlbGYsIHNpemUpOg0KICAgICAgICAiIiJSZWFkIGEgc2luZ2xlIHNlY3Rpb24gb2YgYSBzcGFyc2UgZmlsZS4NCiAgICAgICAgIiIiDQogICAgICAgIHNlY3Rpb24gPSBzZWxmLnNwYXJzZS5maW5kKHNlbGYucG9zaXRpb24pDQoNCiAgICAgICAgaWYgc2VjdGlvbiBpcyBOb25lOg0KICAgICAgICAgICAgcmV0dXJuICIiDQoNCiAgICAgICAgc2l6ZSA9IG1pbihzaXplLCBzZWN0aW9uLm9mZnNldCArIHNlY3Rpb24uc2l6ZSAtIHNlbGYucG9zaXRpb24pDQoNCiAgICAgICAgaWYgaXNpbnN0YW5jZShzZWN0aW9uLCBfZGF0YSk6DQogICAgICAgICAgICByZWFscG9zID0gc2VjdGlvbi5yZWFscG9zICsgc2VsZi5wb3NpdGlvbiAtIHNlY3Rpb24ub2Zmc2V0DQogICAgICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCArIHJlYWxwb3MpDQogICAgICAgICAgICBzZWxmLnBvc2l0aW9uICs9IHNpemUNCiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmoucmVhZChzaXplKQ0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgc2VsZi5wb3NpdGlvbiArPSBzaXplDQogICAgICAgICAgICByZXR1cm4gTlVMICogc2l6ZQ0KI2NsYXNzIF9GaWxlSW5GaWxlDQoNCg0KY2xhc3MgRXhGaWxlT2JqZWN0KG9iamVjdCk6DQogICAgIiIiRmlsZS1saWtlIG9iamVjdCBmb3IgcmVhZGluZyBhbiBhcmNoaXZlIG1lbWJlci4NCiAgICAgICBJcyByZXR1cm5lZCBieSBUYXJGaWxlLmV4dHJhY3RmaWxlKCkuDQogICAgIiIiDQogICAgYmxvY2tzaXplID0gMTAyNA0KDQogICAgZGVmIF9faW5pdF9fKHNlbGYsIHRhcmZpbGUsIHRhcmluZm8pOg0KICAgICAgICBzZWxmLmZpbGVvYmogPSBfRmlsZUluRmlsZSh0YXJmaWxlLmZpbGVvYmosDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmluZm8ub2Zmc2V0X2RhdGEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmluZm8uc2l6ZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0YXR0cih0YXJpbmZvLCAic3BhcnNlIiwgTm9uZSkpDQogICAgICAgIHNlbGYubmFtZSA9IHRhcmluZm8ubmFtZQ0KICAgICAgICBzZWxmLm1vZGUgPSAiciINCiAgICAgICAgc2VsZi5jbG9zZWQgPSBGYWxzZQ0KICAgICAgICBzZWxmLnNpemUgPSB0YXJpbmZvLnNpemUNCg0KICAgICAgICBzZWxmLnBvc2l0aW9uID0gMA0KICAgICAgICBzZWxmLmJ1ZmZlciA9ICIiDQoNCiAgICBkZWYgcmVhZChzZWxmLCBzaXplPU5vbmUpOg0KICAgICAgICAiIiJSZWFkIGF0IG1vc3Qgc2l6ZSBieXRlcyBmcm9tIHRoZSBmaWxlLiBJZiBzaXplIGlzIG5vdA0KICAgICAgICAgICBwcmVzZW50IG9yIE5vbmUsIHJlYWQgYWxsIGRhdGEgdW50aWwgRU9GIGlzIHJlYWNoZWQuDQogICAgICAgICIiIg0KICAgICAgICBpZiBzZWxmLmNsb3NlZDoNCiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkkvTyBvcGVyYXRpb24gb24gY2xvc2VkIGZpbGUiKQ0KDQogICAgICAgIGJ1ZiA9ICIiDQogICAgICAgIGlmIHNlbGYuYnVmZmVyOg0KICAgICAgICAgICAgaWYgc2l6ZSBpcyBOb25lOg0KICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYuYnVmZmVyDQogICAgICAgICAgICAgICAgc2VsZi5idWZmZXIgPSAiIg0KICAgICAgICAgICAgZWxzZToNCiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLmJ1ZmZlcls6c2l6ZV0NCiAgICAgICAgICAgICAgICBzZWxmLmJ1ZmZlciA9IHNlbGYuYnVmZmVyW3NpemU6XQ0KDQogICAgICAgIGlmIHNpemUgaXMgTm9uZToNCiAgICAgICAgICAgIGJ1ZiArPSBzZWxmLmZpbGVvYmoucmVhZCgpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICBidWYgKz0gc2VsZi5maWxlb2JqLnJlYWQoc2l6ZSAtIGxlbihidWYpKQ0KDQogICAgICAgIHNlbGYucG9zaXRpb24gKz0gbGVuKGJ1ZikNCiAgICAgICAgcmV0dXJuIGJ1Zg0KDQogICAgZGVmIHJlYWRsaW5lKHNlbGYsIHNpemU9LTEpOg0KICAgICAgICAiIiJSZWFkIG9uZSBlbnRpcmUgbGluZSBmcm9tIHRoZSBmaWxlLiBJZiBzaXplIGlzIHByZXNlbnQNCiAgICAgICAgICAgYW5kIG5vbi1uZWdhdGl2ZSwgcmV0dXJuIGEgc3RyaW5nIHdpdGggYXQgbW9zdCB0aGF0DQogICAgICAgICAgIHNpemUsIHdoaWNoIG1heSBiZSBhbiBpbmNvbXBsZXRlIGxpbmUuDQogICAgICAgICIiIg0KICAgICAgICBpZiBzZWxmLmNsb3NlZDoNCiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkkvTyBvcGVyYXRpb24gb24gY2xvc2VkIGZpbGUiKQ0KDQogICAgICAgIGlmICJcbiIgaW4gc2VsZi5idWZmZXI6DQogICAgICAgICAgICBwb3MgPSBzZWxmLmJ1ZmZlci5maW5kKCJcbiIpICsgMQ0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgYnVmZmVycyA9IFtzZWxmLmJ1ZmZlcl0NCiAgICAgICAgICAgIHdoaWxlIFRydWU6DQogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoc2VsZi5ibG9ja3NpemUpDQogICAgICAgICAgICAgICAgYnVmZmVycy5hcHBlbmQoYnVmKQ0KICAgICAgICAgICAgICAgIGlmIG5vdCBidWYgb3IgIlxuIiBpbiBidWY6DQogICAgICAgICAgICAgICAgICAgIHNlbGYuYnVmZmVyID0gIiIuam9pbihidWZmZXJzKQ0KICAgICAgICAgICAgICAgICAgICBwb3MgPSBzZWxmLmJ1ZmZlci5maW5kKCJcbiIpICsgMQ0KICAgICAgICAgICAgICAgICAgICBpZiBwb3MgPT0gMDoNCiAgICAgICAgICAgICAgICAgICAgICAgICMgbm8gbmV3bGluZSBmb3VuZC4NCiAgICAgICAgICAgICAgICAgICAgICAgIHBvcyA9IGxlbihzZWxmLmJ1ZmZlcikNCiAgICAgICAgICAgICAgICAgICAgYnJlYWsNCg0KICAgICAgICBpZiBzaXplICE9IC0xOg0KICAgICAgICAgICAgcG9zID0gbWluKHNpemUsIHBvcykNCg0KICAgICAgICBidWYgPSBzZWxmLmJ1ZmZlcls6cG9zXQ0KICAgICAgICBzZWxmLmJ1ZmZlciA9IHNlbGYuYnVmZmVyW3BvczpdDQogICAgICAgIHNlbGYucG9zaXRpb24gKz0gbGVuKGJ1ZikNCiAgICAgICAgcmV0dXJuIGJ1Zg0KDQogICAgZGVmIHJlYWRsaW5lcyhzZWxmKToNCiAgICAgICAgIiIiUmV0dXJuIGEgbGlzdCB3aXRoIGFsbCByZW1haW5pbmcgbGluZXMuDQogICAgICAgICIiIg0KICAgICAgICByZXN1bHQgPSBbXQ0KICAgICAgICB3aGlsZSBUcnVlOg0KICAgICAgICAgICAgbGluZSA9IHNlbGYucmVhZGxpbmUoKQ0KICAgICAgICAgICAgaWYgbm90IGxpbmU6IGJyZWFrDQogICAgICAgICAgICByZXN1bHQuYXBwZW5kKGxpbmUpDQogICAgICAgIHJldHVybiByZXN1bHQNCg0KICAgIGRlZiB0ZWxsKHNlbGYpOg0KICAgICAgICAiIiJSZXR1cm4gdGhlIGN1cnJlbnQgZmlsZSBwb3NpdGlvbi4NCiAgICAgICAgIiIiDQogICAgICAgIGlmIHNlbGYuY2xvc2VkOg0KICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiSS9PIG9wZXJhdGlvbiBvbiBjbG9zZWQgZmlsZSIpDQoNCiAgICAgICAgcmV0dXJuIHNlbGYucG9zaXRpb24NCg0KICAgIGRlZiBzZWVrKHNlbGYsIHBvcywgd2hlbmNlPW9zLlNFRUtfU0VUKToNCiAgICAgICAgIiIiU2VlayB0byBhIHBvc2l0aW9uIGluIHRoZSBmaWxlLg0KICAgICAgICAiIiINCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6DQogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJJL08gb3BlcmF0aW9uIG9uIGNsb3NlZCBmaWxlIikNCg0KICAgICAgICBpZiB3aGVuY2UgPT0gb3MuU0VFS19TRVQ6DQogICAgICAgICAgICBzZWxmLnBvc2l0aW9uID0gbWluKG1heChwb3MsIDApLCBzZWxmLnNpemUpDQogICAgICAgIGVsaWYgd2hlbmNlID09IG9zLlNFRUtfQ1VSOg0KICAgICAgICAgICAgaWYgcG9zIDwgMDoNCiAgICAgICAgICAgICAgICBzZWxmLnBvc2l0aW9uID0gbWF4KHNlbGYucG9zaXRpb24gKyBwb3MsIDApDQogICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgIHNlbGYucG9zaXRpb24gPSBtaW4oc2VsZi5wb3NpdGlvbiArIHBvcywgc2VsZi5zaXplKQ0KICAgICAgICBlbGlmIHdoZW5jZSA9PSBvcy5TRUVLX0VORDoNCiAgICAgICAgICAgIHNlbGYucG9zaXRpb24gPSBtYXgobWluKHNlbGYuc2l6ZSArIHBvcywgc2VsZi5zaXplKSwgMCkNCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkludmFsaWQgYXJndW1lbnQiKQ0KDQogICAgICAgIHNlbGYuYnVmZmVyID0gIiINCiAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5wb3NpdGlvbikNCg0KICAgIGRlZiBjbG9zZShzZWxmKToNCiAgICAgICAgIiIiQ2xvc2UgdGhlIGZpbGUgb2JqZWN0Lg0KICAgICAgICAiIiINCiAgICAgICAgc2VsZi5jbG9zZWQgPSBUcnVlDQoNCiAgICBkZWYgX19pdGVyX18oc2VsZik6DQogICAgICAgICIiIkdldCBhbiBpdGVyYXRvciBvdmVyIHRoZSBmaWxlJ3MgbGluZXMuDQogICAgICAgICIiIg0KICAgICAgICB3aGlsZSBUcnVlOg0KICAgICAgICAgICAgbGluZSA9IHNlbGYucmVhZGxpbmUoKQ0KICAgICAgICAgICAgaWYgbm90IGxpbmU6DQogICAgICAgICAgICAgICAgYnJlYWsNCiAgICAgICAgICAgIHlpZWxkIGxpbmUNCiNjbGFzcyBFeEZpbGVPYmplY3QNCg0KIy0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBFeHBvcnRlZCBDbGFzc2VzDQojLS0tLS0tLS0tLS0tLS0tLS0tDQpjbGFzcyBUYXJJbmZvKG9iamVjdCk6DQogICAgIiIiSW5mb3JtYXRpb25hbCBjbGFzcyB3aGljaCBob2xkcyB0aGUgZGV0YWlscyBhYm91dCBhbg0KICAgICAgIGFyY2hpdmUgbWVtYmVyIGdpdmVuIGJ5IGEgdGFyIGhlYWRlciBibG9jay4NCiAgICAgICBUYXJJbmZvIG9iamVjdHMgYXJlIHJldHVybmVkIGJ5IFRhckZpbGUuZ2V0bWVtYmVyKCksDQogICAgICAgVGFyRmlsZS5nZXRtZW1iZXJzKCkgYW5kIFRhckZpbGUuZ2V0dGFyaW5mbygpIGFuZCBhcmUNCiAgICAgICB1c3VhbGx5IGNyZWF0ZWQgaW50ZXJuYWxseS4NCiAgICAiIiINCg0KICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lPSIiKToNCiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySW5mbyBvYmplY3QuIG5hbWUgaXMgdGhlIG9wdGlvbmFsIG5hbWUNCiAgICAgICAgICAgb2YgdGhlIG1lbWJlci4NCiAgICAgICAgIiIiDQogICAgICAgIHNlbGYubmFtZSA9IG5hbWUgICAgICAgICMgbWVtYmVyIG5hbWUNCiAgICAgICAgc2VsZi5tb2RlID0gMDY0NCAgICAgICAgIyBmaWxlIHBlcm1pc3Npb25zDQogICAgICAgIHNlbGYudWlkID0gMCAgICAgICAgICAgICMgdXNlciBpZA0KICAgICAgICBzZWxmLmdpZCA9IDAgICAgICAgICAgICAjIGdyb3VwIGlkDQogICAgICAgIHNlbGYuc2l6ZSA9IDAgICAgICAgICAgICMgZmlsZSBzaXplDQogICAgICAgIHNlbGYubXRpbWUgPSAwICAgICAgICAgICMgbW9kaWZpY2F0aW9uIHRpbWUNCiAgICAgICAgc2VsZi5jaGtzdW0gPSAwICAgICAgICAgIyBoZWFkZXIgY2hlY2tzdW0NCiAgICAgICAgc2VsZi50eXBlID0gUkVHVFlQRSAgICAgIyBtZW1iZXIgdHlwZQ0KICAgICAgICBzZWxmLmxpbmtuYW1lID0gIiIgICAgICAjIGxpbmsgbmFtZQ0KICAgICAgICBzZWxmLnVuYW1lID0gIiIgICAgICAgICAjIHVzZXIgbmFtZQ0KICAgICAgICBzZWxmLmduYW1lID0gIiIgICAgICAgICAjIGdyb3VwIG5hbWUNCiAgICAgICAgc2VsZi5kZXZtYWpvciA9IDAgICAgICAgIyBkZXZpY2UgbWFqb3IgbnVtYmVyDQogICAgICAgIHNlbGYuZGV2bWlub3IgPSAwICAgICAgICMgZGV2aWNlIG1pbm9yIG51bWJlcg0KDQogICAgICAgIHNlbGYub2Zmc2V0ID0gMCAgICAgICAgICMgdGhlIHRhciBoZWFkZXIgc3RhcnRzIGhlcmUNCiAgICAgICAgc2VsZi5vZmZzZXRfZGF0YSA9IDAgICAgIyB0aGUgZmlsZSdzIGRhdGEgc3RhcnRzIGhlcmUNCg0KICAgICAgICBzZWxmLnBheF9oZWFkZXJzID0ge30gICAjIHBheCBoZWFkZXIgaW5mb3JtYXRpb24NCg0KICAgICMgSW4gcGF4IGhlYWRlcnMgdGhlICJuYW1lIiBhbmQgImxpbmtuYW1lIiBmaWVsZCBhcmUgY2FsbGVkDQogICAgIyAicGF0aCIgYW5kICJsaW5rcGF0aCIuDQogICAgZGVmIF9nZXRwYXRoKHNlbGYpOg0KICAgICAgICByZXR1cm4gc2VsZi5uYW1lDQogICAgZGVmIF9zZXRwYXRoKHNlbGYsIG5hbWUpOg0KICAgICAgICBzZWxmLm5hbWUgPSBuYW1lDQogICAgcGF0aCA9IHByb3BlcnR5KF9nZXRwYXRoLCBfc2V0cGF0aCkNCg0KICAgIGRlZiBfZ2V0bGlua3BhdGgoc2VsZik6DQogICAgICAgIHJldHVybiBzZWxmLmxpbmtuYW1lDQogICAgZGVmIF9zZXRsaW5rcGF0aChzZWxmLCBsaW5rbmFtZSk6DQogICAgICAgIHNlbGYubGlua25hbWUgPSBsaW5rbmFtZQ0KICAgIGxpbmtwYXRoID0gcHJvcGVydHkoX2dldGxpbmtwYXRoLCBfc2V0bGlua3BhdGgpDQoNCiAgICBkZWYgX19yZXByX18oc2VsZik6DQogICAgICAgIHJldHVybiAiPCVzICVyIGF0ICUjeD4iICUgKHNlbGYuX19jbGFzc19fLl9fbmFtZV9fLHNlbGYubmFtZSxpZChzZWxmKSkNCg0KICAgIGRlZiBnZXRfaW5mbyhzZWxmLCBlbmNvZGluZywgZXJyb3JzKToNCiAgICAgICAgIiIiUmV0dXJuIHRoZSBUYXJJbmZvJ3MgYXR0cmlidXRlcyBhcyBhIGRpY3Rpb25hcnkuDQogICAgICAgICIiIg0KICAgICAgICBpbmZvID0gew0KICAgICAgICAgICAgIm5hbWUiOiAgICAgc2VsZi5uYW1lLA0KICAgICAgICAgICAgIm1vZGUiOiAgICAgc2VsZi5tb2RlICYgMDc3NzcsDQogICAgICAgICAgICAidWlkIjogICAgICBzZWxmLnVpZCwNCiAgICAgICAgICAgICJnaWQiOiAgICAgIHNlbGYuZ2lkLA0KICAgICAgICAgICAgInNpemUiOiAgICAgc2VsZi5zaXplLA0KICAgICAgICAgICAgIm10aW1lIjogICAgc2VsZi5tdGltZSwNCiAgICAgICAgICAgICJjaGtzdW0iOiAgIHNlbGYuY2hrc3VtLA0KICAgICAgICAgICAgInR5cGUiOiAgICAgc2VsZi50eXBlLA0KICAgICAgICAgICAgImxpbmtuYW1lIjogc2VsZi5saW5rbmFtZSwNCiAgICAgICAgICAgICJ1bmFtZSI6ICAgIHNlbGYudW5hbWUsDQogICAgICAgICAgICAiZ25hbWUiOiAgICBzZWxmLmduYW1lLA0KICAgICAgICAgICAgImRldm1ham9yIjogc2VsZi5kZXZtYWpvciwNCiAgICAgICAgICAgICJkZXZtaW5vciI6IHNlbGYuZGV2bWlub3INCiAgICAgICAgfQ0KDQogICAgICAgIGlmIGluZm9bInR5cGUiXSA9PSBESVJUWVBFIGFuZCBub3QgaW5mb1sibmFtZSJdLmVuZHN3aXRoKCIvIik6DQogICAgICAgICAgICBpbmZvWyJuYW1lIl0gKz0gIi8iDQoNCiAgICAgICAgZm9yIGtleSBpbiAoIm5hbWUiLCAibGlua25hbWUiLCAidW5hbWUiLCAiZ25hbWUiKToNCiAgICAgICAgICAgIGlmIHR5cGUoaW5mb1trZXldKSBpcyB1bmljb2RlOg0KICAgICAgICAgICAgICAgIGluZm9ba2V5XSA9IGluZm9ba2V5XS5lbmNvZGUoZW5jb2RpbmcsIGVycm9ycykNCg0KICAgICAgICByZXR1cm4gaW5mbw0KDQogICAgZGVmIHRvYnVmKHNlbGYsIGZvcm1hdD1ERUZBVUxUX0ZPUk1BVCwgZW5jb2Rpbmc9RU5DT0RJTkcsIGVycm9ycz0ic3RyaWN0Iik6DQogICAgICAgICIiIlJldHVybiBhIHRhciBoZWFkZXIgYXMgYSBzdHJpbmcgb2YgNTEyIGJ5dGUgYmxvY2tzLg0KICAgICAgICAiIiINCiAgICAgICAgaW5mbyA9IHNlbGYuZ2V0X2luZm8oZW5jb2RpbmcsIGVycm9ycykNCg0KICAgICAgICBpZiBmb3JtYXQgPT0gVVNUQVJfRk9STUFUOg0KICAgICAgICAgICAgcmV0dXJuIHNlbGYuY3JlYXRlX3VzdGFyX2hlYWRlcihpbmZvKQ0KICAgICAgICBlbGlmIGZvcm1hdCA9PSBHTlVfRk9STUFUOg0KICAgICAgICAgICAgcmV0dXJuIHNlbGYuY3JlYXRlX2dudV9oZWFkZXIoaW5mbykNCiAgICAgICAgZWxpZiBmb3JtYXQgPT0gUEFYX0ZPUk1BVDoNCiAgICAgICAgICAgIHJldHVybiBzZWxmLmNyZWF0ZV9wYXhfaGVhZGVyKGluZm8sIGVuY29kaW5nLCBlcnJvcnMpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJpbnZhbGlkIGZvcm1hdCIpDQoNCiAgICBkZWYgY3JlYXRlX3VzdGFyX2hlYWRlcihzZWxmLCBpbmZvKToNCiAgICAgICAgIiIiUmV0dXJuIHRoZSBvYmplY3QgYXMgYSB1c3RhciBoZWFkZXIgYmxvY2suDQogICAgICAgICIiIg0KICAgICAgICBpbmZvWyJtYWdpYyJdID0gUE9TSVhfTUFHSUMNCg0KICAgICAgICBpZiBsZW4oaW5mb1sibGlua25hbWUiXSkgPiBMRU5HVEhfTElOSzoNCiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImxpbmtuYW1lIGlzIHRvbyBsb25nIikNCg0KICAgICAgICBpZiBsZW4oaW5mb1sibmFtZSJdKSA+IExFTkdUSF9OQU1FOg0KICAgICAgICAgICAgaW5mb1sicHJlZml4Il0sIGluZm9bIm5hbWUiXSA9IHNlbGYuX3Bvc2l4X3NwbGl0X25hbWUoaW5mb1sibmFtZSJdKQ0KDQogICAgICAgIHJldHVybiBzZWxmLl9jcmVhdGVfaGVhZGVyKGluZm8sIFVTVEFSX0ZPUk1BVCkNCg0KICAgIGRlZiBjcmVhdGVfZ251X2hlYWRlcihzZWxmLCBpbmZvKToNCiAgICAgICAgIiIiUmV0dXJuIHRoZSBvYmplY3QgYXMgYSBHTlUgaGVhZGVyIGJsb2NrIHNlcXVlbmNlLg0KICAgICAgICAiIiINCiAgICAgICAgaW5mb1sibWFnaWMiXSA9IEdOVV9NQUdJQw0KDQogICAgICAgIGJ1ZiA9ICIiDQogICAgICAgIGlmIGxlbihpbmZvWyJsaW5rbmFtZSJdKSA+IExFTkdUSF9MSU5LOg0KICAgICAgICAgICAgYnVmICs9IHNlbGYuX2NyZWF0ZV9nbnVfbG9uZ19oZWFkZXIoaW5mb1sibGlua25hbWUiXSwgR05VVFlQRV9MT05HTElOSykNCg0KICAgICAgICBpZiBsZW4oaW5mb1sibmFtZSJdKSA+IExFTkdUSF9OQU1FOg0KICAgICAgICAgICAgYnVmICs9IHNlbGYuX2NyZWF0ZV9nbnVfbG9uZ19oZWFkZXIoaW5mb1sibmFtZSJdLCBHTlVUWVBFX0xPTkdOQU1FKQ0KDQogICAgICAgIHJldHVybiBidWYgKyBzZWxmLl9jcmVhdGVfaGVhZGVyKGluZm8sIEdOVV9GT1JNQVQpDQoNCiAgICBkZWYgY3JlYXRlX3BheF9oZWFkZXIoc2VsZiwgaW5mbywgZW5jb2RpbmcsIGVycm9ycyk6DQogICAgICAgICIiIlJldHVybiB0aGUgb2JqZWN0IGFzIGEgdXN0YXIgaGVhZGVyIGJsb2NrLiBJZiBpdCBjYW5ub3QgYmUNCiAgICAgICAgICAgcmVwcmVzZW50ZWQgdGhpcyB3YXksIHByZXBlbmQgYSBwYXggZXh0ZW5kZWQgaGVhZGVyIHNlcXVlbmNlDQogICAgICAgICAgIHdpdGggc3VwcGxlbWVudCBpbmZvcm1hdGlvbi4NCiAgICAgICAgIiIiDQogICAgICAgIGluZm9bIm1hZ2ljIl0gPSBQT1NJWF9NQUdJQw0KICAgICAgICBwYXhfaGVhZGVycyA9IHNlbGYucGF4X2hlYWRlcnMuY29weSgpDQoNCiAgICAgICAgIyBUZXN0IHN0cmluZyBmaWVsZHMgZm9yIHZhbHVlcyB0aGF0IGV4Y2VlZCB0aGUgZmllbGQgbGVuZ3RoIG9yIGNhbm5vdA0KICAgICAgICAjIGJlIHJlcHJlc2VudGVkIGluIEFTQ0lJIGVuY29kaW5nLg0KICAgICAgICBmb3IgbmFtZSwgaG5hbWUsIGxlbmd0aCBpbiAoDQogICAgICAgICAgICAgICAgKCJuYW1lIiwgInBhdGgiLCBMRU5HVEhfTkFNRSksICgibGlua25hbWUiLCAibGlua3BhdGgiLCBMRU5HVEhfTElOSyksDQogICAgICAgICAgICAgICAgKCJ1bmFtZSIsICJ1bmFtZSIsIDMyKSwgKCJnbmFtZSIsICJnbmFtZSIsIDMyKSk6DQoNCiAgICAgICAgICAgIGlmIGhuYW1lIGluIHBheF9oZWFkZXJzOg0KICAgICAgICAgICAgICAgICMgVGhlIHBheCBoZWFkZXIgaGFzIHByaW9yaXR5Lg0KICAgICAgICAgICAgICAgIGNvbnRpbnVlDQoNCiAgICAgICAgICAgIHZhbCA9IGluZm9bbmFtZV0uZGVjb2RlKGVuY29kaW5nLCBlcnJvcnMpDQoNCiAgICAgICAgICAgICMgVHJ5IHRvIGVuY29kZSB0aGUgc3RyaW5nIGFzIEFTQ0lJLg0KICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgIHZhbC5lbmNvZGUoImFzY2lpIikNCiAgICAgICAgICAgIGV4Y2VwdCBVbmljb2RlRW5jb2RlRXJyb3I6DQogICAgICAgICAgICAgICAgcGF4X2hlYWRlcnNbaG5hbWVdID0gdmFsDQogICAgICAgICAgICAgICAgY29udGludWUNCg0KICAgICAgICAgICAgaWYgbGVuKGluZm9bbmFtZV0pID4gbGVuZ3RoOg0KICAgICAgICAgICAgICAgIHBheF9oZWFkZXJzW2huYW1lXSA9IHZhbA0KDQogICAgICAgICMgVGVzdCBudW1iZXIgZmllbGRzIGZvciB2YWx1ZXMgdGhhdCBleGNlZWQgdGhlIGZpZWxkIGxpbWl0IG9yIHZhbHVlcw0KICAgICAgICAjIHRoYXQgbGlrZSB0byBiZSBzdG9yZWQgYXMgZmxvYXQuDQogICAgICAgIGZvciBuYW1lLCBkaWdpdHMgaW4gKCgidWlkIiwgOCksICgiZ2lkIiwgOCksICgic2l6ZSIsIDEyKSwgKCJtdGltZSIsIDEyKSk6DQogICAgICAgICAgICBpZiBuYW1lIGluIHBheF9oZWFkZXJzOg0KICAgICAgICAgICAgICAgICMgVGhlIHBheCBoZWFkZXIgaGFzIHByaW9yaXR5LiBBdm9pZCBvdmVyZmxvdy4NCiAgICAgICAgICAgICAgICBpbmZvW25hbWVdID0gMA0KICAgICAgICAgICAgICAgIGNvbnRpbnVlDQoNCiAgICAgICAgICAgIHZhbCA9IGluZm9bbmFtZV0NCiAgICAgICAgICAgIGlmIG5vdCAwIDw9IHZhbCA8IDggKiogKGRpZ2l0cyAtIDEpIG9yIGlzaW5zdGFuY2UodmFsLCBmbG9hdCk6DQogICAgICAgICAgICAgICAgcGF4X2hlYWRlcnNbbmFtZV0gPSB1bmljb2RlKHZhbCkNCiAgICAgICAgICAgICAgICBpbmZvW25hbWVdID0gMA0KDQogICAgICAgICMgQ3JlYXRlIGEgcGF4IGV4dGVuZGVkIGhlYWRlciBpZiBuZWNlc3NhcnkuDQogICAgICAgIGlmIHBheF9oZWFkZXJzOg0KICAgICAgICAgICAgYnVmID0gc2VsZi5fY3JlYXRlX3BheF9nZW5lcmljX2hlYWRlcihwYXhfaGVhZGVycykNCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIGJ1ZiA9ICIiDQoNCiAgICAgICAgcmV0dXJuIGJ1ZiArIHNlbGYuX2NyZWF0ZV9oZWFkZXIoaW5mbywgVVNUQVJfRk9STUFUKQ0KDQogICAgQGNsYXNzbWV0aG9kDQogICAgZGVmIGNyZWF0ZV9wYXhfZ2xvYmFsX2hlYWRlcihjbHMsIHBheF9oZWFkZXJzKToNCiAgICAgICAgIiIiUmV0dXJuIHRoZSBvYmplY3QgYXMgYSBwYXggZ2xvYmFsIGhlYWRlciBibG9jayBzZXF1ZW5jZS4NCiAgICAgICAgIiIiDQogICAgICAgIHJldHVybiBjbHMuX2NyZWF0ZV9wYXhfZ2VuZXJpY19oZWFkZXIocGF4X2hlYWRlcnMsIHR5cGU9WEdMVFlQRSkNCg0KICAgIGRlZiBfcG9zaXhfc3BsaXRfbmFtZShzZWxmLCBuYW1lKToNCiAgICAgICAgIiIiU3BsaXQgYSBuYW1lIGxvbmdlciB0aGFuIDEwMCBjaGFycyBpbnRvIGEgcHJlZml4DQogICAgICAgICAgIGFuZCBhIG5hbWUgcGFydC4NCiAgICAgICAgIiIiDQogICAgICAgIHByZWZpeCA9IG5hbWVbOkxFTkdUSF9QUkVGSVggKyAxXQ0KICAgICAgICB3aGlsZSBwcmVmaXggYW5kIHByZWZpeFstMV0gIT0gIi8iOg0KICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4WzotMV0NCg0KICAgICAgICBuYW1lID0gbmFtZVtsZW4ocHJlZml4KTpdDQogICAgICAgIHByZWZpeCA9IHByZWZpeFs6LTFdDQoNCiAgICAgICAgaWYgbm90IHByZWZpeCBvciBsZW4obmFtZSkgPiBMRU5HVEhfTkFNRToNCiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm5hbWUgaXMgdG9vIGxvbmciKQ0KICAgICAgICByZXR1cm4gcHJlZml4LCBuYW1lDQoNCiAgICBAc3RhdGljbWV0aG9kDQogICAgZGVmIF9jcmVhdGVfaGVhZGVyKGluZm8sIGZvcm1hdCk6DQogICAgICAgICIiIlJldHVybiBhIGhlYWRlciBibG9jay4gaW5mbyBpcyBhIGRpY3Rpb25hcnkgd2l0aCBmaWxlDQogICAgICAgICAgIGluZm9ybWF0aW9uLCBmb3JtYXQgbXVzdCBiZSBvbmUgb2YgdGhlICpfRk9STUFUIGNvbnN0YW50cy4NCiAgICAgICAgIiIiDQogICAgICAgIHBhcnRzID0gWw0KICAgICAgICAgICAgc3RuKGluZm8uZ2V0KCJuYW1lIiwgIiIpLCAxMDApLA0KICAgICAgICAgICAgaXRuKGluZm8uZ2V0KCJtb2RlIiwgMCkgJiAwNzc3NywgOCwgZm9ybWF0KSwNCiAgICAgICAgICAgIGl0bihpbmZvLmdldCgidWlkIiwgMCksIDgsIGZvcm1hdCksDQogICAgICAgICAgICBpdG4oaW5mby5nZXQoImdpZCIsIDApLCA4LCBmb3JtYXQpLA0KICAgICAgICAgICAgaXRuKGluZm8uZ2V0KCJzaXplIiwgMCksIDEyLCBmb3JtYXQpLA0KICAgICAgICAgICAgaXRuKGluZm8uZ2V0KCJtdGltZSIsIDApLCAxMiwgZm9ybWF0KSwNCiAgICAgICAgICAgICIgICAgICAgICIsICMgY2hlY2tzdW0gZmllbGQNCiAgICAgICAgICAgIGluZm8uZ2V0KCJ0eXBlIiwgUkVHVFlQRSksDQogICAgICAgICAgICBzdG4oaW5mby5nZXQoImxpbmtuYW1lIiwgIiIpLCAxMDApLA0KICAgICAgICAgICAgc3RuKGluZm8uZ2V0KCJtYWdpYyIsIFBPU0lYX01BR0lDKSwgOCksDQogICAgICAgICAgICBzdG4oaW5mby5nZXQoInVuYW1lIiwgIiIpLCAzMiksDQogICAgICAgICAgICBzdG4oaW5mby5nZXQoImduYW1lIiwgIiIpLCAzMiksDQogICAgICAgICAgICBpdG4oaW5mby5nZXQoImRldm1ham9yIiwgMCksIDgsIGZvcm1hdCksDQogICAgICAgICAgICBpdG4oaW5mby5nZXQoImRldm1pbm9yIiwgMCksIDgsIGZvcm1hdCksDQogICAgICAgICAgICBzdG4oaW5mby5nZXQoInByZWZpeCIsICIiKSwgMTU1KQ0KICAgICAgICBdDQoNCiAgICAgICAgYnVmID0gc3RydWN0LnBhY2soIiVkcyIgJSBCTE9DS1NJWkUsICIiLmpvaW4ocGFydHMpKQ0KICAgICAgICBjaGtzdW0gPSBjYWxjX2Noa3N1bXMoYnVmWy1CTE9DS1NJWkU6XSlbMF0NCiAgICAgICAgYnVmID0gYnVmWzotMzY0XSArICIlMDZvXDAiICUgY2hrc3VtICsgYnVmWy0zNTc6XQ0KICAgICAgICByZXR1cm4gYnVmDQoNCiAgICBAc3RhdGljbWV0aG9kDQogICAgZGVmIF9jcmVhdGVfcGF5bG9hZChwYXlsb2FkKToNCiAgICAgICAgIiIiUmV0dXJuIHRoZSBzdHJpbmcgcGF5bG9hZCBmaWxsZWQgd2l0aCB6ZXJvIGJ5dGVzDQogICAgICAgICAgIHVwIHRvIHRoZSBuZXh0IDUxMiBieXRlIGJvcmRlci4NCiAgICAgICAgIiIiDQogICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGxlbihwYXlsb2FkKSwgQkxPQ0tTSVpFKQ0KICAgICAgICBpZiByZW1haW5kZXIgPiAwOg0KICAgICAgICAgICAgcGF5bG9hZCArPSAoQkxPQ0tTSVpFIC0gcmVtYWluZGVyKSAqIE5VTA0KICAgICAgICByZXR1cm4gcGF5bG9hZA0KDQogICAgQGNsYXNzbWV0aG9kDQogICAgZGVmIF9jcmVhdGVfZ251X2xvbmdfaGVhZGVyKGNscywgbmFtZSwgdHlwZSk6DQogICAgICAgICIiIlJldHVybiBhIEdOVVRZUEVfTE9OR05BTUUgb3IgR05VVFlQRV9MT05HTElOSyBzZXF1ZW5jZQ0KICAgICAgICAgICBmb3IgbmFtZS4NCiAgICAgICAgIiIiDQogICAgICAgIG5hbWUgKz0gTlVMDQoNCiAgICAgICAgaW5mbyA9IHt9DQogICAgICAgIGluZm9bIm5hbWUiXSA9ICIuLy4vQExvbmdMaW5rIg0KICAgICAgICBpbmZvWyJ0eXBlIl0gPSB0eXBlDQogICAgICAgIGluZm9bInNpemUiXSA9IGxlbihuYW1lKQ0KICAgICAgICBpbmZvWyJtYWdpYyJdID0gR05VX01BR0lDDQoNCiAgICAgICAgIyBjcmVhdGUgZXh0ZW5kZWQgaGVhZGVyICsgbmFtZSBibG9ja3MuDQogICAgICAgIHJldHVybiBjbHMuX2NyZWF0ZV9oZWFkZXIoaW5mbywgVVNUQVJfRk9STUFUKSArIFwNCiAgICAgICAgICAgICAgICBjbHMuX2NyZWF0ZV9wYXlsb2FkKG5hbWUpDQoNCiAgICBAY2xhc3NtZXRob2QNCiAgICBkZWYgX2NyZWF0ZV9wYXhfZ2VuZXJpY19oZWFkZXIoY2xzLCBwYXhfaGVhZGVycywgdHlwZT1YSERUWVBFKToNCiAgICAgICAgIiIiUmV0dXJuIGEgUE9TSVguMS0yMDAxIGV4dGVuZGVkIG9yIGdsb2JhbCBoZWFkZXIgc2VxdWVuY2UNCiAgICAgICAgICAgdGhhdCBjb250YWlucyBhIGxpc3Qgb2Yga2V5d29yZCwgdmFsdWUgcGFpcnMuIFRoZSB2YWx1ZXMNCiAgICAgICAgICAgbXVzdCBiZSB1bmljb2RlIG9iamVjdHMuDQogICAgICAgICIiIg0KICAgICAgICByZWNvcmRzID0gW10NCiAgICAgICAgZm9yIGtleXdvcmQsIHZhbHVlIGluIHBheF9oZWFkZXJzLml0ZXJpdGVtcygpOg0KICAgICAgICAgICAga2V5d29yZCA9IGtleXdvcmQuZW5jb2RlKCJ1dGY4IikNCiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuZW5jb2RlKCJ1dGY4IikNCiAgICAgICAgICAgIGwgPSBsZW4oa2V5d29yZCkgKyBsZW4odmFsdWUpICsgMyAgICMgJyAnICsgJz0nICsgJ1xuJw0KICAgICAgICAgICAgbiA9IHAgPSAwDQogICAgICAgICAgICB3aGlsZSBUcnVlOg0KICAgICAgICAgICAgICAgIG4gPSBsICsgbGVuKHN0cihwKSkNCiAgICAgICAgICAgICAgICBpZiBuID09IHA6DQogICAgICAgICAgICAgICAgICAgIGJyZWFrDQogICAgICAgICAgICAgICAgcCA9IG4NCiAgICAgICAgICAgIHJlY29yZHMuYXBwZW5kKCIlZCAlcz0lc1xuIiAlIChwLCBrZXl3b3JkLCB2YWx1ZSkpDQogICAgICAgIHJlY29yZHMgPSAiIi5qb2luKHJlY29yZHMpDQoNCiAgICAgICAgIyBXZSB1c2UgYSBoYXJkY29kZWQgIi4vLi9AUGF4SGVhZGVyIiBuYW1lIGxpa2Ugc3RhciBkb2VzDQogICAgICAgICMgaW5zdGVhZCBvZiB0aGUgb25lIHRoYXQgUE9TSVggcmVjb21tZW5kcy4NCiAgICAgICAgaW5mbyA9IHt9DQogICAgICAgIGluZm9bIm5hbWUiXSA9ICIuLy4vQFBheEhlYWRlciINCiAgICAgICAgaW5mb1sidHlwZSJdID0gdHlwZQ0KICAgICAgICBpbmZvWyJzaXplIl0gPSBsZW4ocmVjb3JkcykNCiAgICAgICAgaW5mb1sibWFnaWMiXSA9IFBPU0lYX01BR0lDDQoNCiAgICAgICAgIyBDcmVhdGUgcGF4IGhlYWRlciArIHJlY29yZCBibG9ja3MuDQogICAgICAgIHJldHVybiBjbHMuX2NyZWF0ZV9oZWFkZXIoaW5mbywgVVNUQVJfRk9STUFUKSArIFwNCiAgICAgICAgICAgICAgICBjbHMuX2NyZWF0ZV9wYXlsb2FkKHJlY29yZHMpDQoNCiAgICBAY2xhc3NtZXRob2QNCiAgICBkZWYgZnJvbWJ1ZihjbHMsIGJ1Zik6DQogICAgICAgICIiIkNvbnN0cnVjdCBhIFRhckluZm8gb2JqZWN0IGZyb20gYSA1MTIgYnl0ZSBzdHJpbmcgYnVmZmVyLg0KICAgICAgICAiIiINCiAgICAgICAgaWYgbGVuKGJ1ZikgPT0gMDoNCiAgICAgICAgICAgIHJhaXNlIEVtcHR5SGVhZGVyRXJyb3IoImVtcHR5IGhlYWRlciIpDQogICAgICAgIGlmIGxlbihidWYpICE9IEJMT0NLU0laRToNCiAgICAgICAgICAgIHJhaXNlIFRydW5jYXRlZEhlYWRlckVycm9yKCJ0cnVuY2F0ZWQgaGVhZGVyIikNCiAgICAgICAgaWYgYnVmLmNvdW50KE5VTCkgPT0gQkxPQ0tTSVpFOg0KICAgICAgICAgICAgcmFpc2UgRU9GSGVhZGVyRXJyb3IoImVuZCBvZiBmaWxlIGhlYWRlciIpDQoNCiAgICAgICAgY2hrc3VtID0gbnRpKGJ1ZlsxNDg6MTU2XSkNCiAgICAgICAgaWYgY2hrc3VtIG5vdCBpbiBjYWxjX2Noa3N1bXMoYnVmKToNCiAgICAgICAgICAgIHJhaXNlIEludmFsaWRIZWFkZXJFcnJvcigiYmFkIGNoZWNrc3VtIikNCg0KICAgICAgICBvYmogPSBjbHMoKQ0KICAgICAgICBvYmouYnVmID0gYnVmDQogICAgICAgIG9iai5uYW1lID0gbnRzKGJ1ZlswOjEwMF0pDQogICAgICAgIG9iai5tb2RlID0gbnRpKGJ1ZlsxMDA6MTA4XSkNCiAgICAgICAgb2JqLnVpZCA9IG50aShidWZbMTA4OjExNl0pDQogICAgICAgIG9iai5naWQgPSBudGkoYnVmWzExNjoxMjRdKQ0KICAgICAgICBvYmouc2l6ZSA9IG50aShidWZbMTI0OjEzNl0pDQogICAgICAgIG9iai5tdGltZSA9IG50aShidWZbMTM2OjE0OF0pDQogICAgICAgIG9iai5jaGtzdW0gPSBjaGtzdW0NCiAgICAgICAgb2JqLnR5cGUgPSBidWZbMTU2OjE1N10NCiAgICAgICAgb2JqLmxpbmtuYW1lID0gbnRzKGJ1ZlsxNTc6MjU3XSkNCiAgICAgICAgb2JqLnVuYW1lID0gbnRzKGJ1ZlsyNjU6Mjk3XSkNCiAgICAgICAgb2JqLmduYW1lID0gbnRzKGJ1ZlsyOTc6MzI5XSkNCiAgICAgICAgb2JqLmRldm1ham9yID0gbnRpKGJ1ZlszMjk6MzM3XSkNCiAgICAgICAgb2JqLmRldm1pbm9yID0gbnRpKGJ1ZlszMzc6MzQ1XSkNCiAgICAgICAgcHJlZml4ID0gbnRzKGJ1ZlszNDU6NTAwXSkNCg0KICAgICAgICAjIE9sZCBWNyB0YXIgZm9ybWF0IHJlcHJlc2VudHMgYSBkaXJlY3RvcnkgYXMgYSByZWd1bGFyDQogICAgICAgICMgZmlsZSB3aXRoIGEgdHJhaWxpbmcgc2xhc2guDQogICAgICAgIGlmIG9iai50eXBlID09IEFSRUdUWVBFIGFuZCBvYmoubmFtZS5lbmRzd2l0aCgiLyIpOg0KICAgICAgICAgICAgb2JqLnR5cGUgPSBESVJUWVBFDQoNCiAgICAgICAgIyBSZW1vdmUgcmVkdW5kYW50IHNsYXNoZXMgZnJvbSBkaXJlY3Rvcmllcy4NCiAgICAgICAgaWYgb2JqLmlzZGlyKCk6DQogICAgICAgICAgICBvYmoubmFtZSA9IG9iai5uYW1lLnJzdHJpcCgiLyIpDQoNCiAgICAgICAgIyBSZWNvbnN0cnVjdCBhIHVzdGFyIGxvbmduYW1lLg0KICAgICAgICBpZiBwcmVmaXggYW5kIG9iai50eXBlIG5vdCBpbiBHTlVfVFlQRVM6DQogICAgICAgICAgICBvYmoubmFtZSA9IHByZWZpeCArICIvIiArIG9iai5uYW1lDQogICAgICAgIHJldHVybiBvYmoNCg0KICAgIEBjbGFzc21ldGhvZA0KICAgIGRlZiBmcm9tdGFyZmlsZShjbHMsIHRhcmZpbGUpOg0KICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgVGFySW5mbyBvYmplY3QgZnJvbSBUYXJGaWxlIG9iamVjdA0KICAgICAgICAgICB0YXJmaWxlLg0KICAgICAgICAiIiINCiAgICAgICAgYnVmID0gdGFyZmlsZS5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQ0KICAgICAgICBvYmogPSBjbHMuZnJvbWJ1ZihidWYpDQogICAgICAgIG9iai5vZmZzZXQgPSB0YXJmaWxlLmZpbGVvYmoudGVsbCgpIC0gQkxPQ0tTSVpFDQogICAgICAgIHJldHVybiBvYmouX3Byb2NfbWVtYmVyKHRhcmZpbGUpDQoNCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiAgICAjIFRoZSBmb2xsb3dpbmcgYXJlIG1ldGhvZHMgdGhhdCBhcmUgY2FsbGVkIGRlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiBhDQogICAgIyBtZW1iZXIuIFRoZSBlbnRyeSBwb2ludCBpcyBfcHJvY19tZW1iZXIoKSB3aGljaCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBhDQogICAgIyBzdWJjbGFzcyB0byBhZGQgY3VzdG9tIF9wcm9jXyooKSBtZXRob2RzLiBBIF9wcm9jXyooKSBtZXRob2QgTVVTVA0KICAgICMgaW1wbGVtZW50IHRoZSBmb2xsb3dpbmcNCiAgICAjIG9wZXJhdGlvbnM6DQogICAgIyAxLiBTZXQgc2VsZi5vZmZzZXRfZGF0YSB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIGRhdGEgYmxvY2tzIGJlZ2luLA0KICAgICMgICAgaWYgdGhlcmUgaXMgZGF0YSB0aGF0IGZvbGxvd3MuDQogICAgIyAyLiBTZXQgdGFyZmlsZS5vZmZzZXQgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBuZXh0IG1lbWJlcidzIGhlYWRlciB3aWxsDQogICAgIyAgICBiZWdpbi4NCiAgICAjIDMuIFJldHVybiBzZWxmIG9yIGFub3RoZXIgdmFsaWQgVGFySW5mbyBvYmplY3QuDQogICAgZGVmIF9wcm9jX21lbWJlcihzZWxmLCB0YXJmaWxlKToNCiAgICAgICAgIiIiQ2hvb3NlIHRoZSByaWdodCBwcm9jZXNzaW5nIG1ldGhvZCBkZXBlbmRpbmcgb24NCiAgICAgICAgICAgdGhlIHR5cGUgYW5kIGNhbGwgaXQuDQogICAgICAgICIiIg0KICAgICAgICBpZiBzZWxmLnR5cGUgaW4gKEdOVVRZUEVfTE9OR05BTUUsIEdOVVRZUEVfTE9OR0xJTkspOg0KICAgICAgICAgICAgcmV0dXJuIHNlbGYuX3Byb2NfZ251bG9uZyh0YXJmaWxlKQ0KICAgICAgICBlbGlmIHNlbGYudHlwZSA9PSBHTlVUWVBFX1NQQVJTRToNCiAgICAgICAgICAgIHJldHVybiBzZWxmLl9wcm9jX3NwYXJzZSh0YXJmaWxlKQ0KICAgICAgICBlbGlmIHNlbGYudHlwZSBpbiAoWEhEVFlQRSwgWEdMVFlQRSwgU09MQVJJU19YSERUWVBFKToNCiAgICAgICAgICAgIHJldHVybiBzZWxmLl9wcm9jX3BheCh0YXJmaWxlKQ0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgcmV0dXJuIHNlbGYuX3Byb2NfYnVpbHRpbih0YXJmaWxlKQ0KDQogICAgZGVmIF9wcm9jX2J1aWx0aW4oc2VsZiwgdGFyZmlsZSk6DQogICAgICAgICIiIlByb2Nlc3MgYSBidWlsdGluIHR5cGUgb3IgYW4gdW5rbm93biB0eXBlIHdoaWNoDQogICAgICAgICAgIHdpbGwgYmUgdHJlYXRlZCBhcyBhIHJlZ3VsYXIgZmlsZS4NCiAgICAgICAgIiIiDQogICAgICAgIHNlbGYub2Zmc2V0X2RhdGEgPSB0YXJmaWxlLmZpbGVvYmoudGVsbCgpDQogICAgICAgIG9mZnNldCA9IHNlbGYub2Zmc2V0X2RhdGENCiAgICAgICAgaWYgc2VsZi5pc3JlZygpIG9yIHNlbGYudHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOg0KICAgICAgICAgICAgIyBTa2lwIHRoZSBmb2xsb3dpbmcgZGF0YSBibG9ja3MuDQogICAgICAgICAgICBvZmZzZXQgKz0gc2VsZi5fYmxvY2soc2VsZi5zaXplKQ0KICAgICAgICB0YXJmaWxlLm9mZnNldCA9IG9mZnNldA0KDQogICAgICAgICMgUGF0Y2ggdGhlIFRhckluZm8gb2JqZWN0IHdpdGggc2F2ZWQgZ2xvYmFsDQogICAgICAgICMgaGVhZGVyIGluZm9ybWF0aW9uLg0KICAgICAgICBzZWxmLl9hcHBseV9wYXhfaW5mbyh0YXJmaWxlLnBheF9oZWFkZXJzLCB0YXJmaWxlLmVuY29kaW5nLCB0YXJmaWxlLmVycm9ycykNCg0KICAgICAgICByZXR1cm4gc2VsZg0KDQogICAgZGVmIF9wcm9jX2dudWxvbmcoc2VsZiwgdGFyZmlsZSk6DQogICAgICAgICIiIlByb2Nlc3MgdGhlIGJsb2NrcyB0aGF0IGhvbGQgYSBHTlUgbG9uZ25hbWUNCiAgICAgICAgICAgb3IgbG9uZ2xpbmsgbWVtYmVyLg0KICAgICAgICAiIiINCiAgICAgICAgYnVmID0gdGFyZmlsZS5maWxlb2JqLnJlYWQoc2VsZi5fYmxvY2soc2VsZi5zaXplKSkNCg0KICAgICAgICAjIEZldGNoIHRoZSBuZXh0IGhlYWRlciBhbmQgcHJvY2VzcyBpdC4NCiAgICAgICAgdHJ5Og0KICAgICAgICAgICAgbmV4dCA9IHNlbGYuZnJvbXRhcmZpbGUodGFyZmlsZSkNCiAgICAgICAgZXhjZXB0IEhlYWRlckVycm9yOg0KICAgICAgICAgICAgcmFpc2UgU3Vic2VxdWVudEhlYWRlckVycm9yKCJtaXNzaW5nIG9yIGJhZCBzdWJzZXF1ZW50IGhlYWRlciIpDQoNCiAgICAgICAgIyBQYXRjaCB0aGUgVGFySW5mbyBvYmplY3QgZnJvbSB0aGUgbmV4dCBoZWFkZXIgd2l0aA0KICAgICAgICAjIHRoZSBsb25nbmFtZSBpbmZvcm1hdGlvbi4NCiAgICAgICAgbmV4dC5vZmZzZXQgPSBzZWxmLm9mZnNldA0KICAgICAgICBpZiBzZWxmLnR5cGUgPT0gR05VVFlQRV9MT05HTkFNRToNCiAgICAgICAgICAgIG5leHQubmFtZSA9IG50cyhidWYpDQogICAgICAgIGVsaWYgc2VsZi50eXBlID09IEdOVVRZUEVfTE9OR0xJTks6DQogICAgICAgICAgICBuZXh0LmxpbmtuYW1lID0gbnRzKGJ1ZikNCg0KICAgICAgICByZXR1cm4gbmV4dA0KDQogICAgZGVmIF9wcm9jX3NwYXJzZShzZWxmLCB0YXJmaWxlKToNCiAgICAgICAgIiIiUHJvY2VzcyBhIEdOVSBzcGFyc2UgaGVhZGVyIHBsdXMgZXh0cmEgaGVhZGVycy4NCiAgICAgICAgIiIiDQogICAgICAgIGJ1ZiA9IHNlbGYuYnVmDQogICAgICAgIHNwID0gX3JpbmdidWZmZXIoKQ0KICAgICAgICBwb3MgPSAzODYNCiAgICAgICAgbGFzdHBvcyA9IDBMDQogICAgICAgIHJlYWxwb3MgPSAwTA0KICAgICAgICAjIFRoZXJlIGFyZSA0IHBvc3NpYmxlIHNwYXJzZSBzdHJ1Y3RzIGluIHRoZQ0KICAgICAgICAjIGZpcnN0IGhlYWRlci4NCiAgICAgICAgZm9yIGkgaW4geHJhbmdlKDQpOg0KICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgIG9mZnNldCA9IG50aShidWZbcG9zOnBvcyArIDEyXSkNCiAgICAgICAgICAgICAgICBudW1ieXRlcyA9IG50aShidWZbcG9zICsgMTI6cG9zICsgMjRdKQ0KICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6DQogICAgICAgICAgICAgICAgYnJlYWsNCiAgICAgICAgICAgIGlmIG9mZnNldCA+IGxhc3Rwb3M6DQogICAgICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9mZnNldCAtIGxhc3Rwb3MpKQ0KICAgICAgICAgICAgc3AuYXBwZW5kKF9kYXRhKG9mZnNldCwgbnVtYnl0ZXMsIHJlYWxwb3MpKQ0KICAgICAgICAgICAgcmVhbHBvcyArPSBudW1ieXRlcw0KICAgICAgICAgICAgbGFzdHBvcyA9IG9mZnNldCArIG51bWJ5dGVzDQogICAgICAgICAgICBwb3MgKz0gMjQNCg0KICAgICAgICBpc2V4dGVuZGVkID0gb3JkKGJ1Zls0ODJdKQ0KICAgICAgICBvcmlnc2l6ZSA9IG50aShidWZbNDgzOjQ5NV0pDQoNCiAgICAgICAgIyBJZiB0aGUgaXNleHRlbmRlZCBmbGFnIGlzIGdpdmVuLA0KICAgICAgICAjIHRoZXJlIGFyZSBleHRyYSBoZWFkZXJzIHRvIHByb2Nlc3MuDQogICAgICAgIHdoaWxlIGlzZXh0ZW5kZWQgPT0gMToNCiAgICAgICAgICAgIGJ1ZiA9IHRhcmZpbGUuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkNCiAgICAgICAgICAgIHBvcyA9IDANCiAgICAgICAgICAgIGZvciBpIGluIHhyYW5nZSgyMSk6DQogICAgICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBudGkoYnVmW3Bvczpwb3MgKyAxMl0pDQogICAgICAgICAgICAgICAgICAgIG51bWJ5dGVzID0gbnRpKGJ1Zltwb3MgKyAxMjpwb3MgKyAyNF0pDQogICAgICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6DQogICAgICAgICAgICAgICAgICAgIGJyZWFrDQogICAgICAgICAgICAgICAgaWYgb2Zmc2V0ID4gbGFzdHBvczoNCiAgICAgICAgICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9mZnNldCAtIGxhc3Rwb3MpKQ0KICAgICAgICAgICAgICAgIHNwLmFwcGVuZChfZGF0YShvZmZzZXQsIG51bWJ5dGVzLCByZWFscG9zKSkNCiAgICAgICAgICAgICAgICByZWFscG9zICs9IG51bWJ5dGVzDQogICAgICAgICAgICAgICAgbGFzdHBvcyA9IG9mZnNldCArIG51bWJ5dGVzDQogICAgICAgICAgICAgICAgcG9zICs9IDI0DQogICAgICAgICAgICBpc2V4dGVuZGVkID0gb3JkKGJ1Zls1MDRdKQ0KDQogICAgICAgIGlmIGxhc3Rwb3MgPCBvcmlnc2l6ZToNCiAgICAgICAgICAgIHNwLmFwcGVuZChfaG9sZShsYXN0cG9zLCBvcmlnc2l6ZSAtIGxhc3Rwb3MpKQ0KDQogICAgICAgIHNlbGYuc3BhcnNlID0gc3ANCg0KICAgICAgICBzZWxmLm9mZnNldF9kYXRhID0gdGFyZmlsZS5maWxlb2JqLnRlbGwoKQ0KICAgICAgICB0YXJmaWxlLm9mZnNldCA9IHNlbGYub2Zmc2V0X2RhdGEgKyBzZWxmLl9ibG9jayhzZWxmLnNpemUpDQogICAgICAgIHNlbGYuc2l6ZSA9IG9yaWdzaXplDQoNCiAgICAgICAgcmV0dXJuIHNlbGYNCg0KICAgIGRlZiBfcHJvY19wYXgoc2VsZiwgdGFyZmlsZSk6DQogICAgICAgICIiIlByb2Nlc3MgYW4gZXh0ZW5kZWQgb3IgZ2xvYmFsIGhlYWRlciBhcyBkZXNjcmliZWQgaW4NCiAgICAgICAgICAgUE9TSVguMS0yMDAxLg0KICAgICAgICAiIiINCiAgICAgICAgIyBSZWFkIHRoZSBoZWFkZXIgaW5mb3JtYXRpb24uDQogICAgICAgIGJ1ZiA9IHRhcmZpbGUuZmlsZW9iai5yZWFkKHNlbGYuX2Jsb2NrKHNlbGYuc2l6ZSkpDQoNCiAgICAgICAgIyBBIHBheCBoZWFkZXIgc3RvcmVzIHN1cHBsZW1lbnRhbCBpbmZvcm1hdGlvbiBmb3IgZWl0aGVyDQogICAgICAgICMgdGhlIGZvbGxvd2luZyBmaWxlIChleHRlbmRlZCkgb3IgYWxsIGZvbGxvd2luZyBmaWxlcw0KICAgICAgICAjIChnbG9iYWwpLg0KICAgICAgICBpZiBzZWxmLnR5cGUgPT0gWEdMVFlQRToNCiAgICAgICAgICAgIHBheF9oZWFkZXJzID0gdGFyZmlsZS5wYXhfaGVhZGVycw0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgcGF4X2hlYWRlcnMgPSB0YXJmaWxlLnBheF9oZWFkZXJzLmNvcHkoKQ0KDQogICAgICAgICMgUGFyc2UgcGF4IGhlYWRlciBpbmZvcm1hdGlvbi4gQSByZWNvcmQgbG9va3MgbGlrZSB0aGF0Og0KICAgICAgICAjICIlZCAlcz0lc1xuIiAlIChsZW5ndGgsIGtleXdvcmQsIHZhbHVlKS4gbGVuZ3RoIGlzIHRoZSBzaXplDQogICAgICAgICMgb2YgdGhlIGNvbXBsZXRlIHJlY29yZCBpbmNsdWRpbmcgdGhlIGxlbmd0aCBmaWVsZCBpdHNlbGYgYW5kDQogICAgICAgICMgdGhlIG5ld2xpbmUuIGtleXdvcmQgYW5kIHZhbHVlIGFyZSBib3RoIFVURi04IGVuY29kZWQgc3RyaW5ncy4NCiAgICAgICAgcmVnZXggPSByZS5jb21waWxlKHIiKFxkKykgKFtePV0rKT0iLCByZS5VKQ0KICAgICAgICBwb3MgPSAwDQogICAgICAgIHdoaWxlIFRydWU6DQogICAgICAgICAgICBtYXRjaCA9IHJlZ2V4Lm1hdGNoKGJ1ZiwgcG9zKQ0KICAgICAgICAgICAgaWYgbm90IG1hdGNoOg0KICAgICAgICAgICAgICAgIGJyZWFrDQoNCiAgICAgICAgICAgIGxlbmd0aCwga2V5d29yZCA9IG1hdGNoLmdyb3VwcygpDQogICAgICAgICAgICBsZW5ndGggPSBpbnQobGVuZ3RoKQ0KICAgICAgICAgICAgdmFsdWUgPSBidWZbbWF0Y2guZW5kKDIpICsgMTptYXRjaC5zdGFydCgxKSArIGxlbmd0aCAtIDFdDQoNCiAgICAgICAgICAgIGtleXdvcmQgPSBrZXl3b3JkLmRlY29kZSgidXRmOCIpDQogICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmRlY29kZSgidXRmOCIpDQoNCiAgICAgICAgICAgIHBheF9oZWFkZXJzW2tleXdvcmRdID0gdmFsdWUNCiAgICAgICAgICAgIHBvcyArPSBsZW5ndGgNCg0KICAgICAgICAjIEZldGNoIHRoZSBuZXh0IGhlYWRlci4NCiAgICAgICAgdHJ5Og0KICAgICAgICAgICAgbmV4dCA9IHNlbGYuZnJvbXRhcmZpbGUodGFyZmlsZSkNCiAgICAgICAgZXhjZXB0IEhlYWRlckVycm9yOg0KICAgICAgICAgICAgcmFpc2UgU3Vic2VxdWVudEhlYWRlckVycm9yKCJtaXNzaW5nIG9yIGJhZCBzdWJzZXF1ZW50IGhlYWRlciIpDQoNCiAgICAgICAgaWYgc2VsZi50eXBlIGluIChYSERUWVBFLCBTT0xBUklTX1hIRFRZUEUpOg0KICAgICAgICAgICAgIyBQYXRjaCB0aGUgVGFySW5mbyBvYmplY3Qgd2l0aCB0aGUgZXh0ZW5kZWQgaGVhZGVyIGluZm8uDQogICAgICAgICAgICBuZXh0Ll9hcHBseV9wYXhfaW5mbyhwYXhfaGVhZGVycywgdGFyZmlsZS5lbmNvZGluZywgdGFyZmlsZS5lcnJvcnMpDQogICAgICAgICAgICBuZXh0Lm9mZnNldCA9IHNlbGYub2Zmc2V0DQoNCiAgICAgICAgICAgIGlmICJzaXplIiBpbiBwYXhfaGVhZGVyczoNCiAgICAgICAgICAgICAgICAjIElmIHRoZSBleHRlbmRlZCBoZWFkZXIgcmVwbGFjZXMgdGhlIHNpemUgZmllbGQsDQogICAgICAgICAgICAgICAgIyB3ZSBuZWVkIHRvIHJlY2FsY3VsYXRlIHRoZSBvZmZzZXQgd2hlcmUgdGhlIG5leHQNCiAgICAgICAgICAgICAgICAjIGhlYWRlciBzdGFydHMuDQogICAgICAgICAgICAgICAgb2Zmc2V0ID0gbmV4dC5vZmZzZXRfZGF0YQ0KICAgICAgICAgICAgICAgIGlmIG5leHQuaXNyZWcoKSBvciBuZXh0LnR5cGUgbm90IGluIFNVUFBPUlRFRF9UWVBFUzoNCiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IG5leHQuX2Jsb2NrKG5leHQuc2l6ZSkNCiAgICAgICAgICAgICAgICB0YXJmaWxlLm9mZnNldCA9IG9mZnNldA0KDQogICAgICAgIHJldHVybiBuZXh0DQoNCiAgICBkZWYgX2FwcGx5X3BheF9pbmZvKHNlbGYsIHBheF9oZWFkZXJzLCBlbmNvZGluZywgZXJyb3JzKToNCiAgICAgICAgIiIiUmVwbGFjZSBmaWVsZHMgd2l0aCBzdXBwbGVtZW50YWwgaW5mb3JtYXRpb24gZnJvbSBhIHByZXZpb3VzDQogICAgICAgICAgIHBheCBleHRlbmRlZCBvciBnbG9iYWwgaGVhZGVyLg0KICAgICAgICAiIiINCiAgICAgICAgZm9yIGtleXdvcmQsIHZhbHVlIGluIHBheF9oZWFkZXJzLml0ZXJpdGVtcygpOg0KICAgICAgICAgICAgaWYga2V5d29yZCBub3QgaW4gUEFYX0ZJRUxEUzoNCiAgICAgICAgICAgICAgICBjb250aW51ZQ0KDQogICAgICAgICAgICBpZiBrZXl3b3JkID09ICJwYXRoIjoNCiAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnJzdHJpcCgiLyIpDQoNCiAgICAgICAgICAgIGlmIGtleXdvcmQgaW4gUEFYX05VTUJFUl9GSUVMRFM6DQogICAgICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IFBBWF9OVU1CRVJfRklFTERTW2tleXdvcmRdKHZhbHVlKQ0KICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOg0KICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IDANCiAgICAgICAgICAgIGVsc2U6DQogICAgICAgICAgICAgICAgdmFsdWUgPSB1dHModmFsdWUsIGVuY29kaW5nLCBlcnJvcnMpDQoNCiAgICAgICAgICAgIHNldGF0dHIoc2VsZiwga2V5d29yZCwgdmFsdWUpDQoNCiAgICAgICAgc2VsZi5wYXhfaGVhZGVycyA9IHBheF9oZWFkZXJzLmNvcHkoKQ0KDQogICAgZGVmIF9ibG9jayhzZWxmLCBjb3VudCk6DQogICAgICAgICIiIlJvdW5kIHVwIGEgYnl0ZSBjb3VudCBieSBCTE9DS1NJWkUgYW5kIHJldHVybiBpdCwNCiAgICAgICAgICAgZS5nLiBfYmxvY2soODM0KSA9PiAxMDI0Lg0KICAgICAgICAiIiINCiAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QoY291bnQsIEJMT0NLU0laRSkNCiAgICAgICAgaWYgcmVtYWluZGVyOg0KICAgICAgICAgICAgYmxvY2tzICs9IDENCiAgICAgICAgcmV0dXJuIGJsb2NrcyAqIEJMT0NLU0laRQ0KDQogICAgZGVmIGlzcmVnKHNlbGYpOg0KICAgICAgICByZXR1cm4gc2VsZi50eXBlIGluIFJFR1VMQVJfVFlQRVMNCiAgICBkZWYgaXNmaWxlKHNlbGYpOg0KICAgICAgICByZXR1cm4gc2VsZi5pc3JlZygpDQogICAgZGVmIGlzZGlyKHNlbGYpOg0KICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IERJUlRZUEUNCiAgICBkZWYgaXNzeW0oc2VsZik6DQogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gU1lNVFlQRQ0KICAgIGRlZiBpc2xuayhzZWxmKToNCiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBMTktUWVBFDQogICAgZGVmIGlzY2hyKHNlbGYpOg0KICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IENIUlRZUEUNCiAgICBkZWYgaXNibGsoc2VsZik6DQogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gQkxLVFlQRQ0KICAgIGRlZiBpc2ZpZm8oc2VsZik6DQogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gRklGT1RZUEUNCiAgICBkZWYgaXNzcGFyc2Uoc2VsZik6DQogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gR05VVFlQRV9TUEFSU0UNCiAgICBkZWYgaXNkZXYoc2VsZik6DQogICAgICAgIHJldHVybiBzZWxmLnR5cGUgaW4gKENIUlRZUEUsIEJMS1RZUEUsIEZJRk9UWVBFKQ0KIyBjbGFzcyBUYXJJbmZvDQoNCmNsYXNzIFRhckZpbGUob2JqZWN0KToNCiAgICAiIiJUaGUgVGFyRmlsZSBDbGFzcyBwcm92aWRlcyBhbiBpbnRlcmZhY2UgdG8gdGFyIGFyY2hpdmVzLg0KICAgICIiIg0KDQogICAgZGVidWcgPSAwICAgICAgICAgICAgICAgICAgICMgTWF5IGJlIHNldCBmcm9tIDAgKG5vIG1zZ3MpIHRvIDMgKGFsbCBtc2dzKQ0KDQogICAgZGVyZWZlcmVuY2UgPSBGYWxzZSAgICAgICAgICMgSWYgdHJ1ZSwgYWRkIGNvbnRlbnQgb2YgbGlua2VkIGZpbGUgdG8gdGhlDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGFyIGZpbGUsIGVsc2UgdGhlIGxpbmsuDQoNCiAgICBpZ25vcmVfemVyb3MgPSBGYWxzZSAgICAgICAgIyBJZiB0cnVlLCBza2lwcyBlbXB0eSBvciBpbnZhbGlkIGJsb2NrcyBhbmQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBjb250aW51ZXMgcHJvY2Vzc2luZy4NCg0KICAgIGVycm9ybGV2ZWwgPSAxICAgICAgICAgICAgICAjIElmIDAsIGZhdGFsIGVycm9ycyBvbmx5IGFwcGVhciBpbiBkZWJ1Zw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG1lc3NhZ2VzIChpZiBkZWJ1ZyA+PSAwKS4gSWYgPiAwLCBlcnJvcnMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhcmUgcGFzc2VkIHRvIHRoZSBjYWxsZXIgYXMgZXhjZXB0aW9ucy4NCg0KICAgIGZvcm1hdCA9IERFRkFVTFRfRk9STUFUICAgICAjIFRoZSBmb3JtYXQgdG8gdXNlIHdoZW4gY3JlYXRpbmcgYW4gYXJjaGl2ZS4NCg0KICAgIGVuY29kaW5nID0gRU5DT0RJTkcgICAgICAgICAjIEVuY29kaW5nIGZvciA4LWJpdCBjaGFyYWN0ZXIgc3RyaW5ncy4NCg0KICAgIGVycm9ycyA9IE5vbmUgICAgICAgICAgICAgICAjIEVycm9yIGhhbmRsZXIgZm9yIHVuaWNvZGUgY29udmVyc2lvbi4NCg0KICAgIHRhcmluZm8gPSBUYXJJbmZvICAgICAgICAgICAjIFRoZSBkZWZhdWx0IFRhckluZm8gY2xhc3MgdG8gdXNlLg0KDQogICAgZmlsZW9iamVjdCA9IEV4RmlsZU9iamVjdCAgICMgVGhlIGRlZmF1bHQgRXhGaWxlT2JqZWN0IGNsYXNzIHRvIHVzZS4NCg0KICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lPU5vbmUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGZvcm1hdD1Ob25lLA0KICAgICAgICAgICAgdGFyaW5mbz1Ob25lLCBkZXJlZmVyZW5jZT1Ob25lLCBpZ25vcmVfemVyb3M9Tm9uZSwgZW5jb2Rpbmc9Tm9uZSwNCiAgICAgICAgICAgIGVycm9ycz1Ob25lLCBwYXhfaGVhZGVycz1Ob25lLCBkZWJ1Zz1Ob25lLCBlcnJvcmxldmVsPU5vbmUpOg0KICAgICAgICAiIiJPcGVuIGFuICh1bmNvbXByZXNzZWQpIHRhciBhcmNoaXZlIGBuYW1lJy4gYG1vZGUnIGlzIGVpdGhlciAncicgdG8NCiAgICAgICAgICAgcmVhZCBmcm9tIGFuIGV4aXN0aW5nIGFyY2hpdmUsICdhJyB0byBhcHBlbmQgZGF0YSB0byBhbiBleGlzdGluZw0KICAgICAgICAgICBmaWxlIG9yICd3JyB0byBjcmVhdGUgYSBuZXcgZmlsZSBvdmVyd3JpdGluZyBhbiBleGlzdGluZyBvbmUuIGBtb2RlJw0KICAgICAgICAgICBkZWZhdWx0cyB0byAncicuDQogICAgICAgICAgIElmIGBmaWxlb2JqJyBpcyBnaXZlbiwgaXQgaXMgdXNlZCBmb3IgcmVhZGluZyBvciB3cml0aW5nIGRhdGEuIElmIGl0DQogICAgICAgICAgIGNhbiBiZSBkZXRlcm1pbmVkLCBgbW9kZScgaXMgb3ZlcnJpZGRlbiBieSBgZmlsZW9iaidzIG1vZGUuDQogICAgICAgICAgIGBmaWxlb2JqJyBpcyBub3QgY2xvc2VkLCB3aGVuIFRhckZpbGUgaXMgY2xvc2VkLg0KICAgICAgICAiIiINCiAgICAgICAgaWYgbGVuKG1vZGUpID4gMSBvciBtb2RlIG5vdCBpbiAicmF3IjoNCiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm1vZGUgbXVzdCBiZSAncicsICdhJyBvciAndyciKQ0KICAgICAgICBzZWxmLm1vZGUgPSBtb2RlDQogICAgICAgIHNlbGYuX21vZGUgPSB7InIiOiAicmIiLCAiYSI6ICJyK2IiLCAidyI6ICJ3YiJ9W21vZGVdDQoNCiAgICAgICAgaWYgbm90IGZpbGVvYmo6DQogICAgICAgICAgICBpZiBzZWxmLm1vZGUgPT0gImEiIGFuZCBub3Qgb3MucGF0aC5leGlzdHMobmFtZSk6DQogICAgICAgICAgICAgICAgIyBDcmVhdGUgbm9uZXhpc3RlbnQgZmlsZXMgaW4gYXBwZW5kIG1vZGUuDQogICAgICAgICAgICAgICAgc2VsZi5tb2RlID0gInciDQogICAgICAgICAgICAgICAgc2VsZi5fbW9kZSA9ICJ3YiINCiAgICAgICAgICAgIGZpbGVvYmogPSBibHRuX29wZW4obmFtZSwgc2VsZi5fbW9kZSkNCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBGYWxzZQ0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgaWYgbmFtZSBpcyBOb25lIGFuZCBoYXNhdHRyKGZpbGVvYmosICJuYW1lIik6DQogICAgICAgICAgICAgICAgbmFtZSA9IGZpbGVvYmoubmFtZQ0KICAgICAgICAgICAgaWYgaGFzYXR0cihmaWxlb2JqLCAibW9kZSIpOg0KICAgICAgICAgICAgICAgIHNlbGYuX21vZGUgPSBmaWxlb2JqLm1vZGUNCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlDQogICAgICAgIHNlbGYubmFtZSA9IG9zLnBhdGguYWJzcGF0aChuYW1lKSBpZiBuYW1lIGVsc2UgTm9uZQ0KICAgICAgICBzZWxmLmZpbGVvYmogPSBmaWxlb2JqDQoNCiAgICAgICAgIyBJbml0IGF0dHJpYnV0ZXMuDQogICAgICAgIGlmIGZvcm1hdCBpcyBub3QgTm9uZToNCiAgICAgICAgICAgIHNlbGYuZm9ybWF0ID0gZm9ybWF0DQogICAgICAgIGlmIHRhcmluZm8gaXMgbm90IE5vbmU6DQogICAgICAgICAgICBzZWxmLnRhcmluZm8gPSB0YXJpbmZvDQogICAgICAgIGlmIGRlcmVmZXJlbmNlIGlzIG5vdCBOb25lOg0KICAgICAgICAgICAgc2VsZi5kZXJlZmVyZW5jZSA9IGRlcmVmZXJlbmNlDQogICAgICAgIGlmIGlnbm9yZV96ZXJvcyBpcyBub3QgTm9uZToNCiAgICAgICAgICAgIHNlbGYuaWdub3JlX3plcm9zID0gaWdub3JlX3plcm9zDQogICAgICAgIGlmIGVuY29kaW5nIGlzIG5vdCBOb25lOg0KICAgICAgICAgICAgc2VsZi5lbmNvZGluZyA9IGVuY29kaW5nDQoNCiAgICAgICAgaWYgZXJyb3JzIGlzIG5vdCBOb25lOg0KICAgICAgICAgICAgc2VsZi5lcnJvcnMgPSBlcnJvcnMNCiAgICAgICAgZWxpZiBtb2RlID09ICJyIjoNCiAgICAgICAgICAgIHNlbGYuZXJyb3JzID0gInV0Zi04Ig0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgc2VsZi5lcnJvcnMgPSAic3RyaWN0Ig0KDQogICAgICAgIGlmIHBheF9oZWFkZXJzIGlzIG5vdCBOb25lIGFuZCBzZWxmLmZvcm1hdCA9PSBQQVhfRk9STUFUOg0KICAgICAgICAgICAgc2VsZi5wYXhfaGVhZGVycyA9IHBheF9oZWFkZXJzDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICBzZWxmLnBheF9oZWFkZXJzID0ge30NCg0KICAgICAgICBpZiBkZWJ1ZyBpcyBub3QgTm9uZToNCiAgICAgICAgICAgIHNlbGYuZGVidWcgPSBkZWJ1Zw0KICAgICAgICBpZiBlcnJvcmxldmVsIGlzIG5vdCBOb25lOg0KICAgICAgICAgICAgc2VsZi5lcnJvcmxldmVsID0gZXJyb3JsZXZlbA0KDQogICAgICAgICMgSW5pdCBkYXRhc3RydWN0dXJlcy4NCiAgICAgICAgc2VsZi5jbG9zZWQgPSBGYWxzZQ0KICAgICAgICBzZWxmLm1lbWJlcnMgPSBbXSAgICAgICAjIGxpc3Qgb2YgbWVtYmVycyBhcyBUYXJJbmZvIG9iamVjdHMNCiAgICAgICAgc2VsZi5fbG9hZGVkID0gRmFsc2UgICAgIyBmbGFnIGlmIGFsbCBtZW1iZXJzIGhhdmUgYmVlbiByZWFkDQogICAgICAgIHNlbGYub2Zmc2V0ID0gc2VsZi5maWxlb2JqLnRlbGwoKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIGFyY2hpdmUgZmlsZQ0KICAgICAgICBzZWxmLmlub2RlcyA9IHt9ICAgICAgICAjIGRpY3Rpb25hcnkgY2FjaGluZyB0aGUgaW5vZGVzIG9mDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJjaGl2ZSBtZW1iZXJzIGFscmVhZHkgYWRkZWQNCg0KICAgICAgICB0cnk6DQogICAgICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInIiOg0KICAgICAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lDQogICAgICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IHNlbGYubmV4dCgpDQoNCiAgICAgICAgICAgIGlmIHNlbGYubW9kZSA9PSAiYSI6DQogICAgICAgICAgICAgICAgIyBNb3ZlIHRvIHRoZSBlbmQgb2YgdGhlIGFyY2hpdmUsDQogICAgICAgICAgICAgICAgIyBiZWZvcmUgdGhlIGZpcnN0IGVtcHR5IGJsb2NrLg0KICAgICAgICAgICAgICAgIHdoaWxlIFRydWU6DQogICAgICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0KQ0KICAgICAgICAgICAgICAgICAgICB0cnk6DQogICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJpbmZvLmZyb210YXJmaWxlKHNlbGYpDQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm1lbWJlcnMuYXBwZW5kKHRhcmluZm8pDQogICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBFT0ZIZWFkZXJFcnJvcjoNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0KQ0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsNCiAgICAgICAgICAgICAgICAgICAgZXhjZXB0IEhlYWRlckVycm9yLCBlOg0KICAgICAgICAgICAgICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKHN0cihlKSkNCg0KICAgICAgICAgICAgaWYgc2VsZi5tb2RlIGluICJhdyI6DQogICAgICAgICAgICAgICAgc2VsZi5fbG9hZGVkID0gVHJ1ZQ0KDQogICAgICAgICAgICAgICAgaWYgc2VsZi5wYXhfaGVhZGVyczoNCiAgICAgICAgICAgICAgICAgICAgYnVmID0gc2VsZi50YXJpbmZvLmNyZWF0ZV9wYXhfZ2xvYmFsX2hlYWRlcihzZWxmLnBheF9oZWFkZXJzLmNvcHkoKSkNCiAgICAgICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKGJ1ZikNCiAgICAgICAgICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gbGVuKGJ1ZikNCiAgICAgICAgZXhjZXB0Og0KICAgICAgICAgICAgaWYgbm90IHNlbGYuX2V4dGZpbGVvYmo6DQogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLmNsb3NlKCkNCiAgICAgICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQ0KICAgICAgICAgICAgcmFpc2UNCg0KICAgIGRlZiBfZ2V0cG9zaXgoc2VsZik6DQogICAgICAgIHJldHVybiBzZWxmLmZvcm1hdCA9PSBVU1RBUl9GT1JNQVQNCiAgICBkZWYgX3NldHBvc2l4KHNlbGYsIHZhbHVlKToNCiAgICAgICAgaW1wb3J0IHdhcm5pbmdzDQogICAgICAgIHdhcm5pbmdzLndhcm4oInVzZSB0aGUgZm9ybWF0IGF0dHJpYnV0ZSBpbnN0ZWFkIiwgRGVwcmVjYXRpb25XYXJuaW5nLA0KICAgICAgICAgICAgICAgICAgICAgIDIpDQogICAgICAgIGlmIHZhbHVlOg0KICAgICAgICAgICAgc2VsZi5mb3JtYXQgPSBVU1RBUl9GT1JNQVQNCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIHNlbGYuZm9ybWF0ID0gR05VX0ZPUk1BVA0KICAgIHBvc2l4ID0gcHJvcGVydHkoX2dldHBvc2l4LCBfc2V0cG9zaXgpDQoNCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiAgICAjIEJlbG93IGFyZSB0aGUgY2xhc3NtZXRob2RzIHdoaWNoIGFjdCBhcyBhbHRlcm5hdGUgY29uc3RydWN0b3JzIHRvIHRoZQ0KICAgICMgVGFyRmlsZSBjbGFzcy4gVGhlIG9wZW4oKSBtZXRob2QgaXMgdGhlIG9ubHkgb25lIHRoYXQgaXMgbmVlZGVkIGZvcg0KICAgICMgcHVibGljIHVzZTsgaXQgaXMgdGhlICJzdXBlciItY29uc3RydWN0b3IgYW5kIGlzIGFibGUgdG8gc2VsZWN0IGFuDQogICAgIyBhZGVxdWF0ZSAic3ViIi1jb25zdHJ1Y3RvciBmb3IgYSBwYXJ0aWN1bGFyIGNvbXByZXNzaW9uIHVzaW5nIHRoZSBtYXBwaW5nDQogICAgIyBmcm9tIE9QRU5fTUVUSC4NCiAgICAjDQogICAgIyBUaGlzIGNvbmNlcHQgYWxsb3dzIG9uZSB0byBzdWJjbGFzcyBUYXJGaWxlIHdpdGhvdXQgbG9zaW5nIHRoZSBjb21mb3J0IG9mDQogICAgIyB0aGUgc3VwZXItY29uc3RydWN0b3IuIEEgc3ViLWNvbnN0cnVjdG9yIGlzIHJlZ2lzdGVyZWQgYW5kIG1hZGUgYXZhaWxhYmxlDQogICAgIyBieSBhZGRpbmcgaXQgdG8gdGhlIG1hcHBpbmcgaW4gT1BFTl9NRVRILg0KDQogICAgQGNsYXNzbWV0aG9kDQogICAgZGVmIG9wZW4oY2xzLCBuYW1lPU5vbmUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGJ1ZnNpemU9UkVDT1JEU0laRSwgKiprd2FyZ3MpOg0KICAgICAgICAiIiJPcGVuIGEgdGFyIGFyY2hpdmUgZm9yIHJlYWRpbmcsIHdyaXRpbmcgb3IgYXBwZW5kaW5nLiBSZXR1cm4NCiAgICAgICAgICAgYW4gYXBwcm9wcmlhdGUgVGFyRmlsZSBjbGFzcy4NCg0KICAgICAgICAgICBtb2RlOg0KICAgICAgICAgICAncicgb3IgJ3I6Kicgb3BlbiBmb3IgcmVhZGluZyB3aXRoIHRyYW5zcGFyZW50IGNvbXByZXNzaW9uDQogICAgICAgICAgICdyOicgICAgICAgICBvcGVuIGZvciByZWFkaW5nIGV4Y2x1c2l2ZWx5IHVuY29tcHJlc3NlZA0KICAgICAgICAgICAncjpneicgICAgICAgb3BlbiBmb3IgcmVhZGluZyB3aXRoIGd6aXAgY29tcHJlc3Npb24NCiAgICAgICAgICAgJ3I6YnoyJyAgICAgIG9wZW4gZm9yIHJlYWRpbmcgd2l0aCBiemlwMiBjb21wcmVzc2lvbg0KICAgICAgICAgICAnYScgb3IgJ2E6JyAgb3BlbiBmb3IgYXBwZW5kaW5nLCBjcmVhdGluZyB0aGUgZmlsZSBpZiBuZWNlc3NhcnkNCiAgICAgICAgICAgJ3cnIG9yICd3OicgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aG91dCBjb21wcmVzc2lvbg0KICAgICAgICAgICAndzpneicgICAgICAgb3BlbiBmb3Igd3JpdGluZyB3aXRoIGd6aXAgY29tcHJlc3Npb24NCiAgICAgICAgICAgJ3c6YnoyJyAgICAgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aCBiemlwMiBjb21wcmVzc2lvbg0KDQogICAgICAgICAgICdyfConICAgICAgICBvcGVuIGEgc3RyZWFtIG9mIHRhciBibG9ja3Mgd2l0aCB0cmFuc3BhcmVudCBjb21wcmVzc2lvbg0KICAgICAgICAgICAncnwnICAgICAgICAgb3BlbiBhbiB1bmNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MgZm9yIHJlYWRpbmcNCiAgICAgICAgICAgJ3J8Z3onICAgICAgIG9wZW4gYSBnemlwIGNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MNCiAgICAgICAgICAgJ3J8YnoyJyAgICAgIG9wZW4gYSBiemlwMiBjb21wcmVzc2VkIHN0cmVhbSBvZiB0YXIgYmxvY2tzDQogICAgICAgICAgICd3fCcgICAgICAgICBvcGVuIGFuIHVuY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcNCiAgICAgICAgICAgJ3d8Z3onICAgICAgIG9wZW4gYSBnemlwIGNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nDQogICAgICAgICAgICd3fGJ6MicgICAgICBvcGVuIGEgYnppcDIgY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcNCiAgICAgICAgIiIiDQoNCiAgICAgICAgaWYgbm90IG5hbWUgYW5kIG5vdCBmaWxlb2JqOg0KICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibm90aGluZyB0byBvcGVuIikNCg0KICAgICAgICBpZiBtb2RlIGluICgiciIsICJyOioiKToNCiAgICAgICAgICAgICMgRmluZCBvdXQgd2hpY2ggKm9wZW4oKSBpcyBhcHByb3ByaWF0ZSBmb3Igb3BlbmluZyB0aGUgZmlsZS4NCiAgICAgICAgICAgIGZvciBjb21wdHlwZSBpbiBjbHMuT1BFTl9NRVRIOg0KICAgICAgICAgICAgICAgIGZ1bmMgPSBnZXRhdHRyKGNscywgY2xzLk9QRU5fTUVUSFtjb21wdHlwZV0pDQogICAgICAgICAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToNCiAgICAgICAgICAgICAgICAgICAgc2F2ZWRfcG9zID0gZmlsZW9iai50ZWxsKCkNCiAgICAgICAgICAgICAgICB0cnk6DQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jKG5hbWUsICJyIiwgZmlsZW9iaiwgKiprd2FyZ3MpDQogICAgICAgICAgICAgICAgZXhjZXB0IChSZWFkRXJyb3IsIENvbXByZXNzaW9uRXJyb3IpLCBlOg0KICAgICAgICAgICAgICAgICAgICBpZiBmaWxlb2JqIGlzIG5vdCBOb25lOg0KICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW9iai5zZWVrKHNhdmVkX3BvcykNCiAgICAgICAgICAgICAgICAgICAgY29udGludWUNCiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigiZmlsZSBjb3VsZCBub3QgYmUgb3BlbmVkIHN1Y2Nlc3NmdWxseSIpDQoNCiAgICAgICAgZWxpZiAiOiIgaW4gbW9kZToNCiAgICAgICAgICAgIGZpbGVtb2RlLCBjb21wdHlwZSA9IG1vZGUuc3BsaXQoIjoiLCAxKQ0KICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciINCiAgICAgICAgICAgIGNvbXB0eXBlID0gY29tcHR5cGUgb3IgInRhciINCg0KICAgICAgICAgICAgIyBTZWxlY3QgdGhlICpvcGVuKCkgZnVuY3Rpb24gYWNjb3JkaW5nIHRvDQogICAgICAgICAgICAjIGdpdmVuIGNvbXByZXNzaW9uLg0KICAgICAgICAgICAgaWYgY29tcHR5cGUgaW4gY2xzLk9QRU5fTUVUSDoNCiAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cihjbHMsIGNscy5PUEVOX01FVEhbY29tcHR5cGVdKQ0KICAgICAgICAgICAgZWxzZToNCiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJ1bmtub3duIGNvbXByZXNzaW9uIHR5cGUgJXIiICUgY29tcHR5cGUpDQogICAgICAgICAgICByZXR1cm4gZnVuYyhuYW1lLCBmaWxlbW9kZSwgZmlsZW9iaiwgKiprd2FyZ3MpDQoNCiAgICAgICAgZWxpZiAifCIgaW4gbW9kZToNCiAgICAgICAgICAgIGZpbGVtb2RlLCBjb21wdHlwZSA9IG1vZGUuc3BsaXQoInwiLCAxKQ0KICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciINCiAgICAgICAgICAgIGNvbXB0eXBlID0gY29tcHR5cGUgb3IgInRhciINCg0KICAgICAgICAgICAgaWYgZmlsZW1vZGUgbm90IGluICJydyI6DQogICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndyciKQ0KDQogICAgICAgICAgICB0ID0gY2xzKG5hbWUsIGZpbGVtb2RlLA0KICAgICAgICAgICAgICAgICAgICBfU3RyZWFtKG5hbWUsIGZpbGVtb2RlLCBjb21wdHlwZSwgZmlsZW9iaiwgYnVmc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICoqa3dhcmdzKQ0KICAgICAgICAgICAgdC5fZXh0ZmlsZW9iaiA9IEZhbHNlDQogICAgICAgICAgICByZXR1cm4gdA0KDQogICAgICAgIGVsaWYgbW9kZSBpbiAiYXciOg0KICAgICAgICAgICAgcmV0dXJuIGNscy50YXJvcGVuKG5hbWUsIG1vZGUsIGZpbGVvYmosICoqa3dhcmdzKQ0KDQogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoInVuZGlzY2VybmlibGUgbW9kZSIpDQoNCiAgICBAY2xhc3NtZXRob2QNCiAgICBkZWYgdGFyb3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsICoqa3dhcmdzKToNCiAgICAgICAgIiIiT3BlbiB1bmNvbXByZXNzZWQgdGFyIGFyY2hpdmUgbmFtZSBmb3IgcmVhZGluZyBvciB3cml0aW5nLg0KICAgICAgICAiIiINCiAgICAgICAgaWYgbGVuKG1vZGUpID4gMSBvciBtb2RlIG5vdCBpbiAicmF3IjoNCiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm1vZGUgbXVzdCBiZSAncicsICdhJyBvciAndyciKQ0KICAgICAgICByZXR1cm4gY2xzKG5hbWUsIG1vZGUsIGZpbGVvYmosICoqa3dhcmdzKQ0KDQogICAgQGNsYXNzbWV0aG9kDQogICAgZGVmIGd6b3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGNvbXByZXNzbGV2ZWw9OSwgKiprd2FyZ3MpOg0KICAgICAgICAiIiJPcGVuIGd6aXAgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuDQogICAgICAgICAgIEFwcGVuZGluZyBpcyBub3QgYWxsb3dlZC4NCiAgICAgICAgIiIiDQogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJ3IjoNCiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm1vZGUgbXVzdCBiZSAncicgb3IgJ3cnIikNCg0KICAgICAgICB0cnk6DQogICAgICAgICAgICBpbXBvcnQgZ3ppcA0KICAgICAgICAgICAgZ3ppcC5HemlwRmlsZQ0KICAgICAgICBleGNlcHQgKEltcG9ydEVycm9yLCBBdHRyaWJ1dGVFcnJvcik6DQogICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJnemlwIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIikNCg0KICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6DQogICAgICAgICAgICBmaWxlb2JqID0gYmx0bl9vcGVuKG5hbWUsIG1vZGUgKyAiYiIpDQoNCiAgICAgICAgdHJ5Og0KICAgICAgICAgICAgdCA9IGNscy50YXJvcGVuKG5hbWUsIG1vZGUsDQogICAgICAgICAgICAgICAgZ3ppcC5HemlwRmlsZShuYW1lLCBtb2RlLCBjb21wcmVzc2xldmVsLCBmaWxlb2JqKSwNCiAgICAgICAgICAgICAgICAqKmt3YXJncykNCiAgICAgICAgZXhjZXB0IElPRXJyb3I6DQogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoIm5vdCBhIGd6aXAgZmlsZSIpDQogICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQ0KICAgICAgICByZXR1cm4gdA0KDQogICAgQGNsYXNzbWV0aG9kDQogICAgZGVmIGJ6Mm9wZW4oY2xzLCBuYW1lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCBjb21wcmVzc2xldmVsPTksICoqa3dhcmdzKToNCiAgICAgICAgIiIiT3BlbiBiemlwMiBjb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4NCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLg0KICAgICAgICAiIiINCiAgICAgICAgaWYgbGVuKG1vZGUpID4gMSBvciBtb2RlIG5vdCBpbiAicnciOg0KICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndycuIikNCg0KICAgICAgICB0cnk6DQogICAgICAgICAgICBpbXBvcnQgYnoyDQogICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoNCiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoImJ6MiBtb2R1bGUgaXMgbm90IGF2YWlsYWJsZSIpDQoNCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToNCiAgICAgICAgICAgIGZpbGVvYmogPSBfQloyUHJveHkoZmlsZW9iaiwgbW9kZSkNCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIGZpbGVvYmogPSBiejIuQloyRmlsZShuYW1lLCBtb2RlLCBjb21wcmVzc2xldmVsPWNvbXByZXNzbGV2ZWwpDQoNCiAgICAgICAgdHJ5Og0KICAgICAgICAgICAgdCA9IGNscy50YXJvcGVuKG5hbWUsIG1vZGUsIGZpbGVvYmosICoqa3dhcmdzKQ0KICAgICAgICBleGNlcHQgKElPRXJyb3IsIEVPRkVycm9yKToNCiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigibm90IGEgYnppcDIgZmlsZSIpDQogICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQ0KICAgICAgICByZXR1cm4gdA0KDQogICAgIyBBbGwgKm9wZW4oKSBtZXRob2RzIGFyZSByZWdpc3RlcmVkIGhlcmUuDQogICAgT1BFTl9NRVRIID0gew0KICAgICAgICAidGFyIjogInRhcm9wZW4iLCAgICMgdW5jb21wcmVzc2VkIHRhcg0KICAgICAgICAiZ3oiOiAgImd6b3BlbiIsICAgICMgZ3ppcCBjb21wcmVzc2VkIHRhcg0KICAgICAgICAiYnoyIjogImJ6Mm9wZW4iICAgICMgYnppcDIgY29tcHJlc3NlZCB0YXINCiAgICB9DQoNCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiAgICAjIFRoZSBwdWJsaWMgbWV0aG9kcyB3aGljaCBUYXJGaWxlIHByb3ZpZGVzOg0KDQogICAgZGVmIGNsb3NlKHNlbGYpOg0KICAgICAgICAiIiJDbG9zZSB0aGUgVGFyRmlsZS4gSW4gd3JpdGUtbW9kZSwgdHdvIGZpbmlzaGluZyB6ZXJvIGJsb2NrcyBhcmUNCiAgICAgICAgICAgYXBwZW5kZWQgdG8gdGhlIGFyY2hpdmUuDQogICAgICAgICIiIg0KICAgICAgICBpZiBzZWxmLmNsb3NlZDoNCiAgICAgICAgICAgIHJldHVybg0KDQogICAgICAgIGlmIHNlbGYubW9kZSBpbiAiYXciOg0KICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChCTE9DS1NJWkUgKiAyKSkNCiAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IChCTE9DS1NJWkUgKiAyKQ0KICAgICAgICAgICAgIyBmaWxsIHVwIHRoZSBlbmQgd2l0aCB6ZXJvLWJsb2Nrcw0KICAgICAgICAgICAgIyAobGlrZSBvcHRpb24gLWIyMCBmb3IgdGFyIGRvZXMpDQogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChzZWxmLm9mZnNldCwgUkVDT1JEU0laRSkNCiAgICAgICAgICAgIGlmIHJlbWFpbmRlciA+IDA6DQogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChSRUNPUkRTSVpFIC0gcmVtYWluZGVyKSkNCg0KICAgICAgICBpZiBub3Qgc2VsZi5fZXh0ZmlsZW9iajoNCiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpDQogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQ0KDQogICAgZGVmIGdldG1lbWJlcihzZWxmLCBuYW1lKToNCiAgICAgICAgIiIiUmV0dXJuIGEgVGFySW5mbyBvYmplY3QgZm9yIG1lbWJlciBgbmFtZScuIElmIGBuYW1lJyBjYW4gbm90IGJlDQogICAgICAgICAgIGZvdW5kIGluIHRoZSBhcmNoaXZlLCBLZXlFcnJvciBpcyByYWlzZWQuIElmIGEgbWVtYmVyIG9jY3VycyBtb3JlDQogICAgICAgICAgIHRoYW4gb25jZSBpbiB0aGUgYXJjaGl2ZSwgaXRzIGxhc3Qgb2NjdXJyZW5jZSBpcyBhc3N1bWVkIHRvIGJlIHRoZQ0KICAgICAgICAgICBtb3N0IHVwLXRvLWRhdGUgdmVyc2lvbi4NCiAgICAgICAgIiIiDQogICAgICAgIHRhcmluZm8gPSBzZWxmLl9nZXRtZW1iZXIobmFtZSkNCiAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOg0KICAgICAgICAgICAgcmFpc2UgS2V5RXJyb3IoImZpbGVuYW1lICVyIG5vdCBmb3VuZCIgJSBuYW1lKQ0KICAgICAgICByZXR1cm4gdGFyaW5mbw0KDQogICAgZGVmIGdldG1lbWJlcnMoc2VsZik6DQogICAgICAgICIiIlJldHVybiB0aGUgbWVtYmVycyBvZiB0aGUgYXJjaGl2ZSBhcyBhIGxpc3Qgb2YgVGFySW5mbyBvYmplY3RzLiBUaGUNCiAgICAgICAgICAgbGlzdCBoYXMgdGhlIHNhbWUgb3JkZXIgYXMgdGhlIG1lbWJlcnMgaW4gdGhlIGFyY2hpdmUuDQogICAgICAgICIiIg0KICAgICAgICBzZWxmLl9jaGVjaygpDQogICAgICAgIGlmIG5vdCBzZWxmLl9sb2FkZWQ6ICAgICMgaWYgd2Ugd2FudCB0byBvYnRhaW4gYSBsaXN0IG9mDQogICAgICAgICAgICBzZWxmLl9sb2FkKCkgICAgICAgICMgYWxsIG1lbWJlcnMsIHdlIGZpcnN0IGhhdmUgdG8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzY2FuIHRoZSB3aG9sZSBhcmNoaXZlLg0KICAgICAgICByZXR1cm4gc2VsZi5tZW1iZXJzDQoNCiAgICBkZWYgZ2V0bmFtZXMoc2VsZik6DQogICAgICAgICIiIlJldHVybiB0aGUgbWVtYmVycyBvZiB0aGUgYXJjaGl2ZSBhcyBhIGxpc3Qgb2YgdGhlaXIgbmFtZXMuIEl0IGhhcw0KICAgICAgICAgICB0aGUgc2FtZSBvcmRlciBhcyB0aGUgbGlzdCByZXR1cm5lZCBieSBnZXRtZW1iZXJzKCkuDQogICAgICAgICIiIg0KICAgICAgICByZXR1cm4gW3RhcmluZm8ubmFtZSBmb3IgdGFyaW5mbyBpbiBzZWxmLmdldG1lbWJlcnMoKV0NCg0KICAgIGRlZiBnZXR0YXJpbmZvKHNlbGYsIG5hbWU9Tm9uZSwgYXJjbmFtZT1Ob25lLCBmaWxlb2JqPU5vbmUpOg0KICAgICAgICAiIiJDcmVhdGUgYSBUYXJJbmZvIG9iamVjdCBmb3IgZWl0aGVyIHRoZSBmaWxlIGBuYW1lJyBvciB0aGUgZmlsZQ0KICAgICAgICAgICBvYmplY3QgYGZpbGVvYmonICh1c2luZyBvcy5mc3RhdCBvbiBpdHMgZmlsZSBkZXNjcmlwdG9yKS4gWW91IGNhbg0KICAgICAgICAgICBtb2RpZnkgc29tZSBvZiB0aGUgVGFySW5mbydzIGF0dHJpYnV0ZXMgYmVmb3JlIHlvdSBhZGQgaXQgdXNpbmcNCiAgICAgICAgICAgYWRkZmlsZSgpLiBJZiBnaXZlbiwgYGFyY25hbWUnIHNwZWNpZmllcyBhbiBhbHRlcm5hdGl2ZSBuYW1lIGZvciB0aGUNCiAgICAgICAgICAgZmlsZSBpbiB0aGUgYXJjaGl2ZS4NCiAgICAgICAgIiIiDQogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpDQoNCiAgICAgICAgIyBXaGVuIGZpbGVvYmogaXMgZ2l2ZW4sIHJlcGxhY2UgbmFtZSBieQ0KICAgICAgICAjIGZpbGVvYmoncyByZWFsIG5hbWUuDQogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6DQogICAgICAgICAgICBuYW1lID0gZmlsZW9iai5uYW1lDQoNCiAgICAgICAgIyBCdWlsZGluZyB0aGUgbmFtZSBvZiB0aGUgbWVtYmVyIGluIHRoZSBhcmNoaXZlLg0KICAgICAgICAjIEJhY2t3YXJkIHNsYXNoZXMgYXJlIGNvbnZlcnRlZCB0byBmb3J3YXJkIHNsYXNoZXMsDQogICAgICAgICMgQWJzb2x1dGUgcGF0aHMgYXJlIHR1cm5lZCB0byByZWxhdGl2ZSBwYXRocy4NCiAgICAgICAgaWYgYXJjbmFtZSBpcyBOb25lOg0KICAgICAgICAgICAgYXJjbmFtZSA9IG5hbWUNCiAgICAgICAgZHJ2LCBhcmNuYW1lID0gb3MucGF0aC5zcGxpdGRyaXZlKGFyY25hbWUpDQogICAgICAgIGFyY25hbWUgPSBhcmNuYW1lLnJlcGxhY2Uob3Muc2VwLCAiLyIpDQogICAgICAgIGFyY25hbWUgPSBhcmNuYW1lLmxzdHJpcCgiLyIpDQoNCiAgICAgICAgIyBOb3csIGZpbGwgdGhlIFRhckluZm8gb2JqZWN0IHdpdGgNCiAgICAgICAgIyBpbmZvcm1hdGlvbiBzcGVjaWZpYyBmb3IgdGhlIGZpbGUuDQogICAgICAgIHRhcmluZm8gPSBzZWxmLnRhcmluZm8oKQ0KICAgICAgICB0YXJpbmZvLnRhcmZpbGUgPSBzZWxmDQoNCiAgICAgICAgIyBVc2Ugb3Muc3RhdCBvciBvcy5sc3RhdCwgZGVwZW5kaW5nIG9uIHBsYXRmb3JtDQogICAgICAgICMgYW5kIGlmIHN5bWxpbmtzIHNoYWxsIGJlIHJlc29sdmVkLg0KICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6DQogICAgICAgICAgICBpZiBoYXNhdHRyKG9zLCAibHN0YXQiKSBhbmQgbm90IHNlbGYuZGVyZWZlcmVuY2U6DQogICAgICAgICAgICAgICAgc3RhdHJlcyA9IG9zLmxzdGF0KG5hbWUpDQogICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgIHN0YXRyZXMgPSBvcy5zdGF0KG5hbWUpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICBzdGF0cmVzID0gb3MuZnN0YXQoZmlsZW9iai5maWxlbm8oKSkNCiAgICAgICAgbGlua25hbWUgPSAiIg0KDQogICAgICAgIHN0bWQgPSBzdGF0cmVzLnN0X21vZGUNCiAgICAgICAgaWYgc3RhdC5TX0lTUkVHKHN0bWQpOg0KICAgICAgICAgICAgaW5vZGUgPSAoc3RhdHJlcy5zdF9pbm8sIHN0YXRyZXMuc3RfZGV2KQ0KICAgICAgICAgICAgaWYgbm90IHNlbGYuZGVyZWZlcmVuY2UgYW5kIHN0YXRyZXMuc3RfbmxpbmsgPiAxIGFuZCBcDQogICAgICAgICAgICAgICAgICAgIGlub2RlIGluIHNlbGYuaW5vZGVzIGFuZCBhcmNuYW1lICE9IHNlbGYuaW5vZGVzW2lub2RlXToNCiAgICAgICAgICAgICAgICAjIElzIGl0IGEgaGFyZGxpbmsgdG8gYW4gYWxyZWFkeQ0KICAgICAgICAgICAgICAgICMgYXJjaGl2ZWQgZmlsZT8NCiAgICAgICAgICAgICAgICB0eXBlID0gTE5LVFlQRQ0KICAgICAgICAgICAgICAgIGxpbmtuYW1lID0gc2VsZi5pbm9kZXNbaW5vZGVdDQogICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgICMgVGhlIGlub2RlIGlzIGFkZGVkIG9ubHkgaWYgaXRzIHZhbGlkLg0KICAgICAgICAgICAgICAgICMgRm9yIHdpbjMyIGl0IGlzIGFsd2F5cyAwLg0KICAgICAgICAgICAgICAgIHR5cGUgPSBSRUdUWVBFDQogICAgICAgICAgICAgICAgaWYgaW5vZGVbMF06DQogICAgICAgICAgICAgICAgICAgIHNlbGYuaW5vZGVzW2lub2RlXSA9IGFyY25hbWUNCiAgICAgICAgZWxpZiBzdGF0LlNfSVNESVIoc3RtZCk6DQogICAgICAgICAgICB0eXBlID0gRElSVFlQRQ0KICAgICAgICBlbGlmIHN0YXQuU19JU0ZJRk8oc3RtZCk6DQogICAgICAgICAgICB0eXBlID0gRklGT1RZUEUNCiAgICAgICAgZWxpZiBzdGF0LlNfSVNMTksoc3RtZCk6DQogICAgICAgICAgICB0eXBlID0gU1lNVFlQRQ0KICAgICAgICAgICAgbGlua25hbWUgPSBvcy5yZWFkbGluayhuYW1lKQ0KICAgICAgICBlbGlmIHN0YXQuU19JU0NIUihzdG1kKToNCiAgICAgICAgICAgIHR5cGUgPSBDSFJUWVBFDQogICAgICAgIGVsaWYgc3RhdC5TX0lTQkxLKHN0bWQpOg0KICAgICAgICAgICAgdHlwZSA9IEJMS1RZUEUNCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIHJldHVybiBOb25lDQoNCiAgICAgICAgIyBGaWxsIHRoZSBUYXJJbmZvIG9iamVjdCB3aXRoIGFsbA0KICAgICAgICAjIGluZm9ybWF0aW9uIHdlIGNhbiBnZXQuDQogICAgICAgIHRhcmluZm8ubmFtZSA9IGFyY25hbWUNCiAgICAgICAgdGFyaW5mby5tb2RlID0gc3RtZA0KICAgICAgICB0YXJpbmZvLnVpZCA9IHN0YXRyZXMuc3RfdWlkDQogICAgICAgIHRhcmluZm8uZ2lkID0gc3RhdHJlcy5zdF9naWQNCiAgICAgICAgaWYgdHlwZSA9PSBSRUdUWVBFOg0KICAgICAgICAgICAgdGFyaW5mby5zaXplID0gc3RhdHJlcy5zdF9zaXplDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICB0YXJpbmZvLnNpemUgPSAwTA0KICAgICAgICB0YXJpbmZvLm10aW1lID0gc3RhdHJlcy5zdF9tdGltZQ0KICAgICAgICB0YXJpbmZvLnR5cGUgPSB0eXBlDQogICAgICAgIHRhcmluZm8ubGlua25hbWUgPSBsaW5rbmFtZQ0KICAgICAgICBpZiBwd2Q6DQogICAgICAgICAgICB0cnk6DQogICAgICAgICAgICAgICAgdGFyaW5mby51bmFtZSA9IHB3ZC5nZXRwd3VpZCh0YXJpbmZvLnVpZClbMF0NCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoNCiAgICAgICAgICAgICAgICBwYXNzDQogICAgICAgIGlmIGdycDoNCiAgICAgICAgICAgIHRyeToNCiAgICAgICAgICAgICAgICB0YXJpbmZvLmduYW1lID0gZ3JwLmdldGdyZ2lkKHRhcmluZm8uZ2lkKVswXQ0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOg0KICAgICAgICAgICAgICAgIHBhc3MNCg0KICAgICAgICBpZiB0eXBlIGluIChDSFJUWVBFLCBCTEtUWVBFKToNCiAgICAgICAgICAgIGlmIGhhc2F0dHIob3MsICJtYWpvciIpIGFuZCBoYXNhdHRyKG9zLCAibWlub3IiKToNCiAgICAgICAgICAgICAgICB0YXJpbmZvLmRldm1ham9yID0gb3MubWFqb3Ioc3RhdHJlcy5zdF9yZGV2KQ0KICAgICAgICAgICAgICAgIHRhcmluZm8uZGV2bWlub3IgPSBvcy5taW5vcihzdGF0cmVzLnN0X3JkZXYpDQogICAgICAgIHJldHVybiB0YXJpbmZvDQoNCiAgICBkZWYgbGlzdChzZWxmLCB2ZXJib3NlPVRydWUpOg0KICAgICAgICAiIiJQcmludCBhIHRhYmxlIG9mIGNvbnRlbnRzIHRvIHN5cy5zdGRvdXQuIElmIGB2ZXJib3NlJyBpcyBGYWxzZSwgb25seQ0KICAgICAgICAgICB0aGUgbmFtZXMgb2YgdGhlIG1lbWJlcnMgYXJlIHByaW50ZWQuIElmIGl0IGlzIFRydWUsIGFuIGBscyAtbCctbGlrZQ0KICAgICAgICAgICBvdXRwdXQgaXMgcHJvZHVjZWQuDQogICAgICAgICIiIg0KICAgICAgICBzZWxmLl9jaGVjaygpDQoNCiAgICAgICAgZm9yIHRhcmluZm8gaW4gc2VsZjoNCiAgICAgICAgICAgIGlmIHZlcmJvc2U6DQogICAgICAgICAgICAgICAgcHJpbnQgZmlsZW1vZGUodGFyaW5mby5tb2RlKSwNCiAgICAgICAgICAgICAgICBwcmludCAiJXMvJXMiICUgKHRhcmluZm8udW5hbWUgb3IgdGFyaW5mby51aWQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvLmduYW1lIG9yIHRhcmluZm8uZ2lkKSwNCiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzY2hyKCkgb3IgdGFyaW5mby5pc2JsaygpOg0KICAgICAgICAgICAgICAgICAgICBwcmludCAiJTEwcyIgJSAoIiVkLCVkIiBcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAlICh0YXJpbmZvLmRldm1ham9yLCB0YXJpbmZvLmRldm1pbm9yKSksDQogICAgICAgICAgICAgICAgZWxzZToNCiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIiUxMGQiICUgdGFyaW5mby5zaXplLA0KICAgICAgICAgICAgICAgIHByaW50ICIlZC0lMDJkLSUwMmQgJTAyZDolMDJkOiUwMmQiIFwNCiAgICAgICAgICAgICAgICAgICAgICAlIHRpbWUubG9jYWx0aW1lKHRhcmluZm8ubXRpbWUpWzo2XSwNCg0KICAgICAgICAgICAgcHJpbnQgdGFyaW5mby5uYW1lICsgKCIvIiBpZiB0YXJpbmZvLmlzZGlyKCkgZWxzZSAiIiksDQoNCiAgICAgICAgICAgIGlmIHZlcmJvc2U6DQogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpOg0KICAgICAgICAgICAgICAgICAgICBwcmludCAiLT4iLCB0YXJpbmZvLmxpbmtuYW1lLA0KICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNsbmsoKToNCiAgICAgICAgICAgICAgICAgICAgcHJpbnQgImxpbmsgdG8iLCB0YXJpbmZvLmxpbmtuYW1lLA0KICAgICAgICAgICAgcHJpbnQNCg0KICAgIGRlZiBhZGQoc2VsZiwgbmFtZSwgYXJjbmFtZT1Ob25lLCByZWN1cnNpdmU9VHJ1ZSwgZXhjbHVkZT1Ob25lLCBmaWx0ZXI9Tm9uZSk6DQogICAgICAgICIiIkFkZCB0aGUgZmlsZSBgbmFtZScgdG8gdGhlIGFyY2hpdmUuIGBuYW1lJyBtYXkgYmUgYW55IHR5cGUgb2YgZmlsZQ0KICAgICAgICAgICAoZGlyZWN0b3J5LCBmaWZvLCBzeW1ib2xpYyBsaW5rLCBldGMuKS4gSWYgZ2l2ZW4sIGBhcmNuYW1lJw0KICAgICAgICAgICBzcGVjaWZpZXMgYW4gYWx0ZXJuYXRpdmUgbmFtZSBmb3IgdGhlIGZpbGUgaW4gdGhlIGFyY2hpdmUuDQogICAgICAgICAgIERpcmVjdG9yaWVzIGFyZSBhZGRlZCByZWN1cnNpdmVseSBieSBkZWZhdWx0LiBUaGlzIGNhbiBiZSBhdm9pZGVkIGJ5DQogICAgICAgICAgIHNldHRpbmcgYHJlY3Vyc2l2ZScgdG8gRmFsc2UuIGBleGNsdWRlJyBpcyBhIGZ1bmN0aW9uIHRoYXQgc2hvdWxkDQogICAgICAgICAgIHJldHVybiBUcnVlIGZvciBlYWNoIGZpbGVuYW1lIHRvIGJlIGV4Y2x1ZGVkLiBgZmlsdGVyJyBpcyBhIGZ1bmN0aW9uDQogICAgICAgICAgIHRoYXQgZXhwZWN0cyBhIFRhckluZm8gb2JqZWN0IGFyZ3VtZW50IGFuZCByZXR1cm5zIHRoZSBjaGFuZ2VkDQogICAgICAgICAgIFRhckluZm8gb2JqZWN0LCBpZiBpdCByZXR1cm5zIE5vbmUgdGhlIFRhckluZm8gb2JqZWN0IHdpbGwgYmUNCiAgICAgICAgICAgZXhjbHVkZWQgZnJvbSB0aGUgYXJjaGl2ZS4NCiAgICAgICAgIiIiDQogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpDQoNCiAgICAgICAgaWYgYXJjbmFtZSBpcyBOb25lOg0KICAgICAgICAgICAgYXJjbmFtZSA9IG5hbWUNCg0KICAgICAgICAjIEV4Y2x1ZGUgcGF0aG5hbWVzLg0KICAgICAgICBpZiBleGNsdWRlIGlzIG5vdCBOb25lOg0KICAgICAgICAgICAgaW1wb3J0IHdhcm5pbmdzDQogICAgICAgICAgICB3YXJuaW5ncy53YXJuKCJ1c2UgdGhlIGZpbHRlciBhcmd1bWVudCBpbnN0ZWFkIiwNCiAgICAgICAgICAgICAgICAgICAgRGVwcmVjYXRpb25XYXJuaW5nLCAyKQ0KICAgICAgICAgICAgaWYgZXhjbHVkZShuYW1lKToNCiAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMiwgInRhcmZpbGU6IEV4Y2x1ZGVkICVyIiAlIG5hbWUpDQogICAgICAgICAgICAgICAgcmV0dXJuDQoNCiAgICAgICAgIyBTa2lwIGlmIHNvbWVib2R5IHRyaWVzIHRvIGFyY2hpdmUgdGhlIGFyY2hpdmUuLi4NCiAgICAgICAgaWYgc2VsZi5uYW1lIGlzIG5vdCBOb25lIGFuZCBvcy5wYXRoLmFic3BhdGgobmFtZSkgPT0gc2VsZi5uYW1lOg0KICAgICAgICAgICAgc2VsZi5fZGJnKDIsICJ0YXJmaWxlOiBTa2lwcGVkICVyIiAlIG5hbWUpDQogICAgICAgICAgICByZXR1cm4NCg0KICAgICAgICBzZWxmLl9kYmcoMSwgbmFtZSkNCg0KICAgICAgICAjIENyZWF0ZSBhIFRhckluZm8gb2JqZWN0IGZyb20gdGhlIGZpbGUuDQogICAgICAgIHRhcmluZm8gPSBzZWxmLmdldHRhcmluZm8obmFtZSwgYXJjbmFtZSkNCg0KICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6DQogICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IFVuc3VwcG9ydGVkIHR5cGUgJXIiICUgbmFtZSkNCiAgICAgICAgICAgIHJldHVybg0KDQogICAgICAgICMgQ2hhbmdlIG9yIGV4Y2x1ZGUgdGhlIFRhckluZm8gb2JqZWN0Lg0KICAgICAgICBpZiBmaWx0ZXIgaXMgbm90IE5vbmU6DQogICAgICAgICAgICB0YXJpbmZvID0gZmlsdGVyKHRhcmluZm8pDQogICAgICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6DQogICAgICAgICAgICAgICAgc2VsZi5fZGJnKDIsICJ0YXJmaWxlOiBFeGNsdWRlZCAlciIgJSBuYW1lKQ0KICAgICAgICAgICAgICAgIHJldHVybg0KDQogICAgICAgICMgQXBwZW5kIHRoZSB0YXIgaGVhZGVyIGFuZCBkYXRhIHRvIHRoZSBhcmNoaXZlLg0KICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCk6DQogICAgICAgICAgICBmID0gYmx0bl9vcGVuKG5hbWUsICJyYiIpDQogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbywgZikNCiAgICAgICAgICAgIGYuY2xvc2UoKQ0KDQogICAgICAgIGVsaWYgdGFyaW5mby5pc2RpcigpOg0KICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8pDQogICAgICAgICAgICBpZiByZWN1cnNpdmU6DQogICAgICAgICAgICAgICAgZm9yIGYgaW4gb3MubGlzdGRpcihuYW1lKToNCiAgICAgICAgICAgICAgICAgICAgc2VsZi5hZGQob3MucGF0aC5qb2luKG5hbWUsIGYpLCBvcy5wYXRoLmpvaW4oYXJjbmFtZSwgZiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjdXJzaXZlLCBleGNsdWRlLCBmaWx0ZXIpDQoNCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIHNlbGYuYWRkZmlsZSh0YXJpbmZvKQ0KDQogICAgZGVmIGFkZGZpbGUoc2VsZiwgdGFyaW5mbywgZmlsZW9iaj1Ob25lKToNCiAgICAgICAgIiIiQWRkIHRoZSBUYXJJbmZvIG9iamVjdCBgdGFyaW5mbycgdG8gdGhlIGFyY2hpdmUuIElmIGBmaWxlb2JqJyBpcw0KICAgICAgICAgICBnaXZlbiwgdGFyaW5mby5zaXplIGJ5dGVzIGFyZSByZWFkIGZyb20gaXQgYW5kIGFkZGVkIHRvIHRoZSBhcmNoaXZlLg0KICAgICAgICAgICBZb3UgY2FuIGNyZWF0ZSBUYXJJbmZvIG9iamVjdHMgdXNpbmcgZ2V0dGFyaW5mbygpLg0KICAgICAgICAgICBPbiBXaW5kb3dzIHBsYXRmb3JtcywgYGZpbGVvYmonIHNob3VsZCBhbHdheXMgYmUgb3BlbmVkIHdpdGggbW9kZQ0KICAgICAgICAgICAncmInIHRvIGF2b2lkIGlycml0YXRpb24gYWJvdXQgdGhlIGZpbGUgc2l6ZS4NCiAgICAgICAgIiIiDQogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpDQoNCiAgICAgICAgdGFyaW5mbyA9IGNvcHkuY29weSh0YXJpbmZvKQ0KDQogICAgICAgIGJ1ZiA9IHRhcmluZm8udG9idWYoc2VsZi5mb3JtYXQsIHNlbGYuZW5jb2RpbmcsIHNlbGYuZXJyb3JzKQ0KICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoYnVmKQ0KICAgICAgICBzZWxmLm9mZnNldCArPSBsZW4oYnVmKQ0KDQogICAgICAgICMgSWYgdGhlcmUncyBkYXRhIHRvIGZvbGxvdywgYXBwZW5kIGl0Lg0KICAgICAgICBpZiBmaWxlb2JqIGlzIG5vdCBOb25lOg0KICAgICAgICAgICAgY29weWZpbGVvYmooZmlsZW9iaiwgc2VsZi5maWxlb2JqLCB0YXJpbmZvLnNpemUpDQogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZCh0YXJpbmZvLnNpemUsIEJMT0NLU0laRSkNCiAgICAgICAgICAgIGlmIHJlbWFpbmRlciA+IDA6DQogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChCTE9DS1NJWkUgLSByZW1haW5kZXIpKQ0KICAgICAgICAgICAgICAgIGJsb2NrcyArPSAxDQogICAgICAgICAgICBzZWxmLm9mZnNldCArPSBibG9ja3MgKiBCTE9DS1NJWkUNCg0KICAgICAgICBzZWxmLm1lbWJlcnMuYXBwZW5kKHRhcmluZm8pDQoNCiAgICBkZWYgZXh0cmFjdGFsbChzZWxmLCBwYXRoPSIuIiwgbWVtYmVycz1Ob25lKToNCiAgICAgICAgIiIiRXh0cmFjdCBhbGwgbWVtYmVycyBmcm9tIHRoZSBhcmNoaXZlIHRvIHRoZSBjdXJyZW50IHdvcmtpbmcNCiAgICAgICAgICAgZGlyZWN0b3J5IGFuZCBzZXQgb3duZXIsIG1vZGlmaWNhdGlvbiB0aW1lIGFuZCBwZXJtaXNzaW9ucyBvbg0KICAgICAgICAgICBkaXJlY3RvcmllcyBhZnRlcndhcmRzLiBgcGF0aCcgc3BlY2lmaWVzIGEgZGlmZmVyZW50IGRpcmVjdG9yeQ0KICAgICAgICAgICB0byBleHRyYWN0IHRvLiBgbWVtYmVycycgaXMgb3B0aW9uYWwgYW5kIG11c3QgYmUgYSBzdWJzZXQgb2YgdGhlDQogICAgICAgICAgIGxpc3QgcmV0dXJuZWQgYnkgZ2V0bWVtYmVycygpLg0KICAgICAgICAiIiINCiAgICAgICAgZGlyZWN0b3JpZXMgPSBbXQ0KDQogICAgICAgIGlmIG1lbWJlcnMgaXMgTm9uZToNCiAgICAgICAgICAgIG1lbWJlcnMgPSBzZWxmDQoNCiAgICAgICAgZm9yIHRhcmluZm8gaW4gbWVtYmVyczoNCiAgICAgICAgICAgIGlmIHRhcmluZm8uaXNkaXIoKToNCiAgICAgICAgICAgICAgICAjIEV4dHJhY3QgZGlyZWN0b3JpZXMgd2l0aCBhIHNhZmUgbW9kZS4NCiAgICAgICAgICAgICAgICBkaXJlY3Rvcmllcy5hcHBlbmQodGFyaW5mbykNCiAgICAgICAgICAgICAgICB0YXJpbmZvID0gY29weS5jb3B5KHRhcmluZm8pDQogICAgICAgICAgICAgICAgdGFyaW5mby5tb2RlID0gMDcwMA0KICAgICAgICAgICAgc2VsZi5leHRyYWN0KHRhcmluZm8sIHBhdGgpDQoNCiAgICAgICAgIyBSZXZlcnNlIHNvcnQgZGlyZWN0b3JpZXMuDQogICAgICAgIGRpcmVjdG9yaWVzLnNvcnQoa2V5PW9wZXJhdG9yLmF0dHJnZXR0ZXIoJ25hbWUnKSkNCiAgICAgICAgZGlyZWN0b3JpZXMucmV2ZXJzZSgpDQoNCiAgICAgICAgIyBTZXQgY29ycmVjdCBvd25lciwgbXRpbWUgYW5kIGZpbGVtb2RlIG9uIGRpcmVjdG9yaWVzLg0KICAgICAgICBmb3IgdGFyaW5mbyBpbiBkaXJlY3RvcmllczoNCiAgICAgICAgICAgIGRpcnBhdGggPSBvcy5wYXRoLmpvaW4ocGF0aCwgdGFyaW5mby5uYW1lKQ0KICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgIHNlbGYuY2hvd24odGFyaW5mbywgZGlycGF0aCkNCiAgICAgICAgICAgICAgICBzZWxmLnV0aW1lKHRhcmluZm8sIGRpcnBhdGgpDQogICAgICAgICAgICAgICAgc2VsZi5jaG1vZCh0YXJpbmZvLCBkaXJwYXRoKQ0KICAgICAgICAgICAgZXhjZXB0IEV4dHJhY3RFcnJvciwgZToNCiAgICAgICAgICAgICAgICBpZiBzZWxmLmVycm9ybGV2ZWwgPiAxOg0KICAgICAgICAgICAgICAgICAgICByYWlzZQ0KICAgICAgICAgICAgICAgIGVsc2U6DQogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZSkNCg0KICAgIGRlZiBleHRyYWN0KHNlbGYsIG1lbWJlciwgcGF0aD0iIik6DQogICAgICAgICIiIkV4dHJhY3QgYSBtZW1iZXIgZnJvbSB0aGUgYXJjaGl2ZSB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSwNCiAgICAgICAgICAgdXNpbmcgaXRzIGZ1bGwgbmFtZS4gSXRzIGZpbGUgaW5mb3JtYXRpb24gaXMgZXh0cmFjdGVkIGFzIGFjY3VyYXRlbHkNCiAgICAgICAgICAgYXMgcG9zc2libGUuIGBtZW1iZXInIG1heSBiZSBhIGZpbGVuYW1lIG9yIGEgVGFySW5mbyBvYmplY3QuIFlvdSBjYW4NCiAgICAgICAgICAgc3BlY2lmeSBhIGRpZmZlcmVudCBkaXJlY3RvcnkgdXNpbmcgYHBhdGgnLg0KICAgICAgICAiIiINCiAgICAgICAgc2VsZi5fY2hlY2soInIiKQ0KDQogICAgICAgIGlmIGlzaW5zdGFuY2UobWVtYmVyLCBiYXNlc3RyaW5nKToNCiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLmdldG1lbWJlcihtZW1iZXIpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICB0YXJpbmZvID0gbWVtYmVyDQoNCiAgICAgICAgIyBQcmVwYXJlIHRoZSBsaW5rIHRhcmdldCBmb3IgbWFrZWxpbmsoKS4NCiAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpOg0KICAgICAgICAgICAgdGFyaW5mby5fbGlua190YXJnZXQgPSBvcy5wYXRoLmpvaW4ocGF0aCwgdGFyaW5mby5saW5rbmFtZSkNCg0KICAgICAgICB0cnk6DQogICAgICAgICAgICBzZWxmLl9leHRyYWN0X21lbWJlcih0YXJpbmZvLCBvcy5wYXRoLmpvaW4ocGF0aCwgdGFyaW5mby5uYW1lKSkNCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6DQogICAgICAgICAgICBpZiBzZWxmLmVycm9ybGV2ZWwgPiAwOg0KICAgICAgICAgICAgICAgIHJhaXNlDQogICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgIGlmIGUuZmlsZW5hbWUgaXMgTm9uZToNCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyIgJSBlLnN0cmVycm9yKQ0KICAgICAgICAgICAgICAgIGVsc2U6DQogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMgJXIiICUgKGUuc3RyZXJyb3IsIGUuZmlsZW5hbWUpKQ0KICAgICAgICBleGNlcHQgRXh0cmFjdEVycm9yLCBlOg0KICAgICAgICAgICAgaWYgc2VsZi5lcnJvcmxldmVsID4gMToNCiAgICAgICAgICAgICAgICByYWlzZQ0KICAgICAgICAgICAgZWxzZToNCiAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzIiAlIGUpDQoNCiAgICBkZWYgZXh0cmFjdGZpbGUoc2VsZiwgbWVtYmVyKToNCiAgICAgICAgIiIiRXh0cmFjdCBhIG1lbWJlciBmcm9tIHRoZSBhcmNoaXZlIGFzIGEgZmlsZSBvYmplY3QuIGBtZW1iZXInIG1heSBiZQ0KICAgICAgICAgICBhIGZpbGVuYW1lIG9yIGEgVGFySW5mbyBvYmplY3QuIElmIGBtZW1iZXInIGlzIGEgcmVndWxhciBmaWxlLCBhDQogICAgICAgICAgIGZpbGUtbGlrZSBvYmplY3QgaXMgcmV0dXJuZWQuIElmIGBtZW1iZXInIGlzIGEgbGluaywgYSBmaWxlLWxpa2UNCiAgICAgICAgICAgb2JqZWN0IGlzIGNvbnN0cnVjdGVkIGZyb20gdGhlIGxpbmsncyB0YXJnZXQuIElmIGBtZW1iZXInIGlzIG5vbmUgb2YNCiAgICAgICAgICAgdGhlIGFib3ZlLCBOb25lIGlzIHJldHVybmVkLg0KICAgICAgICAgICBUaGUgZmlsZS1saWtlIG9iamVjdCBpcyByZWFkLW9ubHkgYW5kIHByb3ZpZGVzIHRoZSBmb2xsb3dpbmcNCiAgICAgICAgICAgbWV0aG9kczogcmVhZCgpLCByZWFkbGluZSgpLCByZWFkbGluZXMoKSwgc2VlaygpIGFuZCB0ZWxsKCkNCiAgICAgICAgIiIiDQogICAgICAgIHNlbGYuX2NoZWNrKCJyIikNCg0KICAgICAgICBpZiBpc2luc3RhbmNlKG1lbWJlciwgYmFzZXN0cmluZyk6DQogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5nZXRtZW1iZXIobWVtYmVyKQ0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgdGFyaW5mbyA9IG1lbWJlcg0KDQogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToNCiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmplY3Qoc2VsZiwgdGFyaW5mbykNCg0KICAgICAgICBlbGlmIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOg0KICAgICAgICAgICAgIyBJZiBhIG1lbWJlcidzIHR5cGUgaXMgdW5rbm93biwgaXQgaXMgdHJlYXRlZCBhcyBhDQogICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZS4NCiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmplY3Qoc2VsZiwgdGFyaW5mbykNCg0KICAgICAgICBlbGlmIHRhcmluZm8uaXNsbmsoKSBvciB0YXJpbmZvLmlzc3ltKCk6DQogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHNlbGYuZmlsZW9iaiwgX1N0cmVhbSk6DQogICAgICAgICAgICAgICAgIyBBIHNtYWxsIGJ1dCB1Z2x5IHdvcmthcm91bmQgZm9yIHRoZSBjYXNlIHRoYXQgc29tZW9uZSB0cmllcw0KICAgICAgICAgICAgICAgICMgdG8gZXh0cmFjdCBhIChzeW0pbGluayBhcyBhIGZpbGUtb2JqZWN0IGZyb20gYSBub24tc2Vla2FibGUNCiAgICAgICAgICAgICAgICAjIHN0cmVhbSBvZiB0YXIgYmxvY2tzLg0KICAgICAgICAgICAgICAgIHJhaXNlIFN0cmVhbUVycm9yKCJjYW5ub3QgZXh0cmFjdCAoc3ltKWxpbmsgYXMgZmlsZSBvYmplY3QiKQ0KICAgICAgICAgICAgZWxzZToNCiAgICAgICAgICAgICAgICAjIEEgKHN5bSlsaW5rJ3MgZmlsZSBvYmplY3QgaXMgaXRzIHRhcmdldCdzIGZpbGUgb2JqZWN0Lg0KICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLmV4dHJhY3RmaWxlKHNlbGYuX2ZpbmRfbGlua190YXJnZXQodGFyaW5mbykpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICAjIElmIHRoZXJlJ3Mgbm8gZGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIG1lbWJlciAoZGlyZWN0b3J5LCBjaHJkZXYsDQogICAgICAgICAgICAjIGJsa2RldiwgZXRjLiksIHJldHVybiBOb25lIGluc3RlYWQgb2YgYSBmaWxlIG9iamVjdC4NCiAgICAgICAgICAgIHJldHVybiBOb25lDQoNCiAgICBkZWYgX2V4dHJhY3RfbWVtYmVyKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOg0KICAgICAgICAiIiJFeHRyYWN0IHRoZSBUYXJJbmZvIG9iamVjdCB0YXJpbmZvIHRvIGEgcGh5c2ljYWwNCiAgICAgICAgICAgZmlsZSBjYWxsZWQgdGFyZ2V0cGF0aC4NCiAgICAgICAgIiIiDQogICAgICAgICMgRmV0Y2ggdGhlIFRhckluZm8gb2JqZWN0IGZvciB0aGUgZ2l2ZW4gbmFtZQ0KICAgICAgICAjIGFuZCBidWlsZCB0aGUgZGVzdGluYXRpb24gcGF0aG5hbWUsIHJlcGxhY2luZw0KICAgICAgICAjIGZvcndhcmQgc2xhc2hlcyB0byBwbGF0Zm9ybSBzcGVjaWZpYyBzZXBhcmF0b3JzLg0KICAgICAgICB0YXJnZXRwYXRoID0gdGFyZ2V0cGF0aC5yc3RyaXAoIi8iKQ0KICAgICAgICB0YXJnZXRwYXRoID0gdGFyZ2V0cGF0aC5yZXBsYWNlKCIvIiwgb3Muc2VwKQ0KDQogICAgICAgICMgQ3JlYXRlIGFsbCB1cHBlciBkaXJlY3Rvcmllcy4NCiAgICAgICAgdXBwZXJkaXJzID0gb3MucGF0aC5kaXJuYW1lKHRhcmdldHBhdGgpDQogICAgICAgIGlmIHVwcGVyZGlycyBhbmQgbm90IG9zLnBhdGguZXhpc3RzKHVwcGVyZGlycyk6DQogICAgICAgICAgICAjIENyZWF0ZSBkaXJlY3RvcmllcyB0aGF0IGFyZSBub3QgcGFydCBvZiB0aGUgYXJjaGl2ZSB3aXRoDQogICAgICAgICAgICAjIGRlZmF1bHQgcGVybWlzc2lvbnMuDQogICAgICAgICAgICBvcy5tYWtlZGlycyh1cHBlcmRpcnMpDQoNCiAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToNCiAgICAgICAgICAgIHNlbGYuX2RiZygxLCAiJXMgLT4gJXMiICUgKHRhcmluZm8ubmFtZSwgdGFyaW5mby5saW5rbmFtZSkpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICBzZWxmLl9kYmcoMSwgdGFyaW5mby5uYW1lKQ0KDQogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToNCiAgICAgICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkNCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzZGlyKCk6DQogICAgICAgICAgICBzZWxmLm1ha2VkaXIodGFyaW5mbywgdGFyZ2V0cGF0aCkNCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzZmlmbygpOg0KICAgICAgICAgICAgc2VsZi5tYWtlZmlmbyh0YXJpbmZvLCB0YXJnZXRwYXRoKQ0KICAgICAgICBlbGlmIHRhcmluZm8uaXNjaHIoKSBvciB0YXJpbmZvLmlzYmxrKCk6DQogICAgICAgICAgICBzZWxmLm1ha2VkZXYodGFyaW5mbywgdGFyZ2V0cGF0aCkNCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzbG5rKCkgb3IgdGFyaW5mby5pc3N5bSgpOg0KICAgICAgICAgICAgc2VsZi5tYWtlbGluayh0YXJpbmZvLCB0YXJnZXRwYXRoKQ0KICAgICAgICBlbGlmIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOg0KICAgICAgICAgICAgc2VsZi5tYWtldW5rbm93bih0YXJpbmZvLCB0YXJnZXRwYXRoKQ0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQ0KDQogICAgICAgIHNlbGYuY2hvd24odGFyaW5mbywgdGFyZ2V0cGF0aCkNCiAgICAgICAgaWYgbm90IHRhcmluZm8uaXNzeW0oKToNCiAgICAgICAgICAgIHNlbGYuY2htb2QodGFyaW5mbywgdGFyZ2V0cGF0aCkNCiAgICAgICAgICAgIHNlbGYudXRpbWUodGFyaW5mbywgdGFyZ2V0cGF0aCkNCg0KICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KICAgICMgQmVsb3cgYXJlIHRoZSBkaWZmZXJlbnQgZmlsZSBtZXRob2RzLiBUaGV5IGFyZSBjYWxsZWQgdmlhDQogICAgIyBfZXh0cmFjdF9tZW1iZXIoKSB3aGVuIGV4dHJhY3QoKSBpcyBjYWxsZWQuIFRoZXkgY2FuIGJlIHJlcGxhY2VkIGluIGENCiAgICAjIHN1YmNsYXNzIHRvIGltcGxlbWVudCBvdGhlciBmdW5jdGlvbmFsaXR5Lg0KDQogICAgZGVmIG1ha2VkaXIoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6DQogICAgICAgICIiIk1ha2UgYSBkaXJlY3RvcnkgY2FsbGVkIHRhcmdldHBhdGguDQogICAgICAgICIiIg0KICAgICAgICB0cnk6DQogICAgICAgICAgICAjIFVzZSBhIHNhZmUgbW9kZSBmb3IgdGhlIGRpcmVjdG9yeSwgdGhlIHJlYWwgbW9kZSBpcyBzZXQNCiAgICAgICAgICAgICMgbGF0ZXIgaW4gX2V4dHJhY3RfbWVtYmVyKCkuDQogICAgICAgICAgICBvcy5ta2Rpcih0YXJnZXRwYXRoLCAwNzAwKQ0KICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToNCiAgICAgICAgICAgIGlmIGUuZXJybm8gIT0gZXJybm8uRUVYSVNUOg0KICAgICAgICAgICAgICAgIHJhaXNlDQoNCiAgICBkZWYgbWFrZWZpbGUoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6DQogICAgICAgICIiIk1ha2UgYSBmaWxlIGNhbGxlZCB0YXJnZXRwYXRoLg0KICAgICAgICAiIiINCiAgICAgICAgc291cmNlID0gc2VsZi5leHRyYWN0ZmlsZSh0YXJpbmZvKQ0KICAgICAgICB0YXJnZXQgPSBibHRuX29wZW4odGFyZ2V0cGF0aCwgIndiIikNCiAgICAgICAgY29weWZpbGVvYmooc291cmNlLCB0YXJnZXQpDQogICAgICAgIHNvdXJjZS5jbG9zZSgpDQogICAgICAgIHRhcmdldC5jbG9zZSgpDQoNCiAgICBkZWYgbWFrZXVua25vd24oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6DQogICAgICAgICIiIk1ha2UgYSBmaWxlIGZyb20gYSBUYXJJbmZvIG9iamVjdCB3aXRoIGFuIHVua25vd24gdHlwZQ0KICAgICAgICAgICBhdCB0YXJnZXRwYXRoLg0KICAgICAgICAiIiINCiAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQ0KICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IFVua25vd24gZmlsZSB0eXBlICVyLCAiIFwNCiAgICAgICAgICAgICAgICAgICAgICJleHRyYWN0ZWQgYXMgcmVndWxhciBmaWxlLiIgJSB0YXJpbmZvLnR5cGUpDQoNCiAgICBkZWYgbWFrZWZpZm8oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6DQogICAgICAgICIiIk1ha2UgYSBmaWZvIGNhbGxlZCB0YXJnZXRwYXRoLg0KICAgICAgICAiIiINCiAgICAgICAgaWYgaGFzYXR0cihvcywgIm1rZmlmbyIpOg0KICAgICAgICAgICAgb3MubWtmaWZvKHRhcmdldHBhdGgpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoImZpZm8gbm90IHN1cHBvcnRlZCBieSBzeXN0ZW0iKQ0KDQogICAgZGVmIG1ha2VkZXYoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6DQogICAgICAgICIiIk1ha2UgYSBjaGFyYWN0ZXIgb3IgYmxvY2sgZGV2aWNlIGNhbGxlZCB0YXJnZXRwYXRoLg0KICAgICAgICAiIiINCiAgICAgICAgaWYgbm90IGhhc2F0dHIob3MsICJta25vZCIpIG9yIG5vdCBoYXNhdHRyKG9zLCAibWFrZWRldiIpOg0KICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yKCJzcGVjaWFsIGRldmljZXMgbm90IHN1cHBvcnRlZCBieSBzeXN0ZW0iKQ0KDQogICAgICAgIG1vZGUgPSB0YXJpbmZvLm1vZGUNCiAgICAgICAgaWYgdGFyaW5mby5pc2JsaygpOg0KICAgICAgICAgICAgbW9kZSB8PSBzdGF0LlNfSUZCTEsNCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIG1vZGUgfD0gc3RhdC5TX0lGQ0hSDQoNCiAgICAgICAgb3MubWtub2QodGFyZ2V0cGF0aCwgbW9kZSwNCiAgICAgICAgICAgICAgICAgb3MubWFrZWRldih0YXJpbmZvLmRldm1ham9yLCB0YXJpbmZvLmRldm1pbm9yKSkNCg0KICAgIGRlZiBtYWtlbGluayhzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToNCiAgICAgICAgIiIiTWFrZSBhIChzeW1ib2xpYykgbGluayBjYWxsZWQgdGFyZ2V0cGF0aC4gSWYgaXQgY2Fubm90IGJlIGNyZWF0ZWQNCiAgICAgICAgICAocGxhdGZvcm0gbGltaXRhdGlvbiksIHdlIHRyeSB0byBtYWtlIGEgY29weSBvZiB0aGUgcmVmZXJlbmNlZCBmaWxlDQogICAgICAgICAgaW5zdGVhZCBvZiBhIGxpbmsuDQogICAgICAgICIiIg0KICAgICAgICBpZiBoYXNhdHRyKG9zLCAic3ltbGluayIpIGFuZCBoYXNhdHRyKG9zLCAibGluayIpOg0KICAgICAgICAgICAgIyBGb3Igc3lzdGVtcyB0aGF0IHN1cHBvcnQgc3ltYm9saWMgYW5kIGhhcmQgbGlua3MuDQogICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6DQogICAgICAgICAgICAgICAgaWYgb3MucGF0aC5sZXhpc3RzKHRhcmdldHBhdGgpOg0KICAgICAgICAgICAgICAgICAgICBvcy51bmxpbmsodGFyZ2V0cGF0aCkNCiAgICAgICAgICAgICAgICBvcy5zeW1saW5rKHRhcmluZm8ubGlua25hbWUsIHRhcmdldHBhdGgpDQogICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgICMgU2VlIGV4dHJhY3QoKS4NCiAgICAgICAgICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyh0YXJpbmZvLl9saW5rX3RhcmdldCk6DQogICAgICAgICAgICAgICAgICAgIGlmIG9zLnBhdGgubGV4aXN0cyh0YXJnZXRwYXRoKToNCiAgICAgICAgICAgICAgICAgICAgICAgIG9zLnVubGluayh0YXJnZXRwYXRoKQ0KICAgICAgICAgICAgICAgICAgICBvcy5saW5rKHRhcmluZm8uX2xpbmtfdGFyZ2V0LCB0YXJnZXRwYXRoKQ0KICAgICAgICAgICAgICAgIGVsc2U6DQogICAgICAgICAgICAgICAgICAgIHNlbGYuX2V4dHJhY3RfbWVtYmVyKHNlbGYuX2ZpbmRfbGlua190YXJnZXQodGFyaW5mbyksIHRhcmdldHBhdGgpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICB0cnk6DQogICAgICAgICAgICAgICAgc2VsZi5fZXh0cmFjdF9tZW1iZXIoc2VsZi5fZmluZF9saW5rX3RhcmdldCh0YXJpbmZvKSwgdGFyZ2V0cGF0aCkNCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoNCiAgICAgICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoInVuYWJsZSB0byByZXNvbHZlIGxpbmsgaW5zaWRlIGFyY2hpdmUiKQ0KDQogICAgZGVmIGNob3duKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOg0KICAgICAgICAiIiJTZXQgb3duZXIgb2YgdGFyZ2V0cGF0aCBhY2NvcmRpbmcgdG8gdGFyaW5mby4NCiAgICAgICAgIiIiDQogICAgICAgIGlmIHB3ZCBhbmQgaGFzYXR0cihvcywgImdldGV1aWQiKSBhbmQgb3MuZ2V0ZXVpZCgpID09IDA6DQogICAgICAgICAgICAjIFdlIGhhdmUgdG8gYmUgcm9vdCB0byBkbyBzby4NCiAgICAgICAgICAgIHRyeToNCiAgICAgICAgICAgICAgICBnID0gZ3JwLmdldGdybmFtKHRhcmluZm8uZ25hbWUpWzJdDQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6DQogICAgICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgICAgICBnID0gZ3JwLmdldGdyZ2lkKHRhcmluZm8uZ2lkKVsyXQ0KICAgICAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoNCiAgICAgICAgICAgICAgICAgICAgZyA9IG9zLmdldGdpZCgpDQogICAgICAgICAgICB0cnk6DQogICAgICAgICAgICAgICAgdSA9IHB3ZC5nZXRwd25hbSh0YXJpbmZvLnVuYW1lKVsyXQ0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOg0KICAgICAgICAgICAgICAgIHRyeToNCiAgICAgICAgICAgICAgICAgICAgdSA9IHB3ZC5nZXRwd3VpZCh0YXJpbmZvLnVpZClbMl0NCiAgICAgICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6DQogICAgICAgICAgICAgICAgICAgIHUgPSBvcy5nZXR1aWQoKQ0KICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKSBhbmQgaGFzYXR0cihvcywgImxjaG93biIpOg0KICAgICAgICAgICAgICAgICAgICBvcy5sY2hvd24odGFyZ2V0cGF0aCwgdSwgZykNCiAgICAgICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gIT0gIm9zMmVteCI6DQogICAgICAgICAgICAgICAgICAgICAgICBvcy5jaG93bih0YXJnZXRwYXRoLCB1LCBnKQ0KICAgICAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6DQogICAgICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yKCJjb3VsZCBub3QgY2hhbmdlIG93bmVyIikNCg0KICAgIGRlZiBjaG1vZChzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToNCiAgICAgICAgIiIiU2V0IGZpbGUgcGVybWlzc2lvbnMgb2YgdGFyZ2V0cGF0aCBhY2NvcmRpbmcgdG8gdGFyaW5mby4NCiAgICAgICAgIiIiDQogICAgICAgIGlmIGhhc2F0dHIob3MsICdjaG1vZCcpOg0KICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgIG9zLmNobW9kKHRhcmdldHBhdGgsIHRhcmluZm8ubW9kZSkNCiAgICAgICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOg0KICAgICAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBtb2RlIikNCg0KICAgIGRlZiB1dGltZShzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToNCiAgICAgICAgIiIiU2V0IG1vZGlmaWNhdGlvbiB0aW1lIG9mIHRhcmdldHBhdGggYWNjb3JkaW5nIHRvIHRhcmluZm8uDQogICAgICAgICIiIg0KICAgICAgICBpZiBub3QgaGFzYXR0cihvcywgJ3V0aW1lJyk6DQogICAgICAgICAgICByZXR1cm4NCiAgICAgICAgdHJ5Og0KICAgICAgICAgICAgb3MudXRpbWUodGFyZ2V0cGF0aCwgKHRhcmluZm8ubXRpbWUsIHRhcmluZm8ubXRpbWUpKQ0KICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToNCiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBtb2RpZmljYXRpb24gdGltZSIpDQoNCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiAgICBkZWYgbmV4dChzZWxmKToNCiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IG1lbWJlciBvZiB0aGUgYXJjaGl2ZSBhcyBhIFRhckluZm8gb2JqZWN0LCB3aGVuDQogICAgICAgICAgIFRhckZpbGUgaXMgb3BlbmVkIGZvciByZWFkaW5nLiBSZXR1cm4gTm9uZSBpZiB0aGVyZSBpcyBubyBtb3JlDQogICAgICAgICAgIGF2YWlsYWJsZS4NCiAgICAgICAgIiIiDQogICAgICAgIHNlbGYuX2NoZWNrKCJyYSIpDQogICAgICAgIGlmIHNlbGYuZmlyc3RtZW1iZXIgaXMgbm90IE5vbmU6DQogICAgICAgICAgICBtID0gc2VsZi5maXJzdG1lbWJlcg0KICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IE5vbmUNCiAgICAgICAgICAgIHJldHVybiBtDQoNCiAgICAgICAgIyBSZWFkIHRoZSBuZXh0IGJsb2NrLg0KICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCkNCiAgICAgICAgdGFyaW5mbyA9IE5vbmUNCiAgICAgICAgd2hpbGUgVHJ1ZToNCiAgICAgICAgICAgIHRyeToNCiAgICAgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJpbmZvLmZyb210YXJmaWxlKHNlbGYpDQogICAgICAgICAgICBleGNlcHQgRU9GSGVhZGVyRXJyb3IsIGU6DQogICAgICAgICAgICAgICAgaWYgc2VsZi5pZ25vcmVfemVyb3M6DQogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAiMHglWDogJXMiICUgKHNlbGYub2Zmc2V0LCBlKSkNCiAgICAgICAgICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFDQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlDQogICAgICAgICAgICBleGNlcHQgSW52YWxpZEhlYWRlckVycm9yLCBlOg0KICAgICAgICAgICAgICAgIGlmIHNlbGYuaWdub3JlX3plcm9zOg0KICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMiwgIjB4JVg6ICVzIiAlIChzZWxmLm9mZnNldCwgZSkpDQogICAgICAgICAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQ0KICAgICAgICAgICAgICAgICAgICBjb250aW51ZQ0KICAgICAgICAgICAgICAgIGVsaWYgc2VsZi5vZmZzZXQgPT0gMDoNCiAgICAgICAgICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKHN0cihlKSkNCiAgICAgICAgICAgIGV4Y2VwdCBFbXB0eUhlYWRlckVycm9yOg0KICAgICAgICAgICAgICAgIGlmIHNlbGYub2Zmc2V0ID09IDA6DQogICAgICAgICAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigiZW1wdHkgZmlsZSIpDQogICAgICAgICAgICBleGNlcHQgVHJ1bmNhdGVkSGVhZGVyRXJyb3IsIGU6DQogICAgICAgICAgICAgICAgaWYgc2VsZi5vZmZzZXQgPT0gMDoNCiAgICAgICAgICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKHN0cihlKSkNCiAgICAgICAgICAgIGV4Y2VwdCBTdWJzZXF1ZW50SGVhZGVyRXJyb3IsIGU6DQogICAgICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKHN0cihlKSkNCiAgICAgICAgICAgIGJyZWFrDQoNCiAgICAgICAgaWYgdGFyaW5mbyBpcyBub3QgTm9uZToNCiAgICAgICAgICAgIHNlbGYubWVtYmVycy5hcHBlbmQodGFyaW5mbykNCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIHNlbGYuX2xvYWRlZCA9IFRydWUNCg0KICAgICAgICByZXR1cm4gdGFyaW5mbw0KDQogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQogICAgIyBMaXR0bGUgaGVscGVyIG1ldGhvZHM6DQoNCiAgICBkZWYgX2dldG1lbWJlcihzZWxmLCBuYW1lLCB0YXJpbmZvPU5vbmUsIG5vcm1hbGl6ZT1GYWxzZSk6DQogICAgICAgICIiIkZpbmQgYW4gYXJjaGl2ZSBtZW1iZXIgYnkgbmFtZSBmcm9tIGJvdHRvbSB0byB0b3AuDQogICAgICAgICAgIElmIHRhcmluZm8gaXMgZ2l2ZW4sIGl0IGlzIHVzZWQgYXMgdGhlIHN0YXJ0aW5nIHBvaW50Lg0KICAgICAgICAiIiINCiAgICAgICAgIyBFbnN1cmUgdGhhdCBhbGwgbWVtYmVycyBoYXZlIGJlZW4gbG9hZGVkLg0KICAgICAgICBtZW1iZXJzID0gc2VsZi5nZXRtZW1iZXJzKCkNCg0KICAgICAgICAjIExpbWl0IHRoZSBtZW1iZXIgc2VhcmNoIGxpc3QgdXAgdG8gdGFyaW5mby4NCiAgICAgICAgaWYgdGFyaW5mbyBpcyBub3QgTm9uZToNCiAgICAgICAgICAgIG1lbWJlcnMgPSBtZW1iZXJzWzptZW1iZXJzLmluZGV4KHRhcmluZm8pXQ0KDQogICAgICAgIGlmIG5vcm1hbGl6ZToNCiAgICAgICAgICAgIG5hbWUgPSBvcy5wYXRoLm5vcm1wYXRoKG5hbWUpDQoNCiAgICAgICAgZm9yIG1lbWJlciBpbiByZXZlcnNlZChtZW1iZXJzKToNCiAgICAgICAgICAgIGlmIG5vcm1hbGl6ZToNCiAgICAgICAgICAgICAgICBtZW1iZXJfbmFtZSA9IG9zLnBhdGgubm9ybXBhdGgobWVtYmVyLm5hbWUpDQogICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgIG1lbWJlcl9uYW1lID0gbWVtYmVyLm5hbWUNCg0KICAgICAgICAgICAgaWYgbmFtZSA9PSBtZW1iZXJfbmFtZToNCiAgICAgICAgICAgICAgICByZXR1cm4gbWVtYmVyDQoNCiAgICBkZWYgX2xvYWQoc2VsZik6DQogICAgICAgICIiIlJlYWQgdGhyb3VnaCB0aGUgZW50aXJlIGFyY2hpdmUgZmlsZSBhbmQgbG9vayBmb3IgcmVhZGFibGUNCiAgICAgICAgICAgbWVtYmVycy4NCiAgICAgICAgIiIiDQogICAgICAgIHdoaWxlIFRydWU6DQogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5uZXh0KCkNCiAgICAgICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToNCiAgICAgICAgICAgICAgICBicmVhaw0KICAgICAgICBzZWxmLl9sb2FkZWQgPSBUcnVlDQoNCiAgICBkZWYgX2NoZWNrKHNlbGYsIG1vZGU9Tm9uZSk6DQogICAgICAgICIiIkNoZWNrIGlmIFRhckZpbGUgaXMgc3RpbGwgb3BlbiwgYW5kIGlmIHRoZSBvcGVyYXRpb24ncyBtb2RlDQogICAgICAgICAgIGNvcnJlc3BvbmRzIHRvIFRhckZpbGUncyBtb2RlLg0KICAgICAgICAiIiINCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6DQogICAgICAgICAgICByYWlzZSBJT0Vycm9yKCIlcyBpcyBjbG9zZWQiICUgc2VsZi5fX2NsYXNzX18uX19uYW1lX18pDQogICAgICAgIGlmIG1vZGUgaXMgbm90IE5vbmUgYW5kIHNlbGYubW9kZSBub3QgaW4gbW9kZToNCiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoImJhZCBvcGVyYXRpb24gZm9yIG1vZGUgJXIiICUgc2VsZi5tb2RlKQ0KDQogICAgZGVmIF9maW5kX2xpbmtfdGFyZ2V0KHNlbGYsIHRhcmluZm8pOg0KICAgICAgICAiIiJGaW5kIHRoZSB0YXJnZXQgbWVtYmVyIG9mIGEgc3ltbGluayBvciBoYXJkbGluayBtZW1iZXIgaW4gdGhlDQogICAgICAgICAgIGFyY2hpdmUuDQogICAgICAgICIiIg0KICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6DQogICAgICAgICAgICAjIEFsd2F5cyBzZWFyY2ggdGhlIGVudGlyZSBhcmNoaXZlLg0KICAgICAgICAgICAgbGlua25hbWUgPSBvcy5wYXRoLmRpcm5hbWUodGFyaW5mby5uYW1lKSArICIvIiArIHRhcmluZm8ubGlua25hbWUNCiAgICAgICAgICAgIGxpbWl0ID0gTm9uZQ0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgIyBTZWFyY2ggdGhlIGFyY2hpdmUgYmVmb3JlIHRoZSBsaW5rLCBiZWNhdXNlIGEgaGFyZCBsaW5rIGlzDQogICAgICAgICAgICAjIGp1c3QgYSByZWZlcmVuY2UgdG8gYW4gYWxyZWFkeSBhcmNoaXZlZCBmaWxlLg0KICAgICAgICAgICAgbGlua25hbWUgPSB0YXJpbmZvLmxpbmtuYW1lDQogICAgICAgICAgICBsaW1pdCA9IHRhcmluZm8NCg0KICAgICAgICBtZW1iZXIgPSBzZWxmLl9nZXRtZW1iZXIobGlua25hbWUsIHRhcmluZm89bGltaXQsIG5vcm1hbGl6ZT1UcnVlKQ0KICAgICAgICBpZiBtZW1iZXIgaXMgTm9uZToNCiAgICAgICAgICAgIHJhaXNlIEtleUVycm9yKCJsaW5rbmFtZSAlciBub3QgZm91bmQiICUgbGlua25hbWUpDQogICAgICAgIHJldHVybiBtZW1iZXINCg0KICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToNCiAgICAgICAgIiIiUHJvdmlkZSBhbiBpdGVyYXRvciBvYmplY3QuDQogICAgICAgICIiIg0KICAgICAgICBpZiBzZWxmLl9sb2FkZWQ6DQogICAgICAgICAgICByZXR1cm4gaXRlcihzZWxmLm1lbWJlcnMpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICByZXR1cm4gVGFySXRlcihzZWxmKQ0KDQogICAgZGVmIF9kYmcoc2VsZiwgbGV2ZWwsIG1zZyk6DQogICAgICAgICIiIldyaXRlIGRlYnVnZ2luZyBvdXRwdXQgdG8gc3lzLnN0ZGVyci4NCiAgICAgICAgIiIiDQogICAgICAgIGlmIGxldmVsIDw9IHNlbGYuZGVidWc6DQogICAgICAgICAgICBwcmludCA+PiBzeXMuc3RkZXJyLCBtc2cNCg0KICAgIGRlZiBfX2VudGVyX18oc2VsZik6DQogICAgICAgIHNlbGYuX2NoZWNrKCkNCiAgICAgICAgcmV0dXJuIHNlbGYNCg0KICAgIGRlZiBfX2V4aXRfXyhzZWxmLCB0eXBlLCB2YWx1ZSwgdHJhY2ViYWNrKToNCiAgICAgICAgaWYgdHlwZSBpcyBOb25lOg0KICAgICAgICAgICAgc2VsZi5jbG9zZSgpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICAjIEFuIGV4Y2VwdGlvbiBvY2N1cnJlZC4gV2UgbXVzdCBub3QgY2FsbCBjbG9zZSgpIGJlY2F1c2UNCiAgICAgICAgICAgICMgaXQgd291bGQgdHJ5IHRvIHdyaXRlIGVuZC1vZi1hcmNoaXZlIGJsb2NrcyBhbmQgcGFkZGluZy4NCiAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9leHRmaWxlb2JqOg0KICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpDQogICAgICAgICAgICBzZWxmLmNsb3NlZCA9IFRydWUNCiMgY2xhc3MgVGFyRmlsZQ0KDQpjbGFzcyBUYXJJdGVyOg0KICAgICIiIkl0ZXJhdG9yIENsYXNzLg0KDQogICAgICAgZm9yIHRhcmluZm8gaW4gVGFyRmlsZSguLi4pOg0KICAgICAgICAgICBzdWl0ZS4uLg0KICAgICIiIg0KDQogICAgZGVmIF9faW5pdF9fKHNlbGYsIHRhcmZpbGUpOg0KICAgICAgICAiIiJDb25zdHJ1Y3QgYSBUYXJJdGVyIG9iamVjdC4NCiAgICAgICAgIiIiDQogICAgICAgIHNlbGYudGFyZmlsZSA9IHRhcmZpbGUNCiAgICAgICAgc2VsZi5pbmRleCA9IDANCiAgICBkZWYgX19pdGVyX18oc2VsZik6DQogICAgICAgICIiIlJldHVybiBpdGVyYXRvciBvYmplY3QuDQogICAgICAgICIiIg0KICAgICAgICByZXR1cm4gc2VsZg0KICAgIGRlZiBuZXh0KHNlbGYpOg0KICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgaXRlbSB1c2luZyBUYXJGaWxlJ3MgbmV4dCgpIG1ldGhvZC4NCiAgICAgICAgICAgV2hlbiBhbGwgbWVtYmVycyBoYXZlIGJlZW4gcmVhZCwgc2V0IFRhckZpbGUgYXMgX2xvYWRlZC4NCiAgICAgICAgIiIiDQogICAgICAgICMgRml4IGZvciBTRiAjMTEwMDQyOTogVW5kZXIgcmFyZSBjaXJjdW1zdGFuY2VzIGl0IGNhbg0KICAgICAgICAjIGhhcHBlbiB0aGF0IGdldG1lbWJlcnMoKSBpcyBjYWxsZWQgZHVyaW5nIGl0ZXJhdGlvbiwNCiAgICAgICAgIyB3aGljaCB3aWxsIGNhdXNlIFRhckl0ZXIgdG8gc3RvcCBwcmVtYXR1cmVseS4NCiAgICAgICAgaWYgbm90IHNlbGYudGFyZmlsZS5fbG9hZGVkOg0KICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyZmlsZS5uZXh0KCkNCiAgICAgICAgICAgIGlmIG5vdCB0YXJpbmZvOg0KICAgICAgICAgICAgICAgIHNlbGYudGFyZmlsZS5fbG9hZGVkID0gVHJ1ZQ0KICAgICAgICAgICAgICAgIHJhaXNlIFN0b3BJdGVyYXRpb24NCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIHRyeToNCiAgICAgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJmaWxlLm1lbWJlcnNbc2VsZi5pbmRleF0NCiAgICAgICAgICAgIGV4Y2VwdCBJbmRleEVycm9yOg0KICAgICAgICAgICAgICAgIHJhaXNlIFN0b3BJdGVyYXRpb24NCiAgICAgICAgc2VsZi5pbmRleCArPSAxDQogICAgICAgIHJldHVybiB0YXJpbmZvDQoNCiMgSGVscGVyIGNsYXNzZXMgZm9yIHNwYXJzZSBmaWxlIHN1cHBvcnQNCmNsYXNzIF9zZWN0aW9uOg0KICAgICIiIkJhc2UgY2xhc3MgZm9yIF9kYXRhIGFuZCBfaG9sZS4NCiAgICAiIiINCiAgICBkZWYgX19pbml0X18oc2VsZiwgb2Zmc2V0LCBzaXplKToNCiAgICAgICAgc2VsZi5vZmZzZXQgPSBvZmZzZXQNCiAgICAgICAgc2VsZi5zaXplID0gc2l6ZQ0KICAgIGRlZiBfX2NvbnRhaW5zX18oc2VsZiwgb2Zmc2V0KToNCiAgICAgICAgcmV0dXJuIHNlbGYub2Zmc2V0IDw9IG9mZnNldCA8IHNlbGYub2Zmc2V0ICsgc2VsZi5zaXplDQoNCmNsYXNzIF9kYXRhKF9zZWN0aW9uKToNCiAgICAiIiJSZXByZXNlbnQgYSBkYXRhIHNlY3Rpb24gaW4gYSBzcGFyc2UgZmlsZS4NCiAgICAiIiINCiAgICBkZWYgX19pbml0X18oc2VsZiwgb2Zmc2V0LCBzaXplLCByZWFscG9zKToNCiAgICAgICAgX3NlY3Rpb24uX19pbml0X18oc2VsZiwgb2Zmc2V0LCBzaXplKQ0KICAgICAgICBzZWxmLnJlYWxwb3MgPSByZWFscG9zDQoNCmNsYXNzIF9ob2xlKF9zZWN0aW9uKToNCiAgICAiIiJSZXByZXNlbnQgYSBob2xlIHNlY3Rpb24gaW4gYSBzcGFyc2UgZmlsZS4NCiAgICAiIiINCiAgICBwYXNzDQoNCmNsYXNzIF9yaW5nYnVmZmVyKGxpc3QpOg0KICAgICIiIlJpbmdidWZmZXIgY2xhc3Mgd2hpY2ggaW5jcmVhc2VzIHBlcmZvcm1hbmNlDQogICAgICAgb3ZlciBhIHJlZ3VsYXIgbGlzdC4NCiAgICAiIiINCiAgICBkZWYgX19pbml0X18oc2VsZik6DQogICAgICAgIHNlbGYuaWR4ID0gMA0KICAgIGRlZiBmaW5kKHNlbGYsIG9mZnNldCk6DQogICAgICAgIGlkeCA9IHNlbGYuaWR4DQogICAgICAgIHdoaWxlIFRydWU6DQogICAgICAgICAgICBpdGVtID0gc2VsZltpZHhdDQogICAgICAgICAgICBpZiBvZmZzZXQgaW4gaXRlbToNCiAgICAgICAgICAgICAgICBicmVhaw0KICAgICAgICAgICAgaWR4ICs9IDENCiAgICAgICAgICAgIGlmIGlkeCA9PSBsZW4oc2VsZik6DQogICAgICAgICAgICAgICAgaWR4ID0gMA0KICAgICAgICAgICAgaWYgaWR4ID09IHNlbGYuaWR4Og0KICAgICAgICAgICAgICAgICMgRW5kIG9mIEZpbGUNCiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQ0KICAgICAgICBzZWxmLmlkeCA9IGlkeA0KICAgICAgICByZXR1cm4gaXRlbQ0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIHppcGZpbGUgY29tcGF0aWJsZSBUYXJGaWxlIGNsYXNzDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpUQVJfUExBSU4gPSAwICAgICAgICAgICAjIHppcGZpbGUuWklQX1NUT1JFRA0KVEFSX0daSVBQRUQgPSA4ICAgICAgICAgIyB6aXBmaWxlLlpJUF9ERUZMQVRFRA0KY2xhc3MgVGFyRmlsZUNvbXBhdDoNCiAgICAiIiJUYXJGaWxlIGNsYXNzIGNvbXBhdGlibGUgd2l0aCBzdGFuZGFyZCBtb2R1bGUgemlwZmlsZSdzDQogICAgICAgWmlwRmlsZSBjbGFzcy4NCiAgICAiIiINCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZSwgbW9kZT0iciIsIGNvbXByZXNzaW9uPVRBUl9QTEFJTik6DQogICAgICAgIGZyb20gd2FybmluZ3MgaW1wb3J0IHdhcm5weTNrDQogICAgICAgIHdhcm5weTNrKCJ0aGUgVGFyRmlsZUNvbXBhdCBjbGFzcyBoYXMgYmVlbiByZW1vdmVkIGluIFB5dGhvbiAzLjAiLA0KICAgICAgICAgICAgICAgIHN0YWNrbGV2ZWw9MikNCiAgICAgICAgaWYgY29tcHJlc3Npb24gPT0gVEFSX1BMQUlOOg0KICAgICAgICAgICAgc2VsZi50YXJmaWxlID0gVGFyRmlsZS50YXJvcGVuKGZpbGUsIG1vZGUpDQogICAgICAgIGVsaWYgY29tcHJlc3Npb24gPT0gVEFSX0daSVBQRUQ6DQogICAgICAgICAgICBzZWxmLnRhcmZpbGUgPSBUYXJGaWxlLmd6b3BlbihmaWxlLCBtb2RlKQ0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigidW5rbm93biBjb21wcmVzc2lvbiBjb25zdGFudCIpDQogICAgICAgIGlmIG1vZGVbMDoxXSA9PSAiciI6DQogICAgICAgICAgICBtZW1iZXJzID0gc2VsZi50YXJmaWxlLmdldG1lbWJlcnMoKQ0KICAgICAgICAgICAgZm9yIG0gaW4gbWVtYmVyczoNCiAgICAgICAgICAgICAgICBtLmZpbGVuYW1lID0gbS5uYW1lDQogICAgICAgICAgICAgICAgbS5maWxlX3NpemUgPSBtLnNpemUNCiAgICAgICAgICAgICAgICBtLmRhdGVfdGltZSA9IHRpbWUuZ210aW1lKG0ubXRpbWUpWzo2XQ0KICAgIGRlZiBuYW1lbGlzdChzZWxmKToNCiAgICAgICAgcmV0dXJuIG1hcChsYW1iZGEgbTogbS5uYW1lLCBzZWxmLmluZm9saXN0KCkpDQogICAgZGVmIGluZm9saXN0KHNlbGYpOg0KICAgICAgICByZXR1cm4gZmlsdGVyKGxhbWJkYSBtOiBtLnR5cGUgaW4gUkVHVUxBUl9UWVBFUywNCiAgICAgICAgICAgICAgICAgICAgICBzZWxmLnRhcmZpbGUuZ2V0bWVtYmVycygpKQ0KICAgIGRlZiBwcmludGRpcihzZWxmKToNCiAgICAgICAgc2VsZi50YXJmaWxlLmxpc3QoKQ0KICAgIGRlZiB0ZXN0emlwKHNlbGYpOg0KICAgICAgICByZXR1cm4NCiAgICBkZWYgZ2V0aW5mbyhzZWxmLCBuYW1lKToNCiAgICAgICAgcmV0dXJuIHNlbGYudGFyZmlsZS5nZXRtZW1iZXIobmFtZSkNCiAgICBkZWYgcmVhZChzZWxmLCBuYW1lKToNCiAgICAgICAgcmV0dXJuIHNlbGYudGFyZmlsZS5leHRyYWN0ZmlsZShzZWxmLnRhcmZpbGUuZ2V0bWVtYmVyKG5hbWUpKS5yZWFkKCkNCiAgICBkZWYgd3JpdGUoc2VsZiwgZmlsZW5hbWUsIGFyY25hbWU9Tm9uZSwgY29tcHJlc3NfdHlwZT1Ob25lKToNCiAgICAgICAgc2VsZi50YXJmaWxlLmFkZChmaWxlbmFtZSwgYXJjbmFtZSkNCiAgICBkZWYgd3JpdGVzdHIoc2VsZiwgemluZm8sIGJ5dGVzKToNCiAgICAgICAgdHJ5Og0KICAgICAgICAgICAgZnJvbSBjU3RyaW5nSU8gaW1wb3J0IFN0cmluZ0lPDQogICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoNCiAgICAgICAgICAgIGZyb20gU3RyaW5nSU8gaW1wb3J0IFN0cmluZ0lPDQogICAgICAgIGltcG9ydCBjYWxlbmRhcg0KICAgICAgICB0aW5mbyA9IFRhckluZm8oemluZm8uZmlsZW5hbWUpDQogICAgICAgIHRpbmZvLnNpemUgPSBsZW4oYnl0ZXMpDQogICAgICAgIHRpbmZvLm10aW1lID0gY2FsZW5kYXIudGltZWdtKHppbmZvLmRhdGVfdGltZSkNCiAgICAgICAgc2VsZi50YXJmaWxlLmFkZGZpbGUodGluZm8sIFN0cmluZ0lPKGJ5dGVzKSkNCiAgICBkZWYgY2xvc2Uoc2VsZik6DQogICAgICAgIHNlbGYudGFyZmlsZS5jbG9zZSgpDQojY2xhc3MgVGFyRmlsZUNvbXBhdA0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgZXhwb3J0ZWQgZnVuY3Rpb25zDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0NCmRlZiBpc190YXJmaWxlKG5hbWUpOg0KICAgICIiIlJldHVybiBUcnVlIGlmIG5hbWUgcG9pbnRzIHRvIGEgdGFyIGFyY2hpdmUgdGhhdCB3ZQ0KICAgICAgIGFyZSBhYmxlIHRvIGhhbmRsZSwgZWxzZSByZXR1cm4gRmFsc2UuDQogICAgIiIiDQogICAgdHJ5Og0KICAgICAgICB0ID0gb3BlbihuYW1lKQ0KICAgICAgICB0LmNsb3NlKCkNCiAgICAgICAgcmV0dXJuIFRydWUNCiAgICBleGNlcHQgVGFyRXJyb3I6DQogICAgICAgIHJldHVybiBGYWxzZQ0KDQpibHRuX29wZW4gPSBvcGVuDQpvcGVuID0gVGFyRmlsZS5vcGVuDQo=