projen
Version:
CDK for software projects
192 lines • 31.9 kB
JavaScript
;
var _a, _b;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReleasableCommits = exports.Version = exports.CHANGES_SINCE_LAST_RELEASE = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const path_1 = require("path");
const component_1 = require("./component");
const dependencies_1 = require("./dependencies");
const node_package_1 = require("./javascript/node-package");
/**
* This command determines if there were any changes since the last release in a cross-platform compatible way.
* It is used as a condition for both the `bump` and the `release` tasks.
*
* Explanation:
* - log commits | git log
* - limit log output to a single line per commit | --oneline
* - looks only at the most recent commit | -1
* - silent grep output | grep -q
* - exits with code 0 if a match is found | grep -q "chore(release):"
* - exits with code 1 if a match is found (reverse-match) | grep -qv "chore(release):"
*/
exports.CHANGES_SINCE_LAST_RELEASE = 'git log --oneline -1 | grep -qv "chore(release):"';
/**
* The default package to be used for commit-and-tag-version
*/
const COMMIT_AND_TAG_VERSION_DEFAULT = "commit-and-tag-version@^12";
class Version extends component_1.Component {
constructor(scope, options) {
super(scope);
this.changelogFileName = "changelog.md";
this.versionFileName = "version.txt";
this.releaseTagFileName = "releasetag.txt";
this.bumpPackage = options.bumpPackage ?? COMMIT_AND_TAG_VERSION_DEFAULT;
this.nextVersionCommand = options.nextVersionCommand;
// This component is language independent.
// However, when in the Node.js ecosystem, we can improve the experience by adding a dev dependency on the bump package.
const node = node_package_1.NodePackage.of(this.project);
if (node) {
const { name: bumpName, version: bumpVersion } = dependencies_1.Dependencies.parseDependency(this.bumpPackage);
if (!node.project.deps.isDependencySatisfied(bumpName, dependencies_1.DependencyType.BUILD, bumpVersion ?? "*")) {
node.project.deps.addDependency(this.bumpPackage, dependencies_1.DependencyType.BUILD);
}
}
const versionInputFile = options.versionInputFile;
const changelogFile = path_1.posix.join(options.artifactsDirectory, this.changelogFileName);
const bumpFile = path_1.posix.join(options.artifactsDirectory, this.versionFileName);
const releaseTagFile = path_1.posix.join(options.artifactsDirectory, this.releaseTagFileName);
const commonEnv = {
OUTFILE: versionInputFile,
CHANGELOG: changelogFile,
BUMPFILE: bumpFile,
RELEASETAG: releaseTagFile,
RELEASE_TAG_PREFIX: options.tagPrefix ?? "",
// doesn't work if custom configuration is long
VERSIONRCOPTIONS: JSON.stringify(options.versionrcOptions),
BUMP_PACKAGE: this.bumpPackage,
};
if (options.nextVersionCommand) {
commonEnv.NEXT_VERSION_COMMAND = options.nextVersionCommand;
}
if (options.releasableCommits) {
commonEnv.RELEASABLE_COMMITS = options.releasableCommits.cmd;
}
this.bumpTask = this.project.addTask("bump", {
description: "Bumps version based on latest git tag and generates a changelog entry",
condition: exports.CHANGES_SINCE_LAST_RELEASE,
env: { ...commonEnv },
});
this.bumpTask.builtin("release/bump-version");
this.unbumpTask = this.project.addTask("unbump", {
description: "Restores version to 0.0.0",
env: { ...commonEnv },
});
this.unbumpTask.builtin("release/reset-version");
this.project.addGitIgnore(`/${changelogFile}`);
this.project.addGitIgnore(`/${bumpFile}`);
this.project.addPackageIgnore(`/${changelogFile}`);
this.project.addPackageIgnore(`/${bumpFile}`);
}
/**
* Return the environment variables to modify the bump command for release branches.
*
* These options are used to modify the behavior of the version bumping script
* for additional branches, by setting environment variables.
*
* No settings are inherited from the base `Version` object (but any parameters that
* control versions do conflict with the use of a `nextVersionCommand`).
*/
envForBranch(branchOptions) {
if (this.nextVersionCommand && branchOptions.minMajorVersion) {
throw new Error("minMajorVersion and nextVersionCommand cannot be used together.");
}
const env = {};
if (branchOptions.majorVersion !== undefined) {
env.MAJOR = branchOptions.majorVersion.toString();
}
if (branchOptions.minMajorVersion !== undefined) {
if (branchOptions.majorVersion !== undefined) {
throw new Error(`minMajorVersion and majorVersion cannot be used together.`);
}
env.MIN_MAJOR = branchOptions.minMajorVersion.toString();
}
if (branchOptions.prerelease) {
env.PRERELEASE = branchOptions.prerelease;
}
if (branchOptions.tagPrefix) {
env.RELEASE_TAG_PREFIX = branchOptions.tagPrefix;
}
return env;
}
}
exports.Version = Version;
_a = JSII_RTTI_SYMBOL_1;
Version[_a] = { fqn: "projen.Version", version: "0.91.29" };
/**
* @deprecated use `version.bumpPackage` on the component instance instead
*/
Version.STANDARD_VERSION = COMMIT_AND_TAG_VERSION_DEFAULT;
/**
* Find commits that should be considered releasable to decide if a release is required.
*/
class ReleasableCommits {
/**
* Release every commit
*
* This will only not release if the most recent commit is tagged with the latest matching tag.
*
* @param path Consider only commits that are enough to explain how the files that match the specified paths came to be.
* This path is relative to the current working dir of the `bump` task, i.e. to only consider commits of a subproject use `"."`.
*/
static everyCommit(path) {
const cmd = `git log --oneline $LATEST_TAG..HEAD`;
return new ReleasableCommits(withPath(cmd, path));
}
/**
* Limit commits by their conventional commit type
*
* This will only release commit that match one of the provided types.
* Commits are required to follow the conventional commit spec and will be ignored otherwise.
*
* @param types List of conventional commit types that should be released
* @param path Consider only commits that are enough to explain how the files that match the specified paths came to be.
* This path is relative to the current working dir of the `bump` task, i.e. to only consider commits of a subproject use `"."`.
*/
static ofType(types, path) {
const allowedTypes = types.join("|");
// @see: https://github.com/conventional-commits/parser/blob/eeefb961ebf5b9dfea0fea8b06f8ad34a1e439b9/lib/parser.js
// -E requires this to be POSIX Extended Regular Expression, which comes with certain limitations
// see https://en.wikibooks.org/wiki/Regular_Expressions/POSIX-Extended_Regular_Expressions for details
const cmd = `git log --no-merges --oneline $LATEST_TAG..HEAD -E --grep "^(${allowedTypes}){1}(\\([^()[:space:]]+\\))?(!)?:[[:blank:]]+.+"`;
return new ReleasableCommits(withPath(cmd, path));
}
/**
* Release only features and fixes
*
* Shorthand for `ReleasableCommits.onlyOfType(['feat', 'fix'])`.
*
* @param path Consider only commits that are enough to explain how the files that match the specified paths came to be.
* This path is relative to the current working dir of the `bump` task, i.e. to only consider commits of a subproject use `"."`.
*/
static featuresAndFixes(path) {
return ReleasableCommits.ofType(["feat", "fix"], path);
}
/**
* Use an arbitrary shell command to find releasable commits since the latest tag.
*
* A new release will be initiated, if the number of returned commits is greater than zero.
* Must return a newline separate list of commits that should considered releasable.
* `$LATEST_TAG` will be replaced with the actual latest tag for the given prefix.*
*
* @example "git log --oneline $LATEST_TAG..HEAD -- ."
*/
static exec(cmd) {
return new ReleasableCommits(cmd);
}
constructor(cmd) {
this.cmd = cmd;
}
}
exports.ReleasableCommits = ReleasableCommits;
_b = JSII_RTTI_SYMBOL_1;
ReleasableCommits[_b] = { fqn: "projen.ReleasableCommits", version: "0.91.29" };
/**
* Append a path argument to a git command if one is provided
*/
function withPath(cmd, path) {
if (path !== undefined) {
return `${cmd} -- ${path}`;
}
return cmd;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0JBQTZCO0FBRTdCLDJDQUF3QztBQUN4QyxpREFBOEQ7QUFDOUQsNERBQXdEO0FBR3hEOzs7Ozs7Ozs7OztHQVdHO0FBQ1UsUUFBQSwwQkFBMEIsR0FDckMsbURBQW1ELENBQUM7QUFFdEQ7O0dBRUc7QUFDSCxNQUFNLDhCQUE4QixHQUFHLDRCQUE0QixDQUFDO0FBc0VwRSxNQUFhLE9BQVEsU0FBUSxxQkFBUztJQWdDcEMsWUFBWSxLQUFpQixFQUFFLE9BQXVCO1FBQ3BELEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUViLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxjQUFjLENBQUM7UUFDeEMsSUFBSSxDQUFDLGVBQWUsR0FBRyxhQUFhLENBQUM7UUFDckMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGdCQUFnQixDQUFDO1FBQzNDLElBQUksQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLFdBQVcsSUFBSSw4QkFBOEIsQ0FBQztRQUN6RSxJQUFJLENBQUMsa0JBQWtCLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDO1FBRXJELDBDQUEwQztRQUMxQyx3SEFBd0g7UUFDeEgsTUFBTSxJQUFJLEdBQUcsMEJBQVcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLElBQUksSUFBSSxFQUFFLENBQUM7WUFDVCxNQUFNLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLEdBQzVDLDJCQUFZLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNqRCxJQUNFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQ3RDLFFBQVEsRUFDUiw2QkFBYyxDQUFDLEtBQUssRUFDcEIsV0FBVyxJQUFJLEdB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SCxpR0FBaUc7UUFDakcsdUdBQXVHO1FBQ3ZHLE1BQU0sR0FBRyxHQUFHLGdFQUFnRSxZQUFZLGtEQUFrRCxDQUFDO1FBRTNJLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsSUFBYTtRQUNuQyxPQUFPLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSCxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQVc7UUFDckIsT0FBTyxJQUFJLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxZQUEyQixHQUFXO1FBQVgsUUFBRyxHQUFILEdBQUcsQ0FBUTtJQUFHLENBQUM7O0FBNUQ1Qyw4Q0E2REM7OztBQUVEOztHQUVHO0FBQ0gsU0FBUyxRQUFRLENBQUMsR0FBVyxFQUFFLElBQWE7SUFDMUMsSUFBSSxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDdkIsT0FBTyxHQUFHLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcG9zaXggfSBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgSUNvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tIFwiLi9jb21wb25lbnRcIjtcbmltcG9ydCB7IERlcGVuZGVuY2llcywgRGVwZW5kZW5jeVR5cGUgfSBmcm9tIFwiLi9kZXBlbmRlbmNpZXNcIjtcbmltcG9ydCB7IE5vZGVQYWNrYWdlIH0gZnJvbSBcIi4vamF2YXNjcmlwdC9ub2RlLXBhY2thZ2VcIjtcbmltcG9ydCB7IFRhc2sgfSBmcm9tIFwiLi90YXNrXCI7XG5cbi8qKlxuICogVGhpcyBjb21tYW5kIGRldGVybWluZXMgaWYgdGhlcmUgd2VyZSBhbnkgY2hhbmdlcyBzaW5jZSB0aGUgbGFzdCByZWxlYXNlIGluIGEgY3Jvc3MtcGxhdGZvcm0gY29tcGF0aWJsZSB3YXkuXG4gKiBJdCBpcyB1c2VkIGFzIGEgY29uZGl0aW9uIGZvciBib3RoIHRoZSBgYnVtcGAgYW5kIHRoZSBgcmVsZWFzZWAgdGFza3MuXG4gKlxuICogRXhwbGFuYXRpb246XG4gKiAgLSBsb2cgY29tbWl0cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBnaXQgbG9nXG4gKiAgLSBsaW1pdCBsb2cgb3V0cHV0IHRvIGEgc2luZ2xlIGxpbmUgcGVyIGNvbW1pdCAgICAgICAgICAgICAgfCAtLW9uZWxpbmVcbiAqICAtIGxvb2tzIG9ubHkgYXQgdGhlIG1vc3QgcmVjZW50IGNvbW1pdCAgICAgICAgICAgICAgICAgICAgICB8IC0xXG4gKiAgLSBzaWxlbnQgZ3JlcCBvdXRwdXQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBncmVwIC1xXG4gKiAgLSBleGl0cyB3aXRoIGNvZGUgMCBpZiBhIG1hdGNoIGlzIGZvdW5kICAgICAgICAgICAgICAgICAgICAgfCBncmVwIC1xIFwiY2hvcmUocmVsZWFzZSk6XCJcbiAqICAtIGV4aXRzIHdpdGggY29kZSAxIGlmIGEgbWF0Y2ggaXMgZm91bmQgKHJldmVyc2UtbWF0Y2gpICAgICB8IGdyZXAgLXF2IFwiY2hvcmUocmVsZWFzZSk6XCJcbiAqL1xuZXhwb3J0IGNvbnN0IENIQU5HRVNfU0lOQ0VfTEFTVF9SRUxFQVNFID1cbiAgJ2dpdCBsb2cgLS1vbmVsaW5lIC0xIHwgZ3JlcCAtcXYgXCJjaG9yZShyZWxlYXNlKTpcIic7XG5cbi8qKlxuICogVGhlIGRlZmF1bHQgcGFja2FnZSB0byBiZSB1c2VkIGZvciBjb21taXQtYW5kLXRhZy12ZXJzaW9uXG4gKi9cbmNvbnN0IENPTU1JVF9BTkRfVEFHX1ZFUlNJT05fREVGQVVMVCA9IFwiY29tbWl0LWFuZC10YWctdmVyc2lvbkBeMTJcIjtcblxuLyoqXG4gKiBPcHRpb25zIGZvciBgVmVyc2lvbmAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmVyc2lvbk9wdGlvbnMge1xuICAvKipcbiAgICogQSBuYW1lIG9mIGEgLmpzb24gZmlsZSB0byBzZXQgdGhlIGB2ZXJzaW9uYCBmaWVsZCBpbiBhZnRlciBhIGJ1bXAuXG4gICAqXG4gICAqIEBleGFtcGxlIFwicGFja2FnZS5qc29uXCJcbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb25JbnB1dEZpbGU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIGRpcmVjdG9yeSBpbnRvIHdoaWNoIGBjaGFuZ2Vsb2cubWRgIGFuZCBgdmVyc2lvbi50eHRgIGZpbGVzXG4gICAqIGFyZSBlbWl0dGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgYXJ0aWZhY3RzRGlyZWN0b3J5OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBjb25maWd1cmF0aW9uIGZvciB2ZXJzaW9ucmMgZmlsZSB1c2VkIGJ5IHN0YW5kYXJkLXJlbGVhc2VcbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb25yY09wdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuXG4gIC8qKlxuICAgKiBUaGUgdGFnIHByZWZpeCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgdmVyc2lvbi5cbiAgICovXG4gIHJlYWRvbmx5IHRhZ1ByZWZpeD86IHN0cmluZztcblxuICAvKipcbiAgICogRmluZCBjb21taXRzIHRoYXQgc2hvdWxkIGJlIGNvbnNpZGVyZWQgcmVsZWFzYWJsZVxuICAgKiBVc2VkIHRvIGRlY2lkZSBpZiBhIHJlbGVhc2UgaXMgcmVxdWlyZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IFJlbGVhc2FibGVDb21taXRzLmV2ZXJ5Q29tbWl0KClcbiAgICovXG4gIHJlYWRvbmx5IHJlbGVhc2FibGVDb21taXRzPzogUmVsZWFzYWJsZUNvbW1pdHM7XG5cbiAgLyoqXG4gICAqIFRoZSBgY29tbWl0LWFuZC10YWctdmVyc2lvbmAgY29tcGF0aWJsZSBwYWNrYWdlIHVzZWQgdG8gYnVtcCB0aGUgcGFja2FnZSB2ZXJzaW9uLCBhcyBhIGRlcGVuZGVuY3kgc3RyaW5nLlxuICAgKlxuICAgKiBUaGlzIGNhbiBiZSBhbnkgY29tcGF0aWJsZSBwYWNrYWdlIHZlcnNpb24sIGluY2x1ZGluZyB0aGUgZGVwcmVjYXRlZCBgc3RhbmRhcmQtdmVyc2lvbkA5YC5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJjb21taXQtYW5kLXRhZy12ZXJzaW9uQDEyXCJcbiAgICovXG4gIHJlYWRvbmx5IGJ1bXBQYWNrYWdlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIHNoZWxsIGNvbW1hbmQgdG8gY29udHJvbCB0aGUgbmV4dCB2ZXJzaW9uIHRvIHJlbGVhc2UuXG4gICAqXG4gICAqIElmIHByZXNlbnQsIHRoaXMgc2hlbGwgY29tbWFuZCB3aWxsIGJlIHJ1biBiZWZvcmUgdGhlIGJ1bXAgaXMgZXhlY3V0ZWQsIGFuZFxuICAgKiBpdCBkZXRlcm1pbmVzIHdoYXQgdmVyc2lvbiB0byByZWxlYXNlLiBJdCB3aWxsIGJlIGV4ZWN1dGVkIGluIHRoZSBmb2xsb3dpbmdcbiAgICogZW52aXJvbm1lbnQ6XG4gICAqXG4gICAqIC0gV29ya2luZyBkaXJlY3Rvcnk6IHRoZSBwcm9qZWN0IGRpcmVjdG9yeS5cbiAgICogLSBgJFZFUlNJT05gOiB0aGUgY3VycmVudCB2ZXJzaW9uLiBMb29rcyBsaWtlIGAxLjIuM2AuXG4gICAqIC0gYCRMQVRFU1RfVEFHYDogdGhlIG1vc3QgcmVjZW50IHRhZy4gTG9va3MgbGlrZSBgcHJlZml4LXYxLjIuM2AsIG9yIG1heSBiZSB1bnNldC5cbiAgICogLSBgJFNVR0dFU1RFRF9CVU1QYDogdGhlIHN1Z2dlc3RlZCBidW1wIGFjdGlvbiBiYXNlZCBvbiBjb21taXRzLiBPbmUgb2YgYG1ham9yfG1pbm9yfHBhdGNofG5vbmVgLlxuICAgKlxuICAgKiBUaGUgY29tbWFuZCBzaG91bGQgcHJpbnQgb25lIG9mIHRoZSBmb2xsb3dpbmcgdG8gYHN0ZG91dGA6XG4gICAqXG4gICAqIC0gTm90aGluZzogdGhlIG5leHQgdmVyc2lvbiBudW1iZXIgd2lsbCBiZSBkZXRlcm1pbmVkIGJhc2VkIG9uIGNvbW1pdCBoaXN0b3J5LlxuICAgKiAtIGB4LnkuemA6IHRoZSBuZXh0IHZlcnNpb24gbnVtYmVyIHdpbGwgYmUgYHgueS56YC5cbiAgICogLSBgbWFqb3J8bWlub3J8cGF0Y2hgOiB0aGUgbmV4dCB2ZXJzaW9uIG51bWJlciB3aWxsIGJlIHRoZSBjdXJyZW50IHZlcnNpb24gbnVtYmVyXG4gICAqICAgd2l0aCB0aGUgaW5kaWNhdGVkIGNvbXBvbmVudCBidW1wZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gVGhlIG5leHQgdmVyc2lvbiB3aWxsIGJlIGRldGVybWluZWQgYmFzZWQgb24gdGhlIGNvbW1pdCBoaXN0b3J5IGFuZCBwcm9qZWN0IHNldHRpbmdzLlxuICAgKi9cbiAgcmVhZG9ubHkgbmV4dFZlcnNpb25Db21tYW5kPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgVmVyc2lvbiBleHRlbmRzIENvbXBvbmVudCB7XG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCB1c2UgYHZlcnNpb24uYnVtcFBhY2thZ2VgIG9uIHRoZSBjb21wb25lbnQgaW5zdGFuY2UgaW5zdGVhZFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBTVEFOREFSRF9WRVJTSU9OID0gQ09NTUlUX0FORF9UQUdfVkVSU0lPTl9ERUZBVUxUO1xuXG4gIHB1YmxpYyByZWFkb25seSBidW1wVGFzazogVGFzaztcbiAgcHVibGljIHJlYWRvbmx5IHVuYnVtcFRhc2s6IFRhc2s7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBjaGFuZ2Vsb2cgZmlsZSAodW5kZXIgYGFydGlmYWN0c0RpcmVjdG9yeWApLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNoYW5nZWxvZ0ZpbGVOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBmaWxlIHRoYXQgY29udGFpbnMgdGhlIHZlcnNpb24gKHVuZGVyIGBhcnRpZmFjdHNEaXJlY3RvcnlgKS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB2ZXJzaW9uRmlsZU5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIGZpbGUgdGhhdCBjb250YWlucyB0aGUgcmVsZWFzZSB0YWcgKHVuZGVyIGBhcnRpZmFjdHNEaXJlY3RvcnlgKS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSByZWxlYXNlVGFnRmlsZU5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHBhY2thZ2UgdXNlZCB0byBidW1wIHBhY2thZ2UgdmVyc2lvbnMsIGFzIGEgZGVwZW5kZW5jeSBzdHJpbmcuXG4gICAqIFRoaXMgaXMgYSBgY29tbWl0LWFuZC10YWctdmVyc2lvbmAgY29tcGF0aWJsZSBwYWNrYWdlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGJ1bXBQYWNrYWdlOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBuZXh0VmVyc2lvbkNvbW1hbmQ/OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IElDb25zdHJ1Y3QsIG9wdGlvbnM6IFZlcnNpb25PcHRpb25zKSB7XG4gICAgc3VwZXIoc2NvcGUpO1xuXG4gICAgdGhpcy5jaGFuZ2Vsb2dGaWxlTmFtZSA9IFwiY2hhbmdlbG9nLm1kXCI7XG4gICAgdGhpcy52ZXJzaW9uRmlsZU5hbWUgPSBcInZlcnNpb24udHh0XCI7XG4gICAgdGhpcy5yZWxlYXNlVGFnRmlsZU5hbWUgPSBcInJlbGVhc2V0YWcudHh0XCI7XG4gICAgdGhpcy5idW1wUGFja2FnZSA9IG9wdGlvbnMuYnVtcFBhY2thZ2UgPz8gQ09NTUlUX0FORF9UQUdfVkVSU0lPTl9ERUZBVUxUO1xuICAgIHRoaXMubmV4dFZlcnNpb25Db21tYW5kID0gb3B0aW9ucy5uZXh0VmVyc2lvbkNvbW1hbmQ7XG5cbiAgICAvLyBUaGlzIGNvbXBvbmVudCBpcyBsYW5ndWFnZSBpbmRlcGVuZGVudC5cbiAgICAvLyBIb3dldmVyLCB3aGVuIGluIHRoZSBOb2RlLmpzIGVjb3N5c3RlbSwgd2UgY2FuIGltcHJvdmUgdGhlIGV4cGVyaWVuY2UgYnkgYWRkaW5nIGEgZGV2IGRlcGVuZGVuY3kgb24gdGhlIGJ1bXAgcGFja2FnZS5cbiAgICBjb25zdCBub2RlID0gTm9kZVBhY2thZ2Uub2YodGhpcy5wcm9qZWN0KTtcbiAgICBpZiAobm9kZSkge1xuICAgICAgY29uc3QgeyBuYW1lOiBidW1wTmFtZSwgdmVyc2lvbjogYnVtcFZlcnNpb24gfSA9XG4gICAgICAgIERlcGVuZGVuY2llcy5wYXJzZURlcGVuZGVuY3kodGhpcy5idW1wUGFja2FnZSk7XG4gICAgICBpZiAoXG4gICAgICAgICFub2RlLnByb2plY3QuZGVwcy5pc0RlcGVuZGVuY3lTYXRpc2ZpZWQoXG4gICAgICAgICAgYnVtcE5hbWUsXG4gICAgICAgICAgRGVwZW5kZW5jeVR5cGUuQlVJTEQsXG4gICAgICAgICAgYnVtcFZlcnNpb24gPz8gXCIqXCJcbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIG5vZGUucHJvamVjdC5kZXBzLmFkZERlcGVuZGVuY3kodGhpcy5idW1wUGFja2FnZSwgRGVwZW5kZW5jeVR5cGUuQlVJTEQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHZlcnNpb25JbnB1dEZpbGUgPSBvcHRpb25zLnZlcnNpb25JbnB1dEZpbGU7XG5cbiAgICBjb25zdCBjaGFuZ2Vsb2dGaWxlID0gcG9zaXguam9pbihcbiAgICAgIG9wdGlvbnMuYXJ0aWZhY3RzRGlyZWN0b3J5LFxuICAgICAgdGhpcy5jaGFuZ2Vsb2dGaWxlTmFtZVxuICAgICk7XG4gICAgY29uc3QgYnVtcEZpbGUgPSBwb3NpeC5qb2luKFxuICAgICAgb3B0aW9ucy5hcnRpZmFjdHNEaXJlY3RvcnksXG4gICAgICB0aGlzLnZlcnNpb25GaWxlTmFtZVxuICAgICk7XG4gICAgY29uc3QgcmVsZWFzZVRhZ0ZpbGUgPSBwb3NpeC5qb2luKFxuICAgICAgb3B0aW9ucy5hcnRpZmFjdHNEaXJlY3RvcnksXG4gICAgICB0aGlzLnJlbGVhc2VUYWdGaWxlTmFtZVxuICAgICk7XG5cbiAgICBjb25zdCBjb21tb25FbnY6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICBPVVRGSUxFOiB2ZXJzaW9uSW5wdXRGaWxlLFxuICAgICAgQ0hBTkdFTE9HOiBjaGFuZ2Vsb2dGaWxlLFxuICAgICAgQlVNUEZJTEU6IGJ1bXBGaWxlLFxuICAgICAgUkVMRUFTRVRBRzogcmVsZWFzZVRhZ0ZpbGUsXG4gICAgICBSRUxFQVNFX1RBR19QUkVGSVg6IG9wdGlvbnMudGFnUHJlZml4ID8/IFwiXCIsXG4gICAgICAvLyBkb2Vzbid0IHdvcmsgaWYgY3VzdG9tIGNvbmZpZ3VyYXRpb24gaXMgbG9uZ1xuICAgICAgVkVSU0lPTlJDT1BUSU9OUzogSlNPTi5zdHJpbmdpZnkob3B0aW9ucy52ZXJzaW9ucmNPcHRpb25zKSxcbiAgICAgIEJVTVBfUEFDS0FHRTogdGhpcy5idW1wUGFja2FnZSxcbiAgICB9O1xuICAgIGlmIChvcHRpb25zLm5leHRWZXJzaW9uQ29tbWFuZCkge1xuICAgICAgY29tbW9uRW52Lk5FWFRfVkVSU0lPTl9DT01NQU5EID0gb3B0aW9ucy5uZXh0VmVyc2lvbkNvbW1hbmQ7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLnJlbGVhc2FibGVDb21taXRzKSB7XG4gICAgICBjb21tb25FbnYuUkVMRUFTQUJMRV9DT01NSVRTID0gb3B0aW9ucy5yZWxlYXNhYmxlQ29tbWl0cy5jbWQ7XG4gICAgfVxuXG4gICAgdGhpcy5idW1wVGFzayA9IHRoaXMucHJvamVjdC5hZGRUYXNrKFwiYnVtcFwiLCB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJCdW1wcyB2ZXJzaW9uIGJhc2VkIG9uIGxhdGVzdCBnaXQgdGFnIGFuZCBnZW5lcmF0ZXMgYSBjaGFuZ2Vsb2cgZW50cnlcIixcbiAgICAgIGNvbmRpdGlvbjogQ0hBTkdFU19TSU5DRV9MQVNUX1JFTEVBU0UsXG4gICAgICBlbnY6IHsgLi4uY29tbW9uRW52IH0sXG4gICAgfSk7XG5cbiAgICB0aGlzLmJ1bXBUYXNrLmJ1aWx0aW4oXCJyZWxlYXNlL2J1bXAtdmVyc2lvblwiKTtcblxuICAgIHRoaXMudW5idW1wVGFzayA9IHRoaXMucHJvamVjdC5hZGRUYXNrKFwidW5idW1wXCIsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlJlc3RvcmVzIHZlcnNpb24gdG8gMC4wLjBcIixcbiAgICAgIGVudjogeyAuLi5jb21tb25FbnYgfSxcbiAgICB9KTtcblxuICAgIHRoaXMudW5idW1wVGFzay5idWlsdGluKFwicmVsZWFzZS9yZXNldC12ZXJzaW9uXCIpO1xuXG4gICAgdGhpcy5wcm9qZWN0LmFkZEdpdElnbm9yZShgLyR7Y2hhbmdlbG9nRmlsZX1gKTtcbiAgICB0aGlzLnByb2plY3QuYWRkR2l0SWdub3JlKGAvJHtidW1wRmlsZX1gKTtcbiAgICB0aGlzLnByb2plY3QuYWRkUGFja2FnZUlnbm9yZShgLyR7Y2hhbmdlbG9nRmlsZX1gKTtcbiAgICB0aGlzLnByb2plY3QuYWRkUGFja2FnZUlnbm9yZShgLyR7YnVtcEZpbGV9YCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgdG8gbW9kaWZ5IHRoZSBidW1wIGNvbW1hbmQgZm9yIHJlbGVhc2UgYnJhbmNoZXMuXG4gICAqXG4gICAqIFRoZXNlIG9wdGlvbnMgYXJlIHVzZWQgdG8gbW9kaWZ5IHRoZSBiZWhhdmlvciBvZiB0aGUgdmVyc2lvbiBidW1waW5nIHNjcmlwdFxuICAgKiBmb3IgYWRkaXRpb25hbCBicmFuY2hlcywgYnkgc2V0dGluZyBlbnZpcm9ubWVudCB2YXJpYWJsZXMuXG4gICAqXG4gICAqIE5vIHNldHRpbmdzIGFyZSBpbmhlcml0ZWQgZnJvbSB0aGUgYmFzZSBgVmVyc2lvbmAgb2JqZWN0IChidXQgYW55IHBhcmFtZXRlcnMgdGhhdFxuICAgKiBjb250cm9sIHZlcnNpb25zIGRvIGNvbmZsaWN0IHdpdGggdGhlIHVzZSBvZiBhIGBuZXh0VmVyc2lvbkNvbW1hbmRgKS5cbiAgICovXG4gIHB1YmxpYyBlbnZGb3JCcmFuY2goXG4gICAgYnJhbmNoT3B0aW9uczogVmVyc2lvbkJyYW5jaE9wdGlvbnNcbiAgKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gICAgaWYgKHRoaXMubmV4dFZlcnNpb25Db21tYW5kICYmIGJyYW5jaE9wdGlvbnMubWluTWFqb3JWZXJzaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwibWluTWFqb3JWZXJzaW9uIGFuZCBuZXh0VmVyc2lvbkNvbW1hbmQgY2Fubm90IGJlIHVzZWQgdG9nZXRoZXIuXCJcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgZW52OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gICAgaWYgKGJyYW5jaE9wdGlvbnMubWFqb3JWZXJzaW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGVudi5NQUpPUiA9IGJyYW5jaE9wdGlvbnMubWFqb3JWZXJzaW9uLnRvU3RyaW5nKCk7XG4gICAgfVxuXG4gICAgaWYgKGJyYW5jaE9wdGlvbnMubWluTWFqb3JWZXJzaW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChicmFuY2hPcHRpb25zLm1ham9yVmVyc2lvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgbWluTWFqb3JWZXJzaW9uIGFuZCBtYWpvclZlcnNpb24gY2Fubm90IGJlIHVzZWQgdG9nZXRoZXIuYFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBlbnYuTUlOX01BSk9SID0gYnJhbmNoT3B0aW9ucy5taW5NYWpvclZlcnNpb24udG9TdHJpbmcoKTtcbiAgICB9XG5cbiAgICBpZiAoYnJhbmNoT3B0aW9ucy5wcmVyZWxlYXNlKSB7XG4gICAgICBlbnYuUFJFUkVMRUFTRSA9IGJyYW5jaE9wdGlvbnMucHJlcmVsZWFzZTtcbiAgICB9XG5cbiAgICBpZiAoYnJhbmNoT3B0aW9ucy50YWdQcmVmaXgpIHtcbiAgICAgIGVudi5SRUxFQVNFX1RBR19QUkVGSVggPSBicmFuY2hPcHRpb25zLnRhZ1ByZWZpeDtcbiAgICB9XG5cbiAgICByZXR1cm4gZW52O1xuICB9XG59XG5cbi8qKlxuICogT3B0aW9ucyB0byBwYXNzIHRvIGBtb2RpZnlCcmFuY2hFbnZpcm9ubWVudGBcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWZXJzaW9uQnJhbmNoT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgbWFqb3IgdmVyc2lvbnMgcmVsZWFzZWQgZnJvbSB0aGlzIGJyYW5jaC5cbiAgICovXG4gIHJlYWRvbmx5IG1ham9yVmVyc2lvbj86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIG1pbmltdW0gbWFqb3IgdmVyc2lvbiB0byByZWxlYXNlLlxuICAgKi9cbiAgcmVhZG9ubHkgbWluTWFqb3JWZXJzaW9uPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgbWlub3IgdmVyc2lvbnMgcmVsZWFzZWQgZnJvbSB0aGlzIGJyYW5jaC5cbiAgICovXG4gIHJlYWRvbmx5IG1pbm9yVmVyc2lvbj86IG51bWJlcjtcblxuICAvKipcbiAgICogQnVtcCB0aGUgdmVyc2lvbiBhcyBhIHByZS1yZWxlYXNlIHRhZy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBub3JtYWwgcmVsZWFzZXNcbiAgICovXG4gIHJlYWRvbmx5IHByZXJlbGVhc2U/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEF1dG9tYXRpY2FsbHkgYWRkIHRoZSBnaXZlbiBwcmVmaXggdG8gcmVsZWFzZSB0YWdzLlxuICAgKiBVc2VmdWwgaWYgeW91IGFyZSByZWxlYXNpbmcgb24gbXVsdGlwbGUgYnJhbmNoZXMgd2l0aCBvdmVybGFwcGluZ1xuICAgKiB2ZXJzaW9uIG51bWJlcnMuXG4gICAqXG4gICAqIE5vdGU6IHRoaXMgcHJlZml4IGlzIHVzZWQgdG8gZGV0ZWN0IHRoZSBsYXRlc3QgdGFnZ2VkIHZlcnNpb25cbiAgICogd2hlbiBidW1waW5nLCBzbyBpZiB5b3UgY2hhbmdlIHRoaXMgb24gYSBwcm9qZWN0IHdpdGggYW4gZXhpc3RpbmcgdmVyc2lvblxuICAgKiBoaXN0b3J5LCB5b3UgbWF5IG5lZWQgdG8gbWFudWFsbHkgdGFnIHlvdXIgbGF0ZXN0IHJlbGVhc2VcbiAgICogd2l0aCB0aGUgbmV3IHByZWZpeC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBwcmVmaXhcbiAgICovXG4gIHJlYWRvbmx5IHRhZ1ByZWZpeD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBGaW5kIGNvbW1pdHMgdGhhdCBzaG91bGQgYmUgY29uc2lkZXJlZCByZWxlYXNhYmxlIHRvIGRlY2lkZSBpZiBhIHJlbGVhc2UgaXMgcmVxdWlyZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWxlYXNhYmxlQ29tbWl0cyB7XG4gIC8qKlxuICAgKiBSZWxlYXNlIGV2ZXJ5IGNvbW1pdFxuICAgKlxuICAgKiBUaGlzIHdpbGwgb25seSBub3QgcmVsZWFzZSBpZiB0aGUgbW9zdCByZWNlbnQgY29tbWl0IGlzIHRhZ2dlZCB3aXRoIHRoZSBsYXRlc3QgbWF0Y2hpbmcgdGFnLlxuICAgKlxuICAgKiBAcGFyYW0gcGF0aCBDb25zaWRlciBvbmx5IGNvbW1pdHMgdGhhdCBhcmUgZW5vdWdoIHRvIGV4cGxhaW4gaG93IHRoZSBmaWxlcyB0aGF0IG1hdGNoIHRoZSBzcGVjaWZpZWQgcGF0aHMgY2FtZSB0byBiZS5cbiAgICogVGhpcyBwYXRoIGlzIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyIG9mIHRoZSBgYnVtcGAgdGFzaywgaS5lLiB0byBvbmx5IGNvbnNpZGVyIGNvbW1pdHMgb2YgYSBzdWJwcm9qZWN0IHVzZSBgXCIuXCJgLlxuICAgKi9cbiAgc3RhdGljIGV2ZXJ5Q29tbWl0KHBhdGg/OiBzdHJpbmcpIHtcbiAgICBjb25zdCBjbWQgPSBgZ2l0IGxvZyAtLW9uZWxpbmUgJExBVEVTVF9UQUcuLkhFQURgO1xuICAgIHJldHVybiBuZXcgUmVsZWFzYWJsZUNvbW1pdHMod2l0aFBhdGgoY21kLCBwYXRoKSk7XG4gIH1cblxuICAvKipcbiAgICogTGltaXQgY29tbWl0cyBieSB0aGVpciBjb252ZW50aW9uYWwgY29tbWl0IHR5cGVcbiAgICpcbiAgICogVGhpcyB3aWxsIG9ubHkgcmVsZWFzZSBjb21taXQgdGhhdCBtYXRjaCBvbmUgb2YgdGhlIHByb3ZpZGVkIHR5cGVzLlxuICAgKiBDb21taXRzIGFyZSByZXF1aXJlZCB0byBmb2xsb3cgdGhlIGNvbnZlbnRpb25hbCBjb21taXQgc3BlYyBhbmQgd2lsbCBiZSBpZ25vcmVkIG90aGVyd2lzZS5cbiAgICpcbiAgICogQHBhcmFtIHR5cGVzIExpc3Qgb2YgY29udmVudGlvbmFsIGNvbW1pdCB0eXBlcyB0aGF0IHNob3VsZCBiZSByZWxlYXNlZFxuICAgKiBAcGFyYW0gcGF0aCBDb25zaWRlciBvbmx5IGNvbW1pdHMgdGhhdCBhcmUgZW5vdWdoIHRvIGV4cGxhaW4gaG93IHRoZSBmaWxlcyB0aGF0IG1hdGNoIHRoZSBzcGVjaWZpZWQgcGF0aHMgY2FtZSB0byBiZS5cbiAgICogVGhpcyBwYXRoIGlzIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyIG9mIHRoZSBgYnVtcGAgdGFzaywgaS5lLiB0byBvbmx5IGNvbnNpZGVyIGNvbW1pdHMgb2YgYSBzdWJwcm9qZWN0IHVzZSBgXCIuXCJgLlxuICAgKi9cbiAgc3RhdGljIG9mVHlwZSh0eXBlczogc3RyaW5nW10sIHBhdGg/OiBzdHJpbmcpIHtcbiAgICBjb25zdCBhbGxvd2VkVHlwZXMgPSB0eXBlcy5qb2luKFwifFwiKTtcblxuICAgIC8vIEBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9jb252ZW50aW9uYWwtY29tbWl0cy9wYXJzZXIvYmxvYi9lZWVmYjk2MWViZjViOWRmZWEwZmVhOGIwNmY4YWQzNGExZTQzOWI5L2xpYi9wYXJzZXIuanNcbiAgICAvLyAtRSByZXF1aXJlcyB0aGlzIHRvIGJlIFBPU0lYIEV4dGVuZGVkIFJlZ3VsYXIgRXhwcmVzc2lvbiwgd2hpY2ggY29tZXMgd2l0aCBjZXJ0YWluIGxpbWl0YXRpb25zXG4gICAgLy8gc2VlIGh0dHBzOi8vZW4ud2lraWJvb2tzLm9yZy93aWtpL1JlZ3VsYXJfRXhwcmVzc2lvbnMvUE9TSVgtRXh0ZW5kZWRfUmVndWxhcl9FeHByZXNzaW9ucyBmb3IgZGV0YWlsc1xuICAgIGNvbnN0IGNtZCA9IGBnaXQgbG9nIC0tbm8tbWVyZ2VzIC0tb25lbGluZSAkTEFURVNUX1RBRy4uSEVBRCAtRSAtLWdyZXAgXCJeKCR7YWxsb3dlZFR5cGVzfSl7MX0oXFxcXChbXigpWzpzcGFjZTpdXStcXFxcKSk/KCEpPzpbWzpibGFuazpdXSsuK1wiYDtcblxuICAgIHJldHVybiBuZXcgUmVsZWFzYWJsZUNvbW1pdHMod2l0aFBhdGgoY21kLCBwYXRoKSk7XG4gIH1cblxuICAvKipcbiAgICogUmVsZWFzZSBvbmx5IGZlYXR1cmVzIGFuZCBmaXhlc1xuICAgKlxuICAgKiBTaG9ydGhhbmQgZm9yIGBSZWxlYXNhYmxlQ29tbWl0cy5vbmx5T2ZUeXBlKFsnZmVhdCcsICdmaXgnXSlgLlxuICAgKlxuICAgKiBAcGFyYW0gcGF0aCBDb25zaWRlciBvbmx5IGNvbW1pdHMgdGhhdCBhcmUgZW5vdWdoIHRvIGV4cGxhaW4gaG93IHRoZSBmaWxlcyB0aGF0IG1hdGNoIHRoZSBzcGVjaWZpZWQgcGF0aHMgY2FtZSB0byBiZS5cbiAgICogVGhpcyBwYXRoIGlzIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyIG9mIHRoZSBgYnVtcGAgdGFzaywgaS5lLiB0byBvbmx5IGNvbnNpZGVyIGNvbW1pdHMgb2YgYSBzdWJwcm9qZWN0IHVzZSBgXCIuXCJgLlxuICAgKi9cbiAgc3RhdGljIGZlYXR1cmVzQW5kRml4ZXMocGF0aD86IHN0cmluZykge1xuICAgIHJldHVybiBSZWxlYXNhYmxlQ29tbWl0cy5vZlR5cGUoW1wiZmVhdFwiLCBcImZpeFwiXSwgcGF0aCk7XG4gIH1cblxuICAvKipcbiAgICogVXNlIGFuIGFyYml0cmFyeSBzaGVsbCBjb21tYW5kIHRvIGZpbmQgcmVsZWFzYWJsZSBjb21taXRzIHNpbmNlIHRoZSBsYXRlc3QgdGFnLlxuICAgKlxuICAgKiBBIG5ldyByZWxlYXNlIHdpbGwgYmUgaW5pdGlhdGVkLCBpZiB0aGUgbnVtYmVyIG9mIHJldHVybmVkIGNvbW1pdHMgaXMgZ3JlYXRlciB0aGFuIHplcm8uXG4gICAqIE11c3QgcmV0dXJuIGEgbmV3bGluZSBzZXBhcmF0ZSBsaXN0IG9mIGNvbW1pdHMgdGhhdCBzaG91bGQgY29uc2lkZXJlZCByZWxlYXNhYmxlLlxuICAgKiBgJExBVEVTVF9UQUdgIHdpbGwgYmUgcmVwbGFjZWQgd2l0aCB0aGUgYWN0dWFsIGxhdGVzdCB0YWcgZm9yIHRoZSBnaXZlbiBwcmVmaXguKlxuICAgKlxuICAgKiBAZXhhbXBsZSBcImdpdCBsb2cgLS1vbmVsaW5lICRMQVRFU1RfVEFHLi5IRUFEIC0tIC5cIlxuICAgKi9cbiAgc3RhdGljIGV4ZWMoY21kOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gbmV3IFJlbGVhc2FibGVDb21taXRzKGNtZCk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKHB1YmxpYyBjbWQ6IHN0cmluZykge31cbn1cblxuLyoqXG4gKiBBcHBlbmQgYSBwYXRoIGFyZ3VtZW50IHRvIGEgZ2l0IGNvbW1hbmQgaWYgb25lIGlzIHByb3ZpZGVkXG4gKi9cbmZ1bmN0aW9uIHdpdGhQYXRoKGNtZDogc3RyaW5nLCBwYXRoPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKHBhdGggIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBgJHtjbWR9IC0tICR7cGF0aH1gO1xuICB9XG5cbiAgcmV0dXJuIGNtZDtcbn1cbiJdfQ==