aws-ddk-core
Version:
The AWS DataOps Development Kit is an open source development framework for customers that build data workflows and modern data architecture on AWS.
114 lines • 17.8 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseStack = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const cdk = require("aws-cdk-lib");
const iam = require("aws-cdk-lib/aws-iam");
const config_1 = require("../config");
/**
* Base Stack to inherit from.
*
* Includes configurable termination protection, synthesizer, permissions boundary and tags.
*/
class BaseStack extends cdk.Stack {
/**
* Create a stack.
*
* Includes termination protection settings, multi-level (application, environment,
* and stack-level) tags, and permissions boundary.
* @param scope Scope within which this construct is defined.
* @param id Identifier of the stack.
* @param props Stack properties.
*/
constructor(scope, id, props) {
const synthesizer = props.synthesizer
? props.synthesizer
: props.environmentId
? config_1.getStackSynthesizer({ environmentId: props.environmentId, config: props.config })
: undefined;
super(scope, id, { synthesizer: synthesizer, ...props });
if (props.permissionsBoundaryArn) {
iam.PermissionsBoundary.of(scope).apply(iam.ManagedPolicy.fromManagedPolicyArn(this, "Permissions Boundary", props.permissionsBoundaryArn));
}
}
static createDefaultPermissionsBoundary(scope, id, props) {
const prefix = props.prefix ?? "ddk";
const environmentId = props.environmentId ?? "dev";
const qualifier = props.qualifier ?? "hnb659fds";
const policyStatements = [
new iam.PolicyStatement({
effect: iam.Effect.DENY,
actions: ["s3:PutAccountPublicAccessBlock"],
resources: ["*"],
}),
new iam.PolicyStatement({
effect: iam.Effect.DENY,
actions: [
"iam:CreatePolicyVersion",
"iam:DeletePolicy",
"iam:DeletePolicyVersion",
"iam:SetDefaultPolicyVersion",
],
resources: [
`arn:${cdk.Stack.of(scope).partition}:iam::${cdk.Stack.of(scope).account}:policy/${prefix}-${environmentId}-${qualifier}-permissions-boundary-${cdk.Stack.of(scope).account}-${cdk.Stack.of(scope).region}`,
],
}),
new iam.PolicyStatement({
effect: iam.Effect.DENY,
actions: ["iam:DeleteRolePermissionsBoundary"],
resources: [`arn:${cdk.Stack.of(scope).partition}:iam::${cdk.Stack.of(scope).account}:role/*`],
conditions: {
"ForAnyValue:StringEquals": {
"iam:PermissionsBoundary": `arn:${cdk.Stack.of(scope).partition}:iam::${cdk.Stack.of(scope).account}:policy/${prefix}-${environmentId}-${qualifier}-permissions-boundary-${cdk.Stack.of(scope).account}-${cdk.Stack.of(scope).region}`,
},
},
}),
new iam.PolicyStatement({
effect: iam.Effect.DENY,
actions: ["iam:PutRolePermissionsBoundary"],
resources: [`arn:${cdk.Stack.of(scope).partition}:iam::${cdk.Stack.of(scope).account}:role/*`],
conditions: {
"ForAnyValue:StringNotEquals": {
"iam:PermissionsBoundary": `arn:${cdk.Stack.of(scope).partition}:iam::${cdk.Stack.of(scope).account}:policy/${prefix}-${environmentId}-${qualifier}-permissions-boundary-${cdk.Stack.of(scope).account}-${cdk.Stack.of(scope).region}`,
},
},
}),
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ["*"],
resources: ["*"],
}),
];
return new iam.ManagedPolicy(scope, id, {
statements: policyStatements,
managedPolicyName: `${prefix}-${environmentId}-${qualifier}-permissions-boundary-${cdk.Stack.of(scope).account}-${cdk.Stack.of(scope).region}`,
description: "AWS-DDK: Deny dangerous actions that could escalate privilege or cause security incident",
});
}
/**
* Create a CloudFormation Export for a string value
*
* Returns a string representing the corresponding `Fn.importValue()`
* expression for this Export. You can control the name for the export by
* passing the `name` option.
*
* If you don't supply a value for `name`, the value you're exporting must be
* a Resource attribute (for example: `bucket.bucketName`) and it will be
* given the same name as the automatic cross-stack reference that would be created
* if you used the attribute in another Stack.
*
* One of the uses for this method is to *remove* the relationship between
* two Stacks established by automatic cross-stack references. It will
* temporarily ensure that the CloudFormation Export still exists while you
* remove the reference from the consuming stack. After that, you can remove
* the resource and the manual export.
*/
exportValue(exportedValue, options) {
return super.exportValue(exportedValue, options);
}
}
exports.BaseStack = BaseStack;
_a = JSII_RTTI_SYMBOL_1;
BaseStack[_a] = { fqn: "aws-ddk-core.BaseStack", version: "1.4.1" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYmFzZS9zdGFjay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFFM0Msc0NBQStEO0FBNEIvRDs7OztHQUlHO0FBQ0gsTUFBYSxTQUFVLFNBQVEsR0FBRyxDQUFDLEtBQUs7SUEyRXRDOzs7Ozs7OztPQVFHO0lBQ0gsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFxQjtRQUM3RCxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVztZQUNuQyxDQUFDLENBQUMsS0FBSyxDQUFDLFdBQVc7WUFDbkIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxhQUFhO2dCQUNyQixDQUFDLENBQUMsNEJBQW1CLENBQUMsRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWEsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNuRixDQUFDLENBQUMsU0FBUyxDQUFDO1FBRWQsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLEdBQUcsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUV6RCxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsRUFBRTtZQUNoQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FDckMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsc0JBQXNCLEVBQUUsS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQ25HLENBQUM7U0FDSDtJQUNILENBQUM7SUFqR00sTUFBTSxDQUFDLGdDQUFnQyxDQUM1QyxLQUFnQixFQUNoQixFQUFVLEVBQ1YsS0FBK0I7UUFFL0IsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUM7UUFDckMsTUFBTSxhQUFhLEdBQUcsS0FBSyxD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S0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUN0QixFQUFFO3FCQUNIO2lCQUNGO2FBQ0YsQ0FBQztZQUNGLElBQUksR0FBRyxDQUFDLGVBQWUsQ0FBQztnQkFDdEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSztnQkFDeEIsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDO2dCQUNkLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQzthQUNqQixDQUFDO1NBQ0gsQ0FBQztRQUNGLE9BQU8sSUFBSSxHQUFHLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUU7WUFDdEMsVUFBVSxFQUFFLGdCQUFnQjtZQUM1QixpQkFBaUIsRUFBRSxHQUFHLE1BQU0sSUFBSSxhQUFhLElBQUksU0FBUyx5QkFBeUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxJQUM1RyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUN0QixFQUFFO1lBQ0YsV0FBVyxFQUFFLDBGQUEwRjtTQUN4RyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBMkJEOzs7Ozs7Ozs7Ozs7Ozs7OztPQWlCRztJQUNILFdBQVcsQ0FBQyxhQUFrQixFQUFFLE9BQWdDO1FBQzlELE9BQU8sS0FBSyxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDbkQsQ0FBQzs7QUF4SEgsOEJBeUhDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY2RrIGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHsgQ29uZmlndXJhdGlvbiwgZ2V0U3RhY2tTeW50aGVzaXplciB9IGZyb20gXCIuLi9jb25maWdcIjtcblxuLyoqXG4gKiBQcm9wZXJ0aWVzIG9mIGBCYXNlU3RhY2tgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VTdGFja1Byb3BzIGV4dGVuZHMgY2RrLlN0YWNrUHJvcHMge1xuICAvKipcbiAgICogQVJOIG9mIHRoZSBwZXJtaXNzaW9ucyBib3VuZGFyeSBtYW5hZ2VkIHBvbGljeS5cbiAgICovXG4gIHJlYWRvbmx5IHBlcm1pc3Npb25zQm91bmRhcnlBcm4/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBJZGVudGlmaWVyIG9mIHRoZSBlbnZpcm9ubWVudC5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJkZXZcIlxuICAgKi9cbiAgcmVhZG9ubHkgZW52aXJvbm1lbnRJZD86IHN0cmluZztcbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gb3IgcGF0aCB0byBmaWxlIHdoaWNoIGNvbnRhaW5zIHRoZSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgY29uZmlnPzogc3RyaW5nIHwgQ29uZmlndXJhdGlvbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQZXJtaXNzaW9uc0JvdW5kYXJ5UHJvcHMge1xuICByZWFkb25seSBlbnZpcm9ubWVudElkPzogc3RyaW5nO1xuICByZWFkb25seSBwcmVmaXg/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHF1YWxpZmllcj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBCYXNlIFN0YWNrIHRvIGluaGVyaXQgZnJvbS5cbiAqXG4gKiBJbmNsdWRlcyBjb25maWd1cmFibGUgdGVybWluYXRpb24gcHJvdGVjdGlvbiwgc3ludGhlc2l6ZXIsIHBlcm1pc3Npb25zIGJvdW5kYXJ5IGFuZCB0YWdzLlxuICovXG5leHBvcnQgY2xhc3MgQmFzZVN0YWNrIGV4dGVuZHMgY2RrLlN0YWNrIHtcbiAgcHVibGljIHN0YXRpYyBjcmVhdGVEZWZhdWx0UGVybWlzc2lvbnNCb3VuZGFyeShcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IFBlcm1pc3Npb25zQm91bmRhcnlQcm9wcyxcbiAgKTogaWFtLklNYW5hZ2VkUG9saWN5IHtcbiAgICBjb25zdCBwcmVmaXggPSBwcm9wcy5wcmVmaXggPz8gXCJkZGtcIjtcbiAgICBjb25zdCBlbnZpcm9ubWVudElkID0gcHJvcHMuZW52aXJvbm1lbnRJZCA/PyBcImRldlwiO1xuICAgIGNvbnN0IHF1YWxpZmllciA9IHByb3BzLnF1YWxpZmllciA/PyBcImhuYjY1OWZkc1wiO1xuXG4gICAgY29uc3QgcG9saWN5U3RhdGVtZW50cyA9IFtcbiAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkRFTlksXG4gICAgICAgIGFjdGlvbnM6IFtcInMzOlB1dEFjY291bnRQdWJsaWNBY2Nlc3NCbG9ja1wiXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbXCIqXCJdLFxuICAgICAgfSksXG4gICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5ERU5ZLFxuICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgXCJpYW06Q3JlYXRlUG9saWN5VmVyc2lvblwiLFxuICAgICAgICAgIFwiaWFtOkRlbGV0ZVBvbGljeVwiLFxuICAgICAgICAgIFwiaWFtOkRlbGV0ZVBvbGljeVZlcnNpb25cIixcbiAgICAgICAgICBcImlhbTpTZXREZWZhdWx0UG9saWN5VmVyc2lvblwiLFxuICAgICAgICBdLFxuICAgICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgICBgYXJuOiR7Y2RrLlN0YWNrLm9mKHNjb3BlKS5wYXJ0aXRpb259OmlhbTo6JHtcbiAgICAgICAgICAgIGNkay5TdGFjay5vZihzY29wZSkuYWNjb3VudFxuICAgICAgICAgIH06cG9saWN5LyR7cHJlZml4fS0ke2Vudmlyb25tZW50SWR9LSR7cXVhbGlmaWVyfS1wZXJtaXNzaW9ucy1ib3VuZGFyeS0ke2Nkay5TdGFjay5vZihzY29wZSkuYWNjb3VudH0tJHtcbiAgICAgICAgICAgIGNkay5TdGFjay5vZihzY29wZSkucmVnaW9uXG4gICAgICAgICAgfWAsXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkRFTlksXG4gICAgICAgIGFjdGlvbnM6IFtcImlhbTpEZWxldGVSb2xlUGVybWlzc2lvbnNCb3VuZGFyeVwiXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbYGFybjoke2Nkay5TdGFjay5vZihzY29wZSkucGFydGl0aW9ufTppYW06OiR7Y2RrLlN0YWNrLm9mKHNjb3BlKS5hY2NvdW50fTpyb2xlLypgXSxcbiAgICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICAgIFwiRm9yQW55VmFsdWU6U3RyaW5nRXF1YWxzXCI6IHtcbiAgICAgICAgICAgIFwiaWFtOlBlcm1pc3Npb25zQm91bmRhcnlcIjogYGFybjoke2Nkay5TdGFjay5vZihzY29wZSkucGFydGl0aW9ufTppYW06OiR7XG4gICAgICAgICAgICAgIGNkay5TdGFjay5vZihzY29wZSkuYWNjb3VudFxuICAgICAgICAgICAgfTpwb2xpY3kvJHtwcmVmaXh9LSR7ZW52aXJvbm1lbnRJZH0tJHtxdWFsaWZpZXJ9LXBlcm1pc3Npb25zLWJvdW5kYXJ5LSR7Y2RrLlN0YWNrLm9mKHNjb3BlKS5hY2NvdW50fS0ke1xuICAgICAgICAgICAgICBjZGsuU3RhY2sub2Yoc2NvcGUpLnJlZ2lvblxuICAgICAgICAgICAgfWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuREVOWSxcbiAgICAgICAgYWN0aW9uczogW1wiaWFtOlB1dFJvbGVQZXJtaXNzaW9uc0JvdW5kYXJ5XCJdLFxuICAgICAgICByZXNvdXJjZXM6IFtgYXJuOiR7Y2RrLlN0YWNrLm9mKHNjb3BlKS5wYXJ0aXRpb259OmlhbTo6JHtjZGsuU3RhY2sub2Yoc2NvcGUpLmFjY291bnR9OnJvbGUvKmBdLFxuICAgICAgICBjb25kaXRpb25zOiB7XG4gICAgICAgICAgXCJGb3JBbnlWYWx1ZTpTdHJpbmdOb3RFcXVhbHNcIjoge1xuICAgICAgICAgICAgXCJpYW06UGVybWlzc2lvbnNCb3VuZGFyeVwiOiBgYXJuOiR7Y2RrLlN0YWNrLm9mKHNjb3BlKS5wYXJ0aXRpb259OmlhbTo6JHtcbiAgICAgICAgICAgICAgY2RrLlN0YWNrLm9mKHNjb3BlKS5hY2NvdW50XG4gICAgICAgICAgICB9OnBvbGljeS8ke3ByZWZpeH0tJHtlbnZpcm9ubWVudElkfS0ke3F1YWxpZmllcn0tcGVybWlzc2lvbnMtYm91bmRhcnktJHtjZGsuU3RhY2sub2Yoc2NvcGUpLmFjY291bnR9LSR7XG4gICAgICAgICAgICAgIGNkay5TdGFjay5vZihzY29wZSkucmVnaW9uXG4gICAgICAgICAgICB9YCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcbiAgICAgICAgYWN0aW9uczogW1wiKlwiXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbXCIqXCJdLFxuICAgICAgfSksXG4gICAgXTtcbiAgICByZXR1cm4gbmV3IGlhbS5NYW5hZ2VkUG9saWN5KHNjb3BlLCBpZCwge1xuICAgICAgc3RhdGVtZW50czogcG9saWN5U3RhdGVtZW50cyxcbiAgICAgIG1hbmFnZWRQb2xpY3lOYW1lOiBgJHtwcmVmaXh9LSR7ZW52aXJvbm1lbnRJZH0tJHtxdWFsaWZpZXJ9LXBlcm1pc3Npb25zLWJvdW5kYXJ5LSR7Y2RrLlN0YWNrLm9mKHNjb3BlKS5hY2NvdW50fS0ke1xuICAgICAgICBjZGsuU3RhY2sub2Yoc2NvcGUpLnJlZ2lvblxuICAgICAgfWAsXG4gICAgICBkZXNjcmlwdGlvbjogXCJBV1MtRERLOiBEZW55IGRhbmdlcm91cyBhY3Rpb25zIHRoYXQgY291bGQgZXNjYWxhdGUgcHJpdmlsZWdlIG9yIGNhdXNlIHNlY3VyaXR5IGluY2lkZW50XCIsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgc3RhY2suXG4gICAqXG4gICAqIEluY2x1ZGVzIHRlcm1pbmF0aW9uIHByb3RlY3Rpb24gc2V0dGluZ3MsIG11bHRpLWxldmVsIChhcHBsaWNhdGlvbiwgZW52aXJvbm1lbnQsXG4gICAqIGFuZCBzdGFjay1sZXZlbCkgdGFncywgYW5kIHBlcm1pc3Npb25zIGJvdW5kYXJ5LlxuICAgKiBAcGFyYW0gc2NvcGUgU2NvcGUgd2l0aGluIHdoaWNoIHRoaXMgY29uc3RydWN0IGlzIGRlZmluZWQuXG4gICAqIEBwYXJhbSBpZCBJZGVudGlmaWVyIG9mIHRoZSBzdGFjay5cbiAgICogQHBhcmFtIHByb3BzIFN0YWNrIHByb3BlcnRpZXMuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQmFzZVN0YWNrUHJvcHMpIHtcbiAgICBjb25zdCBzeW50aGVzaXplciA9IHByb3BzLnN5bnRoZXNpemVyXG4gICAgICA/IHByb3BzLnN5bnRoZXNpemVyXG4gICAgICA6IHByb3BzLmVudmlyb25tZW50SWRcbiAgICAgID8gZ2V0U3RhY2tTeW50aGVzaXplcih7IGVudmlyb25tZW50SWQ6IHByb3BzLmVudmlyb25tZW50SWQsIGNvbmZpZzogcHJvcHMuY29uZmlnIH0pXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICAgIHN1cGVyKHNjb3BlLCBpZCwgeyBzeW50aGVzaXplcjogc3ludGhlc2l6ZXIsIC4uLnByb3BzIH0pO1xuXG4gICAgaWYgKHByb3BzLnBlcm1pc3Npb25zQm91bmRhcnlBcm4pIHtcbiAgICAgIGlhbS5QZXJtaXNzaW9uc0JvdW5kYXJ5Lm9mKHNjb3BlKS5hcHBseShcbiAgICAgICAgaWFtLk1hbmFnZWRQb2xpY3kuZnJvbU1hbmFnZWRQb2xpY3lBcm4odGhpcywgXCJQZXJtaXNzaW9ucyBCb3VuZGFyeVwiLCBwcm9wcy5wZXJtaXNzaW9uc0JvdW5kYXJ5QXJuKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIENsb3VkRm9ybWF0aW9uIEV4cG9ydCBmb3IgYSBzdHJpbmcgdmFsdWVcbiAgICpcbiAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGNvcnJlc3BvbmRpbmcgYEZuLmltcG9ydFZhbHVlKClgXG4gICAqIGV4cHJlc3Npb24gZm9yIHRoaXMgRXhwb3J0LiBZb3UgY2FuIGNvbnRyb2wgdGhlIG5hbWUgZm9yIHRoZSBleHBvcnQgYnlcbiAgICogcGFzc2luZyB0aGUgYG5hbWVgIG9wdGlvbi5cbiAgICpcbiAgICogSWYgeW91IGRvbid0IHN1cHBseSBhIHZhbHVlIGZvciBgbmFtZWAsIHRoZSB2YWx1ZSB5b3UncmUgZXhwb3J0aW5nIG11c3QgYmVcbiAgICogYSBSZXNvdXJjZSBhdHRyaWJ1dGUgKGZvciBleGFtcGxlOiBgYnVja2V0LmJ1Y2tldE5hbWVgKSBhbmQgaXQgd2lsbCBiZVxuICAgKiBnaXZlbiB0aGUgc2FtZSBuYW1lIGFzIHRoZSBhdXRvbWF0aWMgY3Jvc3Mtc3RhY2sgcmVmZXJlbmNlIHRoYXQgd291bGQgYmUgY3JlYXRlZFxuICAgKiBpZiB5b3UgdXNlZCB0aGUgYXR0cmlidXRlIGluIGFub3RoZXIgU3RhY2suXG4gICAqXG4gICAqIE9uZSBvZiB0aGUgdXNlcyBmb3IgdGhpcyBtZXRob2QgaXMgdG8gKnJlbW92ZSogdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuXG4gICAqIHR3byBTdGFja3MgZXN0YWJsaXNoZWQgYnkgYXV0b21hdGljIGNyb3NzLXN0YWNrIHJlZmVyZW5jZXMuIEl0IHdpbGxcbiAgICogdGVtcG9yYXJpbHkgZW5zdXJlIHRoYXQgdGhlIENsb3VkRm9ybWF0aW9uIEV4cG9ydCBzdGlsbCBleGlzdHMgd2hpbGUgeW91XG4gICAqIHJlbW92ZSB0aGUgcmVmZXJlbmNlIGZyb20gdGhlIGNvbnN1bWluZyBzdGFjay4gQWZ0ZXIgdGhhdCwgeW91IGNhbiByZW1vdmVcbiAgICogdGhlIHJlc291cmNlIGFuZCB0aGUgbWFudWFsIGV4cG9ydC5cbiAgICovXG4gIGV4cG9ydFZhbHVlKGV4cG9ydGVkVmFsdWU6IGFueSwgb3B0aW9ucz86IGNkay5FeHBvcnRWYWx1ZU9wdGlvbnMpOiBzdHJpbmcge1xuICAgIHJldHVybiBzdXBlci5leHBvcnRWYWx1ZShleHBvcnRlZFZhbHVlLCBvcHRpb25zKTtcbiAgfVxufVxuIl19