UNPKG

io.parrots

Version:

Parrots.io App

727 lines (726 loc) 64.9 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import * as tslib_1 from "tslib"; import { Injectable, Inject } from '@angular/core'; import { Http, RequestOptions } from '@angular/http'; import { CONNECTION_DATA } from 'com.phloxui'; import { BackgroundProcessManager } from 'com.phloxui'; import { ConnectionManager } from 'com.phloxui'; import { ParrotsDefaultConnectionManager } from '../share/ParrotsDefaultConnectionManager'; import { TEST_MODE, TEST_DATA } from '../test'; var /** @type {?} */ RUNNING = 'RUNNING'; var /** @type {?} */ BASE_URL = 'http://10.1.0.22/api'; var /** @type {?} */ TEST_INSTANCE_ID = 'TEST'; /** * <p style="text-indent: 2em;"> * A <code>ng</code> service class implementing [[InstanceConnectionManager]] service interface. Please see [[InstanceConnectionManager]] for more details. * </p> * * @author shiorin, tee4cute */ var InstanceConnectionManager = /** @class */ (function () { function InstanceConnectionManager(connectionManager, http, bgProcessMgr, testMode, testData) { this.seletedInstanceId = ""; this.http = http; this.bgProcessMgr = bgProcessMgr; this.connectionManager = connectionManager; this.instanceConnectionManagerMap = {}; this.testMode = testMode; this.testData = testData; // if (testMode) { this.seletedInstanceId = TEST_INSTANCE_ID; this.instanceConnectionManagerMap[this.seletedInstanceId] = new ParrotsDefaultConnectionManager(null, this.http, this.bgProcessMgr, testMode, testData); // } } /** * @param {?} instanceUUID * @return {?} */ InstanceConnectionManager.prototype.getNodes = /** * @param {?} instanceUUID * @return {?} */ function (instanceUUID) { if (this.connectionManager !== null && typeof this.connectionManager !== 'undefined') { var /** @type {?} */ url = BASE_URL + "/instance/" + instanceUUID + "/node"; var /** @type {?} */ requestOptionsArgs = new RequestOptions(); return this.connectionManager.getWithHttpInfo(url, requestOptionsArgs); } else { return Promise.reject(null); } }; /** * ## setup instance: generate connectionManager by instanceUUID and cache in map * @param {?} instanceUUID * @param {?=} loginData * @return {?} */ InstanceConnectionManager.prototype.setUpInstance = /** * ## setup instance: generate connectionManager by instanceUUID and cache in map * @param {?} instanceUUID * @param {?=} loginData * @return {?} */ function (instanceUUID, loginData) { var _this = this; return new Promise(function (resolve, reject) { _this.getNodes(instanceUUID).then(function (res) { var /** @type {?} */ itemNodes = JSON.parse(res._body).items; var /** @type {?} */ runnintMode = false; var _loop_1 = function (itemNode) { if (itemNode.status === RUNNING) { runnintMode = true; var /** @type {?} */ conMgr_1 = new ParrotsDefaultConnectionManager(null, _this.http, _this.bgProcessMgr, _this.testMode, _this.testData); conMgr_1.setName(itemNode._uuid); //Set for test. var /** @type {?} */ url = itemNode.serverNode.hostName == "localhost" ? "http://10.1.0.22" : itemNode.serverNode.hostName; url += ":" + itemNode.servicePort + "/api"; conMgr_1.addBaseURLs(url); if (loginData !== undefined) { url += "/user/login"; _this.connectionManager.postWithHttpInfo(url, loginData, new RequestOptions()).then(function (res) { var /** @type {?} */ sessionId = JSON.parse((/** @type {?} */ (res))._body).sessionId; conMgr_1.setDefaultHeader('Session-Id', sessionId); _this.instanceConnectionManagerMap[instanceUUID] = conMgr_1; resolve(itemNodes); }).catch(function (error) { _this.instanceConnectionManagerMap[instanceUUID] = conMgr_1; reject(error); }); } else { _this.instanceConnectionManagerMap[instanceUUID] = conMgr_1; } } }; try { for (var itemNodes_1 = tslib_1.__values(itemNodes), itemNodes_1_1 = itemNodes_1.next(); !itemNodes_1_1.done; itemNodes_1_1 = itemNodes_1.next()) { var itemNode = itemNodes_1_1.value; _loop_1(itemNode); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (itemNodes_1_1 && !itemNodes_1_1.done && (_a = itemNodes_1.return)) _a.call(itemNodes_1); } finally { if (e_1) throw e_1.error; } } if (loginData === undefined) { if (runnintMode) { resolve(itemNodes); } reject(itemNodes); } var e_1, _a; }).catch(function (error) { reject(error); }); }); }; /** * ## setup instances: generate connectionManager by instanceUUIDs and cache in map * @param {?} instances * @return {?} */ InstanceConnectionManager.prototype.setUpInstances = /** * ## setup instances: generate connectionManager by instanceUUIDs and cache in map * @param {?} instances * @return {?} */ function (instances) { if (instances === undefined || instances === null) { return Promise.resolve([]); } var /** @type {?} */ proms = []; for (var /** @type {?} */ instanceUUID in instances) { if (instanceUUID === null || instanceUUID === undefined) { continue; } proms.push(this.setUpInstance(instanceUUID, instances[instanceUUID])); } return Promise.all(proms); }; /** * ## remove instance by instanceUUID from map * @param {?} instanceUUID * @return {?} */ InstanceConnectionManager.prototype.tearDownInstance = /** * ## remove instance by instanceUUID from map * @param {?} instanceUUID * @return {?} */ function (instanceUUID) { delete this.instanceConnectionManagerMap[instanceUUID]; }; /** * ## remove instance instanceUUID from map * @param {?=} instanceUUID * @return {?} */ InstanceConnectionManager.prototype.getInstanceConnectionManager = /** * ## remove instance instanceUUID from map * @param {?=} instanceUUID * @return {?} */ function (instanceUUID) { if (instanceUUID !== undefined && instanceUUID !== null && instanceUUID !== '') { return this.instanceConnectionManagerMap[instanceUUID]; } if (this.seletedInstanceId === undefined || this.seletedInstanceId === null) { return null; } return this.instanceConnectionManagerMap[this.seletedInstanceId]; }; /** * @param {?} instanceUUID * @return {?} */ InstanceConnectionManager.prototype.selectInstance = /** * @param {?} instanceUUID * @return {?} */ function (instanceUUID) { this.seletedInstanceId = instanceUUID; }; /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.get = /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ function (url, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().get(url, requestOptionsArgs); }; /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.getWithHttpInfo = /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ function (url, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().getWithHttpInfo(url, requestOptionsArgs); }; /** * @param {?} url * @param {?} body * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.post = /** * @param {?} url * @param {?} body * @param {?} requestOptionsArgs * @return {?} */ function (url, body, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().post(url, body, requestOptionsArgs); }; /** * @param {?} url * @param {?} body * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.postWithHttpInfo = /** * @param {?} url * @param {?} body * @param {?} requestOptionsArgs * @return {?} */ function (url, body, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().postWithHttpInfo(url, body, requestOptionsArgs); }; /** * @param {?} url * @param {?} body * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.put = /** * @param {?} url * @param {?} body * @param {?} requestOptionsArgs * @return {?} */ function (url, body, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().put(url, body, requestOptionsArgs); }; /** * @param {?} url * @param {?} body * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.putWithHttpInfo = /** * @param {?} url * @param {?} body * @param {?} requestOptionsArgs * @return {?} */ function (url, body, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().putWithHttpInfo(url, body, requestOptionsArgs); }; /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.delete = /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ function (url, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().delete(url, requestOptionsArgs); }; /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.deleteWithHttpInfo = /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ function (url, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().deleteWithHttpInfo(url, requestOptionsArgs); }; /** * @param {?} url * @param {?} body * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.patch = /** * @param {?} url * @param {?} body * @param {?} requestOptionsArgs * @return {?} */ function (url, body, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().patch(url, body, requestOptionsArgs); }; /** * @param {?} url * @param {?} body * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.patchWithHttpInfo = /** * @param {?} url * @param {?} body * @param {?} requestOptionsArgs * @return {?} */ function (url, body, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().patchWithHttpInfo(url, body, requestOptionsArgs); }; /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.head = /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ function (url, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().head(url, requestOptionsArgs); }; /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.headWithHttpInfo = /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ function (url, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().headWithHttpInfo(url, requestOptionsArgs); }; /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.options = /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ function (url, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().options(url, requestOptionsArgs); }; /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.optionsWithHttpInfo = /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ function (url, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().optionsWithHttpInfo(url, requestOptionsArgs); }; /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.request = /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ function (url, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().request(url, requestOptionsArgs); }; /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ InstanceConnectionManager.prototype.requestWithHttpInfo = /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ function (url, requestOptionsArgs) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { return Promise.reject('Connection Manager is not setup yet.'); } return this.getInstanceConnectionManager().requestWithHttpInfo(url, requestOptionsArgs); }; /** * @return {?} */ InstanceConnectionManager.prototype.getRunningProcessesCount = /** * @return {?} */ function () { if (this.seletedInstanceId === null || this.seletedInstanceId === undefined) { return null; } if (this.bgProcessMgr != null && typeof this.bgProcessMgr !== 'undefined') { this.bgProcessMgr.getRunningProcessesCount(CONNECTION_DATA, this.seletedInstanceId); } return 0; }; /** * @return {?} */ InstanceConnectionManager.prototype.getRunningProcesses = /** * @return {?} */ function () { if (this.seletedInstanceId === null || this.seletedInstanceId === undefined) { return null; } if (this.bgProcessMgr != null && typeof this.bgProcessMgr !== 'undefined') { this.bgProcessMgr.getRunningProcesses(CONNECTION_DATA, this.seletedInstanceId); } return []; }; /** * @return {?} */ InstanceConnectionManager.prototype.getConnectionQuality = /** * @return {?} */ function () { // TODO return this.connectionManager.getConnectionQuality(); }; /** * @param {?} urls * @return {?} */ InstanceConnectionManager.prototype.setBaseURLs = /** * @param {?} urls * @return {?} */ function (urls) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().setBaseURLs(urls); }; /** * @return {?} */ InstanceConnectionManager.prototype.resetBaseURLs = /** * @return {?} */ function () { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().resetBaseURLs(); }; /** * @param {?} key * @param {?} value * @return {?} */ InstanceConnectionManager.prototype.setDefaultHeader = /** * @param {?} key * @param {?} value * @return {?} */ function (key, value) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().setDefaultHeader(key, value); }; /** * @param {?} key * @return {?} */ InstanceConnectionManager.prototype.removeDefaultHeader = /** * @param {?} key * @return {?} */ function (key) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().removeDefaultHeader(key); }; /** * @return {?} */ InstanceConnectionManager.prototype.resetDefaultHeaders = /** * @return {?} */ function () { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().resetDefaultHeaders(); }; /** * @param {?} key * @param {?} value * @return {?} */ InstanceConnectionManager.prototype.setSearch = /** * @param {?} key * @param {?} value * @return {?} */ function (key, value) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().setSearch(key, value); }; /** * @param {?} key * @return {?} */ InstanceConnectionManager.prototype.removeSearch = /** * @param {?} key * @return {?} */ function (key) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().removeSearch(key); }; /** * @return {?} */ InstanceConnectionManager.prototype.resetSearch = /** * @return {?} */ function () { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().resetSearch(); }; /** * @param {?} key * @param {?} value * @return {?} */ InstanceConnectionManager.prototype.setParam = /** * @param {?} key * @param {?} value * @return {?} */ function (key, value) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().setParam(key, value); }; /** * @param {?} key * @return {?} */ InstanceConnectionManager.prototype.removeParam = /** * @param {?} key * @return {?} */ function (key) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().removeParam(key); }; /** * @return {?} */ InstanceConnectionManager.prototype.resetParams = /** * @return {?} */ function () { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().resetParams(); }; /** * @return {?} */ InstanceConnectionManager.prototype.getName = /** * @return {?} */ function () { return this.name; }; /** * @param {?} name * @return {?} */ InstanceConnectionManager.prototype.setName = /** * @param {?} name * @return {?} */ function (name) { this.name = name; if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().setName(name); }; /** * @template R * @param {?} type * @return {?} */ InstanceConnectionManager.prototype.createResource = /** * @template R * @param {?} type * @return {?} */ function (type) { return this.getInstanceConnectionManager().createResource(type); }; InstanceConnectionManager.decorators = [ { type: Injectable }, ]; /** @nocollapse */ InstanceConnectionManager.ctorParameters = function () { return [ { type: ConnectionManager, }, { type: Http, }, { type: BackgroundProcessManager, }, { type: undefined, decorators: [{ type: Inject, args: [TEST_MODE,] },] }, { type: undefined, decorators: [{ type: Inject, args: [TEST_DATA,] },] }, ]; }; return InstanceConnectionManager; }()); export { InstanceConnectionManager }; function InstanceConnectionManager_tsickle_Closure_declarations() { /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */ InstanceConnectionManager.decorators; /** * @nocollapse * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>} */ InstanceConnectionManager.ctorParameters; /** @type {?} */ InstanceConnectionManager.prototype.instanceConnectionManagerMap; /** @type {?} */ InstanceConnectionManager.prototype.connectionManager; /** @type {?} */ InstanceConnectionManager.prototype.http; /** @type {?} */ InstanceConnectionManager.prototype.bgProcessMgr; /** @type {?} */ InstanceConnectionManager.prototype.seletedInstanceId; /** @type {?} */ InstanceConnectionManager.prototype.name; /** @type {?} */ InstanceConnectionManager.prototype.testMode; /** @type {?} */ InstanceConnectionManager.prototype.testData; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vaW8ucGFycm90cy8iLCJzb3VyY2VzIjpbImxpYi9zZXJ2aWNlL0luc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxJQUFJLEVBQVksY0FBYyxFQUErQixNQUFNLGVBQWUsQ0FBQztBQUM1RixPQUFPLEVBQXNCLGVBQWUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsRSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDdkQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRWhELE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBQzNGLE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRS9DLHFCQUFNLE9BQU8sR0FBVyxTQUFTLENBQUM7QUFDbEMscUJBQU0sUUFBUSxHQUFXLHNCQUFzQixDQUFDO0FBQ2hELHFCQUFNLGdCQUFnQixHQUFXLE1BQU0sQ0FBQzs7Ozs7Ozs7O0lBc0J0QyxtQ0FBWSxpQkFBb0MsRUFBRSxJQUFVLEVBQUUsWUFBc0MsRUFBcUIsVUFBc0M7UUFFN0osSUFBSSxDQUFDLGlCQUFpQixHQUFHLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztRQUNqQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsaUJBQWlCLENBQUM7UUFDM0MsSUFBSSxDQUFDLDRCQUE0QixHQUFHLEVBQUUsQ0FBQztRQUV2QyxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJ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QU0sQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1NBQ2hEO1FBQ0QsSUFBSSxDQUFDLDRCQUE0QixFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDOzs7Ozs7O0lBRzdDLGtEQUFjOzs7OztjQUFtQyxJQUEyQztRQUNqRyxNQUFNLENBQUMsSUFBSSxDQUFDLDRCQUE0QixFQUFFLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDOzs7Z0JBNVhuRSxVQUFVOzs7O2dCQWpCRixpQkFBaUI7Z0JBSGpCLElBQUk7Z0JBRUosd0JBQXdCO2dEQThCd0UsTUFBTSxTQUFDLFNBQVM7Z0RBQXNCLE1BQU0sU0FBQyxTQUFTOztvQ0FqQy9KOztTQXNCYSx5QkFBeUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh0dHAsIFJlc3BvbnNlLCBSZXF1ZXN0T3B0aW9ucywgUmVxdWVzdE9wdGlvbnNBcmdzLCBIZWFkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvaHR0cCc7XG5pbXBvcnQgeyBJQ29ubmVjdGlvbk1hbmFnZXIsIENPTk5FQ1RJT05fREFUQSB9IGZyb20gJ2NvbS5waGxveHVpJztcbmltcG9ydCB7IEJhY2tncm91bmRQcm9jZXNzTWFuYWdlciB9IGZyb20gJ2NvbS5waGxveHVpJztcbmltcG9ydCB7IENvbm5lY3Rpb25NYW5hZ2VyIH0gZnJvbSAnY29tLnBobG94dWknO1xuaW1wb3J0IHsgQWJzdHJhY3RTZXJ2ZXJSZXNvdXJjZSB9IGZyb20gJ2NvbS5waGxveHVpJztcbmltcG9ydCB7IFBhcnJvdHNEZWZhdWx0Q29ubmVjdGlvbk1hbmFnZXIgfSBmcm9tICcuLi9zaGFyZS9QYXJyb3RzRGVmYXVsdENvbm5lY3Rpb25NYW5hZ2VyJztcbmltcG9ydCB7IFRFU1RfTU9ERSwgVEVTVF9EQVRBIH0gZnJvbSAnLi4vdGVzdCc7XG5cbmNvbnN0IFJVTk5JTkc6IHN0cmluZyA9ICdSVU5OSU5HJztcbmNvbnN0IEJBU0VfVVJMOiBzdHJpbmcgPSAnaHR0cDovLzEwLjEuMC4yMi9hcGknO1xuY29uc3QgVEVTVF9JTlNUQU5DRV9JRDogc3RyaW5nID0gJ1RFU1QnO1xuXG5cbi8qKlxuICogPHAgc3R5bGU9XCJ0ZXh0LWluZGVudDogMmVtO1wiPlxuICogQSA8Y29kZT5uZzwvY29kZT4gc2VydmljZSBjbGFzcyBpbXBsZW1lbnRpbmcgW1tJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyXV0gc2VydmljZSBpbnRlcmZhY2UuIFBsZWFzZSBzZWUgW1tJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyXV0gZm9yIG1vcmUgZGV0YWlscy5cbiAqIDwvcD5cbiAqXG4gKiBAYXV0aG9yIHNoaW9yaW4sIHRlZTRjdXRlXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyIGltcGxlbWVudHMgSUNvbm5lY3Rpb25NYW5hZ2VyIHtcblxuICBwcml2YXRlIGluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXJNYXA6IGFueTtcbiAgcHJpdmF0ZSBjb25uZWN0aW9uTWFuYWdlcjogQ29ubmVjdGlvbk1hbmFnZXI7XG4gIHByaXZhdGUgaHR0cDogSHR0cDtcbiAgcHJpdmF0ZSBiZ1Byb2Nlc3NNZ3I6IEJhY2tncm91bmRQcm9jZXNzTWFuYWdlcjtcbiAgcHJpdmF0ZSBzZWxldGVkSW5zdGFuY2VJZDogc3RyaW5nO1xuICBwcml2YXRlIG5hbWU6IHN0cmluZztcbiAgcHJpdmF0ZSB0ZXN0TW9kZTogYm9vbGVhbjtcbiAgcHJpdmF0ZSB0ZXN0RGF0YTogYW55O1xuXG4gIGNvbnN0cnVjdG9yKGNvbm5lY3Rpb25NYW5hZ2VyOiBDb25uZWN0aW9uTWFuYWdlciwgaHR0cDogSHR0cCwgYmdQcm9jZXNzTWdyOiBCYWNrZ3JvdW5kUHJvY2Vzc01hbmFnZXIsIEBJbmplY3QoVEVTVF9NT0RFKSB0ZXN0TW9kZTogYm9vbGVhbiwgQEluamVjdChURVNUX0RBVEEpIHRlc3REYXRhOiBhbnkpIHtcblxuICAgIHRoaXMuc2VsZXRlZEluc3RhbmNlSWQgPSBcIlwiO1xuICAgIHRoaXMuaHR0cCA9IGh0dHA7XG4gICAgdGhpcy5iZ1Byb2Nlc3NNZ3IgPSBiZ1Byb2Nlc3NNZ3I7XG4gICAgdGhpcy5jb25uZWN0aW9uTWFuYWdlciA9IGNvbm5lY3Rpb25NYW5hZ2VyO1xuICAgIHRoaXMuaW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlck1hcCA9IHt9O1xuXG4gICAgdGhpcy50ZXN0TW9kZSA9IHRlc3RNb2RlO1xuICAgIHRoaXMudGVzdERhdGEgPSB0ZXN0RGF0YTtcblxuICAgIC8vIGlmICh0ZXN0TW9kZSkge1xuICAgICAgdGhpcy5zZWxldGVkSW5zdGFuY2VJZCA9IFRFU1RfSU5TVEFOQ0VfSUQ7XG4gICAgICB0aGlzLmluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXJNYXBbdGhpcy5zZWxldGVkSW5zdGFuY2VJZF0gPSBuZXcgUGFycm90c0RlZmF1bHRDb25uZWN0aW9uTWFuYWdlcihudWxsLCB0aGlzLmh0dHAsIHRoaXMuYmdQcm9jZXNzTWdyLCB0ZXN0TW9kZSwgdGVzdERhdGEpO1xuICAgIC8vIH1cblxuICB9XG5cbiAgcHJpdmF0ZSBnZXROb2RlcyhpbnN0YW5jZVVVSUQ6IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKHRoaXMuY29ubmVjdGlvbk1hbmFnZXIgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMuY29ubmVjdGlvbk1hbmFnZXIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBsZXQgdXJsOiBhbnkgPSBCQVNFX1VSTCArIFwiL2luc3RhbmNlL1wiICsgaW5zdGFuY2VVVUlEICsgXCIvbm9kZVwiO1xuXG4gICAgICBsZXQgcmVxdWVzdE9wdGlvbnNBcmdzID0gbmV3IFJlcXVlc3RPcHRpb25zKCk7XG5cbiAgICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb25NYW5hZ2VyLmdldFdpdGhIdHRwSW5mbyh1cmwsIHJlcXVlc3RPcHRpb25zQXJncyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChudWxsKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogIyMgc2V0dXAgaW5zdGFuY2U6IGdlbmVyYXRlIGNvbm5lY3Rpb25NYW5hZ2VyIGJ5IGluc3RhbmNlVVVJRCBhbmQgY2FjaGUgaW4gbWFwXG4gICAqL1xuICBwdWJsaWMgc2V0VXBJbnN0YW5jZShpbnN0YW5jZVVVSUQ6IHN0cmluZywgbG9naW5EYXRhPzogYW55KTogUHJvbWlzZTxhbnk+IHtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmdldE5vZGVzKGluc3RhbmNlVVVJRCkudGhlbigocmVzKSA9PiB7XG4gICAgICAgIGxldCBpdGVtTm9kZXMgPSBKU09OLnBhcnNlKHJlcy5fYm9keSkuaXRlbXM7XG5cbiAgICAgICAgbGV0IHJ1bm5pbnRNb2RlID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGl0ZW1Ob2RlIG9mIGl0ZW1Ob2Rlcykge1xuICAgICAgICAgIGlmIChpdGVtTm9kZS5zdGF0dXMgPT09IFJVTk5JTkcpIHtcblxuICAgICAgICAgICAgcnVubmludE1vZGUgPSB0cnVlO1xuICAgICAgICAgICAgbGV0IGNvbk1nciA9IG5ldyBQYXJyb3RzRGVmYXVsdENvbm5lY3Rpb25NYW5hZ2VyKG51bGwsIHRoaXMuaHR0cCwgdGhpcy5iZ1Byb2Nlc3NNZ3IsIHRoaXMudGVzdE1vZGUsIHRoaXMudGVzdERhdGEpO1xuICAgICAgICAgICAgY29uTWdyLnNldE5hbWUoaXRlbU5vZGUuX3V1aWQpO1xuXG4gICAgICAgICAgICAvL1NldCBmb3IgdGVzdC5cbiAgICAgICAgICAgIGxldCB1cmw6IHN0cmluZyA9IGl0ZW1Ob2RlLnNlcnZlck5vZGUuaG9zdE5hbWUgPT0gXCJsb2NhbGhvc3RcIiA/IFwiaHR0cDovLzEwLjEuMC4yMlwiIDogaXRlbU5vZGUuc2VydmVyTm9kZS5ob3N0TmFtZTtcbiAgICAgICAgICAgIHVybCArPSBcIjpcIiArIGl0ZW1Ob2RlLnNlcnZpY2VQb3J0ICsgXCIvYXBpXCI7XG4gICAgICAgICAgICBjb25NZ3IuYWRkQmFzZVVSTHModXJsKTtcblxuICAgICAgICAgICAgaWYgKGxvZ2luRGF0YSAhPT0gdW5kZWZpbmVkKSB7XG5cbiAgICAgICAgICAgICAgdXJsICs9IFwiL3VzZXIvbG9naW5cIjtcbiAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uTWFuYWdlci5wb3N0V2l0aEh0dHBJbmZvKHVybCwgbG9naW5EYXRhLCBuZXcgUmVxdWVzdE9wdGlvbnMoKSkudGhlbigocmVzKSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IHNlc3Npb25JZCA9IEpTT04ucGFyc2UoKHJlcyBhcyBhbnkpLl9ib2R5KS5zZXNzaW9uSWQ7XG4gICAgICAgICAgICAgICAgY29uTWdyLnNldERlZmF1bHRIZWFkZXIoJ1Nlc3Npb24tSWQnLCBzZXNzaW9uSWQpO1xuICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlck1hcFtpbnN0YW5jZVVVSURdID0gY29uTWdyO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoaXRlbU5vZGVzKTtcbiAgICAgICAgICAgICAgfSkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyTWFwW2luc3RhbmNlVVVJRF0gPSBjb25NZ3I7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXJNYXBbaW5zdGFuY2VVVUlEXSA9IGNvbk1ncjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobG9naW5EYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAocnVubmludE1vZGUpIHtcbiAgICAgICAgICAgIHJlc29sdmUoaXRlbU5vZGVzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZWplY3QoaXRlbU5vZGVzKTtcbiAgICAgICAgfVxuXG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gIH1cblxuICAvKipcbiAgICogIyMgc2V0dXAgaW5zdGFuY2VzOiBnZW5lcmF0ZSBjb25uZWN0aW9uTWFuYWdlciBieSBpbnN0YW5jZVVVSURzIGFuZCBjYWNoZSBpbiBtYXBcbiAgICovXG4gIHB1YmxpYyBzZXRVcEluc3RhbmNlcyhpbnN0YW5jZXM6IHN0cmluZ1tdKTogUHJvbWlzZTxhbnlbXT4ge1xuXG4gICAgaWYgKGluc3RhbmNlcyA9PT0gdW5kZWZpbmVkIHx8IGluc3RhbmNlcyA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShbXSk7XG4gICAgfVxuXG4gICAgbGV0IHByb21zOiBQcm9taXNlPGFueT5bXSA9IFtdO1xuXG4gICAgZm9yIChsZXQgaW5zdGFuY2VVVUlEIGluIGluc3RhbmNlcykge1xuICAgICAgaWYgKGluc3RhbmNlVVVJRCA9PT0gbnVsbCB8fCBpbnN0YW5jZVVVSUQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgcHJvbXMucHVzaCh0aGlzLnNldFVwSW5zdGFuY2UoaW5zdGFuY2VVVUlELCBpbnN0YW5jZXNbaW5zdGFuY2VVVUlEXSkpO1xuICAgIH1cblxuICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9tcyk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiAjIyByZW1vdmUgaW5zdGFuY2UgYnkgaW5zdGFuY2VVVUlEIGZyb20gbWFwXG4gICAqL1xuICBwdWJsaWMgdGVhckRvd25JbnN0YW5jZShpbnN0YW5jZVVVSUQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGRlbGV0ZSB0aGlzLmluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXJNYXBbaW5zdGFuY2VVVUlEXTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyByZW1vdmUgaW5zdG