turbo-gulp
Version:
Gulp tasks to boost high-quality projects.
286 lines (284 loc) • 45.5 kB
JavaScript
;
/**
* This module defines the _lib_ target type used to create libraries for other projects.
*
* In the following list of tasks, `{target}` represents the name of the target as defined by the `name` property
* of the target options.
* The _lib_ target provides the following tasks:
*
* ## {target}:build
*
* Performs a full build of the library to the build directory, used for development.
* This copies the static assets and compiles the scripts.
*
* The following sub-tasks are available:
* - `{target}:build:copy`: Only copy the static assets
* - `{target}:build:script`: Only compile the scripts
*
* For distribution builds, use `{target:dist}`
*
* ## {target}:watch
*
* Watch the files and run incremental builds on change.
* This useful during development to get build errors reported immediately or accelerate the code/test cycle.
* You can combine it with _Nodemon_ to continuously restart your Node process when changing the source.
*
* ## {target}:dist
*
* Performs a full build of the library to the dist directory, used for distribution (ie. publication to _npm_).
* This build creates a fully autonomous directory with its own `package.json`, source code, license file, etc.
* This allows to use a different structure for distribution rather than structure of the repo, the main benefit is
* to provide support for deep package imports (`import * as mod from "my-lib/deep/module"`) by placing the build
* at the root of the package.
* This build also allows you to remap the `package.json`, for example to set the version dynamically.
*
* The following sub-tasks are available:
* - `{target}:dist:publish`: Publish the package to an _npm_ registry (it honors the `registry` option, to publish
* to private _npm_ registries such as _Verdaccio_). It uses the authentication token of the current user, this
* token is in `~/.npmrc`. For CI, you can use the following command to set the token the registry `npm.example.com`.
* (for the official registry, use `//registry.npmjs.org`):
* ```
* echo "//npm.example.com/:_authToken=\"${NPM_TOKEN}\"" > ~/.npmrc
* ```
* - `{target}:dist:copy-src`: Only copy the source files to the build directory.
* - `{target}:dist:package.json`: Copy (and eventually transform) the root `package.json` to the build directory.
*
* For development builds, use `{target:build}`.
*
* ## {target}:typedoc
*
* Generate _Typedoc_ documentation.
*
* ## {target}:typedoc:deploy
*
* Deploy the _Typedoc_ documentation using _git_. This can be used to easily deploy the documentation to the
* `gh-pages` branch.
*
* ## {target}:clean
*
* Remove both the build and dist directories corresponding to this target.
*
* ## {target}:tsconfig.json
*
* Emit a `tsconfig.json` file corresponding to the configuration for this target. This allows to compile it using
* the command line `tsc` program. This is also useful for IDE to auto-detect the configuration of the project.
*
* @module targets/lib
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const minimatch_1 = require("minimatch");
const path_1 = __importDefault(require("path"));
const build_typescript_1 = require("../target-tasks/build-typescript");
const typedoc_1 = require("../target-tasks/typedoc");
const branch_publish_1 = require("../utils/branch-publish");
const git_1 = require("../utils/git");
const matcher = __importStar(require("../utils/matcher"));
const npm_publish_1 = require("../utils/npm-publish");
const project_1 = require("../utils/project");
const _base_1 = require("./_base");
/**
* Resolve absolute paths and dependencies for the provided target.
*
* @param target Non-resolved target.
* @return Resolved target.
*/
function resolveLibTarget(target) {
const base = _base_1.resolveTargetBase(target);
let typedoc = undefined;
if (target.typedoc !== undefined) {
typedoc = {
dir: path_1.default.posix.join(base.project.absRoot, target.typedoc.dir),
name: target.typedoc.name,
deploy: target.typedoc.deploy,
};
}
let dist;
if (target.dist === undefined || target.dist === false) {
dist = false;
}
else {
const defaultDistDir = path_1.default.posix.join(base.project.absDistDir, target.name);
const defaultPackageJsonMap = pkg => pkg;
const defaultCopy = (dest) => [{
files: ["./*.md"],
}];
if (target.dist === true) { // `true` literal
dist = {
distDir: defaultDistDir,
packageJsonMap: defaultPackageJsonMap,
npmPublish: {},
copySrc: true,
copy: defaultCopy(defaultDistDir),
};
}
else {
const distDir = target.dist.distDir !== undefined ? target.dist.distDir : defaultDistDir;
dist = {
distDir,
packageJsonMap: target.dist.packageJsonMap !== undefined ? target.dist.packageJsonMap : defaultPackageJsonMap,
npmPublish: target.dist.npmPublish,
copySrc: target.dist.copySrc !== undefined ? target.dist.copySrc : true,
copy: defaultCopy(distDir),
};
}
}
return Object.assign({}, base, { mainModule: target.mainModule, typedoc, dist });
}
/**
* Generates gulp tasks for the provided lib target.
*
* @param gulp Gulp instance used to generate tasks manipulating files.
* @param targetOptions Target configuration.
*/
function generateLibTasks(gulp, targetOptions) {
const target = resolveLibTarget(targetOptions);
const result = _base_1.generateBaseTasks(gulp, targetOptions);
const tsOptions = {
tscOptions: target.tscOptions,
tsconfigJson: target.tsconfigJson,
customTypingsDir: target.customTypingsDir,
packageJson: target.project.absPackageJson,
buildDir: target.buildDir,
srcDir: target.srcDir,
scripts: target.scripts,
outModules: target.outModules,
};
// typedoc
if (target.typedoc !== undefined) {
const typedocOptions = target.typedoc;
result.typedoc = _base_1.nameTask(`${target.name}:typedoc`, gulp.series([result.tsconfigJson, typedoc_1.getTypedocTask(gulp, tsOptions, typedocOptions)]));
// typedoc:deploy
if (typedocOptions.deploy !== undefined) {
const deploy = typedocOptions.deploy;
async function deployTypedocTask() {
const commitMessage = `Deploy documentation for ${await git_1.getHeadHash()}`;
return branch_publish_1.branchPublish(Object.assign({}, deploy, { dir: typedocOptions.dir, commitMessage }));
}
result.typedocDeploy = _base_1.nameTask(`${target.name}:typedoc:deploy`, gulp.series(result.typedoc, deployTypedocTask));
}
}
// dist
if (target.dist !== false) {
const dist = target.dist;
const distTasks = [];
const copyTasks = [];
// Locations for compilation: default to the original sources but compile the copied files if copySrc is used
let srcDir = target.srcDir;
let customTypingsDir = target.customTypingsDir;
// dist:copy:scripts
if (target.dist.copySrc) {
srcDir = path_1.default.posix.join(dist.distDir, "_src");
copyTasks.push(_base_1.nameTask(`${target.name}:dist:copy:scripts`, () => {
return gulp
.src([...target.scripts], { base: target.srcDir })
.pipe(gulp.dest(srcDir));
}));
// dist:copy:custom-typings
if (target.customTypingsDir !== null) {
const srcCustomTypingsDir = target.customTypingsDir;
const destCustomTypingsDir = path_1.default.posix.join(dist.distDir, "_custom-typings");
customTypingsDir = destCustomTypingsDir;
copyTasks.push(_base_1.nameTask(`${target.name}:dist:copy:custom-typings`, () => {
return gulp
.src([path_1.default.posix.join(srcCustomTypingsDir, "**/*.d.ts")], { base: srcCustomTypingsDir })
.pipe(gulp.dest(destCustomTypingsDir));
}));
}
// dist:copy:dist
if (target.dist.copy !== undefined) {
const [copyBaseTask, copyBaseWatchTask] = _base_1.getCopy(gulp, target.project.absRoot, target.dist.distDir, target.dist.copy);
copyTasks.push(_base_1.nameTask(`${target.name}:dist:copy:dist`, copyBaseTask));
}
}
// dist:copy:lib
if (target.copy !== undefined) {
const [copyBaseTask, copyBaseWatchTask] = _base_1.getCopy(gulp, target.srcDir, target.dist.distDir, target.copy);
copyTasks.push(_base_1.nameTask(`${target.name}:dist:copy:lib`, copyBaseTask));
}
result.distCopy = _base_1.nameTask(`${target.name}:dist:copy`, gulp.parallel(copyTasks));
// Resolve tsconfig for `dist`
const tsconfigJson = target.tsconfigJson !== null ?
path_1.default.posix.join(srcDir, "tsconfig.json") :
null;
let scripts = [];
if (srcDir !== target.srcDir) {
for (const script of target.scripts) {
scripts.push(matcher.asString(matcher.join(srcDir, matcher.relative(target.srcDir, new minimatch_1.Minimatch(script)))));
}
}
else {
scripts = [...target.scripts];
}
const tsOptions = {
tscOptions: target.tscOptions,
tsconfigJson,
customTypingsDir,
packageJson: target.project.absPackageJson,
buildDir: dist.distDir,
srcDir,
scripts,
outModules: target.outModules,
};
// dist:scripts
distTasks.push(_base_1.nameTask(`${target.name}:dist:scripts`, gulp.series(result.distCopy, build_typescript_1.getBuildTypescriptTask(gulp, tsOptions))));
// dist:package.json
{
async function distPackageJsonTask() {
let pkg = await project_1.readJsonFile(target.project.absPackageJson);
if (typeof target.mainModule === "string") {
pkg.main = target.mainModule;
pkg.types = `${target.mainModule}.d.ts`;
}
pkg.gitHead = await git_1.getHeadHash();
pkg = dist.packageJsonMap(pkg);
return _base_1.gulpBufferSrc("package.json", Buffer.from(JSON.stringify(pkg, null, 2)))
.pipe(gulp.dest(dist.distDir));
}
result.distPackageJson = _base_1.nameTask(`${target.name}:dist:package.json`, distPackageJsonTask);
distTasks.push(result.distPackageJson);
}
const distTask = result.clean !== undefined ?
gulp.series(result.clean, gulp.parallel(distTasks)) :
gulp.parallel(distTasks);
result.dist = _base_1.nameTask(`${target.name}:dist`, distTask);
if (dist.npmPublish !== undefined) {
const npmPublishOptions = dist.npmPublish;
const npmPublishTask = async () => {
return npm_publish_1.npmPublish(Object.assign({}, npmPublishOptions, { directory: dist.distDir }));
};
npmPublishTask.displayName = `${target.name}:dist:publish`;
gulp.task(npmPublishTask);
result.distPublish = _base_1.nameTask(`${target.name}:dist:publish`, gulp.series(distTask, npmPublishTask));
}
}
return result;
}
exports.generateLibTasks = generateLibTasks;
/**
* Generates and registers gulp tasks for the provided lib target.
*
* @param gulp Gulp instance where the tasks will be registered.
* @param targetOptions Target configuration.
*/
function registerLibTasks(gulp, targetOptions) {
const tasks = generateLibTasks(gulp, targetOptions);
for (const key in tasks) {
const task = tasks[key];
if (task !== undefined) {
gulp.task(task);
}
}
return tasks;
}
exports.registerLibTasks = registerLibTasks;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIl9zcmMvdGFyZ2V0cy9saWIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWlFRzs7Ozs7Ozs7Ozs7O0FBS0gseUNBQXNDO0FBQ3RDLGdEQUF3QjtBQU94Qix1RUFBMEU7QUFDMUUscURBQXlEO0FBRXpELDREQUF3RDtBQUN4RCxzQ0FBMkM7QUFDM0MsMERBQTRDO0FBQzVDLHNEQUFrRDtBQUNsRCw4Q0FBNkQ7QUFDN0QsbUNBVWlCO0FBMkpqQjs7Ozs7R0FLRztBQUNILDBCQUEwQixNQUFpQjtJQUN6QyxNQUFNLElBQUksR0FBdUIseUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFM0QsSUFBSSxPQUFPLEdBQXVDLFNBQVMsQ0FBQztJQUM1RCxJQUFJLE1BQU0sQ0FBQyxPQUFPLEtBQUssU0FBUyxFQUFFO1FBQ2hDLE9BQU8sR0FBRztZQUNSLEdBQUcsRUFBRSxjQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQztZQUM5RCxJQUFJLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJO1lBQ3pCLE1BQU0sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU07U0FDOUIsQ0FBQztLQUNIO0lBRUQsSUFBSSxJQUFpQyxDQUFDO0lBQ3RDLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxLQUFLLEVBQUU7UUFDdEQsSUFBSSxHQUFHLEtBQUssQ0FBQztLQUNkO1NBQU07UUFDTCxNQUFNLGNBQWMsR0FBaUIsY0FBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNGLE1BQU0scUJBQXFCLEdBQXNDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDO1FBQzVFLE1BQU0sV0FBVyxHQUEwQyxDQUFDLElBQWtCLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQ2xGLEtBQUssRUFBRSxDQUFDLFFBQVEsQ0FBQzthQUNsQixDQUFDLENBQUM7UUFFSCxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssSUFBSSxFQUFFLEVBQUUsaUJBQWlCO1lBQzNDLElBQUksR0FBRztnQkFDTCxPQUFPLEVBQUUsY0FBYztnQkFDdkIsY0FBYyxFQUFFLHFCQUFxQjtnQkFDckMsVUFBVSxFQUFFLEVBQUU7Z0JBQ2QsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsSUFBSSxFQUFFLFdBQVcsQ0FBQyxjQUFjLENBQUM7YUFDbEMsQ0FBQztTQUNIO2FBQU07WUFDTCxNQUFNLE9BQU8sR0FBaUIsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDO1lBQ3ZHLElBQUksR0FBRztnQkFDTCxPQUFPO2dCQUNQLGNBQWMsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLGNBQWMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxxQkFBcUI7Z0JBQzdHLFVBQVUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVU7Z0JBQ2xDLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUN2RSxJQUFJLEVBQUUsV0FBVyxDQUFDLE9BQU8sQ0FBQzthQUMzQixDQUFDO1NBQ0g7S0FDRjtJQUVELHlCQUFXLElBQUksSUFBRSxVQUFVLEVBQUUsTUFBTSxDQUFDLFVBQVUsRUFBRSxPQUFPLEVBQUUsSUFBSSxJQUFFO0FBQ2pFLENBQUM7QUFXRDs7Ozs7R0FLRztBQUNILDBCQUFpQyxJQUFVLEVBQUUsYUFBd0I7SUFDbkUsTUFBTSxNQUFNLEdBQXNCLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2xFLE1BQU0sTUFBTSxHQUF3Qix5QkFBaUIsQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFFM0UsTUFBTSxTQUFTLEdBQXFCO1FBQ2xDLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVTtRQUM3QixZQUFZLEVBQUUsTUFBTSxDQUFDLFlBQVk7UUFDakMsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLGdCQUFnQjtRQUN6QyxXQUFXLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxjQUFjO1FBQzFDLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtRQUN6QixNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU07UUFDckIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPO1FBQ3ZCLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVTtLQUM5QixDQUFDO0lBRUYsVUFBVTtJQUNWLElBQUksTUFBTSxDQUFDLE9BQU8sS0FBSyxTQUFTLEVBQUU7UUFDaEMsTUFBTSxjQUFjLEdBQW1CLE1BQU0sQ0FBQyxPQUFPLENBQUM7UUFDdEQsTUFBTSxDQUFDLE9BQU8sR0FBRyxnQkFBUSxDQUN2QixHQUFHLE1BQU0sQ0FBQyxJQUFJLFVBQVUsRUFDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsd0JBQWMsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FDcEYsQ0FBQztRQUVGLGlCQUFpQjtRQUNqQixJQUFJLGNBQWMsQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFO1lBQ3ZDLE1BQU0sTUFBTSxHQUFxQixjQUFjLENBQUMsTUFBTSxDQUFDO1lBRXZELEtBQUs7Z0JBQ0gsTUFBTSxhQUFhLEdBQVcsNEJBQTRCLE1BQU0saUJBQVcsRUFBRSxFQUFFLENBQUM7Z0JBQ2hGLE9BQU8sOEJBQWEsbUJBQUssTUFBTSxJQUFFLEdBQUcsRUFBRSxjQUFjLENBQUMsR0FBRyxFQUFFLGFBQWEsSUFBRSxDQUFDO1lBQzVFLENBQUM7WUFFRCxNQUFNLENBQUMsYUFBYSxHQUFHLGdCQUFRLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxpQkFBaUIsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFRLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO1NBQ25IO0tBQ0Y7SUFFRCxPQUFPO0lBQ1AsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLEtBQUssRUFBRTtRQUN6QixNQUFNLElBQUksR0FBd0IsTUFBTSxDQUFDLElBQUksQ0FBQztRQUM5QyxNQUFNLFNBQVMsR0FBbUIsRUFBRSxDQUFDO1FBQ3JDLE1BQU0sU0FBUyxHQUFtQixFQUFFLENBQUM7UUFFckMsNkdBQTZHO1FBQzdHLElBQUksTUFBTSxHQUFpQixNQUFNLENBQUMsTUFBTSxDQUFDO1FBQ3pDLElBQUksZ0JBQWdCLEdBQXdCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztRQUNwRSxvQkFBb0I7UUFDcEIsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUN2QixNQUFNLEdBQUcsY0FBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMvQyxTQUFTLENBQUMsSUFBSSxDQUFDLGdCQUFRLENBQ3JCLEdBQUcsTUFBTSxDQUFDLElBQUksb0JBQW9CLEVBQ2xDLEdBQTBCLEVBQUU7Z0JBQzFCLE9BQU8sSUFBSTtxQkFDUixHQUFHLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFDLElBQUksRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFDLENBQUM7cUJBQy9DLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDN0IsQ0FBQyxDQUNGLENBQUMsQ0FBQztZQUNILDJCQUEyQjtZQUMzQixJQUFJLE1BQU0sQ0FBQyxnQkFBZ0IsS0FBSyxJQUFJLEVBQUU7Z0JBQ3BDLE1BQU0sbUJBQW1CLEdBQWlCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztnQkFDbEUsTUFBTSxvQkFBb0IsR0FBaUIsY0FBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO2dCQUM1RixnQkFBZ0IsR0FBRyxvQkFBb0IsQ0FBQztnQkFDeEMsU0FBUyxDQUFDLElBQUksQ0FBQyxnQkFBUSxDQUNyQixHQUFHLE1BQU0sQ0FBQyxJQUFJLDJCQUEyQixFQUN6QyxHQUEwQixFQUFFO29CQUMxQixPQUFPLElBQUk7eUJBQ1IsR0FBRyxDQUFDLENBQUMsY0FBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsV0FBVyxDQUFDLENBQUMsRUFBRSxFQUFDLElBQUksRUFBRSxtQkFBbUIsRUFBQyxDQUFDO3lCQUNyRixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBcUIsQ0FBQyxDQUFDLENBQUM7Z0JBQzVDLENBQUMsQ0FDRixDQUFDLENBQUM7YUFDSjtZQUVELGlCQUFpQjtZQUNqQixJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRTtnQkFDbEMsTUFBTSxDQUFDLFlBQVksRUFBRSxpQkFBaUIsQ0FBQyxHQUFpQyxlQUFPLENBQzdFLElBQUksRUFDSixNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFDdEIsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQ25CLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUNqQixDQUFDO2dCQUNGLFNBQVMsQ0FBQyxJQUFJLENBQUMsZ0JBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLGlCQUFpQixFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7YUFDekU7U0FDRjtRQUVELGdCQUFnQjtRQUNoQixJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFO1lBQzdCLE1BQU0sQ0FBQyxZQUFZLEVBQUUsaUJBQWlCLENBQUMsR0FBaUMsZUFBTyxDQUM3RSxJQUFJLEVBQ0osTUFBTSxDQUFDLE1BQU0sRUFDYixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFDbkIsTUFBTSxDQUFDLElBQUksQ0FDWixDQUFDO1lBQ0YsU0FBUyxDQUFDLElBQUksQ0FBQyxnQkFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksZ0JBQWdCLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztTQUN4RTtRQUVELE1BQU0sQ0FBQyxRQUFRLEdBQUcsZ0JBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLFlBQVksRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFFakYsOEJBQThCO1FBQzlCLE1BQU0sWUFBWSxHQUF3QixNQUFNLENBQUMsWUFBWSxLQUFLLElBQUksQ0FBQyxDQUFDO1lBQ3RFLGNBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDO1lBQzFDLElBQUksQ0FBQztRQUNQLElBQUksT0FBTyxHQUFhLEVBQUUsQ0FBQztRQUMzQixJQUFJLE1BQU0sS0FBSyxNQUFNLENBQUMsTUFBTSxFQUFFO1lBQzVCLEtBQUssTUFBTSxNQUFNLElBQUksTUFBTSxDQUFDLE9BQU8sRUFBRTtnQkFDbkMsT0FBTyxDQUFDLElBQUksQ0FDVixPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxJQUFJLHFCQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQy9GLENBQUM7YUFDSDtTQUNGO2FBQU07WUFDTCxPQUFPLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUMvQjtRQUVELE1BQU0sU0FBUyxHQUFxQjtZQUNsQyxVQUFVLEVBQUUsTUFBTSxDQUFDLFVBQVU7WUFDN0IsWUFBWTtZQUNaLGdCQUFnQjtZQUNoQixXQUFXLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxjQUFjO1lBQzFDLFFBQVEsRUFBRSxJQUFJLENBQUMsT0FBTztZQUN0QixNQUFNO1lBQ04sT0FBTztZQUNQLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVTtTQUM5QixDQUFDO1FBRUYsZUFBZTtRQUNmLFNBQVMsQ0FBQyxJQUFJLENBQUMsZ0JBQVEsQ0FDckIsR0FBRyxNQUFNLENBQUMsSUFBSSxlQUFlLEVBQzdCLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSx5Q0FBc0IsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FDdEUsQ0FBQyxDQUFDO1FBRUgsb0JBQW9CO1FBQ3BCO1lBQ0UsS0FBSztnQkFDSCxJQUFJLEdBQUcsR0FBZ0IsTUFBTSxzQkFBWSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQ3pFLElBQUksT0FBTyxNQUFNLENBQUMsVUFBVSxLQUFLLFFBQVEsRUFBRTtvQkFDekMsR0FBRyxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDO29CQUM3QixHQUFHLENBQUMsS0FBSyxHQUFHLEdBQUcsTUFBTSxDQUFDLFVBQVUsT0FBTyxDQUFDO2lCQUN6QztnQkFDRCxHQUFHLENBQUMsT0FBTyxHQUFHLE1BQU0saUJBQVcsRUFBRSxDQUFDO2dCQUNsQyxHQUFHLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFFL0IsT0FBTyxxQkFBYSxDQUFDLGNBQWMsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO3FCQUM1RSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNuQyxDQUFDO1lBRUQsTUFBTSxDQUFDLGVBQWUsR0FBRyxnQkFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksb0JBQW9CLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztZQUMzRixTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztTQUN4QztRQUVELE1BQU0sUUFBUSxHQUFpQixNQUFNLENBQUMsS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDO1lBQ3pELElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNyRCxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzNCLE1BQU0sQ0FBQyxJQUFJLEdBQUcsZ0JBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUV4RCxJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssU0FBUyxFQUFFO1lBQ2pDLE1BQU0saUJBQWlCLEdBQXNCLElBQUksQ0FBQyxVQUFVLENBQUM7WUFDN0QsTUFBTSxjQUFjLEdBQWlCLEtBQUssSUFBbUIsRUFBRTtnQkFDN0QsT0FBTyx3QkFBVSxtQkFDWixpQkFBaUIsSUFDcEIsU0FBUyxFQUFFLElBQUksQ0FBQyxPQUFPLElBQ3ZCLENBQUM7WUFDTCxDQUFDLENBQUM7WUFDRixjQUFjLENBQUMsV0FBVyxHQUFHLEdBQUcsTUFBTSxDQUFDLElBQUksZUFBZSxDQUFDO1lBQzNELElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDMUIsTUFBTSxDQUFDLFdBQVcsR0FBRyxnQkFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksZUFBZSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUM7U0FDckc7S0FDRjtJQUVELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUF2S0QsNENBdUtDO0FBRUQ7Ozs7O0dBS0c7QUFDSCwwQkFBaUMsSUFBVSxFQUFFLGFBQXdCO0lBQ25FLE1BQU0sS0FBSyxHQUFhLGdCQUFnQixDQUFDLElBQUksRUFBRSxhQUFhLENBQUMsQ0FBQztJQUM5RCxLQUFLLE1BQU0sR0FBRyxJQUFJLEtBQUssRUFBRTtRQUN2QixNQUFNLElBQUksR0FBb0MsS0FBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzFELElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRTtZQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ2pCO0tBQ0Y7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFURCw0Q0FTQyIsImZpbGUiOiJ0YXJnZXRzL2xpYi5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGhpcyBtb2R1bGUgZGVmaW5lcyB0aGUgX2xpYl8gdGFyZ2V0IHR5cGUgdXNlZCB0byBjcmVhdGUgbGlicmFyaWVzIGZvciBvdGhlciBwcm9qZWN0cy5cbiAqXG4gKiBJbiB0aGUgZm9sbG93aW5nIGxpc3Qgb2YgdGFza3MsIGB7dGFyZ2V0fWAgcmVwcmVzZW50cyB0aGUgbmFtZSBvZiB0aGUgdGFyZ2V0IGFzIGRlZmluZWQgYnkgdGhlIGBuYW1lYCBwcm9wZXJ0eVxuICogb2YgdGhlIHRhcmdldCBvcHRpb25zLlxuICogVGhlIF9saWJfIHRhcmdldCBwcm92aWRlcyB0aGUgZm9sbG93aW5nIHRhc2tzOlxuICpcbiAqICMjIHt0YXJnZXR9OmJ1aWxkXG4gKlxuICogUGVyZm9ybXMgYSBmdWxsIGJ1aWxkIG9mIHRoZSBsaWJyYXJ5IHRvIHRoZSBidWlsZCBkaXJlY3RvcnksIHVzZWQgZm9yIGRldmVsb3BtZW50LlxuICogVGhpcyBjb3BpZXMgdGhlIHN0YXRpYyBhc3NldHMgYW5kIGNvbXBpbGVzIHRoZSBzY3JpcHRzLlxuICpcbiAqIFRoZSBmb2xsb3dpbmcgc3ViLXRhc2tzIGFyZSBhdmFpbGFibGU6XG4gKiAtIGB7dGFyZ2V0fTpidWlsZDpjb3B5YDogT25seSBjb3B5IHRoZSBzdGF0aWMgYXNzZXRzXG4gKiAtIGB7dGFyZ2V0fTpidWlsZDpzY3JpcHRgOiBPbmx5IGNvbXBpbGUgdGhlIHNjcmlwdHNcbiAqXG4gKiBGb3IgZGlzdHJpYnV0aW9uIGJ1aWxkcywgdXNlIGB7dGFyZ2V0OmRpc3R9YFxuICpcbiAqICMjIHt0YXJnZXR9OndhdGNoXG4gKlxuICogV2F0Y2ggdGhlIGZpbGVzIGFuZCBydW4gaW5jcmVtZW50YWwgYnVpbGRzIG9uIGNoYW5nZS5cbiAqIFRoaXMgdXNlZnVsIGR1cmluZyBkZXZlbG9wbWVudCB0byBnZXQgYnVpbGQgZXJyb3JzIHJlcG9ydGVkIGltbWVkaWF0ZWx5IG9yIGFjY2VsZXJhdGUgdGhlIGNvZGUvdGVzdCBjeWNsZS5cbiAqIFlvdSBjYW4gY29tYmluZSBpdCB3aXRoIF9Ob2RlbW9uXyB0byBjb250aW51b3VzbHkgcmVzdGFydCB5b3VyIE5vZGUgcHJvY2VzcyB3aGVuIGNoYW5naW5nIHRoZSBzb3VyY2UuXG4gKlxuICogIyMge3RhcmdldH06ZGlzdFxuICpcbiAqIFBlcmZvcm1zIGEgZnVsbCBidWlsZCBvZiB0aGUgbGlicmFyeSB0byB0aGUgZGlzdCBkaXJlY3RvcnksIHVzZWQgZm9yIGRpc3RyaWJ1dGlvbiAoaWUuIHB1YmxpY2F0aW9uIHRvIF9ucG1fKS5cbiAqIFRoaXMgYnVpbGQgY3JlYXRlcyBhIGZ1bGx5IGF1dG9ub21vdXMgZGlyZWN0b3J5IHdpdGggaXRzIG93biBgcGFja2FnZS5qc29uYCwgc291cmNlIGNvZGUsIGxpY2Vuc2UgZmlsZSwgZXRjLlxuICogVGhpcyBhbGxvd3MgdG8gdXNlIGEgZGlmZmVyZW50IHN0cnVjdHVyZSBmb3IgZGlzdHJpYnV0aW9uIHJhdGhlciB0aGFuIHN0cnVjdHVyZSBvZiB0aGUgcmVwbywgdGhlIG1haW4gYmVuZWZpdCBpc1xuICogdG8gcHJvdmlkZSBzdXBwb3J0IGZvciBkZWVwIHBhY2thZ2UgaW1wb3J0cyAoYGltcG9ydCAqIGFzIG1vZCBmcm9tIFwibXktbGliL2RlZXAvbW9kdWxlXCJgKSBieSBwbGFjaW5nIHRoZSBidWlsZFxuICogYXQgdGhlIHJvb3Qgb2YgdGhlIHBhY2thZ2UuXG4gKiBUaGlzIGJ1aWxkIGFsc28gYWxsb3dzIHlvdSB0byByZW1hcCB0aGUgYHBhY2thZ2UuanNvbmAsIGZvciBleGFtcGxlIHRvIHNldCB0aGUgdmVyc2lvbiBkeW5hbWljYWxseS5cbiAqXG4gKiBUaGUgZm9sbG93aW5nIHN1Yi10YXNrcyBhcmUgYXZhaWxhYmxlOlxuICogLSBge3RhcmdldH06ZGlzdDpwdWJsaXNoYDogUHVibGlzaCB0aGUgcGFja2FnZSB0byBhbiBfbnBtXyByZWdpc3RyeSAoaXQgaG9ub3JzIHRoZSBgcmVnaXN0cnlgIG9wdGlvbiwgdG8gcHVibGlzaFxuICogICB0byBwcml2YXRlIF9ucG1fIHJlZ2lzdHJpZXMgc3VjaCBhcyBfVmVyZGFjY2lvXykuIEl0IHVzZXMgdGhlIGF1dGhlbnRpY2F0aW9uIHRva2VuIG9mIHRoZSBjdXJyZW50IHVzZXIsIHRoaXNcbiAqICAgdG9rZW4gaXMgaW4gYH4vLm5wbXJjYC4gRm9yIENJLCB5b3UgY2FuIHVzZSB0aGUgZm9sbG93aW5nIGNvbW1hbmQgdG8gc2V0IHRoZSB0b2tlbiB0aGUgcmVnaXN0cnkgYG5wbS5leGFtcGxlLmNvbWAuXG4gKiAgIChmb3IgdGhlIG9mZmljaWFsIHJlZ2lzdHJ5LCB1c2UgYC8vcmVnaXN0cnkubnBtanMub3JnYCk6XG4gKiAgIGBgYFxuICogICBlY2hvIFwiLy9ucG0uZXhhbXBsZS5jb20vOl9hdXRoVG9rZW49XFxcIiR7TlBNX1RPS0VOfVxcXCJcIiA+IH4vLm5wbXJjXG4gKiAgIGBgYFxuICogLSBge3RhcmdldH06ZGlzdDpjb3B5LXNyY2A6IE9ubHkgY29weSB0aGUgc291cmNlIGZpbGVzIHRvIHRoZSBidWlsZCBkaXJlY3RvcnkuXG4gKiAtIGB7dGFyZ2V0fTpkaXN0OnBhY2thZ2UuanNvbmA6IENvcHkgKGFuZCBldmVudHVhbGx5IHRyYW5zZm9ybSkgdGhlIHJvb3QgYHBhY2thZ2UuanNvbmAgdG8gdGhlIGJ1aWxkIGRpcmVjdG9yeS5cbiAqXG4gKiBGb3IgZGV2ZWxvcG1lbnQgYnVpbGRzLCB1c2UgYHt0YXJnZXQ6YnVpbGR9YC5cbiAqXG4gKiAjIyB7dGFyZ2V0fTp0eXBlZG9jXG4gKlxuICogR2VuZXJhdGUgX1R5cGVkb2NfIGRvY3VtZW50YXRpb24uXG4gKlxuICogIyMge3RhcmdldH06dHlwZWRvYzpkZXBsb3lcbiAqXG4gKiBEZXBsb3kgdGhlIF9UeXBlZG9jXyBkb2N1bWVudGF0aW9uIHVzaW5nIF9naXRfLiBUaGlzIGNhbiBiZSB1c2VkIHRvIGVhc2lseSBkZXBsb3kgdGhlIGRvY3VtZW50YXRpb24gdG8gdGhlXG4gKiBgZ2gtcGFnZXNgIGJyYW5jaC5cbiAqXG4gKiAjIyB7dGFyZ2V0fTpjbGVhblxuICpcbiAqIFJlbW92ZSBib3RoIHRoZSBidWlsZCBhbmQgZGlzdCBkaXJlY3RvcmllcyBjb3JyZXNwb25kaW5nIHRvIHRoaXMgdGFyZ2V0LlxuICpcbiAqICMjIHt0YXJnZXR9OnRzY29uZmlnLmpzb25cbiAqXG4gKiBFbWl0IGEgYHRzY29uZmlnLmpzb25gIGZpbGUgY29ycmVzcG9uZGluZyB0byB0aGUgY29uZmlndXJhdGlvbiBmb3IgdGhpcyB0YXJnZXQuIFRoaXMgYWxsb3dzIHRvIGNvbXBpbGUgaXQgdXNpbmdcbiAqIHRoZSBjb21tYW5kIGxpbmUgYHRzY2AgcHJvZ3JhbS4gVGhpcyBpcyBhbHNvIHVzZWZ1bCBmb3IgSURFIHRvIGF1dG8tZGV0ZWN0IHRoZSBjb25maWd1cmF0aW9uIG9mIHRoZSBwcm9qZWN0LlxuICpcbiAqIEBtb2R1bGUgdGFyZ2V0cy9saWJcbiAqL1xuXG4vKiogKFBsYWNlaG9sZGVyIGNvbW1lbnQsIHNlZSBjaHJpc3RvcGhlcnRoaWVsZW4vdHlwZWRvYy1wbHVnaW4tZXh0ZXJuYWwtbW9kdWxlLW5hbWUjNikgKi9cblxuaW1wb3J0IHsgR3VscCwgVGFza0Z1bmN0aW9uIH0gZnJvbSBcImd1bHBcIjtcbmltcG9ydCB7IE1pbmltYXRjaCB9IGZyb20gXCJtaW5pbWF0Y2hcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBDbGVhbk9wdGlvbnMgfSBmcm9tIFwiLi4vb3B0aW9ucy9jbGVhblwiO1xuaW1wb3J0IHsgQ29weU9wdGlvbnMgfSBmcm9tIFwiLi4vb3B0aW9ucy9jb3B5XCI7XG5pbXBvcnQgeyBDb21waWxlck9wdGlvbnNKc29uIH0gZnJvbSBcIi4uL29wdGlvbnMvdHNjXCI7XG5pbXBvcnQgeyBPdXRNb2R1bGVzIH0gZnJvbSBcIi4uL29wdGlvbnMvdHlwZXNjcmlwdFwiO1xuaW1wb3J0IHsgUmVzb2x2ZWRQcm9qZWN0IH0gZnJvbSBcIi4uL3Byb2plY3RcIjtcbmltcG9ydCB7IFR5cGVzY3JpcHRDb25maWcgfSBmcm9tIFwiLi4vdGFyZ2V0LXRhc2tzL190eXBlc2NyaXB0XCI7XG5pbXBvcnQgeyBnZXRCdWlsZFR5cGVzY3JpcHRUYXNrIH0gZnJvbSBcIi4uL3RhcmdldC10YXNrcy9idWlsZC10eXBlc2NyaXB0XCI7XG5pbXBvcnQgeyBnZXRUeXBlZG9jVGFzayB9IGZyb20gXCIuLi90YXJnZXQtdGFza3MvdHlwZWRvY1wiO1xuaW1wb3J0IHsgQWJzUG9zaXhQYXRoLCBSZWxQb3NpeFBhdGggfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IGJyYW5jaFB1Ymxpc2ggfSBmcm9tIFwiLi4vdXRpbHMvYnJhbmNoLXB1Ymxpc2hcIjtcbmltcG9ydCB7IGdldEhlYWRIYXNoIH0gZnJvbSBcIi4uL3V0aWxzL2dpdFwiO1xuaW1wb3J0ICogYXMgbWF0Y2hlciBmcm9tIFwiLi4vdXRpbHMvbWF0Y2hlclwiO1xuaW1wb3J0IHsgbnBtUHVibGlzaCB9IGZyb20gXCIuLi91dGlscy9ucG0tcHVibGlzaFwiO1xuaW1wb3J0IHsgUGFja2FnZUpzb24sIHJlYWRKc29uRmlsZSB9IGZyb20gXCIuLi91dGlscy9wcm9qZWN0XCI7XG5pbXBvcnQge1xuICBCYXNlVGFza3MsXG4gIGdlbmVyYXRlQmFzZVRhc2tzLFxuICBnZXRDb3B5LFxuICBndWxwQnVmZmVyU3JjLFxuICBuYW1lVGFzayxcbiAgUmVzb2x2ZWRCYXNlRGVwZW5kZW5jaWVzLFxuICBSZXNvbHZlZFRhcmdldEJhc2UsXG4gIHJlc29sdmVUYXJnZXRCYXNlLFxuICBUYXJnZXRCYXNlLFxufSBmcm9tIFwiLi9fYmFzZVwiO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBUeXBlc2NyaXB0IGxpYnJhcnkuXG4gKiBUaGlzIGlzIGNvbXBhdGlibGUgd2l0aCBib3RoIGJyb3dzZXJzIGFuZCBOb2RlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExpYlRhcmdldCBleHRlbmRzIFRhcmdldEJhc2Uge1xuICAvKipcbiAgICogUmVsYXRpdmUgcGF0aCBmb3IgdGhlIG1haW4gbW9kdWxlIChlbnRyeSBwb2ludCBvZiB0aGUgbGliKSBXSVRIT1VUIEVYVEVOU0lPTiwgcmVsYXRpdmUgdG8gYHByb2plY3Quc3JjRGlyYC5cbiAgICogRGVmYXVsdDogYFwiaW5kZXhcImAuXG4gICAqL1xuICBtYWluTW9kdWxlOiBSZWxQb3NpeFBhdGg7XG5cbiAgLyoqXG4gICAqIFBhdGggdG8gdGhlIGB0eXBlZG9jYCBkaXJlY3RvcnksIHJlbGF0aXZlIHRvIGBwcm9qZWN0LnJvb3REaXJgLlxuICAgKiBVc2UgYG51bGxgIHRvIG5vdCBnZW5lcmF0ZSBhIGB0eXBlZG9jYCB0YXNrLlxuICAgKiBEZWZhdWx0OiBgam9pbihwcm9qZWN0LnJvb3REaXIsIFwidHlwZWRvY1wiKWAuXG4gICAqL1xuICB0eXBlZG9jPzogVHlwZWRvY09wdGlvbnM7XG5cbiAgLyoqXG4gICAqIE9wdGlvbnMgZm9yIGRpc3RyaWJ1dGlvbiBidWlsZHMuXG4gICAqIGBmYWxzZWA6IE5vIGRpc3RyaWJ1dGlvbiBidWlsZFxuICAgKiBgdHJ1ZWA6IERpc3RyaWJ1dGlvbiBidWlsZCB3aXRoIGRlZmF1bHRzXG4gICAqIGBEaXN0T3B0aW9uc2A6IFByb3ZpZGUgY3VzdG9tIG9wdGlvbnNcbiAgICogRGVmYXVsdDogYGZhbHNlYCwgbm8gZGlzdHJpYnV0aW9uIGJ1aWxkLlxuICAgKi9cbiAgZGlzdD86IHRydWUgfCBmYWxzZSB8IERpc3RPcHRpb25zO1xufVxuXG4vKipcbiAqIExpYnJhcnkgd2l0aCBmdWxseSByZXNvbHZlZCBwYXRocyBhbmQgZGVwZW5kZW5jaWVzLlxuICovXG5pbnRlcmZhY2UgUmVzb2x2ZWRMaWJUYXJnZXQgZXh0ZW5kcyBMaWJUYXJnZXQsIFJlc29sdmVkVGFyZ2V0QmFzZSB7XG4gIHJlYWRvbmx5IHByb2plY3Q6IFJlc29sdmVkUHJvamVjdDtcblxuICByZWFkb25seSBzcmNEaXI6IEFic1Bvc2l4UGF0aDtcblxuICByZWFkb25seSBidWlsZERpcjogQWJzUG9zaXhQYXRoO1xuXG4gIHJlYWRvbmx5IHNjcmlwdHM6IEl0ZXJhYmxlPHN0cmluZz47XG5cbiAgcmVhZG9ubHkgY3VzdG9tVHlwaW5nc0RpcjogQWJzUG9zaXhQYXRoIHwgbnVsbDtcblxuICByZWFkb25seSB0c2NPcHRpb25zOiBDb21waWxlck9wdGlvbnNKc29uO1xuXG4gIC8qKlxuICAgKiBUT0RPXG4gICAqL1xuICByZWFkb25seSBvdXRNb2R1bGVzOiBPdXRNb2R1bGVzO1xuXG4gIHJlYWRvbmx5IHRzY29uZmlnSnNvbjogQWJzUG9zaXhQYXRoIHwgbnVsbDtcblxuICByZWFkb25seSB0eXBlZG9jPzogUmVzb2x2ZWRUeXBlZG9jT3B0aW9ucztcblxuICByZWFkb25seSBkZXBlbmRlbmNpZXM6IFJlc29sdmVkQmFzZURlcGVuZGVuY2llcztcblxuICByZWFkb25seSBjb3B5PzogQ29weU9wdGlvbnNbXTtcblxuICByZWFkb25seSBjbGVhbj86IENsZWFuT3B0aW9ucztcblxuICByZWFkb25seSBkaXN0OiBmYWxzZSB8IFJlc29sdmVkRGlzdE9wdGlvbnM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGlzdE9wdGlvbnMge1xuICAvKipcbiAgICogRGlyZWN0b3J5IHVzZWQgd2hlcmUgdGhlIGRpc3RyaWJ1dGlvbiBidWlsZHMgd2lsbCBiZSB3cml0dGVuLlxuICAgKiBEZWZhdWx0OiBgcHJvamVjdC5kaXN0RGlyYFxuICAgKi9cbiAgcmVhZG9ubHkgZGlzdERpcj86IFJlbFBvc2l4UGF0aDtcblxuICAvKipcbiAgICogQ29weSB0aGUgc291cmNlcyBmcm9tIGB0YXJnZXQuc3JjRGlyYCB0byBgdGFyZ2V0LmRpc3QuZGlzdERpcmAuIERlZmF1bHQ6IGB0cnVlYC5cbiAgICovXG4gIHJlYWRvbmx5IGNvcHlTcmM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDb3B5IG9wZXJhdGlvbnMgdG8gcGVyZm9ybSB3aGVuIGRpc3RyaWJ1dGluZyB0aGUgcGFja2FnZS5cbiAgICogVGhlIGRlZmF1bHQgY29waWVzIHRoZSBNYXJrZG93biBmaWxlcyBhdCB0aGUgcHJvamVjdCByb290IChzbyB5b3UgZ2V0IGBSRUFETUUubWRgLCBgTElDRU5TRS5tZGAsIC4uLikuXG4gICAqXG4gICAqIFRoZSBiYXNlIHZhbHVlcyBhcmU6XG4gICAqIC0gYHNyY2A6IGBwcm9qZWN0LnJvb3RgXG4gICAqIC0gYGRlc3RgOiBgZGlzdC5kaXN0RGlyYFxuICAgKi9cbiAgcmVhZG9ubHkgY29weT86IENvcHlPcHRpb25zW107XG5cbiAgcmVhZG9ubHkgbnBtUHVibGlzaD86IE5wbVB1Ymxpc2hPcHRpb25zO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBmdW5jdGlvbiB0byBhcHBseSB3aGVuIGNvcHlpbmcgdGhlIGBwYWNrYWdlLmpzb25gIGZpbGUgdG8gdGhlIGRpc3QgZGlyZWN0b3J5LlxuICAgKi9cbiAgcGFja2FnZUpzb25NYXA/KG9sZDogUGFja2FnZUpzb24pOiBQYWNrYWdlSnNvbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlZERpc3RPcHRpb25zIGV4dGVuZHMgRGlzdE9wdGlvbnMge1xuICAvKipcbiAgICogRGlyZWN0b3J5IHVzZWQgZm9yIGRpc3RyaWJ1dGlvbiBidWlsZHMuXG4gICAqL1xuICByZWFkb25seSBkaXN0RGlyOiBBYnNQb3NpeFBhdGg7XG5cbiAgLyoqXG4gICAqIERlcGVuZGluZyBvbiB0aGUgdmFsdWU6XG4gICAqIC0gYGZhbHNlYDogRG8gbm90IGNvcHkgdGhlIHNvdXJjZSBgLnRzYCBmaWxlc1xuICAgKiAtIGB0cnVlYDogQ29weSB0aGUgc291cmNlIGAudHNgIGZpbGUgZnJvbSBgdGFyZ2V0LnNyY0RpcmAgdG8gYCR7dGFyZ2V0LmRpc3QuZGlzdERpcn0vX3NyY2AuIFRoZSBjdXN0b20gdHlwaW5ncyBhcmVcbiAgICogICBjb3BpZWQgdG8gYF9jdXN0b20tdHlwaW5nc2AuXG4gICAqXG4gICAqIERlZmF1bHQ6IGB0cnVlYC5cbiAgICovXG4gIHJlYWRvbmx5IGNvcHlTcmM6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGFwcGx5IHdoZW4gY29weWluZyB0aGUgYHBhY2thZ2UuanNvbmAgZmlsZSB0byB0aGUgZGlzdCBkaXJlY3RvcnkuXG4gICAqL1xuICBwYWNrYWdlSnNvbk1hcChvbGQ6IFBhY2thZ2VKc29uKTogUGFja2FnZUpzb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHlwZWRvY09wdGlvbnMge1xuICAvKipcbiAgICogUGF0aCB0byB0aGUgYHR5cGVkb2NgIGRpcmVjdG9yeSwgcmVsYXRpdmUgdG8gYHByb2plY3Qucm9vdERpcmAuXG4gICAqIFVzZSBgbnVsbGAgdG8gbm90IGdlbmVyYXRlIGEgYHR5cGVkb2NgIHRhc2suXG4gICAqIERlZmF1bHQ6IGBqb2luKHByb2plY3Qucm9vdERpciwgXCJ0eXBlZG9jXCIpYC5cbiAgICovXG4gIHJlYWRvbmx5IGRpcjogUmVsUG9zaXhQYXRoO1xuXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICByZWFkb25seSBkZXBsb3k/OiBHaXREZXBsb3lPcHRpb25zO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkVHlwZWRvY09wdGlvbnMgZXh0ZW5kcyBUeXBlZG9jT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGRpcjogQWJzUG9zaXhQYXRoO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5wbVB1Ymxpc2hPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRhZyB0byB1c2UgZm9yIHRoaXMgcHVibGljYXRpb24uXG4gICAqXG4gICAqIERlZmF1bHQ6IGBcImxhdGVzdFwiYC5cbiAgICovXG4gIHJlYWRvbmx5IHRhZz86IHN0cmluZztcblxuICAvKipcbiAgICogUGF0aCB0byB0aGUgbnBtIGNvbW1hbmQtbGluZSBwcm9ncmFtLlxuICAgKlxuICAgKiBEZWZhdWx0OiBgXCJucG1cImAgKGFzc3VtZXMgdGhhdCBgbnBtYCBpcyBpbiB0aGUgYCRQQVRIYClcbiAgICovXG4gIHJlYWRvbmx5IGNvbW1hbmQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2l0RGVwbG95T3B0aW9ucyB7XG4gIHJlYWRvbmx5IHJlcG9zaXRvcnk6IHN0cmluZztcbiAgcmVhZG9ubHkgYnJhbmNoOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNvbW1pdEF1dGhvcj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGFic29sdXRlIHBhdGhzIGFuZCBkZXBlbmRlbmNpZXMgZm9yIHRoZSBwcm92aWRlZCB0YXJnZXQuXG4gKlxuICogQHBhcmFtIHRhcmdldCBOb24tcmVzb2x2ZWQgdGFyZ2V0LlxuICogQHJldHVybiBSZXNvbHZlZCB0YXJnZXQuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVMaWJUYXJnZXQodGFyZ2V0OiBMaWJUYXJnZXQpOiBSZXNvbHZlZExpYlRhcmdldCB7XG4gIGNvbnN0IGJhc2U6IFJlc29sdmVkVGFyZ2V0QmFzZSA9IHJlc29sdmVUYXJnZXRCYXNlKHRhcmdldCk7XG5cbiAgbGV0IHR5cGVkb2M6IFJlc29sdmVkVHlwZWRvY09wdGlvbnMgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gIGlmICh0YXJnZXQudHlwZWRvYyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdHlwZWRvYyA9IHtcbiAgICAgIGRpcjogcGF0aC5wb3NpeC5qb2luKGJhc2UucHJvamVjdC5hYnNSb290LCB0YXJnZXQudHlwZWRvYy5kaXIpLFxuICAgICAgbmFtZTogdGFyZ2V0LnR5cGVkb2MubmFtZSxcbiAgICAgIGRlcGxveTogdGFyZ2V0LnR5cGVkb2MuZGVwbG95LFxuICAgIH07XG4gIH1cblxuICBsZXQgZGlzdDogUmVzb2x2ZWREaXN0T3B0aW9ucyB8IGZhbHNlO1xuICBpZiAodGFyZ2V0LmRpc3QgPT09IHVuZGVmaW5lZCB8fCB0YXJnZXQuZGlzdCA9PT0gZmFsc2UpIHtcbiAgICBkaXN0ID0gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgZGVmYXVsdERpc3REaXI6IEFic1Bvc2l4UGF0aCA9IHBhdGgucG9zaXguam9pbihiYXNlLnByb2plY3QuYWJzRGlzdERpciwgdGFyZ2V0Lm5hbWUpO1xuICAgIGNvbnN0IGRlZmF1bHRQYWNrYWdlSnNvbk1hcDogKHBrZzogUGFja2FnZUpzb24pID0+IFBhY2thZ2VKc29uID0gcGtnID0+IHBrZztcbiAgICBjb25zdCBkZWZhdWx0Q29weTogKGRlc3Q6IEFic1Bvc2l4UGF0aCkgPT4gQ29weU9wdGlvbnNbXSA9IChkZXN0OiBBYnNQb3NpeFBhdGgpID0+IFt7XG4gICAgICBmaWxlczogW1wiLi8qLm1kXCJdLFxuICAgIH1dO1xuXG4gICAgaWYgKHRhcmdldC5kaXN0ID09PSB0cnVlKSB7IC8vIGB0cnVlYCBsaXRlcmFsXG4gICAgICBkaXN0ID0ge1xuICAgICAgICBkaXN0RGlyOiBkZWZhdWx0RGlzdERpcixcbiAgICAgICAgcGFja2FnZUpzb25NYXA6IGRlZmF1bHRQYWNrYWdlSnNvbk1hcCxcbiAgICAgICAgbnBtUHVibGlzaDoge30sXG4gICAgICAgIGNvcHlTcmM6IHRydWUsXG4gICAgICAgIGNvcHk6IGRlZmF1bHRDb3B5KGRlZmF1bHREaXN0RGlyKSxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRpc3REaXI6IEFic1Bvc2l4UGF0aCA9IHRhcmdldC5kaXN0LmRpc3REaXIgIT09IHVuZGVmaW5lZCA/IHRhcmdldC5kaXN0LmRpc3REaXIgOiBkZWZhdWx0RGlzdERpcjtcbiAgICAgIGRpc3QgPSB7XG4gICAgICAgIGRpc3REaXIsXG4gICAgICAgIHBhY2thZ2VKc29uTWFwOiB0YXJnZXQuZGlzdC5wYWNrYWdlSnNvbk1hcCAhPT0gdW5kZWZpbmVkID8gdGFyZ2V0LmRpc3QucGFja2FnZUpzb25NYXAgOiBkZWZhdWx0UGFja2FnZUpzb25NYXAsXG4gICAgICAgIG5wbVB1Ymxpc2g6IHRhcmdldC5kaXN0Lm5wbVB1Ymxpc2gsXG4gICAgICAgIGNvcHlTcmM6IHRhcmdldC5kaXN0LmNvcHlTcmMgIT09IHVuZGVmaW5lZCA/IHRhcmdldC5kaXN0LmNvcHlTcmMgOiB0cnVlLFxuICAgICAgICBjb3B5OiBkZWZhdWx0Q29weShkaXN0RGlyKSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsuLi5iYXNlLCBtYWluTW9kdWxlOiB0YXJnZXQubWFpbk1vZHVsZSwgdHlwZWRvYywgZGlzdH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGliVGFza3MgZXh0ZW5kcyBCYXNlVGFza3Mge1xuICB0eXBlZG9jPzogVGFza0Z1bmN0aW9uO1xuICB0eXBlZG9jRGVwbG95PzogVGFza0Z1bmN0aW9uO1xuICBkaXN0PzogVGFza0Z1bmN0aW9uO1xuICBkaXN0Q29weT86IFRhc2tGdW5jdGlvbjtcbiAgZGlzdFB1Ymxpc2g/OiBUYXNrRnVuY3Rpb247XG4gIGRpc3RQYWNrYWdlSnNvbj86IFRhc2tGdW5jdGlvbjtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgZ3VscCB0YXNrcyBmb3IgdGhlIHByb3ZpZGVkIGxpYiB0YXJnZXQuXG4gKlxuICogQHBhcmFtIGd1bHAgR3VscCBpbnN0YW5jZSB1c2VkIHRvIGdlbmVyYXRlIHRhc2tzIG1hbmlwdWxhdGluZyBmaWxlcy5cbiAqIEBwYXJhbSB0YXJnZXRPcHRpb25zIFRhcmdldCBjb25maWd1cmF0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVMaWJUYXNrcyhndWxwOiBHdWxwLCB0YXJnZXRPcHRpb25zOiBMaWJUYXJnZXQpOiBMaWJUYXNrcyB7XG4gIGNvbnN0IHRhcmdldDogUmVzb2x2ZWRMaWJUYXJnZXQgPSByZXNvbHZlTGliVGFyZ2V0KHRhcmdldE9wdGlvbnMpO1xuICBjb25zdCByZXN1bHQ6IExpYlRhc2tzID0gPExpYlRhc2tzPiBnZW5lcmF0ZUJhc2VUYXNrcyhndWxwLCB0YXJnZXRPcHRpb25zKTtcblxuICBjb25zdCB0c09wdGlvbnM6IFR5cGVzY3JpcHRDb25maWcgPSB7XG4gICAgdHNjT3B0aW9uczogdGFyZ2V0LnRzY09wdGlvbnMsXG4gICAgdHNjb25maWdKc29uOiB0YXJnZXQudHNjb25maWdKc29uLFxuICAgIGN1c3RvbVR5cGluZ3NEaXI6IHRhcmdldC5jdXN0b21UeXBpbmdzRGlyLFxuICAgIHBhY2thZ2VKc29uOiB0YXJnZXQucHJvamVjdC5hYnNQYWNrYWdlSnNvbixcbiAgICBidWlsZERpcjogdGFyZ2V0LmJ1aWxkRGlyLFxuICAgIHNyY0RpcjogdGFyZ2V0LnNyY0RpcixcbiAgICBzY3JpcHRzOiB0YXJnZXQuc2NyaXB0cyxcbiAgICBvdXRNb2R1bGVzOiB0YXJnZXQub3V0TW9kdWxlcyxcbiAgfTtcblxuICAvLyB0eXBlZG9jXG4gIGlmICh0YXJnZXQudHlwZWRvYyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgdHlwZWRvY09wdGlvbnM6IFR5cGVkb2NPcHRpb25zID0gdGFyZ2V0LnR5cGVkb2M7XG4gICAgcmVzdWx0LnR5cGVkb2MgPSBuYW1lVGFzayhcbiAgICAgIGAke3RhcmdldC5uYW1lfTp0eXBlZG9jYCxcbiAgICAgIGd1bHAuc2VyaWVzKFtyZXN1bHQudHNjb25maWdKc29uLCBnZXRUeXBlZG9jVGFzayhndWxwLCB0c09wdGlvbnMsIHR5cGVkb2NPcHRpb25zKV0pLFxuICAgICk7XG5cbiAgICAvLyB0eXBlZG9jOmRlcGxveVxuICAgIGlmICh0eXBlZG9jT3B0aW9ucy5kZXBsb3kgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgZGVwbG95OiBHaXREZXBsb3lPcHRpb25zID0gdHlwZWRvY09wdGlvbnMuZGVwbG95O1xuXG4gICAgICBhc3luYyBmdW5jdGlvbiBkZXBsb3lUeXBlZG9jVGFzaygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgY29tbWl0TWVzc2FnZTogc3RyaW5nID0gYERlcGxveSBkb2N1bWVudGF0aW9uIGZvciAke2F3YWl0IGdldEhlYWRIYXNoKCl9YDtcbiAgICAgICAgcmV0dXJuIGJyYW5jaFB1Ymxpc2goey4uLmRlcGxveSwgZGlyOiB0eXBlZG9jT3B0aW9ucy5kaXIsIGNvbW1pdE1lc3NhZ2V9KTtcbiAgICAgIH1cblxuICAgICAgcmVzdWx0LnR5cGVkb2NEZXBsb3kgPSBuYW1lVGFzayhgJHt0YXJnZXQubmFtZX06dHlwZWRvYzpkZXBsb3lgLCBndWxwLnNlcmllcyhyZXN1bHQudHlwZWRvYyEsIGRlcGxveVR5cGVkb2NUYXNrKSk7XG4gICAgfVxuICB9XG5cbiAgLy8gZGlzdFxuICBpZiAodGFyZ2V0LmRpc3QgIT09IGZhbHNlKSB7XG4gICAgY29uc3QgZGlzdDogUmVzb2x2ZWREaXN0T3B0aW9ucyA9IHRhcmdldC5kaXN0O1xuICAgIGNvbnN0IGRpc3RUYXNrczogVGFza0Z1bmN0aW9uW10gPSBbXTtcbiAgICBjb25zdCBjb3B5VGFza3M6IFRhc2tGdW5jdGlvbltdID0gW107XG5cbiAgICAvLyBMb2NhdGlvbnMgZm9yIGNvbXBpbGF0aW9uOiBkZWZhdWx0IHRvIHRoZSBvcmlnaW5hbCBzb3VyY2VzIGJ1dCBjb21waWxlIHRoZSBjb3BpZWQgZmlsZXMgaWYgY29weVNyYyBpcyB1c2VkXG4gICAgbGV0IHNyY0RpcjogQWJzUG9zaXhQYXRoID0gdGFyZ2V0LnNyY0RpcjtcbiAgICBsZXQgY3VzdG9tVHlwaW5nc0RpcjogQWJzUG9zaXhQYXRoIHwgbnVsbCA9IHRhcmdldC5jdXN0b21UeXBpbmdzRGlyO1xuICAgIC8vIGRpc3Q6Y29weTpzY3JpcHRzXG4gICAgaWYgKHRhcmdldC5kaXN0LmNvcHlTcmMpIHtcbiAgICAgIHNyY0RpciA9IHBhdGgucG9zaXguam9pbihkaXN0LmRpc3REaXIsIFwiX3NyY1wiKTtcbiAgICAgIGNvcHlUYXNrcy5wdXNoKG5hbWVUYXNrKFxuICAgICAgICBgJHt0YXJnZXQubmFtZX06ZGlzdDpjb3B5OnNjcmlwdHNgLFxuICAgICAgICAoKTogTm9kZUpTLlJlYWRhYmxlU3RyZWFtID0+IHtcbiAgICAgICAgICByZXR1cm4gZ3VscFxuICAgICAgICAgICAgLnNyYyhbLi4udGFyZ2V0LnNjcmlwdHNdLCB7YmFzZTogdGFyZ2V0LnNyY0Rpcn0pXG4gICAgICAgICAgICAucGlwZShndWxwLmRlc3Qoc3JjRGlyKSk7XG4gICAgICAgIH0sXG4gICAgICApKTtcbiAgICAgIC8vIGRpc3Q6Y29weTpjdXN0b20tdHlwaW5nc1xuICAgICAgaWYgKHRhcmdldC5jdXN0b21UeXBpbmdzRGlyICE9PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IHNyY0N1c3RvbVR5cGluZ3NEaXI6IEFic1Bvc2l4UGF0aCA9IHRhcmdldC5jdXN0b21UeXBpbmdzRGlyO1xuICAgICAgICBjb25zdCBkZXN0Q3VzdG9tVHlwaW5nc0RpcjogQWJzUG9zaXhQYXRoID0gcGF0aC5wb3NpeC5qb2luKGRpc3QuZGlzdERpciwgXCJfY3VzdG9tLXR5cGluZ3NcIik7XG4gICAgICAgIGN1c3RvbVR5cGluZ3NEaXIgPSBkZXN0Q3VzdG9tVHlwaW5nc0RpcjtcbiAgICAgICAgY29weVRhc2tzLnB1c2gobmFtZVRhc2soXG4gICAgICAgICAgYCR7dGFyZ2V0Lm5hbWV9OmRpc3Q6Y29weTpjdXN0b20tdHlwaW5nc2AsXG4gICAgICAgICAgKCk6IE5vZGVKUy5SZWFkYWJsZVN0cmVhbSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gZ3VscFxuICAgICAgICAgICAgICAuc3JjKFtwYXRoLnBvc2l4LmpvaW4oc3JjQ3VzdG9tVHlwaW5nc0RpciwgXCIqKi8qLmQudHNcIildLCB7YmFzZTogc3JjQ3VzdG9tVHlwaW5nc0Rpcn0pXG4gICAgICAgICAgICAgIC5waXBlKGd1bHAuZGVzdChkZXN0Q3VzdG9tVHlwaW5nc0RpciEpKTtcbiAgICAgICAgICB9LFxuICAgICAgICApKTtcbiAgICAgIH1cblxuICAgICAgLy8gZGlzdDpjb3B5OmRpc3RcbiAgICAgIGlmICh0YXJnZXQuZGlzdC5jb3B5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgW2NvcHlCYXNlVGFzaywgY29weUJhc2VXYXRjaFRhc2tdOiBbVGFza0Z1bmN0aW9uLCBUYXNrRnVuY3Rpb25dID0gZ2V0Q29weShcbiAgICAgICAgICBndWxwLFxuICAgICAgICAgIHRhcmdldC5wcm9qZWN0LmFic1Jvb3QsXG4gICAgICAgICAgdGFyZ2V0LmRpc3QuZGlzdERpcixcbiAgICAgICAgICB0YXJnZXQuZGlzdC5jb3B5LFxuICAgICAgICApO1xuICAgICAgICBjb3B5VGFza3MucHVzaChuYW1lVGFzayhgJHt0YXJnZXQubmFtZX06ZGlzdDpjb3B5OmRpc3RgLCBjb3B5QmFzZVRhc2spKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBkaXN0OmNvcHk6bGliXG4gICAgaWYgKHRhcmdldC5jb3B5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IFtjb3B5QmFzZVRhc2ssIGNvcHlCYXNlV2F0Y2hUYXNrXTogW1Rhc2tGdW5jdGlvbiwgVGFza0Z1bmN0aW9uXSA9IGdldENvcHkoXG4gICAgICAgIGd1bHAsXG4gICAgICAgIHRhcmdldC5zcmNEaXIsXG4gICAgICAgIHRhcmdldC5kaXN0LmRpc3REaXIsXG4gICAgICAgIHRhcmdldC5jb3B5LFxuICAgICAgKTtcbiAgICAgIGNvcHlUYXNrcy5wdXNoKG5hbWVUYXNrKGAke3RhcmdldC5uYW1lfTpkaXN0OmNvcHk6bGliYCwgY29weUJhc2VUYXNrKSk7XG4gICAgfVxuXG4gICAgcmVzdWx0LmRpc3RDb3B5ID0gbmFtZVRhc2soYCR7dGFyZ2V0Lm5hbWV9OmRpc3Q6Y29weWAsIGd1bHAucGFyYWxsZWwoY29weVRhc2tzKSk7XG5cbiAgICAvLyBSZXNvbHZlIHRzY29uZmlnIGZvciBgZGlzdGBcbiAgICBjb25zdCB0c2NvbmZpZ0pzb246IEFic1Bvc2l4UGF0aCB8IG51bGwgPSB0YXJnZXQudHNjb25maWdKc29uICE9PSBudWxsID9cbiAgICAgIHBhdGgucG9zaXguam9pbihzcmNEaXIsIFwidHNjb25maWcuanNvblwiKSA6XG4gICAgICBudWxsO1xuICAgIGxldCBzY3JpcHRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGlmIChzcmNEaXIgIT09IHRhcmdldC5zcmNEaXIpIHtcbiAgICAgIGZvciAoY29uc3Qgc2NyaXB0IG9mIHRhcmdldC5zY3JpcHRzKSB7XG4gICAgICAgIHNjcmlwdHMucHVzaChcbiAgICAgICAgICBtYXRjaGVyLmFzU3RyaW5nKG1hdGNoZXIuam9pbihzcmNEaXIsIG1hdGNoZXIucmVsYXRpdmUodGFyZ2V0LnNyY0RpciwgbmV3IE1pbmltYXRjaChzY3JpcHQpKSkpLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzY3JpcHRzID0gWy4uLnRhcmdldC5zY3JpcHRzXTtcbiAgICB9XG5cbiAgICBjb25zdCB0c09wdGlvbnM6IFR5cGVzY3JpcHRDb25maWcgPSB7XG4gICAgICB0c2NPcHRpb25zOiB0YXJnZXQudHNjT3B0aW9ucyxcbiAgICAgIHRzY29uZmlnSnNvbixcbiAgICAgIGN1c3RvbVR5cGluZ3NEaXIsXG4gICAgICBwYWNrYWdlSnNvbjogdGFyZ2V0LnByb2plY3QuYWJzUGFja2FnZUpzb24sXG4gICAgICBidWlsZERpcjogZGlzdC5kaXN0RGlyLFxuICAgICAgc3JjRGlyLFxuICAgICAgc2NyaXB0cyxcbiAgICAgIG91dE1vZHVsZXM6IHRhcmdldC5vdXRNb2R1bGVzLFxuICAgIH07XG5cbiAgICAvLyBkaXN0OnNjcmlwdHNcbiAgICBkaXN0VGFza3MucHVzaChuYW1lVGFzayhcbiAgICAgIGAke3RhcmdldC5uYW1lfTpkaXN0OnNjcmlwdHNgLFxuICAgICAgZ3VscC5zZXJpZXMocmVzdWx0LmRpc3RDb3B5LCBnZXRCdWlsZFR5cGVzY3JpcHRUYXNrKGd1bHAsIHRzT3B0aW9ucykpLFxuICAgICkpO1xuXG4gICAgLy8gZGlzdDpwYWNrYWdlLmpzb25cbiAgICB7XG4gICAgICBhc3luYyBmdW5jdGlvbiBkaXN0UGFja2FnZUpzb25UYXNrKCk6IFByb21pc2U8Tm9kZUpTLlJlYWRhYmxlU3RyZWFtPiB7XG4gICAgICAgIGxldCBwa2c6IFBhY2thZ2VKc29uID0gYXdhaXQgcmVhZEpzb25GaWxlKHRhcmdldC5wcm9qZWN0LmFic1BhY2thZ2VKc29uKTtcbiAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXQubWFpbk1vZHVsZSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIHBrZy5tYWluID0gdGFyZ2V0Lm1haW5Nb2R1bGU7XG4gICAgICAgICAgcGtnLnR5cGVzID0gYCR7dGFyZ2V0Lm1haW5Nb2R1bGV9LmQudHNgO1xuICAgICAgICB9XG4gICAgICAgIHBrZy5naXRIZWFkID0gYXdhaXQgZ2V0SGVhZEhhc2goKTtcbiAgICAgICAgcGtnID0gZGlzdC5wYWNrYWdlSnNvbk1hcChwa2cpO1xuXG4gICAgICAgIHJldHVybiBndWxwQnVmZmVyU3JjKFwicGFja2FnZS5qc29uXCIsIEJ1ZmZlci5mcm9tKEpTT04uc3RyaW5naWZ5KHBrZywgbnVsbCwgMikpKVxuICAgICAgICAgIC5waXBlKGd1bHAuZGVzdChkaXN0LmRpc3REaXIpKTtcbiAgICAgIH1cblxuICAgICAgcmVzdWx0LmRpc3RQYWNrYWdlSnNvbiA9IG5hbWVUYXNrKGAke3RhcmdldC5uYW1lfTpkaXN0OnBhY2thZ2UuanNvbmAsIGRpc3RQYWNrYWdlSnNvblRhc2spO1xuICAgICAgZGlzdFRhc2tzLnB1c2gocmVzdWx0LmRpc3RQYWNrYWdlSnNvbik7XG4gICAgfVxuXG4gICAgY29uc3QgZGlzdFRhc2s6IFRhc2tGdW5jdGlvbiA9IHJlc3VsdC5jbGVhbiAhPT0gdW5kZWZpbmVkID9cbiAgICAgIGd1bHAuc2VyaWVzKHJlc3VsdC5jbGVhbiwgZ3VscC5wYXJhbGxlbChkaXN0VGFza3MpKSA6XG4gICAgICBndWxwLnBhcmFsbGVsKGRpc3RUYXNrcyk7XG4gICAgcmVzdWx0LmRpc3QgPSBuYW1lVGFzayhgJHt0YXJnZXQubmFtZX06ZGlzdGAsIGRpc3RUYXNrKTtcblxuICAgIGlmIChkaXN0Lm5wbVB1Ymxpc2ggIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgbnBtUHVibGlzaE9wdGlvbnM6IE5wbVB1Ymxpc2hPcHRpb25zID0gZGlzdC5ucG1QdWJsaXNoO1xuICAgICAgY29uc3QgbnBtUHVibGlzaFRhc2s6IFRhc2tGdW5jdGlvbiA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgICAgcmV0dXJuIG5wbVB1Ymxpc2goe1xuICAgICAgICAgIC4uLm5wbVB1Ymxpc2hPcHRpb25zLFxuICAgICAgICAgIGRpcmVjdG9yeTogZGlzdC5kaXN0RGlyLFxuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgICBucG1QdWJsaXNoVGFzay5kaXNwbGF5TmFtZSA9IGAke3RhcmdldC5uYW1lfTpkaXN0OnB1Ymxpc2hgO1xuICAgICAgZ3VscC50YXNrKG5wbVB1Ymxpc2hUYXNrKTtcbiAgICAgIHJlc3VsdC5kaXN0UHVibGlzaCA9IG5hbWVUYXNrKGAke3RhcmdldC5uYW1lfTpkaXN0OnB1Ymxpc2hgLCBndWxwLnNlcmllcyhkaXN0VGFzaywgbnBtUHVibGlzaFRhc2spKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhbmQgcmVnaXN0ZXJzIGd1bHAgdGFza3MgZm9yIHRoZSBwcm92aWRlZCBsaWIgdGFyZ2V0LlxuICpcbiAqIEBwYXJhbSBndWxwIEd1bHAgaW5zdGFuY2Ugd2hlcmUgdGhlIHRhc2tzIHdpbGwgYmUgcmVnaXN0ZXJlZC5cbiAqIEBwYXJhbSB0YXJnZXRPcHRpb25zIFRhcmdldCBjb25maWd1cmF0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJMaWJUYXNrcyhndWxwOiBHdWxwLCB0YXJnZXRPcHRpb25zOiBMaWJUYXJnZXQpOiBMaWJUYXNrcyB7XG4gIGNvbnN0IHRhc2tzOiBMaWJUYXNrcyA9IGdlbmVyYXRlTGliVGFza3MoZ3VscCwgdGFyZ2V0T3B0aW9ucyk7XG4gIGZvciAoY29uc3Qga2V5IGluIHRhc2tzKSB7XG4gICAgY29uc3QgdGFzazogVGFza0Z1bmN0aW9uIHwgdW5kZWZpbmVkID0gKDxhbnk+IHRhc2tzKVtrZXldO1xuICAgIGlmICh0YXNrICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGd1bHAudGFzayh0YXNrKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRhc2tzO1xufVxuIl0sInNvdXJjZVJvb3QiOiIuLiJ9