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)

173 lines (172 loc) 21.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { HttpClientMock: function() { return HttpClientMock; }, default: function() { return HttpClient; } }); const _axios = /*#__PURE__*/ _interop_require_default(require("axios")); const _errorHandler = require("../../clients/errorHandler"); const _timeoutError = /*#__PURE__*/ _interop_require_default(require("../../clients/timeoutError")); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } let HttpClient = class HttpClient { /** * Performs a request. Response errors are returned as ApiError or subclasses. * @param {Object} options request options * @param {Boolean} isExtendedTimeout whether to run the request with an extended timeout * @returns {Object|String|any} request result */ async request(options, isExtendedTimeout) { options.timeout = isExtendedTimeout ? this._extendedTimeout : this._timeout; try { const response = await this._makeRequest(options); return response && response.data || undefined; } catch (err) { throw this._convertError(err); } } /** * Performs a request with a failover. Response errors are returned as ApiError or subclasses. * @param {Object} options request options * @returns {Object|String|any} request result */ async requestWithFailover(options, retryCounter = 0, endTime = Date.now() + this._maxRetryDelay * this._retries) { options.timeout = this._timeout; let retryAfterSeconds = 0; options.callback = (e, res)=>{ if (res && res.status === 202) { var _res_data_metadata, _res_data; var _res_headers_retryafter; retryAfterSeconds = (_res_headers_retryafter = res.headers["retry-after"]) !== null && _res_headers_retryafter !== void 0 ? _res_headers_retryafter : (_res_data = res.data) === null || _res_data === void 0 ? void 0 : (_res_data_metadata = _res_data.metadata) === null || _res_data_metadata === void 0 ? void 0 : _res_data_metadata.recommendedRetryTime; if (isNaN(retryAfterSeconds)) { retryAfterSeconds = Math.max((new Date(retryAfterSeconds).getTime() - Date.now()) / 1000, 1); } } }; let body; try { const response = await this._makeRequest(options); options.callback(null, response); body = response && response.data || undefined; } catch (err) { retryCounter = await this._handleError(err, retryCounter, endTime); return this.requestWithFailover(options, retryCounter, endTime); } if (retryAfterSeconds) { await this._handleRetry(endTime, retryAfterSeconds * 1000); body = await this.requestWithFailover(options, retryCounter, endTime); } return body; } _makeRequest(options) { return (0, _axios.default)({ transitional: { clarifyTimeoutError: true }, ...options }); } async _wait(pause) { await new Promise((res)=>setTimeout(res, pause)); } async _handleRetry(endTime, retryAfter) { if (endTime > Date.now() + retryAfter) { await this._wait(retryAfter); } else { throw new _timeoutError.default("Timed out waiting for the response"); } } async _handleError(err, retryCounter, endTime) { const error = this._convertError(err); if ([ "ConflictError", "InternalError", "ApiError", "TimeoutError" ].includes(error.name) && retryCounter < this._retries) { const pause = Math.min(Math.pow(2, retryCounter) * this._minRetryDelay, this._maxRetryDelay); await this._wait(pause); return retryCounter + 1; } else if (error.name === "TooManyRequestsError") { const retryTime = Date.parse(error.metadata.recommendedRetryTime); if (retryTime < endTime) { await this._wait(retryTime - Date.now()); return retryCounter; } } throw error; } // eslint-disable-next-line complexity _convertError(err) { var _err_config; const errorResponse = err.response || {}; const errorData = errorResponse.data || {}; const status = errorResponse.status || err.status; const url = err === null || err === void 0 ? void 0 : (_err_config = err.config) === null || _err_config === void 0 ? void 0 : _err_config.url; const errMsgDefault = errorData.message || err.code || err.message; const errMsg = errorData.message || err.message; switch(status){ case 400: return new _errorHandler.ValidationError(errMsg, errorData.details || err.details, url); case 401: return new _errorHandler.UnauthorizedError(errMsg, url); case 403: return new _errorHandler.ForbiddenError(errMsg, url); case 404: return new _errorHandler.NotFoundError(errMsg, url); case 409: return new _errorHandler.ConflictError(errMsg, url); case 429: return new _errorHandler.TooManyRequestsError(errMsg, errorData.metadata || err.metadata, url); case 500: return new _errorHandler.InternalError(errMsg, url); default: return new _errorHandler.ApiError(_errorHandler.ApiError, errMsgDefault, status, url); } } /** * @typedef {Object} RetryOptions retry options * @property {Number} [retries] the number of attempts to retry failed request, default 5 * @property {Number} [minDelayInSeconds] minimum delay in seconds before retrying, default 1 * @property {Number} [maxDelayInSeconds] maximum delay in seconds before retrying, default 30 */ /** * Constructs HttpClient class instance * @param {Number} [timeout] request timeout in seconds * @param {Number} [extendedTimeout] request timeout in seconds * @param {RetryOptions} [retryOpts] retry options */ constructor(timeout = 10, extendedTimeout = 70, retryOpts = {}){ this._timeout = timeout * 1000; this._extendedTimeout = extendedTimeout * 1000; this._retries = retryOpts.retries || 5; this._minRetryDelay = (retryOpts.minDelayInSeconds || 1) * 1000; this._maxRetryDelay = (retryOpts.maxDelayInSeconds || 30) * 1000; } }; let HttpClientMock = class HttpClientMock extends HttpClient { _makeRequest() { return this._requestFn.apply(this, arguments); } /** * Constructs HTTP client mock * @param {Function(options:Object):Promise} requestFn mocked request function * @param {Number} timeout request timeout in seconds * @param {RetryOptions} retryOpts retry options */ constructor(requestFn, timeout, extendedTimeout, retryOpts){ super(timeout, extendedTimeout, retryOpts); this._requestFn = requestFn; } }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjxhbm9uPiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBheGlvcyBmcm9tICdheGlvcyc7XG5pbXBvcnQge1xuICBVbmF1dGhvcml6ZWRFcnJvciwgRm9yYmlkZGVuRXJyb3IsIEFwaUVycm9yLCBWYWxpZGF0aW9uRXJyb3IsIEludGVybmFsRXJyb3IsIFxuICBOb3RGb3VuZEVycm9yLCBUb29NYW55UmVxdWVzdHNFcnJvciwgQ29uZmxpY3RFcnJvclxufSBmcm9tICcuLi8uLi9jbGllbnRzL2Vycm9ySGFuZGxlcic7XG5pbXBvcnQgVGltZW91dEVycm9yIGZyb20gJy4uLy4uL2NsaWVudHMvdGltZW91dEVycm9yJztcblxuLyoqXG4gKiBIVFRQIGNsaWVudCBsaWJyYXJ5IGJhc2VkIG9uIHJlcXVlc3QtcHJvbWlzZVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBIdHRwQ2xpZW50IHtcblxuICAvKipcbiAgICogQHR5cGVkZWYge09iamVjdH0gUmV0cnlPcHRpb25zIHJldHJ5IG9wdGlvbnNcbiAgICogQHByb3BlcnR5IHtOdW1iZXJ9IFtyZXRyaWVzXSB0aGUgbnVtYmVyIG9mIGF0dGVtcHRzIHRvIHJldHJ5IGZhaWxlZCByZXF1ZXN0LCBkZWZhdWx0IDVcbiAgICogQHByb3BlcnR5IHtOdW1iZXJ9IFttaW5EZWxheUluU2Vjb25kc10gbWluaW11bSBkZWxheSBpbiBzZWNvbmRzIGJlZm9yZSByZXRyeWluZywgZGVmYXVsdCAxXG4gICAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBbbWF4RGVsYXlJblNlY29uZHNdIG1heGltdW0gZGVsYXkgaW4gc2Vjb25kcyBiZWZvcmUgcmV0cnlpbmcsIGRlZmF1bHQgMzBcbiAgICovXG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdHMgSHR0cENsaWVudCBjbGFzcyBpbnN0YW5jZVxuICAgKiBAcGFyYW0ge051bWJlcn0gW3RpbWVvdXRdIHJlcXVlc3QgdGltZW91dCBpbiBzZWNvbmRzXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBbZXh0ZW5kZWRUaW1lb3V0XSByZXF1ZXN0IHRpbWVvdXQgaW4gc2Vjb25kc1xuICAgKiBAcGFyYW0ge1JldHJ5T3B0aW9uc30gW3JldHJ5T3B0c10gcmV0cnkgb3B0aW9uc1xuICAgKi9cbiAgY29uc3RydWN0b3IodGltZW91dCA9IDEwLCBleHRlbmRlZFRpbWVvdXQgPSA3MCwgcmV0cnlPcHRzID0ge30pIHtcbiAgICB0aGlzLl90aW1lb3V0ID0gdGltZW91dCAqIDEwMDA7XG4gICAgdGhpcy5fZXh0ZW5kZWRUaW1lb3V0ID0gZXh0ZW5kZWRUaW1lb3V0ICogMTAwMDtcbiAgICB0aGlzLl9yZXRyaWVzID0gcmV0cnlPcHRzLnJldHJpZXMgfHwgNTtcbiAgICB0aGlzLl9taW5SZXRyeURlbGF5ID0gKHJldHJ5T3B0cy5taW5EZWxheUluU2Vjb25kcyB8fCAxKSAqIDEwMDA7XG4gICAgdGhpcy5fbWF4UmV0cnlEZWxheSA9IChyZXRyeU9wdHMubWF4RGVsYXlJblNlY29uZHMgfHwgMzApICogMTAwMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtcyBhIHJlcXVlc3QuIFJlc3BvbnNlIGVycm9ycyBhcmUgcmV0dXJuZWQgYXMgQXBpRXJyb3Igb3Igc3ViY2xhc3Nlcy5cbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgcmVxdWVzdCBvcHRpb25zXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNFeHRlbmRlZFRpbWVvdXQgd2hldGhlciB0byBydW4gdGhlIHJlcXVlc3Qgd2l0aCBhbiBleHRlbmRlZCB0aW1lb3V0XG4gICAqIEByZXR1cm5zIHtPYmplY3R8U3RyaW5nfGFueX0gcmVxdWVzdCByZXN1bHRcbiAgICovXG4gIGFzeW5jIHJlcXVlc3Qob3B0aW9ucywgaXNFeHRlbmRlZFRpbWVvdXQpIHtcbiAgICBvcHRpb25zLnRpbWVvdXQgPSBpc0V4dGVuZGVkVGltZW91dCA/IHRoaXMuX2V4dGVuZGVkVGltZW91dCA6IHRoaXMuX3RpbWVvdXQ7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5fbWFrZVJlcXVlc3Qob3B0aW9ucyk7XG4gICAgICByZXR1cm4gKHJlc3BvbnNlICYmIHJlc3BvbnNlLmRhdGEpIHx8IHVuZGVmaW5lZDtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRocm93IHRoaXMuX2NvbnZlcnRFcnJvcihlcnIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtcyBhIHJlcXVlc3Qgd2l0aCBhIGZhaWxvdmVyLiBSZXNwb25zZSBlcnJvcnMgYXJlIHJldHVybmVkIGFzIEFwaUVycm9yIG9yIHN1YmNsYXNzZXMuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIHJlcXVlc3Qgb3B0aW9uc1xuICAgKiBAcmV0dXJucyB7T2JqZWN0fFN0cmluZ3xhbnl9IHJlcXVlc3QgcmVzdWx0XG4gICAqL1xuICBhc3luYyByZXF1ZXN0V2l0aEZhaWxvdmVyKG9wdGlvbnMsIHJldHJ5Q291bnRlciA9IDAsIGVuZFRpbWUgPSBEYXRlLm5vdygpICsgdGhpcy5fbWF4UmV0cnlEZWxheSAqIHRoaXMuX3JldHJpZXMpIHtcbiAgICBvcHRpb25zLnRpbWVvdXQgPSB0aGlzLl90aW1lb3V0O1xuICAgIGxldCByZXRyeUFmdGVyU2Vjb25kcyA9IDA7XG5cbiAgICBvcHRpb25zLmNhbGxiYWNrID0gKGUsIHJlcykgPT4ge1xuICAgICAgaWYgKHJlcyAmJiByZXMuc3RhdHVzID09PSAyMDIpIHtcbiAgICAgICAgcmV0cnlBZnRlclNlY29uZHMgPSByZXMuaGVhZGVyc1sncmV0cnktYWZ0ZXInXSA/PyByZXMuZGF0YT8ubWV0YWRhdGE/LnJlY29tbWVuZGVkUmV0cnlUaW1lO1xuICAgICAgICBpZiAoaXNOYU4ocmV0cnlBZnRlclNlY29uZHMpKSB7XG4gICAgICAgICAgcmV0cnlBZnRlclNlY29uZHMgPSBNYXRoLm1heCgobmV3IERhdGUocmV0cnlBZnRlclNlY29uZHMpLmdldFRpbWUoKSAtIERhdGUubm93KCkpIC8gMTAwMCwgMSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICAgIFxuICAgIGxldCBib2R5O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX21ha2VSZXF1ZXN0KG9wdGlvbnMpO1xuICAgICAgb3B0aW9ucy5jYWxsYmFjayhudWxsLCByZXNwb25zZSk7XG4gICAgICBib2R5ID0gKHJlc3BvbnNlICYmIHJlc3BvbnNlLmRhdGEpIHx8IHVuZGVmaW5lZDtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHJ5Q291bnRlciA9IGF3YWl0IHRoaXMuX2hhbmRsZUVycm9yKGVyciwgcmV0cnlDb3VudGVyLCBlbmRUaW1lKTtcbiAgICAgIHJldHVybiB0aGlzLnJlcXVlc3RXaXRoRmFpbG92ZXIob3B0aW9ucywgcmV0cnlDb3VudGVyLCBlbmRUaW1lKTtcbiAgICB9XG5cbiAgICBpZiAocmV0cnlBZnRlclNlY29uZHMpIHtcbiAgICAgIGF3YWl0IHRoaXMuX2hhbmRsZVJldHJ5KGVuZFRpbWUsIHJldHJ5QWZ0ZXJTZWNvbmRzICogMTAwMCk7XG4gICAgICBib2R5ID0gYXdhaXQgdGhpcy5yZXF1ZXN0V2l0aEZhaWxvdmVyKG9wdGlvbnMsIHJldHJ5Q291bnRlciwgZW5kVGltZSk7XG4gICAgfVxuICAgIHJldHVybiBib2R5O1xuICB9XG5cbiAgX21ha2VSZXF1ZXN0KG9wdGlvbnMpIHtcbiAgICByZXR1cm4gYXhpb3Moe1xuICAgICAgdHJhbnNpdGlvbmFsOiB7XG4gICAgICAgIGNsYXJpZnlUaW1lb3V0RXJyb3I6IHRydWVcbiAgICAgIH0sXG4gICAgICAuLi5vcHRpb25zXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBfd2FpdChwYXVzZSkge1xuICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlcyA9PiBzZXRUaW1lb3V0KHJlcywgcGF1c2UpKTtcbiAgfVxuXG4gIGFzeW5jIF9oYW5kbGVSZXRyeShlbmRUaW1lLCByZXRyeUFmdGVyKSB7XG4gICAgaWYgKGVuZFRpbWUgPiBEYXRlLm5vdygpICsgcmV0cnlBZnRlcikge1xuICAgICAgYXdhaXQgdGhpcy5fd2FpdChyZXRyeUFmdGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFRpbWVvdXRFcnJvcignVGltZWQgb3V0IHdhaXRpbmcgZm9yIHRoZSByZXNwb25zZScpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIF9oYW5kbGVFcnJvcihlcnIsIHJldHJ5Q291bnRlciwgZW5kVGltZSkge1xuICAgIGNvbnN0IGVycm9yID0gdGhpcy5fY29udmVydEVycm9yKGVycik7XG4gICAgaWYgKFsnQ29uZmxpY3RFcnJvcicsICdJbnRlcm5hbEVycm9yJywgJ0FwaUVycm9yJywgJ1RpbWVvdXRFcnJvciddLmluY2x1ZGVzKGVycm9yLm5hbWUpXG4gICAgICAmJiByZXRyeUNvdW50ZXIgPCB0aGlzLl9yZXRyaWVzKSB7XG4gICAgICBjb25zdCBwYXVzZSA9IE1hdGgubWluKE1hdGgucG93KDIsIHJldHJ5Q291bnRlcikgKiB0aGlzLl9taW5SZXRyeURlbGF5LCB0aGlzLl9tYXhSZXRyeURlbGF5KTtcbiAgICAgIGF3YWl0IHRoaXMuX3dhaXQocGF1c2UpO1xuICAgICAgcmV0dXJuIHJldHJ5Q291bnRlciArIDE7XG4gICAgfSBlbHNlIGlmIChlcnJvci5uYW1lID09PSAnVG9vTWFueVJlcXVlc3RzRXJyb3InKSB7XG4gICAgICBjb25zdCByZXRyeVRpbWUgPSBEYXRlLnBhcnNlKGVycm9yLm1ldGFkYXRhLnJlY29tbWVuZGVkUmV0cnlUaW1lKTtcbiAgICAgIGlmIChyZXRyeVRpbWUgPCBlbmRUaW1lKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuX3dhaXQocmV0cnlUaW1lIC0gRGF0ZS5ub3coKSk7XG4gICAgICAgIHJldHVybiByZXRyeUNvdW50ZXI7XG4gICAgICB9XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbXBsZXhpdHlcbiAgX2NvbnZlcnRFcnJvcihlcnIpIHtcbiAgICBjb25zdCBlcnJvclJlc3BvbnNlID0gZXJyLnJlc3BvbnNlIHx8IHt9O1xuICAgIGNvbnN0IGVycm9yRGF0YSA9IGVycm9yUmVzcG9uc2UuZGF0YSB8fCB7fTtcbiAgICBjb25zdCBzdGF0dXMgPSBlcnJvclJlc3BvbnNlLnN0YXR1cyB8fCBlcnIuc3RhdHVzO1xuICAgIGNvbnN0IHVybCA9IGVycj8uY29uZmlnPy51cmw7XG5cbiAgICBjb25zdCBlcnJNc2dEZWZhdWx0ID0gZXJyb3JEYXRhLm1lc3NhZ2UgfHwgZXJyLmNvZGUgfHwgZXJyLm1lc3NhZ2U7XG4gICAgY29uc3QgZXJyTXNnID0gZXJyb3JEYXRhLm1lc3NhZ2UgfHwgZXJyLm1lc3NhZ2U7XG5cbiAgICBzd2l0Y2ggKHN0YXR1cykge1xuICAgIGNhc2UgNDAwOlxuICAgICAgcmV0dXJuIG5ldyBWYWxpZGF0aW9uRXJyb3IoZXJyTXNnLCBlcnJvckRhdGEuZGV0YWlscyB8fCBlcnIuZGV0YWlscywgdXJsKTtcbiAgICBjYXNlIDQwMTpcbiAgICAgIHJldHVybiBuZXcgVW5hdXRob3JpemVkRXJyb3IoZXJyTXNnLCB1cmwpO1xuICAgIGNhc2UgNDAzOlxuICAgICAgcmV0dXJuIG5ldyBGb3JiaWRkZW5FcnJvcihlcnJNc2csIHVybCk7XG4gICAgY2FzZSA0MDQ6XG4gICAgICByZXR1cm4gbmV3IE5vdEZvdW5kRXJyb3IoZXJyTXNnLCB1cmwpO1xuICAgIGNhc2UgNDA5OlxuICAgICAgcmV0dXJuIG5ldyBDb25mbGljdEVycm9yKGVyck1zZywgdXJsKTtcbiAgICBjYXNlIDQyOTpcbiAgICAgIHJldHVybiBuZXcgVG9vTWFueVJlcXVlc3RzRXJyb3IoZXJyTXNnLCBlcnJvckRhdGEubWV0YWRhdGEgfHwgZXJyLm1ldGFkYXRhLCB1cmwpO1xuICAgIGNhc2UgNTAwOlxuICAgICAgcmV0dXJuIG5ldyBJbnRlcm5hbEVycm9yKGVyck1zZywgdXJsKTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIG5ldyBBcGlFcnJvcihBcGlFcnJvciwgZXJyTXNnRGVmYXVsdCwgc3RhdHVzLCB1cmwpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEhUVFAgY2xpZW50IHNlcnZpY2UgbW9jayBmb3IgdGVzdHNcbiAqL1xuZXhwb3J0IGNsYXNzIEh0dHBDbGllbnRNb2NrIGV4dGVuZHMgSHR0cENsaWVudCB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIEhUVFAgY2xpZW50IG1vY2tcbiAgICogQHBhcmFtIHtGdW5jdGlvbihvcHRpb25zOk9iamVjdCk6UHJvbWlzZX0gcmVxdWVzdEZuIG1vY2tlZCByZXF1ZXN0IGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7TnVtYmVyfSB0aW1lb3V0IHJlcXVlc3QgdGltZW91dCBpbiBzZWNvbmRzXG4gICAqIEBwYXJhbSB7UmV0cnlPcHRpb25zfSByZXRyeU9wdHMgcmV0cnkgb3B0aW9uc1xuICAgKi9cbiAgY29uc3RydWN0b3IocmVxdWVzdEZuLCB0aW1lb3V0LCBleHRlbmRlZFRpbWVvdXQsIHJldHJ5T3B0cykge1xuICAgIHN1cGVyKHRpbWVvdXQsIGV4dGVuZGVkVGltZW91dCwgcmV0cnlPcHRzKTtcbiAgICB0aGlzLl9yZXF1ZXN0Rm4gPSByZXF1ZXN0Rm47XG4gIH1cblxuICBfbWFrZVJlcXVlc3QoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlcXVlc3RGbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbn1cbiJdLCJuYW1lcyI6WyJIdHRwQ2xpZW50TW9jayIsIkh0dHBDbGllbnQiLCJyZXF1ZXN0Iiwib3B0aW9ucyIsImlzRXh0ZW5kZWRUaW1lb3V0IiwidGltZW91dCIsIl9leHRlbmRlZFRpbWVvdXQiLCJfdGltZW91dCIsInJlc3BvbnNlIiwiX21ha2VSZXF1ZXN0IiwiZGF0YSIsInVuZGVmaW5lZCIsImVyciIsIl9jb252ZXJ0RXJyb3IiLCJyZXF1ZXN0V2l0aEZhaWxvdmVyIiwicmV0cnlDb3VudGVyIiwiZW5kVGltZSIsIkRhdGUiLCJub3ciLCJfbWF4UmV0cnlEZWxheSIsIl9yZXRyaWVzIiwicmV0cnlBZnRlclNlY29uZHMiLCJjYWxsYmFjayIsImUiLCJyZXMiLCJzdGF0dXMiLCJoZWFkZXJzIiwibWV0YWRhdGEiLCJyZWNvbW1lbmRlZFJldHJ5VGltZSIsImlzTmFOIiwiTWF0aCIsIm1heCIsImdldFRpbWUiLCJib2R5IiwiX2hhbmRsZUVycm9yIiwiX2hhbmRsZVJldHJ5IiwiYXhpb3MiLCJ0cmFuc2l0aW9uYWwiLCJjbGFyaWZ5VGltZW91dEVycm9yIiwiX3dhaXQiLCJwYXVzZSIsIlByb21pc2UiLCJzZXRUaW1lb3V0IiwicmV0cnlBZnRlciIsIlRpbWVvdXRFcnJvciIsImVycm9yIiwiaW5jbHVkZXMiLCJuYW1lIiwibWluIiwicG93IiwiX21pblJldHJ5RGVsYXkiLCJyZXRyeVRpbWUiLCJwYXJzZSIsImVycm9yUmVzcG9uc2UiLCJlcnJvckRhdGEiLCJ1cmwiLCJjb25maWciLCJlcnJNc2dEZWZhdWx0IiwibWVzc2FnZSIsImNvZGUiLCJlcnJNc2ciLCJWYWxpZGF0aW9uRXJyb3IiLCJkZXRhaWxzIiwiVW5hdXRob3JpemVkRXJyb3IiLCJGb3JiaWRkZW5FcnJvciIsIk5vdEZvdW5kRXJyb3IiLCJDb25mbGljdEVycm9yIiwiVG9vTWFueVJlcXVlc3RzRXJyb3IiLCJJbnRlcm5hbEVycm9yIiwiQXBpRXJyb3IiLCJjb25zdHJ1Y3RvciIsImV4dGVuZGVkVGltZW91dCIsInJldHJ5T3B0cyIsInJldHJpZXMiLCJtaW5EZWxheUluU2Vjb25kcyIsIm1heERlbGF5SW5TZWNvbmRzIiwiX3JlcXVlc3RGbiIsImFwcGx5IiwiYXJndW1lbnRzIiwicmVxdWVzdEZuIl0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7SUE4SmFBLGNBQWM7ZUFBZEE7OztlQWxKUUM7Ozs4REFWSDs4QkFJWDtxRUFDa0I7Ozs7OztBQUtWLElBQUEsQUFBTUEsYUFBTixNQUFNQTtJQXVCbkI7Ozs7O0dBS0MsR0FDRCxNQUFNQyxRQUFRQyxPQUFPLEVBQUVDLGlCQUFp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