@jsprismarine/logger
Version:
JSPrismarine logger and utilities
168 lines (167 loc) • 17.6 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_runtime = require("./_virtual/_rolldown/runtime.cjs.cjs");
const require_transport = require("./transport.cjs.cjs");
let _jsprismarine_color_parser = require("@jsprismarine/color-parser");
_jsprismarine_color_parser = require_runtime.__toESM(_jsprismarine_color_parser, 1);
let winston = require("winston");
winston = require_runtime.__toESM(winston, 1);
//#region src/logger.ts
/**
* Helper class for general logging.
* @document ../../../docs/log-levels.md
* @class
* @public
*/
var Logger = class {
/**
* The internal logger instance.
* @type {Winston}
* @private
* @internal
*/
logger = null;
/**
* Create a new logger instance
* @param {LogLevel} level - The log level to use.
* @param {TransportStream[]} transports - The transports to use.
* @returns {Logger} The logger instance.
*/
constructor(level = "info", transports = []) {
this.createLogger(level, transports);
}
/**
* Create a new logger instance
*
* @returns {void}
*/
createLogger(level = "info", transports = []) {
if (this.logger && !this.logger.closed) return;
this.logger = winston.createLogger({
level,
format: winston.format.combine(winston.format.timestamp({ format: "HH:mm:ss" }), (0, winston.format)((info) => {
info.level = info.level.toUpperCase();
return info;
})(), winston.format.colorize(), winston.format.simple()),
transports: [new require_transport.PrismarineTransport({ format: winston.format.printf(({ level, message, timestamp, namespace: ns }) => {
return (0, _jsprismarine_color_parser.default)(`[${`${timestamp} ${level}${ns ? ` ${ns}` : ""}`}§r]: ${message}§r`);
}) }), ...transports]
});
}
/**
* On enable hook.
* @group Lifecycle
*/
async enable() {
this.createLogger();
}
/**
* On disable hook.
* @group Lifecycle
*/
async disable() {
this.logger.close();
this.logger = null;
}
/**
* Listen for log messages.
* @param {(level: LogLevel, message: string) => void} listener - The listener to call when a log message is received.
* @event
*/
onLine(listener) {
this.logger.on("data", (data) => listener(data.message.toString()));
}
/**
* Set the console instance to use.
* @param {ConsoleLike} console - The console instance to use.
*/
setConsole(console) {
if (!console) return;
this.logger.transports[0].console = console;
}
/**
* Get callee's namespace from the stack trace.
* @private
* @internal
*/
getNamespace = () => {
const stack = (/* @__PURE__ */ new Error()).stack.replaceAll("\\", "/");
if (!stack) return "";
const caller = (stack.split("\n")[3] || "").trim();
if (!caller) return "";
const file = caller.match(/\(([^)]+)\)/)?.[1]?.split("src/")[1] || "";
if (!file) return "";
const path = file.split(":").slice(0, -2).join(":").slice(0, -3);
if (!path) return "";
const lineCol = file.split(":").slice(-2).join(":");
if (!lineCol) return "";
if (this.logger.level === "silly" || this.logger.level === "debug" || this.logger.level === "verbose") return `${path}.ts:${lineCol}`;
return path.split("/").at(-1) || "";
};
/**
* @private
* @internal
*/
parseMessage = (input) => {
const output = input.join("§r ");
if ([
".",
"!",
"?"
].includes(output.charAt(-1))) return `${output}.`;
return output;
};
/**
* Log information messages.
* @param {...string} message - The message to log.
*/
info = (...message) => {
this.logger.log("info", this.parseMessage(message), { namespace: this.getNamespace() });
};
/**
* Log warning messages.
* @param {...string} message - The message to log.
*/
warn = (...message) => {
this.logger.log("warn", this.parseMessage(message), { namespace: this.getNamespace() });
};
/**
* Log error messages.
* @param {string | Error | any} message - The message to log.
*/
error = (message) => {
if (typeof message === "string") {
this.logger.log("error", message, { namespace: this.getNamespace() });
return;
}
if (message.stack) {
this.logger.error(`${message.stack.split("\n")[0] !== message.toString() ? `${message.toString()}\n` : ""}${message.stack}`);
return;
}
this.logger.error(message.toString());
};
/**
* Log verbose messages.
* @param {...string} message - The message to log.
*/
verbose = (...message) => {
this.logger.log("verbose", this.parseMessage(message), { namespace: this.getNamespace() });
};
/**
* Log debug messages.
* @param {...string} message - The message to log.
*/
debug = (...message) => {
this.logger.log("debug", this.parseMessage(message), { namespace: this.getNamespace() });
};
/**
* Log silly messages.
* @param {...string} message - The message to log.
*/
silly = (...message) => {
this.logger.log("silly", this.parseMessage(message), { namespace: this.getNamespace() });
};
};
//#endregion
exports.Logger = Logger;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmNqcy5janMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vc3JjL2xvZ2dlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY29sb3JQYXJzZXIgZnJvbSAnQGpzcHJpc21hcmluZS9jb2xvci1wYXJzZXInO1xuXG5pbXBvcnQgdHlwZSB7IExvZ2dlciBhcyBXaW5zdG9uIH0gZnJvbSAnd2luc3Rvbic7XG5pbXBvcnQgKiBhcyB3aW5zdG9uIGZyb20gJ3dpbnN0b24nO1xuaW1wb3J0IHsgZm9ybWF0IH0gZnJvbSAnd2luc3Rvbic7XG5cbmltcG9ydCB0eXBlIFRyYW5zcG9ydFN0cmVhbSBmcm9tICd3aW5zdG9uLXRyYW5zcG9ydCc7XG5pbXBvcnQgdHlwZSB7IENvbnNvbGVMaWtlIH0gZnJvbSAnLi90cmFuc3BvcnQnO1xuaW1wb3J0IHsgUHJpc21hcmluZVRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0JztcblxuLyoqXG4gKiBBIGxvZyBsZXZlbC5cbiAqIEB0eXBlIHtMb2dMZXZlbH1cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgTG9nTGV2ZWwgPSAnZXJyb3InIHwgJ3dhcm4nIHwgJ2luZm8nIHwgJ3ZlcmJvc2UnIHwgJ2RlYnVnJyB8ICdzaWxseSc7XG5cbi8qKlxuICogSGVscGVyIGNsYXNzIGZvciBnZW5lcmFsIGxvZ2dpbmcuXG4gKiBAZG9jdW1lbnQgLi4vLi4vLi4vZG9jcy9sb2ctbGV2ZWxzLm1kXG4gKiBAY2xhc3NcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNsYXNzIExvZ2dlciB7XG4gICAgLyoqXG4gICAgICogVGhlIGludGVybmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICAgKiBAdHlwZSB7V2luc3Rvbn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHByaXZhdGUgbG9nZ2VyOiBXaW5zdG9uIHwgbnVsbCA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgbG9nZ2VyIGluc3RhbmNlXG4gICAgICogQHBhcmFtIHtMb2dMZXZlbH0gbGV2ZWwgLSBUaGUgbG9nIGxldmVsIHRvIHVzZS5cbiAgICAgKiBAcGFyYW0ge1RyYW5zcG9ydFN0cmVhbVtdfSB0cmFuc3BvcnRzIC0gVGhlIHRyYW5zcG9ydHMgdG8gdXNlLlxuICAgICAqIEByZXR1cm5zIHtMb2dnZXJ9IFRoZSBsb2dnZXIgaW5zdGFuY2UuXG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKGxldmVsOiBMb2dMZXZlbCA9ICdpbmZvJywgdHJhbnNwb3J0czogVHJhbnNwb3J0U3RyZWFtW10gPSBbXSkge1xuICAgICAgICB0aGlzLmNyZWF0ZUxvZ2dlcihsZXZlbCwgdHJhbnNwb3J0cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGxvZ2dlciBpbnN0YW5jZVxuICAgICAqXG4gICAgICogQHJldHVybnMge3ZvaWR9XG4gICAgICovXG4gICAgcHJvdGVjdGVkIGNyZWF0ZUxvZ2dlcihsZXZlbDogTG9nTGV2ZWwgPSAnaW5mbycsIHRyYW5zcG9ydHM6IFRyYW5zcG9ydFN0cmVhbVtdID0gW10pOiB2b2lkIHtcbiAgICAgICAgLy8gSWYgdGhlIGxvZ2dlciBpcyBhbHJlYWR5IGNyZWF0ZWQgYW5kIG5vdCBjbG9zZWQsIHJldHVybi5cbiAgICAgICAgaWYgKCh0aGlzLmxvZ2dlciEgYXMgYW55KSAmJiAhdGhpcy5sb2dnZXIhLmNsb3NlZCkgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMubG9nZ2VyISA9IHdpbnN0b24uY3JlYXRlTG9nZ2VyKHtcbiAgICAgICAgICAgIGxldmVsLFxuICAgICAgICAgICAgZm9ybWF0OiBmb3JtYXQuY29tYmluZShcbiAgICAgICAgICAgICAgICBmb3JtYXQudGltZXN0YW1wKHsgZm9ybWF0OiAnSEg6bW06c3MnIH0pLFxuICAgICAgICAgICAgICAgIGZvcm1hdCgoaW5mbykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpbmZvLmxldmVsID0gaW5mby5sZXZlbC50b1VwcGVyQ2FzZSgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5mbztcbiAgICAgICAgICAgICAgICB9KSgpLFxuICAgICAgICAgICAgICAgIGZvcm1hdC5jb2xvcml6ZSgpLFxuICAgICAgICAgICAgICAgIGZvcm1hdC5zaW1wbGUoKVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIHRyYW5zcG9ydHM6IFtcbiAgICAgICAgICAgICAgICBuZXcgUHJpc21hcmluZVRyYW5zcG9ydCh7XG4gICAgICAgICAgICAgICAgICAgIGZvcm1hdDogZm9ybWF0LnByaW50ZigoeyBsZXZlbCwgbWVzc2FnZSwgdGltZXN0YW1wLCBuYW1lc3BhY2U6IG5zIH0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9IGAke3RpbWVzdGFtcH0gJHtsZXZlbH0ke25zID8gYCAke25zfWAgOiAnJ31gO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29sb3JQYXJzZXIoYFske3ByZWZpeH3Cp3JdOiAke21lc3NhZ2V9wqdyYCk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgLi4udHJhbnNwb3J0c1xuICAgICAgICAgICAgXVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPbiBlbmFibGUgaG9vay5cbiAgICAgKiBAZ3JvdXAgTGlmZWN5Y2xlXG4gICAgICovXG4gICAgcHVibGljIGFzeW5jIGVuYWJsZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5jcmVhdGVMb2dnZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPbiBkaXNhYmxlIGhvb2suXG4gICAgICogQGdyb3VwIExpZmVjeWNsZVxuICAgICAqL1xuICAgIHB1YmxpYyBhc3luYyBkaXNhYmxlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmxvZ2dlciEuY2xvc2UoKTtcbiAgICAgICAgdGhpcy5sb2dnZXIgPSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExpc3RlbiBmb3IgbG9nIG1lc3NhZ2VzLlxuICAgICAqIEBwYXJhbSB7KGxldmVsOiBMb2dMZXZlbCwgbWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkfSBsaXN0ZW5lciAtIFRoZSBsaXN0ZW5lciB0byBjYWxsIHdoZW4gYSBsb2cgbWVzc2FnZSBpcyByZWNlaXZlZC5cbiAgICAgKiBAZXZlbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgb25MaW5lKGxpc3RlbmVyOiAobGluZTogc3RyaW5nKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgICAgIHRoaXMubG9nZ2VyIS5vbignZGF0YScsIChkYXRhKSA9PiBsaXN0ZW5lcihkYXRhLm1lc3NhZ2UudG9TdHJpbmcoKSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgY29uc29sZSBpbnN0YW5jZSB0byB1c2UuXG4gICAgICogQHBhcmFtIHtDb25zb2xlTGlrZX0gY29uc29sZSAtIFRoZSBjb25zb2xlIGluc3RhbmNlIHRvIHVzZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0Q29uc29sZShjb25zb2xlPzogQ29uc29sZUxpa2UpOiB2b2lkIHtcbiAgICAgICAgaWYgKCFjb25zb2xlKSByZXR1cm47XG4gICAgICAgICh0aGlzLmxvZ2dlciEudHJhbnNwb3J0c1swXSBhcyBQcmlzbWFyaW5lVHJhbnNwb3J0KS5jb25zb2xlID0gY29uc29sZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgY2FsbGVlJ3MgbmFtZXNwYWNlIGZyb20gdGhlIHN0YWNrIHRyYWNlLlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHJpdmF0ZSBnZXROYW1lc3BhY2UgPSAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0YWNrID0gKG5ldyBFcnJvcigpLnN0YWNrIGFzIHN0cmluZykucmVwbGFjZUFsbCgnXFxcXCcsICcvJyk7XG4gICAgICAgIGlmICghc3RhY2spIHJldHVybiAnJztcblxuICAgICAgICBjb25zdCBjYWxsZXIgPSAoc3RhY2suc3BsaXQoJ1xcbicpWzNdIHx8ICcnKS50cmltKCk7XG4gICAgICAgIGlmICghY2FsbGVyKSByZXR1cm4gJyc7XG5cbiAgICAgICAgLy8gR2V0IHBhdGggaW5zaWRlIG9mIHRoZSBwYXJlbnRoZXNlcyBpbiB0aGUgY2FsbGVyIHN0cmluZywgZXhjbHVkaW5nIHRoZSBsaW5lOmNvbC5cbiAgICAgICAgY29uc3QgZmlsZSA9IGNhbGxlci5tYXRjaCgvXFwoKFteKV0rKVxcKS8pPy5bMV0/LnNwbGl0KCdzcmMvJylbMV0gfHwgJyc7XG4gICAgICAgIGlmICghZmlsZSkgcmV0dXJuICcnO1xuXG4gICAgICAgIC8vIEdldCBwYXRoIGFuZCBsaW5lOmNvbCBmcm9tIHRoZSBmaWxlIHN0cmluZywgdGhlbiByZW1vdmUgdGhlIGZpbGUgZXh0ZW5zaW9uLlxuICAgICAgICBjb25zdCBwYXRoID0gZmlsZS5zcGxpdCgnOicpLnNsaWNlKDAsIC0yKS5qb2luKCc6Jykuc2xpY2UoMCwgLTMpO1xuICAgICAgICBpZiAoIXBhdGgpIHJldHVybiAnJztcblxuICAgICAgICBjb25zdCBsaW5lQ29sID0gZmlsZS5zcGxpdCgnOicpLnNsaWNlKC0yKS5qb2luKCc6Jyk7XG4gICAgICAgIGlmICghbGluZUNvbCkgcmV0dXJuICcnO1xuXG4gICAgICAgIGlmICh0aGlzLmxvZ2dlciEubGV2ZWwgPT09ICdzaWxseScgfHwgdGhpcy5sb2dnZXIhLmxldmVsID09PSAnZGVidWcnIHx8IHRoaXMubG9nZ2VyIS5sZXZlbCA9PT0gJ3ZlcmJvc2UnKSB7XG4gICAgICAgICAgICByZXR1cm4gYCR7cGF0aH0udHM6JHtsaW5lQ29sfWA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGF0aC5zcGxpdCgnLycpLmF0KC0xKSB8fCAnJztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwcml2YXRlIHBhcnNlTWVzc2FnZSA9IChpbnB1dDogc3RyaW5nW10pID0+IHtcbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gaW5wdXQuam9pbignwqdyICcpO1xuXG4gICAgICAgIC8vIE1ha2Ugc3VyZSBsb2cgbWVzc2FnZXMgZW5kIHdpdGggYSBwZXJpb2QuXG4gICAgICAgIGlmIChbJy4nLCAnIScsICc/J10uaW5jbHVkZXMob3V0cHV0LmNoYXJBdCgtMSkpKSB7XG4gICAgICAgICAgICByZXR1cm4gYCR7b3V0cHV0fS5gO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogTG9nIGluZm9ybWF0aW9uIG1lc3NhZ2VzLlxuICAgICAqIEBwYXJhbSB7Li4uc3RyaW5nfSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gbG9nLlxuICAgICAqL1xuICAgIHB1YmxpYyBpbmZvID0gKC4uLm1lc3NhZ2U6IHN0cmluZ1tdKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMubG9nZ2VyIS5sb2coJ2luZm8nLCB0aGlzLnBhcnNlTWVzc2FnZShtZXNzYWdlKSwge1xuICAgICAgICAgICAgbmFtZXNwYWNlOiB0aGlzLmdldE5hbWVzcGFjZSgpXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBMb2cgd2FybmluZyBtZXNzYWdlcy5cbiAgICAgKiBAcGFyYW0gey4uLnN0cmluZ30gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgd2FybiA9ICguLi5tZXNzYWdlOiBzdHJpbmdbXSk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLmxvZ2dlciEubG9nKCd3YXJuJywgdGhpcy5wYXJzZU1lc3NhZ2UobWVzc2FnZSksIHtcbiAgICAgICAgICAgIG5hbWVzcGFjZTogdGhpcy5nZXROYW1lc3BhY2UoKVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogTG9nIGVycm9yIG1lc3NhZ2VzLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nIHwgRXJyb3IgfCBhbnl9IG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0byBsb2cuXG4gICAgICovXG4gICAgcHVibGljIGVycm9yID0gKG1lc3NhZ2U6IHN0cmluZyB8IEVycm9yIHwgYW55KTogdm9pZCA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyIS5sb2coJ2Vycm9yJywgbWVzc2FnZSwge1xuICAgICAgICAgICAgICAgIG5hbWVzcGFjZTogdGhpcy5nZXROYW1lc3BhY2UoKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWVzc2FnZS5zdGFjaykge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIhLmVycm9yKFxuICAgICAgICAgICAgICAgIGAke21lc3NhZ2Uuc3RhY2suc3BsaXQoJ1xcbicpWzBdICE9PSBtZXNzYWdlLnRvU3RyaW5nKCkgPyBgJHttZXNzYWdlLnRvU3RyaW5nKCl9XFxuYCA6ICcnfSR7bWVzc2FnZS5zdGFja31gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5sb2dnZXIhLmVycm9yKG1lc3NhZ2UudG9TdHJpbmcoKSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIExvZyB2ZXJib3NlIG1lc3NhZ2VzLlxuICAgICAqIEBwYXJhbSB7Li4uc3RyaW5nfSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gbG9nLlxuICAgICAqL1xuICAgIHB1YmxpYyB2ZXJib3NlID0gKC4uLm1lc3NhZ2U6IHN0cmluZ1tdKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMubG9nZ2VyIS5sb2coJ3ZlcmJvc2UnLCB0aGlzLnBhcnNlTWVzc2FnZShtZXNzYWdlKSwge1xuICAgICAgICAgICAgbmFtZXNwYWNlOiB0aGlzLmdldE5hbWVzcGFjZSgpXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBMb2cgZGVidWcgbWVzc2FnZXMuXG4gICAgICogQHBhcmFtIHsuLi5zdHJpbmd9IG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0byBsb2cuXG4gICAgICovXG4gICAgcHVibGljIGRlYnVnID0gKC4uLm1lc3NhZ2U6IHN0cmluZ1tdKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMubG9nZ2VyIS5sb2coJ2RlYnVnJywgdGhpcy5wYXJzZU1lc3NhZ2UobWVzc2FnZSksIHtcbiAgICAgICAgICAgIG5hbWVzcGFjZTogdGhpcy5nZXROYW1lc3BhY2UoKVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogTG9nIHNpbGx5IG1lc3NhZ2VzLlxuICAgICAqIEBwYXJhbSB7Li4uc3RyaW5nfSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gbG9nLlxuICAgICAqL1xuICAgIHB1YmxpYyBzaWxseSA9ICguLi5tZXNzYWdlOiBzdHJpbmdbXSk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLmxvZ2dlciEubG9nKCdzaWxseScsIHRoaXMucGFyc2VNZXNzYWdlKG1lc3NhZ2UpLCB7XG4gICAgICAgICAgICBuYW1lc3BhY2U6IHRoaXMuZ2V0TmFtZXNwYWNlKClcbiAgICAgICAgfSk7XG4gICAgfTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBdUJBLElBQWEsU0FBYixNQUFvQjs7Ozs7OztDQU9oQixTQUFpQzs7Ozs7OztDQVFqQyxZQUFtQixRQUFrQixRQUFRLGFBQWdDLENBQUMsR0FBRztFQUM3RSxLQUFLLGFBQWEsT0FBTyxVQUFVO0NBQ3ZDOzs7Ozs7Q0FPQSxhQUF1QixRQUFrQixRQUFRLGFBQWdDLENBQUMsR0FBUztFQUV2RixJQUFLLEtBQUssVUFBbUIsQ0FBQyxLQUFLLE9BQVEsUUFBUTtFQUVuRCxLQUFLLFNBQVUsUUFBUSxh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