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)

205 lines (204 loc) 21.8 kB
'use strict'; 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); }); }; } import SynchronizationListener from '../clients/metaApi/synchronizationListener'; let HistoryStorage = class HistoryStorage extends SynchronizationListener { /** * Initializes the storage and loads required data from a persistent storage * @param {string} accountId account id * @param {string} application application * @returns {Promise} promise resolving when history storage is initialized */ initialize(accountId, application) { var _this = this; return _async_to_generator(function*() { _this._accountId = accountId; _this._application = application; })(); } /** * Returns flag indicating whether order history synchronization have finished * @return {Boolean} flag indicating whether order history synchronization have finished */ get orderSynchronizationFinished() { return Object.values(this._orderSynchronizationFinished).reduce((acc, r)=>acc || r, false); } /** * Returns flag indicating whether deal history synchronization have finished * @return {Boolean} flag indicating whether deal history synchronization have finished */ get dealSynchronizationFinished() { return Object.values(this._dealSynchronizationFinished).reduce((acc, r)=>acc || r, false); } /** * Clears the storage and deletes persistent data * @returns {Promise} promise resolving when history storage is cleared */ clear() { return _async_to_generator(function*() { throw Error('Abstract method clear has no implementation'); })(); } /** * Returns the time of the last history order record stored in the history storage * @param {String} [instanceIndex] index of an account instance connected * @returns {Promise<Date>} the time of the last history order record stored in the history storage */ lastHistoryOrderTime(instanceIndex) { return _async_to_generator(function*() { throw Error('Abstract method lastHistoryOrderTime has no implementation'); })(); } /** * Returns the time of the last history deal record stored in the history storage * @param {String} [instanceIndex] index of an account instance connected * @returns {Promise<Date>} the time of the last history deal record stored in the history storage */ lastDealTime(instanceIndex) { return _async_to_generator(function*() { throw Error('Abstract method lastDealTime has no implementation'); })(); } /** * Invoked when a new MetaTrader history order is added * @param {String} instanceIndex index of an account instance connected * @param {MetatraderOrder} historyOrder new MetaTrader history order * @return {Promise} promise which resolves when the asynchronous event is processed */ onHistoryOrderAdded(instanceIndex, historyOrder) { return _async_to_generator(function*() { throw Error('Abstract method onHistoryOrderAdded has no implementation'); })(); } /** * Invoked when a new MetaTrader history deal is added * @param {String} instanceIndex index of an account instance connected * @param {MetatraderDeal} deal new MetaTrader history deal * @return {Promise} promise which resolves when the asynchronous event is processed */ onDealAdded(instanceIndex, deal) { return _async_to_generator(function*() { throw Error('Abstract method onDealAdded has no implementation'); })(); } /** * Invoked when a synchronization of history deals on a MetaTrader account have finished to indicate progress of an * initial terminal state synchronization * @param {String} instanceIndex index of an account instance connected * @param {String} synchronizationId synchronization request id * @return {Promise} promise which resolves when the asynchronous event is processed */ onDealsSynchronized(instanceIndex, synchronizationId) { var _this = this; return _async_to_generator(function*() { const instance = _this.getInstanceNumber(instanceIndex); _this._dealSynchronizationFinished['' + instance] = true; })(); } /** * Invoked when a synchronization of history orders on a MetaTrader account have finished to indicate progress of an * initial terminal state synchronization * @param {String} instanceIndex index of an account instance connected * @param {String} synchronizationId synchronization request id * @return {Promise} promise which resolves when the asynchronous event is processed */ onHistoryOrdersSynchronized(instanceIndex, synchronizationId) { var _this = this; return _async_to_generator(function*() { const instance = _this.getInstanceNumber(instanceIndex); _this._orderSynchronizationFinished['' + instance] = true; })(); } /** * Invoked when connection to MetaTrader terminal established * @param {String} instanceIndex index of an account instance connected */ onConnected(instanceIndex) { const instance = this.getInstanceNumber(instanceIndex); this._orderSynchronizationFinished['' + instance] = false; this._dealSynchronizationFinished['' + instance] = false; } /** * Returns all deals * @returns {Array<MetatraderDeal>} all deals */ get deals() { throw Error('Abstract property deals has no implementation'); } /** * Returns deals by ticket id * @param {string} id ticket id * @returns {Array<MetatraderDeal>} deals found */ getDealsByTicket(id) { throw Error('Abstract method getDealsByTicket has no implementation'); } /** * Returns deals by position id * @param {string} positionId position id * @returns {Array<MetatraderDeal>} deals found */ getDealsByPosition(positionId) { throw Error('Abstract method getDealsByPosition has no implementation'); } /** * Returns deals by time range * @param startTime start time, inclusive * @param endTime end time, inclusive * @returns {Array<MetatraderDeal>} deals found */ getDealsByTimeRange(startTime, endTime) { throw Error('Abstract method getDealsByTimeRange has no implementation'); } /** * Returns all history orders * @returns {Array<MetatraderOrder>} all history orders */ get historyOrders() { throw Error('Abstract property historyOrders has no implementation'); } /** * Returns history orders by ticket id * @param {string} id ticket id * @returns {Array<MetatraderOrder>} history orders found */ getHistoryOrdersByTicket(id) { throw Error('Abstract method getHistoryOrdersByTicket has no implementation'); } /** * Returns history orders by position id * @param {string} positionId position id * @returns {Array<MetatraderOrder>} history orders found */ getHistoryOrdersByPosition(positionId) { throw Error('Abstract method getHistoryOrdersByPosition has no implementation'); } /** * Returns history orders by time range * @param startTime start time, inclusive * @param endTime end time, inclusive * @returns {Array<MetatraderOrder>} hisotry orders found */ getHistoryOrdersByTimeRange(startTime, endTime) { throw Error('Abstract method getHistoryOrdersByTimeRange has no implementation'); } /** * Constructs the history storage */ constructor(){ super(); this._orderSynchronizationFinished = {}; this._dealSynchronizationFinished = {}; } }; /** * Abstract class which defines MetaTrader history storage interface. */ export { HistoryStorage as default }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjxhbm9uPiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBTeW5jaHJvbml6YXRpb25MaXN0ZW5lciBmcm9tICcuLi9jbGllbnRzL21ldGFBcGkvc3luY2hyb25pemF0aW9uTGlzdGVuZXInO1xuXG4vKipcbiAqIEFic3RyYWN0IGNsYXNzIHdoaWNoIGRlZmluZXMgTWV0YVRyYWRlciBoaXN0b3J5IHN0b3JhZ2UgaW50ZXJmYWNlLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBIaXN0b3J5U3RvcmFnZSBleHRlbmRzIFN5bmNocm9uaXphdGlvbkxpc3RlbmVyIHtcblxuICAvKipcbiAgICogQ29uc3RydWN0cyB0aGUgaGlzdG9yeSBzdG9yYWdlXG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX29yZGVyU3luY2hyb25pemF0aW9uRmluaXNoZWQgPSB7fTtcbiAgICB0aGlzLl9kZWFsU3luY2hyb25pemF0aW9uRmluaXNoZWQgPSB7fTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyB0aGUgc3RvcmFnZSBhbmQgbG9hZHMgcmVxdWlyZWQgZGF0YSBmcm9tIGEgcGVyc2lzdGVudCBzdG9yYWdlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhY2NvdW50SWQgYWNjb3VudCBpZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXBwbGljYXRpb24gYXBwbGljYXRpb25cbiAgICogQHJldHVybnMge1Byb21pc2V9IHByb21pc2UgcmVzb2x2aW5nIHdoZW4gaGlzdG9yeSBzdG9yYWdlIGlzIGluaXRpYWxpemVkXG4gICAqL1xuICBhc3luYyBpbml0aWFsaXplKGFjY291bnRJZCwgYXBwbGljYXRpb24pIHtcbiAgICB0aGlzLl9hY2NvdW50SWQgPSBhY2NvdW50SWQ7XG4gICAgdGhpcy5fYXBwbGljYXRpb24gPSBhcHBsaWNhdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIG9yZGVyIGhpc3Rvcnkgc3luY2hyb25pemF0aW9uIGhhdmUgZmluaXNoZWRcbiAgICogQHJldHVybiB7Qm9vbGVhbn0gZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgb3JkZXIgaGlzdG9yeSBzeW5jaHJvbml6YXRpb24gaGF2ZSBmaW5pc2hlZFxuICAgKi9cbiAgZ2V0IG9yZGVyU3luY2hyb25pemF0aW9uRmluaXNoZWQoKSB7XG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGhpcy5fb3JkZXJTeW5jaHJvbml6YXRpb25GaW5pc2hlZCkucmVkdWNlKChhY2MsIHIpID0+IGFjYyB8fCByLCBmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBmbGFnIGluZGljYXRpbmcgd2hldGhlciBkZWFsIGhpc3Rvcnkgc3luY2hyb25pemF0aW9uIGhhdmUgZmluaXNoZWRcbiAgICogQHJldHVybiB7Qm9vbGVhbn0gZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgZGVhbCBoaXN0b3J5IHN5bmNocm9uaXphdGlvbiBoYXZlIGZpbmlzaGVkXG4gICAqL1xuICBnZXQgZGVhbFN5bmNocm9uaXphdGlvbkZpbmlzaGVkKCkge1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKHRoaXMuX2RlYWxTeW5jaHJvbml6YXRpb25GaW5pc2hlZCkucmVkdWNlKChhY2MsIHIpID0+IGFjYyB8fCByLCBmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXJzIHRoZSBzdG9yYWdlIGFuZCBkZWxldGVzIHBlcnNpc3RlbnQgZGF0YVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gcHJvbWlzZSByZXNvbHZpbmcgd2hlbiBoaXN0b3J5IHN0b3JhZ2UgaXMgY2xlYXJlZFxuICAgKi9cbiAgYXN5bmMgY2xlYXIoKSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Fic3RyYWN0IG1ldGhvZCBjbGVhciBoYXMgbm8gaW1wbGVtZW50YXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB0aW1lIG9mIHRoZSBsYXN0IGhpc3Rvcnkgb3JkZXIgcmVjb3JkIHN0b3JlZCBpbiB0aGUgaGlzdG9yeSBzdG9yYWdlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbaW5zdGFuY2VJbmRleF0gaW5kZXggb2YgYW4gYWNjb3VudCBpbnN0YW5jZSBjb25uZWN0ZWRcbiAgICogQHJldHVybnMge1Byb21pc2U8RGF0ZT59IHRoZSB0aW1lIG9mIHRoZSBsYXN0IGhpc3Rvcnkgb3JkZXIgcmVjb3JkIHN0b3JlZCBpbiB0aGUgaGlzdG9yeSBzdG9yYWdlXG4gICAqL1xuICBhc3luYyBsYXN0SGlzdG9yeU9yZGVyVGltZShpbnN0YW5jZUluZGV4KSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Fic3RyYWN0IG1ldGhvZCBsYXN0SGlzdG9yeU9yZGVyVGltZSBoYXMgbm8gaW1wbGVtZW50YXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB0aW1lIG9mIHRoZSBsYXN0IGhpc3RvcnkgZGVhbCByZWNvcmQgc3RvcmVkIGluIHRoZSBoaXN0b3J5IHN0b3JhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmd9IFtpbnN0YW5jZUluZGV4XSBpbmRleCBvZiBhbiBhY2NvdW50IGluc3RhbmNlIGNvbm5lY3RlZFxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxEYXRlPn0gdGhlIHRpbWUgb2YgdGhlIGxhc3QgaGlzdG9yeSBkZWFsIHJlY29yZCBzdG9yZWQgaW4gdGhlIGhpc3Rvcnkgc3RvcmFnZVxuICAgKi9cbiAgYXN5bmMgbGFzdERlYWxUaW1lKGluc3RhbmNlSW5kZXgpIHtcbiAgICB0aHJvdyBFcnJvcignQWJzdHJhY3QgbWV0aG9kIGxhc3REZWFsVGltZSBoYXMgbm8gaW1wbGVtZW50YXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gYSBuZXcgTWV0YVRyYWRlciBoaXN0b3J5IG9yZGVyIGlzIGFkZGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnN0YW5jZUluZGV4IGluZGV4IG9mIGFuIGFjY291bnQgaW5zdGFuY2UgY29ubmVjdGVkXG4gICAqIEBwYXJhbSB7TWV0YXRyYWRlck9yZGVyfSBoaXN0b3J5T3JkZXIgbmV3IE1ldGFUcmFkZXIgaGlzdG9yeSBvcmRlclxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uSGlzdG9yeU9yZGVyQWRkZWQoaW5zdGFuY2VJbmRleCwgaGlzdG9yeU9yZGVyKSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Fic3RyYWN0IG1ldGhvZCBvbkhpc3RvcnlPcmRlckFkZGVkIGhhcyBubyBpbXBsZW1lbnRhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiBhIG5ldyBNZXRhVHJhZGVyIGhpc3RvcnkgZGVhbCBpcyBhZGRlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5zdGFuY2VJbmRleCBpbmRleCBvZiBhbiBhY2NvdW50IGluc3RhbmNlIGNvbm5lY3RlZFxuICAgKiBAcGFyYW0ge01ldGF0cmFkZXJEZWFsfSBkZWFsIG5ldyBNZXRhVHJhZGVyIGhpc3RvcnkgZGVhbFxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uRGVhbEFkZGVkKGluc3RhbmNlSW5kZXgsIGRlYWwpIHtcbiAgICB0aHJvdyBFcnJvcignQWJzdHJhY3QgbWV0aG9kIG9uRGVhbEFkZGVkIGhhcyBubyBpbXBsZW1lbnRhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiBhIHN5bmNocm9uaXphdGlvbiBvZiBoaXN0b3J5IGRlYWxzIG9uIGEgTWV0YVRyYWRlciBhY2NvdW50IGhhdmUgZmluaXNoZWQgdG8gaW5kaWNhdGUgcHJvZ3Jlc3Mgb2YgYW5cbiAgICogaW5pdGlhbCB0ZXJtaW5hbCBzdGF0ZSBzeW5jaHJvbml6YXRpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IGluc3RhbmNlSW5kZXggaW5kZXggb2YgYW4gYWNjb3VudCBpbnN0YW5jZSBjb25uZWN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN5bmNocm9uaXphdGlvbklkIHN5bmNocm9uaXphdGlvbiByZXF1ZXN0IGlkXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiB0aGUgYXN5bmNocm9ub3VzIGV2ZW50IGlzIHByb2Nlc3NlZFxuICAgKi9cbiAgYXN5bmMgb25EZWFsc1N5bmNocm9uaXplZChpbnN0YW5jZUluZGV4LCBzeW5jaHJvbml6YXRpb25JZCkge1xuICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5nZXRJbnN0YW5jZU51bWJlcihpbnN0YW5jZUluZGV4KTtcbiAgICB0aGlzLl9kZWFsU3luY2hyb25pemF0aW9uRmluaXNoZWRbJycgKyBpbnN0YW5jZV0gPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiBhIHN5bmNocm9uaXphdGlvbiBvZiBoaXN0b3J5IG9yZGVycyBvbiBhIE1ldGFUcmFkZXIgYWNjb3VudCBoYXZlIGZpbmlzaGVkIHRvIGluZGljYXRlIHByb2dyZXNzIG9mIGFuXG4gICAqIGluaXRpYWwgdGVybWluYWwgc3RhdGUgc3luY2hyb25pemF0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnN0YW5jZUluZGV4IGluZGV4IG9mIGFuIGFjY291bnQgaW5zdGFuY2UgY29ubmVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzeW5jaHJvbml6YXRpb25JZCBzeW5jaHJvbml6YXRpb24gcmVxdWVzdCBpZFxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uSGlzdG9yeU9yZGVyc1N5bmNocm9uaXplZChpbnN0YW5jZUluZGV4LCBzeW5jaHJvbml6YXRpb25JZCkge1xuICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5nZXRJbnN0YW5jZU51bWJlcihpbnN0YW5jZUluZGV4KTtcbiAgICB0aGlzLl9vcmRlclN5bmNocm9uaXphdGlvbkZpbmlzaGVkWycnICsgaW5zdGFuY2VdID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gY29ubmVjdGlvbiB0byBNZXRhVHJhZGVyIHRlcm1pbmFsIGVzdGFibGlzaGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnN0YW5jZUluZGV4IGluZGV4IG9mIGFuIGFjY291bnQgaW5zdGFuY2UgY29ubmVjdGVkXG4gICAqL1xuICBvbkNvbm5lY3RlZChpbnN0YW5jZUluZGV4KSB7XG4gICAgY29uc3QgaW5zdGFuY2UgPSB0aGlzLmdldEluc3RhbmNlTnVtYmVyKGluc3RhbmNlSW5kZXgpO1xuICAgIHRoaXMuX29yZGVyU3luY2hyb25pemF0aW9uRmluaXNoZWRbJycgKyBpbnN0YW5jZV0gPSBmYWxzZTtcbiAgICB0aGlzLl9kZWFsU3luY2hyb25pemF0aW9uRmluaXNoZWRbJycgKyBpbnN0YW5jZV0gPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFsbCBkZWFsc1xuICAgKiBAcmV0dXJucyB7QXJyYXk8TWV0YXRyYWRlckRlYWw+fSBhbGwgZGVhbHNcbiAgICovXG4gIGdldCBkZWFscygpIHtcbiAgICB0aHJvdyBFcnJvcignQWJzdHJhY3QgcHJvcGVydHkgZGVhbHMgaGFzIG5vIGltcGxlbWVudGF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBkZWFscyBieSB0aWNrZXQgaWRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGlkIHRpY2tldCBpZFxuICAgKiBAcmV0dXJucyB7QXJyYXk8TWV0YXRyYWRlckRlYWw+fSBkZWFscyBmb3VuZFxuICAgKi9cbiAgZ2V0RGVhbHNCeVRpY2tldChpZCkge1xuICAgIHRocm93IEVycm9yKCdBYnN0cmFjdCBtZXRob2QgZ2V0RGVhbHNCeVRpY2tldCBoYXMgbm8gaW1wbGVtZW50YXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGRlYWxzIGJ5IHBvc2l0aW9uIGlkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwb3NpdGlvbklkIHBvc2l0aW9uIGlkXG4gICAqIEByZXR1cm5zIHtBcnJheTxNZXRhdHJhZGVyRGVhbD59IGRlYWxzIGZvdW5kXG4gICAqL1xuICBnZXREZWFsc0J5UG9zaXRpb24ocG9zaXRpb25JZCkge1xuICAgIHRocm93IEVycm9yKCdBYnN0cmFjdCBtZXRob2QgZ2V0RGVhbHNCeVBvc2l0aW9uIGhhcyBubyBpbXBsZW1lbnRhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgZGVhbHMgYnkgdGltZSByYW5nZVxuICAgKiBAcGFyYW0gc3RhcnRUaW1lIHN0YXJ0IHRpbWUsIGluY2x1c2l2ZVxuICAgKiBAcGFyYW0gZW5kVGltZSBlbmQgdGltZSwgaW5jbHVzaXZlXG4gICAqIEByZXR1cm5zIHtBcnJheTxNZXRhdHJhZGVyRGVhbD59IGRlYWxzIGZvdW5kXG4gICAqL1xuICBnZXREZWFsc0J5VGltZVJhbmdlKHN0YXJ0VGltZSwgZW5kVGltZSkge1xuICAgIHRocm93IEVycm9yKCdBYnN0cmFjdCBtZXRob2QgZ2V0RGVhbHNCeVRpbWVSYW5nZSBoYXMgbm8gaW1wbGVtZW50YXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFsbCBoaXN0b3J5IG9yZGVyc1xuICAgKiBAcmV0dXJucyB7QXJyYXk8TWV0YXRyYWRlck9yZGVyPn0gYWxsIGhpc3Rvcnkgb3JkZXJzXG4gICAqL1xuICBnZXQgaGlzdG9yeU9yZGVycygpIHtcbiAgICB0aHJvdyBFcnJvcignQWJzdHJhY3QgcHJvcGVydHkgaGlzdG9yeU9yZGVycyBoYXMgbm8gaW1wbGVtZW50YXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGhpc3Rvcnkgb3JkZXJzIGJ5IHRpY2tldCBpZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgdGlja2V0IGlkXG4gICAqIEByZXR1cm5zIHtBcnJheTxNZXRhdHJhZGVyT3JkZXI+fSBoaXN0b3J5IG9yZGVycyBmb3VuZFxuICAgKi9cbiAgZ2V0SGlzdG9yeU9yZGVyc0J5VGlja2V0KGlkKSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Fic3RyYWN0IG1ldGhvZCBnZXRIaXN0b3J5T3JkZXJzQnlUaWNrZXQgaGFzIG5vIGltcGxlbWVudGF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBoaXN0b3J5IG9yZGVycyBieSBwb3NpdGlvbiBpZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gcG9zaXRpb25JZCBwb3NpdGlvbiBpZFxuICAgKiBAcmV0dXJucyB7QXJyYXk8TWV0YXRyYWRlck9yZGVyPn0gaGlzdG9yeSBvcmRlcnMgZm91bmRcbiAgICovXG4gIGdldEhpc3RvcnlPcmRlcnNCeVBvc2l0aW9uKHBvc2l0aW9uSWQpIHtcbiAgICB0aHJvdyBFcnJvcignQWJzdHJhY3QgbWV0aG9kIGdldEhpc3RvcnlPcmRlcnNCeVBvc2l0aW9uIGhhcyBubyBpbXBsZW1lbnRhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgaGlzdG9yeSBvcmRlcnMgYnkgdGltZSByYW5nZVxuICAgKiBAcGFyYW0gc3RhcnRUaW1lIHN0YXJ0IHRpbWUsIGluY2x1c2l2ZVxuICAgKiBAcGFyYW0gZW5kVGltZSBlbmQgdGltZSwgaW5jbHVzaXZlXG4gICAqIEByZXR1cm5zIHtBcnJheTxNZXRhdHJhZGVyT3JkZXI+fSBoaXNvdHJ5IG9yZGVycyBmb3VuZFxuICAgKi9cbiAgZ2V0SGlzdG9yeU9yZGVyc0J5VGltZVJhbmdlKHN0YXJ0VGltZSwgZW5kVGltZSkge1xuICAgIHRocm93IEVycm9yKCdBYnN0cmFjdCBtZXRob2QgZ2V0SGlzdG9yeU9yZGVyc0J5VGltZVJhbmdlIGhhcyBubyBpbXBsZW1lbnRhdGlvbicpO1xuICB9XG5cbn1cbiJdLCJuYW1lcyI6WyJTeW5jaHJvbml6YXRpb25MaXN0ZW5lciIsIkhpc3RvcnlTdG9yYWdlIiwiaW5pdGlhbGl6ZSIsImFjY291bnRJZCIsImFwcGxpY2F0aW9uIiwiX2FjY291bnRJZCIsIl9hcHBsaWNhdGlvbiIsIm9yZGVyU3luY2hyb25pemF0aW9uRmluaXNoZWQiLCJPYmplY3QiLCJ2YWx1ZXMiLCJfb3JkZXJTeW5jaHJvbml6YXRpb25GaW5pc2hlZCIsInJlZHVjZSIsImFjYyIsInIiLCJkZWFsU3luY2hyb25pemF0aW9uRmluaXNoZWQiLCJfZGVhbFN5bmNocm9uaXphdGlvbkZpbmlzaGVkIiwiY2xlYXIiLCJFcnJvciIsImxhc3RIaXN0b3J5T3JkZXJUaW1lIiwiaW5zdGFuY2VJbmRleCIsImxhc3REZWFsVGltZSIsIm9uSGlzdG9yeU9yZGVyQWRkZWQiLCJoaXN0b3J5T3JkZXIiLCJvbkRlYWxBZGRlZCIsImRlYWwiLCJvbkRlYWxzU3luY2hyb25pemVkIiwic3luY2hyb25pemF0aW9uSWQiLCJpbnN0YW5jZSIsImdldEluc3RhbmNlTnVtYmVyIiwib25IaXN0b3J5T3JkZXJzU3luY2hyb25pemVkIiwib25Db25uZWN0ZWQiLCJkZWFscyIsImdldERlYWxzQnlUaWNrZXQiLCJpZCIsImdldERlYWxzQnlQb3NpdGlvbiIsInBvc2l0aW9uSWQiLCJnZXREZWFsc0J5VGltZVJhbmdlIiwic3RhcnRUaW1lIiwiZW5kVGltZSIsImhpc3RvcnlPcmRlcnMiLCJnZXRIaXN0b3J5T3JkZXJzQnlUaWNrZXQiLCJnZXRIaXN0b3J5T3JkZXJzQnlQb3NpdGlvbiIsImdldEhpc3RvcnlPcmRlcnNCeVRpbWVSYW5nZSIsImNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUEsT0FBT0EsNkJBQTZCLDZDQUE2QztBQUtsRSxJQUFBLEFBQU1DLGlCQUFOLE1BQU1BLHVCQUF1QkQ7SUFXMUM7Ozs7O0dBS0MsR0FDRCxBQUFNRSxXQUFXQyxT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