UNPKG

metaapi.cloud-sdk

Version:

SDK for MetaApi, a professional cloud forex API which includes MetaTrader REST API and MetaTrader websocket API. Supports both MetaTrader 5 (MT5) and MetaTrader 4 (MT4). CopyFactory copy trading API included. (https://metaapi.cloud)

148 lines (147 loc) 25.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function() { return MetaApi; } }); const _httpClient = /*#__PURE__*/ _interop_require_default(require("../clients/httpClient")); const _provisioningProfileclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/provisioningProfile.client")); const _provisioningProfileApi = /*#__PURE__*/ _interop_require_default(require("./provisioningProfileApi")); const _metaApiWebsocketclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/metaApiWebsocket.client")); const _metatraderAccountApi = /*#__PURE__*/ _interop_require_default(require("./metatraderAccountApi")); const _metatraderAccountclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/metatraderAccount.client")); const _metatraderAccountGeneratorApi = /*#__PURE__*/ _interop_require_default(require("./metatraderAccountGeneratorApi")); const _metatraderAccountGeneratorclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/metatraderAccountGenerator.client")); const _historicalMarketDataclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/historicalMarketData.client")); const _clientApiclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/clientApi.client")); const _connectionRegistry = /*#__PURE__*/ _interop_require_default(require("./connectionRegistry")); const _errorHandler = require("../clients/errorHandler"); const _optionsValidator = /*#__PURE__*/ _interop_require_default(require("../clients/optionsValidator")); const _latencyMonitor = /*#__PURE__*/ _interop_require_default(require("./latencyMonitor")); const _expertAdvisorclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/expertAdvisor.client")); const _logger = /*#__PURE__*/ _interop_require_default(require("../logger")); const _domainclient = /*#__PURE__*/ _interop_require_default(require("../clients/domain.client")); const _terminalHashManager = /*#__PURE__*/ _interop_require_default(require("./terminalHashManager")); const _tokenManagementclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/tokenManagement.client")); const _tokenManagementApi = /*#__PURE__*/ _interop_require_default(require("./tokenManagementApi")); const _lodash = /*#__PURE__*/ _interop_require_default(require("lodash")); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } let MetaApi = class MetaApi { /** * Enables using Log4js logger with extended log levels for debugging instead of * console.* functions. Note that log4js configuration performed by the user. */ static enableLog4jsLogging() { _logger.default.useLog4js(); } /** * Returns provisioning profile API * @returns {ProvisioningProfileApi} provisioning profile API */ get provisioningProfileApi() { return this._provisioningProfileApi; } /** * Returns MetaTrader account API * @return {MetatraderAccountApi} MetaTrader account API */ get metatraderAccountApi() { return this._metatraderAccountApi; } /** * Returns MetaTrader account generator API * @return {MetatraderDemoAccountApi} MetaTrader account generator API */ get metatraderAccountGeneratorApi() { return this._metatraderAccountGeneratorApi; } /** * Returns MetaApi application latency monitor * @return {LatencyMonitor} latency monitor */ get latencyMonitor() { return this._latencyMonitor; } /** * Returns token management API * @returns {TokenManagementApi} token management API */ get tokenManagementApi() { return this._tokenManagementApi; } /** * Closes all clients and connections and stops all internal jobs */ close() { this._metaApiWebsocketClient.removeLatencyListener(this._latencyMonitor); this._metaApiWebsocketClient.close(); this._metaApiWebsocketClient.stop(); this._terminalHashManager._stop(); } /** * Constructs MetaApi class instance * @param {String} token authorization token * @param {MetaApiOpts} opts application options */ // eslint-disable-next-line complexity constructor(token, opts){ const validator = new _optionsValidator.default(); opts = _lodash.default.omit(opts || {}, [ "connections" ]); const application = opts.application || "MetaApi"; const domain = opts.domain || "agiliumtrade.agiliumtrade.ai"; const requestTimeout = validator.validateNonZero(opts.requestTimeout, 60, "requestTimeout"); const historicalMarketDataRequestTimeout = validator.validateNonZero(opts.historicalMarketDataRequestTimeout, 240, "historicalMarketDataRequestTimeout"); const connectTimeout = validator.validateNonZero(opts.connectTimeout, 60, "connectTimeout"); const packetOrderingTimeout = validator.validateNonZero(opts.packetOrderingTimeout, 60, "packetOrderingTimeout"); const retryOpts = opts.retryOpts || {}; const packetLogger = opts.packetLogger || {}; const synchronizationThrottler = opts.synchronizationThrottler || {}; const accountGeneratorRequestTimeout = validator.validateNonZero(opts.accountGeneratorRequestTimeout, 240, "accountGeneratorRequestTimeout"); if (!application.match(/[a-zA-Z0-9_]+/)) { throw new _errorHandler.ValidationError("Application name must be non-empty string consisting from letters, digits and _ only"); } const useSharedClientApi = opts.useSharedClientApi || false; const refreshSubscriptionsOpts = opts.refreshSubscriptionsOpts || {}; const httpClient = new _httpClient.default(requestTimeout, retryOpts); const domainClient = new _domainclient.default(httpClient, token, domain); const historicalMarketDataHttpClient = new _httpClient.default(historicalMarketDataRequestTimeout, retryOpts); const accountGeneratorHttpClient = new _httpClient.default(accountGeneratorRequestTimeout, retryOpts); const clientApiClient = new _clientApiclient.default(httpClient, domainClient); const tokenManagmentClient = new _tokenManagementclient.default(httpClient, domainClient); this._terminalHashManager = new _terminalHashManager.default(clientApiClient, opts.keepHashTrees); this._metaApiWebsocketClient = new _metaApiWebsocketclient.default(this, domainClient, token, { application, domain, requestTimeout, connectTimeout, packetLogger, packetOrderingTimeout, synchronizationThrottler, retryOpts, useSharedClientApi, region: opts.region, unsubscribeThrottlingIntervalInSeconds: opts.unsubscribeThrottlingIntervalInSeconds, useNativeSocketIoServer: opts.useNativeSocketIoServer }); this._provisioningProfileApi = new _provisioningProfileApi.default(new _provisioningProfileclient.default(httpClient, domainClient)); this._connectionRegistry = new _connectionRegistry.default(opts, this._metaApiWebsocketClient, this._terminalHashManager, application, refreshSubscriptionsOpts); let historicalMarketDataClient = new _historicalMarketDataclient.default(historicalMarketDataHttpClient, domainClient); this._metatraderAccountApi = new _metatraderAccountApi.default(new _metatraderAccountclient.default(httpClient, domainClient), this._metaApiWebsocketClient, this._connectionRegistry, new _expertAdvisorclient.default(httpClient, domainClient), historicalMarketDataClient, application); this._metatraderAccountGeneratorApi = new _metatraderAccountGeneratorApi.default(new _metatraderAccountGeneratorclient.default(accountGeneratorHttpClient, domainClient)); this._tokenManagementApi = new _tokenManagementApi.default(tokenManagmentClient); if (opts.enableLatencyTracking || opts.enableLatencyMonitor) { this._latencyMonitor = new _latencyMonitor.default(); this._metaApiWebsocketClient.addLatencyListener(this._latencyMonitor); } this._logger = _logger.default.getLogger("MetaAPI"); if (process.env.IS_BROWSER) { if (!this._tokenManagementApi.areTokenResourcesNarrowedDown(token)) { this._logger.warn("USING THE ADMIN TOKEN"); this._logger.info("It seems like you are using a admin API token. Since the token can be retrieven from the browser or " + "mobile apps by end user this can lead to your application being compromised, unless you understand what " + "are you doing. Please use Token Management API " + "(https://github.com/metaapi/metaapi-javascript-sdk/blob/master/docs/tokenManagementApi.md) in your " + "backend application to produce secure tokens which you can then use in web UI or mobile apps."); } } } }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjxhbm9uPiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBIdHRwQ2xpZW50IGZyb20gJy4uL2NsaWVudHMvaHR0cENsaWVudCc7XG5pbXBvcnQgUHJvdmlzaW9uaW5nUHJvZmlsZUNsaWVudCBmcm9tICcuLi9jbGllbnRzL21ldGFBcGkvcHJvdmlzaW9uaW5nUHJvZmlsZS5jbGllbnQnO1xuaW1wb3J0IFByb3Zpc2lvbmluZ1Byb2ZpbGVBcGkgZnJvbSAnLi9wcm92aXNpb25pbmdQcm9maWxlQXBpJztcbmltcG9ydCBNZXRhQXBpV2Vic29ja2V0Q2xpZW50IGZyb20gJy4uL2NsaWVudHMvbWV0YUFwaS9tZXRhQXBpV2Vic29ja2V0LmNsaWVudCc7XG5pbXBvcnQgTWV0YXRyYWRlckFjY291bnRBcGkgZnJvbSAnLi9tZXRhdHJhZGVyQWNjb3VudEFwaSc7XG5pbXBvcnQgTWV0YXRyYWRlckFjY291bnRDbGllbnQgZnJvbSAnLi4vY2xpZW50cy9tZXRhQXBpL21ldGF0cmFkZXJBY2NvdW50LmNsaWVudCc7XG5pbXBvcnQgTWV0YXRyYWRlckFjY291bnRHZW5lcmF0b3JBcGkgZnJvbSAnLi9tZXRhdHJhZGVyQWNjb3VudEdlbmVyYXRvckFwaSc7XG5pbXBvcnQgTWV0YXRyYWRlckFjY291bnRHZW5lcmF0b3JDbGllbnQgZnJvbSAnLi4vY2xpZW50cy9tZXRhQXBpL21ldGF0cmFkZXJBY2NvdW50R2VuZXJhdG9yLmNsaWVudCc7XG5pbXBvcnQgSGlzdG9yaWNhbE1hcmtldERhdGFDbGllbnQgZnJvbSAnLi4vY2xpZW50cy9tZXRhQXBpL2hpc3RvcmljYWxNYXJrZXREYXRhLmNsaWVudCc7XG5pbXBvcnQgQ2xpZW50QXBpQ2xpZW50IGZyb20gJy4uL2NsaWVudHMvbWV0YUFwaS9jbGllbnRBcGkuY2xpZW50JztcbmltcG9ydCBDb25uZWN0aW9uUmVnaXN0cnkgZnJvbSAnLi9jb25uZWN0aW9uUmVnaXN0cnknO1xuaW1wb3J0IHtWYWxpZGF0aW9uRXJyb3J9IGZyb20gJy4uL2NsaWVudHMvZXJyb3JIYW5kbGVyJztcbmltcG9ydCBPcHRpb25zVmFsaWRhdG9yIGZyb20gJy4uL2NsaWVudHMvb3B0aW9uc1ZhbGlkYXRvcic7XG5pbXBvcnQgTGF0ZW5jeU1vbml0b3IgZnJvbSAnLi9sYXRlbmN5TW9uaXRvcic7XG5pbXBvcnQgRXhwZXJ0QWR2aXNvckNsaWVudCBmcm9tICcuLi9jbGllbnRzL21ldGFBcGkvZXhwZXJ0QWR2aXNvci5jbGllbnQnO1xuaW1wb3J0IExvZ2dlck1hbmFnZXIgZnJvbSAnLi4vbG9nZ2VyJztcbmltcG9ydCBEb21haW5DbGllbnQgZnJvbSAnLi4vY2xpZW50cy9kb21haW4uY2xpZW50JztcbmltcG9ydCBUZXJtaW5hbEhhc2hNYW5hZ2VyIGZyb20gJy4vdGVybWluYWxIYXNoTWFuYWdlcic7XG5pbXBvcnQgVG9rZW5NYW5hZ2VtZW50Q2xpZW50IGZyb20gJy4uL2NsaWVudHMvbWV0YUFwaS90b2tlbk1hbmFnZW1lbnQuY2xpZW50JztcbmltcG9ydCBUb2tlbk1hbmFnZW1lbnRBcGkgZnJvbSAnLi90b2tlbk1hbmFnZW1lbnRBcGknO1xuaW1wb3J0IHtNZXRhQXBpT3B0c30gZnJvbSAnLi9tZXRhQXBpJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5cbi8qKlxuICogTWV0YUFwaSBNZXRhVHJhZGVyIEFQSSBTREtcbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWV0YUFwaSB7XG5cbiAgLyoqXG4gICAqIEVuYWJsZXMgdXNpbmcgTG9nNGpzIGxvZ2dlciB3aXRoIGV4dGVuZGVkIGxvZyBsZXZlbHMgZm9yIGRlYnVnZ2luZyBpbnN0ZWFkIG9mXG4gICAqIGNvbnNvbGUuKiBmdW5jdGlvbnMuIE5vdGUgdGhhdCBsb2c0anMgY29uZmlndXJhdGlvbiBwZXJmb3JtZWQgYnkgdGhlIHVzZXIuXG4gICAqL1xuICBzdGF0aWMgZW5hYmxlTG9nNGpzTG9nZ2luZygpIHtcbiAgICBMb2dnZXJNYW5hZ2VyLnVzZUxvZzRqcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdHMgTWV0YUFwaSBjbGFzcyBpbnN0YW5jZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gdG9rZW4gYXV0aG9yaXphdGlvbiB0b2tlblxuICAgKiBAcGFyYW0ge01ldGFBcGlPcHRzfSBvcHRzIGFwcGxpY2F0aW9uIG9wdGlvbnNcbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5XG4gIGNvbnN0cnVjdG9yKHRva2VuLCBvcHRzKSB7XG4gICAgY29uc3QgdmFsaWRhdG9yID0gbmV3IE9wdGlvbnNWYWxpZGF0b3IoKTtcbiAgICBvcHRzID0gXy5vbWl0KG9wdHMgfHwge30sIFsnY29ubmVjdGlvbnMnXSk7XG4gICAgY29uc3QgYXBwbGljYXRpb24gPSBvcHRzLmFwcGxpY2F0aW9uIHx8ICdNZXRhQXBpJztcbiAgICBjb25zdCBkb21haW4gPSBvcHRzLmRvbWFpbiB8fCAnYWdpbGl1bXRyYWRlLmFnaWxpdW10cmFkZS5haSc7XG4gICAgY29uc3QgcmVxdWVzdFRpbWVvdXQgPSB2YWxpZGF0b3IudmFsaWRhdGVOb25aZXJvKG9wdHMucmVxdWVzdFRpbWVvdXQsIDYwLCAncmVxdWVzdFRpbWVvdXQnKTtcbiAgICBjb25zdCBoaXN0b3JpY2FsTWFya2V0RGF0YVJlcXVlc3RUaW1lb3V0ID0gdmFsaWRhdG9yLnZhbGlkYXRlTm9uWmVybyhcbiAgICAgIG9wdHMuaGlzdG9yaWNhbE1hcmtldERhdGFSZXF1ZXN0VGltZW91dCwgMjQwLCAnaGlzdG9yaWNhbE1hcmtldERhdGFSZXF1ZXN0VGltZW91dCcpO1xuICAgIGNvbnN0IGNvbm5lY3RUaW1lb3V0ID0gdmFsaWRhdG9yLnZhbGlkYXRlTm9uWmVybyhvcHRzLmNvbm5lY3RUaW1lb3V0LCA2MCwgJ2Nvbm5lY3RUaW1lb3V0Jyk7XG4gICAgY29uc3QgcGFja2V0T3JkZXJpbmdUaW1lb3V0ID0gdmFsaWRhdG9yLnZhbGlkYXRlTm9uWmVybyhvcHRzLnBhY2tldE9yZGVyaW5nVGltZW91dCwgNjAsICdwYWNrZXRPcmRlcmluZ1RpbWVvdXQnKTtcbiAgICBjb25zdCByZXRyeU9wdHMgPSBvcHRzLnJldHJ5T3B0cyB8fCB7fTtcbiAgICBjb25zdCBwYWNrZXRMb2dnZXIgPSBvcHRzLnBhY2tldExvZ2dlciB8fCB7fTtcbiAgICBjb25zdCBzeW5jaHJvbml6YXRpb25UaHJvdHRsZXIgPSBvcHRzLnN5bmNocm9uaXphdGlvblRocm90dGxlciB8fCB7fTtcbiAgICBjb25zdCBhY2NvdW50R2VuZXJhdG9yUmVxdWVzdFRpbWVvdXQgPSB2YWxpZGF0b3IudmFsaWRhdGVOb25aZXJvKG9wdHMuYWNjb3VudEdlbmVyYXRvclJlcXVlc3RUaW1lb3V0LCAyNDAsXG4gICAgICAnYWNjb3VudEdlbmVyYXRvclJlcXVlc3RUaW1lb3V0Jyk7XG4gICAgaWYgKCFhcHBsaWNhdGlvbi5tYXRjaCgvW2EtekEtWjAtOV9dKy8pKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdBcHBsaWNhdGlvbiBuYW1lIG11c3QgYmUgbm9uLWVtcHR5IHN0cmluZyBjb25zaXN0aW5nIGZyb20gbGV0dGVycywgZGlnaXRzIGFuZCBfIG9ubHknKTtcbiAgICB9XG4gICAgY29uc3QgdXNlU2hhcmVkQ2xpZW50QXBpID0gb3B0cy51c2VTaGFyZWRDbGllbnRBcGkgfHwgZmFsc2U7XG4gICAgY29uc3QgcmVmcmVzaFN1YnNjcmlwdGlvbnNPcHRzID0gb3B0cy5yZWZyZXNoU3Vic2NyaXB0aW9uc09wdHMgfHwge307XG4gICAgY29uc3QgaHR0cENsaWVudCA9IG5ldyBIdHRwQ2xpZW50KHJlcXVlc3RUaW1lb3V0LCByZXRyeU9wdHMpO1xuICAgIGNvbnN0IGRvbWFpbkNsaWVudCA9IG5ldyBEb21haW5DbGllbnQoaHR0cENsaWVudCwgdG9rZW4sIGRvbWFpbik7XG4gICAgY29uc3QgaGlzdG9yaWNhbE1hcmtldERhdGFIdHRwQ2xpZW50ID0gbmV3IEh0dHBDbGllbnQoaGlzdG9yaWNhbE1hcmtldERhdGFSZXF1ZXN0VGltZW91dCwgcmV0cnlPcHRzKTtcbiAgICBjb25zdCBhY2NvdW50R2VuZXJhdG9ySHR0cENsaWVudCA9IG5ldyBIdHRwQ2xpZW50KGFjY291bnRHZW5lcmF0b3JSZXF1ZXN0VGltZW91dCwgcmV0cnlPcHRzKTtcbiAgICBjb25zdCBjbGllbnRBcGlDbGllbnQgPSBuZXcgQ2xpZW50QXBpQ2xpZW50KGh0dHBDbGllbnQsIGRvbWFpbkNsaWVudCk7IFxuICAgIGNvbnN0IHRva2VuTWFuYWdtZW50Q2xpZW50ID0gbmV3IFRva2VuTWFuYWdlbWVudENsaWVudChodHRwQ2xpZW50LCBkb21haW5DbGllbnQpOyBcbiAgICB0aGlzLl90ZXJtaW5hbEhhc2hNYW5hZ2VyID0gbmV3IFRlcm1pbmFsSGFzaE1hbmFnZXIoY2xpZW50QXBpQ2xpZW50LCBvcHRzLmtlZXBIYXNoVHJlZXMpO1xuICAgIHRoaXMuX21ldGFBcGlXZWJzb2NrZXRDbGllbnQgPSBuZXcgTWV0YUFwaVdlYnNvY2tldENsaWVudCh0aGlzLCBkb21haW5DbGllbnQsIHRva2VuLCB7XG4gICAgICBhcHBsaWNhdGlvbiwgZG9tYWluLFxuICAgICAgcmVxdWVzdFRpbWVvdXQsIGNvbm5lY3RUaW1lb3V0LCBwYWNrZXRMb2dnZXIsIHBhY2tldE9yZGVyaW5nVGltZW91dCwgc3luY2hyb25pemF0aW9uVGhyb3R0bGVyLCByZXRyeU9wdHMsXG4gICAgICB1c2VTaGFyZWRDbGllbnRBcGksIHJlZ2lvbjogb3B0cy5yZWdpb24sXG4gICAgICB1bnN1YnNjcmliZVRocm90dGxpbmdJbnRlcnZhbEluU2Vjb25kczogb3B0cy51bnN1YnNjcmliZVRocm90dGxpbmdJbnRlcnZhbEluU2Vjb25kcyxcbiAgICAgIHVzZU5hdGl2ZVNvY2tldElvU2VydmVyOiBvcHRzLnVzZU5hdGl2ZVNvY2tldElvU2VydmVyXG4gICAgfSk7XG4gICAgdGhpcy5fcHJvdmlzaW9uaW5nUHJvZmlsZUFwaSA9IG5ldyBQcm92aXNpb25pbmdQcm9maWxlQXBpKG5ldyBQcm92aXNpb25pbmdQcm9maWxlQ2xpZW50KGh0dHBDbGllbnQsIGRvbWFpbkNsaWVudCkpO1xuICAgIHRoaXMuX2Nvbm5lY3Rpb25SZWdpc3RyeSA9IG5ldyBDb25uZWN0aW9uUmVnaXN0cnkob3B0cywgdGhpcy5fbWV0YUFwaVdlYnNvY2tldENsaWVudCwgdGhpcy5fdGVybWluYWxIYXNoTWFuYWdlcixcbiAgICAgIGFwcGxpY2F0aW9uLCByZWZyZXNoU3Vic2NyaXB0aW9uc09wdHMpO1xuICAgIGxldCBoaXN0b3JpY2FsTWFya2V0RGF0YUNsaWVudCA9IG5ldyBIaXN0b3JpY2FsTWFya2V0RGF0YUNsaWVudChoaXN0b3JpY2FsTWFya2V0RGF0YUh0dHBDbGllbnQsIGRvbWFpbkNsaWVudCk7XG4gICAgdGhpcy5fbWV0YXRyYWRlckFjY291bnRBcGkgPSBuZXcgTWV0YXRyYWRlckFjY291bnRBcGkobmV3IE1ldGF0cmFkZXJBY2NvdW50Q2xpZW50KGh0dHBDbGllbnQsIGRvbWFpbkNsaWVudCksXG4gICAgICB0aGlzLl9tZXRhQXBpV2Vic29ja2V0Q2xpZW50LCB0aGlzLl9jb25uZWN0aW9uUmVnaXN0cnksIFxuICAgICAgbmV3IEV4cGVydEFkdmlzb3JDbGllbnQoaHR0cENsaWVudCwgZG9tYWluQ2xpZW50KSwgaGlzdG9yaWNhbE1hcmtldERhdGFDbGllbnQsIGFwcGxpY2F0aW9uKTtcbiAgICB0aGlzLl9tZXRhdHJhZGVyQWNjb3VudEdlbmVyYXRvckFwaSA9IG5ldyBNZXRhdHJhZGVyQWNjb3VudEdlbmVyYXRvckFwaShcbiAgICAgIG5ldyBNZXRhdHJhZGVyQWNjb3VudEdlbmVyYXRvckNsaWVudChhY2NvdW50R2VuZXJhdG9ySHR0cENsaWVudCwgZG9tYWluQ2xpZW50KSk7XG4gICAgdGhpcy5fdG9rZW5NYW5hZ2VtZW50QXBpID0gbmV3IFRva2VuTWFuYWdlbWVudEFwaSh0b2tlbk1hbmFnbWVudENsaWVudCk7XG4gICAgaWYgKG9wdHMuZW5hYmxlTGF0ZW5jeVRyYWNraW5nIHx8IG9wdHMuZW5hYmxlTGF0ZW5jeU1vbml0b3IpIHtcbiAgICAgIHRoaXMuX2xhdGVuY3lNb25pdG9yID0gbmV3IExhdGVuY3lNb25pdG9yKCk7XG4gICAgICB0aGlzLl9tZXRhQXBpV2Vic29ja2V0Q2xpZW50LmFkZExhdGVuY3lMaXN0ZW5lcih0aGlzLl9sYXRlbmN5TW9uaXRvcik7XG4gICAgfVxuICAgIFxuICAgIHRoaXMuX2xvZ2dlciA9IExvZ2dlck1hbmFnZXIuZ2V0TG9nZ2VyKCdNZXRhQVBJJyk7XG4gICAgaWYgKHByb2Nlc3MuZW52LklTX0JST1dTRVIpIHtcbiAgICAgIGlmICghdGhpcy5fdG9rZW5NYW5hZ2VtZW50QXBpLmFyZVRva2VuUmVzb3VyY2VzTmFycm93ZWREb3duKHRva2VuKSkge1xuICAgICAgICB0aGlzLl9sb2dnZXIud2FybignVVNJTkcgVEhFIEFETUlOIFRPS0VOJyk7XG4gICAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKFxuICAgICAgICAgICdJdCBzZWVtcyBsaWtlIHlvdSBhcmUgdXNpbmcgYSBhZG1pbiBBUEkgdG9rZW4uIFNpbmNlIHRoZSB0b2tlbiBjYW4gYmUgcmV0cmlldmVuIGZyb20gdGhlIGJyb3dzZXIgb3IgJyArXG4gICAgICAgICAgJ21vYmlsZSBhcHBzIGJ5IGVuZCB1c2VyIHRoaXMgY2FuIGxlYWQgdG8geW91ciBhcHBsaWNhdGlvbiBiZWluZyBjb21wcm9taXNlZCwgdW5sZXNzIHlvdSB1bmRlcnN0YW5kIHdoYXQgJyArXG4gICAgICAgICAgJ2FyZSB5b3UgZG9pbmcuIFBsZWFzZSB1c2UgVG9rZW4gTWFuYWdlbWVudCBBUEkgJyArXG4gICAgICAgICAgJyhodHRwczovL2dpdGh1Yi5jb20vbWV0YWFwaS9tZXRhYXBpLWphdmFzY3JpcHQtc2RrL2Jsb2IvbWFzdGVyL2RvY3MvdG9rZW5NYW5hZ2VtZW50QXBpLm1kKSBpbiB5b3VyICcgK1xuICAgICAgICAgICdiYWNrZW5kIGFwcGxpY2F0aW9uIHRvIHByb2R1Y2Ugc2VjdXJlIHRva2VucyB3aGljaCB5b3UgY2FuIHRoZW4gdXNlIGluIHdlYiBVSSBvciBtb2JpbGUgYXBwcy4nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgcHJvdmlzaW9uaW5nIHByb2ZpbGUgQVBJXG4gICAqIEByZXR1cm5zIHtQcm92aXNpb25pbmdQcm9maWxlQXBpfSBwcm92aXNpb25pbmcgcHJvZmlsZSBBUElcbiAgICovXG4gIGdldCBwcm92aXNpb25pbmdQcm9maWxlQXBpKCkge1xuICAgIHJldHVybiB0aGlzLl9wcm92aXNpb25pbmdQcm9maWxlQXBpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgTWV0YVRyYWRlciBhY2NvdW50IEFQSVxuICAgKiBAcmV0dXJuIHtNZXRhdHJhZGVyQWNjb3VudEFwaX0gTWV0YVRyYWRlciBhY2NvdW50IEFQSVxuICAgKi9cbiAgZ2V0IG1ldGF0cmFkZXJBY2NvdW50QXBpKCkge1xuICAgIHJldHVybiB0aGlzLl9tZXRhdHJhZGVyQWNjb3VudEFwaTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIE1ldGFUcmFkZXIgYWNjb3VudCBnZW5lcmF0b3IgQVBJXG4gICAqIEByZXR1cm4ge01ldGF0cmFkZXJEZW1vQWNjb3VudEFwaX0gTWV0YVRyYWRlciBhY2NvdW50IGdlbmVyYXRvciBBUElcbiAgICovXG4gIGdldCBtZXRhdHJhZGVyQWNjb3VudEdlbmVyYXRvckFwaSgpIHtcbiAgICByZXR1cm4gdGhpcy5fbWV0YXRyYWRlckFjY291bnRHZW5lcmF0b3JBcGk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBNZXRhQXBpIGFwcGxpY2F0aW9uIGxhdGVuY3kgbW9uaXRvclxuICAgKiBAcmV0dXJuIHtMYXRlbmN5TW9uaXRvcn0gbGF0ZW5jeSBtb25pdG9yXG4gICAqL1xuICBnZXQgbGF0ZW5jeU1vbml0b3IoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2xhdGVuY3lNb25pdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdG9rZW4gbWFuYWdlbWVudCBBUElcbiAgICogQHJldHVybnMge1Rva2VuTWFuYWdlbWVudEFwaX0gdG9rZW4gbWFuYWdlbWVudCBBUElcbiAgICovXG4gIGdldCB0b2tlbk1hbmFnZW1lbnRBcGkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Rva2VuTWFuYWdlbWVudEFwaTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgYWxsIGNsaWVudHMgYW5kIGNvbm5lY3Rpb25zIGFuZCBzdG9wcyBhbGwgaW50ZXJuYWwgam9ic1xuICAgKi9cbiAgY2xvc2UoKSB7XG4gICAgdGhpcy5fbWV0YUFwaVdlYnNvY2tldENsaWVudC5yZW1vdmVMYXRlbmN5TGlzdGVuZXIodGhpcy5fbGF0ZW5jeU1vbml0b3IpO1xuICAgIHRoaXMuX21ldGFBcGlXZWJzb2NrZXRDbGllbnQuY2xvc2UoKTtcbiAgICB0aGlzLl9tZXRhQXBpV2Vic29ja2V0Q2xpZW50LnN0b3AoKTtcbiAgICB0aGlzLl90ZXJtaW5hbEhhc2hNYW5hZ2VyLl9zdG9wKCk7XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJNZXRhQXBpIiwiZW5hYmxlTG9nNGpzTG9nZ2luZyIsIkxvZ2dlck1hbmFnZXIiLCJ1c2VMb2c0anMiLCJwcm92aXNpb25pbmdQcm9maWxlQXBpIiwiX3Byb3Zpc2lvbmluZ1Byb2ZpbGVBcGkiLCJtZXRhdHJhZGVyQWNjb3VudEFwaSIsIl9tZXRhdHJhZGVyQWNjb3VudEFwaSIsIm1ldGF0cmFkZXJBY2NvdW50R2VuZXJhdG9yQXBpIiwiX21ldGF0cmFkZXJBY2NvdW50R2VuZXJhdG9yQXBpIiwibGF0ZW5jeU1vbml0b3IiLCJfbGF0ZW5jeU1vbml0b3IiLCJ0b2tlbk1hbmFnZW1lbnRBcGkiLCJfdG9rZW5NYW5hZ2VtZW50QXBpIiwiY2xvc2UiLCJfbWV0YUFwaVdlYnNvY2tldENsaWVudCIsInJlbW92ZUxhdGVuY3lMaXN0ZW5lciIsInN0b3AiLCJfdGVybWluYWxIYXNoTWFuYWdlciIsIl9zdG9wIiwiY29uc3RydWN0b3IiLCJ0b2tlbiIsIm9wdHMiLCJ2YWxpZGF0b3IiLCJPcHRpb25zVmFsaWRhdG9yIiwiXyIsIm9taXQiLCJhcHBsaWNhdGlvbiIsImRvbWFpbiIsInJlcXVlc3RUaW1lb3V0IiwidmFsaWRhdGVOb25aZXJvIiwiaGlzdG9yaWNhbE1hcmtldERhdGFSZXF1ZXN0VGltZW91dCIsImNvbm5lY3RUaW1lb3V0IiwicGFja2V0T3JkZXJpbmdUaW1lb3V0IiwicmV0cnlPcHRzIiwicGFja2V0TG9nZ2VyIiwic3luY2hyb25pemF0aW9uVGhyb3R0bGVyIiwiYWNjb3VudEdlbmVyYXRvclJlcXVlc3RUaW1lb3V0IiwibWF0Y2giLCJWYWxpZGF0aW9uRXJyb3IiLCJ1c2VTaGFyZWRDbGllbnRBcGkiLCJyZWZyZXNoU3Vic2NyaXB0aW9uc09wdHMiLCJodHRwQ2xpZW50IiwiSHR0cENsaWVudCIsImRvbWFpbkNsaWVudCIsIkRvbWFpbkNsaWVudCIsImhpc3RvcmljYWxNYXJrZXREYXRhSHR0cENsaWVudCIsImFjY291bnRHZW5lcmF0b3JIdHRwQ2xpZW50IiwiY2xpZW50QXBpQ2xpZW50IiwiQ2xpZW50QXBpQ2xpZW50IiwidG9rZW5NYW5hZ21lbnRDbGllbnQiLCJUb2tlbk1hbmFnZW1lbnRDbGllbnQiLCJUZXJtaW5hbEhhc2hNYW5hZ2VyIiwia2VlcEhhc2hUcmVlcyIsIk1ldGFBcGlXZWJzb2NrZXRDbGllbnQiLCJyZWdpb24iLCJ1bnN1YnNjcmliZVRocm90dGxpbmdJbnRlcnZhbEluU2Vjb25kcyIsInVzZU5hdGl2ZVNvY2tldElvU2VydmVyIiwiUHJvdmlzaW9uaW5nUHJvZmlsZUFwaSIsIlByb3Zpc2lvbmluZ1Byb2ZpbGVDbGllbnQiLCJfY29ubmVjdGlvblJlZ2lzdHJ5IiwiQ29ubmVjdGlvblJlZ2lzdHJ5IiwiaGlzdG9yaWNhbE1hcmtldERhdGFDbGllbnQiLCJIaXN0b3JpY2FsTWFya2V0RGF0YUNsaWVudCIsIk1ldGF0cmFkZXJBY2NvdW50QXBpIiwiTWV0YXRyYWRlckFjY291bnRDbGllbnQiLCJFeHBlcnRBZHZpc29yQ2xpZW50IiwiTWV0YXRyYWRlckFjY291bnRHZW5lcmF0b3JBcGkiLCJNZXRhdHJhZGVyQWNjb3VudEdlbmVyYXRvckNsaWVudCIsIlRva2VuTWFuYWdlbWVudEFwaSIsImVuYWJsZUxhdGVuY3lUcmFja2luZyIsImVuYWJsZUxhdGVuY3lNb25pdG9yIiwiTGF0ZW5jeU1vbml0b3IiLCJhZGRMYXRlbmN5TGlzdGVuZXIiLCJfbG9nZ2VyIiwiZ2V0TG9nZ2VyIiwicHJvY2VzcyIsImVudiIsIklTX0JST1dTRVIiLCJhcmVUb2tlblJlc291cmNlc05hcnJvd2VkRG93biIsIndhcm4iLCJpbmZvIl0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7OztlQTRCcUJBOzs7bUVBMUJFO2tGQUNlOytFQUNIOytFQUNBOzZFQUNGO2dGQUNHO3NGQUNNO3lGQUNHO21GQUNOO3dFQUNYOzJFQUNHOzhCQUNEO3lFQUNEO3VFQUNGOzRFQUNLOytEQUNOO3FFQUNEOzRFQUNPOzhFQUNFOzJFQUNIOytEQUVqQjs7Ozs7O0FBS0MsSUFBQSxBQUFNQSxVQUFOLE1BQU1BO0lBRW5COzs7R0FHQyxHQUNELE9BQU9DLHNCQUFzQjtRQUMzQkMsZUFBYSxDQUFDQyxTQUFTO0lBQ3pCO0lBd0VBOzs7R0FHQyxHQUNELElBQUlDLHlCQUF5QjtRQUMzQixPQUFPLElBQUksQ0FBQ0MsdUJBQXVCO0lBQ3JDO0lBRUE7OztHQUdDLEdBQ0QsSUFBSUMsdUJBQXVCO1FBQ3pCLE9BQU8sSUFBSSxDQUFDQyxxQkFBcUI7SUFDbkM7SUFFQTs7O0dBR0MsR0FDRCxJQUFJQyxnQ0FBZ0M7UUFDbEMsT0FBTyxJQUFJLENBQUNDLDhCQUE4QjtJQUM1QztJQUVBOzs7R0FHQyxHQUNELElBQUlDLGlCQUFpQjtRQUNuQixPQUFPLElBQUksQ0FBQ0MsZUFBZTtJQUM3QjtJQUVBOzs7R0FHQyxHQUNELElBQUlDLHFCQUFxQjtRQUN2QixPQUFPLElBQUksQ0FBQ0MsbUJBQW1CO0lBQ2pDO0lBRUE7O0dBRUMsR0FDREMsUUFBUTtRQUNOLElBQUksQ0FBQ0MsdUJBQXVCLENB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