@decaf-ts/fabric-weaver
Version:
template for ts projects
296 lines (288 loc) • 36.3 kB
JavaScript
import { BuildScripts, readFile, writeFile } from '@decaf-ts/utils';
import fs from 'fs';
import path from 'path';
import yaml from 'js-yaml';
import { Logging } from '@decaf-ts/logging';
import { execSync, spawn } from 'child_process';
/**
* @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 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 = readFile(`bin/${cmd}.cjs`);
data = "#!/usr/bin/env node\n" + data;
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.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.for(runCommand);
log.info(`Running command: ${command} ${args.join(" ")}`);
if (!logMatch)
return execSync([command, ...args].join(" "), options);
return new Promise((resolve, reject) => {
const child = 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";
export { BuildScriptsCustom, VERSION, mapParser, readFileYaml, runCommand, safeParseCSV, safeParseInt, safeParseJSON, safeParseSSV, writeFileYaml };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFicmljLXdlYXZlci5lc20uY2pzIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMtb2xkL2J1aWxkLXNjcmlwdHMudHMiLCIuLi9zcmMvY29yZS9jb25zdGFudHMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3V0aWxzL3BhcnNlcnMudHMiLCIuLi9zcmMvdXRpbHMveWFtbC50cyIsIi4uL3NyYy91dGlscy9jaGlsZC1wcm9jZXNzLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQG1vZHVsZSBidWlsZC1zY3JpcHRzXG4gKiBAZGVzY3JpcHRpb24gQ3VzdG9tIGJ1aWxkIHNjcmlwdHMgZm9yIHRoZSBmYWJyaWMtd2VhdmVyIHByb2plY3QuXG4gKiBAc3VtbWFyeSBUaGlzIG1vZHVsZSBleHRlbmRzIHRoZSBCdWlsZFNjcmlwdHMgY2xhc3MgZnJvbSBAZGVjYWYtdHMvdXRpbHMgdG8gcHJvdmlkZSBjdXN0b20gYnVpbGQgZnVuY3Rpb25hbGl0eSBmb3IgdGhlIGZhYnJpYy13ZWF2ZXIgcHJvamVjdC4gSXQgaW5jbHVkZXMgdXRpbGl0aWVzIGZvciBidWlsZGluZyBjb21tYW5kLWxpbmUgaW50ZXJmYWNlcyBhbmQgaGFuZGxpbmcgZGlmZmVyZW50IG1vZHVsZSBmb3JtYXRzIChDb21tb25KUyBhbmQgRVMgTW9kdWxlcykuXG4gKi9cblxuaW1wb3J0IHsgQnVpbGRTY3JpcHRzLCByZWFkRmlsZSwgd3JpdGVGaWxlIH0gZnJvbSBcIkBkZWNhZi10cy91dGlsc1wiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRW51bWVyYXRpb24gb2YgbW9kdWxlIG1vZGVzLlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgZGlmZmVyZW50IG1vZHVsZSBmb3JtYXRzIHN1cHBvcnRlZCBpbiB0aGUgYnVpbGQgcHJvY2Vzcy5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6YnVpbGQtc2NyaXB0c1xuICovXG5lbnVtIE1vZGVzIHtcbiAgLyoqIENvbW1vbkpTIG1vZHVsZSBmb3JtYXQgKi9cbiAgQ0pTID0gXCJjb21tb25qc1wiLFxuICAvKiogRUNNQVNjcmlwdCBtb2R1bGUgZm9ybWF0IChFUzIwMjIpICovXG4gIEVTTSA9IFwiZXMyMDIyXCIsXG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEN1c3RvbSBidWlsZCBzY3JpcHRzIGZvciB0aGUgZmFicmljLXdlYXZlciBwcm9qZWN0LlxuICogQHN1bW1hcnkgRXh0ZW5kcyB0aGUgQnVpbGRTY3JpcHRzIGNsYXNzIHRvIHByb3ZpZGUgcHJvamVjdC1zcGVjaWZpYyBidWlsZCBmdW5jdGlvbmFsaXR5LCBpbmNsdWRpbmcgY29tbWFuZCBidW5kbGluZyBhbmQgZmlsZSBtYW5pcHVsYXRpb24uXG4gKiBAY2xhc3MgQnVpbGRTY3JpcHRzQ3VzdG9tXG4gKiBAZXh0ZW5kcyBCdWlsZFNjcmlwdHNcbiAqL1xuZXhwb3J0IGNsYXNzIEJ1aWxkU2NyaXB0c0N1c3RvbSBleHRlbmRzIEJ1aWxkU2NyaXB0cyB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQnVpbGRzIGNvbW1hbmQtbGluZSBpbnRlcmZhY2VzIGZvciB0aGUgcHJvamVjdC5cbiAgICogQHN1bW1hcnkgUHJvY2Vzc2VzIGVhY2ggY29tbWFuZCBpbiB0aGUgQ29tbWFuZHMgYXJyYXksIGJ1bmRsaW5nIHRoZSBUeXBlU2NyaXB0IGZpbGVzLCBhZGRpbmcgYSBzaGViYW5nIGxpbmUsIGFuZCBzZXR0aW5nIGFwcHJvcHJpYXRlIHBlcm1pc3Npb25zLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fVxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBCdWlsZFNjcmlwdHNDdXN0b21cbiAgICogICBwYXJ0aWNpcGFudCBGaWxlU3lzdGVtXG4gICAqICAgbG9vcCBGb3IgZWFjaCBjb21tYW5kXG4gICAqICAgICBCdWlsZFNjcmlwdHNDdXN0b20tPj5CdWlsZFNjcmlwdHNDdXN0b206IGJ1bmRsZShNb2Rlcy5DSlMsIHRydWUsIHRydWUsIGBzcmMvYmluLyR7Y21kfS50c2AsIGNtZClcbiAgICogICAgIEJ1aWxkU2NyaXB0c0N1c3RvbS0+PkZpbGVTeXN0ZW06IHJlYWRGaWxlKGBiaW4vJHtjbWR9LmNqc2ApXG4gICAqICAgICBGaWxlU3lzdGVtLS0+PkJ1aWxkU2NyaXB0c0N1c3RvbTogZmlsZSBjb250ZW50XG4gICAqICAgICBCdWlsZFNjcmlwdHNDdXN0b20tPj5CdWlsZFNjcmlwdHNDdXN0b206IEFkZCBzaGViYW5nIHRvIGZpbGUgY29udGVudFxuICAgKiAgICAgQnVpbGRTY3JpcHRzQ3VzdG9tLT4+RmlsZVN5c3RlbTogd3JpdGVGaWxlKGBiaW4vJHtjbWR9LmNqc2AsIG1vZGlmaWVkIGNvbnRlbnQpXG4gICAqICAgICBCdWlsZFNjcmlwdHNDdXN0b20tPj5GaWxlU3lzdGVtOiBjaG1vZFN5bmMoYGJpbi8ke2NtZH0uY2pzYCwgXCI3NTVcIilcbiAgICogICBlbmRcbiAgICovXG4gIGFzeW5jIGJ1aWxkQ29tbWFuZHMoKSB7XG4gICAgY29uc3QgY29tbWFuZHMgPSBmcy5yZWFkZGlyU3luYyhwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSArIFwiL3NyYy9iaW5cIikpO1xuICAgIGZvciAoY29uc3QgY21kIG9mIGNvbW1hbmRzKSB7XG4gICAgICBpZiAoIWNtZC5lbmRzV2l0aChcIi50c1wiKSkgY29udGludWU7XG5cbiAgICAgIGF3YWl0IHRoaXMuYnVuZGxlKE1vZGVzLkNKUywgdHJ1ZSwgdHJ1ZSwgYHNyYy9iaW4vJHtjbWR9YCwgY21kKTtcbiAgICAgIGxldCBkYXRhID0gcmVhZEZpbGUoYGJpbi8ke2NtZH0uY2pzYCk7XG4gICAgICBkYXRhID0gXCIjIS91c3IvYmluL2VudiBub2RlXFxuXCIgKyBkYXRhO1xuICAgICAgd3JpdGVGaWxlKGBiaW4vJHtjbWR9LmNqc2AsIGRhdGEpO1xuICAgICAgZnMuY2htb2RTeW5jKGBiaW4vJHtjbWR9LmNqc2AsIFwiNzU1XCIpO1xuICAgIH1cbiAgfVxufVxuIiwiZXhwb3J0IGNvbnN0IENPTU1BX1NFUEFSQVRPUiA9IFwiLFwiO1xuZXhwb3J0IGNvbnN0IENPTE9OX1NFUEFSQVRPUiA9IFwiOlwiO1xuZXhwb3J0IGNvbnN0IFBJUEVfU0VQQVJBVE9SID0gXCJ8XCI7XG5leHBvcnQgY29uc3QgU0xBU0hfU0VQQVJBVE9SID0gXCIvXCI7XG5cbmV4cG9ydCBjb25zdCBOQU1FX1BMQUNFSE9MREVSID0gXCIjI05BTUUjI1wiO1xuZXhwb3J0IGNvbnN0IFZFUlNJT05fUExBQ0VIT0xERVIgPSBcIiMjVkVSIyNcIjtcbmV4cG9ydCBjb25zdCBFTlRSWV9QTEFDRUhPTERFUiA9IFwiIyNFTlRSWSMjXCI7XG4iLCJpbXBvcnQgeyBDT01NQV9TRVBBUkFUT1IsIFNMQVNIX1NFUEFSQVRPUiB9IGZyb20gXCIuLi9jb3JlL2NvbnN0YW50cy9jb25zdGFudHNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHNhZmVQYXJzZUpTT04odjogc3RyaW5nKTogdW5rbm93biB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2Uodik7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgSlNPTjogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2FmZVBhcnNlSW50KHY6IHN0cmluZyB8IG51bWJlcik6IG51bWJlciB7XG4gIGlmICh0eXBlb2YgdiA9PT0gXCJudW1iZXJcIikgcmV0dXJuIE1hdGguZmxvb3Iodik7XG5cbiAgY29uc3QgdmFsdWUgPSBOdW1iZXIodik7XG5cbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBpbnRlZ2VyIHZhbHVlOiAke3Z9YCk7XG4gIH1cblxuICByZXR1cm4gdmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzYWZlUGFyc2VDU1YoY3N2OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGlmICghY3N2LnRyaW0oKSkgcmV0dXJuIFtdO1xuXG4gIHJldHVybiBjc3Yuc3BsaXQoQ09NTUFfU0VQQVJBVE9SKS5tYXAoKGl0ZW0pID0+IGl0ZW0udHJpbSgpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhZmVQYXJzZVNTVihjc3Y6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgY29uc29sZS5sb2coY3N2KTtcbiAgaWYgKCFjc3YudHJpbSgpKSByZXR1cm4gW107XG5cbiAgcmV0dXJuIGNzdi5zcGxpdChTTEFTSF9TRVBBUkFUT1IpLm1hcCgoaXRlbSkgPT4gYFwiJHtpdGVtLnRyaW0oKX1cImApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWFwUGFyc2VyKFxuICBtYXA6IE1hcDxzdHJpbmcsIHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBzdHJpbmdbXT5cbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgYXJneiA9IEFycmF5LmZyb20obWFwLCAoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJib29sZWFuXCIpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA/IFtgLS0ke2tleX1gXSA6IFtdO1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBbYC0tJHtrZXl9YCwgdmFsdWUuam9pbihcIixcIildO1xuICAgIH1cbiAgICByZXR1cm4gW2AtLSR7a2V5fWAsIHZhbHVlLnRvU3RyaW5nKCldO1xuICB9KTtcblxuICByZXR1cm4gYXJnei5tYXAoKGVsKSA9PiBlbC5qb2luKFwiIFwiKSk7XG59XG4iLCJpbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgeWFtbCBmcm9tIFwianMteWFtbFwiO1xuaW1wb3J0IHsgTG9nZ2luZyB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuXG5jb25zdCBsb2dnZXIgPSBMb2dnaW5nLmZvcihcInlhbWxcIik7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlYWRzIGFuZCBwYXJzZXMgYSBZQU1MIGZpbGUsIG9wdGlvbmFsbHkgcmV0cmlldmluZyBhIHNwZWNpZmljIHByb3BlcnR5LlxuICogQHN1bW1hcnkgVGhpcyBmdW5jdGlvbiByZWFkcyBhIFlBTUwgZmlsZSBmcm9tIHRoZSBnaXZlbiBwYXRoLCBwYXJzZXMgaXRzIGNvbnRlbnQsIGFuZCByZXR1cm5zIGVpdGhlciB0aGUgZW50aXJlIHBhcnNlZCBZQU1MIG9iamVjdCBvciBhIHNwZWNpZmljIHByb3BlcnR5IHZhbHVlIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBwYXRoLlxuICpcbiAqIEBmdW5jdGlvbiByZWFkRmlsZVlhbWxcbiAqIEB0ZW1wbGF0ZSBUIC0gVGhlIHR5cGUgb2YgdGhlIHJldHVybmVkIHZhbHVlIHdoZW4gYSBzcGVjaWZpYyBwcm9wZXJ0eSBpcyByZXF1ZXN0ZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30geWFtbEZpbGVQYXRoIC0gVGhlIHBhdGggdG8gdGhlIFlBTUwgZmlsZSB0byBiZSByZWFkLlxuICogQHBhcmFtIHtzdHJpbmd9IFt2YXJpYWJsZV0gLSBPcHRpb25hbC4gQSBkb3Qtbm90YXRlZCBwYXRoIHN0cmluZyB0aGF0IHNwZWNpZmllcyB0aGUgcHJvcGVydHkgdG8gcmV0cmlldmUgZnJvbSB0aGUgcGFyc2VkIFlBTUwuXG4gKiBAcmV0dXJuIHtSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgVH0gUmV0dXJucyB0aGUgZW50aXJlIHBhcnNlZCBZQU1MIG9iamVjdCBpZiBubyBgdmFyaWFibGVgIGlzIHByb3ZpZGVkLCBvciB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwcm9wZXJ0eSBpZiBgdmFyaWFibGVgIGlzIHByb3ZpZGVkLlxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZmFicmljLXdlYXZlci5VdGlsc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBFeGFtcGxlIDE6IFJlYWQgdGhlIGVudGlyZSBZQU1MIGZpbGVcbiAqIGNvbnN0IGNvbmZpZyA9IHJlYWRGaWxlWWFtbChcImNvbmZpZy9zZXR0aW5ncy55YW1sXCIpO1xuICogY29uc29sZS5sb2coY29uZmlnKTtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gRXhhbXBsZSAyOiBSZXRyaWV2ZSBhIHNwZWNpZmljIHByb3BlcnR5IGZyb20gdGhlIFlBTUwgZmlsZVxuICogY29uc3QgZGJIb3N0ID0gcmVhZEZpbGVZYW1sKFwiY29uZmlnL3NldHRpbmdzLnlhbWxcIiwgXCJkYXRhYmFzZS5ob3N0XCIpO1xuICogY29uc29sZS5sb2coZGJIb3N0KTtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gRXhhbXBsZSAzOiBIYW5kbGUgYW4gZXJyb3IgaWYgdGhlIHByb3BlcnR5IGRvZXMgbm90IGV4aXN0XG4gKiBjb25zdCBpbnZhbGlkUHJvcGVydHkgPSByZWFkRmlsZVlhbWwoXCJjb25maWcvc2V0dGluZ3MueWFtbFwiLCBcInNlcnZlci5wb3J0XCIpO1xuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IHJlYWRGaWxlWWFtbFxuICogICBwYXJ0aWNpcGFudCBsb2dnZXJcbiAqICAgcGFydGljaXBhbnQgZnNcbiAqICAgcGFydGljaXBhbnQgeWFtbFxuICpcbiAqICAgQ2FsbGVyLT4+cmVhZEZpbGVZYW1sOiBDYWxsIHdpdGggeWFtbEZpbGVQYXRoIGFuZCBvcHRpb25hbCB2YXJpYWJsZVxuICogICByZWFkRmlsZVlhbWwtPj5sb2dnZXI6IExvZyB2ZXJib3NlIG1lc3NhZ2UgKFJlYWRpbmcgWUFNTCBmaWxlKVxuICogICByZWFkRmlsZVlhbWwtPj5mczogUmVhZCBmaWxlIGNvbnRlbnRcbiAqICAgcmVhZEZpbGVZYW1sLT4+bG9nZ2VyOiBMb2cgdmVyYm9zZSBtZXNzYWdlIChQYXJzZWQgWUFNTCBjb250ZW50KVxuICogICByZWFkRmlsZVlhbWwtPj55YW1sOiBQYXJzZSBZQU1MIGNvbnRlbnRcbiAqICAgcmVhZEZpbGVZYW1sLT4+bG9nZ2VyOiBMb2cgdmVyYm9zZSBtZXNzYWdlIChQYXJzZWQgWUFNTCBvYmplY3QpXG4gKiAgIGFsdCB2YXJpYWJsZSBpcyBwcm92aWRlZFxuICogICAgIHJlYWRGaWxlWWFtbC0+PnJlYWRGaWxlWWFtbDogTmF2aWdhdGUgdGhyb3VnaCBwYXJzZWQgWUFNTCB1c2luZyB2YXJpYWJsZSBwYXRoXG4gKiAgICAgYWx0IFByb3BlcnR5IGV4aXN0c1xuICogICAgICAgcmVhZEZpbGVZYW1sLS0+PkNhbGxlcjogUmV0dXJuIHNwZWNpZmljIHByb3BlcnR5IHZhbHVlXG4gKiAgICAgZWxzZSBQcm9wZXJ0eSBkb2Vzbid0IGV4aXN0XG4gKiAgICAgICByZWFkRmlsZVlhbWwtPj5sb2dnZXI6IExvZyBlcnJvciBtZXNzYWdlXG4gKiAgICAgICByZWFkRmlsZVlhbWwtLT4+Q2FsbGVyOiBSZXR1cm4gZXJyb3JcbiAqICAgICBlbmRcbiAqICAgZWxzZSB2YXJpYWJsZSBpcyBub3QgcHJvdmlkZWRcbiAqICAgICByZWFkRmlsZVlhbWwtLT4+Q2FsbGVyOiBSZXR1cm4gZW50aXJlIHBhcnNlZCBZQU1MIG9iamVjdFxuICogICBlbmRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRGaWxlWWFtbDxUPihcbiAgeWFtbEZpbGVQYXRoOiBzdHJpbmcsXG4gIHZhcmlhYmxlPzogc3RyaW5nXG4pOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgVCB7XG4gIGNvbnN0IGxvZyA9IGxvZ2dlci5mb3IocmVhZEZpbGVZYW1sKTtcblxuICBsb2cuZGVidWcoYFJlYWRpbmcgWUFNTCBmaWxlOiAke3lhbWxGaWxlUGF0aH1gKTtcbiAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyh5YW1sRmlsZVBhdGgsIFwidXRmOFwiKTtcblxuICBsb2cuZGVidWcoYFBhcnNlZCBZQU1MIGNvbnRlbnQ6ICR7Y29udGVudH1gKTtcbiAgY29uc3QgcGFyc2VkWUFNTCA9IHlhbWwubG9hZChjb250ZW50KSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuXG4gIGxvZy5kZWJ1ZyhgUGFyc2VkIFlBTUwgb2JqZWN0OiAke0pTT04uc3RyaW5naWZ5KHBhcnNlZFlBTUwsIG51bGwsIDIpfWApO1xuXG4gIGxvZy5pbmZvKFxuICAgIGBSZXR1cm5pbmcgJHt2YXJpYWJsZSA/IGBwcm9wZXJ0eSAnJHt2YXJpYWJsZX0nYCA6IFwidGhlIGVudGlyZSBwYXJzZWQgWUFNTCBvYmplY3RcIn1gXG4gICk7XG4gIGlmICghdmFyaWFibGUpIHJldHVybiBwYXJzZWRZQU1MO1xuXG4gIGNvbnN0IHZhcmlhYmxlUGF0aCA9IHZhcmlhYmxlLnNwbGl0KFwiLlwiKTtcblxuICByZXR1cm4gdmFyaWFibGVQYXRoLnJlZHVjZSgoYWNjLCBrZXkpID0+IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcHJvdG90eXBlLWJ1aWx0aW5zXG4gICAgaWYgKCFhY2MuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgVW5hYmxlIHRvIGxvY2F0ZSBhIHByb3BlcnR5IG5hbWVkICcke2tleX0nIGZyb20gcGF0aCAnJHt2YXJpYWJsZX0nIGluIGZpbGU6IFxcbj4gJHt5YW1sRmlsZVBhdGh9YFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGVvZiBhY2Nba2V5XSA9PT0gXCJzdHJpbmdcIiA/IGFjY1trZXldLnRyaW0oKSA6IGFjY1trZXldO1xuICB9LCBwYXJzZWRZQU1MKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gV3JpdGVzIGEgSlNPTiBvYmplY3QgdG8gYSBZQU1MIGZpbGUuXG4gKiBAc3VtbWFyeSBUaGlzIGZ1bmN0aW9uIHRha2VzIGEgSlNPTiBvYmplY3QgYW5kIHdyaXRlcyBpdCB0byBhIHNwZWNpZmllZCBmaWxlIHBhdGggaW4gWUFNTCBmb3JtYXQuXG4gKiBJdCB1c2VzIGpzLXlhbWwgdG8gY29udmVydCB0aGUgSlNPTiB0byBZQU1MLCBhbmQgdGhlbiB3cml0ZXMgdGhlIGNvbnRlbnQgdG8gdGhlIGZpbGUuXG4gKlxuICogQGZ1bmN0aW9uIHdyaXRlRmlsZVlhbWxcbiAqIEB0ZW1wbGF0ZSBUIC0gVGhlIHR5cGUgb2YgdGhlIEpTT04gb2JqZWN0IHRvIGJlIHdyaXR0ZW4uXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIFRoZSBmaWxlIHBhdGggd2hlcmUgdGhlIFlBTUwgY29udGVudCB3aWxsIGJlIHdyaXR0ZW4uXG4gKiBAcGFyYW0ge1R9IGpzb24gLSBUaGUgSlNPTiBvYmplY3QgdG8gYmUgY29udmVydGVkIHRvIFlBTUwgYW5kIHdyaXR0ZW4gdG8gdGhlIGZpbGUuXG4gKiBAcmV0dXJuIHt2b2lkfVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZmFicmljLXdlYXZlci5VdGlsc1xuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBjb25maWcgPSB7IGRhdGFiYXNlOiB7IGhvc3Q6ICdsb2NhbGhvc3QnLCBwb3J0OiA1NDMyIH0gfTtcbiAqIHdyaXRlRmlsZVlhbWwoJ2NvbmZpZy9zZXR0aW5ncy55YW1sJywgY29uZmlnKTtcbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCB3cml0ZUZpbGVZYW1sXG4gKiAgIHBhcnRpY2lwYW50IGxvZ2dlclxuICogICBwYXJ0aWNpcGFudCB5YW1sXG4gKiAgIHBhcnRpY2lwYW50IGZzXG4gKlxuICogICBDYWxsZXItPj53cml0ZUZpbGVZYW1sOiBDYWxsIHdpdGggcGF0aCBhbmQgSlNPTlxuICogICB3cml0ZUZpbGVZYW1sLT4+bG9nZ2VyOiBMb2cgdmVyYm9zZSBtZXNzYWdlIChXcml0aW5nIFlBTUwgZmlsZSlcbiAqICAgd3JpdGVGaWxlWWFtbC0+PmxvZ2dlcjogTG9nIHZlcmJvc2UgbWVzc2FnZSAoV3JpdGluZyBZQU1MIGNvbnRlbnQpXG4gKiAgIHdyaXRlRmlsZVlhbWwtPj55YW1sOiBDb252ZXJ0IEpTT04gdG8gWUFNTFxuICogICB3cml0ZUZpbGVZYW1sLT4+bG9nZ2VyOiBMb2cgdmVyYm9zZSBtZXNzYWdlIChXcml0aW5nIFlBTUwgY29udGVudCB0byBmaWxlKVxuICogICB3cml0ZUZpbGVZYW1sLT4+ZnM6IFdyaXRlIFlBTUwgY29udGVudCB0byBmaWxlXG4gKiAgIHdyaXRlRmlsZVlhbWwtLT4+Q2FsbGVyOiBSZXR1cm4gKHZvaWQpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0ZUZpbGVZYW1sPFQ+KHBhdGg6IHN0cmluZywganNvbjogVCkge1xuICBjb25zdCBsb2cgPSBsb2dnZXIuZm9yKHdyaXRlRmlsZVlhbWwpO1xuXG4gIGxvZy5kZWJ1ZyhgV3JpdGluZyBZQU1MIGZpbGU6ICR7cGF0aH1gKTtcbiAgbG9nLmRlYnVnKGBXcml0aW5nIFlBTUwgY29udGVudDogJHtKU09OLnN0cmluZ2lmeShqc29uLCBudWxsLCAyKX1gKTtcbiAgY29uc3QgY29udGVudCA9IHlhbWwuZHVtcChqc29uLCB7IGluZGVudDogMiwgbGluZVdpZHRoOiAtMSB9KTtcblxuICBsb2cuZGVidWcoYFdyaXRpbmcgWUFNTCBjb250ZW50IHRvIGZpbGU6ICR7Y29udGVudH1gKTtcbiAgZnMud3JpdGVGaWxlU3luYyhwYXRoLCBjb250ZW50LnJlcGxhY2UoLyBudWxsJC9nbSwgXCJcIiksIFwidXRmOFwiKTtcbn1cbiIsImltcG9ydCB7IHNwYXduLCBDaGlsZFByb2Nlc3MsIGV4ZWNTeW5jIH0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IExvZ2dlciwgTG9nZ2luZyB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuQ29tbWFuZChcbiAgY29tbWFuZDogc3RyaW5nLFxuICBhcmdzOiBzdHJpbmdbXSA9IFtdLFxuICBvcHRpb25zOiB7IFtpbmRleGVyOiBzdHJpbmddOiBzdHJpbmcgfSA9IHsgc3RkaW86IFwiaW5oZXJpdFwiIH0sXG4gIGxvZ01hdGNoPzogUmVnRXhwXG4pOiBQcm9taXNlPENoaWxkUHJvY2VzcyB8IHZvaWQgfCBCdWZmZXI+IHtcbiAgY29uc3QgbG9nOiBMb2dnZXIgPSBMb2dnaW5nLmZvcihydW5Db21tYW5kKTtcbiAgbG9nLmluZm8oYFJ1bm5pbmcgY29tbWFuZDogJHtjb21tYW5kfSAke2FyZ3Muam9pbihcIiBcIil9YCk7XG5cbiAgaWYgKCFsb2dNYXRjaCkgcmV0dXJuIGV4ZWNTeW5jKFtjb21tYW5kLCAuLi5hcmdzXS5qb2luKFwiIFwiKSwgb3B0aW9ucyk7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBjaGlsZCA9IHNwYXduKGNvbW1hbmQsIGFyZ3MsIG9wdGlvbnMpO1xuICAgIGxldCBzdGRvdXREYXRhID0gXCJcIjtcbiAgICBsZXQgc3RkZXJyRGF0YSA9IFwiXCI7XG5cbiAgICBjb25zdCBjaGVja01hdGNoID0gKGRhdGE6IHN0cmluZykgPT4ge1xuICAgICAgaWYgKGxvZ01hdGNoICYmIGxvZ01hdGNoLnRlc3QoZGF0YSkpIHtcbiAgICAgICAgcmVzb2x2ZShjaGlsZCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNoaWxkLnN0ZG91dC5vbihcImRhdGFcIiwgKGRhdGE6IEJ1ZmZlcikgPT4ge1xuICAgICAgY29uc3Qgc3RyRGF0YSA9IGRhdGEudG9TdHJpbmcoKTtcbiAgICAgIGNvbnNvbGUubG9nKHN0ckRhdGEpO1xuICAgICAgc3Rkb3V0RGF0YSArPSBzdHJEYXRhO1xuICAgICAgY2hlY2tNYXRjaChzdHJEYXRhKTtcbiAgICB9KTtcblxuICAgIGNoaWxkLnN0ZGVyci5vbihcImRhdGFcIiwgKGRhdGE6IEJ1ZmZlcikgPT4ge1xuICAgICAgY29uc3Qgc3RyRGF0YSA9IGRhdGEudG9TdHJpbmcoKTtcbiAgICAgIGNvbnNvbGUuZXJyb3Ioc3RyRGF0YSk7XG4gICAgICBzdGRlcnJEYXRhICs9IHN0ckRhdGE7XG4gICAgICBjaGVja01hdGNoKHN0ckRhdGEpO1xuICAgIH0pO1xuXG4gICAgY2hpbGQub24oXCJlcnJvclwiLCAoZXJyOiBFcnJvcikgPT4ge1xuICAgICAgcmVqZWN0KGVycik7XG4gICAgfSk7XG5cbiAgICBjaGlsZC5vbihcImNsb3NlXCIsIChjb2RlOiBudW1iZXIpID0+IHtcbiAgICAgIGlmIChjb2RlID09PSAwKSB7XG4gICAgICAgIHJlc29sdmUoY2hpbGQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVqZWN0KFxuICAgICAgICAgIG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBQcm9jZXNzIGV4aXRlZCB3aXRoIGNvZGUgJHtjb2RlfVxcblN0ZG91dDogJHtzdGRvdXREYXRhfVxcblN0ZGVycjogJHtzdGRlcnJEYXRhfWBcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuIiwiLyoqXG4gKiBAbW9kdWxlIGZhYnJpYy13ZWF2ZXJcbiAqIEBkZXNjcmlwdGlvbiBUaGlzIG1vZHVsZSBzZXJ2ZXMgYXMgdGhlIG1haW4gZW50cnkgcG9pbnQgZm9yIHRoZSBmYWJyaWMtd2VhdmVyIGxpYnJhcnksIHByb3ZpZGluZyBUeXBlU2NyaXB0IGludGVncmF0aW9uIHdpdGggSHlwZXJsZWRnZXIgRmFicmljLlxuICogQHN1bW1hcnkgQWdncmVnYXRlcyBhbmQgZXhwb3J0cyBmdW5jdGlvbmFsaXR5IGZvciBtYW5hZ2luZyBIeXBlcmxlZGdlciBGYWJyaWMgaW5mcmFzdHJ1Y3R1cmVzLlxuICpcbiAqIFRoZSBtb2R1bGUgaW5jbHVkZXM6XG4gKiAxLiBVdGlsaXR5IGZ1bmN0aW9ucyBhbmQgdHlwZXMgZnJvbSB0aGUgXCIuL3V0aWxzXCIgZGlyZWN0b3J5OlxuICogICAgLSBIZWxwZXIgZnVuY3Rpb25zIGZvciBpbnRlcmFjdGluZyB3aXRoIEZhYnJpYyBiaW5hcmllcy5cbiAqICAgIC0gVXRpbGl0aWVzIGZvciBnZW5lcmF0aW5nIGFuZCBtYW5hZ2luZyBEb2NrZXIgQ29tcG9zZSBmaWxlcy5cbiAqICAgIC0gRnVuY3Rpb25zIHRvIGFzc2lzdCBpbiBjcmVhdGluZywgbWFpbnRhaW5pbmcsIGFuZCB1cGRhdGluZyBIeXBlcmxlZGdlciBGYWJyaWMgbmV0d29ya3MuXG4gKlxuICogMi4gQ29yZSBmdW5jdGlvbmFsaXR5IGZyb20gdGhlIFwiLi9jb3JlXCIgZGlyZWN0b3J5OlxuICogICAgLSBUeXBlU2NyaXB0IGludGVyZmFjZXMgYW5kIGNsYXNzZXMgcmVwcmVzZW50aW5nIEZhYnJpYyBjb25jZXB0cy5cbiAqICAgIC0gSW1wbGVtZW50YXRpb24gb2YgRmFicmljIG9wZXJhdGlvbnMgYW5kIGludGVyYWN0aW9ucy5cbiAqXG4gKiAzLiBBIFZFUlNJT04gY29uc3RhbnQ6XG4gKiAgICAtIFJlcHJlc2VudHMgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUgZmFicmljLXdlYXZlciBtb2R1bGUuXG4gKiAgICAtIFVzZWZ1bCBmb3IgdmVyc2lvbiBjaGVja2luZyBhbmQgY29tcGF0aWJpbGl0eSBwdXJwb3Nlcy5cbiAqXG4gKiBUaGlzIHN0cnVjdHVyZSBwcm92aWRlcyBhIGNvbXByZWhlbnNpdmUgdG9vbGtpdCBmb3Igd29ya2luZyB3aXRoIEh5cGVybGVkZ2VyIEZhYnJpYyBpbiBUeXBlU2NyaXB0LFxuICogYWxsb3dpbmcgZGV2ZWxvcGVycyB0byBlYXNpbHkgc2V0IHVwLCBtYW5hZ2UsIGFuZCBpbnRlcmFjdCB3aXRoIEZhYnJpYyBuZXR3b3JrcyBhbmQgY29tcG9uZW50cy5cbiAqL1xuXG5leHBvcnQgKiBmcm9tIFwiLi91dGlscy1vbGRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzXCI7XG5cbi8qKlxuICogQGNvbnN0IFZFUlNJT05cbiAqIEBuYW1lIFZFUlNJT05cbiAqIEBkZXNjcmlwdGlvbiBSZXByZXNlbnRzIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlIGZhYnJpYy13ZWF2ZXIgbW9kdWxlLlxuICogQHN1bW1hcnkgVGhlIGFjdHVhbCB2ZXJzaW9uIG51bWJlciBpcyByZXBsYWNlZCBkdXJpbmcgdGhlIGJ1aWxkIHByb2Nlc3MuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFJRztBQU1IOzs7Ozs7QUFNRztBQUNILElBQUssS0FLSjtBQUxELENBQUEsVUFBSyxLQUFLLEVBQUE7O0FBRVIsSUFBQSxLQUFBLENBQUEsS0FBQSxDQUFBLEdBQUEsVUFBZ0I7O0FBRWhCLElBQUEsS0FBQSxDQUFBLEtBQUEsQ0FBQSxHQUFBLFFBQWM7QUFDaEIsQ0FBQyxFQUxJLEtBQUssS0FBTCxLQUFLLEdBS1QsRUFBQSxDQUFBLENBQUE7QUFFRDs7Ozs7QUFLRztBQUNHLE1BQU8sa0JBQW1CLFNBQVEsWUFBWSxDQUFBO0FBQ2xEOzs7Ozs7Ozs7Ozs7Ozs7O0FBZ0JHO0FBQ0gsSUFBQSxNQUFNLGFBQWEsR0FBQTtBQUNqQixRQUFBLE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsVUFBVSxDQUFDLENBQUM7QUFDdEUsUUFBQSxLQUFLLE1BQU0sR0FBRyxJQUFJLFFBQVEsRUFBRTtBQUMxQixZQUFBLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztnQkFBRTtBQUUxQixZQUFBLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBVyxRQUFBLEVBQUEsR0FBRyxFQUFFLEVBQUUsR0FBRyxDQUFDO1lBQy9ELElBQUksSUFBSSxHQUFHLFFBQVEsQ0FBQyxPQUFPLEdBQUcsQ0FBQSxJQUFBLENBQU0sQ0FBQztBQUNyQyxZQUFBLElBQUksR0FBRyx1QkFBdUIsR0FBRyxJQUFJO0FBQ3JDLFlBQUEsU0FBUyxD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