@jsprismarine/prismarine
Version:
Dedicated Minecraft Bedrock Edition server written in TypeScript
172 lines (169 loc) • 20.3 kB
JavaScript
import { withCwd } from '../utils/cwd.es.js';
import '@jsprismarine/nbt';
import '@jsprismarine/bedrock-data';
import '@jsprismarine/jsbinaryutils';
import 'zlib';
import '@jsprismarine/math';
import { GeneratorManager } from './GeneratorManager.es.js';
import { World } from './World.es.js';
import Anvil from './providers/anvil/Anvil.es.js';
import Filesystem from './providers/filesystem/Filesystem.es.js';
import fs from 'node: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 GeneratorManager(server);
if (!fs.existsSync(withCwd(WORLDS_FOLDER))) {
fs.mkdirSync(withCwd(WORLDS_FOLDER), { recursive: true });
}
}
/**
* On enable hook, enables the manager and load all worlds.
* @group Lifecycle
*/
async enable() {
this.addProvider("Anvil", Anvil);
this.addProvider("Filesystem", Filesystem);
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 = 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({
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;
}
}
export { WorldManager as default };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV29ybGRNYW5hZ2VyLmVzLmpzIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd29ybGQvV29ybGRNYW5hZ2VyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgU2VydmVyLCBTZXJ2aWNlIH0gZnJvbSAnLi4vJztcbmltcG9ydCB7IHdpdGhDd2QgfSBmcm9tICcuLi91dGlscy9jd2QnO1xuaW1wb3J0IHsgR2VuZXJhdG9yTWFuYWdlciB9IGZyb20gJy4vJztcbmltcG9ydCB7IFdvcmxkIH0gZnJvbSAnLi9Xb3JsZCc7XG5pbXBvcnQgdHlwZSBQcm92aWRlciBmcm9tICcuL3Byb3ZpZGVycy9Qcm92aWRlcic7XG5cbmltcG9ydCBBbnZpbCBmcm9tICcuL3Byb3ZpZGVycy9hbnZpbC9BbnZpbCc7XG5pbXBvcnQgRmlsZXN5c3RlbSBmcm9tICcuL3Byb3ZpZGVycy9maWxlc3lzdGVtL0ZpbGVzeXN0ZW0nO1xuXG5pbXBvcnQgZnMgZnJvbSAnbm9kZTpmcyc7XG5cbi8qKlxuICogU3RhbmRhcmQgd29ybGQgZGF0YS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBXb3JsZERhdGEge1xuICAgIHNlZWQ6IG51bWJlcjtcbiAgICBwcm92aWRlcj86IHN0cmluZztcbiAgICBnZW5lcmF0b3I/OiBzdHJpbmc7XG59XG5cbmNvbnN0IFdPUkxEU19GT0xERVIgPSAnd29ybGRzJztcbmNvbnN0IERFRkFVTFRfV09STERfUFJPVklERVIgPSAnRmlsZXN5c3RlbSc7XG5cbi8qKlxuICogVGhlIHdvcmxkIG1hbmFnZXIgaXMgcmVzcG9uc2libGUgbGV2ZWwgbG9hZGluZywgdW5sb2FkaW5nLCBhbmQgZ2VuZXJhbCBsZXZlbCBtYW5hZ2VtZW50LlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBXb3JsZE1hbmFnZXIgaW1wbGVtZW50cyBTZXJ2aWNlIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHdvcmxkczogTWFwPHN0cmluZywgV29ybGQ+ID0gbmV3IE1hcCgpIGFzIE1hcDxzdHJpbmcsIFdvcmxkPjtcbiAgICBwcml2YXRlIGRlZmF1bHRXb3JsZDogV29ybGQgfCB1bmRlZmluZWQ7XG4gICAgcHJpdmF0ZSByZWFkb25seSBnZW5NYW5hZ2VyOiBHZW5lcmF0b3JNYW5hZ2VyO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgc2VydmVyOiBTZXJ2ZXI7XG4gICAgcHJpdmF0ZSBwcm92aWRlcnM6IE1hcDxzdHJpbmcsIGFueT4gPSBuZXcgTWFwKCkgYXMgTWFwPHN0cmluZywgYW55PjsgLy8gVE9ETzogdGhpcyBzaG91bGQgYmUgYSBtYW5hZ2VyXG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3Ioc2VydmVyOiBTZXJ2ZXIpIHtcbiAgICAgICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7XG4gICAgICAgIHRoaXMuZ2VuTWFuYWdlciA9IG5ldyBHZW5lcmF0b3JNYW5hZ2VyKHNlcnZlcik7XG5cbiAgICAgICAgLy8gQ3JlYXRlIHRoZSB3b3JsZHMgZGlyZWN0b3J5IGlmIGl0IGRvZXNuJ3QgZXhpc3QuXG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyh3aXRoQ3dkKFdPUkxEU19GT0xERVIpKSkge1xuICAgICAgICAgICAgZnMubWtkaXJTeW5jKHdpdGhDd2QoV09STERTX0ZPTERFUiksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT24gZW5hYmxlIGhvb2ssIGVuYWJsZXMgdGhlIG1hbmFnZXIgYW5kIGxvYWQgYWxsIHdvcmxkcy5cbiAgICAgKiBAZ3JvdXAgTGlmZWN5Y2xlXG4gICAgICovXG4gICAgcHVibGljIGFzeW5jIGVuYWJsZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5hZGRQcm92aWRlcignQW52aWwnLCBBbnZpbCk7XG4gICAgICAgIHRoaXMuYWRkUHJvdmlkZXIoJ0ZpbGVzeXN0ZW0nLCBGaWxlc3lzdGVtKTtcblxuICAgICAgICBjb25zdCBkZWZhdWx0V29ybGQgPSB0aGlzLnNlcnZlci5nZXRDb25maWcoKS5nZXRMZXZlbE5hbWUoKTtcbiAgICAgICAgaWYgKCFkZWZhdWx0V29ybGQpIHtcbiAgICAgICAgICAgIHRoaXMuc2VydmVyLmdldExvZ2dlcigpLndhcm4oYEludmFsaWQgd29ybGQhYCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB3b3JsZERhdGEgPSB0aGlzLnNlcnZlci5nZXRDb25maWcoKS5nZXRXb3JsZHMoKVtkZWZhdWx0V29ybGRdO1xuICAgICAgICBpZiAoIXdvcmxkRGF0YSkgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGxldmVsLW5hbWVgKTtcblxuICAgICAgICBhd2FpdCB0aGlzLmxvYWRXb3JsZCh3b3JsZERhdGEsIGRlZmF1bHRXb3JsZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT24gZGlzYWJsZSBob29rLlxuICAgICAqXG4gICAgICogU2lnbmlmaWVzIHRoYXQgdGhlIG1hbmFnZXIgaXMgYmVpbmcgZGlzYWJsZWQgYW5kIGFsbCB3b3JsZHMgc2hvdWxkIGJlIHVubG9hZGVkLlxuICAgICAqIEBncm91cCBMaWZlY3ljbGVcbiAgICAgKi9cbiAgICBwdWJsaWMgYXN5bmMgZGlzYWJsZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwodGhpcy5nZXRXb3JsZHMoKS5tYXAoYXN5bmMgKHdvcmxkKSA9PiB0aGlzLnVubG9hZFdvcmxkKHdvcmxkLmdldE5hbWUoKSkpKTtcbiAgICAgICAgdGhpcy5wcm92aWRlcnMuY2xlYXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBwcm92aWRlciB0byB0aGUgaW50ZXJuYWwgcHJvdmlkZXJzIG1hcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBuYW1lIC0gdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIENBU0UgU0VOU0lUSVZFXG4gICAgICogQHBhcmFtIHByb3ZpZGVyIC0gdGhlIHByb3ZpZGVyXG4gICAgICovXG4gICAgcHVibGljIGFkZFByb3ZpZGVyKG5hbWU6IHN0cmluZywgcHJvdmlkZXI6IGFueSkge1xuICAgICAgICB0aGlzLnByb3ZpZGVycy5zZXQobmFtZSwgcHJvdmlkZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhIHByb3ZpZGVyIGZyb20gdGhlIGludGVybmFsIHByb3ZpZGVycyBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbmFtZSAtIHRoZSBuYW1lIG9mIHRoZSBwcm92aWRlciBDQVNFIFNFTlNJVElWRVxuICAgICAqL1xuICAgIHB1YmxpYyByZW1vdmVQcm92aWRlcihuYW1lOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5wcm92aWRlcnMuZGVsZXRlKG5hbWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgcHJvdmlkZXJzLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRQcm92aWRlcnMoKTogTWFwPHN0cmluZywgUHJvdmlkZXI+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvdmlkZXJzIGFzIE1hcDxzdHJpbmcsIFByb3ZpZGVyPjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTYXZlIHRoZSB3b3JsZCB0byBkaXNrLlxuICAgICAqL1xuICAgIHB1YmxpYyBhc3luYyBzYXZlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnNlcnZlci5nZXRMb2dnZXIoKS5pbmZvKCdTYXZpbmcgd29ybGRzJyk7XG4gICAgICAgIGZvciAoY29uc3Qgd29ybGQgb2YgdGhpcy5nZXRXb3JsZHMoKSkge1xuICAgICAgICAgICAgYXdhaXQgd29ybGQuc2F2ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTG9hZCBhIHdvcmxkXG4gICAgICpcbiAgICAgKiBAcGFyYW0gd29ybGREYXRhIC0gdGhlIHdvcmxkIGRhdGEgaW5jbHVkaW5nIHByb3ZpZGVyIGtleSwgZ2VuZXJhdG9yXG4gICAgICogQHBhcmFtIGZvbGRlck5hbWUgLSB0aGUgbmFtZSBvZiB0aGUgZm9sZGVyIGNvbnRhaW5pbmcgdGhlIHdvcmxkXG4gICAgICovXG4gICAgcHVibGljIGFzeW5jIGxvYWRXb3JsZCh3b3JsZERhdGE6IFdvcmxkRGF0YSwgZm9sZGVyTmFtZTogc3RyaW5nKTogUHJvbWlzZTxXb3JsZD4ge1xuICAgICAgICBpZiAoISh3b3JsZERhdGEgYXMgYW55KSkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHdvcmxkIGRhdGEnKTtcblxuICAgICAgICBpZiAodGhpcy5pc1dvcmxkTG9hZGVkKGZvbGRlck5hbWUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFdvcmxkICR7Zm9sZGVyTmFtZX0gaGFzIGFscmVhZHkgYmVlbiBsb2FkZWRgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxldmVsUGF0aCA9IHdpdGhDd2QoV09STERTX0ZPTERFUiwgZm9sZGVyTmFtZSk7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5wcm92aWRlcnMuZ2V0KHdvcmxkRGF0YS5wcm92aWRlciA/PyBERUZBVUxUX1dPUkxEX1BST1ZJREVSKTtcbiAgICAgICAgY29uc3QgZ2VuZXJhdG9yID0gdGhpcy5nZXRHZW5lcmF0b3JNYW5hZ2VyKCkuZ2V0R2VuZXJhdG9yKHdvcmxkRGF0YS5nZW5lcmF0b3IgPz8gJ0ZsYXQnKTtcblxuICAgICAgICBpZiAoIXByb3ZpZGVyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgcHJvdmlkZXIgd2l0aCBpZCAke3dvcmxkRGF0YS5wcm92aWRlcn1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHdvcmxkID0gbmV3IFdvcmxkKHtcbiAgICAgICAgICAgIG5hbWU6IGZvbGRlck5hbWUsXG4gICAgICAgICAgICBwYXRoOiBsZXZlbFBhdGgsXG4gICAgICAgICAgICBzZXJ2ZXI6IHRoaXMuc2VydmVyLFxuICAgICAgICAgICAgcHJvdmlkZXI6IG5ldyBwcm92aWRlcihsZXZlbFBhdGgsIHRoaXMuc2VydmVyKSxcblxuICAgICAgICAgICAgc2VlZDogd29ybGREYXRhLnNlZWQsXG4gICAgICAgICAgICBnZW5lcmF0b3IsXG4gICAgICAgICAgICBjb25maWc6IHdvcmxkRGF0YVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy53b3JsZHMuc2V0KHdvcmxkLmdldFVVSUQoKSwgd29ybGQpO1xuXG4gICAgICAgIC8vIEZpcnN0IGxldmVsIHRvIGJlIGxvYWRlZCBpcyBhbHNvIHRoZSBkZWZhdWx0IG9uZVxuICAgICAgICBpZiAoIXRoaXMuZGVmYXVsdFdvcmxkKSB7XG4gICAgICAgICAgICB0aGlzLmRlZmF1bHRXb3JsZCA9IHRoaXMud29ybGRzLmdldCh3b3JsZC5nZXRVVUlEKCkpITtcbiAgICAgICAgICAgIHRoaXMuc2VydmVyLmdldExvZ2dlcigpLmluZm8oYExvYWRpbmcgJHt3b3JsZC5nZXRGb3JtYXR0ZWROYW1lKCl9IGFzIGRlZmF1bHQgd29ybGQhYCk7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB3b3JsZC5lbmFibGUoKTtcbiAgICAgICAgdGhpcy5zZXJ2ZXIuZ2V0TG9nZ2VyKCkudmVyYm9zZShgV29ybGQgJHt3b3JsZC5nZXRGb3JtYXR0ZWROYW1lKCl9IHN1Y2Nlc3NmdWxseSBsb2FkZWQhYCk7XG5cbiAgICAgICAgcmV0dXJuIHdvcmxkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVubG9hZHMgYSBsZXZlbCBieSBpdHMgZm9sZGVyIG5hbWUuXG4gICAgICovXG4gICAgcHVibGljIGFzeW5jIHVubG9hZFdvcmxkKGZvbGRlck5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoIXRoaXMuaXNXb3JsZExvYWRlZChmb2xkZXJOYW1lKSkge1xuICAgICAgICAgICAgdGhpcy5zZXJ2ZXIuZ2V0TG9nZ2VyKCkuZXJyb3IoYENhbm5vdCB1bmxvYWQgYSBub3QgbG9hZGVkIHdvcmxkIHdpdGggbmFtZSDCp2Ike2ZvbGRlck5hbWV9YCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB3b3JsZCA9IHRoaXMuZ2V0V29ybGRCeU5hbWUoZm9sZGVyTmFtZSk7XG4gICAgICAgIGlmICghd29ybGQpIHtcbiAgICAgICAgICAgIHRoaXMuc2VydmVyLmdldExvZ2dlcigpLmVycm9yKGBDYW5ub3QgdW5sb2FkIHdvcmxkICR7Zm9sZGVyTmFtZX1gKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IHdvcmxkLmRpc2FibGUoKTtcbiAgICAgICAgdGhpcy53b3JsZHMuZGVsZXRlKHdvcmxkLmdldFVVSUQoKSk7XG4gICAgICAgIHRoaXMuc2VydmVyLmdldExvZ2dlcigpLnZlcmJvc2UoYFN1Y2Nlc3NmdWxseSB1bmxvYWRlZCB3b3JsZCAke3dvcmxkLmdldEZvcm1hdHRlZE5hbWUoKX0hYCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB3aGF0ZXZlciB0aGUgd29ybGQgaXMgbG9hZGVkIG9yIG5vdC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgd29ybGQgaXMgbG9hZGVkLCBmYWxzZSBvdGhlcndpc2VcbiAgICAgKi9cbiAgICBwdWJsaWMgaXNXb3JsZExvYWRlZChmb2xkZXJOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3Qgd29ybGQgPSBBcnJheS5mcm9tKHRoaXMud29ybGRzLnZhbHVlcygpKS5maW5kKFxuICAgICAgICAgICAgKHdvcmxkKSA9PiB3b3JsZC5nZXROYW1lKCkudG9Mb3dlckNhc2UoKSA9PT0gZm9sZGVyTmFtZS50b0xvd2VyQ2FzZSgpXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHdvcmxkKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSB3b3JsZCBieSBpdHMgZm9sZGVyIG5hbWUuXG4gICAgICovXG4gICAgcHVibGljIGdldFdvcmxkQnlOYW1lKGZvbGRlck5hbWU6IHN0cmluZyk6IFdvcmxkIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFdvcmxkcygpLmZpbmQoKHdvcmxkKSA9PiB3b3JsZC5nZXROYW1lKCkudG9Mb3dlckNhc2UoKSA9PT0gZm9sZGVyTmFtZS50b0xvd2VyQ2FzZSgpKSA/PyBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYW4gYXJyYXkgd2l0aCBhbGwgd29ybGRzLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRXb3JsZHMoKTogV29ybGRbXSB7XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMud29ybGRzLnZhbHVlcygpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0RGVmYXVsdFdvcmxkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kZWZhdWx0V29ybGQgPz8gdGhpcy5nZXRXb3JsZHMoKVswXTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0R2VuZXJhdG9yTWFuYWdlcigpOiBHZW5lcmF0b3JNYW5hZ2VyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2VuTWFuYWdlcjtcbiAgICB9XG59XG4iXSwibmFtZXMiOlsid29ybGQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQW9CQSxNQUFNLGFBQWdCLEdBQUEsUUFBQTtBQUN0QixNQUFNLHNCQUF5QixHQUFBLFlBQUE7QUFLL0IsTUFBcUIsWUFBZ0MsQ0FBQTtBQUFBLEVBQ2hDLE1BQUEsdUJBQWlDLEdBQUksRUFBQTtBQUFBLEVBQzlDLFlBQUE7QUFBQSxFQUNTLFVBQUE7QUFBQSxFQUNBLE1BQUE7QUFBQSxFQUNULFNBQUEsdUJBQWtDLEdBQUksRUFBQTtBQUFBO0FBQUEsRUFFdkMsWUFBWSxNQUFnQixFQUFBO0FBQy9CLElBQUEsSUFBQSxDQUFLLE1BQVMsR0FBQSxNQUFBO0FBQ2QsSUFBSyxJQUFBLENBQUEsVUFBQSxHQUFhLElBQUksZ0JBQUEsQ0FBaUIsTUFBTSxDQUFBO0FB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