From a6567c8e6f297e23063b6efc6751a3d5bfafa17c Mon Sep 17 00:00:00 2001 From: Alexey Velikiy Date: Tue, 26 Jun 2018 02:13:17 +0300 Subject: [PATCH] Module for messaging on node.js side #30 --- server/dist/server.js | 143 ++++++++++++++++----- server/src/index.ts | 6 +- server/src/services/analytics.ts | 47 ++----- server/src/services/analyticsConnection.ts | 41 ++++++ 4 files changed, 167 insertions(+), 70 deletions(-) create mode 100644 server/src/services/analyticsConnection.ts diff --git a/server/dist/server.js b/server/dist/server.js index 36668c3..119357d 100644 --- a/server/dist/server.js +++ b/server/dist/server.js @@ -98,6 +98,10 @@ Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(/*! path */ "path"); +const fs = __webpack_require__(/*! fs */ "fs"); +const json_1 = __webpack_require__(/*! ./services/json */ "./src/services/json.ts"); +let configFile = path.join(__dirname, '../../config.json'); +let configExists = fs.existsSync(configFile); exports.ANALYTICS_PATH = path.join(__dirname, '../../analytics'); exports.DATA_PATH = path.join(__dirname, '../../data'); exports.DATASETS_PATH = path.join(exports.DATA_PATH, 'datasets'); @@ -105,6 +109,22 @@ exports.ANOMALIES_PATH = path.join(exports.DATA_PATH, 'anomalies'); exports.MODELS_PATH = path.join(exports.DATA_PATH, 'models'); exports.METRICS_PATH = path.join(exports.DATA_PATH, 'metrics'); exports.SEGMENTS_PATH = path.join(exports.DATA_PATH, 'segments'); +exports.HASTIC_PORT = getConfigField('HASTIC_PORT', '8000'); +function getConfigField(field, defaultVal) { + let val = defaultVal; + if (process.env[field] !== undefined) { + val = process.env[field]; + } else if (configExists) { + let config = json_1.getJsonDataSync(configFile); + if (config[field] !== undefined) { + val = config[field]; + } + } + if (val === undefined) { + throw new Error(`Please configure ${field}`); + } + return val; +} /***/ }), @@ -150,9 +170,9 @@ const anomalies_1 = __webpack_require__(/*! ./routes/anomalies */ "./src/routes/ const segments_1 = __webpack_require__(/*! ./routes/segments */ "./src/routes/segments.ts"); const alerts_1 = __webpack_require__(/*! ./routes/alerts */ "./src/routes/alerts.ts"); const data_1 = __webpack_require__(/*! ./services/data */ "./src/services/data.ts"); +const config_1 = __webpack_require__(/*! ./config */ "./src/config.ts"); data_1.checkDataFolders(); var app = new Koa(); -const PORT = process.env.HASTIC_PORT || 8000; app.use(bodyParser()); app.use(function (ctx, next) { return __awaiter(this, void 0, void 0, function* () { @@ -167,11 +187,11 @@ rootRouter.use('/anomalies', anomalies_1.router.routes(), anomalies_1.router.all rootRouter.use('/segments', segments_1.router.routes(), segments_1.router.allowedMethods()); rootRouter.use('/alerts', alerts_1.router.routes(), alerts_1.router.allowedMethods()); rootRouter.get('/', ctx => __awaiter(undefined, void 0, void 0, function* () { - ctx.response.body = { status: 'Ok ok' }; + ctx.response.body = { status: 'Ok' }; })); app.use(rootRouter.routes()).use(rootRouter.allowedMethods()); -app.listen(PORT, () => { - console.log(`Server is running on :${PORT}`); +app.listen(config_1.HASTIC_PORT, () => { + console.log(`Server is running on :${config_1.HASTIC_PORT}`); }); /***/ }), @@ -605,31 +625,15 @@ var __awaiter = undefined && undefined.__awaiter || function (thisArg, _argument }); }; Object.defineProperty(exports, "__esModule", { value: true }); -const child_process_1 = __webpack_require__(/*! child_process */ "child_process"); -const config_1 = __webpack_require__(/*! ../config */ "./src/config.ts"); const anomalyType_1 = __webpack_require__(/*! ./anomalyType */ "./src/services/anomalyType.ts"); const metrics_1 = __webpack_require__(/*! ./metrics */ "./src/services/metrics.ts"); const segments_1 = __webpack_require__(/*! ./segments */ "./src/services/segments.ts"); -const event_stream_1 = __webpack_require__(/*! event-stream */ "event-stream"); -const fs = __webpack_require__(/*! fs */ "fs"); -const path = __webpack_require__(/*! path */ "path"); -var learnWorker; -if (fs.existsSync(path.join(config_1.ANALYTICS_PATH, 'dist/worker/worker'))) { - learnWorker = child_process_1.spawn('dist/worker/worker', [], { cwd: config_1.ANALYTICS_PATH }); -} else { - // If compiled analytics script doesn't exist - fallback to regular python - learnWorker = child_process_1.spawn('python3', ['worker.py'], { cwd: config_1.ANALYTICS_PATH }); -} -learnWorker.stdout.pipe(event_stream_1.split()).pipe(event_stream_1.mapSync(onMessage)); -learnWorker.stderr.on('data', data => console.error(`worker stderr: ${data}`)); +const analyticsConnection_1 = __webpack_require__(/*! ./analyticsConnection */ "./src/services/analyticsConnection.ts"); const taskMap = {}; let nextTaskId = 0; -function onMessage(data) { - console.log(`worker stdout: ${data}`); - let response = JSON.parse(data); +const analyticsConnection = new analyticsConnection_1.AnalyticsConnection(onResponse); +function onResponse(response) { let taskId = response.__task_id; - // let anomalyName = response.anomaly_name; - // let task = response.task; let status = response.status; if (status === 'success' || status === 'failed') { if (taskId in taskMap) { @@ -640,16 +644,17 @@ function onMessage(data) { } } function runTask(task) { - let anomaly = anomalyType_1.loadAnomalyById(task.anomaly_id); - task.metric = { - datasource: anomaly.metric.datasource, - targets: anomaly.metric.targets.map(t => metrics_1.getTarget(t)) - }; - task.__task_id = nextTaskId++; - let command = JSON.stringify(task); - learnWorker.stdin.write(`${command}\n`); - return new Promise((resolve, reject) => { - taskMap[task.__task_id] = resolve; + return __awaiter(this, void 0, void 0, function* () { + let anomaly = anomalyType_1.loadAnomalyById(task.anomaly_id); + task.metric = { + datasource: anomaly.metric.datasource, + targets: anomaly.metric.targets.map(t => metrics_1.getTarget(t)) + }; + task.__task_id = nextTaskId++; + yield analyticsConnection.sendMessage(task); + return new Promise((resolve, reject) => { + taskMap[task.__task_id] = resolve; + }); }); } function runLearning(anomalyId) { @@ -708,6 +713,76 @@ exports.runPredict = runPredict; /***/ }), +/***/ "./src/services/analyticsConnection.ts": +/*!*********************************************!*\ + !*** ./src/services/analyticsConnection.ts ***! + \*********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : new P(function (resolve) { + resolve(result.value); + }).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const config_1 = __webpack_require__(/*! ../config */ "./src/config.ts"); +const child_process_1 = __webpack_require__(/*! child_process */ "child_process"); +const event_stream_1 = __webpack_require__(/*! event-stream */ "event-stream"); +const fs = __webpack_require__(/*! fs */ "fs"); +const path = __webpack_require__(/*! path */ "path"); +class AnalyticsConnection { + constructor(_onResponse) { + this._onResponse = _onResponse; + if (fs.existsSync(path.join(config_1.ANALYTICS_PATH, 'dist/worker/worker'))) { + this._learnWorker = child_process_1.spawn('dist/worker/worker', [], { cwd: config_1.ANALYTICS_PATH }); + } else { + // If compiled analytics script doesn't exist - fallback to regular python + this._learnWorker = child_process_1.spawn('python3', ['worker.py'], { cwd: config_1.ANALYTICS_PATH }); + } + this._learnWorker.stdout.pipe(event_stream_1.split()).pipe(event_stream_1.mapSync(this._onPipeMessage.bind(this))); + this._learnWorker.stderr.on('data', data => console.error(`worker stderr: ${data}`)); + } + _onPipeMessage(data) { + console.log(`worker stdout: ${data}`); + let response = JSON.parse(data); + this._onResponse(response); + } + sendMessage(task) { + return __awaiter(this, void 0, void 0, function* () { + // return Promise.resolve().then(() => { + let command = JSON.stringify(task); + this._learnWorker.stdin.write(`${command}\n`); + // }); + }); + } +} +exports.AnalyticsConnection = AnalyticsConnection; + +/***/ }), + /***/ "./src/services/anomalyType.ts": /*!*************************************!*\ !*** ./src/services/anomalyType.ts ***! @@ -1248,4 +1323,4 @@ module.exports = require('path'); /***/ }) /******/ }); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbmZpZy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JvdXRlcy9hbGVydHMudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JvdXRlcy9hbm9tYWxpZXMudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JvdXRlcy9zZWdtZW50cy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvc2VydmljZXMvYWxlcnRzLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9hbmFseXRpY3MudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3NlcnZpY2VzL2Fub21hbHlUeXBlLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9kYXRhLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9qc29uLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9tZXRyaWNzLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9ub3RpZmljYXRpb24udHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3NlcnZpY2VzL3NlZ21lbnRzLnRzIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2F4aW9zJylcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZXF1aXJlKCdjaGlsZF9wcm9jZXNzJylcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZXF1aXJlKCdjcnlwdG8nKVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2V2ZW50LXN0cmVhbScpXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVxdWlyZSgnZnMnKVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2tvYScpXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVxdWlyZSgna29hLWJvZHlwYXJzZXInKVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2tvYS1yb3V0ZXInKVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2xvZGFzaCcpXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVxdWlyZSgncGF0aCcpXCIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0RBQTBDLGdDQUFnQztBQUMxRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGdFQUF3RCxrQkFBa0I7QUFDMUU7QUFDQSx5REFBaUQsY0FBYztBQUMvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQXlDLGlDQUFpQztBQUMxRSx3SEFBZ0gsbUJBQW1CLEVBQUU7QUFDckk7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBMkIsMEJBQTBCLEVBQUU7QUFDdkQseUNBQWlDLGVBQWU7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOERBQXNELCtEQUErRDs7QUFFckg7QUFDQTs7O0FBR0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ2xGQTtBQUVhLHlCQUFpQixLQUFLLElBQUwsQ0FBVSxTQUFWLEVBQXFCLGlCQUFyQixDQUFqQjtBQUVBLG9CQUFZLEtBQUssSUFBTCxDQUFVLFNBQVYsRUFBcUIsWUFBckIsQ0FBWjtBQUVBLHdCQUFnQixLQUFLLElBQUwsQ0FBVSxpQkFBVixFQUFxQixVQUFyQixDQUFoQjtBQUNBLHlCQUFpQixLQUFLLElBQUwsQ0FBVSxpQkFBVixFQUFxQixXQUFyQixDQUFqQjtBQUNBLHNCQUFjLEtBQUssSUFBTCxDQUFVLGlCQUFWLEVBQXFCLFFBQXJCLENBQWQ7QUFDQSx1QkFBZSxLQUFLLElBQUwsQ0FBVSxpQkFB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QyxtQkFBVyxTQUFTLE1BQVQsQ0FBZ0IsTUFBTSxHQUFHLEVBQUgsS0FBVSxTQUFoQyxDQUFYO0FBQ0Q7QUFDRCxpQkFBYSxTQUFiLEVBQXdCLFFBQXhCO0FBQ0Q7QUFFZ0Ysd0M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDNUVqRixrQzs7Ozs7Ozs7Ozs7QUNBQSwwQzs7Ozs7Ozs7Ozs7QUNBQSxtQzs7Ozs7Ozs7Ozs7QUNBQSx5Qzs7Ozs7Ozs7Ozs7QUNBQSwrQjs7Ozs7Ozs7Ozs7QUNBQSxnQzs7Ozs7Ozs7Ozs7QUNBQSwyQzs7Ozs7Ozs7Ozs7QUNBQSx1Qzs7Ozs7Ozs7Ozs7QUNBQSxtQzs7Ozs7Ozs7Ozs7QUNBQSxpQyIsImZpbGUiOiJzZXJ2ZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4gXHRcdH1cbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbiBcdH07XG5cbiBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbiBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcbiBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG4gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuIFx0XHRyZXR1cm4gbnM7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gMCk7XG4iLCJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuXG5leHBvcnQgY29uc3QgQU5BTFlUSUNTX1BBVEggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vLi4vYW5hbHl0aWNzJyk7XG5cbmV4cG9ydCBjb25zdCBEQVRBX1BBVEggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vLi4vZGF0YScpO1xuXG5leHBvcnQgY29uc3QgREFUQVNFVFNfUEFUSCA9IHBhdGguam9pbihEQVRBX1BBVEgsICdkYXRhc2V0cycpO1xuZXhwb3J0IGNvbnN0IEFOT01BTElFU19QQVRIID0gcGF0aC5qb2luKERBVEFfUEFUSCwgJ2Fub21hbGllcycpO1xuZXhwb3J0IGNvbnN0IE1PREVMU19QQVRIID0gcGF0aC5qb2luKERBVEFfUEFUSCwgJ21vZGVscycpO1xuZXhwb3J0IGNvbnN0IE1FVFJJQ1NfUEFUSCA9IHBhdGguam9pbihEQVRBX1BBVEgsICdtZXRyaWNzJyk7XG5leHBvcnQgY29uc3QgU0VHTUVOVFNfUEFUSCA9IHBhdGguam9pbihEQVRBX1BBVEgsICdzZWdtZW50cycpO1xuXG4iLCJpbXBvcnQgKiBhcyBLb2EgZnJvbSAna29hJztcbmltcG9ydCAqIGFzIFJvdXRlciBmcm9tICdrb2Etcm91dGVyJztcbmltcG9ydCAqIGFzIGJvZHlQYXJzZXIgZnJvbSAna29hLWJvZHlwYXJzZXInO1xuXG5cbmltcG9ydCB7IHJvdXRlciBhcyBhbm9tYWxpZXNSb3V0ZXIgfSBmcm9tICcuL3JvdXRlcy9hbm9tYWxpZXMnO1xuaW1wb3J0IHsgcm91dGVyIGFzIHNlZ21lbnRzUm91dGVyIH0gZnJvbSAnLi9yb3V0ZXMvc2VnbWVudHMnO1xuaW1wb3J0IHsgcm91dGVyIGFzIGFsZXJ0c1JvdXRlciB9IGZyb20gJy4vcm91dGVzL2FsZXJ0cyc7XG5cbmltcG9ydCB7IGNoZWNrRGF0YUZvbGRlcnMgfSBmcm9tICcuL3NlcnZpY2VzL2RhdGEnO1xuXG5jaGVja0RhdGFGb2xkZXJzKCk7XG5cbnZhciBhcHAgPSBuZXcgS29hKCk7XG5jb25zdCBQT1JUID0gcHJvY2Vzcy5lbnYuSEFTVElDX1BPUlQgfHwgODAwMDtcblxuYXBwLnVzZShib2R5UGFyc2VyKCkpXG5cbmFwcC51c2UoYXN5bmMgZnVuY3Rpb24oY3R4LCBuZXh0KSB7XG4gIGN0eC5zZXQoJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbicsICcqJyk7XG4gIGN0eC5zZXQoJ0FjY2Vzcy1Db250cm9sLUFsbG93LU1ldGhvZHMnLCAnR0VULCBQT1NULCBQVVQsIERFTEVURSwgUEFUQ0gsIE9QVElPTlMnKTtcbiAgY3R4LnNldCgnQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycycsICdPcmlnaW4sIFgtUmVxdWVzdGVkLVdpdGgsIENvbnRlbnQtVHlwZSwgQWNjZXB0Jyk7XG4gIG5leHQoKTtcbn0pO1xuXG5cbnZhciByb290Um91dGVyID0gbmV3IFJvdXRlcigpO1xucm9vdFJvdXRlci51c2UoJy9hbm9tYWxpZXMnLCBhbm9tYWxpZXNSb3V0ZXIucm91dGVzKCksIGFub21hbGllc1JvdXRlci5hbGxvd2VkTWV0aG9kcygpKTtcbnJvb3RSb3V0ZXIudXNlKCcvc2VnbWVudHMnLCBzZWdtZW50c1JvdXRlci5yb3V0ZXMoKSwgc2VnbWVudHNSb3V0ZXIuYWxsb3dlZE1ldGhvZHMoKSk7XG5yb290Um91dGVyLnVzZSgnL2FsZXJ0cycsIGFsZXJ0c1JvdXRlci5yb3V0ZXMoKSwgYWxlcnRzUm91dGVyLmFsbG93ZWRNZXRob2RzKCkpO1xucm9vdFJvdXRlci5nZXQoJy8nLCBhc3luYyAoY3R4KSA9PiB7XG4gIGN0eC5yZXNwb25zZS5ib2R5ID0geyBzdGF0dXM6ICdPayBvaycgfTtcbn0pO1xuXG5hcHBcbiAgLnVzZShyb290Um91dGVyLnJvdXRlcygpKVxuICAudXNlKHJvb3RSb3V0ZXIuYWxsb3dlZE1ldGhvZHMoKSlcblxuYXBwLmxpc3RlbihQT1JULCAoKSA9PiB7XG4gIGNvbnNvbGUubG9nKGBTZXJ2ZXIgaXMgcnVubmluZyBvbiA6JHtQT1JUfWApXG59KTtcblxuIiwiaW1wb3J0IHsgQW5vbWFseUlkLCBnZXRBbm9tYWx5SWRCeU5hbWUsIGxvYWRBbm9tYWx5QnlJZCB9IGZyb20gJy4uL3NlcnZpY2VzL2Fub21hbHlUeXBlJztcbmltcG9ydCB7IGdldEFsZXJ0c0Fub21hbGllcywgc2F2ZUFsZXJ0c0Fub21hbGllcyB9IGZyb20gJy4uL3NlcnZpY2VzL2FsZXJ0cyc7XG5cbmltcG9ydCAqIGFzIFJvdXRlciBmcm9tICdrb2Etcm91dGVyJztcblxuXG5mdW5jdGlvbiBnZXRBbGVydChjdHg6IFJvdXRlci5JUm91dGVyQ29udGV4dCkge1xuICBcbiAgbGV0IGFub21hbHlJZDogQW5vbWFseUlkID0gY3R4LnJlcXVlc3QucXVlcnkuYW5vbWFseV9pZDtcbiAgbGV0IGFub21hbHkgPSBsb2FkQW5vbWFseUJ5SWQoYW5vbWFseUlkKVxuICBpZihhbm9tYWx5ID09IG51bGwpIHtcbiAgICBhbm9tYWx5SWQgPSBnZXRBbm9tYWx5SWRCeU5hbWUoYW5vbWFseUlkLnRvTG93ZXJDYXNlKCkpO1xuICB9XG5cbiAgbGV0IGFsZXJ0c0Fub21hbGllcyA9IGdldEFsZXJ0c0Fub21hbGllcygpO1xuICBsZXQgcG9zID0gYWxlcnRzQW5vbWFsaWVzLmluZGV4T2YoYW5vbWFseUlkKTtcblxuICBsZXQgZW5hYmxlOiBib29sZWFuID0gKHBvcyAhPT0gLTEpO1xuICBjdHgucmVzcG9uc2UuYm9keSA9IHsgZW5hYmxlIH07XG4gIFxufVxuXG5mdW5jdGlvbiBjaGFuZ2VBbGVydChjdHg6IFJvdXRlci5JUm91dGVyQ29udGV4dCkge1xuXG4gIGxldCBhbm9tYWx5SWQ6IEFub21hbHlJZCA9IGN0eC5yZXF1ZXN0LmJvZHkuYW5vbWFseV9pZDtcbiAgbGV0IGVuYWJsZTogYm9vbGVhbiA9IGN0eC5yZXF1ZXN0LmJvZHkuZW5hYmxlO1xuXG4gIGxldCBhbm9tYWx5ID0gbG9hZEFub21hbHlCeUlkKGFub21hbHlJZClcbiAgaWYoYW5vbWFseSA9PSBudWxsKSB7XG4gICAgYW5vbWFseUlkID0gZ2V0QW5vbWFseUlkQnlOYW1lKGFub21hbHlJZC50b0xvd2VyQ2FzZSgpKTtcbiAgfVxuXG4gIGxldCBhbGVydHNBbm9tYWxpZXMgPSBnZXRBbGVydHNBbm9tYWxpZXMoKTtcbiAgbGV0IHBvczogbnVtYmVyID0gYWxlcnRzQW5vbWFsaWVzLmluZGV4T2YoYW5vbWFseUlkKTtcbiAgaWYoZW5hYmxlICYmIHBvcyA9PSAtMSkge1xuICAgIGFsZXJ0c0Fub21hbGllcy5wdXNoKGFub21hbHlJZCk7XG4gICAgc2F2ZUFsZXJ0c0Fub21hbGllcyhhbGVydHNBbm9tYWxpZXMpO1xuICB9IGVsc2UgaWYoIWVuYWJsZSAmJiBwb3MgPiAtMSkge1xuICAgIGFsZXJ0c0Fub21hbGllcy5zcGxpY2UocG9zLCAxKTtcbiAgICBzYXZlQWxlcnRzQW5vbWFsaWVzKGFsZXJ0c0Fub21hbGllcyk7XG4gIH1cbiAgY3R4LnJlc3BvbnNlLmJvZHkgPSB7IHN0YXR1czogJ09LJyB9O1xuXG59XG5cbmV4cG9ydCBjb25zdCByb3V0ZXIgPSBuZXcgUm91dGVyKCk7XG5cbnJvdXRlci5nZXQoJy8nLCBnZXRBbGVydCk7XG5yb3V0ZXIucG9zdCgnLycsIGNoYW5nZUFsZXJ0KTtcblxuIiwiaW1wb3J0ICogYXMgUm91dGVyIGZyb20gJ2tvYS1yb3V0ZXInO1xuXG5pbXBvcnQge1xuICBEYXRhc291cmNlLFxuICBNZXRyaWMsXG4gIEFub21hbHksXG4gIHNhdmVBbm9tYWx5LFxuICBpbnNlcnRBbm9tYWx5LCByZW1vdmVBbm9tYWx5LCBsb2FkQW5vbWFseUJ5TmFtZSwgbG9hZEFub21hbHlCeUlkLCBnZXRBbm9tYWx5SWRCeU5hbWVcbn0gZnJvbSAnLi4vc2VydmljZXMvYW5vbWFseVR5cGUnO1xuaW1wb3J0IHsgcnVuTGVhcm5pbmcgfSBmcm9tICcuLi9zZXJ2aWNlcy9hbmFseXRpY3MnXG5pbXBvcnQgeyBzYXZlVGFyZ2V0cyB9IGZyb20gJy4uL3NlcnZpY2VzL21ldHJpY3MnO1xuXG5hc3luYyBmdW5jdGlvbiBzZW5kQW5vbWFseVR5cGVTdGF0dXMoY3R4OiBSb3V0ZXIuSVJvdXRlckNvbnRleHQpIHtcbiAgbGV0IGlkID0gY3R4LnJlcXVlc3QucXVlcnkuaWQ7XG4gIGxldCBuYW1lID0gY3R4LnJlcXVlc3QucXVlcnkubmFtZTtcbiAgdHJ5IHtcbiAgICBsZXQgYW5vbWFseTogQW5vbWFseTtcbiAgICBpZihpZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhbm9tYWx5ID0gbG9hZEFub21hbHlCeUlkKGlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYW5vbWFseSA9IGxvYWRBbm9tYWx5QnlOYW1lKG5hbWUpO1xuICAgIH1cbiAgICBpZihhbm9tYWx5ID09PSBudWxsKSB7XG4gICAgICBjdHgucmVzcG9uc2Uuc3RhdHVzID0gNDA0O1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZihhbm9tYWx5LnN0YXR1cyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHN0YXR1cyBmb3IgJyArIG5hbWUpO1xuICAgIH1cbiAgICBjdHgucmVzcG9uc2UuYm9keSA9IHsgc3RhdHVzOiBhbm9tYWx5LnN0YXR1cywgZXJyb3JNZXNzYWdlOiBhbm9tYWx5LmVycm9yIH07XG4gIH0gY2F0Y2goZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgLy8gVE9ETzogYmV0dGVyIHNlbmQgNDA0IHdoZW4gd2Uga25vdyB0aGFuIGlzbmB0IGZvdW5kXG4gICAgY3R4LnJlc3BvbnNlLnN0YXR1cyA9IDUwMDtcbiAgICBjdHgucmVzcG9uc2UuYm9keSA9IHsgZXJyb3I6ICdDYW5gdCByZXR1cm4gYW55dGhpbmcnIH07XG4gIH1cblxufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRBbm9tYWx5KGN0eDogUm91dGVyLklSb3V0ZXJDb250ZXh0KSB7XG4gIHRyeSB7XG4gICAgbGV0IGlkID0gY3R4LnJlcXVlc3QucXVlcnkuaWQ7XG4gICAgbGV0IG5hbWUgPSBjdHgucmVxdWVzdC5xdWVyeS5uYW1lO1xuXG4gICAgbGV0IGFub21hbHk6QW5vbWFseTtcbiAgICBpZihpZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhbm9tYWx5ID0gbG9hZEFub21hbHlCeUlkKGlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYW5vbWFseSA9IGxvYWRBbm9tYWx5QnlOYW1lKG5hbWUudG9Mb3dlckNhc2UoKSk7XG4gICAgfVxuICAgIGlmKGFub21hbHkgPT09IG51bGwpIHtcbiAgICAgIGN0eC5yZXNwb25zZS5zdGF0dXMgPSA0MDQ7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY3R4LnJlc3BvbnNlLmJvZHkgPSB7XG4gICAgICBuYW1lOiBhbm9tYWx5Lm5hbWUsXG4gICAgICBtZXRyaWM6IGFub21hbHkubWV0cmljLFxuICAgICAgc3RhdHVzOiBhbm9tYWx5LnN0YXR1c1xuICAgIH07XG4gIH0gY2F0Y2goZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgLy8gVE9ETzogYmV0dGVyIHNlbmQgNDA0IHdoZW4gd2Uga25vdyB0aGFuIGlzbmB0IGZvdW5kXG4gICAgY3R4LnJlc3BvbnNlLnN0YXR1cyA9IDUwMDtcbiAgICBjdHgucmVzcG9uc2UuYm9keSA9ICdDYW5gdCBnZXQgYW55dGhpbmcnO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUFub21hbHkoY3R4OiBSb3V0ZXIuSVJvdXRlckNvbnRleHQpIHtcbiAgdHJ5IHtcbiAgICBsZXQgYm9keSA9IGN0eC5yZXF1ZXN0LmJvZHk7XG4gICAgY29uc3QgbWV0cmljOk1ldHJpYyA9IHtcbiAgICAgIGRhdGFzb3VyY2U6IGJvZHkubWV0cmljLmRhdGFzb3VyY2UsXG4gICAgICB0YXJnZXRzOiBzYXZlVGFyZ2V0cyhib2R5Lm1ldHJpYy50YXJnZXRzKVxuICAgIH07XG5cbiAgICBjb25zdCBhbm9tYWx5OkFub21hbHkgPSB7XG4gICAgICBuYW1lOiBib2R5Lm5hbWUsXG4gICAgICBwYW5lbFVybDogYm9keS5wYW5lbFVybCxcbiAgICAgIHBhdHRlcm46IGJvZHkucGF0dGVybi50b0xvd2VyQ2FzZSgpLFxuICAgICAgbWV0cmljOiBtZXRyaWMsXG4gICAgICBkYXRhc291cmNlOiBib2R5LmRhdGFzb3VyY2UsXG4gICAgICBzdGF0dXM6ICdsZWFybmluZycsXG4gICAgICBsYXN0X3ByZWRpY3Rpb25fdGltZTogMCxcbiAgICAgIG5leHRfaWQ6IDBcbiAgICB9O1xuICAgIGxldCBhbm9tYWx5SWQgPSBpbnNlcnRBbm9tYWx5KGFub21hbHkpO1xuICAgIGlmKGFub21hbHlJZCA9PT0gbnVsbCkge1xuICAgICAgY3R4LnJlc3BvbnNlLnN0YXR1cyA9IDQwMztcbiAgICAgIGN0eC5yZXNwb25zZS5ib2R5ID0ge1xuICAgICAgICBjb2RlOiA0MDMsXG4gICAgICAgIG1lc3NhZ2U6ICdBbHJlYWR5IGV4aXN0cydcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY3R4LnJlc3BvbnNlLmJvZHkgPSB7IGFub21hbHlfaWQ6IGFub21hbHlJZCB9O1xuXG4gICAgcnVuTGVhcm5pbmcoYW5vbWFseUlkKTtcbiAgfSBjYXRjaChlKSB7XG4gICAgY3R4LnJlc3BvbnNlLnN0YXR1cyA9IDUwMDtcbiAgICBjdHgucmVzcG9uc2UuYm9keSA9IHtcbiAgICAgIGNvZGU6IDUwMCxcbiAgICAgIG1lc3NhZ2U6ICdJbnRlcm5hbCBlcnJvcidcbiAgICB9O1xuICB9XG59XG5cbmZ1bmN0aW9uIGRlbGV0ZUFub21hbHkoY3R4OiBSb3V0ZXIuSVJvdXRlckNvbnRleHQpIHtcbiAgdHJ5IHtcbiAgICBsZXQgaWQgPSBjdHgucmVxdWVzdC5xdWVyeS5pZDtcbiAgICBsZXQgbmFtZSA9IGN0eC5yZXF1ZXN0LnF1ZXJ5Lm5hbWU7XG5cbiAgICBpZihpZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZW1vdmVBbm9tYWx5KGlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVtb3ZlQW5vbWFseShuYW1lLnRvTG93ZXJDYXNlKCkpO1xuICAgIH1cbiAgICBcbiAgICBjdHgucmVzcG9uc2UuYm9keSA9IHtcbiAgICAgIGNvZGU6IDIwMCxcbiAgICAgIG1lc3NhZ2U6ICdTdWNjZXNzJ1xuICAgIH07XG4gIH0gY2F0Y2goZSkge1xuICAgIGN0eC5yZXNwb25zZS5zdGF0dXMgPSA1MDA7XG4gICAgY3R4LnJlc3BvbnNlLmJvZHkgPSB7XG4gICAgICBjb2RlOiA1MDAsXG4gICAgICBtZXNzYWdlOiAnSW50ZXJuYWwgZXJyb3InXG4gICAgfTtcbiAgfVxufVxuXG5cbmV4cG9ydCB2YXIgcm91dGVyID0gbmV3IFJvdXRlcigpO1xuXG5yb3V0ZXIuZ2V0KCcvc3RhdHVzJywgc2VuZEFub21hbHlUeXBlU3RhdHVzKTtcbnJvdXRlci5nZXQoJy8nLCBnZXRBbm9tYWx5KTtcbnJvdXRlci5wb3N0KCcvJywgY3JlYXRlQW5vbWFseSk7XG5yb3V0ZXIuZGVsZXRlKCcvJywgZGVsZXRlQW5vbWFseSk7XG4iLCJpbXBvcnQgKiBhcyBSb3V0ZXIgZnJvbSAna29hLXJvdXRlcic7XG5cbmltcG9ydCB7XG4gIGdldExhYmVsZWRTZWdtZW50cyxcbiAgaW5zZXJ0U2VnbWVudHMsXG4gIHJlbW92ZVNlZ21lbnRzLFxufSBmcm9tICcuLi9zZXJ2aWNlcy9zZWdtZW50cyc7XG5cbmltcG9ydCB7XG4gIEFub21hbHksIEFub21hbHlJZCwgZ2V0QW5vbWFseUlkQnlOYW1lLCBsb2FkQW5vbWFseUJ5SWRcbn0gZnJvbSAnLi4vc2VydmljZXMvYW5vbWFseVR5cGUnO1xuXG5pbXBvcnQgeyBydW5MZWFybmluZyB9IGZyb20gJy4uL3NlcnZpY2VzL2FuYWx5dGljcyc7XG5cblxuYXN5bmMgZnVuY3Rpb24gc2VuZFNlZ21lbnRzKGN0eDogUm91dGVyLklSb3V0ZXJDb250ZXh0KSB7XG5cbiAgbGV0IGFub21hbHlJZDogQW5vbWFseUlkID0gY3R4LnJlcXVlc3QucXVlcnkuYW5vbWFseV9pZDtcbiAgbGV0IGFub21hbHk6QW5vbWFseSA9IGxvYWRBbm9tYWx5QnlJZChhbm9tYWx5SWQpO1xuICBpZihhbm9tYWx5ID09PSBudWxsKSB7XG4gICAgYW5vbWFseUlkID0gZ2V0QW5vbWFseUlkQnlOYW1lKGFub21hbHlJZCk7XG4gIH1cblxuICBsZXQgbGFzdFNlZ21lbnRJZCA9IGN0eC5yZXF1ZXN0LnF1ZXJ5Lmxhc3Rfc2VnbWVudDtcbiAgbGV0IHRpbWVGcm9tID0gY3R4LnJlcXVlc3QucXVlcnkuZnJvbTtcbiAgbGV0IHRpbWVUbyA9IGN0eC5yZXF1ZXN0LnF1ZXJ5LnRvO1xuXG4gIGxldCBzZWdtZW50cyA9IGdldExhYmVsZWRTZWdtZW50cyhhbm9tYWx5SWQpO1xuXG4gIC8vIElkIGZpbHRlcmluZ1xuICBpZihsYXN0U2VnbWVudElkICE9PSB1bmRlZmluZWQpIHtcbiAgICBzZWdtZW50cyA9IHNlZ21lbnRzLmZpbHRlcihlbCA9PiBlbC5pZCA+IGxhc3RTZWdtZW50SWQpO1xuICB9XG5cbiAgLy8gVGltZSBmaWx0ZXJpbmdcbiAgaWYodGltZUZyb20gIT09IHVuZGVmaW5lZCkge1xuICAgIHNlZ21lbnRzID0gc2VnbWVudHMuZmlsdGVyKGVsID0+IGVsLmZpbmlzaCA+IHRpbWVGcm9tKTtcbiAgfVxuXG4gIGlmKHRpbWVUbyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgc2VnbWVudHMgPSBzZWdtZW50cy5maWx0ZXIoZWwgPT4gZWwuc3RhcnQgPCB0aW1lVG8pO1xuICB9XG5cbiAgY3R4LnJlc3BvbnNlLmJvZHkgPSB7IHNlZ21lbnRzIH1cblxufVxuXG5hc3luYyBmdW5jdGlvbiB1cGRhdGVTZWdtZW50cyhjdHg6IFJvdXRlci5JUm91dGVyQ29udGV4dCkge1xuICB0cnkge1xuICAgIGxldCBzZWdtZW50c1VwZGF0ZSA9IGN0eC5yZXF1ZXN0LmJvZHk7XG5cbiAgICBsZXQgYW5vbWFseUlkID0gc2VnbWVudHNVcGRhdGUuYW5vbWFseV9pZDtcbiAgICBsZXQgYW5vbWFseU5hbWUgPSBzZWdtZW50c1VwZGF0ZS5uYW1lO1xuXG4gICAgaWYoYW5vbWFseUlkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGFub21hbHlJZCA9IGdldEFub21hbHlJZEJ5TmFtZShhbm9tYWx5TmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgICB9XG5cbiAgICBsZXQgYWRkZWRJZHMgPSBpbnNlcnRTZWdtZW50cyhhbm9tYWx5SWQsIHNlZ21lbnRzVXBkYXRlLmFkZGVkX3NlZ21lbnRzLCB0cnVlKTtcbiAgICByZW1vdmVTZWdtZW50cyhhbm9tYWx5SWQsIHNlZ21lbnRzVXBkYXRlLnJlbW92ZWRfc2VnbWVudHMpO1xuXG4gICAgY3R4LnJlc3BvbnNlLmJvZHkgPSB7IGFkZGVkX2lkczogYWRkZWRJZHMgfTtcblxuICAgIHJ1bkxlYXJuaW5nKGFub21hbHlJZCk7XG4gIH0gY2F0Y2goZSkge1xuICAgIGN0eC5yZXNwb25zZS5zdGF0dXMgPSA1MDA7XG4gICAgY3R4LnJlc3BvbnNlLmJvZHkgPSB7XG4gICAgICBjb2RlOiA1MDAsXG4gICAgICBtZXNzYWdlOiAnSW50ZXJuYWwgZXJyb3InXG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgcm91dGVyID0gbmV3IFJvdXRlcigpO1xuXG5yb3V0ZXIuZ2V0KCcvJywgc2VuZFNlZ21lbnRzKTtcbnJvdXRlci5wYXRjaCgnLycsIHVwZGF0ZVNlZ21lbnRzKTtcbiIsImltcG9ydCB7IGdldEpzb25EYXRhU3luYywgd3JpdGVKc29uRGF0YVN5bmMgfSBmcm9tICcuL2pzb24nO1xuaW1wb3J0IHsgQW5vbWFseUlkIH0gZnJvbSAnLi9hbm9tYWx5VHlwZSc7XG5pbXBvcnQgeyBydW5QcmVkaWN0IH0gZnJvbSAnLi9hbmFseXRpY3MnO1xuaW1wb3J0IHsgc2VuZE5vdGlmaWNhdGlvbiB9IGZyb20gJy4vbm90aWZpY2F0aW9uJztcbmltcG9ydCB7IGdldExhYmVsZWRTZWdtZW50cyB9IGZyb20gJy4vc2VnbWVudHMnO1xuXG5pbXBvcnQgeyBBTk9NQUxJRVNfUEFUSCB9IGZyb20gJy4uL2NvbmZpZyc7XG5cbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5cblxuXG5jb25zdCBBTEVSVFNfREJfUEFUSCA9IHBhdGguam9pbihBTk9NQUxJRVNfUEFUSCwgYGFsZXJ0c19hbm9tYWxpZXMuanNvbmApO1xuXG5mdW5jdGlvbiBnZXRBbGVydHNBbm9tYWxpZXMoKTogQW5vbWFseUlkW10ge1xuICBpZighZnMuZXhpc3RzU3luYyhBTEVSVFNfREJfUEFUSCkpIHtcbiAgICBzYXZlQWxlcnRzQW5vbWFsaWVzKFtdKTtcbiAgfVxuICByZXR1cm4gZ2V0SnNvbkRhdGFTeW5jKEFMRVJUU19EQl9QQVRIKTtcbn1cblxuZnVuY3Rpb24gc2F2ZUFsZXJ0c0Fub21hbGllcyhhbm9tYWxpZXM6IEFub21hbHlJZFtdKSB7XG4gIHJldHVybiB3cml0ZUpzb25EYXRhU3luYyhBTEVSVFNfREJfUEFUSCwgYW5vbWFsaWVzKTtcbn1cblxuZnVuY3Rpb24gcHJvY2Vzc0FsZXJ0cyhhbm9tYWx5SWQpIHtcbiAgbGV0IHNlZ21lbnRzID0gZ2V0TGFiZWxlZFNlZ21lbnRzKGFub21hbHlJZCk7XG5cbiAgY29uc3QgY3VycmVudFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgY29uc3QgYWN0aXZlQWxlcnQgPSBhY3RpdmVBbGVydHMuaGFzKGFub21hbHlJZCk7XG4gIGxldCBuZXdBY3RpdmVBbGVydCA9IGZhbHNlO1xuXG4gIGlmKHNlZ21lbnRzLmxlbmd0aCA+IDApIHtcbiAgICBsZXQgbGFzdFNlZ21lbnQgPSBzZWdtZW50c1tzZWdtZW50cy5sZW5ndGggLSAxXTtcbiAgICBpZihsYXN0U2VnbWVudC5maW5pc2ggPj0gY3VycmVudFRpbWUgLSBhbGVydFRpbWVvdXQpIHtcbiAgICAgIG5ld0FjdGl2ZUFsZXJ0ID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBpZighYWN0aXZlQWxlcnQgJiYgbmV3QWN0aXZlQWxlcnQpIHtcbiAgICBhY3RpdmVBbGVydHMuYWRkKGFub21hbHlJZCk7XG4gICAgc2VuZE5vdGlmaWNhdGlvbihhbm9tYWx5SWQsIHRydWUpO1xuICB9IGVsc2UgaWYoYWN0aXZlQWxlcnQgJiYgIW5ld0FjdGl2ZUFsZXJ0KSB7XG4gICAgYWN0aXZlQWxlcnRzLmRlbGV0ZShhbm9tYWx5SWQpO1xuICAgIHNlbmROb3RpZmljYXRpb24oYW5vbWFseUlkLCBmYWxzZSk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gYWxlcnRzVGljaygpIHtcbiAgbGV0IGFsZXJ0c0Fub21hbGllcyA9IGdldEFsZXJ0c0Fub21hbGllcygpO1xuICBmb3IgKGxldCBhbm9tYWx5SWQgb2YgYWxlcnRzQW5vbWFsaWVzKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHJ1blByZWRpY3QoYW5vbWFseUlkKTtcbiAgICAgIHByb2Nlc3NBbGVydHMoYW5vbWFseUlkKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgIH1cbiAgfVxuICBzZXRUaW1lb3V0KGFsZXJ0c1RpY2ssIDUwMDApO1xufVxuXG5jb25zdCBhbGVydFRpbWVvdXQgPSA2MDAwMDsgLy8gbXNcbmNvbnN0IGFjdGl2ZUFsZXJ0cyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuc2V0VGltZW91dChhbGVydHNUaWNrLCA1MDAwKTtcblxuXG5leHBvcnQgeyBnZXRBbGVydHNBbm9tYWxpZXMsIHNhdmVBbGVydHNBbm9tYWxpZXMgfVxuIiwiaW1wb3J0IHsgc3Bhd24gfSBmcm9tICdjaGlsZF9wcm9jZXNzJ1xuaW1wb3J0IHsgQU5BTFlUSUNTX1BBVEggfSBmcm9tICcuLi9jb25maWcnXG5pbXBvcnQge1xuICBBbm9tYWx5LFxuICBBbm9tYWx5SWQsIGdldEFub21hbHlUeXBlSW5mbyxcbiAgbG9hZEFub21hbHlCeUlkLFxuICBzZXRBbm9tYWx5UHJlZGljdGlvblRpbWUsXG4gIHNldEFub21hbHlTdGF0dXNcbn0gZnJvbSAnLi9hbm9tYWx5VHlwZSdcbmltcG9ydCB7IGdldFRhcmdldCB9IGZyb20gJy4vbWV0cmljcyc7XG5pbXBvcnQgeyBnZXRMYWJlbGVkU2VnbWVudHMsIGluc2VydFNlZ21lbnRzLCByZW1vdmVTZWdtZW50cyB9IGZyb20gJy4vc2VnbWVudHMnO1xuaW1wb3J0IHsgc3BsaXQsIG1hcFN5bmMgfSBmcm9tICdldmVudC1zdHJlYW0nO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcblxudmFyIGxlYXJuV29ya2VyO1xuaWYoZnMuZXhpc3RzU3luYyhwYXRoLmpvaW4oQU5BTFlUSUNTX1BBVEgsICdkaXN0L3dvcmtlci93b3JrZXInKSkpIHtcbiAgbGVhcm5Xb3JrZXIgPSBzcGF3bignZGlzdC93b3JrZXIvd29ya2VyJywgW10sIHsgY3dkOiBBTkFMWVRJQ1NfUEFUSCB9KVxufSBlbHNlIHtcbiAgLy8gSWYgY29tcGlsZWQgYW5hbHl0aWNzIHNjcmlwdCBkb2Vzbid0IGV4aXN0IC0gZmFsbGJhY2sgdG8gcmVndWxhciBweXRob25cbiAgbGVhcm5Xb3JrZXIgPSBzcGF3bigncHl0aG9uMycsIFsnd29ya2VyLnB5J10sIHsgY3dkOiBBTkFMWVRJQ1NfUEFUSCB9KVxufVxubGVhcm5Xb3JrZXIuc3Rkb3V0LnBpcGUoc3BsaXQoKSkucGlwZShtYXBTeW5jKG9uTWVzc2FnZSkpO1xuXG5sZWFybldvcmtlci5zdGRlcnIub24oJ2RhdGEnLCBkYXRhID0+IGNvbnNvbGUuZXJyb3IoYHdvcmtlciBzdGRlcnI6ICR7ZGF0YX1gKSk7XG5cbmNvbnN0IHRhc2tNYXAgPSB7fTtcbmxldCBuZXh0VGFza0lkID0gMDtcblxuZnVuY3Rpb24gb25NZXNzYWdlKGRhdGEpIHtcbiAgY29uc29sZS5sb2coYHdvcmtlciBzdGRvdXQ6ICR7ZGF0YX1gKTtcbiAgbGV0IHJlc3BvbnNlID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgbGV0IHRhc2tJZCA9IHJlc3BvbnNlLl9fdGFza19pZDtcbiAgLy8gbGV0IGFub21hbHlOYW1lID0gcmVzcG9uc2UuYW5vbWFseV9uYW1lO1xuICAvLyBsZXQgdGFzayA9IHJlc3BvbnNlLnRhc2s7XG4gIGxldCBzdGF0dXMgPSByZXNwb25zZS5zdGF0dXM7XG5cbiAgaWYoc3RhdHVzID09PSAnc3VjY2VzcycgfHwgc3RhdHVzID09PSAnZmFpbGVkJykge1xuICAgIGlmKHRhc2tJZCBpbiB0YXNrTWFwKSB7XG4gICAgICBsZXQgcmVzb2x2ZXIgPSB0YXNrTWFwW3Rhc2tJZF07XG4gICAgICByZXNvbHZlcihyZXNwb25zZSk7XG4gICAgICBkZWxldGUgdGFza01hcFt0YXNrSWRdO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBydW5UYXNrKHRhc2spIDogUHJvbWlzZTxhbnk+IHtcbiAgbGV0IGFub21hbHk6QW5vbWFseSA9IGxvYWRBbm9tYWx5QnlJZCh0YXNrLmFub21hbHlfaWQpO1xuICB0YXNrLm1ldHJpYyA9IHtcbiAgICBkYXRhc291cmNlOiBhbm9tYWx5Lm1ldHJpYy5kYXRhc291cmNlLFxuICAgIHRhcmdldHM6IGFub21hbHkubWV0cmljLnRhcmdldHMubWFwKHQgPT4gZ2V0VGFyZ2V0KHQpKVxuICB9O1xuXG4gIHRhc2suX190YXNrX2lkID0gbmV4dFRhc2tJZCsrO1xuICBsZXQgY29tbWFuZCA9IEpTT04uc3RyaW5naWZ5KHRhc2spXG4gIGxlYXJuV29ya2VyLnN0ZGluLndyaXRlKGAke2NvbW1hbmR9XFxuYCk7XG4gIHJldHVybiBuZXcgUHJvbWlzZTxPYmplY3Q+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICB0YXNrTWFwW3Rhc2suX190YXNrX2lkXSA9IHJlc29sdmVcbiAgfSlcbn1cblxuYXN5bmMgZnVuY3Rpb24gcnVuTGVhcm5pbmcoYW5vbWFseUlkOkFub21hbHlJZCkge1xuICBsZXQgc2VnbWVudHMgPSBnZXRMYWJlbGVkU2VnbWVudHMoYW5vbWFseUlkKTtcbiAgc2V0QW5vbWFseVN0YXR1cyhhbm9tYWx5SWQsICdsZWFybmluZycpO1xuICBsZXQgYW5vbWFseTpBbm9tYWx5ICA9IGxvYWRBbm9tYWx5QnlJZChhbm9tYWx5SWQpO1xuICBsZXQgcGF0dGVybiA9IGFub21hbHkucGF0dGVybjtcbiAgbGV0IHRhc2sgPSB7XG4gICAgdHlwZTogJ2xlYXJuJyxcbiAgICBhbm9tYWx5X2lkOiBhbm9tYWx5SWQsXG4gICAgcGF0dGVybixcbiAgICBzZWdtZW50czogc2VnbWVudHNcbiAgfTtcblxuICBsZXQgcmVzdWx0ID0gYXdhaXQgcnVuVGFzayh0YXNrKTtcblxuICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gJ3N1Y2Nlc3MnKSB7XG4gICAgc2V0QW5vbWFseVN0YXR1cyhhbm9tYWx5SWQsICdyZWFkeScpO1xuICAgIGluc2VydFNlZ21lbnRzKGFub21hbHlJZCwgcmVzdWx0LnNlZ21lbnRzLCBmYWxzZSk7XG4gICAgc2V0QW5vbWFseVByZWRpY3Rpb25UaW1lKGFub21hbHlJZCwgcmVzdWx0Lmxhc3RfcHJlZGljdGlvbl90aW1lKTtcbiAgfSBlbHNlIHtcbiAgICBzZXRBbm9tYWx5U3RhdHVzKGFub21hbHlJZCwgJ2ZhaWxlZCcsIHJlc3VsdC5lcnJvcik7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gcnVuUHJlZGljdChhbm9tYWx5SWQ6QW5vbWFseUlkKSB7XG4gIGxldCBhbm9tYWx5OkFub21hbHkgPSBsb2FkQW5vbWFseUJ5SWQoYW5vbWFseUlkKTtcbiAgbGV0IHBhdHRlcm4gPSBhbm9tYWx5LnBhdHRlcm47XG4gIGxldCB0YXNrID0ge1xuICAgIHR5cGU6ICdwcmVkaWN0JyxcbiAgICBhbm9tYWx5X2lkOiBhbm9tYWx5SWQsXG4gICAgcGF0dGVybixcbiAgICBsYXN0X3ByZWRpY3Rpb25fdGltZTogYW5vbWFseS5sYXN0X3ByZWRpY3Rpb25fdGltZVxuICB9O1xuICBsZXQgcmVzdWx0ID0gYXdhaXQgcnVuVGFzayh0YXNrKTtcblxuICBpZihyZXN1bHQuc3RhdHVzID09PSAnZmFpbGVkJykge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICAvLyBNZXJnaW5nIHNlZ21lbnRzXG4gIGxldCBzZWdtZW50cyA9IGdldExhYmVsZWRTZWdtZW50cyhhbm9tYWx5SWQpO1xuICBpZihzZWdtZW50cy5sZW5ndGggPiAwICYmIHJlc3VsdC5zZWdtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgbGV0IGxhc3RPbGRTZWdtZW50ID0gc2VnbWVudHNbc2VnbWVudHMubGVuZ3RoIC0gMV07XG4gICAgbGV0IGZpcnN0TmV3U2VnbWVudCA9IHJlc3VsdC5zZWdtZW50c1swXTtcblxuICAgIGlmKGZpcnN0TmV3U2VnbWVudC5zdGFydCA8PSBsYXN0T2xkU2VnbWVudC5maW5pc2gpIHtcbiAgICAgIHJlc3VsdC5zZWdtZW50c1swXS5zdGFydCA9IGxhc3RPbGRTZWdtZW50LnN0YXJ0O1xuICAgICAgcmVtb3ZlU2VnbWVudHMoYW5vbWFseUlkLCBbbGFzdE9sZFNlZ21lbnQuaWRdKTtcbiAgICB9XG4gIH1cblxuICBpbnNlcnRTZWdtZW50cyhhbm9tYWx5SWQsIHJlc3VsdC5zZWdtZW50cywgZmFsc2UpO1xuICBzZXRBbm9tYWx5UHJlZGljdGlvblRpbWUoYW5vbWFseUlkLCByZXN1bHQubGFzdF9wcmVkaWN0aW9uX3RpbWUpO1xuICByZXR1cm4gcmVzdWx0LnNlZ21lbnRzO1xufVxuXG5leHBvcnQgeyBydW5MZWFybmluZywgcnVuUHJlZGljdCB9XG4iLCJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnXG5pbXBvcnQgeyBnZXRKc29uRGF0YVN5bmMsIHdyaXRlSnNvbkRhdGFTeW5jIH0gZnJvbSAnLi9qc29uJ1xuaW1wb3J0IHsgQU5PTUFMSUVTX1BBVEggfSBmcm9tICcuLi9jb25maWcnXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcydcbmltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nO1xuXG5leHBvcnQgdHlwZSBEYXRhc291cmNlID0ge1xuICBtZXRob2Q6IHN0cmluZyxcbiAgZGF0YTogT2JqZWN0LFxuICBwYXJhbXM6IE9iamVjdCxcbiAgdHlwZTogc3RyaW5nLFxuICB1cmw6IHN0cmluZ1xufVxuXG5leHBvcnQgdHlwZSBNZXRyaWMgPSB7XG4gIGRhdGFzb3VyY2U6IHN0cmluZyxcbiAgdGFyZ2V0czogc3RyaW5nW11cbn1cblxuZXhwb3J0IHR5cGUgQW5vbWFseSA9IHtcbiAgbmFtZTogc3RyaW5nLFxuXG4gIHBhbmVsVXJsOiBzdHJpbmcsXG5cbiAgcGF0dGVybjogc3RyaW5nLFxuICBtZXRyaWM6IE1ldHJpYyxcbiAgZGF0YXNvdXJjZTogRGF0YXNvdXJjZVxuICBzdGF0dXM6IHN0cmluZyxcbiAgZXJyb3I/OiBzdHJpbmcsXG5cbiAgbGFzdF9wcmVkaWN0aW9uX3RpbWU6IG51bWJlcixcbiAgbmV4dF9pZDogbnVtYmVyXG59XG5cbmV4cG9ydCB0eXBlIEFub21hbHlJZCA9IHN0cmluZztcblxubGV0IGFub21hbGllc05hbWVUb0lkTWFwID0ge307XG5cbmZ1bmN0aW9uIGxvYWRBbm9tYWxpZXNNYXAoKSB7XG4gIGxldCBmaWxlbmFtZSA9IHBhdGguam9pbihBTk9NQUxJRVNfUEFUSCwgYGFsbF9hbm9tYWxpZXMuanNvbmApO1xuICBpZighZnMuZXhpc3RzU3luYyhmaWxlbmFtZSkpIHtcbiAgICBzYXZlQW5vbWFsaWVzTWFwKCk7XG4gIH1cbiAgYW5vbWFsaWVzTmFtZVRvSWRNYXAgPSBnZXRKc29uRGF0YVN5bmMoZmlsZW5hbWUpO1xufVxuXG5mdW5jdGlvbiBzYXZlQW5vbWFsaWVzTWFwKCkge1xuICBsZXQgZmlsZW5hbWUgPSBwYXRoLmpvaW4oQU5PTUFMSUVTX1BBVEgsIGBhbGxfYW5vbWFsaWVzLmpzb25gKTtcbiAgd3JpdGVKc29uRGF0YVN5bmMoZmlsZW5hbWUsIGFub21hbGllc05hbWVUb0lkTWFwKTtcbn1cblxuZnVuY3Rpb24gZ2V0QW5vbWFseUlkQnlOYW1lKGFub21hbHlOYW1lOnN0cmluZykgOiBBbm9tYWx5SWQge1xuICBsb2FkQW5vbWFsaWVzTWFwKCk7XG4gIGFub21hbHlOYW1lID0gYW5vbWFseU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgaWYoYW5vbWFseU5hbWUgaW4gYW5vbWFsaWVzTmFtZVRvSWRNYXApIHtcbiAgICByZXR1cm4gYW5vbWFsaWVzTmFtZVRvSWRNYXBbYW5vbWFseU5hbWVdO1xuICB9XG4gIHJldHVybiBhbm9tYWx5TmFtZTtcbn1cblxuZnVuY3Rpb24gaW5zZXJ0QW5vbWFseShhbm9tYWx5OiBBbm9tYWx5KSA6IEFub21hbHlJZCB7XG4gIGNvbnN0IGhhc2hTdHJpbmcgPSBhbm9tYWx5Lm5hbWUgKyAobmV3IERhdGUoKSkudG9TdHJpbmcoKTtcbiAgY29uc3QgYW5vbWFseUlkOkFub21hbHlJZCA9IGNyeXB0by5jcmVhdGVIYXNoKCdtZDUnKS51cGRhdGUoaGFzaFN0cmluZykuZGlnZXN0KCdoZXgnKTtcbiAgYW5vbWFsaWVzTmFtZVRvSWRNYXBbYW5vbWFseS5uYW1lXSA9IGFub21hbHlJZDtcbiAgc2F2ZUFub21hbGllc01hcCgpO1xuICAvLyByZXR1cm4gYW5vbWFseUlkXG4gIC8vIGNvbnN0IGFub21hbHlJZDpBbm9tYWx5SWQgPSBhbm9tYWx5Lm5hbWU7XG4gIGxldCBmaWxlbmFtZSA9IHBhdGguam9pbihBTk9NQUxJRVNfUEFUSCwgYCR7YW5vbWFseUlkfS5qc29uYCk7XG4gIGlmKGZzLmV4aXN0c1N5bmMoZmlsZW5hbWUpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgc2F2ZUFub21hbHkoYW5vbWFseUlkLCBhbm9tYWx5KTtcbiAgcmV0dXJuIGFub21hbHlJZDtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlQW5vbWFseShhbm9tYWx5SWQ6QW5vbWFseUlkKSB7XG4gIGxldCBmaWxlbmFtZSA9IHBhdGguam9pbihBTk9NQUxJRVNfUEFUSCwgYCR7YW5vbWFseUlkfS5qc29uYCk7XG4gIGZzLnVubGlua1N5bmMoZmlsZW5hbWUpO1xufVxuXG5mdW5jdGlvbiBzYXZlQW5vbWFseShhbm9tYWx5SWQ6IEFub21hbHlJZCwgYW5vbWFseTogQW5vbWFseSkge1xuICBsZXQgZmlsZW5hbWUgPSBwYXRoLmpvaW4oQU5PTUFMSUVTX1BBVEgsIGAke2Fub21hbHlJZH0uanNvbmApO1xuICByZXR1cm4gd3JpdGVKc29uRGF0YVN5bmMoZmlsZW5hbWUsIGFub21hbHkpO1xufVxuXG5mdW5jdGlvbiBsb2FkQW5vbWFseUJ5SWQoYW5vbWFseUlkOiBBbm9tYWx5SWQpIDogQW5vbWFseSB7XG4gIGxldCBmaWxlbmFtZSA9IHBhdGguam9pbihBTk9NQUxJRVNfUEFUSCwgYCR7YW5vbWFseUlkfS5qc29uYCk7XG4gIGlmKCFmcy5leGlzdHNTeW5jKGZpbGVuYW1lKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBnZXRKc29uRGF0YVN5bmMoZmlsZW5hbWUpO1xufVxuXG5mdW5jdGlvbiBsb2FkQW5vbWFseUJ5TmFtZShhbm9tYWx5TmFtZTogc3RyaW5nKSA6IEFub21hbHkge1xuICBsZXQgYW5vbWFseUlkID0gZ2V0QW5vbWFseUlkQnlOYW1lKGFub21hbHlOYW1lKTtcbiAgcmV0dXJuIGxvYWRBbm9tYWx5QnlJZChhbm9tYWx5SWQpO1xufVxuXG5mdW5jdGlvbiBzYXZlQW5vbWFseVR5cGVJbmZvKGluZm8pIHtcbiAgY29uc29sZS5sb2coJ1NhdmluZycpO1xuICBsZXQgZmlsZW5hbWUgPSBwYXRoLmpvaW4oQU5PTUFMSUVTX1BBVEgsIGAke2luZm8ubmFtZX0uanNvbmApO1xuICBpZihpbmZvLm5leHRfaWQgPT09IHVuZGVmaW5lZCkge1xuICAgIGluZm8ubmV4dF9pZCA9IDA7XG4gIH1cbiAgaWYoaW5mby5sYXN0X3ByZWRpY3Rpb25fdGltZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpbmZvLmxhc3RfcHJlZGljdGlvbl90aW1lID0gMDtcbiAgfVxuXG4gIHJldHVybiB3cml0ZUpzb25EYXRhU3luYyhmaWxlbmFtZSwgaW5mbyk7XG59XG5cbmZ1bmN0aW9uIGdldEFub21hbHlUeXBlSW5mbyhuYW1lKSB7XG4gIHJldHVybiBnZXRKc29uRGF0YVN5bmMocGF0aC5qb2luKEFOT01BTElFU19QQVRILCBgJHtuYW1lfS5qc29uYCkpO1xufVxuXG5mdW5jdGlvbiBzZXRBbm9tYWx5U3RhdHVzKGFub21hbHlJZDpBbm9tYWx5SWQsIHN0YXR1czpzdHJpbmcsIGVycm9yPzpzdHJpbmcpIHtcbiAgbGV0IGluZm8gPSBsb2FkQW5vbWFseUJ5SWQoYW5vbWFseUlkKTtcbiAgaW5mby5zdGF0dXMgPSBzdGF0dXM7XG4gIGlmKGVycm9yICE9PSB1bmRlZmluZWQpIHtcbiAgICBpbmZvLmVycm9yID0gZXJyb3I7XG4gIH0gZWxzZSB7XG4gICAgaW5mby5lcnJvciA9ICcnO1xuICB9XG4gIHNhdmVBbm9tYWx5KGFub21hbHlJZCwgaW5mbyk7XG59XG5cbmZ1bmN0aW9uIHNldEFub21hbHlQcmVkaWN0aW9uVGltZShhbm9tYWx5SWQ6QW5vbWFseUlkLCBsYXN0UHJlZGljdGlvblRpbWU6bnVtYmVyKSB7XG4gIGxldCBpbmZvID0gbG9hZEFub21hbHlCeUlkKGFub21hbHlJZCk7XG4gIGluZm8ubGFzdF9wcmVkaWN0aW9uX3RpbWUgPSBsYXN0UHJlZGljdGlvblRpbWU7XG4gIHNhdmVBbm9tYWx5KGFub21hbHlJZCwgaW5mbyk7XG59XG5cbmV4cG9ydCB7XG4gIHNhdmVBbm9tYWx5LCBsb2FkQW5vbWFseUJ5SWQsIGxvYWRBbm9tYWx5QnlOYW1lLCBpbnNlcnRBbm9tYWx5LCByZW1vdmVBbm9tYWx5LCBzYXZlQW5vbWFseVR5cGVJbmZvLFxuICBnZXRBbm9tYWx5VHlwZUluZm8sIGdldEFub21hbHlJZEJ5TmFtZSwgc2V0QW5vbWFseVN0YXR1cywgc2V0QW5vbWFseVByZWRpY3Rpb25UaW1lXG59XG4iLCJpbXBvcnQgKiBhcyBjb25maWcgZnJvbSAnLi4vY29uZmlnJ1xyXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XHJcblxyXG5cclxuLy8gc2VlIGFuYWx5dGljcy9wYXR0ZXJuX2RldGVjdGlvbl9tb2RlbC5weSB3aXRoIGZvbGRlcnMgYXZhaWxhYmxlXHJcblxyXG5mdW5jdGlvbiBtYXliZUNyZWF0ZShwYXRoOiBzdHJpbmcpOiB2b2lkIHtcclxuICBpZihmcy5leGlzdHNTeW5jKHBhdGgpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG4gIGZzLm1rZGlyU3luYyhwYXRoKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrRGF0YUZvbGRlcnMoKTogdm9pZCB7XHJcbiAgdmFyIGZvbGRlcnMgPSBbXHJcbiAgICBjb25maWcuREFUQV9QQVRILFxyXG4gICAgY29uZmlnLkRBVEFTRVRTX1BBVEgsXHJcbiAgICBjb25maWcuQU5PTUFMSUVTX1BBVEgsXHJcbiAgICBjb25maWcuTU9ERUxTX1BBVEgsXHJcbiAgICBjb25maWcuTUVUUklDU19QQVRILFxyXG4gICAgY29uZmlnLlNFR01FTlRTX1BBVEhcclxuICBdLmZvckVhY2gobWF5YmVDcmVhdGUpO1xyXG59XHJcbiIsImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcblxuYXN5bmMgZnVuY3Rpb24gZ2V0SnNvbkRhdGEoZmlsZW5hbWU6IHN0cmluZyk6IFByb21pc2U8T2JqZWN0PiB7XG4gIHZhciBkYXRhID0gYXdhaXQgbmV3IFByb21pc2U8c3RyaW5nPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgZnMucmVhZEZpbGUoZmlsZW5hbWUsICd1dGY4JywgKGVyciwgZGF0YSkgPT4ge1xuICAgICAgaWYoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgcmVqZWN0KCdDYW5gdCByZWFkIGZpbGUnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc29sdmUoZGF0YSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoZGF0YSk7XG4gIH0gY2F0Y2goZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdXcm9uZyBmaWxlIGZvcm1hdCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHdyaXRlSnNvbkRhdGEoZmlsZW5hbWU6IHN0cmluZywgZGF0YTogT2JqZWN0KSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgZnMud3JpdGVGaWxlKGZpbGVuYW1lLCBKU09OLnN0cmluZ2lmeShkYXRhKSwgJ3V0ZjgnLCAoZXJyKSA9PiB7XG4gICAgICBpZihlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICByZWplY3QoJ0NhdGB0IHdyaXRlIGZpbGUnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSlcbn1cblxuZnVuY3Rpb24gZ2V0SnNvbkRhdGFTeW5jKGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgbGV0IGRhdGEgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZW5hbWUsICd1dGY4Jyk7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoZGF0YSk7XG4gIH0gY2F0Y2goZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdXcm9uZyBmaWxlIGZvcm1hdCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHdyaXRlSnNvbkRhdGFTeW5jKGZpbGVuYW1lOiBzdHJpbmcsIGRhdGE6IE9iamVjdCkge1xuICBmcy53cml0ZUZpbGVTeW5jKGZpbGVuYW1lLCBKU09OLnN0cmluZ2lmeShkYXRhKSk7XG59XG5cbmV4cG9ydCB7XG4gIGdldEpzb25EYXRhLFxuICB3cml0ZUpzb25EYXRhLFxuICBnZXRKc29uRGF0YVN5bmMsXG4gIHdyaXRlSnNvbkRhdGFTeW5jXG59XG4iLCJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgZ2V0SnNvbkRhdGFTeW5jLCB3cml0ZUpzb25EYXRhU3luYyB9ICBmcm9tICcuL2pzb24nO1xuaW1wb3J0IHsgTUVUUklDU19QQVRIIH0gZnJvbSAnLi4vY29uZmlnJztcbmltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nO1xuXG5mdW5jdGlvbiBzYXZlVGFyZ2V0cyh0YXJnZXRzKSB7XG4gIGxldCBtZXRyaWNzID0gW107XG4gIGZvciAobGV0IHRhcmdldCBvZiB0YXJnZXRzKSB7XG4gICAgbWV0cmljcy5wdXNoKHNhdmVUYXJnZXQodGFyZ2V0KSk7XG4gIH1cbiAgcmV0dXJuIG1ldHJpY3M7XG59XG5cbmZ1bmN0aW9uIHNhdmVUYXJnZXQodGFyZ2V0KSB7XG4gIC8vY29uc3QgbWQ1ID0gY3J5cHRvLmNyZWF0ZUhhc2goJ21kNScpXG4gIGNvbnN0IHRhcmdldElkID0gY3J5cHRvLmNyZWF0ZUhhc2goJ21kNScpLnVwZGF0ZShKU09OLnN0cmluZ2lmeSh0YXJnZXQpKS5kaWdlc3QoJ2hleCcpO1xuICBsZXQgZmlsZW5hbWUgPSBwYXRoLmpvaW4oTUVUUklDU19QQVRILCBgJHt0YXJnZXRJZH0uanNvbmApO1xuICB3cml0ZUpzb25EYXRhU3luYyhmaWxlbmFtZSwgdGFyZ2V0KTtcbiAgcmV0dXJuIHRhcmdldElkO1xufVxuXG5mdW5jdGlvbiBnZXRUYXJnZXQodGFyZ2V0SWQpIHtcbiAgbGV0IGZpbGVuYW1lID0gcGF0aC5qb2luKE1FVFJJQ1NfUEFUSCwgYCR7dGFyZ2V0SWR9Lmpzb25gKTtcbiAgcmV0dXJuIGdldEpzb25EYXRhU3luYyhmaWxlbmFtZSk7XG59XG5cbmV4cG9ydCB7IHNhdmVUYXJnZXRzLCBnZXRUYXJnZXQgfVxuIiwiaW1wb3J0IGF4aW9zIGZyb20gJ2F4aW9zJztcbmltcG9ydCB7IGxvYWRBbm9tYWx5QnlJZCB9IGZyb20gJy4vYW5vbWFseVR5cGUnO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2VuZE5vdGlmaWNhdGlvbihhbm9tYWx5SWQsIGFjdGl2ZSkge1xuICBsZXQgYW5vbWFseU5hbWUgPSBsb2FkQW5vbWFseUJ5SWQoYW5vbWFseUlkKS5uYW1lO1xuICBjb25zb2xlLmxvZygnTm90aWZpY2F0aW9uICcgKyBhbm9tYWx5TmFtZSk7XG5cbiAgbGV0IG5vdGlmaWNhdGlvbiA9IHtcbiAgICBhbm9tYWx5OiBhbm9tYWx5TmFtZSxcbiAgICBzdGF0dXM6ICcnXG4gIH07XG4gIGlmKGFjdGl2ZSkge1xuICAgIG5vdGlmaWNhdGlvbi5zdGF0dXMgPSAnYWxlcnQnO1xuICB9IGVsc2Uge1xuICAgIG5vdGlmaWNhdGlvbi5zdGF0dXMgPSAnT0snO1xuICB9XG5cbiAgbGV0IGVuZHBvaW50ID0gcHJvY2Vzcy5lbnYuSEFTVElDX0FMRVJUX0VORFBPSU5UO1xuICBpZihlbmRwb2ludCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc29sZS5lcnJvcihgQ2FuJ3Qgc2VuZCBhbGVydCwgZW52IEhBU1RJQ19BTEVSVF9FTkRQT0lOVCBpcyB1bmRlZmluZWRgKTtcbiAgICByZXR1cm47XG4gIH1cblxuICB0cnkge1xuICAgIHZhciBkYXRhID0gYXdhaXQgYXhpb3MucG9zdChlbmRwb2ludCwge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShub3RpZmljYXRpb24pXG4gICAgfSlcbiAgICBjb25zb2xlLmxvZyhkYXRhKTtcbiAgfSBjYXRjaChlcnIpIHtcbiAgICBjb25zb2xlLmVycm9yKGBDYW4ndCBzZW5kIGFsZXJ0IHRvICR7ZW5kcG9pbnR9LiBFcnJvcjogJHtlcnJ9YClcbiAgfVxuICBcbn1cblxuIiwiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IGdldEpzb25EYXRhU3luYywgd3JpdGVKc29uRGF0YVN5bmMgfSAgZnJvbSAnLi9qc29uJztcbmltcG9ydCB7IFNFR01FTlRTX1BBVEggfSBmcm9tICcuLi9jb25maWcnO1xuaW1wb3J0IHsgQW5vbWFseUlkLCBsb2FkQW5vbWFseUJ5SWQsIHNhdmVBbm9tYWx5IH0gZnJvbSAnLi9hbm9tYWx5VHlwZSc7XG5cbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcblxuZnVuY3Rpb24gZ2V0TGFiZWxlZFNlZ21lbnRzKGFub21hbHlJZDogQW5vbWFseUlkKSB7XG4gIGxldCBmaWxlbmFtZSA9IHBhdGguam9pbihTRUdNRU5UU19QQVRILCBgJHthbm9tYWx5SWR9X2xhYmVsZWQuanNvbmApO1xuXG4gIGxldCBzZWdtZW50cyA9IFtdO1xuICB0cnkge1xuICAgIHNlZ21lbnRzID0gZ2V0SnNvbkRhdGFTeW5jKGZpbGVuYW1lKTtcbiAgICBmb3IgKGxldCBzZWdtZW50IG9mIHNlZ21lbnRzKSB7XG4gICAgICBpZiAoc2VnbWVudC5sYWJlbGVkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc2VnbWVudC5sYWJlbGVkID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5lcnJvcihlLm1lc3NhZ2UpO1xuICB9XG4gIHJldHVybiBzZWdtZW50cztcbn1cblxuZnVuY3Rpb24gZ2V0UHJlZGljdGVkU2VnbWVudHMoYW5vbWFseUlkOiBBbm9tYWx5SWQpIHtcbiAgbGV0IGZpbGVuYW1lID0gcGF0aC5qb2luKFNFR01FTlRTX1BBVEgsIGAke2Fub21hbHlJZH1fc2VnbWVudHMuanNvbmApO1xuXG4gIGxldCBqc29uRGF0YTtcbiAgdHJ5IHtcbiAgICBqc29uRGF0YSA9IGdldEpzb25EYXRhU3luYyhmaWxlbmFtZSk7XG4gIH0gY2F0Y2goZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoZS5tZXNzYWdlKTtcbiAgICBqc29uRGF0YSA9IFtdO1xuICB9XG4gIHJldHVybiBqc29uRGF0YTtcbn1cblxuZnVuY3Rpb24gc2F2ZVNlZ21lbnRzKGFub21hbHlJZDogQW5vbWFseUlkLCBzZWdtZW50cykge1xuICBsZXQgZmlsZW5hbWUgPSBwYXRoLmpvaW4oU0VHTUVOVFNfUEFUSCwgYCR7YW5vbWFseUlkfV9sYWJlbGVkLmpzb25gKTtcblxuICB0cnkge1xuICAgIHJldHVybiB3cml0ZUpzb25EYXRhU3luYyhmaWxlbmFtZSwgXy51bmlxQnkoc2VnbWVudHMsICdzdGFydCcpKTtcbiAgfSBjYXRjaChlKSB7XG4gICAgY29uc29sZS5lcnJvcihlLm1lc3NhZ2UpO1xuICAgIHRocm93IG5ldyBFcnJvcignQ2FuYHQgd3JpdGUgdG8gZGInKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnNlcnRTZWdtZW50cyhhbm9tYWx5SWQ6IEFub21hbHlJZCwgYWRkZWRTZWdtZW50cywgbGFiZWxlZDpib29sZWFuKSB7XG4gIC8vIFNldCBzdGF0dXNcbiAgbGV0IGluZm8gPSBsb2FkQW5vbWFseUJ5SWQoYW5vbWFseUlkKTtcbiAgbGV0IHNlZ21lbnRzID0gZ2V0TGFiZWxlZFNlZ21lbnRzKGFub21hbHlJZCk7XG5cbiAgbGV0IG5leHRJZCA9IGluZm8ubmV4dF9pZDtcbiAgbGV0IGFkZGVkSWRzID0gW11cbiAgZm9yIChsZXQgc2VnbWVudCBvZiBhZGRlZFNlZ21lbnRzKSB7XG4gICAgc2VnbWVudC5pZCA9IG5leHRJZDtcbiAgICBzZWdtZW50LmxhYmVsZWQgPSBsYWJlbGVkO1xuICAgIGFkZGVkSWRzLnB1c2gobmV4dElkKTtcbiAgICBuZXh0SWQrKztcbiAgICBzZWdtZW50cy5wdXNoKHNlZ21lbnQpO1xuICB9XG4gIGluZm8ubmV4dF9pZCA9IG5leHRJZDtcbiAgc2F2ZVNlZ21lbnRzKGFub21hbHlJZCwgc2VnbWVudHMpO1xuICBzYXZlQW5vbWFseShhbm9tYWx5SWQsIGluZm8pO1xuICByZXR1cm4gYWRkZWRJZHM7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZVNlZ21lbnRzKGFub21hbHlJZDogQW5vbWFseUlkLCByZW1vdmVkU2VnbWVudHMpIHtcbiAgbGV0IHNlZ21lbnRzID0gZ2V0TGFiZWxlZFNlZ21lbnRzKGFub21hbHlJZCk7XG4gIGZvciAobGV0IHNlZ21lbnRJZCBvZiByZW1vdmVkU2VnbWVudHMpIHtcbiAgICBzZWdtZW50cyA9IHNlZ21lbnRzLmZpbHRlcihlbCA9PiBlbC5pZCAhPT0gc2VnbWVudElkKTtcbiAgfVxuICBzYXZlU2VnbWVudHMoYW5vbWFseUlkLCBzZWdtZW50cyk7XG59XG5cbmV4cG9ydCB7IGdldExhYmVsZWRTZWdtZW50cywgZ2V0UHJlZGljdGVkU2VnbWVudHMsIHNhdmVTZWdtZW50cywgaW5zZXJ0U2VnbWVudHMsIHJlbW92ZVNlZ21lbnRzIH1cbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnYXhpb3MnKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJ2NyeXB0bycpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnZXZlbnQtc3RyZWFtJyk7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdmcycpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgna29hJyk7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdrb2EtYm9keXBhcnNlcicpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgna29hLXJvdXRlcicpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnbG9kYXNoJyk7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdwYXRoJyk7Il0sInNvdXJjZVJvb3QiOiIifQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbmZpZy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JvdXRlcy9hbGVydHMudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JvdXRlcy9hbm9tYWxpZXMudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JvdXRlcy9zZWdtZW50cy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvc2VydmljZXMvYWxlcnRzLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9hbmFseXRpY3MudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3NlcnZpY2VzL2FuYWx5dGljc0Nvbm5lY3Rpb24udHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3NlcnZpY2VzL2Fub21hbHlUeXBlLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9kYXRhLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9qc29uLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9tZXRyaWNzLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9ub3RpZmljYXRpb24udHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3NlcnZpY2VzL3NlZ21lbnRzLnRzIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2F4aW9zJylcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZXF1aXJlKCdjaGlsZF9wcm9jZXNzJylcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZXF1aXJlKCdjcnlwdG8nKVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2V2ZW50LXN0cmVhbScpXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVxdWlyZSgnZnMnKVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2tvYScpXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVxdWlyZSgna29hLWJvZHlwYXJzZXInKVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2tvYS1yb3V0ZXInKVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2xvZGFzaCcpXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVxdWlyZSgncGF0aCcpXCIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0RBQTBDLGdDQUFnQztBQUMxRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGdFQUF3RCxrQkFBa0I7QUFDMUU7QUFDQSx5REFBaUQsY0FBYztBQUMvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQXlDLGlDQUFpQztBQUMxRSx3SEFBZ0gsbUJBQW1CLEVBQUU7QUFDckk7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBMkIsMEJBQTBCLEVBQUU7QUFDdkQseUNBQWlDLGVBQWU7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOERBQXNELCtEQUErRDs7QUFFckg7QUFDQTs7O0FBR0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ2xGQTtBQUNBO0FBQ0E7QUFHQSxJQUFJLGFBQWEsS0FBSyxJQUFMLENBQVUsU0FBVixFQUFxQixtQkFBckIsQ0FBakI7QUFDQSxJQUFJLGVBQWUsR0FBRyxVQUFILENBQWMsVUFBZCxDQUFuQjtBQUVhLHlCQUFpQixLQUFLLElBQUwsQ0FBVSxTQUFWLEVBQXFCLGlCQUFyQixDQUFqQjtBQUVBLG9CQUFZLEtBQUssSUFBTCxDQUFVLFNBQVYsRUFBcUIsWUFBckIsQ0FBWjtBQUVBLHdCQUFnQixLQUFLLElBQUwsQ0FB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QUFXLFNBQVMsTUFBVCxDQUFnQixNQUFNLEdBQUcsRUFBSCxLQUFVLFNBQWhDLENBQVg7QUFDRDtBQUNELGlCQUFhLFNBQWIsRUFBd0IsUUFBeEI7QUFDRDtBQUVnRix3Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUM1RWpGLGtDOzs7Ozs7Ozs7OztBQ0FBLDBDOzs7Ozs7Ozs7OztBQ0FBLG1DOzs7Ozs7Ozs7OztBQ0FBLHlDOzs7Ozs7Ozs7OztBQ0FBLCtCOzs7Ozs7Ozs7OztBQ0FBLGdDOzs7Ozs7Ozs7OztBQ0FBLDJDOzs7Ozs7Ozs7OztBQ0FBLHVDOzs7Ozs7Ozs7OztBQ0FBLG1DOzs7Ozs7Ozs7OztBQ0FBLGlDIiwiZmlsZSI6InNlcnZlci5qcyIsInNvdXJjZXNDb250ZW50IjpbIiBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbiBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG5cbiBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbiBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKSB7XG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG4gXHRcdH1cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGk6IG1vZHVsZUlkLFxuIFx0XHRcdGw6IGZhbHNlLFxuIFx0XHRcdGV4cG9ydHM6IHt9XG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbiBcdH1cblxuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbiBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbiBcdC8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIGhhcm1vbnkgZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4gXHRcdGlmKCFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywgbmFtZSkpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgbmFtZSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGdldHRlciB9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yID0gZnVuY3Rpb24oZXhwb3J0cykge1xuIFx0XHRpZih0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcbiBcdFx0fVxuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuIFx0fTtcblxuIFx0Ly8gY3JlYXRlIGEgZmFrZSBuYW1lc3BhY2Ugb2JqZWN0XG4gXHQvLyBtb2RlICYgMTogdmFsdWUgaXMgYSBtb2R1bGUgaWQsIHJlcXVpcmUgaXRcbiBcdC8vIG1vZGUgJiAyOiBtZXJnZSBhbGwgcHJvcGVydGllcyBvZiB2YWx1ZSBpbnRvIHRoZSBuc1xuIFx0Ly8gbW9kZSAmIDQ6IHJldHVybiB2YWx1ZSB3aGVuIGFscmVhZHkgbnMgb2JqZWN0XG4gXHQvLyBtb2RlICYgOHwxOiBiZWhhdmUgbGlrZSByZXF1aXJlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnQgPSBmdW5jdGlvbih2YWx1ZSwgbW9kZSkge1xuIFx0XHRpZihtb2RlICYgMSkgdmFsdWUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKHZhbHVlKTtcbiBcdFx0aWYobW9kZSAmIDgpIHJldHVybiB2YWx1ZTtcbiBcdFx0aWYoKG1vZGUgJiA0KSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICYmIHZhbHVlLl9fZXNNb2R1bGUpIHJldHVybiB2YWx1ZTtcbiBcdFx0dmFyIG5zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yKG5zKTtcbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG5zLCAnZGVmYXVsdCcsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHZhbHVlIH0pO1xuIFx0XHRpZihtb2RlICYgMiAmJiB0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIGZvcih2YXIga2V5IGluIHZhbHVlKSBfX3dlYnBhY2tfcmVxdWlyZV9fLmQobnMsIGtleSwgZnVuY3Rpb24oa2V5KSB7IHJldHVybiB2YWx1ZVtrZXldOyB9LmJpbmQobnVsbCwga2V5KSk7XG4gXHRcdHJldHVybiBucztcbiBcdH07XG5cbiBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbiBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcbiBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XG4gXHRcdHJldHVybiBnZXR0ZXI7XG4gXHR9O1xuXG4gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubyA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHsgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsgfTtcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiXCI7XG5cblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSAwKTtcbiIsImltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgeyBnZXRKc29uRGF0YVN5bmMgfSBmcm9tICcuL3NlcnZpY2VzL2pzb24nO1xuXG5cbmxldCBjb25maWdGaWxlID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uLy4uL2NvbmZpZy5qc29uJyk7XG5sZXQgY29uZmlnRXhpc3RzID0gZnMuZXhpc3RzU3luYyhjb25maWdGaWxlKTtcblxuZXhwb3J0IGNvbnN0IEFOQUxZVElDU19QQVRIID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uLy4uL2FuYWx5dGljcycpO1xuXG5leHBvcnQgY29uc3QgREFUQV9QQVRIID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uLy4uL2RhdGEnKTtcblxuZXhwb3J0IGNvbnN0IERBVEFTRVRTX1BBVEggPSBwYXRoLmpvaW4oREFUQV9QQVRILCAnZGF0YXNldHMnKTtcbmV4cG9ydCBjb25zdCBBTk9NQUxJRVNfUEFUSCA9IHBhdGguam9pbihEQVRBX1BBVEgsICdhbm9tYWxpZXMnKTtcbmV4cG9ydCBjb25zdCBNT0RFTFNfUEFUSCA9IHBhdGguam9pbihEQVRBX1BBVEgsICdtb2RlbHMnKTtcbmV4cG9ydCBjb25zdCBNRVRSSUNTX1BBVEggPSBwYXRoLmpvaW4oREFUQV9QQVRILCAnbWV0cmljcycpO1xuZXhwb3J0IGNvbnN0IFNFR01FTlRTX1BBVEggPSBwYXRoLmpvaW4oREFUQV9QQVRILCAnc2VnbWVudHMnKTtcblxuZXhwb3J0IGNvbnN0IEhBU1RJQ19QT1JUID0gZ2V0Q29uZmlnRmllbGQoJ0hBU1RJQ19QT1JUJywgJzgwMDAnKTtcbmZ1bmN0aW9uIGdldENvbmZpZ0ZpZWxkKGZpZWxkLCBkZWZhdWx0VmFsPykge1xuICBsZXQgdmFsID0gZGVmYXVsdFZhbDtcblxuICBpZihwcm9jZXNzLmVudltmaWVsZF0gIT09IHVuZGVmaW5lZCkge1xuICAgIHZhbCA9IHByb2Nlc3MuZW52W2ZpZWxkXTtcbiAgfSBlbHNlIGlmKGNvbmZpZ0V4aXN0cykge1xuICAgIGxldCBjb25maWc6IGFueSA9IGdldEpzb25EYXRhU3luYyhjb25maWdGaWxlKTtcblxuICAgIGlmKGNvbmZpZ1tmaWVsZF0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFsID0gY29uZmlnW2ZpZWxkXTtcbiAgICB9XG4gIH1cblxuICBpZih2YWwgPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgUGxlYXNlIGNvbmZpZ3VyZSAke2ZpZWxkfWApXG4gIH1cbiAgcmV0dXJuIHZhbDtcbn1cbiIsImltcG9ydCAqIGFzIEtvYSBmcm9tICdrb2EnO1xuaW1wb3J0ICogYXMgUm91dGVyIGZyb20gJ2tvYS1yb3V0ZXInO1xuaW1wb3J0ICogYXMgYm9keVBhcnNlciBmcm9tICdrb2EtYm9keXBhcnNlcic7XG5cblxuaW1wb3J0IHsgcm91dGVyIGFzIGFub21hbGllc1JvdXRlciB9IGZyb20gJy4vcm91dGVzL2Fub21hbGllcyc7XG5pbXBvcnQgeyByb3V0ZXIgYXMgc2VnbWVudHNSb3V0ZXIgfSBmcm9tICcuL3JvdXRlcy9zZWdtZW50cyc7XG5pbXBvcnQgeyByb3V0ZXIgYXMgYWxlcnRzUm91dGVyIH0gZnJvbSAnLi9yb3V0ZXMvYWxlcnRzJztcblxuaW1wb3J0IHsgY2hlY2tEYXRhRm9sZGVycyB9IGZyb20gJy4vc2VydmljZXMvZGF0YSc7XG5cbmltcG9ydCB7IEhBU1RJQ19QT1JUIH0gZnJvbSAnLi9jb25maWcnO1xuXG5jaGVja0RhdGFGb2xkZXJzKCk7XG5cbnZhciBhcHAgPSBuZXcgS29hKCk7XG5cbmFwcC51c2UoYm9keVBhcnNlcigpKVxuXG5hcHAudXNlKGFzeW5jIGZ1bmN0aW9uKGN0eCwgbmV4dCkge1xuICBjdHguc2V0KCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW4nLCAnKicpO1xuICBjdHguc2V0KCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJywgJ0dFVCwgUE9TVCwgUFVULCBERUxFVEUsIFBBVENILCBPUFRJT05TJyk7XG4gIGN0eC5zZXQoJ0FjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnLCAnT3JpZ2luLCBYLVJlcXVlc3RlZC1XaXRoLCBDb250ZW50LVR5cGUsIEFjY2VwdCcpO1xuICBuZXh0KCk7XG59KTtcblxuXG52YXIgcm9vdFJvdXRlciA9IG5ldyBSb3V0ZXIoKTtcbnJvb3RSb3V0ZXIudXNlKCcvYW5vbWFsaWVzJywgYW5vbWFsaWVzUm91dGVyLnJvdXRlcygpLCBhbm9tYWxpZXNSb3V0ZXIuYWxsb3dlZE1ldGhvZHMoKSk7XG5yb290Um91dGVyLnVzZSgnL3NlZ21lbnRzJywgc2VnbWVudHNSb3V0ZXIucm91dGVzKCksIHNlZ21lbnRzUm91dGVyLmFsbG93ZWRNZXRob2RzKCkpO1xucm9vdFJvdXRlci51c2UoJy9hbGVydHMnLCBhbGVydHNSb3V0ZXIucm91dGVzKCksIGFsZXJ0c1JvdXRlci5hbGxvd2VkTWV0aG9kcygpKTtcbnJvb3RSb3V0ZXIuZ2V0KCcvJywgYXN5bmMgKGN0eCkgPT4ge1xuICBjdHgucmVzcG9uc2UuYm9keSA9IHsgc3RhdHVzOiAnT2snIH07XG59KTtcblxuYXBwXG4gIC51c2Uocm9vdFJvdXRlci5yb3V0ZXMoKSlcbiAgLnVzZShyb290Um91dGVyLmFsbG93ZWRNZXRob2RzKCkpO1xuXG5hcHAubGlzdGVuKEhBU1RJQ19QT1JULCAoKSA9PiB7XG4gIGNvbnNvbGUubG9nKGBTZXJ2ZXIgaXMgcnVubmluZyBvbiA6JHtIQVNUSUNfUE9SVH1gKTtcbn0pO1xuXG4iLCJpbXBvcnQgeyBBbm9tYWx5SWQsIGdldEFub21hbHlJZEJ5TmFtZSwgbG9hZEFub21hbHlCeUlkIH0gZnJvbSAnLi4vc2VydmljZXMvYW5vbWFseVR5cGUnO1xuaW1wb3J0IHsgZ2V0QWxlcnRzQW5vbWFsaWVzLCBzYXZlQWxlcnRzQW5vbWFsaWVzIH0gZnJvbSAnLi4vc2VydmljZXMvYWxlcnRzJztcblxuaW1wb3J0ICogYXMgUm91dGVyIGZyb20gJ2tvYS1yb3V0ZXInO1xuXG5cbmZ1bmN0aW9uIGdldEFsZXJ0KGN0eDogUm91dGVyLklSb3V0ZXJDb250ZXh0KSB7XG4gIFxuICBsZXQgYW5vbWFseUlkOiBBbm9tYWx5SWQgPSBjdHgucmVxdWVzdC5xdWVyeS5hbm9tYWx5X2lkO1xuICBsZXQgYW5vbWFseSA9IGxvYWRBbm9tYWx5QnlJZChhbm9tYWx5SWQpXG4gIGlmKGFub21hbHkgPT0gbnVsbCkge1xuICAgIGFub21hbHlJZCA9IGdldEFub21hbHlJZEJ5TmFtZShhbm9tYWx5SWQudG9Mb3dlckNhc2UoKSk7XG4gIH1cblxuICBsZXQgYWxlcnRzQW5vbWFsaWVzID0gZ2V0QWxlcnRzQW5vbWFsaWVzKCk7XG4gIGxldCBwb3MgPSBhbGVydHNBbm9tYWxpZXMuaW5kZXhPZihhbm9tYWx5SWQpO1xuXG4gIGxldCBlbmFibGU6IGJvb2xlYW4gPSAocG9zICE9PSAtMSk7XG4gIGN0eC5yZXNwb25zZS5ib2R5ID0geyBlbmFibGUgfTtcbiAgXG59XG5cbmZ1bmN0aW9uIGNoYW5nZUFsZXJ0KGN0eDogUm91dGVyLklSb3V0ZXJDb250ZXh0KSB7XG5cbiAgbGV0IGFub21hbHlJZDogQW5vbWFseUlkID0gY3R4LnJlcXVlc3QuYm9keS5hbm9tYWx5X2lkO1xuICBsZXQgZW5hYmxlOiBib29sZWFuID0gY3R4LnJlcXVlc3QuYm9keS5lbmFibGU7XG5cbiAgbGV0IGFub21hbHkgPSBsb2FkQW5vbWFseUJ5SWQoYW5vbWFseUlkKVxuICBpZihhbm9tYWx5ID09IG51bGwpIHtcbiAgICBhbm9tYWx5SWQgPSBnZXRBbm9tYWx5SWRCeU5hbWUoYW5vbWFseUlkLnRvTG93ZXJDYXNlKCkpO1xuICB9XG5cbiAgbGV0IGFsZXJ0c0Fub21hbGllcyA9IGdldEFsZXJ0c0Fub21hbGllcygpO1xuICBsZXQgcG9zOiBudW1iZXIgPSBhbGVydHNBbm9tYWxpZXMuaW5kZXhPZihhbm9tYWx5SWQpO1xuICBpZihlbmFibGUgJiYgcG9zID09IC0xKSB7XG4gICAgYWxlcnRzQW5vbWFsaWVzLnB1c2goYW5vbWFseUlkKTtcbiAgICBzYXZlQWxlcnRzQW5vbWFsaWVzKGFsZXJ0c0Fub21hbGllcyk7XG4gIH0gZWxzZSBpZighZW5hYmxlICYmIHBvcyA+IC0xKSB7XG4gICAgYWxlcnRzQW5vbWFsaWVzLnNwbGljZShwb3MsIDEpO1xuICAgIHNhdmVBbGVydHNBbm9tYWxpZXMoYWxlcnRzQW5vbWFsaWVzKTtcbiAgfVxuICBjdHgucmVzcG9uc2UuYm9keSA9IHsgc3RhdHVzOiAnT0snIH07XG5cbn1cblxuZXhwb3J0IGNvbnN0IHJvdXRlciA9IG5ldyBSb3V0ZXIoKTtcblxucm91dGVyLmdldCgnLycsIGdldEFsZXJ0KTtcbnJvdXRlci5wb3N0KCcvJywgY2hhbmdlQWxlcnQpO1xuXG4iLCJpbXBvcnQgKiBhcyBSb3V0ZXIgZnJvbSAna29hLXJvdXRlcic7XG5cbmltcG9ydCB7XG4gIERhdGFzb3VyY2UsXG4gIE1ldHJpYyxcbiAgQW5vbWFseSxcbiAgc2F2ZUFub21hbHksXG4gIGluc2VydEFub21hbHksIHJlbW92ZUFub21hbHksIGxvYWRBbm9tYWx5QnlOYW1lLCBsb2FkQW5vbWFseUJ5SWQsIGdldEFub21hbHlJZEJ5TmFtZVxufSBmcm9tICcuLi9zZXJ2aWNlcy9hbm9tYWx5VHlwZSc7XG5pbXBvcnQgeyBydW5MZWFybmluZyB9IGZyb20gJy4uL3NlcnZpY2VzL2FuYWx5dGljcydcbmltcG9ydCB7IHNhdmVUYXJnZXRzIH0gZnJvbSAnLi4vc2VydmljZXMvbWV0cmljcyc7XG5cbmFzeW5jIGZ1bmN0aW9uIHNlbmRBbm9tYWx5VHlwZVN0YXR1cyhjdHg6IFJvdXRlci5JUm91dGVyQ29udGV4dCkge1xuICBsZXQgaWQgPSBjdHgucmVxdWVzdC5xdWVyeS5pZDtcbiAgbGV0IG5hbWUgPSBjdHgucmVxdWVzdC5xdWVyeS5uYW1lO1xuICB0cnkge1xuICAgIGxldCBhbm9tYWx5OiBBbm9tYWx5O1xuICAgIGlmKGlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGFub21hbHkgPSBsb2FkQW5vbWFseUJ5SWQoaWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhbm9tYWx5ID0gbG9hZEFub21hbHlCeU5hbWUobmFtZSk7XG4gICAgfVxuICAgIGlmKGFub21hbHkgPT09IG51bGwpIHtcbiAgICAgIGN0eC5yZXNwb25zZS5zdGF0dXMgPSA0MDQ7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmKGFub21hbHkuc3RhdHVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gc3RhdHVzIGZvciAnICsgbmFtZSk7XG4gICAgfVxuICAgIGN0eC5yZXNwb25zZS5ib2R5ID0geyBzdGF0dXM6IGFub21hbHkuc3RhdHVzLCBlcnJvck1lc3NhZ2U6IGFub21hbHkuZXJyb3IgfTtcbiAgfSBjYXRjaChlKSB7XG4gICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAvLyBUT0RPOiBiZXR0ZXIgc2VuZCA0MDQgd2hlbiB3ZSBrbm93IHRoYW4gaXNuYHQgZm91bmRcbiAgICBjdHgucmVzcG9uc2Uuc3RhdHVzID0gNTAwO1xuICAgIGN0eC5yZXNwb25zZS5ib2R5ID0geyBlcnJvcjogJ0NhbmB0IHJldHVybiBhbnl0aGluZycgfTtcbiAgfVxuXG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldEFub21hbHkoY3R4OiBSb3V0ZXIuSVJvdXRlckNvbnRleHQpIHtcbiAgdHJ5IHtcbiAgICBsZXQgaWQgPSBjdHgucmVxdWVzdC5xdWVyeS5pZDtcbiAgICBsZXQgbmFtZSA9IGN0eC5yZXF1ZXN0LnF1ZXJ5Lm5hbWU7XG5cbiAgICBsZXQgYW5vbWFseTpBbm9tYWx5O1xuICAgIGlmKGlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGFub21hbHkgPSBsb2FkQW5vbWFseUJ5SWQoaWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhbm9tYWx5ID0gbG9hZEFub21hbHlCeU5hbWUobmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgICB9XG4gICAgaWYoYW5vbWFseSA9PT0gbnVsbCkge1xuICAgICAgY3R4LnJlc3BvbnNlLnN0YXR1cyA9IDQwNDtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjdHgucmVzcG9uc2UuYm9keSA9IHtcbiAgICAgIG5hbWU6IGFub21hbHkubmFtZSxcbiAgICAgIG1ldHJpYzogYW5vbWFseS5tZXRyaWMsXG4gICAgICBzdGF0dXM6IGFub21hbHkuc3RhdHVzXG4gICAgfTtcbiAgfSBjYXRjaChlKSB7XG4gICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAvLyBUT0RPOiBiZXR0ZXIgc2VuZCA0MDQgd2hlbiB3ZSBrbm93IHRoYW4gaXNuYHQgZm91bmRcbiAgICBjdHgucmVzcG9uc2Uuc3RhdHVzID0gNTAwO1xuICAgIGN0eC5yZXNwb25zZS5ib2R5ID0gJ0NhbmB0IGdldCBhbnl0aGluZyc7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gY3JlYXRlQW5vbWFseShjdHg6IFJvdXRlci5JUm91dGVyQ29udGV4dCkge1xuICB0cnkge1xuICAgIGxldCBib2R5ID0gY3R4LnJlcXVlc3QuYm9keTtcbiAgICBjb25zdCBtZXRyaWM6TWV0cmljID0ge1xuICAgICAgZGF0YXNvdXJjZTogYm9keS5tZXRyaWMuZGF0YXNvdXJjZSxcbiAgICAgIHRhcmdldHM6IHNhdmVUYXJnZXRzKGJvZHkubWV0cmljLnRhcmdldHMpXG4gICAgfTtcblxuICAgIGNvbnN0IGFub21hbHk6QW5vbWFseSA9IHtcbiAgICAgIG5hbWU6IGJvZHkubmFtZSxcbiAgICAgIHBhbmVsVXJsOiBib2R5LnBhbmVsVXJsLFxuICAgICAgcGF0dGVybjogYm9keS5wYXR0ZXJuLnRvTG93ZXJDYXNlKCksXG4gICAgICBtZXRyaWM6IG1ldHJpYyxcbiAgICAgIGRhdGFzb3VyY2U6IGJvZHkuZGF0YXNvdXJjZSxcbiAgICAgIHN0YXR1czogJ2xlYXJuaW5nJyxcbiAgICAgIGxhc3RfcHJlZGljdGlvbl90aW1lOiAwLFxuICAgICAgbmV4dF9pZDogMFxuICAgIH07XG4gICAgbGV0IGFub21hbHlJZCA9IGluc2VydEFub21hbHkoYW5vbWFseSk7XG4gICAgaWYoYW5vbWFseUlkID09PSBudWxsKSB7XG4gICAgICBjdHgucmVzcG9uc2Uuc3RhdHVzID0gNDAzO1xuICAgICAgY3R4LnJlc3BvbnNlLmJvZHkgPSB7XG4gICAgICAgIGNvZGU6IDQwMyxcbiAgICAgICAgbWVzc2FnZTogJ0FscmVhZHkgZXhpc3RzJ1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBjdHgucmVzcG9uc2UuYm9keSA9IHsgYW5vbWFseV9pZDogYW5vbWFseUlkIH07XG5cbiAgICBydW5MZWFybmluZyhhbm9tYWx5SWQpO1xuICB9IGNhdGNoKGUpIHtcbiAgICBjdHgucmVzcG9uc2Uuc3RhdHVzID0gNTAwO1xuICAgIGN0eC5yZXNwb25zZS5ib2R5ID0ge1xuICAgICAgY29kZTogNTAwLFxuICAgICAgbWVzc2FnZTogJ0ludGVybmFsIGVycm9yJ1xuICAgIH07XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVsZXRlQW5vbWFseShjdHg6IFJvdXRlci5JUm91dGVyQ29udGV4dCkge1xuICB0cnkge1xuICAgIGxldCBpZCA9IGN0eC5yZXF1ZXN0LnF1ZXJ5LmlkO1xuICAgIGxldCBuYW1lID0gY3R4LnJlcXVlc3QucXVlcnkubmFtZTtcblxuICAgIGlmKGlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJlbW92ZUFub21hbHkoaWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZW1vdmVBbm9tYWx5KG5hbWUudG9Mb3dlckNhc2UoKSk7XG4gICAgfVxuICAgIFxuICAgIGN0eC5yZXNwb25zZS5ib2R5ID0ge1xuICAgICAgY29kZTogMjAwLFxuICAgICAgbWVzc2FnZTogJ1N1Y2Nlc3MnXG4gICAgfTtcbiAgfSBjYXRjaChlKSB7XG4gICAgY3R4LnJlc3BvbnNlLnN0YXR1cyA9IDUwMDtcbiAgICBjdHgucmVzcG9uc2UuYm9keSA9IHtcbiAgICAgIGNvZGU6IDUwMCxcbiAgICAgIG1lc3NhZ2U6ICdJbnRlcm5hbCBlcnJvcidcbiAgICB9O1xuICB9XG59XG5cblxuZXhwb3J0IHZhciByb3V0ZXIgPSBuZXcgUm91dGVyKCk7XG5cbnJvdXRlci5nZXQoJy9zdGF0dXMnLCBzZW5kQW5vbWFseVR5cGVTdGF0dXMpO1xucm91dGVyLmdldCgnLycsIGdldEFub21hbHkpO1xucm91dGVyLnBvc3QoJy8nLCBjcmVhdGVBbm9tYWx5KTtcbnJvdXRlci5kZWxldGUoJy8nLCBkZWxldGVBbm9tYWx5KTtcbiIsImltcG9ydCAqIGFzIFJvdXRlciBmcm9tICdrb2Etcm91dGVyJztcblxuaW1wb3J0IHtcbiAgZ2V0TGFiZWxlZFNlZ21lbnRzLFxuICBpbnNlcnRTZWdtZW50cyxcbiAgcmVtb3ZlU2VnbWVudHMsXG59IGZyb20gJy4uL3NlcnZpY2VzL3NlZ21lbnRzJztcblxuaW1wb3J0IHtcbiAgQW5vbWFseSwgQW5vbWFseUlkLCBnZXRBbm9tYWx5SWRCeU5hbWUsIGxvYWRBbm9tYWx5QnlJZFxufSBmcm9tICcuLi9zZXJ2aWNlcy9hbm9tYWx5VHlwZSc7XG5cbmltcG9ydCB7IHJ1bkxlYXJuaW5nIH0gZnJvbSAnLi4vc2VydmljZXMvYW5hbHl0aWNzJztcblxuXG5hc3luYyBmdW5jdGlvbiBzZW5kU2VnbWVudHMoY3R4OiBSb3V0ZXIuSVJvdXRlckNvbnRleHQpIHtcblxuICBsZXQgYW5vbWFseUlkOiBBbm9tYWx5SWQgPSBjdHgucmVxdWVzdC5xdWVyeS5hbm9tYWx5X2lkO1xuICBsZXQgYW5vbWFseTpBbm9tYWx5ID0gbG9hZEFub21hbHlCeUlkKGFub21hbHlJZCk7XG4gIGlmKGFub21hbHkgPT09IG51bGwpIHtcbiAgICBhbm9tYWx5SWQgPSBnZXRBbm9tYWx5SWRCeU5hbWUoYW5vbWFseUlkKTtcbiAgfVxuXG4gIGxldCBsYXN0U2VnbWVudElkID0gY3R4LnJlcXVlc3QucXVlcnkubGFzdF9zZWdtZW50O1xuICBsZXQgdGltZUZyb20gPSBjdHgucmVxdWVzdC5xdWVyeS5mcm9tO1xuICBsZXQgdGltZVRvID0gY3R4LnJlcXVlc3QucXVlcnkudG87XG5cbiAgbGV0IHNlZ21lbnRzID0gZ2V0TGFiZWxlZFNlZ21lbnRzKGFub21hbHlJZCk7XG5cbiAgLy8gSWQgZmlsdGVyaW5nXG4gIGlmKGxhc3RTZWdtZW50SWQgIT09IHVuZGVmaW5lZCkge1xuICAgIHNlZ21lbnRzID0gc2VnbWVudHMuZmlsdGVyKGVsID0+IGVsLmlkID4gbGFzdFNlZ21lbnRJZCk7XG4gIH1cblxuICAvLyBUaW1lIGZpbHRlcmluZ1xuICBpZih0aW1lRnJvbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgc2VnbWVudHMgPSBzZWdtZW50cy5maWx0ZXIoZWwgPT4gZWwuZmluaXNoID4gdGltZUZyb20pO1xuICB9XG5cbiAgaWYodGltZVRvICE9PSB1bmRlZmluZWQpIHtcbiAgICBzZWdtZW50cyA9IHNlZ21lbnRzLmZpbHRlcihlbCA9PiBlbC5zdGFydCA8IHRpbWVUbyk7XG4gIH1cblxuICBjdHgucmVzcG9uc2UuYm9keSA9IHsgc2VnbWVudHMgfVxuXG59XG5cbmFzeW5jIGZ1bmN0aW9uIHVwZGF0ZVNlZ21lbnRzKGN0eDogUm91dGVyLklSb3V0ZXJDb250ZXh0KSB7XG4gIHRyeSB7XG4gICAgbGV0IHNlZ21lbnRzVXBkYXRlID0gY3R4LnJlcXVlc3QuYm9keTtcblxuICAgIGxldCBhbm9tYWx5SWQgPSBzZWdtZW50c1VwZGF0ZS5hbm9tYWx5X2lkO1xuICAgIGxldCBhbm9tYWx5TmFtZSA9IHNlZ21lbnRzVXBkYXRlLm5hbWU7XG5cbiAgICBpZihhbm9tYWx5SWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgYW5vbWFseUlkID0gZ2V0QW5vbWFseUlkQnlOYW1lKGFub21hbHlOYW1lLnRvTG93ZXJDYXNlKCkpO1xuICAgIH1cblxuICAgIGxldCBhZGRlZElkcyA9IGluc2VydFNlZ21lbnRzKGFub21hbHlJZCwgc2VnbWVudHNVcGRhdGUuYWRkZWRfc2VnbWVudHMsIHRydWUpO1xuICAgIHJlbW92ZVNlZ21lbnRzKGFub21hbHlJZCwgc2VnbWVudHNVcGRhdGUucmVtb3ZlZF9zZWdtZW50cyk7XG5cbiAgICBjdHgucmVzcG9uc2UuYm9keSA9IHsgYWRkZWRfaWRzOiBhZGRlZElkcyB9O1xuXG4gICAgcnVuTGVhcm5pbmcoYW5vbWFseUlkKTtcbiAgfSBjYXRjaChlKSB7XG4gICAgY3R4LnJlc3BvbnNlLnN0YXR1cyA9IDUwMDtcbiAgICBjdHgucmVzcG9uc2UuYm9keSA9IHtcbiAgICAgIGNvZGU6IDUwMCxcbiAgICAgIG1lc3NhZ2U6ICdJbnRlcm5hbCBlcnJvcidcbiAgICB9O1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCByb3V0ZXIgPSBuZXcgUm91dGVyKCk7XG5cbnJvdXRlci5nZXQoJy8nLCBzZW5kU2VnbWVudHMpO1xucm91dGVyLnBhdGNoKCcvJywgdXBkYXRlU2VnbWVudHMpO1xuIiwiaW1wb3J0IHsgZ2V0SnNvbkRhdGFTeW5jLCB3cml0ZUpzb25EYXRhU3luYyB9IGZyb20gJy4vanNvbic7XG5pbXBvcnQgeyBBbm9tYWx5SWQgfSBmcm9tICcuL2Fub21hbHlUeXBlJztcbmltcG9ydCB7IHJ1blByZWRpY3QgfSBmcm9tICcuL2FuYWx5dGljcyc7XG5pbXBvcnQgeyBzZW5kTm90aWZpY2F0aW9uIH0gZnJvbSAnLi9ub3RpZmljYXRpb24nO1xuaW1wb3J0IHsgZ2V0TGFiZWxlZFNlZ21lbnRzIH0gZnJvbSAnLi9zZWdtZW50cyc7XG5cbmltcG9ydCB7IEFOT01BTElFU19QQVRIIH0gZnJvbSAnLi4vY29uZmlnJztcblxuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcblxuXG5cbmNvbnN0IEFMRVJUU19EQl9QQVRIID0gcGF0aC5qb2luKEFOT01BTElFU19QQVRILCBgYWxlcnRzX2Fub21hbGllcy5qc29uYCk7XG5cbmZ1bmN0aW9uIGdldEFsZXJ0c0Fub21hbGllcygpOiBBbm9tYWx5SWRbXSB7XG4gIGlmKCFmcy5leGlzdHNTeW5jKEFMRVJUU19EQl9QQVRIKSkge1xuICAgIHNhdmVBbGVydHNBbm9tYWxpZXMoW10pO1xuICB9XG4gIHJldHVybiBnZXRKc29uRGF0YVN5bmMoQUxFUlRTX0RCX1BBVEgpO1xufVxuXG5mdW5jdGlvbiBzYXZlQWxlcnRzQW5vbWFsaWVzKGFub21hbGllczogQW5vbWFseUlkW10pIHtcbiAgcmV0dXJuIHdyaXRlSnNvbkRhdGFTeW5jKEFMRVJUU19EQl9QQVRILCBhbm9tYWxpZXMpO1xufVxuXG5mdW5jdGlvbiBwcm9jZXNzQWxlcnRzKGFub21hbHlJZCkge1xuICBsZXQgc2VnbWVudHMgPSBnZXRMYWJlbGVkU2VnbWVudHMoYW5vbWFseUlkKTtcblxuICBjb25zdCBjdXJyZW50VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICBjb25zdCBhY3RpdmVBbGVydCA9IGFjdGl2ZUFsZXJ0cy5oYXMoYW5vbWFseUlkKTtcbiAgbGV0IG5ld0FjdGl2ZUFsZXJ0ID0gZmFsc2U7XG5cbiAgaWYoc2VnbWVudHMubGVuZ3RoID4gMCkge1xuICAgIGxldCBsYXN0U2VnbWVudCA9IHNlZ21lbnRzW3NlZ21lbnRzLmxlbmd0aCAtIDFdO1xuICAgIGlmKGxhc3RTZWdtZW50LmZpbmlzaCA+PSBjdXJyZW50VGltZSAtIGFsZXJ0VGltZW91dCkge1xuICAgICAgbmV3QWN0aXZlQWxlcnQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlmKCFhY3RpdmVBbGVydCAmJiBuZXdBY3RpdmVBbGVydCkge1xuICAgIGFjdGl2ZUFsZXJ0cy5hZGQoYW5vbWFseUlkKTtcbiAgICBzZW5kTm90aWZpY2F0aW9uKGFub21hbHlJZCwgdHJ1ZSk7XG4gIH0gZWxzZSBpZihhY3RpdmVBbGVydCAmJiAhbmV3QWN0aXZlQWxlcnQpIHtcbiAgICBhY3RpdmVBbGVydHMuZGVsZXRlKGFub21hbHlJZCk7XG4gICAgc2VuZE5vdGlmaWNhdGlvbihhbm9tYWx5SWQsIGZhbHNlKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBhbGVydHNUaWNrKCkge1xuICBsZXQgYWxlcnRzQW5vbWFsaWVzID0gZ2V0QWxlcnRzQW5vbWFsaWVzKCk7XG4gIGZvciAobGV0IGFub21hbHlJZCBvZiBhbGVydHNBbm9tYWxpZXMpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgcnVuUHJlZGljdChhbm9tYWx5SWQpO1xuICAgICAgcHJvY2Vzc0FsZXJ0cyhhbm9tYWx5SWQpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgfVxuICB9XG4gIHNldFRpbWVvdXQoYWxlcnRzVGljaywgNTAwMCk7XG59XG5cbmNvbnN0IGFsZXJ0VGltZW91dCA9IDYwMDAwOyAvLyBtc1xuY29uc3QgYWN0aXZlQWxlcnRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5zZXRUaW1lb3V0KGFsZXJ0c1RpY2ssIDUwMDApO1xuXG5cbmV4cG9ydCB7IGdldEFsZXJ0c0Fub21hbGllcywgc2F2ZUFsZXJ0c0Fub21hbGllcyB9XG4iLCJpbXBvcnQge1xuICBBbm9tYWx5LFxuICBBbm9tYWx5SWQsIGdldEFub21hbHlUeXBlSW5mbyxcbiAgbG9hZEFub21hbHlCeUlkLFxuICBzZXRBbm9tYWx5UHJlZGljdGlvblRpbWUsXG4gIHNldEFub21hbHlTdGF0dXNcbn0gZnJvbSAnLi9hbm9tYWx5VHlwZSdcbmltcG9ydCB7IGdldFRhcmdldCB9IGZyb20gJy4vbWV0cmljcyc7XG5pbXBvcnQgeyBnZXRMYWJlbGVkU2VnbWVudHMsIGluc2VydFNlZ21lbnRzLCByZW1vdmVTZWdtZW50cyB9IGZyb20gJy4vc2VnbWVudHMnXG5pbXBvcnQgeyBBbmFseXRpY3NDb25uZWN0aW9uIH0gZnJvbSAnLi9hbmFseXRpY3NDb25uZWN0aW9uJ1xuXG5cbmNvbnN0IHRhc2tNYXAgPSB7fTtcbmxldCBuZXh0VGFza0lkID0gMDtcblxuY29uc3QgYW5hbHl0aWNzQ29ubmVjdGlvbiA9IG5ldyBBbmFseXRpY3NDb25uZWN0aW9uKG9uUmVzcG9uc2UpO1xuXG5mdW5jdGlvbiBvblJlc3BvbnNlKHJlc3BvbnNlOiBhbnkpIHtcbiAgbGV0IHRhc2tJZCA9IHJlc3BvbnNlLl9fdGFza19pZDtcbiAgbGV0IHN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cztcbiAgaWYoc3RhdHVzID09PSAnc3VjY2VzcycgfHwgc3RhdHVzID09PSAnZmFpbGVkJykge1xuICAgIGlmKHRhc2tJZCBpbiB0YXNrTWFwKSB7XG4gICAgICBsZXQgcmVzb2x2ZXIgPSB0YXNrTWFwW3Rhc2tJZF07XG4gICAgICByZXNvbHZlcihyZXNwb25zZSk7XG4gICAgICBkZWxldGUgdGFza01hcFt0YXNrSWRdO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBydW5UYXNrKHRhc2spOiBQcm9taXNlPGFueT4ge1xuICBsZXQgYW5vbWFseTogQW5vbWFseSA9IGxvYWRBbm9tYWx5QnlJZCh0YXNrLmFub21hbHlfaWQpO1xuICB0YXNrLm1ldHJpYyA9IHtcbiAgICBkYXRhc291cmNlOiBhbm9tYWx5Lm1ldHJpYy5kYXRhc291cmNlLFxuICAgIHRhcmdldHM6IGFub21hbHkubWV0cmljLnRhcmdldHMubWFwKHQgPT4gZ2V0VGFyZ2V0KHQpKVxuICB9O1xuXG4gIHRhc2suX190YXNrX2lkID0gbmV4dFRhc2tJZCsrO1xuICBhd2FpdCBhbmFseXRpY3NDb25uZWN0aW9uLnNlbmRNZXNzYWdlKHRhc2spO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgdGFza01hcFt0YXNrLl9fdGFza19pZF0gPSByZXNvbHZlO1xuICB9KVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuTGVhcm5pbmcoYW5vbWFseUlkOkFub21hbHlJZCkge1xuICBsZXQgc2VnbWVudHMgPSBnZXRMYWJlbGVkU2VnbWVudHMoYW5vbWFseUlkKTtcbiAgc2V0QW5vbWFseVN0YXR1cyhhbm9tYWx5SWQsICdsZWFybmluZycpO1xuICBsZXQgYW5vbWFseTpBbm9tYWx5ICA9IGxvYWRBbm9tYWx5QnlJZChhbm9tYWx5SWQpO1xuICBsZXQgcGF0dGVybiA9IGFub21hbHkucGF0dGVybjtcbiAgbGV0IHRhc2sgPSB7XG4gICAgdHlwZTogJ2xlYXJuJyxcbiAgICBhbm9tYWx5X2lkOiBhbm9tYWx5SWQsXG4gICAgcGF0dGVybixcbiAgICBzZWdtZW50czogc2VnbWVudHNcbiAgfTtcblxuICBsZXQgcmVzdWx0ID0gYXdhaXQgcnVuVGFzayh0YXNrKTtcblxuICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gJ3N1Y2Nlc3MnKSB7XG4gICAgc2V0QW5vbWFseVN0YXR1cyhhbm9tYWx5SWQsICdyZWFkeScpO1xuICAgIGluc2VydFNlZ21lbnRzKGFub21hbHlJZCwgcmVzdWx0LnNlZ21lbnRzLCBmYWxzZSk7XG4gICAgc2V0QW5vbWFseVByZWRpY3Rpb25UaW1lKGFub21hbHlJZCwgcmVzdWx0Lmxhc3RfcHJlZGljdGlvbl90aW1lKTtcbiAgfSBlbHNlIHtcbiAgICBzZXRBbm9tYWx5U3RhdHVzKGFub21hbHlJZCwgJ2ZhaWxlZCcsIHJlc3VsdC5lcnJvcik7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1blByZWRpY3QoYW5vbWFseUlkOkFub21hbHlJZCkge1xuICBsZXQgYW5vbWFseTpBbm9tYWx5ID0gbG9hZEFub21hbHlCeUlkKGFub21hbHlJZCk7XG4gIGxldCBwYXR0ZXJuID0gYW5vbWFseS5wYXR0ZXJuO1xuICBsZXQgdGFzayA9IHtcbiAgICB0eXBlOiAncHJlZGljdCcsXG4gICAgYW5vbWFseV9pZDogYW5vbWFseUlkLFxuICAgIHBhdHRlcm4sXG4gICAgbGFzdF9wcmVkaWN0aW9uX3RpbWU6IGFub21hbHkubGFzdF9wcmVkaWN0aW9uX3RpbWVcbiAgfTtcbiAgbGV0IHJlc3VsdCA9IGF3YWl0IHJ1blRhc2sodGFzayk7XG5cbiAgaWYocmVzdWx0LnN0YXR1cyA9PT0gJ2ZhaWxlZCcpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgLy8gTWVyZ2luZyBzZWdtZW50c1xuICBsZXQgc2VnbWVudHMgPSBnZXRMYWJlbGVkU2VnbWVudHMoYW5vbWFseUlkKTtcbiAgaWYoc2VnbWVudHMubGVuZ3RoID4gMCAmJiByZXN1bHQuc2VnbWVudHMubGVuZ3RoID4gMCkge1xuICAgIGxldCBsYXN0T2xkU2VnbWVudCA9IHNlZ21lbnRzW3NlZ21lbnRzLmxlbmd0aCAtIDFdO1xuICAgIGxldCBmaXJzdE5ld1NlZ21lbnQgPSByZXN1bHQuc2VnbWVudHNbMF07XG5cbiAgICBpZihmaXJzdE5ld1NlZ21lbnQuc3RhcnQgPD0gbGFzdE9sZFNlZ21lbnQuZmluaXNoKSB7XG4gICAgICByZXN1bHQuc2VnbWVudHNbMF0uc3RhcnQgPSBsYXN0T2xkU2VnbWVudC5zdGFydDtcbiAgICAgIHJlbW92ZVNlZ21lbnRzKGFub21hbHlJZCwgW2xhc3RPbGRTZWdtZW50LmlkXSk7XG4gICAgfVxuICB9XG5cbiAgaW5zZXJ0U2VnbWVudHMoYW5vbWFseUlkLCByZXN1bHQuc2VnbWVudHMsIGZhbHNlKTtcbiAgc2V0QW5vbWFseVByZWRpY3Rpb25UaW1lKGFub21hbHlJZCwgcmVzdWx0Lmxhc3RfcHJlZGljdGlvbl90aW1lKTtcbiAgcmV0dXJuIHJlc3VsdC5zZWdtZW50cztcbn0iLCJpbXBvcnQgeyBBTkFMWVRJQ1NfUEFUSCB9IGZyb20gJy4uL2NvbmZpZydcclxuXHJcbmltcG9ydCB7IHNwYXduLCBDaGlsZFByb2Nlc3MgfSBmcm9tICdjaGlsZF9wcm9jZXNzJ1xyXG5pbXBvcnQgeyBzcGxpdCwgbWFwU3luYyB9IGZyb20gJ2V2ZW50LXN0cmVhbSc7XHJcblxyXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XHJcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIEFuYWx5dGljc0Nvbm5lY3Rpb24ge1xyXG5cclxuICBwcml2YXRlIF9sZWFybldvcmtlcjogQ2hpbGRQcm9jZXNzO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9vblJlc3BvbnNlOiAocmVzcG9uc2U6IGFueSkgPT4gdm9pZCkge1xyXG4gICAgaWYoZnMuZXhpc3RzU3luYyhwYXRoLmpvaW4oQU5BTFlUSUNTX1BBVEgsICdkaXN0L3dvcmtlci93b3JrZXInKSkpIHtcclxuICAgICAgdGhpcy5fbGVhcm5Xb3JrZXIgPSBzcGF3bignZGlzdC93b3JrZXIvd29ya2VyJywgW10sIHsgY3dkOiBBTkFMWVRJQ1NfUEFUSCB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8gSWYgY29tcGlsZWQgYW5hbHl0aWNzIHNjcmlwdCBkb2Vzbid0IGV4aXN0IC0gZmFsbGJhY2sgdG8gcmVndWxhciBweXRob25cclxuICAgICAgdGhpcy5fbGVhcm5Xb3JrZXIgPSBzcGF3bigncHl0aG9uMycsIFsnd29ya2VyLnB5J10sIHsgY3dkOiBBTkFMWVRJQ1NfUEFUSCB9KVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX2xlYXJuV29ya2VyLnN0ZG91dC5waXBlKFxyXG4gICAgICBzcGxpdCgpKS5waXBlKG1hcFN5bmModGhpcy5fb25QaXBlTWVzc2FnZS5iaW5kKHRoaXMpKVxyXG4gICAgKTtcclxuICAgIHRoaXMuX2xlYXJuV29ya2VyLnN0ZGVyci5vbignZGF0YScsIGRhdGEgPT4gY29uc29sZS5lcnJvcihgd29ya2VyIHN0ZGVycjogJHtkYXRhfWApKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX29uUGlwZU1lc3NhZ2UoZGF0YSkge1xyXG4gICAgY29uc29sZS5sb2coYHdvcmtlciBzdGRvdXQ6ICR7ZGF0YX1gKTtcclxuICAgIGxldCByZXNwb25zZSA9IEpTT04ucGFyc2UoZGF0YSk7XHJcbiAgICB0aGlzLl9vblJlc3BvbnNlKHJlc3BvbnNlKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBhc3luYyBzZW5kTWVzc2FnZSh0YXNrOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIC8vIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcclxuICAgIGxldCBjb21tYW5kID0gSlNPTi5zdHJpbmdpZnkodGFzayk7XHJcbiAgICB0aGlzLl9sZWFybldvcmtlci5zdGRpbi53cml0ZShgJHtjb21tYW5kfVxcbmApO1xyXG4gICAgLy8gfSk7XHJcbiAgfVxyXG5cclxufVxyXG4iLCJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnXG5pbXBvcnQgeyBnZXRKc29uRGF0YVN5bmMsIHdyaXRlSnNvbkRhdGFTeW5jIH0gZnJvbSAnLi9qc29uJ1xuaW1wb3J0IHsgQU5PTUFMSUVTX1BBVEggfSBmcm9tICcuLi9jb25maWcnXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcydcbmltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nO1xuXG5leHBvcnQgdHlwZSBEYXRhc291cmNlID0ge1xuICBtZXRob2Q6IHN0cmluZyxcbiAgZGF0YTogT2JqZWN0LFxuICBwYXJhbXM6IE9iamVjdCxcbiAgdHlwZTogc3RyaW5nLFxuICB1cmw6IHN0cmluZ1xufVxuXG5leHBvcnQgdHlwZSBNZXRyaWMgPSB7XG4gIGRhdGFzb3VyY2U6IHN0cmluZyxcbiAgdGFyZ2V0czogc3RyaW5nW11cbn1cblxuZXhwb3J0IHR5cGUgQW5vbWFseSA9IHtcbiAgbmFtZTogc3RyaW5nLFxuXG4gIHBhbmVsVXJsOiBzdHJpbmcsXG5cbiAgcGF0dGVybjogc3RyaW5nLFxuICBtZXRyaWM6IE1ldHJpYyxcbiAgZGF0YXNvdXJjZTogRGF0YXNvdXJjZVxuICBzdGF0dXM6IHN0cmluZyxcbiAgZXJyb3I/OiBzdHJpbmcsXG5cbiAgbGFzdF9wcmVkaWN0aW9uX3RpbWU6IG51bWJlcixcbiAgbmV4dF9pZDogbnVtYmVyXG59XG5cbmV4cG9ydCB0eXBlIEFub21hbHlJZCA9IHN0cmluZztcblxubGV0IGFub21hbGllc05hbWVUb0lkTWFwID0ge307XG5cbmZ1bmN0aW9uIGxvYWRBbm9tYWxpZXNNYXAoKSB7XG4gIGxldCBmaWxlbmFtZSA9IHBhdGguam9pbihBTk9NQUxJRVNfUEFUSCwgYGFsbF9hbm9tYWxpZXMuanNvbmApO1xuICBpZighZnMuZXhpc3RzU3luYyhmaWxlbmFtZSkpIHtcbiAgICBzYXZlQW5vbWFsaWVzTWFwKCk7XG4gIH1cbiAgYW5vbWFsaWVzTmFtZVRvSWRNYXAgPSBnZXRKc29uRGF0YVN5bmMoZmlsZW5hbWUpO1xufVxuXG5mdW5jdGlvbiBzYXZlQW5vbWFsaWVzTWFwKCkge1xuICBsZXQgZmlsZW5hbWUgPSBwYXRoLmpvaW4oQU5PTUFMSUVTX1BBVEgsIGBhbGxfYW5vbWFsaWVzLmpzb25gKTtcbiAgd3JpdGVKc29uRGF0YVN5bmMoZmlsZW5hbWUsIGFub21hbGllc05hbWVUb0lkTWFwKTtcbn1cblxuZnVuY3Rpb24gZ2V0QW5vbWFseUlkQnlOYW1lKGFub21hbHlOYW1lOnN0cmluZykgOiBBbm9tYWx5SWQge1xuICBsb2FkQW5vbWFsaWVzTWFwKCk7XG4gIGFub21hbHlOYW1lID0gYW5vbWFseU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgaWYoYW5vbWFseU5hbWUgaW4gYW5vbWFsaWVzTmFtZVRvSWRNYXApIHtcbiAgICByZXR1cm4gYW5vbWFsaWVzTmFtZVRvSWRNYXBbYW5vbWFseU5hbWVdO1xuICB9XG4gIHJldHVybiBhbm9tYWx5TmFtZTtcbn1cblxuZnVuY3Rpb24gaW5zZXJ0QW5vbWFseShhbm9tYWx5OiBBbm9tYWx5KSA6IEFub21hbHlJZCB7XG4gIGNvbnN0IGhhc2hTdHJpbmcgPSBhbm9tYWx5Lm5hbWUgKyAobmV3IERhdGUoKSkudG9TdHJpbmcoKTtcbiAgY29uc3QgYW5vbWFseUlkOkFub21hbHlJZCA9IGNyeXB0by5jcmVhdGVIYXNoKCdtZDUnKS51cGRhdGUoaGFzaFN0cmluZykuZGlnZXN0KCdoZXgnKTtcbiAgYW5vbWFsaWVzTmFtZVRvSWRNYXBbYW5vbWFseS5uYW1lXSA9IGFub21hbHlJZDtcbiAgc2F2ZUFub21hbGllc01hcCgpO1xuICAvLyByZXR1cm4gYW5vbWFseUlkXG4gIC8vIGNvbnN0IGFub21hbHlJZDpBbm9tYWx5SWQgPSBhbm9tYWx5Lm5hbWU7XG4gIGxldCBmaWxlbmFtZSA9IHBhdGguam9pbihBTk9NQUxJRVNfUEFUSCwgYCR7YW5vbWFseUlkfS5qc29uYCk7XG4gIGlmKGZzLmV4aXN0c1N5bmMoZmlsZW5hbWUpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgc2F2ZUFub21hbHkoYW5vbWFseUlkLCBhbm9tYWx5KTtcbiAgcmV0dXJuIGFub21hbHlJZDtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlQW5vbWFseShhbm9tYWx5SWQ6QW5vbWFseUlkKSB7XG4gIGxldCBmaWxlbmFtZSA9IHBhdGguam9pbihBTk9NQUxJRVNfUEFUSCwgYCR7YW5vbWFseUlkfS5qc29uYCk7XG4gIGZzLnVubGlua1N5bmMoZmlsZW5hbWUpO1xufVxuXG5mdW5jdGlvbiBzYXZlQW5vbWFseShhbm9tYWx5SWQ6IEFub21hbHlJZCwgYW5vbWFseTogQW5vbWFseSkge1xuICBsZXQgZmlsZW5hbWUgPSBwYXRoLmpvaW4oQU5PTUFMSUVTX1BBVEgsIGAke2Fub21hbHlJZH0uanNvbmApO1xuICByZXR1cm4gd3JpdGVKc29uRGF0YVN5bmMoZmlsZW5hbWUsIGFub21hbHkpO1xufVxuXG5mdW5jdGlvbiBsb2FkQW5vbWFseUJ5SWQoYW5vbWFseUlkOiBBbm9tYWx5SWQpIDogQW5vbWFseSB7XG4gIGxldCBmaWxlbmFtZSA9IHBhdGguam9pbihBTk9NQUxJRVNfUEFUSCwgYCR7YW5vbWFseUlkfS5qc29uYCk7XG4gIGlmKCFmcy5leGlzdHNTeW5jKGZpbGVuYW1lKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBnZXRKc29uRGF0YVN5bmMoZmlsZW5hbWUpO1xufVxuXG5mdW5jdGlvbiBsb2FkQW5vbWFseUJ5TmFtZShhbm9tYWx5TmFtZTogc3RyaW5nKSA6IEFub21hbHkge1xuICBsZXQgYW5vbWFseUlkID0gZ2V0QW5vbWFseUlkQnlOYW1lKGFub21hbHlOYW1lKTtcbiAgcmV0dXJuIGxvYWRBbm9tYWx5QnlJZChhbm9tYWx5SWQpO1xufVxuXG5mdW5jdGlvbiBzYXZlQW5vbWFseVR5cGVJbmZvKGluZm8pIHtcbiAgY29uc29sZS5sb2coJ1NhdmluZycpO1xuICBsZXQgZmlsZW5hbWUgPSBwYXRoLmpvaW4oQU5PTUFMSUVTX1BBVEgsIGAke2luZm8ubmFtZX0uanNvbmApO1xuICBpZihpbmZvLm5leHRfaWQgPT09IHVuZGVmaW5lZCkge1xuICAgIGluZm8ubmV4dF9pZCA9IDA7XG4gIH1cbiAgaWYoaW5mby5sYXN0X3ByZWRpY3Rpb25fdGltZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpbmZvLmxhc3RfcHJlZGljdGlvbl90aW1lID0gMDtcbiAgfVxuXG4gIHJldHVybiB3cml0ZUpzb25EYXRhU3luYyhmaWxlbmFtZSwgaW5mbyk7XG59XG5cbmZ1bmN0aW9uIGdldEFub21hbHlUeXBlSW5mbyhuYW1lKSB7XG4gIHJldHVybiBnZXRKc29uRGF0YVN5bmMocGF0aC5qb2luKEFOT01BTElFU19QQVRILCBgJHtuYW1lfS5qc29uYCkpO1xufVxuXG5mdW5jdGlvbiBzZXRBbm9tYWx5U3RhdHVzKGFub21hbHlJZDpBbm9tYWx5SWQsIHN0YXR1czpzdHJpbmcsIGVycm9yPzpzdHJpbmcpIHtcbiAgbGV0IGluZm8gPSBsb2FkQW5vbWFseUJ5SWQoYW5vbWFseUlkKTtcbiAgaW5mby5zdGF0dXMgPSBzdGF0dXM7XG4gIGlmKGVycm9yICE9PSB1bmRlZmluZWQpIHtcbiAgICBpbmZvLmVycm9yID0gZXJyb3I7XG4gIH0gZWxzZSB7XG4gICAgaW5mby5lcnJvciA9ICcnO1xuICB9XG4gIHNhdmVBbm9tYWx5KGFub21hbHlJZCwgaW5mbyk7XG59XG5cbmZ1bmN0aW9uIHNldEFub21hbHlQcmVkaWN0aW9uVGltZShhbm9tYWx5SWQ6QW5vbWFseUlkLCBsYXN0UHJlZGljdGlvblRpbWU6bnVtYmVyKSB7XG4gIGxldCBpbmZvID0gbG9hZEFub21hbHlCeUlkKGFub21hbHlJZCk7XG4gIGluZm8ubGFzdF9wcmVkaWN0aW9uX3RpbWUgPSBsYXN0UHJlZGljdGlvblRpbWU7XG4gIHNhdmVBbm9tYWx5KGFub21hbHlJZCwgaW5mbyk7XG59XG5cbmV4cG9ydCB7XG4gIHNhdmVBbm9tYWx5LCBsb2FkQW5vbWFseUJ5SWQsIGxvYWRBbm9tYWx5QnlOYW1lLCBpbnNlcnRBbm9tYWx5LCByZW1vdmVBbm9tYWx5LCBzYXZlQW5vbWFseVR5cGVJbmZvLFxuICBnZXRBbm9tYWx5VHlwZUluZm8sIGdldEFub21hbHlJZEJ5TmFtZSwgc2V0QW5vbWFseVN0YXR1cywgc2V0QW5vbWFseVByZWRpY3Rpb25UaW1lXG59XG4iLCJpbXBvcnQgKiBhcyBjb25maWcgZnJvbSAnLi4vY29uZmlnJ1xyXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XHJcblxyXG5cclxuLy8gc2VlIGFuYWx5dGljcy9wYXR0ZXJuX2RldGVjdGlvbl9tb2RlbC5weSB3aXRoIGZvbGRlcnMgYXZhaWxhYmxlXHJcblxyXG5mdW5jdGlvbiBtYXliZUNyZWF0ZShwYXRoOiBzdHJpbmcpOiB2b2lkIHtcclxuICBpZihmcy5leGlzdHNTeW5jKHBhdGgpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG4gIGZzLm1rZGlyU3luYyhwYXRoKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrRGF0YUZvbGRlcnMoKTogdm9pZCB7XHJcbiAgdmFyIGZvbGRlcnMgPSBbXHJcbiAgICBjb25maWcuREFUQV9QQVRILFxyXG4gICAgY29uZmlnLkRBVEFTRVRTX1BBVEgsXHJcbiAgICBjb25maWcuQU5PTUFMSUVTX1BBVEgsXHJcbiAgICBjb25maWcuTU9ERUxTX1BBVEgsXHJcbiAgICBjb25maWcuTUVUUklDU19QQVRILFxyXG4gICAgY29uZmlnLlNFR01FTlRTX1BBVEhcclxuICBdLmZvckVhY2gobWF5YmVDcmVhdGUpO1xyXG59XHJcbiIsImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcblxuYXN5bmMgZnVuY3Rpb24gZ2V0SnNvbkRhdGEoZmlsZW5hbWU6IHN0cmluZyk6IFByb21pc2U8T2JqZWN0PiB7XG4gIHZhciBkYXRhID0gYXdhaXQgbmV3IFByb21pc2U8c3RyaW5nPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgZnMucmVhZEZpbGUoZmlsZW5hbWUsICd1dGY4JywgKGVyciwgZGF0YSkgPT4ge1xuICAgICAgaWYoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgcmVqZWN0KCdDYW5gdCByZWFkIGZpbGUnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc29sdmUoZGF0YSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoZGF0YSk7XG4gIH0gY2F0Y2goZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdXcm9uZyBmaWxlIGZvcm1hdCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHdyaXRlSnNvbkRhdGEoZmlsZW5hbWU6IHN0cmluZywgZGF0YTogT2JqZWN0KSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgZnMud3JpdGVGaWxlKGZpbGVuYW1lLCBKU09OLnN0cmluZ2lmeShkYXRhKSwgJ3V0ZjgnLCAoZXJyKSA9PiB7XG4gICAgICBpZihlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICByZWplY3QoJ0NhdGB0IHdyaXRlIGZpbGUnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSlcbn1cblxuZnVuY3Rpb24gZ2V0SnNvbkRhdGFTeW5jKGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgbGV0IGRhdGEgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZW5hbWUsICd1dGY4Jyk7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoZGF0YSk7XG4gIH0gY2F0Y2goZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdXcm9uZyBmaWxlIGZvcm1hdCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHdyaXRlSnNvbkRhdGFTeW5jKGZpbGVuYW1lOiBzdHJpbmcsIGRhdGE6IE9iamVjdCkge1xuICBmcy53cml0ZUZpbGVTeW5jKGZpbGVuYW1lLCBKU09OLnN0cmluZ2lmeShkYXRhKSk7XG59XG5cbmV4cG9ydCB7XG4gIGdldEpzb25EYXRhLFxuICB3cml0ZUpzb25EYXRhLFxuICBnZXRKc29uRGF0YVN5bmMsXG4gIHdyaXRlSnNvbkRhdGFTeW5jXG59XG4iLCJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgZ2V0SnNvbkRhdGFTeW5jLCB3cml0ZUpzb25EYXRhU3luYyB9ICBmcm9tICcuL2pzb24nO1xuaW1wb3J0IHsgTUVUUklDU19QQVRIIH0gZnJvbSAnLi4vY29uZmlnJztcbmltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nO1xuXG5mdW5jdGlvbiBzYXZlVGFyZ2V0cyh0YXJnZXRzKSB7XG4gIGxldCBtZXRyaWNzID0gW107XG4gIGZvciAobGV0IHRhcmdldCBvZiB0YXJnZXRzKSB7XG4gICAgbWV0cmljcy5wdXNoKHNhdmVUYXJnZXQodGFyZ2V0KSk7XG4gIH1cbiAgcmV0dXJuIG1ldHJpY3M7XG59XG5cbmZ1bmN0aW9uIHNhdmVUYXJnZXQodGFyZ2V0KSB7XG4gIC8vY29uc3QgbWQ1ID0gY3J5cHRvLmNyZWF0ZUhhc2goJ21kNScpXG4gIGNvbnN0IHRhcmdldElkID0gY3J5cHRvLmNyZWF0ZUhhc2goJ21kNScpLnVwZGF0ZShKU09OLnN0cmluZ2lmeSh0YXJnZXQpKS5kaWdlc3QoJ2hleCcpO1xuICBsZXQgZmlsZW5hbWUgPSBwYXRoLmpvaW4oTUVUUklDU19QQVRILCBgJHt0YXJnZXRJZH0uanNvbmApO1xuICB3cml0ZUpzb25EYXRhU3luYyhmaWxlbmFtZSwgdGFyZ2V0KTtcbiAgcmV0dXJuIHRhcmdldElkO1xufVxuXG5mdW5jdGlvbiBnZXRUYXJnZXQodGFyZ2V0SWQpIHtcbiAgbGV0IGZpbGVuYW1lID0gcGF0aC5qb2luKE1FVFJJQ1NfUEFUSCwgYCR7dGFyZ2V0SWR9Lmpzb25gKTtcbiAgcmV0dXJuIGdldEpzb25EYXRhU3luYyhmaWxlbmFtZSk7XG59XG5cbmV4cG9ydCB7IHNhdmVUYXJnZXRzLCBnZXRUYXJnZXQgfVxuIiwiaW1wb3J0IGF4aW9zIGZyb20gJ2F4aW9zJztcbmltcG9ydCB7IGxvYWRBbm9tYWx5QnlJZCB9IGZyb20gJy4vYW5vbWFseVR5cGUnO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2VuZE5vdGlmaWNhdGlvbihhbm9tYWx5SWQsIGFjdGl2ZSkge1xuICBsZXQgYW5vbWFseU5hbWUgPSBsb2FkQW5vbWFseUJ5SWQoYW5vbWFseUlkKS5uYW1lO1xuICBjb25zb2xlLmxvZygnTm90aWZpY2F0aW9uICcgKyBhbm9tYWx5TmFtZSk7XG5cbiAgbGV0IG5vdGlmaWNhdGlvbiA9IHtcbiAgICBhbm9tYWx5OiBhbm9tYWx5TmFtZSxcbiAgICBzdGF0dXM6ICcnXG4gIH07XG4gIGlmKGFjdGl2ZSkge1xuICAgIG5vdGlmaWNhdGlvbi5zdGF0dXMgPSAnYWxlcnQnO1xuICB9IGVsc2Uge1xuICAgIG5vdGlmaWNhdGlvbi5zdGF0dXMgPSAnT0snO1xuICB9XG5cbiAgbGV0IGVuZHBvaW50ID0gcHJvY2Vzcy5lbnYuSEFTVElDX0FMRVJUX0VORFBPSU5UO1xuICBpZihlbmRwb2ludCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc29sZS5lcnJvcihgQ2FuJ3Qgc2VuZCBhbGVydCwgZW52IEhBU1RJQ19BTEVSVF9FTkRQT0lOVCBpcyB1bmRlZmluZWRgKTtcbiAgICByZXR1cm47XG4gIH1cblxuICB0cnkge1xuICAgIHZhciBkYXRhID0gYXdhaXQgYXhpb3MucG9zdChlbmRwb2ludCwge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShub3RpZmljYXRpb24pXG4gICAgfSlcbiAgICBjb25zb2xlLmxvZyhkYXRhKTtcbiAgfSBjYXRjaChlcnIpIHtcbiAgICBjb25zb2xlLmVycm9yKGBDYW4ndCBzZW5kIGFsZXJ0IHRvICR7ZW5kcG9pbnR9LiBFcnJvcjogJHtlcnJ9YClcbiAgfVxuICBcbn1cblxuIiwiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IGdldEpzb25EYXRhU3luYywgd3JpdGVKc29uRGF0YVN5bmMgfSAgZnJvbSAnLi9qc29uJztcbmltcG9ydCB7IFNFR01FTlRTX1BBVEggfSBmcm9tICcuLi9jb25maWcnO1xuaW1wb3J0IHsgQW5vbWFseUlkLCBsb2FkQW5vbWFseUJ5SWQsIHNhdmVBbm9tYWx5IH0gZnJvbSAnLi9hbm9tYWx5VHlwZSc7XG5cbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcblxuZnVuY3Rpb24gZ2V0TGFiZWxlZFNlZ21lbnRzKGFub21hbHlJZDogQW5vbWFseUlkKSB7XG4gIGxldCBmaWxlbmFtZSA9IHBhdGguam9pbihTRUdNRU5UU19QQVRILCBgJHthbm9tYWx5SWR9X2xhYmVsZWQuanNvbmApO1xuXG4gIGxldCBzZWdtZW50cyA9IFtdO1xuICB0cnkge1xuICAgIHNlZ21lbnRzID0gZ2V0SnNvbkRhdGFTeW5jKGZpbGVuYW1lKTtcbiAgICBmb3IgKGxldCBzZWdtZW50IG9mIHNlZ21lbnRzKSB7XG4gICAgICBpZiAoc2VnbWVudC5sYWJlbGVkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc2VnbWVudC5sYWJlbGVkID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5lcnJvcihlLm1lc3NhZ2UpO1xuICB9XG4gIHJldHVybiBzZWdtZW50cztcbn1cblxuZnVuY3Rpb24gZ2V0UHJlZGljdGVkU2VnbWVudHMoYW5vbWFseUlkOiBBbm9tYWx5SWQpIHtcbiAgbGV0IGZpbGVuYW1lID0gcGF0aC5qb2luKFNFR01FTlRTX1BBVEgsIGAke2Fub21hbHlJZH1fc2VnbWVudHMuanNvbmApO1xuXG4gIGxldCBqc29uRGF0YTtcbiAgdHJ5IHtcbiAgICBqc29uRGF0YSA9IGdldEpzb25EYXRhU3luYyhmaWxlbmFtZSk7XG4gIH0gY2F0Y2goZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoZS5tZXNzYWdlKTtcbiAgICBqc29uRGF0YSA9IFtdO1xuICB9XG4gIHJldHVybiBqc29uRGF0YTtcbn1cblxuZnVuY3Rpb24gc2F2ZVNlZ21lbnRzKGFub21hbHlJZDogQW5vbWFseUlkLCBzZWdtZW50cykge1xuICBsZXQgZmlsZW5hbWUgPSBwYXRoLmpvaW4oU0VHTUVOVFNfUEFUSCwgYCR7YW5vbWFseUlkfV9sYWJlbGVkLmpzb25gKTtcblxuICB0cnkge1xuICAgIHJldHVybiB3cml0ZUpzb25EYXRhU3luYyhmaWxlbmFtZSwgXy51bmlxQnkoc2VnbWVudHMsICdzdGFydCcpKTtcbiAgfSBjYXRjaChlKSB7XG4gICAgY29uc29sZS5lcnJvcihlLm1lc3NhZ2UpO1xuICAgIHRocm93IG5ldyBFcnJvcignQ2FuYHQgd3JpdGUgdG8gZGInKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnNlcnRTZWdtZW50cyhhbm9tYWx5SWQ6IEFub21hbHlJZCwgYWRkZWRTZWdtZW50cywgbGFiZWxlZDpib29sZWFuKSB7XG4gIC8vIFNldCBzdGF0dXNcbiAgbGV0IGluZm8gPSBsb2FkQW5vbWFseUJ5SWQoYW5vbWFseUlkKTtcbiAgbGV0IHNlZ21lbnRzID0gZ2V0TGFiZWxlZFNlZ21lbnRzKGFub21hbHlJZCk7XG5cbiAgbGV0IG5leHRJZCA9IGluZm8ubmV4dF9pZDtcbiAgbGV0IGFkZGVkSWRzID0gW11cbiAgZm9yIChsZXQgc2VnbWVudCBvZiBhZGRlZFNlZ21lbnRzKSB7XG4gICAgc2VnbWVudC5pZCA9IG5leHRJZDtcbiAgICBzZWdtZW50LmxhYmVsZWQgPSBsYWJlbGVkO1xuICAgIGFkZGVkSWRzLnB1c2gobmV4dElkKTtcbiAgICBuZXh0SWQrKztcbiAgICBzZWdtZW50cy5wdXNoKHNlZ21lbnQpO1xuICB9XG4gIGluZm8ubmV4dF9pZCA9IG5leHRJZDtcbiAgc2F2ZVNlZ21lbnRzKGFub21hbHlJZCwgc2VnbWVudHMpO1xuICBzYXZlQW5vbWFseShhbm9tYWx5SWQsIGluZm8pO1xuICByZXR1cm4gYWRkZWRJZHM7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZVNlZ21lbnRzKGFub21hbHlJZDogQW5vbWFseUlkLCByZW1vdmVkU2VnbWVudHMpIHtcbiAgbGV0IHNlZ21lbnRzID0gZ2V0TGFiZWxlZFNlZ21lbnRzKGFub21hbHlJZCk7XG4gIGZvciAobGV0IHNlZ21lbnRJZCBvZiByZW1vdmVkU2VnbWVudHMpIHtcbiAgICBzZWdtZW50cyA9IHNlZ21lbnRzLmZpbHRlcihlbCA9PiBlbC5pZCAhPT0gc2VnbWVudElkKTtcbiAgfVxuICBzYXZlU2VnbWVudHMoYW5vbWFseUlkLCBzZWdtZW50cyk7XG59XG5cbmV4cG9ydCB7IGdldExhYmVsZWRTZWdtZW50cywgZ2V0UHJlZGljdGVkU2VnbWVudHMsIHNhdmVTZWdtZW50cywgaW5zZXJ0U2VnbWVudHMsIHJlbW92ZVNlZ21lbnRzIH1cbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnYXhpb3MnKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJ2NyeXB0bycpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnZXZlbnQtc3RyZWFtJyk7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdmcycpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgna29hJyk7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdrb2EtYm9keXBhcnNlcicpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgna29hLXJvdXRlcicpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnbG9kYXNoJyk7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdwYXRoJyk7Il0sInNvdXJjZVJvb3QiOiIifQ== \ No newline at end of file diff --git a/server/src/index.ts b/server/src/index.ts index 38fd74f..6b51639 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -30,14 +30,14 @@ rootRouter.use('/anomalies', anomaliesRouter.routes(), anomaliesRouter.allowedMe rootRouter.use('/segments', segmentsRouter.routes(), segmentsRouter.allowedMethods()); rootRouter.use('/alerts', alertsRouter.routes(), alertsRouter.allowedMethods()); rootRouter.get('/', async (ctx) => { - ctx.response.body = { status: 'Ok ok' }; + ctx.response.body = { status: 'Ok' }; }); app .use(rootRouter.routes()) - .use(rootRouter.allowedMethods()) + .use(rootRouter.allowedMethods()); app.listen(HASTIC_PORT, () => { - console.log(`Server is running on :${HASTIC_PORT}`) + console.log(`Server is running on :${HASTIC_PORT}`); }); diff --git a/server/src/services/analytics.ts b/server/src/services/analytics.ts index c0f4c09..52185af 100644 --- a/server/src/services/analytics.ts +++ b/server/src/services/analytics.ts @@ -1,5 +1,3 @@ -import { spawn } from 'child_process' -import { ANALYTICS_PATH } from '../config' import { Anomaly, AnomalyId, getAnomalyTypeInfo, @@ -8,33 +6,18 @@ import { setAnomalyStatus } from './anomalyType' import { getTarget } from './metrics'; -import { getLabeledSegments, insertSegments, removeSegments } from './segments'; -import { split, mapSync } from 'event-stream'; -import * as fs from 'fs'; -import * as path from 'path'; +import { getLabeledSegments, insertSegments, removeSegments } from './segments' +import { AnalyticsConnection } from './analyticsConnection' -var learnWorker; -if(fs.existsSync(path.join(ANALYTICS_PATH, 'dist/worker/worker'))) { - learnWorker = spawn('dist/worker/worker', [], { cwd: ANALYTICS_PATH }) -} else { - // If compiled analytics script doesn't exist - fallback to regular python - learnWorker = spawn('python3', ['worker.py'], { cwd: ANALYTICS_PATH }) -} -learnWorker.stdout.pipe(split()).pipe(mapSync(onMessage)); - -learnWorker.stderr.on('data', data => console.error(`worker stderr: ${data}`)); const taskMap = {}; let nextTaskId = 0; -function onMessage(data) { - console.log(`worker stdout: ${data}`); - let response = JSON.parse(data); +const analyticsConnection = new AnalyticsConnection(onResponse); + +function onResponse(response: any) { let taskId = response.__task_id; - // let anomalyName = response.anomaly_name; - // let task = response.task; let status = response.status; - if(status === 'success' || status === 'failed') { if(taskId in taskMap) { let resolver = taskMap[taskId]; @@ -44,22 +27,22 @@ function onMessage(data) { } } -function runTask(task) : Promise { - let anomaly:Anomaly = loadAnomalyById(task.anomaly_id); +async function runTask(task): Promise { + let anomaly: Anomaly = loadAnomalyById(task.anomaly_id); task.metric = { datasource: anomaly.metric.datasource, targets: anomaly.metric.targets.map(t => getTarget(t)) }; task.__task_id = nextTaskId++; - let command = JSON.stringify(task) - learnWorker.stdin.write(`${command}\n`); - return new Promise((resolve, reject) => { - taskMap[task.__task_id] = resolve + await analyticsConnection.sendMessage(task); + + return new Promise((resolve, reject) => { + taskMap[task.__task_id] = resolve; }) } -async function runLearning(anomalyId:AnomalyId) { +export async function runLearning(anomalyId:AnomalyId) { let segments = getLabeledSegments(anomalyId); setAnomalyStatus(anomalyId, 'learning'); let anomaly:Anomaly = loadAnomalyById(anomalyId); @@ -82,7 +65,7 @@ async function runLearning(anomalyId:AnomalyId) { } } -async function runPredict(anomalyId:AnomalyId) { +export async function runPredict(anomalyId:AnomalyId) { let anomaly:Anomaly = loadAnomalyById(anomalyId); let pattern = anomaly.pattern; let task = { @@ -111,6 +94,4 @@ async function runPredict(anomalyId:AnomalyId) { insertSegments(anomalyId, result.segments, false); setAnomalyPredictionTime(anomalyId, result.last_prediction_time); return result.segments; -} - -export { runLearning, runPredict } +} \ No newline at end of file diff --git a/server/src/services/analyticsConnection.ts b/server/src/services/analyticsConnection.ts new file mode 100644 index 0000000..bb28b39 --- /dev/null +++ b/server/src/services/analyticsConnection.ts @@ -0,0 +1,41 @@ +import { ANALYTICS_PATH } from '../config' + +import { spawn, ChildProcess } from 'child_process' +import { split, mapSync } from 'event-stream'; + +import * as fs from 'fs'; +import * as path from 'path'; + + +export class AnalyticsConnection { + + private _learnWorker: ChildProcess; + + constructor(private _onResponse: (response: any) => void) { + if(fs.existsSync(path.join(ANALYTICS_PATH, 'dist/worker/worker'))) { + this._learnWorker = spawn('dist/worker/worker', [], { cwd: ANALYTICS_PATH }) + } else { + // If compiled analytics script doesn't exist - fallback to regular python + this._learnWorker = spawn('python3', ['worker.py'], { cwd: ANALYTICS_PATH }) + } + + this._learnWorker.stdout.pipe( + split()).pipe(mapSync(this._onPipeMessage.bind(this)) + ); + this._learnWorker.stderr.on('data', data => console.error(`worker stderr: ${data}`)); + } + + private _onPipeMessage(data) { + console.log(`worker stdout: ${data}`); + let response = JSON.parse(data); + this._onResponse(response); + } + + public async sendMessage(task: any): Promise { + // return Promise.resolve().then(() => { + let command = JSON.stringify(task); + this._learnWorker.stdin.write(`${command}\n`); + // }); + } + +}