jsii-docgen
Version:
generates api docs for jsii modules
393 lines • 47.5 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.JavaTranspile = void 0;
const Case = __importStar(require("case"));
const reflect = __importStar(require("jsii-reflect"));
const transpile = __importStar(require("./transpile"));
const schema_1 = require("../schema");
// Helper methods
const toCamelCase = (text) => {
return Case.camel(text !== null && text !== void 0 ? text : '');
};
const toUpperCamelCase = (test) => {
const camelCase = toCamelCase(test);
return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
};
// [1, 2, 3] -> [[], [1], [1, 2], [1, 2, 3]]
const prefixArrays = (arr) => {
const out = [[]];
const prefix = [];
for (const elem of arr) {
prefix.push(elem);
out.push([...prefix]);
}
return out;
};
/**
* Hack to convert a jsii property to a parameter for
* parameter expansion.
*/
const propertyToParameter = (callable, property) => {
return {
docs: property.docs,
method: callable,
name: property.name,
optional: property.optional,
parentType: callable.parentType,
spec: property.spec,
system: property.system,
type: property.type,
variadic: false,
};
};
class JavaTranspile extends transpile.TranspileBase {
constructor() {
super(transpile.Language.JAVA);
}
moduleLike(moduleLike) {
var _a, _b, _c, _d;
const javaPackage = (_b = (_a = moduleLike.targets) === null || _a === void 0 ? void 0 : _a.java) === null || _b === void 0 ? void 0 : _b.package;
// if this is a submodule, we need to break the package name down into the
// parent name and the submodule. we also allow submodules not to have
// explicit target names, in which case we need to append the snake-cased
// submodule name to the parent package name.
if (moduleLike instanceof reflect.Submodule) {
const parent = moduleLike.parent;
const parentFqn = (_d = (_c = parent.targets) === null || _c === void 0 ? void 0 : _c.java) === null || _d === void 0 ? void 0 : _d.package;
// if the submodule does not explicitly define a java package name, we need to deduce it from the parent
// based on jsii-pacmak package naming conventions.
// see https://github.com/aws/jsii/blob/b329670bf9ec222fad5fc0d614dcddd5daca7af5/packages/jsii-pacmak/lib/targets/java.ts#L3150
const submoduleJavaPackage = javaPackage !== null && javaPackage !== void 0 ? javaPackage : `${parentFqn}.${Case.snake(moduleLike.name)}`;
// for some modules, the parent module's Java package is a prefix of
// the submodule's Java package, e.g.
// { name: "software.amazon.awscdk", submodule: "software.amazon.awscdk.services.ecr" }
//
// but it's possible the names differ, for example in aws-cdk-lib:
// { name: "software.amazon.awscdk.core", submodule: "software.amazon.awscdk.services.ecr" }
return { name: parentFqn, submodule: submoduleJavaPackage };
}
return { name: javaPackage };
}
type(type) {
const submodule = this.findSubmodule(type);
const moduleLike = this.moduleLike(submodule ? submodule : type.assembly);
const fqn = [];
let namespace = type.namespace;
if (namespace) {
if (submodule && moduleLike.submodule) {
// if the type is in a submodule, submodule.name is a substring of the namespace
// so we update that part with the language-specific submodule string
fqn.push(namespace.replace(submodule.name, moduleLike.submodule));
}
else {
fqn.push(moduleLike.name);
fqn.push(namespace);
}
}
else {
fqn.push(moduleLike.name);
}
fqn.push(type.name);
return new transpile.TranspiledType({
fqn: fqn.join('.'),
name: type.name,
namespace: namespace,
module: moduleLike.name,
submodule: moduleLike.submodule,
submodulePath: (0, schema_1.submodulePath)(submodule),
source: type,
language: this.language,
});
}
callable(callable) {
const type = this.type(callable.parentType);
const parameters = callable.parameters.sort(this.optionalityCompare);
const requiredParams = parameters.filter((p) => !p.optional);
const optionalParams = parameters.filter((p) => p.optional);
const name = callable.name;
// simulate Java method overloading
const inputLists = prefixArrays(optionalParams).map((optionals) => {
return [...requiredParams, ...optionals].map((p) => this.formatParameter(this.parameter(p)));
});
let returnType;
if (reflect.Initializer.isInitializer(callable)) {
returnType = this.typeReference(callable.parentType.reference);
}
else if (reflect.Method.isMethod(callable)) {
returnType = this.typeReference(callable.returns.type);
}
const returns = returnType === null || returnType === void 0 ? void 0 : returnType.toString({
typeFormatter: (t) => t.name,
});
const signatures = inputLists.map((inputs) => {
return this.formatSignature(name, inputs, returns);
});
let invocations;
if (this.isClassBuilderGenerated(callable)) {
const struct = this.extractFirstStruct(parameters);
// render using Java builder syntax (show no overloads)
invocations = [this.formatClassBuilder(type, parameters, struct)];
// flatten out the parameters so the user doesn't have to jump between
// docs of Foo and FooProps
for (const property of struct.allProperties) {
const parameter = propertyToParameter(callable, property);
parameters.push(parameter);
}
}
else {
invocations = reflect.Initializer.isInitializer(callable)
// render with `new Class` syntax (showing all constructor overloads)
? inputLists.map((inputs) => this.formatClassInitialization(type, inputs))
// render invocation as method calls (showing all method overloads)
: inputLists.map((inputs) => this.formatInvocation(type, inputs, name));
}
return {
name,
parentType: type,
import: this.formatImport(type),
parameters,
signatures,
invocations,
};
}
class(klass) {
return {
name: klass.name,
type: this.type(klass),
};
}
struct(struct) {
const type = this.type(struct);
const indent = ' '.repeat(4);
const inputs = struct.allProperties.map((p) => this.formatBuilderMethod(this.property(p), indent)).flat();
return {
type: type,
name: struct.name,
import: this.formatImport(type),
initialization: this.formatStructBuilder(type, inputs),
};
}
interface(iface) {
return {
name: iface.name,
type: this.type(iface),
};
}
parameter(parameter) {
const typeRef = this.typeReference(parameter.type);
return {
name: parameter.name,
parentType: this.type(parameter.parentType),
typeReference: typeRef,
optional: parameter.optional,
variadic: parameter.variadic,
declaration: this.formatProperty(parameter.name, typeRef),
};
}
property(property) {
const typeRef = this.typeReference(property.type);
return {
name: property.name,
parentType: this.type(property.parentType),
typeReference: typeRef,
optional: property.optional,
declaration: this.formatProperty(property.name, typeRef),
};
}
enum(enu) {
return {
fqn: this.type(enu).fqn,
name: enu.name,
};
}
enumMember(em) {
return {
fqn: `${this.enum(em.enumType).fqn}.${em.name}`,
name: em.name,
};
}
unionOf(types) {
return types.join('|');
}
intersectionOf(types) {
return types.join('+');
}
listOf(type) {
return `java.util.List<${type}>`;
}
variadicOf(type) {
return `${type}...`;
}
mapOf(type) {
return `java.util.Map<java.lang.String, ${type}>`;
}
any() {
return 'java.lang.Object';
}
void() {
return 'void';
}
str() {
return 'java.lang.String';
}
number() {
return 'java.lang.Number';
}
boolean() {
return 'java.lang.Boolean';
}
json() {
return 'com.fasterxml.jackson.databind.node.ObjectNode';
}
date() {
return 'java.time.Instant';
}
readme(readme) {
return readme;
}
formatImport(type) {
return `import ${type.fqn};`;
}
;
formatParameter(transpiled) {
const tf = transpiled.typeReference.toString({
typeFormatter: (t) => t.name,
});
if (transpiled.variadic) {
return `${this.variadicOf(tf)} ${transpiled.name}`;
}
return `${tf} ${transpiled.name}`;
}
formatInputs(inputs) {
return inputs.join(', ');
}
;
formatStructBuilder(type, methods) {
const builder = `${type.name}.builder()`;
return [
builder,
...methods,
' .build();',
].join('\n');
}
;
formatClassInitialization(type, inputs) {
return `new ${type.name}(${this.formatInputs(inputs)});`;
}
;
formatClassBuilder(type, parameters, struct) {
const createArgs = this.formatInputs(parameters.map((p) => this.formatParameter(this.parameter(p))));
const indent = ' '.repeat(4);
const methods = struct.allProperties.map((p) => this.formatBuilderMethod(this.property(p), indent)).flat();
return [
`${type.name}.Builder.create(${createArgs})`,
...methods,
`${indent}.build();`,
].join('\n');
}
;
formatSignature(name, inputs, returns) {
return `public ${returns ? returns + ' ' : ''}${name}(${this.formatInputs(inputs)})`;
}
;
formatBuilderMethod(transpiled, indent) {
if (transpiled.optional)
indent = '//' + indent.slice(2);
const lowerCamel = toCamelCase(transpiled.name);
const base = `${indent}.${lowerCamel}`;
const tf = transpiled.typeReference.toString({
typeFormatter: (t) => t.name,
});
// allow rendering union types as multiple overrided builder methods
if (tf.includes(' OR ')) {
const choices = tf.split(' OR ');
return choices.map((typ) => `${base}(${typ})`);
}
else {
return [`${base}(${tf})`];
}
}
formatInvocation(type, inputs, method) {
let target = type.name;
if (method) {
target = `${target}.${method}`;
}
return `${target}(${this.formatInputs(inputs)})`;
}
;
isStruct(p) {
return p.type.fqn ? p.system.findFqn(p.type.fqn).isDataType() : false;
}
isClassBuilderGenerated(callable) {
if (callable.kind !== reflect.MemberKind.Initializer) {
return false;
}
const parameters = callable.parameters.sort(this.optionalityCompare);
const firstStruct = parameters.find((param) => this.isStruct(param));
// no builder is generated if there is no struct parameter
if (!firstStruct) {
return false;
}
return true;
}
;
/**
* Extracts the first struct out of a list of parameters (and throws
* if there is none), removing it from the array.
*/
extractFirstStruct(parameters) {
const firstStruct = parameters.find((param) => this.isStruct(param));
if (!firstStruct) {
throw new Error('No struct found in parameter list.');
}
const struct = firstStruct.parentType.system.findInterface(firstStruct.type.fqn);
parameters.splice(parameters.indexOf(firstStruct), 1);
return struct;
}
formatProperty(name, typeReference) {
const tf = typeReference.toString({
typeFormatter: (t) => t.name,
});
if (tf.includes(' OR ')) {
return `public java.lang.Object get${toUpperCamelCase(name)}();`;
}
else {
return `public ${tf} get${toUpperCamelCase(name)}();`;
}
}
}
exports.JavaTranspile = JavaTranspile;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamF2YS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kb2NnZW4vdHJhbnNwaWxlL2phdmEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsMkNBQTZCO0FBQzdCLHNEQUF3QztBQUN4Qyx1REFBeUM7QUFDekMsc0NBQTBDO0FBRTFDLGlCQUFpQjtBQUNqQixNQUFNLFdBQVcsR0FBRyxDQUFDLElBQWEsRUFBRSxFQUFFO0lBQ3BDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLGFBQUosSUFBSSxjQUFKLElBQUksR0FBSSxFQUFFLENBQUMsQ0FBQztBQUNoQyxDQUFDLENBQUM7QUFFRixNQUFNLGdCQUFnQixHQUFHLENBQUMsSUFBYSxFQUFFLEVBQUU7SUFDekMsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3BDLE9BQU8sU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hFLENBQUMsQ0FBQztBQUVGLDRDQUE0QztBQUM1QyxNQUFNLFlBQVksR0FBRyxDQUFJLEdBQVEsRUFBUyxFQUFFO0lBQzFDLE1BQU0sR0FBRyxHQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDeEIsTUFBTSxNQUFNLEdBQVEsRUFBRSxDQUFDO0lBQ3ZCLEtBQUssTUFBTSxJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7UUFDdkIsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQixHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3hCLENBQUM7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMsQ0FBQztBQUVGOzs7R0FHRztBQUNILE1BQU0sbUJBQW1CLEdBQUcsQ0FD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LEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUN4RCxDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBSSxDQUFDLENBQUM7UUFDbEYsVUFBVSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3RELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFTyxjQUFjLENBQ3BCLElBQVksRUFDWixhQUFpRDtRQUVqRCxNQUFNLEVBQUUsR0FBRyxhQUFhLENBQUMsUUFBUSxDQUFDO1lBQ2hDLGFBQWEsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUk7U0FDN0IsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDeEIsT0FBTyw4QkFBOEIsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNuRSxDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sVUFBVSxFQUFFLE9BQU8sZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUN4RCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBeFlELHNDQXdZQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIENhc2UgZnJvbSAnY2FzZSc7XG5pbXBvcnQgKiBhcyByZWZsZWN0IGZyb20gJ2pzaWktcmVmbGVjdCc7XG5pbXBvcnQgKiBhcyB0cmFuc3BpbGUgZnJvbSAnLi90cmFuc3BpbGUnO1xuaW1wb3J0IHsgc3VibW9kdWxlUGF0aCB9IGZyb20gJy4uL3NjaGVtYSc7XG5cbi8vIEhlbHBlciBtZXRob2RzXG5jb25zdCB0b0NhbWVsQ2FzZSA9ICh0ZXh0Pzogc3RyaW5nKSA9PiB7XG4gIHJldHVybiBDYXNlLmNhbWVsKHRleHQgPz8gJycpO1xufTtcblxuY29uc3QgdG9VcHBlckNhbWVsQ2FzZSA9ICh0ZXN0Pzogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IGNhbWVsQ2FzZSA9IHRvQ2FtZWxDYXNlKHRlc3QpO1xuICByZXR1cm4gY2FtZWxDYXNlLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgY2FtZWxDYXNlLnNsaWNlKDEpO1xufTtcblxuLy8gWzEsIDIsIDNdIC0+IFtbXSwgWzFdLCBbMSwgMl0sIFsxLCAyLCAzXV1cbmNvbnN0IHByZWZpeEFycmF5cyA9IDxUPihhcnI6IFRbXSk6IFRbXVtdID0+IHtcbiAgY29uc3Qgb3V0OiBUW11bXSA9IFtbXV07XG4gIGNvbnN0IHByZWZpeDogVFtdID0gW107XG4gIGZvciAoY29uc3QgZWxlbSBvZiBhcnIpIHtcbiAgICBwcmVmaXgucHVzaChlbGVtKTtcbiAgICBvdXQucHVzaChbLi4ucHJlZml4XSk7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogSGFjayB0byBjb252ZXJ0IGEganNpaSBwcm9wZXJ0eSB0byBhIHBhcmFtZXRlciBmb3JcbiAqIHBhcmFtZXRlciBleHBhbnNpb24uXG4gKi9cbmNvbnN0IHByb3BlcnR5VG9QYXJhbWV0ZXIgPSAoXG4gIGNhbGxhYmxlOiByZWZsZWN0LkNhbGxhYmxlLFxuICBwcm9wZXJ0eTogcmVmbGVjdC5Qcm9wZXJ0eSxcbik6IHJlZmxlY3QuUGFyYW1ldGVyID0+IHtcbiAgcmV0dXJuIHtcbiAgICBkb2NzOiBwcm9wZXJ0eS5kb2NzLFxuICAgIG1ldGhvZDogY2FsbGFibGUsXG4gICAgbmFtZTogcHJvcGVydHkubmFtZSxcbiAgICBvcHRpb25hbDogcHJvcGVydHkub3B0aW9uYWwsXG4gICAgcGFyZW50VHlwZTogY2FsbGFibGUucGFyZW50VHlwZSxcbiAgICBzcGVjOiBwcm9wZXJ0eS5zcGVjLFxuICAgIHN5c3RlbTogcHJvcGVydHkuc3lzdGVtLFxuICAgIHR5cGU6IHByb3BlcnR5LnR5cGUsXG4gICAgdmFyaWFkaWM6IGZhbHNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNsYXNzIEphdmFUcmFuc3BpbGUgZXh0ZW5kcyB0cmFuc3BpbGUuVHJhbnNwaWxlQmFzZSB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKHRyYW5zcGlsZS5MYW5ndWFnZS5KQVZBKTtcbiAgfVxuXG4gIHB1YmxpYyBtb2R1bGVMaWtlKFxuICAgIG1vZHVsZUxpa2U6IHJlZmxlY3QuTW9kdWxlTGlrZSxcbiAgKTogdHJhbnNwaWxlLlRyYW5zcGlsZWRNb2R1bGVMaWtlIHtcbiAgICBjb25zdCBqYXZhUGFja2FnZTogc3RyaW5nID0gbW9kdWxlTGlrZS50YXJnZXRzPy5qYXZhPy5wYWNrYWdlO1xuXG4gICAgLy8gaWYgdGhpcyBpcyBhIHN1Ym1vZHVsZSwgd2UgbmVlZCB0byBicmVhayB0aGUgcGFja2FnZSBuYW1lIGRvd24gaW50byB0aGVcbiAgICAvLyBwYXJlbnQgbmFtZSBhbmQgdGhlIHN1Ym1vZHVsZS4gd2UgYWxzbyBhbGxvdyBzdWJtb2R1bGVzIG5vdCB0byBoYXZlXG4gICAgLy8gZXhwbGljaXQgdGFyZ2V0IG5hbWVzLCBpbiB3aGljaCBjYXNlIHdlIG5lZWQgdG8gYXBwZW5kIHRoZSBzbmFrZS1jYXNlZFxuICAgIC8vIHN1Ym1vZHVsZSBuYW1lIHRvIHRoZSBwYXJlbnQgcGFja2FnZSBuYW1lLlxuICAgIGlmIChtb2R1bGVMaWtlIGluc3RhbmNlb2YgcmVmbGVjdC5TdWJtb2R1bGUpIHtcbiAgICAgIGNvbnN0IHBhcmVudCA9IG1vZHVsZUxpa2UucGFyZW50O1xuICAgICAgY29uc3QgcGFyZW50RnFuID0gcGFyZW50LnRhcmdldHM/LmphdmE/LnBhY2thZ2U7XG5cbiAgICAgIC8vIGlmIHRoZSBzdWJtb2R1bGUgZG9lcyBub3QgZXhwbGljaXRseSBkZWZpbmUgYSBqYXZhIHBhY2thZ2UgbmFtZSwgd2UgbmVlZCB0byBkZWR1Y2UgaXQgZnJvbSB0aGUgcGFyZW50XG4gICAgICAvLyBiYXNlZCBvbiBqc2lpLXBhY21hayBwYWNrYWdlIG5hbWluZyBjb252ZW50aW9ucy5cbiAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vYXdzL2pzaWkvYmxvYi9iMzI5NjcwYmY5ZWMyMjJmYWQ1ZmMwZDYxNGRjZGRkNWRhY2E3YWY1L3BhY2thZ2VzL2pzaWktcGFjbWFrL2xpYi90YXJnZXRzL2phdmEudHMjTDMxNTBcbiAgICAgIGNvbnN0IHN1Ym1vZHVsZUphdmFQYWNrYWdlID0gamF2YVBhY2thZ2UgPz8gYCR7cGFyZW50RnFufS4ke0Nhc2Uuc25ha2UobW9kdWxlTGlrZS5uYW1lKX1gO1xuXG4gICAgICAvLyBmb3Igc29tZSBtb2R1bGVzLCB0aGUgcGFyZW50IG1vZHVsZSdzIEphdmEgcGFja2FnZSBpcyBhIHByZWZpeCBvZlxuICAgICAgLy8gdGhlIHN1Ym1vZHVsZSdzIEphdmEgcGFja2FnZSwgZS5nLlxuICAgICAgLy8geyBuYW1lOiBcInNvZnR3YXJlLmFtYXpvbi5hd3NjZGtcIiwgc3VibW9kdWxlOiBcInNvZnR3YXJlLmFtYXpvbi5hd3NjZGsuc2VydmljZXMuZWNyXCIgfVxuICAgICAgLy9cbiAgICAgIC8vIGJ1dCBpdCdzIHBvc3NpYmxlIHRoZSBuYW1lcyBkaWZmZXIsIGZvciBleGFtcGxlIGluIGF3cy1jZGstbGliOlxuICAgICAgLy8geyBuYW1lOiBcInNvZnR3YXJlLmFtYXpvbi5hd3NjZGsuY29yZVwiLCBzdWJtb2R1bGU6IFwic29mdHdhcmUuYW1hem9uLmF3c2Nkay5zZXJ2aWNlcy5lY3JcIiB9XG4gICAgICByZXR1cm4geyBuYW1lOiBwYXJlbnRGcW4sIHN1Ym1vZHVsZTogc3VibW9kdWxlSmF2YVBhY2thZ2UgfTtcbiAgICB9XG5cbiAgICByZXR1cm4geyBuYW1lOiBqYXZhUGFja2FnZSB9O1xuICB9XG5cbiAgcHVibGljIHR5cGUodHlwZTogcmVmbGVjdC5UeXBlKTogdHJhbnNwaWxlLlRyYW5zcGlsZWRUeXBlIHtcbiAgICBjb25zdCBzdWJtb2R1bGUgPSB0aGlzLmZpbmRTdWJtb2R1bGUodHlwZSk7XG4gICAgY29uc3QgbW9kdWxlTGlrZSA9IHRoaXMubW9kdWxlTGlrZShzdWJtb2R1bGUgPyBzdWJtb2R1bGUgOiB0eXBlLmFzc2VtYmx5KTtcblxuICAgIGNvbnN0IGZxbiA9IFtdO1xuXG4gICAgbGV0IG5hbWVzcGFjZSA9IHR5cGUubmFtZXNwYWNlO1xuICAgIGlmIChuYW1lc3BhY2UpIHtcbiAgICAgIGlmIChzdWJtb2R1bGUgJiYgbW9kdWxlTGlrZS5zdWJtb2R1bGUpIHtcbiAgICAgICAgLy8gaWYgdGhlIHR5cGUgaXMgaW4gYSBzdWJtb2R1bGUsIHN1Ym1vZHVsZS5uYW1lIGlzIGEgc3Vic3RyaW5nIG9mIHRoZSBuYW1lc3BhY2VcbiAgICAgICAgLy8gc28gd2UgdXBkYXRlIHRoYXQgcGFydCB3aXRoIHRoZSBsYW5ndWFnZS1zcGVjaWZpYyBzdWJtb2R1bGUgc3RyaW5nXG4gICAgICAgIGZxbi5wdXNoKG5hbWVzcGFjZS5yZXBsYWNlKHN1Ym1vZHVsZS5uYW1lLCBtb2R1bGVMaWtlLnN1Ym1vZHVsZSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZnFuLnB1c2gobW9kdWxlTGlrZS5uYW1lKTtcbiAgICAgICAgZnFuLnB1c2gobmFtZXNwYWNlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZnFuLnB1c2gobW9kdWxlTGlrZS5uYW1lKTtcbiAgICB9XG4gICAgZnFuLnB1c2godHlwZS5uYW1lKTtcblxuICAgIHJldHVybiBuZXcgdHJhbnNwaWxlLlRyYW5zcGlsZWRUeXBlKHtcbiAgICAgIGZxbjogZnFuLmpvaW4oJy4nKSxcbiAgICAgIG5hbWU6IHR5cGUubmFtZSxcbiAgICAgIG5hbWVzcGFjZTogbmFtZXNwYWNlLFxuICAgICAgbW9kdWxlOiBtb2R1bGVMaWtlLm5hbWUsXG4gICAgICBzdWJtb2R1bGU6IG1vZHVsZUxpa2Uuc3VibW9kdWxlLFxuICAgICAgc3VibW9kdWxlUGF0aDogc3VibW9kdWxlUGF0aChzdWJtb2R1bGUpLFxuICAgICAgc291cmNlOiB0eXBlLFxuICAgICAgbGFuZ3VhZ2U6IHRoaXMubGFuZ3VhZ2UsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgY2FsbGFibGUoY2FsbGFibGU6IHJlZmxlY3QuQ2FsbGFibGUpOiB0cmFuc3BpbGUuVHJhbnNwaWxlZENhbGxhYmxlIHtcbiAgICBjb25zdCB0eXBlID0gdGhpcy50eXBlKGNhbGxhYmxlLnBhcmVudFR5cGUpO1xuXG4gICAgY29uc3QgcGFyYW1ldGVycyA9IGNhbGxhYmxlLnBhcmFtZXRlcnMuc29ydCh0aGlzLm9wdGlvbmFsaXR5Q29tcGFyZSk7XG5cbiAgICBjb25zdCByZXF1aXJlZFBhcmFtcyA9IHBhcmFtZXRlcnMuZmlsdGVyKChwKSA9PiAhcC5vcHRpb25hbCk7XG4gICAgY29uc3Qgb3B0aW9uYWxQYXJhbXMgPSBwYXJhbWV0ZXJzLmZpbHRlcigocCkgPT4gcC5vcHRpb25hbCk7XG5cbiAgICBjb25zdCBuYW1lID0gY2FsbGFibGUubmFtZTtcblxuICAgIC8vIHNpbXVsYXRlIEphdmEgbWV0aG9kIG92ZXJsb2FkaW5nXG4gICAgY29uc3QgaW5wdXRMaXN0cyA9IHByZWZpeEFycmF5cyhvcHRpb25hbFBhcmFtcykubWFwKChvcHRpb25hbHMpID0+IHtcbiAgICAgIHJldHVybiBbLi4ucmVxdWlyZWRQYXJhbXMsIC4uLm9wdGlvbmFsc10ubWFwKChwKSA9PiB0aGlzLmZvcm1hdFBhcmFtZXRlcih0aGlzLnBhcmFtZXRlcihwKSkpO1xuICAgIH0pO1xuXG4gICAgbGV0IHJldHVyblR5cGU6IHRyYW5zcGlsZS5JVHJhbnNwaWxlZFR5cGVSZWZlcmVuY2UgfCB1bmRlZmluZWQ7XG4gICAgaWYgKHJlZmxlY3QuSW5pdGlhbGl6ZXIuaXNJbml0aWFsaXplcihjYWxsYWJsZSkpIHtcbiAgICAgIHJldHVyblR5cGUgPSB0aGlzLnR5cGVSZWZlcmVuY2UoY2FsbGFibGUucGFyZW50VHlwZS5yZWZlcmVuY2UpO1xuICAgIH0gZWxzZSBpZiAocmVmbGVjdC5NZXRob2QuaXNNZXRob2QoY2FsbGFibGUpKSB7XG4gICAgICByZXR1cm5UeXBlID0gdGhpcy50eXBlUmVmZXJlbmNlKGNhbGxhYmxlLnJldHVybnMudHlwZSk7XG4gICAgfVxuICAgIGNvbnN0IHJldHVybnMgPSByZXR1cm5UeXBlPy50b1N0cmluZyh7XG4gICAgICB0eXBlRm9ybWF0dGVyOiAodCkgPT4gdC5uYW1lLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgc2lnbmF0dXJlcyA9IGlucHV0TGlzdHMubWFwKChpbnB1dHMpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmZvcm1hdFNpZ25hdHVyZShuYW1lLCBpbnB1dHMsIHJldHVybnMpO1xuICAgIH0pO1xuXG4gICAgbGV0IGludm9jYXRpb25zO1xuXG4gICAgaWYgKHRoaXMuaXNDbGFzc0J1aWxkZXJHZW5lcmF0ZWQoY2FsbGFibGUpKSB7XG4gICAgICBjb25zdCBzdHJ1Y3QgPSB0aGlzLmV4dHJhY3RGaXJzdFN0cnVjdChwYXJhbWV0ZXJzKTtcblxuICAgICAgLy8gcmVuZGVyIHVzaW5nIEphdmEgYnVpbGRlciBzeW50YXggKHNob3cgbm8gb3ZlcmxvYWRzKVxuICAgICAgaW52b2NhdGlvbnMgPSBbdGhpcy5mb3JtYXRDbGFzc0J1aWxkZXIodHlwZSwgcGFyYW1ldGVycywgc3RydWN0KV07XG5cbiAgICAgIC8vIGZsYXR0ZW4gb3V0IHRoZSBwYXJhbWV0ZXJzIHNvIHRoZSB1c2VyIGRvZXNuJ3QgaGF2ZSB0byBqdW1wIGJldHdlZW5cbiAgICAgIC8vIGRvY3Mgb2YgRm9vIGFuZCBGb29Qcm9wc1xuICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBzdHJ1Y3QuYWxsUHJvcGVydGllcykge1xuICAgICAgICBjb25zdCBwYXJhbWV0ZXIgPSBwcm9wZXJ0eVRvUGFyYW1ldGVyKGNhbGxhYmxlLCBwcm9wZXJ0eSk7XG4gICAgICAgIHBhcmFtZXRlcnMucHVzaChwYXJhbWV0ZXIpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpbnZvY2F0aW9ucyA9IHJlZmxlY3QuSW5pdGlhbGl6ZXIuaXNJbml0aWFsaXplcihjYWxsYWJsZSlcbiAgICAgICAgLy8gcmVuZGVyIHdpdGggYG5ldyBDbGFzc2Agc3ludGF4IChzaG93aW5nIGFsbCBjb25zdHJ1Y3RvciBvdmVybG9hZHMpXG4gICAgICAgID8gaW5wdXRMaXN0cy5tYXAoKGlucHV0cykgPT4gdGhpcy5mb3JtYXRDbGFzc0luaXRpYWxpemF0aW9uKHR5cGUsIGlucHV0cykpXG4gICAgICAgIC8vIHJlbmRlciBpbnZvY2F0aW9uIGFzIG1ldGhvZCBjYWxscyAoc2hvd2luZyBhbGwgbWV0aG9kIG92ZXJsb2FkcylcbiAgICAgICAgOiBpbnB1dExpc3RzLm1hcCgoaW5wdXRzKSA9PiB0aGlzLmZvcm1hdEludm9jYXRpb24odHlwZSwgaW5wdXRzLCBuYW1lKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWUsXG4gICAgICBwYXJlbnRUeXBlOiB0eXBlLFxuICAgICAgaW1wb3J0OiB0aGlzLmZvcm1hdEltcG9ydCh0eXBlKSxcbiAgICAgIHBhcmFtZXRlcnMsXG4gICAgICBzaWduYXR1cmVzLFxuICAgICAgaW52b2NhdGlvbnMsXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBjbGFzcyhrbGFzczogcmVmbGVjdC5DbGFzc1R5cGUpOiB0cmFuc3BpbGUuVHJhbnNwaWxlZENsYXNzIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZToga2xhc3MubmFtZSxcbiAgICAgIHR5cGU6IHRoaXMudHlwZShrbGFzcyksXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBzdHJ1Y3Qoc3RydWN0OiByZWZsZWN0LkludGVyZmFjZVR5cGUpOiB0cmFuc3BpbGUuVHJhbnNwaWxlZFN0cnVjdCB7XG4gICAgY29uc3QgdHlwZSA9IHRoaXMudHlwZShzdHJ1Y3QpO1xuICAgIGNvbnN0IGluZGVudCA9ICcgJy5yZXBlYXQoNCk7XG4gICAgY29uc3QgaW5wdXRzID0gc3RydWN0LmFsbFByb3BlcnRpZXMubWFwKChwKSA9PlxuICAgICAgdGhpcy5mb3JtYXRCdWlsZGVyTWV0aG9kKHRoaXMucHJvcGVydHkocCksIGluZGVudCksXG4gICAgKS5mbGF0KCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IHR5cGUsXG4gICAgICBuYW1lOiBzdHJ1Y3QubmFtZSxcbiAgICAgIGltcG9ydDogdGhpcy5mb3JtYXRJbXBvcnQodHlwZSksXG4gICAgICBpbml0aWFsaXphdGlvbjogdGhpcy5mb3JtYXRTdHJ1Y3RCdWlsZGVyKHR5cGUsIGlucHV0cyksXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBpbnRlcmZhY2UoXG4gICAgaWZhY2U6IHJlZmxlY3QuSW50ZXJmYWNlVHlwZSxcbiAgKTogdHJhbnNwaWxlLlRyYW5zcGlsZWRJbnRlcmZhY2Uge1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiBpZmFjZS5uYW1lLFxuICAgICAgdHlwZTogdGhpcy50eXBlKGlmYWNlKSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIHBhcmFtZXRlcihcbiAgICBwYXJhbWV0ZXI6IHJlZmxlY3QuUGFyYW1ldGVyLFxuICApOiB0cmFuc3BpbGUuVHJhbnNwaWxlZFBhcmFtZXRlciB7XG4gICAgY29uc3QgdHlwZVJlZiA9IHRoaXMudHlwZVJlZmVyZW5jZShwYXJhbWV0ZXIudHlwZSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IHBhcmFtZXRlci5uYW1lLFxuICAgICAgcGFyZW50VHlwZTogdGhpcy50eXBlKHBhcmFtZXRlci5wYXJlbnRUeXBlKSxcbiAgICAgIHR5cGVSZWZlcmVuY2U6IHR5cGVSZWYsXG4gICAgICBvcHRpb25hbDogcGFyYW1ldGVyLm9wdGlvbmFsLFxuICAgICAgdmFyaWFkaWM6IHBhcmFtZXRlci52YXJpYWRpYyxcbiAgICAgIGRlY2xhcmF0aW9uOiB0aGlzLmZvcm1hdFByb3BlcnR5KHBhcmFtZXRlci5uYW1lLCB0eXBlUmVmKSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIHByb3BlcnR5KHByb3BlcnR5OiByZWZsZWN0LlByb3BlcnR5KTogdHJhbnNwaWxlLlRyYW5zcGlsZWRQcm9wZXJ0eSB7XG4gICAgY29uc3QgdHlwZVJlZiA9IHRoaXMudHlwZVJlZmVyZW5jZShwcm9wZXJ0eS50eXBlKTtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogcHJvcGVydHkubmFtZSxcbiAgICAgIHBhcmVudFR5cGU6IHRoaXMudHlwZShwcm9wZXJ0eS5wYXJlbnRUeXBlKSxcbiAgICAgIHR5cGVSZWZlcmVuY2U6IHR5cGVSZWYsXG4gICAgICBvcHRpb25hbDogcHJvcGVydHkub3B0aW9uYWwsXG4gICAgICBkZWNsYXJhdGlvbjogdGhpcy5mb3JtYXRQcm9wZXJ0eShwcm9wZXJ0eS5uYW1lLCB0eXBlUmVmKSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIGVudW0oZW51OiByZWZsZWN0LkVudW1UeXBlKTogdHJhbnNwaWxlLlRyYW5zcGlsZWRFbnVtIHtcbiAgICByZXR1cm4ge1xuICAgICAgZnFuOiB0aGlzLnR5cGUoZW51KS5mcW4sXG4gICAgICBuYW1lOiBlbnUubmFtZSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIGVudW1NZW1iZXIoZW06IHJlZmxlY3QuRW51bU1lbWJlcik6IHRyYW5zcGlsZS5UcmFuc3BpbGVkRW51bU1lbWJlciB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZxbjogYCR7dGhpcy5lbnVtKGVtLmVudW1UeXBlKS5mcW59LiR7ZW0ubmFtZX1gLFxuICAgICAgbmFtZTogZW0ubmFtZSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIHVuaW9uT2YodHlwZXM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdHlwZXMuam9pbignfCcpO1xuICB9XG5cbiAgcHVibGljIGludGVyc2VjdGlvbk9mKHR5cGVzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHR5cGVzLmpvaW4oJysnKTtcbiAgfVxuXG4gIHB1YmxpYyBsaXN0T2YodHlwZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYGphdmEudXRpbC5MaXN0PCR7dHlwZX0+YDtcbiAgfVxuXG4gIHB1YmxpYyB2YXJpYWRpY09mKHR5cGU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3R5cGV9Li4uYDtcbiAgfVxuXG4gIHB1YmxpYyBtYXBPZih0eXBlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCAke3R5cGV9PmA7XG4gIH1cblxuICBwdWJsaWMgYW55KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdqYXZhLmxhbmcuT2JqZWN0JztcbiAgfVxuXG4gIHB1YmxpYyB2b2lkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICd2b2lkJztcbiAgfVxuXG4gIHB1YmxpYyBzdHIoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ2phdmEubGFuZy5TdHJpbmcnO1xuICB9XG5cbiAgcHVibGljIG51bWJlcigpOiBzdHJpbmcge1xuICAgIHJldHVybiAnamF2YS5sYW5nLk51bWJlcic7XG4gIH1cblxuICBwdWJsaWMgYm9vbGVhbigpOiBzdHJpbmcge1xuICAgIHJldHVybiAnamF2YS5sYW5nLkJvb2xlYW4nO1xuICB9XG5cbiAgcHVibGljIGpzb24oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ2NvbS5mYXN0ZXJ4bWwuamFja3Nvbi5kYXRhYmluZC5ub2RlLk9iamVjdE5vZGUnO1xuICB9XG5cbiAgcHVibGljIGRhdGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ2phdmEudGltZS5JbnN0YW50JztcbiAgfVxuXG4gIHB1YmxpYyByZWFkbWUocmVhZG1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiByZWFkbWU7XG4gIH1cblxuICBwcml2YXRlIGZvcm1hdEltcG9ydCh0eXBlOiB0cmFuc3BpbGUuVHJhbnNwaWxlZFR5cGUpOiBzdHJpbmcge1xuICAgIHJldHVybiBgaW1wb3J0ICR7dHlwZS5mcW59O2A7XG4gIH07XG5cbiAgcHJpdmF0ZSBmb3JtYXRQYXJhbWV0ZXIoXG4gICAgdHJhbnNwaWxlZDogdHJhbnNwaWxlLlRyYW5zcGlsZWRQYXJhbWV0ZXIsXG4gICk6IHN0cmluZyB7XG4gICAgY29uc3QgdGYgPSB0cmFuc3BpbGVkLnR5cGVSZWZlcmVuY2UudG9TdHJpbmcoe1xuICAgICAgdHlwZUZvcm1hdHRlcjogKHQpID0+IHQubmFtZSxcbiAgICB9KTtcblxuICAgIGlmICh0cmFuc3BpbGVkLnZhcmlhZGljKSB7XG4gICAgICByZXR1cm4gYCR7dGhpcy52YXJpYWRpY09mKHRmKX0gJHt0cmFuc3BpbGVkLm5hbWV9YDtcbiAgICB9XG5cbiAgICByZXR1cm4gYCR7dGZ9ICR7dHJhbnNwaWxlZC5uYW1lfWA7XG4gIH1cblxuICBwcml2YXRlIGZvcm1hdElucHV0cyhpbnB1dHM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgICByZXR1cm4gaW5wdXRzLmpvaW4oJywgJyk7XG4gIH07XG5cbiAgcHJpdmF0ZSBmb3JtYXRTdHJ1Y3RCdWlsZGVyKHR5cGU6IHRyYW5zcGlsZS5UcmFuc3BpbGVkVHlwZSwgbWV0aG9kczogc3RyaW5nW10pOiBzdHJpbmcge1xuICAgIGNvbnN0IGJ1aWxkZXIgPSBgJHt0eXBlLm5hbWV9LmJ1aWxkZXIoKWA7XG4gICAgcmV0dXJuIFtcbiAgICAgIGJ1aWxkZXIsXG4gICAgICAuLi5tZXRob2RzLFxuICAgICAgJyAgICAuYnVpbGQoKTsnLFxuICAgIF0uam9pbignXFxuJyk7XG4gIH07XG5cbiAgcHJpdmF0ZSBmb3JtYXRDbGFzc0luaXRpYWxpemF0aW9uKFxuICAgIHR5cGU6IHRyYW5zcGlsZS5UcmFuc3BpbGVkVHlwZSxcbiAgICBpbnB1dHM6IHN0cmluZ1tdLFxuICApOiBzdHJpbmcge1xuICAgIHJldHVybiBgbmV3ICR7dHlwZS5uYW1lfSgke3RoaXMuZm9ybWF0SW5wdXRzKGlucHV0cyl9KTtgO1xuICB9O1xuXG4gIHByaXZhdGUgZm9ybWF0Q2xhc3NCdWlsZGVyKFxuICAgIHR5cGU6IHRyYW5zcGlsZS5UcmFuc3BpbGVkVHlwZSxcbiAgICBwYXJhbWV0ZXJzOiByZWZsZWN0LlBhcmFtZXRlcltdLFxuICAgIHN0cnVjdDogcmVmbGVjdC5JbnRlcmZhY2VUeXBlLFxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IGNyZWF0ZUFyZ3MgPSB0aGlzLmZvcm1hdElucHV0cyhwYXJhbWV0ZXJzLm1hcCgocCkgPT4gdGhpcy5mb3JtYXRQYXJhbWV0ZXIodGhpcy5wYXJhbWV0ZXIocCkpKSk7XG4gICAgY29uc3QgaW5kZW50ID0gJyAnLnJlcGVhdCg0KTtcbiAgICBjb25zdCBtZXRob2RzOiBzdHJpbmdbXSA9IHN0cnVjdC5hbGxQcm9wZXJ0aWVzLm1hcCgocCkgPT5cbiAgICAgIHRoaXMuZm9ybWF0QnVpbGRlck1ldGhvZCh0aGlzLnByb3BlcnR5KHApLCBpbmRlbnQpLFxuICAgICkuZmxhdCgpO1xuICAgIHJldHVybiBbXG4gICAgICBgJHt0eXBlLm5hbWV9LkJ1aWxkZXIuY3JlYXRlKCR7Y3JlYXRlQXJnc30pYCxcbiAgICAgIC4uLm1ldGhvZHMsXG4gICAgICBgJHtpbmRlbnR9LmJ1aWxkKCk7YCxcbiAgICBdLmpvaW4oJ1xcbicpO1xuICB9O1xuXG5cbiAgcHJpdmF0ZSBmb3JtYXRTaWduYXR1cmUobmFtZTogc3RyaW5nLCBpbnB1dHM6IHN0cmluZ1tdLCByZXR1cm5zPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGBwdWJsaWMgJHtyZXR1cm5zID8gcmV0dXJucyArICcgJyA6ICcnfSR7bmFtZX0oJHt0aGlzLmZvcm1hdElucHV0cyhpbnB1dHMpfSlgO1xuICB9O1xuXG4gIHByaXZhdGUgZm9ybWF0QnVpbGRlck1ldGhvZChcbiAgICB0cmFuc3BpbGVkOiB0cmFuc3BpbGUuVHJhbnNwaWxlZFByb3BlcnR5LFxuICAgIGluZGVudDogc3RyaW5nLFxuICApOiBzdHJpbmdbXSB7XG4gICAgaWYgKHRyYW5zcGlsZWQub3B0aW9uYWwpIGluZGVudCA9ICcvLycgKyBpbmRlbnQuc2xpY2UoMik7XG4gICAgY29uc3QgbG93ZXJDYW1lbCA9IHRvQ2FtZWxDYXNlKHRyYW5zcGlsZWQubmFtZSk7XG4gICAgY29uc3QgYmFzZSA9IGAke2luZGVudH0uJHtsb3dlckNhbWVsfWA7XG4gICAgY29uc3QgdGYgPSB0cmFuc3BpbGVkLnR5cGVSZWZlcmVuY2UudG9TdHJpbmcoe1xuICAgICAgdHlwZUZvcm1hdHRlcjogKHQpID0+IHQubmFtZSxcbiAgICB9KTtcbiAgICAvLyBhbGxvdyByZW5kZXJpbmcgdW5pb24gdHlwZXMgYXMgbXVsdGlwbGUgb3ZlcnJpZGVkIGJ1aWxkZXIgbWV0aG9kc1xuICAgIGlmICh0Zi5pbmNsdWRlcygnIE9SICcpKSB7XG4gICAgICBjb25zdCBjaG9pY2VzID0gdGYuc3BsaXQoJyBPUiAnKTtcbiAgICAgIHJldHVybiBjaG9pY2VzLm1hcCgodHlwKSA9PiBgJHtiYXNlfSgke3R5cH0pYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBbYCR7YmFzZX0oJHt0Zn0pYF07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRJbnZvY2F0aW9uKFxuICAgIHR5cGU6IHRyYW5zcGlsZS5UcmFuc3BpbGVkVHlwZSxcbiAgICBpbnB1dHM6IHN0cmluZ1tdLFxuICAgIG1ldGhvZDogc3RyaW5nLFxuICApOiBzdHJpbmcge1xuICAgIGxldCB0YXJnZXQgPSB0eXBlLm5hbWU7XG4gICAgaWYgKG1ldGhvZCkge1xuICAgICAgdGFyZ2V0ID0gYCR7dGFyZ2V0fS4ke21ldGhvZH1gO1xuICAgIH1cbiAgICByZXR1cm4gYCR7dGFyZ2V0fSgke3RoaXMuZm9ybWF0SW5wdXRzKGlucHV0cyl9KWA7XG4gIH07XG5cbiAgcHJpdmF0ZSBpc1N0cnVjdChwOiByZWZsZWN0LlBhcmFtZXRlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBwLnR5cGUuZnFuID8gcC5zeXN0ZW0uZmluZEZxbihwLnR5cGUuZnFuKS5pc0RhdGFUeXBlKCkgOiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgaXNDbGFzc0J1aWxkZXJHZW5lcmF0ZWQoXG4gICAgY2FsbGFibGU6IHJlZmxlY3QuQ2FsbGFibGUsXG4gICk6IGJvb2xlYW4ge1xuICAgIGlmIChjYWxsYWJsZS5raW5kICE9PSByZWZsZWN0Lk1lbWJlcktpbmQuSW5pdGlhbGl6ZXIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJhbWV0ZXJzOiByZWZsZWN0LlBhcmFtZXRlcltdID0gY2FsbGFibGUucGFyYW1ldGVycy5zb3J0KHRoaXMub3B0aW9uYWxpdHlDb21wYXJlKTtcbiAgICBjb25zdCBmaXJzdFN0cnVjdCA9IHBhcmFtZXRlcnMuZmluZCgocGFyYW0pID0+IHRoaXMuaXNTdHJ1Y3QocGFyYW0pKTtcblxuICAgIC8vIG5vIGJ1aWxkZXIgaXMgZ2VuZXJhdGVkIGlmIHRoZXJlIGlzIG5vIHN0cnVjdCBwYXJhbWV0ZXJcbiAgICBpZiAoIWZpcnN0U3RydWN0KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgLyoqXG4gICAqIEV4dHJhY3RzIHRoZSBmaXJzdCBzdHJ1Y3Qgb3V0IG9mIGEgbGlzdCBvZiBwYXJhbWV0ZXJzIChhbmQgdGhyb3dzXG4gICAqIGlmIHRoZXJlIGlzIG5vbmUpLCByZW1vdmluZyBpdCBmcm9tIHRoZSBhcnJheS5cbiAgICovXG4gIHByaXZhdGUgZXh0cmFjdEZpcnN0U3RydWN0KFxuICAgIHBhcmFtZXRlcnM6IHJlZmxlY3QuUGFyYW1ldGVyW10sXG4gICk6IHJlZmxlY3QuSW50ZXJmYWNlVHlwZSB7XG4gICAgY29uc3QgZmlyc3RTdHJ1Y3QgPSBwYXJhbWV0ZXJzLmZpbmQoKHBhcmFtKSA9PiB0aGlzLmlzU3RydWN0KHBhcmFtKSk7XG4gICAgaWYgKCFmaXJzdFN0cnVjdCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBzdHJ1Y3QgZm91bmQgaW4gcGFyYW1ldGVyIGxpc3QuJyk7XG4gICAgfVxuICAgIGNvbnN0IHN0cnVjdCA9IGZpcnN0U3RydWN0LnBhcmVudFR5cGUuc3lzdGVtLmZpbmRJbnRlcmZhY2UoZmlyc3RTdHJ1Y3QudHlwZS5mcW4hKTtcbiAgICBwYXJhbWV0ZXJzLnNwbGljZShwYXJhbWV0ZXJzLmluZGV4T2YoZmlyc3RTdHJ1Y3QpLCAxKTtcbiAgICByZXR1cm4gc3RydWN0O1xuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRQcm9wZXJ0eShcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgdHlwZVJlZmVyZW5jZTogdHJhbnNwaWxlLklUcmFuc3BpbGVkVHlwZVJlZmVyZW5jZSxcbiAgKTogc3RyaW5nIHtcbiAgICBjb25zdCB0ZiA9IHR5cGVSZWZlcmVuY2UudG9TdHJpbmcoe1xuICAgICAgdHlwZUZvcm1hdHRlcjogKHQpID0+IHQubmFtZSxcbiAgICB9KTtcbiAgICBpZiAodGYuaW5jbHVkZXMoJyBPUiAnKSkge1xuICAgICAgcmV0dXJuIGBwdWJsaWMgamF2YS5sYW5nLk9iamVjdCBnZXQke3RvVXBwZXJDYW1lbENhc2UobmFtZSl9KCk7YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGBwdWJsaWMgJHt0Zn0gZ2V0JHt0b1VwcGVyQ2FtZWxDYXNlKG5hbWUpfSgpO2A7XG4gICAgfVxuICB9XG59XG4iXX0=