UNPKG

@decaf-ts/fabric-weaver

Version:
124 lines 15 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.readFileYaml = readFileYaml; exports.writeFileYaml = writeFileYaml; const fs_1 = __importDefault(require("fs")); const js_yaml_1 = __importDefault(require("js-yaml")); const logging_1 = require("@decaf-ts/logging"); const logger = logging_1.Logging.for("yaml"); /** * @description Reads and parses a YAML file, optionally retrieving a specific property. * @summary This function reads a YAML file from the given path, parses its content, and returns either the entire parsed YAML object or a specific property value based on the provided path. * * @function readFileYaml * @template T - The type of the returned value when a specific property is requested. * @param {string} yamlFilePath - The path to the YAML file to be read. * @param {string} [variable] - Optional. A dot-notated path string that specifies the property to retrieve from the parsed YAML. * @return {Record<string, any> | T} Returns the entire parsed YAML object if no `variable` is provided, or the value of the specified property if `variable` is provided. * * @memberOf module:fabric-weaver.Utils * * @example * // Example 1: Read the entire YAML file * const config = readFileYaml("config/settings.yaml"); * console.log(config); * * @example * // Example 2: Retrieve a specific property from the YAML file * const dbHost = readFileYaml("config/settings.yaml", "database.host"); * console.log(dbHost); * * @example * // Example 3: Handle an error if the property does not exist * const invalidProperty = readFileYaml("config/settings.yaml", "server.port"); * * @mermaid * sequenceDiagram * participant Caller * participant readFileYaml * participant logger * participant fs * participant yaml * * Caller->>readFileYaml: Call with yamlFilePath and optional variable * readFileYaml->>logger: Log verbose message (Reading YAML file) * readFileYaml->>fs: Read file content * readFileYaml->>logger: Log verbose message (Parsed YAML content) * readFileYaml->>yaml: Parse YAML content * readFileYaml->>logger: Log verbose message (Parsed YAML object) * alt variable is provided * readFileYaml->>readFileYaml: Navigate through parsed YAML using variable path * alt Property exists * readFileYaml-->>Caller: Return specific property value * else Property doesn't exist * readFileYaml->>logger: Log error message * readFileYaml-->>Caller: Return error * end * else variable is not provided * readFileYaml-->>Caller: Return entire parsed YAML object * end */ function readFileYaml(yamlFilePath, variable) { const log = logger.for(readFileYaml); log.debug(`Reading YAML file: ${yamlFilePath}`); const content = fs_1.default.readFileSync(yamlFilePath, "utf8"); log.debug(`Parsed YAML content: ${content}`); const parsedYAML = js_yaml_1.default.load(content); log.debug(`Parsed YAML object: ${JSON.stringify(parsedYAML, null, 2)}`); log.info(`Returning ${variable ? `property '${variable}'` : "the entire parsed YAML object"}`); if (!variable) return parsedYAML; const variablePath = variable.split("."); return variablePath.reduce((acc, key) => { // eslint-disable-next-line no-prototype-builtins if (!acc.hasOwnProperty(key)) { throw new Error(`Unable to locate a property named '${key}' from path '${variable}' in file: \n> ${yamlFilePath}`); } return typeof acc[key] === "string" ? acc[key].trim() : acc[key]; }, parsedYAML); } /** * @description Writes a JSON object to a YAML file. * @summary This function takes a JSON object and writes it to a specified file path in YAML format. * It uses js-yaml to convert the JSON to YAML, and then writes the content to the file. * * @function writeFileYaml * @template T - The type of the JSON object to be written. * @param {string} path - The file path where the YAML content will be written. * @param {T} json - The JSON object to be converted to YAML and written to the file. * @return {void} * * @memberOf module:fabric-weaver.Utils * * @example * const config = { database: { host: 'localhost', port: 5432 } }; * writeFileYaml('config/settings.yaml', config); * * @mermaid * sequenceDiagram * participant Caller * participant writeFileYaml * participant logger * participant yaml * participant fs * * Caller->>writeFileYaml: Call with path and JSON * writeFileYaml->>logger: Log verbose message (Writing YAML file) * writeFileYaml->>logger: Log verbose message (Writing YAML content) * writeFileYaml->>yaml: Convert JSON to YAML * writeFileYaml->>logger: Log verbose message (Writing YAML content to file) * writeFileYaml->>fs: Write YAML content to file * writeFileYaml-->>Caller: Return (void) */ function writeFileYaml(path, json) { const log = logger.for(writeFileYaml); log.debug(`Writing YAML file: ${path}`); log.debug(`Writing YAML content: ${JSON.stringify(json, null, 2)}`); const content = js_yaml_1.default.dump(json, { indent: 2, lineWidth: -1 }); log.debug(`Writing YAML content to file: ${content}`); fs_1.default.writeFileSync(path, content.replace(/ null$/gm, ""), "utf8"); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieWFtbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy95YW1sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBMERBLG9DQThCQztBQW1DRCxzQ0FTQztBQXBJRCw0Q0FBb0I7QUFDcEIsc0RBQTJCO0FBQzNCLCtDQUE0QztBQUU1QyxNQUFNLE1BQU0sR0FBRyxpQkFBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUVuQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbURHO0FBQ0gsU0FBZ0IsWUFBWSxDQUMxQixZQUFvQixFQUNwQixRQUFpQjtJQUVqQixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRXJDLEdBQUcsQ0FBQyxLQUFLLENBQUMsc0JBQXNCLFlBQVksRUFBRSxDQUFDLENBQUM7SUFDaEQsTUFBTSxPQUFPLEdBQUcsWUFBRSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFFdEQsR0FBRyxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUM3QyxNQUFNLFVBQVUsR0FBRyxpQkFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQXdCLENBQUM7SUFFN0QsR0FBRyxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUV4RSxHQUFHLENBQUMsSUFBSSxDQUNOLGFBQWEsUUFBUSxDQUFDLENBQUMsQ0FBQyxhQUFhLFFBQVEsR0FBRyxDQUFDLENBQUMsQ0FBQywrQkFBK0IsRUFBRSxDQUNyRixDQUFDO0lBQ0YsSUFBSSxDQUFDLFFBQVE7UUFBRSxPQUFPLFVBQVUsQ0FBQztJQUVqQyxNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRXpDLE9BQU8sWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUN0QyxpREFBaUQ7UUFDakQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM3QixNQUFNLElBQUksS0FBSyxDQUNiLHNDQUFzQyxHQUFHLGdCQUFnQixRQUFRLGtCQUFrQixZQUFZLEVBQUUsQ0FDbEcsQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPLE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDbkUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ2pCLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQ0c7QUFDSCxTQUFnQixhQUFhLENBQUksSUFBWSxFQUFFLElBQU87SUFDcEQsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUV0QyxHQUFHLENBQUMsS0FBSyxDQUFDLHNCQUFzQixJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3hDLEdBQUcsQ0FBQyxLQUFLLENBQUMseUJBQXlCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDcEUsTUFBTSxPQUFPLEdBQUcsaUJBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRTlELEdBQUcsQ0FBQyxLQUFLLENBQUMsaUNBQWlDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDdEQsWUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDbEUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCB5YW1sIGZyb20gXCJqcy15YW1sXCI7XG5pbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5cbmNvbnN0IGxvZ2dlciA9IExvZ2dpbmcuZm9yKFwieWFtbFwiKTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVhZHMgYW5kIHBhcnNlcyBhIFlBTUwgZmlsZSwgb3B0aW9uYWxseSByZXRyaWV2aW5nIGEgc3BlY2lmaWMgcHJvcGVydHkuXG4gKiBAc3VtbWFyeSBUaGlzIGZ1bmN0aW9uIHJlYWRzIGEgWUFNTCBmaWxlIGZyb20gdGhlIGdpdmVuIHBhdGgsIHBhcnNlcyBpdHMgY29udGVudCwgYW5kIHJldHVybnMgZWl0aGVyIHRoZSBlbnRpcmUgcGFyc2VkIFlBTUwgb2JqZWN0IG9yIGEgc3BlY2lmaWMgcHJvcGVydHkgdmFsdWUgYmFzZWQgb24gdGhlIHByb3ZpZGVkIHBhdGguXG4gKlxuICogQGZ1bmN0aW9uIHJlYWRGaWxlWWFtbFxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgcmV0dXJuZWQgdmFsdWUgd2hlbiBhIHNwZWNpZmljIHByb3BlcnR5IGlzIHJlcXVlc3RlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSB5YW1sRmlsZVBhdGggLSBUaGUgcGF0aCB0byB0aGUgWUFNTCBmaWxlIHRvIGJlIHJlYWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3ZhcmlhYmxlXSAtIE9wdGlvbmFsLiBBIGRvdC1ub3RhdGVkIHBhdGggc3RyaW5nIHRoYXQgc3BlY2lmaWVzIHRoZSBwcm9wZXJ0eSB0byByZXRyaWV2ZSBmcm9tIHRoZSBwYXJzZWQgWUFNTC5cbiAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIGFueT4gfCBUfSBSZXR1cm5zIHRoZSBlbnRpcmUgcGFyc2VkIFlBTUwgb2JqZWN0IGlmIG5vIGB2YXJpYWJsZWAgaXMgcHJvdmlkZWQsIG9yIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHByb3BlcnR5IGlmIGB2YXJpYWJsZWAgaXMgcHJvdmlkZWQuXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpmYWJyaWMtd2VhdmVyLlV0aWxzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEV4YW1wbGUgMTogUmVhZCB0aGUgZW50aXJlIFlBTUwgZmlsZVxuICogY29uc3QgY29uZmlnID0gcmVhZEZpbGVZYW1sKFwiY29uZmlnL3NldHRpbmdzLnlhbWxcIik7XG4gKiBjb25zb2xlLmxvZyhjb25maWcpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBFeGFtcGxlIDI6IFJldHJpZXZlIGEgc3BlY2lmaWMgcHJvcGVydHkgZnJvbSB0aGUgWUFNTCBmaWxlXG4gKiBjb25zdCBkYkhvc3QgPSByZWFkRmlsZVlhbWwoXCJjb25maWcvc2V0dGluZ3MueWFtbFwiLCBcImRhdGFiYXNlLmhvc3RcIik7XG4gKiBjb25zb2xlLmxvZyhkYkhvc3QpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBFeGFtcGxlIDM6IEhhbmRsZSBhbiBlcnJvciBpZiB0aGUgcHJvcGVydHkgZG9lcyBub3QgZXhpc3RcbiAqIGNvbnN0IGludmFsaWRQcm9wZXJ0eSA9IHJlYWRGaWxlWWFtbChcImNvbmZpZy9zZXR0aW5ncy55YW1sXCIsIFwic2VydmVyLnBvcnRcIik7XG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgcmVhZEZpbGVZYW1sXG4gKiAgIHBhcnRpY2lwYW50IGxvZ2dlclxuICogICBwYXJ0aWNpcGFudCBmc1xuICogICBwYXJ0aWNpcGFudCB5YW1sXG4gKlxuICogICBDYWxsZXItPj5yZWFkRmlsZVlhbWw6IENhbGwgd2l0aCB5YW1sRmlsZVBhdGggYW5kIG9wdGlvbmFsIHZhcmlhYmxlXG4gKiAgIHJlYWRGaWxlWWFtbC0+PmxvZ2dlcjogTG9nIHZlcmJvc2UgbWVzc2FnZSAoUmVhZGluZyBZQU1MIGZpbGUpXG4gKiAgIHJlYWRGaWxlWWFtbC0+PmZzOiBSZWFkIGZpbGUgY29udGVudFxuICogICByZWFkRmlsZVlhbWwtPj5sb2dnZXI6IExvZyB2ZXJib3NlIG1lc3NhZ2UgKFBhcnNlZCBZQU1MIGNvbnRlbnQpXG4gKiAgIHJlYWRGaWxlWWFtbC0+PnlhbWw6IFBhcnNlIFlBTUwgY29udGVudFxuICogICByZWFkRmlsZVlhbWwtPj5sb2dnZXI6IExvZyB2ZXJib3NlIG1lc3NhZ2UgKFBhcnNlZCBZQU1MIG9iamVjdClcbiAqICAgYWx0IHZhcmlhYmxlIGlzIHByb3ZpZGVkXG4gKiAgICAgcmVhZEZpbGVZYW1sLT4+cmVhZEZpbGVZYW1sOiBOYXZpZ2F0ZSB0aHJvdWdoIHBhcnNlZCBZQU1MIHVzaW5nIHZhcmlhYmxlIHBhdGhcbiAqICAgICBhbHQgUHJvcGVydHkgZXhpc3RzXG4gKiAgICAgICByZWFkRmlsZVlhbWwtLT4+Q2FsbGVyOiBSZXR1cm4gc3BlY2lmaWMgcHJvcGVydHkgdmFsdWVcbiAqICAgICBlbHNlIFByb3BlcnR5IGRvZXNuJ3QgZXhpc3RcbiAqICAgICAgIHJlYWRGaWxlWWFtbC0+PmxvZ2dlcjogTG9nIGVycm9yIG1lc3NhZ2VcbiAqICAgICAgIHJlYWRGaWxlWWFtbC0tPj5DYWxsZXI6IFJldHVybiBlcnJvclxuICogICAgIGVuZFxuICogICBlbHNlIHZhcmlhYmxlIGlzIG5vdCBwcm92aWRlZFxuICogICAgIHJlYWRGaWxlWWFtbC0tPj5DYWxsZXI6IFJldHVybiBlbnRpcmUgcGFyc2VkIFlBTUwgb2JqZWN0XG4gKiAgIGVuZFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZEZpbGVZYW1sPFQ+KFxuICB5YW1sRmlsZVBhdGg6IHN0cmluZyxcbiAgdmFyaWFibGU/OiBzdHJpbmdcbik6IFJlY29yZDxzdHJpbmcsIGFueT4gfCBUIHtcbiAgY29uc3QgbG9nID0gbG9nZ2VyLmZvcihyZWFkRmlsZVlhbWwpO1xuXG4gIGxvZy5kZWJ1ZyhgUmVhZGluZyBZQU1MIGZpbGU6ICR7eWFtbEZpbGVQYXRofWApO1xuICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKHlhbWxGaWxlUGF0aCwgXCJ1dGY4XCIpO1xuXG4gIGxvZy5kZWJ1ZyhgUGFyc2VkIFlBTUwgY29udGVudDogJHtjb250ZW50fWApO1xuICBjb25zdCBwYXJzZWRZQU1MID0geWFtbC5sb2FkKGNvbnRlbnQpIGFzIFJlY29yZDxzdHJpbmcsIGFueT47XG5cbiAgbG9nLmRlYnVnKGBQYXJzZWQgWUFNTCBvYmplY3Q6ICR7SlNPTi5zdHJpbmdpZnkocGFyc2VkWUFNTCwgbnVsbCwgMil9YCk7XG5cbiAgbG9nLmluZm8oXG4gICAgYFJldHVybmluZyAke3ZhcmlhYmxlID8gYHByb3BlcnR5ICcke3ZhcmlhYmxlfSdgIDogXCJ0aGUgZW50aXJlIHBhcnNlZCBZQU1MIG9iamVjdFwifWBcbiAgKTtcbiAgaWYgKCF2YXJpYWJsZSkgcmV0dXJuIHBhcnNlZFlBTUw7XG5cbiAgY29uc3QgdmFyaWFibGVQYXRoID0gdmFyaWFibGUuc3BsaXQoXCIuXCIpO1xuXG4gIHJldHVybiB2YXJpYWJsZVBhdGgucmVkdWNlKChhY2MsIGtleSkgPT4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wcm90b3R5cGUtYnVpbHRpbnNcbiAgICBpZiAoIWFjYy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBVbmFibGUgdG8gbG9jYXRlIGEgcHJvcGVydHkgbmFtZWQgJyR7a2V5fScgZnJvbSBwYXRoICcke3ZhcmlhYmxlfScgaW4gZmlsZTogXFxuPiAke3lhbWxGaWxlUGF0aH1gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdHlwZW9mIGFjY1trZXldID09PSBcInN0cmluZ1wiID8gYWNjW2tleV0udHJpbSgpIDogYWNjW2tleV07XG4gIH0sIHBhcnNlZFlBTUwpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBXcml0ZXMgYSBKU09OIG9iamVjdCB0byBhIFlBTUwgZmlsZS5cbiAqIEBzdW1tYXJ5IFRoaXMgZnVuY3Rpb24gdGFrZXMgYSBKU09OIG9iamVjdCBhbmQgd3JpdGVzIGl0IHRvIGEgc3BlY2lmaWVkIGZpbGUgcGF0aCBpbiBZQU1MIGZvcm1hdC5cbiAqIEl0IHVzZXMganMteWFtbCB0byBjb252ZXJ0IHRoZSBKU09OIHRvIFlBTUwsIGFuZCB0aGVuIHdyaXRlcyB0aGUgY29udGVudCB0byB0aGUgZmlsZS5cbiAqXG4gKiBAZnVuY3Rpb24gd3JpdGVGaWxlWWFtbFxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgSlNPTiBvYmplY3QgdG8gYmUgd3JpdHRlbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIGZpbGUgcGF0aCB3aGVyZSB0aGUgWUFNTCBjb250ZW50IHdpbGwgYmUgd3JpdHRlbi5cbiAqIEBwYXJhbSB7VH0ganNvbiAtIFRoZSBKU09OIG9iamVjdCB0byBiZSBjb252ZXJ0ZWQgdG8gWUFNTCBhbmQgd3JpdHRlbiB0byB0aGUgZmlsZS5cbiAqIEByZXR1cm4ge3ZvaWR9XG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpmYWJyaWMtd2VhdmVyLlV0aWxzXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGNvbmZpZyA9IHsgZGF0YWJhc2U6IHsgaG9zdDogJ2xvY2FsaG9zdCcsIHBvcnQ6IDU0MzIgfSB9O1xuICogd3JpdGVGaWxlWWFtbCgnY29uZmlnL3NldHRpbmdzLnlhbWwnLCBjb25maWcpO1xuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IHdyaXRlRmlsZVlhbWxcbiAqICAgcGFydGljaXBhbnQgbG9nZ2VyXG4gKiAgIHBhcnRpY2lwYW50IHlhbWxcbiAqICAgcGFydGljaXBhbnQgZnNcbiAqXG4gKiAgIENhbGxlci0+PndyaXRlRmlsZVlhbWw6IENhbGwgd2l0aCBwYXRoIGFuZCBKU09OXG4gKiAgIHdyaXRlRmlsZVlhbWwtPj5sb2dnZXI6IExvZyB2ZXJib3NlIG1lc3NhZ2UgKFdyaXRpbmcgWUFNTCBmaWxlKVxuICogICB3cml0ZUZpbGVZYW1sLT4+bG9nZ2VyOiBMb2cgdmVyYm9zZSBtZXNzYWdlIChXcml0aW5nIFlBTUwgY29udGVudClcbiAqICAgd3JpdGVGaWxlWWFtbC0+PnlhbWw6IENvbnZlcnQgSlNPTiB0byBZQU1MXG4gKiAgIHdyaXRlRmlsZVlhbWwtPj5sb2dnZXI6IExvZyB2ZXJib3NlIG1lc3NhZ2UgKFdyaXRpbmcgWUFNTCBjb250ZW50IHRvIGZpbGUpXG4gKiAgIHdyaXRlRmlsZVlhbWwtPj5mczogV3JpdGUgWUFNTCBjb250ZW50IHRvIGZpbGVcbiAqICAgd3JpdGVGaWxlWWFtbC0tPj5DYWxsZXI6IFJldHVybiAodm9pZClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRlRmlsZVlhbWw8VD4ocGF0aDogc3RyaW5nLCBqc29uOiBUKSB7XG4gIGNvbnN0IGxvZyA9IGxvZ2dlci5mb3Iod3JpdGVGaWxlWWFtbCk7XG5cbiAgbG9nLmRlYnVnKGBXcml0aW5nIFlBTUwgZmlsZTogJHtwYXRofWApO1xuICBsb2cuZGVidWcoYFdyaXRpbmcgWUFNTCBjb250ZW50OiAke0pTT04uc3RyaW5naWZ5KGpzb24sIG51bGwsIDIpfWApO1xuICBjb25zdCBjb250ZW50ID0geWFtbC5kdW1wKGpzb24sIHsgaW5kZW50OiAyLCBsaW5lV2lkdGg6IC0xIH0pO1xuXG4gIGxvZy5kZWJ1ZyhgV3JpdGluZyBZQU1MIGNvbnRlbnQgdG8gZmlsZTogJHtjb250ZW50fWApO1xuICBmcy53cml0ZUZpbGVTeW5jKHBhdGgsIGNvbnRlbnQucmVwbGFjZSgvIG51bGwkL2dtLCBcIlwiKSwgXCJ1dGY4XCIpO1xufVxuIl19