IyAtKi0gY29kaW5nOiBsYXRpbi0xIC0qLQoiIiJUZXN0cyBmb3IgY29va2llbGliLnB5LiIiIgoKaW1wb3J0IGNvb2tpZWxpYgppbXBvcnQgb3MKaW1wb3J0IHJlCmltcG9ydCB0aW1lCgpmcm9tIHVuaXR0ZXN0IGltcG9ydCBUZXN0Q2FzZQoKZnJvbSB0ZXN0IGltcG9ydCB0ZXN0X3N1cHBvcnQKCgpjbGFzcyBEYXRlVGltZVRlc3RzKFRlc3RDYXNlKToKCiAgICBkZWYgdGVzdF90aW1lMmlzb3ooc2VsZik6CiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IHRpbWUyaXNvegoKICAgICAgICBiYXNlID0gMTAxOTIyNzAwMAogICAgICAgIGRheSA9IDI0KjM2MDAKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRpbWUyaXNveihiYXNlKSwgIjIwMDItMDQtMTkgMTQ6MzY6NDBaIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRpbWUyaXNveihiYXNlK2RheSksICIyMDAyLTA0LTIwIDE0OjM2OjQwWiIpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0aW1lMmlzb3ooYmFzZSsyKmRheSksICIyMDAyLTA0LTIxIDE0OjM2OjQwWiIpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0aW1lMmlzb3ooYmFzZSszKmRheSksICIyMDAyLTA0LTIyIDE0OjM2OjQwWiIpCgogICAgICAgIGF6ID0gdGltZTJpc296KCkKICAgICAgICBieiA9IHRpbWUyaXNveig1MDAwMDApCiAgICAgICAgZm9yIHRleHQgaW4gKGF6LCBieik6CiAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZS5zZWFyY2gociJeXGR7NH0tXGRcZC1cZFxkIFxkXGQ6XGRcZDpcZFxkWiQiLCB0ZXh0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICJiYWQgdGltZTJpc296IGZvcm1hdDogJXMgJXMiICUgKGF6LCBieikpCgogICAgZGVmIHRlc3RfaHR0cDJ0aW1lKHNlbGYpOgogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBodHRwMnRpbWUKCiAgICAgICAgZGVmIHBhcnNlX2RhdGUodGV4dCk6CiAgICAgICAgICAgIHJldHVybiB0aW1lLmdtdGltZShodHRwMnRpbWUodGV4dCkpWzo2XQoKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHBhcnNlX2RhdGUoIjAxIEphbiAyMDAxIiksICgyMDAxLCAxLCAxLCAwLCAwLCAwLjApKQoKICAgICAgICAjIHRoaXMgdGVzdCB3aWxsIGJyZWFrIGFyb3VuZCB5ZWFyIDIwNzAKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHBhcnNlX2RhdGUoIjAzLUZlYi0yMCIpLCAoMjAyMCwgMiwgMywgMCwgMCwgMC4wKSkKCiAgICAgICAgIyB0aGlzIHRlc3Qgd2lsbCBicmVhayBhcm91bmQgeWVhciAyMDQ4CiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChwYXJzZV9kYXRlKCIwMy1GZWItOTgiKSwgKDE5OTgsIDIsIDMsIDAsIDAsIDAuMCkpCgogICAgZGVmIHRlc3RfaHR0cDJ0aW1lX2Zvcm1hdHMoc2VsZik6CiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IGh0dHAydGltZSwgdGltZTJpc296CgogICAgICAgICMgdGVzdCBodHRwMnRpbWUgZm9yIHN1cHBvcnRlZCBkYXRlcy4gIFRlc3QgY2FzZXMgd2l0aCAyIGRpZ2l0IHllYXIKICAgICAgICAjIHdpbGwgcHJvYmFibHkgYnJlYWsgaW4geWVhciAyMDQ0LgogICAgICAgIHRlc3RzID0gWwogICAgICAgICAnVGh1LCAwMyBGZWIgMTk5NCAwMDowMDowMCBHTVQnLCAgIyBwcm9wb3NlZCBuZXcgSFRUUCBmb3JtYXQKICAgICAgICAgJ1RodXJzZGF5LCAwMy1GZWItOTQgMDA6MDA6MDAgR01UJywgICMgb2xkIHJmYzg1MCBIVFRQIGZvcm1hdAogICAgICAgICAnVGh1cnNkYXksIDAzLUZlYi0xOTk0IDAwOjAwOjAwIEdNVCcsICAjIGJyb2tlbiByZmM4NTAgSFRUUCBmb3JtYXQKCiAgICAgICAgICcwMyBGZWIgMTk5NCAwMDowMDowMCBHTVQnLCAgIyBIVFRQIGZvcm1hdCAobm8gd2Vla2RheSkKICAgICAgICAgJzAzLUZlYi05NCAwMDowMDowMCBHTVQnLCAgIyBvbGQgcmZjODUwIChubyB3ZWVrZGF5KQogICAgICAgICAnMDMtRmViLTE5OTQgMDA6MDA6MDAgR01UJywgICMgYnJva2VuIHJmYzg1MCAobm8gd2Vla2RheSkKICAgICAgICAgJzAzLUZlYi0xOTk0IDAwOjAwIEdNVCcsICAjIGJyb2tlbiByZmM4NTAgKG5vIHdlZWtkYXksIG5vIHNlY29uZHMpCiAgICAgICAgICcwMy1GZWItMTk5NCAwMDowMCcsICAjIGJyb2tlbiByZmM4NTAgKG5vIHdlZWtkYXksIG5vIHNlY29uZHMsIG5vIHR6KQoKICAgICAgICAgJzAzLUZlYi05NCcsICAjIG9sZCByZmM4NTAgSFRUUCBmb3JtYXQgKG5vIHdlZWtkYXksIG5vIHRpbWUpCiAgICAgICAgICcwMy1GZWItMTk5NCcsICAjIGJyb2tlbiByZmM4NTAgSFRUUCBmb3JtYXQgKG5vIHdlZWtkYXksIG5vIHRpbWUpCiAgICAgICAgICcwMyBGZWIgMTk5NCcsICAjIHByb3Bvc2VkIG5ldyBIVFRQIGZvcm1hdCAobm8gd2Vla2RheSwgbm8gdGltZSkKCiAgICAgICAgICMgQSBmZXcgdGVzdHMgd2l0aCBleHRyYSBzcGFjZSBhdCB2YXJpb3VzIHBsYWNlcwogICAgICAgICAnICAwMyAgIEZlYiAgIDE5OTQgIDA6MDAgICcsCiAgICAgICAgICcgIDAzLUZlYi0xOTk0ICAnLAogICAgICAgIF0KCiAgICAgICAgdGVzdF90ID0gNzYwMjMzNjAwICAjIGFzc3VtZSBicm9rZW4gUE9TSVggY291bnRpbmcgb2Ygc2Vjb25kcwogICAgICAgIHJlc3VsdCA9IHRpbWUyaXNveih0ZXN0X3QpCiAgICAgICAgZXhwZWN0ZWQgPSAiMTk5NC0wMi0wMyAwMDowMDowMFoiCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyZXN1bHQsIGV4cGVjdGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgIiVzICA9PiAgJyVzJyAoJXMpIiAlICh0ZXN0X3QsIHJlc3VsdCwgZXhwZWN0ZWQpKQoKICAgICAgICBmb3IgcyBpbiB0ZXN0czoKICAgICAgICAgICAgdCA9IGh0dHAydGltZShzKQogICAgICAgICAgICB0MiA9IGh0dHAydGltZShzLmxvd2VyKCkpCiAgICAgICAgICAgIHQzID0gaHR0cDJ0aW1lKHMudXBwZXIoKSkKCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh0ID09IHQyID09IHQzID09IHRlc3RfdCwKICAgICAgICAgICAgICAgICAgICAgICAgICInJXMnICA9PiAgJXMsICVzLCAlcyAoJXMpIiAlIChzLCB0LCB0MiwgdDMsIHRlc3RfdCkpCgogICAgZGVmIHRlc3RfaHR0cDJ0aW1lX2dhcmJhZ2Uoc2VsZik6CiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IGh0dHAydGltZQoKICAgICAgICBmb3IgdGVzdCBpbiBbCiAgICAgICAgICAgICcnLAogICAgICAgICAgICAnR2FyYmFnZScsCiAgICAgICAgICAgICdNYW5kYWcgMTYuIFNlcHRlbWJlciAxOTk2JywKICAgICAgICAgICAgJzAxLTAwLTE5ODAnLAogICAgICAgICAgICAnMDEtMTMtMTk4MCcsCiAgICAgICAgICAgICcwMC0wMS0xOTgwJywKICAgICAgICAgICAgJzMyLTAxLTE5ODAnLAogICAgICAgICAgICAnMDEtMDEtMTk4MCAyNTowMDowMCcsCiAgICAgICAgICAgICcwMS0wMS0xOTgwIDAwOjYxOjAwJywKICAgICAgICAgICAgJzAxLTAxLTE5ODAgMDA6MDA6NjInLAogICAgICAgICAgICBdOgogICAgICAgICAgICBzZWxmLmFzc2VydFRydWUoaHR0cDJ0aW1lKHRlc3QpIGlzIE5vbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAiaHR0cDJ0aW1lKCVzKSBpcyBub3QgTm9uZVxuIgogICAgICAgICAgICAgICAgICAgICAgICAgImh0dHAydGltZSh0ZXN0KSAlcyIgJSAodGVzdCwgaHR0cDJ0aW1lKHRlc3QpKQogICAgICAgICAgICAgICAgICAgICAgICAgKQoKCmNsYXNzIEhlYWRlclRlc3RzKFRlc3RDYXNlKToKCiAgICBkZWYgdGVzdF9wYXJzZV9uc19oZWFkZXJzX2V4cGlyZXMoc2VsZik6CiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IHBhcnNlX25zX2hlYWRlcnMKCiAgICAgICAgIyBxdW90ZXMgc2hvdWxkIGJlIHN0cmlwcGVkCiAgICAgICAgZXhwZWN0ZWQgPSBbWygnZm9vJywgJ2JhcicpLCAoJ2V4cGlyZXMnLCAyMjA5MDY5NDEyTCksICgndmVyc2lvbicsICcwJyldXQogICAgICAgIGZvciBoZHIgaW4gWwogICAgICAgICAgICAnZm9vPWJhcjsgZXhwaXJlcz0wMSBKYW4gMjA0MCAyMjoyMzozMiBHTVQnLAogICAgICAgICAgICAnZm9vPWJhcjsgZXhwaXJlcz0iMDEgSmFuIDIwNDAgMjI6MjM6MzIgR01UIicsCiAgICAgICAgICAgIF06CiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocGFyc2VfbnNfaGVhZGVycyhbaGRyXSksIGV4cGVjdGVkKQoKICAgIGRlZiB0ZXN0X3BhcnNlX25zX2hlYWRlcnNfdmVyc2lvbihzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgcGFyc2VfbnNfaGVhZGVycwoKICAgICAgICAjIHF1b3RlcyBzaG91bGQgYmUgc3RyaXBwZWQKICAgICAgICBleHBlY3RlZCA9IFtbKCdmb28nLCAnYmFyJyksICgndmVyc2lvbicsICcxJyldXQogICAgICAgIGZvciBoZHIgaW4gWwogICAgICAgICAgICAnZm9vPWJhcjsgdmVyc2lvbj0iMSInLAogICAgICAgICAgICAnZm9vPWJhcjsgVmVyc2lvbj0iMSInLAogICAgICAgICAgICBdOgogICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHBhcnNlX25zX2hlYWRlcnMoW2hkcl0pLCBleHBlY3RlZCkKCiAgICBkZWYgdGVzdF9wYXJzZV9uc19oZWFkZXJzX3NwZWNpYWxfbmFtZXMoc2VsZik6CiAgICAgICAgIyBuYW1lcyBzdWNoIGFzICdleHBpcmVzJyBhcmUgbm90IHNwZWNpYWwgaW4gZmlyc3QgbmFtZT12YWx1ZSBwYWlyCiAgICAgICAgIyBvZiBTZXQtQ29va2llOiBoZWFkZXIKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgcGFyc2VfbnNfaGVhZGVycwoKICAgICAgICAjIENvb2tpZSB3aXRoIG5hbWUgJ2V4cGlyZXMnCiAgICAgICAgaGRyID0gJ2V4cGlyZXM9MDEgSmFuIDIwNDAgMjI6MjM6MzIgR01UJwogICAgICAgIGV4cGVjdGVkID0gW1soImV4cGlyZXMiLCAiMDEgSmFuIDIwNDAgMjI6MjM6MzIgR01UIiksICgidmVyc2lvbiIsICIwIildXQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocGFyc2VfbnNfaGVhZGVycyhbaGRyXSksIGV4cGVjdGVkKQoKICAgIGRlZiB0ZXN0X2pvaW5faGVhZGVyX3dvcmRzKHNlbGYpOgogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBqb2luX2hlYWRlcl93b3JkcwoKICAgICAgICBqb2luZWQgPSBqb2luX2hlYWRlcl93b3JkcyhbWygiZm9vIiwgTm9uZSksICgiYmFyIiwgImJheiIpXV0pCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChqb2luZWQsICJmb287IGJhcj1iYXoiKQoKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGpvaW5faGVhZGVyX3dvcmRzKFtbXV0pLCAiIikKCiAgICBkZWYgdGVzdF9zcGxpdF9oZWFkZXJfd29yZHMoc2VsZik6CiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IHNwbGl0X2hlYWRlcl93b3JkcwoKICAgICAgICB0ZXN0cyA9IFsKICAgICAgICAgICAgKCJmb28iLCBbWygiZm9vIiwgTm9uZSldXSksCiAgICAgICAgICAgICgiZm9vPWJhciIsIFtbKCJmb28iLCAiYmFyIildXSksCiAgICAgICAgICAgICgiICAgZm9vICAgIiwgW1soImZvbyIsIE5vbmUpXV0pLAogICAgICAgICAgICAoIiAgIGZvbz0gICAiLCBbWygiZm9vIiwgIiIpXV0pLAogICAgICAgICAgICAoIiAgIGZvbz0iLCBbWygiZm9vIiwgIiIpXV0pLAogICAgICAgICAgICAoIiAgIGZvbz0gICA7ICIsIFtbKCJmb28iLCAiIildXSksCiAgICAgICAgICAgICgiICAgZm9vPSAgIDsgYmFyPSBiYXogIiwgW1soImZvbyIsICIiKSwgKCJiYXIiLCAiYmF6IildXSksCiAgICAgICAgICAgICgiZm9vPWJhciBiYXI9YmF6IiwgW1soImZvbyIsICJiYXIiKSwgKCJiYXIiLCAiYmF6IildXSksCiAgICAgICAgICAgICMgZG9lc24ndCByZWFsbHkgbWF0dGVyIGlmIHRoaXMgbmV4dCBmYWlscywgYnV0IGl0IHdvcmtzIEFUTQogICAgICAgICAgICAoImZvbz0gYmFyPWJheiIsIFtbKCJmb28iLCAiYmFyPWJheiIpXV0pLAogICAgICAgICAgICAoImZvbz1iYXI7YmFyPWJheiIsIFtbKCJmb28iLCAiYmFyIiksICgiYmFyIiwgImJheiIpXV0pLAogICAgICAgICAgICAoJ2ZvbyBiYXIgYmF6JywgW1soImZvbyIsIE5vbmUpLCAoImJhciIsIE5vbmUpLCAoImJheiIsIE5vbmUpXV0pLAogICAgICAgICAgICAoImEsIGIsIGMiLCBbWygiYSIsIE5vbmUpXSwgWygiYiIsIE5vbmUpXSwgWygiYyIsIE5vbmUpXV0pLAogICAgICAgICAgICAocidmb287IGJhcj1iYXosIHNwYW09LCBmb289IlwsXDtcIiIsIGJhcj0gJywKICAgICAgICAgICAgIFtbKCJmb28iLCBOb25lKSwgKCJiYXIiLCAiYmF6IildLAogICAgICAgICAgICAgIFsoInNwYW0iLCAiIildLCBbKCJmb28iLCAnLDsiJyldLCBbKCJiYXIiLCAiIildXSksCiAgICAgICAgICAgIF0KCiAgICAgICAgZm9yIGFyZywgZXhwZWN0IGluIHRlc3RzOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICByZXN1bHQgPSBzcGxpdF9oZWFkZXJfd29yZHMoW2FyZ10pCiAgICAgICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgICAgIGltcG9ydCB0cmFjZWJhY2ssIFN0cmluZ0lPCiAgICAgICAgICAgICAgICBmID0gU3RyaW5nSU8uU3RyaW5nSU8oKQogICAgICAgICAgICAgICAgdHJhY2ViYWNrLnByaW50X2V4YyhOb25lLCBmKQogICAgICAgICAgICAgICAgcmVzdWx0ID0gIihlcnJvciAtLSB0cmFjZWJhY2sgZm9sbG93cylcblxuJXMiICUgZi5nZXR2YWx1ZSgpCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0LCAgZXhwZWN0LCAiIiIKV2hlbiBwYXJzaW5nOiAnJXMnCkV4cGVjdGVkOiAgICAgJyVzJwpHb3Q6ICAgICAgICAgICclcycKIiIiICUgKGFyZywgZXhwZWN0LCByZXN1bHQpKQoKICAgIGRlZiB0ZXN0X3JvdW5kdHJpcChzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgc3BsaXRfaGVhZGVyX3dvcmRzLCBqb2luX2hlYWRlcl93b3JkcwoKICAgICAgICB0ZXN0cyA9IFsKICAgICAgICAgICAgKCJmb28iLCAiZm9vIiksCiAgICAgICAgICAgICgiZm9vPWJhciIsICJmb289YmFyIiksCiAgICAgICAgICAgICgiICAgZm9vICAgIiwgImZvbyIpLAogICAgICAgICAgICAoImZvbz0iLCAnZm9vPSIiJyksCiAgICAgICAgICAgICgiZm9vPWJhciBiYXI9YmF6IiwgImZvbz1iYXI7IGJhcj1iYXoiKSwKICAgICAgICAgICAgKCJmb289YmFyO2Jhcj1iYXoiLCAiZm9vPWJhcjsgYmFyPWJheiIpLAogICAgICAgICAgICAoJ2ZvbyBiYXIgYmF6JywgImZvbzsgYmFyOyBiYXoiKSwKICAgICAgICAgICAgKHInZm9vPSJcIiIgYmFyPSJcXCInLCByJ2Zvbz0iXCIiOyBiYXI9IlxcIicpLAogICAgICAgICAgICAoJ2ZvbywsLGJhcicsICdmb28sIGJhcicpLAogICAgICAgICAgICAoJ2Zvbz1iYXIsYmFyPWJheicsICdmb289YmFyLCBiYXI9YmF6JyksCgogICAgICAgICAgICAoJ3RleHQvaHRtbDsgY2hhcnNldD1pc28tODg1OS0xJywKICAgICAgICAgICAgICd0ZXh0L2h0bWw7IGNoYXJzZXQ9Imlzby04ODU5LTEiJyksCgogICAgICAgICAgICAoJ2Zvbz0iYmFyIjsgcG9ydD0iODAsODEiOyBkaXNjYXJkLCBiYXI9YmF6JywKICAgICAgICAgICAgICdmb289YmFyOyBwb3J0PSI4MCw4MSI7IGRpc2NhcmQsIGJhcj1iYXonKSwKCiAgICAgICAgICAgIChyJ0Jhc2ljIHJlYWxtPSJcImZvb1xcXFxiYXJcIiInLAogICAgICAgICAgICAgcidCYXNpYzsgcmVhbG09IlwiZm9vXFxcXGJhclwiIicpCiAgICAgICAgICAgIF0KCiAgICAgICAgZm9yIGFyZywgZXhwZWN0IGluIHRlc3RzOgogICAgICAgICAgICBpbnB1dCA9IHNwbGl0X2hlYWRlcl93b3JkcyhbYXJnXSkKICAgICAgICAgICAgcmVzID0gam9pbl9oZWFkZXJfd29yZHMoaW5wdXQpCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzLCBleHBlY3QsICIiIgpXaGVuIHBhcnNpbmc6ICclcycKRXhwZWN0ZWQ6ICAgICAnJXMnCkdvdDogICAgICAgICAgJyVzJwpJbnB1dCB3YXM6ICAgICclcycKIiIiICUgKGFyZywgZXhwZWN0LCByZXMsIGlucHV0KSkKCgpjbGFzcyBGYWtlUmVzcG9uc2U6CiAgICBkZWYgX19pbml0X18oc2VsZiwgaGVhZGVycz1bXSwgdXJsPU5vbmUpOgogICAgICAgICIiIgogICAgICAgIGhlYWRlcnM6IGxpc3Qgb2YgUkZDODIyLXN0eWxlICdLZXk6IHZhbHVlJyBzdHJpbmdzCiAgICAgICAgIiIiCiAgICAgICAgaW1wb3J0IG1pbWV0b29scywgU3RyaW5nSU8KICAgICAgICBmID0gU3RyaW5nSU8uU3RyaW5nSU8oIlxuIi5qb2luKGhlYWRlcnMpKQogICAgICAgIHNlbGYuX2hlYWRlcnMgPSBtaW1ldG9vbHMuTWVzc2FnZShmKQogICAgICAgIHNlbGYuX3VybCA9IHVybAogICAgZGVmIGluZm8oc2VsZik6IHJldHVybiBzZWxmLl9oZWFkZXJzCgpkZWYgaW50ZXJhY3RfMjk2NShjb29raWVqYXIsIHVybCwgKnNldF9jb29raWVfaGRycyk6CiAgICByZXR1cm4gX2ludGVyYWN0KGNvb2tpZWphciwgdXJsLCBzZXRfY29va2llX2hkcnMsICJTZXQtQ29va2llMiIpCgpkZWYgaW50ZXJhY3RfbmV0c2NhcGUoY29va2llamFyLCB1cmwsICpzZXRfY29va2llX2hkcnMpOgogICAgcmV0dXJuIF9pbnRlcmFjdChjb29raWVqYXIsIHVybCwgc2V0X2Nvb2tpZV9oZHJzLCAiU2V0LUNvb2tpZSIpCgpkZWYgX2ludGVyYWN0KGNvb2tpZWphciwgdXJsLCBzZXRfY29va2llX2hkcnMsIGhkcl9uYW1lKToKICAgICIiIlBlcmZvcm0gYSBzaW5nbGUgcmVxdWVzdCAvIHJlc3BvbnNlIGN5Y2xlLCByZXR1cm5pbmcgQ29va2llOiBoZWFkZXIuIiIiCiAgICBmcm9tIHVybGxpYjIgaW1wb3J0IFJlcXVlc3QKICAgIHJlcSA9IFJlcXVlc3QodXJsKQogICAgY29va2llamFyLmFkZF9jb29raWVfaGVhZGVyKHJlcSkKICAgIGNvb2tpZV9oZHIgPSByZXEuZ2V0X2hlYWRlcigiQ29va2llIiwgIiIpCiAgICBoZWFkZXJzID0gW10KICAgIGZvciBoZHIgaW4gc2V0X2Nvb2tpZV9oZHJzOgogICAgICAgIGhlYWRlcnMuYXBwZW5kKCIlczogJXMiICUgKGhkcl9uYW1lLCBoZHIpKQogICAgcmVzID0gRmFrZVJlc3BvbnNlKGhlYWRlcnMsIHVybCkKICAgIGNvb2tpZWphci5leHRyYWN0X2Nvb2tpZXMocmVzLCByZXEpCiAgICByZXR1cm4gY29va2llX2hkcgoKCmNsYXNzIEZpbGVDb29raWVKYXJUZXN0cyhUZXN0Q2FzZSk6CiAgICBkZWYgdGVzdF9sd3BfdmFsdWVsZXNzX2Nvb2tpZShzZWxmKToKICAgICAgICAjIGNvb2tpZXMgd2l0aCBubyB2YWx1ZSBzaG91bGQgYmUgc2F2ZWQgYW5kIGxvYWRlZCBjb25zaXN0ZW50bHkKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgTFdQQ29va2llSmFyCiAgICAgICAgZmlsZW5hbWUgPSB0ZXN0X3N1cHBvcnQuVEVTVEZOCiAgICAgICAgYyA9IExXUENvb2tpZUphcigpCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIiwgJ2JvbycpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXVsiLyJdWyJib28iXS52YWx1ZSwgTm9uZSkKICAgICAgICB0cnk6CiAgICAgICAgICAgIGMuc2F2ZShmaWxlbmFtZSwgaWdub3JlX2Rpc2NhcmQ9VHJ1ZSkKICAgICAgICAgICAgYyA9IExXUENvb2tpZUphcigpCiAgICAgICAgICAgIGMubG9hZChmaWxlbmFtZSwgaWdub3JlX2Rpc2NhcmQ9VHJ1ZSkKICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICB0cnk6IG9zLnVubGluayhmaWxlbmFtZSkKICAgICAgICAgICAgZXhjZXB0IE9TRXJyb3I6IHBhc3MKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdWyIvIl1bImJvbyJdLnZhbHVlLCBOb25lKQoKICAgIGRlZiB0ZXN0X2JhZF9tYWdpYyhzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgTFdQQ29va2llSmFyLCBNb3ppbGxhQ29va2llSmFyLCBMb2FkRXJyb3IKICAgICAgICAjIElPRXJyb3JzIChlZy4gZmlsZSBkb2Vzbid0IGV4aXN0KSBhcmUgYWxsb3dlZCB0byBwcm9wYWdhdGUKICAgICAgICBmaWxlbmFtZSA9IHRlc3Rfc3VwcG9ydC5URVNURk4KICAgICAgICBmb3IgY29va2llamFyX2NsYXNzIGluIExXUENvb2tpZUphciwgTW96aWxsYUNvb2tpZUphcjoKICAgICAgICAgICAgYyA9IGNvb2tpZWphcl9jbGFzcygpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGMubG9hZChmaWxlbmFtZT0iZm9yIHRoaXMgdGVzdCB0byB3b3JrLCBhIGZpbGUgd2l0aCB0aGlzICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlsZW5hbWUgc2hvdWxkIG5vdCBleGlzdCIpCiAgICAgICAgICAgIGV4Y2VwdCBJT0Vycm9yLCBleGM6CiAgICAgICAgICAgICAgICAjIGV4YWN0bHkgSU9FcnJvciwgbm90IExvYWRFcnJvcgogICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChleGMuX19jbGFzc19fLCBJT0Vycm9yKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5mYWlsKCJleHBlY3RlZCBJT0Vycm9yIGZvciBpbnZhbGlkIGZpbGVuYW1lIikKICAgICAgICAjIEludmFsaWQgY29udGVudHMgb2YgY29va2llcyBmaWxlIChlZy4gYmFkIG1hZ2ljIHN0cmluZykKICAgICAgICAjIGNhdXNlcyBhIExvYWRFcnJvci4KICAgICAgICB0cnk6CiAgICAgICAgICAgIGYgPSBvcGVuKGZpbGVuYW1lLCAidyIpCiAgICAgICAgICAgIGYud3JpdGUoIm9vcHNcbiIpCiAgICAgICAgICAgIGZvciBjb29raWVqYXJfY2xhc3MgaW4gTFdQQ29va2llSmFyLCBNb3ppbGxhQ29va2llSmFyOgogICAgICAgICAgICAgICAgYyA9IGNvb2tpZWphcl9jbGFzcygpCiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhMb2FkRXJyb3IsIGMubG9hZCwgZmlsZW5hbWUpCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgdHJ5OiBvcy51bmxpbmsoZmlsZW5hbWUpCiAgICAgICAgICAgIGV4Y2VwdCBPU0Vycm9yOiBwYXNzCgpjbGFzcyBDb29raWVUZXN0cyhUZXN0Q2FzZSk6CiAgICAjIFhYWAogICAgIyBHZXQgcmlkIG9mIHN0cmluZyBjb21wYXJpc29ucyB3aGVyZSBub3QgYWN0dWFsbHkgdGVzdGluZyBzdHIgLyByZXByLgogICAgIyAuY2xlYXIoKSBldGMuCiAgICAjIElQIGFkZHJlc3NlcyBsaWtlIDUwIChzaW5nbGUgbnVtYmVyLCBubyBkb3QpIGFuZCBkb21haW4tbWF0Y2hpbmcKICAgICMgIGZ1bmN0aW9ucyAoYW5kIGlzX0hETik/ICBTZWUgZHJhZnQgUkZDIDI5NjUgZXJyYXRhLgogICAgIyBTdHJpY3RuZXNzIHN3aXRjaGVzCiAgICAjIGlzX3RoaXJkX3BhcnR5KCkKICAgICMgdW52ZXJpZmlhYmlsaXR5IC8gdGhpcmQtcGFydHkgYmxvY2tpbmcKICAgICMgTmV0c2NhcGUgY29va2llcyB3b3JrIHRoZSBzYW1lIGFzIFJGQyAyOTY1IHdpdGggcmVnYXJkIHRvIHBvcnQuCiAgICAjIFNldC1Db29raWUgd2l0aCBuZWdhdGl2ZSBtYXggYWdlLgogICAgIyBJZiB0dXJuIFJGQyAyOTY1IGhhbmRsaW5nIG9mZiwgU2V0LUNvb2tpZTIgY29va2llcyBzaG91bGQgbm90IGNsb2JiZXIKICAgICMgIFNldC1Db29raWUgY29va2llcy4KICAgICMgQ29va2llMiBzaG91bGQgYmUgc2VudCBpZiAqYW55KiBjb29raWVzIGFyZSBub3QgVjEgKGllLiBWMCBPUiBWMiBldGMuKS4KICAgICMgQ29va2llcyAoVjEgYW5kIFYwKSB3aXRoIG5vIGV4cGlyeSBkYXRlIHNob3VsZCBiZSBzZXQgdG8gYmUgZGlzY2FyZGVkLgogICAgIyBSRkMgMjk2NSBRdW90aW5nOgogICAgIyAgU2hvdWxkIGFjY2VwdCB1bnF1b3RlZCBjb29raWUtYXR0cmlidXRlIHZhbHVlcz8gIGNoZWNrIGVycmF0YSBkcmFmdC4KICAgICMgICBXaGljaCBhcmUgcmVxdWlyZWQgb24gdGhlIHdheSBpbiBhbmQgb3V0PwogICAgIyAgU2hvdWxkIGFsd2F5cyByZXR1cm4gcXVvdGVkIGNvb2tpZS1hdHRyaWJ1dGUgdmFsdWVzPwogICAgIyBQcm9wZXIgdGVzdGluZyBvZiB3aGVuIFJGQyAyOTY1IGNsb2JiZXJzIE5ldHNjYXBlICh3YWl0aW5nIGZvciBlcnJhdGEpLgogICAgIyBQYXRoLW1hdGNoIG9uIHJldHVybiAoc2FtZSBmb3IgVjAgYW5kIFYxKS4KICAgICMgUkZDIDI5NjUgYWNjZXB0YW5jZSBhbmQgcmV0dXJuaW5nIHJ1bGVzCiAgICAjICBTZXQtQ29va2llMiB3aXRob3V0IHZlcnNpb24gYXR0cmlidXRlIGlzIHJlamVjdGVkLgoKICAgICMgTmV0c2NhcGUgcGVjdWxpYXJpdGllcyBsaXN0IGZyb20gUm9uYWxkIFRzY2hhbGFyLgogICAgIyBUaGUgZmlyc3QgdHdvIHN0aWxsIG5lZWQgdGVzdHMsIHRoZSByZXN0IGFyZSBjb3ZlcmVkLgojIyAtIFF1b3Rpbmc6IG9ubHkgcXVvdGVzIGFyb3VuZCB0aGUgZXhwaXJlcyB2YWx1ZSBhcmUgcmVjb2duaXplZCBhcyBzdWNoCiMjICAgKGFuZCB5ZXMsIHNvbWUgZm9sa3MgcXVvdGUgdGhlIGV4cGlyZXMgdmFsdWUpOyBxdW90ZXMgYXJvdW5kIGFueSBvdGhlcgojIyAgIHZhbHVlIGFyZSB0cmVhdGVkIGFzIHBhcnQgb2YgdGhlIHZhbHVlLgojIyAtIFdoaXRlIHNwYWNlOiB3aGl0ZSBzcGFjZSBhcm91bmQgbmFtZXMgYW5kIHZhbHVlcyBpcyBpZ25vcmVkCiMjIC0gRGVmYXVsdCBwYXRoOiBpZiBubyBwYXRoIHBhcmFtZXRlciBpcyBnaXZlbiwgdGhlIHBhdGggZGVmYXVsdHMgdG8gdGhlCiMjICAgcGF0aCBpbiB0aGUgcmVxdWVzdC11cmkgdXAgdG8sIGJ1dCBub3QgaW5jbHVkaW5nLCB0aGUgbGFzdCAnLycuIE5vdGUKIyMgICB0aGF0IHRoaXMgaXMgZW50aXJlbHkgZGlmZmVyZW50IGZyb20gd2hhdCB0aGUgc3BlYyBzYXlzLgojIyAtIENvbW1hcyBhbmQgb3RoZXIgZGVsaW1pdGVyczogTmV0c2NhcGUganVzdCBwYXJzZXMgdW50aWwgdGhlIG5leHQgJzsnLgojIyAgIFRoaXMgbWVhbnMgaXQgd2lsbCBhbGxvdyBjb21tYXMgZXRjIGluc2lkZSB2YWx1ZXMgKGFuZCB5ZXMsIGJvdGgKIyMgICBjb21tYXMgYW5kIGVxdWFscyBhcmUgY29tbW9ubHkgYXBwZWFyIGluIHRoZSBjb29raWUgdmFsdWUpLiBUaGlzIGFsc28KIyMgICBtZWFucyB0aGF0IGlmIHlvdSBmb2xkIG11bHRpcGxlIFNldC1Db29raWUgaGVhZGVyIGZpZWxkcyBpbnRvIG9uZSwKIyMgICBjb21tYS1zZXBhcmF0ZWQgbGlzdCwgaXQnbGwgYmUgYSBoZWFkYWNoZSB0byBwYXJzZSAoYXQgbGVhc3QgbXkgaGVhZAojIyAgIHN0YXJ0cyBodXJ0aW5nIGV2ZXJ5dGltZSBJIHRoaW5rIG9mIHRoYXQgY29kZSkuCiMjIC0gRXhwaXJlczogWW91J2xsIGdldCBhbGwgc29ydHMgb2YgZGF0ZSBmb3JtYXRzIGluIHRoZSBleHBpcmVzLAojIyAgIGluY2x1ZGluZyBlbXRweSBleHBpcmVzIGF0dHJpYnV0ZXMgKCJleHBpcmVzPSIpLiBCZSBhcyBmbGV4aWJsZSBhcyB5b3UKIyMgICBjYW4sIGFuZCBjZXJ0YWlubHkgZG9uJ3QgZXhwZWN0IHRoZSB3ZWVrZGF5IHRvIGJlIHRoZXJlOyBpZiB5b3UgY2FuJ3QKIyMgICBwYXJzZSBpdCwganVzdCBpZ25vcmUgaXQgYW5kIHByZXRlbmQgaXQncyBhIHNlc3Npb24gY29va2llLgojIyAtIERvbWFpbi1tYXRjaGluZzogTmV0c2NhcGUgdXNlcyB0aGUgMi1kb3QgcnVsZSBmb3IgX2FsbF8gZG9tYWlucywgbm90CiMjICAganVzdCB0aGUgNyBzcGVjaWFsIFRMRCdzIGxpc3RlZCBpbiB0aGVpciBzcGVjLiBBbmQgZm9sa3MgcmVseSBvbgojIyAgIHRoYXQuLi4KCiAgICBkZWYgdGVzdF9kb21haW5fcmV0dXJuX29rKHNlbGYpOgogICAgICAgICMgdGVzdCBvcHRpbWl6YXRpb246IC5kb21haW5fcmV0dXJuX29rKCkgc2hvdWxkIGZpbHRlciBvdXQgbW9zdAogICAgICAgICMgZG9tYWlucyBpbiB0aGUgQ29va2llSmFyIGJlZm9yZSB3ZSB0cnkgdG8gYWNjZXNzIHRoZW0gKGJlY2F1c2UgdGhhdAogICAgICAgICMgbWF5IHJlcXVpcmUgZGlzayBhY2Nlc3MgLS0gaW4gcGFydGljdWxhciwgd2l0aCBNU0lFQ29va2llSmFyKQogICAgICAgICMgVGhpcyBpcyBvbmx5IGEgcm91Z2ggY2hlY2sgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMsIHNvIGl0J3Mgbm90IHRvbwogICAgICAgICMgY3JpdGljYWwgYXMgbG9uZyBhcyBpdCdzIHN1ZmZpY2llbnRseSBsaWJlcmFsLgogICAgICAgIGltcG9ydCBjb29raWVsaWIsIHVybGxpYjIKICAgICAgICBwb2wgPSBjb29raWVsaWIuRGVmYXVsdENvb2tpZVBvbGljeSgpCiAgICAgICAgZm9yIHVybCwgZG9tYWluLCBvayBpbiBbCiAgICAgICAgICAgICgiaHR0cDovL2Zvby5iYXIuY29tLyIsICJibGFoLmNvbSIsIEZhbHNlKSwKICAgICAgICAgICAgKCJodHRwOi8vZm9vLmJhci5jb20vIiwgInJodWJhcmIuYmxhaC5jb20iLCBGYWxzZSksCiAgICAgICAgICAgICgiaHR0cDovL2Zvby5iYXIuY29tLyIsICJyaHViYXJiLmZvby5iYXIuY29tIiwgRmFsc2UpLAogICAgICAgICAgICAoImh0dHA6Ly9mb28uYmFyLmNvbS8iLCAiLmZvby5iYXIuY29tIiwgVHJ1ZSksCiAgICAgICAgICAgICgiaHR0cDovL2Zvby5iYXIuY29tLyIsICJmb28uYmFyLmNvbSIsIFRydWUpLAogICAgICAgICAgICAoImh0dHA6Ly9mb28uYmFyLmNvbS8iLCAiLmJhci5jb20iLCBUcnVlKSwKICAgICAgICAgICAgKCJodHRwOi8vZm9vLmJhci5jb20vIiwgImNvbSIsIFRydWUpLAogICAgICAgICAgICAoImh0dHA6Ly9mb28uY29tLyIsICJyaHViYXJiLmZvby5jb20iLCBGYWxzZSksCiAgICAgICAgICAgICgiaHR0cDovL2Zvby5jb20vIiwgIi5mb28uY29tIiwgVHJ1ZSksCiAgICAgICAgICAgICgiaHR0cDovL2Zvby5jb20vIiwgImZvby5jb20iLCBUcnVlKSwKICAgICAgICAgICAgKCJodHRwOi8vZm9vLmNvbS8iLCAiY29tIiwgVHJ1ZSksCiAgICAgICAgICAgICgiaHR0cDovL2Zvby8iLCAicmh1YmFyYi5mb28iLCBGYWxzZSksCiAgICAgICAgICAgICgiaHR0cDovL2Zvby8iLCAiLmZvbyIsIFRydWUpLAogICAgICAgICAgICAoImh0dHA6Ly9mb28vIiwgImZvbyIsIFRydWUpLAogICAgICAgICAgICAoImh0dHA6Ly9mb28vIiwgImZvby5sb2NhbCIsIFRydWUpLAogICAgICAgICAgICAoImh0dHA6Ly9mb28vIiwgIi5sb2NhbCIsIFRydWUpLAogICAgICAgICAgICBdOgogICAgICAgICAgICByZXF1ZXN0ID0gdXJsbGliMi5SZXF1ZXN0KHVybCkKICAgICAgICAgICAgciA9IHBvbC5kb21haW5fcmV0dXJuX29rKGRvbWFpbiwgcmVxdWVzdCkKICAgICAgICAgICAgaWYgb2s6IHNlbGYuYXNzZXJ0VHJ1ZShyKQogICAgICAgICAgICBlbHNlOiBzZWxmLmFzc2VydFRydWUobm90IHIpCgogICAgZGVmIHRlc3RfbWlzc2luZ192YWx1ZShzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgTW96aWxsYUNvb2tpZUphciwgbHdwX2Nvb2tpZV9zdHIKCiAgICAgICAgIyBtaXNzaW5nID0gc2lnbiBpbiBDb29raWU6IGhlYWRlciBpcyByZWdhcmRlZCBieSBNb3ppbGxhIGFzIGEgbWlzc2luZwogICAgICAgICMgbmFtZSwgYW5kIGJ5IGNvb2tpZWxpYiBhcyBhIG1pc3NpbmcgdmFsdWUKICAgICAgICBmaWxlbmFtZSA9IHRlc3Rfc3VwcG9ydC5URVNURk4KICAgICAgICBjID0gTW96aWxsYUNvb2tpZUphcihmaWxlbmFtZSkKICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLCAnZWdncycpCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIiwgJyJzcGFtIjsgcGF0aD0vZm9vLycpCiAgICAgICAgY29va2llID0gYy5fY29va2llc1sid3d3LmFjbWUuY29tIl1bIi8iXVsiZWdncyJdCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGNvb2tpZS52YWx1ZSBpcyBOb25lKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY29va2llLm5hbWUsICJlZ2dzIikKICAgICAgICBjb29raWUgPSBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXVsnL2Zvby8nXVsnInNwYW0iJ10KICAgICAgICBzZWxmLmFzc2VydFRydWUoY29va2llLnZhbHVlIGlzIE5vbmUpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjb29raWUubmFtZSwgJyJzcGFtIicpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsd3BfY29va2llX3N0cihjb29raWUpLCAoCiAgICAgICAgICAgIHInInNwYW0iOyBwYXRoPSIvZm9vLyI7IGRvbWFpbj0id3d3LmFjbWUuY29tIjsgJwogICAgICAgICAgICAncGF0aF9zcGVjOyBkaXNjYXJkOyB2ZXJzaW9uPTAnKSkKICAgICAgICBvbGRfc3RyID0gcmVwcihjKQogICAgICAgIGMuc2F2ZShpZ25vcmVfZXhwaXJlcz1UcnVlLCBpZ25vcmVfZGlzY2FyZD1UcnVlKQogICAgICAgIHRyeToKICAgICAgICAgICAgYyA9IE1vemlsbGFDb29raWVKYXIoZmlsZW5hbWUpCiAgICAgICAgICAgIGMucmV2ZXJ0KGlnbm9yZV9leHBpcmVzPVRydWUsIGlnbm9yZV9kaXNjYXJkPVRydWUpCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgb3MudW5saW5rKGMuZmlsZW5hbWUpCiAgICAgICAgIyBjb29raWVzIHVuY2hhbmdlZCBhcGFydCBmcm9tIGxvc3QgaW5mbyByZS4gd2hldGhlciBwYXRoIHdhcyBzcGVjaWZpZWQKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKAogICAgICAgICAgICByZXByKGMpLAogICAgICAgICAgICByZS5zdWIoInBhdGhfc3BlY2lmaWVkPSVzIiAlIFRydWUsICJwYXRoX3NwZWNpZmllZD0lcyIgJSBGYWxzZSwKICAgICAgICAgICAgICAgICAgIG9sZF9zdHIpCiAgICAgICAgICAgICkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2Zvby8iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICcic3BhbSI7IGVnZ3MnKQoKICAgIGRlZiB0ZXN0X3JmYzIxMDlfaGFuZGxpbmcoc2VsZik6CiAgICAgICAgIyBSRkMgMjEwOSBjb29raWVzIGFyZSBoYW5kbGVkIGFzIFJGQyAyOTY1IG9yIE5ldHNjYXBlIGNvb2tpZXMsCiAgICAgICAgIyBkZXBlbmRlbnQgb24gcG9saWN5IHNldHRpbmdzCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphciwgRGVmYXVsdENvb2tpZVBvbGljeQoKICAgICAgICBmb3IgcmZjMjEwOV9hc19uZXRzY2FwZSwgcmZjMjk2NSwgdmVyc2lvbiBpbiBbCiAgICAgICAgICAgICMgZGVmYXVsdCBhY2NvcmRpbmcgdG8gcmZjMjk2NSBpZiBub3QgZXhwbGljaXRseSBzcGVjaWZpZWQKICAgICAgICAgICAgKE5vbmUsIEZhbHNlLCAwKSwKICAgICAgICAgICAgKE5vbmUsIFRydWUsIDEpLAogICAgICAgICAgICAjIGV4cGxpY2l0IHJmYzIxMDlfYXNfbmV0c2NhcGUKICAgICAgICAgICAgKEZhbHNlLCBGYWxzZSwgTm9uZSksICAjIHZlcnNpb24gTm9uZSBoZXJlIG1lYW5zIG5vIGNvb2tpZSBzdG9yZWQKICAgICAgICAgICAgKEZhbHNlLCBUcnVlLCAxKSwKICAgICAgICAgICAgKFRydWUsIEZhbHNlLCAwKSwKICAgICAgICAgICAgKFRydWUsIFRydWUsIDApLAogICAgICAgICAgICBdOgogICAgICAgICAgICBwb2xpY3kgPSBEZWZhdWx0Q29va2llUG9saWN5KAogICAgICAgICAgICAgICAgcmZjMjEwOV9hc19uZXRzY2FwZT1yZmMyMTA5X2FzX25ldHNjYXBlLAogICAgICAgICAgICAgICAgcmZjMjk2NT1yZmMyOTY1KQogICAgICAgICAgICBjID0gQ29va2llSmFyKHBvbGljeSkKICAgICAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vIiwgIm5pPW5pOyBWZXJzaW9uPTEiKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBjb29raWUgPSBjLl9jb29raWVzWyJ3d3cuZXhhbXBsZS5jb20iXVsiLyJdWyJuaSJdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh2ZXJzaW9uIGlzIE5vbmUpICAjIGRpZG4ndCBleHBlY3QgYSBzdG9yZWQgY29va2llCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGNvb2tpZS52ZXJzaW9uLCB2ZXJzaW9uKQogICAgICAgICAgICAgICAgIyAyOTY1IGNvb2tpZXMgYXJlIHVuYWZmZWN0ZWQKICAgICAgICAgICAgICAgIGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZvbz1iYXI7IFZlcnNpb249MSIpCiAgICAgICAgICAgICAgICBpZiByZmMyOTY1OgogICAgICAgICAgICAgICAgICAgIGNvb2tpZTI5NjUgPSBjLl9jb29raWVzWyJ3d3cuZXhhbXBsZS5jb20iXVsiLyJdWyJmb28iXQogICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY29va2llMjk2NS52ZXJzaW9uLCAxKQoKICAgIGRlZiB0ZXN0X25zX3BhcnNlcihzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBERUZBVUxUX0hUVFBfUE9SVAoKICAgICAgICBjID0gQ29va2llSmFyKCkKICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICdzcGFtPWVnZ3M7IERvTWFpbj0uYWNtZS5jb207IHBvcnQ7IGJsQXJnaD0iZmVlcCInKQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIsICduaT1uaTsgcG9ydD04MCw4MDgwJykKICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbTo4MC8iLCAnbmluaT1uaScpCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb206ODAvIiwgJ2Zvbz1iYXI7IGV4cGlyZXM9JykKICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbTo4MC8iLCAnc3BhbT1lZ2dzOyAnCiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4cGlyZXM9IkZvbyBCYXIgMjUgMzM6MjI6MTEgMzAyMiInKQoKICAgICAgICBjb29raWUgPSBjLl9jb29raWVzWyIuYWNtZS5jb20iXVsiLyJdWyJzcGFtIl0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGNvb2tpZS5kb21haW4sICIuYWNtZS5jb20iKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShjb29raWUuZG9tYWluX3NwZWNpZmllZCkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGNvb2tpZS5wb3J0LCBERUZBVUxUX0hUVFBfUE9SVCkKICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGNvb2tpZS5wb3J0X3NwZWNpZmllZCkKICAgICAgICAjIGNhc2UgaXMgcHJlc2VydmVkCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGNvb2tpZS5oYXNfbm9uc3RhbmRhcmRfYXR0cigiYmxBcmdoIikgYW5kCiAgICAgICAgICAgICAgICAgICAgIG5vdCBjb29raWUuaGFzX25vbnN0YW5kYXJkX2F0dHIoImJsYXJnaCIpKQoKICAgICAgICBjb29raWUgPSBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXVsiLyJdWyJuaSJdCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjb29raWUuZG9tYWluLCAid3d3LmFjbWUuY29tIikKICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGNvb2tpZS5kb21haW5fc3BlY2lmaWVkKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY29va2llLnBvcnQsICI4MCw4MDgwIikKICAgICAgICBzZWxmLmFzc2VydFRydWUoY29va2llLnBvcnRfc3BlY2lmaWVkKQoKICAgICAgICBjb29raWUgPSBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXVsiLyJdWyJuaW5pIl0KICAgICAgICBzZWxmLmFzc2VydFRydWUoY29va2llLnBvcnQgaXMgTm9uZSkKICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGNvb2tpZS5wb3J0X3NwZWNpZmllZCkKCiAgICAgICAgIyBpbnZhbGlkIGV4cGlyZXMgc2hvdWxkIG5vdCBjYXVzZSBjb29raWUgdG8gYmUgZHJvcHBlZAogICAgICAgIGZvbyA9IGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdWyIvIl1bImZvbyJdCiAgICAgICAgc3BhbSA9IGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdWyIvIl1bImZvbyJdCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGZvby5leHBpcmVzIGlzIE5vbmUpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHNwYW0uZXhwaXJlcyBpcyBOb25lKQoKICAgIGRlZiB0ZXN0X25zX3BhcnNlcl9zcGVjaWFsX25hbWVzKHNlbGYpOgogICAgICAgICMgbmFtZXMgc3VjaCBhcyAnZXhwaXJlcycgYXJlIG5vdCBzcGVjaWFsIGluIGZpcnN0IG5hbWU9dmFsdWUgcGFpcgogICAgICAgICMgb2YgU2V0LUNvb2tpZTogaGVhZGVyCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphcgoKICAgICAgICBjID0gQ29va2llSmFyKCkKICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLCAnZXhwaXJlcz1lZ2dzJykKICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLCAndmVyc2lvbj1lZ2dzOyBzcGFtPWVnZ3MnKQoKICAgICAgICBjb29raWVzID0gYy5fY29va2llc1sid3d3LmFjbWUuY29tIl1bIi8iXQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSgnZXhwaXJlcycgaW4gY29va2llcykKICAgICAgICBzZWxmLmFzc2VydFRydWUoJ3ZlcnNpb24nIGluIGNvb2tpZXMpCgogICAgZGVmIHRlc3RfZXhwaXJlcyhzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgdGltZTJuZXRzY2FwZSwgQ29va2llSmFyCgogICAgICAgICMgaWYgZXhwaXJlcyBpcyBpbiBmdXR1cmUsIGtlZXAgY29va2llLi4uCiAgICAgICAgYyA9IENvb2tpZUphcigpCiAgICAgICAgZnV0dXJlID0gdGltZTJuZXRzY2FwZSh0aW1lLnRpbWUoKSszNjAwKQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIsICdzcGFtPSJiYXIiOyBleHBpcmVzPSVzJyAlCiAgICAgICAgICAgICAgICAgICAgICAgICAgZnV0dXJlKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQogICAgICAgIG5vdyA9IHRpbWUybmV0c2NhcGUodGltZS50aW1lKCktMSkKICAgICAgICAjIC4uLiBhbmQgaWYgaW4gcGFzdCBvciBwcmVzZW50LCBkaXNjYXJkIGl0CiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIiwgJ2Zvbz0iZWdncyI7IGV4cGlyZXM9JXMnICUKICAgICAgICAgICAgICAgICAgICAgICAgICBub3cpCiAgICAgICAgaCA9IGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDEpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKCdzcGFtPSJiYXIiJyBpbiBoIGFuZCAiZm9vIiBub3QgaW4gaCkKCiAgICAgICAgIyBtYXgtYWdlIHRha2VzIHByZWNlZGVuY2Ugb3ZlciBleHBpcmVzLCBhbmQgemVybyBtYXgtYWdlIGlzIHJlcXVlc3QgdG8KICAgICAgICAjIGRlbGV0ZSBib3RoIG5ldyBjb29raWUgYW5kIGFueSBvbGQgbWF0Y2hpbmcgY29va2llCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIiwgJ2VnZ3M9ImJhciI7IGV4cGlyZXM9JXMnICUKICAgICAgICAgICAgICAgICAgICAgICAgICBmdXR1cmUpCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIiwgJ2Jhcj0iYmFyIjsgZXhwaXJlcz0lcycgJQogICAgICAgICAgICAgICAgICAgICAgICAgIGZ1dHVyZSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMykKICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLCAnZWdncz0iYmFyIjsgJwogICAgICAgICAgICAgICAgICAgICAgICAgICdleHBpcmVzPSVzOyBtYXgtYWdlPTAnICUgZnV0dXJlKQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIsICdiYXI9ImJhciI7ICcKICAgICAgICAgICAgICAgICAgICAgICAgICAnbWF4LWFnZT0wOyBleHBpcmVzPSVzJyAlIGZ1dHVyZSkKICAgICAgICBoID0gaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMSkKCiAgICAgICAgIyB0ZXN0IGV4cGlyeSBhdCBlbmQgb2Ygc2Vzc2lvbiBmb3IgY29va2llcyB3aXRoIG5vIGV4cGlyZXMgYXR0cmlidXRlCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cucmh1YmFyYi5uZXQvIiwgJ3dodW09ImZpenoiJykKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMikKICAgICAgICBjLmNsZWFyX3Nlc3Npb25fY29va2llcygpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDEpCiAgICAgICAgc2VsZi5hc3NlcnRJbignc3BhbT0iYmFyIicsIGgpCgogICAgICAgICMgWFhYIFJGQyAyOTY1IGV4cGlyeSBydWxlcyAoc29tZSBhcHBseSB0byBWMCB0b28pCgogICAgZGVmIHRlc3RfZGVmYXVsdF9wYXRoKHNlbGYpOgogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIsIERlZmF1bHRDb29raWVQb2xpY3kKCiAgICAgICAgIyBSRkMgMjk2NQogICAgICAgIHBvbCA9IERlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NT1UcnVlKQoKICAgICAgICBjID0gQ29va2llSmFyKHBvbCkKICAgICAgICBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIsICdzcGFtPSJiYXIiOyBWZXJzaW9uPSIxIicpCiAgICAgICAgc2VsZi5hc3NlcnRJbigiLyIsIGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdKQoKICAgICAgICBjID0gQ29va2llSmFyKHBvbCkKICAgICAgICBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2JsYWgiLCAnZWdncz0iYmFyIjsgVmVyc2lvbj0iMSInKQogICAgICAgIHNlbGYuYXNzZXJ0SW4oIi8iLCBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXSkKCiAgICAgICAgYyA9IENvb2tpZUphcihwb2wpCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS9ibGFoL3JodWJhcmIiLAogICAgICAgICAgICAgICAgICAgICAgJ2VnZ3M9ImJhciI7IFZlcnNpb249IjEiJykKICAgICAgICBzZWxmLmFzc2VydEluKCIvYmxhaC8iLCBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXSkKCiAgICAgICAgYyA9IENvb2tpZUphcihwb2wpCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS9ibGFoL3JodWJhcmIvIiwKICAgICAgICAgICAgICAgICAgICAgICdlZ2dzPSJiYXIiOyBWZXJzaW9uPSIxIicpCiAgICAgICAgc2VsZi5hc3NlcnRJbigiL2JsYWgvcmh1YmFyYi8iLCBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXSkKCiAgICAgICAgIyBOZXRzY2FwZQoKICAgICAgICBjID0gQ29va2llSmFyKCkKICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLCAnc3BhbT0iYmFyIicpCiAgICAgICAgc2VsZi5hc3NlcnRJbigiLyIsIGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdKQoKICAgICAgICBjID0gQ29va2llSmFyKCkKICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS9ibGFoIiwgJ2VnZ3M9ImJhciInKQogICAgICAgIHNlbGYuYXNzZXJ0SW4oIi8iLCBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXSkKCiAgICAgICAgYyA9IENvb2tpZUphcigpCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vYmxhaC9yaHViYXJiIiwgJ2VnZ3M9ImJhciInKQogICAgICAgIHNlbGYuYXNzZXJ0SW4oIi9ibGFoIiwgYy5fY29va2llc1sid3d3LmFjbWUuY29tIl0pCgogICAgICAgIGMgPSBDb29raWVKYXIoKQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2JsYWgvcmh1YmFyYi8iLCAnZWdncz0iYmFyIicpCiAgICAgICAgc2VsZi5hc3NlcnRJbigiL2JsYWgvcmh1YmFyYiIsIGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdKQoKICAgIGRlZiB0ZXN0X2RlZmF1bHRfcGF0aF93aXRoX3F1ZXJ5KHNlbGYpOgogICAgICAgIGNqID0gY29va2llbGliLkNvb2tpZUphcigpCiAgICAgICAgdXJpID0gImh0dHA6Ly9leGFtcGxlLmNvbS8/c3BhbS9lZ2dzIgogICAgICAgIHZhbHVlID0gJ2VnZ3M9ImJhciInCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoY2osIHVyaSwgdmFsdWUpCiAgICAgICAgIyBkZWZhdWx0IHBhdGggZG9lcyBub3QgaW5jbHVkZSBxdWVyeSwgc28gaXMgIi8iLCBub3QgIi8/c3BhbSIKICAgICAgICBzZWxmLmFzc2VydEluKCIvIiwgY2ouX2Nvb2tpZXNbImV4YW1wbGUuY29tIl0pCiAgICAgICAgIyBjb29raWUgaXMgc2VudCBiYWNrIHRvIHRoZSBzYW1lIFVSSQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoaW50ZXJhY3RfbmV0c2NhcGUoY2osIHVyaSksIHZhbHVlKQoKICAgIGRlZiB0ZXN0X2VzY2FwZV9wYXRoKHNlbGYpOgogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBlc2NhcGVfcGF0aAogICAgICAgIGNhc2VzID0gWwogICAgICAgICAgICAjIHF1b3RlZCBzYWZlCiAgICAgICAgICAgICgiL2ZvbyUyZi9iYXIiLCAiL2ZvbyUyRi9iYXIiKSwKICAgICAgICAgICAgKCIvZm9vJTJGL2JhciIsICIvZm9vJTJGL2JhciIpLAogICAgICAgICAgICAjIHF1b3RlZCAlCiAgICAgICAgICAgICgiL2ZvbyUlL2JhciIsICIvZm9vJSUvYmFyIiksCiAgICAgICAgICAgICMgcXVvdGVkIHVuc2FmZQogICAgICAgICAgICAoIi9mbyUxOW8vYmFyIiwgIi9mbyUxOW8vYmFyIiksCiAgICAgICAgICAgICgiL2ZvJTdkby9iYXIiLCAiL2ZvJTdEby9iYXIiKSwKICAgICAgICAgICAgIyB1bnF1b3RlZCBzYWZlCiAgICAgICAgICAgICgiL2Zvby9iYXImIiwgIi9mb28vYmFyJiIpLAogICAgICAgICAgICAoIi9mb28vL2JhciIsICIvZm9vLy9iYXIiKSwKICAgICAgICAgICAgKCJcMTc2L2Zvby9iYXIiLCAiXDE3Ni9mb28vYmFyIiksCiAgICAgICAgICAgICMgdW5xdW90ZWQgdW5zYWZlCiAgICAgICAgICAgICgiL2Zvb1wwMzEvYmFyIiwgIi9mb28lMTkvYmFyIiksCiAgICAgICAgICAgICgiL1wxNzVmb28vYmFyIiwgIi8lN0Rmb28vYmFyIiksCiAgICAgICAgICAgICMgdW5pY29kZQogICAgICAgICAgICAodSIvZm9vL2Jhclx1YWJjZCIsICIvZm9vL2JhciVFQSVBRiU4RCIpLCAgIyBVVEYtOCBlbmNvZGVkCiAgICAgICAgICAgIF0KICAgICAgICBmb3IgYXJnLCByZXN1bHQgaW4gY2FzZXM6CiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoZXNjYXBlX3BhdGgoYXJnKSwgcmVzdWx0KQoKICAgIGRlZiB0ZXN0X3JlcXVlc3RfcGF0aChzZWxmKToKICAgICAgICBmcm9tIHVybGxpYjIgaW1wb3J0IFJlcXVlc3QKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgcmVxdWVzdF9wYXRoCiAgICAgICAgIyB3aXRoIHBhcmFtZXRlcnMKICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmV4YW1wbGUuY29tL3JoZXVtL3JoYXBvbnRpY3VtOyIKICAgICAgICAgICAgICAgICAgICAgICJmb289YmFyO3Npbmc9c29uZz9hcHBsZXM9cGVhcnMmc3BhbT1lZ2dzI25pIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcXVlc3RfcGF0aChyZXEpLAogICAgICAgICAgICAgICAgICAgICAgICAgIi9yaGV1bS9yaGFwb250aWN1bTtmb289YmFyO3Npbmc9c29uZyIpCiAgICAgICAgIyB3aXRob3V0IHBhcmFtZXRlcnMKICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmV4YW1wbGUuY29tL3JoZXVtL3JoYXBvbnRpY3VtPyIKICAgICAgICAgICAgICAgICAgICAgICJhcHBsZXM9cGVhcnMmc3BhbT1lZ2dzI25pIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcXVlc3RfcGF0aChyZXEpLCAiL3JoZXVtL3JoYXBvbnRpY3VtIikKICAgICAgICAjIG1pc3NpbmcgZmluYWwgc2xhc2gKICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmV4YW1wbGUuY29tIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcXVlc3RfcGF0aChyZXEpLCAiLyIpCgogICAgZGVmIHRlc3RfcmVxdWVzdF9wb3J0KHNlbGYpOgogICAgICAgIGZyb20gdXJsbGliMiBpbXBvcnQgUmVxdWVzdAogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCByZXF1ZXN0X3BvcnQsIERFRkFVTFRfSFRUUF9QT1JUCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hY21lLmNvbToxMjM0LyIsCiAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzPXsiSG9zdCI6ICJ3d3cuYWNtZS5jb206NDMyMSJ9KQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVxdWVzdF9wb3J0KHJlcSksICIxMjM0IikKICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmFjbWUuY29tLyIsCiAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzPXsiSG9zdCI6ICJ3d3cuYWNtZS5jb206NDMyMSJ9KQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVxdWVzdF9wb3J0KHJlcSksIERFRkFVTFRfSFRUUF9QT1JUKQoKICAgIGRlZiB0ZXN0X3JlcXVlc3RfaG9zdChzZWxmKToKICAgICAgICBmcm9tIHVybGxpYjIgaW1wb3J0IFJlcXVlc3QKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgcmVxdWVzdF9ob3N0CiAgICAgICAgIyB0aGlzIHJlcXVlc3QgaXMgaWxsZWdhbCAoUkZDMjYxNiwgMTQuMi4zKQogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly8xLjEuMS4xLyIsCiAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzPXsiSG9zdCI6ICJ3d3cuYWNtZS5jb206ODAifSkKICAgICAgICAjIGxpYnd3dy1wZXJsIHdhbnRzIHRoaXMgcmVzcG9uc2UsIGJ1dCB0aGF0IHNlZW1zIHdyb25nIChSRkMgMjYxNiwKICAgICAgICAjIHNlY3Rpb24gNS4yLCBwb2ludCAxLiwgYW5kIFJGQyAyOTY1IHNlY3Rpb24gMSwgcGFyYWdyYXBoIDMpCiAgICAgICAgI3NlbGYuYXNzZXJ0RXF1YWwocmVxdWVzdF9ob3N0KHJlcSksICJ3d3cuYWNtZS5jb20iKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVxdWVzdF9ob3N0KHJlcSksICIxLjEuMS4xIikKICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmFjbWUuY29tLyIsCiAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzPXsiSG9zdCI6ICJpcnJlbGV2YW50LmNvbSJ9KQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVxdWVzdF9ob3N0KHJlcSksICJ3d3cuYWNtZS5jb20iKQogICAgICAgICMgbm90IGFjdHVhbGx5IHN1cmUgdGhpcyBvbmUgaXMgdmFsaWQgUmVxdWVzdCBvYmplY3QsIHNvIG1heWJlIHNob3VsZAogICAgICAgICMgcmVtb3ZlIHRlc3QgZm9yIG5vIGhvc3QgaW4gdXJsIGluIHJlcXVlc3RfaG9zdCBmdW5jdGlvbj8KICAgICAgICByZXEgPSBSZXF1ZXN0KCIvcmVzb3VyY2UuaHRtbCIsCiAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzPXsiSG9zdCI6ICJ3d3cuYWNtZS5jb20ifSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcXVlc3RfaG9zdChyZXEpLCAid3d3LmFjbWUuY29tIikKICAgICAgICAjIHBvcnQgc2hvdWxkbid0IGJlIGluIHJlcXVlc3QtaG9zdAogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuYWNtZS5jb206MjM0NS9yZXNvdXJjZS5odG1sIiwKICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM9eyJIb3N0IjogInd3dy5hY21lLmNvbTo1NDMyIn0pCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyZXF1ZXN0X2hvc3QocmVxKSwgInd3dy5hY21lLmNvbSIpCgogICAgZGVmIHRlc3RfaXNfSEROKHNlbGYpOgogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBpc19IRE4KICAgICAgICBzZWxmLmFzc2VydFRydWUoaXNfSEROKCJmb28uYmFyLmNvbSIpKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc19IRE4oIjFmb28yLjNiYXI0LjVjb20iKSkKICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGlzX0hETigiMTkyLjE2OC4xLjEiKSkKICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGlzX0hETigiIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBpc19IRE4oIi4iKSkKICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGlzX0hETigiLmZvby5iYXIuY29tIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBpc19IRE4oIi4uZm9vIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBpc19IRE4oImZvby4iKSkKCiAgICBkZWYgdGVzdF9yZWFjaChzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgcmVhY2gKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlYWNoKCJ3d3cuYWNtZS5jb20iKSwgIi5hY21lLmNvbSIpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyZWFjaCgiYWNtZS5jb20iKSwgImFjbWUuY29tIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlYWNoKCJhY21lLmxvY2FsIiksICIubG9jYWwiKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVhY2goIi5sb2NhbCIpLCAiLmxvY2FsIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlYWNoKCIuY29tIiksICIuY29tIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlYWNoKCIuIiksICIuIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlYWNoKCIiKSwgIiIpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyZWFjaCgiMTkyLjE2OC4wLjEiKSwgIjE5Mi4xNjguMC4xIikKCiAgICBkZWYgdGVzdF9kb21haW5fbWF0Y2goc2VsZik6CiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IGRvbWFpbl9tYXRjaCwgdXNlcl9kb21haW5fbWF0Y2gKICAgICAgICBzZWxmLmFzc2VydFRydWUoZG9tYWluX21hdGNoKCIxOTIuMTY4LjEuMSIsICIxOTIuMTY4LjEuMSIpKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgZG9tYWluX21hdGNoKCIxOTIuMTY4LjEuMSIsICIuMTY4LjEuMSIpKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShkb21haW5fbWF0Y2goIngueS5jb20iLCAieC5ZLmNvbSIpKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShkb21haW5fbWF0Y2goIngueS5jb20iLCAiLlkuY29tIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBkb21haW5fbWF0Y2goIngueS5jb20iLCAiWS5jb20iKSkKICAgICAgICBzZWxmLmFzc2VydFRydWUoZG9tYWluX21hdGNoKCJhLmIuYy5jb20iLCAiLmMuY29tIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBkb21haW5fbWF0Y2goIi5jLmNvbSIsICJhLmIuYy5jb20iKSkKICAgICAgICBzZWxmLmFzc2VydFRydWUoZG9tYWluX21hdGNoKCJleGFtcGxlLmxvY2FsIiwgIi5sb2NhbCIpKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgZG9tYWluX21hdGNoKCJibGFoLmJsYWgiLCAiIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBkb21haW5fbWF0Y2goIiIsICIucmh1YmFyYi5yaHViYXJiIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGRvbWFpbl9tYXRjaCgiIiwgIiIpKQoKICAgICAgICBzZWxmLmFzc2VydFRydWUodXNlcl9kb21haW5fbWF0Y2goImFjbWUuY29tIiwgImFjbWUuY29tIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB1c2VyX2RvbWFpbl9tYXRjaCgiYWNtZS5jb20iLCAiLmFjbWUuY29tIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHVzZXJfZG9tYWluX21hdGNoKCJyaHViYXJiLmFjbWUuY29tIiwgIi5hY21lLmNvbSIpKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh1c2VyX2RvbWFpbl9tYXRjaCgid3d3LnJodWJhcmIuYWNtZS5jb20iLCAiLmFjbWUuY29tIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHVzZXJfZG9tYWluX21hdGNoKCJ4LnkuY29tIiwgInguWS5jb20iKSkKICAgICAgICBzZWxmLmFzc2VydFRydWUodXNlcl9kb21haW5fbWF0Y2goIngueS5jb20iLCAiLlkuY29tIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB1c2VyX2RvbWFpbl9tYXRjaCgieC55LmNvbSIsICJZLmNvbSIpKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh1c2VyX2RvbWFpbl9tYXRjaCgieS5jb20iLCAiWS5jb20iKSkKICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IHVzZXJfZG9tYWluX21hdGNoKCIueS5jb20iLCAiWS5jb20iKSkKICAgICAgICBzZWxmLmFzc2VydFRydWUodXNlcl9kb21haW5fbWF0Y2goIi55LmNvbSIsICIuWS5jb20iKSkKICAgICAgICBzZWxmLmFzc2VydFRydWUodXNlcl9kb21haW5fbWF0Y2goIngueS5jb20iLCAiLmNvbSIpKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgdXNlcl9kb21haW5fbWF0Y2goIngueS5jb20iLCAiY29tIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB1c2VyX2RvbWFpbl9tYXRjaCgieC55LmNvbSIsICJtIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB1c2VyX2RvbWFpbl9tYXRjaCgieC55LmNvbSIsICIubSIpKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgdXNlcl9kb21haW5fbWF0Y2goIngueS5jb20iLCAiIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB1c2VyX2RvbWFpbl9tYXRjaCgieC55LmNvbSIsICIuIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHVzZXJfZG9tYWluX21hdGNoKCIxOTIuMTY4LjEuMSIsICIxOTIuMTY4LjEuMSIpKQogICAgICAgICMgbm90IGJvdGggSEROcywgc28gbXVzdCBzdHJpbmctY29tcGFyZSBlcXVhbCB0byBtYXRjaAogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgdXNlcl9kb21haW5fbWF0Y2goIjE5Mi4xNjguMS4xIiwgIi4xNjguMS4xIikpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB1c2VyX2RvbWFpbl9tYXRjaCgiMTkyLjE2OC4xLjEiLCAiLiIpKQogICAgICAgICMgZW1wdHkgc3RyaW5nIGlzIGEgc3BlY2lhbCBjYXNlCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB1c2VyX2RvbWFpbl9tYXRjaCgiMTkyLjE2OC4xLjEiLCAiIikpCgogICAgZGVmIHRlc3Rfd3JvbmdfZG9tYWluKHNlbGYpOgogICAgICAgICMgQ29va2llcyB3aG9zZSBlZmZlY3RpdmUgcmVxdWVzdC1ob3N0IG5hbWUgZG9lcyBub3QgZG9tYWluLW1hdGNoIHRoZQogICAgICAgICMgZG9tYWluIGFyZSByZWplY3RlZC4KCiAgICAgICAgIyBYWFggZmFyIGZyb20gY29tcGxldGUKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyCiAgICAgICAgYyA9IENvb2tpZUphcigpCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5uYXN0eS5jb20vIiwKICAgICAgICAgICAgICAgICAgICAgICdmb289YmFyOyBkb21haW49ZnJpZW5kbHkub3JnOyBWZXJzaW9uPSIxIicpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDApCgogICAgZGVmIHRlc3Rfc3RyaWN0X2RvbWFpbihzZWxmKToKICAgICAgICAjIENvb2tpZXMgd2hvc2UgZG9tYWluIGlzIGEgY291bnRyeS1jb2RlIHRsZCBsaWtlIC5jby51ayBzaG91bGQKICAgICAgICAjIG5vdCBiZSBzZXQgaWYgQ29va2llUG9saWN5LnN0cmljdF9kb21haW4gaXMgdHJ1ZS4KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5CgogICAgICAgIGNwID0gRGVmYXVsdENvb2tpZVBvbGljeShzdHJpY3RfZG9tYWluPVRydWUpCiAgICAgICAgY2ogPSBDb29raWVKYXIocG9saWN5PWNwKQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGNqLCAiaHR0cDovL2V4YW1wbGUuY28udWsvIiwgJ25vPXByb2JsZW1vJykKICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjaiwgImh0dHA6Ly9leGFtcGxlLmNvLnVrLyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJ29rZXk9ZG9rZXk7IERvbWFpbj0uZXhhbXBsZS5jby51aycpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oY2opLCAyKQogICAgICAgIGZvciBwc2V1ZG9fdGxkIGluIFsiLmNvLnVrIiwgIi5vcmcuemEiLCAiLnR4LnVzIiwgIi5uYW1lLnVzIl06CiAgICAgICAgICAgIGludGVyYWN0X25ldHNjYXBlKGNqLCAiaHR0cDovL2V4YW1wbGUuJXMvIiAlIHBzZXVkb190bGQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzcGFtPWVnZ3M7IERvbWFpbj0uY28udWsnKQogICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjaiksIDIpCgogICAgZGVmIHRlc3RfdHdvX2NvbXBvbmVudF9kb21haW5fbnMoc2VsZik6CiAgICAgICAgIyBOZXRzY2FwZTogLnd3dy5iYXIuY29tLCB3d3cuYmFyLmNvbSwgLmJhci5jb20sIGJhci5jb20sIG5vIGRvbWFpbgogICAgICAgICMgc2hvdWxkIGFsbCBnZXQgYWNjZXB0ZWQsIGFzIHNob3VsZCAuYWNtZS5jb20sIGFjbWUuY29tIGFuZCBubyBkb21haW4KICAgICAgICAjIGZvciAyLWNvbXBvbmVudCBkb21haW5zIGxpa2UgYWNtZS5jb20uCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphciwgRGVmYXVsdENvb2tpZVBvbGljeQoKICAgICAgICBjID0gQ29va2llSmFyKCkKCiAgICAgICAgIyB0d28tY29tcG9uZW50IFYwIGRvbWFpbiBpcyBPSwogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vZm9vLm5ldC8iLCAnbnM9YmFyJykKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGMuX2Nvb2tpZXNbImZvby5uZXQiXVsiLyJdWyJucyJdLnZhbHVlLCAiYmFyIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vZm9vLm5ldC8iKSwgIm5zPWJhciIpCiAgICAgICAgIyAqd2lsbCogYmUgcmV0dXJuZWQgdG8gYW55IG90aGVyIGRvbWFpbiAodW5saWtlIFJGQyAyOTY1KS4uLgogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuZm9vLm5ldC8iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICJucz1iYXIiKQogICAgICAgICMgLi4udW5sZXNzIHJlcXVlc3RlZCBvdGhlcndpc2UKICAgICAgICBwb2wgPSBEZWZhdWx0Q29va2llUG9saWN5KAogICAgICAgICAgICBzdHJpY3RfbnNfZG9tYWluPURlZmF1bHRDb29raWVQb2xpY3kuRG9tYWluU3RyaWN0Tm9uRG9tYWluKQogICAgICAgIGMuc2V0X3BvbGljeShwb2wpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5mb28ubmV0LyIpLCAiIikKCiAgICAgICAgIyB1bmxpa2UgUkZDIDI5NjUsIGV2ZW4gZXhwbGljaXQgdHdvLWNvbXBvbmVudCBkb21haW4gaXMgT0ssCiAgICAgICAgIyBiZWNhdXNlIC5mb28ubmV0IG1hdGNoZXMgZm9vLm5ldAogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vZm9vLm5ldC9mb28vIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAnc3BhbTE9ZWdnczsgZG9tYWluPWZvby5uZXQnKQogICAgICAgICMgZXZlbiBpZiBzdGFydHMgd2l0aCBhIGRvdCAtLSBpbiBOUyBydWxlcywgLmZvby5uZXQgbWF0Y2hlcyBmb28ubmV0IQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vZm9vLm5ldC9mb28vYmFyLyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NwYW0yPWVnZ3M7IGRvbWFpbj0uZm9vLm5ldCcpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDMpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjLl9jb29raWVzWyIuZm9vLm5ldCJdWyIvZm9vIl1bInNwYW0xIl0udmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAiZWdncyIpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjLl9jb29raWVzWyIuZm9vLm5ldCJdWyIvZm9vL2JhciJdWyJzcGFtMiJdLnZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgImVnZ3MiKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly9mb28ubmV0L2Zvby9iYXIvIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAic3BhbTI9ZWdnczsgc3BhbTE9ZWdnczsgbnM9YmFyIikKCiAgICAgICAgIyB0b3AtbGV2ZWwgZG9tYWluIGlzIHRvbyBnZW5lcmFsCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly9mb28ubmV0LyIsICduaW5pPSJuaSI7IGRvbWFpbj0ubmV0JykKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMykKCiMjICAgICAgICAgIyBOZXRzY2FwZSBwcm90b2NvbCBkb2Vzbid0IGFsbG93IG5vbi1zcGVjaWFsIHRvcCBsZXZlbCBkb21haW5zIChzdWNoCiMjICAgICAgICAgIyBhcyBjby51aykgaW4gdGhlIGRvbWFpbiBhdHRyaWJ1dGUgdW5sZXNzIHRoZXJlIGFyZSBhdCBsZWFzdCB0aHJlZQojIyAgICAgICAgICMgZG90cyBpbiBpdC4KICAgICAgICAjIE9oIHllcyBpdCBkb2VzISAgUmVhbCBpbXBsZW1lbnRhdGlvbnMgZG9uJ3QgY2hlY2sgdGhpcywgYW5kIHJlYWwKICAgICAgICAjIGNvb2tpZXMgKG9mIGNvdXJzZSkgcmVseSBvbiB0aGF0IGJlaGF2aW91ci4KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL2Zvby5jby51ayIsICduYXN0eT10cmljazsgZG9tYWluPS5jby51aycpCiMjICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDIpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDQpCgogICAgZGVmIHRlc3RfdHdvX2NvbXBvbmVudF9kb21haW5fcmZjMjk2NShzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5CgogICAgICAgIHBvbCA9IERlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NT1UcnVlKQogICAgICAgIGMgPSBDb29raWVKYXIocG9sKQoKICAgICAgICAjIHR3by1jb21wb25lbnQgVjEgZG9tYWluIGlzIE9LCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL2Zvby5uZXQvIiwgJ2Zvbz1iYXI7IFZlcnNpb249IjEiJykKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGMuX2Nvb2tpZXNbImZvby5uZXQiXVsiLyJdWyJmb28iXS52YWx1ZSwgImJhciIpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vZm9vLm5ldC8iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICIkVmVyc2lvbj0xOyBmb289YmFyIikKICAgICAgICAjIHdvbid0IGJlIHJldHVybmVkIHRvIGFueSBvdGhlciBkb21haW4gKGJlY2F1c2UgZG9tYWluIHdhcyBpbXBsaWVkKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5mb28ubmV0LyIpLCAiIikKCiAgICAgICAgIyB1bmxlc3MgZG9tYWluIGlzIGdpdmVuIGV4cGxpY2l0bHksIGJlY2F1c2UgdGhlbiBpdCBtdXN0IGJlCiAgICAgICAgIyByZXdyaXR0ZW4gdG8gc3RhcnQgd2l0aCBhIGRvdDogZm9vLm5ldCAtLT4gLmZvby5uZXQsIHdoaWNoIGRvZXMKICAgICAgICAjIG5vdCBkb21haW4tbWF0Y2ggZm9vLm5ldAogICAgICAgIGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly9mb28ubmV0L2ZvbyIsCiAgICAgICAgICAgICAgICAgICAgICAnc3BhbT1lZ2dzOyBkb21haW49Zm9vLm5ldDsgcGF0aD0vZm9vOyBWZXJzaW9uPSIxIicpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDEpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vZm9vLm5ldC9mb28iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICIkVmVyc2lvbj0xOyBmb289YmFyIikKCiAgICAgICAgIyBleHBsaWNpdCBmb28ubmV0IGZyb20gdGhyZWUtY29tcG9uZW50IGRvbWFpbiB3d3cuZm9vLm5ldCAqZG9lcyogZ2V0CiAgICAgICAgIyBzZXQsIGJlY2F1c2UgLmZvby5uZXQgZG9tYWluLW1hdGNoZXMgLmZvby5uZXQKICAgICAgICBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LmZvby5uZXQvZm9vLyIsCiAgICAgICAgICAgICAgICAgICAgICAnc3BhbT1lZ2dzOyBkb21haW49Zm9vLm5ldDsgVmVyc2lvbj0iMSInKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoYy5fY29va2llc1siLmZvby5uZXQiXVsiL2Zvby8iXVsic3BhbSJdLnZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgImVnZ3MiKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAyKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL2Zvby5uZXQvZm9vLyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIiRWZXJzaW9uPTE7IGZvbz1iYXIiKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5mb28ubmV0L2Zvby8iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICckVmVyc2lvbj0xOyBzcGFtPWVnZ3M7ICREb21haW49ImZvby5uZXQiJykKCiAgICAgICAgIyB0b3AtbGV2ZWwgZG9tYWluIGlzIHRvbyBnZW5lcmFsCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL2Zvby5uZXQvIiwKICAgICAgICAgICAgICAgICAgICAgICduaT0ibmkiOyBkb21haW49Ii5uZXQiOyBWZXJzaW9uPSIxIicpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDIpCgogICAgICAgICMgUkZDIDI5NjUgZG9lc24ndCByZXF1aXJlIGJsb2NraW5nIHRoaXMKICAgICAgICBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vZm9vLmNvLnVrLyIsCiAgICAgICAgICAgICAgICAgICAgICAnbmFzdHk9dHJpY2s7IGRvbWFpbj0uY28udWs7IFZlcnNpb249IjEiJykKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMykKCiAgICBkZWYgdGVzdF9kb21haW5fYWxsb3coc2VsZik6CiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphciwgRGVmYXVsdENvb2tpZVBvbGljeQogICAgICAgIGZyb20gdXJsbGliMiBpbXBvcnQgUmVxdWVzdAoKICAgICAgICBjID0gQ29va2llSmFyKHBvbGljeT1EZWZhdWx0Q29va2llUG9saWN5KAogICAgICAgICAgICBibG9ja2VkX2RvbWFpbnM9WyJhY21lLmNvbSJdLAogICAgICAgICAgICBhbGxvd2VkX2RvbWFpbnM9WyJ3d3cuYWNtZS5jb20iXSkpCgogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly9hY21lLmNvbS8iKQogICAgICAgIGhlYWRlcnMgPSBbIlNldC1Db29raWU6IENVU1RPTUVSPVdJTEVfRV9DT1lPVEU7IHBhdGg9LyJdCiAgICAgICAgcmVzID0gRmFrZVJlc3BvbnNlKGhlYWRlcnMsICJodHRwOi8vYWNtZS5jb20vIikKICAgICAgICBjLmV4dHJhY3RfY29va2llcyhyZXMsIHJlcSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMCkKCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hY21lLmNvbS8iKQogICAgICAgIHJlcyA9IEZha2VSZXNwb25zZShoZWFkZXJzLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iKQogICAgICAgIGMuZXh0cmFjdF9jb29raWVzKHJlcywgcmVxKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQoKICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmNveW90ZS5jb20vIikKICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuY295b3RlLmNvbS8iKQogICAgICAgIGMuZXh0cmFjdF9jb29raWVzKHJlcywgcmVxKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQoKICAgICAgICAjIHNldCBhIGNvb2tpZSB3aXRoIG5vbi1hbGxvd2VkIGRvbWFpbi4uLgogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuY295b3RlLmNvbS8iKQogICAgICAgIHJlcyA9IEZha2VSZXNwb25zZShoZWFkZXJzLCAiaHR0cDovL3d3dy5jb3lvdGUuY29tLyIpCiAgICAgICAgY29va2llcyA9IGMubWFrZV9jb29raWVzKHJlcywgcmVxKQogICAgICAgIGMuc2V0X2Nvb2tpZShjb29raWVzWzBdKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAyKQogICAgICAgICMgLi4uIGFuZCBjaGVjayBpcyBkb2Vzbid0IGdldCByZXR1cm5lZAogICAgICAgIGMuYWRkX2Nvb2tpZV9oZWFkZXIocmVxKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgcmVxLmhhc19oZWFkZXIoIkNvb2tpZSIpKQoKICAgIGRlZiB0ZXN0X2RvbWFpbl9ibG9jayhzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5CiAgICAgICAgZnJvbSB1cmxsaWIyIGltcG9ydCBSZXF1ZXN0CgogICAgICAgIHBvbCA9IERlZmF1bHRDb29raWVQb2xpY3koCiAgICAgICAgICAgIHJmYzI5NjU9VHJ1ZSwgYmxvY2tlZF9kb21haW5zPVsiLmFjbWUuY29tIl0pCiAgICAgICAgYyA9IENvb2tpZUphcihwb2xpY3k9cG9sKQogICAgICAgIGhlYWRlcnMgPSBbIlNldC1Db29raWU6IENVU1RPTUVSPVdJTEVfRV9DT1lPVEU7IHBhdGg9LyJdCgogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuYWNtZS5jb20vIikKICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuYWNtZS5jb20vIikKICAgICAgICBjLmV4dHJhY3RfY29va2llcyhyZXMsIHJlcSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMCkKCiAgICAgICAgcCA9IHBvbC5zZXRfYmxvY2tlZF9kb21haW5zKFsiYWNtZS5jb20iXSkKICAgICAgICBjLmV4dHJhY3RfY29va2llcyhyZXMsIHJlcSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMSkKCiAgICAgICAgYy5jbGVhcigpCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5yb2FkcnVubmVyLm5ldC8iKQogICAgICAgIHJlcyA9IEZha2VSZXNwb25zZShoZWFkZXJzLCAiaHR0cDovL3d3dy5yb2FkcnVubmVyLm5ldC8iKQogICAgICAgIGMuZXh0cmFjdF9jb29raWVzKHJlcywgcmVxKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cucm9hZHJ1bm5lci5uZXQvIikKICAgICAgICBjLmFkZF9jb29raWVfaGVhZGVyKHJlcSkKICAgICAgICBzZWxmLmFzc2VydFRydWUoKHJlcS5oYXNfaGVhZGVyKCJDb29raWUiKSBhbmQKICAgICAgICAgICAgICAgICAgICAgIHJlcS5oYXNfaGVhZGVyKCJDb29raWUyIikpKQoKICAgICAgICBjLmNsZWFyKCkKICAgICAgICBwb2wuc2V0X2Jsb2NrZWRfZG9tYWlucyhbIi5hY21lLmNvbSJdKQogICAgICAgIGMuZXh0cmFjdF9jb29raWVzKHJlcywgcmVxKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQoKICAgICAgICAjIHNldCBhIGNvb2tpZSB3aXRoIGJsb2NrZWQgZG9tYWluLi4uCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hY21lLmNvbS8iKQogICAgICAgIHJlcyA9IEZha2VSZXNwb25zZShoZWFkZXJzLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iKQogICAgICAgIGNvb2tpZXMgPSBjLm1ha2VfY29va2llcyhyZXMsIHJlcSkKICAgICAgICBjLnNldF9jb29raWUoY29va2llc1swXSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMikKICAgICAgICAjIC4uLiBhbmQgY2hlY2sgaXMgZG9lc24ndCBnZXQgcmV0dXJuZWQKICAgICAgICBjLmFkZF9jb29raWVfaGVhZGVyKHJlcSkKICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IHJlcS5oYXNfaGVhZGVyKCJDb29raWUiKSkKCiAgICBkZWYgdGVzdF9zZWN1cmUoc2VsZik6CiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphciwgRGVmYXVsdENvb2tpZVBvbGljeQoKICAgICAgICBmb3IgbnMgaW4gVHJ1ZSwgRmFsc2U6CiAgICAgICAgICAgIGZvciB3aGl0ZXNwYWNlIGluICIgIiwgIiI6CiAgICAgICAgICAgICAgICBjID0gQ29va2llSmFyKCkKICAgICAgICAgICAgICAgIGlmIG5zOgogICAgICAgICAgICAgICAgICAgIHBvbCA9IERlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NT1GYWxzZSkKICAgICAgICAgICAgICAgICAgICBpbnQgPSBpbnRlcmFjdF9uZXRzY2FwZQogICAgICAgICAgICAgICAgICAgIHZzID0gIiIKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgcG9sID0gRGVmYXVsdENvb2tpZVBvbGljeShyZmMyOTY1PVRydWUpCiAgICAgICAgICAgICAgICAgICAgaW50ID0gaW50ZXJhY3RfMjk2NQogICAgICAgICAgICAgICAgICAgIHZzID0gIjsgVmVyc2lvbj0xIgogICAgICAgICAgICAgICAgYy5zZXRfcG9saWN5KHBvbCkKICAgICAgICAgICAgICAgIHVybCA9ICJodHRwOi8vd3d3LmFjbWUuY29tLyIKICAgICAgICAgICAgICAgIGludChjLCB1cmwsICJmb28xPWJhciVzJXMiICUgKHZzLCB3aGl0ZXNwYWNlKSkKICAgICAgICAgICAgICAgIGludChjLCB1cmwsICJmb28yPWJhciVzOyBzZWN1cmUlcyIgJSAgKHZzLCB3aGl0ZXNwYWNlKSkKICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSgKICAgICAgICAgICAgICAgICAgICBub3QgYy5fY29va2llc1sid3d3LmFjbWUuY29tIl1bIi8iXVsiZm9vMSJdLnNlY3VyZSwKICAgICAgICAgICAgICAgICAgICAibm9uLXNlY3VyZSBjb29raWUgcmVnaXN0ZXJlZCBzZWN1cmUiKQogICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRUcnVlKAogICAgICAgICAgICAgICAgICAgIGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdWyIvIl1bImZvbzIiXS5zZWN1cmUsCiAgICAgICAgICAgICAgICAgICAgInNlY3VyZSBjb29raWUgcmVnaXN0ZXJlZCBub24tc2VjdXJlIikKCiAgICBkZWYgdGVzdF9xdW90ZV9jb29raWVfdmFsdWUoc2VsZik6CiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphciwgRGVmYXVsdENvb2tpZVBvbGljeQogICAgICAgIGMgPSBDb29raWVKYXIocG9saWN5PURlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NT1UcnVlKSkKICAgICAgICBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIsIHInZm9vPVxiImEicjsgVmVyc2lvbj0xJykKICAgICAgICBoID0gaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoaCwgcickVmVyc2lvbj0xOyBmb289XFxiXCJhXCJyJykKCiAgICBkZWYgdGVzdF9taXNzaW5nX2ZpbmFsX3NsYXNoKHNlbGYpOgogICAgICAgICMgTWlzc2luZyBzbGFzaCBmcm9tIHJlcXVlc3QgVVJMJ3MgYWJzX3BhdGggc2hvdWxkIGJlIGFzc3VtZWQgcHJlc2VudC4KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5CiAgICAgICAgZnJvbSB1cmxsaWIyIGltcG9ydCBSZXF1ZXN0CiAgICAgICAgdXJsID0gImh0dHA6Ly93d3cuYWNtZS5jb20iCiAgICAgICAgYyA9IENvb2tpZUphcihEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkpCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCB1cmwsICJmb289YmFyOyBWZXJzaW9uPTEiKQogICAgICAgIHJlcSA9IFJlcXVlc3QodXJsKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQogICAgICAgIGMuYWRkX2Nvb2tpZV9oZWFkZXIocmVxKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZXEuaGFzX2hlYWRlcigiQ29va2llIikpCgogICAgZGVmIHRlc3RfZG9tYWluX21pcnJvcihzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5CgogICAgICAgIHBvbCA9IERlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NT1UcnVlKQoKICAgICAgICBjID0gQ29va2llSmFyKHBvbCkKICAgICAgICB1cmwgPSAiaHR0cDovL2Zvby5iYXIuY29tLyIKICAgICAgICBpbnRlcmFjdF8yOTY1KGMsIHVybCwgInNwYW09ZWdnczsgVmVyc2lvbj0xIikKICAgICAgICBoID0gaW50ZXJhY3RfMjk2NShjLCB1cmwpCiAgICAgICAgc2VsZi5hc3NlcnROb3RJbigiRG9tYWluIiwgaCwKICAgICAgICAgICAgICAgICAgICAgICAgICJhYnNlbnQgZG9tYWluIHJldHVybmVkIHdpdGggZG9tYWluIHByZXNlbnQiKQoKICAgICAgICBjID0gQ29va2llSmFyKHBvbCkKICAgICAgICB1cmwgPSAiaHR0cDovL2Zvby5iYXIuY29tLyIKICAgICAgICBpbnRlcmFjdF8yOTY1KGMsIHVybCwgJ3NwYW09ZWdnczsgVmVyc2lvbj0xOyBEb21haW49LmJhci5jb20nKQogICAgICAgIGggPSBpbnRlcmFjdF8yOTY1KGMsIHVybCkKICAgICAgICBzZWxmLmFzc2VydEluKCckRG9tYWluPSIuYmFyLmNvbSInLCBoLCAiZG9tYWluIG5vdCByZXR1cm5lZCIpCgogICAgICAgIGMgPSBDb29raWVKYXIocG9sKQogICAgICAgIHVybCA9ICJodHRwOi8vZm9vLmJhci5jb20vIgogICAgICAgICMgbm90ZSBtaXNzaW5nIGluaXRpYWwgZG90IGluIERvbWFpbgogICAgICAgIGludGVyYWN0XzI5NjUoYywgdXJsLCAnc3BhbT1lZ2dzOyBWZXJzaW9uPTE7IERvbWFpbj1iYXIuY29tJykKICAgICAgICBoID0gaW50ZXJhY3RfMjk2NShjLCB1cmwpCiAgICAgICAgc2VsZi5hc3NlcnRJbignJERvbWFpbj0iYmFyLmNvbSInLCBoLCAiZG9tYWluIG5vdCByZXR1cm5lZCIpCgogICAgZGVmIHRlc3RfcGF0aF9taXJyb3Ioc2VsZik6CiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphciwgRGVmYXVsdENvb2tpZVBvbGljeQoKICAgICAgICBwb2wgPSBEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkKCiAgICAgICAgYyA9IENvb2tpZUphcihwb2wpCiAgICAgICAgdXJsID0gImh0dHA6Ly9mb28uYmFyLmNvbS8iCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCB1cmwsICJzcGFtPWVnZ3M7IFZlcnNpb249MSIpCiAgICAgICAgaCA9IGludGVyYWN0XzI5NjUoYywgdXJsKQogICAgICAgIHNlbGYuYXNzZXJ0Tm90SW4oIlBhdGgiLCBoLCAiYWJzZW50IHBhdGggcmV0dXJuZWQgd2l0aCBwYXRoIHByZXNlbnQiKQoKICAgICAgICBjID0gQ29va2llSmFyKHBvbCkKICAgICAgICB1cmwgPSAiaHR0cDovL2Zvby5iYXIuY29tLyIKICAgICAgICBpbnRlcmFjdF8yOTY1KGMsIHVybCwgJ3NwYW09ZWdnczsgVmVyc2lvbj0xOyBQYXRoPS8nKQogICAgICAgIGggPSBpbnRlcmFjdF8yOTY1KGMsIHVybCkKICAgICAgICBzZWxmLmFzc2VydEluKCckUGF0aD0iLyInLCBoLCAicGF0aCBub3QgcmV0dXJuZWQiKQoKICAgIGRlZiB0ZXN0X3BvcnRfbWlycm9yKHNlbGYpOgogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIsIERlZmF1bHRDb29raWVQb2xpY3kKCiAgICAgICAgcG9sID0gRGVmYXVsdENvb2tpZVBvbGljeShyZmMyOTY1PVRydWUpCgogICAgICAgIGMgPSBDb29raWVKYXIocG9sKQogICAgICAgIHVybCA9ICJodHRwOi8vZm9vLmJhci5jb20vIgogICAgICAgIGludGVyYWN0XzI5NjUoYywgdXJsLCAic3BhbT1lZ2dzOyBWZXJzaW9uPTEiKQogICAgICAgIGggPSBpbnRlcmFjdF8yOTY1KGMsIHVybCkKICAgICAgICBzZWxmLmFzc2VydE5vdEluKCJQb3J0IiwgaCwgImFic2VudCBwb3J0IHJldHVybmVkIHdpdGggcG9ydCBwcmVzZW50IikKCiAgICAgICAgYyA9IENvb2tpZUphcihwb2wpCiAgICAgICAgdXJsID0gImh0dHA6Ly9mb28uYmFyLmNvbS8iCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCB1cmwsICJzcGFtPWVnZ3M7IFZlcnNpb249MTsgUG9ydCIpCiAgICAgICAgaCA9IGludGVyYWN0XzI5NjUoYywgdXJsKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZS5zZWFyY2goIlwkUG9ydChbXj1dfCQpIiwgaCksCiAgICAgICAgICAgICAgICAgICAgICJwb3J0IHdpdGggbm8gdmFsdWUgbm90IHJldHVybmVkIHdpdGggbm8gdmFsdWUiKQoKICAgICAgICBjID0gQ29va2llSmFyKHBvbCkKICAgICAgICB1cmwgPSAiaHR0cDovL2Zvby5iYXIuY29tLyIKICAgICAgICBpbnRlcmFjdF8yOTY1KGMsIHVybCwgJ3NwYW09ZWdnczsgVmVyc2lvbj0xOyBQb3J0PSI4MCInKQogICAgICAgIGggPSBpbnRlcmFjdF8yOTY1KGMsIHVybCkKICAgICAgICBzZWxmLmFzc2VydEluKCckUG9ydD0iODAiJywgaCwKICAgICAgICAgICAgICAgICAgICAgICJwb3J0IHdpdGggc2luZ2xlIHZhbHVlIG5vdCByZXR1cm5lZCB3aXRoIHNpbmdsZSB2YWx1ZSIpCgogICAgICAgIGMgPSBDb29raWVKYXIocG9sKQogICAgICAgIHVybCA9ICJodHRwOi8vZm9vLmJhci5jb20vIgogICAgICAgIGludGVyYWN0XzI5NjUoYywgdXJsLCAnc3BhbT1lZ2dzOyBWZXJzaW9uPTE7IFBvcnQ9IjgwLDgwODAiJykKICAgICAgICBoID0gaW50ZXJhY3RfMjk2NShjLCB1cmwpCiAgICAgICAgc2VsZi5hc3NlcnRJbignJFBvcnQ9IjgwLDgwODAiJywgaCwKICAgICAgICAgICAgICAgICAgICAgICJwb3J0IHdpdGggbXVsdGlwbGUgdmFsdWVzIG5vdCByZXR1cm5lZCB3aXRoIG11bHRpcGxlICIKICAgICAgICAgICAgICAgICAgICAgICJ2YWx1ZXMiKQoKICAgIGRlZiB0ZXN0X25vX3JldHVybl9jb21tZW50KHNlbGYpOgogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIsIERlZmF1bHRDb29raWVQb2xpY3kKCiAgICAgICAgYyA9IENvb2tpZUphcihEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkpCiAgICAgICAgdXJsID0gImh0dHA6Ly9mb28uYmFyLmNvbS8iCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCB1cmwsICdzcGFtPWVnZ3M7IFZlcnNpb249MTsgJwogICAgICAgICAgICAgICAgICAgICAgJ0NvbW1lbnQ9ImRvZXMgYW55Ym9keSByZWFkIHRoZXNlPyI7ICcKICAgICAgICAgICAgICAgICAgICAgICdDb21tZW50VVJMPSJodHRwOi8vZm9vLmJhci5uZXQvY29tbWVudC5odG1sIicpCiAgICAgICAgaCA9IGludGVyYWN0XzI5NjUoYywgdXJsKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSgKICAgICAgICAgICAgIkNvbW1lbnQiIG5vdCBpbiBoLAogICAgICAgICAgICAiQ29tbWVudCBvciBDb21tZW50VVJMIGNvb2tpZS1hdHRyaWJ1dGVzIHJldHVybmVkIHRvIHNlcnZlciIpCgogICAgZGVmIHRlc3RfQ29va2llX2l0ZXJhdG9yKHNlbGYpOgogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIsIENvb2tpZSwgRGVmYXVsdENvb2tpZVBvbGljeQoKICAgICAgICBjcyA9IENvb2tpZUphcihEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkpCiAgICAgICAgIyBhZGQgc29tZSByYW5kb20gY29va2llcwogICAgICAgIGludGVyYWN0XzI5NjUoY3MsICJodHRwOi8vYmxhaC5zcGFtLm9yZy8iLCAnZm9vPWVnZ3M7IFZlcnNpb249MTsgJwogICAgICAgICAgICAgICAgICAgICAgJ0NvbW1lbnQ9ImRvZXMgYW55Ym9keSByZWFkIHRoZXNlPyI7ICcKICAgICAgICAgICAgICAgICAgICAgICdDb21tZW50VVJMPSJodHRwOi8vZm9vLmJhci5uZXQvY29tbWVudC5odG1sIicpCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoY3MsICJodHRwOi8vd3d3LmFjbWUuY29tL2JsYWgvIiwgInNwYW09YmFyOyBzZWN1cmUiKQogICAgICAgIGludGVyYWN0XzI5NjUoY3MsICJodHRwOi8vd3d3LmFjbWUuY29tL2JsYWgvIiwKICAgICAgICAgICAgICAgICAgICAgICJmb289YmFyOyBzZWN1cmU7IFZlcnNpb249MSIpCiAgICAgICAgaW50ZXJhY3RfMjk2NShjcywgImh0dHA6Ly93d3cuYWNtZS5jb20vYmxhaC8iLAogICAgICAgICAgICAgICAgICAgICAgImZvbz1iYXI7IHBhdGg9LzsgVmVyc2lvbj0xIikKICAgICAgICBpbnRlcmFjdF8yOTY1KGNzLCAiaHR0cDovL3d3dy5zb2wubm8iLAogICAgICAgICAgICAgICAgICAgICAgcidiYW5nPXdhbGxvcDsgdmVyc2lvbj0xOyBkb21haW49Ii5zb2wubm8iOyAnCiAgICAgICAgICAgICAgICAgICAgICByJ3BvcnQ9IjkwLDEwMCwgODAsODA4MCI7ICcKICAgICAgICAgICAgICAgICAgICAgIHInbWF4LWFnZT0xMDA7IENvbW1lbnQgPSAiSnVzdCBraWRkaW5nISAoXCJ8XFxcXCkgIicpCgogICAgICAgIHZlcnNpb25zID0gWzEsIDEsIDEsIDAsIDFdCiAgICAgICAgbmFtZXMgPSBbImJhbmciLCAiZm9vIiwgImZvbyIsICJzcGFtIiwgImZvbyJdCiAgICAgICAgZG9tYWlucyA9IFsiLnNvbC5ubyIsICJibGFoLnNwYW0ub3JnIiwgInd3dy5hY21lLmNvbSIsCiAgICAgICAgICAgICAgICAgICAid3d3LmFjbWUuY29tIiwgInd3dy5hY21lLmNvbSJdCiAgICAgICAgcGF0aHMgPSBbIi8iLCAiLyIsICIvIiwgIi9ibGFoIiwgIi9ibGFoLyJdCgogICAgICAgIGZvciBpIGluIHJhbmdlKDQpOgogICAgICAgICAgICBpID0gMAogICAgICAgICAgICBmb3IgYyBpbiBjczoKICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0SXNJbnN0YW5jZShjLCBDb29raWUpCiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGMudmVyc2lvbiwgdmVyc2lvbnNbaV0pCiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGMubmFtZSwgbmFtZXNbaV0pCiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGMuZG9tYWluLCBkb21haW5zW2ldKQogICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjLnBhdGgsIHBhdGhzW2ldKQogICAgICAgICAgICAgICAgaSA9IGkgKyAxCgogICAgZGVmIHRlc3RfcGFyc2VfbnNfaGVhZGVycyhzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgcGFyc2VfbnNfaGVhZGVycwoKICAgICAgICAjIG1pc3NpbmcgZG9tYWluIHZhbHVlIChpbnZhbGlkIGNvb2tpZSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKAogICAgICAgICAgICBwYXJzZV9uc19oZWFkZXJzKFsiZm9vPWJhcjsgcGF0aD0vOyBkb21haW4iXSksCiAgICAgICAgICAgIFtbKCJmb28iLCAiYmFyIiksCiAgICAgICAgICAgICAgKCJwYXRoIiwgIi8iKSwgKCJkb21haW4iLCBOb25lKSwgKCJ2ZXJzaW9uIiwgIjAiKV1dCiAgICAgICAgICAgICkKICAgICAgICAjIGludmFsaWQgZXhwaXJlcyB2YWx1ZQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoCiAgICAgICAgICAgIHBhcnNlX25zX2hlYWRlcnMoWyJmb289YmFyOyBleHBpcmVzPUZvbyBCYXIgMTIgMzM6MjI6MTEgMjAwMCJdKSwKICAgICAgICAgICAgW1soImZvbyIsICJiYXIiKSwgKCJleHBpcmVzIiwgTm9uZSksICgidmVyc2lvbiIsICIwIildXQogICAgICAgICAgICApCiAgICAgICAgIyBtaXNzaW5nIGNvb2tpZSB2YWx1ZSAodmFsaWQgY29va2llKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoCiAgICAgICAgICAgIHBhcnNlX25zX2hlYWRlcnMoWyJmb28iXSksCiAgICAgICAgICAgIFtbKCJmb28iLCBOb25lKSwgKCJ2ZXJzaW9uIiwgIjAiKV1dCiAgICAgICAgICAgICkKICAgICAgICAjIHNob3VsZG4ndCBhZGQgdmVyc2lvbiBpZiBoZWFkZXIgaXMgZW1wdHkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHBhcnNlX25zX2hlYWRlcnMoWyIiXSksIFtdKQoKICAgIGRlZiB0ZXN0X2JhZF9jb29raWVfaGVhZGVyKHNlbGYpOgoKICAgICAgICBkZWYgY29va2llamFyX2Zyb21fY29va2llX2hlYWRlcnMoaGVhZGVycyk6CiAgICAgICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIKICAgICAgICAgICAgZnJvbSB1cmxsaWIyIGltcG9ydCBSZXF1ZXN0CiAgICAgICAgICAgIGMgPSBDb29raWVKYXIoKQogICAgICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmV4YW1wbGUuY29tLyIpCiAgICAgICAgICAgIHIgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vIikKICAgICAgICAgICAgYy5leHRyYWN0X2Nvb2tpZXMociwgcmVxKQogICAgICAgICAgICByZXR1cm4gYwoKICAgICAgICAjIG5vbmUgb2YgdGhlc2UgYmFkIGhlYWRlcnMgc2hvdWxkIGNhdXNlIGFuIGV4Y2VwdGlvbiB0byBiZSByYWlzZWQKICAgICAgICBmb3IgaGVhZGVycyBpbiBbCiAgICAgICAgICAgIFsiU2V0LUNvb2tpZTogIl0sICAjIGFjdHVhbGx5LCBub3RoaW5nIHdyb25nIHdpdGggdGhpcwogICAgICAgICAgICBbIlNldC1Db29raWUyOiAiXSwgICMgZGl0dG8KICAgICAgICAgICAgIyBtaXNzaW5nIGRvbWFpbiB2YWx1ZQogICAgICAgICAgICBbIlNldC1Db29raWUyOiBhPWZvbzsgcGF0aD0vOyBWZXJzaW9uPTE7IGRvbWFpbiJdLAogICAgICAgICAgICAjIGJhZCBtYXgtYWdlCiAgICAgICAgICAgIFsiU2V0LUNvb2tpZTogYj1mb287IG1heC1hZ2U9b29wcyJdLAogICAgICAgICAgICAjIGJhZCB2ZXJzaW9uCiAgICAgICAgICAgIFsiU2V0LUNvb2tpZTogYj1mb287IHZlcnNpb249c3BhbSJdLAogICAgICAgICAgICBdOgogICAgICAgICAgICBjID0gY29va2llamFyX2Zyb21fY29va2llX2hlYWRlcnMoaGVhZGVycykKICAgICAgICAgICAgIyB0aGVzZSBiYWQgY29va2llcyBzaG91bGRuJ3QgYmUgc2V0CiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAwKQoKICAgICAgICAjIGNvb2tpZSB3aXRoIGludmFsaWQgZXhwaXJlcyBpcyB0cmVhdGVkIGFzIHNlc3Npb24gY29va2llCiAgICAgICAgaGVhZGVycyA9IFsiU2V0LUNvb2tpZTogYz1mb287IGV4cGlyZXM9Rm9vIEJhciAxMiAzMzoyMjoxMSAyMDAwIl0KICAgICAgICBjID0gY29va2llamFyX2Zyb21fY29va2llX2hlYWRlcnMoaGVhZGVycykKICAgICAgICBjb29raWUgPSBjLl9jb29raWVzWyJ3d3cuZXhhbXBsZS5jb20iXVsiLyJdWyJjIl0KICAgICAgICBzZWxmLmFzc2VydFRydWUoY29va2llLmV4cGlyZXMgaXMgTm9uZSkKCgpjbGFzcyBMV1BDb29raWVUZXN0cyhUZXN0Q2FzZSk6CiAgICAjIFRlc3RzIHRha2VuIGZyb20gbGlid3d3LXBlcmwsIHdpdGggYSBmZXcgbW9kaWZpY2F0aW9ucyBhbmQgYWRkaXRpb25zLgoKICAgIGRlZiB0ZXN0X25ldHNjYXBlX2V4YW1wbGVfMShzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5CiAgICAgICAgZnJvbSB1cmxsaWIyIGltcG9ydCBSZXF1ZXN0CgogICAgICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgIyBGaXJzdCB3ZSBjaGVjayB0aGF0IGl0IHdvcmtzIGZvciB0aGUgb3JpZ2luYWwgZXhhbXBsZSBhdAogICAgICAgICMgaHR0cDovL3d3dy5uZXRzY2FwZS5jb20vbmV3c3JlZi9zdGQvY29va2llX3NwZWMuaHRtbAoKICAgICAgICAjIENsaWVudCByZXF1ZXN0cyBhIGRvY3VtZW50LCBhbmQgcmVjZWl2ZXMgaW4gdGhlIHJlc3BvbnNlOgogICAgICAgICMKICAgICAgICAjICAgICAgIFNldC1Db29raWU6IENVU1RPTUVSPVdJTEVfRV9DT1lPVEU7IHBhdGg9LzsgZXhwaXJlcz1XZWRuZXNkYXksIDA5LU5vdi05OSAyMzoxMjo0MCBHTVQKICAgICAgICAjCiAgICAgICAgIyBXaGVuIGNsaWVudCByZXF1ZXN0cyBhIFVSTCBpbiBwYXRoICIvIiBvbiB0aGlzIHNlcnZlciwgaXQgc2VuZHM6CiAgICAgICAgIwogICAgICAgICMgICAgICAgQ29va2llOiBDVVNUT01FUj1XSUxFX0VfQ09ZT1RFCiAgICAgICAgIwogICAgICAgICMgQ2xpZW50IHJlcXVlc3RzIGEgZG9jdW1lbnQsIGFuZCByZWNlaXZlcyBpbiB0aGUgcmVzcG9uc2U6CiAgICAgICAgIwogICAgICAgICMgICAgICAgU2V0LUNvb2tpZTogUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDE7IHBhdGg9LwogICAgICAgICMKICAgICAgICAjIFdoZW4gY2xpZW50IHJlcXVlc3RzIGEgVVJMIGluIHBhdGggIi8iIG9uIHRoaXMgc2VydmVyLCBpdCBzZW5kczoKICAgICAgICAjCiAgICAgICAgIyAgICAgICBDb29raWU6IENVU1RPTUVSPVdJTEVfRV9DT1lPVEU7IFBBUlRfTlVNQkVSPVJPQ0tFVF9MQVVOQ0hFUl8wMDAxCiAgICAgICAgIwogICAgICAgICMgQ2xpZW50IHJlY2VpdmVzOgogICAgICAgICMKICAgICAgICAjICAgICAgIFNldC1Db29raWU6IFNISVBQSU5HPUZFREVYOyBwYXRoPS9mbwogICAgICAgICMKICAgICAgICAjIFdoZW4gY2xpZW50IHJlcXVlc3RzIGEgVVJMIGluIHBhdGggIi8iIG9uIHRoaXMgc2VydmVyLCBpdCBzZW5kczoKICAgICAgICAjCiAgICAgICAgIyAgICAgICBDb29raWU6IENVU1RPTUVSPVdJTEVfRV9DT1lPVEU7IFBBUlRfTlVNQkVSPVJPQ0tFVF9MQVVOQ0hFUl8wMDAxCiAgICAgICAgIwogICAgICAgICMgV2hlbiBjbGllbnQgcmVxdWVzdHMgYSBVUkwgaW4gcGF0aCAiL2ZvbyIgb24gdGhpcyBzZXJ2ZXIsIGl0IHNlbmRzOgogICAgICAgICMKICAgICAgICAjICAgICAgIENvb2tpZTogQ1VTVE9NRVI9V0lMRV9FX0NPWU9URTsgUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDE7IFNISVBQSU5HPUZFREVYCiAgICAgICAgIwogICAgICAgICMgVGhlIGxhc3QgQ29va2llIGlzIGJ1Z2d5LCBiZWNhdXNlIGJvdGggc3BlY2lmaWNhdGlvbnMgc2F5IHRoYXQgdGhlCiAgICAgICAgIyBtb3N0IHNwZWNpZmljIGNvb2tpZSBtdXN0IGJlIHNlbnQgZmlyc3QuICBTSElQUElORz1GRURFWCBpcyB0aGUKICAgICAgICAjIG1vc3Qgc3BlY2lmaWMgYW5kIHNob3VsZCB0aHVzIGJlIGZpcnN0LgoKICAgICAgICB5ZWFyX3BsdXNfb25lID0gdGltZS5sb2NhbHRpbWUoKVswXSArIDEKCiAgICAgICAgaGVhZGVycyA9IFtdCgogICAgICAgIGMgPSBDb29raWVKYXIoRGVmYXVsdENvb2tpZVBvbGljeShyZmMyOTY1ID0gVHJ1ZSkpCgogICAgICAgICNyZXEgPSBSZXF1ZXN0KCJodHRwOi8vMS4xLjEuMS8iLAogICAgICAgICMgICAgICAgICAgICAgIGhlYWRlcnM9eyJIb3N0IjogInd3dy5hY21lLmNvbTo4MCJ9KQogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuYWNtZS5jb206ODAvIiwKICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM9eyJIb3N0IjogInd3dy5hY21lLmNvbTo4MCJ9KQoKICAgICAgICBoZWFkZXJzLmFwcGVuZCgKICAgICAgICAgICAgIlNldC1Db29raWU6IENVU1RPTUVSPVdJTEVfRV9DT1lPVEU7IHBhdGg9LyA7ICIKICAgICAgICAgICAgImV4cGlyZXM9V2VkbmVzZGF5LCAwOS1Ob3YtJWQgMjM6MTI6NDAgR01UIiAlIHllYXJfcGx1c19vbmUpCiAgICAgICAgcmVzID0gRmFrZVJlc3BvbnNlKGhlYWRlcnMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIpCiAgICAgICAgYy5leHRyYWN0X2Nvb2tpZXMocmVzLCByZXEpCgogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuYWNtZS5jb20vIikKICAgICAgICBjLmFkZF9jb29raWVfaGVhZGVyKHJlcSkKCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyZXEuZ2V0X2hlYWRlcigiQ29va2llIiksICJDVVNUT01FUj1XSUxFX0VfQ09ZT1RFIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcS5nZXRfaGVhZGVyKCJDb29raWUyIiksICckVmVyc2lvbj0iMSInKQoKICAgICAgICBoZWFkZXJzLmFwcGVuZCgiU2V0LUNvb2tpZTogUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDE7IHBhdGg9LyIpCiAgICAgICAgcmVzID0gRmFrZVJlc3BvbnNlKGhlYWRlcnMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIpCiAgICAgICAgYy5leHRyYWN0X2Nvb2tpZXMocmVzLCByZXEpCgogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuYWNtZS5jb20vZm9vL2JhciIpCiAgICAgICAgYy5hZGRfY29va2llX2hlYWRlcihyZXEpCgogICAgICAgIGggPSByZXEuZ2V0X2hlYWRlcigiQ29va2llIikKICAgICAgICBzZWxmLmFzc2VydEluKCJQQVJUX05VTUJFUj1ST0NLRVRfTEFVTkNIRVJfMDAwMSIsIGgpCiAgICAgICAgc2VsZi5hc3NlcnRJbigiQ1VTVE9NRVI9V0lMRV9FX0NPWU9URSIsIGgpCgogICAgICAgIGhlYWRlcnMuYXBwZW5kKCdTZXQtQ29va2llOiBTSElQUElORz1GRURFWDsgcGF0aD0vZm9vJykKICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuYWNtZS5jb20iKQogICAgICAgIGMuZXh0cmFjdF9jb29raWVzKHJlcywgcmVxKQoKICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmFjbWUuY29tLyIpCiAgICAgICAgYy5hZGRfY29va2llX2hlYWRlcihyZXEpCgogICAgICAgIGggPSByZXEuZ2V0X2hlYWRlcigiQ29va2llIikKICAgICAgICBzZWxmLmFzc2VydEluKCJQQVJUX05VTUJFUj1ST0NLRVRfTEFVTkNIRVJfMDAwMSIsIGgpCiAgICAgICAgc2VsZi5hc3NlcnRJbigiQ1VTVE9NRVI9V0lMRV9FX0NPWU9URSIsIGgpCiAgICAgICAgc2VsZi5hc3NlcnROb3RJbigiU0hJUFBJTkc9RkVERVgiLCBoKQoKICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmFjbWUuY29tL2Zvby8iKQogICAgICAgIGMuYWRkX2Nvb2tpZV9oZWFkZXIocmVxKQoKICAgICAgICBoID0gcmVxLmdldF9oZWFkZXIoIkNvb2tpZSIpCiAgICAgICAgc2VsZi5hc3NlcnRJbigiUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDEiLCBoKQogICAgICAgIHNlbGYuYXNzZXJ0SW4oIkNVU1RPTUVSPVdJTEVfRV9DT1lPVEUiLCBoKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShoLnN0YXJ0c3dpdGgoIlNISVBQSU5HPUZFREVYOyIpKQoKICAgIGRlZiB0ZXN0X25ldHNjYXBlX2V4YW1wbGVfMihzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyCiAgICAgICAgZnJvbSB1cmxsaWIyIGltcG9ydCBSZXF1ZXN0CgogICAgICAgICMgU2Vjb25kIEV4YW1wbGUgdHJhbnNhY3Rpb24gc2VxdWVuY2U6CiAgICAgICAgIwogICAgICAgICMgQXNzdW1lIGFsbCBtYXBwaW5ncyBmcm9tIGFib3ZlIGhhdmUgYmVlbiBjbGVhcmVkLgogICAgICAgICMKICAgICAgICAjIENsaWVudCByZWNlaXZlczoKICAgICAgICAjCiAgICAgICAgIyAgICAgICBTZXQtQ29va2llOiBQQVJUX05VTUJFUj1ST0NLRVRfTEFVTkNIRVJfMDAwMTsgcGF0aD0vCiAgICAgICAgIwogICAgICAgICMgV2hlbiBjbGllbnQgcmVxdWVzdHMgYSBVUkwgaW4gcGF0aCAiLyIgb24gdGhpcyBzZXJ2ZXIsIGl0IHNlbmRzOgogICAgICAgICMKICAgICAgICAjICAgICAgIENvb2tpZTogUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDEKICAgICAgICAjCiAgICAgICAgIyBDbGllbnQgcmVjZWl2ZXM6CiAgICAgICAgIwogICAgICAgICMgICAgICAgU2V0LUNvb2tpZTogUEFSVF9OVU1CRVI9UklESU5HX1JPQ0tFVF8wMDIzOyBwYXRoPS9hbW1vCiAgICAgICAgIwogICAgICAgICMgV2hlbiBjbGllbnQgcmVxdWVzdHMgYSBVUkwgaW4gcGF0aCAiL2FtbW8iIG9uIHRoaXMgc2VydmVyLCBpdCBzZW5kczoKICAgICAgICAjCiAgICAgICAgIyAgICAgICBDb29raWU6IFBBUlRfTlVNQkVSPVJJRElOR19ST0NLRVRfMDAyMzsgUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDEKICAgICAgICAjCiAgICAgICAgIyAgICAgICBOT1RFOiBUaGVyZSBhcmUgdHdvIG5hbWUvdmFsdWUgcGFpcnMgbmFtZWQgIlBBUlRfTlVNQkVSIiBkdWUgdG8KICAgICAgICAjICAgICAgIHRoZSBpbmhlcml0YW5jZSBvZiB0aGUgIi8iIG1hcHBpbmcgaW4gYWRkaXRpb24gdG8gdGhlICIvYW1tbyIgbWFwcGluZy4KCiAgICAgICAgYyA9IENvb2tpZUphcigpCiAgICAgICAgaGVhZGVycyA9IFtdCgogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuYWNtZS5jb20vIikKICAgICAgICBoZWFkZXJzLmFwcGVuZCgiU2V0LUNvb2tpZTogUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDE7IHBhdGg9LyIpCiAgICAgICAgcmVzID0gRmFrZVJlc3BvbnNlKGhlYWRlcnMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIpCgogICAgICAgIGMuZXh0cmFjdF9jb29raWVzKHJlcywgcmVxKQoKICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmFjbWUuY29tLyIpCiAgICAgICAgYy5hZGRfY29va2llX2hlYWRlcihyZXEpCgogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVxLmdldF9oZWFkZXIoIkNvb2tpZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICJQQVJUX05VTUJFUj1ST0NLRVRfTEFVTkNIRVJfMDAwMSIpCgogICAgICAgIGhlYWRlcnMuYXBwZW5kKAogICAgICAgICAgICAiU2V0LUNvb2tpZTogUEFSVF9OVU1CRVI9UklESU5HX1JPQ0tFVF8wMDIzOyBwYXRoPS9hbW1vIikKICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuYWNtZS5jb20vIikKICAgICAgICBjLmV4dHJhY3RfY29va2llcyhyZXMsIHJlcSkKCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hY21lLmNvbS9hbW1vIikKICAgICAgICBjLmFkZF9jb29raWVfaGVhZGVyKHJlcSkKCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHJlLnNlYXJjaChyIlBBUlRfTlVNQkVSPVJJRElOR19ST0NLRVRfMDAyMztccyoiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxLmdldF9oZWFkZXIoIkNvb2tpZSIpKSkKCiAgICBkZWYgdGVzdF9pZXRmX2V4YW1wbGVfMShzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5CiAgICAgICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAjIFRoZW4gd2UgdGVzdCB3aXRoIHRoZSBleGFtcGxlcyBmcm9tIGRyYWZ0LWlldGYtaHR0cC1zdGF0ZS1tYW4tbWVjLTAzLnR4dAogICAgICAgICMKICAgICAgICAjIDUuICBFWEFNUExFUwoKICAgICAgICBjID0gQ29va2llSmFyKERlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NT1UcnVlKSkKCiAgICAgICAgIwogICAgICAgICMgNS4xICBFeGFtcGxlIDEKICAgICAgICAjCiAgICAgICAgIyBNb3N0IGRldGFpbCBvZiByZXF1ZXN0IGFuZCByZXNwb25zZSBoZWFkZXJzIGhhcyBiZWVuIG9taXR0ZWQuICBBc3N1bWUKICAgICAgICAjIHRoZSB1c2VyIGFnZW50IGhhcyBubyBzdG9yZWQgY29va2llcy4KICAgICAgICAjCiAgICAgICAgIyAgIDEuICBVc2VyIEFnZW50IC0+IFNlcnZlcgogICAgICAgICMKICAgICAgICAjICAgICAgIFBPU1QgL2FjbWUvbG9naW4gSFRUUC8xLjEKICAgICAgICAjICAgICAgIFtmb3JtIGRhdGFdCiAgICAgICAgIwogICAgICAgICMgICAgICAgVXNlciBpZGVudGlmaWVzIHNlbGYgdmlhIGEgZm9ybS4KICAgICAgICAjCiAgICAgICAgIyAgIDIuICBTZXJ2ZXIgLT4gVXNlciBBZ2VudAogICAgICAgICMKICAgICAgICAjICAgICAgIEhUVFAvMS4xIDIwMCBPSwogICAgICAgICMgICAgICAgU2V0LUNvb2tpZTI6IEN1c3RvbWVyPSJXSUxFX0VfQ09ZT1RFIjsgVmVyc2lvbj0iMSI7IFBhdGg9Ii9hY21lIgogICAgICAgICMKICAgICAgICAjICAgICAgIENvb2tpZSByZWZsZWN0cyB1c2VyJ3MgaWRlbnRpdHkuCgogICAgICAgIGNvb2tpZSA9IGludGVyYWN0XzI5NjUoCiAgICAgICAgICAgIGMsICdodHRwOi8vd3d3LmFjbWUuY29tL2FjbWUvbG9naW4nLAogICAgICAgICAgICAnQ3VzdG9tZXI9IldJTEVfRV9DT1lPVEUiOyBWZXJzaW9uPSIxIjsgUGF0aD0iL2FjbWUiJykKICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGNvb2tpZSkKCiAgICAgICAgIwogICAgICAgICMgICAzLiAgVXNlciBBZ2VudCAtPiBTZXJ2ZXIKICAgICAgICAjCiAgICAgICAgIyAgICAgICBQT1NUIC9hY21lL3BpY2tpdGVtIEhUVFAvMS4xCiAgICAgICAgIyAgICAgICBDb29raWU6ICRWZXJzaW9uPSIxIjsgQ3VzdG9tZXI9IldJTEVfRV9DT1lPVEUiOyAkUGF0aD0iL2FjbWUiCiAgICAgICAgIyAgICAgICBbZm9ybSBkYXRhXQogICAgICAgICMKICAgICAgICAjICAgICAgIFVzZXIgc2VsZWN0cyBhbiBpdGVtIGZvciBgYHNob3BwaW5nIGJhc2tldC4nJwogICAgICAgICMKICAgICAgICAjICAgNC4gIFNlcnZlciAtPiBVc2VyIEFnZW50CiAgICAgICAgIwogICAgICAgICMgICAgICAgSFRUUC8xLjEgMjAwIE9LCiAgICAgICAgIyAgICAgICBTZXQtQ29va2llMjogUGFydF9OdW1iZXI9IlJvY2tldF9MYXVuY2hlcl8wMDAxIjsgVmVyc2lvbj0iMSI7CiAgICAgICAgIyAgICAgICAgICAgICAgIFBhdGg9Ii9hY21lIgogICAgICAgICMKICAgICAgICAjICAgICAgIFNob3BwaW5nIGJhc2tldCBjb250YWlucyBhbiBpdGVtLgoKICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICdodHRwOi8vd3d3LmFjbWUuY29tL2FjbWUvcGlja2l0ZW0nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BhcnRfTnVtYmVyPSJSb2NrZXRfTGF1bmNoZXJfMDAwMSI7ICcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdWZXJzaW9uPSIxIjsgUGF0aD0iL2FjbWUiJyk7CiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHJlLnNlYXJjaCgKICAgICAgICAgICAgcideXCRWZXJzaW9uPSI/MSI/OyBDdXN0b21lcj0iP1dJTEVfRV9DT1lPVEUiPzsgXCRQYXRoPSIvYWNtZSIkJywKICAgICAgICAgICAgY29va2llKSkKCiAgICAgICAgIwogICAgICAgICMgICA1LiAgVXNlciBBZ2VudCAtPiBTZXJ2ZXIKICAgICAgICAjCiAgICAgICAgIyAgICAgICBQT1NUIC9hY21lL3NoaXBwaW5nIEhUVFAvMS4xCiAgICAgICAgIyAgICAgICBDb29raWU6ICRWZXJzaW9uPSIxIjsKICAgICAgICAjICAgICAgICAgICAgICAgQ3VzdG9tZXI9IldJTEVfRV9DT1lPVEUiOyAkUGF0aD0iL2FjbWUiOwogICAgICAgICMgICAgICAgICAgICAgICBQYXJ0X051bWJlcj0iUm9ja2V0X0xhdW5jaGVyXzAwMDEiOyAkUGF0aD0iL2FjbWUiCiAgICAgICAgIyAgICAgICBbZm9ybSBkYXRhXQogICAgICAgICMKICAgICAgICAjICAgICAgIFVzZXIgc2VsZWN0cyBzaGlwcGluZyBtZXRob2QgZnJvbSBmb3JtLgogICAgICAgICMKICAgICAgICAjICAgNi4gIFNlcnZlciAtPiBVc2VyIEFnZW50CiAgICAgICAgIwogICAgICAgICMgICAgICAgSFRUUC8xLjEgMjAwIE9LCiAgICAgICAgIyAgICAgICBTZXQtQ29va2llMjogU2hpcHBpbmc9IkZlZEV4IjsgVmVyc2lvbj0iMSI7IFBhdGg9Ii9hY21lIgogICAgICAgICMKICAgICAgICAjICAgICAgIE5ldyBjb29raWUgcmVmbGVjdHMgc2hpcHBpbmcgbWV0aG9kLgoKICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2FjbWUvc2hpcHBpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1NoaXBwaW5nPSJGZWRFeCI7IFZlcnNpb249IjEiOyBQYXRoPSIvYWNtZSInKQoKICAgICAgICBzZWxmLmFzc2VydFRydWUocmUuc2VhcmNoKHInXlwkVmVyc2lvbj0iPzEiPzsnLCBjb29raWUpKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZS5zZWFyY2gocidQYXJ0X051bWJlcj0iP1JvY2tldF9MYXVuY2hlcl8wMDAxIj87JwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1xzKlwkUGF0aD0iXC9hY21lIicsIGNvb2tpZSkpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHJlLnNlYXJjaChyJ0N1c3RvbWVyPSI/V0lMRV9FX0NPWU9URSI/O1xzKlwkUGF0aD0iXC9hY21lIicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29raWUpKQoKICAgICAgICAjCiAgICAgICAgIyAgIDcuICBVc2VyIEFnZW50IC0+IFNlcnZlcgogICAgICAgICMKICAgICAgICAjICAgICAgIFBPU1QgL2FjbWUvcHJvY2VzcyBIVFRQLzEuMQogICAgICAgICMgICAgICAgQ29va2llOiAkVmVyc2lvbj0iMSI7CiAgICAgICAgIyAgICAgICAgICAgICAgIEN1c3RvbWVyPSJXSUxFX0VfQ09ZT1RFIjsgJFBhdGg9Ii9hY21lIjsKICAgICAgICAjICAgICAgICAgICAgICAgUGFydF9OdW1iZXI9IlJvY2tldF9MYXVuY2hlcl8wMDAxIjsgJFBhdGg9Ii9hY21lIjsKICAgICAgICAjICAgICAgICAgICAgICAgU2hpcHBpbmc9IkZlZEV4IjsgJFBhdGg9Ii9hY21lIgogICAgICAgICMgICAgICAgW2Zvcm0gZGF0YV0KICAgICAgICAjCiAgICAgICAgIyAgICAgICBVc2VyIGNob29zZXMgdG8gcHJvY2VzcyBvcmRlci4KICAgICAgICAjCiAgICAgICAgIyAgIDguICBTZXJ2ZXIgLT4gVXNlciBBZ2VudAogICAgICAgICMKICAgICAgICAjICAgICAgIEhUVFAvMS4xIDIwMCBPSwogICAgICAgICMKICAgICAgICAjICAgICAgIFRyYW5zYWN0aW9uIGlzIGNvbXBsZXRlLgoKICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2FjbWUvcHJvY2VzcyIpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKAogICAgICAgICAgICByZS5zZWFyY2gocidTaGlwcGluZz0iP0ZlZEV4Ij87XHMqXCRQYXRoPSJcL2FjbWUiJywgY29va2llKSBhbmQKICAgICAgICAgICAgIldJTEVfRV9DT1lPVEUiIGluIGNvb2tpZSkKCiAgICAgICAgIwogICAgICAgICMgVGhlIHVzZXIgYWdlbnQgbWFrZXMgYSBzZXJpZXMgb2YgcmVxdWVzdHMgb24gdGhlIG9yaWdpbiBzZXJ2ZXIsIGFmdGVyCiAgICAgICAgIyBlYWNoIG9mIHdoaWNoIGl0IHJlY2VpdmVzIGEgbmV3IGNvb2tpZS4gIEFsbCB0aGUgY29va2llcyBoYXZlIHRoZSBzYW1lCiAgICAgICAgIyBQYXRoIGF0dHJpYnV0ZSBhbmQgKGRlZmF1bHQpIGRvbWFpbi4gIEJlY2F1c2UgdGhlIHJlcXVlc3QgVVJMcyBhbGwgaGF2ZQogICAgICAgICMgL2FjbWUgYXMgYSBwcmVmaXgsIGFuZCB0aGF0IG1hdGNoZXMgdGhlIFBhdGggYXR0cmlidXRlLCBlYWNoIHJlcXVlc3QKICAgICAgICAjIGNvbnRhaW5zIGFsbCB0aGUgY29va2llcyByZWNlaXZlZCBzbyBmYXIuCgogICAgZGVmIHRlc3RfaWV0Zl9leGFtcGxlXzIoc2VsZik6CiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphciwgRGVmYXVsdENvb2tpZVBvbGljeQoKICAgICAgICAjIDUuMiAgRXhhbXBsZSAyCiAgICAgICAgIwogICAgICAgICMgVGhpcyBleGFtcGxlIGlsbHVzdHJhdGVzIHRoZSBlZmZlY3Qgb2YgdGhlIFBhdGggYXR0cmlidXRlLiAgQWxsIGRldGFpbAogICAgICAgICMgb2YgcmVxdWVzdCBhbmQgcmVzcG9uc2UgaGVhZGVycyBoYXMgYmVlbiBvbWl0dGVkLiAgQXNzdW1lIHRoZSB1c2VyIGFnZW50CiAgICAgICAgIyBoYXMgbm8gc3RvcmVkIGNvb2tpZXMuCgogICAgICAgIGMgPSBDb29raWVKYXIoRGVmYXVsdENvb2tpZVBvbGljeShyZmMyOTY1PVRydWUpKQoKICAgICAgICAjIEltYWdpbmUgdGhlIHVzZXIgYWdlbnQgaGFzIHJlY2VpdmVkLCBpbiByZXNwb25zZSB0byBlYXJsaWVyIHJlcXVlc3RzLAogICAgICAgICMgdGhlIHJlc3BvbnNlIGhlYWRlcnMKICAgICAgICAjCiAgICAgICAgIyBTZXQtQ29va2llMjogUGFydF9OdW1iZXI9IlJvY2tldF9MYXVuY2hlcl8wMDAxIjsgVmVyc2lvbj0iMSI7CiAgICAgICAgIyAgICAgICAgIFBhdGg9Ii9hY21lIgogICAgICAgICMKICAgICAgICAjIGFuZAogICAgICAgICMKICAgICAgICAjIFNldC1Db29raWUyOiBQYXJ0X051bWJlcj0iUmlkaW5nX1JvY2tldF8wMDIzIjsgVmVyc2lvbj0iMSI7CiAgICAgICAgIyAgICAgICAgIFBhdGg9Ii9hY21lL2FtbW8iCgogICAgICAgIGludGVyYWN0XzI5NjUoCiAgICAgICAgICAgIGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2FjbWUvYW1tby9zcGVjaWZpYyIsCiAgICAgICAgICAgICdQYXJ0X051bWJlcj0iUm9ja2V0X0xhdW5jaGVyXzAwMDEiOyBWZXJzaW9uPSIxIjsgUGF0aD0iL2FjbWUiJywKICAgICAgICAgICAgJ1BhcnRfTnVtYmVyPSJSaWRpbmdfUm9ja2V0XzAwMjMiOyBWZXJzaW9uPSIxIjsgUGF0aD0iL2FjbWUvYW1tbyInKQoKICAgICAgICAjIEEgc3Vic2VxdWVudCByZXF1ZXN0IGJ5IHRoZSB1c2VyIGFnZW50IHRvIHRoZSAoc2FtZSkgc2VydmVyIGZvciBVUkxzIG9mCiAgICAgICAgIyB0aGUgZm9ybSAvYWNtZS9hbW1vLy4uLiAgd291bGQgaW5jbHVkZSB0aGUgZm9sbG93aW5nIHJlcXVlc3QgaGVhZGVyOgogICAgICAgICMKICAgICAgICAjIENvb2tpZTogJFZlcnNpb249IjEiOwogICAgICAgICMgICAgICAgICBQYXJ0X051bWJlcj0iUmlkaW5nX1JvY2tldF8wMDIzIjsgJFBhdGg9Ii9hY21lL2FtbW8iOwogICAgICAgICMgICAgICAgICBQYXJ0X051bWJlcj0iUm9ja2V0X0xhdW5jaGVyXzAwMDEiOyAkUGF0aD0iL2FjbWUiCiAgICAgICAgIwogICAgICAgICMgTm90ZSB0aGF0IHRoZSBOQU1FPVZBTFVFIHBhaXIgZm9yIHRoZSBjb29raWUgd2l0aCB0aGUgbW9yZSBzcGVjaWZpYyBQYXRoCiAgICAgICAgIyBhdHRyaWJ1dGUsIC9hY21lL2FtbW8sIGNvbWVzIGJlZm9yZSB0aGUgb25lIHdpdGggdGhlIGxlc3Mgc3BlY2lmaWMgUGF0aAogICAgICAgICMgYXR0cmlidXRlLCAvYWNtZS4gIEZ1cnRoZXIgbm90ZSB0aGF0IHRoZSBzYW1lIGNvb2tpZSBuYW1lIGFwcGVhcnMgbW9yZQogICAgICAgICMgdGhhbiBvbmNlLgoKICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2FjbWUvYW1tby8uLi4iKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSgKICAgICAgICAgICAgcmUuc2VhcmNoKHIiUmlkaW5nX1JvY2tldF8wMDIzLipSb2NrZXRfTGF1bmNoZXJfMDAwMSIsIGNvb2tpZSkpCgogICAgICAgICMgQSBzdWJzZXF1ZW50IHJlcXVlc3QgYnkgdGhlIHVzZXIgYWdlbnQgdG8gdGhlIChzYW1lKSBzZXJ2ZXIgZm9yIGEgVVJMIG9mCiAgICAgICAgIyB0aGUgZm9ybSAvYWNtZS9wYXJ0cy8gd291bGQgaW5jbHVkZSB0aGUgZm9sbG93aW5nIHJlcXVlc3QgaGVhZGVyOgogICAgICAgICMKICAgICAgICAjIENvb2tpZTogJFZlcnNpb249IjEiOyBQYXJ0X051bWJlcj0iUm9ja2V0X0xhdW5jaGVyXzAwMDEiOyAkUGF0aD0iL2FjbWUiCiAgICAgICAgIwogICAgICAgICMgSGVyZSwgdGhlIHNlY29uZCBjb29raWUncyBQYXRoIGF0dHJpYnV0ZSAvYWNtZS9hbW1vIGlzIG5vdCBhIHByZWZpeCBvZgogICAgICAgICMgdGhlIHJlcXVlc3QgVVJMLCAvYWNtZS9wYXJ0cy8sIHNvIHRoZSBjb29raWUgZG9lcyBub3QgZ2V0IGZvcndhcmRlZCB0bwogICAgICAgICMgdGhlIHNlcnZlci4KCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS9hY21lL3BhcnRzLyIpCiAgICAgICAgc2VsZi5hc3NlcnRJbigiUm9ja2V0X0xhdW5jaGVyXzAwMDEiLCBjb29raWUpCiAgICAgICAgc2VsZi5hc3NlcnROb3RJbigiUmlkaW5nX1JvY2tldF8wMDIzIiwgY29va2llKQoKICAgIGRlZiB0ZXN0X3JlamVjdGlvbihzZWxmKToKICAgICAgICAjIFRlc3QgcmVqZWN0aW9uIG9mIFNldC1Db29raWUyIHJlc3BvbnNlcyBiYXNlZCBvbiBkb21haW4sIHBhdGgsIHBvcnQuCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IERlZmF1bHRDb29raWVQb2xpY3ksIExXUENvb2tpZUphcgoKICAgICAgICBwb2wgPSBEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkKCiAgICAgICAgYyA9IExXUENvb2tpZUphcihwb2xpY3k9cG9sKQoKICAgICAgICBtYXhfYWdlID0gIm1heC1hZ2U9MzYwMCIKCiAgICAgICAgIyBpbGxlZ2FsIGRvbWFpbiAobm8gZW1iZWRkZWQgZG90cykKICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LmFjbWUuY29tIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmb289YmFyOyBkb21haW49Ii5jb20iOyB2ZXJzaW9uPTEnKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgYykKCiAgICAgICAgIyBsZWdhbCBkb21haW4KICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LmFjbWUuY29tIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwaW5nPXBvbmc7IGRvbWFpbj0iYWNtZS5jb20iOyB2ZXJzaW9uPTEnKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQoKICAgICAgICAjIGlsbGVnYWwgZG9tYWluIChob3N0IHByZWZpeCAid3d3LmEiIGNvbnRhaW5zIGEgZG90KQogICAgICAgIGNvb2tpZSA9IGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuYS5hY21lLmNvbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnd2hpej1iYW5nOyBkb21haW49ImFjbWUuY29tIjsgdmVyc2lvbj0xJykKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMSkKCiAgICAgICAgIyBsZWdhbCBkb21haW4KICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LmEuYWNtZS5jb20iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3dvdz1mbHV0dGVyOyBkb21haW49Ii5hLmFjbWUuY29tIjsgdmVyc2lvbj0xJykKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMikKCiAgICAgICAgIyBjYW4ndCBwYXJ0aWFsbHkgbWF0Y2ggYW4gSVAtYWRkcmVzcwogICAgICAgIGNvb2tpZSA9IGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly8xMjUuMTI1LjEyNS4xMjUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3p6eno9cGluZzsgZG9tYWluPSIxMjUuMTI1LjEyNSI7IHZlcnNpb249MScpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDIpCgogICAgICAgICMgaWxsZWdhbCBwYXRoIChtdXN0IGJlIHByZWZpeCBvZiByZXF1ZXN0IHBhdGgpCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5zb2wubm8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2JsYWg9cmh1YmFyYjsgZG9tYWluPSIuc29sLm5vIjsgcGF0aD0iL2ZvbyI7ICcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uPTEnKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAyKQoKICAgICAgICAjIGxlZ2FsIHBhdGgKICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LnNvbC5uby9mb28vYmFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdiaW5nPWJvbmc7IGRvbWFpbj0iLnNvbC5ubyI7IHBhdGg9Ii9mb28iOyAnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndmVyc2lvbj0xJykKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMykKCiAgICAgICAgIyBpbGxlZ2FsIHBvcnQgKHJlcXVlc3QtcG9ydCBub3QgaW4gbGlzdCkKICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LnNvbC5ubyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnd2hpej1mZmZ0OyBkb21haW49Ii5zb2wubm8iOyBwb3J0PSI5MCwxMDAiOyAnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndmVyc2lvbj0xJykKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMykKCiAgICAgICAgIyBsZWdhbCBwb3J0CiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NSgKICAgICAgICAgICAgYywgImh0dHA6Ly93d3cuc29sLm5vIiwKICAgICAgICAgICAgcidiYW5nPXdhbGxvcDsgdmVyc2lvbj0xOyBkb21haW49Ii5zb2wubm8iOyAnCiAgICAgICAgICAgIHIncG9ydD0iOTAsMTAwLCA4MCw4MDgwIjsgJwogICAgICAgICAgICByJ21heC1hZ2U9MTAwOyBDb21tZW50ID0gIkp1c3Qga2lkZGluZyEgKFwifFxcXFwpICInKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCA0KQoKICAgICAgICAjIHBvcnQgYXR0cmlidXRlIHdpdGhvdXQgYW55IHZhbHVlIChjdXJyZW50IHBvcnQpCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5zb2wubm8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2Zvbzk9YmFyOyB2ZXJzaW9uPTE7IGRvbWFpbj0iLnNvbC5ubyI7IHBvcnQ7ICcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdtYXgtYWdlPTEwMDsnKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCA1KQoKICAgICAgICAjIGVuY29kZWQgcGF0aAogICAgICAgICMgTFdQIGhhcyB0aGlzIHRlc3QsIGJ1dCB1bmVzY2FwaW5nIGFsbG93ZWQgcGF0aCBjaGFyYWN0ZXJzIHNlZW1zCiAgICAgICAgIyBsaWtlIGEgYmFkIGlkZWEsIHNvIEkgdGhpbmsgdGhpcyBzaG91bGQgZmFpbDoKIyMgICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LnNvbC5uby9mb28vIiwKIyMgICAgICAgICAgICAgICAgICAgICAgICAgICByJ2Zvbzg9YmFyOyB2ZXJzaW9uPTE7IHBhdGg9Ii8lNjZvbyInKQogICAgICAgICMgYnV0IHRoaXMgaXMgT0ssIGJlY2F1c2UgJzwnIGlzIG5vdCBhbiBhbGxvd2VkIEhUVFAgVVJMIHBhdGgKICAgICAgICAjIGNoYXJhY3RlcjoKICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LnNvbC5uby88b28vIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHInZm9vOD1iYXI7IHZlcnNpb249MTsgcGF0aD0iLyUzY29vIicpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDYpCgogICAgICAgICMgc2F2ZSBhbmQgcmVzdG9yZQogICAgICAgIGZpbGVuYW1lID0gdGVzdF9zdXBwb3J0LlRFU1RGTgoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGMuc2F2ZShmaWxlbmFtZSwgaWdub3JlX2Rpc2NhcmQ9VHJ1ZSkKICAgICAgICAgICAgb2xkID0gcmVwcihjKQoKICAgICAgICAgICAgYyA9IExXUENvb2tpZUphcihwb2xpY3k9cG9sKQogICAgICAgICAgICBjLmxvYWQoZmlsZW5hbWUsIGlnbm9yZV9kaXNjYXJkPVRydWUpCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgdHJ5OiBvcy51bmxpbmsoZmlsZW5hbWUpCiAgICAgICAgICAgIGV4Y2VwdCBPU0Vycm9yOiBwYXNzCgogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwob2xkLCByZXByKGMpKQoKICAgIGRlZiB0ZXN0X3VybF9lbmNvZGluZyhzZWxmKToKICAgICAgICAjIFRyeSBzb21lIFVSTCBlbmNvZGluZ3Mgb2YgdGhlIFBBVEhzLgogICAgICAgICMgKHRoZSBiZWhhdmlvdXIgaGVyZSBoYXMgY2hhbmdlZCBmcm9tIGxpYnd3dy1wZXJsKQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIsIERlZmF1bHRDb29raWVQb2xpY3kKCiAgICAgICAgYyA9IENvb2tpZUphcihEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkpCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS9mb28lMmYlMjUvJTNjJTNjJTBBbmV3JUU1LyVFNSIsCiAgICAgICAgICAgICAgICAgICAgICAiZm9vICA9ICAgYmFyOyB2ZXJzaW9uICAgID0gICAxIikKCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NSgKICAgICAgICAgICAgYywgImh0dHA6Ly93d3cuYWNtZS5jb20vZm9vJTJmJTI1Lzw8JTBhbmV35S/m+OUiLAogICAgICAgICAgICAnYmFyPWJhejsgcGF0aD0iL2Zvby8iOyB2ZXJzaW9uPTEnKTsKICAgICAgICB2ZXJzaW9uX3JlID0gcmUuY29tcGlsZShyJ15cJHZlcnNpb249XCI/MVwiPycsIHJlLkkpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKCJmb289YmFyIiBpbiBjb29raWUgYW5kIHZlcnNpb25fcmUuc2VhcmNoKGNvb2tpZSkpCgogICAgICAgIGNvb2tpZSA9IGludGVyYWN0XzI5NjUoCiAgICAgICAgICAgIGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2Zvby8lMjUvPDwlMGFuZXflL+b45SIpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBjb29raWUpCgogICAgICAgICMgdW5pY29kZSBVUkwgZG9lc24ndCByYWlzZSBleGNlcHRpb24KICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsIHUiaHR0cDovL3d3dy5hY21lLmNvbS9ceGZjIikKCiAgICBkZWYgdGVzdF9tb3ppbGxhKHNlbGYpOgogICAgICAgICMgU2F2ZSAvIGxvYWQgTW96aWxsYS9OZXRzY2FwZSBjb29raWUgZmlsZSBmb3JtYXQuCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IE1vemlsbGFDb29raWVKYXIsIERlZmF1bHRDb29raWVQb2xpY3kKCiAgICAgICAgeWVhcl9wbHVzX29uZSA9IHRpbWUubG9jYWx0aW1lKClbMF0gKyAxCgogICAgICAgIGZpbGVuYW1lID0gdGVzdF9zdXBwb3J0LlRFU1RGTgoKICAgICAgICBjID0gTW96aWxsYUNvb2tpZUphcihmaWxlbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2xpY3k9RGVmYXVsdENvb2tpZVBvbGljeShyZmMyOTY1PVRydWUpKQogICAgICAgIGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIiwKICAgICAgICAgICAgICAgICAgICAgICJmb28xPWJhcjsgbWF4LWFnZT0xMDA7IFZlcnNpb249MSIpCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLAogICAgICAgICAgICAgICAgICAgICAgJ2ZvbzI9YmFyOyBwb3J0PSI4MCI7IG1heC1hZ2U9MTAwOyBEaXNjYXJkOyBWZXJzaW9uPTEnKQogICAgICAgIGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIiwgImZvbzM9YmFyOyBzZWN1cmU7IFZlcnNpb249MSIpCgogICAgICAgIGV4cGlyZXMgPSAiZXhwaXJlcz0wOS1Ob3YtJWQgMjM6MTI6NDAgR01UIiAlICh5ZWFyX3BsdXNfb25lLCkKICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5mb28uY29tLyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgImZvb2E9YmFyOyAlcyIgJSBleHBpcmVzKQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmZvby5jb20vIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiZm9vYj1iYXI7IERvbWFpbj0uZm9vLmNvbTsgJXMiICUgZXhwaXJlcykKICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5mb28uY29tLyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgImZvb2M9YmFyOyBEb21haW49d3d3LmZvby5jb207ICVzIiAlIGV4cGlyZXMpCgogICAgICAgIGRlZiBzYXZlX2FuZF9yZXN0b3JlKGNqLCBpZ25vcmVfZGlzY2FyZCk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGNqLnNhdmUoaWdub3JlX2Rpc2NhcmQ9aWdub3JlX2Rpc2NhcmQpCiAgICAgICAgICAgICAgICBuZXdfYyA9IE1vemlsbGFDb29raWVKYXIoZmlsZW5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmYXVsdENvb2tpZVBvbGljeShyZmMyOTY1PVRydWUpKQogICAgICAgICAgICAgICAgbmV3X2MubG9hZChpZ25vcmVfZGlzY2FyZD1pZ25vcmVfZGlzY2FyZCkKICAgICAgICAgICAgZmluYWxseToKICAgICAgICAgICAgICAgIHRyeTogb3MudW5saW5rKGZpbGVuYW1lKQogICAgICAgICAgICAgICAgZXhjZXB0IE9TRXJyb3I6IHBhc3MKICAgICAgICAgICAgcmV0dXJuIG5ld19jCgogICAgICAgIG5ld19jID0gc2F2ZV9hbmRfcmVzdG9yZShjLCBUcnVlKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKG5ld19jKSwgNikgICMgbm9uZSBkaXNjYXJkZWQKICAgICAgICBzZWxmLmFzc2VydEluKCJuYW1lPSdmb28xJywgdmFsdWU9J2JhciciLCByZXByKG5ld19jKSkKCiAgICAgICAgbmV3X2MgPSBzYXZlX2FuZF9yZXN0b3JlKGMsIEZhbHNlKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKG5ld19jKSwgNCkgICMgMiBvZiB0aGVtIGRpc2NhcmRlZCBvbiBzYXZlCiAgICAgICAgc2VsZi5hc3NlcnRJbigibmFtZT0nZm9vMScsIHZhbHVlPSdiYXInIiwgcmVwcihuZXdfYykpCgogICAgZGVmIHRlc3RfbmV0c2NhcGVfbWlzYyhzZWxmKToKICAgICAgICAjIFNvbWUgYWRkaXRpb25hbCBOZXRzY2FwZSBjb29raWVzIHRlc3RzLgogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIKICAgICAgICBmcm9tIHVybGxpYjIgaW1wb3J0IFJlcXVlc3QKCiAgICAgICAgYyA9IENvb2tpZUphcigpCiAgICAgICAgaGVhZGVycyA9IFtdCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL2Zvby5iYXIuYWNtZS5jb20vZm9vIikKCiAgICAgICAgIyBOZXRzY2FwZSBhbGxvd3MgYSBob3N0IHBhcnQgdGhhdCBjb250YWlucyBkb3RzCiAgICAgICAgaGVhZGVycy5hcHBlbmQoIlNldC1Db29raWU6IEN1c3RvbWVyPVdJTEVfRV9DT1lPVEU7IGRvbWFpbj0uYWNtZS5jb20iKQogICAgICAgIHJlcyA9IEZha2VSZXNwb25zZShoZWFkZXJzLCAiaHR0cDovL3d3dy5hY21lLmNvbS9mb28iKQogICAgICAgIGMuZXh0cmFjdF9jb29raWVzKHJlcywgcmVxKQoKICAgICAgICAjIGFuZCB0aGF0IHRoZSBkb21haW4gaXMgdGhlIHNhbWUgYXMgdGhlIGhvc3Qgd2l0aG91dCBhZGRpbmcgYSBsZWFkaW5nCiAgICAgICAgIyBkb3QgdG8gdGhlIGRvbWFpbi4gIFNob3VsZCBub3QgcXVvdGUgZXZlbiBpZiBzdHJhbmdlIGNoYXJzIGFyZSB1c2VkCiAgICAgICAgIyBpbiB0aGUgY29va2llIHZhbHVlLgogICAgICAgIGhlYWRlcnMuYXBwZW5kKCJTZXQtQ29va2llOiBQQVJUX05VTUJFUj0zLDQ7IGRvbWFpbj1mb28uYmFyLmFjbWUuY29tIikKICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuYWNtZS5jb20vZm9vIikKICAgICAgICBjLmV4dHJhY3RfY29va2llcyhyZXMsIHJlcSkKCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL2Zvby5iYXIuYWNtZS5jb20vZm9vIikKICAgICAgICBjLmFkZF9jb29raWVfaGVhZGVyKHJlcSkKICAgICAgICBzZWxmLmFzc2VydFRydWUoCiAgICAgICAgICAgICJQQVJUX05VTUJFUj0zLDQiIGluIHJlcS5nZXRfaGVhZGVyKCJDb29raWUiKSBhbmQKICAgICAgICAgICAgIkN1c3RvbWVyPVdJTEVfRV9DT1lPVEUiIGluIHJlcS5nZXRfaGVhZGVyKCJDb29raWUiKSkKCiAgICBkZWYgdGVzdF9pbnRyYW5ldF9kb21haW5zXzI5NjUoc2VsZik6CiAgICAgICAgIyBUZXN0IGhhbmRsaW5nIG9mIGxvY2FsIGludHJhbmV0IGhvc3RuYW1lcyB3aXRob3V0IGEgZG90LgogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIsIERlZmF1bHRDb29raWVQb2xpY3kKCiAgICAgICAgYyA9IENvb2tpZUphcihEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkpCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL2V4YW1wbGUvIiwKICAgICAgICAgICAgICAgICAgICAgICJmb28xPWJhcjsgUE9SVDsgRGlzY2FyZDsgVmVyc2lvbj0xOyIpCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL2V4YW1wbGUvIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmb28yPWJhcjsgZG9tYWluPSIubG9jYWwiOyBWZXJzaW9uPTEnKQogICAgICAgIHNlbGYuYXNzZXJ0SW4oImZvbzE9YmFyIiwgY29va2llKQoKICAgICAgICBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vZXhhbXBsZS8iLCAnZm9vMz1iYXI7IFZlcnNpb249MScpCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL2V4YW1wbGUvIikKICAgICAgICBzZWxmLmFzc2VydEluKCJmb28yPWJhciIsIGNvb2tpZSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMykKCiAgICBkZWYgdGVzdF9pbnRyYW5ldF9kb21haW5zX25zKHNlbGYpOgogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIsIERlZmF1bHRDb29raWVQb2xpY3kKCiAgICAgICAgYyA9IENvb2tpZUphcihEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjUgPSBGYWxzZSkpCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly9leGFtcGxlLyIsICJmb28xPWJhciIpCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly9leGFtcGxlLyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbzI9YmFyOyBkb21haW49LmxvY2FsJykKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMikKICAgICAgICBzZWxmLmFzc2VydEluKCJmb28xPWJhciIsIGNvb2tpZSkKCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly9leGFtcGxlLyIpCiAgICAgICAgc2VsZi5hc3NlcnRJbigiZm9vMj1iYXIiLCBjb29raWUpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDIpCgogICAgZGVmIHRlc3RfZW1wdHlfcGF0aChzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5CiAgICAgICAgZnJvbSB1cmxsaWIyIGltcG9ydCBSZXF1ZXN0CgogICAgICAgICMgVGVzdCBmb3IgZW1wdHkgcGF0aAogICAgICAgICMgQnJva2VuIHdlYi1zZXJ2ZXIgT1JJT04vMS4zLjM4IHJldHVybnMgdG8gdGhlIGNsaWVudCByZXNwb25zZSBsaWtlCiAgICAgICAgIwogICAgICAgICMgICAgICAgU2V0LUNvb2tpZTogSlNFU1NJT05JRD1BQkNERVJBTkRPTTEyMzsgUGF0aD0KICAgICAgICAjCiAgICAgICAgIyBpZS4gd2l0aCBQYXRoIHNldCB0byBub3RoaW5nLgogICAgICAgICMgSW4gdGhpcyBjYXNlLCBleHRyYWN0X2Nvb2tpZXMoKSBtdXN0IHNldCBjb29raWUgdG8gLyAocm9vdCkKICAgICAgICBjID0gQ29va2llSmFyKERlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NSA9IFRydWUpKQogICAgICAgIGhlYWRlcnMgPSBbXQoKICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmFudHMuY29tLyIpCiAgICAgICAgaGVhZGVycy5hcHBlbmQoIlNldC1Db29raWU6IEpTRVNTSU9OSUQ9QUJDREVSQU5ET00xMjM7IFBhdGg9IikKICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuYW50cy5jb20vIikKICAgICAgICBjLmV4dHJhY3RfY29va2llcyhyZXMsIHJlcSkKCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hbnRzLmNvbS8iKQogICAgICAgIGMuYWRkX2Nvb2tpZV9oZWFkZXIocmVxKQoKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcS5nZXRfaGVhZGVyKCJDb29raWUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICJKU0VTU0lPTklEPUFCQ0RFUkFORE9NMTIzIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcS5nZXRfaGVhZGVyKCJDb29raWUyIiksICckVmVyc2lvbj0iMSInKQoKICAgICAgICAjIG1pc3NpbmcgcGF0aCBpbiB0aGUgcmVxdWVzdCBVUkkKICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmFudHMuY29tOjgwODAiKQogICAgICAgIGMuYWRkX2Nvb2tpZV9oZWFkZXIocmVxKQoKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcS5nZXRfaGVhZGVyKCJDb29raWUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICJKU0VTU0lPTklEPUFCQ0RFUkFORE9NMTIzIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcS5nZXRfaGVhZGVyKCJDb29raWUyIiksICckVmVyc2lvbj0iMSInKQoKICAgIGRlZiB0ZXN0X3Nlc3Npb25fY29va2llcyhzZWxmKToKICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyCiAgICAgICAgZnJvbSB1cmxsaWIyIGltcG9ydCBSZXF1ZXN0CgogICAgICAgIHllYXJfcGx1c19vbmUgPSB0aW1lLmxvY2FsdGltZSgpWzBdICsgMQoKICAgICAgICAjIENoZWNrIHNlc3Npb24gY29va2llcyBhcmUgZGVsZXRlZCBwcm9wZXJseSBieQogICAgICAgICMgQ29va2llSmFyLmNsZWFyX3Nlc3Npb25fY29va2llcyBtZXRob2QKCiAgICAgICAgcmVxID0gUmVxdWVzdCgnaHR0cDovL3d3dy5wZXJsbWVpc3Rlci5jb20vc2NyaXB0cycpCiAgICAgICAgaGVhZGVycyA9IFtdCiAgICAgICAgaGVhZGVycy5hcHBlbmQoIlNldC1Db29raWU6IHMxPXNlc3Npb247UGF0aD0vc2NyaXB0cyIpCiAgICAgICAgaGVhZGVycy5hcHBlbmQoIlNldC1Db29raWU6IHAxPXBlcm07IERvbWFpbj0ucGVybG1laXN0ZXIuY29tOyIKICAgICAgICAgICAgICAgICAgICAgICAiUGF0aD0vO2V4cGlyZXM9RnJpLCAwMi1GZWItJWQgMjM6MjQ6MjAgR01UIiAlCiAgICAgICAgICAgICAgICAgICAgICAgeWVhcl9wbHVzX29uZSkKICAgICAgICBoZWFkZXJzLmFwcGVuZCgiU2V0LUNvb2tpZTogcDI9cGVybTtQYXRoPS87ZXhwaXJlcz1GcmksICIKICAgICAgICAgICAgICAgICAgICAgICAiMDItRmViLSVkIDIzOjI0OjIwIEdNVCIgJSB5ZWFyX3BsdXNfb25lKQogICAgICAgIGhlYWRlcnMuYXBwZW5kKCJTZXQtQ29va2llOiBzMj1zZXNzaW9uO1BhdGg9L3NjcmlwdHM7IgogICAgICAgICAgICAgICAgICAgICAgICJEb21haW49LnBlcmxtZWlzdGVyLmNvbSIpCiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ1NldC1Db29raWUyOiBzMz1zZXNzaW9uO1ZlcnNpb249MTtEaXNjYXJkO1BhdGg9Ii8iJykKICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgJ2h0dHA6Ly93d3cucGVybG1laXN0ZXIuY29tL3NjcmlwdHMnKQoKICAgICAgICBjID0gQ29va2llSmFyKCkKICAgICAgICBjLmV4dHJhY3RfY29va2llcyhyZXMsIHJlcSkKICAgICAgICAjIEhvdyBtYW55IHNlc3Npb24vcGVybWFuZW50IGNvb2tpZXMgZG8gd2UgaGF2ZT8KICAgICAgICBjb3VudGVyID0geyJzZXNzaW9uX2FmdGVyIjogMCwKICAgICAgICAgICAgICAgICAgICJwZXJtX2FmdGVyIjogMCwKICAgICAgICAgICAgICAgICAgICJzZXNzaW9uX2JlZm9yZSI6IDAsCiAgICAgICAgICAgICAgICAgICAicGVybV9iZWZvcmUiOiAwfQogICAgICAgIGZvciBjb29raWUgaW4gYzoKICAgICAgICAgICAga2V5ID0gIiVzX2JlZm9yZSIgJSBjb29raWUudmFsdWUKICAgICAgICAgICAgY291bnRlcltrZXldID0gY291bnRlcltrZXldICsgMQogICAgICAgIGMuY2xlYXJfc2Vzc2lvbl9jb29raWVzKCkKICAgICAgICAjIEhvdyBtYW55IG5vdz8KICAgICAgICBmb3IgY29va2llIGluIGM6CiAgICAgICAgICAgIGtleSA9ICIlc19hZnRlciIgJSBjb29raWUudmFsdWUKICAgICAgICAgICAgY291bnRlcltrZXldID0gY291bnRlcltrZXldICsgMQoKICAgICAgICBzZWxmLmFzc2VydFRydWUobm90ICgKICAgICAgICAgICAgIyBhIHBlcm1hbmVudCBjb29raWUgZ290IGxvc3QgYWNjaWRlbnRhbGx5CiAgICAgICAgICAgIGNvdW50ZXJbInBlcm1fYWZ0ZXIiXSAhPSBjb3VudGVyWyJwZXJtX2JlZm9yZSJdIG9yCiAgICAgICAgICAgICMgYSBzZXNzaW9uIGNvb2tpZSBoYXNuJ3QgYmVlbiBjbGVhcmVkCiAgICAgICAgICAgIGNvdW50ZXJbInNlc3Npb25fYWZ0ZXIiXSAhPSAwIG9yCiAgICAgICAgICAgICMgd2UgZGlkbid0IGhhdmUgc2Vzc2lvbiBjb29raWVzIGluIHRoZSBmaXJzdCBwbGFjZQogICAgICAgICAgICBjb3VudGVyWyJzZXNzaW9uX2JlZm9yZSJdID09IDApKQoKCmRlZiB0ZXN0X21haW4odmVyYm9zZT1Ob25lKToKICAgIHRlc3Rfc3VwcG9ydC5ydW5fdW5pdHRlc3QoCiAgICAgICAgRGF0ZVRpbWVUZXN0cywKICAgICAgICBIZWFkZXJUZXN0cywKICAgICAgICBDb29raWVUZXN0cywKICAgICAgICBGaWxlQ29va2llSmFyVGVzdHMsCiAgICAgICAgTFdQQ29va2llVGVzdHMsCiAgICAgICAgKQoKaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKICAgIHRlc3RfbWFpbih2ZXJib3NlPVRydWUpCg==