swig-cli
Version:
Swig is a simple CLI tool for automating dev workflows via compositions of series and parallel tasks.
2 lines • 82.9 kB
JavaScript
"use strict";var t=require("node:fs"),e=require("node:path"),n=require("node:url");function r(t){var e=Object.create(null);return t&&Object.keys(t).forEach((function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(t,n);Object.defineProperty(e,n,r.get?r:{enumerable:!0,get:function(){return t[n]}})}})),e.default=t,Object.freeze(e)}var i,o=r(e);function s(t,e,n,r){return new(n||(n=Promise))((function(i,o){function s(t){try{c(r.next(t))}catch(t){o(t)}}function a(t){try{c(r.throw(t))}catch(t){o(t)}}function c(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,a)}c((r=r.apply(t,e||[])).next())}))}function a(t,e){var n,r,i,o,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function a(a){return function(c){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,a[0]&&(s=0)),s;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return s.label++,{value:a[1],done:!1};case 5:s.label++,r=a[1],a=[0];continue;case 7:a=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){s=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]<i[3])){s.label=a[1];break}if(6===a[0]&&s.label<i[1]){s.label=i[1],i=a;break}if(i&&s.label<i[2]){s.label=i[2],s.ops.push(a);break}i[2]&&s.ops.pop(),s.trys.pop();continue}a=e.call(t,s)}catch(t){a=[6,t],r=0}finally{n=i=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,c])}}}function c(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i<o;i++)!r&&i in e||(r||(r=Array.prototype.slice.call(e,0,i)),r[i]=e[i]);return t.concat(r||Array.prototype.slice.call(e))}function u(t){for(var e=[],n=1;n<arguments.length;n++)e[n-1]=arguments[n];console.log.apply(console,c([t],e,!1))}"function"==typeof SuppressedError&&SuppressedError,function(t){t.RESET="[0m",t.RED="[31m",t.GREEN="[32m",t.YELLOW="[33m",t.CYAN="[96m",t.GRAY="[90m",t.PURPLE="[35m"}(i||(i={}));var l,f=function(t,e){return"".concat(e).concat(t).concat(i.RESET)},h=function(t){return f(t,i.RED)},p=function(t){return f(t,i.CYAN)},m=function(t){return f(t,i.GRAY)},d=function(t){var e;return"function"==typeof t&&!(!1===(null===(e=Object.getOwnPropertyDescriptor(t,"prototype"))||void 0===e?void 0:e.writable))},g=["swigfile.cjs","swigfile.mjs","swigfile.js","swigfile.ts"],v=function(t,e){var n=this;this.matches=function(t){return n.value===t.id},this.value=t,this.isCommand=e},y=function(){function e(){var t=this;this.isCommonJS="function"==typeof require&&"object"==typeof module&&module.exports,this.isEsm=!this.isCommonJS,this.versionString="1.0.4",this.cwd=process.cwd(),this.seriesCounter=1,this.parallelCounter=1,this.listCommand={id:"list",names:["list","ls","l"],alternateNames:["-l","--list"],description:"List available tasks (default)",example:"swig list"},this.helpCommand={id:"help",names:["help","h"],alternateNames:["-h","--help"],description:"Show help message",example:"swig help"},this.versionCommand={id:"version",names:["version","v"],alternateNames:["-v","--version"],description:"Print version number",example:"swig version"},this.filterCommand={id:"filter",names:["filter","f"],alternateNames:["-f","--filter"],description:"Filter and list tasks by name",example:"swig filter pattern"},this.commandDescriptors=[{id:"task",names:["<taskName>"],alternateNames:[],description:'Run a "task", which is an async function exported from your swigfile',example:"swig taskName"},this.listCommand,this.helpCommand,this.versionCommand,this.filterCommand],this.series=function(e){for(var n=[],r=1;r<arguments.length;r++)n[r-1]=arguments[r];return function(){return s(t,void 0,void 0,(function(){var t,r,i;return a(this,(function(o){switch(o.label){case 0:t=0,r=c([e],n,!0),o.label=1;case 1:return t<r.length?(i=r[t],[4,this.runTask(this.getLogNameAndTask(i))]):[3,4];case 2:o.sent(),o.label=3;case 3:return t++,[3,1];case 4:return[2]}}))}))}},this.parallel=function(){for(var e=[],n=0;n<arguments.length;n++)e[n]=arguments[n];return function(){return s(t,void 0,void 0,(function(){var t,n,r,i=this;return a(this,(function(o){switch(o.label){case 0:return t=e.map((function(t){return i.runTask(i.getLogNameAndTask(t))})),[4,Promise.allSettled(t)];case 1:if(n=o.sent(),(r=n.filter((function(t){return"rejected"===t.status}))).length>0)throw r.map((function(t){return t.reason}));return[2]}}))}))}}}return e.prototype.runMainAsync=function(){return s(this,void 0,void 0,(function(){var t;return a(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),[4,this.main()];case 1:return e.sent(),this.okExit(),[3,3];case 2:return t=e.sent(),console.error(t),this.failureExit("An unexpected error occurred"),[3,3];case 3:return[2]}}))}))},e.prototype.runTask=function(t){return s(this,void 0,void 0,(function(){var e,n,r;return a(this,(function(i){switch(i.label){case 0:return e=Date.now(),this.logFormattedStartMessage(t.logName,e),[4,t.task()];case 1:return i.sent(),n=Date.now(),r=n-e,this.logFormattedEndMessage(t.logName,n,r),[2]}}))}))},e.prototype.getLogNameAndTask=function(t){if(this.throwIfNotTaskOrNamedTask(t),k(t))return{logName:t[0],task:t[1]};var e=t.name;return"innerSeries"===e?(e="nested_series_".concat(this.seriesCounter.toString()),this.seriesCounter++):"innerParallel"===e?(e="nested_parallel_".concat(this.parallelCounter.toString()),this.parallelCounter++):e||(e="anonymous"),{logName:e,task:t}},e.prototype.throwIfNotTaskOrNamedTask=function(t){if(!k(t)&&!d(t))throw new Error('A param passed to "series" or "parallel" was not a Task (function) or a NamedTask ([string,function] tuple): '.concat(t))},e.prototype.getTimestampPrefix=function(t){var e=String(t.getHours()).padStart(2,"0"),n=String(t.getMinutes()).padStart(2,"0"),r=String(t.getSeconds()).padStart(2,"0"),i=String(t.getMilliseconds()).padStart(3,"0");return m("[".concat(e,":").concat(n,":").concat(r,".").concat(i,"]"))},e.prototype.logFormattedStartMessage=function(t,e){var n="".concat(this.getTimestampPrefix(new Date(e))," ");u("".concat(n,"Starting 🚀 ").concat(p(t)))},e.prototype.logFormattedEndMessage=function(t,e,n){var r,o="".concat(this.getTimestampPrefix(new Date(e))," ");u("".concat(o,"Finished ✅ ").concat(p(t)," after ").concat((r=this.humanizeTime(n),f(r,i.PURPLE))))},e.prototype.humanizeTime=function(t){var e,n;if(t<1e3)return"".concat(t," ms");t<6e4?(e=t/1e3,n="second"):t<36e5?(e=t/6e4,n="minute"):(e=t/36e5,n="hour");var r=e.toFixed(2);return r.endsWith(".00")?r=r.slice(0,-3):r.endsWith("0")&&(r=r.slice(0,-1)),"1"!==r&&(n+="s"),"".concat(r," ").concat(n)},e.prototype.getTaskFilePath=function(){for(var e=0,r=g;e<r.length;e++){var i=r[e],s=o.resolve(this.cwd,i);if(t.existsSync(s))return this.isEsm?n.pathToFileURL(s).href:s}return null},e.prototype.getStartMessage=function(t,e){var n=e.isCommand?"Command":"Task";"[ ".concat(m("use "),"swig help ").concat(m("for more info")," ]");var r=t?o.basename(t):"";"[ Mode: ".concat(p(this.isEsm?"ESM":"CommonJS")," ]");var i="Version: ".concat(p(this.versionString));return"[ ".concat(n,": ").concat(p(e.value)," ][ Swigfile: ").concat(p(r)," ][ ").concat(i," ]").concat("").concat("")},e.prototype.getFinishedMessage=function(t,e){var n=Date.now()-t,r="Result: ".concat(e?h("failed"):f("success",i.GREEN)),o="Total duration: ".concat(f(this.humanizeTime(n),e?i.YELLOW:i.GREEN));return"[ ".concat(r," ][ ").concat(o," ]")},e.prototype.getCliParam=function(){var t=process.argv[2];if(!t)return new v(this.listCommand.id,!0);var e=this.commandDescriptors.find((function(e){return e.names.includes(t.toLowerCase())||e.alternateNames.includes(t.toLowerCase())}));return e?new v(e.id,!0):(t.replace(/[^a-zA-Z0-9_]/g,"")!==t&&this.failureExit("Invalid task name: ".concat(t)),new v(t,!1))},e.prototype.showTaskList=function(t,e,n){var r=t.map((function(t){return t[0]}));u("Available tasks:");for(var i=0,o=r;i<o.length;i++){var s=o[i];n&&!s.toLowerCase().includes(n.toLowerCase())||u(" ".concat(p(s)))}return u(this.getFinishedMessage(e)),this.okExit()},e.prototype.showHelpMessage=function(){u("Usage: swig <command or taskName> [options]"),u("Commands:");for(var t=0,e=this.commandDescriptors;t<e.length;t++){var n=e[t];u(" ".concat(n.names.join(", ")).concat(m(" - ".concat(n.description)))),u(" ".concat(m(n.example)))}return u("Initialize or update a swig project: npx swig-cli-init@latest"),this.okExit()},e.prototype.showVersionMessage=function(){return u(this.versionString),this.okExit()},e.prototype.getFuncByTaskName=function(t,e){var n;return null===(n=t.find((function(t){return t[0]===e})))||void 0===n?void 0:n[1]},e.prototype.main=function(){return s(this,void 0,void 0,(function(){var t,e,n,r,o,s,c,l,p,m,v,y,w;return a(this,(function(a){switch(a.label){case 0:if(t=Date.now(),e=this.getCliParam(),n=this.getTaskFilePath(),e.value===this.versionCommand.id)return[2,this.showVersionMessage()];if(u(this.getStartMessage(n?n.toString():"",e)),e.value===this.helpCommand.id)return[2,this.showHelpMessage()];if(!n)return[2,this.failureExit("Task file not found - must be one of the following: ".concat(g.join(", ")))];s=n.toString(),a.label=1;case 1:return a.trys.push([1,3,,4]),[4,import(s)];case 2:return r=a.sent(),o=Object.entries(r).filter((function(t){var e=t[1];return d(e)})),[3,4];case 3:return c=a.sent(),s&&s.endsWith(".ts")&&c instanceof Error&&c.message.includes("exports is not defined")&&console.log("".concat(f("Suggestion:",i.YELLOW),' try adjusting your tsconfig.json compilerOptions (especially the "module" setting)')),console.error(c),[2,this.failureExit("Could not import task file ".concat(s))];case 4:if(e.matches(this.listCommand))return[2,this.showTaskList(o,t)];if(e.matches(this.filterCommand))return l=process.argv[3],[2,this.showTaskList(o,t,l)];if(!(p=this.getFuncByTaskName(o,e.value)))return[2,this.failureExit("Task '".concat(e.value,"' not found. Tasks must be exported functions in your swigfile. Try 'swig list' to see available tasks."))];m=!1,a.label=5;case 5:return a.trys.push([5,7,8,9]),[4,p()];case 6:return a.sent(),[3,9];case 7:return v=a.sent(),m=!0,y="Error",w=v,Array.isArray(w)&&(1===w.length?w=w[0]:w.length>1&&(y="Errors (".concat(w.length,")"))),u(h(y)),console.error(w),[3,9];case 8:return u(this.getFinishedMessage(t,m)),m&&this.failureExit(),[7];case 9:return[2]}}))}))},e.prototype.failureExit=function(t){t&&console.error("".concat(h("Error:")," ").concat(t)),process.exit(1)},e.prototype.okExit=function(){process.exit(0)},e}();function w(){return l||(l=new y),l}function k(t){return Array.isArray(t)&&2===t.length&&"string"==typeof t[0]&&d(t[1])}exports.isFunction=d,exports.isNamedTask=k,exports.parallel=function(t){for(var e=[],n=1;n<arguments.length;n++)e[n-1]=arguments[n];var innerParallel=function(){return s(void 0,void 0,void 0,(function(){var n;return a(this,(function(r){return n=w(),[2,n.parallel.apply(n,c([t],e,!1))()]}))}))};return Object.defineProperty(innerParallel,"name",{value:"innerParallel",writable:!1}),innerParallel},exports.series=function(t){for(var e=[],n=1;n<arguments.length;n++)e[n-1]=arguments[n];var innerSeries=function(){return s(void 0,void 0,void 0,(function(){var n;return a(this,(function(r){return n=w(),[2,n.series.apply(n,c([t],e,!1))()]}))}))};return Object.defineProperty(innerSeries,"name",{value:"innerSeries",writable:!1}),innerSeries};
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguY2pzIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdXRpbHMudHMiLCIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHJvbGx1cCtwbHVnaW4tdHlwZXNjcmlwdEAxXzMxMzA2MzFkZDhiYjQ4ZDUxZGNmYTk3MDUxMmUzZDkzL25vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5lczYuanMiLCIuLi8uLi8uLi9zcmMvc2luZ2xldG9uTWFuYWdlci50cyIsIi4uLy4uLy4uL3NyYy9Td2lnLnRzIiwiLi4vLi4vLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tICdub2RlOmZzJ1xuXG5leHBvcnQgY29uc3QgdHJhY2VFbmFibGVkID0gZmFsc2VcblxuZXhwb3J0IGZ1bmN0aW9uIGxvZyhtZXNzYWdlPzogdW5rbm93biwgLi4ub3B0aW9uYWxQYXJhbXM6IHVua25vd25bXSkge1xuICBjb25zb2xlLmxvZyhtZXNzYWdlLCAuLi5vcHRpb25hbFBhcmFtcylcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuZXhwb3J0IGZ1bmN0aW9uIHRyYWNlKG1lc3NhZ2U/OiB1bmtub3duLCAuLi5vcHRpb25hbFBhcmFtczogdW5rbm93bltdKSB7XG4gIGlmICh0cmFjZUVuYWJsZWQpIHtcbiAgICBjb25zb2xlLmxvZyhtZXNzYWdlLCAuLi5vcHRpb25hbFBhcmFtcylcbiAgfVxufVxuXG5leHBvcnQgZW51bSBBbnNpQ29sb3Ige1xuICBSRVNFVCA9ICdcXHgxYlswbScsXG4gIFJFRCA9ICdcXHgxYlszMW0nLFxuICBHUkVFTiA9ICdcXHgxYlszMm0nLFxuICBZRUxMT1cgPSAnXFx4MWJbMzNtJyxcbiAgQ1lBTiA9ICdcXHgxYls5Nm0nLFxuICBHUkFZID0gJ1xceDFiWzkwbScsXG4gIFBVUlBMRSA9ICdcXHgxYlszNW0nXG59XG5cbmV4cG9ydCBjb25zdCBjb2xvciA9IChzdHI6IHN0cmluZywgY29sb3JBbnNpQ29kZTogQW5zaUNvbG9yKTogc3RyaW5nID0+IHtcbiAgcmV0dXJuIGAke2NvbG9yQW5zaUNvZGV9JHtzdHJ9JHtBbnNpQ29sb3IuUkVTRVR9YFxufVxuXG5leHBvcnQgY29uc3QgcmVkID0gKHN0cjogc3RyaW5nKSA9PiBjb2xvcihzdHIsIEFuc2lDb2xvci5SRUQpXG5leHBvcnQgY29uc3QgZ3JlZW4gPSAoc3RyOiBzdHJpbmcpID0+IGNvbG9yKHN0ciwgQW5zaUNvbG9yLkdSRUVOKVxuZXhwb3J0IGNvbnN0IGN5YW4gPSAoc3RyOiBzdHJpbmcpID0+IGNvbG9yKHN0ciwgQW5zaUNvbG9yLkNZQU4pXG5leHBvcnQgY29uc3QgZ3JheSA9IChzdHI6IHN0cmluZykgPT4gY29sb3Ioc3RyLCBBbnNpQ29sb3IuR1JBWSlcbmV4cG9ydCBjb25zdCBwdXJwbGUgPSAoc3RyOiBzdHJpbmcpID0+IGNvbG9yKHN0ciwgQW5zaUNvbG9yLlBVUlBMRSlcbmV4cG9ydCBjb25zdCB5ZWxsb3cgPSAoc3RyOiBzdHJpbmcpID0+IGNvbG9yKHN0ciwgQW5zaUNvbG9yLllFTExPVylcblxuaW50ZXJmYWNlIFNpbXBsZVZlcnNpb24ge1xuICByYXc6IHN0cmluZ1xuICBtYWpvcjogbnVtYmVyXG4gIG1pbm9yOiBudW1iZXJcbiAgcGF0Y2g6IG51bWJlclxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Tm9kZVZlcnNpb24oKTogU2ltcGxlVmVyc2lvbiB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBwYXJzZVZlcnNpb25TdHJpbmcocHJvY2Vzcy52ZXJzaW9uKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VWZXJzaW9uU3RyaW5nKHJhd1ZlcnNpb25TdHJpbmc6IHN0cmluZyB8IHVuZGVmaW5lZCk6IFNpbXBsZVZlcnNpb24gfCB1bmRlZmluZWQge1xuICBpZiAoIXJhd1ZlcnNpb25TdHJpbmcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHJhd1ZlcnNpb25TdHJpbmcgaXMgcmVxdWlyZWRgKVxuICB9XG4gIHRyeSB7XG4gICAgY29uc3QgcGFydHMgPSByYXdWZXJzaW9uU3RyaW5nLnJlcGxhY2UoL1teMC05Ll0vZywgJycpLnNwbGl0KCcuJylcbiAgICByZXR1cm4ge1xuICAgICAgcmF3OiByYXdWZXJzaW9uU3RyaW5nLFxuICAgICAgbWFqb3I6IHBhcnRzLmxlbmd0aCA+IDAgPyBwYXJzZUludChwYXJ0c1swXSwgMTApIDogMCxcbiAgICAgIG1pbm9yOiBwYXJ0cy5sZW5ndGggPiAxID8gcGFyc2VJbnQocGFydHNbMV0sIDEwKSA6IDAsXG4gICAgICBwYXRjaDogcGFydHMubGVuZ3RoID4gMiA/IHBhcnNlSW50KHBhcnRzWzJdLCAxMCkgOiAwXG4gICAgfVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0cmFjZShgdW5hYmxlIHRvIGRldGVybWluZSBOb2RlSlMgdmVyc2lvbmAsIGVycilcbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRzeFZlcnNpb24oKTogU2ltcGxlVmVyc2lvbiB8IHVuZGVmaW5lZCB7XG4gIHRyeSB7XG4gICAgY29uc3QgcGFja2FnZUpzb25QYXRoID0gJy4vbm9kZV9tb2R1bGVzL3RzeC9wYWNrYWdlLmpzb24nXG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHBhY2thZ2VKc29uUGF0aCkpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICB9XG4gICAgY29uc3QgcGFja2FnZUpzb25Db250ZW50cyA9IGZzLnJlYWRGaWxlU3luYyhwYWNrYWdlSnNvblBhdGgsIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSlcbiAgICBjb25zdCBwYWNrYWdlSnNvbiA9IEpTT04ucGFyc2UocGFja2FnZUpzb25Db250ZW50cylcbiAgICBjb25zdCB2ZXJzaW9uU3RyaW5nID0gcGFja2FnZUpzb24udmVyc2lvblxuICAgIHJldHVybiBwYXJzZVZlcnNpb25TdHJpbmcodmVyc2lvblN0cmluZylcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdHJhY2UoYGVycm9yIGdldHRpbmcgdHN4IHZlcnNpb25gLCBlcnIpXG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc05vZGVMZXNzVGhhbjE4RG90MTkobm9kZVZlcnNpb246IFNpbXBsZVZlcnNpb24pOiBib29sZWFuIHtcbiAgcmV0dXJuIG5vZGVWZXJzaW9uLm1ham9yIDwgMTggfHwgKG5vZGVWZXJzaW9uLm1ham9yID09PSAxOCAmJiBub2RlVmVyc2lvbi5taW5vciA8IDE5KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNOb2RlVmVyc2lvbkluY29tcGF0aWJsZVdpdGhUc3gobm9kZVZlcnNpb246IFNpbXBsZVZlcnNpb24pOiBib29sZWFuIHtcbiAgcmV0dXJuIG5vZGVWZXJzaW9uLm1ham9yID09PSAxOCAmJiAobm9kZVZlcnNpb24ubWlub3IgPT09IDE3IHx8IG5vZGVWZXJzaW9uLm1pbm9yID09PSAxOClcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTcGF3blJlc3VsdCB7XG4gIGNvZGU6IG51bWJlclxuICBlcnJvcj86IEVycm9yXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2dUYWJsZShkYXRhOiBzdHJpbmdbXVtdKTogdm9pZCB7XG4gIGlmIChkYXRhLmxlbmd0aCA9PT0gMCB8fCBkYXRhWzBdLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgY29uc3QgbnVtQ29sdW1ucyA9IGRhdGFbMF0ubGVuZ3RoXG4gIGNvbnN0IGNvbHVtbldpZHRoczogbnVtYmVyW10gPSBbXVxuICBmb3IgKGxldCBpID0gMDsgaSA8IG51bUNvbHVtbnM7IGkrKykge1xuICAgIGNvbHVtbldpZHRoc1tpXSA9IE1hdGgubWF4KC4uLmRhdGEubWFwKHJvdyA9PiByb3dbaV0/Lmxlbmd0aCB8fCAwKSlcbiAgfVxuXG4gIGNvbnN0IGxpbmVTZXBhcmF0b3IgPSAnICcgKyBjb2x1bW5XaWR0aHMubWFwKHdpZHRoID0+ICctJy5yZXBlYXQod2lkdGgpKS5qb2luKCcgKyAnKVxuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHBhZGRlZFJvd0FycmF5ID0gZGF0YVtpXS5tYXAoKGNlbGwsIGNvbElkeCkgPT4gY2VsbC5wYWRFbmQoY29sdW1uV2lkdGhzW2NvbElkeF0sICcgJykpXG4gICAgbG9nKCcgJyArIHBhZGRlZFJvd0FycmF5LmpvaW4oJyB8ICcpKVxuICAgIGlmIChpID09PSAwKSBsb2cobGluZVNlcGFyYXRvcilcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgaXNGdW5jdGlvbiA9ICh4OiB1bmtub3duKTogYm9vbGVhbiA9PiB7XG4gIGlmICh0eXBlb2YgeCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIGNvbnN0IGlzQ2xhc3MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHgsICdwcm90b3R5cGUnKT8ud3JpdGFibGUgPT09IGZhbHNlXG4gIHJldHVybiAhaXNDbGFzc1xufVxuIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlLCBTdXBwcmVzc2VkRXJyb3IsIFN5bWJvbCAqL1xyXG5cclxudmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbihkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xyXG4gICAgaWYgKHR5cGVvZiBiICE9PSBcImZ1bmN0aW9uXCIgJiYgYiAhPT0gbnVsbClcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2xhc3MgZXh0ZW5kcyB2YWx1ZSBcIiArIFN0cmluZyhiKSArIFwiIGlzIG5vdCBhIGNvbnN0cnVjdG9yIG9yIG51bGxcIik7XHJcbiAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc3QocywgZSkge1xyXG4gICAgdmFyIHQgPSB7fTtcclxuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDAgJiYgT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHMsIHBbaV0pKVxyXG4gICAgICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XHJcbiAgICAgICAgfVxyXG4gICAgcmV0dXJuIHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2RlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcclxuICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHIpLCByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wYXJhbShwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19lc0RlY29yYXRlKGN0b3IsIGRlc2NyaXB0b3JJbiwgZGVjb3JhdG9ycywgY29udGV4dEluLCBpbml0aWFsaXplcnMsIGV4dHJhSW5pdGlhbGl6ZXJzKSB7XHJcbiAgICBmdW5jdGlvbiBhY2NlcHQoZikgeyBpZiAoZiAhPT0gdm9pZCAwICYmIHR5cGVvZiBmICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJGdW5jdGlvbiBleHBlY3RlZFwiKTsgcmV0dXJuIGY7IH1cclxuICAgIHZhciBraW5kID0gY29udGV4dEluLmtpbmQsIGtleSA9IGtpbmQgPT09IFwiZ2V0dGVyXCIgPyBcImdldFwiIDoga2luZCA9PT0gXCJzZXR0ZXJcIiA/IFwic2V0XCIgOiBcInZhbHVlXCI7XHJcbiAgICB2YXIgdGFyZ2V0ID0gIWRlc2NyaXB0b3JJbiAmJiBjdG9yID8gY29udGV4dEluW1wic3RhdGljXCJdID8gY3RvciA6IGN0b3IucHJvdG90eXBlIDogbnVsbDtcclxuICAgIHZhciBkZXNjcmlwdG9yID0gZGVzY3JpcHRvckluIHx8ICh0YXJnZXQgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgY29udGV4dEluLm5hbWUpIDoge30pO1xyXG4gICAgdmFyIF8sIGRvbmUgPSBmYWxzZTtcclxuICAgIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgdmFyIGNvbnRleHQgPSB7fTtcclxuICAgICAgICBmb3IgKHZhciBwIGluIGNvbnRleHRJbikgY29udGV4dFtwXSA9IHAgPT09IFwiYWNjZXNzXCIgPyB7fSA6IGNvbnRleHRJbltwXTtcclxuICAgICAgICBmb3IgKHZhciBwIGluIGNvbnRleHRJbi5hY2Nlc3MpIGNvbnRleHQuYWNjZXNzW3BdID0gY29udGV4dEluLmFjY2Vzc1twXTtcclxuICAgICAgICBjb250ZXh0LmFkZEluaXRpYWxpemVyID0gZnVuY3Rpb24gKGYpIHsgaWYgKGRvbmUpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgYWRkIGluaXRpYWxpemVycyBhZnRlciBkZWNvcmF0aW9uIGhhcyBjb21wbGV0ZWRcIik7IGV4dHJhSW5pdGlhbGl6ZXJzLnB1c2goYWNjZXB0KGYgfHwgbnVsbCkpOyB9O1xyXG4gICAgICAgIHZhciByZXN1bHQgPSAoMCwgZGVjb3JhdG9yc1tpXSkoa2luZCA9PT0gXCJhY2Nlc3NvclwiID8geyBnZXQ6IGRlc2NyaXB0b3IuZ2V0LCBzZXQ6IGRlc2NyaXB0b3Iuc2V0IH0gOiBkZXNjcmlwdG9yW2tleV0sIGNvbnRleHQpO1xyXG4gICAgICAgIGlmIChraW5kID09PSBcImFjY2Vzc29yXCIpIHtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gdm9pZCAwKSBjb250aW51ZTtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gbnVsbCB8fCB0eXBlb2YgcmVzdWx0ICE9PSBcIm9iamVjdFwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IGV4cGVjdGVkXCIpO1xyXG4gICAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuZ2V0KSkgZGVzY3JpcHRvci5nZXQgPSBfO1xyXG4gICAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuc2V0KSkgZGVzY3JpcHRvci5zZXQgPSBfO1xyXG4gICAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuaW5pdCkpIGluaXRpYWxpemVycy51bnNoaWZ0KF8pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChfID0gYWNjZXB0KHJlc3VsdCkpIHtcclxuICAgICAgICAgICAgaWYgKGtpbmQgPT09IFwiZmllbGRcIikgaW5pdGlhbGl6ZXJzLnVuc2hpZnQoXyk7XHJcbiAgICAgICAgICAgIGVsc2UgZGVzY3JpcHRvcltrZXldID0gXztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAodGFyZ2V0KSBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSwgZGVzY3JpcHRvcik7XHJcbiAgICBkb25lID0gdHJ1ZTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3J1bkluaXRpYWxpemVycyh0aGlzQXJnLCBpbml0aWFsaXplcnMsIHZhbHVlKSB7XHJcbiAgICB2YXIgdXNlVmFsdWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMjtcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5pdGlhbGl6ZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgdmFsdWUgPSB1c2VWYWx1ZSA/IGluaXRpYWxpemVyc1tpXS5jYWxsKHRoaXNBcmcsIHZhbHVlKSA6IGluaXRpYWxpemVyc1tpXS5jYWxsKHRoaXNBcmcpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHVzZVZhbHVlID8gdmFsdWUgOiB2b2lkIDA7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wcm9wS2V5KHgpIHtcclxuICAgIHJldHVybiB0eXBlb2YgeCA9PT0gXCJzeW1ib2xcIiA/IHggOiBcIlwiLmNvbmNhdCh4KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NldEZ1bmN0aW9uTmFtZShmLCBuYW1lLCBwcmVmaXgpIHtcclxuICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gXCJzeW1ib2xcIikgbmFtZSA9IG5hbWUuZGVzY3JpcHRpb24gPyBcIltcIi5jb25jYXQobmFtZS5kZXNjcmlwdGlvbiwgXCJdXCIpIDogXCJcIjtcclxuICAgIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoZiwgXCJuYW1lXCIsIHsgY29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogcHJlZml4ID8gXCJcIi5jb25jYXQocHJlZml4LCBcIiBcIiwgbmFtZSkgOiBuYW1lIH0pO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH1cclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChnICYmIChnID0gMCwgb3BbMF0gJiYgKF8gPSAwKSksIF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2NyZWF0ZUJpbmRpbmcgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xyXG4gICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcclxuICAgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xyXG4gICAgfVxyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcclxufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBvW2syXSA9IG1ba107XHJcbn0pO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheXMoKSB7XHJcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcclxuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgcltrXSA9IGFbal07XHJcbiAgICByZXR1cm4gcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20sIHBhY2spIHtcclxuICAgIGlmIChwYWNrIHx8IGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIGZvciAodmFyIGkgPSAwLCBsID0gZnJvbS5sZW5ndGgsIGFyOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKGFyIHx8ICEoaSBpbiBmcm9tKSkge1xyXG4gICAgICAgICAgICBpZiAoIWFyKSBhciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20sIDAsIGkpO1xyXG4gICAgICAgICAgICBhcltpXSA9IGZyb21baV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvLmNvbmNhdChhciB8fCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tKSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlmIChnW25dKSBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiByZXN1bWUobiwgdikgeyB0cnkgeyBzdGVwKGdbbl0odikpOyB9IGNhdGNoIChlKSB7IHNldHRsZShxWzBdWzNdLCBlKTsgfSB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKHIpIHsgci52YWx1ZSBpbnN0YW5jZW9mIF9fYXdhaXQgPyBQcm9taXNlLnJlc29sdmUoci52YWx1ZS52KS50aGVuKGZ1bGZpbGwsIHJlamVjdCkgOiBzZXR0bGUocVswXVsyXSwgcik7IH1cclxuICAgIGZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHsgcmVzdW1lKFwibmV4dFwiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHJlamVjdCh2YWx1ZSkgeyByZXN1bWUoXCJ0aHJvd1wiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShmLCB2KSB7IGlmIChmKHYpLCBxLnNoaWZ0KCksIHEubGVuZ3RoKSByZXN1bWUocVswXVswXSwgcVswXVsxXSk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNEZWxlZ2F0b3Iobykge1xyXG4gICAgdmFyIGksIHA7XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIsIGZ1bmN0aW9uIChlKSB7IHRocm93IGU7IH0pLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuLCBmKSB7IGlbbl0gPSBvW25dID8gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIChwID0gIXApID8geyB2YWx1ZTogX19hd2FpdChvW25dKHYpKSwgZG9uZTogZmFsc2UgfSA6IGYgPyBmKHYpIDogdjsgfSA6IGY7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNWYWx1ZXMobykge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICByZXR1cm4gbSA/IG0uY2FsbChvKSA6IChvID0gdHlwZW9mIF9fdmFsdWVzID09PSBcImZ1bmN0aW9uXCIgPyBfX3ZhbHVlcyhvKSA6IG9bU3ltYm9sLml0ZXJhdG9yXSgpLCBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaSk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xyXG4gICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgIHJldHVybiBjb29rZWQ7XHJcbn07XHJcblxyXG52YXIgX19zZXRNb2R1bGVEZWZhdWx0ID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgXCJkZWZhdWx0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHYgfSk7XHJcbn0pIDogZnVuY3Rpb24obywgdikge1xyXG4gICAgb1tcImRlZmF1bHRcIl0gPSB2O1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoayAhPT0gXCJkZWZhdWx0XCIgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwgayk7XHJcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4oc3RhdGUsIHJlY2VpdmVyKSB7XHJcbiAgICBpZiAocmVjZWl2ZXIgPT09IG51bGwgfHwgKHR5cGVvZiByZWNlaXZlciAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcmVjZWl2ZXIgIT09IFwiZnVuY3Rpb25cIikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgdXNlICdpbicgb3BlcmF0b3Igb24gbm9uLW9iamVjdFwiKTtcclxuICAgIHJldHVybiB0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyID09PSBzdGF0ZSA6IHN0YXRlLmhhcyhyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZShlbnYsIHZhbHVlLCBhc3luYykge1xyXG4gICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB2b2lkIDApIHtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IGV4cGVjdGVkLlwiKTtcclxuICAgICAgICB2YXIgZGlzcG9zZTtcclxuICAgICAgICBpZiAoYXN5bmMpIHtcclxuICAgICAgICAgICAgaWYgKCFTeW1ib2wuYXN5bmNEaXNwb3NlKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jRGlzcG9zZSBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICAgICAgICAgIGRpc3Bvc2UgPSB2YWx1ZVtTeW1ib2wuYXN5bmNEaXNwb3NlXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGRpc3Bvc2UgPT09IHZvaWQgMCkge1xyXG4gICAgICAgICAgICBpZiAoIVN5bWJvbC5kaXNwb3NlKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmRpc3Bvc2UgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgICAgICAgICBkaXNwb3NlID0gdmFsdWVbU3ltYm9sLmRpc3Bvc2VdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodHlwZW9mIGRpc3Bvc2UgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBub3QgZGlzcG9zYWJsZS5cIik7XHJcbiAgICAgICAgZW52LnN0YWNrLnB1c2goeyB2YWx1ZTogdmFsdWUsIGRpc3Bvc2U6IGRpc3Bvc2UsIGFzeW5jOiBhc3luYyB9KTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGFzeW5jKSB7XHJcbiAgICAgICAgZW52LnN0YWNrLnB1c2goeyBhc3luYzogdHJ1ZSB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiB2YWx1ZTtcclxufVxyXG5cclxudmFyIF9TdXBwcmVzc2VkRXJyb3IgPSB0eXBlb2YgU3VwcHJlc3NlZEVycm9yID09PSBcImZ1bmN0aW9uXCIgPyBTdXBwcmVzc2VkRXJyb3IgOiBmdW5jdGlvbiAoZXJyb3IsIHN1cHByZXNzZWQsIG1lc3NhZ2UpIHtcclxuICAgIHZhciBlID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xyXG4gICAgcmV0dXJuIGUubmFtZSA9IFwiU3VwcHJlc3NlZEVycm9yXCIsIGUuZXJyb3IgPSBlcnJvciwgZS5zdXBwcmVzc2VkID0gc3VwcHJlc3NlZCwgZTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2Rpc3Bvc2VSZXNvdXJjZXMoZW52KSB7XHJcbiAgICBmdW5jdGlvbiBmYWlsKGUpIHtcclxuICAgICAgICBlbnYuZXJyb3IgPSBlbnYuaGFzRXJyb3IgPyBuZXcgX1N1cHByZXNzZWRFcnJvcihlLCBlbnYuZXJyb3IsIFwiQW4gZXJyb3Igd2FzIHN1cHByZXNzZWQgZHVyaW5nIGRpc3Bvc2FsLlwiKSA6IGU7XHJcbiAgICAgICAgZW52Lmhhc0Vycm9yID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIG5leHQoKSB7XHJcbiAgICAgICAgd2hpbGUgKGVudi5zdGFjay5sZW5ndGgpIHtcclxuICAgICAgICAgICAgdmFyIHJlYyA9IGVudi5zdGFjay5wb3AoKTtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSByZWMuZGlzcG9zZSAmJiByZWMuZGlzcG9zZS5jYWxsKHJlYy52YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVjLmFzeW5jKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCkudGhlbihuZXh0LCBmdW5jdGlvbihlKSB7IGZhaWwoZSk7IHJldHVybiBuZXh0KCk7IH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBmYWlsKGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChlbnYuaGFzRXJyb3IpIHRocm93IGVudi5lcnJvcjtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXh0KCk7XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIF9fZXh0ZW5kczogX19leHRlbmRzLFxyXG4gICAgX19hc3NpZ246IF9fYXNzaWduLFxyXG4gICAgX19yZXN0OiBfX3Jlc3QsXHJcbiAgICBfX2RlY29yYXRlOiBfX2RlY29yYXRlLFxyXG4gICAgX19wYXJhbTogX19wYXJhbSxcclxuICAgIF9fbWV0YWRhdGE6IF9fbWV0YWRhdGEsXHJcbiAgICBfX2F3YWl0ZXI6IF9fYXdhaXRlcixcclxuICAgIF9fZ2VuZXJhdG9yOiBfX2dlbmVyYXRvcixcclxuICAgIF9fY3JlYXRlQmluZGluZzogX19jcmVhdGVCaW5kaW5nLFxyXG4gICAgX19leHBvcnRTdGFyOiBfX2V4cG9ydFN0YXIsXHJcbiAgICBfX3ZhbHVlczogX192YWx1ZXMsXHJcbiAgICBfX3JlYWQ6IF9fcmVhZCxcclxuICAgIF9fc3ByZWFkOiBfX3NwcmVhZCxcclxuICAgIF9fc3ByZWFkQXJyYXlzOiBfX3NwcmVhZEFycmF5cyxcclxuICAgIF9fc3ByZWFkQXJyYXk6IF9fc3ByZWFkQXJyYXksXHJcbiAgICBfX2F3YWl0OiBfX2F3YWl0LFxyXG4gICAgX19hc3luY0dlbmVyYXRvcjogX19hc3luY0dlbmVyYXRvcixcclxuICAgIF9fYXN5bmNEZWxlZ2F0b3I6IF9fYXN5bmNEZWxlZ2F0b3IsXHJcbiAgICBfX2FzeW5jVmFsdWVzOiBfX2FzeW5jVmFsdWVzLFxyXG4gICAgX19tYWtlVGVtcGxhdGVPYmplY3Q6IF9fbWFrZVRlbXBsYXRlT2JqZWN0LFxyXG4gICAgX19pbXBvcnRTdGFyOiBfX2ltcG9ydFN0YXIsXHJcbiAgICBfX2ltcG9ydERlZmF1bHQ6IF9faW1wb3J0RGVmYXVsdCxcclxuICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQ6IF9fY2xhc3NQcml2YXRlRmllbGRHZXQsXHJcbiAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0OiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0LFxyXG4gICAgX19jbGFzc1ByaXZhdGVGaWVsZEluOiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4sXHJcbiAgICBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZTogX19hZGREaXNwb3NhYmxlUmVzb3VyY2UsXHJcbiAgICBfX2Rpc3Bvc2VSZXNvdXJjZXM6IF9fZGlzcG9zZVJlc291cmNlcyxcclxufTtcclxuIiwiaW1wb3J0IFN3aWcgZnJvbSAnLi9Td2lnLmpzJ1xuXG5sZXQgaW5zdGFuY2U6IFN3aWdcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFN3aWdJbnN0YW5jZSgpIHtcbiAgaWYgKCFpbnN0YW5jZSkge1xuICAgIGluc3RhbmNlID0gbmV3IFN3aWcoKVxuICB9XG4gIHJldHVybiBpbnN0YW5jZVxufVxuIiwiaW1wb3J0IGZzIGZyb20gJ25vZGU6ZnMnXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ25vZGU6cGF0aCdcbmltcG9ydCB7IHBhdGhUb0ZpbGVVUkwgfSBmcm9tICdub2RlOnVybCdcbmltcG9ydCB7IFRhc2ssIFRhc2tPck5hbWVkVGFzaywgaXNOYW1lZFRhc2sgfSBmcm9tICcuL2luZGV4LmpzJ1xuaW1wb3J0IHsgQW5zaUNvbG9yLCBjb2xvciwgY3lhbiwgZ3JheSwgZ3JlZW4sIGlzRnVuY3Rpb24sIGxvZywgcHVycGxlLCByZWQsIHllbGxvdyB9IGZyb20gJy4vdXRpbHMuanMnXG5cbmNvbnN0IHNob3dNb2RlSW5TdGFydE1lc3NhZ2UgPSBmYWxzZVxuY29uc3Qgc2hvd0hlbHBJblN0YXJ0TWVzc2FnZSA9IGZhbHNlXG5cbmludGVyZmFjZSBMb2dOYW1lQW5kVGFzayB7IGxvZ05hbWU6IHN0cmluZywgdGFzazogVGFzayB9XG5cbmludGVyZmFjZSBDb21tYW5kRGVzY3JpcHRvciB7IGlkOiBzdHJpbmcsIG5hbWVzOiBzdHJpbmdbXSwgYWx0ZXJuYXRlTmFtZXM6IHN0cmluZ1tdLCBkZXNjcmlwdGlvbjogc3RyaW5nLCBleGFtcGxlOiBzdHJpbmcgfVxuXG50eXBlIFRhc2tzTWFwID0gW3N0cmluZywgKCgpID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+KV1bXVxuXG5leHBvcnQgY29uc3QgcG9zc2libGVUYXNrRmlsZU5hbWVzID0gWydzd2lnZmlsZS5janMnLCAnc3dpZ2ZpbGUubWpzJywgJ3N3aWdmaWxlLmpzJywgJ3N3aWdmaWxlLnRzJ11cblxuY2xhc3MgQ2xpUGFyYW0ge1xuICB2YWx1ZTogc3RyaW5nXG4gIGlzQ29tbWFuZDogYm9vbGVhblxuXG4gIGNvbnN0cnVjdG9yKHZhbHVlOiBzdHJpbmcsIGlzQ29tbWFuZDogYm9vbGVhbikge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZVxuICAgIHRoaXMuaXNDb21tYW5kID0gaXNDb21tYW5kXG4gIH1cblxuICBtYXRjaGVzOiAoY29tbWFuZERlc2NyaXB0b3I6IENvbW1hbmREZXNjcmlwdG9yKSA9PiBib29sZWFuID0gKGNvbW1hbmREZXNjcmlwdG9yOiBDb21tYW5kRGVzY3JpcHRvcikgPT4ge1xuICAgIHJldHVybiB0aGlzLnZhbHVlID09PSBjb21tYW5kRGVzY3JpcHRvci5pZFxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN3aWcge1xuICBpc0NvbW1vbkpTID0gdHlwZW9mIHJlcXVpcmUgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIG1vZHVsZS5leHBvcnRzXG4gIGlzRXNtID0gIXRoaXMuaXNDb21tb25KU1xuICBwcml2YXRlIHZlcnNpb25TdHJpbmc6IHN0cmluZyA9ICdfX1ZFUlNJT05fXycgLy8gVGhpcyBpcyByZXBsYWNlZCBpbiB0aGUgYnVpbGQgc2NyaXB0XG4gIHByaXZhdGUgY3dkID0gcHJvY2Vzcy5jd2QoKVxuICBwcml2YXRlIHNlcmllc0NvdW50ZXIgPSAxXG4gIHByaXZhdGUgcGFyYWxsZWxDb3VudGVyID0gMVxuICBwcml2YXRlIGxpc3RDb21tYW5kID0geyBpZDogJ2xpc3QnLCBuYW1lczogWydsaXN0JywgJ2xzJywgJ2wnXSwgYWx0ZXJuYXRlTmFtZXM6IFsnLWwnLCAnLS1saXN0J10sIGRlc2NyaXB0aW9uOiAnTGlzdCBhdmFpbGFibGUgdGFza3MgKGRlZmF1bHQpJywgZXhhbXBsZTogJ3N3aWcgbGlzdCcgfVxuICBwcml2YXRlIGhlbHBDb21tYW5kID0geyBpZDogJ2hlbHAnLCBuYW1lczogWydoZWxwJywgJ2gnXSwgYWx0ZXJuYXRlTmFtZXM6IFsnLWgnLCAnLS1oZWxwJ10sIGRlc2NyaXB0aW9uOiAnU2hvdyBoZWxwIG1lc3NhZ2UnLCBleGFtcGxlOiAnc3dpZyBoZWxwJyB9XG4gIHByaXZhdGUgdmVyc2lvbkNvbW1hbmQgPSB7IGlkOiAndmVyc2lvbicsIG5hbWVzOiBbJ3ZlcnNpb24nLCAndiddLCBhbHRlcm5hdGVOYW1lczogWyctdicsICctLXZlcnNpb24nXSwgZGVzY3JpcHRpb246ICdQcmludCB2ZXJzaW9uIG51bWJlcicsIGV4YW1wbGU6ICdzd2lnIHZlcnNpb24nIH1cbiAgcHJpdmF0ZSBmaWx0ZXJDb21tYW5kID0geyBpZDogJ2ZpbHRlcicsIG5hbWVzOiBbJ2ZpbHRlcicsICdmJ10sIGFsdGVybmF0ZU5hbWVzOiBbJy1mJywgJy0tZmlsdGVyJ10sIGRlc2NyaXB0aW9uOiAnRmlsdGVyIGFuZCBsaXN0IHRhc2tzIGJ5IG5hbWUnLCBleGFtcGxlOiAnc3dpZyBmaWx0ZXIgcGF0dGVybicgfVxuICBwcml2YXRlIGNvbW1hbmREZXNjcmlwdG9yczogQ29tbWFuZERlc2NyaXB0b3JbXSA9IFtcbiAgICB7IGlkOiAndGFzaycsIG5hbWVzOiBbJzx0YXNrTmFtZT4nXSwgYWx0ZXJuYXRlTmFtZXM6IFtdLCBkZXNjcmlwdGlvbjogJ1J1biBhIFwidGFza1wiLCB3aGljaCBpcyBhbiBhc3luYyBmdW5jdGlvbiBleHBvcnRlZCBmcm9tIHlvdXIgc3dpZ2ZpbGUnLCBleGFtcGxlOiAnc3dpZyB0YXNrTmFtZScgfSxcbiAgICB0aGlzLmxpc3RDb21tYW5kLFxuICAgIHRoaXMuaGVscENvbW1hbmQsXG4gICAgdGhpcy52ZXJzaW9uQ29tbWFuZCxcbiAgICB0aGlzLmZpbHRlckNvbW1hbmRcbiAgXVxuXG4gIGNvbnN0cnVjdG9yKCkgeyB9XG5cbiAgLy8gR2V0IGFuIGluc3RhbmNlIHdpdGggc2luZ2xldG9uTWFuYWdlci50cyBhbmQgdGhlbiBydW4gdGhpcyBtZXRob2QgdG8gc3RhcnQgdGhlIENMSS5cbiAgYXN5bmMgcnVuTWFpbkFzeW5jKCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLm1haW4oKVxuICAgICAgdGhpcy5va0V4aXQoKVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcihlcnIpXG4gICAgICB0aGlzLmZhaWx1cmVFeGl0KCdBbiB1bmV4cGVjdGVkIGVycm9yIG9jY3VycmVkJylcbiAgICB9XG4gIH1cblxuICAvLyBEb24ndCBjYWxsIHRoaXMgZGlyZWN0bHkgLSBzZWUgbW9kdWxlIGV4cG9ydHMgaW4gc3JjL2luZGV4LnRzLiBBbHNvIHNlZSBUYXNrT3JOYW1lZFRhc2sgZm9yIG1vcmUgaW5mby5cbiAgc2VyaWVzID0gKGZpcnN0OiBUYXNrT3JOYW1lZFRhc2ssIC4uLnJlc3Q6IFRhc2tPck5hbWVkVGFza1tdKTogVGFzayA9PiB7XG4gICAgY29uc3QgaW5uZXJTZXJpZXMgPSBhc3luYyAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IHRhc2sgb2YgW2ZpcnN0LCAuLi5yZXN0XSkge1xuICAgICAgICBhd2FpdCB0aGlzLnJ1blRhc2sodGhpcy5nZXRMb2dOYW1lQW5kVGFzayh0YXNrKSlcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGlubmVyU2VyaWVzXG4gIH1cblxuICAvLyBEb24ndCBjYWxsIHRoaXMgZGlyZWN0bHkgLSBzZWUgbW9kdWxlIGV4cG9ydHMgaW4gc3JjL2luZGV4LnRzLiBBbHNvIHNlZSBUYXNrT3JOYW1lZFRhc2sgZm9yIG1vcmUgaW5mby5cbiAgcGFyYWxsZWwgPSAoLi4udGFza3M6IFRhc2tPck5hbWVkVGFza1tdKTogVGFzayA9PiB7XG4gICAgY29uc3QgaW5uZXJQYXJhbGxlbCA9IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHByb21pc2VzOiBQcm9taXNlPHZvaWQ+W10gPSB0YXNrcy5tYXAodGFzayA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnJ1blRhc2sodGhpcy5nZXRMb2dOYW1lQW5kVGFzayh0YXNrKSlcbiAgICAgIH0pXG4gICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKHByb21pc2VzKVxuICAgICAgY29uc3QgcmVqZWN0ZWQgPSByZXN1bHRzLmZpbHRlcihyZXN1bHQgPT4gcmVzdWx0LnN0YXR1cyA9PT0gJ3JlamVjdGVkJykgYXMgUHJvbWlzZVJlamVjdGVkUmVzdWx0W11cbiAgICAgIGlmIChyZWplY3RlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGVycm9ycyA9IHJlamVjdGVkLm1hcCgocmVzdWx0KSA9PiByZXN1bHQucmVhc29uKVxuICAgICAgICB0aHJvdyBlcnJvcnNcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGlubmVyUGFyYWxsZWxcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcnVuVGFzayhsb2dOYW1lQW5kVGFzazogTG9nTmFtZUFuZFRhc2spIHtcbiAgICBjb25zdCBzdGFydFRpbWVzdGFtcCA9IERhdGUubm93KClcbiAgICB0aGlzLmxvZ0Zvcm1hdHRlZFN0YXJ0TWVzc2FnZShsb2dOYW1lQW5kVGFzay5sb2dOYW1lLCBzdGFydFRpbWVzdGFtcClcbiAgICBhd2FpdCBsb2dOYW1lQW5kVGFzay50YXNrKClcbiAgICBjb25zdCBlbmRUaW1lc3RhbXAgPSBEYXRlLm5vdygpXG4gICAgY29uc3QgZHVyYXRpb24gPSBlbmRUaW1lc3RhbXAgLSBzdGFydFRpbWVzdGFtcFxuICAgIHRoaXMubG9nRm9ybWF0dGVkRW5kTWVzc2FnZShsb2dOYW1lQW5kVGFzay5sb2dOYW1lLCBlbmRUaW1lc3RhbXAsIGR1cmF0aW9uKVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRMb2dOYW1lQW5kVGFzayh0YXNrT3JOYW1lZFRhc2s6IFRhc2tPck5hbWVkVGFzayk6IExvZ05hbWVBbmRUYXNrIHtcbiAgICB0aGlzLnRocm93SWZOb3RUYXNrT3JOYW1lZFRhc2sodGFza09yTmFtZWRUYXNrKVxuXG4gICAgaWYgKGlzTmFtZWRUYXNrKHRhc2tPck5hbWVkVGFzaykpIHtcbiAgICAgIHJldHVybiB7IGxvZ05hbWU6IHRhc2tPck5hbWVkVGFza1swXSwgdGFzazogdGFza09yTmFtZWRUYXNrWzFdIH1cbiAgICB9XG5cbiAgICBsZXQgbmFtZSA9IHRhc2tPck5hbWVkVGFzay5uYW1lXG5cbiAgICBpZiAobmFtZSA9PT0gJ2lubmVyU2VyaWVzJykge1xuICAgICAgbmFtZSA9IGBuZXN0ZWRfc2VyaWVzXyR7dGhpcy5zZXJpZXNDb3VudGVyLnRvU3RyaW5nKCl9YFxuICAgICAgdGhpcy5zZXJpZXNDb3VudGVyKytcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdpbm5lclBhcmFsbGVsJykge1xuICAgICAgbmFtZSA9IGBuZXN0ZWRfcGFyYWxsZWxfJHt0aGlzLnBhcmFsbGVsQ291bnRlci50b1N0cmluZygpfWBcbiAgICAgIHRoaXMucGFyYWxsZWxDb3VudGVyKytcbiAgICB9IGVsc2UgaWYgKCFuYW1lKSB7XG4gICAgICBuYW1lID0gJ2Fub255bW91cydcbiAgICB9XG5cbiAgICByZXR1cm4geyBsb2dOYW1lOiBuYW1lLCB0YXNrOiB0YXNrT3JOYW1lZFRhc2sgfVxuICB9XG5cbiAgcHJpdmF0ZSB0aHJvd0lmTm90VGFza09yTmFtZWRUYXNrKHRhc2tPck5hbWVkVGFzazogVGFza09yTmFtZWRUYXNrKSB7XG4gICAgaWYgKCFpc05hbWVkVGFzayh0YXNrT3JOYW1lZFRhc2spICYmICFpc0Z1bmN0aW9uKHRhc2tPck5hbWVkVGFzaykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQSBwYXJhbSBwYXNzZWQgdG8gXCJzZXJpZXNcIiBvciBcInBhcmFsbGVsXCIgd2FzIG5vdCBhIFRhc2sgKGZ1bmN0aW9uKSBvciBhIE5hbWVkVGFzayAoW3N0cmluZyxmdW5jdGlvbl0gdHVwbGUpOiAke3Rhc2tPck5hbWVkVGFza31gKVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0VGltZXN0YW1wUHJlZml4KGRhdGU6IERhdGUpIHtcbiAgICBjb25zdCBob3VycyA9IFN0cmluZyhkYXRlLmdldEhvdXJzKCkpLnBhZFN0YXJ0KDIsICcwJylcbiAgICBjb25zdCBtaW51dGVzID0gU3RyaW5nKGRhdGUuZ2V0TWludXRlcygpKS5wYWRTdGFydCgyLCAnMCcpXG4gICAgY29uc3Qgc2Vjb25kcyA9IFN0cmluZyhkYXRlLmdldFNlY29uZHMoKSkucGFkU3RhcnQoMiwgJzAnKVxuICAgIGNvbnN0IG1pbGxpc2Vjb25kcyA9IFN0cmluZyhkYXRlLmdldE1pbGxpc2Vjb25kcygpKS5wYWRTdGFydCgzLCAnMCcpXG4gICAgcmV0dXJuIGdyYXkoYFske2hvdXJzfToke21pbnV0ZXN9OiR7c2Vjb25kc30uJHttaWxsaXNlY29uZHN9XWApXG4gIH1cblxuICBwcml2YXRlIGxvZ0Zvcm1hdHRlZFN0YXJ0TWVzc2FnZSh0YXNrTmFtZTogc3RyaW5nLCBzdGFydFRpbWVzdGFtcDogbnVtYmVyKSB7XG4gICAgY29uc3QgcHJlZml4ID0gYCR7dGhpcy5nZXRUaW1lc3RhbXBQcmVmaXgobmV3IERhdGUoc3RhcnRUaW1lc3RhbXApKX0gYFxuICAgIGxvZyhgJHtwcmVmaXh9U3RhcnRpbmcg8J+agCAke2N5YW4odGFza05hbWUpfWApXG4gIH1cblxuICBwcml2YXRlIGxvZ0Zvcm1hdHRlZEVuZE1lc3NhZ2UodGFza05hbWU6IHN0cmluZywgZW5kVGltZXN0YW1wOiBudW1iZXIsIGR1cmF0aW9uOiBudW1iZXIpIHtcbiAgICBjb25zdCBwcmVmaXggPSBgJHt0aGlzLmdldFRpbWVzdGFtcFByZWZpeChuZXcgRGF0ZShlbmRUaW1lc3RhbXApKX0gYFxuICAgIGxvZyhgJHtwcmVmaXh9RmluaXNoZWQg4pyFICR7Y3lhbih0YXNrTmFtZSl9IGFmdGVyICR7cHVycGxlKHRoaXMuaHVtYW5pemVUaW1lKGR1cmF0aW9uKSl9YClcbiAgfVxuXG4gIHByaXZhdGUgaHVtYW5pemVUaW1lKG1pbGxpc2Vjb25kcz