@cdklabs/multi-az-observability 0.0.1-alpha.6 → 0.0.1-alpha.60
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 +2826 -1008
- package/.jsii.tabl.json +1 -0
- package/API.md +5406 -1585
- package/README.md +176 -152
- package/lib/alarmsandrules/AvailabilityAndLatencyAlarmsAndRules.d.ts +18 -14
- package/lib/alarmsandrules/AvailabilityAndLatencyAlarmsAndRules.js +98 -60
- package/lib/alarmsandrules/BaseOperationRegionalAlarmsAndRules.d.ts +3 -3
- 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 +29 -13
- package/lib/alarmsandrules/IBaseOperationZonalAlarmsAndRules.d.ts +0 -8
- package/lib/alarmsandrules/IBaseOperationZonalAlarmsAndRules.js +1 -1
- package/lib/alarmsandrules/IOperationAlarmsAndRules.d.ts +26 -23
- 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 +21 -18
- package/lib/alarmsandrules/OperationAlarmsAndRules.js +60 -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 +48 -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 +39 -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 +97 -349
- package/lib/basic_observability/props/ApplicationLoadBalancerDetectionProps.d.ts +66 -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 -44
- 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 +436 -510
- package/lib/dashboards/ServiceAvailabilityAndLatencyDashboard.d.ts +2 -10
- package/lib/dashboards/ServiceAvailabilityAndLatencyDashboard.js +420 -416
- 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 +56 -25
- package/lib/index.js +37 -19
- package/lib/metrics/ApplicationLoadBalancerMetrics.d.ts +79 -2
- package/lib/metrics/ApplicationLoadBalancerMetrics.js +883 -26
- package/lib/metrics/AvailabilityAndLatencyMetrics.d.ts +23 -0
- package/lib/metrics/AvailabilityAndLatencyMetrics.js +125 -31
- package/lib/metrics/NatGatewayMetrics.d.ts +113 -0
- package/lib/metrics/NatGatewayMetrics.js +357 -0
- package/lib/metrics/RegionalAvailabilityMetrics.js +9 -10
- 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 +13 -28
- 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/{basic_observability/props/ApplicationLoadBalancerLatencyOutlierCalculation.d.ts → outlier-detection/ApplicationLoadBalancerLatencyOutlierAlgorithm.d.ts} +1 -1
- package/lib/outlier-detection/ApplicationLoadBalancerLatencyOutlierAlgorithm.js +23 -0
- package/lib/outlier-detection/LatencyOutlierMetricAggregation.d.ts +22 -0
- package/lib/outlier-detection/LatencyOutlierMetricAggregation.js +27 -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 +18 -4
- 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 +252 -228
- package/lib/services/Operation.d.ts +8 -6
- package/lib/services/Operation.js +4 -3
- 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 +18 -4
- package/lib/services/Service.js +4 -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 +50 -5
- 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 +18 -4
- package/lib/services/props/ServiceProps.js +1 -1
- package/lib/utilities/MetricsHelper.d.ts +17 -9
- package/lib/utilities/MetricsHelper.js +34 -10
- package/lib/utilities/MinimumUnhealthyTargets.d.ts +25 -0
- package/lib/utilities/MinimumUnhealthyTargets.js +3 -0
- package/package.json +14 -14
- package/rosetta/default.ts-fixture +72 -0
- package/rosetta/service.ts-fixture +144 -0
- package/lib/basic_observability/props/ApplicationLoadBalancerLatencyOutlierCalculation.js +0 -23
- package/lib/services/IBasicServiceMultiAZObservability.d.ts +0 -45
- package/lib/services/IBasicServiceMultiAZObservability.js +0 -3
|
@@ -7,484 +7,488 @@ const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
|
7
7
|
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
|
|
8
8
|
const constructs_1 = require("constructs");
|
|
9
9
|
const ApplicationLoadBalancerMetrics_1 = require("../metrics/ApplicationLoadBalancerMetrics");
|
|
10
|
-
const RegionalAvailabilityMetrics_1 = require("../metrics/RegionalAvailabilityMetrics");
|
|
11
|
-
const RegionalLatencyMetrics_1 = require("../metrics/RegionalLatencyMetrics");
|
|
12
|
-
const ZonalAvailabilityMetrics_1 = require("../metrics/ZonalAvailabilityMetrics");
|
|
13
|
-
const ZonalLatencyMetrics_1 = require("../metrics/ZonalLatencyMetrics");
|
|
14
10
|
const AvailabilityMetricType_1 = require("../utilities/AvailabilityMetricType");
|
|
15
11
|
const LatencyMetricType_1 = require("../utilities/LatencyMetricType");
|
|
16
12
|
const MetricsHelper_1 = require("../utilities/MetricsHelper");
|
|
13
|
+
const AvailabilityAndLatencyMetrics_1 = require("../metrics/AvailabilityAndLatencyMetrics");
|
|
17
14
|
/**
|
|
18
15
|
* Creates a service level availability and latency dashboard
|
|
19
16
|
*/
|
|
20
17
|
class ServiceAvailabilityAndLatencyDashboard extends constructs_1.Construct {
|
|
21
|
-
static
|
|
22
|
-
let
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
left: RegionalAvailabilityMetrics_1.RegionalAvailabilityMetrics.createRegionalServiceAvailabilityMetrics({
|
|
30
|
-
label: aws_cdk_lib_1.Fn.ref('AWS::Region') + ' tps',
|
|
31
|
-
period: props.service.period,
|
|
32
|
-
availabilityMetricProps: props.service.operations
|
|
33
|
-
.filter((x) => x.critical)
|
|
34
|
-
.map((x) => {
|
|
35
|
-
return {
|
|
36
|
-
label: x.operationName,
|
|
37
|
-
metricDetails: x.serverSideAvailabilityMetricDetails,
|
|
38
|
-
metricType: AvailabilityMetricType_1.AvailabilityMetricType.REQUEST_COUNT,
|
|
39
|
-
};
|
|
40
|
-
}),
|
|
41
|
-
}),
|
|
42
|
-
statistic: 'Sum',
|
|
43
|
-
leftYAxis: {
|
|
44
|
-
label: 'TPS',
|
|
45
|
-
showUnits: false,
|
|
46
|
-
},
|
|
18
|
+
static createServerSideWidgets(dashboard, props) {
|
|
19
|
+
let availabilityZones = props.service.availabilityZoneNames;
|
|
20
|
+
let criticalOperations = props.service.operations.filter((x) => x.critical == true);
|
|
21
|
+
dashboard.addWidgets(new aws_cloudwatch_1.TextWidget({
|
|
22
|
+
markdown: "## **Server-side Metrics**",
|
|
23
|
+
background: aws_cloudwatch_1.TextWidgetBackground.TRANSPARENT,
|
|
24
|
+
height: 1,
|
|
25
|
+
width: 24
|
|
47
26
|
}));
|
|
48
|
-
|
|
49
|
-
let
|
|
50
|
-
let
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
27
|
+
let zonalAvailabilityWidgets = availabilityZones.map((availabilityZone) => {
|
|
28
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
29
|
+
let availabilityZoneId = props.azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
30
|
+
let criticalOperationsZonalMetrics = criticalOperations.map((operation, index) => {
|
|
31
|
+
return AvailabilityAndLatencyMetrics_1.AvailabilityAndLatencyMetrics.createZonalAvailabilityMetric({
|
|
32
|
+
availabilityZoneId: availabilityZoneId,
|
|
33
|
+
availabilityZone: availabilityZone,
|
|
34
|
+
label: operation.operationName + " (avg: ${AVG} min: ${MIN})",
|
|
35
|
+
metricDetails: operation.serverSideAvailabilityMetricDetails,
|
|
36
|
+
metricType: AvailabilityMetricType_1.AvailabilityMetricType.SUCCESS_RATE,
|
|
37
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
38
|
+
}, operation.serverSideAvailabilityMetricDetails.metricDimensions.zonalDimensions(availabilityZoneId, aws_cdk_lib_1.Aws.REGION));
|
|
39
|
+
});
|
|
40
|
+
return new aws_cloudwatch_1.GraphWidget({
|
|
41
|
+
height: 8,
|
|
42
|
+
width: 6,
|
|
43
|
+
title: `Availability - ${availabilityZoneId}`,
|
|
44
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
45
|
+
left: criticalOperationsZonalMetrics,
|
|
46
|
+
statistic: 'Sum',
|
|
47
|
+
leftYAxis: {
|
|
48
|
+
max: 100,
|
|
49
|
+
min: 95,
|
|
50
|
+
label: 'Percent',
|
|
51
|
+
showUnits: false,
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
let zonalFaultCountWidgets = availabilityZones.map((availabilityZone) => {
|
|
56
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
57
|
+
let availabilityZoneId = props.azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
58
|
+
let criticalOperationsZonalMetrics = criticalOperations.map((operation, index) => {
|
|
59
|
+
return AvailabilityAndLatencyMetrics_1.AvailabilityAndLatencyMetrics.createZonalAvailabilityMetric({
|
|
60
|
+
availabilityZoneId: availabilityZoneId,
|
|
61
|
+
availabilityZone: availabilityZone,
|
|
62
|
+
label: operation.operationName + " (avg: ${AVG} max: ${MAX})",
|
|
63
|
+
metricDetails: operation.serverSideAvailabilityMetricDetails,
|
|
64
|
+
metricType: AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT,
|
|
65
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
66
|
+
}, operation.serverSideAvailabilityMetricDetails.metricDimensions.zonalDimensions(availabilityZoneId, aws_cdk_lib_1.Aws.REGION));
|
|
67
|
+
});
|
|
68
|
+
return new aws_cloudwatch_1.GraphWidget({
|
|
69
|
+
height: 8,
|
|
70
|
+
width: 6,
|
|
71
|
+
title: `Fault Count - ${availabilityZoneId} `,
|
|
72
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
73
|
+
left: criticalOperationsZonalMetrics,
|
|
74
|
+
statistic: 'Sum',
|
|
75
|
+
leftYAxis: {
|
|
76
|
+
min: 0,
|
|
77
|
+
label: 'Count',
|
|
78
|
+
showUnits: false,
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
let perAZWidgetWithPerOperationLatency = availabilityZones.map((availabilityZone) => {
|
|
83
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
84
|
+
let availabilityZoneId = props.azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
85
|
+
let criticalOperationsZonalMetrics = criticalOperations.map((operation, index) => {
|
|
86
|
+
return AvailabilityAndLatencyMetrics_1.AvailabilityAndLatencyMetrics.createZonalLatencyCountMetric({
|
|
87
|
+
availabilityZoneId: availabilityZoneId,
|
|
88
|
+
availabilityZone: availabilityZone,
|
|
89
|
+
label: `${operation.operationName} (${operation.serverSideLatencyMetricDetails.alarmStatistic})` + " (avg: ${AVG} max: ${MAX})",
|
|
90
|
+
metricDetails: operation.serverSideLatencyMetricDetails,
|
|
91
|
+
metricType: LatencyMetricType_1.LatencyMetricType.SUCCESS_LATENCY,
|
|
92
|
+
color: MetricsHelper_1.MetricsHelper.colors[index],
|
|
93
|
+
statistic: operation.serverSideLatencyMetricDetails.alarmStatistic
|
|
94
|
+
}, operation.serverSideLatencyMetricDetails.metricDimensions.zonalDimensions(availabilityZoneId, aws_cdk_lib_1.Aws.REGION));
|
|
95
|
+
});
|
|
96
|
+
return new aws_cloudwatch_1.GraphWidget({
|
|
97
|
+
height: 6,
|
|
98
|
+
width: 8,
|
|
99
|
+
title: `Latency - ${availabilityZoneId}`,
|
|
100
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
101
|
+
left: criticalOperationsZonalMetrics,
|
|
102
|
+
leftYAxis: {
|
|
103
|
+
min: 0,
|
|
104
|
+
label: 'Milliseconds',
|
|
105
|
+
showUnits: false,
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
let perAZWidgetWithPerOperationHighLatencyCount = availabilityZones.map((availabilityZone) => {
|
|
110
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
111
|
+
let availabilityZoneId = props.azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
112
|
+
let criticalOperationsZonalMetrics = criticalOperations.map((operation, index) => {
|
|
113
|
+
return AvailabilityAndLatencyMetrics_1.AvailabilityAndLatencyMetrics.createZonalLatencyCountMetric({
|
|
114
|
+
availabilityZoneId: availabilityZoneId,
|
|
115
|
+
availabilityZone: availabilityZone,
|
|
116
|
+
label: operation.operationName + " (avg: ${AVG} max: ${MAX})",
|
|
117
|
+
metricDetails: operation.serverSideLatencyMetricDetails,
|
|
118
|
+
metricType: LatencyMetricType_1.LatencyMetricType.SUCCESS_LATENCY,
|
|
119
|
+
color: MetricsHelper_1.MetricsHelper.colors[index],
|
|
120
|
+
statistic: `TC(${MetricsHelper_1.MetricsHelper.convertDurationByUnit(operation.serverSideLatencyMetricDetails.successAlarmThreshold, operation.serverSideLatencyMetricDetails.unit)}:)`,
|
|
121
|
+
}, operation.serverSideLatencyMetricDetails.metricDimensions.zonalDimensions(availabilityZoneId, aws_cdk_lib_1.Aws.REGION));
|
|
122
|
+
});
|
|
123
|
+
return new aws_cloudwatch_1.GraphWidget({
|
|
65
124
|
height: 6,
|
|
66
125
|
width: 8,
|
|
67
|
-
title:
|
|
68
|
-
region: aws_cdk_lib_1.
|
|
69
|
-
left:
|
|
126
|
+
title: `High Latency Count - ${availabilityZoneId}`,
|
|
127
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
128
|
+
left: criticalOperationsZonalMetrics,
|
|
70
129
|
statistic: 'Sum',
|
|
71
130
|
leftYAxis: {
|
|
72
|
-
|
|
131
|
+
min: 0,
|
|
132
|
+
label: 'Count',
|
|
73
133
|
showUnits: false,
|
|
74
|
-
}
|
|
75
|
-
})
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (props.service.operations.filter((x) => x.critical && x.canaryMetricDetails !== undefined).length > 0) {
|
|
106
|
-
widgets.push(new aws_cloudwatch_1.TextWidget({
|
|
107
|
-
height: 2,
|
|
108
|
-
width: 24,
|
|
109
|
-
markdown: '**Canary Measured Latency**\n(Counts of requests exceeding the per-operation latency threshold)',
|
|
110
|
-
}));
|
|
111
|
-
widgets = widgets.concat(ServiceAvailabilityAndLatencyDashboard.generateLatencyMetricWidgets(props, true, availabilityZoneIds));
|
|
112
|
-
}
|
|
113
|
-
return widgets;
|
|
114
|
-
}
|
|
115
|
-
static generateAvailabilityWidgets(props, isCanary, availabilityZoneIds) {
|
|
116
|
-
let widgets = [];
|
|
117
|
-
widgets.push(new aws_cloudwatch_1.GraphWidget({
|
|
118
|
-
height: 6,
|
|
119
|
-
width: 24,
|
|
120
|
-
title: aws_cdk_lib_1.Fn.ref('AWS::Region') + ' Availability',
|
|
121
|
-
region: aws_cdk_lib_1.Fn.ref('AWS::Region'),
|
|
122
|
-
left: RegionalAvailabilityMetrics_1.RegionalAvailabilityMetrics.createRegionalServiceAvailabilityMetrics({
|
|
123
|
-
label: aws_cdk_lib_1.Fn.ref('AWS::Region') + ' availability',
|
|
124
|
-
period: props.service.period,
|
|
125
|
-
availabilityMetricProps: this.createRegionalAvailabilityMetricProps(props.service.operations.filter((x) => x.critical), isCanary, AvailabilityMetricType_1.AvailabilityMetricType.SUCCESS_RATE),
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
dashboard.addWidgets(...zonalAvailabilityWidgets,
|
|
138
|
+
// Server-side per AZ request count
|
|
139
|
+
new aws_cloudwatch_1.GraphWidget({
|
|
140
|
+
height: 8,
|
|
141
|
+
width: 6,
|
|
142
|
+
title: 'Request Count',
|
|
143
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
144
|
+
left: availabilityZones.map((availabilityZone, index) => {
|
|
145
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
146
|
+
let availabilityZoneId = props.azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
147
|
+
let usingMetrics = {};
|
|
148
|
+
criticalOperations.forEach((operation) => {
|
|
149
|
+
usingMetrics[`${azLetter}_${operation.operationName}`] =
|
|
150
|
+
AvailabilityAndLatencyMetrics_1.AvailabilityAndLatencyMetrics.createZonalAvailabilityMetric({
|
|
151
|
+
availabilityZoneId: availabilityZoneId,
|
|
152
|
+
metricDetails: operation.serverSideAvailabilityMetricDetails,
|
|
153
|
+
label: availabilityZoneId,
|
|
154
|
+
metricType: AvailabilityMetricType_1.AvailabilityMetricType.REQUEST_COUNT,
|
|
155
|
+
availabilityZone: availabilityZone
|
|
156
|
+
}, operation.serverSideAvailabilityMetricDetails.metricDimensions.zonalDimensions(availabilityZoneId, aws_cdk_lib_1.Aws.REGION));
|
|
157
|
+
});
|
|
158
|
+
return new aws_cloudwatch_1.MathExpression({
|
|
159
|
+
expression: Object.keys(usingMetrics).join('+'),
|
|
160
|
+
label: availabilityZoneId,
|
|
161
|
+
usingMetrics: usingMetrics,
|
|
162
|
+
period: props.service.period,
|
|
163
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
164
|
+
});
|
|
126
165
|
}),
|
|
127
166
|
statistic: 'Sum',
|
|
128
167
|
leftYAxis: {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
label: 'Availability',
|
|
168
|
+
min: 0,
|
|
169
|
+
label: 'Count',
|
|
132
170
|
showUnits: false,
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
171
|
+
}
|
|
172
|
+
}),
|
|
173
|
+
// Server-side per AZ fault count
|
|
174
|
+
new aws_cloudwatch_1.GraphWidget({
|
|
175
|
+
height: 8,
|
|
176
|
+
width: 6,
|
|
177
|
+
title: 'Fault Count',
|
|
178
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
179
|
+
left: availabilityZones.map((availabilityZone, index) => {
|
|
180
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
181
|
+
let availabilityZoneId = props.azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
182
|
+
let usingMetrics = {};
|
|
183
|
+
criticalOperations.forEach((operation) => {
|
|
184
|
+
usingMetrics[`${azLetter}_${operation.operationName}`] =
|
|
185
|
+
AvailabilityAndLatencyMetrics_1.AvailabilityAndLatencyMetrics.createZonalAvailabilityMetric({
|
|
186
|
+
availabilityZoneId: availabilityZoneId,
|
|
187
|
+
metricDetails: operation.serverSideAvailabilityMetricDetails,
|
|
188
|
+
label: availabilityZoneId,
|
|
189
|
+
metricType: AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT,
|
|
190
|
+
availabilityZone: availabilityZone
|
|
191
|
+
}, operation.serverSideAvailabilityMetricDetails.metricDimensions.zonalDimensions(availabilityZoneId, aws_cdk_lib_1.Aws.REGION));
|
|
192
|
+
});
|
|
193
|
+
return new aws_cloudwatch_1.MathExpression({
|
|
194
|
+
expression: Object.keys(usingMetrics).join('+'),
|
|
195
|
+
label: availabilityZoneId + " (avg: ${AVG} max: ${MAX})",
|
|
196
|
+
usingMetrics: usingMetrics,
|
|
197
|
+
period: props.service.period,
|
|
198
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
199
|
+
});
|
|
138
200
|
}),
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
showUnits: false,
|
|
201
|
+
statistic: 'Sum',
|
|
202
|
+
leftYAxis: {
|
|
142
203
|
min: 0,
|
|
143
|
-
|
|
204
|
+
label: 'Count',
|
|
205
|
+
showUnits: false,
|
|
144
206
|
},
|
|
145
|
-
|
|
207
|
+
leftAnnotations: [
|
|
146
208
|
{
|
|
147
|
-
color: aws_cloudwatch_1.Color.RED,
|
|
148
|
-
label: 'High severity',
|
|
149
209
|
value: props.service.faultCountThreshold,
|
|
210
|
+
visible: true,
|
|
211
|
+
color: aws_cloudwatch_1.Color.RED,
|
|
212
|
+
label: 'High Severity',
|
|
150
213
|
},
|
|
151
|
-
]
|
|
214
|
+
]
|
|
215
|
+
}), ...zonalFaultCountWidgets, ...perAZWidgetWithPerOperationLatency, ...perAZWidgetWithPerOperationHighLatencyCount);
|
|
216
|
+
}
|
|
217
|
+
static createCanaryWidgets(dashboard, props) {
|
|
218
|
+
let availabilityZones = props.service.availabilityZoneNames;
|
|
219
|
+
let criticalOperations = props.service.operations.filter((x) => x.critical == true);
|
|
220
|
+
dashboard.addWidgets(new aws_cloudwatch_1.TextWidget({
|
|
221
|
+
markdown: "## **Canary Metrics**",
|
|
222
|
+
background: aws_cloudwatch_1.TextWidgetBackground.TRANSPARENT,
|
|
223
|
+
height: 1,
|
|
224
|
+
width: 24
|
|
152
225
|
}));
|
|
153
|
-
|
|
154
|
-
let
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
})
|
|
226
|
+
let zonalAvailabilityWidgets = availabilityZones.map((availabilityZone) => {
|
|
227
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
228
|
+
let availabilityZoneId = props.azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
229
|
+
let criticalOperationsZonalMetrics = criticalOperations.map((operation, index) => {
|
|
230
|
+
return AvailabilityAndLatencyMetrics_1.AvailabilityAndLatencyMetrics.createZonalAvailabilityMetric({
|
|
231
|
+
availabilityZoneId: availabilityZoneId,
|
|
232
|
+
availabilityZone: availabilityZone,
|
|
233
|
+
label: operation.operationName + " (avg: ${AVG} min: ${MIN})",
|
|
234
|
+
metricDetails: operation.canaryMetricDetails.canaryAvailabilityMetricDetails,
|
|
235
|
+
metricType: AvailabilityMetricType_1.AvailabilityMetricType.SUCCESS_RATE,
|
|
236
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
237
|
+
}, operation.canaryMetricDetails.canaryAvailabilityMetricDetails.metricDimensions.zonalDimensions(availabilityZoneId, aws_cdk_lib_1.Aws.REGION));
|
|
238
|
+
});
|
|
239
|
+
return new aws_cloudwatch_1.GraphWidget({
|
|
240
|
+
height: 8,
|
|
241
|
+
width: 6,
|
|
242
|
+
title: `Availability - ${availabilityZoneId} `,
|
|
243
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
244
|
+
left: criticalOperationsZonalMetrics,
|
|
165
245
|
statistic: 'Sum',
|
|
166
246
|
leftYAxis: {
|
|
167
247
|
max: 100,
|
|
168
248
|
min: 95,
|
|
169
|
-
label: '
|
|
170
|
-
showUnits: false,
|
|
171
|
-
},
|
|
172
|
-
right: ZonalAvailabilityMetrics_1.ZonalAvailabilityMetrics.createZonalServiceAvailabilityMetrics({
|
|
173
|
-
label: availabilityZoneId + ' faults',
|
|
174
|
-
period: props.service.period,
|
|
175
|
-
availabilityMetricProps: this.createZonalAvailabilityMetricProps(props.service.operations.filter((x) => x.critical), availabilityZoneId, isCanary, AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT),
|
|
176
|
-
}),
|
|
177
|
-
rightYAxis: {
|
|
178
|
-
label: 'Faults',
|
|
249
|
+
label: 'Percent',
|
|
179
250
|
showUnits: false,
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
let zonalFaultCountWidgets = availabilityZones.map((availabilityZone) => {
|
|
255
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
256
|
+
let availabilityZoneId = props.azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
257
|
+
let criticalOperationsZonalMetrics = criticalOperations.map((operation, index) => {
|
|
258
|
+
return AvailabilityAndLatencyMetrics_1.AvailabilityAndLatencyMetrics.createZonalAvailabilityMetric({
|
|
259
|
+
availabilityZoneId: availabilityZoneId,
|
|
260
|
+
availabilityZone: availabilityZone,
|
|
261
|
+
label: operation.operationName + " (avg: ${AVG} max: ${MAX})",
|
|
262
|
+
metricDetails: operation.canaryMetricDetails.canaryAvailabilityMetricDetails,
|
|
263
|
+
metricType: AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT,
|
|
264
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
265
|
+
}, operation.canaryMetricDetails.canaryAvailabilityMetricDetails.metricDimensions.zonalDimensions(availabilityZoneId, aws_cdk_lib_1.Aws.REGION));
|
|
266
|
+
});
|
|
267
|
+
return new aws_cloudwatch_1.GraphWidget({
|
|
268
|
+
height: 8,
|
|
269
|
+
width: 6,
|
|
270
|
+
title: `Fault Count - ${availabilityZoneId}`,
|
|
271
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
272
|
+
left: criticalOperationsZonalMetrics,
|
|
273
|
+
statistic: 'Sum',
|
|
274
|
+
leftYAxis: {
|
|
180
275
|
min: 0,
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
left: RegionalLatencyMetrics_1.RegionalLatencyMetrics.createRegionalServiceLatencyCountMetrics({
|
|
202
|
-
label: aws_cdk_lib_1.Fn.ref('AWS::Region'),
|
|
203
|
-
period: props.service.period,
|
|
204
|
-
latencyMetricProps: this.createRegionalLatencyMetricProps(props.service.operations.filter((x) => x.critical), isCanary, LatencyMetricType_1.LatencyMetricType.SUCCESS_LATENCY),
|
|
205
|
-
}),
|
|
206
|
-
statistic: 'Sum',
|
|
207
|
-
leftYAxis: {
|
|
208
|
-
max: props.service.faultCountThreshold * 1.5,
|
|
209
|
-
min: 0,
|
|
210
|
-
label: 'Sum',
|
|
211
|
-
showUnits: false,
|
|
212
|
-
},
|
|
213
|
-
leftAnnotations: [
|
|
214
|
-
{
|
|
215
|
-
color: aws_cloudwatch_1.Color.RED,
|
|
216
|
-
label: 'High severity',
|
|
217
|
-
value: props.service.faultCountThreshold,
|
|
218
|
-
},
|
|
219
|
-
],
|
|
220
|
-
}));
|
|
221
|
-
for (let i = 0; i < availabilityZoneIds.length; i++) {
|
|
222
|
-
let availabilityZoneId = availabilityZoneIds[i];
|
|
223
|
-
widgets.push(new aws_cloudwatch_1.GraphWidget({
|
|
276
|
+
label: 'Count',
|
|
277
|
+
showUnits: false,
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
let perAZWidgetWithPerOperationLatency = availabilityZones.map((availabilityZone) => {
|
|
282
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
283
|
+
let availabilityZoneId = props.azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
284
|
+
let criticalOperationsZonalMetrics = criticalOperations.map((operation, index) => {
|
|
285
|
+
return AvailabilityAndLatencyMetrics_1.AvailabilityAndLatencyMetrics.createZonalLatencyCountMetric({
|
|
286
|
+
availabilityZoneId: availabilityZoneId,
|
|
287
|
+
availabilityZone: availabilityZone,
|
|
288
|
+
label: `${operation.operationName} (${operation.canaryMetricDetails.canaryLatencyMetricDetails.alarmStatistic})` + " (avg: ${AVG} max: ${MAX})",
|
|
289
|
+
metricDetails: operation.canaryMetricDetails.canaryLatencyMetricDetails,
|
|
290
|
+
metricType: LatencyMetricType_1.LatencyMetricType.SUCCESS_LATENCY,
|
|
291
|
+
color: MetricsHelper_1.MetricsHelper.colors[index],
|
|
292
|
+
statistic: operation.canaryMetricDetails.canaryLatencyMetricDetails.alarmStatistic
|
|
293
|
+
}, operation.canaryMetricDetails.canaryLatencyMetricDetails.metricDimensions.zonalDimensions(availabilityZoneId, aws_cdk_lib_1.Aws.REGION));
|
|
294
|
+
});
|
|
295
|
+
return new aws_cloudwatch_1.GraphWidget({
|
|
224
296
|
height: 6,
|
|
225
297
|
width: 8,
|
|
226
|
-
title:
|
|
227
|
-
region: aws_cdk_lib_1.
|
|
228
|
-
left:
|
|
229
|
-
label: availabilityZoneId,
|
|
230
|
-
period: props.service.period,
|
|
231
|
-
latencyMetricProps: this.createZonalLatencyMetricProps(props.service.operations.filter((x) => x.critical), availabilityZoneId, isCanary, LatencyMetricType_1.LatencyMetricType.SUCCESS_LATENCY),
|
|
232
|
-
}),
|
|
233
|
-
statistic: 'Sum',
|
|
298
|
+
title: `Latency - ${availabilityZoneId}`,
|
|
299
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
300
|
+
left: criticalOperationsZonalMetrics,
|
|
234
301
|
leftYAxis: {
|
|
235
|
-
max: props.service.faultCountThreshold * 1.5,
|
|
236
302
|
min: 0,
|
|
237
|
-
label: '
|
|
303
|
+
label: 'Milliseconds',
|
|
238
304
|
showUnits: false,
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
{
|
|
242
|
-
color: aws_cloudwatch_1.Color.RED,
|
|
243
|
-
label: 'High severity',
|
|
244
|
-
value: props.service.faultCountThreshold,
|
|
245
|
-
},
|
|
246
|
-
],
|
|
247
|
-
}));
|
|
248
|
-
}
|
|
249
|
-
return widgets;
|
|
250
|
-
}
|
|
251
|
-
static createRegionalAvailabilityMetricProps(criticalOperations, isCanary, metricType) {
|
|
252
|
-
return criticalOperations
|
|
253
|
-
.reduce((filtered, value) => {
|
|
254
|
-
if (isCanary && value.canaryMetricDetails) {
|
|
255
|
-
filtered.push(value.canaryMetricDetails.canaryAvailabilityMetricDetails);
|
|
256
|
-
}
|
|
257
|
-
else if (!isCanary) {
|
|
258
|
-
filtered.push(value.serverSideAvailabilityMetricDetails);
|
|
259
|
-
}
|
|
260
|
-
return filtered;
|
|
261
|
-
}, [])
|
|
262
|
-
.map((x) => {
|
|
263
|
-
return {
|
|
264
|
-
label: x.operationName + ' ' + metricType.toString().replace('_', ' '),
|
|
265
|
-
metricDetails: x,
|
|
266
|
-
metricType: metricType,
|
|
267
|
-
};
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
static createRegionalLatencyMetricProps(criticalOperations, isCanary, metricType) {
|
|
271
|
-
return criticalOperations
|
|
272
|
-
.reduce((filtered, value) => {
|
|
273
|
-
if (isCanary && value.canaryMetricDetails) {
|
|
274
|
-
filtered.push(value.canaryMetricDetails.canaryLatencyMetricDetails);
|
|
275
|
-
}
|
|
276
|
-
else if (!isCanary) {
|
|
277
|
-
filtered.push(value.serverSideLatencyMetricDetails);
|
|
278
|
-
}
|
|
279
|
-
return filtered;
|
|
280
|
-
}, [])
|
|
281
|
-
.map((x) => {
|
|
282
|
-
return {
|
|
283
|
-
label: x.operationName,
|
|
284
|
-
metricDetails: x,
|
|
285
|
-
metricType: metricType,
|
|
286
|
-
statistic: 'TC(' + x.successAlarmThreshold + ':)',
|
|
287
|
-
};
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
static createZonalAvailabilityMetricProps(criticalOperations, availabilityZoneId, isCanary, metricType) {
|
|
291
|
-
return criticalOperations
|
|
292
|
-
.reduce((filtered, value) => {
|
|
293
|
-
if (isCanary &&
|
|
294
|
-
value.canaryMetricDetails !== undefined &&
|
|
295
|
-
value.canaryMetricDetails != null) {
|
|
296
|
-
filtered.push(value.canaryMetricDetails.canaryAvailabilityMetricDetails);
|
|
297
|
-
}
|
|
298
|
-
else if (!isCanary) {
|
|
299
|
-
filtered.push(value.serverSideAvailabilityMetricDetails);
|
|
300
|
-
}
|
|
301
|
-
return filtered;
|
|
302
|
-
}, [])
|
|
303
|
-
.map((x) => {
|
|
304
|
-
return {
|
|
305
|
-
label: x.operationName + ' ' + metricType.toString().replace('_', ' '),
|
|
306
|
-
metricDetails: x,
|
|
307
|
-
metricType: metricType,
|
|
308
|
-
availabilityZoneId: availabilityZoneId,
|
|
309
|
-
};
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
static createZonalLatencyMetricProps(criticalOperations, availabilityZoneId, isCanary, metricType) {
|
|
313
|
-
return criticalOperations
|
|
314
|
-
.reduce((filtered, value) => {
|
|
315
|
-
if (isCanary &&
|
|
316
|
-
value.canaryMetricDetails !== undefined &&
|
|
317
|
-
value.canaryMetricDetails != null) {
|
|
318
|
-
filtered.push(value.canaryMetricDetails.canaryLatencyMetricDetails);
|
|
319
|
-
}
|
|
320
|
-
else if (!isCanary) {
|
|
321
|
-
filtered.push(value.serverSideLatencyMetricDetails);
|
|
322
|
-
}
|
|
323
|
-
return filtered;
|
|
324
|
-
}, [])
|
|
325
|
-
.map((x) => {
|
|
326
|
-
return {
|
|
327
|
-
label: x.operationName,
|
|
328
|
-
metricDetails: x,
|
|
329
|
-
metricType: metricType,
|
|
330
|
-
availabilityZoneId: availabilityZoneId,
|
|
331
|
-
statistic: 'TC(' + x.successAlarmThreshold + ':)',
|
|
332
|
-
};
|
|
305
|
+
}
|
|
306
|
+
});
|
|
333
307
|
});
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
availabilityZoneId: availabilityZoneId,
|
|
348
|
-
metricType: AvailabilityMetricType_1.AvailabilityMetricType.FAULT_RATE,
|
|
349
|
-
label: availabilityZoneId,
|
|
350
|
-
period: props.service.period,
|
|
351
|
-
keyprefix: keyprefix
|
|
308
|
+
let perAZWidgetWithPerOperationHighLatencyCount = availabilityZones.map((availabilityZone) => {
|
|
309
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
310
|
+
let availabilityZoneId = props.azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
311
|
+
let criticalOperationsZonalMetrics = criticalOperations.map((operation, index) => {
|
|
312
|
+
return AvailabilityAndLatencyMetrics_1.AvailabilityAndLatencyMetrics.createZonalLatencyCountMetric({
|
|
313
|
+
availabilityZoneId: availabilityZoneId,
|
|
314
|
+
availabilityZone: availabilityZone,
|
|
315
|
+
label: operation.operationName + " (avg: ${AVG} max: ${MAX})",
|
|
316
|
+
metricDetails: operation.canaryMetricDetails.canaryLatencyMetricDetails,
|
|
317
|
+
metricType: LatencyMetricType_1.LatencyMetricType.SUCCESS_LATENCY,
|
|
318
|
+
color: MetricsHelper_1.MetricsHelper.colors[index],
|
|
319
|
+
statistic: `TC(${MetricsHelper_1.MetricsHelper.convertDurationByUnit(operation.canaryMetricDetails.canaryLatencyMetricDetails.successAlarmThreshold, operation.canaryMetricDetails.canaryLatencyMetricDetails.unit)}:)`
|
|
320
|
+
}, operation.canaryMetricDetails.canaryLatencyMetricDetails.metricDimensions.zonalDimensions(availabilityZoneId, aws_cdk_lib_1.Aws.REGION));
|
|
352
321
|
});
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
322
|
+
return new aws_cloudwatch_1.GraphWidget({
|
|
323
|
+
height: 6,
|
|
324
|
+
width: 8,
|
|
325
|
+
title: `High Latency Count - ${availabilityZoneId}`,
|
|
326
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
327
|
+
left: criticalOperationsZonalMetrics,
|
|
328
|
+
statistic: 'Sum',
|
|
329
|
+
leftYAxis: {
|
|
330
|
+
min: 0,
|
|
331
|
+
label: 'Count',
|
|
332
|
+
showUnits: false,
|
|
333
|
+
}
|
|
361
334
|
});
|
|
362
|
-
requestCountMetrics.push(requestCountMetric);
|
|
363
|
-
let processedBytesMetric = ApplicationLoadBalancerMetrics_1.ApplicationLoadBalancerMetrics.getPerAZProcessedBytesMetric(props.service.loadBalancer, availabilityZoneName, availabilityZoneId, props.service.period);
|
|
364
|
-
processedBytesMetrics.push(processedBytesMetric);
|
|
365
335
|
});
|
|
366
|
-
|
|
336
|
+
dashboard.addWidgets(...zonalAvailabilityWidgets,
|
|
337
|
+
// Canary per AZ request count
|
|
338
|
+
new aws_cloudwatch_1.GraphWidget({
|
|
367
339
|
height: 8,
|
|
368
|
-
width:
|
|
369
|
-
title:
|
|
370
|
-
region: aws_cdk_lib_1.
|
|
371
|
-
left:
|
|
340
|
+
width: 6,
|
|
341
|
+
title: 'Request Count',
|
|
342
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
343
|
+
left: availabilityZones.map((availabilityZone, index) => {
|
|
344
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
345
|
+
let availabilityZoneId = props.azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
346
|
+
let usingMetrics = {};
|
|
347
|
+
criticalOperations.forEach((operation) => {
|
|
348
|
+
usingMetrics[`${azLetter}_${operation.operationName}`] =
|
|
349
|
+
AvailabilityAndLatencyMetrics_1.AvailabilityAndLatencyMetrics.createZonalAvailabilityMetric({
|
|
350
|
+
availabilityZoneId: availabilityZoneId,
|
|
351
|
+
metricDetails: operation.canaryMetricDetails.canaryAvailabilityMetricDetails,
|
|
352
|
+
label: availabilityZoneId,
|
|
353
|
+
metricType: AvailabilityMetricType_1.AvailabilityMetricType.REQUEST_COUNT,
|
|
354
|
+
availabilityZone: availabilityZone
|
|
355
|
+
}, operation.canaryMetricDetails.canaryAvailabilityMetricDetails.metricDimensions.zonalDimensions(availabilityZoneId, aws_cdk_lib_1.Aws.REGION));
|
|
356
|
+
});
|
|
357
|
+
return new aws_cloudwatch_1.MathExpression({
|
|
358
|
+
expression: Object.keys(usingMetrics).join('+'),
|
|
359
|
+
label: availabilityZoneId,
|
|
360
|
+
usingMetrics: usingMetrics,
|
|
361
|
+
period: props.service.period,
|
|
362
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
363
|
+
});
|
|
364
|
+
}),
|
|
365
|
+
statistic: 'Sum',
|
|
372
366
|
leftYAxis: {
|
|
373
|
-
max: 35,
|
|
374
367
|
min: 0,
|
|
375
|
-
label: '
|
|
368
|
+
label: 'Count',
|
|
376
369
|
showUnits: false,
|
|
377
370
|
}
|
|
378
|
-
})
|
|
379
|
-
|
|
371
|
+
}),
|
|
372
|
+
// Canary per AZ fault count
|
|
373
|
+
new aws_cloudwatch_1.GraphWidget({
|
|
380
374
|
height: 8,
|
|
381
|
-
width:
|
|
382
|
-
title:
|
|
383
|
-
region: aws_cdk_lib_1.
|
|
384
|
-
left:
|
|
375
|
+
width: 6,
|
|
376
|
+
title: 'Fault Count',
|
|
377
|
+
region: aws_cdk_lib_1.Aws.REGION,
|
|
378
|
+
left: availabilityZones.map((availabilityZone, index) => {
|
|
379
|
+
let azLetter = availabilityZone.substring(availabilityZone.length - 1);
|
|
380
|
+
let availabilityZoneId = props.azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
|
|
381
|
+
let usingMetrics = {};
|
|
382
|
+
criticalOperations.forEach((operation) => {
|
|
383
|
+
usingMetrics[`${azLetter}_${operation.operationName}`] =
|
|
384
|
+
AvailabilityAndLatencyMetrics_1.AvailabilityAndLatencyMetrics.createZonalAvailabilityMetric({
|
|
385
|
+
availabilityZoneId: availabilityZoneId,
|
|
386
|
+
metricDetails: operation.canaryMetricDetails.canaryAvailabilityMetricDetails,
|
|
387
|
+
label: availabilityZoneId,
|
|
388
|
+
metricType: AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT,
|
|
389
|
+
availabilityZone: availabilityZone
|
|
390
|
+
}, operation.canaryMetricDetails.canaryAvailabilityMetricDetails.metricDimensions.zonalDimensions(availabilityZoneId, aws_cdk_lib_1.Aws.REGION));
|
|
391
|
+
});
|
|
392
|
+
return new aws_cloudwatch_1.MathExpression({
|
|
393
|
+
expression: Object.keys(usingMetrics).join('+'),
|
|
394
|
+
label: availabilityZoneId,
|
|
395
|
+
usingMetrics: usingMetrics,
|
|
396
|
+
period: props.service.period,
|
|
397
|
+
color: MetricsHelper_1.MetricsHelper.colors[index]
|
|
398
|
+
});
|
|
399
|
+
}),
|
|
400
|
+
statistic: 'Sum',
|
|
385
401
|
leftYAxis: {
|
|
386
402
|
min: 0,
|
|
387
|
-
label: '
|
|
403
|
+
label: 'Count',
|
|
388
404
|
showUnits: false,
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
showUnits: true,
|
|
400
|
-
}
|
|
401
|
-
}));
|
|
402
|
-
return albWidgets;
|
|
405
|
+
},
|
|
406
|
+
leftAnnotations: [
|
|
407
|
+
{
|
|
408
|
+
value: props.service.faultCountThreshold,
|
|
409
|
+
visible: true,
|
|
410
|
+
color: aws_cloudwatch_1.Color.RED,
|
|
411
|
+
label: 'High Severity',
|
|
412
|
+
},
|
|
413
|
+
]
|
|
414
|
+
}), ...zonalFaultCountWidgets, ...perAZWidgetWithPerOperationLatency, ...perAZWidgetWithPerOperationHighLatencyCount);
|
|
403
415
|
}
|
|
404
416
|
constructor(scope, id, props) {
|
|
405
417
|
super(scope, id);
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
418
|
+
this.dashboard = new aws_cloudwatch_1.Dashboard(this, 'Dashboard', {
|
|
419
|
+
dashboardName: `${props.service.serviceName.toLowerCase()}-availability-and-latency-${aws_cdk_lib_1.Aws.REGION}`,
|
|
420
|
+
defaultInterval: props.interval,
|
|
421
|
+
periodOverride: aws_cloudwatch_1.PeriodOverride.AUTO
|
|
409
422
|
});
|
|
410
|
-
|
|
423
|
+
this.dashboard.addWidgets(new aws_cloudwatch_1.AlarmStatusWidget({
|
|
424
|
+
height: 2,
|
|
425
|
+
width: 6,
|
|
426
|
+
alarms: [
|
|
427
|
+
props.serviceAlarmsAndRules.serviceImpactAlarm
|
|
428
|
+
],
|
|
429
|
+
title: "Service Alarm (any critical operation sees impact zonally or regionally, measured from server-side or canary)"
|
|
430
|
+
}), new aws_cloudwatch_1.AlarmStatusWidget({
|
|
431
|
+
height: 2,
|
|
432
|
+
width: 6,
|
|
433
|
+
alarms: [
|
|
434
|
+
props.serviceAlarmsAndRules.regionalImpactAlarm
|
|
435
|
+
],
|
|
436
|
+
title: "Regional Impact (there is regionally scoped impact to any critical operation, measured from server-side or canary)"
|
|
437
|
+
}), new aws_cloudwatch_1.AlarmStatusWidget({
|
|
438
|
+
height: 2,
|
|
439
|
+
width: 6,
|
|
440
|
+
alarms: [
|
|
441
|
+
props.serviceAlarmsAndRules.regionalServerSideImpactAlarm
|
|
442
|
+
],
|
|
443
|
+
title: "Server-side Regional Impact (there is regionally scoped impact to any critical operation, measured from server-side)"
|
|
444
|
+
}), ...props.serviceAlarmsAndRules.regionalCanaryAlarm ? [new aws_cloudwatch_1.AlarmStatusWidget({
|
|
445
|
+
height: 2,
|
|
446
|
+
width: 6,
|
|
447
|
+
alarms: [
|
|
448
|
+
props.serviceAlarmsAndRules.regionalCanaryAlarm
|
|
449
|
+
],
|
|
450
|
+
title: "Canary Regional Impact (there is regionally scoped impact to any critical operation, measured from the canary)"
|
|
451
|
+
})] : []);
|
|
452
|
+
this.dashboard.addWidgets(new aws_cloudwatch_1.AlarmStatusWidget({
|
|
411
453
|
height: 2,
|
|
412
454
|
width: 24,
|
|
413
|
-
|
|
455
|
+
alarms: [
|
|
456
|
+
...Object.values(props.serviceAlarmsAndRules.zonalAggregateIsolatedImpactAlarms)
|
|
457
|
+
],
|
|
458
|
+
title: "Zonal Aggregate Alarms (alarms trigger if any critical operation in the AZ sees availability or latency impact as measured from server-side or canary)"
|
|
414
459
|
}));
|
|
415
|
-
|
|
460
|
+
this.dashboard.addWidgets(new aws_cloudwatch_1.AlarmStatusWidget({
|
|
416
461
|
height: 2,
|
|
417
462
|
width: 24,
|
|
418
|
-
alarms: [
|
|
419
|
-
|
|
463
|
+
alarms: [
|
|
464
|
+
...Object.values(props.serviceAlarmsAndRules.zonalServerSideIsolatedImpactAlarms)
|
|
465
|
+
],
|
|
466
|
+
title: "Server-side Zonal Alarms (alarms trigger if any critical operation in the AZ sees availability or latency impact as measured from the server-side, these are useful for deployment monitoring, in case the canary sees errors when an AZ is intentionally unavailable)"
|
|
420
467
|
}));
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
title: availabilityZoneId +
|
|
431
|
-
' Zonal Isolated Impact Alarm (any critical operation in this AZ shows impact from server-side or canary)',
|
|
432
|
-
}));
|
|
433
|
-
let usingMetrics = {};
|
|
434
|
-
props.service.operations
|
|
435
|
-
.filter((x) => x.critical == true)
|
|
436
|
-
.forEach((x) => {
|
|
437
|
-
usingMetrics[`${keyPrefix}${counter++}`] =
|
|
438
|
-
ZonalAvailabilityMetrics_1.ZonalAvailabilityMetrics.createZonalAvailabilityMetric({
|
|
439
|
-
availabilityZoneId: availabilityZoneId,
|
|
440
|
-
metricDetails: x.serverSideAvailabilityMetricDetails,
|
|
441
|
-
label: availabilityZoneId + ' ' + x.operationName + ' fault count',
|
|
442
|
-
metricType: AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT,
|
|
443
|
-
keyPrefix: keyPrefix,
|
|
444
|
-
});
|
|
445
|
-
});
|
|
446
|
-
let zonalFaultCount = new aws_cloudwatch_1.MathExpression({
|
|
447
|
-
expression: Object.keys(usingMetrics).join('+'),
|
|
448
|
-
label: availabilityZoneId + ' fault count',
|
|
449
|
-
usingMetrics: usingMetrics,
|
|
450
|
-
period: props.service.period
|
|
451
|
-
});
|
|
452
|
-
perOperationAZFaultsMetrics.push(zonalFaultCount);
|
|
453
|
-
keyPrefix = MetricsHelper_1.MetricsHelper.nextChar(keyPrefix);
|
|
468
|
+
this.dashboard.addWidgets(new aws_cloudwatch_1.TextWidget({
|
|
469
|
+
markdown: "### Per Operation Dashboards\n" + props.operationsDashboard.map(x => `- [${x.dashboardName}](https://${aws_cdk_lib_1.Aws.REGION}.console.aws.amazon.com/cloudwatch/home?region=${aws_cdk_lib_1.Aws.REGION}#dashboards/dashboard/${x.dashboardName})`).join("\n"),
|
|
470
|
+
background: aws_cloudwatch_1.TextWidgetBackground.TRANSPARENT,
|
|
471
|
+
height: 4,
|
|
472
|
+
width: 24
|
|
473
|
+
}));
|
|
474
|
+
ServiceAvailabilityAndLatencyDashboard.createServerSideWidgets(this.dashboard, props);
|
|
475
|
+
if (props.service.canaryTestProps) {
|
|
476
|
+
ServiceAvailabilityAndLatencyDashboard.createCanaryWidgets(this.dashboard, props);
|
|
454
477
|
}
|
|
455
|
-
let azContributorWidgets = [
|
|
456
|
-
new aws_cloudwatch_1.TextWidget({
|
|
457
|
-
height: 2,
|
|
458
|
-
width: 24,
|
|
459
|
-
markdown: '**AZ Contributors To Faults**',
|
|
460
|
-
}),
|
|
461
|
-
new aws_cloudwatch_1.GraphWidget({
|
|
462
|
-
height: 6,
|
|
463
|
-
width: 24,
|
|
464
|
-
title: 'AZ Fault Count',
|
|
465
|
-
period: props.service.period,
|
|
466
|
-
left: perOperationAZFaultsMetrics,
|
|
467
|
-
}),
|
|
468
|
-
];
|
|
469
|
-
topLevelAggregateAlarmWidgets.concat(ServiceAvailabilityAndLatencyDashboard.generateTPSWidgets(props, availabilityZoneIds));
|
|
470
|
-
this.dashboard = new aws_cloudwatch_1.Dashboard(this, 'TopLevelDashboard', {
|
|
471
|
-
dashboardName: props.service.serviceName.toLowerCase() +
|
|
472
|
-
aws_cdk_lib_1.Fn.sub('-availability-and-latency-${AWS::Region}'),
|
|
473
|
-
defaultInterval: props.interval,
|
|
474
|
-
periodOverride: aws_cloudwatch_1.PeriodOverride.AUTO,
|
|
475
|
-
widgets: [
|
|
476
|
-
topLevelAggregateAlarmWidgets,
|
|
477
|
-
azContributorWidgets,
|
|
478
|
-
ServiceAvailabilityAndLatencyDashboard.generateServerSideAndCanaryAvailabilityWidgets(props, availabilityZoneIds),
|
|
479
|
-
ServiceAvailabilityAndLatencyDashboard.generateServerSideAndCanaryLatencyWidgets(props, availabilityZoneIds),
|
|
480
|
-
],
|
|
481
|
-
});
|
|
482
478
|
let lb = props.service.loadBalancer?.node
|
|
483
479
|
.defaultChild;
|
|
484
|
-
if (lb
|
|
485
|
-
this.dashboard.addWidgets(
|
|
480
|
+
if (lb && lb.type == 'application') {
|
|
481
|
+
this.dashboard.addWidgets(new aws_cloudwatch_1.TextWidget({
|
|
482
|
+
markdown: "## **Load Balancer Metrics**",
|
|
483
|
+
background: aws_cloudwatch_1.TextWidgetBackground.TRANSPARENT,
|
|
484
|
+
height: 1,
|
|
485
|
+
width: 24
|
|
486
|
+
}));
|
|
487
|
+
this.dashboard.addWidgets(...ApplicationLoadBalancerMetrics_1.ApplicationLoadBalancerMetrics.generateLoadBalancerWidgets(new Map([
|
|
488
|
+
[props.service.loadBalancer, props.service.targetGroups ? props.service.targetGroups : []]
|
|
489
|
+
]), props.azMapper, props.service.period, props.service.defaultLatencyMetricDetails.alarmStatistic, props.service.defaultLatencyMetricDetails.successAlarmThreshold, props.service.defaultAvailabilityMetricDetails.faultAlarmThreshold));
|
|
486
490
|
}
|
|
487
491
|
}
|
|
488
492
|
}
|
|
489
493
|
exports.ServiceAvailabilityAndLatencyDashboard = ServiceAvailabilityAndLatencyDashboard;
|
|
490
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VydmljZUF2YWlsYWJpbGl0eUFuZExhdGVuY3lEYXNoYm9hcmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGFzaGJvYXJkcy9TZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxRUFBcUU7QUFDckUsc0NBQXNDO0FBQ3RDLDZDQUFpQztBQUNqQywrREFVb0M7QUFLcEMsMkNBQXVDO0FBR3ZDLDhGQUEyRjtBQUczRix3RkFBcUY7QUFDckYsOEVBQTJFO0FBQzNFLGtGQUErRTtBQUMvRSx3RUFBcUU7QUFHckUsZ0ZBQTZFO0FBQzdFLHNFQUFtRTtBQUNuRSw4REFBMkQ7QUFFM0Q7O0dBRUc7QUFDSCxNQUFhLHNDQUNYLFNBQVEsc0JBQVM7SUFFVCxNQUFNLENBQUMsa0JBQWtCLENBQy9CLEtBQWtELEVBQ2xELG1CQUE2QjtRQUU3QixJQUFJLE9BQU8sR0FBYyxFQUFFLENBQUM7UUFFNUIsT0FBTyxDQUFDLElBQUksQ0FDVixJQUFJLDJCQUFVLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLGlCQUFpQixFQUFFLENBQUMsQ0FDdEUsQ0FBQztRQUVGLE9BQU8sQ0FBQyxJQUFJLENBQ1YsSUFBSSw0QkFBVyxDQUFDO1lBQ2QsTUFBTSxFQUFFLENBQUM7WUFDVCxLQUFLLEVBQUUsRUFBRTtZQUNULEtBQUssRUFBRSxnQkFBRSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsR0FBRyxNQUFNO1lBQ3JDLE1BQU0sRUFBRSxnQkFBRSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUM7WUFDN0IsSUFBSSxFQUFFLHlEQUEyQixDQUFDLHdDQUF3QyxDQUN4RTtnQkFDRSxLQUFLLEVBQUUsZ0JBQUUsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEdBQUcsTUFBTTtnQkFDckMsTUFBTSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTTtnQkFDNUIsdUJBQXVCLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVO3FCQUM5QyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7cUJBQ3pCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO29CQUNULE9BQU87d0JBQ0wsS0FBSyxFQUFFLENBQUMsQ0FBQyxhQUFhO3dCQUN0QixhQUFhLEVBQUUsQ0FBQyxDQUFDLG1DQUFtQzt3QkFDcEQsVUFBVSxFQUFFLCtDQUFzQixDQUFDLGFBQWE7cUJBQ2pELENBQUM7Z0JBQ0osQ0FBQyxDQUFDO2FBQ0wsQ0FDRjtZQUNELFNBQVMsRUFBRSxLQUFLO1lBQ2hCLFNBQVMsRUFBRTtnQkFDVCxLQUFLLEVBQUUsS0FBSztnQkFDWixTQUFTLEVBQUUsS0FBSzthQUNqQjtTQUNGLENBQUMsQ0FDSCxDQUFDO1FBRUYsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3BELElBQUksa0JBQWtCLEdBQVcsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFeEQsSUFBSSxnQkFBZ0IsR0FBRztnQkFDckIsdUJBQXVCLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVO3FCQUM5QyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7cUJBQ3pCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO29CQUNULE9BQU87d0JBQ0wsa0JBQWtCLEVBQUUsa0JBQWtCO3dCQUN0QyxLQUFLLEVBQUUsQ0FBQyxDQUFDLGFBQWE7d0JBQ3RCLGFBQWEsRUFBRSxDQUFDLENBQUMsbUNBQW1DO3dCQUNwRCxVQUFVLEVBQUUsK0NBQXNCLENBQUMsYUFBYTtxQkFDakQsQ0FBQztnQkFDSixDQUFDLENBQUM7Z0JBQ0osTUFBTSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTTtnQkFDNUIsS0FBSyxFQUFFLGtCQUFrQixHQUFHLEtBQUs7YUFDbEMsQ0FBQztZQUVGLE9BQU8sQ0FBQyxJQUFJLENBQ1YsSUFBSSw0QkFBVyxDQUFDO2dCQUNkLE1BQU0sRUFBRSxDQUFDO2dCQUNULEtBQUssRUFBRSxDQUFDO2dCQUNSLEtBQUssRUFBRSxrQkFBa0IsR0FBRyxNQUFNO2dCQUNsQyxNQUFNLEVBQUUsZ0JBQUUsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDO2dCQUM3QixJQUFJLEVBQUUsbURBQXdCLENBQUMscUNBQXFDLENBQ2xFLGdCQUFnQixDQUNqQjtnQkFDRCxTQUFTLEVBQUUsS0FBSztnQkFDaEIsU0FBUyxFQUFFO29CQUNULEtBQUssRUFBRSxLQUFLO29CQUNaLFNBQVMsRUFBRSxLQUFLO2lCQUNqQjthQUNGLENBQUMsQ0FDSCxDQUFDO1FBQ0osQ0FBQztRQUVELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFTyxNQUFNLENBQUMsOENBQThDLENBQzNELEtBQWtELEVBQ2xELG1CQUE2QjtRQUU3QixJQUFJLE9BQU8sR0FBYyxFQUFFLENBQUM7UUFFNUIsT0FBTyxDQUFDLElBQUksQ0FDVixJQUFJLDJCQUFVLENBQUM7WUFDYixNQUFNLEVBQUUsQ0FBQztZQUNULEtBQUssRUFBRSxFQUFFO1lBQ1QsUUFBUSxFQUNOLDBHQUEwRztTQUM3RyxDQUFDLENBQ0gsQ0FBQztRQUVGLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUN0QixzQ0FBc0MsQ0FBQywyQkFBMkIsQ0FDaEUsS0FBSyxFQUNMLEtBQUssRUFDTCxtQkFBbUIsQ0FDcEIsQ0FDRixDQUFDO1FBRUYsSUFDRSxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQzdCLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxtQkFBbUIsS0FBSyxTQUFTLENBQ3pELENBQUMsTUFBTSxHQUFHLENBQUMsRUFDWixDQUFDO1lBQ0QsT0FBTyxDQUFDLElBQUksQ0FDVixJQUFJLDJCQUFVLENBQUM7Z0JBQ2IsTUFBTSxFQUFFLENBQUM7Z0JBQ1QsS0FBSyxFQUFFLEVBQUU7Z0JBQ1QsUUFBUSxFQUNOLHFHQUFxRzthQUN4RyxDQUFDLENBQ0gsQ0FBQztZQUVGLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUN0QixzQ0FBc0MsQ0FBQywyQkFBMkIsQ0FDaEUsS0FBSyxFQUNMLElBQUksRUFDSixtQkFBbUIsQ0FDcEIsQ0FDRixDQUFDO1FBQ0osQ0FBQztRQUVELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFTyxNQUFNLENBQUMseUNBQXlDLENBQ3RELEtBQWtELEVBQ2xELG1CQUE2QjtRQUU3QixJQUFJLE9BQU8sR0FBYyxFQUFFLENBQUM7UUFFNUIsT0FBTyxDQUFDLElBQUksQ0FDVixJQUFJLDJCQUFVLENBQUM7WUFDYixNQUFNLEVBQUUsQ0FBQztZQUNULEtBQUssRUFBRSxFQUFFO1lBQ1QsUUFBUSxFQUNOLDZGQUE2RjtTQUNoRyxDQUFDLENBQ0gsQ0FBQztRQUVGLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUN0QixzQ0FBc0MsQ0FBQyw0QkFBNEIsQ0FDakUsS0FBSyxFQUNMLEtBQUssRUFDTCxtQkFBbUIsQ0FDcEIsQ0FDRixDQUFDO1FBRUYsSUFDRSxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQzdCLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxtQkFBbUIsS0FBSyxTQUFTLENBQ3pELENBQUMsTUFBTSxHQUFHLENBQUMsRUFDWixDQUFDO1lBQ0QsT0FBTyxDQUFDLElBQUksQ0FDVixJQUFJLDJCQUFVLENBQUM7Z0JBQ2IsTUFBTSxFQUFFLENBQUM7Z0JBQ1QsS0FBSyxFQUFFLEVBQUU7Z0JBQ1QsUUFBUSxFQUNOLGlHQUFpRzthQUNwRyxDQUFDLENBQ0gsQ0FBQztZQUVGLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUN0QixzQ0FBc0MsQ0FBQyw0QkFBNEIsQ0FDakUsS0FBSyxFQUNMLElBQUksRUFDSixtQkFBbUIsQ0FDcEIsQ0FDRixDQUFDO1FBQ0osQ0FBQztRQUVELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFTyxNQUFNLENBQUMsMkJBQTJCLENBQ3hDLEtBQWtELEVBQ2xELFFBQWlCLEVBQ2pCLG1CQUE2QjtRQUU3QixJQUFJLE9BQU8sR0FBYyxFQUFFLENBQUM7UUFFNUIsT0FBTyxDQUFDLElBQUksQ0FDVixJQUFJLDRCQUFXLENBQUM7WUFDZCxNQUFNLEVBQUUsQ0FBQztZQUNULEtBQUssRUFBRSxFQUFFO1lBQ1QsS0FBSyxFQUFFLGdCQUFFLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxHQUFHLGVBQWU7WUFDOUMsTUFBTSxFQUFFLGdCQUFFLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQztZQUM3QixJQUFJLEVBQUUseURBQTJCLENBQUMsd0NBQXdDLENBQ3hFO2dCQUNFLEtBQUssRUFBRSxnQkFBRSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsR0FBRyxlQUFlO2dCQUM5QyxNQUFNLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNO2dCQUM1Qix1QkFBdUIsRUFBRSxJQUFJLENBQUMscUNBQXFDLENBQ2pFLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUNsRCxRQUFRLEVBQ1IsK0NBQXNCLENBQUMsWUFBWSxDQUNwQzthQUNGLENBQ0Y7WUFDRCxTQUFTLEVBQUUsS0FBSztZQUNoQixTQUFTLEVBQUU7Z0JBQ1QsR0FBRyxFQUFFLEdBQUc7Z0JBQ1IsR0FBRyxFQUFFLEVBQUU7Z0JBQ1AsS0FBSyxFQUFFLGNBQWM7Z0JBQ3JCLFNBQVMsRUFBRSxLQUFLO2FBQ2pCO1lBQ0QsS0FBSyxFQUNILHlEQUEyQixDQUFDLHdDQUF3QyxDQUFDO2dCQUNuRSxLQUFLLEVBQUUsZ0JBQUUsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEdBQUcsU0FBUztnQkFDeEMsTUFBTSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTTtnQkFDNUIsdUJBQXVCLEVBQUUsSUFBSSxDQUFDLHFDQUFxQyxDQUNqRSxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFDbEQsUUFBUSxFQUNSLCtDQUFzQixDQUFDLFdBQVcsQ0FDbkM7YUFDRixDQUFDO1lBQ0osVUFBVSxFQUFFO2dCQUNWLEtBQUssRUFBRSxRQUFRO2dCQUNmLFNBQVMsRUFBRSxLQUFLO2dCQUNoQixHQUFHLEVBQUUsQ0FBQztnQkFDTixHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLG1CQUFtQixHQUFHLEdBQUcsQ0FBQzthQUN4RDtZQUNELGdCQUFnQixFQUFFO2dCQUNoQjtvQkFDRSxLQUFLLEVBQUUsc0JBQUssQ0FBQyxHQUFHO29CQUNoQixLQUFLLEVBQUUsZUFBZTtvQkFDdEIsS0FBSyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsbUJBQW1CO2lCQUN6QzthQUNGO1NBQ0YsQ0FBQyxDQUNILENBQUM7UUFFRixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDcEQsSUFBSSxrQkFBa0IsR0FBRyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUVoRCxPQUFPLENBQUMsSUFBSSxDQUNWLElBQUksNEJBQVcsQ0FBQztnQkFDZCxNQUFNLEVBQUUsQ0FBQztnQkFDVCxLQUFLLEVBQUUsQ0FBQztnQkFDUixLQUFLLEVBQUUsa0JBQWtCLEdBQUcsZUFBZTtnQkFDM0MsTUFBTSxFQUFFLGdCQUFFLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQztnQkFDN0IsSUFBSSxFQUFFLG1EQUF3QixDQUFDLHFDQUFxQyxDQUFDO29CQUNuRSxLQUFLLEVBQUUsa0JBQWtCLEdBQUcsZUFBZTtvQkFDM0MsTUFBTSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTTtvQkFDNUIsdUJBQXVCLEVBQUUsSUFBSSxDQUFDLGtDQUFrQyxDQUM5RCxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFDbEQsa0JBQWtCLEVBQ2xCLFFBQVEsRUFDUiwrQ0FBc0IsQ0FBQyxZQUFZLENBQ3BDO2lCQUNGLENBQUM7Z0JBQ0YsU0FBUyxFQUFFLEtBQUs7Z0JBQ2hCLFNBQVMsRUFBRTtvQkFDVCxHQUFHLEVBQUUsR0FBRztvQkFDUixHQUFHLEVBQUUsRUFBRTtvQkFDUCxLQUFLLEVBQUUsY0FBYztvQkFDckIsU0FBUyxFQUFFLEtBQUs7aUJBQ2pCO2dCQUNELEtBQUssRUFBRSxtREFBd0IsQ0FBQyxxQ0FBcUMsQ0FDbkU7b0JBQ0UsS0FBSyxFQUFFLGtCQUFrQixHQUFHLFNBQVM7b0JBQ3JDLE1BQU0sRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU07b0JBQzVCLHVCQUF1QixFQUFFLElBQUksQ0FBQyxrQ0FBa0MsQ0FDOUQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQ2xELGtCQUFrQixFQUNsQixRQUFRLEVBQ1IsK0NBQXNCLENBQUMsV0FBVyxDQUNuQztpQkFDRixDQUNGO2dCQUNELFVBQVUsRUFBRTtvQkFDVixLQUFLLEVBQUUsUUFBUTtvQkFDZixTQUFTLEVBQUUsS0FBSztvQkFDaEIsR0FBRyxFQUFFLENBQUM7b0JBQ04sR0FBRyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsR0FBRyxHQUFHLENBQUM7aUJBQ3hEO2dCQUNELGdCQUFnQixFQUFFO29CQUNoQjt3QkFDRSxLQUFLLEVBQUUsc0JBQUssQ0FBQyxHQUFHO3dCQUNoQixLQUFLLEVBQUUsZUFBZTt3QkFDdEIsS0FBSyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsbUJBQW1CO3FCQUN6QztpQkFDRjthQUNGLENBQUMsQ0FDSCxDQUFDO1FBQ0osQ0FBQztRQUVELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFTyxNQUFNLENBQUMsNEJBQTRCLENBQ3pDLEtBQWtELEVBQ2xELFFBQWlCLEVBQ2pCLG1CQUE2QjtRQUU3QixJQUFJLE9BQU8sR0FBYyxFQUFFLENBQUM7UUFFNUIsT0FBTyxDQUFDLElBQUksQ0FDVixJQUFJLDRCQUFXLENBQUM7WUFDZCxNQUFNLEVBQUUsQ0FBQztZQUNULEtBQUssRUFBRSxFQUFFO1lBQ1QsS0FBSyxFQUFFLGdCQUFFLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxHQUFHLHFCQUFxQjtZQUNwRCxNQUFNLEVBQUUsZ0JBQUUsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDO1lBQzdCLElBQUksRUFBRSwrQ0FBc0IsQ0FBQyx3Q0FBd0MsQ0FBQztnQkFDcEUsS0FBSyxFQUFFLGdCQUFFLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQztnQkFDNUIsTUFBTSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTTtnQkFDNUIsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLGdDQUFnQyxDQUN2RCxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFDbEQsUUFBUSxFQUNSLHFDQUFpQixDQUFDLGVBQWUsQ0FDbEM7YUFDRixDQUFDO1lBQ0YsU0FBUyxFQUFFLEtBQUs7WUFDaEIsU0FBUyxFQUFFO2dCQUNULEdBQUcsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLG1CQUFtQixHQUFHLEdBQUc7Z0JBQzVDLEdBQUcsRUFBRSxDQUFDO2dCQUNOLEtBQUssRUFBRSxLQUFLO2dCQUNaLFNBQVMsRUFBRSxLQUFLO2FBQ2pCO1lBQ0QsZUFBZSxFQUFFO2dCQUNmO29CQUNFLEtBQUssRUFBRSxzQkFBSyxDQUFDLEdBQUc7b0JBQ2hCLEtBQUssRUFBRSxlQUFlO29CQUN0QixLQUFLLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUI7aUJBQ3pDO2FBQ0Y7U0FDRixDQUFDLENBQ0gsQ0FBQztRQUVGLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNwRCxJQUFJLGtCQUFrQixHQUFHLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRWhELE9BQU8sQ0FBQyxJQUFJLENBQ1YsSUFBSSw0QkFBVyxDQUFDO2dCQUNkLE1BQU0sRUFBRSxDQUFDO2dCQUNULEtBQUssRUFBRSxDQUFDO2dCQUNSLEtBQUssRUFBRSxrQkFBa0IsR0FBRyxxQkFBcUI7Z0JBQ2pELE1BQU0sRUFBRSxnQkFBRSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUM7Z0JBQzdCLElBQUksRUFBRSx5Q0FBbUIsQ0FBQyxnQ0FBZ0MsQ0FBQztvQkFDekQsS0FBSyxFQUFFLGtCQUFrQjtvQkFDekIsTUFBTSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTTtvQkFDNUIsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLDZCQUE2QixDQUNwRCxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFDbEQsa0JBQWtCLEVBQ2xCLFFBQVEsRUFDUixxQ0FBaUIsQ0FBQyxlQUFlLENBQ2xDO2lCQUNGLENBQUM7Z0JBQ0YsU0FBUyxFQUFFLEtBQUs7Z0JBQ2hCLFNBQVMsRUFBRTtvQkFDVCxHQUFHLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsR0FBRyxHQUFHO29CQUM1QyxHQUFHLEVBQUUsQ0FBQztvQkFDTixLQUFLLEVBQUUsS0FBSztvQkFDWixTQUFTLEVBQUUsS0FBSztpQkFDakI7Z0JBQ0QsZUFBZSxFQUFFO29CQUNmO3dCQUNFLEtBQUssRUFBRSxzQkFBSyxDQUFDLEdBQUc7d0JBQ2hCLEtBQUssRUFBRSxlQUFlO3dCQUN0QixLQUFLLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUI7cUJBQ3pDO2lCQUNGO2FBQ0YsQ0FBQyxDQUNILENBQUM7UUFDSixDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVPLE1BQU0sQ0FBQyxxQ0FBcUMsQ0FDbEQsa0JBQWdDLEVBQ2hDLFFBQWlCLEVBQ2pCLFVBQWtDO1FBRWxDLE9BQU8sa0JBQWtCO2FBQ3RCLE1BQU0sQ0FBQyxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUMxQixJQUFJLFFBQVEsSUFBSSxLQUFLLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztnQkFDMUMsUUFBUSxDQUFDLElBQUksQ0FDWCxLQUFLLENBQUMsbUJBQW1CLENBQUMsK0JBQStCLENBQzFELENBQUM7WUFDSixDQUFDO2lCQUFNLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDckIsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsbUNBQW1DLENBQUMsQ0FBQztZQUMzRCxDQUFDO1lBQ0QsT0FBTyxRQUFRLENBQUM7UUFDbEIsQ0FBQyxFQUFFLEVBQStCLENBQUM7YUFDbEMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDVCxPQUFPO2dCQUNMLEtBQUssRUFDSCxDQUFDLENBQUMsYUFBYSxHQUFHLEdBQUcsR0FBRyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUM7Z0JBQ2pFLGFBQWEsRUFBRSxDQUFDO2dCQUNoQixVQUFVLEVBQUUsVUFBVTthQUN2QixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU8sTUFBTSxDQUFDLGdDQUFnQyxDQUM3QyxrQkFBZ0MsRUFDaEMsUUFBaUIsRUFDakIsVUFBNkI7UUFFN0IsT0FBTyxrQkFBa0I7YUFDdEIsTUFBTSxDQUFDLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQzFCLElBQUksUUFBUSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO2dCQUMxQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1lBQ3RFLENBQUM7aUJBQU0sSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUNyQixRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1lBQ3RELENBQUM7WUFDRCxPQUFPLFFBQVEsQ0FBQztRQUNsQixDQUFDLEVBQUUsRUFBK0IsQ0FBQzthQUNsQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUNULE9BQU87Z0JBQ0wsS0FBSyxFQUNILENBQUMsQ0FBQyxhQUFhO2dCQUNqQixhQUFhLEVBQUUsQ0FBQztnQkFDaEIsVUFBVSxFQUFFLFVBQVU7Z0JBQ3RCLFNBQVMsRUFBRSxLQUFLLEdBQUcsQ0FBQyxDQUFDLHFCQUFxQixHQUFHLElBQUk7YUFDbEQsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVPLE1BQU0sQ0FBQyxrQ0FBa0MsQ0FDL0Msa0JBQWdDLEVBQ2hDLGtCQUEwQixFQUMxQixRQUFpQixFQUNqQixVQUFrQztRQUVsQyxPQUFPLGtCQUFrQjthQUN0QixNQUFNLENBQUMsQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDMUIsSUFDRSxRQUFRO2dCQUNSLEtBQUssQ0FBQyxtQkFBbUIsS0FBSyxTQUFTO2dCQUN2QyxLQUFLLENBQUMsbUJBQW1CLElBQUksSUFBSSxFQUNqQyxDQUFDO2dCQUNELFFBQVEsQ0FBQyxJQUFJLENBQ1gsS0FBSyxDQUFDLG1CQUFtQixDQUFDLCtCQUErQixDQUMxRCxDQUFDO1lBQ0osQ0FBQztpQkFBTSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ3JCLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7WUFDM0QsQ0FBQztZQUNELE9BQU8sUUFBUSxDQUFDO1FBQ2xCLENBQUMsRUFBRSxFQUErQixDQUFDO2FBQ2xDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ1QsT0FBTztnQkFDTCxLQUFLLEVBQ0gsQ0FBQyxDQUFDLGFBQWEsR0FBRyxHQUFHLEdBQUcsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDO2dCQUNqRSxhQUFhLEVBQUUsQ0FBQztnQkFDaEIsVUFBVSxFQUFFLFVBQVU7Z0JBQ3RCLGtCQUFrQixFQUFFLGtCQUFrQjthQUN2QyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU8sTUFBTSxDQUFDLDZCQUE2QixDQUMxQyxrQkFBZ0MsRUFDaEMsa0JBQTBCLEVBQzFCLFFBQWlCLEVBQ2pCLFVBQTZCO1FBRTdCLE9BQU8sa0JBQWtCO2FBQ3RCLE1BQU0sQ0FBQyxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUMxQixJQUNFLFFBQVE7Z0JBQ1IsS0FBSyxDQUFDLG1CQUFtQixLQUFLLFNBQVM7Z0JBQ3ZDLEtBQUssQ0FBQyxtQkFBbUIsSUFBSSxJQUFJLEVBQ2pDLENBQUM7Z0JBQ0QsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsMEJBQTBCLENBQUMsQ0FBQztZQUN0RSxDQUFDO2lCQUFNLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDckIsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztZQUN0RCxDQUFDO1lBQ0QsT0FBTyxRQUFRLENBQUM7UUFDbEIsQ0FBQyxFQUFFLEVBQStCLENBQUM7YUFDbEMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDVCxPQUFPO2dCQUNMLEtBQUssRUFDSCxDQUFDLENBQUMsYUFBYTtnQkFDakIsYUFBYSxFQUFFLENBQUM7Z0JBQ2hCLFVBQVUsRUFBRSxVQUFVO2dCQUN0QixrQkFBa0IsRUFBRSxrQkFBa0I7Z0JBQ3RDLFNBQVMsRUFBRSxLQUFLLEdBQUcsQ0FBQyxDQUFDLHFCQUFxQixHQUFHLElBQUk7YUFDbEQsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVPLE1BQU0sQ0FBQywyQkFBMkIsQ0FDeEMsS0FBa0QsRUFDbEQsS0FBYSxFQUNiLHFCQUErQjtRQUUvQixJQUFJLFVBQVUsR0FBYyxFQUFFLENBQUM7UUFFL0IsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLDJCQUFVLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUUzRSxJQUFJLFNBQVMsR0FBRyw2QkFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBRXpDLElBQUksZ0JBQWdCLEdBQWMsRUFBRSxDQUFDO1FBQ3JDLElBQUksbUJBQW1CLEdBQWMsRUFBRSxDQUFDO1FBQ3hDLElBQUkscUJBQXFCLEdBQWMsRUFBRSxDQUFDO1FBRTFDLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxDQUFDLG9CQUFvQixFQUFFLEVBQUU7WUFDckQsSUFBSSxrQkFBa0IsR0FDcEIsS0FBSyxDQUFDLFFBQVEsQ0FBQyw0Q0FBNEMsQ0FDekQsb0JBQW9CLENBQUMsU0FBUyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FDaEUsQ0FBQztZQUVKLFNBQVMsR0FBRyw2QkFBYSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUU5QyxJQUFJLFdBQVcsR0FBWSwrREFBOEIsQ0FBQywwQkFBMEIsQ0FDbEYsS0FBSyxDQUFDLE9BQU8sQ0FBQyxZQUF3QyxFQUN0RDtnQkFDRSxnQkFBZ0IsRUFBRSxvQkFBb0I7Z0JBQ3RDLGtCQUFrQixFQUFFLGtCQUFrQjtnQkFDdEMsVUFBVSxFQUFFLCtDQUFzQixDQUFDLFVBQVU7Z0JBQzdDLEtBQUssRUFBRSxrQkFBa0I7Z0JBQ3pCLE1BQU0sRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU07Z0JBQzVCLFNBQVMsRUFBRSxTQUFTO2FBQ3JCLENBQ0YsQ0FBQztZQUVGLGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUVuQyxJQUFJLGtCQUFrQixHQUFZLCtEQUE4QixDQUFDLDBCQUEwQixDQUN6RixLQUFLLENBQUMsT0FBTyxDQUFDLFlBQXdDLEVBQ3REO2dCQUNFLGdCQUFnQixFQUFFLG9CQUFvQjtnQkFDdEMsa0JBQWtCLEVBQUUsa0JBQWtCO2dCQUN0QyxVQUFVLEVBQUUsK0NBQXNCLENBQUMsYUFBYTtnQkFDaEQsS0FBSyxFQUFFLGtCQUFrQjtnQkFDekIsTUFBTSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTTtnQkFDNUIsU0FBUyxFQUFFLFNBQVM7YUFDckIsQ0FDRixDQUFDO1lBRUYsbUJBQW1CLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFFN0MsSUFBSSxvQkFBb0IsR0FBWSwrREFBOEIsQ0FBQyw0QkFBNEIsQ0FDN0YsS0FBSyxDQUFDLE9BQU8sQ0FBQyxZQUF3QyxFQUN0RCxvQkFBb0IsRUFDcEIsa0JBQWtCLEVBQ2xCLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUNyQixDQUFDO1lBRUYscUJBQXFCLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDbkQsQ0FBQyxDQUFDLENBQUM7UUFFSCxVQUFVLENBQUMsSUFBSSxDQUNiLElBQUksNEJBQVcsQ0FBQztZQUNkLE1BQU0sRUFBRSxDQUFDO1lBQ1QsS0FBSyxFQUFFLENBQUM7WUFDUixLQUFLLEVBQUUsZ0JBQUUsQ0FBQyxHQUFHLENBQUMsMkJBQTJCLENBQUM7WUFDMUMsTUFBTSxFQUFFLGdCQUFFLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDO1lBQ2hDLElBQUksRUFBRSxnQkFBZ0I7WUFDdEIsU0FBUyxFQUFFO2dCQUNULEdBQUcsRUFBRSxFQUFFO2dCQUNQLEdBQUcsRUFBRSxDQUFDO2dCQUNOLEtBQUssRUFBRSxZQUFZO2dCQUNuQixTQUFTLEVBQUUsS0FBSzthQUNqQjtTQUNGLENBQUMsQ0FDSCxDQUFDO1FBRUYsVUFBVSxDQUFDLElBQUksQ0FDYixJQUFJLDRCQUFXLENBQUM7WUFDZCxNQUFNLEVBQUUsQ0FBQztZQUNULEtBQUssRUFBRSxDQUFDO1lBQ1IsS0FBSyxFQUFFLGdCQUFFLENBQUMsR0FBRyxDQUFDLDhCQUE4QixDQUFDO1lBQzdDLE1BQU0sRUFBRSxnQkFBRSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQztZQUNoQyxJQUFJLEVBQUUsbUJBQW1CO1lBQ3pCLFNBQVMsRUFBRTtnQkFDVCxHQUFHLEVBQUUsQ0FBQztnQkFDTixLQUFLLEVBQUUsS0FBSztnQkFDWixTQUFTLEVBQUUsS0FBSzthQUNqQjtTQUNGLENBQUMsQ0FDSCxDQUFDO1FBRUYsVUFBVSxDQUFDLElBQUksQ0FDYixJQUFJLDRCQUFXLENBQUM7WUFDZCxNQUFNLEVBQUUsQ0FBQztZQUNULEtBQUssRUFBRSxDQUFDO1lBQ1IsS0FBSyxFQUFFLGdCQUFFLENBQUMsR0FBRyxDQUFDLGdDQUFnQyxDQUFDO1lBQy9DLE1BQU0sRUFBRSxnQkFBRSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQztZQUNoQyxJQUFJLEVBQUUscUJBQXFCO1lBQzNCLFNBQVMsRUFBRTtnQkFDVCxHQUFHLEVBQUUsQ0FBQztnQkFDTixTQUFTLEVBQUUsSUFBSTthQUNoQjtTQUNGLENBQUMsQ0FDSCxDQUFDO1FBRUYsT0FBTyxVQUFVLENBQUM7SUFDcEIsQ0FBQztJQU1ELFlBQ0UsS0FBZ0IsRUFDaEIsRUFBVSxFQUNWLEtBQWtEO1FBRWxELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsSUFBSSw2QkFBNkIsR0FBYyxFQUFFLENBQUM7UUFFbEQsSUFBSSxtQkFBbUIsR0FBYSxLQUFLLENBQUMsT0FBTyxDQUFDLHFCQUFxQixDQUFDLEdBQUcsQ0FDekUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUNKLE9BQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyw0Q0FBNEMsQ0FDaEUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUMxQixDQUFDO1FBQ0osQ0FBQyxDQUNGLENBQUM7UUFFRiw2QkFBNkIsQ0FBQyxJQUFJLENBQ2hDLElBQUksMkJBQVUsQ0FBQztZQUNiLE1BQU0sRUFBRSxDQUFDO1lBQ1QsS0FBSyxFQUFFLEVBQUU7WUFDVCxRQUFRLEVBQUUsdUNBQXVDO1NBQ2xELENBQUMsQ0FDSCxDQUFDO1FBRUYsNkJBQTZCLENBQUMsSUFBSSxDQUNoQyxJQUFJLGtDQUFpQixDQUFDO1lBQ3BCLE1BQU0sRUFBRSxDQUFDO1lBQ1QsS0FBSyxFQUFFLEVBQUU7WUFDVCxNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUMsc0JBQXNCLENBQUM7WUFDdEMsS0FBSyxFQUNILDBIQUEwSDtTQUM3SCxDQUFDLENBQ0gsQ0FBQztRQUVGLElBQUksU0FBUyxHQUFXLDZCQUFhLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDakQsSUFBSSwyQkFBMkIsR0FBYyxFQUFFLENBQUM7UUFFaEQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3BELElBQUksT0FBTyxHQUFXLENBQUMsQ0FBQztZQUN4QixJQUFJLGtCQUFrQixHQUFXLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRXhELDZCQUE2QixDQUFDLElBQUksQ0FDaEMsSUFBSSxrQ0FBaUIsQ0FBQztnQkFDcEIsTUFBTSxFQUFFLENBQUM7Z0JBQ1QsS0FBSyxFQUFFLENBQUM7Z0JBQ1IsTUFBTSxFQUFFLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN2QyxLQUFLLEVBQ0gsa0JBQWtCO29CQUNsQiwwR0FBMEc7YUFDN0csQ0FBQyxDQUNILENBQUM7WUFFRixJQUFJLFlBQVksR0FBK0IsRUFBRSxDQUFDO1lBRWxELEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVTtpQkFDckIsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQztpQkFDakMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7Z0JBQ2IsWUFBWSxDQUFDLEdBQUcsU0FBUyxHQUFHLE9BQU8sRUFBRSxFQUFFLENBQUM7b0JBQ3RDLG1EQUF3QixDQUFDLDZCQUE2QixDQUFDO3dCQUNyRCxrQkFBa0IsRUFBRSxrQkFBa0I7d0JBQ3RDLGFBQWEsRUFBRSxDQUFDLENBQUMsbUNBQW1DO3dCQUNwRCxLQUFLLEVBQ0gsa0JBQWtCLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxhQUFhLEdBQUcsY0FBYzt3QkFDN0QsVUFBVSxFQUFFLCtDQUFzQixDQUFDLFdBQVc7d0JBQzlDLFNBQVMsRUFBRSxTQUFTO3FCQUNyQixDQUFDLENBQUM7WUFDUCxDQUFDLENBQUMsQ0FBQztZQUVMLElBQUksZUFBZSxHQUFZLElBQUksK0JBQWMsQ0FBQztnQkFDaEQsVUFBVSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztnQkFDL0MsS0FBSyxFQUFFLGtCQUFrQixHQUFHLGNBQWM7Z0JBQzFDLFlBQVksRUFBRSxZQUFZO2dCQUMxQixNQUFNLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNO2FBQzdCLENBQUMsQ0FBQztZQUVILDJCQUEyQixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUNsRCxTQUFTLEdBQUcsNkJBQWEsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUVELElBQUksb0JBQW9CLEdBQWM7WUFDcEMsSUFBSSwyQkFBVSxDQUFDO2dCQUNiLE1BQU0sRUFBRSxDQUFDO2dCQUNULEtBQUssRUFBRSxFQUFFO2dCQUNULFFBQVEsRUFBRSwrQkFBK0I7YUFDMUMsQ0FBQztZQUNGLElBQUksNEJBQVcsQ0FBQztnQkFDZCxNQUFNLEVBQUUsQ0FBQztnQkFDVCxLQUFLLEVBQUUsRUFBRTtnQkFDVCxLQUFLLEVBQUUsZ0JBQWdCO2dCQUN2QixNQUFNLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNO2dCQUM1QixJQUFJLEVBQUUsMkJBQTJCO2FBQ2xDLENBQUM7U0FDSCxDQUFDO1FBRUYsNkJBQTZCLENBQUMsTUFBTSxDQUNsQyxzQ0FBc0MsQ0FBQyxrQkFBa0IsQ0FDdkQsS0FBSyxFQUNMLG1CQUFtQixDQUNwQixDQUNGLENBQUM7UUFFRixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksMEJBQVMsQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLEVBQUU7WUFDeEQsYUFBYSxFQUNYLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRTtnQkFDdkMsZ0JBQUUsQ0FBQyxHQUFHLENBQUMsMENBQTBDLENBQUM7WUFDcEQsZUFBZSxFQUFFLEtBQUssQ0FBQyxRQUFRO1lBQy9CLGNBQWMsRUFBRSwrQkFBYyxDQUFDLElBQUk7WUFDbkMsT0FBTyxFQUFFO2dCQUNQLDZCQUE2QjtnQkFDN0Isb0JBQW9CO2dCQUNwQixzQ0FBc0MsQ0FBQyw4Q0FBOEMsQ0FDbkYsS0FBSyxFQUNMLG1CQUFtQixDQUNwQjtnQkFDRCxzQ0FBc0MsQ0FBQyx5Q0FBeUMsQ0FDOUUsS0FBSyxFQUNMLG1CQUFtQixDQUNwQjthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsSUFBSSxFQUFFLEdBQW9CLEtBQUssQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLElBQUk7YUFDdkQsWUFBK0IsQ0FBQztRQUVuQyxJQUFJLEVBQUUsS0FBSyxTQUFTLElBQUksRUFBRSxJQUFJLElBQUksSUFBSSxFQUFFLENBQUMsSUFBSSxJQUFJLGFBQWEsRUFBRSxDQUFDO1lBQy9ELElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUN2QixHQUFHLHNDQUFzQyxDQUFDLDJCQUEyQixDQUNuRSxLQUFLLEVBQ0wsdUNBQXVDLEVBQ3ZDLEtBQUssQ0FBQyxPQUFPLENBQUMscUJBQXFCLENBQ3BDLENBQ0YsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUEvdEJELHdGQSt0QkMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5pbXBvcnQgeyBGbiB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7XG4gIEFsYXJtU3RhdHVzV2lkZ2V0LFxuICBDb2xvcixcbiAgRGFzaGJvYXJkLFxuICBHcmFwaFdpZGdldCxcbiAgSU1ldHJpYyxcbiAgSVdpZGdldCxcbiAgTWF0aEV4cHJlc3Npb24sXG4gIFBlcmlvZE92ZXJyaWRlLFxuICBUZXh0V2lkZ2V0LFxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaCc7XG5pbXBvcnQge1xuICBDZm5Mb2FkQmFsYW5jZXIsXG4gIElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcixcbn0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjInO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBJU2VydmljZUF2YWlsYWJpbGl0eUFuZExhdGVuY3lEYXNoYm9hcmQgfSBmcm9tICcuL0lTZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZCc7XG5pbXBvcnQgeyBTZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZFByb3BzIH0gZnJvbSAnLi9wcm9wcy9TZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZFByb3BzJztcbmltcG9ydCB7IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTWV0cmljcyB9IGZyb20gJy4uL21ldHJpY3MvQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzJztcbmltcG9ydCB7IEF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzIH0gZnJvbSAnLi4vbWV0cmljcy9wcm9wcy9BdmFpbGFiaWxpdHlNZXRyaWNQcm9wcyc7XG5pbXBvcnQgeyBMYXRlbmN5TWV0cmljUHJvcHMgfSBmcm9tICcuLi9tZXRyaWNzL3Byb3BzL0xhdGVuY3lNZXRyaWNQcm9wcyc7XG5pbXBvcnQgeyBSZWdpb25hbEF2YWlsYWJpbGl0eU1ldHJpY3MgfSBmcm9tICcuLi9tZXRyaWNzL1JlZ2lvbmFsQXZhaWxhYmlsaXR5TWV0cmljcyc7XG5pbXBvcnQgeyBSZWdpb25hbExhdGVuY3lNZXRyaWNzIH0gZnJvbSAnLi4vbWV0cmljcy9SZWdpb25hbExhdGVuY3lNZXRyaWNzJztcbmltcG9ydCB7IFpvbmFsQXZhaWxhYmlsaXR5TWV0cmljcyB9IGZyb20gJy4uL21ldHJpY3MvWm9uYWxBdmFpbGFiaWxpdHlNZXRyaWNzJztcbmltcG9ydCB7IFpvbmFsTGF0ZW5jeU1ldHJpY3MgfSBmcm9tICcuLi9tZXRyaWNzL1pvbmFsTGF0ZW5jeU1ldHJpY3MnO1xuaW1wb3J0IHsgSU9wZXJhdGlvbiB9IGZyb20gJy4uL3NlcnZpY2VzL0lPcGVyYXRpb24nO1xuaW1wb3J0IHsgSU9wZXJhdGlvbk1ldHJpY0RldGFpbHMgfSBmcm9tICcuLi9zZXJ2aWNlcy9JT3BlcmF0aW9uTWV0cmljRGV0YWlscyc7XG5pbXBvcnQgeyBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlIH0gZnJvbSAnLi4vdXRpbGl0aWVzL0F2YWlsYWJpbGl0eU1ldHJpY1R5cGUnO1xuaW1wb3J0IHsgTGF0ZW5jeU1ldHJpY1R5cGUgfSBmcm9tICcuLi91dGlsaXRpZXMvTGF0ZW5jeU1ldHJpY1R5cGUnO1xuaW1wb3J0IHsgTWV0cmljc0hlbHBlciB9IGZyb20gJy4uL3V0aWxpdGllcy9NZXRyaWNzSGVscGVyJztcblxuLyoqXG4gKiBDcmVhdGVzIGEgc2VydmljZSBsZXZlbCBhdmFpbGFiaWxpdHkgYW5kIGxhdGVuY3kgZGFzaGJvYXJkXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZFxuICBleHRlbmRzIENvbnN0cnVjdFxuICBpbXBsZW1lbnRzIElTZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZCB7XG4gIHByaXZhdGUgc3RhdGljIGdlbmVyYXRlVFBTV2lkZ2V0cyhcbiAgICBwcm9wczogU2VydmljZUF2YWlsYWJpbGl0eUFuZExhdGVuY3lEYXNoYm9hcmRQcm9wcyxcbiAgICBhdmFpbGFiaWxpdHlab25lSWRzOiBzdHJpbmdbXSxcbiAgKTogSVdpZGdldFtdIHtcbiAgICBsZXQgd2lkZ2V0czogSVdpZGdldFtdID0gW107XG5cbiAgICB3aWRnZXRzLnB1c2goXG4gICAgICBuZXcgVGV4dFdpZGdldCh7IGhlaWdodDogMiwgd2lkdGg6IDI0LCBtYXJrZG93bjogJyoqVFBTIE1ldHJpY3MqKicgfSksXG4gICAgKTtcblxuICAgIHdpZGdldHMucHVzaChcbiAgICAgIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgIGhlaWdodDogNixcbiAgICAgICAgd2lkdGg6IDI0LFxuICAgICAgICB0aXRsZTogRm4ucmVmKCdBV1M6OlJlZ2lvbicpICsgJyBUUFMnLFxuICAgICAgICByZWdpb246IEZuLnJlZignQVdTOjpSZWdpb24nKSxcbiAgICAgICAgbGVmdDogUmVnaW9uYWxBdmFpbGFiaWxpdHlNZXRyaWNzLmNyZWF0ZVJlZ2lvbmFsU2VydmljZUF2YWlsYWJpbGl0eU1ldHJpY3MoXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGFiZWw6IEZuLnJlZignQVdTOjpSZWdpb24nKSArICcgdHBzJyxcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMuc2VydmljZS5wZXJpb2QsXG4gICAgICAgICAgICBhdmFpbGFiaWxpdHlNZXRyaWNQcm9wczogcHJvcHMuc2VydmljZS5vcGVyYXRpb25zXG4gICAgICAgICAgICAgIC5maWx0ZXIoKHgpID0+IHguY3JpdGljYWwpXG4gICAgICAgICAgICAgIC5tYXAoKHgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgbGFiZWw6IHgub3BlcmF0aW9uTmFtZSxcbiAgICAgICAgICAgICAgICAgIG1ldHJpY0RldGFpbHM6IHguc2VydmVyU2lkZUF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHMsXG4gICAgICAgICAgICAgICAgICBtZXRyaWNUeXBlOiBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlJFUVVFU1RfQ09VTlQsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgfSxcbiAgICAgICAgKSxcbiAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgbGVmdFlBeGlzOiB7XG4gICAgICAgICAgbGFiZWw6ICdUUFMnLFxuICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdmFpbGFiaWxpdHlab25lSWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkOiBzdHJpbmcgPSBhdmFpbGFiaWxpdHlab25lSWRzW2ldO1xuXG4gICAgICBsZXQgem9uYWxNZXRyaWNQcm9wcyA9IHtcbiAgICAgICAgYXZhaWxhYmlsaXR5TWV0cmljUHJvcHM6IHByb3BzLnNlcnZpY2Uub3BlcmF0aW9uc1xuICAgICAgICAgIC5maWx0ZXIoKHgpID0+IHguY3JpdGljYWwpXG4gICAgICAgICAgLm1hcCgoeCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgIGxhYmVsOiB4Lm9wZXJhdGlvbk5hbWUsXG4gICAgICAgICAgICAgIG1ldHJpY0RldGFpbHM6IHguc2VydmVyU2lkZUF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHMsXG4gICAgICAgICAgICAgIG1ldHJpY1R5cGU6IEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuUkVRVUVTVF9DT1VOVCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSksXG4gICAgICAgIHBlcmlvZDogcHJvcHMuc2VydmljZS5wZXJpb2QsXG4gICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQgKyAndHBzJyxcbiAgICAgIH07XG5cbiAgICAgIHdpZGdldHMucHVzaChcbiAgICAgICAgbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICBoZWlnaHQ6IDYsXG4gICAgICAgICAgd2lkdGg6IDgsXG4gICAgICAgICAgdGl0bGU6IGF2YWlsYWJpbGl0eVpvbmVJZCArICcgVFBTJyxcbiAgICAgICAgICByZWdpb246IEZuLnJlZignQVdTOjpSZWdpb24nKSxcbiAgICAgICAgICBsZWZ0OiBab25hbEF2YWlsYWJpbGl0eU1ldHJpY3MuY3JlYXRlWm9uYWxTZXJ2aWNlQXZhaWxhYmlsaXR5TWV0cmljcyhcbiAgICAgICAgICAgIHpvbmFsTWV0cmljUHJvcHMsXG4gICAgICAgICAgKSxcbiAgICAgICAgICBzdGF0aXN0aWM6ICdTdW0nLFxuICAgICAgICAgIGxlZnRZQXhpczoge1xuICAgICAgICAgICAgbGFiZWw6ICdUUFMnLFxuICAgICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHdpZGdldHM7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZW5lcmF0ZVNlcnZlclNpZGVBbmRDYW5hcnlBdmFpbGFiaWxpdHlXaWRnZXRzKFxuICAgIHByb3BzOiBTZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZFByb3BzLFxuICAgIGF2YWlsYWJpbGl0eVpvbmVJZHM6IHN0cmluZ1tdLFxuICApOiBJV2lkZ2V0W10ge1xuICAgIGxldCB3aWRnZXRzOiBJV2lkZ2V0W10gPSBbXTtcblxuICAgIHdpZGdldHMucHVzaChcbiAgICAgIG5ldyBUZXh0V2lkZ2V0KHtcbiAgICAgICAgaGVpZ2h0OiAyLFxuICAgICAgICB3aWR0aDogMjQsXG4gICAgICAgIG1hcmtkb3duOlxuICAgICAgICAgICcqKlNlcnZlci1zaWRlIEF2YWlsYWJpbGl0eSoqXFxuKEVhY2ggY3JpdGljYWwgb3BlcmF0aW9uIGlzIGVxdWFsbHkgd2VpZ2h0ZWQgcmVnYXJkbGVzcyBvZiByZXF1ZXN0IHZvbHVtZSknLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIHdpZGdldHMgPSB3aWRnZXRzLmNvbmNhdChcbiAgICAgIFNlcnZpY2VBdmFpbGFiaWxpdHlBbmRMYXRlbmN5RGFzaGJvYXJkLmdlbmVyYXRlQXZhaWxhYmlsaXR5V2lkZ2V0cyhcbiAgICAgICAgcHJvcHMsXG4gICAgICAgIGZhbHNlLFxuICAgICAgICBhdmFpbGFiaWxpdHlab25lSWRzLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgaWYgKFxuICAgICAgcHJvcHMuc2VydmljZS5vcGVyYXRpb25zLmZpbHRlcihcbiAgICAgICAgKHgpID0+IHguY3JpdGljYWwgJiYgeC5jYW5hcnlNZXRyaWNEZXRhaWxzICE9PSB1bmRlZmluZWQsXG4gICAgICApLmxlbmd0aCA+IDBcbiAgICApIHtcbiAgICAgIHdpZGdldHMucHVzaChcbiAgICAgICAgbmV3IFRleHRXaWRnZXQoe1xuICAgICAgICAgIGhlaWdodDogMixcbiAgICAgICAgICB3aWR0aDogMjQsXG4gICAgICAgICAgbWFya2Rvd246XG4gICAgICAgICAgICAnKipDYW5hcnkgTWVhc3VyZWQgQXZhaWxhYmlsaXR5KipcXG4oRWFjaCBvcGVyYXRpb24gaXMgZXF1YWxseSB3ZWlnaHRlZCByZWdhcmRsZXNzIG9mIHJlcXVlc3Qgdm9sdW1lKScsXG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgd2lkZ2V0cyA9IHdpZGdldHMuY29uY2F0KFxuICAgICAgICBTZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZC5nZW5lcmF0ZUF2YWlsYWJpbGl0eVdpZGdldHMoXG4gICAgICAgICAgcHJvcHMsXG4gICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWRzLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gd2lkZ2V0cztcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdlbmVyYXRlU2VydmVyU2lkZUFuZENhbmFyeUxhdGVuY3lXaWRnZXRzKFxuICAgIHByb3BzOiBTZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZFByb3BzLFxuICAgIGF2YWlsYWJpbGl0eVpvbmVJZHM6IHN0cmluZ1tdLFxuICApOiBJV2lkZ2V0W10ge1xuICAgIGxldCB3aWRnZXRzOiBJV2lkZ2V0W10gPSBbXTtcblxuICAgIHdpZGdldHMucHVzaChcbiAgICAgIG5ldyBUZXh0V2lkZ2V0KHtcbiAgICAgICAgaGVpZ2h0OiAyLFxuICAgICAgICB3aWR0aDogMjQsXG4gICAgICAgIG1hcmtkb3duOlxuICAgICAgICAgICcqKlNlcnZlci1zaWRlIExhdGVuY3kqKlxcbihDb3VudHMgb2YgcmVxdWVzdHMgZXhjZWVkaW5nIHRoZSBwZXItb3BlcmF0aW9uIGxhdGVuY3kgdGhyZXNob2xkKScsXG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgd2lkZ2V0cyA9IHdpZGdldHMuY29uY2F0KFxuICAgICAgU2VydmljZUF2YWlsYWJpbGl0eUFuZExhdGVuY3lEYXNoYm9hcmQuZ2VuZXJhdGVMYXRlbmN5TWV0cmljV2lkZ2V0cyhcbiAgICAgICAgcHJvcHMsXG4gICAgICAgIGZhbHNlLFxuICAgICAgICBhdmFpbGFiaWxpdHlab25lSWRzLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgaWYgKFxuICAgICAgcHJvcHMuc2VydmljZS5vcGVyYXRpb25zLmZpbHRlcihcbiAgICAgICAgKHgpID0+IHguY3JpdGljYWwgJiYgeC5jYW5hcnlNZXRyaWNEZXRhaWxzICE9PSB1bmRlZmluZWQsXG4gICAgICApLmxlbmd0aCA+IDBcbiAgICApIHtcbiAgICAgIHdpZGdldHMucHVzaChcbiAgICAgICAgbmV3IFRleHRXaWRnZXQoe1xuICAgICAgICAgIGhlaWdodDogMixcbiAgICAgICAgICB3aWR0aDogMjQsXG4gICAgICAgICAgbWFya2Rvd246XG4gICAgICAgICAgICAnKipDYW5hcnkgTWVhc3VyZWQgTGF0ZW5jeSoqXFxuKENvdW50cyBvZiByZXF1ZXN0cyBleGNlZWRpbmcgdGhlIHBlci1vcGVyYXRpb24gbGF0ZW5jeSB0aHJlc2hvbGQpJyxcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICB3aWRnZXRzID0gd2lkZ2V0cy5jb25jYXQoXG4gICAgICAgIFNlcnZpY2VBdmFpbGFiaWxpdHlBbmRMYXRlbmN5RGFzaGJvYXJkLmdlbmVyYXRlTGF0ZW5jeU1ldHJpY1dpZGdldHMoXG4gICAgICAgICAgcHJvcHMsXG4gICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWRzLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gd2lkZ2V0cztcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdlbmVyYXRlQXZhaWxhYmlsaXR5V2lkZ2V0cyhcbiAgICBwcm9wczogU2VydmljZUF2YWlsYWJpbGl0eUFuZExhdGVuY3lEYXNoYm9hcmRQcm9wcyxcbiAgICBpc0NhbmFyeTogYm9vbGVhbixcbiAgICBhdmFpbGFiaWxpdHlab25lSWRzOiBzdHJpbmdbXSxcbiAgKTogSVdpZGdldFtdIHtcbiAgICBsZXQgd2lkZ2V0czogSVdpZGdldFtdID0gW107XG5cbiAgICB3aWRnZXRzLnB1c2goXG4gICAgICBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgICBoZWlnaHQ6IDYsXG4gICAgICAgIHdpZHRoOiAyNCxcbiAgICAgICAgdGl0bGU6IEZuLnJlZignQVdTOjpSZWdpb24nKSArICcgQXZhaWxhYmlsaXR5JyxcbiAgICAgICAgcmVnaW9uOiBGbi5yZWYoJ0FXUzo6UmVnaW9uJyksXG4gICAgICAgIGxlZnQ6IFJlZ2lvbmFsQXZhaWxhYmlsaXR5TWV0cmljcy5jcmVhdGVSZWdpb25hbFNlcnZpY2VBdmFpbGFiaWxpdHlNZXRyaWNzKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGxhYmVsOiBGbi5yZWYoJ0FXUzo6UmVnaW9uJykgKyAnIGF2YWlsYWJpbGl0eScsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnNlcnZpY2UucGVyaW9kLFxuICAgICAgICAgICAgYXZhaWxhYmlsaXR5TWV0cmljUHJvcHM6IHRoaXMuY3JlYXRlUmVnaW9uYWxBdmFpbGFiaWxpdHlNZXRyaWNQcm9wcyhcbiAgICAgICAgICAgICAgcHJvcHMuc2VydmljZS5vcGVyYXRpb25zLmZpbHRlcigoeCkgPT4geC5jcml0aWNhbCksXG4gICAgICAgICAgICAgIGlzQ2FuYXJ5LFxuICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfUkFURSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSxcbiAgICAgICAgKSxcbiAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgbGVmdFlBeGlzOiB7XG4gICAgICAgICAgbWF4OiAxMDAsXG4gICAgICAgICAgbWluOiA5NSxcbiAgICAgICAgICBsYWJlbDogJ0F2YWlsYWJpbGl0eScsXG4gICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAgcmlnaHQ6XG4gICAgICAgICAgUmVnaW9uYWxBdmFpbGFiaWxpdHlNZXRyaWNzLmNyZWF0ZVJlZ2lvbmFsU2VydmljZUF2YWlsYWJpbGl0eU1ldHJpY3Moe1xuICAgICAgICAgICAgbGFiZWw6IEZuLnJlZignQVdTOjpSZWdpb24nKSArICcgZmF1bHRzJyxcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMuc2VydmljZS5wZXJpb2QsXG4gICAgICAgICAgICBhdmFpbGFiaWxpdHlNZXRyaWNQcm9wczogdGhpcy5jcmVhdGVSZWdpb25hbEF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzKFxuICAgICAgICAgICAgICBwcm9wcy5zZXJ2aWNlLm9wZXJhdGlvbnMuZmlsdGVyKCh4KSA9PiB4LmNyaXRpY2FsKSxcbiAgICAgICAgICAgICAgaXNDYW5hcnksXG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuRkFVTFRfQ09VTlQsXG4gICAgICAgICAgICApLFxuICAgICAgICAgIH0pLFxuICAgICAgICByaWdodFlBeGlzOiB7XG4gICAgICAgICAgbGFiZWw6ICdGYXVsdHMnLFxuICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgICAgbWluOiAwLFxuICAgICAgICAgIG1heDogTWF0aC5jZWlsKHByb3BzLnNlcnZpY2UuZmF1bHRDb3VudFRocmVzaG9sZCAqIDEuNSksXG4gICAgICAgIH0sXG4gICAgICAgIHJpZ2h0QW5ub3RhdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb2xvcjogQ29sb3IuUkVELFxuICAgICAgICAgICAgbGFiZWw6ICdIaWdoIHNldmVyaXR5JyxcbiAgICAgICAgICAgIHZhbHVlOiBwcm9wcy5zZXJ2aWNlLmZhdWx0Q291bnRUaHJlc2hvbGQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF2YWlsYWJpbGl0eVpvbmVJZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQgPSBhdmFpbGFiaWxpdHlab25lSWRzW2ldO1xuXG4gICAgICB3aWRnZXRzLnB1c2goXG4gICAgICAgIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgICAgaGVpZ2h0OiA2LFxuICAgICAgICAgIHdpZHRoOiA4LFxuICAgICAgICAgIHRpdGxlOiBhdmFpbGFiaWxpdHlab25lSWQgKyAnIEF2YWlsYWJpbGl0eScsXG4gICAgICAgICAgcmVnaW9uOiBGbi5yZWYoJ0FXUzo6UmVnaW9uJyksXG4gICAgICAgICAgbGVmdDogWm9uYWxBdmFpbGFiaWxpdHlNZXRyaWNzLmNyZWF0ZVpvbmFsU2VydmljZUF2YWlsYWJpbGl0eU1ldHJpY3Moe1xuICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCArICcgYXZhaWxhYmlsaXR5JyxcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMuc2VydmljZS5wZXJpb2QsXG4gICAgICAgICAgICBhdmFpbGFiaWxpdHlNZXRyaWNQcm9wczogdGhpcy5jcmVhdGVab25hbEF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzKFxuICAgICAgICAgICAgICBwcm9wcy5zZXJ2aWNlLm9wZXJhdGlvbnMuZmlsdGVyKCh4KSA9PiB4LmNyaXRpY2FsKSxcbiAgICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgICBpc0NhbmFyeSxcbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5TVUNDRVNTX1JBVEUsXG4gICAgICAgICAgICApLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHN0YXRpc3RpYzogJ1N1bScsXG4gICAgICAgICAgbGVmdFlBeGlzOiB7XG4gICAgICAgICAgICBtYXg6IDEwMCxcbiAgICAgICAgICAgIG1pbjogOTUsXG4gICAgICAgICAgICBsYWJlbDogJ0F2YWlsYWJpbGl0eScsXG4gICAgICAgICAgICBzaG93VW5pdHM6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmlnaHQ6IFpvbmFsQXZhaWxhYmlsaXR5TWV0cmljcy5jcmVhdGVab25hbFNlcnZpY2VBdmFpbGFiaWxpdHlNZXRyaWNzKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkICsgJyBmYXVsdHMnLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnNlcnZpY2UucGVyaW9kLFxuICAgICAgICAgICAgICBhdmFpbGFiaWxpdHlNZXRyaWNQcm9wczogdGhpcy5jcmVhdGVab25hbEF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzKFxuICAgICAgICAgICAgICAgIHByb3BzLnNlcnZpY2Uub3BlcmF0aW9ucy5maWx0ZXIoKHgpID0+IHguY3JpdGljYWwpLFxuICAgICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgICAgICBpc0NhbmFyeSxcbiAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX0NPVU5ULFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApLFxuICAgICAgICAgIHJpZ2h0WUF4aXM6IHtcbiAgICAgICAgICAgIGxhYmVsOiAnRmF1bHRzJyxcbiAgICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IE1hdGguY2VpbChwcm9wcy5zZXJ2aWNlLmZhdWx0Q291bnRUaHJlc2hvbGQgKiAxLjUpLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmlnaHRBbm5vdGF0aW9uczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb2xvcjogQ29sb3IuUkVELFxuICAgICAgICAgICAgICBsYWJlbDogJ0hpZ2ggc2V2ZXJpdHknLFxuICAgICAgICAgICAgICB2YWx1ZTogcHJvcHMuc2VydmljZS5mYXVsdENvdW50VGhyZXNob2xkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHdpZGdldHM7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZW5lcmF0ZUxhdGVuY3lNZXRyaWNXaWRnZXRzKFxuICAgIHByb3BzOiBTZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZFByb3BzLFxuICAgIGlzQ2FuYXJ5OiBib29sZWFuLFxuICAgIGF2YWlsYWJpbGl0eVpvbmVJZHM6IHN0cmluZ1tdLFxuICApOiBJV2lkZ2V0W10ge1xuICAgIGxldCB3aWRnZXRzOiBJV2lkZ2V0W10gPSBbXTtcblxuICAgIHdpZGdldHMucHVzaChcbiAgICAgIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgIGhlaWdodDogNixcbiAgICAgICAgd2lkdGg6IDI0LFxuICAgICAgICB0aXRsZTogRm4ucmVmKCdBV1M6OlJlZ2lvbicpICsgJyBIaWdoIExhdGVuY3kgQ291bnQnLFxuICAgICAgICByZWdpb246IEZuLnJlZignQVdTOjpSZWdpb24nKSxcbiAgICAgICAgbGVmdDogUmVnaW9uYWxMYXRlbmN5TWV0cmljcy5jcmVhdGVSZWdpb25hbFNlcnZpY2VMYXRlbmN5Q291bnRNZXRyaWNzKHtcbiAgICAgICAgICBsYWJlbDogRm4ucmVmKCdBV1M6OlJlZ2lvbicpLFxuICAgICAgICAgIHBlcmlvZDogcHJvcHMuc2VydmljZS5wZXJpb2QsXG4gICAgICAgICAgbGF0ZW5jeU1ldHJpY1Byb3BzOiB0aGlzLmNyZWF0ZVJlZ2lvbmFsTGF0ZW5jeU1ldHJpY1Byb3BzKFxuICAgICAgICAgICAgcHJvcHMuc2VydmljZS5vcGVyYXRpb25zLmZpbHRlcigoeCkgPT4geC5jcml0aWNhbCksXG4gICAgICAgICAgICBpc0NhbmFyeSxcbiAgICAgICAgICAgIExhdGVuY3lNZXRyaWNUeXBlLlNVQ0NFU1NfTEFURU5DWSxcbiAgICAgICAgICApLFxuICAgICAgICB9KSxcbiAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgbGVmdFlBeGlzOiB7XG4gICAgICAgICAgbWF4OiBwcm9wcy5zZXJ2aWNlLmZhdWx0Q291bnRUaHJlc2hvbGQgKiAxLjUsXG4gICAgICAgICAgbWluOiAwLFxuICAgICAgICAgIGxhYmVsOiAnU3VtJyxcbiAgICAgICAgICBzaG93VW5pdHM6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICBsZWZ0QW5ub3RhdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb2xvcjogQ29sb3IuUkVELFxuICAgICAgICAgICAgbGFiZWw6ICdIaWdoIHNldmVyaXR5JyxcbiAgICAgICAgICAgIHZhbHVlOiBwcm9wcy5zZXJ2aWNlLmZhdWx0Q291bnRUaHJlc2hvbGQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF2YWlsYWJpbGl0eVpvbmVJZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQgPSBhdmFpbGFiaWxpdHlab25lSWRzW2ldO1xuXG4gICAgICB3aWRnZXRzLnB1c2goXG4gICAgICAgIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgICAgaGVpZ2h0OiA2LFxuICAgICAgICAgIHdpZHRoOiA4LFxuICAgICAgICAgIHRpdGxlOiBhdmFpbGFiaWxpdHlab25lSWQgKyAnIEhpZ2ggTGF0ZW5jeSBDb3VudCcsXG4gICAgICAgICAgcmVnaW9uOiBGbi5yZWYoJ0FXUzo6UmVnaW9uJyksXG4gICAgICAgICAgbGVmdDogWm9uYWxMYXRlbmN5TWV0cmljcy5jcmVhdGVab25hbFNlcnZpY2VMYXRlbmN5TWV0cmljcyh7XG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5zZXJ2aWNlLnBlcmlvZCxcbiAgICAgICAgICAgIGxhdGVuY3lNZXRyaWNQcm9wczogdGhpcy5jcmVhdGVab25hbExhdGVuY3lNZXRyaWNQcm9wcyhcbiAgICAgICAgICAgICAgcHJvcHMuc2VydmljZS5vcGVyYXRpb25zLmZpbHRlcigoeCkgPT4geC5jcml0aWNhbCksXG4gICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgICAgaXNDYW5hcnksXG4gICAgICAgICAgICAgIExhdGVuY3lNZXRyaWNUeXBlLlNVQ0NFU1NfTEFURU5DWSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSksXG4gICAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICAgIG1heDogcHJvcHMuc2VydmljZS5mYXVsdENvdW50VGhyZXNob2xkICogMS41LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbGFiZWw6ICdTdW0nLFxuICAgICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxlZnRBbm5vdGF0aW9uczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb2xvcjogQ29sb3IuUkVELFxuICAgICAgICAgICAgICBsYWJlbDogJ0hpZ2ggc2V2ZXJpdHknLFxuICAgICAgICAgICAgICB2YWx1ZTogcHJvcHMuc2VydmljZS5mYXVsdENvdW50VGhyZXNob2xkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHdpZGdldHM7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjcmVhdGVSZWdpb25hbEF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzKFxuICAgIGNyaXRpY2FsT3BlcmF0aW9uczogSU9wZXJhdGlvbltdLFxuICAgIGlzQ2FuYXJ5OiBib29sZWFuLFxuICAgIG1ldHJpY1R5cGU6IEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUsXG4gICk6IEF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzW10ge1xuICAgIHJldHVybiBjcml0aWNhbE9wZXJhdGlvbnNcbiAgICAgIC5yZWR1Y2UoKGZpbHRlcmVkLCB2YWx1ZSkgPT4ge1xuICAgICAgICBpZiAoaXNDYW5hcnkgJiYgdmFsdWUuY2FuYXJ5TWV0cmljRGV0YWlscykge1xuICAgICAgICAgIGZpbHRlcmVkLnB1c2goXG4gICAgICAgICAgICB2YWx1ZS5jYW5hcnlNZXRyaWNEZXRhaWxzLmNhbmFyeUF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHMsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmICghaXNDYW5hcnkpIHtcbiAgICAgICAgICBmaWx0ZXJlZC5wdXNoKHZhbHVlLnNlcnZlclNpZGVBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmlsdGVyZWQ7XG4gICAgICB9LCBbXSBhcyBJT3BlcmF0aW9uTWV0cmljRGV0YWlsc1tdKVxuICAgICAgLm1hcCgoeCkgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGxhYmVsOlxuICAgICAgICAgICAgeC5vcGVyYXRpb25OYW1lICsgJyAnICsgbWV0cmljVHlwZS50b1N0cmluZygpLnJlcGxhY2UoJ18nLCAnICcpLFxuICAgICAgICAgIG1ldHJpY0RldGFpbHM6IHgsXG4gICAgICAgICAgbWV0cmljVHlwZTogbWV0cmljVHlwZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgY3JlYXRlUmVnaW9uYWxMYXRlbmN5TWV0cmljUHJvcHMoXG4gICAgY3JpdGljYWxPcGVyYXRpb25zOiBJT3BlcmF0aW9uW10sXG4gICAgaXNDYW5hcnk6IGJvb2xlYW4sXG4gICAgbWV0cmljVHlwZTogTGF0ZW5jeU1ldHJpY1R5cGUsXG4gICk6IExhdGVuY3lNZXRyaWNQcm9wc1tdIHtcbiAgICByZXR1cm4gY3JpdGljYWxPcGVyYXRpb25zXG4gICAgICAucmVkdWNlKChmaWx0ZXJlZCwgdmFsdWUpID0+IHtcbiAgICAgICAgaWYgKGlzQ2FuYXJ5ICYmIHZhbHVlLmNhbmFyeU1ldHJpY0RldGFpbHMpIHtcbiAgICAgICAgICBmaWx0ZXJlZC5wdXNoKHZhbHVlLmNhbmFyeU1ldHJpY0RldGFpbHMuY2FuYXJ5TGF0ZW5jeU1ldHJpY0RldGFpbHMpO1xuICAgICAgICB9IGVsc2UgaWYgKCFpc0NhbmFyeSkge1xuICAgICAgICAgIGZpbHRlcmVkLnB1c2godmFsdWUuc2VydmVyU2lkZUxhdGVuY3lNZXRyaWNEZXRhaWxzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmlsdGVyZWQ7XG4gICAgICB9LCBbXSBhcyBJT3BlcmF0aW9uTWV0cmljRGV0YWlsc1tdKVxuICAgICAgLm1hcCgoeCkgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGxhYmVsOlxuICAgICAgICAgICAgeC5vcGVyYXRpb25OYW1lLFxuICAgICAgICAgIG1ldHJpY0RldGFpbHM6IHgsXG4gICAgICAgICAgbWV0cmljVHlwZTogbWV0cmljVHlwZSxcbiAgICAgICAgICBzdGF0aXN0aWM6ICdUQygnICsgeC5zdWNjZXNzQWxhcm1UaHJlc2hvbGQgKyAnOiknLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjcmVhdGVab25hbEF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzKFxuICAgIGNyaXRpY2FsT3BlcmF0aW9uczogSU9wZXJhdGlvbltdLFxuICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogc3RyaW5nLFxuICAgIGlzQ2FuYXJ5OiBib29sZWFuLFxuICAgIG1ldHJpY1R5cGU6IEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUsXG4gICk6IEF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzW10ge1xuICAgIHJldHVybiBjcml0aWNhbE9wZXJhdGlvbnNcbiAgICAgIC5yZWR1Y2UoKGZpbHRlcmVkLCB2YWx1ZSkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaXNDYW5hcnkgJiZcbiAgICAgICAgICB2YWx1ZS5jYW5hcnlNZXRyaWNEZXRhaWxzICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICB2YWx1ZS5jYW5hcnlNZXRyaWNEZXRhaWxzICE9IG51bGxcbiAgICAgICAgKSB7XG4gICAgICAgICAgZmlsdGVyZWQucHVzaChcbiAgICAgICAgICAgIHZhbHVlLmNhbmFyeU1ldHJpY0RldGFpbHMuY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscyxcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKCFpc0NhbmFyeSkge1xuICAgICAgICAgIGZpbHRlcmVkLnB1c2godmFsdWUuc2VydmVyU2lkZUF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmaWx0ZXJlZDtcbiAgICAgIH0sIFtdIGFzIElPcGVyYXRpb25NZXRyaWNEZXRhaWxzW10pXG4gICAgICAubWFwKCh4KSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbGFiZWw6XG4gICAgICAgICAgICB4Lm9wZXJhdGlvbk5hbWUgKyAnICcgKyBtZXRyaWNUeXBlLnRvU3RyaW5nKCkucmVwbGFjZSgnXycsICcgJyksXG4gICAgICAgICAgbWV0cmljRGV0YWlsczogeCxcbiAgICAgICAgICBtZXRyaWNUeXBlOiBtZXRyaWNUeXBlLFxuICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjcmVhdGVab25hbExhdGVuY3lNZXRyaWNQcm9wcyhcbiAgICBjcml0aWNhbE9wZXJhdGlvbnM6IElPcGVyYXRpb25bXSxcbiAgICBhdmFpbGFiaWxpdHlab25lSWQ6IHN0cmluZyxcbiAgICBpc0NhbmFyeTogYm9vbGVhbixcbiAgICBtZXRyaWNUeXBlOiBMYXRlbmN5TWV0cmljVHlwZSxcbiAgKTogTGF0ZW5jeU1ldHJpY1Byb3BzW10ge1xuICAgIHJldHVybiBjcml0aWNhbE9wZXJhdGlvbnNcbiAgICAgIC5yZWR1Y2UoKGZpbHRlcmVkLCB2YWx1ZSkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaXNDYW5hcnkgJiZcbiAgICAgICAgICB2YWx1ZS5jYW5hcnlNZXRyaWNEZXRhaWxzICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICB2YWx1ZS5jYW5hcnlNZXRyaWNEZXRhaWxzICE9IG51bGxcbiAgICAgICAgKSB7XG4gICAgICAgICAgZmlsdGVyZWQucHVzaCh2YWx1ZS5jYW5hcnlNZXRyaWNEZXRhaWxzLmNhbmFyeUxhdGVuY3lNZXRyaWNEZXRhaWxzKTtcbiAgICAgICAgfSBlbHNlIGlmICghaXNDYW5hcnkpIHtcbiAgICAgICAgICBmaWx0ZXJlZC5wdXNoKHZhbHVlLnNlcnZlclNpZGVMYXRlbmN5TWV0cmljRGV0YWlscyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZpbHRlcmVkO1xuICAgICAgfSwgW10gYXMgSU9wZXJhdGlvbk1ldHJpY0RldGFpbHNbXSlcbiAgICAgIC5tYXAoKHgpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBsYWJlbDpcbiAgICAgICAgICAgIHgub3BlcmF0aW9uTmFtZSxcbiAgICAgICAgICBtZXRyaWNEZXRhaWxzOiB4LFxuICAgICAgICAgIG1ldHJpY1R5cGU6IG1ldHJpY1R5cGUsXG4gICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgc3RhdGlzdGljOiAnVEMoJyArIHguc3VjY2Vzc0FsYXJtVGhyZXNob2xkICsgJzopJyxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2VuZXJhdGVMb2FkQmFsYW5jZXJXaWRnZXRzKFxuICAgIHByb3BzOiBTZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZFByb3BzLFxuICAgIHRpdGxlOiBzdHJpbmcsXG4gICAgYXZhaWxhYmlsaXR5Wm9uZU5hbWVzOiBzdHJpbmdbXSxcbiAgKTogSVdpZGdldFtdIHtcbiAgICBsZXQgYWxiV2lkZ2V0czogSVdpZGdldFtdID0gW107XG5cbiAgICBhbGJXaWRnZXRzLnB1c2gobmV3IFRleHRXaWRnZXQoeyBoZWlnaHQ6IDIsIHdpZHRoOiAyNCwgbWFya2Rvd246IHRpdGxlIH0pKTtcblxuICAgIGxldCBrZXlwcmVmaXggPSBNZXRyaWNzSGVscGVyLm5leHRDaGFyKCk7XG5cbiAgICBsZXQgZmF1bHRSYXRlTWV0cmljczogSU1ldHJpY1tdID0gW107XG4gICAgbGV0IHJlcXVlc3RDb3VudE1ldHJpY3M6IElNZXRyaWNbXSA9IFtdO1xuICAgIGxldCBwcm9jZXNzZWRCeXRlc01ldHJpY3M6IElNZXRyaWNbXSA9IFtdO1xuXG4gICAgYXZhaWxhYmlsaXR5Wm9uZU5hbWVzLmZvckVhY2goKGF2YWlsYWJpbGl0eVpvbmVOYW1lKSA9PiB7XG4gICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkOiBzdHJpbmcgPVxuICAgICAgICBwcm9wcy5hek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lTmFtZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZU5hbWUubGVuZ3RoIC0gMSksXG4gICAgICAgICk7XG5cbiAgICAgIGtleXByZWZpeCA9IE1ldHJpY3NIZWxwZXIubmV4dENoYXIoa2V5cHJlZml4KTtcblxuICAgICAgbGV0IGZhdWx0TWV0cmljOiBJTWV0cmljID0gQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmdldFBlckFaQXZhaWxhYmlsaXR5TWV0cmljKFxuICAgICAgICBwcm9wcy5zZXJ2aWNlLmxvYWRCYWxhbmNlciBhcyBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsXG4gICAgICAgIHtcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lTmFtZSxcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQ6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICBtZXRyaWNUeXBlOiBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX1JBVEUsXG4gICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICBwZXJpb2Q6IHByb3BzLnNlcnZpY2UucGVyaW9kLFxuICAgICAgICAgIGtleXByZWZpeDoga2V5cHJlZml4XG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIGZhdWx0UmF0ZU1ldHJpY3MucHVzaChmYXVsdE1ldHJpYyk7XG5cbiAgICAgIGxldCByZXF1ZXN0Q291bnRNZXRyaWM6IElNZXRyaWMgPSBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3MuZ2V0UGVyQVpBdmFpbGFiaWxpdHlNZXRyaWMoXG4gICAgICAgIHByb3BzLnNlcnZpY2UubG9hZEJhbGFuY2VyIGFzIElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcixcbiAgICAgICAge1xuICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmVOYW1lLFxuICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgIG1ldHJpY1R5cGU6IEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuUkVRVUVTVF9DT1VOVCxcbiAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgIHBlcmlvZDogcHJvcHMuc2VydmljZS5wZXJpb2QsXG4gICAgICAgICAga2V5cHJlZml4OiBrZXlwcmVmaXhcbiAgICAgICAgfVxuICAgICAgKTtcblxuICAgICAgcmVxdWVzdENvdW50TWV0cmljcy5wdXNoKHJlcXVlc3RDb3VudE1ldHJpYyk7XG5cbiAgICAgIGxldCBwcm9jZXNzZWRCeXRlc01ldHJpYzogSU1ldHJpYyA9IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTWV0cmljcy5nZXRQZXJBWlByb2Nlc3NlZEJ5dGVzTWV0cmljKFxuICAgICAgICBwcm9wcy5zZXJ2aWNlLmxvYWRCYWxhbmNlciBhcyBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsXG4gICAgICAgIGF2YWlsYWJpbGl0eVpvbmVOYW1lLFxuICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgIHByb3BzLnNlcnZpY2UucGVyaW9kXG4gICAgICApO1xuXG4gICAgICBwcm9jZXNzZWRCeXRlc01ldHJpY3MucHVzaChwcm9jZXNzZWRCeXRlc01ldHJpYyk7XG4gICAgfSk7XG5cbiAgICBhbGJXaWRnZXRzLnB1c2goXG4gICAgICBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgICBoZWlnaHQ6IDgsXG4gICAgICAgIHdpZHRoOiA4LFxuICAgICAgICB0aXRsZTogRm4uc3ViKCcke0FXUzo6UmVnaW9ufSBGYXVsdCBSYXRlJyksXG4gICAgICAgIHJlZ2lvbjogRm4uc3ViKCcke0FXUzo6UmVnaW9ufScpLFxuICAgICAgICBsZWZ0OiBmYXVsdFJhdGVNZXRyaWNzLFxuICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICBtYXg6IDM1LFxuICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICBsYWJlbDogJ0ZhdWx0IFJhdGUnLFxuICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcblxuICAgIGFsYldpZGdldHMucHVzaChcbiAgICAgIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgIGhlaWdodDogOCxcbiAgICAgICAgd2lkdGg6IDgsXG4gICAgICAgIHRpdGxlOiBGbi5zdWIoJyR7QVdTOjpSZWdpb259IFJlcXVlc3QgQ291bnQnKSxcbiAgICAgICAgcmVnaW9uOiBGbi5zdWIoJyR7QVdTOjpSZWdpb259JyksXG4gICAgICAgIGxlZnQ6IHJlcXVlc3RDb3VudE1ldHJpY3MsXG4gICAgICAgIGxlZnRZQXhpczoge1xuICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICBsYWJlbDogJ1N1bScsXG4gICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICApO1xuXG4gICAgYWxiV2lkZ2V0cy5wdXNoKFxuICAgICAgbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgaGVpZ2h0OiA4LFxuICAgICAgICB3aWR0aDogOCxcbiAgICAgICAgdGl0bGU6IEZuLnN1YignJHtBV1M6OlJlZ2lvbn0gUHJvY2Vzc2VkIEJ5dGVzJyksXG4gICAgICAgIHJlZ2lvbjogRm4uc3ViKCcke0FXUzo6UmVnaW9ufScpLFxuICAgICAgICBsZWZ0OiBwcm9jZXNzZWRCeXRlc01ldHJpY3MsXG4gICAgICAgIGxlZnRZQXhpczoge1xuICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICBzaG93VW5pdHM6IHRydWUsXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcblxuICAgIHJldHVybiBhbGJXaWRnZXRzO1xuICB9XG4gIC8qKlxuICAgKiBUaGUgc2VydmljZSBsZXZlbCBkYXNoYm9hcmRcbiAgICovXG4gIGRhc2hib2FyZDogRGFzaGJvYXJkO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHNjb3BlOiBDb25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogU2VydmljZUF2YWlsYWJpbGl0eUFuZExhdGVuY3lEYXNoYm9hcmRQcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGxldCB0b3BMZXZlbEFnZ3JlZ2F0ZUFsYXJtV2lkZ2V0czogSVdpZGdldFtdID0gW107XG5cbiAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkczogc3RyaW5nW10gPSBwcm9wcy5zZXJ2aWNlLmF2YWlsYWJpbGl0eVpvbmVOYW1lcy5tYXAoXG4gICAgICAoeCkgPT4ge1xuICAgICAgICByZXR1cm4gcHJvcHMuYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoXG4gICAgICAgICAgeC5zdWJzdHJpbmcoeC5sZW5ndGggLSAxKSxcbiAgICAgICAgKTtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIHRvcExldmVsQWdncmVnYXRlQWxhcm1XaWRnZXRzLnB1c2goXG4gICAgICBuZXcgVGV4dFdpZGdldCh7XG4gICAgICAgIGhlaWdodDogMixcbiAgICAgICAgd2lkdGg6IDI0LFxuICAgICAgICBtYXJrZG93bjogJyoqKkF2YWlsYWJpbGl0eSBhbmQgTGF0ZW5jeSBBbGFybXMqKionLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIHRvcExldmVsQWdncmVnYXRlQWxhcm1XaWRnZXRzLnB1c2goXG4gICAgICBuZXcgQWxhcm1TdGF0dXNXaWRnZXQoe1xuICAgICAgICBoZWlnaHQ6IDIsXG4gICAgICAgIHdpZHRoOiAyNCxcbiAgICAgICAgYWxhcm1zOiBbcHJvcHMuYWdncmVnYXRlUmVnaW9uYWxBbGFybV0sXG4gICAgICAgIHRpdGxlOlxuICAgICAgICAgICdDdXN0b21lciBFeHBlcmllbmNlIC0gUmVnaW9uYWwgQWdncmVnYXRlIEltcGFjdCBBbGFybSAobWVhc3VyZXMgZmF1bHQgY291bnQgaW4gYWdncmVnYXRlIGFjcm9zcyBhbGwgY3JpdGljYWwgb3BlcmF0aW9ucyknLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIGxldCBrZXlQcmVmaXg6IHN0cmluZyA9IE1ldHJpY3NIZWxwZXIubmV4dENoYXIoKTtcbiAgICBsZXQgcGVyT3BlcmF0aW9uQVpGYXVsdHNNZXRyaWNzOiBJTWV0cmljW10gPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXZhaWxhYmlsaXR5Wm9uZUlkcy5sZW5ndGg7IGkrKykge1xuICAgICAgbGV0IGNvdW50ZXI6IG51bWJlciA9IDE7XG4gICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkOiBzdHJpbmcgPSBhdmFpbGFiaWxpdHlab25lSWRzW2ldO1xuXG4gICAgICB0b3BMZXZlbEFnZ3JlZ2F0ZUFsYXJtV2lkZ2V0cy5wdXNoKFxuICAgICAgICBuZXcgQWxhcm1TdGF0dXNXaWRnZXQoe1xuICAgICAgICAgIGhlaWdodDogMixcbiAgICAgICAgICB3aWR0aDogOCxcbiAgICAgICAgICBhbGFybXM6IFtwcm9wcy56b25hbEFnZ3JlZ2F0ZUFsYXJtc1tpXV0sXG4gICAgICAgICAgdGl0bGU6XG4gICAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQgK1xuICAgICAgICAgICAgJyBab25hbCBJc29sYXRlZCBJbXBhY3QgQWxhcm0gKGFueSBjcml0aWNhbCBvcGVyYXRpb24gaW4gdGhpcyBBWiBzaG93cyBpbXBhY3QgZnJvbSBzZXJ2ZXItc2lkZSBvciBjYW5hcnkpJyxcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuXG4gICAgICBwcm9wcy5zZXJ2aWNlLm9wZXJhdGlvbnNcbiAgICAgICAgLmZpbHRlcigoeCkgPT4geC5jcml0aWNhbCA9PSB0cnVlKVxuICAgICAgICAuZm9yRWFjaCgoeCkgPT4ge1xuICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlQcmVmaXh9JHtjb3VudGVyKyt9YF0gPVxuICAgICAgICAgICAgWm9uYWxBdmFpbGFiaWxpdHlNZXRyaWNzLmNyZWF0ZVpvbmFsQXZhaWxhYmlsaXR5TWV0cmljKHtcbiAgICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgIG1ldHJpY0RldGFpbHM6IHguc2VydmVyU2lkZUF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHMsXG4gICAgICAgICAgICAgIGxhYmVsOlxuICAgICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZCArICcgJyArIHgub3BlcmF0aW9uTmFtZSArICcgZmF1bHQgY291bnQnLFxuICAgICAgICAgICAgICBtZXRyaWNUeXBlOiBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX0NPVU5ULFxuICAgICAgICAgICAgICBrZXlQcmVmaXg6IGtleVByZWZpeCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgbGV0IHpvbmFsRmF1bHRDb3VudDogSU1ldHJpYyA9IG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgIGV4cHJlc3Npb246IE9iamVjdC5rZXlzKHVzaW5nTWV0cmljcykuam9pbignKycpLFxuICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkICsgJyBmYXVsdCBjb3VudCcsXG4gICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICBwZXJpb2Q6IHByb3BzLnNlcnZpY2UucGVyaW9kXG4gICAgICB9KTtcblxuICAgICAgcGVyT3BlcmF0aW9uQVpGYXVsdHNNZXRyaWNzLnB1c2goem9uYWxGYXVsdENvdW50KTtcbiAgICAgIGtleVByZWZpeCA9IE1ldHJpY3NIZWxwZXIubmV4dENoYXIoa2V5UHJlZml4KTtcbiAgICB9XG5cbiAgICBsZXQgYXpDb250cmlidXRvcldpZGdldHM6IElXaWRnZXRbXSA9IFtcbiAgICAgIG5ldyBUZXh0V2lkZ2V0KHtcbiAgICAgICAgaGVpZ2h0OiAyLFxuICAgICAgICB3aWR0aDogMjQsXG4gICAgICAgIG1hcmtkb3duOiAnKipBWiBDb250cmlidXRvcnMgVG8gRmF1bHRzKionLFxuICAgICAgfSksXG4gICAgICBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgICBoZWlnaHQ6IDYsXG4gICAgICAgIHdpZHRoOiAyNCxcbiAgICAgICAgdGl0bGU6ICdBWiBGYXVsdCBDb3VudCcsXG4gICAgICAgIHBlcmlvZDogcHJvcHMuc2VydmljZS5wZXJpb2QsXG4gICAgICAgIGxlZnQ6IHBlck9wZXJhdGlvbkFaRmF1bHRzTWV0cmljcyxcbiAgICAgIH0pLFxuICAgIF07XG5cbiAgICB0b3BMZXZlbEFnZ3JlZ2F0ZUFsYXJtV2lkZ2V0cy5jb25jYXQoXG4gICAgICBTZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZC5nZW5lcmF0ZVRQU1dpZGdldHMoXG4gICAgICAgIHByb3BzLFxuICAgICAgICBhdmFpbGFiaWxpdHlab25lSWRzLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgdGhpcy5kYXNoYm9hcmQgPSBuZXcgRGFzaGJvYXJkKHRoaXMsICdUb3BMZXZlbERhc2hib2FyZCcsIHtcbiAgICAgIGRhc2hib2FyZE5hbWU6XG4gICAgICAgIHByb3BzLnNlcnZpY2Uuc2VydmljZU5hbWUudG9Mb3dlckNhc2UoKSArXG4gICAgICAgIEZuLnN1YignLWF2YWlsYWJpbGl0eS1hbmQtbGF0ZW5jeS0ke0FXUzo6UmVnaW9ufScpLFxuICAgICAgZGVmYXVsdEludGVydmFsOiBwcm9wcy5pbnRlcnZhbCxcbiAgICAgIHBlcmlvZE92ZXJyaWRlOiBQZXJpb2RPdmVycmlkZS5BVVRPLFxuICAgICAgd2lkZ2V0czogW1xuICAgICAgICB0b3BMZXZlbEFnZ3JlZ2F0ZUFsYXJtV2lkZ2V0cyxcbiAgICAgICAgYXpDb250cmlidXRvcldpZGdldHMsXG4gICAgICAgIFNlcnZpY2VBdmFpbGFiaWxpdHlBbmRMYXRlbmN5RGFzaGJvYXJkLmdlbmVyYXRlU2VydmVyU2lkZUFuZENhbmFyeUF2YWlsYWJpbGl0eVdpZGdldHMoXG4gICAgICAgICAgcHJvcHMsXG4gICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkcyxcbiAgICAgICAgKSxcbiAgICAgICAgU2VydmljZUF2YWlsYWJpbGl0eUFuZExhdGVuY3lEYXNoYm9hcmQuZ2VuZXJhdGVTZXJ2ZXJTaWRlQW5kQ2FuYXJ5TGF0ZW5jeVdpZGdldHMoXG4gICAgICAgICAgcHJvcHMsXG4gICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkcyxcbiAgICAgICAgKSxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICBsZXQgbGI6IENmbkxvYWRCYWxhbmNlciA9IHByb3BzLnNlcnZpY2UubG9hZEJhbGFuY2VyPy5ub2RlXG4gICAgICAuZGVmYXVsdENoaWxkIGFzIENmbkxvYWRCYWxhbmNlcjtcblxuICAgIGlmIChsYiAhPT0gdW5kZWZpbmVkICYmIGxiICE9IG51bGwgJiYgbGIudHlwZSA9PSAnYXBwbGljYXRpb24nKSB7XG4gICAgICB0aGlzLmRhc2hib2FyZC5hZGRXaWRnZXRzKFxuICAgICAgICAuLi5TZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZC5nZW5lcmF0ZUxvYWRCYWxhbmNlcldpZGdldHMoXG4gICAgICAgICAgcHJvcHMsXG4gICAgICAgICAgJyoqQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlciBNZXRyaWNzKionLFxuICAgICAgICAgIHByb3BzLnNlcnZpY2UuYXZhaWxhYmlsaXR5Wm9uZU5hbWVzLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
494
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VydmljZUF2YWlsYWJpbGl0eUFuZExhdGVuY3lEYXNoYm9hcmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGFzaGJvYXJkcy9TZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxRUFBcUU7QUFDckUsc0NBQXNDO0FBQ3RDLDZDQUFrQztBQUNsQywrREFXb0M7QUFNcEMsMkNBQXVDO0FBR3ZDLDhGQUEyRjtBQUUzRixnRkFBNkU7QUFDN0Usc0VBQW1FO0FBQ25FLDhEQUEyRDtBQUMzRCw0RkFBeUY7QUFFekY7O0dBRUc7QUFDSCxNQUFhLHNDQUNYLFNBQVEsc0JBQVM7SUFHVCxNQUFNLENBQUMsdUJBQXVCLENBQ3BDLFNBQW9CLEVBQ3BCLEtBQWtEO1FBR2xELElBQUksaUJBQWlCLEdBQWEsS0FBSyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQztRQUN0RSxJQUFJLGtCQUFrQixHQUFrQixLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLENBQUM7UUFFbkcsU0FBUyxDQUFDLFVBQVUsQ0FDbEIsSUFBSSwyQkFBVSxDQUFDO1lBQ2IsUUFBUSxFQUFFLDRCQUE0QjtZQUN0QyxVQUFVLEVBQUUscUNBQW9CLENBQUMsV0FBVztZQUM1QyxNQUFNLEVBQUUsQ0FBQztZQUNULEtBQUssRUFBRSxFQUFFO1NBQ1YsQ0FBQyxDQUNILENBQUM7UUFFRixJQUFJLHdCQUF3QixHQUFjLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDLGdCQUF3QixFQUFFLEVBQUU7WUFDM0YsSUFBSSxRQUFRLEdBQVcsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztZQUMvRSxJQUFJLGtCQUFrQixH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S0FBSyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7YUFDdkgsQ0FBQyxFQUNGLEtBQUssQ0FBQyxRQUFRLEVBQ2QsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQ3BCLEtBQUssQ0FBQyxPQUFPLENBQUMsMkJBQTJCLENBQUMsY0FBYyxFQUN4RCxLQUFLLENBQUMsT0FBTyxDQUFDLDJCQUEyQixDQUFDLHFCQUFxQixFQUMvRCxLQUFLLENBQUMsT0FBTyxDQUFDLGdDQUFnQyxDQUFDLG1CQUFtQixDQUNuRSxDQUNGLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBL29CRCx3RkErb0JDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuaW1wb3J0IHsgQXdzIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHtcbiAgQWxhcm1TdGF0dXNXaWRnZXQsXG4gIENvbG9yLFxuICBEYXNoYm9hcmQsXG4gIEdyYXBoV2lkZ2V0LFxuICBJTWV0cmljLFxuICBJV2lkZ2V0LFxuICBNYXRoRXhwcmVzc2lvbixcbiAgUGVyaW9kT3ZlcnJpZGUsXG4gIFRleHRXaWRnZXQsXG4gIFRleHRXaWRnZXRCYWNrZ3JvdW5kLFxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaCc7XG5pbXBvcnQge1xuICBDZm5Mb2FkQmFsYW5jZXIsXG4gIElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcixcbiAgSVRhcmdldEdyb3VwLFxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWxhc3RpY2xvYWRiYWxhbmNpbmd2Mic7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IElTZXJ2aWNlQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeURhc2hib2FyZCB9IGZyb20gJy4vSVNlcnZpY2VBdmFpbGFiaWxpdHlBbmRMYXRlbmN5RGFzaGJvYXJkJztcbmltcG9ydCB7IFNlcnZpY2VBdmFpbGFiaWxpdHlBbmRMYXRlbmN5RGFzaGJvYXJkUHJvcHMgfSBmcm9tICcuL3Byb3BzL1NlcnZpY2VBdmFpbGFiaWxpdHlBbmRMYXRlbmN5RGFzaGJvYXJkUHJvcHMnO1xuaW1wb3J0IHsgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzIH0gZnJvbSAnLi4vbWV0cmljcy9BcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3MnO1xuaW1wb3J0IHsgSU9wZXJhdGlvbiB9IGZyb20gJy4uL3NlcnZpY2VzL0lPcGVyYXRpb24nO1xuaW1wb3J0IHsgQXZhaWxhYmlsaXR5TWV0cmljVHlwZSB9IGZyb20gJy4uL3V0aWxpdGllcy9BdmFpbGFiaWxpdHlNZXRyaWNUeXBlJztcbmltcG9ydCB7IExhdGVuY3lNZXRyaWNUeXBlIH0gZnJvbSAnLi4vdXRpbGl0aWVzL0xhdGVuY3lNZXRyaWNUeXBlJztcbmltcG9ydCB7IE1ldHJpY3NIZWxwZXIgfSBmcm9tICcuLi91dGlsaXRpZXMvTWV0cmljc0hlbHBlcic7XG5pbXBvcnQgeyBBdmFpbGFiaWxpdHlBbmRMYXRlbmN5TWV0cmljcyB9IGZyb20gJy4uL21ldHJpY3MvQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeU1ldHJpY3MnO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBzZXJ2aWNlIGxldmVsIGF2YWlsYWJpbGl0eSBhbmQgbGF0ZW5jeSBkYXNoYm9hcmRcbiAqL1xuZXhwb3J0IGNsYXNzIFNlcnZpY2VBdmFpbGFiaWxpdHlBbmRMYXRlbmN5RGFzaGJvYXJkXG4gIGV4dGVuZHMgQ29uc3RydWN0XG4gIGltcGxlbWVudHMgSVNlcnZpY2VBdmFpbGFiaWxpdHlBbmRMYXRlbmN5RGFzaGJvYXJkIHtcbiBcbiAgcHJpdmF0ZSBzdGF0aWMgY3JlYXRlU2VydmVyU2lkZVdpZGdldHMoXG4gICAgZGFzaGJvYXJkOiBEYXNoYm9hcmQsXG4gICAgcHJvcHM6IFNlcnZpY2VBdmFpbGFiaWxpdHlBbmRMYXRlbmN5RGFzaGJvYXJkUHJvcHNcbiAgKTogdm9pZCB7XG4gIFxuICAgIGxldCBhdmFpbGFiaWxpdHlab25lczogc3RyaW5nW10gPSBwcm9wcy5zZXJ2aWNlLmF2YWlsYWJpbGl0eVpvbmVOYW1lcztcbiAgICBsZXQgY3JpdGljYWxPcGVyYXRpb25zOiBJT3BlcmF0aW9uW10gPSAgcHJvcHMuc2VydmljZS5vcGVyYXRpb25zLmZpbHRlcigoeCkgPT4geC5jcml0aWNhbCA9PSB0cnVlKTtcbiAgICAgXG4gICAgZGFzaGJvYXJkLmFkZFdpZGdldHMoXG4gICAgICBuZXcgVGV4dFdpZGdldCh7XG4gICAgICAgIG1hcmtkb3duOiBcIiMjICoqU2VydmVyLXNpZGUgTWV0cmljcyoqXCIsXG4gICAgICAgIGJhY2tncm91bmQ6IFRleHRXaWRnZXRCYWNrZ3JvdW5kLlRSQU5TUEFSRU5ULFxuICAgICAgICBoZWlnaHQ6IDEsXG4gICAgICAgIHdpZHRoOiAyNFxuICAgICAgfSlcbiAgICApO1xuXG4gICAgbGV0IHpvbmFsQXZhaWxhYmlsaXR5V2lkZ2V0czogSVdpZGdldFtdID0gYXZhaWxhYmlsaXR5Wm9uZXMubWFwKChhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcpID0+IHtcbiAgICAgIGxldCBhekxldHRlcjogc3RyaW5nID0gYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcbiAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQ6IHN0cmluZyA9IHByb3BzLmF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcblxuICAgICAgbGV0IGNyaXRpY2FsT3BlcmF0aW9uc1pvbmFsTWV0cmljczogSU1ldHJpY1tdID0gY3JpdGljYWxPcGVyYXRpb25zLm1hcCgob3BlcmF0aW9uOiBJT3BlcmF0aW9uLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIHJldHVybiBBdmFpbGFiaWxpdHlBbmRMYXRlbmN5TWV0cmljcy5jcmVhdGVab25hbEF2YWlsYWJpbGl0eU1ldHJpYyh7XG4gICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICBsYWJlbDogb3BlcmF0aW9uLm9wZXJhdGlvbk5hbWUgKyBcIiAoYXZnOiAke0FWR30gIG1pbjogJHtNSU59KVwiLFxuICAgICAgICAgIG1ldHJpY0RldGFpbHM6IG9wZXJhdGlvbi5zZXJ2ZXJTaWRlQXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscyxcbiAgICAgICAgICBtZXRyaWNUeXBlOiBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfUkFURSxcbiAgICAgICAgICBjb2xvcjogTWV0cmljc0hlbHBlci5jb2xvcnNbaW5kZXhdXG4gICAgICAgIH0sXG4gICAgICAgIG9wZXJhdGlvbi5zZXJ2ZXJTaWRlQXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscy5tZXRyaWNEaW1lbnNpb25zLnpvbmFsRGltZW5zaW9ucyhcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgQXdzLlJFR0lPTlxuICAgICAgICApKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICBoZWlnaHQ6IDgsXG4gICAgICAgICAgd2lkdGg6IDYsXG4gICAgICAgICAgdGl0bGU6IGBBdmFpbGFiaWxpdHkgLSAke2F2YWlsYWJpbGl0eVpvbmVJZH1gLFxuICAgICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgICBsZWZ0OiBjcml0aWNhbE9wZXJhdGlvbnNab25hbE1ldHJpY3MsXG4gICAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICAgIG1heDogMTAwLFxuICAgICAgICAgICAgbWluOiA5NSxcbiAgICAgICAgICAgIGxhYmVsOiAnUGVyY2VudCcsXG4gICAgICAgICAgICBzaG93VW5pdHM6IGZhbHNlLFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKVxuICAgIH0pO1xuXG4gICAgbGV0IHpvbmFsRmF1bHRDb3VudFdpZGdldHM6IElXaWRnZXRbXSA9IGF2YWlsYWJpbGl0eVpvbmVzLm1hcCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nKSA9PiB7XG4gICAgICBsZXQgYXpMZXR0ZXI6IHN0cmluZyA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkOiBzdHJpbmcgPSBwcm9wcy5hek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG5cbiAgICAgIGxldCBjcml0aWNhbE9wZXJhdGlvbnNab25hbE1ldHJpY3M6IElNZXRyaWNbXSA9IGNyaXRpY2FsT3BlcmF0aW9ucy5tYXAoKG9wZXJhdGlvbjogSU9wZXJhdGlvbiwgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICByZXR1cm4gQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeU1ldHJpY3MuY3JlYXRlWm9uYWxBdmFpbGFiaWxpdHlNZXRyaWMoe1xuICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgbGFiZWw6IG9wZXJhdGlvbi5vcGVyYXRpb25OYW1lICsgXCIgKGF2ZzogJHtBVkd9ICBtYXg6ICR7TUFYfSlcIixcbiAgICAgICAgICBtZXRyaWNEZXRhaWxzOiBvcGVyYXRpb24uc2VydmVyU2lkZUF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHMsXG4gICAgICAgICAgbWV0cmljVHlwZTogQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5GQVVMVF9DT1VOVCxcbiAgICAgICAgICBjb2xvcjogTWV0cmljc0hlbHBlci5jb2xvcnNbaW5kZXhdXG4gICAgICAgIH0sXG4gICAgICAgIG9wZXJhdGlvbi5zZXJ2ZXJTaWRlQXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscy5tZXRyaWNEaW1lbnNpb25zLnpvbmFsRGltZW5zaW9ucyhcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgQXdzLlJFR0lPTlxuICAgICAgICApKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICBoZWlnaHQ6IDgsXG4gICAgICAgICAgd2lkdGg6IDYsXG4gICAgICAgICAgdGl0bGU6IGBGYXVsdCBDb3VudCAtICR7YXZhaWxhYmlsaXR5Wm9uZUlkfSBgLFxuICAgICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgICBsZWZ0OiBjcml0aWNhbE9wZXJhdGlvbnNab25hbE1ldHJpY3MsXG4gICAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIGxhYmVsOiAnQ291bnQnLFxuICAgICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIClcbiAgICB9KTtcblxuICAgIGxldCBwZXJBWldpZGdldFdpdGhQZXJPcGVyYXRpb25MYXRlbmN5OiBJV2lkZ2V0W10gPSBhdmFpbGFiaWxpdHlab25lcy5tYXAoKGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZykgPT4ge1xuICAgICAgbGV0IGF6TGV0dGVyOiBzdHJpbmcgPSBhdmFpbGFiaWxpdHlab25lLnN1YnN0cmluZyhhdmFpbGFiaWxpdHlab25lLmxlbmd0aCAtIDEpO1xuICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZDogc3RyaW5nID0gcHJvcHMuYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuXG4gICAgICBsZXQgY3JpdGljYWxPcGVyYXRpb25zWm9uYWxNZXRyaWNzOiBJTWV0cmljW10gPSBjcml0aWNhbE9wZXJhdGlvbnMubWFwKChvcGVyYXRpb246IElPcGVyYXRpb24sIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgcmV0dXJuIEF2YWlsYWJpbGl0eUFuZExhdGVuY3lNZXRyaWNzLmNyZWF0ZVpvbmFsTGF0ZW5jeUNvdW50TWV0cmljKHtcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQ6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgIGxhYmVsOiBgJHtvcGVyYXRpb24ub3BlcmF0aW9uTmFtZX0gKCR7b3BlcmF0aW9uLnNlcnZlclNpZGVMYXRlbmN5TWV0cmljRGV0YWlscy5hbGFybVN0YXRpc3RpY30pYCArIFwiIChhdmc6ICR7QVZHfSAgbWF4OiAke01BWH0pXCIsXG4gICAgICAgICAgbWV0cmljRGV0YWlsczogb3BlcmF0aW9uLnNlcnZlclNpZGVMYXRlbmN5TWV0cmljRGV0YWlscyxcbiAgICAgICAgICBtZXRyaWNUeXBlOiBMYXRlbmN5TWV0cmljVHlwZS5TVUNDRVNTX0xBVEVOQ1ksXG4gICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XSxcbiAgICAgICAgICBzdGF0aXN0aWM6IG9wZXJhdGlvbi5zZXJ2ZXJTaWRlTGF0ZW5jeU1ldHJpY0RldGFpbHMuYWxhcm1TdGF0aXN0aWNcbiAgICAgICAgfSxcbiAgICAgICAgb3BlcmF0aW9uLnNlcnZlclNpZGVMYXRlbmN5TWV0cmljRGV0YWlscy5tZXRyaWNEaW1lbnNpb25zLnpvbmFsRGltZW5zaW9ucyhcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgQXdzLlJFR0lPTlxuICAgICAgICApKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICBoZWlnaHQ6IDYsXG4gICAgICAgICAgd2lkdGg6IDgsXG4gICAgICAgICAgdGl0bGU6IGBMYXRlbmN5IC0gJHthdmFpbGFiaWxpdHlab25lSWR9YCxcbiAgICAgICAgICByZWdpb246IEF3cy5SRUdJT04sXG4gICAgICAgICAgbGVmdDogY3JpdGljYWxPcGVyYXRpb25zWm9uYWxNZXRyaWNzLFxuICAgICAgICAgIGxlZnRZQXhpczoge1xuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbGFiZWw6ICdNaWxsaXNlY29uZHMnLFxuICAgICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIClcbiAgICB9KTtcblxuICAgIGxldCBwZXJBWldpZGdldFdpdGhQZXJPcGVyYXRpb25IaWdoTGF0ZW5jeUNvdW50OiBJV2lkZ2V0W10gPSBhdmFpbGFiaWxpdHlab25lcy5tYXAoKGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZykgPT4ge1xuICAgICAgbGV0IGF6TGV0dGVyOiBzdHJpbmcgPSBhdmFpbGFiaWxpdHlab25lLnN1YnN0cmluZyhhdmFpbGFiaWxpdHlab25lLmxlbmd0aCAtIDEpO1xuICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZDogc3RyaW5nID0gcHJvcHMuYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuXG4gICAgICBsZXQgY3JpdGljYWxPcGVyYXRpb25zWm9uYWxNZXRyaWNzOiBJTWV0cmljW10gPSBjcml0aWNhbE9wZXJhdGlvbnMubWFwKChvcGVyYXRpb246IElPcGVyYXRpb24sIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgcmV0dXJuIEF2YWlsYWJpbGl0eUFuZExhdGVuY3lNZXRyaWNzLmNyZWF0ZVpvbmFsTGF0ZW5jeUNvdW50TWV0cmljKHtcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQ6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgIGxhYmVsOiBvcGVyYXRpb24ub3BlcmF0aW9uTmFtZSArIFwiIChhdmc6ICR7QVZHfSAgbWF4OiAke01BWH0pXCIsXG4gICAgICAgICAgbWV0cmljRGV0YWlsczogb3BlcmF0aW9uLnNlcnZlclNpZGVMYXRlbmN5TWV0cmljRGV0YWlscyxcbiAgICAgICAgICBtZXRyaWNUeXBlOiBMYXRlbmN5TWV0cmljVHlwZS5TVUNDRVNTX0xBVEVOQ1ksXG4gICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XSxcbiAgICAgICAgICBzdGF0aXN0aWM6IGBUQygke01ldHJpY3NIZWxwZXIuY29udmVydER1cmF0aW9uQnlVbml0KG9wZXJhdGlvbi5zZXJ2ZXJTaWRlTGF0ZW5jeU1ldHJpY0RldGFpbHMuc3VjY2Vzc0FsYXJtVGhyZXNob2xkLCBvcGVyYXRpb24uc2VydmVyU2lkZUxhdGVuY3lNZXRyaWNEZXRhaWxzLnVuaXQpfTopYCxcbiAgICAgICAgfSxcbiAgICAgICAgb3BlcmF0aW9uLnNlcnZlclNpZGVMYXRlbmN5TWV0cmljRGV0YWlscy5tZXRyaWNEaW1lbnNpb25zLnpvbmFsRGltZW5zaW9ucyhcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgQXdzLlJFR0lPTlxuICAgICAgICApKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICBoZWlnaHQ6IDYsXG4gICAgICAgICAgd2lkdGg6IDgsXG4gICAgICAgICAgdGl0bGU6IGBIaWdoIExhdGVuY3kgQ291bnQgLSAke2F2YWlsYWJpbGl0eVpvbmVJZH1gLFxuICAgICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgICBsZWZ0OiBjcml0aWNhbE9wZXJhdGlvbnNab25hbE1ldHJpY3MsXG4gICAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIGxhYmVsOiAnQ291bnQnLFxuICAgICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIClcbiAgICB9KTtcblxuICAgIGRhc2hib2FyZC5hZGRXaWRnZXRzKFxuXG4gICAgICAuLi56b25hbEF2YWlsYWJpbGl0eVdpZGdldHMsXG5cbiAgICAgIC8vIFNlcnZlci1zaWRlIHBlciBBWiByZXF1ZXN0IGNvdW50XG4gICAgICBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgICBoZWlnaHQ6IDgsXG4gICAgICAgIHdpZHRoOiA2LFxuICAgICAgICB0aXRsZTogJ1JlcXVlc3QgQ291bnQnLFxuICAgICAgICByZWdpb246IEF3cy5SRUdJT04sXG4gICAgICAgIGxlZnQ6IGF2YWlsYWJpbGl0eVpvbmVzLm1hcCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgbGV0IGF6TGV0dGVyOiBzdHJpbmcgPSBhdmFpbGFiaWxpdHlab25lLnN1YnN0cmluZyhhdmFpbGFiaWxpdHlab25lLmxlbmd0aCAtIDEpO1xuICAgICAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQ6IHN0cmluZyA9IHByb3BzLmF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTsgICAgICBcbiAgICBcbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuICAgIFxuICAgICAgICAgIGNyaXRpY2FsT3BlcmF0aW9ucy5mb3JFYWNoKChvcGVyYXRpb246IElPcGVyYXRpb24pID0+IHtcbiAgICAgICAgICAgICAgXG4gICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7YXpMZXR0ZXJ9XyR7b3BlcmF0aW9uLm9wZXJhdGlvbk5hbWV9YF0gPVxuICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlBbmRMYXRlbmN5TWV0cmljcy5jcmVhdGVab25hbEF2YWlsYWJpbGl0eU1ldHJpYyh7XG4gICAgICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgICAgbWV0cmljRGV0YWlsczogb3BlcmF0aW9uLnNlcnZlclNpZGVBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgICAgbWV0cmljVHlwZTogQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5SRVFVRVNUX0NPVU5ULFxuICAgICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmVcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgb3BlcmF0aW9uLnNlcnZlclNpZGVBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzLm1ldHJpY0RpbWVuc2lvbnMuem9uYWxEaW1lbnNpb25zKFxuICAgICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgICAgICBBd3MuUkVHSU9OXG4gICAgICAgICAgICAgICkpO1xuICAgICAgICAgIH0pO1xuICAgIFxuICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgZXhwcmVzc2lvbjogT2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKCcrJyksXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnNlcnZpY2UucGVyaW9kLFxuICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgbGVmdFlBeGlzOiB7XG4gICAgICAgICAgbWluOiAwLFxuICAgICAgICAgIGxhYmVsOiAnQ291bnQnLFxuICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgIH1cbiAgICAgIH0pLFxuXG4gICAgICAvLyBTZXJ2ZXItc2lkZSBwZXIgQVogZmF1bHQgY291bnRcbiAgICAgIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgIGhlaWdodDogOCxcbiAgICAgICAgd2lkdGg6IDYsXG4gICAgICAgIHRpdGxlOiAnRmF1bHQgQ291bnQnLFxuICAgICAgICByZWdpb246IEF3cy5SRUdJT04sXG4gICAgICAgIGxlZnQ6IGF2YWlsYWJpbGl0eVpvbmVzLm1hcCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgbGV0IGF6TGV0dGVyOiBzdHJpbmcgPSBhdmFpbGFiaWxpdHlab25lLnN1YnN0cmluZyhhdmFpbGFiaWxpdHlab25lLmxlbmd0aCAtIDEpO1xuICAgICAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQ6IHN0cmluZyA9IHByb3BzLmF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTsgICAgICBcbiAgICBcbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuICAgIFxuICAgICAgICAgIGNyaXRpY2FsT3BlcmF0aW9ucy5mb3JFYWNoKChvcGVyYXRpb246IElPcGVyYXRpb24pID0+IHtcbiAgICAgICAgICAgICAgXG4gICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7YXpMZXR0ZXJ9XyR7b3BlcmF0aW9uLm9wZXJhdGlvbk5hbWV9YF0gPVxuICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlBbmRMYXRlbmN5TWV0cmljcy5jcmVhdGVab25hbEF2YWlsYWJpbGl0eU1ldHJpYyh7XG4gICAgICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgICAgbWV0cmljRGV0YWlsczogb3BlcmF0aW9uLnNlcnZlclNpZGVBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgICAgbWV0cmljVHlwZTogQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5GQVVMVF9DT1VOVCxcbiAgICAgICAgICAgICAgICBhdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIG9wZXJhdGlvbi5zZXJ2ZXJTaWRlQXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscy5tZXRyaWNEaW1lbnNpb25zLnpvbmFsRGltZW5zaW9ucyhcbiAgICAgICAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgICAgQXdzLlJFR0lPTlxuICAgICAgICAgICAgICApKTtcbiAgICAgICAgICB9KTtcbiAgICBcbiAgICAgICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgIGV4cHJlc3Npb246IE9iamVjdC5rZXlzKHVzaW5nTWV0cmljcykuam9pbignKycpLFxuICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCArIFwiIChhdmc6ICR7QVZHfSAgbWF4OiAke01BWH0pXCIsXG4gICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMuc2VydmljZS5wZXJpb2QsXG4gICAgICAgICAgICBjb2xvcjogTWV0cmljc0hlbHBlci5jb2xvcnNbaW5kZXhdXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgICBzdGF0aXN0aWM6ICdTdW0nLFxuICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgbGFiZWw6ICdDb3VudCcsXG4gICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAgbGVmdEFubm90YXRpb25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFsdWU6IHByb3BzLnNlcnZpY2UuZmF1bHRDb3VudFRocmVzaG9sZCxcbiAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICBjb2xvcjogQ29sb3IuUkVELFxuICAgICAgICAgICAgbGFiZWw6ICdIaWdoIFNldmVyaXR5JyxcbiAgICAgICAgICB9LFxuICAgICAgICBdXG4gICAgICB9KSxcbiAgICAgIFxuICAgICAgLi4uem9uYWxGYXVsdENvdW50V2lkZ2V0cyxcbiAgICAgIC4uLnBlckFaV2lkZ2V0V2l0aFBlck9wZXJhdGlvbkxhdGVuY3ksXG4gICAgICAuLi5wZXJBWldpZGdldFdpdGhQZXJPcGVyYXRpb25IaWdoTGF0ZW5jeUNvdW50XG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGNyZWF0ZUNhbmFyeVdpZGdldHMoXG4gICAgZGFzaGJvYXJkOiBEYXNoYm9hcmQsXG4gICAgcHJvcHM6IFNlcnZpY2VBdmFpbGFiaWxpdHlBbmRMYXRlbmN5RGFzaGJvYXJkUHJvcHNcbiAgKTogdm9pZCB7XG4gIFxuICAgIGxldCBhdmFpbGFiaWxpdHlab25lczogc3RyaW5nW10gPSBwcm9wcy5zZXJ2aWNlLmF2YWlsYWJpbGl0eVpvbmVOYW1lcztcbiAgICBsZXQgY3JpdGljYWxPcGVyYXRpb25zOiBJT3BlcmF0aW9uW10gPSAgcHJvcHMuc2VydmljZS5vcGVyYXRpb25zLmZpbHRlcigoeCkgPT4geC5jcml0aWNhbCA9PSB0cnVlKTtcbiAgICAgXG4gICAgZGFzaGJvYXJkLmFkZFdpZGdldHMoXG4gICAgICBuZXcgVGV4dFdpZGdldCh7XG4gICAgICAgIG1hcmtkb3duOiBcIiMjICoqQ2FuYXJ5IE1ldHJpY3MqKlwiLFxuICAgICAgICBiYWNrZ3JvdW5kOiBUZXh0V2lkZ2V0QmFja2dyb3VuZC5UUkFOU1BBUkVOVCxcbiAgICAgICAgaGVpZ2h0OiAxLFxuICAgICAgICB3aWR0aDogMjRcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIGxldCB6b25hbEF2YWlsYWJpbGl0eVdpZGdldHM6IElXaWRnZXRbXSA9IGF2YWlsYWJpbGl0eVpvbmVzLm1hcCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nKSA9PiB7XG4gICAgICBsZXQgYXpMZXR0ZXI6IHN0cmluZyA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkOiBzdHJpbmcgPSBwcm9wcy5hek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG5cbiAgICAgIGxldCBjcml0aWNhbE9wZXJhdGlvbnNab25hbE1ldHJpY3M6IElNZXRyaWNbXSA9IGNyaXRpY2FsT3BlcmF0aW9ucy5tYXAoKG9wZXJhdGlvbjogSU9wZXJhdGlvbiwgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICByZXR1cm4gQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeU1ldHJpY3MuY3JlYXRlWm9uYWxBdmFpbGFiaWxpdHlNZXRyaWMoe1xuICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgbGFiZWw6IG9wZXJhdGlvbi5vcGVyYXRpb25OYW1lICsgXCIgKGF2ZzogJHtBVkd9ICBtaW46ICR7TUlOfSlcIixcbiAgICAgICAgICBtZXRyaWNEZXRhaWxzOiBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscyEuY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscyxcbiAgICAgICAgICBtZXRyaWNUeXBlOiBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfUkFURSxcbiAgICAgICAgICBjb2xvcjogTWV0cmljc0hlbHBlci5jb2xvcnNbaW5kZXhdXG4gICAgICAgIH0sXG4gICAgICAgIG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzIS5jYW5hcnlBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzLm1ldHJpY0RpbWVuc2lvbnMuem9uYWxEaW1lbnNpb25zKFxuICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICBBd3MuUkVHSU9OXG4gICAgICAgICkpO1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgICAgIGhlaWdodDogOCxcbiAgICAgICAgICB3aWR0aDogNixcbiAgICAgICAgICB0aXRsZTogYEF2YWlsYWJpbGl0eSAtICR7YXZhaWxhYmlsaXR5Wm9uZUlkfSBgLFxuICAgICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgICBsZWZ0OiBjcml0aWNhbE9wZXJhdGlvbnNab25hbE1ldHJpY3MsXG4gICAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICAgIG1heDogMTAwLFxuICAgICAgICAgICAgbWluOiA5NSxcbiAgICAgICAgICAgIGxhYmVsOiAnUGVyY2VudCcsXG4gICAgICAgICAgICBzaG93VW5pdHM6IGZhbHNlLFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKVxuICAgIH0pO1xuXG4gICAgbGV0IHpvbmFsRmF1bHRDb3VudFdpZGdldHM6IElXaWRnZXRbXSA9IGF2YWlsYWJpbGl0eVpvbmVzLm1hcCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nKSA9PiB7XG4gICAgICBsZXQgYXpMZXR0ZXI6IHN0cmluZyA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkOiBzdHJpbmcgPSBwcm9wcy5hek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG5cbiAgICAgIGxldCBjcml0aWNhbE9wZXJhdGlvbnNab25hbE1ldHJpY3M6IElNZXRyaWNbXSA9IGNyaXRpY2FsT3BlcmF0aW9ucy5tYXAoKG9wZXJhdGlvbjogSU9wZXJhdGlvbiwgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICByZXR1cm4gQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeU1ldHJpY3MuY3JlYXRlWm9uYWxBdmFpbGFiaWxpdHlNZXRyaWMoe1xuICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgbGFiZWw6IG9wZXJhdGlvbi5vcGVyYXRpb25OYW1lICsgXCIgKGF2ZzogJHtBVkd9ICBtYXg6ICR7TUFYfSlcIixcbiAgICAgICAgICBtZXRyaWNEZXRhaWxzOiBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscyEuY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscyxcbiAgICAgICAgICBtZXRyaWNUeXBlOiBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX0NPVU5ULFxuICAgICAgICAgIGNvbG9yOiBNZXRyaWNzSGVscGVyLmNvbG9yc1tpbmRleF1cbiAgICAgICAgfSxcbiAgICAgICAgb3BlcmF0aW9uLmNhbmFyeU1ldHJpY0RldGFpbHMhLmNhbmFyeUF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHMubWV0cmljRGltZW5zaW9ucy56b25hbERpbWVuc2lvbnMoXG4gICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgIEF3cy5SRUdJT05cbiAgICAgICAgKSk7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgICAgaGVpZ2h0OiA4LFxuICAgICAgICAgIHdpZHRoOiA2LFxuICAgICAgICAgIHRpdGxlOiBgRmF1bHQgQ291bnQgLSAke2F2YWlsYWJpbGl0eVpvbmVJZH1gLFxuICAgICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgICBsZWZ0OiBjcml0aWNhbE9wZXJhdGlvbnNab25hbE1ldHJpY3MsXG4gICAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIGxhYmVsOiAnQ291bnQnLFxuICAgICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIClcbiAgICB9KTtcblxuICAgIGxldCBwZXJBWldpZGdldFdpdGhQZXJPcGVyYXRpb25MYXRlbmN5OiBJV2lkZ2V0W10gPSBhdmFpbGFiaWxpdHlab25lcy5tYXAoKGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZywgKSA9PiB7XG4gICAgICBsZXQgYXpMZXR0ZXI6IHN0cmluZyA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkOiBzdHJpbmcgPSBwcm9wcy5hek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG5cbiAgICAgIGxldCBjcml0aWNhbE9wZXJhdGlvbnNab25hbE1ldHJpY3M6IElNZXRyaWNbXSA9IGNyaXRpY2FsT3BlcmF0aW9ucy5tYXAoKG9wZXJhdGlvbjogSU9wZXJhdGlvbiwgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICByZXR1cm4gQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeU1ldHJpY3MuY3JlYXRlWm9uYWxMYXRlbmN5Q291bnRNZXRyaWMoe1xuICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgbGFiZWw6IGAke29wZXJhdGlvbi5vcGVyYXRpb25OYW1lfSAoJHtvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscyEuY2FuYXJ5TGF0ZW5jeU1ldHJpY0RldGFpbHMuYWxhcm1TdGF0aXN0aWN9KWAgKyBcIiAoYXZnOiAke0FWR30gIG1heDogJHtNQVh9KVwiLFxuICAgICAgICAgIG1ldHJpY0RldGFpbHM6IG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzIS5jYW5hcnlMYXRlbmN5TWV0cmljRGV0YWlscyxcbiAgICAgICAgICBtZXRyaWNUeXBlOiBMYXRlbmN5TWV0cmljVHlwZS5TVUNDRVNTX0xBVEVOQ1ksXG4gICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XSxcbiAgICAgICAgICBzdGF0aXN0aWM6IG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzIS5jYW5hcnlMYXRlbmN5TWV0cmljRGV0YWlscy5hbGFybVN0YXRpc3RpY1xuICAgICAgICB9LFxuICAgICAgICBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscyEuY2FuYXJ5TGF0ZW5jeU1ldHJpY0RldGFpbHMubWV0cmljRGltZW5zaW9ucy56b25hbERpbWVuc2lvbnMoXG4gICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgIEF3cy5SRUdJT05cbiAgICAgICAgKSk7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgICAgaGVpZ2h0OiA2LFxuICAgICAgICAgIHdpZHRoOiA4LFxuICAgICAgICAgIHRpdGxlOiBgTGF0ZW5jeSAtICR7YXZhaWxhYmlsaXR5Wm9uZUlkfWAsXG4gICAgICAgICAgcmVnaW9uOiBBd3MuUkVHSU9OLFxuICAgICAgICAgIGxlZnQ6IGNyaXRpY2FsT3BlcmF0aW9uc1pvbmFsTWV0cmljcyxcbiAgICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIGxhYmVsOiAnTWlsbGlzZWNvbmRzJyxcbiAgICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApXG4gICAgfSk7XG5cbiAgICBsZXQgcGVyQVpXaWRnZXRXaXRoUGVyT3BlcmF0aW9uSGlnaExhdGVuY3lDb3VudDogSVdpZGdldFtdID0gYXZhaWxhYmlsaXR5Wm9uZXMubWFwKChhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcpID0+IHtcbiAgICAgIGxldCBhekxldHRlcjogc3RyaW5nID0gYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcbiAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQ6IHN0cmluZyA9IHByb3BzLmF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcblxuICAgICAgbGV0IGNyaXRpY2FsT3BlcmF0aW9uc1pvbmFsTWV0cmljczogSU1ldHJpY1tdID0gY3JpdGljYWxPcGVyYXRpb25zLm1hcCgob3BlcmF0aW9uOiBJT3BlcmF0aW9uLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIHJldHVybiBBdmFpbGFiaWxpdHlBbmRMYXRlbmN5TWV0cmljcy5jcmVhdGVab25hbExhdGVuY3lDb3VudE1ldHJpYyh7XG4gICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICBsYWJlbDogb3BlcmF0aW9uLm9wZXJhdGlvbk5hbWUgKyBcIiAoYXZnOiAke0FWR30gIG1heDogJHtNQVh9KVwiLFxuICAgICAgICAgIG1ldHJpY0RldGFpbHM6IG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzIS5jYW5hcnlMYXRlbmN5TWV0cmljRGV0YWlscyxcbiAgICAgICAgICBtZXRyaWNUeXBlOiBMYXRlbmN5TWV0cmljVHlwZS5TVUNDRVNTX0xBVEVOQ1ksXG4gICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XSxcbiAgICAgICAgICBzdGF0aXN0aWM6IGBUQygke01ldHJpY3NIZWxwZXIuY29udmVydER1cmF0aW9uQnlVbml0KFxuICAgICAgICAgICAgICBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscyEuY2FuYXJ5TGF0ZW5jeU1ldHJpY0RldGFpbHMuc3VjY2Vzc0FsYXJtVGhyZXNob2xkLFxuICAgICAgICAgICAgICBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscyEuY2FuYXJ5TGF0ZW5jeU1ldHJpY0RldGFpbHMudW5pdCBcbiAgICAgICAgICAgICl9OilgXG4gICAgICAgIH0sXG4gICAgICAgIG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzIS5jYW5hcnlMYXRlbmN5TWV0cmljRGV0YWlscy5tZXRyaWNEaW1lbnNpb25zLnpvbmFsRGltZW5zaW9ucyhcbiAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgQXdzLlJFR0lPTlxuICAgICAgICApKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICBoZWlnaHQ6IDYsXG4gICAgICAgICAgd2lkdGg6IDgsXG4gICAgICAgICAgdGl0bGU6IGBIaWdoIExhdGVuY3kgQ291bnQgLSAke2F2YWlsYWJpbGl0eVpvbmVJZH1gLFxuICAgICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgICBsZWZ0OiBjcml0aWNhbE9wZXJhdGlvbnNab25hbE1ldHJpY3MsXG4gICAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIGxhYmVsOiAnQ291bnQnLFxuICAgICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIClcbiAgICB9KTtcblxuICAgIGRhc2hib2FyZC5hZGRXaWRnZXRzKFxuXG4gICAgICAuLi56b25hbEF2YWlsYWJpbGl0eVdpZGdldHMsXG5cbiAgICAgIC8vIENhbmFyeSBwZXIgQVogcmVxdWVzdCBjb3VudFxuICAgICAgbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgaGVpZ2h0OiA4LFxuICAgICAgICB3aWR0aDogNixcbiAgICAgICAgdGl0bGU6ICdSZXF1ZXN0IENvdW50JyxcbiAgICAgICAgcmVnaW9uOiBBd3MuUkVHSU9OLFxuICAgICAgICBsZWZ0OiBhdmFpbGFiaWxpdHlab25lcy5tYXAoKGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgIGxldCBhekxldHRlcjogc3RyaW5nID0gYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcbiAgICAgICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkOiBzdHJpbmcgPSBwcm9wcy5hek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7ICAgICAgXG4gICAgXG4gICAgICAgICAgbGV0IHVzaW5nTWV0cmljczogeyBba2V5OiBzdHJpbmddOiBJTWV0cmljIH0gPSB7fTtcbiAgICBcbiAgICAgICAgICBjcml0aWNhbE9wZXJhdGlvbnMuZm9yRWFjaCgob3BlcmF0aW9uOiBJT3BlcmF0aW9uKSA9PiB7XG4gICAgICAgICAgICAgIFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2F6TGV0dGVyfV8ke29wZXJhdGlvbi5vcGVyYXRpb25OYW1lfWBdID1cbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeU1ldHJpY3MuY3JlYXRlWm9uYWxBdmFpbGFiaWxpdHlNZXRyaWMoe1xuICAgICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgICAgIG1ldHJpY0RldGFpbHM6IG9wZXJhdGlvbi5jYW5hcnlNZXRyaWNEZXRhaWxzIS5jYW5hcnlBdmFpbGFiaWxpdHlNZXRyaWNEZXRhaWxzLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgICAgbWV0cmljVHlwZTogQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5SRVFVRVNUX0NPVU5ULFxuICAgICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscyEuY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscy5tZXRyaWNEaW1lbnNpb25zLnpvbmFsRGltZW5zaW9ucyhcbiAgICAgICAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgICAgQXdzLlJFR0lPTlxuICAgICAgICAgICAgICApKTtcbiAgICAgICAgICB9KTtcbiAgICBcbiAgICAgICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgIGV4cHJlc3Npb246IE9iamVjdC5rZXlzKHVzaW5nTWV0cmljcykuam9pbignKycpLFxuICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5zZXJ2aWNlLnBlcmlvZCxcbiAgICAgICAgICAgIGNvbG9yOiBNZXRyaWNzSGVscGVyLmNvbG9yc1tpbmRleF1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICAgIHN0YXRpc3RpYzogJ1N1bScsXG4gICAgICAgIGxlZnRZQXhpczoge1xuICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICBsYWJlbDogJ0NvdW50JyxcbiAgICAgICAgICBzaG93VW5pdHM6IGZhbHNlLFxuICAgICAgICB9XG4gICAgICB9KSxcblxuICAgICAgLy8gQ2FuYXJ5IHBlciBBWiBmYXVsdCBjb3VudFxuICAgICAgbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgaGVpZ2h0OiA4LFxuICAgICAgICB3aWR0aDogNixcbiAgICAgICAgdGl0bGU6ICdGYXVsdCBDb3VudCcsXG4gICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgbGVmdDogYXZhaWxhYmlsaXR5Wm9uZXMubWFwKChhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICBsZXQgYXpMZXR0ZXI6IHN0cmluZyA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZDogc3RyaW5nID0gcHJvcHMuYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpOyAgICAgIFxuICAgIFxuICAgICAgICAgIGxldCB1c2luZ01ldHJpY3M6IHsgW2tleTogc3RyaW5nXTogSU1ldHJpYyB9ID0ge307XG4gICAgXG4gICAgICAgICAgY3JpdGljYWxPcGVyYXRpb25zLmZvckVhY2goKG9wZXJhdGlvbjogSU9wZXJhdGlvbikgPT4ge1xuICAgICAgICAgICAgICBcbiAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHthekxldHRlcn1fJHtvcGVyYXRpb24ub3BlcmF0aW9uTmFtZX1gXSA9XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eUFuZExhdGVuY3lNZXRyaWNzLmNyZWF0ZVpvbmFsQXZhaWxhYmlsaXR5TWV0cmljKHtcbiAgICAgICAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQ6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgICAgICBtZXRyaWNEZXRhaWxzOiBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscyEuY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscyxcbiAgICAgICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgICAgIG1ldHJpY1R5cGU6IEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuRkFVTFRfQ09VTlQsXG4gICAgICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZVxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBvcGVyYXRpb24uY2FuYXJ5TWV0cmljRGV0YWlscyEuY2FuYXJ5QXZhaWxhYmlsaXR5TWV0cmljRGV0YWlscy5tZXRyaWNEaW1lbnNpb25zLnpvbmFsRGltZW5zaW9ucyhcbiAgICAgICAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgICAgQXdzLlJFR0lPTlxuICAgICAgICAgICAgICApKTtcbiAgICAgICAgICB9KTtcbiAgICBcbiAgICAgICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgIGV4cHJlc3Npb246IE9iamVjdC5rZXlzKHVzaW5nTWV0cmljcykuam9pbignKycpLFxuICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5zZXJ2aWNlLnBlcmlvZCxcbiAgICAgICAgICAgIGNvbG9yOiBNZXRyaWNzSGVscGVyLmNvbG9yc1tpbmRleF1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICAgIHN0YXRpc3RpYzogJ1N1bScsXG4gICAgICAgIGxlZnRZQXhpczoge1xuICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICBsYWJlbDogJ0NvdW50JyxcbiAgICAgICAgICBzaG93VW5pdHM6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICBsZWZ0QW5ub3RhdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YWx1ZTogcHJvcHMuc2VydmljZS5mYXVsdENvdW50VGhyZXNob2xkLFxuICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNvbG9yOiBDb2xvci5SRUQsXG4gICAgICAgICAgICBsYWJlbDogJ0hpZ2ggU2V2ZXJpdHknLFxuICAgICAgICAgIH0sXG4gICAgICAgIF1cbiAgICAgIH0pLFxuICAgICAgXG4gICAgICAuLi56b25hbEZhdWx0Q291bnRXaWRnZXRzLFxuICAgICAgLi4ucGVyQVpXaWRnZXRXaXRoUGVyT3BlcmF0aW9uTGF0ZW5jeSxcbiAgICAgIC4uLnBlckFaV2lkZ2V0V2l0aFBlck9wZXJhdGlvbkhpZ2hMYXRlbmN5Q291bnRcbiAgICApO1xuICAgICBcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgc2VydmljZSBsZXZlbCBkYXNoYm9hcmRcbiAgICovXG4gIGRhc2hib2FyZDogRGFzaGJvYXJkO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHNjb3BlOiBDb25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogU2VydmljZUF2YWlsYWJpbGl0eUFuZExhdGVuY3lEYXNoYm9hcmRQcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIHRoaXMuZGFzaGJvYXJkID0gbmV3IERhc2hib2FyZCh0aGlzLCAnRGFzaGJvYXJkJywge1xuICAgICAgZGFzaGJvYXJkTmFtZTogYCR7cHJvcHMuc2VydmljZS5zZXJ2aWNlTmFtZS50b0xvd2VyQ2FzZSgpfS1hdmFpbGFiaWxpdHktYW5kLWxhdGVuY3ktJHtBd3MuUkVHSU9OfWAsXG4gICAgICBkZWZhdWx0SW50ZXJ2YWw6IHByb3BzLmludGVydmFsLFxuICAgICAgcGVyaW9kT3ZlcnJpZGU6IFBlcmlvZE92ZXJyaWRlLkFVVE9cbiAgICB9KTtcblxuICAgIHRoaXMuZGFzaGJvYXJkLmFkZFdpZGdldHMoXG4gICAgICBuZXcgQWxhcm1TdGF0dXNXaWRnZXQoe1xuICAgICAgICBoZWlnaHQ6IDIsXG4gICAgICAgIHdpZHRoOiA2LFxuICAgICAgICBhbGFybXM6IFtcbiAgICAgICAgICBwcm9wcy5zZXJ2aWNlQWxhcm1zQW5kUnVsZXMuc2VydmljZUltcGFjdEFsYXJtXG4gICAgICAgIF0sXG4gICAgICAgIHRpdGxlOiBcIlNlcnZpY2UgQWxhcm0gKGFueSBjcml0aWNhbCBvcGVyYXRpb24gc2VlcyBpbXBhY3Qgem9uYWxseSBvciByZWdpb25hbGx5LCBtZWFzdXJlZCBmcm9tIHNlcnZlci1zaWRlIG9yIGNhbmFyeSlcIlxuICAgICAgfSksXG4gICAgICBuZXcgQWxhcm1TdGF0dXNXaWRnZXQoe1xuICAgICAgICBoZWlnaHQ6IDIsXG4gICAgICAgIHdpZHRoOiA2LFxuICAgICAgICBhbGFybXM6IFtcbiAgICAgICAgICBwcm9wcy5zZXJ2aWNlQWxhcm1zQW5kUnVsZXMucmVnaW9uYWxJbXBhY3RBbGFybVxuICAgICAgICBdLFxuICAgICAgICB0aXRsZTogXCJSZWdpb25hbCBJbXBhY3QgKHRoZXJlIGlzIHJlZ2lvbmFsbHkgc2NvcGVkIGltcGFjdCB0byBhbnkgY3JpdGljYWwgb3BlcmF0aW9uLCBtZWFzdXJlZCBmcm9tIHNlcnZlci1zaWRlIG9yIGNhbmFyeSlcIlxuICAgICAgfSksXG4gICAgICBuZXcgQWxhcm1TdGF0dXNXaWRnZXQoe1xuICAgICAgICBoZWlnaHQ6IDIsXG4gICAgICAgIHdpZHRoOiA2LFxuICAgICAgICBhbGFybXM6IFtcbiAgICAgICAgICBwcm9wcy5zZXJ2aWNlQWxhcm1zQW5kUnVsZXMucmVnaW9uYWxTZXJ2ZXJTaWRlSW1wYWN0QWxhcm1cbiAgICAgICAgXSxcbiAgICAgICAgdGl0bGU6IFwiU2VydmVyLXNpZGUgUmVnaW9uYWwgSW1wYWN0ICh0aGVyZSBpcyByZWdpb25hbGx5IHNjb3BlZCBpbXBhY3QgdG8gYW55IGNyaXRpY2FsIG9wZXJhdGlvbiwgbWVhc3VyZWQgZnJvbSBzZXJ2ZXItc2lkZSlcIlxuICAgICAgfSksXG4gICAgICAuLi5wcm9wcy5zZXJ2aWNlQWxhcm1zQW5kUnVsZXMucmVnaW9uYWxDYW5hcnlBbGFybSA/IFtuZXcgQWxhcm1TdGF0dXNXaWRnZXQoe1xuICAgICAgICBoZWlnaHQ6IDIsXG4gICAgICAgIHdpZHRoOiA2LFxuICAgICAgICBhbGFybXM6IFtcbiAgICAgICAgICBwcm9wcy5zZXJ2aWNlQWxhcm1zQW5kUnVsZXMucmVnaW9uYWxDYW5hcnlBbGFybVxuICAgICAgICBdLFxuICAgICAgICB0aXRsZTogXCJDYW5hcnkgUmVnaW9uYWwgSW1wYWN0ICh0aGVyZSBpcyByZWdpb25hbGx5IHNjb3BlZCBpbXBhY3QgdG8gYW55IGNyaXRpY2FsIG9wZXJhdGlvbiwgbWVhc3VyZWQgZnJvbSB0aGUgY2FuYXJ5KVwiXG4gICAgICB9KV0gOiBbXVxuICAgICk7XG5cbiAgICB0aGlzLmRhc2hib2FyZC5hZGRXaWRnZXRzKFxuICAgICAgbmV3IEFsYXJtU3RhdHVzV2lkZ2V0KHtcbiAgICAgICAgaGVpZ2h0OiAyLFxuICAgICAgICB3aWR0aDogMjQsXG4gICAgICAgIGFsYXJtczogW1xuICAgICAgICAgIC4uLk9iamVjdC52YWx1ZXMocHJvcHMuc2VydmljZUFsYXJtc0FuZFJ1bGVzLnpvbmFsQWdncmVnYXRlSXNvbGF0ZWRJbXBhY3RBbGFybXMpXG4gICAgICAgIF0sXG4gICAgICAgIHRpdGxlOiBcIlpvbmFsIEFnZ3JlZ2F0ZSBBbGFybXMgKGFsYXJtcyB0cmlnZ2VyIGlmIGFueSBjcml0aWNhbCBvcGVyYXRpb24gaW4gdGhlIEFaIHNlZXMgYXZhaWxhYmlsaXR5IG9yIGxhdGVuY3kgaW1wYWN0IGFzIG1lYXN1cmVkIGZyb20gc2VydmVyLXNpZGUgb3IgY2FuYXJ5KVwiXG4gICAgICB9XG4gICAgKSk7XG5cbiAgICB0aGlzLmRhc2hib2FyZC5hZGRXaWRnZXRzKFxuICAgICAgbmV3IEFsYXJtU3RhdHVzV2lkZ2V0KHtcbiAgICAgICAgaGVpZ2h0OiAyLFxuICAgICAgICB3aWR0aDogMjQsXG4gICAgICAgIGFsYXJtczogW1xuICAgICAgICAgIC4uLk9iamVjdC52YWx1ZXMocHJvcHMuc2VydmljZUFsYXJtc0FuZFJ1bGVzLnpvbmFsU2VydmVyU2lkZUlzb2xhdGVkSW1wYWN0QWxhcm1zKVxuICAgICAgICBdLFxuICAgICAgICB0aXRsZTogXCJTZXJ2ZXItc2lkZSBab25hbCBBbGFybXMgKGFsYXJtcyB0cmlnZ2VyIGlmIGFueSBjcml0aWNhbCBvcGVyYXRpb24gaW4gdGhlIEFaIHNlZXMgYXZhaWxhYmlsaXR5IG9yIGxhdGVuY3kgaW1wYWN0IGFzIG1lYXN1cmVkIGZyb20gdGhlIHNlcnZlci1zaWRlLCB0aGVzZSBhcmUgdXNlZnVsIGZvciBkZXBsb3ltZW50IG1vbml0b3JpbmcsIGluIGNhc2UgdGhlIGNhbmFyeSBzZWVzIGVycm9ycyB3aGVuIGFuIEFaIGlzIGludGVudGlvbmFsbHkgdW5hdmFpbGFibGUpXCJcbiAgICAgIH1cbiAgICApKTtcblxuICAgIHRoaXMuZGFzaGJvYXJkLmFkZFdpZGdldHMoXG4gICAgICBuZXcgVGV4dFdpZGdldCh7XG4gICAgICAgIG1hcmtkb3duOiBcIiMjIyBQZXIgT3BlcmF0aW9uIERhc2hib2FyZHNcXG5cIiArIHByb3BzLm9wZXJhdGlvbnNEYXNoYm9hcmQubWFwKHggPT4gYC0gWyR7eC5kYXNoYm9hcmROYW1lfV0oaHR0cHM6Ly8ke0F3cy5SRUdJT059LmNvbnNvbGUuYXdzLmFtYXpvbi5jb20vY2xvdWR3YXRjaC9ob21lP3JlZ2lvbj0ke0F3cy5SRUdJT059I2Rhc2hib2FyZHMvZGFzaGJvYXJkLyR7eC5kYXNoYm9hcmROYW1lfSlgKS5qb2luKFwiXFxuXCIpLFxuICAgICAgICBiYWNrZ3JvdW5kOiBUZXh0V2lkZ2V0QmFja2dyb3VuZC5UUkFOU1BBUkVOVCxcbiAgICAgICAgaGVpZ2h0OiA0LFxuICAgICAgICB3aWR0aDogMjRcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIFNlcnZpY2VBdmFpbGFiaWxpdHlBbmRMYXRlbmN5RGFzaGJvYXJkLmNyZWF0ZVNlcnZlclNpZGVXaWRnZXRzKHRoaXMuZGFzaGJvYXJkLCBwcm9wcyk7XG5cbiAgICBpZiAocHJvcHMuc2VydmljZS5jYW5hcnlUZXN0UHJvcHMpIHtcbiAgICAgIFNlcnZpY2VBdmFpbGFiaWxpdHlBbmRMYXRlbmN5RGFzaGJvYXJkLmNyZWF0ZUNhbmFyeVdpZGdldHModGhpcy5kYXNoYm9hcmQsIHByb3BzKTtcbiAgICB9XG5cbiAgICBsZXQgbGI6IENmbkxvYWRCYWxhbmNlciA9IHByb3BzLnNlcnZpY2UubG9hZEJhbGFuY2VyPy5ub2RlXG4gICAgICAuZGVmYXVsdENoaWxkIGFzIENmbkxvYWRCYWxhbmNlcjtcblxuICAgIGlmIChsYiAmJiBsYi50eXBlID09ICdhcHBsaWNhdGlvbicpIHtcbiAgICAgIHRoaXMuZGFzaGJvYXJkLmFkZFdpZGdldHMoXG4gICAgICAgIG5ldyBUZXh0V2lkZ2V0KHtcbiAgICAgICAgICBtYXJrZG93bjogXCIjIyAqKkxvYWQgQmFsYW5jZXIgTWV0cmljcyoqXCIsXG4gICAgICAgICAgYmFja2dyb3VuZDogVGV4dFdpZGdldEJhY2tncm91bmQuVFJBTlNQQVJFTlQsXG4gICAgICAgICAgaGVpZ2h0OiAxLFxuICAgICAgICAgIHdpZHRoOiAyNFxuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMuZGFzaGJvYXJkLmFkZFdpZGdldHMoXG4gICAgICAgIC4uLkFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTWV0cmljcy5nZW5lcmF0ZUxvYWRCYWxhbmNlcldpZGdldHMoXG4gICAgICAgICAgbmV3IE1hcDxJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsIElUYXJnZXRHcm91cFtdPihbXG4gICAgICAgICAgICBbcHJvcHMuc2VydmljZS5sb2FkQmFsYW5jZXIgYXMgSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLCBwcm9wcy5zZXJ2aWNlLnRhcmdldEdyb3VwcyA/IHByb3BzLnNlcnZpY2UudGFyZ2V0R3JvdXBzIDogW11dXG4gICAgICAgICAgXSksXG4gICAgICAgICAgcHJvcHMuYXpNYXBwZXIsXG4gICAgICAgICAgcHJvcHMuc2VydmljZS5wZXJpb2QsXG4gICAgICAgICAgcHJvcHMuc2VydmljZS5kZWZhdWx0TGF0ZW5jeU1ldHJpY0RldGFpbHMuYWxhcm1TdGF0aXN0aWMsXG4gICAgICAgICAgcHJvcHMuc2VydmljZS5kZWZhdWx0TGF0ZW5jeU1ldHJpY0RldGFpbHMuc3VjY2Vzc0FsYXJtVGhyZXNob2xkLFxuICAgICAgICAgIHByb3BzLnNlcnZpY2UuZGVmYXVsdEF2YWlsYWJpbGl0eU1ldHJpY0RldGFpbHMuZmF1bHRBbGFybVRocmVzaG9sZFxuICAgICAgICApXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuIl19
|