IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiIiIkdlbmVyYXRlIFB5dGhvbiBkb2N1bWVudGF0aW9uIGluIEhUTUwgb3IgdGV4dCBmb3IgaW50ZXJhY3RpdmUgdXNlLgoKSW4gdGhlIFB5dGhvbiBpbnRlcnByZXRlciwgZG8gImZyb20gcHlkb2MgaW1wb3J0IGhlbHAiIHRvIHByb3ZpZGUgb25saW5lCmhlbHAuICBDYWxsaW5nIGhlbHAodGhpbmcpIG9uIGEgUHl0aG9uIG9iamVjdCBkb2N1bWVudHMgdGhlIG9iamVjdC4KCk9yLCBhdCB0aGUgc2hlbGwgY29tbWFuZCBsaW5lIG91dHNpZGUgb2YgUHl0aG9uOgoKUnVuICJweWRvYyA8bmFtZT4iIHRvIHNob3cgZG9jdW1lbnRhdGlvbiBvbiBzb21ldGhpbmcuICA8bmFtZT4gbWF5IGJlCnRoZSBuYW1lIG9mIGEgZnVuY3Rpb24sIG1vZHVsZSwgcGFja2FnZSwgb3IgYSBkb3R0ZWQgcmVmZXJlbmNlIHRvIGEKY2xhc3Mgb3IgZnVuY3Rpb24gd2l0aGluIGEgbW9kdWxlIG9yIG1vZHVsZSBpbiBhIHBhY2thZ2UuICBJZiB0aGUKYXJndW1lbnQgY29udGFpbnMgYSBwYXRoIHNlZ21lbnQgZGVsaW1pdGVyIChlLmcuIHNsYXNoIG9uIFVuaXgsCmJhY2tzbGFzaCBvbiBXaW5kb3dzKSBpdCBpcyB0cmVhdGVkIGFzIHRoZSBwYXRoIHRvIGEgUHl0aG9uIHNvdXJjZSBmaWxlLgoKUnVuICJweWRvYyAtayA8a2V5d29yZD4iIHRvIHNlYXJjaCBmb3IgYSBrZXl3b3JkIGluIHRoZSBzeW5vcHNpcyBsaW5lcwpvZiBhbGwgYXZhaWxhYmxlIG1vZHVsZXMuCgpSdW4gInB5ZG9jIC1wIDxwb3J0PiIgdG8gc3RhcnQgYW4gSFRUUCBzZXJ2ZXIgb24gYSBnaXZlbiBwb3J0IG9uIHRoZQpsb2NhbCBtYWNoaW5lIHRvIGdlbmVyYXRlIGRvY3VtZW50YXRpb24gd2ViIHBhZ2VzLgoKRm9yIHBsYXRmb3JtcyB3aXRob3V0IGEgY29tbWFuZCBsaW5lLCAicHlkb2MgLWciIHN0YXJ0cyB0aGUgSFRUUCBzZXJ2ZXIKYW5kIGFsc28gcG9wcyB1cCBhIGxpdHRsZSB3aW5kb3cgZm9yIGNvbnRyb2xsaW5nIGl0LgoKUnVuICJweWRvYyAtdyA8bmFtZT4iIHRvIHdyaXRlIG91dCB0aGUgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIG1vZHVsZQp0byBhIGZpbGUgbmFtZWQgIjxuYW1lPi5odG1sIi4KIiIiCgpfX2F1dGhvcl9fID0gIkthLVBpbmcgWWVlIDxwaW5nQGxmdy5vcmc+IgpfX2RhdGVfXyA9ICIyNiBGZWJydWFyeSAyMDAxIgpfX3ZlcnNpb25fXyA9ICIkUmV2aXNpb24kIgpfX2NyZWRpdHNfXyA9ICIiIkd1aWRvIHZhbiBSb3NzdW0sIGZvciBhbiBleGNlbGxlbnQgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuClRvbW15IEJ1cm5ldHRlLCB0aGUgb3JpZ2luYWwgY3JlYXRvciBvZiBtYW5weS4KUGF1bCBQcmVzY29kLCBmb3IgYWxsIGhpcyB3b3JrIG9uIG9ubGluZWhlbHAuClJpY2hhcmQgQ2hhbWJlcmxhaW4sIGZvciB0aGUgZmlyc3QgaW1wbGVtZW50YXRpb24gb2YgdGV4dGRvYy4KCk15bmQgeW91LCBt+PhzZSBiaXRlcyBLYW4gYmUgcHJldHR5IG5hc3RpLi4uIiIiCgojIE5vdGU6IHRoaXMgbW9kdWxlIGlzIGRlc2lnbmVkIHRvIGRlcGxveSBpbnN0YW50bHkgYW5kIHJ1biB1bmRlciBhbnkKIyB2ZXJzaW9uIG9mIFB5dGhvbiBmcm9tIDEuNSBhbmQgdXAuICBUaGF0J3Mgd2h5IGl0J3MgYSBzaW5nbGUgZmlsZSBhbmQKIyBzb21lIDIuMCBmZWF0dXJlcyAobGlrZSBzdHJpbmcgbWV0aG9kcykgYXJlIGNvbnNwaWN1b3VzbHkgYWJzZW50LgoKIyBLbm93biBidWdzIHRoYXQgY2FuJ3QgYmUgZml4ZWQgaGVyZToKIyAgIC0gaW1wLmxvYWRfbW9kdWxlKCkgY2Fubm90IGJlIHByZXZlbnRlZCBmcm9tIGNsb2JiZXJpbmcgZXhpc3RpbmcKIyAgICAgbG9hZGVkIG1vZHVsZXMsIHNvIGNhbGxpbmcgc3lub3BzaXMoKSBvbiBhIGJpbmFyeSBtb2R1bGUgZmlsZQojICAgICBjaGFuZ2VzIHRoZSBjb250ZW50cyBvZiBhbnkgZXhpc3RpbmcgbW9kdWxlIHdpdGggdGhlIHNhbWUgbmFtZS4KIyAgIC0gSWYgdGhlIF9fZmlsZV9fIGF0dHJpYnV0ZSBvbiBhIG1vZHVsZSBpcyBhIHJlbGF0aXZlIHBhdGggYW5kCiMgICAgIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBpcyBjaGFuZ2VkIHdpdGggb3MuY2hkaXIoKSwgYW4gaW5jb3JyZWN0CiMgICAgIHBhdGggd2lsbCBiZSBkaXNwbGF5ZWQuCgppbXBvcnQgc3lzLCBpbXAsIG9zLCBzdGF0LCByZSwgdHlwZXMsIGluc3BlY3QKZnJvbSByZXByIGltcG9ydCBSZXByCmZyb20gc3RyaW5nIGltcG9ydCBleHBhbmR0YWJzLCBmaW5kLCBqb2luLCBsb3dlciwgc3BsaXQsIHN0cmlwLCByZmluZCwgcnN0cmlwCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBjb21tb24gcm91dGluZXMKCmRlZiBwYXRoZGlycygpOgogICAgIiIiQ29udmVydCBzeXMucGF0aCBpbnRvIGEgbGlzdCBvZiBhYnNvbHV0ZSwgZXhpc3RpbmcsIHVuaXF1ZSBwYXRocy4iIiIKICAgIGRpcnMgPSBbXQogICAgbm9ybWRpcnMgPSBbXQogICAgZm9yIGRpciBpbiBzeXMucGF0aDoKICAgICAgICBkaXIgPSBvcy5wYXRoLmFic3BhdGgoZGlyIG9yICcuJykKICAgICAgICBub3JtZGlyID0gb3MucGF0aC5ub3JtY2FzZShkaXIpCiAgICAgICAgaWYgbm9ybWRpciBub3QgaW4gbm9ybWRpcnMgYW5kIG9zLnBhdGguaXNkaXIoZGlyKToKICAgICAgICAgICAgZGlycy5hcHBlbmQoZGlyKQogICAgICAgICAgICBub3JtZGlycy5hcHBlbmQobm9ybWRpcikKICAgIHJldHVybiBkaXJzCgpkZWYgZ2V0ZG9jKG9iamVjdCk6CiAgICAiIiJHZXQgdGhlIGRvYyBzdHJpbmcgb3IgY29tbWVudHMgZm9yIGFuIG9iamVjdC4iIiIKICAgIHJlc3VsdCA9IGluc3BlY3QuZ2V0ZG9jKG9iamVjdCkgb3IgaW5zcGVjdC5nZXRjb21tZW50cyhvYmplY3QpCiAgICByZXR1cm4gcmVzdWx0IGFuZCByZS5zdWIoJ14gKlxuJywgJycsIHJzdHJpcChyZXN1bHQpKSBvciAnJwoKZGVmIHNwbGl0ZG9jKGRvYyk6CiAgICAiIiJTcGxpdCBhIGRvYyBzdHJpbmcgaW50byBhIHN5bm9wc2lzIGxpbmUgKGlmIGFueSkgYW5kIHRoZSByZXN0LiIiIgogICAgbGluZXMgPSBzcGxpdChzdHJpcChkb2MpLCAnXG4nKQogICAgaWYgbGVuKGxpbmVzKSA9PSAxOgogICAgICAgIHJldHVybiBsaW5lc1swXSwgJycKICAgIGVsaWYgbGVuKGxpbmVzKSA+PSAyIGFuZCBub3QgcnN0cmlwKGxpbmVzWzFdKToKICAgICAgICByZXR1cm4gbGluZXNbMF0sIGpvaW4obGluZXNbMjpdLCAnXG4nKQogICAgcmV0dXJuICcnLCBqb2luKGxpbmVzLCAnXG4nKQoKZGVmIGNsYXNzbmFtZShvYmplY3QsIG1vZG5hbWUpOgogICAgIiIiR2V0IGEgY2xhc3MgbmFtZSBhbmQgcXVhbGlmeSBpdCB3aXRoIGEgbW9kdWxlIG5hbWUgaWYgbmVjZXNzYXJ5LiIiIgogICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgaWYgb2JqZWN0Ll9fbW9kdWxlX18gIT0gbW9kbmFtZToKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbW9kdWxlX18gKyAnLicgKyBuYW1lCiAgICByZXR1cm4gbmFtZQoKZGVmIGlzZGF0YShvYmplY3QpOgogICAgIiIiQ2hlY2sgaWYgYW4gb2JqZWN0IGlzIG9mIGEgdHlwZSB0aGF0IHByb2JhYmx5IG1lYW5zIGl0J3MgZGF0YS4iIiIKICAgIHJldHVybiBub3QgKGluc3BlY3QuaXNtb2R1bGUob2JqZWN0KSBvciBpbnNwZWN0LmlzY2xhc3Mob2JqZWN0KSBvcgogICAgICAgICAgICAgICAgaW5zcGVjdC5pc3JvdXRpbmUob2JqZWN0KSBvciBpbnNwZWN0LmlzZnJhbWUob2JqZWN0KSBvcgogICAgICAgICAgICAgICAgaW5zcGVjdC5pc3RyYWNlYmFjayhvYmplY3QpIG9yIGluc3BlY3QuaXNjb2RlKG9iamVjdCkpCgpkZWYgcmVwbGFjZSh0ZXh0LCAqcGFpcnMpOgogICAgIiIiRG8gYSBzZXJpZXMgb2YgZ2xvYmFsIHJlcGxhY2VtZW50cyBvbiBhIHN0cmluZy4iIiIKICAgIHdoaWxlIHBhaXJzOgogICAgICAgIHRleHQgPSBqb2luKHNwbGl0KHRleHQsIHBhaXJzWzBdKSwgcGFpcnNbMV0pCiAgICAgICAgcGFpcnMgPSBwYWlyc1syOl0KICAgIHJldHVybiB0ZXh0CgpkZWYgY3JhbSh0ZXh0LCBtYXhsZW4pOgogICAgIiIiT21pdCBwYXJ0IG9mIGEgc3RyaW5nIGlmIG5lZWRlZCB0byBtYWtlIGl0IGZpdCBpbiBhIG1heGltdW0gbGVuZ3RoLiIiIgogICAgaWYgbGVuKHRleHQpID4gbWF4bGVuOgogICAgICAgIHByZSA9IG1heCgwLCAobWF4bGVuLTMpLzIpCiAgICAgICAgcG9zdCA9IG1heCgwLCBtYXhsZW4tMy1wcmUpCiAgICAgICAgcmV0dXJuIHRleHRbOnByZV0gKyAnLi4uJyArIHRleHRbbGVuKHRleHQpLXBvc3Q6XQogICAgcmV0dXJuIHRleHQKCmRlZiBzdHJpcGlkKHRleHQpOgogICAgIiIiUmVtb3ZlIHRoZSBoZXhhZGVjaW1hbCBpZCBmcm9tIGEgUHl0aG9uIG9iamVjdCByZXByZXNlbnRhdGlvbi4iIiIKICAgICMgVGhlIGJlaGF2aW91ciBvZiAlcCBpcyBpbXBsZW1lbnRhdGlvbi1kZXBlbmRlbnQ7IHdlIGNoZWNrIHR3byBjYXNlcy4KICAgIGZvciBwYXR0ZXJuIGluIFsnIGF0IDB4WzAtOWEtZl17Nix9PiQnLCAnIGF0IFswLTlBLUZdezgsfT4kJ106CiAgICAgICAgaWYgcmUuc2VhcmNoKHBhdHRlcm4sIHJlcHIoRXhjZXB0aW9uKSk6CiAgICAgICAgICAgIHJldHVybiByZS5zdWIocGF0dGVybiwgJz4nLCB0ZXh0KQogICAgcmV0dXJuIHRleHQKCmRlZiBfaXNfc29tZV9tZXRob2Qob2JqZWN0KToKICAgIHJldHVybiBpbnNwZWN0LmlzbWV0aG9kKG9iamVjdCkgb3IgaW5zcGVjdC5pc21ldGhvZGRlc2NyaXB0b3Iob2JqZWN0KQoKZGVmIGFsbG1ldGhvZHMoY2wpOgogICAgbWV0aG9kcyA9IHt9CiAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMoY2wsIF9pc19zb21lX21ldGhvZCk6CiAgICAgICAgbWV0aG9kc1trZXldID0gMQogICAgZm9yIGJhc2UgaW4gY2wuX19iYXNlc19fOgogICAgICAgIG1ldGhvZHMudXBkYXRlKGFsbG1ldGhvZHMoYmFzZSkpICMgYWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVzCiAgICBmb3Iga2V5IGluIG1ldGhvZHMua2V5cygpOgogICAgICAgIG1ldGhvZHNba2V5XSA9IGdldGF0dHIoY2wsIGtleSkKICAgIHJldHVybiBtZXRob2RzCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIG1vZHVsZSBtYW5pcHVsYXRpb24KCmRlZiBpc3BhY2thZ2UocGF0aCk6CiAgICAiIiJHdWVzcyB3aGV0aGVyIGEgcGF0aCByZWZlcnMgdG8gYSBwYWNrYWdlIGRpcmVjdG9yeS4iIiIKICAgIGlmIG9zLnBhdGguaXNkaXIocGF0aCk6CiAgICAgICAgZm9yIGV4dCBpbiBbJy5weScsICcucHljJywgJy5weW8nXToKICAgICAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUob3MucGF0aC5qb2luKHBhdGgsICdfX2luaXRfXycgKyBleHQpKToKICAgICAgICAgICAgICAgIHJldHVybiAxCgpkZWYgc3lub3BzaXMoZmlsZW5hbWUsIGNhY2hlPXt9KToKICAgICIiIkdldCB0aGUgb25lLWxpbmUgc3VtbWFyeSBvdXQgb2YgYSBtb2R1bGUgZmlsZS4iIiIKICAgIG10aW1lID0gb3Muc3RhdChmaWxlbmFtZSlbc3RhdC5TVF9NVElNRV0KICAgIGxhc3R1cGRhdGUsIHJlc3VsdCA9IGNhY2hlLmdldChmaWxlbmFtZSwgKDAsIE5vbmUpKQogICAgaWYgbGFzdHVwZGF0ZSA8IG10aW1lOgogICAgICAgIGluZm8gPSBpbnNwZWN0LmdldG1vZHVsZWluZm8oZmlsZW5hbWUpCiAgICAgICAgZmlsZSA9IG9wZW4oZmlsZW5hbWUpCiAgICAgICAgaWYgaW5mbyBhbmQgJ2InIGluIGluZm9bMl06ICMgYmluYXJ5IG1vZHVsZXMgaGF2ZSB0byBiZSBpbXBvcnRlZAogICAgICAgICAgICB0cnk6IG1vZHVsZSA9IGltcC5sb2FkX21vZHVsZSgnX190ZW1wX18nLCBmaWxlLCBmaWxlbmFtZSwgaW5mb1sxOl0pCiAgICAgICAgICAgIGV4Y2VwdDogcmV0dXJuIE5vbmUKICAgICAgICAgICAgcmVzdWx0ID0gc3BsaXQobW9kdWxlLl9fZG9jX18gb3IgJycsICdcbicpWzBdCiAgICAgICAgICAgIGRlbCBzeXMubW9kdWxlc1snX190ZW1wX18nXQogICAgICAgIGVsc2U6ICMgdGV4dCBtb2R1bGVzIGNhbiBiZSBkaXJlY3RseSBleGFtaW5lZAogICAgICAgICAgICBsaW5lID0gZmlsZS5yZWFkbGluZSgpCiAgICAgICAgICAgIHdoaWxlIGxpbmVbOjFdID09ICcjJyBvciBub3Qgc3RyaXAobGluZSk6CiAgICAgICAgICAgICAgICBsaW5lID0gZmlsZS5yZWFkbGluZSgpCiAgICAgICAgICAgICAgICBpZiBub3QgbGluZTogYnJlYWsKICAgICAgICAgICAgbGluZSA9IHN0cmlwKGxpbmUpCiAgICAgICAgICAgIGlmIGxpbmVbOjRdID09ICdyIiIiJzogbGluZSA9IGxpbmVbMTpdCiAgICAgICAgICAgIGlmIGxpbmVbOjNdID09ICciIiInOgogICAgICAgICAgICAgICAgbGluZSA9IGxpbmVbMzpdCiAgICAgICAgICAgICAgICBpZiBsaW5lWy0xOl0gPT0gJ1xcJzogbGluZSA9IGxpbmVbOi0xXQogICAgICAgICAgICAgICAgd2hpbGUgbm90IHN0cmlwKGxpbmUpOgogICAgICAgICAgICAgICAgICAgIGxpbmUgPSBmaWxlLnJlYWRsaW5lKCkKICAgICAgICAgICAgICAgICAgICBpZiBub3QgbGluZTogYnJlYWsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHN0cmlwKHNwbGl0KGxpbmUsICciIiInKVswXSkKICAgICAgICAgICAgZWxzZTogcmVzdWx0ID0gTm9uZQogICAgICAgIGZpbGUuY2xvc2UoKQogICAgICAgIGNhY2hlW2ZpbGVuYW1lXSA9IChtdGltZSwgcmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdAoKY2xhc3MgRXJyb3JEdXJpbmdJbXBvcnQoRXhjZXB0aW9uKToKICAgICIiIkVycm9ycyB0aGF0IG9jY3VycmVkIHdoaWxlIHRyeWluZyB0byBpbXBvcnQgc29tZXRoaW5nIHRvIGRvY3VtZW50IGl0LiIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGVuYW1lLCAoZXhjLCB2YWx1ZSwgdGIpKToKICAgICAgICBzZWxmLmZpbGVuYW1lID0gZmlsZW5hbWUKICAgICAgICBzZWxmLmV4YyA9IGV4YwogICAgICAgIHNlbGYudmFsdWUgPSB2YWx1ZQogICAgICAgIHNlbGYudGIgPSB0YgoKICAgIGRlZiBfX3N0cl9fKHNlbGYpOgogICAgICAgIGV4YyA9IHNlbGYuZXhjCiAgICAgICAgaWYgdHlwZShleGMpIGlzIHR5cGVzLkNsYXNzVHlwZToKICAgICAgICAgICAgZXhjID0gZXhjLl9fbmFtZV9fCiAgICAgICAgcmV0dXJuICdwcm9ibGVtIGluICVzIC0gJXM6ICVzJyAlIChzZWxmLmZpbGVuYW1lLCBleGMsIHNlbGYudmFsdWUpCgpkZWYgaW1wb3J0ZmlsZShwYXRoKToKICAgICIiIkltcG9ydCBhIFB5dGhvbiBzb3VyY2UgZmlsZSBvciBjb21waWxlZCBmaWxlIGdpdmVuIGl0cyBwYXRoLiIiIgogICAgbWFnaWMgPSBpbXAuZ2V0X21hZ2ljKCkKICAgIGZpbGUgPSBvcGVuKHBhdGgsICdyJykKICAgIGlmIGZpbGUucmVhZChsZW4obWFnaWMpKSA9PSBtYWdpYzoKICAgICAgICBraW5kID0gaW1wLlBZX0NPTVBJTEVECiAgICBlbHNlOgogICAgICAgIGtpbmQgPSBpbXAuUFlfU09VUkNFCiAgICBmaWxlLmNsb3NlKCkKICAgIGZpbGVuYW1lID0gb3MucGF0aC5iYXNlbmFtZShwYXRoKQogICAgbmFtZSwgZXh0ID0gb3MucGF0aC5zcGxpdGV4dChmaWxlbmFtZSkKICAgIGZpbGUgPSBvcGVuKHBhdGgsICdyJykKICAgIHRyeToKICAgICAgICBtb2R1bGUgPSBpbXAubG9hZF9tb2R1bGUobmFtZSwgZmlsZSwgcGF0aCwgKGV4dCwgJ3InLCBraW5kKSkKICAgIGV4Y2VwdDoKICAgICAgICByYWlzZSBFcnJvckR1cmluZ0ltcG9ydChwYXRoLCBzeXMuZXhjX2luZm8oKSkKICAgIGZpbGUuY2xvc2UoKQogICAgcmV0dXJuIG1vZHVsZQoKZGVmIHNhZmVpbXBvcnQocGF0aCwgZm9yY2Vsb2FkPTAsIGNhY2hlPXt9KToKICAgICIiIkltcG9ydCBhIG1vZHVsZTsgaGFuZGxlIGVycm9yczsgcmV0dXJuIE5vbmUgaWYgdGhlIG1vZHVsZSBpc24ndCBmb3VuZC4KCiAgICBJZiB0aGUgbW9kdWxlICppcyogZm91bmQgYnV0IGFuIGV4Y2VwdGlvbiBvY2N1cnMsIGl0J3Mgd3JhcHBlZCBpbiBhbgogICAgRXJyb3JEdXJpbmdJbXBvcnQgZXhjZXB0aW9uIGFuZCByZXJhaXNlZC4gIFVubGlrZSBfX2ltcG9ydF9fLCBpZiBhCiAgICBwYWNrYWdlIHBhdGggaXMgc3BlY2lmaWVkLCB0aGUgbW9kdWxlIGF0IHRoZSBlbmQgb2YgdGhlIHBhdGggaXMgcmV0dXJuZWQsCiAgICBub3QgdGhlIHBhY2thZ2UgYXQgdGhlIGJlZ2lubmluZy4gIElmIHRoZSBvcHRpb25hbCAnZm9yY2Vsb2FkJyBhcmd1bWVudAogICAgaXMgMSwgd2UgcmVsb2FkIHRoZSBtb2R1bGUgZnJvbSBkaXNrICh1bmxlc3MgaXQncyBhIGR5bmFtaWMgZXh0ZW5zaW9uKS4iIiIKICAgIGlmIGZvcmNlbG9hZCBhbmQgc3lzLm1vZHVsZXMuaGFzX2tleShwYXRoKToKICAgICAgICAjIFRoaXMgaXMgdGhlIG9ubHkgd2F5IHRvIGJlIHN1cmUuICBDaGVja2luZyB0aGUgbXRpbWUgb2YgdGhlIGZpbGUKICAgICAgICAjIGlzbid0IGdvb2QgZW5vdWdoIChlLmcuIHdoYXQgaWYgdGhlIG1vZHVsZSBjb250YWlucyBhIGNsYXNzIHRoYXQKICAgICAgICAjIGluaGVyaXRzIGZyb20gYW5vdGhlciBtb2R1bGUgdGhhdCBoYXMgY2hhbmdlZD8pLgogICAgICAgIGlmIHBhdGggbm90IGluIHN5cy5idWlsdGluX21vZHVsZV9uYW1lczoKICAgICAgICAgICAgIyBQeXRob24gbmV2ZXIgbG9hZHMgYSBkeW5hbWljIGV4dGVuc2lvbiBhIHNlY29uZCB0aW1lIGZyb20gdGhlCiAgICAgICAgICAgICMgc2FtZSBwYXRoLCBldmVuIGlmIHRoZSBmaWxlIGlzIGNoYW5nZWQgb3IgbWlzc2luZy4gIERlbGV0aW5nCiAgICAgICAgICAgICMgdGhlIGVudHJ5IGluIHN5cy5tb2R1bGVzIGRvZXNuJ3QgaGVscCBmb3IgZHluYW1pYyBleHRlbnNpb25zLAogICAgICAgICAgICAjIHNvIHdlJ3JlIG5vdCBldmVuIGdvaW5nIHRvIHRyeSB0byBrZWVwIHRoZW0gdXAgdG8gZGF0ZS4KICAgICAgICAgICAgaW5mbyA9IGluc3BlY3QuZ2V0bW9kdWxlaW5mbyhzeXMubW9kdWxlc1twYXRoXS5fX2ZpbGVfXykKICAgICAgICAgICAgaWYgaW5mb1szXSAhPSBpbXAuQ19FWFRFTlNJT046CiAgICAgICAgICAgICAgICBjYWNoZVtwYXRoXSA9IHN5cy5tb2R1bGVzW3BhdGhdICMgcHJldmVudCBtb2R1bGUgZnJvbSBjbGVhcmluZwogICAgICAgICAgICAgICAgZGVsIHN5cy5tb2R1bGVzW3BhdGhdCiAgICB0cnk6CiAgICAgICAgbW9kdWxlID0gX19pbXBvcnRfXyhwYXRoKQogICAgZXhjZXB0OgogICAgICAgICMgRGlkIHRoZSBlcnJvciBvY2N1ciBiZWZvcmUgb3IgYWZ0ZXIgdGhlIG1vZHVsZSB3YXMgZm91bmQ/CiAgICAgICAgKGV4YywgdmFsdWUsIHRiKSA9IGluZm8gPSBzeXMuZXhjX2luZm8oKQogICAgICAgIGlmIHN5cy5tb2R1bGVzLmhhc19rZXkocGF0aCk6CiAgICAgICAgICAgICMgQW4gZXJyb3Igb2NjdXJlZCB3aGlsZSBleGVjdXRpbmcgdGhlIGltcG9ydGVkIG1vZHVsZS4KICAgICAgICAgICAgcmFpc2UgRXJyb3JEdXJpbmdJbXBvcnQoc3lzLm1vZHVsZXNbcGF0aF0uX19maWxlX18sIGluZm8pCiAgICAgICAgZWxpZiBleGMgaXMgU3ludGF4RXJyb3I6CiAgICAgICAgICAgICMgQSBTeW50YXhFcnJvciBvY2N1cnJlZCBiZWZvcmUgd2UgY291bGQgZXhlY3V0ZSB0aGUgbW9kdWxlLgogICAgICAgICAgICByYWlzZSBFcnJvckR1cmluZ0ltcG9ydCh2YWx1ZS5maWxlbmFtZSwgaW5mbykKICAgICAgICBlbGlmIGV4YyBpcyBJbXBvcnRFcnJvciBhbmQgXAogICAgICAgICAgICAgc3BsaXQobG93ZXIoc3RyKHZhbHVlKSkpWzoyXSA9PSBbJ25vJywgJ21vZHVsZSddOgogICAgICAgICAgICAjIFRoZSBtb2R1bGUgd2FzIG5vdCBmb3VuZC4KICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICBlbHNlOgogICAgICAgICAgICAjIFNvbWUgb3RoZXIgZXJyb3Igb2NjdXJyZWQgZHVyaW5nIHRoZSBpbXBvcnRpbmcgcHJvY2Vzcy4KICAgICAgICAgICAgcmFpc2UgRXJyb3JEdXJpbmdJbXBvcnQocGF0aCwgc3lzLmV4Y19pbmZvKCkpCiAgICBmb3IgcGFydCBpbiBzcGxpdChwYXRoLCAnLicpWzE6XToKICAgICAgICB0cnk6IG1vZHVsZSA9IGdldGF0dHIobW9kdWxlLCBwYXJ0KQogICAgICAgIGV4Y2VwdCBBdHRyaWJ1dGVFcnJvcjogcmV0dXJuIE5vbmUKICAgIHJldHVybiBtb2R1bGUKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBmb3JtYXR0ZXIgYmFzZSBjbGFzcwoKY2xhc3MgRG9jOgogICAgZGVmIGRvY3VtZW50KHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCAqYXJncyk6CiAgICAgICAgIiIiR2VuZXJhdGUgZG9jdW1lbnRhdGlvbiBmb3IgYW4gb2JqZWN0LiIiIgogICAgICAgIGFyZ3MgPSAob2JqZWN0LCBuYW1lKSArIGFyZ3MKICAgICAgICBpZiBpbnNwZWN0LmlzbW9kdWxlKG9iamVjdCk6IHJldHVybiBhcHBseShzZWxmLmRvY21vZHVsZSwgYXJncykKICAgICAgICBpZiBpbnNwZWN0LmlzY2xhc3Mob2JqZWN0KTogcmV0dXJuIGFwcGx5KHNlbGYuZG9jY2xhc3MsIGFyZ3MpCiAgICAgICAgaWYgaW5zcGVjdC5pc3JvdXRpbmUob2JqZWN0KTogcmV0dXJuIGFwcGx5KHNlbGYuZG9jcm91dGluZSwgYXJncykKICAgICAgICByZXR1cm4gYXBwbHkoc2VsZi5kb2NvdGhlciwgYXJncykKCiAgICBkZWYgZmFpbChzZWxmLCBvYmplY3QsIG5hbWU9Tm9uZSwgKmFyZ3MpOgogICAgICAgICIiIlJhaXNlIGFuIGV4Y2VwdGlvbiBmb3IgdW5pbXBsZW1lbnRlZCB0eXBlcy4iIiIKICAgICAgICBtZXNzYWdlID0gImRvbid0IGtub3cgaG93IHRvIGRvY3VtZW50IG9iamVjdCVzIG9mIHR5cGUgJXMiICUgKAogICAgICAgICAgICBuYW1lIGFuZCAnICcgKyByZXByKG5hbWUpLCB0eXBlKG9iamVjdCkuX19uYW1lX18pCiAgICAgICAgcmFpc2UgVHlwZUVycm9yLCBtZXNzYWdlCgogICAgZG9jbW9kdWxlID0gZG9jY2xhc3MgPSBkb2Nyb3V0aW5lID0gZG9jb3RoZXIgPSBmYWlsCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEhUTUwgZG9jdW1lbnRhdGlvbiBnZW5lcmF0b3IKCmNsYXNzIEhUTUxSZXByKFJlcHIpOgogICAgIiIiQ2xhc3MgZm9yIHNhZmVseSBtYWtpbmcgYW4gSFRNTCByZXByZXNlbnRhdGlvbiBvZiBhIFB5dGhvbiBvYmplY3QuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgUmVwci5fX2luaXRfXyhzZWxmKQogICAgICAgIHNlbGYubWF4bGlzdCA9IHNlbGYubWF4dHVwbGUgPSAyMAogICAgICAgIHNlbGYubWF4ZGljdCA9IDEwCiAgICAgICAgc2VsZi5tYXhzdHJpbmcgPSBzZWxmLm1heG90aGVyID0gMTAwCgogICAgZGVmIGVzY2FwZShzZWxmLCB0ZXh0KToKICAgICAgICByZXR1cm4gcmVwbGFjZSh0ZXh0LCAnJicsICcmYW1wOycsICc8JywgJyZsdDsnLCAnPicsICcmZ3Q7JykKCiAgICBkZWYgcmVwcihzZWxmLCBvYmplY3QpOgogICAgICAgIHJldHVybiBSZXByLnJlcHIoc2VsZiwgb2JqZWN0KQoKICAgIGRlZiByZXByMShzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgbWV0aG9kbmFtZSA9ICdyZXByXycgKyBqb2luKHNwbGl0KHR5cGUoeCkuX19uYW1lX18pLCAnXycpCiAgICAgICAgaWYgaGFzYXR0cihzZWxmLCBtZXRob2RuYW1lKToKICAgICAgICAgICAgcmV0dXJuIGdldGF0dHIoc2VsZiwgbWV0aG9kbmFtZSkoeCwgbGV2ZWwpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZXNjYXBlKGNyYW0oc3RyaXBpZChyZXByKHgpKSwgc2VsZi5tYXhvdGhlcikpCgogICAgZGVmIHJlcHJfc3RyaW5nKHNlbGYsIHgsIGxldmVsKToKICAgICAgICB0ZXN0ID0gY3JhbSh4LCBzZWxmLm1heHN0cmluZykKICAgICAgICB0ZXN0cmVwciA9IHJlcHIodGVzdCkKICAgICAgICBpZiAnXFwnIGluIHRlc3QgYW5kICdcXCcgbm90IGluIHJlcGxhY2UodGVzdHJlcHIsIHInXFwnLCAnJyk6CiAgICAgICAgICAgICMgQmFja3NsYXNoZXMgYXJlIG9ubHkgbGl0ZXJhbCBpbiB0aGUgc3RyaW5nIGFuZCBhcmUgbmV2ZXIKICAgICAgICAgICAgIyBuZWVkZWQgdG8gbWFrZSBhbnkgc3BlY2lhbCBjaGFyYWN0ZXJzLCBzbyBzaG93IGEgcmF3IHN0cmluZy4KICAgICAgICAgICAgcmV0dXJuICdyJyArIHRlc3RyZXByWzBdICsgc2VsZi5lc2NhcGUodGVzdCkgKyB0ZXN0cmVwclswXQogICAgICAgIHJldHVybiByZS5zdWIocicoKFxcW1xcYWJmbnJ0dlwnIl18XFxbMC05XS4ufFxceC4ufFxcdS4uLi4pKyknLAogICAgICAgICAgICAgICAgICAgICAgcic8Zm9udCBjb2xvcj0iI2MwNDBjMCI+XDE8L2ZvbnQ+JywKICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZXNjYXBlKHRlc3RyZXByKSkKCiAgICBkZWYgcmVwcl9pbnN0YW5jZShzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXR1cm4gc2VsZi5lc2NhcGUoY3JhbShzdHJpcGlkKHJlcHIoeCkpLCBzZWxmLm1heHN0cmluZykpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICByZXR1cm4gc2VsZi5lc2NhcGUoJzwlcyBpbnN0YW5jZT4nICUgeC5fX2NsYXNzX18uX19uYW1lX18pCgogICAgcmVwcl91bmljb2RlID0gcmVwcl9zdHJpbmcKCmNsYXNzIEhUTUxEb2MoRG9jKToKICAgICIiIkZvcm1hdHRlciBjbGFzcyBmb3IgSFRNTCBkb2N1bWVudGF0aW9uLiIiIgoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBIVE1MIGZvcm1hdHRpbmcgdXRpbGl0aWVzCgogICAgX3JlcHJfaW5zdGFuY2UgPSBIVE1MUmVwcigpCiAgICByZXByID0gX3JlcHJfaW5zdGFuY2UucmVwcgogICAgZXNjYXBlID0gX3JlcHJfaW5zdGFuY2UuZXNjYXBlCgogICAgZGVmIHBhZ2Uoc2VsZiwgdGl0bGUsIGNvbnRlbnRzKToKICAgICAgICAiIiJGb3JtYXQgYW4gSFRNTCBwYWdlLiIiIgogICAgICAgIHJldHVybiAnJycKPCFkb2N0eXBlIGh0bWwgcHVibGljICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KPGh0bWw+PGhlYWQ+PHRpdGxlPlB5dGhvbjogJXM8L3RpdGxlPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPjwhLS0KVFQgeyBmb250LWZhbWlseTogbHVjaWRhdHlwZXdyaXRlciwgbHVjaWRhIGNvbnNvbGUsIGNvdXJpZXIgfQotLT48L3N0eWxlPjwvaGVhZD48Ym9keSBiZ2NvbG9yPSIjZjBmMGY4Ij4KJXMKPC9ib2R5PjwvaHRtbD4nJycgJSAodGl0bGUsIGNvbnRlbnRzKQoKICAgIGRlZiBoZWFkaW5nKHNlbGYsIHRpdGxlLCBmZ2NvbCwgYmdjb2wsIGV4dHJhcz0nJyk6CiAgICAgICAgIiIiRm9ybWF0IGEgcGFnZSBoZWFkaW5nLiIiIgogICAgICAgIHJldHVybiAnJycKPHRhYmxlIHdpZHRoPSIxMDAlJSIgY2VsbHNwYWNpbmc9MCBjZWxscGFkZGluZz0yIGJvcmRlcj0wPgo8dHIgYmdjb2xvcj0iJXMiPgo8dGQgdmFsaWduPWJvdHRvbT48c21hbGw+Jm5ic3A7PGJyPjwvc21hbGwKPjxmb250IGNvbG9yPSIlcyIgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+Jm5ic3A7PGJyPiVzPC9mb250PjwvdGQKPjx0ZCBhbGlnbj1yaWdodCB2YWxpZ249Ym90dG9tCj48Zm9udCBjb2xvcj0iJXMiIGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPiVzPC9mb250PjwvdGQ+PC90cj48L3RhYmxlPgogICAgJycnICUgKGJnY29sLCBmZ2NvbCwgdGl0bGUsIGZnY29sLCBleHRyYXMgb3IgJyZuYnNwOycpCgogICAgZGVmIHNlY3Rpb24oc2VsZiwgdGl0bGUsIGZnY29sLCBiZ2NvbCwgY29udGVudHMsIHdpZHRoPTEwLAogICAgICAgICAgICAgICAgcHJlbHVkZT0nJywgbWFyZ2luYWxpYT1Ob25lLCBnYXA9JyZuYnNwOyZuYnNwOycpOgogICAgICAgICIiIkZvcm1hdCBhIHNlY3Rpb24gd2l0aCBhIGhlYWRpbmcuIiIiCiAgICAgICAgaWYgbWFyZ2luYWxpYSBpcyBOb25lOgogICAgICAgICAgICBtYXJnaW5hbGlhID0gJzx0dD4nICsgJyZuYnNwOycgKiB3aWR0aCArICc8L3R0PicKICAgICAgICByZXN1bHQgPSAnJycKPHA+PHRhYmxlIHdpZHRoPSIxMDAlJSIgY2VsbHNwYWNpbmc9MCBjZWxscGFkZGluZz0yIGJvcmRlcj0wPgo8dHIgYmdjb2xvcj0iJXMiPgo8dGQgY29sc3Bhbj0zIHZhbGlnbj1ib3R0b20+PHNtYWxsPjxzbWFsbD4mbmJzcDs8YnI+PC9zbWFsbD48L3NtYWxsCj48Zm9udCBjb2xvcj0iJXMiIGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPiVzPC9mb250PjwvdGQ+PC90cj4KICAgICcnJyAlIChiZ2NvbCwgZmdjb2wsIHRpdGxlKQogICAgICAgIGlmIHByZWx1ZGU6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICcnJwo8dHIgYmdjb2xvcj0iJXMiPjx0ZCByb3dzcGFuPTI+JXM8L3RkPgo8dGQgY29sc3Bhbj0yPiVzPC90ZD48L3RyPgo8dHI+PHRkPiVzPC90ZD4nJycgJSAoYmdjb2wsIG1hcmdpbmFsaWEsIHByZWx1ZGUsIGdhcCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnJycKPHRyPjx0ZCBiZ2NvbG9yPSIlcyI+JXM8L3RkPjx0ZD4lczwvdGQ+JycnICUgKGJnY29sLCBtYXJnaW5hbGlhLCBnYXApCgogICAgICAgIHJldHVybiByZXN1bHQgKyAnXG48dGQgd2lkdGg9IjEwMCUlIj4lczwvdGQ+PC90cj48L3RhYmxlPicgJSBjb250ZW50cwoKICAgIGRlZiBiaWdzZWN0aW9uKHNlbGYsIHRpdGxlLCAqYXJncyk6CiAgICAgICAgIiIiRm9ybWF0IGEgc2VjdGlvbiB3aXRoIGEgYmlnIGhlYWRpbmcuIiIiCiAgICAgICAgdGl0bGUgPSAnPGJpZz48c3Ryb25nPiVzPC9zdHJvbmc+PC9iaWc+JyAlIHRpdGxlCiAgICAgICAgcmV0dXJuIGFwcGx5KHNlbGYuc2VjdGlvbiwgKHRpdGxlLCkgKyBhcmdzKQoKICAgIGRlZiBwcmVmb3JtYXQoc2VsZiwgdGV4dCk6CiAgICAgICAgIiIiRm9ybWF0IGxpdGVyYWwgcHJlZm9ybWF0dGVkIHRleHQuIiIiCiAgICAgICAgdGV4dCA9IHNlbGYuZXNjYXBlKGV4cGFuZHRhYnModGV4dCkpCiAgICAgICAgcmV0dXJuIHJlcGxhY2UodGV4dCwgJ1xuXG4nLCAnXG4gXG4nLCAnXG5cbicsICdcbiBcbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyAnLCAnJm5ic3A7JywgJ1xuJywgJzxicj5cbicpCgogICAgZGVmIG11bHRpY29sdW1uKHNlbGYsIGxpc3QsIGZvcm1hdCwgY29scz00KToKICAgICAgICAiIiJGb3JtYXQgYSBsaXN0IG9mIGl0ZW1zIGludG8gYSBtdWx0aS1jb2x1bW4gbGlzdC4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIHJvd3MgPSAobGVuKGxpc3QpK2NvbHMtMSkvY29scwogICAgICAgIGZvciBjb2wgaW4gcmFuZ2UoY29scyk6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8dGQgd2lkdGg9IiVkJSUiIHZhbGlnbj10b3A+JyAlICgxMDAvY29scykKICAgICAgICAgICAgZm9yIGkgaW4gcmFuZ2Uocm93cypjb2wsIHJvd3MqY29sK3Jvd3MpOgogICAgICAgICAgICAgICAgaWYgaSA8IGxlbihsaXN0KToKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBmb3JtYXQobGlzdFtpXSkgKyAnPGJyPlxuJwogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPC90ZD4nCiAgICAgICAgcmV0dXJuICc8dGFibGUgd2lkdGg9IjEwMCUlIj48dHI+JXM8L3RyPjwvdGFibGU+JyAlIHJlc3VsdAoKICAgIGRlZiBzbWFsbChzZWxmLCB0ZXh0KTogcmV0dXJuICc8c21hbGw+JXM8L3NtYWxsPicgJSB0ZXh0CiAgICBkZWYgZ3JleShzZWxmLCB0ZXh0KTogcmV0dXJuICc8Zm9udCBjb2xvcj0iIzkwOTA5MCI+JXM8L2ZvbnQ+JyAlIHRleHQKCiAgICBkZWYgbmFtZWxpbmsoc2VsZiwgbmFtZSwgKmRpY3RzKToKICAgICAgICAiIiJNYWtlIGEgbGluayBmb3IgYW4gaWRlbnRpZmllciwgZ2l2ZW4gbmFtZS10by1VUkwgbWFwcGluZ3MuIiIiCiAgICAgICAgZm9yIGRpY3QgaW4gZGljdHM6CiAgICAgICAgICAgIGlmIGRpY3QuaGFzX2tleShuYW1lKToKICAgICAgICAgICAgICAgIHJldHVybiAnPGEgaHJlZj0iJXMiPiVzPC9hPicgJSAoZGljdFtuYW1lXSwgbmFtZSkKICAgICAgICByZXR1cm4gbmFtZQoKICAgIGRlZiBjbGFzc2xpbmsoc2VsZiwgb2JqZWN0LCBtb2RuYW1lKToKICAgICAgICAiIiJNYWtlIGEgbGluayBmb3IgYSBjbGFzcy4iIiIKICAgICAgICBuYW1lLCBtb2R1bGUgPSBvYmplY3QuX19uYW1lX18sIHN5cy5tb2R1bGVzLmdldChvYmplY3QuX19tb2R1bGVfXykKICAgICAgICBpZiBoYXNhdHRyKG1vZHVsZSwgbmFtZSkgYW5kIGdldGF0dHIobW9kdWxlLCBuYW1lKSBpcyBvYmplY3Q6CiAgICAgICAgICAgIHJldHVybiAnPGEgaHJlZj0iJXMuaHRtbCMlcyI+JXM8L2E+JyAlICgKICAgICAgICAgICAgICAgIG1vZHVsZS5fX25hbWVfXywgbmFtZSwgY2xhc3NuYW1lKG9iamVjdCwgbW9kbmFtZSkpCiAgICAgICAgcmV0dXJuIGNsYXNzbmFtZShvYmplY3QsIG1vZG5hbWUpCgogICAgZGVmIG1vZHVsZWxpbmsoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJNYWtlIGEgbGluayBmb3IgYSBtb2R1bGUuIiIiCiAgICAgICAgcmV0dXJuICc8YSBocmVmPSIlcy5odG1sIj4lczwvYT4nICUgKG9iamVjdC5fX25hbWVfXywgb2JqZWN0Ll9fbmFtZV9fKQoKICAgIGRlZiBtb2Rwa2dsaW5rKHNlbGYsIChuYW1lLCBwYXRoLCBpc3BhY2thZ2UsIHNoYWRvd2VkKSk6CiAgICAgICAgIiIiTWFrZSBhIGxpbmsgZm9yIGEgbW9kdWxlIG9yIHBhY2thZ2UgdG8gZGlzcGxheSBpbiBhbiBpbmRleC4iIiIKICAgICAgICBpZiBzaGFkb3dlZDoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZ3JleShuYW1lKQogICAgICAgIGlmIHBhdGg6CiAgICAgICAgICAgIHVybCA9ICclcy4lcy5odG1sJyAlIChwYXRoLCBuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHVybCA9ICclcy5odG1sJyAlIG5hbWUKICAgICAgICBpZiBpc3BhY2thZ2U6CiAgICAgICAgICAgIHRleHQgPSAnPHN0cm9uZz4lczwvc3Ryb25nPiZuYnNwOyhwYWNrYWdlKScgJSBuYW1lCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGV4dCA9IG5hbWUKICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKHVybCwgdGV4dCkKCiAgICBkZWYgbWFya3VwKHNlbGYsIHRleHQsIGVzY2FwZT1Ob25lLCBmdW5jcz17fSwgY2xhc3Nlcz17fSwgbWV0aG9kcz17fSk6CiAgICAgICAgIiIiTWFyayB1cCBzb21lIHBsYWluIHRleHQsIGdpdmVuIGEgY29udGV4dCBvZiBzeW1ib2xzIHRvIGxvb2sgZm9yLgogICAgICAgIEVhY2ggY29udGV4dCBkaWN0aW9uYXJ5IG1hcHMgb2JqZWN0IG5hbWVzIHRvIGFuY2hvciBuYW1lcy4iIiIKICAgICAgICBlc2NhcGUgPSBlc2NhcGUgb3Igc2VsZi5lc2NhcGUKICAgICAgICByZXN1bHRzID0gW10KICAgICAgICBoZXJlID0gMAogICAgICAgIHBhdHRlcm4gPSByZS5jb21waWxlKHInXGIoKGh0dHB8ZnRwKTovL1xTK1tcdy9dfCcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByJ1JGQ1stIF0/KFxkKyl8JwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHInUEVQWy0gXT8oXGQrKXwnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcicoc2VsZlwuKT8oXHcrKSlcYicpCiAgICAgICAgd2hpbGUgMToKICAgICAgICAgICAgbWF0Y2ggPSBwYXR0ZXJuLnNlYXJjaCh0ZXh0LCBoZXJlKQogICAgICAgICAgICBpZiBub3QgbWF0Y2g6IGJyZWFrCiAgICAgICAgICAgIHN0YXJ0LCBlbmQgPSBtYXRjaC5zcGFuKCkKICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoZXNjYXBlKHRleHRbaGVyZTpzdGFydF0pKQoKICAgICAgICAgICAgYWxsLCBzY2hlbWUsIHJmYywgcGVwLCBzZWxmZG90LCBuYW1lID0gbWF0Y2guZ3JvdXBzKCkKICAgICAgICAgICAgaWYgc2NoZW1lOgogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKGFsbCwgZXNjYXBlKGFsbCkpKQogICAgICAgICAgICBlbGlmIHJmYzoKICAgICAgICAgICAgICAgIHVybCA9ICdodHRwOi8vd3d3LnJmYy1lZGl0b3Iub3JnL3JmYy9yZmMlZC50eHQnICUgaW50KHJmYykKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCc8YSBocmVmPSIlcyI+JXM8L2E+JyAlICh1cmwsIGVzY2FwZShhbGwpKSkKICAgICAgICAgICAgZWxpZiBwZXA6CiAgICAgICAgICAgICAgICB1cmwgPSAnaHR0cDovL3d3dy5weXRob24ub3JnL3BlcHMvcGVwLSUwNGQuaHRtbCcgJSBpbnQocGVwKQogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKHVybCwgZXNjYXBlKGFsbCkpKQogICAgICAgICAgICBlbGlmIHRleHRbZW5kOmVuZCsxXSA9PSAnKCc6CiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZChzZWxmLm5hbWVsaW5rKG5hbWUsIG1ldGhvZHMsIGZ1bmNzLCBjbGFzc2VzKSkKICAgICAgICAgICAgZWxpZiBzZWxmZG90OgogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJ3NlbGYuPHN0cm9uZz4lczwvc3Ryb25nPicgJSBuYW1lKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoc2VsZi5uYW1lbGluayhuYW1lLCBjbGFzc2VzKSkKICAgICAgICAgICAgaGVyZSA9IGVuZAogICAgICAgIHJlc3VsdHMuYXBwZW5kKGVzY2FwZSh0ZXh0W2hlcmU6XSkpCiAgICAgICAgcmV0dXJuIGpvaW4ocmVzdWx0cywgJycpCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHR5cGUtc3BlY2lmaWMgcm91dGluZXMKCiAgICBkZWYgZm9ybWF0dHJlZShzZWxmLCB0cmVlLCBtb2RuYW1lLCBwYXJlbnQ9Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGZvciBhIGNsYXNzIHRyZWUgYXMgZ2l2ZW4gYnkgaW5zcGVjdC5nZXRjbGFzc3RyZWUoKS4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIGZvciBlbnRyeSBpbiB0cmVlOgogICAgICAgICAgICBpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKCgpKToKICAgICAgICAgICAgICAgIGMsIGJhc2VzID0gZW50cnkKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8ZHQ+PGZvbnQgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+PHNtYWxsPicKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuY2xhc3NsaW5rKGMsIG1vZG5hbWUpCiAgICAgICAgICAgICAgICBpZiBiYXNlcyBhbmQgYmFzZXMgIT0gKHBhcmVudCwpOgogICAgICAgICAgICAgICAgICAgIHBhcmVudHMgPSBbXQogICAgICAgICAgICAgICAgICAgIGZvciBiYXNlIGluIGJhc2VzOgogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRzLmFwcGVuZChzZWxmLmNsYXNzbGluayhiYXNlLCBtb2RuYW1lKSkKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnKCcgKyBqb2luKHBhcmVudHMsICcsICcpICsgJyknCiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnXG48L3NtYWxsPjwvZm9udD48L2R0PicKICAgICAgICAgICAgZWxpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKFtdKToKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8ZGQ+XG4lczwvZGQ+XG4nICUgc2VsZi5mb3JtYXR0cmVlKAogICAgICAgICAgICAgICAgICAgIGVudHJ5LCBtb2RuYW1lLCBjKQogICAgICAgIHJldHVybiAnPGRsPlxuJXM8L2RsPlxuJyAlIHJlc3VsdAoKICAgIGRlZiBkb2Ntb2R1bGUoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBtb2R1bGUgb2JqZWN0LiIiIgogICAgICAgIG5hbWUgPSBvYmplY3QuX19uYW1lX18gIyBpZ25vcmUgdGhlIHBhc3NlZC1pbiBuYW1lCiAgICAgICAgcGFydHMgPSBzcGxpdChuYW1lLCAnLicpCiAgICAgICAgbGlua3MgPSBbXQogICAgICAgIGZvciBpIGluIHJhbmdlKGxlbihwYXJ0cyktMSk6CiAgICAgICAgICAgIGxpbmtzLmFwcGVuZCgKICAgICAgICAgICAgICAgICc8YSBocmVmPSIlcy5odG1sIj48Zm9udCBjb2xvcj0iI2ZmZmZmZiI+JXM8L2ZvbnQ+PC9hPicgJQogICAgICAgICAgICAgICAgKGpvaW4ocGFydHNbOmkrMV0sICcuJyksIHBhcnRzW2ldKSkKICAgICAgICBsaW5rZWRuYW1lID0gam9pbihsaW5rcyArIHBhcnRzWy0xOl0sICcuJykKICAgICAgICBoZWFkID0gJzxiaWc+PGJpZz48c3Ryb25nPiVzPC9zdHJvbmc+PC9iaWc+PC9iaWc+JyAlIGxpbmtlZG5hbWUKICAgICAgICB0cnk6CiAgICAgICAgICAgIHBhdGggPSBpbnNwZWN0LmdldGFic2ZpbGUob2JqZWN0KQogICAgICAgICAgICB1cmwgPSBwYXRoCiAgICAgICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInOgogICAgICAgICAgICAgICAgaW1wb3J0IG50dXJsMnBhdGgKICAgICAgICAgICAgICAgIHVybCA9IG50dXJsMnBhdGgucGF0aG5hbWUydXJsKHBhdGgpCiAgICAgICAgICAgIGZpbGVsaW5rID0gJzxhIGhyZWY9ImZpbGU6JXMiPiVzPC9hPicgJSAodXJsLCBwYXRoKQogICAgICAgIGV4Y2VwdCBUeXBlRXJyb3I6CiAgICAgICAgICAgIGZpbGVsaW5rID0gJyhidWlsdC1pbiknCiAgICAgICAgaW5mbyA9IFtdCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX3ZlcnNpb25fXycpOgogICAgICAgICAgICB2ZXJzaW9uID0gc3RyKG9iamVjdC5fX3ZlcnNpb25fXykKICAgICAgICAgICAgaWYgdmVyc2lvbls6MTFdID09ICckJyArICdSZXZpc2lvbjogJyBhbmQgdmVyc2lvblstMTpdID09ICckJzoKICAgICAgICAgICAgICAgIHZlcnNpb24gPSBzdHJpcCh2ZXJzaW9uWzExOi0xXSkKICAgICAgICAgICAgaW5mby5hcHBlbmQoJ3ZlcnNpb24gJXMnICUgc2VsZi5lc2NhcGUodmVyc2lvbikpCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2RhdGVfXycpOgogICAgICAgICAgICBpbmZvLmFwcGVuZChzZWxmLmVzY2FwZShzdHIob2JqZWN0Ll9fZGF0ZV9fKSkpCiAgICAgICAgaWYgaW5mbzoKICAgICAgICAgICAgaGVhZCA9IGhlYWQgKyAnICglcyknICUgam9pbihpbmZvLCAnLCAnKQogICAgICAgIHJlc3VsdCA9IHNlbGYuaGVhZGluZygKICAgICAgICAgICAgaGVhZCwgJyNmZmZmZmYnLCAnIzc3OTllZScsICc8YSBocmVmPSIuIj5pbmRleDwvYT48YnI+JyArIGZpbGVsaW5rKQoKICAgICAgICBtb2R1bGVzID0gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc21vZHVsZSkKCiAgICAgICAgY2xhc3NlcywgY2RpY3QgPSBbXSwge30KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0LmlzY2xhc3MpOgogICAgICAgICAgICBpZiAoaW5zcGVjdC5nZXRtb2R1bGUodmFsdWUpIG9yIG9iamVjdCkgaXMgb2JqZWN0OgogICAgICAgICAgICAgICAgY2xhc3Nlcy5hcHBlbmQoKGtleSwgdmFsdWUpKQogICAgICAgICAgICAgICAgY2RpY3Rba2V5XSA9IGNkaWN0W3ZhbHVlXSA9ICcjJyArIGtleQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGNsYXNzZXM6CiAgICAgICAgICAgIGZvciBiYXNlIGluIHZhbHVlLl9fYmFzZXNfXzoKICAgICAgICAgICAgICAgIGtleSwgbW9kbmFtZSA9IGJhc2UuX19uYW1lX18sIGJhc2UuX19tb2R1bGVfXwogICAgICAgICAgICAgICAgbW9kdWxlID0gc3lzLm1vZHVsZXMuZ2V0KG1vZG5hbWUpCiAgICAgICAgICAgICAgICBpZiBtb2RuYW1lICE9IG5hbWUgYW5kIG1vZHVsZSBhbmQgaGFzYXR0cihtb2R1bGUsIGtleSk6CiAgICAgICAgICAgICAgICAgICAgaWYgZ2V0YXR0cihtb2R1bGUsIGtleSkgaXMgYmFzZToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm90IGNkaWN0Lmhhc19rZXkoa2V5KToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNkaWN0W2tleV0gPSBjZGljdFtiYXNlXSA9IG1vZG5hbWUgKyAnLmh0bWwjJyArIGtleQogICAgICAgIGZ1bmNzLCBmZGljdCA9IFtdLCB7fQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNyb3V0aW5lKToKICAgICAgICAgICAgaWYgaW5zcGVjdC5pc2J1aWx0aW4odmFsdWUpIG9yIGluc3BlY3QuZ2V0bW9kdWxlKHZhbHVlKSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBmdW5jcy5hcHBlbmQoKGtleSwgdmFsdWUpKQogICAgICAgICAgICAgICAgZmRpY3Rba2V5XSA9ICcjLScgKyBrZXkKICAgICAgICAgICAgICAgIGlmIGluc3BlY3QuaXNmdW5jdGlvbih2YWx1ZSk6IGZkaWN0W3ZhbHVlXSA9IGZkaWN0W2tleV0KICAgICAgICBkYXRhID0gW10KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpc2RhdGEpOgogICAgICAgICAgICBpZiBrZXkgbm90IGluIFsnX19idWlsdGluc19fJywgJ19fZG9jX18nXToKICAgICAgICAgICAgICAgIGRhdGEuYXBwZW5kKChrZXksIHZhbHVlKSkKCiAgICAgICAgZG9jID0gc2VsZi5tYXJrdXAoZ2V0ZG9jKG9iamVjdCksIHNlbGYucHJlZm9ybWF0LCBmZGljdCwgY2RpY3QpCiAgICAgICAgZG9jID0gZG9jIGFuZCAnPHR0PiVzPC90dD4nICUgZG9jCiAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJzxwPiVzPC9wPlxuJyAlIHNlbGYuc21hbGwoZG9jKQoKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fcGF0aF9fJyk6CiAgICAgICAgICAgIG1vZHBrZ3MgPSBbXQogICAgICAgICAgICBtb2RuYW1lcyA9IFtdCiAgICAgICAgICAgIGZvciBmaWxlIGluIG9zLmxpc3RkaXIob2JqZWN0Ll9fcGF0aF9fWzBdKToKICAgICAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4ob2JqZWN0Ll9fcGF0aF9fWzBdLCBmaWxlKQogICAgICAgICAgICAgICAgbW9kbmFtZSA9IGluc3BlY3QuZ2V0bW9kdWxlbmFtZShmaWxlKQogICAgICAgICAgICAgICAgaWYgbW9kbmFtZSBhbmQgbW9kbmFtZSBub3QgaW4gbW9kbmFtZXM6CiAgICAgICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQoKG1vZG5hbWUsIG5hbWUsIDAsIDApKQogICAgICAgICAgICAgICAgICAgIG1vZG5hbWVzLmFwcGVuZChtb2RuYW1lKQogICAgICAgICAgICAgICAgZWxpZiBpc3BhY2thZ2UocGF0aCk6CiAgICAgICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQoKGZpbGUsIG5hbWUsIDEsIDApKQogICAgICAgICAgICBtb2Rwa2dzLnNvcnQoKQogICAgICAgICAgICBjb250ZW50cyA9IHNlbGYubXVsdGljb2x1bW4obW9kcGtncywgc2VsZi5tb2Rwa2dsaW5rKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnUGFja2FnZSBDb250ZW50cycsICcjZmZmZmZmJywgJyNhYTU1Y2MnLCBjb250ZW50cykKICAgICAgICBlbGlmIG1vZHVsZXM6CiAgICAgICAgICAgIGNvbnRlbnRzID0gc2VsZi5tdWx0aWNvbHVtbigKICAgICAgICAgICAgICAgIG1vZHVsZXMsIGxhbWJkYSAoa2V5LCB2YWx1ZSksIHM9c2VsZjogcy5tb2R1bGVsaW5rKHZhbHVlKSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ01vZHVsZXMnLCAnI2ZmZmZmJywgJyNhYTU1Y2MnLCBjb250ZW50cykKCiAgICAgICAgaWYgY2xhc3NlczoKICAgICAgICAgICAgY2xhc3NsaXN0ID0gbWFwKGxhbWJkYSAoa2V5LCB2YWx1ZSk6IHZhbHVlLCBjbGFzc2VzKQogICAgICAgICAgICBjb250ZW50cyA9IFsKICAgICAgICAgICAgICAgIHNlbGYuZm9ybWF0dHJlZShpbnNwZWN0LmdldGNsYXNzdHJlZShjbGFzc2xpc3QsIDEpLCBuYW1lKV0KICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gY2xhc3NlczoKICAgICAgICAgICAgICAgIGNvbnRlbnRzLmFwcGVuZChzZWxmLmRvY3VtZW50KHZhbHVlLCBrZXksIG5hbWUsIGZkaWN0LCBjZGljdCkpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdDbGFzc2VzJywgJyNmZmZmZmYnLCAnI2VlNzdhYScsIGpvaW4oY29udGVudHMpKQogICAgICAgIGlmIGZ1bmNzOgogICAgICAgICAgICBjb250ZW50cyA9IFtdCiAgICAgICAgICAgIGZvciBrZXksIHZhbHVlIGluIGZ1bmNzOgogICAgICAgICAgICAgICAgY29udGVudHMuYXBwZW5kKHNlbGYuZG9jdW1lbnQodmFsdWUsIGtleSwgbmFtZSwgZmRpY3QsIGNkaWN0KSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0Z1bmN0aW9ucycsICcjZmZmZmZmJywgJyNlZWFhNzcnLCBqb2luKGNvbnRlbnRzKSkKICAgICAgICBpZiBkYXRhOgogICAgICAgICAgICBjb250ZW50cyA9IFtdCiAgICAgICAgICAgIGZvciBrZXksIHZhbHVlIGluIGRhdGE6CiAgICAgICAgICAgICAgICBjb250ZW50cy5hcHBlbmQoc2VsZi5kb2N1bWVudCh2YWx1ZSwga2V5KSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0RhdGEnLCAnI2ZmZmZmZicsICcjNTVhYTU1Jywgam9pbihjb250ZW50cywgJzxicj5cbicpKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19hdXRob3JfXycpOgogICAgICAgICAgICBjb250ZW50cyA9IHNlbGYubWFya3VwKHN0cihvYmplY3QuX19hdXRob3JfXyksIHNlbGYucHJlZm9ybWF0KQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnQXV0aG9yJywgJyNmZmZmZmYnLCAnIzc3OTllZScsIGNvbnRlbnRzKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19jcmVkaXRzX18nKToKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm1hcmt1cChzdHIob2JqZWN0Ll9fY3JlZGl0c19fKSwgc2VsZi5wcmVmb3JtYXQpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdDcmVkaXRzJywgJyNmZmZmZmYnLCAnIzc3OTllZScsIGNvbnRlbnRzKQoKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIGRvY2NsYXNzKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCBtb2Q9Tm9uZSwgZnVuY3M9e30sIGNsYXNzZXM9e30pOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIGNsYXNzIG9iamVjdC4iIiIKICAgICAgICByZWFsbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIG5hbWUgPSBuYW1lIG9yIHJlYWxuYW1lCiAgICAgICAgYmFzZXMgPSBvYmplY3QuX19iYXNlc19fCiAgICAgICAgY29udGVudHMgPSAnJwoKICAgICAgICBtZXRob2RzLCBtZGljdCA9IGFsbG1ldGhvZHMob2JqZWN0KS5pdGVtcygpLCB7fQogICAgICAgIG1ldGhvZHMuc29ydCgpCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gbWV0aG9kczoKICAgICAgICAgICAgbWRpY3Rba2V5XSA9IG1kaWN0W3ZhbHVlXSA9ICcjJyArIG5hbWUgKyAnLScgKyBrZXkKICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBtZXRob2RzOgogICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgc2VsZi5kb2N1bWVudCgKICAgICAgICAgICAgICAgIHZhbHVlLCBrZXksIG1vZCwgZnVuY3MsIGNsYXNzZXMsIG1kaWN0LCBvYmplY3QpCgogICAgICAgIGlmIG5hbWUgPT0gcmVhbG5hbWU6CiAgICAgICAgICAgIHRpdGxlID0gJzxhIG5hbWU9IiVzIj5jbGFzcyA8c3Ryb25nPiVzPC9zdHJvbmc+PC9hPicgJSAoCiAgICAgICAgICAgICAgICBuYW1lLCByZWFsbmFtZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICB0aXRsZSA9ICc8c3Ryb25nPiVzPC9zdHJvbmc+ID0gPGEgbmFtZT0iJXMiPmNsYXNzICVzPC9hPicgJSAoCiAgICAgICAgICAgICAgICBuYW1lLCBuYW1lLCByZWFsbmFtZSkKICAgICAgICBpZiBiYXNlczoKICAgICAgICAgICAgcGFyZW50cyA9IFtdCiAgICAgICAgICAgIGZvciBiYXNlIGluIGJhc2VzOgogICAgICAgICAgICAgICAgcGFyZW50cy5hcHBlbmQoc2VsZi5jbGFzc2xpbmsoYmFzZSwgb2JqZWN0Ll9fbW9kdWxlX18pKQogICAgICAgICAgICB0aXRsZSA9IHRpdGxlICsgJyglcyknICUgam9pbihwYXJlbnRzLCAnLCAnKQogICAgICAgIGRvYyA9IHNlbGYubWFya3VwKAogICAgICAgICAgICBnZXRkb2Mob2JqZWN0KSwgc2VsZi5wcmVmb3JtYXQsIGZ1bmNzLCBjbGFzc2VzLCBtZGljdCkKICAgICAgICBkb2MgPSBzZWxmLnNtYWxsKGRvYyBhbmQgJzx0dD4lczxicj4mbmJzcDs8L3R0PicgJSBkb2Mgb3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zbWFsbCgnJm5ic3A7JykpCiAgICAgICAgcmV0dXJuIHNlbGYuc2VjdGlvbih0aXRsZSwgJyMwMDAwMDAnLCAnI2ZmYzhkOCcsIGNvbnRlbnRzLCA1LCBkb2MpCgogICAgZGVmIGZvcm1hdHZhbHVlKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiRm9ybWF0IGFuIGFyZ3VtZW50IGRlZmF1bHQgdmFsdWUgYXMgdGV4dC4iIiIKICAgICAgICByZXR1cm4gc2VsZi5zbWFsbChzZWxmLmdyZXkoJz0nICsgc2VsZi5yZXByKG9iamVjdCkpKQoKICAgIGRlZiBkb2Nyb3V0aW5lKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCBtb2Q9Tm9uZSwKICAgICAgICAgICAgICAgICAgIGZ1bmNzPXt9LCBjbGFzc2VzPXt9LCBtZXRob2RzPXt9LCBjbD1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBmdW5jdGlvbiBvciBtZXRob2Qgb2JqZWN0LiIiIgogICAgICAgIHJlYWxuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgbmFtZSA9IG5hbWUgb3IgcmVhbG5hbWUKICAgICAgICBhbmNob3IgPSAoY2wgYW5kIGNsLl9fbmFtZV9fIG9yICcnKSArICctJyArIG5hbWUKICAgICAgICBub3RlID0gJycKICAgICAgICBza2lwZG9jcyA9IDAKICAgICAgICBpZiBpbnNwZWN0LmlzbWV0aG9kKG9iamVjdCk6CiAgICAgICAgICAgIGltY2xhc3MgPSBvYmplY3QuaW1fY2xhc3MKICAgICAgICAgICAgaWYgY2w6CiAgICAgICAgICAgICAgICBpZiBpbWNsYXNzIGlzIG5vdCBjbDoKICAgICAgICAgICAgICAgICAgICBub3RlID0gJyBmcm9tICcgKyBzZWxmLmNsYXNzbGluayhpbWNsYXNzLCBtb2QpCiAgICAgICAgICAgICAgICAgICAgc2tpcGRvY3MgPSAxCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBpZiBvYmplY3QuaW1fc2VsZjoKICAgICAgICAgICAgICAgICAgICBub3RlID0gJyBtZXRob2Qgb2YgJXMgaW5zdGFuY2UnICUgc2VsZi5jbGFzc2xpbmsoCiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5pbV9zZWxmLl9fY2xhc3NfXywgbW9kKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBub3RlID0gJyB1bmJvdW5kICVzIG1ldGhvZCcgJSBzZWxmLmNsYXNzbGluayhpbWNsYXNzLG1vZCkKICAgICAgICAgICAgb2JqZWN0ID0gb2JqZWN0LmltX2Z1bmMKCiAgICAgICAgaWYgbmFtZSA9PSByZWFsbmFtZToKICAgICAgICAgICAgdGl0bGUgPSAnPGEgbmFtZT0iJXMiPjxzdHJvbmc+JXM8L3N0cm9uZz48L2E+JyAlIChhbmNob3IsIHJlYWxuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIChjbCBhbmQgY2wuX19kaWN0X18uaGFzX2tleShyZWFsbmFtZSkgYW5kCiAgICAgICAgICAgICAgICBjbC5fX2RpY3RfX1tyZWFsbmFtZV0gaXMgb2JqZWN0KToKICAgICAgICAgICAgICAgIHJlYWxsaW5rID0gJzxhIGhyZWY9IiMlcyI+JXM8L2E+JyAlICgKICAgICAgICAgICAgICAgICAgICBjbC5fX25hbWVfXyArICctJyArIHJlYWxuYW1lLCByZWFsbmFtZSkKICAgICAgICAgICAgICAgIHNraXBkb2NzID0gMQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmVhbGxpbmsgPSByZWFsbmFtZQogICAgICAgICAgICB0aXRsZSA9ICc8YSBuYW1lPSIlcyI+PHN0cm9uZz4lczwvc3Ryb25nPjwvYT4gPSAlcycgJSAoCiAgICAgICAgICAgICAgICBhbmNob3IsIG5hbWUsIHJlYWxsaW5rKQogICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKG9iamVjdCkgb3IgaW5zcGVjdC5pc21ldGhvZGRlc2NyaXB0b3Iob2JqZWN0KToKICAgICAgICAgICAgYXJnc3BlYyA9ICcoLi4uKScKICAgICAgICBlbHNlOgogICAgICAgICAgICBhcmdzLCB2YXJhcmdzLCB2YXJrdywgZGVmYXVsdHMgPSBpbnNwZWN0LmdldGFyZ3NwZWMob2JqZWN0KQogICAgICAgICAgICBhcmdzcGVjID0gaW5zcGVjdC5mb3JtYXRhcmdzcGVjKAogICAgICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzLCBmb3JtYXR2YWx1ZT1zZWxmLmZvcm1hdHZhbHVlKQogICAgICAgICAgICBpZiByZWFsbmFtZSA9PSAnPGxhbWJkYT4nOgogICAgICAgICAgICAgICAgZGVjbCA9ICc8ZW0+bGFtYmRhPC9lbT4nCiAgICAgICAgICAgICAgICBhcmdzcGVjID0gYXJnc3BlY1sxOi0xXSAjIHJlbW92ZSBwYXJlbnRoZXNlcwoKICAgICAgICBkZWNsID0gdGl0bGUgKyBhcmdzcGVjICsgKG5vdGUgYW5kIHNlbGYuc21hbGwoc2VsZi5ncmV5KAogICAgICAgICAgICAnPGZvbnQgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+JXM8L2ZvbnQ+JyAlIG5vdGUpKSkKCiAgICAgICAgaWYgc2tpcGRvY3M6CiAgICAgICAgICAgIHJldHVybiAnPGRsPjxkdD4lczwvZGw+XG4nICUgZGVjbAogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGRvYyA9IHNlbGYubWFya3VwKAogICAgICAgICAgICAgICAgZ2V0ZG9jKG9iamVjdCksIHNlbGYucHJlZm9ybWF0LCBmdW5jcywgY2xhc3NlcywgbWV0aG9kcykKICAgICAgICAgICAgZG9jID0gZG9jIGFuZCAnPGRkPicgKyBzZWxmLnNtYWxsKCc8dHQ+JXM8L3R0PicgJSBkb2MpCiAgICAgICAgICAgIHJldHVybiAnPGRsPjxkdD4lcyVzPC9kbD5cbicgJSAoZGVjbCwgZG9jKQoKICAgIGRlZiBkb2NvdGhlcihzZWxmLCBvYmplY3QsIG5hbWU9Tm9uZSwgbW9kPU5vbmUpOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIGRhdGEgb2JqZWN0LiIiIgogICAgICAgIGxocyA9IG5hbWUgYW5kICc8c3Ryb25nPiVzPC9zdHJvbmc+ID0gJyAlIG5hbWUgb3IgJycKICAgICAgICByZXR1cm4gbGhzICsgc2VsZi5yZXByKG9iamVjdCkKCiAgICBkZWYgaW5kZXgoc2VsZiwgZGlyLCBzaGFkb3dlZD1Ob25lKToKICAgICAgICAiIiJHZW5lcmF0ZSBhbiBIVE1MIGluZGV4IGZvciBhIGRpcmVjdG9yeSBvZiBtb2R1bGVzLiIiIgogICAgICAgIG1vZHBrZ3MgPSBbXQogICAgICAgIGlmIHNoYWRvd2VkIGlzIE5vbmU6IHNoYWRvd2VkID0ge30KICAgICAgICBzZWVuID0ge30KICAgICAgICBmaWxlcyA9IG9zLmxpc3RkaXIoZGlyKQoKICAgICAgICBkZWYgZm91bmQobmFtZSwgaXNwYWNrYWdlLAogICAgICAgICAgICAgICAgICBtb2Rwa2dzPW1vZHBrZ3MsIHNoYWRvd2VkPXNoYWRvd2VkLCBzZWVuPXNlZW4pOgogICAgICAgICAgICBpZiBub3Qgc2Vlbi5oYXNfa2V5KG5hbWUpOgogICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQoKG5hbWUsICcnLCBpc3BhY2thZ2UsIHNoYWRvd2VkLmhhc19rZXkobmFtZSkpKQogICAgICAgICAgICAgICAgc2VlbltuYW1lXSA9IDEKICAgICAgICAgICAgICAgIHNoYWRvd2VkW25hbWVdID0gMQoKICAgICAgICAjIFBhY2thZ2Ugc3BhbS9fX2luaXRfXy5weSB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgbW9kdWxlIHNwYW0ucHkuCiAgICAgICAgZm9yIGZpbGUgaW4gZmlsZXM6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oZGlyLCBmaWxlKQogICAgICAgICAgICBpZiBpc3BhY2thZ2UocGF0aCk6IGZvdW5kKGZpbGUsIDEpCiAgICAgICAgZm9yIGZpbGUgaW4gZmlsZXM6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oZGlyLCBmaWxlKQogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZmlsZShwYXRoKToKICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBpbnNwZWN0LmdldG1vZHVsZW5hbWUoZmlsZSkKICAgICAgICAgICAgICAgIGlmIG1vZG5hbWU6IGZvdW5kKG1vZG5hbWUsIDApCgogICAgICAgIG1vZHBrZ3Muc29ydCgpCiAgICAgICAgY29udGVudHMgPSBzZWxmLm11bHRpY29sdW1uKG1vZHBrZ3MsIHNlbGYubW9kcGtnbGluaykKICAgICAgICByZXR1cm4gc2VsZi5iaWdzZWN0aW9uKGRpciwgJyNmZmZmZmYnLCAnI2VlNzdhYScsIGNvbnRlbnRzKQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0ZXh0IGRvY3VtZW50YXRpb24gZ2VuZXJhdG9yCgpjbGFzcyBUZXh0UmVwcihSZXByKToKICAgICIiIkNsYXNzIGZvciBzYWZlbHkgbWFraW5nIGEgdGV4dCByZXByZXNlbnRhdGlvbiBvZiBhIFB5dGhvbiBvYmplY3QuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgUmVwci5fX2luaXRfXyhzZWxmKQogICAgICAgIHNlbGYubWF4bGlzdCA9IHNlbGYubWF4dHVwbGUgPSAyMAogICAgICAgIHNlbGYubWF4ZGljdCA9IDEwCiAgICAgICAgc2VsZi5tYXhzdHJpbmcgPSBzZWxmLm1heG90aGVyID0gMTAwCgogICAgZGVmIHJlcHIxKHNlbGYsIHgsIGxldmVsKToKICAgICAgICBtZXRob2RuYW1lID0gJ3JlcHJfJyArIGpvaW4oc3BsaXQodHlwZSh4KS5fX25hbWVfXyksICdfJykKICAgICAgICBpZiBoYXNhdHRyKHNlbGYsIG1ldGhvZG5hbWUpOgogICAgICAgICAgICByZXR1cm4gZ2V0YXR0cihzZWxmLCBtZXRob2RuYW1lKSh4LCBsZXZlbCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gY3JhbShzdHJpcGlkKHJlcHIoeCkpLCBzZWxmLm1heG90aGVyKQoKICAgIGRlZiByZXByX3N0cmluZyhzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgdGVzdCA9IGNyYW0oeCwgc2VsZi5tYXhzdHJpbmcpCiAgICAgICAgdGVzdHJlcHIgPSByZXByKHRlc3QpCiAgICAgICAgaWYgJ1xcJyBpbiB0ZXN0IGFuZCAnXFwnIG5vdCBpbiByZXBsYWNlKHRlc3RyZXByLCByJ1xcJywgJycpOgogICAgICAgICAgICAjIEJhY2tzbGFzaGVzIGFyZSBvbmx5IGxpdGVyYWwgaW4gdGhlIHN0cmluZyBhbmQgYXJlIG5ldmVyCiAgICAgICAgICAgICMgbmVlZGVkIHRvIG1ha2UgYW55IHNwZWNpYWwgY2hhcmFjdGVycywgc28gc2hvdyBhIHJhdyBzdHJpbmcuCiAgICAgICAgICAgIHJldHVybiAncicgKyB0ZXN0cmVwclswXSArIHRlc3QgKyB0ZXN0cmVwclswXQogICAgICAgIHJldHVybiB0ZXN0cmVwcgoKICAgIGRlZiByZXByX2luc3RhbmNlKHNlbGYsIHgsIGxldmVsKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHJldHVybiBjcmFtKHN0cmlwaWQocmVwcih4KSksIHNlbGYubWF4c3RyaW5nKQogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgcmV0dXJuICc8JXMgaW5zdGFuY2U+JyAlIHguX19jbGFzc19fLl9fbmFtZV9fCgpjbGFzcyBUZXh0RG9jKERvYyk6CiAgICAiIiJGb3JtYXR0ZXIgY2xhc3MgZm9yIHRleHQgZG9jdW1lbnRhdGlvbi4iIiIKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdGV4dCBmb3JtYXR0aW5nIHV0aWxpdGllcwoKICAgIF9yZXByX2luc3RhbmNlID0gVGV4dFJlcHIoKQogICAgcmVwciA9IF9yZXByX2luc3RhbmNlLnJlcHIKCiAgICBkZWYgYm9sZChzZWxmLCB0ZXh0KToKICAgICAgICAiIiJGb3JtYXQgYSBzdHJpbmcgaW4gYm9sZCBieSBvdmVyc3RyaWtpbmcuIiIiCiAgICAgICAgcmV0dXJuIGpvaW4obWFwKGxhbWJkYSBjaDogY2ggKyAnXGInICsgY2gsIHRleHQpLCAnJykKCiAgICBkZWYgaW5kZW50KHNlbGYsIHRleHQsIHByZWZpeD0nICAgICcpOgogICAgICAgICIiIkluZGVudCB0ZXh0IGJ5IHByZXBlbmRpbmcgYSBnaXZlbiBwcmVmaXggdG8gZWFjaCBsaW5lLiIiIgogICAgICAgIGlmIG5vdCB0ZXh0OiByZXR1cm4gJycKICAgICAgICBsaW5lcyA9IHNwbGl0KHRleHQsICdcbicpCiAgICAgICAgbGluZXMgPSBtYXAobGFtYmRhIGxpbmUsIHByZWZpeD1wcmVmaXg6IHByZWZpeCArIGxpbmUsIGxpbmVzKQogICAgICAgIGlmIGxpbmVzOiBsaW5lc1stMV0gPSByc3RyaXAobGluZXNbLTFdKQogICAgICAgIHJldHVybiBqb2luKGxpbmVzLCAnXG4nKQoKICAgIGRlZiBzZWN0aW9uKHNlbGYsIHRpdGxlLCBjb250ZW50cyk6CiAgICAgICAgIiIiRm9ybWF0IGEgc2VjdGlvbiB3aXRoIGEgZ2l2ZW4gaGVhZGluZy4iIiIKICAgICAgICByZXR1cm4gc2VsZi5ib2xkKHRpdGxlKSArICdcbicgKyByc3RyaXAoc2VsZi5pbmRlbnQoY29udGVudHMpKSArICdcblxuJwoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlLXNwZWNpZmljIHJvdXRpbmVzCgogICAgZGVmIGZvcm1hdHRyZWUoc2VsZiwgdHJlZSwgbW9kbmFtZSwgcGFyZW50PU5vbmUsIHByZWZpeD0nJyk6CiAgICAgICAgIiIiUmVuZGVyIGluIHRleHQgYSBjbGFzcyB0cmVlIGFzIHJldHVybmVkIGJ5IGluc3BlY3QuZ2V0Y2xhc3N0cmVlKCkuIiIiCiAgICAgICAgcmVzdWx0ID0gJycKICAgICAgICBmb3IgZW50cnkgaW4gdHJlZToKICAgICAgICAgICAgaWYgdHlwZShlbnRyeSkgaXMgdHlwZSgoKSk6CiAgICAgICAgICAgICAgICBjLCBiYXNlcyA9IGVudHJ5CiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBwcmVmaXggKyBjbGFzc25hbWUoYywgbW9kbmFtZSkKICAgICAgICAgICAgICAgIGlmIGJhc2VzIGFuZCBiYXNlcyAhPSAocGFyZW50LCk6CiAgICAgICAgICAgICAgICAgICAgcGFyZW50cyA9IG1hcChsYW1iZGEgYywgbT1tb2RuYW1lOiBjbGFzc25hbWUoYywgbSksIGJhc2VzKQogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICcoJXMpJyAlIGpvaW4ocGFyZW50cywgJywgJykKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICdcbicKICAgICAgICAgICAgZWxpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKFtdKToKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuZm9ybWF0dHJlZSgKICAgICAgICAgICAgICAgICAgICBlbnRyeSwgbW9kbmFtZSwgYywgcHJlZml4ICsgJyAgICAnKQogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBkZWYgZG9jbW9kdWxlKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCBtb2Q9Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSB0ZXh0IGRvY3VtZW50YXRpb24gZm9yIGEgZ2l2ZW4gbW9kdWxlIG9iamVjdC4iIiIKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fICMgaWdub3JlIHRoZSBwYXNzZWQtaW4gbmFtZQogICAgICAgIHN5bm9wLCBkZXNjID0gc3BsaXRkb2MoZ2V0ZG9jKG9iamVjdCkpCiAgICAgICAgcmVzdWx0ID0gc2VsZi5zZWN0aW9uKCdOQU1FJywgbmFtZSArIChzeW5vcCBhbmQgJyAtICcgKyBzeW5vcCkpCgogICAgICAgIHRyeToKICAgICAgICAgICAgZmlsZSA9IGluc3BlY3QuZ2V0YWJzZmlsZShvYmplY3QpCiAgICAgICAgZXhjZXB0IFR5cGVFcnJvcjoKICAgICAgICAgICAgZmlsZSA9ICcoYnVpbHQtaW4pJwogICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignRklMRScsIGZpbGUpCiAgICAgICAgaWYgZGVzYzoKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdERVNDUklQVElPTicsIGRlc2MpCgogICAgICAgIGNsYXNzZXMgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNjbGFzcyk6CiAgICAgICAgICAgIGlmIChpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgb3Igb2JqZWN0KSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBjbGFzc2VzLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCiAgICAgICAgZnVuY3MgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNyb3V0aW5lKToKICAgICAgICAgICAgaWYgaW5zcGVjdC5pc2J1aWx0aW4odmFsdWUpIG9yIGluc3BlY3QuZ2V0bW9kdWxlKHZhbHVlKSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBmdW5jcy5hcHBlbmQoKGtleSwgdmFsdWUpKQogICAgICAgIGRhdGEgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGlzZGF0YSk6CiAgICAgICAgICAgIGlmIGtleSBub3QgaW4gWydfX2J1aWx0aW5zX18nLCAnX19kb2NfXyddOgogICAgICAgICAgICAgICAgZGF0YS5hcHBlbmQoKGtleSwgdmFsdWUpKQoKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fcGF0aF9fJyk6CiAgICAgICAgICAgIG1vZHBrZ3MgPSBbXQogICAgICAgICAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKG9iamVjdC5fX3BhdGhfX1swXSk6CiAgICAgICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKG9iamVjdC5fX3BhdGhfX1swXSwgZmlsZSkKICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBpbnNwZWN0LmdldG1vZHVsZW5hbWUoZmlsZSkKICAgICAgICAgICAgICAgIGlmIG1vZG5hbWUgYW5kIG1vZG5hbWUgbm90IGluIG1vZHBrZ3M6CiAgICAgICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQobW9kbmFtZSkKICAgICAgICAgICAgICAgIGVsaWYgaXNwYWNrYWdlKHBhdGgpOgogICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKGZpbGUgKyAnIChwYWNrYWdlKScpCiAgICAgICAgICAgIG1vZHBrZ3Muc29ydCgpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbigKICAgICAgICAgICAgICAgICdQQUNLQUdFIENPTlRFTlRTJywgam9pbihtb2Rwa2dzLCAnXG4nKSkKCiAgICAgICAgaWYgY2xhc3NlczoKICAgICAgICAgICAgY2xhc3NsaXN0ID0gbWFwKGxhbWJkYSAoa2V5LCB2YWx1ZSk6IHZhbHVlLCBjbGFzc2VzKQogICAgICAgICAgICBjb250ZW50cyA9IFtzZWxmLmZvcm1hdHRyZWUoCiAgICAgICAgICAgICAgICBpbnNwZWN0LmdldGNsYXNzdHJlZShjbGFzc2xpc3QsIDEpLCBuYW1lKV0KICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gY2xhc3NlczoKICAgICAgICAgICAgICAgIGNvbnRlbnRzLmFwcGVuZChzZWxmLmRvY3VtZW50KHZhbHVlLCBrZXksIG5hbWUpKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0NMQVNTRVMnLCBqb2luKGNvbnRlbnRzLCAnXG4nKSkKCiAgICAgICAgaWYgZnVuY3M6CiAgICAgICAgICAgIGNvbnRlbnRzID0gW10KICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gZnVuY3M6CiAgICAgICAgICAgICAgICBjb250ZW50cy5hcHBlbmQoc2VsZi5kb2N1bWVudCh2YWx1ZSwga2V5LCBuYW1lKSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdGVU5DVElPTlMnLCBqb2luKGNvbnRlbnRzLCAnXG4nKSkKCiAgICAgICAgaWYgZGF0YToKICAgICAgICAgICAgY29udGVudHMgPSBbXQogICAgICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBkYXRhOgogICAgICAgICAgICAgICAgY29udGVudHMuYXBwZW5kKHNlbGYuZG9jb3RoZXIodmFsdWUsIGtleSwgbmFtZSwgNzApKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0RBVEEnLCBqb2luKGNvbnRlbnRzLCAnXG4nKSkKCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX3ZlcnNpb25fXycpOgogICAgICAgICAgICB2ZXJzaW9uID0gc3RyKG9iamVjdC5fX3ZlcnNpb25fXykKICAgICAgICAgICAgaWYgdmVyc2lvbls6MTFdID09ICckJyArICdSZXZpc2lvbjogJyBhbmQgdmVyc2lvblstMTpdID09ICckJzoKICAgICAgICAgICAgICAgIHZlcnNpb24gPSBzdHJpcCh2ZXJzaW9uWzExOi0xXSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdWRVJTSU9OJywgdmVyc2lvbikKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fZGF0ZV9fJyk6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignREFURScsIHN0cihvYmplY3QuX19kYXRlX18pKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19hdXRob3JfXycpOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0FVVEhPUicsIHN0cihvYmplY3QuX19hdXRob3JfXykpCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2NyZWRpdHNfXycpOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0NSRURJVFMnLCBzdHIob2JqZWN0Ll9fY3JlZGl0c19fKSkKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIGRvY2NsYXNzKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCBtb2Q9Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSB0ZXh0IGRvY3VtZW50YXRpb24gZm9yIGEgZ2l2ZW4gY2xhc3Mgb2JqZWN0LiIiIgogICAgICAgIHJlYWxuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgbmFtZSA9IG5hbWUgb3IgcmVhbG5hbWUKICAgICAgICBiYXNlcyA9IG9iamVjdC5fX2Jhc2VzX18KCiAgICAgICAgaWYgbmFtZSA9PSByZWFsbmFtZToKICAgICAgICAgICAgdGl0bGUgPSAnY2xhc3MgJyArIHNlbGYuYm9sZChyZWFsbmFtZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICB0aXRsZSA9IHNlbGYuYm9sZChuYW1lKSArICcgPSBjbGFzcyAnICsgcmVhbG5hbWUKICAgICAgICBpZiBiYXNlczoKICAgICAgICAgICAgZGVmIG1ha2VuYW1lKGMsIG09b2JqZWN0Ll9fbW9kdWxlX18pOiByZXR1cm4gY2xhc3NuYW1lKGMsIG0pCiAgICAgICAgICAgIHBhcmVudHMgPSBtYXAobWFrZW5hbWUsIGJhc2VzKQogICAgICAgICAgICB0aXRsZSA9IHRpdGxlICsgJyglcyknICUgam9pbihwYXJlbnRzLCAnLCAnKQoKICAgICAgICBkb2MgPSBnZXRkb2Mob2JqZWN0KQogICAgICAgIGNvbnRlbnRzID0gZG9jIGFuZCBkb2MgKyAnXG4nCiAgICAgICAgbWV0aG9kcyA9IGFsbG1ldGhvZHMob2JqZWN0KS5pdGVtcygpCiAgICAgICAgbWV0aG9kcy5zb3J0KCkKICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBtZXRob2RzOgogICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgJ1xuJyArIHNlbGYuZG9jdW1lbnQodmFsdWUsIGtleSwgbW9kLCBvYmplY3QpCgogICAgICAgIGlmIG5vdCBjb250ZW50czogcmV0dXJuIHRpdGxlICsgJ1xuJwogICAgICAgIHJldHVybiB0aXRsZSArICdcbicgKyBzZWxmLmluZGVudChyc3RyaXAoY29udGVudHMpLCAnIHwgICcpICsgJ1xuJwoKICAgIGRlZiBmb3JtYXR2YWx1ZShzZWxmLCBvYmplY3QpOgogICAgICAgICIiIkZvcm1hdCBhbiBhcmd1bWVudCBkZWZhdWx0IHZhbHVlIGFzIHRleHQuIiIiCiAgICAgICAgcmV0dXJuICc9JyArIHNlbGYucmVwcihvYmplY3QpCgogICAgZGVmIGRvY3JvdXRpbmUoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lLCBjbD1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBmdW5jdGlvbiBvciBtZXRob2Qgb2JqZWN0LiIiIgogICAgICAgIHJlYWxuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgbmFtZSA9IG5hbWUgb3IgcmVhbG5hbWUKICAgICAgICBub3RlID0gJycKICAgICAgICBza2lwZG9jcyA9IDAKICAgICAgICBpZiBpbnNwZWN0LmlzbWV0aG9kKG9iamVjdCk6CiAgICAgICAgICAgIGltY2xhc3MgPSBvYmplY3QuaW1fY2xhc3MKICAgICAgICAgICAgaWYgY2w6CiAgICAgICAgICAgICAgICBpZiBpbWNsYXNzIGlzIG5vdCBjbDoKICAgICAgICAgICAgICAgICAgICBub3RlID0gJyBmcm9tICcgKyBjbGFzc25hbWUoaW1jbGFzcywgbW9kKQogICAgICAgICAgICAgICAgICAgIHNraXBkb2NzID0gMQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgb2JqZWN0LmltX3NlbGY6CiAgICAgICAgICAgICAgICAgICAgbm90ZSA9ICcgbWV0aG9kIG9mICVzIGluc3RhbmNlJyAlIGNsYXNzbmFtZSgKICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmltX3NlbGYuX19jbGFzc19fLCBtb2QpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIG5vdGUgPSAnIHVuYm91bmQgJXMgbWV0aG9kJyAlIGNsYXNzbmFtZShpbWNsYXNzLG1vZCkKICAgICAgICAgICAgb2JqZWN0ID0gb2JqZWN0LmltX2Z1bmMKCiAgICAgICAgaWYgbmFtZSA9PSByZWFsbmFtZToKICAgICAgICAgICAgdGl0bGUgPSBzZWxmLmJvbGQocmVhbG5hbWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgaWYgKGNsIGFuZCBjbC5fX2RpY3RfXy5oYXNfa2V5KHJlYWxuYW1lKSBhbmQKICAgICAgICAgICAgICAgIGNsLl9fZGljdF9fW3JlYWxuYW1lXSBpcyBvYmplY3QpOgogICAgICAgICAgICAgICAgc2tpcGRvY3MgPSAxCiAgICAgICAgICAgIHRpdGxlID0gc2VsZi5ib2xkKG5hbWUpICsgJyA9ICcgKyByZWFsbmFtZQogICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKG9iamVjdCkgb3IgaW5zcGVjdC5pc21ldGhvZGRlc2NyaXB0b3Iob2JqZWN0KToKICAgICAgICAgICAgYXJnc3BlYyA9ICcoLi4uKScKICAgICAgICBlbHNlOgogICAgICAgICAgICBhcmdzLCB2YXJhcmdzLCB2YXJrdywgZGVmYXVsdHMgPSBpbnNwZWN0LmdldGFyZ3NwZWMob2JqZWN0KQogICAgICAgICAgICBhcmdzcGVjID0gaW5zcGVjdC5mb3JtYXRhcmdzcGVjKAogICAgICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzLCBmb3JtYXR2YWx1ZT1zZWxmLmZvcm1hdHZhbHVlKQogICAgICAgICAgICBpZiByZWFsbmFtZSA9PSAnPGxhbWJkYT4nOgogICAgICAgICAgICAgICAgdGl0bGUgPSAnbGFtYmRhJwogICAgICAgICAgICAgICAgYXJnc3BlYyA9IGFyZ3NwZWNbMTotMV0gIyByZW1vdmUgcGFyZW50aGVzZXMKICAgICAgICBkZWNsID0gdGl0bGUgKyBhcmdzcGVjICsgbm90ZQoKICAgICAgICBpZiBza2lwZG9jczoKICAgICAgICAgICAgcmV0dXJuIGRlY2wgKyAnXG4nCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZG9jID0gZ2V0ZG9jKG9iamVjdCkgb3IgJycKICAgICAgICAgICAgcmV0dXJuIGRlY2wgKyAnXG4nICsgKGRvYyBhbmQgcnN0cmlwKHNlbGYuaW5kZW50KGRvYykpICsgJ1xuJykKCiAgICBkZWYgZG9jb3RoZXIoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lLCBtYXhsZW49Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSB0ZXh0IGRvY3VtZW50YXRpb24gZm9yIGEgZGF0YSBvYmplY3QuIiIiCiAgICAgICAgcmVwciA9IHNlbGYucmVwcihvYmplY3QpCiAgICAgICAgaWYgbWF4bGVuOgogICAgICAgICAgICBsaW5lID0gKG5hbWUgYW5kIG5hbWUgKyAnID0gJyBvciAnJykgKyByZXByCiAgICAgICAgICAgIGNob3AgPSBtYXhsZW4gLSBsZW4obGluZSkKICAgICAgICAgICAgaWYgY2hvcCA8IDA6IHJlcHIgPSByZXByWzpjaG9wXSArICcuLi4nCiAgICAgICAgbGluZSA9IChuYW1lIGFuZCBzZWxmLmJvbGQobmFtZSkgKyAnID0gJyBvciAnJykgKyByZXByCiAgICAgICAgcmV0dXJuIGxpbmUKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHVzZXIgaW50ZXJmYWNlcwoKZGVmIHBhZ2VyKHRleHQpOgogICAgIiIiVGhlIGZpcnN0IHRpbWUgdGhpcyBpcyBjYWxsZWQsIGRldGVybWluZSB3aGF0IGtpbmQgb2YgcGFnZXIgdG8gdXNlLiIiIgogICAgZ2xvYmFsIHBhZ2VyCiAgICBwYWdlciA9IGdldHBhZ2VyKCkKICAgIHBhZ2VyKHRleHQpCgpkZWYgZ2V0cGFnZXIoKToKICAgICIiIkRlY2lkZSB3aGF0IG1ldGhvZCB0byB1c2UgZm9yIHBhZ2luZyB0aHJvdWdoIHRleHQuIiIiCiAgICBpZiB0eXBlKHN5cy5zdGRvdXQpIGlzIG5vdCB0eXBlcy5GaWxlVHlwZToKICAgICAgICByZXR1cm4gcGxhaW5wYWdlcgogICAgaWYgbm90IHN5cy5zdGRpbi5pc2F0dHkoKSBvciBub3Qgc3lzLnN0ZG91dC5pc2F0dHkoKToKICAgICAgICByZXR1cm4gcGxhaW5wYWdlcgogICAgaWYgb3MuZW52aXJvbi5nZXQoJ1RFUk0nKSBpbiBbJ2R1bWInLCAnZW1hY3MnXToKICAgICAgICByZXR1cm4gcGxhaW5wYWdlcgogICAgaWYgb3MuZW52aXJvbi5oYXNfa2V5KCdQQUdFUicpOgogICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInOiAjIHBpcGVzIGNvbXBsZXRlbHkgYnJva2VuIGluIFdpbmRvd3MKICAgICAgICAgICAgcmV0dXJuIGxhbWJkYSB0ZXh0OiB0ZW1wZmlsZXBhZ2VyKHBsYWluKHRleHQpLCBvcy5lbnZpcm9uWydQQUdFUiddKQogICAgICAgIGVsaWYgb3MuZW52aXJvbi5nZXQoJ1RFUk0nKSBpbiBbJ2R1bWInLCAnZW1hY3MnXToKICAgICAgICAgICAgcmV0dXJuIGxhbWJkYSB0ZXh0OiBwaXBlcGFnZXIocGxhaW4odGV4dCksIG9zLmVudmlyb25bJ1BBR0VSJ10pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIGxhbWJkYSB0ZXh0OiBwaXBlcGFnZXIodGV4dCwgb3MuZW52aXJvblsnUEFHRVInXSkKICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInOgogICAgICAgIHJldHVybiBsYW1iZGEgdGV4dDogdGVtcGZpbGVwYWdlcihwbGFpbih0ZXh0KSwgJ21vcmUgPCcpCiAgICBpZiBoYXNhdHRyKG9zLCAnc3lzdGVtJykgYW5kIG9zLnN5c3RlbSgnbGVzcyAyPi9kZXYvbnVsbCcpID09IDA6CiAgICAgICAgcmV0dXJuIGxhbWJkYSB0ZXh0OiBwaXBlcGFnZXIodGV4dCwgJ2xlc3MnKQoKICAgIGltcG9ydCB0ZW1wZmlsZQogICAgZmlsZW5hbWUgPSB0ZW1wZmlsZS5ta3RlbXAoKQogICAgb3BlbihmaWxlbmFtZSwgJ3cnKS5jbG9zZSgpCiAgICB0cnk6CiAgICAgICAgaWYgaGFzYXR0cihvcywgJ3N5c3RlbScpIGFuZCBvcy5zeXN0ZW0oJ21vcmUgJXMnICUgZmlsZW5hbWUpID09IDA6CiAgICAgICAgICAgIHJldHVybiBsYW1iZGEgdGV4dDogcGlwZXBhZ2VyKHRleHQsICdtb3JlJykKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gdHR5cGFnZXIKICAgIGZpbmFsbHk6CiAgICAgICAgb3MudW5saW5rKGZpbGVuYW1lKQoKZGVmIHBsYWluKHRleHQpOgogICAgIiIiUmVtb3ZlIGJvbGRmYWNlIGZvcm1hdHRpbmcgZnJvbSB0ZXh0LiIiIgogICAgcmV0dXJuIHJlLnN1YignLlxiJywgJycsIHRleHQpCgpkZWYgcGlwZXBhZ2VyKHRleHQsIGNtZCk6CiAgICAiIiJQYWdlIHRocm91Z2ggdGV4dCBieSBmZWVkaW5nIGl0IHRvIGFub3RoZXIgcHJvZ3JhbS4iIiIKICAgIHBpcGUgPSBvcy5wb3BlbihjbWQsICd3JykKICAgIHRyeToKICAgICAgICBwaXBlLndyaXRlKHRleHQpCiAgICAgICAgcGlwZS5jbG9zZSgpCiAgICBleGNlcHQgSU9FcnJvcjoKICAgICAgICBwYXNzICMgSWdub3JlIGJyb2tlbiBwaXBlcyBjYXVzZWQgYnkgcXVpdHRpbmcgdGhlIHBhZ2VyIHByb2dyYW0uCgpkZWYgdGVtcGZpbGVwYWdlcih0ZXh0LCBjbWQpOgogICAgIiIiUGFnZSB0aHJvdWdoIHRleHQgYnkgaW52b2tpbmcgYSBwcm9ncmFtIG9uIGEgdGVtcG9yYXJ5IGZpbGUuIiIiCiAgICBpbXBvcnQgdGVtcGZpbGUKICAgIGZpbGVuYW1lID0gdGVtcGZpbGUubWt0ZW1wKCkKICAgIGZpbGUgPSBvcGVuKGZpbGVuYW1lLCAndycpCiAgICBmaWxlLndyaXRlKHRleHQpCiAgICBmaWxlLmNsb3NlKCkKICAgIHRyeToKICAgICAgICBvcy5zeXN0ZW0oY21kICsgJyAnICsgZmlsZW5hbWUpCiAgICBmaW5hbGx5OgogICAgICAgIG9zLnVubGluayhmaWxlbmFtZSkKCmRlZiB0dHlwYWdlcih0ZXh0KToKICAgICIiIlBhZ2UgdGhyb3VnaCB0ZXh0IG9uIGEgdGV4dCB0ZXJtaW5hbC4iIiIKICAgIGxpbmVzID0gc3BsaXQocGxhaW4odGV4dCksICdcbicpCiAgICB0cnk6CiAgICAgICAgaW1wb3J0IHR0eQogICAgICAgIGZkID0gc3lzLnN0ZGluLmZpbGVubygpCiAgICAgICAgb2xkID0gdHR5LnRjZ2V0YXR0cihmZCkKICAgICAgICB0dHkuc2V0Y2JyZWFrKGZkKQogICAgICAgIGdldGNoYXIgPSBsYW1iZGE6IHN5cy5zdGRpbi5yZWFkKDEpCiAgICBleGNlcHQgKEltcG9ydEVycm9yLCBBdHRyaWJ1dGVFcnJvcik6CiAgICAgICAgdHR5ID0gTm9uZQogICAgICAgIGdldGNoYXIgPSBsYW1iZGE6IHN5cy5zdGRpbi5yZWFkbGluZSgpWzotMV1bOjFdCgogICAgdHJ5OgogICAgICAgIHIgPSBpbmMgPSBvcy5lbnZpcm9uLmdldCgnTElORVMnLCAyNSkgLSAxCiAgICAgICAgc3lzLnN0ZG91dC53cml0ZShqb2luKGxpbmVzWzppbmNdLCAnXG4nKSArICdcbicpCiAgICAgICAgd2hpbGUgbGluZXNbcjpdOgogICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCctLSBtb3JlIC0tJykKICAgICAgICAgICAgc3lzLnN0ZG91dC5mbHVzaCgpCiAgICAgICAgICAgIGMgPSBnZXRjaGFyKCkKCiAgICAgICAgICAgIGlmIGMgaW4gWydxJywgJ1EnXToKICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoJ1xyICAgICAgICAgIFxyJykKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGVsaWYgYyBpbiBbJ1xyJywgJ1xuJ106CiAgICAgICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCdcciAgICAgICAgICBccicgKyBsaW5lc1tyXSArICdcbicpCiAgICAgICAgICAgICAgICByID0gciArIDEKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIGlmIGMgaW4gWydiJywgJ0InLCAnXHgxYiddOgogICAgICAgICAgICAgICAgciA9IHIgLSBpbmMgLSBpbmMKICAgICAgICAgICAgICAgIGlmIHIgPCAwOiByID0gMAogICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCdcbicgKyBqb2luKGxpbmVzW3I6citpbmNdLCAnXG4nKSArICdcbicpCiAgICAgICAgICAgIHIgPSByICsgaW5jCgogICAgZmluYWxseToKICAgICAgICBpZiB0dHk6CiAgICAgICAgICAgIHR0eS50Y3NldGF0dHIoZmQsIHR0eS5UQ1NBRkxVU0gsIG9sZCkKCmRlZiBwbGFpbnBhZ2VyKHRleHQpOgogICAgIiIiU2ltcGx5IHByaW50IHVuZm9ybWF0dGVkIHRleHQuICBUaGlzIGlzIHRoZSB1bHRpbWF0ZSBmYWxsYmFjay4iIiIKICAgIHN5cy5zdGRvdXQud3JpdGUocGxhaW4odGV4dCkpCgpkZWYgZGVzY3JpYmUodGhpbmcpOgogICAgIiIiUHJvZHVjZSBhIHNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSBnaXZlbiB0aGluZy4iIiIKICAgIGlmIGluc3BlY3QuaXNtb2R1bGUodGhpbmcpOgogICAgICAgIGlmIHRoaW5nLl9fbmFtZV9fIGluIHN5cy5idWlsdGluX21vZHVsZV9uYW1lczoKICAgICAgICAgICAgcmV0dXJuICdidWlsdC1pbiBtb2R1bGUgJyArIHRoaW5nLl9fbmFtZV9fCiAgICAgICAgaWYgaGFzYXR0cih0aGluZywgJ19fcGF0aF9fJyk6CiAgICAgICAgICAgIHJldHVybiAncGFja2FnZSAnICsgdGhpbmcuX19uYW1lX18KICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gJ21vZHVsZSAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIGluc3BlY3QuaXNidWlsdGluKHRoaW5nKToKICAgICAgICByZXR1cm4gJ2J1aWx0LWluIGZ1bmN0aW9uICcgKyB0aGluZy5fX25hbWVfXwogICAgaWYgaW5zcGVjdC5pc2NsYXNzKHRoaW5nKToKICAgICAgICByZXR1cm4gJ2NsYXNzICcgKyB0aGluZy5fX25hbWVfXwogICAgaWYgaW5zcGVjdC5pc2Z1bmN0aW9uKHRoaW5nKToKICAgICAgICByZXR1cm4gJ2Z1bmN0aW9uICcgKyB0aGluZy5fX25hbWVfXwogICAgaWYgaW5zcGVjdC5pc21ldGhvZCh0aGluZyk6CiAgICAgICAgcmV0dXJuICdtZXRob2QgJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiB0eXBlKHRoaW5nKSBpcyB0eXBlcy5JbnN0YW5jZVR5cGU6CiAgICAgICAgcmV0dXJuICdpbnN0YW5jZSBvZiAnICsgdGhpbmcuX19jbGFzc19fLl9fbmFtZV9fCiAgICByZXR1cm4gdHlwZSh0aGluZykuX19uYW1lX18KCmRlZiBsb2NhdGUocGF0aCwgZm9yY2Vsb2FkPTApOgogICAgIiIiTG9jYXRlIGFuIG9iamVjdCBieSBuYW1lIG9yIGRvdHRlZCBwYXRoLCBpbXBvcnRpbmcgYXMgbmVjZXNzYXJ5LiIiIgogICAgcGFydHMgPSBzcGxpdChwYXRoLCAnLicpCiAgICBtb2R1bGUsIG4gPSBOb25lLCAwCiAgICB3aGlsZSBuIDwgbGVuKHBhcnRzKToKICAgICAgICBuZXh0bW9kdWxlID0gc2FmZWltcG9ydChqb2luKHBhcnRzWzpuKzFdLCAnLicpLCBmb3JjZWxvYWQpCiAgICAgICAgaWYgbmV4dG1vZHVsZTogbW9kdWxlLCBuID0gbmV4dG1vZHVsZSwgbiArIDEKICAgICAgICBlbHNlOiBicmVhawogICAgaWYgbW9kdWxlOgogICAgICAgIG9iamVjdCA9IG1vZHVsZQogICAgICAgIGZvciBwYXJ0IGluIHBhcnRzW246XToKICAgICAgICAgICAgdHJ5OiBvYmplY3QgPSBnZXRhdHRyKG9iamVjdCwgcGFydCkKICAgICAgICAgICAgZXhjZXB0IEF0dHJpYnV0ZUVycm9yOiByZXR1cm4gTm9uZQogICAgICAgIHJldHVybiBvYmplY3QKICAgIGVsc2U6CiAgICAgICAgaW1wb3J0IF9fYnVpbHRpbl9fCiAgICAgICAgaWYgaGFzYXR0cihfX2J1aWx0aW5fXywgcGF0aCk6CiAgICAgICAgICAgIHJldHVybiBnZXRhdHRyKF9fYnVpbHRpbl9fLCBwYXRoKQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gaW50ZXJhY3RpdmUgaW50ZXJwcmV0ZXIgaW50ZXJmYWNlCgp0ZXh0ID0gVGV4dERvYygpCmh0bWwgPSBIVE1MRG9jKCkKCmRlZiBkb2ModGhpbmcsIHRpdGxlPSdQeXRob24gTGlicmFyeSBEb2N1bWVudGF0aW9uOiAlcycsIGZvcmNlbG9hZD0wKToKICAgICIiIkRpc3BsYXkgdGV4dCBkb2N1bWVudGF0aW9uLCBnaXZlbiBhbiBvYmplY3Qgb3IgYSBwYXRoIHRvIGFuIG9iamVjdC4iIiIKICAgIHN1ZmZpeCwgbmFtZSA9ICcnLCBOb25lCiAgICBpZiB0eXBlKHRoaW5nKSBpcyB0eXBlKCcnKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIG9iamVjdCA9IGxvY2F0ZSh0aGluZywgZm9yY2Vsb2FkKQogICAgICAgIGV4Y2VwdCBFcnJvckR1cmluZ0ltcG9ydCwgdmFsdWU6CiAgICAgICAgICAgIHByaW50IHZhbHVlCiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIG5vdCBvYmplY3Q6CiAgICAgICAgICAgIHByaW50ICdubyBQeXRob24gZG9jdW1lbnRhdGlvbiBmb3VuZCBmb3IgJXMnICUgcmVwcih0aGluZykKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgcGFydHMgPSBzcGxpdCh0aGluZywgJy4nKQogICAgICAgIGlmIGxlbihwYXJ0cykgPiAxOiBzdWZmaXggPSAnIGluICcgKyBqb2luKHBhcnRzWzotMV0sICcuJykKICAgICAgICBuYW1lID0gcGFydHNbLTFdCiAgICAgICAgdGhpbmcgPSBvYmplY3QKCiAgICBkZXNjID0gZGVzY3JpYmUodGhpbmcpCiAgICBtb2R1bGUgPSBpbnNwZWN0LmdldG1vZHVsZSh0aGluZykKICAgIGlmIG5vdCBzdWZmaXggYW5kIG1vZHVsZSBhbmQgbW9kdWxlIGlzIG5vdCB0aGluZzoKICAgICAgICBzdWZmaXggPSAnIGluIG1vZHVsZSAnICsgbW9kdWxlLl9fbmFtZV9fCiAgICBwYWdlcih0aXRsZSAlIChkZXNjICsgc3VmZml4KSArICdcblxuJyArIHRleHQuZG9jdW1lbnQodGhpbmcsIG5hbWUpKQoKZGVmIHdyaXRlZG9jKGtleSwgZm9yY2Vsb2FkPTApOgogICAgIiIiV3JpdGUgSFRNTCBkb2N1bWVudGF0aW9uIHRvIGEgZmlsZSBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuIiIiCiAgICB0cnk6CiAgICAgICAgb2JqZWN0ID0gbG9jYXRlKGtleSwgZm9yY2Vsb2FkKQogICAgZXhjZXB0IEVycm9yRHVyaW5nSW1wb3J0LCB2YWx1ZToKICAgICAgICBwcmludCB2YWx1ZQogICAgZWxzZToKICAgICAgICBpZiBvYmplY3Q6CiAgICAgICAgICAgIHBhZ2UgPSBodG1sLnBhZ2UoZGVzY3JpYmUob2JqZWN0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBodG1sLmRvY3VtZW50KG9iamVjdCwgb2JqZWN0Ll9fbmFtZV9fKSkKICAgICAgICAgICAgZmlsZSA9IG9wZW4oa2V5ICsgJy5odG1sJywgJ3cnKQogICAgICAgICAgICBmaWxlLndyaXRlKHBhZ2UpCiAgICAgICAgICAgIGZpbGUuY2xvc2UoKQogICAgICAgICAgICBwcmludCAnd3JvdGUnLCBrZXkgKyAnLmh0bWwnCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcHJpbnQgJ25vIFB5dGhvbiBkb2N1bWVudGF0aW9uIGZvdW5kIGZvciAlcycgJSByZXByKGtleSkKCmRlZiB3cml0ZWRvY3MoZGlyLCBwa2dwYXRoPScnLCBkb25lPU5vbmUpOgogICAgIiIiV3JpdGUgb3V0IEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYWxsIG1vZHVsZXMgaW4gYSBkaXJlY3RvcnkgdHJlZS4iIiIKICAgIGlmIGRvbmUgaXMgTm9uZTogZG9uZSA9IHt9CiAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKGRpcik6CiAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihkaXIsIGZpbGUpCiAgICAgICAgaWYgaXNwYWNrYWdlKHBhdGgpOgogICAgICAgICAgICB3cml0ZWRvY3MocGF0aCwgcGtncGF0aCArIGZpbGUgKyAnLicsIGRvbmUpCiAgICAgICAgZWxpZiBvcy5wYXRoLmlzZmlsZShwYXRoKToKICAgICAgICAgICAgbW9kbmFtZSA9IGluc3BlY3QuZ2V0bW9kdWxlbmFtZShwYXRoKQogICAgICAgICAgICBpZiBtb2RuYW1lOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IHBrZ3BhdGggKyBtb2RuYW1lCiAgICAgICAgICAgICAgICBpZiBub3QgZG9uZS5oYXNfa2V5KG1vZG5hbWUpOgogICAgICAgICAgICAgICAgICAgIGRvbmVbbW9kbmFtZV0gPSAxCiAgICAgICAgICAgICAgICAgICAgd3JpdGVkb2MobW9kbmFtZSkKCmNsYXNzIEhlbHBlcjoKICAgIGtleXdvcmRzID0gewogICAgICAgICdhbmQnOiAnQk9PTEVBTicsCiAgICAgICAgJ2Fzc2VydCc6ICgncmVmL2Fzc2VydCcsICcnKSwKICAgICAgICAnYnJlYWsnOiAoJ3JlZi9icmVhaycsICd3aGlsZSBmb3InKSwKICAgICAgICAnY2xhc3MnOiAoJ3JlZi9jbGFzcycsICdDTEFTU0VTIFNQRUNJQUxNRVRIT0RTJyksCiAgICAgICAgJ2NvbnRpbnVlJzogKCdyZWYvY29udGludWUnLCAnd2hpbGUgZm9yJyksCiAgICAgICAgJ2RlZic6ICgncmVmL2Z1bmN0aW9uJywgJycpLAogICAgICAgICdkZWwnOiAoJ3JlZi9kZWwnLCAnQkFTSUNNRVRIT0RTJyksCiAgICAgICAgJ2VsaWYnOiAnaWYnLAogICAgICAgICdlbHNlJzogKCdyZWYvaWYnLCAnd2hpbGUgZm9yJyksCiAgICAgICAgJ2V4Y2VwdCc6ICd0cnknLAogICAgICAgICdleGVjJzogKCdyZWYvZXhlYycsICcnKSwKICAgICAgICAnZmluYWxseSc6ICd0cnknLAogICAgICAgICdmb3InOiAoJ3JlZi9mb3InLCAnYnJlYWsgY29udGludWUgd2hpbGUnKSwKICAgICAgICAnZnJvbSc6ICdpbXBvcnQnLAogICAgICAgICdnbG9iYWwnOiAoJ3JlZi9nbG9iYWwnLCAnTkFNRVNQQUNFUycpLAogICAgICAgICdpZic6ICgncmVmL2lmJywgJ1RSVVRIVkFMVUUnKSwKICAgICAgICAnaW1wb3J0JzogKCdyZWYvaW1wb3J0JywgJ01PRFVMRVMnKSwKICAgICAgICAnaW4nOiAoJ3JlZi9jb21wYXJpc29ucycsICdTRVFVRU5DRU1FVEhPRFMyJyksCiAgICAgICAgJ2lzJzogJ0NPTVBBUklTT04nLAogICAgICAgICdsYW1iZGEnOiAoJ3JlZi9sYW1iZGEnLCAnRlVOQ1RJT05TJyksCiAgICAgICAgJ25vdCc6ICdCT09MRUFOJywKICAgICAgICAnb3InOiAnQk9PTEVBTicsCiAgICAgICAgJ3Bhc3MnOiAnUEFTUycsCiAgICAgICAgJ3ByaW50JzogKCdyZWYvcHJpbnQnLCAnJyksCiAgICAgICAgJ3JhaXNlJzogKCdyZWYvcmFpc2UnLCAnRVhDRVBUSU9OUycpLAogICAgICAgICdyZXR1cm4nOiAoJ3JlZi9yZXR1cm4nLCAnRlVOQ1RJT05TJyksCiAgICAgICAgJ3RyeSc6ICgncmVmL3RyeScsICdFWENFUFRJT05TJyksCiAgICAgICAgJ3doaWxlJzogKCdyZWYvd2hpbGUnLCAnYnJlYWsgY29udGludWUgaWYgVFJVVEhWQUxVRScpLAogICAgfQoKICAgIHRvcGljcyA9IHsKICAgICAgICAnVFlQRVMnOiAoJ3JlZi90eXBlcycsICdTVFJJTkdTIFVOSUNPREUgTlVNQkVSUyBTRVFVRU5DRVMgTUFQUElOR1MgRlVOQ1RJT05TIENMQVNTRVMgTU9EVUxFUyBGSUxFUyBpbnNwZWN0JyksCiAgICAgICAgJ1NUUklOR1MnOiAoJ3JlZi9zdHJpbmdzJywgJ3N0ciBVTklDT0RFIFNFUVVFTkNFUyBTVFJJTkdNRVRIT0RTIEZPUk1BVFRJTkcgVFlQRVMnKSwKICAgICAgICAnU1RSSU5HTUVUSE9EUyc6ICgnbGliL3N0cmluZy1tZXRob2RzJywgJ1NUUklOR1MgRk9STUFUVElORycpLAogICAgICAgICdGT1JNQVRUSU5HJzogKCdsaWIvdHlwZXNzZXEtc3RyaW5ncycsICdPUEVSQVRPUlMnKSwKICAgICAgICAnVU5JQ09ERSc6ICgncmVmL3VuaWNvZGUnLCAnZW5jb2RpbmdzIHVuaWNvZGUgVFlQRVMgU1RSSU5HJyksCiAgICAgICAgJ05VTUJFUlMnOiAoJ3JlZi9udW1iZXJzJywgJ0lOVEVHRVIgRkxPQVQgQ09NUExFWCBUWVBFUycpLAogICAgICAgICdJTlRFR0VSJzogKCdyZWYvaW50ZWdlcnMnLCAnaW50IHJhbmdlJyksCiAgICAgICAgJ0ZMT0FUJzogKCdyZWYvZmxvYXRpbmcnLCAnZmxvYXQgbWF0aCcpLAogICAgICAgICdDT01QTEVYJzogKCdyZWYvaW1hZ2luYXJ5JywgJ2NvbXBsZXggY21hdGgnKSwKICAgICAgICAnU0VRVUVOQ0VTJzogKCdsaWIvdHlwZXNzZXEnLCAnU1RSSU5HTUVUSE9EUyBGT1JNQVRUSU5HIHhyYW5nZSBMSVNUUycpLAogICAgICAgICdNQVBQSU5HUyc6ICdESUNUSU9OQVJJRVMnLAogICAgICAgICdGVU5DVElPTlMnOiAoJ2xpYi90eXBlc2Z1bmN0aW9ucycsICdkZWYgVFlQRVMnKSwKICAgICAgICAnTUVUSE9EUyc6ICgnbGliL3R5cGVzbWV0aG9kcycsICdjbGFzcyBkZWYgQ0xBU1NFUyBUWVBFUycpLAogICAgICAgICdDT0RFT0JKRUNUUyc6ICgnbGliL2JsdGluLWNvZGUtb2JqZWN0cycsICdjb21waWxlIEZVTkNUSU9OUyBUWVBFUycpLAogICAgICAgICdUWVBFT0JKRUNUUyc6ICgnbGliL2JsdGluLXR5cGUtb2JqZWN0cycsICd0eXBlcyBUWVBFUycpLAogICAgICAgICdGUkFNRU9CSkVDVFMnOiAnVFlQRVMnLAogICAgICAgICdUUkFDRUJBQ0tTJzogJ1RZUEVTJywKICAgICAgICAnTk9ORSc6ICgnbGliL2JsdGluLW51bGwtb2JqZWN0JywgJycpLAogICAgICAgICdFTExJUFNJUyc6ICgnbGliL2JsdGluLWVsbGlwc2lzLW9iamVjdCcsICdTTElDSU5HUycpLAogICAgICAgICdGSUxFUyc6ICgnbGliL2JsdGluLWZpbGUtb2JqZWN0cycsICcnKSwKICAgICAgICAnU1BFQ0lBTEFUVFJJQlVURVMnOiAoJ2xpYi9zcGVjaWFsYXR0cnMnLCAnJyksCiAgICAgICAgJ0NMQVNTRVMnOiAoJ3JlZi90eXBlcycsICdjbGFzcyBTUEVDSUFMTUVUSE9EUyBQUklWQVRFTkFNRVMnKSwKICAgICAgICAnTU9EVUxFUyc6ICgnbGliL3R5cGVzbW9kdWxlcycsICdpbXBvcnQnKSwKICAgICAgICAnUEFDS0FHRVMnOiAnaW1wb3J0JywKICAgICAgICAnRVhQUkVTU0lPTlMnOiAoJ3JlZi9zdW1tYXJ5JywgJ2xhbWJkYSBvciBhbmQgbm90IGluIGlzIEJPT0xFQU4gQ09NUEFSSVNPTiBCSVRXSVNFIFNISUZUSU5HIEJJTkFSWSBGT1JNQVRUSU5HIFBPV0VSIFVOQVJZIEFUVFJJQlVURVMgU1VCU0NSSVBUUyBTTElDSU5HUyBDQUxMUyBUVVBMRVMgTElTVFMgRElDVElPTkFSSUVTIEJBQ0tRVU9URVMnKSwKICAgICAgICAnT1BFUkFUT1JTJzogJ0VYUFJFU1NJT05TJywKICAgICAgICAnUFJFQ0VERU5DRSc6ICdFWFBSRVNTSU9OUycsCiAgICAgICAgJ09CSkVDVFMnOiAoJ3JlZi9vYmplY3RzJywgJ1RZUEVTJyksCiAgICAgICAgJ1NQRUNJQUxNRVRIT0RTJzogKCdyZWYvc3BlY2lhbG5hbWVzJywgJ0JBU0lDTUVUSE9EUyBBVFRSSUJVVEVNRVRIT0RTIENBTExBQkxFTUVUSE9EUyBTRVFVRU5DRU1FVEhPRFMxIE1BUFBJTkdNRVRIT0RTIFNFUVVFTkNFTUVUSE9EUzIgTlVNQkVSTUVUSE9EUyBDTEFTU0VTJyksCiAgICAgICAgJ0JBU0lDTUVUSE9EUyc6ICgncmVmL2N1c3RvbWl6YXRpb24nLCAnY21wIGhhc2ggcmVwciBzdHIgU1BFQ0lBTE1FVEhPRFMnKSwKICAgICAgICAnQVRUUklCVVRFTUVUSE9EUyc6ICgncmVmL2F0dHJpYnV0ZS1hY2Nlc3MnLCAnQVRUUklCVVRFUyBTUEVDSUFMTUVUSE9EUycpLAogICAgICAgICdDQUxMQUJMRU1FVEhPRFMnOiAoJ3JlZi9jYWxsYWJsZS10eXBlcycsICdDQUxMUyBTUEVDSUFMTUVUSE9EUycpLAogICAgICAgICdTRVFVRU5DRU1FVEhPRFMxJzogKCdyZWYvc2VxdWVuY2UtdHlwZXMnLCAnU0VRVUVOQ0VTIFNFUVVFTkNFTUVUSE9EUzIgU1BFQ0lBTE1FVEhPRFMnKSwKICAgICAgICAnU0VRVUVOQ0VNRVRIT0RTMic6ICgncmVmL3NlcXVlbmNlLW1ldGhvZHMnLCAnU0VRVUVOQ0VTIFNFUVVFTkNFTUVUSE9EUzEgU1BFQ0lBTE1FVEhPRFMnKSwKICAgICAgICAnTUFQUElOR01FVEhPRFMnOiAoJ3JlZi9zZXF1ZW5jZS10eXBlcycsICdNQVBQSU5HUyBTUEVDSUFMTUVUSE9EUycpLAogICAgICAgICdOVU1CRVJNRVRIT0RTJzogKCdyZWYvbnVtZXJpYy10eXBlcycsICdOVU1CRVJTIEFVR01FTlRFREFTU0lHTk1FTlQgU1BFQ0lBTE1FVEhPRFMnKSwKICAgICAgICAnRVhFQ1VUSU9OJzogKCdyZWYvZXhlY2ZyYW1lcycsICcnKSwKICAgICAgICAnTkFNRVNQQUNFUyc6ICgncmVmL2V4ZWNmcmFtZXMnLCAnZ2xvYmFsIEFTU0lHTk1FTlQgREVMRVRJT04nKSwKICAgICAgICAnU0NPUElORyc6ICdOQU1FU1BBQ0VTJywKICAgICAgICAnRlJBTUVTJzogJ05BTUVTUEFDRVMnLAogICAgICAgICdFWENFUFRJT05TJzogKCdyZWYvZXhjZXB0aW9ucycsICd0cnkgZXhjZXB0IGZpbmFsbHkgcmFpc2UnKSwKICAgICAgICAnQ09FUkNJT05TJzogJ0NPTlZFUlNJT05TJywKICAgICAgICAnQ09OVkVSU0lPTlMnOiAoJ3JlZi9jb252ZXJzaW9ucycsICcnKSwKICAgICAgICAnSURFTlRJRklFUlMnOiAoJ3JlZi9pZGVudGlmaWVycycsICdrZXl3b3JkcyBTUEVDSUFMSURFTlRJRklFUlMnKSwKICAgICAgICAnU1BFQ0lBTElERU5USUZJRVJTJzogKCdyZWYvaWQtY2xhc3NlcycsICcnKSwKICAgICAgICAnUFJJVkFURU5BTUVTJzogKCdyZWYvYXRvbS1pZGVudGlmaWVycycsICcnKSwKICAgICAgICAnTElURVJBTFMnOiAoJ3JlZi9hdG9tLWxpdGVyYWxzJywgJ1NUUklOR1MgQkFDS1FVT1RFUyBOVU1CRVJTIFRVUExFTElURVJBTFMgTElTVExJVEVSQUxTIERJQ1RJT05BUllMSVRFUkFMUycpLAogICAgICAgICdUVVBMRVMnOiAnU0VRVUVOQ0VTJywKICAgICAgICAnVFVQTEVMSVRFUkFMUyc6ICgncmVmL2V4cHJsaXN0cycsICdUVVBMRVMgTElURVJBTFMnKSwKICAgICAgICAnTElTVFMnOiAoJ2xpYi90eXBlc3NlcS1tdXRhYmxlJywgJ0xJU1RMSVRFUkFMUycpLAogICAgICAgICdMSVNUTElURVJBTFMnOiAoJ3JlZi9saXN0cycsICdMSVNUUyBMSVRFUkFMUycpLAogICAgICAgICdESUNUSU9OQVJJRVMnOiAoJ2xpYi90eXBlc21hcHBpbmcnLCAnRElDVElPTkFSWUxJVEVSQUxTJyksCiAgICAgICAgJ0RJQ1RJT05BUllMSVRFUkFMUyc6ICgncmVmL2RpY3QnLCAnRElDVElPTkFSSUVTIExJVEVSQUxTJyksCiAgICAgICAgJ0JBQ0tRVU9URVMnOiAoJ3JlZi9zdHJpbmctY29udmVyc2lvbnMnLCAncmVwciBzdHIgU1RSSU5HUyBMSVRFUkFMUycpLAogICAgICAgICdBVFRSSUJVVEVTJzogKCdyZWYvYXR0cmlidXRlLXJlZmVyZW5jZXMnLCAnZ2V0YXR0ciBoYXNhdHRyIHNldGF0dHIgQVRUUklCVVRFTUVUSE9EUycpLAogICAgICAgICdTVUJTQ1JJUFRTJzogKCdyZWYvc3Vic2NyaXB0aW9ucycsICdTRVFVRU5DRU1FVEhPRFMxJyksCiAgICAgICAgJ1NMSUNJTkdTJzogKCdyZWYvc2xpY2luZ3MnLCAnU0VRVUVOQ0VNRVRIT0RTMicpLAogICAgICAgICdDQUxMUyc6ICgncmVmL2NhbGxzJywgJ0VYUFJFU1NJT05TJyksCiAgICAgICAgJ1BPV0VSJzogKCdyZWYvcG93ZXInLCAnRVhQUkVTU0lPTlMnKSwKICAgICAgICAnVU5BUlknOiAoJ3JlZi91bmFyeScsICdFWFBSRVNTSU9OUycpLAogICAgICAgICdCSU5BUlknOiAoJ3JlZi9iaW5hcnknLCAnRVhQUkVTU0lPTlMnKSwKICAgICAgICAnU0hJRlRJTkcnOiAoJ3JlZi9zaGlmdGluZycsICdFWFBSRVNTSU9OUycpLAogICAgICAgICdCSVRXSVNFJzogKCdyZWYvYml0d2lzZScsICdFWFBSRVNTSU9OUycpLAogICAgICAgICdDT01QQVJJU09OJzogKCdyZWYvY29tcGFyaXNvbnMnLCAnRVhQUkVTU0lPTlMgQkFTSUNNRVRIT0RTJyksCiAgICAgICAgJ0JPT0xFQU4nOiAoJ3JlZi9sYW1iZGEnLCAnRVhQUkVTU0lPTlMgVFJVVEhWQUxVRScpLAogICAgICAgICdBU1NFUlRJT04nOiAnYXNzZXJ0JywKICAgICAgICAnQVNTSUdOTUVOVCc6ICgncmVmL2Fzc2lnbm1lbnQnLCAnQVVHTUVOVEVEQVNTSUdOTUVOVCcpLAogICAgICAgICdBVUdNRU5URURBU1NJR05NRU5UJzogKCdyZWYvYXVnYXNzaWduJywgJ05VTUJFUk1FVEhPRFMnKSwKICAgICAgICAnREVMRVRJT04nOiAnZGVsJywKICAgICAgICAnUFJJTlRJTkcnOiAncHJpbnQnLAogICAgICAgICdSRVRVUk5JTkcnOiAncmV0dXJuJywKICAgICAgICAnSU1QT1JUSU5HJzogJ2ltcG9ydCcsCiAgICAgICAgJ0NPTkRJVElPTkFMJzogJ2lmJywKICAgICAgICAnTE9PUElORyc6ICgncmVmL2NvbXBvdW5kJywgJ2ZvciB3aGlsZSBicmVhayBjb250aW51ZScpLAogICAgICAgICdUUlVUSFZBTFVFJzogKCdsaWIvdHJ1dGgnLCAnaWYgd2hpbGUgYW5kIG9yIG5vdCBCQVNJQ01FVEhPRFMnKSwKICAgICAgICAnREVCVUdHSU5HJzogKCdsaWIvbW9kdWxlLXBkYicsICdwZGInKSwKICAgIH0KCiAgICBkZWYgX19pbml0X18oc2VsZiwgaW5wdXQsIG91dHB1dCk6CiAgICAgICAgc2VsZi5pbnB1dCA9IGlucHV0CiAgICAgICAgc2VsZi5vdXRwdXQgPSBvdXRwdXQKICAgICAgICBzZWxmLmRvY2RpciA9IE5vbmUKICAgICAgICBleGVjZGlyID0gb3MucGF0aC5kaXJuYW1lKHN5cy5leGVjdXRhYmxlKQogICAgICAgIGhvbWVkaXIgPSBvcy5lbnZpcm9uLmdldCgnUFlUSE9OSE9NRScpCiAgICAgICAgZm9yIGRpciBpbiBbb3MuZW52aXJvbi5nZXQoJ1BZVEhPTkRPQ1MnKSwKICAgICAgICAgICAgICAgICAgICBob21lZGlyIGFuZCBvcy5wYXRoLmpvaW4oaG9tZWRpciwgJ2RvYycpLAogICAgICAgICAgICAgICAgICAgIG9zLnBhdGguam9pbihleGVjZGlyLCAnZG9jJyksCiAgICAgICAgICAgICAgICAgICAgJy91c3IvZG9jL3B5dGhvbi1kb2NzLScgKyBzcGxpdChzeXMudmVyc2lvbilbMF0sCiAgICAgICAgICAgICAgICAgICAgJy91c3IvZG9jL3B5dGhvbi0nICsgc3BsaXQoc3lzLnZlcnNpb24pWzBdLAogICAgICAgICAgICAgICAgICAgICcvdXNyL2RvYy9weXRob24tZG9jcy0nICsgc3lzLnZlcnNpb25bOjNdLAogICAgICAgICAgICAgICAgICAgICcvdXNyL2RvYy9weXRob24tJyArIHN5cy52ZXJzaW9uWzozXV06CiAgICAgICAgICAgIGlmIGRpciBhbmQgb3MucGF0aC5pc2Rpcihvcy5wYXRoLmpvaW4oZGlyLCAnbGliJykpOgogICAgICAgICAgICAgICAgc2VsZi5kb2NkaXIgPSBkaXIKCiAgICBkZWYgX19yZXByX18oc2VsZik6CiAgICAgICAgaWYgaW5zcGVjdC5zdGFjaygpWzFdWzNdID09ICc/JzoKICAgICAgICAgICAgc2VsZigpCiAgICAgICAgICAgIHJldHVybiAnJwogICAgICAgIHJldHVybiAnPHB5ZG9jLkhlbHBlciBpbnN0YW5jZT4nCgogICAgZGVmIF9fY2FsbF9fKHNlbGYsIHJlcXVlc3Q9Tm9uZSk6CiAgICAgICAgaWYgcmVxdWVzdCBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi5oZWxwKHJlcXVlc3QpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5pbnRybygpCiAgICAgICAgICAgIHNlbGYuaW50ZXJhY3QoKQogICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnJycKWW91IGFyZSBub3cgbGVhdmluZyBoZWxwIGFuZCByZXR1cm5pbmcgdG8gdGhlIFB5dGhvbiBpbnRlcnByZXRlci4KSWYgeW91IHdhbnQgdG8gYXNrIGZvciBoZWxwIG9uIGEgcGFydGljdWxhciBvYmplY3QgZGlyZWN0bHkgZnJvbSB0aGUKaW50ZXJwcmV0ZXIsIHlvdSBjYW4gdHlwZSAiaGVscChvYmplY3QpIi4gIEV4ZWN1dGluZyAiaGVscCgnc3RyaW5nJykiCmhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgdHlwaW5nIGEgcGFydGljdWxhciBzdHJpbmcgYXQgdGhlIGhlbHA+IHByb21wdC4KJycnKQoKICAgIGRlZiBpbnRlcmFjdChzZWxmKToKICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnXG4nKQogICAgICAgIHdoaWxlIDE6CiAgICAgICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCdoZWxwPiAnKQogICAgICAgICAgICBzZWxmLm91dHB1dC5mbHVzaCgpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHJlcXVlc3QgPSBzZWxmLmlucHV0LnJlYWRsaW5lKCkKICAgICAgICAgICAgICAgIGlmIG5vdCByZXF1ZXN0OiBicmVhawogICAgICAgICAgICBleGNlcHQgS2V5Ym9hcmRJbnRlcnJ1cHQ6IGJyZWFrCiAgICAgICAgICAgIHJlcXVlc3QgPSBzdHJpcChyZXBsYWNlKHJlcXVlc3QsICciJywgJycsICInIiwgJycpKQogICAgICAgICAgICBpZiBsb3dlcihyZXF1ZXN0KSBpbiBbJ3EnLCAncXVpdCddOiBicmVhawogICAgICAgICAgICBzZWxmLmhlbHAocmVxdWVzdCkKCiAgICBkZWYgaGVscChzZWxmLCByZXF1ZXN0KToKICAgICAgICBpZiB0eXBlKHJlcXVlc3QpIGlzIHR5cGUoJycpOgogICAgICAgICAgICBpZiByZXF1ZXN0ID09ICdoZWxwJzogc2VsZi5pbnRybygpCiAgICAgICAgICAgIGVsaWYgcmVxdWVzdCA9PSAna2V5d29yZHMnOiBzZWxmLmxpc3RrZXl3b3JkcygpCiAgICAgICAgICAgIGVsaWYgcmVxdWVzdCA9PSAndG9waWNzJzogc2VsZi5saXN0dG9waWNzKCkKICAgICAgICAgICAgZWxpZiByZXF1ZXN0ID09ICdtb2R1bGVzJzogc2VsZi5saXN0bW9kdWxlcygpCiAgICAgICAgICAgIGVsaWYgcmVxdWVzdFs6OF0gPT0gJ21vZHVsZXMgJzoKICAgICAgICAgICAgICAgIHNlbGYubGlzdG1vZHVsZXMoc3BsaXQocmVxdWVzdClbMV0pCiAgICAgICAgICAgIGVsaWYgc2VsZi5rZXl3b3Jkcy5oYXNfa2V5KHJlcXVlc3QpOiBzZWxmLnNob3d0b3BpYyhyZXF1ZXN0KQogICAgICAgICAgICBlbGlmIHNlbGYudG9waWNzLmhhc19rZXkocmVxdWVzdCk6IHNlbGYuc2hvd3RvcGljKHJlcXVlc3QpCiAgICAgICAgICAgIGVsaWYgcmVxdWVzdDogZG9jKHJlcXVlc3QsICdIZWxwIG9uICVzOicpCiAgICAgICAgZWxpZiBpc2luc3RhbmNlKHJlcXVlc3QsIEhlbHBlcik6IHNlbGYoKQogICAgICAgIGVsc2U6IGRvYyhyZXF1ZXN0LCAnSGVscCBvbiAlczonKQogICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCdcbicpCgogICAgZGVmIGludHJvKHNlbGYpOgogICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCcnJwpXZWxjb21lIHRvIFB5dGhvbiAlcyEgIFRoaXMgaXMgdGhlIG9ubGluZSBoZWxwIHV0aWxpdHkuCgpJZiB0aGlzIGlzIHlvdXIgZmlyc3QgdGltZSB1c2luZyBQeXRob24sIHlvdSBzaG91bGQgZGVmaW5pdGVseSBjaGVjayBvdXQKdGhlIHR1dG9yaWFsIG9uIHRoZSBJbnRlcm5ldCBhdCBodHRwOi8vd3d3LnB5dGhvbi5vcmcvZG9jL3R1dC8uCgpFbnRlciB0aGUgbmFtZSBvZiBhbnkgbW9kdWxlLCBrZXl3b3JkLCBvciB0b3BpYyB0byBnZXQgaGVscCBvbiB3cml0aW5nClB5dGhvbiBwcm9ncmFtcyBhbmQgdXNpbmcgUHl0aG9uIG1vZHVsZXMuICBUbyBxdWl0IHRoaXMgaGVscCB1dGlsaXR5IGFuZApyZXR1cm4gdG8gdGhlIGludGVycHJldGVyLCBqdXN0IHR5cGUgInF1aXQiLgoKVG8gZ2V0IGEgbGlzdCBvZiBhdmFpbGFibGUgbW9kdWxlcywga2V5d29yZHMsIG9yIHRvcGljcywgdHlwZSAibW9kdWxlcyIsCiJrZXl3b3JkcyIsIG9yICJ0b3BpY3MiLiAgRWFjaCBtb2R1bGUgYWxzbyBjb21lcyB3aXRoIGEgb25lLWxpbmUgc3VtbWFyeQpvZiB3aGF0IGl0IGRvZXM7IHRvIGxpc3QgdGhlIG1vZHVsZXMgd2hvc2Ugc3VtbWFyaWVzIGNvbnRhaW4gYSBnaXZlbiB3b3JkCnN1Y2ggYXMgInNwYW0iLCB0eXBlICJtb2R1bGVzIHNwYW0iLgonJycgJSBzeXMudmVyc2lvbls6M10pCgogICAgZGVmIGxpc3Qoc2VsZiwgaXRlbXMsIGNvbHVtbnM9NCwgd2lkdGg9ODApOgogICAgICAgIGl0ZW1zID0gaXRlbXNbOl0KICAgICAgICBpdGVtcy5zb3J0KCkKICAgICAgICBjb2x3ID0gd2lkdGggLyBjb2x1bW5zCiAgICAgICAgcm93cyA9IChsZW4oaXRlbXMpICsgY29sdW1ucyAtIDEpIC8gY29sdW1ucwogICAgICAgIGZvciByb3cgaW4gcmFuZ2Uocm93cyk6CiAgICAgICAgICAgIGZvciBjb2wgaW4gcmFuZ2UoY29sdW1ucyk6CiAgICAgICAgICAgICAgICBpID0gY29sICogcm93cyArIHJvdwogICAgICAgICAgICAgICAgaWYgaSA8IGxlbihpdGVtcyk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoaXRlbXNbaV0pCiAgICAgICAgICAgICAgICAgICAgaWYgY29sIDwgY29sdW1ucyAtIDE6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCcgJyArICcgJyAqIChjb2x3LTEgLSBsZW4oaXRlbXNbaV0pKSkKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJ1xuJykKCiAgICBkZWYgbGlzdGtleXdvcmRzKHNlbGYpOgogICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCcnJwpIZXJlIGlzIGEgbGlzdCBvZiB0aGUgUHl0aG9uIGtleXdvcmRzLiAgRW50ZXIgYW55IGtleXdvcmQgdG8gZ2V0IG1vcmUgaGVscC4KCicnJykKICAgICAgICBzZWxmLmxpc3Qoc2VsZi5rZXl3b3Jkcy5rZXlzKCkpCgogICAgZGVmIGxpc3R0b3BpY3Moc2VsZik6CiAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnCkhlcmUgaXMgYSBsaXN0IG9mIGF2YWlsYWJsZSB0b3BpY3MuICBFbnRlciBhbnkgdG9waWMgbmFtZSB0byBnZXQgbW9yZSBoZWxwLgoKJycnKQogICAgICAgIHNlbGYubGlzdChzZWxmLnRvcGljcy5rZXlzKCkpCgogICAgZGVmIHNob3d0b3BpYyhzZWxmLCB0b3BpYyk6CiAgICAgICAgaWYgbm90IHNlbGYuZG9jZGlyOgogICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnJycKU29ycnksIHRvcGljIGFuZCBrZXl3b3JkIGRvY3VtZW50YXRpb24gaXMgbm90IGF2YWlsYWJsZSBiZWNhdXNlIHRoZSBQeXRob24KSFRNTCBkb2N1bWVudGF0aW9uIGZpbGVzIGNvdWxkIG5vdCBiZSBmb3VuZC4gIElmIHlvdSBoYXZlIGluc3RhbGxlZCB0aGVtLApwbGVhc2Ugc2V0IHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZSBQWVRIT05ET0NTIHRvIGluZGljYXRlIHRoZWlyIGxvY2F0aW9uLgonJycpCiAgICAgICAgICAgIHJldHVybgogICAgICAgIHRhcmdldCA9IHNlbGYudG9waWNzLmdldCh0b3BpYywgc2VsZi5rZXl3b3Jkcy5nZXQodG9waWMpKQogICAgICAgIGlmIG5vdCB0YXJnZXQ6CiAgICAgICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCdubyBkb2N1bWVudGF0aW9uIGZvdW5kIGZvciAlc1xuJyAlIHJlcHIodG9waWMpKQogICAgICAgICAgICByZXR1cm4KICAgICAgICBpZiB0eXBlKHRhcmdldCkgaXMgdHlwZSgnJyk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLnNob3d0b3BpYyh0YXJnZXQpCgogICAgICAgIGZpbGVuYW1lLCB4cmVmcyA9IHRhcmdldAogICAgICAgIGZpbGVuYW1lID0gc2VsZi5kb2NkaXIgKyAnLycgKyBmaWxlbmFtZSArICcuaHRtbCcKICAgICAgICB0cnk6CiAgICAgICAgICAgIGZpbGUgPSBvcGVuKGZpbGVuYW1lKQogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJ2NvdWxkIG5vdCByZWFkIGRvY3MgZnJvbSAlc1xuJyAlIGZpbGVuYW1lKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgZGl2cGF0ID0gcmUuY29tcGlsZSgnPGRpdltePl0qbmF2aWdhdC4qPzwvZGl2Lio/PicsIHJlLkkgfCByZS5TKQogICAgICAgIGFkZHJwYXQgPSByZS5jb21waWxlKCc8YWRkcmVzcy4qPz4uKj88L2FkZHJlc3MuKj8+JywgcmUuSSB8IHJlLlMpCiAgICAgICAgZG9jdW1lbnQgPSByZS5zdWIoYWRkcnBhdCwgJycsIHJlLnN1YihkaXZwYXQsICcnLCBmaWxlLnJlYWQoKSkpCiAgICAgICAgZmlsZS5jbG9zZSgpCgogICAgICAgIGltcG9ydCBodG1sbGliLCBmb3JtYXR0ZXIsIFN0cmluZ0lPCiAgICAgICAgYnVmZmVyID0gU3RyaW5nSU8uU3RyaW5nSU8oKQogICAgICAgIHBhcnNlciA9IGh0bWxsaWIuSFRNTFBhcnNlcigKICAgICAgICAgICAgZm9ybWF0dGVyLkFic3RyYWN0Rm9ybWF0dGVyKGZvcm1hdHRlci5EdW1iV3JpdGVyKGJ1ZmZlcikpKQogICAgICAgIHBhcnNlci5zdGFydF90YWJsZSA9IHBhcnNlci5kb19wCiAgICAgICAgcGFyc2VyLmVuZF90YWJsZSA9IGxhbWJkYSBwYXJzZXI9cGFyc2VyOiBwYXJzZXIuZG9fcCh7fSkKICAgICAgICBwYXJzZXIuc3RhcnRfdHIgPSBwYXJzZXIuZG9fYnIKICAgICAgICBwYXJzZXIuc3RhcnRfdGQgPSBwYXJzZXIuc3RhcnRfdGggPSBsYW1iZGEgYSwgYj1idWZmZXI6IGIud3JpdGUoJ1x0JykKICAgICAgICBwYXJzZXIuZmVlZChkb2N1bWVudCkKICAgICAgICBidWZmZXIgPSByZXBsYWNlKGJ1ZmZlci5nZXR2YWx1ZSgpLCAnXHhhMCcsICcgJywgJ1xuJywgJ1xuICAnKQogICAgICAgIHBhZ2VyKCcgICcgKyBzdHJpcChidWZmZXIpICsgJ1xuJykKICAgICAgICBpZiB4cmVmczoKICAgICAgICAgICAgYnVmZmVyID0gU3RyaW5nSU8uU3RyaW5nSU8oKQogICAgICAgICAgICBmb3JtYXR0ZXIuRHVtYldyaXRlcihidWZmZXIpLnNlbmRfZmxvd2luZ19kYXRhKAogICAgICAgICAgICAgICAgJ1JlbGF0ZWQgaGVscCB0b3BpY3M6ICcgKyBqb2luKHNwbGl0KHhyZWZzKSwgJywgJykgKyAnXG4nKQogICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnXG4lc1xuJyAlIGJ1ZmZlci5nZXR2YWx1ZSgpKQoKICAgIGRlZiBsaXN0bW9kdWxlcyhzZWxmLCBrZXk9JycpOgogICAgICAgIGlmIGtleToKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnCkhlcmUgaXMgYSBsaXN0IG9mIG1hdGNoaW5nIG1vZHVsZXMuICBFbnRlciBhbnkgbW9kdWxlIG5hbWUgdG8gZ2V0IG1vcmUgaGVscC4KCicnJykKICAgICAgICAgICAgYXByb3BvcyhrZXkpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnClBsZWFzZSB3YWl0IGEgbW9tZW50IHdoaWxlIEkgZ2F0aGVyIGEgbGlzdCBvZiBhbGwgYXZhaWxhYmxlIG1vZHVsZXMuLi4KCicnJykKICAgICAgICAgICAgbW9kdWxlcyA9IHt9CiAgICAgICAgICAgIGRlZiBjYWxsYmFjayhwYXRoLCBtb2RuYW1lLCBkZXNjLCBtb2R1bGVzPW1vZHVsZXMpOgogICAgICAgICAgICAgICAgaWYgbW9kbmFtZSBhbmQgbW9kbmFtZVstOTpdID09ICcuX19pbml0X18nOgogICAgICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBtb2RuYW1lWzotOV0gKyAnIChwYWNrYWdlKScKICAgICAgICAgICAgICAgIGlmIGZpbmQobW9kbmFtZSwgJy4nKSA8IDA6CiAgICAgICAgICAgICAgICAgICAgbW9kdWxlc1ttb2RuYW1lXSA9IDEKICAgICAgICAgICAgTW9kdWxlU2Nhbm5lcigpLnJ1bihjYWxsYmFjaykKICAgICAgICAgICAgc2VsZi5saXN0KG1vZHVsZXMua2V5cygpKQogICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnJycKRW50ZXIgYW55IG1vZHVsZSBuYW1lIHRvIGdldCBtb3JlIGhlbHAuICBPciwgdHlwZSAibW9kdWxlcyBzcGFtIiB0byBzZWFyY2gKZm9yIG1vZHVsZXMgd2hvc2UgZGVzY3JpcHRpb25zIGNvbnRhaW4gdGhlIHdvcmQgInNwYW0iLgonJycpCgpoZWxwID0gSGVscGVyKHN5cy5zdGRpbiwgc3lzLnN0ZG91dCkKCmNsYXNzIFNjYW5uZXI6CiAgICAiIiJBIGdlbmVyaWMgdHJlZSBpdGVyYXRvci4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCByb290cywgY2hpbGRyZW4sIGRlc2NlbmRwKToKICAgICAgICBzZWxmLnJvb3RzID0gcm9vdHNbOl0KICAgICAgICBzZWxmLnN0YXRlID0gW10KICAgICAgICBzZWxmLmNoaWxkcmVuID0gY2hpbGRyZW4KICAgICAgICBzZWxmLmRlc2NlbmRwID0gZGVzY2VuZHAKCiAgICBkZWYgbmV4dChzZWxmKToKICAgICAgICBpZiBub3Qgc2VsZi5zdGF0ZToKICAgICAgICAgICAgaWYgbm90IHNlbGYucm9vdHM6CiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgICAgICByb290ID0gc2VsZi5yb290cy5wb3AoMCkKICAgICAgICAgICAgc2VsZi5zdGF0ZSA9IFsocm9vdCwgc2VsZi5jaGlsZHJlbihyb290KSldCiAgICAgICAgbm9kZSwgY2hpbGRyZW4gPSBzZWxmLnN0YXRlWy0xXQogICAgICAgIGlmIG5vdCBjaGlsZHJlbjoKICAgICAgICAgICAgc2VsZi5zdGF0ZS5wb3AoKQogICAgICAgICAgICByZXR1cm4gc2VsZi5uZXh0KCkKICAgICAgICBjaGlsZCA9IGNoaWxkcmVuLnBvcCgwKQogICAgICAgIGlmIHNlbGYuZGVzY2VuZHAoY2hpbGQpOgogICAgICAgICAgICBzZWxmLnN0YXRlLmFwcGVuZCgoY2hpbGQsIHNlbGYuY2hpbGRyZW4oY2hpbGQpKSkKICAgICAgICByZXR1cm4gY2hpbGQKCmNsYXNzIE1vZHVsZVNjYW5uZXIoU2Nhbm5lcik6CiAgICAiIiJBbiBpbnRlcnJ1cHRpYmxlIHNjYW5uZXIgdGhhdCBzZWFyY2hlcyBtb2R1bGUgc3lub3BzZXMuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgcm9vdHMgPSBtYXAobGFtYmRhIGRpcjogKGRpciwgJycpLCBwYXRoZGlycygpKQogICAgICAgIFNjYW5uZXIuX19pbml0X18oc2VsZiwgcm9vdHMsIHNlbGYuc3VibW9kdWxlcywgc2VsZi5pc25ld3BhY2thZ2UpCiAgICAgICAgc2VsZi5pbm9kZXMgPSBtYXAobGFtYmRhIChkaXIsIHBrZyk6IG9zLnN0YXQoZGlyKVsxXSwgcm9vdHMpCgogICAgZGVmIHN1Ym1vZHVsZXMoc2VsZiwgKGRpciwgcGFja2FnZSkpOgogICAgICAgIGNoaWxkcmVuID0gW10KICAgICAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKGRpcik6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oZGlyLCBmaWxlKQogICAgICAgICAgICBpZiBpc3BhY2thZ2UocGF0aCk6CiAgICAgICAgICAgICAgICBjaGlsZHJlbi5hcHBlbmQoKHBhdGgsIHBhY2thZ2UgKyAocGFja2FnZSBhbmQgJy4nKSArIGZpbGUpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgY2hpbGRyZW4uYXBwZW5kKChwYXRoLCBwYWNrYWdlKSkKICAgICAgICBjaGlsZHJlbi5zb3J0KCkgIyBzbyB0aGF0IHNwYW0ucHkgY29tZXMgYmVmb3JlIHNwYW0ucHljIG9yIHNwYW0ucHlvCiAgICAgICAgcmV0dXJuIGNoaWxkcmVuCgogICAgZGVmIGlzbmV3cGFja2FnZShzZWxmLCAoZGlyLCBwYWNrYWdlKSk6CiAgICAgICAgaW5vZGUgPSBvcy5wYXRoLmV4aXN0cyhkaXIpIGFuZCBvcy5zdGF0KGRpcilbMV0KICAgICAgICBpZiBub3QgKG9zLnBhdGguaXNsaW5rKGRpcikgYW5kIGlub2RlIGluIHNlbGYuaW5vZGVzKToKICAgICAgICAgICAgc2VsZi5pbm9kZXMuYXBwZW5kKGlub2RlKSAjIGRldGVjdCBjaXJjdWxhciBzeW1ib2xpYyBsaW5rcwogICAgICAgICAgICByZXR1cm4gaXNwYWNrYWdlKGRpcikKCiAgICBkZWYgcnVuKHNlbGYsIGNhbGxiYWNrLCBrZXk9Tm9uZSwgY29tcGxldGVyPU5vbmUpOgogICAgICAgIGlmIGtleToga2V5ID0gbG93ZXIoa2V5KQogICAgICAgIHNlbGYucXVpdCA9IDAKICAgICAgICBzZWVuID0ge30KCiAgICAgICAgZm9yIG1vZG5hbWUgaW4gc3lzLmJ1aWx0aW5fbW9kdWxlX25hbWVzOgogICAgICAgICAgICBpZiBtb2RuYW1lICE9ICdfX21haW5fXyc6CiAgICAgICAgICAgICAgICBzZWVuW21vZG5hbWVdID0gMQogICAgICAgICAgICAgICAgaWYga2V5IGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soTm9uZSwgbW9kbmFtZSwgJycpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIGRlc2MgPSBzcGxpdChfX2ltcG9ydF9fKG1vZG5hbWUpLl9fZG9jX18gb3IgJycsICdcbicpWzBdCiAgICAgICAgICAgICAgICAgICAgaWYgZmluZChsb3dlcihtb2RuYW1lICsgJyAtICcgKyBkZXNjKSwga2V5KSA+PSAwOgogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhOb25lLCBtb2RuYW1lLCBkZXNjKQoKICAgICAgICB3aGlsZSBub3Qgc2VsZi5xdWl0OgogICAgICAgICAgICBub2RlID0gc2VsZi5uZXh0KCkKICAgICAgICAgICAgaWYgbm90IG5vZGU6IGJyZWFrCiAgICAgICAgICAgIHBhdGgsIHBhY2thZ2UgPSBub2RlCiAgICAgICAgICAgIG1vZG5hbWUgPSBpbnNwZWN0LmdldG1vZHVsZW5hbWUocGF0aCkKICAgICAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUocGF0aCkgYW5kIG1vZG5hbWU6CiAgICAgICAgICAgICAgICBtb2RuYW1lID0gcGFja2FnZSArIChwYWNrYWdlIGFuZCAnLicpICsgbW9kbmFtZQogICAgICAgICAgICAgICAgaWYgbm90IHNlZW4uaGFzX2tleShtb2RuYW1lKToKICAgICAgICAgICAgICAgICAgICBzZWVuW21vZG5hbWVdID0gMSAjIGlmIHdlIHNlZSBzcGFtLnB5LCBza2lwIHNwYW0ucHljCiAgICAgICAgICAgICAgICAgICAgaWYga2V5IGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHBhdGgsIG1vZG5hbWUsICcnKQogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2MgPSBzeW5vcHNpcyhwYXRoKSBvciAnJwogICAgICAgICAgICAgICAgICAgICAgICBpZiBmaW5kKGxvd2VyKG1vZG5hbWUgKyAnIC0gJyArIGRlc2MpLCBrZXkpID49IDA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhwYXRoLCBtb2RuYW1lLCBkZXNjKQogICAgICAgIGlmIGNvbXBsZXRlcjogY29tcGxldGVyKCkKCmRlZiBhcHJvcG9zKGtleSk6CiAgICAiIiJQcmludCBhbGwgdGhlIG9uZS1saW5lIG1vZHVsZSBzdW1tYXJpZXMgdGhhdCBjb250YWluIGEgc3Vic3RyaW5nLiIiIgogICAgZGVmIGNhbGxiYWNrKHBhdGgsIG1vZG5hbWUsIGRlc2MpOgogICAgICAgIGlmIG1vZG5hbWVbLTk6XSA9PSAnLl9faW5pdF9fJzoKICAgICAgICAgICAgbW9kbmFtZSA9IG1vZG5hbWVbOi05XSArICcgKHBhY2thZ2UpJwogICAgICAgIHByaW50IG1vZG5hbWUsIGRlc2MgYW5kICctICcgKyBkZXNjCiAgICB0cnk6IGltcG9ydCB3YXJuaW5ncwogICAgZXhjZXB0IEltcG9ydEVycm9yOiBwYXNzCiAgICBlbHNlOiB3YXJuaW5ncy5maWx0ZXJ3YXJuaW5ncygnaWdub3JlJykgIyBpZ25vcmUgcHJvYmxlbXMgZHVyaW5nIGltcG9ydAogICAgTW9kdWxlU2Nhbm5lcigpLnJ1bihjYWxsYmFjaywga2V5KQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gd2ViIGJyb3dzZXIgaW50ZXJmYWNlCgpkZWYgc2VydmUocG9ydCwgY2FsbGJhY2s9Tm9uZSwgY29tcGxldGVyPU5vbmUpOgogICAgaW1wb3J0IEJhc2VIVFRQU2VydmVyLCBtaW1ldG9vbHMsIHNlbGVjdAoKICAgICMgUGF0Y2ggdXAgbWltZXRvb2xzLk1lc3NhZ2Ugc28gaXQgZG9lc24ndCBicmVhayBpZiByZmM4MjIgaXMgcmVsb2FkZWQuCiAgICBjbGFzcyBNZXNzYWdlKG1pbWV0b29scy5NZXNzYWdlKToKICAgICAgICBkZWYgX19pbml0X18oc2VsZiwgZnAsIHNlZWthYmxlPTEpOgogICAgICAgICAgICBNZXNzYWdlID0gc2VsZi5fX2NsYXNzX18KICAgICAgICAgICAgTWVzc2FnZS5fX2Jhc2VzX19bMF0uX19iYXNlc19fWzBdLl9faW5pdF9fKHNlbGYsIGZwLCBzZWVrYWJsZSkKICAgICAgICAgICAgc2VsZi5lbmNvZGluZ2hlYWRlciA9IHNlbGYuZ2V0aGVhZGVyKCdjb250ZW50LXRyYW5zZmVyLWVuY29kaW5nJykKICAgICAgICAgICAgc2VsZi50eXBlaGVhZGVyID0gc2VsZi5nZXRoZWFkZXIoJ2NvbnRlbnQtdHlwZScpCiAgICAgICAgICAgIHNlbGYucGFyc2V0eXBlKCkKICAgICAgICAgICAgc2VsZi5wYXJzZXBsaXN0KCkKCiAgICBjbGFzcyBEb2NIYW5kbGVyKEJhc2VIVFRQU2VydmVyLkJhc2VIVFRQUmVxdWVzdEhhbmRsZXIpOgogICAgICAgIGRlZiBzZW5kX2RvY3VtZW50KHNlbGYsIHRpdGxlLCBjb250ZW50cyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9yZXNwb25zZSgyMDApCiAgICAgICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCdDb250ZW50LVR5cGUnLCAndGV4dC9odG1sJykKICAgICAgICAgICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgICAgICAgICAgc2VsZi53ZmlsZS53cml0ZShodG1sLnBhZ2UodGl0bGUsIGNvbnRlbnRzKSkKICAgICAgICAgICAgZXhjZXB0IElPRXJyb3I6IHBhc3MKCiAgICAgICAgZGVmIGRvX0dFVChzZWxmKToKICAgICAgICAgICAgcGF0aCA9IHNlbGYucGF0aAogICAgICAgICAgICBpZiBwYXRoWy01Ol0gPT0gJy5odG1sJzogcGF0aCA9IHBhdGhbOi01XQogICAgICAgICAgICBpZiBwYXRoWzoxXSA9PSAnLyc6IHBhdGggPSBwYXRoWzE6XQogICAgICAgICAgICBpZiBwYXRoIGFuZCBwYXRoICE9ICcuJzoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBvYmogPSBsb2NhdGUocGF0aCwgZm9yY2Vsb2FkPTEpCiAgICAgICAgICAgICAgICBleGNlcHQgRXJyb3JEdXJpbmdJbXBvcnQsIHZhbHVlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9kb2N1bWVudChwYXRoLCBodG1sLmVzY2FwZShzdHIodmFsdWUpKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIGlmIG9iajoKICAgICAgICAgICAgICAgICAgICBzZWxmLnNlbmRfZG9jdW1lbnQoZGVzY3JpYmUob2JqKSwgaHRtbC5kb2N1bWVudChvYmosIHBhdGgpKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLnNlbmRfZG9jdW1lbnQocGF0aCwKJ25vIFB5dGhvbiBkb2N1bWVudGF0aW9uIGZvdW5kIGZvciAlcycgJSByZXByKHBhdGgpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaGVhZGluZyA9IGh0bWwuaGVhZGluZygKJzxiaWc+PGJpZz48c3Ryb25nPlB5dGhvbjogSW5kZXggb2YgTW9kdWxlczwvc3Ryb25nPjwvYmlnPjwvYmlnPicsCicjZmZmZmZmJywgJyM3Nzk5ZWUnKQogICAgICAgICAgICAgICAgZGVmIGJsdGlubGluayhuYW1lKToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzLmh0bWwiPiVzPC9hPicgJSAobmFtZSwgbmFtZSkKICAgICAgICAgICAgICAgIG5hbWVzID0gZmlsdGVyKGxhbWJkYSB4OiB4ICE9ICdfX21haW5fXycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXMuYnVpbHRpbl9tb2R1bGVfbmFtZXMpCiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGh0bWwubXVsdGljb2x1bW4obmFtZXMsIGJsdGlubGluaykKICAgICAgICAgICAgICAgIGluZGljZXMgPSBbJzxwPicgKyBodG1sLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgJ0J1aWx0LWluIE1vZHVsZXMnLCAnI2ZmZmZmZicsICcjZWU3N2FhJywgY29udGVudHMpXQoKICAgICAgICAgICAgICAgIHNlZW4gPSB7fQogICAgICAgICAgICAgICAgZm9yIGRpciBpbiBwYXRoZGlycygpOgogICAgICAgICAgICAgICAgICAgIGluZGljZXMuYXBwZW5kKGh0bWwuaW5kZXgoZGlyLCBzZWVuKSkKICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gaGVhZGluZyArIGpvaW4oaW5kaWNlcykgKyAnJyc8cCBhbGlnbj1yaWdodD4KPHNtYWxsPjxzbWFsbD48Zm9udCBjb2xvcj0iIzkwOTA5MCIgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+PHN0cm9uZz4KcHlkb2M8L3N0cm9uZz4gYnkgS2EtUGluZyBZZWUgJmx0O3BpbmdAbGZ3Lm9yZyZndDs8L2ZvbnQ+PC9zbWFsbD48L3NtYWxsPicnJwogICAgICAgICAgICAgICAgc2VsZi5zZW5kX2RvY3VtZW50KCdJbmRleCBvZiBNb2R1bGVzJywgY29udGVudHMpCgogICAgICAgIGRlZiBsb2dfbWVzc2FnZShzZWxmLCAqYXJncyk6IHBhc3MKCiAgICBjbGFzcyBEb2NTZXJ2ZXIoQmFzZUhUVFBTZXJ2ZXIuSFRUUFNlcnZlcik6CiAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIHBvcnQsIGNhbGxiYWNrKToKICAgICAgICAgICAgaG9zdCA9IChzeXMucGxhdGZvcm0gPT0gJ21hYycpIGFuZCAnMTI3LjAuMC4xJyBvciAnbG9jYWxob3N0JwogICAgICAgICAgICBzZWxmLmFkZHJlc3MgPSAoJycsIHBvcnQpCiAgICAgICAgICAgIHNlbGYudXJsID0gJ2h0dHA6Ly8lczolZC8nICUgKGhvc3QsIHBvcnQpCiAgICAgICAgICAgIHNlbGYuY2FsbGJhY2sgPSBjYWxsYmFjawogICAgICAgICAgICBzZWxmLmJhc2UuX19pbml0X18oc2VsZiwgc2VsZi5hZGRyZXNzLCBzZWxmLmhhbmRsZXIpCgogICAgICAgIGRlZiBzZXJ2ZV91bnRpbF9xdWl0KHNlbGYpOgogICAgICAgICAgICBpbXBvcnQgc2VsZWN0CiAgICAgICAgICAgIHNlbGYucXVpdCA9IDAKICAgICAgICAgICAgd2hpbGUgbm90IHNlbGYucXVpdDoKICAgICAgICAgICAgICAgIHJkLCB3ciwgZXggPSBzZWxlY3Quc2VsZWN0KFtzZWxmLnNvY2tldC5maWxlbm8oKV0sIFtdLCBbXSwgMSkKICAgICAgICAgICAgICAgIGlmIHJkOiBzZWxmLmhhbmRsZV9yZXF1ZXN0KCkKCiAgICAgICAgZGVmIHNlcnZlcl9hY3RpdmF0ZShzZWxmKToKICAgICAgICAgICAgc2VsZi5iYXNlLnNlcnZlcl9hY3RpdmF0ZShzZWxmKQogICAgICAgICAgICBpZiBzZWxmLmNhbGxiYWNrOiBzZWxmLmNhbGxiYWNrKHNlbGYpCgogICAgRG9jU2VydmVyLmJhc2UgPSBCYXNlSFRUUFNlcnZlci5IVFRQU2VydmVyCiAgICBEb2NTZXJ2ZXIuaGFuZGxlciA9IERvY0hhbmRsZXIKICAgIERvY0hhbmRsZXIuTWVzc2FnZUNsYXNzID0gTWVzc2FnZQogICAgdHJ5OgogICAgICAgIHRyeToKICAgICAgICAgICAgRG9jU2VydmVyKHBvcnQsIGNhbGxiYWNrKS5zZXJ2ZV91bnRpbF9xdWl0KCkKICAgICAgICBleGNlcHQgKEtleWJvYXJkSW50ZXJydXB0LCBzZWxlY3QuZXJyb3IpOgogICAgICAgICAgICBwYXNzCiAgICBmaW5hbGx5OgogICAgICAgIGlmIGNvbXBsZXRlcjogY29tcGxldGVyKCkKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gZ3JhcGhpY2FsIGludGVyZmFjZQoKZGVmIGd1aSgpOgogICAgIiIiR3JhcGhpY2FsIGludGVyZmFjZSAoc3RhcnRzIHdlYiBzZXJ2ZXIgYW5kIHBvcHMgdXAgYSBjb250cm9sIHdpbmRvdykuIiIiCiAgICBjbGFzcyBHVUk6CiAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIHdpbmRvdywgcG9ydD03NDY0KToKICAgICAgICAgICAgc2VsZi53aW5kb3cgPSB3aW5kb3cKICAgICAgICAgICAgc2VsZi5zZXJ2ZXIgPSBOb25lCiAgICAgICAgICAgIHNlbGYuc2Nhbm5lciA9IE5vbmUKCiAgICAgICAgICAgIGltcG9ydCBUa2ludGVyCiAgICAgICAgICAgIHNlbGYuc2VydmVyX2ZybSA9IFRraW50ZXIuRnJhbWUod2luZG93KQogICAgICAgICAgICBzZWxmLnRpdGxlX2xibCA9IFRraW50ZXIuTGFiZWwoc2VsZi5zZXJ2ZXJfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0nU3RhcnRpbmcgc2VydmVyLi4uXG4gJykKICAgICAgICAgICAgc2VsZi5vcGVuX2J0biA9IFRraW50ZXIuQnV0dG9uKHNlbGYuc2VydmVyX2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J29wZW4gYnJvd3NlcicsIGNvbW1hbmQ9c2VsZi5vcGVuLCBzdGF0ZT0nZGlzYWJsZWQnKQogICAgICAgICAgICBzZWxmLnF1aXRfYnRuID0gVGtpbnRlci5CdXR0b24oc2VsZi5zZXJ2ZXJfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0ncXVpdCBzZXJ2aW5nJywgY29tbWFuZD1zZWxmLnF1aXQsIHN0YXRlPSdkaXNhYmxlZCcpCgogICAgICAgICAgICBzZWxmLnNlYXJjaF9mcm0gPSBUa2ludGVyLkZyYW1lKHdpbmRvdykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfbGJsID0gVGtpbnRlci5MYWJlbChzZWxmLnNlYXJjaF9mcm0sIHRleHQ9J1NlYXJjaCBmb3InKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQgPSBUa2ludGVyLkVudHJ5KHNlbGYuc2VhcmNoX2ZybSkKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50LmJpbmQoJzxSZXR1cm4+Jywgc2VsZi5zZWFyY2gpCiAgICAgICAgICAgIHNlbGYuc3RvcF9idG4gPSBUa2ludGVyLkJ1dHRvbihzZWxmLnNlYXJjaF9mcm0sCiAgICAgICAgICAgICAgICB0ZXh0PSdzdG9wJywgcGFkeT0wLCBjb21tYW5kPXNlbGYuc3RvcCwgc3RhdGU9J2Rpc2FibGVkJykKICAgICAgICAgICAgaWYgc3lzLnBsYXRmb3JtID09ICd3aW4zMic6CiAgICAgICAgICAgICAgICAjIFRyeWluZyB0byBoaWRlIGFuZCBzaG93IHRoaXMgYnV0dG9uIGNyYXNoZXMgdW5kZXIgV2luZG93cy4KICAgICAgICAgICAgICAgIHNlbGYuc3RvcF9idG4ucGFjayhzaWRlPSdyaWdodCcpCgogICAgICAgICAgICBzZWxmLndpbmRvdy50aXRsZSgncHlkb2MnKQogICAgICAgICAgICBzZWxmLndpbmRvdy5wcm90b2NvbCgnV01fREVMRVRFX1dJTkRPVycsIHNlbGYucXVpdCkKICAgICAgICAgICAgc2VsZi50aXRsZV9sYmwucGFjayhzaWRlPSd0b3AnLCBmaWxsPSd4JykKICAgICAgICAgICAgc2VsZi5vcGVuX2J0bi5wYWNrKHNpZGU9J2xlZnQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCiAgICAgICAgICAgIHNlbGYucXVpdF9idG4ucGFjayhzaWRlPSdyaWdodCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKICAgICAgICAgICAgc2VsZi5zZXJ2ZXJfZnJtLnBhY2soc2lkZT0ndG9wJywgZmlsbD0neCcpCgogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwucGFjayhzaWRlPSdsZWZ0JykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50LnBhY2soc2lkZT0ncmlnaHQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2ZybS5wYWNrKHNpZGU9J3RvcCcsIGZpbGw9J3gnKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQuZm9jdXNfc2V0KCkKCiAgICAgICAgICAgIGZvbnQgPSAoJ2hlbHZldGljYScsIHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInIGFuZCA4IG9yIDEwKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QgPSBUa2ludGVyLkxpc3Rib3god2luZG93LCBmb250PWZvbnQsIGhlaWdodD02KQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QuYmluZCgnPEJ1dHRvbi0xPicsIHNlbGYuc2VsZWN0KQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QuYmluZCgnPERvdWJsZS1CdXR0b24tMT4nLCBzZWxmLmdvdG8pCiAgICAgICAgICAgIHNlbGYucmVzdWx0X3NjciA9IFRraW50ZXIuU2Nyb2xsYmFyKHdpbmRvdywKICAgICAgICAgICAgICAgIG9yaWVudD0ndmVydGljYWwnLCBjb21tYW5kPXNlbGYucmVzdWx0X2xzdC55dmlldykKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmNvbmZpZyh5c2Nyb2xsY29tbWFuZD1zZWxmLnJlc3VsdF9zY3Iuc2V0KQoKICAgICAgICAgICAgc2VsZi5yZXN1bHRfZnJtID0gVGtpbnRlci5GcmFtZSh3aW5kb3cpCiAgICAgICAgICAgIHNlbGYuZ290b19idG4gPSBUa2ludGVyLkJ1dHRvbihzZWxmLnJlc3VsdF9mcm0sCiAgICAgICAgICAgICAgICB0ZXh0PSdnbyB0byBzZWxlY3RlZCcsIGNvbW1hbmQ9c2VsZi5nb3RvKQogICAgICAgICAgICBzZWxmLmhpZGVfYnRuID0gVGtpbnRlci5CdXR0b24oc2VsZi5yZXN1bHRfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0naGlkZSByZXN1bHRzJywgY29tbWFuZD1zZWxmLmhpZGUpCiAgICAgICAgICAgIHNlbGYuZ290b19idG4ucGFjayhzaWRlPSdsZWZ0JywgZmlsbD0neCcsIGV4cGFuZD0xKQogICAgICAgICAgICBzZWxmLmhpZGVfYnRuLnBhY2soc2lkZT0ncmlnaHQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCgogICAgICAgICAgICBzZWxmLndpbmRvdy51cGRhdGUoKQogICAgICAgICAgICBzZWxmLm1pbndpZHRoID0gc2VsZi53aW5kb3cud2luZm9fd2lkdGgoKQogICAgICAgICAgICBzZWxmLm1pbmhlaWdodCA9IHNlbGYud2luZG93LndpbmZvX2hlaWdodCgpCiAgICAgICAgICAgIHNlbGYuYmlnbWluaGVpZ2h0ID0gKHNlbGYuc2VydmVyX2ZybS53aW5mb19yZXFoZWlnaHQoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc2VhcmNoX2ZybS53aW5mb19yZXFoZWlnaHQoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC53aW5mb19yZXFoZWlnaHQoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYucmVzdWx0X2ZybS53aW5mb19yZXFoZWlnaHQoKSkKICAgICAgICAgICAgc2VsZi5iaWd3aWR0aCwgc2VsZi5iaWdoZWlnaHQgPSBzZWxmLm1pbndpZHRoLCBzZWxmLmJpZ21pbmhlaWdodAogICAgICAgICAgICBzZWxmLmV4cGFuZGVkID0gMAogICAgICAgICAgICBzZWxmLndpbmRvdy53bV9nZW9tZXRyeSgnJWR4JWQnICUgKHNlbGYubWlud2lkdGgsIHNlbGYubWluaGVpZ2h0KSkKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fbWluc2l6ZShzZWxmLm1pbndpZHRoLCBzZWxmLm1pbmhlaWdodCkKCiAgICAgICAgICAgIGltcG9ydCB0aHJlYWRpbmcKICAgICAgICAgICAgdGhyZWFkaW5nLlRocmVhZCgKICAgICAgICAgICAgICAgIHRhcmdldD1zZXJ2ZSwgYXJncz0ocG9ydCwgc2VsZi5yZWFkeSwgc2VsZi5xdWl0KSkuc3RhcnQoKQoKICAgICAgICBkZWYgcmVhZHkoc2VsZiwgc2VydmVyKToKICAgICAgICAgICAgc2VsZi5zZXJ2ZXIgPSBzZXJ2ZXIKICAgICAgICAgICAgc2VsZi50aXRsZV9sYmwuY29uZmlnKAogICAgICAgICAgICAgICAgdGV4dD0nUHl0aG9uIGRvY3VtZW50YXRpb24gc2VydmVyIGF0XG4nICsgc2VydmVyLnVybCkKICAgICAgICAgICAgc2VsZi5vcGVuX2J0bi5jb25maWcoc3RhdGU9J25vcm1hbCcpCiAgICAgICAgICAgIHNlbGYucXVpdF9idG4uY29uZmlnKHN0YXRlPSdub3JtYWwnKQoKICAgICAgICBkZWYgb3BlbihzZWxmLCBldmVudD1Ob25lLCB1cmw9Tm9uZSk6CiAgICAgICAgICAgIHVybCA9IHVybCBvciBzZWxmLnNlcnZlci51cmwKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaW1wb3J0IHdlYmJyb3dzZXIKICAgICAgICAgICAgICAgIHdlYmJyb3dzZXIub3Blbih1cmwpCiAgICAgICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjogIyBwcmUtd2ViYnJvd3Nlci5weSBjb21wYXRpYmlsaXR5CiAgICAgICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gPT0gJ3dpbjMyJzoKICAgICAgICAgICAgICAgICAgICBvcy5zeXN0ZW0oJ3N0YXJ0ICIlcyInICUgdXJsKQogICAgICAgICAgICAgICAgZWxpZiBzeXMucGxhdGZvcm0gPT0gJ21hYyc6CiAgICAgICAgICAgICAgICAgICAgdHJ5OiBpbXBvcnQgaWMKICAgICAgICAgICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6IHBhc3MKICAgICAgICAgICAgICAgICAgICBlbHNlOiBpYy5sYXVuY2h1cmwodXJsKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICByYyA9IG9zLnN5c3RlbSgnbmV0c2NhcGUgLXJlbW90ZSAib3BlblVSTCglcykiICYnICUgdXJsKQogICAgICAgICAgICAgICAgICAgIGlmIHJjOiBvcy5zeXN0ZW0oJ25ldHNjYXBlICIlcyIgJicgJSB1cmwpCgogICAgICAgIGRlZiBxdWl0KHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBpZiBzZWxmLnNlcnZlcjoKICAgICAgICAgICAgICAgIHNlbGYuc2VydmVyLnF1aXQgPSAxCiAgICAgICAgICAgIHNlbGYud2luZG93LnF1aXQoKQoKICAgICAgICBkZWYgc2VhcmNoKHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBrZXkgPSBzZWxmLnNlYXJjaF9lbnQuZ2V0KCkKICAgICAgICAgICAgc2VsZi5zdG9wX2J0bi5wYWNrKHNpZGU9J3JpZ2h0JykKICAgICAgICAgICAgc2VsZi5zdG9wX2J0bi5jb25maWcoc3RhdGU9J25vcm1hbCcpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibC5jb25maWcodGV4dD0nU2VhcmNoaW5nIGZvciAiJXMiLi4uJyAlIGtleSkKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50LmZvcmdldCgpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibC5wYWNrKHNpZGU9J2xlZnQnKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QuZGVsZXRlKDAsICdlbmQnKQogICAgICAgICAgICBzZWxmLmdvdG9fYnRuLmNvbmZpZyhzdGF0ZT0nZGlzYWJsZWQnKQogICAgICAgICAgICBzZWxmLmV4cGFuZCgpCgogICAgICAgICAgICBpbXBvcnQgdGhyZWFkaW5nCiAgICAgICAgICAgIGlmIHNlbGYuc2Nhbm5lcjoKICAgICAgICAgICAgICAgIHNlbGYuc2Nhbm5lci5xdWl0ID0gMQogICAgICAgICAgICBzZWxmLnNjYW5uZXIgPSBNb2R1bGVTY2FubmVyKCkKICAgICAgICAgICAgdGhyZWFkaW5nLlRocmVhZCh0YXJnZXQ9c2VsZi5zY2FubmVyLnJ1biwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzPShzZWxmLnVwZGF0ZSwga2V5LCBzZWxmLmRvbmUpKS5zdGFydCgpCgogICAgICAgIGRlZiB1cGRhdGUoc2VsZiwgcGF0aCwgbW9kbmFtZSwgZGVzYyk6CiAgICAgICAgICAgIGlmIG1vZG5hbWVbLTk6XSA9PSAnLl9faW5pdF9fJzoKICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBtb2RuYW1lWzotOV0gKyAnIChwYWNrYWdlKScKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0Lmluc2VydCgnZW5kJywKICAgICAgICAgICAgICAgIG1vZG5hbWUgKyAnIC0gJyArIChkZXNjIG9yICcobm8gZGVzY3JpcHRpb24pJykpCgogICAgICAgIGRlZiBzdG9wKHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBpZiBzZWxmLnNjYW5uZXI6CiAgICAgICAgICAgICAgICBzZWxmLnNjYW5uZXIucXVpdCA9IDEKICAgICAgICAgICAgICAgIHNlbGYuc2Nhbm5lciA9IE5vbmUKCiAgICAgICAgZGVmIGRvbmUoc2VsZik6CiAgICAgICAgICAgIHNlbGYuc2Nhbm5lciA9IE5vbmUKICAgICAgICAgICAgc2VsZi5zZWFyY2hfbGJsLmNvbmZpZyh0ZXh0PSdTZWFyY2ggZm9yJykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfbGJsLnBhY2soc2lkZT0nbGVmdCcpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudC5wYWNrKHNpZGU9J3JpZ2h0JywgZmlsbD0neCcsIGV4cGFuZD0xKQogICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gIT0gJ3dpbjMyJzogc2VsZi5zdG9wX2J0bi5mb3JnZXQoKQogICAgICAgICAgICBzZWxmLnN0b3BfYnRuLmNvbmZpZyhzdGF0ZT0nZGlzYWJsZWQnKQoKICAgICAgICBkZWYgc2VsZWN0KHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBzZWxmLmdvdG9fYnRuLmNvbmZpZyhzdGF0ZT0nbm9ybWFsJykKCiAgICAgICAgZGVmIGdvdG8oc2VsZiwgZXZlbnQ9Tm9uZSk6CiAgICAgICAgICAgIHNlbGVjdGlvbiA9IHNlbGYucmVzdWx0X2xzdC5jdXJzZWxlY3Rpb24oKQogICAgICAgICAgICBpZiBzZWxlY3Rpb246CiAgICAgICAgICAgICAgICBtb2RuYW1lID0gc3BsaXQoc2VsZi5yZXN1bHRfbHN0LmdldChzZWxlY3Rpb25bMF0pKVswXQogICAgICAgICAgICAgICAgc2VsZi5vcGVuKHVybD1zZWxmLnNlcnZlci51cmwgKyBtb2RuYW1lICsgJy5odG1sJykKCiAgICAgICAgZGVmIGNvbGxhcHNlKHNlbGYpOgogICAgICAgICAgICBpZiBub3Qgc2VsZi5leHBhbmRlZDogcmV0dXJuCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2ZybS5mb3JnZXQoKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9zY3IuZm9yZ2V0KCkKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmZvcmdldCgpCiAgICAgICAgICAgIHNlbGYuYmlnd2lkdGggPSBzZWxmLndpbmRvdy53aW5mb193aWR0aCgpCiAgICAgICAgICAgIHNlbGYuYmlnaGVpZ2h0ID0gc2VsZi53aW5kb3cud2luZm9faGVpZ2h0KCkKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fZ2VvbWV0cnkoJyVkeCVkJyAlIChzZWxmLm1pbndpZHRoLCBzZWxmLm1pbmhlaWdodCkpCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX21pbnNpemUoc2VsZi5taW53aWR0aCwgc2VsZi5taW5oZWlnaHQpCiAgICAgICAgICAgIHNlbGYuZXhwYW5kZWQgPSAwCgogICAgICAgIGRlZiBleHBhbmQoc2VsZik6CiAgICAgICAgICAgIGlmIHNlbGYuZXhwYW5kZWQ6IHJldHVybgogICAgICAgICAgICBzZWxmLnJlc3VsdF9mcm0ucGFjayhzaWRlPSdib3R0b20nLCBmaWxsPSd4JykKICAgICAgICAgICAgc2VsZi5yZXN1bHRfc2NyLnBhY2soc2lkZT0ncmlnaHQnLCBmaWxsPSd5JykKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LnBhY2soc2lkZT0ndG9wJywgZmlsbD0nYm90aCcsIGV4cGFuZD0xKQogICAgICAgICAgICBzZWxmLndpbmRvdy53bV9nZW9tZXRyeSgnJWR4JWQnICUgKHNlbGYuYmlnd2lkdGgsIHNlbGYuYmlnaGVpZ2h0KSkKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fbWluc2l6ZShzZWxmLm1pbndpZHRoLCBzZWxmLmJpZ21pbmhlaWdodCkKICAgICAgICAgICAgc2VsZi5leHBhbmRlZCA9IDEKCiAgICAgICAgZGVmIGhpZGUoc2VsZiwgZXZlbnQ9Tm9uZSk6CiAgICAgICAgICAgIHNlbGYuc3RvcCgpCiAgICAgICAgICAgIHNlbGYuY29sbGFwc2UoKQoKICAgIGltcG9ydCBUa2ludGVyCiAgICB0cnk6CiAgICAgICAgZ3VpID0gR1VJKFRraW50ZXIuVGsoKSkKICAgICAgICBUa2ludGVyLm1haW5sb29wKCkKICAgIGV4Y2VwdCBLZXlib2FyZEludGVycnVwdDoKICAgICAgICBwYXNzCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGNvbW1hbmQtbGluZSBpbnRlcmZhY2UKCmRlZiBpc3BhdGgoeCk6CiAgICByZXR1cm4gdHlwZSh4KSBpcyB0eXBlcy5TdHJpbmdUeXBlIGFuZCBmaW5kKHgsIG9zLnNlcCkgPj0gMAoKZGVmIGNsaSgpOgogICAgIiIiQ29tbWFuZC1saW5lIGludGVyZmFjZSAobG9va3MgYXQgc3lzLmFyZ3YgdG8gZGVjaWRlIHdoYXQgdG8gZG8pLiIiIgogICAgaW1wb3J0IGdldG9wdAogICAgY2xhc3MgQmFkVXNhZ2U6IHBhc3MKCiAgICAjIFNjcmlwdHMgZG9uJ3QgZ2V0IHRoZSBjdXJyZW50IGRpcmVjdG9yeSBpbiB0aGVpciBwYXRoIGJ5IGRlZmF1bHQuCiAgICBzY3JpcHRkaXIgPSBvcy5wYXRoLmRpcm5hbWUoc3lzLmFyZ3ZbMF0pCiAgICBpZiBzY3JpcHRkaXIgaW4gc3lzLnBhdGg6CiAgICAgICAgc3lzLnBhdGgucmVtb3ZlKHNjcmlwdGRpcikKICAgIHN5cy5wYXRoLmluc2VydCgwLCAnLicpCgogICAgdHJ5OgogICAgICAgIG9wdHMsIGFyZ3MgPSBnZXRvcHQuZ2V0b3B0KHN5cy5hcmd2WzE6XSwgJ2drOnA6dycpCiAgICAgICAgd3JpdGluZyA9IDAKCiAgICAgICAgZm9yIG9wdCwgdmFsIGluIG9wdHM6CiAgICAgICAgICAgIGlmIG9wdCA9PSAnLWcnOgogICAgICAgICAgICAgICAgZ3VpKCkKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBpZiBvcHQgPT0gJy1rJzoKICAgICAgICAgICAgICAgIGFwcm9wb3ModmFsKQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGlmIG9wdCA9PSAnLXAnOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHBvcnQgPSBpbnQodmFsKQogICAgICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgQmFkVXNhZ2UKICAgICAgICAgICAgICAgIGRlZiByZWFkeShzZXJ2ZXIpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICdweWRvYyBzZXJ2ZXIgcmVhZHkgYXQgJXMnICUgc2VydmVyLnVybAogICAgICAgICAgICAgICAgZGVmIHN0b3BwZWQoKToKICAgICAgICAgICAgICAgICAgICBwcmludCAncHlkb2Mgc2VydmVyIHN0b3BwZWQnCiAgICAgICAgICAgICAgICBzZXJ2ZShwb3J0LCByZWFkeSwgc3RvcHBlZCkKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBpZiBvcHQgPT0gJy13JzoKICAgICAgICAgICAgICAgIHdyaXRpbmcgPSAxCgogICAgICAgIGlmIG5vdCBhcmdzOiByYWlzZSBCYWRVc2FnZQogICAgICAgIGZvciBhcmcgaW4gYXJnczoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaWYgaXNwYXRoKGFyZykgYW5kIG9zLnBhdGguaXNmaWxlKGFyZyk6CiAgICAgICAgICAgICAgICAgICAgYXJnID0gaW1wb3J0ZmlsZShhcmcpCiAgICAgICAgICAgICAgICBpZiB3cml0aW5nOgogICAgICAgICAgICAgICAgICAgIGlmIGlzcGF0aChhcmcpIGFuZCBvcy5wYXRoLmlzZGlyKGFyZyk6CiAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlZG9jcyhhcmcpCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVkb2MoYXJnKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBkb2MoYXJnKQogICAgICAgICAgICBleGNlcHQgRXJyb3JEdXJpbmdJbXBvcnQsIHZhbHVlOgogICAgICAgICAgICAgICAgcHJpbnQgdmFsdWUKCiAgICBleGNlcHQgKGdldG9wdC5lcnJvciwgQmFkVXNhZ2UpOgogICAgICAgIGNtZCA9IHN5cy5hcmd2WzBdCiAgICAgICAgcHJpbnQgIiIicHlkb2MgLSB0aGUgUHl0aG9uIGRvY3VtZW50YXRpb24gdG9vbAoKJXMgPG5hbWU+IC4uLgogICAgU2hvdyB0ZXh0IGRvY3VtZW50YXRpb24gb24gc29tZXRoaW5nLiAgPG5hbWU+IG1heSBiZSB0aGUgbmFtZSBvZiBhCiAgICBmdW5jdGlvbiwgbW9kdWxlLCBvciBwYWNrYWdlLCBvciBhIGRvdHRlZCByZWZlcmVuY2UgdG8gYSBjbGFzcyBvcgogICAgZnVuY3Rpb24gd2l0aGluIGEgbW9kdWxlIG9yIG1vZHVsZSBpbiBhIHBhY2thZ2UuICBJZiA8bmFtZT4gY29udGFpbnMKICAgIGEgJyVzJywgaXQgaXMgdXNlZCBhcyB0aGUgcGF0aCB0byBhIFB5dGhvbiBzb3VyY2UgZmlsZSB0byBkb2N1bWVudC4KCiVzIC1rIDxrZXl3b3JkPgogICAgU2VhcmNoIGZvciBhIGtleXdvcmQgaW4gdGhlIHN5bm9wc2lzIGxpbmVzIG9mIGFsbCBhdmFpbGFibGUgbW9kdWxlcy4KCiVzIC1wIDxwb3J0PgogICAgU3RhcnQgYW4gSFRUUCBzZXJ2ZXIgb24gdGhlIGdpdmVuIHBvcnQgb24gdGhlIGxvY2FsIG1hY2hpbmUuCgolcyAtZwogICAgUG9wIHVwIGEgZ3JhcGhpY2FsIGludGVyZmFjZSBmb3IgZmluZGluZyBhbmQgc2VydmluZyBkb2N1bWVudGF0aW9uLgoKJXMgLXcgPG5hbWU+IC4uLgogICAgV3JpdGUgb3V0IHRoZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGEgbW9kdWxlIHRvIGEgZmlsZSBpbiB0aGUgY3VycmVudAogICAgZGlyZWN0b3J5LiAgSWYgPG5hbWU+IGNvbnRhaW5zIGEgJyVzJywgaXQgaXMgdHJlYXRlZCBhcyBhIGZpbGVuYW1lOyBpZgogICAgaXQgbmFtZXMgYSBkaXJlY3RvcnksIGRvY3VtZW50YXRpb24gaXMgd3JpdHRlbiBmb3IgYWxsIHRoZSBjb250ZW50cy4KIiIiICUgKGNtZCwgb3Muc2VwLCBjbWQsIGNtZCwgY21kLCBjbWQsIG9zLnNlcCkKCmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6IGNsaSgpCg==