UNPKG

aws-cdk

Version:

CDK Toolkit, the command line tool for CDK apps

204 lines 25.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.highlight = exports.success = exports.trace = exports.debug = exports.data = exports.info = exports.warning = exports.error = void 0; exports.withCorkedLogging = withCorkedLogging; const util = require("util"); const chalk = require("chalk"); const cli_io_host_1 = require("./toolkit/cli-io-host"); // Corking mechanism let CORK_COUNTER = 0; const logBuffer = []; /** * Executes a block of code with corked logging. All log messages during execution * are buffered and only written when all nested cork blocks complete (when CORK_COUNTER reaches 0). * @param block - Async function to execute with corked logging * @returns Promise that resolves with the block's return value */ async function withCorkedLogging(block) { CORK_COUNTER++; try { return await block(); } finally { CORK_COUNTER--; if (CORK_COUNTER === 0) { // Process each buffered message through notify for (const ioMessage of logBuffer) { void cli_io_host_1.CliIoHost.instance().notify(ioMessage); } logBuffer.splice(0); } } } /** * Internal core logging function that writes messages through the CLI IO host. * @param msg Configuration options for the log message. See {@link LogMessage} */ function log(msg) { const ioMessage = { level: msg.level, message: msg.message, forceStdout: msg.forceStdout, time: new Date(), action: cli_io_host_1.CliIoHost.instance().currentAction, code: msg.code, }; if (CORK_COUNTER > 0) { if (cli_io_host_1.levelPriority[msg.level] > cli_io_host_1.levelPriority[cli_io_host_1.CliIoHost.instance().logLevel]) { return; } logBuffer.push(ioMessage); return; } void cli_io_host_1.CliIoHost.instance().notify(ioMessage); } /** * Internal helper that processes log inputs into a consistent format. * Handles string interpolation, format strings, and object parameter styles. * Applies optional styling and prepares the final message for logging. */ function formatMessageAndLog(level, forceStdout, input, style, ...args) { // Extract message and code from input, using new default code format const { message, code = getDefaultCode(level) } = typeof input === 'object' ? input : { message: input }; // Format message if args are provided const formattedMessage = args.length > 0 ? util.format(message, ...args) : message; // Apply style if provided const finalMessage = style ? style(formattedMessage) : formattedMessage; log({ level, message: finalMessage, code, forceStdout, }); } function getDefaultCode(level, category = 'TOOLKIT') { const levelIndicator = level === 'error' ? 'E' : level === 'warn' ? 'W' : 'I'; return `CDK_${category}_${levelIndicator}0000`; } // Exported logging functions. If any additional logging functionality is required, it should be added as // a new logging function here. /** * Logs an error level message. * * Can be used in multiple ways: * ```ts * error(`operation failed: ${e}`) // infers default error code `CDK_TOOLKIT_E000` * error('operation failed: %s', e) // infers default error code `CDK_TOOLKIT_E000` * error({ message: 'operation failed', code: 'CDK_SDK_E001' }) // specifies error code `CDK_SDK_E001` * error({ message: 'operation failed: %s', code: 'CDK_SDK_E001' }, e) // specifies error code `CDK_SDK_E001` * ``` */ const error = (input, ...args) => { return formatMessageAndLog('error', false, input, undefined, ...args); }; exports.error = error; /** * Logs an warning level message. * * Can be used in multiple ways: * ```ts * warning(`deprected feature: ${message}`) // infers default warning code `CDK_TOOLKIT_W000` * warning('deprected feature: %s', message) // infers default warning code `CDK_TOOLKIT_W000` * warning({ message: 'deprected feature', code: 'CDK_SDK_W001' }) // specifies warning code `CDK_SDK_W001` * warning({ message: 'deprected feature: %s', code: 'CDK_SDK_W001' }, message) // specifies warning code `CDK_SDK_W001` * ``` */ const warning = (input, ...args) => { return formatMessageAndLog('warn', false, input, undefined, ...args); }; exports.warning = warning; /** * Logs an info level message. * * Can be used in multiple ways: * ```ts * info(`processing: ${message}`) // infers default info code `CDK_TOOLKIT_I000` * info('processing: %s', message) // infers default info code `CDK_TOOLKIT_I000` * info({ message: 'processing', code: 'CDK_TOOLKIT_I001' }) // specifies info code `CDK_TOOLKIT_I001` * info({ message: 'processing: %s', code: 'CDK_TOOLKIT_I001' }, message) // specifies info code `CDK_TOOLKIT_I001` * ``` */ const info = (input, ...args) => { return formatMessageAndLog('info', false, input, undefined, ...args); }; exports.info = info; /** * Logs an info level message to stdout. * * Can be used in multiple ways: * ```ts * data(`${JSON.stringify(stats)}`) // infers default info code `CDK_TOOLKIT_I000` * data('{"count": %d}', count) // infers default info code `CDK_TOOLKIT_I000` * data({ message: 'stats: %j', code: 'CDK_DATA_I001' }) // specifies info code `CDK_DATA_I001` * data({ message: 'stats: %j', code: 'CDK_DATA_I001' }, stats) // specifies info code `CDK_DATA_I001` * ``` */ const data = (input, ...args) => { return formatMessageAndLog('info', true, input, undefined, ...args); }; exports.data = data; /** * Logs a debug level message. * * Can be used in multiple ways: * ```ts * debug(`state: ${JSON.stringify(state)}`) // infers default info code `CDK_TOOLKIT_I000` * debug('cache hit ratio: %d%%', ratio) // infers default info code `CDK_TOOLKIT_I000` * debug({ message: 'state update', code: 'CDK_TOOLKIT_I001' }) // specifies info code `CDK_TOOLKIT_I001` * debug({ message: 'ratio: %d%%', code: 'CDK_TOOLKIT_I001' }, ratio) // specifies info code `CDK_TOOLKIT_I001` * ``` */ const debug = (input, ...args) => { return formatMessageAndLog('debug', false, input, undefined, ...args); }; exports.debug = debug; /** * Logs a trace level message. * * Can be used in multiple ways: * ```ts * trace(`entered ${name} with ${args}`) // infers default info code `CDK_TOOLKIT_I000` * trace('method: %s, args: %j', name, args) // infers default info code `CDK_TOOLKIT_I000` * trace({ message: 'entered', code: 'CDK_TOOLKIT_I001' }) // specifies info code `CDK_TOOLKIT_I001` * trace({ message: 'method: %s', code: 'CDK_TOOLKIT_I001' }, name) // specifies info code `CDK_TOOLKIT_I001` * ``` */ const trace = (input, ...args) => { return formatMessageAndLog('trace', false, input, undefined, ...args); }; exports.trace = trace; /** * Logs an info level success message in green text. * * Can be used in multiple ways: * ```ts * success(`deployment completed: ${name}`) // infers default info code `CDK_TOOLKIT_I000` * success('processed %d items', count) // infers default info code `CDK_TOOLKIT_I000` * success({ message: 'completed', code: 'CDK_TOOLKIT_I001' }) // specifies info code `CDK_TOOLKIT_I001` * success({ message: 'items: %d', code: 'CDK_TOOLKIT_I001' }, count) // specifies info code `CDK_TOOLKIT_I001` * ``` */ const success = (input, ...args) => { return formatMessageAndLog('info', false, input, chalk.green, ...args); }; exports.success = success; /** * Logs an info level message in bold text. * * Can be used in multiple ways: * ```ts * highlight(`important: ${msg}`) // infers default info code `CDK_TOOLKIT_I000` * highlight('attention required: %s', reason) // infers default info code `CDK_TOOLKIT_I000` * highlight({ message: 'notice', code: 'CDK_TOOLKIT_I001' }) // specifies info code `CDK_TOOLKIT_I001` * highlight({ message: 'notice: %s', code: 'CDK_TOOLKIT_I001' }, msg) // specifies info code `CDK_TOOLKIT_I001` * ``` */ const highlight = (input, ...args) => { return formatMessageAndLog('info', false, input, chalk.bold, ...args); }; exports.highlight = highlight; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2luZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxvZ2dpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBY0EsOENBY0M7QUE1QkQsNkJBQTZCO0FBQzdCLCtCQUErQjtBQUMvQix1REFBc0s7QUFFdEssb0JBQW9CO0FBQ3BCLElBQUksWUFBWSxHQUFHLENBQUMsQ0FBQztBQUNyQixNQUFNLFNBQVMsR0FBcUIsRUFBRSxDQUFDO0FBRXZDOzs7OztHQUtHO0FBQ0ksS0FBSyxVQUFVLGlCQUFpQixDQUFJLEtBQXVCO0lBQ2hFLFlBQVksRUFBRSxDQUFDO0lBQ2YsSUFBSSxDQUFDO1FBQ0gsT0FBTyxNQUFNLEtBQUssRUFBRSxDQUFDO0lBQ3ZCLENBQUM7WUFBUyxDQUFDO1FBQ1QsWUFBWSxFQUFFLENBQUM7UUFDZixJQUFJLFlBQVksS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN2QiwrQ0FBK0M7WUFDL0MsS0FBSyxNQUFNLFNBQVMsSUFBSSxTQUFTLEVBQUUsQ0FBQztnQkFDbEMsS0FBSyx1QkFBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUM5QyxDQUFDO1lBQ0QsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUM7QUF3QkQ7OztHQUdHO0FBQ0gsU0FBUyxHQUFHLENBQUMsR0FBZTtJQUMxQixNQUFNLFNBQVMsR0FBeUI7UUFDdEMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLO1FBQ2hCLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTztRQUNwQixXQUFXLEVBQUUsR0FBRyxDQUFDLFdBQVc7UUFDNUIsSUFBSSxFQUFFLElBQUksSUFBSSxFQUFFO1FBQ2hCLE1BQU0sRUFBRSx1QkFBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLGFBQWE7UUFDMUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJO0tBQ2YsQ0FBQztJQUVGLElBQUksWUFB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U0FBUyxhQUVwQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHV0aWwgZnJvbSAndXRpbCc7XG5pbXBvcnQgKiBhcyBjaGFsayBmcm9tICdjaGFsayc7XG5pbXBvcnQgeyBJb01lc3NhZ2VMZXZlbCwgSW9NZXNzYWdlLCBDbGlJb0hvc3QsIElvTWVzc2FnZVNwZWNpZmljQ29kZSwgSW9NZXNzYWdlQ29kZSwgSW9NZXNzYWdlQ29kZUNhdGVnb3J5LCBJb0NvZGVMZXZlbCwgbGV2ZWxQcmlvcml0eSB9IGZyb20gJy4vdG9vbGtpdC9jbGktaW8taG9zdCc7XG5cbi8vIENvcmtpbmcgbWVjaGFuaXNtXG5sZXQgQ09SS19DT1VOVEVSID0gMDtcbmNvbnN0IGxvZ0J1ZmZlcjogSW9NZXNzYWdlPGFueT5bXSA9IFtdO1xuXG4vKipcbiAqIEV4ZWN1dGVzIGEgYmxvY2sgb2YgY29kZSB3aXRoIGNvcmtlZCBsb2dnaW5nLiBBbGwgbG9nIG1lc3NhZ2VzIGR1cmluZyBleGVjdXRpb25cbiAqIGFyZSBidWZmZXJlZCBhbmQgb25seSB3cml0dGVuIHdoZW4gYWxsIG5lc3RlZCBjb3JrIGJsb2NrcyBjb21wbGV0ZSAod2hlbiBDT1JLX0NPVU5URVIgcmVhY2hlcyAwKS5cbiAqIEBwYXJhbSBibG9jayAtIEFzeW5jIGZ1bmN0aW9uIHRvIGV4ZWN1dGUgd2l0aCBjb3JrZWQgbG9nZ2luZ1xuICogQHJldHVybnMgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGJsb2NrJ3MgcmV0dXJuIHZhbHVlXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3aXRoQ29ya2VkTG9nZ2luZzxUPihibG9jazogKCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICBDT1JLX0NPVU5URVIrKztcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgYmxvY2soKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBDT1JLX0NPVU5URVItLTtcbiAgICBpZiAoQ09SS19DT1VOVEVSID09PSAwKSB7XG4gICAgICAvLyBQcm9jZXNzIGVhY2ggYnVmZmVyZWQgbWVzc2FnZSB0aHJvdWdoIG5vdGlmeVxuICAgICAgZm9yIChjb25zdCBpb01lc3NhZ2Ugb2YgbG9nQnVmZmVyKSB7XG4gICAgICAgIHZvaWQgQ2xpSW9Ib3N0Lmluc3RhbmNlKCkubm90aWZ5KGlvTWVzc2FnZSk7XG4gICAgICB9XG4gICAgICBsb2dCdWZmZXIuc3BsaWNlKDApO1xuICAgIH1cbiAgfVxufVxuXG5pbnRlcmZhY2UgTG9nTWVzc2FnZSB7XG4gIC8qKlxuICAgKiBUaGUgbG9nIGxldmVsIHRvIHVzZVxuICAgKi9cbiAgcmVhZG9ubHkgbGV2ZWw6IElvTWVzc2FnZUxldmVsO1xuICAvKipcbiAgICogVGhlIG1lc3NhZ2UgdG8gbG9nXG4gICAqL1xuICByZWFkb25seSBtZXNzYWdlOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGZvcmNlIHN0ZG91dFxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZm9yY2VTdGRvdXQ/OiBib29sZWFuO1xuICAvKipcbiAgICogTWVzc2FnZSBjb2RlIG9mIHRoZSBmb3JtYXQgW0NBVEVHT1JZXV9bTlVNQkVSX0NPREVdXG4gICAqIEBwYXR0ZXJuIFtBLVpdK19bMC0yXVswLTldezN9XG4gICAqIEBkZWZhdWx0IFRPT0xLSVRfWzAvMS8yXTAwMFxuICAgKi9cbiAgcmVhZG9ubHkgY29kZTogSW9NZXNzYWdlQ29kZTtcbn1cblxuLyoqXG4gKiBJbnRlcm5hbCBjb3JlIGxvZ2dpbmcgZnVuY3Rpb24gdGhhdCB3cml0ZXMgbWVzc2FnZXMgdGhyb3VnaCB0aGUgQ0xJIElPIGhvc3QuXG4gKiBAcGFyYW0gbXNnIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgdGhlIGxvZyBtZXNzYWdlLiBTZWUgIHtAbGluayBMb2dNZXNzYWdlfVxuICovXG5mdW5jdGlvbiBsb2cobXNnOiBMb2dNZXNzYWdlKSB7XG4gIGNvbnN0IGlvTWVzc2FnZTogSW9NZXNzYWdlPHVuZGVmaW5lZD4gPSB7XG4gICAgbGV2ZWw6IG1zZy5sZXZlbCxcbiAgICBtZXNzYWdlOiBtc2cubWVzc2FnZSxcbiAgICBmb3JjZVN0ZG91dDogbXNnLmZvcmNlU3Rkb3V0LFxuICAgIHRpbWU6IG5ldyBEYXRlKCksXG4gICAgYWN0aW9uOiBDbGlJb0hvc3QuaW5zdGFuY2UoKS5jdXJyZW50QWN0aW9uLFxuICAgIGNvZGU6IG1zZy5jb2RlLFxuICB9O1xuXG4gIGlmIChDT1JLX0NPVU5URVIgPiAwKSB7XG4gICAgaWYgKGxldmVsUHJpb3JpdHlbbXNnLmxldmVsXSA+IGxldmVsUHJpb3JpdHlbQ2xpSW9Ib3N0Lmluc3RhbmNlKCkubG9nTGV2ZWxdKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxvZ0J1ZmZlci5wdXNoKGlvTWVzc2FnZSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdm9pZCBDbGlJb0hvc3QuaW5zdGFuY2UoKS5ub3RpZnkoaW9NZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBJbnRlcm5hbCBoZWxwZXIgdGhhdCBwcm9jZXNzZXMgbG9nIGlucHV0cyBpbnRvIGEgY29uc2lzdGVudCBmb3JtYXQuXG4gKiBIYW5kbGVzIHN0cmluZyBpbnRlcnBvbGF0aW9uLCBmb3JtYXQgc3RyaW5ncywgYW5kIG9iamVjdCBwYXJhbWV0ZXIgc3R5bGVzLlxuICogQXBwbGllcyBvcHRpb25hbCBzdHlsaW5nIGFuZCBwcmVwYXJlcyB0aGUgZmluYWwgbWVzc2FnZSBmb3IgbG9nZ2luZy5cbiAqL1xuZnVuY3Rpb24gZm9ybWF0TWVzc2FnZUFuZExvZyhcbiAgbGV2ZWw6IElvTWVzc2FnZUxldmVsLFxuICBmb3JjZVN0ZG91dDogYm9vbGVhbixcbiAgaW5wdXQ6IExvZ0lucHV0PElvQ29kZUxldmVsPixcbiAgc3R5bGU/OiAoc3RyOiBzdHJpbmcpID0+IHN0cmluZyxcbiAgLi4uYXJnczogdW5rbm93bltdXG4pOiB2b2lkIHtcbiAgLy8gRXh0cmFjdCBtZXNzYWdlIGFuZCBjb2RlIGZyb20gaW5wdXQsIHVzaW5nIG5ldyBkZWZhdWx0IGNvZGUgZm9ybWF0XG4gIGNvbnN0IHsgbWVzc2FnZSwgY29kZSA9IGdldERlZmF1bHRDb2RlKGxldmVsKSB9ID0gdHlwZW9mIGlucHV0ID09PSAnb2JqZWN0JyA/IGlucHV0IDogeyBtZXNzYWdlOiBpbnB1dCB9O1xuXG4gIC8vIEZvcm1hdCBtZXNzYWdlIGlmIGFyZ3MgYXJlIHByb3ZpZGVkXG4gIGNvbnN0IGZvcm1hdHRlZE1lc3NhZ2UgPSBhcmdzLmxlbmd0aCA+IDBcbiAgICA/IHV0aWwuZm9ybWF0KG1lc3NhZ2UsIC4uLmFyZ3MpXG4gICAgOiBtZXNzYWdlO1xuXG4gIC8vIEFwcGx5IHN0eWxlIGlmIHByb3ZpZGVkXG4gIGNvbnN0IGZpbmFsTWVzc2FnZSA9IHN0eWxlID8gc3R5bGUoZm9ybWF0dGVkTWVzc2FnZSkgOiBmb3JtYXR0ZWRNZXNzYWdlO1xuXG4gIGxvZyh7XG4gICAgbGV2ZWwsXG4gICAgbWVzc2FnZTogZmluYWxNZXNzYWdlLFxuICAgIGNvZGUsXG4gICAgZm9yY2VTdGRvdXQsXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBnZXREZWZhdWx0Q29kZShsZXZlbDogSW9NZXNzYWdlTGV2ZWwsIGNhdGVnb3J5OiBJb01lc3NhZ2VDb2RlQ2F0ZWdvcnkgPSAnVE9PTEtJVCcpOiBJb01lc3NhZ2VDb2RlIHtcbiAgY29uc3QgbGV2ZWxJbmRpY2F0b3IgPSBsZXZlbCA9PT0gJ2Vycm9yJyA/ICdFJyA6XG4gICAgbGV2ZWwgPT09ICd3YXJuJyA/ICdXJyA6XG4gICAgICAnSSc7XG4gIHJldHVybiBgQ0RLXyR7Y2F0ZWdvcnl9XyR7bGV2ZWxJbmRpY2F0b3J9MDAwMGA7XG59XG5cbi8vIFR5cGUgZm9yIHRoZSBvYmplY3QgcGFyYW1ldGVyIHN0eWxlXG5pbnRlcmZhY2UgTG9nUGFyYW1zPEwgZXh0ZW5kcyBJb0NvZGVMZXZlbD4ge1xuICAvKipcbiAgICogQHNlZSB7QGxpbmsgSW9NZXNzYWdlLmNvZGV9XG4gICAqL1xuICByZWFkb25seSBjb2RlPzogSW9NZXNzYWdlU3BlY2lmaWNDb2RlPEw+O1xuICAvKipcbiAgICogQHNlZSB7QGxpbmsgSW9NZXNzYWdlLm1lc3NhZ2V9XG4gICAqL1xuICByZWFkb25seSBtZXNzYWdlOiBzdHJpbmc7XG59XG5cbi8vIFR5cGUgZm9yIHRoZSBleHBvcnRlZCBsb2cgZnVuY3Rpb24gYXJndW1lbnRzXG50eXBlIExvZ0lucHV0PEwgZXh0ZW5kcyBJb0NvZGVMZXZlbD4gPSBzdHJpbmcgfCBMb2dQYXJhbXM8TD47XG5cbi8vIEV4cG9ydGVkIGxvZ2dpbmcgZnVuY3Rpb25zLiBJZiBhbnkgYWRkaXRpb25hbCBsb2dnaW5nIGZ1bmN0aW9uYWxpdHkgaXMgcmVxdWlyZWQsIGl0IHNob3VsZCBiZSBhZGRlZCBhc1xuLy8gYSBuZXcgbG9nZ2luZyBmdW5jdGlvbiBoZXJlLlxuXG4vKipcbiAqIExvZ3MgYW4gZXJyb3IgbGV2ZWwgbWVzc2FnZS5cbiAqXG4gKiBDYW4gYmUgdXNlZCBpbiBtdWx0aXBsZSB3YXlzOlxuICogYGBgdHNcbiAqIGVycm9yKGBvcGVyYXRpb24gZmFpbGVkOiAke2V9YCkgLy8gaW5mZXJzIGRlZmF1bHQgZXJyb3IgY29kZSBgQ0RLX1RPT0xLSVRfRTAwMGBcbiAqIGVycm9yKCdvcGVyYXRpb24gZmFpbGVkOiAlcycsIGUpIC8vIGluZmVycyBkZWZhdWx0IGVycm9yIGNvZGUgYENES19UT09MS0lUX0UwMDBgXG4gKiBlcnJvcih7IG1lc3NhZ2U6ICdvcGVyYXRpb24gZmFpbGVkJywgY29kZTogJ0NES19TREtfRTAwMScgfSkgLy8gc3BlY2lmaWVzIGVycm9yIGNvZGUgYENES19TREtfRTAwMWBcbiAqIGVycm9yKHsgbWVzc2FnZTogJ29wZXJhdGlvbiBmYWlsZWQ6ICVzJywgY29kZTogJ0NES19TREtfRTAwMScgfSwgZSkgLy8gc3BlY2lmaWVzIGVycm9yIGNvZGUgYENES19TREtfRTAwMWBcbiAqIGBgYFxuICovXG5leHBvcnQgY29uc3QgZXJyb3IgPSAoaW5wdXQ6IExvZ0lucHV0PCdFJz4sIC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICByZXR1cm4gZm9ybWF0TWVzc2FnZUFuZExvZygnZXJyb3InLCBmYWxzZSwgaW5wdXQsIHVuZGVmaW5lZCwgLi4uYXJncyk7XG59O1xuXG4vKipcbiAqIExvZ3MgYW4gd2FybmluZyBsZXZlbCBtZXNzYWdlLlxuICpcbiAqIENhbiBiZSB1c2VkIGluIG11bHRpcGxlIHdheXM6XG4gKiBgYGB0c1xuICogd2FybmluZyhgZGVwcmVjdGVkIGZlYXR1cmU6ICR7bWVzc2FnZX1gKSAvLyBpbmZlcnMgZGVmYXVsdCB3YXJuaW5nIGNvZGUgYENES19UT09MS0lUX1cwMDBgXG4gKiB3YXJuaW5nKCdkZXByZWN0ZWQgZmVhdHVyZTogJXMnLCBtZXNzYWdlKSAvLyBpbmZlcnMgZGVmYXVsdCB3YXJuaW5nIGNvZGUgYENES19UT09MS0lUX1cwMDBgXG4gKiB3YXJuaW5nKHsgbWVzc2FnZTogJ2RlcHJlY3RlZCBmZWF0dXJlJywgY29kZTogJ0NES19TREtfVzAwMScgfSkgLy8gc3BlY2lmaWVzIHdhcm5pbmcgY29kZSBgQ0RLX1NES19XMDAxYFxuICogd2FybmluZyh7IG1lc3NhZ2U6ICdkZXByZWN0ZWQgZmVhdHVyZTogJXMnLCBjb2RlOiAnQ0RLX1NES19XMDAxJyB9LCBtZXNzYWdlKSAvLyBzcGVjaWZpZXMgd2FybmluZyBjb2RlIGBDREtfU0RLX1cwMDFgXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IHdhcm5pbmcgPSAoaW5wdXQ6IExvZ0lucHV0PCdXJz4sIC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICByZXR1cm4gZm9ybWF0TWVzc2FnZUFuZExvZygnd2FybicsIGZhbHNlLCBpbnB1dCwgdW5kZWZpbmVkLCAuLi5hcmdzKTtcbn07XG5cbi8qKlxuICogTG9ncyBhbiBpbmZvIGxldmVsIG1lc3NhZ2UuXG4gKlxuICogQ2FuIGJlIHVzZWQgaW4gbXVsdGlwbGUgd2F5czpcbiAqIGBgYHRzXG4gKiBpbmZvKGBwcm9jZXNzaW5nOiAke21lc3NhZ2V9YCkgLy8gaW5mZXJzIGRlZmF1bHQgaW5mbyBjb2RlIGBDREtfVE9PTEtJVF9JMDAwYFxuICogaW5mbygncHJvY2Vzc2luZzogJXMnLCBtZXNzYWdlKSAvLyBpbmZlcnMgZGVmYXVsdCBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDBgXG4gKiBpbmZvKHsgbWVzc2FnZTogJ3Byb2Nlc3NpbmcnLCBjb2RlOiAnQ0RLX1RPT0xLSVRfSTAwMScgfSkgLy8gc3BlY2lmaWVzIGluZm8gY29kZSBgQ0RLX1RPT0xLSVRfSTAwMWBcbiAqIGluZm8oeyBtZXNzYWdlOiAncHJvY2Vzc2luZzogJXMnLCBjb2RlOiAnQ0RLX1RPT0xLSVRfSTAwMScgfSwgbWVzc2FnZSkgLy8gc3BlY2lmaWVzIGluZm8gY29kZSBgQ0RLX1RPT0xLSVRfSTAwMWBcbiAqIGBgYFxuICovXG5leHBvcnQgY29uc3QgaW5mbyA9IChpbnB1dDogTG9nSW5wdXQ8J0knPiwgLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gIHJldHVybiBmb3JtYXRNZXNzYWdlQW5kTG9nKCdpbmZvJywgZmFsc2UsIGlucHV0LCB1bmRlZmluZWQsIC4uLmFyZ3MpO1xufTtcblxuLyoqXG4gKiBMb2dzIGFuIGluZm8gbGV2ZWwgbWVzc2FnZSB0byBzdGRvdXQuXG4gKlxuICogQ2FuIGJlIHVzZWQgaW4gbXVsdGlwbGUgd2F5czpcbiAqIGBgYHRzXG4gKiBkYXRhKGAke0pTT04uc3RyaW5naWZ5KHN0YXRzKX1gKSAvLyBpbmZlcnMgZGVmYXVsdCBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDBgXG4gKiBkYXRhKCd7XCJjb3VudFwiOiAlZH0nLCBjb3VudCkgLy8gaW5mZXJzIGRlZmF1bHQgaW5mbyBjb2RlIGBDREtfVE9PTEtJVF9JMDAwYFxuICogZGF0YSh7IG1lc3NhZ2U6ICdzdGF0czogJWonLCBjb2RlOiAnQ0RLX0RBVEFfSTAwMScgfSkgLy8gc3BlY2lmaWVzIGluZm8gY29kZSBgQ0RLX0RBVEFfSTAwMWBcbiAqIGRhdGEoeyBtZXNzYWdlOiAnc3RhdHM6ICVqJywgY29kZTogJ0NES19EQVRBX0kwMDEnIH0sIHN0YXRzKSAvLyBzcGVjaWZpZXMgaW5mbyBjb2RlIGBDREtfREFUQV9JMDAxYFxuICogYGBgXG4gKi9cbmV4cG9ydCBjb25zdCBkYXRhID0gKGlucHV0OiBMb2dJbnB1dDwnSSc+LCAuLi5hcmdzOiB1bmtub3duW10pID0+IHtcbiAgcmV0dXJuIGZvcm1hdE1lc3NhZ2VBbmRMb2coJ2luZm8nLCB0cnVlLCBpbnB1dCwgdW5kZWZpbmVkLCAuLi5hcmdzKTtcbn07XG5cbi8qKlxuICogTG9ncyBhIGRlYnVnIGxldmVsIG1lc3NhZ2UuXG4gKlxuICogQ2FuIGJlIHVzZWQgaW4gbXVsdGlwbGUgd2F5czpcbiAqIGBgYHRzXG4gKiBkZWJ1Zyhgc3RhdGU6ICR7SlNPTi5zdHJpbmdpZnkoc3RhdGUpfWApIC8vIGluZmVycyBkZWZhdWx0IGluZm8gY29kZSBgQ0RLX1RPT0xLSVRfSTAwMGBcbiAqIGRlYnVnKCdjYWNoZSBoaXQgcmF0aW86ICVkJSUnLCByYXRpbykgLy8gaW5mZXJzIGRlZmF1bHQgaW5mbyBjb2RlIGBDREtfVE9PTEtJVF9JMDAwYFxuICogZGVidWcoeyBtZXNzYWdlOiAnc3RhdGUgdXBkYXRlJywgY29kZTogJ0NES19UT09MS0lUX0kwMDEnIH0pIC8vIHNwZWNpZmllcyBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDFgXG4gKiBkZWJ1Zyh7IG1lc3NhZ2U6ICdyYXRpbzogJWQlJScsIGNvZGU6ICdDREtfVE9PTEtJVF9JMDAxJyB9LCByYXRpbykgLy8gc3BlY2lmaWVzIGluZm8gY29kZSBgQ0RLX1RPT0xLSVRfSTAwMWBcbiAqIGBgYFxuICovXG5leHBvcnQgY29uc3QgZGVidWcgPSAoaW5wdXQ6IExvZ0lucHV0PCdJJz4sIC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICByZXR1cm4gZm9ybWF0TWVzc2FnZUFuZExvZygnZGVidWcnLCBmYWxzZSwgaW5wdXQsIHVuZGVmaW5lZCwgLi4uYXJncyk7XG59O1xuXG4vKipcbiAqIExvZ3MgYSB0cmFjZSBsZXZlbCBtZXNzYWdlLlxuICpcbiAqIENhbiBiZSB1c2VkIGluIG11bHRpcGxlIHdheXM6XG4gKiBgYGB0c1xuICogdHJhY2UoYGVudGVyZWQgJHtuYW1lfSB3aXRoICR7YXJnc31gKSAvLyBpbmZlcnMgZGVmYXVsdCBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDBgXG4gKiB0cmFjZSgnbWV0aG9kOiAlcywgYXJnczogJWonLCBuYW1lLCBhcmdzKSAvLyBpbmZlcnMgZGVmYXVsdCBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDBgXG4gKiB0cmFjZSh7IG1lc3NhZ2U6ICdlbnRlcmVkJywgY29kZTogJ0NES19UT09MS0lUX0kwMDEnIH0pIC8vIHNwZWNpZmllcyBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDFgXG4gKiB0cmFjZSh7IG1lc3NhZ2U6ICdtZXRob2Q6ICVzJywgY29kZTogJ0NES19UT09MS0lUX0kwMDEnIH0sIG5hbWUpIC8vIHNwZWNpZmllcyBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDFgXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IHRyYWNlID0gKGlucHV0OiBMb2dJbnB1dDwnSSc+LCAuLi5hcmdzOiB1bmtub3duW10pID0+IHtcbiAgcmV0dXJuIGZvcm1hdE1lc3NhZ2VBbmRMb2coJ3RyYWNlJywgZmFsc2UsIGlucHV0LCB1bmRlZmluZWQsIC4uLmFyZ3MpO1xufTtcblxuLyoqXG4gKiBMb2dzIGFuIGluZm8gbGV2ZWwgc3VjY2VzcyBtZXNzYWdlIGluIGdyZWVuIHRleHQuXG4gKlxuICogQ2FuIGJlIHVzZWQgaW4gbXVsdGlwbGUgd2F5czpcbiAqIGBgYHRzXG4gKiBzdWNjZXNzKGBkZXBsb3ltZW50IGNvbXBsZXRlZDogJHtuYW1lfWApIC8vIGluZmVycyBkZWZhdWx0IGluZm8gY29kZSBgQ0RLX1RPT0xLSVRfSTAwMGBcbiAqIHN1Y2Nlc3MoJ3Byb2Nlc3NlZCAlZCBpdGVtcycsIGNvdW50KSAvLyBpbmZlcnMgZGVmYXVsdCBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDBgXG4gKiBzdWNjZXNzKHsgbWVzc2FnZTogJ2NvbXBsZXRlZCcsIGNvZGU6ICdDREtfVE9PTEtJVF9JMDAxJyB9KSAvLyBzcGVjaWZpZXMgaW5mbyBjb2RlIGBDREtfVE9PTEtJVF9JMDAxYFxuICogc3VjY2Vzcyh7IG1lc3NhZ2U6ICdpdGVtczogJWQnLCBjb2RlOiAnQ0RLX1RPT0xLSVRfSTAwMScgfSwgY291bnQpIC8vIHNwZWNpZmllcyBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDFgXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IHN1Y2Nlc3MgPSAoaW5wdXQ6IExvZ0lucHV0PCdJJz4sIC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICByZXR1cm4gZm9ybWF0TWVzc2FnZUFuZExvZygnaW5mbycsIGZhbHNlLCBpbnB1dCwgY2hhbGsuZ3JlZW4sIC4uLmFyZ3MpO1xufTtcblxuLyoqXG4gKiBMb2dzIGFuIGluZm8gbGV2ZWwgbWVzc2FnZSBpbiBib2xkIHRleHQuXG4gKlxuICogQ2FuIGJlIHVzZWQgaW4gbXVsdGlwbGUgd2F5czpcbiAqIGBgYHRzXG4gKiBoaWdobGlnaHQoYGltcG9ydGFudDogJHttc2d9YCkgLy8gaW5mZXJzIGRlZmF1bHQgaW5mbyBjb2RlIGBDREtfVE9PTEtJVF9JMDAwYFxuICogaGlnaGxpZ2h0KCdhdHRlbnRpb24gcmVxdWlyZWQ6ICVzJywgcmVhc29uKSAvLyBpbmZlcnMgZGVmYXVsdCBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDBgXG4gKiBoaWdobGlnaHQoeyBtZXNzYWdlOiAnbm90aWNlJywgY29kZTogJ0NES19UT09MS0lUX0kwMDEnIH0pIC8vIHNwZWNpZmllcyBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDFgXG4gKiBoaWdobGlnaHQoeyBtZXNzYWdlOiAnbm90aWNlOiAlcycsIGNvZGU6ICdDREtfVE9PTEtJVF9JMDAxJyB9LCBtc2cpIC8vIHNwZWNpZmllcyBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDFgXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IGhpZ2hsaWdodCA9IChpbnB1dDogTG9nSW5wdXQ8J0knPiwgLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gIHJldHVybiBmb3JtYXRNZXNzYWdlQW5kTG9nKCdpbmZvJywgZmFsc2UsIGlucHV0LCBjaGFsay5ib2xkLCAuLi5hcmdzKTtcbn07XG4iXX0=