@jsprismarine/prismarine
Version:
Dedicated Minecraft Bedrock Edition server written in TypeScript
164 lines (163 loc) • 17.1 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_runtime = require("../_virtual/_rolldown/runtime.cjs.cjs");
let node_fs = require("node:fs");
node_fs = require_runtime.__toESM(node_fs, 1);
let confbox = require("confbox");
let _jsprismarine_errors = require("@jsprismarine/errors");
let node_path = require("node:path");
node_path = require_runtime.__toESM(node_path, 1);
//#region src/config/ConfigBuilder.ts
var _ = {
get: (obj, path, defaultValue = void 0) => {
const travel = (regexp) => String.prototype.split.call(path, regexp).filter(Boolean).reduce((res, key) => res !== null && res !== void 0 ? res[key] : res, obj);
const result = travel(/[,[\]]+?/) || travel(/[,[\].]+?/);
return result === void 0 || result === obj ? defaultValue : result;
},
set: (obj, path, value) => {
if (Object(obj) !== obj) return obj;
if (!Array.isArray(path)) path = path.toString().match(/[^.[\]]+/g) || [];
path.slice(0, -1).reduce((a, c, i) => Object(a[c]) === a[c] ? a[c] : a[c] = Math.abs(path[i + 1]) >> 0 === Number(path[i + 1]) ? [] : {}, obj)[path.at(-1)] = value;
return obj;
},
has: (obj, key) => {
const keyParts = key.split(".");
return Boolean(obj && (keyParts.length > 1 ? _.has(obj[key.split(".")[0]], keyParts.slice(1).join(".")) : Object.hasOwnProperty.call(obj, key)));
},
del: (obj, path) => {
const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
pathArray.reduce((acc, key, i) => {
if (i === pathArray.length - 1) delete acc[key];
return acc[key];
}, obj);
return true;
}
};
var TypeDefaults = {
json: "{}",
yaml: " "
};
/**
* General config-file handler.
*/
var ConfigBuilder = class {
type;
path;
/**
* Config constructor.
*/
constructor(filePath) {
const pathSplitted = node_path.default.parse(filePath);
this.type = pathSplitted.ext.slice(1);
if (!Object.keys(TypeDefaults).some((i) => i.toLowerCase() === this.type.toLowerCase())) throw new Error(`Unsupported config type. (Supported types: ${Object.keys(TypeDefaults).join(", ")})`);
if (!node_fs.default.existsSync(pathSplitted.dir)) node_fs.default.mkdirSync(pathSplitted.dir, { recursive: true });
if (!node_fs.default.existsSync(filePath)) node_fs.default.writeFileSync(filePath, TypeDefaults[this.type], "utf8");
this.path = filePath;
}
/**
* Get path to the config file on the filesystem.
*
* @returns {string} the path to the config file
*/
getPath() {
return this.path;
}
/**
* Get the config format (eg. type).
*
* @returns {'yaml' | 'json'} either `yaml` or `json`
*/
getType() {
return this.type;
}
/**
* @private
*/
setFileData(data = {}) {
if (!data) throw new _jsprismarine_errors.ConfigInvalidDataError();
node_fs.default.writeFileSync(this.path, this.stringify(data), "utf8");
}
/**
* @private
*/
stringify(data = {}) {
switch (this.type) {
case "json": return JSON.stringify(data, null, 4);
case "yaml": return (0, confbox.stringifyYAML)(data, { indent: 4 });
default: throw new Error(`Unknown config type ${this.type}!`);
}
}
getFileData() {
const raw = node_fs.default.readFileSync(this.path, "utf8");
switch (this.type) {
case "json":
try {
return (0, confbox.parseJSON5)(raw);
} catch {}
break;
case "yaml":
try {
return (0, confbox.parseYAML)(raw);
} catch {}
break;
default: throw new Error(`Unknown config type: ${this.type}!`);
}
return {};
}
/**
* Get a config value from a key.
*
* @param {string} key - the config key
* @param {T} defaults -
*/
get(key, defaults) {
const data = this.getFileData();
let result = _.get(data, key);
if (typeof result === "undefined" && typeof defaults !== "undefined") {
const newData = _.set(data, key, defaults);
this.setFileData(newData);
result = defaults;
}
return result;
}
/**
* Sets a key - value pair in config.
*
* @returns true if the value was set successfully
*/
set(key, value) {
const data = this.getFileData();
const newData = _.set(data, key, value);
try {
this.setFileData(newData);
return true;
} catch {
return false;
}
}
/**
* Check if config value exists.
*
* @param key - the config key
* @returns true if the config contains that key
*/
has(key) {
const data = this.getFileData();
return _.has(data, key);
}
/**
* Delete a config value.
*
* @param key - the config key
* @returns true if the deletion was successful
*/
del(key) {
const data = this.getFileData();
const isSuccessful = _.del(data, key);
this.setFileData(data);
return isSuccessful;
}
};
//#endregion
exports.ConfigBuilder = ConfigBuilder;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29uZmlnQnVpbGRlci5janMuY2pzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25maWcvQ29uZmlnQnVpbGRlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb25maWdJbnZhbGlkRGF0YUVycm9yIH0gZnJvbSAnQGpzcHJpc21hcmluZS9lcnJvcnMnO1xuaW1wb3J0IHsgcGFyc2VKU09ONSwgcGFyc2VZQU1MLCBzdHJpbmdpZnlZQU1MIH0gZnJvbSAnY29uZmJveCc7XG5pbXBvcnQgZnMgZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuXG5jb25zdCBfID0ge1xuICAgIGdldDogKG9iajogYW55LCBwYXRoOiBzdHJpbmcsIGRlZmF1bHRWYWx1ZSA9IHVuZGVmaW5lZCkgPT4ge1xuICAgICAgICBjb25zdCB0cmF2ZWwgPSAocmVnZXhwOiBhbnkpID0+XG4gICAgICAgICAgICBTdHJpbmcucHJvdG90eXBlLnNwbGl0XG4gICAgICAgICAgICAgICAgLmNhbGwocGF0aCwgcmVnZXhwKVxuICAgICAgICAgICAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgICAgICAgICAgICAucmVkdWNlKChyZXMsIGtleSkgPT4gKHJlcyAhPT0gbnVsbCAmJiByZXMgIT09IHVuZGVmaW5lZCA/IHJlc1trZXldIDogcmVzKSwgb2JqKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdHJhdmVsKC9bLFtcXF1dKz8vKSB8fCB0cmF2ZWwoL1ssW1xcXS5dKz8vKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkIHx8IHJlc3VsdCA9PT0gb2JqID8gZGVmYXVsdFZhbHVlIDogcmVzdWx0O1xuICAgIH0sXG4gICAgc2V0OiAob2JqOiBhbnksIHBhdGg6IGFueSwgdmFsdWU6IGFueSkgPT4ge1xuICAgICAgICBpZiAoT2JqZWN0KG9iaikgIT09IG9iaikgcmV0dXJuIG9iajtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHBhdGgpKSBwYXRoID0gcGF0aC50b1N0cmluZygpLm1hdGNoKC9bXi5bXFxdXSsvZykgfHwgW107XG4gICAgICAgIHBhdGhcbiAgICAgICAgICAgIC5zbGljZSgwLCAtMSlcbiAgICAgICAgICAgIC5yZWR1Y2UoXG4gICAgICAgICAgICAgICAgKGE6IGFueSwgYzogYW55LCBpOiBhbnkpID0+XG4gICAgICAgICAgICAgICAgICAgIE9iamVjdChhW2NdKSA9PT0gYVtjXVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBhW2NdXG4gICAgICAgICAgICAgICAgICAgICAgICA6IChhW2NdID0gTWF0aC5hYnMocGF0aFtpICsgMV0pID4+IDAgPT09IE51bWJlcihwYXRoW2kgKyAxXSkgPyBbXSA6IHt9KSxcbiAgICAgICAgICAgICAgICBvYmpcbiAgICAgICAgICAgIClbcGF0aC5hdCgtMSldID0gdmFsdWU7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfSxcbiAgICBoYXM6IChvYmo6IGFueSwga2V5OiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgICAgICAgY29uc3Qga2V5UGFydHMgPSBrZXkuc3BsaXQoJy4nKTtcblxuICAgICAgICByZXR1cm4gQm9vbGVhbihcbiAgICAgICAgICAgIG9iaiAmJlxuICAgICAgICAgICAgKGtleVBhcnRzLmxlbmd0aCA+IDFcbiAgICAgICAgICAgICAgICA/IF8uaGFzKG9ialtrZXkuc3BsaXQoJy4nKVswXSFdLCBrZXlQYXJ0cy5zbGljZSgxKS5qb2luKCcuJykpXG4gICAgICAgICAgICAgICAgOiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpXG4gICAgICAgICk7XG4gICAgfSxcbiAgICBkZWw6IChvYmo6IGFueSwgcGF0aDogYW55KSA9PiB7XG4gICAgICAgIGNvbnN0IHBhdGhBcnJheSA9IEFycmF5LmlzQXJyYXkocGF0aCkgPyBwYXRoIDogcGF0aC5tYXRjaCgvKFteWy5cXF1dKSsvZyk7XG5cbiAgICAgICAgcGF0aEFycmF5LnJlZHVjZSgoYWNjOiBhbnksIGtleTogYW55LCBpOiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIGlmIChpID09PSBwYXRoQXJyYXkubGVuZ3RoIC0gMSkgZGVsZXRlIGFjY1trZXldO1xuICAgICAgICAgICAgcmV0dXJuIGFjY1trZXldO1xuICAgICAgICB9LCBvYmopO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG59O1xuXG5jb25zdCBUeXBlRGVmYXVsdHMgPSB7XG4gICAganNvbjogJ3t9JyxcbiAgICB5YW1sOiAnICdcbn07XG5cbmV4cG9ydCB0eXBlIENvbmZpZ0RhdGEgPSB7XG4gICAgW2tleTogc3RyaW5nXTogYW55O1xufTtcblxuLyoqXG4gKiBHZW5lcmFsIGNvbmZpZy1maWxlIGhhbmRsZXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25maWdCdWlsZGVyIHtcbiAgICBwcml2YXRlIHR5cGU6ICd5YW1sJyB8ICdqc29uJztcbiAgICBwcml2YXRlIHBhdGg6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbmZpZyBjb25zdHJ1Y3Rvci5cbiAgICAgKi9cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoZmlsZVBhdGg6IHN0cmluZykge1xuICAgICAgICBjb25zdCBwYXRoU3BsaXR0ZWQgPSBwYXRoLnBhcnNlKGZpbGVQYXRoKTtcblxuICAgICAgICB0aGlzLnR5cGUgPSBwYXRoU3BsaXR0ZWQuZXh0LnNsaWNlKDEpIGFzICd5YW1sJyB8ICdqc29uJztcblxuICAgICAgICBpZiAoIU9iamVjdC5rZXlzKFR5cGVEZWZhdWx0cykuc29tZSgoaSkgPT4gaS50b0xvd2VyQ2FzZSgpID09PSB0aGlzLnR5cGUudG9Mb3dlckNhc2UoKSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgY29uZmlnIHR5cGUuIChTdXBwb3J0ZWQgdHlwZXM6ICR7T2JqZWN0LmtleXMoVHlwZURlZmF1bHRzKS5qb2luKCcsICcpfSlgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENyZWF0ZSB0aGUgY29uZmlnIGRpcmVjdG9yeSBpZiBpdCBkb2Vzbid0IGV4aXN0LlxuICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmMocGF0aFNwbGl0dGVkLmRpcikpIGZzLm1rZGlyU3luYyhwYXRoU3BsaXR0ZWQuZGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGZpbGVQYXRoKSkgZnMud3JpdGVGaWxlU3luYyhmaWxlUGF0aCwgKFR5cGVEZWZhdWx0cyBhcyBhbnkpW3RoaXMudHlwZV0sICd1dGY4Jyk7XG5cbiAgICAgICAgdGhpcy5wYXRoID0gZmlsZVBhdGg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHBhdGggdG8gdGhlIGNvbmZpZyBmaWxlIG9uIHRoZSBmaWxlc3lzdGVtLlxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ30gdGhlIHBhdGggdG8gdGhlIGNvbmZpZyBmaWxlXG4gICAgICovXG4gICAgcHVibGljIGdldFBhdGgoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGF0aDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGNvbmZpZyBmb3JtYXQgKGVnLiB0eXBlKS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHsneWFtbCcgfCAnanNvbid9IGVpdGhlciBgeWFtbGAgb3IgYGpzb25gXG4gICAgICovXG4gICAgcHVibGljIGdldFR5cGUoKTogJ3lhbWwnIHwgJ2pzb24nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgc2V0RmlsZURhdGEoZGF0YTogQ29uZmlnRGF0YSA9IHt9KSB7XG4gICAgICAgIGlmICghKGRhdGEgYXMgYW55KSkgdGhyb3cgbmV3IENvbmZpZ0ludmFsaWREYXRhRXJyb3IoKTtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0aGlzLnBhdGgsIHRoaXMuc3RyaW5naWZ5KGRhdGEpLCAndXRmOCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBzdHJpbmdpZnkoZGF0YTogQ29uZmlnRGF0YSA9IHt9KSB7XG4gICAgICAgIC8vIEZJWE1FOiBUaGlzIG92ZXJ3cml0ZXMgY29tbWVudHMgaW4gdGhlIGZpbGUuXG4gICAgICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICAgICAgICBjYXNlICdqc29uJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZGF0YSwgbnVsbCwgNCk7XG4gICAgICAgICAgICBjYXNlICd5YW1sJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RyaW5naWZ5WUFNTChkYXRhLCB7IGluZGVudDogNCB9KTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGNvbmZpZyB0eXBlICR7dGhpcy50eXBlfSFgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0RmlsZURhdGEoKTogQ29uZmlnRGF0YSB7XG4gICAgICAgIGNvbnN0IHJhdyA9IGZzLnJlYWRGaWxlU3luYyh0aGlzLnBhdGgsICd1dGY4Jyk7XG5cbiAgICAgICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2pzb24nOlxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUpTT041KHJhdyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCB7fVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAneWFtbCc6XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlWUFNTChyYXcpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2gge31cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGNvbmZpZyB0eXBlOiAke3RoaXMudHlwZX0hYCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGEgY29uZmlnIHZhbHVlIGZyb20gYSBrZXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gdGhlIGNvbmZpZyBrZXlcbiAgICAgKiBAcGFyYW0ge1R9IGRlZmF1bHRzIC1cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0PFQgPSBhbnk+KGtleTogc3RyaW5nLCBkZWZhdWx0cz86IFQpOiBUIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZ2V0RmlsZURhdGEoKTtcbiAgICAgICAgbGV0IHJlc3VsdCA9IF8uZ2V0KGRhdGEsIGtleSk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBkZWZhdWx0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGNvbnN0IG5ld0RhdGEgPSBfLnNldChkYXRhLCBrZXksIGRlZmF1bHRzKTtcbiAgICAgICAgICAgIHRoaXMuc2V0RmlsZURhdGEobmV3RGF0YSk7XG4gICAgICAgICAgICByZXN1bHQgPSBkZWZhdWx0cztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBhIGtleSAtIHZhbHVlIHBhaXIgaW4gY29uZmlnLlxuICAgICAqXG4gICAgICogQHJldHVybnMgdHJ1ZSBpZiB0aGUgdmFsdWUgd2FzIHNldCBzdWNjZXNzZnVsbHlcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0KGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdldEZpbGVEYXRhKCk7XG4gICAgICAgIGNvbnN0IG5ld0RhdGEgPSBfLnNldChkYXRhLCBrZXksIHZhbHVlKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5zZXRGaWxlRGF0YShuZXdEYXRhKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIGNvbmZpZyB2YWx1ZSBleGlzdHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ga2V5IC0gdGhlIGNvbmZpZyBrZXlcbiAgICAgKiBAcmV0dXJucyB0cnVlIGlmIHRoZSBjb25maWcgY29udGFpbnMgdGhhdCBrZXlcbiAgICAgKi9cbiAgICBwdWJsaWMgaGFzKGtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdldEZpbGVEYXRhKCk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IF8uaGFzKGRhdGEsIGtleSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVsZXRlIGEgY29uZmlnIHZhbHVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIGtleSAtIHRoZSBjb25maWcga2V5XG4gICAgICogQHJldHVybnMgdHJ1ZSBpZiB0aGUgZGVsZXRpb24gd2FzIHN1Y2Nlc3NmdWxcbiAgICAgKi9cbiAgICBwdWJsaWMgZGVsKGtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdldEZpbGVEYXRhKCk7XG5cbiAgICAgICAgLy8gSXQgbXV0YXRlcyB0aGUgb2JqZWN0LCB3ZVxuICAgICAgICAvLyBkb24ndCBuZWVkIHRvIGRlZmluZSBhIG5ld1xuICAgICAgICAvLyB2YXJpYWJsZS5cbiAgICAgICAgY29uc3QgaXNTdWNjZXNzZnVsID0gXy5kZWwoZGF0YSwga2V5KTtcblxuICAgICAgICB0aGlzLnNldEZpbGVEYXRhKGRhdGEpO1xuICAgICAgICByZXR1cm4gaXNTdWNjZXNzZnVsO1xuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUtBLElBQU0sSUFBSTtDQUNOLE1BQU0sS0FBVSxNQUFjLGVBQWUsS0FBQSxNQUFjO0VBQ3ZELE1BQU0sVUFBVSxXQUNaLE9BQU8sVUFBVSxNQUNaLEtBQUssTUFBTSxNQUFNLEVBQ2pCLE9BQU8sT0FBTyxFQUNkLFFBQVEsS0FBSyxRQUFTLFFBQVEsUUFBUSxRQUFRLEtBQUEsSUFBWSxJQUFJLE9BQU8sS0FBTSxHQUFHO0VBQ3ZGLE1BQU0sU0FBUyxPQUFPLFVBQVUsS0FBSyxPQUFPLFdBQVc7RUFDdkQsT0FBTyxXQUFXLEtBQUEsS0FBYSxXQUFXLE1BQU0sZUFBZTtDQUNuRTtDQUNBLE1BQU0sS0FBVSxNQUFXLFVBQWU7RUFDdEMsSUFBSSxPQUFPLEdBQUcsTUFBTSxLQUFLLE9BQU87RUFDaEMsSUFBSSxDQUFDLE1BQU0sUUFBUSxJQUFJLEdBQUcsT0FBTyxLQUFLLFNBQVMsRUFBRSxNQUFNLFdBQVcsS0FBSyxDQUFDO0VBQ3hFLEtBQ0ssTUFBTSxHQUFHLEVBQUUsRUFDWCxRQUNJLEdBQVEsR0FBUSxNQUNiLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUNiLEVBQUUsS0FDRCxFQUFFLEtBQUssS0FBSyxJQUFJLEtBQUssSUFBSSxFQUFFLEtBQUssTUFBTSxPQUFPLEtBQUssSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FDN0UsR0FDSixFQUFFLEtBQUssR0FBRyxFQUFFLEtBQUs7RUFDckIsT0FBTztDQUNYO0NBQ0EsTUFBTSxLQUFVLFFBQXlCO0VBQ3JDLE1BQU0sV0FBVyxJQUFJLE1BQU0sR0FBRztFQUU5QixPQUFPLFFBQ0gsUUFDQyxTQUFTLFNBQVMsSUFDYixFQUFFLElBQUksSUFBSSxJQUFJLE1BQU0sR0FBRyxFQUFFLEtBQU0sU0FBUyxNQUFNLENBQUMsRUFBRSxLQUFLLEdBQUcsQ0FBQyxJQUMxRCxPQUFPLGVB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