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)

215 lines (214 loc) 25.7 kB
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _async_to_generator(fn) { return function() { var self = this, args = arguments; return new Promise(function(resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function _define_property(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } import randomstring from 'randomstring'; import * as lrap from '../long-running-async-process'; import StickySocketConnection from './stickySocketConnection'; import * as errors from '../../clients/errorHandler'; import { destroyInternalClientSocket } from './common.utils'; import { msToSeconds } from '../../helpers/convert/time'; import EventEmitter from '../../tools/eventEmitter'; import LoggerManager from '../../logger'; import Queue from '../../tools/queue'; /** * Client sticky socket */ let ClientStickySocket = class ClientStickySocket extends EventEmitter { /** * Returns socket ID * @returns socket ID */ get id() { return this._id; } /** * Returns current native socket * @returns socket.io socket * @internal intended for tests only */ get socket() { var _this__pool_getProcess; return (_this__pool_getProcess = this._pool.getProcess('connection')) === null || _this__pool_getProcess === void 0 ? void 0 : _this__pool_getProcess.socket; } /** * Returns current transport name, using socket.io internals * @returns transport name, e.g. "websocket" * @internal intended for tests only */ get transportName() { var _this__pool_getProcess; return (_this__pool_getProcess = this._pool.getProcess('connection')) === null || _this__pool_getProcess === void 0 ? void 0 : _this__pool_getProcess.transportName; } /** * Returns first present packet index in last emit history * @returns first history index * @internal intended for tests only */ get firstHistoryIndex() { var _this__pool_getProcess; return (_this__pool_getProcess = this._pool.getProcess('connection')) === null || _this__pool_getProcess === void 0 ? void 0 : _this__pool_getProcess.firstHistoryIndex; } /** * Returns whether socket connected * @returns is connected */ get connected() { return this._connected; } /** * @inheritdoc * @remarks Socket events `ClientStickySockets.INTERNAL_EVENTS` cannot be subscribed to * @throws `ValidationError` if attempting to subscribe to an internal event */ on(event, callback) { if (ClientStickySocket.INTERNAL_EVENTS.includes(event)) { throw new errors.ValidationError('Cannot subscribe to an internal event'); } super.on(event, callback); } /** * Emits a data event. All events are buffered if no connection * @param event The event that we're emitting * @param args Optional arguments to send with the event */ send(event, ...args) { var _this__pool_getProcess; (_this__pool_getProcess = this._pool.getProcess('connection')) === null || _this__pool_getProcess === void 0 ? void 0 : _this__pool_getProcess.send(event, ...args); } /** * Disconnects socket * @param err error if disconnecting with error * @returns promise resolving when disconnected */ disconnect(err) { var _this = this; return _async_to_generator(function*() { clearTimeout(_this._stickyConnectionWaitTimeout); let wasStopped = _this._stopped; _this._stopped = true; yield _this._pool.stop(); if (!wasStopped) { _this._connected = false; _this.emit('disconnect', err); } })(); } /** * Destroys underlying socket, using socket.io internals. The socket must have `websocket` transport * @param err optional error * @internal intended for tests only, e.g. to test connection loss */ destroyInternalSocket(err) { destroyInternalClientSocket(this._pool.getProcess('connection').socket, err); } /** * Removes expired emit history * @internal intended for tests only */ removeExpiredEmitHistory() { var _this__pool_getProcess; (_this__pool_getProcess = this._pool.getProcess('connection')) === null || _this__pool_getProcess === void 0 ? void 0 : _this__pool_getProcess.removeExpiredEmitHistory(); } /** * Constructs instance * @param url URL * @param options options */ constructor(url, options){ super(); _define_property(this, "_logger", LoggerManager.getLogger('ClientStickySocket')); _define_property(this, "_pool", void 0); _define_property(this, "_stickyConnectionWaitTimeout", void 0); _define_property(this, "_id", randomstring.generate(16)); _define_property(this, "_label", void 0); _define_property(this, "_stopped", false); _define_property(this, "_connected", false); this._label = `${(options === null || options === void 0 ? void 0 : options.label) || 'connection'}:${this._id}`; var _options_stickyConnectionTtlInSeconds; const stickyConnectionTtlInMs = 1000 * ((_options_stickyConnectionTtlInSeconds = options === null || options === void 0 ? void 0 : options.stickyConnectionTtlInSeconds) !== null && _options_stickyConnectionTtlInSeconds !== void 0 ? _options_stickyConnectionTtlInSeconds : 10); let internalEvents = new EventEmitter(); internalEvents.once('connect', ()=>{ this._connected = true; this.emit('connect'); }); internalEvents.on('connect', ()=>clearTimeout(this._stickyConnectionWaitTimeout)); internalEvents.on('fail', (err)=>{ if (options === null || options === void 0 ? void 0 : options.useNativeSocketIoServer) { this.disconnect(err); return; } if (!this._stopped) { this._stickyConnectionWaitTimeout = setTimeout(()=>{ this._logger.warn(`${this._label}: failed to restore sticky connection`); this.disconnect(err); }, stickyConnectionTtlInMs); } }); this._pool = new lrap.RootPool(StickySocketConnection, { dependencies: [ this, internalEvents ], label: `clientStickySocket:${this._label}` }); var _options_emitHistoryTtlInSeconds, _options_reconnectionDelayInMs, _options_reconnectionDelayMaxInMs, _options_reconnectionRandomizationFactor; this._pool.scheduleProcess('connection', { args: [ url, this._id, { startCount: 0, emitHistory: new Queue(), lastSentIndex: -1, lastReceivedIndex: -1 }, { label: this._label, connection: options === null || options === void 0 ? void 0 : options.connection, useNativeSocketIoServer: options === null || options === void 0 ? void 0 : options.useNativeSocketIoServer, emitHistoryTtlInSeconds: (_options_emitHistoryTtlInSeconds = options === null || options === void 0 ? void 0 : options.emitHistoryTtlInSeconds) !== null && _options_emitHistoryTtlInSeconds !== void 0 ? _options_emitHistoryTtlInSeconds : msToSeconds(stickyConnectionTtlInMs) } ], failoverThrottleDelay: { mode: 'exponential', resetDelayInMs: 0, minDelayInMs: (_options_reconnectionDelayInMs = options === null || options === void 0 ? void 0 : options.reconnectionDelayInMs) !== null && _options_reconnectionDelayInMs !== void 0 ? _options_reconnectionDelayInMs : 1000, maxDelayInMs: (_options_reconnectionDelayMaxInMs = options === null || options === void 0 ? void 0 : options.reconnectionDelayMaxInMs) !== null && _options_reconnectionDelayMaxInMs !== void 0 ? _options_reconnectionDelayMaxInMs : 10000, randomizationFactor: (_options_reconnectionRandomizationFactor = options === null || options === void 0 ? void 0 : options.reconnectionRandomizationFactor) !== null && _options_reconnectionRandomizationFactor !== void 0 ? _options_reconnectionRandomizationFactor : 0.5 } }); } }; (function(ClientStickySocket) { /** Connection events */ ClientStickySocket.CONNECTION_EVENTS = StickySocketConnection.CONNECTION_EVENTS; /** Internal events */ ClientStickySocket.INTERNAL_EVENTS = StickySocketConnection.INTERNAL_EVENTS; })(ClientStickySocket || (ClientStickySocket = {})); export default ClientStickySocket; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjxhbm9uPiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcmFuZG9tc3RyaW5nIGZyb20gJ3JhbmRvbXN0cmluZyc7XG5pbXBvcnQgKiBhcyBscmFwIGZyb20gJy4uL2xvbmctcnVubmluZy1hc3luYy1wcm9jZXNzJztcbmltcG9ydCBTdGlja3lTb2NrZXRDb25uZWN0aW9uIGZyb20gJy4vc3RpY2t5U29ja2V0Q29ubmVjdGlvbic7XG5pbXBvcnQgKiBhcyBlcnJvcnMgZnJvbSAnLi4vLi4vY2xpZW50cy9lcnJvckhhbmRsZXInO1xuaW1wb3J0IHtkZXN0cm95SW50ZXJuYWxDbGllbnRTb2NrZXR9IGZyb20gJy4vY29tbW9uLnV0aWxzJztcbmltcG9ydCB7bXNUb1NlY29uZHN9IGZyb20gJy4uLy4uL2hlbHBlcnMvY29udmVydC90aW1lJztcbmltcG9ydCBFdmVudEVtaXR0ZXIgZnJvbSAnLi4vLi4vdG9vbHMvZXZlbnRFbWl0dGVyJztcbmltcG9ydCBMb2dnZXJNYW5hZ2VyIGZyb20gJy4uLy4uL2xvZ2dlcic7XG5pbXBvcnQgUXVldWUgZnJvbSAnLi4vLi4vdG9vbHMvcXVldWUnO1xuXG4vKipcbiAqIENsaWVudCBzdGlja3kgc29ja2V0XG4gKi9cbmNsYXNzIENsaWVudFN0aWNreVNvY2tldCBleHRlbmRzIEV2ZW50RW1pdHRlcjxDbGllbnRTdGlja3lTb2NrZXQuRXZlbnRzPiB7XG5cbiAgcHJpdmF0ZSBfbG9nZ2VyID0gTG9nZ2VyTWFuYWdlci5nZXRMb2dnZXIoJ0NsaWVudFN0aWNreVNvY2tldCcpO1xuICBwcml2YXRlIF9wb29sOiBscmFwLlJvb3RQb29sPFN0aWNreVNvY2tldENvbm5lY3Rpb24+O1xuICBwcml2YXRlIF9zdGlja3lDb25uZWN0aW9uV2FpdFRpbWVvdXQ/OiBOb2RlSlMuVGltZW91dDtcbiAgcHJpdmF0ZSBfaWQgPSByYW5kb21zdHJpbmcuZ2VuZXJhdGUoMTYpO1xuICBwcml2YXRlIF9sYWJlbDogc3RyaW5nO1xuICBwcml2YXRlIF9zdG9wcGVkID0gZmFsc2U7XG4gIHByaXZhdGUgX2Nvbm5lY3RlZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGluc3RhbmNlXG4gICAqIEBwYXJhbSB1cmwgVVJMXG4gICAqIEBwYXJhbSBvcHRpb25zIG9wdGlvbnNcbiAgICovXG4gIGNvbnN0cnVjdG9yKHVybDogc3RyaW5nLCBvcHRpb25zPzogQ2xpZW50U3RpY2t5U29ja2V0Lk9wdGlvbnMpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX2xhYmVsID0gYCR7b3B0aW9ucz8ubGFiZWwgfHwgJ2Nvbm5lY3Rpb24nfToke3RoaXMuX2lkfWA7XG4gICAgXG4gICAgY29uc3Qgc3RpY2t5Q29ubmVjdGlvblR0bEluTXMgPSAxMDAwICogKG9wdGlvbnM/LnN0aWNreUNvbm5lY3Rpb25UdGxJblNlY29uZHMgPz8gMTApO1xuICAgIGxldCBpbnRlcm5hbEV2ZW50cyA9IG5ldyBFdmVudEVtaXR0ZXI8U3RpY2t5U29ja2V0Q29ubmVjdGlvbi5TaGFyZWRFdmVudHM+KCk7XG4gICAgaW50ZXJuYWxFdmVudHMub25jZSgnY29ubmVjdCcsICgpID0+IHtcbiAgICAgIHRoaXMuX2Nvbm5lY3RlZCA9IHRydWU7XG4gICAgICB0aGlzLmVtaXQoJ2Nvbm5lY3QnKTtcbiAgICB9KTtcbiAgICBpbnRlcm5hbEV2ZW50cy5vbignY29ubmVjdCcsICgpID0+IGNsZWFyVGltZW91dCh0aGlzLl9zdGlja3lDb25uZWN0aW9uV2FpdFRpbWVvdXQpKTtcbiAgICBpbnRlcm5hbEV2ZW50cy5vbignZmFpbCcsIGVyciA9PiB7XG4gICAgICBpZiAob3B0aW9ucz8udXNlTmF0aXZlU29ja2V0SW9TZXJ2ZXIpIHtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0KGVycik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5fc3RvcHBlZCkge1xuICAgICAgICB0aGlzLl9zdGlja3lDb25uZWN0aW9uV2FpdFRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0aGlzLl9sb2dnZXIud2FybihgJHt0aGlzLl9sYWJlbH06IGZhaWxlZCB0byByZXN0b3JlIHN0aWNreSBjb25uZWN0aW9uYCk7XG4gICAgICAgICAgdGhpcy5kaXNjb25uZWN0KGVycik7XG4gICAgICAgIH0sIHN0aWNreUNvbm5lY3Rpb25UdGxJbk1zKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBcbiAgICB0aGlzLl9wb29sID0gbmV3IGxyYXAuUm9vdFBvb2woU3RpY2t5U29ja2V0Q29ubmVjdGlvbiwge1xuICAgICAgZGVwZW5kZW5jaWVzOiBbdGhpcywgaW50ZXJuYWxFdmVudHNdLFxuICAgICAgbGFiZWw6IGBjbGllbnRTdGlja3lTb2NrZXQ6JHt0aGlzLl9sYWJlbH1gLFxuICAgIH0pO1xuICAgIHRoaXMuX3Bvb2wuc2NoZWR1bGVQcm9jZXNzKCdjb25uZWN0aW9uJywge1xuICAgICAgYXJnczogW1xuICAgICAgICB1cmwsIHRoaXMuX2lkLFxuICAgICAgICB7XG4gICAgICAgICAgc3RhcnRDb3VudDogMCxcbiAgICAgICAgICBlbWl0SGlzdG9yeTogbmV3IFF1ZXVlKCksXG4gICAgICAgICAgbGFzdFNlbnRJbmRleDogLTEsXG4gICAgICAgICAgbGFzdFJlY2VpdmVkSW5kZXg6IC0xXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBsYWJlbDogdGhpcy5fbGFiZWwsXG4gICAgICAgICAgY29ubmVjdGlvbjogb3B0aW9ucz8uY29ubmVjdGlvbixcbiAgICAgICAgICB1c2VOYXRpdmVTb2NrZXRJb1NlcnZlcjogb3B0aW9ucz8udXNlTmF0aXZlU29ja2V0SW9TZXJ2ZXIsXG4gICAgICAgICAgZW1pdEhpc3RvcnlUdGxJblNlY29uZHM6IG9wdGlvbnM/LmVtaXRIaXN0b3J5VHRsSW5TZWNvbmRzID8/IG1zVG9TZWNvbmRzKHN0aWNreUNvbm5lY3Rpb25UdGxJbk1zKVxuICAgICAgICB9XG4gICAgICBdLFxuICAgICAgZmFpbG92ZXJUaHJvdHRsZURlbGF5OiB7XG4gICAgICAgIG1vZGU6ICdleHBvbmVudGlhbCcsXG4gICAgICAgIHJlc2V0RGVsYXlJbk1zOiAwLFxuICAgICAgICBtaW5EZWxheUluTXM6IG9wdGlvbnM/LnJlY29ubmVjdGlvbkRlbGF5SW5NcyA/PyAxMDAwLFxuICAgICAgICBtYXhEZWxheUluTXM6IG9wdGlvbnM/LnJlY29ubmVjdGlvbkRlbGF5TWF4SW5NcyA/PyAxMDAwMCxcbiAgICAgICAgcmFuZG9taXphdGlvbkZhY3Rvcjogb3B0aW9ucz8ucmVjb25uZWN0aW9uUmFuZG9taXphdGlvbkZhY3RvciA/PyAwLjVcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHNvY2tldCBJRFxuICAgKiBAcmV0dXJucyBzb2NrZXQgSURcbiAgICovXG4gIGdldCBpZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9pZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGN1cnJlbnQgbmF0aXZlIHNvY2tldFxuICAgKiBAcmV0dXJucyBzb2NrZXQuaW8gc29ja2V0XG4gICAqIEBpbnRlcm5hbCBpbnRlbmRlZCBmb3IgdGVzdHMgb25seVxuICAgKi9cbiAgZ2V0IHNvY2tldCgpOiBTb2NrZXRJT0NsaWVudC5Tb2NrZXQge1xuICAgIHJldHVybiB0aGlzLl9wb29sLmdldFByb2Nlc3MoJ2Nvbm5lY3Rpb24nKT8uc29ja2V0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgY3VycmVudCB0cmFuc3BvcnQgbmFtZSwgdXNpbmcgc29ja2V0LmlvIGludGVybmFsc1xuICAgKiBAcmV0dXJucyB0cmFuc3BvcnQgbmFtZSwgZS5nLiBcIndlYnNvY2tldFwiXG4gICAqIEBpbnRlcm5hbCBpbnRlbmRlZCBmb3IgdGVzdHMgb25seVxuICAgKi9cbiAgZ2V0IHRyYW5zcG9ydE5hbWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fcG9vbC5nZXRQcm9jZXNzKCdjb25uZWN0aW9uJyk/LnRyYW5zcG9ydE5hbWU7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBSZXR1cm5zIGZpcnN0IHByZXNlbnQgcGFja2V0IGluZGV4IGluIGxhc3QgZW1pdCBoaXN0b3J5XG4gICAqIEByZXR1cm5zIGZpcnN0IGhpc3RvcnkgaW5kZXhcbiAgICogQGludGVybmFsIGludGVuZGVkIGZvciB0ZXN0cyBvbmx5XG4gICAqL1xuICBnZXQgZmlyc3RIaXN0b3J5SW5kZXgoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fcG9vbC5nZXRQcm9jZXNzKCdjb25uZWN0aW9uJyk/LmZpcnN0SGlzdG9yeUluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciBzb2NrZXQgY29ubmVjdGVkXG4gICAqIEByZXR1cm5zIGlzIGNvbm5lY3RlZFxuICAgKi9cbiAgZ2V0IGNvbm5lY3RlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbmhlcml0ZG9jXG4gICAqIEByZW1hcmtzIFNvY2tldCBldmVudHMgYENsaWVudFN0aWNreVNvY2tldHMuSU5URVJOQUxfRVZFTlRTYCBjYW5ub3QgYmUgc3Vic2NyaWJlZCB0b1xuICAgKiBAdGhyb3dzIGBWYWxpZGF0aW9uRXJyb3JgIGlmIGF0dGVtcHRpbmcgdG8gc3Vic2NyaWJlIHRvIGFuIGludGVybmFsIGV2ZW50XG4gICAqL1xuICBvbjxVIGV4dGVuZHMgRXZlbnRFbWl0dGVyLkV2ZW50PENsaWVudFN0aWNreVNvY2tldC5FdmVudHM+PihldmVudDogVSwgY2FsbGJhY2s6IENsaWVudFN0aWNreVNvY2tldC5FdmVudHNbVV0pIHtcbiAgICBpZiAoQ2xpZW50U3RpY2t5U29ja2V0LklOVEVSTkFMX0VWRU5UUy5pbmNsdWRlcyhldmVudCkpIHtcbiAgICAgIHRocm93IG5ldyBlcnJvcnMuVmFsaWRhdGlvbkVycm9yKCdDYW5ub3Qgc3Vic2NyaWJlIHRvIGFuIGludGVybmFsIGV2ZW50Jyk7XG4gICAgfVxuICAgIHN1cGVyLm9uKGV2ZW50LCBjYWxsYmFjayk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgYSBkYXRhIGV2ZW50LiBBbGwgZXZlbnRzIGFyZSBidWZmZXJlZCBpZiBubyBjb25uZWN0aW9uXG4gICAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgdGhhdCB3ZSdyZSBlbWl0dGluZ1xuICAgKiBAcGFyYW0gYXJncyBPcHRpb25hbCBhcmd1bWVudHMgdG8gc2VuZCB3aXRoIHRoZSBldmVudFxuICAgKi9cbiAgc2VuZChldmVudDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIHRoaXMuX3Bvb2wuZ2V0UHJvY2VzcygnY29ubmVjdGlvbicpPy5zZW5kKGV2ZW50LCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNjb25uZWN0cyBzb2NrZXRcbiAgICogQHBhcmFtIGVyciBlcnJvciBpZiBkaXNjb25uZWN0aW5nIHdpdGggZXJyb3JcbiAgICogQHJldHVybnMgcHJvbWlzZSByZXNvbHZpbmcgd2hlbiBkaXNjb25uZWN0ZWRcbiAgICovXG4gIGFzeW5jIGRpc2Nvbm5lY3QoZXJyPzogRXJyb3IpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5fc3RpY2t5Q29ubmVjdGlvbldhaXRUaW1lb3V0KTtcbiAgICBsZXQgd2FzU3RvcHBlZCA9IHRoaXMuX3N0b3BwZWQ7XG4gICAgdGhpcy5fc3RvcHBlZCA9IHRydWU7XG4gICAgYXdhaXQgdGhpcy5fcG9vbC5zdG9wKCk7XG4gICAgaWYgKCF3YXNTdG9wcGVkKSB7XG4gICAgICB0aGlzLl9jb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuZW1pdCgnZGlzY29ubmVjdCcsIGVycik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlc3Ryb3lzIHVuZGVybHlpbmcgc29ja2V0LCB1c2luZyBzb2NrZXQuaW8gaW50ZXJuYWxzLiBUaGUgc29ja2V0IG11c3QgaGF2ZSBgd2Vic29ja2V0YCB0cmFuc3BvcnRcbiAgICogQHBhcmFtIGVyciBvcHRpb25hbCBlcnJvclxuICAgKiBAaW50ZXJuYWwgaW50ZW5kZWQgZm9yIHRlc3RzIG9ubHksIGUuZy4gdG8gdGVzdCBjb25uZWN0aW9uIGxvc3NcbiAgICovXG4gIGRlc3Ryb3lJbnRlcm5hbFNvY2tldChlcnI/OiBFcnJvcikge1xuICAgIGRlc3Ryb3lJbnRlcm5hbENsaWVudFNvY2tldCh0aGlzLl9wb29sLmdldFByb2Nlc3MoJ2Nvbm5lY3Rpb24nKS5zb2NrZXQsIGVycik7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBleHBpcmVkIGVtaXQgaGlzdG9yeVxuICAgKiBAaW50ZXJuYWwgaW50ZW5kZWQgZm9yIHRlc3RzIG9ubHlcbiAgICovXG4gIHJlbW92ZUV4cGlyZWRFbWl0SGlzdG9yeSgpIHtcbiAgICB0aGlzLl9wb29sLmdldFByb2Nlc3MoJ2Nvbm5lY3Rpb24nKT8ucmVtb3ZlRXhwaXJlZEVtaXRIaXN0b3J5KCk7XG4gIH1cbn1cblxubmFtZXNwYWNlIENsaWVudFN0aWNreVNvY2tldCB7XG5cbiAgLyoqIENvbnN0cnVjdGluZyBvcHRpb25zICovXG4gIGV4cG9ydCB0eXBlIE9wdGlvbnMgPSBQaWNrPFN0aWNreVNvY2tldENvbm5lY3Rpb24uT3B0aW9ucywgJ2Nvbm5lY3Rpb24nIHwgJ2xhYmVsJyB8ICd1c2VOYXRpdmVTb2NrZXRJb1NlcnZlcic+ICYge1xuICAgIC8qKlxuICAgICAqIEVtaXQgaGlzdG9yeSBidWZmZXIgVFRMLiBEZWZhdWx0cyB0byBgc3RpY2t5Q29ubmVjdGlvblR0bEluU2Vjb25kc2AgKyBgcmVjb25uZWN0VGhyb3R0bGVEZWxheUluTXNgXG4gICAgICogKGNvbnZlcnRlZCB0byBzZWNvbmRzKVxuICAgICAqL1xuICAgIGVtaXRIaXN0b3J5VHRsSW5TZWNvbmRzPzogbnVtYmVyO1xuICAgIC8qKiBUaW1lb3V0IHdpdGhpbiBvZiB3aGljaCBhIGNvbm5lY3Rpb24gY2FuIGJlIHJlc3RvcmVkIGFzIHByZXZpb3VzIG9uZS4gRGVmYXVsdHMgdG8gYDEwYCAqL1xuICAgIHN0aWNreUNvbm5lY3Rpb25UdGxJblNlY29uZHM/OiBudW1iZXI7XG4gICAgLyoqIFJlY29ubmVjdGlvbiBkZWxheS4gVGhlIGRlbGF5IHdpbGwgYmUgaW5jcmVhc2VkIGJ5IDJ4IGVhY2ggZmFpbGVkIGNvbm5lY3Rpb24gYXR0ZW1wdC4gRGVmYXVsdHMgdG8gYDEwMDBgICovXG4gICAgcmVjb25uZWN0aW9uRGVsYXlJbk1zPzogbnVtYmVyO1xuICAgIC8qKiBNYXggcmVjb25uZWN0aW9uIGRlbGF5LiBEZWZhdWx0cyB0byBgMTAwMDBgICovXG4gICAgcmVjb25uZWN0aW9uRGVsYXlNYXhJbk1zPzogbnVtYmVyO1xuICAgIC8qKiBSZWNvbm5lY3Rpb24gZGVsYXkgcmFuZG9taXphdGlvbiBmYWN0b3IgaW4gcmFuZ2UgWzA7IDFdLiBEZWZhdWx0cyB0byBgMC41YCAqL1xuICAgIHJlY29ubmVjdGlvblJhbmRvbWl6YXRpb25GYWN0b3I/OiBudW1iZXI7XG4gIH07XG5cbiAgLyoqIEV2ZW50IGxpc3RlbmVycyAqL1xuICBleHBvcnQgdHlwZSBFdmVudHMgPSB7XG4gICAgLyoqIEZpcmVkIG9ubHkgb25jZSB1cG9uIGZpcnN0IGNvbm5lY3Rpb24gKi9cbiAgICBjb25uZWN0OiAoKSA9PiB2b2lkO1xuICAgIC8qKiBGaXJlZCBvbmx5IG9uY2UgdXBvbiB0aGUgbGFzdCBkaXNjb25uZWN0aW9uLiBXaWxsIGJlIGZpcmVkIGFueXdheSwgZXZlbiBpZiB3YXMgbmV2ZXIgY29ubmVjdGVkICovXG4gICAgZGlzY29ubmVjdDogKGVycj86IEVycm9yKSA9PiB2b2lkO1xuICAgIC8qKiBDdXN0b20gc3Vic2NyaXB0aW9uIGV2ZW50cyAqL1xuICAgIFtldmVudDogc3RyaW5nXTogKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnk7XG4gIH07XG5cbiAgLyoqIENvbm5lY3Rpb24gZXZlbnRzICovXG4gIGV4cG9ydCBjb25zdCBDT05ORUNUSU9OX0VWRU5UUyA9IFN0aWNreVNvY2tldENvbm5lY3Rpb24uQ09OTkVDVElPTl9FVkVOVFM7XG4gIC8qKiBJbnRlcm5hbCBldmVudHMgKi9cbiAgZXhwb3J0IGNvbnN0IElOVEVSTkFMX0VWRU5UUyA9IFN0aWNreVNvY2tldENvbm5lY3Rpb24uSU5URVJOQUxfRVZFTlRTO1xufVxuXG5leHBvcnQgZGVmYXVsdCBDbGllbnRTdGlja3lTb2NrZXQ7XG4iXSwibmFtZXMiOlsicmFuZG9tc3RyaW5nIiwibHJhcCIsIlN0aWNreVNvY2tldENvbm5lY3Rpb24iLCJlcnJvcnMiLCJkZXN0cm95SW50ZXJuYWxDbGllbnRTb2NrZXQiLCJtc1RvU2Vjb25kcyIsIkV2ZW50RW1pdHRlciIsIkxvZ2dlck1hbmFnZXIiLCJRdWV1ZSIsIkNsaWVudFN0aWNreVNvY2tldCIsImlkIiwiX2lkIiwic29ja2V0IiwiX3Bvb2wiLCJnZXRQcm9jZXNzIiwidHJhbnNwb3J0TmFtZSIsImZpcnN0SGlzdG9yeUluZGV4IiwiY29ubmVjdGVkIiwiX2Nvbm5lY3RlZCIsIm9uIiwiZXZlbnQiLCJjYWxsYmFjayIsIklOVEVSTkFMX0VWRU5UUyIsImluY2x1ZGVzIiwiVmFsaWRhdGlvbkVycm9yIiwic2VuZCIsImFyZ3MiLCJkaXNjb25uZWN0IiwiZXJyIiwiY2xlYXJUaW1lb3V0IiwiX3N0aWNreUNvbm5lY3Rpb25XYWl0VGltZW91dCIsIndhc1N0b3BwZWQiLCJfc3RvcHBlZCIsInN0b3AiLCJlbWl0IiwiZGVzdHJveUludGVybmFsU29ja2V0IiwicmVtb3ZlRXhwaXJlZEVtaXRIaXN0b3J5IiwiY29uc3RydWN0b3IiLCJ1cmwiLCJvcHRpb25zIiwiX2xvZ2dlciIsImdldExvZ2dlciIsImdlbmVyYXRlIiwiX2xhYmVsIiwibGFiZWwiLCJzdGlja3lDb25uZWN0aW9uVHRsSW5NcyIsInN0aWNreUNvbm5lY3Rpb25UdGxJblNlY29uZHMiLCJpbnRlcm5hbEV2ZW50cyIsIm9uY2UiLCJ1c2VOYXRpdmVTb2NrZXRJb1NlcnZlciIsInNldFRpbWVvdXQiLCJ3YXJuIiwiUm9vdFBvb2wiLCJkZXBlbmRlbmNpZXMiLCJzY2hlZHVsZVByb2Nlc3MiLCJzdGFydENvdW50IiwiZW1pdEhpc3RvcnkiLCJsYXN0U2VudEluZGV4IiwibGFzdFJlY2VpdmVkSW5kZXgiLCJjb25uZWN0aW9uIiwiZW1pdEhpc3RvcnlUdGxJblNlY29uZHMiLCJmYWlsb3ZlclRocm90dGxlRGVsYXkiLCJtb2RlIiwicmVzZXREZWxheUluTXMiLCJtaW5EZWxheUluTXMiLCJyZWNvbm5lY3Rpb25EZWxheUluTXMiLCJtYXhEZWxheUluTXMiLCJyZWNvbm5lY3Rpb25EZWxheU1heEluTXMiLCJyYW5kb21pemF0aW9uRmFjdG9yIiwicmVjb25uZWN0aW9uUmFuZG9taXphdGlvbkZhY3RvciIsIkNPTk5FQ1RJT05fRVZFTlRTIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPQSxrQkFBa0IsZUFBZTtBQUN4QyxZQUFZQyxVQUFVLGdDQUFnQztBQUN0RCxPQUFPQyw0QkFBNEIsMkJBQTJCO0FBQzlELFlBQVlDLFlBQVksNkJBQTZCO0FBQ3JELFNBQVFDLDJCQUEyQixRQUFPLGlCQUFpQjtBQUMzRCxTQUFRQyxXQUFXLFFBQU8sNkJBQTZCO0FBQ3ZELE9BQU9DLGtCQUFrQiwyQkFBMkI7QUFDcEQsT0FBT0MsbUJBQW1CLGVBQWU7QUFDekMsT0FBT0MsV0FBVyxvQkFBb0I7QUFFdEM7O0NBRUMsR0FDRCxJQUFBLEFBQU1DLHFCQUFOLE1BQU1BLDJCQUEyQkg7SUFxRS9COzs7R0FHQyxHQUNELElBQUlJLEtBQWE7UUFDZixPQUFPLElBQUksQ0FBQ0MsR0FBRztJQUNqQjtJQUVBOzs7O0dBSUMsR0FDRCxJQUFJQyxTQUFnQztZQUMzQjtRQUFQLFFBQU8seUJBQUEsSUFBSSxDQUFDQyxLQUFLLENBQUNDLFVBQVUsQ0FBQywyQkFBdEIsNkNBQUEsdUJBQXFDRixNQUFNO0lBQ3BEO0lBRUE7Ozs7R0FJQyxHQUNELElBQUlHLGdCQUF3QjtZQUNuQjtRQUFQLFFBQU8seUJB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