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)

253 lines (252 loc) 32.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function() { return Reservoir; } }); let Reservoir = class Reservoir { checkStatisticsOnRestore(statistics) { if (statistics.count === 0) { statistics = { count: 0, sum: 0, max: undefined, min: undefined, average: undefined, sumOfSquares: 0, msdev: undefined, stddev: undefined }; } else if (statistics.count < 2) { statistics.msdev = undefined; statistics.stddev = undefined; } return statistics; } /** * Add element to Reservoir * @param {Number} data to add */ pushMeasurement(data) { if (isFinite(data)) { this._updateQueue(); this._updateIntermediaryRecord(data); this._updateStatisticsOnAdd(data); } } /** * return Reservoir statistics * @return {Object} Reservoir statistics */ getStatistics() { this._updateQueue(); return this.statistics; } toPlainObject() { this._updateQueue(true); return { array: this.array, size: this.size, _interval: this._interval, _queueEndTime: this._queueEndTime, _fisrtQueueIndex: this._fisrtQueueIndex, _intermediaryRecord: this._intermediaryRecord, statistics: this.statistics }; } _updateQueue() { let intervalsCount = this._takeTimeIntervalsCount(); let emptyElementsCount = this._takeEmptyElementsAddCount(); if (emptyElementsCount > 0) { this._addRecord(emptyElementsCount); this._queueEndTime += intervalsCount * this._interval; } } _takeEmptyElementsAddCount() { let emptyElementsCount = this._takeTimeIntervalsCount(); if (emptyElementsCount > this.size) { emptyElementsCount = this.size; } return emptyElementsCount; } _takeTimeIntervalsCount() { let timeNow = Date.now(); let timeDiff = timeNow - this._queueEndTime; let timeIntervalsCount = Math.floor(timeDiff / this._interval); return timeIntervalsCount; } _updateRunningStatisticsOnRemove(removeCount) { let removeElementIndex = this._fisrtQueueIndex + 1; for(let i = 0; i < removeCount; i++){ if (removeElementIndex >= this.size) { removeElementIndex = 0; } this._updateStatisticsOnRemove(this.array[removeElementIndex], removeElementIndex); this.array[removeElementIndex] = { count: 0, sum: 0, max: undefined, min: undefined, average: 0, sumOfSquares: 0 }; removeElementIndex++; } removeElementIndex--; if (removeElementIndex < 0) { removeElementIndex = this.size - 1; } return removeElementIndex; } _updateStatisticsOnRemove(removeElement, removeElementIndex) { if (removeElement !== undefined && removeElement !== null) { this.statistics.count -= removeElement.count; this.statistics.sumOfSquares -= removeElement.sumOfSquares; this.statistics.sum -= removeElement.sum; this._updateStatisticsMinAndMaxOnRemove(removeElement, removeElementIndex); if (this.statistics.count > 0) { this.statistics.average = this.statistics.sum / this.statistics.count; if (this.statistics.count > 1) { let difOfSums = this._calculateDifferenceOfSums(this.statistics.sumOfSquares, this.statistics.sum, this.statistics.count); this.statistics.msdev = parseFloat(Math.sqrt(difOfSums / this.statistics.count)); this.statistics.stddev = parseFloat(Math.sqrt(difOfSums / (this.statistics.count - 1))); } else { this.statistics.stddev = undefined; this.statistics.msdev = undefined; } } else { this.statistics.average = undefined; this.statistics.stddev = undefined; this.statistics.msdev = undefined; } } } _updateStatisticsMinAndMaxOnRemove(removeElement, removeElementIndex) { if (removeElement.max !== undefined && removeElement.max === this.statistics.max) { this.statistics.max = this._findMax(removeElementIndex); } if (removeElement.min !== undefined && removeElement.min === this.statistics.min) { this.statistics.min = this._findMin(removeElementIndex); } } _updateStatisticsOnAdd(el) { if (el !== undefined && el !== null) { this.statistics.count += 1; this.statistics.sum += el; this._updateStatisticsMinAndMaxOnAdd(el); this.statistics.sumOfSquares += Math.pow(el, 2); if (this.statistics.count > 0) { this.statistics.average = this.statistics.sum / this.statistics.count; let difOfSums = this._calculateDifferenceOfSums(this.statistics.sumOfSquares, this.statistics.sum, this.statistics.count); if (this.statistics.count > 1) { this.statistics.msdev = parseFloat(Math.sqrt(difOfSums / this.statistics.count)); this.statistics.stddev = parseFloat(Math.sqrt(difOfSums / (this.statistics.count - 1))); } else { this.statistics.msdev = undefined; this.statistics.stddev = undefined; } } } } _updateStatisticsMinAndMaxOnAdd(el) { if (this.statistics.max < el || this.statistics.max === undefined || this.statistics.max === null) { this.statistics.max = el; } if (this.statistics.min > el || this.statistics.min === undefined || this.statistics.min === null) { this.statistics.min = el; } } _addRecord(emptyElementsCount) { if (this._intermediaryRecord !== undefined) { this.array[this._fisrtQueueIndex] = this._intermediaryRecord; this._intermediaryRecord = undefined; } let curIndexInArray = this._updateRunningStatisticsOnRemove(emptyElementsCount); this._fisrtQueueIndex = curIndexInArray; } _calculateDifferenceOfSums(sum1, sum2, count) { let dif = sum1 - Math.pow(sum2, 2) / count; return dif; } _updateIntermediaryRecord(el) { if (this._intermediaryRecord === undefined) { this._intermediaryRecord = { count: 1, sum: el, max: el, min: el, average: el, sumOfSquares: Math.pow(el, 2) }; } else { if (this._intermediaryRecord.max < el) { this._intermediaryRecord.max = el; } if (this._intermediaryRecord.min > el) { this._intermediaryRecord.min = el; } this._intermediaryRecord.count += 1; this._intermediaryRecord.sum += el; this._intermediaryRecord.sumOfSquares += Math.pow(el, 2); } } _findMin(index) { let min = Infinity; this.array.forEach((el, i)=>{ if (el !== null && el !== undefined && el.min !== undefined && el.min < min && i !== index) { min = el.min; } }); if (min === Infinity) { return this._intermediaryRecord !== undefined ? this._intermediaryRecord.min : undefined; } return min; } _findMax(index) { let max = -Infinity; this.array.forEach((el, i)=>{ if (el !== null && el !== undefined && el.max !== undefined && el.max > max && i !== index) { max = el.max; } }); if (max === -Infinity) { return this._intermediaryRecord !== undefined ? this._intermediaryRecord.max : undefined; } return max; } /** * Constructs Reservoir * @param {number} size Reservoir size * @param {number} observationIntervalInMS Reservoir observation Interval In ms */ constructor(size, observationIntervalInMS, object){ if (!object) { this.array = []; this.size = size; this._interval = observationIntervalInMS / size; this._queueEndTime = Date.now(); this._fisrtQueueIndex = 0; this._intermediaryRecord = undefined; this.statistics = { count: 0, sum: 0, max: undefined, min: undefined, average: 0, sumOfSquares: 0, msdev: 0, stddev: 0 }; } else { this.array = object.array; this.size = object.size; this._interval = object._interval; this._queueEndTime = object._queueEndTime; this._fisrtQueueIndex = object._fisrtQueueIndex; this._intermediaryRecord = object._intermediaryRecord; this.statistics = this.checkStatisticsOnRestore(object.statistics); } } }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjxhbm9uPiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogRklGTy1saWtlIHJlc2Vydm9pciBvZiBhIGZpeGVkIHNpemUgY2FwYWJsZVxuICogY2FsY3VsYXRpbmcgcnVubmluZyBzdW1zLCBtaW4vbWF4LCBhdmVyYWdlLCBtc2RldiBhbmQgc3RkZGV2XG4gKiBtc2RldiBhbmQgc3RkZGV2IGNhbGN1bGF0aW9uIGJ5IE5haXZlIGFsZ29yaXRobVxuICogKE1lYW4gc3F1YXJlIGRldmlhdGlvbikgbXNkZXYgPSBzcXJ0KCjiiJF7aSA9IGZyb20gMSB0byBufShYaSleMiAtKOKIkXtpID0gZnJvbSAxIHRvIG59WGkpXjIgLyBOKSAvIE4pXG4gKiAoU3RhbmRhcmQgZGV2aWF0aW9uKSBzdGRkZXYgPSBzcXJ0KCjiiJF7aSA9IGZyb20gMSB0byBufShYaSleMiAtKOKIkXtpID0gZnJvbSAxIHRvIG59WGkpXjIgLyBOKSAvIE4gLSAxKVxuICogbGluazogaHR0cHM6Ly9nb28uZ2wvTUFFR1AyXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlc2Vydm9pciB7XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdHMgUmVzZXJ2b2lyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIFJlc2Vydm9pciBzaXplXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYnNlcnZhdGlvbkludGVydmFsSW5NUyBSZXNlcnZvaXIgb2JzZXJ2YXRpb24gSW50ZXJ2YWwgSW4gbXNcbiAgICovXG4gIGNvbnN0cnVjdG9yKHNpemUsIG9ic2VydmF0aW9uSW50ZXJ2YWxJbk1TLCBvYmplY3QpIHtcbiAgICBpZiAoIW9iamVjdCkge1xuICAgICAgdGhpcy5hcnJheSA9IFtdO1xuICAgICAgdGhpcy5zaXplID0gc2l6ZTtcbiAgICAgIHRoaXMuX2ludGVydmFsID0gKG9ic2VydmF0aW9uSW50ZXJ2YWxJbk1TIC8gc2l6ZSk7XG4gICAgICB0aGlzLl9xdWV1ZUVuZFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgdGhpcy5fZmlzcnRRdWV1ZUluZGV4ID0gMDtcbiAgICAgIHRoaXMuX2ludGVybWVkaWFyeVJlY29yZCA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuc3RhdGlzdGljcyA9IHtcbiAgICAgICAgY291bnQ6IDAsXG4gICAgICAgIHN1bTogMCxcbiAgICAgICAgbWF4OiB1bmRlZmluZWQsXG4gICAgICAgIG1pbjogdW5kZWZpbmVkLFxuICAgICAgICBhdmVyYWdlOiAwLFxuICAgICAgICBzdW1PZlNxdWFyZXM6IDAsXG4gICAgICAgIG1zZGV2OiAwLFxuICAgICAgICBzdGRkZXY6IDBcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXJyYXkgPSBvYmplY3QuYXJyYXk7XG4gICAgICB0aGlzLnNpemUgPSBvYmplY3Quc2l6ZTtcbiAgICAgIHRoaXMuX2ludGVydmFsID0gb2JqZWN0Ll9pbnRlcnZhbDtcbiAgICAgIHRoaXMuX3F1ZXVlRW5kVGltZSA9IG9iamVjdC5fcXVldWVFbmRUaW1lO1xuICAgICAgdGhpcy5fZmlzcnRRdWV1ZUluZGV4ID0gb2JqZWN0Ll9maXNydFF1ZXVlSW5kZXg7XG4gICAgICB0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQgPSBvYmplY3QuX2ludGVybWVkaWFyeVJlY29yZDtcbiAgICAgIHRoaXMuc3RhdGlzdGljcyA9IHRoaXMuY2hlY2tTdGF0aXN0aWNzT25SZXN0b3JlKG9iamVjdC5zdGF0aXN0aWNzKTtcbiAgICB9XG4gIH1cblxuICBjaGVja1N0YXRpc3RpY3NPblJlc3RvcmUoc3RhdGlzdGljcykge1xuICAgIGlmIChzdGF0aXN0aWNzLmNvdW50ID09PSAwKSB7XG4gICAgICBzdGF0aXN0aWNzID0ge1xuICAgICAgICBjb3VudDogMCxcbiAgICAgICAgc3VtOiAwLFxuICAgICAgICBtYXg6IHVuZGVmaW5lZCxcbiAgICAgICAgbWluOiB1bmRlZmluZWQsXG4gICAgICAgIGF2ZXJhZ2U6IHVuZGVmaW5lZCxcbiAgICAgICAgc3VtT2ZTcXVhcmVzOiAwLFxuICAgICAgICBtc2RldjogdW5kZWZpbmVkLFxuICAgICAgICBzdGRkZXY6IHVuZGVmaW5lZFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHN0YXRpc3RpY3MuY291bnQgPCAyKSB7XG4gICAgICBzdGF0aXN0aWNzLm1zZGV2ID0gdW5kZWZpbmVkO1xuICAgICAgc3RhdGlzdGljcy5zdGRkZXYgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBzdGF0aXN0aWNzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBlbGVtZW50IHRvIFJlc2Vydm9pclxuICAgKiBAcGFyYW0ge051bWJlcn0gZGF0YSB0byBhZGRcbiAgICovXG4gIHB1c2hNZWFzdXJlbWVudChkYXRhKSB7XG4gICAgaWYgKGlzRmluaXRlKGRhdGEpKSB7XG4gICAgICB0aGlzLl91cGRhdGVRdWV1ZSgpO1xuICAgICAgdGhpcy5fdXBkYXRlSW50ZXJtZWRpYXJ5UmVjb3JkKGRhdGEpO1xuICAgICAgdGhpcy5fdXBkYXRlU3RhdGlzdGljc09uQWRkKGRhdGEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiByZXR1cm4gUmVzZXJ2b2lyIHN0YXRpc3RpY3NcbiAgICogQHJldHVybiB7T2JqZWN0fSBSZXNlcnZvaXIgc3RhdGlzdGljc1xuICAgKi9cbiAgZ2V0U3RhdGlzdGljcygpIHtcbiAgICB0aGlzLl91cGRhdGVRdWV1ZSgpO1xuICAgIHJldHVybiB0aGlzLnN0YXRpc3RpY3M7XG4gIH1cblxuICB0b1BsYWluT2JqZWN0KCkge1xuICAgIHRoaXMuX3VwZGF0ZVF1ZXVlKHRydWUpO1xuICAgIHJldHVybiB7XG4gICAgICBhcnJheTogdGhpcy5hcnJheSxcbiAgICAgIHNpemU6IHRoaXMuc2l6ZSxcbiAgICAgIF9pbnRlcnZhbDogdGhpcy5faW50ZXJ2YWwsXG4gICAgICBfcXVldWVFbmRUaW1lOiB0aGlzLl9xdWV1ZUVuZFRpbWUsXG4gICAgICBfZmlzcnRRdWV1ZUluZGV4OiB0aGlzLl9maXNydFF1ZXVlSW5kZXgsXG4gICAgICBfaW50ZXJtZWRpYXJ5UmVjb3JkOiB0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQsXG4gICAgICBzdGF0aXN0aWNzOiB0aGlzLnN0YXRpc3RpY3NcbiAgICB9O1xuICB9XG5cbiAgX3VwZGF0ZVF1ZXVlKCkge1xuICAgIGxldCBpbnRlcnZhbHNDb3VudCA9IHRoaXMuX3Rha2VUaW1lSW50ZXJ2YWxzQ291bnQoKTtcbiAgICBsZXQgZW1wdHlFbGVtZW50c0NvdW50ID0gdGhpcy5fdGFrZUVtcHR5RWxlbWVudHNBZGRDb3VudCgpO1xuICAgIGlmIChlbXB0eUVsZW1lbnRzQ291bnQgPiAwKSB7XG4gICAgICB0aGlzLl9hZGRSZWNvcmQoZW1wdHlFbGVtZW50c0NvdW50KTtcbiAgICAgIHRoaXMuX3F1ZXVlRW5kVGltZSArPSBpbnRlcnZhbHNDb3VudCAqIHRoaXMuX2ludGVydmFsO1xuICAgIH1cbiAgfVxuXG4gIF90YWtlRW1wdHlFbGVtZW50c0FkZENvdW50KCkge1xuICAgIGxldCBlbXB0eUVsZW1lbnRzQ291bnQgPSB0aGlzLl90YWtlVGltZUludGVydmFsc0NvdW50KCk7XG4gICAgaWYgKGVtcHR5RWxlbWVudHNDb3VudCA+IHRoaXMuc2l6ZSkge1xuICAgICAgZW1wdHlFbGVtZW50c0NvdW50ID0gdGhpcy5zaXplO1xuICAgIH1cbiAgICByZXR1cm4gZW1wdHlFbGVtZW50c0NvdW50O1xuICB9XG5cbiAgX3Rha2VUaW1lSW50ZXJ2YWxzQ291bnQoKSB7XG4gICAgbGV0IHRpbWVOb3cgPSBEYXRlLm5vdygpO1xuICAgIGxldCB0aW1lRGlmZiA9IHRpbWVOb3cgLSB0aGlzLl9xdWV1ZUVuZFRpbWU7XG4gICAgbGV0IHRpbWVJbnRlcnZhbHNDb3VudCA9IE1hdGguZmxvb3IodGltZURpZmYgLyB0aGlzLl9pbnRlcnZhbCk7XG4gICAgcmV0dXJuIHRpbWVJbnRlcnZhbHNDb3VudDtcbiAgfVxuXG4gIF91cGRhdGVSdW5uaW5nU3RhdGlzdGljc09uUmVtb3ZlKHJlbW92ZUNvdW50KSB7XG4gICAgbGV0IHJlbW92ZUVsZW1lbnRJbmRleCA9IHRoaXMuX2Zpc3J0UXVldWVJbmRleCArIDE7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZW1vdmVDb3VudDsgaSsrKSB7XG4gICAgICBpZiAocmVtb3ZlRWxlbWVudEluZGV4ID49IHRoaXMuc2l6ZSkge1xuICAgICAgICByZW1vdmVFbGVtZW50SW5kZXggPSAwO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl91cGRhdGVTdGF0aXN0aWNzT25SZW1vdmUodGhpcy5hcnJheVtyZW1vdmVFbGVtZW50SW5kZXhdLCByZW1vdmVFbGVtZW50SW5kZXgpO1xuICAgICAgdGhpcy5hcnJheVtyZW1vdmVFbGVtZW50SW5kZXhdID0ge1xuICAgICAgICBjb3VudDogMCxcbiAgICAgICAgc3VtOiAwLFxuICAgICAgICBtYXg6IHVuZGVmaW5lZCxcbiAgICAgICAgbWluOiB1bmRlZmluZWQsXG4gICAgICAgIGF2ZXJhZ2U6IDAsXG4gICAgICAgIHN1bU9mU3F1YXJlczogMFxuICAgICAgfTtcbiAgICAgIHJlbW92ZUVsZW1lbnRJbmRleCsrO1xuICAgIH1cbiAgICByZW1vdmVFbGVtZW50SW5kZXgtLTtcbiAgICBpZiAocmVtb3ZlRWxlbWVudEluZGV4IDwgMCkge1xuICAgICAgcmVtb3ZlRWxlbWVudEluZGV4ID0gdGhpcy5zaXplIC0gMTtcbiAgICB9XG4gICAgcmV0dXJuIHJlbW92ZUVsZW1lbnRJbmRleDtcbiAgfVxuXG4gIF91cGRhdGVTdGF0aXN0aWNzT25SZW1vdmUocmVtb3ZlRWxlbWVudCwgcmVtb3ZlRWxlbWVudEluZGV4KSB7XG4gICAgaWYgKHJlbW92ZUVsZW1lbnQgIT09IHVuZGVmaW5lZCAmJiByZW1vdmVFbGVtZW50ICE9PSBudWxsKSB7XG4gICAgICB0aGlzLnN0YXRpc3RpY3MuY291bnQgLT0gcmVtb3ZlRWxlbWVudC5jb3VudDtcbiAgICAgIHRoaXMuc3RhdGlzdGljcy5zdW1PZlNxdWFyZXMgLT0gcmVtb3ZlRWxlbWVudC5zdW1PZlNxdWFyZXM7XG4gICAgICB0aGlzLnN0YXRpc3RpY3Muc3VtIC09IHJlbW92ZUVsZW1lbnQuc3VtO1xuICAgICAgdGhpcy5fdXBkYXRlU3RhdGlzdGljc01pbkFuZE1heE9uUmVtb3ZlKHJlbW92ZUVsZW1lbnQsIHJlbW92ZUVsZW1lbnRJbmRleCk7XG4gICAgICBpZiAodGhpcy5zdGF0aXN0aWNzLmNvdW50ID4gMCkge1xuICAgICAgICB0aGlzLnN0YXRpc3RpY3MuYXZlcmFnZSA9IHRoaXMuc3RhdGlzdGljcy5zdW0gLyB0aGlzLnN0YXRpc3RpY3MuY291bnQ7XG4gICAgICAgIGlmICh0aGlzLnN0YXRpc3RpY3MuY291bnQgPiAxKSB7XG4gICAgICAgICAgbGV0IGRpZk9mU3VtcyA9IHRoaXMuX2NhbGN1bGF0ZURpZmZlcmVuY2VPZlN1bXModGhpcy5zdGF0aXN0aWNzLnN1bU9mU3F1YXJlcyxcbiAgICAgICAgICAgIHRoaXMuc3RhdGlzdGljcy5zdW0sIHRoaXMuc3RhdGlzdGljcy5jb3VudCk7XG4gICAgICAgICAgdGhpcy5zdGF0aXN0aWNzLm1zZGV2ID0gcGFyc2VGbG9hdChNYXRoLnNxcnQoZGlmT2ZTdW1zIC8gdGhpcy5zdGF0aXN0aWNzLmNvdW50KSk7XG4gICAgICAgICAgdGhpcy5zdGF0aXN0aWNzLnN0ZGRldiA9IHBhcnNlRmxvYXQoTWF0aC5zcXJ0KGRpZk9mU3VtcyAvICh0aGlzLnN0YXRpc3RpY3MuY291bnQgLSAxKSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuc3RhdGlzdGljcy5zdGRkZXYgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgdGhpcy5zdGF0aXN0aWNzLm1zZGV2ID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnN0YXRpc3RpY3MuYXZlcmFnZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5zdGF0aXN0aWNzLnN0ZGRldiA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5zdGF0aXN0aWNzLm1zZGV2ID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF91cGRhdGVTdGF0aXN0aWNzTWluQW5kTWF4T25SZW1vdmUocmVtb3ZlRWxlbWVudCwgcmVtb3ZlRWxlbWVudEluZGV4KSB7XG4gICAgaWYgKHJlbW92ZUVsZW1lbnQubWF4ICE9PSB1bmRlZmluZWQgJiYgcmVtb3ZlRWxlbWVudC5tYXggPT09IHRoaXMuc3RhdGlzdGljcy5tYXgpIHtcbiAgICAgIHRoaXMuc3RhdGlzdGljcy5tYXggPSB0aGlzLl9maW5kTWF4KHJlbW92ZUVsZW1lbnRJbmRleCk7XG4gICAgfVxuXG4gICAgaWYgKHJlbW92ZUVsZW1lbnQubWluICE9PSB1bmRlZmluZWQgJiYgcmVtb3ZlRWxlbWVudC5taW4gPT09IHRoaXMuc3RhdGlzdGljcy5taW4pIHtcbiAgICAgIHRoaXMuc3RhdGlzdGljcy5taW4gPSB0aGlzLl9maW5kTWluKHJlbW92ZUVsZW1lbnRJbmRleCk7XG4gICAgfVxuICB9XG5cbiAgX3VwZGF0ZVN0YXRpc3RpY3NPbkFkZChlbCkge1xuICAgIGlmIChlbCAhPT0gdW5kZWZpbmVkICYmIGVsICE9PSBudWxsKSB7XG4gICAgICB0aGlzLnN0YXRpc3RpY3MuY291bnQgKz0gMTtcbiAgICAgIHRoaXMuc3RhdGlzdGljcy5zdW0gKz0gZWw7XG4gICAgICB0aGlzLl91cGRhdGVTdGF0aXN0aWNzTWluQW5kTWF4T25BZGQoZWwpO1xuICAgICAgdGhpcy5zdGF0aXN0aWNzLnN1bU9mU3F1YXJlcyArPSBNYXRoLnBvdyhlbCwgMik7XG4gICAgICBpZiAodGhpcy5zdGF0aXN0aWNzLmNvdW50ID4gMCkge1xuICAgICAgICB0aGlzLnN0YXRpc3RpY3MuYXZlcmFnZSA9IHRoaXMuc3RhdGlzdGljcy5zdW0gLyB0aGlzLnN0YXRpc3RpY3MuY291bnQ7XG4gICAgICAgIGxldCBkaWZPZlN1bXMgPSB0aGlzLl9jYWxjdWxhdGVEaWZmZXJlbmNlT2ZTdW1zKHRoaXMuc3RhdGlzdGljcy5zdW1PZlNxdWFyZXMsXG4gICAgICAgICAgdGhpcy5zdGF0aXN0aWNzLnN1bSwgdGhpcy5zdGF0aXN0aWNzLmNvdW50KTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGlzdGljcy5jb3VudCA+IDEpIHtcbiAgICAgICAgICB0aGlzLnN0YXRpc3RpY3MubXNkZXYgPSBwYXJzZUZsb2F0KE1hdGguc3FydChkaWZPZlN1bXMgLyB0aGlzLnN0YXRpc3RpY3MuY291bnQpKTtcbiAgICAgICAgICB0aGlzLnN0YXRpc3RpY3Muc3RkZGV2ID0gcGFyc2VGbG9hdChNYXRoLnNxcnQoZGlmT2ZTdW1zIC8gKHRoaXMuc3RhdGlzdGljcy5jb3VudCAtIDEpKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zdGF0aXN0aWNzLm1zZGV2ID0gdW5kZWZpbmVkO1xuICAgICAgICAgIHRoaXMuc3RhdGlzdGljcy5zdGRkZXYgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfdXBkYXRlU3RhdGlzdGljc01pbkFuZE1heE9uQWRkKGVsKSB7XG4gICAgaWYgKHRoaXMuc3RhdGlzdGljcy5tYXggPCBlbCB8fCB0aGlzLnN0YXRpc3RpY3MubWF4ID09PSB1bmRlZmluZWQgfHwgdGhpcy5zdGF0aXN0aWNzLm1heCA9PT0gbnVsbCkge1xuICAgICAgdGhpcy5zdGF0aXN0aWNzLm1heCA9IGVsO1xuICAgIH1cbiAgICBpZiAodGhpcy5zdGF0aXN0aWNzLm1pbiA+IGVsIHx8IHRoaXMuc3RhdGlzdGljcy5taW4gPT09IHVuZGVmaW5lZCB8fCB0aGlzLnN0YXRpc3RpY3MubWluID09PSBudWxsKSB7XG4gICAgICB0aGlzLnN0YXRpc3RpY3MubWluID0gZWw7XG4gICAgfVxuICB9XG5cbiAgX2FkZFJlY29yZChlbXB0eUVsZW1lbnRzQ291bnQpIHtcbiAgICBpZiAodGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuYXJyYXlbdGhpcy5fZmlzcnRRdWV1ZUluZGV4XSA9IHRoaXMuX2ludGVybWVkaWFyeVJlY29yZDtcbiAgICAgIHRoaXMuX2ludGVybWVkaWFyeVJlY29yZCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgbGV0IGN1ckluZGV4SW5BcnJheSA9IHRoaXMuX3VwZGF0ZVJ1bm5pbmdTdGF0aXN0aWNzT25SZW1vdmUoZW1wdHlFbGVtZW50c0NvdW50KTtcbiAgICB0aGlzLl9maXNydFF1ZXVlSW5kZXggPSBjdXJJbmRleEluQXJyYXk7XG4gIH1cblxuICBfY2FsY3VsYXRlRGlmZmVyZW5jZU9mU3VtcyhzdW0xLCBzdW0yLCBjb3VudCkge1xuICAgIGxldCBkaWYgPSBzdW0xIC0gTWF0aC5wb3coc3VtMiwgMikgLyBjb3VudDtcbiAgICByZXR1cm4gZGlmO1xuICB9XG5cbiAgX3VwZGF0ZUludGVybWVkaWFyeVJlY29yZChlbCkge1xuICAgIGlmICh0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkID0ge1xuICAgICAgICBjb3VudDogMSxcbiAgICAgICAgc3VtOiBlbCxcbiAgICAgICAgbWF4OiBlbCxcbiAgICAgICAgbWluOiBlbCxcbiAgICAgICAgYXZlcmFnZTogZWwsXG4gICAgICAgIHN1bU9mU3F1YXJlczogTWF0aC5wb3coZWwsIDIpXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkLm1heCA8IGVsKSB7XG4gICAgICAgIHRoaXMuX2ludGVybWVkaWFyeVJlY29yZC5tYXggPSBlbDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQubWluID4gZWwpIHtcbiAgICAgICAgdGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkLm1pbiA9IGVsO1xuICAgICAgfVxuICAgICAgdGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkLmNvdW50ICs9IDE7XG4gICAgICB0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQuc3VtICs9IGVsO1xuICAgICAgdGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkLnN1bU9mU3F1YXJlcyArPSBNYXRoLnBvdyhlbCwgMik7XG4gICAgfVxuICB9XG5cbiAgX2ZpbmRNaW4oaW5kZXgpIHtcbiAgICBsZXQgbWluID0gSW5maW5pdHk7XG4gICAgdGhpcy5hcnJheS5mb3JFYWNoKChlbCwgaSkgPT4ge1xuICAgICAgaWYgKGVsICE9PSBudWxsICYmIGVsICE9PSB1bmRlZmluZWQgJiYgZWwubWluICE9PSB1bmRlZmluZWQgJiYgZWwubWluIDwgbWluICYmIGkgIT09IGluZGV4KSB7XG4gICAgICAgIG1pbiA9IGVsLm1pbjtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAobWluID09PSBJbmZpbml0eSkge1xuICAgICAgcmV0dXJuICh0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQgIT09IHVuZGVmaW5lZCkgPyB0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQubWluIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gbWluO1xuICB9XG5cbiAgX2ZpbmRNYXgoaW5kZXgpIHtcbiAgICBsZXQgbWF4ID0gLUluZmluaXR5O1xuXG4gICAgdGhpcy5hcnJheS5mb3JFYWNoKChlbCwgaSkgPT4ge1xuICAgICAgaWYgKGVsICE9PSBudWxsICYmIGVsICE9PSB1bmRlZmluZWQgJiYgZWwubWF4ICE9PSB1bmRlZmluZWQgJiYgZWwubWF4ID4gbWF4ICYmIGkgIT09IGluZGV4KSB7XG4gICAgICAgIG1heCA9IGVsLm1heDtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAobWF4ID09PSAtSW5maW5pdHkpIHtcbiAgICAgIHJldHVybiAodGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkICE9PSB1bmRlZmluZWQpID8gdGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkLm1heCA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIG1heDtcbiAgfVxufVxuIl0sIm5hbWVzIjpbIlJlc2Vydm9pciIsImNoZWNrU3RhdGlzdGljc09uUmVzdG9yZSIsInN0YXRpc3RpY3MiLCJjb3VudCIsInN1bSIsIm1heCIsInVuZGVmaW5lZCIsIm1pbiIsImF2ZXJhZ2UiLCJzdW1PZlNxdWFyZXMiLCJtc2RldiIsInN0ZGRldiIsInB1c2hNZWFzdXJlbWVudCIsImRhdGEiLCJpc0Zpbml0ZSIsIl91cGRhdGVRdWV1ZSIsIl91cGRhdGVJbnRlcm1lZGlhcnlSZWNvcmQiLCJfdXBkYXRlU3RhdGlzdGljc09uQWRkIiwiZ2V0U3RhdGlzdGljcyIsInRvUGxhaW5PYmplY3QiLCJhcnJheSIsInNpemUiLCJfaW50ZXJ2YWwiLCJfcXVldWVFbmRUaW1lIiwiX2Zpc3J0UXVldWVJbmRleCIsIl9pbnRlcm1lZGlhcnlSZWNvcmQiLCJpbnRlcnZhbHNDb3VudCIsIl90YWtlVGltZUludGVydmFsc0NvdW50IiwiZW1wdHlFbGVtZW50c0NvdW50IiwiX3Rha2VFbXB0eUVsZW1lbnRzQWRkQ291bnQiLCJfYWRkUmVjb3JkIiwidGltZU5vdyIsIkRhdGUiLCJub3ciLCJ0aW1lRGlmZiIsInRpbWVJbnRlcnZhbHNDb3VudCIsIk1hdGgiLCJmbG9vciIsIl91cGRhdGVSdW5uaW5nU3RhdGlzdGljc09uUmVtb3ZlIiwicmVtb3ZlQ291bnQiLCJyZW1vdmVFbGVtZW50SW5kZXgiLCJpIiwiX3VwZGF0ZVN0YXRpc3RpY3NPblJlbW92ZSIsInJlbW92ZUVsZW1lbnQiLCJfdXBkYXRlU3RhdGlzdGljc01pbkFuZE1heE9uUmVtb3ZlIiwiZGlmT2ZTdW1zIiwiX2NhbGN1bGF0ZURpZmZlcmVuY2VPZlN1bXMiLCJwYXJzZUZsb2F0Iiwic3FydCIsIl9maW5kTWF4IiwiX2ZpbmRNaW4iLCJlbCIsIl91cGRhdGVTdGF0aXN0aWNzTWluQW5kTWF4T25BZGQiLCJwb3ciLCJjdXJJbmRleEluQXJyYXkiLCJzdW0xIiwic3VtMiIsImRpZiIsImluZGV4IiwiSW5maW5pdHkiLCJmb3JFYWNoIiwiY29uc3RydWN0b3IiLCJvYnNlcnZhdGlvbkludGVy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