projen
Version:
CDK for software projects
273 lines • 42.7 kB
JavaScript
;
var _a, _b;
Object.defineProperty(exports, "__esModule", { value: true });
exports.LambdaRuntime = exports.LambdaFunction = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const path = require("path");
const case_1 = require("case");
const internal_1 = require("./internal");
const component_1 = require("../component");
const javascript_1 = require("../javascript");
const source_code_1 = require("../source-code");
const util_1 = require("../util");
/**
* Generates a pre-bundled AWS Lambda function construct from handler code.
*
* To use this, create an AWS Lambda handler file under your source tree with
* the `.lambda.ts` extension and add a `LambdaFunction` component to your
* typescript project pointing to this entrypoint.
*
* This will add a task to your "compile" step which will use `esbuild` to
* bundle the handler code into the build directory. It will also generate a
* file `src/foo-function.ts` with a custom AWS construct called `FooFunction`
* which extends `@aws-cdk/aws-lambda.Function` which is bound to the bundled
* handle through an asset.
*
* @example
*
* new LambdaFunction(myProject, {
* srcdir: myProject.srcdir,
* entrypoint: 'src/foo.lambda.ts',
* });
*/
class LambdaFunction extends component_1.Component {
/**
* Defines a pre-bundled AWS Lambda function construct from handler code.
*
* @param project The project to use
* @param options Options
*/
constructor(project, options) {
super(project);
const cdkDeps = options.cdkDeps;
const bundler = javascript_1.Bundler.of(project);
if (!bundler) {
throw new Error("No bundler found. Please add a Bundler component to your project.");
}
// Use NODEJS_REGIONAL_LATEST as default, which generates determineLatestNodeRuntime()
const runtime = options.runtime ?? LambdaRuntime.NODEJS_REGIONAL_LATEST;
const entrypoint = (0, util_1.normalizePersistedPath)(options.entrypoint);
// allow Lambda handler code to import dev-deps since they are only needed
// during bundling
const eslint = javascript_1.Eslint.of(project);
eslint?.allowDevDeps(entrypoint);
if (!entrypoint.endsWith(internal_1.TYPESCRIPT_LAMBDA_EXT) &&
!entrypoint.endsWith(internal_1.TYPESCRIPT_EDGE_LAMBDA_EXT) &&
!entrypoint.endsWith(internal_1.TYPESCRIPT_SINGLETON_LAMBDA_EXT)) {
throw new Error(`${entrypoint} must have a ${internal_1.TYPESCRIPT_LAMBDA_EXT}, ${internal_1.TYPESCRIPT_EDGE_LAMBDA_EXT}, or ${internal_1.TYPESCRIPT_SINGLETON_LAMBDA_EXT} extension`);
}
if (options.edgeLambda && options.singleton) {
throw new Error("singleton cannot be used with edgeLambda");
}
if (options.singletonUuid && !options.singleton) {
throw new Error("singletonUuid can only be used with singleton");
}
const sourceExtension = entrypoint.endsWith(internal_1.TYPESCRIPT_EDGE_LAMBDA_EXT)
? internal_1.TYPESCRIPT_EDGE_LAMBDA_EXT
: entrypoint.endsWith(internal_1.TYPESCRIPT_SINGLETON_LAMBDA_EXT)
? internal_1.TYPESCRIPT_SINGLETON_LAMBDA_EXT
: internal_1.TYPESCRIPT_LAMBDA_EXT;
const basePath = path.posix.join(path.dirname(entrypoint), path.basename(entrypoint, sourceExtension));
const constructFile = options.constructFile ?? `${basePath}-function.ts`;
if (path.extname(constructFile) !== ".ts") {
throw new Error(`Construct file name "${constructFile}" must have a .ts extension`);
}
// type names
const constructName = options.constructName ?? (0, case_1.pascal)(path.basename(basePath)) + "Function";
const propsType = `${constructName}Props`;
const bundle = bundler.addBundle(entrypoint, {
target: runtime.esbuildTarget,
platform: runtime.esbuildPlatform,
externals: runtime.defaultExternals,
...options.bundlingOptions,
tsconfigPath: project?.tsconfigDev?.fileName,
});
// calculate the relative path between the directory containing the
// generated construct source file to the directory containing the bundle
// index.js by resolving them as absolute paths first.
// e.g:
// - outfileAbs => `/project-outdir/assets/foo/bar/baz/foo-function/index.js`
// - constructAbs => `/project-outdir/src/foo/bar/baz/foo-function.ts`
const outfileAbs = path.join(project.outdir, bundle.outfile);
const constructAbs = path.join(project.outdir, constructFile);
const relativeOutfile = path.relative(path.dirname(constructAbs), path.dirname(outfileAbs));
const src = new source_code_1.SourceCode(project, constructFile);
if (src.marker) {
src.line(`// ${src.marker}`);
}
src.line("import * as path from 'path';");
if (cdkDeps.cdkMajorVersion === 1) {
if (options.edgeLambda) {
src.line("import * as cloudfront from '@aws-cdk/aws-cloudfront';");
cdkDeps.addV1Dependencies("@aws-cdk/aws-cloudfront");
}
src.line("import * as lambda from '@aws-cdk/aws-lambda';");
src.line("import { Construct } from '@aws-cdk/core';");
cdkDeps.addV1Dependencies("@aws-cdk/aws-lambda");
cdkDeps.addV1Dependencies("@aws-cdk/core");
}
else {
if (options.edgeLambda) {
src.line("import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';");
}
src.line("import * as lambda from 'aws-cdk-lib/aws-lambda';");
// Import determineLatestNodeRuntime if using NODEJS_REGIONAL_LATEST
if (runtime === LambdaRuntime.NODEJS_REGIONAL_LATEST) {
src.line("import { determineLatestNodeRuntime } from 'aws-cdk-lib/aws-lambda';");
}
src.line("import { Construct } from 'constructs';");
}
src.line();
src.line("/**");
src.line(` * Props for ${constructName}`);
src.line(" */");
if (options.edgeLambda) {
src.open(`export interface ${propsType} extends cloudfront.experimental.EdgeFunctionProps {`);
}
else if (options.singleton) {
src.open(`export interface ${propsType} extends lambda.SingletonFunctionProps {`);
}
else {
src.open(`export interface ${propsType} extends lambda.FunctionOptions {`);
}
// Add runtime prop to interface only when runtime is not explicitly set
// This allows consumers to override the default NODEJS_REGIONAL_LATEST
if (!options.runtime) {
src.line("/**");
src.line(" * The Lambda runtime to use.");
src.line(" * @default - Latest Node.js runtime available in the deployment region");
src.line(" */");
src.line("readonly runtime?: lambda.Runtime;");
}
src.close("}");
src.line();
src.line("/**");
src.line(` * An AWS Lambda function which executes ${(0, internal_1.convertToPosixPath)(basePath)}.`);
src.line(" */");
if (options.edgeLambda) {
src.open(`export class ${constructName} extends cloudfront.experimental.EdgeFunction {`);
}
else if (options.singleton) {
src.open(`export class ${constructName} extends lambda.SingletonFunction {`);
}
else {
src.open(`export class ${constructName} extends lambda.Function {`);
}
src.open(`constructor(scope: Construct, id: string, props?: ${propsType}) {`);
src.open("super(scope, id, {");
src.line(`description: '${(0, internal_1.convertToPosixPath)(entrypoint)}',`);
src.line("...props,");
if (options.singleton && options.singletonUuid) {
src.line(`uuid: ${JSON.stringify(options.singletonUuid)},`);
}
// Generate runtime code
if (runtime === LambdaRuntime.NODEJS_REGIONAL_LATEST) {
// Regional latest runtime
if (!options.runtime) {
// Default (not explicitly set) - allow consumer override
src.line("runtime: props?.runtime ?? determineLatestNodeRuntime(scope),");
}
else {
// Explicitly set - no override
src.line("runtime: determineLatestNodeRuntime(scope),");
}
}
else {
// Explicit runtime - hardcoded, no override
src.line(`runtime: new lambda.Runtime('${runtime.functionRuntime}', lambda.RuntimeFamily.NODEJS),`);
}
src.line("handler: 'index.handler',");
src.line(`code: lambda.Code.fromAsset(path.join(__dirname, '${(0, internal_1.convertToPosixPath)(relativeOutfile)}')),`);
src.close("});");
if ((options.awsSdkConnectionReuse ?? true) && !options.edgeLambda) {
src.line("this.addEnvironment('AWS_NODEJS_CONNECTION_REUSE_ENABLED', '1', { removeInEdge: true });");
}
src.close("}");
src.close("}");
this.project.logger.verbose(`${basePath}: construct "${constructName}" generated under "${constructFile}"`);
this.project.logger.verbose(`${basePath}: bundle task "${bundle.bundleTask.name}"`);
if (bundle.watchTask) {
this.project.logger.verbose(`${basePath}: bundle watch task "${bundle.watchTask.name}"`);
}
}
}
exports.LambdaFunction = LambdaFunction;
_a = JSII_RTTI_SYMBOL_1;
LambdaFunction[_a] = { fqn: "projen.awscdk.LambdaFunction", version: "0.99.34" };
/**
* The runtime for the AWS Lambda function.
*/
class LambdaRuntime {
constructor(
/**
* The Node.js runtime to use
*/
functionRuntime,
/**
* The esbuild setting to use.
*/
esbuildTarget,
/**
* Options for this runtime.
*/
options) {
this.functionRuntime = functionRuntime;
this.esbuildTarget = esbuildTarget;
this.esbuildPlatform = "node";
this.defaultExternals = options?.defaultExternals ?? ["@aws-sdk/*"];
}
}
exports.LambdaRuntime = LambdaRuntime;
_b = JSII_RTTI_SYMBOL_1;
LambdaRuntime[_b] = { fqn: "projen.awscdk.LambdaRuntime", version: "0.99.34" };
/**
* Node.js 10.x
* @deprecated Node.js 10 runtime has been deprecated on Jul 30, 2021
*/
LambdaRuntime.NODEJS_10_X = new LambdaRuntime("nodejs10.x", "node10", { defaultExternals: ["aws-sdk"] });
/**
* Node.js 12.x
* @deprecated Node.js 12 runtime has been deprecated on Mar 31, 2023
*/
LambdaRuntime.NODEJS_12_X = new LambdaRuntime("nodejs12.x", "node12", { defaultExternals: ["aws-sdk"] });
/**
* Node.js 14.x
* @deprecated Node.js 14 runtime has been deprecated on Dec 4, 2023
*/
LambdaRuntime.NODEJS_14_X = new LambdaRuntime("nodejs14.x", "node14", { defaultExternals: ["aws-sdk"] });
/**
* Node.js 16.x
* @deprecated Node.js 16 runtime has been deprecated on Jun 12, 2024
*/
LambdaRuntime.NODEJS_16_X = new LambdaRuntime("nodejs16.x", "node16", { defaultExternals: ["aws-sdk"] });
/**
* Node.js 18.x
*
* @deprecated: Node.js 18 runtime has been deprecated on Sep 1, 2025
*/
LambdaRuntime.NODEJS_18_X = new LambdaRuntime("nodejs18.x", "node18");
/**
* Node.js 20.x
*/
LambdaRuntime.NODEJS_20_X = new LambdaRuntime("nodejs20.x", "node20");
/**
* Node.js 22.x
*/
LambdaRuntime.NODEJS_22_X = new LambdaRuntime("nodejs22.x", "node22");
/**
* Node.js 24.x
*/
LambdaRuntime.NODEJS_24_X = new LambdaRuntime("nodejs24.x", "node24");
/**
* Use the latest Node.js runtime available in the deployment region.
*
* This generates code that uses `determineLatestNodeRuntime()` at CDK synthesis time,
* which dynamically selects the latest Node.js runtime available based on regional
* availability. This eliminates the need to manually update runtime versions and
* avoids EOL warnings.
*
* @default Uses determineLatestNodeRuntime() from aws-cdk-lib
*/
LambdaRuntime.NODEJS_REGIONAL_LATEST = new LambdaRuntime("NODEJS_REGIONAL_LATEST", // Marker value
"node22");
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGFtYmRhLWZ1bmN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F3c2Nkay9sYW1iZGEtZnVuY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2QkFBNkI7QUFDN0IsK0JBQThCO0FBRTlCLHlDQUtvQjtBQUNwQiw0Q0FBeUM7QUFDekMsOENBQWlFO0FBRWpFLGdEQUE0QztBQUU1QyxrQ0FBaUQ7QUE0R2pEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBQ0gsTUFBYSxjQUFlLFNBQVEscUJBQVM7SUFDM0M7Ozs7O09BS0c7SUFDSCxZQUFZLE9BQWdCLEVBQUUsT0FBOEI7UUFDMUQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWYsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQztRQUNoQyxNQUFNLE9BQU8sR0FBRyxvQkFBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNwQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixNQUFNLElBQUksS0FBSyxDQUNiLG1FQUFtRSxDQUNwRSxDQUFDO1FBQ0osQ0FBQztRQUVELHNGQUFzRjtRQUN0RixNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxJQUFJLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQztRQUV4RSxNQUFNLFVBQVUsR0FBRyxJQUFBLDZCQUFzQixFQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUU5RCwwRUFBMEU7UUFDMUUsa0JBQWtCO1FBQ2xCLE1BQU0sTUFBTSxHQUFHLG1CQUFNLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2xDLE1BQU0sRUFBRSxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFakMsSUFDRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsZ0NBQXFCLENBQUM7WUFDM0MsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLHFDQUEwQixDQUFDO1lBQ2hELENBQUMs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O0FBQ29CLG9DQUFzQixHQUFHLElBQUksYUFBYSxDQUMvRCx3QkFBd0IsRUFBRSxlQUFlO0FBQ3pDLFFBQVEsQ0FDVCxBQUg0QyxDQUczQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IHBhc2NhbCB9IGZyb20gXCJjYXNlXCI7XG5pbXBvcnQgeyBBd3NDZGtEZXBzIH0gZnJvbSBcIi4vYXdzY2RrLWRlcHNcIjtcbmltcG9ydCB7XG4gIGNvbnZlcnRUb1Bvc2l4UGF0aCxcbiAgVFlQRVNDUklQVF9FREdFX0xBTUJEQV9FWFQsXG4gIFRZUEVTQ1JJUFRfTEFNQkRBX0VYVCxcbiAgVFlQRVNDUklQVF9TSU5HTEVUT05fTEFNQkRBX0VYVCxcbn0gZnJvbSBcIi4vaW50ZXJuYWxcIjtcbmltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gXCIuLi9jb21wb25lbnRcIjtcbmltcG9ydCB7IEJ1bmRsZXIsIEJ1bmRsaW5nT3B0aW9ucywgRXNsaW50IH0gZnJvbSBcIi4uL2phdmFzY3JpcHRcIjtcbmltcG9ydCB7IFByb2plY3QgfSBmcm9tIFwiLi4vcHJvamVjdFwiO1xuaW1wb3J0IHsgU291cmNlQ29kZSB9IGZyb20gXCIuLi9zb3VyY2UtY29kZVwiO1xuaW1wb3J0IHsgVHlwZVNjcmlwdFByb2plY3QgfSBmcm9tIFwiLi4vdHlwZXNjcmlwdFwiO1xuaW1wb3J0IHsgbm9ybWFsaXplUGVyc2lzdGVkUGF0aCB9IGZyb20gXCIuLi91dGlsXCI7XG5cbi8qKlxuICogQ29tbW9uIG9wdGlvbnMgZm9yIGBMYW1iZGFGdW5jdGlvbmAuIEFwcGxpZXMgdG8gYWxsIGZ1bmN0aW9ucyBpblxuICogYXV0by1kaXNjb3ZlcnkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGFtYmRhRnVuY3Rpb25Db21tb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBub2RlLmpzIHZlcnNpb24gdG8gdGFyZ2V0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBMYW1iZGFSdW50aW1lLk5PREVKU19SRUdJT05BTF9MQVRFU1QgLSBVc2VzIHRoZSBsYXRlc3QgTm9kZS5qcyBydW50aW1lXG4gICAqIGF2YWlsYWJsZSBpbiB0aGUgZGVwbG95bWVudCByZWdpb24sIGRldGVybWluZWQgYXQgQ0RLIHN5bnRoZXNpcyB0aW1lLlxuICAgKi9cbiAgcmVhZG9ubHkgcnVudGltZT86IExhbWJkYVJ1bnRpbWU7XG5cbiAgLyoqXG4gICAqIEJ1bmRsaW5nIG9wdGlvbnMgZm9yIHRoaXMgQVdTIExhbWJkYSBmdW5jdGlvbi5cbiAgICpcbiAgICogSWYgbm90IHNwZWNpZmllZCB0aGUgZGVmYXVsdCBidW5kbGluZyBvcHRpb25zIHNwZWNpZmllZCBmb3IgdGhlIHByb2plY3RcbiAgICogYEJ1bmRsZXJgIGluc3RhbmNlIHdpbGwgYmUgdXNlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBkZWZhdWx0c1xuICAgKi9cbiAgcmVhZG9ubHkgYnVuZGxpbmdPcHRpb25zPzogQnVuZGxpbmdPcHRpb25zO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGF1dG9tYXRpY2FsbHkgcmV1c2UgVENQIGNvbm5lY3Rpb25zIHdoZW4gd29ya2luZyB3aXRoIHRoZSBBV1NcbiAgICogU0RLIGZvciBKYXZhU2NyaXB0LlxuICAgKlxuICAgKiBUaGlzIHNldHMgdGhlIGBBV1NfTk9ERUpTX0NPTk5FQ1RJT05fUkVVU0VfRU5BQkxFRGAgZW52aXJvbm1lbnQgdmFyaWFibGVcbiAgICogdG8gYDFgLlxuICAgKlxuICAgKiBOb3QgYXBwbGljYWJsZSB3aGVuIGBlZGdlTGFtYmRhYCBpcyBzZXQgdG8gYHRydWVgIGJlY2F1c2UgZW52aXJvbm1lbnRcbiAgICogdmFyaWFibGVzIGFyZSBub3Qgc3VwcG9ydGVkIGluIExhbWJkYUBFZGdlLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZGstZm9yLWphdmFzY3JpcHQvdjIvZGV2ZWxvcGVyLWd1aWRlL25vZGUtcmV1c2luZy1jb25uZWN0aW9ucy5odG1sXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGF3c1Nka0Nvbm5lY3Rpb25SZXVzZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gY3JlYXRlIGEgYGNsb3VkZnJvbnQuZXhwZXJpbWVudGFsLkVkZ2VGdW5jdGlvbmAgaW5zdGVhZFxuICAgKiBvZiBhIGBsYW1iZGEuRnVuY3Rpb25gLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZWRnZUxhbWJkYT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gY3JlYXRlIGEgYGxhbWJkYS5TaW5nbGV0b25GdW5jdGlvbmAgaW5zdGVhZCBvZiBhXG4gICAqIGBsYW1iZGEuRnVuY3Rpb25gLlxuICAgKlxuICAgKiBOb3QgY29tcGF0aWJsZSB3aXRoIGBlZGdlTGFtYmRhYC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHNpbmdsZXRvbj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFVVSUQgdG8gdXNlIGZvciBzaW5nbGV0b24gbGFtYmRhIHVuaXF1ZW5lc3MuXG4gICAqXG4gICAqIFdoZW4gc3BlY2lmaWVkLCB0aGUgZ2VuZXJhdGVkIHNpbmdsZXRvbiBjb25zdHJ1Y3QgaGFyZGNvZGVzIHRoaXMgVVVJRC5cbiAgICpcbiAgICogT25seSB2YWxpZCB3aGVuIGBzaW5nbGV0b25gIGlzIHNldCB0byBgdHJ1ZWAuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gVVVJRCBpcyBoYXJkY29kZWQgYW5kIGNvbnN1bWVycyBtdXN0IHByb3ZpZGUgb25lXG4gICAqL1xuICByZWFkb25seSBzaW5nbGV0b25VdWlkPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGBGdW5jdGlvbmAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGFtYmRhRnVuY3Rpb25PcHRpb25zIGV4dGVuZHMgTGFtYmRhRnVuY3Rpb25Db21tb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIEEgcGF0aCBmcm9tIHRoZSBwcm9qZWN0IHJvb3QgZGlyZWN0b3J5IHRvIGEgVHlwZVNjcmlwdCBmaWxlIHdoaWNoIGNvbnRhaW5zXG4gICAqIHRoZSBBV1MgTGFtYmRhIGhhbmRsZXIgZW50cnlwb2ludCAoZXhwb3J0cyBhIGBoYW5kbGVyYCBmdW5jdGlvbikuXG4gICAqXG4gICAqIFRoaXMgaXMgcmVsYXRpdmUgdG8gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoZSBwcm9qZWN0LlxuICAgKlxuICAgKiBAZXhhbXBsZSBcInNyYy9zdWJkaXIvZm9vLmxhbWJkYS50c1wiXG4gICAqL1xuICByZWFkb25seSBlbnRyeXBvaW50OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBnZW5lcmF0ZWQgVHlwZVNjcmlwdCBzb3VyY2UgZmlsZS4gVGhpcyBmaWxlIHNob3VsZCBhbHNvIGJlXG4gICAqIHVuZGVyIHRoZSBzb3VyY2UgdHJlZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBUaGUgbmFtZSBvZiB0aGUgZW50cnlwb2ludCBmaWxlLCB3aXRoIHRoZSBgLWZ1bmN0aW9uLnRzYCBzdWZmaXhcbiAgICogaW5zdGVhZCBvZiBgLmxhbWJkYS50c2AuXG4gICAqL1xuICByZWFkb25seSBjb25zdHJ1Y3RGaWxlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgZ2VuZXJhdGVkIGBsYW1iZGEuRnVuY3Rpb25gIHN1YmNsYXNzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEEgcGFzY2FsIGNhc2VkIHZlcnNpb24gb2YgdGhlIG5hbWUgb2YgdGhlIGVudHJ5cG9pbnQgZmlsZSwgd2l0aFxuICAgKiB0aGUgZXh0ZW5zaW9uIGBGdW5jdGlvbmAgKGUuZy4gYFJlc2l6ZUltYWdlRnVuY3Rpb25gKS5cbiAgICovXG4gIHJlYWRvbmx5IGNvbnN0cnVjdE5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEFXUyBDREsgZGVwZW5kZW5jeSBtYW5hZ2VyLlxuICAgKi9cbiAgcmVhZG9ubHkgY2RrRGVwczogQXdzQ2RrRGVwcztcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBwcmUtYnVuZGxlZCBBV1MgTGFtYmRhIGZ1bmN0aW9uIGNvbnN0cnVjdCBmcm9tIGhhbmRsZXIgY29kZS5cbiAqXG4gKiBUbyB1c2UgdGhpcywgY3JlYXRlIGFuIEFXUyBMYW1iZGEgaGFuZGxlciBmaWxlIHVuZGVyIHlvdXIgc291cmNlIHRyZWUgd2l0aFxuICogdGhlIGAubGFtYmRhLnRzYCBleHRlbnNpb24gYW5kIGFkZCBhIGBMYW1iZGFGdW5jdGlvbmAgY29tcG9uZW50IHRvIHlvdXJcbiAqIHR5cGVzY3JpcHQgcHJvamVjdCBwb2ludGluZyB0byB0aGlzIGVudHJ5cG9pbnQuXG4gKlxuICogVGhpcyB3aWxsIGFkZCBhIHRhc2sgdG8geW91ciBcImNvbXBpbGVcIiBzdGVwIHdoaWNoIHdpbGwgdXNlIGBlc2J1aWxkYCB0b1xuICogYnVuZGxlIHRoZSBoYW5kbGVyIGNvZGUgaW50byB0aGUgYnVpbGQgZGlyZWN0b3J5LiBJdCB3aWxsIGFsc28gZ2VuZXJhdGUgYVxuICogZmlsZSBgc3JjL2Zvby1mdW5jdGlvbi50c2Agd2l0aCBhIGN1c3RvbSBBV1MgY29uc3RydWN0IGNhbGxlZCBgRm9vRnVuY3Rpb25gXG4gKiB3aGljaCBleHRlbmRzIGBAYXdzLWNkay9hd3MtbGFtYmRhLkZ1bmN0aW9uYCB3aGljaCBpcyBib3VuZCB0byB0aGUgYnVuZGxlZFxuICogaGFuZGxlIHRocm91Z2ggYW4gYXNzZXQuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBuZXcgTGFtYmRhRnVuY3Rpb24obXlQcm9qZWN0LCB7XG4gKiAgIHNyY2RpcjogbXlQcm9qZWN0LnNyY2RpcixcbiAqICAgZW50cnlwb2ludDogJ3NyYy9mb28ubGFtYmRhLnRzJyxcbiAqIH0pO1xuICovXG5leHBvcnQgY2xhc3MgTGFtYmRhRnVuY3Rpb24gZXh0ZW5kcyBDb21wb25lbnQge1xuICAvKipcbiAgICogRGVmaW5lcyBhIHByZS1idW5kbGVkIEFXUyBMYW1iZGEgZnVuY3Rpb24gY29uc3RydWN0IGZyb20gaGFuZGxlciBjb2RlLlxuICAgKlxuICAgKiBAcGFyYW0gcHJvamVjdCBUaGUgcHJvamVjdCB0byB1c2VcbiAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9uc1xuICAgKi9cbiAgY29uc3RydWN0b3IocHJvamVjdDogUHJvamVjdCwgb3B0aW9uczogTGFtYmRhRnVuY3Rpb25PcHRpb25zKSB7XG4gICAgc3VwZXIocHJvamVjdCk7XG5cbiAgICBjb25zdCBjZGtEZXBzID0gb3B0aW9ucy5jZGtEZXBzO1xuICAgIGNvbnN0IGJ1bmRsZXIgPSBCdW5kbGVyLm9mKHByb2plY3QpO1xuICAgIGlmICghYnVuZGxlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIk5vIGJ1bmRsZXIgZm91bmQuIFBsZWFzZSBhZGQgYSBCdW5kbGVyIGNvbXBvbmVudCB0byB5b3VyIHByb2plY3QuXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFVzZSBOT0RFSlNfUkVHSU9OQUxfTEFURVNUIGFzIGRlZmF1bHQsIHdoaWNoIGdlbmVyYXRlcyBkZXRlcm1pbmVMYXRlc3ROb2RlUnVudGltZSgpXG4gICAgY29uc3QgcnVudGltZSA9IG9wdGlvbnMucnVudGltZSA/PyBMYW1iZGFSdW50aW1lLk5PREVKU19SRUdJT05BTF9MQVRFU1Q7XG5cbiAgICBjb25zdCBlbnRyeXBvaW50ID0gbm9ybWFsaXplUGVyc2lzdGVkUGF0aChvcHRpb25zLmVudHJ5cG9pbnQpO1xuXG4gICAgLy8gYWxsb3cgTGFtYmRhIGhhbmRsZXIgY29kZSB0byBpbXBvcnQgZGV2LWRlcHMgc2luY2UgdGhleSBhcmUgb25seSBuZWVkZWRcbiAgICAvLyBkdXJpbmcgYnVuZGxpbmdcbiAgICBjb25zdCBlc2xpbnQgPSBFc2xpbnQub2YocHJvamVjdCk7XG4gICAgZXNsaW50Py5hbGxvd0RldkRlcHMoZW50cnlwb2ludCk7XG5cbiAgICBpZiAoXG4gICAgICAhZW50cnlwb2ludC5lbmRzV2l0aChUWVBFU0NSSVBUX0xBTUJEQV9FWFQpICYmXG4gICAgICAhZW50cnlwb2ludC5lbmRzV2l0aChUWVBFU0NSSVBUX0VER0VfTEFNQkRBX0VYVCkgJiZcbiAgICAgICFlbnRyeXBvaW50LmVuZHNXaXRoKFRZUEVTQ1JJUFRfU0lOR0xFVE9OX0xBTUJEQV9FWFQpXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGAke2VudHJ5cG9pbnR9IG11c3QgaGF2ZSBhICR7VFlQRVNDUklQVF9MQU1CREFfRVhUfSwgJHtUWVBFU0NSSVBUX0VER0VfTEFNQkRBX0VYVH0sIG9yICR7VFlQRVNDUklQVF9TSU5HTEVUT05fTEFNQkRBX0VYVH0gZXh0ZW5zaW9uYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuZWRnZUxhbWJkYSAmJiBvcHRpb25zLnNpbmdsZXRvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwic2luZ2xldG9uIGNhbm5vdCBiZSB1c2VkIHdpdGggZWRnZUxhbWJkYVwiKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5zaW5nbGV0b25VdWlkICYmICFvcHRpb25zLnNpbmdsZXRvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwic2luZ2xldG9uVXVpZCBjYW4gb25seSBiZSB1c2VkIHdpdGggc2luZ2xldG9uXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHNvdXJjZUV4dGVuc2lvbiA9IGVudHJ5cG9pbnQuZW5kc1dpdGgoVFlQRVNDUklQVF9FREdFX0xBTUJEQV9FWFQpXG4gICAgICA/IFRZUEVTQ1JJUFRfRURHRV9MQU1CREFfRVhUXG4gICAgICA6IGVudHJ5cG9pbnQuZW5kc1dpdGgoVFlQRVNDUklQVF9TSU5HTEVUT05fTEFNQkRBX0VYVClcbiAgICAgICAgPyBUWVBFU0NSSVBUX1NJTkdMRVRPTl9MQU1CREFfRVhUXG4gICAgICAgIDogVFlQRVNDUklQVF9MQU1CREFfRVhUO1xuXG4gICAgY29uc3QgYmFzZVBhdGggPSBwYXRoLnBvc2l4LmpvaW4oXG4gICAgICBwYXRoLmRpcm5hbWUoZW50cnlwb2ludCksXG4gICAgICBwYXRoLmJhc2VuYW1lKGVudHJ5cG9pbnQsIHNvdXJjZUV4dGVuc2lvbiksXG4gICAgKTtcbiAgICBjb25zdCBjb25zdHJ1Y3RGaWxlID0gb3B0aW9ucy5jb25zdHJ1Y3RGaWxlID8/IGAke2Jhc2VQYXRofS1mdW5jdGlvbi50c2A7XG5cbiAgICBpZiAocGF0aC5leHRuYW1lKGNvbnN0cnVjdEZpbGUpICE9PSBcIi50c1wiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBDb25zdHJ1Y3QgZmlsZSBuYW1lIFwiJHtjb25zdHJ1Y3RGaWxlfVwiIG11c3QgaGF2ZSBhIC50cyBleHRlbnNpb25gLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyB0eXBlIG5hbWVzXG4gICAgY29uc3QgY29uc3RydWN0TmFtZSA9XG4gICAgICBvcHRpb25zLmNvbnN0cnVjdE5hbWUgPz8gcGFzY2FsKHBhdGguYmFzZW5hbWUoYmFzZVBhdGgpKSArIFwiRnVuY3Rpb25cIjtcbiAgICBjb25zdCBwcm9wc1R5cGUgPSBgJHtjb25zdHJ1Y3ROYW1lfVByb3BzYDtcblxuICAgIGNvbnN0IGJ1bmRsZSA9IGJ1bmRsZXIuYWRkQnVuZGxlKGVudHJ5cG9pbnQsIHtcbiAgICAgIHRhcmdldDogcnVudGltZS5lc2J1aWxkVGFyZ2V0LFxuICAgICAgcGxhdGZvcm06IHJ1bnRpbWUuZXNidWlsZFBsYXRmb3JtLFxuICAgICAgZXh0ZXJuYWxzOiBydW50aW1lLmRlZmF1bHRFeHRlcm5hbHMsXG4gICAgICAuLi5vcHRpb25zLmJ1bmRsaW5nT3B0aW9ucyxcbiAgICAgIHRzY29uZmlnUGF0aDogKHByb2plY3QgYXMgVHlwZVNjcmlwdFByb2plY3QpPy50c2NvbmZpZ0Rldj8uZmlsZU5hbWUsXG4gICAgfSk7XG5cbiAgICAvLyBjYWxjdWxhdGUgdGhlIHJlbGF0aXZlIHBhdGggYmV0d2VlbiB0aGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgdGhlXG4gICAgLy8gZ2VuZXJhdGVkIGNvbnN0cnVjdCBzb3VyY2UgZmlsZSB0byB0aGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgdGhlIGJ1bmRsZVxuICAgIC8vIGluZGV4LmpzIGJ5IHJlc29sdmluZyB0aGVtIGFzIGFic29sdXRlIHBhdGhzIGZpcnN0LlxuICAgIC8vIGUuZzpcbiAgICAvLyAgLSBvdXRmaWxlQWJzID0+IGAvcHJvamVjdC1vdXRkaXIvYXNzZXRzL2Zvby9iYXIvYmF6L2Zvby1mdW5jdGlvbi9pbmRleC5qc2BcbiAgICAvLyAgLSBjb25zdHJ1Y3RBYnMgPT4gYC9wcm9qZWN0LW91dGRpci9zcmMvZm9vL2Jhci9iYXovZm9vLWZ1bmN0aW9uLnRzYFxuICAgIGNvbnN0IG91dGZpbGVBYnMgPSBwYXRoLmpvaW4ocHJvamVjdC5vdXRkaXIsIGJ1bmRsZS5vdXRmaWxlKTtcbiAgICBjb25zdCBjb25zdHJ1Y3RBYnMgPSBwYXRoLmpvaW4ocHJvamVjdC5vdXRkaXIsIGNvbnN0cnVjdEZpbGUpO1xuICAgIGNvbnN0IHJlbGF0aXZlT3V0ZmlsZSA9IHBhdGgucmVsYXRpdmUoXG4gICAgICBwYXRoLmRpcm5hbWUoY29uc3RydWN0QWJzKSxcbiAgICAgIHBhdGguZGlybmFtZShvdXRmaWxlQWJzKSxcbiAgICApO1xuXG4gICAgY29uc3Qgc3JjID0gbmV3IFNvdXJjZUNvZGUocHJvamVjdCwgY29uc3RydWN0RmlsZSk7XG4gICAgaWYgKHNyYy5tYXJrZXIpIHtcbiAgICAgIHNyYy5saW5lKGAvLyAke3NyYy5tYXJrZXJ9YCk7XG4gICAgfVxuICAgIHNyYy5saW5lKFwiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcIik7XG5cbiAgICBpZiAoY2RrRGVwcy5jZGtNYWpvclZlcnNpb24gPT09IDEpIHtcbiAgICAgIGlmIChvcHRpb25zLmVkZ2VMYW1iZGEpIHtcbiAgICAgICAgc3JjLmxpbmUoXCJpbXBvcnQgKiBhcyBjbG91ZGZyb250IGZyb20gJ0Bhd3MtY2RrL2F3cy1jbG91ZGZyb250JztcIik7XG4gICAgICAgIGNka0RlcHMuYWRkVjFEZXBlbmRlbmNpZXMoXCJAYXdzLWNkay9hd3MtY2xvdWRmcm9udFwiKTtcbiAgICAgIH1cbiAgICAgIHNyYy5saW5lKFwiaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ0Bhd3MtY2RrL2F3cy1sYW1iZGEnO1wiKTtcbiAgICAgIHNyYy5saW5lKFwiaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnQGF3cy1jZGsvY29yZSc7XCIpO1xuICAgICAgY2RrRGVwcy5hZGRWMURlcGVuZGVuY2llcyhcIkBhd3MtY2RrL2F3cy1sYW1iZGFcIik7XG4gICAgICBjZGtEZXBzLmFkZFYxRGVwZW5kZW5jaWVzKFwiQGF3cy1jZGsvY29yZVwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKG9wdGlvbnMuZWRnZUxhbWJkYSkge1xuICAgICAgICBzcmMubGluZShcImltcG9ydCAqIGFzIGNsb3VkZnJvbnQgZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnQnO1wiKTtcbiAgICAgIH1cbiAgICAgIHNyYy5saW5lKFwiaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1wiKTtcbiAgICAgIC8vIEltcG9ydCBkZXRlcm1pbmVMYXRlc3ROb2RlUnVudGltZSBpZiB1c2luZyBOT0RFSlNfUkVHSU9OQUxfTEFURVNUXG4gICAgICBpZiAocnVudGltZSA9PT0gTGFtYmRhUnVudGltZS5OT0RFSlNfUkVHSU9OQUxfTEFURVNUKSB7XG4gICAgICAgIHNyYy5saW5lKFxuICAgICAgICAgIFwiaW1wb3J0IHsgZGV0ZXJtaW5lTGF0ZXN0Tm9kZVJ1bnRpbWUgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcIixcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHNyYy5saW5lKFwiaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XCIpO1xuICAgIH1cblxuICAgIHNyYy5saW5lKCk7XG4gICAgc3JjLmxpbmUoXCIvKipcIik7XG4gICAgc3JjLmxpbmUoYCAqIFByb3BzIGZvciAke2NvbnN0cnVjdE5hbWV9YCk7XG4gICAgc3JjLmxpbmUoXCIgKi9cIik7XG4gICAgaWYgKG9wdGlvbnMuZWRnZUxhbWJkYSkge1xuICAgICAgc3JjLm9wZW4oXG4gICAgICAgIGBleHBvcnQgaW50ZXJmYWNlICR7cHJvcHNUeXBlfSBleHRlbmRzIGNsb3VkZnJvbnQuZXhwZXJpbWVudGFsLkVkZ2VGdW5jdGlvblByb3BzIHtgLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMuc2luZ2xldG9uKSB7XG4gICAgICBzcmMub3BlbihcbiAgICAgICAgYGV4cG9ydCBpbnRlcmZhY2UgJHtwcm9wc1R5cGV9IGV4dGVuZHMgbGFtYmRhLlNpbmdsZXRvbkZ1bmN0aW9uUHJvcHMge2AsXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBzcmMub3BlbihcbiAgICAgICAgYGV4cG9ydCBpbnRlcmZhY2UgJHtwcm9wc1R5cGV9IGV4dGVuZHMgbGFtYmRhLkZ1bmN0aW9uT3B0aW9ucyB7YCxcbiAgICAgICk7XG4gICAgfVxuICAgIC8vIEFkZCBydW50aW1lIHByb3AgdG8gaW50ZXJmYWNlIG9ubHkgd2hlbiBydW50aW1lIGlzIG5vdCBleHBsaWNpdGx5IHNldFxuICAgIC8vIFRoaXMgYWxsb3dzIGNvbnN1bWVycyB0byBvdmVycmlkZSB0aGUgZGVmYXVsdCBOT0RFSlNfUkVHSU9OQUxfTEFURVNUXG4gICAgaWYgKCFvcHRpb25zLnJ1bnRpbWUpIHtcbiAgICAgIHNyYy5saW5lKFwiLyoqXCIpO1xuICAgICAgc3JjLmxpbmUoXCIgKiBUaGUgTGFtYmRhIHJ1bnRpbWUgdG8gdXNlLlwiKTtcbiAgICAgIHNyYy5saW5lKFxuICAgICAgICBcIiAqIEBkZWZhdWx0IC0gTGF0ZXN0IE5vZGUuanMgcnVudGltZSBhdmFpbGFibGUgaW4gdGhlIGRlcGxveW1lbnQgcmVnaW9uXCIsXG4gICAgICApO1xuICAgICAgc3JjLmxpbmUoXCIgKi9cIik7XG4gICAgICBzcmMubGluZShcInJlYWRvbmx5IHJ1bnRpbWU/OiBsYW1iZGEuUnVudGltZTtcIik7XG4gICAgfVxuICAgIHNyYy5jbG9zZShcIn1cIik7XG4gICAgc3JjLmxpbmUoKTtcbiAgICBzcmMubGluZShcIi8qKlwiKTtcbiAgICBzcmMubGluZShcbiAgICAgIGAgKiBBbiBBV1MgTGFtYmRhIGZ1bmN0aW9uIHdoaWNoIGV4ZWN1dGVzICR7Y29udmVydFRvUG9zaXhQYXRoKFxuICAgICAgICBiYXNlUGF0aCxcbiAgICAgICl9LmAsXG4gICAgKTtcbiAgICBzcmMubGluZShcIiAqL1wiKTtcbiAgICBpZiAob3B0aW9ucy5lZGdlTGFtYmRhKSB7XG4gICAgICBzcmMub3BlbihcbiAgICAgICAgYGV4cG9ydCBjbGFzcyAke2NvbnN0cnVjdE5hbWV9IGV4dGVuZHMgY2xvdWRmcm9udC5leHBlcmltZW50YWwuRWRnZUZ1bmN0aW9uIHtgLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMuc2luZ2xldG9uKSB7XG4gICAgICBzcmMub3BlbihcbiAgICAgICAgYGV4cG9ydCBjbGFzcyAke2NvbnN0cnVjdE5hbWV9IGV4dGVuZHMgbGFtYmRhLlNpbmdsZXRvbkZ1bmN0aW9uIHtgLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3JjLm9wZW4oYGV4cG9ydCBjbGFzcyAke2NvbnN0cnVjdE5hbWV9IGV4dGVuZHMgbGFtYmRhLkZ1bmN0aW9uIHtgKTtcbiAgICB9XG4gICAgc3JjLm9wZW4oXG4gICAgICBgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM/OiAke3Byb3BzVHlwZX0pIHtgLFxuICAgICk7XG4gICAgc3JjLm9wZW4oXCJzdXBlcihzY29wZSwgaWQsIHtcIik7XG4gICAgc3JjLmxpbmUoYGRlc2NyaXB0aW9uOiAnJHtjb252ZXJ0VG9Qb3NpeFBhdGgoZW50cnlwb2ludCl9JyxgKTtcbiAgICBzcmMubGluZShcIi4uLnByb3BzLFwiKTtcbiAgICBpZiAob3B0aW9ucy5zaW5nbGV0b24gJiYgb3B0aW9ucy5zaW5nbGV0b25VdWlkKSB7XG4gICAgICBzcmMubGluZShgdXVpZDogJHtKU09OLnN0cmluZ2lmeShvcHRpb25zLnNpbmdsZXRvblV1aWQpfSxgKTtcbiAgICB9XG5cbiAgICAvLyBHZW5lcmF0ZSBydW50aW1lIGNvZGVcbiAgICBpZiAocnVudGltZSA9PT0gTGFtYmRhUnVudGltZS5OT0RFSlNfUkVHSU9OQUxfTEFURVNUKSB7XG4gICAgICAvLyBSZWdpb25hbCBsYXRlc3QgcnVudGltZVxuICAgICAgaWYgKCFvcHRpb25zLnJ1bnRpbWUpIHtcbiAgICAgICAgLy8gRGVmYXVsdCAobm90IGV4cGxpY2l0bHkgc2V0KSAtIGFsbG93IGNvbnN1bWVyIG92ZXJyaWRlXG4gICAgICAgIHNyYy5saW5lKFxuICAgICAgICAgIFwicnVudGltZTogcHJvcHM/LnJ1bnRpbWUgPz8gZGV0ZXJtaW5lTGF0ZXN0Tm9kZVJ1bnRpbWUoc2NvcGUpLFwiLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRXhwbGljaXRseSBzZXQgLSBubyBvdmVycmlkZVxuICAgICAgICBzcmMubGluZShcInJ1bnRpbWU6IGRldGVybWluZUxhdGVzdE5vZGVSdW50aW1lKHNjb3BlKSxcIik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEV4cGxpY2l0IHJ1bnRpbWUgLSBoYXJkY29kZWQsIG5vIG92ZXJyaWRlXG4gICAgICBzcmMubGluZShcbiAgICAgICAgYHJ1bnRpbWU6IG5ldyBsYW1iZGEuUnVudGltZSgnJHtydW50aW1lLmZ1bmN0aW9uUnVudGltZX0nLCBsYW1iZGEuUnVudGltZUZhbWlseS5OT0RFSlMpLGAsXG4gICAgICApO1xuICAgIH1cblxuICAgIHNyYy5saW5lKFwiaGFuZGxlcjogJ2luZGV4LmhhbmRsZXInLFwiKTtcbiAgICBzcmMubGluZShcbiAgICAgIGBjb2RlOiBsYW1iZGEuQ29kZS5mcm9tQXNzZXQocGF0aC5qb2luKF9fZGlybmFtZSwgJyR7Y29udmVydFRvUG9zaXhQYXRoKFxuICAgICAgICByZWxhdGl2ZU91dGZpbGUsXG4gICAgICApfScpKSxgLFxuICAgICk7XG4gICAgc3JjLmNsb3NlKFwifSk7XCIpO1xuICAgIGlmICgob3B0aW9ucy5hd3NTZGtDb25uZWN0aW9uUmV1c2UgPz8gdHJ1ZSkgJiYgIW9wdGlvbnMuZWRnZUxhbWJkYSkge1xuICAgICAgc3JjLmxpbmUoXG4gICAgICAgIFwidGhpcy5hZGRFbnZpcm9ubWVudCgnQVdTX05PREVKU19DT05ORUNUSU9OX1JFVVNFX0VOQUJMRUQnLCAnMScsIHsgcmVtb3ZlSW5FZGdlOiB0cnVlIH0pO1wiLFxuICAgICAgKTtcbiAgICB9XG4gICAgc3JjLmNsb3NlKFwifVwiKTtcbiAgICBzcmMuY2xvc2UoXCJ9XCIpO1xuXG4gICAgdGhpcy5wcm9qZWN0LmxvZ2dlci52ZXJib3NlKFxuICAgICAgYCR7YmFzZVBhdGh9OiBjb25zdHJ1Y3QgXCIke2NvbnN0cnVjdE5hbWV9XCIgZ2VuZXJhdGVkIHVuZGVyIFwiJHtjb25zdHJ1Y3RGaWxlfVwiYCxcbiAgICApO1xuICAgIHRoaXMucHJvamVjdC5sb2dnZXIudmVyYm9zZShcbiAgICAgIGAke2Jhc2VQYXRofTogYnVuZGxlIHRhc2sgXCIke2J1bmRsZS5idW5kbGVUYXNrLm5hbWV9XCJgLFxuICAgICk7XG4gICAgaWYgKGJ1bmRsZS53YXRjaFRhc2spIHtcbiAgICAgIHRoaXMucHJvamVjdC5sb2dnZXIudmVyYm9zZShcbiAgICAgICAgYCR7YmFzZVBhdGh9OiBidW5kbGUgd2F0Y2ggdGFzayBcIiR7YnVuZGxlLndhdGNoVGFzay5uYW1lfVwiYCxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgdGhlIEFXUyBMYW1iZGEgZnVuY3Rpb24gcnVudGltZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIExhbWJkYVJ1bnRpbWVPcHRpb25zIHtcbiAgLyoqXG4gICAqIFBhY2thZ2VzIHRoYXQgYXJlIGNvbnNpZGVyZWQgZXh0ZXJuYWxzIGJ5IGRlZmF1bHQgd2hlbiBidW5kbGluZ1xuICAgKlxuICAgKiBAZGVmYXVsdCBbJ0Bhd3Mtc2RrLyonXVxuICAgKi9cbiAgcmVhZG9ubHkgZGVmYXVsdEV4dGVybmFscz86IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFRoZSBydW50aW1lIGZvciB0aGUgQVdTIExhbWJkYSBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIExhbWJkYVJ1bnRpbWUge1xuICAvKipcbiAgICogTm9kZS5qcyAxMC54XG4gICAqIEBkZXByZWNhdGVkIE5vZGUuanMgMTAgcnVudGltZSBoYXMgYmVlbiBkZXByZWNhdGVkIG9uIEp1bCAzMCwgMjAyMVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBOT0RFSlNfMTBfWCA9IG5ldyBMYW1iZGFSdW50aW1lKFxuICAgIFwibm9kZWpzMTAueFwiLFxuICAgIFwibm9kZTEwXCIsXG4gICAgeyBkZWZhdWx0RXh0ZXJuYWxzOiBbXCJhd3Mtc2RrXCJdIH0sXG4gICk7XG5cbiAgLyoqXG4gICAqIE5vZGUuanMgMTIueFxuICAgKiBAZGVwcmVjYXRlZCBOb2RlLmpzIDEyIHJ1bnRpbWUgaGFzIGJlZW4gZGVwcmVjYXRlZCBvbiBNYXIgMzEsIDIwMjNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgTk9ERUpTXzEyX1ggPSBuZXcgTGFtYmRhUnVudGltZShcbiAgICBcIm5vZGVqczEyLnhcIixcbiAgICBcIm5vZGUxMlwiLFxuICAgIHsgZGVmYXVsdEV4dGVybmFsczogW1wiYXdzLXNka1wiXSB9LFxuICApO1xuXG4gIC8qKlxuICAgKiBOb2RlLmpzIDE0LnhcbiAgICogQGRlcHJlY2F0ZWQgTm9kZS5qcyAxNCBydW50aW1lIGhhcyBiZWVuIGRlcHJlY2F0ZWQgb24gRGVjIDQsIDIwMjNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgTk9ERUpTXzE0X1ggPSBuZXcgTGFtYmRhUnVudGltZShcbiAgICBcIm5vZGVqczE0LnhcIixcbiAgICBcIm5vZGUxNFwiLFxuICAgIHsgZGVmYXVsdEV4dGVybmFsczogW1wiYXdzLXNka1wiXSB9LFxuICApO1xuXG4gIC8qKlxuICAgKiBOb2RlLmpzIDE2LnhcbiAgICogQGRlcHJlY2F0ZWQgTm9kZS5qcyAxNiBydW50aW1lIGhhcyBiZWVuIGRlcHJlY2F0ZWQgb24gSnVuIDEyLCAyMDI0XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IE5PREVKU18xNl9YID0gbmV3IExhbWJkYVJ1bnRpbWUoXG4gICAgXCJub2RlanMxNi54XCIsXG4gICAgXCJub2RlMTZcIixcbiAgICB7IGRlZmF1bHRFeHRlcm5hbHM6IFtcImF3cy1zZGtcIl0gfSxcbiAgKTtcblxuICAvKipcbiAgICogTm9kZS5qcyAxOC54XG4gICAqXG4gICAqIEBkZXByZWNhdGVkOiBOb2RlLmpzIDE4IHJ1bnRpbWUgaGFzIGJlZW4gZGVwcmVjYXRlZCBvbiBTZXAgMSwgMjAyNVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBOT0RFSlNfMThfWCA9IG5ldyBMYW1iZGFSdW50aW1lKFxuICAgIFwibm9kZWpzMTgueFwiLFxuICAgIFwibm9kZTE4XCIsXG4gICk7XG5cbiAgLyoqXG4gICAqIE5vZGUuanMgMjAueFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBOT0RFSlNfMjBfWCA9IG5ldyBMYW1iZGFSdW50aW1lKFxuICAgIFwibm9kZWpzMjAueFwiLFxuICAgIFwibm9kZTIwXCIsXG4gICk7XG5cbiAgLyoqXG4gICAqIE5vZGUuanMgMjIueFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBOT0RFSlNfMjJfWCA9IG5ldyBMYW1iZGFSdW50aW1lKFxuICAgIFwibm9kZWpzMjIueFwiLFxuICAgIFwibm9kZTIyXCIsXG4gICk7XG5cbiAgLyoqXG4gICAqIE5vZGUuanMgMjQueFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBOT0RFSlNfMjRfWCA9IG5ldyBMYW1iZGFSdW50aW1lKFxuICAgIFwibm9kZWpzMjQueFwiLFxuICAgIFwibm9kZTI0XCIsXG4gICk7XG5cbiAgLyoqXG4gICAqIFVzZSB0aGUgbGF0ZXN0IE5vZGUuanMgcnVudGltZSBhdmFpbGFibGUgaW4gdGhlIGRlcGxveW1lbnQgcmVnaW9uLlxuICAgKlxuICAgKiBUaGlzIGdlbmVyYXRlcyBjb2RlIHRoYXQgdXNlcyBgZGV0ZXJtaW5lTGF0ZXN0Tm9kZVJ1bnRpbWUoKWAgYXQgQ0RLIHN5bnRoZXNpcyB0aW1lLFxuICAgKiB3aGljaCBkeW5hbWljYWxseSBzZWxlY3RzIHRoZSBsYXRlc3QgTm9kZS5qcyBydW50aW1lIGF2YWlsYWJsZSBiYXNlZCBvbiByZWdpb25hbFxuICAgKiBhdmFpbGFiaWxpdHkuIFRoaXMgZWxpbWluYXRlcyB0aGUgbmVlZCB0byBtYW51YWxseSB1cGRhdGUgcnVudGltZSB2ZXJzaW9ucyBhbmRcbiAgICogYXZvaWRzIEVPTCB3YXJuaW5ncy5cbiAgICpcbiAgICogQGRlZmF1bHQgVXNlcyBkZXRlcm1pbmVMYXRlc3ROb2RlUnVudGltZSgpIGZyb20gYXdzLWNkay1saWJcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgTk9ERUpTX1JFR0lPTkFMX0xBVEVTVCA9IG5ldyBMYW1iZGFSdW50aW1lKFxuICAgIFwiTk9ERUpTX1JFR0lPTkFMX0xBVEVTVFwiLCAvLyBNYXJrZXIgdmFsdWVcbiAgICBcIm5vZGUyMlwiLCAvLyBlc2J1aWxkIHRhcmdldCAoY3VycmVudCBMVFMpXG4gICk7XG5cbiAgcHVibGljIHJlYWRvbmx5IGVzYnVpbGRQbGF0Zm9ybSA9IFwibm9kZVwiO1xuXG4gIHB1YmxpYyByZWFkb25seSBkZWZhdWx0RXh0ZXJuYWxzOiBzdHJpbmdbXTtcblxuICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgICogVGhlIE5vZGUuanMgcnVudGltZSB0byB1c2VcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgZnVuY3Rpb25SdW50aW1lOiBzdHJpbmcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZXNidWlsZCBzZXR0aW5nIHRvIHVzZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgZXNidWlsZFRhcmdldDogc3RyaW5nLFxuXG4gICAgLyoqXG4gICAgICogT3B0aW9ucyBmb3IgdGhpcyBydW50aW1lLlxuICAgICAqL1xuICAgIG9wdGlvbnM/OiBMYW1iZGFSdW50aW1lT3B0aW9ucyxcbiAgKSB7XG4gICAgdGhpcy5kZWZhdWx0RXh0ZXJuYWxzID0gb3B0aW9ucz8uZGVmYXVsdEV4dGVybmFscyA/PyBbXCJAYXdzLXNkay8qXCJdO1xuICB9XG59XG4iXX0=