@jsprismarine/logger
Version:
JSPrismarine logger and utilities
184 lines (181 loc) • 20.3 kB
JavaScript
import colorParser from '@jsprismarine/color-parser';
import * as winston from 'winston';
import { format } from 'winston';
import { PrismarineTransport } from './transport.es.js';
class Logger {
/**
* 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: format.combine(
format.timestamp({ format: "HH:mm:ss" }),
format((info) => {
info.level = info.level.toUpperCase();
return info;
})(),
format.colorize(),
format.simple()
),
transports: [
new PrismarineTransport({
format: format.printf(({ level: level2, message, timestamp, namespace: ns }) => {
const prefix = `${timestamp} ${level2}${ns ? ` ${ns}` : ""}`;
return colorParser(`[${prefix}§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 = 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()}
` : ""}${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()
});
};
}
export { Logger };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmVzLmpzIiwic291cmNlcyI6WyIuLi9zcmMvbG9nZ2VyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjb2xvclBhcnNlciBmcm9tICdAanNwcmlzbWFyaW5lL2NvbG9yLXBhcnNlcic7XG5cbmltcG9ydCB0eXBlIHsgTG9nZ2VyIGFzIFdpbnN0b24gfSBmcm9tICd3aW5zdG9uJztcbmltcG9ydCAqIGFzIHdpbnN0b24gZnJvbSAnd2luc3Rvbic7XG5pbXBvcnQgeyBmb3JtYXQgfSBmcm9tICd3aW5zdG9uJztcblxuaW1wb3J0IHR5cGUgVHJhbnNwb3J0U3RyZWFtIGZyb20gJ3dpbnN0b24tdHJhbnNwb3J0JztcbmltcG9ydCB0eXBlIHsgQ29uc29sZUxpa2UgfSBmcm9tICcuL3RyYW5zcG9ydCc7XG5pbXBvcnQgeyBQcmlzbWFyaW5lVHJhbnNwb3J0IH0gZnJvbSAnLi90cmFuc3BvcnQnO1xuXG4vKipcbiAqIEEgbG9nIGxldmVsLlxuICogQHR5cGUge0xvZ0xldmVsfVxuICogQHB1YmxpY1xuICovXG5leHBvcnQgdHlwZSBMb2dMZXZlbCA9ICdlcnJvcicgfCAnd2FybicgfCAnaW5mbycgfCAndmVyYm9zZScgfCAnZGVidWcnIHwgJ3NpbGx5JztcblxuLyoqXG4gKiBIZWxwZXIgY2xhc3MgZm9yIGdlbmVyYWwgbG9nZ2luZy5cbiAqIEBkb2N1bWVudCBkb2NzL2xvZy1sZXZlbHMubWRcbiAqIEBjbGFzc1xuICogQHB1YmxpY1xuICovXG5leHBvcnQgY2xhc3MgTG9nZ2VyIHtcbiAgICAvKipcbiAgICAgKiBUaGUgaW50ZXJuYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgICAqIEB0eXBlIHtXaW5zdG9ufVxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHJpdmF0ZSBsb2dnZXI6IFdpbnN0b24gfCBudWxsID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBsb2dnZXIgaW5zdGFuY2VcbiAgICAgKiBAcGFyYW0ge0xvZ0xldmVsfSBsZXZlbCAtIFRoZSBsb2cgbGV2ZWwgdG8gdXNlLlxuICAgICAqIEBwYXJhbSB7VHJhbnNwb3J0U3RyZWFtW119IHRyYW5zcG9ydHMgLSBUaGUgdHJhbnNwb3J0cyB0byB1c2UuXG4gICAgICogQHJldHVybnMge0xvZ2dlcn0gVGhlIGxvZ2dlciBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgY29uc3RydWN0b3IobGV2ZWw6IExvZ0xldmVsID0gJ2luZm8nLCB0cmFuc3BvcnRzOiBUcmFuc3BvcnRTdHJlYW1bXSA9IFtdKSB7XG4gICAgICAgIHRoaXMuY3JlYXRlTG9nZ2VyKGxldmVsLCB0cmFuc3BvcnRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgbG9nZ2VyIGluc3RhbmNlXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY3JlYXRlTG9nZ2VyKGxldmVsOiBMb2dMZXZlbCA9ICdpbmZvJywgdHJhbnNwb3J0czogVHJhbnNwb3J0U3RyZWFtW10gPSBbXSk6IHZvaWQge1xuICAgICAgICAvLyBJZiB0aGUgbG9nZ2VyIGlzIGFscmVhZHkgY3JlYXRlZCBhbmQgbm90IGNsb3NlZCwgcmV0dXJuLlxuICAgICAgICBpZiAoKHRoaXMubG9nZ2VyISBhcyBhbnkpICYmICF0aGlzLmxvZ2dlciEuY2xvc2VkKSByZXR1cm47XG5cbiAgICAgICAgdGhpcy5sb2dnZXIhID0gd2luc3Rvbi5jcmVhdGVMb2dnZXIoe1xuICAgICAgICAgICAgbGV2ZWwsXG4gICAgICAgICAgICBmb3JtYXQ6IGZvcm1hdC5jb21iaW5lKFxuICAgICAgICAgICAgICAgIGZvcm1hdC50aW1lc3RhbXAoeyBmb3JtYXQ6ICdISDptbTpzcycgfSksXG4gICAgICAgICAgICAgICAgZm9ybWF0KChpbmZvKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGluZm8ubGV2ZWwgPSBpbmZvLmxldmVsLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpbmZvO1xuICAgICAgICAgICAgICAgIH0pKCksXG4gICAgICAgICAgICAgICAgZm9ybWF0LmNvbG9yaXplKCksXG4gICAgICAgICAgICAgICAgZm9ybWF0LnNpbXBsZSgpXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgdHJhbnNwb3J0czogW1xuICAgICAgICAgICAgICAgIG5ldyBQcmlzbWFyaW5lVHJhbnNwb3J0KHtcbiAgICAgICAgICAgICAgICAgICAgZm9ybWF0OiBmb3JtYXQucHJpbnRmKCh7IGxldmVsLCBtZXNzYWdlLCB0aW1lc3RhbXAsIG5hbWVzcGFjZTogbnMgfSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJlZml4ID0gYCR7dGltZXN0YW1wfSAke2xldmVsfSR7bnMgPyBgICR7bnN9YCA6ICcnfWA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb2xvclBhcnNlcihgWyR7cHJlZml4fcKncl06ICR7bWVzc2FnZX3Cp3JgKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAuLi50cmFuc3BvcnRzXG4gICAgICAgICAgICBdXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9uIGVuYWJsZSBob29rLlxuICAgICAqIEBncm91cCBMaWZlY3ljbGVcbiAgICAgKi9cbiAgICBwdWJsaWMgYXN5bmMgZW5hYmxlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmNyZWF0ZUxvZ2dlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9uIGRpc2FibGUgaG9vay5cbiAgICAgKiBAZ3JvdXAgTGlmZWN5Y2xlXG4gICAgICovXG4gICAgcHVibGljIGFzeW5jIGRpc2FibGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMubG9nZ2VyIS5jbG9zZSgpO1xuICAgICAgICB0aGlzLmxvZ2dlciA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIGZvciBsb2cgbWVzc2FnZXMuXG4gICAgICogQHBhcmFtIHsobGV2ZWw6IExvZ0xldmVsLCBtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWR9IGxpc3RlbmVyIC0gVGhlIGxpc3RlbmVyIHRvIGNhbGwgd2hlbiBhIGxvZyBtZXNzYWdlIGlzIHJlY2VpdmVkLlxuICAgICAqIEBldmVudFxuICAgICAqL1xuICAgIHB1YmxpYyBvbkxpbmUobGlzdGVuZXI6IChsaW5lOiBzdHJpbmcpID0+IHZvaWQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sb2dnZXIhLm9uKCdkYXRhJywgKGRhdGEpID0+IGxpc3RlbmVyKGRhdGEubWVzc2FnZS50b1N0cmluZygpKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBjb25zb2xlIGluc3RhbmNlIHRvIHVzZS5cbiAgICAgKiBAcGFyYW0ge0NvbnNvbGVMaWtlfSBjb25zb2xlIC0gVGhlIGNvbnNvbGUgaW5zdGFuY2UgdG8gdXNlLlxuICAgICAqL1xuICAgIHB1YmxpYyBzZXRDb25zb2xlKGNvbnNvbGU/OiBDb25zb2xlTGlrZSk6IHZvaWQge1xuICAgICAgICBpZiAoIWNvbnNvbGUpIHJldHVybjtcbiAgICAgICAgKHRoaXMubG9nZ2VyIS50cmFuc3BvcnRzWzBdIGFzIFByaXNtYXJpbmVUcmFuc3BvcnQpLmNvbnNvbGUgPSBjb25zb2xlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBjYWxsZWUncyBuYW1lc3BhY2UgZnJvbSB0aGUgc3RhY2sgdHJhY2UuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwcml2YXRlIGdldE5hbWVzcGFjZSA9ICgpID0+IHtcbiAgICAgICAgY29uc3Qgc3RhY2sgPSAobmV3IEVycm9yKCkuc3RhY2sgYXMgc3RyaW5nKS5yZXBsYWNlQWxsKCdcXFxcJywgJy8nKTtcbiAgICAgICAgaWYgKCFzdGFjaykgcmV0dXJuICcnO1xuXG4gICAgICAgIGNvbnN0IGNhbGxlciA9IChzdGFjay5zcGxpdCgnXFxuJylbM10gfHwgJycpLnRyaW0oKTtcbiAgICAgICAgaWYgKCFjYWxsZXIpIHJldHVybiAnJztcblxuICAgICAgICAvLyBHZXQgcGF0aCBpbnNpZGUgb2YgdGhlIHBhcmVudGhlc2VzIGluIHRoZSBjYWxsZXIgc3RyaW5nLCBleGNsdWRpbmcgdGhlIGxpbmU6Y29sLlxuICAgICAgICBjb25zdCBmaWxlID0gY2FsbGVyLm1hdGNoKC9cXCgoW14pXSspXFwpLyk/LlsxXT8uc3BsaXQoJ3NyYy8nKVsxXSB8fCAnJztcbiAgICAgICAgaWYgKCFmaWxlKSByZXR1cm4gJyc7XG5cbiAgICAgICAgLy8gR2V0IHBhdGggYW5kIGxpbmU6Y29sIGZyb20gdGhlIGZpbGUgc3RyaW5nLCB0aGVuIHJlbW92ZSB0aGUgZmlsZSBleHRlbnNpb24uXG4gICAgICAgIGNvbnN0IHBhdGggPSBmaWxlLnNwbGl0KCc6Jykuc2xpY2UoMCwgLTIpLmpvaW4oJzonKS5zbGljZSgwLCAtMyk7XG4gICAgICAgIGlmICghcGF0aCkgcmV0dXJuICcnO1xuXG4gICAgICAgIGNvbnN0IGxpbmVDb2wgPSBmaWxlLnNwbGl0KCc6Jykuc2xpY2UoLTIpLmpvaW4oJzonKTtcbiAgICAgICAgaWYgKCFsaW5lQ29sKSByZXR1cm4gJyc7XG5cbiAgICAgICAgaWYgKHRoaXMubG9nZ2VyIS5sZXZlbCA9PT0gJ3NpbGx5JyB8fCB0aGlzLmxvZ2dlciEubGV2ZWwgPT09ICdkZWJ1ZycgfHwgdGhpcy5sb2dnZXIhLmxldmVsID09PSAndmVyYm9zZScpIHtcbiAgICAgICAgICAgIHJldHVybiBgJHtwYXRofS50czoke2xpbmVDb2x9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwYXRoLnNwbGl0KCcvJykuYXQoLTEpIHx8ICcnO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHByaXZhdGUgcGFyc2VNZXNzYWdlID0gKGlucHV0OiBzdHJpbmdbXSkgPT4ge1xuICAgICAgICBjb25zdCBvdXRwdXQgPSBpbnB1dC5qb2luKCfCp3IgJyk7XG5cbiAgICAgICAgLy8gTWFrZSBzdXJlIGxvZyBtZXNzYWdlcyBlbmQgd2l0aCBhIHBlcmlvZC5cbiAgICAgICAgaWYgKFsnLicsICchJywgJz8nXS5pbmNsdWRlcyhvdXRwdXQuY2hhckF0KC0xKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBgJHtvdXRwdXR9LmA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBMb2cgaW5mb3JtYXRpb24gbWVzc2FnZXMuXG4gICAgICogQHBhcmFtIHsuLi5zdHJpbmd9IG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0byBsb2cuXG4gICAgICovXG4gICAgcHVibGljIGluZm8gPSAoLi4ubWVzc2FnZTogc3RyaW5nW10pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIhLmxvZygnaW5mbycsIHRoaXMucGFyc2VNZXNzYWdlKG1lc3NhZ2UpLCB7XG4gICAgICAgICAgICBuYW1lc3BhY2U6IHRoaXMuZ2V0TmFtZXNwYWNlKClcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIExvZyB3YXJuaW5nIG1lc3NhZ2VzLlxuICAgICAqIEBwYXJhbSB7Li4uc3RyaW5nfSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gbG9nLlxuICAgICAqL1xuICAgIHB1YmxpYyB3YXJuID0gKC4uLm1lc3NhZ2U6IHN0cmluZ1tdKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMubG9nZ2VyIS5sb2coJ3dhcm4nLCB0aGlzLnBhcnNlTWVzc2FnZShtZXNzYWdlKSwge1xuICAgICAgICAgICAgbmFtZXNwYWNlOiB0aGlzLmdldE5hbWVzcGFjZSgpXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBMb2cgZXJyb3IgbWVzc2FnZXMuXG4gICAgICogQHBhcmFtIHtzdHJpbmcgfCBFcnJvciB8IGFueX0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgZXJyb3IgPSAobWVzc2FnZTogc3RyaW5nIHwgRXJyb3IgfCBhbnkpOiB2b2lkID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIhLmxvZygnZXJyb3InLCBtZXNzYWdlLCB7XG4gICAgICAgICAgICAgICAgbmFtZXNwYWNlOiB0aGlzLmdldE5hbWVzcGFjZSgpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtZXNzYWdlLnN0YWNrKSB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlciEuZXJyb3IoXG4gICAgICAgICAgICAgICAgYCR7bWVzc2FnZS5zdGFjay5zcGxpdCgnXFxuJylbMF0gIT09IG1lc3NhZ2UudG9TdHJpbmcoKSA/IGAke21lc3NhZ2UudG9TdHJpbmcoKX1cXG5gIDogJyd9JHttZXNzYWdlLnN0YWNrfWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmxvZ2dlciEuZXJyb3IobWVzc2FnZS50b1N0cmluZygpKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogTG9nIHZlcmJvc2UgbWVzc2FnZXMuXG4gICAgICogQHBhcmFtIHsuLi5zdHJpbmd9IG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0byBsb2cuXG4gICAgICovXG4gICAgcHVibGljIHZlcmJvc2UgPSAoLi4ubWVzc2FnZTogc3RyaW5nW10pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIhLmxvZygndmVyYm9zZScsIHRoaXMucGFyc2VNZXNzYWdlKG1lc3NhZ2UpLCB7XG4gICAgICAgICAgICBuYW1lc3BhY2U6IHRoaXMuZ2V0TmFtZXNwYWNlKClcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIExvZyBkZWJ1ZyBtZXNzYWdlcy5cbiAgICAgKiBAcGFyYW0gey4uLnN0cmluZ30gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgZGVidWcgPSAoLi4ubWVzc2FnZTogc3RyaW5nW10pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIhLmxvZygnZGVidWcnLCB0aGlzLnBhcnNlTWVzc2FnZShtZXNzYWdlKSwge1xuICAgICAgICAgICAgbmFtZXNwYWNlOiB0aGlzLmdldE5hbWVzcGFjZSgpXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBMb2cgc2lsbHkgbWVzc2FnZXMuXG4gICAgICogQHBhcmFtIHsuLi5zdHJpbmd9IG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0byBsb2cuXG4gICAgICovXG4gICAgcHVibGljIHNpbGx5ID0gKC4uLm1lc3NhZ2U6IHN0cmluZ1tdKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMubG9nZ2VyIS5sb2coJ3NpbGx5JywgdGhpcy5wYXJzZU1lc3NhZ2UobWVzc2FnZSksIHtcbiAgICAgICAgICAgIG5hbWVzcGFjZTogdGhpcy5nZXROYW1lc3BhY2UoKVxuICAgICAgICB9KTtcbiAgICB9O1xufVxuIl0sIm5hbWVzIjpbImxldmVsIl0sIm1hcHBpbmdzIjoiOzs7OztBQXVCTyxNQUFNLE1BQU8sQ0FBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT1IsTUFBeUIsR0FBQSxJQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFRMUIsV0FBWSxDQUFBLEtBQUEsR0FBa0IsTUFBUSxFQUFBLFVBQUEsR0FBZ0MsRUFBSSxFQUFBO0FBQzdFLElBQUssSUFBQSxDQUFBLFlBQUEsQ0FBYSxPQUFPLFVBQVUsQ0FBQTtBQUFBO0FBQ3ZDO0FBQUE7QUFBQTtB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