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)

149 lines (148 loc) 17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function() { return ExpertAdvisorClient; } }); const _metaApiclient = /*#__PURE__*/ _interop_require_default(require("../metaApi.client")); const _formdata = /*#__PURE__*/ _interop_require_default(require("form-data")); const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } let ExpertAdvisorClient = class ExpertAdvisorClient extends _metaApiclient.default { /** * Expert advisor model * @typedef {Object} ExpertAdvisorDto * @property {String} expertId expert advisor id * @property {String} period expert advisor period * @property {String} symbol expert advisor symbol * @property {Boolean} fileUploaded true if expert file was uploaded */ /** * Retrieves expert advisors by account id (see * https://metaapi.cloud/docs/provisioning/api/expertAdvisor/readExpertAdvisors/) * Method is accessible only with API access token * @param {String} accountId Metatrader account id * @returns {Promise<ExpertAdvisorDto[]>} promise resolving with expert advisors found */ getExpertAdvisors(accountId) { if (this._isNotJwtToken()) { return this._handleNoAccessError("getExpertAdvisors"); } const opts = { url: `${this._host}/users/current/accounts/${accountId}/expert-advisors`, method: "GET", headers: { "auth-token": this._token }, json: true }; return this._httpClient.request(opts, "getExpertAdvisors"); } /** * Retrieves an expert advisor by id (see * https://metaapi.cloud/docs/provisioning/api/expertAdvisor/readExpertAdvisor/). * Thrown an error if expert is not found. Method is accessible only with API access token * @param {String} accountId Metatrader account id * @param {String} expertId expert advisor id * @returns {Promise<ExpertAdvisorDto>} promise resolving with expert advisor found */ getExpertAdvisor(accountId, expertId) { if (this._isNotJwtToken()) { return this._handleNoAccessError("getExpertAdvisor"); } const opts = { url: `${this._host}/users/current/accounts/${accountId}/expert-advisors/${expertId}`, method: "GET", headers: { "auth-token": this._token }, json: true }; return this._httpClient.request(opts, "getExpertAdvisor"); } /** * Updated expert advisor data * @typedef {Object} NewExpertAdvisorDto * @property {String} period expert advisor symbol. * For MetaTrader 4 allowed periods are 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w, 1mn * For MetaTrader 5 allowed periods are 1m, 2m, 3m, 4m, 5m, 6m, 10m, 12m, 15m, 20m, 30m, 1h, 2h, 3h, 4h, 6h, 8h, 12h, * 1d, 1w, 1mn * @property {String} symbol expert advisor period * @property {String} preset base64-encoded preset file */ /** * Updates or creates expert advisor data (see * https://metaapi.cloud/docs/provisioning/api/expertAdvisor/updateExpertAdvisor/). * Method is accessible only with API access token * @param {String} accountId Metatrader account id * @param {String} expertId expert id * @param {NewExpertAdvisorDto} expert new expert advisor data * @returns {Promise} promise resolving when expert advisor is updated */ updateExpertAdvisor(accountId, expertId, expert) { if (this._isNotJwtToken()) { return this._handleNoAccessError("updateExpertAdvisor"); } const opts = { url: `${this._host}/users/current/accounts/${accountId}/expert-advisors/${expertId}`, method: "PUT", headers: { "auth-token": this._token }, json: true, data: expert }; return this._httpClient.request(opts, "updateExpertAdvisor"); } /** * Uploads an expert advisor file (see https://metaapi.cloud/docs/provisioning/api/expertAdvisor/uploadEAFile/) * Method is accessible only with API access token * @param {String} accountId Metatrader account id * @param {String} expertId expert id * @param {String|Buffer} file path to a file to upload or buffer containing file contents * @returns {Promise} promise resolving when file upload is completed */ uploadExpertAdvisorFile(accountId, expertId, file) { if (this._isNotJwtToken()) { return this._handleNoAccessError("uploadExpertAdvisorFile"); } if (typeof file === "string") { file = _fs.default.createReadStream(file); } const formData = new _formdata.default(); formData.append("file", file); const opts = { method: "PUT", url: `${this._host}/users/current/accounts/${accountId}/expert-advisors/${expertId}/file`, data: formData, headers: { ...formData.getHeaders(), "auth-token": this._token } }; return this._httpClient.request(opts, "uploadExpertAdvisorFile"); } /** * Deletes an expert advisor (see https://metaapi.cloud/docs/provisioning/api/expertAdvisor/deleteExpertAdvisor/) * Method is accessible only with API access token * @param {String} accountId Metatrader account id * @param {String} expertId expert id * @returns {Promise} promise resolving when expert advisor is deleted */ deleteExpertAdvisor(accountId, expertId) { if (this._isNotJwtToken()) { return this._handleNoAccessError("deleteExpertAdvisor"); } const opts = { url: `${this._host}/users/current/accounts/${accountId}/expert-advisors/${expertId}`, method: "DELETE", headers: { "auth-token": this._token }, json: true }; return this._httpClient.request(opts, "deleteExpertAdvisor"); } }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjxhbm9uPiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBNZXRhQXBpQ2xpZW50IGZyb20gJy4uL21ldGFBcGkuY2xpZW50JztcbmltcG9ydCBGb3JtRGF0YSBmcm9tICdmb3JtLWRhdGEnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzJztcblxuLyoqXG4gKiBtZXRhYXBpLmNsb3VkIGV4cGVydCBhZHZpc29yIEFQSSBjbGllbnQgKHNlZSBodHRwczovL21ldGFhcGkuY2xvdWQvZG9jcy9wcm92aXNpb25pbmcvKVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFeHBlcnRBZHZpc29yQ2xpZW50IGV4dGVuZHMgTWV0YUFwaUNsaWVudCB7XG5cbiAgLyoqXG4gICAqIEV4cGVydCBhZHZpc29yIG1vZGVsXG4gICAqIEB0eXBlZGVmIHtPYmplY3R9IEV4cGVydEFkdmlzb3JEdG9cbiAgICogQHByb3BlcnR5IHtTdHJpbmd9IGV4cGVydElkIGV4cGVydCBhZHZpc29yIGlkXG4gICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBwZXJpb2QgZXhwZXJ0IGFkdmlzb3IgcGVyaW9kXG4gICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBzeW1ib2wgZXhwZXJ0IGFkdmlzb3Igc3ltYm9sXG4gICAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZmlsZVVwbG9hZGVkIHRydWUgaWYgZXhwZXJ0IGZpbGUgd2FzIHVwbG9hZGVkXG4gICAqL1xuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgZXhwZXJ0IGFkdmlzb3JzIGJ5IGFjY291bnQgaWQgKHNlZVxuICAgKiBodHRwczovL21ldGFhcGkuY2xvdWQvZG9jcy9wcm92aXNpb25pbmcvYXBpL2V4cGVydEFkdmlzb3IvcmVhZEV4cGVydEFkdmlzb3JzLylcbiAgICogTWV0aG9kIGlzIGFjY2Vzc2libGUgb25seSB3aXRoIEFQSSBhY2Nlc3MgdG9rZW5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGFjY291bnRJZCBNZXRhdHJhZGVyIGFjY291bnQgaWRcbiAgICogQHJldHVybnMge1Byb21pc2U8RXhwZXJ0QWR2aXNvckR0b1tdPn0gcHJvbWlzZSByZXNvbHZpbmcgd2l0aCBleHBlcnQgYWR2aXNvcnMgZm91bmRcbiAgICovXG4gIGdldEV4cGVydEFkdmlzb3JzKGFjY291bnRJZCkge1xuICAgIGlmICh0aGlzLl9pc05vdEp3dFRva2VuKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVOb0FjY2Vzc0Vycm9yKCdnZXRFeHBlcnRBZHZpc29ycycpO1xuICAgIH1cbiAgICBjb25zdCBvcHRzID0ge1xuICAgICAgdXJsOiBgJHt0aGlzLl9ob3N0fS91c2Vycy9jdXJyZW50L2FjY291bnRzLyR7YWNjb3VudElkfS9leHBlcnQtYWR2aXNvcnNgLFxuICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ2F1dGgtdG9rZW4nOiB0aGlzLl90b2tlblxuICAgICAgfSxcbiAgICAgIGpzb246IHRydWVcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLl9odHRwQ2xpZW50LnJlcXVlc3Qob3B0cywgJ2dldEV4cGVydEFkdmlzb3JzJyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIGFuIGV4cGVydCBhZHZpc29yIGJ5IGlkIChzZWVcbiAgICogaHR0cHM6Ly9tZXRhYXBpLmNsb3VkL2RvY3MvcHJvdmlzaW9uaW5nL2FwaS9leHBlcnRBZHZpc29yL3JlYWRFeHBlcnRBZHZpc29yLykuXG4gICAqIFRocm93biBhbiBlcnJvciBpZiBleHBlcnQgaXMgbm90IGZvdW5kLiBNZXRob2QgaXMgYWNjZXNzaWJsZSBvbmx5IHdpdGggQVBJIGFjY2VzcyB0b2tlblxuICAgKiBAcGFyYW0ge1N0cmluZ30gYWNjb3VudElkIE1ldGF0cmFkZXIgYWNjb3VudCBpZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXhwZXJ0SWQgZXhwZXJ0IGFkdmlzb3IgaWRcbiAgICogQHJldHVybnMge1Byb21pc2U8RXhwZXJ0QWR2aXNvckR0bz59IHByb21pc2UgcmVzb2x2aW5nIHdpdGggZXhwZXJ0IGFkdmlzb3IgZm91bmRcbiAgICovXG4gIGdldEV4cGVydEFkdmlzb3IoYWNjb3VudElkLCBleHBlcnRJZCkge1xuICAgIGlmICh0aGlzLl9pc05vdEp3dFRva2VuKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVOb0FjY2Vzc0Vycm9yKCdnZXRFeHBlcnRBZHZpc29yJyk7XG4gICAgfVxuICAgIGNvbnN0IG9wdHMgPSB7XG4gICAgICB1cmw6IGAke3RoaXMuX2hvc3R9L3VzZXJzL2N1cnJlbnQvYWNjb3VudHMvJHthY2NvdW50SWR9L2V4cGVydC1hZHZpc29ycy8ke2V4cGVydElkfWAsXG4gICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnYXV0aC10b2tlbic6IHRoaXMuX3Rva2VuXG4gICAgICB9LFxuICAgICAganNvbjogdHJ1ZVxuICAgIH07XG4gICAgcmV0dXJuIHRoaXMuX2h0dHBDbGllbnQucmVxdWVzdChvcHRzLCAnZ2V0RXhwZXJ0QWR2aXNvcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZWQgZXhwZXJ0IGFkdmlzb3IgZGF0YVxuICAgKiBAdHlwZWRlZiB7T2JqZWN0fSBOZXdFeHBlcnRBZHZpc29yRHRvXG4gICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBwZXJpb2QgZXhwZXJ0IGFkdmlzb3Igc3ltYm9sLlxuICAgKiBGb3IgTWV0YVRyYWRlciA0IGFsbG93ZWQgcGVyaW9kcyBhcmUgMW0sIDVtLCAxNW0sIDMwbSwgMWgsIDRoLCAxZCwgMXcsIDFtblxuICAgKiBGb3IgTWV0YVRyYWRlciA1IGFsbG93ZWQgcGVyaW9kcyBhcmUgMW0sIDJtLCAzbSwgNG0sIDVtLCA2bSwgMTBtLCAxMm0sIDE1bSwgMjBtLCAzMG0sIDFoLCAyaCwgM2gsIDRoLCA2aCwgOGgsIDEyaCxcbiAgICogMWQsIDF3LCAxbW5cbiAgICogQHByb3BlcnR5IHtTdHJpbmd9IHN5bWJvbCBleHBlcnQgYWR2aXNvciBwZXJpb2RcbiAgICogQHByb3BlcnR5IHtTdHJpbmd9IHByZXNldCBiYXNlNjQtZW5jb2RlZCBwcmVzZXQgZmlsZVxuICAgKi9cblxuICAvKipcbiAgICogVXBkYXRlcyBvciBjcmVhdGVzIGV4cGVydCBhZHZpc29yIGRhdGEgKHNlZVxuICAgKiBodHRwczovL21ldGFhcGkuY2xvdWQvZG9jcy9wcm92aXNpb25pbmcvYXBpL2V4cGVydEFkdmlzb3IvdXBkYXRlRXhwZXJ0QWR2aXNvci8pLlxuICAgKiBNZXRob2QgaXMgYWNjZXNzaWJsZSBvbmx5IHdpdGggQVBJIGFjY2VzcyB0b2tlblxuICAgKiBAcGFyYW0ge1N0cmluZ30gYWNjb3VudElkIE1ldGF0cmFkZXIgYWNjb3VudCBpZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXhwZXJ0SWQgZXhwZXJ0IGlkXG4gICAqIEBwYXJhbSB7TmV3RXhwZXJ0QWR2aXNvckR0b30gZXhwZXJ0IG5ldyBleHBlcnQgYWR2aXNvciBkYXRhXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBwcm9taXNlIHJlc29sdmluZyB3aGVuIGV4cGVydCBhZHZpc29yIGlzIHVwZGF0ZWRcbiAgICovXG4gIHVwZGF0ZUV4cGVydEFkdmlzb3IoYWNjb3VudElkLCBleHBlcnRJZCwgZXhwZXJ0KSB7XG4gICAgaWYgKHRoaXMuX2lzTm90Snd0VG9rZW4oKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZU5vQWNjZXNzRXJyb3IoJ3VwZGF0ZUV4cGVydEFkdmlzb3InKTtcbiAgICB9XG4gICAgY29uc3Qgb3B0cyA9IHtcbiAgICAgIHVybDogYCR7dGhpcy5faG9zdH0vdXNlcnMvY3VycmVudC9hY2NvdW50cy8ke2FjY291bnRJZH0vZXhwZXJ0LWFkdmlzb3JzLyR7ZXhwZXJ0SWR9YCxcbiAgICAgIG1ldGhvZDogJ1BVVCcsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgICdhdXRoLXRva2VuJzogdGhpcy5fdG9rZW5cbiAgICAgIH0sXG4gICAgICBqc29uOiB0cnVlLFxuICAgICAgZGF0YTogZXhwZXJ0XG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy5faHR0cENsaWVudC5yZXF1ZXN0KG9wdHMsICd1cGRhdGVFeHBlcnRBZHZpc29yJyk7XG4gIH1cblxuICAvKipcbiAgICogVXBsb2FkcyBhbiBleHBlcnQgYWR2aXNvciBmaWxlIChzZWUgaHR0cHM6Ly9tZXRhYXBpLmNsb3VkL2RvY3MvcHJvdmlzaW9uaW5nL2FwaS9leHBlcnRBZHZpc29yL3VwbG9hZEVBRmlsZS8pXG4gICAqIE1ldGhvZCBpcyBhY2Nlc3NpYmxlIG9ubHkgd2l0aCBBUEkgYWNjZXNzIHRva2VuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBhY2NvdW50SWQgTWV0YXRyYWRlciBhY2NvdW50IGlkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBleHBlcnRJZCBleHBlcnQgaWRcbiAgICogQHBhcmFtIHtTdHJpbmd8QnVmZmVyfSBmaWxlIHBhdGggdG8gYSBmaWxlIHRvIHVwbG9hZCBvciBidWZmZXIgY29udGFpbmluZyBmaWxlIGNvbnRlbnRzXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBwcm9taXNlIHJlc29sdmluZyB3aGVuIGZpbGUgdXBsb2FkIGlzIGNvbXBsZXRlZFxuICAgKi9cbiAgdXBsb2FkRXhwZXJ0QWR2aXNvckZpbGUoYWNjb3VudElkLCBleHBlcnRJZCwgZmlsZSkge1xuICAgIGlmICh0aGlzLl9pc05vdEp3dFRva2VuKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVOb0FjY2Vzc0Vycm9yKCd1cGxvYWRFeHBlcnRBZHZpc29yRmlsZScpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGZpbGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmaWxlID0gZnMuY3JlYXRlUmVhZFN0cmVhbShmaWxlKTtcbiAgICB9XG5cbiAgICBjb25zdCBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgIGZvcm1EYXRhLmFwcGVuZCgnZmlsZScsIGZpbGUpO1xuXG4gICAgY29uc3Qgb3B0cyA9IHtcbiAgICAgIG1ldGhvZDogJ1BVVCcsXG4gICAgICB1cmw6IGAke3RoaXMuX2hvc3R9L3VzZXJzL2N1cnJlbnQvYWNjb3VudHMvJHthY2NvdW50SWR9L2V4cGVydC1hZHZpc29ycy8ke2V4cGVydElkfS9maWxlYCxcbiAgICAgIGRhdGE6IGZvcm1EYXRhLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAuLi5mb3JtRGF0YS5nZXRIZWFkZXJzKCksXG4gICAgICAgICdhdXRoLXRva2VuJzogdGhpcy5fdG9rZW5cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoaXMuX2h0dHBDbGllbnQucmVxdWVzdChvcHRzLCAndXBsb2FkRXhwZXJ0QWR2aXNvckZpbGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGFuIGV4cGVydCBhZHZpc29yIChzZWUgaHR0cHM6Ly9tZXRhYXBpLmNsb3VkL2RvY3MvcHJvdmlzaW9uaW5nL2FwaS9leHBlcnRBZHZpc29yL2RlbGV0ZUV4cGVydEFkdmlzb3IvKVxuICAgKiBNZXRob2QgaXMgYWNjZXNzaWJsZSBvbmx5IHdpdGggQVBJIGFjY2VzcyB0b2tlblxuICAgKiBAcGFyYW0ge1N0cmluZ30gYWNjb3VudElkIE1ldGF0cmFkZXIgYWNjb3VudCBpZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXhwZXJ0SWQgZXhwZXJ0IGlkXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBwcm9taXNlIHJlc29sdmluZyB3aGVuIGV4cGVydCBhZHZpc29yIGlzIGRlbGV0ZWRcbiAgICovXG4gIGRlbGV0ZUV4cGVydEFkdmlzb3IoYWNjb3VudElkLCBleHBlcnRJZCkge1xuICAgIGlmICh0aGlzLl9pc05vdEp3dFRva2VuKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVOb0FjY2Vzc0Vycm9yKCdkZWxldGVFeHBlcnRBZHZpc29yJyk7XG4gICAgfVxuICAgIGNvbnN0IG9wdHMgPSB7XG4gICAgICB1cmw6IGAke3RoaXMuX2hvc3R9L3VzZXJzL2N1cnJlbnQvYWNjb3VudHMvJHthY2NvdW50SWR9L2V4cGVydC1hZHZpc29ycy8ke2V4cGVydElkfWAsXG4gICAgICBtZXRob2Q6ICdERUxFVEUnLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnYXV0aC10b2tlbic6IHRoaXMuX3Rva2VuXG4gICAgICB9LFxuICAgICAganNvbjogdHJ1ZVxuICAgIH07XG4gICAgcmV0dXJuIHRoaXMuX2h0dHBDbGllbnQucmVxdWVzdChvcHRzLCAnZGVsZXRlRXhwZXJ0QWR2aXNvcicpO1xuICB9XG5cbn1cbiJdLCJuYW1lcyI6WyJFeHBlcnRBZHZpc29yQ2xpZW50IiwiTWV0YUFwaUNsaWVudCIsImdldEV4cGVydEFkdmlzb3JzIiwiYWNjb3VudElkIiwiX2lzTm90Snd0VG9rZW4iLCJfaGFuZGxlTm9BY2Nlc3NFcnJvciIsIm9wdHMiLCJ1cmwiLCJfaG9zdCIsIm1ldGhvZCIsImhlYWRlcnMiLCJfdG9rZW4iLCJqc29uIiwiX2h0dHBDbGllbnQiLCJyZXF1ZXN0IiwiZ2V0RXhwZXJ0QWR2aXNvciIsImV4cGVydElkIiwidXBkYXRlRXhwZXJ0QWR2aXNvciIsImV4cGVydCIsImRhdGEiLCJ1cGxvYWRFeHBlcnRBZHZpc29yRmlsZSIsImZpbGUiLCJmcyIsImNyZWF0ZVJlYWRTdHJlYW0iLCJmb3JtRGF0YSIsIkZvcm1EYXRhIiwiYXBwZW5kIiwiZ2V0SGVhZGVycyIsImRlbGV0ZUV4cGVydEFkdmlzb3IiXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7O2VBU3FCQTs7O3NFQVBLO2lFQUNMOzJEQUNOOzs7Ozs7QUFLQSxJQUFBLEFBQU1BLHNCQUFOLE1BQU1BLDRCQUE0QkMsc0JBQWE7SUFFNUQ7Ozs7Ozs7R0FPQyxHQUVEOzs7Ozs7R0FNQyxHQUNEQyxrQkFBa0JDLFNBQVMsRUFBRTtRQUMzQixJQUFJLElBQUksQ0FBQ0MsY0FBYyxJQUFJO1lBQ3pCLE9BQU8sSUFBSSxDQUFDQyxvQkFBb0IsQ0FBQztRQUNuQztRQUNBLE1BQU1DLE9BQU87WUFDWEMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDQyxLQUFL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