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)
168 lines (167 loc) • 20.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return HistoryStorage;
}
});
const _synchronizationListener = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/synchronizationListener"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
let HistoryStorage = class HistoryStorage extends _synchronizationListener.default {
/**
* 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
*/ async initialize(accountId, application) {
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
*/ async clear() {
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
*/ async lastHistoryOrderTime(instanceIndex) {
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
*/ async lastDealTime(instanceIndex) {
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
*/ async onHistoryOrderAdded(instanceIndex, historyOrder) {
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
*/ async onDealAdded(instanceIndex, deal) {
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
*/ async onDealsSynchronized(instanceIndex, synchronizationId) {
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
*/ async onHistoryOrdersSynchronized(instanceIndex, synchronizationId) {
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 = {};
}
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjxhbm9uPiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBTeW5jaHJvbml6YXRpb25MaXN0ZW5lciBmcm9tICcuLi9jbGllbnRzL21ldGFBcGkvc3luY2hyb25pemF0aW9uTGlzdGVuZXInO1xuXG4vKipcbiAqIEFic3RyYWN0IGNsYXNzIHdoaWNoIGRlZmluZXMgTWV0YVRyYWRlciBoaXN0b3J5IHN0b3JhZ2UgaW50ZXJmYWNlLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBIaXN0b3J5U3RvcmFnZSBleHRlbmRzIFN5bmNocm9uaXphdGlvbkxpc3RlbmVyIHtcblxuICAvKipcbiAgICogQ29uc3RydWN0cyB0aGUgaGlzdG9yeSBzdG9yYWdlXG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX29yZGVyU3luY2hyb25pemF0aW9uRmluaXNoZWQgPSB7fTtcbiAgICB0aGlzLl9kZWFsU3luY2hyb25pemF0aW9uRmluaXNoZWQgPSB7fTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyB0aGUgc3RvcmFnZSBhbmQgbG9hZHMgcmVxdWlyZWQgZGF0YSBmcm9tIGEgcGVyc2lzdGVudCBzdG9yYWdlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhY2NvdW50SWQgYWNjb3VudCBpZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXBwbGljYXRpb24gYXBwbGljYXRpb25cbiAgICogQHJldHVybnMge1Byb21pc2V9IHByb21pc2UgcmVzb2x2aW5nIHdoZW4gaGlzdG9yeSBzdG9yYWdlIGlzIGluaXRpYWxpemVkXG4gICAqL1xuICBhc3luYyBpbml0aWFsaXplKGFjY291bnRJZCwgYXBwbGljYXRpb24pIHtcbiAgICB0aGlzLl9hY2NvdW50SWQgPSBhY2NvdW50SWQ7XG4gICAgdGhpcy5fYXBwbGljYXRpb24gPSBhcHBsaWNhdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIG9yZGVyIGhpc3Rvcnkgc3luY2hyb25pemF0aW9uIGhhdmUgZmluaXNoZWRcbiAgICogQHJldHVybiB7Qm9vbGVhbn0gZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgb3JkZXIgaGlzdG9yeSBzeW5jaHJvbml6YXRpb24gaGF2ZSBmaW5pc2hlZFxuICAgKi9cbiAgZ2V0IG9yZGVyU3luY2hyb25pemF0aW9uRmluaXNoZWQoKSB7XG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGhpcy5fb3JkZXJTeW5jaHJvbml6YXRpb25GaW5pc2hlZCkucmVkdWNlKChhY2MsIHIpID0+IGFjYyB8fCByLCBmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBmbGFnIGluZGljYXRpbmcgd2hldGhlciBkZWFsIGhpc3Rvcnkgc3luY2hyb25pemF0aW9uIGhhdmUgZmluaXNoZWRcbiAgICogQHJldHVybiB7Qm9vbGVhbn0gZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgZGVhbCBoaXN0b3J5IHN5bmNocm9uaXphdGlvbiBoYXZlIGZpbmlzaGVkXG4gICAqL1xuICBnZXQgZGVhbFN5bmNocm9uaXphdGlvbkZpbmlzaGVkKCkge1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKHRoaXMuX2RlYWxTeW5jaHJvbml6YXRpb25GaW5pc2hlZCkucmVkdWNlKChhY2MsIHIpID0+IGFjYyB8fCByLCBmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXJzIHRoZSBzdG9yYWdlIGFuZCBkZWxldGVzIHBlcnNpc3RlbnQgZGF0YVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gcHJvbWlzZSByZXNvbHZpbmcgd2hlbiBoaXN0b3J5IHN0b3JhZ2UgaXMgY2xlYXJlZFxuICAgKi9cbiAgYXN5bmMgY2xlYXIoKSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Fic3RyYWN0IG1ldGhvZCBjbGVhciBoYXMgbm8gaW1wbGVtZW50YXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB0aW1lIG9mIHRoZSBsYXN0IGhpc3Rvcnkgb3JkZXIgcmVjb3JkIHN0b3JlZCBpbiB0aGUgaGlzdG9yeSBzdG9yYWdlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbaW5zdGFuY2VJbmRleF0gaW5kZXggb2YgYW4gYWNjb3VudCBpbnN0YW5jZSBjb25uZWN0ZWRcbiAgICogQHJldHVybnMge1Byb21pc2U8RGF0ZT59IHRoZSB0aW1lIG9mIHRoZSBsYXN0IGhpc3Rvcnkgb3JkZXIgcmVjb3JkIHN0b3JlZCBpbiB0aGUgaGlzdG9yeSBzdG9yYWdlXG4gICAqL1xuICBhc3luYyBsYXN0SGlzdG9yeU9yZGVyVGltZShpbnN0YW5jZUluZGV4KSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Fic3RyYWN0IG1ldGhvZCBsYXN0SGlzdG9yeU9yZGVyVGltZSBoYXMgbm8gaW1wbGVtZW50YXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB0aW1lIG9mIHRoZSBsYXN0IGhpc3RvcnkgZGVhbCByZWNvcmQgc3RvcmVkIGluIHRoZSBoaXN0b3J5IHN0b3JhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmd9IFtpbnN0YW5jZUluZGV4XSBpbmRleCBvZiBhbiBhY2NvdW50IGluc3RhbmNlIGNvbm5lY3RlZFxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxEYXRlPn0gdGhlIHRpbWUgb2YgdGhlIGxhc3QgaGlzdG9yeSBkZWFsIHJlY29yZCBzdG9yZWQgaW4gdGhlIGhpc3Rvcnkgc3RvcmFnZVxuICAgKi9cbiAgYXN5bmMgbGFzdERlYWxUaW1lKGluc3RhbmNlSW5kZXgpIHtcbiAgICB0aHJvdyBFcnJvcignQWJzdHJhY3QgbWV0aG9kIGxhc3REZWFsVGltZSBoYXMgbm8gaW1wbGVtZW50YXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gYSBuZXcgTWV0YVRyYWRlciBoaXN0b3J5IG9yZGVyIGlzIGFkZGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnN0YW5jZUluZGV4IGluZGV4IG9mIGFuIGFjY291bnQgaW5zdGFuY2UgY29ubmVjdGVkXG4gICAqIEBwYXJhbSB7TWV0YXRyYWRlck9yZGVyfSBoaXN0b3J5T3JkZXIgbmV3IE1ldGFUcmFkZXIgaGlzdG9yeSBvcmRlclxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uSGlzdG9yeU9yZGVyQWRkZWQoaW5zdGFuY2VJbmRleCwgaGlzdG9yeU9yZGVyKSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Fic3RyYWN0IG1ldGhvZCBvbkhpc3RvcnlPcmRlckFkZGVkIGhhcyBubyBpbXBsZW1lbnRhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiBhIG5ldyBNZXRhVHJhZGVyIGhpc3RvcnkgZGVhbCBpcyBhZGRlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5zdGFuY2VJbmRleCBpbmRleCBvZiBhbiBhY2NvdW50IGluc3RhbmNlIGNvbm5lY3RlZFxuICAgKiBAcGFyYW0ge01ldGF0cmFkZXJEZWFsfSBkZWFsIG5ldyBNZXRhVHJhZGVyIGhpc3RvcnkgZGVhbFxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uRGVhbEFkZGVkKGluc3RhbmNlSW5kZXgsIGRlYWwpIHtcbiAgICB0aHJvdyBFcnJvcignQWJzdHJhY3QgbWV0aG9kIG9uRGVhbEFkZGVkIGhhcyBubyBpbXBsZW1lbnRhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiBhIHN5bmNocm9uaXphdGlvbiBvZiBoaXN0b3J5IGRlYWxzIG9uIGEgTWV0YVRyYWRlciBhY2NvdW50IGhhdmUgZmluaXNoZWQgdG8gaW5kaWNhdGUgcHJvZ3Jlc3Mgb2YgYW5cbiAgICogaW5pdGlhbCB0ZXJtaW5hbCBzdGF0ZSBzeW5jaHJvbml6YXRpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IGluc3RhbmNlSW5kZXggaW5kZXggb2YgYW4gYWNjb3VudCBpbnN0YW5jZSBjb25uZWN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN5bmNocm9uaXphdGlvbklkIHN5bmNocm9uaXphdGlvbiByZXF1ZXN0IGlkXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiB0aGUgYXN5bmNocm9ub3VzIGV2ZW50IGlzIHByb2Nlc3NlZFxuICAgKi9cbiAgYXN5bmMgb25EZWFsc1N5bmNocm9uaXplZChpbnN0YW5jZUluZGV4LCBzeW5jaHJvbml6YXRpb25JZCkge1xuICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5nZXRJbnN0YW5jZU51bWJlcihpbnN0YW5jZUluZGV4KTtcbiAgICB0aGlzLl9kZWFsU3luY2hyb25pemF0aW9uRmluaXNoZWRbJycgKyBpbnN0YW5jZV0gPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiBhIHN5bmNocm9uaXphdGlvbiBvZiBoaXN0b3J5IG9yZGVycyBvbiBhIE1ldGFUcmFkZXIgYWNjb3VudCBoYXZlIGZpbmlzaGVkIHRvIGluZGljYXRlIHByb2dyZXNzIG9mIGFuXG4gICAqIGluaXRpYWwgdGVybWluYWwgc3RhdGUgc3luY2hyb25pemF0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnN0YW5jZUluZGV4IGluZGV4IG9mIGFuIGFjY291bnQgaW5zdGFuY2UgY29ubmVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzeW5jaHJvbml6YXRpb25JZCBzeW5jaHJvbml6YXRpb24gcmVxdWVzdCBpZFxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uSGlzdG9yeU9yZGVyc1N5bmNocm9uaXplZChpbnN0YW5jZUluZGV4LCBzeW5jaHJvbml6YXRpb25JZCkge1xuICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5nZXRJbnN0YW5jZU51bWJlcihpbnN0YW5jZUluZGV4KTtcbiAgICB0aGlzLl9vcmRlclN5bmNocm9uaXphdGlvbkZpbmlzaGVkWycnICsgaW5zdGFuY2VdID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gY29ubmVjdGlvbiB0byBNZXRhVHJhZGVyIHRlcm1pbmFsIGVzdGFibGlzaGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnN0YW5jZUluZGV4IGluZGV4IG9mIGFuIGFjY291bnQgaW5zdGFuY2UgY29ubmVjdGVkXG4gICAqL1xuICBvbkNvbm5lY3RlZChpbnN0YW5jZUluZGV4KSB7XG4gICAgY29uc3QgaW5zdGFuY2UgPSB0aGlzLmdldEluc3RhbmNlTnVtYmVyKGluc3RhbmNlSW5kZXgpO1xuICAgIHRoaXMuX29yZGVyU3luY2hyb25pemF0aW9uRmluaXNoZWRbJycgKyBpbnN0YW5jZV0gPSBmYWxzZTtcbiAgICB0aGlzLl9kZWFsU3luY2hyb25pemF0aW9uRmluaXNoZWRbJycgKyBpbnN0YW5jZV0gPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFsbCBkZWFsc1xuICAgKiBAcmV0dXJucyB7QXJyYXk8TWV0YXRyYWRlckRlYWw+fSBhbGwgZGVhbHNcbiAgICovXG4gIGdldCBkZWFscygpIHtcbiAgICB0aHJvdyBFcnJvcignQWJzdHJhY3QgcHJvcGVydHkgZGVhbHMgaGFzIG5vIGltcGxlbWVudGF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBkZWFscyBieSB0aWNrZXQgaWRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGlkIHRpY2tldCBpZFxuICAgKiBAcmV0dXJucyB7QXJyYXk8TWV0YXRyYWRlckRlYWw+fSBkZWFscyBmb3VuZFxuICAgKi9cbiAgZ2V0RGVhbHNCeVRpY2tldChpZCkge1xuICAgIHRocm93IEVycm9yKCdBYnN0cmFjdCBtZXRob2QgZ2V0RGVhbHNCeVRpY2tldCBoYXMgbm8gaW1wbGVtZW50YXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGRlYWxzIGJ5IHBvc2l0aW9uIGlkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwb3NpdGlvbklkIHBvc2l0aW9uIGlkXG4gICAqIEByZXR1cm5zIHtBcnJheTxNZXRhdHJhZGVyRGVhbD59IGRlYWxzIGZvdW5kXG4gICAqL1xuICBnZXREZWFsc0J5UG9zaXRpb24ocG9zaXRpb25JZCkge1xuICAgIHRocm93IEVycm9yKCdBYnN0cmFjdCBtZXRob2QgZ2V0RGVhbHNCeVBvc2l0aW9uIGhhcyBubyBpbXBsZW1lbnRhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgZGVhbHMgYnkgdGltZSByYW5nZVxuICAgKiBAcGFyYW0gc3RhcnRUaW1lIHN0YXJ0IHRpbWUsIGluY2x1c2l2ZVxuICAgKiBAcGFyYW0gZW5kVGltZSBlbmQgdGltZSwgaW5jbHVzaXZlXG4gICAqIEByZXR1cm5zIHtBcnJheTxNZXRhdHJhZGVyRGVhbD59IGRlYWxzIGZvdW5kXG4gICAqL1xuICBnZXREZWFsc0J5VGltZVJhbmdlKHN0YXJ0VGltZSwgZW5kVGltZSkge1xuICAgIHRocm93IEVycm9yKCdBYnN0cmFjdCBtZXRob2QgZ2V0RGVhbHNCeVRpbWVSYW5nZSBoYXMgbm8gaW1wbGVtZW50YXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFsbCBoaXN0b3J5IG9yZGVyc1xuICAgKiBAcmV0dXJucyB7QXJyYXk8TWV0YXRyYWRlck9yZGVyPn0gYWxsIGhpc3Rvcnkgb3JkZXJzXG4gICAqL1xuICBnZXQgaGlzdG9yeU9yZGVycygpIHtcbiAgICB0aHJvdyBFcnJvcignQWJzdHJhY3QgcHJvcGVydHkgaGlzdG9yeU9yZGVycyBoYXMgbm8gaW1wbGVtZW50YXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGhpc3Rvcnkgb3JkZXJzIGJ5IHRpY2tldCBpZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgdGlja2V0IGlkXG4gICAqIEByZXR1cm5zIHtBcnJheTxNZXRhdHJhZGVyT3JkZXI+fSBoaXN0b3J5IG9yZGVycyBmb3VuZFxuICAgKi9cbiAgZ2V0SGlzdG9yeU9yZGVyc0J5VGlja2V0KGlkKSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Fic3RyYWN0IG1ldGhvZCBnZXRIaXN0b3J5T3JkZXJzQnlUaWNrZXQgaGFzIG5vIGltcGxlbWVudGF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBoaXN0b3J5IG9yZGVycyBieSBwb3NpdGlvbiBpZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gcG9zaXRpb25JZCBwb3NpdGlvbiBpZFxuICAgKiBAcmV0dXJucyB7QXJyYXk8TWV0YXRyYWRlck9yZGVyPn0gaGlzdG9yeSBvcmRlcnMgZm91bmRcbiAgICovXG4gIGdldEhpc3RvcnlPcmRlcnNCeVBvc2l0aW9uKHBvc2l0aW9uSWQpIHtcbiAgICB0aHJvdyBFcnJvcignQWJzdHJhY3QgbWV0aG9kIGdldEhpc3RvcnlPcmRlcnNCeVBvc2l0aW9uIGhhcyBubyBpbXBsZW1lbnRhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgaGlzdG9yeSBvcmRlcnMgYnkgdGltZSByYW5nZVxuICAgKiBAcGFyYW0gc3RhcnRUaW1lIHN0YXJ0IHRpbWUsIGluY2x1c2l2ZVxuICAgKiBAcGFyYW0gZW5kVGltZSBlbmQgdGltZSwgaW5jbHVzaXZlXG4gICAqIEByZXR1cm5zIHtBcnJheTxNZXRhdHJhZGVyT3JkZXI+fSBoaXNvdHJ5IG9yZGVycyBmb3VuZFxuICAgKi9cbiAgZ2V0SGlzdG9yeU9yZGVyc0J5VGltZVJhbmdlKHN0YXJ0VGltZSwgZW5kVGltZSkge1xuICAgIHRocm93IEVycm9yKCdBYnN0cmFjdCBtZXRob2QgZ2V0SGlzdG9yeU9yZGVyc0J5VGltZVJhbmdlIGhhcyBubyBpbXBsZW1lbnRhdGlvbicpO1xuICB9XG5cbn1cbiJdLCJuYW1lcyI6WyJIaXN0b3J5U3RvcmFnZSIsIlN5bmNocm9uaXphdGlvbkxpc3RlbmVyIiwiaW5pdGlhbGl6ZSIsImFjY291bnRJZCIsImFwcGxpY2F0aW9uIiwiX2FjY291bnRJZCIsIl9hcHBsaWNhdGlvbiIsIm9yZGVyU3luY2hyb25pemF0aW9uRmluaXNoZWQiLCJPYmplY3QiLCJ2YWx1ZXMiLCJfb3JkZXJTeW5jaHJvbml6YXRpb25GaW5pc2hlZCIsInJlZHVjZSIsImFjYyIsInIiLCJkZWFsU3luY2hyb25pemF0aW9uRmluaXNoZWQiLCJfZGVhbFN5bmNocm9uaXphdGlvbkZpbmlzaGVkIiwiY2xlYXIiLCJFcnJvciIsImxhc3RIaXN0b3J5T3JkZXJUaW1lIiwiaW5zdGFuY2VJbmRleCIsImxhc3REZWFsVGltZSIsIm9uSGlzdG9yeU9yZGVyQWRkZWQiLCJoaXN0b3J5T3JkZXIiLCJvbkRlYWxBZGRlZCIsImRlYWwiLCJvbkRlYWxzU3luY2hyb25pemVkIiwic3luY2hyb25pemF0aW9uSWQiLCJpbnN0YW5jZSIsImdldEluc3RhbmNlTnVtYmVyIiwib25IaXN0b3J5T3JkZXJzU3luY2hyb25pemVkIiwib25Db25uZWN0ZWQiLCJkZWFscyIsImdldERlYWxzQnlUaWNrZXQiLCJpZCIsImdldERlYWxzQnlQb3NpdGlvbiIsInBvc2l0aW9uSWQiLCJnZXREZWFsc0J5VGltZVJhbmdlIiwic3RhcnRUaW1lIiwiZW5kVGltZSIsImhpc3RvcnlPcmRlcnMiLCJnZXRIaXN0b3J5T3JkZXJzQnlUaWNrZXQiLCJnZXRIaXN0b3J5T3JkZXJzQnlQb3NpdGlvbiIsImdldEhpc3RvcnlPcmRlcnNCeVRpbWVSYW5nZSIsImNvbnN0cnVjdG9yIl0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7OztlQU9xQkE7OztnRkFMZTs7Ozs7O0FBS3JCLElBQUEsQUFBTUEsaUJBQU4sTUFBTUEsdUJBQXVCQyxnQ0FBdUI7SUFXakU7Ozs7O0dBS0MsR0FDRCxNQUFNQyxXQUFXQyxTQUFTLEVBQUVDLFdBQVcsRUFBRTtR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