UNPKG

io.parrots

Version:

Parrots.io App

537 lines (536 loc) 58.7 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ 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'; const /** @type {?} */ RUNNING = 'RUNNING'; const /** @type {?} */ BASE_URL = 'http://10.1.0.22/api'; const /** @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 */ export class InstanceConnectionManager { /** * @param {?} connectionManager * @param {?} http * @param {?} bgProcessMgr * @param {?} testMode * @param {?} testData */ constructor(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 {?} */ getNodes(instanceUUID) { if (this.connectionManager !== null && typeof this.connectionManager !== 'undefined') { let /** @type {?} */ url = BASE_URL + "/instance/" + instanceUUID + "/node"; let /** @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 {?} */ setUpInstance(instanceUUID, loginData) { return new Promise((resolve, reject) => { this.getNodes(instanceUUID).then((res) => { let /** @type {?} */ itemNodes = JSON.parse(res._body).items; let /** @type {?} */ runnintMode = false; for (let /** @type {?} */ itemNode of itemNodes) { if (itemNode.status === RUNNING) { runnintMode = true; let /** @type {?} */ conMgr = new ParrotsDefaultConnectionManager(null, this.http, this.bgProcessMgr, this.testMode, this.testData); conMgr.setName(itemNode._uuid); //Set for test. let /** @type {?} */ url = itemNode.serverNode.hostName == "localhost" ? "http://10.1.0.22" : itemNode.serverNode.hostName; url += ":" + itemNode.servicePort + "/api"; conMgr.addBaseURLs(url); if (loginData !== undefined) { url += "/user/login"; this.connectionManager.postWithHttpInfo(url, loginData, new RequestOptions()).then((res) => { let /** @type {?} */ sessionId = JSON.parse((/** @type {?} */ (res))._body).sessionId; conMgr.setDefaultHeader('Session-Id', sessionId); this.instanceConnectionManagerMap[instanceUUID] = conMgr; resolve(itemNodes); }).catch((error) => { this.instanceConnectionManagerMap[instanceUUID] = conMgr; reject(error); }); } else { this.instanceConnectionManagerMap[instanceUUID] = conMgr; } } } if (loginData === undefined) { if (runnintMode) { resolve(itemNodes); } reject(itemNodes); } }).catch((error) => { reject(error); }); }); } /** * ## setup instances: generate connectionManager by instanceUUIDs and cache in map * @param {?} instances * @return {?} */ setUpInstances(instances) { if (instances === undefined || instances === null) { return Promise.resolve([]); } let /** @type {?} */ proms = []; for (let /** @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 {?} */ tearDownInstance(instanceUUID) { delete this.instanceConnectionManagerMap[instanceUUID]; } /** * ## remove instance instanceUUID from map * @param {?=} instanceUUID * @return {?} */ getInstanceConnectionManager(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 {?} */ selectInstance(instanceUUID) { this.seletedInstanceId = instanceUUID; } /** * @param {?} url * @param {?} requestOptionsArgs * @return {?} */ get(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 {?} */ getWithHttpInfo(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 {?} */ post(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 {?} */ postWithHttpInfo(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 {?} */ put(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 {?} */ putWithHttpInfo(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 {?} */ delete(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 {?} */ deleteWithHttpInfo(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 {?} */ patch(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 {?} */ patchWithHttpInfo(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 {?} */ head(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 {?} */ headWithHttpInfo(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 {?} */ options(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 {?} */ optionsWithHttpInfo(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 {?} */ request(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 {?} */ requestWithHttpInfo(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 {?} */ getRunningProcessesCount() { 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 {?} */ getRunningProcesses() { 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 {?} */ getConnectionQuality() { // TODO return this.connectionManager.getConnectionQuality(); } /** * @param {?} urls * @return {?} */ setBaseURLs(urls) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().setBaseURLs(urls); } /** * @return {?} */ resetBaseURLs() { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().resetBaseURLs(); } /** * @param {?} key * @param {?} value * @return {?} */ setDefaultHeader(key, value) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().setDefaultHeader(key, value); } /** * @param {?} key * @return {?} */ removeDefaultHeader(key) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().removeDefaultHeader(key); } /** * @return {?} */ resetDefaultHeaders() { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().resetDefaultHeaders(); } /** * @param {?} key * @param {?} value * @return {?} */ setSearch(key, value) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().setSearch(key, value); } /** * @param {?} key * @return {?} */ removeSearch(key) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().removeSearch(key); } /** * @return {?} */ resetSearch() { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().resetSearch(); } /** * @param {?} key * @param {?} value * @return {?} */ setParam(key, value) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().setParam(key, value); } /** * @param {?} key * @return {?} */ removeParam(key) { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().removeParam(key); } /** * @return {?} */ resetParams() { if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) { throw ('Connection Manager is not setup yet.'); } this.getInstanceConnectionManager().resetParams(); } /** * @return {?} */ getName() { return this.name; } /** * @param {?} name * @return {?} */ setName(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 {?} */ createResource(type) { return this.getInstanceConnectionManager().createResource(type); } } InstanceConnectionManager.decorators = [ { type: Injectable }, ]; /** @nocollapse */ InstanceConnectionManager.ctorParameters = () => [ { type: ConnectionManager, }, { type: Http, }, { type: BackgroundProcessManager, }, { type: undefined, decorators: [{ type: Inject, args: [TEST_MODE,] },] }, { type: undefined, decorators: [{ type: Inject, args: [TEST_DATA,] },] }, ]; 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vaW8ucGFycm90cy8iLCJzb3VyY2VzIjpbImxpYi9zZXJ2aWNlL0luc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLElBQUksRUFBWSxjQUFjLEVBQStCLE1BQU0sZUFBZSxDQUFDO0FBQzVGLE9BQU8sRUFBc0IsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xFLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN2RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFaEQsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDM0YsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFL0MsdUJBQU0sT0FBTyxHQUFXLFNBQVMsQ0FBQztBQUNsQyx1QkFBTSxRQUFRLEdBQVcsc0JBQXNCLENBQUM7QUFDaEQsdUJBQU0sZ0JBQWdCLEdBQVcsTUFBTSxDQUFDOzs7Ozs7OztBQVd4QyxNQUFNOzs7Ozs7OztJQVdKLFlBQVksaUJBQW9DLEVBQUUsSUFBVSxFQUFFLFlBQXNDLEVBQXFCLFVBQXNDO1FBRTdKLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7UUFDakMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLGlCQUFpQixDQUFDO1FBQzNDLElBQUksQ0FBQyw0QkFBNEIsR0FBRyxFQUFFLENBQUM7UUFFdkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFR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QyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7Ozs7WUE1WG5FLFVBQVU7Ozs7WUFqQkYsaUJBQWlCO1lBSGpCLElBQUk7WUFFSix3QkFBd0I7NENBOEJ3RSxNQUFNLFNBQUMsU0FBUzs0Q0FBc0IsTUFBTSxTQUFDLFNBQVMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh0dHAsIFJlc3BvbnNlLCBSZXF1ZXN0T3B0aW9ucywgUmVxdWVzdE9wdGlvbnNBcmdzLCBIZWFkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvaHR0cCc7XG5pbXBvcnQgeyBJQ29ubmVjdGlvbk1hbmFnZXIsIENPTk5FQ1RJT05fREFUQSB9IGZyb20gJ2NvbS5waGxveHVpJztcbmltcG9ydCB7IEJhY2tncm91bmRQcm9jZXNzTWFuYWdlciB9IGZyb20gJ2NvbS5waGxveHVpJztcbmltcG9ydCB7IENvbm5lY3Rpb25NYW5hZ2VyIH0gZnJvbSAnY29tLnBobG94dWknO1xuaW1wb3J0IHsgQWJzdHJhY3RTZXJ2ZXJSZXNvdXJjZSB9IGZyb20gJ2NvbS5waGxveHVpJztcbmltcG9ydCB7IFBhcnJvdHNEZWZhdWx0Q29ubmVjdGlvbk1hbmFnZXIgfSBmcm9tICcuLi9zaGFyZS9QYXJyb3RzRGVmYXVsdENvbm5lY3Rpb25NYW5hZ2VyJztcbmltcG9ydCB7IFRFU1RfTU9ERSwgVEVTVF9EQVRBIH0gZnJvbSAnLi4vdGVzdCc7XG5cbmNvbnN0IFJVTk5JTkc6IHN0cmluZyA9ICdSVU5OSU5HJztcbmNvbnN0IEJBU0VfVVJMOiBzdHJpbmcgPSAnaHR0cDovLzEwLjEuMC4yMi9hcGknO1xuY29uc3QgVEVTVF9JTlNUQU5DRV9JRDogc3RyaW5nID0gJ1RFU1QnO1xuXG5cbi8qKlxuICogPHAgc3R5bGU9XCJ0ZXh0LWluZGVudDogMmVtO1wiPlxuICogQSA8Y29kZT5uZzwvY29kZT4gc2VydmljZSBjbGFzcyBpbXBsZW1lbnRpbmcgW1tJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyXV0gc2VydmljZSBpbnRlcmZhY2UuIFBsZWFzZSBzZWUgW1tJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyXV0gZm9yIG1vcmUgZGV0YWlscy5cbiAqIDwvcD5cbiAqXG4gKiBAYXV0aG9yIHNoaW9yaW4sIHRlZTRjdXRlXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyIGltcGxlbWVudHMgSUNvbm5lY3Rpb25NYW5hZ2VyIHtcblxuICBwcml2YXRlIGluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXJNYXA6IGFueTtcbiAgcHJpdmF0ZSBjb25uZWN0aW9uTWFuYWdlcjogQ29ubmVjdGlvbk1hbmFnZXI7XG4gIHByaXZhdGUgaHR0cDogSHR0cDtcbiAgcHJpdmF0ZSBiZ1Byb2Nlc3NNZ3I6IEJhY2tncm91bmRQcm9jZXNzTWFuYWdlcjtcbiAgcHJpdmF0ZSBzZWxldGVkSW5zdGFuY2VJZDogc3RyaW5nO1xuICBwcml2YXRlIG5hbWU6IHN0cmluZztcbiAgcHJpdmF0ZSB0ZXN0TW9kZTogYm9vbGVhbjtcbiAgcHJpdmF0ZSB0ZXN0RGF0YTogYW55O1xuXG4gIGNvbnN0cnVjdG9yKGNvbm5lY3Rpb25NYW5hZ2VyOiBDb25uZWN0aW9uTWFuYWdlciwgaHR0cDogSHR0cCwgYmdQcm9jZXNzTWdyOiBCYWNrZ3JvdW5kUHJvY2Vzc01hbmFnZXIsIEBJbmplY3QoVEVTVF9NT0RFKSB0ZXN0TW9kZTogYm9vbGVhbiwgQEluamVjdChURVNUX0RBVEEpIHRlc3REYXRhOiBhbnkpIHtcblxuICAgIHRoaXMuc2VsZXRlZEluc3RhbmNlSWQgPSBcIlwiO1xuICAgIHRoaXMuaHR0cCA9IGh0dHA7XG4gICAgdGhpcy5iZ1Byb2Nlc3NNZ3IgPSBiZ1Byb2Nlc3NNZ3I7XG4gICAgdGhpcy5jb25uZWN0aW9uTWFuYWdlciA9IGNvbm5lY3Rpb25NYW5hZ2VyO1xuICAgIHRoaXMuaW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlck1hcCA9IHt9O1xuXG4gICAgdGhpcy50ZXN0TW9kZSA9IHRlc3RNb2RlO1xuICAgIHRoaXMudGVzdERhdGEgPSB0ZXN0RGF0YTtcblxuICAgIC8vIGlmICh0ZXN0TW9kZSkge1xuICAgICAgdGhpcy5zZWxldGVkSW5zdGFuY2VJZCA9IFRFU1RfSU5TVEFOQ0VfSUQ7XG4gICAgICB0aGlzLmluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXJNYXBbdGhpcy5zZWxldGVkSW5zdGFuY2VJZF0gPSBuZXcgUGFycm90c0RlZmF1bHRDb25uZWN0aW9uTWFuYWdlcihudWxsLCB0aGlzLmh0dHAsIHRoaXMuYmdQcm9jZXNzTWdyLCB0ZXN0TW9kZSwgdGVzdERhdGEpO1xuICAgIC8vIH1cblxuICB9XG5cbiAgcHJpdmF0ZSBnZXROb2RlcyhpbnN0YW5jZVVVSUQ6IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKHRoaXMuY29ubmVjdGlvbk1hbmFnZXIgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMuY29ubmVjdGlvbk1hbmFnZXIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBsZXQgdXJsOiBhbnkgPSBCQVNFX1VSTCArIFwiL2luc3RhbmNlL1wiICsgaW5zdGFuY2VVVUlEICsgXCIvbm9kZVwiO1xuXG4gICAgICBsZXQgcmVxdWVzdE9wdGlvbnNBcmdzID0gbmV3IFJlcXVlc3RPcHRpb25zKCk7XG5cbiAgICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb25NYW5hZ2VyLmdldFdpdGhIdHRwSW5mbyh1cmwsIHJlcXVlc3RPcHRpb25zQXJncyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChudWxsKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogIyMgc2V0dXAgaW5zdGFuY2U6IGdlbmVyYXRlIGNvbm5lY3Rpb25NYW5hZ2VyIGJ5IGluc3RhbmNlVVVJRCBhbmQgY2FjaGUgaW4gbWFwXG4gICAqL1xuICBwdWJsaWMgc2V0VXBJbnN0YW5jZShpbnN0YW5jZVVVSUQ6IHN0cmluZywgbG9naW5EYXRhPzogYW55KTogUHJvbWlzZTxhbnk+IHtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmdldE5vZGVzKGluc3RhbmNlVVVJRCkudGhlbigocmVzKSA9PiB7XG4gICAgICAgIGxldCBpdGVtTm9kZXMgPSBKU09OLnBhcnNlKHJlcy5fYm9keSkuaXRlbXM7XG5cbiAgICAgICAgbGV0IHJ1bm5pbnRNb2RlID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGl0ZW1Ob2RlIG9mIGl0ZW1Ob2Rlcykge1xuICAgICAgICAgIGlmIChpdGVtTm9kZS5zdGF0dXMgPT09IFJVTk5JTkcpIHtcblxuICAgICAgICAgICAgcnVubmludE1vZGUgPSB0cnVlO1xuICAgICAgICAgICAgbGV0IGNvbk1nciA9IG5ldyBQYXJyb3RzRGVmYXVsdENvbm5lY3Rpb25NYW5hZ2VyKG51bGwsIHRoaXMuaHR0cCwgdGhpcy5iZ1Byb2Nlc3NNZ3IsIHRoaXMudGVzdE1vZGUsIHRoaXMudGVzdERhdGEpO1xuICAgICAgICAgICAgY29uTWdyLnNldE5hbWUoaXRlbU5vZGUuX3V1aWQpO1xuXG4gICAgICAgICAgICAvL1NldCBmb3IgdGVzdC5cbiAgICAgICAgICAgIGxldCB1cmw6IHN0cmluZyA9IGl0ZW1Ob2RlLnNlcnZlck5vZGUuaG9zdE5hbWUgPT0gXCJsb2NhbGhvc3RcIiA/IFwiaHR0cDovLzEwLjEuMC4yMlwiIDogaXRlbU5vZGUuc2VydmVyTm9kZS5ob3N0TmFtZTtcbiAgICAgICAgICAgIHVybCArPSBcIjpcIiArIGl0ZW1Ob2RlLnNlcnZpY2VQb3J0ICsgXCIvYXBpXCI7XG4gICAgICAgICAgICBjb25NZ3IuYWRkQmFzZVVSTHModXJsKTtcblxuICAgICAgICAgICAgaWYgKGxvZ2luRGF0YSAhPT0gdW5kZWZpbmVkKSB7XG5cbiAgICAgICAgICAgICAgdXJsICs9IFwiL3VzZXIvbG9naW5cIjtcbiAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uTWFuYWdlci5wb3N0V2l0aEh0dHBJbmZvKHVybCwgbG9naW5EYXRhLCBuZXcgUmVxdWVzdE9wdGlvbnMoKSkudGhlbigocmVzKSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IHNlc3Npb25JZCA9IEpTT04ucGFyc2UoKHJlcyBhcyBhbnkpLl9ib2R5KS5zZXNzaW9uSWQ7XG4gICAgICAgICAgICAgICAgY29uTWdyLnNldERlZmF1bHRIZWFkZXIoJ1Nlc3Npb24tSWQnLCBzZXNzaW9uSWQpO1xuICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlck1hcFtpbnN0YW5jZVVVSURdID0gY29uTWdyO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoaXRlbU5vZGVzKTtcbiAgICAgICAgICAgICAgfSkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyTWFwW2luc3RhbmNlVVVJRF0gPSBjb25NZ3I7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXJNYXBbaW5zdGFuY2VVVUlEXSA9IGNvbk1ncjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobG9naW5EYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAocnVubmludE1vZGUpIHtcbiAgICAgICAgICAgIHJlc29sdmUoaXRlbU5vZGVzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZWplY3QoaXRlbU5vZGVzKTtcbiAgICAgICAgfVxuXG4gICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gIH1cblxuICAvKipcbiAgICogIyMgc2V0dXAgaW5zdGFuY2VzOiBnZW5lcmF0ZSBjb25uZWN0aW9uTWFuYWdlciBieSBpbnN0YW5jZVVVSURzIGFuZCBjYWNoZSBpbiBtYXBcbiAgICovXG4gIHB1YmxpYyBzZXRVcEluc3RhbmNlcyhpbnN0YW5jZXM6IHN0cmluZ1tdKTogUHJvbWlzZTxhbnlbXT4ge1xuXG4gICAgaWYgKGluc3RhbmNlcyA9PT0gdW5kZWZpbmVkIHx8IGluc3RhbmNlcyA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShbXSk7XG4gICAgfVxuXG4gICAgbGV0IHByb21zOiBQcm9taXNlPGFueT5bXSA9IFtdO1xuXG4gICAgZm9yIChsZXQgaW5zdGFuY2VVVUlEIGluIGluc3RhbmNlcykge1xuICAgICAgaWYgKGluc3RhbmNlVVVJRCA9PT0gbnVsbCB8fCBpbnN0YW5jZVVVSUQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgcHJvbXMucHVzaCh0aGlzLnNldFVwSW5zdGFuY2UoaW5zdGFuY2VVVUlELCBpbnN0YW5jZXNbaW5zdGFuY2VVVUlEXSkpO1xuICAgIH1cblxuICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9tcyk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiAjIyByZW1vdmUgaW5zdGFuY2UgYnkgaW5zdGFuY2VVVUlEIGZyb20gbWFwXG4gICAqL1xuICBwdWJsaWMgdGVhckRvd25JbnN0YW5jZShpbnN0YW5jZVVVSUQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGRlbGV0ZSB0aGlzLmluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXJNYXBbaW5zdGFuY2VVVUlEXTtcbiAgfVxuXG4gIC8qKlxuICAgKiAjIyByZW1vdmUgaW5zdGFuY2UgaW5zdGFuY2VVVUlEIGZyb20gbWFwXG4gICAqL1xuICBwdWJsaWMgZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcihpbnN0YW5jZVVVSUQ/OiBzdHJpbmcpOiBJQ29ubmVjdGlvbk1hbmFnZXIge1xuICAgIGlmIChpbnN0YW5jZVVVSUQgIT09IHVuZGVmaW5lZCAmJiBpbnN0YW5jZVVVSUQgIT09IG51bGwgJiYgaW5zdGFuY2VVVUlEICE9PSAnJykge1xuICAgICAgcmV0dXJuIHRoaXMuaW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlck1hcFtpbnN0YW5jZVVVSURdO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnNlbGV0ZWRJbnN0YW5jZUlkID09PSB1bmRlZmluZWQgfHwgdGhpcy5zZWxldGVkSW5zdGFuY2VJZCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuaW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlck1hcFt0aGlzLnNlbGV0ZWRJbnN0YW5jZUlkXTtcbiAgfVxuXG4gIHB1YmxpYyBzZWxlY3RJbnN0YW5jZShpbnN0YW5jZVVVSUQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc2VsZXRlZEluc3RhbmNlSWQgPSBpbnN0YW5jZVVVSUQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0KHVybDogc3RyaW5nLCByZXF1ZXN0T3B0aW9uc0FyZ3M6IFJlcXVlc3RPcHRpb25zQXJncyk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSBudWxsIHx8IHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnQ29ubmVjdGlvbiBNYW5hZ2VyIGlzIG5vdCBzZXR1cCB5ZXQuJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKS5nZXQodXJsLCByZXF1ZXN0T3B0aW9uc0FyZ3MpO1xuICB9XG5cbiAgcHVibGljIGdldFdpdGhIdHRwSW5mbyh1cmw6IHN0cmluZywgcmVxdWVzdE9wdGlvbnNBcmdzOiBSZXF1ZXN0T3B0aW9uc0FyZ3MpOiBQcm9taXNlPFJlc3BvbnNlPiB7XG4gICAgaWYgKHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSBudWxsIHx8IHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnQ29ubmVjdGlvbiBNYW5hZ2VyIGlzIG5vdCBzZXR1cCB5ZXQuJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKS5nZXRXaXRoSHR0cEluZm8odXJsLCByZXF1ZXN0T3B0aW9uc0FyZ3MpO1xuICB9XG5cbiAgcHVibGljIHBvc3QodXJsOiBzdHJpbmcsIGJvZHk6IGFueSwgcmVxdWVzdE9wdGlvbnNBcmdzOiBSZXF1ZXN0T3B0aW9uc0FyZ3MpOiBQcm9taXNlPGFueT4ge1xuICAgIGlmICh0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gbnVsbCB8fCB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ0Nvbm5lY3Rpb24gTWFuYWdlciBpcyBub3Qgc2V0dXAgeWV0LicpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkucG9zdCh1cmwsIGJvZHksIHJlcXVlc3RPcHRpb25zQXJncyk7XG4gIH1cblxuICBwdWJsaWMgcG9zdFdpdGhIdHRwSW5mbyh1cmw6IHN0cmluZywgYm9keTogYW55LCByZXF1ZXN0T3B0aW9uc0FyZ3M6IFJlcXVlc3RPcHRpb25zQXJncyk6IFByb21pc2U8UmVzcG9uc2U+IHtcbiAgICBpZiAodGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IG51bGwgfHwgdGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdDb25uZWN0aW9uIE1hbmFnZXIgaXMgbm90IHNldHVwIHlldC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpLnBvc3RXaXRoSHR0cEluZm8odXJsLCBib2R5LCByZXF1ZXN0T3B0aW9uc0FyZ3MpO1xuICB9XG5cbiAgcHVibGljIHB1dCh1cmw6IHN0cmluZywgYm9keTogYW55LCByZXF1ZXN0T3B0aW9uc0FyZ3M6IFJlcXVlc3RPcHRpb25zQXJncyk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSBudWxsIHx8IHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnQ29ubmVjdGlvbiBNYW5hZ2VyIGlzIG5vdCBzZXR1cCB5ZXQuJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKS5wdXQodXJsLCBib2R5LCByZXF1ZXN0T3B0aW9uc0FyZ3MpO1xuICB9XG5cbiAgcHVibGljIHB1dFdpdGhIdHRwSW5mbyh1cmw6IHN0cmluZywgYm9keTogYW55LCByZXF1ZXN0T3B0aW9uc0FyZ3M6IFJlcXVlc3RPcHRpb25zQXJncyk6IFByb21pc2U8UmVzcG9uc2U+IHtcbiAgICBpZiAodGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IG51bGwgfHwgdGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdDb25uZWN0aW9uIE1hbmFnZXIgaXMgbm90IHNldHVwIHlldC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpLnB1dFdpdGhIdHRwSW5mbyh1cmwsIGJvZHksIHJlcXVlc3RPcHRpb25zQXJncyk7XG4gIH1cblxuICBwdWJsaWMgZGVsZXRlKHVybDogc3RyaW5nLCByZXF1ZXN0T3B0aW9uc0FyZ3M6IFJlcXVlc3RPcHRpb25zQXJncyk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSBudWxsIHx8IHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnQ29ubmVjdGlvbiBNYW5hZ2VyIGlzIG5vdCBzZXR1cCB5ZXQuJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKS5kZWxldGUodXJsLCByZXF1ZXN0T3B0aW9uc0FyZ3MpO1xuICB9XG5cbiAgcHVibGljIGRlbGV0ZVdpdGhIdHRwSW5mbyh1cmw6IHN0cmluZywgcmVxdWVzdE9wdGlvbnNBcmdzOiBSZXF1ZXN0T3B0aW9uc0FyZ3MpOiBQcm9taXNlPFJlc3BvbnNlPiB7XG4gICAgaWYgKHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSBudWxsIHx8IHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnQ29ubmVjdGlvbiBNYW5hZ2VyIGlzIG5vdCBzZXR1cCB5ZXQuJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKS5kZWxldGVXaXRoSHR0cEluZm8odXJsLCByZXF1ZXN0T3B0aW9uc0FyZ3MpO1xuICB9XG5cbiAgcHVibGljIHBhdGNoKHVybDogc3RyaW5nLCBib2R5OiBhbnksIHJlcXVlc3RPcHRpb25zQXJnczogUmVxdWVzdE9wdGlvbnNBcmdzKTogUHJvbWlzZTxhbnk+IHtcbiAgICBpZiAodGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IG51bGwgfHwgdGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdDb25uZWN0aW9uIE1hbmFnZXIgaXMgbm90IHNldHVwIHlldC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpLnBhdGNoKHVybCwgYm9keSwgcmVxdWVzdE9wdGlvbnNBcmdzKTtcbiAgfVxuXG4gIHB1YmxpYyBwYXRjaFdpdGhIdHRwSW5mbyh1cmw6IHN0cmluZywgYm9keTogYW55LCByZXF1ZXN0T3B0aW9uc0FyZ3M6IFJlcXVlc3RPcHRpb25zQXJncyk6IFByb21pc2U8UmVzcG9uc2U+IHtcbiAgICBpZiAodGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IG51bGwgfHwgdGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdDb25uZWN0aW9uIE1hbmFnZXIgaXMgbm90IHNldHVwIHlldC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpLnBhdGNoV2l0aEh0dHBJbmZvKHVybCwgYm9keSwgcmVxdWVzdE9wdGlvbnNBcmdzKTtcbiAgfVxuXG4gIHB1YmxpYyBoZWFkKHVybDogc3RyaW5nLCByZXF1ZXN0T3B0aW9uc0FyZ3M6IFJlcXVlc3RPcHRpb25zQXJncyk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSBudWxsIHx8IHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnQ29ubmVjdGlvbiBNYW5hZ2VyIGlzIG5vdC