Skip to content

Instantly share code, notes, and snippets.

@scomma
Created October 19, 2018 09:25
Show Gist options
  • Save scomma/29d6d8367829b76e6898a70c5c8772e8 to your computer and use it in GitHub Desktop.
Save scomma/29d6d8367829b76e6898a70c5c8772e8 to your computer and use it in GitHub Desktop.
Maniphest Quick Triage for Tampermonkey
{"created_by":"Tampermonkey","version":"1","scripts":[{"name":"Quick Triage","options":{"check_for_updates":true,"comment":null,"compatopts_for_requires":true,"compat_wrappedjsobject":false,"compat_metadata":false,"compat_foreach":false,"compat_arrayleft":false,"compat_uW_gmonkey":false,"compat_forvarin":false,"noframes":null,"awareOfChrome":false,"run_at":null,"override":{"use_includes":[],"orig_includes":[],"merge_includes":true,"use_matches":[],"orig_matches":["http://softbaked.co/*"],"merge_matches":true,"use_excludes":[],"orig_excludes":[],"merge_excludes":true,"use_connects":[],"merge_connects":true,"use_blockers":[],"orig_run_at":"document-idle","orig_noframes":null,"orig_connects":[]}},"storage":{"ts":1513744916648,"data":{}},"enabled":true,"position":1,"uuid":"8ff81db7-8771-4213-bb0e-98da3ab3e721","source":"Ly8gPT1Vc2VyU2NyaXB0PT0KLy8gQG5hbWUgICAgICAgICBRdWljayBUcmlhZ2UKLy8gQG5hbWVzcGFjZSAgICBodHRwOi8vc29mdGJha2VkLmNvLwovLyBAdmVyc2lvbiAgICAgIDAuMQovLyBAZGVzY3JpcHRpb24gIFF1aWNrbHkgdHJpYWdlIE1hbmlwaGVzdCB0YXNrcwovLyBAYXV0aG9yICAgICAgIFlvdQovLyBAbWF0Y2ggICAgICAgIGh0dHA6Ly9zb2Z0YmFrZWQuY28vKgovLyBAcmVxdWlyZSAgICAgIGh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL21vdXNldHJhcC8xLjYuMS9tb3VzZXRyYXAuanMKLy8gQHJlcXVpcmUgICAgICBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vY2NhbXBiZWxsL21vdXNldHJhcC9tYXN0ZXIvcGx1Z2lucy9nbG9iYWwtYmluZC9tb3VzZXRyYXAtZ2xvYmFsLWJpbmQuanMKLy8gPT0vVXNlclNjcmlwdD09CgooZnVuY3Rpb24oKSB7CiAgICAndXNlIHN0cmljdCc7CiAgICB2YXIgb3B0aW9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcigib3B0aW9uW3ZhbHVlPScrJ10iKTsKICAgIGlmICghb3B0aW9uKSByZXR1cm47IC8vIG5vdCBtYW5pcGhlc3QgdGFzawoKICAgIHZhciBhY3Rpb24gPSBvcHRpb24ucGFyZW50RWxlbWVudCwKICAgICAgICBmb3JtICAgPSBhY3Rpb24ucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQsCiAgICAgICAgY2hhbmdlID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0hUTUxFdmVudHMnKTsKICAgIGNoYW5nZS5pbml0RXZlbnQoJ2NoYW5nZScsIGZhbHNlLCB0cnVlKTsKCiAgICB2YXIgZm9jdXNMYXN0ID0gZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIGlucHV0cyAgICA9IGZvcm0uZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnYXBocm9udC1mb3JtLWlucHV0JyksCiAgICAgICAgICAgIGxhc3RJbnB1dCA9IGlucHV0c1tpbnB1dHMubGVuZ3RoIC0gM107CiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHRleHRJbnB1dCA9IGxhc3RJbnB1dC5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPXRleHRdJyk7CiAgICAgICAgICAgIGlmICh0ZXh0SW5wdXQpIHsgdGV4dElucHV0LmZvY3VzKCk7IH0KICAgICAgICAgICAgZWxzZSB7IGxhc3RJbnB1dC5maXJzdENoaWxkLmZvY3VzKCk7IH0KICAgICAgICB9LCAwKTsKICAgIH07CgogICAgdmFyIGJpbmRRdWlja0FjdGlvbiA9IGZ1bmN0aW9uKHNob3J0Y3V0LCBhKSB7CiAgICAgICAgTW91c2V0cmFwLmJpbmRHbG9iYWwoc2hvcnRjdXQsIGZ1bmN0aW9uKGUpIHsKICAgICAgICAgICAgYWN0aW9uLnZhbHVlID0gYTsKICAgICAgICAgICAgYWN0aW9uLmRpc3BhdGNoRXZlbnQoY2hhbmdlKTsKICAgICAgICAgICAgZm9jdXNMYXN0KCk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9KTsKICAgIH07CgogICAgYmluZFF1aWNrQWN0aW9uKCdjdHJsK28nLCAnb3duZXInKTsKICAgIGJpbmRRdWlja0FjdGlvbignY3RybCtzJywgJ3N0YXR1cycpOwogICAgYmluZFF1aWNrQWN0aW9uKCdjdHJsK3AnLCAncHJpb3JpdHknKTsKICAgIGJpbmRRdWlja0FjdGlvbignY3RybCt4JywgJ3BvaW50cycpOwogICAgYmluZFF1aWNrQWN0aW9uKCdjdHJsK3QnLCAncHJvamVjdFBISURzJyk7CiAgICBiaW5kUXVpY2tBY3Rpb24oJ2N0cmwrbScsICdjb2x1bW4nKTsKfSkoKTs=","requires":[{"meta":{"name":"mousetrap.js","url":"https://cdnjs.cloudflare.com/ajax/libs/mousetrap/1.6.1/mousetrap.js","ts":1539246620294,"mimetype":"text/javascript"},"source":"LypnbG9iYWwgZGVmaW5lOmZhbHNlICovCi8qKgogKiBDb3B5cmlnaHQgMjAxMi0yMDE3IENyYWlnIENhbXBiZWxsCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICoKICogTW91c2V0cmFwIGlzIGEgc2ltcGxlIGtleWJvYXJkIHNob3J0Y3V0IGxpYnJhcnkgZm9yIEphdmFzY3JpcHQgd2l0aAogKiBubyBleHRlcm5hbCBkZXBlbmRlbmNpZXMKICoKICogQHZlcnNpb24gMS42LjEKICogQHVybCBjcmFpZy5pcy9raWxsaW5nL21pY2UKICovCihmdW5jdGlvbih3aW5kb3csIGRvY3VtZW50LCB1bmRlZmluZWQpIHsKCiAgICAvLyBDaGVjayBpZiBtb3VzZXRyYXAgaXMgdXNlZCBpbnNpZGUgYnJvd3NlciwgaWYgbm90LCByZXR1cm4KICAgIGlmICghd2luZG93KSB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qKgogICAgICogbWFwcGluZyBvZiBzcGVjaWFsIGtleWNvZGVzIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcga2V5cwogICAgICoKICAgICAqIGV2ZXJ5dGhpbmcgaW4gdGhpcyBkaWN0aW9uYXJ5IGNhbm5vdCB1c2Uga2V5cHJlc3MgZXZlbnRzCiAgICAgKiBzbyBpdCBoYXMgdG8gYmUgaGVyZSB0byBtYXAgdG8gdGhlIGNvcnJlY3Qga2V5Y29kZXMgZm9yCiAgICAgKiBrZXl1cC9rZXlkb3duIGV2ZW50cwogICAgICoKICAgICAqIEB0eXBlIHtPYmplY3R9CiAgICAgKi8KICAgIHZhciBfTUFQID0gewogICAgICAgIDg6ICdiYWNrc3BhY2UnLAogICAgICAgIDk6ICd0YWInLAogICAgICAgIDEzOiAnZW50ZXInLAogICAgICAgIDE2OiAnc2hpZnQnLAogICAgICAgIDE3OiAnY3RybCcsCiAgICAgICAgMTg6ICdhbHQnLAogICAgICAgIDIwOiAnY2Fwc2xvY2snLAogICAgICAgIDI3OiAnZXNjJywKICAgICAgICAzMjogJ3NwYWNlJywKICAgICAgICAzMzogJ3BhZ2V1cCcsCiAgICAgICAgMzQ6ICdwYWdlZG93bicsCiAgICAgICAgMzU6ICdlbmQnLAogICAgICAgIDM2OiAnaG9tZScsCiAgICAgICAgMzc6ICdsZWZ0JywKICAgICAgICAzODogJ3VwJywKICAgICAgICAzOTogJ3JpZ2h0JywKICAgICAgICA0MDogJ2Rvd24nLAogICAgICAgIDQ1OiAnaW5zJywKICAgICAgICA0NjogJ2RlbCcsCiAgICAgICAgOTE6ICdtZXRhJywKICAgICAgICA5MzogJ21ldGEnLAogICAgICAgIDIyNDogJ21ldGEnCiAgICB9OwoKICAgIC8qKgogICAgICogbWFwcGluZyBmb3Igc3BlY2lhbCBjaGFyYWN0ZXJzIHNvIHRoZXkgY2FuIHN1cHBvcnQKICAgICAqCiAgICAgKiB0aGlzIGRpY3Rpb25hcnkgaXMgb25seSB1c2VkIGluY2FzZSB5b3Ugd2FudCB0byBiaW5kIGEKICAgICAqIGtleXVwIG9yIGtleWRvd24gZXZlbnQgdG8gb25lIG9mIHRoZXNlIGtleXMKICAgICAqCiAgICAgKiBAdHlwZSB7T2JqZWN0fQogICAgICovCiAgICB2YXIgX0tFWUNPREVfTUFQID0gewogICAgICAgIDEwNjogJyonLAogICAgICAgIDEwNzogJysnLAogICAgICAgIDEwOTogJy0nLAogICAgICAgIDExMDogJy4nLAogICAgICAgIDExMSA6ICcvJywKICAgICAgICAxODY6ICc7JywKICAgICAgICAxODc6ICc9JywKICAgICAgICAxODg6ICcsJywKICAgICAgICAxODk6ICctJywKICAgICAgICAxOTA6ICcuJywKICAgICAgICAxOTE6ICcvJywKICAgICAgICAxOTI6ICdgJywKICAgICAgICAyMTk6ICdbJywKICAgICAgICAyMjA6ICdcXCcsCiAgICAgICAgMjIxOiAnXScsCiAgICAgICAgMjIyOiAnXCcnCiAgICB9OwoKICAgIC8qKgogICAgICogdGhpcyBpcyBhIG1hcHBpbmcgb2Yga2V5cyB0aGF0IHJlcXVpcmUgc2hpZnQgb24gYSBVUyBrZXlwYWQKICAgICAqIGJhY2sgdG8gdGhlIG5vbiBzaGlmdCBlcXVpdmVsZW50cwogICAgICoKICAgICAqIHRoaXMgaXMgc28geW91IGNhbiB1c2Uga2V5dXAgZXZlbnRzIHdpdGggdGhlc2Uga2V5cwogICAgICoKICAgICAqIG5vdGUgdGhhdCB0aGlzIHdpbGwgb25seSB3b3JrIHJlbGlhYmx5IG9uIFVTIGtleWJvYXJkcwogICAgICoKICAgICAqIEB0eXBlIHtPYmplY3R9CiAgICAgKi8KICAgIHZhciBfU0hJRlRfTUFQID0gewogICAgICAgICd+JzogJ2AnLAogICAgICAgICchJzogJzEnLAogICAgICAgICdAJzogJzInLAogICAgICAgICcjJzogJzMnLAogICAgICAgICckJzogJzQnLAogICAgICAgICclJzogJzUnLAogICAgICAgICdeJzogJzYnLAogICAgICAgICcmJzogJzcnLAogICAgICAgICcqJzogJzgnLAogICAgICAgICcoJzogJzknLAogICAgICAgICcpJzogJzAnLAogICAgICAgICdfJzogJy0nLAogICAgICAgICcrJzogJz0nLAogICAgICAgICc6JzogJzsnLAogICAgICAgICdcIic6ICdcJycsCiAgICAgICAgJzwnOiAnLCcsCiAgICAgICAgJz4nOiAnLicsCiAgICAgICAgJz8nOiAnLycsCiAgICAgICAgJ3wnOiAnXFwnCiAgICB9OwoKICAgIC8qKgogICAgICogdGhpcyBpcyBhIGxpc3Qgb2Ygc3BlY2lhbCBzdHJpbmdzIHlvdSBjYW4gdXNlIHRvIG1hcAogICAgICogdG8gbW9kaWZpZXIga2V5cyB3aGVuIHlvdSBzcGVjaWZ5IHlvdXIga2V5Ym9hcmQgc2hvcnRjdXRzCiAgICAgKgogICAgICogQHR5cGUge09iamVjdH0KICAgICAqLwogICAgdmFyIF9TUEVDSUFMX0FMSUFTRVMgPSB7CiAgICAgICAgJ29wdGlvbic6ICdhbHQnLAogICAgICAgICdjb21tYW5kJzogJ21ldGEnLAogICAgICAgICdyZXR1cm4nOiAnZW50ZXInLAogICAgICAgICdlc2NhcGUnOiAnZXNjJywKICAgICAgICAncGx1cyc6ICcrJywKICAgICAgICAnbW9kJzogL01hY3xpUG9kfGlQaG9uZXxpUGFkLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSkgPyAnbWV0YScgOiAnY3RybCcKICAgIH07CgogICAgLyoqCiAgICAgKiB2YXJpYWJsZSB0byBzdG9yZSB0aGUgZmxpcHBlZCB2ZXJzaW9uIG9mIF9NQVAgZnJvbSBhYm92ZQogICAgICogbmVlZGVkIHRvIGNoZWNrIGlmIHdlIHNob3VsZCB1c2Uga2V5cHJlc3Mgb3Igbm90IHdoZW4gbm8gYWN0aW9uCiAgICAgKiBpcyBzcGVjaWZpZWQKICAgICAqCiAgICAgKiBAdHlwZSB7T2JqZWN0fHVuZGVmaW5lZH0KICAgICAqLwogICAgdmFyIF9SRVZFUlNFX01BUDsKCiAgICAvKioKICAgICAqIGxvb3AgdGhyb3VnaCB0aGUgZiBrZXlzLCBmMSB0byBmMTkgYW5kIGFkZCB0aGVtIHRvIHRoZSBtYXAKICAgICAqIHByb2dyYW1hdGljYWxseQogICAgICovCiAgICBmb3IgKHZhciBpID0gMTsgaSA8IDIwOyArK2kpIHsKICAgICAgICBfTUFQWzExMSArIGldID0gJ2YnICsgaTsKICAgIH0KCiAgICAvKioKICAgICAqIGxvb3AgdGhyb3VnaCB0byBtYXAgbnVtYmVycyBvbiB0aGUgbnVtZXJpYyBrZXlwYWQKICAgICAqLwogICAgZm9yIChpID0gMDsgaSA8PSA5OyArK2kpIHsKCiAgICAgICAgLy8gVGhpcyBuZWVkcyB0byB1c2UgYSBzdHJpbmcgY2F1c2Ugb3RoZXJ3aXNlIHNpbmNlIDAgaXMgZmFsc2V5CiAgICAgICAgLy8gbW91c2V0cmFwIHdpbGwgbmV2ZXIgZmlyZSBmb3IgbnVtcGFkIDAgcHJlc3NlZCBhcyBwYXJ0IG9mIGEga2V5ZG93bgogICAgICAgIC8vIGV2ZW50LgogICAgICAgIC8vCiAgICAgICAgLy8gQHNlZSBodHRwczovL2dpdGh1Yi5jb20vY2NhbXBiZWxsL21vdXNldHJhcC9wdWxsLzI1OAogICAgICAgIF9NQVBbaSArIDk2XSA9IGkudG9TdHJpbmcoKTsKICAgIH0KCiAgICAvKioKICAgICAqIGNyb3NzIGJyb3dzZXIgYWRkIGV2ZW50IG1ldGhvZAogICAgICoKICAgICAqIEBwYXJhbSB7RWxlbWVudHxIVE1MRG9jdW1lbnR9IG9iamVjdAogICAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUKICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrCiAgICAgKiBAcmV0dXJucyB2b2lkCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hZGRFdmVudChvYmplY3QsIHR5cGUsIGNhbGxiYWNrKSB7CiAgICAgICAgaWYgKG9iamVjdC5hZGRFdmVudExpc3RlbmVyKSB7CiAgICAgICAgICAgIG9iamVjdC5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrLCBmYWxzZSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIG9iamVjdC5hdHRhY2hFdmVudCgnb24nICsgdHlwZSwgY2FsbGJhY2spOwogICAgfQoKICAgIC8qKgogICAgICogdGFrZXMgdGhlIGV2ZW50IGFuZCByZXR1cm5zIHRoZSBrZXkgY2hhcmFjdGVyCiAgICAgKgogICAgICogQHBhcmFtIHtFdmVudH0gZQogICAgICogQHJldHVybiB7c3RyaW5nfQogICAgICovCiAgICBmdW5jdGlvbiBfY2hhcmFjdGVyRnJvbUV2ZW50KGUpIHsKCiAgICAgICAgLy8gZm9yIGtleXByZXNzIGV2ZW50cyB3ZSBzaG91bGQgcmV0dXJuIHRoZSBjaGFyYWN0ZXIgYXMgaXMKICAgICAgICBpZiAoZS50eXBlID09ICdrZXlwcmVzcycpIHsKICAgICAgICAgICAgdmFyIGNoYXJhY3RlciA9IFN0cmluZy5mcm9tQ2hhckNvZGUoZS53aGljaCk7CgogICAgICAgICAgICAvLyBpZiB0aGUgc2hpZnQga2V5IGlzIG5vdCBwcmVzc2VkIHRoZW4gaXQgaXMgc2FmZSB0byBhc3N1bWUKICAgICAgICAgICAgLy8gdGhhdCB3ZSB3YW50IHRoZSBjaGFyYWN0ZXIgdG8gYmUgbG93ZXJjYXNlLiAgdGhpcyBtZWFucyBpZgogICAgICAgICAgICAvLyB5b3UgYWNjaWRlbnRhbGx5IGhhdmUgY2FwcyBsb2NrIG9uIHRoZW4geW91ciBrZXkgYmluZGluZ3MKICAgICAgICAgICAgLy8gd2lsbCBjb250aW51ZSB0byB3b3JrCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIHRoZSBvbmx5IHNpZGUgZWZmZWN0IHRoYXQgbWlnaHQgbm90IGJlIGRlc2lyZWQgaXMgaWYgeW91CiAgICAgICAgICAgIC8vIGJpbmQgc29tZXRoaW5nIGxpa2UgJ0EnIGNhdXNlIHlvdSB3YW50IHRvIHRyaWdnZXIgYW4KICAgICAgICAgICAgLy8gZXZlbnQgd2hlbiBjYXBpdGFsIEEgaXMgcHJlc3NlZCBjYXBzIGxvY2sgd2lsbCBubyBsb25nZXIKICAgICAgICAgICAgLy8gdHJpZ2dlciB0aGUgZXZlbnQuICBzaGlmdCthIHdpbGwgdGhvdWdoLgogICAgICAgICAgICBpZiAoIWUuc2hpZnRLZXkpIHsKICAgICAgICAgICAgICAgIGNoYXJhY3RlciA9IGNoYXJhY3Rlci50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gY2hhcmFjdGVyOwogICAgICAgIH0KCiAgICAgICAgLy8gZm9yIG5vbiBrZXlwcmVzcyBldmVudHMgdGhlIHNwZWNpYWwgbWFwcyBhcmUgbmVlZGVkCiAgICAgICAgaWYgKF9NQVBbZS53aGljaF0pIHsKICAgICAgICAgICAgcmV0dXJuIF9NQVBbZS53aGljaF07CiAgICAgICAgfQoKICAgICAgICBpZiAoX0tFWUNPREVfTUFQW2Uud2hpY2hdKSB7CiAgICAgICAgICAgIHJldHVybiBfS0VZQ09ERV9NQVBbZS53aGljaF07CiAgICAgICAgfQoKICAgICAgICAvLyBpZiBpdCBpcyBub3QgaW4gdGhlIHNwZWNpYWwgbWFwCgogICAgICAgIC8vIHdpdGgga2V5ZG93biBhbmQga2V5dXAgZXZlbnRzIHRoZSBjaGFyYWN0ZXIgc2VlbXMgdG8gYWx3YXlzCiAgICAgICAgLy8gY29tZSBpbiBhcyBhbiB1cHBlcmNhc2UgY2hhcmFjdGVyIHdoZXRoZXIgeW91IGFyZSBwcmVzc2luZyBzaGlmdAogICAgICAgIC8vIG9yIG5vdC4gIHdlIHNob3VsZCBtYWtlIHN1cmUgaXQgaXMgYWx3YXlzIGxvd2VyY2FzZSBmb3IgY29tcGFyaXNvbnMKICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShlLndoaWNoKS50b0xvd2VyQ2FzZSgpOwogICAgfQoKICAgIC8qKgogICAgICogY2hlY2tzIGlmIHR3byBhcnJheXMgYXJlIGVxdWFsCiAgICAgKgogICAgICogQHBhcmFtIHtBcnJheX0gbW9kaWZpZXJzMQogICAgICogQHBhcmFtIHtBcnJheX0gbW9kaWZpZXJzMgogICAgICogQHJldHVybnMge2Jvb2xlYW59CiAgICAgKi8KICAgIGZ1bmN0aW9uIF9tb2RpZmllcnNNYXRjaChtb2RpZmllcnMxLCBtb2RpZmllcnMyKSB7CiAgICAgICAgcmV0dXJuIG1vZGlmaWVyczEuc29ydCgpLmpvaW4oJywnKSA9PT0gbW9kaWZpZXJzMi5zb3J0KCkuam9pbignLCcpOwogICAgfQoKICAgIC8qKgogICAgICogdGFrZXMgYSBrZXkgZXZlbnQgYW5kIGZpZ3VyZXMgb3V0IHdoYXQgdGhlIG1vZGlmaWVycyBhcmUKICAgICAqCiAgICAgKiBAcGFyYW0ge0V2ZW50fSBlCiAgICAgKiBAcmV0dXJucyB7QXJyYXl9CiAgICAgKi8KICAgIGZ1bmN0aW9uIF9ldmVudE1vZGlmaWVycyhlKSB7CiAgICAgICAgdmFyIG1vZGlmaWVycyA9IFtdOwoKICAgICAgICBpZiAoZS5zaGlmdEtleSkgewogICAgICAgICAgICBtb2RpZmllcnMucHVzaCgnc2hpZnQnKTsKICAgICAgICB9CgogICAgICAgIGlmIChlLmFsdEtleSkgewogICAgICAgICAgICBtb2RpZmllcnMucHVzaCgnYWx0Jyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZS5jdHJsS2V5KSB7CiAgICAgICAgICAgIG1vZGlmaWVycy5wdXNoKCdjdHJsJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZS5tZXRhS2V5KSB7CiAgICAgICAgICAgIG1vZGlmaWVycy5wdXNoKCdtZXRhJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbW9kaWZpZXJzOwogICAgfQoKICAgIC8qKgogICAgICogcHJldmVudHMgZGVmYXVsdCBmb3IgdGhpcyBldmVudAogICAgICoKICAgICAqIEBwYXJhbSB7RXZlbnR9IGUKICAgICAqIEByZXR1cm5zIHZvaWQKICAgICAqLwogICAgZnVuY3Rpb24gX3ByZXZlbnREZWZhdWx0KGUpIHsKICAgICAgICBpZiAoZS5wcmV2ZW50RGVmYXVsdCkgewogICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGUucmV0dXJuVmFsdWUgPSBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIHN0b3BzIHByb3BvZ2F0aW9uIGZvciB0aGlzIGV2ZW50CiAgICAgKgogICAgICogQHBhcmFtIHtFdmVudH0gZQogICAgICogQHJldHVybnMgdm9pZAogICAgICovCiAgICBmdW5jdGlvbiBfc3RvcFByb3BhZ2F0aW9uKGUpIHsKICAgICAgICBpZiAoZS5zdG9wUHJvcGFnYXRpb24pIHsKICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgZS5jYW5jZWxCdWJibGUgPSB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogZGV0ZXJtaW5lcyBpZiB0aGUga2V5Y29kZSBzcGVjaWZpZWQgaXMgYSBtb2RpZmllciBrZXkgb3Igbm90CiAgICAgKgogICAgICogQHBhcmFtIHtzdHJpbmd9IGtleQogICAgICogQHJldHVybnMge2Jvb2xlYW59CiAgICAgKi8KICAgIGZ1bmN0aW9uIF9pc01vZGlmaWVyKGtleSkgewogICAgICAgIHJldHVybiBrZXkgPT0gJ3NoaWZ0JyB8fCBrZXkgPT0gJ2N0cmwnIHx8IGtleSA9PSAnYWx0JyB8fCBrZXkgPT0gJ21ldGEnOwogICAgfQoKICAgIC8qKgogICAgICogcmV2ZXJzZXMgdGhlIG1hcCBsb29rdXAgc28gdGhhdCB3ZSBjYW4gbG9vayBmb3Igc3BlY2lmaWMga2V5cwogICAgICogdG8gc2VlIHdoYXQgY2FuIGFuZCBjYW4ndCB1c2Uga2V5cHJlc3MKICAgICAqCiAgICAgKiBAcmV0dXJuIHtPYmplY3R9CiAgICAgKi8KICAgIGZ1bmN0aW9uIF9nZXRSZXZlcnNlTWFwKCkgewogICAgICAgIGlmICghX1JFVkVSU0VfTUFQKSB7CiAgICAgICAgICAgIF9SRVZFUlNFX01BUCA9IHt9OwogICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gX01BUCkgewoKICAgICAgICAgICAgICAgIC8vIHB1bGwgb3V0IHRoZSBudW1lcmljIGtleXBhZCBmcm9tIGhlcmUgY2F1c2Uga2V5cHJlc3Mgc2hvdWxkCiAgICAgICAgICAgICAgICAvLyBiZSBhYmxlIHRvIGRldGVjdCB0aGUga2V5cyBmcm9tIHRoZSBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgIGlmIChrZXkgPiA5NSAmJiBrZXkgPCAxMTIpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoX01BUC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7CiAgICAgICAgICAgICAgICAgICAgX1JFVkVSU0VfTUFQW19NQVBba2V5XV0gPSBrZXk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIF9SRVZFUlNFX01BUDsKICAgIH0KCiAgICAvKioKICAgICAqIHBpY2tzIHRoZSBiZXN0IGFjdGlvbiBiYXNlZCBvbiB0aGUga2V5IGNvbWJpbmF0aW9uCiAgICAgKgogICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIGNoYXJhY3RlciBmb3Iga2V5CiAgICAgKiBAcGFyYW0ge0FycmF5fSBtb2RpZmllcnMKICAgICAqIEBwYXJhbSB7c3RyaW5nPX0gYWN0aW9uIHBhc3NlZCBpbgogICAgICovCiAgICBmdW5jdGlvbiBfcGlja0Jlc3RBY3Rpb24oa2V5LCBtb2RpZmllcnMsIGFjdGlvbikgewoKICAgICAgICAvLyBpZiBubyBhY3Rpb24gd2FzIHBpY2tlZCBpbiB3ZSBzaG91bGQgdHJ5IHRvIHBpY2sgdGhlIG9uZQogICAgICAgIC8vIHRoYXQgd2UgdGhpbmsgd291bGQgd29yayBiZXN0IGZvciB0aGlzIGtleQogICAgICAgIGlmICghYWN0aW9uKSB7CiAgICAgICAgICAgIGFjdGlvbiA9IF9nZXRSZXZlcnNlTWFwKClba2V5XSA/ICdrZXlkb3duJyA6ICdrZXlwcmVzcyc7CiAgICAgICAgfQoKICAgICAgICAvLyBtb2RpZmllciBrZXlzIGRvbid0IHdvcmsgYXMgZXhwZWN0ZWQgd2l0aCBrZXlwcmVzcywKICAgICAgICAvLyBzd2l0Y2ggdG8ga2V5ZG93bgogICAgICAgIGlmIChhY3Rpb24gPT0gJ2tleXByZXNzJyAmJiBtb2RpZmllcnMubGVuZ3RoKSB7CiAgICAgICAgICAgIGFjdGlvbiA9ICdrZXlkb3duJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhY3Rpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBmcm9tIGEgc3RyaW5nIGtleSBjb21iaW5hdGlvbiB0byBhbiBhcnJheQogICAgICoKICAgICAqIEBwYXJhbSAge3N0cmluZ30gY29tYmluYXRpb24gbGlrZSAiY29tbWFuZCtzaGlmdCtsIgogICAgICogQHJldHVybiB7QXJyYXl9CiAgICAgKi8KICAgIGZ1bmN0aW9uIF9rZXlzRnJvbVN0cmluZyhjb21iaW5hdGlvbikgewogICAgICAgIGlmIChjb21iaW5hdGlvbiA9PT0gJysnKSB7CiAgICAgICAgICAgIHJldHVybiBbJysnXTsKICAgICAgICB9CgogICAgICAgIGNvbWJpbmF0aW9uID0gY29tYmluYXRpb24ucmVwbGFjZSgvXCt7Mn0vZywgJytwbHVzJyk7CiAgICAgICAgcmV0dXJuIGNvbWJpbmF0aW9uLnNwbGl0KCcrJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIGluZm8gZm9yIGEgc3BlY2lmaWMga2V5IGNvbWJpbmF0aW9uCiAgICAgKgogICAgICogQHBhcmFtICB7c3RyaW5nfSBjb21iaW5hdGlvbiBrZXkgY29tYmluYXRpb24gKCJjb21tYW5kK3MiIG9yICJhIiBvciAiKiIpCiAgICAgKiBAcGFyYW0gIHtzdHJpbmc9fSBhY3Rpb24KICAgICAqIEByZXR1cm5zIHtPYmplY3R9CiAgICAgKi8KICAgIGZ1bmN0aW9uIF9nZXRLZXlJbmZvKGNvbWJpbmF0aW9uLCBhY3Rpb24pIHsKICAgICAgICB2YXIga2V5czsKICAgICAgICB2YXIga2V5OwogICAgICAgIHZhciBpOwogICAgICAgIHZhciBtb2RpZmllcnMgPSBbXTsKCiAgICAgICAgLy8gdGFrZSB0aGUga2V5cyBmcm9tIHRoaXMgcGF0dGVybiBhbmQgZmlndXJlIG91dCB3aGF0IHRoZSBhY3R1YWwKICAgICAgICAvLyBwYXR0ZXJuIGlzIGFsbCBhYm91dAogICAgICAgIGtleXMgPSBfa2V5c0Zyb21TdHJpbmcoY29tYmluYXRpb24pOwoKICAgICAgICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBrZXkgPSBrZXlzW2ldOwoKICAgICAgICAgICAgLy8gbm9ybWFsaXplIGtleSBuYW1lcwogICAgICAgICAgICBpZiAoX1NQRUNJQUxfQUxJQVNFU1trZXldKSB7CiAgICAgICAgICAgICAgICBrZXkgPSBfU1BFQ0lBTF9BTElBU0VTW2tleV07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgbm90IGEga2V5cHJlc3MgZXZlbnQgdGhlbiB3ZSBzaG91bGQKICAgICAgICAgICAgLy8gYmUgc21hcnQgYWJvdXQgdXNpbmcgc2hpZnQga2V5cwogICAgICAgICAgICAvLyB0aGlzIHdpbGwgb25seSB3b3JrIGZvciBVUyBrZXlib2FyZHMgaG93ZXZlcgogICAgICAgICAgICBpZiAoYWN0aW9uICYmIGFjdGlvbiAhPSAna2V5cHJlc3MnICYmIF9TSElGVF9NQVBba2V5XSkgewogICAgICAgICAgICAgICAga2V5ID0gX1NISUZUX01BUFtrZXldOwogICAgICAgICAgICAgICAgbW9kaWZpZXJzLnB1c2goJ3NoaWZ0Jyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGlmIHRoaXMga2V5IGlzIGEgbW9kaWZpZXIgdGhlbiBhZGQgaXQgdG8gdGhlIGxpc3Qgb2YgbW9kaWZpZXJzCiAgICAgICAgICAgIGlmIChfaXNNb2RpZmllcihrZXkpKSB7CiAgICAgICAgICAgICAgICBtb2RpZmllcnMucHVzaChrZXkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBkZXBlbmRpbmcgb24gd2hhdCB0aGUga2V5IGNvbWJpbmF0aW9uIGlzCiAgICAgICAgLy8gd2Ugd2lsbCB0cnkgdG8gcGljayB0aGUgYmVzdCBldmVudCBmb3IgaXQKICAgICAgICBhY3Rpb24gPSBfcGlja0Jlc3RBY3Rpb24oa2V5LCBtb2RpZmllcnMsIGFjdGlvbik7CgogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIGtleToga2V5LAogICAgICAgICAgICBtb2RpZmllcnM6IG1vZGlmaWVycywKICAgICAgICAgICAgYWN0aW9uOiBhY3Rpb24KICAgICAgICB9OwogICAgfQoKICAgIGZ1bmN0aW9uIF9iZWxvbmdzVG8oZWxlbWVudCwgYW5jZXN0b3IpIHsKICAgICAgICBpZiAoZWxlbWVudCA9PT0gbnVsbCB8fCBlbGVtZW50ID09PSBkb2N1bWVudCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoZWxlbWVudCA9PT0gYW5jZXN0b3IpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gX2JlbG9uZ3NUbyhlbGVtZW50LnBhcmVudE5vZGUsIGFuY2VzdG9yKTsKICAgIH0KCiAgICBmdW5jdGlvbiBNb3VzZXRyYXAodGFyZ2V0RWxlbWVudCkgewogICAgICAgIHZhciBzZWxmID0gdGhpczsKCiAgICAgICAgdGFyZ2V0RWxlbWVudCA9IHRhcmdldEVsZW1lbnQgfHwgZG9jdW1lbnQ7CgogICAgICAgIGlmICghKHNlbGYgaW5zdGFuY2VvZiBNb3VzZXRyYXApKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgTW91c2V0cmFwKHRhcmdldEVsZW1lbnQpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogZWxlbWVudCB0byBhdHRhY2gga2V5IGV2ZW50cyB0bwogICAgICAgICAqCiAgICAgICAgICogQHR5cGUge0VsZW1lbnR9CiAgICAgICAgICovCiAgICAgICAgc2VsZi50YXJnZXQgPSB0YXJnZXRFbGVtZW50OwoKICAgICAgICAvKioKICAgICAgICAgKiBhIGxpc3Qgb2YgYWxsIHRoZSBjYWxsYmFja3Mgc2V0dXAgdmlhIE1vdXNldHJhcC5iaW5kKCkKICAgICAgICAgKgogICAgICAgICAqIEB0eXBlIHtPYmplY3R9CiAgICAgICAgICovCiAgICAgICAgc2VsZi5fY2FsbGJhY2tzID0ge307CgogICAgICAgIC8qKgogICAgICAgICAqIGRpcmVjdCBtYXAgb2Ygc3RyaW5nIGNvbWJpbmF0aW9ucyB0byBjYWxsYmFja3MgdXNlZCBmb3IgdHJpZ2dlcigpCiAgICAgICAgICoKICAgICAgICAgKiBAdHlwZSB7T2JqZWN0fQogICAgICAgICAqLwogICAgICAgIHNlbGYuX2RpcmVjdE1hcCA9IHt9OwoKICAgICAgICAvKioKICAgICAgICAgKiBrZWVwcyB0cmFjayBvZiB3aGF0IGxldmVsIGVhY2ggc2VxdWVuY2UgaXMgYXQgc2luY2UgbXVsdGlwbGUKICAgICAgICAgKiBzZXF1ZW5jZXMgY2FuIHN0YXJ0IG91dCB3aXRoIHRoZSBzYW1lIHNlcXVlbmNlCiAgICAgICAgICoKICAgICAgICAgKiBAdHlwZSB7T2JqZWN0fQogICAgICAgICAqLwogICAgICAgIHZhciBfc2VxdWVuY2VMZXZlbHMgPSB7fTsKCiAgICAgICAgLyoqCiAgICAgICAgICogdmFyaWFibGUgdG8gc3RvcmUgdGhlIHNldFRpbWVvdXQgY2FsbAogICAgICAgICAqCiAgICAgICAgICogQHR5cGUge251bGx8bnVtYmVyfQogICAgICAgICAqLwogICAgICAgIHZhciBfcmVzZXRUaW1lcjsKCiAgICAgICAgLyoqCiAgICAgICAgICogdGVtcG9yYXJ5IHN0YXRlIHdoZXJlIHdlIHdpbGwgaWdub3JlIHRoZSBuZXh0IGtleXVwCiAgICAgICAgICoKICAgICAgICAgKiBAdHlwZSB7Ym9vbGVhbnxzdHJpbmd9CiAgICAgICAgICovCiAgICAgICAgdmFyIF9pZ25vcmVOZXh0S2V5dXAgPSBmYWxzZTsKCiAgICAgICAgLyoqCiAgICAgICAgICogdGVtcG9yYXJ5IHN0YXRlIHdoZXJlIHdlIHdpbGwgaWdub3JlIHRoZSBuZXh0IGtleXByZXNzCiAgICAgICAgICoKICAgICAgICAgKiBAdHlwZSB7Ym9vbGVhbn0KICAgICAgICAgKi8KICAgICAgICB2YXIgX2lnbm9yZU5leHRLZXlwcmVzcyA9IGZhbHNlOwoKICAgICAgICAvKioKICAgICAgICAgKiBhcmUgd2UgY3VycmVudGx5IGluc2lkZSBvZiBhIHNlcXVlbmNlPwogICAgICAgICAqIHR5cGUgb2YgYWN0aW9uICgia2V5dXAiIG9yICJrZXlkb3duIiBvciAia2V5cHJlc3MiKSBvciBmYWxzZQogICAgICAgICAqCiAgICAgICAgICogQHR5cGUge2Jvb2xlYW58c3RyaW5nfQogICAgICAgICAqLwogICAgICAgIHZhciBfbmV4dEV4cGVjdGVkQWN0aW9uID0gZmFsc2U7CgogICAgICAgIC8qKgogICAgICAgICAqIHJlc2V0cyBhbGwgc2VxdWVuY2UgY291bnRlcnMgZXhjZXB0IGZvciB0aGUgb25lcyBwYXNzZWQgaW4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBkb05vdFJlc2V0CiAgICAgICAgICogQHJldHVybnMgdm9pZAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIF9yZXNldFNlcXVlbmNlcyhkb05vdFJlc2V0KSB7CiAgICAgICAgICAgIGRvTm90UmVzZXQgPSBkb05vdFJlc2V0IHx8IHt9OwoKICAgICAgICAgICAgdmFyIGFjdGl2ZVNlcXVlbmNlcyA9IGZhbHNlLAogICAgICAgICAgICAgICAga2V5OwoKICAgICAgICAgICAgZm9yIChrZXkgaW4gX3NlcXVlbmNlTGV2ZWxzKSB7CiAgICAgICAgICAgICAgICBpZiAoZG9Ob3RSZXNldFtrZXldKSB7CiAgICAgICAgICAgICAgICAgICAgYWN0aXZlU2VxdWVuY2VzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIF9zZXF1ZW5jZUxldmVsc1trZXldID0gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFhY3RpdmVTZXF1ZW5jZXMpIHsKICAgICAgICAgICAgICAgIF9uZXh0RXhwZWN0ZWRBY3Rpb24gPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogZmluZHMgYWxsIGNhbGxiYWNrcyB0aGF0IG1hdGNoIGJhc2VkIG9uIHRoZSBrZXljb2RlLCBtb2RpZmllcnMsCiAgICAgICAgICogYW5kIGFjdGlvbgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGNoYXJhY3RlcgogICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IG1vZGlmaWVycwogICAgICAgICAqIEBwYXJhbSB7RXZlbnR8T2JqZWN0fSBlCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmc9fSBzZXF1ZW5jZU5hbWUgLSBuYW1lIG9mIHRoZSBzZXF1ZW5jZSB3ZSBhcmUgbG9va2luZyBmb3IKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZz19IGNvbWJpbmF0aW9uCiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBsZXZlbAogICAgICAgICAqIEByZXR1cm5zIHtBcnJheX0KICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBfZ2V0TWF0Y2hlcyhjaGFyYWN0ZXIsIG1vZGlmaWVycywgZSwgc2VxdWVuY2VOYW1lLCBjb21iaW5hdGlvbiwgbGV2ZWwpIHsKICAgICAgICAgICAgdmFyIGk7CiAgICAgICAgICAgIHZhciBjYWxsYmFjazsKICAgICAgICAgICAgdmFyIG1hdGNoZXMgPSBbXTsKICAgICAgICAgICAgdmFyIGFjdGlvbiA9IGUudHlwZTsKCiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGFyZSBubyBldmVudHMgcmVsYXRlZCB0byB0aGlzIGtleWNvZGUKICAgICAgICAgICAgaWYgKCFzZWxmLl9jYWxsYmFja3NbY2hhcmFjdGVyXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIFtdOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBpZiBhIG1vZGlmaWVyIGtleSBpcyBjb21pbmcgdXAgb24gaXRzIG93biB3ZSBzaG91bGQgYWxsb3cgaXQKICAgICAgICAgICAgaWYgKGFjdGlvbiA9PSAna2V5dXAnICYmIF9pc01vZGlmaWVyKGNoYXJhY3RlcikpIHsKICAgICAgICAgICAgICAgIG1vZGlmaWVycyA9IFtjaGFyYWN0ZXJdOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBsb29wIHRocm91Z2ggYWxsIGNhbGxiYWNrcyBmb3IgdGhlIGtleSB0aGF0IHdhcyBwcmVzc2VkCiAgICAgICAgICAgIC8vIGFuZCBzZWUgaWYgYW55IG9mIHRoZW0gbWF0Y2gKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHNlbGYuX2NhbGxiYWNrc1tjaGFyYWN0ZXJdLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgICAgICBjYWxsYmFjayA9IHNlbGYuX2NhbGxiYWNrc1tjaGFyYWN0ZXJdW2ldOwoKICAgICAgICAgICAgICAgIC8vIGlmIGEgc2VxdWVuY2UgbmFtZSBpcyBub3Qgc3BlY2lmaWVkLCBidXQgdGhpcyBpcyBhIHNlcXVlbmNlIGF0CiAgICAgICAgICAgICAgICAvLyB0aGUgd3JvbmcgbGV2ZWwgdGhlbiBtb3ZlIG9udG8gdGhlIG5leHQgbWF0Y2gKICAgICAgICAgICAgICAgIGlmICghc2VxdWVuY2VOYW1lICYmIGNhbGxiYWNrLnNlcSAmJiBfc2VxdWVuY2VMZXZlbHNbY2FsbGJhY2suc2VxXSAhPSBjYWxsYmFjay5sZXZlbCkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBhY3Rpb24gd2UgYXJlIGxvb2tpbmcgZm9yIGRvZXNuJ3QgbWF0Y2ggdGhlIGFjdGlvbiB3ZSBnb3QKICAgICAgICAgICAgICAgIC8vIHRoZW4gd2Ugc2hvdWxkIGtlZXAgZ29pbmcKICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gIT0gY2FsbGJhY2suYWN0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gaWYgdGhpcyBpcyBhIGtleXByZXNzIGV2ZW50IGFuZCB0aGUgbWV0YSBrZXkgYW5kIGNvbnRyb2wga2V5CiAgICAgICAgICAgICAgICAvLyBhcmUgbm90IHByZXNzZWQgdGhhdCBtZWFucyB0aGF0IHdlIG5lZWQgdG8gb25seSBsb29rIGF0IHRoZQogICAgICAgICAgICAgICAgLy8gY2hhcmFjdGVyLCBvdGhlcndpc2UgY2hlY2sgdGhlIG1vZGlmaWVycyBhcyB3ZWxsCiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgLy8gY2hyb21lIHdpbGwgbm90IGZpcmUgYSBrZXlwcmVzcyBpZiBtZXRhIG9yIGNvbnRyb2wgaXMgZG93bgogICAgICAgICAgICAgICAgLy8gc2FmYXJpIHdpbGwgZmlyZSBhIGtleXByZXNzIGlmIG1ldGEgb3IgbWV0YStzaGlmdCBpcyBkb3duCiAgICAgICAgICAgICAgICAvLyBmaXJlZm94IHdpbGwgZmlyZSBhIGtleXByZXNzIGlmIG1ldGEgb3IgY29udHJvbCBpcyBkb3duCiAgICAgICAgICAgICAgICBpZiAoKGFjdGlvbiA9PSAna2V5cHJlc3MnICYmICFlLm1ldGFLZXkgJiYgIWUuY3RybEtleSkgfHwgX21vZGlmaWVyc01hdGNoKG1vZGlmaWVycywgY2FsbGJhY2subW9kaWZpZXJzKSkgewoKICAgICAgICAgICAgICAgICAgICAvLyB3aGVuIHlvdSBiaW5kIGEgY29tYmluYXRpb24gb3Igc2VxdWVuY2UgYSBzZWNvbmQgdGltZSBpdAogICAgICAgICAgICAgICAgICAgIC8vIHNob3VsZCBvdmVyd3JpdGUgdGhlIGZpcnN0IG9uZS4gIGlmIGEgc2VxdWVuY2VOYW1lIG9yCiAgICAgICAgICAgICAgICAgICAgLy8gY29tYmluYXRpb24gaXMgc3BlY2lmaWVkIGluIHRoaXMgY2FsbCBpdCBkb2VzIGp1c3QgdGhhdAogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgLy8gQHRvZG8gbWFrZSBkZWxldGluZyBpdHMgb3duIG1ldGhvZD8KICAgICAgICAgICAgICAgICAgICB2YXIgZGVsZXRlQ29tYm8gPSAhc2VxdWVuY2VOYW1lICYmIGNhbGxiYWNrLmNvbWJvID09IGNvbWJpbmF0aW9uOwogICAgICAgICAgICAgICAgICAgIHZhciBkZWxldGVTZXF1ZW5jZSA9IHNlcXVlbmNlTmFtZSAmJiBjYWxsYmFjay5zZXEgPT0gc2VxdWVuY2VOYW1lICYmIGNhbGxiYWNrLmxldmVsID09IGxldmVsOwogICAgICAgICAgICAgICAgICAgIGlmIChkZWxldGVDb21ibyB8fCBkZWxldGVTZXF1ZW5jZSkgewogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jYWxsYmFja3NbY2hhcmFjdGVyXS5zcGxpY2UoaSwgMSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBtYXRjaGVzLnB1c2goY2FsbGJhY2spOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbWF0Y2hlczsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIGFjdHVhbGx5IGNhbGxzIHRoZSBjYWxsYmFjayBmdW5jdGlvbgogICAgICAgICAqCiAgICAgICAgICogaWYgeW91ciBjYWxsYmFjayBmdW5jdGlvbiByZXR1cm5zIGZhbHNlIHRoaXMgd2lsbCB1c2UgdGhlIGpxdWVyeQogICAgICAgICAqIGNvbnZlbnRpb24gLSBwcmV2ZW50IGRlZmF1bHQgYW5kIHN0b3AgcHJvcG9nYXRpb24gb24gdGhlIGV2ZW50CiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjawogICAgICAgICAqIEBwYXJhbSB7RXZlbnR9IGUKICAgICAgICAgKiBAcmV0dXJucyB2b2lkCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gX2ZpcmVDYWxsYmFjayhjYWxsYmFjaywgZSwgY29tYm8sIHNlcXVlbmNlKSB7CgogICAgICAgICAgICAvLyBpZiB0aGlzIGV2ZW50IHNob3VsZCBub3QgaGFwcGVuIHN0b3AgaGVyZQogICAgICAgICAgICBpZiAoc2VsZi5zdG9wQ2FsbGJhY2soZSwgZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50LCBjb21ibywgc2VxdWVuY2UpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjYWxsYmFjayhlLCBjb21ibykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICBfcHJldmVudERlZmF1bHQoZSk7CiAgICAgICAgICAgICAgICBfc3RvcFByb3BhZ2F0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBoYW5kbGVzIGEgY2hhcmFjdGVyIGtleSBldmVudAogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGNoYXJhY3RlcgogICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IG1vZGlmaWVycwogICAgICAgICAqIEBwYXJhbSB7RXZlbnR9IGUKICAgICAgICAgKiBAcmV0dXJucyB2b2lkCiAgICAgICAgICovCiAgICAgICAgc2VsZi5faGFuZGxlS2V5ID0gZnVuY3Rpb24oY2hhcmFjdGVyLCBtb2RpZmllcnMsIGUpIHsKICAgICAgICAgICAgdmFyIGNhbGxiYWNrcyA9IF9nZXRNYXRjaGVzKGNoYXJhY3RlciwgbW9kaWZpZXJzLCBlKTsKICAgICAgICAgICAgdmFyIGk7CiAgICAgICAgICAgIHZhciBkb05vdFJlc2V0ID0ge307CiAgICAgICAgICAgIHZhciBtYXhMZXZlbCA9IDA7CiAgICAgICAgICAgIHZhciBwcm9jZXNzZWRTZXF1ZW5jZUNhbGxiYWNrID0gZmFsc2U7CgogICAgICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIG1heExldmVsIGZvciBzZXF1ZW5jZXMgc28gd2UgY2FuIG9ubHkgZXhlY3V0ZSB0aGUgbG9uZ2VzdCBjYWxsYmFjayBzZXF1ZW5jZQogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY2FsbGJhY2tzLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2tzW2ldLnNlcSkgewogICAgICAgICAgICAgICAgICAgIG1heExldmVsID0gTWF0aC5tYXgobWF4TGV2ZWwsIGNhbGxiYWNrc1tpXS5sZXZlbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGxvb3AgdGhyb3VnaCBtYXRjaGluZyBjYWxsYmFja3MgZm9yIHRoaXMga2V5IGV2ZW50CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyArK2kpIHsKCiAgICAgICAgICAgICAgICAvLyBmaXJlIGZvciBhbGwgc2VxdWVuY2UgY2FsbGJhY2tzCiAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIGJlY2F1c2UgaWYgZm9yIGV4YW1wbGUgeW91IGhhdmUgbXVsdGlwbGUgc2VxdWVuY2VzCiAgICAgICAgICAgICAgICAvLyBib3VuZCBzdWNoIGFzICJnIGkiIGFuZCAiZyB0IiB0aGV5IGJvdGggbmVlZCB0byBmaXJlIHRoZQogICAgICAgICAgICAgICAgLy8gY2FsbGJhY2sgZm9yIG1hdGNoaW5nIGcgY2F1c2Ugb3RoZXJ3aXNlIHlvdSBjYW4gb25seSBldmVyCiAgICAgICAgICAgICAgICAvLyBtYXRjaCB0aGUgZmlyc3Qgb25lCiAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2tzW2ldLnNlcSkgewoKICAgICAgICAgICAgICAgICAgICAvLyBvbmx5IGZpcmUgY2FsbGJhY2tzIGZvciB0aGUgbWF4TGV2ZWwgdG8gcHJldmVudAogICAgICAgICAgICAgICAgICAgIC8vIHN1YnNlcXVlbmNlcyBmcm9tIGFsc28gZmlyaW5nCiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAvLyBmb3IgZXhhbXBsZSAnYSBvcHRpb24gYicgc2hvdWxkIG5vdCBjYXVzZSAnb3B0aW9uIGInIHRvIGZpcmUKICAgICAgICAgICAgICAgICAgICAvLyBldmVuIHRob3VnaCAnb3B0aW9uIGInIGlzIHBhcnQgb2YgdGhlIG90aGVyIHNlcXVlbmNlCiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAvLyBhbnkgc2VxdWVuY2VzIHRoYXQgZG8gbm90IG1hdGNoIGhlcmUgd2lsbCBiZSBkaXNjYXJkZWQKICAgICAgICAgICAgICAgICAgICAvLyBiZWxvdyBieSB0aGUgX3Jlc2V0U2VxdWVuY2VzIGNhbGwKICAgICAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2tzW2ldLmxldmVsICE9IG1heExldmVsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc2VkU2VxdWVuY2VDYWxsYmFjayA9IHRydWU7CgogICAgICAgICAgICAgICAgICAgIC8vIGtlZXAgYSBsaXN0IG9mIHdoaWNoIHNlcXVlbmNlcyB3ZXJlIG1hdGNoZXMgZm9yIGxhdGVyCiAgICAgICAgICAgICAgICAgICAgZG9Ob3RSZXNldFtjYWxsYmFja3NbaV0uc2VxXSA9IDE7CiAgICAgICAgICAgICAgICAgICAgX2ZpcmVDYWxsYmFjayhjYWxsYmFja3NbaV0uY2FsbGJhY2ssIGUsIGNhbGxiYWNrc1tpXS5jb21ibywgY2FsbGJhY2tzW2ldLnNlcSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gaWYgdGhlcmUgd2VyZSBubyBzZXF1ZW5jZSBtYXRjaGVzIGJ1dCB3ZSBhcmUgc3RpbGwgaGVyZQogICAgICAgICAgICAgICAgLy8gdGhhdCBtZWFucyB0aGlzIGlzIGEgcmVndWxhciBtYXRjaCBzbyB3ZSBzaG91bGQgZmlyZSB0aGF0CiAgICAgICAgICAgICAgICBpZiAoIXByb2Nlc3NlZFNlcXVlbmNlQ2FsbGJhY2spIHsKICAgICAgICAgICAgICAgICAgICBfZmlyZUNhbGxiYWNrKGNhbGxiYWNrc1tpXS5jYWxsYmFjaywgZSwgY2FsbGJhY2tzW2ldLmNvbWJvKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gaWYgdGhlIGtleSB5b3UgcHJlc3NlZCBtYXRjaGVzIHRoZSB0eXBlIG9mIHNlcXVlbmNlIHdpdGhvdXQKICAgICAgICAgICAgLy8gYmVpbmcgYSBtb2RpZmllciAoaWUgImtleXVwIiBvciAia2V5cHJlc3MiKSB0aGVuIHdlIHNob3VsZAogICAgICAgICAgICAvLyByZXNldCBhbGwgc2VxdWVuY2VzIHRoYXQgd2VyZSBub3QgbWF0Y2hlZCBieSB0aGlzIGV2ZW50CiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIHRoaXMgaXMgc28sIGZvciBleGFtcGxlLCBpZiB5b3UgaGF2ZSB0aGUgc2VxdWVuY2UgImggYSB0IiBhbmQgeW91CiAgICAgICAgICAgIC8vIHR5cGUgImggZSBhIHIgdCIgaXQgZG9lcyBub3QgbWF0Y2guICBpbiB0aGlzIGNhc2UgdGhlICJlIiB3aWxsCiAgICAgICAgICAgIC8vIGNhdXNlIHRoZSBzZXF1ZW5jZSB0byByZXNldAogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyBtb2RpZmllciBrZXlzIGFyZSBpZ25vcmVkIGJlY2F1c2UgeW91IGNhbiBoYXZlIGEgc2VxdWVuY2UKICAgICAgICAgICAgLy8gdGhhdCBjb250YWlucyBtb2RpZmllcnMgc3VjaCBhcyAiZW50ZXIgY3RybCtzcGFjZSIgYW5kIGluIG1vc3QKICAgICAgICAgICAgLy8gY2FzZXMgdGhlIG1vZGlmaWVyIGtleSB3aWxsIGJlIHByZXNzZWQgYmVmb3JlIHRoZSBuZXh0IGtleQogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyBhbHNvIGlmIHlvdSBoYXZlIGEgc2VxdWVuY2Ugc3VjaCBhcyAiY3RybCtiIGEiIHRoZW4gcHJlc3NpbmcgdGhlCiAgICAgICAgICAgIC8vICJiIiBrZXkgd2lsbCB0cmlnZ2VyIGEgImtleXByZXNzIiBhbmQgYSAia2V5ZG93biIKICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gdGhlICJrZXlkb3duIiBpcyBleHBlY3RlZCB3aGVuIHRoZXJlIGlzIGEgbW9kaWZpZXIsIGJ1dCB0aGUKICAgICAgICAgICAgLy8gImtleXByZXNzIiBlbmRzIHVwIG1hdGNoaW5nIHRoZSBfbmV4dEV4cGVjdGVkQWN0aW9uIHNpbmNlIGl0IG9jY3VycwogICAgICAgICAgICAvLyBhZnRlciBhbmQgdGhhdCBjYXVzZXMgdGhlIHNlcXVlbmNlIHRvIHJlc2V0CiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIHdlIGlnbm9yZSBrZXlwcmVzc2VzIGluIGEgc2VxdWVuY2UgdGhhdCBkaXJlY3RseSBmb2xsb3cgYSBrZXlkb3duCiAgICAgICAgICAgIC8vIGZvciB0aGUgc2FtZSBjaGFyYWN0ZXIKICAgICAgICAgICAgdmFyIGlnbm9yZVRoaXNLZXlwcmVzcyA9IGUudHlwZSA9PSAna2V5cHJlc3MnICYmIF9pZ25vcmVOZXh0S2V5cHJlc3M7CiAgICAgICAgICAgIGlmIChlLnR5cGUgPT0gX25leHRFeHBlY3RlZEFjdGlvbiAmJiAhX2lzTW9kaWZpZXIoY2hhcmFjdGVyKSAmJiAhaWdub3JlVGhpc0tleXByZXNzKSB7CiAgICAgICAgICAgICAgICBfcmVzZXRTZXF1ZW5jZXMoZG9Ob3RSZXNldCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIF9pZ25vcmVOZXh0S2V5cHJlc3MgPSBwcm9jZXNzZWRTZXF1ZW5jZUNhbGxiYWNrICYmIGUudHlwZSA9PSAna2V5ZG93bic7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICogaGFuZGxlcyBhIGtleWRvd24gZXZlbnQKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7RXZlbnR9IGUKICAgICAgICAgKiBAcmV0dXJucyB2b2lkCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gX2hhbmRsZUtleUV2ZW50KGUpIHsKCiAgICAgICAgICAgIC8vIG5vcm1hbGl6ZSBlLndoaWNoIGZvciBrZXkgZXZlbnRzCiAgICAgICAgICAgIC8vIEBzZWUgaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80Mjg1NjI3L2phdmFzY3JpcHQta2V5Y29kZS12cy1jaGFyY29kZS11dHRlci1jb25mdXNpb24KICAgICAgICAgICAgaWYgKHR5cGVvZiBlLndoaWNoICE9PSAnbnVtYmVyJykgewogICAgICAgICAgICAgICAgZS53aGljaCA9IGUua2V5Q29kZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGNoYXJhY3RlciA9IF9jaGFyYWN0ZXJGcm9tRXZlbnQoZSk7CgogICAgICAgICAgICAvLyBubyBjaGFyYWN0ZXIgZm91bmQgdGhlbiBzdG9wCiAgICAgICAgICAgIGlmICghY2hhcmFjdGVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIG5lZWQgdG8gdXNlID09PSBmb3IgdGhlIGNoYXJhY3RlciBjaGVjayBiZWNhdXNlIHRoZSBjaGFyYWN0ZXIgY2FuIGJlIDAKICAgICAgICAgICAgaWYgKGUudHlwZSA9PSAna2V5dXAnICYmIF9pZ25vcmVOZXh0S2V5dXAgPT09IGNoYXJhY3RlcikgewogICAgICAgICAgICAgICAgX2lnbm9yZU5leHRLZXl1cCA9IGZhbHNlOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzZWxmLmhhbmRsZUtleShjaGFyYWN0ZXIsIF9ldmVudE1vZGlmaWVycyhlKSwgZSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBjYWxsZWQgdG8gc2V0IGEgMSBzZWNvbmQgdGltZW91dCBvbiB0aGUgc3BlY2lmaWVkIHNlcXVlbmNlCiAgICAgICAgICoKICAgICAgICAgKiB0aGlzIGlzIHNvIGFmdGVyIGVhY2gga2V5IHByZXNzIGluIHRoZSBzZXF1ZW5jZSB5b3UgaGF2ZSAxIHNlY29uZAogICAgICAgICAqIHRvIHByZXNzIHRoZSBuZXh0IGtleSBiZWZvcmUgeW91IGhhdmUgdG8gc3RhcnQgb3ZlcgogICAgICAgICAqCiAgICAgICAgICogQHJldHVybnMgdm9pZAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIF9yZXNldFNlcXVlbmNlVGltZXIoKSB7CiAgICAgICAgICAgIGNsZWFyVGltZW91dChfcmVzZXRUaW1lcik7CiAgICAgICAgICAgIF9yZXNldFRpbWVyID0gc2V0VGltZW91dChfcmVzZXRTZXF1ZW5jZXMsIDEwMDApOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogYmluZHMgYSBrZXkgc2VxdWVuY2UgdG8gYW4gZXZlbnQKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjb21ibyAtIGNvbWJvIHNwZWNpZmllZCBpbiBiaW5kIGNhbGwKICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBrZXlzCiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZz19IGFjdGlvbgogICAgICAgICAqIEByZXR1cm5zIHZvaWQKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBfYmluZFNlcXVlbmNlKGNvbWJvLCBrZXlzLCBjYWxsYmFjaywgYWN0aW9uKSB7CgogICAgICAgICAgICAvLyBzdGFydCBvZmYgYnkgYWRkaW5nIGEgc2VxdWVuY2UgbGV2ZWwgcmVjb3JkIGZvciB0aGlzIGNvbWJpbmF0aW9uCiAgICAgICAgICAgIC8vIGFuZCBzZXR0aW5nIHRoZSBsZXZlbCB0byAwCiAgICAgICAgICAgIF9zZXF1ZW5jZUxldmVsc1tjb21ib10gPSAwOwoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIGNhbGxiYWNrIHRvIGluY3JlYXNlIHRoZSBzZXF1ZW5jZSBsZXZlbCBmb3IgdGhpcyBzZXF1ZW5jZSBhbmQgcmVzZXQKICAgICAgICAgICAgICogYWxsIG90aGVyIHNlcXVlbmNlcyB0aGF0IHdlcmUgYWN0aXZlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuZXh0QWN0aW9uCiAgICAgICAgICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZ1bmN0aW9uIF9pbmNyZWFzZVNlcXVlbmNlKG5leHRBY3Rpb24pIHsKICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICBfbmV4dEV4cGVjdGVkQWN0aW9uID0gbmV4dEFjdGlvbjsKICAgICAgICAgICAgICAgICAgICArK19zZXF1ZW5jZUxldmVsc1tjb21ib107CiAgICAgICAgICAgICAgICAgICAgX3Jlc2V0U2VxdWVuY2VUaW1lcigpOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIHdyYXBzIHRoZSBzcGVjaWZpZWQgY2FsbGJhY2sgaW5zaWRlIG9mIGFub3RoZXIgZnVuY3Rpb24gaW4gb3JkZXIKICAgICAgICAgICAgICogdG8gcmVzZXQgYWxsIHNlcXVlbmNlIGNvdW50ZXJzIGFzIHNvb24gYXMgdGhpcyBzZXF1ZW5jZSBpcyBkb25lCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7RXZlbnR9IGUKICAgICAgICAgICAgICogQHJldHVybnMgdm9pZAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZnVuY3Rpb24gX2NhbGxiYWNrQW5kUmVzZXQoZSkgewogICAgICAgICAgICAgICAgX2ZpcmVDYWxsYmFjayhjYWxsYmFjaywgZSwgY29tYm8pOwoKICAgICAgICAgICAgICAgIC8vIHdlIHNob3VsZCBpZ25vcmUgdGhlIG5leHQga2V5IHVwIGlmIHRoZSBhY3Rpb24gaXMga2V5IGRvd24KICAgICAgICAgICAgICAgIC8vIG9yIGtleXByZXNzLiAgdGhpcyBpcyBzbyBpZiB5b3UgZmluaXNoIGEgc2VxdWVuY2UgYW5kCiAgICAgICAgICAgICAgICAvLyByZWxlYXNlIHRoZSBrZXkgdGhlIGZpbmFsIGtleSB3aWxsIG5vdCB0cmlnZ2VyIGEga2V5dXAKICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gIT09ICdrZXl1cCcpIHsKICAgICAgICAgICAgICAgICAgICBfaWdub3JlTmV4dEtleXVwID0gX2NoYXJhY3RlckZyb21FdmVudChlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyB3ZWlyZCByYWNlIGNvbmRpdGlvbiBpZiBhIHNlcXVlbmNlIGVuZHMgd2l0aCB0aGUga2V5CiAgICAgICAgICAgICAgICAvLyBhbm90aGVyIHNlcXVlbmNlIGJlZ2lucyB3aXRoCiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KF9yZXNldFNlcXVlbmNlcywgMTApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBsb29wIHRocm91Z2gga2V5cyBvbmUgYXQgYSB0aW1lIGFuZCBiaW5kIHRoZSBhcHByb3ByaWF0ZSBjYWxsYmFjawogICAgICAgICAgICAvLyBmdW5jdGlvbi4gIGZvciBhbnkga2V5IGxlYWRpbmcgdXAgdG8gdGhlIGZpbmFsIG9uZSBpdCBzaG91bGQKICAgICAgICAgICAgLy8gaW5jcmVhc2UgdGhlIHNlcXVlbmNlLiBhZnRlciB0aGUgZmluYWwsIGl0IHNob3VsZCByZXNldCBhbGwgc2VxdWVuY2VzCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIGlmIGFuIGFjdGlvbiBpcyBzcGVjaWZpZWQgaW4gdGhlIG9yaWdpbmFsIGJpbmQgY2FsbCB0aGVuIHRoYXQgd2lsbAogICAgICAgICAgICAvLyBiZSB1c2VkIHRocm91Z2hvdXQuICBvdGhlcndpc2Ugd2Ugd2lsbCBwYXNzIHRoZSBhY3Rpb24gdGhhdCB0aGUKICAgICAgICAgICAgLy8gbmV4dCBrZXkgaW4gdGhlIHNlcXVlbmNlIHNob3VsZCBtYXRjaC4gIHRoaXMgYWxsb3dzIGEgc2VxdWVuY2UKICAgICAgICAgICAgLy8gdG8gbWl4IGFuZCBtYXRjaCBrZXlwcmVzcyBhbmQga2V5ZG93biBldmVudHMgZGVwZW5kaW5nIG9uIHdoaWNoCiAgICAgICAgICAgIC8vIG9uZXMgYXJlIGJldHRlciBzdWl0ZWQgdG8gdGhlIGtleSBwcm92aWRlZAogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIHZhciBpc0ZpbmFsID0gaSArIDEgPT09IGtleXMubGVuZ3RoOwogICAgICAgICAgICAgICAgdmFyIHdyYXBwZWRDYWxsYmFjayA9IGlzRmluYWwgPyBfY2FsbGJhY2tBbmRSZXNldCA6IF9pbmNyZWFzZVNlcXVlbmNlKGFjdGlvbiB8fCBfZ2V0S2V5SW5mbyhrZXlzW2kgKyAxXSkuYWN0aW9uKTsKICAgICAgICAgICAgICAgIF9iaW5kU2luZ2xlKGtleXNbaV0sIHdyYXBwZWRDYWxsYmFjaywgYWN0aW9uLCBjb21ibywgaSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIGJpbmRzIGEgc2luZ2xlIGtleWJvYXJkIGNvbWJpbmF0aW9uCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gY29tYmluYXRpb24KICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjawogICAgICAgICAqIEBwYXJhbSB7c3RyaW5nPX0gYWN0aW9uCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmc9fSBzZXF1ZW5jZU5hbWUgLSBuYW1lIG9mIHNlcXVlbmNlIGlmIHBhcnQgb2Ygc2VxdWVuY2UKICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IGxldmVsIC0gd2hhdCBwYXJ0IG9mIHRoZSBzZXF1ZW5jZSB0aGUgY29tbWFuZCBpcwogICAgICAgICAqIEByZXR1cm5zIHZvaWQKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBfYmluZFNpbmdsZShjb21iaW5hdGlvbiwgY2FsbGJhY2ssIGFjdGlvbiwgc2VxdWVuY2VOYW1lLCBsZXZlbCkgewoKICAgICAgICAgICAgLy8gc3RvcmUgYSBkaXJlY3QgbWFwcGVkIHJlZmVyZW5jZSBmb3IgdXNlIHdpdGggTW91c2V0cmFwLnRyaWdnZXIKICAgICAgICAgICAgc2VsZi5fZGlyZWN0TWFwW2NvbWJpbmF0aW9uICsgJzonICsgYWN0aW9uXSA9IGNhbGxiYWNrOwoKICAgICAgICAgICAgLy8gbWFrZSBzdXJlIG11bHRpcGxlIHNwYWNlcyBpbiBhIHJvdyBiZWNvbWUgYSBzaW5nbGUgc3BhY2UKICAgICAgICAgICAgY29tYmluYXRpb24gPSBjb21iaW5hdGlvbi5yZXBsYWNlKC9ccysvZywgJyAnKTsKCiAgICAgICAgICAgIHZhciBzZXF1ZW5jZSA9IGNvbWJpbmF0aW9uLnNwbGl0KCcgJyk7CiAgICAgICAgICAgIHZhciBpbmZvOwoKICAgICAgICAgICAgLy8gaWYgdGhpcyBwYXR0ZXJuIGlzIGEgc2VxdWVuY2Ugb2Yga2V5cyB0aGVuIHJ1biB0aHJvdWdoIHRoaXMgbWV0aG9kCiAgICAgICAgICAgIC8vIHRvIHJlcHJvY2VzcyBlYWNoIHBhdHRlcm4gb25lIGtleSBhdCBhIHRpbWUKICAgICAgICAgICAgaWYgKHNlcXVlbmNlLmxlbmd0aCA+IDEpIHsKICAgICAgICAgICAgICAgIF9iaW5kU2VxdWVuY2UoY29tYmluYXRpb24sIHNlcXVlbmNlLCBjYWxsYmFjaywgYWN0aW9uKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaW5mbyA9IF9nZXRLZXlJbmZvKGNvbWJpbmF0aW9uLCBhY3Rpb24pOwoKICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRvIGluaXRpYWxpemUgYXJyYXkgaWYgdGhpcyBpcyB0aGUgZmlyc3QgdGltZQogICAgICAgICAgICAvLyBhIGNhbGxiYWNrIGlzIGFkZGVkIGZvciB0aGlzIGtleQogICAgICAgICAgICBzZWxmLl9jYWxsYmFja3NbaW5mby5rZXldID0gc2VsZi5fY2FsbGJhY2tzW2luZm8ua2V5XSB8fCBbXTsKCiAgICAgICAgICAgIC8vIHJlbW92ZSBhbiBleGlzdGluZyBtYXRjaCBpZiB0aGVyZSBpcyBvbmUKICAgICAgICAgICAgX2dldE1hdGNoZXMoaW5mby5rZXksIGluZm8ubW9kaWZpZXJzLCB7dHlwZTogaW5mby5hY3Rpb259LCBzZXF1ZW5jZU5hbWUsIGNvbWJpbmF0aW9uLCBsZXZlbCk7CgogICAgICAgICAgICAvLyBhZGQgdGhpcyBjYWxsIGJhY2sgdG8gdGhlIGFycmF5CiAgICAgICAgICAgIC8vIGlmIGl0IGlzIGEgc2VxdWVuY2UgcHV0IGl0IGF0IHRoZSBiZWdpbm5pbmcKICAgICAgICAgICAgLy8gaWYgbm90IHB1dCBpdCBhdCB0aGUgZW5kCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIHRoaXMgaXMgaW1wb3J0YW50IGJlY2F1c2UgdGhlIHdheSB0aGVzZSBhcmUgcHJvY2Vzc2VkIGV4cGVjdHMKICAgICAgICAgICAgLy8gdGhlIHNlcXVlbmNlIG9uZXMgdG8gY29tZSBmaXJzdAogICAgICAgICAgICBzZWxmLl9jYWxsYmFja3NbaW5mby5rZXldW3NlcXVlbmNlTmFtZSA/ICd1bnNoaWZ0JyA6ICdwdXNoJ10oewogICAgICAgICAgICAgICAgY2FsbGJhY2s6IGNhbGxiYWNrLAogICAgICAgICAgICAgICAgbW9kaWZpZXJzOiBpbmZvLm1vZGlmaWVycywKICAgICAgICAgICAgICAgIGFjdGlvbjogaW5mby5hY3Rpb24sCiAgICAgICAgICAgICAgICBzZXE6IHNlcXVlbmNlTmFtZSwKICAgICAgICAgICAgICAgIGxldmVsOiBsZXZlbCwKICAgICAgICAgICAgICAgIGNvbWJvOiBjb21iaW5hdGlvbgogICAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIGJpbmRzIG11bHRpcGxlIGNvbWJpbmF0aW9ucyB0byB0aGUgc2FtZSBjYWxsYmFjawogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtBcnJheX0gY29tYmluYXRpb25zCiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ3x1bmRlZmluZWR9IGFjdGlvbgogICAgICAgICAqIEByZXR1cm5zIHZvaWQKICAgICAgICAgKi8KICAgICAgICBzZWxmLl9iaW5kTXVsdGlwbGUgPSBmdW5jdGlvbihjb21iaW5hdGlvbnMsIGNhbGxiYWNrLCBhY3Rpb24pIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb21iaW5hdGlvbnMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIF9iaW5kU2luZ2xlKGNvbWJpbmF0aW9uc1tpXSwgY2FsbGJhY2ssIGFjdGlvbik7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICAvLyBzdGFydCEKICAgICAgICBfYWRkRXZlbnQodGFyZ2V0RWxlbWVudCwgJ2tleXByZXNzJywgX2hhbmRsZUtleUV2ZW50KTsKICAgICAgICBfYWRkRXZlbnQodGFyZ2V0RWxlbWVudCwgJ2tleWRvd24nLCBfaGFuZGxlS2V5RXZlbnQpOwogICAgICAgIF9hZGRFdmVudCh0YXJnZXRFbGVtZW50LCAna2V5dXAnLCBfaGFuZGxlS2V5RXZlbnQpOwogICAgfQoKICAgIC8qKgogICAgICogYmluZHMgYW4gZXZlbnQgdG8gbW91c2V0cmFwCiAgICAgKgogICAgICogY2FuIGJlIGEgc2luZ2xlIGtleSwgYSBjb21iaW5hdGlvbiBvZiBrZXlzIHNlcGFyYXRlZCB3aXRoICssCiAgICAgKiBhbiBhcnJheSBvZiBrZXlzLCBvciBhIHNlcXVlbmNlIG9mIGtleXMgc2VwYXJhdGVkIGJ5IHNwYWNlcwogICAgICoKICAgICAqIGJlIHN1cmUgdG8gbGlzdCB0aGUgbW9kaWZpZXIga2V5cyBmaXJzdCB0byBtYWtlIHN1cmUgdGhhdCB0aGUKICAgICAqIGNvcnJlY3Qga2V5IGVuZHMgdXAgZ2V0dGluZyBib3VuZCAodGhlIGxhc3Qga2V5IGluIHRoZSBwYXR0ZXJuKQogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfEFycmF5fSBrZXlzCiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjawogICAgICogQHBhcmFtIHtzdHJpbmc9fSBhY3Rpb24gLSAna2V5cHJlc3MnLCAna2V5ZG93bicsIG9yICdrZXl1cCcKICAgICAqIEByZXR1cm5zIHZvaWQKICAgICAqLwogICAgTW91c2V0cmFwLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24oa2V5cywgY2FsbGJhY2ssIGFjdGlvbikgewogICAgICAgIHZhciBzZWxmID0gdGhpczsKICAgICAgICBrZXlzID0ga2V5cyBpbnN0YW5jZW9mIEFycmF5ID8ga2V5cyA6IFtrZXlzXTsKICAgICAgICBzZWxmLl9iaW5kTXVsdGlwbGUuY2FsbChzZWxmLCBrZXlzLCBjYWxsYmFjaywgYWN0aW9uKTsKICAgICAgICByZXR1cm4gc2VsZjsKICAgIH07CgogICAgLyoqCiAgICAgKiB1bmJpbmRzIGFuIGV2ZW50IHRvIG1vdXNldHJhcAogICAgICoKICAgICAqIHRoZSB1bmJpbmRpbmcgc2V0cyB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gb2YgdGhlIHNwZWNpZmllZCBrZXkgY29tYm8KICAgICAqIHRvIGFuIGVtcHR5IGZ1bmN0aW9uIGFuZCBkZWxldGVzIHRoZSBjb3JyZXNwb25kaW5nIGtleSBpbiB0aGUKICAgICAqIF9kaXJlY3RNYXAgZGljdC4KICAgICAqCiAgICAgKiBUT0RPOiBhY3R1YWxseSByZW1vdmUgdGhpcyBmcm9tIHRoZSBfY2FsbGJhY2tzIGRpY3Rpb25hcnkgaW5zdGVhZAogICAgICogb2YgYmluZGluZyBhbiBlbXB0eSBmdW5jdGlvbgogICAgICoKICAgICAqIHRoZSBrZXljb21ibythY3Rpb24gaGFzIHRvIGJlIGV4YWN0bHkgdGhlIHNhbWUgYXMKICAgICAqIGl0IHdhcyBkZWZpbmVkIGluIHRoZSBiaW5kIG1ldGhvZAogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfEFycmF5fSBrZXlzCiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYWN0aW9uCiAgICAgKiBAcmV0dXJucyB2b2lkCiAgICAgKi8KICAgIE1vdXNldHJhcC5wcm90b3R5cGUudW5iaW5kID0gZnVuY3Rpb24oa2V5cywgYWN0aW9uKSB7CiAgICAgICAgdmFyIHNlbGYgPSB0aGlzOwogICAgICAgIHJldHVybiBzZWxmLmJpbmQuY2FsbChzZWxmLCBrZXlzLCBmdW5jdGlvbigpIHt9LCBhY3Rpb24pOwogICAgfTsKCiAgICAvKioKICAgICAqIHRyaWdnZXJzIGFuIGV2ZW50IHRoYXQgaGFzIGFscmVhZHkgYmVlbiBib3VuZAogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlzCiAgICAgKiBAcGFyYW0ge3N0cmluZz19IGFjdGlvbgogICAgICogQHJldHVybnMgdm9pZAogICAgICovCiAgICBNb3VzZXRyYXAucHJvdG90eXBlLnRyaWdnZXIgPSBmdW5jdGlvbihrZXlzLCBhY3Rpb24pIHsKICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICAgICAgaWYgKHNlbGYuX2RpcmVjdE1hcFtrZXlzICsgJzonICsgYWN0aW9uXSkgewogICAgICAgICAgICBzZWxmLl9kaXJlY3RNYXBba2V5cyArICc6JyArIGFjdGlvbl0oe30sIGtleXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsZjsKICAgIH07CgogICAgLyoqCiAgICAgKiByZXNldHMgdGhlIGxpYnJhcnkgYmFjayB0byBpdHMgaW5pdGlhbCBzdGF0ZS4gIHRoaXMgaXMgdXNlZnVsCiAgICAgKiBpZiB5b3Ugd2FudCB0byBjbGVhciBvdXQgdGhlIGN1cnJlbnQga2V5Ym9hcmQgc2hvcnRjdXRzIGFuZCBiaW5kCiAgICAgKiBuZXcgb25lcyAtIGZvciBleGFtcGxlIGlmIHlvdSBzd2l0Y2ggdG8gYW5vdGhlciBwYWdlCiAgICAgKgogICAgICogQHJldHVybnMgdm9pZAogICAgICovCiAgICBNb3VzZXRyYXAucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIHNlbGYgPSB0aGlzOwogICAgICAgIHNlbGYuX2NhbGxiYWNrcyA9IHt9OwogICAgICAgIHNlbGYuX2RpcmVjdE1hcCA9IHt9OwogICAgICAgIHJldHVybiBzZWxmOwogICAgfTsKCiAgICAvKioKICAgICAqIHNob3VsZCB3ZSBzdG9wIHRoaXMgZXZlbnQgYmVmb3JlIGZpcmluZyBvZmYgY2FsbGJhY2tzCiAgICAgKgogICAgICogQHBhcmFtIHtFdmVudH0gZQogICAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50CiAgICAgKiBAcmV0dXJuIHtib29sZWFufQogICAgICovCiAgICBNb3VzZXRyYXAucHJvdG90eXBlLnN0b3BDYWxsYmFjayA9IGZ1bmN0aW9uKGUsIGVsZW1lbnQpIHsKICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CgogICAgICAgIC8vIGlmIHRoZSBlbGVtZW50IGhhcyB0aGUgY2xhc3MgIm1vdXNldHJhcCIgdGhlbiBubyBuZWVkIHRvIHN0b3AKICAgICAgICBpZiAoKCcgJyArIGVsZW1lbnQuY2xhc3NOYW1lICsgJyAnKS5pbmRleE9mKCcgbW91c2V0cmFwICcpID4gLTEpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKF9iZWxvbmdzVG8oZWxlbWVudCwgc2VsZi50YXJnZXQpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8vIHN0b3AgZm9yIGlucHV0LCBzZWxlY3QsIGFuZCB0ZXh0YXJlYQogICAgICAgIHJldHVybiBlbGVtZW50LnRhZ05hbWUgPT0gJ0lOUFVUJyB8fCBlbGVtZW50LnRhZ05hbWUgPT0gJ1NFTEVDVCcgfHwgZWxlbWVudC50YWdOYW1lID09ICdURVhUQVJFQScgfHwgZWxlbWVudC5pc0NvbnRlbnRFZGl0YWJsZTsKICAgIH07CgogICAgLyoqCiAgICAgKiBleHBvc2VzIF9oYW5kbGVLZXkgcHVibGljbHkgc28gaXQgY2FuIGJlIG92ZXJ3cml0dGVuIGJ5IGV4dGVuc2lvbnMKICAgICAqLwogICAgTW91c2V0cmFwLnByb3RvdHlwZS5oYW5kbGVLZXkgPSBmdW5jdGlvbigpIHsKICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICAgICAgcmV0dXJuIHNlbGYuX2hhbmRsZUtleS5hcHBseShzZWxmLCBhcmd1bWVudHMpOwogICAgfTsKCiAgICAvKioKICAgICAqIGFsbG93IGN1c3RvbSBrZXkgbWFwcGluZ3MKICAgICAqLwogICAgTW91c2V0cmFwLmFkZEtleWNvZGVzID0gZnVuY3Rpb24ob2JqZWN0KSB7CiAgICAgICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkgewogICAgICAgICAgICBpZiAob2JqZWN0Lmhhc093blByb3BlcnR5KGtleSkpIHsKICAgICAgICAgICAgICAgIF9NQVBba2V5XSA9IG9iamVjdFtrZXldOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIF9SRVZFUlNFX01BUCA9IG51bGw7CiAgICB9OwoKICAgIC8qKgogICAgICogSW5pdCB0aGUgZ2xvYmFsIG1vdXNldHJhcCBmdW5jdGlvbnMKICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBpcyBuZWVkZWQgdG8gYWxsb3cgdGhlIGdsb2JhbCBtb3VzZXRyYXAgZnVuY3Rpb25zIHRvIHdvcmsKICAgICAqIG5vdyB0aGF0IG1vdXNldHJhcCBpcyBhIGNvbnN0cnVjdG9yIGZ1bmN0aW9uLgogICAgICovCiAgICBNb3VzZXRyYXAuaW5pdCA9IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciBkb2N1bWVudE1vdXNldHJhcCA9IE1vdXNldHJhcChkb2N1bWVudCk7CiAgICAgICAgZm9yICh2YXIgbWV0aG9kIGluIGRvY3VtZW50TW91c2V0cmFwKSB7CiAgICAgICAgICAgIGlmIChtZXRob2QuY2hhckF0KDApICE9PSAnXycpIHsKICAgICAgICAgICAgICAgIE1vdXNldHJhcFttZXRob2RdID0gKGZ1bmN0aW9uKG1ldGhvZCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50TW91c2V0cmFwW21ldGhvZF0uYXBwbHkoZG9jdW1lbnRNb3VzZXRyYXAsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIH0gKG1ldGhvZCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKCiAgICBNb3VzZXRyYXAuaW5pdCgpOwoKICAgIC8vIGV4cG9zZSBtb3VzZXRyYXAgdG8gdGhlIGdsb2JhbCBvYmplY3QKICAgIHdpbmRvdy5Nb3VzZXRyYXAgPSBNb3VzZXRyYXA7CgogICAgLy8gZXhwb3NlIGFzIGEgY29tbW9uIGpzIG1vZHVsZQogICAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBNb3VzZXRyYXA7CiAgICB9CgogICAgLy8gZXhwb3NlIG1vdXNldHJhcCBhcyBhbiBBTUQgbW9kdWxlCiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7CiAgICAgICAgZGVmaW5lKGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gTW91c2V0cmFwOwogICAgICAgIH0pOwogICAgfQp9KSAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiBudWxsLCB0eXBlb2YgIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyBkb2N1bWVudCA6IG51bGwpOwo="},{"meta":{"name":"mousetrap-global-bind.js","url":"https://raw.githubusercontent.com/ccampbell/mousetrap/master/plugins/global-bind/mousetrap-global-bind.js","ts":1539246621153,"mimetype":"text/javascript"},"source":"LyoqCiAqIGFkZHMgYSBiaW5kR2xvYmFsIG1ldGhvZCB0byBNb3VzZXRyYXAgdGhhdCBhbGxvd3MgeW91IHRvCiAqIGJpbmQgc3BlY2lmaWMga2V5Ym9hcmQgc2hvcnRjdXRzIHRoYXQgd2lsbCBzdGlsbCB3b3JrCiAqIGluc2lkZSBhIHRleHQgaW5wdXQgZmllbGQKICoKICogdXNhZ2U6CiAqIE1vdXNldHJhcC5iaW5kR2xvYmFsKCdjdHJsK3MnLCBfc2F2ZUNoYW5nZXMpOwogKi8KLyogZ2xvYmFsIE1vdXNldHJhcDp0cnVlICovCihmdW5jdGlvbihNb3VzZXRyYXApIHsKICAgIHZhciBfZ2xvYmFsQ2FsbGJhY2tzID0ge307CiAgICB2YXIgX29yaWdpbmFsU3RvcENhbGxiYWNrID0gTW91c2V0cmFwLnByb3RvdHlwZS5zdG9wQ2FsbGJhY2s7CgogICAgTW91c2V0cmFwLnByb3RvdHlwZS5zdG9wQ2FsbGJhY2sgPSBmdW5jdGlvbihlLCBlbGVtZW50LCBjb21ibywgc2VxdWVuY2UpIHsKICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CgogICAgICAgIGlmIChzZWxmLnBhdXNlZCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmIChfZ2xvYmFsQ2FsbGJhY2tzW2NvbWJvXSB8fCBfZ2xvYmFsQ2FsbGJhY2tzW3NlcXVlbmNlXSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gX29yaWdpbmFsU3RvcENhbGxiYWNrLmNhbGwoc2VsZiwgZSwgZWxlbWVudCwgY29tYm8pOwogICAgfTsKCiAgICBNb3VzZXRyYXAucHJvdG90eXBlLmJpbmRHbG9iYWwgPSBmdW5jdGlvbihrZXlzLCBjYWxsYmFjaywgYWN0aW9uKSB7CiAgICAgICAgdmFyIHNlbGYgPSB0aGlzOwogICAgICAgIHNlbGYuYmluZChrZXlzLCBjYWxsYmFjaywgYWN0aW9uKTsKCiAgICAgICAgaWYgKGtleXMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIF9nbG9iYWxDYWxsYmFja3Nba2V5c1tpXV0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIF9nbG9iYWxDYWxsYmFja3Nba2V5c10gPSB0cnVlOwogICAgfTsKCiAgICBNb3VzZXRyYXAuaW5pdCgpOwp9KSAoTW91c2V0cmFwKTsK"}]}]}
{"created_by":"Tampermonkey","version":"1","scripts":[{"name":"Quick Triage","options":{"check_for_updates":true,"comment":null,"compatopts_for_requires":true,"compat_wrappedjsobject":false,"compat_metadata":false,"compat_foreach":false,"compat_arrayleft":false,"compat_uW_gmonkey":false,"compat_forvarin":false,"noframes":null,"awareOfChrome":false,"run_at":null,"override":{"use_includes":[],"orig_includes":[],"merge_includes":true,"use_matches":[],"orig_matches":["http://softbaked.co/*"],"merge_matches":true,"use_excludes":[],"orig_excludes":[],"merge_excludes":true,"use_connects":[],"merge_connects":true,"use_blockers":[],"orig_run_at":"document-idle","orig_noframes":null,"orig_connects":[]}},"storage":{"ts":1513744916648,"data":{}},"enabled":true,"position":1,"uuid":"8ff81db7-8771-4213-bb0e-98da3ab3e721","source":"Ly8gPT1Vc2VyU2NyaXB0PT0KLy8gQG5hbWUgICAgICAgICBRdWljayBUcmlhZ2UKLy8gQG5hbWVzcGFjZSAgICBodHRwOi8vc29mdGJha2VkLmNvLwovLyBAdmVyc2lvbiAgICAgIDAuMQovLyBAZGVzY3JpcHRpb24gIFF1aWNrbHkgdHJpYWdlIE1hbmlwaGVzdCB0YXNrcwovLyBAYXV0aG9yICAgICAgIFlvdQovLyBAbWF0Y2ggICAgICAgIGh0dHA6Ly9zb2Z0YmFrZWQuY28vKgovLyBAcmVxdWlyZSAgICAgIGh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL21vdXNldHJhcC8xLjYuMS9tb3VzZXRyYXAuanMKLy8gQHJlcXVpcmUgICAgICBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vY2NhbXBiZWxsL21vdXNldHJhcC9tYXN0ZXIvcGx1Z2lucy9nbG9iYWwtYmluZC9tb3VzZXRyYXAtZ2xvYmFsLWJpbmQuanMKLy8gPT0vVXNlclNjcmlwdD09CgooZnVuY3Rpb24oKSB7CiAgICAndXNlIHN0cmljdCc7CiAgICB2YXIgb3B0aW9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcigib3B0aW9uW3ZhbHVlPScrJ10iKTsKICAgIGlmICghb3B0aW9uKSByZXR1cm47IC8vIG5vdCBtYW5pcGhlc3QgdGFzawoKICAgIHZhciBhY3Rpb24gPSBvcHRpb24ucGFyZW50RWxlbWVudCwKICAgICAgICBmb3JtICAgPSBhY3Rpb24ucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQsCiAgICAgICAgY2hhbmdlID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0hUTUxFdmVudHMnKTsKICAgIGNoYW5nZS5pbml0RXZlbnQoJ2NoYW5nZScsIGZhbHNlLCB0cnVlKTsKCiAgICB2YXIgZm9jdXNMYXN0ID0gZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIGlucHV0cyAgICA9IGZvcm0uZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnYXBocm9udC1mb3JtLWlucHV0JyksCiAgICAgICAgICAgIGxhc3RJbnB1dCA9IGlucHV0c1tpbnB1dHMubGVuZ3RoIC0gM107CiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHRleHRJbnB1dCA9IGxhc3RJbnB1dC5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPXRleHRdJyk7CiAgICAgICAgICAgIGlmICh0ZXh0SW5wdXQpIHsgdGV4dElucHV0LmZvY3VzKCk7IH0KICAgICAgICAgICAgZWxzZSB7IGxhc3RJbnB1dC5maXJzdENoaWxkLmZvY3VzKCk7IH0KICAgICAgICB9LCAwKTsKICAgIH07CgogICAgdmFyIGJpbmRRdWlja0FjdGlvbiA9IGZ1bmN0aW9uKHNob3J0Y3V0LCBhKSB7CiAgICAgICAgTW91c2V0cmFwLmJpbmRHbG9iYWwoc2hvcnRjdXQsIGZ1bmN0aW9uKGUpIHsKICAgICAgICAgICAgYWN0aW9uLnZhbHVlID0gYTsKICAgICAgICAgICAgYWN0aW9uLmRpc3BhdGNoRXZlbnQoY2hhbmdlKTsKICAgICAgICAgICAgZm9jdXNMYXN0KCk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9KTsKICAgIH07CgogICAgYmluZFF1aWNrQWN0aW9uKCdjdHJsK28nLCAnb3duZXInKTsKICAgIGJpbmRRdWlja0FjdGlvbignY3RybCtzJywgJ3N0YXR1cycpOwogICAgYmluZFF1aWNrQWN0aW9uKCdjdHJsK3AnLCAncHJpb3JpdHknKTsKICAgIGJpbmRRdWlja0FjdGlvbignY3RybCt4JywgJ3BvaW50cycpOwogICAgYmluZFF1aWNrQWN0aW9uKCdjdHJsK3QnLCAncHJvamVjdFBISURzJyk7CiAgICBiaW5kUXVpY2tBY3Rpb24oJ2N0cmwrbScsICdjb2x1bW4nKTsKfSkoKTs=","requires":[{"meta":{"name":"mousetrap.js","url":"https://cdnjs.cloudflare.com/ajax/libs/mousetrap/1.6.1/mousetrap.js","ts":1539246620294,"mimetype":"text/javascript"},"source":"LypnbG9iYWwgZGVmaW5lOmZhbHNlICovCi8qKgogKiBDb3B5cmlnaHQgMjAxMi0yMDE3IENyYWlnIENhbXBiZWxsCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICoKICogTW91c2V0cmFwIGlzIGEgc2ltcGxlIGtleWJvYXJkIHNob3J0Y3V0IGxpYnJhcnkgZm9yIEphdmFzY3JpcHQgd2l0aAogKiBubyBleHRlcm5hbCBkZXBlbmRlbmNpZXMKICoKICogQHZlcnNpb24gMS42LjEKICogQHVybCBjcmFpZy5pcy9raWxsaW5nL21pY2UKICovCihmdW5jdGlvbih3aW5kb3csIGRvY3VtZW50LCB1bmRlZmluZWQpIHsKCiAgICAvLyBDaGVjayBpZiBtb3VzZXRyYXAgaXMgdXNlZCBpbnNpZGUgYnJvd3NlciwgaWYgbm90LCByZXR1cm4KICAgIGlmICghd2luZG93KSB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qKgogICAgICogbWFwcGluZyBvZiBzcGVjaWFsIGtleWNvZGVzIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcga2V5cwogICAgICoKICAgICAqIGV2ZXJ5dGhpbmcgaW4gdGhpcyBkaWN0aW9uYXJ5IGNhbm5vdCB1c2Uga2V5cHJlc3MgZXZlbnRzCiAgICAgKiBzbyBpdCBoYXMgdG8gYmUgaGVyZSB0byBtYXAgdG8gdGhlIGNvcnJlY3Qga2V5Y29kZXMgZm9yCiAgICAgKiBrZXl1cC9rZXlkb3duIGV2ZW50cwogICAgICoKICAgICAqIEB0eXBlIHtPYmplY3R9CiAgICAgKi8KICAgIHZhciBfTUFQID0gewogICAgICAgIDg6ICdiYWNrc3BhY2UnLAogICAgICAgIDk6ICd0YWInLAogICAgICAgIDEzOiAnZW50ZXInLAogICAgICAgIDE2OiAnc2hpZnQnLAogICAgICAgIDE3OiAnY3RybCcsCiAgICAgICAgMTg6ICdhbHQnLAogICAgICAgIDIwOiAnY2Fwc2xvY2snLAogICAgICAgIDI3OiAnZXNjJywKICAgICAgICAzMjogJ3NwYWNlJywKICAgICAgICAzMzogJ3BhZ2V1cCcsCiAgICAgICAgMzQ6ICdwYWdlZG93bicsCiAgICAgICAgMzU6ICdlbmQnLAogICAgICAgIDM2OiAnaG9tZScsCiAgICAgICAgMzc6ICdsZWZ0JywKICAgICAgICAzODogJ3VwJywKICAgICAgICAzOTogJ3JpZ2h0JywKICAgICAgICA0MDogJ2Rvd24nLAogICAgICAgIDQ1OiAnaW5zJywKICAgICAgICA0NjogJ2RlbCcsCiAgICAgICAgOTE6ICdtZXRhJywKICAgICAgICA5MzogJ21ldGEnLAogICAgICAgIDIyNDogJ21ldGEnCiAgICB9OwoKICAgIC8qKgogICAgICogbWFwcGluZyBmb3Igc3BlY2lhbCBjaGFyYWN0ZXJzIHNvIHRoZXkgY2FuIHN1cHBvcnQKICAgICAqCiAgICAgKiB0aGlzIGRpY3Rpb25hcnkgaXMgb25seSB1c2VkIGluY2FzZSB5b3Ugd2FudCB0byBiaW5kIGEKICAgICAqIGtleXVwIG9yIGtleWRvd24gZXZlbnQgdG8gb25lIG9mIHRoZXNlIGtleXMKICAgICAqCiAgICAgKiBAdHlwZSB7T2JqZWN0fQogICAgICovCiAgICB2YXIgX0tFWUNPREVfTUFQID0gewogICAgICAgIDEwNjogJyonLAogICAgICAgIDEwNzogJysnLAogICAgICAgIDEwOTogJy0nLAogICAgICAgIDExMDogJy4nLAogICAgICAgIDExMSA6ICcvJywKICAgICAgICAxODY6ICc7JywKICAgICAgICAxODc6ICc9JywKICAgICAgICAxODg6ICcsJywKICAgICAgICAxODk6ICctJywKICAgICAgICAxOTA6ICcuJywKICAgICAgICAxOTE6ICcvJywKICAgICAgICAxOTI6ICdgJywKICAgICAgICAyMTk6ICdbJywKICAgICAgICAyMjA6ICdcXCcsCiAgICAgICAgMjIxOiAnXScsCiAgICAgICAgMjIyOiAnXCcnCiAgICB9OwoKICAgIC8qKgogICAgICogdGhpcyBpcyBhIG1hcHBpbmcgb2Yga2V5cyB0aGF0IHJlcXVpcmUgc2hpZnQgb24gYSBVUyBrZXlwYWQKICAgICAqIGJhY2sgdG8gdGhlIG5vbiBzaGlmdCBlcXVpdmVsZW50cwogICAgICoKICAgICAqIHRoaXMgaXMgc28geW91IGNhbiB1c2Uga2V5dXAgZXZlbnRzIHdpdGggdGhlc2Uga2V5cwogICAgICoKICAgICAqIG5vdGUgdGhhdCB0aGlzIHdpbGwgb25seSB3b3JrIHJlbGlhYmx5IG9uIFVTIGtleWJvYXJkcwogICAgICoKICAgICAqIEB0eXBlIHtPYmplY3R9CiAgICAgKi8KICAgIHZhciBfU0hJRlRfTUFQID0gewogICAgICAgICd+JzogJ2AnLAogICAgICAgICchJzogJzEnLAogICAgICAgICdAJzogJzInLAogICAgICAgICcjJzogJzMnLAogICAgICAgICckJzogJzQnLAogICAgICAgICclJzogJzUnLAogICAgICAgICdeJzogJzYnLAogICAgICAgICcmJzogJzcnLAogICAgICAgICcqJzogJzgnLAogICAgICAgICcoJzogJzknLAogICAgICAgICcpJzogJzAnLAogICAgICAgICdfJzogJy0nLAogICAgICAgICcrJzogJz0nLAogICAgICAgICc6JzogJzsnLAogICAgICAgICdcIic6ICdcJycsCiAgICAgICAgJzwnOiAnLCcsCiAgICAgICAgJz4nOiAnLicsCiAgICAgICAgJz8nOiAnLycsCiAgICAgICAgJ3wnOiAnXFwnCiAgICB9OwoKICAgIC8qKgogICAgICogdGhpcyBpcyBhIGxpc3Qgb2Ygc3BlY2lhbCBzdHJpbmdzIHlvdSBjYW4gdXNlIHRvIG1hcAogICAgICogdG8gbW9kaWZpZXIga2V5cyB3aGVuIHlvdSBzcGVjaWZ5IHlvdXIga2V5Ym9hcmQgc2hvcnRjdXRzCiAgICAgKgogICAgICogQHR5cGUge09iamVjdH0KICAgICAqLwogICAgdmFyIF9TUEVDSUFMX0FMSUFTRVMgPSB7CiAgICAgICAgJ29wdGlvbic6ICdhbHQnLAogICAgICAgICdjb21tYW5kJzogJ21ldGEnLAogICAgICAgICdyZXR1cm4nOiAnZW50ZXInLAogICAgICAgICdlc2NhcGUnOiAnZXNjJywKICAgICAgICAncGx1cyc6ICcrJywKICAgICAgICAnbW9kJzogL01hY3xpUG9kfGlQaG9uZXxpUGFkLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSkgPyAnbWV0YScgOiAnY3RybCcKICAgIH07CgogICAgLyoqCiAgICAgKiB2YXJpYWJsZSB0byBzdG9yZSB0aGUgZmxpcHBlZCB2ZXJzaW9uIG9mIF9NQVAgZnJvbSBhYm92ZQogICAgICogbmVlZGVkIHRvIGNoZWNrIGlmIHdlIHNob3VsZCB1c2Uga2V5cHJlc3Mgb3Igbm90IHdoZW4gbm8gYWN0aW9uCiAgICAgKiBpcyBzcGVjaWZpZWQKICAgICAqCiAgICAgKiBAdHlwZSB7T2JqZWN0fHVuZGVmaW5lZH0KICAgICAqLwogICAgdmFyIF9SRVZFUlNFX01BUDsKCiAgICAvKioKICAgICAqIGxvb3AgdGhyb3VnaCB0aGUgZiBrZXlzLCBmMSB0byBmMTkgYW5kIGFkZCB0aGVtIHRvIHRoZSBtYXAKICAgICAqIHByb2dyYW1hdGljYWxseQogICAgICovCiAgICBmb3IgKHZhciBpID0gMTsgaSA8IDIwOyArK2kpIHsKICAgICAgICBfTUFQWzExMSArIGldID0gJ2YnICsgaTsKICAgIH0KCiAgICAvKioKICAgICAqIGxvb3AgdGhyb3VnaCB0byBtYXAgbnVtYmVycyBvbiB0aGUgbnVtZXJpYyBrZXlwYWQKICAgICAqLwogICAgZm9yIChpID0gMDsgaSA8PSA5OyArK2kpIHsKCiAgICAgICAgLy8gVGhpcyBuZWVkcyB0byB1c2UgYSBzdHJpbmcgY2F1c2Ugb3RoZXJ3aXNlIHNpbmNlIDAgaXMgZmFsc2V5CiAgICAgICAgLy8gbW91c2V0cmFwIHdpbGwgbmV2ZXIgZmlyZSBmb3IgbnVtcGFkIDAgcHJlc3NlZCBhcyBwYXJ0IG9mIGEga2V5ZG93bgogICAgICAgIC8vIGV2ZW50LgogICAgICAgIC8vCiAgICAgICAgLy8gQHNlZSBodHRwczovL2dpdGh1Yi5jb20vY2NhbXBiZWxsL21vdXNldHJhcC9wdWxsLzI1OAogICAgICAgIF9NQVBbaSArIDk2XSA9IGkudG9TdHJpbmcoKTsKICAgIH0KCiAgICAvKioKICAgICAqIGNyb3NzIGJyb3dzZXIgYWRkIGV2ZW50IG1ldGhvZAogICAgICoKICAgICAqIEBwYXJhbSB7RWxlbWVudHxIVE1MRG9jdW1lbnR9IG9iamVjdAogICAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUKICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrCiAgICAgKiBAcmV0dXJucyB2b2lkCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hZGRFdmVudChvYmplY3QsIHR5cGUsIGNhbGxiYWNrKSB7CiAgICAgICAgaWYgKG9iamVjdC5hZGRFdmVudExpc3RlbmVyKSB7CiAgICAgICAgICAgIG9iamVjdC5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrLCBmYWxzZSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIG9iamVjdC5hdHRhY2hFdmVudCgnb24nICsgdHlwZSwgY2FsbGJhY2spOwogICAgfQoKICAgIC8qKgogICAgICogdGFrZXMgdGhlIGV2ZW50IGFuZCByZXR1cm5zIHRoZSBrZXkgY2hhcmFjdGVyCiAgICAgKgogICAgICogQHBhcmFtIHtFdmVudH0gZQogICAgICogQHJldHVybiB7c3RyaW5nfQogICAgICovCiAgICBmdW5jdGlvbiBfY2hhcmFjdGVyRnJvbUV2ZW50KGUpIHsKCiAgICAgICAgLy8gZm9yIGtleXByZXNzIGV2ZW50cyB3ZSBzaG91bGQgcmV0dXJuIHRoZSBjaGFyYWN0ZXIgYXMgaXMKICAgICAgICBpZiAoZS50eXBlID09ICdrZXlwcmVzcycpIHsKICAgICAgICAgICAgdmFyIGNoYXJhY3RlciA9IFN0cmluZy5mcm9tQ2hhckNvZGUoZS53aGljaCk7CgogICAgICAgICAgICAvLyBpZiB0aGUgc2hpZnQga2V5IGlzIG5vdCBwcmVzc2VkIHRoZW4gaXQgaXMgc2FmZSB0byBhc3N1bWUKICAgICAgICAgICAgLy8gdGhhdCB3ZSB3YW50IHRoZSBjaGFyYWN0ZXIgdG8gYmUgbG93ZXJjYXNlLiAgdGhpcyBtZWFucyBpZgogICAgICAgICAgICAvLyB5b3UgYWNjaWRlbnRhbGx5IGhhdmUgY2FwcyBsb2NrIG9uIHRoZW4geW91ciBrZXkgYmluZGluZ3MKICAgICAgICAgICAgLy8gd2lsbCBjb250aW51ZSB0byB3b3JrCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIHRoZSBvbmx5IHNpZGUgZWZmZWN0IHRoYXQgbWlnaHQgbm90IGJlIGRlc2lyZWQgaXMgaWYgeW91CiAgICAgICAgICAgIC8vIGJpbmQgc29tZXRoaW5nIGxpa2UgJ0EnIGNhdXNlIHlvdSB3YW50IHRvIHRyaWdnZXIgYW4KICAgICAgICAgICAgLy8gZXZlbnQgd2hlbiBjYXBpdGFsIEEgaXMgcHJlc3NlZCBjYXBzIGxvY2sgd2lsbCBubyBsb25nZXIKICAgICAgICAgICAgLy8gdHJpZ2dlciB0aGUgZXZlbnQuICBzaGlmdCthIHdpbGwgdGhvdWdoLgogICAgICAgICAgICBpZiAoIWUuc2hpZnRLZXkpIHsKICAgICAgICAgICAgICAgIGNoYXJhY3RlciA9IGNoYXJhY3Rlci50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gY2hhcmFjdGVyOwogICAgICAgIH0KCiAgICAgICAgLy8gZm9yIG5vbiBrZXlwcmVzcyBldmVudHMgdGhlIHNwZWNpYWwgbWFwcyBhcmUgbmVlZGVkCiAgICAgICAgaWYgKF9NQVBbZS53aGljaF0pIHsKICAgICAgICAgICAgcmV0dXJuIF9NQVBbZS53aGljaF07CiAgICAgICAgfQoKICAgICAgICBpZiAoX0tFWUNPREVfTUFQW2Uud2hpY2hdKSB7CiAgICAgICAgICAgIHJldHVybiBfS0VZQ09ERV9NQVBbZS53aGljaF07CiAgICAgICAgfQoKICAgICAgICAvLyBpZiBpdCBpcyBub3QgaW4gdGhlIHNwZWNpYWwgbWFwCgogICAgICAgIC8vIHdpdGgga2V5ZG93biBhbmQga2V5dXAgZXZlbnRzIHRoZSBjaGFyYWN0ZXIgc2VlbXMgdG8gYWx3YXlzCiAgICAgICAgLy8gY29tZSBpbiBhcyBhbiB1cHBlcmNhc2UgY2hhcmFjdGVyIHdoZXRoZXIgeW91IGFyZSBwcmVzc2luZyBzaGlmdAogICAgICAgIC8vIG9yIG5vdC4gIHdlIHNob3VsZCBtYWtlIHN1cmUgaXQgaXMgYWx3YXlzIGxvd2VyY2FzZSBmb3IgY29tcGFyaXNvbnMKICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShlLndoaWNoKS50b0xvd2VyQ2FzZSgpOwogICAgfQoKICAgIC8qKgogICAgICogY2hlY2tzIGlmIHR3byBhcnJheXMgYXJlIGVxdWFsCiAgICAgKgogICAgICogQHBhcmFtIHtBcnJheX0gbW9kaWZpZXJzMQogICAgICogQHBhcmFtIHtBcnJheX0gbW9kaWZpZXJzMgogICAgICogQHJldHVybnMge2Jvb2xlYW59CiAgICAgKi8KICAgIGZ1bmN0aW9uIF9tb2RpZmllcnNNYXRjaChtb2RpZmllcnMxLCBtb2RpZmllcnMyKSB7CiAgICAgICAgcmV0dXJuIG1vZGlmaWVyczEuc29ydCgpLmpvaW4oJywnKSA9PT0gbW9kaWZpZXJzMi5zb3J0KCkuam9pbignLCcpOwogICAgfQoKICAgIC8qKgogICAgICogdGFrZXMgYSBrZXkgZXZlbnQgYW5kIGZpZ3VyZXMgb3V0IHdoYXQgdGhlIG1vZGlmaWVycyBhcmUKICAgICAqCiAgICAgKiBAcGFyYW0ge0V2ZW50fSBlCiAgICAgKiBAcmV0dXJucyB7QXJyYXl9CiAgICAgKi8KICAgIGZ1bmN0aW9uIF9ldmVudE1vZGlmaWVycyhlKSB7CiAgICAgICAgdmFyIG1vZGlmaWVycyA9IFtdOwoKICAgICAgICBpZiAoZS5zaGlmdEtleSkgewogICAgICAgICAgICBtb2RpZmllcnMucHVzaCgnc2hpZnQnKTsKICAgICAgICB9CgogICAgICAgIGlmIChlLmFsdEtleSkgewogICAgICAgICAgICBtb2RpZmllcnMucHVzaCgnYWx0Jyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZS5jdHJsS2V5KSB7CiAgICAgICAgICAgIG1vZGlmaWVycy5wdXNoKCdjdHJsJyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZS5tZXRhS2V5KSB7CiAgICAgICAgICAgIG1vZGlmaWVycy5wdXNoKCdtZXRhJyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbW9kaWZpZXJzOwogICAgfQoKICAgIC8qKgogICAgICogcHJldmVudHMgZGVmYXVsdCBmb3IgdGhpcyBldmVudAogICAgICoKICAgICAqIEBwYXJhbSB7RXZlbnR9IGUKICAgICAqIEByZXR1cm5zIHZvaWQKICAgICAqLwogICAgZnVuY3Rpb24gX3ByZXZlbnREZWZhdWx0KGUpIHsKICAgICAgICBpZiAoZS5wcmV2ZW50RGVmYXVsdCkgewogICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGUucmV0dXJuVmFsdWUgPSBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIHN0b3BzIHByb3BvZ2F0aW9uIGZvciB0aGlzIGV2ZW50CiAgICAgKgogICAgICogQHBhcmFtIHtFdmVudH0gZQogICAgICogQHJldHVybnMgdm9pZAogICAgICovCiAgICBmdW5jdGlvbiBfc3RvcFByb3BhZ2F0aW9uKGUpIHsKICAgICAgICBpZiAoZS5zdG9wUHJvcGFnYXRpb24pIHsKICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgZS5jYW5jZWxCdWJibGUgPSB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogZGV0ZXJtaW5lcyBpZiB0aGUga2V5Y29kZSBzcGVjaWZpZWQgaXMgYSBtb2RpZmllciBrZXkgb3Igbm90CiAgICAgKgogICAgICogQHBhcmFtIHtzdHJpbmd9IGtleQogICAgICogQHJldHVybnMge2Jvb2xlYW59CiAgICAgKi8KICAgIGZ1bmN0aW9uIF9pc01vZGlmaWVyKGtleSkgewogICAgICAgIHJldHVybiBrZXkgPT0gJ3NoaWZ0JyB8fCBrZXkgPT0gJ2N0cmwnIHx8IGtleSA9PSAnYWx0JyB8fCBrZXkgPT0gJ21ldGEnOwogICAgfQoKICAgIC8qKgogICAgICogcmV2ZXJzZXMgdGhlIG1hcCBsb29rdXAgc28gdGhhdCB3ZSBjYW4gbG9vayBmb3Igc3BlY2lmaWMga2V5cwogICAgICogdG8gc2VlIHdoYXQgY2FuIGFuZCBjYW4ndCB1c2Uga2V5cHJlc3MKICAgICAqCiAgICAgKiBAcmV0dXJuIHtPYmplY3R9CiAgICAgKi8KICAgIGZ1bmN0aW9uIF9nZXRSZXZlcnNlTWFwKCkgewogICAgICAgIGlmICghX1JFVkVSU0VfTUFQKSB7CiAgICAgICAgICAgIF9SRVZFUlNFX01BUCA9IHt9OwogICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gX01BUCkgewoKICAgICAgICAgICAgICAgIC8vIHB1bGwgb3V0IHRoZSBudW1lcmljIGtleXBhZCBmcm9tIGhlcmUgY2F1c2Uga2V5cHJlc3Mgc2hvdWxkCiAgICAgICAgICAgICAgICAvLyBiZSBhYmxlIHRvIGRldGVjdCB0aGUga2V5cyBmcm9tIHRoZSBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgIGlmIChrZXkgPiA5NSAmJiBrZXkgPCAxMTIpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoX01BUC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7CiAgICAgICAgICAgICAgICAgICAgX1JFVkVSU0VfTUFQW19NQVBba2V5XV0gPSBrZXk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIF9SRVZFUlNFX01BUDsKICAgIH0KCiAgICAvKioKICAgICAqIHBpY2tzIHRoZSBiZXN0IGFjdGlvbiBiYXNlZCBvbiB0aGUga2V5IGNvbWJpbmF0aW9uCiAgICAgKgogICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIGNoYXJhY3RlciBmb3Iga2V5CiAgICAgKiBAcGFyYW0ge0FycmF5fSBtb2RpZmllcnMKICAgICAqIEBwYXJhbSB7c3RyaW5nPX0gYWN0aW9uIHBhc3NlZCBpbgogICAgICovCiAgICBmdW5jdGlvbiBfcGlja0Jlc3RBY3Rpb24oa2V5LCBtb2RpZmllcnMsIGFjdGlvbikgewoKICAgICAgICAvLyBpZiBubyBhY3Rpb24gd2FzIHBpY2tlZCBpbiB3ZSBzaG91bGQgdHJ5IHRvIHBpY2sgdGhlIG9uZQogICAgICAgIC8vIHRoYXQgd2UgdGhpbmsgd291bGQgd29yayBiZXN0IGZvciB0aGlzIGtleQogICAgICAgIGlmICghYWN0aW9uKSB7CiAgICAgICAgICAgIGFjdGlvbiA9IF9nZXRSZXZlcnNlTWFwKClba2V5XSA/ICdrZXlkb3duJyA6ICdrZXlwcmVzcyc7CiAgICAgICAgfQoKICAgICAgICAvLyBtb2RpZmllciBrZXlzIGRvbid0IHdvcmsgYXMgZXhwZWN0ZWQgd2l0aCBrZXlwcmVzcywKICAgICAgICAvLyBzd2l0Y2ggdG8ga2V5ZG93bgogICAgICAgIGlmIChhY3Rpb24gPT0gJ2tleXByZXNzJyAmJiBtb2RpZmllcnMubGVuZ3RoKSB7CiAgICAgICAgICAgIGFjdGlvbiA9ICdrZXlkb3duJzsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhY3Rpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBmcm9tIGEgc3RyaW5nIGtleSBjb21iaW5hdGlvbiB0byBhbiBhcnJheQogICAgICoKICAgICAqIEBwYXJhbSAge3N0cmluZ30gY29tYmluYXRpb24gbGlrZSAiY29tbWFuZCtzaGlmdCtsIgogICAgICogQHJldHVybiB7QXJyYXl9CiAgICAgKi8KICAgIGZ1bmN0aW9uIF9rZXlzRnJvbVN0cmluZyhjb21iaW5hdGlvbikgewogICAgICAgIGlmIChjb21iaW5hdGlvbiA9PT0gJysnKSB7CiAgICAgICAgICAgIHJldHVybiBbJysnXTsKICAgICAgICB9CgogICAgICAgIGNvbWJpbmF0aW9uID0gY29tYmluYXRpb24ucmVwbGFjZSgvXCt7Mn0vZywgJytwbHVzJyk7CiAgICAgICAgcmV0dXJuIGNvbWJpbmF0aW9uLnNwbGl0KCcrJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXRzIGluZm8gZm9yIGEgc3BlY2lmaWMga2V5IGNvbWJpbmF0aW9uCiAgICAgKgogICAgICogQHBhcmFtICB7c3RyaW5nfSBjb21iaW5hdGlvbiBrZXkgY29tYmluYXRpb24gKCJjb21tYW5kK3MiIG9yICJhIiBvciAiKiIpCiAgICAgKiBAcGFyYW0gIHtzdHJpbmc9fSBhY3Rpb24KICAgICAqIEByZXR1cm5zIHtPYmplY3R9CiAgICAgKi8KICAgIGZ1bmN0aW9uIF9nZXRLZXlJbmZvKGNvbWJpbmF0aW9uLCBhY3Rpb24pIHsKICAgICAgICB2YXIga2V5czsKICAgICAgICB2YXIga2V5OwogICAgICAgIHZhciBpOwogICAgICAgIHZhciBtb2RpZmllcnMgPSBbXTsKCiAgICAgICAgLy8gdGFrZSB0aGUga2V5cyBmcm9tIHRoaXMgcGF0dGVybiBhbmQgZmlndXJlIG91dCB3aGF0IHRoZSBhY3R1YWwKICAgICAgICAvLyBwYXR0ZXJuIGlzIGFsbCBhYm91dAogICAgICAgIGtleXMgPSBfa2V5c0Zyb21TdHJpbmcoY29tYmluYXRpb24pOwoKICAgICAgICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBrZXkgPSBrZXlzW2ldOwoKICAgICAgICAgICAgLy8gbm9ybWFsaXplIGtleSBuYW1lcwogICAgICAgICAgICBpZiAoX1NQRUNJQUxfQUxJQVNFU1trZXldKSB7CiAgICAgICAgICAgICAgICBrZXkgPSBfU1BFQ0lBTF9BTElBU0VTW2tleV07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgbm90IGEga2V5cHJlc3MgZXZlbnQgdGhlbiB3ZSBzaG91bGQKICAgICAgICAgICAgLy8gYmUgc21hcnQgYWJvdXQgdXNpbmcgc2hpZnQga2V5cwogICAgICAgICAgICAvLyB0aGlzIHdpbGwgb25seSB3b3JrIGZvciBVUyBrZXlib2FyZHMgaG93ZXZlcgogICAgICAgICAgICBpZiAoYWN0aW9uICYmIGFjdGlvbiAhPSAna2V5cHJlc3MnICYmIF9TSElGVF9NQVBba2V5XSkgewogICAgICAgICAgICAgICAga2V5ID0gX1NISUZUX01BUFtrZXldOwogICAgICAgICAgICAgICAgbW9kaWZpZXJzLnB1c2goJ3NoaWZ0Jyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGlmIHRoaXMga2V5IGlzIGEgbW9kaWZpZXIgdGhlbiBhZGQgaXQgdG8gdGhlIGxpc3Qgb2YgbW9kaWZpZXJzCiAgICAgICAgICAgIGlmIChfaXNNb2RpZmllcihrZXkpKSB7CiAgICAgICAgICAgICAgICBtb2RpZmllcnMucHVzaChrZXkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBkZXBlbmRpbmcgb24gd2hhdCB0aGUga2V5IGNvbWJpbmF0aW9uIGlzCiAgICAgICAgLy8gd2Ugd2lsbCB0cnkgdG8gcGljayB0aGUgYmVzdCBldmVudCBmb3IgaXQKICAgICAgICBhY3Rpb24gPSBfcGlja0Jlc3RBY3Rpb24oa2V5LCBtb2RpZmllcnMsIGFjdGlvbik7CgogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIGtleToga2V5LAogICAgICAgICAgICBtb2RpZmllcnM6IG1vZGlmaWVycywKICAgICAgICAgICAgYWN0aW9uOiBhY3Rpb24KICAgICAgICB9OwogICAgfQoKICAgIGZ1bmN0aW9uIF9iZWxvbmdzVG8oZWxlbWVudCwgYW5jZXN0b3IpIHsKICAgICAgICBpZiAoZWxlbWVudCA9PT0gbnVsbCB8fCBlbGVtZW50ID09PSBkb2N1bWVudCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoZWxlbWVudCA9PT0gYW5jZXN0b3IpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gX2JlbG9uZ3NUbyhlbGVtZW50LnBhcmVudE5vZGUsIGFuY2VzdG9yKTsKICAgIH0KCiAgICBmdW5jdGlvbiBNb3VzZXRyYXAodGFyZ2V0RWxlbWVudCkgewogICAgICAgIHZhciBzZWxmID0gdGhpczsKCiAgICAgICAgdGFyZ2V0RWxlbWVudCA9IHRhcmdldEVsZW1lbnQgfHwgZG9jdW1lbnQ7CgogICAgICAgIGlmICghKHNlbGYgaW5zdGFuY2VvZiBNb3VzZXRyYXApKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgTW91c2V0cmFwKHRhcmdldEVsZW1lbnQpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogZWxlbWVudCB0byBhdHRhY2gga2V5IGV2ZW50cyB0bwogICAgICAgICAqCiAgICAgICAgICogQHR5cGUge0VsZW1lbnR9CiAgICAgICAgICovCiAgICAgICAgc2VsZi50YXJnZXQgPSB0YXJnZXRFbGVtZW50OwoKICAgICAgICAvKioKICAgICAgICAgKiBhIGxpc3Qgb2YgYWxsIHRoZSBjYWxsYmFja3Mgc2V0dXAgdmlhIE1vdXNldHJhcC5iaW5kKCkKICAgICAgICAgKgogICAgICAgICAqIEB0eXBlIHtPYmplY3R9CiAgICAgICAgICovCiAgICAgICAgc2VsZi5fY2FsbGJhY2tzID0ge307CgogICAgICAgIC8qKgogICAgICAgICAqIGRpcmVjdCBtYXAgb2Ygc3RyaW5nIGNvbWJpbmF0aW9ucyB0byBjYWxsYmFja3MgdXNlZCBmb3IgdHJpZ2dlcigpCiAgICAgICAgICoKICAgICAgICAgKiBAdHlwZSB7T2JqZWN0fQogICAgICAgICAqLwogICAgICAgIHNlbGYuX2RpcmVjdE1hcCA9IHt9OwoKICAgICAgICAvKioKICAgICAgICAgKiBrZWVwcyB0cmFjayBvZiB3aGF0IGxldmVsIGVhY2ggc2VxdWVuY2UgaXMgYXQgc2luY2UgbXVsdGlwbGUKICAgICAgICAgKiBzZXF1ZW5jZXMgY2FuIHN0YXJ0IG91dCB3aXRoIHRoZSBzYW1lIHNlcXVlbmNlCiAgICAgICAgICoKICAgICAgICAgKiBAdHlwZSB7T2JqZWN0fQogICAgICAgICAqLwogICAgICAgIHZhciBfc2VxdWVuY2VMZXZlbHMgPSB7fTsKCiAgICAgICAgLyoqCiAgICAgICAgICogdmFyaWFibGUgdG8gc3RvcmUgdGhlIHNldFRpbWVvdXQgY2FsbAogICAgICAgICAqCiAgICAgICAgICogQHR5cGUge251bGx8bnVtYmVyfQogICAgICAgICAqLwogICAgICAgIHZhciBfcmVzZXRUaW1lcjsKCiAgICAgICAgLyoqCiAgICAgICAgICogdGVtcG9yYXJ5IHN0YXRlIHdoZXJlIHdlIHdpbGwgaWdub3JlIHRoZSBuZXh0IGtleXVwCiAgICAgICAgICoKICAgICAgICAgKiBAdHlwZSB7Ym9vbGVhbnxzdHJpbmd9CiAgICAgICAgICovCiAgICAgICAgdmFyIF9pZ25vcmVOZXh0S2V5dXAgPSBmYWxzZTsKCiAgICAgICAgLyoqCiAgICAgICAgICogdGVtcG9yYXJ5IHN0YXRlIHdoZXJlIHdlIHdpbGwgaWdub3JlIHRoZSBuZXh0IGtleXByZXNzCiAgICAgICAgICoKICAgICAgICAgKiBAdHlwZSB7Ym9vbGVhbn0KICAgICAgICAgKi8KICAgICAgICB2YXIgX2lnbm9yZU5leHRLZXlwcmVzcyA9IGZhbHNlOwoKICAgICAgICAvKioKICAgICAgICAgKiBhcmUgd2UgY3VycmVudGx5IGluc2lkZSBvZiBhIHNlcXVlbmNlPwogICAgICAgICAqIHR5cGUgb2YgYWN0aW9uICgia2V5dXAiIG9yICJrZXlkb3duIiBvciAia2V5cHJlc3MiKSBvciBmYWxzZQogICAgICAgICAqCiAgICAgICAgICogQHR5cGUge2Jvb2xlYW58c3RyaW5nfQogICAgICAgICAqLwogICAgICAgIHZhciBfbmV4dEV4cGVjdGVkQWN0aW9uID0gZmFsc2U7CgogICAgICAgIC8qKgogICAgICAgICAqIHJlc2V0cyBhbGwgc2VxdWVuY2UgY291bnRlcnMgZXhjZXB0IGZvciB0aGUgb25lcyBwYXNzZWQgaW4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBkb05vdFJlc2V0CiAgICAgICAgICogQHJldHVybnMgdm9pZAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIF9yZXNldFNlcXVlbmNlcyhkb05vdFJlc2V0KSB7CiAgICAgICAgICAgIGRvTm90UmVzZXQgPSBkb05vdFJlc2V0IHx8IHt9OwoKICAgICAgICAgICAgdmFyIGFjdGl2ZVNlcXVlbmNlcyA9IGZhbHNlLAogICAgICAgICAgICAgICAga2V5OwoKICAgICAgICAgICAgZm9yIChrZXkgaW4gX3NlcXVlbmNlTGV2ZWxzKSB7CiAgICAgICAgICAgICAgICBpZiAoZG9Ob3RSZXNldFtrZXldKSB7CiAgICAgICAgICAgICAgICAgICAgYWN0aXZlU2VxdWVuY2VzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIF9zZXF1ZW5jZUxldmVsc1trZXldID0gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFhY3RpdmVTZXF1ZW5jZXMpIHsKICAgICAgICAgICAgICAgIF9uZXh0RXhwZWN0ZWRBY3Rpb24gPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogZmluZHMgYWxsIGNhbGxiYWNrcyB0aGF0IG1hdGNoIGJhc2VkIG9uIHRoZSBrZXljb2RlLCBtb2RpZmllcnMsCiAgICAgICAgICogYW5kIGFjdGlvbgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGNoYXJhY3RlcgogICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IG1vZGlmaWVycwogICAgICAgICAqIEBwYXJhbSB7RXZlbnR8T2JqZWN0fSBlCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmc9fSBzZXF1ZW5jZU5hbWUgLSBuYW1lIG9mIHRoZSBzZXF1ZW5jZSB3ZSBhcmUgbG9va2luZyBmb3IKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZz19IGNvbWJpbmF0aW9uCiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBsZXZlbAogICAgICAgICAqIEByZXR1cm5zIHtBcnJheX0KICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBfZ2V0TWF0Y2hlcyhjaGFyYWN0ZXIsIG1vZGlmaWVycywgZSwgc2VxdWVuY2VOYW1lLCBjb21iaW5hdGlvbiwgbGV2ZWwpIHsKICAgICAgICAgICAgdmFyIGk7CiAgICAgICAgICAgIHZhciBjYWxsYmFjazsKICAgICAgICAgICAgdmFyIG1hdGNoZXMgPSBbXTsKICAgICAgICAgICAgdmFyIGFjdGlvbiA9IGUudHlwZTsKCiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGFyZSBubyBldmVudHMgcmVsYXRlZCB0byB0aGlzIGtleWNvZGUKICAgICAgICAgICAgaWYgKCFzZWxmLl9jYWxsYmFja3NbY2hhcmFjdGVyXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIFtdOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBpZiBhIG1vZGlmaWVyIGtleSBpcyBjb21pbmcgdXAgb24gaXRzIG93biB3ZSBzaG91bGQgYWxsb3cgaXQKICAgICAgICAgICAgaWYgKGFjdGlvbiA9PSAna2V5dXAnICYmIF9pc01vZGlmaWVyKGNoYXJhY3RlcikpIHsKICAgICAgICAgICAgICAgIG1vZGlmaWVycyA9IFtjaGFyYWN0ZXJdOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBsb29wIHRocm91Z2ggYWxsIGNhbGxiYWNrcyBmb3IgdGhlIGtleSB0aGF0IHdhcyBwcmVzc2VkCiAgICAgICAgICAgIC8vIGFuZCBzZWUgaWYgYW55IG9mIHRoZW0gbWF0Y2gKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHNlbGYuX2NhbGxiYWNrc1tjaGFyYWN0ZXJdLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgICAgICBjYWxsYmFjayA9IHNlbGYuX2NhbGxiYWNrc1tjaGFyYWN0ZXJdW2ldOwoKICAgICAgICAgICAgICAgIC8vIGlmIGEgc2VxdWVuY2UgbmFtZSBpcyBub3Qgc3BlY2lmaWVkLCBidXQgdGhpcyBpcyBhIHNlcXVlbmNlIGF0CiAgICAgICAgICAgICAgICAvLyB0aGUgd3JvbmcgbGV2ZWwgdGhlbiBtb3ZlIG9udG8gdGhlIG5leHQgbWF0Y2gKICAgICAgICAgICAgICAgIGlmICghc2VxdWVuY2VOYW1lICYmIGNhbGxiYWNrLnNlcSAmJiBfc2VxdWVuY2VMZXZlbHNbY2FsbGJhY2suc2VxXSAhPSBjYWxsYmFjay5sZXZlbCkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBhY3Rpb24gd2UgYXJlIGxvb2tpbmcgZm9yIGRvZXNuJ3QgbWF0Y2ggdGhlIGFjdGlvbiB3ZSBnb3QKICAgICAgICAgICAgICAgIC8vIHRoZW4gd2Ugc2hvdWxkIGtlZXAgZ29pbmcKICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gIT0gY2FsbGJhY2suYWN0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gaWYgdGhpcyBpcyBhIGtleXByZXNzIGV2ZW50IGFuZCB0aGUgbWV0YSBrZXkgYW5kIGNvbnRyb2wga2V5CiAgICAgICAgICAgICAgICAvLyBhcmUgbm90IHByZXNzZWQgdGhhdCBtZWFucyB0aGF0IHdlIG5lZWQgdG8gb25seSBsb29rIGF0IHRoZQogICAgICAgICAgICAgICAgLy8gY2hhcmFjdGVyLCBvdGhlcndpc2UgY2hlY2sgdGhlIG1vZGlmaWVycyBhcyB3ZWxsCiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgLy8gY2hyb21lIHdpbGwgbm90IGZpcmUgYSBrZXlwcmVzcyBpZiBtZXRhIG9yIGNvbnRyb2wgaXMgZG93bgogICAgICAgICAgICAgICAgLy8gc2FmYXJpIHdpbGwgZmlyZSBhIGtleXByZXNzIGlmIG1ldGEgb3IgbWV0YStzaGlmdCBpcyBkb3duCiAgICAgICAgICAgICAgICAvLyBmaXJlZm94IHdpbGwgZmlyZSBhIGtleXByZXNzIGlmIG1ldGEgb3IgY29udHJvbCBpcyBkb3duCiAgICAgICAgICAgICAgICBpZiAoKGFjdGlvbiA9PSAna2V5cHJlc3MnICYmICFlLm1ldGFLZXkgJiYgIWUuY3RybEtleSkgfHwgX21vZGlmaWVyc01hdGNoKG1vZGlmaWVycywgY2FsbGJhY2subW9kaWZpZXJzKSkgewoKICAgICAgICAgICAgICAgICAgICAvLyB3aGVuIHlvdSBiaW5kIGEgY29tYmluYXRpb24gb3Igc2VxdWVuY2UgYSBzZWNvbmQgdGltZSBpdAogICAgICAgICAgICAgICAgICAgIC8vIHNob3VsZCBvdmVyd3JpdGUgdGhlIGZpcnN0IG9uZS4gIGlmIGEgc2VxdWVuY2VOYW1lIG9yCiAgICAgICAgICAgICAgICAgICAgLy8gY29tYmluYXRpb24gaXMgc3BlY2lmaWVkIGluIHRoaXMgY2FsbCBpdCBkb2VzIGp1c3QgdGhhdAogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgLy8gQHRvZG8gbWFrZSBkZWxldGluZyBpdHMgb3duIG1ldGhvZD8KICAgICAgICAgICAgICAgICAgICB2YXIgZGVsZXRlQ29tYm8gPSAhc2VxdWVuY2VOYW1lICYmIGNhbGxiYWNrLmNvbWJvID09IGNvbWJpbmF0aW9uOwogICAgICAgICAgICAgICAgICAgIHZhciBkZWxldGVTZXF1ZW5jZSA9IHNlcXVlbmNlTmFtZSAmJiBjYWxsYmFjay5zZXEgPT0gc2VxdWVuY2VOYW1lICYmIGNhbGxiYWNrLmxldmVsID09IGxldmVsOwogICAgICAgICAgICAgICAgICAgIGlmIChkZWxldGVDb21ibyB8fCBkZWxldGVTZXF1ZW5jZSkgewogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jYWxsYmFja3NbY2hhcmFjdGVyXS5zcGxpY2UoaSwgMSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBtYXRjaGVzLnB1c2goY2FsbGJhY2spOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbWF0Y2hlczsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIGFjdHVhbGx5IGNhbGxzIHRoZSBjYWxsYmFjayBmdW5jdGlvbgogICAgICAgICAqCiAgICAgICAgICogaWYgeW91ciBjYWxsYmFjayBmdW5jdGlvbiByZXR1cm5zIGZhbHNlIHRoaXMgd2lsbCB1c2UgdGhlIGpxdWVyeQogICAgICAgICAqIGNvbnZlbnRpb24gLSBwcmV2ZW50IGRlZmF1bHQgYW5kIHN0b3AgcHJvcG9nYXRpb24gb24gdGhlIGV2ZW50CiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjawogICAgICAgICAqIEBwYXJhbSB7RXZlbnR9IGUKICAgICAgICAgKiBAcmV0dXJucyB2b2lkCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gX2ZpcmVDYWxsYmFjayhjYWxsYmFjaywgZSwgY29tYm8sIHNlcXVlbmNlKSB7CgogICAgICAgICAgICAvLyBpZiB0aGlzIGV2ZW50IHNob3VsZCBub3QgaGFwcGVuIHN0b3AgaGVyZQogICAgICAgICAgICBpZiAoc2VsZi5zdG9wQ2FsbGJhY2soZSwgZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50LCBjb21ibywgc2VxdWVuY2UpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjYWxsYmFjayhlLCBjb21ibykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICBfcHJldmVudERlZmF1bHQoZSk7CiAgICAgICAgICAgICAgICBfc3RvcFByb3BhZ2F0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBoYW5kbGVzIGEgY2hhcmFjdGVyIGtleSBldmVudAogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGNoYXJhY3RlcgogICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IG1vZGlmaWVycwogICAgICAgICAqIEBwYXJhbSB7RXZlbnR9IGUKICAgICAgICAgKiBAcmV0dXJucyB2b2lkCiAgICAgICAgICovCiAgICAgICAgc2VsZi5faGFuZGxlS2V5ID0gZnVuY3Rpb24oY2hhcmFjdGVyLCBtb2RpZmllcnMsIGUpIHsKICAgICAgICAgICAgdmFyIGNhbGxiYWNrcyA9IF9nZXRNYXRjaGVzKGNoYXJhY3RlciwgbW9kaWZpZXJzLCBlKTsKICAgICAgICAgICAgdmFyIGk7CiAgICAgICAgICAgIHZhciBkb05vdFJlc2V0ID0ge307CiAgICAgICAgICAgIHZhciBtYXhMZXZlbCA9IDA7CiAgICAgICAgICAgIHZhciBwcm9jZXNzZWRTZXF1ZW5jZUNhbGxiYWNrID0gZmFsc2U7CgogICAgICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIG1heExldmVsIGZvciBzZXF1ZW5jZXMgc28gd2UgY2FuIG9ubHkgZXhlY3V0ZSB0aGUgbG9uZ2VzdCBjYWxsYmFjayBzZXF1ZW5jZQogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY2FsbGJhY2tzLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2tzW2ldLnNlcSkgewogICAgICAgICAgICAgICAgICAgIG1heExldmVsID0gTWF0aC5tYXgobWF4TGV2ZWwsIGNhbGxiYWNrc1tpXS5sZXZlbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGxvb3AgdGhyb3VnaCBtYXRjaGluZyBjYWxsYmFja3MgZm9yIHRoaXMga2V5IGV2ZW50CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyArK2kpIHsKCiAgICAgICAgICAgICAgICAvLyBmaXJlIGZvciBhbGwgc2VxdWVuY2UgY2FsbGJhY2tzCiAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIGJlY2F1c2UgaWYgZm9yIGV4YW1wbGUgeW91IGhhdmUgbXVsdGlwbGUgc2VxdWVuY2VzCiAgICAgICAgICAgICAgICAvLyBib3VuZCBzdWNoIGFzICJnIGkiIGFuZCAiZyB0IiB0aGV5IGJvdGggbmVlZCB0byBmaXJlIHRoZQogICAgICAgICAgICAgICAgLy8gY2FsbGJhY2sgZm9yIG1hdGNoaW5nIGcgY2F1c2Ugb3RoZXJ3aXNlIHlvdSBjYW4gb25seSBldmVyCiAgICAgICAgICAgICAgICAvLyBtYXRjaCB0aGUgZmlyc3Qgb25lCiAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2tzW2ldLnNlcSkgewoKICAgICAgICAgICAgICAgICAgICAvLyBvbmx5IGZpcmUgY2FsbGJhY2tzIGZvciB0aGUgbWF4TGV2ZWwgdG8gcHJldmVudAogICAgICAgICAgICAgICAgICAgIC8vIHN1YnNlcXVlbmNlcyBmcm9tIGFsc28gZmlyaW5nCiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAvLyBmb3IgZXhhbXBsZSAnYSBvcHRpb24gYicgc2hvdWxkIG5vdCBjYXVzZSAnb3B0aW9uIGInIHRvIGZpcmUKICAgICAgICAgICAgICAgICAgICAvLyBldmVuIHRob3VnaCAnb3B0aW9uIGInIGlzIHBhcnQgb2YgdGhlIG90aGVyIHNlcXVlbmNlCiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAvLyBhbnkgc2VxdWVuY2VzIHRoYXQgZG8gbm90IG1hdGNoIGhlcmUgd2lsbCBiZSBkaXNjYXJkZWQKICAgICAgICAgICAgICAgICAgICAvLyBiZWxvdyBieSB0aGUgX3Jlc2V0U2VxdWVuY2VzIGNhbGwKICAgICAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2tzW2ldLmxldmVsICE9IG1heExldmVsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc2VkU2VxdWVuY2VDYWxsYmFjayA9IHRydWU7CgogICAgICAgICAgICAgICAgICAgIC8vIGtlZXAgYSBsaXN0IG9mIHdoaWNoIHNlcXVlbmNlcyB3ZXJlIG1hdGNoZXMgZm9yIGxhdGVyCiAgICAgICAgICAgICAgICAgICAgZG9Ob3RSZXNldFtjYWxsYmFja3NbaV0uc2VxXSA9IDE7CiAgICAgICAgICAgICAgICAgICAgX2ZpcmVDYWxsYmFjayhjYWxsYmFja3NbaV0uY2FsbGJhY2ssIGUsIGNhbGxiYWNrc1tpXS5jb21ibywgY2FsbGJhY2tzW2ldLnNlcSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gaWYgdGhlcmUgd2VyZSBubyBzZXF1ZW5jZSBtYXRjaGVzIGJ1dCB3ZSBhcmUgc3RpbGwgaGVyZQogICAgICAgICAgICAgICAgLy8gdGhhdCBtZWFucyB0aGlzIGlzIGEgcmVndWxhciBtYXRjaCBzbyB3ZSBzaG91bGQgZmlyZSB0aGF0CiAgICAgICAgICAgICAgICBpZiAoIXByb2Nlc3NlZFNlcXVlbmNlQ2FsbGJhY2spIHsKICAgICAgICAgICAgICAgICAgICBfZmlyZUNhbGxiYWNrKGNhbGxiYWNrc1tpXS5jYWxsYmFjaywgZSwgY2FsbGJhY2tzW2ldLmNvbWJvKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gaWYgdGhlIGtleSB5b3UgcHJlc3NlZCBtYXRjaGVzIHRoZSB0eXBlIG9mIHNlcXVlbmNlIHdpdGhvdXQKICAgICAgICAgICAgLy8gYmVpbmcgYSBtb2RpZmllciAoaWUgImtleXVwIiBvciAia2V5cHJlc3MiKSB0aGVuIHdlIHNob3VsZAogICAgICAgICAgICAvLyByZXNldCBhbGwgc2VxdWVuY2VzIHRoYXQgd2VyZSBub3QgbWF0Y2hlZCBieSB0aGlzIGV2ZW50CiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIHRoaXMgaXMgc28sIGZvciBleGFtcGxlLCBpZiB5b3UgaGF2ZSB0aGUgc2VxdWVuY2UgImggYSB0IiBhbmQgeW91CiAgICAgICAgICAgIC8vIHR5cGUgImggZSBhIHIgdCIgaXQgZG9lcyBub3QgbWF0Y2guICBpbiB0aGlzIGNhc2UgdGhlICJlIiB3aWxsCiAgICAgICAgICAgIC8vIGNhdXNlIHRoZSBzZXF1ZW5jZSB0byByZXNldAogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyBtb2RpZmllciBrZXlzIGFyZSBpZ25vcmVkIGJlY2F1c2UgeW91IGNhbiBoYXZlIGEgc2VxdWVuY2UKICAgICAgICAgICAgLy8gdGhhdCBjb250YWlucyBtb2RpZmllcnMgc3VjaCBhcyAiZW50ZXIgY3RybCtzcGFjZSIgYW5kIGluIG1vc3QKICAgICAgICAgICAgLy8gY2FzZXMgdGhlIG1vZGlmaWVyIGtleSB3aWxsIGJlIHByZXNzZWQgYmVmb3JlIHRoZSBuZXh0IGtleQogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyBhbHNvIGlmIHlvdSBoYXZlIGEgc2VxdWVuY2Ugc3VjaCBhcyAiY3RybCtiIGEiIHRoZW4gcHJlc3NpbmcgdGhlCiAgICAgICAgICAgIC8vICJiIiBrZXkgd2lsbCB0cmlnZ2VyIGEgImtleXByZXNzIiBhbmQgYSAia2V5ZG93biIKICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gdGhlICJrZXlkb3duIiBpcyBleHBlY3RlZCB3aGVuIHRoZXJlIGlzIGEgbW9kaWZpZXIsIGJ1dCB0aGUKICAgICAgICAgICAgLy8gImtleXByZXNzIiBlbmRzIHVwIG1hdGNoaW5nIHRoZSBfbmV4dEV4cGVjdGVkQWN0aW9uIHNpbmNlIGl0IG9jY3VycwogICAgICAgICAgICAvLyBhZnRlciBhbmQgdGhhdCBjYXVzZXMgdGhlIHNlcXVlbmNlIHRvIHJlc2V0CiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIHdlIGlnbm9yZSBrZXlwcmVzc2VzIGluIGEgc2VxdWVuY2UgdGhhdCBkaXJlY3RseSBmb2xsb3cgYSBrZXlkb3duCiAgICAgICAgICAgIC8vIGZvciB0aGUgc2FtZSBjaGFyYWN0ZXIKICAgICAgICAgICAgdmFyIGlnbm9yZVRoaXNLZXlwcmVzcyA9IGUudHlwZSA9PSAna2V5cHJlc3MnICYmIF9pZ25vcmVOZXh0S2V5cHJlc3M7CiAgICAgICAgICAgIGlmIChlLnR5cGUgPT0gX25leHRFeHBlY3RlZEFjdGlvbiAmJiAhX2lzTW9kaWZpZXIoY2hhcmFjdGVyKSAmJiAhaWdub3JlVGhpc0tleXByZXNzKSB7CiAgICAgICAgICAgICAgICBfcmVzZXRTZXF1ZW5jZXMoZG9Ob3RSZXNldCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIF9pZ25vcmVOZXh0S2V5cHJlc3MgPSBwcm9jZXNzZWRTZXF1ZW5jZUNhbGxiYWNrICYmIGUudHlwZSA9PSAna2V5ZG93bic7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICogaGFuZGxlcyBhIGtleWRvd24gZXZlbnQKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7RXZlbnR9IGUKICAgICAgICAgKiBAcmV0dXJucyB2b2lkCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gX2hhbmRsZUtleUV2ZW50KGUpIHsKCiAgICAgICAgICAgIC8vIG5vcm1hbGl6ZSBlLndoaWNoIGZvciBrZXkgZXZlbnRzCiAgICAgICAgICAgIC8vIEBzZWUgaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80Mjg1NjI3L2phdmFzY3JpcHQta2V5Y29kZS12cy1jaGFyY29kZS11dHRlci1jb25mdXNpb24KICAgICAgICAgICAgaWYgKHR5cGVvZiBlLndoaWNoICE9PSAnbnVtYmVyJykgewogICAgICAgICAgICAgICAgZS53aGljaCA9IGUua2V5Q29kZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGNoYXJhY3RlciA9IF9jaGFyYWN0ZXJGcm9tRXZlbnQoZSk7CgogICAgICAgICAgICAvLyBubyBjaGFyYWN0ZXIgZm91bmQgdGhlbiBzdG9wCiAgICAgICAgICAgIGlmICghY2hhcmFjdGVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIG5lZWQgdG8gdXNlID09PSBmb3IgdGhlIGNoYXJhY3RlciBjaGVjayBiZWNhdXNlIHRoZSBjaGFyYWN0ZXIgY2FuIGJlIDAKICAgICAgICAgICAgaWYgKGUudHlwZSA9PSAna2V5dXAnICYmIF9pZ25vcmVOZXh0S2V5dXAgPT09IGNoYXJhY3RlcikgewogICAgICAgICAgICAgICAgX2lnbm9yZU5leHRLZXl1cCA9IGZhbHNlOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzZWxmLmhhbmRsZUtleShjaGFyYWN0ZXIsIF9ldmVudE1vZGlmaWVycyhlKSwgZSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBjYWxsZWQgdG8gc2V0IGEgMSBzZWNvbmQgdGltZW91dCBvbiB0aGUgc3BlY2lmaWVkIHNlcXVlbmNlCiAgICAgICAgICoKICAgICAgICAgKiB0aGlzIGlzIHNvIGFmdGVyIGVhY2gga2V5IHByZXNzIGluIHRoZSBzZXF1ZW5jZSB5b3UgaGF2ZSAxIHNlY29uZAogICAgICAgICAqIHRvIHByZXNzIHRoZSBuZXh0IGtleSBiZWZvcmUgeW91IGhhdmUgdG8gc3RhcnQgb3ZlcgogICAgICAgICAqCiAgICAgICAgICogQHJldHVybnMgdm9pZAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIF9yZXNldFNlcXVlbmNlVGltZXIoKSB7CiAgICAgICAgICAgIGNsZWFyVGltZW91dChfcmVzZXRUaW1lcik7CiAgICAgICAgICAgIF9yZXNldFRpbWVyID0gc2V0VGltZW91dChfcmVzZXRTZXF1ZW5jZXMsIDEwMDApOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogYmluZHMgYSBrZXkgc2VxdWVuY2UgdG8gYW4gZXZlbnQKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjb21ibyAtIGNvbWJvIHNwZWNpZmllZCBpbiBiaW5kIGNhbGwKICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBrZXlzCiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZz19IGFjdGlvbgogICAgICAgICAqIEByZXR1cm5zIHZvaWQKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBfYmluZFNlcXVlbmNlKGNvbWJvLCBrZXlzLCBjYWxsYmFjaywgYWN0aW9uKSB7CgogICAgICAgICAgICAvLyBzdGFydCBvZmYgYnkgYWRkaW5nIGEgc2VxdWVuY2UgbGV2ZWwgcmVjb3JkIGZvciB0aGlzIGNvbWJpbmF0aW9uCiAgICAgICAgICAgIC8vIGFuZCBzZXR0aW5nIHRoZSBsZXZlbCB0byAwCiAgICAgICAgICAgIF9zZXF1ZW5jZUxldmVsc1tjb21ib10gPSAwOwoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIGNhbGxiYWNrIHRvIGluY3JlYXNlIHRoZSBzZXF1ZW5jZSBsZXZlbCBmb3IgdGhpcyBzZXF1ZW5jZSBhbmQgcmVzZXQKICAgICAgICAgICAgICogYWxsIG90aGVyIHNlcXVlbmNlcyB0aGF0IHdlcmUgYWN0aXZlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuZXh0QWN0aW9uCiAgICAgICAgICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZ1bmN0aW9uIF9pbmNyZWFzZVNlcXVlbmNlKG5leHRBY3Rpb24pIHsKICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICBfbmV4dEV4cGVjdGVkQWN0aW9uID0gbmV4dEFjdGlvbjsKICAgICAgICAgICAgICAgICAgICArK19zZXF1ZW5jZUxldmVsc1tjb21ib107CiAgICAgICAgICAgICAgICAgICAgX3Jlc2V0U2VxdWVuY2VUaW1lcigpOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIHdyYXBzIHRoZSBzcGVjaWZpZWQgY2FsbGJhY2sgaW5zaWRlIG9mIGFub3RoZXIgZnVuY3Rpb24gaW4gb3JkZXIKICAgICAgICAgICAgICogdG8gcmVzZXQgYWxsIHNlcXVlbmNlIGNvdW50ZXJzIGFzIHNvb24gYXMgdGhpcyBzZXF1ZW5jZSBpcyBkb25lCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7RXZlbnR9IGUKICAgICAgICAgICAgICogQHJldHVybnMgdm9pZAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZnVuY3Rpb24gX2NhbGxiYWNrQW5kUmVzZXQoZSkgewogICAgICAgICAgICAgICAgX2ZpcmVDYWxsYmFjayhjYWxsYmFjaywgZSwgY29tYm8pOwoKICAgICAgICAgICAgICAgIC8vIHdlIHNob3VsZCBpZ25vcmUgdGhlIG5leHQga2V5IHVwIGlmIHRoZSBhY3Rpb24gaXMga2V5IGRvd24KICAgICAgICAgICAgICAgIC8vIG9yIGtleXByZXNzLiAgdGhpcyBpcyBzbyBpZiB5b3UgZmluaXNoIGEgc2VxdWVuY2UgYW5kCiAgICAgICAgICAgICAgICAvLyByZWxlYXNlIHRoZSBrZXkgdGhlIGZpbmFsIGtleSB3aWxsIG5vdCB0cmlnZ2VyIGEga2V5dXAKICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gIT09ICdrZXl1cCcpIHsKICAgICAgICAgICAgICAgICAgICBfaWdub3JlTmV4dEtleXVwID0gX2NoYXJhY3RlckZyb21FdmVudChlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyB3ZWlyZCByYWNlIGNvbmRpdGlvbiBpZiBhIHNlcXVlbmNlIGVuZHMgd2l0aCB0aGUga2V5CiAgICAgICAgICAgICAgICAvLyBhbm90aGVyIHNlcXVlbmNlIGJlZ2lucyB3aXRoCiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KF9yZXNldFNlcXVlbmNlcywgMTApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBsb29wIHRocm91Z2gga2V5cyBvbmUgYXQgYSB0aW1lIGFuZCBiaW5kIHRoZSBhcHByb3ByaWF0ZSBjYWxsYmFjawogICAgICAgICAgICAvLyBmdW5jdGlvbi4gIGZvciBhbnkga2V5IGxlYWRpbmcgdXAgdG8gdGhlIGZpbmFsIG9uZSBpdCBzaG91bGQKICAgICAgICAgICAgLy8gaW5jcmVhc2UgdGhlIHNlcXVlbmNlLiBhZnRlciB0aGUgZmluYWwsIGl0IHNob3VsZCByZXNldCBhbGwgc2VxdWVuY2VzCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIGlmIGFuIGFjdGlvbiBpcyBzcGVjaWZpZWQgaW4gdGhlIG9yaWdpbmFsIGJpbmQgY2FsbCB0aGVuIHRoYXQgd2lsbAogICAgICAgICAgICAvLyBiZSB1c2VkIHRocm91Z2hvdXQuICBvdGhlcndpc2Ugd2Ugd2lsbCBwYXNzIHRoZSBhY3Rpb24gdGhhdCB0aGUKICAgICAgICAgICAgLy8gbmV4dCBrZXkgaW4gdGhlIHNlcXVlbmNlIHNob3VsZCBtYXRjaC4gIHRoaXMgYWxsb3dzIGEgc2VxdWVuY2UKICAgICAgICAgICAgLy8gdG8gbWl4IGFuZCBtYXRjaCBrZXlwcmVzcyBhbmQga2V5ZG93biBldmVudHMgZGVwZW5kaW5nIG9uIHdoaWNoCiAgICAgICAgICAgIC8vIG9uZXMgYXJlIGJldHRlciBzdWl0ZWQgdG8gdGhlIGtleSBwcm92aWRlZAogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIHZhciBpc0ZpbmFsID0gaSArIDEgPT09IGtleXMubGVuZ3RoOwogICAgICAgICAgICAgICAgdmFyIHdyYXBwZWRDYWxsYmFjayA9IGlzRmluYWwgPyBfY2FsbGJhY2tBbmRSZXNldCA6IF9pbmNyZWFzZVNlcXVlbmNlKGFjdGlvbiB8fCBfZ2V0S2V5SW5mbyhrZXlzW2kgKyAxXSkuYWN0aW9uKTsKICAgICAgICAgICAgICAgIF9iaW5kU2luZ2xlKGtleXNbaV0sIHdyYXBwZWRDYWxsYmFjaywgYWN0aW9uLCBjb21ibywgaSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIGJpbmRzIGEgc2luZ2xlIGtleWJvYXJkIGNvbWJpbmF0aW9uCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gY29tYmluYXRpb24KICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjawogICAgICAgICAqIEBwYXJhbSB7c3RyaW5nPX0gYWN0aW9uCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmc9fSBzZXF1ZW5jZU5hbWUgLSBuYW1lIG9mIHNlcXVlbmNlIGlmIHBhcnQgb2Ygc2VxdWVuY2UKICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IGxldmVsIC0gd2hhdCBwYXJ0IG9mIHRoZSBzZXF1ZW5jZSB0aGUgY29tbWFuZCBpcwogICAgICAgICAqIEByZXR1cm5zIHZvaWQKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBfYmluZFNpbmdsZShjb21iaW5hdGlvbiwgY2FsbGJhY2ssIGFjdGlvbiwgc2VxdWVuY2VOYW1lLCBsZXZlbCkgewoKICAgICAgICAgICAgLy8gc3RvcmUgYSBkaXJlY3QgbWFwcGVkIHJlZmVyZW5jZSBmb3IgdXNlIHdpdGggTW91c2V0cmFwLnRyaWdnZXIKICAgICAgICAgICAgc2VsZi5fZGlyZWN0TWFwW2NvbWJpbmF0aW9uICsgJzonICsgYWN0aW9uXSA9IGNhbGxiYWNrOwoKICAgICAgICAgICAgLy8gbWFrZSBzdXJlIG11bHRpcGxlIHNwYWNlcyBpbiBhIHJvdyBiZWNvbWUgYSBzaW5nbGUgc3BhY2UKICAgICAgICAgICAgY29tYmluYXRpb24gPSBjb21iaW5hdGlvbi5yZXBsYWNlKC9ccysvZywgJyAnKTsKCiAgICAgICAgICAgIHZhciBzZXF1ZW5jZSA9IGNvbWJpbmF0aW9uLnNwbGl0KCcgJyk7CiAgICAgICAgICAgIHZhciBpbmZvOwoKICAgICAgICAgICAgLy8gaWYgdGhpcyBwYXR0ZXJuIGlzIGEgc2VxdWVuY2Ugb2Yga2V5cyB0aGVuIHJ1biB0aHJvdWdoIHRoaXMgbWV0aG9kCiAgICAgICAgICAgIC8vIHRvIHJlcHJvY2VzcyBlYWNoIHBhdHRlcm4gb25lIGtleSBhdCBhIHRpbWUKICAgICAgICAgICAgaWYgKHNlcXVlbmNlLmxlbmd0aCA+IDEpIHsKICAgICAgICAgICAgICAgIF9iaW5kU2VxdWVuY2UoY29tYmluYXRpb24sIHNlcXVlbmNlLCBjYWxsYmFjaywgYWN0aW9uKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaW5mbyA9IF9nZXRLZXlJbmZvKGNvbWJpbmF0aW9uLCBhY3Rpb24pOwoKICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRvIGluaXRpYWxpemUgYXJyYXkgaWYgdGhpcyBpcyB0aGUgZmlyc3QgdGltZQogICAgICAgICAgICAvLyBhIGNhbGxiYWNrIGlzIGFkZGVkIGZvciB0aGlzIGtleQogICAgICAgICAgICBzZWxmLl9jYWxsYmFja3NbaW5mby5rZXldID0gc2VsZi5fY2FsbGJhY2tzW2luZm8ua2V5XSB8fCBbXTsKCiAgICAgICAgICAgIC8vIHJlbW92ZSBhbiBleGlzdGluZyBtYXRjaCBpZiB0aGVyZSBpcyBvbmUKICAgICAgICAgICAgX2dldE1hdGNoZXMoaW5mby5rZXksIGluZm8ubW9kaWZpZXJzLCB7dHlwZTogaW5mby5hY3Rpb259LCBzZXF1ZW5jZU5hbWUsIGNvbWJpbmF0aW9uLCBsZXZlbCk7CgogICAgICAgICAgICAvLyBhZGQgdGhpcyBjYWxsIGJhY2sgdG8gdGhlIGFycmF5CiAgICAgICAgICAgIC8vIGlmIGl0IGlzIGEgc2VxdWVuY2UgcHV0IGl0IGF0IHRoZSBiZWdpbm5pbmcKICAgICAgICAgICAgLy8gaWYgbm90IHB1dCBpdCBhdCB0aGUgZW5kCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIHRoaXMgaXMgaW1wb3J0YW50IGJlY2F1c2UgdGhlIHdheSB0aGVzZSBhcmUgcHJvY2Vzc2VkIGV4cGVjdHMKICAgICAgICAgICAgLy8gdGhlIHNlcXVlbmNlIG9uZXMgdG8gY29tZSBmaXJzdAogICAgICAgICAgICBzZWxmLl9jYWxsYmFja3NbaW5mby5rZXldW3NlcXVlbmNlTmFtZSA/ICd1bnNoaWZ0JyA6ICdwdXNoJ10oewogICAgICAgICAgICAgICAgY2FsbGJhY2s6IGNhbGxiYWNrLAogICAgICAgICAgICAgICAgbW9kaWZpZXJzOiBpbmZvLm1vZGlmaWVycywKICAgICAgICAgICAgICAgIGFjdGlvbjogaW5mby5hY3Rpb24sCiAgICAgICAgICAgICAgICBzZXE6IHNlcXVlbmNlTmFtZSwKICAgICAgICAgICAgICAgIGxldmVsOiBsZXZlbCwKICAgICAgICAgICAgICAgIGNvbWJvOiBjb21iaW5hdGlvbgogICAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIGJpbmRzIG11bHRpcGxlIGNvbWJpbmF0aW9ucyB0byB0aGUgc2FtZSBjYWxsYmFjawogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtBcnJheX0gY29tYmluYXRpb25zCiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ3x1bmRlZmluZWR9IGFjdGlvbgogICAgICAgICAqIEByZXR1cm5zIHZvaWQKICAgICAgICAgKi8KICAgICAgICBzZWxmLl9iaW5kTXVsdGlwbGUgPSBmdW5jdGlvbihjb21iaW5hdGlvbnMsIGNhbGxiYWNrLCBhY3Rpb24pIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb21iaW5hdGlvbnMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIF9iaW5kU2luZ2xlKGNvbWJpbmF0aW9uc1tpXSwgY2FsbGJhY2ssIGFjdGlvbik7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICAvLyBzdGFydCEKICAgICAgICBfYWRkRXZlbnQodGFyZ2V0RWxlbWVudCwgJ2tleXByZXNzJywgX2hhbmRsZUtleUV2ZW50KTsKICAgICAgICBfYWRkRXZlbnQodGFyZ2V0RWxlbWVudCwgJ2tleWRvd24nLCBfaGFuZGxlS2V5RXZlbnQpOwogICAgICAgIF9hZGRFdmVudCh0YXJnZXRFbGVtZW50LCAna2V5dXAnLCBfaGFuZGxlS2V5RXZlbnQpOwogICAgfQoKICAgIC8qKgogICAgICogYmluZHMgYW4gZXZlbnQgdG8gbW91c2V0cmFwCiAgICAgKgogICAgICogY2FuIGJlIGEgc2luZ2xlIGtleSwgYSBjb21iaW5hdGlvbiBvZiBrZXlzIHNlcGFyYXRlZCB3aXRoICssCiAgICAgKiBhbiBhcnJheSBvZiBrZXlzLCBvciBhIHNlcXVlbmNlIG9mIGtleXMgc2VwYXJhdGVkIGJ5IHNwYWNlcwogICAgICoKICAgICAqIGJlIHN1cmUgdG8gbGlzdCB0aGUgbW9kaWZpZXIga2V5cyBmaXJzdCB0byBtYWtlIHN1cmUgdGhhdCB0aGUKICAgICAqIGNvcnJlY3Qga2V5IGVuZHMgdXAgZ2V0dGluZyBib3VuZCAodGhlIGxhc3Qga2V5IGluIHRoZSBwYXR0ZXJuKQogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfEFycmF5fSBrZXlzCiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjawogICAgICogQHBhcmFtIHtzdHJpbmc9fSBhY3Rpb24gLSAna2V5cHJlc3MnLCAna2V5ZG93bicsIG9yICdrZXl1cCcKICAgICAqIEByZXR1cm5zIHZvaWQKICAgICAqLwogICAgTW91c2V0cmFwLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24oa2V5cywgY2FsbGJhY2ssIGFjdGlvbikgewogICAgICAgIHZhciBzZWxmID0gdGhpczsKICAgICAgICBrZXlzID0ga2V5cyBpbnN0YW5jZW9mIEFycmF5ID8ga2V5cyA6IFtrZXlzXTsKICAgICAgICBzZWxmLl9iaW5kTXVsdGlwbGUuY2FsbChzZWxmLCBrZXlzLCBjYWxsYmFjaywgYWN0aW9uKTsKICAgICAgICByZXR1cm4gc2VsZjsKICAgIH07CgogICAgLyoqCiAgICAgKiB1bmJpbmRzIGFuIGV2ZW50IHRvIG1vdXNldHJhcAogICAgICoKICAgICAqIHRoZSB1bmJpbmRpbmcgc2V0cyB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gb2YgdGhlIHNwZWNpZmllZCBrZXkgY29tYm8KICAgICAqIHRvIGFuIGVtcHR5IGZ1bmN0aW9uIGFuZCBkZWxldGVzIHRoZSBjb3JyZXNwb25kaW5nIGtleSBpbiB0aGUKICAgICAqIF9kaXJlY3RNYXAgZGljdC4KICAgICAqCiAgICAgKiBUT0RPOiBhY3R1YWxseSByZW1vdmUgdGhpcyBmcm9tIHRoZSBfY2FsbGJhY2tzIGRpY3Rpb25hcnkgaW5zdGVhZAogICAgICogb2YgYmluZGluZyBhbiBlbXB0eSBmdW5jdGlvbgogICAgICoKICAgICAqIHRoZSBrZXljb21ibythY3Rpb24gaGFzIHRvIGJlIGV4YWN0bHkgdGhlIHNhbWUgYXMKICAgICAqIGl0IHdhcyBkZWZpbmVkIGluIHRoZSBiaW5kIG1ldGhvZAogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfEFycmF5fSBrZXlzCiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYWN0aW9uCiAgICAgKiBAcmV0dXJucyB2b2lkCiAgICAgKi8KICAgIE1vdXNldHJhcC5wcm90b3R5cGUudW5iaW5kID0gZnVuY3Rpb24oa2V5cywgYWN0aW9uKSB7CiAgICAgICAgdmFyIHNlbGYgPSB0aGlzOwogICAgICAgIHJldHVybiBzZWxmLmJpbmQuY2FsbChzZWxmLCBrZXlzLCBmdW5jdGlvbigpIHt9LCBhY3Rpb24pOwogICAgfTsKCiAgICAvKioKICAgICAqIHRyaWdnZXJzIGFuIGV2ZW50IHRoYXQgaGFzIGFscmVhZHkgYmVlbiBib3VuZAogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlzCiAgICAgKiBAcGFyYW0ge3N0cmluZz19IGFjdGlvbgogICAgICogQHJldHVybnMgdm9pZAogICAgICovCiAgICBNb3VzZXRyYXAucHJvdG90eXBlLnRyaWdnZXIgPSBmdW5jdGlvbihrZXlzLCBhY3Rpb24pIHsKICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICAgICAgaWYgKHNlbGYuX2RpcmVjdE1hcFtrZXlzICsgJzonICsgYWN0aW9uXSkgewogICAgICAgICAgICBzZWxmLl9kaXJlY3RNYXBba2V5cyArICc6JyArIGFjdGlvbl0oe30sIGtleXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsZjsKICAgIH07CgogICAgLyoqCiAgICAgKiByZXNldHMgdGhlIGxpYnJhcnkgYmFjayB0byBpdHMgaW5pdGlhbCBzdGF0ZS4gIHRoaXMgaXMgdXNlZnVsCiAgICAgKiBpZiB5b3Ugd2FudCB0byBjbGVhciBvdXQgdGhlIGN1cnJlbnQga2V5Ym9hcmQgc2hvcnRjdXRzIGFuZCBiaW5kCiAgICAgKiBuZXcgb25lcyAtIGZvciBleGFtcGxlIGlmIHlvdSBzd2l0Y2ggdG8gYW5vdGhlciBwYWdlCiAgICAgKgogICAgICogQHJldHVybnMgdm9pZAogICAgICovCiAgICBNb3VzZXRyYXAucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIHNlbGYgPSB0aGlzOwogICAgICAgIHNlbGYuX2NhbGxiYWNrcyA9IHt9OwogICAgICAgIHNlbGYuX2RpcmVjdE1hcCA9IHt9OwogICAgICAgIHJldHVybiBzZWxmOwogICAgfTsKCiAgICAvKioKICAgICAqIHNob3VsZCB3ZSBzdG9wIHRoaXMgZXZlbnQgYmVmb3JlIGZpcmluZyBvZmYgY2FsbGJhY2tzCiAgICAgKgogICAgICogQHBhcmFtIHtFdmVudH0gZQogICAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50CiAgICAgKiBAcmV0dXJuIHtib29sZWFufQogICAgICovCiAgICBNb3VzZXRyYXAucHJvdG90eXBlLnN0b3BDYWxsYmFjayA9IGZ1bmN0aW9uKGUsIGVsZW1lbnQpIHsKICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CgogICAgICAgIC8vIGlmIHRoZSBlbGVtZW50IGhhcyB0aGUgY2xhc3MgIm1vdXNldHJhcCIgdGhlbiBubyBuZWVkIHRvIHN0b3AKICAgICAgICBpZiAoKCcgJyArIGVsZW1lbnQuY2xhc3NOYW1lICsgJyAnKS5pbmRleE9mKCcgbW91c2V0cmFwICcpID4gLTEpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYgKF9iZWxvbmdzVG8oZWxlbWVudCwgc2VsZi50YXJnZXQpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8vIHN0b3AgZm9yIGlucHV0LCBzZWxlY3QsIGFuZCB0ZXh0YXJlYQogICAgICAgIHJldHVybiBlbGVtZW50LnRhZ05hbWUgPT0gJ0lOUFVUJyB8fCBlbGVtZW50LnRhZ05hbWUgPT0gJ1NFTEVDVCcgfHwgZWxlbWVudC50YWdOYW1lID09ICdURVhUQVJFQScgfHwgZWxlbWVudC5pc0NvbnRlbnRFZGl0YWJsZTsKICAgIH07CgogICAgLyoqCiAgICAgKiBleHBvc2VzIF9oYW5kbGVLZXkgcHVibGljbHkgc28gaXQgY2FuIGJlIG92ZXJ3cml0dGVuIGJ5IGV4dGVuc2lvbnMKICAgICAqLwogICAgTW91c2V0cmFwLnByb3RvdHlwZS5oYW5kbGVLZXkgPSBmdW5jdGlvbigpIHsKICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICAgICAgcmV0dXJuIHNlbGYuX2hhbmRsZUtleS5hcHBseShzZWxmLCBhcmd1bWVudHMpOwogICAgfTsKCiAgICAvKioKICAgICAqIGFsbG93IGN1c3RvbSBrZXkgbWFwcGluZ3MKICAgICAqLwogICAgTW91c2V0cmFwLmFkZEtleWNvZGVzID0gZnVuY3Rpb24ob2JqZWN0KSB7CiAgICAgICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkgewogICAgICAgICAgICBpZiAob2JqZWN0Lmhhc093blByb3BlcnR5KGtleSkpIHsKICAgICAgICAgICAgICAgIF9NQVBba2V5XSA9IG9iamVjdFtrZXldOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIF9SRVZFUlNFX01BUCA9IG51bGw7CiAgICB9OwoKICAgIC8qKgogICAgICogSW5pdCB0aGUgZ2xvYmFsIG1vdXNldHJhcCBmdW5jdGlvbnMKICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBpcyBuZWVkZWQgdG8gYWxsb3cgdGhlIGdsb2JhbCBtb3VzZXRyYXAgZnVuY3Rpb25zIHRvIHdvcmsKICAgICAqIG5vdyB0aGF0IG1vdXNldHJhcCBpcyBhIGNvbnN0cnVjdG9yIGZ1bmN0aW9uLgogICAgICovCiAgICBNb3VzZXRyYXAuaW5pdCA9IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciBkb2N1bWVudE1vdXNldHJhcCA9IE1vdXNldHJhcChkb2N1bWVudCk7CiAgICAgICAgZm9yICh2YXIgbWV0aG9kIGluIGRvY3VtZW50TW91c2V0cmFwKSB7CiAgICAgICAgICAgIGlmIChtZXRob2QuY2hhckF0KDApICE9PSAnXycpIHsKICAgICAgICAgICAgICAgIE1vdXNldHJhcFttZXRob2RdID0gKGZ1bmN0aW9uKG1ldGhvZCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50TW91c2V0cmFwW21ldGhvZF0uYXBwbHkoZG9jdW1lbnRNb3VzZXRyYXAsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIH0gKG1ldGhvZCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKCiAgICBNb3VzZXRyYXAuaW5pdCgpOwoKICAgIC8vIGV4cG9zZSBtb3VzZXRyYXAgdG8gdGhlIGdsb2JhbCBvYmplY3QKICAgIHdpbmRvdy5Nb3VzZXRyYXAgPSBNb3VzZXRyYXA7CgogICAgLy8gZXhwb3NlIGFzIGEgY29tbW9uIGpzIG1vZHVsZQogICAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBNb3VzZXRyYXA7CiAgICB9CgogICAgLy8gZXhwb3NlIG1vdXNldHJhcCBhcyBhbiBBTUQgbW9kdWxlCiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7CiAgICAgICAgZGVmaW5lKGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gTW91c2V0cmFwOwogICAgICAgIH0pOwogICAgfQp9KSAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiBudWxsLCB0eXBlb2YgIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyBkb2N1bWVudCA6IG51bGwpOwo="},{"meta":{"name":"mousetrap-global-bind.js","url":"https://raw.githubusercontent.com/ccampbell/mousetrap/master/plugins/global-bind/mousetrap-global-bind.js","ts":1539246621153,"mimetype":"text/javascript"},"source":"LyoqCiAqIGFkZHMgYSBiaW5kR2xvYmFsIG1ldGhvZCB0byBNb3VzZXRyYXAgdGhhdCBhbGxvd3MgeW91IHRvCiAqIGJpbmQgc3BlY2lmaWMga2V5Ym9hcmQgc2hvcnRjdXRzIHRoYXQgd2lsbCBzdGlsbCB3b3JrCiAqIGluc2lkZSBhIHRleHQgaW5wdXQgZmllbGQKICoKICogdXNhZ2U6CiAqIE1vdXNldHJhcC5iaW5kR2xvYmFsKCdjdHJsK3MnLCBfc2F2ZUNoYW5nZXMpOwogKi8KLyogZ2xvYmFsIE1vdXNldHJhcDp0cnVlICovCihmdW5jdGlvbihNb3VzZXRyYXApIHsKICAgIHZhciBfZ2xvYmFsQ2FsbGJhY2tzID0ge307CiAgICB2YXIgX29yaWdpbmFsU3RvcENhbGxiYWNrID0gTW91c2V0cmFwLnByb3RvdHlwZS5zdG9wQ2FsbGJhY2s7CgogICAgTW91c2V0cmFwLnByb3RvdHlwZS5zdG9wQ2FsbGJhY2sgPSBmdW5jdGlvbihlLCBlbGVtZW50LCBjb21ibywgc2VxdWVuY2UpIHsKICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CgogICAgICAgIGlmIChzZWxmLnBhdXNlZCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmIChfZ2xvYmFsQ2FsbGJhY2tzW2NvbWJvXSB8fCBfZ2xvYmFsQ2FsbGJhY2tzW3NlcXVlbmNlXSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gX29yaWdpbmFsU3RvcENhbGxiYWNrLmNhbGwoc2VsZiwgZSwgZWxlbWVudCwgY29tYm8pOwogICAgfTsKCiAgICBNb3VzZXRyYXAucHJvdG90eXBlLmJpbmRHbG9iYWwgPSBmdW5jdGlvbihrZXlzLCBjYWxsYmFjaywgYWN0aW9uKSB7CiAgICAgICAgdmFyIHNlbGYgPSB0aGlzOwogICAgICAgIHNlbGYuYmluZChrZXlzLCBjYWxsYmFjaywgYWN0aW9uKTsKCiAgICAgICAgaWYgKGtleXMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIF9nbG9iYWxDYWxsYmFja3Nba2V5c1tpXV0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIF9nbG9iYWxDYWxsYmFja3Nba2V5c10gPSB0cnVlOwogICAgfTsKCiAgICBNb3VzZXRyYXAuaW5pdCgpOwp9KSAoTW91c2V0cmFwKTsK"}]}]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment