@cdklabs/multi-az-observability 0.0.1-alpha.4 → 0.0.1-alpha.41
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/.jsii +2237 -769
- package/API.md +5141 -1591
- package/README.md +63 -54
- package/cdk.json +1 -1
- package/lib/alarmsandrules/AvailabilityAndLatencyAlarmsAndRules.d.ts +14 -12
- package/lib/alarmsandrules/AvailabilityAndLatencyAlarmsAndRules.js +50 -49
- package/lib/alarmsandrules/BaseOperationRegionalAlarmsAndRules.js +2 -2
- package/lib/alarmsandrules/BaseOperationZonalAlarmsAndRules.d.ts +6 -15
- package/lib/alarmsandrules/BaseOperationZonalAlarmsAndRules.js +2 -10
- package/lib/alarmsandrules/CanaryOperationZonalAlarmsAndRules.d.ts +11 -3
- package/lib/alarmsandrules/CanaryOperationZonalAlarmsAndRules.js +24 -13
- package/lib/alarmsandrules/IBaseOperationZonalAlarmsAndRules.d.ts +0 -8
- package/lib/alarmsandrules/IBaseOperationZonalAlarmsAndRules.js +1 -1
- package/lib/alarmsandrules/IOperationAlarmsAndRules.d.ts +20 -27
- package/lib/alarmsandrules/IOperationAlarmsAndRules.js +1 -1
- package/lib/alarmsandrules/IServerSideOperationRegionalAlarmsAndRules.js +1 -1
- package/lib/alarmsandrules/IServiceAlarmsAndRules.d.ts +19 -15
- package/lib/alarmsandrules/IServiceAlarmsAndRules.js +1 -1
- package/lib/alarmsandrules/OperationAlarmsAndRules.d.ts +15 -22
- package/lib/alarmsandrules/OperationAlarmsAndRules.js +52 -72
- package/lib/alarmsandrules/ServerSideOperationRegionalAlarmsAndRules.d.ts +5 -5
- package/lib/alarmsandrules/ServerSideOperationRegionalAlarmsAndRules.js +2 -3
- package/lib/alarmsandrules/ServerSideOperationZonalAlarmsAndRules.d.ts +21 -13
- package/lib/alarmsandrules/ServerSideOperationZonalAlarmsAndRules.js +43 -29
- package/lib/alarmsandrules/ServiceAlarmsAndRules.d.ts +19 -15
- package/lib/alarmsandrules/ServiceAlarmsAndRules.js +34 -136
- package/lib/alarmsandrules/props/BaseOperationRegionalAlarmsAndRulesProps.d.ts +4 -3
- package/lib/alarmsandrules/props/BaseOperationRegionalAlarmsAndRulesProps.js +1 -1
- package/lib/alarmsandrules/props/BaseOperationZonalAlarmsAndRulesProps.d.ts +6 -44
- package/lib/alarmsandrules/props/BaseOperationZonalAlarmsAndRulesProps.js +1 -1
- package/lib/alarmsandrules/props/OperationAlarmsAndRulesProps.d.ts +28 -7
- package/lib/alarmsandrules/props/OperationAlarmsAndRulesProps.js +1 -1
- package/lib/azmapper/AvailabilityZoneMapper.js +8 -9
- package/lib/basic_observability/BasicServiceDashboard.d.ts +0 -3
- package/lib/basic_observability/BasicServiceDashboard.js +24 -112
- package/lib/basic_observability/BasicServiceMultiAZObservability.d.ts +8 -9
- package/lib/basic_observability/BasicServiceMultiAZObservability.js +98 -312
- package/lib/basic_observability/props/ApplicationLoadBalancerDetectionProps.d.ts +51 -0
- package/lib/basic_observability/props/ApplicationLoadBalancerDetectionProps.js +3 -0
- package/lib/basic_observability/props/BasicServiceDashboardProps.d.ts +27 -13
- package/lib/basic_observability/props/BasicServiceDashboardProps.js +1 -1
- package/lib/basic_observability/props/BasicServiceMultiAZObservabilityProps.d.ts +10 -38
- package/lib/basic_observability/props/BasicServiceMultiAZObservabilityProps.js +1 -1
- package/lib/basic_observability/props/NatGatewayDetectionProps.d.ts +31 -0
- package/lib/basic_observability/props/NatGatewayDetectionProps.js +3 -0
- package/lib/canaries/CanaryFunction.js +14 -13
- package/lib/canaries/CanaryTest.js +4 -4
- package/lib/canaries/src/canary.zip +0 -0
- package/lib/dashboards/ContributorInsightsWidget.d.ts +1 -1
- package/lib/dashboards/ContributorInsightsWidget.js +13 -17
- package/lib/dashboards/OperationAvailabilityAndLatencyDashboard.d.ts +2 -6
- package/lib/dashboards/OperationAvailabilityAndLatencyDashboard.js +445 -507
- package/lib/dashboards/ServiceAvailabilityAndLatencyDashboard.d.ts +2 -10
- package/lib/dashboards/ServiceAvailabilityAndLatencyDashboard.js +350 -437
- package/lib/dashboards/props/OperationAvailabilityAndLatencyDashboardProps.d.ts +3 -66
- package/lib/dashboards/props/OperationAvailabilityAndLatencyDashboardProps.js +1 -1
- package/lib/dashboards/props/OperationAvailabilityWidgetProps.d.ts +7 -2
- package/lib/dashboards/props/OperationAvailabilityWidgetProps.js +1 -1
- package/lib/dashboards/props/OperationLatencyWidgetProps.d.ts +7 -2
- package/lib/dashboards/props/OperationLatencyWidgetProps.js +1 -1
- package/lib/dashboards/props/ServiceAvailabilityAndLatencyDashboardProps.d.ts +8 -8
- package/lib/dashboards/props/ServiceAvailabilityAndLatencyDashboardProps.js +1 -1
- package/lib/index.d.ts +54 -24
- package/lib/index.js +36 -17
- package/lib/metrics/ApplicationLoadBalancerMetrics.d.ts +77 -3
- package/lib/metrics/ApplicationLoadBalancerMetrics.js +813 -32
- package/lib/metrics/AvailabilityAndLatencyMetrics.d.ts +23 -0
- package/lib/metrics/AvailabilityAndLatencyMetrics.js +120 -26
- package/lib/metrics/NatGatewayMetrics.d.ts +113 -0
- package/lib/metrics/NatGatewayMetrics.js +357 -0
- package/lib/metrics/RegionalAvailabilityMetrics.js +4 -5
- package/lib/metrics/RegionalLatencyMetrics.d.ts +1 -1
- package/lib/metrics/RegionalLatencyMetrics.js +27 -20
- package/lib/metrics/ZonalAvailabilityMetrics.d.ts +2 -8
- package/lib/metrics/ZonalAvailabilityMetrics.js +10 -25
- package/lib/metrics/ZonalLatencyMetrics.d.ts +2 -1
- package/lib/metrics/ZonalLatencyMetrics.js +33 -23
- package/lib/metrics/props/AvailabilityAndLatencyMetricProps.d.ts +4 -0
- package/lib/metrics/props/AvailabilityAndLatencyMetricProps.js +1 -1
- package/lib/metrics/props/LatencyMetricProps.d.ts +6 -0
- package/lib/metrics/props/LatencyMetricProps.js +1 -1
- package/lib/metrics/props/ZonalAvailabilityMetricProps.d.ts +4 -0
- package/lib/metrics/props/ZonalAvailabilityMetricProps.js +1 -1
- package/lib/metrics/props/ZonalLatencyMetricProps.d.ts +4 -0
- package/lib/metrics/props/ZonalLatencyMetricProps.js +1 -1
- package/lib/monitoring/src/monitoring-layer.zip +0 -0
- package/lib/outlier-detection/ApplicationLoadBalancerAvailabilityOutlierAlgorithm.d.ts +10 -0
- package/lib/outlier-detection/ApplicationLoadBalancerAvailabilityOutlierAlgorithm.js +15 -0
- package/lib/outlier-detection/ApplicationLoadBalancerLatencyOutlierAlgorithm.d.ts +18 -0
- package/lib/outlier-detection/ApplicationLoadBalancerLatencyOutlierAlgorithm.js +23 -0
- package/lib/outlier-detection/OutlierDetectionFunction.js +7 -6
- package/lib/outlier-detection/PacketLossOutlierAlgorithm.d.ts +10 -0
- package/lib/outlier-detection/PacketLossOutlierAlgorithm.js +15 -0
- package/lib/outlier-detection/src/outlier-detection.zip +0 -0
- package/lib/outlier-detection/src/scipy-layer.zip +0 -0
- package/lib/services/CanaryMetrics.d.ts +4 -3
- package/lib/services/CanaryMetrics.js +3 -4
- package/lib/services/CanaryTestAvailabilityMetricsOverride.d.ts +21 -0
- package/lib/services/CanaryTestAvailabilityMetricsOverride.js +23 -0
- package/lib/services/CanaryTestLatencyMetricsOverride.d.ts +15 -0
- package/lib/services/CanaryTestLatencyMetricsOverride.js +20 -0
- package/lib/services/CanaryTestMetricsOverride.d.ts +1 -13
- package/lib/services/CanaryTestMetricsOverride.js +2 -4
- package/lib/services/ContributorInsightRuleDetails.js +1 -1
- package/lib/services/ICanaryMetrics.d.ts +4 -3
- package/lib/services/ICanaryMetrics.js +1 -1
- package/lib/services/ICanaryTestAvailabilityMetricsOverride.d.ts +23 -0
- package/lib/services/ICanaryTestAvailabilityMetricsOverride.js +3 -0
- package/lib/services/ICanaryTestLatencyMetricsOverride.d.ts +13 -0
- package/lib/services/ICanaryTestLatencyMetricsOverride.js +3 -0
- package/lib/services/ICanaryTestMetricsOverride.d.ts +0 -12
- package/lib/services/ICanaryTestMetricsOverride.js +1 -1
- package/lib/services/IInstrumentedServiceMultiAZObservability.d.ts +13 -3
- package/lib/services/IInstrumentedServiceMultiAZObservability.js +1 -1
- package/lib/services/IOperation.d.ts +8 -6
- package/lib/services/IOperation.js +1 -1
- package/lib/services/IOperationAvailabilityMetricDetails.d.ts +18 -0
- package/lib/services/IOperationAvailabilityMetricDetails.js +3 -0
- package/lib/services/IOperationLatencyMetricDetails.d.ts +12 -0
- package/lib/services/IOperationLatencyMetricDetails.js +3 -0
- package/lib/services/IOperationMetricDetails.d.ts +0 -12
- package/lib/services/IOperationMetricDetails.js +1 -1
- package/lib/services/IService.d.ts +4 -3
- package/lib/services/IService.js +1 -1
- package/lib/services/IServiceAvailabilityMetricDetails.d.ts +18 -0
- package/lib/services/IServiceAvailabilityMetricDetails.js +3 -0
- package/lib/services/IServiceLatencyMetricDetails.d.ts +12 -0
- package/lib/services/IServiceLatencyMetricDetails.js +3 -0
- package/lib/services/IServiceMetricDetails.d.ts +0 -12
- package/lib/services/IServiceMetricDetails.js +1 -1
- package/lib/services/InstrumentedServiceMultiAZObservability.d.ts +15 -3
- package/lib/services/InstrumentedServiceMultiAZObservability.js +197 -208
- package/lib/services/Operation.d.ts +8 -6
- package/lib/services/Operation.js +2 -2
- package/lib/services/OperationAvailabilityMetricDetails.d.ts +22 -0
- package/lib/services/OperationAvailabilityMetricDetails.js +24 -0
- package/lib/services/OperationLatencyMetricDetails.d.ts +16 -0
- package/lib/services/OperationLatencyMetricDetails.js +21 -0
- package/lib/services/OperationMetricDetails.d.ts +1 -13
- package/lib/services/OperationMetricDetails.js +2 -8
- package/lib/services/Service.d.ts +4 -3
- package/lib/services/Service.js +2 -2
- package/lib/services/ServiceAvailabilityMetricDetails.d.ts +21 -0
- package/lib/services/ServiceAvailabilityMetricDetails.js +20 -0
- package/lib/services/ServiceLatencyMetricDetails.d.ts +15 -0
- package/lib/services/ServiceLatencyMetricDetails.js +19 -0
- package/lib/services/ServiceMetricDetails.d.ts +1 -13
- package/lib/services/ServiceMetricDetails.js +2 -4
- package/lib/services/props/CanaryMetricProps.d.ts +4 -3
- package/lib/services/props/CanaryMetricProps.js +1 -1
- package/lib/services/props/CanaryTestAvailabilityMetricsOverrideProps.d.ts +22 -0
- package/lib/services/props/CanaryTestAvailabilityMetricsOverrideProps.js +3 -0
- package/lib/services/props/CanaryTestLatencyMetricsOverrideProps.d.ts +14 -0
- package/lib/services/props/CanaryTestLatencyMetricsOverrideProps.js +3 -0
- package/lib/services/props/CanaryTestMetricsOverrideProps.d.ts +0 -16
- package/lib/services/props/CanaryTestMetricsOverrideProps.js +1 -1
- package/lib/services/props/InstrumentedServiceMultiAZObservabilityProps.d.ts +1 -1
- package/lib/services/props/InstrumentedServiceMultiAZObservabilityProps.js +1 -1
- package/lib/services/props/MetricDimensions.js +1 -1
- package/lib/services/props/OperationAvailabilityMetricDetailsProps.d.ts +22 -0
- package/lib/services/props/OperationAvailabilityMetricDetailsProps.js +3 -0
- package/lib/services/props/OperationLatencyMetricDetailsProps.d.ts +14 -0
- package/lib/services/props/OperationLatencyMetricDetailsProps.js +3 -0
- package/lib/services/props/OperationMetricDetailsProps.d.ts +0 -16
- package/lib/services/props/OperationMetricDetailsProps.js +1 -1
- package/lib/services/props/OperationProps.d.ts +4 -3
- package/lib/services/props/OperationProps.js +1 -1
- package/lib/services/props/ServiceAvailabilityMetricDetailsProps.d.ts +18 -0
- package/lib/services/props/ServiceAvailabilityMetricDetailsProps.js +3 -0
- package/lib/services/props/ServiceLatencyMetricDetailsProps.d.ts +12 -0
- package/lib/services/props/ServiceLatencyMetricDetailsProps.js +3 -0
- package/lib/services/props/ServiceMetricDetailsProps.d.ts +0 -12
- package/lib/services/props/ServiceMetricDetailsProps.js +1 -1
- package/lib/services/props/ServiceProps.d.ts +4 -3
- package/lib/services/props/ServiceProps.js +1 -1
- package/lib/utilities/MetricsHelper.d.ts +17 -9
- package/lib/utilities/MetricsHelper.js +34 -10
- package/package.json +10 -10
- package/lib/services/IBasicServiceMultiAZObservability.d.ts +0 -45
- package/lib/services/IBasicServiceMultiAZObservability.js +0 -3
|
@@ -4,7 +4,10 @@ exports.ApplicationLoadBalancerMetrics = void 0;
|
|
|
4
4
|
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
|
|
5
5
|
const aws_elasticloadbalancingv2_1 = require("aws-cdk-lib/aws-elasticloadbalancingv2");
|
|
6
6
|
const AvailabilityMetricType_1 = require("../utilities/AvailabilityMetricType");
|
|
7
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
7
8
|
const MetricsHelper_1 = require("../utilities/MetricsHelper");
|
|
9
|
+
const ApplicationLoadBalancerAvailabilityOutlierAlgorithm_1 = require("../outlier-detection/ApplicationLoadBalancerAvailabilityOutlierAlgorithm");
|
|
10
|
+
const ApplicationLoadBalancerLatencyOutlierAlgorithm_1 = require("../outlier-detection/ApplicationLoadBalancerLatencyOutlierAlgorithm");
|
|
8
11
|
class ApplicationLoadBalancerMetrics {
|
|
9
12
|
/**
|
|
10
13
|
* Gets the TargetResponseTime latency for the ALB
|
|
@@ -109,7 +112,7 @@ class ApplicationLoadBalancerMetrics {
|
|
|
109
112
|
usingMetrics[`${keyprefix}1`] = target5xx;
|
|
110
113
|
usingMetrics[`${keyprefix}2`] = elb5xx;
|
|
111
114
|
metrics.push(new aws_cloudwatch_1.MathExpression({
|
|
112
|
-
expression:
|
|
115
|
+
expression: `FILL(${keyprefix}1, 0) + FILL(${keyprefix}2, 0)`,
|
|
113
116
|
usingMetrics: usingMetrics,
|
|
114
117
|
label: props.availabilityZoneId + "-" + alb.loadBalancerArn + "-fault-count",
|
|
115
118
|
period: props.period,
|
|
@@ -180,7 +183,7 @@ class ApplicationLoadBalancerMetrics {
|
|
|
180
183
|
LoadBalancer: alb
|
|
181
184
|
.loadBalancerFullName,
|
|
182
185
|
},
|
|
183
|
-
label: props.availabilityZoneId
|
|
186
|
+
label: props.availabilityZoneId,
|
|
184
187
|
period: props.period,
|
|
185
188
|
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
186
189
|
unit: aws_cloudwatch_1.Unit.COUNT
|
|
@@ -224,7 +227,7 @@ class ApplicationLoadBalancerMetrics {
|
|
|
224
227
|
usingMetrics[`${keyprefix}1`] = target5xx;
|
|
225
228
|
usingMetrics[`${keyprefix}2`] = elb5xx;
|
|
226
229
|
return new aws_cloudwatch_1.MathExpression({
|
|
227
|
-
expression:
|
|
230
|
+
expression: `FILL(${keyprefix}1, 0) + FILL(${keyprefix}2, 0)`,
|
|
228
231
|
usingMetrics: usingMetrics,
|
|
229
232
|
label: props.label,
|
|
230
233
|
period: props.period,
|
|
@@ -338,7 +341,7 @@ class ApplicationLoadBalancerMetrics {
|
|
|
338
341
|
usingMetrics[`${keyprefix}1`] = target5xx;
|
|
339
342
|
usingMetrics[`${keyprefix}2`] = elb5xx;
|
|
340
343
|
return new aws_cloudwatch_1.MathExpression({
|
|
341
|
-
expression:
|
|
344
|
+
expression: `FILL(${keyprefix}1, 0) + FILL(${keyprefix}2, 0)`,
|
|
342
345
|
usingMetrics: usingMetrics,
|
|
343
346
|
label: props.label,
|
|
344
347
|
period: props.period,
|
|
@@ -388,7 +391,7 @@ class ApplicationLoadBalancerMetrics {
|
|
|
388
391
|
LoadBalancer: props.alb
|
|
389
392
|
.loadBalancerFullName,
|
|
390
393
|
},
|
|
391
|
-
label:
|
|
394
|
+
label: aws_cdk_lib_1.Aws.REGION,
|
|
392
395
|
period: props.period,
|
|
393
396
|
statistic: props.statistic,
|
|
394
397
|
unit: aws_cloudwatch_1.Unit.SECONDS
|
|
@@ -404,14 +407,13 @@ class ApplicationLoadBalancerMetrics {
|
|
|
404
407
|
static getTotalAlbFaultCountPerZone(albs, period, azMapper) {
|
|
405
408
|
let faultsPerZone = {};
|
|
406
409
|
let metricsPerAZ = {};
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
alb.vpc.availabilityZones.forEach((availabilityZone) => {
|
|
410
|
-
if (!(availabilityZone in metricsPerAZ)) {
|
|
411
|
-
metricsPerAZ[availabilityZone] = [];
|
|
412
|
-
}
|
|
410
|
+
albs.forEach((alb, albIndex) => {
|
|
411
|
+
alb.vpc.availabilityZones.forEach((availabilityZone, index) => {
|
|
413
412
|
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
414
413
|
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
414
|
+
if (!(azLetter in metricsPerAZ)) {
|
|
415
|
+
metricsPerAZ[azLetter] = [];
|
|
416
|
+
}
|
|
415
417
|
// 5xx responses from targets
|
|
416
418
|
let target5xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_5XX_COUNT, {
|
|
417
419
|
dimensionsMap: {
|
|
@@ -424,8 +426,85 @@ class ApplicationLoadBalancerMetrics {
|
|
|
424
426
|
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
425
427
|
unit: aws_cloudwatch_1.Unit.COUNT
|
|
426
428
|
});
|
|
427
|
-
|
|
428
|
-
|
|
429
|
+
let usingMetrics = {};
|
|
430
|
+
usingMetrics[`${azLetter}${albIndex}_faultcount`] = target5xx;
|
|
431
|
+
// This is the total number of faults per zone for this load balancer
|
|
432
|
+
metricsPerAZ[azLetter].push(new aws_cloudwatch_1.MathExpression({
|
|
433
|
+
expression: `FILL(${azLetter}${albIndex}_faultcount, 0)`,
|
|
434
|
+
usingMetrics: usingMetrics,
|
|
435
|
+
period: period,
|
|
436
|
+
label: availabilityZoneId,
|
|
437
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
438
|
+
}));
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
// We can have multiple load balancers per zone, so add their fault count
|
|
442
|
+
// metrics together
|
|
443
|
+
Object.keys(metricsPerAZ).forEach((azLetter, index) => {
|
|
444
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
445
|
+
if (metricsPerAZ[azLetter].length > 1) {
|
|
446
|
+
let usingMetrics = {};
|
|
447
|
+
metricsPerAZ[azLetter].forEach((metric, index) => {
|
|
448
|
+
usingMetrics[`${azLetter}${index}_total_faultcount`] = metric;
|
|
449
|
+
});
|
|
450
|
+
faultsPerZone[azLetter] = new aws_cloudwatch_1.MathExpression({
|
|
451
|
+
expression: Object.keys(usingMetrics).join("+"),
|
|
452
|
+
usingMetrics: usingMetrics,
|
|
453
|
+
label: availabilityZoneId,
|
|
454
|
+
period: period,
|
|
455
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
faultsPerZone[azLetter] = metricsPerAZ[azLetter][0];
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
return faultsPerZone;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Calculates the total number of faults for all ALBs combined per AZ
|
|
466
|
+
* @param albs The ALBs to aggregate
|
|
467
|
+
* @param period The period of time to calculate the metrics
|
|
468
|
+
* @param azMapper The AZ mapper function so the metrics are correctly labeled with their AZ ID
|
|
469
|
+
* @returns
|
|
470
|
+
*/
|
|
471
|
+
static getTotalAlbSuccessCountPerZone(albs, period, azMapper) {
|
|
472
|
+
let successPerZone = {};
|
|
473
|
+
let metricsPerAZ = {};
|
|
474
|
+
let keyprefix = MetricsHelper_1.MetricsHelper.nextChar();
|
|
475
|
+
albs.forEach((alb) => {
|
|
476
|
+
alb.vpc.availabilityZones.forEach((availabilityZone, index) => {
|
|
477
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
478
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
479
|
+
if (!(azLetter in metricsPerAZ)) {
|
|
480
|
+
metricsPerAZ[azLetter] = [];
|
|
481
|
+
}
|
|
482
|
+
// 2xx responses from targets
|
|
483
|
+
let target2xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_2XX_COUNT, {
|
|
484
|
+
dimensionsMap: {
|
|
485
|
+
AvailabilityZone: availabilityZone,
|
|
486
|
+
LoadBalancer: alb
|
|
487
|
+
.loadBalancerFullName,
|
|
488
|
+
},
|
|
489
|
+
label: availabilityZoneId,
|
|
490
|
+
period: period,
|
|
491
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
492
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
493
|
+
});
|
|
494
|
+
// 3xx responses from targets
|
|
495
|
+
let target3xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_3XX_COUNT, {
|
|
496
|
+
dimensionsMap: {
|
|
497
|
+
AvailabilityZone: availabilityZone,
|
|
498
|
+
LoadBalancer: alb
|
|
499
|
+
.loadBalancerFullName,
|
|
500
|
+
},
|
|
501
|
+
label: availabilityZoneId,
|
|
502
|
+
period: period,
|
|
503
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
504
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
505
|
+
});
|
|
506
|
+
// 3xx responses from ELB
|
|
507
|
+
let elb3xx = alb.metrics.httpCodeElb(aws_elasticloadbalancingv2_1.HttpCodeElb.ELB_3XX_COUNT, {
|
|
429
508
|
dimensionsMap: {
|
|
430
509
|
AvailabilityZone: availabilityZone,
|
|
431
510
|
LoadBalancer: alb
|
|
@@ -437,31 +516,454 @@ class ApplicationLoadBalancerMetrics {
|
|
|
437
516
|
unit: aws_cloudwatch_1.Unit.COUNT
|
|
438
517
|
});
|
|
439
518
|
let usingMetrics = {};
|
|
440
|
-
usingMetrics[`${keyprefix}1`] =
|
|
441
|
-
usingMetrics[`${keyprefix}2`] =
|
|
442
|
-
|
|
443
|
-
|
|
519
|
+
usingMetrics[`${keyprefix}1`] = elb3xx;
|
|
520
|
+
usingMetrics[`${keyprefix}2`] = target2xx;
|
|
521
|
+
usingMetrics[`${keyprefix}3`] = target3xx;
|
|
522
|
+
// This is the total number of faults per zone for this load balancer
|
|
523
|
+
metricsPerAZ[azLetter].push(new aws_cloudwatch_1.MathExpression({
|
|
524
|
+
expression: `FILL(${keyprefix}1, 0) + FILL(${keyprefix}2, 0) + FILL(${keyprefix}3, 0)`,
|
|
444
525
|
usingMetrics: usingMetrics,
|
|
445
|
-
period: period
|
|
526
|
+
period: period,
|
|
527
|
+
label: availabilityZoneId,
|
|
528
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
446
529
|
}));
|
|
447
530
|
keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
|
|
448
531
|
});
|
|
449
532
|
});
|
|
450
|
-
|
|
451
|
-
|
|
533
|
+
// We can have multiple load balancers per zone, so add their success count
|
|
534
|
+
// metrics together
|
|
535
|
+
Object.keys(metricsPerAZ).forEach((azLetter, index) => {
|
|
536
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
537
|
+
if (metricsPerAZ[azLetter].length > 1) {
|
|
538
|
+
let usingMetrics = {};
|
|
539
|
+
metricsPerAZ[azLetter].forEach((metric, index) => {
|
|
540
|
+
usingMetrics[`${keyprefix}${index}`] = metric;
|
|
541
|
+
});
|
|
542
|
+
successPerZone[azLetter] = new aws_cloudwatch_1.MathExpression({
|
|
543
|
+
expression: Object.keys(usingMetrics).join("+"),
|
|
544
|
+
usingMetrics: usingMetrics,
|
|
545
|
+
label: availabilityZoneId,
|
|
546
|
+
period: period,
|
|
547
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
successPerZone[azLetter] = metricsPerAZ[azLetter][0];
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
return successPerZone;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Calculates the total number of processed bytes for all ALBs in each zone
|
|
558
|
+
* @param albs
|
|
559
|
+
* @param period
|
|
560
|
+
* @param azMapper
|
|
561
|
+
* @returns
|
|
562
|
+
*/
|
|
563
|
+
static getTotalAlbRequestsPerZone(albs, period, azMapper) {
|
|
564
|
+
let requestsPerZone = {};
|
|
565
|
+
let metricsPerAZ = {};
|
|
566
|
+
albs.forEach((alb) => {
|
|
567
|
+
alb.vpc.availabilityZones.forEach((availabilityZone, index) => {
|
|
568
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
569
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
570
|
+
if (!(azLetter in metricsPerAZ)) {
|
|
571
|
+
metricsPerAZ[azLetter] = [];
|
|
572
|
+
}
|
|
573
|
+
let requestCount = alb.metrics.requestCount({
|
|
574
|
+
dimensionsMap: {
|
|
575
|
+
AvailabilityZone: availabilityZone,
|
|
576
|
+
LoadBalancer: alb
|
|
577
|
+
.loadBalancerFullName,
|
|
578
|
+
},
|
|
579
|
+
label: availabilityZoneId,
|
|
580
|
+
period: period,
|
|
581
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
582
|
+
unit: aws_cloudwatch_1.Unit.COUNT,
|
|
583
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
584
|
+
});
|
|
585
|
+
metricsPerAZ[azLetter].push(requestCount);
|
|
586
|
+
});
|
|
587
|
+
});
|
|
588
|
+
// We can have multiple load balancers per zone, so add their processed bytes together
|
|
589
|
+
Object.keys(metricsPerAZ).forEach((azLetter, index) => {
|
|
590
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
591
|
+
if (metricsPerAZ[azLetter].length > 1) {
|
|
592
|
+
let usingMetrics = {};
|
|
593
|
+
metricsPerAZ[azLetter].forEach((metric, index) => {
|
|
594
|
+
usingMetrics[`${azLetter}${index}`] = metric;
|
|
595
|
+
});
|
|
596
|
+
requestsPerZone[azLetter] = new aws_cloudwatch_1.MathExpression({
|
|
597
|
+
expression: Object.keys(usingMetrics).join("+"),
|
|
598
|
+
usingMetrics: usingMetrics,
|
|
599
|
+
label: availabilityZoneId,
|
|
600
|
+
period: period,
|
|
601
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
else {
|
|
605
|
+
requestsPerZone[azLetter] = metricsPerAZ[azLetter][0];
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
return requestsPerZone;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Calculates the total number of processed bytes for all ALBs in each zone
|
|
612
|
+
* @param albs
|
|
613
|
+
* @param period
|
|
614
|
+
* @param azMapper
|
|
615
|
+
* @returns
|
|
616
|
+
*/
|
|
617
|
+
static getTotalAlbProcessedBytesPerZone(albs, period, azMapper) {
|
|
618
|
+
let processedBytesPerZone = {};
|
|
619
|
+
let metricsPerAZ = {};
|
|
620
|
+
let keyprefix = MetricsHelper_1.MetricsHelper.nextChar();
|
|
621
|
+
albs.forEach((alb) => {
|
|
622
|
+
alb.vpc.availabilityZones.forEach((availabilityZone, index) => {
|
|
623
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
624
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
625
|
+
if (!(azLetter in metricsPerAZ)) {
|
|
626
|
+
metricsPerAZ[azLetter] = [];
|
|
627
|
+
}
|
|
628
|
+
let processedBytes = alb.metrics.processedBytes({
|
|
629
|
+
dimensionsMap: {
|
|
630
|
+
AvailabilityZone: availabilityZone,
|
|
631
|
+
LoadBalancer: alb
|
|
632
|
+
.loadBalancerFullName,
|
|
633
|
+
},
|
|
634
|
+
label: availabilityZoneId,
|
|
635
|
+
period: period,
|
|
636
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
637
|
+
unit: aws_cloudwatch_1.Unit.COUNT,
|
|
638
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
639
|
+
});
|
|
640
|
+
metricsPerAZ[azLetter].push(processedBytes);
|
|
641
|
+
});
|
|
642
|
+
});
|
|
643
|
+
// We can have multiple load balancers per zone, so add their processed bytes together
|
|
644
|
+
Object.keys(metricsPerAZ).forEach((azLetter, index) => {
|
|
645
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
646
|
+
if (metricsPerAZ[azLetter].length > 1) {
|
|
647
|
+
let usingMetrics = {};
|
|
648
|
+
metricsPerAZ[azLetter].forEach((metric, index) => {
|
|
649
|
+
usingMetrics[`${keyprefix}${index}`] = metric;
|
|
650
|
+
});
|
|
651
|
+
keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
|
|
652
|
+
processedBytesPerZone[azLetter] = new aws_cloudwatch_1.MathExpression({
|
|
653
|
+
expression: Object.keys(usingMetrics).join("+"),
|
|
654
|
+
usingMetrics: usingMetrics,
|
|
655
|
+
label: availabilityZoneId,
|
|
656
|
+
period: period,
|
|
657
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
else {
|
|
661
|
+
processedBytesPerZone[azLetter] = metricsPerAZ[azLetter][0];
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
return processedBytesPerZone;
|
|
665
|
+
}
|
|
666
|
+
static getTotalAnomalousHostCountPerZone(albs, period, azMapper) {
|
|
667
|
+
let anomalousHostsPerZone = {};
|
|
668
|
+
let metricsPerAZ = {};
|
|
669
|
+
albs.forEach((alb) => {
|
|
670
|
+
alb.vpc.availabilityZones.forEach((availabilityZone, index) => {
|
|
671
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
672
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
673
|
+
if (!(azLetter in metricsPerAZ)) {
|
|
674
|
+
metricsPerAZ[azLetter] = [];
|
|
675
|
+
}
|
|
676
|
+
let anomalousHostCount = new aws_cloudwatch_1.Metric({
|
|
677
|
+
namespace: "AWS/ApplicationELB",
|
|
678
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
679
|
+
metricName: "AnomalousHostCount",
|
|
680
|
+
dimensionsMap: {
|
|
681
|
+
AvailabilityZone: availabilityZone,
|
|
682
|
+
LoadBalancer: alb
|
|
683
|
+
.loadBalancerFullName,
|
|
684
|
+
},
|
|
685
|
+
label: availabilityZoneId,
|
|
686
|
+
unit: aws_cloudwatch_1.Unit.COUNT,
|
|
687
|
+
color: MetricsHelper_1.MetricsHelper.colors[index],
|
|
688
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
689
|
+
period: period
|
|
690
|
+
});
|
|
691
|
+
metricsPerAZ[azLetter].push(anomalousHostCount);
|
|
692
|
+
});
|
|
693
|
+
});
|
|
694
|
+
// We can have multiple load balancers per zone, so add their counts together
|
|
695
|
+
Object.keys(metricsPerAZ).forEach((azLetter, index) => {
|
|
696
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
697
|
+
if (metricsPerAZ[azLetter].length > 1) {
|
|
698
|
+
let usingMetrics = {};
|
|
699
|
+
metricsPerAZ[azLetter].forEach((metric, metricIndex) => {
|
|
700
|
+
usingMetrics[`${azLetter}${metricIndex}`] = metric;
|
|
701
|
+
});
|
|
702
|
+
anomalousHostsPerZone[azLetter] = new aws_cloudwatch_1.MathExpression({
|
|
703
|
+
expression: Object.keys(usingMetrics).join("+") + " + TIME_SERIES(0)",
|
|
704
|
+
usingMetrics: usingMetrics,
|
|
705
|
+
label: availabilityZoneId,
|
|
706
|
+
period: period,
|
|
707
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
else {
|
|
711
|
+
let usingMetrics = {};
|
|
712
|
+
usingMetrics[azLetter] = metricsPerAZ[azLetter][0];
|
|
713
|
+
anomalousHostsPerZone[azLetter] = new aws_cloudwatch_1.MathExpression({
|
|
714
|
+
expression: `FILL(${azLetter}, 0)`,
|
|
715
|
+
usingMetrics: usingMetrics,
|
|
716
|
+
label: availabilityZoneId,
|
|
717
|
+
period: period,
|
|
718
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
return anomalousHostsPerZone;
|
|
723
|
+
}
|
|
724
|
+
static getTotalMitigatedHostCountPerZone(albs, period, azMapper) {
|
|
725
|
+
let mitigatedHostsPerZone = {};
|
|
726
|
+
let metricsPerAZ = {};
|
|
727
|
+
albs.forEach((alb) => {
|
|
728
|
+
alb.vpc.availabilityZones.forEach((availabilityZone, index) => {
|
|
729
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
730
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
731
|
+
if (!(azLetter in metricsPerAZ)) {
|
|
732
|
+
metricsPerAZ[azLetter] = [];
|
|
733
|
+
}
|
|
734
|
+
let mitigatedHostCount = new aws_cloudwatch_1.Metric({
|
|
735
|
+
namespace: "AWS/ApplicationELB",
|
|
736
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
737
|
+
metricName: "MitigatedHostCount",
|
|
738
|
+
dimensionsMap: {
|
|
739
|
+
AvailabilityZone: availabilityZone,
|
|
740
|
+
LoadBalancer: alb
|
|
741
|
+
.loadBalancerFullName,
|
|
742
|
+
},
|
|
743
|
+
label: availabilityZoneId,
|
|
744
|
+
unit: aws_cloudwatch_1.Unit.COUNT,
|
|
745
|
+
color: MetricsHelper_1.MetricsHelper.colors[index],
|
|
746
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
747
|
+
period: period
|
|
748
|
+
});
|
|
749
|
+
metricsPerAZ[azLetter].push(mitigatedHostCount);
|
|
750
|
+
});
|
|
751
|
+
});
|
|
752
|
+
// We can have multiple load balancers per zone, so add their counts together
|
|
753
|
+
Object.keys(metricsPerAZ).forEach((azLetter, index) => {
|
|
452
754
|
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
755
|
+
if (metricsPerAZ[azLetter].length > 1) {
|
|
756
|
+
let usingMetrics = {};
|
|
757
|
+
metricsPerAZ[azLetter].forEach((metric, metricIndex) => {
|
|
758
|
+
usingMetrics[`${azLetter}${metricIndex}`] = metric;
|
|
759
|
+
});
|
|
760
|
+
mitigatedHostsPerZone[azLetter] = new aws_cloudwatch_1.MathExpression({
|
|
761
|
+
expression: Object.keys(usingMetrics).join("+") + " + TIME_SERIES(0)",
|
|
762
|
+
usingMetrics: usingMetrics,
|
|
763
|
+
label: availabilityZoneId,
|
|
764
|
+
period: period,
|
|
765
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
else {
|
|
769
|
+
let usingMetrics = {};
|
|
770
|
+
usingMetrics[azLetter] = metricsPerAZ[azLetter][0];
|
|
771
|
+
mitigatedHostsPerZone[azLetter] = new aws_cloudwatch_1.MathExpression({
|
|
772
|
+
expression: `FILL(${azLetter}, 0)`,
|
|
773
|
+
usingMetrics: usingMetrics,
|
|
774
|
+
label: availabilityZoneId,
|
|
775
|
+
period: period,
|
|
776
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
return mitigatedHostsPerZone;
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Calculates a weighted approximation of the latency at the provided statistic for all ALBs
|
|
784
|
+
* in each zone.
|
|
785
|
+
* @param albs
|
|
786
|
+
* @param statistic
|
|
787
|
+
* @param period
|
|
788
|
+
* @param azMapper
|
|
789
|
+
* @returns
|
|
790
|
+
*/
|
|
791
|
+
static getTotalAlbLatencyPerZone(albs, statistic, period, azMapper) {
|
|
792
|
+
let latencyPerZonePerAlb = {};
|
|
793
|
+
albs.forEach((alb) => {
|
|
794
|
+
alb.vpc.availabilityZones.forEach((availabilityZone) => {
|
|
795
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
796
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
797
|
+
if (!(availabilityZone in latencyPerZonePerAlb)) {
|
|
798
|
+
latencyPerZonePerAlb[availabilityZone] = [];
|
|
799
|
+
}
|
|
800
|
+
let latency = alb.metrics.targetResponseTime({
|
|
801
|
+
dimensionsMap: {
|
|
802
|
+
AvailabilityZone: availabilityZone,
|
|
803
|
+
LoadBalancer: alb
|
|
804
|
+
.loadBalancerFullName,
|
|
805
|
+
},
|
|
806
|
+
label: availabilityZoneId,
|
|
807
|
+
period: period,
|
|
808
|
+
statistic: statistic,
|
|
809
|
+
unit: aws_cloudwatch_1.Unit.SECONDS
|
|
810
|
+
});
|
|
811
|
+
let requestCount = alb.metrics.requestCount({
|
|
812
|
+
dimensionsMap: {
|
|
813
|
+
AvailabilityZone: availabilityZone,
|
|
814
|
+
LoadBalancer: alb
|
|
815
|
+
.loadBalancerFullName,
|
|
816
|
+
},
|
|
817
|
+
label: availabilityZoneId,
|
|
818
|
+
period: period,
|
|
819
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
820
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
821
|
+
});
|
|
822
|
+
latencyPerZonePerAlb[availabilityZone].push({ "latency": latency, "requests": requestCount });
|
|
823
|
+
});
|
|
824
|
+
});
|
|
825
|
+
/**
|
|
826
|
+
* We want to calculate this formula
|
|
827
|
+
*
|
|
828
|
+
* (((p99_1 * requests_1) + (p99_2 * requests_2) + (p99_3 * requests_3)) / (requests_1 + requests_2 + requests_3)) * 1000
|
|
829
|
+
*
|
|
830
|
+
* This will provide a request weighted approximation of the p99
|
|
831
|
+
* latency per AZ
|
|
832
|
+
*/
|
|
833
|
+
let latencyPerZone = {};
|
|
834
|
+
Object.keys(latencyPerZonePerAlb).forEach((availabiltityZone, index) => {
|
|
835
|
+
let requestKeys = [];
|
|
836
|
+
let latencyKeys = [];
|
|
453
837
|
let usingMetrics = {};
|
|
454
|
-
|
|
455
|
-
|
|
838
|
+
let azLetter = availabiltityZone.substring(availabiltityZone.length - 1);
|
|
839
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
840
|
+
latencyPerZonePerAlb[availabiltityZone].forEach((metric, index) => {
|
|
841
|
+
usingMetrics[`${azLetter}${index}_requests`] = metric["requests"];
|
|
842
|
+
usingMetrics[`${azLetter}${index}_latency`] = metric["latency"];
|
|
843
|
+
requestKeys.push(`${azLetter}${index}_requests`);
|
|
844
|
+
latencyKeys.push(`(${azLetter}${index}_latency * ${azLetter}${index}_requests)`);
|
|
456
845
|
});
|
|
457
|
-
|
|
458
|
-
expression:
|
|
846
|
+
latencyPerZone[availabiltityZone] = new aws_cloudwatch_1.MathExpression({
|
|
847
|
+
expression: `((${latencyKeys.join("+")}) / (${requestKeys.join("+")})) * 1000`, // Converts the calculation to milliseconds
|
|
459
848
|
usingMetrics: usingMetrics,
|
|
460
|
-
label: availabilityZoneId
|
|
461
|
-
period: period
|
|
849
|
+
label: availabilityZoneId,
|
|
850
|
+
period: period,
|
|
851
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
462
852
|
});
|
|
463
853
|
});
|
|
464
|
-
return
|
|
854
|
+
return latencyPerZone;
|
|
855
|
+
}
|
|
856
|
+
static getWeightedLatencyZScorePerZone(albs, statistic, period, azMapper) {
|
|
857
|
+
let weightedLatency = this.getTotalAlbLatencyPerZone(albs, statistic, period, azMapper);
|
|
858
|
+
let zscore = {};
|
|
859
|
+
// Rename the metric keys to the AZ letter to use in the metrics equations
|
|
860
|
+
let updatedMetrics = {};
|
|
861
|
+
Object.keys(weightedLatency).forEach((availabilityZone) => {
|
|
862
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
863
|
+
updatedMetrics[azLetter] = weightedLatency[availabilityZone];
|
|
864
|
+
});
|
|
865
|
+
Object.keys(weightedLatency).forEach((availabilityZone, index) => {
|
|
866
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
867
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
868
|
+
zscore[availabilityZone] = new aws_cloudwatch_1.MathExpression({
|
|
869
|
+
expression: `(${azLetter} - AVG([${Object.keys(updatedMetrics).filter(x => x != azLetter).join(",")}])) / STDDEV([${Object.keys(updatedMetrics).filter(x => x != azLetter).join(",")}])`,
|
|
870
|
+
usingMetrics: updatedMetrics,
|
|
871
|
+
label: availabilityZoneId,
|
|
872
|
+
period: period,
|
|
873
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
874
|
+
});
|
|
875
|
+
});
|
|
876
|
+
return zscore;
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Calculates the fault rate per AZ
|
|
880
|
+
* @param requestsPerZone
|
|
881
|
+
* @param faultsPerZone
|
|
882
|
+
* @param period
|
|
883
|
+
* @param azMapper
|
|
884
|
+
* @returns The fault rate per AZ using the AZ name letter as the key for each metric
|
|
885
|
+
*/
|
|
886
|
+
static getTotalAlbFaultRatePerZone(albs, period, azMapper) {
|
|
887
|
+
let faultRateMetrics = {};
|
|
888
|
+
let requestsPerZone = this.getTotalAlbRequestsPerZone(albs, period, azMapper);
|
|
889
|
+
let faultsPerZone = this.getTotalAlbFaultCountPerZone(albs, period, azMapper);
|
|
890
|
+
Object.keys(requestsPerZone).forEach((key, index) => {
|
|
891
|
+
if (key in faultsPerZone) {
|
|
892
|
+
let usingMetrics = {};
|
|
893
|
+
let keyprefix = 'z' + key;
|
|
894
|
+
usingMetrics[`${keyprefix}1`] = faultsPerZone[key];
|
|
895
|
+
usingMetrics[`${keyprefix}2`] = requestsPerZone[key];
|
|
896
|
+
let zonalFaultRate = new aws_cloudwatch_1.MathExpression({
|
|
897
|
+
expression: `(${keyprefix}1/${keyprefix}2) * 100`,
|
|
898
|
+
usingMetrics: usingMetrics,
|
|
899
|
+
period: period,
|
|
900
|
+
label: azMapper.availabilityZoneIdFromAvailabilityZoneLetter(key),
|
|
901
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
902
|
+
});
|
|
903
|
+
faultRateMetrics[key] = zonalFaultRate;
|
|
904
|
+
}
|
|
905
|
+
else {
|
|
906
|
+
throw new Error("The zone " + key + " is not present in the faultsPerZone parameter.");
|
|
907
|
+
}
|
|
908
|
+
});
|
|
909
|
+
Object.keys(faultsPerZone).forEach((key) => {
|
|
910
|
+
if (!(key in requestsPerZone)) {
|
|
911
|
+
throw new Error("The zone " + key + " is not present in the requestsPerZone parameter.");
|
|
912
|
+
}
|
|
913
|
+
});
|
|
914
|
+
return faultRateMetrics;
|
|
915
|
+
}
|
|
916
|
+
static getTotalAlb5xxCountPerZone(albs, period, azMapper) {
|
|
917
|
+
let faultsPerZone = {};
|
|
918
|
+
let aggregateFaultsPerZone = {};
|
|
919
|
+
albs.forEach((alb) => {
|
|
920
|
+
alb.vpc?.availabilityZones.forEach((availabilityZone) => {
|
|
921
|
+
if (!(availabilityZone in faultsPerZone)) {
|
|
922
|
+
faultsPerZone[availabilityZone] = [];
|
|
923
|
+
}
|
|
924
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
925
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
926
|
+
let elb5xx = alb.metrics.httpCodeElb(aws_elasticloadbalancingv2_1.HttpCodeElb.ELB_5XX_COUNT, {
|
|
927
|
+
dimensionsMap: {
|
|
928
|
+
AvailabilityZone: availabilityZone,
|
|
929
|
+
LoadBalancer: alb
|
|
930
|
+
.loadBalancerFullName,
|
|
931
|
+
},
|
|
932
|
+
label: availabilityZoneId,
|
|
933
|
+
period: period,
|
|
934
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
935
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
936
|
+
});
|
|
937
|
+
faultsPerZone[availabilityZone].push(elb5xx);
|
|
938
|
+
});
|
|
939
|
+
});
|
|
940
|
+
Object.keys(faultsPerZone).forEach((availabilityZone, index) => {
|
|
941
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
942
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
943
|
+
let usingMetrics = {};
|
|
944
|
+
if (faultsPerZone[availabilityZone].length > 1) {
|
|
945
|
+
faultsPerZone[availabilityZone].forEach((metric, faultIndex) => {
|
|
946
|
+
usingMetrics[`${azLetter}${faultIndex}`] = metric;
|
|
947
|
+
});
|
|
948
|
+
aggregateFaultsPerZone[availabilityZone] = new aws_cloudwatch_1.MathExpression({
|
|
949
|
+
expression: Object.keys(usingMetrics).join("+") + " + TIME_SERIES(0)",
|
|
950
|
+
usingMetrics: usingMetrics,
|
|
951
|
+
color: MetricsHelper_1.MetricsHelper.colors[index],
|
|
952
|
+
label: availabilityZoneId
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
else {
|
|
956
|
+
let usingMetrics = {};
|
|
957
|
+
usingMetrics[azLetter] = faultsPerZone[availabilityZone][0];
|
|
958
|
+
aggregateFaultsPerZone[availabilityZone] = new aws_cloudwatch_1.MathExpression({
|
|
959
|
+
expression: `FILL(${azLetter}, 0)`,
|
|
960
|
+
usingMetrics: usingMetrics,
|
|
961
|
+
color: MetricsHelper_1.MetricsHelper.colors[index],
|
|
962
|
+
label: availabilityZoneId
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
});
|
|
966
|
+
return aggregateFaultsPerZone;
|
|
465
967
|
}
|
|
466
968
|
/**
|
|
467
969
|
* Creates a zonal processed bytes metric for the specified load balancer
|
|
@@ -470,14 +972,14 @@ class ApplicationLoadBalancerMetrics {
|
|
|
470
972
|
* @param period
|
|
471
973
|
* @returns IMetric
|
|
472
974
|
*/
|
|
473
|
-
static getPerAZProcessedBytesMetric(alb, availabilityZone, availabilityZoneId, period) {
|
|
975
|
+
static getPerAZProcessedBytesMetric(alb, availabilityZone, availabilityZoneId, period, addLoadBalancerArnToLabel) {
|
|
474
976
|
return alb.metrics.processedBytes({
|
|
475
977
|
period: period,
|
|
476
978
|
dimensionsMap: {
|
|
477
979
|
LoadBalancer: alb.loadBalancerFullName,
|
|
478
980
|
AvailabilityZone: availabilityZone,
|
|
479
981
|
},
|
|
480
|
-
label: availabilityZoneId + "-" + alb.loadBalancerArn
|
|
982
|
+
label: availabilityZoneId + (addLoadBalancerArnToLabel ? "-" + alb.loadBalancerArn : "")
|
|
481
983
|
});
|
|
482
984
|
}
|
|
483
985
|
/**
|
|
@@ -487,15 +989,294 @@ class ApplicationLoadBalancerMetrics {
|
|
|
487
989
|
* @param period
|
|
488
990
|
* @returns IMetric
|
|
489
991
|
*/
|
|
490
|
-
static getRegionalProcessedBytesMetric(alb, period) {
|
|
992
|
+
static getRegionalProcessedBytesMetric(alb, period, addLoadBalancerArn) {
|
|
491
993
|
return alb.metrics.processedBytes({
|
|
492
994
|
period: period,
|
|
493
995
|
dimensionsMap: {
|
|
494
996
|
LoadBalancer: alb.loadBalancerFullName,
|
|
495
997
|
},
|
|
496
|
-
label:
|
|
998
|
+
label: aws_cdk_lib_1.Aws.REGION + (addLoadBalancerArn ? "-" + alb.loadBalancerArn : "")
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
static createAZAvailabilityImpactAlarm(scope, alb, availabilityZoneId, availabilityZone, threshold, keyprefix, period, evaluationPeriods, datapointsToAlarm) {
|
|
1002
|
+
// Create a fault rate alarm for the ALB in the specified AZ
|
|
1003
|
+
return new aws_cloudwatch_1.Alarm(scope, keyprefix + '-fault-rate-alarm', {
|
|
1004
|
+
alarmName: availabilityZoneId + '-' + alb.loadBalancerArn + '-fault-rate',
|
|
1005
|
+
actionsEnabled: false,
|
|
1006
|
+
metric: ApplicationLoadBalancerMetrics.getPerAZAvailabilityMetric(alb, {
|
|
1007
|
+
period: period,
|
|
1008
|
+
label: availabilityZoneId + '-' + alb.loadBalancerArn + '-fault-rate',
|
|
1009
|
+
availabilityZone: availabilityZone,
|
|
1010
|
+
availabilityZoneId: availabilityZoneId,
|
|
1011
|
+
metricType: AvailabilityMetricType_1.AvailabilityMetricType.FAULT_RATE
|
|
1012
|
+
}),
|
|
1013
|
+
evaluationPeriods: evaluationPeriods,
|
|
1014
|
+
datapointsToAlarm: datapointsToAlarm,
|
|
1015
|
+
threshold: threshold,
|
|
1016
|
+
comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
1017
|
+
treatMissingData: aws_cloudwatch_1.TreatMissingData.IGNORE
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
static createAZLatencyImpactAlarm(scope, alb, availabilityZoneId, availabilityZone, threshold, statistic, keyprefix, period, evaluationPeriods, datapointsToAlarm) {
|
|
1021
|
+
// Create a fault rate alarm for the ALB in the specified AZ
|
|
1022
|
+
return new aws_cloudwatch_1.Alarm(scope, keyprefix + '-latency-alarm', {
|
|
1023
|
+
alarmName: availabilityZoneId + '-' + alb.loadBalancerArn + '-latency',
|
|
1024
|
+
actionsEnabled: false,
|
|
1025
|
+
metric: ApplicationLoadBalancerMetrics.getPerAZLatencyMetric({
|
|
1026
|
+
alb: alb,
|
|
1027
|
+
availabilityZone: availabilityZone,
|
|
1028
|
+
availabilityZoneId: availabilityZoneId,
|
|
1029
|
+
label: availabilityZoneId + "-" + alb.loadBalancerArn + "-target-latency",
|
|
1030
|
+
period: period,
|
|
1031
|
+
statistic: statistic
|
|
1032
|
+
}),
|
|
1033
|
+
evaluationPeriods: evaluationPeriods,
|
|
1034
|
+
datapointsToAlarm: datapointsToAlarm,
|
|
1035
|
+
threshold: threshold.toSeconds({ integral: false }), // ALB latency is measured in seconds
|
|
1036
|
+
comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
1037
|
+
treatMissingData: aws_cloudwatch_1.TreatMissingData.IGNORE
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
static createAZAvailabilityOutlierAlarm(scope, alb, algorithm, availabilityZoneId, availabilityZone, threshold, keyprefix, period, evaluationPeriods, datapointsToAlarm) {
|
|
1041
|
+
let usingMetrics = {};
|
|
1042
|
+
let azMetricId = "";
|
|
1043
|
+
alb.vpc.availabilityZones.forEach((az) => {
|
|
1044
|
+
let azFaultCount = ApplicationLoadBalancerMetrics.getPerAZAvailabilityMetric(alb, {
|
|
1045
|
+
metricType: AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT,
|
|
1046
|
+
availabilityZone: availabilityZone,
|
|
1047
|
+
availabilityZoneId: availabilityZoneId,
|
|
1048
|
+
period: period,
|
|
1049
|
+
label: availabilityZoneId + "-" + alb.loadBalancerArn + "-fault-count",
|
|
1050
|
+
keyprefix: keyprefix
|
|
1051
|
+
});
|
|
1052
|
+
keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
|
|
1053
|
+
usingMetrics[`${keyprefix}1`] = azFaultCount;
|
|
1054
|
+
if (az == availabilityZone) {
|
|
1055
|
+
azMetricId = `${keyprefix}1`;
|
|
1056
|
+
}
|
|
1057
|
+
keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
|
|
497
1058
|
});
|
|
1059
|
+
switch (algorithm) {
|
|
1060
|
+
case ApplicationLoadBalancerAvailabilityOutlierAlgorithm_1.ApplicationLoadBalancerAvailabilityOutlierAlgorithm.STATIC:
|
|
1061
|
+
default:
|
|
1062
|
+
return new aws_cloudwatch_1.Alarm(scope, keyprefix + '-availability-outlier-alarm', {
|
|
1063
|
+
alarmName: availabilityZoneId + '-' + alb.loadBalancerArn + '-availability-impact-outlier',
|
|
1064
|
+
actionsEnabled: false,
|
|
1065
|
+
metric: new aws_cloudwatch_1.MathExpression({
|
|
1066
|
+
expression: `(${azMetricId}/(${Object.keys(usingMetrics).join("+")})) * 100`,
|
|
1067
|
+
usingMetrics: usingMetrics,
|
|
1068
|
+
label: availabilityZoneId + '-' + alb.loadBalancerArn + '-percent-of-faults',
|
|
1069
|
+
period: period,
|
|
1070
|
+
}),
|
|
1071
|
+
evaluationPeriods: evaluationPeriods,
|
|
1072
|
+
datapointsToAlarm: datapointsToAlarm,
|
|
1073
|
+
threshold: threshold,
|
|
1074
|
+
comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
|
|
1075
|
+
treatMissingData: aws_cloudwatch_1.TreatMissingData.IGNORE
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
static createAZLatencyOutlierAlarm(scope, alb, algorithm, availabilityZone, statistic, latencyThresold, outlierThreshold, period, evaluationPeriods, datapointsToAlarm, azMapper) {
|
|
1080
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
1081
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
1082
|
+
switch (algorithm) {
|
|
1083
|
+
case ApplicationLoadBalancerLatencyOutlierAlgorithm_1.ApplicationLoadBalancerLatencyOutlierAlgorithm.Z_SCORE:
|
|
1084
|
+
default:
|
|
1085
|
+
let weightedLatencyZScorePerZone = ApplicationLoadBalancerMetrics.getWeightedLatencyZScorePerZone([alb], statistic, period, azMapper);
|
|
1086
|
+
return new aws_cloudwatch_1.Alarm(scope, azLetter + "-latency-outlier-alarm", {
|
|
1087
|
+
alarmName: availabilityZoneId + '-' + alb.loadBalancerArn + '-latency-impact-outlier',
|
|
1088
|
+
actionsEnabled: false,
|
|
1089
|
+
metric: weightedLatencyZScorePerZone[availabilityZone],
|
|
1090
|
+
evaluationPeriods: evaluationPeriods,
|
|
1091
|
+
datapointsToAlarm: datapointsToAlarm,
|
|
1092
|
+
threshold: outlierThreshold,
|
|
1093
|
+
comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
|
|
1094
|
+
treatMissingData: aws_cloudwatch_1.TreatMissingData.IGNORE
|
|
1095
|
+
});
|
|
1096
|
+
case ApplicationLoadBalancerLatencyOutlierAlgorithm_1.ApplicationLoadBalancerLatencyOutlierAlgorithm.STATIC:
|
|
1097
|
+
let usingMetrics = {};
|
|
1098
|
+
alb.vpc.availabilityZones.forEach((az) => {
|
|
1099
|
+
let azLetter = az.substring(az.length - 1);
|
|
1100
|
+
let azId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
1101
|
+
// Target response time
|
|
1102
|
+
let targetResponseTime = ApplicationLoadBalancerMetrics.getPerAZLatencyMetric({
|
|
1103
|
+
alb: alb,
|
|
1104
|
+
availabilityZone: az,
|
|
1105
|
+
label: azId,
|
|
1106
|
+
statistic: `TC(${MetricsHelper_1.MetricsHelper.convertDurationByUnit(latencyThresold, aws_cloudwatch_1.Unit.SECONDS)}:)`,
|
|
1107
|
+
period: period
|
|
1108
|
+
});
|
|
1109
|
+
usingMetrics[`${azLetter}`] = targetResponseTime;
|
|
1110
|
+
});
|
|
1111
|
+
return new aws_cloudwatch_1.Alarm(scope, azLetter + "-latency-outlier-alarm", {
|
|
1112
|
+
alarmName: availabilityZoneId + '-' + alb.loadBalancerArn + '-latency-impact-outlier',
|
|
1113
|
+
actionsEnabled: false,
|
|
1114
|
+
metric: new aws_cloudwatch_1.MathExpression({
|
|
1115
|
+
expression: `(${azLetter}/(${Object.keys(usingMetrics).join("+")})) * 100`,
|
|
1116
|
+
usingMetrics: usingMetrics,
|
|
1117
|
+
label: availabilityZoneId,
|
|
1118
|
+
period: period,
|
|
1119
|
+
}),
|
|
1120
|
+
evaluationPeriods: evaluationPeriods,
|
|
1121
|
+
datapointsToAlarm: datapointsToAlarm,
|
|
1122
|
+
threshold: outlierThreshold,
|
|
1123
|
+
comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
|
|
1124
|
+
treatMissingData: aws_cloudwatch_1.TreatMissingData.IGNORE
|
|
1125
|
+
});
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
static generateLoadBalancerWidgets(albs, azMapper, period, latencyStatistic, latencyThreshold, faultRateThreshold) {
|
|
1129
|
+
let albWidgets = [];
|
|
1130
|
+
let successCountPerZone = ApplicationLoadBalancerMetrics.getTotalAlbSuccessCountPerZone(albs, period, azMapper);
|
|
1131
|
+
let faultCountPerZone = ApplicationLoadBalancerMetrics.getTotalAlbFaultCountPerZone(albs, period, azMapper);
|
|
1132
|
+
let processedBytesPerZone = ApplicationLoadBalancerMetrics.getTotalAlbProcessedBytesPerZone(albs, period, azMapper);
|
|
1133
|
+
let latencyPerZone = ApplicationLoadBalancerMetrics.getTotalAlbLatencyPerZone(albs, latencyStatistic, period, azMapper);
|
|
1134
|
+
let requestsPerZone = ApplicationLoadBalancerMetrics.getTotalAlbRequestsPerZone(albs, period, azMapper);
|
|
1135
|
+
let faultRatePerZone = ApplicationLoadBalancerMetrics.getTotalAlbFaultRatePerZone(albs, period, azMapper);
|
|
1136
|
+
let weightedLatencyZScorePerZone = ApplicationLoadBalancerMetrics.getWeightedLatencyZScorePerZone(albs, latencyStatistic, period, azMapper);
|
|
1137
|
+
albWidgets.push(new aws_cloudwatch_1.GraphWidget({
|
|
1138
|
+
height: 8,
|
|
1139
|
+
width: 8,
|
|
1140
|
+
title: "Success Count",
|
|
1141
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
1142
|
+
left: Object.values(successCountPerZone),
|
|
1143
|
+
leftYAxis: {
|
|
1144
|
+
min: 0,
|
|
1145
|
+
label: 'Count',
|
|
1146
|
+
showUnits: false,
|
|
1147
|
+
}
|
|
1148
|
+
}));
|
|
1149
|
+
albWidgets.push(new aws_cloudwatch_1.GraphWidget({
|
|
1150
|
+
height: 8,
|
|
1151
|
+
width: 8,
|
|
1152
|
+
title: "Target 5xx Count",
|
|
1153
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
1154
|
+
left: Object.values(faultCountPerZone),
|
|
1155
|
+
leftYAxis: {
|
|
1156
|
+
min: 0,
|
|
1157
|
+
label: 'Count',
|
|
1158
|
+
showUnits: false,
|
|
1159
|
+
}
|
|
1160
|
+
}));
|
|
1161
|
+
albWidgets.push(new aws_cloudwatch_1.GraphWidget({
|
|
1162
|
+
height: 8,
|
|
1163
|
+
width: 8,
|
|
1164
|
+
title: "ELB 5xx Count",
|
|
1165
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
1166
|
+
left: Object.values(this.getTotalAlb5xxCountPerZone(albs, period, azMapper)),
|
|
1167
|
+
leftYAxis: {
|
|
1168
|
+
min: 0,
|
|
1169
|
+
label: 'Count',
|
|
1170
|
+
showUnits: false,
|
|
1171
|
+
}
|
|
1172
|
+
}));
|
|
1173
|
+
albWidgets.push(new aws_cloudwatch_1.GraphWidget({
|
|
1174
|
+
height: 8,
|
|
1175
|
+
width: 8,
|
|
1176
|
+
title: "Request Count",
|
|
1177
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
1178
|
+
left: Object.values(requestsPerZone),
|
|
1179
|
+
leftYAxis: {
|
|
1180
|
+
min: 0,
|
|
1181
|
+
label: 'Count',
|
|
1182
|
+
showUnits: false,
|
|
1183
|
+
}
|
|
1184
|
+
}));
|
|
1185
|
+
albWidgets.push(new aws_cloudwatch_1.GraphWidget({
|
|
1186
|
+
height: 8,
|
|
1187
|
+
width: 8,
|
|
1188
|
+
title: "Fault Rate",
|
|
1189
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
1190
|
+
left: Object.values(faultRatePerZone),
|
|
1191
|
+
leftYAxis: {
|
|
1192
|
+
min: 0,
|
|
1193
|
+
label: 'Percent',
|
|
1194
|
+
showUnits: false,
|
|
1195
|
+
},
|
|
1196
|
+
leftAnnotations: [
|
|
1197
|
+
{
|
|
1198
|
+
label: "High Severity",
|
|
1199
|
+
value: faultRateThreshold,
|
|
1200
|
+
color: aws_cloudwatch_1.Color.RED
|
|
1201
|
+
}
|
|
1202
|
+
]
|
|
1203
|
+
}));
|
|
1204
|
+
albWidgets.push(new aws_cloudwatch_1.GraphWidget({
|
|
1205
|
+
height: 8,
|
|
1206
|
+
width: 8,
|
|
1207
|
+
title: "Processed Bytes",
|
|
1208
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
1209
|
+
left: Object.values(processedBytesPerZone),
|
|
1210
|
+
leftYAxis: {
|
|
1211
|
+
min: 0,
|
|
1212
|
+
showUnits: false,
|
|
1213
|
+
label: 'Bytes'
|
|
1214
|
+
}
|
|
1215
|
+
}));
|
|
1216
|
+
albWidgets.push(new aws_cloudwatch_1.GraphWidget({
|
|
1217
|
+
height: 8,
|
|
1218
|
+
width: 8,
|
|
1219
|
+
title: `Target Response Time (${latencyStatistic})`,
|
|
1220
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
1221
|
+
left: Object.values(latencyPerZone),
|
|
1222
|
+
leftYAxis: {
|
|
1223
|
+
min: 0,
|
|
1224
|
+
label: "Milliseconds",
|
|
1225
|
+
showUnits: false,
|
|
1226
|
+
},
|
|
1227
|
+
leftAnnotations: [
|
|
1228
|
+
{
|
|
1229
|
+
label: "High Severity",
|
|
1230
|
+
value: latencyThreshold.toMilliseconds(),
|
|
1231
|
+
color: aws_cloudwatch_1.Color.RED
|
|
1232
|
+
}
|
|
1233
|
+
]
|
|
1234
|
+
}));
|
|
1235
|
+
albWidgets.push(new aws_cloudwatch_1.GraphWidget({
|
|
1236
|
+
height: 8,
|
|
1237
|
+
width: 8,
|
|
1238
|
+
title: `Latency Z-Score (${latencyStatistic})`,
|
|
1239
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
1240
|
+
left: Object.values(weightedLatencyZScorePerZone),
|
|
1241
|
+
leftYAxis: {
|
|
1242
|
+
min: 0,
|
|
1243
|
+
label: "Score",
|
|
1244
|
+
showUnits: false,
|
|
1245
|
+
},
|
|
1246
|
+
leftAnnotations: [
|
|
1247
|
+
{
|
|
1248
|
+
label: "High Severity",
|
|
1249
|
+
value: 3,
|
|
1250
|
+
color: aws_cloudwatch_1.Color.RED
|
|
1251
|
+
}
|
|
1252
|
+
]
|
|
1253
|
+
}));
|
|
1254
|
+
albWidgets.push(new aws_cloudwatch_1.GraphWidget({
|
|
1255
|
+
height: 8,
|
|
1256
|
+
width: 8,
|
|
1257
|
+
title: "Anomalous Hosts",
|
|
1258
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
1259
|
+
left: Object.values(this.getTotalAnomalousHostCountPerZone(albs, period, azMapper)),
|
|
1260
|
+
leftYAxis: {
|
|
1261
|
+
min: 0,
|
|
1262
|
+
label: "Count",
|
|
1263
|
+
showUnits: false,
|
|
1264
|
+
}
|
|
1265
|
+
}));
|
|
1266
|
+
albWidgets.push(new aws_cloudwatch_1.GraphWidget({
|
|
1267
|
+
height: 8,
|
|
1268
|
+
width: 8,
|
|
1269
|
+
title: "Mitigated Hosts",
|
|
1270
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
1271
|
+
left: Object.values(this.getTotalMitigatedHostCountPerZone(albs, period, azMapper)),
|
|
1272
|
+
leftYAxis: {
|
|
1273
|
+
min: 0,
|
|
1274
|
+
label: "Count",
|
|
1275
|
+
showUnits: false,
|
|
1276
|
+
}
|
|
1277
|
+
}));
|
|
1278
|
+
return albWidgets;
|
|
498
1279
|
}
|
|
499
1280
|
}
|
|
500
1281
|
exports.ApplicationLoadBalancerMetrics = ApplicationLoadBalancerMetrics;
|
|
501
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21ldHJpY3MvQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtEQUFrRjtBQUNsRix1RkFBa0o7QUFDbEosZ0ZBQTZFO0FBTzdFLDhEQUEyRDtBQUUzRCxNQUFhLDhCQUE4QjtJQUV2Qzs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxxQkFBcUIsQ0FDeEIsS0FBcUQ7UUFFckQsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FDdkM7WUFDRSxhQUFhLEVBQUU7Z0JBQ2IsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQjtnQkFDeEMsWUFBWSxFQUFHLEtBQUssQ0FBQyxHQUEyQztxQkFDN0Qsb0JBQW9CO2FBQ3hCO1lBQ0QsS0FBSyxFQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEdBQUcsdUJBQXVCO1lBQzdHLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtZQUNwQixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7WUFDMUIsSUFBSSxFQUFFLHFCQUFJLENBQUMsT0FBTztTQUNuQixDQUNGLENBQUM7SUFDUixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILE1BQU0sQ0FBQyx3Q0FBd0MsQ0FDM0MsSUFBZ0MsRUFDaEMsS0FBMEQ7UUFFMUQsSUFBSSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRXhILElBQUks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Q0FBQztDQUNKO0FBem9CRCx3RUF5b0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSU1ldHJpYywgTWF0aEV4cHJlc3Npb24sIFN0YXRzLCBVbml0IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoXCI7XG5pbXBvcnQgeyBCYXNlTG9hZEJhbGFuY2VyLCBIdHRwQ29kZUVsYiwgSHR0cENvZGVUYXJnZXQsIElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgSUxvYWRCYWxhbmNlclYyIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lbGFzdGljbG9hZGJhbGFuY2luZ3YyXCI7XG5pbXBvcnQgeyBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9BdmFpbGFiaWxpdHlNZXRyaWNUeXBlXCI7XG5pbXBvcnQgeyBab25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lNZXRyaWNQcm9wc1wiO1xuaW1wb3J0IHsgWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzXCI7XG5pbXBvcnQgeyBEdXJhdGlvbiB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzXCI7XG5pbXBvcnQgeyBSZWdpb25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lNZXRyaWNQcm9wc1wiO1xuaW1wb3J0IHsgQXZhaWxhYmlsaXR5Wm9uZU1hcHBlciB9IGZyb20gXCIuLi9hem1hcHBlci9BdmFpbGFiaWxpdHlab25lTWFwcGVyXCI7XG5pbXBvcnQgeyBNZXRyaWNzSGVscGVyIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9NZXRyaWNzSGVscGVyXCI7XG5cbmV4cG9ydCBjbGFzcyBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3Mge1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgVGFyZ2V0UmVzcG9uc2VUaW1lIGxhdGVuY3kgZm9yIHRoZSBBTEJcbiAgICAgKiB0YXJnZXRzXG4gICAgICogQHBhcmFtIHByb3BzIFRoZSByZXF1ZXN0IHByb3BzXG4gICAgICogQHJldHVybnMgVGhlIFRhcmdldFJlc3BvbnNlVGltZSBtZXRyaWMgZm9yIHRoZSBBTEIgaW4gdGhlIHNwZWNpZmllZCBBWlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRQZXJBWkxhdGVuY3lNZXRyaWMoXG4gICAgICAgIHByb3BzOiBab25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzXG4gICAgKTogSU1ldHJpYyB7XG4gICAgICAgIHJldHVybiBwcm9wcy5hbGIubWV0cmljcy50YXJnZXRSZXNwb25zZVRpbWUoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKHByb3BzLmFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCA/IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCA6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUgKyBcIi10YXJnZXQtcmVzcG9uc2UtdGltZVwiLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBwcm9wcy5zdGF0aXN0aWMsXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuU0VDT05EU1xuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBlaXRoZXIgdGhlIHN1Y2Nlc3NmdWwsIGZhdWx0LCBvciB0b3RhbCBjb3VudCBtZXRyaWNzXG4gICAgICogZm9yIHRoZSBsb2FkIGJhbGFuY2VyIHRhcmdldHMgYWNyb3NzIGFsbCBvZiB0aGUgcHJvdmlkZWQgXG4gICAgICogQUxCcyBpbiBlYWNoIEFaLlxuICAgICAqIEBwYXJhbSBhbGJzIFRoZSBBTEJzIHRvIGFnZ3JlZ2F0ZSB0aGUgY291bnQgb2ZcbiAgICAgKiBAcGFyYW0gcHJvcHMgVGhlIHJlcXVlc3QgcHJvcHNcbiAgICAgKiBAcmV0dXJucyBUaGUgdG90YWwgY291bnQgb2Ygc3VjZXNzLCBmYXVsdHMsIG9yIHRvdGFsIHJlcXVlc3RzIGluIHRoZSBzcGVjaWZpZWQgQVpcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UGVyQVpBdmFpbGFiaWxpdHlNZXRyaWNDb3VudEFnZ3JlZ2F0ZShcbiAgICAgICAgYWxiczogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyW10sXG4gICAgICAgIHByb3BzOiBab25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5TWV0cmljUHJvcHNcbiAgICApOiBJTWV0cmljIHtcbiAgICAgICAgbGV0IGtleXByZWZpeCA9IHByb3BzLmtleXByZWZpeCA/IHByb3BzLmtleXByZWZpeCA6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKHByb3BzLmF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG5cbiAgICAgICAgbGV0IHVzaW5nTWV0cmljczogeyBba2V5OiBzdHJpbmddOiBJTWV0cmljIH0gPSB7fTtcbiAgICAgICAgbGV0IG1ldHJpY3M6IElNZXRyaWNbXSA9IFtdO1xuXG4gICAgICAgIGFsYnMuZm9yRWFjaCgoYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIpID0+IHtcbiAgICAgICAgICAgIGxldCB0YXJnZXQ1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfNVhYX0NPVU5ULFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItdGFyZ2V0LTV4eFwiLFxuICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAgIGxldCBlbGI1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZUVsYihcbiAgICAgICAgICAgICAgICBIdHRwQ29kZUVsYi5FTEJfNVhYX0NPVU5ULFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItZWxiLTV4eFwiLFxuICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICApO1xuICAgICAgXG4gICAgICAgICAgICAgIGxldCByZXF1ZXN0Q291bnQ6IElNZXRyaWMgPSBhbGIubWV0cmljcy5yZXF1ZXN0Q291bnQoXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi1yZXF1ZXN0LWNvdW50XCIsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKTtcbiAgICAgIFxuICAgICAgICAgICAgICBsZXQgdGFyZ2V0Mnh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzJYWF9DT1VOVCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiArIFwiLXRhcmdldC0yeHhcIixcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICApO1xuICAgICAgXG4gICAgICAgICAgICAgIGxldCBlbGIzeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZUVsYihcbiAgICAgICAgICAgICAgICBIdHRwQ29kZUVsYi5FTEJfM1hYX0NPVU5ULFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItZWxiLTN4eFwiLFxuICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICk7XG4gICAgICBcbiAgICAgICAgICAgICAgbGV0IHRhcmdldDN4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlVGFyZ2V0KFxuICAgICAgICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF8zWFhfQ09VTlQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi10YXJnZXQtM3h4XCIsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKTtcbiAgICAgICBcbiAgICAgICAgICAgICAgc3dpdGNoKHByb3BzLm1ldHJpY1R5cGUpIHtcbiAgICAgICAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5GQVVMVF9DT1VOVDpcbiAgICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IHRhcmdldDV4eDtcbiAgICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IGVsYjV4eDtcbiAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3MucHVzaChuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yYCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi1mYXVsdC1jb3VudFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIFxuICAgICAgICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlQ6XG4gICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQyeHg7XG4gICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQzeHg7XG4gICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSBlbGIzeHg7XG4gICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3MucHVzaChuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yKyR7a2V5cHJlZml4fTNgLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiArIFwiLXN1Y2Nlc3MtY291bnRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuUkVRVUVTVF9DT1VOVDpcbiAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3MucHVzaChyZXF1ZXN0Q291bnQpO1xuICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgbWV0aG9kIG9ubHkgc3VwcG9ydHMgQ09VTlQgYXZhaWxhYmlsaXR5IG1ldHJpY3MuXCIpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGtleXByZWZpeCA9IE1ldHJpY3NIZWxwZXIubmV4dENoYXIoa2V5cHJlZml4KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbWV0cmljcy5mb3JFYWNoKChtZXRyaWM6IElNZXRyaWMsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9JHtpbmRleH1gXSA9IG1ldHJpYztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBleHByZXNzaW9uOiBPYmplY3Qua2V5cyh1c2luZ01ldHJpY3MpLmpvaW4oXCIrXCIpLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIEdldHMgYSBzcGVjaWZpZWQgYXZhaWxhYmlsaXR5IG1ldHJpYyBpbiB0aGUgc3BlY2lmaWVkIEFaIGZvciB0aGUgQUxCXG4gICAgICogQHBhcmFtIGFsYiBUaGUgQUxCXG4gICAgICogQHBhcmFtIHByb3BzIFRoZSByZXF1ZXN0IHByb3BzXG4gICAgICogQHJldHVybnMgVGhlIG1ldHJpYyByZXF1ZXN0ZWRcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UGVyQVpBdmFpbGFiaWxpdHlNZXRyaWMoXG4gICAgICAgIGFsYjogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLCBcbiAgICAgICAgcHJvcHM6IFpvbmFsQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJBdmFpbGFiaWxpdHlNZXRyaWNQcm9wc1xuICAgICk6IElNZXRyaWMge1xuICAgICAgICBsZXQga2V5cHJlZml4ID0gcHJvcHMua2V5cHJlZml4ID8gcHJvcHMua2V5cHJlZml4IDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcocHJvcHMuYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcblxuICAgICAgICBsZXQgdGFyZ2V0NXh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzVYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLXRhcmdldC01eHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIFxuICAgICAgICBsZXQgZWxiNXh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVFbGIoXG4gICAgICAgICAgSHR0cENvZGVFbGIuRUxCXzVYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLWVsYi01eHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgcmVxdWVzdENvdW50OiBJTWV0cmljID0gYWxiLm1ldHJpY3MucmVxdWVzdENvdW50KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItcmVxdWVzdC1jb3VudFwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IHRhcmdldDJ4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlVGFyZ2V0KFxuICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF8yWFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi10YXJnZXQtMnh4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgZWxiM3h4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVFbGIoXG4gICAgICAgICAgSHR0cENvZGVFbGIuRUxCXzNYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLWVsYi0zeHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGxldCB0YXJnZXQzeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfM1hYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItdGFyZ2V0LTN4eFwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IHVzaW5nTWV0cmljczogeyBba2V5OiBzdHJpbmddOiBJTWV0cmljIH0gPSB7fTtcblxuICAgICAgICBzd2l0Y2gocHJvcHMubWV0cmljVHlwZSkge1xuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX0NPVU5UOlxuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gdGFyZ2V0NXh4O1xuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gZWxiNXh4O1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAke2tleXByZWZpeH0xKyR7a2V5cHJlZml4fTJgLFxuICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX1JBVEU6XG4gICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAvLyBSZXF1ZXN0IGNvdW50IG9ubHkgaW5jbHVkZXMgcmVxdWVzdHMgd2hlcmUgYSByZXNwb25zZSB3YXMgZ2VuZXJhdGVkIGZyb20gYSB0YXJnZXRcbiAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQ1eHg7XG4gICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gcmVxdWVzdENvdW50O1xuXG4gICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCgke2tleXByZWZpeH0xLyR7a2V5cHJlZml4fTIpKjEwMGAsXG4gICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlQ6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQyeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQzeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSBlbGIzeHg7XG4gIFxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yKyR7a2V5cHJlZml4fTNgLFxuICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfUkFURTpcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IHRhcmdldDJ4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IHRhcmdldDN4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTNgXSA9IHJlcXVlc3RDb3VudDtcbiAgXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAoKCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9MikvJHtrZXlwcmVmaXh9MykqMTAwYCxcbiAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5SRVFVRVNUX0NPVU5UOlxuICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RDb3VudDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIEFMQnMgc3BlY2lmaWVkIGF2YWlsYWJpbGl0eSBtZXRyaWMgYXQgdGhlIHJlZ2lvbmFsIGxldmVsIChvbmx5IGxvb2tzXG4gICAgICogYXQgdGhlIHJlZ2lvbmFsIGRpbWVuc2lvbiBmb3IgdGhlIHRhcmdldHMsIG5vdCBwZXIgQVopXG4gICAgICogQHBhcmFtIGFsYiBUaGUgQUxCXG4gICAgICogQHBhcmFtIHByb3BzIFRoZSByZXF1ZXN0IHByb3BzXG4gICAgICogQHJldHVybnMgVGhlIHJlZ2lvbmFsIGF2YWlsYWJpbGl0eSBtZXRyaWMgcmVxdWVzdGVkXG4gICAgICovXG4gICAgc3RhdGljIGdldFJlZ2lvbmFsQXZhaWxhYmlsaXR5TWV0cmljKFxuICAgICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgXG4gICAgICAgIHByb3BzOiBSZWdpb25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5TWV0cmljUHJvcHNcbiAgICApOiBJTWV0cmljIHtcbiAgICAgICAgbGV0IGtleXByZWZpeCA9IHByb3BzLmtleXByZWZpeCA/IHByb3BzLmtleXByZWZpeCA6IFwiYVwiO1xuXG4gICAgICAgIGxldCB0YXJnZXQ1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfNVhYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJ0YXJnZXQtNXh4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICBcbiAgICAgICAgbGV0IGVsYjV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl81WFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBcImVsYi01eHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgcmVxdWVzdENvdW50OiBJTWV0cmljID0gYWxiLm1ldHJpY3MucmVxdWVzdENvdW50KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJyZXF1ZXN0LWNvdW50XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgdGFyZ2V0Mnh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzJYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IFwidGFyZ2V0LTJ4eFwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IGVsYjN4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl8zWFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBcImVsYi0zeHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGxldCB0YXJnZXQzeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfM1hYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJ0YXJnZXQtM3h4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuXG4gICAgICAgIHN3aXRjaChwcm9wcy5tZXRyaWNUeXBlKSB7XG4gICAgICAgICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuRkFVTFRfQ09VTlQ6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQ1eHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSBlbGI1eHg7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9MmAsXG4gICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuRkFVTFRfUkFURTpcbiAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gdGFyZ2V0NXh4O1xuICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IHJlcXVlc3RDb3VudDtcblxuICAgICAgICAgICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAoJHtrZXlwcmVmaXh9MS8ke2tleXByZWZpeH0yKSoxMDBgLFxuICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5TVUNDRVNTX0NPVU5UOlxuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gdGFyZ2V0Mnh4O1xuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gdGFyZ2V0M3h4O1xuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9M2BdID0gZWxiM3h4O1xuICBcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9Miske2tleXByZWZpeH0zYCxcbiAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5TVUNDRVNTX1JBVEU6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQyeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQzeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSByZXF1ZXN0Q291bnQ7XG4gIFxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgKCgke2tleXByZWZpeH0xKyR7a2V5cHJlZml4fTIpLyR7a2V5cHJlZml4fTMpKjEwMGAsXG4gICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuUkVRVUVTVF9DT1VOVDpcbiAgICAgICAgICAgICAgIHJldHVybiByZXF1ZXN0Q291bnQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBBTEIncyBUYXJnZXRSZXNwb25zZVRpbWUgbWV0cmljIGF0IHRoZSByZWdpb25hbCBsZXZlbCAob25seSBsb29rc1xuICAgICAqIGF0IHRoZSByZWdpb25hbCBkaW1lbnNpb24gZm9yIHRoZSB0YXJnZXRzLCBub3QgcGVyIEFaKVxuICAgICAqIEBwYXJhbSBwcm9wcyAgVGhlIHJlcXVlc3QgcHJvcHNcbiAgICAgKiBAcmV0dXJucyBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UmVnaW9uYWxMYXRlbmN5TWV0cmljKFxuICAgICAgICBwcm9wczogUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lNZXRyaWNQcm9wc1xuICAgICk6IElNZXRyaWMge1xuICAgICAgICByZXR1cm4gcHJvcHMuYWxiLm1ldHJpY3MudGFyZ2V0UmVzcG9uc2VUaW1lKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAocHJvcHMuYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBsYWJlbDogXCJ0YXJnZXQtcmVzcG9uc2UtdGltZVwiLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBwcm9wcy5zdGF0aXN0aWMsXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuU0VDT05EU1xuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgdG90YWwgbnVtYmVyIG9mIGZhdWx0cyBmb3IgYWxsIEFMQnMgY29tYmluZWQgcGVyIEFaXG4gICAgICogQHBhcmFtIGFsYnMgVGhlIEFMQnMgdG8gYWdncmVnYXRlXG4gICAgICogQHBhcmFtIHBlcmlvZCBUaGUgcGVyaW9kIG9mIHRpbWUgdG8gY2FsY3VsYXRlIHRoZSBtZXRyaWNzXG4gICAgICogQHBhcmFtIGF6TWFwcGVyIFRoZSBBWiBtYXBwZXIgZnVuY3Rpb24gc28gdGhlIG1ldHJpY3MgYXJlIGNvcnJlY3RseSBsYWJlbGVkIHdpdGggdGhlaXIgQVogSURcbiAgICAgKiBAcmV0dXJucyBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0VG90YWxBbGJGYXVsdENvdW50UGVyWm9uZShcbiAgICAgIGFsYnM6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcltdLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgIGF6TWFwcGVyOiBBdmFpbGFiaWxpdHlab25lTWFwcGVyXG4gICAgKSA6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfVxuICAgIHtcbiAgICAgIGxldCBmYXVsdHNQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgIGxldCBtZXRyaWNzUGVyQVo6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljW119ID0ge307XG4gICAgICBsZXQga2V5cHJlZml4OiBzdHJpbmcgPSBNZXRyaWNzSGVscGVyLm5leHRDaGFyKCcnKTtcbiAgXG4gICAgICBhbGJzLmZvckVhY2goKGFsYjogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyKSA9PiB7XG4gIFxuICAgICAgICBhbGIudnBjIS5hdmFpbGFiaWxpdHlab25lcy5mb3JFYWNoKChhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICBpZiAoIShhdmFpbGFiaWxpdHlab25lIGluIG1ldHJpY3NQZXJBWikpIHtcbiAgICAgICAgICAgIG1ldHJpY3NQZXJBWlthdmFpbGFiaWxpdHlab25lXSA9IFtdO1xuICAgICAgICAgIH1cbiAgXG4gICAgICAgICAgbGV0IGF6TGV0dGVyID0gYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcbiAgICAgICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkID0gYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuICBcbiAgICAgICAgICAvLyA1eHggcmVzcG9uc2VzIGZyb20gdGFyZ2V0c1xuICAgICAgICAgIGxldCB0YXJnZXQ1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF81WFhfQ09VTlQsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gICAgICAgIFxuICAgICAgICAgIC8vIDV4eCByZXNwb25zZXMgZnJvbSBFTEJcbiAgICAgICAgICBsZXQgZWxiNXh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVFbGIoXG4gICAgICAgICAgICBIdHRwQ29kZUVsYi5FTEJfNVhYX0NPVU5ULFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICBcbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IGVsYjV4eDtcbiAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IHRhcmdldDV4eDtcbiAgXG4gICAgICAgICAgbWV0cmljc1BlckFaW2F2YWlsYWJpbGl0eVpvbmVdLnB1c2gobmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgIGV4cHJlc3Npb246IGAke2tleXByZWZpeH0xICsgJHtrZXlwcmVmaXh9MmAsXG4gICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kXG4gICAgICAgICAgfSkpO1xuICBcbiAgICAgICAgICBrZXlwcmVmaXggPSBNZXRyaWNzSGVscGVyLm5leHRDaGFyKGtleXByZWZpeCk7XG4gICAgICAgIH0pOyAgIFxuICAgICAgfSk7XG4gIFxuICAgICAgT2JqZWN0LmtleXMobWV0cmljc1BlckFaKS5mb3JFYWNoKChhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgbGV0IGF6TGV0dGVyID0gYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcbiAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcbiAgXG4gICAgICAgIGxldCB1c2luZ01ldHJpY3M6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuICBcbiAgICAgICAgbWV0cmljc1BlckFaW2F2YWlsYWJpbGl0eVpvbmVdLmZvckVhY2goKG1ldHJpYzogSU1ldHJpYykgPT4ge1xuICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gbWV0cmljO1xuICAgICAgICB9KTtcbiAgXG4gICAgICAgIGZhdWx0c1BlclpvbmVbYXZhaWxhYmlsaXR5Wm9uZV0gPSBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgIGV4cHJlc3Npb246IE9iamVjdC5rZXlzKHVzaW5nTWV0cmljcykuam9pbihcIitcIiksXG4gICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLXRvdGFsLWZhdWx0c1wiLFxuICAgICAgICAgIHBlcmlvZDogcGVyaW9kXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIFxuICAgICAgcmV0dXJuIGZhdWx0c1BlclpvbmU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHpvbmFsIHByb2Nlc3NlZCBieXRlcyBtZXRyaWMgZm9yIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlclxuICAgICAqIEBwYXJhbSBsb2FkQmFsYW5jZXJGdWxsTmFtZVxuICAgICAqIEBwYXJhbSBhdmFpbGFiaWxpdHlab25lTmFtZVxuICAgICAqIEBwYXJhbSBwZXJpb2RcbiAgICAgKiBAcmV0dXJucyBJTWV0cmljXG4gICAgICovXG4gICAgc3RhdGljIGdldFBlckFaUHJvY2Vzc2VkQnl0ZXNNZXRyaWMoXG4gICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcixcbiAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZyxcbiAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogc3RyaW5nLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICApOiBJTWV0cmljIHtcbiAgICAgIHJldHVybiBhbGIubWV0cmljcy5wcm9jZXNzZWRCeXRlcyh7XG4gICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgZGltZW5zaW9uc01hcDp7XG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcikubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItcHJvY2Vzc2VkLWJ5dGVzXCJcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB6b25hbCBwcm9jZXNzZWQgYnl0ZXMgbWV0cmljIGZvciB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICAgKiBAcGFyYW0gbG9hZEJhbGFuY2VyRnVsbE5hbWVcbiAgICAgKiBAcGFyYW0gYXZhaWxhYmlsaXR5Wm9uZU5hbWVcbiAgICAgKiBAcGFyYW0gcGVyaW9kXG4gICAgICogQHJldHVybnMgSU1ldHJpY1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSZWdpb25hbFByb2Nlc3NlZEJ5dGVzTWV0cmljKFxuICAgICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcixcbiAgICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgICk6IElNZXRyaWMge1xuICAgICAgICByZXR1cm4gYWxiLm1ldHJpY3MucHJvY2Vzc2VkQnl0ZXMoe1xuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOntcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItcHJvY2Vzc2VkLWJ5dGVzXCJcbiAgICAgICAgfSk7XG4gICAgfVxufSJdfQ==
|
|
1282
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21ldHJpY3MvQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtEQUE0SztBQUM1Syx1RkFBa0o7QUFDbEosZ0ZBQTZFO0FBRzdFLDZDQUE0QztBQUk1Qyw4REFBMkQ7QUFFM0Qsa0pBQStJO0FBQy9JLHdJQUFxSTtBQUdySSxNQUFhLDhCQUE4QjtJQUV2Qzs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxxQkFBcUIsQ0FDeEIsS0FBcUQ7UUFFckQsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FDdkM7WUFDRSxhQUFhLEVBQUU7Z0JBQ2IsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQjtnQkFDeEMsWUFBWSxFQUFHLEtBQUssQ0FBQyxHQUEyQztxQkFDN0Qsb0JBQW9CO2FBQ3hCO1lBQ0QsS0FBSyxFQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEdBQUcsdUJBQXVCO1lBQzdHLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtZQUNwQixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7WUFDMUIsSUFBSSxFQUFFLHFCQUFJLENBQUMsT0FBTztTQUNuQixDQUNGLENBQUM7SUFDUixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILE1BQU0sQ0FBQyx3Q0FBd0MsQ0FDM0MsSUFBZ0MsRUFDaEMsS0FBMEQ7UUFFMUQsSUFBSSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENB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QUFDLENBQ0gsQ0FBQztRQUVGLE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7Q0FDTjtBQWp0REQsd0VBaXREQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFsYXJtLCBDb2xvciwgQ29tcGFyaXNvbk9wZXJhdG9yLCBHcmFwaFdpZGdldCwgSUFsYXJtLCBJTWV0cmljLCBJV2lkZ2V0LCBNYXRoRXhwcmVzc2lvbiwgTWV0cmljLCBTdGF0cywgVHJlYXRNaXNzaW5nRGF0YSwgVW5pdCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaFwiO1xuaW1wb3J0IHsgQmFzZUxvYWRCYWxhbmNlciwgSHR0cENvZGVFbGIsIEh0dHBDb2RlVGFyZ2V0LCBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsIElMb2FkQmFsYW5jZXJWMiB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZWxhc3RpY2xvYWRiYWxhbmNpbmd2MlwiO1xuaW1wb3J0IHsgQXZhaWxhYmlsaXR5TWV0cmljVHlwZSB9IGZyb20gXCIuLi91dGlsaXRpZXMvQXZhaWxhYmlsaXR5TWV0cmljVHlwZVwiO1xuaW1wb3J0IHsgWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lNZXRyaWNQcm9wcyB9IGZyb20gXCIuLi9iYXNpY19vYnNlcnZhYmlsaXR5L3Byb3BzL1pvbmFsQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJMYXRlbmN5TWV0cmljUHJvcHNcIjtcbmltcG9ydCB7IFpvbmFsQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJBdmFpbGFiaWxpdHlNZXRyaWNQcm9wcyB9IGZyb20gXCIuLi9iYXNpY19vYnNlcnZhYmlsaXR5L3Byb3BzL1pvbmFsQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJBdmFpbGFiaWxpdHlNZXRyaWNQcm9wc1wiO1xuaW1wb3J0IHsgQXdzLCBEdXJhdGlvbiB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzXCI7XG5pbXBvcnQgeyBSZWdpb25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lNZXRyaWNQcm9wc1wiO1xuaW1wb3J0IHsgQXZhaWxhYmlsaXR5Wm9uZU1hcHBlciB9IGZyb20gXCIuLi9hem1hcHBlci9BdmFpbGFiaWxpdHlab25lTWFwcGVyXCI7XG5pbXBvcnQgeyBNZXRyaWNzSGVscGVyIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9NZXRyaWNzSGVscGVyXCI7XG5pbXBvcnQgeyBJQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5T3V0bGllckFsZ29yaXRobSB9IGZyb20gXCIuLi9vdXRsaWVyLWRldGVjdGlvbi9BcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU91dGxpZXJBbGdvcml0aG1cIjtcbmltcG9ydCB7IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU91dGxpZXJBbGdvcml0aG0gfSBmcm9tIFwiLi4vb3V0bGllci1kZXRlY3Rpb24vQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJMYXRlbmN5T3V0bGllckFsZ29yaXRobVwiO1xuaW1wb3J0IHsgSUF2YWlsYWJpbGl0eVpvbmVNYXBwZXIgfSBmcm9tIFwiLi4vYXptYXBwZXIvSUF2YWlsYWJpbGl0eVpvbmVNYXBwZXJcIjtcblxuZXhwb3J0IGNsYXNzIEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTWV0cmljcyB7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBUYXJnZXRSZXNwb25zZVRpbWUgbGF0ZW5jeSBmb3IgdGhlIEFMQlxuICAgICAqIHRhcmdldHNcbiAgICAgKiBAcGFyYW0gcHJvcHMgVGhlIHJlcXVlc3QgcHJvcHNcbiAgICAgKiBAcmV0dXJucyBUaGUgVGFyZ2V0UmVzcG9uc2VUaW1lIG1ldHJpYyBmb3IgdGhlIEFMQiBpbiB0aGUgc3BlY2lmaWVkIEFaXG4gICAgICovXG4gICAgc3RhdGljIGdldFBlckFaTGF0ZW5jeU1ldHJpYyhcbiAgICAgICAgcHJvcHM6IFpvbmFsQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJMYXRlbmN5TWV0cmljUHJvcHNcbiAgICApOiBJTWV0cmljIHtcbiAgICAgICAgcmV0dXJuIHByb3BzLmFsYi5tZXRyaWNzLnRhcmdldFJlc3BvbnNlVGltZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAocHJvcHMuYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkID8gcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkIDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSArIFwiLXRhcmdldC1yZXNwb25zZS10aW1lXCIsXG4gICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICBzdGF0aXN0aWM6IHByb3BzLnN0YXRpc3RpYyxcbiAgICAgICAgICAgICAgdW5pdDogVW5pdC5TRUNPTkRTXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGVpdGhlciB0aGUgc3VjY2Vzc2Z1bCwgZmF1bHQsIG9yIHRvdGFsIGNvdW50IG1ldHJpY3NcbiAgICAgKiBmb3IgdGhlIGxvYWQgYmFsYW5jZXIgdGFyZ2V0cyBhY3Jvc3MgYWxsIG9mIHRoZSBwcm92aWRlZCBcbiAgICAgKiBBTEJzIGluIGVhY2ggQVouXG4gICAgICogQHBhcmFtIGFsYnMgVGhlIEFMQnMgdG8gYWdncmVnYXRlIHRoZSBjb3VudCBvZlxuICAgICAqIEBwYXJhbSBwcm9wcyBUaGUgcmVxdWVzdCBwcm9wc1xuICAgICAqIEByZXR1cm5zIFRoZSB0b3RhbCBjb3VudCBvZiBzdWNlc3MsIGZhdWx0cywgb3IgdG90YWwgcmVxdWVzdHMgaW4gdGhlIHNwZWNpZmllZCBBWlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRQZXJBWkF2YWlsYWJpbGl0eU1ldHJpY0NvdW50QWdncmVnYXRlKFxuICAgICAgICBhbGJzOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJbXSxcbiAgICAgICAgcHJvcHM6IFpvbmFsQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJBdmFpbGFiaWxpdHlNZXRyaWNQcm9wc1xuICAgICk6IElNZXRyaWMge1xuICAgICAgICBsZXQga2V5cHJlZml4ID0gcHJvcHMua2V5cHJlZml4ID8gcHJvcHMua2V5cHJlZml4IDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcocHJvcHMuYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcblxuICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuICAgICAgICBsZXQgbWV0cmljczogSU1ldHJpY1tdID0gW107XG5cbiAgICAgICAgYWxicy5mb3JFYWNoKChhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcikgPT4ge1xuICAgICAgICAgICAgbGV0IHRhcmdldDV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlVGFyZ2V0KFxuICAgICAgICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF81WFhfQ09VTlQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi10YXJnZXQtNXh4XCIsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgICAgbGV0IGVsYjV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl81WFhfQ09VTlQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi1lbGItNXh4XCIsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICk7XG4gICAgICBcbiAgICAgICAgICAgICAgbGV0IHJlcXVlc3RDb3VudDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLnJlcXVlc3RDb3VudChcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiArIFwiLXJlcXVlc3QtY291bnRcIixcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICApO1xuICAgICAgXG4gICAgICAgICAgICAgIGxldCB0YXJnZXQyeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfMlhYX0NPVU5ULFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItdGFyZ2V0LTJ4eFwiLFxuICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICk7XG4gICAgICBcbiAgICAgICAgICAgICAgbGV0IGVsYjN4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl8zWFhfQ09VTlQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi1lbGItM3h4XCIsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKTtcbiAgICAgIFxuICAgICAgICAgICAgICBsZXQgdGFyZ2V0M3h4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzNYWF9DT1VOVCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiArIFwiLXRhcmdldC0zeHhcIixcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICApO1xuICAgICAgIFxuICAgICAgICAgICAgICBzd2l0Y2gocHJvcHMubWV0cmljVHlwZSkge1xuICAgICAgICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX0NPVU5UOlxuICAgICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gdGFyZ2V0NXh4O1xuICAgICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gZWxiNXh4O1xuICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgbWV0cmljcy5wdXNoKG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGBGSUxMKCR7a2V5cHJlZml4fTEsIDApICsgRklMTCgke2tleXByZWZpeH0yLCAwKWAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItZmF1bHQtY291bnRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBcbiAgICAgICAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5TVUNDRVNTX0NPVU5UOlxuICAgICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gdGFyZ2V0Mnh4O1xuICAgICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gdGFyZ2V0M3h4O1xuICAgICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9M2BdID0gZWxiM3h4O1xuICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzLnB1c2gobmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9Miske2tleXByZWZpeH0zYCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi1zdWNjZXNzLWNvdW50XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlJFUVVFU1RfQ09VTlQ6XG4gICAgICAgICAgICAgICAgICAgICBtZXRyaWNzLnB1c2gocmVxdWVzdENvdW50KTtcbiAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIG1ldGhvZCBvbmx5IHN1cHBvcnRzIENPVU5UIGF2YWlsYWJpbGl0eSBtZXRyaWNzLlwiKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBrZXlwcmVmaXggPSBNZXRyaWNzSGVscGVyLm5leHRDaGFyKGtleXByZWZpeCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIG1ldHJpY3MuZm9yRWFjaCgobWV0cmljOiBJTWV0cmljLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fSR7aW5kZXh9YF0gPSBtZXRyaWM7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgZXhwcmVzc2lvbjogT2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKFwiK1wiKSxcbiAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBHZXRzIGEgc3BlY2lmaWVkIGF2YWlsYWJpbGl0eSBtZXRyaWMgaW4gdGhlIHNwZWNpZmllZCBBWiBmb3IgdGhlIEFMQlxuICAgICAqIEBwYXJhbSBhbGIgVGhlIEFMQlxuICAgICAqIEBwYXJhbSBwcm9wcyBUaGUgcmVxdWVzdCBwcm9wc1xuICAgICAqIEByZXR1cm5zIFRoZSBtZXRyaWMgcmVxdWVzdGVkXG4gICAgICovXG4gICAgc3RhdGljIGdldFBlckFaQXZhaWxhYmlsaXR5TWV0cmljKFxuICAgICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgXG4gICAgICAgIHByb3BzOiBab25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5TWV0cmljUHJvcHNcbiAgICApOiBJTWV0cmljIHtcbiAgICAgICAgbGV0IGtleXByZWZpeCA9IHByb3BzLmtleXByZWZpeCA/IHByb3BzLmtleXByZWZpeCA6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKHByb3BzLmF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG5cbiAgICAgICAgbGV0IHRhcmdldDV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlVGFyZ2V0KFxuICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF81WFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi10YXJnZXQtNXh4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICBcbiAgICAgICAgbGV0IGVsYjV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl81WFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1lbGItNXh4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IHJlcXVlc3RDb3VudDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLnJlcXVlc3RDb3VudChcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGxldCB0YXJnZXQyeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfMlhYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItdGFyZ2V0LTJ4eFwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IGVsYjN4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl8zWFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1lbGItM3h4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgdGFyZ2V0M3h4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzNYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLXRhcmdldC0zeHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGxldCB1c2luZ01ldHJpY3M6IHsgW2tleTogc3RyaW5nXTogSU1ldHJpYyB9ID0ge307XG5cbiAgICAgICAgc3dpdGNoKHByb3BzLm1ldHJpY1R5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5GQVVMVF9DT1VOVDpcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IHRhcmdldDV4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IGVsYjV4eDtcblxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgRklMTCgke2tleXByZWZpeH0xLCAwKSArIEZJTEwoJHtrZXlwcmVmaXh9MiwgMClgLFxuICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX1JBVEU6XG4gICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAvLyBSZXF1ZXN0IGNvdW50IG9ubHkgaW5jbHVkZXMgcmVxdWVzdHMgd2hlcmUgYSByZXNwb25zZSB3YXMgZ2VuZXJhdGVkIGZyb20gYSB0YXJnZXRcbiAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQ1eHg7XG4gICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gcmVxdWVzdENvdW50O1xuXG4gICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCgke2tleXByZWZpeH0xLyR7a2V5cHJlZml4fTIpKjEwMGAsXG4gICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlQ6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQyeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQzeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSBlbGIzeHg7XG4gIFxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yKyR7a2V5cHJlZml4fTNgLFxuICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfUkFURTpcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IHRhcmdldDJ4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IHRhcmdldDN4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTNgXSA9IHJlcXVlc3RDb3VudDtcbiAgXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAoKCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9MikvJHtrZXlwcmVmaXh9MykqMTAwYCxcbiAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5SRVFVRVNUX0NPVU5UOlxuICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RDb3VudDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIEFMQnMgc3BlY2lmaWVkIGF2YWlsYWJpbGl0eSBtZXRyaWMgYXQgdGhlIHJlZ2lvbmFsIGxldmVsIChvbmx5IGxvb2tzXG4gICAgICogYXQgdGhlIHJlZ2lvbmFsIGRpbWVuc2lvbiBmb3IgdGhlIHRhcmdldHMsIG5vdCBwZXIgQVopXG4gICAgICogQHBhcmFtIGFsYiBUaGUgQUxCXG4gICAgICogQHBhcmFtIHByb3BzIFRoZSByZXF1ZXN0IHByb3BzXG4gICAgICogQHJldHVybnMgVGhlIHJlZ2lvbmFsIGF2YWlsYWJpbGl0eSBtZXRyaWMgcmVxdWVzdGVkXG4gICAgICovXG4gICAgc3RhdGljIGdldFJlZ2lvbmFsQXZhaWxhYmlsaXR5TWV0cmljKFxuICAgICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgXG4gICAgICAgIHByb3BzOiBSZWdpb25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5TWV0cmljUHJvcHNcbiAgICApOiBJTWV0cmljIHtcbiAgICAgICAgbGV0IGtleXByZWZpeCA9IHByb3BzLmtleXByZWZpeCA/IHByb3BzLmtleXByZWZpeCA6IFwiYVwiO1xuXG4gICAgICAgIGxldCB0YXJnZXQ1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfNVhYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJ0YXJnZXQtNXh4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICBcbiAgICAgICAgbGV0IGVsYjV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl81WFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBcImVsYi01eHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgcmVxdWVzdENvdW50OiBJTWV0cmljID0gYWxiLm1ldHJpY3MucmVxdWVzdENvdW50KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJyZXF1ZXN0LWNvdW50XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgdGFyZ2V0Mnh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzJYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IFwidGFyZ2V0LTJ4eFwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IGVsYjN4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl8zWFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBcImVsYi0zeHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGxldCB0YXJnZXQzeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfM1hYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJ0YXJnZXQtM3h4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuXG4gICAgICAgIHN3aXRjaChwcm9wcy5tZXRyaWNUeXBlKSB7XG4gICAgICAgICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuRkFVTFRfQ09VTlQ6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQ1eHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSBlbGI1eHg7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYEZJTEwoJHtrZXlwcmVmaXh9MSwgMCkgKyBGSUxMKCR7a2V5cHJlZml4fTIsIDApYCxcbiAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5GQVVMVF9SQVRFOlxuICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQ1eHg7XG4gICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gcmVxdWVzdENvdW50O1xuXG4gICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCgke2tleXByZWZpeH0xLyR7a2V5cHJlZml4fTIpKjEwMGAsXG4gICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlQ6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQyeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQzeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSBlbGIzeHg7XG4gIFxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yKyR7a2V5cHJlZml4fTNgLFxuICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfUkFURTpcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IHRhcmdldDJ4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IHRhcmdldDN4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTNgXSA9IHJlcXVlc3RDb3VudDtcbiAgXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAoKCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9MikvJHtrZXlwcmVmaXh9MykqMTAwYCxcbiAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5SRVFVRVNUX0NPVU5UOlxuICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RDb3VudDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIEFMQidzIFRhcmdldFJlc3BvbnNlVGltZSBtZXRyaWMgYXQgdGhlIHJlZ2lvbmFsIGxldmVsIChvbmx5IGxvb2tzXG4gICAgICogYXQgdGhlIHJlZ2lvbmFsIGRpbWVuc2lvbiBmb3IgdGhlIHRhcmdldHMsIG5vdCBwZXIgQVopXG4gICAgICogQHBhcmFtIHByb3BzICBUaGUgcmVxdWVzdCBwcm9wc1xuICAgICAqIEByZXR1cm5zIFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSZWdpb25hbExhdGVuY3lNZXRyaWMoXG4gICAgICAgIHByb3BzOiBSZWdpb25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzXG4gICAgKTogSU1ldHJpYyB7XG4gICAgICAgIHJldHVybiBwcm9wcy5hbGIubWV0cmljcy50YXJnZXRSZXNwb25zZVRpbWUoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChwcm9wcy5hbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGxhYmVsOiBBd3MuUkVHSU9OLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBwcm9wcy5zdGF0aXN0aWMsXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuU0VDT05EU1xuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgdG90YWwgbnVtYmVyIG9mIGZhdWx0cyBmb3IgYWxsIEFMQnMgY29tYmluZWQgcGVyIEFaXG4gICAgICogQHBhcmFtIGFsYnMgVGhlIEFMQnMgdG8gYWdncmVnYXRlXG4gICAgICogQHBhcmFtIHBlcmlvZCBUaGUgcGVyaW9kIG9mIHRpbWUgdG8gY2FsY3VsYXRlIHRoZSBtZXRyaWNzXG4gICAgICogQHBhcmFtIGF6TWFwcGVyIFRoZSBBWiBtYXBwZXIgZnVuY3Rpb24gc28gdGhlIG1ldHJpY3MgYXJlIGNvcnJlY3RseSBsYWJlbGVkIHdpdGggdGhlaXIgQVogSURcbiAgICAgKiBAcmV0dXJucyBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0VG90YWxBbGJGYXVsdENvdW50UGVyWm9uZShcbiAgICAgIGFsYnM6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcltdLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgIGF6TWFwcGVyOiBBdmFpbGFiaWxpdHlab25lTWFwcGVyLFxuICAgICkgOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY31cbiAgICB7XG4gICAgICBsZXQgZmF1bHRzUGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG4gICAgICBsZXQgbWV0cmljc1BlckFaOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY1tdfSA9IHt9O1xuICBcbiAgICAgIGFsYnMuZm9yRWFjaCgoYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsIGFsYkluZGV4OiBudW1iZXIpID0+IHtcbiAgXG4gICAgICAgIGFsYi52cGMhLmF2YWlsYWJpbGl0eVpvbmVzLmZvckVhY2goKGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgIGxldCBhekxldHRlciA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcblxuICAgICAgICAgIGlmICghKGF6TGV0dGVyIGluIG1ldHJpY3NQZXJBWikpIHtcbiAgICAgICAgICAgIG1ldHJpY3NQZXJBWlthekxldHRlcl0gPSBbXTtcbiAgICAgICAgICB9XG4gIFxuICAgICAgICAgIC8vIDV4eCByZXNwb25zZXMgZnJvbSB0YXJnZXRzXG4gICAgICAgICAgbGV0IHRhcmdldDV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlVGFyZ2V0KFxuICAgICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzVYWF9DT1VOVCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgXG4gICAgICAgICAgbGV0IHVzaW5nTWV0cmljczoge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG4gICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2F6TGV0dGVyfSR7YWxiSW5kZXh9X2ZhdWx0Y291bnRgXSA9IHRhcmdldDV4eDtcbiAgXG4gICAgICAgICAgLy8gVGhpcyBpcyB0aGUgdG90YWwgbnVtYmVyIG9mIGZhdWx0cyBwZXIgem9uZSBmb3IgdGhpcyBsb2FkIGJhbGFuY2VyXG4gICAgICAgICAgbWV0cmljc1BlckFaW2F6TGV0dGVyXS5wdXNoKG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBleHByZXNzaW9uOiBgRklMTCgke2F6TGV0dGVyfSR7YWxiSW5kZXh9X2ZhdWx0Y291bnQsIDApYCxcbiAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XVxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfSk7ICAgXG4gICAgICB9KTtcbiAgXG4gICAgICAvLyBXZSBjYW4gaGF2ZSBtdWx0aXBsZSBsb2FkIGJhbGFuY2VycyBwZXIgem9uZSwgc28gYWRkIHRoZWlyIGZhdWx0IGNvdW50XG4gICAgICAvLyBtZXRyaWNzIHRvZ2V0aGVyXG4gICAgICBPYmplY3Qua2V5cyhtZXRyaWNzUGVyQVopLmZvckVhY2goKGF6TGV0dGVyOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcblxuICAgICAgICBpZiAobWV0cmljc1BlckFaW2F6TGV0dGVyXS5sZW5ndGggPiAxKSB7XG4gIFxuICAgICAgICAgIGxldCB1c2luZ01ldHJpY3M6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuICAgICAgICAgIFxuICAgICAgICAgIG1ldHJpY3NQZXJBWlthekxldHRlcl0uZm9yRWFjaCgobWV0cmljOiBJTWV0cmljLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7YXpMZXR0ZXJ9JHtpbmRleH1fdG90YWxfZmF1bHRjb3VudGBdID0gbWV0cmljO1xuICAgICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgICBmYXVsdHNQZXJab25lW2F6TGV0dGVyXSA9IG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBleHByZXNzaW9uOiBPYmplY3Qua2V5cyh1c2luZ01ldHJpY3MpLmpvaW4oXCIrXCIpLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBjb2xvcjogTWV0cmljc0hlbHBlci5jb2xvcnNbaW5kZXhdXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZmF1bHRzUGVyWm9uZVthekxldHRlcl0gPSBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdWzBdO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBmYXVsdHNQZXJab25lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZXMgdGhlIHRvdGFsIG51bWJlciBvZiBmYXVsdHMgZm9yIGFsbCBBTEJzIGNvbWJpbmVkIHBlciBBWlxuICAgICAqIEBwYXJhbSBhbGJzIFRoZSBBTEJzIHRvIGFnZ3JlZ2F0ZVxuICAgICAqIEBwYXJhbSBwZXJpb2QgVGhlIHBlcmlvZCBvZiB0aW1lIHRvIGNhbGN1bGF0ZSB0aGUgbWV0cmljc1xuICAgICAqIEBwYXJhbSBhek1hcHBlciBUaGUgQVogbWFwcGVyIGZ1bmN0aW9uIHNvIHRoZSBtZXRyaWNzIGFyZSBjb3JyZWN0bHkgbGFiZWxlZCB3aXRoIHRoZWlyIEFaIElEXG4gICAgICogQHJldHVybnMgXG4gICAgICovXG4gICAgc3RhdGljIGdldFRvdGFsQWxiU3VjY2Vzc0NvdW50UGVyWm9uZShcbiAgICAgIGFsYnM6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcltdLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgIGF6TWFwcGVyOiBBdmFpbGFiaWxpdHlab25lTWFwcGVyXG4gICAgKSA6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfVxuICAgIHtcbiAgICAgIGxldCBzdWNjZXNzUGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG4gICAgICBsZXQgbWV0cmljc1BlckFaOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY1tdfSA9IHt9O1xuICAgICAgbGV0IGtleXByZWZpeDogc3RyaW5nID0gTWV0cmljc0hlbHBlci5uZXh0Q2hhcigpO1xuICBcbiAgICAgIGFsYnMuZm9yRWFjaCgoYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIpID0+IHtcbiAgXG4gICAgICAgIGFsYi52cGMhLmF2YWlsYWJpbGl0eVpvbmVzLmZvckVhY2goKGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgIGxldCBhekxldHRlciA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcblxuICAgICAgICAgIGlmICghKGF6TGV0dGVyIGluIG1ldHJpY3NQZXJBWikpIHtcbiAgICAgICAgICAgIG1ldHJpY3NQZXJBWlthekxldHRlcl0gPSBbXTtcbiAgICAgICAgICB9XG4gIFxuICAgICAgICAgIC8vIDJ4eCByZXNwb25zZXMgZnJvbSB0YXJnZXRzXG4gICAgICAgICAgbGV0IHRhcmdldDJ4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlVGFyZ2V0KFxuICAgICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzJYWF9DT1VOVCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIC8vIDN4eCByZXNwb25zZXMgZnJvbSB0YXJnZXRzXG4gICAgICAgICAgbGV0IHRhcmdldDN4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlVGFyZ2V0KFxuICAgICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzNYWF9DT1VOVCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgXG4gICAgICAgICAgLy8gM3h4IHJlc3BvbnNlcyBmcm9tIEVMQlxuICAgICAgICAgIGxldCBlbGIzeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZUVsYihcbiAgICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl8zWFhfQ09VTlQsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gIFxuICAgICAgICAgIGxldCB1c2luZ01ldHJpY3M6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gZWxiM3h4O1xuICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gdGFyZ2V0Mnh4O1xuICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9M2BdID0gdGFyZ2V0M3h4O1xuICBcbiAgICAgICAgICAvLyBUaGlzIGlzIHRoZSB0b3RhbCBudW1iZXIgb2YgZmF1bHRzIHBlciB6b25lIGZvciB0aGlzIGxvYWQgYmFsYW5jZXJcbiAgICAgICAgICBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdLnB1c2gobmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgIGV4cHJlc3Npb246IGBGSUxMKCR7a2V5cHJlZml4fTEsIDApICsgRklMTCgke2tleXByZWZpeH0yLCAwKSArIEZJTEwoJHtrZXlwcmVmaXh9MywgMClgLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICBjb2xvcjogTWV0cmljc0hlbHBlci5jb2xvcnNbaW5kZXhdXG4gICAgICAgICAgfSkpO1xuICBcbiAgICAgICAgICBrZXlwcmVmaXggPSBNZXRyaWNzSGVscGVyLm5leHRDaGFyKGtleXByZWZpeCk7XG4gICAgICAgIH0pOyAgIFxuICAgICAgfSk7XG4gIFxuICAgICAgLy8gV2UgY2FuIGhhdmUgbXVsdGlwbGUgbG9hZCBiYWxhbmNlcnMgcGVyIHpvbmUsIHNvIGFkZCB0aGVpciBzdWNjZXNzIGNvdW50XG4gICAgICAvLyBtZXRyaWNzIHRvZ2V0aGVyXG4gICAgICBPYmplY3Qua2V5cyhtZXRyaWNzUGVyQVopLmZvckVhY2goKGF6TGV0dGVyOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcblxuICAgICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkID0gYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuICAgICAgICBcbiAgICAgICAgaWYgKG1ldHJpY3NQZXJBWlthekxldHRlcl0ubGVuZ3RoID4gMSkge1xuICAgICAgICAgIGxldCB1c2luZ01ldHJpY3M6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuICAgICAgICAgIFxuICAgICAgICAgIG1ldHJpY3NQZXJBWlthekxldHRlcl0uZm9yRWFjaCgobWV0cmljOiBJTWV0cmljLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fSR7aW5kZXh9YF0gPSBtZXRyaWM7XG4gICAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICAgIHN1Y2Nlc3NQZXJab25lW2F6TGV0dGVyXSA9IG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBleHByZXNzaW9uOiBPYmplY3Qua2V5cyh1c2luZ01ldHJpY3MpLmpvaW4oXCIrXCIpLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBjb2xvcjogTWV0cmljc0hlbHBlci5jb2xvcnNbaW5kZXhdXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgc3VjY2Vzc1BlclpvbmVbYXpMZXR0ZXJdID0gbWV0cmljc1BlckFaW2F6TGV0dGVyXVswXTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgXG4gICAgICByZXR1cm4gc3VjY2Vzc1BlclpvbmU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgdG90YWwgbnVtYmVyIG9mIHByb2Nlc3NlZCBieXRlcyBmb3IgYWxsIEFMQnMgaW4gZWFjaCB6b25lXG4gICAgICogQHBhcmFtIGFsYnMgXG4gICAgICogQHBhcmFtIHBlcmlvZCBcbiAgICAgKiBAcGFyYW0gYXpNYXBwZXIgXG4gICAgICogQHJldHVybnMgXG4gICAgICovXG4gICAgc3RhdGljIGdldFRvdGFsQWxiUmVxdWVzdHNQZXJab25lKFxuICAgICAgYWxiczogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyW10sXG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLFxuICAgICAgYXpNYXBwZXI6IEF2YWlsYWJpbGl0eVpvbmVNYXBwZXJcbiAgICApIDoge1trZXk6IHN0cmluZ106IElNZXRyaWN9XG4gICAge1xuICAgICAgbGV0IHJlcXVlc3RzUGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG4gICAgICBsZXQgbWV0cmljc1BlckFaOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY1tdfSA9IHt9O1xuXG4gICAgICBhbGJzLmZvckVhY2goKGFsYjogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyKSA9PiB7XG4gIFxuICAgICAgICBhbGIudnBjIS5hdmFpbGFiaWxpdHlab25lcy5mb3JFYWNoKChhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICBsZXQgYXpMZXR0ZXIgPSBhdmFpbGFiaWxpdHlab25lLnN1YnN0cmluZyhhdmFpbGFiaWxpdHlab25lLmxlbmd0aCAtIDEpO1xuICAgICAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQgPSBhek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG5cbiAgICAgICAgICBpZiAoIShhekxldHRlciBpbiBtZXRyaWNzUGVyQVopKSB7XG4gICAgICAgICAgICBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdID0gW107XG4gICAgICAgICAgfVxuICBcbiAgICAgICAgICBsZXQgcmVxdWVzdENvdW50OiBJTWV0cmljID0gYWxiLm1ldHJpY3MucmVxdWVzdENvdW50KFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVCxcbiAgICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICBcbiAgICAgICAgICBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdLnB1c2gocmVxdWVzdENvdW50KTtcbiAgICAgICAgfSk7ICAgXG4gICAgICB9KTtcbiAgXG4gICAgICAvLyBXZSBjYW4gaGF2ZSBtdWx0aXBsZSBsb2FkIGJhbGFuY2VycyBwZXIgem9uZSwgc28gYWRkIHRoZWlyIHByb2Nlc3NlZCBieXRlcyB0b2dldGhlclxuICAgICAgT2JqZWN0LmtleXMobWV0cmljc1BlckFaKS5mb3JFYWNoKChhekxldHRlcjogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQgPSBhek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG5cbiAgICAgICAgaWYgKG1ldHJpY3NQZXJBWlthekxldHRlcl0ubGVuZ3RoID4gMSkge1xuICBcbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICBcbiAgICAgICAgICBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdLmZvckVhY2goKG1ldHJpYzogSU1ldHJpYywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2F6TGV0dGVyfSR7aW5kZXh9YF0gPSBtZXRyaWM7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICByZXF1ZXN0c1BlclpvbmVbYXpMZXR0ZXJdID0gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgIGV4cHJlc3Npb246IE9iamVjdC5rZXlzKHVzaW5nTWV0cmljcykuam9pbihcIitcIiksXG4gICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgIGNvbG9yOiBNZXRyaWNzSGVscGVyLmNvbG9yc1tpbmRleF1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICByZXF1ZXN0c1BlclpvbmVbYXpMZXR0ZXJdID0gbWV0cmljc1BlckFaW2F6TGV0dGVyXVswXTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIFxuICAgICAgcmV0dXJuIHJlcXVlc3RzUGVyWm9uZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSB0b3RhbCBudW1iZXIgb2YgcHJvY2Vzc2VkIGJ5dGVzIGZvciBhbGwgQUxCcyBpbiBlYWNoIHpvbmVcbiAgICAgKiBAcGFyYW0gYWxicyBcbiAgICAgKiBAcGFyYW0gcGVyaW9kIFxuICAgICAqIEBwYXJhbSBhek1hcHBlciBcbiAgICAgKiBAcmV0dXJucyBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0VG90YWxBbGJQcm9jZXNzZWRCeXRlc1BlclpvbmUoXG4gICAgICBhbGJzOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJbXSxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBhek1hcHBlcjogQXZhaWxhYmlsaXR5Wm9uZU1hcHBlclxuICAgICkgOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY31cbiAgICB7XG4gICAgICBsZXQgcHJvY2Vzc2VkQnl0ZXNQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgIGxldCBtZXRyaWNzUGVyQVo6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljW119ID0ge307XG4gICAgICBsZXQga2V5cHJlZml4OiBzdHJpbmcgPSBNZXRyaWNzSGVscGVyLm5leHRDaGFyKCk7XG4gIFxuICAgICAgYWxicy5mb3JFYWNoKChhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcikgPT4ge1xuICBcbiAgICAgICAgYWxiLnZwYyEuYXZhaWxhYmlsaXR5Wm9uZXMuZm9yRWFjaCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgbGV0IGF6TGV0dGVyID0gYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcbiAgICAgICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkID0gYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuXG4gICAgICAgICAgaWYgKCEoYXpMZXR0ZXIgaW4gbWV0cmljc1BlckFaKSkge1xuICAgICAgICAgICAgbWV0cmljc1BlckFaW2F6TGV0dGVyXSA9IFtdO1xuICAgICAgICAgIH1cbiAgXG4gICAgICAgICAgbGV0IHByb2Nlc3NlZEJ5dGVzOiBJTWV0cmljID0gYWxiLm1ldHJpY3MucHJvY2Vzc2VkQnl0ZXMoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5ULFxuICAgICAgICAgICAgICBjb2xvcjogTWV0cmljc0hlbHBlci5jb2xvcnNbaW5kZXhdXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gIFxuICAgICAgICAgIG1ldHJpY3NQZXJBWlthekxldHRlcl0ucHVzaChwcm9jZXNzZWRCeXRlcyk7XG4gICAgICAgIH0pOyAgIFxuICAgICAgfSk7XG4gIFxuICAgICAgLy8gV2UgY2FuIGhhdmUgbXVsdGlwbGUgbG9hZCBiYWxhbmNlcnMgcGVyIHpvbmUsIHNvIGFkZCB0aGVpciBwcm9jZXNzZWQgYnl0ZXMgdG9nZXRoZXJcbiAgICAgIE9iamVjdC5rZXlzKG1ldHJpY3NQZXJBWikuZm9yRWFjaCgoYXpMZXR0ZXI6IHN0cmluZywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkID0gYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuXG4gICAgICAgIGlmIChtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdLmxlbmd0aCA+IDEpIHtcblxuICAgICAgICAgIGxldCB1c2luZ01ldHJpY3M6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuICAgICAgICAgIFxuICAgICAgICAgIG1ldHJpY3NQZXJBWlthekxldHRlcl0uZm9yRWFjaCgobWV0cmljOiBJTWV0cmljLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fSR7aW5kZXh9YF0gPSBtZXRyaWM7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBrZXlwcmVmaXggPSBNZXRyaWNzSGVscGVyLm5leHRDaGFyKGtleXByZWZpeCk7XG4gICAgICAgIFxuICAgICAgICAgIHByb2Nlc3NlZEJ5dGVzUGVyWm9uZVthekxldHRlcl0gPSBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgZXhwcmVzc2lvbjogT2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKFwiK1wiKSxcbiAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHByb2Nlc3NlZEJ5dGVzUGVyWm9uZVthekxldHRlcl0gPSBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdWzBdO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgXG4gICAgICByZXR1cm4gcHJvY2Vzc2VkQnl0ZXNQZXJab25lO1xuICAgIH1cblxuICAgIHN0YXRpYyBnZXRUb3RhbEFub21hbG91c0hvc3RDb3VudFBlclpvbmUoXG4gICAgICBhbGJzOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJbXSxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBhek1hcHBlcjogQXZhaWxhYmlsaXR5Wm9uZU1hcHBlclxuICAgICkgOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY31cbiAgICB7XG4gICAgICBsZXQgYW5vbWFsb3VzSG9zdHNQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgIGxldCBtZXRyaWNzUGVyQVo6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljW119ID0ge307XG4gIFxuICAgICAgYWxicy5mb3JFYWNoKChhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcikgPT4ge1xuICBcbiAgICAgICAgYWxiLnZwYyEuYXZhaWxhYmlsaXR5Wm9uZXMuZm9yRWFjaCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgbGV0IGF6TGV0dGVyID0gYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcbiAgICAgICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkID0gYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuXG4gICAgICAgICAgaWYgKCEoYXpMZXR0ZXIgaW4gbWV0cmljc1BlckFaKSkge1xuICAgICAgICAgICAgbWV0cmljc1BlckFaW2F6TGV0dGVyXSA9IFtdO1xuICAgICAgICAgIH1cbiAgXG4gICAgICAgICAgbGV0IGFub21hbG91c0hvc3RDb3VudDogSU1ldHJpYyA9IG5ldyBNZXRyaWMoe1xuICAgICAgICAgICAgbmFtZXNwYWNlOiBcIkFXUy9BcHBsaWNhdGlvbkVMQlwiLFxuICAgICAgICAgICAgcmVnaW9uOiBBd3MuUkVHSU9OLFxuICAgICAgICAgICAgbWV0cmljTmFtZTogXCJBbm9tYWxvdXNIb3N0Q291bnRcIixcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVCxcbiAgICAgICAgICAgIGNvbG9yOiBNZXRyaWNzSGVscGVyLmNvbG9yc1tpbmRleF0sXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kXG4gICAgICAgICAgfSk7XG4gIFxuICAgICAgICAgIG1ldHJpY3NQZXJBWlthekxldHRlcl0ucHVzaChhbm9tYWxvdXNIb3N0Q291bnQpO1xuICAgICAgICB9KTsgICBcbiAgICAgIH0pO1xuICBcbiAgICAgIC8vIFdlIGNhbiBoYXZlIG11bHRpcGxlIGxvYWQgYmFsYW5jZXJzIHBlciB6b25lLCBzbyBhZGQgdGhlaXIgY291bnRzIHRvZ2V0aGVyXG4gICAgICBPYmplY3Qua2V5cyhtZXRyaWNzUGVyQVopLmZvckVhY2goKGF6TGV0dGVyOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcblxuICAgICAgICBpZiAobWV0cmljc1BlckFaW2F6TGV0dGVyXS5sZW5ndGggPiAxKSB7XG5cbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICBcbiAgICAgICAgICBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdLmZvckVhY2goKG1ldHJpYzogSU1ldHJpYywgbWV0cmljSW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2F6TGV0dGVyfSR7bWV0cmljSW5kZXh9YF0gPSBtZXRyaWM7XG4gICAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICAgIGFub21hbG91c0hvc3RzUGVyWm9uZVthekxldHRlcl0gPSBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgZXhwcmVzc2lvbjogT2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKFwiK1wiKSArIFwiICsgVElNRV9TRVJJRVMoMClcIixcbiAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGxldCB1c2luZ01ldHJpY3M6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuICAgICAgICAgIHVzaW5nTWV0cmljc1thekxldHRlcl0gPSBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdWzBdO1xuXG4gICAgICAgICAgYW5vbWFsb3VzSG9zdHNQZXJab25lW2F6TGV0dGVyXSA9IG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBleHByZXNzaW9uOiBgRklMTCgke2F6TGV0dGVyfSwgMClgLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBjb2xvcjogTWV0cmljc0hlbHBlci5jb2xvcnNbaW5kZXhdXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICBcbiAgICAgIHJldHVybiBhbm9tYWxvdXNIb3N0c1BlclpvbmU7XG4gICAgfVxuXG4gICAgc3RhdGljIGdldFRvdGFsTWl0aWdhdGVkSG9zdENvdW50UGVyWm9uZShcbiAgICAgIGFsYnM6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcltdLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgIGF6TWFwcGVyOiBBdmFpbGFiaWxpdHlab25lTWFwcGVyXG4gICAgKSA6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfVxuICAgIHtcbiAgICAgIGxldCBtaXRpZ2F0ZWRIb3N0c1BlclpvbmU6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuICAgICAgbGV0IG1ldHJpY3NQZXJBWjoge1trZXk6IHN0cmluZ106IElNZXRyaWNbXX0gPSB7fTtcblxuICAgICAgYWxicy5mb3JFYWNoKChhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcikgPT4ge1xuICBcbiAgICAgICAgYWxiLnZwYyEuYXZhaWxhYmlsaXR5Wm9uZXMuZm9yRWFjaCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgbGV0IGF6TGV0dGVyID0gYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcbiAgICAgICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkID0gYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuXG4gICAgICAgICAgaWYgKCEoYXpMZXR0ZXIgaW4gbWV0cmljc1BlckFaKSkge1xuICAgICAgICAgICAgbWV0cmljc1BlckFaW2F6TGV0dGVyXSA9IFtdO1xuICAgICAgICAgIH1cbiAgXG4gICAgICAgICAgbGV0IG1pdGlnYXRlZEhvc3RDb3VudDogSU1ldHJpYyA9IG5ldyBNZXRyaWMoe1xuICAgICAgICAgICAgbmFtZXNwYWNlOiBcIkFXUy9BcHBsaWNhdGlvbkVMQlwiLFxuICAgICAgICAgICAgcmVnaW9uOiBBd3MuUkVHSU9OLFxuICAgICAgICAgICAgbWV0cmljTmFtZTogXCJNaXRpZ2F0ZWRIb3N0Q291bnRcIixcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVCxcbiAgICAgICAgICAgIGNvbG9yOiBNZXRyaWNzSGVscGVyLmNvbG9yc1tpbmRleF0sXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kXG4gICAgICAgICAgfSk7XG4gIFxuICAgICAgICAgIG1ldHJpY3NQZXJBWlthekxldHRlcl0ucHVzaChtaXRpZ2F0ZWRIb3N0Q291bnQpO1xuICAgICAgICB9KTsgICBcbiAgICAgIH0pO1xuICBcbiAgICAgIC8vIFdlIGNhbiBoYXZlIG11bHRpcGxlIGxvYWQgYmFsYW5jZXJzIHBlciB6b25lLCBzbyBhZGQgdGhlaXIgY291bnRzIHRvZ2V0aGVyXG4gICAgICBPYmplY3Qua2V5cyhtZXRyaWNzUGVyQVopLmZvckVhY2goKGF6TGV0dGVyOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcblxuICAgICAgICBpZiAobWV0cmljc1BlckFaW2F6TGV0dGVyXS5sZW5ndGggPiAxKSB7XG5cbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICBcbiAgICAgICAgICBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdLmZvckVhY2goKG1ldHJpYzogSU1ldHJpYywgbWV0cmljSW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2F6TGV0dGVyfSR7bWV0cmljSW5kZXh9YF0gPSBtZXRyaWM7XG4gICAgICAgICAgfSk7XG4gICAgICAgXG4gICAgICAgICAgbWl0aWdhdGVkSG9zdHNQZXJab25lW2F6TGV0dGVyXSA9IG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBleHByZXNzaW9uOiBPYmplY3Qua2V5cyh1c2luZ01ldHJpY3MpLmpvaW4oXCIrXCIpICsgXCIgKyBUSU1FX1NFUklFUygwKVwiLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBjb2xvcjogTWV0cmljc0hlbHBlci5jb2xvcnNbaW5kZXhdXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgbGV0IHVzaW5nTWV0cmljczoge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG4gICAgICAgICAgdXNpbmdNZXRyaWNzW2F6TGV0dGVyXSA9IG1ldHJpY3NQZXJBWlthekxldHRlcl1bMF07XG5cbiAgICAgICAgICBtaXRpZ2F0ZWRIb3N0c1BlclpvbmVbYXpMZXR0ZXJdID0gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgIGV4cHJlc3Npb246IGBGSUxMKCR7YXpMZXR0ZXJ9LCAwKWAsXG4gICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgIGNvbG9yOiBNZXRyaWNzSGVscGVyLmNvbG9yc1tpbmRleF1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIFxuICAgICAgcmV0dXJuIG1pdGlnYXRlZEhvc3RzUGVyWm9uZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGVzIGEgd2VpZ2h0ZWQgYXBwcm94aW1hdGlvbiBvZiB0aGUgbGF0ZW5jeSBhdCB0aGUgcHJvdmlkZWQgc3RhdGlzdGljIGZvciBhbGwgQUxCc1xuICAgICAqIGluIGVhY2ggem9uZS5cbiAgICAgKiBAcGFyYW0gYWxicyBcbiAgICAgKiBAcGFyYW0gc3RhdGlzdGljIFxuICAgICAqIEBwYXJhbSBwZXJpb2QgXG4gICAgICogQHBhcmFtIGF6TWFwcGVyIFxuICAgICAqIEByZXR1cm5zIFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRUb3RhbEFsYkxhdGVuY3lQZXJab25lKFxuICAgICAgYWxiczogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyW10sXG4gICAgICBzdGF0aXN0aWM6IHN0cmluZyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBhek1hcHBlcjogQXZhaWxhYmlsaXR5Wm9uZU1hcHBlclxuICAgICkgOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY31cbiAgICB7XG4gICAgICBsZXQgbGF0ZW5jeVBlclpvbmVQZXJBbGI6IHtba2V5OiBzdHJpbmddOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY31bXX0gPSB7fTtcbiAgXG4gICAgICBhbGJzLmZvckVhY2goKGFsYjogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyKSA9PiB7XG4gIFxuICAgICAgICBhbGIudnBjIS5hdmFpbGFiaWxpdHlab25lcy5mb3JFYWNoKChhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcpID0+IHtcblxuICAgICAgICAgIGxldCBhekxldHRlciA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcblxuICAgICAgICAgIGlmICghKGF2YWlsYWJpbGl0eVpvbmUgaW4gbGF0ZW5jeVBlclpvbmVQZXJBbGIpKSB7XG4gICAgICAgICAgICBsYXRlbmN5UGVyWm9uZVBlckFsYlthdmFpbGFiaWxpdHlab25lXSA9IFtdO1xuICAgICAgICAgIH1cbiAgICAgICBcbiAgICAgICAgICBsZXQgbGF0ZW5jeTogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLnRhcmdldFJlc3BvbnNlVGltZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBzdGF0aXN0aWMsXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuU0VDT05EU1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgbGV0IHJlcXVlc3RDb3VudDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLnJlcXVlc3RDb3VudChcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGxhdGVuY3lQZXJab25lUGVyQWxiW2F2YWlsYWJpbGl0eVpvbmVdLnB1c2goe1wibGF0ZW5jeVwiOiBsYXRlbmN5LCBcInJlcXVlc3RzXCI6IHJlcXVlc3RDb3VudH0pO1xuICAgICAgICB9KTsgICBcbiAgICAgIH0pO1xuXG4gICAgICAvKipcbiAgICAgICAqIFdlIHdhbnQgdG8gY2FsY3VsYXRlIHRoaXMgZm9ybXVsYVxuICAgICAgICogXG4gICAgICAgKiAoKChwOTlfMSAqIHJlcXVlc3RzXzEpICsgKHA5OV8yICogcmVxdWVzdHNfMikgKyAocDk5XzMgKiByZXF1ZXN0c18zKSkgLyAocmVxdWVzdHNfMSArIHJlcXVlc3RzXzIgKyByZXF1ZXN0c18zKSkgKiAxMDAwXG4gICAgICAgKiBcbiAgICAgICAqIFRoaXMgd2lsbCBwcm92aWRlIGEgcmVxdWVzdCB3ZWlnaHRlZCBhcHByb3hpbWF0aW9uIG9mIHRoZSBwOTlcbiAgICAgICAqIGxhdGVuY3kgcGVyIEFaXG4gICAgICAgKi8gIFxuICAgICAgbGV0IGxhdGVuY3lQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcblxuICAgICAgT2JqZWN0LmtleXMobGF0ZW5jeVBlclpvbmVQZXJBbGIpLmZvckVhY2goKGF2YWlsYWJpbHRpdHlab25lOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgbGV0IHJlcXVlc3RLZXlzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICBsZXQgbGF0ZW5jeUtleXM6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGxldCB1c2luZ01ldHJpY3M6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuICAgICAgICBcbiAgICAgICAgbGV0IGF6TGV0dGVyOiBzdHJpbmcgPSBhdmFpbGFiaWx0aXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsdGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQ6IHN0cmluZyA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcbiAgICAgICAgXG4gICAgICAgIGxhdGVuY3lQZXJab25lUGVyQWxiW2F2YWlsYWJpbHRpdHlab25lXS5mb3JFYWNoKChtZXRyaWM6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSwgaW5kZXg6IG51bWJlcikgPT4ge1xuXG4gICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2F6TGV0dGVyfSR7aW5kZXh9X3JlcXVlc3RzYF0gPSAgbWV0cmljW1wicmVxdWVzdHNcIl07XG4gICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2F6TGV0dGVyfSR7aW5kZXh9X2xhdGVuY3lgXSA9IG1ldHJpY1tcImxhdGVuY3lcIl07XG5cbiAgICAgICAgICByZXF1ZXN0S2V5cy5wdXNoKGAke2F6TGV0dGVyfSR7aW5kZXh9X3JlcXVlc3RzYCk7XG4gICAgICAgICAgbGF0ZW5jeUtleXMucHVzaChgKCR7YXpMZXR0ZXJ9JHtpbmRleH1fbGF0ZW5jeSAqICR7YXpMZXR0ZXJ9JHtpbmRleH1fcmVxdWVzdHMpYCk7XG5cbiAgICAgICAgfSk7XG5cbiAgICAgICAgbGF0ZW5jeVBlclpvbmVbYXZhaWxhYmlsdGl0eVpvbmVdID0gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICBleHByZXNzaW9uOiBgKCgke2xhdGVuY3lLZXlzLmpvaW4oXCIrXCIpfSkgLyAoJHtyZXF1ZXN0S2V5cy5qb2luKFwiK1wiKX0pKSAqIDEwMDBgLCAvLyBDb252ZXJ0cyB0aGUgY2FsY3VsYXRpb24gdG8gbWlsbGlzZWNvbmRzXG4gICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICBjb2xvcjogTWV0cmljc0hlbHBlci5jb2xvcnNbaW5kZXhdXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIFxuICAgICAgcmV0dXJuIGxhdGVuY3lQZXJab25lO1xuICAgIH1cblxuICAgIHN0YXRpYyBnZXRXZWlnaHRlZExhdGVuY3laU2NvcmVQZXJab25lKFxuICAgICAgYWxiczogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyW10sXG4gICAgICBzdGF0aXN0aWM6IHN0cmluZyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBhek1hcHBlcjogSUF2YWlsYWJpbGl0eVpvbmVNYXBwZXJcbiAgICApIDoge1trZXk6IHN0cmluZ106IElNZXRyaWN9IHtcblxuICAgICAgbGV0IHdlaWdodGVkTGF0ZW5jeToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0gdGhpcy5nZXRUb3RhbEFsYkxhdGVuY3lQZXJab25lKGFsYnMsIHN0YXRpc3RpYywgcGVyaW9kLCBhek1hcHBlcik7XG4gICAgICBsZXQgenNjb3JlOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcblxuICAgICAgLy8gUmVuYW1lIHRoZSBtZXRyaWMga2V5cyB0byB0aGUgQVogbGV0dGVyIHRvIHVzZSBpbiB0aGUgbWV0cmljcyBlcXVhdGlvbnNcbiAgICAgIGxldCB1cGRhdGVkTWV0cmljczoge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG5cbiAgICAgIE9iamVjdC5rZXlzKHdlaWdodGVkTGF0ZW5jeSkuZm9yRWFjaCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nKSA9PiB7XG4gICAgICAgIGxldCBhekxldHRlcjogc3RyaW5nID0gYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcbiAgICAgICAgdXBkYXRlZE1ldHJpY3NbYXpMZXR0ZXJdID0gd2VpZ2h0ZWRMYXRlbmN5W2F2YWlsYWJpbGl0eVpvbmVdO1xuICAgICAgfSlcblxuICAgICAgT2JqZWN0LmtleXMod2VpZ2h0ZWRMYXRlbmN5KS5mb3JFYWNoKChhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgbGV0IGF6TGV0dGVyOiBzdHJpbmcgPSBhdmFpbGFiaWxpdHlab25lLnN1YnN0cmluZyhhdmFpbGFiaWxpdHlab25lLmxlbmd0aCAtIDEpO1xuICAgICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkOiBzdHJpbmcgPSBhek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG5cbiAgICAgICAgenNjb3JlW2F2YWlsYWJpbGl0eVpvbmVdID0gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICBleHByZXNzaW9uOiBgKCR7YXpMZXR0ZXJ9IC0gQVZHKFske09iamVjdC5rZXlzKHVwZGF0ZWRNZXRyaWNzKS5maWx0ZXIoeCA9PiB4ICE9IGF6TGV0dGVyKS5qb2luKFwiLFwiKX1dKSkgLyBTVERERVYoWyR7T2JqZWN0LmtleXModXBkYXRlZE1ldHJpY3MpLmZpbHRlcih4ID0+IHggIT0gYXpMZXR0ZXIpLmpvaW4oXCIsXCIpfV0pYCxcbiAgICAgICAgICB1c2luZ01ldHJpY3M6IHVwZGF0ZWRNZXRyaWNzLFxuICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4genNjb3JlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZXMgdGhlIGZhdWx0IHJhdGUgcGVyIEFaXG4gICAgICogQHBhcmFtIHJlcXVlc3RzUGVyWm9uZSBcbiAgICAgKiBAcGFyYW0gZmF1bHRzUGVyWm9uZSBcbiAgICAgKiBAcGFyYW0gcGVyaW9kIFxuICAgICAqIEBwYXJhbSBhek1hcHBlciBcbiAgICAgKiBAcmV0dXJucyBUaGUgZmF1bHQgcmF0ZSBwZXIgQVogdXNpbmcgdGhlIEFaIG5hbWUgbGV0dGVyIGFzIHRoZSBrZXkgZm9yIGVhY2ggbWV0cmljXG4gICAgICovXG4gICAgc3RhdGljIGdldFRvdGFsQWxiRmF1bHRSYXRlUGVyWm9uZShcbiAgICAgIGFsYnM6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcltdLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgIGF6TWFwcGVyOiBBdmFpbGFiaWxpdHlab25lTWFwcGVyLFxuICAgICkgOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30ge1xuXG4gICAgICBsZXQgZmF1bHRSYXRlTWV0cmljczoge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG4gICAgICBsZXQgcmVxdWVzdHNQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB0aGlzLmdldFRvdGFsQWxiUmVxdWVzdHNQZXJab25lKGFsYnMsIHBlcmlvZCwgYXpNYXBwZXIpO1xuICAgICAgbGV0IGZhdWx0c1BlclpvbmU6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHRoaXMuZ2V0VG90YWxBbGJGYXVsdENvdW50UGVyWm9uZShhbGJzLCBwZXJpb2QsIGF6TWFwcGVyKTtcblxuICAgICAgT2JqZWN0LmtleXMocmVxdWVzdHNQZXJab25lKS5mb3JFYWNoKChrZXk6IHN0cmluZywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICBpZiAoa2V5IGluIGZhdWx0c1BlclpvbmUpIHtcbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICBsZXQga2V5cHJlZml4ID0gJ3onICsga2V5O1xuICAgICAgICAgXG4gICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSBmYXVsdHNQZXJab25lW2tleV07XG4gICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSByZXF1ZXN0c1BlclpvbmVba2V5XTtcblxuICAgICAgICAgIGxldCB6b25hbEZhdWx0UmF0ZTogSU1ldHJpYyA9IG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBleHByZXNzaW9uOiBgKCR7a2V5cHJlZml4fTEvJHtrZXlwcmVmaXh9MikgKiAxMDBgLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgIGxhYmVsOiBhek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihrZXkpLFxuICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgZmF1bHRSYXRlTWV0cmljc1trZXldID0gem9uYWxGYXVsdFJhdGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHpvbmUgXCIgKyBrZXkgKyBcIiBpcyBub3QgcHJlc2VudCBpbiB0aGUgZmF1bHRzUGVyWm9uZSBwYXJhbWV0ZXIuXCIpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgT2JqZWN0LmtleXMoZmF1bHRzUGVyWm9uZSkuZm9yRWFjaCgoa2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgaWYgKCEoa2V5IGluIHJlcXVlc3RzUGVyWm9uZSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgem9uZSBcIiArIGtleSArIFwiIGlzIG5vdCBwcmVzZW50IGluIHRoZSByZXF1ZXN0c1BlclpvbmUgcGFyYW1ldGVyLlwiKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBmYXVsdFJhdGVNZXRyaWNzO1xuICAgIH1cblxuICAgIHN0YXRpYyBnZXRUb3RhbEFsYjV4eENvdW50UGVyWm9uZShcbiAgICAgIGFsYnM6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcltdLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgIGF6TWFwcGVyOiBJQXZhaWxhYmlsaXR5Wm9uZU1hcHBlclxuICAgICkgOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30ge1xuXG4gICAgICBsZXQgZmF1bHRzUGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWNbXX0gPSB7fTtcbiAgICAgIGxldCBhZ2dyZWdhdGVGYXVsdHNQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcblxuICAgICAgYWxicy5mb3JFYWNoKChhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcikgPT4ge1xuXG4gICAgICAgIGFsYi52cGM/LmF2YWlsYWJpbGl0eVpvbmVzLmZvckVhY2goKGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZykgPT4ge1xuXG4gICAgICAgICAgaWYgKCEoYXZhaWxhYmlsaXR5Wm9uZSBpbiBmYXVsdHNQZXJab25lKSkge1xuICAgICAgICAgICAgZmF1bHRzUGVyWm9uZVthdmFpbGFiaWxpdHlab25lXSA9IFtdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGxldCBhekxldHRlciA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcblxuICAgICAgICAgIGxldCBlbGI1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZUVsYihcbiAgICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl81WFhfQ09VTlQsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBmYXVsdHNQZXJab25lW2F2YWlsYWJpbGl0eVpvbmVdLnB1c2goZWxiNXh4KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgT2JqZWN0LmtleXMoZmF1bHRzUGVyWm9uZSkuZm9yRWFjaCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGxldCBhekxldHRlciA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQgPSBhek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG5cbiAgICAgICAgbGV0IHVzaW5nTWV0cmljczoge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG5cbiAgICAgICAgaWYgKGZhdWx0c1BlclpvbmVbYXZhaWxhYmlsaXR5Wm9uZV0ubGVuZ3RoID4gMSkge1xuXG4gICAgICAgICAgZmF1bHRzUGVyWm9uZVthdmFpbGFiaWxpdHlab25lXS5mb3JFYWNoKChtZXRyaWM6IElNZXRyaWMsIGZhdWx0SW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2F6TGV0dGVyfSR7ZmF1bHRJbmRleH1gXSA9IG1ldHJpYztcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGFnZ3JlZ2F0ZUZhdWx0c1BlclpvbmVbYXZhaWxhYmlsaXR5Wm9uZV0gPSBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgZXhwcmVzc2lvbjogT2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKFwiK1wiKSArIFwiICsgVElNRV9TRVJJRVMoMClcIixcbiAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XSxcbiAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWRcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICB1c2luZ01ldHJpY3NbYXpMZXR0ZXJdID0gZmF1bHRzUGVyWm9uZVthdmFpbGFiaWxpdHlab25lXVswXTtcblxuICAgICAgICAgIGFnZ3JlZ2F0ZUZhdWx0c1BlclpvbmVbYXZhaWxhYmlsaXR5Wm9uZV0gPSBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgZXhwcmVzc2lvbjogYEZJTEwoJHthekxldHRlcn0sIDApYCxcbiAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XSxcbiAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWRcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBhZ2dyZWdhdGVGYXVsdHNQZXJab25lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB6b25hbCBwcm9jZXNzZWQgYnl0ZXMgbWV0cmljIGZvciB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICAgKiBAcGFyYW0gbG9hZEJhbGFuY2VyRnVsbE5hbWVcbiAgICAgKiBAcGFyYW0gYXZhaWxhYmlsaXR5Wm9uZU5hbWVcbiAgICAgKiBAcGFyYW0gcGVyaW9kXG4gICAgICogQHJldHVybnMgSU1ldHJpY1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXRQZXJBWlByb2Nlc3NlZEJ5dGVzTWV0cmljKFxuICAgICAgYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsXG4gICAgICBhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcsXG4gICAgICBhdmFpbGFiaWxpdHlab25lSWQ6IHN0cmluZyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBhZGRMb2FkQmFsYW5jZXJBcm5Ub0xhYmVsPzogYm9vbGVhblxuICAgICk6IElNZXRyaWMge1xuICAgICAgcmV0dXJuIGFsYi5tZXRyaWNzLnByb2Nlc3NlZEJ5dGVzKHtcbiAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICBkaW1lbnNpb25zTWFwOntcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKS5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQgKyAoYWRkTG9hZEJhbGFuY2VyQXJuVG9MYWJlbCA/IFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiA6IFwiXCIpXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgem9uYWwgcHJvY2Vzc2VkIGJ5dGVzIG1ldHJpYyBmb3IgdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyXG4gICAgICogQHBhcmFtIGxvYWRCYWxhbmNlckZ1bGxOYW1lXG4gICAgICogQHBhcmFtIGF2YWlsYWJpbGl0eVpvbmVOYW1lXG4gICAgICogQHBhcmFtIHBlcmlvZFxuICAgICAqIEByZXR1cm5zIElNZXRyaWNcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UmVnaW9uYWxQcm9jZXNzZWRCeXRlc01ldHJpYyhcbiAgICAgICAgYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsXG4gICAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICAgIGFkZExvYWRCYWxhbmNlckFybj86IGJvb2xlYW5cbiAgICAgICk6IElNZXRyaWMge1xuICAgICAgICByZXR1cm4gYWxiLm1ldHJpY3MucHJvY2Vzc2VkQnl0ZXMoe1xuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOntcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBBd3MuUkVHSU9OICsgKGFkZExvYWRCYWxhbmNlckFybiA/IFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiA6IFwiXCIpXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVBWkF2YWlsYWJpbGl0eUltcGFjdEFsYXJtKFxuICAgICAgc2NvcGU6IElDb25zdHJ1Y3QsXG4gICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgXG4gICAgICBhdmFpbGFiaWxpdHlab25lSWQ6IHN0cmluZyxcbiAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZyxcbiAgICAgIHRocmVzaG9sZDogbnVtYmVyLFxuICAgICAga2V5cHJlZml4OiBzdHJpbmcsXG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLFxuICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IG51bWJlcixcbiAgICAgIGRhdGFwb2ludHNUb0FsYXJtOiBudW1iZXJcbiAgICApIDogSUFsYXJtIHtcbiAgICAgXG4gICAgICAvLyBDcmVhdGUgYSBmYXVsdCByYXRlIGFsYXJtIGZvciB0aGUgQUxCIGluIHRoZSBzcGVjaWZpZWQgQVpcbiAgICAgIHJldHVybiBuZXcgQWxhcm0oXG4gICAgICAgIHNjb3BlLFxuICAgICAgICBrZXlwcmVmaXggKyAnLWZhdWx0LXJhdGUtYWxhcm0nLFxuICAgICAgICB7XG4gICAgICAgICAgYWxhcm1OYW1lOlxuICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkICsgJy0nICsgYWxiLmxvYWRCYWxhbmNlckFybiArICctZmF1bHQtcmF0ZScsXG4gICAgICAgICAgYWN0aW9uc0VuYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgIG1ldHJpYzogQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmdldFBlckFaQXZhaWxhYmlsaXR5TWV0cmljKGFsYiwge1xuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkICsgJy0nICsgYWxiLmxvYWRCYWxhbmNlckFybiArICctZmF1bHQtcmF0ZScsXG4gICAgICAgICAgICBhdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICBtZXRyaWNUeXBlOiBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX1JBVEVcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBldmFsdWF0aW9uUGVyaW9kczogZXZhbHVhdGlvblBlcmlvZHMsXG4gICAgICAgICAgZGF0YXBvaW50c1RvQWxhcm06IGRhdGFwb2ludHNUb0FsYXJtLFxuICAgICAgICAgIHRocmVzaG9sZDogdGhyZXNob2xkLFxuICAgICAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9USFJFU0hPTEQsXG4gICAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogVHJlYXRNaXNzaW5nRGF0YS5JR05PUkVcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9XG4gIFxuICAgIHN0YXRpYyBjcmVhdGVBWkxhdGVuY3lJbXBhY3RBbGFybShcbiAgICAgIHNjb3BlOiBJQ29uc3RydWN0LFxuICAgICAgYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsIFxuICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkOiBzdHJpbmcsXG4gICAgICBhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcsXG4gICAgICB0aHJlc2hvbGQ6IER1cmF0aW9uLFxuICAgICAgc3RhdGlzdGljOiBzdHJpbmcsXG4gICAgICBrZXlwcmVmaXg6IHN0cmluZyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBldmFsdWF0aW9uUGVyaW9kczogbnVtYmVyLFxuICAgICAgZGF0YXBvaW50c1RvQWxhcm06IG51bWJlclxuICAgICk6IElBbGFybSB7XG4gICAgICBcbiAgICAgIC8vIENyZWF0ZSBhIGZhdWx0IHJhdGUgYWxhcm0gZm9yIHRoZSBBTEIgaW4gdGhlIHNwZWNpZmllZCBBWlxuICAgICAgcmV0dXJuIG5ldyBBbGFybShcbiAgICAgICAgc2NvcGUsXG4gICAgICAgIGtleXByZWZpeCArICctbGF0ZW5jeS1hbGFybScsXG4gICAgICAgIHtcbiAgICAgICAgICBhbGFybU5hbWU6XG4gICAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQgKyAnLScgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgJy1sYXRlbmN5JyxcbiAgICAgICAgICBhY3Rpb25zRW5hYmxlZDogZmFsc2UsXG4gICAgICAgICAgbWV0cmljOiBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3MuZ2V0UGVyQVpMYXRlbmN5TWV0cmljKHtcbiAgICAgICAgICAgIGFsYjogYWxiLFxuICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiArIFwiLXRhcmdldC1sYXRlbmN5XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogc3RhdGlzdGljXG4gICAgICAgICAgfSksXG4gICAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IGV2YWx1YXRpb25QZXJpb2RzLFxuICAgICAgICAgIGRhdGFwb2ludHNUb0FsYXJtOiBkYXRhcG9pbnRzVG9BbGFybSxcbiAgICAgICAgICB0aHJlc2hvbGQ6IHRocmVzaG9sZC50b1NlY29uZHMoe2ludGVncmFsOiBmYWxzZX0pLCAvLyBBTEIgbGF0ZW5jeSBpcyBtZWFzdXJlZCBpbiBzZWNvbmRzXG4gICAgICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX1RIUkVTSE9MRCxcbiAgICAgICAgICB0cmVhdE1pc3NpbmdEYXRhOiBUcmVhdE1pc3NpbmdEYXRhLklHTk9SRVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cbiAgXG4gICAgc3RhdGljIGNyZWF0ZUFaQXZhaWxhYmlsaXR5T3V0bGllckFsYXJtKFxuICAgICAgc2NvcGU6IElDb25zdHJ1Y3QsXG4gICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgXG4gICAgICBhbGdvcml0aG06IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5T3V0bGllckFsZ29yaXRobSxcbiAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogc3RyaW5nLFxuICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nLFxuICAgICAgdGhyZXNob2xkOiBudW1iZXIsXG4gICAgICBrZXlwcmVmaXg6IHN0cmluZyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBldmFsdWF0aW9uUGVyaW9kczogbnVtYmVyLFxuICAgICAgZGF0YXBvaW50c1RvQWxhcm06IG51bWJlciAgIFxuICAgICkgOiBJQWxhcm0ge1xuICBcbiAgICAgIGxldCB1c2luZ01ldHJpY3M6IHsgW2tleTogc3RyaW5nXTogSU1ldHJpYyB9ID0ge307XG4gICAgICBsZXQgYXpNZXRyaWNJZDogc3RyaW5nID0gXCJcIjtcbiAgXG4gICAgICBhbGIudnBjIS5hdmFpbGFiaWxpdHlab25lcy5mb3JFYWNoKChhejogc3RyaW5nKSA9PiB7XG4gIFxuICAgICAgICBsZXQgYXpGYXVsdENvdW50ID0gQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmdldFBlckFaQXZhaWxhYmlsaXR5TWV0cmljKFxuICAgICAgICAgIGFsYixcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtZXRyaWNUeXBlOiBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX0NPVU5ULFxuICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItZmF1bHQtY291bnRcIixcbiAgICAgICAgICAgIGtleXByZWZpeDoga2V5cHJlZml4XG4gICAgICAgICAgfVxuICAgICAgICApO1xuICBcbiAgICAgICAga2V5cHJlZml4ID0gTWV0cmljc0hlbHBlci5uZXh0Q2hhcihrZXlwcmVmaXgpO1xuICBcbiAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSBhekZhdWx0Q291bnQ7XG4gIFxuICAgICAgICBpZiAoYXogPT0gYXZhaWxhYmlsaXR5Wm9uZSkge1xuICAgICAgICAgIGF6TWV0cmljSWQgPSBgJHtrZXlwcmVmaXh9MWA7XG4gICAgICAgIH1cbiAgXG4gICAgICAgIGtleXByZWZpeCA9IE1ldHJpY3NIZWxwZXIubmV4dENoYXIoa2V5cHJlZml4KTtcbiAgICAgIH0pO1xuICBcbiAgICAgIHN3aXRjaCAoYWxnb3JpdGhtKSB7XG4gICAgICAgIGNhc2UgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJBdmFpbGFiaWxpdHlPdXRsaWVyQWxnb3JpdGhtLlNUQVRJQzpcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gbmV3IEFsYXJtKFxuICAgICAgICAgICAgc2NvcGUsXG4gICAgICAgICAgICBrZXlwcmVmaXggKyAnLWF2YWlsYWJpbGl0eS1vdXRsaWVyLWFsYXJtJyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWxhcm1OYW1lOlxuICAgICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZCArICctJyArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyAnLWF2YWlsYWJpbGl0eS1pbXBhY3Qtb3V0bGllcicsXG4gICAgICAgICAgICAgIGFjdGlvbnNFbmFibGVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgbWV0cmljOiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAoJHthek1ldHJpY0lkIX0vKCR7T2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKFwiK1wiKX0pKSAqIDEwMGAsXG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCArICctJyArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyAnLXBlcmNlbnQtb2YtZmF1bHRzJyxcbiAgICAgICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiBldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgICAgICAgICAgZGF0YXBvaW50c1RvQWxhcm06IGRhdGFwb2ludHNUb0FsYXJtLFxuICAgICAgICAgICAgICB0aHJlc2hvbGQ6IHRocmVzaG9sZCxcbiAgICAgICAgICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX09SX0VRVUFMX1RPX1RIUkVTSE9MRCxcbiAgICAgICAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogVHJlYXRNaXNzaW5nRGF0YS5JR05PUkVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgXG4gICAgc3RhdGljIGNyZWF0ZUFaTGF0ZW5jeU91dGxpZXJBbGFybShcbiAgICAgIHNjb3BlOiBJQ29uc3RydWN0LFxuICAgICAgYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsIFxuICAgICAgYWxnb3JpdGhtOiBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lPdXRsaWVyQWxnb3JpdGhtLFxuICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nLFxuICAgICAgc3RhdGlzdGljOiBzdHJpbmcsXG4gICAgICBsYXRlbmN5VGhyZXNvbGQ6IER1cmF0aW9uLFxuICAgICAgb3V0bGllclRocmVzaG9sZDogbnVtYmVyLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiBudW1iZXIsXG4gICAgICBkYXRhcG9pbnRzVG9BbGFybTogbnVtYmVyLFxuICAgICAgYXpNYXBwZXI6IElBdmFpbGFiaWxpdHlab25lTWFwcGVyXG4gICAgKSA6IElBbGFybSB7XG4gIFxuICAgICAgbGV0IGF6TGV0dGVyOiBzdHJpbmcgPSBhdmFpbGFiaWxpdHlab25lLnN1YnN0cmluZyhhdmFpbGFiaWxpdHlab25lLmxlbmd0aCAtIDEpO1xuICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZDogc3RyaW5nID0gYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuXG4gICAgICBzd2l0Y2ggKGFsZ29yaXRobSlcbiAgICAgIHtcbiAgICAgICAgY2FzZSBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lPdXRsaWVyQWxnb3JpdGhtLlpfU0NPUkU6XG4gICAgICAgIGRlZmF1bHQ6XG5cbiAgICAgICAgICBsZXQgd2VpZ2h0ZWRMYXRlbmN5WlNjb3JlUGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0gQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmdldFdlaWdodGVkTGF0ZW5jeVpTY29yZVBlclpvbmUoIFsgYWxiIF0sIHN0YXRpc3RpYywgcGVyaW9kLCBhek1hcHBlcik7XG4gICAgICAgICAgXG4gICAgICAgICAgcmV0dXJuIG5ldyBBbGFybShcbiAgICAgICAgICAgIHNjb3BlLFxuICAgICAgICAgICAgYXpMZXR0ZXIgKyBcIi1sYXRlbmN5LW91dGxpZXItYWxhcm1cIixcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWxhcm1OYW1lOlxuICAgICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZCArICctJyArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyAnLWxhdGVuY3ktaW1wYWN0LW91dGxpZXInLFxuICAgICAgICAgICAgICBhY3Rpb25zRW5hYmxlZDogZmFsc2UsXG4gICAgICAgICAgICAgIG1ldHJpYzogd2VpZ2h0ZWRMYXRlbmN5WlNjb3JlUGVyWm9uZVthdmFpbGFiaWxpdHlab25lXSxcbiAgICAgICAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IGV2YWx1YXRpb25QZXJpb2RzLFxuICAgICAgICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTogZGF0YXBvaW50c1RvQWxhcm0sXG4gICAgICAgICAgICAgIHRocmVzaG9sZDogb3V0bGllclRocmVzaG9sZCxcbiAgICAgICAgICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX09SX0VRVUFMX1RPX1RIUkVTSE9MRCxcbiAgICAgICAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogVHJlYXRNaXNzaW5nRGF0YS5JR05PUkVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICBjYXNlIEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU91dGxpZXJBbGdvcml0aG0uU1RBVElDOlxuICAgICAgICAgIFxuICAgICAgICAgIGxldCB1c2luZ01ldHJpY3M6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuXG4gICAgICAgICAgYWxiLnZwYyEuYXZhaWxhYmlsaXR5Wm9uZXMuZm9yRWFjaCgoYXo6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgbGV0IGF6TGV0dGVyOiBzdHJpbmcgPSBhei5zdWJzdHJpbmcoYXoubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICBsZXQgYXpJZDogc3RyaW5nID0gYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuXG4gICAgICAgICAgICAvLyBUYXJnZXQgcmVzcG9uc2UgdGltZVxuICAgICAgICAgICAgbGV0IHRhcmdldFJlc3BvbnNlVGltZTogSU1ldHJpYyA9IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTWV0cmljcy5nZXRQZXJBWkxhdGVuY3lNZXRyaWMoe1xuICAgICAgICAgICAgICBhbGI6IGFsYixcbiAgICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogYXosXG4gICAgICAgICAgICAgIGxhYmVsOiBheklkLFxuICAgICAgICAgICAgICBzdGF0aXN0aWM6IGBUQygke01ldHJpY3NIZWxwZXIuY29udmVydER1cmF0aW9uQnlVbml0KGxhdGVuY3lUaHJlc29sZCwgVW5pdC5TRUNPTkRTKX06KWAsXG4gICAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2F6TGV0dGVyfWBdID0gdGFyZ2V0UmVzcG9uc2VUaW1lO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcmV0dXJuIG5ldyBBbGFybShcbiAgICAgICAgICAgIHNjb3BlLFxuICAgICAgICAgICAgYXpMZXR0ZXIgKyBcIi1sYXRlbmN5LW91dGxpZXItYWxhcm1cIixcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWxhcm1OYW1lOlxuICAgICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZCArICctJyArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyAnLWxhdGVuY3ktaW1wYWN0LW91dGxpZXInLFxuICAgICAgICAgICAgICBhY3Rpb25zRW5hYmxlZDogZmFsc2UsXG4gICAgICAgICAgICAgIG1ldHJpYzogbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgKCR7YXpMZXR0ZXJ9Lygke09iamVjdC5rZXlzKHVzaW5nTWV0cmljcykuam9pbihcIitcIil9KSkgKiAxMDBgLFxuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBldmFsdWF0aW9uUGVyaW9kczogZXZhbHVhdGlvblBlcmlvZHMsXG4gICAgICAgICAgICAgIGRhdGFwb2ludHNUb0FsYXJtOiBkYXRhcG9pbnRzVG9BbGFybSxcbiAgICAgICAgICAgICAgdGhyZXNob2xkOiBvdXRsaWVyVGhyZXNob2xkLFxuICAgICAgICAgICAgICBjb21wYXJpc29uT3BlcmF0b3I6IENvbXBhcmlzb25PcGVyYXRvci5HUkVBVEVSX1RIQU5fT1JfRVFVQUxfVE9fVEhSRVNIT0xELFxuICAgICAgICAgICAgICB0cmVhdE1pc3NpbmdEYXRhOiBUcmVhdE1pc3NpbmdEYXRhLklHTk9SRVxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIGdlbmVyYXRlTG9hZEJhbGFuY2VyV2lkZ2V0cyhcbiAgICAgICAgYWxiczogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyW10sXG4gICAgICAgIGF6TWFwcGVyOiBBdmFpbGFiaWxpdHlab25lTWFwcGVyLFxuICAgICAgICBwZXJpb2Q6IER1cmF0aW9uLFxuICAgICAgICBsYXRlbmN5U3RhdGlzdGljOiBzdHJpbmcsXG4gICAgICAgIGxhdGVuY3lUaHJlc2hvbGQ6IER1cmF0aW9uLFxuICAgICAgICBmYXVsdFJhdGVUaHJlc2hvbGQ6IG51bWJlclxuICAgICAgKTogSVdpZGdldFtdIHtcbiAgICAgICAgbGV0IGFsYldpZGdldHM6IElXaWRnZXRbXSA9IFtdO1xuICAgXG4gICAgICAgIGxldCBzdWNjZXNzQ291bnRQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSBcbiAgICAgICAgICBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3MuZ2V0VG90YWxBbGJTdWNjZXNzQ291bnRQZXJab25lKGFsYnMsIHBlcmlvZCwgYXpNYXBwZXIpO1xuICAgICAgICBsZXQgZmF1bHRDb3VudFBlclpvbmU6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IFxuICAgICAgICAgIEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTWV0cmljcy5nZXRUb3RhbEFsYkZhdWx0Q291bnRQZXJab25lKGFsYnMsIHBlcmlvZCwgYXpNYXBwZXIpO1xuICAgICAgICBsZXQgcHJvY2Vzc2VkQnl0ZXNQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSBcbiAgICAgICAgICBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3MuZ2V0VG90YWxBbGJQcm9jZXNzZWRCeXRlc1BlclpvbmUoYWxicywgcGVyaW9kLCBhek1hcHBlcik7XG4gICAgICAgIGxldCBsYXRlbmN5UGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0gXG4gICAgICAgICAgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmdldFRvdGFsQWxiTGF0ZW5jeVBlclpvbmUoYWxicywgbGF0ZW5jeVN0YXRpc3RpYywgcGVyaW9kLCBhek1hcHBlcik7XG4gICAgICAgIGxldCByZXF1ZXN0c1BlclpvbmU6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IFxuICAgICAgICAgIEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTWV0cmljcy5nZXRUb3RhbEFsYlJlcXVlc3RzUGVyWm9uZShhbGJzLCBwZXJpb2QsIGF6TWFwcGVyKTsgIFxuICAgICAgICBsZXQgZmF1bHRSYXRlUGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID1cbiAgICAgICAgICBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3MuZ2V0VG90YWxBbGJGYXVsdFJhdGVQZXJab25lKGFsYnMsIHBlcmlvZCwgYXpNYXBwZXIpOyAgXG4gICAgICAgIGxldCB3ZWlnaHRlZExhdGVuY3laU2NvcmVQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSBcbiAgICAgICAgICBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3MuZ2V0V2VpZ2h0ZWRMYXRlbmN5WlNjb3JlUGVyWm9uZShhbGJzLCBsYXRlbmN5U3RhdGlzdGljLCBwZXJpb2QsIGF6TWFwcGVyKTtcbiAgICBcbiAgICAgICAgYWxiV2lkZ2V0cy5wdXNoKFxuICAgICAgICAgIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgICAgICBoZWlnaHQ6IDgsXG4gICAgICAgICAgICB3aWR0aDogOCxcbiAgICAgICAgICAgIHRpdGxlOiBcIlN1Y2Nlc3MgQ291bnRcIixcbiAgICAgICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgICAgIGxlZnQ6IE9iamVjdC52YWx1ZXMoc3VjY2Vzc0NvdW50UGVyWm9uZSksXG4gICAgICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgICBsYWJlbDogJ0NvdW50JyxcbiAgICAgICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIFxuICAgICAgIGFsYldpZGdldHMucHVzaChcbiAgICAgICAgICBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgICAgICAgaGVpZ2h0OiA4LFxuICAgICAgICAgICAgd2lkdGg6IDgsXG4gICAgICAgICAgICB0aXRsZTogXCJUYXJnZXQgNXh4IENvdW50XCIsXG4gICAgICAgICAgICByZWdpb246IEF3cy5SRUdJT04sXG4gICAgICAgICAgICBsZWZ0OiBPYmplY3QudmFsdWVzKGZhdWx0Q291bnRQZXJab25lKSxcbiAgICAgICAgICAgIGxlZnRZQXhpczoge1xuICAgICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICAgIGxhYmVsOiAnQ291bnQnLFxuICAgICAgICAgICAgICBzaG93VW5pdHM6IGZhbHNlLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG5cbiAgICAgICAgYWxiV2lkZ2V0cy5wdXNoKFxuICAgICAgICAgIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgICAgICBoZWlnaHQ6IDgsXG4gICAgICAgICAgICB3aWR0aDogOCxcbiAgICAgICAgICAgIHRpdGxlOiBcIkVMQiA1eHggQ291bnRcIixcbiAgICAgICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgICAgIGxlZnQ6IE9iamVjdC52YWx1ZXModGhpcy5nZXRUb3RhbEFsYjV4eENvdW50UGVyWm9uZShhbGJzLCBwZXJpb2QsIGF6TWFwcGVyKSksXG4gICAgICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgICBsYWJlbDogJ0NvdW50JyxcbiAgICAgICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIFxuICAgICAgICBhbGJXaWRnZXRzLnB1c2goXG4gICAgICAgICAgbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICAgIGhlaWdodDogOCxcbiAgICAgICAgICAgIHdpZHRoOiA4LFxuICAgICAgICAgICAgdGl0bGU6IFwiUmVxdWVzdCBDb3VudFwiLFxuICAgICAgICAgICAgcmVnaW9uOiBBd3MuUkVHSU9OLFxuICAgICAgICAgICAgbGVmdDogT2JqZWN0LnZhbHVlcyhyZXF1ZXN0c1BlclpvbmUpLFxuICAgICAgICAgICAgbGVmdFlBeGlzOiB7XG4gICAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgICAgbGFiZWw6ICdDb3VudCcsXG4gICAgICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICBcbiAgICAgICAgYWxiV2lkZ2V0cy5wdXNoKFxuICAgICAgICAgIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgICAgICBoZWlnaHQ6IDgsXG4gICAgICAgICAgICB3aWR0aDogOCxcbiAgICAgICAgICAgIHRpdGxlOiBcIkZhdWx0IFJhdGVcIixcbiAgICAgICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgICAgIGxlZnQ6IE9iamVjdC52YWx1ZXMoZmF1bHRSYXRlUGVyWm9uZSksXG4gICAgICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgICBsYWJlbDogJ1BlcmNlbnQnLFxuICAgICAgICAgICAgICBzaG93VW5pdHM6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxlZnRBbm5vdGF0aW9uczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6IFwiSGlnaCBTZXZlcml0eVwiLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBmYXVsdFJhdGVUaHJlc2hvbGQsXG4gICAgICAgICAgICAgICAgY29sb3I6IENvbG9yLlJFRFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdICAgICAgIFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgXG4gICAgICAgIGFsYldpZGdldHMucHVzaChcbiAgICAgICAgICBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgICAgICAgaGVpZ2h0OiA4LFxuICAgICAgICAgICAgd2lkdGg6IDgsXG4gICAgICAgICAgICB0aXRsZTogXCJQcm9jZXNzZWQgQnl0ZXNcIixcbiAgICAgICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgICAgIGxlZnQ6IE9iamVjdC52YWx1ZXMocHJvY2Vzc2VkQnl0ZXNQZXJab25lKSxcbiAgICAgICAgICAgIGxlZnRZQXhpczoge1xuICAgICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgICAgICAgIGxhYmVsOiAnQnl0ZXMnXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICBcbiAgICAgICAgYWxiV2lkZ2V0cy5wdXNoKFxuICAgICAgICAgIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgICAgICBoZWlnaHQ6IDgsXG4gICAgICAgICAgICB3aWR0aDogOCxcbiAgICAgICAgICAgIHRpdGxlOiBgVGFyZ2V0IFJlc3BvbnNlIFRpbWUgKCR7bGF0ZW5jeVN0YXRpc3RpY30pYCxcbiAgICAgICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgICAgIGxlZnQ6IE9iamVjdC52YWx1ZXMobGF0ZW5jeVBlclpvbmUpLFxuICAgICAgICAgICAgbGVmdFlBeGlzOiB7XG4gICAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgICAgbGFiZWw6IFwiTWlsbGlzZWNvbmRzXCIsXG4gICAgICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGVmdEFubm90YXRpb25zOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogXCJIaWdoIFNldmVyaXR5XCIsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGxhdGVuY3lUaHJlc2hvbGQudG9NaWxsaXNlY29uZHMoKSxcbiAgICAgICAgICAgICAgICBjb2xvcjogQ29sb3IuUkVEXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9KVxuICAgICAgICApO1xuXG4gICAgICAgIGFsYldpZGdldHMucHVzaChcbiAgICAgICAgICBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgICAgICAgaGVpZ2h0OiA4LFxuICAgICAgICAgICAgd2lkdGg6IDgsXG4gICAgICAgICAgICB0aXRsZTogYExhdGVuY3kgWi1TY29yZSAoJHtsYXRlbmN5U3RhdGlzdGljfSlgLFxuICAgICAgICAgICAgcmVnaW9uOiBBd3MuUkVHSU9OLFxuICAgICAgICAgICAgbGVmdDogT2JqZWN0LnZhbHVlcyh3ZWlnaHRlZExhdGVuY3laU2NvcmVQZXJab25lKSxcbiAgICAgICAgICAgIGxlZnRZQXhpczoge1xuICAgICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICAgIGxhYmVsOiBcIlNjb3JlXCIsXG4gICAgICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGVmdEFubm90YXRpb25zOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogXCJIaWdoIFNldmVyaXR5XCIsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDMsXG4gICAgICAgICAgICAgICAgY29sb3I6IENvbG9yLlJFRFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcblxuICAgICAgICBhbGJXaWRnZXRzLnB1c2goXG4gICAgICAgICAgbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICAgIGhlaWdodDogOCxcbiAgICAgICAgICAgIHdpZHRoOiA4LFxuICAgICAgICAgICAgdGl0bGU6IFwiQW5vbWFsb3VzIEhvc3RzXCIsXG4gICAgICAgICAgICByZWdpb246IEF3cy5SRUdJT04sXG4gICAgICAgICAgICBsZWZ0OiBPYmplY3QudmFsdWVzKHRoaXMuZ2V0VG90YWxBbm9tYWxvdXNIb3N0Q291bnRQZXJab25lKGFsYnMsIHBlcmlvZCwgYXpNYXBwZXIpKSxcbiAgICAgICAgICAgIGxlZnRZQXhpczoge1xuICAgICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICAgIGxhYmVsOiBcIkNvdW50XCIsXG4gICAgICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcblxuICAgICAgICBhbGJXaWRnZXRzLnB1c2goXG4gICAgICAgICAgbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICAgIGhlaWdodDogOCxcbiAgICAgICAgICAgIHdpZHRoOiA4LFxuICAgICAgICAgICAgdGl0bGU6IFwiTWl0aWdhdGVkIEhvc3RzXCIsXG4gICAgICAgICAgICByZWdpb246IEF3cy5SRUdJT04sXG4gICAgICAgICAgICBsZWZ0OiBPYmplY3QudmFsdWVzKHRoaXMuZ2V0VG90YWxNaXRpZ2F0ZWRIb3N0Q291bnRQZXJab25lKGFsYnMsIHBlcmlvZCwgYXpNYXBwZXIpKSxcbiAgICAgICAgICAgIGxlZnRZQXhpczoge1xuICAgICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICAgIGxhYmVsOiBcIkNvdW50XCIsXG4gICAgICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICBcbiAgICAgICAgcmV0dXJuIGFsYldpZGdldHM7XG4gICAgICB9XG59XG4iXX0=
|