IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiIiIkdlbmVyYXRlIFB5dGhvbiBkb2N1bWVudGF0aW9uIGluIEhUTUwgb3IgdGV4dCBmb3IgaW50ZXJhY3RpdmUgdXNlLgoKSW4gdGhlIFB5dGhvbiBpbnRlcnByZXRlciwgZG8gImZyb20gcHlkb2MgaW1wb3J0IGhlbHAiIHRvIHByb3ZpZGUgb25saW5lCmhlbHAuICBDYWxsaW5nIGhlbHAodGhpbmcpIG9uIGEgUHl0aG9uIG9iamVjdCBkb2N1bWVudHMgdGhlIG9iamVjdC4KCkF0IHRoZSBzaGVsbCBjb21tYW5kIGxpbmUgb3V0c2lkZSBvZiBQeXRob246CiAgICBSdW4gInB5ZG9jIDxuYW1lPiIgdG8gc2hvdyBkb2N1bWVudGF0aW9uIG9uIHNvbWV0aGluZy4gIDxuYW1lPiBtYXkgYmUKICAgIHRoZSBuYW1lIG9mIGEgZnVuY3Rpb24sIG1vZHVsZSwgcGFja2FnZSwgb3IgYSBkb3R0ZWQgcmVmZXJlbmNlIHRvIGEKICAgIGNsYXNzIG9yIGZ1bmN0aW9uIHdpdGhpbiBhIG1vZHVsZSBvciBtb2R1bGUgaW4gYSBwYWNrYWdlLiAgSWYgdGhlCiAgICBhcmd1bWVudCBjb250YWlucyBhIHBhdGggc2VnbWVudCBkZWxpbWl0ZXIgKGUuZy4gc2xhc2ggb24gVW5peCwKICAgIGJhY2tzbGFzaCBvbiBXaW5kb3dzKSBpdCBpcyB0cmVhdGVkIGFzIHRoZSBwYXRoIHRvIGEgUHl0aG9uIHNvdXJjZSBmaWxlLgoKICAgIFJ1biAicHlkb2MgLWsgPGtleXdvcmQ+IiB0byBzZWFyY2ggZm9yIGEga2V5d29yZCBpbiB0aGUgc3lub3BzaXMgbGluZXMKICAgIG9mIGFsbCBhdmFpbGFibGUgbW9kdWxlcy4KCiAgICBSdW4gInB5ZG9jIC1wIDxwb3J0PiIgdG8gc3RhcnQgYW4gSFRUUCBzZXJ2ZXIgb24gYSBnaXZlbiBwb3J0IG9uIHRoZQogICAgbG9jYWwgbWFjaGluZSB0byBnZW5lcmF0ZSBkb2N1bWVudGF0aW9uIHdlYiBwYWdlcy4KCiAgICBGb3IgcGxhdGZvcm1zIHdpdGhvdXQgYSBjb21tYW5kIGxpbmUsICJweWRvYyAtZyIgc3RhcnRzIHRoZSBIVFRQIHNlcnZlcgogICAgYW5kIGFsc28gcG9wcyB1cCBhIGxpdHRsZSB3aW5kb3cgZm9yIGNvbnRyb2xsaW5nIGl0LgoKICAgIFJ1biAicHlkb2MgLXcgPG5hbWU+IiB0byB3cml0ZSBvdXQgdGhlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBtb2R1bGUKICAgIHRvIGEgZmlsZSBuYW1lZCAiPG5hbWU+Lmh0bWwiLgoiIiIKCl9fYXV0aG9yX18gPSAiS2EtUGluZyBZZWUgPHBpbmdAbGZ3Lm9yZz4iCl9fZGF0ZV9fID0gIjI2IEZlYnJ1YXJ5IDIwMDEiCl9fdmVyc2lvbl9fID0gIiRSZXZpc2lvbiQiCl9fY3JlZGl0c19fID0gIiIiR3VpZG8gdmFuIFJvc3N1bSwgZm9yIGFuIGV4Y2VsbGVudCBwcm9ncmFtbWluZyBsYW5ndWFnZS4KVG9tbXkgQnVybmV0dGUsIHRoZSBvcmlnaW5hbCBjcmVhdG9yIG9mIG1hbnB5LgpQYXVsIFByZXNjb2QsIGZvciBhbGwgaGlzIHdvcmsgb24gb25saW5laGVscC4KUmljaGFyZCBDaGFtYmVybGFpbiwgZm9yIHRoZSBmaXJzdCBpbXBsZW1lbnRhdGlvbiBvZiB0ZXh0ZG9jLgoKTXluZCB5b3UsIG34+HNlIGJpdGVzIEthbiBiZSBwcmV0dHkgbmFzdGkuLi4iIiIKCiMgTm90ZTogdGhpcyBtb2R1bGUgaXMgZGVzaWduZWQgdG8gZGVwbG95IGluc3RhbnRseSBhbmQgcnVuIHVuZGVyIGFueQojIHZlcnNpb24gb2YgUHl0aG9uIGZyb20gMS41IGFuZCB1cC4gIFRoYXQncyB3aHkgaXQncyBhIHNpbmdsZSBmaWxlIGFuZAojIHNvbWUgMi4wIGZlYXR1cmVzIChsaWtlIHN0cmluZyBtZXRob2RzKSBhcmUgY29uc3BpY3VvdXNseSBhdm9pZGVkLgoKaW1wb3J0IHN5cywgaW1wLCBvcywgc3RhdCwgcmUsIHR5cGVzLCBpbnNwZWN0CmZyb20gcmVwciBpbXBvcnQgUmVwcgpmcm9tIHN0cmluZyBpbXBvcnQgZXhwYW5kdGFicywgZmluZCwgam9pbiwgbG93ZXIsIHNwbGl0LCBzdHJpcCwgcnN0cmlwCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBjb21tb24gcm91dGluZXMKCmRlZiBzeW5vcHNpcyhmaWxlbmFtZSwgY2FjaGU9e30pOgogICAgIiIiR2V0IHRoZSBvbmUtbGluZSBzdW1tYXJ5IG91dCBvZiBhIG1vZHVsZSBmaWxlLiIiIgogICAgbXRpbWUgPSBvcy5zdGF0KGZpbGVuYW1lKVtzdGF0LlNUX01USU1FXQogICAgbGFzdHVwZGF0ZSwgcmVzdWx0ID0gY2FjaGUuZ2V0KGZpbGVuYW1lLCAoMCwgTm9uZSkpCiAgICBpZiBsYXN0dXBkYXRlIDwgbXRpbWU6CiAgICAgICAgZmlsZSA9IG9wZW4oZmlsZW5hbWUpCiAgICAgICAgbGluZSA9IGZpbGUucmVhZGxpbmUoKQogICAgICAgIHdoaWxlIGxpbmVbOjFdID09ICcjJyBvciBzdHJpcChsaW5lKSA9PSAnJzoKICAgICAgICAgICAgbGluZSA9IGZpbGUucmVhZGxpbmUoKQogICAgICAgICAgICBpZiBub3QgbGluZTogYnJlYWsKICAgICAgICBpZiBsaW5lWy0yOl0gPT0gJ1xcXG4nOgogICAgICAgICAgICBsaW5lID0gbGluZVs6LTJdICsgZmlsZS5yZWFkbGluZSgpCiAgICAgICAgbGluZSA9IHN0cmlwKGxpbmUpCiAgICAgICAgaWYgbGluZVs6M10gPT0gJyIiIic6CiAgICAgICAgICAgIGxpbmUgPSBsaW5lWzM6XQogICAgICAgICAgICB3aGlsZSBzdHJpcChsaW5lKSA9PSAnJzoKICAgICAgICAgICAgICAgIGxpbmUgPSBmaWxlLnJlYWRsaW5lKCkKICAgICAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgICAgICByZXN1bHQgPSBzcGxpdChsaW5lLCAnIiIiJylbMF0KICAgICAgICBlbHNlOiByZXN1bHQgPSBOb25lCiAgICAgICAgZmlsZS5jbG9zZSgpCiAgICAgICAgY2FjaGVbZmlsZW5hbWVdID0gKG10aW1lLCByZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0CgpkZWYgcGF0aGRpcnMoKToKICAgICIiIkNvbnZlcnQgc3lzLnBhdGggaW50byBhIGxpc3Qgb2YgYWJzb2x1dGUsIGV4aXN0aW5nLCB1bmlxdWUgcGF0aHMuIiIiCiAgICBkaXJzID0gW10KICAgIG5vcm1kaXJzID0gW10KICAgIGZvciBkaXIgaW4gc3lzLnBhdGg6CiAgICAgICAgZGlyID0gb3MucGF0aC5hYnNwYXRoKGRpciBvciAnLicpCiAgICAgICAgbm9ybWRpciA9IG9zLnBhdGgubm9ybWNhc2UoZGlyKQogICAgICAgIGlmIG5vcm1kaXIgbm90IGluIG5vcm1kaXJzIGFuZCBvcy5wYXRoLmlzZGlyKGRpcik6CiAgICAgICAgICAgIGRpcnMuYXBwZW5kKGRpcikKICAgICAgICAgICAgbm9ybWRpcnMuYXBwZW5kKG5vcm1kaXIpCiAgICByZXR1cm4gZGlycwoKZGVmIGdldGRvYyhvYmplY3QpOgogICAgIiIiR2V0IHRoZSBkb2Mgc3RyaW5nIG9yIGNvbW1lbnRzIGZvciBhbiBvYmplY3QuIiIiCiAgICByZXN1bHQgPSBpbnNwZWN0LmdldGRvYyhvYmplY3QpCiAgICBpZiBub3QgcmVzdWx0OgogICAgICAgIHRyeTogcmVzdWx0ID0gaW5zcGVjdC5nZXRjb21tZW50cyhvYmplY3QpCiAgICAgICAgZXhjZXB0OiBwYXNzCiAgICByZXR1cm4gcmVzdWx0IGFuZCByc3RyaXAocmVzdWx0KSBvciAnJwoKZGVmIGNsYXNzbmFtZShvYmplY3QsIG1vZG5hbWUpOgogICAgIiIiR2V0IGEgY2xhc3MgbmFtZSBhbmQgcXVhbGlmeSBpdCB3aXRoIGEgbW9kdWxlIG5hbWUgaWYgbmVjZXNzYXJ5LiIiIgogICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgaWYgb2JqZWN0Ll9fbW9kdWxlX18gIT0gbW9kbmFtZToKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbW9kdWxlX18gKyAnLicgKyBuYW1lCiAgICByZXR1cm4gbmFtZQoKZGVmIGlzY29uc3RhbnQob2JqZWN0KToKICAgICIiIkNoZWNrIGlmIGFuIG9iamVjdCBpcyBvZiBhIHR5cGUgdGhhdCBwcm9iYWJseSBtZWFucyBpdCdzIGEgY29uc3RhbnQuIiIiCiAgICByZXR1cm4gdHlwZShvYmplY3QpIGluIFsKICAgICAgICB0eXBlcy5GbG9hdFR5cGUsIHR5cGVzLkludFR5cGUsIHR5cGVzLkxpc3RUeXBlLCB0eXBlcy5Mb25nVHlwZSwKICAgICAgICB0eXBlcy5TdHJpbmdUeXBlLCB0eXBlcy5UdXBsZVR5cGUsIHR5cGVzLlR5cGVUeXBlLAogICAgICAgIGhhc2F0dHIodHlwZXMsICdVbmljb2RlVHlwZScpIGFuZCB0eXBlcy5Vbmljb2RlVHlwZSBvciAwXQoKZGVmIHJlcGxhY2UodGV4dCwgKnBhaXJzKToKICAgICIiIkRvIGEgc2VyaWVzIG9mIGdsb2JhbCByZXBsYWNlbWVudHMgb24gYSBzdHJpbmcuIiIiCiAgICBmb3Igb2xkLCBuZXcgaW4gcGFpcnM6CiAgICAgICAgdGV4dCA9IGpvaW4oc3BsaXQodGV4dCwgb2xkKSwgbmV3KQogICAgcmV0dXJuIHRleHQKCmRlZiBjcmFtKHRleHQsIG1heGxlbik6CiAgICAiIiJPbWl0IHBhcnQgb2YgYSBzdHJpbmcgaWYgbmVlZGVkIHRvIG1ha2UgaXQgZml0IGluIGEgbWF4aW11bSBsZW5ndGguIiIiCiAgICBpZiBsZW4odGV4dCkgPiBtYXhsZW46CiAgICAgICAgcHJlID0gbWF4KDAsIChtYXhsZW4tMykvMikKICAgICAgICBwb3N0ID0gbWF4KDAsIG1heGxlbi0zLXByZSkKICAgICAgICByZXR1cm4gdGV4dFs6cHJlXSArICcuLi4nICsgdGV4dFtsZW4odGV4dCktcG9zdDpdCiAgICByZXR1cm4gdGV4dAoKZGVmIHN0cmlwaWQodGV4dCk6CiAgICAiIiJSZW1vdmUgdGhlIGhleGFkZWNpbWFsIGlkIGZyb20gYSBQeXRob24gb2JqZWN0IHJlcHJlc2VudGF0aW9uLiIiIgogICAgIyBUaGUgYmVoYXZpb3VyIG9mICVwIGlzIGltcGxlbWVudGF0aW9uLWRlcGVuZGVudCwgc28gd2UgbmVlZCBhbiBleGFtcGxlLgogICAgZm9yIHBhdHRlcm4gaW4gWycgYXQgMHhbMC05YS1mXXs2LH0+JCcsICcgYXQgWzAtOUEtRl17OCx9PiQnXToKICAgICAgICBpZiByZS5zZWFyY2gocGF0dGVybiwgcmVwcihFeGNlcHRpb24pKToKICAgICAgICAgICAgcmV0dXJuIHJlLnN1YihwYXR0ZXJuLCAnPicsIHRleHQpCiAgICByZXR1cm4gdGV4dAoKZGVmIG1vZHVsZW5hbWUocGF0aCk6CiAgICAiIiJSZXR1cm4gdGhlIFB5dGhvbiBtb2R1bGUgbmFtZSBmb3IgYSBnaXZlbiBwYXRoLCBvciBOb25lLiIiIgogICAgZmlsZW5hbWUgPSBvcy5wYXRoLmJhc2VuYW1lKHBhdGgpCiAgICBmb3IgZW5kaW5nIGluIFsnLnB5JywgJy5weWMnLCAnLnB5ZCcsICcucHlvJywKICAgICAgICAgICAgICAgICAgICdtb2R1bGUuc28nLCAnbW9kdWxlLnNvLjEnLCAnLnNvJ106CiAgICAgICAgaWYgbGVuKGZpbGVuYW1lKSA+IGxlbihlbmRpbmcpIGFuZCBmaWxlbmFtZVstbGVuKGVuZGluZyk6XSA9PSBlbmRpbmc6CiAgICAgICAgICAgIHJldHVybiBmaWxlbmFtZVs6LWxlbihlbmRpbmcpXQoKY2xhc3MgRG9jSW1wb3J0RXJyb3IoRXhjZXB0aW9uKToKICAgICIiIkNsYXNzIGZvciBlcnJvcnMgd2hpbGUgdHJ5aW5nIHRvIGltcG9ydCBzb21ldGhpbmcgdG8gZG9jdW1lbnQgaXQuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW5hbWUsIGV0eXBlLCBldmFsdWUpOgogICAgICAgIHNlbGYuZmlsZW5hbWUgPSBmaWxlbmFtZQogICAgICAgIHNlbGYuZXR5cGUgPSBldHlwZQogICAgICAgIHNlbGYuZXZhbHVlID0gZXZhbHVlCiAgICAgICAgaWYgdHlwZShldHlwZSkgaXMgdHlwZXMuQ2xhc3NUeXBlOgogICAgICAgICAgICBldHlwZSA9IGV0eXBlLl9fbmFtZV9fCiAgICAgICAgc2VsZi5hcmdzID0gJyVzOiAlcycgJSAoZXR5cGUsIGV2YWx1ZSkKCmRlZiBpbXBvcnRmaWxlKHBhdGgpOgogICAgIiIiSW1wb3J0IGEgUHl0aG9uIHNvdXJjZSBmaWxlIG9yIGNvbXBpbGVkIGZpbGUgZ2l2ZW4gaXRzIHBhdGguIiIiCiAgICBtYWdpYyA9IGltcC5nZXRfbWFnaWMoKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgaWYgZmlsZS5yZWFkKGxlbihtYWdpYykpID09IG1hZ2ljOgogICAgICAgIGtpbmQgPSBpbXAuUFlfQ09NUElMRUQKICAgIGVsc2U6CiAgICAgICAga2luZCA9IGltcC5QWV9TT1VSQ0UKICAgIGZpbGUuY2xvc2UoKQogICAgZmlsZW5hbWUgPSBvcy5wYXRoLmJhc2VuYW1lKHBhdGgpCiAgICBuYW1lLCBleHQgPSBvcy5wYXRoLnNwbGl0ZXh0KGZpbGVuYW1lKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgdHJ5OgogICAgICAgIG1vZHVsZSA9IGltcC5sb2FkX21vZHVsZShuYW1lLCBmaWxlLCBwYXRoLCAoZXh0LCAncicsIGtpbmQpKQogICAgZXhjZXB0OgogICAgICAgIHJhaXNlIERvY0ltcG9ydEVycm9yKHBhdGgsIHN5cy5leGNfdHlwZSwgc3lzLmV4Y192YWx1ZSkKICAgIGZpbGUuY2xvc2UoKQogICAgcmV0dXJuIG1vZHVsZQoKZGVmIGlzcGFja2FnZShwYXRoKToKICAgICIiIkd1ZXNzIHdoZXRoZXIgYSBwYXRoIHJlZmVycyB0byBhIHBhY2thZ2UgZGlyZWN0b3J5LiIiIgogICAgaWYgb3MucGF0aC5pc2RpcihwYXRoKToKICAgICAgICBpbml0ID0gb3MucGF0aC5qb2luKHBhdGgsICdfX2luaXRfXy5weScpCiAgICAgICAgaW5pdGMgPSBvcy5wYXRoLmpvaW4ocGF0aCwgJ19faW5pdF9fLnB5YycpCiAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUoaW5pdCkgb3Igb3MucGF0aC5pc2ZpbGUoaW5pdGMpOgogICAgICAgICAgICByZXR1cm4gMQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGZvcm1hdHRlciBiYXNlIGNsYXNzCgpjbGFzcyBEb2M6CiAgICBkZWYgZG9jdW1lbnQoc2VsZiwgb2JqZWN0LCAqYXJncyk6CiAgICAgICAgIiIiR2VuZXJhdGUgZG9jdW1lbnRhdGlvbiBmb3IgYW4gb2JqZWN0LiIiIgogICAgICAgIGFyZ3MgPSAob2JqZWN0LCkgKyBhcmdzCiAgICAgICAgaWYgaW5zcGVjdC5pc21vZHVsZShvYmplY3QpOiByZXR1cm4gYXBwbHkoc2VsZi5kb2Ntb2R1bGUsIGFyZ3MpCiAgICAgICAgaWYgaW5zcGVjdC5pc2NsYXNzKG9iamVjdCk6IHJldHVybiBhcHBseShzZWxmLmRvY2NsYXNzLCBhcmdzKQogICAgICAgIGlmIGluc3BlY3QuaXNyb3V0aW5lKG9iamVjdCk6IHJldHVybiBhcHBseShzZWxmLmRvY3JvdXRpbmUsIGFyZ3MpCiAgICAgICAgcmFpc2UgVHlwZUVycm9yLCAiZG9uJ3Qga25vdyBob3cgdG8gZG9jdW1lbnQgb2JqZWN0cyBvZiB0eXBlICIgKyBcCiAgICAgICAgICAgIHR5cGUob2JqZWN0KS5fX25hbWVfXwoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBIVE1MIGRvY3VtZW50YXRpb24gZ2VuZXJhdG9yCgpjbGFzcyBIVE1MUmVwcihSZXByKToKICAgICIiIkNsYXNzIGZvciBzYWZlbHkgbWFraW5nIGFuIEhUTUwgcmVwcmVzZW50YXRpb24gb2YgYSBQeXRob24gb2JqZWN0LiIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIFJlcHIuX19pbml0X18oc2VsZikKICAgICAgICBzZWxmLm1heGxpc3QgPSBzZWxmLm1heHR1cGxlID0gc2VsZi5tYXhkaWN0ID0gMTAKICAgICAgICBzZWxmLm1heHN0cmluZyA9IHNlbGYubWF4b3RoZXIgPSA1MAoKICAgIGRlZiBlc2NhcGUoc2VsZiwgdGV4dCk6CiAgICAgICAgcmV0dXJuIHJlcGxhY2UodGV4dCwgKCcmJywgJyZhbXA7JyksICgnPCcsICcmbHQ7JyksICgnPicsICcmZ3Q7JykpCgogICAgZGVmIHJlcHIoc2VsZiwgb2JqZWN0KToKICAgICAgICByZXN1bHQgPSBSZXByLnJlcHIoc2VsZiwgb2JqZWN0KQogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBkZWYgcmVwcjEoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIG1ldGhvZG5hbWUgPSAncmVwcl8nICsgam9pbihzcGxpdCh0eXBlKHgpLl9fbmFtZV9fKSwgJ18nKQogICAgICAgIGlmIGhhc2F0dHIoc2VsZiwgbWV0aG9kbmFtZSk6CiAgICAgICAgICAgIHJldHVybiBnZXRhdHRyKHNlbGYsIG1ldGhvZG5hbWUpKHgsIGxldmVsKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmVzY2FwZShjcmFtKHN0cmlwaWQocmVwcih4KSksIHNlbGYubWF4b3RoZXIpKQoKICAgIGRlZiByZXByX3N0cmluZyhzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgdGV4dCA9IHNlbGYuZXNjYXBlKGNyYW0oeCwgc2VsZi5tYXhzdHJpbmcpKQogICAgICAgIHJldHVybiByZS5zdWIocicoKFxcW1xcYWJmbnJ0dl18XFx4Li58XFx1Li4uLikrKScsCiAgICAgICAgICAgICAgICAgICAgICByJzxmb250IGNvbG9yPSIjYzA0MGMwIj5cMTwvZm9udD4nLCByZXByKHRleHQpKQoKICAgIGRlZiByZXByX2luc3RhbmNlKHNlbGYsIHgsIGxldmVsKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHJldHVybiBjcmFtKHN0cmlwaWQocmVwcih4KSksIHNlbGYubWF4c3RyaW5nKQogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZXNjYXBlKCc8JXMgaW5zdGFuY2U+JyAlIHguX19jbGFzc19fLl9fbmFtZV9fKQoKICAgIHJlcHJfdW5pY29kZSA9IHJlcHJfc3RyaW5nCgpjbGFzcyBIVE1MRG9jKERvYyk6CiAgICAiIiJGb3JtYXR0ZXIgY2xhc3MgZm9yIEhUTUwgZG9jdW1lbnRhdGlvbi4iIiIKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSFRNTCBmb3JtYXR0aW5nIHV0aWxpdGllcwoKICAgIF9yZXByX2luc3RhbmNlID0gSFRNTFJlcHIoKQogICAgcmVwciA9IF9yZXByX2luc3RhbmNlLnJlcHIKICAgIGVzY2FwZSA9IF9yZXByX2luc3RhbmNlLmVzY2FwZQoKICAgIGRlZiBwcmVmb3JtYXQoc2VsZiwgdGV4dCk6CiAgICAgICAgIiIiRm9ybWF0IGxpdGVyYWwgcHJlZm9ybWF0dGVkIHRleHQuIiIiCiAgICAgICAgdGV4dCA9IHNlbGYuZXNjYXBlKGV4cGFuZHRhYnModGV4dCkpCiAgICAgICAgcmV0dXJuIHJlcGxhY2UodGV4dCwgKCdcblxuJywgJ1xuIFxuJyksICgnXG5cbicsICdcbiBcbicpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICgnICcsICcmbmJzcDsnKSwgKCdcbicsICc8YnI+XG4nKSkKCiAgICBkZWYgbXVsdGljb2x1bW4oc2VsZiwgbGlzdCwgZm9ybWF0LCBjb2xzPTQpOgogICAgICAgICIiIkZvcm1hdCBhIGxpc3Qgb2YgaXRlbXMgaW50byBhIG11bHRpLWNvbHVtbiBsaXN0LiIiIgogICAgICAgIHJlc3VsdCA9ICcnCiAgICAgICAgcm93cyA9IChsZW4obGlzdCkrY29scy0xKS9jb2xzCgogICAgICAgIGZvciBjb2wgaW4gcmFuZ2UoY29scyk6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8dGQgd2lkdGg9IiVkJSUiIHZhbGlnbj10b3A+JyAlICgxMDAvY29scykKICAgICAgICAgICAgZm9yIGkgaW4gcmFuZ2Uocm93cypjb2wsIHJvd3MqY29sK3Jvd3MpOgogICAgICAgICAgICAgICAgaWYgaSA8IGxlbihsaXN0KToKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBmb3JtYXQobGlzdFtpXSkgKyAnPGJyPicKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJzwvdGQ+JwogICAgICAgIHJldHVybiAnPHRhYmxlIHdpZHRoPSIxMDAlJSI+PHRyPiVzPC90cj48L3RhYmxlPicgJSByZXN1bHQKCiAgICBkZWYgaGVhZGluZyhzZWxmLCB0aXRsZSwgZmdjb2wsIGJnY29sLCBleHRyYXM9JycpOgogICAgICAgICIiIkZvcm1hdCBhIHBhZ2UgaGVhZGluZy4iIiIKICAgICAgICByZXR1cm4gIiIiCjxwPjx0YWJsZSB3aWR0aD0iMTAwJSUiIGNlbGxzcGFjaW5nPTAgY2VsbHBhZGRpbmc9MCBib3JkZXI9MD4KPHRyIGJnY29sb3I9IiVzIj48dGQ+Jm5ic3A7PC90ZD4KPHRkIHZhbGlnbj1ib3R0b20+PHNtYWxsPjxzbWFsbD48YnI+PC9zbWFsbD48L3NtYWxsCj48Zm9udCBjb2xvcj0iJXMiIGZhY2U9ImhlbHZldGljYSI+PGJyPiZuYnNwOyVzPC9mb250PjwvdGQKPjx0ZCBhbGlnbj1yaWdodCB2YWxpZ249Ym90dG9tCj48Zm9udCBjb2xvcj0iJXMiIGZhY2U9ImhlbHZldGljYSI+JXM8L2ZvbnQ+PC90ZD48dGQ+Jm5ic3A7PC90ZD48L3RyPjwvdGFibGU+CiAgICAiIiIgJSAoYmdjb2wsIGZnY29sLCB0aXRsZSwgZmdjb2wsIGV4dHJhcyBvciAnJm5ic3A7JykKCiAgICBkZWYgc2VjdGlvbihzZWxmLCB0aXRsZSwgZmdjb2wsIGJnY29sLCBjb250ZW50cywgd2lkdGg9MjAsCiAgICAgICAgICAgICAgICBwcmVsdWRlPScnLCBtYXJnaW5hbGlhPU5vbmUsIGdhcD0nJm5ic3A7Jm5ic3A7Jm5ic3A7Jyk6CiAgICAgICAgIiIiRm9ybWF0IGEgc2VjdGlvbiB3aXRoIGEgaGVhZGluZy4iIiIKICAgICAgICBpZiBtYXJnaW5hbGlhIGlzIE5vbmU6CiAgICAgICAgICAgIG1hcmdpbmFsaWEgPSAnJm5ic3A7JyAqIHdpZHRoCiAgICAgICAgcmVzdWx0ID0gIiIiCjxwPjx0YWJsZSB3aWR0aD0iMTAwJSUiIGNlbGxzcGFjaW5nPTAgY2VsbHBhZGRpbmc9MCBib3JkZXI9MD4KPHRyIGJnY29sb3I9IiVzIj48dGQgcm93c3Bhbj0yPiZuYnNwOzwvdGQ+Cjx0ZCBjb2xzcGFuPTMgdmFsaWduPWJvdHRvbT48c21hbGw+PHNtYWxsPjxicj48L3NtYWxsPjwvc21hbGwKPjxmb250IGNvbG9yPSIlcyIgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+Jm5ic3A7JXM8L2ZvbnQ+PC90ZD48L3RyPgogICAgIiIiICUgKGJnY29sLCBmZ2NvbCwgdGl0bGUpCiAgICAgICAgaWYgcHJlbHVkZToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgIiIiCjx0cj48dGQgYmdjb2xvcj0iJXMiPiVzPC90ZD4KPHRkIGJnY29sb3I9IiVzIiBjb2xzcGFuPTI+JXM8L3RkPjwvdHI+CiAgICAiIiIgJSAoYmdjb2wsIG1hcmdpbmFsaWEsIGJnY29sLCBwcmVsdWRlKQogICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICIiIgo8dHI+PHRkIGJnY29sb3I9IiVzIj4lczwvdGQ+PHRkPiVzPC90ZD4KICAgICIiIiAlIChiZ2NvbCwgbWFyZ2luYWxpYSwgZ2FwKQoKICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPHRkIHdpZHRoPSIxMDAlJSI+JXM8L3RkPjwvdHI+PC90YWJsZT4nICUgY29udGVudHMKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIGJpZ3NlY3Rpb24oc2VsZiwgdGl0bGUsICphcmdzKToKICAgICAgICAiIiJGb3JtYXQgYSBzZWN0aW9uIHdpdGggYSBiaWcgaGVhZGluZy4iIiIKICAgICAgICB0aXRsZSA9ICc8YmlnPjxzdHJvbmc+JXM8L3N0cm9uZz48L2JpZz4nICUgdGl0bGUKICAgICAgICByZXR1cm4gYXBwbHkoc2VsZi5zZWN0aW9uLCAodGl0bGUsKSArIGFyZ3MpCgogICAgZGVmIG5hbWVsaW5rKHNlbGYsIG5hbWUsICpkaWN0cyk6CiAgICAgICAgIiIiTWFrZSBhIGxpbmsgZm9yIGFuIGlkZW50aWZpZXIsIGdpdmVuIG5hbWUtdG8tVVJMIG1hcHBpbmdzLiIiIgogICAgICAgIGZvciBkaWN0IGluIGRpY3RzOgogICAgICAgICAgICBpZiBkaWN0Lmhhc19rZXkobmFtZSk6CiAgICAgICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKGRpY3RbbmFtZV0sIG5hbWUpCiAgICAgICAgcmV0dXJuIG5hbWUKCiAgICBkZWYgY2xhc3NsaW5rKHNlbGYsIG9iamVjdCwgbW9kbmFtZSwgKmRpY3RzKToKICAgICAgICAiIiJNYWtlIGEgbGluayBmb3IgYSBjbGFzcy4iIiIKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgaWYgb2JqZWN0Ll9fbW9kdWxlX18gIT0gbW9kbmFtZToKICAgICAgICAgICAgbmFtZSA9IG9iamVjdC5fX21vZHVsZV9fICsgJy4nICsgbmFtZQogICAgICAgIGZvciBkaWN0IGluIGRpY3RzOgogICAgICAgICAgICBpZiBkaWN0Lmhhc19rZXkob2JqZWN0KToKICAgICAgICAgICAgICAgIHJldHVybiAnPGEgaHJlZj0iJXMiPiVzPC9hPicgJSAoZGljdFtvYmplY3RdLCBuYW1lKQogICAgICAgIHJldHVybiBuYW1lCgogICAgZGVmIG1vZHVsZWxpbmsoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJNYWtlIGEgbGluayBmb3IgYSBtb2R1bGUuIiIiCiAgICAgICAgcmV0dXJuICc8YSBocmVmPSIlcy5odG1sIj4lczwvYT4nICUgKG9iamVjdC5fX25hbWVfXywgb2JqZWN0Ll9fbmFtZV9fKQoKICAgIGRlZiBtb2Rwa2dsaW5rKHNlbGYsIChuYW1lLCBwYXRoLCBpc3BhY2thZ2UsIHNoYWRvd2VkKSk6CiAgICAgICAgIiIiTWFrZSBhIGxpbmsgZm9yIGEgbW9kdWxlIG9yIHBhY2thZ2UgdG8gZGlzcGxheSBpbiBhbiBpbmRleC4iIiIKICAgICAgICBpZiBzaGFkb3dlZDoKICAgICAgICAgICAgcmV0dXJuICc8Zm9udCBjb2xvcj0iIzkwOTA5MCI+JXM8L2ZvbnQ+JyAlIG5hbWUKICAgICAgICBpZiBwYXRoOgogICAgICAgICAgICB1cmwgPSAnJXMuJXMuaHRtbCcgJSAocGF0aCwgbmFtZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICB1cmwgPSAnJXMuaHRtbCcgJSBuYW1lCiAgICAgICAgaWYgaXNwYWNrYWdlOgogICAgICAgICAgICB0ZXh0ID0gJzxzdHJvbmc+JXM8L3N0cm9uZz4mbmJzcDsocGFja2FnZSknICUgbmFtZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRleHQgPSBuYW1lCiAgICAgICAgcmV0dXJuICc8YSBocmVmPSIlcyI+JXM8L2E+JyAlICh1cmwsIHRleHQpCgogICAgZGVmIG1hcmt1cChzZWxmLCB0ZXh0LCBlc2NhcGU9Tm9uZSwgZnVuY3M9e30sIGNsYXNzZXM9e30sIG1ldGhvZHM9e30pOgogICAgICAgICIiIk1hcmsgdXAgc29tZSBwbGFpbiB0ZXh0LCBnaXZlbiBhIGNvbnRleHQgb2Ygc3ltYm9scyB0byBsb29rIGZvci4KICAgICAgICBFYWNoIGNvbnRleHQgZGljdGlvbmFyeSBtYXBzIG9iamVjdCBuYW1lcyB0byBhbmNob3IgbmFtZXMuIiIiCiAgICAgICAgZXNjYXBlID0gZXNjYXBlIG9yIHNlbGYuZXNjYXBlCiAgICAgICAgcmVzdWx0cyA9IFtdCiAgICAgICAgaGVyZSA9IDAKICAgICAgICBwYXR0ZXJuID0gcmUuY29tcGlsZShyJ1xiKCgoaHR0cHxmdHApOi8vXFMrW1x3L10pfCcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByJyhSRkNbLSBdPyhcZCspKXwnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcicoc2VsZlwuKT8oXHcrKSlcYicpCiAgICAgICAgd2hpbGUgMToKICAgICAgICAgICAgbWF0Y2ggPSBwYXR0ZXJuLnNlYXJjaCh0ZXh0LCBoZXJlKQogICAgICAgICAgICBpZiBub3QgbWF0Y2g6IGJyZWFrCiAgICAgICAgICAgIHN0YXJ0LCBlbmQgPSBtYXRjaC5zcGFuKCkKICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoZXNjYXBlKHRleHRbaGVyZTpzdGFydF0pKQoKICAgICAgICAgICAgYWxsLCB1cmwsIHNjaGVtZSwgcmZjLCByZmNudW0sIHNlbGZkb3QsIG5hbWUgPSBtYXRjaC5ncm91cHMoKQogICAgICAgICAgICBpZiB1cmw6CiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgnPGEgaHJlZj0iJXMiPiVzPC9hPicgJSAodXJsLCBlc2NhcGUodXJsKSkpCiAgICAgICAgICAgIGVsaWYgcmZjOgogICAgICAgICAgICAgICAgdXJsID0gJ2h0dHA6Ly93d3cucmZjLWVkaXRvci5vcmcvcmZjL3JmYyVzLnR4dCcgJSByZmNudW0KICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCc8YSBocmVmPSIlcyI+JXM8L2E+JyAlICh1cmwsIGVzY2FwZShyZmMpKSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGlmIHRleHRbZW5kOmVuZCsxXSA9PSAnKCc6CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoc2VsZi5uYW1lbGluayhuYW1lLCBtZXRob2RzLCBmdW5jcywgY2xhc3NlcykpCiAgICAgICAgICAgICAgICBlbGlmIHNlbGZkb3Q6CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJ3NlbGYuPHN0cm9uZz4lczwvc3Ryb25nPicgJSBuYW1lKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZChzZWxmLm5hbWVsaW5rKG5hbWUsIGNsYXNzZXMpKQogICAgICAgICAgICBoZXJlID0gZW5kCiAgICAgICAgcmVzdWx0cy5hcHBlbmQoZXNjYXBlKHRleHRbaGVyZTpdKSkKICAgICAgICByZXR1cm4gam9pbihyZXN1bHRzLCAnJykKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdHlwZS1zcGVjaWZpYyByb3V0aW5lcwoKICAgIGRlZiBkb2N0cmVlKHNlbGYsIHRyZWUsIG1vZG5hbWUsIGNsYXNzZXM9e30sIHBhcmVudD1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZm9yIGEgY2xhc3MgdHJlZSBhcyBnaXZlbiBieSBpbnNwZWN0LmdldGNsYXNzdHJlZSgpLiIiIgogICAgICAgIHJlc3VsdCA9ICcnCiAgICAgICAgZm9yIGVudHJ5IGluIHRyZWU6CiAgICAgICAgICAgIGlmIHR5cGUoZW50cnkpIGlzIHR5cGUoKCkpOgogICAgICAgICAgICAgICAgYywgYmFzZXMgPSBlbnRyeQogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJzxkdD48Zm9udCBmYWNlPSJoZWx2ZXRpY2EsIGFyaWFsIj48c21hbGw+JwogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5jbGFzc2xpbmsoYywgbW9kbmFtZSwgY2xhc3NlcykKICAgICAgICAgICAgICAgIGlmIGJhc2VzIGFuZCBiYXNlcyAhPSAocGFyZW50LCk6CiAgICAgICAgICAgICAgICAgICAgcGFyZW50cyA9IFtdCiAgICAgICAgICAgICAgICAgICAgZm9yIGJhc2UgaW4gYmFzZXM6CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudHMuYXBwZW5kKHNlbGYuY2xhc3NsaW5rKGJhc2UsIG1vZG5hbWUsIGNsYXNzZXMpKQogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICcoJyArIGpvaW4ocGFyZW50cywgJywgJykgKyAnKScKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICdcbjwvc21hbGw+PC9mb250PjwvZHQ+JwogICAgICAgICAgICBlbGlmIHR5cGUoZW50cnkpIGlzIHR5cGUoW10pOgogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgXAogICAgICAgICAgICAgICAgICAgICc8ZGQ+XG4lczwvZGQ+XG4nICUgc2VsZi5kb2N0cmVlKGVudHJ5LCBtb2RuYW1lLCBjbGFzc2VzLCBjKQogICAgICAgIHJldHVybiAnPGRsPlxuJXM8L2RsPlxuJyAlIHJlc3VsdAoKICAgIGRlZiBkb2Ntb2R1bGUoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBtb2R1bGUgb2JqZWN0LiIiIgogICAgICAgIG5hbWUgPSBvYmplY3QuX19uYW1lX18KICAgICAgICBwYXJ0cyA9IHNwbGl0KG5hbWUsICcuJykKICAgICAgICBsaW5rcyA9IFtdCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UobGVuKHBhcnRzKS0xKToKICAgICAgICAgICAgbGlua3MuYXBwZW5kKAogICAgICAgICAgICAgICAgJzxhIGhyZWY9IiVzLmh0bWwiPjxmb250IGNvbG9yPSIjZmZmZmZmIj4lczwvZm9udD48L2E+JyAlCiAgICAgICAgICAgICAgICAoam9pbihwYXJ0c1s6aSsxXSwgJy4nKSwgcGFydHNbaV0pKQogICAgICAgIGxpbmtlZG5hbWUgPSBqb2luKGxpbmtzICsgcGFydHNbLTE6XSwgJy4nKQogICAgICAgIGhlYWQgPSAnPGJpZz48YmlnPjxzdHJvbmc+JXM8L3N0cm9uZz48L2JpZz48L2JpZz4nICUgbGlua2VkbmFtZQogICAgICAgIHRyeToKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguYWJzcGF0aChpbnNwZWN0LmdldGZpbGUob2JqZWN0KSkKICAgICAgICAgICAgc291cmNlcGF0aCA9IG9zLnBhdGguYWJzcGF0aChpbnNwZWN0LmdldHNvdXJjZWZpbGUob2JqZWN0KSkKICAgICAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUoc291cmNlcGF0aCk6IHBhdGggPSBzb3VyY2VwYXRoCiAgICAgICAgICAgIGZpbGVsaW5rID0gJzxhIGhyZWY9ImZpbGU6JXMiPiVzPC9hPicgJSAocGF0aCwgcGF0aCkKICAgICAgICBleGNlcHQgVHlwZUVycm9yOgogICAgICAgICAgICBmaWxlbGluayA9ICcoYnVpbHQtaW4pJwogICAgICAgIGluZm8gPSBbXQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX192ZXJzaW9uX18nKToKICAgICAgICAgICAgdmVyc2lvbiA9IHN0cihvYmplY3QuX192ZXJzaW9uX18pCiAgICAgICAgICAgIGlmIHZlcnNpb25bOjExXSA9PSAnJCcgKyAnUmV2aXNpb246ICcgYW5kIHZlcnNpb25bLTE6XSA9PSAnJCc6CiAgICAgICAgICAgICAgICB2ZXJzaW9uID0gc3RyaXAodmVyc2lvblsxMTotMV0pCiAgICAgICAgICAgIGluZm8uYXBwZW5kKCd2ZXJzaW9uICVzJyAlIHNlbGYuZXNjYXBlKHZlcnNpb24pKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19kYXRlX18nKToKICAgICAgICAgICAgaW5mby5hcHBlbmQoc2VsZi5lc2NhcGUoc3RyKG9iamVjdC5fX2RhdGVfXykpKQogICAgICAgIGlmIGluZm86CiAgICAgICAgICAgIGhlYWQgPSBoZWFkICsgJyAoJXMpJyAlIGpvaW4oaW5mbywgJywgJykKICAgICAgICByZXN1bHQgPSBzZWxmLmhlYWRpbmcoCiAgICAgICAgICAgIGhlYWQsICcjZmZmZmZmJywgJyM3Nzk5ZWUnLCAnPGEgaHJlZj0iLiI+aW5kZXg8L2E+PGJyPicgKyBmaWxlbGluaykKCiAgICAgICAgc2Vjb25kID0gbGFtYmRhIGxpc3Q6IGxpc3RbMV0KICAgICAgICBtb2R1bGVzID0gbWFwKHNlY29uZCwgaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc21vZHVsZSkpCgogICAgICAgIGNsYXNzZXMsIGNkaWN0ID0gW10sIHt9CiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc2NsYXNzKToKICAgICAgICAgICAgaWYgKGluc3BlY3QuZ2V0bW9kdWxlKHZhbHVlKSBvciBvYmplY3QpIGlzIG9iamVjdDoKICAgICAgICAgICAgICAgIGNsYXNzZXMuYXBwZW5kKHZhbHVlKQogICAgICAgICAgICAgICAgY2RpY3Rba2V5XSA9IGNkaWN0W3ZhbHVlXSA9ICcjJyArIGtleQogICAgICAgIGZ1bmNzLCBmZGljdCA9IFtdLCB7fQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNyb3V0aW5lKToKICAgICAgICAgICAgaWYgaW5zcGVjdC5pc2J1aWx0aW4odmFsdWUpIG9yIGluc3BlY3QuZ2V0bW9kdWxlKHZhbHVlKSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBmdW5jcy5hcHBlbmQodmFsdWUpCiAgICAgICAgICAgICAgICBmZGljdFtrZXldID0gJyMtJyArIGtleQogICAgICAgICAgICAgICAgaWYgaW5zcGVjdC5pc2Z1bmN0aW9uKHZhbHVlKTogZmRpY3RbdmFsdWVdID0gZmRpY3Rba2V5XQogICAgICAgIGZvciBjIGluIGNsYXNzZXM6CiAgICAgICAgICAgIGZvciBiYXNlIGluIGMuX19iYXNlc19fOgogICAgICAgICAgICAgICAga2V5LCBtb2RuYW1lID0gYmFzZS5fX25hbWVfXywgYmFzZS5fX21vZHVsZV9fCiAgICAgICAgICAgICAgICBpZiBtb2RuYW1lICE9IG5hbWUgYW5kIHN5cy5tb2R1bGVzLmhhc19rZXkobW9kbmFtZSk6CiAgICAgICAgICAgICAgICAgICAgbW9kdWxlID0gc3lzLm1vZHVsZXNbbW9kbmFtZV0KICAgICAgICAgICAgICAgICAgICBpZiBoYXNhdHRyKG1vZHVsZSwga2V5KSBhbmQgZ2V0YXR0cihtb2R1bGUsIGtleSkgaXMgYmFzZToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm90IGNkaWN0Lmhhc19rZXkoa2V5KToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNkaWN0W2tleV0gPSBjZGljdFtiYXNlXSA9IG1vZG5hbWUgKyAnLmh0bWwjJyArIGtleQogICAgICAgIGNvbnN0YW50cyA9IFtdCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaXNjb25zdGFudCk6CiAgICAgICAgICAgIGlmIGtleVs6MV0gIT0gJ18nOgogICAgICAgICAgICAgICAgY29uc3RhbnRzLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCgogICAgICAgIGRvYyA9IHNlbGYubWFya3VwKGdldGRvYyhvYmplY3QpLCBzZWxmLnByZWZvcm1hdCwgZmRpY3QsIGNkaWN0KQogICAgICAgIGRvYyA9IGRvYyBhbmQgJzx0dD4lczwvdHQ+JyAlIGRvYwogICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8cD48c21hbGw+JXM8L3NtYWxsPjwvcD5cbicgJSBkb2MKCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX3BhdGhfXycpOgogICAgICAgICAgICBtb2Rwa2dzID0gW10KICAgICAgICAgICAgbW9kbmFtZXMgPSBbXQogICAgICAgICAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKG9iamVjdC5fX3BhdGhfX1swXSk6CiAgICAgICAgICAgICAgICBpZiBmaWxlWzoxXSAhPSAnXyc6CiAgICAgICAgICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihvYmplY3QuX19wYXRoX19bMF0sIGZpbGUpCiAgICAgICAgICAgICAgICAgICAgbW9kbmFtZSA9IG1vZHVsZW5hbWUoZmlsZSkKICAgICAgICAgICAgICAgICAgICBpZiBtb2RuYW1lIGFuZCBtb2RuYW1lIG5vdCBpbiBtb2RuYW1lczoKICAgICAgICAgICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQoKG1vZG5hbWUsIG5hbWUsIDAsIDApKQogICAgICAgICAgICAgICAgICAgICAgICBtb2RuYW1lcy5hcHBlbmQobW9kbmFtZSkKICAgICAgICAgICAgICAgICAgICBlbGlmIGlzcGFja2FnZShwYXRoKToKICAgICAgICAgICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQoKGZpbGUsIG5hbWUsIDEsIDApKQogICAgICAgICAgICBtb2Rwa2dzLnNvcnQoKQogICAgICAgICAgICBjb250ZW50cyA9IHNlbGYubXVsdGljb2x1bW4obW9kcGtncywgc2VsZi5tb2Rwa2dsaW5rKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnUGFja2FnZSBDb250ZW50cycsICcjZmZmZmZmJywgJyNhYTU1Y2MnLCBjb250ZW50cykKCiAgICAgICAgZWxpZiBtb2R1bGVzOgogICAgICAgICAgICBjb250ZW50cyA9IHNlbGYubXVsdGljb2x1bW4obW9kdWxlcywgc2VsZi5tb2R1bGVsaW5rKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnTW9kdWxlcycsICcjZmZmZmYnLCAnI2FhNTVjYycsIGNvbnRlbnRzKQoKICAgICAgICBpZiBjbGFzc2VzOgogICAgICAgICAgICBjb250ZW50cyA9IHNlbGYuZG9jdHJlZSgKICAgICAgICAgICAgICAgIGluc3BlY3QuZ2V0Y2xhc3N0cmVlKGNsYXNzZXMsIDEpLCBuYW1lLCBjZGljdCkKICAgICAgICAgICAgZm9yIGl0ZW0gaW4gY2xhc3NlczoKICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gY29udGVudHMgKyBzZWxmLmRvY3VtZW50KGl0ZW0sIGZkaWN0LCBjZGljdCkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0NsYXNzZXMnLCAnI2ZmZmZmZicsICcjZWU3N2FhJywgY29udGVudHMpCiAgICAgICAgaWYgZnVuY3M6CiAgICAgICAgICAgIGNvbnRlbnRzID0gJycKICAgICAgICAgICAgZm9yIGl0ZW0gaW4gZnVuY3M6CiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgc2VsZi5kb2N1bWVudChpdGVtLCBmZGljdCwgY2RpY3QpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdGdW5jdGlvbnMnLCAnI2ZmZmZmZicsICcjZWVhYTc3JywgY29udGVudHMpCgogICAgICAgIGlmIGNvbnN0YW50czoKICAgICAgICAgICAgY29udGVudHMgPSAnJwogICAgICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBjb25zdGFudHM6CiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgKCc8YnI+PHN0cm9uZz4lczwvc3Ryb25nPiA9ICVzJyAlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChrZXksIHNlbGYucmVwcih2YWx1ZSkpKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnQ29uc3RhbnRzJywgJyNmZmZmZmYnLCAnIzU1YWE1NScsIGNvbnRlbnRzKQoKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fYXV0aG9yX18nKToKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm1hcmt1cChzdHIob2JqZWN0Ll9fYXV0aG9yX18pLCBzZWxmLnByZWZvcm1hdCkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0F1dGhvcicsICcjZmZmZmZmJywgJyM3Nzk5ZWUnLCBjb250ZW50cykKCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2NyZWRpdHNfXycpOgogICAgICAgICAgICBjb250ZW50cyA9IHNlbGYubWFya3VwKHN0cihvYmplY3QuX19jcmVkaXRzX18pLCBzZWxmLnByZWZvcm1hdCkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0NyZWRpdHMnLCAnI2ZmZmZmZicsICcjNzc5OWVlJywgY29udGVudHMpCgogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBkZWYgZG9jY2xhc3Moc2VsZiwgb2JqZWN0LCBmdW5jcz17fSwgY2xhc3Nlcz17fSk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGEgY2xhc3Mgb2JqZWN0LiIiIgogICAgICAgIG5hbWUgPSBvYmplY3QuX19uYW1lX18KICAgICAgICBiYXNlcyA9IG9iamVjdC5fX2Jhc2VzX18KICAgICAgICBjb250ZW50cyA9ICcnCgogICAgICAgIG1ldGhvZHMsIG1kaWN0ID0gW10sIHt9CiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc21ldGhvZCk6CiAgICAgICAgICAgIG1ldGhvZHMuYXBwZW5kKHZhbHVlKQogICAgICAgICAgICBtZGljdFtrZXldID0gbWRpY3RbdmFsdWVdID0gJyMnICsgbmFtZSArICctJyArIGtleQogICAgICAgIGZvciBpdGVtIGluIG1ldGhvZHM6CiAgICAgICAgICAgIGNvbnRlbnRzID0gY29udGVudHMgKyBzZWxmLmRvY3VtZW50KAogICAgICAgICAgICAgICAgaXRlbSwgZnVuY3MsIGNsYXNzZXMsIG1kaWN0LCBuYW1lKQoKICAgICAgICB0aXRsZSA9ICc8YSBuYW1lPSIlcyI+Y2xhc3MgPHN0cm9uZz4lczwvc3Ryb25nPjwvYT4nICUgKG5hbWUsIG5hbWUpCiAgICAgICAgaWYgYmFzZXM6CiAgICAgICAgICAgIHBhcmVudHMgPSBbXQogICAgICAgICAgICBmb3IgYmFzZSBpbiBiYXNlczoKICAgICAgICAgICAgICAgIHBhcmVudHMuYXBwZW5kKHNlbGYuY2xhc3NsaW5rKGJhc2UsIG9iamVjdC5fX21vZHVsZV9fLCBjbGFzc2VzKSkKICAgICAgICAgICAgdGl0bGUgPSB0aXRsZSArICcoJXMpJyAlIGpvaW4ocGFyZW50cywgJywgJykKICAgICAgICBkb2MgPSBzZWxmLm1hcmt1cChnZXRkb2Mob2JqZWN0KSwgc2VsZi5wcmVmb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3MsIGNsYXNzZXMsIG1kaWN0KQogICAgICAgIGlmIGRvYzogZG9jID0gJzxzbWFsbD48dHQ+JyArIGRvYyArICc8L3R0Pjwvc21hbGw+JwogICAgICAgIHJldHVybiBzZWxmLnNlY3Rpb24odGl0bGUsICcjMDAwMDAwJywgJyNmZmM4ZDgnLCBjb250ZW50cywgMTAsIGRvYykKCiAgICBkZWYgZm9ybWF0dmFsdWUoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJGb3JtYXQgYW4gYXJndW1lbnQgZGVmYXVsdCB2YWx1ZSBhcyB0ZXh0LiIiIgogICAgICAgIHJldHVybiAoJzxzbWFsbD48Zm9udCBjb2xvcj0iIzkwOTA5MCI+PSVzPC9mb250Pjwvc21hbGw+JyAlCiAgICAgICAgICAgICAgICBzZWxmLnJlcHIob2JqZWN0KSkKCiAgICBkZWYgZG9jcm91dGluZShzZWxmLCBvYmplY3QsIGZ1bmNzPXt9LCBjbGFzc2VzPXt9LCBtZXRob2RzPXt9LCBjbG5hbWU9JycpOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIGZ1bmN0aW9uIG9yIG1ldGhvZCBvYmplY3QuIiIiCiAgICAgICAgaWYgaW5zcGVjdC5pc21ldGhvZChvYmplY3QpOiBvYmplY3QgPSBvYmplY3QuaW1fZnVuYwogICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKG9iamVjdCk6CiAgICAgICAgICAgIGRlY2wgPSAnPGEgbmFtZT0iJXMiPjxzdHJvbmc+JXM8L3N0cm9uZz4oLi4uKTwvYT5cbicgJSAoCiAgICAgICAgICAgICAgICBjbG5hbWUgKyAnLScgKyBvYmplY3QuX19uYW1lX18sIG9iamVjdC5fX25hbWVfXykKICAgICAgICBlbHNlOgogICAgICAgICAgICBhcmdzLCB2YXJhcmdzLCB2YXJrdywgZGVmYXVsdHMgPSBpbnNwZWN0LmdldGFyZ3NwZWMob2JqZWN0KQogICAgICAgICAgICBhcmdzcGVjID0gaW5zcGVjdC5mb3JtYXRhcmdzcGVjKAogICAgICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzLCBmb3JtYXR2YWx1ZT1zZWxmLmZvcm1hdHZhbHVlKQoKICAgICAgICAgICAgaWYgb2JqZWN0Ll9fbmFtZV9fID09ICc8bGFtYmRhPic6CiAgICAgICAgICAgICAgICBkZWNsID0gJzxlbT5sYW1iZGE8L2VtPiAnICsgYXJnc3BlY1sxOi0xXQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgYW5jaG9yID0gY2xuYW1lICsgJy0nICsgb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgICAgICAgICBkZWNsID0gJzxhIG5hbWU9IiVzIlxuPjxzdHJvbmc+JXM8L3N0cm9uZz4lczwvYT5cbicgJSAoCiAgICAgICAgICAgICAgICAgICAgYW5jaG9yLCBvYmplY3QuX19uYW1lX18sIGFyZ3NwZWMpCiAgICAgICAgZG9jID0gc2VsZi5tYXJrdXAoZ2V0ZG9jKG9iamVjdCksIHNlbGYucHJlZm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmNzLCBjbGFzc2VzLCBtZXRob2RzKQogICAgICAgIGRvYyA9IHJlcGxhY2UoZG9jLCAoJzxicj5cbicsICc8L3R0Pjwvc21hbGxcbj48ZGQ+PHNtYWxsPjx0dD4nKSkKICAgICAgICBkb2MgPSBkb2MgYW5kICc8dHQ+JXM8L3R0PicgJSBkb2MKICAgICAgICByZXR1cm4gJzxkbD48ZHQ+JXM8ZGQ+PHNtYWxsPiVzPC9zbWFsbD48L2RsPicgJSAoZGVjbCwgZG9jKQoKICAgIGRlZiBwYWdlKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiUHJvZHVjZSBhIGNvbXBsZXRlIEhUTUwgcGFnZSBvZiBkb2N1bWVudGF0aW9uIGZvciBhbiBvYmplY3QuIiIiCiAgICAgICAgcmV0dXJuICcnJwo8IWRvY3R5cGUgaHRtbCBwdWJsaWMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgo8aHRtbD48dGl0bGU+UHl0aG9uOiAlczwvdGl0bGU+PGJvZHkgYmdjb2xvcj0iI2ZmZmZmZiI+CiVzCjwvYm9keT48L2h0bWw+CicnJyAlIChkZXNjcmliZShvYmplY3QpLCBzZWxmLmRvY3VtZW50KG9iamVjdCkpCgogICAgZGVmIGluZGV4KHNlbGYsIGRpciwgc2hhZG93ZWQ9Tm9uZSk6CiAgICAgICAgIiIiR2VuZXJhdGUgYW4gSFRNTCBpbmRleCBmb3IgYSBkaXJlY3Rvcnkgb2YgbW9kdWxlcy4iIiIKICAgICAgICBtb2Rwa2dzID0gW10KICAgICAgICBpZiBzaGFkb3dlZCBpcyBOb25lOiBzaGFkb3dlZCA9IHt9CiAgICAgICAgc2VlbiA9IHt9CiAgICAgICAgZmlsZXMgPSBvcy5saXN0ZGlyKGRpcikKCiAgICAgICAgZGVmIGZvdW5kKG5hbWUsIGlzcGFja2FnZSwKICAgICAgICAgICAgICAgICAgbW9kcGtncz1tb2Rwa2dzLCBzaGFkb3dlZD1zaGFkb3dlZCwgc2Vlbj1zZWVuKToKICAgICAgICAgICAgaWYgbm90IHNlZW4uaGFzX2tleShuYW1lKToKICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKChuYW1lLCAnJywgaXNwYWNrYWdlLCBzaGFkb3dlZC5oYXNfa2V5KG5hbWUpKSkKICAgICAgICAgICAgICAgIHNlZW5bbmFtZV0gPSAxCiAgICAgICAgICAgICAgICBzaGFkb3dlZFtuYW1lXSA9IDEKCiAgICAgICAgIyBQYWNrYWdlIHNwYW0vX19pbml0X18ucHkgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIG1vZHVsZSBzcGFtLnB5LgogICAgICAgIGZvciBmaWxlIGluIGZpbGVzOgogICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKGRpciwgZmlsZSkKICAgICAgICAgICAgaWYgaXNwYWNrYWdlKHBhdGgpOiBmb3VuZChmaWxlLCAxKQogICAgICAgIGZvciBmaWxlIGluIGZpbGVzOgogICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKGRpciwgZmlsZSkKICAgICAgICAgICAgaWYgZmlsZVs6MV0gIT0gJ18nIGFuZCBvcy5wYXRoLmlzZmlsZShwYXRoKToKICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBtb2R1bGVuYW1lKGZpbGUpCiAgICAgICAgICAgICAgICBpZiBtb2RuYW1lOiBmb3VuZChtb2RuYW1lLCAwKQoKICAgICAgICBtb2Rwa2dzLnNvcnQoKQogICAgICAgIGNvbnRlbnRzID0gc2VsZi5tdWx0aWNvbHVtbihtb2Rwa2dzLCBzZWxmLm1vZHBrZ2xpbmspCiAgICAgICAgcmV0dXJuIHNlbGYuYmlnc2VjdGlvbihkaXIsICcjZmZmZmZmJywgJyNlZTc3YWEnLCBjb250ZW50cykKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdGV4dCBkb2N1bWVudGF0aW9uIGdlbmVyYXRvcgoKY2xhc3MgVGV4dFJlcHIoUmVwcik6CiAgICAiIiJDbGFzcyBmb3Igc2FmZWx5IG1ha2luZyBhIHRleHQgcmVwcmVzZW50YXRpb24gb2YgYSBQeXRob24gb2JqZWN0LiIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIFJlcHIuX19pbml0X18oc2VsZikKICAgICAgICBzZWxmLm1heGxpc3QgPSBzZWxmLm1heHR1cGxlID0gc2VsZi5tYXhkaWN0ID0gMTAKICAgICAgICBzZWxmLm1heHN0cmluZyA9IHNlbGYubWF4b3RoZXIgPSA1MAoKICAgIGRlZiByZXByMShzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgbWV0aG9kbmFtZSA9ICdyZXByXycgKyBqb2luKHNwbGl0KHR5cGUoeCkuX19uYW1lX18pLCAnXycpCiAgICAgICAgaWYgaGFzYXR0cihzZWxmLCBtZXRob2RuYW1lKToKICAgICAgICAgICAgcmV0dXJuIGdldGF0dHIoc2VsZiwgbWV0aG9kbmFtZSkoeCwgbGV2ZWwpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIGNyYW0oc3RyaXBpZChyZXByKHgpKSwgc2VsZi5tYXhvdGhlcikKCiAgICBkZWYgcmVwcl9pbnN0YW5jZShzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXR1cm4gY3JhbShzdHJpcGlkKHJlcHIoeCkpLCBzZWxmLm1heHN0cmluZykKICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIHJldHVybiAnPCVzIGluc3RhbmNlPicgJSB4Ll9fY2xhc3NfXy5fX25hbWVfXwoKY2xhc3MgVGV4dERvYyhEb2MpOgogICAgIiIiRm9ybWF0dGVyIGNsYXNzIGZvciB0ZXh0IGRvY3VtZW50YXRpb24uIiIiCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHRleHQgZm9ybWF0dGluZyB1dGlsaXRpZXMKCiAgICBfcmVwcl9pbnN0YW5jZSA9IFRleHRSZXByKCkKICAgIHJlcHIgPSBfcmVwcl9pbnN0YW5jZS5yZXByCgogICAgZGVmIGJvbGQoc2VsZiwgdGV4dCk6CiAgICAgICAgIiIiRm9ybWF0IGEgc3RyaW5nIGluIGJvbGQgYnkgb3ZlcnN0cmlraW5nLiIiIgogICAgICAgIHJldHVybiBqb2luKG1hcChsYW1iZGEgY2g6IGNoICsgJ1xiJyArIGNoLCB0ZXh0KSwgJycpCgogICAgZGVmIGluZGVudChzZWxmLCB0ZXh0LCBwcmVmaXg9JyAgICAnKToKICAgICAgICAiIiJJbmRlbnQgdGV4dCBieSBwcmVwZW5kaW5nIGEgZ2l2ZW4gcHJlZml4IHRvIGVhY2ggbGluZS4iIiIKICAgICAgICBpZiBub3QgdGV4dDogcmV0dXJuICcnCiAgICAgICAgbGluZXMgPSBzcGxpdCh0ZXh0LCAnXG4nKQogICAgICAgIGxpbmVzID0gbWFwKGxhbWJkYSBsaW5lLCBwcmVmaXg9cHJlZml4OiBwcmVmaXggKyBsaW5lLCBsaW5lcykKICAgICAgICBpZiBsaW5lczogbGluZXNbLTFdID0gcnN0cmlwKGxpbmVzWy0xXSkKICAgICAgICByZXR1cm4gam9pbihsaW5lcywgJ1xuJykKCiAgICBkZWYgc2VjdGlvbihzZWxmLCB0aXRsZSwgY29udGVudHMpOgogICAgICAgICIiIkZvcm1hdCBhIHNlY3Rpb24gd2l0aCBhIGdpdmVuIGhlYWRpbmcuIiIiCiAgICAgICAgcmV0dXJuIHNlbGYuYm9sZCh0aXRsZSkgKyAnXG4nICsgcnN0cmlwKHNlbGYuaW5kZW50KGNvbnRlbnRzKSkgKyAnXG5cbicKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdHlwZS1zcGVjaWZpYyByb3V0aW5lcwoKICAgIGRlZiBkb2N0cmVlKHNlbGYsIHRyZWUsIG1vZG5hbWUsIHBhcmVudD1Ob25lLCBwcmVmaXg9JycpOgogICAgICAgICIiIlJlbmRlciBpbiB0ZXh0IGEgY2xhc3MgdHJlZSBhcyByZXR1cm5lZCBieSBpbnNwZWN0LmdldGNsYXNzdHJlZSgpLiIiIgogICAgICAgIHJlc3VsdCA9ICcnCiAgICAgICAgZm9yIGVudHJ5IGluIHRyZWU6CiAgICAgICAgICAgIGlmIHR5cGUoZW50cnkpIGlzIHR5cGUoKCkpOgogICAgICAgICAgICAgICAgY2wsIGJhc2VzID0gZW50cnkKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHByZWZpeCArIGNsYXNzbmFtZShjbCwgbW9kbmFtZSkKICAgICAgICAgICAgICAgIGlmIGJhc2VzIGFuZCBiYXNlcyAhPSAocGFyZW50LCk6CiAgICAgICAgICAgICAgICAgICAgcGFyZW50cyA9IG1hcChsYW1iZGEgY2wsIG09bW9kbmFtZTogY2xhc3NuYW1lKGNsLCBtKSwgYmFzZXMpCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJyglcyknICUgam9pbihwYXJlbnRzLCAnLCAnKQogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJ1xuJwogICAgICAgICAgICBlbGlmIHR5cGUoZW50cnkpIGlzIHR5cGUoW10pOgogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5kb2N0cmVlKAogICAgICAgICAgICAgICAgICAgIGVudHJ5LCBtb2RuYW1lLCBjbCwgcHJlZml4ICsgJyAgICAnKQogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBkZWYgZG9jbW9kdWxlKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiUHJvZHVjZSB0ZXh0IGRvY3VtZW50YXRpb24gZm9yIGEgZ2l2ZW4gbW9kdWxlIG9iamVjdC4iIiIKICAgICAgICByZXN1bHQgPSAnJwoKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgbGluZXMgPSBzcGxpdChzdHJpcChnZXRkb2Mob2JqZWN0KSksICdcbicpCiAgICAgICAgaWYgbGVuKGxpbmVzKSA9PSAxOgogICAgICAgICAgICBpZiBsaW5lc1swXTogbmFtZSA9IG5hbWUgKyAnIC0gJyArIGxpbmVzWzBdCiAgICAgICAgICAgIGxpbmVzID0gW10KICAgICAgICBlbGlmIGxlbihsaW5lcykgPj0gMiBhbmQgbm90IHJzdHJpcChsaW5lc1sxXSk6CiAgICAgICAgICAgIGlmIGxpbmVzWzBdOiBuYW1lID0gbmFtZSArICcgLSAnICsgbGluZXNbMF0KICAgICAgICAgICAgbGluZXMgPSBsaW5lc1syOl0KICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ05BTUUnLCBuYW1lKQogICAgICAgIHRyeTogZmlsZSA9IGluc3BlY3QuZ2V0ZmlsZShvYmplY3QpICMgWFhYIG9yIGdldHNvdXJjZWZpbGU/CiAgICAgICAgZXhjZXB0IFR5cGVFcnJvcjogZmlsZSA9IE5vbmUKICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0ZJTEUnLCBmaWxlIG9yICcoYnVpbHQtaW4pJykKICAgICAgICBpZiBsaW5lczoKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdERVNDUklQVElPTicsIGpvaW4obGluZXMsICdcbicpKQoKICAgICAgICBjbGFzc2VzID0gW10KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0LmlzY2xhc3MpOgogICAgICAgICAgICBpZiAoaW5zcGVjdC5nZXRtb2R1bGUodmFsdWUpIG9yIG9iamVjdCkgaXMgb2JqZWN0OgogICAgICAgICAgICAgICAgY2xhc3Nlcy5hcHBlbmQodmFsdWUpCiAgICAgICAgZnVuY3MgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNyb3V0aW5lKToKICAgICAgICAgICAgaWYgaW5zcGVjdC5pc2J1aWx0aW4odmFsdWUpIG9yIGluc3BlY3QuZ2V0bW9kdWxlKHZhbHVlKSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBmdW5jcy5hcHBlbmQodmFsdWUpCiAgICAgICAgY29uc3RhbnRzID0gW10KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpc2NvbnN0YW50KToKICAgICAgICAgICAgaWYga2V5WzoxXSAhPSAnXyc6CiAgICAgICAgICAgICAgICBjb25zdGFudHMuYXBwZW5kKChrZXksIHZhbHVlKSkKCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX3BhdGhfXycpOgogICAgICAgICAgICBtb2Rwa2dzID0gW10KICAgICAgICAgICAgZm9yIGZpbGUgaW4gb3MubGlzdGRpcihvYmplY3QuX19wYXRoX19bMF0pOgogICAgICAgICAgICAgICAgaWYgZmlsZVs6MV0gIT0gJ18nOgogICAgICAgICAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4ob2JqZWN0Ll9fcGF0aF9fWzBdLCBmaWxlKQogICAgICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBtb2R1bGVuYW1lKGZpbGUpCiAgICAgICAgICAgICAgICAgICAgaWYgbW9kbmFtZSBhbmQgbW9kbmFtZSBub3QgaW4gbW9kcGtnczoKICAgICAgICAgICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQobW9kbmFtZSkKICAgICAgICAgICAgICAgICAgICBlbGlmIGlzcGFja2FnZShwYXRoKToKICAgICAgICAgICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQoZmlsZSArICcgKHBhY2thZ2UpJykKICAgICAgICAgICAgbW9kcGtncy5zb3J0KCkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKAogICAgICAgICAgICAgICAgJ1BBQ0tBR0UgQ09OVEVOVFMnLCBqb2luKG1vZHBrZ3MsICdcbicpKQoKICAgICAgICBpZiBjbGFzc2VzOgogICAgICAgICAgICBjb250ZW50cyA9IHNlbGYuZG9jdHJlZSgKICAgICAgICAgICAgICAgIGluc3BlY3QuZ2V0Y2xhc3N0cmVlKGNsYXNzZXMsIDEpLCBvYmplY3QuX19uYW1lX18pICsgJ1xuJwogICAgICAgICAgICBmb3IgaXRlbSBpbiBjbGFzc2VzOgogICAgICAgICAgICAgICAgY29udGVudHMgPSBjb250ZW50cyArIHNlbGYuZG9jdW1lbnQoaXRlbSkgKyAnXG4nCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignQ0xBU1NFUycsIGNvbnRlbnRzKQoKICAgICAgICBpZiBmdW5jczoKICAgICAgICAgICAgY29udGVudHMgPSAnJwogICAgICAgICAgICBmb3IgaXRlbSBpbiBmdW5jczoKICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gY29udGVudHMgKyBzZWxmLmRvY3VtZW50KGl0ZW0pICsgJ1xuJwogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0ZVTkNUSU9OUycsIGNvbnRlbnRzKQoKICAgICAgICBpZiBjb25zdGFudHM6CiAgICAgICAgICAgIGNvbnRlbnRzID0gJycKICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gY29uc3RhbnRzOgogICAgICAgICAgICAgICAgbGluZSA9IGtleSArICcgPSAnICsgc2VsZi5yZXByKHZhbHVlKQogICAgICAgICAgICAgICAgY2hvcCA9IDcwIC0gbGVuKGxpbmUpCiAgICAgICAgICAgICAgICBsaW5lID0gc2VsZi5ib2xkKGtleSkgKyAnID0gJyArIHNlbGYucmVwcih2YWx1ZSkKICAgICAgICAgICAgICAgIGlmIGNob3AgPCAwOiBsaW5lID0gbGluZVs6Y2hvcF0gKyAnLi4uJwogICAgICAgICAgICAgICAgY29udGVudHMgPSBjb250ZW50cyArIGxpbmUgKyAnXG4nCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignQ09OU1RBTlRTJywgY29udGVudHMpCgogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX192ZXJzaW9uX18nKToKICAgICAgICAgICAgdmVyc2lvbiA9IHN0cihvYmplY3QuX192ZXJzaW9uX18pCiAgICAgICAgICAgIGlmIHZlcnNpb25bOjExXSA9PSAnJCcgKyAnUmV2aXNpb246ICcgYW5kIHZlcnNpb25bLTE6XSA9PSAnJCc6CiAgICAgICAgICAgICAgICB2ZXJzaW9uID0gc3RyaXAodmVyc2lvblsxMTotMV0pCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignVkVSU0lPTicsIHZlcnNpb24pCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2RhdGVfXycpOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0RBVEUnLCBzdHIob2JqZWN0Ll9fZGF0ZV9fKSkKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fYXV0aG9yX18nKToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdBVVRIT1InLCBzdHIob2JqZWN0Ll9fYXV0aG9yX18pKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19jcmVkaXRzX18nKToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdDUkVESVRTJywgc3RyKG9iamVjdC5fX2NyZWRpdHNfXykpCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBkb2NjbGFzcyhzZWxmLCBvYmplY3QpOgogICAgICAgICIiIlByb2R1Y2UgdGV4dCBkb2N1bWVudGF0aW9uIGZvciBhIGdpdmVuIGNsYXNzIG9iamVjdC4iIiIKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgYmFzZXMgPSBvYmplY3QuX19iYXNlc19fCgogICAgICAgIHRpdGxlID0gJ2NsYXNzICcgKyBzZWxmLmJvbGQobmFtZSkKICAgICAgICBpZiBiYXNlczoKICAgICAgICAgICAgcGFyZW50cyA9IG1hcChsYW1iZGEgYywgbT1vYmplY3QuX19tb2R1bGVfXzogY2xhc3NuYW1lKGMsIG0pLCBiYXNlcykKICAgICAgICAgICAgdGl0bGUgPSB0aXRsZSArICcoJXMpJyAlIGpvaW4ocGFyZW50cywgJywgJykKCiAgICAgICAgZG9jID0gZ2V0ZG9jKG9iamVjdCkKICAgICAgICBjb250ZW50cyA9IGRvYyBhbmQgZG9jICsgJ1xuJwogICAgICAgIG1ldGhvZHMgPSBtYXAobGFtYmRhIChrZXksIHZhbHVlKTogdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0LmlzbWV0aG9kKSkKICAgICAgICBmb3IgaXRlbSBpbiBtZXRob2RzOgogICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgJ1xuJyArIHNlbGYuZG9jdW1lbnQoaXRlbSkKCiAgICAgICAgaWYgbm90IGNvbnRlbnRzOiByZXR1cm4gdGl0bGUgKyAnXG4nCiAgICAgICAgcmV0dXJuIHRpdGxlICsgJ1xuJyArIHNlbGYuaW5kZW50KHJzdHJpcChjb250ZW50cyksICcgfCAgJykgKyAnXG4nCgogICAgZGVmIGZvcm1hdHZhbHVlKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiRm9ybWF0IGFuIGFyZ3VtZW50IGRlZmF1bHQgdmFsdWUgYXMgdGV4dC4iIiIKICAgICAgICByZXR1cm4gJz0nICsgc2VsZi5yZXByKG9iamVjdCkKCiAgICBkZWYgZG9jcm91dGluZShzZWxmLCBvYmplY3QpOgogICAgICAgICIiIlByb2R1Y2UgdGV4dCBkb2N1bWVudGF0aW9uIGZvciBhIGZ1bmN0aW9uIG9yIG1ldGhvZCBvYmplY3QuIiIiCiAgICAgICAgaWYgaW5zcGVjdC5pc21ldGhvZChvYmplY3QpOiBvYmplY3QgPSBvYmplY3QuaW1fZnVuYwogICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKG9iamVjdCk6CiAgICAgICAgICAgIGRlY2wgPSBzZWxmLmJvbGQob2JqZWN0Ll9fbmFtZV9fKSArICcoLi4uKScKICAgICAgICBlbHNlOgogICAgICAgICAgICBhcmdzLCB2YXJhcmdzLCB2YXJrdywgZGVmYXVsdHMgPSBpbnNwZWN0LmdldGFyZ3NwZWMob2JqZWN0KQogICAgICAgICAgICBhcmdzcGVjID0gaW5zcGVjdC5mb3JtYXRhcmdzcGVjKAogICAgICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzLCBmb3JtYXR2YWx1ZT1zZWxmLmZvcm1hdHZhbHVlKQogICAgICAgICAgICBpZiBvYmplY3QuX19uYW1lX18gPT0gJzxsYW1iZGE+JzoKICAgICAgICAgICAgICAgIGRlY2wgPSAnPGxhbWJkYT4gJyArIGFyZ3NwZWNbMTotMV0KICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGRlY2wgPSBzZWxmLmJvbGQob2JqZWN0Ll9fbmFtZV9fKSArIGFyZ3NwZWMKICAgICAgICBkb2MgPSBnZXRkb2Mob2JqZWN0KQogICAgICAgIGlmIGRvYzoKICAgICAgICAgICAgcmV0dXJuIGRlY2wgKyAnXG4nICsgcnN0cmlwKHNlbGYuaW5kZW50KGRvYykpICsgJ1xuJwogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBkZWNsICsgJ1xuJwoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdXNlciBpbnRlcmZhY2VzCgpkZWYgcGFnZXIodGV4dCk6CiAgICAiIiJUaGUgZmlyc3QgdGltZSB0aGlzIGlzIGNhbGxlZCwgZGV0ZXJtaW5lIHdoYXQga2luZCBvZiBwYWdlciB0byB1c2UuIiIiCiAgICBnbG9iYWwgcGFnZXIKICAgIHBhZ2VyID0gZ2V0cGFnZXIoKQogICAgcGFnZXIodGV4dCkKCmRlZiBnZXRwYWdlcigpOgogICAgIiIiRGVjaWRlIHdoYXQgbWV0aG9kIHRvIHVzZSBmb3IgcGFnaW5nIHRocm91Z2ggdGV4dC4iIiIKICAgIGlmIHR5cGUoc3lzLnN0ZG91dCkgaXMgbm90IHR5cGVzLkZpbGVUeXBlOgogICAgICAgIHJldHVybiBwbGFpbnBhZ2VyCiAgICBpZiBub3Qgc3lzLnN0ZGluLmlzYXR0eSgpIG9yIG5vdCBzeXMuc3Rkb3V0LmlzYXR0eSgpOgogICAgICAgIHJldHVybiBwbGFpbnBhZ2VyCiAgICBpZiBvcy5lbnZpcm9uLmhhc19rZXkoJ1BBR0VSJyk6CiAgICAgICAgcmV0dXJuIGxhbWJkYSBhOiBwaXBlcGFnZXIoYSwgb3MuZW52aXJvblsnUEFHRVInXSkKICAgIGlmIHN5cy5wbGF0Zm9ybSBpbiBbJ3dpbicsICd3aW4zMicsICdudCddOgogICAgICAgIHJldHVybiBsYW1iZGEgYTogdGVtcGZpbGVwYWdlcihhLCAnbW9yZScpCiAgICBpZiBoYXNhdHRyKG9zLCAnc3lzdGVtJykgYW5kIG9zLnN5c3RlbSgnbGVzcyAyPi9kZXYvbnVsbCcpID09IDA6CiAgICAgICAgcmV0dXJuIGxhbWJkYSBhOiBwaXBlcGFnZXIoYSwgJ2xlc3MnKQoKICAgIGltcG9ydCB0ZW1wZmlsZQogICAgZmlsZW5hbWUgPSB0ZW1wZmlsZS5ta3RlbXAoKQogICAgb3BlbihmaWxlbmFtZSwgJ3cnKS5jbG9zZSgpCiAgICB0cnk6CiAgICAgICAgaWYgaGFzYXR0cihvcywgJ3N5c3RlbScpIGFuZCBvcy5zeXN0ZW0oJ21vcmUgJXMnICUgZmlsZW5hbWUpID09IDA6CiAgICAgICAgICAgIHJldHVybiBsYW1iZGEgdGV4dDogcGlwZXBhZ2VyKHRleHQsICdtb3JlJykKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gdHR5cGFnZXIKICAgIGZpbmFsbHk6CiAgICAgICAgb3MudW5saW5rKGZpbGVuYW1lKQoKZGVmIHBpcGVwYWdlcih0ZXh0LCBjbWQpOgogICAgIiIiUGFnZSB0aHJvdWdoIHRleHQgYnkgZmVlZGluZyBpdCB0byBhbm90aGVyIHByb2dyYW0uIiIiCiAgICBwaXBlID0gb3MucG9wZW4oY21kLCAndycpCiAgICB0cnk6CiAgICAgICAgcGlwZS53cml0ZSh0ZXh0KQogICAgICAgIHBpcGUuY2xvc2UoKQogICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgIyBJZ25vcmUgYnJva2VuIHBpcGVzIGNhdXNlZCBieSBxdWl0dGluZyB0aGUgcGFnZXIgcHJvZ3JhbS4KICAgICAgICBwYXNzCgpkZWYgdGVtcGZpbGVwYWdlcih0ZXh0LCBjbWQpOgogICAgIiIiUGFnZSB0aHJvdWdoIHRleHQgYnkgaW52b2tpbmcgYSBwcm9ncmFtIG9uIGEgdGVtcG9yYXJ5IGZpbGUuIiIiCiAgICBpbXBvcnQgdGVtcGZpbGUKICAgIGZpbGVuYW1lID0gdGVtcGZpbGUubWt0ZW1wKCkKICAgIGZpbGUgPSBvcGVuKGZpbGVuYW1lLCAndycpCiAgICBmaWxlLndyaXRlKHRleHQpCiAgICBmaWxlLmNsb3NlKCkKICAgIHRyeToKICAgICAgICBvcy5zeXN0ZW0oY21kICsgJyAnICsgZmlsZW5hbWUpCiAgICBmaW5hbGx5OgogICAgICAgIG9zLnVubGluayhmaWxlbmFtZSkKCmRlZiBwbGFpbih0ZXh0KToKICAgICIiIlJlbW92ZSBib2xkZmFjZSBmb3JtYXR0aW5nIGZyb20gdGV4dC4iIiIKICAgIHJldHVybiByZS5zdWIoJy5cYicsICcnLCB0ZXh0KQoKZGVmIHR0eXBhZ2VyKHRleHQpOgogICAgIiIiUGFnZSB0aHJvdWdoIHRleHQgb24gYSB0ZXh0IHRlcm1pbmFsLiIiIgogICAgbGluZXMgPSBzcGxpdChwbGFpbih0ZXh0KSwgJ1xuJykKICAgIHRyeToKICAgICAgICBpbXBvcnQgdHR5CiAgICAgICAgZmQgPSBzeXMuc3RkaW4uZmlsZW5vKCkKICAgICAgICBvbGQgPSB0dHkudGNnZXRhdHRyKGZkKQogICAgICAgIHR0eS5zZXRjYnJlYWsoZmQpCiAgICAgICAgZ2V0Y2hhciA9IGxhbWJkYTogc3lzLnN0ZGluLnJlYWQoMSkKICAgIGV4Y2VwdCAoSW1wb3J0RXJyb3IsIEF0dHJpYnV0ZUVycm9yKToKICAgICAgICB0dHkgPSBOb25lCiAgICAgICAgZ2V0Y2hhciA9IGxhbWJkYTogc3lzLnN0ZGluLnJlYWRsaW5lKClbOi0xXVs6MV0KCiAgICB0cnk6CiAgICAgICAgciA9IGluYyA9IG9zLmVudmlyb24uZ2V0KCdMSU5FUycsIDI1KSAtIDEKICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKGpvaW4obGluZXNbOmluY10sICdcbicpICsgJ1xuJykKICAgICAgICB3aGlsZSBsaW5lc1tyOl06CiAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoJy0tIG1vcmUgLS0nKQogICAgICAgICAgICBzeXMuc3Rkb3V0LmZsdXNoKCkKICAgICAgICAgICAgYyA9IGdldGNoYXIoKQoKICAgICAgICAgICAgaWYgYyBpbiBbJ3EnLCAnUSddOgogICAgICAgICAgICAgICAgc3lzLnN0ZG91dC53cml0ZSgnXHIgICAgICAgICAgXHInKQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgZWxpZiBjIGluIFsnXHInLCAnXG4nXToKICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoJ1xyICAgICAgICAgIFxyJyArIGxpbmVzW3JdICsgJ1xuJykKICAgICAgICAgICAgICAgIHIgPSByICsgMQogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgaWYgYyBpbiBbJ2InLCAnQicsICdceDFiJ106CiAgICAgICAgICAgICAgICByID0gciAtIGluYyAtIGluYwogICAgICAgICAgICAgICAgaWYgciA8IDA6IHIgPSAwCiAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoJ1xuJyArIGpvaW4obGluZXNbcjpyK2luY10sICdcbicpICsgJ1xuJykKICAgICAgICAgICAgciA9IHIgKyBpbmMKCiAgICBmaW5hbGx5OgogICAgICAgIGlmIHR0eToKICAgICAgICAgICAgdHR5LnRjc2V0YXR0cihmZCwgdHR5LlRDU0FGTFVTSCwgb2xkKQoKZGVmIHBsYWlucGFnZXIodGV4dCk6CiAgICAiIiJTaW1wbHkgcHJpbnQgdW5mb3JtYXR0ZWQgdGV4dC4gIFRoaXMgaXMgdGhlIHVsdGltYXRlIGZhbGxiYWNrLiIiIgogICAgc3lzLnN0ZG91dC53cml0ZShwbGFpbih0ZXh0KSkKCmRlZiBkZXNjcmliZSh0aGluZyk6CiAgICAiIiJQcm9kdWNlIGEgc2hvcnQgZGVzY3JpcHRpb24gb2YgdGhlIGdpdmVuIGtpbmQgb2YgdGhpbmcuIiIiCiAgICBpZiBpbnNwZWN0LmlzbW9kdWxlKHRoaW5nKToKICAgICAgICBpZiB0aGluZy5fX25hbWVfXyBpbiBzeXMuYnVpbHRpbl9tb2R1bGVfbmFtZXM6CiAgICAgICAgICAgIHJldHVybiAnYnVpbHQtaW4gbW9kdWxlICcgKyB0aGluZy5fX25hbWVfXwogICAgICAgIGlmIGhhc2F0dHIodGhpbmcsICdfX3BhdGhfXycpOgogICAgICAgICAgICByZXR1cm4gJ3BhY2thZ2UgJyArIHRoaW5nLl9fbmFtZV9fCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuICdtb2R1bGUgJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiBpbnNwZWN0LmlzYnVpbHRpbih0aGluZyk6CiAgICAgICAgcmV0dXJuICdidWlsdC1pbiBmdW5jdGlvbiAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIGluc3BlY3QuaXNjbGFzcyh0aGluZyk6CiAgICAgICAgcmV0dXJuICdjbGFzcyAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIGluc3BlY3QuaXNmdW5jdGlvbih0aGluZyk6CiAgICAgICAgcmV0dXJuICdmdW5jdGlvbiAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIGluc3BlY3QuaXNtZXRob2QodGhpbmcpOgogICAgICAgIHJldHVybiAnbWV0aG9kICcgKyB0aGluZy5fX25hbWVfXwogICAgcmV0dXJuIHJlcHIodGhpbmcpCgpkZWYgbG9jYXRlKHBhdGgpOgogICAgIiIiTG9jYXRlIGFuIG9iamVjdCBieSBuYW1lIChvciBkb3R0ZWQgcGF0aCksIGltcG9ydGluZyBhcyBuZWNlc3NhcnkuIiIiCiAgICBpZiBub3QgcGF0aDogIyBzcGVjaWFsIGNhc2U6IGltcC5maW5kX21vZHVsZSgnJykgc3RyYW5nZWx5IHN1Y2NlZWRzCiAgICAgICAgcmV0dXJuIE5vbmUsIE5vbmUKICAgIGlmIHR5cGUocGF0aCkgaXMgbm90IHR5cGVzLlN0cmluZ1R5cGU6CiAgICAgICAgcmV0dXJuIE5vbmUsIHBhdGgKICAgIHBhcnRzID0gc3BsaXQocGF0aCwgJy4nKQogICAgbiA9IDEKICAgIHdoaWxlIG4gPD0gbGVuKHBhcnRzKToKICAgICAgICBwYXRoID0gam9pbihwYXJ0c1s6bl0sICcuJykKICAgICAgICB0cnk6CiAgICAgICAgICAgIG1vZHVsZSA9IF9faW1wb3J0X18ocGF0aCkKICAgICAgICAgICAgbW9kdWxlID0gcmVsb2FkKG1vZHVsZSkKICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICMgZGV0ZXJtaW5lIGlmIGVycm9yIG9jY3VycmVkIGJlZm9yZSBvciBhZnRlciBtb2R1bGUgd2FzIGZvdW5kCiAgICAgICAgICAgIGlmIHN5cy5tb2R1bGVzLmhhc19rZXkocGF0aCk6CiAgICAgICAgICAgICAgICBmaWxlbmFtZSA9IHN5cy5tb2R1bGVzW3BhdGhdLl9fZmlsZV9fCiAgICAgICAgICAgIGVsaWYgc3lzLmV4Y190eXBlIGlzIFN5bnRheEVycm9yOgogICAgICAgICAgICAgICAgZmlsZW5hbWUgPSBzeXMuZXhjX3ZhbHVlLmZpbGVuYW1lCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIG1vZHVsZSBub3QgZm91bmQsIHNvIHN0b3AgbG9va2luZwogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgIyBlcnJvciBvY2N1cnJlZCBpbiB0aGUgaW1wb3J0ZWQgbW9kdWxlLCBzbyByZXBvcnQgaXQKICAgICAgICAgICAgcmFpc2UgRG9jSW1wb3J0RXJyb3IoZmlsZW5hbWUsIHN5cy5leGNfdHlwZSwgc3lzLmV4Y192YWx1ZSkKICAgICAgICB0cnk6CiAgICAgICAgICAgIHggPSBtb2R1bGUKICAgICAgICAgICAgZm9yIHAgaW4gcGFydHNbMTpdOgogICAgICAgICAgICAgICAgeCA9IGdldGF0dHIoeCwgcCkKICAgICAgICAgICAgcmV0dXJuIGpvaW4ocGFydHNbOi0xXSwgJy4nKSwgeAogICAgICAgIGV4Y2VwdCBBdHRyaWJ1dGVFcnJvcjoKICAgICAgICAgICAgbiA9IG4gKyAxCiAgICAgICAgICAgIGNvbnRpbnVlCiAgICBpZiBoYXNhdHRyKF9fYnVpbHRpbnNfXywgcGF0aCk6CiAgICAgICAgcmV0dXJuIE5vbmUsIGdldGF0dHIoX19idWlsdGluc19fLCBwYXRoKQogICAgcmV0dXJuIE5vbmUsIE5vbmUKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGludGVyYWN0aXZlIGludGVycHJldGVyIGludGVyZmFjZQoKdGV4dCA9IFRleHREb2MoKQpodG1sID0gSFRNTERvYygpCgpkZWYgZG9jKHRoaW5nKToKICAgICIiIkRpc3BsYXkgZG9jdW1lbnRhdGlvbiBvbiBhbiBvYmplY3QgKGZvciBpbnRlcmFjdGl2ZSB1c2UpLiIiIgogICAgaWYgdHlwZSh0aGluZykgaXMgdHlwZSgiIik6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBwYXRoLCB4ID0gbG9jYXRlKHRoaW5nKQogICAgICAgIGV4Y2VwdCBEb2NJbXBvcnRFcnJvciwgdmFsdWU6CiAgICAgICAgICAgIHByaW50ICdQcm9ibGVtIGluICVzIC0gJXMnICUgKHZhbHVlLmZpbGVuYW1lLCB2YWx1ZS5hcmdzKQogICAgICAgICAgICByZXR1cm4KICAgICAgICBpZiB4OgogICAgICAgICAgICB0aGluZyA9IHgKICAgICAgICBlbHNlOgogICAgICAgICAgICBwcmludCAnTm8gUHl0aG9uIGRvY3VtZW50YXRpb24gZm91bmQgZm9yICVzLicgJSByZXByKHRoaW5nKQogICAgICAgICAgICByZXR1cm4KCiAgICBkZXNjID0gZGVzY3JpYmUodGhpbmcpCiAgICBtb2R1bGUgPSBpbnNwZWN0LmdldG1vZHVsZSh0aGluZykKICAgIGlmIG1vZHVsZSBhbmQgbW9kdWxlIGlzIG5vdCB0aGluZzoKICAgICAgICBkZXNjID0gZGVzYyArICcgaW4gbW9kdWxlICcgKyBtb2R1bGUuX19uYW1lX18KICAgIHBhZ2VyKCdIZWxwIG9uICVzOlxuXG4nICUgZGVzYyArIHRleHQuZG9jdW1lbnQodGhpbmcpKQoKZGVmIHdyaXRlZG9jKGtleSk6CiAgICAiIiJXcml0ZSBIVE1MIGRvY3VtZW50YXRpb24gdG8gYSBmaWxlIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeS4iIiIKICAgIHBhdGgsIG9iamVjdCA9IGxvY2F0ZShrZXkpCiAgICBpZiBvYmplY3Q6CiAgICAgICAgZmlsZSA9IG9wZW4oa2V5ICsgJy5odG1sJywgJ3cnKQogICAgICAgIGZpbGUud3JpdGUoaHRtbC5wYWdlKG9iamVjdCkpCiAgICAgICAgZmlsZS5jbG9zZSgpCiAgICAgICAgcHJpbnQgJ3dyb3RlJywga2V5ICsgJy5odG1sJwoKY2xhc3MgSGVscGVyOgogICAgZGVmIF9fcmVwcl9fKHNlbGYpOgogICAgICAgIHJldHVybiAiIiJUbyBnZXQgaGVscCBvbiBhIFB5dGhvbiBvYmplY3QsIGNhbGwgaGVscChvYmplY3QpLgpUbyBnZXQgaGVscCBvbiBhIG1vZHVsZSBvciBwYWNrYWdlLCBlaXRoZXIgaW1wb3J0IGl0IGJlZm9yZSBjYWxsaW5nCmhlbHAobW9kdWxlKSBvciBjYWxsIGhlbHAoJ21vZHVsZW5hbWUnKS4iIiIKCiAgICBkZWYgX19jYWxsX18oc2VsZiwgKmFyZ3MpOgogICAgICAgIGlmIGFyZ3M6CiAgICAgICAgICAgIGRvYyhhcmdzWzBdKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHByaW50IHJlcHIoc2VsZikKCmhlbHAgPSBIZWxwZXIoKQoKZGVmIG1hbihrZXkpOgogICAgIiIiRGlzcGxheSBkb2N1bWVudGF0aW9uIG9uIGFuIG9iamVjdCBpbiBhIGZvcm0gc2ltaWxhciB0byBtYW4oMSkuIiIiCiAgICBwYXRoLCBvYmplY3QgPSBsb2NhdGUoa2V5KQogICAgaWYgb2JqZWN0OgogICAgICAgIHRpdGxlID0gJ1B5dGhvbiBMaWJyYXJ5IERvY3VtZW50YXRpb246ICcgKyBkZXNjcmliZShvYmplY3QpCiAgICAgICAgaWYgcGF0aDogdGl0bGUgPSB0aXRsZSArICcgaW4gJyArIHBhdGgKICAgICAgICBwYWdlcignXG4nICsgdGl0bGUgKyAnXG5cbicgKyB0ZXh0LmRvY3VtZW50KG9iamVjdCkpCiAgICAgICAgZm91bmQgPSAxCiAgICBlbHNlOgogICAgICAgIHByaW50ICdObyBQeXRob24gZG9jdW1lbnRhdGlvbiBmb3VuZCBmb3IgJXMuJyAlIHJlcHIoa2V5KQoKY2xhc3MgU2Nhbm5lcjoKICAgICIiIkEgZ2VuZXJpYyB0cmVlIGl0ZXJhdG9yLiIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIHJvb3RzLCBjaGlsZHJlbiwgcmVjdXJzZSk6CiAgICAgICAgc2VsZi5yb290cyA9IHJvb3RzWzpdCiAgICAgICAgc2VsZi5zdGF0ZSA9IFtdCiAgICAgICAgc2VsZi5jaGlsZHJlbiA9IGNoaWxkcmVuCiAgICAgICAgc2VsZi5yZWN1cnNlID0gcmVjdXJzZQoKICAgIGRlZiBuZXh0KHNlbGYpOgogICAgICAgIGlmIG5vdCBzZWxmLnN0YXRlOgogICAgICAgICAgICBpZiBub3Qgc2VsZi5yb290czoKICAgICAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgICAgIHJvb3QgPSBzZWxmLnJvb3RzLnBvcCgwKQogICAgICAgICAgICBzZWxmLnN0YXRlID0gWyhyb290LCBzZWxmLmNoaWxkcmVuKHJvb3QpKV0KICAgICAgICBub2RlLCBjaGlsZHJlbiA9IHNlbGYuc3RhdGVbLTFdCiAgICAgICAgaWYgbm90IGNoaWxkcmVuOgogICAgICAgICAgICBzZWxmLnN0YXRlLnBvcCgpCiAgICAgICAgICAgIHJldHVybiBzZWxmLm5leHQoKQogICAgICAgIGNoaWxkID0gY2hpbGRyZW4ucG9wKDApCiAgICAgICAgaWYgc2VsZi5yZWN1cnNlKGNoaWxkKToKICAgICAgICAgICAgc2VsZi5zdGF0ZS5hcHBlbmQoKGNoaWxkLCBzZWxmLmNoaWxkcmVuKGNoaWxkKSkpCiAgICAgICAgcmV0dXJuIGNoaWxkCgpjbGFzcyBNb2R1bGVTY2FubmVyKFNjYW5uZXIpOgogICAgIiIiQW4gaW50ZXJydXB0aWJsZSBzY2FubmVyIHRoYXQgc2VhcmNoZXMgbW9kdWxlIHN5bm9wc2VzLiIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHJvb3RzID0gbWFwKGxhbWJkYSBkaXI6IChkaXIsICcnKSwgcGF0aGRpcnMoKSkKICAgICAgICBTY2FubmVyLl9faW5pdF9fKHNlbGYsIHJvb3RzLCBzZWxmLnN1Ym1vZHVsZXMsIHNlbGYuaXNwYWNrYWdlKQoKICAgIGRlZiBzdWJtb2R1bGVzKHNlbGYsIChkaXIsIHBhY2thZ2UpKToKICAgICAgICBjaGlsZHJlbiA9IFtdCiAgICAgICAgZm9yIGZpbGUgaW4gb3MubGlzdGRpcihkaXIpOgogICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKGRpciwgZmlsZSkKICAgICAgICAgICAgaWYgaXNwYWNrYWdlKHBhdGgpOiAKICAgICAgICAgICAgICAgIGNoaWxkcmVuLmFwcGVuZCgocGF0aCwgcGFja2FnZSArIChwYWNrYWdlIGFuZCAnLicpICsgZmlsZSkpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBjaGlsZHJlbi5hcHBlbmQoKHBhdGgsIHBhY2thZ2UpKQogICAgICAgIGNoaWxkcmVuLnNvcnQoKQogICAgICAgIHJldHVybiBjaGlsZHJlbgoKICAgIGRlZiBpc3BhY2thZ2Uoc2VsZiwgKGRpciwgcGFja2FnZSkpOgogICAgICAgIHJldHVybiBpc3BhY2thZ2UoZGlyKQoKICAgIGRlZiBydW4oc2VsZiwga2V5LCBjYWxsYmFjaywgY29tcGxldGVyPU5vbmUpOgogICAgICAgIHNlbGYucXVpdCA9IDAKICAgICAgICBzZWVuID0ge30KCiAgICAgICAgZm9yIG1vZG5hbWUgaW4gc3lzLmJ1aWx0aW5fbW9kdWxlX25hbWVzOgogICAgICAgICAgICBzZWVuW21vZG5hbWVdID0gMQogICAgICAgICAgICBkZXNjID0gc3BsaXQoX19pbXBvcnRfXyhtb2RuYW1lKS5fX2RvY19fIG9yICcnLCAnXG4nKVswXQogICAgICAgICAgICBpZiBmaW5kKGxvd2VyKG1vZG5hbWUgKyAnIC0gJyArIGRlc2MpLCBsb3dlcihrZXkpKSA+PSAwOgogICAgICAgICAgICAgICAgY2FsbGJhY2soTm9uZSwgbW9kbmFtZSwgZGVzYykKCiAgICAgICAgd2hpbGUgbm90IHNlbGYucXVpdDoKICAgICAgICAgICAgbm9kZSA9IHNlbGYubmV4dCgpCiAgICAgICAgICAgIGlmIG5vdCBub2RlOiBicmVhawogICAgICAgICAgICBwYXRoLCBwYWNrYWdlID0gbm9kZQogICAgICAgICAgICBtb2RuYW1lID0gbW9kdWxlbmFtZShwYXRoKQogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZmlsZShwYXRoKSBhbmQgbW9kbmFtZToKICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBwYWNrYWdlICsgKHBhY2thZ2UgYW5kICcuJykgKyBtb2RuYW1lCiAgICAgICAgICAgICAgICBpZiBub3Qgc2Vlbi5oYXNfa2V5KG1vZG5hbWUpOgogICAgICAgICAgICAgICAgICAgIHNlZW5bbW9kbmFtZV0gPSAxCiAgICAgICAgICAgICAgICAgICAgZGVzYyA9IHN5bm9wc2lzKHBhdGgpIG9yICcnCiAgICAgICAgICAgICAgICAgICAgaWYgZmluZChsb3dlcihtb2RuYW1lICsgJyAtICcgKyBkZXNjKSwgbG93ZXIoa2V5KSkgPj0gMDoKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2socGF0aCwgbW9kbmFtZSwgZGVzYykKICAgICAgICBpZiBjb21wbGV0ZXI6IGNvbXBsZXRlcigpCgpkZWYgYXByb3BvcyhrZXkpOgogICAgIiIiUHJpbnQgYWxsIHRoZSBvbmUtbGluZSBtb2R1bGUgc3VtbWFyaWVzIHRoYXQgY29udGFpbiBhIHN1YnN0cmluZy4iIiIKICAgIGRlZiBjYWxsYmFjayhwYXRoLCBtb2RuYW1lLCBkZXNjKToKICAgICAgICBpZiBtb2RuYW1lWy05Ol0gPT0gJy5fX2luaXRfXyc6CiAgICAgICAgICAgIG1vZG5hbWUgPSBtb2RuYW1lWzotOV0gKyAnIChwYWNrYWdlKScKICAgICAgICBwcmludCBtb2RuYW1lLCAnLScsIGRlc2Mgb3IgJyhubyBkZXNjcmlwdGlvbiknCiAgICBNb2R1bGVTY2FubmVyKCkucnVuKGtleSwgY2FsbGJhY2spCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB3ZWIgYnJvd3NlciBpbnRlcmZhY2UKCmRlZiBzZXJ2ZShwb3J0LCBjYWxsYmFjaz1Ob25lKToKICAgIGltcG9ydCBCYXNlSFRUUFNlcnZlciwgbWltZXRvb2xzLCBzZWxlY3QKCiAgICAjIFBhdGNoIHVwIG1pbWV0b29scy5NZXNzYWdlIHNvIGl0IGRvZXNuJ3QgYnJlYWsgaWYgcmZjODIyIGlzIHJlbG9hZGVkLgogICAgY2xhc3MgTWVzc2FnZShtaW1ldG9vbHMuTWVzc2FnZSk6CiAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIGZwLCBzZWVrYWJsZT0xKToKICAgICAgICAgICAgTWVzc2FnZSA9IHNlbGYuX19jbGFzc19fCiAgICAgICAgICAgIE1lc3NhZ2UuX19iYXNlc19fWzBdLl9fYmFzZXNfX1swXS5fX2luaXRfXyhzZWxmLCBmcCwgc2Vla2FibGUpCiAgICAgICAgICAgIHNlbGYuZW5jb2RpbmdoZWFkZXIgPSBzZWxmLmdldGhlYWRlcignY29udGVudC10cmFuc2Zlci1lbmNvZGluZycpCiAgICAgICAgICAgIHNlbGYudHlwZWhlYWRlciA9IHNlbGYuZ2V0aGVhZGVyKCdjb250ZW50LXR5cGUnKQogICAgICAgICAgICBzZWxmLnBhcnNldHlwZSgpCiAgICAgICAgICAgIHNlbGYucGFyc2VwbGlzdCgpCgogICAgY2xhc3MgRG9jSGFuZGxlcihCYXNlSFRUUFNlcnZlci5CYXNlSFRUUFJlcXVlc3RIYW5kbGVyKToKICAgICAgICBkZWYgc2VuZF9kb2N1bWVudChzZWxmLCB0aXRsZSwgY29udGVudHMpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWxmLnNlbmRfcmVzcG9uc2UoMjAwKQogICAgICAgICAgICAgICAgc2VsZi5zZW5kX2hlYWRlcignQ29udGVudC1UeXBlJywgJ3RleHQvaHRtbCcpCiAgICAgICAgICAgICAgICBzZWxmLmVuZF9oZWFkZXJzKCkKICAgICAgICAgICAgICAgIHNlbGYud2ZpbGUud3JpdGUoJycnCjwhZG9jdHlwZSBodG1sIHB1YmxpYyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAgVHJhbnNpdGlvbmFsLy9FTiI+CjxodG1sPjx0aXRsZT5QeXRob246ICVzPC90aXRsZT48Ym9keSBiZ2NvbG9yPSIjZmZmZmZmIj4KJXMKPC9ib2R5PjwvaHRtbD4nJycgJSAodGl0bGUsIGNvbnRlbnRzKSkKICAgICAgICAgICAgZXhjZXB0IElPRXJyb3I6IHBhc3MKCiAgICAgICAgZGVmIGRvX0dFVChzZWxmKToKICAgICAgICAgICAgcGF0aCA9IHNlbGYucGF0aAogICAgICAgICAgICBpZiBwYXRoWy01Ol0gPT0gJy5odG1sJzogcGF0aCA9IHBhdGhbOi01XQogICAgICAgICAgICBpZiBwYXRoWzoxXSA9PSAnLyc6IHBhdGggPSBwYXRoWzE6XQogICAgICAgICAgICBpZiBwYXRoIGFuZCBwYXRoICE9ICcuJzoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBwLCB4ID0gbG9jYXRlKHBhdGgpCiAgICAgICAgICAgICAgICBleGNlcHQgRG9jSW1wb3J0RXJyb3IsIHZhbHVlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9kb2N1bWVudChwYXRoLCBodG1sLmVzY2FwZSgKICAgICAgICAgICAgICAgICAgICAgICAgJ1Byb2JsZW0gaW4gJXMgLSAlcycgJSAodmFsdWUuZmlsZW5hbWUsIHZhbHVlLmFyZ3MpKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIGlmIHg6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZW5kX2RvY3VtZW50KGRlc2NyaWJlKHgpLCBodG1sLmRvY3VtZW50KHgpKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLnNlbmRfZG9jdW1lbnQocGF0aCwKJ05vIFB5dGhvbiBkb2N1bWVudGF0aW9uIGZvdW5kIGZvciAlcy4nICUgcmVwcihwYXRoKSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGhlYWRpbmcgPSBodG1sLmhlYWRpbmcoCic8YmlnPjxiaWc+PHN0cm9uZz5QeXRob246IEluZGV4IG9mIE1vZHVsZXM8L3N0cm9uZz48L2JpZz48L2JpZz4nLAonI2ZmZmZmZicsICcjNzc5OWVlJykKICAgICAgICAgICAgICAgIGJ1aWx0aW5zID0gW10KICAgICAgICAgICAgICAgIGZvciBuYW1lIGluIHN5cy5idWlsdGluX21vZHVsZV9uYW1lczoKICAgICAgICAgICAgICAgICAgICBidWlsdGlucy5hcHBlbmQoJzxhIGhyZWY9IiVzLmh0bWwiPiVzPC9hPicgJSAobmFtZSwgbmFtZSkpCiAgICAgICAgICAgICAgICBpbmRpY2VzID0gWyc8cD5CdWlsdC1pbiBtb2R1bGVzOiAnICsgam9pbihidWlsdGlucywgJywgJyldCiAgICAgICAgICAgICAgICBzZWVuID0ge30KICAgICAgICAgICAgICAgIGZvciBkaXIgaW4gcGF0aGRpcnMoKToKICAgICAgICAgICAgICAgICAgICBpbmRpY2VzLmFwcGVuZChodG1sLmluZGV4KGRpciwgc2VlbikpCiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGhlYWRpbmcgKyBqb2luKGluZGljZXMpICsgIiIiPHAgYWxpZ249cmlnaHQ+CjxzbWFsbD48c21hbGw+PGZvbnQgY29sb3I9IiM5MDkwOTAiIGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPjxzdHJvbmc+CnB5ZG9jPC9zdHJvbmc+IGJ5IEthLVBpbmcgWWVlICZsdDtwaW5nQGxmdy5vcmcmZ3Q7PC9mb250Pjwvc21hbGw+PC9zbWFsbD4iIiIKICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9kb2N1bWVudCgnSW5kZXggb2YgTW9kdWxlcycsIGNvbnRlbnRzKQoKICAgICAgICBkZWYgbG9nX21lc3NhZ2Uoc2VsZiwgKmFyZ3MpOiBwYXNzCgogICAgY2xhc3MgRG9jU2VydmVyKEJhc2VIVFRQU2VydmVyLkhUVFBTZXJ2ZXIpOgogICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBwb3J0LCBjYWxsYmFjayk6CiAgICAgICAgICAgIHNlbGYuYWRkcmVzcyA9ICgnMTI3LjAuMC4xJywgcG9ydCkKICAgICAgICAgICAgc2VsZi51cmwgPSAnaHR0cDovLzEyNy4wLjAuMTolZC8nICUgcG9ydAogICAgICAgICAgICBzZWxmLmNhbGxiYWNrID0gY2FsbGJhY2sKICAgICAgICAgICAgc2VsZi5iYXNlLl9faW5pdF9fKHNlbGYsIHNlbGYuYWRkcmVzcywgc2VsZi5oYW5kbGVyKQoKICAgICAgICBkZWYgc2VydmVfdW50aWxfcXVpdChzZWxmKToKICAgICAgICAgICAgaW1wb3J0IHNlbGVjdAogICAgICAgICAgICBzZWxmLnF1aXQgPSAwCiAgICAgICAgICAgIHdoaWxlIG5vdCBzZWxmLnF1aXQ6CiAgICAgICAgICAgICAgICByZCwgd3IsIGV4ID0gc2VsZWN0LnNlbGVjdChbc2VsZi5zb2NrZXQuZmlsZW5vKCldLCBbXSwgW10sIDEpCiAgICAgICAgICAgICAgICBpZiByZDogc2VsZi5oYW5kbGVfcmVxdWVzdCgpCgogICAgICAgIGRlZiBzZXJ2ZXJfYWN0aXZhdGUoc2VsZik6CiAgICAgICAgICAgIHNlbGYuYmFzZS5zZXJ2ZXJfYWN0aXZhdGUoc2VsZikKICAgICAgICAgICAgaWYgc2VsZi5jYWxsYmFjazogc2VsZi5jYWxsYmFjayhzZWxmKQoKICAgIERvY1NlcnZlci5iYXNlID0gQmFzZUhUVFBTZXJ2ZXIuSFRUUFNlcnZlcgogICAgRG9jU2VydmVyLmhhbmRsZXIgPSBEb2NIYW5kbGVyCiAgICBEb2NIYW5kbGVyLk1lc3NhZ2VDbGFzcyA9IE1lc3NhZ2UKICAgIHRyeToKICAgICAgICBEb2NTZXJ2ZXIocG9ydCwgY2FsbGJhY2spLnNlcnZlX3VudGlsX3F1aXQoKQogICAgZXhjZXB0IChLZXlib2FyZEludGVycnVwdCwgc2VsZWN0LmVycm9yKToKICAgICAgICBwYXNzCiAgICBwcmludCAnc2VydmVyIHN0b3BwZWQnCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGdyYXBoaWNhbCBpbnRlcmZhY2UKCmRlZiBndWkoKToKICAgICIiIkdyYXBoaWNhbCBpbnRlcmZhY2UgKHN0YXJ0cyB3ZWIgc2VydmVyIGFuZCBwb3BzIHVwIGEgY29udHJvbCB3aW5kb3cpLiIiIgogICAgY2xhc3MgR1VJOgogICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCB3aW5kb3csIHBvcnQ9NzQ2NCk6CiAgICAgICAgICAgIHNlbGYud2luZG93ID0gd2luZG93CiAgICAgICAgICAgIHNlbGYuc2VydmVyID0gTm9uZQogICAgICAgICAgICBzZWxmLnNjYW5uZXIgPSBOb25lCgogICAgICAgICAgICBpbXBvcnQgVGtpbnRlcgogICAgICAgICAgICBzZWxmLnNlcnZlcl9mcm0gPSBUa2ludGVyLkZyYW1lKHdpbmRvdykKICAgICAgICAgICAgc2VsZi50aXRsZV9sYmwgPSBUa2ludGVyLkxhYmVsKHNlbGYuc2VydmVyX2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J1N0YXJ0aW5nIHNlcnZlci4uLlxuICcpCiAgICAgICAgICAgIHNlbGYub3Blbl9idG4gPSBUa2ludGVyLkJ1dHRvbihzZWxmLnNlcnZlcl9mcm0sCiAgICAgICAgICAgICAgICB0ZXh0PSdvcGVuIGJyb3dzZXInLCBjb21tYW5kPXNlbGYub3Blbiwgc3RhdGU9J2Rpc2FibGVkJykKICAgICAgICAgICAgc2VsZi5xdWl0X2J0biA9IFRraW50ZXIuQnV0dG9uKHNlbGYuc2VydmVyX2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J3F1aXQgc2VydmluZycsIGNvbW1hbmQ9c2VsZi5xdWl0LCBzdGF0ZT0nZGlzYWJsZWQnKQoKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZnJtID0gVGtpbnRlci5GcmFtZSh3aW5kb3cpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibCA9IFRraW50ZXIuTGFiZWwoc2VsZi5zZWFyY2hfZnJtLCB0ZXh0PSdTZWFyY2ggZm9yJykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50ID0gVGtpbnRlci5FbnRyeShzZWxmLnNlYXJjaF9mcm0pCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudC5iaW5kKCc8UmV0dXJuPicsIHNlbGYuc2VhcmNoKQogICAgICAgICAgICBzZWxmLnN0b3BfYnRuID0gVGtpbnRlci5CdXR0b24oc2VsZi5zZWFyY2hfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0nc3RvcCcsIHBhZHk9MCwgY29tbWFuZD1zZWxmLnN0b3AsIHN0YXRlPSdkaXNhYmxlZCcpCiAgICAgICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInOgogICAgICAgICAgICAgICAgIyBBdHRlbXB0aW5nIHRvIGhpZGUgYW5kIHNob3cgdGhpcyBidXR0b24gY3Jhc2hlcyB1bmRlciBXaW5kb3dzLgogICAgICAgICAgICAgICAgc2VsZi5zdG9wX2J0bi5wYWNrKHNpZGU9J3JpZ2h0JykKCiAgICAgICAgICAgIHNlbGYud2luZG93LnRpdGxlKCdweWRvYycpCiAgICAgICAgICAgIHNlbGYud2luZG93LnByb3RvY29sKCdXTV9ERUxFVEVfV0lORE9XJywgc2VsZi5xdWl0KQogICAgICAgICAgICBzZWxmLnRpdGxlX2xibC5wYWNrKHNpZGU9J3RvcCcsIGZpbGw9J3gnKQogICAgICAgICAgICBzZWxmLm9wZW5fYnRuLnBhY2soc2lkZT0nbGVmdCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKICAgICAgICAgICAgc2VsZi5xdWl0X2J0bi5wYWNrKHNpZGU9J3JpZ2h0JywgZmlsbD0neCcsIGV4cGFuZD0xKQogICAgICAgICAgICBzZWxmLnNlcnZlcl9mcm0ucGFjayhzaWRlPSd0b3AnLCBmaWxsPSd4JykKCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibC5wYWNrKHNpZGU9J2xlZnQnKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQucGFjayhzaWRlPSdyaWdodCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZnJtLnBhY2soc2lkZT0ndG9wJywgZmlsbD0neCcpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudC5mb2N1c19zZXQoKQoKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0ID0gVGtpbnRlci5MaXN0Ym94KHdpbmRvdywgCiAgICAgICAgICAgICAgICBmb250PSgnaGVsdmV0aWNhJywgOCksIGhlaWdodD02KQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QuYmluZCgnPEJ1dHRvbi0xPicsIHNlbGYuc2VsZWN0KQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QuYmluZCgnPERvdWJsZS1CdXR0b24tMT4nLCBzZWxmLmdvdG8pCiAgICAgICAgICAgIHNlbGYucmVzdWx0X3NjciA9IFRraW50ZXIuU2Nyb2xsYmFyKHdpbmRvdywKICAgICAgICAgICAgICAgIG9yaWVudD0ndmVydGljYWwnLCBjb21tYW5kPXNlbGYucmVzdWx0X2xzdC55dmlldykKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmNvbmZpZyh5c2Nyb2xsY29tbWFuZD1zZWxmLnJlc3VsdF9zY3Iuc2V0KQoKICAgICAgICAgICAgc2VsZi5yZXN1bHRfZnJtID0gVGtpbnRlci5GcmFtZSh3aW5kb3cpCiAgICAgICAgICAgIHNlbGYuZ290b19idG4gPSBUa2ludGVyLkJ1dHRvbihzZWxmLnJlc3VsdF9mcm0sCiAgICAgICAgICAgICAgICB0ZXh0PSdnbyB0byBzZWxlY3RlZCcsIGNvbW1hbmQ9c2VsZi5nb3RvKQogICAgICAgICAgICBzZWxmLmhpZGVfYnRuID0gVGtpbnRlci5CdXR0b24oc2VsZi5yZXN1bHRfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0naGlkZSByZXN1bHRzJywgY29tbWFuZD1zZWxmLmhpZGUpCiAgICAgICAgICAgIHNlbGYuZ290b19idG4ucGFjayhzaWRlPSdsZWZ0JywgZmlsbD0neCcsIGV4cGFuZD0xKQogICAgICAgICAgICBzZWxmLmhpZGVfYnRuLnBhY2soc2lkZT0ncmlnaHQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCgogICAgICAgICAgICBzZWxmLndpbmRvdy51cGRhdGUoKQogICAgICAgICAgICBzZWxmLm1pbndpZHRoID0gc2VsZi53aW5kb3cud2luZm9fd2lkdGgoKQogICAgICAgICAgICBzZWxmLm1pbmhlaWdodCA9IHNlbGYud2luZG93LndpbmZvX2hlaWdodCgpCiAgICAgICAgICAgIHNlbGYuYmlnbWluaGVpZ2h0ID0gKHNlbGYuc2VydmVyX2ZybS53aW5mb19yZXFoZWlnaHQoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc2VhcmNoX2ZybS53aW5mb19yZXFoZWlnaHQoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC53aW5mb19yZXFoZWlnaHQoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYucmVzdWx0X2ZybS53aW5mb19yZXFoZWlnaHQoKSkKICAgICAgICAgICAgc2VsZi5iaWd3aWR0aCwgc2VsZi5iaWdoZWlnaHQgPSBzZWxmLm1pbndpZHRoLCBzZWxmLmJpZ21pbmhlaWdodAogICAgICAgICAgICBzZWxmLmV4cGFuZGVkID0gMAogICAgICAgICAgICBzZWxmLndpbmRvdy53bV9nZW9tZXRyeSgnJWR4JWQnICUgKHNlbGYubWlud2lkdGgsIHNlbGYubWluaGVpZ2h0KSkKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fbWluc2l6ZShzZWxmLm1pbndpZHRoLCBzZWxmLm1pbmhlaWdodCkKCiAgICAgICAgICAgIGltcG9ydCB0aHJlYWRpbmcKICAgICAgICAgICAgdGhyZWFkaW5nLlRocmVhZCh0YXJnZXQ9c2VydmUsIGFyZ3M9KHBvcnQsIHNlbGYucmVhZHkpKS5zdGFydCgpCgogICAgICAgIGRlZiByZWFkeShzZWxmLCBzZXJ2ZXIpOgogICAgICAgICAgICBzZWxmLnNlcnZlciA9IHNlcnZlcgogICAgICAgICAgICBzZWxmLnRpdGxlX2xibC5jb25maWcoCiAgICAgICAgICAgICAgICB0ZXh0PSdQeXRob24gZG9jdW1lbnRhdGlvbiBzZXJ2ZXIgYXRcbicgKyBzZXJ2ZXIudXJsKQogICAgICAgICAgICBzZWxmLm9wZW5fYnRuLmNvbmZpZyhzdGF0ZT0nbm9ybWFsJykKICAgICAgICAgICAgc2VsZi5xdWl0X2J0bi5jb25maWcoc3RhdGU9J25vcm1hbCcpCgogICAgICAgIGRlZiBvcGVuKHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBpbXBvcnQgd2ViYnJvd3NlcgogICAgICAgICAgICB3ZWJicm93c2VyLm9wZW4oc2VsZi5zZXJ2ZXIudXJsKQoKICAgICAgICBkZWYgcXVpdChzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgaWYgc2VsZi5zZXJ2ZXI6CiAgICAgICAgICAgICAgICBzZWxmLnNlcnZlci5xdWl0ID0gMQogICAgICAgICAgICBzZWxmLndpbmRvdy5xdWl0KCkKCiAgICAgICAgZGVmIHNlYXJjaChzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAga2V5ID0gc2VsZi5zZWFyY2hfZW50LmdldCgpCiAgICAgICAgICAgIHNlbGYuc3RvcF9idG4ucGFjayhzaWRlPSdyaWdodCcpCiAgICAgICAgICAgIHNlbGYuc3RvcF9idG4uY29uZmlnKHN0YXRlPSdub3JtYWwnKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwuY29uZmlnKHRleHQ9J1NlYXJjaGluZyBmb3IgIiVzIi4uLicgJSBrZXkpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudC5mb3JnZXQoKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwucGFjayhzaWRlPSdsZWZ0JykKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmRlbGV0ZSgwLCAnZW5kJykKICAgICAgICAgICAgc2VsZi5nb3RvX2J0bi5jb25maWcoc3RhdGU9J2Rpc2FibGVkJykKICAgICAgICAgICAgc2VsZi5leHBhbmQoKQoKICAgICAgICAgICAgaW1wb3J0IHRocmVhZGluZwogICAgICAgICAgICBpZiBzZWxmLnNjYW5uZXI6CiAgICAgICAgICAgICAgICBzZWxmLnNjYW5uZXIucXVpdCA9IDEKICAgICAgICAgICAgc2VsZi5zY2FubmVyID0gTW9kdWxlU2Nhbm5lcigpCiAgICAgICAgICAgIHRocmVhZGluZy5UaHJlYWQodGFyZ2V0PXNlbGYuc2Nhbm5lci5ydW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJncz0oa2V5LCBzZWxmLnVwZGF0ZSwgc2VsZi5kb25lKSkuc3RhcnQoKQoKICAgICAgICBkZWYgdXBkYXRlKHNlbGYsIHBhdGgsIG1vZG5hbWUsIGRlc2MpOgogICAgICAgICAgICBpZiBtb2RuYW1lWy05Ol0gPT0gJy5fX2luaXRfXyc6CiAgICAgICAgICAgICAgICBtb2RuYW1lID0gbW9kbmFtZVs6LTldICsgJyAocGFja2FnZSknCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5pbnNlcnQoJ2VuZCcsCiAgICAgICAgICAgICAgICBtb2RuYW1lICsgJyAtICcgKyAoZGVzYyBvciAnKG5vIGRlc2NyaXB0aW9uKScpKQoKICAgICAgICBkZWYgc3RvcChzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgaWYgc2VsZi5zY2FubmVyOgogICAgICAgICAgICAgICAgc2VsZi5zY2FubmVyLnF1aXQgPSAxCiAgICAgICAgICAgICAgICBzZWxmLnNjYW5uZXIgPSBOb25lCgogICAgICAgIGRlZiBkb25lKHNlbGYpOgogICAgICAgICAgICBzZWxmLnNjYW5uZXIgPSBOb25lCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibC5jb25maWcodGV4dD0nU2VhcmNoIGZvcicpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibC5wYWNrKHNpZGU9J2xlZnQnKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQucGFjayhzaWRlPSdyaWdodCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKICAgICAgICAgICAgaWYgc3lzLnBsYXRmb3JtICE9ICd3aW4zMic6IHNlbGYuc3RvcF9idG4uZm9yZ2V0KCkKICAgICAgICAgICAgc2VsZi5zdG9wX2J0bi5jb25maWcoc3RhdGU9J2Rpc2FibGVkJykKCiAgICAgICAgZGVmIHNlbGVjdChzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgc2VsZi5nb3RvX2J0bi5jb25maWcoc3RhdGU9J25vcm1hbCcpCgogICAgICAgIGRlZiBnb3RvKHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBzZWxlY3Rpb24gPSBzZWxmLnJlc3VsdF9sc3QuY3Vyc2VsZWN0aW9uKCkKICAgICAgICAgICAgaWYgc2VsZWN0aW9uOgogICAgICAgICAgICAgICAgaW1wb3J0IHdlYmJyb3dzZXIKICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBzcGxpdChzZWxmLnJlc3VsdF9sc3QuZ2V0KHNlbGVjdGlvblswXSkpWzBdCiAgICAgICAgICAgICAgICB3ZWJicm93c2VyLm9wZW4oc2VsZi5zZXJ2ZXIudXJsICsgbW9kbmFtZSArICcuaHRtbCcpCgogICAgICAgIGRlZiBjb2xsYXBzZShzZWxmKToKICAgICAgICAgICAgaWYgbm90IHNlbGYuZXhwYW5kZWQ6IHJldHVybgogICAgICAgICAgICBzZWxmLnJlc3VsdF9mcm0uZm9yZ2V0KCkKICAgICAgICAgICAgc2VsZi5yZXN1bHRfc2NyLmZvcmdldCgpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5mb3JnZXQoKQogICAgICAgICAgICBzZWxmLmJpZ3dpZHRoID0gc2VsZi53aW5kb3cud2luZm9fd2lkdGgoKQogICAgICAgICAgICBzZWxmLmJpZ2hlaWdodCA9IHNlbGYud2luZG93LndpbmZvX2hlaWdodCgpCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX2dlb21ldHJ5KCclZHglZCcgJSAoc2VsZi5taW53aWR0aCwgc2VsZi5taW5oZWlnaHQpKQogICAgICAgICAgICBzZWxmLndpbmRvdy53bV9taW5zaXplKHNlbGYubWlud2lkdGgsIHNlbGYubWluaGVpZ2h0KQogICAgICAgICAgICBzZWxmLmV4cGFuZGVkID0gMAoKICAgICAgICBkZWYgZXhwYW5kKHNlbGYpOgogICAgICAgICAgICBpZiBzZWxmLmV4cGFuZGVkOiByZXR1cm4KICAgICAgICAgICAgc2VsZi5yZXN1bHRfZnJtLnBhY2soc2lkZT0nYm90dG9tJywgZmlsbD0neCcpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X3Njci5wYWNrKHNpZGU9J3JpZ2h0JywgZmlsbD0neScpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5wYWNrKHNpZGU9J3RvcCcsIGZpbGw9J2JvdGgnLCBleHBhbmQ9MSkKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fZ2VvbWV0cnkoJyVkeCVkJyAlIChzZWxmLmJpZ3dpZHRoLCBzZWxmLmJpZ2hlaWdodCkpCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX21pbnNpemUoc2VsZi5taW53aWR0aCwgc2VsZi5iaWdtaW5oZWlnaHQpCiAgICAgICAgICAgIHNlbGYuZXhwYW5kZWQgPSAxCgogICAgICAgIGRlZiBoaWRlKHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBzZWxmLnN0b3AoKQogICAgICAgICAgICBzZWxmLmNvbGxhcHNlKCkKCiAgICBpbXBvcnQgVGtpbnRlcgogICAgdHJ5OgogICAgICAgIGd1aSA9IEdVSShUa2ludGVyLlRrKCkpCiAgICAgICAgVGtpbnRlci5tYWlubG9vcCgpCiAgICBleGNlcHQgS2V5Ym9hcmRJbnRlcnJ1cHQ6CiAgICAgICAgcGFzcwoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBjb21tYW5kLWxpbmUgaW50ZXJmYWNlCgpkZWYgY2xpKCk6CiAgICAiIiJDb21tYW5kLWxpbmUgaW50ZXJmYWNlIChsb29rcyBhdCBzeXMuYXJndiB0byBkZWNpZGUgd2hhdCB0byBkbykuIiIiCiAgICBpbXBvcnQgZ2V0b3B0CiAgICBjbGFzcyBCYWRVc2FnZTogcGFzcwoKICAgIHRyeToKICAgICAgICBpZiBzeXMucGxhdGZvcm0gaW4gWydtYWMnLCAnd2luJywgJ3dpbjMyJywgJ250J10gYW5kIG5vdCBzeXMuYXJndlsxOl06CiAgICAgICAgICAgICMgQ0xJLWxlc3MgcGxhdGZvcm1zCiAgICAgICAgICAgIGd1aSgpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBvcHRzLCBhcmdzID0gZ2V0b3B0LmdldG9wdChzeXMuYXJndlsxOl0sICdnazpwOncnKQogICAgICAgIHdyaXRpbmcgPSAwCgogICAgICAgIGZvciBvcHQsIHZhbCBpbiBvcHRzOgogICAgICAgICAgICBpZiBvcHQgPT0gJy1nJzoKICAgICAgICAgICAgICAgIGd1aSgpCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgaWYgb3B0ID09ICctayc6CiAgICAgICAgICAgICAgICBhcHJvcG9zKHZhbCkKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBpZiBvcHQgPT0gJy1wJzoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBwb3J0ID0gaW50KHZhbCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIEJhZFVzYWdlCiAgICAgICAgICAgICAgICBkZWYgcmVhZHkoc2VydmVyKToKICAgICAgICAgICAgICAgICAgICBwcmludCAnc2VydmVyIHJlYWR5IGF0ICVzJyAlIHNlcnZlci51cmwKICAgICAgICAgICAgICAgIHNlcnZlKHBvcnQsIHJlYWR5KQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGlmIG9wdCA9PSAnLXcnOgogICAgICAgICAgICAgICAgd3JpdGluZyA9IDEKCiAgICAgICAgaWYgbm90IGFyZ3M6IHJhaXNlIEJhZFVzYWdlCiAgICAgICAgZm9yIGFyZyBpbiBhcmdzOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpZiBmaW5kKGFyZywgb3Muc2VwKSA+PSAwIGFuZCBvcy5wYXRoLmlzZmlsZShhcmcpOgogICAgICAgICAgICAgICAgICAgIGFyZyA9IGltcG9ydGZpbGUoYXJnKQogICAgICAgICAgICAgICAgaWYgd3JpdGluZzogd3JpdGVkb2MoYXJnKQogICAgICAgICAgICAgICAgZWxzZTogbWFuKGFyZykKICAgICAgICAgICAgZXhjZXB0IERvY0ltcG9ydEVycm9yLCB2YWx1ZToKICAgICAgICAgICAgICAgIHByaW50ICdQcm9ibGVtIGluICVzIC0gJXMnICUgKHZhbHVlLmZpbGVuYW1lLCB2YWx1ZS5hcmdzKQoKICAgIGV4Y2VwdCAoZ2V0b3B0LmVycm9yLCBCYWRVc2FnZSk6CiAgICAgICAgY21kID0gc3lzLmFyZ3ZbMF0KICAgICAgICBwcmludCAiIiJweWRvYyAtIHRoZSBQeXRob24gZG9jdW1lbnRhdGlvbiB0b29sCgolcyA8bmFtZT4gLi4uCiAgICBTaG93IHRleHQgZG9jdW1lbnRhdGlvbiBvbiBzb21ldGhpbmcuICA8bmFtZT4gbWF5IGJlIHRoZSBuYW1lIG9mIGEKICAgIGZ1bmN0aW9uLCBtb2R1bGUsIG9yIHBhY2thZ2UsIG9yIGEgZG90dGVkIHJlZmVyZW5jZSB0byBhIGNsYXNzIG9yCiAgICBmdW5jdGlvbiB3aXRoaW4gYSBtb2R1bGUgb3IgbW9kdWxlIGluIGEgcGFja2FnZS4gIElmIDxuYW1lPiBjb250YWlucwogICAgYSAnJXMnLCBpdCBpcyB1c2VkIGFzIHRoZSBwYXRoIHRvIGEgUHl0aG9uIHNvdXJjZSBmaWxlIHRvIGRvY3VtZW50LgoKJXMgLWsgPGtleXdvcmQ+CiAgICBTZWFyY2ggZm9yIGEga2V5d29yZCBpbiB0aGUgc3lub3BzaXMgbGluZXMgb2YgYWxsIGF2YWlsYWJsZSBtb2R1bGVzLgoKJXMgLXAgPHBvcnQ+CiAgICBTdGFydCBhbiBIVFRQIHNlcnZlciBvbiB0aGUgZ2l2ZW4gcG9ydCBvbiB0aGUgbG9jYWwgbWFjaGluZS4KCiVzIC1nCiAgICBQb3AgdXAgYSBncmFwaGljYWwgaW50ZXJmYWNlIGZvciBzZXJ2aW5nIGFuZCBmaW5kaW5nIGRvY3VtZW50YXRpb24uCgolcyAtdyA8bmFtZT4gLi4uCiAgICBXcml0ZSBvdXQgdGhlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBtb2R1bGUgdG8gYSBmaWxlIGluIHRoZSBjdXJyZW50CiAgICBkaXJlY3RvcnkuICBJZiA8bmFtZT4gY29udGFpbnMgYSAnJXMnLCBpdCBpcyB0cmVhdGVkIGFzIGEgZmlsZW5hbWUuCiIiIiAlIChjbWQsIG9zLnNlcCwgY21kLCBjbWQsIGNtZCwgY21kLCBvcy5zZXApCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOiBjbGkoKQoKCg==