IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiIiIkdlbmVyYXRlIFB5dGhvbiBkb2N1bWVudGF0aW9uIGluIEhUTUwgb3IgdGV4dCBmb3IgaW50ZXJhY3RpdmUgdXNlLgoKSW4gdGhlIFB5dGhvbiBpbnRlcnByZXRlciwgZG8gImZyb20gcHlkb2MgaW1wb3J0IGhlbHAiIHRvIHByb3ZpZGUgb25saW5lCmhlbHAuICBDYWxsaW5nIGhlbHAodGhpbmcpIG9uIGEgUHl0aG9uIG9iamVjdCBkb2N1bWVudHMgdGhlIG9iamVjdC4KCk9yLCBhdCB0aGUgc2hlbGwgY29tbWFuZCBsaW5lIG91dHNpZGUgb2YgUHl0aG9uOgoKUnVuICJweWRvYyA8bmFtZT4iIHRvIHNob3cgZG9jdW1lbnRhdGlvbiBvbiBzb21ldGhpbmcuICA8bmFtZT4gbWF5IGJlCnRoZSBuYW1lIG9mIGEgZnVuY3Rpb24sIG1vZHVsZSwgcGFja2FnZSwgb3IgYSBkb3R0ZWQgcmVmZXJlbmNlIHRvIGEKY2xhc3Mgb3IgZnVuY3Rpb24gd2l0aGluIGEgbW9kdWxlIG9yIG1vZHVsZSBpbiBhIHBhY2thZ2UuICBJZiB0aGUKYXJndW1lbnQgY29udGFpbnMgYSBwYXRoIHNlZ21lbnQgZGVsaW1pdGVyIChlLmcuIHNsYXNoIG9uIFVuaXgsCmJhY2tzbGFzaCBvbiBXaW5kb3dzKSBpdCBpcyB0cmVhdGVkIGFzIHRoZSBwYXRoIHRvIGEgUHl0aG9uIHNvdXJjZSBmaWxlLgoKUnVuICJweWRvYyAtayA8a2V5d29yZD4iIHRvIHNlYXJjaCBmb3IgYSBrZXl3b3JkIGluIHRoZSBzeW5vcHNpcyBsaW5lcwpvZiBhbGwgYXZhaWxhYmxlIG1vZHVsZXMuCgpSdW4gInB5ZG9jIC1wIDxwb3J0PiIgdG8gc3RhcnQgYW4gSFRUUCBzZXJ2ZXIgb24gYSBnaXZlbiBwb3J0IG9uIHRoZQpsb2NhbCBtYWNoaW5lIHRvIGdlbmVyYXRlIGRvY3VtZW50YXRpb24gd2ViIHBhZ2VzLgoKRm9yIHBsYXRmb3JtcyB3aXRob3V0IGEgY29tbWFuZCBsaW5lLCAicHlkb2MgLWciIHN0YXJ0cyB0aGUgSFRUUCBzZXJ2ZXIKYW5kIGFsc28gcG9wcyB1cCBhIGxpdHRsZSB3aW5kb3cgZm9yIGNvbnRyb2xsaW5nIGl0LgoKUnVuICJweWRvYyAtdyA8bmFtZT4iIHRvIHdyaXRlIG91dCB0aGUgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIG1vZHVsZQp0byBhIGZpbGUgbmFtZWQgIjxuYW1lPi5odG1sIi4KIiIiCgpfX2F1dGhvcl9fID0gIkthLVBpbmcgWWVlIDxwaW5nQGxmdy5vcmc+IgpfX2RhdGVfXyA9ICIyNiBGZWJydWFyeSAyMDAxIgpfX3ZlcnNpb25fXyA9ICIkUmV2aXNpb24kIgpfX2NyZWRpdHNfXyA9ICIiIkd1aWRvIHZhbiBSb3NzdW0sIGZvciBhbiBleGNlbGxlbnQgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuClRvbW15IEJ1cm5ldHRlLCB0aGUgb3JpZ2luYWwgY3JlYXRvciBvZiBtYW5weS4KUGF1bCBQcmVzY29kLCBmb3IgYWxsIGhpcyB3b3JrIG9uIG9ubGluZWhlbHAuClJpY2hhcmQgQ2hhbWJlcmxhaW4sIGZvciB0aGUgZmlyc3QgaW1wbGVtZW50YXRpb24gb2YgdGV4dGRvYy4KCk15bmQgeW91LCBt+PhzZSBiaXRlcyBLYW4gYmUgcHJldHR5IG5hc3RpLi4uIiIiCgojIE5vdGU6IHRoaXMgbW9kdWxlIGlzIGRlc2lnbmVkIHRvIGRlcGxveSBpbnN0YW50bHkgYW5kIHJ1biB1bmRlciBhbnkKIyB2ZXJzaW9uIG9mIFB5dGhvbiBmcm9tIDEuNSBhbmQgdXAuICBUaGF0J3Mgd2h5IGl0J3MgYSBzaW5nbGUgZmlsZSBhbmQKIyBzb21lIDIuMCBmZWF0dXJlcyAobGlrZSBzdHJpbmcgbWV0aG9kcykgYXJlIGNvbnNwaWN1b3VzbHkgYWJzZW50LgoKIyBLbm93biBidWdzIHRoYXQgY2FuJ3QgYmUgZml4ZWQgaGVyZToKIyAgIC0gaW1wLmxvYWRfbW9kdWxlKCkgY2Fubm90IGJlIHByZXZlbnRlZCBmcm9tIGNsb2JiZXJpbmcgZXhpc3RpbmcKIyAgICAgbG9hZGVkIG1vZHVsZXMsIHNvIGNhbGxpbmcgc3lub3BzaXMoKSBvbiBhIGJpbmFyeSBtb2R1bGUgZmlsZQojICAgICBjaGFuZ2VzIHRoZSBjb250ZW50cyBvZiBhbnkgZXhpc3RpbmcgbW9kdWxlIHdpdGggdGhlIHNhbWUgbmFtZS4KIyAgIC0gSWYgdGhlIF9fZmlsZV9fIGF0dHJpYnV0ZSBvbiBhIG1vZHVsZSBpcyBhIHJlbGF0aXZlIHBhdGggYW5kCiMgICAgIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBpcyBjaGFuZ2VkIHdpdGggb3MuY2hkaXIoKSwgYW4gaW5jb3JyZWN0CiMgICAgIHBhdGggd2lsbCBiZSBkaXNwbGF5ZWQuCgppbXBvcnQgc3lzLCBpbXAsIG9zLCBzdGF0LCByZSwgdHlwZXMsIGluc3BlY3QKZnJvbSByZXByIGltcG9ydCBSZXByCmZyb20gc3RyaW5nIGltcG9ydCBleHBhbmR0YWJzLCBmaW5kLCBqb2luLCBsb3dlciwgc3BsaXQsIHN0cmlwLCByZmluZCwgcnN0cmlwCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBjb21tb24gcm91dGluZXMKCmRlZiBzeW5vcHNpcyhmaWxlbmFtZSwgY2FjaGU9e30pOgogICAgIiIiR2V0IHRoZSBvbmUtbGluZSBzdW1tYXJ5IG91dCBvZiBhIG1vZHVsZSBmaWxlLiIiIgogICAgbXRpbWUgPSBvcy5zdGF0KGZpbGVuYW1lKVtzdGF0LlNUX01USU1FXQogICAgbGFzdHVwZGF0ZSwgcmVzdWx0ID0gY2FjaGUuZ2V0KGZpbGVuYW1lLCAoMCwgTm9uZSkpCiAgICBpZiBsYXN0dXBkYXRlIDwgbXRpbWU6CiAgICAgICAgaW5mbyA9IGluc3BlY3QuZ2V0bW9kdWxlaW5mbyhmaWxlbmFtZSkKICAgICAgICBmaWxlID0gb3BlbihmaWxlbmFtZSkKICAgICAgICBpZiBpbmZvIGFuZCAnYicgaW4gaW5mb1syXTogIyBiaW5hcnkgbW9kdWxlcyBoYXZlIHRvIGJlIGltcG9ydGVkCiAgICAgICAgICAgIHRyeTogbW9kdWxlID0gaW1wLmxvYWRfbW9kdWxlKGluZm9bMF0sIGZpbGUsIGZpbGVuYW1lLCBpbmZvWzE6XSkKICAgICAgICAgICAgZXhjZXB0OiByZXR1cm4gTm9uZQogICAgICAgICAgICByZXN1bHQgPSBzcGxpdChtb2R1bGUuX19kb2NfXyBvciAnJywgJ1xuJylbMF0KICAgICAgICBlbHNlOiAjIHRleHQgbW9kdWxlcyBjYW4gYmUgZGlyZWN0bHkgZXhhbWluZWQKICAgICAgICAgICAgbGluZSA9IGZpbGUucmVhZGxpbmUoKQogICAgICAgICAgICB3aGlsZSBsaW5lWzoxXSA9PSAnIycgb3Igbm90IHN0cmlwKGxpbmUpOgogICAgICAgICAgICAgICAgbGluZSA9IGZpbGUucmVhZGxpbmUoKQogICAgICAgICAgICAgICAgaWYgbm90IGxpbmU6IGJyZWFrCiAgICAgICAgICAgIGxpbmUgPSBzdHJpcChsaW5lKQogICAgICAgICAgICBpZiBsaW5lWzo0XSA9PSAnciIiIic6IGxpbmUgPSBsaW5lWzE6XQogICAgICAgICAgICBpZiBsaW5lWzozXSA9PSAnIiIiJzoKICAgICAgICAgICAgICAgIGxpbmUgPSBsaW5lWzM6XQogICAgICAgICAgICAgICAgaWYgbGluZVstMTpdID09ICdcXCc6IGxpbmUgPSBsaW5lWzotMV0KICAgICAgICAgICAgICAgIHdoaWxlIG5vdCBzdHJpcChsaW5lKToKICAgICAgICAgICAgICAgICAgICBsaW5lID0gZmlsZS5yZWFkbGluZSgpCiAgICAgICAgICAgICAgICAgICAgaWYgbm90IGxpbmU6IGJyZWFrCiAgICAgICAgICAgICAgICByZXN1bHQgPSBzdHJpcChzcGxpdChsaW5lLCAnIiIiJylbMF0pCiAgICAgICAgICAgIGVsc2U6IHJlc3VsdCA9IE5vbmUKICAgICAgICBmaWxlLmNsb3NlKCkKICAgICAgICBjYWNoZVtmaWxlbmFtZV0gPSAobXRpbWUsIHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQKCmRlZiBwYXRoZGlycygpOgogICAgIiIiQ29udmVydCBzeXMucGF0aCBpbnRvIGEgbGlzdCBvZiBhYnNvbHV0ZSwgZXhpc3RpbmcsIHVuaXF1ZSBwYXRocy4iIiIKICAgIGRpcnMgPSBbXQogICAgbm9ybWRpcnMgPSBbXQogICAgZm9yIGRpciBpbiBzeXMucGF0aDoKICAgICAgICBkaXIgPSBvcy5wYXRoLmFic3BhdGgoZGlyIG9yICcuJykKICAgICAgICBub3JtZGlyID0gb3MucGF0aC5ub3JtY2FzZShkaXIpCiAgICAgICAgaWYgbm9ybWRpciBub3QgaW4gbm9ybWRpcnMgYW5kIG9zLnBhdGguaXNkaXIoZGlyKToKICAgICAgICAgICAgZGlycy5hcHBlbmQoZGlyKQogICAgICAgICAgICBub3JtZGlycy5hcHBlbmQobm9ybWRpcikKICAgIHJldHVybiBkaXJzCgpkZWYgZ2V0ZG9jKG9iamVjdCk6CiAgICAiIiJHZXQgdGhlIGRvYyBzdHJpbmcgb3IgY29tbWVudHMgZm9yIGFuIG9iamVjdC4iIiIKICAgIHJlc3VsdCA9IGluc3BlY3QuZ2V0ZG9jKG9iamVjdCkgb3IgaW5zcGVjdC5nZXRjb21tZW50cyhvYmplY3QpCiAgICByZXR1cm4gcmVzdWx0IGFuZCByZS5zdWIoJ14gKlxuJywgJycsIHJzdHJpcChyZXN1bHQpKSBvciAnJwoKZGVmIHNwbGl0ZG9jKGRvYyk6CiAgICAiIiJTcGxpdCBhIGRvYyBzdHJpbmcgaW50byBhIHN5bm9wc2lzIGxpbmUgKGlmIGFueSkgYW5kIHRoZSByZXN0LiIiIgogICAgbGluZXMgPSBzcGxpdChzdHJpcChkb2MpLCAnXG4nKQogICAgaWYgbGVuKGxpbmVzKSA9PSAxOgogICAgICAgIHJldHVybiBsaW5lc1swXSwgJycKICAgIGVsaWYgbGVuKGxpbmVzKSA+PSAyIGFuZCBub3QgcnN0cmlwKGxpbmVzWzFdKToKICAgICAgICByZXR1cm4gbGluZXNbMF0sIGpvaW4obGluZXNbMjpdLCAnXG4nKQogICAgcmV0dXJuICcnLCBqb2luKGxpbmVzLCAnXG4nKQoKZGVmIGNsYXNzbmFtZShvYmplY3QsIG1vZG5hbWUpOgogICAgIiIiR2V0IGEgY2xhc3MgbmFtZSBhbmQgcXVhbGlmeSBpdCB3aXRoIGEgbW9kdWxlIG5hbWUgaWYgbmVjZXNzYXJ5LiIiIgogICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgaWYgb2JqZWN0Ll9fbW9kdWxlX18gIT0gbW9kbmFtZToKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbW9kdWxlX18gKyAnLicgKyBuYW1lCiAgICByZXR1cm4gbmFtZQoKZGVmIGlzY29uc3RhbnQob2JqZWN0KToKICAgICIiIkNoZWNrIGlmIGFuIG9iamVjdCBpcyBvZiBhIHR5cGUgdGhhdCBwcm9iYWJseSBtZWFucyBpdCdzIGEgY29uc3RhbnQuIiIiCiAgICByZXR1cm4gdHlwZShvYmplY3QpIGluIFsKICAgICAgICB0eXBlcy5GbG9hdFR5cGUsIHR5cGVzLkludFR5cGUsIHR5cGVzLkxpc3RUeXBlLCB0eXBlcy5Mb25nVHlwZSwKICAgICAgICB0eXBlcy5TdHJpbmdUeXBlLCB0eXBlcy5UdXBsZVR5cGUsIHR5cGVzLlR5cGVUeXBlLAogICAgICAgIGhhc2F0dHIodHlwZXMsICdVbmljb2RlVHlwZScpIGFuZCB0eXBlcy5Vbmljb2RlVHlwZSBvciAwXQoKZGVmIHJlcGxhY2UodGV4dCwgKnBhaXJzKToKICAgICIiIkRvIGEgc2VyaWVzIG9mIGdsb2JhbCByZXBsYWNlbWVudHMgb24gYSBzdHJpbmcuIiIiCiAgICB3aGlsZSBwYWlyczoKICAgICAgICB0ZXh0ID0gam9pbihzcGxpdCh0ZXh0LCBwYWlyc1swXSksIHBhaXJzWzFdKQogICAgICAgIHBhaXJzID0gcGFpcnNbMjpdCiAgICByZXR1cm4gdGV4dAoKZGVmIGNyYW0odGV4dCwgbWF4bGVuKToKICAgICIiIk9taXQgcGFydCBvZiBhIHN0cmluZyBpZiBuZWVkZWQgdG8gbWFrZSBpdCBmaXQgaW4gYSBtYXhpbXVtIGxlbmd0aC4iIiIKICAgIGlmIGxlbih0ZXh0KSA+IG1heGxlbjoKICAgICAgICBwcmUgPSBtYXgoMCwgKG1heGxlbi0zKS8yKQogICAgICAgIHBvc3QgPSBtYXgoMCwgbWF4bGVuLTMtcHJlKQogICAgICAgIHJldHVybiB0ZXh0WzpwcmVdICsgJy4uLicgKyB0ZXh0W2xlbih0ZXh0KS1wb3N0Ol0KICAgIHJldHVybiB0ZXh0CgpkZWYgc3RyaXBpZCh0ZXh0KToKICAgICIiIlJlbW92ZSB0aGUgaGV4YWRlY2ltYWwgaWQgZnJvbSBhIFB5dGhvbiBvYmplY3QgcmVwcmVzZW50YXRpb24uIiIiCiAgICAjIFRoZSBiZWhhdmlvdXIgb2YgJXAgaXMgaW1wbGVtZW50YXRpb24tZGVwZW5kZW50OyB3ZSBjaGVjayB0d28gY2FzZXMuCiAgICBmb3IgcGF0dGVybiBpbiBbJyBhdCAweFswLTlhLWZdezYsfT4kJywgJyBhdCBbMC05QS1GXXs4LH0+JCddOgogICAgICAgIGlmIHJlLnNlYXJjaChwYXR0ZXJuLCByZXByKEV4Y2VwdGlvbikpOgogICAgICAgICAgICByZXR1cm4gcmUuc3ViKHBhdHRlcm4sICc+JywgdGV4dCkKICAgIHJldHVybiB0ZXh0CgpkZWYgYWxsbWV0aG9kcyhjbCk6CiAgICBtZXRob2RzID0ge30KICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhjbCwgaW5zcGVjdC5pc21ldGhvZCk6CiAgICAgICAgbWV0aG9kc1trZXldID0gMQogICAgZm9yIGJhc2UgaW4gY2wuX19iYXNlc19fOgogICAgICAgIG1ldGhvZHMudXBkYXRlKGFsbG1ldGhvZHMoYmFzZSkpICMgYWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVzCiAgICBmb3Iga2V5IGluIG1ldGhvZHMua2V5cygpOgogICAgICAgIG1ldGhvZHNba2V5XSA9IGdldGF0dHIoY2wsIGtleSkKICAgIHJldHVybiBtZXRob2RzCgpjbGFzcyBFcnJvckR1cmluZ0ltcG9ydChFeGNlcHRpb24pOgogICAgIiIiRXJyb3JzIHRoYXQgb2NjdXJyZWQgd2hpbGUgdHJ5aW5nIHRvIGltcG9ydCBzb21ldGhpbmcgdG8gZG9jdW1lbnQgaXQuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW5hbWUsIChleGMsIHZhbHVlLCB0YikpOgogICAgICAgIHNlbGYuZmlsZW5hbWUgPSBmaWxlbmFtZQogICAgICAgIHNlbGYuZXhjID0gZXhjCiAgICAgICAgc2VsZi52YWx1ZSA9IHZhbHVlCiAgICAgICAgc2VsZi50YiA9IHRiCgogICAgZGVmIF9fc3RyX18oc2VsZik6CiAgICAgICAgZXhjID0gc2VsZi5leGMKICAgICAgICBpZiB0eXBlKGV4YykgaXMgdHlwZXMuQ2xhc3NUeXBlOgogICAgICAgICAgICBleGMgPSBleGMuX19uYW1lX18KICAgICAgICByZXR1cm4gJ3Byb2JsZW0gaW4gJXMgLSAlczogJXMnICUgKHNlbGYuZmlsZW5hbWUsIGV4Yywgc2VsZi52YWx1ZSkKCmRlZiBpbXBvcnRmaWxlKHBhdGgpOgogICAgIiIiSW1wb3J0IGEgUHl0aG9uIHNvdXJjZSBmaWxlIG9yIGNvbXBpbGVkIGZpbGUgZ2l2ZW4gaXRzIHBhdGguIiIiCiAgICBtYWdpYyA9IGltcC5nZXRfbWFnaWMoKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgaWYgZmlsZS5yZWFkKGxlbihtYWdpYykpID09IG1hZ2ljOgogICAgICAgIGtpbmQgPSBpbXAuUFlfQ09NUElMRUQKICAgIGVsc2U6CiAgICAgICAga2luZCA9IGltcC5QWV9TT1VSQ0UKICAgIGZpbGUuY2xvc2UoKQogICAgZmlsZW5hbWUgPSBvcy5wYXRoLmJhc2VuYW1lKHBhdGgpCiAgICBuYW1lLCBleHQgPSBvcy5wYXRoLnNwbGl0ZXh0KGZpbGVuYW1lKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgdHJ5OgogICAgICAgIG1vZHVsZSA9IGltcC5sb2FkX21vZHVsZShuYW1lLCBmaWxlLCBwYXRoLCAoZXh0LCAncicsIGtpbmQpKQogICAgZXhjZXB0OgogICAgICAgIHJhaXNlIEVycm9yRHVyaW5nSW1wb3J0KHBhdGgsIHN5cy5leGNfaW5mbygpKQogICAgZmlsZS5jbG9zZSgpCiAgICByZXR1cm4gbW9kdWxlCgpkZWYgaXNwYWNrYWdlKHBhdGgpOgogICAgIiIiR3Vlc3Mgd2hldGhlciBhIHBhdGggcmVmZXJzIHRvIGEgcGFja2FnZSBkaXJlY3RvcnkuIiIiCiAgICBpZiBvcy5wYXRoLmlzZGlyKHBhdGgpOgogICAgICAgIGZvciBleHQgaW4gWycucHknLCAnLnB5YycsICcucHlvJ106CiAgICAgICAgICAgIGlmIG9zLnBhdGguaXNmaWxlKG9zLnBhdGguam9pbihwYXRoLCAnX19pbml0X18nICsgZXh0KSk6CiAgICAgICAgICAgICAgICByZXR1cm4gMQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGZvcm1hdHRlciBiYXNlIGNsYXNzCgpjbGFzcyBEb2M6CiAgICBkZWYgZG9jdW1lbnQoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsICphcmdzKToKICAgICAgICAiIiJHZW5lcmF0ZSBkb2N1bWVudGF0aW9uIGZvciBhbiBvYmplY3QuIiIiCiAgICAgICAgYXJncyA9IChvYmplY3QsIG5hbWUpICsgYXJncwogICAgICAgIGlmIGluc3BlY3QuaXNtb2R1bGUob2JqZWN0KTogcmV0dXJuIGFwcGx5KHNlbGYuZG9jbW9kdWxlLCBhcmdzKQogICAgICAgIGlmIGluc3BlY3QuaXNjbGFzcyhvYmplY3QpOiByZXR1cm4gYXBwbHkoc2VsZi5kb2NjbGFzcywgYXJncykKICAgICAgICBpZiBpbnNwZWN0Lmlzcm91dGluZShvYmplY3QpOiByZXR1cm4gYXBwbHkoc2VsZi5kb2Nyb3V0aW5lLCBhcmdzKQogICAgICAgIHJldHVybiBhcHBseShzZWxmLmRvY290aGVyLCBhcmdzKQoKICAgIGRlZiBmYWlsKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCAqYXJncyk6CiAgICAgICAgIiIiUmFpc2UgYW4gZXhjZXB0aW9uIGZvciB1bmltcGxlbWVudGVkIHR5cGVzLiIiIgogICAgICAgIG1lc3NhZ2UgPSAiZG9uJ3Qga25vdyBob3cgdG8gZG9jdW1lbnQgb2JqZWN0JXMgb2YgdHlwZSAlcyIgJSAoCiAgICAgICAgICAgIG5hbWUgYW5kICcgJyArIHJlcHIobmFtZSksIHR5cGUob2JqZWN0KS5fX25hbWVfXykKICAgICAgICByYWlzZSBUeXBlRXJyb3IsIG1lc3NhZ2UKCiAgICBkb2Ntb2R1bGUgPSBkb2NjbGFzcyA9IGRvY3JvdXRpbmUgPSBkb2NvdGhlciA9IGZhaWwKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSFRNTCBkb2N1bWVudGF0aW9uIGdlbmVyYXRvcgoKY2xhc3MgSFRNTFJlcHIoUmVwcik6CiAgICAiIiJDbGFzcyBmb3Igc2FmZWx5IG1ha2luZyBhbiBIVE1MIHJlcHJlc2VudGF0aW9uIG9mIGEgUHl0aG9uIG9iamVjdC4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBSZXByLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5tYXhsaXN0ID0gc2VsZi5tYXh0dXBsZSA9IHNlbGYubWF4ZGljdCA9IDEwCiAgICAgICAgc2VsZi5tYXhzdHJpbmcgPSBzZWxmLm1heG90aGVyID0gMTAwCgogICAgZGVmIGVzY2FwZShzZWxmLCB0ZXh0KToKICAgICAgICByZXR1cm4gcmVwbGFjZSh0ZXh0LCAnJicsICcmYW1wOycsICc8JywgJyZsdDsnLCAnPicsICcmZ3Q7JykKCiAgICBkZWYgcmVwcihzZWxmLCBvYmplY3QpOgogICAgICAgIHJldHVybiBSZXByLnJlcHIoc2VsZiwgb2JqZWN0KQoKICAgIGRlZiByZXByMShzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgbWV0aG9kbmFtZSA9ICdyZXByXycgKyBqb2luKHNwbGl0KHR5cGUoeCkuX19uYW1lX18pLCAnXycpCiAgICAgICAgaWYgaGFzYXR0cihzZWxmLCBtZXRob2RuYW1lKToKICAgICAgICAgICAgcmV0dXJuIGdldGF0dHIoc2VsZiwgbWV0aG9kbmFtZSkoeCwgbGV2ZWwpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZXNjYXBlKGNyYW0oc3RyaXBpZChyZXByKHgpKSwgc2VsZi5tYXhvdGhlcikpCgogICAgZGVmIHJlcHJfc3RyaW5nKHNlbGYsIHgsIGxldmVsKToKICAgICAgICB0ZXN0ID0gY3JhbSh4LCBzZWxmLm1heHN0cmluZykKICAgICAgICB0ZXN0cmVwciA9IHJlcHIodGVzdCkKICAgICAgICBpZiAnXFwnIGluIHRlc3QgYW5kICdcXCcgbm90IGluIHJlcGxhY2UodGVzdHJlcHIsIHInXFwnLCAnJyk6CiAgICAgICAgICAgICMgQmFja3NsYXNoZXMgYXJlIG9ubHkgbGl0ZXJhbCBpbiB0aGUgc3RyaW5nIGFuZCBhcmUgbmV2ZXIKICAgICAgICAgICAgIyBuZWVkZWQgdG8gbWFrZSBhbnkgc3BlY2lhbCBjaGFyYWN0ZXJzLCBzbyBzaG93IGEgcmF3IHN0cmluZy4KICAgICAgICAgICAgcmV0dXJuICdyJyArIHRlc3RyZXByWzBdICsgc2VsZi5lc2NhcGUodGVzdCkgKyB0ZXN0cmVwclswXQogICAgICAgIHJldHVybiByZS5zdWIocicoKFxcW1xcYWJmbnJ0dlwnIl18XFxbMC05XS4ufFxceC4ufFxcdS4uLi4pKyknLAogICAgICAgICAgICAgICAgICAgICAgcic8Zm9udCBjb2xvcj0iI2MwNDBjMCI+XDE8L2ZvbnQ+JywKICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZXNjYXBlKHRlc3RyZXByKSkKCiAgICBkZWYgcmVwcl9pbnN0YW5jZShzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXR1cm4gc2VsZi5lc2NhcGUoY3JhbShzdHJpcGlkKHJlcHIoeCkpLCBzZWxmLm1heHN0cmluZykpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICByZXR1cm4gc2VsZi5lc2NhcGUoJzwlcyBpbnN0YW5jZT4nICUgeC5fX2NsYXNzX18uX19uYW1lX18pCgogICAgcmVwcl91bmljb2RlID0gcmVwcl9zdHJpbmcKCmNsYXNzIEhUTUxEb2MoRG9jKToKICAgICIiIkZvcm1hdHRlciBjbGFzcyBmb3IgSFRNTCBkb2N1bWVudGF0aW9uLiIiIgoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBIVE1MIGZvcm1hdHRpbmcgdXRpbGl0aWVzCgogICAgX3JlcHJfaW5zdGFuY2UgPSBIVE1MUmVwcigpCiAgICByZXByID0gX3JlcHJfaW5zdGFuY2UucmVwcgogICAgZXNjYXBlID0gX3JlcHJfaW5zdGFuY2UuZXNjYXBlCgogICAgZGVmIHBhZ2Uoc2VsZiwgdGl0bGUsIGNvbnRlbnRzKToKICAgICAgICAiIiJGb3JtYXQgYW4gSFRNTCBwYWdlLiIiIgogICAgICAgIHJldHVybiAnJycKPCFkb2N0eXBlIGh0bWwgcHVibGljICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KPGh0bWw+PGhlYWQ+PHRpdGxlPlB5dGhvbjogJXM8L3RpdGxlPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPjwhLS0KVFQgeyBmb250LWZhbWlseTogbHVjaWRhIGNvbnNvbGUsIGx1Y2lkYSB0eXBld3JpdGVyLCBjb3VyaWVyIH0KLS0+PC9zdHlsZT48L2hlYWQ+PGJvZHkgYmdjb2xvcj0iI2YwZjBmOCI+CiVzCjwvYm9keT48L2h0bWw+JycnICUgKHRpdGxlLCBjb250ZW50cykKCiAgICBkZWYgaGVhZGluZyhzZWxmLCB0aXRsZSwgZmdjb2wsIGJnY29sLCBleHRyYXM9JycpOgogICAgICAgICIiIkZvcm1hdCBhIHBhZ2UgaGVhZGluZy4iIiIKICAgICAgICByZXR1cm4gJycnCjx0YWJsZSB3aWR0aD0iMTAwJSUiIGNlbGxzcGFjaW5nPTAgY2VsbHBhZGRpbmc9MiBib3JkZXI9MD4KPHRyIGJnY29sb3I9IiVzIj4KPHRkIHZhbGlnbj1ib3R0b20+PHNtYWxsPiZuYnNwOzxicj48L3NtYWxsCj48Zm9udCBjb2xvcj0iJXMiIGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPiZuYnNwOzxicj4lczwvZm9udD48L3RkCj48dGQgYWxpZ249cmlnaHQgdmFsaWduPWJvdHRvbQo+PGZvbnQgY29sb3I9IiVzIiBmYWNlPSJoZWx2ZXRpY2EsIGFyaWFsIj4lczwvZm9udD48L3RkPjwvdHI+PC90YWJsZT4KICAgICcnJyAlIChiZ2NvbCwgZmdjb2wsIHRpdGxlLCBmZ2NvbCwgZXh0cmFzIG9yICcmbmJzcDsnKQoKICAgIGRlZiBzZWN0aW9uKHNlbGYsIHRpdGxlLCBmZ2NvbCwgYmdjb2wsIGNvbnRlbnRzLCB3aWR0aD0xMCwKICAgICAgICAgICAgICAgIHByZWx1ZGU9JycsIG1hcmdpbmFsaWE9Tm9uZSwgZ2FwPScmbmJzcDsmbmJzcDsnKToKICAgICAgICAiIiJGb3JtYXQgYSBzZWN0aW9uIHdpdGggYSBoZWFkaW5nLiIiIgogICAgICAgIGlmIG1hcmdpbmFsaWEgaXMgTm9uZToKICAgICAgICAgICAgbWFyZ2luYWxpYSA9ICc8dHQ+JyArICcmbmJzcDsnICogd2lkdGggKyAnPC90dD4nCiAgICAgICAgcmVzdWx0ID0gJycnCjxwPjx0YWJsZSB3aWR0aD0iMTAwJSUiIGNlbGxzcGFjaW5nPTAgY2VsbHBhZGRpbmc9MiBib3JkZXI9MD4KPHRyIGJnY29sb3I9IiVzIj4KPHRkIGNvbHNwYW49MyB2YWxpZ249Ym90dG9tPjxzbWFsbD48c21hbGw+Jm5ic3A7PGJyPjwvc21hbGw+PC9zbWFsbAo+PGZvbnQgY29sb3I9IiVzIiBmYWNlPSJoZWx2ZXRpY2EsIGFyaWFsIj4lczwvZm9udD48L3RkPjwvdHI+CiAgICAnJycgJSAoYmdjb2wsIGZnY29sLCB0aXRsZSkKICAgICAgICBpZiBwcmVsdWRlOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnJycKPHRyIGJnY29sb3I9IiVzIj48dGQgcm93c3Bhbj0yPiVzPC90ZD4KPHRkIGNvbHNwYW49Mj4lczwvdGQ+PC90cj4KPHRyPjx0ZD4lczwvdGQ+JycnICUgKGJnY29sLCBtYXJnaW5hbGlhLCBwcmVsdWRlLCBnYXApCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJycnCjx0cj48dGQgYmdjb2xvcj0iJXMiPiVzPC90ZD48dGQ+JXM8L3RkPicnJyAlIChiZ2NvbCwgbWFyZ2luYWxpYSwgZ2FwKQoKICAgICAgICByZXR1cm4gcmVzdWx0ICsgJ1xuPHRkIHdpZHRoPSIxMDAlJSI+JXM8L3RkPjwvdHI+PC90YWJsZT4nICUgY29udGVudHMKCiAgICBkZWYgYmlnc2VjdGlvbihzZWxmLCB0aXRsZSwgKmFyZ3MpOgogICAgICAgICIiIkZvcm1hdCBhIHNlY3Rpb24gd2l0aCBhIGJpZyBoZWFkaW5nLiIiIgogICAgICAgIHRpdGxlID0gJzxiaWc+PHN0cm9uZz4lczwvc3Ryb25nPjwvYmlnPicgJSB0aXRsZQogICAgICAgIHJldHVybiBhcHBseShzZWxmLnNlY3Rpb24sICh0aXRsZSwpICsgYXJncykKCiAgICBkZWYgcHJlZm9ybWF0KHNlbGYsIHRleHQpOgogICAgICAgICIiIkZvcm1hdCBsaXRlcmFsIHByZWZvcm1hdHRlZCB0ZXh0LiIiIgogICAgICAgIHRleHQgPSBzZWxmLmVzY2FwZShleHBhbmR0YWJzKHRleHQpKQogICAgICAgIHJldHVybiByZXBsYWNlKHRleHQsICdcblxuJywgJ1xuIFxuJywgJ1xuXG4nLCAnXG4gXG4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgJywgJyZuYnNwOycsICdcbicsICc8YnI+XG4nKQoKICAgIGRlZiBtdWx0aWNvbHVtbihzZWxmLCBsaXN0LCBmb3JtYXQsIGNvbHM9NCk6CiAgICAgICAgIiIiRm9ybWF0IGEgbGlzdCBvZiBpdGVtcyBpbnRvIGEgbXVsdGktY29sdW1uIGxpc3QuIiIiCiAgICAgICAgcmVzdWx0ID0gJycKICAgICAgICByb3dzID0gKGxlbihsaXN0KStjb2xzLTEpL2NvbHMKICAgICAgICBmb3IgY29sIGluIHJhbmdlKGNvbHMpOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPHRkIHdpZHRoPSIlZCUlIiB2YWxpZ249dG9wPicgJSAoMTAwL2NvbHMpCiAgICAgICAgICAgIGZvciBpIGluIHJhbmdlKHJvd3MqY29sLCByb3dzKmNvbCtyb3dzKToKICAgICAgICAgICAgICAgIGlmIGkgPCBsZW4obGlzdCk6CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgZm9ybWF0KGxpc3RbaV0pICsgJzxicj5cbicKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJzwvdGQ+JwogICAgICAgIHJldHVybiAnPHRhYmxlIHdpZHRoPSIxMDAlJSI+PHRyPiVzPC90cj48L3RhYmxlPicgJSByZXN1bHQKCiAgICBkZWYgc21hbGwoc2VsZiwgdGV4dCk6IHJldHVybiAnPHNtYWxsPiVzPC9zbWFsbD4nICUgdGV4dAogICAgZGVmIGdyZXkoc2VsZiwgdGV4dCk6IHJldHVybiAnPGZvbnQgY29sb3I9IiM5MDkwOTAiPiVzPC9mb250PicgJSB0ZXh0CgogICAgZGVmIG5hbWVsaW5rKHNlbGYsIG5hbWUsICpkaWN0cyk6CiAgICAgICAgIiIiTWFrZSBhIGxpbmsgZm9yIGFuIGlkZW50aWZpZXIsIGdpdmVuIG5hbWUtdG8tVVJMIG1hcHBpbmdzLiIiIgogICAgICAgIGZvciBkaWN0IGluIGRpY3RzOgogICAgICAgICAgICBpZiBkaWN0Lmhhc19rZXkobmFtZSk6CiAgICAgICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKGRpY3RbbmFtZV0sIG5hbWUpCiAgICAgICAgcmV0dXJuIG5hbWUKCiAgICBkZWYgY2xhc3NsaW5rKHNlbGYsIG9iamVjdCwgbW9kbmFtZSk6CiAgICAgICAgIiIiTWFrZSBhIGxpbmsgZm9yIGEgY2xhc3MuIiIiCiAgICAgICAgbmFtZSA9IGNsYXNzbmFtZShvYmplY3QsIG1vZG5hbWUpCiAgICAgICAgaWYgc3lzLm1vZHVsZXMuaGFzX2tleShvYmplY3QuX19tb2R1bGVfXykgYW5kIFwKICAgICAgICAgICAgZ2V0YXR0cihzeXMubW9kdWxlc1tvYmplY3QuX19tb2R1bGVfX10sIG9iamVjdC5fX25hbWVfXykgaXMgb2JqZWN0OgogICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzLmh0bWwjJXMiPiVzPC9hPicgJSAoCiAgICAgICAgICAgICAgICBvYmplY3QuX19tb2R1bGVfXywgb2JqZWN0Ll9fbmFtZV9fLCBuYW1lKQogICAgICAgIHJldHVybiBuYW1lCgogICAgZGVmIG1vZHVsZWxpbmsoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJNYWtlIGEgbGluayBmb3IgYSBtb2R1bGUuIiIiCiAgICAgICAgcmV0dXJuICc8YSBocmVmPSIlcy5odG1sIj4lczwvYT4nICUgKG9iamVjdC5fX25hbWVfXywgb2JqZWN0Ll9fbmFtZV9fKQoKICAgIGRlZiBtb2Rwa2dsaW5rKHNlbGYsIChuYW1lLCBwYXRoLCBpc3BhY2thZ2UsIHNoYWRvd2VkKSk6CiAgICAgICAgIiIiTWFrZSBhIGxpbmsgZm9yIGEgbW9kdWxlIG9yIHBhY2thZ2UgdG8gZGlzcGxheSBpbiBhbiBpbmRleC4iIiIKICAgICAgICBpZiBzaGFkb3dlZDoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZ3JleShuYW1lKQogICAgICAgIGlmIHBhdGg6CiAgICAgICAgICAgIHVybCA9ICclcy4lcy5odG1sJyAlIChwYXRoLCBuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHVybCA9ICclcy5odG1sJyAlIG5hbWUKICAgICAgICBpZiBpc3BhY2thZ2U6CiAgICAgICAgICAgIHRleHQgPSAnPHN0cm9uZz4lczwvc3Ryb25nPiZuYnNwOyhwYWNrYWdlKScgJSBuYW1lCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGV4dCA9IG5hbWUKICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKHVybCwgdGV4dCkKCiAgICBkZWYgbWFya3VwKHNlbGYsIHRleHQsIGVzY2FwZT1Ob25lLCBmdW5jcz17fSwgY2xhc3Nlcz17fSwgbWV0aG9kcz17fSk6CiAgICAgICAgIiIiTWFyayB1cCBzb21lIHBsYWluIHRleHQsIGdpdmVuIGEgY29udGV4dCBvZiBzeW1ib2xzIHRvIGxvb2sgZm9yLgogICAgICAgIEVhY2ggY29udGV4dCBkaWN0aW9uYXJ5IG1hcHMgb2JqZWN0IG5hbWVzIHRvIGFuY2hvciBuYW1lcy4iIiIKICAgICAgICBlc2NhcGUgPSBlc2NhcGUgb3Igc2VsZi5lc2NhcGUKICAgICAgICByZXN1bHRzID0gW10KICAgICAgICBoZXJlID0gMAogICAgICAgIHBhdHRlcm4gPSByZS5jb21waWxlKHInXGIoKGh0dHB8ZnRwKTovL1xTK1tcdy9dfCcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByJ1JGQ1stIF0/KFxkKyl8JwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHInUEVQWy0gXT8oXGQrKXwnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcicoc2VsZlwuKT8oXHcrKSlcYicpCiAgICAgICAgd2hpbGUgMToKICAgICAgICAgICAgbWF0Y2ggPSBwYXR0ZXJuLnNlYXJjaCh0ZXh0LCBoZXJlKQogICAgICAgICAgICBpZiBub3QgbWF0Y2g6IGJyZWFrCiAgICAgICAgICAgIHN0YXJ0LCBlbmQgPSBtYXRjaC5zcGFuKCkKICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoZXNjYXBlKHRleHRbaGVyZTpzdGFydF0pKQoKICAgICAgICAgICAgYWxsLCBzY2hlbWUsIHJmYywgcGVwLCBzZWxmZG90LCBuYW1lID0gbWF0Y2guZ3JvdXBzKCkKICAgICAgICAgICAgaWYgc2NoZW1lOgogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKGFsbCwgZXNjYXBlKGFsbCkpKQogICAgICAgICAgICBlbGlmIHJmYzoKICAgICAgICAgICAgICAgIHVybCA9ICdodHRwOi8vd3d3LnJmYy1lZGl0b3Iub3JnL3JmYy9yZmMlZC50eHQnICUgaW50KHJmYykKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCc8YSBocmVmPSIlcyI+JXM8L2E+JyAlICh1cmwsIGVzY2FwZShhbGwpKSkKICAgICAgICAgICAgZWxpZiBwZXA6CiAgICAgICAgICAgICAgICB1cmwgPSAnaHR0cDovL3d3dy5weXRob24ub3JnL3BlcHMvcGVwLSUwNGQuaHRtbCcgJSBpbnQocGVwKQogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKHVybCwgZXNjYXBlKGFsbCkpKQogICAgICAgICAgICBlbGlmIHRleHRbZW5kOmVuZCsxXSA9PSAnKCc6CiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZChzZWxmLm5hbWVsaW5rKG5hbWUsIG1ldGhvZHMsIGZ1bmNzLCBjbGFzc2VzKSkKICAgICAgICAgICAgZWxpZiBzZWxmZG90OgogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJ3NlbGYuPHN0cm9uZz4lczwvc3Ryb25nPicgJSBuYW1lKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoc2VsZi5uYW1lbGluayhuYW1lLCBjbGFzc2VzKSkKICAgICAgICAgICAgaGVyZSA9IGVuZAogICAgICAgIHJlc3VsdHMuYXBwZW5kKGVzY2FwZSh0ZXh0W2hlcmU6XSkpCiAgICAgICAgcmV0dXJuIGpvaW4ocmVzdWx0cywgJycpCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHR5cGUtc3BlY2lmaWMgcm91dGluZXMKCiAgICBkZWYgZm9ybWF0dHJlZShzZWxmLCB0cmVlLCBtb2RuYW1lLCBwYXJlbnQ9Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGZvciBhIGNsYXNzIHRyZWUgYXMgZ2l2ZW4gYnkgaW5zcGVjdC5nZXRjbGFzc3RyZWUoKS4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIGZvciBlbnRyeSBpbiB0cmVlOgogICAgICAgICAgICBpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKCgpKToKICAgICAgICAgICAgICAgIGMsIGJhc2VzID0gZW50cnkKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8ZHQ+PGZvbnQgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+PHNtYWxsPicKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuY2xhc3NsaW5rKGMsIG1vZG5hbWUpCiAgICAgICAgICAgICAgICBpZiBiYXNlcyBhbmQgYmFzZXMgIT0gKHBhcmVudCwpOgogICAgICAgICAgICAgICAgICAgIHBhcmVudHMgPSBbXQogICAgICAgICAgICAgICAgICAgIGZvciBiYXNlIGluIGJhc2VzOgogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRzLmFwcGVuZChzZWxmLmNsYXNzbGluayhiYXNlLCBtb2RuYW1lKSkKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnKCcgKyBqb2luKHBhcmVudHMsICcsICcpICsgJyknCiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnXG48L3NtYWxsPjwvZm9udD48L2R0PicKICAgICAgICAgICAgZWxpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKFtdKToKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8ZGQ+XG4lczwvZGQ+XG4nICUgc2VsZi5mb3JtYXR0cmVlKAogICAgICAgICAgICAgICAgICAgIGVudHJ5LCBtb2RuYW1lLCBjKQogICAgICAgIHJldHVybiAnPGRsPlxuJXM8L2RsPlxuJyAlIHJlc3VsdAoKICAgIGRlZiBkb2Ntb2R1bGUoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBtb2R1bGUgb2JqZWN0LiIiIgogICAgICAgIG5hbWUgPSBvYmplY3QuX19uYW1lX18gIyBpZ25vcmUgdGhlIHBhc3NlZC1pbiBuYW1lCiAgICAgICAgcGFydHMgPSBzcGxpdChuYW1lLCAnLicpCiAgICAgICAgbGlua3MgPSBbXQogICAgICAgIGZvciBpIGluIHJhbmdlKGxlbihwYXJ0cyktMSk6CiAgICAgICAgICAgIGxpbmtzLmFwcGVuZCgKICAgICAgICAgICAgICAgICc8YSBocmVmPSIlcy5odG1sIj48Zm9udCBjb2xvcj0iI2ZmZmZmZiI+JXM8L2ZvbnQ+PC9hPicgJQogICAgICAgICAgICAgICAgKGpvaW4ocGFydHNbOmkrMV0sICcuJyksIHBhcnRzW2ldKSkKICAgICAgICBsaW5rZWRuYW1lID0gam9pbihsaW5rcyArIHBhcnRzWy0xOl0sICcuJykKICAgICAgICBoZWFkID0gJzxiaWc+PGJpZz48c3Ryb25nPiVzPC9zdHJvbmc+PC9iaWc+PC9iaWc+JyAlIGxpbmtlZG5hbWUKICAgICAgICB0cnk6CiAgICAgICAgICAgIHBhdGggPSBpbnNwZWN0LmdldGFic2ZpbGUob2JqZWN0KQogICAgICAgICAgICBmaWxlbGluayA9ICc8YSBocmVmPSJmaWxlOiVzIj4lczwvYT4nICUgKHBhdGgsIHBhdGgpCiAgICAgICAgZXhjZXB0IFR5cGVFcnJvcjoKICAgICAgICAgICAgZmlsZWxpbmsgPSAnKGJ1aWx0LWluKScKICAgICAgICBpbmZvID0gW10KICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fdmVyc2lvbl9fJyk6CiAgICAgICAgICAgIHZlcnNpb24gPSBzdHIob2JqZWN0Ll9fdmVyc2lvbl9fKQogICAgICAgICAgICBpZiB2ZXJzaW9uWzoxMV0gPT0gJyQnICsgJ1JldmlzaW9uOiAnIGFuZCB2ZXJzaW9uWy0xOl0gPT0gJyQnOgogICAgICAgICAgICAgICAgdmVyc2lvbiA9IHN0cmlwKHZlcnNpb25bMTE6LTFdKQogICAgICAgICAgICBpbmZvLmFwcGVuZCgndmVyc2lvbiAlcycgJSBzZWxmLmVzY2FwZSh2ZXJzaW9uKSkKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fZGF0ZV9fJyk6CiAgICAgICAgICAgIGluZm8uYXBwZW5kKHNlbGYuZXNjYXBlKHN0cihvYmplY3QuX19kYXRlX18pKSkKICAgICAgICBpZiBpbmZvOgogICAgICAgICAgICBoZWFkID0gaGVhZCArICcgKCVzKScgJSBqb2luKGluZm8sICcsICcpCiAgICAgICAgcmVzdWx0ID0gc2VsZi5oZWFkaW5nKAogICAgICAgICAgICBoZWFkLCAnI2ZmZmZmZicsICcjNzc5OWVlJywgJzxhIGhyZWY9Ii4iPmluZGV4PC9hPjxicj4nICsgZmlsZWxpbmspCgogICAgICAgIG1vZHVsZXMgPSBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0LmlzbW9kdWxlKQoKICAgICAgICBjbGFzc2VzLCBjZGljdCA9IFtdLCB7fQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNjbGFzcyk6CiAgICAgICAgICAgIGlmIChpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgb3Igb2JqZWN0KSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBjbGFzc2VzLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCiAgICAgICAgICAgICAgICBjZGljdFtrZXldID0gY2RpY3RbdmFsdWVdID0gJyMnICsga2V5CiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gY2xhc3NlczoKICAgICAgICAgICAgZm9yIGJhc2UgaW4gdmFsdWUuX19iYXNlc19fOgogICAgICAgICAgICAgICAga2V5LCBtb2RuYW1lID0gYmFzZS5fX25hbWVfXywgYmFzZS5fX21vZHVsZV9fCiAgICAgICAgICAgICAgICBtb2R1bGUgPSBzeXMubW9kdWxlcy5nZXQobW9kbmFtZSkKICAgICAgICAgICAgICAgIGlmIG1vZG5hbWUgIT0gbmFtZSBhbmQgbW9kdWxlIGFuZCBoYXNhdHRyKG1vZHVsZSwga2V5KToKICAgICAgICAgICAgICAgICAgICBpZiBnZXRhdHRyKG1vZHVsZSwga2V5KSBpcyBiYXNlOgogICAgICAgICAgICAgICAgICAgICAgICBpZiBub3QgY2RpY3QuaGFzX2tleShrZXkpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2RpY3Rba2V5XSA9IGNkaWN0W2Jhc2VdID0gbW9kbmFtZSArICcuaHRtbCMnICsga2V5CiAgICAgICAgZnVuY3MsIGZkaWN0ID0gW10sIHt9CiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc3JvdXRpbmUpOgogICAgICAgICAgICBpZiBpbnNwZWN0LmlzYnVpbHRpbih2YWx1ZSkgb3IgaW5zcGVjdC5nZXRtb2R1bGUodmFsdWUpIGlzIG9iamVjdDoKICAgICAgICAgICAgICAgIGZ1bmNzLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCiAgICAgICAgICAgICAgICBmZGljdFtrZXldID0gJyMtJyArIGtleQogICAgICAgICAgICAgICAgaWYgaW5zcGVjdC5pc2Z1bmN0aW9uKHZhbHVlKTogZmRpY3RbdmFsdWVdID0gZmRpY3Rba2V5XQogICAgICAgIGNvbnN0YW50cyA9IFtdCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaXNjb25zdGFudCk6CiAgICAgICAgICAgIGNvbnN0YW50cy5hcHBlbmQoKGtleSwgdmFsdWUpKQoKICAgICAgICBkb2MgPSBzZWxmLm1hcmt1cChnZXRkb2Mob2JqZWN0KSwgc2VsZi5wcmVmb3JtYXQsIGZkaWN0LCBjZGljdCkKICAgICAgICBkb2MgPSBkb2MgYW5kICc8dHQ+JXM8L3R0PicgJSBkb2MKICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPHA+JXM8L3A+XG4nICUgc2VsZi5zbWFsbChkb2MpCgogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19wYXRoX18nKToKICAgICAgICAgICAgbW9kcGtncyA9IFtdCiAgICAgICAgICAgIG1vZG5hbWVzID0gW10KICAgICAgICAgICAgZm9yIGZpbGUgaW4gb3MubGlzdGRpcihvYmplY3QuX19wYXRoX19bMF0pOgogICAgICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihvYmplY3QuX19wYXRoX19bMF0sIGZpbGUpCiAgICAgICAgICAgICAgICBtb2RuYW1lID0gaW5zcGVjdC5nZXRtb2R1bGVuYW1lKGZpbGUpCiAgICAgICAgICAgICAgICBpZiBtb2RuYW1lIGFuZCBtb2RuYW1lIG5vdCBpbiBtb2RuYW1lczoKICAgICAgICAgICAgICAgICAgICBtb2Rwa2dzLmFwcGVuZCgobW9kbmFtZSwgbmFtZSwgMCwgMCkpCiAgICAgICAgICAgICAgICAgICAgbW9kbmFtZXMuYXBwZW5kKG1vZG5hbWUpCiAgICAgICAgICAgICAgICBlbGlmIGlzcGFja2FnZShwYXRoKToKICAgICAgICAgICAgICAgICAgICBtb2Rwa2dzLmFwcGVuZCgoZmlsZSwgbmFtZSwgMSwgMCkpCiAgICAgICAgICAgIG1vZHBrZ3Muc29ydCgpCiAgICAgICAgICAgIGNvbnRlbnRzID0gc2VsZi5tdWx0aWNvbHVtbihtb2Rwa2dzLCBzZWxmLm1vZHBrZ2xpbmspCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdQYWNrYWdlIENvbnRlbnRzJywgJyNmZmZmZmYnLCAnI2FhNTVjYycsIGNvbnRlbnRzKQogICAgICAgIGVsaWYgbW9kdWxlczoKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm11bHRpY29sdW1uKAogICAgICAgICAgICAgICAgbW9kdWxlcywgbGFtYmRhIChrZXksIHZhbHVlKSwgcz1zZWxmOiBzLm1vZHVsZWxpbmsodmFsdWUpKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnTW9kdWxlcycsICcjZmZmZmYnLCAnI2FhNTVjYycsIGNvbnRlbnRzKQoKICAgICAgICBpZiBjbGFzc2VzOgogICAgICAgICAgICBjbGFzc2xpc3QgPSBtYXAobGFtYmRhIChrZXksIHZhbHVlKTogdmFsdWUsIGNsYXNzZXMpCiAgICAgICAgICAgIGNvbnRlbnRzID0gWwogICAgICAgICAgICAgICAgc2VsZi5mb3JtYXR0cmVlKGluc3BlY3QuZ2V0Y2xhc3N0cmVlKGNsYXNzbGlzdCwgMSksIG5hbWUpXQogICAgICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBjbGFzc2VzOgogICAgICAgICAgICAgICAgY29udGVudHMuYXBwZW5kKHNlbGYuZG9jdW1lbnQodmFsdWUsIGtleSwgbmFtZSwgZmRpY3QsIGNkaWN0KSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0NsYXNzZXMnLCAnI2ZmZmZmZicsICcjZWU3N2FhJywgam9pbihjb250ZW50cykpCiAgICAgICAgaWYgZnVuY3M6CiAgICAgICAgICAgIGNvbnRlbnRzID0gW10KICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gZnVuY3M6CiAgICAgICAgICAgICAgICBjb250ZW50cy5hcHBlbmQoc2VsZi5kb2N1bWVudCh2YWx1ZSwga2V5LCBuYW1lLCBmZGljdCwgY2RpY3QpKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnRnVuY3Rpb25zJywgJyNmZmZmZmYnLCAnI2VlYWE3NycsIGpvaW4oY29udGVudHMpKQogICAgICAgIGlmIGNvbnN0YW50czoKICAgICAgICAgICAgY29udGVudHMgPSBbXQogICAgICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBjb25zdGFudHM6CiAgICAgICAgICAgICAgICBjb250ZW50cy5hcHBlbmQoc2VsZi5kb2N1bWVudCh2YWx1ZSwga2V5KSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0NvbnN0YW50cycsICcjZmZmZmZmJywgJyM1NWFhNTUnLCBqb2luKGNvbnRlbnRzLCAnPGJyPicpKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19hdXRob3JfXycpOgogICAgICAgICAgICBjb250ZW50cyA9IHNlbGYubWFya3VwKHN0cihvYmplY3QuX19hdXRob3JfXyksIHNlbGYucHJlZm9ybWF0KQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnQXV0aG9yJywgJyNmZmZmZmYnLCAnIzc3OTllZScsIGNvbnRlbnRzKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19jcmVkaXRzX18nKToKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm1hcmt1cChzdHIob2JqZWN0Ll9fY3JlZGl0c19fKSwgc2VsZi5wcmVmb3JtYXQpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdDcmVkaXRzJywgJyNmZmZmZmYnLCAnIzc3OTllZScsIGNvbnRlbnRzKQoKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIGRvY2NsYXNzKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCBtb2Q9Tm9uZSwgZnVuY3M9e30sIGNsYXNzZXM9e30pOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIGNsYXNzIG9iamVjdC4iIiIKICAgICAgICByZWFsbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIG5hbWUgPSBuYW1lIG9yIHJlYWxuYW1lCiAgICAgICAgYmFzZXMgPSBvYmplY3QuX19iYXNlc19fCiAgICAgICAgY29udGVudHMgPSAnJwoKICAgICAgICBtZXRob2RzLCBtZGljdCA9IGFsbG1ldGhvZHMob2JqZWN0KS5pdGVtcygpLCB7fQogICAgICAgIG1ldGhvZHMuc29ydCgpCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gbWV0aG9kczoKICAgICAgICAgICAgbWRpY3Rba2V5XSA9IG1kaWN0W3ZhbHVlXSA9ICcjJyArIG5hbWUgKyAnLScgKyBrZXkKICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBtZXRob2RzOgogICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgc2VsZi5kb2N1bWVudCgKICAgICAgICAgICAgICAgIHZhbHVlLCBrZXksIG1vZCwgZnVuY3MsIGNsYXNzZXMsIG1kaWN0LCBvYmplY3QpCgogICAgICAgIGlmIG5hbWUgPT0gcmVhbG5hbWU6CiAgICAgICAgICAgIHRpdGxlID0gJzxhIG5hbWU9IiVzIj5jbGFzcyA8c3Ryb25nPiVzPC9zdHJvbmc+PC9hPicgJSAoCiAgICAgICAgICAgICAgICBuYW1lLCByZWFsbmFtZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICB0aXRsZSA9ICc8c3Ryb25nPiVzPC9zdHJvbmc+ID0gPGEgbmFtZT0iJXMiPmNsYXNzICVzPC9hPicgJSAoCiAgICAgICAgICAgICAgICBuYW1lLCBuYW1lLCByZWFsbmFtZSkKICAgICAgICBpZiBiYXNlczoKICAgICAgICAgICAgcGFyZW50cyA9IFtdCiAgICAgICAgICAgIGZvciBiYXNlIGluIGJhc2VzOgogICAgICAgICAgICAgICAgcGFyZW50cy5hcHBlbmQoc2VsZi5jbGFzc2xpbmsoYmFzZSwgb2JqZWN0Ll9fbW9kdWxlX18pKQogICAgICAgICAgICB0aXRsZSA9IHRpdGxlICsgJyglcyknICUgam9pbihwYXJlbnRzLCAnLCAnKQogICAgICAgIGRvYyA9IHNlbGYubWFya3VwKAogICAgICAgICAgICBnZXRkb2Mob2JqZWN0KSwgc2VsZi5wcmVmb3JtYXQsIGZ1bmNzLCBjbGFzc2VzLCBtZGljdCkKICAgICAgICBkb2MgPSBzZWxmLnNtYWxsKGRvYyBhbmQgJzx0dD4lczxicj4mbmJzcDs8L3R0PicgJSBkb2Mgb3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zbWFsbCgnJm5ic3A7JykpCiAgICAgICAgcmV0dXJuIHNlbGYuc2VjdGlvbih0aXRsZSwgJyMwMDAwMDAnLCAnI2ZmYzhkOCcsIGNvbnRlbnRzLCA1LCBkb2MpCgogICAgZGVmIGZvcm1hdHZhbHVlKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiRm9ybWF0IGFuIGFyZ3VtZW50IGRlZmF1bHQgdmFsdWUgYXMgdGV4dC4iIiIKICAgICAgICByZXR1cm4gc2VsZi5zbWFsbChzZWxmLmdyZXkoJz0nICsgc2VsZi5yZXByKG9iamVjdCkpKQoKICAgIGRlZiBkb2Nyb3V0aW5lKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCBtb2Q9Tm9uZSwKICAgICAgICAgICAgICAgICAgIGZ1bmNzPXt9LCBjbGFzc2VzPXt9LCBtZXRob2RzPXt9LCBjbD1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBmdW5jdGlvbiBvciBtZXRob2Qgb2JqZWN0LiIiIgogICAgICAgIHJlYWxuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgbmFtZSA9IG5hbWUgb3IgcmVhbG5hbWUKICAgICAgICBhbmNob3IgPSAoY2wgYW5kIGNsLl9fbmFtZV9fIG9yICcnKSArICctJyArIG5hbWUKICAgICAgICBub3RlID0gJycKICAgICAgICBza2lwZG9jcyA9IDAKICAgICAgICBpZiBpbnNwZWN0LmlzbWV0aG9kKG9iamVjdCk6CiAgICAgICAgICAgIGltY2xhc3MgPSBvYmplY3QuaW1fY2xhc3MKICAgICAgICAgICAgaWYgY2w6CiAgICAgICAgICAgICAgICBpZiBpbWNsYXNzIGlzIG5vdCBjbDoKICAgICAgICAgICAgICAgICAgICBub3RlID0gJyBmcm9tICcgKyBzZWxmLmNsYXNzbGluayhpbWNsYXNzLCBtb2QpCiAgICAgICAgICAgICAgICAgICAgc2tpcGRvY3MgPSAxCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBpZiBvYmplY3QuaW1fc2VsZjoKICAgICAgICAgICAgICAgICAgICBub3RlID0gJyBtZXRob2Qgb2YgJXMgaW5zdGFuY2UnICUgc2VsZi5jbGFzc2xpbmsoCiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5pbV9zZWxmLl9fY2xhc3NfXywgbW9kKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBub3RlID0gJyB1bmJvdW5kICVzIG1ldGhvZCcgJSBzZWxmLmNsYXNzbGluayhpbWNsYXNzLG1vZCkKICAgICAgICAgICAgb2JqZWN0ID0gb2JqZWN0LmltX2Z1bmMKCiAgICAgICAgaWYgbmFtZSA9PSByZWFsbmFtZToKICAgICAgICAgICAgdGl0bGUgPSAnPGEgbmFtZT0iJXMiPjxzdHJvbmc+JXM8L3N0cm9uZz48L2E+JyAlIChhbmNob3IsIHJlYWxuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIChjbCBhbmQgY2wuX19kaWN0X18uaGFzX2tleShyZWFsbmFtZSkgYW5kCiAgICAgICAgICAgICAgICBjbC5fX2RpY3RfX1tyZWFsbmFtZV0gaXMgb2JqZWN0KToKICAgICAgICAgICAgICAgIHJlYWxsaW5rID0gJzxhIGhyZWY9IiMlcyI+JXM8L2E+JyAlICgKICAgICAgICAgICAgICAgICAgICBjbC5fX25hbWVfXyArICctJyArIHJlYWxuYW1lLCByZWFsbmFtZSkKICAgICAgICAgICAgICAgIHNraXBkb2NzID0gMQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmVhbGxpbmsgPSByZWFsbmFtZQogICAgICAgICAgICB0aXRsZSA9ICc8YSBuYW1lPSIlcyI+PHN0cm9uZz4lczwvc3Ryb25nPjwvYT4gPSAlcycgJSAoCiAgICAgICAgICAgICAgICBhbmNob3IsIG5hbWUsIHJlYWxsaW5rKQogICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKG9iamVjdCk6CiAgICAgICAgICAgIGFyZ3NwZWMgPSAnKC4uLiknCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzID0gaW5zcGVjdC5nZXRhcmdzcGVjKG9iamVjdCkKICAgICAgICAgICAgYXJnc3BlYyA9IGluc3BlY3QuZm9ybWF0YXJnc3BlYygKICAgICAgICAgICAgICAgIGFyZ3MsIHZhcmFyZ3MsIHZhcmt3LCBkZWZhdWx0cywgZm9ybWF0dmFsdWU9c2VsZi5mb3JtYXR2YWx1ZSkKICAgICAgICAgICAgaWYgcmVhbG5hbWUgPT0gJzxsYW1iZGE+JzoKICAgICAgICAgICAgICAgIGRlY2wgPSAnPGVtPmxhbWJkYTwvZW0+JwogICAgICAgICAgICAgICAgYXJnc3BlYyA9IGFyZ3NwZWNbMTotMV0gIyByZW1vdmUgcGFyZW50aGVzZXMKCiAgICAgICAgZGVjbCA9IHRpdGxlICsgYXJnc3BlYyArIChub3RlIGFuZCBzZWxmLnNtYWxsKHNlbGYuZ3JleSgKICAgICAgICAgICAgJzxmb250IGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPiVzPC9mb250PicgJSBub3RlKSkpCgogICAgICAgIGlmIHNraXBkb2NzOgogICAgICAgICAgICByZXR1cm4gJzxkbD48ZHQ+JXM8L2RsPlxuJyAlIGRlY2wKICAgICAgICBlbHNlOgogICAgICAgICAgICBkb2MgPSBzZWxmLm1hcmt1cCgKICAgICAgICAgICAgICAgIGdldGRvYyhvYmplY3QpLCBzZWxmLnByZWZvcm1hdCwgZnVuY3MsIGNsYXNzZXMsIG1ldGhvZHMpCiAgICAgICAgICAgIGRvYyA9IGRvYyBhbmQgJzxkZD4nICsgc2VsZi5zbWFsbCgnPHR0PiVzPC90dD4nICUgZG9jKQogICAgICAgICAgICByZXR1cm4gJzxkbD48ZHQ+JXMlczwvZGw+XG4nICUgKGRlY2wsIGRvYykKCiAgICBkZWYgZG9jb3RoZXIoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBkYXRhIG9iamVjdC4iIiIKICAgICAgICBsaHMgPSBuYW1lIGFuZCAnPHN0cm9uZz4lczwvc3Ryb25nPiA9ICcgJSBuYW1lIG9yICcnCiAgICAgICAgcmV0dXJuIGxocyArIHNlbGYucmVwcihvYmplY3QpCgogICAgZGVmIGluZGV4KHNlbGYsIGRpciwgc2hhZG93ZWQ9Tm9uZSk6CiAgICAgICAgIiIiR2VuZXJhdGUgYW4gSFRNTCBpbmRleCBmb3IgYSBkaXJlY3Rvcnkgb2YgbW9kdWxlcy4iIiIKICAgICAgICBtb2Rwa2dzID0gW10KICAgICAgICBpZiBzaGFkb3dlZCBpcyBOb25lOiBzaGFkb3dlZCA9IHt9CiAgICAgICAgc2VlbiA9IHt9CiAgICAgICAgZmlsZXMgPSBvcy5saXN0ZGlyKGRpcikKCiAgICAgICAgZGVmIGZvdW5kKG5hbWUsIGlzcGFja2FnZSwKICAgICAgICAgICAgICAgICAgbW9kcGtncz1tb2Rwa2dzLCBzaGFkb3dlZD1zaGFkb3dlZCwgc2Vlbj1zZWVuKToKICAgICAgICAgICAgaWYgbm90IHNlZW4uaGFzX2tleShuYW1lKToKICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKChuYW1lLCAnJywgaXNwYWNrYWdlLCBzaGFkb3dlZC5oYXNfa2V5KG5hbWUpKSkKICAgICAgICAgICAgICAgIHNlZW5bbmFtZV0gPSAxCiAgICAgICAgICAgICAgICBzaGFkb3dlZFtuYW1lXSA9IDEKCiAgICAgICAgIyBQYWNrYWdlIHNwYW0vX19pbml0X18ucHkgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIG1vZHVsZSBzcGFtLnB5LgogICAgICAgIGZvciBmaWxlIGluIGZpbGVzOgogICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKGRpciwgZmlsZSkKICAgICAgICAgICAgaWYgaXNwYWNrYWdlKHBhdGgpOiBmb3VuZChmaWxlLCAxKQogICAgICAgIGZvciBmaWxlIGluIGZpbGVzOgogICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKGRpciwgZmlsZSkKICAgICAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUocGF0aCk6CiAgICAgICAgICAgICAgICBtb2RuYW1lID0gaW5zcGVjdC5nZXRtb2R1bGVuYW1lKGZpbGUpCiAgICAgICAgICAgICAgICBpZiBtb2RuYW1lOiBmb3VuZChtb2RuYW1lLCAwKQoKICAgICAgICBtb2Rwa2dzLnNvcnQoKQogICAgICAgIGNvbnRlbnRzID0gc2VsZi5tdWx0aWNvbHVtbihtb2Rwa2dzLCBzZWxmLm1vZHBrZ2xpbmspCiAgICAgICAgcmV0dXJuIHNlbGYuYmlnc2VjdGlvbihkaXIsICcjZmZmZmZmJywgJyNlZTc3YWEnLCBjb250ZW50cykKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdGV4dCBkb2N1bWVudGF0aW9uIGdlbmVyYXRvcgoKY2xhc3MgVGV4dFJlcHIoUmVwcik6CiAgICAiIiJDbGFzcyBmb3Igc2FmZWx5IG1ha2luZyBhIHRleHQgcmVwcmVzZW50YXRpb24gb2YgYSBQeXRob24gb2JqZWN0LiIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIFJlcHIuX19pbml0X18oc2VsZikKICAgICAgICBzZWxmLm1heGxpc3QgPSBzZWxmLm1heHR1cGxlID0gc2VsZi5tYXhkaWN0ID0gMTAKICAgICAgICBzZWxmLm1heHN0cmluZyA9IHNlbGYubWF4b3RoZXIgPSAxMDAKCiAgICBkZWYgcmVwcjEoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIG1ldGhvZG5hbWUgPSAncmVwcl8nICsgam9pbihzcGxpdCh0eXBlKHgpLl9fbmFtZV9fKSwgJ18nKQogICAgICAgIGlmIGhhc2F0dHIoc2VsZiwgbWV0aG9kbmFtZSk6CiAgICAgICAgICAgIHJldHVybiBnZXRhdHRyKHNlbGYsIG1ldGhvZG5hbWUpKHgsIGxldmVsKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBjcmFtKHN0cmlwaWQocmVwcih4KSksIHNlbGYubWF4b3RoZXIpCgogICAgZGVmIHJlcHJfc3RyaW5nKHNlbGYsIHgsIGxldmVsKToKICAgICAgICB0ZXN0ID0gY3JhbSh4LCBzZWxmLm1heHN0cmluZykKICAgICAgICB0ZXN0cmVwciA9IHJlcHIodGVzdCkKICAgICAgICBpZiAnXFwnIGluIHRlc3QgYW5kICdcXCcgbm90IGluIHJlcGxhY2UodGVzdHJlcHIsIHInXFwnLCAnJyk6CiAgICAgICAgICAgICMgQmFja3NsYXNoZXMgYXJlIG9ubHkgbGl0ZXJhbCBpbiB0aGUgc3RyaW5nIGFuZCBhcmUgbmV2ZXIKICAgICAgICAgICAgIyBuZWVkZWQgdG8gbWFrZSBhbnkgc3BlY2lhbCBjaGFyYWN0ZXJzLCBzbyBzaG93IGEgcmF3IHN0cmluZy4KICAgICAgICAgICAgcmV0dXJuICdyJyArIHRlc3RyZXByWzBdICsgdGVzdCArIHRlc3RyZXByWzBdCiAgICAgICAgcmV0dXJuIHRlc3RyZXByCgogICAgZGVmIHJlcHJfaW5zdGFuY2Uoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIHRyeToKICAgICAgICAgICAgcmV0dXJuIGNyYW0oc3RyaXBpZChyZXByKHgpKSwgc2VsZi5tYXhzdHJpbmcpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICByZXR1cm4gJzwlcyBpbnN0YW5jZT4nICUgeC5fX2NsYXNzX18uX19uYW1lX18KCmNsYXNzIFRleHREb2MoRG9jKToKICAgICIiIkZvcm1hdHRlciBjbGFzcyBmb3IgdGV4dCBkb2N1bWVudGF0aW9uLiIiIgoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0ZXh0IGZvcm1hdHRpbmcgdXRpbGl0aWVzCgogICAgX3JlcHJfaW5zdGFuY2UgPSBUZXh0UmVwcigpCiAgICByZXByID0gX3JlcHJfaW5zdGFuY2UucmVwcgoKICAgIGRlZiBib2xkKHNlbGYsIHRleHQpOgogICAgICAgICIiIkZvcm1hdCBhIHN0cmluZyBpbiBib2xkIGJ5IG92ZXJzdHJpa2luZy4iIiIKICAgICAgICByZXR1cm4gam9pbihtYXAobGFtYmRhIGNoOiBjaCArICdcYicgKyBjaCwgdGV4dCksICcnKQoKICAgIGRlZiBpbmRlbnQoc2VsZiwgdGV4dCwgcHJlZml4PScgICAgJyk6CiAgICAgICAgIiIiSW5kZW50IHRleHQgYnkgcHJlcGVuZGluZyBhIGdpdmVuIHByZWZpeCB0byBlYWNoIGxpbmUuIiIiCiAgICAgICAgaWYgbm90IHRleHQ6IHJldHVybiAnJwogICAgICAgIGxpbmVzID0gc3BsaXQodGV4dCwgJ1xuJykKICAgICAgICBsaW5lcyA9IG1hcChsYW1iZGEgbGluZSwgcHJlZml4PXByZWZpeDogcHJlZml4ICsgbGluZSwgbGluZXMpCiAgICAgICAgaWYgbGluZXM6IGxpbmVzWy0xXSA9IHJzdHJpcChsaW5lc1stMV0pCiAgICAgICAgcmV0dXJuIGpvaW4obGluZXMsICdcbicpCgogICAgZGVmIHNlY3Rpb24oc2VsZiwgdGl0bGUsIGNvbnRlbnRzKToKICAgICAgICAiIiJGb3JtYXQgYSBzZWN0aW9uIHdpdGggYSBnaXZlbiBoZWFkaW5nLiIiIgogICAgICAgIHJldHVybiBzZWxmLmJvbGQodGl0bGUpICsgJ1xuJyArIHJzdHJpcChzZWxmLmluZGVudChjb250ZW50cykpICsgJ1xuXG4nCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHR5cGUtc3BlY2lmaWMgcm91dGluZXMKCiAgICBkZWYgZm9ybWF0dHJlZShzZWxmLCB0cmVlLCBtb2RuYW1lLCBwYXJlbnQ9Tm9uZSwgcHJlZml4PScnKToKICAgICAgICAiIiJSZW5kZXIgaW4gdGV4dCBhIGNsYXNzIHRyZWUgYXMgcmV0dXJuZWQgYnkgaW5zcGVjdC5nZXRjbGFzc3RyZWUoKS4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIGZvciBlbnRyeSBpbiB0cmVlOgogICAgICAgICAgICBpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKCgpKToKICAgICAgICAgICAgICAgIGMsIGJhc2VzID0gZW50cnkKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHByZWZpeCArIGNsYXNzbmFtZShjLCBtb2RuYW1lKQogICAgICAgICAgICAgICAgaWYgYmFzZXMgYW5kIGJhc2VzICE9IChwYXJlbnQsKToKICAgICAgICAgICAgICAgICAgICBwYXJlbnRzID0gbWFwKGxhbWJkYSBjLCBtPW1vZG5hbWU6IGNsYXNzbmFtZShjLCBtKSwgYmFzZXMpCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJyglcyknICUgam9pbihwYXJlbnRzLCAnLCAnKQogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJ1xuJwogICAgICAgICAgICBlbGlmIHR5cGUoZW50cnkpIGlzIHR5cGUoW10pOgogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5mb3JtYXR0cmVlKAogICAgICAgICAgICAgICAgICAgIGVudHJ5LCBtb2RuYW1lLCBjLCBwcmVmaXggKyAnICAgICcpCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBkb2Ntb2R1bGUoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBnaXZlbiBtb2R1bGUgb2JqZWN0LiIiIgogICAgICAgIG5hbWUgPSBvYmplY3QuX19uYW1lX18gIyBpZ25vcmUgdGhlIHBhc3NlZC1pbiBuYW1lCiAgICAgICAgc3lub3AsIGRlc2MgPSBzcGxpdGRvYyhnZXRkb2Mob2JqZWN0KSkKICAgICAgICByZXN1bHQgPSBzZWxmLnNlY3Rpb24oJ05BTUUnLCBuYW1lICsgKHN5bm9wIGFuZCAnIC0gJyArIHN5bm9wKSkKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBmaWxlID0gaW5zcGVjdC5nZXRhYnNmaWxlKG9iamVjdCkKICAgICAgICBleGNlcHQgVHlwZUVycm9yOgogICAgICAgICAgICBmaWxlID0gJyhidWlsdC1pbiknCiAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdGSUxFJywgZmlsZSkKICAgICAgICBpZiBkZXNjOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0RFU0NSSVBUSU9OJywgZGVzYykKCiAgICAgICAgY2xhc3NlcyA9IFtdCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc2NsYXNzKToKICAgICAgICAgICAgaWYgKGluc3BlY3QuZ2V0bW9kdWxlKHZhbHVlKSBvciBvYmplY3QpIGlzIG9iamVjdDoKICAgICAgICAgICAgICAgIGNsYXNzZXMuYXBwZW5kKChrZXksIHZhbHVlKSkKICAgICAgICBmdW5jcyA9IFtdCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc3JvdXRpbmUpOgogICAgICAgICAgICBpZiBpbnNwZWN0LmlzYnVpbHRpbih2YWx1ZSkgb3IgaW5zcGVjdC5nZXRtb2R1bGUodmFsdWUpIGlzIG9iamVjdDoKICAgICAgICAgICAgICAgIGZ1bmNzLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCiAgICAgICAgY29uc3RhbnRzID0gW10KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpc2NvbnN0YW50KToKICAgICAgICAgICAgY29uc3RhbnRzLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCgogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19wYXRoX18nKToKICAgICAgICAgICAgbW9kcGtncyA9IFtdCiAgICAgICAgICAgIGZvciBmaWxlIGluIG9zLmxpc3RkaXIob2JqZWN0Ll9fcGF0aF9fWzBdKToKICAgICAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4ob2JqZWN0Ll9fcGF0aF9fWzBdLCBmaWxlKQogICAgICAgICAgICAgICAgbW9kbmFtZSA9IGluc3BlY3QuZ2V0bW9kdWxlbmFtZShmaWxlKQogICAgICAgICAgICAgICAgaWYgbW9kbmFtZSBhbmQgbW9kbmFtZSBub3QgaW4gbW9kcGtnczoKICAgICAgICAgICAgICAgICAgICBtb2Rwa2dzLmFwcGVuZChtb2RuYW1lKQogICAgICAgICAgICAgICAgZWxpZiBpc3BhY2thZ2UocGF0aCk6CiAgICAgICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQoZmlsZSArICcgKHBhY2thZ2UpJykKICAgICAgICAgICAgbW9kcGtncy5zb3J0KCkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKAogICAgICAgICAgICAgICAgJ1BBQ0tBR0UgQ09OVEVOVFMnLCBqb2luKG1vZHBrZ3MsICdcbicpKQoKICAgICAgICBpZiBjbGFzc2VzOgogICAgICAgICAgICBjbGFzc2xpc3QgPSBtYXAobGFtYmRhIChrZXksIHZhbHVlKTogdmFsdWUsIGNsYXNzZXMpCiAgICAgICAgICAgIGNvbnRlbnRzID0gW3NlbGYuZm9ybWF0dHJlZSgKICAgICAgICAgICAgICAgIGluc3BlY3QuZ2V0Y2xhc3N0cmVlKGNsYXNzbGlzdCwgMSksIG5hbWUpXQogICAgICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBjbGFzc2VzOgogICAgICAgICAgICAgICAgY29udGVudHMuYXBwZW5kKHNlbGYuZG9jdW1lbnQodmFsdWUsIGtleSwgbmFtZSkpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignQ0xBU1NFUycsIGpvaW4oY29udGVudHMsICdcbicpKQoKICAgICAgICBpZiBmdW5jczoKICAgICAgICAgICAgY29udGVudHMgPSBbXQogICAgICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBmdW5jczoKICAgICAgICAgICAgICAgIGNvbnRlbnRzLmFwcGVuZChzZWxmLmRvY3VtZW50KHZhbHVlLCBrZXksIG5hbWUpKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0ZVTkNUSU9OUycsIGpvaW4oY29udGVudHMsICdcbicpKQoKICAgICAgICBpZiBjb25zdGFudHM6CiAgICAgICAgICAgIGNvbnRlbnRzID0gW10KICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gY29uc3RhbnRzOgogICAgICAgICAgICAgICAgY29udGVudHMuYXBwZW5kKHNlbGYuZG9jb3RoZXIodmFsdWUsIGtleSwgbmFtZSwgNzApKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0NPTlNUQU5UUycsIGpvaW4oY29udGVudHMsICdcbicpKQoKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fdmVyc2lvbl9fJyk6CiAgICAgICAgICAgIHZlcnNpb24gPSBzdHIob2JqZWN0Ll9fdmVyc2lvbl9fKQogICAgICAgICAgICBpZiB2ZXJzaW9uWzoxMV0gPT0gJyQnICsgJ1JldmlzaW9uOiAnIGFuZCB2ZXJzaW9uWy0xOl0gPT0gJyQnOgogICAgICAgICAgICAgICAgdmVyc2lvbiA9IHN0cmlwKHZlcnNpb25bMTE6LTFdKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ1ZFUlNJT04nLCB2ZXJzaW9uKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19kYXRlX18nKToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdEQVRFJywgc3RyKG9iamVjdC5fX2RhdGVfXykpCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2F1dGhvcl9fJyk6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignQVVUSE9SJywgc3RyKG9iamVjdC5fX2F1dGhvcl9fKSkKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fY3JlZGl0c19fJyk6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignQ1JFRElUUycsIHN0cihvYmplY3QuX19jcmVkaXRzX18pKQogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBkZWYgZG9jY2xhc3Moc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBnaXZlbiBjbGFzcyBvYmplY3QuIiIiCiAgICAgICAgcmVhbG5hbWUgPSBvYmplY3QuX19uYW1lX18KICAgICAgICBuYW1lID0gbmFtZSBvciByZWFsbmFtZQogICAgICAgIGJhc2VzID0gb2JqZWN0Ll9fYmFzZXNfXwoKICAgICAgICBpZiBuYW1lID09IHJlYWxuYW1lOgogICAgICAgICAgICB0aXRsZSA9ICdjbGFzcyAnICsgc2VsZi5ib2xkKHJlYWxuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRpdGxlID0gc2VsZi5ib2xkKG5hbWUpICsgJyA9IGNsYXNzICcgKyByZWFsbmFtZQogICAgICAgIGlmIGJhc2VzOgogICAgICAgICAgICBkZWYgbWFrZW5hbWUoYywgbT1vYmplY3QuX19tb2R1bGVfXyk6IHJldHVybiBjbGFzc25hbWUoYywgbSkKICAgICAgICAgICAgcGFyZW50cyA9IG1hcChtYWtlbmFtZSwgYmFzZXMpCiAgICAgICAgICAgIHRpdGxlID0gdGl0bGUgKyAnKCVzKScgJSBqb2luKHBhcmVudHMsICcsICcpCgogICAgICAgIGRvYyA9IGdldGRvYyhvYmplY3QpCiAgICAgICAgY29udGVudHMgPSBkb2MgYW5kIGRvYyArICdcbicKICAgICAgICBtZXRob2RzID0gYWxsbWV0aG9kcyhvYmplY3QpLml0ZW1zKCkKICAgICAgICBtZXRob2RzLnNvcnQoKQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIG1ldGhvZHM6CiAgICAgICAgICAgIGNvbnRlbnRzID0gY29udGVudHMgKyAnXG4nICsgc2VsZi5kb2N1bWVudCh2YWx1ZSwga2V5LCBtb2QsIG9iamVjdCkKCiAgICAgICAgaWYgbm90IGNvbnRlbnRzOiByZXR1cm4gdGl0bGUgKyAnXG4nCiAgICAgICAgcmV0dXJuIHRpdGxlICsgJ1xuJyArIHNlbGYuaW5kZW50KHJzdHJpcChjb250ZW50cyksICcgfCAgJykgKyAnXG4nCgogICAgZGVmIGZvcm1hdHZhbHVlKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiRm9ybWF0IGFuIGFyZ3VtZW50IGRlZmF1bHQgdmFsdWUgYXMgdGV4dC4iIiIKICAgICAgICByZXR1cm4gJz0nICsgc2VsZi5yZXByKG9iamVjdCkKCiAgICBkZWYgZG9jcm91dGluZShzZWxmLCBvYmplY3QsIG5hbWU9Tm9uZSwgbW9kPU5vbmUsIGNsPU5vbmUpOgogICAgICAgICIiIlByb2R1Y2UgdGV4dCBkb2N1bWVudGF0aW9uIGZvciBhIGZ1bmN0aW9uIG9yIG1ldGhvZCBvYmplY3QuIiIiCiAgICAgICAgcmVhbG5hbWUgPSBvYmplY3QuX19uYW1lX18KICAgICAgICBuYW1lID0gbmFtZSBvciByZWFsbmFtZQogICAgICAgIG5vdGUgPSAnJwogICAgICAgIHNraXBkb2NzID0gMAogICAgICAgIGlmIGluc3BlY3QuaXNtZXRob2Qob2JqZWN0KToKICAgICAgICAgICAgaW1jbGFzcyA9IG9iamVjdC5pbV9jbGFzcwogICAgICAgICAgICBpZiBjbDoKICAgICAgICAgICAgICAgIGlmIGltY2xhc3MgaXMgbm90IGNsOgogICAgICAgICAgICAgICAgICAgIG5vdGUgPSAnIGZyb20gJyArIGNsYXNzbmFtZShpbWNsYXNzLCBtb2QpCiAgICAgICAgICAgICAgICAgICAgc2tpcGRvY3MgPSAxCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBpZiBvYmplY3QuaW1fc2VsZjoKICAgICAgICAgICAgICAgICAgICBub3RlID0gJyBtZXRob2Qgb2YgJXMgaW5zdGFuY2UnICUgY2xhc3NuYW1lKAogICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuaW1fc2VsZi5fX2NsYXNzX18sIG1vZCkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgbm90ZSA9ICcgdW5ib3VuZCAlcyBtZXRob2QnICUgY2xhc3NuYW1lKGltY2xhc3MsbW9kKQogICAgICAgICAgICBvYmplY3QgPSBvYmplY3QuaW1fZnVuYwoKICAgICAgICBpZiBuYW1lID09IHJlYWxuYW1lOgogICAgICAgICAgICB0aXRsZSA9IHNlbGYuYm9sZChyZWFsbmFtZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBpZiAoY2wgYW5kIGNsLl9fZGljdF9fLmhhc19rZXkocmVhbG5hbWUpIGFuZAogICAgICAgICAgICAgICAgY2wuX19kaWN0X19bcmVhbG5hbWVdIGlzIG9iamVjdCk6CiAgICAgICAgICAgICAgICBza2lwZG9jcyA9IDEKICAgICAgICAgICAgdGl0bGUgPSBzZWxmLmJvbGQobmFtZSkgKyAnID0gJyArIHJlYWxuYW1lCiAgICAgICAgaWYgaW5zcGVjdC5pc2J1aWx0aW4ob2JqZWN0KToKICAgICAgICAgICAgYXJnc3BlYyA9ICcoLi4uKScKICAgICAgICBlbHNlOgogICAgICAgICAgICBhcmdzLCB2YXJhcmdzLCB2YXJrdywgZGVmYXVsdHMgPSBpbnNwZWN0LmdldGFyZ3NwZWMob2JqZWN0KQogICAgICAgICAgICBhcmdzcGVjID0gaW5zcGVjdC5mb3JtYXRhcmdzcGVjKAogICAgICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzLCBmb3JtYXR2YWx1ZT1zZWxmLmZvcm1hdHZhbHVlKQogICAgICAgICAgICBpZiByZWFsbmFtZSA9PSAnPGxhbWJkYT4nOgogICAgICAgICAgICAgICAgdGl0bGUgPSAnbGFtYmRhJwogICAgICAgICAgICAgICAgYXJnc3BlYyA9IGFyZ3NwZWNbMTotMV0gIyByZW1vdmUgcGFyZW50aGVzZXMKICAgICAgICBkZWNsID0gdGl0bGUgKyBhcmdzcGVjICsgbm90ZQoKICAgICAgICBpZiBza2lwZG9jczoKICAgICAgICAgICAgcmV0dXJuIGRlY2wgKyAnXG4nCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZG9jID0gZ2V0ZG9jKG9iamVjdCkgb3IgJycKICAgICAgICAgICAgcmV0dXJuIGRlY2wgKyAnXG4nICsgKGRvYyBhbmQgcnN0cmlwKHNlbGYuaW5kZW50KGRvYykpICsgJ1xuJykKCiAgICBkZWYgZG9jb3RoZXIoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lLCBtYXhsZW49Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSB0ZXh0IGRvY3VtZW50YXRpb24gZm9yIGEgZGF0YSBvYmplY3QuIiIiCiAgICAgICAgcmVwciA9IHNlbGYucmVwcihvYmplY3QpCiAgICAgICAgaWYgbWF4bGVuOgogICAgICAgICAgICBsaW5lID0gKG5hbWUgYW5kIG5hbWUgKyAnID0gJyBvciAnJykgKyByZXByCiAgICAgICAgICAgIGNob3AgPSBtYXhsZW4gLSBsZW4obGluZSkKICAgICAgICAgICAgaWYgY2hvcCA8IDA6IHJlcHIgPSByZXByWzpjaG9wXSArICcuLi4nCiAgICAgICAgbGluZSA9IChuYW1lIGFuZCBzZWxmLmJvbGQobmFtZSkgKyAnID0gJyBvciAnJykgKyByZXByCiAgICAgICAgcmV0dXJuIGxpbmUKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHVzZXIgaW50ZXJmYWNlcwoKZGVmIHBhZ2VyKHRleHQpOgogICAgIiIiVGhlIGZpcnN0IHRpbWUgdGhpcyBpcyBjYWxsZWQsIGRldGVybWluZSB3aGF0IGtpbmQgb2YgcGFnZXIgdG8gdXNlLiIiIgogICAgZ2xvYmFsIHBhZ2VyCiAgICBwYWdlciA9IGdldHBhZ2VyKCkKICAgIHBhZ2VyKHRleHQpCgpkZWYgZ2V0cGFnZXIoKToKICAgICIiIkRlY2lkZSB3aGF0IG1ldGhvZCB0byB1c2UgZm9yIHBhZ2luZyB0aHJvdWdoIHRleHQuIiIiCiAgICBpZiB0eXBlKHN5cy5zdGRvdXQpIGlzIG5vdCB0eXBlcy5GaWxlVHlwZToKICAgICAgICByZXR1cm4gcGxhaW5wYWdlcgogICAgaWYgbm90IHN5cy5zdGRpbi5pc2F0dHkoKSBvciBub3Qgc3lzLnN0ZG91dC5pc2F0dHkoKToKICAgICAgICByZXR1cm4gcGxhaW5wYWdlcgogICAgaWYgb3MuZW52aXJvbi5oYXNfa2V5KCdQQUdFUicpOgogICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInOiAjIHBpcGVzIGNvbXBsZXRlbHkgYnJva2VuIGluIFdpbmRvd3MKICAgICAgICAgICAgcmV0dXJuIGxhbWJkYSBhOiB0ZW1wZmlsZXBhZ2VyKGEsIG9zLmVudmlyb25bJ1BBR0VSJ10pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIGxhbWJkYSBhOiBwaXBlcGFnZXIoYSwgb3MuZW52aXJvblsnUEFHRVInXSkKICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInOgogICAgICAgIHJldHVybiBsYW1iZGEgYTogdGVtcGZpbGVwYWdlcihhLCAnbW9yZSA8JykKICAgIGlmIGhhc2F0dHIob3MsICdzeXN0ZW0nKSBhbmQgb3Muc3lzdGVtKCdsZXNzIDI+L2Rldi9udWxsJykgPT0gMDoKICAgICAgICByZXR1cm4gbGFtYmRhIGE6IHBpcGVwYWdlcihhLCAnbGVzcycpCgogICAgaW1wb3J0IHRlbXBmaWxlCiAgICBmaWxlbmFtZSA9IHRlbXBmaWxlLm1rdGVtcCgpCiAgICBvcGVuKGZpbGVuYW1lLCAndycpLmNsb3NlKCkKICAgIHRyeToKICAgICAgICBpZiBoYXNhdHRyKG9zLCAnc3lzdGVtJykgYW5kIG9zLnN5c3RlbSgnbW9yZSAlcycgJSBmaWxlbmFtZSkgPT0gMDoKICAgICAgICAgICAgcmV0dXJuIGxhbWJkYSB0ZXh0OiBwaXBlcGFnZXIodGV4dCwgJ21vcmUnKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiB0dHlwYWdlcgogICAgZmluYWxseToKICAgICAgICBvcy51bmxpbmsoZmlsZW5hbWUpCgpkZWYgcGlwZXBhZ2VyKHRleHQsIGNtZCk6CiAgICAiIiJQYWdlIHRocm91Z2ggdGV4dCBieSBmZWVkaW5nIGl0IHRvIGFub3RoZXIgcHJvZ3JhbS4iIiIKICAgIHBpcGUgPSBvcy5wb3BlbihjbWQsICd3JykKICAgIHRyeToKICAgICAgICBwaXBlLndyaXRlKHRleHQpCiAgICAgICAgcGlwZS5jbG9zZSgpCiAgICBleGNlcHQgSU9FcnJvcjoKICAgICAgICBwYXNzICMgSWdub3JlIGJyb2tlbiBwaXBlcyBjYXVzZWQgYnkgcXVpdHRpbmcgdGhlIHBhZ2VyIHByb2dyYW0uCgpkZWYgdGVtcGZpbGVwYWdlcih0ZXh0LCBjbWQpOgogICAgIiIiUGFnZSB0aHJvdWdoIHRleHQgYnkgaW52b2tpbmcgYSBwcm9ncmFtIG9uIGEgdGVtcG9yYXJ5IGZpbGUuIiIiCiAgICBpbXBvcnQgdGVtcGZpbGUKICAgIGZpbGVuYW1lID0gdGVtcGZpbGUubWt0ZW1wKCkKICAgIGZpbGUgPSBvcGVuKGZpbGVuYW1lLCAndycpCiAgICBmaWxlLndyaXRlKHRleHQpCiAgICBmaWxlLmNsb3NlKCkKICAgIHRyeToKICAgICAgICBvcy5zeXN0ZW0oY21kICsgJyAnICsgZmlsZW5hbWUpCiAgICBmaW5hbGx5OgogICAgICAgIG9zLnVubGluayhmaWxlbmFtZSkKCmRlZiBwbGFpbih0ZXh0KToKICAgICIiIlJlbW92ZSBib2xkZmFjZSBmb3JtYXR0aW5nIGZyb20gdGV4dC4iIiIKICAgIHJldHVybiByZS5zdWIoJy5cYicsICcnLCB0ZXh0KQoKZGVmIHR0eXBhZ2VyKHRleHQpOgogICAgIiIiUGFnZSB0aHJvdWdoIHRleHQgb24gYSB0ZXh0IHRlcm1pbmFsLiIiIgogICAgbGluZXMgPSBzcGxpdChwbGFpbih0ZXh0KSwgJ1xuJykKICAgIHRyeToKICAgICAgICBpbXBvcnQgdHR5CiAgICAgICAgZmQgPSBzeXMuc3RkaW4uZmlsZW5vKCkKICAgICAgICBvbGQgPSB0dHkudGNnZXRhdHRyKGZkKQogICAgICAgIHR0eS5zZXRjYnJlYWsoZmQpCiAgICAgICAgZ2V0Y2hhciA9IGxhbWJkYTogc3lzLnN0ZGluLnJlYWQoMSkKICAgIGV4Y2VwdCAoSW1wb3J0RXJyb3IsIEF0dHJpYnV0ZUVycm9yKToKICAgICAgICB0dHkgPSBOb25lCiAgICAgICAgZ2V0Y2hhciA9IGxhbWJkYTogc3lzLnN0ZGluLnJlYWRsaW5lKClbOi0xXVs6MV0KCiAgICB0cnk6CiAgICAgICAgciA9IGluYyA9IG9zLmVudmlyb24uZ2V0KCdMSU5FUycsIDI1KSAtIDEKICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKGpvaW4obGluZXNbOmluY10sICdcbicpICsgJ1xuJykKICAgICAgICB3aGlsZSBsaW5lc1tyOl06CiAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoJy0tIG1vcmUgLS0nKQogICAgICAgICAgICBzeXMuc3Rkb3V0LmZsdXNoKCkKICAgICAgICAgICAgYyA9IGdldGNoYXIoKQoKICAgICAgICAgICAgaWYgYyBpbiBbJ3EnLCAnUSddOgogICAgICAgICAgICAgICAgc3lzLnN0ZG91dC53cml0ZSgnXHIgICAgICAgICAgXHInKQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgZWxpZiBjIGluIFsnXHInLCAnXG4nXToKICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoJ1xyICAgICAgICAgIFxyJyArIGxpbmVzW3JdICsgJ1xuJykKICAgICAgICAgICAgICAgIHIgPSByICsgMQogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgaWYgYyBpbiBbJ2InLCAnQicsICdceDFiJ106CiAgICAgICAgICAgICAgICByID0gciAtIGluYyAtIGluYwogICAgICAgICAgICAgICAgaWYgciA8IDA6IHIgPSAwCiAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoJ1xuJyArIGpvaW4obGluZXNbcjpyK2luY10sICdcbicpICsgJ1xuJykKICAgICAgICAgICAgciA9IHIgKyBpbmMKCiAgICBmaW5hbGx5OgogICAgICAgIGlmIHR0eToKICAgICAgICAgICAgdHR5LnRjc2V0YXR0cihmZCwgdHR5LlRDU0FGTFVTSCwgb2xkKQoKZGVmIHBsYWlucGFnZXIodGV4dCk6CiAgICAiIiJTaW1wbHkgcHJpbnQgdW5mb3JtYXR0ZWQgdGV4dC4gIFRoaXMgaXMgdGhlIHVsdGltYXRlIGZhbGxiYWNrLiIiIgogICAgc3lzLnN0ZG91dC53cml0ZShwbGFpbih0ZXh0KSkKCmRlZiBkZXNjcmliZSh0aGluZyk6CiAgICAiIiJQcm9kdWNlIGEgc2hvcnQgZGVzY3JpcHRpb24gb2YgdGhlIGdpdmVuIHRoaW5nLiIiIgogICAgaWYgaW5zcGVjdC5pc21vZHVsZSh0aGluZyk6CiAgICAgICAgaWYgdGhpbmcuX19uYW1lX18gaW4gc3lzLmJ1aWx0aW5fbW9kdWxlX25hbWVzOgogICAgICAgICAgICByZXR1cm4gJ2J1aWx0LWluIG1vZHVsZSAnICsgdGhpbmcuX19uYW1lX18KICAgICAgICBpZiBoYXNhdHRyKHRoaW5nLCAnX19wYXRoX18nKToKICAgICAgICAgICAgcmV0dXJuICdwYWNrYWdlICcgKyB0aGluZy5fX25hbWVfXwogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiAnbW9kdWxlICcgKyB0aGluZy5fX25hbWVfXwogICAgaWYgaW5zcGVjdC5pc2J1aWx0aW4odGhpbmcpOgogICAgICAgIHJldHVybiAnYnVpbHQtaW4gZnVuY3Rpb24gJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiBpbnNwZWN0LmlzY2xhc3ModGhpbmcpOgogICAgICAgIHJldHVybiAnY2xhc3MgJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiBpbnNwZWN0LmlzZnVuY3Rpb24odGhpbmcpOgogICAgICAgIHJldHVybiAnZnVuY3Rpb24gJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiBpbnNwZWN0LmlzbWV0aG9kKHRoaW5nKToKICAgICAgICByZXR1cm4gJ21ldGhvZCAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIHR5cGUodGhpbmcpIGlzIHR5cGVzLkluc3RhbmNlVHlwZToKICAgICAgICByZXR1cm4gJ2luc3RhbmNlIG9mICcgKyB0aGluZy5fX2NsYXNzX18uX19uYW1lX18KICAgIHJldHVybiB0eXBlKHRoaW5nKS5fX25hbWVfXwoKZGVmIGZyZXNoaW1wb3J0KHBhdGgsIGNhY2hlPXt9KToKICAgICIiIkltcG9ydCBhIG1vZHVsZSBmcmVzaGx5IGZyb20gZGlzaywgbWFraW5nIHN1cmUgaXQncyB1cCB0byBkYXRlLiIiIgogICAgaWYgc3lzLm1vZHVsZXMuaGFzX2tleShwYXRoKToKICAgICAgICAjIFRoaXMgaXMgdGhlIG9ubHkgd2F5IHRvIGJlIHN1cmUuICBDaGVja2luZyB0aGUgbXRpbWUgb2YgdGhlIGZpbGUKICAgICAgICAjIGlzbid0IGdvb2QgZW5vdWdoIChlLmcuIHdoYXQgaWYgdGhlIG1vZHVsZSBjb250YWlucyBhIGNsYXNzIHRoYXQKICAgICAgICAjIGluaGVyaXRzIGZyb20gYW5vdGhlciBtb2R1bGUgdGhhdCBoYXMgY2hhbmdlZD8pLgogICAgICAgIGlmIHBhdGggbm90IGluIHN5cy5idWlsdGluX21vZHVsZV9uYW1lczoKICAgICAgICAgICAgIyBQeXRob24gbmV2ZXIgbG9hZHMgYSBkeW5hbWljIGV4dGVuc2lvbiBhIHNlY29uZCB0aW1lIGZyb20gdGhlCiAgICAgICAgICAgICMgc2FtZSBwYXRoLCBldmVuIGlmIHRoZSBmaWxlIGlzIGNoYW5nZWQgb3IgbWlzc2luZy4gIERlbGV0aW5nCiAgICAgICAgICAgICMgdGhlIGVudHJ5IGluIHN5cy5tb2R1bGVzIGRvZXNuJ3QgaGVscCBmb3IgZHluYW1pYyBleHRlbnNpb25zLAogICAgICAgICAgICAjIHNvIHdlJ3JlIG5vdCBldmVuIGdvaW5nIHRvIHRyeSB0byBrZWVwIHRoZW0gdXAgdG8gZGF0ZS4KICAgICAgICAgICAgaW5mbyA9IGluc3BlY3QuZ2V0bW9kdWxlaW5mbyhzeXMubW9kdWxlc1twYXRoXS5fX2ZpbGVfXykKICAgICAgICAgICAgaWYgaW5mb1szXSAhPSBpbXAuQ19FWFRFTlNJT046CiAgICAgICAgICAgICAgICBkZWwgc3lzLm1vZHVsZXNbcGF0aF0KICAgIHRyeToKICAgICAgICBtb2R1bGUgPSBfX2ltcG9ydF9fKHBhdGgpCiAgICBleGNlcHQ6CiAgICAgICAgIyBEaWQgdGhlIGVycm9yIG9jY3VyIGJlZm9yZSBvciBhZnRlciB0aGUgbW9kdWxlIHdhcyBmb3VuZD8KICAgICAgICAoZXhjLCB2YWx1ZSwgdGIpID0gaW5mbyA9IHN5cy5leGNfaW5mbygpCiAgICAgICAgaWYgc3lzLm1vZHVsZXMuaGFzX2tleShwYXRoKToKICAgICAgICAgICAgIyBBbiBlcnJvciBvY2N1cmVkIHdoaWxlIGV4ZWN1dGluZyB0aGUgaW1wb3J0ZWQgbW9kdWxlLgogICAgICAgICAgICByYWlzZSBFcnJvckR1cmluZ0ltcG9ydChzeXMubW9kdWxlc1twYXRoXS5fX2ZpbGVfXywgaW5mbykKICAgICAgICBlbGlmIGV4YyBpcyBTeW50YXhFcnJvcjoKICAgICAgICAgICAgIyBBIFN5bnRheEVycm9yIG9jY3VycmVkIGJlZm9yZSB3ZSBjb3VsZCBleGVjdXRlIHRoZSBtb2R1bGUuCiAgICAgICAgICAgIHJhaXNlIEVycm9yRHVyaW5nSW1wb3J0KHZhbHVlLmZpbGVuYW1lLCBpbmZvKQogICAgICAgIGVsaWYgZXhjIGlzIEltcG9ydEVycm9yIGFuZCBcCiAgICAgICAgICAgICBzcGxpdChsb3dlcihzdHIodmFsdWUpKSlbOjJdID09IFsnbm8nLCAnbW9kdWxlJ106CiAgICAgICAgICAgICMgVGhlIG1vZHVsZSB3YXMgbm90IGZvdW5kLgogICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgICMgU29tZSBvdGhlciBlcnJvciBvY2N1cnJlZCBkdXJpbmcgdGhlIGltcG9ydGluZyBwcm9jZXNzLgogICAgICAgICAgICByYWlzZSBFcnJvckR1cmluZ0ltcG9ydChwYXRoLCBzeXMuZXhjX2luZm8oKSkKICAgIGZvciBwYXJ0IGluIHNwbGl0KHBhdGgsICcuJylbMTpdOgogICAgICAgIHRyeTogbW9kdWxlID0gZ2V0YXR0cihtb2R1bGUsIHBhcnQpCiAgICAgICAgZXhjZXB0IEF0dHJpYnV0ZUVycm9yOiByZXR1cm4gTm9uZQogICAgcmV0dXJuIG1vZHVsZQoKZGVmIGxvY2F0ZShwYXRoKToKICAgICIiIkxvY2F0ZSBhbiBvYmplY3QgYnkgbmFtZSBvciBkb3R0ZWQgcGF0aCwgaW1wb3J0aW5nIGFzIG5lY2Vzc2FyeS4iIiIKICAgIHBhcnRzID0gc3BsaXQocGF0aCwgJy4nKQogICAgbW9kdWxlLCBuID0gTm9uZSwgMAogICAgd2hpbGUgbiA8IGxlbihwYXJ0cyk6CiAgICAgICAgbmV4dG1vZHVsZSA9IGZyZXNoaW1wb3J0KGpvaW4ocGFydHNbOm4rMV0sICcuJykpCiAgICAgICAgaWYgbmV4dG1vZHVsZTogbW9kdWxlLCBuID0gbmV4dG1vZHVsZSwgbiArIDEKICAgICAgICBlbHNlOiBicmVhawogICAgaWYgbW9kdWxlOgogICAgICAgIG9iamVjdCA9IG1vZHVsZQogICAgICAgIGZvciBwYXJ0IGluIHBhcnRzW246XToKICAgICAgICAgICAgdHJ5OiBvYmplY3QgPSBnZXRhdHRyKG9iamVjdCwgcGFydCkKICAgICAgICAgICAgZXhjZXB0IEF0dHJpYnV0ZUVycm9yOiByZXR1cm4gTm9uZQogICAgICAgIHJldHVybiBvYmplY3QKICAgIGVsc2U6CiAgICAgICAgaW1wb3J0IF9fYnVpbHRpbl9fCiAgICAgICAgaWYgaGFzYXR0cihfX2J1aWx0aW5fXywgcGF0aCk6CiAgICAgICAgICAgIHJldHVybiBnZXRhdHRyKF9fYnVpbHRpbl9fLCBwYXRoKQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gaW50ZXJhY3RpdmUgaW50ZXJwcmV0ZXIgaW50ZXJmYWNlCgp0ZXh0ID0gVGV4dERvYygpCmh0bWwgPSBIVE1MRG9jKCkKCmRlZiBkb2ModGhpbmcsIHRpdGxlPSdQeXRob24gTGlicmFyeSBEb2N1bWVudGF0aW9uOiAlcycpOgogICAgIiIiRGlzcGxheSB0ZXh0IGRvY3VtZW50YXRpb24sIGdpdmVuIGFuIG9iamVjdCBvciBhIHBhdGggdG8gYW4gb2JqZWN0LiIiIgogICAgc3VmZml4LCBuYW1lID0gJycsIE5vbmUKICAgIGlmIHR5cGUodGhpbmcpIGlzIHR5cGUoJycpOgogICAgICAgIHRyeToKICAgICAgICAgICAgb2JqZWN0ID0gbG9jYXRlKHRoaW5nKQogICAgICAgIGV4Y2VwdCBFcnJvckR1cmluZ0ltcG9ydCwgdmFsdWU6CiAgICAgICAgICAgIHByaW50IHZhbHVlCiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIG5vdCBvYmplY3Q6CiAgICAgICAgICAgIHByaW50ICdubyBQeXRob24gZG9jdW1lbnRhdGlvbiBmb3VuZCBmb3IgJXMnICUgcmVwcih0aGluZykKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgcGFydHMgPSBzcGxpdCh0aGluZywgJy4nKQogICAgICAgIGlmIGxlbihwYXJ0cykgPiAxOiBzdWZmaXggPSAnIGluICcgKyBqb2luKHBhcnRzWzotMV0sICcuJykKICAgICAgICBuYW1lID0gcGFydHNbLTFdCiAgICAgICAgdGhpbmcgPSBvYmplY3QKCiAgICBkZXNjID0gZGVzY3JpYmUodGhpbmcpCiAgICBtb2R1bGUgPSBpbnNwZWN0LmdldG1vZHVsZSh0aGluZykKICAgIGlmIG5vdCBzdWZmaXggYW5kIG1vZHVsZSBhbmQgbW9kdWxlIGlzIG5vdCB0aGluZzoKICAgICAgICBzdWZmaXggPSAnIGluIG1vZHVsZSAnICsgbW9kdWxlLl9fbmFtZV9fCiAgICBwYWdlcih0aXRsZSAlIChkZXNjICsgc3VmZml4KSArICdcblxuJyArIHRleHQuZG9jdW1lbnQodGhpbmcsIG5hbWUpKQoKZGVmIHdyaXRlZG9jKGtleSk6CiAgICAiIiJXcml0ZSBIVE1MIGRvY3VtZW50YXRpb24gdG8gYSBmaWxlIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeS4iIiIKICAgIHRyeToKICAgICAgICBvYmplY3QgPSBsb2NhdGUoa2V5KQogICAgZXhjZXB0IEVycm9yRHVyaW5nSW1wb3J0LCB2YWx1ZToKICAgICAgICBwcmludCB2YWx1ZQogICAgZWxzZToKICAgICAgICBpZiBvYmplY3Q6CiAgICAgICAgICAgIHBhZ2UgPSBodG1sLnBhZ2UoZGVzY3JpYmUob2JqZWN0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBodG1sLmRvY3VtZW50KG9iamVjdCwgb2JqZWN0Ll9fbmFtZV9fKSkKICAgICAgICAgICAgZmlsZSA9IG9wZW4oa2V5ICsgJy5odG1sJywgJ3cnKQogICAgICAgICAgICBmaWxlLndyaXRlKHBhZ2UpCiAgICAgICAgICAgIGZpbGUuY2xvc2UoKQogICAgICAgICAgICBwcmludCAnd3JvdGUnLCBrZXkgKyAnLmh0bWwnCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcHJpbnQgJ25vIFB5dGhvbiBkb2N1bWVudGF0aW9uIGZvdW5kIGZvciAlcycgJSByZXByKGtleSkKCmRlZiB3cml0ZWRvY3MoZGlyLCBwa2dwYXRoPScnLCBkb25lPXt9KToKICAgICIiIldyaXRlIG91dCBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGFsbCBtb2R1bGVzIGluIGEgZGlyZWN0b3J5IHRyZWUuIiIiCiAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKGRpcik6CiAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihkaXIsIGZpbGUpCiAgICAgICAgaWYgaXNwYWNrYWdlKHBhdGgpOgogICAgICAgICAgICB3cml0ZWRvY3MocGF0aCwgcGtncGF0aCArIGZpbGUgKyAnLicpCiAgICAgICAgZWxpZiBvcy5wYXRoLmlzZmlsZShwYXRoKToKICAgICAgICAgICAgbW9kbmFtZSA9IGluc3BlY3QuZ2V0bW9kdWxlbmFtZShwYXRoKQogICAgICAgICAgICBpZiBtb2RuYW1lOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IHBrZ3BhdGggKyBtb2RuYW1lCiAgICAgICAgICAgICAgICBpZiBub3QgZG9uZS5oYXNfa2V5KG1vZG5hbWUpOgogICAgICAgICAgICAgICAgICAgIGRvbmVbbW9kbmFtZV0gPSAxCiAgICAgICAgICAgICAgICAgICAgd3JpdGVkb2MobW9kbmFtZSkKCmNsYXNzIEhlbHBlcjoKICAgIGtleXdvcmRzID0gewogICAgICAgICdhbmQnOiAnQk9PTEVBTicsCiAgICAgICAgJ2Fzc2VydCc6ICdBU1NFUlQnLAogICAgICAgICdicmVhayc6ICgncmVmL2JyZWFrJywgJ3doaWxlIGZvcicpLAogICAgICAgICdjbGFzcyc6ICgncmVmL2NsYXNzJywgJ0NMQVNTRVMgU1BFQ0lBTE1FVEhPRFMnKSwKICAgICAgICAnY29udGludWUnOiAoJ3JlZi9jb250aW51ZScsICd3aGlsZSBmb3InKSwKICAgICAgICAnZGVmJzogKCdyZWYvZnVuY3Rpb24nLCAnJyksCiAgICAgICAgJ2RlbCc6ICgncmVmL2RlbCcsICdCQVNJQ01FVEhPRFMnKSwKICAgICAgICAnZWxpZic6ICdpZicsCiAgICAgICAgJ2Vsc2UnOiAoJ3JlZi9pZicsICd3aGlsZSBmb3InKSwKICAgICAgICAnZXhjZXB0JzogJ3RyeScsCiAgICAgICAgJ2V4ZWMnOiAoJ3JlZi9leGVjJywgJycpLAogICAgICAgICdmaW5hbGx5JzogJ3RyeScsCiAgICAgICAgJ2Zvcic6ICgncmVmL2ZvcicsICdicmVhayBjb250aW51ZSB3aGlsZScpLAogICAgICAgICdmcm9tJzogJ2ltcG9ydCcsCiAgICAgICAgJ2dsb2JhbCc6ICgncmVmL2dsb2JhbCcsICdOQU1FU1BBQ0VTJyksCiAgICAgICAgJ2lmJzogKCdyZWYvaWYnLCAnVFJVVEhWQUxVRScpLAogICAgICAgICdpbXBvcnQnOiAoJ3JlZi9pbXBvcnQnLCAnTU9EVUxFUycpLAogICAgICAgICdpbic6ICgncmVmL2NvbXBhcmlzb25zJywgJ1NFUVVFTkNFTUVUSE9EUzInKSwKICAgICAgICAnaXMnOiAnQ09NUEFSSVNPTicsCiAgICAgICAgJ2xhbWJkYSc6ICgncmVmL2xhbWJkYScsICdGVU5DVElPTlMnKSwKICAgICAgICAnbm90JzogJ0JPT0xFQU4nLAogICAgICAgICdvcic6ICdCT09MRUFOJywKICAgICAgICAncGFzcyc6ICdQQVNTJywKICAgICAgICAncHJpbnQnOiAoJ3JlZi9wcmludCcsICcnKSwKICAgICAgICAncmFpc2UnOiAoJ3JlZi9yYWlzZScsICdFWENFUFRJT05TJyksCiAgICAgICAgJ3JldHVybic6ICgncmVmL3JldHVybicsICcnKSwKICAgICAgICAndHJ5JzogKCdyZWYvdHJ5JywgJ0VYQ0VQVElPTlMnKSwKICAgICAgICAnd2hpbGUnOiAoJ3JlZi93aGlsZScsICdicmVhayBjb250aW51ZSBpZiBUUlVUSFZBTFVFJyksCiAgICB9CgogICAgdG9waWNzID0gewogICAgICAgICdUWVBFUyc6ICgncmVmL3R5cGVzJywgJ1NUUklOR1MgVU5JQ09ERSBOVU1CRVJTIFNFUVVFTkNFUyBNQVBQSU5HUyBGVU5DVElPTlMgQ0xBU1NFUyBNT0RVTEVTIEZJTEVTIGluc3BlY3QnKSwKICAgICAgICAnU1RSSU5HUyc6ICgncmVmL3N0cmluZ3MnLCAnVU5JQ09ERSBTRVFVRU5DRVMgU1RSSU5HTUVUSE9EUyBGT1JNQVRUSU5HIFRZUEVTJyksCiAgICAgICAgJ1NUUklOR01FVEhPRFMnOiAoJ2xpYi9zdHJpbmctbWV0aG9kcycsICdTVFJJTkdTIEZPUk1BVFRJTkcnKSwKICAgICAgICAnRk9STUFUVElORyc6ICgnbGliL3R5cGVzc2VxLXN0cmluZ3MnLCAnT1BFUkFUT1JTJyksCiAgICAgICAgJ1VOSUNPREUnOiAoJ3JlZi91bmljb2RlJywgJ1RZUEVTIFNUUklORycpLAogICAgICAgICdOVU1CRVJTJzogKCdyZWYvbnVtYmVycycsICdJTlRFR0VSIEZMT0FUIENPTVBMRVggVFlQRVMnKSwKICAgICAgICAnSU5URUdFUic6ICgncmVmL2ludGVnZXJzJywgJ2ludCByYW5nZScpLAogICAgICAgICdGTE9BVCc6ICgncmVmL2Zsb2F0aW5nJywgJ2Zsb2F0IG1hdGgnKSwKICAgICAgICAnQ09NUExFWCc6ICgncmVmL2ltYWdpbmFyeScsICdjb21wbGV4IGNtYXRoJyksCiAgICAgICAgJ1NFUVVFTkNFUyc6ICgnbGliL3R5cGVzc2VxJywgJ0xJU1RTJyksCiAgICAgICAgJ01BUFBJTkdTJzogJ0RJQ1RJT05BUklFUycsCiAgICAgICAgJ0ZVTkNUSU9OUyc6ICgnbGliL3R5cGVzZnVuY3Rpb25zJywgJ2RlZiBUWVBFUycpLAogICAgICAgICdNRVRIT0RTJzogKCdsaWIvdHlwZXNtZXRob2RzJywgJ2NsYXNzIGRlZiBDTEFTU0VTIFRZUEVTJyksCiAgICAgICAgJ0NPREVPQkpFQ1RTJzogKCdsaWIvYmx0aW4tY29kZS1vYmplY3RzJywgJ2NvbXBpbGUgRlVOQ1RJT05TIFRZUEVTJyksCiAgICAgICAgJ1RZUEVPQkpFQ1RTJzogKCdsaWIvYmx0aW4tdHlwZS1vYmplY3RzJywgJ1RZUEVTJyksCiAgICAgICAgJ0ZSQU1FT0JKRUNUUyc6ICdUWVBFUycsCiAgICAgICAgJ1RSQUNFQkFDS1MnOiAnVFlQRVMnLAogICAgICAgICdOT05FJzogKCdsaWIvYmx0aW4tbnVsbC1vYmplY3QnLCAnJyksCiAgICAgICAgJ0VMTElQU0lTJzogKCdsaWIvYmx0aW4tZWxsaXBzaXMtb2JqZWN0JywgJ1NMSUNJTkdTJyksCiAgICAgICAgJ0ZJTEVTJzogKCdsaWIvYmx0aW4tZmlsZS1vYmplY3RzJywgJycpLAogICAgICAgICdTUEVDSUFMQVRUUklCVVRFUyc6ICgnbGliL3NwZWNpYWxhdHRycycsICcnKSwKICAgICAgICAnQ0xBU1NFUyc6ICgncmVmL3R5cGVzJywgJ2NsYXNzIFNQRUNJQUxNRVRIT0RTIFBSSVZBVEVOQU1FUycpLAogICAgICAgICdNT0RVTEVTJzogKCdsaWIvdHlwZXNtb2R1bGVzJywgJ2ltcG9ydCcpLAogICAgICAgICdQQUNLQUdFUyc6ICdpbXBvcnQnLAogICAgICAgICdFWFBSRVNTSU9OUyc6ICgncmVmL3N1bW1hcnknLCAnbGFtYmRhIG9yIGFuZCBub3QgaW4gaXMgQk9PTEVBTiBDT01QQVJJU09OIEJJVFdJU0UgU0hJRlRJTkcgQklOQVJZIEZPUk1BVFRJTkcgUE9XRVIgVU5BUlkgQVRUUklCVVRFUyBTVUJTQ1JJUFRTIFNMSUNJTkdTIENBTExTIFRVUExFUyBMSVNUUyBESUNUSU9OQVJJRVMgQkFDS1FVT1RFUycpLAogICAgICAgICdPUEVSQVRPUlMnOiAnRVhQUkVTU0lPTlMnLAogICAgICAgICdQUkVDRURFTkNFJzogJ0VYUFJFU1NJT05TJywKICAgICAgICAnT0JKRUNUUyc6ICgncmVmL29iamVjdHMnLCAnVFlQRVMnKSwKICAgICAgICAnU1BFQ0lBTE1FVEhPRFMnOiAoJ3JlZi9zcGVjaWFsbmFtZXMnLCAnQkFTSUNNRVRIT0RTIEFUVFJJQlVURU1FVEhPRFMgQ0FMTEFCTEVNRVRIT0RTIFNFUVVFTkNFTUVUSE9EUzEgTUFQUElOR01FVEhPRFMgU0VRVUVOQ0VNRVRIT0RTMiBOVU1CRVJNRVRIT0RTIENMQVNTRVMnKSwKICAgICAgICAnQkFTSUNNRVRIT0RTJzogKCdyZWYvY3VzdG9taXphdGlvbicsICdTUEVDSUFMTUVUSE9EUycpLAogICAgICAgICdBVFRSSUJVVEVNRVRIT0RTJzogKCdyZWYvYXR0cmlidXRlLWFjY2VzcycsICdTUEVDSUFMTUVUSE9EUycpLAogICAgICAgICdDQUxMQUJMRU1FVEhPRFMnOiAoJ3JlZi9jYWxsYWJsZS10eXBlcycsICdTUEVDSUFMTUVUSE9EUycpLAogICAgICAgICdTRVFVRU5DRU1FVEhPRFMxJzogKCdyZWYvc2VxdWVuY2UtdHlwZXMnLCAnU0VRVUVOQ0VNRVRIT0RTMicpLAogICAgICAgICdTRVFVRU5DRU1FVEhPRFMyJzogKCdyZWYvc2VxdWVuY2UtbWV0aG9kcycsICdTRVFVRU5DRU1FVEhPRFMxJyksCiAgICAgICAgJ01BUFBJTkdNRVRIT0RTJzogKCdyZWYvc2VxdWVuY2UtdHlwZXMnLCAnU1BFQ0lBTE1FVEhPRFMnKSwKICAgICAgICAnTlVNQkVSTUVUSE9EUyc6ICgncmVmL251bWVyaWMtdHlwZXMnLCAnU1BFQ0lBTE1FVEhPRFMnKSwKICAgICAgICAnRVhFQ1VUSU9OJzogKCdyZWYvZXhlY2ZyYW1lcycsICcnKSwKICAgICAgICAnTkFNRVNQQUNFUyc6ICgncmVmL2V4ZWNmcmFtZXMnLCAnZ2xvYmFsIEFTU0lHTk1FTlQgREVMRVRJT04nKSwKICAgICAgICAnU0NPUElORyc6ICdOQU1FU1BBQ0VTJywKICAgICAgICAnRlJBTUVTJzogJ05BTUVTUEFDRVMnLAogICAgICAgICdFWENFUFRJT05TJzogKCdyZWYvZXhjZXB0aW9ucycsICd0cnkgZXhjZXB0IGZpbmFsbHkgcmFpc2UnKSwKICAgICAgICAnQ09FUkNJT05TJzogJ0NPTlZFUlNJT05TJywKICAgICAgICAnQ09OVkVSU0lPTlMnOiAoJ3JlZi9jb252ZXJzaW9ucycsICcnKSwKICAgICAgICAnSURFTlRJRklFUlMnOiAoJ3JlZi9pZGVudGlmaWVycycsICdrZXl3b3JkcyBTUEVDSUFMSURFTlRJRklFUlMnKSwKICAgICAgICAnU1BFQ0lBTElERU5USUZJRVJTJzogKCdyZWYvaWQtY2xhc3NlcycsICcnKSwKICAgICAgICAnUFJJVkFURU5BTUVTJzogKCdyZWYvaWRlbnRpZmllcnMnLCAnJyksCiAgICAgICAgJ0xJVEVSQUxTJzogKCdyZWYvYXRvbS1saXRlcmFscycsICdTVFJJTkdTIEJBQ0tRVU9URVMgTlVNQkVSUyBUVVBMRUxJVEVSQUxTIExJU1RMSVRFUkFMUyBESUNUSU9OQVJZTElURVJBTFMnKSwKICAgICAgICAnVFVQTEVTJzogJ1NFUVVFTkNFUycsCiAgICAgICAgJ1RVUExFTElURVJBTFMnOiAoJ3JlZi9leHBybGlzdHMnLCAnTElURVJBTFMnKSwKICAgICAgICAnTElTVFMnOiAoJ2xpYi90eXBlc3NlcS1tdXRhYmxlJywgJ0xJU1RMSVRFUkFMUycpLAogICAgICAgICdMSVNUTElURVJBTFMnOiAoJ3JlZi9saXN0cycsICdMSVRFUkFMUycpLAogICAgICAgICdESUNUSU9OQVJJRVMnOiAoJ2xpYi90eXBlc21hcHBpbmcnLCAnRElDVElPTkFSWUxJVEVSQUxTJyksCiAgICAgICAgJ0RJQ1RJT05BUllMSVRFUkFMUyc6ICgncmVmL2RpY3QnLCAnTElURVJBTFMnKSwKICAgICAgICAnQkFDS1FVT1RFUyc6ICgncmVmL3N0cmluZy1jb252ZXJzaW9ucycsICdMSVRFUkFMUycpLAogICAgICAgICdBVFRSSUJVVEVTJzogKCdyZWYvYXR0cmlidXRlLXJlZmVyZW5jZXMnLCAnZ2V0YXR0ciBoYXNhdHRyIHNldGF0dHIgQVRUUklCVVRFTUVUSE9EUycpLAogICAgICAgICdTVUJTQ1JJUFRTJzogKCdyZWYvc3Vic2NyaXB0aW9ucycsICdTRVFVRU5DRU1FVEhPRFMxJyksCiAgICAgICAgJ1NMSUNJTkdTJzogKCdyZWYvc2xpY2luZ3MnLCAnU0VRVUVOQ0VNRVRIT0RTMicpLAogICAgICAgICdDQUxMUyc6ICgncmVmL2NhbGxzJywgJ0VYUFJFU1NJT05TJyksCiAgICAgICAgJ1BPV0VSJzogKCdyZWYvcG93ZXInLCAnRVhQUkVTU0lPTlMnKSwKICAgICAgICAnVU5BUlknOiAoJ3JlZi91bmFyeScsICdFWFBSRVNTSU9OUycpLAogICAgICAgICdCSU5BUlknOiAoJ3JlZi9iaW5hcnknLCAnRVhQUkVTU0lPTlMnKSwKICAgICAgICAnU0hJRlRJTkcnOiAoJ3JlZi9zaGlmdGluZycsICdFWFBSRVNTSU9OUycpLAogICAgICAgICdCSVRXSVNFJzogKCdyZWYvYml0d2lzZScsICdFWFBSRVNTSU9OUycpLAogICAgICAgICdDT01QQVJJU09OJzogKCdyZWYvY29tcGFyaXNvbnMnLCAnRVhQUkVTU0lPTlMgQkFTSUNNRVRIT0RTJyksCiAgICAgICAgJ0JPT0xFQU4nOiAoJ3JlZi9sYW1iZGEnLCAnRVhQUkVTU0lPTlMnKSwKICAgICAgICAnQVNTRVJUSU9OJzogJ2Fzc2VydCcsCiAgICAgICAgJ0FTU0lHTk1FTlQnOiAoJ3JlZi9hc3NpZ25tZW50JywgJ0FVR01FTlRFREFTU0lHTk1FTlQnKSwKICAgICAgICAnQVVHTUVOVEVEQVNTSUdOTUVOVCc6ICgncmVmL2F1Z2Fzc2lnbicsICcnKSwKICAgICAgICAnREVMRVRJT04nOiAnZGVsJywKICAgICAgICAnUFJJTlRJTkcnOiAncHJpbnQnLAogICAgICAgICdSRVRVUk5JTkcnOiAncmV0dXJuJywKICAgICAgICAnSU1QT1JUSU5HJzogJ2ltcG9ydCcsCiAgICAgICAgJ0NPTkRJVElPTkFMJzogJ2lmJywKICAgICAgICAnTE9PUElORyc6ICgncmVmL2NvbXBvdW5kJywgJ2ZvciB3aGlsZSBicmVhayBjb250aW51ZScpLAogICAgICAgICdUUlVUSFZBTFVFJzogKCdsaWIvdHJ1dGgnLCAnaWYgd2hpbGUgYW5kIG9yIG5vdCBCQVNJQ01FVEhPRFMnKSwKICAgIH0KCiAgICBkZWYgX19pbml0X18oc2VsZiwgaW5wdXQsIG91dHB1dCk6CiAgICAgICAgc2VsZi5pbnB1dCA9IGlucHV0CiAgICAgICAgc2VsZi5vdXRwdXQgPSBvdXRwdXQKICAgICAgICBzZWxmLmRvY2RpciA9IE5vbmUKICAgICAgICBleGVjZGlyID0gb3MucGF0aC5kaXJuYW1lKHN5cy5leGVjdXRhYmxlKQogICAgICAgIGhvbWVkaXIgPSBvcy5lbnZpcm9uLmdldCgnUFlUSE9OSE9NRScpCiAgICAgICAgZm9yIGRpciBpbiBbb3MuZW52aXJvbi5nZXQoJ1BZVEhPTkRPQ1MnKSwKICAgICAgICAgICAgICAgICAgICBob21lZGlyIGFuZCBvcy5wYXRoLmpvaW4oaG9tZWRpciwgJ2RvYycpLAogICAgICAgICAgICAgICAgICAgIG9zLnBhdGguam9pbihleGVjZGlyLCAnZG9jJyksCiAgICAgICAgICAgICAgICAgICAgJy91c3IvZG9jL3B5dGhvbi1kb2NzLScgKyBzcGxpdChzeXMudmVyc2lvbilbMF0sCiAgICAgICAgICAgICAgICAgICAgJy91c3IvZG9jL3B5dGhvbi0nICsgc3BsaXQoc3lzLnZlcnNpb24pWzBdLAogICAgICAgICAgICAgICAgICAgICcvdXNyL2RvYy9weXRob24tZG9jcy0nICsgc3lzLnZlcnNpb25bOjNdLAogICAgICAgICAgICAgICAgICAgICcvdXNyL2RvYy9weXRob24tJyArIHN5cy52ZXJzaW9uWzozXV06CiAgICAgICAgICAgIGlmIGRpciBhbmQgb3MucGF0aC5pc2Rpcihvcy5wYXRoLmpvaW4oZGlyLCAnbGliJykpOgogICAgICAgICAgICAgICAgc2VsZi5kb2NkaXIgPSBkaXIKCiAgICBkZWYgX19yZXByX18oc2VsZik6CiAgICAgICAgc2VsZigpCiAgICAgICAgcmV0dXJuICcnCgogICAgZGVmIF9fY2FsbF9fKHNlbGYsIHJlcXVlc3Q9Tm9uZSk6CiAgICAgICAgaWYgcmVxdWVzdCBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi5oZWxwKHJlcXVlc3QpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5pbnRybygpCiAgICAgICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCdcbicpCiAgICAgICAgICAgIHdoaWxlIDE6CiAgICAgICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnaGVscD4gJykKICAgICAgICAgICAgICAgIHNlbGYub3V0cHV0LmZsdXNoKCkKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICByZXF1ZXN0ID0gc2VsZi5pbnB1dC5yZWFkbGluZSgpCiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHJlcXVlc3Q6IGJyZWFrCiAgICAgICAgICAgICAgICBleGNlcHQgS2V5Ym9hcmRJbnRlcnJ1cHQ6IGJyZWFrCiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gc3RyaXAocmVwbGFjZShyZXF1ZXN0LCAnIicsICcnLCAiJyIsICcnKSkKICAgICAgICAgICAgICAgIGlmIGxvd2VyKHJlcXVlc3QpIGluIFsncScsICdxdWl0J106IGJyZWFrCiAgICAgICAgICAgICAgICBzZWxmLmhlbHAocmVxdWVzdCkKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnCllvdSdyZSBub3cgbGVhdmluZyBoZWxwIGFuZCByZXR1cm5pbmcgdG8gdGhlIFB5dGhvbiBpbnRlcnByZXRlci4KSWYgeW91IHdhbnQgdG8gYXNrIGZvciBoZWxwIG9uIGEgcGFydGljdWxhciBvYmplY3QgZGlyZWN0bHkgZnJvbSB0aGUKaW50ZXJwcmV0ZXIsIHlvdSBjYW4gdHlwZSAiaGVscChvYmplY3QpIi4gIEV4ZWN1dGluZyAiaGVscCgnc3RyaW5nJykiCmhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgdHlwaW5nIGEgcGFydGljdWxhciBzdHJpbmcgYXQgdGhlIGhlbHA+IHByb21wdC4KJycnKQoKICAgIGRlZiBoZWxwKHNlbGYsIHJlcXVlc3QpOgogICAgICAgIGlmIHR5cGUocmVxdWVzdCkgaXMgdHlwZSgnJyk6CiAgICAgICAgICAgIGlmIHJlcXVlc3QgPT0gJ2hlbHAnOiBzZWxmLmludHJvKCkKICAgICAgICAgICAgZWxpZiByZXF1ZXN0ID09ICdrZXl3b3Jkcyc6IHNlbGYubGlzdGtleXdvcmRzKCkKICAgICAgICAgICAgZWxpZiByZXF1ZXN0ID09ICd0b3BpY3MnOiBzZWxmLmxpc3R0b3BpY3MoKQogICAgICAgICAgICBlbGlmIHJlcXVlc3QgPT0gJ21vZHVsZXMnOiBzZWxmLmxpc3Rtb2R1bGVzKCkKICAgICAgICAgICAgZWxpZiByZXF1ZXN0Wzo4XSA9PSAnbW9kdWxlcyAnOgogICAgICAgICAgICAgICAgc2VsZi5saXN0bW9kdWxlcyhzcGxpdChyZXF1ZXN0KVsxXSkKICAgICAgICAgICAgZWxpZiBzZWxmLmtleXdvcmRzLmhhc19rZXkocmVxdWVzdCk6IHNlbGYuc2hvd3RvcGljKHJlcXVlc3QpCiAgICAgICAgICAgIGVsaWYgc2VsZi50b3BpY3MuaGFzX2tleShyZXF1ZXN0KTogc2VsZi5zaG93dG9waWMocmVxdWVzdCkKICAgICAgICAgICAgZWxpZiByZXF1ZXN0OiBkb2MocmVxdWVzdCwgJ0hlbHAgb24gJXM6JykKICAgICAgICBlbGlmIGlzaW5zdGFuY2UocmVxdWVzdCwgSGVscGVyKTogc2VsZigpCiAgICAgICAgZWxzZTogZG9jKHJlcXVlc3QsICdIZWxwIG9uICVzOicpCiAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJ1xuJykKCiAgICBkZWYgaW50cm8oc2VsZik6CiAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnCldlbGNvbWUgdG8gUHl0aG9uICVzISAgVGhpcyBpcyB0aGUgb25saW5lIGhlbHAgdXRpbGl0eS4KCklmIHRoaXMgaXMgeW91ciBmaXJzdCB0aW1lIHVzaW5nIFB5dGhvbiwgeW91IHNob3VsZCBkZWZpbml0ZWx5IGNoZWNrIG91dAp0aGUgdHV0b3JpYWwgb24gdGhlIEludGVybmV0IGF0IGh0dHA6Ly93d3cucHl0aG9uLm9yZy9kb2MvdHV0Ly4KCkVudGVyIHRoZSBuYW1lIG9mIGFueSBtb2R1bGUsIGtleXdvcmQsIG9yIHRvcGljIHRvIGdldCBoZWxwIG9uIHdyaXRpbmcKUHl0aG9uIHByb2dyYW1zIGFuZCB1c2luZyBQeXRob24gbW9kdWxlcy4gIFRvIHF1aXQgdGhpcyBoZWxwIHV0aWxpdHkgYW5kCnJldHVybiB0byB0aGUgaW50ZXJwcmV0ZXIsIGp1c3QgdHlwZSAicXVpdCIuCgpUbyBnZXQgYSBsaXN0IG9mIGF2YWlsYWJsZSBtb2R1bGVzLCBrZXl3b3Jkcywgb3IgdG9waWNzLCB0eXBlICJtb2R1bGVzIiwKImtleXdvcmRzIiwgb3IgInRvcGljcyIuICBFYWNoIG1vZHVsZSBhbHNvIGNvbWVzIHdpdGggYSBvbmUtbGluZSBzdW1tYXJ5Cm9mIHdoYXQgaXQgZG9lczsgdG8gbGlzdCB0aGUgbW9kdWxlcyB3aG9zZSBzdW1tYXJpZXMgY29udGFpbiBhIGdpdmVuIHdvcmQKc3VjaCBhcyAic3BhbSIsIHR5cGUgIm1vZHVsZXMgc3BhbSIuCicnJyAlIHN5cy52ZXJzaW9uWzozXSkKCiAgICBkZWYgbGlzdChzZWxmLCBpdGVtcywgY29sdW1ucz00LCB3aWR0aD04MCk6CiAgICAgICAgaXRlbXMgPSBpdGVtc1s6XQogICAgICAgIGl0ZW1zLnNvcnQoKQogICAgICAgIGNvbHcgPSB3aWR0aCAvIGNvbHVtbnMKICAgICAgICByb3dzID0gKGxlbihpdGVtcykgKyBjb2x1bW5zIC0gMSkgLyBjb2x1bW5zCiAgICAgICAgZm9yIHJvdyBpbiByYW5nZShyb3dzKToKICAgICAgICAgICAgZm9yIGNvbCBpbiByYW5nZShjb2x1bW5zKToKICAgICAgICAgICAgICAgIGkgPSBjb2wgKiByb3dzICsgcm93CiAgICAgICAgICAgICAgICBpZiBpIDwgbGVuKGl0ZW1zKToKICAgICAgICAgICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZShpdGVtc1tpXSkKICAgICAgICAgICAgICAgICAgICBpZiBjb2wgPCBjb2x1bW5zIC0gMToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJyAnICsgJyAnICogKGNvbHctMSAtIGxlbihpdGVtc1tpXSkpKQogICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnXG4nKQoKICAgIGRlZiBsaXN0a2V5d29yZHMoc2VsZik6CiAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnCkhlcmUgaXMgYSBsaXN0IG9mIHRoZSBQeXRob24ga2V5d29yZHMuICBFbnRlciBhbnkga2V5d29yZCB0byBnZXQgbW9yZSBoZWxwLgoKJycnKQogICAgICAgIHNlbGYubGlzdChzZWxmLmtleXdvcmRzLmtleXMoKSkKCiAgICBkZWYgbGlzdHRvcGljcyhzZWxmKToKICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnJycKSGVyZSBpcyBhIGxpc3Qgb2YgYXZhaWxhYmxlIHRvcGljcy4gIEVudGVyIGFueSB0b3BpYyBuYW1lIHRvIGdldCBtb3JlIGhlbHAuCgonJycpCiAgICAgICAgc2VsZi5saXN0KHNlbGYudG9waWNzLmtleXMoKSkKCiAgICBkZWYgc2hvd3RvcGljKHNlbGYsIHRvcGljKToKICAgICAgICBpZiBub3Qgc2VsZi5kb2NkaXI6CiAgICAgICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCcnJwpTb3JyeSwgdG9waWMgYW5kIGtleXdvcmQgZG9jdW1lbnRhdGlvbiBpcyBub3QgYXZhaWxhYmxlIGJlY2F1c2UgdGhlIFB5dGhvbgpIVE1MIGRvY3VtZW50YXRpb24gZmlsZXMgY291bGQgbm90IGJlIGZvdW5kLiAgSWYgeW91IGhhdmUgaW5zdGFsbGVkIHRoZW0sCnBsZWFzZSBzZXQgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlIFBZVEhPTkRPQ1MgdG8gaW5kaWNhdGUgdGhlaXIgbG9jYXRpb24uCicnJykKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgdGFyZ2V0ID0gc2VsZi50b3BpY3MuZ2V0KHRvcGljLCBzZWxmLmtleXdvcmRzLmdldCh0b3BpYykpCiAgICAgICAgaWYgbm90IHRhcmdldDoKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJ25vIGRvY3VtZW50YXRpb24gZm91bmQgZm9yICVzXG4nICUgcmVwcih0b3BpYykpCiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIHR5cGUodGFyZ2V0KSBpcyB0eXBlKCcnKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuc2hvd3RvcGljKHRhcmdldCkKCiAgICAgICAgZmlsZW5hbWUsIHhyZWZzID0gdGFyZ2V0CiAgICAgICAgZmlsZW5hbWUgPSBzZWxmLmRvY2RpciArICcvJyArIGZpbGVuYW1lICsgJy5odG1sJwogICAgICAgIHRyeToKICAgICAgICAgICAgZmlsZSA9IG9wZW4oZmlsZW5hbWUpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnY291bGQgbm90IHJlYWQgZG9jcyBmcm9tICVzXG4nICUgZmlsZW5hbWUpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBkaXZwYXQgPSByZS5jb21waWxlKCc8ZGl2W14+XSpuYXZpZ2F0Lio/PC9kaXZbXj5dKj4nLCByZS5JIHwgcmUuUykKICAgICAgICBhZGRycGF0ID0gcmUuY29tcGlsZSgnPGFkZHJlc3NbXj5dKj4uKj88L2FkZHJlc3NbXj5dKj4nLCByZS5JIHwgcmUuUykKICAgICAgICBkb2N1bWVudCA9IHJlLnN1YihhZGRycGF0LCAnJywgcmUuc3ViKGRpdnBhdCwgJycsIGZpbGUucmVhZCgpKSkKICAgICAgICBmaWxlLmNsb3NlKCkKCiAgICAgICAgaW1wb3J0IGh0bWxsaWIsIGZvcm1hdHRlciwgU3RyaW5nSU8KICAgICAgICBidWZmZXIgPSBTdHJpbmdJTy5TdHJpbmdJTygpCiAgICAgICAgcGFyc2VyID0gaHRtbGxpYi5IVE1MUGFyc2VyKAogICAgICAgICAgICBmb3JtYXR0ZXIuQWJzdHJhY3RGb3JtYXR0ZXIoZm9ybWF0dGVyLkR1bWJXcml0ZXIoYnVmZmVyKSkpCiAgICAgICAgcGFyc2VyLnN0YXJ0X3RhYmxlID0gcGFyc2VyLmRvX3AKICAgICAgICBwYXJzZXIuZW5kX3RhYmxlID0gbGFtYmRhIHBhcnNlcj1wYXJzZXI6IHBhcnNlci5kb19wKHt9KQogICAgICAgIHBhcnNlci5zdGFydF90ciA9IHBhcnNlci5kb19icgogICAgICAgIHBhcnNlci5zdGFydF90ZCA9IHBhcnNlci5zdGFydF90aCA9IGxhbWJkYSBhLCBiPWJ1ZmZlcjogYi53cml0ZSgnXHQnKQogICAgICAgIHBhcnNlci5mZWVkKGRvY3VtZW50KQogICAgICAgIGJ1ZmZlciA9IHJlcGxhY2UoYnVmZmVyLmdldHZhbHVlKCksICdceGEwJywgJyAnLCAnXG4nLCAnXG4gICcpCiAgICAgICAgcGFnZXIoJyAgJyArIHN0cmlwKGJ1ZmZlcikgKyAnXG4nKQogICAgICAgIGlmIHhyZWZzOiBzZWxmLm91dHB1dC53cml0ZSgnXG5SZWxhdGVkIGhlbHAgdG9waWNzOiAlc1xuJyAlIHhyZWZzKQoKICAgIGRlZiBsaXN0bW9kdWxlcyhzZWxmLCBrZXk9JycpOgogICAgICAgIGlmIGtleToKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnCkhlcmUgaXMgYSBsaXN0IG9mIG1hdGNoaW5nIG1vZHVsZXMuICBFbnRlciBhbnkgbW9kdWxlIG5hbWUgdG8gZ2V0IG1vcmUgaGVscC4KCicnJykKICAgICAgICAgICAgYXByb3BvcyhrZXkpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnClBsZWFzZSB3YWl0IGEgbW9tZW50IHdoaWxlIEkgZ2F0aGVyIGEgbGlzdCBvZiBhbGwgYXZhaWxhYmxlIG1vZHVsZXMuLi4KCicnJykKICAgICAgICAgICAgbW9kdWxlcyA9IHt9CiAgICAgICAgICAgIGRlZiBjYWxsYmFjayhwYXRoLCBtb2RuYW1lLCBkZXNjLCBtb2R1bGVzPW1vZHVsZXMpOgogICAgICAgICAgICAgICAgaWYgbW9kbmFtZSBhbmQgbW9kbmFtZVstOTpdID09ICcuX19pbml0X18nOgogICAgICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBtb2RuYW1lWzotOV0gKyAnIChwYWNrYWdlKScKICAgICAgICAgICAgICAgIGlmIGZpbmQobW9kbmFtZSwgJy4nKSA8IDA6CiAgICAgICAgICAgICAgICAgICAgbW9kdWxlc1ttb2RuYW1lXSA9IDEKICAgICAgICAgICAgTW9kdWxlU2Nhbm5lcigpLnJ1bihjYWxsYmFjaykKICAgICAgICAgICAgc2VsZi5saXN0KG1vZHVsZXMua2V5cygpKQogICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnJycKRW50ZXIgYW55IG1vZHVsZSBuYW1lIHRvIGdldCBtb3JlIGhlbHAuICBPciwgdHlwZSAibW9kdWxlcyBzcGFtIiB0byBzZWFyY2gKZm9yIG1vZHVsZXMgd2hvc2UgZGVzY3JpcHRpb25zIGNvbnRhaW4gdGhlIHdvcmQgInNwYW0iLgonJycpCgpoZWxwID0gSGVscGVyKHN5cy5zdGRpbiwgc3lzLnN0ZG91dCkKCmNsYXNzIFNjYW5uZXI6CiAgICAiIiJBIGdlbmVyaWMgdHJlZSBpdGVyYXRvci4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCByb290cywgY2hpbGRyZW4sIGRlc2NlbmRwKToKICAgICAgICBzZWxmLnJvb3RzID0gcm9vdHNbOl0KICAgICAgICBzZWxmLnN0YXRlID0gW10KICAgICAgICBzZWxmLmNoaWxkcmVuID0gY2hpbGRyZW4KICAgICAgICBzZWxmLmRlc2NlbmRwID0gZGVzY2VuZHAKCiAgICBkZWYgbmV4dChzZWxmKToKICAgICAgICBpZiBub3Qgc2VsZi5zdGF0ZToKICAgICAgICAgICAgaWYgbm90IHNlbGYucm9vdHM6CiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgICAgICByb290ID0gc2VsZi5yb290cy5wb3AoMCkKICAgICAgICAgICAgc2VsZi5zdGF0ZSA9IFsocm9vdCwgc2VsZi5jaGlsZHJlbihyb290KSldCiAgICAgICAgbm9kZSwgY2hpbGRyZW4gPSBzZWxmLnN0YXRlWy0xXQogICAgICAgIGlmIG5vdCBjaGlsZHJlbjoKICAgICAgICAgICAgc2VsZi5zdGF0ZS5wb3AoKQogICAgICAgICAgICByZXR1cm4gc2VsZi5uZXh0KCkKICAgICAgICBjaGlsZCA9IGNoaWxkcmVuLnBvcCgwKQogICAgICAgIGlmIHNlbGYuZGVzY2VuZHAoY2hpbGQpOgogICAgICAgICAgICBzZWxmLnN0YXRlLmFwcGVuZCgoY2hpbGQsIHNlbGYuY2hpbGRyZW4oY2hpbGQpKSkKICAgICAgICByZXR1cm4gY2hpbGQKCmNsYXNzIE1vZHVsZVNjYW5uZXIoU2Nhbm5lcik6CiAgICAiIiJBbiBpbnRlcnJ1cHRpYmxlIHNjYW5uZXIgdGhhdCBzZWFyY2hlcyBtb2R1bGUgc3lub3BzZXMuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgcm9vdHMgPSBtYXAobGFtYmRhIGRpcjogKGRpciwgJycpLCBwYXRoZGlycygpKQogICAgICAgIFNjYW5uZXIuX19pbml0X18oc2VsZiwgcm9vdHMsIHNlbGYuc3VibW9kdWxlcywgc2VsZi5pc3BhY2thZ2UpCgogICAgZGVmIHN1Ym1vZHVsZXMoc2VsZiwgKGRpciwgcGFja2FnZSkpOgogICAgICAgIGNoaWxkcmVuID0gW10KICAgICAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKGRpcik6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oZGlyLCBmaWxlKQogICAgICAgICAgICBpZiBpc3BhY2thZ2UocGF0aCk6CiAgICAgICAgICAgICAgICBjaGlsZHJlbi5hcHBlbmQoKHBhdGgsIHBhY2thZ2UgKyAocGFja2FnZSBhbmQgJy4nKSArIGZpbGUpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgY2hpbGRyZW4uYXBwZW5kKChwYXRoLCBwYWNrYWdlKSkKICAgICAgICBjaGlsZHJlbi5zb3J0KCkgIyBzbyB0aGF0IHNwYW0ucHkgY29tZXMgYmVmb3JlIHNwYW0ucHljIG9yIHNwYW0ucHlvCiAgICAgICAgcmV0dXJuIGNoaWxkcmVuCgogICAgZGVmIGlzcGFja2FnZShzZWxmLCAoZGlyLCBwYWNrYWdlKSk6CiAgICAgICAgcmV0dXJuIGlzcGFja2FnZShkaXIpCgogICAgZGVmIHJ1bihzZWxmLCBjYWxsYmFjaywga2V5PU5vbmUsIGNvbXBsZXRlcj1Ob25lKToKICAgICAgICBpZiBrZXk6IGtleSA9IGxvd2VyKGtleSkKICAgICAgICBzZWxmLnF1aXQgPSAwCiAgICAgICAgc2VlbiA9IHt9CgogICAgICAgIGZvciBtb2RuYW1lIGluIHN5cy5idWlsdGluX21vZHVsZV9uYW1lczoKICAgICAgICAgICAgaWYgbW9kbmFtZSAhPSAnX19tYWluX18nOgogICAgICAgICAgICAgICAgc2Vlblttb2RuYW1lXSA9IDEKICAgICAgICAgICAgICAgIGlmIGtleSBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKE5vbmUsIG1vZG5hbWUsICcnKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBkZXNjID0gc3BsaXQoZnJlc2hpbXBvcnQobW9kbmFtZSkuX19kb2NfXyBvciAnJywgJ1xuJylbMF0KICAgICAgICAgICAgICAgICAgICBpZiBmaW5kKGxvd2VyKG1vZG5hbWUgKyAnIC0gJyArIGRlc2MpLCBrZXkpID49IDA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKE5vbmUsIG1vZG5hbWUsIGRlc2MpCgogICAgICAgIHdoaWxlIG5vdCBzZWxmLnF1aXQ6CiAgICAgICAgICAgIG5vZGUgPSBzZWxmLm5leHQoKQogICAgICAgICAgICBpZiBub3Qgbm9kZTogYnJlYWsKICAgICAgICAgICAgcGF0aCwgcGFja2FnZSA9IG5vZGUKICAgICAgICAgICAgbW9kbmFtZSA9IGluc3BlY3QuZ2V0bW9kdWxlbmFtZShwYXRoKQogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZmlsZShwYXRoKSBhbmQgbW9kbmFtZToKICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBwYWNrYWdlICsgKHBhY2thZ2UgYW5kICcuJykgKyBtb2RuYW1lCiAgICAgICAgICAgICAgICBpZiBub3Qgc2Vlbi5oYXNfa2V5KG1vZG5hbWUpOgogICAgICAgICAgICAgICAgICAgIHNlZW5bbW9kbmFtZV0gPSAxICMgaWYgd2Ugc2VlIHNwYW0ucHksIHNraXAgc3BhbS5weWMKICAgICAgICAgICAgICAgICAgICBpZiBrZXkgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2socGF0aCwgbW9kbmFtZSwgJycpCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgZGVzYyA9IHN5bm9wc2lzKHBhdGgpIG9yICcnCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGZpbmQobG93ZXIobW9kbmFtZSArICcgLSAnICsgZGVzYyksIGtleSkgPj0gMDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHBhdGgsIG1vZG5hbWUsIGRlc2MpCiAgICAgICAgaWYgY29tcGxldGVyOiBjb21wbGV0ZXIoKQoKZGVmIGFwcm9wb3Moa2V5KToKICAgICIiIlByaW50IGFsbCB0aGUgb25lLWxpbmUgbW9kdWxlIHN1bW1hcmllcyB0aGF0IGNvbnRhaW4gYSBzdWJzdHJpbmcuIiIiCiAgICBkZWYgY2FsbGJhY2socGF0aCwgbW9kbmFtZSwgZGVzYyk6CiAgICAgICAgaWYgbW9kbmFtZVstOTpdID09ICcuX19pbml0X18nOgogICAgICAgICAgICBtb2RuYW1lID0gbW9kbmFtZVs6LTldICsgJyAocGFja2FnZSknCiAgICAgICAgcHJpbnQgbW9kbmFtZSwgZGVzYyBhbmQgJy0gJyArIGRlc2MKICAgIHRyeTogaW1wb3J0IHdhcm5pbmdzCiAgICBleGNlcHQgSW1wb3J0RXJyb3I6IHBhc3MKICAgIGVsc2U6IHdhcm5pbmdzLmZpbHRlcndhcm5pbmdzKCdpZ25vcmUnKSAjIGlnbm9yZSBwcm9ibGVtcyBkdXJpbmcgaW1wb3J0CiAgICBNb2R1bGVTY2FubmVyKCkucnVuKGNhbGxiYWNrLCBrZXkpCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB3ZWIgYnJvd3NlciBpbnRlcmZhY2UKCmRlZiBzZXJ2ZShwb3J0LCBjYWxsYmFjaz1Ob25lLCBjb21wbGV0ZXI9Tm9uZSk6CiAgICBpbXBvcnQgQmFzZUhUVFBTZXJ2ZXIsIG1pbWV0b29scywgc2VsZWN0CgogICAgIyBQYXRjaCB1cCBtaW1ldG9vbHMuTWVzc2FnZSBzbyBpdCBkb2Vzbid0IGJyZWFrIGlmIHJmYzgyMiBpcyByZWxvYWRlZC4KICAgIGNsYXNzIE1lc3NhZ2UobWltZXRvb2xzLk1lc3NhZ2UpOgogICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmcCwgc2Vla2FibGU9MSk6CiAgICAgICAgICAgIE1lc3NhZ2UgPSBzZWxmLl9fY2xhc3NfXwogICAgICAgICAgICBNZXNzYWdlLl9fYmFzZXNfX1swXS5fX2Jhc2VzX19bMF0uX19pbml0X18oc2VsZiwgZnAsIHNlZWthYmxlKQogICAgICAgICAgICBzZWxmLmVuY29kaW5naGVhZGVyID0gc2VsZi5nZXRoZWFkZXIoJ2NvbnRlbnQtdHJhbnNmZXItZW5jb2RpbmcnKQogICAgICAgICAgICBzZWxmLnR5cGVoZWFkZXIgPSBzZWxmLmdldGhlYWRlcignY29udGVudC10eXBlJykKICAgICAgICAgICAgc2VsZi5wYXJzZXR5cGUoKQogICAgICAgICAgICBzZWxmLnBhcnNlcGxpc3QoKQoKICAgIGNsYXNzIERvY0hhbmRsZXIoQmFzZUhUVFBTZXJ2ZXIuQmFzZUhUVFBSZXF1ZXN0SGFuZGxlcik6CiAgICAgICAgZGVmIHNlbmRfZG9jdW1lbnQoc2VsZiwgdGl0bGUsIGNvbnRlbnRzKToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2VsZi5zZW5kX3Jlc3BvbnNlKDIwMCkKICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoJ0NvbnRlbnQtVHlwZScsICd0ZXh0L2h0bWwnKQogICAgICAgICAgICAgICAgc2VsZi5lbmRfaGVhZGVycygpCiAgICAgICAgICAgICAgICBzZWxmLndmaWxlLndyaXRlKGh0bWwucGFnZSh0aXRsZSwgY29udGVudHMpKQogICAgICAgICAgICBleGNlcHQgSU9FcnJvcjogcGFzcwoKICAgICAgICBkZWYgZG9fR0VUKHNlbGYpOgogICAgICAgICAgICBwYXRoID0gc2VsZi5wYXRoCiAgICAgICAgICAgIGlmIHBhdGhbLTU6XSA9PSAnLmh0bWwnOiBwYXRoID0gcGF0aFs6LTVdCiAgICAgICAgICAgIGlmIHBhdGhbOjFdID09ICcvJzogcGF0aCA9IHBhdGhbMTpdCiAgICAgICAgICAgIGlmIHBhdGggYW5kIHBhdGggIT0gJy4nOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIG9iaiA9IGxvY2F0ZShwYXRoKQogICAgICAgICAgICAgICAgZXhjZXB0IEVycm9yRHVyaW5nSW1wb3J0LCB2YWx1ZToKICAgICAgICAgICAgICAgICAgICBzZWxmLnNlbmRfZG9jdW1lbnQocGF0aCwgaHRtbC5lc2NhcGUoc3RyKHZhbHVlKSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICBpZiBvYmo6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZW5kX2RvY3VtZW50KGRlc2NyaWJlKG9iaiksIGh0bWwuZG9jdW1lbnQob2JqLCBwYXRoKSkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZW5kX2RvY3VtZW50KHBhdGgsCidubyBQeXRob24gZG9jdW1lbnRhdGlvbiBmb3VuZCBmb3IgJXMnICUgcmVwcihwYXRoKSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGhlYWRpbmcgPSBodG1sLmhlYWRpbmcoCic8YmlnPjxiaWc+PHN0cm9uZz5QeXRob246IEluZGV4IG9mIE1vZHVsZXM8L3N0cm9uZz48L2JpZz48L2JpZz4nLAonI2ZmZmZmZicsICcjNzc5OWVlJykKICAgICAgICAgICAgICAgIGRlZiBibHRpbmxpbmsobmFtZSk6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICc8YSBocmVmPSIlcy5odG1sIj4lczwvYT4nICUgKG5hbWUsIG5hbWUpCiAgICAgICAgICAgICAgICBuYW1lcyA9IGZpbHRlcihsYW1iZGEgeDogeCAhPSAnX19tYWluX18nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzLmJ1aWx0aW5fbW9kdWxlX25hbWVzKQogICAgICAgICAgICAgICAgY29udGVudHMgPSBodG1sLm11bHRpY29sdW1uKG5hbWVzLCBibHRpbmxpbmspCiAgICAgICAgICAgICAgICBpbmRpY2VzID0gWyc8cD4nICsgaHRtbC5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgICAgICdCdWlsdC1pbiBNb2R1bGVzJywgJyNmZmZmZmYnLCAnI2VlNzdhYScsIGNvbnRlbnRzKV0KCiAgICAgICAgICAgICAgICBzZWVuID0ge30KICAgICAgICAgICAgICAgIGZvciBkaXIgaW4gcGF0aGRpcnMoKToKICAgICAgICAgICAgICAgICAgICBpbmRpY2VzLmFwcGVuZChodG1sLmluZGV4KGRpciwgc2VlbikpCiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGhlYWRpbmcgKyBqb2luKGluZGljZXMpICsgJycnPHAgYWxpZ249cmlnaHQ+CjxzbWFsbD48c21hbGw+PGZvbnQgY29sb3I9IiM5MDkwOTAiIGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPjxzdHJvbmc+CnB5ZG9jPC9zdHJvbmc+IGJ5IEthLVBpbmcgWWVlICZsdDtwaW5nQGxmdy5vcmcmZ3Q7PC9mb250Pjwvc21hbGw+PC9zbWFsbD4nJycKICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9kb2N1bWVudCgnSW5kZXggb2YgTW9kdWxlcycsIGNvbnRlbnRzKQoKICAgICAgICBkZWYgbG9nX21lc3NhZ2Uoc2VsZiwgKmFyZ3MpOiBwYXNzCgogICAgY2xhc3MgRG9jU2VydmVyKEJhc2VIVFRQU2VydmVyLkhUVFBTZXJ2ZXIpOgogICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBwb3J0LCBjYWxsYmFjayk6CiAgICAgICAgICAgIGhvc3QgPSAoc3lzLnBsYXRmb3JtID09ICdtYWMnKSBhbmQgJzEyNy4wLjAuMScgb3IgJ2xvY2FsaG9zdCcKICAgICAgICAgICAgc2VsZi5hZGRyZXNzID0gKCcnLCBwb3J0KQogICAgICAgICAgICBzZWxmLnVybCA9ICdodHRwOi8vJXM6JWQvJyAlIChob3N0LCBwb3J0KQogICAgICAgICAgICBzZWxmLmNhbGxiYWNrID0gY2FsbGJhY2sKICAgICAgICAgICAgc2VsZi5iYXNlLl9faW5pdF9fKHNlbGYsIHNlbGYuYWRkcmVzcywgc2VsZi5oYW5kbGVyKQoKICAgICAgICBkZWYgc2VydmVfdW50aWxfcXVpdChzZWxmKToKICAgICAgICAgICAgaW1wb3J0IHNlbGVjdAogICAgICAgICAgICBzZWxmLnF1aXQgPSAwCiAgICAgICAgICAgIHdoaWxlIG5vdCBzZWxmLnF1aXQ6CiAgICAgICAgICAgICAgICByZCwgd3IsIGV4ID0gc2VsZWN0LnNlbGVjdChbc2VsZi5zb2NrZXQuZmlsZW5vKCldLCBbXSwgW10sIDEpCiAgICAgICAgICAgICAgICBpZiByZDogc2VsZi5oYW5kbGVfcmVxdWVzdCgpCgogICAgICAgIGRlZiBzZXJ2ZXJfYWN0aXZhdGUoc2VsZik6CiAgICAgICAgICAgIHNlbGYuYmFzZS5zZXJ2ZXJfYWN0aXZhdGUoc2VsZikKICAgICAgICAgICAgaWYgc2VsZi5jYWxsYmFjazogc2VsZi5jYWxsYmFjayhzZWxmKQoKICAgIERvY1NlcnZlci5iYXNlID0gQmFzZUhUVFBTZXJ2ZXIuSFRUUFNlcnZlcgogICAgRG9jU2VydmVyLmhhbmRsZXIgPSBEb2NIYW5kbGVyCiAgICBEb2NIYW5kbGVyLk1lc3NhZ2VDbGFzcyA9IE1lc3NhZ2UKICAgIHRyeToKICAgICAgICB0cnk6CiAgICAgICAgICAgIERvY1NlcnZlcihwb3J0LCBjYWxsYmFjaykuc2VydmVfdW50aWxfcXVpdCgpCiAgICAgICAgZXhjZXB0IChLZXlib2FyZEludGVycnVwdCwgc2VsZWN0LmVycm9yKToKICAgICAgICAgICAgcGFzcwogICAgZmluYWxseToKICAgICAgICBpZiBjb21wbGV0ZXI6IGNvbXBsZXRlcigpCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGdyYXBoaWNhbCBpbnRlcmZhY2UKCmRlZiBndWkoKToKICAgICIiIkdyYXBoaWNhbCBpbnRlcmZhY2UgKHN0YXJ0cyB3ZWIgc2VydmVyIGFuZCBwb3BzIHVwIGEgY29udHJvbCB3aW5kb3cpLiIiIgogICAgY2xhc3MgR1VJOgogICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCB3aW5kb3csIHBvcnQ9NzQ2NCk6CiAgICAgICAgICAgIHNlbGYud2luZG93ID0gd2luZG93CiAgICAgICAgICAgIHNlbGYuc2VydmVyID0gTm9uZQogICAgICAgICAgICBzZWxmLnNjYW5uZXIgPSBOb25lCgogICAgICAgICAgICBpbXBvcnQgVGtpbnRlcgogICAgICAgICAgICBzZWxmLnNlcnZlcl9mcm0gPSBUa2ludGVyLkZyYW1lKHdpbmRvdykKICAgICAgICAgICAgc2VsZi50aXRsZV9sYmwgPSBUa2ludGVyLkxhYmVsKHNlbGYuc2VydmVyX2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J1N0YXJ0aW5nIHNlcnZlci4uLlxuICcpCiAgICAgICAgICAgIHNlbGYub3Blbl9idG4gPSBUa2ludGVyLkJ1dHRvbihzZWxmLnNlcnZlcl9mcm0sCiAgICAgICAgICAgICAgICB0ZXh0PSdvcGVuIGJyb3dzZXInLCBjb21tYW5kPXNlbGYub3Blbiwgc3RhdGU9J2Rpc2FibGVkJykKICAgICAgICAgICAgc2VsZi5xdWl0X2J0biA9IFRraW50ZXIuQnV0dG9uKHNlbGYuc2VydmVyX2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J3F1aXQgc2VydmluZycsIGNvbW1hbmQ9c2VsZi5xdWl0LCBzdGF0ZT0nZGlzYWJsZWQnKQoKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZnJtID0gVGtpbnRlci5GcmFtZSh3aW5kb3cpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibCA9IFRraW50ZXIuTGFiZWwoc2VsZi5zZWFyY2hfZnJtLCB0ZXh0PSdTZWFyY2ggZm9yJykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50ID0gVGtpbnRlci5FbnRyeShzZWxmLnNlYXJjaF9mcm0pCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudC5iaW5kKCc8UmV0dXJuPicsIHNlbGYuc2VhcmNoKQogICAgICAgICAgICBzZWxmLnN0b3BfYnRuID0gVGtpbnRlci5CdXR0b24oc2VsZi5zZWFyY2hfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0nc3RvcCcsIHBhZHk9MCwgY29tbWFuZD1zZWxmLnN0b3AsIHN0YXRlPSdkaXNhYmxlZCcpCiAgICAgICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInOgogICAgICAgICAgICAgICAgIyBUcnlpbmcgdG8gaGlkZSBhbmQgc2hvdyB0aGlzIGJ1dHRvbiBjcmFzaGVzIHVuZGVyIFdpbmRvd3MuCiAgICAgICAgICAgICAgICBzZWxmLnN0b3BfYnRuLnBhY2soc2lkZT0ncmlnaHQnKQoKICAgICAgICAgICAgc2VsZi53aW5kb3cudGl0bGUoJ3B5ZG9jJykKICAgICAgICAgICAgc2VsZi53aW5kb3cucHJvdG9jb2woJ1dNX0RFTEVURV9XSU5ET1cnLCBzZWxmLnF1aXQpCiAgICAgICAgICAgIHNlbGYudGl0bGVfbGJsLnBhY2soc2lkZT0ndG9wJywgZmlsbD0neCcpCiAgICAgICAgICAgIHNlbGYub3Blbl9idG4ucGFjayhzaWRlPSdsZWZ0JywgZmlsbD0neCcsIGV4cGFuZD0xKQogICAgICAgICAgICBzZWxmLnF1aXRfYnRuLnBhY2soc2lkZT0ncmlnaHQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCiAgICAgICAgICAgIHNlbGYuc2VydmVyX2ZybS5wYWNrKHNpZGU9J3RvcCcsIGZpbGw9J3gnKQoKICAgICAgICAgICAgc2VsZi5zZWFyY2hfbGJsLnBhY2soc2lkZT0nbGVmdCcpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudC5wYWNrKHNpZGU9J3JpZ2h0JywgZmlsbD0neCcsIGV4cGFuZD0xKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9mcm0ucGFjayhzaWRlPSd0b3AnLCBmaWxsPSd4JykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50LmZvY3VzX3NldCgpCgogICAgICAgICAgICBmb250ID0gKCdoZWx2ZXRpY2EnLCBzeXMucGxhdGZvcm0gPT0gJ3dpbjMyJyBhbmQgOCBvciAxMCkKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0ID0gVGtpbnRlci5MaXN0Ym94KHdpbmRvdywgZm9udD1mb250LCBoZWlnaHQ9NikKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmJpbmQoJzxCdXR0b24tMT4nLCBzZWxmLnNlbGVjdCkKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmJpbmQoJzxEb3VibGUtQnV0dG9uLTE+Jywgc2VsZi5nb3RvKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9zY3IgPSBUa2ludGVyLlNjcm9sbGJhcih3aW5kb3csCiAgICAgICAgICAgICAgICBvcmllbnQ9J3ZlcnRpY2FsJywgY29tbWFuZD1zZWxmLnJlc3VsdF9sc3QueXZpZXcpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5jb25maWcoeXNjcm9sbGNvbW1hbmQ9c2VsZi5yZXN1bHRfc2NyLnNldCkKCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2ZybSA9IFRraW50ZXIuRnJhbWUod2luZG93KQogICAgICAgICAgICBzZWxmLmdvdG9fYnRuID0gVGtpbnRlci5CdXR0b24oc2VsZi5yZXN1bHRfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0nZ28gdG8gc2VsZWN0ZWQnLCBjb21tYW5kPXNlbGYuZ290bykKICAgICAgICAgICAgc2VsZi5oaWRlX2J0biA9IFRraW50ZXIuQnV0dG9uKHNlbGYucmVzdWx0X2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J2hpZGUgcmVzdWx0cycsIGNvbW1hbmQ9c2VsZi5oaWRlKQogICAgICAgICAgICBzZWxmLmdvdG9fYnRuLnBhY2soc2lkZT0nbGVmdCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKICAgICAgICAgICAgc2VsZi5oaWRlX2J0bi5wYWNrKHNpZGU9J3JpZ2h0JywgZmlsbD0neCcsIGV4cGFuZD0xKQoKICAgICAgICAgICAgc2VsZi53aW5kb3cudXBkYXRlKCkKICAgICAgICAgICAgc2VsZi5taW53aWR0aCA9IHNlbGYud2luZG93LndpbmZvX3dpZHRoKCkKICAgICAgICAgICAgc2VsZi5taW5oZWlnaHQgPSBzZWxmLndpbmRvdy53aW5mb19oZWlnaHQoKQogICAgICAgICAgICBzZWxmLmJpZ21pbmhlaWdodCA9IChzZWxmLnNlcnZlcl9mcm0ud2luZm9fcmVxaGVpZ2h0KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnNlYXJjaF9mcm0ud2luZm9fcmVxaGVpZ2h0KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3Qud2luZm9fcmVxaGVpZ2h0KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnJlc3VsdF9mcm0ud2luZm9fcmVxaGVpZ2h0KCkpCiAgICAgICAgICAgIHNlbGYuYmlnd2lkdGgsIHNlbGYuYmlnaGVpZ2h0ID0gc2VsZi5taW53aWR0aCwgc2VsZi5iaWdtaW5oZWlnaHQKICAgICAgICAgICAgc2VsZi5leHBhbmRlZCA9IDAKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fZ2VvbWV0cnkoJyVkeCVkJyAlIChzZWxmLm1pbndpZHRoLCBzZWxmLm1pbmhlaWdodCkpCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX21pbnNpemUoc2VsZi5taW53aWR0aCwgc2VsZi5taW5oZWlnaHQpCgogICAgICAgICAgICBpbXBvcnQgdGhyZWFkaW5nCiAgICAgICAgICAgIHRocmVhZGluZy5UaHJlYWQoCiAgICAgICAgICAgICAgICB0YXJnZXQ9c2VydmUsIGFyZ3M9KHBvcnQsIHNlbGYucmVhZHksIHNlbGYucXVpdCkpLnN0YXJ0KCkKCiAgICAgICAgZGVmIHJlYWR5KHNlbGYsIHNlcnZlcik6CiAgICAgICAgICAgIHNlbGYuc2VydmVyID0gc2VydmVyCiAgICAgICAgICAgIHNlbGYudGl0bGVfbGJsLmNvbmZpZygKICAgICAgICAgICAgICAgIHRleHQ9J1B5dGhvbiBkb2N1bWVudGF0aW9uIHNlcnZlciBhdFxuJyArIHNlcnZlci51cmwpCiAgICAgICAgICAgIHNlbGYub3Blbl9idG4uY29uZmlnKHN0YXRlPSdub3JtYWwnKQogICAgICAgICAgICBzZWxmLnF1aXRfYnRuLmNvbmZpZyhzdGF0ZT0nbm9ybWFsJykKCiAgICAgICAgZGVmIG9wZW4oc2VsZiwgZXZlbnQ9Tm9uZSwgdXJsPU5vbmUpOgogICAgICAgICAgICB1cmwgPSB1cmwgb3Igc2VsZi5zZXJ2ZXIudXJsCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGltcG9ydCB3ZWJicm93c2VyCiAgICAgICAgICAgICAgICB3ZWJicm93c2VyLm9wZW4odXJsKQogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6ICMgcHJlLXdlYmJyb3dzZXIucHkgY29tcGF0aWJpbGl0eQogICAgICAgICAgICAgICAgaWYgc3lzLnBsYXRmb3JtID09ICd3aW4zMic6CiAgICAgICAgICAgICAgICAgICAgb3Muc3lzdGVtKCdzdGFydCAiJXMiJyAlIHVybCkKICAgICAgICAgICAgICAgIGVsaWYgc3lzLnBsYXRmb3JtID09ICdtYWMnOgogICAgICAgICAgICAgICAgICAgIHRyeTogaW1wb3J0IGljCiAgICAgICAgICAgICAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOiBwYXNzCiAgICAgICAgICAgICAgICAgICAgZWxzZTogaWMubGF1bmNodXJsKHVybCkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgcmMgPSBvcy5zeXN0ZW0oJ25ldHNjYXBlIC1yZW1vdGUgIm9wZW5VUkwoJXMpIiAmJyAlIHVybCkKICAgICAgICAgICAgICAgICAgICBpZiByYzogb3Muc3lzdGVtKCduZXRzY2FwZSAiJXMiICYnICUgdXJsKQoKICAgICAgICBkZWYgcXVpdChzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgaWYgc2VsZi5zZXJ2ZXI6CiAgICAgICAgICAgICAgICBzZWxmLnNlcnZlci5xdWl0ID0gMQogICAgICAgICAgICBzZWxmLndpbmRvdy5xdWl0KCkKCiAgICAgICAgZGVmIHNlYXJjaChzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAga2V5ID0gc2VsZi5zZWFyY2hfZW50LmdldCgpCiAgICAgICAgICAgIHNlbGYuc3RvcF9idG4ucGFjayhzaWRlPSdyaWdodCcpCiAgICAgICAgICAgIHNlbGYuc3RvcF9idG4uY29uZmlnKHN0YXRlPSdub3JtYWwnKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwuY29uZmlnKHRleHQ9J1NlYXJjaGluZyBmb3IgIiVzIi4uLicgJSBrZXkpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudC5mb3JnZXQoKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwucGFjayhzaWRlPSdsZWZ0JykKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmRlbGV0ZSgwLCAnZW5kJykKICAgICAgICAgICAgc2VsZi5nb3RvX2J0bi5jb25maWcoc3RhdGU9J2Rpc2FibGVkJykKICAgICAgICAgICAgc2VsZi5leHBhbmQoKQoKICAgICAgICAgICAgaW1wb3J0IHRocmVhZGluZwogICAgICAgICAgICBpZiBzZWxmLnNjYW5uZXI6CiAgICAgICAgICAgICAgICBzZWxmLnNjYW5uZXIucXVpdCA9IDEKICAgICAgICAgICAgc2VsZi5zY2FubmVyID0gTW9kdWxlU2Nhbm5lcigpCiAgICAgICAgICAgIHRocmVhZGluZy5UaHJlYWQodGFyZ2V0PXNlbGYuc2Nhbm5lci5ydW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJncz0oc2VsZi51cGRhdGUsIGtleSwgc2VsZi5kb25lKSkuc3RhcnQoKQoKICAgICAgICBkZWYgdXBkYXRlKHNlbGYsIHBhdGgsIG1vZG5hbWUsIGRlc2MpOgogICAgICAgICAgICBpZiBtb2RuYW1lWy05Ol0gPT0gJy5fX2luaXRfXyc6CiAgICAgICAgICAgICAgICBtb2RuYW1lID0gbW9kbmFtZVs6LTldICsgJyAocGFja2FnZSknCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5pbnNlcnQoJ2VuZCcsCiAgICAgICAgICAgICAgICBtb2RuYW1lICsgJyAtICcgKyAoZGVzYyBvciAnKG5vIGRlc2NyaXB0aW9uKScpKQoKICAgICAgICBkZWYgc3RvcChzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgaWYgc2VsZi5zY2FubmVyOgogICAgICAgICAgICAgICAgc2VsZi5zY2FubmVyLnF1aXQgPSAxCiAgICAgICAgICAgICAgICBzZWxmLnNjYW5uZXIgPSBOb25lCgogICAgICAgIGRlZiBkb25lKHNlbGYpOgogICAgICAgICAgICBzZWxmLnNjYW5uZXIgPSBOb25lCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibC5jb25maWcodGV4dD0nU2VhcmNoIGZvcicpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibC5wYWNrKHNpZGU9J2xlZnQnKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQucGFjayhzaWRlPSdyaWdodCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKICAgICAgICAgICAgaWYgc3lzLnBsYXRmb3JtICE9ICd3aW4zMic6IHNlbGYuc3RvcF9idG4uZm9yZ2V0KCkKICAgICAgICAgICAgc2VsZi5zdG9wX2J0bi5jb25maWcoc3RhdGU9J2Rpc2FibGVkJykKCiAgICAgICAgZGVmIHNlbGVjdChzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgc2VsZi5nb3RvX2J0bi5jb25maWcoc3RhdGU9J25vcm1hbCcpCgogICAgICAgIGRlZiBnb3RvKHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBzZWxlY3Rpb24gPSBzZWxmLnJlc3VsdF9sc3QuY3Vyc2VsZWN0aW9uKCkKICAgICAgICAgICAgaWYgc2VsZWN0aW9uOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IHNwbGl0KHNlbGYucmVzdWx0X2xzdC5nZXQoc2VsZWN0aW9uWzBdKSlbMF0KICAgICAgICAgICAgICAgIHNlbGYub3Blbih1cmw9c2VsZi5zZXJ2ZXIudXJsICsgbW9kbmFtZSArICcuaHRtbCcpCgogICAgICAgIGRlZiBjb2xsYXBzZShzZWxmKToKICAgICAgICAgICAgaWYgbm90IHNlbGYuZXhwYW5kZWQ6IHJldHVybgogICAgICAgICAgICBzZWxmLnJlc3VsdF9mcm0uZm9yZ2V0KCkKICAgICAgICAgICAgc2VsZi5yZXN1bHRfc2NyLmZvcmdldCgpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5mb3JnZXQoKQogICAgICAgICAgICBzZWxmLmJpZ3dpZHRoID0gc2VsZi53aW5kb3cud2luZm9fd2lkdGgoKQogICAgICAgICAgICBzZWxmLmJpZ2hlaWdodCA9IHNlbGYud2luZG93LndpbmZvX2hlaWdodCgpCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX2dlb21ldHJ5KCclZHglZCcgJSAoc2VsZi5taW53aWR0aCwgc2VsZi5taW5oZWlnaHQpKQogICAgICAgICAgICBzZWxmLndpbmRvdy53bV9taW5zaXplKHNlbGYubWlud2lkdGgsIHNlbGYubWluaGVpZ2h0KQogICAgICAgICAgICBzZWxmLmV4cGFuZGVkID0gMAoKICAgICAgICBkZWYgZXhwYW5kKHNlbGYpOgogICAgICAgICAgICBpZiBzZWxmLmV4cGFuZGVkOiByZXR1cm4KICAgICAgICAgICAgc2VsZi5yZXN1bHRfZnJtLnBhY2soc2lkZT0nYm90dG9tJywgZmlsbD0neCcpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X3Njci5wYWNrKHNpZGU9J3JpZ2h0JywgZmlsbD0neScpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5wYWNrKHNpZGU9J3RvcCcsIGZpbGw9J2JvdGgnLCBleHBhbmQ9MSkKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fZ2VvbWV0cnkoJyVkeCVkJyAlIChzZWxmLmJpZ3dpZHRoLCBzZWxmLmJpZ2hlaWdodCkpCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX21pbnNpemUoc2VsZi5taW53aWR0aCwgc2VsZi5iaWdtaW5oZWlnaHQpCiAgICAgICAgICAgIHNlbGYuZXhwYW5kZWQgPSAxCgogICAgICAgIGRlZiBoaWRlKHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBzZWxmLnN0b3AoKQogICAgICAgICAgICBzZWxmLmNvbGxhcHNlKCkKCiAgICBpbXBvcnQgVGtpbnRlcgogICAgdHJ5OgogICAgICAgIGd1aSA9IEdVSShUa2ludGVyLlRrKCkpCiAgICAgICAgVGtpbnRlci5tYWlubG9vcCgpCiAgICBleGNlcHQgS2V5Ym9hcmRJbnRlcnJ1cHQ6CiAgICAgICAgcGFzcwoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBjb21tYW5kLWxpbmUgaW50ZXJmYWNlCgpkZWYgaXNwYXRoKHgpOgogICAgcmV0dXJuIHR5cGUoeCkgaXMgdHlwZXMuU3RyaW5nVHlwZSBhbmQgZmluZCh4LCBvcy5zZXApID49IDAKCmRlZiBjbGkoKToKICAgICIiIkNvbW1hbmQtbGluZSBpbnRlcmZhY2UgKGxvb2tzIGF0IHN5cy5hcmd2IHRvIGRlY2lkZSB3aGF0IHRvIGRvKS4iIiIKICAgIGltcG9ydCBnZXRvcHQKICAgIGNsYXNzIEJhZFVzYWdlOiBwYXNzCgogICAgIyBTY3JpcHRzIGRvbid0IGdldCB0aGUgY3VycmVudCBkaXJlY3RvcnkgaW4gdGhlaXIgcGF0aCBieSBkZWZhdWx0LgogICAgc2NyaXB0ZGlyID0gb3MucGF0aC5kaXJuYW1lKHN5cy5hcmd2WzBdKQogICAgaWYgc2NyaXB0ZGlyIGluIHN5cy5wYXRoOgogICAgICAgIHN5cy5wYXRoLnJlbW92ZShzY3JpcHRkaXIpCiAgICBzeXMucGF0aC5pbnNlcnQoMCwgJy4nKQoKICAgIHRyeToKICAgICAgICBvcHRzLCBhcmdzID0gZ2V0b3B0LmdldG9wdChzeXMuYXJndlsxOl0sICdnazpwOncnKQogICAgICAgIHdyaXRpbmcgPSAwCgogICAgICAgIGZvciBvcHQsIHZhbCBpbiBvcHRzOgogICAgICAgICAgICBpZiBvcHQgPT0gJy1nJzoKICAgICAgICAgICAgICAgIGd1aSgpCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgaWYgb3B0ID09ICctayc6CiAgICAgICAgICAgICAgICBhcHJvcG9zKHZhbCkKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBpZiBvcHQgPT0gJy1wJzoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBwb3J0ID0gaW50KHZhbCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIEJhZFVzYWdlCiAgICAgICAgICAgICAgICBkZWYgcmVhZHkoc2VydmVyKToKICAgICAgICAgICAgICAgICAgICBwcmludCAncHlkb2Mgc2VydmVyIHJlYWR5IGF0ICVzJyAlIHNlcnZlci51cmwKICAgICAgICAgICAgICAgIGRlZiBzdG9wcGVkKCk6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgJ3B5ZG9jIHNlcnZlciBzdG9wcGVkJwogICAgICAgICAgICAgICAgc2VydmUocG9ydCwgcmVhZHksIHN0b3BwZWQpCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgaWYgb3B0ID09ICctdyc6CiAgICAgICAgICAgICAgICB3cml0aW5nID0gMQoKICAgICAgICBpZiBub3QgYXJnczogcmFpc2UgQmFkVXNhZ2UKICAgICAgICBmb3IgYXJnIGluIGFyZ3M6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGlmIGlzcGF0aChhcmcpIGFuZCBvcy5wYXRoLmlzZmlsZShhcmcpOgogICAgICAgICAgICAgICAgICAgIGFyZyA9IGltcG9ydGZpbGUoYXJnKQogICAgICAgICAgICAgICAgaWYgd3JpdGluZzoKICAgICAgICAgICAgICAgICAgICBpZiBpc3BhdGgoYXJnKSBhbmQgb3MucGF0aC5pc2RpcihhcmcpOgogICAgICAgICAgICAgICAgICAgICAgICB3cml0ZWRvY3MoYXJnKQogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlZG9jKGFyZykKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgZG9jKGFyZykKICAgICAgICAgICAgZXhjZXB0IEVycm9yRHVyaW5nSW1wb3J0LCB2YWx1ZToKICAgICAgICAgICAgICAgIHByaW50IHZhbHVlCgogICAgZXhjZXB0IChnZXRvcHQuZXJyb3IsIEJhZFVzYWdlKToKICAgICAgICBjbWQgPSBzeXMuYXJndlswXQogICAgICAgIHByaW50ICIiInB5ZG9jIC0gdGhlIFB5dGhvbiBkb2N1bWVudGF0aW9uIHRvb2wKCiVzIDxuYW1lPiAuLi4KICAgIFNob3cgdGV4dCBkb2N1bWVudGF0aW9uIG9uIHNvbWV0aGluZy4gIDxuYW1lPiBtYXkgYmUgdGhlIG5hbWUgb2YgYQogICAgZnVuY3Rpb24sIG1vZHVsZSwgb3IgcGFja2FnZSwgb3IgYSBkb3R0ZWQgcmVmZXJlbmNlIHRvIGEgY2xhc3Mgb3IKICAgIGZ1bmN0aW9uIHdpdGhpbiBhIG1vZHVsZSBvciBtb2R1bGUgaW4gYSBwYWNrYWdlLiAgSWYgPG5hbWU+IGNvbnRhaW5zCiAgICBhICclcycsIGl0IGlzIHVzZWQgYXMgdGhlIHBhdGggdG8gYSBQeXRob24gc291cmNlIGZpbGUgdG8gZG9jdW1lbnQuCgolcyAtayA8a2V5d29yZD4KICAgIFNlYXJjaCBmb3IgYSBrZXl3b3JkIGluIHRoZSBzeW5vcHNpcyBsaW5lcyBvZiBhbGwgYXZhaWxhYmxlIG1vZHVsZXMuCgolcyAtcCA8cG9ydD4KICAgIFN0YXJ0IGFuIEhUVFAgc2VydmVyIG9uIHRoZSBnaXZlbiBwb3J0IG9uIHRoZSBsb2NhbCBtYWNoaW5lLgoKJXMgLWcKICAgIFBvcCB1cCBhIGdyYXBoaWNhbCBpbnRlcmZhY2UgZm9yIGZpbmRpbmcgYW5kIHNlcnZpbmcgZG9jdW1lbnRhdGlvbi4KCiVzIC13IDxuYW1lPiAuLi4KICAgIFdyaXRlIG91dCB0aGUgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIG1vZHVsZSB0byBhIGZpbGUgaW4gdGhlIGN1cnJlbnQKICAgIGRpcmVjdG9yeS4gIElmIDxuYW1lPiBjb250YWlucyBhICclcycsIGl0IGlzIHRyZWF0ZWQgYXMgYSBmaWxlbmFtZTsgaWYKICAgIGl0IG5hbWVzIGEgZGlyZWN0b3J5LCBkb2N1bWVudGF0aW9uIGlzIHdyaXR0ZW4gZm9yIGFsbCB0aGUgY29udGVudHMuCiIiIiAlIChjbWQsIG9zLnNlcCwgY21kLCBjbWQsIGNtZCwgY21kLCBvcy5zZXApCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOiBjbGkoKQo=