#!/bin/bash
# AIRLAB FPV · instalador del Conector para Mac (versión 1.6). Se ejecuta una vez:  bash ~/Downloads/airlab-instalar.sh
# Deja todo en ~/AIRLAB y pone «AIRLAB Conector» en el Escritorio (doble clic para abrirlo). Repetirlo actualiza.
set -e
DEST="$HOME/AIRLAB"
echo; echo "  AIRLAB Conector 1.6 · instalación"; echo "  ───────────────────────────────"
if ! command -v python3 >/dev/null 2>&1 || ! python3 -c 'import sys; sys.exit(0 if sys.version_info>=(3,8) else 1)' 2>/dev/null; then
  echo "  Falta Python 3. Se abrirá la instalación de las herramientas de Apple: pulsa Instalar y vuelve a ejecutar esto."
  xcode-select --install 2>/dev/null || true; exit 1
fi
mkdir -p "$DEST"
python3 - "$DEST" <<'PY'
import base64, os, sys
d = sys.argv[1]
F = {
    'airlab-conector.py': 'IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwoiIiJBSVJMQUIgRlBWIMK3IENvbmVjdG9yOiB1biBzb2xvIHByb2dyYW1hIHBhcmEgdG9kbyBsbyBxdWUgZWwgbmF2ZWdhZG9yIG5vIHB1ZWRlIGhhY2VyIHBvciBzw60gbWlzbW8uCgoxLiBWdWVsbyByZWFsIGNvbiBpbnN0cnVjdG9yOiByZWNvZ2UgbGEgdGVsZW1ldHLDrWEgTUFWTGluayBxdWUgbWFuZGEgZWwgQmFja3BhY2sgZGUgRUxSUyBwb3IgV2lGaSAoVURQIDE0NTUwKSB5IHNlIGxhCiAgIHBhc2EgYWwgc2ltdWxhZG9yIGVuIGh0dHA6Ly8xMjcuMC4wLjE6MTQ1ODAvc3RyZWFtIChlbCBhbnRpZ3VvIGFpcmxhYi1wdWVudGUucHkpLgoyLiBBcmR1UGlsb3QgcmVhbCAoU0lUTCk6IGhhY2UgZGUgcHVlbnRlIGVudHJlIEFyZHVQbGFuZSBTSVRMIChmw61zaWNhIEpTT04gZW4gVURQIDkwMDIsIE1BVkxpbmsgZW4gVURQIDE0NTUxKSB5IGVsCiAgIHNpbXVsYWRvciAod3M6Ly8xMjcuMC4wLjE6MTQ1OTAvc2l0bCksIHkgYXJyYW5jYSwgcGFyYSBvIHJlaW5pY2lhIEFyZHVQaWxvdCBjdWFuZG8gZWwgc2ltdWxhZG9yIGxvIHBpZGUuCiAgIEFJUkxBQiBDb2NrcGl0IHdlYiAoYWlybGFiZnB2LmVzL2NvY2twaXQpIHVzYSBlbCBtaXNtbyAvc3RyZWFtIHkgbWFuZGEgc3VzIHBldGljaW9uZXMgZGUgbG9nIGEgL3JlYWwvZW52aWFyLgozLiBFc3RhZG86IGh0dHA6Ly8xMjcuMC4wLjE6MTQ1ODAvZXN0YWRvIGRpY2UgYWwgc2ltdWxhZG9yIChPcGNpb25lcyDigLogQ29uZXhpb25lcykgcXXDqSBlc3TDoSBmdW5jaW9uYW5kbyB5IHF1w6kgZmFsdGEuCjQuIExvZ3MgZGVsIGF2acOzbiBwb3IgV2lGaTogYnVzY2EgZWwgV2lGaSBkZWwgYXZpw7NuIChlbCBtw7NkdWxvIGludGVncmFkbyBkZSBsYSBDb3JlV2luZyBGNDA1IFdpbmcgVjIsIFRDUCA0Mjc4IGVuCiAgIDE5Mi4xNjguMS4xLCBvIHVuIEVTUDMyIGNvbiBEcm9uZUJyaWRnZSwgVENQIDU3NjAgZW4gZHJvbmVicmlkZ2UubG9jYWwgbyAxOTIuMTY4LjIuMSksCiAgIGJhamEgc29sb3MgbG9zIGxvZ3MgLmJpbiBudWV2b3MgZGUgQXJkdVBpbG90IChwcm90b2NvbG8gZGUgbG9ncyBkZSBNQVZMaW5rLCBjb24gZWwgYXZpw7NuIGRlc2FybWFkbykgYQogICB+L0RvY3VtZW50cy9BSVJMQUIgTG9ncyB5IGVsIHNpbXVsYWRvciBsb3MgaW1wb3J0YSBlbiBBbsOhbGlzaXMg4oC6IE1hbnRlbmltaWVudG8gZGUgbGEgZmxvdGEgKGh0dHA6Ly8xMjcuMC4wLjE6MTQ1ODAvbG9ncykuCgpTZSBhYnJlIGNvbiBkb2JsZSBjbGljIGVuIMKrQUlSTEFCIENvbmVjdG9ywrsgKGxvIGluc3RhbGEgYWlybGFiLWluc3RhbGFyLnNoKSBvIGNvbjogIHB5dGhvbjMgYWlybGFiLWNvbmVjdG9yLnB5Ck9wY2lvbmVzOiAgLS1yZWVudmlhciAxNDU2MCAgKGNvcGlhIGxhIHRlbGVtZXRyw61hIHJlYWwgYSBRR3JvdW5kQ29udHJvbC9NaXNzaW9uIFBsYW5uZXIgZW4gZXNlIHB1ZXJ0bykKICAgICAgICAgICAtLWFyZHVwaWxvdCBSVVRBICAoY2FycGV0YSBkZSBBcmR1UGlsb3Qgc2kgbm8gZXN0w6EgZW4gfi9hcmR1cGlsb3QpCiAgICAgICAgICAgLS1lc3AgSE9TVFs6UFVFUlRPXSAoV2lGaSBkZWwgYXZpw7NuOyBwb3IgZGVmZWN0byBDb3JlV2luZyAxOTIuMTY4LjEuMTo0Mjc4IHkgRHJvbmVCcmlkZ2UgOjU3NjApClNvbG8gUHl0aG9uIDMsIHNpbiBpbnN0YWxhciBuYWRhIG3DoXMuIENpw6lycmFsbyBjb24gQ3RybCtDIG8gY2VycmFuZG8gbGEgdmVudGFuYS4KIiIiCmltcG9ydCBhcmdwYXJzZSwgYmFzZTY0LCBoYXNobGliLCBqc29uLCBvcywgcXVldWUsIHJlLCBzb2NrZXQsIHN0cnVjdCwgc3VicHJvY2Vzcywgc3lzLCB0aHJlYWRpbmcsIHRpbWUKZnJvbSBodHRwLnNlcnZlciBpbXBvcnQgQmFzZUhUVFBSZXF1ZXN0SGFuZGxlciwgVGhyZWFkaW5nSFRUUFNlcnZlcgpmcm9tIHVybGxpYi5wYXJzZSBpbXBvcnQgdXJscGFyc2UsIHBhcnNlX3FzCgpWRVJTSU9OID0gJzEuNicKSEVSRSA9IG9zLnBhdGguZGlybmFtZShvcy5wYXRoLmFic3BhdGgoX19maWxlX18pKQpHVUlEID0gJzI1OEVBRkE1LUU5MTQtNDdEQS05NUNBLUM1QUIwREM4NUIxMScKbG9jayA9IHRocmVhZGluZy5Mb2NrKCkKd3NfbG9jayA9IHRocmVhZGluZy5Mb2NrKCkgICAgICMgYWwgV2ViU29ja2V0IGRlbCBzaW11bGFkb3IgZXNjcmliZW4gdmFyaW9zIGhpbG9zIChmw61zaWNhLCBNQVZMaW5rLCBwaW5nKTogdW5hIHRyYW1hIGNhZGEgdmV6CiMgdnVlbG8gcmVhbApyZWFsID0geydwYXF1ZXRlcyc6IDAsICdieXRlcyc6IDAsICdkZXNkZSc6IE5vbmUsICdvY3VwYWRvJzogRmFsc2UsICd1bHRpbW8nOiAwLjAsICdjbGllbnRlcyc6IFtdfQojIFNJVEwKc2l0bCA9IHsnYWRkcic6IE5vbmUsICd3cyc6IE5vbmUsICdyeCc6IDAsICd0eCc6IDAsICdyYXRlJzogMCwgJ2xhc3RfZmMnOiAtMSwgJ3VsdGltbyc6IDAuMCwgJ21hdmFkZHInOiBOb25lLCAnbWF2X3NvY2snOiBOb25lLAogICAgICAgICdzZXEnOiAwLCAncHJvYyc6IE5vbmUsICdsb2cnOiBbXSwgJ2luaWNpbyc6IDAuMCwgJ29jdXBhZG8nOiBGYWxzZSwgJ21hdl91bHRpbW8nOiAwLjAsICdhcGFyYXRvJzogTm9uZX0KIyBhcGFyYXRvcyBkZSBTSVRMOiAucGFyYW0gZGUgcHJ1ZWJhIHkgY2FycGV0YSBwcm9waWEgKGNhZGEgdW5vIGd1YXJkYSBzdXMgcGFyw6FtZXRyb3MgZW4gc3UgZWVwcm9tLmJpbikKQVBBUkFUT1MgPSB7J2Z3JzogKCdzdGFsbGlvbi1zaXRsLnBhcm0nLCAnc2l0bC1ydW4nKSwgJ3Z0b2wnOiAoJ3N0YWxsaW9uLXZ0b2wtc2l0bC5wYXJtJywgJ3NpdGwtcnVuLXZ0b2wnKX0KY2ZnID0geydhcmR1cGlsb3QnOiBOb25lLCAncmVlbnZpYXInOiAwfQojIGNhc2EgZGUgQXJkdVBpbG90IChsYXQsIGxvbiwgYWx0aXR1ZCBkZWwgc3VlbG8gZW4gbSwgcnVtYm8pOiBsYSBtYW5kYSBlbCBzaW11bGFkb3IgKHN1IGNhc2EgZGVsIHBsYW5pZmljYWRvcikgYWwgYXJyYW5jYXIKSE9NRV9ERUYgPSAoMzcuMjM4LCAtNS4xLCAyMDAuMCwgMC4wKQpzaXRsWydob21lJ10gPSBIT01FX0RFRgpzaXRsWydob21lX3Byb2MnXSA9IE5vbmUKCgpkZWYgYWhvcmEoKToKICAgIHJldHVybiB0aW1lLnRpbWUoKQoKCmRlZiBsb2codCk6CiAgICBwcmludCh0aW1lLnN0cmZ0aW1lKCclSDolTTolUycpLCB0LCBmbHVzaD1UcnVlKQoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdnVlbG8gcmVhbCAoVURQIDE0NTUwKQpkZWYgcmVhbF91ZHAocHVlcnRvLCByZWVudmlhcik6CiAgICBzID0gc29ja2V0LnNvY2tldChzb2NrZXQuQUZfSU5FVCwgc29ja2V0LlNPQ0tfREdSQU0pCiAgICBzLnNldHNvY2tvcHQoc29ja2V0LlNPTF9TT0NLRVQsIHNvY2tldC5TT19SRVVTRUFERFIsIDEpCiAgICB0cnk6CiAgICAgICAgcy5zZXRzb2Nrb3B0KHNvY2tldC5TT0xfU09DS0VULCBzb2NrZXQuU09fQlJPQURDQVNULCAxKQogICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgcGFzcwogICAgdHJ5OgogICAgICAgIHMuYmluZCgoJzAuMC4wLjAnLCBwdWVydG8pKQogICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgcmVhbFsnb2N1cGFkbyddID0gVHJ1ZQogICAgICAgIGxvZyhmJ1Z1ZWxvIHJlYWw6IGVsIHB1ZXJ0byBVRFAge3B1ZXJ0b30gbG8gdXNhIG90cm8gcHJvZ3JhbWEgKGNhc2kgc2llbXByZSBRR3JvdW5kQ29udHJvbCBvIE1pc3Npb24gUGxhbm5lcikuICcKICAgICAgICAgICAgJ0Npw6lycmFsbyBkZWwgdG9kbyAoQ21kK1EpIHkgdnVlbHZlIGEgYWJyaXIgZWwgY29uZWN0b3IuJykKICAgICAgICByZXR1cm4KICAgIHNhbGlkYSA9IHNvY2tldC5zb2NrZXQoc29ja2V0LkFGX0lORVQsIHNvY2tldC5TT0NLX0RHUkFNKSBpZiByZWVudmlhciBlbHNlIE5vbmUKICAgIHJlYWxbJ3NvY2snXSA9IHMKICAgIHdoaWxlIFRydWU6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBkYXRvcywgb3JpZ2VuID0gcy5yZWN2ZnJvbSg0MDk2KQogICAgICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGlmIHJlYWxbJ2Rlc2RlJ10gaXMgTm9uZToKICAgICAgICAgICAgbG9nKGYnVnVlbG8gcmVhbDogcmVjaWJpZW5kbyB0ZWxlbWV0csOtYSBkZSB7b3JpZ2VuWzBdfTp7b3JpZ2VuWzFdfScpCiAgICAgICAgcmVhbFsnZGVzZGUnXSA9IG9yaWdlbgogICAgICAgIHJlYWxbJ3BhcXVldGVzJ10gKz0gMQogICAgICAgIHJlYWxbJ2J5dGVzJ10gKz0gbGVuKGRhdG9zKQogICAgICAgIHJlYWxbJ3VsdGltbyddID0gYWhvcmEoKQogICAgICAgIGxpbmVhID0gKCdkYXRhOiAnICsgYmFzZTY0LmI2NGVuY29kZShkYXRvcykuZGVjb2RlKCkgKyAnXG5cbicpLmVuY29kZSgpCiAgICAgICAgd2l0aCBsb2NrOgogICAgICAgICAgICBmb3IgcSBpbiBsaXN0KHJlYWxbJ2NsaWVudGVzJ10pOgogICAgICAgICAgICAgICAgaWYgcS5xc2l6ZSgpIDwgNTAwOgogICAgICAgICAgICAgICAgICAgIHEucHV0KGxpbmVhKQogICAgICAgIGlmIHNhbGlkYToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2FsaWRhLnNlbmR0byhkYXRvcywgKCcxMjcuMC4wLjEnLCByZWVudmlhcikpCiAgICAgICAgICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgICAgICAgICAgcGFzcwoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gU0lUTDogZsOtc2ljYSB5IE1BVkxpbmsKZGVmIHgyNShidWYsIGNyYz0weEZGRkYpOgogICAgZm9yIGIgaW4gYnVmOgogICAgICAgIHQgPSBiIF4gKGNyYyAmIDB4RkYpCiAgICAgICAgdCA9ICh0IF4gKHQgPDwgNCkpICYgMHhGRgogICAgICAgIGNyYyA9ICgoY3JjID4+IDgpIF4gKHQgPDwgOCkgXiAodCA8PCAzKSBeICh0ID4+IDQpKSAmIDB4RkZGRgogICAgcmV0dXJuIGNyYwoKCmRlZiBtYXZfZW52aWFyKG1zZ2lkLCBjcmNfZXh0cmEsIHBheWxvYWQpOgogICAgIiIiTWFuZGEgdW4gbWVuc2FqZSBNQVZMaW5rIDEgYSBBcmR1UGlsb3QgU0lUTCAoc2lzdGVtYSAyNTUsIGNvbXBvbmVudGUgMTkwLCBjb21vIHVuYSBlc3RhY2nDs24gZGUgdGllcnJhKS4iIiIKICAgIHNpdGxbJ3NlcSddID0gKHNpdGxbJ3NlcSddICsgMSkgJiAweEZGCiAgICBoZWFkID0gc3RydWN0LnBhY2soJzxCQkJCQicsIGxlbihwYXlsb2FkKSwgc2l0bFsnc2VxJ10sIDI1NSwgMTkwLCBtc2dpZCkKICAgIGNyYyA9IHgyNShoZWFkICsgcGF5bG9hZCArIGJ5dGVzKFtjcmNfZXh0cmFdKSkKICAgIHNpdGxbJ21hdl9zb2NrJ10uc2VuZHRvKGInXHhmZScgKyBoZWFkICsgcGF5bG9hZCArIHN0cnVjdC5wYWNrKCc8SCcsIGNyYyksIHNpdGxbJ21hdmFkZHInXSkKCgpkZWYgc2l0bF9jbWRfbG9uZyhjbWQsIHAxPTAuMCwgcDI9MC4wKToKICAgICIiIkNPTU1BTkRfTE9ORyAoNzYpIGFsIGF1dG9waWxvdG8gKHNpc3RlbWEgMSwgY29tcG9uZW50ZSAxKS4gUGFyYSBhcm1hci9kZXNhcm1hciAoNDAwKSB5IGNhbWJpYXIgZGUgbW9kbyAoMTc2KSBjdWFuZG8KICAgIGVsIC5wYXJhbSBubyB0aWVuZSBpbnRlcnJ1cHRvciBkZSBhcm1hZG8gbmkgY2FuYWwgZGUgbW9kb3MgcXVlIGVsIHNpbXVsYWRvciBwdWVkYSBtb3ZlciAoU0lNX0pTT04gc29sbyBsZWUgcmNfMeKApnJjXzEyKS4iIiIKICAgIGlmIG5vdCAoc2l0bFsnbWF2YWRkciddIGFuZCBzaXRsWydtYXZfc29jayddIGFuZCBhaG9yYSgpIC0gc2l0bFsnbWF2X3VsdGltbyddIDwgNSk6CiAgICAgICAgcmV0dXJuIEZhbHNlCiAgICBtYXZfZW52aWFyKDc2LCAxNTIsIHN0cnVjdC5wYWNrKCc8N2ZIQkJCJywgcDEsIHAyLCAwLCAwLCAwLCAwLCAwLCBjbWQsIDEsIDEsIDApKQogICAgcmV0dXJuIFRydWUKCgpkZWYgc2l0bF9yZWJvb3QoKToKICAgICIiIk1BVl9DTURfUFJFRkxJR0hUX1JFQk9PVF9TSFVURE9XTiBwb3IgTUFWTGluayAoZm9yemFkbyBhdW5xdWUgZXN0w6kgYXJtYWRvIHRyYXMgdW4gY2hvcXVlKS4KICAgIFNpIEFyZHVQaWxvdCBubyByZXNwb25kZSBwb3IgTUFWTGluayBwZXJvIGxvIGFycmFuY8OzIGVsIGNvbmVjdG9yLCBzZSByZWluaWNpYSBlbCBwcm9jZXNvLiIiIgogICAgaWYgc2l0bFsnbWF2YWRkciddIGFuZCBzaXRsWydtYXZfc29jayddIGFuZCBhaG9yYSgpIC0gc2l0bFsnbWF2X3VsdGltbyddIDwgNToKICAgICAgICBwYXlsb2FkID0gc3RydWN0LnBhY2soJzw0ZmlpZkhCQkJCQicsIDEsIDAsIDAsIDAsIDAsIDIwMTkwMjI2LCAwLCAyNDYsIDEsIDEsIDAsIDAsIDApCiAgICAgICAgc2l0bFsnc2VxJ10gPSAoc2l0bFsnc2VxJ10gKyAxKSAmIDB4RkYKICAgICAgICBoZWFkID0gc3RydWN0LnBhY2soJzxCQkJCQicsIGxlbihwYXlsb2FkKSwgc2l0bFsnc2VxJ10sIDI1NSwgMTkwLCA3NSkKICAgICAgICBjcmMgPSB4MjUoaGVhZCArIHBheWxvYWQgKyBieXRlcyhbMTU4XSkpCiAgICAgICAgc2l0bFsnbWF2X3NvY2snXS5zZW5kdG8oYidceGZlJyArIGhlYWQgKyBwYXlsb2FkICsgc3RydWN0LnBhY2soJzxIJywgY3JjKSwgc2l0bFsnbWF2YWRkciddKQogICAgICAgIGxvZygnQXJkdVBpbG90OiByZWluaWNpbyBwZWRpZG8gKGVsIGF2acOzbiB2dWVsdmUgYSBsYSBwaXN0YSknKQogICAgICAgIHJldHVybiBUcnVlCiAgICBpZiBzaXRsWydwcm9jJ10gYW5kIHNpdGxbJ3Byb2MnXS5wb2xsKCkgaXMgTm9uZToKICAgICAgICBsb2coJ0FyZHVQaWxvdCBubyByZXNwb25kZSBwb3IgTUFWTGluazogbG8gcmVpbmljaW8nKQogICAgICAgIGFwID0gc2l0bFsnYXBhcmF0byddIG9yICdmdycgICAgICAjIGVsIG1pc21vIGFwYXJhdG8gKHNpdGxfcGFyYXIgbG8gYm9ycmEpCiAgICAgICAgc2l0bF9wYXJhcigpCiAgICAgICAgcmV0dXJuIHNpdGxfYXJyYW5jYXIoRmFsc2UsIGFwKQogICAgbG9nKCdObyBwdWVkbyByZWluaWNpYXIgQXJkdVBpbG90OiBubyBlc3TDoSBlbiBtYXJjaGEnKQogICAgcmV0dXJuIEZhbHNlCgoKZGVmIHdzX3NlbmQoY29ubiwgZGF0YSwgb3Bjb2RlKToKICAgIG4gPSBsZW4oZGF0YSkKICAgIGlmIG4gPCAxMjY6CiAgICAgICAgaGVhZCA9IHN0cnVjdC5wYWNrKCchQkInLCAweDgwIHwgb3Bjb2RlLCBuKQogICAgZWxpZiBuIDwgNjU1MzY6CiAgICAgICAgaGVhZCA9IHN0cnVjdC5wYWNrKCchQkJIJywgMHg4MCB8IG9wY29kZSwgMTI2LCBuKQogICAgZWxzZToKICAgICAgICBoZWFkID0gc3RydWN0LnBhY2soJyFCQlEnLCAweDgwIHwgb3Bjb2RlLCAxMjcsIG4pCiAgICB3aXRoIHdzX2xvY2s6CiAgICAgICAgY29ubi5zZW5kYWxsKGhlYWQgKyBkYXRhKQoKCmRlZiByZWN2X2V4YWN0KGNvbm4sIG4pOgogICAgYiA9IGInJwogICAgd2hpbGUgbGVuKGIpIDwgbjoKICAgICAgICBjID0gY29ubi5yZWN2KG4gLSBsZW4oYikpCiAgICAgICAgaWYgbm90IGM6CiAgICAgICAgICAgIHJhaXNlIENvbm5lY3Rpb25FcnJvcignY2VycmFkbycpCiAgICAgICAgYiArPSBjCiAgICByZXR1cm4gYgoKCmRlZiB3c19jbGllbnRlKGNvbm4sIHVkcCk6CiAgICAiIiJQZXN0YcOxYSBkZWwgc2ltdWxhZG9yIGVuIG1vZG8gU0lUTDogbG8gcXVlIG1hbmRhIGVzIGxhIHJlc3B1ZXN0YSBKU09OIHBhcmEgQXJkdVBpbG90IChvIMKrI3JlYm9vdMK7KS4iIiIKICAgIHRyeToKICAgICAgICByZXEgPSBiJycKICAgICAgICB3aGlsZSBiJ1xyXG5cclxuJyBub3QgaW4gcmVxOgogICAgICAgICAgICBjID0gY29ubi5yZWN2KDQwOTYpCiAgICAgICAgICAgIGlmIG5vdCBjOgogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIHJlcSArPSBjCiAgICAgICAgbGluZXMgPSByZXEuZGVjb2RlKCdsYXRpbi0xJykuc3BsaXQoJ1xyXG4nKQogICAgICAgIGhkciA9IHtsLnNwbGl0KCc6JywgMSlbMF0uc3RyaXAoKS5sb3dlcigpOiBsLnNwbGl0KCc6JywgMSlbMV0uc3RyaXAoKSBmb3IgbCBpbiBsaW5lc1sxOl0gaWYgJzonIGluIGx9CiAgICAgICAgaWYgJ3NlYy13ZWJzb2NrZXQta2V5JyBub3QgaW4gaGRyOgogICAgICAgICAgICBib2R5ID0gYidBSVJMQUIgQ29uZWN0b3I6IFdlYlNvY2tldCBkZSBTSVRMXG4nCiAgICAgICAgICAgIGNvbm4uc2VuZGFsbChiJ0hUVFAvMS4xIDIwMCBPS1xyXG5Db250ZW50LVR5cGU6IHRleHQvcGxhaW5cclxuQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luOiAqXHJcbkNvbnRlbnQtTGVuZ3RoOiAnCiAgICAgICAgICAgICAgICAgICAgICAgICArIHN0cihsZW4oYm9keSkpLmVuY29kZSgpICsgYidcclxuXHJcbicgKyBib2R5KQogICAgICAgICAgICByZXR1cm4KICAgICAgICBhY2MgPSBiYXNlNjQuYjY0ZW5jb2RlKGhhc2hsaWIuc2hhMSgoaGRyWydzZWMtd2Vic29ja2V0LWtleSddICsgR1VJRCkuZW5jb2RlKCkpLmRpZ2VzdCgpKS5kZWNvZGUoKQogICAgICAgIGNvbm4uc2VuZGFsbCgoJ0hUVFAvMS4xIDEwMSBTd2l0Y2hpbmcgUHJvdG9jb2xzXHJcblVwZ3JhZGU6IHdlYnNvY2tldFxyXG5Db25uZWN0aW9uOiBVcGdyYWRlXHJcbicKICAgICAgICAgICAgICAgICAgICAgIGYnU2VjLVdlYlNvY2tldC1BY2NlcHQ6IHthY2N9XHJcblxyXG4nKS5lbmNvZGUoKSkKICAgICAgICBjb25uLnNldHNvY2tvcHQoc29ja2V0LklQUFJPVE9fVENQLCBzb2NrZXQuVENQX05PREVMQVksIDEpCiAgICAgICAgd2l0aCBsb2NrOgogICAgICAgICAgICBvbGQsIHNpdGxbJ3dzJ10gPSBzaXRsWyd3cyddLCBjb25uCiAgICAgICAgaWYgb2xkOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBvbGQuY2xvc2UoKQogICAgICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICBsb2coJ1NJVEw6IHNpbXVsYWRvciBlbmxhemFkbycpCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgYjAsIGIxID0gcmVjdl9leGFjdChjb25uLCAyKQogICAgICAgICAgICBvcCwgbWFza2VkLCBuID0gYjAgJiAweDBGLCBiMSAmIDB4ODAsIGIxICYgMHg3RgogICAgICAgICAgICBpZiBuID09IDEyNjoKICAgICAgICAgICAgICAgIG4gPSBzdHJ1Y3QudW5wYWNrKCchSCcsIHJlY3ZfZXhhY3QoY29ubiwgMikpWzBdCiAgICAgICAgICAgIGVsaWYgbiA9PSAxMjc6CiAgICAgICAgICAgICAgICBuID0gc3RydWN0LnVucGFjaygnIVEnLCByZWN2X2V4YWN0KGNvbm4sIDgpKVswXQogICAgICAgICAgICBtYXNrID0gcmVjdl9leGFjdChjb25uLCA0KSBpZiBtYXNrZWQgZWxzZSBiJ1wwXDBcMFwwJwogICAgICAgICAgICBkYXRhID0gYnl0ZWFycmF5KHJlY3ZfZXhhY3QoY29ubiwgbikpCiAgICAgICAgICAgIGZvciBpIGluIHJhbmdlKG4pOgogICAgICAgICAgICAgICAgZGF0YVtpXSBePSBtYXNrW2kgJiAzXQogICAgICAgICAgICBpZiBvcCA9PSA4OgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgaWYgb3AgPT0gOToKICAgICAgICAgICAgICAgIHdzX3NlbmQoY29ubiwgYnl0ZXMoZGF0YSksIDB4QSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIGlmIG9wID09IDEgYW5kIGRhdGFbOjFdID09IGInIyc6CiAgICAgICAgICAgICAgICBpZiBkYXRhWzo3XSA9PSBiJyNyZWJvb3QnOgogICAgICAgICAgICAgICAgICAgIHNpdGxfcmVib290KCkKICAgICAgICAgICAgICAgIGVsaWYgZGF0YVs6NF0gPT0gYicjYXJtJzogICAgICAgICAgIyDCqyNhcm3CuyAvIMKrI2FybSAwwrs6IE1BVl9DTURfQ09NUE9ORU5UX0FSTV9ESVNBUk0KICAgICAgICAgICAgICAgICAgICBzaXRsX2NtZF9sb25nKDQwMCwgMC4wIGlmIGRhdGFbNDpdLnN0cmlwKCkgPT0gYicwJyBlbHNlIDEuMCkKICAgICAgICAgICAgICAgIGVsaWYgZGF0YVs6NV0gPT0gYicjbW9kZSc6ICAgICAgICAgIyDCqyNtb2RlIE7CuzogTUFWX0NNRF9ET19TRVRfTU9ERSBjb24gZWwgbsO6bWVybyBkZSBtb2RvIGRlIEFyZHVQbGFuZQogICAgICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICAgICAgc2l0bF9jbWRfbG9uZygxNzYsIDEuMCwgZmxvYXQoaW50KGRhdGFbNTpdLnN0cmlwKCkpKSkKICAgICAgICAgICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgICAgICAgICAgcGFzcwogICAgICAgICAgICAgICAgY29udGludWUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbnVuY2EgbWFuZGFyIGEgQXJkdVBpbG90IGFsZ28gcXVlIG5vIHNlYSBzdSBKU09OCiAgICAgICAgICAgIGlmIG9wIGluICgxLCAyKSBhbmQgc2l0bFsnYWRkciddIGFuZCBkYXRhWzoxXSA9PSBiJ3snOgogICAgICAgICAgICAgICAgdWRwLnNlbmR0byhiJ1xuJyArIGJ5dGVzKGRhdGEpICsgYidcbicsIHNpdGxbJ2FkZHInXSkKICAgICAgICAgICAgICAgIHNpdGxbJ3R4J10gKz0gMQogICAgZXhjZXB0IChDb25uZWN0aW9uRXJyb3IsIE9TRXJyb3IpOgogICAgICAgIHBhc3MKICAgIGZpbmFsbHk6CiAgICAgICAgd2l0aCBsb2NrOgogICAgICAgICAgICBpZiBzaXRsWyd3cyddIGlzIGNvbm46CiAgICAgICAgICAgICAgICBzaXRsWyd3cyddID0gTm9uZQogICAgICAgIHRyeToKICAgICAgICAgICAgY29ubi5jbG9zZSgpCiAgICAgICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgICAgIHBhc3MKICAgICAgICBsb2coJ1NJVEw6IHNpbXVsYWRvciBkZXNlbmxhemFkbycpCgoKZGVmIHNpdGxfdWRwKHVkcCk6CiAgICAiIiJQYXF1ZXRlcyBkZSBTSVRMIChtYWdpYywgZnJlY3VlbmNpYSwgY29udGFkb3IsIFBXTSk6IHNlIHBhc2FuIHRhbCBjdWFsIGFsIHNpbXVsYWRvci4iIiIKICAgIHdoaWxlIFRydWU6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBkYXRhLCBhZGRyID0gdWRwLnJlY3Zmcm9tKDIwNDgpCiAgICAgICAgICAgIGlmIGxlbihkYXRhKSA8IDg6CiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBtYWdpYywgcmF0ZSwgZmMgPSBzdHJ1Y3QudW5wYWNrKCc8SEhJJywgZGF0YVs6OF0pCiAgICAgICAgICAgIGlmIG1hZ2ljIG5vdCBpbiAoMTg0NTgsIDI5NTY5KToKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIGlmIHNpdGxbJ2FkZHInXSAhPSBhZGRyOgogICAgICAgICAgICAgICAgbG9nKGYnU0lUTDogQXJkdVBpbG90IGNvbmVjdGFkbyAoe3JhdGV9IEh6KScpCiAgICAgICAgICAgIHNpdGxbJ2FkZHInXSwgc2l0bFsncmF0ZSddLCBzaXRsWyd1bHRpbW8nXSA9IGFkZHIsIHJhdGUsIGFob3JhKCkKICAgICAgICAgICAgaWYgZmMgPCBzaXRsWydsYXN0X2ZjJ106CiAgICAgICAgICAgICAgICBsb2coJ1NJVEw6IEFyZHVQaWxvdCBzZSBoYSByZWluaWNpYWRvOyBlbCBhdmnDs24gdnVlbHZlIGEgbGEgcGlzdGEnKQogICAgICAgICAgICBzaXRsWydsYXN0X2ZjJ10gPSBmYwogICAgICAgICAgICBzaXRsWydyeCddICs9IDEKICAgICAgICAgICAgd2l0aCBsb2NrOgogICAgICAgICAgICAgICAgd3MgPSBzaXRsWyd3cyddCiAgICAgICAgICAgIGlmIHdzOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHdzX3NlbmQod3MsIGRhdGEsIDIpCiAgICAgICAgICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICBsb2coZidTSVRMOiBwYXF1ZXRlIGRlc2NhcnRhZG8gKHtlfSknKQoKCmRlZiBzaXRsX21hdihtYXYpOgogICAgIiIiTUFWTGluayBkZSBTSVRMIChsYXRpZG8geSBhdmlzb3MpIHBhcmEgZWwgT1NEIGRlbCBzaW11bGFkb3IuIiIiCiAgICB3aGlsZSBUcnVlOgogICAgICAgIHRyeToKICAgICAgICAgICAgZGF0YSwgYWRkciA9IG1hdi5yZWN2ZnJvbSg0MDk2KQogICAgICAgICAgICBzaXRsWydtYXZhZGRyJ10sIHNpdGxbJ21hdl91bHRpbW8nXSA9IGFkZHIsIGFob3JhKCkKICAgICAgICAgICAgd2l0aCBsb2NrOgogICAgICAgICAgICAgICAgd3MgPSBzaXRsWyd3cyddCiAgICAgICAgICAgIGlmIHdzIGFuZCBkYXRhIGFuZCBkYXRhWzBdIGluICgweEZELCAweEZFKToKICAgICAgICAgICAgICAgIHdzX3NlbmQod3MsIGRhdGEsIDIpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICAgICAgcGFzcwoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gYXJyYW5jYXIgQXJkdVBpbG90CmRlZiBhcmR1cGlsb3RfYmluKCk6CiAgICBjYW5kcyA9IFtjZmdbJ2FyZHVwaWxvdCddLCBvcy5lbnZpcm9uLmdldCgnQVJEVVBJTE9UJyksIG9zLnBhdGguZXhwYW5kdXNlcignfi9hcmR1cGlsb3QnKV0KICAgIGZvciBjIGluIGNhbmRzOgogICAgICAgIGlmIGM6CiAgICAgICAgICAgIGIgPSBvcy5wYXRoLmpvaW4ob3MucGF0aC5leHBhbmR1c2VyKGMpLCAnYnVpbGQnLCAnc2l0bCcsICdiaW4nLCAnYXJkdXBsYW5lJykKICAgICAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUoYikgYW5kIG9zLmFjY2VzcyhiLCBvcy5YX09LKToKICAgICAgICAgICAgICAgIHJldHVybiBiCiAgICByZXR1cm4gTm9uZQoKCmRlZiBzaXRsX2xlY3Rvcihwcm9jKToKICAgIGZvciByYXcgaW4gaXRlcihwcm9jLnN0ZG91dC5yZWFkbGluZSwgYicnKToKICAgICAgICB0ID0gcmF3LmRlY29kZSgndXRmLTgnLCAncmVwbGFjZScpLnJzdHJpcCgpCiAgICAgICAgaWYgbm90IHQgb3IgdC5zdGFydHN3aXRoKCdObyBKU09OIHNlbnNvciBtZXNzYWdlJyk6CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgc2l0bFsnbG9nJ10uYXBwZW5kKHQpCiAgICAgICAgZGVsIHNpdGxbJ2xvZyddWzotNDBdCiAgICBsb2coZidBcmR1UGlsb3Qgc2UgaGEgY2VycmFkbyAoY8OzZGlnbyB7cHJvYy5wb2xsKCl9KScpCgoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdHUgLnBhcmFtIGVuIFNJVEwKIyBEZWwgLnBhcmFtIGRlIHR1IGF2acOzbiBzZSBxdWl0YW4gbG9zIHBhcsOhbWV0cm9zIGRlIGxhIHBsYWNhIChjYWxpYnJhY2lvbmVzLCBwdWVydG9zLCBvcmllbnRhY2nDs24sIHNlbnNvcmVzKTogZW4gU0lUTCBubyBoYXkKIyBwbGFjYSB5IGVzdG9yYmFuLiBFbmNpbWEgdmEgc2l0bC1hanVzdGVzLnBhcm0gY29uIGxvIHF1ZSBTSVRMIG5lY2VzaXRhLiBPcmRlbiBkZSBjYXJnYTogcHJ1ZWJhIOKGkiB0dXlvIOKGkiBhanVzdGVzLgpRVUlUQVIgPSByZS5jb21waWxlKHInXihJTlNfLiooT0ZGU3xTQ0FMfF9JRHxUQ0FMfFBPUykuKnxDT01QQVNTXy4qfEJBUk8uKnxHTkRfLip8U0VSSUFMXGQuKnxCUkRfLip8Q0FOXy4qfEdQU18uKnxHUFNcZF8uKnxBSFJTX09SSUVOVC4qJwogICAgICAgICAgICAgICAgICAgIHInfEFSU1BEXyhUWVBFfEJVU3xQSU58T0ZGU0VUfEFVVE9DQUx8U0tJUF9DQUx8REVWSUR8UFJJTUFSWXxPUFRJT05TKS4qfEFSU1BEXGRfLip8QkFUVFxkP18oVk9MVF9QSU58Q1VSUl9QSU58Vk9MVF9NVUxUfEFNUF9QRVJWTFR8QU1QX09GRlNFVHxNT05JVE9SfFNFUklBTF9OVU0pLionCiAgICAgICAgICAgICAgICAgICAgcid8UkNcZCtfKE1JTnxNQVh8VFJJTXxSRVZFUlNFRHxEWil8U1RBVF8uKnxGT1JNQVRfVkVSU0lPTnxTWVNJRF8uKnxTSU1fLip8U0NIRURfLip8TE9HX0JBQ0tFTkQuKnxSQ01BUF8uKikkJykKQUpVU1RFUyA9ICIiIiMgQUlSTEFCIMK3IGFqdXN0ZXMgcGFyYSB2b2xhciB0dSAucGFyYW0gZW4gU0lUTCAodmFuIGVuY2ltYSBkZSB0dSAucGFyYW0pCkFIUlNfT1JJRU5UQVRJT04gMApTQ0hFRF9MT09QX1JBVEUgMjAwClNJTV9SQVRFX0haIDQwMApRX01fUFdNX1RZUEUgMApRX01fUFdNX01JTiAxMDAwClFfTV9QV01fTUFYIDIwMDAKQVJTUERfVFlQRSAxMDAKRlNfR0NTX0VOQUJMIDAKQkFUVF9NT05JVE9SIDQKIiIiCgoKZGVmIG1pb19ydXRhKGFwYXJhdG8pOgogICAgcmV0dXJuIG9zLnBhdGguam9pbihIRVJFLCBmJ21pLXBhcmFtLXthcGFyYXRvfS5wYXJtJykKCgpkZWYgbWlvX2d1YXJkYXIodGV4dG8sIGFwYXJhdG8pOgogICAgYnVlbmFzLCBxdWl0YWRhcyA9IFtdLCAwCiAgICBmb3IgbCBpbiB0ZXh0by5zcGxpdGxpbmVzKCk6CiAgICAgICAgdCA9IGwuc3RyaXAoKS5yZXBsYWNlKCcsJywgJyAnKS5zcGxpdCgpCiAgICAgICAgaWYgbGVuKHQpID49IDQgYW5kIHRbMF0uaXNkaWdpdCgpIGFuZCB0WzFdLmlzZGlnaXQoKToKICAgICAgICAgICAgdCA9IHRbMjpdICAgICAgICMgZm9ybWF0byBkZSBRR3JvdW5kQ29udHJvbDogc2lzdGVtYSwgY29tcG9uZW50ZSwgTk9NQlJFLCB2YWxvciwgdGlwbwogICAgICAgIGlmIGxlbih0KSA8IDIgb3Igbm90IHJlLm1hdGNoKHInXltBLVpdW0EtWjAtOV9dKiQnLCB0WzBdKToKICAgICAgICAgICAgY29udGludWUKICAgICAgICB0cnk6CiAgICAgICAgICAgIGZsb2F0KHRbMV0pCiAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgaWYgUVVJVEFSLm1hdGNoKHRbMF0pOgogICAgICAgICAgICBxdWl0YWRhcyArPSAxCiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgYnVlbmFzLmFwcGVuZChmJ3t0WzBdfSB7dFsxXX0nKQogICAgaWYgbm90IGJ1ZW5hczoKICAgICAgICByZXR1cm4gMCwgMAogICAgIyBsbyBxdWUgdHUgLnBhcmFtIG5vIGRpZ2EgbG8gcG9uZSBlbCBkZSBwcnVlYmE6IHF1ZSBubyBzZSBxdWVkZSB1biBpbnRlcnJ1cHRvciBzdXlvIChwLiBlai4gYXJtYWRvIGVuIGVsIDcpIGR1cGxpY2FuZG8gZWwgdHV5bwogICAgdGllbmUgPSB7Yi5zcGxpdCgpWzBdIGZvciBiIGluIGJ1ZW5hc30KICAgIGJ1ZW5hcyArPSBbZidSQ3tufV9PUFRJT04gMCcgZm9yIG4gaW4gcmFuZ2UoNSwgMTcpIGlmIGYnUkN7bn1fT1BUSU9OJyBub3QgaW4gdGllbmVdCiAgICBvcGVuKG1pb19ydXRhKGFwYXJhdG8pLCAndycpLndyaXRlKCcjIFR1IC5wYXJhbSAoc2luIGxvcyBwYXLDoW1ldHJvcyBkZSBsYSBwbGFjYSksIGNhcmdhZG8gZGVzZGUgZWwgc2ltdWxhZG9yXG4nICsgJ1xuJy5qb2luKGJ1ZW5hcykgKyAnXG4nKQogICAgb3Blbihvcy5wYXRoLmpvaW4oSEVSRSwgJ3NpdGwtYWp1c3Rlcy5wYXJtJyksICd3Jykud3JpdGUoQUpVU1RFUykKICAgIGxvZyhmJ1R1IC5wYXJhbSBwYXJhIFNJVEw6IHtsZW4oYnVlbmFzKX0gcGFyw6FtZXRyb3MgKHF1aXRhZG9zIHtxdWl0YWRhc30gZGUgbGEgcGxhY2EpJykKICAgIHJldHVybiBsZW4oYnVlbmFzKSwgcXVpdGFkYXMKCgpkZWYgbGVlcl9ob21lKHEpOgogICAgIiIiQ2FzYSBxdWUgbWFuZGEgZWwgc2ltdWxhZG9yIGVuIGxhIGNvbnN1bHRhIChsYXQsIGxvbiwgYWx0ID0gYWx0aXR1ZCBkZWwgc3VlbG8gZW4gbGEgY2FzYSk7IHNpIGZhbHRhIG8gbm8gdmFsZSwgbGEgw7psdGltYS4iIiIKICAgIHRyeToKICAgICAgICBsYSwgbG8gPSBmbG9hdChxWydsYXQnXVswXSksIGZsb2F0KHFbJ2xvbiddWzBdKQogICAgICAgIGFsID0gZmxvYXQocS5nZXQoJ2FsdCcsIFtIT01FX0RFRlsyXV0pWzBdKQogICAgICAgIGlmIC05MCA8PSBsYSA8PSA5MCBhbmQgLTE4MCA8PSBsbyA8PSAxODAgYW5kIChsYSBvciBsbykgYW5kIC01MDAgPD0gYWwgPD0gOTAwMDoKICAgICAgICAgICAgcmV0dXJuIChsYSwgbG8sIGFsLCAwLjApCiAgICBleGNlcHQgKEtleUVycm9yLCBJbmRleEVycm9yLCBWYWx1ZUVycm9yKToKICAgICAgICBwYXNzCiAgICByZXR1cm4gc2l0bFsnaG9tZSddCgoKZGVmIHNpdGxfYXJyYW5jYXIobGltcGlvLCBhcGFyYXRvPSdmdycsIGhvbWU9Tm9uZSk6CiAgICBpZiBhcGFyYXRvIG5vdCBpbiBBUEFSQVRPUzoKICAgICAgICBhcGFyYXRvID0gJ2Z3JwogICAgaWYgaG9tZToKICAgICAgICBzaXRsWydob21lJ10gPSBob21lCiAgICBpZiBsaW1waW8gYW5kIG9zLnBhdGguZXhpc3RzKG1pb19ydXRhKGFwYXJhdG8pKToKICAgICAgICBvcy5yZW1vdmUobWlvX3J1dGEoYXBhcmF0bykpICAgICAgIyDCq2RlIGNlcm/CuzogdnVlbHZlIGFsIC5wYXJhbSBkZSBwcnVlYmEKICAgICAgICBsb2coJ1R1IC5wYXJhbSBxdWl0YWRvOiB2dWVsdmUgZWwgZGUgcHJ1ZWJhJykKICAgIGlmIHNpdGxbJ3Byb2MnXSBhbmQgc2l0bFsncHJvYyddLnBvbGwoKSBpcyBOb25lOgogICAgICAgIGlmIHNpdGxbJ2FwYXJhdG8nXSA9PSBhcGFyYXRvIGFuZCBub3QgbGltcGlvIGFuZCBzaXRsWydob21lX3Byb2MnXSA9PSBzaXRsWydob21lJ106CiAgICAgICAgICAgIHJldHVybiBUcnVlCiAgICAgICAgc2l0bF9wYXJhcigpICAgICAgIyBvdHJvIGFwYXJhdG8sIG90cmEgY2FzYSAobyDCq2RlIGNlcm/Cuyk6IHNlIHBhcmEgeSBzZSBhcnJhbmNhIGNvbiBzdSAucGFyYW0KICAgIGVsaWYgc2l0bFsnYWRkciddIGFuZCBhaG9yYSgpIC0gc2l0bFsndWx0aW1vJ10gPCAzOgogICAgICAgIGxvZygnQXJkdVBpbG90IHlhIGVzdMOhIGVuIG1hcmNoYSAobGFuemFkbyBhcGFydGUpJykKICAgICAgICByZXR1cm4gVHJ1ZQogICAgYiA9IGFyZHVwaWxvdF9iaW4oKQogICAgaWYgbm90IGI6CiAgICAgICAgbG9nKCdObyBlbmN1ZW50cm8gQXJkdVBpbG90IGNvbXBpbGFkbyAo4oCmL2FyZHVwaWxvdC9idWlsZC9zaXRsL2Jpbi9hcmR1cGxhbmUpLiBNaXJhIE9wY2lvbmVzIOKAuiBDb25leGlvbmVzLicpCiAgICAgICAgcmV0dXJuIEZhbHNlCiAgICBwYXJtLCBjYXJwZXRhID0gQVBBUkFUT1NbYXBhcmF0b10KICAgIHJ1biA9IG9zLnBhdGguam9pbihIRVJFLCBjYXJwZXRhKQogICAgb3MubWFrZWRpcnMocnVuLCBleGlzdF9vaz1UcnVlKQogICAgcGFycyA9IFtvcy5wYXRoLmpvaW4oSEVSRSwgcGFybSldCiAgICBpZiBvcy5wYXRoLmV4aXN0cyhtaW9fcnV0YShhcGFyYXRvKSk6CiAgICAgICAgcGFycyArPSBbbWlvX3J1dGEoYXBhcmF0byksIG9zLnBhdGguam9pbihIRVJFLCAnc2l0bC1hanVzdGVzLnBhcm0nKV0KICAgIGFyZ3MgPSBbYiwgJy0tbW9kZWwnLCAnSlNPTjoxMjcuMC4wLjEnLCAnLS1zcGVlZHVwJywgJzEnLCAnLS1kZWZhdWx0cycsICcsJy5qb2luKHBhcnMpLAogICAgICAgICAgICAnLS1ob21lJywgJywnLmpvaW4oZid7djouN2Z9Jy5yc3RyaXAoJzAnKS5yc3RyaXAoJy4nKSBmb3IgdiBpbiBzaXRsWydob21lJ10pLCAnLUkwJywgJy0tc2VyaWFsMCcsICd0Y3A6NTc2MDpub3dhaXQnLCAnLS1zZXJpYWwxJywgJ3VkcGNsaWVudDoxMjcuMC4wLjE6MTQ1NTEnXQogICAgaWYgbGltcGlvOgogICAgICAgIGFyZ3MuYXBwZW5kKCctdycpICAgICAjIMKrLXfCuyAobm8gwqstLXdpcGXCuyk6IGFzw60gdW4gcmVpbmljaW8gcGVkaWRvIGRlc2RlIGVsIHNpbXVsYWRvciBubyBib3JyYSBsb3MgcGFyw6FtZXRyb3MKICAgIHNpdGxbJ2xhc3RfZmMnXSA9IC0xCiAgICBzaXRsWydsb2cnXSA9IFtdCiAgICBzaXRsWydwcm9jJ10gPSBzdWJwcm9jZXNzLlBvcGVuKGFyZ3MsIGN3ZD1ydW4sIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLlNURE9VVCkKICAgIHNpdGxbJ2luaWNpbyddID0gYWhvcmEoKQogICAgc2l0bFsnYXBhcmF0byddID0gYXBhcmF0bwogICAgc2l0bFsnaG9tZV9wcm9jJ10gPSBzaXRsWydob21lJ10KICAgIHRocmVhZGluZy5UaHJlYWQodGFyZ2V0PXNpdGxfbGVjdG9yLCBhcmdzPShzaXRsWydwcm9jJ10sKSwgZGFlbW9uPVRydWUpLnN0YXJ0KCkKICAgIGxvZygnQXJkdVBpbG90IFNJVEwgYXJyYW5jYWRvOiAnICsgKCdTdGFsbGlvbiBWVE9MICh0aWx0LXJvdG9yKScgaWYgYXBhcmF0byA9PSAndnRvbCcgZWxzZSAnYWxhIGZpamEgYmltb3RvcicpCiAgICAgICAgKyAoJywgY29uIHR1IC5wYXJhbScgaWYgbGVuKHBhcnMpID4gMSBlbHNlICcsIGNvbiBlbCAucGFyYW0gZGUgcHJ1ZWJhJykgKyAoJyAocGFyw6FtZXRyb3MgZGVzZGUgY2VybyknIGlmIGxpbXBpbyBlbHNlICcnKSkKICAgIHJldHVybiBUcnVlCgoKZGVmIHNpdGxfYXJyYW5jYXJfbWlvKGFwYXJhdG8sIGhvbWU9Tm9uZSk6CiAgICAiIiJBcnJhbmNhIGRlIGNlcm8gKGVlcHJvbSBudWV2YSkgY29uIHR1IC5wYXJhbSByZWNpw6luIGNhcmdhZG8sIHNpbiBib3JyYXJsby4iIiIKICAgIGlmIHNpdGxbJ3Byb2MnXSBhbmQgc2l0bFsncHJvYyddLnBvbGwoKSBpcyBOb25lOgogICAgICAgIHNpdGxfcGFyYXIoKQogICAgZWVwID0gb3MucGF0aC5qb2luKEhFUkUsIEFQQVJBVE9TLmdldChhcGFyYXRvLCBBUEFSQVRPU1sndnRvbCddKVsxXSwgJ2VlcHJvbS5iaW4nKQogICAgaWYgb3MucGF0aC5leGlzdHMoZWVwKToKICAgICAgICBvcy5yZW1vdmUoZWVwKQogICAgcmV0dXJuIHNpdGxfYXJyYW5jYXIoRmFsc2UsIGFwYXJhdG8sIGhvbWUpCgoKZGVmIHNpdGxfcGFyYXIoKToKICAgIHAgPSBzaXRsWydwcm9jJ10KICAgIGlmIHAgYW5kIHAucG9sbCgpIGlzIE5vbmU6CiAgICAgICAgcC50ZXJtaW5hdGUoKQogICAgICAgIHRyeToKICAgICAgICAgICAgcC53YWl0KDUpCiAgICAgICAgZXhjZXB0IHN1YnByb2Nlc3MuVGltZW91dEV4cGlyZWQ6CiAgICAgICAgICAgIHAua2lsbCgpCiAgICAgICAgbG9nKCdBcmR1UGlsb3QgU0lUTCBwYXJhZG8nKQogICAgc2l0bFsncHJvYyddID0gTm9uZQogICAgc2l0bFsnYWRkciddID0gTm9uZQogICAgc2l0bFsndWx0aW1vJ10gPSAwLjAKICAgIHNpdGxbJ2FwYXJhdG8nXSA9IE5vbmUKICAgIHNpdGxbJ2hvbWVfcHJvYyddID0gTm9uZQogICAgcmV0dXJuIFRydWUKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEhUVFAgKDE0NTgwKQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gbG9ncyBkZWwgYXZpw7NuIHBvciBlbCBXaUZpIGRlbCBFU1AzMgojIERyb25lQnJpZGdlIChFU1AzMiBhIGJvcmRvLCBjb25lY3RhZG8gYSB1biBVQVJUIGRlIGxhIGNvbnRyb2xhZG9yYSkgZGEgdW4gc2Vydmlkb3IgVENQIGVuIGVsIHB1ZXJ0byA1NzYwIGNvbiBlbCBNQVZMaW5rCiMgZGUgQXJkdVBpbG90LiBQb3IgYWjDrSBzZSBwaWRlbiBsb3MgbG9ncyBjb21vIFFHcm91bmRDb250cm9sIChBbmFseXplIOKAuiBMb2cgRG93bmxvYWQpOiBMT0dfUkVRVUVTVF9MSVNUIOKGkiBMT0dfRU5UUlksCiMgTE9HX1JFUVVFU1RfREFUQSDihpIgTE9HX0RBVEEgKHRyb3pvcyBkZSA5MCBieXRlczsgbG9zIHF1ZSBmYWx0YW4gc2UgdnVlbHZlbiBhIHBlZGlyKSB5IExPR19SRVFVRVNUX0VORC4KIyBTb2xvIHBldGljaW9uZXMgZGUgbG9nLCBjb24gZWwgc2lzdGVtYSAyNTMgKG5vIGVsIDI1NSBkZSBsYSBlc3RhY2nDs24gZGUgdGllcnJhOiBubyB0b2NhIGVsIGZhaWxzYWZlIGRlIEdDUykuCkxPR1NfRElSID0gb3MucGF0aC5leHBhbmR1c2VyKCd+L0RvY3VtZW50cy9BSVJMQUIgTG9ncycpCkxPR19DUkMgPSB7MDogNTAsIDExODogNTYsIDEyMDogMTM0fQpMT0dfTEVOID0gezA6IDksIDExODogMTQsIDEyMDogOTd9CmVzcCA9IHsnaG9zdCc6IE5vbmUsICdjb25lY3RhZG8nOiBGYWxzZSwgJ2FybWFkbyc6IE5vbmUsICdsYXRpZG8nOiAwLjAsICdsaXN0YSc6IFtdLCAnbGlzdGFuZG8nOiBGYWxzZSwKICAgICAgICdkZXNjYXJnYSc6IE5vbmUsICdjb2xhJzogW10sICdlcnJvcic6IE5vbmUsICdhdXRvJzogVHJ1ZSwgJ2hlY2hvcyc6IDAsICdzZXNpb24nOiBOb25lfQojIGTDs25kZSBidXNjYXIgZWwgTUFWTGluayBkZWwgYXZpw7NuIHBvciBUQ1A6IENvcmVXaW5nIEY0MDUgV2luZyBWMiAobcOzZHVsbyBFU1AzMi1TMyBpbnRlZ3JhZG8gZW4gZWwgU0VSSUFMMSwgcmVkCiMgwqtDb3JlV2luZyBXSU5HLVdpRmnCuywgY29udHJhc2XDsWEgODg4ODg4ODgpIHkgRVNQMzIgZXh0ZXJubyBjb24gRHJvbmVCcmlkZ2UKY2ZnWydlc3AnXSA9IFsoJzE5Mi4xNjguMS4xJywgNDI3OCksICgnZHJvbmVicmlkZ2UubG9jYWwnLCA1NzYwKSwgKCcxOTIuMTY4LjIuMScsIDU3NjApXQoKCmRlZiBtYXZfY3JjKGRhdGEsIGV4dHJhKToKICAgIGNyYyA9IDB4RkZGRgogICAgZm9yIGIgaW4gYnl0ZXMoZGF0YSkgKyBieXRlcyhbZXh0cmFdKToKICAgICAgICB0ID0gKGIgXiAoY3JjICYgMHhGRikpICYgMHhGRgogICAgICAgIHQgPSAodCBeICh0IDw8IDQpKSAmIDB4RkYKICAgICAgICBjcmMgPSAoKGNyYyA+PiA4KSBeICh0IDw8IDgpIF4gKHQgPDwgMykgXiAodCA+PiA0KSkgJiAweEZGRkYKICAgIHJldHVybiBjcmMKCgpkZWYgbWF2Mihtc2dpZCwgZXh0cmEsIHBheWxvYWQsIHNlcSwgc3lzaWQ9MjUzLCBjb21waWQ9MTkwKToKICAgIHAgPSBieXRlcyhwYXlsb2FkKQogICAgd2hpbGUgbGVuKHApID4gMSBhbmQgcFstMV0gPT0gMDoKICAgICAgICBwID0gcFs6LTFdCiAgICBoID0gYnl0ZXMoW2xlbihwKSwgMCwgMCwgc2VxICYgMHhGRiwgc3lzaWQsIGNvbXBpZCwgbXNnaWQgJiAweEZGLCAobXNnaWQgPj4gOCkgJiAweEZGLCBtc2dpZCA+PiAxNl0pCiAgICBjID0gbWF2X2NyYyhoICsgcCwgZXh0cmEpCiAgICByZXR1cm4gYidceGZkJyArIGggKyBwICsgc3RydWN0LnBhY2soJzxIJywgYykKCgpjbGFzcyBMZWN0b3JNYXY6CiAgICAiIiJUcmFtYXMgTUFWTGluayAxIHkgMiBkZSBsb3MgbWVuc2FqZXMgcXVlIHNlIHVzYW4gcGFyYSBsb3MgbG9ncyAoQ1JDIGNvbXByb2JhZG8pLiIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBzZWxmLmJ1ZiA9IGJ5dGVhcnJheSgpCgogICAgZGVmIGZlZWQoc2VsZiwgZGF0YSk6CiAgICAgICAgc2VsZi5idWYgKz0gZGF0YQogICAgICAgIG91dCwgaSwgYiA9IFtdLCAwLCBzZWxmLmJ1ZgogICAgICAgIHdoaWxlIGkgPCBsZW4oYik6CiAgICAgICAgICAgIGlmIGJbaV0gbm90IGluICgweEZELCAweEZFKToKICAgICAgICAgICAgICAgIGkgKz0gMQogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgdjIgPSBiW2ldID09IDB4RkQKICAgICAgICAgICAgaGwgPSAxMCBpZiB2MiBlbHNlIDYKICAgICAgICAgICAgaWYgbGVuKGIpIC0gaSA8IGhsICsgMjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIG4gPSBiW2kgKyAxXQogICAgICAgICAgICB0b3QgPSBobCArIG4gKyAyICsgKDEzIGlmIHYyIGFuZCAoYltpICsgMl0gJiAxKSBlbHNlIDApCiAgICAgICAgICAgIGlmIGxlbihiKSAtIGkgPCB0b3Q6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBtaWQgPSAoYltpICsgN10gfCBiW2kgKyA4XSA8PCA4IHwgYltpICsgOV0gPDwgMTYpIGlmIHYyIGVsc2UgYltpICsgNV0KICAgICAgICAgICAgaWYgbWlkIG5vdCBpbiBMT0dfQ1JDOgogICAgICAgICAgICAgICAgaSArPSAxCiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBpZiBtYXZfY3JjKGJbaSArIDE6aSArIGhsICsgbl0sIExPR19DUkNbbWlkXSkgPT0gc3RydWN0LnVucGFja19mcm9tKCc8SCcsIGIsIGkgKyBobCArIG4pWzBdOgogICAgICAgICAgICAgICAgcGwgPSBieXRlcyhiW2kgKyBobDppICsgaGwgKyBuXSkubGp1c3QoTE9HX0xFTlttaWRdLCBiJ1wwJykKICAgICAgICAgICAgICAgIG91dC5hcHBlbmQoKG1pZCwgYltpICsgNV0gaWYgdjIgZWxzZSBiW2kgKyAzXSwgYltpICsgNl0gaWYgdjIgZWxzZSBiW2kgKyA0XSwgcGwpKQogICAgICAgICAgICAgICAgaSArPSB0b3QKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGkgKz0gMQogICAgICAgIGRlbCBzZWxmLmJ1Zls6aV0KICAgICAgICBpZiBsZW4oc2VsZi5idWYpID4gODE5MjoKICAgICAgICAgICAgc2VsZi5idWYuY2xlYXIoKQogICAgICAgIHJldHVybiBvdXQKCgpkZWYgbG9nc19pbmRpY2UoKToKICAgIHRyeToKICAgICAgICB3aXRoIG9wZW4ob3MucGF0aC5qb2luKExPR1NfRElSLCAnLmluZGljZS5qc29uJykpIGFzIGY6CiAgICAgICAgICAgIHJldHVybiBqc29uLmxvYWQoZikKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmV0dXJuIHt9CgoKZGVmIGxvZ3NfZ3VhcmRhcl9pbmRpY2UoaW5kKToKICAgIG9zLm1ha2VkaXJzKExPR1NfRElSLCBleGlzdF9vaz1UcnVlKQogICAgd2l0aCBvcGVuKG9zLnBhdGguam9pbihMT0dTX0RJUiwgJy5pbmRpY2UuanNvbicpLCAndycpIGFzIGY6CiAgICAgICAganNvbi5kdW1wKGluZCwgZiwgaW5kZW50PTEpCgoKZGVmIGNsYXZlX2xvZyhlKToKICAgIHJldHVybiBmIntlWydpZCddfS17ZVsnc2l6ZSddfS17ZVsndXRjJ119IgoKCmNsYXNzIFNlc2lvbkxvZ3M6CiAgICAiIiJVbmEgY29uZXhpw7NuIGNvbiBsYSBjb250cm9sYWRvcmEgYSB0cmF2w6lzIGRlbCBFU1AzMiAobyBjdWFscXVpZXIgdHJhbnNwb3J0ZSBjb24gc2VuZC9yZWN2IGRlIGJ5dGVzKS4iIiIKICAgIENIID0gOTAKCiAgICBkZWYgX19pbml0X18oc2VsZiwgZW52aWFyLCBjYXJwZXRhPU5vbmUsIGF1dG89VHJ1ZSk6CiAgICAgICAgc2VsZi5lbnZpYXIsIHNlbGYuY2FycGV0YSwgc2VsZi5hdXRvID0gZW52aWFyLCBjYXJwZXRhIG9yIExPR1NfRElSLCBhdXRvCiAgICAgICAgc2VsZi5sZWN0b3IsIHNlbGYuc2VxID0gTGVjdG9yTWF2KCksIDAKICAgICAgICBzZWxmLnRndCA9ICgxLCAxKQogICAgICAgIHNlbGYub2lkbyA9IEZhbHNlCiAgICAgICAgc2VsZi5hcm1hZG8gPSBOb25lCiAgICAgICAgc2VsZi5saXN0YSwgc2VsZi5lc3BlcmFkb3MsIHNlbGYudWx0X2VudHJ5LCBzZWxmLmxpc3RhbmRvLCBzZWxmLnRfbGlzdGEsIHNlbGYuaW50ZW50b3MgPSBbXSwgMCwgMC4wLCBGYWxzZSwgMC4wLCAwCiAgICAgICAgc2VsZi5kID0gTm9uZSAgICAgICAgICAgICMgZGVzY2FyZ2EgZW4gY3Vyc28KICAgICAgICBzZWxmLmNvbGEgPSBbXQogICAgICAgIHNlbGYuaGVjaG9zID0gW10gICAgICAgICAjIGFyY2hpdm9zIGd1YXJkYWRvcyBlbiBlc3RhIHNlc2nDs24KICAgICAgICBzZWxmLmVycm9yID0gTm9uZQoKICAgIGRlZiBfdHgoc2VsZiwgbWlkLCBleHRyYSwgcGwpOgogICAgICAgIHNlbGYuZW52aWFyKG1hdjIobWlkLCBleHRyYSwgcGwsIHNlbGYuc2VxKSkKICAgICAgICBzZWxmLnNlcSA9IChzZWxmLnNlcSArIDEpICYgMHhGRgoKICAgIGRlZiBwZWRpcl9saXN0YShzZWxmLCB0KToKICAgICAgICBzZWxmLmxpc3RhLCBzZWxmLmVzcGVyYWRvcywgc2VsZi51bHRfZW50cnkgPSBbXSwgMCwgMC4wCiAgICAgICAgc2VsZi5saXN0YW5kbywgc2VsZi50X2xpc3RhID0gVHJ1ZSwgdAogICAgICAgIHNlbGYuaW50ZW50b3MgKz0gMQogICAgICAgIHNlbGYuX3R4KDExNywgMTI4LCBzdHJ1Y3QucGFjaygnPEhIQkInLCAwLCAweEZGRkYsICpzZWxmLnRndCkpCgogICAgZGVmIF9wZWRpcl9kYXRvcyhzZWxmLCBsaWQsIG9mcywgY250LCB0KToKICAgICAgICBzZWxmLmRbJ3RfcmVxJ10gPSB0CiAgICAgICAgc2VsZi5kWydmaW5fcmVxJ10gPSAoc2VsZi5kWyduJ10gaWYgY250ID09IDB4RkZGRkZGRkYgZWxzZSAob2ZzICsgY250ICsgc2VsZi5DSCAtIDEpIC8vIHNlbGYuQ0gpIC0gMQogICAgICAgIHNlbGYuX3R4KDExOSwgMTE2LCBzdHJ1Y3QucGFjaygnPElJSEJCJywgb2ZzLCBjbnQsIGxpZCwgKnNlbGYudGd0KSkKCiAgICBkZWYgX2h1ZWNvcyhzZWxmLCB0KToKICAgICAgICAiIiJQaWRlIGRlIHVuYSB2ZXogZGVzZGUgZWwgcHJpbWVyIGh1ZWNvIGhhc3RhIGVsIMO6bHRpbW8gcXVlIHF1ZWRlIGEgbWVub3MgZGUgMTI4IHRyb3pvcyAobG9zIHJlcGV0aWRvcyBzZSBpZ25vcmFuKS4iIiIKICAgICAgICBkLCBoID0gc2VsZi5kLCBzZWxmLmRbJ2hhdmUnXQogICAgICAgIGsgPSBoLmZpbmQoMCkKICAgICAgICBpZiBrIDwgMDoKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgaiA9IGsKICAgICAgICBmb3IgbSBpbiByYW5nZShrICsgMSwgbWluKGRbJ24nXSwgayArIDEyOCkpOgogICAgICAgICAgICBpZiBub3QgaFttXToKICAgICAgICAgICAgICAgIGogPSBtCiAgICAgICAgb2ZzID0gayAqIHNlbGYuQ0gKICAgICAgICBzZWxmLl9wZWRpcl9kYXRvcyhkWydlJ11bJ2lkJ10sIG9mcywgbWluKGRbJ2UnXVsnc2l6ZSddIC0gb2ZzLCAoaiAtIGsgKyAxKSAqIHNlbGYuQ0gpLCB0KQoKICAgIGRlZiBfZmluKHNlbGYpOgogICAgICAgIHNlbGYuX3R4KDEyMiwgMjAzLCBzdHJ1Y3QucGFjaygnPEJCJywgKnNlbGYudGd0KSkKCiAgICBkZWYgYmFqYXIoc2VsZiwgZSwgdCk6CiAgICAgICAgaWYgc2VsZi5hcm1hZG86CiAgICAgICAgICAgIHNlbGYuZXJyb3IgPSAnRWwgYXZpw7NuIGVzdMOhIGFybWFkbzogbG9zIGxvZ3Mgc2UgYmFqYW4gYWwgZGVzYXJtYXIuJwogICAgICAgICAgICByZXR1cm4gRmFsc2UKICAgICAgICBuID0gKGVbJ3NpemUnXSArIHNlbGYuQ0ggLSAxKSAvLyBzZWxmLkNICiAgICAgICAgc2VsZi5kID0geydlJzogZSwgJ2J1Zic6IGJ5dGVhcnJheShlWydzaXplJ10pLCAnaGF2ZSc6IGJ5dGVhcnJheShuKSwgJ24nOiBuLCAnb2snOiAwLCAnYnl0ZXMnOiAwLAogICAgICAgICAgICAgICAgICAndDAnOiB0LCAndF9kYXRvJzogdCwgJ3RfcmVxJzogdCwgJ2Zpbl9yZXEnOiBuIC0gMSwgJ3dpbic6ICh0LCAwKSwgJ2ticyc6IDAuMH0KICAgICAgICBzZWxmLl9wZWRpcl9kYXRvcyhlWydpZCddLCAwLCAweEZGRkZGRkZGLCB0KQogICAgICAgIHJldHVybiBUcnVlCgogICAgZGVmIGVudHJhZGEoc2VsZiwgZGF0YSwgdCk6CiAgICAgICAgZm9yIG1pZCwgc3lzaWQsIGNvbXAsIHBsIGluIHNlbGYubGVjdG9yLmZlZWQoZGF0YSk6CiAgICAgICAgICAgIGlmIG1pZCA9PSAwOgogICAgICAgICAgICAgICAgaWYgY29tcCAhPSAxIG9yIHBsWzRdID09IDY6CiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgIHNlbGYudGd0ID0gKHN5c2lkLCBjb21wKQogICAgICAgICAgICAgICAgc2VsZi5hcm1hZG8gPSBib29sKHBsWzZdICYgMHg4MCkKICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLm9pZG86CiAgICAgICAgICAgICAgICAgICAgc2VsZi5vaWRvID0gVHJ1ZQogICAgICAgICAgICAgICAgICAgIHNlbGYucGVkaXJfbGlzdGEodCkKICAgICAgICAgICAgZWxpZiBtaWQgPT0gMTE4OgogICAgICAgICAgICAgICAgdXRjLCBzaXplLCBsaWQsIG51bSwgXyA9IHN0cnVjdC51bnBhY2tfZnJvbSgnPElJSEhIJywgcGwpCiAgICAgICAgICAgICAgICBzZWxmLmVzcGVyYWRvcywgc2VsZi51bHRfZW50cnkgPSBudW0sIHQKICAgICAgICAgICAgICAgIGlmIG51bSA9PSAwOgogICAgICAgICAgICAgICAgICAgIHNlbGYubGlzdGEsIHNlbGYubGlzdGFuZG8gPSBbXSwgRmFsc2UKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgaWYgc2l6ZSA+IDAgYW5kIG5vdCBhbnkoeFsnaWQnXSA9PSBsaWQgZm9yIHggaW4gc2VsZi5saXN0YSk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5saXN0YS5hcHBlbmQoeydpZCc6IGxpZCwgJ3NpemUnOiBzaXplLCAndXRjJzogdXRjfSkKICAgICAgICAgICAgICAgICAgICBzZWxmLmxpc3RhLnNvcnQoa2V5PWxhbWJkYSB4OiB4WydpZCddKQogICAgICAgICAgICAgICAgaWYgbGVuKHNlbGYubGlzdGEpID49IG51bSBhbmQgc2VsZi5saXN0YW5kbzoKICAgICAgICAgICAgICAgICAgICBzZWxmLl9saXN0YV9oZWNoYSgpCiAgICAgICAgICAgIGVsaWYgbWlkID09IDEyMCBhbmQgc2VsZi5kOgogICAgICAgICAgICAgICAgb2ZzLCBsaWQsIGNudCA9IHN0cnVjdC51bnBhY2tfZnJvbSgnPElIQicsIHBsKQogICAgICAgICAgICAgICAgZSA9IHNlbGYuZFsnZSddCiAgICAgICAgICAgICAgICBpZiBsaWQgIT0gZVsnaWQnXSBvciBjbnQgPT0gMCBvciBvZnMgPj0gZVsnc2l6ZSddIG9yIG9mcyAlIHNlbGYuQ0g6CiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgIGssIG4gPSBvZnMgLy8gc2VsZi5DSCwgbWluKGNudCwgZVsnc2l6ZSddIC0gb2ZzLCBzZWxmLkNIKQogICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuZFsnaGF2ZSddW2tdOgogICAgICAgICAgICAgICAgICAgIHNlbGYuZFsnYnVmJ11bb2ZzOm9mcyArIG5dID0gcGxbNzo3ICsgbl0KICAgICAgICAgICAgICAgICAgICBzZWxmLmRbJ2hhdmUnXVtrXSA9IDEKICAgICAgICAgICAgICAgICAgICBzZWxmLmRbJ29rJ10gKz0gMQogICAgICAgICAgICAgICAgICAgIHNlbGYuZFsnYnl0ZXMnXSArPSBuCiAgICAgICAgICAgICAgICBzZWxmLmRbJ3RfZGF0byddID0gdAogICAgICAgICAgICAgICAgaWYgc2VsZi5kWydvayddID09IHNlbGYuZFsnbiddOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2d1YXJkYXIodCkKICAgICAgICAgICAgICAgIGVsaWYgayA9PSBzZWxmLmRbJ2Zpbl9yZXEnXToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9odWVjb3ModCkgICAgICAjIGFjYWLDsyBlbCB0cmFtbyBwZWRpZG86IGxvcyBodWVjb3MgcXVlIHF1ZWRlbiwgc2luIGVzcGVyYXIKCiAgICBkZWYgX2xpc3RhX2hlY2hhKHNlbGYpOgogICAgICAgIHNlbGYubGlzdGFuZG8gPSBGYWxzZQogICAgICAgIGlmIHNlbGYuYXV0bzoKICAgICAgICAgICAgaW5kID0gbG9nc19pbmRpY2UoKQogICAgICAgICAgICBzZWxmLmNvbGEgPSBbZSBmb3IgZSBpbiBzZWxmLmxpc3RhIGlmIGNsYXZlX2xvZyhlKSBub3QgaW4gaW5kXQoKICAgIGRlZiBfZ3VhcmRhcihzZWxmLCB0KToKICAgICAgICBlID0gc2VsZi5kWydlJ10KICAgICAgICBzZWxmLl9maW4oKQogICAgICAgIGZlY2hhID0gdGltZS5zdHJmdGltZSgnJVktJW0tJWRfJUgtJU0nLCB0aW1lLmxvY2FsdGltZShlWyd1dGMnXSBpZiBlWyd1dGMnXSA+IDAgZWxzZSB0aW1lLnRpbWUoKSkpCiAgICAgICAgbm9tYnJlID0gZid7ZmVjaGF9X2xvZ3tlWyJpZCJdfS5iaW4nCiAgICAgICAgb3MubWFrZWRpcnMoc2VsZi5jYXJwZXRhLCBleGlzdF9vaz1UcnVlKQogICAgICAgIHdpdGggb3Blbihvcy5wYXRoLmpvaW4oc2VsZi5jYXJwZXRhLCBub21icmUpLCAnd2InKSBhcyBmOgogICAgICAgICAgICBmLndyaXRlKHNlbGYuZFsnYnVmJ10pCiAgICAgICAgaW5kID0gbG9nc19pbmRpY2UoKQogICAgICAgIGluZFtjbGF2ZV9sb2coZSldID0geydhcmNoaXZvJzogbm9tYnJlLCAnYmFqYWRvJzogaW50KHRpbWUudGltZSgpKSwgJ3NpemUnOiBlWydzaXplJ119CiAgICAgICAgbG9nc19ndWFyZGFyX2luZGljZShpbmQpCiAgICAgICAgZHVyID0gbWF4KDAuMSwgdCAtIHNlbGYuZFsndDAnXSkKICAgICAgICBsb2coZidMb2dzOiBsb2cge2VbImlkIl19IGd1YXJkYWRvICh7ZVsic2l6ZSJdIC8gMWU2Oi4xZn0gTUIgZW4ge2R1cjouMGZ9IHMsIHtlWyJzaXplIl0gLyBkdXIgLyAxMDI0Oi4wZn0ga0Ivcykg4oaSIHtub21icmV9JykKICAgICAgICBzZWxmLmhlY2hvcy5hcHBlbmQobm9tYnJlKQogICAgICAgIHNlbGYuZCA9IE5vbmUKCiAgICBkZWYgdGljKHNlbGYsIHQpOgogICAgICAgIGlmIHNlbGYubGlzdGFuZG86CiAgICAgICAgICAgIGlmIG5vdCBzZWxmLmxpc3RhIGFuZCB0IC0gc2VsZi50X2xpc3RhID4gMjoKICAgICAgICAgICAgICAgIGlmIHNlbGYuaW50ZW50b3MgPCA1OgogICAgICAgICAgICAgICAgICAgIHNlbGYucGVkaXJfbGlzdGEodCkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5saXN0YW5kbywgc2VsZi5lcnJvciA9IEZhbHNlLCAnTGEgY29udHJvbGFkb3JhIG5vIGNvbnRlc3RhIGEgbGEgbGlzdGEgZGUgbG9ncy4nCiAgICAgICAgICAgIGVsaWYgc2VsZi5saXN0YSBhbmQgdCAtIHNlbGYudWx0X2VudHJ5ID4gMjoKICAgICAgICAgICAgICAgIHNlbGYuX2xpc3RhX2hlY2hhKCkKICAgICAgICBkID0gc2VsZi5kCiAgICAgICAgaWYgZDoKICAgICAgICAgICAgdyA9IGRbJ3dpbiddCiAgICAgICAgICAgIGlmIHQgLSB3WzBdID49IDE6CiAgICAgICAgICAgICAgICBkWydrYnMnXSA9IChkWydieXRlcyddIC0gd1sxXSkgLyAodCAtIHdbMF0pIC8gMTAyNAogICAgICAgICAgICAgICAgZFsnd2luJ10gPSAodCwgZFsnYnl0ZXMnXSkKICAgICAgICAgICAgcGFyYWRvID0gdCAtIGRbJ3RfZGF0byddCiAgICAgICAgICAgIGlmIHBhcmFkbyA+IDE1OgogICAgICAgICAgICAgICAgc2VsZi5lcnJvciA9IGYnRWwgbG9nIHtkWyJlIl1bImlkIl19IHNlIGhhIGNvcnRhZG86IGVsIGF2acOzbiBoYSBkZWphZG8gZGUgY29udGVzdGFyLicKICAgICAgICAgICAgICAgIHNlbGYuZCA9IE5vbmUKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBpZiBwYXJhZG8gPiAwLjQgYW5kIHQgLSBkWyd0X3JlcSddID4gMC40OgogICAgICAgICAgICAgICAgc2VsZi5faHVlY29zKHQpICAgICAgICAgICMgc2UgcGVyZGnDsyBlbCBmaW5hbCBkZSB1biB0cmFtbzogc2UgdnVlbHZlIGEgcGVkaXIgbG8gcXVlIGZhbHRlCiAgICAgICAgZWxpZiBzZWxmLmNvbGEgYW5kIG5vdCBzZWxmLmxpc3RhbmRvIGFuZCBzZWxmLmFybWFkbyBpcyBGYWxzZToKICAgICAgICAgICAgc2VsZi5iYWphcihzZWxmLmNvbGEucG9wKDApLCB0KQoKICAgIGRlZiBlc3RhZG8oc2VsZik6CiAgICAgICAgZCA9IHNlbGYuZAogICAgICAgIHJldHVybiB7J29pZG8nOiBzZWxmLm9pZG8sICdhcm1hZG8nOiBzZWxmLmFybWFkbywgJ2xpc3RhbmRvJzogc2VsZi5saXN0YW5kbywgJ2Vycm9yJzogc2VsZi5lcnJvciwKICAgICAgICAgICAgICAgICdsaXN0YSc6IFt7KiplLCAnYmFqYWRvJzogY2xhdmVfbG9nKGUpIGluIGxvZ3NfaW5kaWNlKCl9IGZvciBlIGluIHNlbGYubGlzdGFdLAogICAgICAgICAgICAgICAgJ2NvbGEnOiBbZVsnaWQnXSBmb3IgZSBpbiBzZWxmLmNvbGFdLAogICAgICAgICAgICAgICAgJ2Rlc2NhcmdhJzogTm9uZSBpZiBub3QgZCBlbHNlIHsnaWQnOiBkWydlJ11bJ2lkJ10sICdzaXplJzogZFsnZSddWydzaXplJ10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwcm9ncmVzbyc6IGRbJ29rJ10gLyBkWyduJ10sICdrYnMnOiByb3VuZChkWydrYnMnXSl9fQoKCmRlZiBlc3BfdmlnaWEoKToKICAgICIiIkJ1c2NhIGVsIEVTUDMyIGRlIGEgYm9yZG8gY2FkYSBwb2NvcyBzZWd1bmRvcyB5LCBhbCBlbmNvbnRyYXJsbywgYmFqYSBsb3MgbG9ncyBudWV2b3MuIiIiCiAgICB3aGlsZSBUcnVlOgogICAgICAgIGZvciBob3N0LCBwdWVydG8gaW4gY2ZnWydlc3AnXToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgcyA9IHNvY2tldC5jcmVhdGVfY29ubmVjdGlvbigoaG9zdCwgcHVlcnRvKSwgdGltZW91dD0zKQogICAgICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIHMuc2V0dGltZW91dCgwLjIpCiAgICAgICAgICAgIHMuc2V0c29ja29wdChzb2NrZXQuSVBQUk9UT19UQ1AsIHNvY2tldC5UQ1BfTk9ERUxBWSwgMSkKICAgICAgICAgICAgc2VzID0gU2VzaW9uTG9ncyhsYW1iZGEgYjogcy5zZW5kYWxsKGIpLCBhdXRvPWVzcFsnYXV0byddKQogICAgICAgICAgICBlc3AudXBkYXRlKGhvc3Q9Zid7aG9zdH06e3B1ZXJ0b30nLCBjb25lY3RhZG89VHJ1ZSwgc2VzaW9uPXNlcywgZXJyb3I9Tm9uZSkKICAgICAgICAgICAgbG9nKGYnTG9nczogV2lGaSBkZWwgYXZpw7NuIGVuY29udHJhZG8gZW4ge2hvc3R9OntwdWVydG99JykKICAgICAgICAgICAgdWx0aW1vID0gYWhvcmEoKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHMucmVjdig2NTUzNikKICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm90IGRhdGE6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgICAgICAgICB1bHRpbW8gPSBhaG9yYSgpCiAgICAgICAgICAgICAgICAgICAgICAgIHNlcy5lbnRyYWRhKGRhdGEsIHVsdGltbykKICAgICAgICAgICAgICAgICAgICBleGNlcHQgc29ja2V0LnRpbWVvdXQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICAgICAgICAgICAgICBzZXMudGljKGFob3JhKCkpCiAgICAgICAgICAgICAgICAgICAgaWYgYWhvcmEoKSAtIHVsdGltbyA+IDEwOgogICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICAgICAgZmluYWxseToKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBzLmNsb3NlKCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICAgICAgICAgIGVzcC51cGRhdGUoY29uZWN0YWRvPUZhbHNlLCBzZXNpb249Tm9uZSkKICAgICAgICAgICAgICAgIGxvZygnTG9nczogV2lGaSBkZWwgYXZpw7NuIGRlc2NvbmVjdGFkbycpCiAgICAgICAgICAgIGJyZWFrCiAgICAgICAgdGltZS5zbGVlcCg1KQoKCmRlZiBsb2dzX2FyY2hpdm9zKCk6CiAgICB0cnk6CiAgICAgICAgZnMgPSBbZiBmb3IgZiBpbiBvcy5saXN0ZGlyKExPR1NfRElSKSBpZiBmLmxvd2VyKCkuZW5kc3dpdGgoJy5iaW4nKV0KICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgIHJldHVybiBbXQogICAgb3V0ID0gW10KICAgIGZvciBmIGluIGZzOgogICAgICAgIHN0ID0gb3Muc3RhdChvcy5wYXRoLmpvaW4oTE9HU19ESVIsIGYpKQogICAgICAgIG91dC5hcHBlbmQoeydub21icmUnOiBmLCAndGFtJzogc3Quc3Rfc2l6ZSwgJ210aW1lJzogaW50KHN0LnN0X210aW1lKX0pCiAgICByZXR1cm4gc29ydGVkKG91dCwga2V5PWxhbWJkYSB4OiAteFsnbXRpbWUnXSlbOjYwXQoKCmRlZiBsb2dzX2VzdGFkbygpOgogICAgc2VzID0gZXNwWydzZXNpb24nXQogICAgcmV0dXJuIHsnY2FycGV0YSc6IExPR1NfRElSLCAnaG9zdCc6IGVzcFsnaG9zdCddLCAnY29uZWN0YWRvJzogZXNwWydjb25lY3RhZG8nXSwgJ2F1dG8nOiBlc3BbJ2F1dG8nXSwKICAgICAgICAgICAgJ2F2aW9uJzogc2VzLmVzdGFkbygpIGlmIHNlcyBlbHNlIE5vbmUsICdhcmNoaXZvcyc6IGxvZ3NfYXJjaGl2b3MoKX0KCgpkZWYgZXN0YWRvKCk6CiAgICB0ID0gYWhvcmEoKQogICAgcCA9IHNpdGxbJ3Byb2MnXQogICAgcmV0dXJuIHsKICAgICAgICAnY29uZWN0b3InOiBWRVJTSU9OLCAncGxhdGFmb3JtYSc6IHN5cy5wbGF0Zm9ybSwKICAgICAgICAncmVhbCc6IHsnb2N1cGFkbyc6IHJlYWxbJ29jdXBhZG8nXSwgJ3BhcXVldGVzJzogcmVhbFsncGFxdWV0ZXMnXSwgJ2xsZWdhJzogdCAtIHJlYWxbJ3VsdGltbyddIDwgMywKICAgICAgICAgICAgICAgICAnZGVzZGUnOiByZWFsWydkZXNkZSddWzBdIGlmIHJlYWxbJ2Rlc2RlJ10gZWxzZSBOb25lLCAncGVzdGFuYXMnOiBsZW4ocmVhbFsnY2xpZW50ZXMnXSksCiAgICAgICAgICAgICAgICAgJ3JlZW52aWFyJzogY2ZnWydyZWVudmlhciddfSwKICAgICAgICAnc2l0bCc6IHsnYmluYXJpbyc6IGJvb2woYXJkdXBpbG90X2JpbigpKSwgJ3J1dGEnOiBhcmR1cGlsb3RfYmluKCksICdwcm9waW8nOiBib29sKHAgYW5kIHAucG9sbCgpIGlzIE5vbmUpLAogICAgICAgICAgICAgICAgICdhY3Rpdm8nOiB0IC0gc2l0bFsndWx0aW1vJ10gPCAzLCAncmF0ZSc6IHNpdGxbJ3JhdGUnXSwgJ3NpbXVsYWRvcic6IHNpdGxbJ3dzJ10gaXMgbm90IE5vbmUsCiAgICAgICAgICAgICAgICAgJ21hdmxpbmsnOiB0IC0gc2l0bFsnbWF2X3VsdGltbyddIDwgNSwgJ29jdXBhZG8nOiBzaXRsWydvY3VwYWRvJ10sICdsb2cnOiBzaXRsWydsb2cnXVstODpdLAogICAgICAgICAgICAgICAgICdhcGFyYXRvJzogc2l0bFsnYXBhcmF0byddIGlmIChwIGFuZCBwLnBvbGwoKSBpcyBOb25lKSBlbHNlIE5vbmUsCiAgICAgICAgICAgICAgICAgJ21pbyc6IHthOiBvcy5wYXRoLmV4aXN0cyhtaW9fcnV0YShhKSkgZm9yIGEgaW4gQVBBUkFUT1N9LAogICAgICAgICAgICAgICAgICdtYXZjbWQnOiBUcnVlLCAnaG9tZSc6IGxpc3Qoc2l0bFsnaG9tZV9wcm9jJ10gb3Igc2l0bFsnaG9tZSddKX0sCiAgICAgICAgJ2xvZ3MnOiB7J2VzcCc6IGVzcFsnY29uZWN0YWRvJ10sICdob3N0JzogZXNwWydob3N0J10sICdhcmNoaXZvcyc6IGxlbihsb2dzX2FyY2hpdm9zKCkpfSwKICAgIH0KCgpjbGFzcyBNYW5lamFkb3IoQmFzZUhUVFBSZXF1ZXN0SGFuZGxlcik6CiAgICBkZWYgY2FiZWNlcmFzKHNlbGYsIHRpcG89J3RleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgnKToKICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCdDb250ZW50LVR5cGUnLCB0aXBvKQogICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbicsICcqJykKICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1Qcml2YXRlLU5ldHdvcmsnLCAndHJ1ZScpCiAgICAgICAgc2VsZi5zZW5kX2hlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycycsICcqJykKICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCdDYWNoZS1Db250cm9sJywgJ25vLWNhY2hlJykKCiAgICBkZWYgZG9fT1BUSU9OUyhzZWxmKToKICAgICAgICBzZWxmLnNlbmRfcmVzcG9uc2UoMjA0KQogICAgICAgIHNlbGYuY2FiZWNlcmFzKCkKICAgICAgICBzZWxmLmVuZF9oZWFkZXJzKCkKCiAgICBkZWYganNvbihzZWxmLCBvYmopOgogICAgICAgIGIgPSBqc29uLmR1bXBzKG9iaikuZW5jb2RlKCkKICAgICAgICBzZWxmLnNlbmRfcmVzcG9uc2UoMjAwKQogICAgICAgIHNlbGYuY2FiZWNlcmFzKCdhcHBsaWNhdGlvbi9qc29uJykKICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCdDb250ZW50LUxlbmd0aCcsIHN0cihsZW4oYikpKQogICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgIHNlbGYud2ZpbGUud3JpdGUoYikKCiAgICBkZWYgZG9fUE9TVChzZWxmKToKICAgICAgICB1ID0gdXJscGFyc2Uoc2VsZi5wYXRoKQogICAgICAgIGlmIHUucGF0aCA9PSAnL3NpdGwvcGFyYW0nOgogICAgICAgICAgICAjIHR1IC5wYXJhbTogc2UgZ3VhcmRhIHNpbiBsbyBkZSBsYSBwbGFjYSB5IEFyZHVQaWxvdCBzZSBhcnJhbmNhIGRlIGNlcm8gY29uIMOpbAogICAgICAgICAgICBxID0gcGFyc2VfcXModS5xdWVyeSkKICAgICAgICAgICAgYXAgPSBxLmdldCgnYXBhcmF0bycsIFsndnRvbCddKVswXQogICAgICAgICAgICBuID0gaW50KHNlbGYuaGVhZGVycy5nZXQoJ0NvbnRlbnQtTGVuZ3RoJykgb3IgMCkKICAgICAgICAgICAgdGV4dG8gPSBzZWxmLnJmaWxlLnJlYWQobWluKG4sIDJfMDAwXzAwMCkpLmRlY29kZSgndXRmLTgnLCAncmVwbGFjZScpCiAgICAgICAgICAgIGJ1ZW5hcywgcXVpdGFkYXMgPSBtaW9fZ3VhcmRhcih0ZXh0bywgYXAgaWYgYXAgaW4gQVBBUkFUT1MgZWxzZSAndnRvbCcpCiAgICAgICAgICAgIG9rID0gRmFsc2UKICAgICAgICAgICAgaWYgYnVlbmFzOgogICAgICAgICAgICAgICAgc2l0bF9wYXJhcigpCiAgICAgICAgICAgICAgICBvayA9IHNpdGxfYXJyYW5jYXJfbWlvKGFwLCBsZWVyX2hvbWUocSkpCiAgICAgICAgICAgIHJldHVybiBzZWxmLmpzb24oeydvayc6IG9rLCAncGFyYW1ldHJvcyc6IGJ1ZW5hcywgJ3F1aXRhZG9zJzogcXVpdGFkYXMsICoqZXN0YWRvKCl9KQogICAgICAgIGlmIHUucGF0aCA9PSAnL3JlYWwvZW52aWFyJzoKICAgICAgICAgICAgIyBBSVJMQUIgQ29ja3BpdCB3ZWI6IHRyYW1hcyBNQVZMaW5rIGVuIGJhc2U2NCBoYWNpYSBlbCBCYWNrcGFjayAoc29sbyBwZXRpY2lvbmVzIGRlIGxvZywgc2lzdGVtYSAyNTMpCiAgICAgICAgICAgIG4gPSBpbnQoc2VsZi5oZWFkZXJzLmdldCgnQ29udGVudC1MZW5ndGgnKSBvciAwKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBkYXRvcyA9IGJhc2U2NC5iNjRkZWNvZGUoc2VsZi5yZmlsZS5yZWFkKG1pbihuLCA0MDk2KSkpCiAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgZGF0b3MgPSBiJycKICAgICAgICAgICAgb2sgPSBib29sKGRhdG9zKSBhbmQgZGF0b3NbMF0gaW4gKDB4RkQsIDB4RkUpIGFuZCByZWFsLmdldCgnc29jaycpIGlzIG5vdCBOb25lIGFuZCByZWFsWydkZXNkZSddIGlzIG5vdCBOb25lCiAgICAgICAgICAgIGlmIG9rOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHJlYWxbJ3NvY2snXS5zZW5kdG8oZGF0b3MsIHJlYWxbJ2Rlc2RlJ10pCiAgICAgICAgICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgICAgICAgICBvayA9IEZhbHNlCiAgICAgICAgICAgIHJldHVybiBzZWxmLmpzb24oeydvayc6IG9rfSkKICAgICAgICBzZWxmLmRvX0dFVCgpCgogICAgZGVmIGRvX0dFVChzZWxmKToKICAgICAgICB1ID0gdXJscGFyc2Uoc2VsZi5wYXRoKQogICAgICAgIHEgPSBwYXJzZV9xcyh1LnF1ZXJ5KQogICAgICAgIGlmIHUucGF0aCA9PSAnL2VzdGFkbyc6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmpzb24oZXN0YWRvKCkpCiAgICAgICAgaWYgdS5wYXRoID09ICcvc2l0bC9hcnJhbmNhcic6CiAgICAgICAgICAgIG9rID0gc2l0bF9hcnJhbmNhcihxLmdldCgnbGltcGlvJywgWycwJ10pWzBdID09ICcxJywgcS5nZXQoJ2FwYXJhdG8nLCBbJ2Z3J10pWzBdLCBsZWVyX2hvbWUocSkpCiAgICAgICAgICAgIHJldHVybiBzZWxmLmpzb24oeydvayc6IG9rLCAqKmVzdGFkbygpfSkKICAgICAgICBpZiB1LnBhdGggPT0gJy9zaXRsL3BhcmFyJzoKICAgICAgICAgICAgc2l0bF9wYXJhcigpCiAgICAgICAgICAgIHJldHVybiBzZWxmLmpzb24oeydvayc6IFRydWUsICoqZXN0YWRvKCl9KQogICAgICAgIGlmIHUucGF0aCA9PSAnL3NpdGwvcmVpbmljaWFyJzoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuanNvbih7J29rJzogc2l0bF9yZWJvb3QoKSwgKiplc3RhZG8oKX0pCiAgICAgICAgaWYgdS5wYXRoID09ICcvc3RyZWFtJzoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuc3RyZWFtKCkKICAgICAgICBpZiB1LnBhdGggPT0gJy9sb2dzJzoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuanNvbihsb2dzX2VzdGFkbygpKQogICAgICAgIGlmIHUucGF0aCA9PSAnL2xvZ3MvYXJjaGl2byc6CiAgICAgICAgICAgIG5vbWJyZSA9IG9zLnBhdGguYmFzZW5hbWUocS5nZXQoJ24nLCBbJyddKVswXSkKICAgICAgICAgICAgcnV0YSA9IG9zLnBhdGguam9pbihMT0dTX0RJUiwgbm9tYnJlKQogICAgICAgICAgICBpZiBub3Qgbm9tYnJlLmxvd2VyKCkuZW5kc3dpdGgoJy5iaW4nKSBvciBub3Qgb3MucGF0aC5pc2ZpbGUocnV0YSk6CiAgICAgICAgICAgICAgICBzZWxmLnNlbmRfcmVzcG9uc2UoNDA0KQogICAgICAgICAgICAgICAgc2VsZi5jYWJlY2VyYXMoKQogICAgICAgICAgICAgICAgc2VsZi5lbmRfaGVhZGVycygpCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgd2l0aCBvcGVuKHJ1dGEsICdyYicpIGFzIGY6CiAgICAgICAgICAgICAgICBiID0gZi5yZWFkKCkKICAgICAgICAgICAgc2VsZi5zZW5kX3Jlc3BvbnNlKDIwMCkKICAgICAgICAgICAgc2VsZi5jYWJlY2VyYXMoJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpCiAgICAgICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoJ0NvbnRlbnQtTGVuZ3RoJywgc3RyKGxlbihiKSkpCiAgICAgICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgICAgICBzZWxmLndmaWxlLndyaXRlKGIpCiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIHUucGF0aCA9PSAnL2xvZ3MvYmFqYXInOgogICAgICAgICAgICBzZXMgPSBlc3BbJ3Nlc2lvbiddCiAgICAgICAgICAgIGlmIHNlcyBhbmQgc2VzLmxpc3RhOgogICAgICAgICAgICAgICAgbGlkID0gaW50KHEuZ2V0KCdpZCcsIFsnLTEnXSlbMF0pCiAgICAgICAgICAgICAgICBlID0gbmV4dCgoeCBmb3IgeCBpbiBzZXMubGlzdGEgaWYgeFsnaWQnXSA9PSBsaWQpLCBOb25lKQogICAgICAgICAgICAgICAgaWYgZSBhbmQgZSBub3QgaW4gc2VzLmNvbGEgYW5kIG5vdCAoc2VzLmQgYW5kIHNlcy5kWydlJ11bJ2lkJ10gPT0gbGlkKToKICAgICAgICAgICAgICAgICAgICBzZXMuY29sYS5hcHBlbmQoZSkKICAgICAgICAgICAgcmV0dXJuIHNlbGYuanNvbihsb2dzX2VzdGFkbygpKQogICAgICAgIGlmIHUucGF0aCA9PSAnL2xvZ3MvYnVzY2FyJzoKICAgICAgICAgICAgc2VzID0gZXNwWydzZXNpb24nXQogICAgICAgICAgICBpZiBzZXMgYW5kIG5vdCBzZXMuZDoKICAgICAgICAgICAgICAgIHNlcy5pbnRlbnRvcyA9IDAKICAgICAgICAgICAgICAgIHNlcy5wZWRpcl9saXN0YShhaG9yYSgpKQogICAgICAgICAgICByZXR1cm4gc2VsZi5qc29uKGxvZ3NfZXN0YWRvKCkpCiAgICAgICAgaWYgdS5wYXRoID09ICcvbG9ncy9hdXRvJzoKICAgICAgICAgICAgZXNwWydhdXRvJ10gPSBxLmdldCgnb24nLCBbJzEnXSlbMF0gPT0gJzEnCiAgICAgICAgICAgIGlmIGVzcFsnc2VzaW9uJ106CiAgICAgICAgICAgICAgICBlc3BbJ3Nlc2lvbiddLmF1dG8gPSBlc3BbJ2F1dG8nXQogICAgICAgICAgICByZXR1cm4gc2VsZi5qc29uKGxvZ3NfZXN0YWRvKCkpCiAgICAgICAgc2VsZi5zZW5kX3Jlc3BvbnNlKDIwMCkKICAgICAgICBzZWxmLmNhYmVjZXJhcygpCiAgICAgICAgc2VsZi5lbmRfaGVhZGVycygpCiAgICAgICAgc2VsZi53ZmlsZS53cml0ZShmIkFJUkxBQiBDb25lY3RvciB7VkVSU0lPTn0gZW4gbWFyY2hhLiBUZWxlbWV0csOtYSByZWFsOiB7cmVhbFsncGFxdWV0ZXMnXX0gcGFxdWV0ZXMgwrcgIgogICAgICAgICAgICAgICAgICAgICAgICAgZiJTSVRMOiB7c2l0bFsncngnXX0gcGFzb3NcbiIuZW5jb2RlKCkpCgogICAgZGVmIHN0cmVhbShzZWxmKToKICAgICAgICBzZWxmLnNlbmRfcmVzcG9uc2UoMjAwKQogICAgICAgIHNlbGYuY2FiZWNlcmFzKCd0ZXh0L2V2ZW50LXN0cmVhbScpCiAgICAgICAgc2VsZi5lbmRfaGVhZGVycygpCiAgICAgICAgcSA9IHF1ZXVlLlF1ZXVlKCkKICAgICAgICB3aXRoIGxvY2s6CiAgICAgICAgICAgIHJlYWxbJ2NsaWVudGVzJ10uYXBwZW5kKHEpCiAgICAgICAgbG9nKCdWdWVsbyByZWFsOiBzaW11bGFkb3IgY29uZWN0YWRvJykKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYud2ZpbGUud3JpdGUoYic6IGhvbGFcblxuJykKICAgICAgICAgICAgc2VsZi53ZmlsZS5mbHVzaCgpCiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgbGluZWEgPSBxLmdldCh0aW1lb3V0PTUpCiAgICAgICAgICAgICAgICBleGNlcHQgcXVldWUuRW1wdHk6CiAgICAgICAgICAgICAgICAgICAgbGluZWEgPSBiJzogbGF0aWRvXG5cbicKICAgICAgICAgICAgICAgIHNlbGYud2ZpbGUud3JpdGUobGluZWEpCiAgICAgICAgICAgICAgICBzZWxmLndmaWxlLmZsdXNoKCkKICAgICAgICBleGNlcHQgKEJyb2tlblBpcGVFcnJvciwgQ29ubmVjdGlvblJlc2V0RXJyb3IsIENvbm5lY3Rpb25BYm9ydGVkRXJyb3IsIE9TRXJyb3IpOgogICAgICAgICAgICBwYXNzCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgd2l0aCBsb2NrOgogICAgICAgICAgICAgICAgaWYgcSBpbiByZWFsWydjbGllbnRlcyddOgogICAgICAgICAgICAgICAgICAgIHJlYWxbJ2NsaWVudGVzJ10ucmVtb3ZlKHEpCiAgICAgICAgICAgIGxvZygnVnVlbG8gcmVhbDogc2ltdWxhZG9yIGRlc2NvbmVjdGFkbycpCgogICAgZGVmIGxvZ19tZXNzYWdlKHNlbGYsICphKToKICAgICAgICBwYXNzCgoKZGVmIHJlc3VtZW4oKToKICAgIGEgPSBiID0gYyA9IDAKICAgIHdoaWxlIFRydWU6CiAgICAgICAgdGltZS5zbGVlcCgxMCkKICAgICAgICBwYXJ0ZXMgPSBbXQogICAgICAgIGlmIHJlYWxbJ3BhcXVldGVzJ10gIT0gYToKICAgICAgICAgICAgcGFydGVzLmFwcGVuZChmInRlbGVtZXRyw61hIHJlYWwgeyhyZWFsWydwYXF1ZXRlcyddIC0gYSkgLyAxMDouMGZ9IHBhcXVldGVzL3MiKQogICAgICAgIGlmIHNpdGxbJ3J4J10gIT0gYjoKICAgICAgICAgICAgcGFydGVzLmFwcGVuZChmIlNJVEwgeyhzaXRsWydyeCddIC0gYikgLyAxMDouMGZ9IHBhc29zL3MiICsgKCcnIGlmIHNpdGxbJ3dzJ10gZWxzZSAnIChmYWx0YSBlbmxhemFyIGVsIHNpbXVsYWRvciknKSkKICAgICAgICBpZiBwYXJ0ZXM6CiAgICAgICAgICAgIGxvZygnRW4gbWFyY2hhOiAnICsgJyDCtyAnLmpvaW4ocGFydGVzKSkKICAgICAgICBhLCBiID0gcmVhbFsncGFxdWV0ZXMnXSwgc2l0bFsncngnXQoKCmRlZiBtYWluKCk6CiAgICBhcCA9IGFyZ3BhcnNlLkFyZ3VtZW50UGFyc2VyKGRlc2NyaXB0aW9uPSdBSVJMQUIgRlBWIMK3IENvbmVjdG9yICh2dWVsbyByZWFsICsgQXJkdVBpbG90IFNJVEwpJykKICAgIGFwLmFkZF9hcmd1bWVudCgnLS1yZWVudmlhcicsIHR5cGU9aW50LCBkZWZhdWx0PTAsIGhlbHA9J2NvcGlhciBsYSB0ZWxlbWV0csOtYSByZWFsIGEgMTI3LjAuMC4xOlBVRVJUTycpCiAgICBhcC5hZGRfYXJndW1lbnQoJy0tYXJkdXBpbG90JywgZGVmYXVsdD1Ob25lLCBoZWxwPSdjYXJwZXRhIGRlIEFyZHVQaWxvdCAocG9yIGRlZmVjdG8gfi9hcmR1cGlsb3QpJykKICAgIGFwLmFkZF9hcmd1bWVudCgnLS1odHRwJywgdHlwZT1pbnQsIGRlZmF1bHQ9MTQ1ODApCiAgICBhcC5hZGRfYXJndW1lbnQoJy0td3MnLCB0eXBlPWludCwgZGVmYXVsdD0xNDU5MCkKICAgIGFwLmFkZF9hcmd1bWVudCgnLS1lc3AnLCBkZWZhdWx0PU5vbmUsIGhlbHA9J1dpRmkgZGVsIGF2acOzbiwgSE9TVFs6UFVFUlRPXSAocG9yIGRlZmVjdG8gQ29yZVdpbmcgMTkyLjE2OC4xLjE6NDI3OCB5IERyb25lQnJpZGdlIDo1NzYwKScpCiAgICBvID0gYXAucGFyc2VfYXJncygpCiAgICBjZmdbJ2FyZHVwaWxvdCddLCBjZmdbJ3JlZW52aWFyJ10gPSBvLmFyZHVwaWxvdCwgby5yZWVudmlhcgogICAgaWYgby5lc3A6CiAgICAgICAgaCwgXywgcHQgPSBvLmVzcC5wYXJ0aXRpb24oJzonKQogICAgICAgIGNmZ1snZXNwJ10gPSBbKGgsIGludChwdCkpXSBpZiBwdCBlbHNlIFsoaCwgNDI3OCksIChoLCA1NzYwKV0KICAgIHByaW50KGYnXG4gIEFJUkxBQiBDb25lY3RvciB7VkVSU0lPTn1cbiAg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4nCiAgICAgICAgICAnICBEw6lqYWxvIGFiaWVydG8gbWllbnRyYXMgdnVlbGFzLiBFbiBlbCBzaW11bGFkb3I6IE9wY2lvbmVzIOKAuiBDb25leGlvbmVzLlxuJwogICAgICAgICAgJyAgUGFyYSBjZXJyYXJsbzogQ3RybCtDIG8gY2llcnJhIGVzdGEgdmVudGFuYS5cbicsIGZsdXNoPVRydWUpCiAgICB0cnk6CiAgICAgICAgc3J2ID0gVGhyZWFkaW5nSFRUUFNlcnZlcigoJzEyNy4wLjAuMScsIG8uaHR0cCksIE1hbmVqYWRvcikKICAgICAgICBzcnYuZGFlbW9uX3RocmVhZHMgPSBUcnVlCiAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICBwcmludChmJyoqKiBFbCBwdWVydG8ge28uaHR0cH0geWEgZXN0w6EgZW4gdXNvOiDCv3RpZW5lcyBvdHJvIGNvbmVjdG9yIChvIGVsIHB1ZW50ZSBhbnRpZ3VvKSBhYmllcnRvPyBDacOpcnJhbG8uJykKICAgICAgICBpbnB1dCgnUHVsc2EgSW50cm8gcGFyYSBzYWxpci4nKQogICAgICAgIHJldHVybgogICAgdGhyZWFkaW5nLlRocmVhZCh0YXJnZXQ9cmVhbF91ZHAsIGFyZ3M9KDE0NTUwLCBvLnJlZW52aWFyKSwgZGFlbW9uPVRydWUpLnN0YXJ0KCkKICAgIHVkcCA9IHNvY2tldC5zb2NrZXQoc29ja2V0LkFGX0lORVQsIHNvY2tldC5TT0NLX0RHUkFNKQogICAgdHJ5OgogICAgICAgIHVkcC5iaW5kKCgnMC4wLjAuMCcsIDkwMDIpKQogICAgICAgIHRocmVhZGluZy5UaHJlYWQodGFyZ2V0PXNpdGxfdWRwLCBhcmdzPSh1ZHAsKSwgZGFlbW9uPVRydWUpLnN0YXJ0KCkKICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgIHNpdGxbJ29jdXBhZG8nXSA9IFRydWUKICAgICAgICBsb2coJ1NJVEw6IGVsIHB1ZXJ0byBVRFAgOTAwMiBlc3TDoSBvY3VwYWRvOiBjaWVycmEgZWwgcHVlbnRlIGFudGlndW8gKGFpcmxhYi1zaXRsLnB5KSBvIGVsIG90cm8gY29uZWN0b3IgeSB2dWVsdmUgYSBhYnJpciBlc3RlLicpCiAgICBtYXYgPSBzb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19ER1JBTSkKICAgIHRyeToKICAgICAgICBtYXYuYmluZCgoJzEyNy4wLjAuMScsIDE0NTUxKSkKICAgICAgICBzaXRsWydtYXZfc29jayddID0gbWF2CiAgICAgICAgdGhyZWFkaW5nLlRocmVhZCh0YXJnZXQ9c2l0bF9tYXYsIGFyZ3M9KG1hdiwpLCBkYWVtb249VHJ1ZSkuc3RhcnQoKQogICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgcGFzcwogICAgd3MgPSBzb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19TVFJFQU0pCiAgICB3cy5zZXRzb2Nrb3B0KHNvY2tldC5TT0xfU09DS0VULCBzb2NrZXQuU09fUkVVU0VBRERSLCAxKQogICAgdHJ5OgogICAgICAgIHdzLmJpbmQoKCcxMjcuMC4wLjEnLCBvLndzKSkKICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgIHByaW50KGYnXG4qKiogRWwgcHVlcnRvIHtvLndzfSB5YSBlc3TDoSBlbiB1c286IGhheSBhYmllcnRvIHVuIHB1ZW50ZSBhbnRpZ3VvIChhaXJsYWItc2l0bC5weSkgdSBvdHJvIGNvbmVjdG9yLicpCiAgICAgICAgcHJpbnQoJyoqKiBDaWVycmEgZXNhcyB2ZW50YW5hcyBkZWwgVGVybWluYWwgKEN0cmwrQyBlbiBjYWRhIHVuYSwgbyBjacOpcnJhbGFzKSB5IHZ1ZWx2ZSBhIGFicmlyIEFJUkxBQiBDb25lY3Rvci5cbicpCiAgICAgICAgaW5wdXQoJ1B1bHNhIEludHJvIHBhcmEgc2FsaXIuJykKICAgICAgICByZXR1cm4KICAgIHdzLmxpc3Rlbig0KQoKICAgIGRlZiBhY2VwdGFyKCk6CiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgYywgXyA9IHdzLmFjY2VwdCgpCiAgICAgICAgICAgIHRocmVhZGluZy5UaHJlYWQodGFyZ2V0PXdzX2NsaWVudGUsIGFyZ3M9KGMsIHVkcCksIGRhZW1vbj1UcnVlKS5zdGFydCgpCiAgICB0aHJlYWRpbmcuVGhyZWFkKHRhcmdldD1hY2VwdGFyLCBkYWVtb249VHJ1ZSkuc3RhcnQoKQogICAgdGhyZWFkaW5nLlRocmVhZCh0YXJnZXQ9cmVzdW1lbiwgZGFlbW9uPVRydWUpLnN0YXJ0KCkKICAgIHRocmVhZGluZy5UaHJlYWQodGFyZ2V0PWVzcF92aWdpYSwgZGFlbW9uPVRydWUpLnN0YXJ0KCkKICAgIGIgPSBhcmR1cGlsb3RfYmluKCkKICAgIGxvZygnVnVlbG8gcmVhbDogZXNjdWNoYW5kbyBsYSB0ZWxlbWV0csOtYSBkZWwgQmFja3BhY2sgKFVEUCAxNDU1MCknIGlmIG5vdCByZWFsWydvY3VwYWRvJ10gZWxzZSAnVnVlbG8gcmVhbDogbm8gZGlzcG9uaWJsZSAocHVlcnRvIG9jdXBhZG8pJykKICAgIGxvZygnQXJkdVBpbG90IFNJVEw6ICcgKyAoZidlbmNvbnRyYWRvICh7Yn0pJyBpZiBiIGVsc2UgJ25vIGNvbXBpbGFkbyB0b2RhdsOtYSAob3BjaW9uYWw7IHZlciBPcGNpb25lcyDigLogQ29uZXhpb25lcyknKSkKICAgIGxvZyhmJ0xvZ3MgZGVsIGF2acOzbjogYnVzY2FuZG8gc3UgV2lGaSAoeyIsICIuam9pbihmIntofTp7cHR9IiBmb3IgaCwgcHQgaW4gY2ZnWyJlc3AiXSl9KTsgbG9zIGxvZ3MgbnVldm9zIHNlIGd1YXJkYW4gZW4ge0xPR1NfRElSfScpCiAgICAjIGNlcnJhciBsYSB2ZW50YW5hIGRlbCBUZXJtaW5hbCAoU0lHSFVQKSBvIHVuIMKra2lsbMK7IChTSUdURVJNKSB0YW1iacOpbiBwYXJhbiBlbCBBcmR1UGlsb3QgcXVlIGhheWEgbGFuemFkbyBlbCBjb25lY3RvcgogICAgaW1wb3J0IHNpZ25hbAoKICAgIGRlZiBfc2FsaXIoKl8pOgogICAgICAgIHJhaXNlIEtleWJvYXJkSW50ZXJydXB0CiAgICBmb3Igc2cgaW4gKHNpZ25hbC5TSUdURVJNLCBnZXRhdHRyKHNpZ25hbCwgJ1NJR0hVUCcsIE5vbmUpKToKICAgICAgICBpZiBzZzoKICAgICAgICAgICAgc2lnbmFsLnNpZ25hbChzZywgX3NhbGlyKQogICAgdHJ5OgogICAgICAgIHNydi5zZXJ2ZV9mb3JldmVyKCkKICAgIGV4Y2VwdCBLZXlib2FyZEludGVycnVwdDoKICAgICAgICBwYXNzCiAgICBmaW5hbGx5OgogICAgICAgIHNpdGxfcGFyYXIoKQogICAgICAgIHByaW50KCdcbkNvbmVjdG9yIGNlcnJhZG8uJykKCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgbWFpbigpCg==',
    'stallion-sitl.parm': 'IyBCYXNlOiBUb29scy9hdXRvdGVzdC9tb2RlbHMvcGxhbmUucGFybSBkZSBBcmR1UGlsb3QKRUsyX0VOQUJMRSAgICAgIDEKQkFUVF9NT05JVE9SICAgIDQKUFRDSF9UUklNX0RFRyAwLjAwCkxBTkRfUElUQ0hfREVHIDEuMDAKTEFORF9GTEFSRV9TRUMgIDMKTEFORF9ESVNBUk1ERUxBWSAzCkFSU1BEX1VTRSAgICAgICAxCktGRl9SRERSTUlYICAgICAwLjUKVEhSX01BWAkJMTAwClJDMV9NQVggICAgICAgICAyMDAwClJDMV9NSU4gICAgICAgICAxMDAwClJDMV9UUklNICAgICAgICAxNTAwClJDMl9NQVggICAgICAgICAyMDAwClJDMl9NSU4gICAgICAgICAxMDAwClJDMl9UUklNICAgICAgICAxNTAwClJDM19NQVggICAgICAgICAyMDAwClJDM19NSU4gICAgICAgICAxMDAwClNFUlZPM19NSU4gICAgICAxMDAwClNFUlZPM19NQVggICAgICAyMDAwClJDM19UUklNICAgICAgICAxMDAwClJDNF9NQVggICAgICAgICAyMDAwClJDNF9NSU4gICAgICAgICAxMDAwClJDNF9UUklNICAgICAgICAxNTAwClJDNV9NQVggICAgICAgICAyMDAwClJDNV9NSU4gICAgICAgICAxMDAwClJDNV9UUklNICAgICAgICAxNTAwClJDNl9NQVggICAgICAgICAyMDAwClJDNl9NSU4gICAgICAgICAxMDAwClJDNl9UUklNICAgICAgICAxNTAwClJDN19NQVggICAgICAgICAyMDAwClJDN19NSU4gICAgICAgICAxMDAwClJDN19UUklNICAgICAgICAxNTAwClJDOF9NQVggICAgICAgICAyMDAwClJDOF9NSU4gICAgICAgICAxMDAwClJDOF9UUklNICAgICAgICAxNTAwCldQX0xPSVRFUl9SQUQgICA4MApXUF9SQURJVVMgICAgICAgNTAKUkxMMlNSVl9STUFYICAgICA5MApSTEwyU1JWX1RDT05TVCAgIDAuMjUwMDAwClJMTF9SQVRFX0QgICAgICAgMC4wMTc0MzAKUkxMX1JBVEVfRkYgICAgICAwLjIzNzIxMgpSTExfUkFURV9JICAgICAgIDAuMjUKUkxMX1JBVEVfUCAgICAgICAwLjMKUFRDSDJTUlZfUk1BWF9ETiA5MApQVENIMlNSVl9STUFYX1VQIDkwClBUQ0gyU1JWX1RDT05TVCAgMC4yNQpQVENIX1JBVEVfRCAgICAgIDAuMDA3MjY1ClBUQ0hfUkFURV9GRiAgICAgMC41OTU3MjMKUFRDSF9SQVRFX0kgICAgICAwLjExClBUQ0hfUkFURV9QICAgICAgMC4xNQpQVENIMlNSVl9STEwgICAgIDEKTkFWTDFfUEVSSU9EICAgICAxNQpBQ1JPX0xPQ0tJTkcgICAgIDEKSU5TX0FDQ09GRlNfWCAgIDAuMDAxCklOU19BQ0NPRkZTX1kgICAwLjAwMQpJTlNfQUNDT0ZGU19aICAgMC4wMDEKSU5TX0FDQ1NDQUxfWCAgIDEuMDAxCklOU19BQ0NTQ0FMX1kgICAxLjAwMQpJTlNfQUNDU0NBTF9aICAgMS4wMDEKSU5TX0FDQzJPRkZTX1ggICAwLjAwMQpJTlNfQUNDMk9GRlNfWSAgIDAuMDAxCklOU19BQ0MyT0ZGU19aICAgMC4wMDEKSU5TX0FDQzJTQ0FMX1ggICAxLjAwMQpJTlNfQUNDMlNDQUxfWSAgIDEuMDAxCklOU19BQ0MyU0NBTF9aICAgMS4wMDEKSU5TX0dZUl9DQUwgICAgICAwCiMgLS0tIEFJUkxBQiBGUFYgwrcgU3RhbGxpb24gYWxhIGZpamEgKGJpbW90b3IsIHNpbiBWVE9MKSBlbiBTSVRMIGNvbiBsYSBmw61zaWNhIGRlbCBzaW11bGFkb3IgLS0tCiMgU2FsaWRhczogMSBhbGVyw7NuIMK3IDIgcHJvZnVuZGlkYWQgwrcgMyBnYXMgwrcgNCB0aW3Ds24gKGVsIHNpbXVsYWRvciBtZXpjbGEgbGEgY29sYSBlbiBWIHBvciBzdSBjdWVudGEpClNFUlZPMV9GVU5DVElPTiA0ClNFUlZPMl9GVU5DVElPTiAxOQpTRVJWTzNfRlVOQ1RJT04gNzAKU0VSVk80X0ZVTkNUSU9OIDIxClNFUlZPMV9NSU4gMTEwMApTRVJWTzFfTUFYIDE5MDAKU0VSVk8yX01JTiAxMTAwClNFUlZPMl9NQVggMTkwMApTRVJWTzRfTUlOIDExMDAKU0VSVk80X01BWCAxOTAwCiMgTW9kb3MgZW4gZWwgY2FuYWwgOCAobG9zIGJvdG9uZXMgZGVsIHBhbmVsKTogTUFOVUFMIMK3IEZCV0EgwrcgQ1JVSVNFIMK3IEFVVE8gwrcgUlRMIMK3IExPSVRFUgpGTFRNT0RFX0NIIDgKRkxUTU9ERTEgMApGTFRNT0RFMiA1CkZMVE1PREUzIDcKRkxUTU9ERTQgMTAKRkxUTU9ERTUgMTEKRkxUTU9ERTYgMTIKIyBBcm1hZG8gY29uIGludGVycnVwdG9yIGVuIGVsIGNhbmFsIDcKUkM3X09QVElPTiAxNTMKIyBWZWxvY2lkYWRlcyBkZWwgU3RhbGxpb24gKGFqw7pzdGFsYXMgYSB0dSBhdmnDs24pCkFJUlNQRUVEX01JTiAxMwpBSVJTUEVFRF9DUlVJU0UgMTgKQUlSU1BFRURfTUFYIDI4ClRSSU1fVEhST1RUTEUgNDUKUk9MTF9MSU1JVF9ERUcgNTAKUFRDSF9MSU1fTUFYX0RFRyAyMApQVENIX0xJTV9NSU5fREVHIC0yMAojIExhbnphbWllbnRvIGEgbWFubzogVEFLRU9GRiBhcnJhbmNhIGVsIG1vdG9yIGFsIGRldGVjdGFyIGVsIGxhbnphbWllbnRvClRLT0ZGX1RIUl9NSU5BQ0MgMTUKVEtPRkZfVEhSX0RFTEFZIDIKVEtPRkZfVEhSX01JTlNQRCA0ClRLT0ZGX0FMVCA0MAojIFJpdG1vIGRlIGxhIGbDrXNpY2E6IDIwMCBwYXNvcyBwb3Igc2VndW5kbyAoZWwgYnVjbGUgZGUgQXJkdVBsYW5lIHZhIGEgNTAgSHopClNJTV9SQVRFX0haIDIwMApMT0dfQklUTUFTSyA2NTUzNQojIEdQUyBzaW11bGFkbyBkZSBTSVRMICg0LjYrOiBHUFMxX1RZUEU7IGVsIEdQUyBkZSBsYSBwbGFjYSBkZSB0dSAucGFyYW0gc2UgcXVpdGEgYWwgY2FyZ2FybG8pCkdQUzFfVFlQRSAxCg==',
    'stallion-vtol-sitl.parm': 'IyBCYXNlOiBUb29scy9hdXRvdGVzdC9tb2RlbHMvcGxhbmUucGFybSBkZSBBcmR1UGlsb3QKRUsyX0VOQUJMRSAgICAgIDEKQkFUVF9NT05JVE9SICAgIDQKUFRDSF9UUklNX0RFRyAwLjAwCkxBTkRfUElUQ0hfREVHIDEuMDAKTEFORF9GTEFSRV9TRUMgIDMKTEFORF9ESVNBUk1ERUxBWSAzCkFSU1BEX1VTRSAgICAgICAxCktGRl9SRERSTUlYICAgICAwLjUKVEhSX01BWAkJMTAwClJDMV9NQVggICAgICAgICAyMDAwClJDMV9NSU4gICAgICAgICAxMDAwClJDMV9UUklNICAgICAgICAxNTAwClJDMl9NQVggICAgICAgICAyMDAwClJDMl9NSU4gICAgICAgICAxMDAwClJDMl9UUklNICAgICAgICAxNTAwClJDM19NQVggICAgICAgICAyMDAwClJDM19NSU4gICAgICAgICAxMDAwClJDM19UUklNICAgICAgICAxMDAwClJDNF9NQVggICAgICAgICAyMDAwClJDNF9NSU4gICAgICAgICAxMDAwClJDNF9UUklNICAgICAgICAxNTAwClJDNV9NQVggICAgICAgICAyMDAwClJDNV9NSU4gICAgICAgICAxMDAwClJDNV9UUklNICAgICAgICAxNTAwClJDNl9NQVggICAgICAgICAyMDAwClJDNl9NSU4gICAgICAgICAxMDAwClJDNl9UUklNICAgICAgICAxNTAwClJDN19NQVggICAgICAgICAyMDAwClJDN19NSU4gICAgICAgICAxMDAwClJDN19UUklNICAgICAgICAxNTAwClJDOF9NQVggICAgICAgICAyMDAwClJDOF9NSU4gICAgICAgICAxMDAwClJDOF9UUklNICAgICAgICAxNTAwCldQX0xPSVRFUl9SQUQgICA4MApXUF9SQURJVVMgICAgICAgNTAKUkxMMlNSVl9STUFYICAgICA5MApSTEwyU1JWX1RDT05TVCAgIDAuMjUwMDAwClJMTF9SQVRFX0QgICAgICAgMC4wMTc0MzAKUkxMX1JBVEVfRkYgICAgICAwLjIzNzIxMgpSTExfUkFURV9JICAgICAgIDAuMjUKUkxMX1JBVEVfUCAgICAgICAwLjMKUFRDSDJTUlZfUk1BWF9ETiA5MApQVENIMlNSVl9STUFYX1VQIDkwClBUQ0gyU1JWX1RDT05TVCAgMC4yNQpQVENIX1JBVEVfRCAgICAgIDAuMDA3MjY1ClBUQ0hfUkFURV9GRiAgICAgMC41OTU3MjMKUFRDSF9SQVRFX0kgICAgICAwLjExClBUQ0hfUkFURV9QICAgICAgMC4xNQpQVENIMlNSVl9STEwgICAgIDEKTkFWTDFfUEVSSU9EICAgICAxNQpBQ1JPX0xPQ0tJTkcgICAgIDEKSU5TX0FDQ09GRlNfWCAgIDAuMDAxCklOU19BQ0NPRkZTX1kgICAwLjAwMQpJTlNfQUNDT0ZGU19aICAgMC4wMDEKSU5TX0FDQ1NDQUxfWCAgIDEuMDAxCklOU19BQ0NTQ0FMX1kgICAxLjAwMQpJTlNfQUNDU0NBTF9aICAgMS4wMDEKSU5TX0FDQzJPRkZTX1ggICAwLjAwMQpJTlNfQUNDMk9GRlNfWSAgIDAuMDAxCklOU19BQ0MyT0ZGU19aICAgMC4wMDEKSU5TX0FDQzJTQ0FMX1ggICAxLjAwMQpJTlNfQUNDMlNDQUxfWSAgIDEuMDAxCklOU19BQ0MyU0NBTF9aICAgMS4wMDEKSU5TX0dZUl9DQUwgICAgICAwCiMgLS0tIEFJUkxBQiBGUFYgwrcgU3RhbGxpb24gVlRPTCB0aWx0LXJvdG9yIChRdWFkUGxhbmUgdHJpY8OzcHRlcm8sIHZlY3RvcmVkIHlhdykgZW4gU0lUTCBjb24gbGEgZsOtc2ljYSBkZWwgc2ltdWxhZG9yIC0tLQojIFBhcsOhbWV0cm9zIGRlbCBtYW51YWwgRmxpZ2h0b3J5IFN0YWxsaW9uIFZUT0wgVjIgKHDDoWdzLiAyMC0yMikgeSBkZSBxdWFkcGxhbmUtdGlsdHRyaXZlYy5wYXJtIGRlIEFyZHVQaWxvdC4KUV9FTkFCTEUgICAgICAgICAxClFfRlJBTUVfQ0xBU1MgICAgNwpRX1RJTFRfRU5BQkxFICAgIDEKUV9USUxUX01BU0sgICAgICAzClFfVElMVF9UWVBFICAgICAgMgpRX1RJTFRfWUFXX0FOR0xFIDE1ClFfVElMVF9NQVggICAgICAgNDUKUV9USUxUX1JBVEVfVVAgICAxNQpRX0FTU0lTVF9TUEVFRCAgIC0xClFfT1BUSU9OUyAgICAgICAgMTYzODQxClFfVFJBTlNJVElPTl9NUyAgNzAwMApRX0xBTkRfRklOQUxfU1BEIDAuMwojIFNhbGlkYXMgKGxhcyBkZSB0dSBhdmnDs24pOiAxLTIgYWxlcm9uZXMgwrcgMy00IGNvbGEgZW4gViDCtyA1IG1vdG9yIDEgKGRlbGFudGVybyBkY2hvLikgwrcgNiBtb3RvciAyIChkZWxhbnRlcm8gaXpxLikKIyA3IG1vdG9yIDQgKHRyYXNlcm8pIMK3IDggdGlsdCBpenF1aWVyZG8gwrcgOSB0aWx0IGRlcmVjaG8KU0VSVk8xX0ZVTkNUSU9OICA0ClNFUlZPMl9GVU5DVElPTiAgNApTRVJWTzNfRlVOQ1RJT04gIDc5ClNFUlZPNF9GVU5DVElPTiAgODAKU0VSVk81X0ZVTkNUSU9OICAzMwpTRVJWTzZfRlVOQ1RJT04gIDM0ClNFUlZPN19GVU5DVElPTiAgMzYKU0VSVk84X0ZVTkNUSU9OICA3NQpTRVJWTzlfRlVOQ1RJT04gIDc2ClNFUlZPMV9NSU4gMTEwMApTRVJWTzFfTUFYIDE5MDAKU0VSVk8yX01JTiAxMTAwClNFUlZPMl9NQVggMTkwMApTRVJWTzNfTUlOIDExMDAKU0VSVk8zX01BWCAxOTAwClNFUlZPNF9NSU4gMTEwMApTRVJWTzRfTUFYIDE5MDAKU0VSVk84X01JTiAxMDAwClNFUlZPOF9NQVggMjAwMApTRVJWTzlfTUlOIDEwMDAKU0VSVk85X01BWCAyMDAwCiMgRW4gU0lUTCBsb3MgbW90b3JlcyB2YW4gcG9yIFBXTSBub3JtYWwgKGVuIGVsIGF2acOzbiByZWFsLCBEU2hvdDogUV9NX1BXTV9UWVBFIDcpClFfTV9QV01fVFlQRSAgICAgMApRX01fUFdNX01JTiAgICAgIDEwMDAKUV9NX1BXTV9NQVggICAgICAyMDAwClFfTV9USFNUX0VYUE8gICAgMC42NQpRX01fU1BJTl9NSU4gICAgIDAuMTUKUV9NX1NQSU5fTUFYICAgICAwLjk1ClFfTV9USFNUX0hPVkVSICAgMC40NQpRX01fQkFUX1ZPTFRfTUFYIDI1LjIKUV9NX0JBVF9WT0xUX01JTiAxOS44CiMgQWp1c3RlIGRlIHBhcnRpZGEgZGUgbG9zIFBJRCBkZSBWVE9MIChxdWFkcGxhbmUtdGlsdHRyaXZlYy5wYXJtIGRlIEFyZHVQaWxvdCkKUV9BX1JBVF9STExfUCAgICAwLjEyNgpRX0FfUkFUX1JMTF9JICAgIDAuMTI2ClFfQV9SQVRfUkxMX0QgICAgMC4wMDMKUV9BX1JBVF9STExfRkxUVCAxMApRX0FfUkFUX1BJVF9QICAgIDAuMTIKUV9BX1JBVF9QSVRfSSAgICAwLjEyClFfQV9SQVRfUElUX0QgICAgMC4wMDI1ClFfQV9SQVRfUElUX0ZMVFQgMTAKUV9BX1JBVF9ZQVdfUCAgICAwLjUKUV9BX1JBVF9ZQVdfSSAgICAwLjA1ClFfQV9SQVRfWUFXX0QgICAgMC4wMQpRX0FfUkFUX1lBV19GTFRUIDEwClFfQV9SQVRfWUFXX0ZMVEUgMApRX0FfUkFUX1lBV19GTFREIDEwCiMgTW9kb3MgZW4gZWwgY2FuYWwgOCAobG9zIGJvdG9uZXMgZGVsIHBhbmVsKTogUVNUQUJJTElaRSDCtyBRSE9WRVIgwrcgUUxPSVRFUiDCtyBGQldBIMK3IFFSVEwgwrcgUUxBTkQKRkxUTU9ERV9DSCA4CkZMVE1PREUxIDE3CkZMVE1PREUyIDE4CkZMVE1PREUzIDE5CkZMVE1PREU0IDUKRkxUTU9ERTUgMjEKRkxUTU9ERTYgMjAKIyBBcm1hZG8gY29uIGludGVycnVwdG9yIGVuIGVsIGNhbmFsIDcgKG5vIGNvbiBlbCB0aW3Ds24pClJDN19PUFRJT04gMTUzCkFSTUlOR19SVURERVIgMAojIFZlbG9jaWRhZGVzIChsYXMgcXVlIHZhcyBhIGNhcmdhciBlbiB0dSBTdGFsbGlvbiBwb3Igc3UgcGVzbzsgZWwgbWFudWFsIGRhIDEyIC8gMjUpCkFJUlNQRUVEX01JTiAxNgpBSVJTUEVFRF9DUlVJU0UgMTkKQUlSU1BFRURfTUFYIDI1ClRSSU1fVEhST1RUTEUgNDUKUk9MTF9MSU1JVF9ERUcgNDUKUFRDSF9MSU1fTUFYX0RFRyAyMApQVENIX0xJTV9NSU5fREVHIC0yMApRX1JUTF9BTFQgMjAKUlRMX0FMVElUVURFIDYwCiMgUml0bW86IGJ1Y2xlIGRlIEFyZHVQbGFuZSBhIDIwMCBIeiB5IGbDrXNpY2EgYSA0MDAgcGFzb3MgcG9yIHNlZ3VuZG8gKGxhIElNVSBkZWJlIGlyIGEgMSw4IHZlY2VzIGVsIGJ1Y2xlIG8gbcOhcykKU0NIRURfTE9PUF9SQVRFIDIwMApTSU1fUkFURV9IWiA0MDAKTE9HX0JJVE1BU0sgNjU1MzUKIyBHUFMgc2ltdWxhZG8gZGUgU0lUTCAoNC42KzogR1BTMV9UWVBFOyBlbCBHUFMgZGUgbGEgcGxhY2EgZGUgdHUgLnBhcmFtIHNlIHF1aXRhIGFsIGNhcmdhcmxvKQpHUFMxX1RZUEUgMQo=',
    'compilar-ardupilot.sh': 'IyEvYmluL2Jhc2gKIyBBSVJMQUIgRlBWIMK3IGNvbXBpbGEgQXJkdVBsYW5lIFNJVEwgZW4gZWwgTWFjICh1bmEgc29sYSB2ZXosIDIwLTQwIG1pbikuIFNvbG8gaGFjZSBmYWx0YSBwYXJhIMKrQXJkdVBpbG90IHJlYWwgKFNJVEwpwrsuCiMgVXNvOiBiYXNoIH4vQUlSTEFCL2NvbXBpbGFyLWFyZHVwaWxvdC5zaApzZXQgLWUKQVA9IiR7QVJEVVBJTE9UOi0kSE9NRS9hcmR1cGlsb3R9IgplY2hvOyBlY2hvICIgIEFJUkxBQiDCtyBjb21waWxhciBBcmR1UGlsb3QgU0lUTCBlbiAkQVAiOyBlY2hvCmlmICEgeGNvZGUtc2VsZWN0IC1wID4vZGV2L251bGwgMj4mMTsgdGhlbgogIGVjaG8gIjEvNCBGYWx0YW4gbGFzIGhlcnJhbWllbnRhcyBkZSBBcHBsZS4gU2UgYWJyaXLDoSB1bmEgdmVudGFuYTogcHVsc2EgSW5zdGFsYXIgeSwgYWwgdGVybWluYXIsIHZ1ZWx2ZSBhIGVqZWN1dGFyIGVzdGUgc2NyaXB0LiIKICB4Y29kZS1zZWxlY3QgLS1pbnN0YWxsIHx8IHRydWU7IGV4aXQgMQpmaQplY2hvICIxLzQgSGVycmFtaWVudGFzIGRlIEFwcGxlOiBPSyIKaWYgISBjb21tYW5kIC12IGJyZXcgPi9kZXYvbnVsbCAyPiYxOyB0aGVuCiAgZWNobyAiMi80IEZhbHRhIEhvbWVicmV3LiBJbnN0w6FsYWxvIGNvbiBlbCBjb21hbmRvIGRlIGh0dHBzOi8vYnJldy5zaCB5IHZ1ZWx2ZSBhIGVqZWN1dGFyIGVzdGUgc2NyaXB0LiI7IGV4aXQgMQpmaQplY2hvICIyLzQgSG9tZWJyZXc6IE9LIgppZiBbICEgLWQgIiRBUC8uZ2l0IiBdOyB0aGVuCiAgZWNobyAiMy80IERlc2NhcmdhbmRvIEFyZHVQaWxvdCAoMSw1IEdCKeKApiIKICBnaXQgY2xvbmUgLS1yZWN1cnNlLXN1Ym1vZHVsZXMgaHR0cHM6Ly9naXRodWIuY29tL0FyZHVQaWxvdC9hcmR1cGlsb3QuZ2l0ICIkQVAiCiAgZWNobyAiICAgIEluc3RhbGFuZG8gc3VzIGRlcGVuZGVuY2lhcy4gUmVzcHVlc3RhczogUHl0aG9uIGNvbiBweWVudiDihpIgeSDCtyBTVE0zMiB0b29sY2hhaW4g4oaSIG4gwrcgZWwgcmVzdG8g4oaSIHkiCiAgKGNkICIkQVAiICYmIFRvb2xzL2Vudmlyb25tZW50X2luc3RhbGwvaW5zdGFsbC1wcmVyZXFzLW1hYy5zaCkKICBlY2hvOyBlY2hvICIgICAgRGVwZW5kZW5jaWFzIGluc3RhbGFkYXMuIENJRVJSQSBlbCBUZXJtaW5hbCAoQ21kK1EpLCDDoWJyZWxvIHkgdnVlbHZlIGEgZWplY3V0YXI6ICBiYXNoIH4vQUlSTEFCL2NvbXBpbGFyLWFyZHVwaWxvdC5zaCI7IGV4aXQgMApmaQplY2hvICIzLzQgQXJkdVBpbG90IGRlc2NhcmdhZG86IE9LIgplY2hvICI0LzQgQ29tcGlsYW5kbyBBcmR1UGxhbmUgcGFyYSBzaW11bGFjacOzbuKApiIKY2QgIiRBUCIgJiYgLi93YWYgY29uZmlndXJlIC0tYm9hcmQgc2l0bCAmJiAuL3dhZiBwbGFuZQplY2hvOyBlY2hvICIgIExpc3RvLiBBYnJlIMKrQUlSTEFCIENvbmVjdG9ywrsgeSwgZW4gZWwgc2ltdWxhZG9yLCBPcGNpb25lcyDigLogQ29uZXhpb25lcyDigLogQXJkdVBpbG90IHJlYWwuIgo=',
}
for n, b in F.items():
    p = os.path.join(d, n)
    open(p, 'wb').write(base64.b64decode(b))
    os.chmod(p, 0o755 if n.endswith(('.py', '.sh')) else 0o644)
print('  Archivos instalados en ' + d)
PY
LANZ="$DEST/AIRLAB Conector.command"
cat > "$LANZ" <<'CMD'
#!/bin/bash
# Doble clic: abre el conector de AIRLAB FPV (vuelo real y ArduPilot SITL). Déjalo abierto mientras vuelas.
cd "$HOME/AIRLAB" && exec python3 airlab-conector.py
CMD
chmod +x "$LANZ"
ESC="$HOME/Desktop"; [ -d "$ESC" ] || ESC="$DEST"
cp "$LANZ" "$ESC/AIRLAB Conector.command"; chmod +x "$ESC/AIRLAB Conector.command"
xattr -dr com.apple.quarantine "$DEST" "$ESC/AIRLAB Conector.command" 2>/dev/null || true
echo "  Acceso directo: «AIRLAB Conector» en el Escritorio"
if [ -x "${ARDUPILOT:-$HOME/ardupilot}/build/sitl/bin/arduplane" ]; then
  echo "  ArduPilot SITL: encontrado ✔"
else
  echo "  ArduPilot SITL: no compilado (solo hace falta para «ArduPilot real»): bash ~/AIRLAB/compilar-ardupilot.sh"
fi
echo; echo "  Listo. Abriendo el conector…"; echo
open "$ESC/AIRLAB Conector.command" 2>/dev/null || echo "  Ábrelo con doble clic en «AIRLAB Conector»."
