@cdklabs/multi-az-observability 0.0.0-alpha.0 → 0.0.1-alpha.0
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 +85 -84
- package/API.md +54 -64
- package/lib/alarmsandrules/AvailabilityAndLatencyAlarmsAndRules.d.ts +15 -0
- package/lib/alarmsandrules/AvailabilityAndLatencyAlarmsAndRules.js +127 -1
- package/lib/alarmsandrules/BaseOperationZonalAlarmsAndRules.d.ts +2 -2
- package/lib/alarmsandrules/BaseOperationZonalAlarmsAndRules.js +1 -18
- package/lib/alarmsandrules/CanaryOperationZonalAlarmsAndRules.d.ts +8 -0
- package/lib/alarmsandrules/CanaryOperationZonalAlarmsAndRules.js +18 -1
- package/lib/alarmsandrules/ServerSideOperationZonalAlarmsAndRules.d.ts +8 -0
- package/lib/alarmsandrules/ServerSideOperationZonalAlarmsAndRules.js +18 -1
- package/lib/alarmsandrules/ServiceAlarmsAndRules.js +3 -3
- package/lib/alarmsandrules/props/CanaryOperationZonalAlarmsAndRulesProps.js +1 -1
- package/lib/azmapper/AvailabilityZoneMapper.js +1 -1
- package/lib/basic_observability/BasicServiceDashboard.js +130 -0
- package/lib/{services → basic_observability}/BasicServiceMultiAZObservability.d.ts +9 -7
- package/lib/basic_observability/BasicServiceMultiAZObservability.js +429 -0
- package/lib/basic_observability/IBasicServiceMultiAZObservability.d.ts +51 -0
- package/lib/basic_observability/IBasicServiceMultiAZObservability.js +5 -0
- package/lib/{dashboards → basic_observability}/props/BasicServiceDashboardProps.d.ts +3 -0
- package/lib/basic_observability/props/BasicServiceDashboardProps.js +3 -0
- package/lib/{services → basic_observability}/props/BasicServiceMultiAZObservabilityProps.d.ts +29 -46
- package/lib/basic_observability/props/BasicServiceMultiAZObservabilityProps.js +5 -0
- package/lib/basic_observability/props/RegionalApplicationLoadBalancerAvailabilityMetricProps.d.ts +8 -0
- package/lib/basic_observability/props/RegionalApplicationLoadBalancerAvailabilityMetricProps.js +3 -0
- package/lib/basic_observability/props/RegionalApplicationLoadBalancerLatencyMetricProps.d.ts +8 -0
- package/lib/basic_observability/props/RegionalApplicationLoadBalancerLatencyMetricProps.js +3 -0
- package/lib/basic_observability/props/ZonalApplicationLoadBalancerAvailabilityMetricProps.d.ts +10 -0
- package/lib/basic_observability/props/ZonalApplicationLoadBalancerAvailabilityMetricProps.js +3 -0
- package/lib/basic_observability/props/ZonalApplicationLoadBalancerLatencyMetricProps.d.ts +10 -0
- package/lib/basic_observability/props/ZonalApplicationLoadBalancerLatencyMetricProps.js +3 -0
- package/lib/canaries/src/canary.zip +0 -0
- package/lib/dashboards/OperationAvailabilityAndLatencyDashboard.js +14 -16
- package/lib/dashboards/ServiceAvailabilityAndLatencyDashboard.js +16 -7
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -2
- package/lib/metrics/ApplicationLoadBalancerMetrics.d.ts +55 -17
- package/lib/metrics/ApplicationLoadBalancerMetrics.js +459 -105
- package/lib/metrics/AvailabilityAndLatencyMetrics.d.ts +0 -11
- package/lib/metrics/AvailabilityAndLatencyMetrics.js +1 -24
- package/lib/metrics/RegionalLatencyMetrics.js +7 -6
- package/lib/metrics/ZonalAvailabilityMetrics.js +2 -2
- package/lib/metrics/ZonalLatencyMetrics.js +4 -3
- package/lib/monitoring/src/monitoring-layer.zip +0 -0
- package/lib/outlier-detection/OutlierDetectionFunction.js +5 -5
- package/lib/outlier-detection/src/outlier-detection.zip +0 -0
- package/lib/outlier-detection/src/scipy-layer.zip +0 -0
- package/lib/services/CanaryMetrics.js +1 -1
- package/lib/services/CanaryTestMetricsOverride.js +1 -1
- package/lib/services/ContributorInsightRuleDetails.js +1 -1
- package/lib/services/InstrumentedServiceMultiAZObservability.js +1 -1
- package/lib/services/Operation.js +1 -1
- package/lib/services/OperationMetricDetails.js +1 -1
- package/lib/services/Service.js +1 -1
- package/lib/services/ServiceMetricDetails.js +1 -1
- package/lib/services/props/MetricDimensions.js +1 -1
- package/lib/utilities/LatencyMetricType.d.ts +5 -1
- package/lib/utilities/LatencyMetricType.js +5 -1
- package/lib/utilities/MetricsHelper.d.ts +13 -0
- package/lib/utilities/MetricsHelper.js +30 -0
- package/package.json +7 -7
- package/lib/dashboards/BasicServiceDashboard.js +0 -130
- package/lib/dashboards/props/BasicServiceDashboardProps.js +0 -3
- package/lib/services/BasicServiceMultiAZObservability.js +0 -504
- package/lib/services/props/BasicServiceMultiAZObservabilityProps.js +0 -3
- /package/lib/{dashboards → basic_observability}/BasicServiceDashboard.d.ts +0 -0
|
@@ -2,126 +2,485 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ApplicationLoadBalancerMetrics = void 0;
|
|
4
4
|
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
|
|
5
|
+
const aws_elasticloadbalancingv2_1 = require("aws-cdk-lib/aws-elasticloadbalancingv2");
|
|
6
|
+
const AvailabilityMetricType_1 = require("../utilities/AvailabilityMetricType");
|
|
7
|
+
const MetricsHelper_1 = require("../utilities/MetricsHelper");
|
|
5
8
|
class ApplicationLoadBalancerMetrics {
|
|
6
9
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* @param
|
|
10
|
-
* @
|
|
11
|
-
* @returns
|
|
10
|
+
* Gets the TargetResponseTime latency for the ALB
|
|
11
|
+
* targets
|
|
12
|
+
* @param props The request props
|
|
13
|
+
* @returns The TargetResponseTime metric for the ALB in the specified AZ
|
|
12
14
|
*/
|
|
13
|
-
static
|
|
15
|
+
static getPerAZLatencyMetric(props) {
|
|
16
|
+
return props.alb.metrics.targetResponseTime({
|
|
17
|
+
dimensionsMap: {
|
|
18
|
+
AvailabilityZone: props.availabilityZone,
|
|
19
|
+
LoadBalancer: props.alb
|
|
20
|
+
.loadBalancerFullName,
|
|
21
|
+
},
|
|
22
|
+
label: props.availabilityZoneId ? props.availabilityZoneId : props.availabilityZone + "-target-response-time",
|
|
23
|
+
period: props.period,
|
|
24
|
+
statistic: props.statistic,
|
|
25
|
+
unit: aws_cloudwatch_1.Unit.SECONDS
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Gets either the successful, fault, or total count metrics
|
|
30
|
+
* for the load balancer targets across all of the provided
|
|
31
|
+
* ALBs in each AZ.
|
|
32
|
+
* @param albs The ALBs to aggregate the count of
|
|
33
|
+
* @param props The request props
|
|
34
|
+
* @returns The total count of sucess, faults, or total requests in the specified AZ
|
|
35
|
+
*/
|
|
36
|
+
static getPerAZAvailabilityMetricCountAggregate(albs, props) {
|
|
37
|
+
let keyprefix = props.keyprefix ? props.keyprefix : props.availabilityZone.substring(props.availabilityZone.length - 1);
|
|
38
|
+
let usingMetrics = {};
|
|
39
|
+
let metrics = [];
|
|
40
|
+
albs.forEach((alb) => {
|
|
41
|
+
let target5xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_5XX_COUNT, {
|
|
42
|
+
dimensionsMap: {
|
|
43
|
+
AvailabilityZone: props.availabilityZone,
|
|
44
|
+
LoadBalancer: alb
|
|
45
|
+
.loadBalancerFullName,
|
|
46
|
+
},
|
|
47
|
+
label: props.availabilityZoneId + "-" + alb.loadBalancerArn + "-target-5xx",
|
|
48
|
+
period: props.period,
|
|
49
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
50
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
51
|
+
});
|
|
52
|
+
let elb5xx = alb.metrics.httpCodeElb(aws_elasticloadbalancingv2_1.HttpCodeElb.ELB_5XX_COUNT, {
|
|
53
|
+
dimensionsMap: {
|
|
54
|
+
AvailabilityZone: props.availabilityZone,
|
|
55
|
+
LoadBalancer: alb
|
|
56
|
+
.loadBalancerFullName,
|
|
57
|
+
},
|
|
58
|
+
label: props.availabilityZoneId + "-" + alb.loadBalancerArn + "-elb-5xx",
|
|
59
|
+
period: props.period,
|
|
60
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
61
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
62
|
+
});
|
|
63
|
+
let requestCount = alb.metrics.requestCount({
|
|
64
|
+
dimensionsMap: {
|
|
65
|
+
AvailabilityZone: props.availabilityZone,
|
|
66
|
+
LoadBalancer: alb
|
|
67
|
+
.loadBalancerFullName,
|
|
68
|
+
},
|
|
69
|
+
label: props.availabilityZoneId + "-" + alb.loadBalancerArn + "-request-count",
|
|
70
|
+
period: props.period,
|
|
71
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
72
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
73
|
+
});
|
|
74
|
+
let target2xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_2XX_COUNT, {
|
|
75
|
+
dimensionsMap: {
|
|
76
|
+
AvailabilityZone: props.availabilityZone,
|
|
77
|
+
LoadBalancer: alb
|
|
78
|
+
.loadBalancerFullName,
|
|
79
|
+
},
|
|
80
|
+
label: props.availabilityZoneId + "-" + alb.loadBalancerArn + "-target-2xx",
|
|
81
|
+
period: props.period,
|
|
82
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
83
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
84
|
+
});
|
|
85
|
+
let elb3xx = alb.metrics.httpCodeElb(aws_elasticloadbalancingv2_1.HttpCodeElb.ELB_3XX_COUNT, {
|
|
86
|
+
dimensionsMap: {
|
|
87
|
+
AvailabilityZone: props.availabilityZone,
|
|
88
|
+
LoadBalancer: alb
|
|
89
|
+
.loadBalancerFullName,
|
|
90
|
+
},
|
|
91
|
+
label: props.availabilityZoneId + "-" + alb.loadBalancerArn + "-elb-3xx",
|
|
92
|
+
period: props.period,
|
|
93
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
94
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
95
|
+
});
|
|
96
|
+
let target3xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_3XX_COUNT, {
|
|
97
|
+
dimensionsMap: {
|
|
98
|
+
AvailabilityZone: props.availabilityZone,
|
|
99
|
+
LoadBalancer: alb
|
|
100
|
+
.loadBalancerFullName,
|
|
101
|
+
},
|
|
102
|
+
label: props.availabilityZoneId + "-" + alb.loadBalancerArn + "-target-3xx",
|
|
103
|
+
period: props.period,
|
|
104
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
105
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
106
|
+
});
|
|
107
|
+
switch (props.metricType) {
|
|
108
|
+
case AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT:
|
|
109
|
+
usingMetrics[`${keyprefix}1`] = target5xx;
|
|
110
|
+
usingMetrics[`${keyprefix}2`] = elb5xx;
|
|
111
|
+
metrics.push(new aws_cloudwatch_1.MathExpression({
|
|
112
|
+
expression: `${keyprefix}1+${keyprefix}2`,
|
|
113
|
+
usingMetrics: usingMetrics,
|
|
114
|
+
label: props.availabilityZoneId + "-" + alb.loadBalancerArn + "-fault-count",
|
|
115
|
+
period: props.period,
|
|
116
|
+
}));
|
|
117
|
+
break;
|
|
118
|
+
case AvailabilityMetricType_1.AvailabilityMetricType.SUCCESS_COUNT:
|
|
119
|
+
usingMetrics[`${keyprefix}1`] = target2xx;
|
|
120
|
+
usingMetrics[`${keyprefix}2`] = target3xx;
|
|
121
|
+
usingMetrics[`${keyprefix}3`] = elb3xx;
|
|
122
|
+
metrics.push(new aws_cloudwatch_1.MathExpression({
|
|
123
|
+
expression: `${keyprefix}1+${keyprefix}2+${keyprefix}3`,
|
|
124
|
+
usingMetrics: usingMetrics,
|
|
125
|
+
label: props.availabilityZoneId + "-" + alb.loadBalancerArn + "-success-count",
|
|
126
|
+
period: props.period,
|
|
127
|
+
}));
|
|
128
|
+
break;
|
|
129
|
+
case AvailabilityMetricType_1.AvailabilityMetricType.REQUEST_COUNT:
|
|
130
|
+
metrics.push(requestCount);
|
|
131
|
+
break;
|
|
132
|
+
default:
|
|
133
|
+
throw new Error("This method only supports COUNT availability metrics.");
|
|
134
|
+
}
|
|
135
|
+
keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
|
|
136
|
+
});
|
|
137
|
+
metrics.forEach((metric, index) => {
|
|
138
|
+
usingMetrics[`${keyprefix}${index}`] = metric;
|
|
139
|
+
});
|
|
14
140
|
return new aws_cloudwatch_1.MathExpression({
|
|
15
|
-
expression:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
141
|
+
expression: Object.keys(usingMetrics).join("+"),
|
|
142
|
+
usingMetrics: usingMetrics,
|
|
143
|
+
label: props.label,
|
|
144
|
+
period: props.period,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Gets a specified availability metric in the specified AZ for the ALB
|
|
149
|
+
* @param alb The ALB
|
|
150
|
+
* @param props The request props
|
|
151
|
+
* @returns The metric requested
|
|
152
|
+
*/
|
|
153
|
+
static getPerAZAvailabilityMetric(alb, props) {
|
|
154
|
+
let keyprefix = props.keyprefix ? props.keyprefix : props.availabilityZone.substring(props.availabilityZone.length - 1);
|
|
155
|
+
let target5xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_5XX_COUNT, {
|
|
156
|
+
dimensionsMap: {
|
|
157
|
+
AvailabilityZone: props.availabilityZone,
|
|
158
|
+
LoadBalancer: alb
|
|
159
|
+
.loadBalancerFullName,
|
|
160
|
+
},
|
|
161
|
+
label: props.availabilityZoneId + "-target-5xx",
|
|
162
|
+
period: props.period,
|
|
163
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
164
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
165
|
+
});
|
|
166
|
+
let elb5xx = alb.metrics.httpCodeElb(aws_elasticloadbalancingv2_1.HttpCodeElb.ELB_5XX_COUNT, {
|
|
167
|
+
dimensionsMap: {
|
|
168
|
+
AvailabilityZone: props.availabilityZone,
|
|
169
|
+
LoadBalancer: alb
|
|
170
|
+
.loadBalancerFullName,
|
|
171
|
+
},
|
|
172
|
+
label: props.availabilityZoneId + "-elb-5xx",
|
|
173
|
+
period: props.period,
|
|
174
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
175
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
176
|
+
});
|
|
177
|
+
let requestCount = alb.metrics.requestCount({
|
|
178
|
+
dimensionsMap: {
|
|
179
|
+
AvailabilityZone: props.availabilityZone,
|
|
180
|
+
LoadBalancer: alb
|
|
181
|
+
.loadBalancerFullName,
|
|
52
182
|
},
|
|
183
|
+
label: props.availabilityZoneId + "-request-count",
|
|
184
|
+
period: props.period,
|
|
185
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
186
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
53
187
|
});
|
|
188
|
+
let target2xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_2XX_COUNT, {
|
|
189
|
+
dimensionsMap: {
|
|
190
|
+
AvailabilityZone: props.availabilityZone,
|
|
191
|
+
LoadBalancer: alb
|
|
192
|
+
.loadBalancerFullName,
|
|
193
|
+
},
|
|
194
|
+
label: props.availabilityZoneId + "-target-2xx",
|
|
195
|
+
period: props.period,
|
|
196
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
197
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
198
|
+
});
|
|
199
|
+
let elb3xx = alb.metrics.httpCodeElb(aws_elasticloadbalancingv2_1.HttpCodeElb.ELB_3XX_COUNT, {
|
|
200
|
+
dimensionsMap: {
|
|
201
|
+
AvailabilityZone: props.availabilityZone,
|
|
202
|
+
LoadBalancer: alb
|
|
203
|
+
.loadBalancerFullName,
|
|
204
|
+
},
|
|
205
|
+
label: props.availabilityZoneId + "-elb-3xx",
|
|
206
|
+
period: props.period,
|
|
207
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
208
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
209
|
+
});
|
|
210
|
+
let target3xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_3XX_COUNT, {
|
|
211
|
+
dimensionsMap: {
|
|
212
|
+
AvailabilityZone: props.availabilityZone,
|
|
213
|
+
LoadBalancer: alb
|
|
214
|
+
.loadBalancerFullName,
|
|
215
|
+
},
|
|
216
|
+
label: props.availabilityZoneId + "-target-3xx",
|
|
217
|
+
period: props.period,
|
|
218
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
219
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
220
|
+
});
|
|
221
|
+
let usingMetrics = {};
|
|
222
|
+
switch (props.metricType) {
|
|
223
|
+
case AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT:
|
|
224
|
+
usingMetrics[`${keyprefix}1`] = target5xx;
|
|
225
|
+
usingMetrics[`${keyprefix}2`] = elb5xx;
|
|
226
|
+
return new aws_cloudwatch_1.MathExpression({
|
|
227
|
+
expression: `${keyprefix}1+${keyprefix}2`,
|
|
228
|
+
usingMetrics: usingMetrics,
|
|
229
|
+
label: props.label,
|
|
230
|
+
period: props.period,
|
|
231
|
+
});
|
|
232
|
+
case AvailabilityMetricType_1.AvailabilityMetricType.FAULT_RATE:
|
|
233
|
+
usingMetrics[`${keyprefix}1`] = target5xx;
|
|
234
|
+
usingMetrics[`${keyprefix}2`] = elb5xx;
|
|
235
|
+
usingMetrics[`${keyprefix}3`] = requestCount;
|
|
236
|
+
return new aws_cloudwatch_1.MathExpression({
|
|
237
|
+
expression: `((${keyprefix}1+${keyprefix}2)/${keyprefix}3)*100`,
|
|
238
|
+
usingMetrics: usingMetrics,
|
|
239
|
+
label: props.label,
|
|
240
|
+
period: props.period,
|
|
241
|
+
});
|
|
242
|
+
case AvailabilityMetricType_1.AvailabilityMetricType.SUCCESS_COUNT:
|
|
243
|
+
usingMetrics[`${keyprefix}1`] = target2xx;
|
|
244
|
+
usingMetrics[`${keyprefix}2`] = target3xx;
|
|
245
|
+
usingMetrics[`${keyprefix}3`] = elb3xx;
|
|
246
|
+
return new aws_cloudwatch_1.MathExpression({
|
|
247
|
+
expression: `${keyprefix}1+${keyprefix}2+${keyprefix}3`,
|
|
248
|
+
usingMetrics: usingMetrics,
|
|
249
|
+
label: props.label,
|
|
250
|
+
period: props.period,
|
|
251
|
+
});
|
|
252
|
+
case AvailabilityMetricType_1.AvailabilityMetricType.SUCCESS_RATE:
|
|
253
|
+
usingMetrics[`${keyprefix}1`] = target2xx;
|
|
254
|
+
usingMetrics[`${keyprefix}2`] = target3xx;
|
|
255
|
+
usingMetrics[`${keyprefix}3`] = elb3xx;
|
|
256
|
+
usingMetrics[`${keyprefix}4`] = requestCount;
|
|
257
|
+
return new aws_cloudwatch_1.MathExpression({
|
|
258
|
+
expression: `((${keyprefix}1+${keyprefix}2+${keyprefix}3)/${keyprefix}4)*100`,
|
|
259
|
+
usingMetrics: usingMetrics,
|
|
260
|
+
label: props.label,
|
|
261
|
+
period: props.period,
|
|
262
|
+
});
|
|
263
|
+
case AvailabilityMetricType_1.AvailabilityMetricType.REQUEST_COUNT:
|
|
264
|
+
return requestCount;
|
|
265
|
+
}
|
|
54
266
|
}
|
|
55
267
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* @param
|
|
59
|
-
* @param
|
|
60
|
-
* @
|
|
268
|
+
* Gets the ALBs specified availability metric at the regional level (only looks
|
|
269
|
+
* at the regional dimension for the targets, not per AZ)
|
|
270
|
+
* @param alb The ALB
|
|
271
|
+
* @param props The request props
|
|
272
|
+
* @returns The regional availability metric requested
|
|
273
|
+
*/
|
|
274
|
+
static getRegionalAvailabilityMetric(alb, props) {
|
|
275
|
+
let keyprefix = props.keyprefix ? props.keyprefix : "a";
|
|
276
|
+
let target5xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_5XX_COUNT, {
|
|
277
|
+
dimensionsMap: {
|
|
278
|
+
LoadBalancer: alb
|
|
279
|
+
.loadBalancerFullName,
|
|
280
|
+
},
|
|
281
|
+
label: "target-5xx",
|
|
282
|
+
period: props.period,
|
|
283
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
284
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
285
|
+
});
|
|
286
|
+
let elb5xx = alb.metrics.httpCodeElb(aws_elasticloadbalancingv2_1.HttpCodeElb.ELB_5XX_COUNT, {
|
|
287
|
+
dimensionsMap: {
|
|
288
|
+
LoadBalancer: alb
|
|
289
|
+
.loadBalancerFullName,
|
|
290
|
+
},
|
|
291
|
+
label: "elb-5xx",
|
|
292
|
+
period: props.period,
|
|
293
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
294
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
295
|
+
});
|
|
296
|
+
let requestCount = alb.metrics.requestCount({
|
|
297
|
+
dimensionsMap: {
|
|
298
|
+
LoadBalancer: alb
|
|
299
|
+
.loadBalancerFullName,
|
|
300
|
+
},
|
|
301
|
+
label: "request-count",
|
|
302
|
+
period: props.period,
|
|
303
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
304
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
305
|
+
});
|
|
306
|
+
let target2xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_2XX_COUNT, {
|
|
307
|
+
dimensionsMap: {
|
|
308
|
+
LoadBalancer: alb
|
|
309
|
+
.loadBalancerFullName,
|
|
310
|
+
},
|
|
311
|
+
label: "target-2xx",
|
|
312
|
+
period: props.period,
|
|
313
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
314
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
315
|
+
});
|
|
316
|
+
let elb3xx = alb.metrics.httpCodeElb(aws_elasticloadbalancingv2_1.HttpCodeElb.ELB_3XX_COUNT, {
|
|
317
|
+
dimensionsMap: {
|
|
318
|
+
LoadBalancer: alb
|
|
319
|
+
.loadBalancerFullName,
|
|
320
|
+
},
|
|
321
|
+
label: "elb-3xx",
|
|
322
|
+
period: props.period,
|
|
323
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
324
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
325
|
+
});
|
|
326
|
+
let target3xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_3XX_COUNT, {
|
|
327
|
+
dimensionsMap: {
|
|
328
|
+
LoadBalancer: alb
|
|
329
|
+
.loadBalancerFullName,
|
|
330
|
+
},
|
|
331
|
+
label: "target-3xx",
|
|
332
|
+
period: props.period,
|
|
333
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
334
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
335
|
+
});
|
|
336
|
+
let usingMetrics = {};
|
|
337
|
+
switch (props.metricType) {
|
|
338
|
+
case AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT:
|
|
339
|
+
usingMetrics[`${keyprefix}1`] = target5xx;
|
|
340
|
+
usingMetrics[`${keyprefix}2`] = elb5xx;
|
|
341
|
+
return new aws_cloudwatch_1.MathExpression({
|
|
342
|
+
expression: `${keyprefix}1+${keyprefix}2`,
|
|
343
|
+
usingMetrics: usingMetrics,
|
|
344
|
+
label: props.label,
|
|
345
|
+
period: props.period,
|
|
346
|
+
});
|
|
347
|
+
case AvailabilityMetricType_1.AvailabilityMetricType.FAULT_RATE:
|
|
348
|
+
usingMetrics[`${keyprefix}1`] = target5xx;
|
|
349
|
+
usingMetrics[`${keyprefix}2`] = elb5xx;
|
|
350
|
+
usingMetrics[`${keyprefix}3`] = requestCount;
|
|
351
|
+
return new aws_cloudwatch_1.MathExpression({
|
|
352
|
+
expression: `((${keyprefix}1+${keyprefix}2)/${keyprefix}3)*100`,
|
|
353
|
+
usingMetrics: usingMetrics,
|
|
354
|
+
label: props.label,
|
|
355
|
+
period: props.period,
|
|
356
|
+
});
|
|
357
|
+
case AvailabilityMetricType_1.AvailabilityMetricType.SUCCESS_COUNT:
|
|
358
|
+
usingMetrics[`${keyprefix}1`] = target2xx;
|
|
359
|
+
usingMetrics[`${keyprefix}2`] = target3xx;
|
|
360
|
+
usingMetrics[`${keyprefix}3`] = elb3xx;
|
|
361
|
+
return new aws_cloudwatch_1.MathExpression({
|
|
362
|
+
expression: `${keyprefix}1+${keyprefix}2+${keyprefix}3`,
|
|
363
|
+
usingMetrics: usingMetrics,
|
|
364
|
+
label: props.label,
|
|
365
|
+
period: props.period,
|
|
366
|
+
});
|
|
367
|
+
case AvailabilityMetricType_1.AvailabilityMetricType.SUCCESS_RATE:
|
|
368
|
+
usingMetrics[`${keyprefix}1`] = target2xx;
|
|
369
|
+
usingMetrics[`${keyprefix}2`] = target3xx;
|
|
370
|
+
usingMetrics[`${keyprefix}3`] = elb3xx;
|
|
371
|
+
usingMetrics[`${keyprefix}4`] = requestCount;
|
|
372
|
+
return new aws_cloudwatch_1.MathExpression({
|
|
373
|
+
expression: `((${keyprefix}1+${keyprefix}2+${keyprefix}3)/${keyprefix}4)*100`,
|
|
374
|
+
usingMetrics: usingMetrics,
|
|
375
|
+
label: props.label,
|
|
376
|
+
period: props.period,
|
|
377
|
+
});
|
|
378
|
+
case AvailabilityMetricType_1.AvailabilityMetricType.REQUEST_COUNT:
|
|
379
|
+
return requestCount;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Gets the ALB's TargetResponseTime metric at the regional level (only looks
|
|
384
|
+
* at the regional dimension for the targets, not per AZ)
|
|
385
|
+
* @param props The request props
|
|
61
386
|
* @returns
|
|
62
387
|
*/
|
|
63
|
-
static
|
|
64
|
-
return
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
388
|
+
static getRegionalLatencyMetric(props) {
|
|
389
|
+
return props.alb.metrics.targetResponseTime({
|
|
390
|
+
dimensionsMap: {
|
|
391
|
+
LoadBalancer: props.alb
|
|
392
|
+
.loadBalancerFullName,
|
|
393
|
+
},
|
|
394
|
+
label: "target-response-time",
|
|
395
|
+
period: props.period,
|
|
396
|
+
statistic: props.statistic,
|
|
397
|
+
unit: aws_cloudwatch_1.Unit.SECONDS
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Calculates the total number of faults for all ALBs combined per AZ
|
|
402
|
+
* @param albs The ALBs to aggregate
|
|
403
|
+
* @param period The period of time to calculate the metrics
|
|
404
|
+
* @param azMapper The AZ mapper function so the metrics are correctly labeled with their AZ ID
|
|
405
|
+
* @returns
|
|
406
|
+
*/
|
|
407
|
+
static getTotalAlbFaultCountPerZone(albs, period, azMapper) {
|
|
408
|
+
let faultsPerZone = {};
|
|
409
|
+
let metricsPerAZ = {};
|
|
410
|
+
let keyprefix = MetricsHelper_1.MetricsHelper.nextChar('');
|
|
411
|
+
albs.forEach((alb) => {
|
|
412
|
+
alb.vpc.availabilityZones.forEach((availabilityZone) => {
|
|
413
|
+
if (!(availabilityZone in metricsPerAZ)) {
|
|
414
|
+
metricsPerAZ[availabilityZone] = [];
|
|
415
|
+
}
|
|
416
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
417
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
418
|
+
// 5xx responses from targets
|
|
419
|
+
let target5xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_5XX_COUNT, {
|
|
75
420
|
dimensionsMap: {
|
|
76
|
-
|
|
77
|
-
|
|
421
|
+
AvailabilityZone: availabilityZone,
|
|
422
|
+
LoadBalancer: alb
|
|
423
|
+
.loadBalancerFullName,
|
|
78
424
|
},
|
|
79
|
-
label:
|
|
80
|
-
}),
|
|
81
|
-
m2: new aws_cloudwatch_1.Metric({
|
|
82
|
-
metricName: 'HTTPCode_ELB_5XX_Count',
|
|
83
|
-
namespace: 'AWS/ApplicationELB',
|
|
84
|
-
unit: aws_cloudwatch_1.Unit.COUNT,
|
|
425
|
+
label: availabilityZoneId,
|
|
85
426
|
period: period,
|
|
86
|
-
statistic:
|
|
427
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
428
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
429
|
+
});
|
|
430
|
+
// 5xx responses from ELB
|
|
431
|
+
let elb5xx = alb.metrics.httpCodeElb(aws_elasticloadbalancingv2_1.HttpCodeElb.ELB_5XX_COUNT, {
|
|
87
432
|
dimensionsMap: {
|
|
88
|
-
|
|
89
|
-
|
|
433
|
+
AvailabilityZone: availabilityZone,
|
|
434
|
+
LoadBalancer: alb
|
|
435
|
+
.loadBalancerFullName,
|
|
90
436
|
},
|
|
91
|
-
label:
|
|
92
|
-
}),
|
|
93
|
-
m3: new aws_cloudwatch_1.Metric({
|
|
94
|
-
metricName: 'RequestCount',
|
|
95
|
-
namespace: 'AWS/ApplicationELB',
|
|
96
|
-
unit: aws_cloudwatch_1.Unit.COUNT,
|
|
437
|
+
label: availabilityZoneId,
|
|
97
438
|
period: period,
|
|
98
|
-
statistic:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
439
|
+
statistic: aws_cloudwatch_1.Stats.SUM,
|
|
440
|
+
unit: aws_cloudwatch_1.Unit.COUNT
|
|
441
|
+
});
|
|
442
|
+
let usingMetrics = {};
|
|
443
|
+
usingMetrics[`${keyprefix}1`] = elb5xx;
|
|
444
|
+
usingMetrics[`${keyprefix}2`] = target5xx;
|
|
445
|
+
metricsPerAZ[availabilityZone].push(new aws_cloudwatch_1.MathExpression({
|
|
446
|
+
expression: `${keyprefix}1 + ${keyprefix}2`,
|
|
447
|
+
usingMetrics: usingMetrics,
|
|
448
|
+
period: period
|
|
449
|
+
}));
|
|
450
|
+
keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
|
|
451
|
+
});
|
|
106
452
|
});
|
|
453
|
+
Object.keys(metricsPerAZ).forEach((availabilityZone) => {
|
|
454
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
455
|
+
let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
456
|
+
let usingMetrics = {};
|
|
457
|
+
metricsPerAZ[availabilityZone].forEach((metric) => {
|
|
458
|
+
usingMetrics[`${keyprefix}1`] = metric;
|
|
459
|
+
});
|
|
460
|
+
faultsPerZone[availabilityZone] = new aws_cloudwatch_1.MathExpression({
|
|
461
|
+
expression: Object.keys(usingMetrics).join("+"),
|
|
462
|
+
usingMetrics: usingMetrics,
|
|
463
|
+
label: availabilityZoneId + "-total-faults",
|
|
464
|
+
period: period
|
|
465
|
+
});
|
|
466
|
+
});
|
|
467
|
+
return faultsPerZone;
|
|
107
468
|
}
|
|
108
469
|
/**
|
|
109
|
-
* Creates a
|
|
470
|
+
* Creates a zonal processed bytes metric for the specified load balancer
|
|
110
471
|
* @param loadBalancerFullName
|
|
472
|
+
* @param availabilityZoneName
|
|
111
473
|
* @param period
|
|
112
|
-
* @returns
|
|
474
|
+
* @returns IMetric
|
|
113
475
|
*/
|
|
114
|
-
static
|
|
115
|
-
return
|
|
116
|
-
metricName: 'ProcessedBytes',
|
|
117
|
-
namespace: 'AWS/ApplicationELB',
|
|
118
|
-
unit: aws_cloudwatch_1.Unit.COUNT,
|
|
476
|
+
static getPerAZProcessedBytesMetric(alb, availabilityZone, availabilityZoneId, period) {
|
|
477
|
+
return alb.metrics.processedBytes({
|
|
119
478
|
period: period,
|
|
120
|
-
statistic: 'Sum',
|
|
121
479
|
dimensionsMap: {
|
|
122
|
-
LoadBalancer: loadBalancerFullName,
|
|
480
|
+
LoadBalancer: alb.loadBalancerFullName,
|
|
481
|
+
AvailabilityZone: availabilityZone,
|
|
123
482
|
},
|
|
124
|
-
label:
|
|
483
|
+
label: availabilityZoneId + "-" + alb.loadBalancerArn + "-processed-bytes"
|
|
125
484
|
});
|
|
126
485
|
}
|
|
127
486
|
/**
|
|
@@ -131,20 +490,15 @@ class ApplicationLoadBalancerMetrics {
|
|
|
131
490
|
* @param period
|
|
132
491
|
* @returns IMetric
|
|
133
492
|
*/
|
|
134
|
-
static
|
|
135
|
-
return
|
|
136
|
-
metricName: 'ProcessedBytes',
|
|
137
|
-
namespace: 'AWS/ApplicationELB',
|
|
138
|
-
unit: aws_cloudwatch_1.Unit.COUNT,
|
|
493
|
+
static getRegionalProcessedBytesMetric(alb, period) {
|
|
494
|
+
return alb.metrics.processedBytes({
|
|
139
495
|
period: period,
|
|
140
|
-
statistic: 'Sum',
|
|
141
496
|
dimensionsMap: {
|
|
142
|
-
LoadBalancer: loadBalancerFullName,
|
|
143
|
-
AvailabilityZone: availabilityZoneName,
|
|
497
|
+
LoadBalancer: alb.loadBalancerFullName,
|
|
144
498
|
},
|
|
145
|
-
label:
|
|
499
|
+
label: alb.loadBalancerArn + "-processed-bytes"
|
|
146
500
|
});
|
|
147
501
|
}
|
|
148
502
|
}
|
|
149
503
|
exports.ApplicationLoadBalancerMetrics = ApplicationLoadBalancerMetrics;
|
|
150
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21ldHJpY3MvQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUdBLCtEQUtvQztBQUVwQyxNQUFhLDhCQUE4QjtJQUN6Qzs7Ozs7O09BTUc7SUFDSCxNQUFNLENBQUMsb0RBQW9ELENBQ3pELG9CQUE0QixFQUM1QixNQUFnQjtRQUVoQixPQUFPLElBQUksK0JBQWMsQ0FBQztZQUN4QixVQUFVLEVBQUUsd0JBQXdCO1lBQ3BDLEtBQUssRUFBRSxZQUFZO1lBQ25CLE1BQU0sRUFBRSxNQUFNO1lBQ2QsWUFBWSxFQUFFO2dCQUNaLEVBQUUsRUFBRSxJQUFJLHVCQUFNLENBQUM7b0JBQ2IsVUFBVSxFQUFFLDJCQUEyQjtvQkFDdkMsU0FBUyxFQUFFLG9CQUFvQjtvQkFDL0IsSUFBSSxFQUFFLHFCQUFJLENBQUMsS0FBSztvQkFDaEIsTUFBTSxFQUFFLE1BQU07b0JBQ2QsU0FBUyxFQUFFLEtBQUs7b0JBQ2hCLGFBQWEsRUFBRTt3QkFDYixZQUFZLEVBQUUsb0JBQW9CO3FCQUNuQztvQkFDRCxLQUFLLEVBQUUsV0FBVztpQkFDbkIsQ0FBQztnQkFDRixFQUFFLEVBQUUsSUFBSSx1QkFBTSxDQUFDO29CQUNiLFVBQVUsRUFBRSx3QkFBd0I7b0JBQ3BDLFNBQVMsRUFBRSxvQkFBb0I7b0JBQy9CLElBQUksRUFBRSxxQkFBSSxDQUFDLEtBQUs7b0JBQ2hCLE1BQU0sRUFBRSxNQUFNO29CQUNkLFNBQVMsRUFBRSxLQUFLO29CQUNoQixhQUFhLEVBQUU7d0JBQ2IsWUFBWSxFQUFFLG9CQUFvQjtxQkFDbkM7b0JBQ0QsS0FBSyxFQUFFLFFBQVE7aUJBQ2hCLENBQUM7Z0JBQ0YsRUFBRSxFQUFFLElBQUksdUJBQU0sQ0FBQztvQkFDYixVQUFVLEVBQUUsY0FBYztvQkFDMUIsU0FBUyxF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QUFnQjtTQUN4QixDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUFoS0Qsd0VBZ0tDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuaW1wb3J0IHsgRHVyYXRpb24gfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQge1xuICBJTWV0cmljLFxuICBNYXRoRXhwcmVzc2lvbixcbiAgTWV0cmljLFxuICBVbml0LFxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaCc7XG5cbmV4cG9ydCBjbGFzcyBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3Mge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlZ2lvbmFsIGZhdWx0IGNvdW50IG1ldHJpYyB1c2luZyA1eHggdGFyZ2V0IGFuZCBsb2FkIGJhbGFuY2VyXG4gICAqIG1ldHJpY3MgYWdhaW5zdCB0b3RhbCByZXF1ZXN0cyBmb3IgdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyXG4gICAqIEBwYXJhbSBwZXJpb2RcbiAgICogQHBhcmFtIGxvYWRCYWxhbmNlckZ1bGxOYW1lXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckZhdWx0UmF0ZU1ldHJpYyhcbiAgICBsb2FkQmFsYW5jZXJGdWxsTmFtZTogc3RyaW5nLFxuICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICk6IElNZXRyaWMge1xuICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgZXhwcmVzc2lvbjogJygobTEgKyBtMikgLyBtMykgKiAxMDAnLFxuICAgICAgbGFiZWw6ICdGYXVsdCBSYXRlJyxcbiAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgdXNpbmdNZXRyaWNzOiB7XG4gICAgICAgIG0xOiBuZXcgTWV0cmljKHtcbiAgICAgICAgICBtZXRyaWNOYW1lOiAnSFRUUENvZGVfVGFyZ2V0XzVYWF9Db3VudCcsXG4gICAgICAgICAgbmFtZXNwYWNlOiAnQVdTL0FwcGxpY2F0aW9uRUxCJyxcbiAgICAgICAgICB1bml0OiBVbml0LkNPVU5ULFxuICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgIHN0YXRpc3RpYzogJ1N1bScsXG4gICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiBsb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxhYmVsOiAnNXh4VGFyZ2V0JyxcbiAgICAgICAgfSksXG4gICAgICAgIG0yOiBuZXcgTWV0cmljKHtcbiAgICAgICAgICBtZXRyaWNOYW1lOiAnSFRUUENvZGVfRUxCXzVYWF9Db3VudCcsXG4gICAgICAgICAgbmFtZXNwYWNlOiAnQVdTL0FwcGxpY2F0aW9uRUxCJyxcbiAgICAgICAgICB1bml0OiBVbml0LkNPVU5ULFxuICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgIHN0YXRpc3RpYzogJ1N1bScsXG4gICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiBsb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxhYmVsOiAnNXh4RUxCJyxcbiAgICAgICAgfSksXG4gICAgICAgIG0zOiBuZXcgTWV0cmljKHtcbiAgICAgICAgICBtZXRyaWNOYW1lOiAnUmVxdWVzdENvdW50JyxcbiAgICAgICAgICBuYW1lc3BhY2U6ICdBV1MvQXBwbGljYXRpb25FTEInLFxuICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlQsXG4gICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICBMb2FkQmFsYW5jZXI6IGxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbGFiZWw6ICdSZXF1ZXN0cycsXG4gICAgICAgIH0pLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgem9uYWwgZmF1bHQgY291bnQgbWV0cmljIHVzaW5nIDV4eCB0YXJnZXQgYW5kIGxvYWQgYmFsYW5jZXJcbiAgICogbWV0cmljcyBhZ2FpbnN0IHRvdGFsIHJlcXVlc3RzIGZvciB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICogQHBhcmFtIGxvYWRCYWxhbmNlckZ1bGxOYW1lXG4gICAqIEBwYXJhbSBhdmFpbGFiaWxpdHlab25lTmFtZVxuICAgKiBAcGFyYW0gcGVyaW9kXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckZhdWx0UmF0ZU1ldHJpYyhcbiAgICBsb2FkQmFsYW5jZXJGdWxsTmFtZTogc3RyaW5nLFxuICAgIGF2YWlsYWJpbGl0eVpvbmVOYW1lOiBzdHJpbmcsXG4gICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgKTogSU1ldHJpYyB7XG4gICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICBleHByZXNzaW9uOiAnKChtMSArIG0yKSAvIG0zKSAqIDEwMCcsXG4gICAgICBsYWJlbDogJ0ZhdWx0IFJhdGUnLFxuICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICB1c2luZ01ldHJpY3M6IHtcbiAgICAgICAgbTE6IG5ldyBNZXRyaWMoe1xuICAgICAgICAgIG1ldHJpY05hbWU6ICdIVFRQQ29kZV9UYXJnZXRfNVhYX0NvdW50JyxcbiAgICAgICAgICBuYW1lc3BhY2U6ICdBV1MvQXBwbGljYXRpb25FTEInLFxuICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlQsXG4gICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICBMb2FkQmFsYW5jZXI6IGxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZU5hbWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBsYWJlbDogJzV4eFRhcmdldCcsXG4gICAgICAgIH0pLFxuICAgICAgICBtMjogbmV3IE1ldHJpYyh7XG4gICAgICAgICAgbWV0cmljTmFtZTogJ0hUVFBDb2RlX0VMQl81WFhfQ291bnQnLFxuICAgICAgICAgIG5hbWVzcGFjZTogJ0FXUy9BcHBsaWNhdGlvbkVMQicsXG4gICAgICAgICAgdW5pdDogVW5pdC5DT1VOVCxcbiAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICBzdGF0aXN0aWM6ICdTdW0nLFxuICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgIExvYWRCYWxhbmNlcjogbG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lTmFtZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxhYmVsOiAnNXh4RUxCJyxcbiAgICAgICAgfSksXG4gICAgICAgIG0zOiBuZXcgTWV0cmljKHtcbiAgICAgICAgICBtZXRyaWNOYW1lOiAnUmVxdWVzdENvdW50JyxcbiAgICAgICAgICBuYW1lc3BhY2U6ICdBV1MvQXBwbGljYXRpb25FTEInLFxuICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlQsXG4gICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICBMb2FkQmFsYW5jZXI6IGxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZU5hbWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBsYWJlbDogJ1JlcXVlc3RzJyxcbiAgICAgICAgfSksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSByZWdpb25hbCBwcm9jZXNzZWQgYnl0ZXMgbWV0cmljIGZvciB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICogQHBhcmFtIGxvYWRCYWxhbmNlckZ1bGxOYW1lXG4gICAqIEBwYXJhbSBwZXJpb2RcbiAgICogQHJldHVybnNcbiAgICovXG4gIHN0YXRpYyBjcmVhdGVSZWdpb25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyUHJvY2Vzc2VkQnl0ZXNNZXRyaWMoXG4gICAgbG9hZEJhbGFuY2VyRnVsbE5hbWU6IHN0cmluZyxcbiAgICBwZXJpb2Q6IER1cmF0aW9uLFxuICApOiBJTWV0cmljIHtcbiAgICByZXR1cm4gbmV3IE1ldHJpYyh7XG4gICAgICBtZXRyaWNOYW1lOiAnUHJvY2Vzc2VkQnl0ZXMnLFxuICAgICAgbmFtZXNwYWNlOiAnQVdTL0FwcGxpY2F0aW9uRUxCJyxcbiAgICAgIHVuaXQ6IFVuaXQuQ09VTlQsXG4gICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgIHN0YXRpc3RpYzogJ1N1bScsXG4gICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgIExvYWRCYWxhbmNlcjogbG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICB9LFxuICAgICAgbGFiZWw6ICdQcm9jZXNzZWRCeXRlcycsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHpvbmFsIHByb2Nlc3NlZCBieXRlcyBtZXRyaWMgZm9yIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlclxuICAgKiBAcGFyYW0gbG9hZEJhbGFuY2VyRnVsbE5hbWVcbiAgICogQHBhcmFtIGF2YWlsYWJpbGl0eVpvbmVOYW1lXG4gICAqIEBwYXJhbSBwZXJpb2RcbiAgICogQHJldHVybnMgSU1ldHJpY1xuICAgKi9cbiAgc3RhdGljIGNyZWF0ZVpvbmFsQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJQcm9jZXNzZWRCeXRlc01ldHJpYyhcbiAgICBsb2FkQmFsYW5jZXJGdWxsTmFtZTogc3RyaW5nLFxuICAgIGF2YWlsYWJpbGl0eVpvbmVOYW1lOiBzdHJpbmcsXG4gICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgKTogSU1ldHJpYyB7XG4gICAgcmV0dXJuIG5ldyBNZXRyaWMoe1xuICAgICAgbWV0cmljTmFtZTogJ1Byb2Nlc3NlZEJ5dGVzJyxcbiAgICAgIG5hbWVzcGFjZTogJ0FXUy9BcHBsaWNhdGlvbkVMQicsXG4gICAgICB1bml0OiBVbml0LkNPVU5ULFxuICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICBzdGF0aXN0aWM6ICdTdW0nLFxuICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICBMb2FkQmFsYW5jZXI6IGxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lTmFtZSxcbiAgICAgIH0sXG4gICAgICBsYWJlbDogJ1Byb2Nlc3NlZEJ5dGVzJyxcbiAgICB9KTtcbiAgfVxufVxuIl19
|
|
504
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21ldHJpY3MvQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtEQUFrRjtBQUNsRix1RkFBa0o7QUFDbEosZ0ZBQTZFO0FBTzdFLDhEQUEyRDtBQUUzRCxNQUFhLDhCQUE4QjtJQUV2Qzs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxxQkFBcUIsQ0FDeEIsS0FBcUQ7UUFFckQsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FDdkM7WUFDRSxhQUFhLEVBQUU7Z0JBQ2IsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQjtnQkFDeEMsWUFBWSxFQUFHLEtBQUssQ0FBQyxHQUEyQztxQkFDN0Qsb0JBQW9CO2FBQ3hCO1lBQ0QsS0FBSyxFQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEdBQUcsdUJBQXVCO1lBQzdHLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtZQUNwQixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7WUFDMUIsSUFBSSxFQUFFLHFCQUFJLENBQUMsT0FBTztTQUNuQixDQUNGLENBQUM7SUFDUixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILE1BQU0sQ0FBQyx3Q0FBd0MsQ0FDM0MsSUFBZ0MsRUFDaEMsS0FBMEQ7UUFFMUQsSUFBSSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRXhILElBQUks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Ozs7T0FNRztJQUNILE1BQU0sQ0FBQywrQkFBK0IsQ0FDbEMsR0FBNkIsRUFDN0IsTUFBZ0I7UUFFaEIsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQztZQUM5QixNQUFNLEVBQUUsTUFBTTtZQUNkLGFBQWEsRUFBQztnQkFDVixZQUFZLEVBQUcsR0FBMkMsQ0FBQyxvQkFBb0I7YUFDbEY7WUFDRCxLQUFLLEVBQUUsR0FBRyxDQUFDLGVBQWUsR0FBRyxrQkFBa0I7U0FDbEQsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztDQUNKO0FBNW9CRCx3RUE0b0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSU1ldHJpYywgTWF0aEV4cHJlc3Npb24sIFN0YXRzLCBVbml0IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoXCI7XG5pbXBvcnQgeyBCYXNlTG9hZEJhbGFuY2VyLCBIdHRwQ29kZUVsYiwgSHR0cENvZGVUYXJnZXQsIElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgSUxvYWRCYWxhbmNlclYyIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lbGFzdGljbG9hZGJhbGFuY2luZ3YyXCI7XG5pbXBvcnQgeyBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9BdmFpbGFiaWxpdHlNZXRyaWNUeXBlXCI7XG5pbXBvcnQgeyBab25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lNZXRyaWNQcm9wc1wiO1xuaW1wb3J0IHsgWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzXCI7XG5pbXBvcnQgeyBEdXJhdGlvbiB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzXCI7XG5pbXBvcnQgeyBSZWdpb25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lNZXRyaWNQcm9wc1wiO1xuaW1wb3J0IHsgQXZhaWxhYmlsaXR5Wm9uZU1hcHBlciB9IGZyb20gXCIuLi9hem1hcHBlci9BdmFpbGFiaWxpdHlab25lTWFwcGVyXCI7XG5pbXBvcnQgeyBNZXRyaWNzSGVscGVyIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9NZXRyaWNzSGVscGVyXCI7XG5cbmV4cG9ydCBjbGFzcyBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3Mge1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgVGFyZ2V0UmVzcG9uc2VUaW1lIGxhdGVuY3kgZm9yIHRoZSBBTEJcbiAgICAgKiB0YXJnZXRzXG4gICAgICogQHBhcmFtIHByb3BzIFRoZSByZXF1ZXN0IHByb3BzXG4gICAgICogQHJldHVybnMgVGhlIFRhcmdldFJlc3BvbnNlVGltZSBtZXRyaWMgZm9yIHRoZSBBTEIgaW4gdGhlIHNwZWNpZmllZCBBWlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRQZXJBWkxhdGVuY3lNZXRyaWMoXG4gICAgICAgIHByb3BzOiBab25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzXG4gICAgKTogSU1ldHJpYyB7XG4gICAgICAgIHJldHVybiBwcm9wcy5hbGIubWV0cmljcy50YXJnZXRSZXNwb25zZVRpbWUoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKHByb3BzLmFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCA/IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCA6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUgKyBcIi10YXJnZXQtcmVzcG9uc2UtdGltZVwiLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBwcm9wcy5zdGF0aXN0aWMsXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuU0VDT05EU1xuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBlaXRoZXIgdGhlIHN1Y2Nlc3NmdWwsIGZhdWx0LCBvciB0b3RhbCBjb3VudCBtZXRyaWNzXG4gICAgICogZm9yIHRoZSBsb2FkIGJhbGFuY2VyIHRhcmdldHMgYWNyb3NzIGFsbCBvZiB0aGUgcHJvdmlkZWQgXG4gICAgICogQUxCcyBpbiBlYWNoIEFaLlxuICAgICAqIEBwYXJhbSBhbGJzIFRoZSBBTEJzIHRvIGFnZ3JlZ2F0ZSB0aGUgY291bnQgb2ZcbiAgICAgKiBAcGFyYW0gcHJvcHMgVGhlIHJlcXVlc3QgcHJvcHNcbiAgICAgKiBAcmV0dXJucyBUaGUgdG90YWwgY291bnQgb2Ygc3VjZXNzLCBmYXVsdHMsIG9yIHRvdGFsIHJlcXVlc3RzIGluIHRoZSBzcGVjaWZpZWQgQVpcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UGVyQVpBdmFpbGFiaWxpdHlNZXRyaWNDb3VudEFnZ3JlZ2F0ZShcbiAgICAgICAgYWxiczogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyW10sXG4gICAgICAgIHByb3BzOiBab25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5TWV0cmljUHJvcHNcbiAgICApOiBJTWV0cmljIHtcbiAgICAgICAgbGV0IGtleXByZWZpeCA9IHByb3BzLmtleXByZWZpeCA/IHByb3BzLmtleXByZWZpeCA6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKHByb3BzLmF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG5cbiAgICAgICAgbGV0IHVzaW5nTWV0cmljczogeyBba2V5OiBzdHJpbmddOiBJTWV0cmljIH0gPSB7fTtcbiAgICAgICAgbGV0IG1ldHJpY3M6IElNZXRyaWNbXSA9IFtdO1xuXG4gICAgICAgIGFsYnMuZm9yRWFjaCgoYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIpID0+IHtcbiAgICAgICAgICAgIGxldCB0YXJnZXQ1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfNVhYX0NPVU5ULFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItdGFyZ2V0LTV4eFwiLFxuICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAgIGxldCBlbGI1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZUVsYihcbiAgICAgICAgICAgICAgICBIdHRwQ29kZUVsYi5FTEJfNVhYX0NPVU5ULFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItZWxiLTV4eFwiLFxuICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICApO1xuICAgICAgXG4gICAgICAgICAgICAgIGxldCByZXF1ZXN0Q291bnQ6IElNZXRyaWMgPSBhbGIubWV0cmljcy5yZXF1ZXN0Q291bnQoXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi1yZXF1ZXN0LWNvdW50XCIsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKTtcbiAgICAgIFxuICAgICAgICAgICAgICBsZXQgdGFyZ2V0Mnh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzJYWF9DT1VOVCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiArIFwiLXRhcmdldC0yeHhcIixcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICApO1xuICAgICAgXG4gICAgICAgICAgICAgIGxldCBlbGIzeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZUVsYihcbiAgICAgICAgICAgICAgICBIdHRwQ29kZUVsYi5FTEJfM1hYX0NPVU5ULFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItZWxiLTN4eFwiLFxuICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICk7XG4gICAgICBcbiAgICAgICAgICAgICAgbGV0IHRhcmdldDN4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlVGFyZ2V0KFxuICAgICAgICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF8zWFhfQ09VTlQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi10YXJnZXQtM3h4XCIsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKTtcbiAgICAgICBcbiAgICAgICAgICAgICAgc3dpdGNoKHByb3BzLm1ldHJpY1R5cGUpIHtcbiAgICAgICAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5GQVVMVF9DT1VOVDpcbiAgICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IHRhcmdldDV4eDtcbiAgICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IGVsYjV4eDtcbiAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3MucHVzaChuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yYCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi1mYXVsdC1jb3VudFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIFxuICAgICAgICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlQ6XG4gICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQyeHg7XG4gICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQzeHg7XG4gICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSBlbGIzeHg7XG4gICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3MucHVzaChuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yKyR7a2V5cHJlZml4fTNgLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiArIFwiLXN1Y2Nlc3MtY291bnRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuUkVRVUVTVF9DT1VOVDpcbiAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3MucHVzaChyZXF1ZXN0Q291bnQpO1xuICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgbWV0aG9kIG9ubHkgc3VwcG9ydHMgQ09VTlQgYXZhaWxhYmlsaXR5IG1ldHJpY3MuXCIpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGtleXByZWZpeCA9IE1ldHJpY3NIZWxwZXIubmV4dENoYXIoa2V5cHJlZml4KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbWV0cmljcy5mb3JFYWNoKChtZXRyaWM6IElNZXRyaWMsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9JHtpbmRleH1gXSA9IG1ldHJpYztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBleHByZXNzaW9uOiBPYmplY3Qua2V5cyh1c2luZ01ldHJpY3MpLmpvaW4oXCIrXCIpLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIEdldHMgYSBzcGVjaWZpZWQgYXZhaWxhYmlsaXR5IG1ldHJpYyBpbiB0aGUgc3BlY2lmaWVkIEFaIGZvciB0aGUgQUxCXG4gICAgICogQHBhcmFtIGFsYiBUaGUgQUxCXG4gICAgICogQHBhcmFtIHByb3BzIFRoZSByZXF1ZXN0IHByb3BzXG4gICAgICogQHJldHVybnMgVGhlIG1ldHJpYyByZXF1ZXN0ZWRcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UGVyQVpBdmFpbGFiaWxpdHlNZXRyaWMoXG4gICAgICAgIGFsYjogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLCBcbiAgICAgICAgcHJvcHM6IFpvbmFsQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJBdmFpbGFiaWxpdHlNZXRyaWNQcm9wc1xuICAgICk6IElNZXRyaWMge1xuICAgICAgICBsZXQga2V5cHJlZml4ID0gcHJvcHMua2V5cHJlZml4ID8gcHJvcHMua2V5cHJlZml4IDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcocHJvcHMuYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcblxuICAgICAgICBsZXQgdGFyZ2V0NXh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzVYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLXRhcmdldC01eHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIFxuICAgICAgICBsZXQgZWxiNXh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVFbGIoXG4gICAgICAgICAgSHR0cENvZGVFbGIuRUxCXzVYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLWVsYi01eHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgcmVxdWVzdENvdW50OiBJTWV0cmljID0gYWxiLm1ldHJpY3MucmVxdWVzdENvdW50KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItcmVxdWVzdC1jb3VudFwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IHRhcmdldDJ4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlVGFyZ2V0KFxuICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF8yWFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi10YXJnZXQtMnh4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgZWxiM3h4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVFbGIoXG4gICAgICAgICAgSHR0cENvZGVFbGIuRUxCXzNYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLWVsYi0zeHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGxldCB0YXJnZXQzeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfM1hYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItdGFyZ2V0LTN4eFwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IHVzaW5nTWV0cmljczogeyBba2V5OiBzdHJpbmddOiBJTWV0cmljIH0gPSB7fTtcblxuICAgICAgICBzd2l0Y2gocHJvcHMubWV0cmljVHlwZSkge1xuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX0NPVU5UOlxuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gdGFyZ2V0NXh4O1xuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gZWxiNXh4O1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAke2tleXByZWZpeH0xKyR7a2V5cHJlZml4fTJgLFxuICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX1JBVEU6XG4gICAgICAgICAgICAgIFxuICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IHRhcmdldDV4eDtcbiAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSBlbGI1eHg7XG4gICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9M2BdID0gcmVxdWVzdENvdW50O1xuXG4gICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCgoJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yKS8ke2tleXByZWZpeH0zKSoxMDBgLFxuICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5TVUNDRVNTX0NPVU5UOlxuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gdGFyZ2V0Mnh4O1xuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gdGFyZ2V0M3h4O1xuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9M2BdID0gZWxiM3h4O1xuICBcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9Miske2tleXByZWZpeH0zYCxcbiAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5TVUNDRVNTX1JBVEU6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQyeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQzeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSBlbGIzeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH00YF0gPSByZXF1ZXN0Q291bnQ7XG4gIFxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgKCgke2tleXByZWZpeH0xKyR7a2V5cHJlZml4fTIrJHtrZXlwcmVmaXh9MykvJHtrZXlwcmVmaXh9NCkqMTAwYCxcbiAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5SRVFVRVNUX0NPVU5UOlxuICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RDb3VudDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIEFMQnMgc3BlY2lmaWVkIGF2YWlsYWJpbGl0eSBtZXRyaWMgYXQgdGhlIHJlZ2lvbmFsIGxldmVsIChvbmx5IGxvb2tzXG4gICAgICogYXQgdGhlIHJlZ2lvbmFsIGRpbWVuc2lvbiBmb3IgdGhlIHRhcmdldHMsIG5vdCBwZXIgQVopXG4gICAgICogQHBhcmFtIGFsYiBUaGUgQUxCXG4gICAgICogQHBhcmFtIHByb3BzIFRoZSByZXF1ZXN0IHByb3BzXG4gICAgICogQHJldHVybnMgVGhlIHJlZ2lvbmFsIGF2YWlsYWJpbGl0eSBtZXRyaWMgcmVxdWVzdGVkXG4gICAgICovXG4gICAgc3RhdGljIGdldFJlZ2lvbmFsQXZhaWxhYmlsaXR5TWV0cmljKFxuICAgICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgXG4gICAgICAgIHByb3BzOiBSZWdpb25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5TWV0cmljUHJvcHNcbiAgICApOiBJTWV0cmljIHtcbiAgICAgICAgbGV0IGtleXByZWZpeCA9IHByb3BzLmtleXByZWZpeCA/IHByb3BzLmtleXByZWZpeCA6IFwiYVwiO1xuXG4gICAgICAgIGxldCB0YXJnZXQ1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfNVhYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJ0YXJnZXQtNXh4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICBcbiAgICAgICAgbGV0IGVsYjV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl81WFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBcImVsYi01eHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgcmVxdWVzdENvdW50OiBJTWV0cmljID0gYWxiLm1ldHJpY3MucmVxdWVzdENvdW50KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJyZXF1ZXN0LWNvdW50XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgdGFyZ2V0Mnh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzJYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IFwidGFyZ2V0LTJ4eFwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IGVsYjN4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl8zWFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBcImVsYi0zeHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGxldCB0YXJnZXQzeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfM1hYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJ0YXJnZXQtM3h4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuXG4gICAgICAgIHN3aXRjaChwcm9wcy5tZXRyaWNUeXBlKSB7XG4gICAgICAgICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuRkFVTFRfQ09VTlQ6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQ1eHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSBlbGI1eHg7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9MmAsXG4gICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuRkFVTFRfUkFURTpcbiAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gdGFyZ2V0NXh4O1xuICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IGVsYjV4eDtcbiAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSByZXF1ZXN0Q291bnQ7XG5cbiAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgKCgke2tleXByZWZpeH0xKyR7a2V5cHJlZml4fTIpLyR7a2V5cHJlZml4fTMpKjEwMGAsXG4gICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlQ6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQyeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQzeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSBlbGIzeHg7XG4gIFxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yKyR7a2V5cHJlZml4fTNgLFxuICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfUkFURTpcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IHRhcmdldDJ4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IHRhcmdldDN4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTNgXSA9IGVsYjN4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTRgXSA9IHJlcXVlc3RDb3VudDtcbiAgXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAoKCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9Miske2tleXByZWZpeH0zKS8ke2tleXByZWZpeH00KSoxMDBgLFxuICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlJFUVVFU1RfQ09VTlQ6XG4gICAgICAgICAgICAgICByZXR1cm4gcmVxdWVzdENvdW50O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgQUxCJ3MgVGFyZ2V0UmVzcG9uc2VUaW1lIG1ldHJpYyBhdCB0aGUgcmVnaW9uYWwgbGV2ZWwgKG9ubHkgbG9va3NcbiAgICAgKiBhdCB0aGUgcmVnaW9uYWwgZGltZW5zaW9uIGZvciB0aGUgdGFyZ2V0cywgbm90IHBlciBBWilcbiAgICAgKiBAcGFyYW0gcHJvcHMgIFRoZSByZXF1ZXN0IHByb3BzXG4gICAgICogQHJldHVybnMgXG4gICAgICovXG4gICAgc3RhdGljIGdldFJlZ2lvbmFsTGF0ZW5jeU1ldHJpYyhcbiAgICAgICAgcHJvcHM6IFJlZ2lvbmFsQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJMYXRlbmN5TWV0cmljUHJvcHNcbiAgICApOiBJTWV0cmljIHtcbiAgICAgICAgcmV0dXJuIHByb3BzLmFsYi5tZXRyaWNzLnRhcmdldFJlc3BvbnNlVGltZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKHByb3BzLmFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbGFiZWw6IFwidGFyZ2V0LXJlc3BvbnNlLXRpbWVcIixcbiAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgIHN0YXRpc3RpYzogcHJvcHMuc3RhdGlzdGljLFxuICAgICAgICAgICAgICB1bml0OiBVbml0LlNFQ09ORFNcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZXMgdGhlIHRvdGFsIG51bWJlciBvZiBmYXVsdHMgZm9yIGFsbCBBTEJzIGNvbWJpbmVkIHBlciBBWlxuICAgICAqIEBwYXJhbSBhbGJzIFRoZSBBTEJzIHRvIGFnZ3JlZ2F0ZVxuICAgICAqIEBwYXJhbSBwZXJpb2QgVGhlIHBlcmlvZCBvZiB0aW1lIHRvIGNhbGN1bGF0ZSB0aGUgbWV0cmljc1xuICAgICAqIEBwYXJhbSBhek1hcHBlciBUaGUgQVogbWFwcGVyIGZ1bmN0aW9uIHNvIHRoZSBtZXRyaWNzIGFyZSBjb3JyZWN0bHkgbGFiZWxlZCB3aXRoIHRoZWlyIEFaIElEXG4gICAgICogQHJldHVybnMgXG4gICAgICovXG4gICAgc3RhdGljIGdldFRvdGFsQWxiRmF1bHRDb3VudFBlclpvbmUoXG4gICAgICBhbGJzOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJbXSxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBhek1hcHBlcjogQXZhaWxhYmlsaXR5Wm9uZU1hcHBlclxuICAgICkgOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY31cbiAgICB7XG4gICAgICBsZXQgZmF1bHRzUGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG4gICAgICBsZXQgbWV0cmljc1BlckFaOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY1tdfSA9IHt9O1xuICAgICAgbGV0IGtleXByZWZpeDogc3RyaW5nID0gTWV0cmljc0hlbHBlci5uZXh0Q2hhcignJyk7XG4gIFxuICAgICAgYWxicy5mb3JFYWNoKChhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcikgPT4ge1xuICBcbiAgICAgICAgYWxiLnZwYyEuYXZhaWxhYmlsaXR5Wm9uZXMuZm9yRWFjaCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgaWYgKCEoYXZhaWxhYmlsaXR5Wm9uZSBpbiBtZXRyaWNzUGVyQVopKSB7XG4gICAgICAgICAgICBtZXRyaWNzUGVyQVpbYXZhaWxhYmlsaXR5Wm9uZV0gPSBbXTtcbiAgICAgICAgICB9XG4gIFxuICAgICAgICAgIGxldCBhekxldHRlciA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcbiAgXG4gICAgICAgICAgLy8gNXh4IHJlc3BvbnNlcyBmcm9tIHRhcmdldHNcbiAgICAgICAgICBsZXQgdGFyZ2V0NXh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfNVhYX0NPVU5ULFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICAgICAgICBcbiAgICAgICAgICAvLyA1eHggcmVzcG9uc2VzIGZyb20gRUxCXG4gICAgICAgICAgbGV0IGVsYjV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgICAgSHR0cENvZGVFbGIuRUxCXzVYWF9DT1VOVCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgXG4gICAgICAgICAgbGV0IHVzaW5nTWV0cmljczoge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG4gICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSBlbGI1eHg7XG4gICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQ1eHg7XG4gIFxuICAgICAgICAgIG1ldHJpY3NQZXJBWlthdmFpbGFiaWxpdHlab25lXS5wdXNoKG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSArICR7a2V5cHJlZml4fTJgLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZFxuICAgICAgICAgIH0pKTtcbiAgXG4gICAgICAgICAga2V5cHJlZml4ID0gTWV0cmljc0hlbHBlci5uZXh0Q2hhcihrZXlwcmVmaXgpO1xuICAgICAgICB9KTsgICBcbiAgICAgIH0pO1xuICBcbiAgICAgIE9iamVjdC5rZXlzKG1ldHJpY3NQZXJBWikuZm9yRWFjaCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nKSA9PiB7XG4gICAgICAgIGxldCBhekxldHRlciA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQgPSBhek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG4gIFxuICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgXG4gICAgICAgIG1ldHJpY3NQZXJBWlthdmFpbGFiaWxpdHlab25lXS5mb3JFYWNoKChtZXRyaWM6IElNZXRyaWMpID0+IHtcbiAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IG1ldHJpYztcbiAgICAgICAgfSk7XG4gIFxuICAgICAgICBmYXVsdHNQZXJab25lW2F2YWlsYWJpbGl0eVpvbmVdID0gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICBleHByZXNzaW9uOiBPYmplY3Qua2V5cyh1c2luZ01ldHJpY3MpLmpvaW4oXCIrXCIpLFxuICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQgKyBcIi10b3RhbC1mYXVsdHNcIixcbiAgICAgICAgICBwZXJpb2Q6IHBlcmlvZFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICBcbiAgICAgIHJldHVybiBmYXVsdHNQZXJab25lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB6b25hbCBwcm9jZXNzZWQgYnl0ZXMgbWV0cmljIGZvciB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICAgKiBAcGFyYW0gbG9hZEJhbGFuY2VyRnVsbE5hbWVcbiAgICAgKiBAcGFyYW0gYXZhaWxhYmlsaXR5Wm9uZU5hbWVcbiAgICAgKiBAcGFyYW0gcGVyaW9kXG4gICAgICogQHJldHVybnMgSU1ldHJpY1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXRQZXJBWlByb2Nlc3NlZEJ5dGVzTWV0cmljKFxuICAgICAgYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsXG4gICAgICBhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcsXG4gICAgICBhdmFpbGFiaWxpdHlab25lSWQ6IHN0cmluZyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgKTogSU1ldHJpYyB7XG4gICAgICByZXR1cm4gYWxiLm1ldHJpY3MucHJvY2Vzc2VkQnl0ZXMoe1xuICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgIGRpbWVuc2lvbnNNYXA6e1xuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiArIFwiLXByb2Nlc3NlZC1ieXRlc1wiXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgem9uYWwgcHJvY2Vzc2VkIGJ5dGVzIG1ldHJpYyBmb3IgdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyXG4gICAgICogQHBhcmFtIGxvYWRCYWxhbmNlckZ1bGxOYW1lXG4gICAgICogQHBhcmFtIGF2YWlsYWJpbGl0eVpvbmVOYW1lXG4gICAgICogQHBhcmFtIHBlcmlvZFxuICAgICAqIEByZXR1cm5zIElNZXRyaWNcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UmVnaW9uYWxQcm9jZXNzZWRCeXRlc01ldHJpYyhcbiAgICAgICAgYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsXG4gICAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICApOiBJTWV0cmljIHtcbiAgICAgICAgcmV0dXJuIGFsYi5tZXRyaWNzLnByb2Nlc3NlZEJ5dGVzKHtcbiAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgZGltZW5zaW9uc01hcDp7XG4gICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKS5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogYWxiLmxvYWRCYWxhbmNlckFybiArIFwiLXByb2Nlc3NlZC1ieXRlc1wiXG4gICAgICAgIH0pO1xuICAgIH1cbn0iXX0=
|