@tylertech/forge-build-tools
Version:
Node utilities for building and packaging libraries.
213 lines • 30.5 kB
JavaScript
import * as fs from 'fs';
import * as util from 'util';
import { rimrafSync } from 'rimraf';
import * as tmp from 'tmp';
import { glob, globSync } from 'glob';
import fsExtra from 'fs-extra';
import cpath from 'canonical-path';
import { isGlob, logError } from '../utils/index.js';
export const existsSync = (path) => fs.existsSync(path);
// Export promisified fs functions here
export const mkdirAsync = util.promisify(fs.mkdir);
export const mkdirp = fsExtra.mkdirpSync;
export const copy = fsExtra.copySync;
export const copyAsync = util.promisify(fsExtra.copy);
export const symlinkAsync = util.promisify(fs.symlink);
export const readFileAsync = util.promisify(fs.readFile);
export const writeFileAsync = util.promisify(fs.writeFile);
export const existsAsync = util.promisify(fs.exists);
export const readdirAsync = util.promisify(fs.readdir);
export const statAsync = util.promisify(fs.stat);
export const lstatAsync = util.promisify(fs.lstat);
export const removeSync = fsExtra.removeSync;
export const ensureDir = util.promisify(fsExtra.ensureDir);
export const ensureDirSync = fsExtra.ensureDirSync;
export const outputFileAsync = fsExtra.outputFile;
export const globFiles = globSync;
export const emptyDir = fsExtra.emptyDirSync;
export const emptyDirAsync = fsExtra.emptyDir;
export const deleteDir = rimrafSync;
export const rename = util.promisify(fs.rename);
export const deleteFile = util.promisify(fs.unlink);
export const moveAsync = util.promisify(fsExtra.move);
export function globFilesAsync(pattern, options) {
return glob(pattern, options);
}
/**
* Deletes the list of files.
* @param files The files to delete.
*/
export async function deleteFiles(files) {
if (typeof files === 'string') {
files = isGlob(files) ? await globFilesAsync(files, {}) : [files];
}
files.forEach(filename => deleteFile(cpath.resolve(filename)));
}
/**
* Moves an array of files or a glob pattern of files to a directory.
* @param {string[] | string} files The array of files or a glob pattern of files to search for.
* @param {string} rootDir The common root directory in which to build the structure in the output directory.
* @param {string} outputDir The output directory path.
*/
export async function moveFiles(files, rootDir, outputDir) {
if (typeof files === 'string') {
files = isGlob(files) ? await globFilesAsync(files, {}) : [files];
}
if (rootDir) {
rootDir = cpath.resolve(rootDir);
}
outputDir = cpath.resolve(outputDir);
for (const filename of files) {
const absoluteFilePath = cpath.resolve(filename);
const filePath = rootDir ? absoluteFilePath.replace(rootDir, '').replace(/^\//, '') : cpath.basename(absoluteFilePath);
const outputFilePath = cpath.join(outputDir, filePath);
mkdirp(cpath.dirname(outputFilePath));
await rename(filename, outputFilePath);
}
}
/**
*
* @param dirs The directory paths to move.
* @param outputDir The new directory location.
*/
export async function moveDirectories(dirs, outputDir) {
for (const dir of dirs) {
const outputPath = cpath.join(outputDir, cpath.basename(dir));
if (existsSync(dir) && !existsSync(outputPath)) {
await moveAsync(dir, outputPath);
}
}
}
/**
* Copies an array of files or a glob pattern of files to a directory.
* @param {string | string[]} files The array of files or a glob pattern of files to search for.
* @param {string} rootDir The common root directory in which to build the structure in the output directory.
* @param {string | string[]} outputDirs The output directory path.
*/
export async function copyFilesAsync(files, rootDir, outputDirs, ignoredFiles) {
if (typeof files === 'string') {
files = isGlob(files) ? await globFilesAsync(files, { ignore: ignoredFiles }) : [files];
}
if (typeof outputDirs === 'string') {
outputDirs = [outputDirs];
}
if (!(outputDirs instanceof Array)) {
throw new Error('outputDirs must be an array.');
}
if (rootDir) {
rootDir = cpath.resolve(rootDir);
}
outputDirs = outputDirs.map(dir => cpath.resolve(dir));
outputDirs.forEach(dir => mkdirp(dir));
for (const file of files) {
const absoluteFilePath = cpath.resolve(file);
const promises = [];
for (const outputDir of outputDirs) {
const relativePath = rootDir ? absoluteFilePath.replace(rootDir, '').replace(/^\//, '') : cpath.basename(absoluteFilePath);
const outputFilePath = cpath.join(outputDir, relativePath);
promises.push(copyAsync(file, outputFilePath));
}
await Promise.all(promises);
}
}
/**
* Copies the provided files from one directory to another.
* @param fileConfigs The file copy descriptors.
*/
export async function copyFilesMultiple(fileConfigs) {
if (fileConfigs.some(config => !config.path || !config.outputPath)) {
throw new Error('Every file config must specify valid path and outputPath properties.');
}
for (const config of fileConfigs) {
let files = [];
if (typeof config.path === 'string') {
files = isGlob(config.path) ? await globFilesAsync(config.path, {}) : [config.path];
}
else if (config.path instanceof Array) {
for (const filename of config.path) {
files = files.concat(isGlob(filename) ? await globFilesAsync(filename, {}) : [filename]);
}
}
else {
throw new Error('Invalid filepath provided.');
}
const outputPath = cpath.resolve(config.outputPath);
mkdirp(outputPath);
for (const file of files) {
const absoluteFilePath = cpath.resolve(file);
const outputFilePath = config.rootPath ? cpath.join(outputPath, absoluteFilePath.replace(cpath.resolve(config.rootPath), '').replace(/^\//, '')) : cpath.join(outputPath, cpath.basename(file));
await copy(file, outputFilePath);
}
}
}
/**
* Reads in a JSON file and returns an instance of it.
* @param filepath The path to the file to read.
*/
export async function readJsonFile(filepath) {
let json;
let contents;
try {
contents = await readFileAsync(filepath, 'utf-8');
}
catch {
return undefined;
}
if (contents) {
try {
json = JSON.parse(contents);
}
catch (e) {
logError('Invalid JSON file: ' + filepath);
}
}
return json;
}
/**
* Writes an object to a JSON file.
* Note: overwrites the file, does not merge the JSON contents.
* @param filepath The file path to write to.
* @param data The object to convert to JSON.
*/
export async function writeJsonFile(filepath, data) {
const contents = JSON.stringify(data, null, ' ');
await writeFileAsync(filepath, contents, 'utf8');
}
/**
* Creates a new temporary directory.
* @param options The options to pass to `tmp`.
*/
export async function createTempDir(options) {
const defaultOptions = {
mode: 0o777,
keep: false,
unsafeCleanup: true
};
const tmpOptions = Object.assign(defaultOptions, options);
return new Promise((resolve, reject) => {
tmp.setGracefulCleanup();
tmp.dir(tmpOptions, (err, path, cleanupCallback) => {
if (err) {
reject(err);
}
const result = {
path,
remove: cleanupCallback
};
resolve(result);
});
});
}
/**
* Replaces the extension in `inPath` with the extension specified in `extension`.
* @param {string} inPath The path to replace the extension in.
* @param {string} extension The new extension.
*/
export function replaceExtension(inPath, extension) {
if (!inPath || typeof inPath !== 'string') {
return inPath;
}
const newPath = cpath.basename(inPath, cpath.extname(inPath)) + extension.replace(/^\.?/, '.');
return cpath.join(cpath.dirname(inPath), newPath);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZnMvZnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDekIsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUNwQyxPQUFPLEtBQUssR0FBRyxNQUFNLEtBQUssQ0FBQztBQUMzQixPQUFPLEVBQUUsSUFBSSxFQUFpQyxRQUFRLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDckUsT0FBTyxPQUFPLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBRW5DLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFckQsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLENBQUMsSUFBWSxFQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBRXpFLHVDQUF1QztBQUN2QyxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbkQsTUFBTSxDQUFDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUM7QUFDekMsTUFBTSxDQUFDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7QUFDckMsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3RELE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUN2RCxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FB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R0FBRyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxFQUFFO1lBQ2pELElBQUksR0FBRyxFQUFFLENBQUM7Z0JBQ1IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2QsQ0FBQztZQUVELE1BQU0sTUFBTSxHQUFHO2dCQUNiLElBQUk7Z0JBQ0osTUFBTSxFQUFFLGVBQWU7YUFDeEIsQ0FBQztZQUNGLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsTUFBYyxFQUFFLFNBQWlCO0lBQ2hFLElBQUksQ0FBQyxNQUFNLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDMUMsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUNELE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztJQUMvRixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNwRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgdXRpbCBmcm9tICd1dGlsJztcbmltcG9ydCB7IHJpbXJhZlN5bmMgfSBmcm9tICdyaW1yYWYnO1xuaW1wb3J0ICogYXMgdG1wIGZyb20gJ3RtcCc7XG5pbXBvcnQgeyBnbG9iLCBHbG9iT3B0aW9uc1dpdGhGaWxlVHlwZXNVbnNldCwgZ2xvYlN5bmMgfSBmcm9tICdnbG9iJztcbmltcG9ydCBmc0V4dHJhIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCBjcGF0aCBmcm9tICdjYW5vbmljYWwtcGF0aCc7XG5cbmltcG9ydCB7IGlzR2xvYiwgbG9nRXJyb3IgfSBmcm9tICcuLi91dGlscy9pbmRleC5qcyc7XG5cbmV4cG9ydCBjb25zdCBleGlzdHNTeW5jID0gKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4gPT4gZnMuZXhpc3RzU3luYyhwYXRoKTtcblxuLy8gRXhwb3J0IHByb21pc2lmaWVkIGZzIGZ1bmN0aW9ucyBoZXJlXG5leHBvcnQgY29uc3QgbWtkaXJBc3luYyA9IHV0aWwucHJvbWlzaWZ5KGZzLm1rZGlyKTtcbmV4cG9ydCBjb25zdCBta2RpcnAgPSBmc0V4dHJhLm1rZGlycFN5bmM7XG5leHBvcnQgY29uc3QgY29weSA9IGZzRXh0cmEuY29weVN5bmM7XG5leHBvcnQgY29uc3QgY29weUFzeW5jID0gdXRpbC5wcm9taXNpZnkoZnNFeHRyYS5jb3B5KTtcbmV4cG9ydCBjb25zdCBzeW1saW5rQXN5bmMgPSB1dGlsLnByb21pc2lmeShmcy5zeW1saW5rKTtcbmV4cG9ydCBjb25zdCByZWFkRmlsZUFzeW5jID0gdXRpbC5wcm9taXNpZnkoZnMucmVhZEZpbGUpO1xuZXhwb3J0IGNvbnN0IHdyaXRlRmlsZUFzeW5jID0gdXRpbC5wcm9taXNpZnkoZnMud3JpdGVGaWxlKTtcbmV4cG9ydCBjb25zdCBleGlzdHNBc3luYyA9IHV0aWwucHJvbWlzaWZ5KGZzLmV4aXN0cyk7XG5leHBvcnQgY29uc3QgcmVhZGRpckFzeW5jID0gdXRpbC5wcm9taXNpZnkoZnMucmVhZGRpcik7XG5leHBvcnQgY29uc3Qgc3RhdEFzeW5jID0gdXRpbC5wcm9taXNpZnkoZnMuc3RhdCk7XG5leHBvcnQgY29uc3QgbHN0YXRBc3luYyA9IHV0aWwucHJvbWlzaWZ5KGZzLmxzdGF0KTtcbmV4cG9ydCBjb25zdCByZW1vdmVTeW5jID0gZnNFeHRyYS5yZW1vdmVTeW5jO1xuZXhwb3J0IGNvbnN0IGVuc3VyZURpciA9IHV0aWwucHJvbWlzaWZ5KGZzRXh0cmEuZW5zdXJlRGlyKTtcbmV4cG9ydCBjb25zdCBlbnN1cmVEaXJTeW5jID0gZnNFeHRyYS5lbnN1cmVEaXJTeW5jO1xuZXhwb3J0IGNvbnN0IG91dHB1dEZpbGVBc3luYyA9IGZzRXh0cmEub3V0cHV0RmlsZTtcbmV4cG9ydCBjb25zdCBnbG9iRmlsZXMgPSBnbG9iU3luYztcbmV4cG9ydCBjb25zdCBlbXB0eURpciA9IGZzRXh0cmEuZW1wdHlEaXJTeW5jO1xuZXhwb3J0IGNvbnN0IGVtcHR5RGlyQXN5bmMgPSBmc0V4dHJhLmVtcHR5RGlyO1xuZXhwb3J0IGNvbnN0IGRlbGV0ZURpciA9IHJpbXJhZlN5bmM7XG5leHBvcnQgY29uc3QgcmVuYW1lID0gdXRpbC5wcm9taXNpZnkoZnMucmVuYW1lKTtcbmV4cG9ydCBjb25zdCBkZWxldGVGaWxlID0gdXRpbC5wcm9taXNpZnkoZnMudW5saW5rKTtcbmV4cG9ydCBjb25zdCBtb3ZlQXN5bmMgPSB1dGlsLnByb21pc2lmeShmc0V4dHJhLm1vdmUpO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2xvYkZpbGVzQXN5bmMocGF0dGVybjogc3RyaW5nIHwgc3RyaW5nW10sIG9wdGlvbnM/OiBHbG9iT3B0aW9uc1dpdGhGaWxlVHlwZXNVbnNldCB8IHVuZGVmaW5lZCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgcmV0dXJuIGdsb2IocGF0dGVybiwgb3B0aW9ucyk7XG59XG5cbi8qKlxuICogRGVsZXRlcyB0aGUgbGlzdCBvZiBmaWxlcy5cbiAqIEBwYXJhbSBmaWxlcyBUaGUgZmlsZXMgdG8gZGVsZXRlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVsZXRlRmlsZXMoZmlsZXM6IHN0cmluZyB8IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmICh0eXBlb2YgZmlsZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgZmlsZXMgPSBpc0dsb2IoZmlsZXMpID8gYXdhaXQgZ2xvYkZpbGVzQXN5bmMoZmlsZXMsIHt9KSBhcyBzdHJpbmdbXSA6IFtmaWxlc107XG4gIH1cblxuICBmaWxlcy5mb3JFYWNoKGZpbGVuYW1lID0+IGRlbGV0ZUZpbGUoY3BhdGgucmVzb2x2ZShmaWxlbmFtZSkpKTtcbn1cblxuLyoqXG4gKiBNb3ZlcyBhbiBhcnJheSBvZiBmaWxlcyBvciBhIGdsb2IgcGF0dGVybiBvZiBmaWxlcyB0byBhIGRpcmVjdG9yeS5cbiAqIEBwYXJhbSB7c3RyaW5nW10gfCBzdHJpbmd9IGZpbGVzIFRoZSBhcnJheSBvZiBmaWxlcyBvciBhIGdsb2IgcGF0dGVybiBvZiBmaWxlcyB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtzdHJpbmd9IHJvb3REaXIgVGhlIGNvbW1vbiByb290IGRpcmVjdG9yeSBpbiB3aGljaCB0byBidWlsZCB0aGUgc3RydWN0dXJlIGluIHRoZSBvdXRwdXQgZGlyZWN0b3J5LlxuICogQHBhcmFtIHtzdHJpbmd9IG91dHB1dERpciBUaGUgb3V0cHV0IGRpcmVjdG9yeSBwYXRoLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbW92ZUZpbGVzKGZpbGVzOiBzdHJpbmdbXSB8IHN0cmluZywgcm9vdERpcjogc3RyaW5nIHwgbnVsbCwgb3V0cHV0RGlyOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKHR5cGVvZiBmaWxlcyA9PT0gJ3N0cmluZycpIHtcbiAgICBmaWxlcyA9IGlzR2xvYihmaWxlcykgPyBhd2FpdCBnbG9iRmlsZXNBc3luYyhmaWxlcywge30pIGFzIHN0cmluZ1tdIDogW2ZpbGVzXTtcbiAgfVxuXG4gIGlmIChyb290RGlyKSB7XG4gICAgcm9vdERpciA9IGNwYXRoLnJlc29sdmUocm9vdERpcik7XG4gIH1cbiAgb3V0cHV0RGlyID0gY3BhdGgucmVzb2x2ZShvdXRwdXREaXIpO1xuXG4gIGZvciAoY29uc3QgZmlsZW5hbWUgb2YgZmlsZXMpIHtcbiAgICBjb25zdCBhYnNvbHV0ZUZpbGVQYXRoID0gY3BhdGgucmVzb2x2ZShmaWxlbmFtZSk7XG4gICAgY29uc3QgZmlsZVBhdGggPSByb290RGlyID8gYWJzb2x1dGVGaWxlUGF0aC5yZXBsYWNlKHJvb3REaXIsICcnKS5yZXBsYWNlKC9eXFwvLywgJycpIDogY3BhdGguYmFzZW5hbWUoYWJzb2x1dGVGaWxlUGF0aCk7XG4gICAgY29uc3Qgb3V0cHV0RmlsZVBhdGggPSBjcGF0aC5qb2luKG91dHB1dERpciwgZmlsZVBhdGgpO1xuICAgIG1rZGlycChjcGF0aC5kaXJuYW1lKG91dHB1dEZpbGVQYXRoKSk7XG4gICAgYXdhaXQgcmVuYW1lKGZpbGVuYW1lLCBvdXRwdXRGaWxlUGF0aCk7XG4gIH1cbn1cblxuLyoqXG4gKlxuICogQHBhcmFtIGRpcnMgVGhlIGRpcmVjdG9yeSBwYXRocyB0byBtb3ZlLlxuICogQHBhcmFtIG91dHB1dERpciBUaGUgbmV3IGRpcmVjdG9yeSBsb2NhdGlvbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1vdmVEaXJlY3RvcmllcyhkaXJzOiBzdHJpbmdbXSwgb3V0cHV0RGlyOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgZm9yIChjb25zdCBkaXIgb2YgZGlycykge1xuICAgIGNvbnN0IG91dHB1dFBhdGggPSBjcGF0aC5qb2luKG91dHB1dERpciwgY3BhdGguYmFzZW5hbWUoZGlyKSk7XG4gICAgaWYgKGV4aXN0c1N5bmMoZGlyKSAmJiAhZXhpc3RzU3luYyhvdXRwdXRQYXRoKSkge1xuICAgICAgYXdhaXQgbW92ZUFzeW5jKGRpciwgb3V0cHV0UGF0aCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQ29waWVzIGFuIGFycmF5IG9mIGZpbGVzIG9yIGEgZ2xvYiBwYXR0ZXJuIG9mIGZpbGVzIHRvIGEgZGlyZWN0b3J5LlxuICogQHBhcmFtIHtzdHJpbmcgfCBzdHJpbmdbXX0gZmlsZXMgVGhlIGFycmF5IG9mIGZpbGVzIG9yIGEgZ2xvYiBwYXR0ZXJuIG9mIGZpbGVzIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0ge3N0cmluZ30gcm9vdERpciBUaGUgY29tbW9uIHJvb3QgZGlyZWN0b3J5IGluIHdoaWNoIHRvIGJ1aWxkIHRoZSBzdHJ1Y3R1cmUgaW4gdGhlIG91dHB1dCBkaXJlY3RvcnkuXG4gKiBAcGFyYW0ge3N0cmluZyB8IHN0cmluZ1tdfSBvdXRwdXREaXJzIFRoZSBvdXRwdXQgZGlyZWN0b3J5IHBhdGguXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb3B5RmlsZXNBc3luYyhmaWxlczogc3RyaW5nIHwgc3RyaW5nW10sIHJvb3REaXI6IHN0cmluZyB8IG51bGwsIG91dHB1dERpcnM6IHN0cmluZyB8IHN0cmluZ1tdLCBpZ25vcmVkRmlsZXM/OiBzdHJpbmcgfCBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAodHlwZW9mIGZpbGVzID09PSAnc3RyaW5nJykge1xuICAgIGZpbGVzID0gaXNHbG9iKGZpbGVzKSA/IGF3YWl0IGdsb2JGaWxlc0FzeW5jKGZpbGVzLCB7IGlnbm9yZTogaWdub3JlZEZpbGVzIH0pIGFzIHN0cmluZ1tdIDogW2ZpbGVzXTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb3V0cHV0RGlycyA9PT0gJ3N0cmluZycpIHtcbiAgICBvdXRwdXREaXJzID0gW291dHB1dERpcnNdO1xuICB9XG5cbiAgaWYgKCEob3V0cHV0RGlycyBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgIHRocm93IG5ldyBFcnJvcignb3V0cHV0RGlycyBtdXN0IGJlIGFuIGFycmF5LicpO1xuICB9XG5cbiAgaWYgKHJvb3REaXIpIHtcbiAgICByb290RGlyID0gY3BhdGgucmVzb2x2ZShyb290RGlyKTtcbiAgfVxuXG4gIG91dHB1dERpcnMgPSBvdXRwdXREaXJzLm1hcChkaXIgPT4gY3BhdGgucmVzb2x2ZShkaXIpKTtcbiAgb3V0cHV0RGlycy5mb3JFYWNoKGRpciA9PiBta2RpcnAoZGlyKSk7XG5cbiAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgY29uc3QgYWJzb2x1dGVGaWxlUGF0aCA9IGNwYXRoLnJlc29sdmUoZmlsZSk7XG4gICAgY29uc3QgcHJvbWlzZXM6IEFycmF5PFByb21pc2U8dm9pZD4+ID0gW107XG5cbiAgICBmb3IgKGNvbnN0IG91dHB1dERpciBvZiBvdXRwdXREaXJzKSB7XG4gICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSByb290RGlyID8gYWJzb2x1dGVGaWxlUGF0aC5yZXBsYWNlKHJvb3REaXIsICcnKS5yZXBsYWNlKC9eXFwvLywgJycpIDogY3BhdGguYmFzZW5hbWUoYWJzb2x1dGVGaWxlUGF0aCk7XG4gICAgICBjb25zdCBvdXRwdXRGaWxlUGF0aCA9IGNwYXRoLmpvaW4ob3V0cHV0RGlyLCByZWxhdGl2ZVBhdGgpO1xuICAgICAgcHJvbWlzZXMucHVzaChjb3B5QXN5bmMoZmlsZSwgb3V0cHV0RmlsZVBhdGgpKTtcbiAgICB9XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBJRmlsZUNvcHlDb25maWcge1xuICBwYXRoOiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgb3V0cHV0UGF0aDogc3RyaW5nO1xuICByb290UGF0aD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBDb3BpZXMgdGhlIHByb3ZpZGVkIGZpbGVzIGZyb20gb25lIGRpcmVjdG9yeSB0byBhbm90aGVyLlxuICogQHBhcmFtIGZpbGVDb25maWdzIFRoZSBmaWxlIGNvcHkgZGVzY3JpcHRvcnMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb3B5RmlsZXNNdWx0aXBsZShmaWxlQ29uZmlnczogSUZpbGVDb3B5Q29uZmlnW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKGZpbGVDb25maWdzLnNvbWUoY29uZmlnID0+ICFjb25maWcucGF0aCB8fCAhY29uZmlnLm91dHB1dFBhdGgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdFdmVyeSBmaWxlIGNvbmZpZyBtdXN0IHNwZWNpZnkgdmFsaWQgcGF0aCBhbmQgb3V0cHV0UGF0aCBwcm9wZXJ0aWVzLicpO1xuICB9XG5cbiAgZm9yIChjb25zdCBjb25maWcgb2YgZmlsZUNvbmZpZ3MpIHtcbiAgICBsZXQgZmlsZXM6IHN0cmluZ1tdID0gW107XG5cbiAgICBpZiAodHlwZW9mIGNvbmZpZy5wYXRoID09PSAnc3RyaW5nJykge1xuICAgICAgZmlsZXMgPSBpc0dsb2IoY29uZmlnLnBhdGgpID8gYXdhaXQgZ2xvYkZpbGVzQXN5bmMoY29uZmlnLnBhdGgsIHt9KSA6IFtjb25maWcucGF0aF07XG4gICAgfSBlbHNlIGlmIChjb25maWcucGF0aCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBmb3IgKGNvbnN0IGZpbGVuYW1lIG9mIGNvbmZpZy5wYXRoKSB7XG4gICAgICAgIGZpbGVzID0gZmlsZXMuY29uY2F0KGlzR2xvYihmaWxlbmFtZSkgPyBhd2FpdCBnbG9iRmlsZXNBc3luYyhmaWxlbmFtZSwge30pIDogW2ZpbGVuYW1lXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBmaWxlcGF0aCBwcm92aWRlZC4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBvdXRwdXRQYXRoID0gY3BhdGgucmVzb2x2ZShjb25maWcub3V0cHV0UGF0aCk7XG4gICAgbWtkaXJwKG91dHB1dFBhdGgpO1xuXG4gICAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgICBjb25zdCBhYnNvbHV0ZUZpbGVQYXRoID0gY3BhdGgucmVzb2x2ZShmaWxlKTtcbiAgICAgIGNvbnN0IG91dHB1dEZpbGVQYXRoID0gY29uZmlnLnJvb3RQYXRoID8gY3BhdGguam9pbihvdXRwdXRQYXRoLCBhYnNvbHV0ZUZpbGVQYXRoLnJlcGxhY2UoY3BhdGgucmVzb2x2ZShjb25maWcucm9vdFBhdGgpLCAnJykucmVwbGFjZSgvXlxcLy8sICcnKSkgOiBjcGF0aC5qb2luKG91dHB1dFBhdGgsIGNwYXRoLmJhc2VuYW1lKGZpbGUpKTtcbiAgICAgIGF3YWl0IGNvcHkoZmlsZSwgb3V0cHV0RmlsZVBhdGgpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlYWRzIGluIGEgSlNPTiBmaWxlIGFuZCByZXR1cm5zIGFuIGluc3RhbmNlIG9mIGl0LlxuICogQHBhcmFtIGZpbGVwYXRoIFRoZSBwYXRoIHRvIHRoZSBmaWxlIHRvIHJlYWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWFkSnNvbkZpbGU8VD4oZmlsZXBhdGg6IHN0cmluZyk6IFByb21pc2U8VCB8IHVuZGVmaW5lZD4ge1xuICBsZXQganNvbjogVCB8IHVuZGVmaW5lZDtcbiAgbGV0IGNvbnRlbnRzOiBzdHJpbmc7XG5cbiAgdHJ5IHtcbiAgICBjb250ZW50cyA9IGF3YWl0IHJlYWRGaWxlQXN5bmMoZmlsZXBhdGgsICd1dGYtOCcpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKGNvbnRlbnRzKSB7XG4gICAgdHJ5IHtcbiAgICAgIGpzb24gPSBKU09OLnBhcnNlKGNvbnRlbnRzKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dFcnJvcignSW52YWxpZCBKU09OIGZpbGU6ICcgKyBmaWxlcGF0aCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGpzb247XG59XG5cbi8qKlxuICogV3JpdGVzIGFuIG9iamVjdCB0byBhIEpTT04gZmlsZS5cbiAqIE5vdGU6IG92ZXJ3cml0ZXMgdGhlIGZpbGUsIGRvZXMgbm90IG1lcmdlIHRoZSBKU09OIGNvbnRlbnRzLlxuICogQHBhcmFtIGZpbGVwYXRoIFRoZSBmaWxlIHBhdGggdG8gd3JpdGUgdG8uXG4gKiBAcGFyYW0gZGF0YSBUaGUgb2JqZWN0IHRvIGNvbnZlcnQgdG8gSlNPTi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdyaXRlSnNvbkZpbGU8VD4oZmlsZXBhdGg6IHN0cmluZywgZGF0YTogVCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBjb250ZW50cyA9IEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsICcgICcpO1xuICBhd2FpdCB3cml0ZUZpbGVBc3luYyhmaWxlcGF0aCwgY29udGVudHMsICd1dGY4Jyk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyB0ZW1wb3JhcnkgZGlyZWN0b3J5LlxuICogQHBhcmFtIG9wdGlvbnMgVGhlIG9wdGlvbnMgdG8gcGFzcyB0byBgdG1wYC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVRlbXBEaXIob3B0aW9ucz86IElUZW1wT3B0aW9ucyk6IFByb21pc2U8SVRlbXBEaXJSZXN1bHQ+IHtcbiAgY29uc3QgZGVmYXVsdE9wdGlvbnM6IHRtcC5EaXJPcHRpb25zID0ge1xuICAgIG1vZGU6IDBvNzc3LFxuICAgIGtlZXA6IGZhbHNlLFxuICAgIHVuc2FmZUNsZWFudXA6IHRydWVcbiAgfTtcbiAgY29uc3QgdG1wT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oZGVmYXVsdE9wdGlvbnMsIG9wdGlvbnMpIGFzIHRtcC5EaXJPcHRpb25zO1xuICByZXR1cm4gbmV3IFByb21pc2U8SVRlbXBEaXJSZXN1bHQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICB0bXAuc2V0R3JhY2VmdWxDbGVhbnVwKCk7XG4gICAgdG1wLmRpcih0bXBPcHRpb25zLCAoZXJyLCBwYXRoLCBjbGVhbnVwQ2FsbGJhY2spID0+IHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IHtcbiAgICAgICAgcGF0aCxcbiAgICAgICAgcmVtb3ZlOiBjbGVhbnVwQ2FsbGJhY2tcbiAgICAgIH07XG4gICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFJlcGxhY2VzIHRoZSBleHRlbnNpb24gaW4gYGluUGF0aGAgd2l0aCB0aGUgZXh0ZW5zaW9uIHNwZWNpZmllZCBpbiBgZXh0ZW5zaW9uYC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpblBhdGggVGhlIHBhdGggdG8gcmVwbGFjZSB0aGUgZXh0ZW5zaW9uIGluLlxuICogQHBhcmFtIHtzdHJpbmd9IGV4dGVuc2lvbiBUaGUgbmV3IGV4dGVuc2lvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2VFeHRlbnNpb24oaW5QYXRoOiBzdHJpbmcsIGV4dGVuc2lvbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKCFpblBhdGggfHwgdHlwZW9mIGluUGF0aCAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gaW5QYXRoO1xuICB9XG4gIGNvbnN0IG5ld1BhdGggPSBjcGF0aC5iYXNlbmFtZShpblBhdGgsIGNwYXRoLmV4dG5hbWUoaW5QYXRoKSkgKyBleHRlbnNpb24ucmVwbGFjZSgvXlxcLj8vLCAnLicpO1xuICByZXR1cm4gY3BhdGguam9pbihjcGF0aC5kaXJuYW1lKGluUGF0aCksIG5ld1BhdGgpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElUZW1wT3B0aW9ucyB7XG4gIG1vZGU/OiBudW1iZXI7XG4gIHByZWZpeD86IHN0cmluZztcbiAgcG9zdGZpeD86IHN0cmluZztcbiAga2VlcD86IGJvb2xlYW47XG4gIHJlY3Vyc2l2ZUNsZWFudXA/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElUZW1wRGlyUmVzdWx0IHtcbiAgcGF0aDogc3RyaW5nO1xuICByZW1vdmU6ICgpID0+IHZvaWQ7XG59XG4iXX0=