IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiIiIkdlbmVyYXRlIFB5dGhvbiBkb2N1bWVudGF0aW9uIGluIEhUTUwgb3IgYXMgdGV4dCBmb3IgaW50ZXJhY3RpdmUgdXNlLgoKQXQgdGhlIHNoZWxsIGNvbW1hbmQgbGluZSBvdXRzaWRlIG9mIFB5dGhvbiwgcnVuICJweWRvYyA8bmFtZT4iIHRvIHNob3cKZG9jdW1lbnRhdGlvbiBvbiBzb21ldGhpbmcuICA8bmFtZT4gbWF5IGJlIHRoZSBuYW1lIG9mIGEgUHl0aG9uIGZ1bmN0aW9uLAptb2R1bGUsIHBhY2thZ2UsIG9yIGEgZG90dGVkIHJlZmVyZW5jZSB0byBhIGNsYXNzIG9yIGZ1bmN0aW9uIHdpdGhpbiBhCm1vZHVsZSBvciBtb2R1bGUgaW4gYSBwYWNrYWdlLiAgQWx0ZXJuYXRpdmVseSwgdGhlIGFyZ3VtZW50IGNhbiBiZSB0aGUKcGF0aCB0byBhIFB5dGhvbiBzb3VyY2UgZmlsZS4KCk9yLCBhdCB0aGUgc2hlbGwgcHJvbXB0LCBydW4gInB5ZG9jIC1rIDxrZXl3b3JkPiIgdG8gc2VhcmNoIGZvciBhIGtleXdvcmQKaW4gdGhlIG9uZS1saW5lIGRlc2NyaXB0aW9ucyBvZiBtb2R1bGVzLgoKT3IsIGF0IHRoZSBzaGVsbCBwcm9tcHQsIHJ1biAicHlkb2MgLXAgPHBvcnQ+IiB0byBzdGFydCBhbiBIVFRQIHNlcnZlcgpvbiBhIGdpdmVuIHBvcnQgb24gdGhlIGxvY2FsIG1hY2hpbmUgdG8gZ2VuZXJhdGUgZG9jdW1lbnRhdGlvbiB3ZWIgcGFnZXMuCgpPciwgYXQgdGhlIHNoZWxsIHByb21wdCwgcnVuICJweWRvYyAtdyA8bmFtZT4iIHRvIHdyaXRlIG91dCB0aGUgSFRNTApkb2N1bWVudGF0aW9uIGZvciBhIG1vZHVsZSB0byBhIGZpbGUgbmFtZWQgIjxuYW1lPi5odG1sIi4KCkluIHRoZSBQeXRob24gaW50ZXJwcmV0ZXIsIGRvICJmcm9tIHB5ZG9jIGltcG9ydCBoZWxwIiB0byBwcm92aWRlIG9ubGluZQpoZWxwLiAgQ2FsbGluZyBoZWxwKHRoaW5nKSBvbiBhIFB5dGhvbiBvYmplY3QgZG9jdW1lbnRzIHRoZSBvYmplY3QuIiIiCgpfX2F1dGhvcl9fID0gIkthLVBpbmcgWWVlIDxwaW5nQGxmdy5vcmc+IgpfX2RhdGVfXyA9ICIyNiBGZWJydWFyeSAyMDAxIgpfX3ZlcnNpb25fXyA9ICIkUmV2aXNpb24kIgpfX2NyZWRpdHNfXyA9ICIiIkd1aWRvIHZhbiBSb3NzdW0sIGZvciBhbiBleGNlbGxlbnQgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuClRvbW15IEJ1cm5ldHRlLCB0aGUgb3JpZ2luYWwgY3JlYXRvciBvZiBtYW5weS4KUGF1bCBQcmVzY29kLCBmb3IgYWxsIGhpcyB3b3JrIG9uIG9ubGluZWhlbHAuClJpY2hhcmQgQ2hhbWJlcmxhaW4sIGZvciB0aGUgZmlyc3QgaW1wbGVtZW50YXRpb24gb2YgdGV4dGRvYy4KCk15bmQgeW91LCBt+PhzZSBiaXRlcyBLYW4gYmUgcHJldHR5IG5hc3RpLi4uIiIiCgppbXBvcnQgc3lzLCBpbXAsIG9zLCBzdGF0LCByZSwgdHlwZXMsIGluc3BlY3QKZnJvbSByZXByIGltcG9ydCBSZXByCmZyb20gc3RyaW5nIGltcG9ydCBleHBhbmR0YWJzLCBmaW5kLCBqb2luLCBsb3dlciwgc3BsaXQsIHN0cmlwLCByc3RyaXAKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGNvbW1vbiByb3V0aW5lcwoKZGVmIHN5bm9wc2lzKGZpbGVuYW1lLCBjYWNoZT17fSk6CiAgICAiIiJHZXQgdGhlIG9uZS1saW5lIHN1bW1hcnkgb3V0IG9mIGEgbW9kdWxlIGZpbGUuIiIiCiAgICBtdGltZSA9IG9zLnN0YXQoZmlsZW5hbWUpW3N0YXQuU1RfTVRJTUVdCiAgICBsYXN0dXBkYXRlLCByZXN1bHQgPSBjYWNoZS5nZXQoZmlsZW5hbWUsICgwLCBOb25lKSkKICAgIGlmIGxhc3R1cGRhdGUgPCBtdGltZToKICAgICAgICBmaWxlID0gb3BlbihmaWxlbmFtZSkKICAgICAgICBsaW5lID0gZmlsZS5yZWFkbGluZSgpCiAgICAgICAgd2hpbGUgbGluZVs6MV0gPT0gJyMnIG9yIHN0cmlwKGxpbmUpID09ICcnOgogICAgICAgICAgICBsaW5lID0gZmlsZS5yZWFkbGluZSgpCiAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgIGlmIGxpbmVbLTI6XSA9PSAnXFxcbic6CiAgICAgICAgICAgIGxpbmUgPSBsaW5lWzotMl0gKyBmaWxlLnJlYWRsaW5lKCkKICAgICAgICBsaW5lID0gc3RyaXAobGluZSkKICAgICAgICBpZiBsaW5lWzozXSA9PSAnIiIiJzoKICAgICAgICAgICAgbGluZSA9IGxpbmVbMzpdCiAgICAgICAgICAgIHdoaWxlIHN0cmlwKGxpbmUpID09ICcnOgogICAgICAgICAgICAgICAgbGluZSA9IGZpbGUucmVhZGxpbmUoKQogICAgICAgICAgICAgICAgaWYgbm90IGxpbmU6IGJyZWFrCiAgICAgICAgICAgIHJlc3VsdCA9IHNwbGl0KGxpbmUsICciIiInKVswXQogICAgICAgIGVsc2U6IHJlc3VsdCA9IE5vbmUKICAgICAgICBmaWxlLmNsb3NlKCkKICAgICAgICBjYWNoZVtmaWxlbmFtZV0gPSAobXRpbWUsIHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQKCmRlZiBpbmRleChkaXIpOgogICAgIiIiUmV0dXJuIGEgbGlzdCBvZiAobW9kdWxlLW5hbWUsIHN5bm9wc2lzKSBwYWlycyBmb3IgYSBkaXJlY3RvcnkgdHJlZS4iIiIKICAgIHJlc3VsdHMgPSBbXQogICAgZm9yIGVudHJ5IGluIG9zLmxpc3RkaXIoZGlyKToKICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKGRpciwgZW50cnkpCiAgICAgICAgaWYgaXNwYWNrYWdlKHBhdGgpOgogICAgICAgICAgICByZXN1bHRzLmV4dGVuZChtYXAoCiAgICAgICAgICAgICAgICBsYW1iZGEgKG0sIHMpLCBwa2c9ZW50cnk6IChwa2cgKyAnLicgKyBtLCBzKSwgaW5kZXgocGF0aCkpKQogICAgICAgIGVsaWYgb3MucGF0aC5pc2ZpbGUocGF0aCkgYW5kIGVudHJ5Wy0zOl0gPT0gJy5weSc6CiAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKChlbnRyeVs6LTNdLCBzeW5vcHNpcyhwYXRoKSkpCiAgICByZXR1cm4gcmVzdWx0cwoKZGVmIHBhdGhkaXJzKCk6CiAgICAiIiJDb252ZXJ0IHN5cy5wYXRoIGludG8gYSBsaXN0IG9mIGFic29sdXRlLCBleGlzdGluZywgdW5pcXVlIHBhdGhzLiIiIgogICAgZGlycyA9IFtdCiAgICBmb3IgZGlyIGluIHN5cy5wYXRoOgogICAgICAgIGRpciA9IG9zLnBhdGguYWJzcGF0aChkaXIgb3IgJy4nKQogICAgICAgIGlmIGRpciBub3QgaW4gZGlycyBhbmQgb3MucGF0aC5pc2RpcihkaXIpOgogICAgICAgICAgICBkaXJzLmFwcGVuZChkaXIpCiAgICByZXR1cm4gZGlycwoKZGVmIGdldGRvYyhvYmplY3QpOgogICAgIiIiR2V0IHRoZSBkb2Mgc3RyaW5nIG9yIGNvbW1lbnRzIGZvciBhbiBvYmplY3QuIiIiCiAgICByZXN1bHQgPSBpbnNwZWN0LmdldGRvYyhvYmplY3QpCiAgICBpZiBub3QgcmVzdWx0OgogICAgICAgIHRyeTogcmVzdWx0ID0gaW5zcGVjdC5nZXRjb21tZW50cyhvYmplY3QpCiAgICAgICAgZXhjZXB0OiBwYXNzCiAgICByZXR1cm4gcmVzdWx0IGFuZCByc3RyaXAocmVzdWx0KSBvciAnJwoKZGVmIGNsYXNzbmFtZShvYmplY3QsIG1vZG5hbWUpOgogICAgIiIiR2V0IGEgY2xhc3MgbmFtZSBhbmQgcXVhbGlmeSBpdCB3aXRoIGEgbW9kdWxlIG5hbWUgaWYgbmVjZXNzYXJ5LiIiIgogICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgaWYgb2JqZWN0Ll9fbW9kdWxlX18gIT0gbW9kbmFtZToKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbW9kdWxlX18gKyAnLicgKyBuYW1lCiAgICByZXR1cm4gbmFtZQoKZGVmIGlzY29uc3RhbnQob2JqZWN0KToKICAgICIiIkNoZWNrIGlmIGFuIG9iamVjdCBpcyBvZiBhIHR5cGUgdGhhdCBwcm9iYWJseSBtZWFucyBpdCdzIGEgY29uc3RhbnQuIiIiCiAgICByZXR1cm4gdHlwZShvYmplY3QpIGluIFsKICAgICAgICB0eXBlcy5GbG9hdFR5cGUsIHR5cGVzLkludFR5cGUsIHR5cGVzLkxpc3RUeXBlLCB0eXBlcy5Mb25nVHlwZSwKICAgICAgICB0eXBlcy5TdHJpbmdUeXBlLCB0eXBlcy5UdXBsZVR5cGUsIHR5cGVzLlR5cGVUeXBlLAogICAgICAgIGhhc2F0dHIodHlwZXMsICdVbmljb2RlVHlwZScpIGFuZCB0eXBlcy5Vbmljb2RlVHlwZSBvciAwXQoKZGVmIHJlcGxhY2UodGV4dCwgKnBhaXJzKToKICAgICIiIkRvIGEgc2VyaWVzIG9mIGdsb2JhbCByZXBsYWNlbWVudHMgb24gYSBzdHJpbmcuIiIiCiAgICBmb3Igb2xkLCBuZXcgaW4gcGFpcnM6CiAgICAgICAgdGV4dCA9IGpvaW4oc3BsaXQodGV4dCwgb2xkKSwgbmV3KQogICAgcmV0dXJuIHRleHQKCmRlZiBjcmFtKHRleHQsIG1heGxlbik6CiAgICAiIiJPbWl0IHBhcnQgb2YgYSBzdHJpbmcgaWYgbmVlZGVkIHRvIG1ha2UgaXQgZml0IGluIGEgbWF4aW11bSBsZW5ndGguIiIiCiAgICBpZiBsZW4odGV4dCkgPiBtYXhsZW46CiAgICAgICAgcHJlID0gbWF4KDAsIChtYXhsZW4tMykvMikKICAgICAgICBwb3N0ID0gbWF4KDAsIG1heGxlbi0zLXByZSkKICAgICAgICByZXR1cm4gdGV4dFs6cHJlXSArICcuLi4nICsgdGV4dFtsZW4odGV4dCktcG9zdDpdCiAgICByZXR1cm4gdGV4dAoKZGVmIGNsZWFuaWQodGV4dCk6CiAgICAiIiJSZW1vdmUgdGhlIGhleGFkZWNpbWFsIGlkIGZyb20gYSBQeXRob24gb2JqZWN0IHJlcHJlc2VudGF0aW9uLiIiIgogICAgcmV0dXJuIHJlLnN1YignIGF0IDB4WzAtOWEtZl17NSx9PiQnLCAnPicsIHRleHQpCgpkZWYgbW9kdWxlbmFtZShwYXRoKToKICAgICIiIlJldHVybiB0aGUgUHl0aG9uIG1vZHVsZSBuYW1lIGZvciBhIGdpdmVuIHBhdGgsIG9yIE5vbmUuIiIiCiAgICBmaWxlbmFtZSA9IG9zLnBhdGguYmFzZW5hbWUocGF0aCkKICAgIGlmIGxvd2VyKGZpbGVuYW1lWy0zOl0pID09ICcucHknOgogICAgICAgIHJldHVybiBmaWxlbmFtZVs6LTNdCiAgICBlbGlmIGxvd2VyKGZpbGVuYW1lWy00Ol0pID09ICcucHljJzoKICAgICAgICByZXR1cm4gZmlsZW5hbWVbOi00XQogICAgZWxpZiBsb3dlcihmaWxlbmFtZVstMTE6XSkgPT0gJ21vZHVsZS5zbyc6CiAgICAgICAgcmV0dXJuIGZpbGVuYW1lWzotMTFdCiAgICBlbGlmIGxvd2VyKGZpbGVuYW1lWy0xMzpdKSA9PSAnbW9kdWxlLnNvLjEnOgogICAgICAgIHJldHVybiBmaWxlbmFtZVs6LTEzXQoKY2xhc3MgRG9jSW1wb3J0RXJyb3IoRXhjZXB0aW9uKToKICAgICIiIkNsYXNzIGZvciBlcnJvcnMgd2hpbGUgdHJ5aW5nIHRvIGltcG9ydCBzb21ldGhpbmcgdG8gZG9jdW1lbnQgaXQuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW5hbWUsIGV0eXBlLCBldmFsdWUpOgogICAgICAgIHNlbGYuZmlsZW5hbWUgPSBmaWxlbmFtZQogICAgICAgIHNlbGYuZXR5cGUgPSBldHlwZQogICAgICAgIHNlbGYuZXZhbHVlID0gZXZhbHVlCiAgICAgICAgaWYgdHlwZShldHlwZSkgaXMgdHlwZXMuQ2xhc3NUeXBlOgogICAgICAgICAgICBldHlwZSA9IGV0eXBlLl9fbmFtZV9fCiAgICAgICAgc2VsZi5hcmdzID0gJyVzOiAlcycgJSAoZXR5cGUsIGV2YWx1ZSkKCmRlZiBpbXBvcnRmaWxlKHBhdGgpOgogICAgIiIiSW1wb3J0IGEgUHl0aG9uIHNvdXJjZSBmaWxlIG9yIGNvbXBpbGVkIGZpbGUgZ2l2ZW4gaXRzIHBhdGguIiIiCiAgICBtYWdpYyA9IGltcC5nZXRfbWFnaWMoKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgaWYgZmlsZS5yZWFkKGxlbihtYWdpYykpID09IG1hZ2ljOgogICAgICAgIGtpbmQgPSBpbXAuUFlfQ09NUElMRUQKICAgIGVsc2U6CiAgICAgICAga2luZCA9IGltcC5QWV9TT1VSQ0UKICAgIGZpbGUuY2xvc2UoKQogICAgZmlsZW5hbWUgPSBvcy5wYXRoLmJhc2VuYW1lKHBhdGgpCiAgICBuYW1lLCBleHQgPSBvcy5wYXRoLnNwbGl0ZXh0KGZpbGVuYW1lKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgdHJ5OgogICAgICAgIG1vZHVsZSA9IGltcC5sb2FkX21vZHVsZShuYW1lLCBmaWxlLCBwYXRoLCAoZXh0LCAncicsIGtpbmQpKQogICAgZXhjZXB0OgogICAgICAgIHJhaXNlIERvY0ltcG9ydEVycm9yKHBhdGgsIHN5cy5leGNfdHlwZSwgc3lzLmV4Y192YWx1ZSkKICAgIGZpbGUuY2xvc2UoKQogICAgcmV0dXJuIG1vZHVsZQoKZGVmIGlzcGFja2FnZShwYXRoKToKICAgICIiIkd1ZXNzIHdoZXRoZXIgYSBwYXRoIHJlZmVycyB0byBhIHBhY2thZ2UgZGlyZWN0b3J5LiIiIgogICAgaWYgb3MucGF0aC5pc2RpcihwYXRoKToKICAgICAgICBpbml0ID0gb3MucGF0aC5qb2luKHBhdGgsICdfX2luaXRfXy5weScpCiAgICAgICAgaW5pdGMgPSBvcy5wYXRoLmpvaW4ocGF0aCwgJ19faW5pdF9fLnB5YycpCiAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUoaW5pdCkgb3Igb3MucGF0aC5pc2ZpbGUoaW5pdGMpOgogICAgICAgICAgICByZXR1cm4gMQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGZvcm1hdHRlciBiYXNlIGNsYXNzCgpjbGFzcyBEb2M6CiAgICBkZWYgZG9jdW1lbnQoc2VsZiwgb2JqZWN0LCAqYXJncyk6CiAgICAgICAgIiIiR2VuZXJhdGUgZG9jdW1lbnRhdGlvbiBmb3IgYW4gb2JqZWN0LiIiIgogICAgICAgIGFyZ3MgPSAob2JqZWN0LCkgKyBhcmdzCiAgICAgICAgaWYgaW5zcGVjdC5pc21vZHVsZShvYmplY3QpOiByZXR1cm4gYXBwbHkoc2VsZi5kb2Ntb2R1bGUsIGFyZ3MpCiAgICAgICAgaWYgaW5zcGVjdC5pc2NsYXNzKG9iamVjdCk6IHJldHVybiBhcHBseShzZWxmLmRvY2NsYXNzLCBhcmdzKQogICAgICAgIGlmIGluc3BlY3QuaXNtZXRob2Qob2JqZWN0KTogcmV0dXJuIGFwcGx5KHNlbGYuZG9jbWV0aG9kLCBhcmdzKQogICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKG9iamVjdCk6IHJldHVybiBhcHBseShzZWxmLmRvY2J1aWx0aW4sIGFyZ3MpCiAgICAgICAgaWYgaW5zcGVjdC5pc2Z1bmN0aW9uKG9iamVjdCk6IHJldHVybiBhcHBseShzZWxmLmRvY2Z1bmN0aW9uLCBhcmdzKQogICAgICAgIHJhaXNlIFR5cGVFcnJvciwgImRvbid0IGtub3cgaG93IHRvIGRvY3VtZW50IG9iamVjdHMgb2YgdHlwZSAiICsgXAogICAgICAgICAgICB0eXBlKG9iamVjdCkuX19uYW1lX18KCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSFRNTCBkb2N1bWVudGF0aW9uIGdlbmVyYXRvcgoKY2xhc3MgSFRNTFJlcHIoUmVwcik6CiAgICAiIiJDbGFzcyBmb3Igc2FmZWx5IG1ha2luZyBhbiBIVE1MIHJlcHJlc2VudGF0aW9uIG9mIGEgUHl0aG9uIG9iamVjdC4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBSZXByLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5tYXhsaXN0ID0gc2VsZi5tYXh0dXBsZSA9IHNlbGYubWF4ZGljdCA9IDEwCiAgICAgICAgc2VsZi5tYXhzdHJpbmcgPSBzZWxmLm1heG90aGVyID0gNTAKCiAgICBkZWYgZXNjYXBlKHNlbGYsIHRleHQpOgogICAgICAgIHJldHVybiByZXBsYWNlKHRleHQsICgnJicsICcmYW1wOycpLCAoJzwnLCAnJmx0OycpLCAoJz4nLCAnJmd0OycpKQoKICAgIGRlZiByZXByKHNlbGYsIG9iamVjdCk6CiAgICAgICAgcmVzdWx0ID0gUmVwci5yZXByKHNlbGYsIG9iamVjdCkKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIHJlcHIxKHNlbGYsIHgsIGxldmVsKToKICAgICAgICBtZXRob2RuYW1lID0gJ3JlcHJfJyArIGpvaW4oc3BsaXQodHlwZSh4KS5fX25hbWVfXyksICdfJykKICAgICAgICBpZiBoYXNhdHRyKHNlbGYsIG1ldGhvZG5hbWUpOgogICAgICAgICAgICByZXR1cm4gZ2V0YXR0cihzZWxmLCBtZXRob2RuYW1lKSh4LCBsZXZlbCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gc2VsZi5lc2NhcGUoY3JhbShjbGVhbmlkKHJlcHIoeCkpLCBzZWxmLm1heG90aGVyKSkKCiAgICBkZWYgcmVwcl9zdHJpbmcoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIHRleHQgPSBzZWxmLmVzY2FwZShjcmFtKHgsIHNlbGYubWF4c3RyaW5nKSkKICAgICAgICByZXR1cm4gcmUuc3ViKHInKChcXFtcXGFiZm5ydHZdfFxceC4ufFxcdS4uLi4pKyknLAogICAgICAgICAgICAgICAgICAgICAgcic8Zm9udCBjb2xvcj0iI2MwNDBjMCI+XDE8L2ZvbnQ+JywgcmVwcih0ZXh0KSkKCiAgICBkZWYgcmVwcl9pbnN0YW5jZShzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXR1cm4gY3JhbShjbGVhbmlkKHJlcHIoeCkpLCBzZWxmLm1heHN0cmluZykKICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmVzY2FwZSgnPCVzIGluc3RhbmNlPicgJSB4Ll9fY2xhc3NfXy5fX25hbWVfXykKCiAgICByZXByX3VuaWNvZGUgPSByZXByX3N0cmluZwoKY2xhc3MgSFRNTERvYyhEb2MpOgogICAgIiIiRm9ybWF0dGVyIGNsYXNzIGZvciBIVE1MIGRvY3VtZW50YXRpb24uIiIiCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEhUTUwgZm9ybWF0dGluZyB1dGlsaXRpZXMKCiAgICBfcmVwcl9pbnN0YW5jZSA9IEhUTUxSZXByKCkKICAgIHJlcHIgPSBfcmVwcl9pbnN0YW5jZS5yZXByCiAgICBlc2NhcGUgPSBfcmVwcl9pbnN0YW5jZS5lc2NhcGUKCiAgICBkZWYgcHJlZm9ybWF0KHNlbGYsIHRleHQpOgogICAgICAgICIiIkZvcm1hdCBsaXRlcmFsIHByZWZvcm1hdHRlZCB0ZXh0LiIiIgogICAgICAgIHRleHQgPSBzZWxmLmVzY2FwZShleHBhbmR0YWJzKHRleHQpKQogICAgICAgIHJldHVybiByZXBsYWNlKHRleHQsICgnXG5cbicsICdcbiBcbicpLCAoJ1xuXG4nLCAnXG4gXG4nKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJyAnLCAnJm5ic3A7JyksICgnXG4nLCAnPGJyPlxuJykpCgogICAgZGVmIG11bHRpY29sdW1uKHNlbGYsIGxpc3QsIGZvcm1hdCwgY29scz00KToKICAgICAgICAiIiJGb3JtYXQgYSBsaXN0IG9mIGl0ZW1zIGludG8gYSBtdWx0aS1jb2x1bW4gbGlzdC4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIHJvd3MgPSAobGVuKGxpc3QpK2NvbHMtMSkvY29scwoKICAgICAgICBmb3IgY29sIGluIHJhbmdlKGNvbHMpOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPHRkIHdpZHRoPSIlZCUlIiB2YWxpZ249dG9wPicgJSAoMTAwL2NvbHMpCiAgICAgICAgICAgIGZvciBpIGluIHJhbmdlKHJvd3MqY29sLCByb3dzKmNvbCtyb3dzKToKICAgICAgICAgICAgICAgIGlmIGkgPCBsZW4obGlzdCk6CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgZm9ybWF0KGxpc3RbaV0pICsgJzxicj4nCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8L3RkPicKICAgICAgICByZXR1cm4gJzx0YWJsZSB3aWR0aD0iMTAwJSUiPjx0cj4lczwvdHI+PC90YWJsZT4nICUgcmVzdWx0CgogICAgZGVmIGhlYWRpbmcoc2VsZiwgdGl0bGUsIGZnY29sLCBiZ2NvbCwgZXh0cmFzPScnKToKICAgICAgICAiIiJGb3JtYXQgYSBwYWdlIGhlYWRpbmcuIiIiCiAgICAgICAgcmV0dXJuICIiIgo8cD48dGFibGUgd2lkdGg9IjEwMCUlIiBjZWxsc3BhY2luZz0wIGNlbGxwYWRkaW5nPTAgYm9yZGVyPTA+Cjx0ciBiZ2NvbG9yPSIlcyI+PHRkIGNvbHNwYW49MyB2YWxpZ249Ym90dG9tPjxzbWFsbD48c21hbGw+PGJyPjwvc21hbGw+PC9zbWFsbAo+PGZvbnQgY29sb3I9IiVzIiBmYWNlPSJoZWx2ZXRpY2EsIGFyaWFsIj4mbmJzcDslczwvZm9udD48L3RkCj48dGQgYWxpZ249cmlnaHQgdmFsaWduPWJvdHRvbQo+PGZvbnQgY29sb3I9IiVzIiBmYWNlPSJoZWx2ZXRpY2EsIGFyaWFsIj4mbmJzcDslczwvZm9udD48L3RkPjwvdHI+PC90YWJsZT4KICAgICIiIiAlIChiZ2NvbCwgZmdjb2wsIHRpdGxlLCBmZ2NvbCwgZXh0cmFzKQoKICAgIGRlZiBzZWN0aW9uKHNlbGYsIHRpdGxlLCBmZ2NvbCwgYmdjb2wsIGNvbnRlbnRzLCB3aWR0aD0yMCwKICAgICAgICAgICAgICAgIHByZWx1ZGU9JycsIG1hcmdpbmFsaWE9Tm9uZSwgZ2FwPScmbmJzcDsmbmJzcDsmbmJzcDsnKToKICAgICAgICAiIiJGb3JtYXQgYSBzZWN0aW9uIHdpdGggYSBoZWFkaW5nLiIiIgogICAgICAgIGlmIG1hcmdpbmFsaWEgaXMgTm9uZToKICAgICAgICAgICAgbWFyZ2luYWxpYSA9ICcmbmJzcDsnICogd2lkdGgKICAgICAgICByZXN1bHQgPSAiIiIKPHA+PHRhYmxlIHdpZHRoPSIxMDAlJSIgY2VsbHNwYWNpbmc9MCBjZWxscGFkZGluZz0wIGJvcmRlcj0wPgo8dHIgYmdjb2xvcj0iJXMiPjx0ZCBjb2xzcGFuPTMgdmFsaWduPWJvdHRvbT48c21hbGw+PHNtYWxsPjxicj48L3NtYWxsPjwvc21hbGwKPjxmb250IGNvbG9yPSIlcyIgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+Jm5ic3A7JXM8L2ZvbnQ+PC90ZD48L3RyPgogICAgIiIiICUgKGJnY29sLCBmZ2NvbCwgdGl0bGUpCiAgICAgICAgaWYgcHJlbHVkZToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgIiIiCjx0cj48dGQgYmdjb2xvcj0iJXMiPiVzPC90ZD4KPHRkIGJnY29sb3I9IiVzIiBjb2xzcGFuPTI+JXM8L3RkPjwvdHI+CiAgICAiIiIgJSAoYmdjb2wsIG1hcmdpbmFsaWEsIGJnY29sLCBwcmVsdWRlKQogICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICIiIgo8dHI+PHRkIGJnY29sb3I9IiVzIj4lczwvdGQ+PHRkPiVzPC90ZD4KICAgICIiIiAlIChiZ2NvbCwgbWFyZ2luYWxpYSwgZ2FwKQoKICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPHRkIHdpZHRoPSIxMDAlJSI+JXM8L3RkPjwvdHI+PC90YWJsZT4nICUgY29udGVudHMKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIGJpZ3NlY3Rpb24oc2VsZiwgdGl0bGUsICphcmdzKToKICAgICAgICAiIiJGb3JtYXQgYSBzZWN0aW9uIHdpdGggYSBiaWcgaGVhZGluZy4iIiIKICAgICAgICB0aXRsZSA9ICc8YmlnPjxzdHJvbmc+JXM8L3N0cm9uZz48L2JpZz4nICUgdGl0bGUKICAgICAgICByZXR1cm4gYXBwbHkoc2VsZi5zZWN0aW9uLCAodGl0bGUsKSArIGFyZ3MpCgogICAgZGVmIGZvb3RlcihzZWxmKToKICAgICAgICByZXR1cm4gIiIiCjx0YWJsZSB3aWR0aD0iMTAwJSI+PHRyPjx0ZCBhbGlnbj1yaWdodD4KPGZvbnQgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+PHNtYWxsPjxzbWFsbD5nZW5lcmF0ZWQgd2l0aAo8c3Ryb25nPmh0bWxkb2M8L3N0cm9uZz4gYnkgS2EtUGluZyBZZWU8L2E+PC9zbWFsbD48L3NtYWxsPjwvZm9udD4KPC90ZD48L3RyPjwvdGFibGU+CiAgICAiIiIKCiAgICBkZWYgbmFtZWxpbmsoc2VsZiwgbmFtZSwgKmRpY3RzKToKICAgICAgICAiIiJNYWtlIGEgbGluayBmb3IgYW4gaWRlbnRpZmllciwgZ2l2ZW4gbmFtZS10by1VUkwgbWFwcGluZ3MuIiIiCiAgICAgICAgZm9yIGRpY3QgaW4gZGljdHM6CiAgICAgICAgICAgIGlmIGRpY3QuaGFzX2tleShuYW1lKToKICAgICAgICAgICAgICAgIHJldHVybiAnPGEgaHJlZj0iJXMiPiVzPC9hPicgJSAoZGljdFtuYW1lXSwgbmFtZSkKICAgICAgICByZXR1cm4gbmFtZQoKICAgIGRlZiBjbGFzc2xpbmsoc2VsZiwgb2JqZWN0LCBtb2RuYW1lLCAqZGljdHMpOgogICAgICAgICIiIk1ha2UgYSBsaW5rIGZvciBhIGNsYXNzLiIiIgogICAgICAgIG5hbWUgPSBvYmplY3QuX19uYW1lX18KICAgICAgICBpZiBvYmplY3QuX19tb2R1bGVfXyAhPSBtb2RuYW1lOgogICAgICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbW9kdWxlX18gKyAnLicgKyBuYW1lCiAgICAgICAgZm9yIGRpY3QgaW4gZGljdHM6CiAgICAgICAgICAgIGlmIGRpY3QuaGFzX2tleShvYmplY3QpOgogICAgICAgICAgICAgICAgcmV0dXJuICc8YSBocmVmPSIlcyI+JXM8L2E+JyAlIChkaWN0W29iamVjdF0sIG5hbWUpCiAgICAgICAgcmV0dXJuIG5hbWUKCiAgICBkZWYgbW9kdWxlbGluayhzZWxmLCBvYmplY3QpOgogICAgICAgICIiIk1ha2UgYSBsaW5rIGZvciBhIG1vZHVsZS4iIiIKICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzLmh0bWwiPiVzPC9hPicgJSAob2JqZWN0Ll9fbmFtZV9fLCBvYmplY3QuX19uYW1lX18pCgogICAgZGVmIG1vZHBrZ2xpbmsoc2VsZiwgKG5hbWUsIHBhdGgsIGlzcGFja2FnZSwgc2hhZG93ZWQpKToKICAgICAgICAiIiJNYWtlIGEgbGluayBmb3IgYSBtb2R1bGUgb3IgcGFja2FnZSB0byBkaXNwbGF5IGluIGFuIGluZGV4LiIiIgogICAgICAgIGlmIHNoYWRvd2VkOgogICAgICAgICAgICByZXR1cm4gJzxmb250IGNvbG9yPSIjOTA5MDkwIj4lczwvZm9udD4nICUgbmFtZQogICAgICAgIGlmIHBhdGg6CiAgICAgICAgICAgIHVybCA9ICclcy4lcy5odG1sJyAlIChwYXRoLCBuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHVybCA9ICclcy5odG1sJyAlIG5hbWUKICAgICAgICBpZiBpc3BhY2thZ2U6CiAgICAgICAgICAgIHRleHQgPSAnPHN0cm9uZz4lczwvc3Ryb25nPiZuYnNwOyhwYWNrYWdlKScgJSBuYW1lCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGV4dCA9IG5hbWUKICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKHVybCwgdGV4dCkKCiAgICBkZWYgbWFya3VwKHNlbGYsIHRleHQsIGVzY2FwZT1Ob25lLCBmdW5jcz17fSwgY2xhc3Nlcz17fSwgbWV0aG9kcz17fSk6CiAgICAgICAgIiIiTWFyayB1cCBzb21lIHBsYWluIHRleHQsIGdpdmVuIGEgY29udGV4dCBvZiBzeW1ib2xzIHRvIGxvb2sgZm9yLgogICAgICAgIEVhY2ggY29udGV4dCBkaWN0aW9uYXJ5IG1hcHMgb2JqZWN0IG5hbWVzIHRvIGFuY2hvciBuYW1lcy4iIiIKICAgICAgICBlc2NhcGUgPSBlc2NhcGUgb3Igc2VsZi5lc2NhcGUKICAgICAgICByZXN1bHRzID0gW10KICAgICAgICBoZXJlID0gMAogICAgICAgIHBhdHRlcm4gPSByZS5jb21waWxlKHInXGIoKChodHRwfGZ0cCk6Ly9cUytbXHcvXSl8JwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHInKFJGQ1stIF0/KFxkKykpfCcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByJyhzZWxmXC4pPyhcdyspKVxiJykKICAgICAgICB3aGlsZSAxOgogICAgICAgICAgICBtYXRjaCA9IHBhdHRlcm4uc2VhcmNoKHRleHQsIGhlcmUpCiAgICAgICAgICAgIGlmIG5vdCBtYXRjaDogYnJlYWsKICAgICAgICAgICAgc3RhcnQsIGVuZCA9IG1hdGNoLnNwYW4oKQogICAgICAgICAgICByZXN1bHRzLmFwcGVuZChlc2NhcGUodGV4dFtoZXJlOnN0YXJ0XSkpCgogICAgICAgICAgICBhbGwsIHVybCwgc2NoZW1lLCByZmMsIHJmY251bSwgc2VsZmRvdCwgbmFtZSA9IG1hdGNoLmdyb3VwcygpCiAgICAgICAgICAgIGlmIHVybDoKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCc8YSBocmVmPSIlcyI+JXM8L2E+JyAlICh1cmwsIGVzY2FwZSh1cmwpKSkKICAgICAgICAgICAgZWxpZiByZmM6CiAgICAgICAgICAgICAgICB1cmwgPSAnaHR0cDovL3d3dy5yZmMtZWRpdG9yLm9yZy9yZmMvcmZjJXMudHh0JyAlIHJmY251bQogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKHVybCwgZXNjYXBlKHJmYykpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgdGV4dFtlbmQ6ZW5kKzFdID09ICcoJzoKICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZChzZWxmLm5hbWVsaW5rKG5hbWUsIG1ldGhvZHMsIGZ1bmNzLCBjbGFzc2VzKSkKICAgICAgICAgICAgICAgIGVsaWYgc2VsZmRvdDoKICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgnc2VsZi48c3Ryb25nPiVzPC9zdHJvbmc+JyAlIG5hbWUpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKHNlbGYubmFtZWxpbmsobmFtZSwgY2xhc3NlcykpCiAgICAgICAgICAgIGhlcmUgPSBlbmQKICAgICAgICByZXN1bHRzLmFwcGVuZChlc2NhcGUodGV4dFtoZXJlOl0pKQogICAgICAgIHJldHVybiBqb2luKHJlc3VsdHMsICcnKQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlLXNwZWNpZmljIHJvdXRpbmVzCgogICAgZGVmIGRvY3RyZWUoc2VsZiwgdHJlZSwgbW9kbmFtZSwgY2xhc3Nlcz17fSwgcGFyZW50PU5vbmUpOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBmb3IgYSBjbGFzcyB0cmVlIGFzIGdpdmVuIGJ5IGluc3BlY3QuZ2V0Y2xhc3N0cmVlKCkuIiIiCiAgICAgICAgcmVzdWx0ID0gJycKICAgICAgICBmb3IgZW50cnkgaW4gdHJlZToKICAgICAgICAgICAgaWYgdHlwZShlbnRyeSkgaXMgdHlwZSgoKSk6CiAgICAgICAgICAgICAgICBjLCBiYXNlcyA9IGVudHJ5CiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPGR0Pjxmb250IGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPjxzbWFsbD4nCiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmNsYXNzbGluayhjLCBtb2RuYW1lLCBjbGFzc2VzKQogICAgICAgICAgICAgICAgaWYgYmFzZXMgYW5kIGJhc2VzICE9IChwYXJlbnQsKToKICAgICAgICAgICAgICAgICAgICBwYXJlbnRzID0gW10KICAgICAgICAgICAgICAgICAgICBmb3IgYmFzZSBpbiBiYXNlczoKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50cy5hcHBlbmQoc2VsZi5jbGFzc2xpbmsoYmFzZSwgbW9kbmFtZSwgY2xhc3NlcykpCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJygnICsgam9pbihwYXJlbnRzLCAnLCAnKSArICcpJwogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJ1xuPC9zbWFsbD48L2ZvbnQ+PC9kdD4nCiAgICAgICAgICAgIGVsaWYgdHlwZShlbnRyeSkgaXMgdHlwZShbXSk6CiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBcCiAgICAgICAgICAgICAgICAgICAgJzxkZD5cbiVzPC9kZD5cbicgJSBzZWxmLmRvY3RyZWUoZW50cnksIG1vZG5hbWUsIGNsYXNzZXMsIGMpCiAgICAgICAgcmV0dXJuICc8ZGw+XG4lczwvZGw+XG4nICUgcmVzdWx0CgogICAgZGVmIGRvY21vZHVsZShzZWxmLCBvYmplY3QpOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIG1vZHVsZSBvYmplY3QuIiIiCiAgICAgICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIHJlc3VsdCA9ICcnCiAgICAgICAgaGVhZCA9ICc8YnI+PGJpZz48YmlnPjxzdHJvbmc+Jm5ic3A7JXM8L3N0cm9uZz48L2JpZz48L2JpZz4nICUgbmFtZQogICAgICAgIHRyeToKICAgICAgICAgICAgZmlsZSA9IGluc3BlY3QuZ2V0c291cmNlZmlsZShvYmplY3QpCiAgICAgICAgICAgIGZpbGVsaW5rID0gJzxhIGhyZWY9ImZpbGU6JXMiPiVzPC9hPicgJSAoZmlsZSwgZmlsZSkKICAgICAgICBleGNlcHQgVHlwZUVycm9yOgogICAgICAgICAgICBmaWxlbGluayA9ICcoYnVpbHQtaW4pJwogICAgICAgIGluZm8gPSBbXQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX192ZXJzaW9uX18nKToKICAgICAgICAgICAgdmVyc2lvbiA9IHN0cihvYmplY3QuX192ZXJzaW9uX18pCiAgICAgICAgICAgIGlmIHZlcnNpb25bOjExXSA9PSAnJCcgKyAnUmV2aXNpb246ICcgYW5kIHZlcnNpb25bLTE6XSA9PSAnJCc6CiAgICAgICAgICAgICAgICB2ZXJzaW9uID0gc3RyaXAodmVyc2lvblsxMTotMV0pCiAgICAgICAgICAgIGluZm8uYXBwZW5kKCd2ZXJzaW9uOiAlcycgJSBzZWxmLmVzY2FwZSh2ZXJzaW9uKSkKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fZGF0ZV9fJyk6CiAgICAgICAgICAgIGluZm8uYXBwZW5kKHNlbGYuZXNjYXBlKHN0cihvYmplY3QuX19kYXRlX18pKSkKICAgICAgICBpZiBpbmZvOgogICAgICAgICAgICBoZWFkID0gaGVhZCArICcgKCVzKScgJSBqb2luKGluZm8sICcsICcpCiAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5oZWFkaW5nKAogICAgICAgICAgICBoZWFkLCAnI2ZmZmZmZicsICcjNzc5OWVlJywgJzxhIGhyZWY9Ii4iPmluZGV4PC9hPjxicj4nICsgZmlsZWxpbmspCgogICAgICAgIHNlY29uZCA9IGxhbWJkYSBsaXN0OiBsaXN0WzFdCiAgICAgICAgbW9kdWxlcyA9IG1hcChzZWNvbmQsIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNtb2R1bGUpKQoKICAgICAgICBjbGFzc2VzLCBjZGljdCA9IFtdLCB7fQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNjbGFzcyk6CiAgICAgICAgICAgIGlmIChpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgb3Igb2JqZWN0KSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBjbGFzc2VzLmFwcGVuZCh2YWx1ZSkKICAgICAgICAgICAgICAgIGNkaWN0W2tleV0gPSBjZGljdFt2YWx1ZV0gPSAnIycgKyBrZXkKICAgICAgICBmdW5jcywgZmRpY3QgPSBbXSwge30KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0Lmlzcm91dGluZSk6CiAgICAgICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKHZhbHVlKSBvciBpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgaXMgb2JqZWN0OgogICAgICAgICAgICAgICAgZnVuY3MuYXBwZW5kKHZhbHVlKQogICAgICAgICAgICAgICAgZmRpY3Rba2V5XSA9ICcjLScgKyBrZXkKICAgICAgICAgICAgICAgIGlmIGluc3BlY3QuaXNmdW5jdGlvbih2YWx1ZSk6IGZkaWN0W3ZhbHVlXSA9IGZkaWN0W2tleV0KICAgICAgICBmb3IgYyBpbiBjbGFzc2VzOgogICAgICAgICAgICBmb3IgYmFzZSBpbiBjLl9fYmFzZXNfXzoKICAgICAgICAgICAgICAgIGtleSwgbW9kbmFtZSA9IGJhc2UuX19uYW1lX18sIGJhc2UuX19tb2R1bGVfXwogICAgICAgICAgICAgICAgaWYgbW9kbmFtZSAhPSBuYW1lIGFuZCBzeXMubW9kdWxlcy5oYXNfa2V5KG1vZG5hbWUpOgogICAgICAgICAgICAgICAgICAgIG1vZHVsZSA9IHN5cy5tb2R1bGVzW21vZG5hbWVdCiAgICAgICAgICAgICAgICAgICAgaWYgaGFzYXR0cihtb2R1bGUsIGtleSkgYW5kIGdldGF0dHIobW9kdWxlLCBrZXkpIGlzIGJhc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5vdCBjZGljdC5oYXNfa2V5KGtleSk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZGljdFtrZXldID0gY2RpY3RbYmFzZV0gPSBtb2RuYW1lICsgJy5odG1sIycgKyBrZXkKICAgICAgICBjb25zdGFudHMgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGlzY29uc3RhbnQpOgogICAgICAgICAgICBpZiBrZXlbOjFdICE9ICdfJzoKICAgICAgICAgICAgICAgIGNvbnN0YW50cy5hcHBlbmQoKGtleSwgdmFsdWUpKQoKICAgICAgICBkb2MgPSBzZWxmLm1hcmt1cChnZXRkb2Mob2JqZWN0KSwgc2VsZi5wcmVmb3JtYXQsIGZkaWN0LCBjZGljdCkKICAgICAgICBkb2MgPSBkb2MgYW5kICc8dHQ+JXM8L3R0PicgJSBkb2MKICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPHA+PHNtYWxsPiVzPC9zbWFsbD48L3A+XG4nICUgZG9jCgogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19wYXRoX18nKToKICAgICAgICAgICAgbW9kcGtncyA9IFtdCiAgICAgICAgICAgIG1vZG5hbWVzID0gW10KICAgICAgICAgICAgZm9yIGZpbGUgaW4gb3MubGlzdGRpcihvYmplY3QuX19wYXRoX19bMF0pOgogICAgICAgICAgICAgICAgaWYgZmlsZVs6MV0gIT0gJ18nOgogICAgICAgICAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4ob2JqZWN0Ll9fcGF0aF9fWzBdLCBmaWxlKQogICAgICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBtb2R1bGVuYW1lKGZpbGUpCiAgICAgICAgICAgICAgICAgICAgaWYgbW9kbmFtZSBhbmQgbW9kbmFtZSBub3QgaW4gbW9kbmFtZXM6CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKChtb2RuYW1lLCBuYW1lLCAwLCAwKSkKICAgICAgICAgICAgICAgICAgICAgICAgbW9kbmFtZXMuYXBwZW5kKG1vZG5hbWUpCiAgICAgICAgICAgICAgICAgICAgZWxpZiBpc3BhY2thZ2UocGF0aCk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2Rwa2dzLmFwcGVuZCgoZmlsZSwgbmFtZSwgMSwgMCkpCiAgICAgICAgICAgIG1vZHBrZ3Muc29ydCgpCiAgICAgICAgICAgIGNvbnRlbnRzID0gc2VsZi5tdWx0aWNvbHVtbihtb2Rwa2dzLCBzZWxmLm1vZHBrZ2xpbmspCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdQYWNrYWdlIENvbnRlbnRzJywgJyNmZmZmZmYnLCAnI2FhNTVjYycsIGNvbnRlbnRzKQoKICAgICAgICBlbGlmIG1vZHVsZXM6CiAgICAgICAgICAgIGNvbnRlbnRzID0gc2VsZi5tdWx0aWNvbHVtbihtb2R1bGVzLCBzZWxmLm1vZHVsZWxpbmspCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdNb2R1bGVzJywgJyNmZmZmZicsICcjYWE1NWNjJywgY29udGVudHMpCgogICAgICAgIGlmIGNsYXNzZXM6CiAgICAgICAgICAgIGNvbnRlbnRzID0gc2VsZi5kb2N0cmVlKAogICAgICAgICAgICAgICAgaW5zcGVjdC5nZXRjbGFzc3RyZWUoY2xhc3NlcywgMSksIG5hbWUsIGNkaWN0KQogICAgICAgICAgICBmb3IgaXRlbSBpbiBjbGFzc2VzOgogICAgICAgICAgICAgICAgY29udGVudHMgPSBjb250ZW50cyArIHNlbGYuZG9jdW1lbnQoaXRlbSwgZmRpY3QsIGNkaWN0KQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnQ2xhc3NlcycsICcjZmZmZmZmJywgJyNlZTc3YWEnLCBjb250ZW50cykKICAgICAgICBpZiBmdW5jczoKICAgICAgICAgICAgY29udGVudHMgPSAnJwogICAgICAgICAgICBmb3IgaXRlbSBpbiBmdW5jczoKICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gY29udGVudHMgKyBzZWxmLmRvY3VtZW50KGl0ZW0sIGZkaWN0LCBjZGljdCkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0Z1bmN0aW9ucycsICcjZmZmZmZmJywgJyNlZWFhNzcnLCBjb250ZW50cykKCiAgICAgICAgaWYgY29uc3RhbnRzOgogICAgICAgICAgICBjb250ZW50cyA9ICcnCiAgICAgICAgICAgIGZvciBrZXksIHZhbHVlIGluIGNvbnN0YW50czoKICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gY29udGVudHMgKyAoJzxicj48c3Ryb25nPiVzPC9zdHJvbmc+ID0gJXMnICUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleSwgc2VsZi5yZXByKHZhbHVlKSkpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdDb25zdGFudHMnLCAnI2ZmZmZmZicsICcjNTVhYTU1JywgY29udGVudHMpCgogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19hdXRob3JfXycpOgogICAgICAgICAgICBjb250ZW50cyA9IHNlbGYubWFya3VwKHN0cihvYmplY3QuX19hdXRob3JfXyksIHNlbGYucHJlZm9ybWF0KQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnQXV0aG9yJywgJyNmZmZmZmYnLCAnIzc3OTllZScsIGNvbnRlbnRzKQoKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fY3JlZGl0c19fJyk6CiAgICAgICAgICAgIGNvbnRlbnRzID0gc2VsZi5tYXJrdXAoc3RyKG9iamVjdC5fX2NyZWRpdHNfXyksIHNlbGYucHJlZm9ybWF0KQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnQ3JlZGl0cycsICcjZmZmZmZmJywgJyM3Nzk5ZWUnLCBjb250ZW50cykKCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBkb2NjbGFzcyhzZWxmLCBvYmplY3QsIGZ1bmNzPXt9LCBjbGFzc2VzPXt9KToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBjbGFzcyBvYmplY3QuIiIiCiAgICAgICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIGJhc2VzID0gb2JqZWN0Ll9fYmFzZXNfXwogICAgICAgIGNvbnRlbnRzID0gJycKCiAgICAgICAgbWV0aG9kcywgbWRpY3QgPSBbXSwge30KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0LmlzbWV0aG9kKToKICAgICAgICAgICAgbWV0aG9kcy5hcHBlbmQodmFsdWUpCiAgICAgICAgICAgIG1kaWN0W2tleV0gPSBtZGljdFt2YWx1ZV0gPSAnIycgKyBuYW1lICsgJy0nICsga2V5CiAgICAgICAgZm9yIGl0ZW0gaW4gbWV0aG9kczoKICAgICAgICAgICAgY29udGVudHMgPSBjb250ZW50cyArIHNlbGYuZG9jdW1lbnQoCiAgICAgICAgICAgICAgICBpdGVtLCBmdW5jcywgY2xhc3NlcywgbWRpY3QsIG5hbWUpCgogICAgICAgIHRpdGxlID0gJzxhIG5hbWU9IiVzIj5jbGFzcyA8c3Ryb25nPiVzPC9zdHJvbmc+PC9hPicgJSAobmFtZSwgbmFtZSkKICAgICAgICBpZiBiYXNlczoKICAgICAgICAgICAgcGFyZW50cyA9IFtdCiAgICAgICAgICAgIGZvciBiYXNlIGluIGJhc2VzOgogICAgICAgICAgICAgICAgcGFyZW50cy5hcHBlbmQoc2VsZi5jbGFzc2xpbmsoYmFzZSwgb2JqZWN0Ll9fbW9kdWxlX18sIGNsYXNzZXMpKQogICAgICAgICAgICB0aXRsZSA9IHRpdGxlICsgJyglcyknICUgam9pbihwYXJlbnRzLCAnLCAnKQogICAgICAgIGRvYyA9IHNlbGYubWFya3VwKGdldGRvYyhvYmplY3QpLCBzZWxmLnByZWZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jcywgY2xhc3NlcywgbWRpY3QpCiAgICAgICAgaWYgZG9jOiBkb2MgPSAnPHNtYWxsPjx0dD4nICsgZG9jICsgJzxicj4mbmJzcDs8L3R0Pjwvc21hbGw+JwogICAgICAgIHJldHVybiBzZWxmLnNlY3Rpb24odGl0bGUsICcjMDAwMDAwJywgJyNmZmM4ZDgnLCBjb250ZW50cywgMTAsIGRvYykKCiAgICBkZWYgZG9jbWV0aG9kKHNlbGYsIG9iamVjdCwgZnVuY3M9e30sIGNsYXNzZXM9e30sIG1ldGhvZHM9e30sIGNsbmFtZT0nJyk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGEgbWV0aG9kIG9iamVjdC4iIiIKICAgICAgICByZXR1cm4gc2VsZi5kb2N1bWVudCgKICAgICAgICAgICAgb2JqZWN0LmltX2Z1bmMsIGZ1bmNzLCBjbGFzc2VzLCBtZXRob2RzLCBjbG5hbWUpCgogICAgZGVmIGZvcm1hdHZhbHVlKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiRm9ybWF0IGFuIGFyZ3VtZW50IGRlZmF1bHQgdmFsdWUgYXMgdGV4dC4iIiIKICAgICAgICByZXR1cm4gKCc8c21hbGw+PGZvbnQgY29sb3I9IiM5MDkwOTAiPj0lczwvZm9udD48L3NtYWxsPicgJQogICAgICAgICAgICAgICAgc2VsZi5yZXByKG9iamVjdCkpCgogICAgZGVmIGRvY2Z1bmN0aW9uKHNlbGYsIG9iamVjdCwgZnVuY3M9e30sIGNsYXNzZXM9e30sIG1ldGhvZHM9e30sIGNsbmFtZT0nJyk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGEgZnVuY3Rpb24gb2JqZWN0LiIiIgogICAgICAgIGFyZ3MsIHZhcmFyZ3MsIHZhcmt3LCBkZWZhdWx0cyA9IGluc3BlY3QuZ2V0YXJnc3BlYyhvYmplY3QpCiAgICAgICAgYXJnc3BlYyA9IGluc3BlY3QuZm9ybWF0YXJnc3BlYygKICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzLCBmb3JtYXR2YWx1ZT1zZWxmLmZvcm1hdHZhbHVlKQoKICAgICAgICBpZiBvYmplY3QuX19uYW1lX18gPT0gJzxsYW1iZGE+JzoKICAgICAgICAgICAgZGVjbCA9ICc8ZW0+bGFtYmRhPC9lbT4gJyArIGFyZ3NwZWNbMTotMV0KICAgICAgICBlbHNlOgogICAgICAgICAgICBhbmNob3IgPSBjbG5hbWUgKyAnLScgKyBvYmplY3QuX19uYW1lX18KICAgICAgICAgICAgZGVjbCA9ICc8YSBuYW1lPSIlcyJcbj48c3Ryb25nPiVzPC9zdHJvbmc+JXM8L2E+XG4nICUgKAogICAgICAgICAgICAgICAgYW5jaG9yLCBvYmplY3QuX19uYW1lX18sIGFyZ3NwZWMpCiAgICAgICAgZG9jID0gc2VsZi5tYXJrdXAoZ2V0ZG9jKG9iamVjdCksIHNlbGYucHJlZm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmNzLCBjbGFzc2VzLCBtZXRob2RzKQogICAgICAgIGRvYyA9IHJlcGxhY2UoZG9jLCAoJzxicj5cbicsICc8L3R0Pjwvc21hbGxcbj48ZGQ+PHNtYWxsPjx0dD4nKSkKICAgICAgICBkb2MgPSBkb2MgYW5kICc8dHQ+JXM8L3R0PicgJSBkb2MKICAgICAgICByZXR1cm4gJzxkbD48ZHQ+JXM8ZGQ+PHNtYWxsPiVzPC9zbWFsbD48L2RsPicgJSAoZGVjbCwgZG9jKQoKICAgIGRlZiBkb2NidWlsdGluKHNlbGYsIG9iamVjdCwgKmV4dHJhcyk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGEgYnVpbHQtaW4gZnVuY3Rpb24uIiIiCiAgICAgICAgcmV0dXJuICc8ZGw+PGR0PjxzdHJvbmc+JXM8L3N0cm9uZz4oLi4uKTwvZGw+JyAlIG9iamVjdC5fX25hbWVfXwoKICAgIGRlZiBwYWdlKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiUHJvZHVjZSBhIGNvbXBsZXRlIEhUTUwgcGFnZSBvZiBkb2N1bWVudGF0aW9uIGZvciBhbiBvYmplY3QuIiIiCiAgICAgICAgcmV0dXJuICcnJzwhZG9jdHlwZSBodG1sIHB1YmxpYyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAgVHJhbnNpdGlvbmFsLy9FTiI+CjxodG1sPjx0aXRsZT5QeXRob246ICVzPC90aXRsZT4KPGJvZHkgYmdjb2xvcj0iI2ZmZmZmZiI+CiVzCjwvYm9keT48L2h0bWw+CicnJyAlIChkZXNjcmliZShvYmplY3QpLCBzZWxmLmRvY3VtZW50KG9iamVjdCkpCgogICAgZGVmIGluZGV4KHNlbGYsIGRpciwgc2hhZG93ZWQ9Tm9uZSk6CiAgICAgICAgIiIiR2VuZXJhdGUgYW4gSFRNTCBpbmRleCBmb3IgYSBkaXJlY3Rvcnkgb2YgbW9kdWxlcy4iIiIKICAgICAgICBtb2Rwa2dzID0gW10KICAgICAgICBpZiBzaGFkb3dlZCBpcyBOb25lOiBzaGFkb3dlZCA9IHt9CiAgICAgICAgc2VlbiA9IHt9CiAgICAgICAgZmlsZXMgPSBvcy5saXN0ZGlyKGRpcikKCiAgICAgICAgZGVmIGZvdW5kKG5hbWUsIGlzcGFja2FnZSwKICAgICAgICAgICAgICAgICAgbW9kcGtncz1tb2Rwa2dzLCBzaGFkb3dlZD1zaGFkb3dlZCwgc2Vlbj1zZWVuKToKICAgICAgICAgICAgaWYgbm90IHNlZW4uaGFzX2tleShuYW1lKToKICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKChuYW1lLCAnJywgaXNwYWNrYWdlLCBzaGFkb3dlZC5oYXNfa2V5KG5hbWUpKSkKICAgICAgICAgICAgICAgIHNlZW5bbmFtZV0gPSAxCiAgICAgICAgICAgICAgICBzaGFkb3dlZFtuYW1lXSA9IDEKCiAgICAgICAgIyBQYWNrYWdlIHNwYW0vX19pbml0X18ucHkgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIG1vZHVsZSBzcGFtLnB5LgogICAgICAgIGZvciBmaWxlIGluIGZpbGVzOgogICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKGRpciwgZmlsZSkKICAgICAgICAgICAgaWYgaXNwYWNrYWdlKHBhdGgpOiBmb3VuZChmaWxlLCAxKQogICAgICAgIGZvciBmaWxlIGluIGZpbGVzOgogICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKGRpciwgZmlsZSkKICAgICAgICAgICAgaWYgZmlsZVs6MV0gIT0gJ18nIGFuZCBvcy5wYXRoLmlzZmlsZShwYXRoKTogCiAgICAgICAgICAgICAgICBtb2RuYW1lID0gbW9kdWxlbmFtZShmaWxlKQogICAgICAgICAgICAgICAgaWYgbW9kbmFtZTogZm91bmQobW9kbmFtZSwgMCkKCiAgICAgICAgbW9kcGtncy5zb3J0KCkKICAgICAgICBjb250ZW50cyA9IHNlbGYubXVsdGljb2x1bW4obW9kcGtncywgc2VsZi5tb2Rwa2dsaW5rKQogICAgICAgIHJldHVybiBzZWxmLmJpZ3NlY3Rpb24oZGlyLCAnI2ZmZmZmZicsICcjZWU3N2FhJywgY29udGVudHMpCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHRleHQgZG9jdW1lbnRhdGlvbiBnZW5lcmF0b3IKCmNsYXNzIFRleHRSZXByKFJlcHIpOgogICAgIiIiQ2xhc3MgZm9yIHNhZmVseSBtYWtpbmcgYSB0ZXh0IHJlcHJlc2VudGF0aW9uIG9mIGEgUHl0aG9uIG9iamVjdC4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBSZXByLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5tYXhsaXN0ID0gc2VsZi5tYXh0dXBsZSA9IHNlbGYubWF4ZGljdCA9IDEwCiAgICAgICAgc2VsZi5tYXhzdHJpbmcgPSBzZWxmLm1heG90aGVyID0gNTAKCiAgICBkZWYgcmVwcjEoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIG1ldGhvZG5hbWUgPSAncmVwcl8nICsgam9pbihzcGxpdCh0eXBlKHgpLl9fbmFtZV9fKSwgJ18nKQogICAgICAgIGlmIGhhc2F0dHIoc2VsZiwgbWV0aG9kbmFtZSk6CiAgICAgICAgICAgIHJldHVybiBnZXRhdHRyKHNlbGYsIG1ldGhvZG5hbWUpKHgsIGxldmVsKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBjcmFtKGNsZWFuaWQocmVwcih4KSksIHNlbGYubWF4b3RoZXIpCgogICAgZGVmIHJlcHJfaW5zdGFuY2Uoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIHRyeToKICAgICAgICAgICAgcmV0dXJuIGNyYW0oY2xlYW5pZChyZXByKHgpKSwgc2VsZi5tYXhzdHJpbmcpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICByZXR1cm4gJzwlcyBpbnN0YW5jZT4nICUgeC5fX2NsYXNzX18uX19uYW1lX18KCmNsYXNzIFRleHREb2MoRG9jKToKICAgICIiIkZvcm1hdHRlciBjbGFzcyBmb3IgdGV4dCBkb2N1bWVudGF0aW9uLiIiIgoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0ZXh0IGZvcm1hdHRpbmcgdXRpbGl0aWVzCgogICAgX3JlcHJfaW5zdGFuY2UgPSBUZXh0UmVwcigpCiAgICByZXByID0gX3JlcHJfaW5zdGFuY2UucmVwcgoKICAgIGRlZiBib2xkKHNlbGYsIHRleHQpOgogICAgICAgICIiIkZvcm1hdCBhIHN0cmluZyBpbiBib2xkIGJ5IG92ZXJzdHJpa2luZy4iIiIKICAgICAgICByZXR1cm4gam9pbihtYXAobGFtYmRhIGNoOiBjaCArICdcYicgKyBjaCwgdGV4dCksICcnKQoKICAgIGRlZiBpbmRlbnQoc2VsZiwgdGV4dCwgcHJlZml4PScgICAgJyk6CiAgICAgICAgIiIiSW5kZW50IHRleHQgYnkgcHJlcGVuZGluZyBhIGdpdmVuIHByZWZpeCB0byBlYWNoIGxpbmUuIiIiCiAgICAgICAgaWYgbm90IHRleHQ6IHJldHVybiAnJwogICAgICAgIGxpbmVzID0gc3BsaXQodGV4dCwgJ1xuJykKICAgICAgICBsaW5lcyA9IG1hcChsYW1iZGEgbGluZSwgcHJlZml4PXByZWZpeDogcHJlZml4ICsgbGluZSwgbGluZXMpCiAgICAgICAgaWYgbGluZXM6IGxpbmVzWy0xXSA9IHJzdHJpcChsaW5lc1stMV0pCiAgICAgICAgcmV0dXJuIGpvaW4obGluZXMsICdcbicpCgogICAgZGVmIHNlY3Rpb24oc2VsZiwgdGl0bGUsIGNvbnRlbnRzKToKICAgICAgICAiIiJGb3JtYXQgYSBzZWN0aW9uIHdpdGggYSBnaXZlbiBoZWFkaW5nLiIiIgogICAgICAgIHJldHVybiBzZWxmLmJvbGQodGl0bGUpICsgJ1xuJyArIHJzdHJpcChzZWxmLmluZGVudChjb250ZW50cykpICsgJ1xuXG4nCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHR5cGUtc3BlY2lmaWMgcm91dGluZXMKCiAgICBkZWYgZG9jdHJlZShzZWxmLCB0cmVlLCBtb2RuYW1lLCBwYXJlbnQ9Tm9uZSwgcHJlZml4PScnKToKICAgICAgICAiIiJSZW5kZXIgaW4gdGV4dCBhIGNsYXNzIHRyZWUgYXMgcmV0dXJuZWQgYnkgaW5zcGVjdC5nZXRjbGFzc3RyZWUoKS4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIGZvciBlbnRyeSBpbiB0cmVlOgogICAgICAgICAgICBpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKCgpKToKICAgICAgICAgICAgICAgIGNsLCBiYXNlcyA9IGVudHJ5CiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBwcmVmaXggKyBjbGFzc25hbWUoY2wsIG1vZG5hbWUpCiAgICAgICAgICAgICAgICBpZiBiYXNlcyBhbmQgYmFzZXMgIT0gKHBhcmVudCwpOgogICAgICAgICAgICAgICAgICAgIHBhcmVudHMgPSBtYXAobGFtYmRhIGNsLCBtPW1vZG5hbWU6IGNsYXNzbmFtZShjbCwgbSksIGJhc2VzKQogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICcoJXMpJyAlIGpvaW4ocGFyZW50cywgJywgJykKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICdcbicKICAgICAgICAgICAgZWxpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKFtdKToKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuZG9jdHJlZSgKICAgICAgICAgICAgICAgICAgICBlbnRyeSwgbW9kbmFtZSwgY2wsIHByZWZpeCArICcgICAgJykKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIGRvY21vZHVsZShzZWxmLCBvYmplY3QpOgogICAgICAgICIiIlByb2R1Y2UgdGV4dCBkb2N1bWVudGF0aW9uIGZvciBhIGdpdmVuIG1vZHVsZSBvYmplY3QuIiIiCiAgICAgICAgcmVzdWx0ID0gJycKCiAgICAgICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIGxpbmVzID0gc3BsaXQoc3RyaXAoZ2V0ZG9jKG9iamVjdCkpLCAnXG4nKQogICAgICAgIGlmIGxlbihsaW5lcykgPT0gMToKICAgICAgICAgICAgaWYgbGluZXNbMF06IG5hbWUgPSBuYW1lICsgJyAtICcgKyBsaW5lc1swXQogICAgICAgICAgICBsaW5lcyA9IFtdCiAgICAgICAgZWxpZiBsZW4obGluZXMpID49IDIgYW5kIG5vdCByc3RyaXAobGluZXNbMV0pOgogICAgICAgICAgICBpZiBsaW5lc1swXTogbmFtZSA9IG5hbWUgKyAnIC0gJyArIGxpbmVzWzBdCiAgICAgICAgICAgIGxpbmVzID0gbGluZXNbMjpdCiAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdOQU1FJywgbmFtZSkKICAgICAgICB0cnk6IGZpbGUgPSBpbnNwZWN0LmdldGZpbGUob2JqZWN0KSAjIFhYWCBvciBnZXRzb3VyY2VmaWxlPwogICAgICAgIGV4Y2VwdCBUeXBlRXJyb3I6IGZpbGUgPSBOb25lCiAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdGSUxFJywgZmlsZSBvciAnKGJ1aWx0LWluKScpCiAgICAgICAgaWYgbGluZXM6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignREVTQ1JJUFRJT04nLCBqb2luKGxpbmVzLCAnXG4nKSkKCiAgICAgICAgY2xhc3NlcyA9IFtdCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc2NsYXNzKToKICAgICAgICAgICAgaWYgKGluc3BlY3QuZ2V0bW9kdWxlKHZhbHVlKSBvciBvYmplY3QpIGlzIG9iamVjdDoKICAgICAgICAgICAgICAgIGNsYXNzZXMuYXBwZW5kKHZhbHVlKQogICAgICAgIGZ1bmNzID0gW10KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0Lmlzcm91dGluZSk6CiAgICAgICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKHZhbHVlKSBvciBpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgaXMgb2JqZWN0OgogICAgICAgICAgICAgICAgZnVuY3MuYXBwZW5kKHZhbHVlKQogICAgICAgIGNvbnN0YW50cyA9IFtdCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaXNjb25zdGFudCk6CiAgICAgICAgICAgIGlmIGtleVs6MV0gIT0gJ18nOgogICAgICAgICAgICAgICAgY29uc3RhbnRzLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCgogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19wYXRoX18nKToKICAgICAgICAgICAgbW9kcGtncyA9IFtdCiAgICAgICAgICAgIGZvciBmaWxlIGluIG9zLmxpc3RkaXIob2JqZWN0Ll9fcGF0aF9fWzBdKToKICAgICAgICAgICAgICAgIGlmIGZpbGVbOjFdICE9ICdfJzoKICAgICAgICAgICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKG9iamVjdC5fX3BhdGhfX1swXSwgZmlsZSkKICAgICAgICAgICAgICAgICAgICBtb2RuYW1lID0gbW9kdWxlbmFtZShmaWxlKQogICAgICAgICAgICAgICAgICAgIGlmIG1vZG5hbWUgYW5kIG1vZG5hbWUgbm90IGluIG1vZHBrZ3M6CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKG1vZG5hbWUpCiAgICAgICAgICAgICAgICAgICAgZWxpZiBpc3BhY2thZ2UocGF0aCk6CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKGZpbGUgKyAnIChwYWNrYWdlKScpCiAgICAgICAgICAgIG1vZHBrZ3Muc29ydCgpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbigKICAgICAgICAgICAgICAgICdQQUNLQUdFIENPTlRFTlRTJywgam9pbihtb2Rwa2dzLCAnXG4nKSkKCiAgICAgICAgaWYgY2xhc3NlczoKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLmRvY3RyZWUoCiAgICAgICAgICAgICAgICBpbnNwZWN0LmdldGNsYXNzdHJlZShjbGFzc2VzLCAxKSwgb2JqZWN0Ll9fbmFtZV9fKSArICdcbicKICAgICAgICAgICAgZm9yIGl0ZW0gaW4gY2xhc3NlczoKICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gY29udGVudHMgKyBzZWxmLmRvY3VtZW50KGl0ZW0pICsgJ1xuJwogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0NMQVNTRVMnLCBjb250ZW50cykKCiAgICAgICAgaWYgZnVuY3M6CiAgICAgICAgICAgIGNvbnRlbnRzID0gJycKICAgICAgICAgICAgZm9yIGl0ZW0gaW4gZnVuY3M6CiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgc2VsZi5kb2N1bWVudChpdGVtKSArICdcbicKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdGVU5DVElPTlMnLCBjb250ZW50cykKCiAgICAgICAgaWYgY29uc3RhbnRzOgogICAgICAgICAgICBjb250ZW50cyA9ICcnCiAgICAgICAgICAgIGZvciBrZXksIHZhbHVlIGluIGNvbnN0YW50czoKICAgICAgICAgICAgICAgIGxpbmUgPSBrZXkgKyAnID0gJyArIHNlbGYucmVwcih2YWx1ZSkKICAgICAgICAgICAgICAgIGNob3AgPSA3MCAtIGxlbihsaW5lKQogICAgICAgICAgICAgICAgbGluZSA9IHNlbGYuYm9sZChrZXkpICsgJyA9ICcgKyBzZWxmLnJlcHIodmFsdWUpCiAgICAgICAgICAgICAgICBpZiBjaG9wIDwgMDogbGluZSA9IGxpbmVbOmNob3BdICsgJy4uLicKICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gY29udGVudHMgKyBsaW5lICsgJ1xuJwogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0NPTlNUQU5UUycsIGNvbnRlbnRzKQoKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fdmVyc2lvbl9fJyk6CiAgICAgICAgICAgIHZlcnNpb24gPSBzdHIob2JqZWN0Ll9fdmVyc2lvbl9fKQogICAgICAgICAgICBpZiB2ZXJzaW9uWzoxMV0gPT0gJyRSZXZpc2lvbiQnOgogICAgICAgICAgICAgICAgdmVyc2lvbiA9IHZlcnNpb25bMTE6LTFdCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignVkVSU0lPTicsIHZlcnNpb24pCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2RhdGVfXycpOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0RBVEUnLCBzdHIob2JqZWN0Ll9fZGF0ZV9fKSkKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fYXV0aG9yX18nKToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdBVVRIT1InLCBzdHIob2JqZWN0Ll9fYXV0aG9yX18pKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19jcmVkaXRzX18nKToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdDUkVESVRTJywgc3RyKG9iamVjdC5fX2NyZWRpdHNfXykpCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBkb2NjbGFzcyhzZWxmLCBvYmplY3QpOgogICAgICAgICIiIlByb2R1Y2UgdGV4dCBkb2N1bWVudGF0aW9uIGZvciBhIGdpdmVuIGNsYXNzIG9iamVjdC4iIiIKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgYmFzZXMgPSBvYmplY3QuX19iYXNlc19fCgogICAgICAgIHRpdGxlID0gJ2NsYXNzICcgKyBzZWxmLmJvbGQobmFtZSkKICAgICAgICBpZiBiYXNlczoKICAgICAgICAgICAgcGFyZW50cyA9IG1hcChsYW1iZGEgYywgbT1vYmplY3QuX19tb2R1bGVfXzogY2xhc3NuYW1lKGMsIG0pLCBiYXNlcykKICAgICAgICAgICAgdGl0bGUgPSB0aXRsZSArICcoJXMpJyAlIGpvaW4ocGFyZW50cywgJywgJykKCiAgICAgICAgZG9jID0gZ2V0ZG9jKG9iamVjdCkKICAgICAgICBjb250ZW50cyA9IGRvYyBhbmQgZG9jICsgJ1xuJwogICAgICAgIG1ldGhvZHMgPSBtYXAobGFtYmRhIChrZXksIHZhbHVlKTogdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0LmlzbWV0aG9kKSkKICAgICAgICBmb3IgaXRlbSBpbiBtZXRob2RzOgogICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgJ1xuJyArIHNlbGYuZG9jdW1lbnQoaXRlbSkKCiAgICAgICAgaWYgbm90IGNvbnRlbnRzOiByZXR1cm4gdGl0bGUgKyAnXG4nCiAgICAgICAgcmV0dXJuIHRpdGxlICsgJ1xuJyArIHNlbGYuaW5kZW50KHJzdHJpcChjb250ZW50cyksICcgfCAgJykgKyAnXG4nCgogICAgZGVmIGRvY21ldGhvZChzZWxmLCBvYmplY3QpOgogICAgICAgICIiIlByb2R1Y2UgdGV4dCBkb2N1bWVudGF0aW9uIGZvciBhIG1ldGhvZCBvYmplY3QuIiIiCiAgICAgICAgcmV0dXJuIHNlbGYuZG9jdW1lbnQob2JqZWN0LmltX2Z1bmMpCgogICAgZGVmIGZvcm1hdHZhbHVlKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiRm9ybWF0IGFuIGFyZ3VtZW50IGRlZmF1bHQgdmFsdWUgYXMgdGV4dC4iIiIKICAgICAgICByZXR1cm4gJz0nICsgc2VsZi5yZXByKG9iamVjdCkKCiAgICBkZWYgZG9jZnVuY3Rpb24oc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBmdW5jdGlvbiBvYmplY3QuIiIiCiAgICAgICAgdHJ5OgogICAgICAgICAgICBhcmdzLCB2YXJhcmdzLCB2YXJrdywgZGVmYXVsdHMgPSBpbnNwZWN0LmdldGFyZ3NwZWMob2JqZWN0KQogICAgICAgICAgICBhcmdzcGVjID0gaW5zcGVjdC5mb3JtYXRhcmdzcGVjKAogICAgICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzLCBmb3JtYXR2YWx1ZT1zZWxmLmZvcm1hdHZhbHVlKQogICAgICAgIGV4Y2VwdCBUeXBlRXJyb3I6CiAgICAgICAgICAgIGFyZ3NwZWMgPSAnKC4uLiknCgogICAgICAgIGlmIG9iamVjdC5fX25hbWVfXyA9PSAnPGxhbWJkYT4nOgogICAgICAgICAgICBkZWNsID0gJzxsYW1iZGE+ICcgKyBhcmdzcGVjWzE6LTFdCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZGVjbCA9IHNlbGYuYm9sZChvYmplY3QuX19uYW1lX18pICsgYXJnc3BlYwogICAgICAgIGRvYyA9IGdldGRvYyhvYmplY3QpCiAgICAgICAgaWYgZG9jOgogICAgICAgICAgICByZXR1cm4gZGVjbCArICdcbicgKyByc3RyaXAoc2VsZi5pbmRlbnQoZG9jKSkgKyAnXG4nCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIGRlY2wgKyAnXG4nCgogICAgZGVmIGRvY2J1aWx0aW4oc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBidWlsdC1pbiBmdW5jdGlvbiBvYmplY3QuIiIiCiAgICAgICAgcmV0dXJuIChzZWxmLmJvbGQob2JqZWN0Ll9fbmFtZV9fKSArICcoLi4uKVxuJyArCiAgICAgICAgICAgICAgICByc3RyaXAoc2VsZi5pbmRlbnQob2JqZWN0Ll9fZG9jX18pKSArICdcbicpCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB1c2VyIGludGVyZmFjZXMKCmRlZiBwYWdlcih0ZXh0KToKICAgICIiIlRoZSBmaXJzdCB0aW1lIHRoaXMgaXMgY2FsbGVkLCBkZXRlcm1pbmUgd2hhdCBraW5kIG9mIHBhZ2VyIHRvIHVzZS4iIiIKICAgIGdsb2JhbCBwYWdlcgogICAgcGFnZXIgPSBnZXRwYWdlcigpCiAgICBwYWdlcih0ZXh0KQoKZGVmIGdldHBhZ2VyKCk6CiAgICAiIiJEZWNpZGUgd2hhdCBtZXRob2QgdG8gdXNlIGZvciBwYWdpbmcgdGhyb3VnaCB0ZXh0LiIiIgogICAgaWYgdHlwZShzeXMuc3Rkb3V0KSBpcyBub3QgdHlwZXMuRmlsZVR5cGU6CiAgICAgICAgcmV0dXJuIHBsYWlucGFnZXIKICAgIGlmIG5vdCBzeXMuc3RkaW4uaXNhdHR5KCkgb3Igbm90IHN5cy5zdGRvdXQuaXNhdHR5KCk6CiAgICAgICAgcmV0dXJuIHBsYWlucGFnZXIKICAgIGlmIG9zLmVudmlyb24uaGFzX2tleSgnUEFHRVInKToKICAgICAgICByZXR1cm4gbGFtYmRhIGE6IHBpcGVwYWdlcihhLCBvcy5lbnZpcm9uWydQQUdFUiddKQogICAgaWYgc3lzLnBsYXRmb3JtIGluIFsnd2luJywgJ3dpbjMyJywgJ250J106CiAgICAgICAgcmV0dXJuIGxhbWJkYSBhOiB0ZW1wZmlsZXBhZ2VyKGEsICdtb3JlJykKICAgIGlmIGhhc2F0dHIob3MsICdzeXN0ZW0nKSBhbmQgb3Muc3lzdGVtKCdsZXNzIDI+L2Rldi9udWxsJykgPT0gMDoKICAgICAgICByZXR1cm4gbGFtYmRhIGE6IHBpcGVwYWdlcihhLCAnbGVzcycpCgogICAgaW1wb3J0IHRlbXBmaWxlCiAgICBmaWxlbmFtZSA9IHRlbXBmaWxlLm1rdGVtcCgpCiAgICBvcGVuKGZpbGVuYW1lLCAndycpLmNsb3NlKCkKICAgIHRyeToKICAgICAgICBpZiBoYXNhdHRyKG9zLCAnc3lzdGVtJykgYW5kIG9zLnN5c3RlbSgnbW9yZSAlcycgJSBmaWxlbmFtZSkgPT0gMDoKICAgICAgICAgICAgcmV0dXJuIGxhbWJkYSB0ZXh0OiBwaXBlcGFnZXIodGV4dCwgJ21vcmUnKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiB0dHlwYWdlcgogICAgZmluYWxseToKICAgICAgICBvcy51bmxpbmsoZmlsZW5hbWUpCgpkZWYgcGlwZXBhZ2VyKHRleHQsIGNtZCk6CiAgICAiIiJQYWdlIHRocm91Z2ggdGV4dCBieSBmZWVkaW5nIGl0IHRvIGFub3RoZXIgcHJvZ3JhbS4iIiIKICAgIHBpcGUgPSBvcy5wb3BlbihjbWQsICd3JykKICAgIHRyeToKICAgICAgICBwaXBlLndyaXRlKHRleHQpCiAgICAgICAgcGlwZS5jbG9zZSgpCiAgICBleGNlcHQgSU9FcnJvcjoKICAgICAgICAjIElnbm9yZSBicm9rZW4gcGlwZXMgY2F1c2VkIGJ5IHF1aXR0aW5nIHRoZSBwYWdlciBwcm9ncmFtLgogICAgICAgIHBhc3MKCmRlZiB0ZW1wZmlsZXBhZ2VyKHRleHQsIGNtZCk6CiAgICAiIiJQYWdlIHRocm91Z2ggdGV4dCBieSBpbnZva2luZyBhIHByb2dyYW0gb24gYSB0ZW1wb3JhcnkgZmlsZS4iIiIKICAgIGltcG9ydCB0ZW1wZmlsZQogICAgZmlsZW5hbWUgPSB0ZW1wZmlsZS5ta3RlbXAoKQogICAgZmlsZSA9IG9wZW4oZmlsZW5hbWUsICd3JykKICAgIGZpbGUud3JpdGUodGV4dCkKICAgIGZpbGUuY2xvc2UoKQogICAgdHJ5OgogICAgICAgIG9zLnN5c3RlbShjbWQgKyAnICcgKyBmaWxlbmFtZSkKICAgIGZpbmFsbHk6CiAgICAgICAgb3MudW5saW5rKGZpbGVuYW1lKQoKZGVmIHBsYWluKHRleHQpOgogICAgIiIiUmVtb3ZlIGJvbGRmYWNlIGZvcm1hdHRpbmcgZnJvbSB0ZXh0LiIiIgogICAgcmV0dXJuIHJlLnN1YignLlxiJywgJycsIHRleHQpCgpkZWYgdHR5cGFnZXIodGV4dCk6CiAgICAiIiJQYWdlIHRocm91Z2ggdGV4dCBvbiBhIHRleHQgdGVybWluYWwuIiIiCiAgICBsaW5lcyA9IHNwbGl0KHBsYWluKHRleHQpLCAnXG4nKQogICAgdHJ5OgogICAgICAgIGltcG9ydCB0dHkKICAgICAgICBmZCA9IHN5cy5zdGRpbi5maWxlbm8oKQogICAgICAgIG9sZCA9IHR0eS50Y2dldGF0dHIoZmQpCiAgICAgICAgdHR5LnNldGNicmVhayhmZCkKICAgICAgICBnZXRjaGFyID0gbGFtYmRhOiBzeXMuc3RkaW4ucmVhZCgxKQogICAgZXhjZXB0IChJbXBvcnRFcnJvciwgQXR0cmlidXRlRXJyb3IpOgogICAgICAgIHR0eSA9IE5vbmUKICAgICAgICBnZXRjaGFyID0gbGFtYmRhOiBzeXMuc3RkaW4ucmVhZGxpbmUoKVs6LTFdWzoxXQoKICAgIHRyeToKICAgICAgICByID0gaW5jID0gb3MuZW52aXJvbi5nZXQoJ0xJTkVTJywgMjUpIC0gMQogICAgICAgIHN5cy5zdGRvdXQud3JpdGUoam9pbihsaW5lc1s6aW5jXSwgJ1xuJykgKyAnXG4nKQogICAgICAgIHdoaWxlIGxpbmVzW3I6XToKICAgICAgICAgICAgc3lzLnN0ZG91dC53cml0ZSgnLS0gbW9yZSAtLScpCiAgICAgICAgICAgIHN5cy5zdGRvdXQuZmx1c2goKQogICAgICAgICAgICBjID0gZ2V0Y2hhcigpCgogICAgICAgICAgICBpZiBjIGluIFsncScsICdRJ106CiAgICAgICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCdcciAgICAgICAgICBccicpCiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBlbGlmIGMgaW4gWydccicsICdcbiddOgogICAgICAgICAgICAgICAgc3lzLnN0ZG91dC53cml0ZSgnXHIgICAgICAgICAgXHInICsgbGluZXNbcl0gKyAnXG4nKQogICAgICAgICAgICAgICAgciA9IHIgKyAxCiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBpZiBjIGluIFsnYicsICdCJywgJ1x4MWInXToKICAgICAgICAgICAgICAgIHIgPSByIC0gaW5jIC0gaW5jCiAgICAgICAgICAgICAgICBpZiByIDwgMDogciA9IDAKICAgICAgICAgICAgc3lzLnN0ZG91dC53cml0ZSgnXG4nICsgam9pbihsaW5lc1tyOnIraW5jXSwgJ1xuJykgKyAnXG4nKQogICAgICAgICAgICByID0gciArIGluYwoKICAgIGZpbmFsbHk6CiAgICAgICAgaWYgdHR5OgogICAgICAgICAgICB0dHkudGNzZXRhdHRyKGZkLCB0dHkuVENTQUZMVVNILCBvbGQpCgpkZWYgcGxhaW5wYWdlcih0ZXh0KToKICAgICIiIlNpbXBseSBwcmludCB1bmZvcm1hdHRlZCB0ZXh0LiAgVGhpcyBpcyB0aGUgdWx0aW1hdGUgZmFsbGJhY2suIiIiCiAgICBzeXMuc3Rkb3V0LndyaXRlKHBsYWluKHRleHQpKQoKZGVmIGRlc2NyaWJlKHRoaW5nKToKICAgICIiIlByb2R1Y2UgYSBzaG9ydCBkZXNjcmlwdGlvbiBvZiB0aGUgZ2l2ZW4ga2luZCBvZiB0aGluZy4iIiIKICAgIGlmIGluc3BlY3QuaXNtb2R1bGUodGhpbmcpOgogICAgICAgIGlmIHRoaW5nLl9fbmFtZV9fIGluIHN5cy5idWlsdGluX21vZHVsZV9uYW1lczoKICAgICAgICAgICAgcmV0dXJuICdidWlsdC1pbiBtb2R1bGUgJyArIHRoaW5nLl9fbmFtZV9fCiAgICAgICAgaWYgaGFzYXR0cih0aGluZywgJ19fcGF0aF9fJyk6CiAgICAgICAgICAgIHJldHVybiAncGFja2FnZSAnICsgdGhpbmcuX19uYW1lX18KICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gJ21vZHVsZSAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIGluc3BlY3QuaXNidWlsdGluKHRoaW5nKToKICAgICAgICByZXR1cm4gJ2J1aWx0LWluIGZ1bmN0aW9uICcgKyB0aGluZy5fX25hbWVfXwogICAgaWYgaW5zcGVjdC5pc2NsYXNzKHRoaW5nKToKICAgICAgICByZXR1cm4gJ2NsYXNzICcgKyB0aGluZy5fX25hbWVfXwogICAgaWYgaW5zcGVjdC5pc2Z1bmN0aW9uKHRoaW5nKToKICAgICAgICByZXR1cm4gJ2Z1bmN0aW9uICcgKyB0aGluZy5fX25hbWVfXwogICAgaWYgaW5zcGVjdC5pc21ldGhvZCh0aGluZyk6CiAgICAgICAgcmV0dXJuICdtZXRob2QgJyArIHRoaW5nLl9fbmFtZV9fCiAgICByZXR1cm4gcmVwcih0aGluZykKCmRlZiBsb2NhdGUocGF0aCk6CiAgICAiIiJMb2NhdGUgYW4gb2JqZWN0IGJ5IG5hbWUgKG9yIGRvdHRlZCBwYXRoKSwgaW1wb3J0aW5nIGFzIG5lY2Vzc2FyeS4iIiIKICAgIGlmIG5vdCBwYXRoOiAjIHNwZWNpYWwgY2FzZTogaW1wLmZpbmRfbW9kdWxlKCcnKSBzdHJhbmdlbHkgc3VjY2VlZHMKICAgICAgICByZXR1cm4gTm9uZSwgTm9uZQogICAgaWYgdHlwZShwYXRoKSBpcyBub3QgdHlwZXMuU3RyaW5nVHlwZToKICAgICAgICByZXR1cm4gTm9uZSwgcGF0aAogICAgaWYgaGFzYXR0cihfX2J1aWx0aW5zX18sIHBhdGgpOgogICAgICAgIHJldHVybiBOb25lLCBnZXRhdHRyKF9fYnVpbHRpbnNfXywgcGF0aCkKICAgIHBhcnRzID0gc3BsaXQocGF0aCwgJy4nKQogICAgbiA9IDEKICAgIHdoaWxlIG4gPD0gbGVuKHBhcnRzKToKICAgICAgICBwYXRoID0gam9pbihwYXJ0c1s6bl0sICcuJykKICAgICAgICB0cnk6CiAgICAgICAgICAgIG1vZHVsZSA9IF9faW1wb3J0X18ocGF0aCkKICAgICAgICAgICAgbW9kdWxlID0gcmVsb2FkKG1vZHVsZSkKICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICMgRGlkIHRoZSBlcnJvciBvY2N1ciBiZWZvcmUgb3IgYWZ0ZXIgd2UgZm91bmQgdGhlIG1vZHVsZT8KICAgICAgICAgICAgaWYgc3lzLm1vZHVsZXMuaGFzX2tleShwYXRoKToKICAgICAgICAgICAgICAgIGZpbGVuYW1lID0gc3lzLm1vZHVsZXNbcGF0aF0uX19maWxlX18KICAgICAgICAgICAgZWxpZiBzeXMuZXhjX3R5cGUgaXMgU3ludGF4RXJyb3I6CiAgICAgICAgICAgICAgICBmaWxlbmFtZSA9IHN5cy5leGNfdmFsdWUuZmlsZW5hbWUKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgbW9kdWxlIG5vdCBmb3VuZCwgc28gc3RvcCBsb29raW5nCiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAjIGVycm9yIG9jY3VycmVkIGluIHRoZSBpbXBvcnRlZCBtb2R1bGUsIHNvIHJlcG9ydCBpdAogICAgICAgICAgICByYWlzZSBEb2NJbXBvcnRFcnJvcihmaWxlbmFtZSwgc3lzLmV4Y190eXBlLCBzeXMuZXhjX3ZhbHVlKQogICAgICAgIHRyeToKICAgICAgICAgICAgeCA9IG1vZHVsZQogICAgICAgICAgICBmb3IgcCBpbiBwYXJ0c1sxOl06CiAgICAgICAgICAgICAgICB4ID0gZ2V0YXR0cih4LCBwKQogICAgICAgICAgICByZXR1cm4gam9pbihwYXJ0c1s6LTFdLCAnLicpLCB4CiAgICAgICAgZXhjZXB0IEF0dHJpYnV0ZUVycm9yOgogICAgICAgICAgICBuID0gbiArIDEKICAgICAgICAgICAgY29udGludWUKICAgIHJldHVybiBOb25lLCBOb25lCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBpbnRlcmFjdGl2ZSBpbnRlcnByZXRlciBpbnRlcmZhY2UKCnRleHQgPSBUZXh0RG9jKCkKaHRtbCA9IEhUTUxEb2MoKQoKZGVmIGRvYyh0aGluZyk6CiAgICAiIiJEaXNwbGF5IGRvY3VtZW50YXRpb24gb24gYW4gb2JqZWN0IChmb3IgaW50ZXJhY3RpdmUgdXNlKS4iIiIKICAgIGlmIHR5cGUodGhpbmcpIGlzIHR5cGUoIiIpOgogICAgICAgIHRyeToKICAgICAgICAgICAgcGF0aCwgeCA9IGxvY2F0ZSh0aGluZykKICAgICAgICBleGNlcHQgRG9jSW1wb3J0RXJyb3IsIHZhbHVlOgogICAgICAgICAgICBwcmludCAncHJvYmxlbSBpbiAlcyAtICVzJyAlICh2YWx1ZS5maWxlbmFtZSwgdmFsdWUuYXJncykKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgaWYgeDoKICAgICAgICAgICAgdGhpbmcgPSB4CiAgICAgICAgZWxzZToKICAgICAgICAgICAgcHJpbnQgJ2NvdWxkIG5vdCBmaW5kIG9yIGltcG9ydCAlcycgJSByZXByKHRoaW5nKQogICAgICAgICAgICByZXR1cm4KCiAgICBkZXNjID0gZGVzY3JpYmUodGhpbmcpCiAgICBtb2R1bGUgPSBpbnNwZWN0LmdldG1vZHVsZSh0aGluZykKICAgIGlmIG1vZHVsZSBhbmQgbW9kdWxlIGlzIG5vdCB0aGluZzoKICAgICAgICBkZXNjID0gZGVzYyArICcgaW4gbW9kdWxlICcgKyBtb2R1bGUuX19uYW1lX18KICAgIHBhZ2VyKCdIZWxwIG9uICVzOlxuXG4nICUgZGVzYyArIHRleHQuZG9jdW1lbnQodGhpbmcpKQoKZGVmIHdyaXRlZG9jcyhwYXRoLCBwa2dwYXRoPScnKToKICAgIGlmIG9zLnBhdGguaXNkaXIocGF0aCk6CiAgICAgICAgZGlyID0gcGF0aAogICAgICAgIGZvciBmaWxlIGluIG9zLmxpc3RkaXIoZGlyKToKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihkaXIsIGZpbGUpCiAgICAgICAgICAgIGlmIG9zLnBhdGguaXNkaXIocGF0aCk6CiAgICAgICAgICAgICAgICB3cml0ZWRvY3MocGF0aCwgZmlsZSArICcuJyArIHBrZ3BhdGgpCiAgICAgICAgICAgIGlmIG9zLnBhdGguaXNmaWxlKHBhdGgpOgogICAgICAgICAgICAgICAgd3JpdGVkb2NzKHBhdGgsIHBrZ3BhdGgpCiAgICBpZiBvcy5wYXRoLmlzZmlsZShwYXRoKToKICAgICAgICBtb2RuYW1lID0gbW9kdWxlbmFtZShwYXRoKQogICAgICAgIGlmIG1vZG5hbWU6CiAgICAgICAgICAgIHdyaXRlZG9jKHBrZ3BhdGggKyBtb2RuYW1lKQoKZGVmIHdyaXRlZG9jKGtleSk6CiAgICAiIiJXcml0ZSBIVE1MIGRvY3VtZW50YXRpb24gdG8gYSBmaWxlIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeS4iIiIKICAgIHBhdGgsIG9iamVjdCA9IGxvY2F0ZShrZXkpCiAgICBpZiBvYmplY3Q6CiAgICAgICAgZmlsZSA9IG9wZW4oa2V5ICsgJy5odG1sJywgJ3cnKQogICAgICAgIGZpbGUud3JpdGUoaHRtbC5wYWdlKG9iamVjdCkpCiAgICAgICAgZmlsZS5jbG9zZSgpCiAgICAgICAgcHJpbnQgJ3dyb3RlJywga2V5ICsgJy5odG1sJwoKY2xhc3MgSGVscGVyOgogICAgZGVmIF9fcmVwcl9fKHNlbGYpOgogICAgICAgIHJldHVybiAiIiJUbyBnZXQgaGVscCBvbiBhIFB5dGhvbiBvYmplY3QsIGNhbGwgaGVscChvYmplY3QpLgpUbyBnZXQgaGVscCBvbiBhIG1vZHVsZSBvciBwYWNrYWdlLCBlaXRoZXIgaW1wb3J0IGl0IGJlZm9yZSBjYWxsaW5nCmhlbHAobW9kdWxlKSBvciBjYWxsIGhlbHAoJ21vZHVsZW5hbWUnKS4iIiIKCiAgICBkZWYgX19jYWxsX18oc2VsZiwgKmFyZ3MpOgogICAgICAgIGlmIGFyZ3M6CiAgICAgICAgICAgIGRvYyhhcmdzWzBdKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHByaW50IHJlcHIoc2VsZikKCmhlbHAgPSBIZWxwZXIoKQoKZGVmIG1hbihrZXkpOgogICAgIiIiRGlzcGxheSBkb2N1bWVudGF0aW9uIG9uIGFuIG9iamVjdCBpbiBhIGZvcm0gc2ltaWxhciB0byBtYW4oMSkuIiIiCiAgICBwYXRoLCBvYmplY3QgPSBsb2NhdGUoa2V5KQogICAgaWYgb2JqZWN0OgogICAgICAgIHRpdGxlID0gJ1B5dGhvbiBMaWJyYXJ5IERvY3VtZW50YXRpb246ICcgKyBkZXNjcmliZShvYmplY3QpCiAgICAgICAgaWYgcGF0aDogdGl0bGUgPSB0aXRsZSArICcgaW4gJyArIHBhdGgKICAgICAgICBwYWdlcignXG4nICsgdGl0bGUgKyAnXG5cbicgKyB0ZXh0LmRvY3VtZW50KG9iamVjdCkpCiAgICAgICAgZm91bmQgPSAxCiAgICBlbHNlOgogICAgICAgIHByaW50ICdjb3VsZCBub3QgZmluZCBvciBpbXBvcnQgJXMnICUgcmVwcihrZXkpCgpkZWYgYXByb3BvcyhrZXkpOgogICAgIiIiUHJpbnQgYWxsIHRoZSBvbmUtbGluZSBtb2R1bGUgc3VtbWFyaWVzIHRoYXQgY29udGFpbiBhIHN1YnN0cmluZy4iIiIKICAgIGtleSA9IGxvd2VyKGtleSkKICAgIGZvciBtb2R1bGUgaW4gc3lzLmJ1aWx0aW5fbW9kdWxlX25hbWVzOgogICAgICAgIGRlc2MgPSBfX2ltcG9ydF9fKG1vZHVsZSkuX19kb2NfXyBvciAnJwogICAgICAgIGRlc2MgPSBzcGxpdChkZXNjLCAnXG4nKVswXQogICAgICAgIGlmIGZpbmQobG93ZXIobW9kdWxlICsgJyAnICsgZGVzYyksIGtleSkgPj0gMDoKICAgICAgICAgICAgcHJpbnQgbW9kdWxlLCAnLScsIGRlc2Mgb3IgJyhubyBkZXNjcmlwdGlvbiknCiAgICBtb2R1bGVzID0gW10KICAgIGZvciBkaXIgaW4gcGF0aGRpcnMoKToKICAgICAgICBmb3IgbW9kdWxlLCBkZXNjIGluIGluZGV4KGRpcik6CiAgICAgICAgICAgIGRlc2MgPSBkZXNjIG9yICcnCiAgICAgICAgICAgIGlmIG1vZHVsZSBub3QgaW4gbW9kdWxlczoKICAgICAgICAgICAgICAgIG1vZHVsZXMuYXBwZW5kKG1vZHVsZSkKICAgICAgICAgICAgICAgIGlmIGZpbmQobG93ZXIobW9kdWxlICsgJyAnICsgZGVzYyksIGtleSkgPj0gMDoKICAgICAgICAgICAgICAgICAgICBkZXNjID0gZGVzYyBvciAnKG5vIGRlc2NyaXB0aW9uKScKICAgICAgICAgICAgICAgICAgICBpZiBtb2R1bGVbLTk6XSA9PSAnLl9faW5pdF9fJzoKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQgbW9kdWxlWzotOV0sICcocGFja2FnZSkgLScsIGRlc2MKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBwcmludCBtb2R1bGUsICctJywgZGVzYwoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gd2ViIGJyb3dzZXIgaW50ZXJmYWNlCgpkZWYgc2VydmUoYWRkcmVzcywgY2FsbGJhY2s9Tm9uZSk6CiAgICBpbXBvcnQgQmFzZUhUVFBTZXJ2ZXIsIG1pbWV0b29scwoKICAgICMgUGF0Y2ggdXAgbWltZXRvb2xzLk1lc3NhZ2Ugc28gaXQgZG9lc24ndCBicmVhayBpZiByZmM4MjIgaXMgcmVsb2FkZWQuCiAgICBjbGFzcyBNZXNzYWdlKG1pbWV0b29scy5NZXNzYWdlKToKICAgICAgICBkZWYgX19pbml0X18oc2VsZiwgZnAsIHNlZWthYmxlPTEpOgogICAgICAgICAgICBNZXNzYWdlID0gc2VsZi5fX2NsYXNzX18KICAgICAgICAgICAgTWVzc2FnZS5fX2Jhc2VzX19bMF0uX19iYXNlc19fWzBdLl9faW5pdF9fKHNlbGYsIGZwLCBzZWVrYWJsZSkKICAgICAgICAgICAgc2VsZi5lbmNvZGluZ2hlYWRlciA9IHNlbGYuZ2V0aGVhZGVyKCdjb250ZW50LXRyYW5zZmVyLWVuY29kaW5nJykKICAgICAgICAgICAgc2VsZi50eXBlaGVhZGVyID0gc2VsZi5nZXRoZWFkZXIoJ2NvbnRlbnQtdHlwZScpCiAgICAgICAgICAgIHNlbGYucGFyc2V0eXBlKCkKICAgICAgICAgICAgc2VsZi5wYXJzZXBsaXN0KCkKCiAgICBjbGFzcyBEb2NIYW5kbGVyKEJhc2VIVFRQU2VydmVyLkJhc2VIVFRQUmVxdWVzdEhhbmRsZXIpOgogICAgICAgIGRlZiBzZW5kX2RvY3VtZW50KHNlbGYsIHRpdGxlLCBjb250ZW50cyk6CiAgICAgICAgICAgIHNlbGYuc2VuZF9yZXNwb25zZSgyMDApCiAgICAgICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoJ0NvbnRlbnQtVHlwZScsICd0ZXh0L2h0bWwnKQogICAgICAgICAgICBzZWxmLmVuZF9oZWFkZXJzKCkKICAgICAgICAgICAgc2VsZi53ZmlsZS53cml0ZSgKJycnPCFkb2N0eXBlIGh0bWwgcHVibGljICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KPGh0bWw+PHRpdGxlPlB5dGhvbjogJXM8L3RpdGxlPjxib2R5IGJnY29sb3I9IiNmZmZmZmYiPicnJyAlIHRpdGxlKQogICAgICAgICAgICBzZWxmLndmaWxlLndyaXRlKGNvbnRlbnRzKQogICAgICAgICAgICBzZWxmLndmaWxlLndyaXRlKCc8L2JvZHk+PC9odG1sPicpCgogICAgICAgIGRlZiBkb19HRVQoc2VsZik6CiAgICAgICAgICAgIHBhdGggPSBzZWxmLnBhdGgKICAgICAgICAgICAgaWYgcGF0aFstNTpdID09ICcuaHRtbCc6IHBhdGggPSBwYXRoWzotNV0KICAgICAgICAgICAgaWYgcGF0aFs6MV0gPT0gJy8nOiBwYXRoID0gcGF0aFsxOl0KICAgICAgICAgICAgaWYgcGF0aCBhbmQgcGF0aCAhPSAnLic6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgcCwgeCA9IGxvY2F0ZShwYXRoKQogICAgICAgICAgICAgICAgZXhjZXB0IERvY0ltcG9ydEVycm9yLCB2YWx1ZToKICAgICAgICAgICAgICAgICAgICBzZWxmLnNlbmRfZG9jdW1lbnQocGF0aCwgaHRtbC5lc2NhcGUoCiAgICAgICAgICAgICAgICAgICAgICAgICdwcm9ibGVtIHdpdGggJXMgLSAlcycgJSAodmFsdWUuZmlsZW5hbWUsIHZhbHVlLmFyZ3MpKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIGlmIHg6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZW5kX2RvY3VtZW50KGRlc2NyaWJlKHgpLCBodG1sLmRvY3VtZW50KHgpKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLnNlbmRfZG9jdW1lbnQocGF0aCwKJ1RoZXJlIGlzIG5vIFB5dGhvbiBtb2R1bGUgb3Igb2JqZWN0IG5hbWVkICIlcyIuJyAlIHBhdGgpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBoZWFkaW5nID0gaHRtbC5oZWFkaW5nKAogICAgICAgICAgICAgICAgICAgICc8YnI+PGJpZz48YmlnPjxzdHJvbmc+Jm5ic3A7JwogICAgICAgICAgICAgICAgICAgICdQeXRob246IEluZGV4IG9mIE1vZHVsZXMnCiAgICAgICAgICAgICAgICAgICAgJzwvc3Ryb25nPjwvYmlnPjwvYmlnPicsCiAgICAgICAgICAgICAgICAgICAgJyNmZmZmZmYnLCAnIzc3OTllZScpCiAgICAgICAgICAgICAgICBidWlsdGlucyA9IFtdCiAgICAgICAgICAgICAgICBmb3IgbmFtZSBpbiBzeXMuYnVpbHRpbl9tb2R1bGVfbmFtZXM6CiAgICAgICAgICAgICAgICAgICAgYnVpbHRpbnMuYXBwZW5kKCc8YSBocmVmPSIlcy5odG1sIj4lczwvYT4nICUgKG5hbWUsIG5hbWUpKQogICAgICAgICAgICAgICAgaW5kaWNlcyA9IFsnPHA+QnVpbHQtaW4gbW9kdWxlczogJyArIGpvaW4oYnVpbHRpbnMsICcsICcpXQogICAgICAgICAgICAgICAgc2VlbiA9IHt9CiAgICAgICAgICAgICAgICBmb3IgZGlyIGluIHBhdGhkaXJzKCk6CiAgICAgICAgICAgICAgICAgICAgaW5kaWNlcy5hcHBlbmQoaHRtbC5pbmRleChkaXIsIHNlZW4pKQogICAgICAgICAgICAgICAgc2VsZi5zZW5kX2RvY3VtZW50KCdJbmRleCBvZiBNb2R1bGVzJywgaGVhZGluZyArIGpvaW4oaW5kaWNlcykpCgogICAgICAgIGRlZiBsb2dfbWVzc2FnZShzZWxmLCAqYXJncyk6IHBhc3MKCiAgICBjbGFzcyBEb2NTZXJ2ZXIoQmFzZUhUVFBTZXJ2ZXIuSFRUUFNlcnZlcik6CiAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIGFkZHJlc3MsIGNhbGxiYWNrKToKICAgICAgICAgICAgc2VsZi5jYWxsYmFjayA9IGNhbGxiYWNrCiAgICAgICAgICAgIHNlbGYuYmFzZS5fX2luaXRfXyhzZWxmLCBhZGRyZXNzLCBzZWxmLmhhbmRsZXIpCgogICAgICAgIGRlZiBzZXJ2ZXJfYWN0aXZhdGUoc2VsZik6CiAgICAgICAgICAgIHNlbGYuYmFzZS5zZXJ2ZXJfYWN0aXZhdGUoc2VsZikKICAgICAgICAgICAgaWYgc2VsZi5jYWxsYmFjazogc2VsZi5jYWxsYmFjaygpCgogICAgRG9jU2VydmVyLmJhc2UgPSBCYXNlSFRUUFNlcnZlci5IVFRQU2VydmVyCiAgICBEb2NTZXJ2ZXIuaGFuZGxlciA9IERvY0hhbmRsZXIKICAgIERvY0hhbmRsZXIuTWVzc2FnZUNsYXNzID0gTWVzc2FnZQogICAgdHJ5OgogICAgICAgIERvY1NlcnZlcihhZGRyZXNzLCBjYWxsYmFjaykuc2VydmVfZm9yZXZlcigpCiAgICBleGNlcHQgS2V5Ym9hcmRJbnRlcnJ1cHQ6CiAgICAgICAgcHJpbnQgJ3NlcnZlciBzdG9wcGVkJwoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBjb21tYW5kLWxpbmUgaW50ZXJmYWNlCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgaW1wb3J0IGdldG9wdAogICAgY2xhc3MgQmFkVXNhZ2U6IHBhc3MKCiAgICB0cnk6CiAgICAgICAgb3B0cywgYXJncyA9IGdldG9wdC5nZXRvcHQoc3lzLmFyZ3ZbMTpdLCAnazpwOncnKQogICAgICAgIHdyaXRpbmcgPSAwCgogICAgICAgIGZvciBvcHQsIHZhbCBpbiBvcHRzOgogICAgICAgICAgICBpZiBvcHQgPT0gJy1rJzoKICAgICAgICAgICAgICAgIGFwcm9wb3MobG93ZXIodmFsKSkKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGlmIG9wdCA9PSAnLXAnOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHBvcnQgPSBpbnQodmFsKQogICAgICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgQmFkVXNhZ2UKICAgICAgICAgICAgICAgIGRlZiByZWFkeShwb3J0PXBvcnQpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICdzZXJ2ZXIgcmVhZHkgYXQgaHR0cDovLzEyNy4wLjAuMTolZC8nICUgcG9ydAogICAgICAgICAgICAgICAgc2VydmUoKCcxMjcuMC4wLjEnLCBwb3J0KSwgcmVhZHkpCiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBpZiBvcHQgPT0gJy13JzoKICAgICAgICAgICAgICAgIGlmIG5vdCBhcmdzOiByYWlzZSBCYWRVc2FnZQogICAgICAgICAgICAgICAgd3JpdGluZyA9IDEKICAgICAgICBlbHNlOgogICAgICAgICAgICBpZiBhcmdzOgogICAgICAgICAgICAgICAgZm9yIGFyZyBpbiBhcmdzOgogICAgICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUoYXJnKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZyA9IGltcG9ydGZpbGUoYXJnKQogICAgICAgICAgICAgICAgICAgICAgICBpZiB3cml0aW5nOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgb3MucGF0aC5pc2RpcihhcmcpOiB3cml0ZWRvY3MoYXJnKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZTogd3JpdGVkb2MoYXJnKQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlOiBtYW4oYXJnKQogICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBEb2NJbXBvcnRFcnJvciwgdmFsdWU6CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ICdwcm9ibGVtIGluICVzIC0gJXMnICUgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUuZmlsZW5hbWUsIHZhbHVlLmFyZ3MpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gaW4gWydtYWMnLCAnd2luJywgJ3dpbjMyJywgJ250J106CiAgICAgICAgICAgICAgICAgICAgIyBHVUkgcGxhdGZvcm1zIHdpdGggdGhyZWFkaW5nCiAgICAgICAgICAgICAgICAgICAgaW1wb3J0IHRocmVhZGluZwogICAgICAgICAgICAgICAgICAgIHJlYWR5ID0gdGhyZWFkaW5nLkV2ZW50KCkKICAgICAgICAgICAgICAgICAgICBhZGRyZXNzID0gKCcxMjcuMC4wLjEnLCAxMjM0NikKICAgICAgICAgICAgICAgICAgICB0aHJlYWRpbmcuVGhyZWFkKAogICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQ9c2VydmUsIGFyZ3M9KGFkZHJlc3MsIHJlYWR5LnNldCkpLnN0YXJ0KCkKICAgICAgICAgICAgICAgICAgICByZWFkeS53YWl0KCkKICAgICAgICAgICAgICAgICAgICBpbXBvcnQgd2ViYnJvd3NlcgogICAgICAgICAgICAgICAgICAgIHdlYmJyb3dzZXIub3BlbignaHR0cDovLzEyNy4wLjAuMToxMjM0Ni8nKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICByYWlzZSBCYWRVc2FnZQoKICAgIGV4Y2VwdCAoZ2V0b3B0LmVycm9yLCBCYWRVc2FnZSk6CiAgICAgICAgcHJpbnQgIiIiJXMgPG5hbWU+IC4uLgogICAgU2hvdyBkb2N1bWVudGF0aW9uIG9uIHNvbWV0aGluZy4KICAgIDxuYW1lPiBtYXkgYmUgdGhlIG5hbWUgb2YgYSBQeXRob24gZnVuY3Rpb24sIG1vZHVsZSwgb3IgcGFja2FnZSwKICAgIG9yIGEgZG90dGVkIHJlZmVyZW5jZSB0byBhIGNsYXNzIG9yIGZ1bmN0aW9uIHdpdGhpbiBhIG1vZHVsZSBvcgogICAgbW9kdWxlIGluIGEgcGFja2FnZSwgb3IgdGhlIGZpbGVuYW1lIG9mIGEgUHl0aG9uIG1vZHVsZSB0byBpbXBvcnQuCgolcyAtayA8a2V5d29yZD4KICAgIFNlYXJjaCBmb3IgYSBrZXl3b3JkIGluIHRoZSBzeW5vcHNpcyBsaW5lcyBvZiBhbGwgbW9kdWxlcy4KCiVzIC1wIDxwb3J0PgogICAgU3RhcnQgYW4gSFRUUCBzZXJ2ZXIgb24gdGhlIGdpdmVuIHBvcnQgb24gdGhlIGxvY2FsIG1hY2hpbmUuCgolcyAtdyA8bW9kdWxlPiAuLi4KICAgIFdyaXRlIG91dCB0aGUgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIG1vZHVsZSB0byBhIGZpbGUuCgolcyAtdyA8bW9kdWxlZGlyPgogICAgV3JpdGUgb3V0IHRoZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGFsbCBtb2R1bGVzIGluIHRoZSB0cmVlCiAgICB1bmRlciBhIGdpdmVuIGRpcmVjdG9yeSB0byBmaWxlcyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuCiIiIiAlICgoc3lzLmFyZ3ZbMF0sKSAqIDUpCg==