metaapi.cloud-copyfactory-sdk
Version:
Javascript SDK for SDK for CopyFactory trade copying API. Can copy trades both between MetaTrader 5 (MT5) and MetaTrader 4 (MT4). (https://metaapi.cloud)
200 lines (199 loc) • 21.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, /**
* Connection URL and request managing client
*/ "default", {
enumerable: true,
get: function() {
return DomainClient;
}
});
const _promiseany = /*#__PURE__*/ _interop_require_default(require("promise.any"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
let DomainClient = class DomainClient {
/**
* Constructs domain client instance
* @param {HttpClient} httpClient HTTP client
* @param {String} token authorization token
* @param {String} domain domain to connect to, default is agiliumtrade.agiliumtrade.ai
*/ constructor(httpClient, token, domain = "agiliumtrade.agiliumtrade.ai"){
this._httpClient = httpClient;
this._domain = domain;
this._token = token;
this._urlCache = null;
this._regionCache = [];
this._regionIndex = 0;
}
/**
* Returns domain client domain
* @returns {String} client domain
*/ get domain() {
return this._domain;
}
/**
* Returns domain client token
* @returns {String} client token
*/ get token() {
return this._token;
}
/**
* Sends a CopyFactory API request
* @param {Object} opts options request options
* @param {Boolean} isExtendedTimeout whether to run the request with an extended timeout
* @returns {Object|String|any} request result
*/ async requestCopyFactory(opts, isExtendedTimeout = false) {
await this._updateHost();
const regionIndex = this._regionIndex;
try {
return await this._httpClient.request(Object.assign({}, opts, {
url: this._urlCache.url + opts.url
}), isExtendedTimeout);
} catch (err) {
if (![
"ConflictError",
"InternalError",
"ApiError",
"TimeoutError"
].includes(err.name)) {
throw err;
} else {
if (this._regionCache.length === this._regionIndex + 1) {
this._regionIndex = 0;
throw err;
} else {
if (this._regionIndex === regionIndex) {
this._regionIndex++;
}
return await this.requestCopyFactory(opts, isExtendedTimeout);
}
}
}
}
/**
* Sends an http request
* @param {Object} opts options request options
* @returns {Object|String|any} request result
*/ request(opts) {
return this._httpClient.request(opts);
}
/**
* Sends a signal client request
* @param {Object} opts options request options
* @param {Object} host signal client host data
* @param {String} accountId account id
* @returns {Object|String|any} request result
*/ async requestSignal(opts, host, accountId) {
this._updateAccountRegions(host, accountId);
try {
return await (0, _promiseany.default)(host.regions.map((region)=>{
return this._httpClient.requestWithFailover(Object.assign({}, opts, {
url: `${host.host}.${region}.${host.domain}` + opts.url,
headers: {
"auth-token": this._token
}
}));
}));
} catch (error) {
throw error.errors[0];
}
}
/**
* Returns CopyFactory host for signal client requests
* @param {String[]} regions subscriber regions
* @returns {String} signal client CopyFactory host
*/ async getSignalClientHost(regions) {
await this._updateHost();
return {
host: "https://copyfactory-api-v1",
regions,
lastUpdated: Date.now(),
domain: this._urlCache.domain
};
}
/**
* Account request info
* @typedef {Object} AccountInfo
* @property {String} id primary account id
* @property {String[]} regions account available regions
*/ /**
* Returns account data by id
* @param {String} accountId account id
* @returns {AccountInfo} account data
*/ async getAccountInfo(accountId) {
const getAccount = async (id)=>{
const accountOpts = {
url: `https://mt-provisioning-api-v1.${this.domain}/users/current/accounts/${id}`,
method: "GET",
headers: {
"auth-token": this.token
},
json: true
};
return await this._httpClient.requestWithFailover(accountOpts);
};
let accountData = await getAccount(accountId);
let primaryAccountId = "";
if (accountData.primaryAccountId) {
primaryAccountId = accountData.primaryAccountId;
accountData = await getAccount(primaryAccountId);
} else {
primaryAccountId = accountData._id;
}
let regions = [
accountData.region
].concat(accountData.accountReplicas && accountData.accountReplicas.map((replica)=>replica.region) || []);
return {
id: primaryAccountId,
regions
};
}
async _updateHost() {
if (!this._urlCache || this._urlCache.lastUpdated < Date.now() - 1000 * 60 * 10) {
await this._updateRegions();
const urlSettings = await this._httpClient.request({
url: `https://mt-provisioning-api-v1.${this._domain}/users/current/servers/mt-client-api`,
method: "GET",
headers: {
"auth-token": this._token
},
json: true
});
this._urlCache = {
url: `https://copyfactory-api-v1.${this._regionCache[this._regionIndex]}.${urlSettings.domain}`,
domain: urlSettings.domain,
lastUpdated: Date.now()
};
} else {
this._urlCache = {
url: `https://copyfactory-api-v1.${this._regionCache[this._regionIndex]}.${this._urlCache.domain}`,
domain: this._urlCache.domain,
lastUpdated: Date.now()
};
}
}
async _updateRegions() {
this._regionCache = await this._httpClient.request({
url: `https://mt-provisioning-api-v1.${this._domain}/users/current/regions`,
method: "GET",
headers: {
"auth-token": this._token
},
json: true
});
this._regionIndex = 0;
}
async _updateAccountRegions(host, accountId) {
if (host.lastUpdated < Date.now() - 1000 * 60 * 10) {
const accountData = await this.getAccountInfo(accountId);
host.lastUpdated = Date.now();
host.regions = accountData.regions;
}
}
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjxhbm9uPiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBhbnkgZnJvbSAncHJvbWlzZS5hbnknO1xuXG4vKipcbiAqIENvbm5lY3Rpb24gVVJMIGFuZCByZXF1ZXN0IG1hbmFnaW5nIGNsaWVudFxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEb21haW5DbGllbnQge1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGRvbWFpbiBjbGllbnQgaW5zdGFuY2VcbiAgICogQHBhcmFtIHtIdHRwQ2xpZW50fSBodHRwQ2xpZW50IEhUVFAgY2xpZW50XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0b2tlbiBhdXRob3JpemF0aW9uIHRva2VuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkb21haW4gZG9tYWluIHRvIGNvbm5lY3QgdG8sIGRlZmF1bHQgaXMgYWdpbGl1bXRyYWRlLmFnaWxpdW10cmFkZS5haVxuICAgKi9cbiAgY29uc3RydWN0b3IoaHR0cENsaWVudCwgdG9rZW4sIGRvbWFpbiA9ICdhZ2lsaXVtdHJhZGUuYWdpbGl1bXRyYWRlLmFpJykge1xuICAgIHRoaXMuX2h0dHBDbGllbnQgPSBodHRwQ2xpZW50O1xuICAgIHRoaXMuX2RvbWFpbiA9IGRvbWFpbjtcbiAgICB0aGlzLl90b2tlbiA9IHRva2VuO1xuICAgIHRoaXMuX3VybENhY2hlID0gbnVsbDtcbiAgICB0aGlzLl9yZWdpb25DYWNoZSA9IFtdO1xuICAgIHRoaXMuX3JlZ2lvbkluZGV4ID0gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGRvbWFpbiBjbGllbnQgZG9tYWluXG4gICAqIEByZXR1cm5zIHtTdHJpbmd9IGNsaWVudCBkb21haW5cbiAgICovXG4gIGdldCBkb21haW4oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RvbWFpbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGRvbWFpbiBjbGllbnQgdG9rZW5cbiAgICogQHJldHVybnMge1N0cmluZ30gY2xpZW50IHRva2VuXG4gICAqL1xuICBnZXQgdG9rZW4oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Rva2VuO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbmRzIGEgQ29weUZhY3RvcnkgQVBJIHJlcXVlc3RcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdHMgb3B0aW9ucyByZXF1ZXN0IG9wdGlvbnNcbiAgICogQHBhcmFtIHtCb29sZWFufSBpc0V4dGVuZGVkVGltZW91dCB3aGV0aGVyIHRvIHJ1biB0aGUgcmVxdWVzdCB3aXRoIGFuIGV4dGVuZGVkIHRpbWVvdXRcbiAgICogQHJldHVybnMge09iamVjdHxTdHJpbmd8YW55fSByZXF1ZXN0IHJlc3VsdFxuICAgKi9cbiAgYXN5bmMgcmVxdWVzdENvcHlGYWN0b3J5KG9wdHMsIGlzRXh0ZW5kZWRUaW1lb3V0ID0gZmFsc2UpIHtcbiAgICBhd2FpdCB0aGlzLl91cGRhdGVIb3N0KCk7XG4gICAgY29uc3QgcmVnaW9uSW5kZXggPSB0aGlzLl9yZWdpb25JbmRleDtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX2h0dHBDbGllbnQucmVxdWVzdChPYmplY3QuYXNzaWduKHt9LCBvcHRzLCB7XG4gICAgICAgIHVybDogdGhpcy5fdXJsQ2FjaGUudXJsICsgb3B0cy51cmxcbiAgICAgIH0pLCBpc0V4dGVuZGVkVGltZW91dCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZighWydDb25mbGljdEVycm9yJywgJ0ludGVybmFsRXJyb3InLCAnQXBpRXJyb3InLCAnVGltZW91dEVycm9yJ10uaW5jbHVkZXMoZXJyLm5hbWUpKSB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmKHRoaXMuX3JlZ2lvbkNhY2hlLmxlbmd0aCA9PT0gdGhpcy5fcmVnaW9uSW5kZXggKyAxKSB7XG4gICAgICAgICAgdGhpcy5fcmVnaW9uSW5kZXggPSAwO1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZih0aGlzLl9yZWdpb25JbmRleCA9PT0gcmVnaW9uSW5kZXgpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlZ2lvbkluZGV4Kys7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlcXVlc3RDb3B5RmFjdG9yeShvcHRzLCBpc0V4dGVuZGVkVGltZW91dCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kcyBhbiBodHRwIHJlcXVlc3RcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdHMgb3B0aW9ucyByZXF1ZXN0IG9wdGlvbnNcbiAgICogQHJldHVybnMge09iamVjdHxTdHJpbmd8YW55fSByZXF1ZXN0IHJlc3VsdFxuICAgKi9cbiAgcmVxdWVzdChvcHRzKSB7XG4gICAgcmV0dXJuIHRoaXMuX2h0dHBDbGllbnQucmVxdWVzdChvcHRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kcyBhIHNpZ25hbCBjbGllbnQgcmVxdWVzdFxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyBvcHRpb25zIHJlcXVlc3Qgb3B0aW9ucyBcbiAgICogQHBhcmFtIHtPYmplY3R9IGhvc3Qgc2lnbmFsIGNsaWVudCBob3N0IGRhdGFcbiAgICogQHBhcmFtIHtTdHJpbmd9IGFjY291bnRJZCBhY2NvdW50IGlkXG4gICAqIEByZXR1cm5zIHtPYmplY3R8U3RyaW5nfGFueX0gcmVxdWVzdCByZXN1bHRcbiAgICovXG4gIGFzeW5jIHJlcXVlc3RTaWduYWwob3B0cywgaG9zdCwgYWNjb3VudElkKSB7XG4gICAgdGhpcy5fdXBkYXRlQWNjb3VudFJlZ2lvbnMoaG9zdCwgYWNjb3VudElkKTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGFueShob3N0LnJlZ2lvbnMubWFwKHJlZ2lvbiA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9odHRwQ2xpZW50LnJlcXVlc3RXaXRoRmFpbG92ZXIoT2JqZWN0LmFzc2lnbih7fSwgb3B0cywge1xuICAgICAgICAgIHVybDogYCR7aG9zdC5ob3N0fS4ke3JlZ2lvbn0uJHtob3N0LmRvbWFpbn1gICsgb3B0cy51cmwsXG4gICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgJ2F1dGgtdG9rZW4nOiB0aGlzLl90b2tlblxuICAgICAgICAgIH0sXG4gICAgICAgIH0pKTtcbiAgICAgIH0pKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgZXJyb3IuZXJyb3JzWzBdOyBcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBDb3B5RmFjdG9yeSBob3N0IGZvciBzaWduYWwgY2xpZW50IHJlcXVlc3RzXG4gICAqIEBwYXJhbSB7U3RyaW5nW119IHJlZ2lvbnMgc3Vic2NyaWJlciByZWdpb25zXG4gICAqIEByZXR1cm5zIHtTdHJpbmd9IHNpZ25hbCBjbGllbnQgQ29weUZhY3RvcnkgaG9zdFxuICAgKi9cbiAgYXN5bmMgZ2V0U2lnbmFsQ2xpZW50SG9zdChyZWdpb25zKSB7XG4gICAgYXdhaXQgdGhpcy5fdXBkYXRlSG9zdCgpO1xuICAgIHJldHVybiB7XG4gICAgICBob3N0OiAnaHR0cHM6Ly9jb3B5ZmFjdG9yeS1hcGktdjEnLFxuICAgICAgcmVnaW9ucyxcbiAgICAgIGxhc3RVcGRhdGVkOiBEYXRlLm5vdygpLFxuICAgICAgZG9tYWluOiB0aGlzLl91cmxDYWNoZS5kb21haW5cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFjY291bnQgcmVxdWVzdCBpbmZvXG4gICAqIEB0eXBlZGVmIHtPYmplY3R9IEFjY291bnRJbmZvXG4gICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpZCBwcmltYXJ5IGFjY291bnQgaWRcbiAgICogQHByb3BlcnR5IHtTdHJpbmdbXX0gcmVnaW9ucyBhY2NvdW50IGF2YWlsYWJsZSByZWdpb25zXG4gICAqL1xuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFjY291bnQgZGF0YSBieSBpZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gYWNjb3VudElkIGFjY291bnQgaWRcbiAgICogQHJldHVybnMge0FjY291bnRJbmZvfSBhY2NvdW50IGRhdGFcbiAgICovXG4gIGFzeW5jIGdldEFjY291bnRJbmZvKGFjY291bnRJZCkge1xuICAgIGNvbnN0IGdldEFjY291bnQgPSBhc3luYyAoaWQpID0+IHtcbiAgICAgIGNvbnN0IGFjY291bnRPcHRzID0ge1xuICAgICAgICB1cmw6IGBodHRwczovL210LXByb3Zpc2lvbmluZy1hcGktdjEuJHt0aGlzLmRvbWFpbn0vdXNlcnMvY3VycmVudC9hY2NvdW50cy8ke2lkfWAsXG4gICAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAnYXV0aC10b2tlbic6IHRoaXMudG9rZW5cbiAgICAgICAgfSxcbiAgICAgICAganNvbjogdHJ1ZVxuICAgICAgfTtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9odHRwQ2xpZW50LnJlcXVlc3RXaXRoRmFpbG92ZXIoYWNjb3VudE9wdHMpO1xuICAgIH07XG5cbiAgICBsZXQgYWNjb3VudERhdGEgPSBhd2FpdCBnZXRBY2NvdW50KGFjY291bnRJZCk7XG4gICAgbGV0IHByaW1hcnlBY2NvdW50SWQgPSAnJztcbiAgICBpZihhY2NvdW50RGF0YS5wcmltYXJ5QWNjb3VudElkKSB7XG4gICAgICBwcmltYXJ5QWNjb3VudElkID0gYWNjb3VudERhdGEucHJpbWFyeUFjY291bnRJZDtcbiAgICAgIGFjY291bnREYXRhID0gYXdhaXQgZ2V0QWNjb3VudChwcmltYXJ5QWNjb3VudElkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJpbWFyeUFjY291bnRJZCA9IGFjY291bnREYXRhLl9pZDtcbiAgICB9XG5cbiAgICBsZXQgcmVnaW9ucyA9IFthY2NvdW50RGF0YS5yZWdpb25dLmNvbmNhdChhY2NvdW50RGF0YS5hY2NvdW50UmVwbGljYXMgJiYgXG4gICAgICBhY2NvdW50RGF0YS5hY2NvdW50UmVwbGljYXMubWFwKHJlcGxpY2EgPT4gcmVwbGljYS5yZWdpb24pIHx8IFtdKTtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHByaW1hcnlBY2NvdW50SWQsXG4gICAgICByZWdpb25zXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIF91cGRhdGVIb3N0KCkge1xuICAgIGlmKCF0aGlzLl91cmxDYWNoZSB8fCB0aGlzLl91cmxDYWNoZS5sYXN0VXBkYXRlZCA8IERhdGUubm93KCkgLSAxMDAwICogNjAgKiAxMCkge1xuICAgICAgYXdhaXQgdGhpcy5fdXBkYXRlUmVnaW9ucygpO1xuICAgICAgY29uc3QgdXJsU2V0dGluZ3MgPSBhd2FpdCB0aGlzLl9odHRwQ2xpZW50LnJlcXVlc3Qoe1xuICAgICAgICB1cmw6IGBodHRwczovL210LXByb3Zpc2lvbmluZy1hcGktdjEuJHt0aGlzLl9kb21haW59L3VzZXJzL2N1cnJlbnQvc2VydmVycy9tdC1jbGllbnQtYXBpYCxcbiAgICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICdhdXRoLXRva2VuJzogdGhpcy5fdG9rZW5cbiAgICAgICAgfSxcbiAgICAgICAganNvbjogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5fdXJsQ2FjaGUgPSB7XG4gICAgICAgIHVybDogYGh0dHBzOi8vY29weWZhY3RvcnktYXBpLXYxLiR7dGhpcy5fcmVnaW9uQ2FjaGVbdGhpcy5fcmVnaW9uSW5kZXhdfS4ke3VybFNldHRpbmdzLmRvbWFpbn1gLFxuICAgICAgICBkb21haW46IHVybFNldHRpbmdzLmRvbWFpbixcbiAgICAgICAgbGFzdFVwZGF0ZWQ6IERhdGUubm93KClcbiAgICAgIH07IFxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl91cmxDYWNoZSA9IHtcbiAgICAgICAgdXJsOiBgaHR0cHM6Ly9jb3B5ZmFjdG9yeS1hcGktdjEuJHt0aGlzLl9yZWdpb25DYWNoZVt0aGlzLl9yZWdpb25JbmRleF19LiR7dGhpcy5fdXJsQ2FjaGUuZG9tYWlufWAsXG4gICAgICAgIGRvbWFpbjogdGhpcy5fdXJsQ2FjaGUuZG9tYWluLFxuICAgICAgICBsYXN0VXBkYXRlZDogRGF0ZS5ub3coKVxuICAgICAgfTsgXG4gICAgfVxuICB9XG5cbiAgYXN5bmMgX3VwZGF0ZVJlZ2lvbnMoKSB7XG4gICAgdGhpcy5fcmVnaW9uQ2FjaGUgPSBhd2FpdCB0aGlzLl9odHRwQ2xpZW50LnJlcXVlc3Qoe1xuICAgICAgdXJsOiBgaHR0cHM6Ly9tdC1wcm92aXNpb25pbmctYXBpLXYxLiR7dGhpcy5fZG9tYWlufS91c2Vycy9jdXJyZW50L3JlZ2lvbnNgLFxuICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ2F1dGgtdG9rZW4nOiB0aGlzLl90b2tlblxuICAgICAgfSxcbiAgICAgIGpzb246IHRydWUsXG4gICAgfSk7XG4gICAgdGhpcy5fcmVnaW9uSW5kZXggPSAwO1xuICB9XG5cbiAgYXN5bmMgX3VwZGF0ZUFjY291bnRSZWdpb25zKGhvc3QsIGFjY291bnRJZCkge1xuICAgIGlmKGhvc3QubGFzdFVwZGF0ZWQgPCBEYXRlLm5vdygpIC0gMTAwMCAqIDYwICogMTApIHtcbiAgICAgIGNvbnN0IGFjY291bnREYXRhID0gYXdhaXQgdGhpcy5nZXRBY2NvdW50SW5mbyhhY2NvdW50SWQpO1xuICAgICAgaG9zdC5sYXN0VXBkYXRlZCA9IERhdGUubm93KCk7XG4gICAgICBob3N0LnJlZ2lvbnMgPSBhY2NvdW50RGF0YS5yZWdpb25zO1xuICAgIH1cbiAgfVxuXG59Il0sIm5hbWVzIjpbIkRvbWFpbkNsaWVudCIsImNvbnN0cnVjdG9yIiwiaHR0cENsaWVudCIsInRva2VuIiwiZG9tYWluIiwiX2h0dHBDbGllbnQiLCJfZG9tYWluIiwiX3Rva2VuIiwiX3VybENhY2hlIiwiX3JlZ2lvbkNhY2hlIiwiX3JlZ2lvbkluZGV4IiwicmVxdWVzdENvcHlGYWN0b3J5Iiwib3B0cyIsImlzRXh0ZW5kZWRUaW1lb3V0IiwiX3VwZGF0ZUhvc3QiLCJyZWdpb25JbmRleCIsInJlcXVlc3QiLCJPYmplY3QiLCJhc3NpZ24iLCJ1cmwiLCJlcnIiLCJpbmNsdWRlcyIsIm5hbWUiLCJsZW5ndGgiLCJyZXF1ZXN0U2lnbmFsIiwiaG9zdCIsImFjY291bnRJZCIsIl91cGRhdGVBY2NvdW50UmVnaW9ucyIsImFueSIsInJlZ2lvbnMiLCJtYXAiLCJyZWdpb24iLCJyZXF1ZXN0V2l0aEZhaWxvdmVyIiwiaGVhZGVycyIsImVycm9yIiwiZXJyb3JzIiwiZ2V0U2lnbmFsQ2xpZW50SG9zdCIsImxhc3RVcGRhdGVkIiwiRGF0ZSIsIm5vdyIsImdldEFjY291bnRJbmZvIiwiZ2V0QWNjb3VudCIsImlkIiwiYWNjb3VudE9wdHMiLCJtZXRob2QiLCJqc29uIiwiYWNjb3VudERhdGEiLCJwcmltYXJ5QWNjb3VudElkIiwiX2lkIiwiY29uY2F0IiwiYWNjb3VudFJlcGxpY2FzIiwicmVwbGljYSIsIl91cGRhdGVSZWdpb25zIiwidXJsU2V0dGluZ3MiXSwibWFwcGluZ3MiOiJBQUFBOzs7OytCQUlBOztDQUVDLEdBQ0Q7OztlQUFxQkE7OzttRUFMTDs7Ozs7O0FBS0QsSUFBQSxBQUFNQSxlQUFOLE1BQU1BO0lBRW5COzs7OztHQUtDLEdBQ0RDLFlBQVlDLFVBQVUsRUFBRUMsS0FBSyxFQUFFQyxTQUFTLDhCQUE4QixDQUFFO1FBQ3RFLElBQUksQ0FBQ0MsV0FBVyxHQUFHSDtRQUNuQixJQUFJLENBQUNJLE9BQU8sR0FBR0Y7UUFDZixJQUFJLENBQUNHLE1BQU0sR0FBR0o7UUFDZCxJQUFJLENBQUNLLFNBQVMsR0FBRyxJQUFJO1FBQ3JCLElBQUksQ0FBQ0MsWUFBWSxHQUFHLEVBQUU7UUFDdEIsSUFBSSxDQUFDQyxZQUFZLEdBQUc7SUFDdEI7SUFFQTs7O0dBR0MsR0FDRCxJQUFJTixTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUNFLE9BQU87SUFDckI7SUFFQTs7O0dBR0MsR0FDRCxJQUFJSCxRQUFRO1FBQ1YsT0FBTyxJQUFJLENBQUNJLE1BQU07SUFDcEI7SUFFQTs7Ozs7R0FL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