projen
Version:
CDK for software projects
219 lines • 36.5 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AwsCdkDeps = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const semver = require("semver");
const component_1 = require("../component");
const dependencies_1 = require("../dependencies");
/**
* Manages dependencies on the AWS CDK.
*/
class AwsCdkDeps extends component_1.Component {
constructor(project, options) {
super(project);
this.cdkDependenciesAsDeps = options.cdkDependenciesAsDeps ?? true;
this.dependencyType = options.dependencyType;
this._packageNames = this.packageNames();
const framework = determineFrameworkVersion(options);
this.cdkCliVersion = options.cdkCliVersion ?? "^2";
this.cdkVersion = framework.range;
this.cdkMajorVersion = framework.major;
this.cdkMinimumVersion = framework.minimum;
this.addFrameworkDependency(options);
// assert/assertions library
this.addV1AssertionLibraryDependency(options);
// constructs library
this.addConstructsDependency(options.constructsVersion);
// user-defined v1 dependencies (will only fail in CDK v2 if these have values)
this.addV1Dependencies(...(options.cdkDependencies ?? []));
this.addV1DevDependencies(...(options.cdkTestDependencies ?? []));
}
preSynthesize() {
// Log a warning if any AWS CDK v1-only deps are found in the dependencies.
const depNames = Array.from(new Set(this.project.deps.all.map((dep) => dep.name)));
const v1Deps = depNames
.filter((dep) => [PACKAGE_AWS_CDK_VERSION.V1].includes(cdkVersionOfPackage(dep)))
.sort();
if (this.cdkMajorVersion === 2 && v1Deps.length > 0) {
this.project.logger.warn(`WARNING: Found CDK v1 deps in your project, even though your "cdkVersion" is 2.x: [${v1Deps.join(", ")}]. Check out https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html for more information about using CDK v2 dependencies.`);
}
}
/**
* Adds dependencies to AWS CDK modules.
*
* The type of dependency is determined by the `dependencyType` option.
*
* This method is not supported in CDK v2. Use `project.addPeerDeps()` or
* `project.addDeps()` as appropriate.
*
* @param deps names of cdk modules (e.g. `@aws-cdk/aws-lambda`).
*/
addV1Dependencies(...deps) {
if (deps.length > 0 && this.cdkMajorVersion !== 1) {
throw new Error("addV1Dependencies() is not supported for CDK 2.x and above, use addDeps() or addPeerDeps() instead");
}
// this will add dependencies based on the type requested by the user
// for libraries, this will be "peer" and for apps it will be "runtime"
this.addV1DependenciesByType(this.dependencyType, ...deps);
// add deps as runtime deps if `cdkDepsAsDeps` is true
if (this.cdkDependenciesAsDeps) {
this.addV1DependenciesByType(dependencies_1.DependencyType.RUNTIME, ...deps);
}
}
/**
* Adds AWS CDK modules as dev dependencies.
*
* This method is not supported in CDK v2. Use `project.addPeerDeps()` or
* `project.addDeps()` as appropriate.
*
* @param deps fully qualified names of cdk modules (e.g. `@aws-cdk/aws-lambda`).
*/
addV1DevDependencies(...deps) {
if (deps.length > 0 && this.cdkMajorVersion !== 1) {
throw new Error("addV1DevDependencies() is not supported for CDK 2.x and above, use addDevDeps()/addTestDeps() instead");
}
this.addV1DependenciesByType(dependencies_1.DependencyType.BUILD, ...deps);
}
addConstructsDependency(requestedVersion) {
if (requestedVersion && !semver.parse(requestedVersion)) {
throw new Error(`"constructsVersion" cannot be parsed as a semver version: ${requestedVersion}`);
}
const defaultVersion = this.cdkMajorVersion === 1 ? "3.2.27" : "10.0.5";
const versionRequirement = `^${requestedVersion ?? defaultVersion}`;
const constructsMajorVersion = semver.minVersion(versionRequirement)?.major;
if (!constructsMajorVersion) {
throw new Error(`Cannot determine major version of constructs version '${versionRequirement}'`);
}
switch (this.cdkMajorVersion) {
case 1:
if (constructsMajorVersion !== 3) {
throw new Error("AWS CDK 1.x requires constructs 3.x");
}
break;
case 2:
if (constructsMajorVersion !== 10) {
throw new Error("AWS CDK 2.x requires constructs 10.x");
}
break;
}
// First remove the version added by projen
this.project.deps.removeDependency("constructs", dependencies_1.DependencyType.BUILD);
// Add the version for CDK
this.project.deps.addDependency(`${this._packageNames.constructs}@${versionRequirement}`, this.dependencyType);
return versionRequirement;
}
/**
* Adds a dependency on the AWS CDK framework (e.g. `@aws-cdk/core` for V1 or `aws-cdk-lib` for V1).
*/
addFrameworkDependency(options) {
switch (this.cdkMajorVersion) {
case 1:
this.addV1Dependencies(this._packageNames.coreV1);
break;
case 2:
if (options.cdkDependencies !== undefined) {
throw new Error('cdkDependencies is not used for CDK 2.x. Use "peerDeps" or "deps" instead');
}
if (options.cdkDependenciesAsDeps !== undefined) {
throw new Error("cdkDependenciesAsDeps is not used for CDK 2.x");
}
if (options.cdkTestDependencies !== undefined) {
throw new Error('cdkTestDependencies is not used for CDK 2.x. Use "devDeps" or "testDeps" instead');
}
this.project.deps.addDependency(`${this._packageNames.coreV2}@${this.cdkVersion}`, this.dependencyType);
break;
default:
throw new Error(`Unsupported AWS CDK major version ${this.cdkMajorVersion}.x`);
}
}
addV1AssertionLibraryDependency(options) {
if (this.cdkMajorVersion !== 1) {
if (options.cdkAssert !== undefined) {
throw new Error("cdkAssert is not used for CDK 2.x. Use the assertions library that is provided in aws-cdk-lib");
}
if (options.cdkAssertions !== undefined) {
throw new Error("cdkAssertion is not used for CDK 2.x. Use the assertions library that is provided in aws-cdk-lib");
}
return;
}
const testDeps = new Array();
if ((options.cdkAssert ?? true) && this._packageNames.assert) {
testDeps.push(this._packageNames.assert);
}
// @aws-cdk/assertions is only available starting v1.111.0
if (semver.gte(this.cdkMinimumVersion, "1.111.0") &&
(options.cdkAssertions ?? true)) {
testDeps.push(this._packageNames.assertions);
}
this.addV1DependenciesByType(dependencies_1.DependencyType.TEST, ...testDeps);
}
/**
* Adds a set of dependencies with the user-specified dependency type.
* @param deps The set of dependency specifications
*/
addV1DependenciesByType(type, ...modules) {
for (const module of modules) {
this.project.deps.addDependency(`${module}@${this.cdkVersion}`, type);
}
}
}
exports.AwsCdkDeps = AwsCdkDeps;
_a = JSII_RTTI_SYMBOL_1;
AwsCdkDeps[_a] = { fqn: "projen.awscdk.AwsCdkDeps", version: "0.91.20" };
/**
* Which AWS CDK version a construct library package belongs to.
*/
var PACKAGE_AWS_CDK_VERSION;
(function (PACKAGE_AWS_CDK_VERSION) {
PACKAGE_AWS_CDK_VERSION["V1"] = "v1";
PACKAGE_AWS_CDK_VERSION["V2"] = "v2";
PACKAGE_AWS_CDK_VERSION["EITHER"] = "either";
PACKAGE_AWS_CDK_VERSION["UNKNOWN"] = "unknown";
})(PACKAGE_AWS_CDK_VERSION || (PACKAGE_AWS_CDK_VERSION = {}));
function cdkVersionOfPackage(packageName) {
if (packageName === "aws-cdk-lib") {
return PACKAGE_AWS_CDK_VERSION.V2;
}
else if (packageName.startsWith("@aws-cdk/")) {
if (packageName.endsWith("-alpha")) {
return PACKAGE_AWS_CDK_VERSION.V2;
}
else if (AWS_CDK_V1_V2_SCOPED_PACKAGES.includes(packageName)) {
return PACKAGE_AWS_CDK_VERSION.EITHER;
}
else {
return PACKAGE_AWS_CDK_VERSION.V1;
}
}
else {
return PACKAGE_AWS_CDK_VERSION.UNKNOWN;
}
}
/**
* A list of all known packages in the "@aws-cdk/" scope that are published
* both for v1 and v2.
*/
const AWS_CDK_V1_V2_SCOPED_PACKAGES = [
"@aws-cdk/cfnspec",
"@aws-cdk/cx-api",
"@aws-cdk/region-info",
"@aws-cdk/cloud-assembly-schema",
"@aws-cdk/assert",
"@aws-cdk/cloudformation-diff",
"@aws-cdk/integ-runner",
];
function determineFrameworkVersion(options) {
const ver = semver.parse(options.cdkVersion);
if (!ver) {
throw new Error(`"cdkVersion" cannot be parsed as a semver version: ${options.cdkVersion}`);
}
return {
minimum: ver.format(),
range: options.cdkVersionPinning
? options.cdkVersion
: `^${options.cdkVersion}`,
major: ver.major,
};
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzY2RrLWRlcHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXdzY2RrL2F3c2Nkay1kZXBzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsaUNBQWlDO0FBQ2pDLDRDQUF5QztBQUN6QyxrREFBaUQ7QUFpSWpEOztHQUVHO0FBQ0gsTUFBc0IsVUFBVyxTQUFRLHFCQUFTO0lBaUNoRCxZQUFZLE9BQWdCLEVBQUUsT0FBMEI7UUFDdEQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWYsSUFBSSxDQUFDLHFCQUFxQixHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsSUFBSSxJQUFJLENBQUM7UUFFbkUsSUFBSSxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDO1FBQzdDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBRXpDLE1BQU0sU0FBUyxHQUFHLHlCQUF5QixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXJELElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUM7UUFDbkQsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxlQUFlLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQztRQUN2QyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQztRQUUzQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFckMsNEJBQTRCO1FBQzVCLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUU5QyxxQkFBcUI7UUFDckIsSUFBSSxDQUFDLHVCQUF1QixDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBRXhELCtFQUErRTtRQUMvRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxlQUFlLElB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USxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDL0QsT0FBTyx1QkFBdUIsQ0FBQyxNQUFNLENBQUM7UUFDeEMsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLHVCQUF1QixDQUFDLEVBQUUsQ0FBQztRQUNwQyxDQUFDO0lBQ0gsQ0FBQztTQUFNLENBQUM7UUFDTixPQUFPLHVCQUF1QixDQUFDLE9BQU8sQ0FBQztJQUN6QyxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sNkJBQTZCLEdBQUc7SUFDcEMsa0JBQWtCO0lBQ2xCLGlCQUFpQjtJQUNqQixzQkFBc0I7SUFDdEIsZ0NBQWdDO0lBQ2hDLGlCQUFpQjtJQUNqQiw4QkFBOEI7SUFDOUIsdUJBQXVCO0NBQ3hCLENBQUM7QUFFRixTQUFTLHlCQUF5QixDQUFDLE9BQTBCO0lBQzNELE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzdDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNULE1BQU0sSUFBSSxLQUFLLENBQ2Isc0RBQXNELE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FDM0UsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPO1FBQ0wsT0FBTyxFQUFFLEdBQUcsQ0FBQyxNQUFNLEVBQUU7UUFDckIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxpQkFBaUI7WUFDOUIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFVO1lBQ3BCLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxVQUFVLEVBQUU7UUFDNUIsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLO0tBQ2pCLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgc2VtdmVyIGZyb20gXCJzZW12ZXJcIjtcbmltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gXCIuLi9jb21wb25lbnRcIjtcbmltcG9ydCB7IERlcGVuZGVuY3lUeXBlIH0gZnJvbSBcIi4uL2RlcGVuZGVuY2llc1wiO1xuaW1wb3J0IHsgUHJvamVjdCB9IGZyb20gXCIuLi9wcm9qZWN0XCI7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYEF3c0Nka0RlcHNgXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXdzQ2RrRGVwc0NvbW1vbk9wdGlvbnMge1xuICAvKipcbiAgICogTWluaW11bSB2ZXJzaW9uIG9mIHRoZSBBV1MgQ0RLIHRvIGRlcGVuZCBvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgXCIyLjEuMFwiXG4gICAqL1xuICByZWFkb25seSBjZGtWZXJzaW9uOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFZlcnNpb24gcmFuZ2Ugb2YgdGhlIEFXUyBDREsgQ0xJIHRvIGRlcGVuZCBvbi5cbiAgICpcbiAgICogQ2FuIGJlIGVpdGhlciBhIHNwZWNpZmljIHZlcnNpb24sIG9yIGFuIE5QTSB2ZXJzaW9uIHJhbmdlLlxuICAgKlxuICAgKiBCeSBkZWZhdWx0LCB0aGUgbGF0ZXN0IDIueCB2ZXJzaW9uIHdpbGwgYmUgaW5zdGFsbGVkOyB5b3UgY2FuIHVzZSB0aGlzXG4gICAqIG9wdGlvbiB0byByZXN0cmljdCBpdCB0byBhIHNwZWNpZmljIHZlcnNpb24gb3IgdmVyc2lvbiByYW5nZS5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJeMlwiXG4gICAqL1xuICByZWFkb25seSBjZGtDbGlWZXJzaW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNaW5pbXVtIHZlcnNpb24gb2YgdGhlIGBjb25zdHJ1Y3RzYCBsaWJyYXJ5IHRvIGRlcGVuZCBvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBmb3IgQ0RLIDEueCB0aGUgZGVmYXVsdCBpcyBcIjMuMi4yN1wiLCBmb3IgQ0RLIDIueCB0aGUgZGVmYXVsdCBpc1xuICAgKiBcIjEwLjAuNVwiLlxuICAgKi9cbiAgcmVhZG9ubHkgY29uc3RydWN0c1ZlcnNpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFVzZSBwaW5uZWQgdmVyc2lvbiBpbnN0ZWFkIG9mIGNhcmV0IHZlcnNpb24gZm9yIENESy5cbiAgICpcbiAgICogWW91IGNhbiB1c2UgdGhpcyB0byBwcmV2ZW50IG1peGVkIHZlcnNpb25zIGZvciB5b3VyIENESyBkZXBlbmRlbmNpZXMgYW5kIHRvIHByZXZlbnQgYXV0by11cGRhdGVzLlxuICAgKiBJZiB5b3UgdXNlIGV4cGVyaW1lbnRhbCBmZWF0dXJlcyB0aGlzIHdpbGwgbGV0IHlvdSBkZWZpbmUgdGhlIG1vbWVudCB5b3UgaW5jbHVkZSBicmVha2luZyBjaGFuZ2VzLlxuICAgKi9cbiAgcmVhZG9ubHkgY2RrVmVyc2lvblBpbm5pbmc/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGljaCBBV1MgQ0RLdjEgbW9kdWxlcyB0aGlzIHByb2plY3QgcmVxdWlyZXNcbiAgICpcbiAgICogQGRlcHJlY2F0ZWQgRm9yIENESyAyLnggdXNlIFwiZGVwc1wiIGluc3RlYWQuIChvciBcInBlZXJEZXBzXCIgaWYgeW91J3JlIGJ1aWxkaW5nIGEgbGlicmFyeSlcbiAgICovXG4gIHJlYWRvbmx5IGNka0RlcGVuZGVuY2llcz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBJZiB0aGlzIGlzIGVuYWJsZWQgKGRlZmF1bHQpLCBhbGwgbW9kdWxlcyBkZWNsYXJlZCBpbiBgY2RrRGVwZW5kZW5jaWVzYCB3aWxsIGJlIGFsc28gYWRkZWQgYXNcbiAgICogbm9ybWFsIGBkZXBlbmRlbmNpZXNgIChhcyB3ZWxsIGFzIGBwZWVyRGVwZW5kZW5jaWVzYCkuXG4gICAqXG4gICAqIFRoaXMgaXMgdG8gZW5zdXJlIHRoYXQgZG93bnN0cmVhbSBjb25zdW1lcnMgYWN0dWFsbHkgaGF2ZSB5b3VyIENESyBkZXBlbmRlbmNpZXMgaW5zdGFsbGVkXG4gICAqIHdoZW4gdXNpbmcgbnBtIDwgNyBvciB5YXJuLCB3aGVyZSBwZWVyIGRlcGVuZGVuY2llcyBhcmUgbm90IGF1dG9tYXRpY2FsbHkgaW5zdGFsbGVkLlxuICAgKiBJZiB0aGlzIGlzIGRpc2FibGVkLCBgY2RrRGVwZW5kZW5jaWVzYCB3aWxsIGJlIGFkZGVkIHRvIGBkZXZEZXBlbmRlbmNpZXNgIHRvIGVuc3VyZVxuICAgKiB0aGV5IGFyZSBwcmVzZW50IGR1cmluZyBkZXZlbG9wbWVudC5cbiAgICpcbiAgICogTm90ZTogdGhpcyBzZXR0aW5nIG9ubHkgYXBwbGllcyB0byBjb25zdHJ1Y3QgbGlicmFyeSBwcm9qZWN0c1xuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqIEBkZXByZWNhdGVkIE5vdCBzdXBwb3J0ZWQgaW4gQ0RLIHYyLlxuICAgKi9cbiAgcmVhZG9ubHkgY2RrRGVwZW5kZW5jaWVzQXNEZXBzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2FybmluZzogTm9kZUpTIG9ubHkuXG4gICAqIEluc3RhbGwgdGhlIEBhd3MtY2RrL2Fzc2VydCBsaWJyYXJ5P1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIHdpbGwgYmUgaW5jbHVkZWQgYnkgZGVmYXVsdCBmb3IgQVdTIENESyA+PSAxLjAuMCA8IDIuMC4wXG4gICAqIEBkZXByZWNhdGVkIFRoZSBAYXdzLWNkay9hc3NlcnQgbGlicmFyeSBpcyBkZXByZWNhdGVkIGluIGZhdm9yIG9mXG4gICAqIEBhd3MtY2RrL2Fzc2VydGlvbnMgKGluIFYxKSBhbmQgaW5jbHVkZWQgaW4gYGF3cy1jZGstbGliYCBmb3IgVjIuXG4gICAqL1xuICByZWFkb25seSBjZGtBc3NlcnQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbnN0YWxsIHRoZSBhc3NlcnRpb25zIGxpYnJhcnk/XG4gICAqXG4gICAqIE9ubHkgbmVlZGVkIGZvciBDREsgMS54LiBJZiB1c2luZyBDREsgMi54IHRoZW5cbiAgICogYXNzZXJ0aW9ucyBpcyBhbHJlYWR5IGluY2x1ZGVkIGluICdhd3MtY2RrLWxpYidcbiAgICpcbiAgICogQGRlZmF1bHQgLSB3aWxsIGJlIGluY2x1ZGVkIGJ5IGRlZmF1bHQgZm9yIEFXUyBDREsgPj0gMS4xMTEuMCA8IDIuMC4wXG4gICAqL1xuICByZWFkb25seSBjZGtBc3NlcnRpb25zPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQVdTIENESyBtb2R1bGVzIHJlcXVpcmVkIGZvciB0ZXN0aW5nLlxuICAgKlxuICAgKiBAZGVwcmVjYXRlZCBGb3IgQ0RLIDIueCB1c2UgJ2RldkRlcHMnIChpbiBub2RlLmpzIHByb2plY3RzKSBvciAndGVzdERlcHMnIChpbiBqYXZhIHByb2plY3RzKSBpbnN0ZWFkXG4gICAqL1xuICByZWFkb25seSBjZGtUZXN0RGVwZW5kZW5jaWVzPzogc3RyaW5nW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXdzQ2RrRGVwc09wdGlvbnMgZXh0ZW5kcyBBd3NDZGtEZXBzQ29tbW9uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgdHlwZSBvZiBkZXBlbmRlbmN5IHRvIHVzZSBmb3IgcnVudGltZSBBV1MgQ0RLIGFuZCBgY29uc3RydWN0c2AgbW9kdWxlcy5cbiAgICpcbiAgICogRm9yIGxpYnJhcmllcywgdXNlIHBlZXIgZGVwZW5kZW5jaWVzIGFuZCBmb3IgYXBwcyB1c2UgcnVudGltZSBkZXBlbmRlbmNpZXMuXG4gICAqL1xuICByZWFkb25seSBkZXBlbmRlbmN5VHlwZTogRGVwZW5kZW5jeVR5cGU7XG59XG5cbi8qKlxuICogTGFuZ3VhZ2Utc3BlY2lmaWMgQVdTIENESyBwYWNrYWdlIG5hbWVzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEF3c0Nka1BhY2thZ2VOYW1lcyB7XG4gIC8qKlxuICAgKiBGdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgY29yZSBmcmFtZXdvcmsgcGFja2FnZSBmb3IgQ0RLdjFcbiAgICovXG4gIHJlYWRvbmx5IGNvcmVWMTogc3RyaW5nO1xuICAvKipcbiAgICogRnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGNvcmUgZnJhbWV3b3JrIHBhY2thZ2UgZm9yIENES3YyXG4gICAqL1xuICByZWFkb25seSBjb3JlVjI6IHN0cmluZztcbiAgLyoqXG4gICAqIEZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBjb25zdHJ1Y3RzIGxpYnJhcnkgcGFja2FnZVxuICAgKi9cbiAgcmVhZG9ubHkgY29uc3RydWN0czogc3RyaW5nO1xuICAvKipcbiAgICogRnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGFzc2VydGlvbnMgbGlicmFyeSBwYWNrYWdlXG4gICAqL1xuICByZWFkb25seSBhc3NlcnRpb25zOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBGdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgYXNzZXJ0IGxpYnJhcnkgcGFja2FnZVxuICAgKiBDYW4gYmUgZW1wdHkgYXMgaXQncyBvbmx5IHJlYWxseSBhdmFpbGFibGUgZm9yIGphdmFzY3JpcHQgcHJvamVjdHNcbiAgICovXG4gIHJlYWRvbmx5IGFzc2VydD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBNYW5hZ2VzIGRlcGVuZGVuY2llcyBvbiB0aGUgQVdTIENESy5cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEF3c0Nka0RlcHMgZXh0ZW5kcyBDb21wb25lbnQge1xuICAvKipcbiAgICogVGhlIGRlcGVuZGVuY3kgcmVxdWlyZW1lbnQgZm9yIEFXUyBDREsgKGUuZy4gYF4yLjAuMGApLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNka1ZlcnNpb246IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGRlcGVuZGVuY3kgcmVxdWlyZW1lbnQgZm9yIHRoZSBDREsgQ0xJIChlLmcuICdeMi4zLjQnKS5cbiAgICpcbiAgICogV2lsbCByZXR1cm4gYF4yYCBpZiB0aGUgdmVyc2lvbiB3YXMgdW5zcGVjaWZpZWQgYnkgdGhlIHVzZXIuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY2RrQ2xpVmVyc2lvbjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbWluaW11bSB2ZXJzaW9uIG9mIHRoZSBBV1MgQ0RLIChlLmcuIGAyLjAuMGApLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNka01pbmltdW1WZXJzaW9uOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgQ0RLIGRlcGVuZGVuY2llcyBhcmUgYWRkZWQgYXMgbm9ybWFsIGRlcGVuZGVuY2llcyAoYW5kIHBlZXIgZGVwZW5kZW5jaWVzKS5cbiAgICogQGRlcHJlY2F0ZWQgTm90IHVzZWQgZm9yIENESyAyLnhcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjZGtEZXBlbmRlbmNpZXNBc0RlcHM6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBtYWpvciB2ZXJzaW9uIG9mIHRoZSBBV1MgQ0RLIChlLmcuIDEsIDIsIC4uLilcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjZGtNYWpvclZlcnNpb246IG51bWJlcjtcblxuICBwcml2YXRlIHJlYWRvbmx5IGRlcGVuZGVuY3lUeXBlOiBEZXBlbmRlbmN5VHlwZTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9wYWNrYWdlTmFtZXM6IEF3c0Nka1BhY2thZ2VOYW1lcztcblxuICBjb25zdHJ1Y3Rvcihwcm9qZWN0OiBQcm9qZWN0LCBvcHRpb25zOiBBd3NDZGtEZXBzT3B0aW9ucykge1xuICAgIHN1cGVyKHByb2plY3QpO1xuXG4gICAgdGhpcy5jZGtEZXBlbmRlbmNpZXNBc0RlcHMgPSBvcHRpb25zLmNka0RlcGVuZGVuY2llc0FzRGVwcyA/PyB0cnVlO1xuXG4gICAgdGhpcy5kZXBlbmRlbmN5VHlwZSA9IG9wdGlvbnMuZGVwZW5kZW5jeVR5cGU7XG4gICAgdGhpcy5fcGFja2FnZU5hbWVzID0gdGhpcy5wYWNrYWdlTmFtZXMoKTtcblxuICAgIGNvbnN0IGZyYW1ld29yayA9IGRldGVybWluZUZyYW1ld29ya1ZlcnNpb24ob3B0aW9ucyk7XG5cbiAgICB0aGlzLmNka0NsaVZlcnNpb24gPSBvcHRpb25zLmNka0NsaVZlcnNpb24gPz8gXCJeMlwiO1xuICAgIHRoaXMuY2RrVmVyc2lvbiA9IGZyYW1ld29yay5yYW5nZTtcbiAgICB0aGlzLmNka01ham9yVmVyc2lvbiA9IGZyYW1ld29yay5tYWpvcjtcbiAgICB0aGlzLmNka01pbmltdW1WZXJzaW9uID0gZnJhbWV3b3JrLm1pbmltdW07XG5cbiAgICB0aGlzLmFkZEZyYW1ld29ya0RlcGVuZGVuY3kob3B0aW9ucyk7XG5cbiAgICAvLyBhc3NlcnQvYXNzZXJ0aW9ucyBsaWJyYXJ5XG4gICAgdGhpcy5hZGRWMUFzc2VydGlvbkxpYnJhcnlEZXBlbmRlbmN5KG9wdGlvbnMpO1xuXG4gICAgLy8gY29uc3RydWN0cyBsaWJyYXJ5XG4gICAgdGhpcy5hZGRDb25zdHJ1Y3RzRGVwZW5kZW5jeShvcHRpb25zLmNvbnN0cnVjdHNWZXJzaW9uKTtcblxuICAgIC8vIHVzZXItZGVmaW5lZCB2MSBkZXBlbmRlbmNpZXMgKHdpbGwgb25seSBmYWlsIGluIENESyB2MiBpZiB0aGVzZSBoYXZlIHZhbHVlcylcbiAgICB0aGlzLmFkZFYxRGVwZW5kZW5jaWVzKC4uLihvcHRpb25zLmNka0RlcGVuZGVuY2llcyA/PyBbXSkpO1xuICAgIHRoaXMuYWRkVjFEZXZEZXBlbmRlbmNpZXMoLi4uKG9wdGlvbnMuY2RrVGVzdERlcGVuZGVuY2llcyA/PyBbXSkpO1xuICB9XG5cbiAgcHVibGljIHByZVN5bnRoZXNpemUoKTogdm9pZCB7XG4gICAgLy8gTG9nIGEgd2FybmluZyBpZiBhbnkgQVdTIENESyB2MS1vbmx5IGRlcHMgYXJlIGZvdW5kIGluIHRoZSBkZXBlbmRlbmNpZXMuXG4gICAgY29uc3QgZGVwTmFtZXMgPSBBcnJheS5mcm9tKFxuICAgICAgbmV3IFNldCh0aGlzLnByb2plY3QuZGVwcy5hbGwubWFwKChkZXApID0+IGRlcC5uYW1lKSlcbiAgICApO1xuICAgIGNvbnN0IHYxRGVwcyA9IGRlcE5hbWVzXG4gICAgICAuZmlsdGVyKChkZXApID0+XG4gICAgICAgIFtQQUNLQUdFX0FXU19DREtfVkVSU0lPTi5WMV0uaW5jbHVkZXMoY2RrVmVyc2lvbk9mUGFja2FnZShkZXApKVxuICAgICAgKVxuICAgICAgLnNvcnQoKTtcbiAgICBpZiAodGhpcy5jZGtNYWpvclZlcnNpb24gPT09IDIgJiYgdjFEZXBzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMucHJvamVjdC5sb2dnZXIud2FybihcbiAgICAgICAgYFdBUk5JTkc6IEZvdW5kIENESyB2MSBkZXBzIGluIHlvdXIgcHJvamVjdCwgZXZlbiB0aG91Z2ggeW91ciBcImNka1ZlcnNpb25cIiBpcyAyLng6IFske3YxRGVwcy5qb2luKFxuICAgICAgICAgIFwiLCBcIlxuICAgICAgICApfV0uIENoZWNrIG91dCBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2RrL3YyL2d1aWRlL21pZ3JhdGluZy12Mi5odG1sIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHVzaW5nIENESyB2MiBkZXBlbmRlbmNpZXMuYFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBkZXBlbmRlbmNpZXMgdG8gQVdTIENESyBtb2R1bGVzLlxuICAgKlxuICAgKiBUaGUgdHlwZSBvZiBkZXBlbmRlbmN5IGlzIGRldGVybWluZWQgYnkgdGhlIGBkZXBlbmRlbmN5VHlwZWAgb3B0aW9uLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBpcyBub3Qgc3VwcG9ydGVkIGluIENESyB2Mi4gVXNlIGBwcm9qZWN0LmFkZFBlZXJEZXBzKClgIG9yXG4gICAqIGBwcm9qZWN0LmFkZERlcHMoKWAgYXMgYXBwcm9wcmlhdGUuXG4gICAqXG4gICAqIEBwYXJhbSBkZXBzIG5hbWVzIG9mIGNkayBtb2R1bGVzIChlLmcuIGBAYXdzLWNkay9hd3MtbGFtYmRhYCkuXG4gICAqL1xuICBwdWJsaWMgYWRkVjFEZXBlbmRlbmNpZXMoLi4uZGVwczogc3RyaW5nW10pIHtcbiAgICBpZiAoZGVwcy5sZW5ndGggPiAwICYmIHRoaXMuY2RrTWFqb3JWZXJzaW9uICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiYWRkVjFEZXBlbmRlbmNpZXMoKSBpcyBub3Qgc3VwcG9ydGVkIGZvciBDREsgMi54IGFuZCBhYm92ZSwgdXNlIGFkZERlcHMoKSBvciBhZGRQZWVyRGVwcygpIGluc3RlYWRcIlxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyB0aGlzIHdpbGwgYWRkIGRlcGVuZGVuY2llcyBiYXNlZCBvbiB0aGUgdHlwZSByZXF1ZXN0ZWQgYnkgdGhlIHVzZXJcbiAgICAvLyBmb3IgbGlicmFyaWVzLCB0aGlzIHdpbGwgYmUgXCJwZWVyXCIgYW5kIGZvciBhcHBzIGl0IHdpbGwgYmUgXCJydW50aW1lXCJcbiAgICB0aGlzLmFkZFYxRGVwZW5kZW5jaWVzQnlUeXBlKHRoaXMuZGVwZW5kZW5jeVR5cGUsIC4uLmRlcHMpO1xuXG4gICAgLy8gYWRkIGRlcHMgYXMgcnVudGltZSBkZXBzIGlmIGBjZGtEZXBzQXNEZXBzYCBpcyB0cnVlXG4gICAgaWYgKHRoaXMuY2RrRGVwZW5kZW5jaWVzQXNEZXBzKSB7XG4gICAgICB0aGlzLmFkZFYxRGVwZW5kZW5jaWVzQnlUeXBlKERlcGVuZGVuY3lUeXBlLlJVTlRJTUUsIC4uLmRlcHMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIEFXUyBDREsgbW9kdWxlcyBhcyBkZXYgZGVwZW5kZW5jaWVzLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBpcyBub3Qgc3VwcG9ydGVkIGluIENESyB2Mi4gVXNlIGBwcm9qZWN0LmFkZFBlZXJEZXBzKClgIG9yXG4gICAqIGBwcm9qZWN0LmFkZERlcHMoKWAgYXMgYXBwcm9wcmlhdGUuXG4gICAqXG4gICAqIEBwYXJhbSBkZXBzIGZ1bGx5IHF1YWxpZmllZCBuYW1lcyBvZiBjZGsgbW9kdWxlcyAoZS5nLiBgQGF3cy1jZGsvYXdzLWxhbWJkYWApLlxuICAgKi9cbiAgcHVibGljIGFkZFYxRGV2RGVwZW5kZW5jaWVzKC4uLmRlcHM6IHN0cmluZ1tdKSB7XG4gICAgaWYgKGRlcHMubGVuZ3RoID4gMCAmJiB0aGlzLmNka01ham9yVmVyc2lvbiAhPT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcImFkZFYxRGV2RGVwZW5kZW5jaWVzKCkgaXMgbm90IHN1cHBvcnRlZCBmb3IgQ0RLIDIueCBhbmQgYWJvdmUsIHVzZSBhZGREZXZEZXBzKCkvYWRkVGVzdERlcHMoKSBpbnN0ZWFkXCJcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5hZGRWMURlcGVuZGVuY2llc0J5VHlwZShEZXBlbmRlbmN5VHlwZS5CVUlMRCwgLi4uZGVwcyk7XG4gIH1cblxuICBwcml2YXRlIGFkZENvbnN0cnVjdHNEZXBlbmRlbmN5KHJlcXVlc3RlZFZlcnNpb246IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICAgIGlmIChyZXF1ZXN0ZWRWZXJzaW9uICYmICFzZW12ZXIucGFyc2UocmVxdWVzdGVkVmVyc2lvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFwiY29uc3RydWN0c1ZlcnNpb25cIiBjYW5ub3QgYmUgcGFyc2VkIGFzIGEgc2VtdmVyIHZlcnNpb246ICR7cmVxdWVzdGVkVmVyc2lvbn1gXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmF1bHRWZXJzaW9uID0gdGhpcy5jZGtNYWpvclZlcnNpb24gPT09IDEgPyBcIjMuMi4yN1wiIDogXCIxMC4wLjVcIjtcbiAgICBjb25zdCB2ZXJzaW9uUmVxdWlyZW1lbnQgPSBgXiR7cmVxdWVzdGVkVmVyc2lvbiA/PyBkZWZhdWx0VmVyc2lvbn1gO1xuXG4gICAgY29uc3QgY29uc3RydWN0c01ham9yVmVyc2lvbiA9IHNlbXZlci5taW5WZXJzaW9uKHZlcnNpb25SZXF1aXJlbWVudCk/Lm1ham9yO1xuICAgIGlmICghY29uc3RydWN0c01ham9yVmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgQ2Fubm90IGRldGVybWluZSBtYWpvciB2ZXJzaW9uIG9mIGNvbnN0cnVjdHMgdmVyc2lvbiAnJHt2ZXJzaW9uUmVxdWlyZW1lbnR9J2BcbiAgICAgICk7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0aGlzLmNka01ham9yVmVyc2lvbikge1xuICAgICAgY2FzZSAxOlxuICAgICAgICBpZiAoY29uc3RydWN0c01ham9yVmVyc2lvbiAhPT0gMykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkFXUyBDREsgMS54IHJlcXVpcmVzIGNvbnN0cnVjdHMgMy54XCIpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIDI6XG4gICAgICAgIGlmIChjb25zdHJ1Y3RzTWFqb3JWZXJzaW9uICE9PSAxMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkFXUyBDREsgMi54IHJlcXVpcmVzIGNvbnN0cnVjdHMgMTAueFwiKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyBGaXJzdCByZW1vdmUgdGhlIHZlcnNpb24gYWRkZWQgYnkgcHJvamVuXG4gICAgdGhpcy5wcm9qZWN0LmRlcHMucmVtb3ZlRGVwZW5kZW5jeShcImNvbnN0cnVjdHNcIiwgRGVwZW5kZW5jeVR5cGUuQlVJTEQpO1xuXG4gICAgLy8gQWRkIHRoZSB2ZXJzaW9uIGZvciBDREtcbiAgICB0aGlzLnByb2plY3QuZGVwcy5hZGREZXBlbmRlbmN5KFxuICAgICAgYCR7dGhpcy5fcGFja2FnZU5hbWVzLmNvbnN0cnVjdHN9QCR7dmVyc2lvblJlcXVpcmVtZW50fWAsXG4gICAgICB0aGlzLmRlcGVuZGVuY3lUeXBlXG4gICAgKTtcblxuICAgIHJldHVybiB2ZXJzaW9uUmVxdWlyZW1lbnQ7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIGRlcGVuZGVuY3kgb24gdGhlIEFXUyBDREsgZnJhbWV3b3JrIChlLmcuIGBAYXdzLWNkay9jb3JlYCBmb3IgVjEgb3IgYGF3cy1jZGstbGliYCBmb3IgVjEpLlxuICAgKi9cbiAgcHJpdmF0ZSBhZGRGcmFtZXdvcmtEZXBlbmRlbmN5KG9wdGlvbnM6IEF3c0Nka0RlcHNPcHRpb25zKSB7XG4gICAgc3dpdGNoICh0aGlzLmNka01ham9yVmVyc2lvbikge1xuICAgICAgY2FzZSAxOlxuICAgICAgICB0aGlzLmFkZFYxRGVwZW5kZW5jaWVzKHRoaXMuX3BhY2thZ2VOYW1lcy5jb3JlVjEpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAyOlxuICAgICAgICBpZiAob3B0aW9ucy5jZGtEZXBlbmRlbmNpZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICdjZGtEZXBlbmRlbmNpZXMgaXMgbm90IHVzZWQgZm9yIENESyAyLnguIFVzZSBcInBlZXJEZXBzXCIgb3IgXCJkZXBzXCIgaW5zdGVhZCdcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLmNka0RlcGVuZGVuY2llc0FzRGVwcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2RrRGVwZW5kZW5jaWVzQXNEZXBzIGlzIG5vdCB1c2VkIGZvciBDREsgMi54XCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLmNka1Rlc3REZXBlbmRlbmNpZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICdjZGtUZXN0RGVwZW5kZW5jaWVzIGlzIG5vdCB1c2VkIGZvciBDREsgMi54LiBVc2UgXCJkZXZEZXBzXCIgb3IgXCJ0ZXN0RGVwc1wiIGluc3RlYWQnXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucHJvamVjdC5kZXBzLmFkZERlcGVuZGVuY3koXG4gICAgICAgICAgYCR7dGhpcy5fcGFja2FnZU5hbWVzLmNvcmVWMn1AJHt0aGlzLmNka1ZlcnNpb259YCxcbiAgICAgICAgICB0aGlzLmRlcGVuZGVuY3lUeXBlXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFVuc3VwcG9ydGVkIEFXUyBDREsgbWFqb3IgdmVyc2lvbiAke3RoaXMuY2RrTWFqb3JWZXJzaW9ufS54YFxuICAgICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYWRkVjFBc3NlcnRpb25MaWJyYXJ5RGVwZW5kZW5jeShvcHRpb25zOiBBd3NDZGtEZXBzT3B0aW9ucykge1xuICAgIGlmICh0aGlzLmNka01ham9yVmVyc2lvbiAhPT0gMSkge1xuICAgICAgaWYgKG9wdGlvbnMuY2RrQXNzZXJ0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiY2RrQXNzZXJ0IGlzIG5vdCB1c2VkIGZvciBDREsgMi54LiBVc2UgdGhlIGFzc2VydGlvbnMgbGlicmFyeSB0aGF0IGlzIHByb3ZpZGVkIGluIGF3cy1jZGstbGliXCJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLmNka0Fzc2VydGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgXCJjZGtBc3NlcnRpb24gaXMgbm90IHVzZWQgZm9yIENESyAyLnguIFVzZSB0aGUgYXNzZXJ0aW9ucyBsaWJyYXJ5IHRoYXQgaXMgcHJvdmlkZWQgaW4gYXdzLWNkay1saWJcIlxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdGVzdERlcHMgPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xuXG4gICAgaWYgKChvcHRpb25zLmNka0Fzc2VydCA/PyB0cnVlKSAmJiB0aGlzLl9wYWNrYWdlTmFtZXMuYXNzZXJ0KSB7XG4gICAgICB0ZXN0RGVwcy5wdXNoKHRoaXMuX3BhY2thZ2VOYW1lcy5hc3NlcnQpO1xuICAgIH1cblxuICAgIC8vIEBhd3MtY2RrL2Fzc2VydGlvbnMgaXMgb25seSBhdmFpbGFibGUgc3RhcnRpbmcgdjEuMTExLjBcbiAgICBpZiAoXG4gICAgICBzZW12ZXIuZ3RlKHRoaXMuY2RrTWluaW11bVZlcnNpb24sIFwiMS4xMTEuMFwiKSAmJlxuICAgICAgKG9wdGlvbnMuY2RrQXNzZXJ0aW9ucyA/PyB0cnVlKVxuICAgICkge1xuICAgICAgdGVzdERlcHMucHVzaCh0aGlzLl9wYWNrYWdlTmFtZXMuYXNzZXJ0aW9ucyk7XG4gICAgfVxuXG4gICAgdGhpcy5hZGRWMURlcGVuZGVuY2llc0J5VHlwZShEZXBlbmRlbmN5VHlwZS5URVNULCAuLi50ZXN0RGVwcyk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHNldCBvZiBkZXBlbmRlbmNpZXMgd2l0aCB0aGUgdXNlci1zcGVjaWZpZWQgZGVwZW5kZW5jeSB0eXBlLlxuICAgKiBAcGFyYW0gZGVwcyBUaGUgc2V0IG9mIGRlcGVuZGVuY3kgc3BlY2lmaWNhdGlvbnNcbiAgICovXG4gIHByaXZhdGUgYWRkVjFEZXBlbmRlbmNpZXNCeVR5cGUodHlwZTogRGVwZW5kZW5jeVR5cGUsIC4uLm1vZHVsZXM6IHN0cmluZ1tdKSB7XG4gICAgZm9yIChjb25zdCBtb2R1bGUgb2YgbW9kdWxlcykge1xuICAgICAgdGhpcy5wcm9qZWN0LmRlcHMuYWRkRGVwZW5kZW5jeShgJHttb2R1bGV9QCR7dGhpcy5jZGtWZXJzaW9ufWAsIHR5cGUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBjb25maWd1cmF0aW9uIG9iamVjdCB3aXRoIGluZm9ybWF0aW9uIGFib3V0IHBhY2thZ2UgbmFtaW5nIGluIHZhcmlvdXMgbGFuZ3VhZ2VzXG4gICAqL1xuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcGFja2FnZU5hbWVzKCk6IEF3c0Nka1BhY2thZ2VOYW1lcztcbn1cblxuLyoqXG4gKiBXaGljaCBBV1MgQ0RLIHZlcnNpb24gYSBjb25zdHJ1Y3QgbGlicmFyeSBwYWNrYWdlIGJlbG9uZ3MgdG8uXG4gKi9cbmVudW0gUEFDS0FHRV9BV1NfQ0RLX1ZFUlNJT04ge1xuICBWMSA9IFwidjFcIixcbiAgVjIgPSBcInYyXCIsXG4gIEVJVEhFUiA9IFwiZWl0aGVyXCIsIC8vIFRoaXMgcGFja2FnZSBoYXMgYmVlbiBwdWJsaXNoZWQgYm90aCBmb3IgdjEgYW5kIHYyLlxuICBVTktOT1dOID0gXCJ1bmtub3duXCIsXG59XG5cbmZ1bmN0aW9uIGNka1ZlcnNpb25PZlBhY2thZ2UocGFja2FnZU5hbWU6IHN0cmluZykge1xuICBpZiAocGFja2FnZU5hbWUgPT09IFwiYXdzLWNkay1saWJcIikge1xuICAgIHJldHVybiBQQUNLQUdFX0FXU19DREtfVkVSU0lPTi5WMjtcbiAgfSBlbHNlIGlmIChwYWNrYWdlTmFtZS5zdGFydHNXaXRoKFwiQGF3cy1jZGsvXCIpKSB7XG4gICAgaWYgKHBhY2thZ2VOYW1lLmVuZHNXaXRoKFwiLWFscGhhXCIpKSB7XG4gICAgICByZXR1cm4gUEFDS0FHRV9BV1NfQ0RLX1ZFUlNJT04uVjI7XG4gICAgfSBlbHNlIGlmIChBV1NfQ0RLX1YxX1YyX1NDT1BFRF9QQUNLQUdFUy5pbmNsdWRlcyhwYWNrYWdlTmFtZSkpIHtcbiAgICAgIHJldHVybiBQQUNLQUdFX0FXU19DREtfVkVSU0lPTi5FSVRIRVI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBQQUNLQUdFX0FXU19DREtfVkVSU0lPTi5WMTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFBBQ0tBR0VfQVdTX0NES19WRVJTSU9OLlVOS05PV047XG4gIH1cbn1cblxuLyoqXG4gKiBBIGxpc3Qgb2YgYWxsIGtub3duIHBhY2thZ2VzIGluIHRoZSBcIkBhd3MtY2RrL1wiIHNjb3BlIHRoYXQgYXJlIHB1Ymxpc2hlZFxuICogYm90aCBmb3IgdjEgYW5kIHYyLlxuICovXG5jb25zdCBBV1NfQ0RLX1YxX1YyX1NDT1BFRF9QQUNLQUdFUyA9IFtcbiAgXCJAYXdzLWNkay9jZm5zcGVjXCIsXG4gIFwiQGF3cy1jZGsvY3gtYXBpXCIsXG4gIFwiQGF3cy1jZGsvcmVnaW9uLWluZm9cIixcbiAgXCJAYXdzLWNkay9jbG91ZC1hc3NlbWJseS1zY2hlbWFcIixcbiAgXCJAYXdzLWNkay9hc3NlcnRcIixcbiAgXCJAYXdzLWNkay9jbG91ZGZvcm1hdGlvbi1kaWZmXCIsXG4gIFwiQGF3cy1jZGsvaW50ZWctcnVubmVyXCIsXG5dO1xuXG5mdW5jdGlvbiBkZXRlcm1pbmVGcmFtZXdvcmtWZXJzaW9uKG9wdGlvbnM6IEF3c0Nka0RlcHNPcHRpb25zKSB7XG4gIGNvbnN0IHZlciA9IHNlbXZlci5wYXJzZShvcHRpb25zLmNka1ZlcnNpb24pO1xuICBpZiAoIXZlcikge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBcImNka1ZlcnNpb25cIiBjYW5ub3QgYmUgcGFyc2VkIGFzIGEgc2VtdmVyIHZlcnNpb246ICR7b3B0aW9ucy5jZGtWZXJzaW9ufWBcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBtaW5pbXVtOiB2ZXIuZm9ybWF0KCksXG4gICAgcmFuZ2U6IG9wdGlvbnMuY2RrVmVyc2lvblBpbm5pbmdcbiAgICAgID8gb3B0aW9ucy5jZGtWZXJzaW9uXG4gICAgICA6IGBeJHtvcHRpb25zLmNka1ZlcnNpb259YCxcbiAgICBtYWpvcjogdmVyLm1ham9yLFxuICB9O1xufVxuIl19