truemark-cdk-lib 1.28.1 → 1.28.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aws-patterns-autobackup/lib/autobackup-construct.js +6 -2
- package/dist/aws-vpc/lib/index.d.ts +1 -0
- package/dist/aws-vpc/lib/index.js +2 -1
- package/dist/aws-vpc/lib/nat-instance.d.ts +166 -0
- package/dist/aws-vpc/lib/nat-instance.js +508 -0
- package/dist/aws-vpc/lib/standard-network.d.ts +19 -3
- package/dist/aws-vpc/lib/standard-network.js +42 -3
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ exports.AutoBackup = void 0;
|
|
|
4
4
|
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
5
5
|
const aws_backup_1 = require("aws-cdk-lib/aws-backup");
|
|
6
6
|
const aws_events_1 = require("aws-cdk-lib/aws-events");
|
|
7
|
+
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
7
8
|
const aws_cdk_1 = require("../../aws-cdk");
|
|
8
9
|
class AutoBackup extends aws_cdk_1.ExtendedConstruct {
|
|
9
10
|
daily(days) {
|
|
@@ -33,9 +34,12 @@ class AutoBackup extends aws_cdk_1.ExtendedConstruct {
|
|
|
33
34
|
});
|
|
34
35
|
}
|
|
35
36
|
tagSelection(plan, tagValue) {
|
|
36
|
-
plan.addSelection('Selection', {
|
|
37
|
+
const selection = plan.addSelection('Selection', {
|
|
37
38
|
resources: [aws_backup_1.BackupResource.fromTag('backup:policy', tagValue)],
|
|
38
39
|
});
|
|
40
|
+
// The default backup policy does not cover S3, so a tagged bucket fails
|
|
41
|
+
// with a permission error until the S3-specific policy is attached.
|
|
42
|
+
selection.grantPrincipal.addManagedPolicy(aws_iam_1.ManagedPolicy.fromAwsManagedPolicyName('AWSBackupServiceRolePolicyForS3Backup'));
|
|
39
43
|
}
|
|
40
44
|
constructor(scope, id, props = {}) {
|
|
41
45
|
super(scope, id);
|
|
@@ -81,4 +85,4 @@ class AutoBackup extends aws_cdk_1.ExtendedConstruct {
|
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
87
|
exports.AutoBackup = AutoBackup;
|
|
84
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
88
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0b2JhY2t1cC1jb25zdHJ1Y3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXdzLXBhdHRlcm5zLWF1dG9iYWNrdXAvbGliL2F1dG9iYWNrdXAtY29uc3RydWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUFxQztBQUNyQyx1REFNZ0M7QUFDaEMsdURBQWdEO0FBQ2hELGlEQUE4RDtBQUU5RCwyQ0FBZ0Q7QUFnQmhELE1BQWEsVUFBVyxTQUFRLDJCQUFpQjtJQUN2QyxLQUFLLENBQUMsSUFBWTtRQUN4QixPQUFPLElBQUksMkJBQWMsQ0FBQztZQUN4QixRQUFRLEVBQUUsT0FBTztZQUNqQixrQkFBa0IsRUFBRSxxQkFBUSxDQUFDLElBQUksQ0FBQyxFQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBQyxDQUFDO1lBQzNELFdBQVcsRUFBRSxzQkFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7U0FDakMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLE1BQU0sQ0FBQyxJQUFZO1FBQ3pCLE9BQU8sSUFBSSwyQkFBYyxDQUFDO1lBQ3hCLFFBQVEsRUFBRSxRQUFRO1lBQ2xCLGtCQUFrQixFQUFFLHFCQUFRLENBQUMsSUFBSSxDQUFDO2dCQUNoQyxJQUFJLEVBQUUsR0FBRztnQkFDVCxNQUFNLEVBQUUsR0FBRztnQkFDWCxPQUFPLEVBQUUsS0FBSzthQUNmLENBQUM7WUFDRixXQUFXLEVBQUUsc0JBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1NBQ2pDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxPQUFPLENBQUMsSUFBWTtRQUMxQixPQUFPLElBQUksMkJBQWMsQ0FBQztZQUN4QixRQUFRLEVBQUUsU0FBUztZQUNuQixrQkFBa0IsRUFBRSxxQkFBUSxDQUFDLElBQUksQ0FBQyxFQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxNQUFN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QUVwRSxNQUFNLGlDQUFpQyxHQUFHLElBQUksdUJBQVUsQ0FDdEQsSUFBSSxFQUNKLGVBQWUsRUFDZjtZQUNFLFdBQVc7WUFDWCxlQUFlLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUN2RSxDQUNGLENBQUM7UUFDRixJQUFJLENBQUMsWUFBWSxDQUFDLGlDQUFpQyxFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDMUUsQ0FBQztDQUNGO0FBcEdELGdDQW9HQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7RHVyYXRpb259IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7XG4gIEJhY2t1cFBsYW4sXG4gIEJhY2t1cFBsYW5SdWxlLFxuICBCYWNrdXBSZXNvdXJjZSxcbiAgQmFja3VwVmF1bHQsXG4gIHR5cGUgQ2ZuQmFja3VwVmF1bHQsXG59IGZyb20gJ2F3cy1jZGstbGliL2F3cy1iYWNrdXAnO1xuaW1wb3J0IHtTY2hlZHVsZX0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWV2ZW50cyc7XG5pbXBvcnQge3R5cGUgSVJvbGUsIE1hbmFnZWRQb2xpY3l9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0IHR5cGUge0NvbnN0cnVjdH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQge0V4dGVuZGVkQ29uc3RydWN0fSBmcm9tICcuLi8uLi9hd3MtY2RrJztcblxuZXhwb3J0IGludGVyZmFjZSBBdXRvQmFja3VwUHJvcHMge1xuICAvKipcbiAgICogSWYgdHJ1ZSwgYXBwbGllcyBBV1MgQmFja3VwIFZhdWx0IExvY2sgdG8gdGhlIEF1dG9CYWNrdXAgdmF1bHQuXG4gICAqIE5vdGU6IFZhdWx0IExvY2sgYXBwbGllcyB0byBhbGwgcmVjb3ZlcnkgcG9pbnRzIGluIHRoZSB2YXVsdC5cbiAgICovXG4gIGVuYWJsZUltbXV0YWJsZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZW4gcHJvdmlkZWQgKG1pbiAzKSwgVmF1bHQgTG9jayBpcyBDb21wbGlhbmNlIG1vZGUuXG4gICAqIFdoZW4gb21pdHRlZCwgVmF1bHQgTG9jayBpcyBHb3Zlcm5hbmNlIG1vZGUuXG4gICAqL1xuICB2YXVsdExvY2tDaGFuZ2VhYmxlRm9yRGF5cz86IG51bWJlcjtcbn1cblxuZXhwb3J0IGNsYXNzIEF1dG9CYWNrdXAgZXh0ZW5kcyBFeHRlbmRlZENvbnN0cnVjdCB7XG4gIHByaXZhdGUgZGFpbHkoZGF5czogbnVtYmVyKTogQmFja3VwUGxhblJ1bGUge1xuICAgIHJldHVybiBuZXcgQmFja3VwUGxhblJ1bGUoe1xuICAgICAgcnVsZU5hbWU6ICdEYWlseScsXG4gICAgICBzY2hlZHVsZUV4cHJlc3Npb246IFNjaGVkdWxlLmNyb24oe2hvdXI6ICc1JywgbWludXRlOiAnMCd9KSxcbiAgICAgIGRlbGV0ZUFmdGVyOiBEdXJhdGlvbi5kYXlzKGRheXMpLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB3ZWVrbHkoZGF5czogbnVtYmVyKTogQmFja3VwUGxhblJ1bGUge1xuICAgIHJldHVybiBuZXcgQmFja3VwUGxhblJ1bGUoe1xuICAgICAgcnVsZU5hbWU6ICdXZWVrbHknLFxuICAgICAgc2NoZWR1bGVFeHByZXNzaW9uOiBTY2hlZHVsZS5jcm9uKHtcbiAgICAgICAgaG91cjogJzUnLFxuICAgICAgICBtaW51dGU6ICcwJyxcbiAgICAgICAgd2Vla0RheTogJ1NBVCcsXG4gICAgICB9KSxcbiAgICAgIGRlbGV0ZUFmdGVyOiBEdXJhdGlvbi5kYXlzKGRheXMpLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBtb250aGx5KGRheXM6IG51bWJlcik6IEJhY2t1cFBsYW5SdWxlIHtcbiAgICByZXR1cm4gbmV3IEJhY2t1cFBsYW5SdWxlKHtcbiAgICAgIHJ1bGVOYW1lOiAnTW9udGhseScsXG4gICAgICBzY2hlZHVsZUV4cHJlc3Npb246IFNjaGVkdWxlLmNyb24oe2RheTogJzEnLCBob3VyOiAnNScsIG1pbnV0ZTogJzAnfSksXG4gICAgICBtb3ZlVG9Db2xkU3RvcmFnZUFmdGVyOiBEdXJhdGlvbi5kYXlzKDMwKSxcbiAgICAgIGRlbGV0ZUFmdGVyOiBEdXJhdGlvbi5kYXlzKGRheXMpLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB0YWdTZWxlY3Rpb24ocGxhbjogQmFja3VwUGxhbiwgdGFnVmFsdWU6IHN0cmluZykge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHBsYW4uYWRkU2VsZWN0aW9uKCdTZWxlY3Rpb24nLCB7XG4gICAgICByZXNvdXJjZXM6IFtCYWNrdXBSZXNvdXJjZS5mcm9tVGFnKCdiYWNrdXA6cG9saWN5JywgdGFnVmFsdWUpXSxcbiAgICB9KTtcbiAgICAvLyBUaGUgZGVmYXVsdCBiYWNrdXAgcG9saWN5IGRvZXMgbm90IGNvdmVyIFMzLCBzbyBhIHRhZ2dlZCBidWNrZXQgZmFpbHNcbiAgICAvLyB3aXRoIGEgcGVybWlzc2lvbiBlcnJvciB1bnRpbCB0aGUgUzMtc3BlY2lmaWMgcG9saWN5IGlzIGF0dGFjaGVkLlxuICAgIChzZWxlY3Rpb24uZ3JhbnRQcmluY2lwYWwgYXMgSVJvbGUpLmFkZE1hbmFnZWRQb2xpY3koXG4gICAgICBNYW5hZ2VkUG9saWN5LmZyb21Bd3NNYW5hZ2VkUG9saWN5TmFtZShcbiAgICAgICAgJ0FXU0JhY2t1cFNlcnZpY2VSb2xlUG9saWN5Rm9yUzNCYWNrdXAnLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEF1dG9CYWNrdXBQcm9wcyA9IHt9KSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGNvbnN0IGJhY2t1cFZhdWx0ID0gbmV3IEJhY2t1cFZhdWx0KHRoaXMsICdEZWZhdWx0Jywge1xuICAgICAgYmFja3VwVmF1bHROYW1lOiAnQXV0b0JhY2t1cCcsXG4gICAgfSk7XG5cbiAgICAvLyBBcHBseSBWYXVsdCBMb2NrIHdoZW4gZW5hYmxlSW1tdXRhYmxlIGlzIHRydWVcbiAgICBpZiAocHJvcHMuZW5hYmxlSW1tdXRhYmxlKSB7XG4gICAgICBjb25zdCBjZm5WYXVsdCA9IGJhY2t1cFZhdWx0Lm5vZGUuZGVmYXVsdENoaWxkIGFzIENmbkJhY2t1cFZhdWx0O1xuICAgICAgY2ZuVmF1bHQubG9ja0NvbmZpZ3VyYXRpb24gPSB7XG4gICAgICAgIG1pblJldGVudGlvbkRheXM6IDEsXG4gICAgICAgIG1heFJldGVudGlvbkRheXM6IDI1NTUsXG4gICAgICAgIC4uLihwcm9wcy52YXVsdExvY2tDaGFuZ2VhYmxlRm9yRGF5cyAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyB7Y2hhbmdlYWJsZUZvckRheXM6IHByb3BzLnZhdWx0TG9ja0NoYW5nZWFibGVGb3JEYXlzfVxuICAgICAgICAgIDoge30pLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBkZWZhdWx0V2VlayA9IG5ldyBCYWNrdXBQbGFuKHRoaXMsICdEZWZhdWx0V2VlaycsIHtcbiAgICAgIGJhY2t1cFZhdWx0LFxuICAgICAgYmFja3VwUGxhblJ1bGVzOiBbdGhpcy5kYWlseSg3KV0sXG4gICAgfSk7XG4gICAgdGhpcy50YWdTZWxlY3Rpb24oZGVmYXVsdFdlZWssICdkZWZhdWx0LXdlZWsnKTtcblxuICAgIGNvbnN0IGRlZmF1bHRNb250aCA9IG5ldyBCYWNrdXBQbGFuKHRoaXMsICdEZWZhdWx0TW9udGgnLCB7XG4gICAgICBiYWNrdXBWYXVsdCxcbiAgICAgIGJhY2t1cFBsYW5SdWxlczogW3RoaXMuZGFpbHkoMzUpXSxcbiAgICB9KTtcbiAgICB0aGlzLnRhZ1NlbGVjdGlvbihkZWZhdWx0TW9udGgsICdkZWZhdWx0LW1vbnRoJyk7XG5cbiAgICBjb25zdCBkZWZhdWx0UXVhcnRlciA9IG5ldyBCYWNrdXBQbGFuKHRoaXMsICdEZWZhdWx0UXVhcnRlcicsIHtcbiAgICAgIGJhY2t1cFZhdWx0LFxuICAgICAgYmFja3VwUGxhblJ1bGVzOiBbdGhpcy5kYWlseSgzNSksIHRoaXMud2Vla2x5KDkwKV0sXG4gICAgfSk7XG4gICAgdGhpcy50YWdTZWxlY3Rpb24oZGVmYXVsdFF1YXJ0ZXIsICdkZWZhdWx0LXF1YXJ0ZXInKTtcblxuICAgIGNvbnN0IGRlZmF1bHREYWlseTM1V2Vla2x5OTBNb250aGx5MzY1ID0gbmV3IEJhY2t1cFBsYW4oXG4gICAgICB0aGlzLFxuICAgICAgJ0RlZmF1bHRZZWFyJyxcbiAgICAgIHtcbiAgICAgICAgYmFja3VwVmF1bHQsXG4gICAgICAgIGJhY2t1cFBsYW5SdWxlczogW3RoaXMuZGFpbHkoMzUpLCB0aGlzLndlZWtseSg5MCksIHRoaXMubW9udGhseSgzNjUpXSxcbiAgICAgIH0sXG4gICAgKTtcbiAgICB0aGlzLnRhZ1NlbGVjdGlvbihkZWZhdWx0RGFpbHkzNVdlZWtseTkwTW9udGhseTM2NSwgJ2RlZmF1bHQteWVhcicpO1xuXG4gICAgY29uc3QgZGVmYXVsdERhaWx5MzVXZWVrbHk5ME1vbnRobHkyNTU1ID0gbmV3IEJhY2t1cFBsYW4oXG4gICAgICB0aGlzLFxuICAgICAgJ0RlZmF1bHQ3WWVhcnMnLFxuICAgICAge1xuICAgICAgICBiYWNrdXBWYXVsdCxcbiAgICAgICAgYmFja3VwUGxhblJ1bGVzOiBbdGhpcy5kYWlseSgzNSksIHRoaXMud2Vla2x5KDkwKSwgdGhpcy5tb250aGx5KDI1NTUpXSxcbiAgICAgIH0sXG4gICAgKTtcbiAgICB0aGlzLnRhZ1NlbGVjdGlvbihkZWZhdWx0RGFpbHkzNVdlZWtseTkwTW9udGhseTI1NTUsICdkZWZhdWx0LTcteWVhcnMnKTtcbiAgfVxufVxuIl19
|
|
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./nat-instance"), exports);
|
|
17
18
|
__exportStar(require("./network-parameters"), exports);
|
|
18
19
|
__exportStar(require("./standard-network"), exports);
|
|
19
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXdzLXZwYy9saWIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLGlEQUErQjtBQUMvQix1REFBcUM7QUFDckMscURBQW1DIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9uYXQtaW5zdGFuY2UnO1xuZXhwb3J0ICogZnJvbSAnLi9uZXR3b3JrLXBhcmFtZXRlcnMnO1xuZXhwb3J0ICogZnJvbSAnLi9zdGFuZGFyZC1uZXR3b3JrJztcbiJdfQ==
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
|
2
|
+
import type { Construct } from 'constructs';
|
|
3
|
+
import { ExtendedConstruct, type ExtendedConstructProps } from '../../aws-cdk/index';
|
|
4
|
+
/**
|
|
5
|
+
* An additional file to write via cloud-init write_files.
|
|
6
|
+
*/
|
|
7
|
+
export interface NatInstanceWriteFile {
|
|
8
|
+
/** Absolute path on the instance where the file will be written. */
|
|
9
|
+
readonly path: string;
|
|
10
|
+
/** File content. */
|
|
11
|
+
readonly content: string;
|
|
12
|
+
/** Octal file permissions string, e.g. '0755'. */
|
|
13
|
+
readonly permissions?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Properties for NatInstance.
|
|
17
|
+
*/
|
|
18
|
+
export interface NatInstanceProps extends ExtendedConstructProps {
|
|
19
|
+
/**
|
|
20
|
+
* VPC to place the NAT instance in.
|
|
21
|
+
*/
|
|
22
|
+
readonly vpc: ec2.IVpc;
|
|
23
|
+
/**
|
|
24
|
+
* The public subnet where the ENI and instance will live.
|
|
25
|
+
*/
|
|
26
|
+
readonly publicSubnet: ec2.ISubnet;
|
|
27
|
+
/**
|
|
28
|
+
* CIDR blocks of private subnets. Used for the security group ingress rule
|
|
29
|
+
* so that private instances can route traffic through the NAT instance.
|
|
30
|
+
*/
|
|
31
|
+
readonly privateSubnetCidrBlocks: string[];
|
|
32
|
+
/**
|
|
33
|
+
* Whether to run the ASG at desired capacity of 1. When false the ASG is
|
|
34
|
+
* set to desired/min=0, effectively pausing the NAT instance without
|
|
35
|
+
* destroying the ENI or other resources. Default is true.
|
|
36
|
+
*
|
|
37
|
+
* @default true
|
|
38
|
+
*/
|
|
39
|
+
readonly enabled?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* IDs of private route tables that should receive a 0.0.0.0/0 default
|
|
42
|
+
* route pointing to the NAT instance ENI. Typically one per AZ.
|
|
43
|
+
*/
|
|
44
|
+
readonly privateRouteTableIds?: string[];
|
|
45
|
+
/**
|
|
46
|
+
* Custom AMI ID. When omitted the latest Amazon Linux 2023 standard AMI
|
|
47
|
+
* is used, filtered by the resolved architecture. The standard edition
|
|
48
|
+
* includes the SSM agent for remote management.
|
|
49
|
+
*/
|
|
50
|
+
readonly imageId?: string;
|
|
51
|
+
/**
|
|
52
|
+
* CPU architecture used for the AMI lookup. Default is ARM_64, which
|
|
53
|
+
* corresponds to the default t4g.micro instance type.
|
|
54
|
+
*
|
|
55
|
+
* @default ec2.AmazonLinuxCpuType.ARM_64
|
|
56
|
+
*/
|
|
57
|
+
readonly architecture?: ec2.AmazonLinuxCpuType;
|
|
58
|
+
/**
|
|
59
|
+
* EC2 instance types for the Auto Scaling Group mixed instances policy.
|
|
60
|
+
* Defaults based on architecture: t4g.micro for ARM64 (~$6/month on-demand),
|
|
61
|
+
* t3a.micro for X86_64 (~$7.60/month on-demand).
|
|
62
|
+
*
|
|
63
|
+
* @default [new ec2.InstanceType('t4g.micro')] for ARM64, [new ec2.InstanceType('t3a.micro')] for X86_64
|
|
64
|
+
*/
|
|
65
|
+
readonly instanceTypes?: ec2.InstanceType[];
|
|
66
|
+
/**
|
|
67
|
+
* Use Spot instances instead of On-Demand. Spot can reduce cost to ~$1/month
|
|
68
|
+
* but the instance may be interrupted with a 2-minute warning. Default is false.
|
|
69
|
+
*
|
|
70
|
+
* @default false
|
|
71
|
+
*/
|
|
72
|
+
readonly useSpotInstance?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Name of an existing EC2 key pair to allow SSH access. When omitted,
|
|
75
|
+
* AWS Systems Manager Session Manager (enabled via the attached SSM policy)
|
|
76
|
+
* is the only console access method.
|
|
77
|
+
*/
|
|
78
|
+
readonly keyName?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Additional cloud-init write_files entries appended after the built-in
|
|
81
|
+
* NAT scripts. Useful for injecting custom configuration files.
|
|
82
|
+
*/
|
|
83
|
+
readonly additionalWriteFiles?: NatInstanceWriteFile[];
|
|
84
|
+
/**
|
|
85
|
+
* Additional cloud-init runcmd entries appended after /opt/nat/runonce.sh.
|
|
86
|
+
* Each inner array represents one command invocation (argv style).
|
|
87
|
+
*/
|
|
88
|
+
readonly additionalRunCmds?: string[][];
|
|
89
|
+
/**
|
|
90
|
+
* ARN of the IAM managed policy attached to the instance role for Systems
|
|
91
|
+
* Manager access. When omitted, uses AmazonSSMManagedInstanceCore resolved
|
|
92
|
+
* for the stack's partition (works in GovCloud and China).
|
|
93
|
+
*
|
|
94
|
+
* @default AmazonSSMManagedInstanceCore (partition-agnostic)
|
|
95
|
+
*/
|
|
96
|
+
readonly ssmPolicyArn?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* A self-healing, cost-optimised NAT instance for private subnet egress.
|
|
100
|
+
*
|
|
101
|
+
* This is a CDK port of the truemark/nat-instance Terraform module. It
|
|
102
|
+
* provisions:
|
|
103
|
+
* - A dedicated secondary Elastic Network Interface (ENI) with source/dest
|
|
104
|
+
* check disabled. Private subnets route to this ENI, which persists across
|
|
105
|
+
* instance replacements. Actual NAT egress happens through the instance's
|
|
106
|
+
* primary interface (which has an auto-assigned public IP by default).
|
|
107
|
+
* - An IAM role with AmazonSSMManagedInstanceCore and the EC2 permissions
|
|
108
|
+
* needed for snat.sh to attach the secondary ENI at boot.
|
|
109
|
+
* - An EC2 Launch Template running Amazon Linux 2023 standard (ARM64 by
|
|
110
|
+
* default) with a cloud-init user-data that installs iptables, attaches
|
|
111
|
+
* the ENI, enables IP forwarding, and sets up NAT masquerading.
|
|
112
|
+
* - An Auto Scaling Group (desired=1) that auto-replaces the instance on
|
|
113
|
+
* failure, keeping the ENI persistent across replacements.
|
|
114
|
+
* - Optional 0.0.0.0/0 routes in private route tables pointing to the ENI.
|
|
115
|
+
*
|
|
116
|
+
* **Usage with StandardNetwork:**
|
|
117
|
+
* ```ts
|
|
118
|
+
* const network = new StandardNetwork(this, 'Network', {
|
|
119
|
+
* name: 'prod',
|
|
120
|
+
* vpcCidr: '10.0.0.0/20',
|
|
121
|
+
* natType: 'none', // no managed NAT gateway
|
|
122
|
+
* });
|
|
123
|
+
*
|
|
124
|
+
* const nat = new NatInstance(this, 'Nat', {
|
|
125
|
+
* vpc: network.vpc,
|
|
126
|
+
* publicSubnet: network.vpc.selectSubnets({subnetGroupName: 'public'}).subnets[0],
|
|
127
|
+
* privateSubnetCidrBlocks: ['10.0.0.0/24'],
|
|
128
|
+
* privateRouteTableIds: network.vpc
|
|
129
|
+
* .selectSubnets({subnetGroupName: 'private'})
|
|
130
|
+
* .subnets.map(s => s.routeTable.routeTableId),
|
|
131
|
+
* });
|
|
132
|
+
*
|
|
133
|
+
* // The instance's primary interface gets an auto-assigned public IP.
|
|
134
|
+
* // For a stable outbound IP, allocate and associate an EIP with the
|
|
135
|
+
* // instance's primary interface using ASG lifecycle hooks or tags.
|
|
136
|
+
* // Example:
|
|
137
|
+
* // const eip = new ec2.CfnEIP(this, 'NatEip', {domain: 'vpc'});
|
|
138
|
+
* // Associate the EIP with new instances via lifecycle hook or tag matching.
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
141
|
+
* > **Note:** This construct is optimised for cost (ARM64 spot/on-demand
|
|
142
|
+
* > t4g.micro at ~$2–6/month) and is suitable for dev/staging environments.
|
|
143
|
+
* > For production use prefer AWS NAT Gateway or a larger instance type with
|
|
144
|
+
* > `useSpotInstance: false`.
|
|
145
|
+
*/
|
|
146
|
+
export declare class NatInstance extends ExtendedConstruct {
|
|
147
|
+
/**
|
|
148
|
+
* CloudFormation resource ID of the dedicated secondary ENI. Private subnet
|
|
149
|
+
* routes point to this ENI, which persists across instance replacements.
|
|
150
|
+
* Note: NAT egress occurs through the primary interface, not this ENI.
|
|
151
|
+
*/
|
|
152
|
+
readonly eniId: string;
|
|
153
|
+
/**
|
|
154
|
+
* Primary private IPv4 address of the dedicated ENI.
|
|
155
|
+
*/
|
|
156
|
+
readonly eniPrivateIp: string;
|
|
157
|
+
/**
|
|
158
|
+
* Security group ID of the NAT instance security group.
|
|
159
|
+
*/
|
|
160
|
+
readonly sgId: string;
|
|
161
|
+
/**
|
|
162
|
+
* Name of the IAM role attached to the NAT instance.
|
|
163
|
+
*/
|
|
164
|
+
readonly iamRoleName: string;
|
|
165
|
+
constructor(scope: Construct, id: string, props: NatInstanceProps);
|
|
166
|
+
}
|
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NatInstance = void 0;
|
|
4
|
+
const cdk = require("aws-cdk-lib");
|
|
5
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
6
|
+
const autoscaling = require("aws-cdk-lib/aws-autoscaling");
|
|
7
|
+
const ec2 = require("aws-cdk-lib/aws-ec2");
|
|
8
|
+
const iam = require("aws-cdk-lib/aws-iam");
|
|
9
|
+
const index_1 = require("../../aws-cdk/index");
|
|
10
|
+
const truemark_1 = require("../../truemark");
|
|
11
|
+
// Verbatim content of the startup scripts, embedded at build time.
|
|
12
|
+
// Shell `$var` and `$(cmd)` references are escaped as `\${var}` / `\$(cmd)`
|
|
13
|
+
// to prevent TypeScript template-literal interpolation.
|
|
14
|
+
const SNAT_SH = `#!/bin/sh
|
|
15
|
+
set -e
|
|
16
|
+
dnf install -y iptables-services awscli || yum install -y iptables-services awscli
|
|
17
|
+
if test -f "/etc/nat.conf"; then
|
|
18
|
+
echo "Found nat configuration at /etc/nat.conf"
|
|
19
|
+
. /etc/nat.conf
|
|
20
|
+
else
|
|
21
|
+
echo "No nat configuration at /etc/nat.conf"
|
|
22
|
+
fi
|
|
23
|
+
token="$(curl -sS -X PUT -H 'X-aws-ec2-metadata-token-ttl-seconds: 300' http://169.254.169.254/latest/api/token)"
|
|
24
|
+
aws_region="$(curl -sS -H "X-aws-ec2-metadata-token: \${token}" http://169.254.169.254/latest/meta-data/placement/region)"
|
|
25
|
+
instance_id="$(curl -sS -H "X-aws-ec2-metadata-token: \${token}" http://169.254.169.254/latest/meta-data/instance-id)"
|
|
26
|
+
# Do not assume the primary interface is named eth0.
|
|
27
|
+
# Use the interface that owns the default route.
|
|
28
|
+
primary_interface="$(ip route | awk '/default/ {print $5; exit}')"
|
|
29
|
+
if test -z "\${primary_interface}"; then
|
|
30
|
+
echo "Could not determine primary/default network interface"
|
|
31
|
+
ip route
|
|
32
|
+
exit 1
|
|
33
|
+
fi
|
|
34
|
+
primary_mac="$(cat /sys/class/net/\${primary_interface}/address)"
|
|
35
|
+
echo "Primary/default interface is \${primary_interface} with MAC \${primary_mac}"
|
|
36
|
+
if test -n "\${eni_id}"; then
|
|
37
|
+
echo "Found eni_id configuration, attaching \${eni_id}..."
|
|
38
|
+
primary_eni_id="$(curl -sS -H "X-aws-ec2-metadata-token: \${token}" http://169.254.169.254/latest/meta-data/network/interfaces/macs/\${primary_mac}/interface-id)"
|
|
39
|
+
echo "Disabling source/dest check on primary ENI \${primary_eni_id}..."
|
|
40
|
+
aws ec2 modify-network-interface-attribute \\
|
|
41
|
+
--region "\${aws_region}" \\
|
|
42
|
+
--network-interface-id "\${primary_eni_id}" \\
|
|
43
|
+
--source-dest-check '{"Value":false}'
|
|
44
|
+
echo "Disabling source/dest check on NAT ENI \${eni_id}..."
|
|
45
|
+
aws ec2 modify-network-interface-attribute \\
|
|
46
|
+
--region "\${aws_region}" \\
|
|
47
|
+
--network-interface-id "\${eni_id}" \\
|
|
48
|
+
--source-dest-check '{"Value":false}'
|
|
49
|
+
echo "Checking current attachment state for NAT ENI \${eni_id}..."
|
|
50
|
+
attached_instance_id="$(aws ec2 describe-network-interfaces \\
|
|
51
|
+
--region "\${aws_region}" \\
|
|
52
|
+
--network-interface-ids "\${eni_id}" \\
|
|
53
|
+
--query 'NetworkInterfaces[0].Attachment.InstanceId' \\
|
|
54
|
+
--output text 2>/dev/null || true)"
|
|
55
|
+
if test "\${attached_instance_id}" = "\${instance_id}"; then
|
|
56
|
+
echo "NAT ENI \${eni_id} is already attached to this instance."
|
|
57
|
+
elif test -n "\${attached_instance_id}" && test "\${attached_instance_id}" != "None"; then
|
|
58
|
+
echo "NAT ENI \${eni_id} is attached to another instance: \${attached_instance_id}"
|
|
59
|
+
echo "This may be the previous instance during replacement. Retrying for up to 60 seconds..."
|
|
60
|
+
for retry in $(seq 1 12); do
|
|
61
|
+
sleep 5
|
|
62
|
+
attached_instance_id="$(aws ec2 describe-network-interfaces \\
|
|
63
|
+
--region "\${aws_region}" \\
|
|
64
|
+
--network-interface-ids "\${eni_id}" \\
|
|
65
|
+
--query 'NetworkInterfaces[0].Attachment.InstanceId' \\
|
|
66
|
+
--output text 2>/dev/null || true)"
|
|
67
|
+
if test "\${attached_instance_id}" = "\${instance_id}"; then
|
|
68
|
+
echo "ENI is now attached to this instance."
|
|
69
|
+
break
|
|
70
|
+
elif test -z "\${attached_instance_id}" || test "\${attached_instance_id}" = "None"; then
|
|
71
|
+
echo "ENI is now available. Proceeding with attachment."
|
|
72
|
+
break
|
|
73
|
+
fi
|
|
74
|
+
echo "Retry \${retry}/12: ENI still attached to \${attached_instance_id}"
|
|
75
|
+
done
|
|
76
|
+
if test -n "\${attached_instance_id}" && test "\${attached_instance_id}" != "None" && test "\${attached_instance_id}" != "\${instance_id}"; then
|
|
77
|
+
echo "ERROR: ENI \${eni_id} is still attached to another instance after retries: \${attached_instance_id}"
|
|
78
|
+
# Systemd will retry this service. If all systemd retries are exhausted, terminate.
|
|
79
|
+
exit 1
|
|
80
|
+
fi
|
|
81
|
+
fi
|
|
82
|
+
if test "\${attached_instance_id}" != "\${instance_id}"; then
|
|
83
|
+
echo "Attaching NAT ENI \${eni_id} to instance \${instance_id}..."
|
|
84
|
+
# Use if statement to capture exit status before errexit triggers
|
|
85
|
+
if attach_output="$(aws ec2 attach-network-interface \\
|
|
86
|
+
--region "\${aws_region}" \\
|
|
87
|
+
--instance-id "\${instance_id}" \\
|
|
88
|
+
--device-index 1 \\
|
|
89
|
+
--network-interface-id "\${eni_id}" 2>&1)"; then
|
|
90
|
+
echo "\${attach_output}"
|
|
91
|
+
echo "ENI attached successfully."
|
|
92
|
+
else
|
|
93
|
+
attach_status=$?
|
|
94
|
+
echo "\${attach_output}"
|
|
95
|
+
echo "Failed to attach NAT ENI \${eni_id} with status \${attach_status}"
|
|
96
|
+
exit "\${attach_status}"
|
|
97
|
+
fi
|
|
98
|
+
fi
|
|
99
|
+
echo "Waiting for NAT ENI \${eni_id} to appear in metadata..."
|
|
100
|
+
nat_eni_mac=""
|
|
101
|
+
for attempt in $(seq 1 60); do
|
|
102
|
+
for mac in $(curl -sS -H "X-aws-ec2-metadata-token: \${token}" http://169.254.169.254/latest/meta-data/network/interfaces/macs/); do
|
|
103
|
+
interface_id="$(curl -sS -H "X-aws-ec2-metadata-token: \${token}" http://169.254.169.254/latest/meta-data/network/interfaces/macs/\${mac}interface-id)"
|
|
104
|
+
if test "\${interface_id}" = "\${eni_id}"; then
|
|
105
|
+
nat_eni_mac="$(echo "\${mac}" | sed 's#/$##')"
|
|
106
|
+
break
|
|
107
|
+
fi
|
|
108
|
+
done
|
|
109
|
+
if test -n "\${nat_eni_mac}"; then
|
|
110
|
+
break
|
|
111
|
+
fi
|
|
112
|
+
echo "Waiting for ENI metadata..."
|
|
113
|
+
sleep 2
|
|
114
|
+
done
|
|
115
|
+
if test -z "\${nat_eni_mac}"; then
|
|
116
|
+
echo "Could not find MAC address for NAT ENI \${eni_id}"
|
|
117
|
+
exit 1
|
|
118
|
+
fi
|
|
119
|
+
nat_eni_linux_device=""
|
|
120
|
+
for dev in $(ls /sys/class/net); do
|
|
121
|
+
dev_mac="$(cat /sys/class/net/\${dev}/address 2>/dev/null || true)"
|
|
122
|
+
if test "\${dev_mac}" = "\${nat_eni_mac}"; then
|
|
123
|
+
nat_eni_linux_device="\${dev}"
|
|
124
|
+
break
|
|
125
|
+
fi
|
|
126
|
+
done
|
|
127
|
+
if test -z "\${nat_eni_linux_device}"; then
|
|
128
|
+
echo "Could not map NAT ENI MAC \${nat_eni_mac} to Linux network device"
|
|
129
|
+
ip link show
|
|
130
|
+
exit 1
|
|
131
|
+
fi
|
|
132
|
+
echo "NAT ENI \${eni_id} is Linux device \${nat_eni_linux_device}"
|
|
133
|
+
# Private subnet routes target the NAT ENI for stable routing, but outbound
|
|
134
|
+
# SNAT leaves through the primary interface (which has the auto-assigned
|
|
135
|
+
# public IP or manually attached EIP). Secondary ENIs don't get auto-assigned
|
|
136
|
+
# public IPs, and setting up policy routing through eth1 is complex.
|
|
137
|
+
nat_interface="\${primary_interface}"
|
|
138
|
+
echo "Using outbound NAT interface \${nat_interface}"
|
|
139
|
+
elif test -n "\${interface}"; then
|
|
140
|
+
echo "Found interface configuration, using \${interface}"
|
|
141
|
+
nat_interface="\${interface}"
|
|
142
|
+
else
|
|
143
|
+
nat_interface="\${primary_interface}"
|
|
144
|
+
echo "No eni_id or interface configuration found, using default interface \${nat_interface}"
|
|
145
|
+
fi
|
|
146
|
+
echo "Enabling ip_forward..."
|
|
147
|
+
sysctl -q -w net.ipv4.ip_forward=1
|
|
148
|
+
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-nat.conf
|
|
149
|
+
echo "Disabling reverse path protection..."
|
|
150
|
+
for i in $(find /proc/sys/net/ipv4/conf/ -name rp_filter); do
|
|
151
|
+
echo 0 > "\${i}";
|
|
152
|
+
done
|
|
153
|
+
cat > /etc/sysctl.d/98-disable-rp-filter.conf <<'EOF'
|
|
154
|
+
net.ipv4.conf.all.rp_filter = 0
|
|
155
|
+
net.ipv4.conf.default.rp_filter = 0
|
|
156
|
+
EOF
|
|
157
|
+
echo "Flushing NAT table..."
|
|
158
|
+
iptables -t nat -F
|
|
159
|
+
echo "Adding NAT rule..."
|
|
160
|
+
iptables -t nat -A POSTROUTING -o "\${nat_interface}" -j MASQUERADE -m comment --comment "NAT routing rule installed"
|
|
161
|
+
echo "Current NAT table:"
|
|
162
|
+
iptables -t nat -L -n -v
|
|
163
|
+
service iptables save || true
|
|
164
|
+
echo "Done!"
|
|
165
|
+
`;
|
|
166
|
+
const SNAT_SERVICE = `[Unit]
|
|
167
|
+
Description = Configure this machine to act as a NAT instance.
|
|
168
|
+
Wants = network-online.target
|
|
169
|
+
After = network-online.target
|
|
170
|
+
# If NAT setup fails after all retries, terminate the instance so ASG replaces it
|
|
171
|
+
OnFailure = snat-failure.service
|
|
172
|
+
# Limit total retries to 10 attempts within a 10-minute window.
|
|
173
|
+
# With RestartSec=30s, 10 attempts take ~5 minutes; this window ensures
|
|
174
|
+
# the 10th failure triggers OnFailure rather than resetting the burst counter.
|
|
175
|
+
StartLimitIntervalSec = 600
|
|
176
|
+
StartLimitBurst = 10
|
|
177
|
+
|
|
178
|
+
[Service]
|
|
179
|
+
ExecStart = /opt/nat/snat.sh
|
|
180
|
+
Type = oneshot
|
|
181
|
+
# Retry on failure to handle transient ENI attachment issues during ASG replacement.
|
|
182
|
+
# If ENI is still attached to previous instance, systemd will retry after 30s.
|
|
183
|
+
Restart = on-failure
|
|
184
|
+
RestartSec = 30s
|
|
185
|
+
|
|
186
|
+
[Install]
|
|
187
|
+
WantedBy = multi-user.target
|
|
188
|
+
`;
|
|
189
|
+
const SNAT_FAILURE_SERVICE = `[Unit]
|
|
190
|
+
Description = Terminate NAT instance after unrecoverable setup failure
|
|
191
|
+
DefaultDependencies = no
|
|
192
|
+
|
|
193
|
+
[Service]
|
|
194
|
+
Type = oneshot
|
|
195
|
+
ExecStart = /opt/nat/terminate-on-failure.sh
|
|
196
|
+
`;
|
|
197
|
+
const TERMINATE_ON_FAILURE_SH = `#!/bin/sh
|
|
198
|
+
# This script is invoked by snat-failure.service when NAT setup fails after all retries.
|
|
199
|
+
# Terminating the instance triggers ASG to replace it, preventing blackholed routes.
|
|
200
|
+
set -ex
|
|
201
|
+
token="$(curl -sS -X PUT -H 'X-aws-ec2-metadata-token-ttl-seconds: 300' http://169.254.169.254/latest/api/token)"
|
|
202
|
+
aws_region="$(curl -sS -H "X-aws-ec2-metadata-token: \${token}" http://169.254.169.254/latest/meta-data/placement/region)"
|
|
203
|
+
instance_id="$(curl -sS -H "X-aws-ec2-metadata-token: \${token}" http://169.254.169.254/latest/meta-data/instance-id)"
|
|
204
|
+
echo "FATAL: NAT setup failed after all retries. Terminating instance \${instance_id} to trigger ASG replacement..."
|
|
205
|
+
aws ec2 terminate-instances --instance-ids "\${instance_id}" --region "\${aws_region}"
|
|
206
|
+
`;
|
|
207
|
+
const RUNONCE_SH = `#!/bin/bash -x
|
|
208
|
+
|
|
209
|
+
# start SNAT
|
|
210
|
+
systemctl enable snat
|
|
211
|
+
systemctl start snat
|
|
212
|
+
`;
|
|
213
|
+
/**
|
|
214
|
+
* Indents script content for embedding in a YAML literal block scalar.
|
|
215
|
+
* Each line is prefixed with 4 spaces; blank lines are left truly empty
|
|
216
|
+
* to satisfy strict YAML parsers. The trailing newline produced by scripts
|
|
217
|
+
* ending with \n is consumed (the YAML `|` chomping handles it).
|
|
218
|
+
*/
|
|
219
|
+
function indentLiteralBlock(content) {
|
|
220
|
+
const lines = content.split('\n');
|
|
221
|
+
// Drop the last element when it is an empty string produced by a
|
|
222
|
+
// trailing \n — the `|` block indicator already implies one final newline.
|
|
223
|
+
if (lines[lines.length - 1] === '') {
|
|
224
|
+
lines.pop();
|
|
225
|
+
}
|
|
226
|
+
return lines.map((line) => (line === '' ? '' : ` ${line}`)).join('\n');
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Renders a single cloud-init write_files list entry as YAML, using a
|
|
230
|
+
* literal block scalar for the content field to avoid any escaping issues
|
|
231
|
+
* with shell special characters.
|
|
232
|
+
*/
|
|
233
|
+
function writeFileEntry(path, content, permissions) {
|
|
234
|
+
const permsLine = permissions !== undefined ? `\n permissions: '${permissions}'` : '';
|
|
235
|
+
return `- path: ${path}${permsLine}\n content: |\n${indentLiteralBlock(content)}\n`;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* A self-healing, cost-optimised NAT instance for private subnet egress.
|
|
239
|
+
*
|
|
240
|
+
* This is a CDK port of the truemark/nat-instance Terraform module. It
|
|
241
|
+
* provisions:
|
|
242
|
+
* - A dedicated secondary Elastic Network Interface (ENI) with source/dest
|
|
243
|
+
* check disabled. Private subnets route to this ENI, which persists across
|
|
244
|
+
* instance replacements. Actual NAT egress happens through the instance's
|
|
245
|
+
* primary interface (which has an auto-assigned public IP by default).
|
|
246
|
+
* - An IAM role with AmazonSSMManagedInstanceCore and the EC2 permissions
|
|
247
|
+
* needed for snat.sh to attach the secondary ENI at boot.
|
|
248
|
+
* - An EC2 Launch Template running Amazon Linux 2023 standard (ARM64 by
|
|
249
|
+
* default) with a cloud-init user-data that installs iptables, attaches
|
|
250
|
+
* the ENI, enables IP forwarding, and sets up NAT masquerading.
|
|
251
|
+
* - An Auto Scaling Group (desired=1) that auto-replaces the instance on
|
|
252
|
+
* failure, keeping the ENI persistent across replacements.
|
|
253
|
+
* - Optional 0.0.0.0/0 routes in private route tables pointing to the ENI.
|
|
254
|
+
*
|
|
255
|
+
* **Usage with StandardNetwork:**
|
|
256
|
+
* ```ts
|
|
257
|
+
* const network = new StandardNetwork(this, 'Network', {
|
|
258
|
+
* name: 'prod',
|
|
259
|
+
* vpcCidr: '10.0.0.0/20',
|
|
260
|
+
* natType: 'none', // no managed NAT gateway
|
|
261
|
+
* });
|
|
262
|
+
*
|
|
263
|
+
* const nat = new NatInstance(this, 'Nat', {
|
|
264
|
+
* vpc: network.vpc,
|
|
265
|
+
* publicSubnet: network.vpc.selectSubnets({subnetGroupName: 'public'}).subnets[0],
|
|
266
|
+
* privateSubnetCidrBlocks: ['10.0.0.0/24'],
|
|
267
|
+
* privateRouteTableIds: network.vpc
|
|
268
|
+
* .selectSubnets({subnetGroupName: 'private'})
|
|
269
|
+
* .subnets.map(s => s.routeTable.routeTableId),
|
|
270
|
+
* });
|
|
271
|
+
*
|
|
272
|
+
* // The instance's primary interface gets an auto-assigned public IP.
|
|
273
|
+
* // For a stable outbound IP, allocate and associate an EIP with the
|
|
274
|
+
* // instance's primary interface using ASG lifecycle hooks or tags.
|
|
275
|
+
* // Example:
|
|
276
|
+
* // const eip = new ec2.CfnEIP(this, 'NatEip', {domain: 'vpc'});
|
|
277
|
+
* // Associate the EIP with new instances via lifecycle hook or tag matching.
|
|
278
|
+
* ```
|
|
279
|
+
*
|
|
280
|
+
* > **Note:** This construct is optimised for cost (ARM64 spot/on-demand
|
|
281
|
+
* > t4g.micro at ~$2–6/month) and is suitable for dev/staging environments.
|
|
282
|
+
* > For production use prefer AWS NAT Gateway or a larger instance type with
|
|
283
|
+
* > `useSpotInstance: false`.
|
|
284
|
+
*/
|
|
285
|
+
class NatInstance extends index_1.ExtendedConstruct {
|
|
286
|
+
constructor(scope, id, props) {
|
|
287
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
288
|
+
super(scope, id, {
|
|
289
|
+
standardTags: index_1.StandardTags.merge(props.standardTags, truemark_1.LibStandardTags),
|
|
290
|
+
});
|
|
291
|
+
const enabled = (_a = props.enabled) !== null && _a !== void 0 ? _a : true;
|
|
292
|
+
const architecture = (_b = props.architecture) !== null && _b !== void 0 ? _b : ec2.AmazonLinuxCpuType.ARM_64;
|
|
293
|
+
// Unique tag value for this NAT instance, used to scope IAM permissions.
|
|
294
|
+
// Includes stack name to ensure uniqueness across multiple stack deployments.
|
|
295
|
+
const natInstanceRoleTag = `nat-instance-${cdk.Stack.of(this).stackName}-${id}`;
|
|
296
|
+
// Derive default instance type from architecture to avoid AMI/instance mismatch
|
|
297
|
+
// Use micro (1GB RAM) instead of nano (512MB) to prevent OOM during package installation
|
|
298
|
+
const defaultInstanceType = architecture === ec2.AmazonLinuxCpuType.X86_64
|
|
299
|
+
? new ec2.InstanceType('t3a.micro')
|
|
300
|
+
: new ec2.InstanceType('t4g.micro');
|
|
301
|
+
const instanceTypes = (_c = props.instanceTypes) !== null && _c !== void 0 ? _c : [defaultInstanceType];
|
|
302
|
+
if (instanceTypes.length === 0) {
|
|
303
|
+
throw new Error('instanceTypes must contain at least one instance type. Omit the property to use the architecture-appropriate default (t4g.micro for ARM64, t3a.micro for X86_64).');
|
|
304
|
+
}
|
|
305
|
+
const useSpotInstance = (_d = props.useSpotInstance) !== null && _d !== void 0 ? _d : false;
|
|
306
|
+
// ── Security Group ────────────────────────────────────────────────────────
|
|
307
|
+
const sg = new ec2.SecurityGroup(this, 'SecurityGroup', {
|
|
308
|
+
vpc: props.vpc,
|
|
309
|
+
description: `Security group for NAT instance ${id}`,
|
|
310
|
+
allowAllOutbound: true, // mirrors the egress all-traffic rule in Terraform
|
|
311
|
+
});
|
|
312
|
+
for (const cidr of props.privateSubnetCidrBlocks) {
|
|
313
|
+
sg.addIngressRule(ec2.Peer.ipv4(cidr), ec2.Port.allTraffic());
|
|
314
|
+
}
|
|
315
|
+
this.sgId = sg.securityGroupId;
|
|
316
|
+
// ── Elastic Network Interface ─────────────────────────────────────────────
|
|
317
|
+
// No L2 ENI construct exists — use L1 directly.
|
|
318
|
+
// source_dest_check=false is required for the instance to forward packets.
|
|
319
|
+
const eni = new ec2.CfnNetworkInterface(this, 'Eni', {
|
|
320
|
+
subnetId: props.publicSubnet.subnetId,
|
|
321
|
+
groupSet: [sg.securityGroupId],
|
|
322
|
+
sourceDestCheck: false,
|
|
323
|
+
description: `ENI for NAT instance ${id}`,
|
|
324
|
+
});
|
|
325
|
+
aws_cdk_lib_1.Tags.of(eni).add('Name', `nat-instance-${id}`);
|
|
326
|
+
this.eniId = eni.ref;
|
|
327
|
+
this.eniPrivateIp = eni.attrPrimaryPrivateIpAddress;
|
|
328
|
+
// ── Private Routes ────────────────────────────────────────────────────────
|
|
329
|
+
// CfnRoute is used because the L2 Route construct does not support
|
|
330
|
+
// targeting a raw ENI as the next hop.
|
|
331
|
+
const routeTableIds = (_e = props.privateRouteTableIds) !== null && _e !== void 0 ? _e : [];
|
|
332
|
+
for (let i = 0; i < routeTableIds.length; i++) {
|
|
333
|
+
new ec2.CfnRoute(this, `PrivateRoute${i}`, {
|
|
334
|
+
routeTableId: routeTableIds[i],
|
|
335
|
+
destinationCidrBlock: '0.0.0.0/0',
|
|
336
|
+
networkInterfaceId: eni.ref,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
// ── IAM Role ──────────────────────────────────────────────────────────────
|
|
340
|
+
const role = new iam.Role(this, 'Role', {
|
|
341
|
+
assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
|
|
342
|
+
});
|
|
343
|
+
// Add SSM managed policy (partition-agnostic when no override provided)
|
|
344
|
+
if (props.ssmPolicyArn) {
|
|
345
|
+
role.addManagedPolicy(iam.ManagedPolicy.fromManagedPolicyArn(this, 'SsmPolicy', props.ssmPolicyArn));
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'));
|
|
349
|
+
}
|
|
350
|
+
// snat.sh calls aws ec2 describe/attach/modify operations at instance boot.
|
|
351
|
+
// Describe actions use wildcard; Attach/Modify are constrained to the dedicated ENI.
|
|
352
|
+
role.addToPrincipalPolicy(new iam.PolicyStatement({
|
|
353
|
+
actions: ['ec2:DescribeNetworkInterfaces', 'ec2:DescribeInstances'],
|
|
354
|
+
resources: ['*'],
|
|
355
|
+
}));
|
|
356
|
+
// AttachNetworkInterface on instances - restricted to instances with matching tag
|
|
357
|
+
// to prevent attaching arbitrary ENIs to arbitrary instances.
|
|
358
|
+
role.addToPrincipalPolicy(new iam.PolicyStatement({
|
|
359
|
+
actions: ['ec2:AttachNetworkInterface'],
|
|
360
|
+
resources: [
|
|
361
|
+
`arn:${cdk.Stack.of(this).partition}:ec2:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:instance/*`,
|
|
362
|
+
],
|
|
363
|
+
conditions: {
|
|
364
|
+
StringEquals: {
|
|
365
|
+
'ec2:ResourceTag/nat-instance-role': natInstanceRoleTag,
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
}));
|
|
369
|
+
// AttachNetworkInterface only on the specific NAT ENI
|
|
370
|
+
role.addToPrincipalPolicy(new iam.PolicyStatement({
|
|
371
|
+
actions: ['ec2:AttachNetworkInterface'],
|
|
372
|
+
resources: [
|
|
373
|
+
`arn:${cdk.Stack.of(this).partition}:ec2:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:network-interface/${eni.ref}`,
|
|
374
|
+
],
|
|
375
|
+
}));
|
|
376
|
+
// ModifyNetworkInterfaceAttribute on network-interfaces within VPC (for primary ENI source/dest check)
|
|
377
|
+
role.addToPrincipalPolicy(new iam.PolicyStatement({
|
|
378
|
+
actions: ['ec2:ModifyNetworkInterfaceAttribute'],
|
|
379
|
+
resources: [
|
|
380
|
+
`arn:${cdk.Stack.of(this).partition}:ec2:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:network-interface/*`,
|
|
381
|
+
],
|
|
382
|
+
conditions: {
|
|
383
|
+
StringEquals: {
|
|
384
|
+
'ec2:Vpc': `arn:${cdk.Stack.of(this).partition}:ec2:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:vpc/${props.vpc.vpcId}`,
|
|
385
|
+
},
|
|
386
|
+
},
|
|
387
|
+
}));
|
|
388
|
+
this.iamRoleName = role.roleName;
|
|
389
|
+
// ── Machine Image ─────────────────────────────────────────────────────────
|
|
390
|
+
const machineImage = props.imageId
|
|
391
|
+
? new RawAmiMachineImage(props.imageId)
|
|
392
|
+
: ec2.MachineImage.latestAmazonLinux2023({
|
|
393
|
+
cpuType: architecture,
|
|
394
|
+
edition: ec2.AmazonLinuxEdition.STANDARD,
|
|
395
|
+
});
|
|
396
|
+
// ── User Data (cloud-init) ────────────────────────────────────────────────
|
|
397
|
+
// /etc/nat.conf tells snat.sh which ENI to attach as eth1 at boot.
|
|
398
|
+
// eni.ref is a CFN token resolved to the ENI resource ID at deploy time.
|
|
399
|
+
const natConfContent = `eni_id=${eni.ref}\n`;
|
|
400
|
+
const cloudConfig = '#cloud-config\n' +
|
|
401
|
+
'write_files:\n' +
|
|
402
|
+
writeFileEntry('/opt/nat/runonce.sh', RUNONCE_SH, '0755') +
|
|
403
|
+
writeFileEntry('/opt/nat/snat.sh', SNAT_SH, '0755') +
|
|
404
|
+
writeFileEntry('/opt/nat/terminate-on-failure.sh', TERMINATE_ON_FAILURE_SH, '0755') +
|
|
405
|
+
writeFileEntry('/etc/systemd/system/snat.service', SNAT_SERVICE) +
|
|
406
|
+
writeFileEntry('/etc/systemd/system/snat-failure.service', SNAT_FAILURE_SERVICE) +
|
|
407
|
+
// nat.conf: plain literal block — ENI ID is alphanumeric+hyphen, safe in YAML
|
|
408
|
+
`- path: /etc/nat.conf\n permissions: '0644'\n content: |\n ${natConfContent}` +
|
|
409
|
+
((_f = props.additionalWriteFiles) !== null && _f !== void 0 ? _f : [])
|
|
410
|
+
.map((f) => writeFileEntry(f.path, f.content, f.permissions))
|
|
411
|
+
.join('') +
|
|
412
|
+
'runcmd:\n' +
|
|
413
|
+
'- ["/opt/nat/runonce.sh"]\n' +
|
|
414
|
+
((_g = props.additionalRunCmds) !== null && _g !== void 0 ? _g : [])
|
|
415
|
+
.map((cmd) => `- [${cmd.map((c) => JSON.stringify(c)).join(', ')}]\n`)
|
|
416
|
+
.join('');
|
|
417
|
+
const userData = ec2.UserData.custom(cloudConfig);
|
|
418
|
+
// ── Launch Template ───────────────────────────────────────────────────────
|
|
419
|
+
const lt = new ec2.LaunchTemplate(this, 'LaunchTemplate', {
|
|
420
|
+
machineImage,
|
|
421
|
+
role,
|
|
422
|
+
userData,
|
|
423
|
+
securityGroup: sg,
|
|
424
|
+
keyPair: props.keyName
|
|
425
|
+
? ec2.KeyPair.fromKeyPairName(this, 'KeyPair', props.keyName)
|
|
426
|
+
: undefined,
|
|
427
|
+
requireImdsv2: true,
|
|
428
|
+
// instanceType is omitted — set via mixedInstancesPolicy overrides below
|
|
429
|
+
});
|
|
430
|
+
// ── Auto Scaling Group ────────────────────────────────────────────────────
|
|
431
|
+
const asg = new autoscaling.AutoScalingGroup(this, 'AutoScalingGroup', {
|
|
432
|
+
vpc: props.vpc,
|
|
433
|
+
// The pinned ENI controls actual AZ placement; vpcSubnets keeps CDK happy.
|
|
434
|
+
vpcSubnets: { subnets: [props.publicSubnet] },
|
|
435
|
+
minCapacity: enabled ? 1 : 0,
|
|
436
|
+
maxCapacity: 1,
|
|
437
|
+
desiredCapacity: enabled ? 1 : 0,
|
|
438
|
+
healthCheck: autoscaling.HealthCheck.ec2({
|
|
439
|
+
// Extended grace period to allow NAT setup to complete.
|
|
440
|
+
// Note: This only checks EC2 instance health, not NAT setup success directly.
|
|
441
|
+
// However, snat.service is configured to retry on failure and will terminate
|
|
442
|
+
// the instance if all retries are exhausted, triggering ASG replacement.
|
|
443
|
+
grace: cdk.Duration.minutes(5),
|
|
444
|
+
}),
|
|
445
|
+
mixedInstancesPolicy: {
|
|
446
|
+
launchTemplate: lt,
|
|
447
|
+
instancesDistribution: {
|
|
448
|
+
onDemandBaseCapacity: useSpotInstance ? 0 : 1,
|
|
449
|
+
onDemandPercentageAboveBaseCapacity: useSpotInstance ? 0 : 100,
|
|
450
|
+
},
|
|
451
|
+
launchTemplateOverrides: instanceTypes.map((it) => ({
|
|
452
|
+
instanceType: it,
|
|
453
|
+
})),
|
|
454
|
+
},
|
|
455
|
+
});
|
|
456
|
+
// Tag the ASG instances with the unique identifier used in IAM conditions.
|
|
457
|
+
// This tag is propagated to instances and restricts IAM permissions to self-only operations.
|
|
458
|
+
aws_cdk_lib_1.Tags.of(asg).add('nat-instance-role', natInstanceRoleTag);
|
|
459
|
+
// Allow instance to terminate itself on unrecoverable NAT setup failure.
|
|
460
|
+
// Restricted to instances with the matching nat-instance-role tag,
|
|
461
|
+
// ensuring the instance can only terminate itself, not other instances in the VPC.
|
|
462
|
+
role.addToPrincipalPolicy(new iam.PolicyStatement({
|
|
463
|
+
actions: ['ec2:TerminateInstances'],
|
|
464
|
+
resources: [
|
|
465
|
+
`arn:${cdk.Stack.of(this).partition}:ec2:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:instance/*`,
|
|
466
|
+
],
|
|
467
|
+
conditions: {
|
|
468
|
+
StringEquals: {
|
|
469
|
+
'ec2:ResourceTag/nat-instance-role': natInstanceRoleTag,
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
}));
|
|
473
|
+
// Use rolling update to avoid race condition with ENI attachment.
|
|
474
|
+
// autoScalingReplacingUpdate can create overlapping instances that both
|
|
475
|
+
// try to attach the singleton ENI, causing the boot script to fail.
|
|
476
|
+
const cfnAsg = asg.node.defaultChild;
|
|
477
|
+
cfnAsg.cfnOptions.updatePolicy = {
|
|
478
|
+
autoScalingRollingUpdate: {
|
|
479
|
+
maxBatchSize: 1,
|
|
480
|
+
minInstancesInService: 0,
|
|
481
|
+
pauseTime: 'PT5M',
|
|
482
|
+
},
|
|
483
|
+
};
|
|
484
|
+
aws_cdk_lib_1.Tags.of(asg).add('Name', `nat-instance-${id}`);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
exports.NatInstance = NatInstance;
|
|
488
|
+
/**
|
|
489
|
+
* Minimal IMachineImage implementation for a caller-supplied AMI ID.
|
|
490
|
+
*
|
|
491
|
+
* MachineImage.genericLinux() requires a concrete region key at synth time,
|
|
492
|
+
* which breaks environment-agnostic stacks. This implementation passes the
|
|
493
|
+
* AMI ID through directly and lets CloudFormation handle region resolution.
|
|
494
|
+
*/
|
|
495
|
+
class RawAmiMachineImage {
|
|
496
|
+
constructor(amiId) {
|
|
497
|
+
this.amiId = amiId;
|
|
498
|
+
}
|
|
499
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
500
|
+
getImage(_scope) {
|
|
501
|
+
return {
|
|
502
|
+
imageId: this.amiId,
|
|
503
|
+
osType: ec2.OperatingSystemType.LINUX,
|
|
504
|
+
userData: ec2.UserData.forLinux(),
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF0LWluc3RhbmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2F3cy12cGMvbGliL25hdC1pbnN0YW5jZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBbUM7QUFDbkMsNkNBQWlDO0FBQ2pDLDJEQUEyRDtBQUMzRCwyQ0FBMkM7QUFDM0MsMkNBQTJDO0FBRTNDLCtDQUk2QjtBQUM3Qiw2Q0FBK0M7QUFFL0MsbUVBQW1FO0FBQ25FLDRFQUE0RTtBQUM1RSx3REFBd0Q7QUFFeEQsTUFBTSxPQUFPLEdBQUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0F1SmYsQ0FBQztBQUVGLE1BQU0sWUFBWSxHQUFHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBc0JwQixDQUFDO0FBRUYsTUFBTSxvQkFBb0IsR0FBRzs7Ozs7OztDQU81QixDQUFDO0FBRUYsTUFBTSx1QkFBdUIsR0FBRzs7Ozs7Ozs7O0NBUy9CLENBQUM7QUFFRixNQUFNLFVBQVUsR0FBRzs7Ozs7Q0FLbEIsQ0FBQztBQThHRjs7Ozs7R0FLRztBQUNILFNBQVMsa0JBQWtCLENBQUMsT0FBZTtJQUN6QyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xDLGlFQUFpRTtJQUNqRSwyRUFBMkU7SUFDM0UsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQztRQUNuQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDZCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUs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WUFBWSxFQUFFO29CQUNaLG1DQUFtQyxFQUFFLGtCQUFrQjtpQkFDeEQ7YUFDRjtTQUNGLENBQUMsQ0FDSCxDQUFDO1FBRUYsa0VBQWtFO1FBQ2xFLHdFQUF3RTtRQUN4RSxvRUFBb0U7UUFDcEUsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxZQUErQyxDQUFDO1FBQ3hFLE1BQU0sQ0FBQyxVQUFVLENBQUMsWUFBWSxHQUFHO1lBQy9CLHdCQUF3QixFQUFFO2dCQUN4QixZQUFZLEVBQUUsQ0FBQztnQkFDZixxQkFBcUIsRUFBRSxDQUFDO2dCQUN4QixTQUFTLEVBQUUsTUFBTTthQUNsQjtTQUNGLENBQUM7UUFFRixrQkFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLGdCQUFnQixFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ2pELENBQUM7Q0FDRjtBQWhSRCxrQ0FnUkM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLGtCQUFrQjtJQUN0QixZQUE2QixLQUFhO1FBQWIsVUFBSyxHQUFMLEtBQUssQ0FBUTtJQUFHLENBQUM7SUFFOUMsNkRBQTZEO0lBQzdELFFBQVEsQ0FBQyxNQUFpQjtRQUN4QixPQUFPO1lBQ0wsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLO1lBQ25CLE1BQU0sRUFBRSxHQUFHLENBQUMsbUJBQW1CLENBQUMsS0FBSztZQUNyQyxRQUFRLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUU7U0FDbEMsQ0FBQztJQUNKLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQge1RhZ3N9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGF1dG9zY2FsaW5nIGZyb20gJ2F3cy1jZGstbGliL2F3cy1hdXRvc2NhbGluZyc7XG5pbXBvcnQgKiBhcyBlYzIgZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjMic7XG5pbXBvcnQgKiBhcyBpYW0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgdHlwZSB7Q29uc3RydWN0fSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7XG4gIEV4dGVuZGVkQ29uc3RydWN0LFxuICB0eXBlIEV4dGVuZGVkQ29uc3RydWN0UHJvcHMsXG4gIFN0YW5kYXJkVGFncyxcbn0gZnJvbSAnLi4vLi4vYXdzLWNkay9pbmRleCc7XG5pbXBvcnQge0xpYlN0YW5kYXJkVGFnc30gZnJvbSAnLi4vLi4vdHJ1ZW1hcmsnO1xuXG4vLyBWZXJiYXRpbSBjb250ZW50IG9mIHRoZSBzdGFydHVwIHNjcmlwdHMsIGVtYmVkZGVkIGF0IGJ1aWxkIHRpbWUuXG4vLyBTaGVsbCBgJHZhcmAgYW5kIGAkKGNtZClgIHJlZmVyZW5jZXMgYXJlIGVzY2FwZWQgYXMgYFxcJHt2YXJ9YCAvIGBcXCQoY21kKWBcbi8vIHRvIHByZXZlbnQgVHlwZVNjcmlwdCB0ZW1wbGF0ZS1saXRlcmFsIGludGVycG9sYXRpb24uXG5cbmNvbnN0IFNOQVRfU0ggPSBgIyEvYmluL3NoXG5zZXQgLWVcbmRuZiBpbnN0YWxsIC15IGlwdGFibGVzLXNlcnZpY2VzIGF3c2NsaSB8fCB5dW0gaW5zdGFsbCAteSBpcHRhYmxlcy1zZXJ2aWNlcyBhd3NjbGlcbmlmIHRlc3QgLWYgXCIvZXRjL25hdC5jb25mXCI7IHRoZW5cbiAgICBlY2hvIFwiRm91bmQgbmF0IGNvbmZpZ3VyYXRpb24gYXQgL2V0Yy9uYXQuY29uZlwiXG4gICAgLiAvZXRjL25hdC5jb25mXG5lbHNlXG4gICAgZWNobyBcIk5vIG5hdCBjb25maWd1cmF0aW9uIGF0IC9ldGMvbmF0LmNvbmZcIlxuZmlcbnRva2VuPVwiJChjdXJsIC1zUyAtWCBQVVQgLUggJ1gtYXdzLWVjMi1tZXRhZGF0YS10b2tlbi10dGwtc2Vjb25kczogMzAwJyBodHRwOi8vMTY5LjI1NC4xNjkuMjU0L2xhdGVzdC9hcGkvdG9rZW4pXCJcbmF3c19yZWdpb249XCIkKGN1cmwgLXNTIC1IIFwiWC1hd3MtZWMyLW1ldGFkYXRhLXRva2VuOiBcXCR7dG9rZW59XCIgaHR0cDovLzE2OS4yNTQuMTY5LjI1NC9sYXRlc3QvbWV0YS1kYXRhL3BsYWNlbWVudC9yZWdpb24pXCJcbmluc3RhbmNlX2lkPVwiJChjdXJsIC1zUyAtSCBcIlgtYXdzLWVjMi1tZXRhZGF0YS10b2tlbjogXFwke3Rva2VufVwiIGh0dHA6Ly8xNjkuMjU0LjE2OS4yNTQvbGF0ZXN0L21ldGEtZGF0YS9pbnN0YW5jZS1pZClcIlxuIyBEbyBub3QgYXNzdW1lIHRoZSBwcmltYXJ5IGludGVyZmFjZSBpcyBuYW1lZCBldGgwLlxuIyBVc2UgdGhlIGludGVyZmFjZSB0aGF0IG93bnMgdGhlIGRlZmF1bHQgcm91dGUuXG5wcmltYXJ5X2ludGVyZmFjZT1cIiQoaXAgcm91dGUgfCBhd2sgJy9kZWZhdWx0LyB7cHJpbnQgJDU7IGV4aXR9JylcIlxuaWYgdGVzdCAteiBcIlxcJHtwcmltYXJ5X2ludGVyZmFjZX1cIjsgdGhlblxuICAgIGVjaG8gXCJDb3VsZCBub3QgZGV0ZXJtaW5lIHByaW1hcnkvZGVmYXVsdCBuZXR3b3JrIGludGVyZmFjZVwiXG4gICAgaXAgcm91dGVcbiAgICBleGl0IDFcbmZpXG5wcmltYXJ5X21hYz1cIiQoY2F0IC9zeXMvY2xhc3MvbmV0L1xcJHtwcmltYXJ5X2ludGVyZmFjZX0vYWRkcmVzcylcIlxuZWNobyBcIlByaW1hcnkvZGVmYXVsdCBpbnRlcmZhY2UgaXMgXFwke3ByaW1hcnlfaW50ZXJmYWNlfSB3aXRoIE1BQyBcXCR7cHJpbWFyeV9tYWN9XCJcbmlmIHRlc3QgLW4gXCJcXCR7ZW5pX2lkfVwiOyB0aGVuXG4gICAgZWNobyBcIkZvdW5kIGVuaV9pZCBjb25maWd1cmF0aW9uLCBhdHRhY2hpbmcgXFwke2VuaV9pZH0uLi5cIlxuICAgIHByaW1hcnlfZW5pX2lkPVwiJChjdXJsIC1zUyAtSCBcIlgtYXdzLWVjMi1tZXRhZGF0YS10b2tlbjogXFwke3Rva2VufVwiIGh0dHA6Ly8xNjkuMjU0LjE2OS4yNTQvbGF0ZXN0L21ldGEtZGF0YS9uZXR3b3JrL2ludGVyZmFjZXMvbWFjcy9cXCR7cHJpbWFyeV9tYWN9L2ludGVyZmFjZS1pZClcIlxuICAgIGVjaG8gXCJEaXNhYmxpbmcgc291cmNlL2Rlc3QgY2hlY2sgb24gcHJpbWFyeSBFTkkgXFwke3ByaW1hcnlfZW5pX2lkfS4uLlwiXG4gICAgYXdzIGVjMiBtb2RpZnktbmV0d29yay1pbnRlcmZhY2UtYXR0cmlidXRlIFxcXFxcbiAgICAgICAgLS1yZWdpb24gXCJcXCR7YXdzX3JlZ2lvbn1cIiBcXFxcXG4gICAgICAgIC0tbmV0d29yay1pbnRlcmZhY2UtaWQgXCJcXCR7cHJpbWFyeV9lbmlfaWR9XCIgXFxcXFxuICAgICAgICAtLXNvdXJjZS1kZXN0LWNoZWNrICd7XCJWYWx1ZVwiOmZhbHNlfSdcbiAgICBlY2hvIFwiRGlzYWJsaW5nIHNvdXJjZS9kZXN0IGNoZWNrIG9uIE5BVCBFTkkgXFwke2VuaV9pZH0uLi5cIlxuICAgIGF3cyBlYzIgbW9kaWZ5LW5ldHdvcmstaW50ZXJmYWNlLWF0dHJpYnV0ZSBcXFxcXG4gICAgICAgIC0tcmVnaW9uIFwiXFwke2F3c19yZWdpb259XCIgXFxcXFxuICAgICAgICAtLW5ldHdvcmstaW50ZXJmYWNlLWlkIFwiXFwke2VuaV9pZH1cIiBcXFxcXG4gICAgICAgIC0tc291cmNlLWRlc3QtY2hlY2sgJ3tcIlZhbHVlXCI6ZmFsc2V9J1xuICAgIGVjaG8gXCJDaGVja2luZyBjdXJyZW50IGF0dGFjaG1lbnQgc3RhdGUgZm9yIE5BVCBFTkkgXFwke2VuaV9pZH0uLi5cIlxuICAgIGF0dGFjaGVkX2luc3RhbmNlX2lkPVwiJChhd3MgZWMyIGRlc2NyaWJlLW5ldHdvcmstaW50ZXJmYWNlcyBcXFxcXG4gICAgICAgIC0tcmVnaW9uIFwiXFwke2F3c19yZWdpb259XCIgXFxcXFxuICAgICAgICAtLW5ldHdvcmstaW50ZXJmYWNlLWlkcyBcIlxcJHtlbmlfaWR9XCIgXFxcXFxuICAgICAgICAtLXF1ZXJ5ICdOZXR3b3JrSW50ZXJmYWNlc1swXS5BdHRhY2htZW50Lkluc3RhbmNlSWQnIFxcXFxcbiAgICAgICAgLS1vdXRwdXQgdGV4dCAyPi9kZXYvbnVsbCB8fCB0cnVlKVwiXG4gICAgaWYgdGVzdCBcIlxcJHthdHRhY2hlZF9pbnN0YW5jZV9pZH1cIiA9IFwiXFwke2luc3RhbmNlX2lkfVwiOyB0aGVuXG4gICAgICAgIGVjaG8gXCJOQVQgRU5JIFxcJHtlbmlfaWR9IGlzIGFscmVhZHkgYXR0YWNoZWQgdG8gdGhpcyBpbnN0YW5jZS5cIlxuICAgIGVsaWYgdGVzdCAtbiBcIlxcJHthdHRhY2hlZF9pbnN0YW5jZV9pZH1cIiAmJiB0ZXN0IFwiXFwke2F0dGFjaGVkX2luc3RhbmNlX2lkfVwiICE9IFwiTm9uZVwiOyB0aGVuXG4gICAgICAgIGVjaG8gXCJOQVQgRU5JIFxcJHtlbmlfaWR9IGlzIGF0dGFjaGVkIHRvIGFub3RoZXIgaW5zdGFuY2U6IFxcJHthdHRhY2hlZF9pbnN0YW5jZV9pZH1cIlxuICAgICAgICBlY2hvIFwiVGhpcyBtYXkgYmUgdGhlIHByZXZpb3VzIGluc3RhbmNlIGR1cmluZyByZXBsYWNlbWVudC4gUmV0cnlpbmcgZm9yIHVwIHRvIDYwIHNlY29uZHMuLi5cIlxuICAgICAgICBmb3IgcmV0cnkgaW4gJChzZXEgMSAxMik7IGRvXG4gICAgICAgICAgICBzbGVlcCA1XG4gICAgICAgICAgICBhdHRhY2hlZF9pbnN0YW5jZV9pZD1cIiQoYXdzIGVjMiBkZXNjcmliZS1uZXR3b3JrLWludGVyZmFjZXMgXFxcXFxuICAgICAgICAgICAgICAgIC0tcmVnaW9uIFwiXFwke2F3c19yZWdpb259XCIgXFxcXFxuICAgICAgICAgICAgICAgIC0tbmV0d29yay1pbnRlcmZhY2UtaWRzIFwiXFwke2VuaV9pZH1cIiBcXFxcXG4gICAgICAgICAgICAgICAgLS1xdWVyeSAnTmV0d29ya0ludGVyZmFjZXNbMF0uQXR0YWNobWVudC5JbnN0YW5jZUlkJyBcXFxcXG4gICAgICAgICAgICAgICAgLS1vdXRwdXQgdGV4dCAyPi9kZXYvbnVsbCB8fCB0cnVlKVwiXG4gICAgICAgICAgICBpZiB0ZXN0IFwiXFwke2F0dGFjaGVkX2luc3RhbmNlX2lkfVwiID0gXCJcXCR7aW5zdGFuY2VfaWR9XCI7IHRoZW5cbiAgICAgICAgICAgICAgICBlY2hvIFwiRU5JIGlzIG5vdyBhdHRhY2hlZCB0byB0aGlzIGluc3RhbmNlLlwiXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGVsaWYgdGVzdCAteiBcIlxcJHthdHRhY2hlZF9pbnN0YW5jZV9pZH1cIiB8fCB0ZXN0IFwiXFwke2F0dGFjaGVkX2luc3RhbmNlX2lkfVwiID0gXCJOb25lXCI7IHRoZW5cbiAgICAgICAgICAgICAgICBlY2hvIFwiRU5JIGlzIG5vdyBhdmFpbGFibGUuIFByb2NlZWRpbmcgd2l0aCBhdHRhY2htZW50LlwiXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGZpXG4gICAgICAgICAgICBlY2hvIFwiUmV0cnkgXFwke3JldHJ5fS8xMjogRU5JIHN0aWxsIGF0dGFjaGVkIHRvIFxcJHthdHRhY2hlZF9pbnN0YW5jZV9pZH1cIlxuICAgICAgICBkb25lXG4gICAgICAgIGlmIHRlc3QgLW4gXCJcXCR7YXR0YWNoZWRfaW5zdGFuY2VfaWR9XCIgJiYgdGVzdCBcIlxcJHthdHRhY2hlZF9pbnN0YW5jZV9pZH1cIiAhPSBcIk5vbmVcIiAmJiB0ZXN0IFwiXFwke2F0dGFjaGVkX2luc3RhbmNlX2lkfVwiICE9IFwiXFwke2luc3RhbmNlX2lkfVwiOyB0aGVuXG4gICAgICAgICAgICBlY2hvIFwiRVJST1I6IEVOSSBcXCR7ZW5pX2lkfSBpcyBzdGlsbCBhdHRhY2hlZCB0byBhbm90aGVyIGluc3RhbmNlIGFmdGVyIHJldHJpZXM6IFxcJHthdHRhY2hlZF9pbnN0YW5jZV9pZH1cIlxuICAgICAgICAgICAgIyBTeXN0ZW1kIHdpbGwgcmV0cnkgdGhpcyBzZXJ2aWNlLiBJZiBhbGwgc3lzdGVtZCByZXRyaWVzIGFyZSBleGhhdXN0ZWQsIHRlcm1pbmF0ZS5cbiAgICAgICAgICAgIGV4aXQgMVxuICAgICAgICBmaVxuICAgIGZpXG4gICAgaWYgdGVzdCBcIlxcJHthdHRhY2hlZF9pbnN0YW5jZV9pZH1cIiAhPSBcIlxcJHtpbnN0YW5jZV9pZH1cIjsgdGhlblxuICAgICAgICBlY2hvIFwiQXR0YWNoaW5nIE5BVCBFTkkgXFwke2VuaV9pZH0gdG8gaW5zdGFuY2UgXFwke2luc3RhbmNlX2lkfS4uLlwiXG4gICAgICAgICMgVXNlIGlmIHN0YXRlbWVudCB0byBjYXB0dXJlIGV4aXQgc3RhdHVzIGJlZm9yZSBlcnJleGl0IHRyaWdnZXJzXG4gICAgICAgIGlmIGF0dGFjaF9vdXRwdXQ9XCIkKGF3cyBlYzIgYXR0YWNoLW5ldHdvcmstaW50ZXJmYWNlIFxcXFxcbiAgICAgICAgICAgIC0tcmVnaW9uIFwiXFwke2F3c19yZWdpb259XCIgXFxcXFxuICAgICAgICAgICAgLS1pbnN0YW5jZS1pZCBcIlxcJHtpbnN0YW5jZV9pZH1cIiBcXFxcXG4gICAgICAgICAgICAtLWRldmljZS1pbmRleCAxIFxcXFxcbiAgICAgICAgICAgIC0tbmV0d29yay1pbnRlcmZhY2UtaWQgXCJcXCR7ZW5pX2lkfVwiIDI+JjEpXCI7IHRoZW5cbiAgICAgICAgICAgIGVjaG8gXCJcXCR7YXR0YWNoX291dHB1dH1cIlxuICAgICAgICAgICAgZWNobyBcIkVOSSBhdHRhY2hlZCBzdWNjZXNzZnVsbHkuXCJcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgYXR0YWNoX3N0YXR1cz0kP1xuICAgICAgICAgICAgZWNobyBcIlxcJHthdHRhY2hfb3V0cHV0fVwiXG4gICAgICAgICAgICBlY2hvIFwiRmFpbGVkIHRvIGF0dGFjaCBOQVQgRU5JIFxcJHtlbmlfaWR9IHdpdGggc3RhdHVzIFxcJHthdHRhY2hfc3RhdHVzfVwiXG4gICAgICAgICAgICBleGl0IFwiXFwke2F0dGFjaF9zdGF0dXN9XCJcbiAgICAgICAgZmlcbiAgICBmaVxuICAgIGVjaG8gXCJXYWl0aW5nIGZvciBOQVQgRU5JIFxcJHtlbmlfaWR9IHRvIGFwcGVhciBpbiBtZXRhZGF0YS4uLlwiXG4gICAgbmF0X2VuaV9tYWM9XCJcIlxuICAgIGZvciBhdHRlbXB0IGluICQoc2VxIDEgNjApOyBkb1xuICAgICAgICBmb3IgbWFjIGluICQoY3VybCAtc1MgLUggXCJYLWF3cy1lYzItbWV0YWRhdGEtdG9rZW46IFxcJHt0b2tlbn1cIiBodHRwOi8vMTY5LjI1NC4xNjkuMjU0L2xhdGVzdC9tZXRhLWRhdGEvbmV0d29yay9pbnRlcmZhY2VzL21hY3MvKTsgZG9cbiAgICAgICAgICAgIGludGVyZmFjZV9pZD1cIiQoY3VybCAtc1MgLUggXCJYLWF3cy1lYzItbWV0YWRhdGEtdG9rZW46IFxcJHt0b2tlbn1cIiBodHRwOi8vMTY5LjI1NC4xNjkuMjU0L2xhdGVzdC9tZXRhLWRhdGEvbmV0d29yay9pbnRlcmZhY2VzL21hY3MvXFwke21hY31pbnRlcmZhY2UtaWQpXCJcbiAgICAgICAgICAgIGlmIHRlc3QgXCJcXCR7aW50ZXJmYWNlX2lkfVwiID0gXCJcXCR7ZW5pX2lkfVwiOyB0aGVuXG4gICAgICAgICAgICAgICAgbmF0X2VuaV9tYWM9XCIkKGVjaG8gXCJcXCR7bWFjfVwiIHwgc2VkICdzIy8kIyMnKVwiXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGZpXG4gICAgICAgIGRvbmVcbiAgICAgICAgaWYgdGVzdCAtbiBcIlxcJHtuYXRfZW5pX21hY31cIjsgdGhlblxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgZmlcbiAgICAgICAgZWNobyBcIldhaXRpbmcgZm9yIEVOSSBtZXRhZGF0YS4uLlwiXG4gICAgICAgIHNsZWVwIDJcbiAgICBkb25lXG4gICAgaWYgdGVzdCAteiBcIlxcJHtuYXRfZW5pX21hY31cIjsgdGhlblxuICAgICAgICBlY2hvIFwiQ291bGQgbm90IGZpbmQgTUFDIGFkZHJlc3MgZm9yIE5BVCBFTkkgXFwke2VuaV9pZH1cIlxuICAgICAgICBleGl0IDFcbiAgICBmaVxuICAgIG5hdF9lbmlfbGludXhfZGV2aWNlPVwiXCJcbiAgICBmb3IgZGV2IGluICQobHMgL3N5cy9jbGFzcy9uZXQpOyBkb1xuICAgICAgICBkZXZfbWFjPVwiJChjYXQgL3N5cy9jbGFzcy9uZXQvXFwke2Rldn0vYWRkcmVzcyAyPi9kZXYvbnVsbCB8fCB0cnVlKVwiXG4gICAgICAgIGlmIHRlc3QgXCJcXCR7ZGV2X21hY31cIiA9IFwiXFwke25hdF9lbmlfbWFjfVwiOyB0aGVuXG4gICAgICAgICAgICBuYXRfZW5pX2xpbnV4X2RldmljZT1cIlxcJHtkZXZ9XCJcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgIGZpXG4gICAgZG9uZVxuICAgIGlmIHRlc3QgLXogXCJcXCR7bmF0X2VuaV9saW51eF9kZXZpY2V9XCI7IHRoZW5cbiAgICAgICAgZWNobyBcIkNvdWxkIG5vdCBtYXAgTkFUIEVOSSBNQUMgXFwke25hdF9lbmlfbWFjfSB0byBMaW51eCBuZXR3b3JrIGRldmljZVwiXG4gICAgICAgIGlwIGxpbmsgc2hvd1xuICAgICAgICBleGl0IDFcbiAgICBmaVxuICAgIGVjaG8gXCJOQVQgRU5JIFxcJHtlbmlfaWR9IGlzIExpbnV4IGRldmljZSBcXCR7bmF0X2VuaV9saW51eF9kZXZpY2V9XCJcbiAgICAjIFByaXZhdGUgc3VibmV0IHJvdXRlcyB0YXJnZXQgdGhlIE5BVCBFTkkgZm9yIHN0YWJsZSByb3V0aW5nLCBidXQgb3V0Ym91bmRcbiAgICAjIFNOQVQgbGVhdmVzIHRocm91Z2ggdGhlIHByaW1hcnkgaW50ZXJmYWNlICh3aGljaCBoYXMgdGhlIGF1dG8tYXNzaWduZWRcbiAgICAjIHB1YmxpYyBJUCBvciBtYW51YWxseSBhdHRhY2hlZCBFSVApLiBTZWNvbmRhcnkgRU5JcyBkb24ndCBnZXQgYXV0by1hc3NpZ25lZFxuICAgICMgcHVibGljIElQcywgYW5kIHNldHRpbmcgdXAgcG9saWN5IHJvdXRpbmcgdGhyb3VnaCBldGgxIGlzIGNvbXBsZXguXG4gICAgbmF0X2ludGVyZmFjZT1cIlxcJHtwcmltYXJ5X2ludGVyZmFjZX1cIlxuICAgIGVjaG8gXCJVc2luZyBvdXRib3VuZCBOQVQgaW50ZXJmYWNlIFxcJHtuYXRfaW50ZXJmYWNlfVwiXG5lbGlmIHRlc3QgLW4gXCJcXCR7aW50ZXJmYWNlfVwiOyB0aGVuXG4gICAgZWNobyBcIkZvdW5kIGludGVyZmFjZSBjb25maWd1cmF0aW9uLCB1c2luZyBcXCR7aW50ZXJmYWNlfVwiXG4gICAgbmF0X2ludGVyZmFjZT1cIlxcJHtpbnRlcmZhY2V9XCJcbmVsc2VcbiAgICBuYXRfaW50ZXJmYWNlPVwiXFwke3ByaW1hcnlfaW50ZXJmYWNlfVwiXG4gICAgZWNobyBcIk5vIGVuaV9pZCBvciBpbnRlcmZhY2UgY29uZmlndXJhdGlvbiBmb3VuZCwgdXNpbmcgZGVmYXVsdCBpbnRlcmZhY2UgXFwke25hdF9pbnRlcmZhY2V9XCJcbmZpXG5lY2hvIFwiRW5hYmxpbmcgaXBfZm9yd2FyZC4uLlwiXG5zeXNjdGwgLXEgLXcgbmV0LmlwdjQuaXBfZm9yd2FyZD0xXG5lY2hvIFwibmV0LmlwdjQuaXBfZm9yd2FyZCA9IDFcIiA+IC9ldGMvc3lzY3RsLmQvOTktbmF0LmNvbmZcbmVjaG8gXCJEaXNhYmxpbmcgcmV2ZXJzZSBwYXRoIHByb3RlY3Rpb24uLi5cIlxuZm9yIGkgaW4gJChmaW5kIC9wcm9jL3N5cy9uZXQvaXB2NC9jb25mLyAtbmFtZSBycF9maWx0ZXIpOyBkb1xuICBlY2hvIDAgPiBcIlxcJHtpfVwiO1xuZG9uZVxuY2F0ID4gL2V0Yy9zeXNjdGwuZC85OC1kaXNhYmxlLXJwLWZpbHRlci5jb25mIDw8J0VPRidcbm5ldC5pcHY0LmNvbmYuYWxsLnJwX2ZpbHRlciA9IDBcbm5ldC5pcHY0LmNvbmYuZGVmYXVsdC5ycF9maWx0ZXIgPSAwXG5FT0ZcbmVjaG8gXCJGbHVzaGluZyBOQVQgdGFibGUuLi5cIlxuaXB0YWJsZXMgLXQgbmF0IC1GXG5lY2hvIFwiQWRkaW5nIE5BVCBydWxlLi4uXCJcbmlwdGFibGVzIC10IG5hdCAtQSBQT1NUUk9VVElORyAtbyBcIlxcJHtuYXRfaW50ZXJmYWNlfVwiIC1qIE1BU1FVRVJBREUgLW0gY29tbWVudCAtLWNvbW1lbnQgXCJOQVQgcm91dGluZyBydWxlIGluc3RhbGxlZFwiXG5lY2hvIFwiQ3VycmVudCBOQVQgdGFibGU6XCJcbmlwdGFibGVzIC10IG5hdCAtTCAtbiAtdlxuc2VydmljZSBpcHRhYmxlcyBzYXZlIHx8IHRydWVcbmVjaG8gXCJEb25lIVwiXG5gO1xuXG5jb25zdCBTTkFUX1NFUlZJQ0UgPSBgW1VuaXRdXG5EZXNjcmlwdGlvbiA9IENvbmZpZ3VyZSB0aGlzIG1hY2hpbmUgdG8gYWN0IGFzIGEgTkFUIGluc3RhbmNlLlxuV2FudHMgPSBuZXR3b3JrLW9ubGluZS50YXJnZXRcbkFmdGVyID0gbmV0d29yay1vbmxpbmUudGFyZ2V0XG4jIElmIE5BVCBzZXR1cCBmYWlscyBhZnRlciBhbGwgcmV0cmllcywgdGVybWluYXRlIHRoZSBpbnN0YW5jZSBzbyBBU0cgcmVwbGFjZXMgaXRcbk9uRmFpbHVyZSA9IHNuYXQtZmFpbHVyZS5zZXJ2aWNlXG4jIExpbWl0IHRvdGFsIHJldHJpZXMgdG8gMTAgYXR0ZW1wdHMgd2l0aGluIGEgMTAtbWludXRlIHdpbmRvdy5cbiMgV2l0aCBSZXN0YXJ0U2VjPTMwcywgMTAgYXR0ZW1wdHMgdGFrZSB+NSBtaW51dGVzOyB0aGlzIHdpbmRvdyBlbnN1cmVzXG4jIHRoZSAxMHRoIGZhaWx1cmUgdHJpZ2dlcnMgT25GYWlsdXJlIHJhdGhlciB0aGFuIHJlc2V0dGluZyB0aGUgYnVyc3QgY291bnRlci5cblN0YXJ0TGltaXRJbnRlcnZhbFNlYyA9IDYwMFxuU3RhcnRMaW1pdEJ1cnN0ID0gMTBcblxuW1NlcnZpY2VdXG5FeGVjU3RhcnQgPSAvb3B0L25hdC9zbmF0LnNoXG5UeXBlID0gb25lc2hvdFxuIyBSZXRyeSBvbiBmYWlsdXJlIHRvIGhhbmRsZSB0cmFuc2llbnQgRU5JIGF0dGFjaG1lbnQgaXNzdWVzIGR1cmluZyBBU0cgcmVwbGFjZW1lbnQuXG4jIElmIEVOSSBpcyBzdGlsbCBhdHRhY2hlZCB0byBwcmV2aW91cyBpbnN0YW5jZSwgc3lzdGVtZCB3aWxsIHJldHJ5IGFmdGVyIDMwcy5cblJlc3RhcnQgPSBvbi1mYWlsdXJlXG5SZXN0YXJ0U2VjID0gMzBzXG5cbltJbnN0YWxsXVxuV2FudGVkQnkgPSBtdWx0aS11c2VyLnRhcmdldFxuYDtcblxuY29uc3QgU05BVF9GQUlMVVJFX1NFUlZJQ0UgPSBgW1VuaXRdXG5EZXNjcmlwdGlvbiA9IFRlcm1pbmF0ZSBOQVQgaW5zdGFuY2UgYWZ0ZXIgdW5yZWNvdmVyYWJsZSBzZXR1cCBmYWlsdXJlXG5EZWZhdWx0RGVwZW5kZW5jaWVzID0gbm9cblxuW1NlcnZpY2VdXG5UeXBlID0gb25lc2hvdFxuRXhlY1N0YXJ0ID0gL29wdC9uYXQvdGVybWluYXRlLW9uLWZhaWx1cmUuc2hcbmA7XG5cbmNvbnN0IFRFUk1JTkFURV9PTl9GQUlMVVJFX1NIID0gYCMhL2Jpbi9zaFxuIyBUaGlzIHNjcmlwdCBpcyBpbnZva2VkIGJ5IHNuYXQtZmFpbHVyZS5zZXJ2aWNlIHdoZW4gTkFUIHNldHVwIGZhaWxzIGFmdGVyIGFsbCByZXRyaWVzLlxuIyBUZXJtaW5hdGluZyB0aGUgaW5zdGFuY2UgdHJpZ2dlcnMgQVNHIHRvIHJlcGxhY2UgaXQsIHByZXZlbnRpbmcgYmxhY2tob2xlZCByb3V0ZXMuXG5zZXQgLWV4XG50b2tlbj1cIiQoY3VybCAtc1MgLVggUFVUIC1IICdYLWF3cy1lYzItbWV0YWRhdGEtdG9rZW4tdHRsLXNlY29uZHM6IDMwMCcgaHR0cDovLzE2OS4yNTQuMTY5LjI1NC9sYXRlc3QvYXBpL3Rva2VuKVwiXG5hd3NfcmVnaW9uPVwiJChjdXJsIC1zUyAtSCBcIlgtYXdzLWVjMi1tZXRhZGF0YS10b2tlbjogXFwke3Rva2VufVwiIGh0dHA6Ly8xNjkuMjU0LjE2OS4yNTQvbGF0ZXN0L21ldGEtZGF0YS9wbGFjZW1lbnQvcmVnaW9uKVwiXG5pbnN0YW5jZV9pZD1cIiQoY3VybCAtc1MgLUggXCJYLWF3cy1lYzItbWV0YWRhdGEtdG9rZW46IFxcJHt0b2tlbn1cIiBodHRwOi8vMTY5LjI1NC4xNjkuMjU0L2xhdGVzdC9tZXRhLWRhdGEvaW5zdGFuY2UtaWQpXCJcbmVjaG8gXCJGQVRBTDogTkFUIHNldHVwIGZhaWxlZCBhZnRlciBhbGwgcmV0cmllcy4gVGVybWluYXRpbmcgaW5zdGFuY2UgXFwke2luc3RhbmNlX2lkfSB0byB0cmlnZ2VyIEFTRyByZXBsYWNlbWVudC4uLlwiXG5hd3MgZWMyIHRlcm1pbmF0ZS1pbnN0YW5jZXMgLS1pbnN0YW5jZS1pZHMgXCJcXCR7aW5zdGFuY2VfaWR9XCIgLS1yZWdpb24gXCJcXCR7YXdzX3JlZ2lvbn1cIlxuYDtcblxuY29uc3QgUlVOT05DRV9TSCA9IGAjIS9iaW4vYmFzaCAteFxuXG4jIHN0YXJ0IFNOQVRcbnN5c3RlbWN0bCBlbmFibGUgc25hdFxuc3lzdGVtY3RsIHN0YXJ0IHNuYXRcbmA7XG5cbi8qKlxuICogQW4gYWRkaXRpb25hbCBmaWxlIHRvIHdyaXRlIHZpYSBjbG91ZC1pbml0IHdyaXRlX2ZpbGVzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5hdEluc3RhbmNlV3JpdGVGaWxlIHtcbiAgLyoqIEFic29sdXRlIHBhdGggb24gdGhlIGluc3RhbmNlIHdoZXJlIHRoZSBmaWxlIHdpbGwgYmUgd3JpdHRlbi4gKi9cbiAgcmVhZG9ubHkgcGF0aDogc3RyaW5nO1xuICAvKiogRmlsZSBjb250ZW50LiAqL1xuICByZWFkb25seSBjb250ZW50OiBzdHJpbmc7XG4gIC8qKiBPY3RhbCBmaWxlIHBlcm1pc3Npb25zIHN0cmluZywgZS5nLiAnMDc1NScuICovXG4gIHJlYWRvbmx5IHBlcm1pc3Npb25zPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIE5hdEluc3RhbmNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5hdEluc3RhbmNlUHJvcHMgZXh0ZW5kcyBFeHRlbmRlZENvbnN0cnVjdFByb3BzIHtcbiAgLyoqXG4gICAqIFZQQyB0byBwbGFjZSB0aGUgTkFUIGluc3RhbmNlIGluLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjOiBlYzIuSVZwYztcblxuICAvKipcbiAgICogVGhlIHB1YmxpYyBzdWJuZXQgd2hlcmUgdGhlIEVOSSBhbmQgaW5zdGFuY2Ugd2lsbCBsaXZlLlxuICAgKi9cbiAgcmVhZG9ubHkgcHVibGljU3VibmV0OiBlYzIuSVN1Ym5ldDtcblxuICAvKipcbiAgICogQ0lEUiBibG9ja3Mgb2YgcHJpdmF0ZSBzdWJuZXRzLiBVc2VkIGZvciB0aGUgc2VjdXJpdHkgZ3JvdXAgaW5ncmVzcyBydWxlXG4gICAqIHNvIHRoYXQgcHJpdmF0ZSBpbnN0YW5jZXMgY2FuIHJvdXRlIHRyYWZmaWMgdGhyb3VnaCB0aGUgTkFUIGluc3RhbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJpdmF0ZVN1Ym5ldENpZHJCbG9ja3M6IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHJ1biB0aGUgQVNHIGF0IGRlc2lyZWQgY2FwYWNpdHkgb2YgMS4gV2hlbiBmYWxzZSB0aGUgQVNHIGlzXG4gICAqIHNldCB0byBkZXNpcmVkL21pbj0wLCBlZmZlY3RpdmVseSBwYXVzaW5nIHRoZSBOQVQgaW5zdGFuY2Ugd2l0aG91dFxuICAgKiBkZXN0cm95aW5nIHRoZSBFTkkgb3Igb3RoZXIgcmVzb3VyY2VzLiBEZWZhdWx0IGlzIHRydWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGVuYWJsZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJRHMgb2YgcHJpdmF0ZSByb3V0ZSB0YWJsZXMgdGhhdCBzaG91bGQgcmVjZWl2ZSBhIDAuMC4wLjAvMCBkZWZhdWx0XG4gICAqIHJvdXRlIHBvaW50aW5nIHRvIHRoZSBOQVQgaW5zdGFuY2UgRU5JLiBUeXBpY2FsbHkgb25lIHBlciBBWi5cbiAgICovXG4gIHJlYWRvbmx5IHByaXZhdGVSb3V0ZVRhYmxlSWRzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBBTUkgSUQuIFdoZW4gb21pdHRlZCB0aGUgbGF0ZXN0IEFtYXpvbiBMaW51eCAyMDIzIHN0YW5kYXJkIEFNSVxuICAgKiBpcyB1c2VkLCBmaWx0ZXJlZCBieSB0aGUgcmVzb2x2ZWQgYXJjaGl0ZWN0dXJlLiBUaGUgc3RhbmRhcmQgZWRpdGlvblxuICAgKiBpbmNsdWRlcyB0aGUgU1NNIGFnZW50IGZvciByZW1vdGUgbWFuYWdlbWVudC5cbiAgICovXG4gIHJlYWRvbmx5IGltYWdlSWQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENQVSBhcmNoaXRlY3R1cmUgdXNlZCBmb3IgdGhlIEFNSSBsb29rdXAuIERlZmF1bHQgaXMgQVJNXzY0LCB3aGljaFxuICAgKiBjb3JyZXNwb25kcyB0byB0aGUgZGVmYXVsdCB0NGcubWljcm8gaW5zdGFuY2UgdHlwZS5cbiAgICpcbiAgICogQGRlZmF1bHQgZWMyLkFtYXpvbkxpbnV4Q3B1VHlwZS5BUk1fNjRcbiAgICovXG4gIHJlYWRvbmx5IGFyY2hpdGVjdHVyZT86IGVjMi5BbWF6b25MaW51eENwdVR5cGU7XG5cbiAgLyoqXG4gICAqIEVDMiBpbnN0YW5jZSB0eXBlcyBmb3IgdGhlIEF1dG8gU2NhbGluZyBHcm91cCBtaXhlZCBpbnN0YW5jZXMgcG9saWN5LlxuICAgKiBEZWZhdWx0cyBiYXNlZCBvbiBhcmNoaXRlY3R1cmU6IHQ0Zy5taWNybyBmb3IgQVJNNjQgKH4kNi9tb250aCBvbi1kZW1hbmQpLFxuICAgKiB0M2EubWljcm8gZm9yIFg4Nl82NCAofiQ3LjYwL21vbnRoIG9uLWRlbWFuZCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IFtuZXcgZWMyLkluc3RhbmNlVHlwZSgndDRnLm1pY3JvJyldIGZvciBBUk02NCwgW25ldyBlYzIuSW5zdGFuY2VUeXBlKCd0M2EubWljcm8nKV0gZm9yIFg4Nl82NFxuICAgKi9cbiAgcmVhZG9ubHkgaW5zdGFuY2VUeXBlcz86IGVjMi5JbnN0YW5jZVR5cGVbXTtcblxuICAvKipcbiAgICogVXNlIFNwb3QgaW5zdGFuY2VzIGluc3RlYWQgb2YgT24tRGVtYW5kLiBTcG90IGNhbiByZWR1Y2UgY29zdCB0byB+JDEvbW9udGhcbiAgICogYnV0IHRoZSBpbnN0YW5jZSBtYXkgYmUgaW50ZXJydXB0ZWQgd2l0aCBhIDItbWludXRlIHdhcm5pbmcuIERlZmF1bHQgaXMgZmFsc2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSB1c2VTcG90SW5zdGFuY2U/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIGFuIGV4aXN0aW5nIEVDMiBrZXkgcGFpciB0byBhbGxvdyBTU0ggYWNjZXNzLiBXaGVuIG9taXR0ZWQsXG4gICAqIEFXUyBTeXN0ZW1zIE1hbmFnZXIgU2Vzc2lvbiBNYW5hZ2VyIChlbmFibGVkIHZpYSB0aGUgYXR0YWNoZWQgU1NNIHBvbGljeSlcbiAgICogaXMgdGhlIG9ubHkgY29uc29sZSBhY2Nlc3MgbWV0aG9kLlxuICAgKi9cbiAgcmVhZG9ubHkga2V5TmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBjbG91ZC1pbml0IHdyaXRlX2ZpbGVzIGVudHJpZXMgYXBwZW5kZWQgYWZ0ZXIgdGhlIGJ1aWx0LWluXG4gICAqIE5BVCBzY3JpcHRzLiBVc2VmdWwgZm9yIGluamVjdGluZyBjdXN0b20gY29uZmlndXJhdGlvbiBmaWxlcy5cbiAgICovXG4gIHJlYWRvbmx5IGFkZGl0aW9uYWxXcml0ZUZpbGVzPzogTmF0SW5zdGFuY2VXcml0ZUZpbGVbXTtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBjbG91ZC1pbml0IHJ1bmNtZCBlbnRyaWVzIGFwcGVuZGVkIGFmdGVyIC9vcHQvbmF0L3J1bm9uY2Uuc2guXG4gICAqIEVhY2ggaW5uZXIgYXJyYXkgcmVwcmVzZW50cyBvbmUgY29tbWFuZCBpbnZvY2F0aW9uIChhcmd2IHN0eWxlKS5cbiAgICovXG4gIHJlYWRvbmx5IGFkZGl0aW9uYWxSdW5DbWRzPzogc3RyaW5nW11bXTtcblxuICAvKipcbiAgICogQVJOIG9mIHRoZSBJQU0gbWFuYWdlZCBwb2xpY3kgYXR0YWNoZWQgdG8gdGhlIGluc3RhbmNlIHJvbGUgZm9yIFN5c3RlbXNcbiAgICogTWFuYWdlciBhY2Nlc3MuIFdoZW4gb21pdHRlZCwgdXNlcyBBbWF6b25TU01NYW5hZ2VkSW5zdGFuY2VDb3JlIHJlc29sdmVkXG4gICAqIGZvciB0aGUgc3RhY2sncyBwYXJ0aXRpb24gKHdvcmtzIGluIEdvdkNsb3VkIGFuZCBDaGluYSkuXG4gICAqXG4gICAqIEBkZWZhdWx0IEFtYXpvblNTTU1hbmFnZWRJbnN0YW5jZUNvcmUgKHBhcnRpdGlvbi1hZ25vc3RpYylcbiAgICovXG4gIHJlYWRvbmx5IHNzbVBvbGljeUFybj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBJbmRlbnRzIHNjcmlwdCBjb250ZW50IGZvciBlbWJlZGRpbmcgaW4gYSBZQU1MIGxpdGVyYWwgYmxvY2sgc2NhbGFyLlxuICogRWFjaCBsaW5lIGlzIHByZWZpeGVkIHdpdGggNCBzcGFjZXM7IGJsYW5rIGxpbmVzIGFyZSBsZWZ0IHRydWx5IGVtcHR5XG4gKiB0byBzYXRpc2Z5IHN0cmljdCBZQU1MIHBhcnNlcnMuIFRoZSB0cmFpbGluZyBuZXdsaW5lIHByb2R1Y2VkIGJ5IHNjcmlwdHNcbiAqIGVuZGluZyB3aXRoIFxcbiBpcyBjb25zdW1lZCAodGhlIFlBTUwgYHxgIGNob21waW5nIGhhbmRsZXMgaXQpLlxuICovXG5mdW5jdGlvbiBpbmRlbnRMaXRlcmFsQmxvY2soY29udGVudDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgbGluZXMgPSBjb250ZW50LnNwbGl0KCdcXG4nKTtcbiAgLy8gRHJvcCB0aGUgbGFzdCBlbGVtZW50IHdoZW4gaXQgaXMgYW4gZW1wdHkgc3RyaW5nIHByb2R1Y2VkIGJ5IGFcbiAgLy8gdHJhaWxpbmcgXFxuIOKAlCB0aGUgYHxgIGJsb2NrIGluZGljYXRvciBhbHJlYWR5IGltcGxpZXMgb25lIGZpbmFsIG5ld2xpbmUuXG4gIGlmIChsaW5lc1tsaW5lcy5sZW5ndGggLSAxXSA9PT0gJycpIHtcbiAgICBsaW5lcy5wb3AoKTtcbiAgfVxuICByZXR1cm4gbGluZXMubWFwKChsaW5lKSA9PiAobGluZSA9PT0gJycgPyAnJyA6IGAgICAgJHtsaW5lfWApKS5qb2luKCdcXG4nKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIGEgc2luZ2xlIGNsb3VkLWluaXQgd3JpdGVfZmlsZXMgbGlzdCBlbnRyeSBhcyBZQU1MLCB1c2luZyBhXG4gKiBsaXRlcmFsIGJsb2NrIHNjYWxhciBmb3IgdGhlIGNvbnRlbnQgZmllbGQgdG8gYXZvaWQgYW55IGVzY2FwaW5nIGlzc3Vlc1xuICogd2l0aCBzaGVsbCBzcGVjaWFsIGNoYXJhY3RlcnMuXG4gKi9cbmZ1bmN0aW9uIHdyaXRlRmlsZUVudHJ5KFxuICBwYXRoOiBzdHJpbmcsXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgcGVybWlzc2lvbnM/OiBzdHJpbmcsXG4pOiBzdHJpbmcge1xuICBjb25zdCBwZXJtc0xpbmUgPVxuICAgIHBlcm1pc3Npb25zICE9PSB1bmRlZmluZWQgPyBgXFxuICBwZXJtaXNzaW9uczogJyR7cGVybWlzc2lvbnN9J2AgOiAnJztcbiAgcmV0dXJuIGAtIHBhdGg6ICR7cGF0aH0ke3Blcm1zTGluZX1cXG4gIGNvbnRlbnQ6IHxcXG4ke2luZGVudExpdGVyYWxCbG9jayhjb250ZW50KX1cXG5gO1xufVxuXG4vKipcbiAqIEEgc2VsZi1oZWFsaW5nLCBjb3N0LW9wdGltaXNlZCBOQVQgaW5zdGFuY2UgZm9yIHByaXZhdGUgc3VibmV0IGVncmVzcy5cbiAqXG4gKiBUaGlzIGlzIGEgQ0RLIHBvcnQgb2YgdGhlIHRydWVtYXJrL25hdC1pbnN0YW5jZSBUZXJyYWZvcm0gbW9kdWxlLiBJdFxuICogcHJvdmlzaW9uczpcbiAqIC0gQSBkZWRpY2F0ZWQgc2Vjb25kYXJ5IEVsYXN0aWMgTmV0d29yayBJbnRlcmZhY2UgKEVOSSkgd2l0aCBzb3VyY2UvZGVzdFxuICogICBjaGVjayBkaXNhYmxlZC4gUHJpdmF0ZSBzdWJuZXRzIHJvdXRlIHRvIHRoaXMgRU5JLCB3aGljaCBwZXJzaXN0cyBhY3Jvc3NcbiAqICAgaW5zdGFuY2UgcmVwbGFjZW1lbnRzLiBBY3R1YWwgTkFUIGVncmVzcyBoYXBwZW5zIHRocm91Z2ggdGhlIGluc3RhbmNlJ3NcbiAqICAgcHJpbWFyeSBpbnRlcmZhY2UgKHdoaWNoIGhhcyBhbiBhdXRvLWFzc2lnbmVkIHB1YmxpYyBJUCBieSBkZWZhdWx0KS5cbiAqIC0gQW4gSUFNIHJvbGUgd2l0aCBBbWF6b25TU01NYW5hZ2VkSW5zdGFuY2VDb3JlIGFuZCB0aGUgRUMyIHBlcm1pc3Npb25zXG4gKiAgIG5lZWRlZCBmb3Igc25hdC5zaCB0byBhdHRhY2ggdGhlIHNlY29uZGFyeSBFTkkgYXQgYm9vdC5cbiAqIC0gQW4gRUMyIExhdW5jaCBUZW1wbGF0ZSBydW5uaW5nIEFtYXpvbiBMaW51eCAyMDIzIHN0YW5kYXJkIChBUk02NCBieVxuICogICBkZWZhdWx0KSB3aXRoIGEgY2xvdWQtaW5pdCB1c2VyLWRhdGEgdGhhdCBpbnN0YWxscyBpcHRhYmxlcywgYXR0YWNoZXNcbiAqICAgdGhlIEVOSSwgZW5hYmxlcyBJUCBmb3J3YXJkaW5nLCBhbmQgc2V0cyB1cCBOQVQgbWFzcXVlcmFkaW5nLlxuICogLSBBbiBBdXRvIFNjYWxpbmcgR3JvdXAgKGRlc2lyZWQ9MSkgdGhhdCBhdXRvLXJlcGxhY2VzIHRoZSBpbnN0YW5jZSBvblxuICogICBmYWlsdXJlLCBrZWVwaW5nIHRoZSBFTkkgcGVyc2lzdGVudCBhY3Jvc3MgcmVwbGFjZW1lbnRzLlxuICogLSBPcHRpb25hbCAwLjAuMC4wLzAgcm91dGVzIGluIHByaXZhdGUgcm91dGUgdGFibGVzIHBvaW50aW5nIHRvIHRoZSBFTkkuXG4gKlxuICogKipVc2FnZSB3aXRoIFN0YW5kYXJkTmV0d29yazoqKlxuICogYGBgdHNcbiAqIGNvbnN0IG5ldHdvcmsgPSBuZXcgU3RhbmRhcmROZXR3b3JrKHRoaXMsICdOZXR3b3JrJywge1xuICogICBuYW1lOiAncHJvZCcsXG4gKiAgIHZwY0NpZHI6ICcxMC4wLjAuMC8yMCcsXG4gKiAgIG5hdFR5cGU6ICdub25lJywgICAvLyBubyBtYW5hZ2VkIE5BVCBnYXRld2F5XG4gKiB9KTtcbiAqXG4gKiBjb25zdCBuYXQgPSBuZXcgTmF0SW5zdGFuY2UodGhpcywgJ05hdCcsIHtcbiAqICAgdnBjOiBuZXR3b3JrLnZwYyxcbiAqICAgcHVibGljU3VibmV0OiBuZXR3b3JrLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdwdWJsaWMnfSkuc3VibmV0c1swXSxcbiAqICAgcHJpdmF0ZVN1Ym5ldENpZHJCbG9ja3M6IFsnMTAuMC4wLjAvMjQnXSxcbiAqICAgcHJpdmF0ZVJvdXRlVGFibGVJZHM6IG5ldHdvcmsudnBjXG4gKiAgICAgLnNlbGVjdFN1Ym5ldHMoe3N1Ym5ldEdyb3VwTmFtZTogJ3ByaXZhdGUnfSlcbiAqICAgICAuc3VibmV0cy5tYXAocyA9PiBzLnJvdXRlVGFibGUucm91dGVUYWJsZUlkKSxcbiAqIH0pO1xuICpcbiAqIC8vIFRoZSBpbnN0YW5jZSdzIHByaW1hcnkgaW50ZXJmYWNlIGdldHMgYW4gYXV0by1hc3NpZ25lZCBwdWJsaWMgSVAuXG4gKiAvLyBGb3IgYSBzdGFibGUgb3V0Ym91bmQgSVAsIGFsbG9jYXRlIGFuZCBhc3NvY2lhdGUgYW4gRUlQIHdpdGggdGhlXG4gKiAvLyBpbnN0YW5jZSdzIHByaW1hcnkgaW50ZXJmYWNlIHVzaW5nIEFTRyBsaWZlY3ljbGUgaG9va3Mgb3IgdGFncy5cbiAqIC8vIEV4YW1wbGU6XG4gKiAvLyBjb25zdCBlaXAgPSBuZXcgZWMyLkNmbkVJUCh0aGlzLCAnTmF0RWlwJywge2RvbWFpbjogJ3ZwYyd9KTtcbiAqIC8vIEFzc29jaWF0ZSB0aGUgRUlQIHdpdGggbmV3IGluc3RhbmNlcyB2aWEgbGlmZWN5Y2xlIGhvb2sgb3IgdGFnIG1hdGNoaW5nLlxuICogYGBgXG4gKlxuICogPiAqKk5vdGU6KiogVGhpcyBjb25zdHJ1Y3QgaXMgb3B0aW1pc2VkIGZvciBjb3N0IChBUk02NCBzcG90L29uLWRlbWFuZFxuICogPiB0NGcubWljcm8gYXQgfiQy4oCTNi9tb250aCkgYW5kIGlzIHN1aXRhYmxlIGZvciBkZXYvc3RhZ2luZyBlbnZpcm9ubWVudHMuXG4gKiA+IEZvciBwcm9kdWN0aW9uIHVzZSBwcmVmZXIgQVdTIE5BVCBHYXRld2F5IG9yIGEgbGFyZ2VyIGluc3RhbmNlIHR5cGUgd2l0aFxuICogPiBgdXNlU3BvdEluc3RhbmNlOiBmYWxzZWAuXG4gKi9cbmV4cG9ydCBjbGFzcyBOYXRJbnN0YW5jZSBleHRlbmRzIEV4dGVuZGVkQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIElEIG9mIHRoZSBkZWRpY2F0ZWQgc2Vjb25kYXJ5IEVOSS4gUHJpdmF0ZSBzdWJuZXRcbiAgICogcm91dGVzIHBvaW50IHRvIHRoaXMgRU5JLCB3aGljaCBwZXJzaXN0cyBhY3Jvc3MgaW5zdGFuY2UgcmVwbGFjZW1lbnRzLlxuICAgKiBOb3RlOiBOQVQgZWdyZXNzIG9jY3VycyB0aHJvdWdoIHRoZSBwcmltYXJ5IGludGVyZmFjZSwgbm90IHRoaXMgRU5JLlxuICAgKi9cbiAgcmVhZG9ubHkgZW5pSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogUHJpbWFyeSBwcml2YXRlIElQdjQgYWRkcmVzcyBvZiB0aGUgZGVkaWNhdGVkIEVOSS5cbiAgICovXG4gIHJlYWRvbmx5IGVuaVByaXZhdGVJcDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTZWN1cml0eSBncm91cCBJRCBvZiB0aGUgTkFUIGluc3RhbmNlIHNlY3VyaXR5IGdyb3VwLlxuICAgKi9cbiAgcmVhZG9ubHkgc2dJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSBJQU0gcm9sZSBhdHRhY2hlZCB0byB0aGUgTkFUIGluc3RhbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgaWFtUm9sZU5hbWU6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTmF0SW5zdGFuY2VQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgc3RhbmRhcmRUYWdzOiBTdGFuZGFyZFRhZ3MubWVyZ2UocHJvcHMuc3RhbmRhcmRUYWdzLCBMaWJTdGFuZGFyZFRhZ3MpLFxuICAgIH0pO1xuXG4gICAgY29uc3QgZW5hYmxlZCA9IHByb3BzLmVuYWJsZWQgPz8gdHJ1ZTtcbiAgICBjb25zdCBhcmNoaXRlY3R1cmUgPSBwcm9wcy5hcmNoaXRlY3R1cmUgPz8gZWMyLkFtYXpvbkxpbnV4Q3B1VHlwZS5BUk1fNjQ7XG5cbiAgICAvLyBVbmlxdWUgdGFnIHZhbHVlIGZvciB0aGlzIE5BVCBpbnN0YW5jZSwgdXNlZCB0byBzY29wZSBJQU0gcGVybWlzc2lvbnMuXG4gICAgLy8gSW5jbHVkZXMgc3RhY2sgbmFtZSB0byBlbnN1cmUgdW5pcXVlbmVzcyBhY3Jvc3MgbXVsdGlwbGUgc3RhY2sgZGVwbG95bWVudHMuXG4gICAgY29uc3QgbmF0SW5zdGFuY2VSb2xlVGFnID0gYG5hdC1pbnN0YW5jZS0ke2Nkay5TdGFjay5vZih0aGlzKS5zdGFja05hbWV9LSR7aWR9YDtcblxuICAgIC8vIERlcml2ZSBkZWZhdWx0IGluc3RhbmNlIHR5cGUgZnJvbSBhcmNoaXRlY3R1cmUgdG8gYXZvaWQgQU1JL2luc3RhbmNlIG1pc21hdGNoXG4gICAgLy8gVXNlIG1pY3JvICgxR0IgUkFNKSBpbnN0ZWFkIG9mIG5hbm8gKDUxMk1CKSB0byBwcmV2ZW50IE9PTSBkdXJpbmcgcGFja2FnZSBpbnN0YWxsYXRpb25cbiAgICBjb25zdCBkZWZhdWx0SW5zdGFuY2VUeXBlID1cbiAgICAgIGFyY2hpdGVjdHVyZSA9PT0gZWMyLkFtYXpvbkxpbnV4Q3B1VHlwZS5YODZfNjRcbiAgICAgICAgPyBuZXcgZWMyLkluc3RhbmNlVHlwZSgndDNhLm1pY3JvJylcbiAgICAgICAgOiBuZXcgZWMyLkluc3RhbmNlVHlwZSgndDRnLm1pY3JvJyk7XG5cbiAgICBjb25zdCBpbnN0YW5jZVR5cGVzID0gcHJvcHMuaW5zdGFuY2VUeXBlcyA/PyBbZGVmYXVsdEluc3RhbmNlVHlwZV07XG4gICAgaWYgKGluc3RhbmNlVHlwZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdpbnN0YW5jZVR5cGVzIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgaW5zdGFuY2UgdHlwZS4gT21pdCB0aGUgcHJvcGVydHkgdG8gdXNlIHRoZSBhcmNoaXRlY3R1cmUtYXBwcm9wcmlhdGUgZGVmYXVsdCAodDRnLm1pY3JvIGZvciBBUk02NCwgdDNhLm1pY3JvIGZvciBYODZfNjQpLicsXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCB1c2VTcG90SW5zdGFuY2UgPSBwcm9wcy51c2VTcG90SW5zdGFuY2UgPz8gZmFsc2U7XG5cbiAgICAvLyDilIDilIAgU2VjdXJpdHkgR3JvdXAg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gICAgY29uc3Qgc2cgPSBuZXcgZWMyLlNlY3VyaXR5R3JvdXAodGhpcywgJ1NlY3VyaXR5R3JvdXAnLCB7XG4gICAgICB2cGM6IHByb3BzLnZwYyxcbiAgICAgIGRlc2NyaXB0aW9uOiBgU2VjdXJpdHkgZ3JvdXAgZm9yIE5BVCBpbnN0YW5jZSAke2lkfWAsXG4gICAgICBhbGxvd0FsbE91dGJvdW5kOiB0cnVlLCAvLyBtaXJyb3JzIHRoZSBlZ3Jlc3MgYWxsLXRyYWZmaWMgcnVsZSBpbiBUZXJyYWZvcm1cbiAgICB9KTtcbiAgICBmb3IgKGNvbnN0IGNpZHIgb2YgcHJvcHMucHJpdmF0ZVN1Ym5ldENpZHJCbG9ja3MpIHtcbiAgICAgIHNnLmFkZEluZ3Jlc3NSdWxlKGVjMi5QZWVyLmlwdjQoY2lkciksIGVjMi5Qb3J0LmFsbFRyYWZmaWMoKSk7XG4gICAgfVxuICAgIHRoaXMuc2dJZCA9IHNnLnNlY3VyaXR5R3JvdXBJZDtcblxuICAgIC8vIOKUgOKUgCBFbGFzdGljIE5ldHdvcmsgSW50ZXJmYWNlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgIC8vIE5vIEwyIEVOSSBjb25zdHJ1Y3QgZXhpc3RzIOKAlCB1c2UgTDEgZGlyZWN0bHkuXG4gICAgLy8gc291cmNlX2Rlc3RfY2hlY2s9ZmFsc2UgaXMgcmVxdWlyZWQgZm9yIHRoZSBpbnN0YW5jZSB0byBmb3J3YXJkIHBhY2tldHMuXG4gICAgY29uc3QgZW5pID0gbmV3IGVjMi5DZm5OZXR3b3JrSW50ZXJmYWNlKHRoaXMsICdFbmknLCB7XG4gICAgICBzdWJuZXRJZDogcHJvcHMucHVibGljU3VibmV0LnN1Ym5ldElkLFxuICAgICAgZ3JvdXBTZXQ6IFtzZy5zZWN1cml0eUdyb3VwSWRdLFxuICAgICAgc291cmNlRGVzdENoZWNrOiBmYWxzZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBgRU5JIGZvciBOQVQgaW5zdGFuY2UgJHtpZH1gLFxuICAgIH0pO1xuICAgIFRhZ3Mub2YoZW5pKS5hZGQoJ05hbWUnLCBgbmF0LWluc3RhbmNlLSR7aWR9YCk7XG4gICAgdGhpcy5lbmlJZCA9IGVuaS5yZWY7XG4gICAgdGhpcy5lbmlQcml2YXRlSXAgPSBlbmkuYXR0clByaW1hcnlQcml2YXRlSXBBZGRyZXNzO1xuXG4gICAgLy8g4pSA4pSAIFByaXZhdGUgUm91dGVzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgIC8vIENmblJvdXRlIGlzIHVzZWQgYmVjYXVzZSB0aGUgTDIgUm91dGUgY29uc3RydWN0IGRvZXMgbm90IHN1cHBvcnRcbiAgICAvLyB0YXJnZXRpbmcgYSByYXcgRU5JIGFzIHRoZSBuZXh0IGhvcC5cbiAgICBjb25zdCByb3V0ZVRhYmxlSWRzID0gcHJvcHMucHJpdmF0ZVJvdXRlVGFibGVJZHMgPz8gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3V0ZVRhYmxlSWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBuZXcgZWMyLkNmblJvdXRlKHRoaXMsIGBQcml2YXRlUm91dGUke2l9YCwge1xuICAgICAgICByb3V0ZVRhYmxlSWQ6IHJvdXRlVGFibGVJZHNbaV0sXG4gICAgICAgIGRlc3RpbmF0aW9uQ2lkckJsb2NrOiAnMC4wLjAuMC8wJyxcbiAgICAgICAgbmV0d29ya0ludGVyZmFjZUlkOiBlbmkucmVmLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8g4pSA4pSAIElBTSBSb2xlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgIGNvbnN0IHJvbGUgPSBuZXcgaWFtLlJvbGUodGhpcywgJ1JvbGUnLCB7XG4gICAgICBhc3N1bWVkQnk6IG5ldyBpYW0uU2VydmljZVByaW5jaXBhbCgnZWMyLmFtYXpvbmF3cy5jb20nKSxcbiAgICB9KTtcblxuICAgIC8vIEFkZCBTU00gbWFuYWdlZCBwb2xpY3kgKHBhcnRpdGlvbi1hZ25vc3RpYyB3aGVuIG5vIG92ZXJyaWRlIHByb3ZpZGVkKVxuICAgIGlmIChwcm9wcy5zc21Qb2xpY3lBcm4pIHtcbiAgICAgIHJvbGUuYWRkTWFuYWdlZFBvbGljeShcbiAgICAgICAgaWFtLk1hbmFnZWRQb2xpY3kuZnJvbU1hbmFnZWRQb2xpY3lBcm4oXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICAnU3NtUG9saWN5JyxcbiAgICAgICAgICBwcm9wcy5zc21Qb2xpY3lBcm4sXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICByb2xlLmFkZE1hbmFnZWRQb2xpY3koXG4gICAgICAgIGlhbS5NYW5hZ2VkUG9saWN5LmZyb21Bd3NNYW5hZ2VkUG9saWN5TmFtZShcbiAgICAgICAgICAnQW1hem9uU1NNTWFuYWdlZEluc3RhbmNlQ29yZScsXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIHNuYXQuc2ggY2FsbHMgYXdzIGVjMiBkZXNjcmliZS9hdHRhY2gvbW9kaWZ5IG9wZXJhdGlvbnMgYXQgaW5zdGFuY2UgYm9vdC5cbiAgICAvLyBEZXNjcmliZSBhY3Rpb25zIHVzZSB3aWxkY2FyZDsgQXR0YWNoL01vZGlmeSBhcmUgY29uc3RyYWluZWQgdG8gdGhlIGRlZGljYXRlZCBFTkkuXG4gICAgcm9sZS5hZGRUb1ByaW5jaXBhbFBvbGljeShcbiAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogWydlYzI6RGVzY3JpYmVOZXR3b3JrSW50ZXJmYWNlcycsICdlYzI6RGVzY3JpYmVJbnN0YW5jZXMnXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgLy8gQXR0YWNoTmV0d29ya0ludGVyZmFjZSBvbiBpbnN0YW5jZXMgLSByZXN0cmljdGVkIHRvIGluc3RhbmNlcyB3aXRoIG1hdGNoaW5nIHRhZ1xuICAgIC8vIHRvIHByZXZlbnQgYXR0YWNoaW5nIGFyYml0cmFyeSBFTklzIHRvIGFyYml0cmFyeSBpbnN0YW5jZXMuXG4gICAgcm9sZS5hZGRUb1ByaW5jaXBhbFBvbGljeShcbiAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogWydlYzI6QXR0YWNoTmV0d29ya0ludGVyZmFjZSddLFxuICAgICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgICBgYXJuOiR7Y2RrLlN0YWNrLm9mKHRoaXMpLnBhcnRpdGlvbn06ZWMyOiR7Y2RrLlN0YWNrLm9mKHRoaXMpLnJlZ2lvbn06JHtjZGsuU3RhY2sub2YodGhpcykuYWNjb3VudH06aW5zdGFuY2UvKmAsXG4gICAgICAgIF0sXG4gICAgICAgIGNvbmRpdGlvbnM6IHtcbiAgICAgICAgICBTdHJpbmdFcXVhbHM6IHtcbiAgICAgICAgICAgICdlYzI6UmVzb3VyY2VUYWcvbmF0LWluc3RhbmNlLXJvbGUnOiBuYXRJbnN0YW5jZVJvbGVUYWcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgLy8gQXR0YWNoTmV0d29ya0ludGVyZmFjZSBvbmx5IG9uIHRoZSBzcGVjaWZpYyBOQVQgRU5JXG4gICAgcm9sZS5hZGRUb1ByaW5jaXBhbFBvbGljeShcbiAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogWydlYzI6QXR0YWNoTmV0d29ya0ludGVyZmFjZSddLFxuICAgICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgICBgYXJuOiR7Y2RrLlN0YWNrLm9mKHRoaXMpLnBhcnRpdGlvbn06ZWMyOiR7Y2RrLlN0YWNrLm9mKHRoaXMpLnJlZ2lvbn06JHtjZGsuU3RhY2sub2YodGhpcykuYWNjb3VudH06bmV0d29yay1pbnRlcmZhY2UvJHtlbmkucmVmfWAsXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICApO1xuICAgIC8vIE1vZGlmeU5ldHdvcmtJbnRlcmZhY2VBdHRyaWJ1dGUgb24gbmV0d29yay1pbnRlcmZhY2VzIHdpdGhpbiBWUEMgKGZvciBwcmltYXJ5IEVOSSBzb3VyY2UvZGVzdCBjaGVjaylcbiAgICByb2xlLmFkZFRvUHJpbmNpcGFsUG9saWN5KFxuICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbJ2VjMjpNb2RpZnlOZXR3b3JrSW50ZXJmYWNlQXR0cmlidXRlJ10sXG4gICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgIGBhcm46JHtjZGsuU3RhY2sub2YodGhpcykucGFydGl0aW9ufTplYzI6JHtjZGsuU3RhY2sub2YodGhpcykucmVnaW9ufToke2Nkay5TdGFjay5vZih0aGlzKS5hY2NvdW50fTpuZXR3b3JrLWludGVyZmFjZS8qYCxcbiAgICAgICAgXSxcbiAgICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICAgIFN0cmluZ0VxdWFsczoge1xuICAgICAgICAgICAgJ2VjMjpWcGMnOiBgYXJuOiR7Y2RrLlN0YWNrLm9mKHRoaXMpLnBhcnRpdGlvbn06ZWMyOiR7Y2RrLlN0YWNrLm9mKHRoaXMpLnJlZ2lvbn06JHtjZGsuU3RhY2sub2YodGhpcykuYWNjb3VudH06dnBjLyR7cHJvcHMudnBjLnZwY0lkfWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgdGhpcy5pYW1Sb2xlTmFtZSA9IHJvbGUucm9sZU5hbWU7XG5cbiAgICAvLyDilIDilIAgTWFjaGluZSBJbWFnZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICBjb25zdCBtYWNoaW5lSW1hZ2U6IGVjMi5JTWFjaGluZUltYWdlID0gcHJvcHMuaW1hZ2VJZFxuICAgICAgPyBuZXcgUmF3QW1pTWFjaGluZUltYWdlKHByb3BzLmltYWdlSWQpXG4gICAgICA6IGVjMi5NYWNoaW5lSW1hZ2UubGF0ZXN0QW1hem9uTGludXgyMDIzKHtcbiAgICAgICAgICBjcHVUeXBlOiBhcmNoaXRlY3R1cmUsXG4gICAgICAgICAgZWRpdGlvbjogZWMyLkFtYXpvbkxpbnV4RWRpdGlvbi5TVEFOREFSRCxcbiAgICAgICAgfSk7XG5cbiAgICAvLyDilIDilIAgVXNlciBEYXRhIChjbG91ZC1pbml0KSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICAvLyAvZXRjL25hdC5jb25mIHRlbGxzIHNuYXQuc2ggd2hpY2ggRU5JIHRvIGF0dGFjaCBhcyBldGgxIGF0IGJvb3QuXG4gICAgLy8gZW5pLnJlZiBpcyBhIENGTiB0b2tlbiByZXNvbHZlZCB0byB0aGUgRU5JIHJlc291cmNlIElEIGF0IGRlcGxveSB0aW1lLlxuICAgIGNvbnN0IG5hdENvbmZDb250ZW50ID0gYGVuaV9pZD0ke2VuaS5yZWZ9XFxuYDtcblxuICAgIGNvbnN0IGNsb3VkQ29uZmlnID1cbiAgICAgICcjY2xvdWQtY29uZmlnXFxuJyArXG4gICAgICAnd3JpdGVfZmlsZXM6XFxuJyArXG4gICAgICB3cml0ZUZpbGVFbnRyeSgnL29wdC9uYXQvcnVub25jZS5zaCcsIFJVTk9OQ0VfU0gsICcwNzU1JykgK1xuICAgICAgd3JpdGVGaWxlRW50cnkoJy9vcHQvbmF0L3NuYXQuc2gnLCBTTkFUX1NILCAnMDc1NScpICtcbiAgICAgIHdyaXRlRmlsZUVudHJ5KFxuICAgICAgICAnL29wdC9uYXQvdGVybWluYXRlLW9uLWZhaWx1cmUuc2gnLFxuICAgICAgICBURVJNSU5BVEVfT05fRkFJTFVSRV9TSCxcbiAgICAgICAgJzA3NTUnLFxuICAgICAgKSArXG4gICAgICB3cml0ZUZpbGVFbnRyeSgnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9zbmF0LnNlcnZpY2UnLCBTTkFUX1NFUlZJQ0UpICtcbiAgICAgIHdyaXRlRmlsZUVudHJ5KFxuICAgICAgICAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9zbmF0LWZhaWx1cmUuc2VydmljZScsXG4gICAgICAgIFNOQVRfRkFJTFVSRV9TRVJWSUNFLFxuICAgICAgKSArXG4gICAgICAvLyBuYXQuY29uZjogcGxhaW4gbGl0ZXJhbCBibG9jayDigJQgRU5JIElEIGlzIGFscGhhbnVtZXJpYytoeXBoZW4sIHNhZmUgaW4gWUFNTFxuICAgICAgYC0gcGF0aDogL2V0Yy9uYXQuY29uZlxcbiAgcGVybWlzc2lvbnM6ICcwNjQ0J1xcbiAgY29udGVudDogfFxcbiAgICAke25hdENvbmZDb250ZW50fWAgK1xuICAgICAgKHByb3BzLmFkZGl0aW9uYWxXcml0ZUZpbGVzID8/IFtdKVxuICAgICAgICAubWFwKChmKSA9PiB3cml0ZUZpbGVFbnRyeShmLnBhdGgsIGYuY29udGVudCwgZi5wZXJtaXNzaW9ucykpXG4gICAgICAgIC5qb2luKCcnKSArXG4gICAgICAncnVuY21kOlxcbicgK1xuICAgICAgJy0gW1wiL29wdC9uYXQvcnVub25jZS5zaFwiXVxcbicgK1xuICAgICAgKHByb3BzLmFkZGl0aW9uYWxSdW5DbWRzID8/IFtdKVxuICAgICAgICAubWFwKChjbWQpID0+IGAtIFske2NtZC5tYXAoKGMpID0+IEpTT04uc3RyaW5naWZ5KGMpKS5qb2luKCcsICcpfV1cXG5gKVxuICAgICAgICAuam9pbignJyk7XG5cbiAgICBjb25zdCB1c2VyRGF0YSA9IGVjMi5Vc2VyRGF0YS5jdXN0b20oY2xvdWRDb25maWcpO1xuXG4gICAgLy8g4pSA4pSAIExhdW5jaCBUZW1wbGF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICBjb25zdCBsdCA9IG5ldyBlYzIuTGF1bmNoVGVtcGxhdGUodGhpcywgJ0xhdW5jaFRlbXBsYXRlJywge1xuICAgICAgbWFjaGluZUltYWdlLFxuICAgICAgcm9sZSxcbiAgICAgIHVzZXJEYXRhLFxuICAgICAgc2VjdXJpdHlHcm91cDogc2csXG4gICAgICBrZXlQYWlyOiBwcm9wcy5rZXlOYW1lXG4gICAgICAgID8gZWMyLktleVBhaXIuZnJvbUtleVBhaXJOYW1lKHRoaXMsICdLZXlQYWlyJywgcHJvcHMua2V5TmFtZSlcbiAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICByZXF1aXJlSW1kc3YyOiB0cnVlLFxuICAgICAgLy8gaW5zdGFuY2VUeXBlIGlzIG9taXR0ZWQg4oCUIHNldCB2aWEgbWl4ZWRJbnN0YW5jZXNQb2xpY3kgb3ZlcnJpZGVzIGJlbG93XG4gICAgfSk7XG5cbiAgICAvLyDilIDilIAgQXV0byBTY2FsaW5nIEdyb3VwIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgIGNvbnN0IGFzZyA9IG5ldyBhdXRvc2NhbGluZy5BdXRvU2NhbGluZ0dyb3VwKHRoaXMsICdBdXRvU2NhbGluZ0dyb3VwJywge1xuICAgICAgdnBjOiBwcm9wcy52cGMsXG4gICAgICAvLyBUaGUgcGlubmVkIEVOSSBjb250cm9scyBhY3R1YWwgQVogcGxhY2VtZW50OyB2cGNTdWJuZXRzIGtlZXBzIENESyBoYXBweS5cbiAgICAgIHZwY1N1Ym5ldHM6IHtzdWJuZXRzOiBbcHJvcHMucHVibGljU3VibmV0XX0sXG4gICAgICBtaW5DYXBhY2l0eTogZW5hYmxlZCA/IDEgOiAwLFxuICAgICAgbWF4Q2FwYWNpdHk6IDEsXG4gICAgICBkZXNpcmVkQ2FwYWNpdHk6IGVuYWJsZWQgPyAxIDogMCxcbiAgICAgIGhlYWx0aENoZWNrOiBhdXRvc2NhbGluZy5IZWFsdGhDaGVjay5lYzIoe1xuICAgICAgICAvLyBFeHRlbmRlZCBncmFjZSBwZXJpb2QgdG8gYWxsb3cgTkFUIHNldHVwIHRvIGNvbXBsZXRlLlxuICAgICAgICAvLyBOb3RlOiBUaGlzIG9ubHkgY2hlY2tzIEVDMiBpbnN0YW5jZSBoZWFsdGgsIG5vdCBOQVQgc2V0dXAgc3VjY2VzcyBkaXJlY3RseS5cbiAgICAgICAgLy8gSG93ZXZlciwgc25hdC5zZXJ2aWNlIGlzIGNvbmZpZ3VyZWQgdG8gcmV0cnkgb24gZmFpbHVyZSBhbmQgd2lsbCB0ZXJtaW5hdGVcbiAgICAgICAgLy8gdGhlIGluc3RhbmNlIGlmIGFsbCByZXRyaWVzIGFyZSBleGhhdXN0ZWQsIHRyaWdnZXJpbmcgQVNHIHJlcGxhY2VtZW50LlxuICAgICAgICBncmFjZTogY2RrLkR1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgICB9KSxcbiAgICAgIG1peGVkSW5zdGFuY2VzUG9saWN5OiB7XG4gICAgICAgIGxhdW5jaFRlbXBsYXRlOiBsdCxcbiAgICAgICAgaW5zdGFuY2VzRGlzdHJpYnV0aW9uOiB7XG4gICAgICAgICAgb25EZW1hbmRCYXNlQ2FwYWNpdHk6IHVzZVNwb3RJbnN0YW5jZSA/IDAgOiAxLFxuICAgICAgICAgIG9uRGVtYW5kUGVyY2VudGFnZUFib3ZlQmFzZUNhcGFjaXR5OiB1c2VTcG90SW5zdGFuY2UgPyAwIDogMTAwLFxuICAgICAgICB9LFxuICAgICAgICBsYXVuY2hUZW1wbGF0ZU92ZXJyaWRlczogaW5zdGFuY2VUeXBlcy5tYXAoKGl0KSA9PiAoe1xuICAgICAgICAgIGluc3RhbmNlVHlwZTogaXQsXG4gICAgICAgIH0pKSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyBUYWcgdGhlIEFTRyBpbnN0YW5jZXMgd2l0aCB0aGUgdW5pcXVlIGlkZW50aWZpZXIgdXNlZCBpbiBJQU0gY29uZGl0aW9ucy5cbiAgICAvLyBUaGlzIHRhZyBpcyBwcm9wYWdhdGVkIHRvIGluc3RhbmNlcyBhbmQgcmVzdHJpY3RzIElBTSBwZXJtaXNzaW9ucyB0byBzZWxmLW9ubHkgb3BlcmF0aW9ucy5cbiAgICBUYWdzLm9mKGFzZykuYWRkKCduYXQtaW5zdGFuY2Utcm9sZScsIG5hdEluc3RhbmNlUm9sZVRhZyk7XG5cbiAgICAvLyBBbGxvdyBpbnN0YW5jZSB0byB0ZXJtaW5hdGUgaXRzZWxmIG9uIHVucmVjb3ZlcmFibGUgTkFUIHNldHVwIGZhaWx1cmUuXG4gICAgLy8gUmVzdHJpY3RlZCB0byBpbnN0YW5jZXMgd2l0aCB0aGUgbWF0Y2hpbmcgbmF0LWluc3RhbmNlLXJvbGUgdGFnLFxuICAgIC8vIGVuc3VyaW5nIHRoZSBpbnN0YW5jZSBjYW4gb25seSB0ZXJtaW5hdGUgaXRzZWxmLCBub3Qgb3RoZXIgaW5zdGFuY2VzIGluIHRoZSBWUEMuXG4gICAgcm9sZS5hZGRUb1ByaW5jaXBhbFBvbGljeShcbiAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogWydlYzI6VGVybWluYXRlSW5zdGFuY2VzJ10sXG4gICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgIGBhcm46JHtjZGsuU3RhY2sub2YodGhpcykucGFydGl0aW9ufTplYzI6JHtjZGsuU3RhY2sub2YodGhpcykucmVnaW9ufToke2Nkay5TdGFjay5vZih0aGlzKS5hY2NvdW50fTppbnN0YW5jZS8qYCxcbiAgICAgICAgXSxcbiAgICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICAgIFN0cmluZ0VxdWFsczoge1xuICAgICAgICAgICAgJ2VjMjpSZXNvdXJjZVRhZy9uYXQtaW5zdGFuY2Utcm9sZSc6IG5hdEluc3RhbmNlUm9sZVRhZyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIC8vIFVzZSByb2xsaW5nIHVwZGF0ZSB0byBhdm9pZCByYWNlIGNvbmRpdGlvbiB3aXRoIEVOSSBhdHRhY2htZW50LlxuICAgIC8vIGF1dG9TY2FsaW5nUmVwbGFjaW5nVXBkYXRlIGNhbiBjcmVhdGUgb3ZlcmxhcHBpbmcgaW5zdGFuY2VzIHRoYXQgYm90aFxuICAgIC8vIHRyeSB0byBhdHRhY2ggdGhlIHNpbmdsZXRvbiBFTkksIGNhdXNpbmcgdGhlIGJvb3Qgc2NyaXB0IHRvIGZhaWwuXG4gICAgY29uc3QgY2ZuQXNnID0gYXNnLm5vZGUuZGVmYXVsdENoaWxkIGFzIGF1dG9zY2FsaW5nLkNmbkF1dG9TY2FsaW5nR3JvdXA7XG4gICAgY2ZuQXNnLmNmbk9wdGlvbnMudXBkYXRlUG9saWN5ID0ge1xuICAgICAgYXV0b1NjYWxpbmdSb2xsaW5nVXBkYXRlOiB7XG4gICAgICAgIG1heEJhdGNoU2l6ZTogMSxcbiAgICAgICAgbWluSW5zdGFuY2VzSW5TZXJ2aWNlOiAwLFxuICAgICAgICBwYXVzZVRpbWU6ICdQVDVNJyxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIFRhZ3Mub2YoYXNnKS5hZGQoJ05hbWUnLCBgbmF0LWluc3RhbmNlLSR7aWR9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBNaW5pbWFsIElNYWNoaW5lSW1hZ2UgaW1wbGVtZW50YXRpb24gZm9yIGEgY2FsbGVyLXN1cHBsaWVkIEFNSSBJRC5cbiAqXG4gKiBNYWNoaW5lSW1hZ2UuZ2VuZXJpY0xpbnV4KCkgcmVxdWlyZXMgYSBjb25jcmV0ZSByZWdpb24ga2V5IGF0IHN5bnRoIHRpbWUsXG4gKiB3aGljaCBicmVha3MgZW52aXJvbm1lbnQtYWdub3N0aWMgc3RhY2tzLiBUaGlzIGltcGxlbWVudGF0aW9uIHBhc3NlcyB0aGVcbiAqIEFNSSBJRCB0aHJvdWdoIGRpcmVjdGx5IGFuZCBsZXRzIENsb3VkRm9ybWF0aW9uIGhhbmRsZSByZWdpb24gcmVzb2x1dGlvbi5cbiAqL1xuY2xhc3MgUmF3QW1pTWFjaGluZUltYWdlIGltcGxlbWVudHMgZWMyLklNYWNoaW5lSW1hZ2Uge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGFtaUlkOiBzdHJpbmcpIHt9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBnZXRJbWFnZShfc2NvcGU6IENvbnN0cnVjdCk6IGVjMi5NYWNoaW5lSW1hZ2VDb25maWcge1xuICAgIHJldHVybiB7XG4gICAgICBpbWFnZUlkOiB0aGlzLmFtaUlkLFxuICAgICAgb3NUeXBlOiBlYzIuT3BlcmF0aW5nU3lzdGVtVHlwZS5MSU5VWCxcbiAgICAgIHVzZXJEYXRhOiBlYzIuVXNlckRhdGEuZm9yTGludXgoKSxcbiAgICB9O1xuICB9XG59XG4iXX0=
|
|
@@ -2,7 +2,7 @@ import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
|
|
2
2
|
import type { Construct } from 'constructs';
|
|
3
3
|
import { ExtendedConstruct, type ExtendedConstructProps } from '../../aws-cdk';
|
|
4
4
|
import { NetworkParameters } from './network-parameters';
|
|
5
|
-
export type NatType = 'none' | 'single' | 'multi';
|
|
5
|
+
export type NatType = 'none' | 'single' | 'multi' | 'natInstance';
|
|
6
6
|
/**
|
|
7
7
|
* Properties for StandardNetwork.
|
|
8
8
|
*/
|
|
@@ -18,11 +18,23 @@ export interface StandardNetworkProps extends ExtendedConstructProps {
|
|
|
18
18
|
*/
|
|
19
19
|
readonly vpcCidr: string;
|
|
20
20
|
/**
|
|
21
|
-
* Number of availability zones to deploy subnets into.
|
|
21
|
+
* Number of availability zones to deploy subnets into.
|
|
22
22
|
*
|
|
23
|
-
*
|
|
23
|
+
* **Breaking Change**: The default was changed from 2 to 3 to align with AWS best
|
|
24
|
+
* practices for high availability. Existing consumers upgrading will see additional
|
|
25
|
+
* subnets and resources created unless they explicitly set `azCount: 2`.
|
|
26
|
+
*
|
|
27
|
+
* @default 3
|
|
24
28
|
*/
|
|
25
29
|
readonly azCount?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Whether to enable IPv6 for the VPC. When enabled, an Amazon-provided IPv6 CIDR
|
|
32
|
+
* block is associated with the VPC and subnets are configured with IPv6 addresses.
|
|
33
|
+
* Default is false.
|
|
34
|
+
*
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
readonly enableIpv6?: boolean;
|
|
26
38
|
/**
|
|
27
39
|
* NAT gateway configuration. Default is 'none'.
|
|
28
40
|
*
|
|
@@ -212,6 +224,10 @@ export interface StandardNetworkProps extends ExtendedConstructProps {
|
|
|
212
224
|
* > addresses within the VPC. The subnet *sizes* match exactly; only the
|
|
213
225
|
* > starting addresses within the VPC differ.
|
|
214
226
|
*
|
|
227
|
+
* **IPv6 Support:** Set `enableIpv6: true` to configure the VPC in dual-stack
|
|
228
|
+
* mode with both IPv4 and IPv6. AWS automatically assigns an Amazon-provided
|
|
229
|
+
* /56 IPv6 CIDR block to the VPC, and each subnet receives a /64 IPv6 CIDR.
|
|
230
|
+
*
|
|
215
231
|
* Gateway VPC endpoints for S3 and DynamoDB are created by default and attached
|
|
216
232
|
* to private, intra, database, elasticache, and redshift route tables.
|
|
217
233
|
*
|
|
@@ -5,8 +5,9 @@ const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
|
5
5
|
const ec2 = require("aws-cdk-lib/aws-ec2");
|
|
6
6
|
const aws_cdk_1 = require("../../aws-cdk");
|
|
7
7
|
const truemark_1 = require("../../truemark");
|
|
8
|
+
const nat_instance_1 = require("./nat-instance");
|
|
8
9
|
const network_parameters_1 = require("./network-parameters");
|
|
9
|
-
// TODO Need
|
|
10
|
+
// TODO Need to add support for ipv6 only mode (currently supports dual-stack)
|
|
10
11
|
/**
|
|
11
12
|
* Subnet sizing lookup table keyed by VPC prefix length.
|
|
12
13
|
*
|
|
@@ -152,6 +153,10 @@ function applySubnetTags(subnets, tags) {
|
|
|
152
153
|
* > addresses within the VPC. The subnet *sizes* match exactly; only the
|
|
153
154
|
* > starting addresses within the VPC differ.
|
|
154
155
|
*
|
|
156
|
+
* **IPv6 Support:** Set `enableIpv6: true` to configure the VPC in dual-stack
|
|
157
|
+
* mode with both IPv4 and IPv6. AWS automatically assigns an Amazon-provided
|
|
158
|
+
* /56 IPv6 CIDR block to the VPC, and each subnet receives a /64 IPv6 CIDR.
|
|
159
|
+
*
|
|
155
160
|
* Gateway VPC endpoints for S3 and DynamoDB are created by default and attached
|
|
156
161
|
* to private, intra, database, elasticache, and redshift route tables.
|
|
157
162
|
*
|
|
@@ -165,11 +170,12 @@ class StandardNetwork extends aws_cdk_1.ExtendedConstruct {
|
|
|
165
170
|
standardTags: aws_cdk_1.StandardTags.merge(props.standardTags, truemark_1.LibStandardTags),
|
|
166
171
|
});
|
|
167
172
|
// TODO You change the default here Daren
|
|
168
|
-
const azCount = (_a = props.azCount) !== null && _a !== void 0 ? _a :
|
|
173
|
+
const azCount = (_a = props.azCount) !== null && _a !== void 0 ? _a : 3;
|
|
169
174
|
const natType = (_b = props.natType) !== null && _b !== void 0 ? _b : 'none';
|
|
170
175
|
const natGateways = natType === 'multi' ? azCount : natType === 'single' ? 1 : 0;
|
|
171
176
|
// TODO Need to add support for regional NAT
|
|
172
177
|
// TODO Need to add support for poor NAT
|
|
178
|
+
const useNatInstance = natType === 'natInstance';
|
|
173
179
|
// TODO Need to add support for network firewall
|
|
174
180
|
const createPublic = (_c = props.createPublicSubnets) !== null && _c !== void 0 ? _c : true;
|
|
175
181
|
const createPrivate = (_d = props.createPrivateSubnets) !== null && _d !== void 0 ? _d : true;
|
|
@@ -205,6 +211,7 @@ class StandardNetwork extends aws_cdk_1.ExtendedConstruct {
|
|
|
205
211
|
name: 'public',
|
|
206
212
|
subnetType: ec2.SubnetType.PUBLIC,
|
|
207
213
|
cidrMask: masks.public,
|
|
214
|
+
mapPublicIpOnLaunch: true,
|
|
208
215
|
});
|
|
209
216
|
}
|
|
210
217
|
if (createIntra) {
|
|
@@ -241,7 +248,39 @@ class StandardNetwork extends aws_cdk_1.ExtendedConstruct {
|
|
|
241
248
|
natGateways,
|
|
242
249
|
ipAddresses: ec2.IpAddresses.cidr(props.vpcCidr),
|
|
243
250
|
subnetConfiguration,
|
|
251
|
+
...(props.enableIpv6
|
|
252
|
+
? {
|
|
253
|
+
ipProtocol: ec2.IpProtocol.DUAL_STACK,
|
|
254
|
+
}
|
|
255
|
+
: {}),
|
|
244
256
|
});
|
|
257
|
+
if (useNatInstance) {
|
|
258
|
+
if (!createPublic) {
|
|
259
|
+
throw new Error("natType 'natInstance' requires public subnets.");
|
|
260
|
+
}
|
|
261
|
+
// Get private subnets (PRIVATE_WITH_EGRESS type) for NAT routing.
|
|
262
|
+
// This includes: private, database, elasticache, and redshift subnet groups.
|
|
263
|
+
// This does NOT include: intra subnets (which are PRIVATE_ISOLATED and have no internet access).
|
|
264
|
+
const allPrivateSubnets = this.vpc.privateSubnets;
|
|
265
|
+
if (allPrivateSubnets.length === 0) {
|
|
266
|
+
throw new Error("natType 'natInstance' requires at least one private subnet.");
|
|
267
|
+
}
|
|
268
|
+
// Collect all private subnet CIDR blocks for security group rules
|
|
269
|
+
const privateCidrBlocks = allPrivateSubnets.map((s) => s.ipv4CidrBlock);
|
|
270
|
+
// Get private subnet route tables for NAT routing
|
|
271
|
+
const routeTableIds = allPrivateSubnets.map((s) => s.routeTable.routeTableId);
|
|
272
|
+
// The NAT instance's primary interface will receive an auto-assigned
|
|
273
|
+
// public IP from the public subnet, enabling immediate Internet egress.
|
|
274
|
+
// For a stable outbound IP, allocate an EIP and associate it with the
|
|
275
|
+
// instance's primary interface using ASG lifecycle hooks or tags.
|
|
276
|
+
new nat_instance_1.NatInstance(this, 'Nat', {
|
|
277
|
+
vpc: this.vpc,
|
|
278
|
+
publicSubnet: this.vpc.selectSubnets({ subnetGroupName: 'public' })
|
|
279
|
+
.subnets[0],
|
|
280
|
+
privateSubnetCidrBlocks: privateCidrBlocks,
|
|
281
|
+
privateRouteTableIds: routeTableIds,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
245
284
|
// Apply per-subnet-group tags
|
|
246
285
|
if (props.publicSubnetTags && createPublic) {
|
|
247
286
|
applySubnetTags(this.vpc.selectSubnets({ subnetGroupName: 'public' }).subnets, props.publicSubnetTags);
|
|
@@ -381,4 +420,4 @@ class StandardNetwork extends aws_cdk_1.ExtendedConstruct {
|
|
|
381
420
|
}
|
|
382
421
|
}
|
|
383
422
|
exports.StandardNetwork = StandardNetwork;
|
|
384
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhcmQtbmV0d29yay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hd3MtdnBjL2xpYi9zdGFuZGFyZC1uZXR3b3JrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUFtRDtBQUNuRCwyQ0FBMkM7QUFFM0MsMkNBSXVCO0FBQ3ZCLDZDQUErQztBQUMvQyw2REFBdUQ7QUFJdkQsMERBQTBEO0FBRTFEOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsTUFBTSxjQUFjLEdBQ2xCO0lBQ0UsRUFBRSxFQUFFLEVBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFDO0lBQ2xDLEVBQUUsRUFBRSxFQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBQztJQUNsQyxFQUFFLEVBQUUsRUFBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUM7SUFDbEMsRUFBRSxFQUFFLEVBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFDO0lBQ2xDLEVBQUUsRUFBRSxFQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBQztDQUNuQyxDQUFDO0FBeU5KOzs7Ozs7O0dBT0c7QUFDSCxTQUFTLGtCQUFrQixDQUN6QixPQUFlLEVBQ2YsS0FBMkI7O0lBRTNCLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFaEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUNoQyxNQUFNLElBQUksS0FBSyxDQUFDLHFCQUFxQixPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRCw0Q0FBNEM7SUFDNUMsTUFBTSxJQUFJLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFD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aWInO1xuaW1wb3J0ICogYXMgZWMyIGZyb20gJ2F3cy1jZGstbGliL2F3cy1lYzInO1xuaW1wb3J0IHR5cGUge0NvbnN0cnVjdH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQge1xuICBFeHRlbmRlZENvbnN0cnVjdCxcbiAgdHlwZSBFeHRlbmRlZENvbnN0cnVjdFByb3BzLFxuICBTdGFuZGFyZFRhZ3MsXG59IGZyb20gJy4uLy4uL2F3cy1jZGsnO1xuaW1wb3J0IHtMaWJTdGFuZGFyZFRhZ3N9IGZyb20gJy4uLy4uL3RydWVtYXJrJztcbmltcG9ydCB7TmV0d29ya1BhcmFtZXRlcnN9IGZyb20gJy4vbmV0d29yay1wYXJhbWV0ZXJzJztcblxuZXhwb3J0IHR5cGUgTmF0VHlwZSA9ICdub25lJyB8ICdzaW5nbGUnIHwgJ211bHRpJzsgLy8gVE9ETyBBZGQgIHwgJ3JlZ2lvbmFsJyB8ICdwb29yJztcblxuLy8gVE9ETyBOZWVkIGlwdjYgc3VwcG9ydCBhbmQgd2UgbmVlZCB0byBzdXBwb3J0IGlwdjYgb25seVxuXG4vKipcbiAqIFN1Ym5ldCBzaXppbmcgbG9va3VwIHRhYmxlIGtleWVkIGJ5IFZQQyBwcmVmaXggbGVuZ3RoLlxuICpcbiAqIE1pcnJvcnMgdGhlIGBwcml2YXRlX3N1Ym5ldHNgIGFuZCBgc3VibmV0c2AgbG9jYWxzIGluIHRydWVtYXJrL3RlcnJhZm9ybS1hd3MtdnBjOlxuICpcbiAqICAgVlBDICAgICBwcml2YXRlIG5ld2JpdHMgIHByaXZhdGUgbWFzayAgIG90aGVyIG5ld2JpdHMgICBvdGhlciBtYXNrXG4gKiAgIC8xNiAgICAgICAgICAzICAgICAgICAgICAgICAgLzE5ICAgICAgICAgICAgICA2ICAgICAgICAgICAgICAvMjJcbiAqICAgLzE3ICAgICAgICAgIDMgICAgICAgICAgICAgICAvMjAgICAgICAgICAgICAgIDUgICAgICAgICAgICAgIC8yMlxuICogICAvMTggICAgICAgICAgMyAgICAgICAgICAgICAgIC8yMSAgICAgICAgICAgICAgNSAgICAgICAgICAgICAgLzIzXG4gKiAgIC8xOSAgICAgICAgICAzICAgICAgICAgICAgICAgLzIyICAgICAgICAgICAgICA1ICAgICAgICAgICAgICAvMjRcbiAqICAgLzIwICAgICAgICAgIDQgICAgICAgICAgICAgICAvMjQgICAgICAgICAgICAgIDUgICAgICAgICAgICAgIC8yNVxuICpcbiAqIFwibmV3Yml0c1wiIGlzIHRoZSBudW1iZXIgb2YgYml0cyB0byBleHRlbmQgdGhlIFZQQyBwcmVmaXguXG4gKiBjaWRyTWFzayA9IHZwY1ByZWZpeCArIG5ld2JpdHMuXG4gKi9cbmNvbnN0IFNVQk5FVF9ORVdCSVRTOiBSZWNvcmQ8bnVtYmVyLCB7cHJpdmF0ZUJpdHM6IG51bWJlcjsgb3RoZXJCaXRzOiBudW1iZXJ9PiA9XG4gIHtcbiAgICAxNjoge3ByaXZhdGVCaXRzOiAzLCBvdGhlckJpdHM6IDZ9LFxuICAgIDE3OiB7cHJpdmF0ZUJpdHM6IDMsIG90aGVyQml0czogNX0sXG4gICAgMTg6IHtwcml2YXRlQml0czogMywgb3RoZXJCaXRzOiA1fSxcbiAgICAxOToge3ByaXZhdGVCaXRzOiAzLCBvdGhlckJpdHM6IDV9LFxuICAgIDIwOiB7cHJpdmF0ZUJpdHM6IDQsIG90aGVyQml0czogNX0sXG4gIH07XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgU3RhbmRhcmROZXR3b3JrLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YW5kYXJkTmV0d29ya1Byb3BzIGV4dGVuZHMgRXh0ZW5kZWRDb25zdHJ1Y3RQcm9wcyB7XG4gIC8qKlxuICAgKiBOYW1lIGZvciB0aGUgVlBDLiBVc2VkIGFzIHRoZSBWUEMgbmFtZSB0YWcgYW5kIHRoZSBTU00gcGFyYW1ldGVyIHBhdGhcbiAgICogc2VnbWVudCAoZS5nLiAvbmV0d29yay97bmFtZX0vdnBjKS5cbiAgICovXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogRnVsbCBWUEMgQ0lEUiBibG9jay4gZS5nLiBcIjEwLjAuMC4wLzIwXCIuXG4gICAqIFN1cHBvcnRlZCBWUEMgcHJlZml4IGxlbmd0aHMgZm9yIGF1dG8tc2l6aW5nOiAvMTYsIC8xNywgLzE4LCAvMTksIC8yMC5cbiAgICovXG4gIHJlYWRvbmx5IHZwY0NpZHI6IHN0cmluZztcblxuICAvLyBUT0RPIFN1Z2dlc3QgYm90aCB0aGlzIGFuZCB0aGUgdGVycmFmb3JtIG1vZHVsZSBkZWZhdWx0IHRvIDNcbiAgLyoqXG4gICAqIE51bWJlciBvZiBhdmFpbGFiaWxpdHkgem9uZXMgdG8gZGVwbG95IHN1Ym5ldHMgaW50by4gRGVmYXVsdCBpcyAyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAyXG4gICAqL1xuICByZWFkb25seSBhekNvdW50PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBOQVQgZ2F0ZXdheSBjb25maWd1cmF0aW9uLiBEZWZhdWx0IGlzICdub25lJy5cbiAgICpcbiAgICogQGRlZmF1bHQgJ25vbmUnXG4gICAqL1xuICByZWFkb25seSBuYXRUeXBlPzogTmF0VHlwZTtcblxuICAvKipcbiAgICogV2hldGhlciB0byBjcmVhdGUgcHVibGljIHN1Ym5ldHMuIERlZmF1bHQgaXMgdHJ1ZS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgY3JlYXRlUHVibGljU3VibmV0cz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gY3JlYXRlIHByaXZhdGUgc3VibmV0cyAoUFJJVkFURV9XSVRIX0VHUkVTUykuIERlZmF1bHQgaXMgdHJ1ZS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgY3JlYXRlUHJpdmF0ZVN1Ym5ldHM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNyZWF0ZSBpbnRyYSBzdWJuZXRzIChQUklWQVRFX0lTT0xBVEVELCBubyBlZ3Jlc3MpLiBEZWZhdWx0IGlzIHRydWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGNyZWF0ZUludHJhU3VibmV0cz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gY3JlYXRlIGRhdGFiYXNlIHN1Ym5ldHMgKFBSSVZBVEVfV0lUSF9FR1JFU1MpLiBEZWZhdWx0IGlzIHRydWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGNyZWF0ZURhdGFiYXNlU3VibmV0cz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gY3JlYXRlIGVsYXN0aWNhY2hlIHN1Ym5ldHMgKFBSSVZBVEVfV0lUSF9FR1JFU1MpLiBEZWZhdWx0IGlzIHRydWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGNyZWF0ZUVsYXN0aWNhY2hlU3VibmV0cz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gY3JlYXRlIHJlZHNoaWZ0IHN1Ym5ldHMgKFBSSVZBVEVfV0lUSF9FR1JFU1MpLiBEZWZhdWx0IGlzIGZhbHNlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgY3JlYXRlUmVkc2hpZnRTdWJuZXRzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQXBwbHkgYSB1bmlmb3JtIENJRFIgbWFzayB0byBBTEwgc3VibmV0IGdyb3Vwcywgb3ZlcnJpZGluZyB0aGUgdGVycmFmb3JtLXN0eWxlXG4gICAqIGF1dG8tc2l6aW5nLiBXaGVuIHNldCwgYWxsIGdyb3VwcyByZWNlaXZlIHRoZSBzYW1lIG1hc2sgcmVnYXJkbGVzcyBvZiB0eXBlLlxuICAgKiBQZXItZ3JvdXAgb3ZlcnJpZGVzIGJlbG93IHRha2UgcHJlY2VkZW5jZSBvdmVyIHRoaXMgdmFsdWUuXG4gICAqL1xuICByZWFkb25seSBzdWJuZXRDaWRyTWFzaz86IG51bWJlcjtcblxuICAvKipcbiAgICogQ0lEUiBtYXNrIG92ZXJyaWRlIGZvciBwcml2YXRlIHN1Ym5ldHMgb25seS5cbiAgICpcbiAgICogRXF1aXZhbGVudCB0byBzZXR0aW5nIGBwcml2YXRlX25ld2JpdHNgIGluIHRlcnJhZm9ybS1hd3MtdnBjOlxuICAgKiAgIHByaXZhdGVTdWJuZXRDaWRyTWFzayA9IHZwY1ByZWZpeCArIHByaXZhdGVfbmV3Yml0c1xuICAgKlxuICAgKiBUYWtlcyBwcmVjZWRlbmNlIG92ZXIgc3VibmV0Q2lkck1hc2sgYW5kIGF1dG8tc2l6aW5nLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJpdmF0ZVN1Ym5ldENpZHJNYXNrPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBDSURSIG1hc2sgb3ZlcnJpZGUgZm9yIHB1YmxpYyBzdWJuZXRzIG9ubHkuXG4gICAqXG4gICAqIEVxdWl2YWxlbnQgdG8gc2V0dGluZyBgcHVibGljX25ld2JpdHNgIGluIHRlcnJhZm9ybS1hd3MtdnBjOlxuICAgKiAgIHB1YmxpY1N1Ym5ldENpZHJNYXNrID0gdnBjUHJlZml4ICsgcHVibGljX25ld2JpdHNcbiAgICpcbiAgICogVGFrZXMgcHJlY2VkZW5jZSBvdmVyIHN1Ym5ldENpZHJNYXNrIGFuZCBhdXRvLXNpemluZy5cbiAgICovXG4gIHJlYWRvbmx5IHB1YmxpY1N1Ym5ldENpZHJNYXNrPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBDSURSIG1hc2sgb3ZlcnJpZGUgZm9yIGludHJhIHN1Ym5ldHMgb25seS5cbiAgICpcbiAgICogRXF1aXZhbGVudCB0byBzZXR0aW5nIGBpbnRyYV9uZXdiaXRzYCBpbiB0ZXJyYWZvcm0tYXdzLXZwYy5cbiAgICogVGFrZXMgcHJlY2VkZW5jZSBvdmVyIHN1Ym5ldENpZHJNYXNrIGFuZCBhdXRvLXNpemluZy5cbiAgICovXG4gIHJlYWRvbmx5IGludHJhU3VibmV0Q2lkck1hc2s/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIENJRFIgbWFzayBvdmVycmlkZSBmb3IgZGF0YWJhc2Ugc3VibmV0cyBvbmx5LlxuICAgKlxuICAgKiBFcXVpdmFsZW50IHRvIHNldHRpbmcgYGRhdGFiYXNlX25ld2JpdHNgIGluIHRlcnJhZm9ybS1hd3MtdnBjLlxuICAgKiBUYWtlcyBwcmVjZWRlbmNlIG92ZXIgc3VibmV0Q2lkck1hc2sgYW5kIGF1dG8tc2l6aW5nLlxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YWJhc2VTdWJuZXRDaWRyTWFzaz86IG51bWJlcjtcblxuICAvKipcbiAgICogQ0lEUiBtYXNrIG92ZXJyaWRlIGZvciBlbGFzdGljYWNoZSBzdWJuZXRzIG9ubHkuXG4gICAqXG4gICAqIEVxdWl2YWxlbnQgdG8gc2V0dGluZyBgZWxhc3RpY2FjaGVfbmV3Yml0c2AgaW4gdGVycmFmb3JtLWF3cy12cGMuXG4gICAqIFRha2VzIHByZWNlZGVuY2Ugb3ZlciBzdWJuZXRDaWRyTWFzayBhbmQgYXV0by1zaXppbmcuXG4gICAqL1xuICByZWFkb25seSBlbGFzdGljYWNoZVN1Ym5ldENpZHJNYXNrPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBDSURSIG1hc2sgb3ZlcnJpZGUgZm9yIHJlZHNoaWZ0IHN1Ym5ldHMgb25seS5cbiAgICpcbiAgICogRXF1aXZhbGVudCB0byBzZXR0aW5nIGByZWRzaGlmdF9uZXdiaXRzYCBpbiB0ZXJyYWZvcm0tYXdzLXZwYy5cbiAgICogVGFrZXMgcHJlY2VkZW5jZSBvdmVyIHN1Ym5ldENpZHJNYXNrIGFuZCBhdXRvLXNpemluZy5cbiAgICovXG4gIHJlYWRvbmx5IHJlZHNoaWZ0U3VibmV0Q2lkck1hc2s/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gY3JlYXRlIGFuIFMzIGdhdGV3YXkgVlBDIGVuZHBvaW50LiBUaGUgZW5kcG9pbnQgaXMgYXR0YWNoZWQgdG9cbiAgICogcHJpdmF0ZSwgZGF0YWJhc2UsIGVsYXN0aWNhY2hlLCByZWRzaGlmdCwgYW5kIGludHJhIHN1Ym5ldHMgKHdoaWNoZXZlciBhcmVcbiAgICogZW5hYmxlZCkuIERlZmF1bHQgaXMgdHJ1ZS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgY3JlYXRlUzNFbmRwb2ludD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gY3JlYXRlIGEgRHluYW1vREIgZ2F0ZXdheSBWUEMgZW5kcG9pbnQuIEF0dGFjaGVkIHRvIHRoZSBzYW1lXG4gICAqIHN1Ym5ldCBncm91cHMgYXMgdGhlIFMzIGVuZHBvaW50LiBEZWZhdWx0IGlzIHRydWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGNyZWF0ZUR5bmFtb0RiRW5kcG9pbnQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHN0b3JlIFZQQyBhbmQgc3VibmV0IElEcyBpbiBBV1MgU1NNIFBhcmFtZXRlciBTdG9yZSB2aWEgdGhlXG4gICAqIE5ldHdvcmtQYXJhbWV0ZXJzIGNvbnN0cnVjdC4gRGVmYXVsdCBpcyB0cnVlLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBzdG9yZVBhcmFtZXRlcnM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBTU00gcGFyYW1ldGVyIHByZWZpeCB1c2VkIHdoZW4gc3RvcmVQYXJhbWV0ZXJzIGlzIHRydWUuIERlZmF1bHQgaXMgXCIvbmV0d29ya1wiLlxuICAgKlxuICAgKiBAZGVmYXVsdCBcIi9uZXR3b3JrXCJcbiAgICovXG4gIHJlYWRvbmx5IHBhcmFtZXRlcnNQcmVmaXg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gY3JlYXRlIENsb3VkRm9ybWF0aW9uIHN0YWNrIG91dHB1dHMgZm9yIFZQQyBhbmQgc3VibmV0IElEcy5cbiAgICogRGVmYXVsdCBpcyB0cnVlLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBjcmVhdGVPdXRwdXRzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCB0YWdzIHRvIGFwcGx5IHRvIHB1YmxpYyBzdWJuZXRzLlxuICAgKi9cbiAgcmVhZG9ubHkgcHVibGljU3VibmV0VGFncz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG5cbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgdGFncyB0byBhcHBseSB0byBwcml2YXRlIHN1Ym5ldHMuXG4gICAqL1xuICByZWFkb25seSBwcml2YXRlU3VibmV0VGFncz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG5cbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgdGFncyB0byBhcHBseSB0byBpbnRyYSBzdWJuZXRzLlxuICAgKi9cbiAgcmVhZG9ubHkgaW50cmFTdWJuZXRUYWdzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCB0YWdzIHRvIGFwcGx5IHRvIGRhdGFiYXNlIHN1Ym5ldHMuXG4gICAqL1xuICByZWFkb25seSBkYXRhYmFzZVN1Ym5ldFRhZ3M/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIHRhZ3MgdG8gYXBwbHkgdG8gZWxhc3RpY2FjaGUgc3VibmV0cy5cbiAgICovXG4gIHJlYWRvbmx5IGVsYXN0aWNhY2hlU3VibmV0VGFncz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG5cbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgdGFncyB0byBhcHBseSB0byByZWRzaGlmdCBzdWJuZXRzLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVkc2hpZnRTdWJuZXRUYWdzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbn1cblxuLyoqXG4gKiBSZXNvbHZlZCBDSURSIG1hc2sgZm9yIGVhY2ggc3VibmV0IGdyb3VwLlxuICovXG5pbnRlcmZhY2UgUmVzb2x2ZWRTdWJuZXRNYXNrcyB7XG4gIHByaXZhdGU6IG51bWJlcjtcbiAgcHVibGljOiBudW1iZXI7XG4gIGludHJhOiBudW1iZXI7XG4gIGRhdGFiYXNlOiBudW1iZXI7XG4gIGVsYXN0aWNhY2hlOiBudW1iZXI7XG4gIHJlZHNoaWZ0OiBudW1iZXI7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB0aGUgQ0lEUiBtYXNrcyBmb3IgZWFjaCBzdWJuZXQgZ3JvdXAuXG4gKlxuICogUmVzb2x1dGlvbiBvcmRlciAoaGlnaGVzdCB3aW5zKTpcbiAqICAgMS4gUGVyLWdyb3VwIG92ZXJyaWRlIChlLmcuIHByaXZhdGVTdWJuZXRDaWRyTWFzaylcbiAqICAgMi4gVW5pZm9ybSBvdmVycmlkZSAgKHN1Ym5ldENpZHJNYXNrKVxuICogICAzLiBUZXJyYWZvcm0tdGFibGUgYXV0by1zaXppbmcgZnJvbSB0aGUgVlBDIHByZWZpeFxuICovXG5mdW5jdGlvbiByZXNvbHZlU3VibmV0TWFza3MoXG4gIHZwY0NpZHI6IHN0cmluZyxcbiAgcHJvcHM6IFN0YW5kYXJkTmV0d29ya1Byb3BzLFxuKTogUmVzb2x2ZWRTdWJuZXRNYXNrcyB7XG4gIGNvbnN0IHZwY1ByZWZpeCA9IE51bWJlcih2cGNDaWRyLnNwbGl0KCcvJylbMV0pO1xuXG4gIGlmICghTnVtYmVyLmlzRmluaXRlKHZwY1ByZWZpeCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgVlBDIENJRFI6ICR7dnBjQ2lkcn1gKTtcbiAgfVxuXG4gIC8vIC0tLSBBdXRvLXNpemluZyBmcm9tIHRlcnJhZm9ybSB0YWJsZXMgLS0tXG4gIGNvbnN0IGJpdHMgPSBTVUJORVRfTkVXQklUU1t2cGNQcmVmaXhdO1xuXG4gIGxldCBhdXRvUHJpdmF0ZTogbnVtYmVyO1xuICBsZXQgYXV0b090aGVyOiBudW1iZXI7XG5cbiAgaWYgKGJpdHMpIHtcbiAgICBhdXRvUHJpdmF0ZSA9IHZwY1ByZWZpeCArIGJpdHMucHJpdmF0ZUJpdHM7XG4gICAgYXV0b090aGVyID0gdnBjUHJlZml4ICsgYml0cy5vdGhlckJpdHM7XG4gIH0gZWxzZSBpZiAocHJvcHMuc3VibmV0Q2lkck1hc2sgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIEZhbGwgYmFjayB0byB1bmlmb3JtIHdoZW4gVlBDIHByZWZpeCBpcyBvdXRzaWRlIHRoZSB0YWJsZSByYW5nZVxuICAgIGF1dG9Qcml2YXRlID0gcHJvcHMuc3VibmV0Q2lkck1hc2s7XG4gICAgYXV0b090aGVyID0gcHJvcHMuc3VibmV0Q2lkck1hc2s7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFZQQyBwcmVmaXggLyR7dnBjUHJlZml4fSBpcyBub3QgaW4gdGhlIGF1dG8tc2l6aW5nIHRhYmxlIChzdXBwb3J0ZWQ6IC8xNuKAky8yMCkuIGAgK1xuICAgICAgICBgUHJvdmlkZSBzdWJuZXRDaWRyTWFzayBvciBwZXItZ3JvdXAgb3ZlcnJpZGVzLmAsXG4gICAgKTtcbiAgfVxuXG4gIC8vIFVuaWZvcm0gb3ZlcnJpZGUgcmVwbGFjZXMgYm90aCBwcml2YXRlIGFuZCBvdGhlciBkZWZhdWx0c1xuICBjb25zdCB1bmlmb3JtTWFzayA9IHByb3BzLnN1Ym5ldENpZHJNYXNrO1xuICBjb25zdCBiYXNlTWFza1ByaXZhdGUgPSB1bmlmb3JtTWFzayA/PyBhdXRvUHJpdmF0ZTtcbiAgY29uc3QgYmFzZU1hc2tPdGhlciA9IHVuaWZvcm1NYXNrID8/IGF1dG9PdGhlcjtcblxuICByZXR1cm4ge1xuICAgIHByaXZhdGU6IHByb3BzLnByaXZhdGVTdWJuZXRDaWRyTWFzayA/PyBiYXNlTWFza1ByaXZhdGUsXG4gICAgcHVibGljOiBwcm9wcy5wdWJsaWNTdWJuZXRDaWRyTWFzayA/PyBiYXNlTWFza090aGVyLFxuICAgIGludHJhOiBwcm9wcy5pbnRyYVN1Ym5ldENpZHJNYXNrID8/IGJhc2VNYXNrT3RoZXIsXG4gICAgZGF0YWJhc2U6IHByb3BzLmRhdGFiYXNlU3VibmV0Q2lkck1hc2sgPz8gYmFzZU1hc2tPdGhlcixcbiAgICBlbGFzdGljYWNoZTogcHJvcHMuZWxhc3RpY2FjaGVTdWJuZXRDaWRyTWFzayA/PyBiYXNlTWFza090aGVyLFxuICAgIHJlZHNoaWZ0OiBwcm9wcy5yZWRzaGlmdFN1Ym5ldENpZHJNYXNrID8/IGJhc2VNYXNrT3RoZXIsXG4gIH07XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIHRoYXQgdGhlIFZQQyBDSURSIGhhcyBlbm91Z2ggYWRkcmVzcyBzcGFjZSBmb3IgYWxsIGVuYWJsZWQgc3VibmV0XG4gKiBncm91cHMuIEVhY2ggZ3JvdXAgY29uc3VtZXMgYXpDb3VudCDDlyAyXigzMi1jaWRyTWFzaykgSVBzLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUFkZHJlc3NTcGFjZShcbiAgdnBjQ2lkcjogc3RyaW5nLFxuICBhekNvdW50OiBudW1iZXIsXG4gIGVuYWJsZWRHcm91cHM6IHttYXNrOiBudW1iZXI7IG5hbWU6IHN0cmluZ31bXSxcbik6IHZvaWQge1xuICBjb25zdCB2cGNQcmVmaXggPSBOdW1iZXIodnBjQ2lkci5zcGxpdCgnLycpWzFdKTtcblxuICAvLyBBV1MgYWxsb3dzIFZQQyBuZXRtYXNrcyBiZXR3ZWVuIC8xNiBhbmQgLzI4LlxuICBpZiAoIU51bWJlci5pc0ludGVnZXIodnBjUHJlZml4KSB8fCB2cGNQcmVmaXggPCAxNiB8fCB2cGNQcmVmaXggPiAyOCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBJbnZhbGlkIFZQQyBDSURSICR7dnBjQ2lkcn06IHByZWZpeCBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAvMTYgYW5kIC8yOC5gLFxuICAgICk7XG4gIH1cblxuICBpZiAoIU51bWJlci5pc0ludGVnZXIoYXpDb3VudCkgfHwgYXpDb3VudCA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGF6Q291bnQgbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXIsIGdvdCAke2F6Q291bnR9LmApO1xuICB9XG5cbiAgLy8gQVdTIHN1Ym5ldCBtYXNrcyBtdXN0IGJlIGJldHdlZW4gLzE2IGFuZCAvMjgsIGFuZCBuZXZlciBsYXJnZXIgdGhhbiB0aGVcbiAgLy8gVlBDIGl0c2VsZi5cbiAgZm9yIChjb25zdCBnIG9mIGVuYWJsZWRHcm91cHMpIHtcbiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIoZy5tYXNrKSB8fCBnLm1hc2sgPCB2cGNQcmVmaXggfHwgZy5tYXNrID4gMjgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEludmFsaWQgQ0lEUiBtYXNrIC8ke2cubWFza30gZm9yICR7Zy5uYW1lfSBzdWJuZXRzOiBtdXN0IGJlIGFuIGAgK1xuICAgICAgICAgIGBpbnRlZ2VyIGJldHdlZW4gdGhlIFZQQyBwcmVmaXggKC8ke3ZwY1ByZWZpeH0pIGFuZCAvMjguYCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgdnBjSXBzID0gMiAqKiAoMzIgLSB2cGNQcmVmaXgpO1xuICBsZXQgcmVxdWlyZWRJcHMgPSAwO1xuICBjb25zdCBkZXRhaWw6IHN0cmluZ1tdID0gW107XG5cbiAgZm9yIChjb25zdCBnIG9mIGVuYWJsZWRHcm91cHMpIHtcbiAgICBjb25zdCBzdWJuZXRJcHMgPSAyICoqICgzMiAtIGcubWFzayk7XG4gICAgY29uc3QgZ3JvdXBJcHMgPSBhekNvdW50ICogc3VibmV0SXBzO1xuICAgIHJlcXVpcmVkSXBzICs9IGdyb3VwSXBzO1xuICAgIGRldGFpbC5wdXNoKGAke2cubmFtZX06ICR7YXpDb3VudH0gw5cgLyR7Zy5tYXNrfSA9ICR7Z3JvdXBJcHN9IElQc2ApO1xuICB9XG5cbiAgaWYgKHJlcXVpcmVkSXBzID4gdnBjSXBzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFZQQyBDSURSICR7dnBjQ2lkcn0gKCR7dnBjSXBzfSBJUHMpIGlzIHRvbyBzbWFsbC5cXG5gICtcbiAgICAgICAgYFJlcXVpcmVkOiAke3JlcXVpcmVkSXBzfSBJUHMgYWNyb3NzICR7ZW5hYmxlZEdyb3Vwcy5sZW5ndGh9IHN1Ym5ldCBncm91cHM6XFxuYCArXG4gICAgICAgIGRldGFpbC5tYXAoKGQpID0+IGAgICR7ZH1gKS5qb2luKCdcXG4nKSArXG4gICAgICAgICdcXG5JbmNyZWFzZSB0aGUgVlBDIHNpemUsIHJlZHVjZSBhekNvdW50LCBvciBkaXNhYmxlIHNvbWUgc3VibmV0IGdyb3Vwcy4nLFxuICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYXBwbHlTdWJuZXRUYWdzKFxuICBzdWJuZXRzOiBlYzIuSVN1Ym5ldFtdLFxuICB0YWdzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LFxuKTogdm9pZCB7XG4gIGZvciAoY29uc3Qgc3VibmV0IG9mIHN1Ym5ldHMpIHtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh0YWdzKSkge1xuICAgICAgVGFncy5vZihzdWJuZXQpLmFkZChrZXksIHZhbHVlKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgc3RhbmRhcmQgbXVsdGktdGllciBWUEMgZm9sbG93aW5nIFRydWVNYXJrIGNvbnZlbnRpb25zLCB3aXRoIHN1Ym5ldFxuICogc2l6aW5nIHRoYXQgbWlycm9ycyB0aGUgdHJ1ZW1hcmsvdGVycmFmb3JtLWF3cy12cGMgVGVycmFmb3JtIG1vZHVsZS5cbiAqXG4gKiAqKlN1Ym5ldCBsYXlvdXQqKiAoZWFjaCBncm91cCBpcyByZXBsaWNhdGVkIGFjcm9zcyBhbGwgQVpzKTpcbiAqXG4gKiB8IEdyb3VwICAgICAgIHwgVHlwZSAgICAgICAgICAgICAgICB8IERlZmF1bHQgc2l6aW5nIChhdXRvLCBzZWUgdGFibGUgYmVsb3cpIHxcbiAqIHwtLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfFxuICogfCBwcml2YXRlICAgICB8IFBSSVZBVEVfV0lUSF9FR1JFU1MgfCBMYXJnZXIg4oCUIHNpemVkIGZvciB3b3JrbG9hZCB0cmFmZmljICAgIHxcbiAqIHwgcHVibGljICAgICAgfCBQVUJMSUMgICAgICAgICAgICAgIHwgU21hbGxlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogfCBpbnRyYSAgICAgICB8IFBSSVZBVEVfSVNPTEFURUQgICAgfCBTbWFsbGVyIOKAlCBubyBlZ3Jlc3MgICAgICAgICAgICAgICAgICAgIHxcbiAqIHwgZGF0YWJhc2UgICAgfCBQUklWQVRFX1dJVEhfRUdSRVNTIHwgU21hbGxlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogfCBlbGFzdGljYWNoZSB8IFBSSVZBVEVfV0lUSF9FR1JFU1MgfCBTbWFsbGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8IHJlZHNoaWZ0ICAgIHwgUFJJVkFURV9XSVRIX0VHUkVTUyB8IFNtYWxsZXIgKGRpc2FibGVkIGJ5IGRlZmF1bHQpICAgICAgICAgIHxcbiAqXG4gKiAqKkF1dG8tc2l6aW5nIHRhYmxlKiogKG1hdGNoZXMgdGVycmFmb3JtLWF3cy12cGMgYHByaXZhdGVfc3VibmV0c2AvYHN1Ym5ldHNgIGxvY2Fscyk6XG4gKlxuICogfCBWUEMgICAgfCBwcml2YXRlIHwgcHVibGljL2ludHJhL2RhdGFiYXNlL2VsYXN0aWNhY2hlL3JlZHNoaWZ0IHxcbiAqIHwtLS0tLS0tLXwtLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfFxuICogfCAvMTYgICAgfCAvMTkgICAgIHwgLzIyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8IC8xNyAgICB8IC8yMCAgICAgfCAvMjIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqIHwgLzE4ICAgIHwgLzIxICAgICB8IC8yMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogfCAvMTkgICAgfCAvMjIgICAgIHwgLzI0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8IC8yMCAgICB8IC8yNCAgICAgfCAvMjUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqXG4gKiBPdmVycmlkZSBzaXppbmcgdmlhIGBzdWJuZXRDaWRyTWFza2AgKHVuaWZvcm0pIG9yIHBlci1ncm91cCBwcm9wcyBsaWtlXG4gKiBgcHJpdmF0ZVN1Ym5ldENpZHJNYXNrYCwgYHB1YmxpY1N1Ym5ldENpZHJNYXNrYCwgZXRjLiDigJQgZXF1aXZhbGVudCB0byB0aGVcbiAqIGBwcml2YXRlX25ld2JpdHNgLCBgcHVibGljX25ld2JpdHNgLCAuLi4gdmFyaWFibGVzIGluIFRlcnJhZm9ybS5cbiAqXG4gKiA+ICoqTm90ZSBvbiBDSURSIHBsYWNlbWVudDoqKiBDREsgYWxsb2NhdGVzIHN1Ym5ldCBDSURScyBzZXF1ZW50aWFsbHkgZnJvbVxuICogPiB0aGUgc3RhcnQgb2YgdGhlIFZQQyBDSURSIGJsb2NrLiBUaGlzIGRpZmZlcnMgZnJvbSBUZXJyYWZvcm0ncyBwbGFjZW1lbnQsXG4gKiA+IHdoaWNoIHVzZXMgZXhwbGljaXQgYG5ldG51bWAgb2Zmc2V0cyB0byBwb3NpdGlvbiBzdWJuZXQgZ3JvdXBzIGF0IHNwZWNpZmljXG4gKiA+IGFkZHJlc3NlcyB3aXRoaW4gdGhlIFZQQy4gVGhlIHN1Ym5ldCAqc2l6ZXMqIG1hdGNoIGV4YWN0bHk7IG9ubHkgdGhlXG4gKiA+IHN0YXJ0aW5nIGFkZHJlc3NlcyB3aXRoaW4gdGhlIFZQQyBkaWZmZXIuXG4gKlxuICogR2F0ZXdheSBWUEMgZW5kcG9pbnRzIGZvciBTMyBhbmQgRHluYW1vREIgYXJlIGNyZWF0ZWQgYnkgZGVmYXVsdCBhbmQgYXR0YWNoZWRcbiAqIHRvIHByaXZhdGUsIGludHJhLCBkYXRhYmFzZSwgZWxhc3RpY2FjaGUsIGFuZCByZWRzaGlmdCByb3V0ZSB0YWJsZXMuXG4gKlxuICogVlBDIGFuZCBzdWJuZXQgSURzIGFyZSBzdG9yZWQgaW4gQVdTIFNTTSBQYXJhbWV0ZXIgU3RvcmUgdmlhIE5ldHdvcmtQYXJhbWV0ZXJzXG4gKiBhbmQgb3B0aW9uYWxseSBleHBvcnRlZCBhcyBDbG91ZEZvcm1hdGlvbiBvdXRwdXRzLlxuICovXG5leHBvcnQgY2xhc3MgU3RhbmRhcmROZXR3b3JrIGV4dGVuZHMgRXh0ZW5kZWRDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIFZQQyBjcmVhdGVkIGJ5IHRoaXMgY29uc3RydWN0LlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjOiBlYzIuVnBjO1xuXG4gIC8qKlxuICAgKiBUaGUgTmV0d29ya1BhcmFtZXRlcnMgY29uc3RydWN0IGhvbGRpbmcgU1NNIHBhdGhzIGFuZCBjcmVhdGVkIHBhcmFtZXRlcnMuXG4gICAqIFVuZGVmaW5lZCB3aGVuIHN0b3JlUGFyYW1ldGVycyBpcyBmYWxzZS5cbiAgICovXG4gIHJlYWRvbmx5IG5ldHdvcmtQYXJhbWV0ZXJzPzogTmV0d29ya1BhcmFtZXRlcnM7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFN0YW5kYXJkTmV0d29ya1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBzdGFuZGFyZFRhZ3M6IFN0YW5kYXJkVGFncy5tZXJnZShwcm9wcy5zdGFuZGFyZFRhZ3MsIExpYlN0YW5kYXJkVGFncyksXG4gICAgfSk7XG5cbiAgICAvLyBUT0RPIFlvdSBjaGFuZ2UgdGhlIGRlZmF1bHQgaGVyZSBEYXJlblxuICAgIGNvbnN0IGF6Q291bnQgPSBwcm9wcy5hekNvdW50ID8/IDI7XG4gICAgY29uc3QgbmF0VHlwZSA9IHByb3BzLm5hdFR5cGUgPz8gJ25vbmUnO1xuXG4gICAgY29uc3QgbmF0R2F0ZXdheXMgPVxuICAgICAgbmF0VHlwZSA9PT0gJ211bHRpJyA/IGF6Q291bnQgOiBuYXRUeXBlID09PSAnc2luZ2xlJyA/IDEgOiAwO1xuXG4gICAgLy8gVE9ETyBOZWVkIHRvIGFkZCBzdXBwb3J0IGZvciByZWdpb25hbCBOQVRcbiAgICAvLyBUT0RPIE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIHBvb3IgTkFUXG5cbiAgICAvLyBUT0RPIE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIG5ldHdvcmsgZmlyZXdhbGxcblxuICAgIGNvbnN0IGNyZWF0ZVB1YmxpYyA9IHByb3BzLmNyZWF0ZVB1YmxpY1N1Ym5ldHMgPz8gdHJ1ZTtcbiAgICBjb25zdCBjcmVhdGVQcml2YXRlID0gcHJvcHMuY3JlYXRlUHJpdmF0ZVN1Ym5ldHMgPz8gdHJ1ZTtcbiAgICBjb25zdCBjcmVhdGVJbnRyYSA9IHByb3BzLmNyZWF0ZUludHJhU3VibmV0cyA/PyB0cnVlO1xuICAgIGNvbnN0IGNyZWF0ZURhdGFiYXNlID0gcHJvcHMuY3JlYXRlRGF0YWJhc2VTdWJuZXRzID8/IHRydWU7XG4gICAgY29uc3QgY3JlYXRlRWxhc3RpY2FjaGUgPSBwcm9wcy5jcmVhdGVFbGFzdGljYWNoZVN1Ym5ldHMgPz8gdHJ1ZTtcbiAgICBjb25zdCBjcmVhdGVSZWRzaGlmdCA9IHByb3BzLmNyZWF0ZVJlZHNoaWZ0U3VibmV0cyA/PyBmYWxzZTtcblxuICAgIGNvbnN0IG1hc2tzID0gcmVzb2x2ZVN1Ym5ldE1hc2tzKHByb3BzLnZwY0NpZHIsIHByb3BzKTtcblxuICAgIGNvbnN0IGVuYWJsZWRHcm91cHM6IHttYXNrOiBudW1iZXI7IG5hbWU6IHN0cmluZ31bXSA9IFtdO1xuICAgIGlmIChjcmVhdGVQdWJsaWMpIGVuYWJsZWRHcm91cHMucHVzaCh7bWFzazogbWFza3MucHVibGljLCBuYW1lOiAncHVibGljJ30pO1xuICAgIGlmIChjcmVhdGVQcml2YXRlKVxuICAgICAgZW5hYmxlZEdyb3Vwcy5wdXNoKHttYXNrOiBtYXNrcy5wcml2YXRlLCBuYW1lOiAncHJpdmF0ZSd9KTtcbiAgICBpZiAoY3JlYXRlSW50cmEpIGVuYWJsZWRHcm91cHMucHVzaCh7bWFzazogbWFza3MuaW50cmEsIG5hbWU6ICdpbnRyYSd9KTtcbiAgICBpZiAoY3JlYXRlRGF0YWJhc2UpXG4gICAgICBlbmFibGVkR3JvdXBzLnB1c2goe21hc2s6IG1hc2tzLmRhdGFiYXNlLCBuYW1lOiAnZGF0YWJhc2UnfSk7XG4gICAgaWYgKGNyZWF0ZUVsYXN0aWNhY2hlKVxuICAgICAgZW5hYmxlZEdyb3Vwcy5wdXNoKHttYXNrOiBtYXNrcy5lbGFzdGljYWNoZSwgbmFtZTogJ2VsYXN0aWNhY2hlJ30pO1xuICAgIGlmIChjcmVhdGVSZWRzaGlmdClcbiAgICAgIGVuYWJsZWRHcm91cHMucHVzaCh7bWFzazogbWFza3MucmVkc2hpZnQsIG5hbWU6ICdyZWRzaGlmdCd9KTtcblxuICAgIHZhbGlkYXRlQWRkcmVzc1NwYWNlKHByb3BzLnZwY0NpZHIsIGF6Q291bnQsIGVuYWJsZWRHcm91cHMpO1xuXG4gICAgY29uc3Qgc3VibmV0Q29uZmlndXJhdGlvbjogZWMyLlN1Ym5ldENvbmZpZ3VyYXRpb25bXSA9IFtdO1xuXG4gICAgaWYgKGNyZWF0ZVByaXZhdGUpIHtcbiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb24ucHVzaCh7XG4gICAgICAgIG5hbWU6ICdwcml2YXRlJyxcbiAgICAgICAgc3VibmV0VHlwZTogZWMyLlN1Ym5ldFR5cGUuUFJJVkFURV9XSVRIX0VHUkVTUyxcbiAgICAgICAgY2lkck1hc2s6IG1hc2tzLnByaXZhdGUsXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKGNyZWF0ZVB1YmxpYykge1xuICAgICAgc3VibmV0Q29uZmlndXJhdGlvbi5wdXNoKHtcbiAgICAgICAgbmFtZTogJ3B1YmxpYycsXG4gICAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBVQkxJQyxcbiAgICAgICAgY2lkck1hc2s6IG1hc2tzLnB1YmxpYyxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoY3JlYXRlSW50cmEpIHtcbiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb24ucHVzaCh7XG4gICAgICAgIG5hbWU6ICdpbnRyYScsXG4gICAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfSVNPTEFURUQsXG4gICAgICAgIGNpZHJNYXNrOiBtYXNrcy5pbnRyYSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoY3JlYXRlRGF0YWJhc2UpIHtcbiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb24ucHVzaCh7XG4gICAgICAgIG5hbWU6ICdkYXRhYmFzZScsXG4gICAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfV0lUSF9FR1JFU1MsXG4gICAgICAgIGNpZHJNYXNrOiBtYXNrcy5kYXRhYmFzZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoY3JlYXRlRWxhc3RpY2FjaGUpIHtcbiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb24ucHVzaCh7XG4gICAgICAgIG5hbWU6ICdlbGFzdGljYWNoZScsXG4gICAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfV0lUSF9FR1JFU1MsXG4gICAgICAgIGNpZHJNYXNrOiBtYXNrcy5lbGFzdGljYWNoZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoY3JlYXRlUmVkc2hpZnQpIHtcbiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb24ucHVzaCh7XG4gICAgICAgIG5hbWU6ICdyZWRzaGlmdCcsXG4gICAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfV0lUSF9FR1JFU1MsXG4gICAgICAgIGNpZHJNYXNrOiBtYXNrcy5yZWRzaGlmdCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMudnBjID0gbmV3IGVjMi5WcGModGhpcywgJ1ZwYycsIHtcbiAgICAgIHZwY05hbWU6IHByb3BzLm5hbWUsXG4gICAgICBtYXhBenM6IGF6Q291bnQsXG4gICAgICBuYXRHYXRld2F5cyxcbiAgICAgIGlwQWRkcmVzc2VzOiBlYzIuSXBBZGRyZXNzZXMuY2lkcihwcm9wcy52cGNDaWRyKSxcbiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb24sXG4gICAgfSk7XG5cbiAgICAvLyBBcHBseSBwZXItc3VibmV0LWdyb3VwIHRhZ3NcbiAgICBpZiAocHJvcHMucHVibGljU3VibmV0VGFncyAmJiBjcmVhdGVQdWJsaWMpIHtcbiAgICAgIGFwcGx5U3VibmV0VGFncyhcbiAgICAgICAgdGhpcy52cGMuc2VsZWN0U3VibmV0cyh7c3VibmV0R3JvdXBOYW1lOiAncHVibGljJ30pLnN1Ym5ldHMsXG4gICAgICAgIHByb3BzLnB1YmxpY1N1Ym5ldFRhZ3MsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAocHJvcHMucHJpdmF0ZVN1Ym5ldFRhZ3MgJiYgY3JlYXRlUHJpdmF0ZSkge1xuICAgICAgYXBwbHlTdWJuZXRUYWdzKFxuICAgICAgICB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdwcml2YXRlJ30pLnN1Ym5ldHMsXG4gICAgICAgIHByb3BzLnByaXZhdGVTdWJuZXRUYWdzLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLmludHJhU3VibmV0VGFncyAmJiBjcmVhdGVJbnRyYSkge1xuICAgICAgYXBwbHlTdWJuZXRUYWdzKFxuICAgICAgICB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdpbnRyYSd9KS5zdWJuZXRzLFxuICAgICAgICBwcm9wcy5pbnRyYVN1Ym5ldFRhZ3MsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAocHJvcHMuZGF0YWJhc2VTdWJuZXRUYWdzICYmIGNyZWF0ZURhdGFiYXNlKSB7XG4gICAgICBhcHBseVN1Ym5ldFRhZ3MoXG4gICAgICAgIHRoaXMudnBjLnNlbGVjdFN1Ym5ldHMoe3N1Ym5ldEdyb3VwTmFtZTogJ2RhdGFiYXNlJ30pLnN1Ym5ldHMsXG4gICAgICAgIHByb3BzLmRhdGFiYXNlU3VibmV0VGFncyxcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChwcm9wcy5lbGFzdGljYWNoZVN1Ym5ldFRhZ3MgJiYgY3JlYXRlRWxhc3RpY2FjaGUpIHtcbiAgICAgIGFwcGx5U3VibmV0VGFncyhcbiAgICAgICAgdGhpcy52cGMuc2VsZWN0U3VibmV0cyh7c3VibmV0R3JvdXBOYW1lOiAnZWxhc3RpY2FjaGUnfSkuc3VibmV0cyxcbiAgICAgICAgcHJvcHMuZWxhc3RpY2FjaGVTdWJuZXRUYWdzLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLnJlZHNoaWZ0U3VibmV0VGFncyAmJiBjcmVhdGVSZWRzaGlmdCkge1xuICAgICAgYXBwbHlTdWJuZXRUYWdzKFxuICAgICAgICB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdyZWRzaGlmdCd9KS5zdWJuZXRzLFxuICAgICAgICBwcm9wcy5yZWRzaGlmdFN1Ym5ldFRhZ3MsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEJ1aWxkIHRoZSBsaXN0IG9mIHN1Ym5ldCBncm91cHMgZm9yIGdhdGV3YXkgZW5kcG9pbnQgcm91dGUgdGFibGVzLlxuICAgIGNvbnN0IGVuZHBvaW50U3VibmV0czogZWMyLlN1Ym5ldFNlbGVjdGlvbltdID0gW107XG4gICAgaWYgKGNyZWF0ZVByaXZhdGUpIGVuZHBvaW50U3VibmV0cy5wdXNoKHtzdWJuZXRHcm91cE5hbWU6ICdwcml2YXRlJ30pO1xuICAgIGlmIChjcmVhdGVJbnRyYSkgZW5kcG9pbnRTdWJuZXRzLnB1c2goe3N1Ym5ldEdyb3VwTmFtZTogJ2ludHJhJ30pO1xuICAgIGlmIChjcmVhdGVEYXRhYmFzZSkgZW5kcG9pbnRTdWJuZXRzLnB1c2goe3N1Ym5ldEdyb3VwTmFtZTogJ2RhdGFiYXNlJ30pO1xuICAgIGlmIChjcmVhdGVFbGFzdGljYWNoZSlcbiAgICAgIGVuZHBvaW50U3VibmV0cy5wdXNoKHtzdWJuZXRHcm91cE5hbWU6ICdlbGFzdGljYWNoZSd9KTtcbiAgICBpZiAoY3JlYXRlUmVkc2hpZnQpIGVuZHBvaW50U3VibmV0cy5wdXNoKHtzdWJuZXRHcm91cE5hbWU6ICdyZWRzaGlmdCd9KTtcblxuICAgIGlmICgocHJvcHMuY3JlYXRlUzNFbmRwb2ludCA/PyB0cnVlKSAmJiBlbmRwb2ludFN1Ym5ldHMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy52cGMuYWRkR2F0ZXdheUVuZHBvaW50KCdTM0dhdGV3YXlFbmRwb2ludCcsIHtcbiAgICAgICAgc2VydmljZTogZWMyLkdhdGV3YXlWcGNFbmRwb2ludEF3c1NlcnZpY2UuUzMsXG4gICAgICAgIHN1Ym5ldHM6IGVuZHBvaW50U3VibmV0cyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICgocHJvcHMuY3JlYXRlRHluYW1vRGJFbmRwb2ludCA/PyB0cnVlKSAmJiBlbmRwb2ludFN1Ym5ldHMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy52cGMuYWRkR2F0ZXdheUVuZHBvaW50KCdEeW5hbW9EYkdhdGV3YXlFbmRwb2ludCcsIHtcbiAgICAgICAgc2VydmljZTogZWMyLkdhdGV3YXlWcGNFbmRwb2ludEF3c1NlcnZpY2UuRFlOQU1PREIsXG4gICAgICAgIHN1Ym5ldHM6IGVuZHBvaW50U3VibmV0cyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIENsb3VkRm9ybWF0aW9uIG91dHB1dHNcbiAgICBpZiAocHJvcHMuY3JlYXRlT3V0cHV0cyA/PyB0cnVlKSB7XG4gICAgICBjb25zdCBzdGFja05hbWUgPSBTdGFjay5vZih0aGlzKS5zdGFja05hbWU7XG5cbiAgICAgIG5ldyBDZm5PdXRwdXQodGhpcywgJ1ZwY0lkJywge1xuICAgICAgICB2YWx1ZTogdGhpcy52cGMudnBjSWQsXG4gICAgICAgIGV4cG9ydE5hbWU6IGAke3N0YWNrTmFtZX06VnBjSWRgLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChjcmVhdGVQdWJsaWMpIHtcbiAgICAgICAgbmV3IENmbk91dHB1dCh0aGlzLCAnUHVibGljU3VibmV0SWRzJywge1xuICAgICAgICAgIHZhbHVlOiB0aGlzLnZwY1xuICAgICAgICAgICAgLnNlbGVjdFN1Ym5ldHMoe3N1Ym5ldEdyb3VwTmFtZTogJ3B1YmxpYyd9KVxuICAgICAgICAgICAgLnN1Ym5ldElkcy5qb2luKCcsJyksXG4gICAgICAgICAgZXhwb3J0TmFtZTogYCR7c3RhY2tOYW1lfTpQdWJsaWNTdWJuZXRJZHNgLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChjcmVhdGVQcml2YXRlKSB7XG4gICAgICAgIG5ldyBDZm5PdXRwdXQodGhpcywgJ1ByaXZhdGVTdWJuZXRJZHMnLCB7XG4gICAgICAgICAgdmFsdWU6IHRoaXMudnBjXG4gICAgICAgICAgICAuc2VsZWN0U3VibmV0cyh7c3VibmV0R3JvdXBOYW1lOiAncHJpdmF0ZSd9KVxuICAgICAgICAgICAgLnN1Ym5ldElkcy5qb2luKCcsJyksXG4gICAgICAgICAgZXhwb3J0TmFtZTogYCR7c3RhY2tOYW1lfTpQcml2YXRlU3VibmV0SWRzYCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY3JlYXRlSW50cmEpIHtcbiAgICAgICAgbmV3IENmbk91dHB1dCh0aGlzLCAnSW50cmFTdWJuZXRJZHMnLCB7XG4gICAgICAgICAgdmFsdWU6IHRoaXMudnBjXG4gICAgICAgICAgICAuc2VsZWN0U3VibmV0cyh7c3VibmV0R3JvdXBOYW1lOiAnaW50cmEnfSlcbiAgICAgICAgICAgIC5zdWJuZXRJZHMuam9pbignLCcpLFxuICAgICAgICAgIGV4cG9ydE5hbWU6IGAke3N0YWNrTmFtZX06SW50cmFTdWJuZXRJZHNgLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChjcmVhdGVEYXRhYmFzZSkge1xuICAgICAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsICdEYXRhYmFzZVN1Ym5ldElkcycsIHtcbiAgICAgICAgICB2YWx1ZTogdGhpcy52cGNcbiAgICAgICAgICAgIC5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdkYXRhYmFzZSd9KVxuICAgICAgICAgICAgLnN1Ym5ldElkcy5qb2luKCcsJyksXG4gICAgICAgICAgZXhwb3J0TmFtZTogYCR7c3RhY2tOYW1lfTpEYXRhYmFzZVN1Ym5ldElkc2AsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGNyZWF0ZUVsYXN0aWNhY2hlKSB7XG4gICAgICAgIG5ldyBDZm5PdXRwdXQodGhpcywgJ0VsYXN0aWNhY2hlU3VibmV0SWRzJywge1xuICAgICAgICAgIHZhbHVlOiB0aGlzLnZwY1xuICAgICAgICAgICAgLnNlbGVjdFN1Ym5ldHMoe3N1Ym5ldEdyb3VwTmFtZTogJ2VsYXN0aWNhY2hlJ30pXG4gICAgICAgICAgICAuc3VibmV0SWRzLmpvaW4oJywnKSxcbiAgICAgICAgICBleHBvcnROYW1lOiBgJHtzdGFja05hbWV9OkVsYXN0aWNhY2hlU3VibmV0SWRzYCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY3JlYXRlUmVkc2hpZnQpIHtcbiAgICAgICAgbmV3IENmbk91dHB1dCh0aGlzLCAnUmVkc2hpZnRTdWJuZXRJZHMnLCB7XG4gICAgICAgICAgdmFsdWU6IHRoaXMudnBjXG4gICAgICAgICAgICAuc2VsZWN0U3VibmV0cyh7c3VibmV0R3JvdXBOYW1lOiAncmVkc2hpZnQnfSlcbiAgICAgICAgICAgIC5zdWJuZXRJZHMuam9pbignLCcpLFxuICAgICAgICAgIGV4cG9ydE5hbWU6IGAke3N0YWNrTmFtZX06UmVkc2hpZnRTdWJuZXRJZHNgLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTU00gUGFyYW1ldGVyIFN0b3JlIHZpYSBOZXR3b3JrUGFyYW1ldGVyc1xuICAgIGlmIChwcm9wcy5zdG9yZVBhcmFtZXRlcnMgPz8gdHJ1ZSkge1xuICAgICAgdGhpcy5uZXR3b3JrUGFyYW1ldGVycyA9IG5ldyBOZXR3b3JrUGFyYW1ldGVycyhcbiAgICAgICAgdGhpcyxcbiAgICAgICAgJ05ldHdvcmtQYXJhbWV0ZXJzJyxcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IHByb3BzLm5hbWUsXG4gICAgICAgICAgcHJlZml4OiBwcm9wcy5wYXJhbWV0ZXJzUHJlZml4LFxuICAgICAgICAgIGNyZWF0ZTogdHJ1ZSxcbiAgICAgICAgICBsb29rdXBWcGM6IGZhbHNlLFxuICAgICAgICAgIGxvb2t1cEF6czogZmFsc2UsXG4gICAgICAgICAgbG9va3VwUHVibGljU3VibmV0czogZmFsc2UsXG4gICAgICAgICAgbG9va3VwUHJpdmF0ZVN1Ym5ldHM6IGZhbHNlLFxuICAgICAgICAgIGxvb2t1cEludHJhU3VibmV0czogZmFsc2UsXG4gICAgICAgICAgbG9va3VwRGF0YWJhc2VTdWJuZXRzOiBmYWxzZSxcbiAgICAgICAgICBsb29rdXBFbGFzdGljYWNoZVN1Ym5ldHM6IGZhbHNlLFxuICAgICAgICAgIGxvb2t1cFJlZHNoaWZ0U3VibmV0czogZmFsc2UsXG4gICAgICAgICAgbG9va3VwT3V0cG9zdFN1Ym5ldHM6IGZhbHNlLFxuICAgICAgICAgIHZwY0lkOiB0aGlzLnZwYy52cGNJZCxcbiAgICAgICAgICBhenM6IHRoaXMudnBjLmF2YWlsYWJpbGl0eVpvbmVzLFxuICAgICAgICAgIHB1YmxpY1N1Ym5ldElkczogY3JlYXRlUHVibGljXG4gICAgICAgICAgICA/IHRoaXMudnBjLnNlbGVjdFN1Ym5ldHMoe3N1Ym5ldEdyb3VwTmFtZTogJ3B1YmxpYyd9KS5zdWJuZXRJZHNcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgIHByaXZhdGVTdWJuZXRJZHM6IGNyZWF0ZVByaXZhdGVcbiAgICAgICAgICAgID8gdGhpcy52cGMuc2VsZWN0U3VibmV0cyh7c3VibmV0R3JvdXBOYW1lOiAncHJpdmF0ZSd9KS5zdWJuZXRJZHNcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGludHJhU3VibmV0SWRzOiBjcmVhdGVJbnRyYVxuICAgICAgICAgICAgPyB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdpbnRyYSd9KS5zdWJuZXRJZHNcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGRhdGFiYXNlU3VibmV0SWRzOiBjcmVhdGVEYXRhYmFzZVxuICAgICAgICAgICAgPyB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdkYXRhYmFzZSd9KS5zdWJuZXRJZHNcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGVsYXN0aWNhY2hlU3VibmV0SWRzOiBjcmVhdGVFbGFzdGljYWNoZVxuICAgICAgICAgICAgPyB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdlbGFzdGljYWNoZSd9KS5zdWJuZXRJZHNcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgIHJlZHNoaWZ0U3VibmV0SWRzOiBjcmVhdGVSZWRzaGlmdFxuICAgICAgICAgICAgPyB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdyZWRzaGlmdCd9KS5zdWJuZXRJZHNcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
423
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhcmQtbmV0d29yay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hd3MtdnBjL2xpYi9zdGFuZGFyZC1uZXR3b3JrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUFtRDtBQUNuRCwyQ0FBMkM7QUFFM0MsMkNBSXVCO0FBQ3ZCLDZDQUErQztBQUMvQyxpREFBMkM7QUFDM0MsNkRBQXVEO0FBSXZELDhFQUE4RTtBQUU5RTs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sY0FBYyxHQUNsQjtJQUNFLEVBQUUsRUFBRSxFQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBQztJQUNsQyxFQUFFLEVBQUUsRUFBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUM7SUFDbEMsRUFBRSxFQUFFLEVBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFDO0lBQ2xDLEVBQUUsRUFBRSxFQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBQztJQUNsQyxFQUFFLEVBQUUsRUFBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUM7Q0FDbkMsQ0FBQztBQXFPSjs7Ozs7OztHQU9HO0FBQ0gsU0FBUyxrQkFBa0IsQ0FDekIsT0FBZSxFQUNmLEtBQTJCOztJQUUzQixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRWhELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDaEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRUQsNENBQTRDO0lBQzVDLE1BQU0sSUFBSSxHQUFHLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUV2QyxJQUFJLFdBQW1CLENBQUM7SUFDeEIsSUFBSSxTQUFpQixDQUFDO0lBRXRCLElBQUksSUFBSSxFQUFFLENBQUM7UUFDVCxXQUFXLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDM0MsU0FBUyxHQUFHLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3pDLENBQUM7U0FBTSxJQUFJLEtBQUssQ0FBQyxjQUFjLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDOUMsa0VBQWtFO1FBQ2xFLFdBQVcsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDO1FBQ25DLFNBQVMsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDO0lBQ25DLENBQUM7U0FBTSxDQUFDO1FBQ04sTUFBTSxJQUFJLEtBQUssQ0FDYixlQUFlLFNBQVMseURBQXlEO1lBQy9FLGdEQUFnRCxDQUNuRCxDQUFDO0lBQ0osQ0FBQztJQUVELDREQUE0RDtJQUM1RCxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDO0lBQ3pDLE1BQU0sZUFBZSxHQUFHLFdBQVcsYUFBWCxXQUFXLGNBQVgsV0FBVyxHQUFJLFdBQVcsQ0FBQztJQUNuRCxNQUFNLGFBQWEsR0FBRyxXQUFXLGFBQVgsV0FBVyxjQUFYLFdBQVcsR0FBSSxTQUFTLENBQUM7SUFFL0MsT0FBTztRQUNMLE9BQU8sRUFBRSxNQUFBLEtBQUssQ0FBQyxxQkFBcUIsbUNBQUksZUFBZTtRQUN2RCxNQUFNLEVBQUUsTUFBQSxLQUFLLENBQUMsb0JBQW9CLG1DQUFJLGFBQWE7UUFDbkQsS0FBSyxFQUFFLE1BQUEsS0FBSyxDQUFDLG1CQUFtQixtQ0FBSSxhQUFhO1FBQ2pELFFBQVEsRUFBRSxNQUFBLEtBQUssQ0FBQyxzQkFBc0IsbUNBQUksYUFBYTtRQUN2RCxXQUFXLEVBQUUsTUFBQSxLQUFLLENBQUMseUJBQXlCLG1DQUFJLGFBQWE7UUFDN0QsUUFBUSxFQUFFLE1BQUEsS0FBSyxDQUFDLHNCQUFzQixtQ0FBSSxhQUFhO0tBQ3hELENBQUM7QUFDSixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxvQkFBb0IsQ0FDM0IsT0FBZSxFQUNmLE9BQWUsRUFDZixhQUE2QztJQUU3QyxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRWhELCtDQUErQztJQUMvQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsSUFBSSxTQUFTLEdBQUcsRUFBRSxJQUFJLFNBQVMsR0FBRyxFQUFFLEVBQUUsQ0FBQztRQUNyRSxNQUFNLElBQUksS0FBSyxDQUNiLG9CQUFvQixPQUFPLGtEQUFrRCxDQUM5RSxDQUFDO0lBQ0osQ0FBQztJQUVELElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUM5QyxNQUFNLElBQUksS0FBSyxDQUFDLDJDQUEyQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFRCwwRUFBMEU7SUFDMUUsY0FBYztJQUNkLEtBQUssTUFBTSxDQUFDLElBQUksYUFBYSxFQUFFLENBQUM7UUFDOUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEdBQUcsU0FBUyxJQUFJLENBQUMsQ0FBQyxJQUFJLEdBQUcsRUFBRSxFQUFFLENBQUM7WUFDbkUsTUFBTSxJQUFJLEtBQUssQ0FDYixzQkFBc0IsQ0FBQyxDQUFDLElBQUksUUFBUSxDQUFDLENBQUMsSUFBSSx1QkFBdUI7Z0JBQy9ELG9DQUFvQyxTQUFTLFlBQVksQ0FDNUQsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0lBQ3JDLElBQUksV0FBVyxHQUFHLENBQUMsQ0FBQztJQUNwQixNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7SUFFNUIsS0FBSyxNQUFNLENBQUMsSUFBSSxhQUFhLEVBQUUsQ0FBQztRQUM5QixNQUFNLFNBQVMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sUUFBUSxHQUFHLE9BQU8sR0FBRyxTQUFTLENBQUM7UUFDckMsV0FBVyxJQUFJLFFBQVEsQ0FBQztRQUN4QixNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksS0FBSyxPQUFPLE9BQU8sQ0FBQyxDQUFDLElBQUksTUFBTSxRQUFRLE1BQU0sQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFFRCxJQUFJLFdBQVcsR0FBRyxNQUFNLEVBQUUsQ0FBQztRQUN6QixNQUFNLElBQUksS0FBSyxDQUNiLFlBQVksT0FBTyxLQUFLLE1BQU0sdUJBQXVCO1lBQ25ELGFBQWEsV0FBVyxlQUFlLGFBQWEsQ0FBQyxNQUFNLG1CQUFtQjtZQUM5RSxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUN0Qyx5RUFBeUUsQ0FDNUUsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxlQUFlLENBQ3RCLE9BQXNCLEVBQ3RCLElBQTRCO0lBRTVCLEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFLENBQUM7UUFDN0IsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNoRCxrQkFBSSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2xDLENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRDRztBQUNILE1BQWEsZUFBZ0IsU0FBUSwyQkFBaUI7SUFZcEQsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUEyQjs7UUFDbkUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUU7WUFDZixZQUFZLEVBQUUsc0JBQVksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSwwQkFBZSxDQUFDO1NBQ3RFLENBQUMsQ0FBQztRQUVILHlDQUF5QztRQUN6QyxNQUFNLE9BQU8sR0FBRyxNQUFBLEtBQUssQ0FBQyxPQUFPLG1DQUFJLENBQUMsQ0FBQztRQUNuQyxNQUFNLE9BQU8sR0FBRyxNQUFBLEtBQUssQ0FBQyxPQUFPLG1DQUFJLE1BQU0sQ0FBQztRQUV4QyxNQUFNLFdBQVcsR0FDZixPQUFPLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRS9ELDRDQUE0QztRQUM1Qyx3Q0FBd0M7UUFDeEMsTUFBTSxjQUFjLEdBQUcsT0FBTyxLQUFLLGFBQWEsQ0FBQztRQUVqRCxnREFBZ0Q7UUFFaEQsTUFBTSxZQUFZLEdBQUcsTUFBQSxLQUFLLENBQUMsbUJBQW1CLG1DQUFJLElBQUksQ0FBQztRQUN2RCxNQUFNLGFBQWEsR0FBRyxNQUFBLEtBQUssQ0FBQyxvQkFBb0IsbUNBQUksSUFBSSxDQUFDO1FBQ3pELE1BQU0sV0FBVyxHQUFHLE1BQUEsS0FBSyxDQUFDLGtCQUFrQixtQ0FBSSxJQUFJLENBQUM7UUFDckQsTUFBTSxjQUFjLEdBQUcsTUFBQSxLQUFLLENBQUMscUJBQXFCLG1DQUFJLElBQUksQ0FBQztRQUMzRCxNQUFNLGlCQUFpQixHQUFHLE1BQUEsS0FBSyxDQUFDLHdCQUF3QixtQ0FBSSxJQUFJLENBQUM7UUFDakUsTUFBTSxjQUFjLEdBQUcsTUFBQSxLQUFLLENBQUMscUJBQXFCLG1DQUFJLEtBQUssQ0FBQztRQUU1RCxNQUFNLEtBQUssR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXZELE1BQU0sYUFBYSxHQUFtQyxFQUFFLENBQUM7UUFDekQsSUFBSSxZQUFZO1lBQUUsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFDLElBQUksRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFDO1FBQzNFLElBQUksYUFBYTtZQUNmLGFBQWEsQ0FBQyxJQUFJLENBQUMsRUFBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDLENBQUMsQ0FBQztRQUM3RCxJQUFJLFdBQVc7WUFBRSxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUM7UUFDeEUsSUFBSSxjQUFjO1lBQ2hCLGFBQWEsQ0FBQyxJQUFJLENBQUMsRUFBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFDLENBQUMsQ0FBQztRQUMvRCxJQUFJLGlCQUFpQjtZQUNuQixhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxXQUFXLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBQyxDQUFDLENBQUM7UUFDckUsSUFBSSxjQUFjO1lBQ2hCLGFBQWEsQ0FBQyxJQUFJLENBQUMsRUFBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFDLENBQUMsQ0FBQztRQUUvRCxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxhQUFhLENBQUMsQ0FBQztRQUU1RCxNQUFNLG1CQUFtQixHQUE4QixFQUFFLENBQUM7UUFFMUQsSUFBSSxhQUFhLEVBQUUsQ0FBQztZQUNsQixtQkFBbUIsQ0FBQyxJQUFJLENBQUM7Z0JBQ3ZCLElBQUksRUFBRSxTQUFTO2dCQUNmLFVBQVUsRUFBRSxHQUFHLENBQUMsVUFBVSxDQUFDLG1CQUFtQjtnQkFDOUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxPQUFPO2FBQ3hCLENBQUMsQ0FBQztRQUNMLENBQUM7UUFDRCxJQUFJLFlBQVksRUFBRSxDQUFDO1lBQ2pCLG1CQUFtQixDQUFDLElBQUksQ0FBQztnQkFDdkIsSUFBSSxFQUFFLFFBQVE7Z0JBQ2QsVUFBVSxFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTTtnQkFDakMsUUFBUSxFQUFFLEtBQUssQ0FBQyxNQUFNO2dCQUN0QixtQkFBbUIsRUFBRSxJQUFJO2FBQzFCLENBQUMsQ0FBQztRQUNMLENBQUM7UUFDRCxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ2hCLG1CQUFtQixDQUFDLElBQUksQ0FBQztnQkFDdkIsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsVUFBVSxFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsZ0JBQWdCO2dCQUMzQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEtBQUs7YUFDdEIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELElBQUksY0FBYyxFQUFFLENBQUM7WUFDbkIsbUJBQW1CLENBQUMsSUFBSSxDQUFDO2dCQUN2QixJQUFJLEVBQUUsVUFBVTtnQkFDaEIsVUFBVSxFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsbUJBQW1CO2dCQUM5QyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVE7YUFDekIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELElBQUksaUJBQWlCLEVBQUUsQ0FBQztZQUN0QixtQkFBbUIsQ0FBQyxJQUFJLENBQUM7Z0JBQ3ZCLElBQUksRUFBRSxhQUFhO2dCQUNuQixVQUFVLEVBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxtQkFBbUI7Z0JBQzlDLFFBQVEsRUFBRSxLQUFLLENBQUMsV0FBVzthQUM1QixDQUFDLENBQUM7UUFDTCxDQUFDO1FBQ0QsSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUNuQixtQkFBbUIsQ0FBQyxJQUFJLENBQUM7Z0JBQ3ZCLElBQUksRUFBRSxVQUFVO2dCQUNoQixVQUFVLEVBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxtQkFBbUI7Z0JBQzlDLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUTthQUN6QixDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRTtZQUNsQyxPQUFPLEVBQUUsS0FBSyxDQUFDLElBQUk7WUFDbkIsTUFBTSxFQUFFLE9BQU87WUFDZixXQUFXO1lBQ1gsV0FBVyxFQUFFLEdBQUcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7WUFDaEQsbUJBQW1CO1lBQ25CLEdBQUcsQ0FBQyxLQUFLLENBQUMsVUFBVTtnQkFDbEIsQ0FBQyxDQUFDO29CQUNFLFVBQVUsRUFBRSxHQUFHLENBQUMsVUFBVSxDQUFDLFVBQVU7aUJBQ3RDO2dCQUNILENBQUMsQ0FBQyxFQUFFLENBQUM7U0FDUixDQUFDLENBQUM7UUFFSCxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ25CLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDbEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO1lBQ3BFLENBQUM7WUFFRCxrRUFBa0U7WUFDbEUsNkVBQTZFO1lBQzdFLGlHQUFpRztZQUNqRyxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBOEIsQ0FBQztZQUVsRSxJQUFJLGlCQUFpQixDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDbkMsTUFBTSxJQUFJLEtBQUssQ0FDYiw2REFBNkQsQ0FDOUQsQ0FBQztZQUNKLENBQUM7WUFFRCxrRUFBa0U7WUFDbEUsTUFBTSxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUV4RSxrREFBa0Q7WUFDbEQsTUFBTSxhQUFhLEdBQUcsaUJBQWlCLENBQUMsR0FBRyxDQUN6QyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQ2pDLENBQUM7WUFFRixxRUFBcUU7WUFDckUsd0VBQXdFO1lBQ3hFLHNFQUFzRTtZQUN0RSxrRUFBa0U7WUFDbEUsSUFBSSwwQkFBVyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUU7Z0JBQzNCLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRztnQkFDYixZQUFZLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsRUFBQyxlQUFlLEVBQUUsUUFBUSxFQUFDLENBQUM7cUJBQzlELE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQ2IsdUJBQXVCLEVBQUUsaUJBQWlCO2dCQUMxQyxvQkFBb0IsRUFBRSxhQUFhO2FBQ3BDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCw4QkFBOEI7UUFDOUIsSUFBSSxLQUFLLENBQUMsZ0JBQWdCLElBQUksWUFBWSxFQUFFLENBQUM7WUFDM0MsZUFBZSxDQUNiLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEVBQUMsZUFBZSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUMsT0FBTyxFQUMzRCxLQUFLLENBQUMsZ0JBQWdCLENBQ3ZCLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxLQUFLLENBQUMsaUJBQWlCLElBQUksYUFBYSxFQUFFLENBQUM7WUFDN0MsZUFBZSxDQUNiLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEVBQUMsZUFBZSxFQUFFLFNBQVMsRUFBQyxDQUFDLENBQUMsT0FBTyxFQUM1RCxLQUFLLENBQUMsaUJBQWlCLENBQ3hCLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxLQUFLLENBQUMsZUFBZSxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ3pDLGVBQWUsQ0FDYixJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxFQUFDLGVBQWUsRUFBRSxPQUFPLEVBQUMsQ0FBQyxDQUFDLE9BQU8sRUFDMUQsS0FBSyxDQUFDLGVBQWUsQ0FDdEIsQ0FBQztRQUNKLENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyxrQkFBa0IsSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUMvQyxlQUFlLENBQ2IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsRUFBQyxlQUFlLEVBQUUsVUFBVSxFQUFDLENBQUMsQ0FBQyxPQUFPLEVBQzdELEtBQUssQ0FBQyxrQkFBa0IsQ0FDekIsQ0FBQztRQUNKLENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsSUFBSSxpQkFBaUIsRUFBRSxDQUFDO1lBQ3JELGVBQWUsQ0FDYixJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxFQUFDLGVBQWUsRUFBRSxhQUFhLEVBQUMsQ0FBQyxDQUFDLE9BQU8sRUFDaEUsS0FBSyxDQUFDLHFCQUFxQixDQUM1QixDQUFDO1FBQ0osQ0FBQztRQUNELElBQUksS0FBSyxDQUFDLGtCQUFrQixJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQy9DLGVBQWUsQ0FDYixJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxFQUFDLGVBQWUsRUFBRSxVQUFVLEVBQUMsQ0FBQyxDQUFDLE9BQU8sRUFDN0QsS0FBSyxDQUFDLGtCQUFrQixDQUN6QixDQUFDO1FBQ0osQ0FBQztRQUVELHFFQUFxRTtRQUNyRSxNQUFNLGVBQWUsR0FBMEIsRUFBRSxDQUFDO1FBQ2xELElBQUksYUFBYTtZQUFFLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBQyxlQUFlLEVBQUUsU0FBUyxFQUFDLENBQUMsQ0FBQztRQUN0RSxJQUFJLFdBQVc7WUFBRSxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUMsZUFBZSxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUM7UUFDbEUsSUFBSSxjQUFjO1lBQUUsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFDLGVBQWUsRUFBRSxVQUFVLEVBQUMsQ0FBQyxDQUFDO1FBQ3hFLElBQUksaUJBQWlCO1lBQ25CLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBQyxlQUFlLEVBQUUsYUFBYSxFQUFDLENBQUMsQ0FBQztRQUN6RCxJQUFJLGNBQWM7WUFBRSxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUMsZUFBZSxFQUFFLFVBQVUsRUFBQyxDQUFDLENBQUM7UUFFeEUsSUFBSSxDQUFDLE1BQUEsS0FBSyxDQUFDLGdCQUFnQixtQ0FBSSxJQUFJLENBQUMsSUFBSSxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ25FLElBQUksQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLEVBQUU7Z0JBQy9DLE9BQU8sRUFBRSxHQUFHLENBQUMsNEJBQTRCLENBQUMsRUFBRTtnQkFDNUMsT0FBTyxFQUFFLGVBQWU7YUFDekIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELElBQUksQ0FBQyxNQUFBLEtBQUssQ0FBQyxzQkFBc0IsbUNBQUksSUFBSSxDQUFDLElBQUksZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN6RSxJQUFJLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLHlCQUF5QixFQUFFO2dCQUNyRCxPQUFPLEVBQUUsR0FBRyxDQUFDLDRCQUE0QixDQUFDLFFBQVE7Z0JBQ2xELE9BQU8sRUFBRSxlQUFlO2FBQ3pCLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCx5QkFBeUI7UUFDekIsSUFBSSxNQUFBLEtBQUssQ0FBQyxhQUFhLG1DQUFJLElBQUksRUFBRSxDQUFDO1lBQ2hDLE1BQU0sU0FBUyxHQUFHLG1CQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUUzQyxJQUFJLHVCQUFTLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRTtnQkFDM0IsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSztnQkFDckIsVUFBVSxFQUFFLEdBQUcsU0FBUyxRQUFRO2FBQ2pDLENBQUMsQ0FBQztZQUVILElBQUksWUFBWSxFQUFFLENBQUM7Z0JBQ2pCLElBQUksdUJBQVMsQ0FBQyxJQUFJLEVBQUUsaUJBQWlCLEVBQUU7b0JBQ3JDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRzt5QkFDWixhQUFhLENBQUMsRUFBQyxlQUFlLEVBQUUsUUFBUSxFQUFDLENBQUM7eUJBQzFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO29CQUN0QixVQUFVLEVBQUUsR0FBRyxTQUFTLGtCQUFrQjtpQkFDM0MsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUNELElBQUksYUFBYSxFQUFFLENBQUM7Z0JBQ2xCLElBQUksdUJBQVMsQ0FBQyxJQUFJLEVBQUUsa0JBQWtCLEVBQUU7b0JBQ3RDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRzt5QkFDWixhQUFhLENBQUMsRUFBQyxlQUFlLEVBQUUsU0FBUyxFQUFDLENBQUM7eUJBQzNDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO29CQUN0QixVQUFVLEVBQUUsR0FBRyxTQUFTLG1CQUFtQjtpQkFDNUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUNELElBQUksV0FBVyxFQUFFLENBQUM7Z0JBQ2hCLElBQUksdUJBQVMsQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7b0JBQ3BDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRzt5QkFDWixhQUFhLENBQUMsRUFBQyxlQUFlLEVBQUUsT0FBTyxFQUFDLENBQUM7eUJBQ3pDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO29CQUN0QixVQUFVLEVBQUUsR0FBRyxTQUFTLGlCQUFpQjtpQkFDMUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUNELElBQUksY0FBYyxFQUFFLENBQUM7Z0JBQ25CLElBQUksdUJBQVMsQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLEVBQUU7b0JBQ3ZDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRzt5QkFDWixhQUFhLENBQUMsRUFBQyxlQUFlLEVBQUUsVUFBVSxFQUFDLENBQUM7eUJBQzVDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO29CQUN0QixVQUFVLEVBQUUsR0FBRyxTQUFTLG9CQUFvQjtpQkFDN0MsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUNELElBQUksaUJBQWlCLEVBQUUsQ0FBQztnQkFDdEIsSUFBSSx1QkFBUyxDQUFDLElBQUksRUFBRSxzQkFBc0IsRUFBRTtvQkFDMUMsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHO3lCQUNaLGFBQWEsQ0FBQyxFQUFDLGVBQWUsRUFBRSxhQUFhLEVBQUMsQ0FBQzt5QkFDL0MsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7b0JBQ3RCLFVBQVUsRUFBRSxHQUFHLFNBQVMsdUJBQXVCO2lCQUNoRCxDQUFDLENBQUM7WUFDTCxDQUFDO1lBQ0QsSUFBSSxjQUFjLEVBQUUsQ0FBQztnQkFDbkIsSUFBSSx1QkFBUyxDQUFDLElBQUksRUFBRSxtQkFBbUIsRUFBRTtvQkFDdkMsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHO3lCQUNaLGFBQWEsQ0FBQyxFQUFDLGVBQWUsRUFBRSxVQUFVLEVBQUMsQ0FBQzt5QkFDNUMsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7b0JBQ3RCLFVBQVUsRUFBRSxHQUFHLFNBQVMsb0JBQW9CO2lCQUM3QyxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztRQUVELDRDQUE0QztRQUM1QyxJQUFJLE1BQUEsS0FBSyxDQUFDLGVBQWUsbUNBQUksSUFBSSxFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksc0NBQWlCLENBQzVDLElBQUksRUFDSixtQkFBbUIsRUFDbkI7Z0JBQ0UsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO2dCQUNoQixNQUFNLEVBQUUsS0FBSyxDQUFDLGdCQUFnQjtnQkFDOUIsTUFBTSxFQUFFLElBQUk7Z0JBQ1osU0FBUyxFQUFFLEtBQUs7Z0JBQ2hCLFNBQVMsRUFBRSxLQUFLO2dCQUNoQixtQkFBbUIsRUFBRSxLQUFLO2dCQUMxQixvQkFBb0IsRUFBRSxLQUFLO2dCQUMzQixrQkFBa0IsRUFBRSxLQUFLO2dCQUN6QixxQkFBcUIsRUFBRSxLQUFLO2dCQUM1Qix3QkFBd0IsRUFBRSxLQUFLO2dCQUMvQixxQkFBcUIsRUFBRSxLQUFLO2dCQUM1QixvQkFBb0IsRUFBRSxLQUFLO2dCQUMzQixLQUFLLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLO2dCQUNyQixHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxpQkFBaUI7Z0JBQy9CLGVBQWUsRUFBRSxZQUFZO29CQUMzQixDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsRUFBQyxlQUFlLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQyxTQUFTO29CQUMvRCxDQUFDLENBQUMsU0FBUztnQkFDYixnQkFBZ0IsRUFBRSxhQUFhO29CQUM3QixDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsRUFBQyxlQUFlLEVBQUUsU0FBUyxFQUFDLENBQUMsQ0FBQyxTQUFTO29CQUNoRSxDQUFDLENBQUMsU0FBUztnQkFDYixjQUFjLEVBQUUsV0FBVztvQkFDekIsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEVBQUMsZUFBZSxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUMsU0FBUztvQkFDOUQsQ0FBQyxDQUFDLFNBQVM7Z0JBQ2IsaUJBQWlCLEVBQUUsY0FBYztvQkFDL0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEVBQUMsZUFBZSxFQUFFLFVBQVUsRUFBQyxDQUFDLENBQUMsU0FBUztvQkFDakUsQ0FBQyxDQUFDLFNBQVM7Z0JBQ2Isb0JBQW9CLEVBQUUsaUJBQWlCO29CQUNyQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsRUFBQyxlQUFlLEVBQUUsYUFBYSxFQUFDLENBQUMsQ0FBQyxTQUFTO29CQUNwRSxDQUFDLENBQUMsU0FBUztnQkFDYixpQkFBaUIsRUFBRSxjQUFjO29CQUMvQixDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsRUFBQyxlQUFlLEVBQUUsVUFBVSxFQUFDLENBQUMsQ0FBQyxTQUFTO29CQUNqRSxDQUFDLENBQUMsU0FBUzthQUNkLENBQ0YsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUF2VEQsMENBdVRDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDZm5PdXRwdXQsIFN0YWNrLCBUYWdzfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBlYzIgZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjMic7XG5pbXBvcnQgdHlwZSB7Q29uc3RydWN0fSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7XG4gIEV4dGVuZGVkQ29uc3RydWN0LFxuICB0eXBlIEV4dGVuZGVkQ29uc3RydWN0UHJvcHMsXG4gIFN0YW5kYXJkVGFncyxcbn0gZnJvbSAnLi4vLi4vYXdzLWNkayc7XG5pbXBvcnQge0xpYlN0YW5kYXJkVGFnc30gZnJvbSAnLi4vLi4vdHJ1ZW1hcmsnO1xuaW1wb3J0IHtOYXRJbnN0YW5jZX0gZnJvbSAnLi9uYXQtaW5zdGFuY2UnO1xuaW1wb3J0IHtOZXR3b3JrUGFyYW1ldGVyc30gZnJvbSAnLi9uZXR3b3JrLXBhcmFtZXRlcnMnO1xuXG5leHBvcnQgdHlwZSBOYXRUeXBlID0gJ25vbmUnIHwgJ3NpbmdsZScgfCAnbXVsdGknIHwgJ25hdEluc3RhbmNlJzsgLy8gVE9ETyBBZGQgIHwgJ3JlZ2lvbmFsJyB8ICdwb29yJztcblxuLy8gVE9ETyBOZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBpcHY2IG9ubHkgbW9kZSAoY3VycmVudGx5IHN1cHBvcnRzIGR1YWwtc3RhY2spXG5cbi8qKlxuICogU3VibmV0IHNpemluZyBsb29rdXAgdGFibGUga2V5ZWQgYnkgVlBDIHByZWZpeCBsZW5ndGguXG4gKlxuICogTWlycm9ycyB0aGUgYHByaXZhdGVfc3VibmV0c2AgYW5kIGBzdWJuZXRzYCBsb2NhbHMgaW4gdHJ1ZW1hcmsvdGVycmFmb3JtLWF3cy12cGM6XG4gKlxuICogICBWUEMgICAgIHByaXZhdGUgbmV3Yml0cyAgcHJpdmF0ZSBtYXNrICAgb3RoZXIgbmV3Yml0cyAgIG90aGVyIG1hc2tcbiAqICAgLzE2ICAgICAgICAgIDMgICAgICAgICAgICAgICAvMTkgICAgICAgICAgICAgIDYgICAgICAgICAgICAgIC8yMlxuICogICAvMTcgICAgICAgICAgMyAgICAgICAgICAgICAgIC8yMCAgICAgICAgICAgICAgNSAgICAgICAgICAgICAgLzIyXG4gKiAgIC8xOCAgICAgICAgICAzICAgICAgICAgICAgICAgLzIxICAgICAgICAgICAgICA1ICAgICAgICAgICAgICAvMjNcbiAqICAgLzE5ICAgICAgICAgIDMgICAgICAgICAgICAgICAvMjIgICAgICAgICAgICAgIDUgICAgICAgICAgICAgIC8yNFxuICogICAvMjAgICAgICAgICAgNCAgICAgICAgICAgICAgIC8yNCAgICAgICAgICAgICAgNSAgICAgICAgICAgICAgLzI1XG4gKlxuICogXCJuZXdiaXRzXCIgaXMgdGhlIG51bWJlciBvZiBiaXRzIHRvIGV4dGVuZCB0aGUgVlBDIHByZWZpeC5cbiAqIGNpZHJNYXNrID0gdnBjUHJlZml4ICsgbmV3Yml0cy5cbiAqL1xuY29uc3QgU1VCTkVUX05FV0JJVFM6IFJlY29yZDxudW1iZXIsIHtwcml2YXRlQml0czogbnVtYmVyOyBvdGhlckJpdHM6IG51bWJlcn0+ID1cbiAge1xuICAgIDE2OiB7cHJpdmF0ZUJpdHM6IDMsIG90aGVyQml0czogNn0sXG4gICAgMTc6IHtwcml2YXRlQml0czogMywgb3RoZXJCaXRzOiA1fSxcbiAgICAxODoge3ByaXZhdGVCaXRzOiAzLCBvdGhlckJpdHM6IDV9LFxuICAgIDE5OiB7cHJpdmF0ZUJpdHM6IDMsIG90aGVyQml0czogNX0sXG4gICAgMjA6IHtwcml2YXRlQml0czogNCwgb3RoZXJCaXRzOiA1fSxcbiAgfTtcblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBTdGFuZGFyZE5ldHdvcmsuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhbmRhcmROZXR3b3JrUHJvcHMgZXh0ZW5kcyBFeHRlbmRlZENvbnN0cnVjdFByb3BzIHtcbiAgLyoqXG4gICAqIE5hbWUgZm9yIHRoZSBWUEMuIFVzZWQgYXMgdGhlIFZQQyBuYW1lIHRhZyBhbmQgdGhlIFNTTSBwYXJhbWV0ZXIgcGF0aFxuICAgKiBzZWdtZW50IChlLmcuIC9uZXR3b3JrL3tuYW1lfS92cGMpLlxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBGdWxsIFZQQyBDSURSIGJsb2NrLiBlLmcuIFwiMTAuMC4wLjAvMjBcIi5cbiAgICogU3VwcG9ydGVkIFZQQyBwcmVmaXggbGVuZ3RocyBmb3IgYXV0by1zaXppbmc6IC8xNiwgLzE3LCAvMTgsIC8xOSwgLzIwLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjQ2lkcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgYXZhaWxhYmlsaXR5IHpvbmVzIHRvIGRlcGxveSBzdWJuZXRzIGludG8uXG4gICAqXG4gICAqICoqQnJlYWtpbmcgQ2hhbmdlKio6IFRoZSBkZWZhdWx0IHdhcyBjaGFuZ2VkIGZyb20gMiB0byAzIHRvIGFsaWduIHdpdGggQVdTIGJlc3RcbiAgICogcHJhY3RpY2VzIGZvciBoaWdoIGF2YWlsYWJpbGl0eS4gRXhpc3RpbmcgY29uc3VtZXJzIHVwZ3JhZGluZyB3aWxsIHNlZSBhZGRpdGlvbmFsXG4gICAqIHN1Ym5ldHMgYW5kIHJlc291cmNlcyBjcmVhdGVkIHVubGVzcyB0aGV5IGV4cGxpY2l0bHkgc2V0IGBhekNvdW50OiAyYC5cbiAgICpcbiAgICogQGRlZmF1bHQgM1xuICAgKi9cbiAgcmVhZG9ubHkgYXpDb3VudD86IG51bWJlcjtcblxuICAvKipcbiAgICogV2hldGhlciB0byBlbmFibGUgSVB2NiBmb3IgdGhlIFZQQy4gV2hlbiBlbmFibGVkLCBhbiBBbWF6b24tcHJvdmlkZWQgSVB2NiBDSURSXG4gICAqIGJsb2NrIGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgVlBDIGFuZCBzdWJuZXRzIGFyZSBjb25maWd1cmVkIHdpdGggSVB2NiBhZGRyZXNzZXMuXG4gICAqIERlZmF1bHQgaXMgZmFsc2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBlbmFibGVJcHY2PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogTkFUIGdhdGV3YXkgY29uZmlndXJhdGlvbi4gRGVmYXVsdCBpcyAnbm9uZScuXG4gICAqXG4gICAqIEBkZWZhdWx0ICdub25lJ1xuICAgKi9cbiAgcmVhZG9ubHkgbmF0VHlwZT86IE5hdFR5cGU7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gY3JlYXRlIHB1YmxpYyBzdWJuZXRzLiBEZWZhdWx0IGlzIHRydWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGNyZWF0ZVB1YmxpY1N1Ym5ldHM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNyZWF0ZSBwcml2YXRlIHN1Ym5ldHMgKFBSSVZBVEVfV0lUSF9FR1JFU1MpLiBEZWZhdWx0IGlzIHRydWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGNyZWF0ZVByaXZhdGVTdWJuZXRzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciB0byBjcmVhdGUgaW50cmEgc3VibmV0cyAoUFJJVkFURV9JU09MQVRFRCwgbm8gZWdyZXNzKS4gRGVmYXVsdCBpcyB0cnVlLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBjcmVhdGVJbnRyYVN1Ym5ldHM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNyZWF0ZSBkYXRhYmFzZSBzdWJuZXRzIChQUklWQVRFX1dJVEhfRUdSRVNTKS4gRGVmYXVsdCBpcyB0cnVlLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBjcmVhdGVEYXRhYmFzZVN1Ym5ldHM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNyZWF0ZSBlbGFzdGljYWNoZSBzdWJuZXRzIChQUklWQVRFX1dJVEhfRUdSRVNTKS4gRGVmYXVsdCBpcyB0cnVlLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBjcmVhdGVFbGFzdGljYWNoZVN1Ym5ldHM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNyZWF0ZSByZWRzaGlmdCBzdWJuZXRzIChQUklWQVRFX1dJVEhfRUdSRVNTKS4gRGVmYXVsdCBpcyBmYWxzZS5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGNyZWF0ZVJlZHNoaWZ0U3VibmV0cz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEFwcGx5IGEgdW5pZm9ybSBDSURSIG1hc2sgdG8gQUxMIHN1Ym5ldCBncm91cHMsIG92ZXJyaWRpbmcgdGhlIHRlcnJhZm9ybS1zdHlsZVxuICAgKiBhdXRvLXNpemluZy4gV2hlbiBzZXQsIGFsbCBncm91cHMgcmVjZWl2ZSB0aGUgc2FtZSBtYXNrIHJlZ2FyZGxlc3Mgb2YgdHlwZS5cbiAgICogUGVyLWdyb3VwIG92ZXJyaWRlcyBiZWxvdyB0YWtlIHByZWNlZGVuY2Ugb3ZlciB0aGlzIHZhbHVlLlxuICAgKi9cbiAgcmVhZG9ubHkgc3VibmV0Q2lkck1hc2s/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIENJRFIgbWFzayBvdmVycmlkZSBmb3IgcHJpdmF0ZSBzdWJuZXRzIG9ubHkuXG4gICAqXG4gICAqIEVxdWl2YWxlbnQgdG8gc2V0dGluZyBgcHJpdmF0ZV9uZXdiaXRzYCBpbiB0ZXJyYWZvcm0tYXdzLXZwYzpcbiAgICogICBwcml2YXRlU3VibmV0Q2lkck1hc2sgPSB2cGNQcmVmaXggKyBwcml2YXRlX25ld2JpdHNcbiAgICpcbiAgICogVGFrZXMgcHJlY2VkZW5jZSBvdmVyIHN1Ym5ldENpZHJNYXNrIGFuZCBhdXRvLXNpemluZy5cbiAgICovXG4gIHJlYWRvbmx5IHByaXZhdGVTdWJuZXRDaWRyTWFzaz86IG51bWJlcjtcblxuICAvKipcbiAgICogQ0lEUiBtYXNrIG92ZXJyaWRlIGZvciBwdWJsaWMgc3VibmV0cyBvbmx5LlxuICAgKlxuICAgKiBFcXVpdmFsZW50IHRvIHNldHRpbmcgYHB1YmxpY19uZXdiaXRzYCBpbiB0ZXJyYWZvcm0tYXdzLXZwYzpcbiAgICogICBwdWJsaWNTdWJuZXRDaWRyTWFzayA9IHZwY1ByZWZpeCArIHB1YmxpY19uZXdiaXRzXG4gICAqXG4gICAqIFRha2VzIHByZWNlZGVuY2Ugb3ZlciBzdWJuZXRDaWRyTWFzayBhbmQgYXV0by1zaXppbmcuXG4gICAqL1xuICByZWFkb25seSBwdWJsaWNTdWJuZXRDaWRyTWFzaz86IG51bWJlcjtcblxuICAvKipcbiAgICogQ0lEUiBtYXNrIG92ZXJyaWRlIGZvciBpbnRyYSBzdWJuZXRzIG9ubHkuXG4gICAqXG4gICAqIEVxdWl2YWxlbnQgdG8gc2V0dGluZyBgaW50cmFfbmV3Yml0c2AgaW4gdGVycmFmb3JtLWF3cy12cGMuXG4gICAqIFRha2VzIHByZWNlZGVuY2Ugb3ZlciBzdWJuZXRDaWRyTWFzayBhbmQgYXV0by1zaXppbmcuXG4gICAqL1xuICByZWFkb25seSBpbnRyYVN1Ym5ldENpZHJNYXNrPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBDSURSIG1hc2sgb3ZlcnJpZGUgZm9yIGRhdGFiYXNlIHN1Ym5ldHMgb25seS5cbiAgICpcbiAgICogRXF1aXZhbGVudCB0byBzZXR0aW5nIGBkYXRhYmFzZV9uZXdiaXRzYCBpbiB0ZXJyYWZvcm0tYXdzLXZwYy5cbiAgICogVGFrZXMgcHJlY2VkZW5jZSBvdmVyIHN1Ym5ldENpZHJNYXNrIGFuZCBhdXRvLXNpemluZy5cbiAgICovXG4gIHJlYWRvbmx5IGRhdGFiYXNlU3VibmV0Q2lkck1hc2s/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIENJRFIgbWFzayBvdmVycmlkZSBmb3IgZWxhc3RpY2FjaGUgc3VibmV0cyBvbmx5LlxuICAgKlxuICAgKiBFcXVpdmFsZW50IHRvIHNldHRpbmcgYGVsYXN0aWNhY2hlX25ld2JpdHNgIGluIHRlcnJhZm9ybS1hd3MtdnBjLlxuICAgKiBUYWtlcyBwcmVjZWRlbmNlIG92ZXIgc3VibmV0Q2lkck1hc2sgYW5kIGF1dG8tc2l6aW5nLlxuICAgKi9cbiAgcmVhZG9ubHkgZWxhc3RpY2FjaGVTdWJuZXRDaWRyTWFzaz86IG51bWJlcjtcblxuICAvKipcbiAgICogQ0lEUiBtYXNrIG92ZXJyaWRlIGZvciByZWRzaGlmdCBzdWJuZXRzIG9ubHkuXG4gICAqXG4gICAqIEVxdWl2YWxlbnQgdG8gc2V0dGluZyBgcmVkc2hpZnRfbmV3Yml0c2AgaW4gdGVycmFmb3JtLWF3cy12cGMuXG4gICAqIFRha2VzIHByZWNlZGVuY2Ugb3ZlciBzdWJuZXRDaWRyTWFzayBhbmQgYXV0by1zaXppbmcuXG4gICAqL1xuICByZWFkb25seSByZWRzaGlmdFN1Ym5ldENpZHJNYXNrPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNyZWF0ZSBhbiBTMyBnYXRld2F5IFZQQyBlbmRwb2ludC4gVGhlIGVuZHBvaW50IGlzIGF0dGFjaGVkIHRvXG4gICAqIHByaXZhdGUsIGRhdGFiYXNlLCBlbGFzdGljYWNoZSwgcmVkc2hpZnQsIGFuZCBpbnRyYSBzdWJuZXRzICh3aGljaGV2ZXIgYXJlXG4gICAqIGVuYWJsZWQpLiBEZWZhdWx0IGlzIHRydWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGNyZWF0ZVMzRW5kcG9pbnQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNyZWF0ZSBhIER5bmFtb0RCIGdhdGV3YXkgVlBDIGVuZHBvaW50LiBBdHRhY2hlZCB0byB0aGUgc2FtZVxuICAgKiBzdWJuZXQgZ3JvdXBzIGFzIHRoZSBTMyBlbmRwb2ludC4gRGVmYXVsdCBpcyB0cnVlLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBjcmVhdGVEeW5hbW9EYkVuZHBvaW50PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciB0byBzdG9yZSBWUEMgYW5kIHN1Ym5ldCBJRHMgaW4gQVdTIFNTTSBQYXJhbWV0ZXIgU3RvcmUgdmlhIHRoZVxuICAgKiBOZXR3b3JrUGFyYW1ldGVycyBjb25zdHJ1Y3QuIERlZmF1bHQgaXMgdHJ1ZS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgc3RvcmVQYXJhbWV0ZXJzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogU1NNIHBhcmFtZXRlciBwcmVmaXggdXNlZCB3aGVuIHN0b3JlUGFyYW1ldGVycyBpcyB0cnVlLiBEZWZhdWx0IGlzIFwiL25ldHdvcmtcIi5cbiAgICpcbiAgICogQGRlZmF1bHQgXCIvbmV0d29ya1wiXG4gICAqL1xuICByZWFkb25seSBwYXJhbWV0ZXJzUHJlZml4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNyZWF0ZSBDbG91ZEZvcm1hdGlvbiBzdGFjayBvdXRwdXRzIGZvciBWUEMgYW5kIHN1Ym5ldCBJRHMuXG4gICAqIERlZmF1bHQgaXMgdHJ1ZS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgY3JlYXRlT3V0cHV0cz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgdGFncyB0byBhcHBseSB0byBwdWJsaWMgc3VibmV0cy5cbiAgICovXG4gIHJlYWRvbmx5IHB1YmxpY1N1Ym5ldFRhZ3M/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIHRhZ3MgdG8gYXBwbHkgdG8gcHJpdmF0ZSBzdWJuZXRzLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJpdmF0ZVN1Ym5ldFRhZ3M/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIHRhZ3MgdG8gYXBwbHkgdG8gaW50cmEgc3VibmV0cy5cbiAgICovXG4gIHJlYWRvbmx5IGludHJhU3VibmV0VGFncz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG5cbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgdGFncyB0byBhcHBseSB0byBkYXRhYmFzZSBzdWJuZXRzLlxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YWJhc2VTdWJuZXRUYWdzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCB0YWdzIHRvIGFwcGx5IHRvIGVsYXN0aWNhY2hlIHN1Ym5ldHMuXG4gICAqL1xuICByZWFkb25seSBlbGFzdGljYWNoZVN1Ym5ldFRhZ3M/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIHRhZ3MgdG8gYXBwbHkgdG8gcmVkc2hpZnQgc3VibmV0cy5cbiAgICovXG4gIHJlYWRvbmx5IHJlZHNoaWZ0U3VibmV0VGFncz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59XG5cbi8qKlxuICogUmVzb2x2ZWQgQ0lEUiBtYXNrIGZvciBlYWNoIHN1Ym5ldCBncm91cC5cbiAqL1xuaW50ZXJmYWNlIFJlc29sdmVkU3VibmV0TWFza3Mge1xuICBwcml2YXRlOiBudW1iZXI7XG4gIHB1YmxpYzogbnVtYmVyO1xuICBpbnRyYTogbnVtYmVyO1xuICBkYXRhYmFzZTogbnVtYmVyO1xuICBlbGFzdGljYWNoZTogbnVtYmVyO1xuICByZWRzaGlmdDogbnVtYmVyO1xufVxuXG4vKipcbiAqIERldGVybWluZXMgdGhlIENJRFIgbWFza3MgZm9yIGVhY2ggc3VibmV0IGdyb3VwLlxuICpcbiAqIFJlc29sdXRpb24gb3JkZXIgKGhpZ2hlc3Qgd2lucyk6XG4gKiAgIDEuIFBlci1ncm91cCBvdmVycmlkZSAoZS5nLiBwcml2YXRlU3VibmV0Q2lkck1hc2spXG4gKiAgIDIuIFVuaWZvcm0gb3ZlcnJpZGUgIChzdWJuZXRDaWRyTWFzaylcbiAqICAgMy4gVGVycmFmb3JtLXRhYmxlIGF1dG8tc2l6aW5nIGZyb20gdGhlIFZQQyBwcmVmaXhcbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVN1Ym5ldE1hc2tzKFxuICB2cGNDaWRyOiBzdHJpbmcsXG4gIHByb3BzOiBTdGFuZGFyZE5ldHdvcmtQcm9wcyxcbik6IFJlc29sdmVkU3VibmV0TWFza3Mge1xuICBjb25zdCB2cGNQcmVmaXggPSBOdW1iZXIodnBjQ2lkci5zcGxpdCgnLycpWzFdKTtcblxuICBpZiAoIU51bWJlci5pc0Zpbml0ZSh2cGNQcmVmaXgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIFZQQyBDSURSOiAke3ZwY0NpZHJ9YCk7XG4gIH1cblxuICAvLyAtLS0gQXV0by1zaXppbmcgZnJvbSB0ZXJyYWZvcm0gdGFibGVzIC0tLVxuICBjb25zdCBiaXRzID0gU1VCTkVUX05FV0JJVFNbdnBjUHJlZml4XTtcblxuICBsZXQgYXV0b1ByaXZhdGU6IG51bWJlcjtcbiAgbGV0IGF1dG9PdGhlcjogbnVtYmVyO1xuXG4gIGlmIChiaXRzKSB7XG4gICAgYXV0b1ByaXZhdGUgPSB2cGNQcmVmaXggKyBiaXRzLnByaXZhdGVCaXRzO1xuICAgIGF1dG9PdGhlciA9IHZwY1ByZWZpeCArIGJpdHMub3RoZXJCaXRzO1xuICB9IGVsc2UgaWYgKHByb3BzLnN1Ym5ldENpZHJNYXNrICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBGYWxsIGJhY2sgdG8gdW5pZm9ybSB3aGVuIFZQQyBwcmVmaXggaXMgb3V0c2lkZSB0aGUgdGFibGUgcmFuZ2VcbiAgICBhdXRvUHJpdmF0ZSA9IHByb3BzLnN1Ym5ldENpZHJNYXNrO1xuICAgIGF1dG9PdGhlciA9IHByb3BzLnN1Ym5ldENpZHJNYXNrO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBWUEMgcHJlZml4IC8ke3ZwY1ByZWZpeH0gaXMgbm90IGluIHRoZSBhdXRvLXNpemluZyB0YWJsZSAoc3VwcG9ydGVkOiAvMTbigJMvMjApLiBgICtcbiAgICAgICAgYFByb3ZpZGUgc3VibmV0Q2lkck1hc2sgb3IgcGVyLWdyb3VwIG92ZXJyaWRlcy5gLFxuICAgICk7XG4gIH1cblxuICAvLyBVbmlmb3JtIG92ZXJyaWRlIHJlcGxhY2VzIGJvdGggcHJpdmF0ZSBhbmQgb3RoZXIgZGVmYXVsdHNcbiAgY29uc3QgdW5pZm9ybU1hc2sgPSBwcm9wcy5zdWJuZXRDaWRyTWFzaztcbiAgY29uc3QgYmFzZU1hc2tQcml2YXRlID0gdW5pZm9ybU1hc2sgPz8gYXV0b1ByaXZhdGU7XG4gIGNvbnN0IGJhc2VNYXNrT3RoZXIgPSB1bmlmb3JtTWFzayA/PyBhdXRvT3RoZXI7XG5cbiAgcmV0dXJuIHtcbiAgICBwcml2YXRlOiBwcm9wcy5wcml2YXRlU3VibmV0Q2lkck1hc2sgPz8gYmFzZU1hc2tQcml2YXRlLFxuICAgIHB1YmxpYzogcHJvcHMucHVibGljU3VibmV0Q2lkck1hc2sgPz8gYmFzZU1hc2tPdGhlcixcbiAgICBpbnRyYTogcHJvcHMuaW50cmFTdWJuZXRDaWRyTWFzayA/PyBiYXNlTWFza090aGVyLFxuICAgIGRhdGFiYXNlOiBwcm9wcy5kYXRhYmFzZVN1Ym5ldENpZHJNYXNrID8/IGJhc2VNYXNrT3RoZXIsXG4gICAgZWxhc3RpY2FjaGU6IHByb3BzLmVsYXN0aWNhY2hlU3VibmV0Q2lkck1hc2sgPz8gYmFzZU1hc2tPdGhlcixcbiAgICByZWRzaGlmdDogcHJvcHMucmVkc2hpZnRTdWJuZXRDaWRyTWFzayA/PyBiYXNlTWFza090aGVyLFxuICB9O1xufVxuXG4vKipcbiAqIFZhbGlkYXRlcyB0aGF0IHRoZSBWUEMgQ0lEUiBoYXMgZW5vdWdoIGFkZHJlc3Mgc3BhY2UgZm9yIGFsbCBlbmFibGVkIHN1Ym5ldFxuICogZ3JvdXBzLiBFYWNoIGdyb3VwIGNvbnN1bWVzIGF6Q291bnQgw5cgMl4oMzItY2lkck1hc2spIElQcy5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVBZGRyZXNzU3BhY2UoXG4gIHZwY0NpZHI6IHN0cmluZyxcbiAgYXpDb3VudDogbnVtYmVyLFxuICBlbmFibGVkR3JvdXBzOiB7bWFzazogbnVtYmVyOyBuYW1lOiBzdHJpbmd9W10sXG4pOiB2b2lkIHtcbiAgY29uc3QgdnBjUHJlZml4ID0gTnVtYmVyKHZwY0NpZHIuc3BsaXQoJy8nKVsxXSk7XG5cbiAgLy8gQVdTIGFsbG93cyBWUEMgbmV0bWFza3MgYmV0d2VlbiAvMTYgYW5kIC8yOC5cbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHZwY1ByZWZpeCkgfHwgdnBjUHJlZml4IDwgMTYgfHwgdnBjUHJlZml4ID4gMjgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgSW52YWxpZCBWUEMgQ0lEUiAke3ZwY0NpZHJ9OiBwcmVmaXggbXVzdCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gLzE2IGFuZCAvMjguYCxcbiAgICApO1xuICB9XG5cbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGF6Q291bnQpIHx8IGF6Q291bnQgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBhekNvdW50IG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyLCBnb3QgJHthekNvdW50fS5gKTtcbiAgfVxuXG4gIC8vIEFXUyBzdWJuZXQgbWFza3MgbXVzdCBiZSBiZXR3ZWVuIC8xNiBhbmQgLzI4LCBhbmQgbmV2ZXIgbGFyZ2VyIHRoYW4gdGhlXG4gIC8vIFZQQyBpdHNlbGYuXG4gIGZvciAoY29uc3QgZyBvZiBlbmFibGVkR3JvdXBzKSB7XG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGcubWFzaykgfHwgZy5tYXNrIDwgdnBjUHJlZml4IHx8IGcubWFzayA+IDI4KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIENJRFIgbWFzayAvJHtnLm1hc2t9IGZvciAke2cubmFtZX0gc3VibmV0czogbXVzdCBiZSBhbiBgICtcbiAgICAgICAgICBgaW50ZWdlciBiZXR3ZWVuIHRoZSBWUEMgcHJlZml4ICgvJHt2cGNQcmVmaXh9KSBhbmQgLzI4LmAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHZwY0lwcyA9IDIgKiogKDMyIC0gdnBjUHJlZml4KTtcbiAgbGV0IHJlcXVpcmVkSXBzID0gMDtcbiAgY29uc3QgZGV0YWlsOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgZyBvZiBlbmFibGVkR3JvdXBzKSB7XG4gICAgY29uc3Qgc3VibmV0SXBzID0gMiAqKiAoMzIgLSBnLm1hc2spO1xuICAgIGNvbnN0IGdyb3VwSXBzID0gYXpDb3VudCAqIHN1Ym5ldElwcztcbiAgICByZXF1aXJlZElwcyArPSBncm91cElwcztcbiAgICBkZXRhaWwucHVzaChgJHtnLm5hbWV9OiAke2F6Q291bnR9IMOXIC8ke2cubWFza30gPSAke2dyb3VwSXBzfSBJUHNgKTtcbiAgfVxuXG4gIGlmIChyZXF1aXJlZElwcyA+IHZwY0lwcykge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBWUEMgQ0lEUiAke3ZwY0NpZHJ9ICgke3ZwY0lwc30gSVBzKSBpcyB0b28gc21hbGwuXFxuYCArXG4gICAgICAgIGBSZXF1aXJlZDogJHtyZXF1aXJlZElwc30gSVBzIGFjcm9zcyAke2VuYWJsZWRHcm91cHMubGVuZ3RofSBzdWJuZXQgZ3JvdXBzOlxcbmAgK1xuICAgICAgICBkZXRhaWwubWFwKChkKSA9PiBgICAke2R9YCkuam9pbignXFxuJykgK1xuICAgICAgICAnXFxuSW5jcmVhc2UgdGhlIFZQQyBzaXplLCByZWR1Y2UgYXpDb3VudCwgb3IgZGlzYWJsZSBzb21lIHN1Ym5ldCBncm91cHMuJyxcbiAgICApO1xuICB9XG59XG5cbmZ1bmN0aW9uIGFwcGx5U3VibmV0VGFncyhcbiAgc3VibmV0czogZWMyLklTdWJuZXRbXSxcbiAgdGFnczogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbik6IHZvaWQge1xuICBmb3IgKGNvbnN0IHN1Ym5ldCBvZiBzdWJuZXRzKSB7XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXModGFncykpIHtcbiAgICAgIFRhZ3Mub2Yoc3VibmV0KS5hZGQoa2V5LCB2YWx1ZSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHN0YW5kYXJkIG11bHRpLXRpZXIgVlBDIGZvbGxvd2luZyBUcnVlTWFyayBjb252ZW50aW9ucywgd2l0aCBzdWJuZXRcbiAqIHNpemluZyB0aGF0IG1pcnJvcnMgdGhlIHRydWVtYXJrL3RlcnJhZm9ybS1hd3MtdnBjIFRlcnJhZm9ybSBtb2R1bGUuXG4gKlxuICogKipTdWJuZXQgbGF5b3V0KiogKGVhY2ggZ3JvdXAgaXMgcmVwbGljYXRlZCBhY3Jvc3MgYWxsIEFacyk6XG4gKlxuICogfCBHcm91cCAgICAgICB8IFR5cGUgICAgICAgICAgICAgICAgfCBEZWZhdWx0IHNpemluZyAoYXV0bywgc2VlIHRhYmxlIGJlbG93KSB8XG4gKiB8LS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXxcbiAqIHwgcHJpdmF0ZSAgICAgfCBQUklWQVRFX1dJVEhfRUdSRVNTIHwgTGFyZ2VyIOKAlCBzaXplZCBmb3Igd29ya2xvYWQgdHJhZmZpYyAgICB8XG4gKiB8IHB1YmxpYyAgICAgIHwgUFVCTElDICAgICAgICAgICAgICB8IFNtYWxsZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqIHwgaW50cmEgICAgICAgfCBQUklWQVRFX0lTT0xBVEVEICAgIHwgU21hbGxlciDigJQgbm8gZWdyZXNzICAgICAgICAgICAgICAgICAgICB8XG4gKiB8IGRhdGFiYXNlICAgIHwgUFJJVkFURV9XSVRIX0VHUkVTUyB8IFNtYWxsZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqIHwgZWxhc3RpY2FjaGUgfCBQUklWQVRFX1dJVEhfRUdSRVNTIHwgU21hbGxlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogfCByZWRzaGlmdCAgICB8IFBSSVZBVEVfV0lUSF9FR1JFU1MgfCBTbWFsbGVyIChkaXNhYmxlZCBieSBkZWZhdWx0KSAgICAgICAgICB8XG4gKlxuICogKipBdXRvLXNpemluZyB0YWJsZSoqIChtYXRjaGVzIHRlcnJhZm9ybS1hd3MtdnBjIGBwcml2YXRlX3N1Ym5ldHNgL2BzdWJuZXRzYCBsb2NhbHMpOlxuICpcbiAqIHwgVlBDICAgIHwgcHJpdmF0ZSB8IHB1YmxpYy9pbnRyYS9kYXRhYmFzZS9lbGFzdGljYWNoZS9yZWRzaGlmdCB8XG4gKiB8LS0tLS0tLS18LS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXxcbiAqIHwgLzE2ICAgIHwgLzE5ICAgICB8IC8yMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogfCAvMTcgICAgfCAvMjAgICAgIHwgLzIyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8IC8xOCAgICB8IC8yMSAgICAgfCAvMjMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqIHwgLzE5ICAgIHwgLzIyICAgICB8IC8yNCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogfCAvMjAgICAgfCAvMjQgICAgIHwgLzI1ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKlxuICogT3ZlcnJpZGUgc2l6aW5nIHZpYSBgc3VibmV0Q2lkck1hc2tgICh1bmlmb3JtKSBvciBwZXItZ3JvdXAgcHJvcHMgbGlrZVxuICogYHByaXZhdGVTdWJuZXRDaWRyTWFza2AsIGBwdWJsaWNTdWJuZXRDaWRyTWFza2AsIGV0Yy4g4oCUIGVxdWl2YWxlbnQgdG8gdGhlXG4gKiBgcHJpdmF0ZV9uZXdiaXRzYCwgYHB1YmxpY19uZXdiaXRzYCwgLi4uIHZhcmlhYmxlcyBpbiBUZXJyYWZvcm0uXG4gKlxuICogPiAqKk5vdGUgb24gQ0lEUiBwbGFjZW1lbnQ6KiogQ0RLIGFsbG9jYXRlcyBzdWJuZXQgQ0lEUnMgc2VxdWVudGlhbGx5IGZyb21cbiAqID4gdGhlIHN0YXJ0IG9mIHRoZSBWUEMgQ0lEUiBibG9jay4gVGhpcyBkaWZmZXJzIGZyb20gVGVycmFmb3JtJ3MgcGxhY2VtZW50LFxuICogPiB3aGljaCB1c2VzIGV4cGxpY2l0IGBuZXRudW1gIG9mZnNldHMgdG8gcG9zaXRpb24gc3VibmV0IGdyb3VwcyBhdCBzcGVjaWZpY1xuICogPiBhZGRyZXNzZXMgd2l0aGluIHRoZSBWUEMuIFRoZSBzdWJuZXQgKnNpemVzKiBtYXRjaCBleGFjdGx5OyBvbmx5IHRoZVxuICogPiBzdGFydGluZyBhZGRyZXNzZXMgd2l0aGluIHRoZSBWUEMgZGlmZmVyLlxuICpcbiAqICoqSVB2NiBTdXBwb3J0OioqIFNldCBgZW5hYmxlSXB2NjogdHJ1ZWAgdG8gY29uZmlndXJlIHRoZSBWUEMgaW4gZHVhbC1zdGFja1xuICogbW9kZSB3aXRoIGJvdGggSVB2NCBhbmQgSVB2Ni4gQVdTIGF1dG9tYXRpY2FsbHkgYXNzaWducyBhbiBBbWF6b24tcHJvdmlkZWRcbiAqIC81NiBJUHY2IENJRFIgYmxvY2sgdG8gdGhlIFZQQywgYW5kIGVhY2ggc3VibmV0IHJlY2VpdmVzIGEgLzY0IElQdjYgQ0lEUi5cbiAqXG4gKiBHYXRld2F5IFZQQyBlbmRwb2ludHMgZm9yIFMzIGFuZCBEeW5hbW9EQiBhcmUgY3JlYXRlZCBieSBkZWZhdWx0IGFuZCBhdHRhY2hlZFxuICogdG8gcHJpdmF0ZSwgaW50cmEsIGRhdGFiYXNlLCBlbGFzdGljYWNoZSwgYW5kIHJlZHNoaWZ0IHJvdXRlIHRhYmxlcy5cbiAqXG4gKiBWUEMgYW5kIHN1Ym5ldCBJRHMgYXJlIHN0b3JlZCBpbiBBV1MgU1NNIFBhcmFtZXRlciBTdG9yZSB2aWEgTmV0d29ya1BhcmFtZXRlcnNcbiAqIGFuZCBvcHRpb25hbGx5IGV4cG9ydGVkIGFzIENsb3VkRm9ybWF0aW9uIG91dHB1dHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGFuZGFyZE5ldHdvcmsgZXh0ZW5kcyBFeHRlbmRlZENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBUaGUgVlBDIGNyZWF0ZWQgYnkgdGhpcyBjb25zdHJ1Y3QuXG4gICAqL1xuICByZWFkb25seSB2cGM6IGVjMi5WcGM7XG5cbiAgLyoqXG4gICAqIFRoZSBOZXR3b3JrUGFyYW1ldGVycyBjb25zdHJ1Y3QgaG9sZGluZyBTU00gcGF0aHMgYW5kIGNyZWF0ZWQgcGFyYW1ldGVycy5cbiAgICogVW5kZWZpbmVkIHdoZW4gc3RvcmVQYXJhbWV0ZXJzIGlzIGZhbHNlLlxuICAgKi9cbiAgcmVhZG9ubHkgbmV0d29ya1BhcmFtZXRlcnM/OiBOZXR3b3JrUGFyYW1ldGVycztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogU3RhbmRhcmROZXR3b3JrUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIHN0YW5kYXJkVGFnczogU3RhbmRhcmRUYWdzLm1lcmdlKHByb3BzLnN0YW5kYXJkVGFncywgTGliU3RhbmRhcmRUYWdzKSxcbiAgICB9KTtcblxuICAgIC8vIFRPRE8gWW91IGNoYW5nZSB0aGUgZGVmYXVsdCBoZXJlIERhcmVuXG4gICAgY29uc3QgYXpDb3VudCA9IHByb3BzLmF6Q291bnQgPz8gMztcbiAgICBjb25zdCBuYXRUeXBlID0gcHJvcHMubmF0VHlwZSA/PyAnbm9uZSc7XG5cbiAgICBjb25zdCBuYXRHYXRld2F5cyA9XG4gICAgICBuYXRUeXBlID09PSAnbXVsdGknID8gYXpDb3VudCA6IG5hdFR5cGUgPT09ICdzaW5nbGUnID8gMSA6IDA7XG5cbiAgICAvLyBUT0RPIE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIHJlZ2lvbmFsIE5BVFxuICAgIC8vIFRPRE8gTmVlZCB0byBhZGQgc3VwcG9ydCBmb3IgcG9vciBOQVRcbiAgICBjb25zdCB1c2VOYXRJbnN0YW5jZSA9IG5hdFR5cGUgPT09ICduYXRJbnN0YW5jZSc7XG5cbiAgICAvLyBUT0RPIE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIG5ldHdvcmsgZmlyZXdhbGxcblxuICAgIGNvbnN0IGNyZWF0ZVB1YmxpYyA9IHByb3BzLmNyZWF0ZVB1YmxpY1N1Ym5ldHMgPz8gdHJ1ZTtcbiAgICBjb25zdCBjcmVhdGVQcml2YXRlID0gcHJvcHMuY3JlYXRlUHJpdmF0ZVN1Ym5ldHMgPz8gdHJ1ZTtcbiAgICBjb25zdCBjcmVhdGVJbnRyYSA9IHByb3BzLmNyZWF0ZUludHJhU3VibmV0cyA/PyB0cnVlO1xuICAgIGNvbnN0IGNyZWF0ZURhdGFiYXNlID0gcHJvcHMuY3JlYXRlRGF0YWJhc2VTdWJuZXRzID8/IHRydWU7XG4gICAgY29uc3QgY3JlYXRlRWxhc3RpY2FjaGUgPSBwcm9wcy5jcmVhdGVFbGFzdGljYWNoZVN1Ym5ldHMgPz8gdHJ1ZTtcbiAgICBjb25zdCBjcmVhdGVSZWRzaGlmdCA9IHByb3BzLmNyZWF0ZVJlZHNoaWZ0U3VibmV0cyA/PyBmYWxzZTtcblxuICAgIGNvbnN0IG1hc2tzID0gcmVzb2x2ZVN1Ym5ldE1hc2tzKHByb3BzLnZwY0NpZHIsIHByb3BzKTtcblxuICAgIGNvbnN0IGVuYWJsZWRHcm91cHM6IHttYXNrOiBudW1iZXI7IG5hbWU6IHN0cmluZ31bXSA9IFtdO1xuICAgIGlmIChjcmVhdGVQdWJsaWMpIGVuYWJsZWRHcm91cHMucHVzaCh7bWFzazogbWFza3MucHVibGljLCBuYW1lOiAncHVibGljJ30pO1xuICAgIGlmIChjcmVhdGVQcml2YXRlKVxuICAgICAgZW5hYmxlZEdyb3Vwcy5wdXNoKHttYXNrOiBtYXNrcy5wcml2YXRlLCBuYW1lOiAncHJpdmF0ZSd9KTtcbiAgICBpZiAoY3JlYXRlSW50cmEpIGVuYWJsZWRHcm91cHMucHVzaCh7bWFzazogbWFza3MuaW50cmEsIG5hbWU6ICdpbnRyYSd9KTtcbiAgICBpZiAoY3JlYXRlRGF0YWJhc2UpXG4gICAgICBlbmFibGVkR3JvdXBzLnB1c2goe21hc2s6IG1hc2tzLmRhdGFiYXNlLCBuYW1lOiAnZGF0YWJhc2UnfSk7XG4gICAgaWYgKGNyZWF0ZUVsYXN0aWNhY2hlKVxuICAgICAgZW5hYmxlZEdyb3Vwcy5wdXNoKHttYXNrOiBtYXNrcy5lbGFzdGljYWNoZSwgbmFtZTogJ2VsYXN0aWNhY2hlJ30pO1xuICAgIGlmIChjcmVhdGVSZWRzaGlmdClcbiAgICAgIGVuYWJsZWRHcm91cHMucHVzaCh7bWFzazogbWFza3MucmVkc2hpZnQsIG5hbWU6ICdyZWRzaGlmdCd9KTtcblxuICAgIHZhbGlkYXRlQWRkcmVzc1NwYWNlKHByb3BzLnZwY0NpZHIsIGF6Q291bnQsIGVuYWJsZWRHcm91cHMpO1xuXG4gICAgY29uc3Qgc3VibmV0Q29uZmlndXJhdGlvbjogZWMyLlN1Ym5ldENvbmZpZ3VyYXRpb25bXSA9IFtdO1xuXG4gICAgaWYgKGNyZWF0ZVByaXZhdGUpIHtcbiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb24ucHVzaCh7XG4gICAgICAgIG5hbWU6ICdwcml2YXRlJyxcbiAgICAgICAgc3VibmV0VHlwZTogZWMyLlN1Ym5ldFR5cGUuUFJJVkFURV9XSVRIX0VHUkVTUyxcbiAgICAgICAgY2lkck1hc2s6IG1hc2tzLnByaXZhdGUsXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKGNyZWF0ZVB1YmxpYykge1xuICAgICAgc3VibmV0Q29uZmlndXJhdGlvbi5wdXNoKHtcbiAgICAgICAgbmFtZTogJ3B1YmxpYycsXG4gICAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBVQkxJQyxcbiAgICAgICAgY2lkck1hc2s6IG1hc2tzLnB1YmxpYyxcbiAgICAgICAgbWFwUHVibGljSXBPbkxhdW5jaDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoY3JlYXRlSW50cmEpIHtcbiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb24ucHVzaCh7XG4gICAgICAgIG5hbWU6ICdpbnRyYScsXG4gICAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfSVNPTEFURUQsXG4gICAgICAgIGNpZHJNYXNrOiBtYXNrcy5pbnRyYSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoY3JlYXRlRGF0YWJhc2UpIHtcbiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb24ucHVzaCh7XG4gICAgICAgIG5hbWU6ICdkYXRhYmFzZScsXG4gICAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfV0lUSF9FR1JFU1MsXG4gICAgICAgIGNpZHJNYXNrOiBtYXNrcy5kYXRhYmFzZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoY3JlYXRlRWxhc3RpY2FjaGUpIHtcbiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb24ucHVzaCh7XG4gICAgICAgIG5hbWU6ICdlbGFzdGljYWNoZScsXG4gICAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfV0lUSF9FR1JFU1MsXG4gICAgICAgIGNpZHJNYXNrOiBtYXNrcy5lbGFzdGljYWNoZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoY3JlYXRlUmVkc2hpZnQpIHtcbiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb24ucHVzaCh7XG4gICAgICAgIG5hbWU6ICdyZWRzaGlmdCcsXG4gICAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfV0lUSF9FR1JFU1MsXG4gICAgICAgIGNpZHJNYXNrOiBtYXNrcy5yZWRzaGlmdCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMudnBjID0gbmV3IGVjMi5WcGModGhpcywgJ1ZwYycsIHtcbiAgICAgIHZwY05hbWU6IHByb3BzLm5hbWUsXG4gICAgICBtYXhBenM6IGF6Q291bnQsXG4gICAgICBuYXRHYXRld2F5cyxcbiAgICAgIGlwQWRkcmVzc2VzOiBlYzIuSXBBZGRyZXNzZXMuY2lkcihwcm9wcy52cGNDaWRyKSxcbiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb24sXG4gICAgICAuLi4ocHJvcHMuZW5hYmxlSXB2NlxuICAgICAgICA/IHtcbiAgICAgICAgICAgIGlwUHJvdG9jb2w6IGVjMi5JcFByb3RvY29sLkRVQUxfU1RBQ0ssXG4gICAgICAgICAgfVxuICAgICAgICA6IHt9KSxcbiAgICB9KTtcblxuICAgIGlmICh1c2VOYXRJbnN0YW5jZSkge1xuICAgICAgaWYgKCFjcmVhdGVQdWJsaWMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibmF0VHlwZSAnbmF0SW5zdGFuY2UnIHJlcXVpcmVzIHB1YmxpYyBzdWJuZXRzLlwiKTtcbiAgICAgIH1cblxuICAgICAgLy8gR2V0IHByaXZhdGUgc3VibmV0cyAoUFJJVkFURV9XSVRIX0VHUkVTUyB0eXBlKSBmb3IgTkFUIHJvdXRpbmcuXG4gICAgICAvLyBUaGlzIGluY2x1ZGVzOiBwcml2YXRlLCBkYXRhYmFzZSwgZWxhc3RpY2FjaGUsIGFuZCByZWRzaGlmdCBzdWJuZXQgZ3JvdXBzLlxuICAgICAgLy8gVGhpcyBkb2VzIE5PVCBpbmNsdWRlOiBpbnRyYSBzdWJuZXRzICh3aGljaCBhcmUgUFJJVkFURV9JU09MQVRFRCBhbmQgaGF2ZSBubyBpbnRlcm5ldCBhY2Nlc3MpLlxuICAgICAgY29uc3QgYWxsUHJpdmF0ZVN1Ym5ldHMgPSB0aGlzLnZwYy5wcml2YXRlU3VibmV0cyBhcyBlYzIuU3VibmV0W107XG5cbiAgICAgIGlmIChhbGxQcml2YXRlU3VibmV0cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwibmF0VHlwZSAnbmF0SW5zdGFuY2UnIHJlcXVpcmVzIGF0IGxlYXN0IG9uZSBwcml2YXRlIHN1Ym5ldC5cIixcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ29sbGVjdCBhbGwgcHJpdmF0ZSBzdWJuZXQgQ0lEUiBibG9ja3MgZm9yIHNlY3VyaXR5IGdyb3VwIHJ1bGVzXG4gICAgICBjb25zdCBwcml2YXRlQ2lkckJsb2NrcyA9IGFsbFByaXZhdGVTdWJuZXRzLm1hcCgocykgPT4gcy5pcHY0Q2lkckJsb2NrKTtcblxuICAgICAgLy8gR2V0IHByaXZhdGUgc3VibmV0IHJvdXRlIHRhYmxlcyBmb3IgTkFUIHJvdXRpbmdcbiAgICAgIGNvbnN0IHJvdXRlVGFibGVJZHMgPSBhbGxQcml2YXRlU3VibmV0cy5tYXAoXG4gICAgICAgIChzKSA9PiBzLnJvdXRlVGFibGUucm91dGVUYWJsZUlkLFxuICAgICAgKTtcblxuICAgICAgLy8gVGhlIE5BVCBpbnN0YW5jZSdzIHByaW1hcnkgaW50ZXJmYWNlIHdpbGwgcmVjZWl2ZSBhbiBhdXRvLWFzc2lnbmVkXG4gICAgICAvLyBwdWJsaWMgSVAgZnJvbSB0aGUgcHVibGljIHN1Ym5ldCwgZW5hYmxpbmcgaW1tZWRpYXRlIEludGVybmV0IGVncmVzcy5cbiAgICAgIC8vIEZvciBhIHN0YWJsZSBvdXRib3VuZCBJUCwgYWxsb2NhdGUgYW4gRUlQIGFuZCBhc3NvY2lhdGUgaXQgd2l0aCB0aGVcbiAgICAgIC8vIGluc3RhbmNlJ3MgcHJpbWFyeSBpbnRlcmZhY2UgdXNpbmcgQVNHIGxpZmVjeWNsZSBob29rcyBvciB0YWdzLlxuICAgICAgbmV3IE5hdEluc3RhbmNlKHRoaXMsICdOYXQnLCB7XG4gICAgICAgIHZwYzogdGhpcy52cGMsXG4gICAgICAgIHB1YmxpY1N1Ym5ldDogdGhpcy52cGMuc2VsZWN0U3VibmV0cyh7c3VibmV0R3JvdXBOYW1lOiAncHVibGljJ30pXG4gICAgICAgICAgLnN1Ym5ldHNbMF0sXG4gICAgICAgIHByaXZhdGVTdWJuZXRDaWRyQmxvY2tzOiBwcml2YXRlQ2lkckJsb2NrcyxcbiAgICAgICAgcHJpdmF0ZVJvdXRlVGFibGVJZHM6IHJvdXRlVGFibGVJZHMsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBBcHBseSBwZXItc3VibmV0LWdyb3VwIHRhZ3NcbiAgICBpZiAocHJvcHMucHVibGljU3VibmV0VGFncyAmJiBjcmVhdGVQdWJsaWMpIHtcbiAgICAgIGFwcGx5U3VibmV0VGFncyhcbiAgICAgICAgdGhpcy52cGMuc2VsZWN0U3VibmV0cyh7c3VibmV0R3JvdXBOYW1lOiAncHVibGljJ30pLnN1Ym5ldHMsXG4gICAgICAgIHByb3BzLnB1YmxpY1N1Ym5ldFRhZ3MsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAocHJvcHMucHJpdmF0ZVN1Ym5ldFRhZ3MgJiYgY3JlYXRlUHJpdmF0ZSkge1xuICAgICAgYXBwbHlTdWJuZXRUYWdzKFxuICAgICAgICB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdwcml2YXRlJ30pLnN1Ym5ldHMsXG4gICAgICAgIHByb3BzLnByaXZhdGVTdWJuZXRUYWdzLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLmludHJhU3VibmV0VGFncyAmJiBjcmVhdGVJbnRyYSkge1xuICAgICAgYXBwbHlTdWJuZXRUYWdzKFxuICAgICAgICB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdpbnRyYSd9KS5zdWJuZXRzLFxuICAgICAgICBwcm9wcy5pbnRyYVN1Ym5ldFRhZ3MsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAocHJvcHMuZGF0YWJhc2VTdWJuZXRUYWdzICYmIGNyZWF0ZURhdGFiYXNlKSB7XG4gICAgICBhcHBseVN1Ym5ldFRhZ3MoXG4gICAgICAgIHRoaXMudnBjLnNlbGVjdFN1Ym5ldHMoe3N1Ym5ldEdyb3VwTmFtZTogJ2RhdGFiYXNlJ30pLnN1Ym5ldHMsXG4gICAgICAgIHByb3BzLmRhdGFiYXNlU3VibmV0VGFncyxcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChwcm9wcy5lbGFzdGljYWNoZVN1Ym5ldFRhZ3MgJiYgY3JlYXRlRWxhc3RpY2FjaGUpIHtcbiAgICAgIGFwcGx5U3VibmV0VGFncyhcbiAgICAgICAgdGhpcy52cGMuc2VsZWN0U3VibmV0cyh7c3VibmV0R3JvdXBOYW1lOiAnZWxhc3RpY2FjaGUnfSkuc3VibmV0cyxcbiAgICAgICAgcHJvcHMuZWxhc3RpY2FjaGVTdWJuZXRUYWdzLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLnJlZHNoaWZ0U3VibmV0VGFncyAmJiBjcmVhdGVSZWRzaGlmdCkge1xuICAgICAgYXBwbHlTdWJuZXRUYWdzKFxuICAgICAgICB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdyZWRzaGlmdCd9KS5zdWJuZXRzLFxuICAgICAgICBwcm9wcy5yZWRzaGlmdFN1Ym5ldFRhZ3MsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEJ1aWxkIHRoZSBsaXN0IG9mIHN1Ym5ldCBncm91cHMgZm9yIGdhdGV3YXkgZW5kcG9pbnQgcm91dGUgdGFibGVzLlxuICAgIGNvbnN0IGVuZHBvaW50U3VibmV0czogZWMyLlN1Ym5ldFNlbGVjdGlvbltdID0gW107XG4gICAgaWYgKGNyZWF0ZVByaXZhdGUpIGVuZHBvaW50U3VibmV0cy5wdXNoKHtzdWJuZXRHcm91cE5hbWU6ICdwcml2YXRlJ30pO1xuICAgIGlmIChjcmVhdGVJbnRyYSkgZW5kcG9pbnRTdWJuZXRzLnB1c2goe3N1Ym5ldEdyb3VwTmFtZTogJ2ludHJhJ30pO1xuICAgIGlmIChjcmVhdGVEYXRhYmFzZSkgZW5kcG9pbnRTdWJuZXRzLnB1c2goe3N1Ym5ldEdyb3VwTmFtZTogJ2RhdGFiYXNlJ30pO1xuICAgIGlmIChjcmVhdGVFbGFzdGljYWNoZSlcbiAgICAgIGVuZHBvaW50U3VibmV0cy5wdXNoKHtzdWJuZXRHcm91cE5hbWU6ICdlbGFzdGljYWNoZSd9KTtcbiAgICBpZiAoY3JlYXRlUmVkc2hpZnQpIGVuZHBvaW50U3VibmV0cy5wdXNoKHtzdWJuZXRHcm91cE5hbWU6ICdyZWRzaGlmdCd9KTtcblxuICAgIGlmICgocHJvcHMuY3JlYXRlUzNFbmRwb2ludCA/PyB0cnVlKSAmJiBlbmRwb2ludFN1Ym5ldHMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy52cGMuYWRkR2F0ZXdheUVuZHBvaW50KCdTM0dhdGV3YXlFbmRwb2ludCcsIHtcbiAgICAgICAgc2VydmljZTogZWMyLkdhdGV3YXlWcGNFbmRwb2ludEF3c1NlcnZpY2UuUzMsXG4gICAgICAgIHN1Ym5ldHM6IGVuZHBvaW50U3VibmV0cyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICgocHJvcHMuY3JlYXRlRHluYW1vRGJFbmRwb2ludCA/PyB0cnVlKSAmJiBlbmRwb2ludFN1Ym5ldHMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy52cGMuYWRkR2F0ZXdheUVuZHBvaW50KCdEeW5hbW9EYkdhdGV3YXlFbmRwb2ludCcsIHtcbiAgICAgICAgc2VydmljZTogZWMyLkdhdGV3YXlWcGNFbmRwb2ludEF3c1NlcnZpY2UuRFlOQU1PREIsXG4gICAgICAgIHN1Ym5ldHM6IGVuZHBvaW50U3VibmV0cyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIENsb3VkRm9ybWF0aW9uIG91dHB1dHNcbiAgICBpZiAocHJvcHMuY3JlYXRlT3V0cHV0cyA/PyB0cnVlKSB7XG4gICAgICBjb25zdCBzdGFja05hbWUgPSBTdGFjay5vZih0aGlzKS5zdGFja05hbWU7XG5cbiAgICAgIG5ldyBDZm5PdXRwdXQodGhpcywgJ1ZwY0lkJywge1xuICAgICAgICB2YWx1ZTogdGhpcy52cGMudnBjSWQsXG4gICAgICAgIGV4cG9ydE5hbWU6IGAke3N0YWNrTmFtZX06VnBjSWRgLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChjcmVhdGVQdWJsaWMpIHtcbiAgICAgICAgbmV3IENmbk91dHB1dCh0aGlzLCAnUHVibGljU3VibmV0SWRzJywge1xuICAgICAgICAgIHZhbHVlOiB0aGlzLnZwY1xuICAgICAgICAgICAgLnNlbGVjdFN1Ym5ldHMoe3N1Ym5ldEdyb3VwTmFtZTogJ3B1YmxpYyd9KVxuICAgICAgICAgICAgLnN1Ym5ldElkcy5qb2luKCcsJyksXG4gICAgICAgICAgZXhwb3J0TmFtZTogYCR7c3RhY2tOYW1lfTpQdWJsaWNTdWJuZXRJZHNgLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChjcmVhdGVQcml2YXRlKSB7XG4gICAgICAgIG5ldyBDZm5PdXRwdXQodGhpcywgJ1ByaXZhdGVTdWJuZXRJZHMnLCB7XG4gICAgICAgICAgdmFsdWU6IHRoaXMudnBjXG4gICAgICAgICAgICAuc2VsZWN0U3VibmV0cyh7c3VibmV0R3JvdXBOYW1lOiAncHJpdmF0ZSd9KVxuICAgICAgICAgICAgLnN1Ym5ldElkcy5qb2luKCcsJyksXG4gICAgICAgICAgZXhwb3J0TmFtZTogYCR7c3RhY2tOYW1lfTpQcml2YXRlU3VibmV0SWRzYCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY3JlYXRlSW50cmEpIHtcbiAgICAgICAgbmV3IENmbk91dHB1dCh0aGlzLCAnSW50cmFTdWJuZXRJZHMnLCB7XG4gICAgICAgICAgdmFsdWU6IHRoaXMudnBjXG4gICAgICAgICAgICAuc2VsZWN0U3VibmV0cyh7c3VibmV0R3JvdXBOYW1lOiAnaW50cmEnfSlcbiAgICAgICAgICAgIC5zdWJuZXRJZHMuam9pbignLCcpLFxuICAgICAgICAgIGV4cG9ydE5hbWU6IGAke3N0YWNrTmFtZX06SW50cmFTdWJuZXRJZHNgLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChjcmVhdGVEYXRhYmFzZSkge1xuICAgICAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsICdEYXRhYmFzZVN1Ym5ldElkcycsIHtcbiAgICAgICAgICB2YWx1ZTogdGhpcy52cGNcbiAgICAgICAgICAgIC5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdkYXRhYmFzZSd9KVxuICAgICAgICAgICAgLnN1Ym5ldElkcy5qb2luKCcsJyksXG4gICAgICAgICAgZXhwb3J0TmFtZTogYCR7c3RhY2tOYW1lfTpEYXRhYmFzZVN1Ym5ldElkc2AsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGNyZWF0ZUVsYXN0aWNhY2hlKSB7XG4gICAgICAgIG5ldyBDZm5PdXRwdXQodGhpcywgJ0VsYXN0aWNhY2hlU3VibmV0SWRzJywge1xuICAgICAgICAgIHZhbHVlOiB0aGlzLnZwY1xuICAgICAgICAgICAgLnNlbGVjdFN1Ym5ldHMoe3N1Ym5ldEdyb3VwTmFtZTogJ2VsYXN0aWNhY2hlJ30pXG4gICAgICAgICAgICAuc3VibmV0SWRzLmpvaW4oJywnKSxcbiAgICAgICAgICBleHBvcnROYW1lOiBgJHtzdGFja05hbWV9OkVsYXN0aWNhY2hlU3VibmV0SWRzYCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY3JlYXRlUmVkc2hpZnQpIHtcbiAgICAgICAgbmV3IENmbk91dHB1dCh0aGlzLCAnUmVkc2hpZnRTdWJuZXRJZHMnLCB7XG4gICAgICAgICAgdmFsdWU6IHRoaXMudnBjXG4gICAgICAgICAgICAuc2VsZWN0U3VibmV0cyh7c3VibmV0R3JvdXBOYW1lOiAncmVkc2hpZnQnfSlcbiAgICAgICAgICAgIC5zdWJuZXRJZHMuam9pbignLCcpLFxuICAgICAgICAgIGV4cG9ydE5hbWU6IGAke3N0YWNrTmFtZX06UmVkc2hpZnRTdWJuZXRJZHNgLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTU00gUGFyYW1ldGVyIFN0b3JlIHZpYSBOZXR3b3JrUGFyYW1ldGVyc1xuICAgIGlmIChwcm9wcy5zdG9yZVBhcmFtZXRlcnMgPz8gdHJ1ZSkge1xuICAgICAgdGhpcy5uZXR3b3JrUGFyYW1ldGVycyA9IG5ldyBOZXR3b3JrUGFyYW1ldGVycyhcbiAgICAgICAgdGhpcyxcbiAgICAgICAgJ05ldHdvcmtQYXJhbWV0ZXJzJyxcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IHByb3BzLm5hbWUsXG4gICAgICAgICAgcHJlZml4OiBwcm9wcy5wYXJhbWV0ZXJzUHJlZml4LFxuICAgICAgICAgIGNyZWF0ZTogdHJ1ZSxcbiAgICAgICAgICBsb29rdXBWcGM6IGZhbHNlLFxuICAgICAgICAgIGxvb2t1cEF6czogZmFsc2UsXG4gICAgICAgICAgbG9va3VwUHVibGljU3VibmV0czogZmFsc2UsXG4gICAgICAgICAgbG9va3VwUHJpdmF0ZVN1Ym5ldHM6IGZhbHNlLFxuICAgICAgICAgIGxvb2t1cEludHJhU3VibmV0czogZmFsc2UsXG4gICAgICAgICAgbG9va3VwRGF0YWJhc2VTdWJuZXRzOiBmYWxzZSxcbiAgICAgICAgICBsb29rdXBFbGFzdGljYWNoZVN1Ym5ldHM6IGZhbHNlLFxuICAgICAgICAgIGxvb2t1cFJlZHNoaWZ0U3VibmV0czogZmFsc2UsXG4gICAgICAgICAgbG9va3VwT3V0cG9zdFN1Ym5ldHM6IGZhbHNlLFxuICAgICAgICAgIHZwY0lkOiB0aGlzLnZwYy52cGNJZCxcbiAgICAgICAgICBhenM6IHRoaXMudnBjLmF2YWlsYWJpbGl0eVpvbmVzLFxuICAgICAgICAgIHB1YmxpY1N1Ym5ldElkczogY3JlYXRlUHVibGljXG4gICAgICAgICAgICA/IHRoaXMudnBjLnNlbGVjdFN1Ym5ldHMoe3N1Ym5ldEdyb3VwTmFtZTogJ3B1YmxpYyd9KS5zdWJuZXRJZHNcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgIHByaXZhdGVTdWJuZXRJZHM6IGNyZWF0ZVByaXZhdGVcbiAgICAgICAgICAgID8gdGhpcy52cGMuc2VsZWN0U3VibmV0cyh7c3VibmV0R3JvdXBOYW1lOiAncHJpdmF0ZSd9KS5zdWJuZXRJZHNcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGludHJhU3VibmV0SWRzOiBjcmVhdGVJbnRyYVxuICAgICAgICAgICAgPyB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdpbnRyYSd9KS5zdWJuZXRJZHNcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGRhdGFiYXNlU3VibmV0SWRzOiBjcmVhdGVEYXRhYmFzZVxuICAgICAgICAgICAgPyB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdkYXRhYmFzZSd9KS5zdWJuZXRJZHNcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGVsYXN0aWNhY2hlU3VibmV0SWRzOiBjcmVhdGVFbGFzdGljYWNoZVxuICAgICAgICAgICAgPyB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdlbGFzdGljYWNoZSd9KS5zdWJuZXRJZHNcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgIHJlZHNoaWZ0U3VibmV0SWRzOiBjcmVhdGVSZWRzaGlmdFxuICAgICAgICAgICAgPyB0aGlzLnZwYy5zZWxlY3RTdWJuZXRzKHtzdWJuZXRHcm91cE5hbWU6ICdyZWRzaGlmdCd9KS5zdWJuZXRJZHNcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|