@fjall/components-infrastructure 0.77.4 → 0.78.3
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/lib/app.d.ts +8 -5
- package/dist/lib/app.js +19 -7
- package/dist/lib/patterns/aws/buildkite.js +4 -7
- package/dist/lib/patterns/aws/compute.d.ts +479 -48
- package/dist/lib/patterns/aws/compute.js +307 -94
- package/dist/lib/patterns/aws/database.d.ts +1 -0
- package/dist/lib/patterns/aws/database.js +4 -1
- package/dist/lib/patterns/aws/hostedZone.js +4 -7
- package/dist/lib/patterns/aws/loadBalancer.d.ts +163 -0
- package/dist/lib/patterns/aws/loadBalancer.js +278 -0
- package/dist/lib/patterns/aws/network.d.ts +1 -0
- package/dist/lib/patterns/aws/network.js +2 -1
- package/dist/lib/resources/aws/compute/capacityProviderDrainWaiter.d.ts +20 -0
- package/dist/lib/resources/aws/compute/capacityProviderDrainWaiter.js +180 -0
- package/dist/lib/resources/aws/compute/ecs.d.ts +294 -57
- package/dist/lib/resources/aws/compute/ecs.js +747 -261
- package/dist/lib/resources/aws/compute/ecsFreeTier.js +1 -1
- package/dist/lib/resources/aws/compute/ecsSpot.js +1 -1
- package/dist/lib/resources/aws/compute/utilities/capacityProviderDrainWaiter.d.ts +20 -0
- package/dist/lib/resources/aws/compute/utilities/capacityProviderDrainWaiter.js +180 -0
- package/dist/lib/resources/aws/database/rdsAurora.d.ts +1 -0
- package/dist/lib/resources/aws/database/rdsAurora.js +2 -2
- package/dist/lib/resources/aws/database/rdsAuroraGlobal.d.ts +1 -0
- package/dist/lib/resources/aws/database/rdsAuroraGlobal.js +2 -1
- package/dist/lib/resources/aws/database/rdsDeletionWaiter.d.ts +33 -0
- package/dist/lib/resources/aws/database/rdsDeletionWaiter.js +74 -0
- package/dist/lib/resources/aws/database/rdsInstance.d.ts +1 -0
- package/dist/lib/resources/aws/database/rdsInstance.js +3 -3
- package/dist/lib/resources/aws/networking/vpc.d.ts +1 -0
- package/dist/lib/resources/aws/networking/vpc.js +4 -3
- package/dist/lib/resources/aws/networking/vpcEndpoint.d.ts +2 -2
- package/dist/lib/resources/aws/networking/vpcEndpoint.js +1 -1
- package/dist/lib/resources/aws/networking/vpcEndpoints.d.ts +71 -0
- package/dist/lib/resources/aws/networking/vpcEndpoints.js +125 -0
- package/dist/lib/resources/aws/secrets/kms.d.ts +14 -0
- package/dist/lib/resources/aws/secrets/kms.js +5 -2
- package/dist/lib/resources/aws/secrets/secret.js +1 -1
- package/dist/lib/utils/standardTagsAspect.d.ts +26 -12
- package/dist/lib/utils/standardTagsAspect.js +67 -477
- package/dist/lib/utils/tagResource.d.ts +18 -3
- package/dist/lib/utils/tagResource.js +23 -6
- package/package.json +3 -3
- package/dist/lib/aspects/resourceInventory.d.ts +0 -41
- package/dist/lib/aspects/resourceInventory.js +0 -56
- package/dist/lib/config/audit.d.ts +0 -18
- package/dist/lib/config/audit.js +0 -22
- package/dist/lib/patterns/aws/auditRole.d.ts +0 -44
- package/dist/lib/patterns/aws/auditRole.js +0 -58
- package/dist/lib/patterns/aws/basicApp.d.ts +0 -0
- package/dist/lib/patterns/aws/basicApp.js +0 -150
- package/dist/lib/patterns/aws/ec2.d.ts +0 -43
- package/dist/lib/patterns/aws/ec2.js +0 -123
- package/dist/lib/patterns/aws/freeTierApp.d.ts +0 -44
- package/dist/lib/patterns/aws/freeTierApp.js +0 -83
- package/dist/lib/patterns/aws/spotInstanceApp.d.ts +0 -45
- package/dist/lib/patterns/aws/spotInstanceApp.js +0 -85
- package/dist/lib/resources/aws/audit/auditRole.d.ts +0 -32
- package/dist/lib/resources/aws/audit/auditRole.js +0 -46
- package/dist/lib/resources/aws/database/databaseFreeTier.d.ts +0 -15
- package/dist/lib/resources/aws/database/databaseFreeTier.js +0 -29
- package/dist/lib/resources/aws/database/rdsFreeTier.d.ts +0 -37
- package/dist/lib/resources/aws/database/rdsFreeTier.js +0 -84
- package/dist/lib/utils/getCidr.d.ts +0 -8
- package/dist/lib/utils/getCidr.js +0 -40
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LoadBalancer = exports.LoadBalancerFactory = void 0;
|
|
4
|
+
const constructs_1 = require("constructs");
|
|
5
|
+
const aws_elasticloadbalancingv2_1 = require("aws-cdk-lib/aws-elasticloadbalancingv2");
|
|
6
|
+
const aws_certificatemanager_1 = require("aws-cdk-lib/aws-certificatemanager");
|
|
7
|
+
const aws_route53_1 = require("aws-cdk-lib/aws-route53");
|
|
8
|
+
const aws_route53_targets_1 = require("aws-cdk-lib/aws-route53-targets");
|
|
9
|
+
const aws_ec2_1 = require("aws-cdk-lib/aws-ec2");
|
|
10
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
11
|
+
const cfnOutput_1 = require("../../resources/aws/utilities/cfnOutput");
|
|
12
|
+
const hostedZone_1 = require("./hostedZone");
|
|
13
|
+
/**
|
|
14
|
+
* Validates load balancer props and logs warnings for misconfigured options.
|
|
15
|
+
*/
|
|
16
|
+
function validateLoadBalancerProps(props) {
|
|
17
|
+
if (props.healthCheck) {
|
|
18
|
+
if (props.healthCheck.interval !== undefined) {
|
|
19
|
+
if (props.healthCheck.interval < 5 || props.healthCheck.interval > 300) {
|
|
20
|
+
throw new Error("Health check interval must be between 5 and 300 seconds.");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (props.healthCheck.timeout !== undefined) {
|
|
24
|
+
if (props.healthCheck.timeout < 2 || props.healthCheck.timeout > 120) {
|
|
25
|
+
throw new Error("Health check timeout must be between 2 and 120 seconds.");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Factory for creating LoadBalancer constructs.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* // Simple HTTP load balancer
|
|
35
|
+
* const alb = app.addCompute(
|
|
36
|
+
* LoadBalancerFactory.build("MainALB", {})
|
|
37
|
+
* );
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // HTTPS load balancer with domain
|
|
41
|
+
* const alb = app.addCompute(
|
|
42
|
+
* LoadBalancerFactory.build("MainALB", {
|
|
43
|
+
* domain: "app.example.com"
|
|
44
|
+
* })
|
|
45
|
+
* );
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* // Internal load balancer
|
|
49
|
+
* const alb = app.addCompute(
|
|
50
|
+
* LoadBalancerFactory.build("InternalALB", {
|
|
51
|
+
* public: false
|
|
52
|
+
* })
|
|
53
|
+
* );
|
|
54
|
+
*/
|
|
55
|
+
class LoadBalancerFactory {
|
|
56
|
+
static build(id, props) {
|
|
57
|
+
return (app, scope) => {
|
|
58
|
+
validateLoadBalancerProps(props);
|
|
59
|
+
const resolvedProps = {
|
|
60
|
+
...props,
|
|
61
|
+
vpc: props.vpc || app.getVpc()
|
|
62
|
+
};
|
|
63
|
+
return new LoadBalancer(scope, id, resolvedProps);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.LoadBalancerFactory = LoadBalancerFactory;
|
|
68
|
+
/**
|
|
69
|
+
* Application Load Balancer construct that can be shared across multiple ECS services.
|
|
70
|
+
*
|
|
71
|
+
* Use LoadBalancerFactory.build() to create instances via app.addCompute().
|
|
72
|
+
*/
|
|
73
|
+
class LoadBalancer extends constructs_1.Construct {
|
|
74
|
+
constructor(scope, id, props) {
|
|
75
|
+
super(scope, id);
|
|
76
|
+
this.defaultHealthCheck = props.healthCheck || {};
|
|
77
|
+
this.isHttps = !!props.domain;
|
|
78
|
+
// Create security group
|
|
79
|
+
this.securityGroup = new aws_ec2_1.SecurityGroup(this, "SecurityGroup", {
|
|
80
|
+
vpc: props.vpc,
|
|
81
|
+
description: `Security group for ${id} load balancer`,
|
|
82
|
+
allowAllOutbound: true
|
|
83
|
+
});
|
|
84
|
+
// Allow inbound traffic
|
|
85
|
+
const inboundPort = this.isHttps ? 443 : 80;
|
|
86
|
+
this.securityGroup.addIngressRule({ connections: { allowFromAnyIpv4: () => { } } }, aws_ec2_1.Port.tcp(inboundPort), `Allow inbound ${this.isHttps ? "HTTPS" : "HTTP"}`);
|
|
87
|
+
// Create ALB
|
|
88
|
+
const loadBalancerName = this.truncateName(`${id}ALB`, 32);
|
|
89
|
+
this.alb = new aws_elasticloadbalancingv2_1.ApplicationLoadBalancer(this, "ALB", {
|
|
90
|
+
vpc: props.vpc,
|
|
91
|
+
internetFacing: props.public !== false,
|
|
92
|
+
securityGroup: this.securityGroup,
|
|
93
|
+
loadBalancerName,
|
|
94
|
+
vpcSubnets: {
|
|
95
|
+
subnetType: props.public !== false ? aws_ec2_1.SubnetType.PUBLIC : aws_ec2_1.SubnetType.PRIVATE_WITH_EGRESS
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
// Set up domain if configured
|
|
99
|
+
if (props.domain) {
|
|
100
|
+
const domainConfig = this.normaliseDomainConfig(props.domain);
|
|
101
|
+
this.setupDomain(domainConfig);
|
|
102
|
+
}
|
|
103
|
+
// Create listener
|
|
104
|
+
if (this.isHttps && this.certificate) {
|
|
105
|
+
this.listener = this.alb.addListener("Listener", {
|
|
106
|
+
port: 443,
|
|
107
|
+
protocol: aws_elasticloadbalancingv2_1.ApplicationProtocol.HTTPS,
|
|
108
|
+
certificates: [this.certificate]
|
|
109
|
+
});
|
|
110
|
+
// Add HTTP redirect
|
|
111
|
+
this.alb.addListener("HttpRedirect", {
|
|
112
|
+
port: 80,
|
|
113
|
+
protocol: aws_elasticloadbalancingv2_1.ApplicationProtocol.HTTP,
|
|
114
|
+
defaultAction: {
|
|
115
|
+
redirect: {
|
|
116
|
+
protocol: "HTTPS",
|
|
117
|
+
port: "443",
|
|
118
|
+
permanent: true
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
this.listener = this.alb.addListener("Listener", {
|
|
125
|
+
port: 80,
|
|
126
|
+
protocol: aws_elasticloadbalancingv2_1.ApplicationProtocol.HTTP
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
// Add default action (returns 503 if no targets match)
|
|
130
|
+
this.listener.addAction("DefaultAction", {
|
|
131
|
+
action: {
|
|
132
|
+
fixedResponse: {
|
|
133
|
+
statusCode: 503,
|
|
134
|
+
contentType: "text/plain",
|
|
135
|
+
messageBody: "No service available"
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
// Set URL
|
|
140
|
+
this.url = this.isHttps
|
|
141
|
+
? `https://${this.alb.loadBalancerDnsName}`
|
|
142
|
+
: `http://${this.alb.loadBalancerDnsName}`;
|
|
143
|
+
// Set up connections
|
|
144
|
+
this.connections = new aws_ec2_1.Connections({
|
|
145
|
+
securityGroups: [this.securityGroup],
|
|
146
|
+
defaultPort: aws_ec2_1.Port.tcp(inboundPort)
|
|
147
|
+
});
|
|
148
|
+
// Outputs
|
|
149
|
+
new cfnOutput_1.CfnOutput(this, "LoadBalancerDnsName", {
|
|
150
|
+
key: `${id}LoadBalancerDnsName`,
|
|
151
|
+
exportName: `${id}LoadBalancerDnsName`,
|
|
152
|
+
value: this.alb.loadBalancerDnsName
|
|
153
|
+
});
|
|
154
|
+
new cfnOutput_1.CfnOutput(this, "LoadBalancerUrl", {
|
|
155
|
+
key: `${id}LoadBalancerUrl`,
|
|
156
|
+
exportName: `${id}LoadBalancerUrl`,
|
|
157
|
+
value: this.url,
|
|
158
|
+
description: `Load Balancer URL for ${id}`
|
|
159
|
+
});
|
|
160
|
+
new cfnOutput_1.CfnOutput(this, "LoadBalancerArn", {
|
|
161
|
+
key: `${id}LoadBalancerArn`,
|
|
162
|
+
exportName: `${id}LoadBalancerArn`,
|
|
163
|
+
value: this.alb.loadBalancerArn,
|
|
164
|
+
description: `Load Balancer ARN for ${id}`
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Register a target group with routing rules.
|
|
169
|
+
* Called internally by EcsCluster when loadBalancer.target is specified.
|
|
170
|
+
*
|
|
171
|
+
* @param targetGroup - The target group to register
|
|
172
|
+
* @param routing - Routing configuration (path, host, priority)
|
|
173
|
+
*/
|
|
174
|
+
registerTargetGroup(targetGroup, routing) {
|
|
175
|
+
const conditions = [];
|
|
176
|
+
if (routing.path) {
|
|
177
|
+
const paths = Array.isArray(routing.path) ? routing.path : [routing.path];
|
|
178
|
+
conditions.push(aws_elasticloadbalancingv2_1.ListenerCondition.pathPatterns(paths));
|
|
179
|
+
}
|
|
180
|
+
if (routing.host) {
|
|
181
|
+
const hosts = Array.isArray(routing.host) ? routing.host : [routing.host];
|
|
182
|
+
conditions.push(aws_elasticloadbalancingv2_1.ListenerCondition.hostHeaders(hosts));
|
|
183
|
+
}
|
|
184
|
+
if (conditions.length === 0) {
|
|
185
|
+
throw new Error("At least one routing condition (path or host) must be specified.");
|
|
186
|
+
}
|
|
187
|
+
this.listener.addTargetGroups(`Rule${routing.priority}`, {
|
|
188
|
+
targetGroups: [targetGroup],
|
|
189
|
+
conditions,
|
|
190
|
+
priority: routing.priority
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Create a target group for an ECS service.
|
|
195
|
+
* Returns the target group for the service to register with.
|
|
196
|
+
*
|
|
197
|
+
* @param id - Unique identifier for the target group
|
|
198
|
+
* @param port - Container port
|
|
199
|
+
* @param vpc - VPC for the target group
|
|
200
|
+
* @param healthCheckPath - Optional health check path override
|
|
201
|
+
*/
|
|
202
|
+
createTargetGroup(id, port, vpc, healthCheckPath) {
|
|
203
|
+
const targetGroup = new aws_elasticloadbalancingv2_1.ApplicationTargetGroup(this, `${id}TargetGroup`, {
|
|
204
|
+
vpc,
|
|
205
|
+
port,
|
|
206
|
+
protocol: aws_elasticloadbalancingv2_1.ApplicationProtocol.HTTP,
|
|
207
|
+
targetType: aws_elasticloadbalancingv2_1.TargetType.IP,
|
|
208
|
+
healthCheck: {
|
|
209
|
+
path: healthCheckPath || this.defaultHealthCheck.path || "/",
|
|
210
|
+
interval: aws_cdk_lib_1.Duration.seconds(this.defaultHealthCheck.interval || 30),
|
|
211
|
+
timeout: aws_cdk_lib_1.Duration.seconds(this.defaultHealthCheck.timeout || 5),
|
|
212
|
+
healthyThresholdCount: this.defaultHealthCheck.healthyThreshold || 2,
|
|
213
|
+
unhealthyThresholdCount: this.defaultHealthCheck.unhealthyThreshold || 3
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
return targetGroup;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Allow traffic from this load balancer to a connectable resource.
|
|
220
|
+
*/
|
|
221
|
+
allowTo(connectable, port) {
|
|
222
|
+
this.connections.allowTo(connectable, port || connectable.connections.defaultPort || aws_ec2_1.Port.allTcp());
|
|
223
|
+
}
|
|
224
|
+
normaliseDomainConfig(domain) {
|
|
225
|
+
if (typeof domain === "string") {
|
|
226
|
+
return { name: domain };
|
|
227
|
+
}
|
|
228
|
+
return domain;
|
|
229
|
+
}
|
|
230
|
+
setupDomain(config) {
|
|
231
|
+
// Get or create hosted zone
|
|
232
|
+
if (config.hostedZone) {
|
|
233
|
+
this.hostedZone = config.hostedZone.getInternalHostedZone();
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
const hostedZone = new hostedZone_1.HostedZone(this, "HostedZone", {
|
|
237
|
+
zoneName: config.name
|
|
238
|
+
});
|
|
239
|
+
this.hostedZone = hostedZone.getInternalHostedZone();
|
|
240
|
+
}
|
|
241
|
+
// Get or create certificate
|
|
242
|
+
if (config.certificate) {
|
|
243
|
+
this.certificate = config.certificate;
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
this.certificate = new aws_certificatemanager_1.Certificate(this, "Certificate", {
|
|
247
|
+
domainName: config.name,
|
|
248
|
+
validation: aws_certificatemanager_1.CertificateValidation.fromDns(this.hostedZone)
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
// Create DNS record pointing to ALB
|
|
252
|
+
new aws_route53_1.ARecord(this, "AliasRecord", {
|
|
253
|
+
zone: this.hostedZone,
|
|
254
|
+
recordName: config.name,
|
|
255
|
+
target: aws_route53_1.RecordTarget.fromAlias(new aws_route53_targets_1.LoadBalancerTarget(this.alb))
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
truncateName(name, maxLength) {
|
|
259
|
+
if (name.length <= maxLength) {
|
|
260
|
+
return name;
|
|
261
|
+
}
|
|
262
|
+
return name.substring(0, maxLength).replace(/-+$/, "");
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Get the DNS name of the load balancer.
|
|
266
|
+
*/
|
|
267
|
+
getDnsName() {
|
|
268
|
+
return this.alb.loadBalancerDnsName;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Get the ARN of the load balancer.
|
|
272
|
+
*/
|
|
273
|
+
getArn() {
|
|
274
|
+
return this.alb.loadBalancerArn;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
exports.LoadBalancer = LoadBalancer;
|
|
278
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZEJhbGFuY2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vbGliL3BhdHRlcm5zL2F3cy9sb2FkQmFsYW5jZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkNBQXVDO0FBQ3ZDLHVGQVFnRDtBQUNoRCwrRUFHNEM7QUFDNUMseURBQWtGO0FBQ2xGLHlFQUFxRTtBQUNyRSxpREFPNkI7QUFDN0IsNkNBQXVDO0FBR3ZDLHVFQUFvRTtBQUNwRSw2Q0FBNkQ7QUFxRjdEOztHQUVHO0FBQ0gsU0FBUyx5QkFBeUIsQ0FBQyxLQUF5QjtJQUMxRCxJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN0QixJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsUUFBUSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzdDLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsUUFBUSxHQUFHLEdBQUcsRUFBRSxDQUFDO2dCQUN2RSxNQUFNLElBQUksS0FBSyxDQUNiLDBEQUEwRCxDQUMzRCxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzVDLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsT0FBTyxHQUFHLEdBQUcsRUFBRSxDQUFDO2dCQUNyRSxNQUFNLElBQUksS0FBSyxDQUNiLHlEQUF5RCxDQUMxRCxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F3Qkc7QUFDSCxNQUFhLG1CQUFtQjtJQUM5QixNQUFNLENBQUMsS0FBSyxDQUFDLEVBQVUsRUFBRSxLQUF5QjtRQUNoRCxPQUFPLENBQUMsR0FBUSxF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ZXNDb250ZW50IjpbImltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQge1xuICBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcixcbiAgQXBwbGljYXRpb25MaXN0ZW5lcixcbiAgQXBwbGljYXRpb25Qcm90b2NvbCxcbiAgQXBwbGljYXRpb25UYXJnZXRHcm91cCxcbiAgTGlzdGVuZXJDb25kaXRpb24sXG4gIFRhcmdldFR5cGUsXG4gIHR5cGUgSUFwcGxpY2F0aW9uVGFyZ2V0R3JvdXBcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lbGFzdGljbG9hZGJhbGFuY2luZ3YyXCI7XG5pbXBvcnQge1xuICBDZXJ0aWZpY2F0ZSxcbiAgQ2VydGlmaWNhdGVWYWxpZGF0aW9uXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2VydGlmaWNhdGVtYW5hZ2VyXCI7XG5pbXBvcnQgeyBBUmVjb3JkLCBSZWNvcmRUYXJnZXQsIHR5cGUgSUhvc3RlZFpvbmUgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXJvdXRlNTNcIjtcbmltcG9ydCB7IExvYWRCYWxhbmNlclRhcmdldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtcm91dGU1My10YXJnZXRzXCI7XG5pbXBvcnQge1xuICBDb25uZWN0aW9ucyxcbiAgdHlwZSBJQ29ubmVjdGFibGUsXG4gIHR5cGUgSVZwYyxcbiAgUG9ydCxcbiAgU2VjdXJpdHlHcm91cCxcbiAgU3VibmV0VHlwZVxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjMlwiO1xuaW1wb3J0IHsgRHVyYXRpb24gfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcblxuaW1wb3J0IHR5cGUgQXBwIGZyb20gXCIuLi8uLi9hcHBcIjtcbmltcG9ydCB7IENmbk91dHB1dCB9IGZyb20gXCIuLi8uLi9yZXNvdXJjZXMvYXdzL3V0aWxpdGllcy9jZm5PdXRwdXRcIjtcbmltcG9ydCB7IEhvc3RlZFpvbmUgYXMgRmphbGxIb3N0ZWRab25lIH0gZnJvbSBcIi4vaG9zdGVkWm9uZVwiO1xuXG4vKipcbiAqIFJvdXRpbmcgY29uZmlndXJhdGlvbiBmb3IgcmVnaXN0ZXJpbmcgc2VydmljZXMgd2l0aCB0aGUgbG9hZCBiYWxhbmNlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMb2FkQmFsYW5jZXJSb3V0aW5nQ29uZmlnIHtcbiAgLyoqXG4gICAqIFBhdGggcGF0dGVybihzKSB0byBtYXRjaC4gRXhhbXBsZXM6IFwiL2FwaS8qXCIsIFtcIi9hcGkvKlwiLCBcIi92MS8qXCJdXG4gICAqL1xuICBwYXRoPzogc3RyaW5nIHwgc3RyaW5nW107XG4gIC8qKlxuICAgKiBIb3N0IHBhdHRlcm4ocykgdG8gbWF0Y2guIEV4YW1wbGVzOiBcImFwaS5leGFtcGxlLmNvbVwiLCBbXCJhcGkuZXhhbXBsZS5jb21cIiwgXCJ3d3cuZXhhbXBsZS5jb21cIl1cbiAgICovXG4gIGhvc3Q/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIFByaW9yaXR5IGZvciB0aGlzIHJvdXRpbmcgcnVsZS4gTG93ZXIgbnVtYmVycyA9IGhpZ2hlciBwcmlvcml0eS5cbiAgICogTXVzdCBiZSB1bmlxdWUgcGVyIGxpc3RlbmVyLiBSYW5nZTogMS01MDAwMC5cbiAgICovXG4gIHByaW9yaXR5OiBudW1iZXI7XG4gIC8qKlxuICAgKiBIZWFsdGggY2hlY2sgcGF0aCBmb3IgdGhpcyB0YXJnZXQgZ3JvdXAuIERlZmF1bHQ6IFwiL1wiXG4gICAqL1xuICBoZWFsdGhDaGVja1BhdGg/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogSGVhbHRoIGNoZWNrIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBsb2FkIGJhbGFuY2VyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExvYWRCYWxhbmNlckhlYWx0aENoZWNrQ29uZmlnIHtcbiAgLyoqIEhlYWx0aCBjaGVjayBwYXRoLiBEZWZhdWx0OiBcIi9cIiAqL1xuICBwYXRoPzogc3RyaW5nO1xuICAvKiogSW50ZXJ2YWwgYmV0d2VlbiBoZWFsdGggY2hlY2tzIGluIHNlY29uZHMuIERlZmF1bHQ6IDMwICovXG4gIGludGVydmFsPzogbnVtYmVyO1xuICAvKiogSGVhbHRoIGNoZWNrIHRpbWVvdXQgaW4gc2Vjb25kcy4gRGVmYXVsdDogNSAqL1xuICB0aW1lb3V0PzogbnVtYmVyO1xuICAvKiogTnVtYmVyIG9mIGNvbnNlY3V0aXZlIHN1Y2Nlc3NlcyBiZWZvcmUgaGVhbHRoeS4gRGVmYXVsdDogMiAqL1xuICBoZWFsdGh5VGhyZXNob2xkPzogbnVtYmVyO1xuICAvKiogTnVtYmVyIG9mIGNvbnNlY3V0aXZlIGZhaWx1cmVzIGJlZm9yZSB1bmhlYWx0aHkuIERlZmF1bHQ6IDMgKi9cbiAgdW5oZWFsdGh5VGhyZXNob2xkPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIERvbWFpbiBjb25maWd1cmF0aW9uIGZvciBIVFRQUyBhbmQgRE5TLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExvYWRCYWxhbmNlckRvbWFpbkNvbmZpZyB7XG4gIC8qKiBEb21haW4gbmFtZSAoZS5nLiwgXCJhcGkuZXhhbXBsZS5jb21cIikgKi9cbiAgbmFtZTogc3RyaW5nO1xuICAvKiogRXhpc3RpbmcgaG9zdGVkIHpvbmUuIElmIG9taXR0ZWQsIGNyZWF0ZXMgbmV3IG9uZS4gKi9cbiAgaG9zdGVkWm9uZT86IEZqYWxsSG9zdGVkWm9uZTtcbiAgLyoqIEV4aXN0aW5nIGNlcnRpZmljYXRlLiBJZiBvbWl0dGVkLCBjcmVhdGVzIG5ldyBvbmUgd2l0aCBETlMgdmFsaWRhdGlvbi4gKi9cbiAgY2VydGlmaWNhdGU/OiBDZXJ0aWZpY2F0ZTtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBMb2FkQmFsYW5jZXJGYWN0b3J5LmJ1aWxkKClcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJTG9hZEJhbGFuY2VyUHJvcHMge1xuICAvKiogVlBDIHRvIHBsYWNlIHRoZSBsb2FkIGJhbGFuY2VyIGluLiBEZWZhdWx0OiBhcHAncyBkZWZhdWx0IFZQQyAqL1xuICB2cGM/OiBJVnBjO1xuICAvKipcbiAgICogRG9tYWluIGNvbmZpZ3VyYXRpb24gZm9yIEhUVFBTLlxuICAgKiAtIHN0cmluZzogRG9tYWluIG5hbWUgKGNyZWF0ZXMgaG9zdGVkIHpvbmUgYW5kIGNlcnRpZmljYXRlKVxuICAgKiAtIExvYWRCYWxhbmNlckRvbWFpbkNvbmZpZzogRnVsbCBjb25maWd1cmF0aW9uXG4gICAqIC0gT21pdDogSFRUUCBvbmx5XG4gICAqL1xuICBkb21haW4/OiBzdHJpbmcgfCBMb2FkQmFsYW5jZXJEb21haW5Db25maWc7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBsb2FkIGJhbGFuY2VyIGlzIGludGVybmV0LWZhY2luZy5cbiAgICogRGVmYXVsdDogdHJ1ZVxuICAgKi9cbiAgcHVibGljPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIERlZmF1bHQgaGVhbHRoIGNoZWNrIGNvbmZpZ3VyYXRpb24uXG4gICAqIEluZGl2aWR1YWwgc2VydmljZXMgY2FuIG92ZXJyaWRlIHRoaXMuXG4gICAqL1xuICBoZWFsdGhDaGVjaz86IExvYWRCYWxhbmNlckhlYWx0aENoZWNrQ29uZmlnO1xufVxuXG4vKipcbiAqIEludGVybmFsIHByb3BzIHdpdGggcmVzb2x2ZWQgVlBDLlxuICovXG5pbnRlcmZhY2UgTG9hZEJhbGFuY2VyUHJvcHNSZXNvbHZlZCBleHRlbmRzIElMb2FkQmFsYW5jZXJQcm9wcyB7XG4gIHZwYzogSVZwYztcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgbG9hZCBiYWxhbmNlciBwcm9wcyBhbmQgbG9ncyB3YXJuaW5ncyBmb3IgbWlzY29uZmlndXJlZCBvcHRpb25zLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUxvYWRCYWxhbmNlclByb3BzKHByb3BzOiBJTG9hZEJhbGFuY2VyUHJvcHMpOiB2b2lkIHtcbiAgaWYgKHByb3BzLmhlYWx0aENoZWNrKSB7XG4gICAgaWYgKHByb3BzLmhlYWx0aENoZWNrLmludGVydmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChwcm9wcy5oZWFsdGhDaGVjay5pbnRlcnZhbCA8IDUgfHwgcHJvcHMuaGVhbHRoQ2hlY2suaW50ZXJ2YWwgPiAzMDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiSGVhbHRoIGNoZWNrIGludGVydmFsIG11c3QgYmUgYmV0d2VlbiA1IGFuZCAzMDAgc2Vjb25kcy5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAocHJvcHMuaGVhbHRoQ2hlY2sudGltZW91dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAocHJvcHMuaGVhbHRoQ2hlY2sudGltZW91dCA8IDIgfHwgcHJvcHMuaGVhbHRoQ2hlY2sudGltZW91dCA+IDEyMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgXCJIZWFsdGggY2hlY2sgdGltZW91dCBtdXN0IGJlIGJldHdlZW4gMiBhbmQgMTIwIHNlY29uZHMuXCJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBGYWN0b3J5IGZvciBjcmVhdGluZyBMb2FkQmFsYW5jZXIgY29uc3RydWN0cy5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gU2ltcGxlIEhUVFAgbG9hZCBiYWxhbmNlclxuICogY29uc3QgYWxiID0gYXBwLmFkZENvbXB1dGUoXG4gKiAgIExvYWRCYWxhbmNlckZhY3RvcnkuYnVpbGQoXCJNYWluQUxCXCIsIHt9KVxuICogKTtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSFRUUFMgbG9hZCBiYWxhbmNlciB3aXRoIGRvbWFpblxuICogY29uc3QgYWxiID0gYXBwLmFkZENvbXB1dGUoXG4gKiAgIExvYWRCYWxhbmNlckZhY3RvcnkuYnVpbGQoXCJNYWluQUxCXCIsIHtcbiAqICAgICBkb21haW46IFwiYXBwLmV4YW1wbGUuY29tXCJcbiAqICAgfSlcbiAqICk7XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEludGVybmFsIGxvYWQgYmFsYW5jZXJcbiAqIGNvbnN0IGFsYiA9IGFwcC5hZGRDb21wdXRlKFxuICogICBMb2FkQmFsYW5jZXJGYWN0b3J5LmJ1aWxkKFwiSW50ZXJuYWxBTEJcIiwge1xuICogICAgIHB1YmxpYzogZmFsc2VcbiAqICAgfSlcbiAqICk7XG4gKi9cbmV4cG9ydCBjbGFzcyBMb2FkQmFsYW5jZXJGYWN0b3J5IHtcbiAgc3RhdGljIGJ1aWxkKGlkOiBzdHJpbmcsIHByb3BzOiBJTG9hZEJhbGFuY2VyUHJvcHMpIHtcbiAgICByZXR1cm4gKGFwcDogQXBwLCBzY29wZTogQ29uc3RydWN0KTogTG9hZEJhbGFuY2VyID0+IHtcbiAgICAgIHZhbGlkYXRlTG9hZEJhbGFuY2VyUHJvcHMocHJvcHMpO1xuXG4gICAgICBjb25zdCByZXNvbHZlZFByb3BzOiBMb2FkQmFsYW5jZXJQcm9wc1Jlc29sdmVkID0ge1xuICAgICAgICAuLi5wcm9wcyxcbiAgICAgICAgdnBjOiBwcm9wcy52cGMgfHwgYXBwLmdldFZwYygpXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gbmV3IExvYWRCYWxhbmNlcihzY29wZSwgaWQsIHJlc29sdmVkUHJvcHMpO1xuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyIGNvbnN0cnVjdCB0aGF0IGNhbiBiZSBzaGFyZWQgYWNyb3NzIG11bHRpcGxlIEVDUyBzZXJ2aWNlcy5cbiAqXG4gKiBVc2UgTG9hZEJhbGFuY2VyRmFjdG9yeS5idWlsZCgpIHRvIGNyZWF0ZSBpbnN0YW5jZXMgdmlhIGFwcC5hZGRDb21wdXRlKCkuXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2FkQmFsYW5jZXIgZXh0ZW5kcyBDb25zdHJ1Y3QgaW1wbGVtZW50cyBJQ29ubmVjdGFibGUge1xuICBwdWJsaWMgcmVhZG9ubHkgYWxiOiBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcjtcbiAgcHVibGljIHJlYWRvbmx5IGxpc3RlbmVyOiBBcHBsaWNhdGlvbkxpc3RlbmVyO1xuICBwdWJsaWMgcmVhZG9ubHkgc2VjdXJpdHlHcm91cDogU2VjdXJpdHlHcm91cDtcbiAgcHVibGljIHJlYWRvbmx5IHVybDogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgY29ubmVjdGlvbnM6IENvbm5lY3Rpb25zO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgaG9zdGVkWm9uZT86IElIb3N0ZWRab25lO1xuICBwcml2YXRlIHJlYWRvbmx5IGNlcnRpZmljYXRlPzogQ2VydGlmaWNhdGU7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVmYXVsdEhlYWx0aENoZWNrOiBMb2FkQmFsYW5jZXJIZWFsdGhDaGVja0NvbmZpZztcbiAgcHJpdmF0ZSByZWFkb25seSBpc0h0dHBzOiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBMb2FkQmFsYW5jZXJQcm9wc1Jlc29sdmVkKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIHRoaXMuZGVmYXVsdEhlYWx0aENoZWNrID0gcHJvcHMuaGVhbHRoQ2hlY2sgfHwge307XG4gICAgdGhpcy5pc0h0dHBzID0gISFwcm9wcy5kb21haW47XG5cbiAgICAvLyBDcmVhdGUgc2VjdXJpdHkgZ3JvdXBcbiAgICB0aGlzLnNlY3VyaXR5R3JvdXAgPSBuZXcgU2VjdXJpdHlHcm91cCh0aGlzLCBcIlNlY3VyaXR5R3JvdXBcIiwge1xuICAgICAgdnBjOiBwcm9wcy52cGMsXG4gICAgICBkZXNjcmlwdGlvbjogYFNlY3VyaXR5IGdyb3VwIGZvciAke2lkfSBsb2FkIGJhbGFuY2VyYCxcbiAgICAgIGFsbG93QWxsT3V0Ym91bmQ6IHRydWVcbiAgICB9KTtcblxuICAgIC8vIEFsbG93IGluYm91bmQgdHJhZmZpY1xuICAgIGNvbnN0IGluYm91bmRQb3J0ID0gdGhpcy5pc0h0dHBzID8gNDQzIDogODA7XG4gICAgdGhpcy5zZWN1cml0eUdyb3VwLmFkZEluZ3Jlc3NSdWxlKFxuICAgICAgeyBjb25uZWN0aW9uczogeyBhbGxvd0Zyb21BbnlJcHY0OiAoKSA9PiB7fSB9IH0gYXMgYW55LFxuICAgICAgUG9ydC50Y3AoaW5ib3VuZFBvcnQpLFxuICAgICAgYEFsbG93IGluYm91bmQgJHt0aGlzLmlzSHR0cHMgPyBcIkhUVFBTXCIgOiBcIkhUVFBcIn1gXG4gICAgKTtcblxuICAgIC8vIENyZWF0ZSBBTEJcbiAgICBjb25zdCBsb2FkQmFsYW5jZXJOYW1lID0gdGhpcy50cnVuY2F0ZU5hbWUoYCR7aWR9QUxCYCwgMzIpO1xuICAgIHRoaXMuYWxiID0gbmV3IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyKHRoaXMsIFwiQUxCXCIsIHtcbiAgICAgIHZwYzogcHJvcHMudnBjLFxuICAgICAgaW50ZXJuZXRGYWNpbmc6IHByb3BzLnB1YmxpYyAhPT0gZmFsc2UsXG4gICAgICBzZWN1cml0eUdyb3VwOiB0aGlzLnNlY3VyaXR5R3JvdXAsXG4gICAgICBsb2FkQmFsYW5jZXJOYW1lLFxuICAgICAgdnBjU3VibmV0czoge1xuICAgICAgICBzdWJuZXRUeXBlOlxuICAgICAgICAgIHByb3BzLnB1YmxpYyAhPT0gZmFsc2UgPyBTdWJuZXRUeXBlLlBVQkxJQyA6IFN1Ym5ldFR5cGUuUFJJVkFURV9XSVRIX0VHUkVTU1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gU2V0IHVwIGRvbWFpbiBpZiBjb25maWd1cmVkXG4gICAgaWYgKHByb3BzLmRvbWFpbikge1xuICAgICAgY29uc3QgZG9tYWluQ29uZmlnID0gdGhpcy5ub3JtYWxpc2VEb21haW5Db25maWcocHJvcHMuZG9tYWluKTtcbiAgICAgIHRoaXMuc2V0dXBEb21haW4oZG9tYWluQ29uZmlnKTtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgbGlzdGVuZXJcbiAgICBpZiAodGhpcy5pc0h0dHBzICYmIHRoaXMuY2VydGlmaWNhdGUpIHtcbiAgICAgIHRoaXMubGlzdGVuZXIgPSB0aGlzLmFsYi5hZGRMaXN0ZW5lcihcIkxpc3RlbmVyXCIsIHtcbiAgICAgICAgcG9ydDogNDQzLFxuICAgICAgICBwcm90b2NvbDogQXBwbGljYXRpb25Qcm90b2NvbC5IVFRQUyxcbiAgICAgICAgY2VydGlmaWNhdGVzOiBbdGhpcy5jZXJ0aWZpY2F0ZV1cbiAgICAgIH0pO1xuXG4gICAgICAvLyBBZGQgSFRUUCByZWRpcmVjdFxuICAgICAgdGhpcy5hbGIuYWRkTGlzdGVuZXIoXCJIdHRwUmVkaXJlY3RcIiwge1xuICAgICAgICBwb3J0OiA4MCxcbiAgICAgICAgcHJvdG9jb2w6IEFwcGxpY2F0aW9uUHJvdG9jb2wuSFRUUCxcbiAgICAgICAgZGVmYXVsdEFjdGlvbjoge1xuICAgICAgICAgIHJlZGlyZWN0OiB7XG4gICAgICAgICAgICBwcm90b2NvbDogXCJIVFRQU1wiLFxuICAgICAgICAgICAgcG9ydDogXCI0NDNcIixcbiAgICAgICAgICAgIHBlcm1hbmVudDogdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfSBhcyBhbnlcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxpc3RlbmVyID0gdGhpcy5hbGIuYWRkTGlzdGVuZXIoXCJMaXN0ZW5lclwiLCB7XG4gICAgICAgIHBvcnQ6IDgwLFxuICAgICAgICBwcm90b2NvbDogQXBwbGljYXRpb25Qcm90b2NvbC5IVFRQXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBBZGQgZGVmYXVsdCBhY3Rpb24gKHJldHVybnMgNTAzIGlmIG5vIHRhcmdldHMgbWF0Y2gpXG4gICAgdGhpcy5saXN0ZW5lci5hZGRBY3Rpb24oXCJEZWZhdWx0QWN0aW9uXCIsIHtcbiAgICAgIGFjdGlvbjoge1xuICAgICAgICBmaXhlZFJlc3BvbnNlOiB7XG4gICAgICAgICAgc3RhdHVzQ29kZTogNTAzLFxuICAgICAgICAgIGNvbnRlbnRUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgICAgICBtZXNzYWdlQm9keTogXCJObyBzZXJ2aWNlIGF2YWlsYWJsZVwiXG4gICAgICAgIH1cbiAgICAgIH0gYXMgYW55XG4gICAgfSk7XG5cbiAgICAvLyBTZXQgVVJMXG4gICAgdGhpcy51cmwgPSB0aGlzLmlzSHR0cHNcbiAgICAgID8gYGh0dHBzOi8vJHt0aGlzLmFsYi5sb2FkQmFsYW5jZXJEbnNOYW1lfWBcbiAgICAgIDogYGh0dHA6Ly8ke3RoaXMuYWxiLmxvYWRCYWxhbmNlckRuc05hbWV9YDtcblxuICAgIC8vIFNldCB1cCBjb25uZWN0aW9uc1xuICAgIHRoaXMuY29ubmVjdGlvbnMgPSBuZXcgQ29ubmVjdGlvbnMoe1xuICAgICAgc2VjdXJpdHlHcm91cHM6IFt0aGlzLnNlY3VyaXR5R3JvdXBdLFxuICAgICAgZGVmYXVsdFBvcnQ6IFBvcnQudGNwKGluYm91bmRQb3J0KVxuICAgIH0pO1xuXG4gICAgLy8gT3V0cHV0c1xuICAgIG5ldyBDZm5PdXRwdXQodGhpcywgXCJMb2FkQmFsYW5jZXJEbnNOYW1lXCIsIHtcbiAgICAgIGtleTogYCR7aWR9TG9hZEJhbGFuY2VyRG5zTmFtZWAsXG4gICAgICBleHBvcnROYW1lOiBgJHtpZH1Mb2FkQmFsYW5jZXJEbnNOYW1lYCxcbiAgICAgIHZhbHVlOiB0aGlzLmFsYi5sb2FkQmFsYW5jZXJEbnNOYW1lXG4gICAgfSk7XG5cbiAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsIFwiTG9hZEJhbGFuY2VyVXJsXCIsIHtcbiAgICAgIGtleTogYCR7aWR9TG9hZEJhbGFuY2VyVXJsYCxcbiAgICAgIGV4cG9ydE5hbWU6IGAke2lkfUxvYWRCYWxhbmNlclVybGAsXG4gICAgICB2YWx1ZTogdGhpcy51cmwsXG4gICAgICBkZXNjcmlwdGlvbjogYExvYWQgQmFsYW5jZXIgVVJMIGZvciAke2lkfWBcbiAgICB9KTtcblxuICAgIG5ldyBDZm5PdXRwdXQodGhpcywgXCJMb2FkQmFsYW5jZXJBcm5cIiwge1xuICAgICAga2V5OiBgJHtpZH1Mb2FkQmFsYW5jZXJBcm5gLFxuICAgICAgZXhwb3J0TmFtZTogYCR7aWR9TG9hZEJhbGFuY2VyQXJuYCxcbiAgICAgIHZhbHVlOiB0aGlzLmFsYi5sb2FkQmFsYW5jZXJBcm4sXG4gICAgICBkZXNjcmlwdGlvbjogYExvYWQgQmFsYW5jZXIgQVJOIGZvciAke2lkfWBcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBhIHRhcmdldCBncm91cCB3aXRoIHJvdXRpbmcgcnVsZXMuXG4gICAqIENhbGxlZCBpbnRlcm5hbGx5IGJ5IEVjc0NsdXN0ZXIgd2hlbiBsb2FkQmFsYW5jZXIudGFyZ2V0IGlzIHNwZWNpZmllZC5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldEdyb3VwIC0gVGhlIHRhcmdldCBncm91cCB0byByZWdpc3RlclxuICAgKiBAcGFyYW0gcm91dGluZyAtIFJvdXRpbmcgY29uZmlndXJhdGlvbiAocGF0aCwgaG9zdCwgcHJpb3JpdHkpXG4gICAqL1xuICBwdWJsaWMgcmVnaXN0ZXJUYXJnZXRHcm91cChcbiAgICB0YXJnZXRHcm91cDogSUFwcGxpY2F0aW9uVGFyZ2V0R3JvdXAsXG4gICAgcm91dGluZzogTG9hZEJhbGFuY2VyUm91dGluZ0NvbmZpZ1xuICApOiB2b2lkIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBMaXN0ZW5lckNvbmRpdGlvbltdID0gW107XG5cbiAgICBpZiAocm91dGluZy5wYXRoKSB7XG4gICAgICBjb25zdCBwYXRocyA9IEFycmF5LmlzQXJyYXkocm91dGluZy5wYXRoKSA/IHJvdXRpbmcucGF0aCA6IFtyb3V0aW5nLnBhdGhdO1xuICAgICAgY29uZGl0aW9ucy5wdXNoKExpc3RlbmVyQ29uZGl0aW9uLnBhdGhQYXR0ZXJucyhwYXRocykpO1xuICAgIH1cblxuICAgIGlmIChyb3V0aW5nLmhvc3QpIHtcbiAgICAgIGNvbnN0IGhvc3RzID0gQXJyYXkuaXNBcnJheShyb3V0aW5nLmhvc3QpID8gcm91dGluZy5ob3N0IDogW3JvdXRpbmcuaG9zdF07XG4gICAgICBjb25kaXRpb25zLnB1c2goTGlzdGVuZXJDb25kaXRpb24uaG9zdEhlYWRlcnMoaG9zdHMpKTtcbiAgICB9XG5cbiAgICBpZiAoY29uZGl0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJBdCBsZWFzdCBvbmUgcm91dGluZyBjb25kaXRpb24gKHBhdGggb3IgaG9zdCkgbXVzdCBiZSBzcGVjaWZpZWQuXCJcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5saXN0ZW5lci5hZGRUYXJnZXRHcm91cHMoYFJ1bGUke3JvdXRpbmcucHJpb3JpdHl9YCwge1xuICAgICAgdGFyZ2V0R3JvdXBzOiBbdGFyZ2V0R3JvdXBdLFxuICAgICAgY29uZGl0aW9ucyxcbiAgICAgIHByaW9yaXR5OiByb3V0aW5nLnByaW9yaXR5XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgdGFyZ2V0IGdyb3VwIGZvciBhbiBFQ1Mgc2VydmljZS5cbiAgICogUmV0dXJucyB0aGUgdGFyZ2V0IGdyb3VwIGZvciB0aGUgc2VydmljZSB0byByZWdpc3RlciB3aXRoLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgLSBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIHRhcmdldCBncm91cFxuICAgKiBAcGFyYW0gcG9ydCAtIENvbnRhaW5lciBwb3J0XG4gICAqIEBwYXJhbSB2cGMgLSBWUEMgZm9yIHRoZSB0YXJnZXQgZ3JvdXBcbiAgICogQHBhcmFtIGhlYWx0aENoZWNrUGF0aCAtIE9wdGlvbmFsIGhlYWx0aCBjaGVjayBwYXRoIG92ZXJyaWRlXG4gICAqL1xuICBwdWJsaWMgY3JlYXRlVGFyZ2V0R3JvdXAoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwb3J0OiBudW1iZXIsXG4gICAgdnBjOiBJVnBjLFxuICAgIGhlYWx0aENoZWNrUGF0aD86IHN0cmluZ1xuICApOiBBcHBsaWNhdGlvblRhcmdldEdyb3VwIHtcbiAgICBjb25zdCB0YXJnZXRHcm91cCA9IG5ldyBBcHBsaWNhdGlvblRhcmdldEdyb3VwKHRoaXMsIGAke2lkfVRhcmdldEdyb3VwYCwge1xuICAgICAgdnBjLFxuICAgICAgcG9ydCxcbiAgICAgIHByb3RvY29sOiBBcHBsaWNhdGlvblByb3RvY29sLkhUVFAsXG4gICAgICB0YXJnZXRUeXBlOiBUYXJnZXRUeXBlLklQLFxuICAgICAgaGVhbHRoQ2hlY2s6IHtcbiAgICAgICAgcGF0aDogaGVhbHRoQ2hlY2tQYXRoIHx8IHRoaXMuZGVmYXVsdEhlYWx0aENoZWNrLnBhdGggfHwgXCIvXCIsXG4gICAgICAgIGludGVydmFsOiBEdXJhdGlvbi5zZWNvbmRzKFxuICAgICAgICAgIHRoaXMuZGVmYXVsdEhlYWx0aENoZWNrLmludGVydmFsIHx8IDMwXG4gICAgICAgICksXG4gICAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoXG4gICAgICAgICAgdGhpcy5kZWZhdWx0SGVhbHRoQ2hlY2sudGltZW91dCB8fCA1XG4gICAgICAgICksXG4gICAgICAgIGhlYWx0aHlUaHJlc2hvbGRDb3VudDogdGhpcy5kZWZhdWx0SGVhbHRoQ2hlY2suaGVhbHRoeVRocmVzaG9sZCB8fCAyLFxuICAgICAgICB1bmhlYWx0aHlUaHJlc2hvbGRDb3VudDogdGhpcy5kZWZhdWx0SGVhbHRoQ2hlY2sudW5oZWFsdGh5VGhyZXNob2xkIHx8IDNcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiB0YXJnZXRHcm91cDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbGxvdyB0cmFmZmljIGZyb20gdGhpcyBsb2FkIGJhbGFuY2VyIHRvIGEgY29ubmVjdGFibGUgcmVzb3VyY2UuXG4gICAqL1xuICBwdWJsaWMgYWxsb3dUbyhjb25uZWN0YWJsZTogSUNvbm5lY3RhYmxlLCBwb3J0PzogUG9ydCk6IHZvaWQge1xuICAgIHRoaXMuY29ubmVjdGlvbnMuYWxsb3dUbyhcbiAgICAgIGNvbm5lY3RhYmxlLFxuICAgICAgcG9ydCB8fCBjb25uZWN0YWJsZS5jb25uZWN0aW9ucy5kZWZhdWx0UG9ydCB8fCBQb3J0LmFsbFRjcCgpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgbm9ybWFsaXNlRG9tYWluQ29uZmlnKFxuICAgIGRvbWFpbjogc3RyaW5nIHwgTG9hZEJhbGFuY2VyRG9tYWluQ29uZmlnXG4gICk6IExvYWRCYWxhbmNlckRvbWFpbkNvbmZpZyB7XG4gICAgaWYgKHR5cGVvZiBkb21haW4gPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiB7IG5hbWU6IGRvbWFpbiB9O1xuICAgIH1cbiAgICByZXR1cm4gZG9tYWluO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cERvbWFpbihjb25maWc6IExvYWRCYWxhbmNlckRvbWFpbkNvbmZpZyk6IHZvaWQge1xuICAgIC8vIEdldCBvciBjcmVhdGUgaG9zdGVkIHpvbmVcbiAgICBpZiAoY29uZmlnLmhvc3RlZFpvbmUpIHtcbiAgICAgICh0aGlzIGFzIGFueSkuaG9zdGVkWm9uZSA9IGNvbmZpZy5ob3N0ZWRab25lLmdldEludGVybmFsSG9zdGVkWm9uZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBob3N0ZWRab25lID0gbmV3IEZqYWxsSG9zdGVkWm9uZSh0aGlzLCBcIkhvc3RlZFpvbmVcIiwge1xuICAgICAgICB6b25lTmFtZTogY29uZmlnLm5hbWVcbiAgICAgIH0pO1xuICAgICAgKHRoaXMgYXMgYW55KS5ob3N0ZWRab25lID0gaG9zdGVkWm9uZS5nZXRJbnRlcm5hbEhvc3RlZFpvbmUoKTtcbiAgICB9XG5cbiAgICAvLyBHZXQgb3IgY3JlYXRlIGNlcnRpZmljYXRlXG4gICAgaWYgKGNvbmZpZy5jZXJ0aWZpY2F0ZSkge1xuICAgICAgKHRoaXMgYXMgYW55KS5jZXJ0aWZpY2F0ZSA9IGNvbmZpZy5jZXJ0aWZpY2F0ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgKHRoaXMgYXMgYW55KS5jZXJ0aWZpY2F0ZSA9IG5ldyBDZXJ0aWZpY2F0ZSh0aGlzLCBcIkNlcnRpZmljYXRlXCIsIHtcbiAgICAgICAgZG9tYWluTmFtZTogY29uZmlnLm5hbWUsXG4gICAgICAgIHZhbGlkYXRpb246IENlcnRpZmljYXRlVmFsaWRhdGlvbi5mcm9tRG5zKHRoaXMuaG9zdGVkWm9uZSlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBETlMgcmVjb3JkIHBvaW50aW5nIHRvIEFMQlxuICAgIG5ldyBBUmVjb3JkKHRoaXMsIFwiQWxpYXNSZWNvcmRcIiwge1xuICAgICAgem9uZTogdGhpcy5ob3N0ZWRab25lISxcbiAgICAgIHJlY29yZE5hbWU6IGNvbmZpZy5uYW1lLFxuICAgICAgdGFyZ2V0OiBSZWNvcmRUYXJnZXQuZnJvbUFsaWFzKG5ldyBMb2FkQmFsYW5jZXJUYXJnZXQodGhpcy5hbGIpKVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB0cnVuY2F0ZU5hbWUobmFtZTogc3RyaW5nLCBtYXhMZW5ndGg6IG51bWJlcik6IHN0cmluZyB7XG4gICAgaWYgKG5hbWUubGVuZ3RoIDw9IG1heExlbmd0aCkge1xuICAgICAgcmV0dXJuIG5hbWU7XG4gICAgfVxuICAgIHJldHVybiBuYW1lLnN1YnN0cmluZygwLCBtYXhMZW5ndGgpLnJlcGxhY2UoLy0rJC8sIFwiXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgRE5TIG5hbWUgb2YgdGhlIGxvYWQgYmFsYW5jZXIuXG4gICAqL1xuICBwdWJsaWMgZ2V0RG5zTmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmFsYi5sb2FkQmFsYW5jZXJEbnNOYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgQVJOIG9mIHRoZSBsb2FkIGJhbGFuY2VyLlxuICAgKi9cbiAgcHVibGljIGdldEFybigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmFsYi5sb2FkQmFsYW5jZXJBcm47XG4gIH1cbn1cbiJdfQ==
|
|
@@ -53,6 +53,7 @@ export interface TransitGatewayConfig {
|
|
|
53
53
|
* { maxAzs: 3, natGateways: { count: 3 }, vpcEndpoints: { interface: { ecr: true } } }
|
|
54
54
|
*/
|
|
55
55
|
export interface INetworkProps {
|
|
56
|
+
vpcName?: string;
|
|
56
57
|
maxAzs?: number;
|
|
57
58
|
cidrMask?: number;
|
|
58
59
|
natGateways?: NatConfig | false;
|
|
@@ -44,6 +44,7 @@ class Network extends constructs_1.Construct {
|
|
|
44
44
|
ipv4IpamPoolId = aws_cdk_lib_1.Fn.importValue(`IpamPoolId${accountId}${regionSuffix}`);
|
|
45
45
|
}
|
|
46
46
|
const vpcProps = {
|
|
47
|
+
vpcName: props.vpcName,
|
|
47
48
|
accountId,
|
|
48
49
|
region,
|
|
49
50
|
ipv4IpamPoolId,
|
|
@@ -96,4 +97,4 @@ class Network extends constructs_1.Construct {
|
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
exports.Network = Network;
|
|
99
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29yay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9wYXR0ZXJucy9hd3MvbmV0d29yay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQ0FBdUM7QUFDdkMsNkNBQWlDO0FBSWpDLDREQUF3RTtBQXNFeEUsU0FBUyxvQkFBb0IsQ0FBQyxLQUFvQjtJQUNoRCxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3pFLE9BQU8sQ0FBQyxJQUFJLENBQ1YsNkRBQTZELEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FDN0UsQ0FBQztJQUNKLENBQUM7SUFFRCxJQUNFLE9BQU8sS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRO1FBQ3JDLEtBQUssQ0FBQyxXQUFXLEtBQUssSUFBSTtRQUMxQixLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQ3JDLENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQztRQUNqQyxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxHQUFHLE1BQU0sRUFBRSxDQUFDO1lBQ3JDLE9BQU8sQ0FBQyxJQUFJLENBQ1YseUNBQXlDLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxxQkFBcUIsTUFBTSxJQUFJLENBQ2hHLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLGNBQWMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDckQsTUFBTSxJQUFJLEtBQUssQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7QUFDSCxDQUFDO0FBRUQsTUFBYSxjQUFjO0lBQ3pCLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFB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QUFLLENBQUM7UUFFbkMscUNBQXFDO1FBQ3JDLElBQUksTUFBTSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3pCLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQ25ELENBQUM7UUFFRCxPQUFPO1lBQ0wsT0FBTyxFQUNMLE1BQU0sQ0FBQyxPQUFPLEtBQUssS0FBSztnQkFDdEIsQ0FBQyxDQUFDLEtBQUs7Z0JBQ1AsQ0FBQyxDQUFDO29CQUNFLEVBQUUsRUFBRSxNQUFNLENBQUMsT0FBTyxFQUFFLEVBQUUsSUFBSSxJQUFJO29CQUM5QixRQUFRLEVBQUUsTUFBTSxDQUFDLE9BQU8sRUFBRSxRQUFRLElBQUksSUFBSTtpQkFDM0M7WUFDUCxTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVM7U0FDakUsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNO1FBQ0osT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQ2xCLENBQUM7Q0FDRjtBQXJHRCwwQkFxR0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHsgRm4gfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7IHR5cGUgSVZwYyB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZWMyXCI7XG5cbmltcG9ydCB0eXBlIEFwcCBmcm9tIFwiLi4vLi4vYXBwXCI7XG5pbXBvcnQgeyBWcGMsIHR5cGUgVnBjUHJvcHMgfSBmcm9tIFwiLi4vLi4vcmVzb3VyY2VzL2F3cy9uZXR3b3JraW5nL3ZwY1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIE5hdENvbmZpZyB7XG4gIGNvdW50PzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZsb3dMb2dDb25maWcge1xuICBkZXN0aW5hdGlvbj86IFwiY2xvdWR3YXRjaFwiIHwgXCJzM1wiO1xuICByZXRlbnRpb25EYXlzPzogbnVtYmVyO1xuICB0cmFmZmljVHlwZT86IFwiQUxMXCIgfCBcIkFDQ0VQVFwiIHwgXCJSRUpFQ1RcIjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHYXRld2F5RW5kcG9pbnRzQ29uZmlnIHtcbiAgczM/OiBib29sZWFuO1xuICBkeW5hbW9kYj86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW50ZXJmYWNlRW5kcG9pbnRzQ29uZmlnIHtcbiAgZWNyPzogYm9vbGVhbjtcbiAgc2VjcmV0c01hbmFnZXI/OiBib29sZWFuO1xuICBrbXM/OiBib29sZWFuO1xuICBjbG91ZHdhdGNoTG9ncz86IGJvb2xlYW47XG4gIHNzbT86IGJvb2xlYW47XG4gIHN0cz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVnBjRW5kcG9pbnRzQ29uZmlnIHtcbiAgZ2F0ZXdheT86IEdhdGV3YXlFbmRwb2ludHNDb25maWcgfCBmYWxzZTtcbiAgaW50ZXJmYWNlPzogSW50ZXJmYWNlRW5kcG9pbnRzQ29uZmlnIHwgZmFsc2U7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3VibmV0Q29uZmlnIHtcbiAgY2lkck1hc2s/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3VibmV0c0NvbmZpZyB7XG4gIHB1YmxpYz86IFN1Ym5ldENvbmZpZztcbiAgcHJpdmF0ZT86IFN1Ym5ldENvbmZpZztcbiAgaXNvbGF0ZWQ/OiBTdWJuZXRDb25maWcgfCBmYWxzZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2l0R2F0ZXdheUNvbmZpZyB7XG4gIGlkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogTmV0d29yayAoVlBDKSBjb25maWd1cmF0aW9uLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBNaW5pbWFsIGNvc3QgVlBDIChubyBOQVQsIGdhdGV3YXkgZW5kcG9pbnRzIG9ubHkpXG4gKiB7IG5hdEdhdGV3YXlzOiBmYWxzZSB9XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFByb2R1Y3Rpb24gVlBDIHdpdGggMSBOQVQgZ2F0ZXdheVxuICogeyBuYXRHYXRld2F5czogeyBjb3VudDogMSB9LCBmbG93TG9nczoge30gfVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBIaWdoLWF2YWlsYWJpbGl0eSBWUEMgd2l0aCBpbnRlcmZhY2UgZW5kcG9pbnRzXG4gKiB7IG1heEF6czogMywgbmF0R2F0ZXdheXM6IHsgY291bnQ6IDMgfSwgdnBjRW5kcG9pbnRzOiB7IGludGVyZmFjZTogeyBlY3I6IHRydWUgfSB9IH1cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJTmV0d29ya1Byb3BzIHtcbiAgbWF4QXpzPzogbnVtYmVyO1xuICBjaWRyTWFzaz86IG51bWJlcjtcbiAgbmF0R2F0ZXdheXM/OiBOYXRDb25maWcgfCBmYWxzZTtcbiAgZmxvd0xvZ3M/OiBGbG93TG9nQ29uZmlnIHwgZmFsc2U7XG4gIHZwY0VuZHBvaW50cz86IFZwY0VuZHBvaW50c0NvbmZpZyB8IGZhbHNlO1xuICBzdWJuZXRzPzogU3VibmV0c0NvbmZpZztcbiAgdHJhbnNpdEdhdGV3YXk/OiBUcmFuc2l0R2F0ZXdheUNvbmZpZztcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVOZXR3b3JrUHJvcHMocHJvcHM6IElOZXR3b3JrUHJvcHMpOiB2b2lkIHtcbiAgaWYgKHByb3BzLm1heEF6cyAhPT0gdW5kZWZpbmVkICYmIChwcm9wcy5tYXhBenMgPCAxIHx8IHByb3BzLm1heEF6cyA+IDMpKSB7XG4gICAgY29uc29sZS53YXJuKFxuICAgICAgYFtGamFsbF0gV2FybmluZzogJ21heEF6cycgc2hvdWxkIGJlIGJldHdlZW4gMSBhbmQgMy4gR290OiAke3Byb3BzLm1heEF6c30uYFxuICAgICk7XG4gIH1cblxuICBpZiAoXG4gICAgdHlwZW9mIHByb3BzLm5hdEdhdGV3YXlzID09PSBcIm9iamVjdFwiICYmXG4gICAgcHJvcHMubmF0R2F0ZXdheXMgIT09IG51bGwgJiZcbiAgICBwcm9wcy5uYXRHYXRld2F5cy5jb3VudCAhPT0gdW5kZWZpbmVkXG4gICkge1xuICAgIGNvbnN0IG1heEF6cyA9IHByb3BzLm1heEF6cyA/PyAzO1xuICAgIGlmIChwcm9wcy5uYXRHYXRld2F5cy5jb3VudCA+IG1heEF6cykge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgW0ZqYWxsXSBXYXJuaW5nOiAnbmF0R2F0ZXdheXMuY291bnQnICgke3Byb3BzLm5hdEdhdGV3YXlzLmNvdW50fSkgZXhjZWVkcyBtYXhBenMgKCR7bWF4QXpzfSkuYFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBpZiAocHJvcHMudHJhbnNpdEdhdGV3YXkgJiYgIXByb3BzLnRyYW5zaXRHYXRld2F5LmlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVHJhbnNpdCBHYXRld2F5IGNvbmZpZ3VyYXRpb24gcmVxdWlyZXMgJ2lkJy5cIik7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIE5ldHdvcmtGYWN0b3J5IHtcbiAgc3RhdGljIGJ1aWxkKGlkOiBzdHJpbmcsIHByb3BzOiBJTmV0d29ya1Byb3BzKSB7XG4gICAgcmV0dXJuIChhcHA6IEFwcCwgc2NvcGU6IENvbnN0cnVjdCkgPT4ge1xuICAgICAgdmFsaWRhdGVOZXR3b3JrUHJvcHMocHJvcHMpO1xuICAgICAgcmV0dXJuIG5ldyBOZXR3b3JrKHNjb3BlLCBpZCwgcHJvcHMsIGFwcCk7XG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTmV0d29yayBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyByZWFkb25seSB2cGM6IFZwYztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogSU5ldHdvcmtQcm9wcywgYXBwOiBBcHApIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIHRoaXMudnBjID0gdGhpcy5jcmVhdGVWcGMoaWQsIHByb3BzLCBhcHApO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVWcGMoaWQ6IHN0cmluZywgcHJvcHM6IElOZXR3b3JrUHJvcHMsIGFwcDogQXBwKTogVnBjIHtcbiAgICBjb25zdCBhY2NvdW50SWQgPVxuICAgICAgYXBwLm5vZGUudHJ5R2V0Q29udGV4dChcImFjY291bnRJZFwiKSB8fCBwcm9jZXNzLmVudi5DREtfREVGQVVMVF9BQ0NPVU5UO1xuICAgIGNvbnN0IHJlZ2lvbiA9IHByb2Nlc3MuZW52LkNES19ERUZBVUxUX1JFR0lPTjtcbiAgICBjb25zdCBpc01hbmFnZWRBY2NvdW50ID1cbiAgICAgIGFwcC5ub2RlLnRyeUdldENvbnRleHQoXCJtYW5hZ2VkQWNjb3VudFwiKSA9PT0gXCJ0cnVlXCI7XG5cbiAgICBsZXQgaXB2NElwYW1Qb29sSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBpZiAoaXNNYW5hZ2VkQWNjb3VudCAmJiBhY2NvdW50SWQgJiYgcmVnaW9uKSB7XG4gICAgICBjb25zdCByZWdpb25TdWZmaXggPSByZWdpb24ucmVwbGFjZSgvLS9nLCBcIlwiKTtcbiAgICAgIGlwdjRJcGFtUG9vbElkID0gRm4uaW1wb3J0VmFsdWUoYElwYW1Qb29sSWQke2FjY291bnRJZH0ke3JlZ2lvblN1ZmZpeH1gKTtcbiAgICB9XG5cbiAgICBjb25zdCB2cGNQcm9wczogVnBjUHJvcHMgPSB7XG4gICAgICBhY2NvdW50SWQsXG4gICAgICByZWdpb24sXG4gICAgICBpcHY0SXBhbVBvb2xJZCxcbiAgICAgIG1heEF6czogcHJvcHMubWF4QXpzLFxuICAgICAgdnBjQ2lkck1hc2s6IHByb3BzLmNpZHJNYXNrLFxuICAgICAgc3VibmV0Q2lkck1hc2s6IHByb3BzLnN1Ym5ldHM/LnByaXZhdGU/LmNpZHJNYXNrLFxuICAgICAgbmF0R2F0ZXdheUNvbmZpZzogdGhpcy5yZXNvbHZlTmF0Q29uZmlnKHByb3BzLm5hdEdhdGV3YXlzKSxcbiAgICAgIGZsb3dMb2dDb25maWc6IHRoaXMucmVzb2x2ZUZsb3dMb2dDb25maWcocHJvcHMuZmxvd0xvZ3MpLFxuICAgICAgZW5kcG9pbnRzQ29uZmlnOiB0aGlzLnJlc29sdmVFbmRwb2ludHNDb25maWcocHJvcHMudnBjRW5kcG9pbnRzKVxuICAgIH07XG5cbiAgICByZXR1cm4gbmV3IFZwYyh0aGlzLCBpZCwgdnBjUHJvcHMpO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlTmF0Q29uZmlnKFxuICAgIGNvbmZpZzogTmF0Q29uZmlnIHwgZmFsc2UgfCB1bmRlZmluZWRcbiAgKTogeyBjb3VudD86IG51bWJlciB9IHwgZmFsc2UgfCB1bmRlZmluZWQge1xuICAgIGlmIChjb25maWcgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBpZiAoY29uZmlnID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB7IGNvdW50OiBjb25maWcuY291bnQgfTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZUZsb3dMb2dDb25maWcoY29uZmlnOiBGbG93TG9nQ29uZmlnIHwgZmFsc2UgfCB1bmRlZmluZWQpOlxuICAgIHwge1xuICAgICAgICBkZXN0aW5hdGlvbj86IFwiY2xvdWR3YXRjaFwiIHwgXCJzM1wiO1xuICAgICAgICByZXRlbnRpb25EYXlzPzogbnVtYmVyO1xuICAgICAgICB0cmFmZmljVHlwZT86IFwiQUxMXCIgfCBcIkFDQ0VQVFwiIHwgXCJSRUpFQ1RcIjtcbiAgICAgIH1cbiAgICB8IGZhbHNlXG4gICAgfCB1bmRlZmluZWQge1xuICAgIGlmIChjb25maWcgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBpZiAoY29uZmlnID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB7XG4gICAgICBkZXN0aW5hdGlvbjogY29uZmlnLmRlc3RpbmF0aW9uLFxuICAgICAgcmV0ZW50aW9uRGF5czogY29uZmlnLnJldGVudGlvbkRheXMsXG4gICAgICB0cmFmZmljVHlwZTogY29uZmlnLnRyYWZmaWNUeXBlXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZUVuZHBvaW50c0NvbmZpZyhcbiAgICBjb25maWc6IFZwY0VuZHBvaW50c0NvbmZpZyB8IGZhbHNlIHwgdW5kZWZpbmVkXG4gICk6XG4gICAgfCB7XG4gICAgICAgIGdhdGV3YXk/OiB7IHMzPzogYm9vbGVhbjsgZHluYW1vZGI/OiBib29sZWFuIH0gfCBmYWxzZTtcbiAgICAgICAgaW50ZXJmYWNlPzpcbiAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgZWNyPzogYm9vbGVhbjtcbiAgICAgICAgICAgICAgc2VjcmV0c01hbmFnZXI/OiBib29sZWFuO1xuICAgICAgICAgICAgICBrbXM/OiBib29sZWFuO1xuICAgICAgICAgICAgICBjbG91ZHdhdGNoTG9ncz86IGJvb2xlYW47XG4gICAgICAgICAgICAgIHNzbT86IGJvb2xlYW47XG4gICAgICAgICAgICAgIHN0cz86IGJvb2xlYW47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfCBmYWxzZTtcbiAgICAgIH1cbiAgICB8IGZhbHNlXG4gICAgfCB1bmRlZmluZWQge1xuICAgIGlmIChjb25maWcgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBEZWZhdWx0OiBnYXRld2F5IGVuZHBvaW50cyBlbmFibGVkXG4gICAgaWYgKGNvbmZpZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4geyBnYXRld2F5OiB7IHMzOiB0cnVlLCBkeW5hbW9kYjogdHJ1ZSB9IH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGdhdGV3YXk6XG4gICAgICAgIGNvbmZpZy5nYXRld2F5ID09PSBmYWxzZVxuICAgICAgICAgID8gZmFsc2VcbiAgICAgICAgICA6IHtcbiAgICAgICAgICAgICAgczM6IGNvbmZpZy5nYXRld2F5Py5zMyA/PyB0cnVlLFxuICAgICAgICAgICAgICBkeW5hbW9kYjogY29uZmlnLmdhdGV3YXk/LmR5bmFtb2RiID8/IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICBpbnRlcmZhY2U6IGNvbmZpZy5pbnRlcmZhY2UgPT09IGZhbHNlID8gZmFsc2UgOiBjb25maWcuaW50ZXJmYWNlXG4gICAgfTtcbiAgfVxuXG4gIGdldFZwYygpOiBJVnBjIHtcbiAgICByZXR1cm4gdGhpcy52cGM7XG4gIH1cbn1cbiJdfQ==
|
|
100
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29yay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9wYXR0ZXJucy9hd3MvbmV0d29yay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQ0FBdUM7QUFDdkMsNkNBQWlDO0FBSWpDLDREQUF3RTtBQXVFeEUsU0FBUyxvQkFBb0IsQ0FBQyxLQUFvQjtJQUNoRCxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3pFLE9BQU8sQ0FBQyxJQUFJLENBQ1YsNkRBQTZELEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FDN0UsQ0FBQztJQUNKLENBQUM7SUFFRCxJQUNFLE9BQU8sS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRO1FBQ3JDLEtBQUssQ0FBQyxXQUFXLEtBQUssSUFBSTtRQUMxQixLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQ3JDLENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQztRQUNqQyxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxHQUFHLE1BQU0sRUFBRSxDQUFDO1lBQ3JDLE9BQU8sQ0FBQyxJQUFJLENBQ1YseUNBQXlDLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxxQkFBcUIsTUFBTSxJQUFJLENBQ2hHLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLGNBQWMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDckQsTUFBTSxJQUFJLEtBQUssQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7QUFDSCxDQUFDO0FBRUQsTUFBYSxjQUFjO0lBQ3pCLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFB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SUFBSSxNQUFNLEtBQUssS0FBSztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBRW5DLHFDQUFxQztRQUNyQyxJQUFJLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN6QixPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQztRQUNuRCxDQUFDO1FBRUQsT0FBTztZQUNMLE9BQU8sRUFDTCxNQUFNLENBQUMsT0FBTyxLQUFLLEtBQUs7Z0JBQ3RCLENBQUMsQ0FBQyxLQUFLO2dCQUNQLENBQUMsQ0FBQztvQkFDRSxFQUFFLEVBQUUsTUFBTSxDQUFDLE9BQU8sRUFBRSxFQUFFLElBQUksSUFBSTtvQkFDOUIsUUFBUSxFQUFFLE1BQU0sQ0FBQyxPQUFPLEVBQUUsUUFBUSxJQUFJLElBQUk7aUJBQzNDO1lBQ1AsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTO1NBQ2pFLENBQUM7SUFDSixDQUFDO0lBRUQsTUFBTTtRQUNKLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUNsQixDQUFDO0NBQ0Y7QUF0R0QsMEJBc0dDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IEZuIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyB0eXBlIElWcGMgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjMlwiO1xuXG5pbXBvcnQgdHlwZSBBcHAgZnJvbSBcIi4uLy4uL2FwcFwiO1xuaW1wb3J0IHsgVnBjLCB0eXBlIFZwY1Byb3BzIH0gZnJvbSBcIi4uLy4uL3Jlc291cmNlcy9hd3MvbmV0d29ya2luZy92cGNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBOYXRDb25maWcge1xuICBjb3VudD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGbG93TG9nQ29uZmlnIHtcbiAgZGVzdGluYXRpb24/OiBcImNsb3Vkd2F0Y2hcIiB8IFwiczNcIjtcbiAgcmV0ZW50aW9uRGF5cz86IG51bWJlcjtcbiAgdHJhZmZpY1R5cGU/OiBcIkFMTFwiIHwgXCJBQ0NFUFRcIiB8IFwiUkVKRUNUXCI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2F0ZXdheUVuZHBvaW50c0NvbmZpZyB7XG4gIHMzPzogYm9vbGVhbjtcbiAgZHluYW1vZGI/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEludGVyZmFjZUVuZHBvaW50c0NvbmZpZyB7XG4gIGVjcj86IGJvb2xlYW47XG4gIHNlY3JldHNNYW5hZ2VyPzogYm9vbGVhbjtcbiAga21zPzogYm9vbGVhbjtcbiAgY2xvdWR3YXRjaExvZ3M/OiBib29sZWFuO1xuICBzc20/OiBib29sZWFuO1xuICBzdHM/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZwY0VuZHBvaW50c0NvbmZpZyB7XG4gIGdhdGV3YXk/OiBHYXRld2F5RW5kcG9pbnRzQ29uZmlnIHwgZmFsc2U7XG4gIGludGVyZmFjZT86IEludGVyZmFjZUVuZHBvaW50c0NvbmZpZyB8IGZhbHNlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN1Ym5ldENvbmZpZyB7XG4gIGNpZHJNYXNrPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN1Ym5ldHNDb25maWcge1xuICBwdWJsaWM/OiBTdWJuZXRDb25maWc7XG4gIHByaXZhdGU/OiBTdWJuZXRDb25maWc7XG4gIGlzb2xhdGVkPzogU3VibmV0Q29uZmlnIHwgZmFsc2U7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNpdEdhdGV3YXlDb25maWcge1xuICBpZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIE5ldHdvcmsgKFZQQykgY29uZmlndXJhdGlvbi5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gTWluaW1hbCBjb3N0IFZQQyAobm8gTkFULCBnYXRld2F5IGVuZHBvaW50cyBvbmx5KVxuICogeyBuYXRHYXRld2F5czogZmFsc2UgfVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBQcm9kdWN0aW9uIFZQQyB3aXRoIDEgTkFUIGdhdGV3YXlcbiAqIHsgbmF0R2F0ZXdheXM6IHsgY291bnQ6IDEgfSwgZmxvd0xvZ3M6IHt9IH1cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSGlnaC1hdmFpbGFiaWxpdHkgVlBDIHdpdGggaW50ZXJmYWNlIGVuZHBvaW50c1xuICogeyBtYXhBenM6IDMsIG5hdEdhdGV3YXlzOiB7IGNvdW50OiAzIH0sIHZwY0VuZHBvaW50czogeyBpbnRlcmZhY2U6IHsgZWNyOiB0cnVlIH0gfSB9XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSU5ldHdvcmtQcm9wcyB7XG4gIHZwY05hbWU/OiBzdHJpbmc7XG4gIG1heEF6cz86IG51bWJlcjtcbiAgY2lkck1hc2s/OiBudW1iZXI7XG4gIG5hdEdhdGV3YXlzPzogTmF0Q29uZmlnIHwgZmFsc2U7XG4gIGZsb3dMb2dzPzogRmxvd0xvZ0NvbmZpZyB8IGZhbHNlO1xuICB2cGNFbmRwb2ludHM/OiBWcGNFbmRwb2ludHNDb25maWcgfCBmYWxzZTtcbiAgc3VibmV0cz86IFN1Ym5ldHNDb25maWc7XG4gIHRyYW5zaXRHYXRld2F5PzogVHJhbnNpdEdhdGV3YXlDb25maWc7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlTmV0d29ya1Byb3BzKHByb3BzOiBJTmV0d29ya1Byb3BzKTogdm9pZCB7XG4gIGlmIChwcm9wcy5tYXhBenMgIT09IHVuZGVmaW5lZCAmJiAocHJvcHMubWF4QXpzIDwgMSB8fCBwcm9wcy5tYXhBenMgPiAzKSkge1xuICAgIGNvbnNvbGUud2FybihcbiAgICAgIGBbRmphbGxdIFdhcm5pbmc6ICdtYXhBenMnIHNob3VsZCBiZSBiZXR3ZWVuIDEgYW5kIDMuIEdvdDogJHtwcm9wcy5tYXhBenN9LmBcbiAgICApO1xuICB9XG5cbiAgaWYgKFxuICAgIHR5cGVvZiBwcm9wcy5uYXRHYXRld2F5cyA9PT0gXCJvYmplY3RcIiAmJlxuICAgIHByb3BzLm5hdEdhdGV3YXlzICE9PSBudWxsICYmXG4gICAgcHJvcHMubmF0R2F0ZXdheXMuY291bnQgIT09IHVuZGVmaW5lZFxuICApIHtcbiAgICBjb25zdCBtYXhBenMgPSBwcm9wcy5tYXhBenMgPz8gMztcbiAgICBpZiAocHJvcHMubmF0R2F0ZXdheXMuY291bnQgPiBtYXhBenMpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFtGamFsbF0gV2FybmluZzogJ25hdEdhdGV3YXlzLmNvdW50JyAoJHtwcm9wcy5uYXRHYXRld2F5cy5jb3VudH0pIGV4Y2VlZHMgbWF4QXpzICgke21heEF6c30pLmBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHByb3BzLnRyYW5zaXRHYXRld2F5ICYmICFwcm9wcy50cmFuc2l0R2F0ZXdheS5pZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlRyYW5zaXQgR2F0ZXdheSBjb25maWd1cmF0aW9uIHJlcXVpcmVzICdpZCcuXCIpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBOZXR3b3JrRmFjdG9yeSB7XG4gIHN0YXRpYyBidWlsZChpZDogc3RyaW5nLCBwcm9wczogSU5ldHdvcmtQcm9wcykge1xuICAgIHJldHVybiAoYXBwOiBBcHAsIHNjb3BlOiBDb25zdHJ1Y3QpID0+IHtcbiAgICAgIHZhbGlkYXRlTmV0d29ya1Byb3BzKHByb3BzKTtcbiAgICAgIHJldHVybiBuZXcgTmV0d29yayhzY29wZSwgaWQsIHByb3BzLCBhcHApO1xuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIE5ldHdvcmsgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwdWJsaWMgcmVhZG9ubHkgdnBjOiBWcGM7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IElOZXR3b3JrUHJvcHMsIGFwcDogQXBwKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICB0aGlzLnZwYyA9IHRoaXMuY3JlYXRlVnBjKGlkLCBwcm9wcywgYXBwKTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVnBjKGlkOiBzdHJpbmcsIHByb3BzOiBJTmV0d29ya1Byb3BzLCBhcHA6IEFwcCk6IFZwYyB7XG4gICAgY29uc3QgYWNjb3VudElkID1cbiAgICAgIGFwcC5ub2RlLnRyeUdldENvbnRleHQoXCJhY2NvdW50SWRcIikgfHwgcHJvY2Vzcy5lbnYuQ0RLX0RFRkFVTFRfQUNDT1VOVDtcbiAgICBjb25zdCByZWdpb24gPSBwcm9jZXNzLmVudi5DREtfREVGQVVMVF9SRUdJT047XG4gICAgY29uc3QgaXNNYW5hZ2VkQWNjb3VudCA9XG4gICAgICBhcHAubm9kZS50cnlHZXRDb250ZXh0KFwibWFuYWdlZEFjY291bnRcIikgPT09IFwidHJ1ZVwiO1xuXG4gICAgbGV0IGlwdjRJcGFtUG9vbElkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgaWYgKGlzTWFuYWdlZEFjY291bnQgJiYgYWNjb3VudElkICYmIHJlZ2lvbikge1xuICAgICAgY29uc3QgcmVnaW9uU3VmZml4ID0gcmVnaW9uLnJlcGxhY2UoLy0vZywgXCJcIik7XG4gICAgICBpcHY0SXBhbVBvb2xJZCA9IEZuLmltcG9ydFZhbHVlKGBJcGFtUG9vbElkJHthY2NvdW50SWR9JHtyZWdpb25TdWZmaXh9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgdnBjUHJvcHM6IFZwY1Byb3BzID0ge1xuICAgICAgdnBjTmFtZTogcHJvcHMudnBjTmFtZSxcbiAgICAgIGFjY291bnRJZCxcbiAgICAgIHJlZ2lvbixcbiAgICAgIGlwdjRJcGFtUG9vbElkLFxuICAgICAgbWF4QXpzOiBwcm9wcy5tYXhBenMsXG4gICAgICB2cGNDaWRyTWFzazogcHJvcHMuY2lkck1hc2ssXG4gICAgICBzdWJuZXRDaWRyTWFzazogcHJvcHMuc3VibmV0cz8ucHJpdmF0ZT8uY2lkck1hc2ssXG4gICAgICBuYXRHYXRld2F5Q29uZmlnOiB0aGlzLnJlc29sdmVOYXRDb25maWcocHJvcHMubmF0R2F0ZXdheXMpLFxuICAgICAgZmxvd0xvZ0NvbmZpZzogdGhpcy5yZXNvbHZlRmxvd0xvZ0NvbmZpZyhwcm9wcy5mbG93TG9ncyksXG4gICAgICBlbmRwb2ludHNDb25maWc6IHRoaXMucmVzb2x2ZUVuZHBvaW50c0NvbmZpZyhwcm9wcy52cGNFbmRwb2ludHMpXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgVnBjKHRoaXMsIGlkLCB2cGNQcm9wcyk7XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVOYXRDb25maWcoXG4gICAgY29uZmlnOiBOYXRDb25maWcgfCBmYWxzZSB8IHVuZGVmaW5lZFxuICApOiB7IGNvdW50PzogbnVtYmVyIH0gfCBmYWxzZSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKGNvbmZpZyA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGlmIChjb25maWcgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHsgY291bnQ6IGNvbmZpZy5jb3VudCB9O1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlRmxvd0xvZ0NvbmZpZyhjb25maWc6IEZsb3dMb2dDb25maWcgfCBmYWxzZSB8IHVuZGVmaW5lZCk6XG4gICAgfCB7XG4gICAgICAgIGRlc3RpbmF0aW9uPzogXCJjbG91ZHdhdGNoXCIgfCBcInMzXCI7XG4gICAgICAgIHJldGVudGlvbkRheXM/OiBudW1iZXI7XG4gICAgICAgIHRyYWZmaWNUeXBlPzogXCJBTExcIiB8IFwiQUNDRVBUXCIgfCBcIlJFSkVDVFwiO1xuICAgICAgfVxuICAgIHwgZmFsc2VcbiAgICB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKGNvbmZpZyA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGlmIChjb25maWcgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRlc3RpbmF0aW9uOiBjb25maWcuZGVzdGluYXRpb24sXG4gICAgICByZXRlbnRpb25EYXlzOiBjb25maWcucmV0ZW50aW9uRGF5cyxcbiAgICAgIHRyYWZmaWNUeXBlOiBjb25maWcudHJhZmZpY1R5cGVcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlRW5kcG9pbnRzQ29uZmlnKFxuICAgIGNvbmZpZzogVnBjRW5kcG9pbnRzQ29uZmlnIHwgZmFsc2UgfCB1bmRlZmluZWRcbiAgKTpcbiAgICB8IHtcbiAgICAgICAgZ2F0ZXdheT86IHsgczM/OiBib29sZWFuOyBkeW5hbW9kYj86IGJvb2xlYW4gfSB8IGZhbHNlO1xuICAgICAgICBpbnRlcmZhY2U/OlxuICAgICAgICAgIHwge1xuICAgICAgICAgICAgICBlY3I/OiBib29sZWFuO1xuICAgICAgICAgICAgICBzZWNyZXRzTWFuYWdlcj86IGJvb2xlYW47XG4gICAgICAgICAgICAgIGttcz86IGJvb2xlYW47XG4gICAgICAgICAgICAgIGNsb3Vkd2F0Y2hMb2dzPzogYm9vbGVhbjtcbiAgICAgICAgICAgICAgc3NtPzogYm9vbGVhbjtcbiAgICAgICAgICAgICAgc3RzPzogYm9vbGVhbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB8IGZhbHNlO1xuICAgICAgfVxuICAgIHwgZmFsc2VcbiAgICB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKGNvbmZpZyA9PT0gZmFsc2UpIHJldHVybiBmYWxzZTtcblxuICAgIC8vIERlZmF1bHQ6IGdhdGV3YXkgZW5kcG9pbnRzIGVuYWJsZWRcbiAgICBpZiAoY29uZmlnID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB7IGdhdGV3YXk6IHsgczM6IHRydWUsIGR5bmFtb2RiOiB0cnVlIH0gfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZ2F0ZXdheTpcbiAgICAgICAgY29uZmlnLmdhdGV3YXkgPT09IGZhbHNlXG4gICAgICAgICAgPyBmYWxzZVxuICAgICAgICAgIDoge1xuICAgICAgICAgICAgICBzMzogY29uZmlnLmdhdGV3YXk/LnMzID8/IHRydWUsXG4gICAgICAgICAgICAgIGR5bmFtb2RiOiBjb25maWcuZ2F0ZXdheT8uZHluYW1vZGIgPz8gdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgIGludGVyZmFjZTogY29uZmlnLmludGVyZmFjZSA9PT0gZmFsc2UgPyBmYWxzZSA6IGNvbmZpZy5pbnRlcmZhY2VcbiAgICB9O1xuICB9XG5cbiAgZ2V0VnBjKCk6IElWcGMge1xuICAgIHJldHVybiB0aGlzLnZwYztcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Construct } from "constructs";
|
|
2
|
+
/**
|
|
3
|
+
* Props for CapacityProviderDrainWaiter
|
|
4
|
+
*/
|
|
5
|
+
interface CapacityProviderDrainWaiterProps {
|
|
6
|
+
/** The ECS cluster name */
|
|
7
|
+
clusterName: string;
|
|
8
|
+
/** The capacity provider name to wait for */
|
|
9
|
+
capacityProviderName: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Custom resource that waits for ECS services to drain before allowing
|
|
13
|
+
* capacity provider disassociation.
|
|
14
|
+
*
|
|
15
|
+
* @see https://github.com/aws/aws-cdk/issues/14732
|
|
16
|
+
*/
|
|
17
|
+
export declare class CapacityProviderDrainWaiter extends Construct {
|
|
18
|
+
constructor(scope: Construct, id: string, props: CapacityProviderDrainWaiterProps);
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CapacityProviderDrainWaiter = void 0;
|
|
4
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
5
|
+
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
6
|
+
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
7
|
+
const constructs_1 = require("constructs");
|
|
8
|
+
const customResource_1 = require("../utilities/customResource");
|
|
9
|
+
/**
|
|
10
|
+
* Custom resource that waits for ECS services to drain before allowing
|
|
11
|
+
* capacity provider disassociation.
|
|
12
|
+
*
|
|
13
|
+
* @see https://github.com/aws/aws-cdk/issues/14732
|
|
14
|
+
*/
|
|
15
|
+
class CapacityProviderDrainWaiter extends constructs_1.Construct {
|
|
16
|
+
constructor(scope, id, props) {
|
|
17
|
+
super(scope, id);
|
|
18
|
+
const { clusterName, capacityProviderName } = props;
|
|
19
|
+
// Lambda inline code for the custom resource handler
|
|
20
|
+
const handlerCode = `
|
|
21
|
+
const { ECSClient, ListServicesCommand, DescribeServicesCommand, PutClusterCapacityProvidersCommand, DescribeClustersCommand } = require("@aws-sdk/client-ecs");
|
|
22
|
+
|
|
23
|
+
const ecsClient = new ECSClient({});
|
|
24
|
+
const POLL_INTERVAL_MS = 5000;
|
|
25
|
+
const MAX_WAIT_MS = 300000; // 5 minutes
|
|
26
|
+
|
|
27
|
+
async function sleep(ms) {
|
|
28
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function getClusterCapacityProviders(clusterName) {
|
|
32
|
+
const response = await ecsClient.send(new DescribeClustersCommand({
|
|
33
|
+
clusters: [clusterName]
|
|
34
|
+
}));
|
|
35
|
+
return response.clusters?.[0]?.capacityProviders || [];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function waitForServicesDrained(clusterName, capacityProviderName) {
|
|
39
|
+
const startTime = Date.now();
|
|
40
|
+
|
|
41
|
+
while (Date.now() - startTime < MAX_WAIT_MS) {
|
|
42
|
+
// List all services in the cluster
|
|
43
|
+
const listResponse = await ecsClient.send(new ListServicesCommand({
|
|
44
|
+
cluster: clusterName,
|
|
45
|
+
maxResults: 100
|
|
46
|
+
}));
|
|
47
|
+
|
|
48
|
+
const serviceArns = listResponse.serviceArns || [];
|
|
49
|
+
|
|
50
|
+
if (serviceArns.length === 0) {
|
|
51
|
+
console.log("No services found in cluster - drain complete");
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Describe services to check running counts
|
|
56
|
+
const describeResponse = await ecsClient.send(new DescribeServicesCommand({
|
|
57
|
+
cluster: clusterName,
|
|
58
|
+
services: serviceArns
|
|
59
|
+
}));
|
|
60
|
+
|
|
61
|
+
const activeServices = (describeResponse.services || []).filter(svc => {
|
|
62
|
+
// Check if service uses this capacity provider
|
|
63
|
+
const usesCapacityProvider = (svc.capacityProviderStrategy || [])
|
|
64
|
+
.some(strategy => strategy.capacityProvider === capacityProviderName);
|
|
65
|
+
|
|
66
|
+
// Only care about services using this capacity provider that still have running tasks
|
|
67
|
+
return usesCapacityProvider && svc.runningCount > 0;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (activeServices.length === 0) {
|
|
71
|
+
console.log("All services using capacity provider have drained");
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.log(\`Waiting for \${activeServices.length} services to drain: \${activeServices.map(s => s.serviceName).join(", ")}\`);
|
|
76
|
+
await sleep(POLL_INTERVAL_MS);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log("Timeout waiting for services to drain, proceeding anyway");
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function disassociateCapacityProvider(clusterName, capacityProviderName) {
|
|
84
|
+
try {
|
|
85
|
+
// Get current capacity providers
|
|
86
|
+
const currentProviders = await getClusterCapacityProviders(clusterName);
|
|
87
|
+
|
|
88
|
+
// Filter out the one we want to remove
|
|
89
|
+
const remainingProviders = currentProviders.filter(cp => cp !== capacityProviderName);
|
|
90
|
+
|
|
91
|
+
if (remainingProviders.length === currentProviders.length) {
|
|
92
|
+
console.log(\`Capacity provider \${capacityProviderName} not associated with cluster\`);
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Ensure we keep at least FARGATE as a provider (required by ECS)
|
|
97
|
+
if (remainingProviders.length === 0) {
|
|
98
|
+
remainingProviders.push("FARGATE");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
console.log(\`Disassociating \${capacityProviderName} from cluster. Remaining: \${remainingProviders.join(", ")}\`);
|
|
102
|
+
|
|
103
|
+
await ecsClient.send(new PutClusterCapacityProvidersCommand({
|
|
104
|
+
cluster: clusterName,
|
|
105
|
+
capacityProviders: remainingProviders,
|
|
106
|
+
defaultCapacityProviderStrategy: []
|
|
107
|
+
}));
|
|
108
|
+
|
|
109
|
+
console.log("Successfully disassociated capacity provider");
|
|
110
|
+
return true;
|
|
111
|
+
} catch (error) {
|
|
112
|
+
// If cluster or capacity provider doesn't exist, that's fine (already deleted)
|
|
113
|
+
if (error.name === "ClusterNotFoundException" ||
|
|
114
|
+
error.name === "ResourceNotFoundException" ||
|
|
115
|
+
error.message?.includes("does not exist")) {
|
|
116
|
+
console.log("Cluster or capacity provider not found - already cleaned up");
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
exports.handler = async (event) => {
|
|
124
|
+
console.log("Event:", JSON.stringify(event, null, 2));
|
|
125
|
+
|
|
126
|
+
const clusterName = event.ResourceProperties.ClusterName;
|
|
127
|
+
const capacityProviderName = event.ResourceProperties.CapacityProviderName;
|
|
128
|
+
const requestType = event.RequestType;
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
if (requestType === "Delete") {
|
|
132
|
+
console.log(\`Handling DELETE for capacity provider \${capacityProviderName} in cluster \${clusterName}\`);
|
|
133
|
+
|
|
134
|
+
// Wait for services to drain
|
|
135
|
+
await waitForServicesDrained(clusterName, capacityProviderName);
|
|
136
|
+
|
|
137
|
+
// Disassociate capacity provider from cluster
|
|
138
|
+
await disassociateCapacityProvider(clusterName, capacityProviderName);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Return success for all request types
|
|
142
|
+
return {
|
|
143
|
+
PhysicalResourceId: \`\${clusterName}-\${capacityProviderName}-drain-waiter\`,
|
|
144
|
+
Data: {
|
|
145
|
+
Message: \`\${requestType} completed successfully\`
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.error("Error:", error);
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
`;
|
|
154
|
+
new customResource_1.CustomResource(this, "DrainWaiter", {
|
|
155
|
+
runtime: aws_lambda_1.Runtime.NODEJS_22_X,
|
|
156
|
+
inlineCode: handlerCode,
|
|
157
|
+
timeout: aws_cdk_lib_1.Duration.minutes(6),
|
|
158
|
+
lambdaDescription: `Waits for ECS services to drain before capacity provider disassociation`,
|
|
159
|
+
roleDescription: `Role for ${clusterName} capacity provider drain waiter`,
|
|
160
|
+
inlinePolicy: [
|
|
161
|
+
new aws_iam_1.PolicyStatement({
|
|
162
|
+
effect: aws_iam_1.Effect.ALLOW,
|
|
163
|
+
actions: [
|
|
164
|
+
"ecs:ListServices",
|
|
165
|
+
"ecs:DescribeServices",
|
|
166
|
+
"ecs:DescribeClusters",
|
|
167
|
+
"ecs:PutClusterCapacityProviders"
|
|
168
|
+
],
|
|
169
|
+
resources: ["*"]
|
|
170
|
+
})
|
|
171
|
+
],
|
|
172
|
+
properties: {
|
|
173
|
+
ClusterName: clusterName,
|
|
174
|
+
CapacityProviderName: capacityProviderName
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.CapacityProviderDrainWaiter = CapacityProviderDrainWaiter;
|
|
180
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FwYWNpdHlQcm92aWRlckRyYWluV2FpdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGliL3Jlc291cmNlcy9hd3MvY29tcHV0ZS9jYXBhY2l0eVByb3ZpZGVyRHJhaW5XYWl0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkNBQXVDO0FBQ3ZDLGlEQUE4RDtBQUM5RCx1REFBaUQ7QUFDakQsMkNBQXVDO0FBQ3ZDLGdFQUE2RDtBQVk3RDs7Ozs7R0FLRztBQUNILE1BQWEsMkJBQTRCLFNBQVEsc0JBQVM7SUFDeEQsWUFDRSxLQUFnQixFQUNoQixFQUFVLEVBQ1YsS0FBdUM7UUFFdkMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLEVBQUUsV0FBVyxFQUFFLG9CQUFvQixFQUFFLEdBQUcsS0FBSyxDQUFDO1FBRXBELHFEQUFxRDtRQUNyRCxNQUFNLFdBQVcsR0FBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztDQXFJdkIsQ0FBQztRQUVFLElBQUksK0JBQWMsQ0FBQyxJQUFJLEVBQUUsYUFBYSxFQUFFO1lBQ3RDLE9BQU8sRUFBRSxvQkFBTyxDQUFDLFdBQVc7WUFDNUIsVUFBVSxFQUFFLFdBQVc7WUFDdkIsT0FBTyxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUM1QixpQkFBaUIsRUFBRSx5RUFBeUU7WUFDNUYsZUFBZSxFQUFFLFlBQVksV0FBVyxpQ0FBaUM7WUFDekUsWUFBWSxFQUFFO2dCQUNaLElBQUkseUJBQWUsQ0FBQztvQkFDbEIsTUFBTSxFQUFFLGdCQUFNLENBQUMsS0FBSztvQkFDcEIsT0FBTyxFQUFFO3dCQUNQLGtCQUFrQjt3QkFDbEIsc0JBQXNCO3dCQUN0QixzQkFBc0I7d0JBQ3RCLGlDQUFpQztxQkFDbEM7b0JBQ0QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO2lCQUNqQixDQUFDO2FBQ0g7WUFDRCxVQUFVLEVBQUU7Z0JBQ1YsV0FBVyxFQUFFLFdBQVc7Z0JBQ3hCLG9CQUFvQixFQUFFLG9CQUFvQjthQUMzQztTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQTFLRCxrRUEwS0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEdXJhdGlvbiB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50LCBFZmZlY3QgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWlhbVwiO1xuaW1wb3J0IHsgUnVudGltZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHsgQ3VzdG9tUmVzb3VyY2UgfSBmcm9tIFwiLi4vdXRpbGl0aWVzL2N1c3RvbVJlc291cmNlXCI7XG5cbi8qKlxuICogUHJvcHMgZm9yIENhcGFjaXR5UHJvdmlkZXJEcmFpbldhaXRlclxuICovXG5pbnRlcmZhY2UgQ2FwYWNpdHlQcm92aWRlckRyYWluV2FpdGVyUHJvcHMge1xuICAvKiogVGhlIEVDUyBjbHVzdGVyIG5hbWUgKi9cbiAgY2x1c3Rlck5hbWU6IHN0cmluZztcbiAgLyoqIFRoZSBjYXBhY2l0eSBwcm92aWRlciBuYW1lIHRvIHdhaXQgZm9yICovXG4gIGNhcGFjaXR5UHJvdmlkZXJOYW1lOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ3VzdG9tIHJlc291cmNlIHRoYXQgd2FpdHMgZm9yIEVDUyBzZXJ2aWNlcyB0byBkcmFpbiBiZWZvcmUgYWxsb3dpbmdcbiAqIGNhcGFjaXR5IHByb3ZpZGVyIGRpc2Fzc29jaWF0aW9uLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy8xNDczMlxuICovXG5leHBvcnQgY2xhc3MgQ2FwYWNpdHlQcm92aWRlckRyYWluV2FpdGVyIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IENvbnN0cnVjdCxcbiAgICBpZDogc3RyaW5nLFxuICAgIHByb3BzOiBDYXBhY2l0eVByb3ZpZGVyRHJhaW5XYWl0ZXJQcm9wc1xuICApIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgeyBjbHVzdGVyTmFtZSwgY2FwYWNpdHlQcm92aWRlck5hbWUgfSA9IHByb3BzO1xuXG4gICAgLy8gTGFtYmRhIGlubGluZSBjb2RlIGZvciB0aGUgY3VzdG9tIHJlc291cmNlIGhhbmRsZXJcbiAgICBjb25zdCBoYW5kbGVyQ29kZSA9IGBcbmNvbnN0IHsgRUNTQ2xpZW50LCBMaXN0U2VydmljZXNDb21tYW5kLCBEZXNjcmliZVNlcnZpY2VzQ29tbWFuZCwgUHV0Q2x1c3RlckNhcGFjaXR5UHJvdmlkZXJzQ29tbWFuZCwgRGVzY3JpYmVDbHVzdGVyc0NvbW1hbmQgfSA9IHJlcXVpcmUoXCJAYXdzLXNkay9jbGllbnQtZWNzXCIpO1xuXG5jb25zdCBlY3NDbGllbnQgPSBuZXcgRUNTQ2xpZW50KHt9KTtcbmNvbnN0IFBPTExfSU5URVJWQUxfTVMgPSA1MDAwO1xuY29uc3QgTUFYX1dBSVRfTVMgPSAzMDAwMDA7IC8vIDUgbWludXRlc1xuXG5hc3luYyBmdW5jdGlvbiBzbGVlcChtcykge1xuICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldENsdXN0ZXJDYXBhY2l0eVByb3ZpZGVycyhjbHVzdGVyTmFtZSkge1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGVjc0NsaWVudC5zZW5kKG5ldyBEZXNjcmliZUNsdXN0ZXJzQ29tbWFuZCh7XG4gICAgY2x1c3RlcnM6IFtjbHVzdGVyTmFtZV1cbiAgfSkpO1xuICByZXR1cm4gcmVzcG9uc2UuY2x1c3RlcnM/LlswXT8uY2FwYWNpdHlQcm92aWRlcnMgfHwgW107XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHdhaXRGb3JTZXJ2aWNlc0RyYWluZWQoY2x1c3Rlck5hbWUsIGNhcGFjaXR5UHJvdmlkZXJOYW1lKSB7XG4gIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG5cbiAgd2hpbGUgKERhdGUubm93KCkgLSBzdGFydFRpbWUgPCBNQVhfV0FJVF9NUykge1xuICAgIC8vIExpc3QgYWxsIHNlcnZpY2VzIGluIHRoZSBjbHVzdGVyXG4gICAgY29uc3QgbGlzdFJlc3BvbnNlID0gYXdhaXQgZWNzQ2xpZW50LnNlbmQobmV3IExpc3RTZXJ2aWNlc0NvbW1hbmQoe1xuICAgICAgY2x1c3RlcjogY2x1c3Rlck5hbWUsXG4gICAgICBtYXhSZXN1bHRzOiAxMDBcbiAgICB9KSk7XG5cbiAgICBjb25zdCBzZXJ2aWNlQXJucyA9IGxpc3RSZXNwb25zZS5zZXJ2aWNlQXJucyB8fCBbXTtcblxuICAgIGlmIChzZXJ2aWNlQXJucy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnNvbGUubG9nKFwiTm8gc2VydmljZXMgZm91bmQgaW4gY2x1c3RlciAtIGRyYWluIGNvbXBsZXRlXCIpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gRGVzY3JpYmUgc2VydmljZXMgdG8gY2hlY2sgcnVubmluZyBjb3VudHNcbiAgICBjb25zdCBkZXNjcmliZVJlc3BvbnNlID0gYXdhaXQgZWNzQ2xpZW50LnNlbmQobmV3IERlc2NyaWJlU2VydmljZXNDb21tYW5kKHtcbiAgICAgIGNsdXN0ZXI6IGNsdXN0ZXJOYW1lLFxuICAgICAgc2VydmljZXM6IHNlcnZpY2VBcm5zXG4gICAgfSkpO1xuXG4gICAgY29uc3QgYWN0aXZlU2VydmljZXMgPSAoZGVzY3JpYmVSZXNwb25zZS5zZXJ2aWNlcyB8fCBbXSkuZmlsdGVyKHN2YyA9PiB7XG4gICAgICAvLyBDaGVjayBpZiBzZXJ2aWNlIHVzZXMgdGhpcyBjYXBhY2l0eSBwcm92aWRlclxuICAgICAgY29uc3QgdXNlc0NhcGFjaXR5UHJvdmlkZXIgPSAoc3ZjLmNhcGFjaXR5UHJvdmlkZXJTdHJhdGVneSB8fCBbXSlcbiAgICAgICAgLnNvbWUoc3RyYXRlZ3kgPT4gc3RyYXRlZ3kuY2FwYWNpdHlQcm92aWRlciA9PT0gY2FwYWNpdHlQcm92aWRlck5hbWUpO1xuXG4gICAgICAvLyBPbmx5IGNhcmUgYWJvdXQgc2VydmljZXMgdXNpbmcgdGhpcyBjYXBhY2l0eSBwcm92aWRlciB0aGF0IHN0aWxsIGhhdmUgcnVubmluZyB0YXNrc1xuICAgICAgcmV0dXJuIHVzZXNDYXBhY2l0eVByb3ZpZGVyICYmIHN2Yy5ydW5uaW5nQ291bnQgPiAwO1xuICAgIH0pO1xuXG4gICAgaWYgKGFjdGl2ZVNlcnZpY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgY29uc29sZS5sb2coXCJBbGwgc2VydmljZXMgdXNpbmcgY2FwYWNpdHkgcHJvdmlkZXIgaGF2ZSBkcmFpbmVkXCIpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgY29uc29sZS5sb2coXFxgV2FpdGluZyBmb3IgXFwke2FjdGl2ZVNlcnZpY2VzLmxlbmd0aH0gc2VydmljZXMgdG8gZHJhaW46IFxcJHthY3RpdmVTZXJ2aWNlcy5tYXAocyA9PiBzLnNlcnZpY2VOYW1lKS5qb2luKFwiLCBcIil9XFxgKTtcbiAgICBhd2FpdCBzbGVlcChQT0xMX0lOVEVSVkFMX01TKTtcbiAgfVxuXG4gIGNvbnNvbGUubG9nKFwiVGltZW91dCB3YWl0aW5nIGZvciBzZXJ2aWNlcyB0byBkcmFpbiwgcHJvY2VlZGluZyBhbnl3YXlcIik7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZGlzYXNzb2NpYXRlQ2FwYWNpdHlQcm92aWRlcihjbHVzdGVyTmFtZSwgY2FwYWNpdHlQcm92aWRlck5hbWUpIHtcbiAgdHJ5IHtcbiAgICAvLyBHZXQgY3VycmVudCBjYXBhY2l0eSBwcm92aWRlcnNcbiAgICBjb25zdCBjdXJyZW50UHJvdmlkZXJzID0gYXdhaXQgZ2V0Q2x1c3RlckNhcGFjaXR5UHJvdmlkZXJzKGNsdXN0ZXJOYW1lKTtcblxuICAgIC8vIEZpbHRlciBvdXQgdGhlIG9uZSB3ZSB3YW50IHRvIHJlbW92ZVxuICAgIGNvbnN0IHJlbWFpbmluZ1Byb3ZpZGVycyA9IGN1cnJlbnRQcm92aWRlcnMuZmlsdGVyKGNwID0+IGNwICE9PSBjYXBhY2l0eVByb3ZpZGVyTmFtZSk7XG5cbiAgICBpZiAocmVtYWluaW5nUHJvdmlkZXJzLmxlbmd0aCA9PT0gY3VycmVudFByb3ZpZGVycy5sZW5ndGgpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxcYENhcGFjaXR5IHByb3ZpZGVyIFxcJHtjYXBhY2l0eVByb3ZpZGVyTmFtZX0gbm90IGFzc29jaWF0ZWQgd2l0aCBjbHVzdGVyXFxgKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIEVuc3VyZSB3ZSBrZWVwIGF0IGxlYXN0IEZBUkdBVEUgYXMgYSBwcm92aWRlciAocmVxdWlyZWQgYnkgRUNTKVxuICAgIGlmIChyZW1haW5pbmdQcm92aWRlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZW1haW5pbmdQcm92aWRlcnMucHVzaChcIkZBUkdBVEVcIik7XG4gICAgfVxuXG4gICAgY29uc29sZS5sb2coXFxgRGlzYXNzb2NpYXRpbmcgXFwke2NhcGFjaXR5UHJvdmlkZXJOYW1lfSBmcm9tIGNsdXN0ZXIuIFJlbWFpbmluZzogXFwke3JlbWFpbmluZ1Byb3ZpZGVycy5qb2luKFwiLCBcIil9XFxgKTtcblxuICAgIGF3YWl0IGVjc0NsaWVudC5zZW5kKG5ldyBQdXRDbHVzdGVyQ2FwYWNpdHlQcm92aWRlcnNDb21tYW5kKHtcbiAgICAgIGNsdXN0ZXI6IGNsdXN0ZXJOYW1lLFxuICAgICAgY2FwYWNpdHlQcm92aWRlcnM6IHJlbWFpbmluZ1Byb3ZpZGVycyxcbiAgICAgIGRlZmF1bHRDYXBhY2l0eVByb3ZpZGVyU3RyYXRlZ3k6IFtdXG4gICAgfSkpO1xuXG4gICAgY29uc29sZS5sb2coXCJTdWNjZXNzZnVsbHkgZGlzYXNzb2NpYXRlZCBjYXBhY2l0eSBwcm92aWRlclwiKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAvLyBJZiBjbHVzdGVyIG9yIGNhcGFjaXR5IHByb3ZpZGVyIGRvZXNuJ3QgZXhpc3QsIHRoYXQncyBmaW5lIChhbHJlYWR5IGRlbGV0ZWQpXG4gICAgaWYgKGVycm9yLm5hbWUgPT09IFwiQ2x1c3Rlck5vdEZvdW5kRXhjZXB0aW9uXCIgfHxcbiAgICAgICAgZXJyb3IubmFtZSA9PT0gXCJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uXCIgfHxcbiAgICAgICAgZXJyb3IubWVzc2FnZT8uaW5jbHVkZXMoXCJkb2VzIG5vdCBleGlzdFwiKSkge1xuICAgICAgY29uc29sZS5sb2coXCJDbHVzdGVyIG9yIGNhcGFjaXR5IHByb3ZpZGVyIG5vdCBmb3VuZCAtIGFscmVhZHkgY2xlYW5lZCB1cFwiKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG5leHBvcnRzLmhhbmRsZXIgPSBhc3luYyAoZXZlbnQpID0+IHtcbiAgY29uc29sZS5sb2coXCJFdmVudDpcIiwgSlNPTi5zdHJpbmdpZnkoZXZlbnQsIG51bGwsIDIpKTtcblxuICBjb25zdCBjbHVzdGVyTmFtZSA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5DbHVzdGVyTmFtZTtcbiAgY29uc3QgY2FwYWNpdHlQcm92aWRlck5hbWUgPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuQ2FwYWNpdHlQcm92aWRlck5hbWU7XG4gIGNvbnN0IHJlcXVlc3RUeXBlID0gZXZlbnQuUmVxdWVzdFR5cGU7XG5cbiAgdHJ5IHtcbiAgICBpZiAocmVxdWVzdFR5cGUgPT09IFwiRGVsZXRlXCIpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxcYEhhbmRsaW5nIERFTEVURSBmb3IgY2FwYWNpdHkgcHJvdmlkZXIgXFwke2NhcGFjaXR5UHJvdmlkZXJOYW1lfSBpbiBjbHVzdGVyIFxcJHtjbHVzdGVyTmFtZX1cXGApO1xuXG4gICAgICAvLyBXYWl0IGZvciBzZXJ2aWNlcyB0byBkcmFpblxuICAgICAgYXdhaXQgd2FpdEZvclNlcnZpY2VzRHJhaW5lZChjbHVzdGVyTmFtZSwgY2FwYWNpdHlQcm92aWRlck5hbWUpO1xuXG4gICAgICAvLyBEaXNhc3NvY2lhdGUgY2FwYWNpdHkgcHJvdmlkZXIgZnJvbSBjbHVzdGVyXG4gICAgICBhd2FpdCBkaXNhc3NvY2lhdGVDYXBhY2l0eVByb3ZpZGVyKGNsdXN0ZXJOYW1lLCBjYXBhY2l0eVByb3ZpZGVyTmFtZSk7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIHN1Y2Nlc3MgZm9yIGFsbCByZXF1ZXN0IHR5cGVzXG4gICAgcmV0dXJuIHtcbiAgICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogXFxgXFwke2NsdXN0ZXJOYW1lfS1cXCR7Y2FwYWNpdHlQcm92aWRlck5hbWV9LWRyYWluLXdhaXRlclxcYCxcbiAgICAgIERhdGE6IHtcbiAgICAgICAgTWVzc2FnZTogXFxgXFwke3JlcXVlc3RUeXBlfSBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5XFxgXG4gICAgICB9XG4gICAgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zb2xlLmVycm9yKFwiRXJyb3I6XCIsIGVycm9yKTtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufTtcbmA7XG5cbiAgICBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgXCJEcmFpbldhaXRlclwiLCB7XG4gICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgaW5saW5lQ29kZTogaGFuZGxlckNvZGUsXG4gICAgICB0aW1lb3V0OiBEdXJhdGlvbi5taW51dGVzKDYpLFxuICAgICAgbGFtYmRhRGVzY3JpcHRpb246IGBXYWl0cyBmb3IgRUNTIHNlcnZpY2VzIHRvIGRyYWluIGJlZm9yZSBjYXBhY2l0eSBwcm92aWRlciBkaXNhc3NvY2lhdGlvbmAsXG4gICAgICByb2xlRGVzY3JpcHRpb246IGBSb2xlIGZvciAke2NsdXN0ZXJOYW1lfSBjYXBhY2l0eSBwcm92aWRlciBkcmFpbiB3YWl0ZXJgLFxuICAgICAgaW5saW5lUG9saWN5OiBbXG4gICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGVmZmVjdDogRWZmZWN0LkFMTE9XLFxuICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgIFwiZWNzOkxpc3RTZXJ2aWNlc1wiLFxuICAgICAgICAgICAgXCJlY3M6RGVzY3JpYmVTZXJ2aWNlc1wiLFxuICAgICAgICAgICAgXCJlY3M6RGVzY3JpYmVDbHVzdGVyc1wiLFxuICAgICAgICAgICAgXCJlY3M6UHV0Q2x1c3RlckNhcGFjaXR5UHJvdmlkZXJzXCJcbiAgICAgICAgICBdLFxuICAgICAgICAgIHJlc291cmNlczogW1wiKlwiXVxuICAgICAgICB9KVxuICAgICAgXSxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgQ2x1c3Rlck5hbWU6IGNsdXN0ZXJOYW1lLFxuICAgICAgICBDYXBhY2l0eVByb3ZpZGVyTmFtZTogY2FwYWNpdHlQcm92aWRlck5hbWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuIl19
|