@decaf-ts/fabric-weaver
Version:
template for ts projects
306 lines (297 loc) • 38.3 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@decaf-ts/utils'), require('fs'), require('path'), require('js-yaml'), require('@decaf-ts/logging'), require('child_process')) :
typeof define === 'function' && define.amd ? define(['exports', '@decaf-ts/utils', 'fs', 'path', 'js-yaml', '@decaf-ts/logging', 'child_process'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["fabric-weaver"] = {}, global.utils, global.fs, global.path, global.yaml, global.logging, global.child_process));
})(this, (function (exports, utils, fs, path, yaml, logging, child_process) { 'use strict';
/**
* @module build-scripts
* @description Custom build scripts for the fabric-weaver project.
* @summary This module extends the BuildScripts class from @decaf-ts/utils to provide custom build functionality for the fabric-weaver project. It includes utilities for building command-line interfaces and handling different module formats (CommonJS and ES Modules).
*/
/**
* @description Enumeration of module modes.
* @summary Defines the different module formats supported in the build process.
* @enum {string}
* @readonly
* @memberOf module:build-scripts
*/
var Modes;
(function (Modes) {
/** CommonJS module format */
Modes["CJS"] = "commonjs";
/** ECMAScript module format (ES2022) */
Modes["ESM"] = "es2022";
})(Modes || (Modes = {}));
/**
* @description Custom build scripts for the fabric-weaver project.
* @summary Extends the BuildScripts class to provide project-specific build functionality, including command bundling and file manipulation.
* @class BuildScriptsCustom
* @extends BuildScripts
*/
class BuildScriptsCustom extends utils.BuildScripts {
/**
* @description Builds command-line interfaces for the project.
* @summary Processes each command in the Commands array, bundling the TypeScript files, adding a shebang line, and setting appropriate permissions.
* @return {Promise<void>}
* @mermaid
* sequenceDiagram
* participant BuildScriptsCustom
* participant FileSystem
* loop For each command
* BuildScriptsCustom->>BuildScriptsCustom: bundle(Modes.CJS, true, true, `src/bin/${cmd}.ts`, cmd)
* BuildScriptsCustom->>FileSystem: readFile(`bin/${cmd}.cjs`)
* FileSystem-->>BuildScriptsCustom: file content
* BuildScriptsCustom->>BuildScriptsCustom: Add shebang to file content
* BuildScriptsCustom->>FileSystem: writeFile(`bin/${cmd}.cjs`, modified content)
* BuildScriptsCustom->>FileSystem: chmodSync(`bin/${cmd}.cjs`, "755")
* end
*/
async buildCommands() {
const commands = fs.readdirSync(path.join(process.cwd() + "/src/bin"));
for (const cmd of commands) {
if (!cmd.endsWith(".ts"))
continue;
await this.bundle(Modes.CJS, true, true, `src/bin/${cmd}`, cmd);
let data = utils.readFile(`bin/${cmd}.cjs`);
data = "#!/usr/bin/env node\n" + data;
utils.writeFile(`bin/${cmd}.cjs`, data);
fs.chmodSync(`bin/${cmd}.cjs`, "755");
}
}
}
const COMMA_SEPARATOR = ",";
const SLASH_SEPARATOR = "/";
function safeParseJSON(v) {
try {
return JSON.parse(v);
}
catch (e) {
throw new Error(`Invalid JSON: ${e.message}`);
}
}
function safeParseInt(v) {
if (typeof v === "number")
return Math.floor(v);
const value = Number(v);
if (!Number.isInteger(value)) {
throw new Error(`Invalid integer value: ${v}`);
}
return value;
}
function safeParseCSV(csv) {
if (!csv.trim())
return [];
return csv.split(COMMA_SEPARATOR).map((item) => item.trim());
}
function safeParseSSV(csv) {
console.log(csv);
if (!csv.trim())
return [];
return csv.split(SLASH_SEPARATOR).map((item) => `"${item.trim()}"`);
}
function mapParser(map) {
const argz = Array.from(map, ([key, value]) => {
if (typeof value === "boolean") {
return value ? [`--${key}`] : [];
}
if (Array.isArray(value)) {
return [`--${key}`, value.join(",")];
}
return [`--${key}`, value.toString()];
});
return argz.map((el) => el.join(" "));
}
const logger = logging.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.readFileSync(yamlFilePath, "utf8");
log.debug(`Parsed YAML content: ${content}`);
const parsedYAML = yaml.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 = yaml.dump(json, { indent: 2, lineWidth: -1 });
log.debug(`Writing YAML content to file: ${content}`);
fs.writeFileSync(path, content.replace(/ null$/gm, ""), "utf8");
}
async function runCommand(command, args = [], options = { stdio: "inherit" }, logMatch) {
const log = logging.Logging.for(runCommand);
log.info(`Running command: ${command} ${args.join(" ")}`);
if (!logMatch)
return child_process.execSync([command, ...args].join(" "), options);
return new Promise((resolve, reject) => {
const child = child_process.spawn(command, args, options);
let stdoutData = "";
let stderrData = "";
const checkMatch = (data) => {
if (logMatch && logMatch.test(data)) {
resolve(child);
}
};
child.stdout.on("data", (data) => {
const strData = data.toString();
console.log(strData);
stdoutData += strData;
checkMatch(strData);
});
child.stderr.on("data", (data) => {
const strData = data.toString();
console.error(strData);
stderrData += strData;
checkMatch(strData);
});
child.on("error", (err) => {
reject(err);
});
child.on("close", (code) => {
if (code === 0) {
resolve(child);
}
else {
reject(new Error(`Process exited with code ${code}\nStdout: ${stdoutData}\nStderr: ${stderrData}`));
}
});
});
}
/**
* @module fabric-weaver
* @description This module serves as the main entry point for the fabric-weaver library, providing TypeScript integration with Hyperledger Fabric.
* @summary Aggregates and exports functionality for managing Hyperledger Fabric infrastructures.
*
* The module includes:
* 1. Utility functions and types from the "./utils" directory:
* - Helper functions for interacting with Fabric binaries.
* - Utilities for generating and managing Docker Compose files.
* - Functions to assist in creating, maintaining, and updating Hyperledger Fabric networks.
*
* 2. Core functionality from the "./core" directory:
* - TypeScript interfaces and classes representing Fabric concepts.
* - Implementation of Fabric operations and interactions.
*
* 3. A VERSION constant:
* - Represents the current version of the fabric-weaver module.
* - Useful for version checking and compatibility purposes.
*
* This structure provides a comprehensive toolkit for working with Hyperledger Fabric in TypeScript,
* allowing developers to easily set up, manage, and interact with Fabric networks and components.
*/
/**
* @const VERSION
* @name VERSION
* @description Represents the current version of the fabric-weaver module.
* @summary The actual version number is replaced during the build process.
* @type {string}
*/
const VERSION = "0.0.14";
exports.BuildScriptsCustom = BuildScriptsCustom;
exports.VERSION = VERSION;
exports.mapParser = mapParser;
exports.readFileYaml = readFileYaml;
exports.runCommand = runCommand;
exports.safeParseCSV = safeParseCSV;
exports.safeParseInt = safeParseInt;
exports.safeParseJSON = safeParseJSON;
exports.safeParseSSV = safeParseSSV;
exports.writeFileYaml = writeFileYaml;
}));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFicmljLXdlYXZlci5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy91dGlscy1vbGQvYnVpbGQtc2NyaXB0cy50cyIsIi4uL3NyYy9jb3JlL2NvbnN0YW50cy9jb25zdGFudHMudHMiLCIuLi9zcmMvdXRpbHMvcGFyc2Vycy50cyIsIi4uL3NyYy91dGlscy95YW1sLnRzIiwiLi4vc3JjL3V0aWxzL2NoaWxkLXByb2Nlc3MudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIGJ1aWxkLXNjcmlwdHNcbiAqIEBkZXNjcmlwdGlvbiBDdXN0b20gYnVpbGQgc2NyaXB0cyBmb3IgdGhlIGZhYnJpYy13ZWF2ZXIgcHJvamVjdC5cbiAqIEBzdW1tYXJ5IFRoaXMgbW9kdWxlIGV4dGVuZHMgdGhlIEJ1aWxkU2NyaXB0cyBjbGFzcyBmcm9tIEBkZWNhZi10cy91dGlscyB0byBwcm92aWRlIGN1c3RvbSBidWlsZCBmdW5jdGlvbmFsaXR5IGZvciB0aGUgZmFicmljLXdlYXZlciBwcm9qZWN0LiBJdCBpbmNsdWRlcyB1dGlsaXRpZXMgZm9yIGJ1aWxkaW5nIGNvbW1hbmQtbGluZSBpbnRlcmZhY2VzIGFuZCBoYW5kbGluZyBkaWZmZXJlbnQgbW9kdWxlIGZvcm1hdHMgKENvbW1vbkpTIGFuZCBFUyBNb2R1bGVzKS5cbiAqL1xuXG5pbXBvcnQgeyBCdWlsZFNjcmlwdHMsIHJlYWRGaWxlLCB3cml0ZUZpbGUgfSBmcm9tIFwiQGRlY2FmLXRzL3V0aWxzXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFbnVtZXJhdGlvbiBvZiBtb2R1bGUgbW9kZXMuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBkaWZmZXJlbnQgbW9kdWxlIGZvcm1hdHMgc3VwcG9ydGVkIGluIHRoZSBidWlsZCBwcm9jZXNzLlxuICogQGVudW0ge3N0cmluZ31cbiAqIEByZWFkb25seVxuICogQG1lbWJlck9mIG1vZHVsZTpidWlsZC1zY3JpcHRzXG4gKi9cbmVudW0gTW9kZXMge1xuICAvKiogQ29tbW9uSlMgbW9kdWxlIGZvcm1hdCAqL1xuICBDSlMgPSBcImNvbW1vbmpzXCIsXG4gIC8qKiBFQ01BU2NyaXB0IG1vZHVsZSBmb3JtYXQgKEVTMjAyMikgKi9cbiAgRVNNID0gXCJlczIwMjJcIixcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3VzdG9tIGJ1aWxkIHNjcmlwdHMgZm9yIHRoZSBmYWJyaWMtd2VhdmVyIHByb2plY3QuXG4gKiBAc3VtbWFyeSBFeHRlbmRzIHRoZSBCdWlsZFNjcmlwdHMgY2xhc3MgdG8gcHJvdmlkZSBwcm9qZWN0LXNwZWNpZmljIGJ1aWxkIGZ1bmN0aW9uYWxpdHksIGluY2x1ZGluZyBjb21tYW5kIGJ1bmRsaW5nIGFuZCBmaWxlIG1hbmlwdWxhdGlvbi5cbiAqIEBjbGFzcyBCdWlsZFNjcmlwdHNDdXN0b21cbiAqIEBleHRlbmRzIEJ1aWxkU2NyaXB0c1xuICovXG5leHBvcnQgY2xhc3MgQnVpbGRTY3JpcHRzQ3VzdG9tIGV4dGVuZHMgQnVpbGRTY3JpcHRzIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBCdWlsZHMgY29tbWFuZC1saW5lIGludGVyZmFjZXMgZm9yIHRoZSBwcm9qZWN0LlxuICAgKiBAc3VtbWFyeSBQcm9jZXNzZXMgZWFjaCBjb21tYW5kIGluIHRoZSBDb21tYW5kcyBhcnJheSwgYnVuZGxpbmcgdGhlIFR5cGVTY3JpcHQgZmlsZXMsIGFkZGluZyBhIHNoZWJhbmcgbGluZSwgYW5kIHNldHRpbmcgYXBwcm9wcmlhdGUgcGVybWlzc2lvbnMuXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59XG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IEJ1aWxkU2NyaXB0c0N1c3RvbVxuICAgKiAgIHBhcnRpY2lwYW50IEZpbGVTeXN0ZW1cbiAgICogICBsb29wIEZvciBlYWNoIGNvbW1hbmRcbiAgICogICAgIEJ1aWxkU2NyaXB0c0N1c3RvbS0+PkJ1aWxkU2NyaXB0c0N1c3RvbTogYnVuZGxlKE1vZGVzLkNKUywgdHJ1ZSwgdHJ1ZSwgYHNyYy9iaW4vJHtjbWR9LnRzYCwgY21kKVxuICAgKiAgICAgQnVpbGRTY3JpcHRzQ3VzdG9tLT4+RmlsZVN5c3RlbTogcmVhZEZpbGUoYGJpbi8ke2NtZH0uY2pzYClcbiAgICogICAgIEZpbGVTeXN0ZW0tLT4+QnVpbGRTY3JpcHRzQ3VzdG9tOiBmaWxlIGNvbnRlbnRcbiAgICogICAgIEJ1aWxkU2NyaXB0c0N1c3RvbS0+PkJ1aWxkU2NyaXB0c0N1c3RvbTogQWRkIHNoZWJhbmcgdG8gZmlsZSBjb250ZW50XG4gICAqICAgICBCdWlsZFNjcmlwdHNDdXN0b20tPj5GaWxlU3lzdGVtOiB3cml0ZUZpbGUoYGJpbi8ke2NtZH0uY2pzYCwgbW9kaWZpZWQgY29udGVudClcbiAgICogICAgIEJ1aWxkU2NyaXB0c0N1c3RvbS0+PkZpbGVTeXN0ZW06IGNobW9kU3luYyhgYmluLyR7Y21kfS5janNgLCBcIjc1NVwiKVxuICAgKiAgIGVuZFxuICAgKi9cbiAgYXN5bmMgYnVpbGRDb21tYW5kcygpIHtcbiAgICBjb25zdCBjb21tYW5kcyA9IGZzLnJlYWRkaXJTeW5jKHBhdGguam9pbihwcm9jZXNzLmN3ZCgpICsgXCIvc3JjL2JpblwiKSk7XG4gICAgZm9yIChjb25zdCBjbWQgb2YgY29tbWFuZHMpIHtcbiAgICAgIGlmICghY21kLmVuZHNXaXRoKFwiLnRzXCIpKSBjb250aW51ZTtcblxuICAgICAgYXdhaXQgdGhpcy5idW5kbGUoTW9kZXMuQ0pTLCB0cnVlLCB0cnVlLCBgc3JjL2Jpbi8ke2NtZH1gLCBjbWQpO1xuICAgICAgbGV0IGRhdGEgPSByZWFkRmlsZShgYmluLyR7Y21kfS5janNgKTtcbiAgICAgIGRhdGEgPSBcIiMhL3Vzci9iaW4vZW52IG5vZGVcXG5cIiArIGRhdGE7XG4gICAgICB3cml0ZUZpbGUoYGJpbi8ke2NtZH0uY2pzYCwgZGF0YSk7XG4gICAgICBmcy5jaG1vZFN5bmMoYGJpbi8ke2NtZH0uY2pzYCwgXCI3NTVcIik7XG4gICAgfVxuICB9XG59XG4iLCJleHBvcnQgY29uc3QgQ09NTUFfU0VQQVJBVE9SID0gXCIsXCI7XG5leHBvcnQgY29uc3QgQ09MT05fU0VQQVJBVE9SID0gXCI6XCI7XG5leHBvcnQgY29uc3QgUElQRV9TRVBBUkFUT1IgPSBcInxcIjtcbmV4cG9ydCBjb25zdCBTTEFTSF9TRVBBUkFUT1IgPSBcIi9cIjtcblxuZXhwb3J0IGNvbnN0IE5BTUVfUExBQ0VIT0xERVIgPSBcIiMjTkFNRSMjXCI7XG5leHBvcnQgY29uc3QgVkVSU0lPTl9QTEFDRUhPTERFUiA9IFwiIyNWRVIjI1wiO1xuZXhwb3J0IGNvbnN0IEVOVFJZX1BMQUNFSE9MREVSID0gXCIjI0VOVFJZIyNcIjtcbiIsImltcG9ydCB7IENPTU1BX1NFUEFSQVRPUiwgU0xBU0hfU0VQQVJBVE9SIH0gZnJvbSBcIi4uL2NvcmUvY29uc3RhbnRzL2NvbnN0YW50c1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gc2FmZVBhcnNlSlNPTih2OiBzdHJpbmcpOiB1bmtub3duIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZSh2KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBKU09OOiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzYWZlUGFyc2VJbnQodjogc3RyaW5nIHwgbnVtYmVyKTogbnVtYmVyIHtcbiAgaWYgKHR5cGVvZiB2ID09PSBcIm51bWJlclwiKSByZXR1cm4gTWF0aC5mbG9vcih2KTtcblxuICBjb25zdCB2YWx1ZSA9IE51bWJlcih2KTtcblxuICBpZiAoIU51bWJlci5pc0ludGVnZXIodmFsdWUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGludGVnZXIgdmFsdWU6ICR7dn1gKTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhZmVQYXJzZUNTVihjc3Y6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgaWYgKCFjc3YudHJpbSgpKSByZXR1cm4gW107XG5cbiAgcmV0dXJuIGNzdi5zcGxpdChDT01NQV9TRVBBUkFUT1IpLm1hcCgoaXRlbSkgPT4gaXRlbS50cmltKCkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2FmZVBhcnNlU1NWKGNzdjogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zb2xlLmxvZyhjc3YpO1xuICBpZiAoIWNzdi50cmltKCkpIHJldHVybiBbXTtcblxuICByZXR1cm4gY3N2LnNwbGl0KFNMQVNIX1NFUEFSQVRPUikubWFwKChpdGVtKSA9PiBgXCIke2l0ZW0udHJpbSgpfVwiYCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXBQYXJzZXIoXG4gIG1hcDogTWFwPHN0cmluZywgc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IHN0cmluZ1tdPlxuKTogc3RyaW5nW10ge1xuICBjb25zdCBhcmd6ID0gQXJyYXkuZnJvbShtYXAsIChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcImJvb2xlYW5cIikge1xuICAgICAgcmV0dXJuIHZhbHVlID8gW2AtLSR7a2V5fWBdIDogW107XG4gICAgfVxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIFtgLS0ke2tleX1gLCB2YWx1ZS5qb2luKFwiLFwiKV07XG4gICAgfVxuICAgIHJldHVybiBbYC0tJHtrZXl9YCwgdmFsdWUudG9TdHJpbmcoKV07XG4gIH0pO1xuXG4gIHJldHVybiBhcmd6Lm1hcCgoZWwpID0+IGVsLmpvaW4oXCIgXCIpKTtcbn1cbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCB5YW1sIGZyb20gXCJqcy15YW1sXCI7XG5pbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5cbmNvbnN0IGxvZ2dlciA9IExvZ2dpbmcuZm9yKFwieWFtbFwiKTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVhZHMgYW5kIHBhcnNlcyBhIFlBTUwgZmlsZSwgb3B0aW9uYWxseSByZXRyaWV2aW5nIGEgc3BlY2lmaWMgcHJvcGVydHkuXG4gKiBAc3VtbWFyeSBUaGlzIGZ1bmN0aW9uIHJlYWRzIGEgWUFNTCBmaWxlIGZyb20gdGhlIGdpdmVuIHBhdGgsIHBhcnNlcyBpdHMgY29udGVudCwgYW5kIHJldHVybnMgZWl0aGVyIHRoZSBlbnRpcmUgcGFyc2VkIFlBTUwgb2JqZWN0IG9yIGEgc3BlY2lmaWMgcHJvcGVydHkgdmFsdWUgYmFzZWQgb24gdGhlIHByb3ZpZGVkIHBhdGguXG4gKlxuICogQGZ1bmN0aW9uIHJlYWRGaWxlWWFtbFxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgcmV0dXJuZWQgdmFsdWUgd2hlbiBhIHNwZWNpZmljIHByb3BlcnR5IGlzIHJlcXVlc3RlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSB5YW1sRmlsZVBhdGggLSBUaGUgcGF0aCB0byB0aGUgWUFNTCBmaWxlIHRvIGJlIHJlYWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3ZhcmlhYmxlXSAtIE9wdGlvbmFsLiBBIGRvdC1ub3RhdGVkIHBhdGggc3RyaW5nIHRoYXQgc3BlY2lmaWVzIHRoZSBwcm9wZXJ0eSB0byByZXRyaWV2ZSBmcm9tIHRoZSBwYXJzZWQgWUFNTC5cbiAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIGFueT4gfCBUfSBSZXR1cm5zIHRoZSBlbnRpcmUgcGFyc2VkIFlBTUwgb2JqZWN0IGlmIG5vIGB2YXJpYWJsZWAgaXMgcHJvdmlkZWQsIG9yIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHByb3BlcnR5IGlmIGB2YXJpYWJsZWAgaXMgcHJvdmlkZWQuXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpmYWJyaWMtd2VhdmVyLlV0aWxzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEV4YW1wbGUgMTogUmVhZCB0aGUgZW50aXJlIFlBTUwgZmlsZVxuICogY29uc3QgY29uZmlnID0gcmVhZEZpbGVZYW1sKFwiY29uZmlnL3NldHRpbmdzLnlhbWxcIik7XG4gKiBjb25zb2xlLmxvZyhjb25maWcpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBFeGFtcGxlIDI6IFJldHJpZXZlIGEgc3BlY2lmaWMgcHJvcGVydHkgZnJvbSB0aGUgWUFNTCBmaWxlXG4gKiBjb25zdCBkYkhvc3QgPSByZWFkRmlsZVlhbWwoXCJjb25maWcvc2V0dGluZ3MueWFtbFwiLCBcImRhdGFiYXNlLmhvc3RcIik7XG4gKiBjb25zb2xlLmxvZyhkYkhvc3QpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBFeGFtcGxlIDM6IEhhbmRsZSBhbiBlcnJvciBpZiB0aGUgcHJvcGVydHkgZG9lcyBub3QgZXhpc3RcbiAqIGNvbnN0IGludmFsaWRQcm9wZXJ0eSA9IHJlYWRGaWxlWWFtbChcImNvbmZpZy9zZXR0aW5ncy55YW1sXCIsIFwic2VydmVyLnBvcnRcIik7XG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgcmVhZEZpbGVZYW1sXG4gKiAgIHBhcnRpY2lwYW50IGxvZ2dlclxuICogICBwYXJ0aWNpcGFudCBmc1xuICogICBwYXJ0aWNpcGFudCB5YW1sXG4gKlxuICogICBDYWxsZXItPj5yZWFkRmlsZVlhbWw6IENhbGwgd2l0aCB5YW1sRmlsZVBhdGggYW5kIG9wdGlvbmFsIHZhcmlhYmxlXG4gKiAgIHJlYWRGaWxlWWFtbC0+PmxvZ2dlcjogTG9nIHZlcmJvc2UgbWVzc2FnZSAoUmVhZGluZyBZQU1MIGZpbGUpXG4gKiAgIHJlYWRGaWxlWWFtbC0+PmZzOiBSZWFkIGZpbGUgY29udGVudFxuICogICByZWFkRmlsZVlhbWwtPj5sb2dnZXI6IExvZyB2ZXJib3NlIG1lc3NhZ2UgKFBhcnNlZCBZQU1MIGNvbnRlbnQpXG4gKiAgIHJlYWRGaWxlWWFtbC0+PnlhbWw6IFBhcnNlIFlBTUwgY29udGVudFxuICogICByZWFkRmlsZVlhbWwtPj5sb2dnZXI6IExvZyB2ZXJib3NlIG1lc3NhZ2UgKFBhcnNlZCBZQU1MIG9iamVjdClcbiAqICAgYWx0IHZhcmlhYmxlIGlzIHByb3ZpZGVkXG4gKiAgICAgcmVhZEZpbGVZYW1sLT4+cmVhZEZpbGVZYW1sOiBOYXZpZ2F0ZSB0aHJvdWdoIHBhcnNlZCBZQU1MIHVzaW5nIHZhcmlhYmxlIHBhdGhcbiAqICAgICBhbHQgUHJvcGVydHkgZXhpc3RzXG4gKiAgICAgICByZWFkRmlsZVlhbWwtLT4+Q2FsbGVyOiBSZXR1cm4gc3BlY2lmaWMgcHJvcGVydHkgdmFsdWVcbiAqICAgICBlbHNlIFByb3BlcnR5IGRvZXNuJ3QgZXhpc3RcbiAqICAgICAgIHJlYWRGaWxlWWFtbC0+PmxvZ2dlcjogTG9nIGVycm9yIG1lc3NhZ2VcbiAqICAgICAgIHJlYWRGaWxlWWFtbC0tPj5DYWxsZXI6IFJldHVybiBlcnJvclxuICogICAgIGVuZFxuICogICBlbHNlIHZhcmlhYmxlIGlzIG5vdCBwcm92aWRlZFxuICogICAgIHJlYWRGaWxlWWFtbC0tPj5DYWxsZXI6IFJldHVybiBlbnRpcmUgcGFyc2VkIFlBTUwgb2JqZWN0XG4gKiAgIGVuZFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZEZpbGVZYW1sPFQ+KFxuICB5YW1sRmlsZVBhdGg6IHN0cmluZyxcbiAgdmFyaWFibGU/OiBzdHJpbmdcbik6IFJlY29yZDxzdHJpbmcsIGFueT4gfCBUIHtcbiAgY29uc3QgbG9nID0gbG9nZ2VyLmZvcihyZWFkRmlsZVlhbWwpO1xuXG4gIGxvZy5kZWJ1ZyhgUmVhZGluZyBZQU1MIGZpbGU6ICR7eWFtbEZpbGVQYXRofWApO1xuICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKHlhbWxGaWxlUGF0aCwgXCJ1dGY4XCIpO1xuXG4gIGxvZy5kZWJ1ZyhgUGFyc2VkIFlBTUwgY29udGVudDogJHtjb250ZW50fWApO1xuICBjb25zdCBwYXJzZWRZQU1MID0geWFtbC5sb2FkKGNvbnRlbnQpIGFzIFJlY29yZDxzdHJpbmcsIGFueT47XG5cbiAgbG9nLmRlYnVnKGBQYXJzZWQgWUFNTCBvYmplY3Q6ICR7SlNPTi5zdHJpbmdpZnkocGFyc2VkWUFNTCwgbnVsbCwgMil9YCk7XG5cbiAgbG9nLmluZm8oXG4gICAgYFJldHVybmluZyAke3ZhcmlhYmxlID8gYHByb3BlcnR5ICcke3ZhcmlhYmxlfSdgIDogXCJ0aGUgZW50aXJlIHBhcnNlZCBZQU1MIG9iamVjdFwifWBcbiAgKTtcbiAgaWYgKCF2YXJpYWJsZSkgcmV0dXJuIHBhcnNlZFlBTUw7XG5cbiAgY29uc3QgdmFyaWFibGVQYXRoID0gdmFyaWFibGUuc3BsaXQoXCIuXCIpO1xuXG4gIHJldHVybiB2YXJpYWJsZVBhdGgucmVkdWNlKChhY2MsIGtleSkgPT4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wcm90b3R5cGUtYnVpbHRpbnNcbiAgICBpZiAoIWFjYy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBVbmFibGUgdG8gbG9jYXRlIGEgcHJvcGVydHkgbmFtZWQgJyR7a2V5fScgZnJvbSBwYXRoICcke3ZhcmlhYmxlfScgaW4gZmlsZTogXFxuPiAke3lhbWxGaWxlUGF0aH1gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdHlwZW9mIGFjY1trZXldID09PSBcInN0cmluZ1wiID8gYWNjW2tleV0udHJpbSgpIDogYWNjW2tleV07XG4gIH0sIHBhcnNlZFlBTUwpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBXcml0ZXMgYSBKU09OIG9iamVjdCB0byBhIFlBTUwgZmlsZS5cbiAqIEBzdW1tYXJ5IFRoaXMgZnVuY3Rpb24gdGFrZXMgYSBKU09OIG9iamVjdCBhbmQgd3JpdGVzIGl0IHRvIGEgc3BlY2lmaWVkIGZpbGUgcGF0aCBpbiBZQU1MIGZvcm1hdC5cbiAqIEl0IHVzZXMganMteWFtbCB0byBjb252ZXJ0IHRoZSBKU09OIHRvIFlBTUwsIGFuZCB0aGVuIHdyaXRlcyB0aGUgY29udGVudCB0byB0aGUgZmlsZS5cbiAqXG4gKiBAZnVuY3Rpb24gd3JpdGVGaWxlWWFtbFxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgSlNPTiBvYmplY3QgdG8gYmUgd3JpdHRlbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIGZpbGUgcGF0aCB3aGVyZSB0aGUgWUFNTCBjb250ZW50IHdpbGwgYmUgd3JpdHRlbi5cbiAqIEBwYXJhbSB7VH0ganNvbiAtIFRoZSBKU09OIG9iamVjdCB0byBiZSBjb252ZXJ0ZWQgdG8gWUFNTCBhbmQgd3JpdHRlbiB0byB0aGUgZmlsZS5cbiAqIEByZXR1cm4ge3ZvaWR9XG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpmYWJyaWMtd2VhdmVyLlV0aWxzXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGNvbmZpZyA9IHsgZGF0YWJhc2U6IHsgaG9zdDogJ2xvY2FsaG9zdCcsIHBvcnQ6IDU0MzIgfSB9O1xuICogd3JpdGVGaWxlWWFtbCgnY29uZmlnL3NldHRpbmdzLnlhbWwnLCBjb25maWcpO1xuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IHdyaXRlRmlsZVlhbWxcbiAqICAgcGFydGljaXBhbnQgbG9nZ2VyXG4gKiAgIHBhcnRpY2lwYW50IHlhbWxcbiAqICAgcGFydGljaXBhbnQgZnNcbiAqXG4gKiAgIENhbGxlci0+PndyaXRlRmlsZVlhbWw6IENhbGwgd2l0aCBwYXRoIGFuZCBKU09OXG4gKiAgIHdyaXRlRmlsZVlhbWwtPj5sb2dnZXI6IExvZyB2ZXJib3NlIG1lc3NhZ2UgKFdyaXRpbmcgWUFNTCBmaWxlKVxuICogICB3cml0ZUZpbGVZYW1sLT4+bG9nZ2VyOiBMb2cgdmVyYm9zZSBtZXNzYWdlIChXcml0aW5nIFlBTUwgY29udGVudClcbiAqICAgd3JpdGVGaWxlWWFtbC0+PnlhbWw6IENvbnZlcnQgSlNPTiB0byBZQU1MXG4gKiAgIHdyaXRlRmlsZVlhbWwtPj5sb2dnZXI6IExvZyB2ZXJib3NlIG1lc3NhZ2UgKFdyaXRpbmcgWUFNTCBjb250ZW50IHRvIGZpbGUpXG4gKiAgIHdyaXRlRmlsZVlhbWwtPj5mczogV3JpdGUgWUFNTCBjb250ZW50IHRvIGZpbGVcbiAqICAgd3JpdGVGaWxlWWFtbC0tPj5DYWxsZXI6IFJldHVybiAodm9pZClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRlRmlsZVlhbWw8VD4ocGF0aDogc3RyaW5nLCBqc29uOiBUKSB7XG4gIGNvbnN0IGxvZyA9IGxvZ2dlci5mb3Iod3JpdGVGaWxlWWFtbCk7XG5cbiAgbG9nLmRlYnVnKGBXcml0aW5nIFlBTUwgZmlsZTogJHtwYXRofWApO1xuICBsb2cuZGVidWcoYFdyaXRpbmcgWUFNTCBjb250ZW50OiAke0pTT04uc3RyaW5naWZ5KGpzb24sIG51bGwsIDIpfWApO1xuICBjb25zdCBjb250ZW50ID0geWFtbC5kdW1wKGpzb24sIHsgaW5kZW50OiAyLCBsaW5lV2lkdGg6IC0xIH0pO1xuXG4gIGxvZy5kZWJ1ZyhgV3JpdGluZyBZQU1MIGNvbnRlbnQgdG8gZmlsZTogJHtjb250ZW50fWApO1xuICBmcy53cml0ZUZpbGVTeW5jKHBhdGgsIGNvbnRlbnQucmVwbGFjZSgvIG51bGwkL2dtLCBcIlwiKSwgXCJ1dGY4XCIpO1xufVxuIiwiaW1wb3J0IHsgc3Bhd24sIENoaWxkUHJvY2VzcywgZXhlY1N5bmMgfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBydW5Db21tYW5kKFxuICBjb21tYW5kOiBzdHJpbmcsXG4gIGFyZ3M6IHN0cmluZ1tdID0gW10sXG4gIG9wdGlvbnM6IHsgW2luZGV4ZXI6IHN0cmluZ106IHN0cmluZyB9ID0geyBzdGRpbzogXCJpbmhlcml0XCIgfSxcbiAgbG9nTWF0Y2g/OiBSZWdFeHBcbik6IFByb21pc2U8Q2hpbGRQcm9jZXNzIHwgdm9pZCB8IEJ1ZmZlcj4ge1xuICBjb25zdCBsb2c6IExvZ2dlciA9IExvZ2dpbmcuZm9yKHJ1bkNvbW1hbmQpO1xuICBsb2cuaW5mbyhgUnVubmluZyBjb21tYW5kOiAke2NvbW1hbmR9ICR7YXJncy5qb2luKFwiIFwiKX1gKTtcblxuICBpZiAoIWxvZ01hdGNoKSByZXR1cm4gZXhlY1N5bmMoW2NvbW1hbmQsIC4uLmFyZ3NdLmpvaW4oXCIgXCIpLCBvcHRpb25zKTtcblxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IGNoaWxkID0gc3Bhd24oY29tbWFuZCwgYXJncywgb3B0aW9ucyk7XG4gICAgbGV0IHN0ZG91dERhdGEgPSBcIlwiO1xuICAgIGxldCBzdGRlcnJEYXRhID0gXCJcIjtcblxuICAgIGNvbnN0IGNoZWNrTWF0Y2ggPSAoZGF0YTogc3RyaW5nKSA9PiB7XG4gICAgICBpZiAobG9nTWF0Y2ggJiYgbG9nTWF0Y2gudGVzdChkYXRhKSkge1xuICAgICAgICByZXNvbHZlKGNoaWxkKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY2hpbGQuc3Rkb3V0Lm9uKFwiZGF0YVwiLCAoZGF0YTogQnVmZmVyKSA9PiB7XG4gICAgICBjb25zdCBzdHJEYXRhID0gZGF0YS50b1N0cmluZygpO1xuICAgICAgY29uc29sZS5sb2coc3RyRGF0YSk7XG4gICAgICBzdGRvdXREYXRhICs9IHN0ckRhdGE7XG4gICAgICBjaGVja01hdGNoKHN0ckRhdGEpO1xuICAgIH0pO1xuXG4gICAgY2hpbGQuc3RkZXJyLm9uKFwiZGF0YVwiLCAoZGF0YTogQnVmZmVyKSA9PiB7XG4gICAgICBjb25zdCBzdHJEYXRhID0gZGF0YS50b1N0cmluZygpO1xuICAgICAgY29uc29sZS5lcnJvcihzdHJEYXRhKTtcbiAgICAgIHN0ZGVyckRhdGEgKz0gc3RyRGF0YTtcbiAgICAgIGNoZWNrTWF0Y2goc3RyRGF0YSk7XG4gICAgfSk7XG5cbiAgICBjaGlsZC5vbihcImVycm9yXCIsIChlcnI6IEVycm9yKSA9PiB7XG4gICAgICByZWplY3QoZXJyKTtcbiAgICB9KTtcblxuICAgIGNoaWxkLm9uKFwiY2xvc2VcIiwgKGNvZGU6IG51bWJlcikgPT4ge1xuICAgICAgaWYgKGNvZGUgPT09IDApIHtcbiAgICAgICAgcmVzb2x2ZShjaGlsZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZWplY3QoXG4gICAgICAgICAgbmV3IEVycm9yKFxuICAgICAgICAgICAgYFByb2Nlc3MgZXhpdGVkIHdpdGggY29kZSAke2NvZGV9XFxuU3Rkb3V0OiAke3N0ZG91dERhdGF9XFxuU3RkZXJyOiAke3N0ZGVyckRhdGF9YFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59XG4iLCIvKipcbiAqIEBtb2R1bGUgZmFicmljLXdlYXZlclxuICogQGRlc2NyaXB0aW9uIFRoaXMgbW9kdWxlIHNlcnZlcyBhcyB0aGUgbWFpbiBlbnRyeSBwb2ludCBmb3IgdGhlIGZhYnJpYy13ZWF2ZXIgbGlicmFyeSwgcHJvdmlkaW5nIFR5cGVTY3JpcHQgaW50ZWdyYXRpb24gd2l0aCBIeXBlcmxlZGdlciBGYWJyaWMuXG4gKiBAc3VtbWFyeSBBZ2dyZWdhdGVzIGFuZCBleHBvcnRzIGZ1bmN0aW9uYWxpdHkgZm9yIG1hbmFnaW5nIEh5cGVybGVkZ2VyIEZhYnJpYyBpbmZyYXN0cnVjdHVyZXMuXG4gKlxuICogVGhlIG1vZHVsZSBpbmNsdWRlczpcbiAqIDEuIFV0aWxpdHkgZnVuY3Rpb25zIGFuZCB0eXBlcyBmcm9tIHRoZSBcIi4vdXRpbHNcIiBkaXJlY3Rvcnk6XG4gKiAgICAtIEhlbHBlciBmdW5jdGlvbnMgZm9yIGludGVyYWN0aW5nIHdpdGggRmFicmljIGJpbmFyaWVzLlxuICogICAgLSBVdGlsaXRpZXMgZm9yIGdlbmVyYXRpbmcgYW5kIG1hbmFnaW5nIERvY2tlciBDb21wb3NlIGZpbGVzLlxuICogICAgLSBGdW5jdGlvbnMgdG8gYXNzaXN0IGluIGNyZWF0aW5nLCBtYWludGFpbmluZywgYW5kIHVwZGF0aW5nIEh5cGVybGVkZ2VyIEZhYnJpYyBuZXR3b3Jrcy5cbiAqXG4gKiAyLiBDb3JlIGZ1bmN0aW9uYWxpdHkgZnJvbSB0aGUgXCIuL2NvcmVcIiBkaXJlY3Rvcnk6XG4gKiAgICAtIFR5cGVTY3JpcHQgaW50ZXJmYWNlcyBhbmQgY2xhc3NlcyByZXByZXNlbnRpbmcgRmFicmljIGNvbmNlcHRzLlxuICogICAgLSBJbXBsZW1lbnRhdGlvbiBvZiBGYWJyaWMgb3BlcmF0aW9ucyBhbmQgaW50ZXJhY3Rpb25zLlxuICpcbiAqIDMuIEEgVkVSU0lPTiBjb25zdGFudDpcbiAqICAgIC0gUmVwcmVzZW50cyB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoZSBmYWJyaWMtd2VhdmVyIG1vZHVsZS5cbiAqICAgIC0gVXNlZnVsIGZvciB2ZXJzaW9uIGNoZWNraW5nIGFuZCBjb21wYXRpYmlsaXR5IHB1cnBvc2VzLlxuICpcbiAqIFRoaXMgc3RydWN0dXJlIHByb3ZpZGVzIGEgY29tcHJlaGVuc2l2ZSB0b29sa2l0IGZvciB3b3JraW5nIHdpdGggSHlwZXJsZWRnZXIgRmFicmljIGluIFR5cGVTY3JpcHQsXG4gKiBhbGxvd2luZyBkZXZlbG9wZXJzIHRvIGVhc2lseSBzZXQgdXAsIG1hbmFnZSwgYW5kIGludGVyYWN0IHdpdGggRmFicmljIG5ldHdvcmtzIGFuZCBjb21wb25lbnRzLlxuICovXG5cbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzLW9sZFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbHNcIjtcblxuLyoqXG4gKiBAY29uc3QgVkVSU0lPTlxuICogQG5hbWUgVkVSU0lPTlxuICogQGRlc2NyaXB0aW9uIFJlcHJlc2VudHMgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUgZmFicmljLXdlYXZlciBtb2R1bGUuXG4gKiBAc3VtbWFyeSBUaGUgYWN0dWFsIHZlcnNpb24gbnVtYmVyIGlzIHJlcGxhY2VkIGR1cmluZyB0aGUgYnVpbGQgcHJvY2Vzcy5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuIl0sIm5hbWVzIjpbIkJ1aWxkU2NyaXB0cyIsInJlYWRGaWxlIiwid3JpdGVGaWxlIiwiTG9nZ2luZyIsImV4ZWNTeW5jIiwic3Bhd24iXSwibWFwcGluZ3MiOiI7Ozs7OztJQUFBOzs7O0lBSUc7SUFNSDs7Ozs7O0lBTUc7SUFDSCxJQUFLLEtBS0o7SUFMRCxDQUFBLFVBQUssS0FBSyxFQUFBOztJQUVSLElBQUEsS0FBQSxDQUFBLEtBQUEsQ0FBQSxHQUFBLFVBQWdCOztJQUVoQixJQUFBLEtBQUEsQ0FBQSxLQUFBLENBQUEsR0FBQSxRQUFjO0lBQ2hCLENBQUMsRUFMSSxLQUFLLEtBQUwsS0FBSyxHQUtULEVBQUEsQ0FBQSxDQUFBO0lBRUQ7Ozs7O0lBS0c7SUFDRyxNQUFPLGtCQUFtQixTQUFRQSxrQkFBWSxDQUFBO0lBQ2xEOzs7Ozs7Ozs7Ozs7Ozs7O0lBZ0JHO0lBQ0gsSUFBQSxNQUFNLGFBQWEsR0FBQTtJQUNqQixRQUFBLE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsVUFBVSxDQUFDLENBQUM7SUFDdEUsUUFBQSxLQUFLLE1BQU0sR0FBRyxJQUFJLFFBQVEsRUFBRTtJQUMxQixZQUFBLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztvQkFBRTtJQUUxQixZQUFBLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBVyxRQUFBLEVBQUEsR0FBRyxFQUFFLEVBQUUsR0FBRyxDQUFDO2dCQUMvRCxJQUFJLElBQUksR0FBR0MsY0FBUSxDQUFDLE9BQU8sR0FBRyxDQUFBLElBQUEs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