UNPKG

@jsprismarine/prismarine

Version:

Dedicated Minecraft Bedrock Edition server written in TypeScript

180 lines (173 loc) 20.9 kB
'use strict'; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } }); const utils_cwd = require('../utils/cwd.cjs.cjs'); require('@jsprismarine/nbt'); require('@jsprismarine/bedrock-data'); require('@jsprismarine/jsbinaryutils'); require('zlib'); require('@jsprismarine/math'); const world_GeneratorManager = require('./GeneratorManager.cjs.cjs'); const world_World = require('./World.cjs.cjs'); const world_providers_anvil_Anvil = require('./providers/anvil/Anvil.cjs.cjs'); const world_providers_filesystem_Filesystem = require('./providers/filesystem/Filesystem.cjs.cjs'); const fs = require('node:fs'); const _interopDefault = e => e && e.__esModule ? e : { default: e }; const fs__default = /*#__PURE__*/_interopDefault(fs); const WORLDS_FOLDER = "worlds"; const DEFAULT_WORLD_PROVIDER = "Filesystem"; class WorldManager { worlds = /* @__PURE__ */ new Map(); defaultWorld; genManager; server; providers = /* @__PURE__ */ new Map(); // TODO: this should be a manager constructor(server) { this.server = server; this.genManager = new world_GeneratorManager.GeneratorManager(server); if (!fs__default.default.existsSync(utils_cwd.withCwd(WORLDS_FOLDER))) { fs__default.default.mkdirSync(utils_cwd.withCwd(WORLDS_FOLDER), { recursive: true }); } } /** * On enable hook, enables the manager and load all worlds. * @group Lifecycle */ async enable() { this.addProvider("Anvil", world_providers_anvil_Anvil.default); this.addProvider("Filesystem", world_providers_filesystem_Filesystem.default); const defaultWorld = this.server.getConfig().getLevelName(); if (!defaultWorld) { this.server.getLogger().warn(`Invalid world!`); return; } const worldData = this.server.getConfig().getWorlds()[defaultWorld]; if (!worldData) throw new Error(`Invalid level-name`); await this.loadWorld(worldData, defaultWorld); } /** * On disable hook. * * Signifies that the manager is being disabled and all worlds should be unloaded. * @group Lifecycle */ async disable() { await Promise.all(this.getWorlds().map(async (world) => this.unloadWorld(world.getName()))); this.providers.clear(); } /** * Add a provider to the internal providers map. * * @param name - the name of the provider CASE SENSITIVE * @param provider - the provider */ addProvider(name, provider) { this.providers.set(name, provider); } /** * Remove a provider from the internal providers map. * * @param name - the name of the provider CASE SENSITIVE */ removeProvider(name) { this.providers.delete(name); } /** * Get all providers. */ getProviders() { return this.providers; } /** * Save the world to disk. */ async save() { this.server.getLogger().info("Saving worlds"); for (const world of this.getWorlds()) { await world.save(); } } /** * Load a world * * @param worldData - the world data including provider key, generator * @param folderName - the name of the folder containing the world */ async loadWorld(worldData, folderName) { if (!worldData) throw new Error("Invalid world data"); if (this.isWorldLoaded(folderName)) { throw new Error(`World ${folderName} has already been loaded`); } const levelPath = utils_cwd.withCwd(WORLDS_FOLDER, folderName); const provider = this.providers.get(worldData.provider ?? DEFAULT_WORLD_PROVIDER); const generator = this.getGeneratorManager().getGenerator(worldData.generator ?? "Flat"); if (!provider) { throw new Error(`invalid provider with id ${worldData.provider}`); } const world = new world_World.World({ name: folderName, path: levelPath, server: this.server, provider: new provider(levelPath, this.server), seed: worldData.seed, generator, config: worldData }); this.worlds.set(world.getUUID(), world); if (!this.defaultWorld) { this.defaultWorld = this.worlds.get(world.getUUID()); this.server.getLogger().info(`Loading ${world.getFormattedName()} as default world!`); } await world.enable(); this.server.getLogger().verbose(`World ${world.getFormattedName()} successfully loaded!`); return world; } /** * Unloads a level by its folder name. */ async unloadWorld(folderName) { if (!this.isWorldLoaded(folderName)) { this.server.getLogger().error(`Cannot unload a not loaded world with name §b${folderName}`); return; } const world = this.getWorldByName(folderName); if (!world) { this.server.getLogger().error(`Cannot unload world ${folderName}`); return; } await world.disable(); this.worlds.delete(world.getUUID()); this.server.getLogger().verbose(`Successfully unloaded world ${world.getFormattedName()}!`); } /** * Returns whatever the world is loaded or not. * @returns {boolean} true if the world is loaded, false otherwise */ isWorldLoaded(folderName) { const world = Array.from(this.worlds.values()).find( (world2) => world2.getName().toLowerCase() === folderName.toLowerCase() ); if (world) return true; return false; } /** * Returns a world by its folder name. */ getWorldByName(folderName) { return this.getWorlds().find((world) => world.getName().toLowerCase() === folderName.toLowerCase()) ?? null; } /** * Returns an array with all worlds. */ getWorlds() { return Array.from(this.worlds.values()); } getDefaultWorld() { return this.defaultWorld ?? this.getWorlds()[0]; } getGeneratorManager() { return this.genManager; } } exports.default = WorldManager; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV29ybGRNYW5hZ2VyLmNqcy5janMiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93b3JsZC9Xb3JsZE1hbmFnZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBTZXJ2ZXIsIFNlcnZpY2UgfSBmcm9tICcuLi8nO1xuaW1wb3J0IHsgd2l0aEN3ZCB9IGZyb20gJy4uL3V0aWxzL2N3ZCc7XG5pbXBvcnQgeyBHZW5lcmF0b3JNYW5hZ2VyIH0gZnJvbSAnLi8nO1xuaW1wb3J0IHsgV29ybGQgfSBmcm9tICcuL1dvcmxkJztcbmltcG9ydCB0eXBlIFByb3ZpZGVyIGZyb20gJy4vcHJvdmlkZXJzL1Byb3ZpZGVyJztcblxuaW1wb3J0IEFudmlsIGZyb20gJy4vcHJvdmlkZXJzL2FudmlsL0FudmlsJztcbmltcG9ydCBGaWxlc3lzdGVtIGZyb20gJy4vcHJvdmlkZXJzL2ZpbGVzeXN0ZW0vRmlsZXN5c3RlbSc7XG5cbmltcG9ydCBmcyBmcm9tICdub2RlOmZzJztcblxuLyoqXG4gKiBTdGFuZGFyZCB3b3JsZCBkYXRhLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFdvcmxkRGF0YSB7XG4gICAgc2VlZDogbnVtYmVyO1xuICAgIHByb3ZpZGVyPzogc3RyaW5nO1xuICAgIGdlbmVyYXRvcj86IHN0cmluZztcbn1cblxuY29uc3QgV09STERTX0ZPTERFUiA9ICd3b3JsZHMnO1xuY29uc3QgREVGQVVMVF9XT1JMRF9QUk9WSURFUiA9ICdGaWxlc3lzdGVtJztcblxuLyoqXG4gKiBUaGUgd29ybGQgbWFuYWdlciBpcyByZXNwb25zaWJsZSBsZXZlbCBsb2FkaW5nLCB1bmxvYWRpbmcsIGFuZCBnZW5lcmFsIGxldmVsIG1hbmFnZW1lbnQuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFdvcmxkTWFuYWdlciBpbXBsZW1lbnRzIFNlcnZpY2Uge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgd29ybGRzOiBNYXA8c3RyaW5nLCBXb3JsZD4gPSBuZXcgTWFwKCkgYXMgTWFwPHN0cmluZywgV29ybGQ+O1xuICAgIHByaXZhdGUgZGVmYXVsdFdvcmxkOiBXb3JsZCB8IHVuZGVmaW5lZDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGdlbk1hbmFnZXI6IEdlbmVyYXRvck1hbmFnZXI7XG4gICAgcHJpdmF0ZSByZWFkb25seSBzZXJ2ZXI6IFNlcnZlcjtcbiAgICBwcml2YXRlIHByb3ZpZGVyczogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKSBhcyBNYXA8c3RyaW5nLCBhbnk+OyAvLyBUT0RPOiB0aGlzIHNob3VsZCBiZSBhIG1hbmFnZXJcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihzZXJ2ZXI6IFNlcnZlcikge1xuICAgICAgICB0aGlzLnNlcnZlciA9IHNlcnZlcjtcbiAgICAgICAgdGhpcy5nZW5NYW5hZ2VyID0gbmV3IEdlbmVyYXRvck1hbmFnZXIoc2VydmVyKTtcblxuICAgICAgICAvLyBDcmVhdGUgdGhlIHdvcmxkcyBkaXJlY3RvcnkgaWYgaXQgZG9lc24ndCBleGlzdC5cbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHdpdGhDd2QoV09STERTX0ZPTERFUikpKSB7XG4gICAgICAgICAgICBmcy5ta2RpclN5bmMod2l0aEN3ZChXT1JMRFNfRk9MREVSKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPbiBlbmFibGUgaG9vaywgZW5hYmxlcyB0aGUgbWFuYWdlciBhbmQgbG9hZCBhbGwgd29ybGRzLlxuICAgICAqIEBncm91cCBMaWZlY3ljbGVcbiAgICAgKi9cbiAgICBwdWJsaWMgYXN5bmMgZW5hYmxlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmFkZFByb3ZpZGVyKCdBbnZpbCcsIEFudmlsKTtcbiAgICAgICAgdGhpcy5hZGRQcm92aWRlcignRmlsZXN5c3RlbScsIEZpbGVzeXN0ZW0pO1xuXG4gICAgICAgIGNvbnN0IGRlZmF1bHRXb3JsZCA9IHRoaXMuc2VydmVyLmdldENvbmZpZygpLmdldExldmVsTmFtZSgpO1xuICAgICAgICBpZiAoIWRlZmF1bHRXb3JsZCkge1xuICAgICAgICAgICAgdGhpcy5zZXJ2ZXIuZ2V0TG9nZ2VyKCkud2FybihgSW52YWxpZCB3b3JsZCFgKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHdvcmxkRGF0YSA9IHRoaXMuc2VydmVyLmdldENvbmZpZygpLmdldFdvcmxkcygpW2RlZmF1bHRXb3JsZF07XG4gICAgICAgIGlmICghd29ybGREYXRhKSB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgbGV2ZWwtbmFtZWApO1xuXG4gICAgICAgIGF3YWl0IHRoaXMubG9hZFdvcmxkKHdvcmxkRGF0YSwgZGVmYXVsdFdvcmxkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPbiBkaXNhYmxlIGhvb2suXG4gICAgICpcbiAgICAgKiBTaWduaWZpZXMgdGhhdCB0aGUgbWFuYWdlciBpcyBiZWluZyBkaXNhYmxlZCBhbmQgYWxsIHdvcmxkcyBzaG91bGQgYmUgdW5sb2FkZWQuXG4gICAgICogQGdyb3VwIExpZmVjeWNsZVxuICAgICAqL1xuICAgIHB1YmxpYyBhc3luYyBkaXNhYmxlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbCh0aGlzLmdldFdvcmxkcygpLm1hcChhc3luYyAod29ybGQpID0+IHRoaXMudW5sb2FkV29ybGQod29ybGQuZ2V0TmFtZSgpKSkpO1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5jbGVhcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCBhIHByb3ZpZGVyIHRvIHRoZSBpbnRlcm5hbCBwcm92aWRlcnMgbWFwLlxuICAgICAqXG4gICAgICogQHBhcmFtIG5hbWUgLSB0aGUgbmFtZSBvZiB0aGUgcHJvdmlkZXIgQ0FTRSBTRU5TSVRJVkVcbiAgICAgKiBAcGFyYW0gcHJvdmlkZXIgLSB0aGUgcHJvdmlkZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgYWRkUHJvdmlkZXIobmFtZTogc3RyaW5nLCBwcm92aWRlcjogYW55KSB7XG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChuYW1lLCBwcm92aWRlcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGEgcHJvdmlkZXIgZnJvbSB0aGUgaW50ZXJuYWwgcHJvdmlkZXJzIG1hcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBuYW1lIC0gdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIENBU0UgU0VOU0lUSVZFXG4gICAgICovXG4gICAgcHVibGljIHJlbW92ZVByb3ZpZGVyKG5hbWU6IHN0cmluZykge1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5kZWxldGUobmFtZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGFsbCBwcm92aWRlcnMuXG4gICAgICovXG4gICAgcHVibGljIGdldFByb3ZpZGVycygpOiBNYXA8c3RyaW5nLCBQcm92aWRlcj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm92aWRlcnMgYXMgTWFwPHN0cmluZywgUHJvdmlkZXI+O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNhdmUgdGhlIHdvcmxkIHRvIGRpc2suXG4gICAgICovXG4gICAgcHVibGljIGFzeW5jIHNhdmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuc2VydmVyLmdldExvZ2dlcigpLmluZm8oJ1NhdmluZyB3b3JsZHMnKTtcbiAgICAgICAgZm9yIChjb25zdCB3b3JsZCBvZiB0aGlzLmdldFdvcmxkcygpKSB7XG4gICAgICAgICAgICBhd2FpdCB3b3JsZC5zYXZlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMb2FkIGEgd29ybGRcbiAgICAgKlxuICAgICAqIEBwYXJhbSB3b3JsZERhdGEgLSB0aGUgd29ybGQgZGF0YSBpbmNsdWRpbmcgcHJvdmlkZXIga2V5LCBnZW5lcmF0b3JcbiAgICAgKiBAcGFyYW0gZm9sZGVyTmFtZSAtIHRoZSBuYW1lIG9mIHRoZSBmb2xkZXIgY29udGFpbmluZyB0aGUgd29ybGRcbiAgICAgKi9cbiAgICBwdWJsaWMgYXN5bmMgbG9hZFdvcmxkKHdvcmxkRGF0YTogV29ybGREYXRhLCBmb2xkZXJOYW1lOiBzdHJpbmcpOiBQcm9taXNlPFdvcmxkPiB7XG4gICAgICAgIGlmICghKHdvcmxkRGF0YSBhcyBhbnkpKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgd29ybGQgZGF0YScpO1xuXG4gICAgICAgIGlmICh0aGlzLmlzV29ybGRMb2FkZWQoZm9sZGVyTmFtZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgV29ybGQgJHtmb2xkZXJOYW1lfSBoYXMgYWxyZWFkeSBiZWVuIGxvYWRlZGApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGV2ZWxQYXRoID0gd2l0aEN3ZChXT1JMRFNfRk9MREVSLCBmb2xkZXJOYW1lKTtcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLnByb3ZpZGVycy5nZXQod29ybGREYXRhLnByb3ZpZGVyID8/IERFRkFVTFRfV09STERfUFJPVklERVIpO1xuICAgICAgICBjb25zdCBnZW5lcmF0b3IgPSB0aGlzLmdldEdlbmVyYXRvck1hbmFnZXIoKS5nZXRHZW5lcmF0b3Iod29ybGREYXRhLmdlbmVyYXRvciA/PyAnRmxhdCcpO1xuXG4gICAgICAgIGlmICghcHJvdmlkZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBwcm92aWRlciB3aXRoIGlkICR7d29ybGREYXRhLnByb3ZpZGVyfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgd29ybGQgPSBuZXcgV29ybGQoe1xuICAgICAgICAgICAgbmFtZTogZm9sZGVyTmFtZSxcbiAgICAgICAgICAgIHBhdGg6IGxldmVsUGF0aCxcbiAgICAgICAgICAgIHNlcnZlcjogdGhpcy5zZXJ2ZXIsXG4gICAgICAgICAgICBwcm92aWRlcjogbmV3IHByb3ZpZGVyKGxldmVsUGF0aCwgdGhpcy5zZXJ2ZXIpLFxuXG4gICAgICAgICAgICBzZWVkOiB3b3JsZERhdGEuc2VlZCxcbiAgICAgICAgICAgIGdlbmVyYXRvcixcbiAgICAgICAgICAgIGNvbmZpZzogd29ybGREYXRhXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLndvcmxkcy5zZXQod29ybGQuZ2V0VVVJRCgpLCB3b3JsZCk7XG5cbiAgICAgICAgLy8gRmlyc3QgbGV2ZWwgdG8gYmUgbG9hZGVkIGlzIGFsc28gdGhlIGRlZmF1bHQgb25lXG4gICAgICAgIGlmICghdGhpcy5kZWZhdWx0V29ybGQpIHtcbiAgICAgICAgICAgIHRoaXMuZGVmYXVsdFdvcmxkID0gdGhpcy53b3JsZHMuZ2V0KHdvcmxkLmdldFVVSUQoKSkhO1xuICAgICAgICAgICAgdGhpcy5zZXJ2ZXIuZ2V0TG9nZ2VyKCkuaW5mbyhgTG9hZGluZyAke3dvcmxkLmdldEZvcm1hdHRlZE5hbWUoKX0gYXMgZGVmYXVsdCB3b3JsZCFgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IHdvcmxkLmVuYWJsZSgpO1xuICAgICAgICB0aGlzLnNlcnZlci5nZXRMb2dnZXIoKS52ZXJib3NlKGBXb3JsZCAke3dvcmxkLmdldEZvcm1hdHRlZE5hbWUoKX0gc3VjY2Vzc2Z1bGx5IGxvYWRlZCFgKTtcblxuICAgICAgICByZXR1cm4gd29ybGQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVW5sb2FkcyBhIGxldmVsIGJ5IGl0cyBmb2xkZXIgbmFtZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgYXN5bmMgdW5sb2FkV29ybGQoZm9sZGVyTmFtZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICghdGhpcy5pc1dvcmxkTG9hZGVkKGZvbGRlck5hbWUpKSB7XG4gICAgICAgICAgICB0aGlzLnNlcnZlci5nZXRMb2dnZXIoKS5lcnJvcihgQ2Fubm90IHVubG9hZCBhIG5vdCBsb2FkZWQgd29ybGQgd2l0aCBuYW1lIMKnYiR7Zm9sZGVyTmFtZX1gKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHdvcmxkID0gdGhpcy5nZXRXb3JsZEJ5TmFtZShmb2xkZXJOYW1lKTtcbiAgICAgICAgaWYgKCF3b3JsZCkge1xuICAgICAgICAgICAgdGhpcy5zZXJ2ZXIuZ2V0TG9nZ2VyKCkuZXJyb3IoYENhbm5vdCB1bmxvYWQgd29ybGQgJHtmb2xkZXJOYW1lfWApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgd29ybGQuZGlzYWJsZSgpO1xuICAgICAgICB0aGlzLndvcmxkcy5kZWxldGUod29ybGQuZ2V0VVVJRCgpKTtcbiAgICAgICAgdGhpcy5zZXJ2ZXIuZ2V0TG9nZ2VyKCkudmVyYm9zZShgU3VjY2Vzc2Z1bGx5IHVubG9hZGVkIHdvcmxkICR7d29ybGQuZ2V0Rm9ybWF0dGVkTmFtZSgpfSFgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHdoYXRldmVyIHRoZSB3b3JsZCBpcyBsb2FkZWQgb3Igbm90LlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIHRoZSB3b3JsZCBpcyBsb2FkZWQsIGZhbHNlIG90aGVyd2lzZVxuICAgICAqL1xuICAgIHB1YmxpYyBpc1dvcmxkTG9hZGVkKGZvbGRlck5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCB3b3JsZCA9IEFycmF5LmZyb20odGhpcy53b3JsZHMudmFsdWVzKCkpLmZpbmQoXG4gICAgICAgICAgICAod29ybGQpID0+IHdvcmxkLmdldE5hbWUoKS50b0xvd2VyQ2FzZSgpID09PSBmb2xkZXJOYW1lLnRvTG93ZXJDYXNlKClcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAod29ybGQpIHJldHVybiB0cnVlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHdvcmxkIGJ5IGl0cyBmb2xkZXIgbmFtZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0V29ybGRCeU5hbWUoZm9sZGVyTmFtZTogc3RyaW5nKTogV29ybGQgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0V29ybGRzKCkuZmluZCgod29ybGQpID0+IHdvcmxkLmdldE5hbWUoKS50b0xvd2VyQ2FzZSgpID09PSBmb2xkZXJOYW1lLnRvTG93ZXJDYXNlKCkpID8/IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbiBhcnJheSB3aXRoIGFsbCB3b3JsZHMuXG4gICAgICovXG4gICAgcHVibGljIGdldFdvcmxkcygpOiBXb3JsZFtdIHtcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy53b3JsZHMudmFsdWVzKCkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXREZWZhdWx0V29ybGQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRlZmF1bHRXb3JsZCA/PyB0aGlzLmdldFdvcmxkcygpWzBdO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRHZW5lcmF0b3JNYW5hZ2VyKCk6IEdlbmVyYXRvck1hbmFnZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5nZW5NYW5hZ2VyO1xuICAgIH1cbn1cbiJdLCJuYW1lcyI6WyJHZW5lcmF0b3JNYW5hZ2VyIiwiZnMiLCJ3aXRoQ3dkIiwiQW52aWwiLCJGaWxlc3lzdGVtIiwiV29ybGQiLCJ3b3JsZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFvQkEsTUFBTSxhQUFnQixHQUFBLFFBQUE7QUFDdEIsTUFBTSxzQkFBeUIsR0FBQSxZQUFBO0FBSy9CLE1BQXFCLFlBQWdDLENBQUE7QUFBQSxFQUNoQyxNQUFBLHVCQUFpQyxHQUFJLEVBQUE7QUFBQSxFQUM5QyxZQUFBO0FBQUEsRUFDUyxVQUFBO0FBQUEsRUFDQSxNQUFBO0FBQUEsRUFDVCxTQUFBLHVCQUFrQyxHQUFJLEVBQUE7QUFBQTtBQUFBLEVBRXZDLFlBQVksTUFBZ0IsRUFBQTtBQUMvQixJQUFBLElBQUEsQ0FBSyxNQUFTLEdBQUEsTUFBQTtBQUNkLElBQUssSUFBQSxDQUFBLFVBQUEsR0FBYSxJQUFJQSx1Q0FBQSxDQUFpQixNQUFNLENBQUE7QUFHN0MsSUFBQSxJQUFJLENBQUNDLG1CQUFHLENBQUEsVUFBQSxDQUFXQyxpQkFBUSxDQUFBLGFBQWEsQ0FBQyxDQUFHLEVBQUE7QUFDeEMsTUFBQUQsbUJBQUEsQ0FBRyxVQUFVQyxpQkFBUSxDQUFBLGFBQWEsR0FBRyxFQUFFLFNBQUEsRUFBVyxNQUFNLENBQUE7QUFBQTtBQUM1RDtBQUNKO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFNQSxNQUFhLE1BQXdCLEdBQUE7QUFDakMsSUFBSyxJQUFBLENBQUEsV0FBQSxDQUFZLFNBQVNDLG1DQUFLLENBQUE7QUFDL0IsSUFBSyxJQUFBLENBQUEsV0FBQSxDQUFZLGNBQWNDLDZDQUFVLENBQUE7QUFFekMsSUFBQSxNQUFNLFlBQWUsR0FBQSxJQUFBLENBQUssTUFBTyxDQUFBLFNBQUEsR0FBWSxZQUFhLEVBQUE7QUFDMUQsSUFBQSxJQUFJLENBQUMsWUFBYyxFQUFBO0FBQ2YsTUFBQSxJQUFBLENBQUssTUFBTyxDQUFBLFNBQUEsRUFBWSxDQUFBLElBQUEsQ0FBSyxDQUFnQixjQUFBLENBQUEsQ0FBQTtBQUM3QyxNQUFBO0FBQUE7QUFHSixJQUFBLE1BQU0sWUFBWSxJQUFLLENBQUEsTUFBQSxDQUFPLFdBQVksQ0FBQSxTQUFBLEdBQVksWUFBWSxDQUFBO0FBQ2xFLElBQUEsSUFBSSxDQUFDLFNBQUEsRUFBaUIsTUFBQSxJQUFJLE1BQU0sQ0FBb0Isa0JBQUEsQ0FBQSxDQUFBO0FBRXBELElBQU0sTUFBQSxJQUFBLENBQUssU0FBVSxDQUFBLFNBQUEsRUFBVyxZQUFZLENBQUE7QUFBQTtBQUNoRDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVFBLE1BQWEsT0FBeUIsR0FBQTtBQUNsQyxJQUFBLE1BQU0sT0FBUSxDQUFBLEdBQUEsQ0FBSSxJQUFLLENBQUEsU0FBQSxHQUFZLEdBQUksQ0FBQSxPQUFPLEtBQVUsS0FBQSxJQUFBLENBQUssV0FBWSxDQUFBLEtBQUEsQ0FBTSxPQUFRLEVBQUMsQ0FBQyxDQUFDLENBQUE7QUFDMUYsSUFBQSxJQUFBLENBQUssVUFBVSxLQUFNLEVBQUE7QUFBQTtBQUN6QjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVFPLFdBQUEsQ0FBWSxNQUFjLFFBQWUsRUFBQTtBQUM1QyxJQUFLLElBQUEsQ0FBQSxTQUFBLENBQVUsR0FBSSxDQUFBLElBQUEsRUFBTSxRQUFRLENBQUE7QUFBQTtBQUNyQztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPTyxlQUFlLElBQWMsRUFBQTtBQUNoQyxJQUFLLElBQUEsQ0FBQSxTQUFBLENBQVUsT0FBTyxJQUFJLENBQUE7QUFBQTtBQUM5QjtBQUFBO0FBQUE7QUFBQSxFQUtPLFlBQXNDLEdBQUE7QUFDekMsSUFBQSxPQUFPLElBQUssQ0FBQSxTQUFBO0FBQUE7QUFDaEI7QUFBQTtBQUFBO0FBQUEsRUFLQSxNQUFhLElBQXNCLEdBQUE7QUFDL0IsSUFBQSxJQUFBLENBQUssTUFBTyxDQUFBLFNBQUEsRUFBWSxDQUFBLElBQUEsQ0FBSyxlQUFlLENBQUE7QUFDNUMsSUFBVyxLQUFBLE1BQUEsS0FBQSxJQUFTLElBQUssQ0FBQSxTQUFBLEVBQWEsRUFBQTtBQUNsQyxNQUFBLE1BQU0sTUFBTSxJQUFLLEVBQUE7QUFBQTtBQUNyQjtBQUNKO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBUUEsTUFBYSxTQUFVLENBQUEsU0FBQSxFQUFzQixVQUFvQyxFQUFBO0FBQzdFLElBQUEsSUFBSSxDQUFFLFNBQUEsRUFBeUIsTUFBQSxJQUFJLE1BQU0sb0JBQW9CLENBQUE7QUFFN0QsSUFBSSxJQUFBLElBQUEsQ0FBSyxhQUFjLENBQUEsVUFBVSxDQUFHLEVBQUE7QUFDaEMsTUFBQSxNQUFNLElBQUksS0FBQSxDQUFNLENBQVMsTUFBQSxFQUFBLFVBQVUsQ0FBMEIsd0JBQUEsQ0FBQSxDQUFBO0FBQUE7QUFHakUsSUFBTSxNQUFBLFNBQUEsR0FBWUYsaUJBQVEsQ0FBQSxhQUFBLEVBQWUsVUFBVSxDQUFBO0FBQ25ELElBQUEsTUFBTSxXQUFXLElBQUssQ0FBQSxTQUFBLENBQVUsR0FBSSxDQUFBLFNBQUEsQ0FBVSxZQUFZLHNCQUFzQixDQUFBO0FBQ2hGLElBQUEsTUFBTSxZQUFZLElBQUssQ0FBQSxtQkFBQSxHQUFzQixZQUFhLENBQUEsU0FBQSxDQUFVLGFBQWEsTUFBTSxDQUFBO0FBRXZGLElBQUEsSUFBSSxDQUFDLFFBQVUsRUFBQTtBQUNYLE1BQUEsTUFBTSxJQUFJLEtBQUEsQ0FBTSxDQUE0Qix5QkFBQSxFQUFBLFNBQUEsQ0FBVSxRQUFRLENBQUUsQ0FBQSxDQUFBO0FBQUE7QUFHcEUsSUFBTSxNQUFBLEtBQUEsR0FBUSxJQUFJRyxpQkFBTSxDQUFBO0FBQUEsTUFDcEIsSUFBTSxFQUFBLFVBQUE7QUFBQSxNQUNOLElBQU0sRUFBQSxTQUFBO0FBQUEsTUFDTixRQUFRLElBQUssQ0FBQSxNQUFBO0FBQUEsTUFDYixRQUFVLEVBQUEsSUFBSSxRQUFTLENBQUEsU0FBQSxFQUFXLEtBQUssTUFBTSxDQUFBO0FBQUEsTUFFN0MsTUFBTSxTQUFVLENBQUEsSUFBQTtBQUFBLE1BQ2hCLFNBQUE7QUFBQSxNQUNBLE1BQVEsRUFBQTtBQUFBLEtBQ1gsQ0FBQTtBQUNELElBQUEsSUFBQSxDQUFLLE1BQU8sQ0FBQSxHQUFBLENBQUksS0FBTSxDQUFBLE9BQUEsSUFBVyxLQUFLLENBQUE7QUFHdEMsSUFBSSxJQUFBLENBQUMsS0FBSyxZQUFjLEVBQUE7QUFDcEIsTUFBQSxJQUFBLENBQUssZUFBZSxJQUFLLENBQUEsTUFBQSxDQUFPLEdBQUksQ0FBQSxLQUFBLENBQU0sU0FBUyxDQUFBO0FBQ25ELE1BQUssSUFBQSxDQUFBLE1BQUEsQ0FBTyxXQUFZLENBQUEsSUFBQSxDQUFLLFdBQVcsS0FBTSxDQUFBLGdCQUFBLEVBQWtCLENBQW9CLGtCQUFBLENBQUEsQ0FBQTtBQUFBO0FBR3hGLElBQUEsTUFBTSxNQUFNLE1BQU8sRUFBQTtBQUNuQixJQUFLLElBQUEsQ0FBQSxNQUFBLENBQU8sV0FBWSxDQUFBLE9BQUEsQ0FBUSxTQUFTLEtBQU0sQ0FBQSxnQkFBQSxFQUFrQixDQUF1QixxQkFBQSxDQUFBLENBQUE7QUFFeEYsSUFBTyxPQUFBLEtBQUE7QUFBQTtBQUNYO0FBQUE7QUFBQTtBQUFBLEVBS0EsTUFBYSxZQUFZLFVBQW1DLEVBQUE7QUFDeEQsSUFBQSxJQUFJLENBQUMsSUFBQSxDQUFLLGFBQWMsQ0FBQSxVQUFVLENBQUcsRUFBQTtBQUNqQyxNQUFBLElBQUEsQ0FBSyxPQUFPLFNBQVUsRUFBQSxDQUFFLEtBQU0sQ0FBQSxDQUFBLDZDQUFBLEVBQWdELFVBQVUsQ0FBRSxDQUFBLENBQUE7QUFDMUYsTUFBQTtBQUFBO0FBR0osSUFBTSxNQUFBLEtBQUEsR0FBUSxJQUFLLENBQUEsY0FBQSxDQUFlLFVBQVUsQ0FBQTtBQUM1QyxJQUFBLElBQUksQ0FBQyxLQUFPLEVBQUE7QUFDUixNQUFBLElBQUEsQ0FBSyxPQUFPLFNBQVUsRUFBQSxDQUFFLEtBQU0sQ0FBQSxDQUFBLG9CQUFBLEVBQXVCLFVBQVUsQ0FBRSxDQUFBLENBQUE7QUFDakUsTUFBQTtBQUFBO0FBR0osSUFBQSxNQUFNLE1BQU0sT0FBUSxFQUFBO0FBQ3BCLElBQUEsSUFBQSxDQUFLLE1BQU8sQ0FBQSxNQUFBLENBQU8sS0FBTSxDQUFBLE9BQUEsRUFBUyxDQUFBO0FBQ2xDLElBQUssSUFBQSxDQUFBLE1BQUEsQ0FBTyxXQUFZLENBQUEsT0FBQSxDQUFRLCtCQUErQixLQUFNLENBQUEsZ0JBQUEsRUFBa0IsQ0FBRyxDQUFBLENBQUEsQ0FBQTtBQUFBO0FBQzlGO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFNTyxjQUFjLFVBQTZCLEVBQUE7QUFDOUMsSUFBQSxNQUFNLFFBQVEsS0FBTSxDQUFBLElBQUEsQ0FBSyxLQUFLLE1BQU8sQ0FBQSxNQUFBLEVBQVEsQ0FBRSxDQUFBLElBQUE7QUFBQSxNQUMzQyxDQUFDQyxXQUFVQSxNQUFNLENBQUEsT0FBQSxHQUFVLFdBQVksRUFBQSxLQUFNLFdBQVcsV0FBWTtBQUFBLEtBQ3hFO0FBRUEsSUFBQSxJQUFJLE9BQWMsT0FBQSxJQUFBO0FBQ2xCLElBQU8sT0FBQSxLQUFBO0FBQUE7QUFDWDtBQUFBO0FBQUE7QUFBQSxFQUtPLGVBQWUsVUFBa0MsRUFBQTtBQUNwRCxJQUFBLE9BQU8sSUFBSyxDQUFBLFNBQUEsRUFBWSxDQUFBLElBQUEsQ0FBSyxDQUFDLEtBQVUsS0FBQSxLQUFBLENBQU0sT0FBUSxFQUFBLENBQUUsV0FBWSxFQUFBLEtBQU0sVUFBVyxDQUFBLFdBQUEsRUFBYSxDQUFLLElBQUEsSUFBQTtBQUFBO0FBQzNHO0FBQUE7QUFBQTtBQUFBLEVBS08sU0FBcUIsR0FBQTtBQUN4QixJQUFBLE9BQU8sS0FBTSxDQUFBLElBQUEsQ0FBSyxJQUFLLENBQUEsTUFBQSxDQUFPLFFBQVEsQ0FBQTtBQUFBO0FBQzFDLEVBRU8sZUFBa0IsR0FBQTtBQUNyQixJQUFBLE9BQU8sSUFBSyxDQUFBLFlBQUEsSUFBZ0IsSUFBSyxDQUFBLFNBQUEsR0FBWSxDQUFDLENBQUE7QUFBQTtBQUNsRCxFQUVPLG1CQUF3QyxHQUFBO0FBQzNDLElBQUEsT0FBTyxJQUFLLENBQUEsVUFBQTtBQUFBO0FBRXBCOzs7OyJ9