@cdklabs/multi-az-observability 0.0.1-alpha.3 → 0.0.1-alpha.30

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.
Files changed (100) hide show
  1. package/.jsii +374 -147
  2. package/API.md +292 -100
  3. package/README.md +21 -14
  4. package/cdk.json +1 -1
  5. package/lib/alarmsandrules/AvailabilityAndLatencyAlarmsAndRules.d.ts +7 -7
  6. package/lib/alarmsandrules/AvailabilityAndLatencyAlarmsAndRules.js +35 -35
  7. package/lib/alarmsandrules/BaseOperationRegionalAlarmsAndRules.js +2 -2
  8. package/lib/alarmsandrules/BaseOperationZonalAlarmsAndRules.d.ts +6 -15
  9. package/lib/alarmsandrules/BaseOperationZonalAlarmsAndRules.js +2 -10
  10. package/lib/alarmsandrules/CanaryOperationZonalAlarmsAndRules.d.ts +11 -3
  11. package/lib/alarmsandrules/CanaryOperationZonalAlarmsAndRules.js +24 -13
  12. package/lib/alarmsandrules/IBaseOperationZonalAlarmsAndRules.d.ts +0 -8
  13. package/lib/alarmsandrules/IBaseOperationZonalAlarmsAndRules.js +1 -1
  14. package/lib/alarmsandrules/IOperationAlarmsAndRules.d.ts +19 -27
  15. package/lib/alarmsandrules/IOperationAlarmsAndRules.js +1 -1
  16. package/lib/alarmsandrules/IServerSideOperationRegionalAlarmsAndRules.js +1 -1
  17. package/lib/alarmsandrules/IServiceAlarmsAndRules.d.ts +0 -8
  18. package/lib/alarmsandrules/IServiceAlarmsAndRules.js +1 -1
  19. package/lib/alarmsandrules/OperationAlarmsAndRules.d.ts +14 -22
  20. package/lib/alarmsandrules/OperationAlarmsAndRules.js +51 -71
  21. package/lib/alarmsandrules/ServerSideOperationRegionalAlarmsAndRules.d.ts +5 -5
  22. package/lib/alarmsandrules/ServerSideOperationRegionalAlarmsAndRules.js +2 -3
  23. package/lib/alarmsandrules/ServerSideOperationZonalAlarmsAndRules.d.ts +21 -13
  24. package/lib/alarmsandrules/ServerSideOperationZonalAlarmsAndRules.js +43 -29
  25. package/lib/alarmsandrules/ServiceAlarmsAndRules.d.ts +0 -2
  26. package/lib/alarmsandrules/ServiceAlarmsAndRules.js +61 -39
  27. package/lib/alarmsandrules/props/BaseOperationZonalAlarmsAndRulesProps.d.ts +6 -44
  28. package/lib/alarmsandrules/props/BaseOperationZonalAlarmsAndRulesProps.js +1 -1
  29. package/lib/alarmsandrules/props/OperationAlarmsAndRulesProps.d.ts +28 -7
  30. package/lib/alarmsandrules/props/OperationAlarmsAndRulesProps.js +1 -1
  31. package/lib/azmapper/AvailabilityZoneMapper.js +4 -3
  32. package/lib/basic_observability/BasicServiceDashboard.d.ts +1 -3
  33. package/lib/basic_observability/BasicServiceDashboard.js +69 -100
  34. package/lib/basic_observability/BasicServiceMultiAZObservability.d.ts +8 -9
  35. package/lib/basic_observability/BasicServiceMultiAZObservability.js +100 -312
  36. package/lib/basic_observability/props/ApplicationLoadBalancerDetectionProps.d.ts +50 -0
  37. package/lib/basic_observability/props/ApplicationLoadBalancerDetectionProps.js +3 -0
  38. package/lib/basic_observability/props/BasicServiceDashboardProps.d.ts +27 -13
  39. package/lib/basic_observability/props/BasicServiceDashboardProps.js +1 -1
  40. package/lib/basic_observability/props/BasicServiceMultiAZObservabilityProps.d.ts +10 -38
  41. package/lib/basic_observability/props/BasicServiceMultiAZObservabilityProps.js +1 -1
  42. package/lib/basic_observability/props/NatGatewayDetectionProps.d.ts +31 -0
  43. package/lib/basic_observability/props/NatGatewayDetectionProps.js +3 -0
  44. package/lib/canaries/CanaryFunction.js +7 -6
  45. package/lib/canaries/src/canary.zip +0 -0
  46. package/lib/dashboards/OperationAvailabilityAndLatencyDashboard.d.ts +2 -6
  47. package/lib/dashboards/OperationAvailabilityAndLatencyDashboard.js +440 -506
  48. package/lib/dashboards/ServiceAvailabilityAndLatencyDashboard.d.ts +0 -1
  49. package/lib/dashboards/ServiceAvailabilityAndLatencyDashboard.js +56 -113
  50. package/lib/dashboards/props/OperationAvailabilityAndLatencyDashboardProps.d.ts +3 -66
  51. package/lib/dashboards/props/OperationAvailabilityAndLatencyDashboardProps.js +1 -1
  52. package/lib/dashboards/props/OperationAvailabilityWidgetProps.d.ts +7 -2
  53. package/lib/dashboards/props/OperationAvailabilityWidgetProps.js +1 -1
  54. package/lib/dashboards/props/OperationLatencyWidgetProps.d.ts +7 -2
  55. package/lib/dashboards/props/OperationLatencyWidgetProps.js +1 -1
  56. package/lib/index.d.ts +5 -0
  57. package/lib/index.js +8 -2
  58. package/lib/metrics/ApplicationLoadBalancerMetrics.d.ts +72 -4
  59. package/lib/metrics/ApplicationLoadBalancerMetrics.js +712 -32
  60. package/lib/metrics/AvailabilityAndLatencyMetrics.d.ts +23 -0
  61. package/lib/metrics/AvailabilityAndLatencyMetrics.js +117 -24
  62. package/lib/metrics/NatGatewayMetrics.d.ts +110 -0
  63. package/lib/metrics/NatGatewayMetrics.js +300 -0
  64. package/lib/metrics/RegionalLatencyMetrics.d.ts +1 -1
  65. package/lib/metrics/RegionalLatencyMetrics.js +27 -20
  66. package/lib/metrics/ZonalAvailabilityMetrics.d.ts +2 -8
  67. package/lib/metrics/ZonalAvailabilityMetrics.js +10 -25
  68. package/lib/metrics/ZonalLatencyMetrics.d.ts +2 -1
  69. package/lib/metrics/ZonalLatencyMetrics.js +33 -23
  70. package/lib/metrics/props/AvailabilityAndLatencyMetricProps.d.ts +4 -0
  71. package/lib/metrics/props/AvailabilityAndLatencyMetricProps.js +1 -1
  72. package/lib/metrics/props/LatencyMetricProps.d.ts +6 -0
  73. package/lib/metrics/props/LatencyMetricProps.js +1 -1
  74. package/lib/metrics/props/ZonalAvailabilityMetricProps.d.ts +4 -0
  75. package/lib/metrics/props/ZonalAvailabilityMetricProps.js +1 -1
  76. package/lib/metrics/props/ZonalLatencyMetricProps.d.ts +4 -0
  77. package/lib/metrics/props/ZonalLatencyMetricProps.js +1 -1
  78. package/lib/monitoring/src/monitoring-layer.zip +0 -0
  79. package/lib/outlier-detection/ApplicationLoadBalancerAvailabilityOutlierAlgorithm.d.ts +10 -0
  80. package/lib/outlier-detection/ApplicationLoadBalancerAvailabilityOutlierAlgorithm.js +15 -0
  81. package/lib/outlier-detection/ApplicationLoadBalancerLatencyOutlierAlgorithm.d.ts +18 -0
  82. package/lib/outlier-detection/ApplicationLoadBalancerLatencyOutlierAlgorithm.js +23 -0
  83. package/lib/outlier-detection/OutlierDetectionFunction.js +6 -5
  84. package/lib/outlier-detection/PacketLossOutlierAlgorithm.d.ts +10 -0
  85. package/lib/outlier-detection/PacketLossOutlierAlgorithm.js +15 -0
  86. package/lib/outlier-detection/src/outlier-detection.zip +0 -0
  87. package/lib/outlier-detection/src/scipy-layer.zip +0 -0
  88. package/lib/services/CanaryMetrics.js +1 -1
  89. package/lib/services/CanaryTestMetricsOverride.js +1 -1
  90. package/lib/services/ContributorInsightRuleDetails.js +1 -1
  91. package/lib/services/InstrumentedServiceMultiAZObservability.d.ts +10 -0
  92. package/lib/services/InstrumentedServiceMultiAZObservability.js +188 -194
  93. package/lib/services/Operation.js +1 -1
  94. package/lib/services/OperationMetricDetails.js +1 -1
  95. package/lib/services/Service.js +1 -1
  96. package/lib/services/ServiceMetricDetails.js +1 -1
  97. package/lib/services/props/MetricDimensions.js +1 -1
  98. package/lib/utilities/MetricsHelper.d.ts +15 -10
  99. package/lib/utilities/MetricsHelper.js +19 -11
  100. package/package.json +8 -8
@@ -4,7 +4,10 @@ exports.ApplicationLoadBalancerMetrics = void 0;
4
4
  const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
5
5
  const aws_elasticloadbalancingv2_1 = require("aws-cdk-lib/aws-elasticloadbalancingv2");
6
6
  const AvailabilityMetricType_1 = require("../utilities/AvailabilityMetricType");
7
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
7
8
  const MetricsHelper_1 = require("../utilities/MetricsHelper");
9
+ const ApplicationLoadBalancerAvailabilityOutlierAlgorithm_1 = require("../outlier-detection/ApplicationLoadBalancerAvailabilityOutlierAlgorithm");
10
+ const ApplicationLoadBalancerLatencyOutlierAlgorithm_1 = require("../outlier-detection/ApplicationLoadBalancerLatencyOutlierAlgorithm");
8
11
  class ApplicationLoadBalancerMetrics {
9
12
  /**
10
13
  * Gets the TargetResponseTime latency for the ALB
@@ -109,7 +112,7 @@ class ApplicationLoadBalancerMetrics {
109
112
  usingMetrics[`${keyprefix}1`] = target5xx;
110
113
  usingMetrics[`${keyprefix}2`] = elb5xx;
111
114
  metrics.push(new aws_cloudwatch_1.MathExpression({
112
- expression: `${keyprefix}1+${keyprefix}2`,
115
+ expression: `FILL(${keyprefix}1, 0) + FILL(${keyprefix}2, 0)`,
113
116
  usingMetrics: usingMetrics,
114
117
  label: props.availabilityZoneId + "-" + alb.loadBalancerArn + "-fault-count",
115
118
  period: props.period,
@@ -180,7 +183,7 @@ class ApplicationLoadBalancerMetrics {
180
183
  LoadBalancer: alb
181
184
  .loadBalancerFullName,
182
185
  },
183
- label: props.availabilityZoneId + "-request-count",
186
+ label: props.availabilityZoneId,
184
187
  period: props.period,
185
188
  statistic: aws_cloudwatch_1.Stats.SUM,
186
189
  unit: aws_cloudwatch_1.Unit.COUNT
@@ -224,7 +227,7 @@ class ApplicationLoadBalancerMetrics {
224
227
  usingMetrics[`${keyprefix}1`] = target5xx;
225
228
  usingMetrics[`${keyprefix}2`] = elb5xx;
226
229
  return new aws_cloudwatch_1.MathExpression({
227
- expression: `${keyprefix}1+${keyprefix}2`,
230
+ expression: `FILL(${keyprefix}1, 0) + FILL(${keyprefix}2, 0)`,
228
231
  usingMetrics: usingMetrics,
229
232
  label: props.label,
230
233
  period: props.period,
@@ -338,7 +341,7 @@ class ApplicationLoadBalancerMetrics {
338
341
  usingMetrics[`${keyprefix}1`] = target5xx;
339
342
  usingMetrics[`${keyprefix}2`] = elb5xx;
340
343
  return new aws_cloudwatch_1.MathExpression({
341
- expression: `${keyprefix}1+${keyprefix}2`,
344
+ expression: `FILL(${keyprefix}1, 0) + FILL(${keyprefix}2, 0)`,
342
345
  usingMetrics: usingMetrics,
343
346
  label: props.label,
344
347
  period: props.period,
@@ -388,7 +391,7 @@ class ApplicationLoadBalancerMetrics {
388
391
  LoadBalancer: props.alb
389
392
  .loadBalancerFullName,
390
393
  },
391
- label: "target-response-time",
394
+ label: aws_cdk_lib_1.Aws.REGION,
392
395
  period: props.period,
393
396
  statistic: props.statistic,
394
397
  unit: aws_cloudwatch_1.Unit.SECONDS
@@ -401,17 +404,17 @@ class ApplicationLoadBalancerMetrics {
401
404
  * @param azMapper The AZ mapper function so the metrics are correctly labeled with their AZ ID
402
405
  * @returns
403
406
  */
404
- static getTotalAlbFaultCountPerZone(albs, period, azMapper) {
407
+ static getTotalAlbFaultCountPerZone(albs, period, azMapper, prefix) {
405
408
  let faultsPerZone = {};
406
409
  let metricsPerAZ = {};
407
- let keyprefix = MetricsHelper_1.MetricsHelper.nextChar('');
408
- albs.forEach((alb) => {
409
- alb.vpc.availabilityZones.forEach((availabilityZone) => {
410
- if (!(availabilityZone in metricsPerAZ)) {
411
- metricsPerAZ[availabilityZone] = [];
412
- }
410
+ let keyprefix = prefix ? prefix : MetricsHelper_1.MetricsHelper.nextChar();
411
+ albs.forEach((alb, albIndex) => {
412
+ alb.vpc.availabilityZones.forEach((availabilityZone, index) => {
413
413
  let azLetter = availabilityZone.substring(availabilityZone.length - 1);
414
414
  let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
415
+ if (!(azLetter in metricsPerAZ)) {
416
+ metricsPerAZ[azLetter] = [];
417
+ }
415
418
  // 5xx responses from targets
416
419
  let target5xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_5XX_COUNT, {
417
420
  dimensionsMap: {
@@ -424,8 +427,86 @@ class ApplicationLoadBalancerMetrics {
424
427
  statistic: aws_cloudwatch_1.Stats.SUM,
425
428
  unit: aws_cloudwatch_1.Unit.COUNT
426
429
  });
427
- // 5xx responses from ELB
428
- let elb5xx = alb.metrics.httpCodeElb(aws_elasticloadbalancingv2_1.HttpCodeElb.ELB_5XX_COUNT, {
430
+ let usingMetrics = {};
431
+ usingMetrics[`${azLetter}${albIndex}_faultcount`] = target5xx;
432
+ // This is the total number of faults per zone for this load balancer
433
+ metricsPerAZ[azLetter].push(new aws_cloudwatch_1.MathExpression({
434
+ expression: `FILL(${azLetter}${albIndex}_faultcount, 0)`,
435
+ usingMetrics: usingMetrics,
436
+ period: period,
437
+ label: availabilityZoneId,
438
+ color: MetricsHelper_1.MetricsHelper.colors[index]
439
+ }));
440
+ keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
441
+ });
442
+ });
443
+ // We can have multiple load balancers per zone, so add their fault count
444
+ // metrics together
445
+ Object.keys(metricsPerAZ).forEach((azLetter, index) => {
446
+ let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
447
+ if (metricsPerAZ[azLetter].length > 1) {
448
+ let usingMetrics = {};
449
+ metricsPerAZ[azLetter].forEach((metric, index) => {
450
+ usingMetrics[`${azLetter}${index}_total_faultcount`] = metric;
451
+ });
452
+ faultsPerZone[azLetter] = new aws_cloudwatch_1.MathExpression({
453
+ expression: Object.keys(usingMetrics).join("+"),
454
+ usingMetrics: usingMetrics,
455
+ label: availabilityZoneId,
456
+ period: period,
457
+ color: MetricsHelper_1.MetricsHelper.colors[index]
458
+ });
459
+ }
460
+ else {
461
+ faultsPerZone[azLetter] = metricsPerAZ[azLetter][0];
462
+ }
463
+ });
464
+ return faultsPerZone;
465
+ }
466
+ /**
467
+ * Calculates the total number of faults for all ALBs combined per AZ
468
+ * @param albs The ALBs to aggregate
469
+ * @param period The period of time to calculate the metrics
470
+ * @param azMapper The AZ mapper function so the metrics are correctly labeled with their AZ ID
471
+ * @returns
472
+ */
473
+ static getTotalAlbSuccessCountPerZone(albs, period, azMapper) {
474
+ let successPerZone = {};
475
+ let metricsPerAZ = {};
476
+ let keyprefix = MetricsHelper_1.MetricsHelper.nextChar();
477
+ albs.forEach((alb) => {
478
+ alb.vpc.availabilityZones.forEach((availabilityZone, index) => {
479
+ let azLetter = availabilityZone.substring(availabilityZone.length - 1);
480
+ let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
481
+ if (!(azLetter in metricsPerAZ)) {
482
+ metricsPerAZ[azLetter] = [];
483
+ }
484
+ // 2xx responses from targets
485
+ let target2xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_2XX_COUNT, {
486
+ dimensionsMap: {
487
+ AvailabilityZone: availabilityZone,
488
+ LoadBalancer: alb
489
+ .loadBalancerFullName,
490
+ },
491
+ label: availabilityZoneId,
492
+ period: period,
493
+ statistic: aws_cloudwatch_1.Stats.SUM,
494
+ unit: aws_cloudwatch_1.Unit.COUNT
495
+ });
496
+ // 3xx responses from targets
497
+ let target3xx = alb.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_3XX_COUNT, {
498
+ dimensionsMap: {
499
+ AvailabilityZone: availabilityZone,
500
+ LoadBalancer: alb
501
+ .loadBalancerFullName,
502
+ },
503
+ label: availabilityZoneId,
504
+ period: period,
505
+ statistic: aws_cloudwatch_1.Stats.SUM,
506
+ unit: aws_cloudwatch_1.Unit.COUNT
507
+ });
508
+ // 3xx responses from ELB
509
+ let elb3xx = alb.metrics.httpCodeElb(aws_elasticloadbalancingv2_1.HttpCodeElb.ELB_3XX_COUNT, {
429
510
  dimensionsMap: {
430
511
  AvailabilityZone: availabilityZone,
431
512
  LoadBalancer: alb
@@ -437,31 +518,351 @@ class ApplicationLoadBalancerMetrics {
437
518
  unit: aws_cloudwatch_1.Unit.COUNT
438
519
  });
439
520
  let usingMetrics = {};
440
- usingMetrics[`${keyprefix}1`] = elb5xx;
441
- usingMetrics[`${keyprefix}2`] = target5xx;
442
- metricsPerAZ[availabilityZone].push(new aws_cloudwatch_1.MathExpression({
443
- expression: `${keyprefix}1 + ${keyprefix}2`,
521
+ usingMetrics[`${keyprefix}1`] = elb3xx;
522
+ usingMetrics[`${keyprefix}2`] = target2xx;
523
+ usingMetrics[`${keyprefix}3`] = target3xx;
524
+ // This is the total number of faults per zone for this load balancer
525
+ metricsPerAZ[azLetter].push(new aws_cloudwatch_1.MathExpression({
526
+ expression: `FILL(${keyprefix}1, 0) + FILL(${keyprefix}2, 0) + FILL(${keyprefix}3, 0)`,
444
527
  usingMetrics: usingMetrics,
445
- period: period
528
+ period: period,
529
+ label: availabilityZoneId,
530
+ color: MetricsHelper_1.MetricsHelper.colors[index]
446
531
  }));
447
532
  keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
448
533
  });
449
534
  });
450
- Object.keys(metricsPerAZ).forEach((availabilityZone) => {
535
+ // We can have multiple load balancers per zone, so add their success count
536
+ // metrics together
537
+ Object.keys(metricsPerAZ).forEach((azLetter, index) => {
538
+ let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
539
+ if (metricsPerAZ[azLetter].length > 1) {
540
+ let usingMetrics = {};
541
+ metricsPerAZ[azLetter].forEach((metric, index) => {
542
+ usingMetrics[`${keyprefix}${index}`] = metric;
543
+ });
544
+ successPerZone[azLetter] = new aws_cloudwatch_1.MathExpression({
545
+ expression: Object.keys(usingMetrics).join("+"),
546
+ usingMetrics: usingMetrics,
547
+ label: availabilityZoneId,
548
+ period: period,
549
+ color: MetricsHelper_1.MetricsHelper.colors[index]
550
+ });
551
+ }
552
+ else {
553
+ successPerZone[azLetter] = metricsPerAZ[azLetter][0];
554
+ }
555
+ });
556
+ return successPerZone;
557
+ }
558
+ /**
559
+ * Calculates the total number of processed bytes for all ALBs in each zone
560
+ * @param albs
561
+ * @param period
562
+ * @param azMapper
563
+ * @returns
564
+ */
565
+ static getTotalAlbRequestsPerZone(albs, period, azMapper, prefix) {
566
+ let requestsPerZone = {};
567
+ let metricsPerAZ = {};
568
+ let keyprefix = prefix ? prefix : MetricsHelper_1.MetricsHelper.nextChar();
569
+ albs.forEach((alb) => {
570
+ alb.vpc.availabilityZones.forEach((availabilityZone, index) => {
571
+ let azLetter = availabilityZone.substring(availabilityZone.length - 1);
572
+ let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
573
+ if (!(azLetter in metricsPerAZ)) {
574
+ metricsPerAZ[azLetter] = [];
575
+ }
576
+ let requestCount = alb.metrics.requestCount({
577
+ dimensionsMap: {
578
+ AvailabilityZone: availabilityZone,
579
+ LoadBalancer: alb
580
+ .loadBalancerFullName,
581
+ },
582
+ label: availabilityZoneId,
583
+ period: period,
584
+ statistic: aws_cloudwatch_1.Stats.SUM,
585
+ unit: aws_cloudwatch_1.Unit.COUNT,
586
+ color: MetricsHelper_1.MetricsHelper.colors[index]
587
+ });
588
+ metricsPerAZ[azLetter].push(requestCount);
589
+ });
590
+ });
591
+ // We can have multiple load balancers per zone, so add their processed bytes together
592
+ Object.keys(metricsPerAZ).forEach((azLetter, index) => {
593
+ let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
594
+ if (metricsPerAZ[azLetter].length > 1) {
595
+ let usingMetrics = {};
596
+ metricsPerAZ[azLetter].forEach((metric, index) => {
597
+ usingMetrics[`${keyprefix}${index}`] = metric;
598
+ });
599
+ keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
600
+ requestsPerZone[azLetter] = new aws_cloudwatch_1.MathExpression({
601
+ expression: Object.keys(usingMetrics).join("+"),
602
+ usingMetrics: usingMetrics,
603
+ label: availabilityZoneId,
604
+ period: period,
605
+ color: MetricsHelper_1.MetricsHelper.colors[index]
606
+ });
607
+ }
608
+ else {
609
+ requestsPerZone[azLetter] = metricsPerAZ[azLetter][0];
610
+ }
611
+ });
612
+ return requestsPerZone;
613
+ }
614
+ /**
615
+ * Calculates the total number of processed bytes for all ALBs in each zone
616
+ * @param albs
617
+ * @param period
618
+ * @param azMapper
619
+ * @returns
620
+ */
621
+ static getTotalAlbProcessedBytesPerZone(albs, period, azMapper) {
622
+ let processedBytesPerZone = {};
623
+ let metricsPerAZ = {};
624
+ let keyprefix = MetricsHelper_1.MetricsHelper.nextChar();
625
+ albs.forEach((alb) => {
626
+ alb.vpc.availabilityZones.forEach((availabilityZone, index) => {
627
+ let azLetter = availabilityZone.substring(availabilityZone.length - 1);
628
+ let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
629
+ if (!(azLetter in metricsPerAZ)) {
630
+ metricsPerAZ[azLetter] = [];
631
+ }
632
+ let processedBytes = alb.metrics.processedBytes({
633
+ dimensionsMap: {
634
+ AvailabilityZone: availabilityZone,
635
+ LoadBalancer: alb
636
+ .loadBalancerFullName,
637
+ },
638
+ label: availabilityZoneId,
639
+ period: period,
640
+ statistic: aws_cloudwatch_1.Stats.SUM,
641
+ unit: aws_cloudwatch_1.Unit.COUNT,
642
+ color: MetricsHelper_1.MetricsHelper.colors[index]
643
+ });
644
+ metricsPerAZ[azLetter].push(processedBytes);
645
+ });
646
+ });
647
+ // We can have multiple load balancers per zone, so add their processed bytes together
648
+ Object.keys(metricsPerAZ).forEach((azLetter, index) => {
649
+ let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
650
+ if (metricsPerAZ[azLetter].length > 1) {
651
+ let usingMetrics = {};
652
+ metricsPerAZ[azLetter].forEach((metric, index) => {
653
+ usingMetrics[`${keyprefix}${index}`] = metric;
654
+ });
655
+ keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
656
+ processedBytesPerZone[azLetter] = new aws_cloudwatch_1.MathExpression({
657
+ expression: Object.keys(usingMetrics).join("+"),
658
+ usingMetrics: usingMetrics,
659
+ label: availabilityZoneId,
660
+ period: period,
661
+ color: MetricsHelper_1.MetricsHelper.colors[index]
662
+ });
663
+ }
664
+ else {
665
+ processedBytesPerZone[azLetter] = metricsPerAZ[azLetter][0];
666
+ }
667
+ });
668
+ return processedBytesPerZone;
669
+ }
670
+ /**
671
+ * Calculates a weighted approximation of the latency at the provided statistic for all ALBs
672
+ * in each zone.
673
+ * @param albs
674
+ * @param statistic
675
+ * @param period
676
+ * @param azMapper
677
+ * @returns
678
+ */
679
+ static getTotalAlbLatencyPerZone(albs, statistic, period, azMapper) {
680
+ let latencyPerZone = {};
681
+ let keyprefix = MetricsHelper_1.MetricsHelper.nextChar();
682
+ let requestCountsPerAZMetricKeys = {};
683
+ let weightedLatencyPerAZ = {};
684
+ albs.forEach((alb) => {
685
+ alb.vpc.availabilityZones.forEach((availabilityZone) => {
686
+ let azLetter = availabilityZone.substring(availabilityZone.length - 1);
687
+ if (!(azLetter in weightedLatencyPerAZ)) {
688
+ weightedLatencyPerAZ[azLetter] = [];
689
+ }
690
+ if (!(azLetter in requestCountsPerAZMetricKeys)) {
691
+ requestCountsPerAZMetricKeys[azLetter] = [];
692
+ }
693
+ let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
694
+ let latency = alb.metrics.targetResponseTime({
695
+ dimensionsMap: {
696
+ AvailabilityZone: availabilityZone,
697
+ LoadBalancer: alb
698
+ .loadBalancerFullName,
699
+ },
700
+ label: availabilityZoneId,
701
+ period: period,
702
+ statistic: statistic,
703
+ unit: aws_cloudwatch_1.Unit.SECONDS
704
+ });
705
+ let requestCount = alb.metrics.requestCount({
706
+ dimensionsMap: {
707
+ AvailabilityZone: availabilityZone,
708
+ LoadBalancer: alb
709
+ .loadBalancerFullName,
710
+ },
711
+ label: availabilityZoneId,
712
+ period: period,
713
+ statistic: aws_cloudwatch_1.Stats.SUM,
714
+ unit: aws_cloudwatch_1.Unit.COUNT
715
+ });
716
+ let usingMetrics = {};
717
+ usingMetrics[`${keyprefix}1`] = latency;
718
+ usingMetrics[`${keyprefix}2`] = requestCount;
719
+ let weightedLatency = new aws_cloudwatch_1.MathExpression({
720
+ expression: `${keyprefix}1*${keyprefix}2`,
721
+ usingMetrics: usingMetrics,
722
+ period: period,
723
+ label: availabilityZoneId
724
+ });
725
+ weightedLatencyPerAZ[azLetter].push(weightedLatency);
726
+ requestCountsPerAZMetricKeys[azLetter].push(`${keyprefix}2`);
727
+ keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
728
+ });
729
+ });
730
+ // We can have multiple load balancers per zone, combine their latency per zone
731
+ // to get an average latency percentile latency, like average p99
732
+ Object.keys(weightedLatencyPerAZ).forEach((azLetter, index) => {
733
+ let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
734
+ let usingMetrics = {};
735
+ weightedLatencyPerAZ[azLetter].forEach((metric, index) => {
736
+ usingMetrics[`${keyprefix}${index}`] = metric;
737
+ });
738
+ let numerator = "(" + Object.keys(usingMetrics).join("+") + ")";
739
+ let denominator = "(" + requestCountsPerAZMetricKeys[azLetter].join("+") + ")";
740
+ keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
741
+ /**
742
+ * We want to calculate this formula
743
+ *
744
+ * (p99_1 * requests_1 + p99_2 * requests_2 + p99_3 * requests_3) / (requests_1 + requests_2 + requests_3)
745
+ *
746
+ * This will provide a request weighted approximation of the p99
747
+ * latency per AZ
748
+ */
749
+ latencyPerZone[azLetter] = new aws_cloudwatch_1.MathExpression({
750
+ expression: "(" + numerator + "/" + denominator + ") * 1000",
751
+ usingMetrics: usingMetrics,
752
+ label: availabilityZoneId,
753
+ period: period,
754
+ color: MetricsHelper_1.MetricsHelper.colors[index]
755
+ });
756
+ keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
757
+ });
758
+ return latencyPerZone;
759
+ }
760
+ static getWeightedLatencyZScorePerZone(albs, statistic, period, azMapper) {
761
+ let weightedLatency = this.getTotalAlbLatencyPerZone(albs, statistic, period, azMapper);
762
+ let zscore = {};
763
+ Object.keys(weightedLatency).forEach((availabilityZone, index) => {
451
764
  let azLetter = availabilityZone.substring(availabilityZone.length - 1);
452
765
  let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
453
766
  let usingMetrics = {};
454
- metricsPerAZ[availabilityZone].forEach((metric) => {
455
- usingMetrics[`${keyprefix}1`] = metric;
767
+ let azMetricId = `${azLetter}1_zscore`;
768
+ usingMetrics[azMetricId] = weightedLatency[availabilityZone];
769
+ Object.keys(weightedLatency).forEach((az, metricIndex) => {
770
+ if (az != availabilityZone) {
771
+ usingMetrics[`others_${azLetter}${metricIndex}`] = weightedLatency[az];
772
+ }
456
773
  });
457
- faultsPerZone[availabilityZone] = new aws_cloudwatch_1.MathExpression({
458
- expression: Object.keys(usingMetrics).join("+"),
774
+ zscore[availabilityZone] = new aws_cloudwatch_1.MathExpression({
775
+ expression: `(${azMetricId} - AVG(METRICS("others_${azLetter}"))) / AVG(STDDEV(METRICS("others_${azLetter}")))`,
459
776
  usingMetrics: usingMetrics,
460
- label: availabilityZoneId + "-total-faults",
461
- period: period
777
+ label: availabilityZoneId,
778
+ period: period,
779
+ color: MetricsHelper_1.MetricsHelper.colors[index]
462
780
  });
463
781
  });
464
- return faultsPerZone;
782
+ return zscore;
783
+ }
784
+ /**
785
+ * Calculates the fault rate per AZ
786
+ * @param requestsPerZone
787
+ * @param faultsPerZone
788
+ * @param period
789
+ * @param azMapper
790
+ * @returns The fault rate per AZ using the AZ name letter as the key for each metric
791
+ */
792
+ static getTotalAlbFaultRatePerZone(albs, period, azMapper) {
793
+ let faultRateMetrics = {};
794
+ let requestsPerZone = this.getTotalAlbRequestsPerZone(albs, period, azMapper, "a");
795
+ let faultsPerZone = this.getTotalAlbFaultCountPerZone(albs, period, azMapper, "e");
796
+ Object.keys(requestsPerZone).forEach((key, index) => {
797
+ if (key in faultsPerZone) {
798
+ let usingMetrics = {};
799
+ let keyprefix = 'z' + key;
800
+ usingMetrics[`${keyprefix}1`] = faultsPerZone[key];
801
+ usingMetrics[`${keyprefix}2`] = requestsPerZone[key];
802
+ let zonalFaultRate = new aws_cloudwatch_1.MathExpression({
803
+ expression: `(${keyprefix}1/${keyprefix}2) * 100`,
804
+ usingMetrics: usingMetrics,
805
+ period: period,
806
+ label: azMapper.availabilityZoneIdFromAvailabilityZoneLetter(key),
807
+ color: MetricsHelper_1.MetricsHelper.colors[index]
808
+ });
809
+ faultRateMetrics[key] = zonalFaultRate;
810
+ }
811
+ else {
812
+ throw new Error("The zone " + key + " is not present in the faultsPerZone parameter.");
813
+ }
814
+ });
815
+ Object.keys(faultsPerZone).forEach((key) => {
816
+ if (!(key in requestsPerZone)) {
817
+ throw new Error("The zone " + key + " is not present in the requestsPerZone parameter.");
818
+ }
819
+ });
820
+ return faultRateMetrics;
821
+ }
822
+ static getTotalAlb5xxCountPerZone(albs, period, azMapper) {
823
+ let faultsPerZone = {};
824
+ let aggregateFaultsPerZone = {};
825
+ albs.forEach((alb) => {
826
+ alb.vpc?.availabilityZones.forEach((availabilityZone) => {
827
+ if (!(availabilityZone in faultsPerZone)) {
828
+ faultsPerZone[availabilityZone] = [];
829
+ }
830
+ let azLetter = availabilityZone.substring(availabilityZone.length - 1);
831
+ let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
832
+ let elb5xx = alb.metrics.httpCodeElb(aws_elasticloadbalancingv2_1.HttpCodeElb.ELB_5XX_COUNT, {
833
+ dimensionsMap: {
834
+ AvailabilityZone: availabilityZone,
835
+ LoadBalancer: alb
836
+ .loadBalancerFullName,
837
+ },
838
+ label: availabilityZoneId,
839
+ period: period,
840
+ statistic: aws_cloudwatch_1.Stats.SUM,
841
+ unit: aws_cloudwatch_1.Unit.COUNT
842
+ });
843
+ faultsPerZone[availabilityZone].push(elb5xx);
844
+ });
845
+ });
846
+ Object.keys(faultsPerZone).forEach((availabilityZone, index) => {
847
+ let azLetter = availabilityZone.substring(availabilityZone.length - 1);
848
+ let availabilityZoneId = azMapper.availabilityZoneIdFromAvailabilityZoneLetter(azLetter);
849
+ let usingMetrics = {};
850
+ if (faultsPerZone[availabilityZone].length > 1) {
851
+ faultsPerZone[availabilityZone].forEach((metric, faultIndex) => {
852
+ usingMetrics[`${azLetter}${faultIndex}`] = metric;
853
+ });
854
+ aggregateFaultsPerZone[availabilityZone] = new aws_cloudwatch_1.MathExpression({
855
+ expression: Object.keys(usingMetrics).join("+"),
856
+ usingMetrics: usingMetrics,
857
+ color: MetricsHelper_1.MetricsHelper.colors[index],
858
+ label: availabilityZoneId
859
+ });
860
+ }
861
+ else {
862
+ aggregateFaultsPerZone[availabilityZone] = faultsPerZone[availabilityZone][0];
863
+ }
864
+ });
865
+ return aggregateFaultsPerZone;
465
866
  }
466
867
  /**
467
868
  * Creates a zonal processed bytes metric for the specified load balancer
@@ -470,14 +871,14 @@ class ApplicationLoadBalancerMetrics {
470
871
  * @param period
471
872
  * @returns IMetric
472
873
  */
473
- static getPerAZProcessedBytesMetric(alb, availabilityZone, availabilityZoneId, period) {
874
+ static getPerAZProcessedBytesMetric(alb, availabilityZone, availabilityZoneId, period, addLoadBalancerArnToLabel) {
474
875
  return alb.metrics.processedBytes({
475
876
  period: period,
476
877
  dimensionsMap: {
477
878
  LoadBalancer: alb.loadBalancerFullName,
478
879
  AvailabilityZone: availabilityZone,
479
880
  },
480
- label: availabilityZoneId + "-" + alb.loadBalancerArn + "-processed-bytes"
881
+ label: availabilityZoneId + (addLoadBalancerArnToLabel ? "-" + alb.loadBalancerArn : "")
481
882
  });
482
883
  }
483
884
  /**
@@ -487,15 +888,294 @@ class ApplicationLoadBalancerMetrics {
487
888
  * @param period
488
889
  * @returns IMetric
489
890
  */
490
- static getRegionalProcessedBytesMetric(alb, period) {
891
+ static getRegionalProcessedBytesMetric(alb, period, addLoadBalancerArn) {
491
892
  return alb.metrics.processedBytes({
492
893
  period: period,
493
894
  dimensionsMap: {
494
895
  LoadBalancer: alb.loadBalancerFullName,
495
896
  },
496
- label: alb.loadBalancerArn + "-processed-bytes"
897
+ label: aws_cdk_lib_1.Aws.REGION + (addLoadBalancerArn ? "-" + alb.loadBalancerArn : "")
898
+ });
899
+ }
900
+ static createAZAvailabilityImpactAlarm(scope, alb, availabilityZoneId, availabilityZone, threshold, keyprefix, period, evaluationPeriods, datapointsToAlarm) {
901
+ // Create a fault rate alarm for the ALB in the specified AZ
902
+ return new aws_cloudwatch_1.Alarm(scope, keyprefix + '-fault-rate-alarm', {
903
+ alarmName: availabilityZoneId + '-' + alb.loadBalancerArn + '-fault-rate',
904
+ actionsEnabled: false,
905
+ metric: ApplicationLoadBalancerMetrics.getPerAZAvailabilityMetric(alb, {
906
+ period: period,
907
+ label: availabilityZoneId + '-' + alb.loadBalancerArn + '-fault-rate',
908
+ availabilityZone: availabilityZone,
909
+ availabilityZoneId: availabilityZoneId,
910
+ metricType: AvailabilityMetricType_1.AvailabilityMetricType.FAULT_RATE
911
+ }),
912
+ evaluationPeriods: evaluationPeriods,
913
+ datapointsToAlarm: datapointsToAlarm,
914
+ threshold: threshold,
915
+ comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
916
+ treatMissingData: aws_cloudwatch_1.TreatMissingData.IGNORE
917
+ });
918
+ }
919
+ static createAZLatencyImpactAlarm(scope, alb, availabilityZoneId, availabilityZone, threshold, statistic, keyprefix, period, evaluationPeriods, datapointsToAlarm) {
920
+ // Create a fault rate alarm for the ALB in the specified AZ
921
+ return new aws_cloudwatch_1.Alarm(scope, keyprefix + '-latency-alarm', {
922
+ alarmName: availabilityZoneId + '-' + alb.loadBalancerArn + '-latency',
923
+ actionsEnabled: false,
924
+ metric: ApplicationLoadBalancerMetrics.getPerAZLatencyMetric({
925
+ alb: alb,
926
+ availabilityZone: availabilityZone,
927
+ availabilityZoneId: availabilityZoneId,
928
+ label: availabilityZoneId + "-" + alb.loadBalancerArn + "-target-latency",
929
+ period: period,
930
+ statistic: statistic
931
+ }),
932
+ evaluationPeriods: evaluationPeriods,
933
+ datapointsToAlarm: datapointsToAlarm,
934
+ threshold: threshold,
935
+ comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
936
+ treatMissingData: aws_cloudwatch_1.TreatMissingData.IGNORE
937
+ });
938
+ }
939
+ static createAZAvailabilityOutlierAlarm(scope, alb, algorithm, availabilityZoneId, availabilityZone, threshold, keyprefix, period, evaluationPeriods, datapointsToAlarm) {
940
+ let usingMetrics = {};
941
+ let azMetricId = "";
942
+ alb.vpc.availabilityZones.forEach((az) => {
943
+ let azFaultCount = ApplicationLoadBalancerMetrics.getPerAZAvailabilityMetric(alb, {
944
+ metricType: AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT,
945
+ availabilityZone: availabilityZone,
946
+ availabilityZoneId: availabilityZoneId,
947
+ period: period,
948
+ label: availabilityZoneId + "-" + alb.loadBalancerArn + "-fault-count",
949
+ keyprefix: keyprefix
950
+ });
951
+ keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
952
+ usingMetrics[`${keyprefix}1`] = azFaultCount;
953
+ if (az == availabilityZone) {
954
+ azMetricId = `${keyprefix}1`;
955
+ }
956
+ keyprefix = MetricsHelper_1.MetricsHelper.nextChar(keyprefix);
497
957
  });
958
+ switch (algorithm) {
959
+ case ApplicationLoadBalancerAvailabilityOutlierAlgorithm_1.ApplicationLoadBalancerAvailabilityOutlierAlgorithm.STATIC:
960
+ default:
961
+ return new aws_cloudwatch_1.Alarm(scope, keyprefix + '-availability-outlier-alarm', {
962
+ alarmName: availabilityZoneId + '-' + alb.loadBalancerArn + '-availability-impact-outlier',
963
+ actionsEnabled: false,
964
+ metric: new aws_cloudwatch_1.MathExpression({
965
+ expression: `(${azMetricId}/(${Object.keys(usingMetrics).join("+")})) * 100`,
966
+ usingMetrics: usingMetrics,
967
+ label: availabilityZoneId + '-' + alb.loadBalancerArn + '-percent-of-faults',
968
+ period: period,
969
+ }),
970
+ evaluationPeriods: evaluationPeriods,
971
+ datapointsToAlarm: datapointsToAlarm,
972
+ threshold: threshold,
973
+ comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
974
+ treatMissingData: aws_cloudwatch_1.TreatMissingData.IGNORE
975
+ });
976
+ }
977
+ }
978
+ static createAZLatencyOutlierAlarm(scope, alb, algorithm, availabilityZoneId, availabilityZone, statistic, latencyThresold, outlierThreshold, period, evaluationPeriods, datapointsToAlarm, keyprefix) {
979
+ let usingMetrics = {};
980
+ let azMetricId = "";
981
+ switch (algorithm) {
982
+ case ApplicationLoadBalancerLatencyOutlierAlgorithm_1.ApplicationLoadBalancerLatencyOutlierAlgorithm.Z_SCORE:
983
+ default:
984
+ alb.vpc.availabilityZones.forEach((az, index) => {
985
+ // Target response time
986
+ let targetResponseTime = ApplicationLoadBalancerMetrics.getPerAZLatencyMetric({
987
+ alb: alb,
988
+ availabilityZone: az,
989
+ label: az + "-target-response-time",
990
+ statistic: statistic,
991
+ period: period
992
+ });
993
+ if (az == availabilityZone) {
994
+ azMetricId = `a${index}`;
995
+ usingMetrics[`a${index}`] = targetResponseTime;
996
+ }
997
+ else {
998
+ usingMetrics[`b${index}`] = targetResponseTime;
999
+ }
1000
+ });
1001
+ return new aws_cloudwatch_1.Alarm(scope, keyprefix + "-latency-outlier-alarm", {
1002
+ alarmName: availabilityZoneId + '-' + alb.loadBalancerArn + '-latency-impact-outlier',
1003
+ actionsEnabled: false,
1004
+ metric: new aws_cloudwatch_1.MathExpression({
1005
+ expression: `(${azMetricId} - AVG(METRICS("b"))) / AVG(STDDEV(METRICS("b")))`,
1006
+ usingMetrics: usingMetrics,
1007
+ label: availabilityZoneId + '-' + alb.loadBalancerArn + '-latency-z-score',
1008
+ period: period,
1009
+ }),
1010
+ evaluationPeriods: evaluationPeriods,
1011
+ datapointsToAlarm: datapointsToAlarm,
1012
+ threshold: outlierThreshold,
1013
+ comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
1014
+ treatMissingData: aws_cloudwatch_1.TreatMissingData.IGNORE
1015
+ });
1016
+ case ApplicationLoadBalancerLatencyOutlierAlgorithm_1.ApplicationLoadBalancerLatencyOutlierAlgorithm.STATIC:
1017
+ alb.vpc.availabilityZones.forEach((az, index) => {
1018
+ // Target response time
1019
+ let targetResponseTime = ApplicationLoadBalancerMetrics.getPerAZLatencyMetric({
1020
+ alb: alb,
1021
+ availabilityZone: az,
1022
+ label: az + "-target-response-time",
1023
+ statistic: `TC(${latencyThresold}:)`,
1024
+ period: period
1025
+ });
1026
+ if (az == availabilityZone) {
1027
+ azMetricId = `a${index}`;
1028
+ usingMetrics[`a${index}`] = targetResponseTime;
1029
+ }
1030
+ else {
1031
+ usingMetrics[`b${index}`] = targetResponseTime;
1032
+ }
1033
+ });
1034
+ return new aws_cloudwatch_1.Alarm(scope, keyprefix + "-latency-outlier-alarm", {
1035
+ alarmName: availabilityZoneId + '-' + alb.loadBalancerArn + '-latency-impact-outlier',
1036
+ actionsEnabled: false,
1037
+ metric: new aws_cloudwatch_1.MathExpression({
1038
+ expression: `(${azMetricId}/(${Object.keys(usingMetrics).join("+")})) * 100`,
1039
+ usingMetrics: usingMetrics,
1040
+ label: availabilityZoneId + '-' + alb.loadBalancerArn + '-latency-static',
1041
+ period: period,
1042
+ }),
1043
+ evaluationPeriods: evaluationPeriods,
1044
+ datapointsToAlarm: datapointsToAlarm,
1045
+ threshold: outlierThreshold,
1046
+ comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
1047
+ treatMissingData: aws_cloudwatch_1.TreatMissingData.IGNORE
1048
+ });
1049
+ }
1050
+ }
1051
+ static generateLoadBalancerWidgets(albs, azMapper, period, latencyStatistic, latencyThreshold, faultRateThreshold) {
1052
+ let albWidgets = [];
1053
+ let successCountPerZone = ApplicationLoadBalancerMetrics.getTotalAlbSuccessCountPerZone(albs, period, azMapper);
1054
+ let faultCountPerZone = ApplicationLoadBalancerMetrics.getTotalAlbFaultCountPerZone(albs, period, azMapper);
1055
+ let processedBytesPerZone = ApplicationLoadBalancerMetrics.getTotalAlbProcessedBytesPerZone(albs, period, azMapper);
1056
+ let latencyPerZone = ApplicationLoadBalancerMetrics.getTotalAlbLatencyPerZone(albs, latencyStatistic, period, azMapper);
1057
+ let requestsPerZone = ApplicationLoadBalancerMetrics.getTotalAlbRequestsPerZone(albs, period, azMapper);
1058
+ let faultRatePerZone = ApplicationLoadBalancerMetrics.getTotalAlbFaultRatePerZone(albs, period, azMapper);
1059
+ let weightedLatencyZScorePerZone = ApplicationLoadBalancerMetrics.getWeightedLatencyZScorePerZone(albs, latencyStatistic, period, azMapper);
1060
+ albWidgets.push(new aws_cloudwatch_1.GraphWidget({
1061
+ height: 8,
1062
+ width: 8,
1063
+ title: aws_cdk_lib_1.Fn.sub('${AWS::Region} Zonal Success Count'),
1064
+ region: aws_cdk_lib_1.Aws.REGION,
1065
+ left: Object.values(successCountPerZone),
1066
+ leftYAxis: {
1067
+ min: 0,
1068
+ label: 'Count',
1069
+ showUnits: false,
1070
+ }
1071
+ }));
1072
+ albWidgets.push(new aws_cloudwatch_1.GraphWidget({
1073
+ height: 8,
1074
+ width: 8,
1075
+ title: aws_cdk_lib_1.Fn.sub('${AWS::Region} Zonal Target 5xx Count'),
1076
+ region: aws_cdk_lib_1.Aws.REGION,
1077
+ left: Object.values(faultCountPerZone),
1078
+ leftYAxis: {
1079
+ min: 0,
1080
+ label: 'Count',
1081
+ showUnits: false,
1082
+ }
1083
+ }));
1084
+ albWidgets.push(new aws_cloudwatch_1.GraphWidget({
1085
+ height: 8,
1086
+ width: 8,
1087
+ title: aws_cdk_lib_1.Fn.sub('${AWS::Region} Zonal ELB 5xx Count'),
1088
+ region: aws_cdk_lib_1.Aws.REGION,
1089
+ left: Object.values(this.getTotalAlb5xxCountPerZone(albs, period, azMapper)),
1090
+ leftYAxis: {
1091
+ min: 0,
1092
+ label: 'Count',
1093
+ showUnits: false,
1094
+ }
1095
+ }));
1096
+ albWidgets.push(new aws_cloudwatch_1.GraphWidget({
1097
+ height: 8,
1098
+ width: 8,
1099
+ title: aws_cdk_lib_1.Fn.sub('${AWS::Region} Zonal Request Count'),
1100
+ region: aws_cdk_lib_1.Aws.REGION,
1101
+ left: Object.values(requestsPerZone),
1102
+ leftYAxis: {
1103
+ min: 0,
1104
+ label: 'Count',
1105
+ showUnits: false,
1106
+ }
1107
+ }));
1108
+ albWidgets.push(new aws_cloudwatch_1.GraphWidget({
1109
+ height: 8,
1110
+ width: 8,
1111
+ title: aws_cdk_lib_1.Fn.sub('${AWS::Region} Zonal Fault Rate'),
1112
+ region: aws_cdk_lib_1.Aws.REGION,
1113
+ left: Object.values(faultRatePerZone),
1114
+ leftYAxis: {
1115
+ min: 0,
1116
+ label: 'Percent',
1117
+ showUnits: false,
1118
+ },
1119
+ leftAnnotations: [
1120
+ {
1121
+ label: "High Severity",
1122
+ value: faultRateThreshold,
1123
+ color: aws_cloudwatch_1.Color.RED
1124
+ }
1125
+ ]
1126
+ }));
1127
+ albWidgets.push(new aws_cloudwatch_1.GraphWidget({
1128
+ height: 8,
1129
+ width: 8,
1130
+ title: aws_cdk_lib_1.Fn.sub('${AWS::Region} Zonal Processed Bytes'),
1131
+ region: aws_cdk_lib_1.Aws.REGION,
1132
+ left: Object.values(processedBytesPerZone),
1133
+ leftYAxis: {
1134
+ min: 0,
1135
+ showUnits: false,
1136
+ label: 'Bytes'
1137
+ }
1138
+ }));
1139
+ albWidgets.push(new aws_cloudwatch_1.GraphWidget({
1140
+ height: 8,
1141
+ width: 8,
1142
+ title: aws_cdk_lib_1.Fn.sub('${AWS::Region} Zonal Target Response Time (' + latencyStatistic + ')'),
1143
+ region: aws_cdk_lib_1.Aws.REGION,
1144
+ left: Object.values(latencyPerZone),
1145
+ leftYAxis: {
1146
+ min: 0,
1147
+ label: "Milliseconds",
1148
+ showUnits: false,
1149
+ },
1150
+ leftAnnotations: [
1151
+ {
1152
+ label: "High Severity",
1153
+ value: latencyThreshold,
1154
+ color: aws_cloudwatch_1.Color.RED
1155
+ }
1156
+ ]
1157
+ }));
1158
+ albWidgets.push(new aws_cloudwatch_1.GraphWidget({
1159
+ height: 8,
1160
+ width: 8,
1161
+ title: aws_cdk_lib_1.Fn.sub('${AWS::Region} Zonal Latency Z-Score (' + latencyStatistic + ')'),
1162
+ region: aws_cdk_lib_1.Aws.REGION,
1163
+ left: Object.values(weightedLatencyZScorePerZone),
1164
+ leftYAxis: {
1165
+ min: 0,
1166
+ label: "Score",
1167
+ showUnits: false,
1168
+ },
1169
+ leftAnnotations: [
1170
+ {
1171
+ label: "High Severity",
1172
+ value: 3,
1173
+ color: aws_cloudwatch_1.Color.RED
1174
+ }
1175
+ ]
1176
+ }));
1177
+ return albWidgets;
498
1178
  }
499
1179
  }
500
1180
  exports.ApplicationLoadBalancerMetrics = ApplicationLoadBalancerMetrics;
501
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21ldHJpY3MvQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtEQUFrRjtBQUNsRix1RkFBa0o7QUFDbEosZ0ZBQTZFO0FBTzdFLDhEQUEyRDtBQUUzRCxNQUFhLDhCQUE4QjtJQUV2Qzs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxxQkFBcUIsQ0FDeEIsS0FBcUQ7UUFFckQsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FDdkM7WUFDRSxhQUFhLEVBQUU7Z0JBQ2IsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQjtnQkFDeEMsWUFBWSxFQUFHLEtBQUssQ0FBQyxHQUEyQztxQkFDN0Qsb0JBQW9CO2FBQ3hCO1lBQ0QsS0FBSyxFQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEdBQUcsdUJBQXVCO1lBQzdHLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtZQUNwQixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7WUFDMUIsSUFBSSxFQUFFLHFCQUFJLENBQUMsT0FBTztTQUNuQixDQUNGLENBQUM7SUFDUixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILE1BQU0sQ0FBQyx3Q0FBd0MsQ0FDM0MsSUFBZ0MsRUFDaEMsS0FBMEQ7UUFFMUQsSUFBSSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRXhILElBQUks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Q0FBQztDQUNKO0FBem9CRCx3RUF5b0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSU1ldHJpYywgTWF0aEV4cHJlc3Npb24sIFN0YXRzLCBVbml0IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoXCI7XG5pbXBvcnQgeyBCYXNlTG9hZEJhbGFuY2VyLCBIdHRwQ29kZUVsYiwgSHR0cENvZGVUYXJnZXQsIElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgSUxvYWRCYWxhbmNlclYyIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lbGFzdGljbG9hZGJhbGFuY2luZ3YyXCI7XG5pbXBvcnQgeyBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9BdmFpbGFiaWxpdHlNZXRyaWNUeXBlXCI7XG5pbXBvcnQgeyBab25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lNZXRyaWNQcm9wc1wiO1xuaW1wb3J0IHsgWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzXCI7XG5pbXBvcnQgeyBEdXJhdGlvbiB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzXCI7XG5pbXBvcnQgeyBSZWdpb25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lNZXRyaWNQcm9wc1wiO1xuaW1wb3J0IHsgQXZhaWxhYmlsaXR5Wm9uZU1hcHBlciB9IGZyb20gXCIuLi9hem1hcHBlci9BdmFpbGFiaWxpdHlab25lTWFwcGVyXCI7XG5pbXBvcnQgeyBNZXRyaWNzSGVscGVyIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9NZXRyaWNzSGVscGVyXCI7XG5cbmV4cG9ydCBjbGFzcyBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3Mge1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgVGFyZ2V0UmVzcG9uc2VUaW1lIGxhdGVuY3kgZm9yIHRoZSBBTEJcbiAgICAgKiB0YXJnZXRzXG4gICAgICogQHBhcmFtIHByb3BzIFRoZSByZXF1ZXN0IHByb3BzXG4gICAgICogQHJldHVybnMgVGhlIFRhcmdldFJlc3BvbnNlVGltZSBtZXRyaWMgZm9yIHRoZSBBTEIgaW4gdGhlIHNwZWNpZmllZCBBWlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRQZXJBWkxhdGVuY3lNZXRyaWMoXG4gICAgICAgIHByb3BzOiBab25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzXG4gICAgKTogSU1ldHJpYyB7XG4gICAgICAgIHJldHVybiBwcm9wcy5hbGIubWV0cmljcy50YXJnZXRSZXNwb25zZVRpbWUoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKHByb3BzLmFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCA/IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCA6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUgKyBcIi10YXJnZXQtcmVzcG9uc2UtdGltZVwiLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBwcm9wcy5zdGF0aXN0aWMsXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuU0VDT05EU1xuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBlaXRoZXIgdGhlIHN1Y2Nlc3NmdWwsIGZhdWx0LCBvciB0b3RhbCBjb3VudCBtZXRyaWNzXG4gICAgICogZm9yIHRoZSBsb2FkIGJhbGFuY2VyIHRhcmdldHMgYWNyb3NzIGFsbCBvZiB0aGUgcHJvdmlkZWQgXG4gICAgICogQUxCcyBpbiBlYWNoIEFaLlxuICAgICAqIEBwYXJhbSBhbGJzIFRoZSBBTEJzIHRvIGFnZ3JlZ2F0ZSB0aGUgY291bnQgb2ZcbiAgICAgKiBAcGFyYW0gcHJvcHMgVGhlIHJlcXVlc3QgcHJvcHNcbiAgICAgKiBAcmV0dXJucyBUaGUgdG90YWwgY291bnQgb2Ygc3VjZXNzLCBmYXVsdHMsIG9yIHRvdGFsIHJlcXVlc3RzIGluIHRoZSBzcGVjaWZpZWQgQVpcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UGVyQVpBdmFpbGFiaWxpdHlNZXRyaWNDb3VudEFnZ3JlZ2F0ZShcbiAgICAgICAgYWxiczogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyW10sXG4gICAgICAgIHByb3BzOiBab25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5TWV0cmljUHJvcHNcbiAgICApOiBJTWV0cmljIHtcbiAgICAgICAgbGV0IGtleXByZWZpeCA9IHByb3BzLmtleXByZWZpeCA/IHByb3BzLmtleXByZWZpeCA6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKHByb3BzLmF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG5cbiAgICAgICAgbGV0IHVzaW5nTWV0cmljczogeyBba2V5OiBzdHJpbmddOiBJTWV0cmljIH0gPSB7fTtcbiAgICAgICAgbGV0IG1ldHJpY3M6IElNZXRyaWNbXSA9IFtdO1xuXG4gICAgICAgIGFsYnMuZm9yRWFjaCgoYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIpID0+IHtcbiAgICAgICAgICAgIGxldCB0YXJnZXQ1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfNVhYX0NPVU5ULFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItdGFyZ2V0LTV4eFwiLFxuICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAgIGxldCBlbGI1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZUVsYihcbiAgICAgICAgICAgICAgICBIdHRwQ29kZUVsYi5FTEJfNVhYX0NPVU5ULFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItZWxiLTV4eFwiLFxuICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICApO1xuICAgICAgXG4gICAgICAgICAgICAgIGxldCByZXF1ZXN0Q291bnQ6IElNZXRyaWMgPSBhbGIubWV0cmljcy5yZXF1ZXN0Q291bnQoXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi1yZXF1ZXN0LWNvdW50XCIsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKTtcbiAgICAgIFxuICAgICAgICAgICAgICBsZXQgdGFyZ2V0Mnh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzJYWF9DT1VOVCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiArIFwiLXRhcmdldC0yeHhcIixcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICApO1xuICAgICAgXG4gICAgICAgICAgICAgIGxldCBlbGIzeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZUVsYihcbiAgICAgICAgICAgICAgICBIdHRwQ29kZUVsYi5FTEJfM1hYX0NPVU5ULFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItZWxiLTN4eFwiLFxuICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICk7XG4gICAgICBcbiAgICAgICAgICAgICAgbGV0IHRhcmdldDN4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlVGFyZ2V0KFxuICAgICAgICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF8zWFhfQ09VTlQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi10YXJnZXQtM3h4XCIsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKTtcbiAgICAgICBcbiAgICAgICAgICAgICAgc3dpdGNoKHByb3BzLm1ldHJpY1R5cGUpIHtcbiAgICAgICAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5GQVVMVF9DT1VOVDpcbiAgICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IHRhcmdldDV4eDtcbiAgICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IGVsYjV4eDtcbiAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3MucHVzaChuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yYCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi1mYXVsdC1jb3VudFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIFxuICAgICAgICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlQ6XG4gICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQyeHg7XG4gICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQzeHg7XG4gICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSBlbGIzeHg7XG4gICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3MucHVzaChuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yKyR7a2V5cHJlZml4fTNgLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiArIFwiLXN1Y2Nlc3MtY291bnRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuUkVRVUVTVF9DT1VOVDpcbiAgICAgICAgICAgICAgICAgICAgIG1ldHJpY3MucHVzaChyZXF1ZXN0Q291bnQpO1xuICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgbWV0aG9kIG9ubHkgc3VwcG9ydHMgQ09VTlQgYXZhaWxhYmlsaXR5IG1ldHJpY3MuXCIpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGtleXByZWZpeCA9IE1ldHJpY3NIZWxwZXIubmV4dENoYXIoa2V5cHJlZml4KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbWV0cmljcy5mb3JFYWNoKChtZXRyaWM6IElNZXRyaWMsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9JHtpbmRleH1gXSA9IG1ldHJpYztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBleHByZXNzaW9uOiBPYmplY3Qua2V5cyh1c2luZ01ldHJpY3MpLmpvaW4oXCIrXCIpLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIEdldHMgYSBzcGVjaWZpZWQgYXZhaWxhYmlsaXR5IG1ldHJpYyBpbiB0aGUgc3BlY2lmaWVkIEFaIGZvciB0aGUgQUxCXG4gICAgICogQHBhcmFtIGFsYiBUaGUgQUxCXG4gICAgICogQHBhcmFtIHByb3BzIFRoZSByZXF1ZXN0IHByb3BzXG4gICAgICogQHJldHVybnMgVGhlIG1ldHJpYyByZXF1ZXN0ZWRcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UGVyQVpBdmFpbGFiaWxpdHlNZXRyaWMoXG4gICAgICAgIGFsYjogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLCBcbiAgICAgICAgcHJvcHM6IFpvbmFsQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJBdmFpbGFiaWxpdHlNZXRyaWNQcm9wc1xuICAgICk6IElNZXRyaWMge1xuICAgICAgICBsZXQga2V5cHJlZml4ID0gcHJvcHMua2V5cHJlZml4ID8gcHJvcHMua2V5cHJlZml4IDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcocHJvcHMuYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcblxuICAgICAgICBsZXQgdGFyZ2V0NXh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzVYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLXRhcmdldC01eHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIFxuICAgICAgICBsZXQgZWxiNXh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVFbGIoXG4gICAgICAgICAgSHR0cENvZGVFbGIuRUxCXzVYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLWVsYi01eHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgcmVxdWVzdENvdW50OiBJTWV0cmljID0gYWxiLm1ldHJpY3MucmVxdWVzdENvdW50KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItcmVxdWVzdC1jb3VudFwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IHRhcmdldDJ4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlVGFyZ2V0KFxuICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF8yWFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi10YXJnZXQtMnh4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgZWxiM3h4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVFbGIoXG4gICAgICAgICAgSHR0cENvZGVFbGIuRUxCXzNYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLWVsYi0zeHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGxldCB0YXJnZXQzeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfM1hYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItdGFyZ2V0LTN4eFwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IHVzaW5nTWV0cmljczogeyBba2V5OiBzdHJpbmddOiBJTWV0cmljIH0gPSB7fTtcblxuICAgICAgICBzd2l0Y2gocHJvcHMubWV0cmljVHlwZSkge1xuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX0NPVU5UOlxuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gdGFyZ2V0NXh4O1xuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gZWxiNXh4O1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAke2tleXByZWZpeH0xKyR7a2V5cHJlZml4fTJgLFxuICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX1JBVEU6XG4gICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAvLyBSZXF1ZXN0IGNvdW50IG9ubHkgaW5jbHVkZXMgcmVxdWVzdHMgd2hlcmUgYSByZXNwb25zZSB3YXMgZ2VuZXJhdGVkIGZyb20gYSB0YXJnZXRcbiAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQ1eHg7XG4gICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gcmVxdWVzdENvdW50O1xuXG4gICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCgke2tleXByZWZpeH0xLyR7a2V5cHJlZml4fTIpKjEwMGAsXG4gICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlQ6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQyeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQzeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSBlbGIzeHg7XG4gIFxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yKyR7a2V5cHJlZml4fTNgLFxuICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfUkFURTpcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IHRhcmdldDJ4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IHRhcmdldDN4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTNgXSA9IHJlcXVlc3RDb3VudDtcbiAgXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAoKCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9MikvJHtrZXlwcmVmaXh9MykqMTAwYCxcbiAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5SRVFVRVNUX0NPVU5UOlxuICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RDb3VudDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIEFMQnMgc3BlY2lmaWVkIGF2YWlsYWJpbGl0eSBtZXRyaWMgYXQgdGhlIHJlZ2lvbmFsIGxldmVsIChvbmx5IGxvb2tzXG4gICAgICogYXQgdGhlIHJlZ2lvbmFsIGRpbWVuc2lvbiBmb3IgdGhlIHRhcmdldHMsIG5vdCBwZXIgQVopXG4gICAgICogQHBhcmFtIGFsYiBUaGUgQUxCXG4gICAgICogQHBhcmFtIHByb3BzIFRoZSByZXF1ZXN0IHByb3BzXG4gICAgICogQHJldHVybnMgVGhlIHJlZ2lvbmFsIGF2YWlsYWJpbGl0eSBtZXRyaWMgcmVxdWVzdGVkXG4gICAgICovXG4gICAgc3RhdGljIGdldFJlZ2lvbmFsQXZhaWxhYmlsaXR5TWV0cmljKFxuICAgICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgXG4gICAgICAgIHByb3BzOiBSZWdpb25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5TWV0cmljUHJvcHNcbiAgICApOiBJTWV0cmljIHtcbiAgICAgICAgbGV0IGtleXByZWZpeCA9IHByb3BzLmtleXByZWZpeCA/IHByb3BzLmtleXByZWZpeCA6IFwiYVwiO1xuXG4gICAgICAgIGxldCB0YXJnZXQ1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfNVhYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJ0YXJnZXQtNXh4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICBcbiAgICAgICAgbGV0IGVsYjV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl81WFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBcImVsYi01eHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgcmVxdWVzdENvdW50OiBJTWV0cmljID0gYWxiLm1ldHJpY3MucmVxdWVzdENvdW50KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJyZXF1ZXN0LWNvdW50XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgdGFyZ2V0Mnh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzJYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IFwidGFyZ2V0LTJ4eFwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IGVsYjN4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl8zWFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBcImVsYi0zeHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGxldCB0YXJnZXQzeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfM1hYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJ0YXJnZXQtM3h4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuXG4gICAgICAgIHN3aXRjaChwcm9wcy5tZXRyaWNUeXBlKSB7XG4gICAgICAgICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuRkFVTFRfQ09VTlQ6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQ1eHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSBlbGI1eHg7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9MmAsXG4gICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuRkFVTFRfUkFURTpcbiAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gdGFyZ2V0NXh4O1xuICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IHJlcXVlc3RDb3VudDtcblxuICAgICAgICAgICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAoJHtrZXlwcmVmaXh9MS8ke2tleXByZWZpeH0yKSoxMDBgLFxuICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5TVUNDRVNTX0NPVU5UOlxuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gdGFyZ2V0Mnh4O1xuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gdGFyZ2V0M3h4O1xuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9M2BdID0gZWxiM3h4O1xuICBcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9Miske2tleXByZWZpeH0zYCxcbiAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5TVUNDRVNTX1JBVEU6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQyeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQzeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSByZXF1ZXN0Q291bnQ7XG4gIFxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgKCgke2tleXByZWZpeH0xKyR7a2V5cHJlZml4fTIpLyR7a2V5cHJlZml4fTMpKjEwMGAsXG4gICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuUkVRVUVTVF9DT1VOVDpcbiAgICAgICAgICAgICAgIHJldHVybiByZXF1ZXN0Q291bnQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBBTEIncyBUYXJnZXRSZXNwb25zZVRpbWUgbWV0cmljIGF0IHRoZSByZWdpb25hbCBsZXZlbCAob25seSBsb29rc1xuICAgICAqIGF0IHRoZSByZWdpb25hbCBkaW1lbnNpb24gZm9yIHRoZSB0YXJnZXRzLCBub3QgcGVyIEFaKVxuICAgICAqIEBwYXJhbSBwcm9wcyAgVGhlIHJlcXVlc3QgcHJvcHNcbiAgICAgKiBAcmV0dXJucyBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UmVnaW9uYWxMYXRlbmN5TWV0cmljKFxuICAgICAgICBwcm9wczogUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lNZXRyaWNQcm9wc1xuICAgICk6IElNZXRyaWMge1xuICAgICAgICByZXR1cm4gcHJvcHMuYWxiLm1ldHJpY3MudGFyZ2V0UmVzcG9uc2VUaW1lKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAocHJvcHMuYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBsYWJlbDogXCJ0YXJnZXQtcmVzcG9uc2UtdGltZVwiLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBwcm9wcy5zdGF0aXN0aWMsXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuU0VDT05EU1xuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgdG90YWwgbnVtYmVyIG9mIGZhdWx0cyBmb3IgYWxsIEFMQnMgY29tYmluZWQgcGVyIEFaXG4gICAgICogQHBhcmFtIGFsYnMgVGhlIEFMQnMgdG8gYWdncmVnYXRlXG4gICAgICogQHBhcmFtIHBlcmlvZCBUaGUgcGVyaW9kIG9mIHRpbWUgdG8gY2FsY3VsYXRlIHRoZSBtZXRyaWNzXG4gICAgICogQHBhcmFtIGF6TWFwcGVyIFRoZSBBWiBtYXBwZXIgZnVuY3Rpb24gc28gdGhlIG1ldHJpY3MgYXJlIGNvcnJlY3RseSBsYWJlbGVkIHdpdGggdGhlaXIgQVogSURcbiAgICAgKiBAcmV0dXJucyBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0VG90YWxBbGJGYXVsdENvdW50UGVyWm9uZShcbiAgICAgIGFsYnM6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcltdLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgIGF6TWFwcGVyOiBBdmFpbGFiaWxpdHlab25lTWFwcGVyXG4gICAgKSA6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfVxuICAgIHtcbiAgICAgIGxldCBmYXVsdHNQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgIGxldCBtZXRyaWNzUGVyQVo6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljW119ID0ge307XG4gICAgICBsZXQga2V5cHJlZml4OiBzdHJpbmcgPSBNZXRyaWNzSGVscGVyLm5leHRDaGFyKCcnKTtcbiAgXG4gICAgICBhbGJzLmZvckVhY2goKGFsYjogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyKSA9PiB7XG4gIFxuICAgICAgICBhbGIudnBjIS5hdmFpbGFiaWxpdHlab25lcy5mb3JFYWNoKChhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICBpZiAoIShhdmFpbGFiaWxpdHlab25lIGluIG1ldHJpY3NQZXJBWikpIHtcbiAgICAgICAgICAgIG1ldHJpY3NQZXJBWlthdmFpbGFiaWxpdHlab25lXSA9IFtdO1xuICAgICAgICAgIH1cbiAgXG4gICAgICAgICAgbGV0IGF6TGV0dGVyID0gYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcbiAgICAgICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkID0gYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuICBcbiAgICAgICAgICAvLyA1eHggcmVzcG9uc2VzIGZyb20gdGFyZ2V0c1xuICAgICAgICAgIGxldCB0YXJnZXQ1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF81WFhfQ09VTlQsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gICAgICAgIFxuICAgICAgICAgIC8vIDV4eCByZXNwb25zZXMgZnJvbSBFTEJcbiAgICAgICAgICBsZXQgZWxiNXh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVFbGIoXG4gICAgICAgICAgICBIdHRwQ29kZUVsYi5FTEJfNVhYX0NPVU5ULFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICBcbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IGVsYjV4eDtcbiAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IHRhcmdldDV4eDtcbiAgXG4gICAgICAgICAgbWV0cmljc1BlckFaW2F2YWlsYWJpbGl0eVpvbmVdLnB1c2gobmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgIGV4cHJlc3Npb246IGAke2tleXByZWZpeH0xICsgJHtrZXlwcmVmaXh9MmAsXG4gICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kXG4gICAgICAgICAgfSkpO1xuICBcbiAgICAgICAgICBrZXlwcmVmaXggPSBNZXRyaWNzSGVscGVyLm5leHRDaGFyKGtleXByZWZpeCk7XG4gICAgICAgIH0pOyAgIFxuICAgICAgfSk7XG4gIFxuICAgICAgT2JqZWN0LmtleXMobWV0cmljc1BlckFaKS5mb3JFYWNoKChhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgbGV0IGF6TGV0dGVyID0gYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcbiAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcbiAgXG4gICAgICAgIGxldCB1c2luZ01ldHJpY3M6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuICBcbiAgICAgICAgbWV0cmljc1BlckFaW2F2YWlsYWJpbGl0eVpvbmVdLmZvckVhY2goKG1ldHJpYzogSU1ldHJpYykgPT4ge1xuICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gbWV0cmljO1xuICAgICAgICB9KTtcbiAgXG4gICAgICAgIGZhdWx0c1BlclpvbmVbYXZhaWxhYmlsaXR5Wm9uZV0gPSBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgIGV4cHJlc3Npb246IE9iamVjdC5rZXlzKHVzaW5nTWV0cmljcykuam9pbihcIitcIiksXG4gICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLXRvdGFsLWZhdWx0c1wiLFxuICAgICAgICAgIHBlcmlvZDogcGVyaW9kXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIFxuICAgICAgcmV0dXJuIGZhdWx0c1BlclpvbmU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHpvbmFsIHByb2Nlc3NlZCBieXRlcyBtZXRyaWMgZm9yIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlclxuICAgICAqIEBwYXJhbSBsb2FkQmFsYW5jZXJGdWxsTmFtZVxuICAgICAqIEBwYXJhbSBhdmFpbGFiaWxpdHlab25lTmFtZVxuICAgICAqIEBwYXJhbSBwZXJpb2RcbiAgICAgKiBAcmV0dXJucyBJTWV0cmljXG4gICAgICovXG4gICAgc3RhdGljIGdldFBlckFaUHJvY2Vzc2VkQnl0ZXNNZXRyaWMoXG4gICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcixcbiAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZyxcbiAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogc3RyaW5nLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICApOiBJTWV0cmljIHtcbiAgICAgIHJldHVybiBhbGIubWV0cmljcy5wcm9jZXNzZWRCeXRlcyh7XG4gICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgZGltZW5zaW9uc01hcDp7XG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcikubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItcHJvY2Vzc2VkLWJ5dGVzXCJcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB6b25hbCBwcm9jZXNzZWQgYnl0ZXMgbWV0cmljIGZvciB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICAgKiBAcGFyYW0gbG9hZEJhbGFuY2VyRnVsbE5hbWVcbiAgICAgKiBAcGFyYW0gYXZhaWxhYmlsaXR5Wm9uZU5hbWVcbiAgICAgKiBAcGFyYW0gcGVyaW9kXG4gICAgICogQHJldHVybnMgSU1ldHJpY1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSZWdpb25hbFByb2Nlc3NlZEJ5dGVzTWV0cmljKFxuICAgICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcixcbiAgICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgICk6IElNZXRyaWMge1xuICAgICAgICByZXR1cm4gYWxiLm1ldHJpY3MucHJvY2Vzc2VkQnl0ZXMoe1xuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOntcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItcHJvY2Vzc2VkLWJ5dGVzXCJcbiAgICAgICAgfSk7XG4gICAgfVxufSJdfQ==
1181
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21ldHJpY3MvQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtEQUFvSztBQUNwSyx1RkFBa0o7QUFDbEosZ0ZBQTZFO0FBRzdFLDZDQUFnRDtBQUloRCw4REFBMkQ7QUFFM0Qsa0pBQStJO0FBQy9JLHdJQUFxSTtBQUdySSxNQUFhLDhCQUE4QjtJQUV2Qzs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxxQkFBcUIsQ0FDeEIsS0FBcUQ7UUFFckQsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FDdkM7WUFDRSxhQUFhLEVBQUU7Z0JBQ2IsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQjtnQkFDeEMsWUFBWSxFQUFHLEtBQUssQ0FBQyxHQUEyQztxQkFDN0Qsb0JBQW9CO2FBQ3hCO1lBQ0QsS0FBSyxFQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEdBQUcsdUJBQXVCO1lBQzdHLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtZQUNwQixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7WUFDMUIsSUFBSSxFQUFFLHFCQUFJLENBQUMsT0FBTztTQUNuQixDQUNGLENBQUM7SUFDUixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILE1BQU0sQ0FBQyx3Q0FBd0MsQ0FDM0MsSUFBZ0MsRUFDaEMsS0FBMEQ7UUFFMUQsSUFBSSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENB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Q29udGVudCI6WyJpbXBvcnQgeyBBbGFybSwgQ29sb3IsIENvbXBhcmlzb25PcGVyYXRvciwgR3JhcGhXaWRnZXQsIElBbGFybSwgSU1ldHJpYywgSVdpZGdldCwgTWF0aEV4cHJlc3Npb24sIFN0YXRzLCBUcmVhdE1pc3NpbmdEYXRhLCBVbml0IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoXCI7XG5pbXBvcnQgeyBCYXNlTG9hZEJhbGFuY2VyLCBIdHRwQ29kZUVsYiwgSHR0cENvZGVUYXJnZXQsIElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgSUxvYWRCYWxhbmNlclYyIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lbGFzdGljbG9hZGJhbGFuY2luZ3YyXCI7XG5pbXBvcnQgeyBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9BdmFpbGFiaWxpdHlNZXRyaWNUeXBlXCI7XG5pbXBvcnQgeyBab25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lNZXRyaWNQcm9wc1wiO1xuaW1wb3J0IHsgWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvWm9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzXCI7XG5pbXBvcnQgeyBBd3MsIER1cmF0aW9uLCBGbiB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzXCI7XG5pbXBvcnQgeyBSZWdpb25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzIH0gZnJvbSBcIi4uL2Jhc2ljX29ic2VydmFiaWxpdHkvcHJvcHMvUmVnaW9uYWxBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lNZXRyaWNQcm9wc1wiO1xuaW1wb3J0IHsgQXZhaWxhYmlsaXR5Wm9uZU1hcHBlciB9IGZyb20gXCIuLi9hem1hcHBlci9BdmFpbGFiaWxpdHlab25lTWFwcGVyXCI7XG5pbXBvcnQgeyBNZXRyaWNzSGVscGVyIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9NZXRyaWNzSGVscGVyXCI7XG5pbXBvcnQgeyBJQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5T3V0bGllckFsZ29yaXRobSB9IGZyb20gXCIuLi9vdXRsaWVyLWRldGVjdGlvbi9BcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF2YWlsYWJpbGl0eU91dGxpZXJBbGdvcml0aG1cIjtcbmltcG9ydCB7IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU91dGxpZXJBbGdvcml0aG0gfSBmcm9tIFwiLi4vb3V0bGllci1kZXRlY3Rpb24vQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJMYXRlbmN5T3V0bGllckFsZ29yaXRobVwiO1xuaW1wb3J0IHsgSUF2YWlsYWJpbGl0eVpvbmVNYXBwZXIgfSBmcm9tIFwiLi4vYXptYXBwZXIvSUF2YWlsYWJpbGl0eVpvbmVNYXBwZXJcIjtcblxuZXhwb3J0IGNsYXNzIEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTWV0cmljcyB7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBUYXJnZXRSZXNwb25zZVRpbWUgbGF0ZW5jeSBmb3IgdGhlIEFMQlxuICAgICAqIHRhcmdldHNcbiAgICAgKiBAcGFyYW0gcHJvcHMgVGhlIHJlcXVlc3QgcHJvcHNcbiAgICAgKiBAcmV0dXJucyBUaGUgVGFyZ2V0UmVzcG9uc2VUaW1lIG1ldHJpYyBmb3IgdGhlIEFMQiBpbiB0aGUgc3BlY2lmaWVkIEFaXG4gICAgICovXG4gICAgc3RhdGljIGdldFBlckFaTGF0ZW5jeU1ldHJpYyhcbiAgICAgICAgcHJvcHM6IFpvbmFsQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJMYXRlbmN5TWV0cmljUHJvcHNcbiAgICApOiBJTWV0cmljIHtcbiAgICAgICAgcmV0dXJuIHByb3BzLmFsYi5tZXRyaWNzLnRhcmdldFJlc3BvbnNlVGltZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAocHJvcHMuYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkID8gcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkIDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSArIFwiLXRhcmdldC1yZXNwb25zZS10aW1lXCIsXG4gICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICBzdGF0aXN0aWM6IHByb3BzLnN0YXRpc3RpYyxcbiAgICAgICAgICAgICAgdW5pdDogVW5pdC5TRUNPTkRTXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGVpdGhlciB0aGUgc3VjY2Vzc2Z1bCwgZmF1bHQsIG9yIHRvdGFsIGNvdW50IG1ldHJpY3NcbiAgICAgKiBmb3IgdGhlIGxvYWQgYmFsYW5jZXIgdGFyZ2V0cyBhY3Jvc3MgYWxsIG9mIHRoZSBwcm92aWRlZCBcbiAgICAgKiBBTEJzIGluIGVhY2ggQVouXG4gICAgICogQHBhcmFtIGFsYnMgVGhlIEFMQnMgdG8gYWdncmVnYXRlIHRoZSBjb3VudCBvZlxuICAgICAqIEBwYXJhbSBwcm9wcyBUaGUgcmVxdWVzdCBwcm9wc1xuICAgICAqIEByZXR1cm5zIFRoZSB0b3RhbCBjb3VudCBvZiBzdWNlc3MsIGZhdWx0cywgb3IgdG90YWwgcmVxdWVzdHMgaW4gdGhlIHNwZWNpZmllZCBBWlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRQZXJBWkF2YWlsYWJpbGl0eU1ldHJpY0NvdW50QWdncmVnYXRlKFxuICAgICAgICBhbGJzOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJbXSxcbiAgICAgICAgcHJvcHM6IFpvbmFsQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJBdmFpbGFiaWxpdHlNZXRyaWNQcm9wc1xuICAgICk6IElNZXRyaWMge1xuICAgICAgICBsZXQga2V5cHJlZml4ID0gcHJvcHMua2V5cHJlZml4ID8gcHJvcHMua2V5cHJlZml4IDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcocHJvcHMuYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcblxuICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuICAgICAgICBsZXQgbWV0cmljczogSU1ldHJpY1tdID0gW107XG5cbiAgICAgICAgYWxicy5mb3JFYWNoKChhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcikgPT4ge1xuICAgICAgICAgICAgbGV0IHRhcmdldDV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlVGFyZ2V0KFxuICAgICAgICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF81WFhfQ09VTlQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi10YXJnZXQtNXh4XCIsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgICAgbGV0IGVsYjV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl81WFhfQ09VTlQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi1lbGItNXh4XCIsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICk7XG4gICAgICBcbiAgICAgICAgICAgICAgbGV0IHJlcXVlc3RDb3VudDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLnJlcXVlc3RDb3VudChcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiArIFwiLXJlcXVlc3QtY291bnRcIixcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICApO1xuICAgICAgXG4gICAgICAgICAgICAgIGxldCB0YXJnZXQyeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfMlhYX0NPVU5ULFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItdGFyZ2V0LTJ4eFwiLFxuICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICk7XG4gICAgICBcbiAgICAgICAgICAgICAgbGV0IGVsYjN4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl8zWFhfQ09VTlQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi1lbGItM3h4XCIsXG4gICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKTtcbiAgICAgIFxuICAgICAgICAgICAgICBsZXQgdGFyZ2V0M3h4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzNYWF9DT1VOVCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiArIFwiLXRhcmdldC0zeHhcIixcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICApO1xuICAgICAgIFxuICAgICAgICAgICAgICBzd2l0Y2gocHJvcHMubWV0cmljVHlwZSkge1xuICAgICAgICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX0NPVU5UOlxuICAgICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gdGFyZ2V0NXh4O1xuICAgICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gZWxiNXh4O1xuICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgbWV0cmljcy5wdXNoKG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGBGSUxMKCR7a2V5cHJlZml4fTEsIDApICsgRklMTCgke2tleXByZWZpeH0yLCAwKWAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItZmF1bHQtY291bnRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBcbiAgICAgICAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5TVUNDRVNTX0NPVU5UOlxuICAgICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MWBdID0gdGFyZ2V0Mnh4O1xuICAgICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gdGFyZ2V0M3h4O1xuICAgICAgICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9M2BdID0gZWxiM3h4O1xuICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzLnB1c2gobmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9Miske2tleXByZWZpeH0zYCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi1zdWNjZXNzLWNvdW50XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlJFUVVFU1RfQ09VTlQ6XG4gICAgICAgICAgICAgICAgICAgICBtZXRyaWNzLnB1c2gocmVxdWVzdENvdW50KTtcbiAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIG1ldGhvZCBvbmx5IHN1cHBvcnRzIENPVU5UIGF2YWlsYWJpbGl0eSBtZXRyaWNzLlwiKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBrZXlwcmVmaXggPSBNZXRyaWNzSGVscGVyLm5leHRDaGFyKGtleXByZWZpeCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIG1ldHJpY3MuZm9yRWFjaCgobWV0cmljOiBJTWV0cmljLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fSR7aW5kZXh9YF0gPSBtZXRyaWM7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgZXhwcmVzc2lvbjogT2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKFwiK1wiKSxcbiAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBHZXRzIGEgc3BlY2lmaWVkIGF2YWlsYWJpbGl0eSBtZXRyaWMgaW4gdGhlIHNwZWNpZmllZCBBWiBmb3IgdGhlIEFMQlxuICAgICAqIEBwYXJhbSBhbGIgVGhlIEFMQlxuICAgICAqIEBwYXJhbSBwcm9wcyBUaGUgcmVxdWVzdCBwcm9wc1xuICAgICAqIEByZXR1cm5zIFRoZSBtZXRyaWMgcmVxdWVzdGVkXG4gICAgICovXG4gICAgc3RhdGljIGdldFBlckFaQXZhaWxhYmlsaXR5TWV0cmljKFxuICAgICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgXG4gICAgICAgIHByb3BzOiBab25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5TWV0cmljUHJvcHNcbiAgICApOiBJTWV0cmljIHtcbiAgICAgICAgbGV0IGtleXByZWZpeCA9IHByb3BzLmtleXByZWZpeCA/IHByb3BzLmtleXByZWZpeCA6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKHByb3BzLmF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG5cbiAgICAgICAgbGV0IHRhcmdldDV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlVGFyZ2V0KFxuICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF81WFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi10YXJnZXQtNXh4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICBcbiAgICAgICAgbGV0IGVsYjV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl81WFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1lbGItNXh4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IHJlcXVlc3RDb3VudDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLnJlcXVlc3RDb3VudChcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGxldCB0YXJnZXQyeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfMlhYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItdGFyZ2V0LTJ4eFwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IGVsYjN4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl8zWFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5hdmFpbGFiaWxpdHlab25lSWQgKyBcIi1lbGItM3h4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgdGFyZ2V0M3h4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzNYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHByb3BzLmF2YWlsYWJpbGl0eVpvbmVJZCArIFwiLXRhcmdldC0zeHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGxldCB1c2luZ01ldHJpY3M6IHsgW2tleTogc3RyaW5nXTogSU1ldHJpYyB9ID0ge307XG5cbiAgICAgICAgc3dpdGNoKHByb3BzLm1ldHJpY1R5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5GQVVMVF9DT1VOVDpcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IHRhcmdldDV4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IGVsYjV4eDtcblxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgRklMTCgke2tleXByZWZpeH0xLCAwKSArIEZJTEwoJHtrZXlwcmVmaXh9MiwgMClgLFxuICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX1JBVEU6XG4gICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAvLyBSZXF1ZXN0IGNvdW50IG9ubHkgaW5jbHVkZXMgcmVxdWVzdHMgd2hlcmUgYSByZXNwb25zZSB3YXMgZ2VuZXJhdGVkIGZyb20gYSB0YXJnZXRcbiAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQ1eHg7XG4gICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gcmVxdWVzdENvdW50O1xuXG4gICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCgke2tleXByZWZpeH0xLyR7a2V5cHJlZml4fTIpKjEwMGAsXG4gICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlQ6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQyeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQzeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSBlbGIzeHg7XG4gIFxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yKyR7a2V5cHJlZml4fTNgLFxuICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfUkFURTpcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IHRhcmdldDJ4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IHRhcmdldDN4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTNgXSA9IHJlcXVlc3RDb3VudDtcbiAgXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAoKCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9MikvJHtrZXlwcmVmaXh9MykqMTAwYCxcbiAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5SRVFVRVNUX0NPVU5UOlxuICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RDb3VudDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIEFMQnMgc3BlY2lmaWVkIGF2YWlsYWJpbGl0eSBtZXRyaWMgYXQgdGhlIHJlZ2lvbmFsIGxldmVsIChvbmx5IGxvb2tzXG4gICAgICogYXQgdGhlIHJlZ2lvbmFsIGRpbWVuc2lvbiBmb3IgdGhlIHRhcmdldHMsIG5vdCBwZXIgQVopXG4gICAgICogQHBhcmFtIGFsYiBUaGUgQUxCXG4gICAgICogQHBhcmFtIHByb3BzIFRoZSByZXF1ZXN0IHByb3BzXG4gICAgICogQHJldHVybnMgVGhlIHJlZ2lvbmFsIGF2YWlsYWJpbGl0eSBtZXRyaWMgcmVxdWVzdGVkXG4gICAgICovXG4gICAgc3RhdGljIGdldFJlZ2lvbmFsQXZhaWxhYmlsaXR5TWV0cmljKFxuICAgICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgXG4gICAgICAgIHByb3BzOiBSZWdpb25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5TWV0cmljUHJvcHNcbiAgICApOiBJTWV0cmljIHtcbiAgICAgICAgbGV0IGtleXByZWZpeCA9IHByb3BzLmtleXByZWZpeCA/IHByb3BzLmtleXByZWZpeCA6IFwiYVwiO1xuXG4gICAgICAgIGxldCB0YXJnZXQ1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfNVhYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJ0YXJnZXQtNXh4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICBcbiAgICAgICAgbGV0IGVsYjV4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl81WFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBcImVsYi01eHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgcmVxdWVzdENvdW50OiBJTWV0cmljID0gYWxiLm1ldHJpY3MucmVxdWVzdENvdW50KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJyZXF1ZXN0LWNvdW50XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgdGFyZ2V0Mnh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgSHR0cENvZGVUYXJnZXQuVEFSR0VUXzJYWF9DT1VOVCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IFwidGFyZ2V0LTJ4eFwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlRcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IGVsYjN4eDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLmh0dHBDb2RlRWxiKFxuICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl8zWFhfQ09VTlQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBcImVsYi0zeHhcIixcbiAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGxldCB0YXJnZXQzeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfM1hYX0NPVU5ULFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDogXCJ0YXJnZXQtM3h4XCIsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuXG4gICAgICAgIHN3aXRjaChwcm9wcy5tZXRyaWNUeXBlKSB7XG4gICAgICAgICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuRkFVTFRfQ09VTlQ6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQ1eHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSBlbGI1eHg7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYEZJTEwoJHtrZXlwcmVmaXh9MSwgMCkgKyBGSUxMKCR7a2V5cHJlZml4fTIsIDApYCxcbiAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5GQVVMVF9SQVRFOlxuICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQ1eHg7XG4gICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9MmBdID0gcmVxdWVzdENvdW50O1xuXG4gICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogYCgke2tleXByZWZpeH0xLyR7a2V5cHJlZml4fTIpKjEwMGAsXG4gICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgIHBlcmlvZDogcHJvcHMucGVyaW9kLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlQ6XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSB0YXJnZXQyeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSB0YXJnZXQzeHg7XG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0zYF0gPSBlbGIzeHg7XG4gIFxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgJHtrZXlwcmVmaXh9MSske2tleXByZWZpeH0yKyR7a2V5cHJlZml4fTNgLFxuICAgICAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfUkFURTpcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IHRhcmdldDJ4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IHRhcmdldDN4eDtcbiAgICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTNgXSA9IHJlcXVlc3RDb3VudDtcbiAgXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAoKCR7a2V5cHJlZml4fTErJHtrZXlwcmVmaXh9MikvJHtrZXlwcmVmaXh9MykqMTAwYCxcbiAgICAgICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kOiBwcm9wcy5wZXJpb2QsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5SRVFVRVNUX0NPVU5UOlxuICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RDb3VudDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIEFMQidzIFRhcmdldFJlc3BvbnNlVGltZSBtZXRyaWMgYXQgdGhlIHJlZ2lvbmFsIGxldmVsIChvbmx5IGxvb2tzXG4gICAgICogYXQgdGhlIHJlZ2lvbmFsIGRpbWVuc2lvbiBmb3IgdGhlIHRhcmdldHMsIG5vdCBwZXIgQVopXG4gICAgICogQHBhcmFtIHByb3BzICBUaGUgcmVxdWVzdCBwcm9wc1xuICAgICAqIEByZXR1cm5zIFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSZWdpb25hbExhdGVuY3lNZXRyaWMoXG4gICAgICAgIHByb3BzOiBSZWdpb25hbEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU1ldHJpY1Byb3BzXG4gICAgKTogSU1ldHJpYyB7XG4gICAgICAgIHJldHVybiBwcm9wcy5hbGIubWV0cmljcy50YXJnZXRSZXNwb25zZVRpbWUoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChwcm9wcy5hbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGxhYmVsOiBBd3MuUkVHSU9OLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBwcm9wcy5zdGF0aXN0aWMsXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuU0VDT05EU1xuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgdG90YWwgbnVtYmVyIG9mIGZhdWx0cyBmb3IgYWxsIEFMQnMgY29tYmluZWQgcGVyIEFaXG4gICAgICogQHBhcmFtIGFsYnMgVGhlIEFMQnMgdG8gYWdncmVnYXRlXG4gICAgICogQHBhcmFtIHBlcmlvZCBUaGUgcGVyaW9kIG9mIHRpbWUgdG8gY2FsY3VsYXRlIHRoZSBtZXRyaWNzXG4gICAgICogQHBhcmFtIGF6TWFwcGVyIFRoZSBBWiBtYXBwZXIgZnVuY3Rpb24gc28gdGhlIG1ldHJpY3MgYXJlIGNvcnJlY3RseSBsYWJlbGVkIHdpdGggdGhlaXIgQVogSURcbiAgICAgKiBAcmV0dXJucyBcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0VG90YWxBbGJGYXVsdENvdW50UGVyWm9uZShcbiAgICAgIGFsYnM6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcltdLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgIGF6TWFwcGVyOiBBdmFpbGFiaWxpdHlab25lTWFwcGVyLFxuICAgICAgcHJlZml4Pzogc3RyaW5nXG4gICAgKSA6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfVxuICAgIHtcbiAgICAgIGxldCBmYXVsdHNQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgIGxldCBtZXRyaWNzUGVyQVo6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljW119ID0ge307XG4gICAgICBsZXQga2V5cHJlZml4OiBzdHJpbmcgPSBwcmVmaXggPyBwcmVmaXggOiBNZXRyaWNzSGVscGVyLm5leHRDaGFyKCk7XG4gIFxuICAgICAgYWxicy5mb3JFYWNoKChhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgYWxiSW5kZXg6IG51bWJlcikgPT4ge1xuICBcbiAgICAgICAgYWxiLnZwYyEuYXZhaWxhYmlsaXR5Wm9uZXMuZm9yRWFjaCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgbGV0IGF6TGV0dGVyID0gYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcbiAgICAgICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkID0gYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuXG4gICAgICAgICAgaWYgKCEoYXpMZXR0ZXIgaW4gbWV0cmljc1BlckFaKSkge1xuICAgICAgICAgICAgbWV0cmljc1BlckFaW2F6TGV0dGVyXSA9IFtdO1xuICAgICAgICAgIH1cbiAgXG4gICAgICAgICAgLy8gNXh4IHJlc3BvbnNlcyBmcm9tIHRhcmdldHNcbiAgICAgICAgICBsZXQgdGFyZ2V0NXh4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoXG4gICAgICAgICAgICBIdHRwQ29kZVRhcmdldC5UQVJHRVRfNVhYX0NPVU5ULFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICAgICAgICBcbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7YXpMZXR0ZXJ9JHthbGJJbmRleH1fZmF1bHRjb3VudGBdID0gdGFyZ2V0NXh4O1xuICBcbiAgICAgICAgICAvLyBUaGlzIGlzIHRoZSB0b3RhbCBudW1iZXIgb2YgZmF1bHRzIHBlciB6b25lIGZvciB0aGlzIGxvYWQgYmFsYW5jZXJcbiAgICAgICAgICBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdLnB1c2gobmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgIGV4cHJlc3Npb246IGBGSUxMKCR7YXpMZXR0ZXJ9JHthbGJJbmRleH1fZmF1bHRjb3VudCwgMClgLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICBjb2xvcjogTWV0cmljc0hlbHBlci5jb2xvcnNbaW5kZXhdXG4gICAgICAgICAgfSkpO1xuICBcbiAgICAgICAgICBrZXlwcmVmaXggPSBNZXRyaWNzSGVscGVyLm5leHRDaGFyKGtleXByZWZpeCk7XG4gICAgICAgIH0pOyAgIFxuICAgICAgfSk7XG4gIFxuICAgICAgLy8gV2UgY2FuIGhhdmUgbXVsdGlwbGUgbG9hZCBiYWxhbmNlcnMgcGVyIHpvbmUsIHNvIGFkZCB0aGVpciBmYXVsdCBjb3VudFxuICAgICAgLy8gbWV0cmljcyB0b2dldGhlclxuICAgICAgT2JqZWN0LmtleXMobWV0cmljc1BlckFaKS5mb3JFYWNoKChhekxldHRlcjogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQgPSBhek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG5cbiAgICAgICAgaWYgKG1ldHJpY3NQZXJBWlthekxldHRlcl0ubGVuZ3RoID4gMSkge1xuICBcbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICBcbiAgICAgICAgICBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdLmZvckVhY2goKG1ldHJpYzogSU1ldHJpYywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2F6TGV0dGVyfSR7aW5kZXh9X3RvdGFsX2ZhdWx0Y291bnRgXSA9IG1ldHJpYztcbiAgICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgICAgZmF1bHRzUGVyWm9uZVthekxldHRlcl0gPSBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgZXhwcmVzc2lvbjogT2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKFwiK1wiKSxcbiAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGZhdWx0c1BlclpvbmVbYXpMZXR0ZXJdID0gbWV0cmljc1BlckFaW2F6TGV0dGVyXVswXTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gZmF1bHRzUGVyWm9uZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSB0b3RhbCBudW1iZXIgb2YgZmF1bHRzIGZvciBhbGwgQUxCcyBjb21iaW5lZCBwZXIgQVpcbiAgICAgKiBAcGFyYW0gYWxicyBUaGUgQUxCcyB0byBhZ2dyZWdhdGVcbiAgICAgKiBAcGFyYW0gcGVyaW9kIFRoZSBwZXJpb2Qgb2YgdGltZSB0byBjYWxjdWxhdGUgdGhlIG1ldHJpY3NcbiAgICAgKiBAcGFyYW0gYXpNYXBwZXIgVGhlIEFaIG1hcHBlciBmdW5jdGlvbiBzbyB0aGUgbWV0cmljcyBhcmUgY29ycmVjdGx5IGxhYmVsZWQgd2l0aCB0aGVpciBBWiBJRFxuICAgICAqIEByZXR1cm5zIFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRUb3RhbEFsYlN1Y2Nlc3NDb3VudFBlclpvbmUoXG4gICAgICBhbGJzOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJbXSxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBhek1hcHBlcjogQXZhaWxhYmlsaXR5Wm9uZU1hcHBlclxuICAgICkgOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY31cbiAgICB7XG4gICAgICBsZXQgc3VjY2Vzc1BlclpvbmU6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuICAgICAgbGV0IG1ldHJpY3NQZXJBWjoge1trZXk6IHN0cmluZ106IElNZXRyaWNbXX0gPSB7fTtcbiAgICAgIGxldCBrZXlwcmVmaXg6IHN0cmluZyA9IE1ldHJpY3NIZWxwZXIubmV4dENoYXIoKTtcbiAgXG4gICAgICBhbGJzLmZvckVhY2goKGFsYjogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyKSA9PiB7XG4gIFxuICAgICAgICBhbGIudnBjIS5hdmFpbGFiaWxpdHlab25lcy5mb3JFYWNoKChhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICBsZXQgYXpMZXR0ZXIgPSBhdmFpbGFiaWxpdHlab25lLnN1YnN0cmluZyhhdmFpbGFiaWxpdHlab25lLmxlbmd0aCAtIDEpO1xuICAgICAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQgPSBhek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG5cbiAgICAgICAgICBpZiAoIShhekxldHRlciBpbiBtZXRyaWNzUGVyQVopKSB7XG4gICAgICAgICAgICBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdID0gW107XG4gICAgICAgICAgfVxuICBcbiAgICAgICAgICAvLyAyeHggcmVzcG9uc2VzIGZyb20gdGFyZ2V0c1xuICAgICAgICAgIGxldCB0YXJnZXQyeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF8yWFhfQ09VTlQsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICAvLyAzeHggcmVzcG9uc2VzIGZyb20gdGFyZ2V0c1xuICAgICAgICAgIGxldCB0YXJnZXQzeHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZVRhcmdldChcbiAgICAgICAgICAgIEh0dHBDb2RlVGFyZ2V0LlRBUkdFVF8zWFhfQ09VTlQsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gICAgICAgIFxuICAgICAgICAgIC8vIDN4eCByZXNwb25zZXMgZnJvbSBFTEJcbiAgICAgICAgICBsZXQgZWxiM3h4OiBJTWV0cmljID0gYWxiLm1ldHJpY3MuaHR0cENvZGVFbGIoXG4gICAgICAgICAgICBIdHRwQ29kZUVsYi5FTEJfM1hYX0NPVU5ULFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICBcbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IGVsYjN4eDtcbiAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTJgXSA9IHRhcmdldDJ4eDtcbiAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTNgXSA9IHRhcmdldDN4eDtcbiAgXG4gICAgICAgICAgLy8gVGhpcyBpcyB0aGUgdG90YWwgbnVtYmVyIG9mIGZhdWx0cyBwZXIgem9uZSBmb3IgdGhpcyBsb2FkIGJhbGFuY2VyXG4gICAgICAgICAgbWV0cmljc1BlckFaW2F6TGV0dGVyXS5wdXNoKG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBleHByZXNzaW9uOiBgRklMTCgke2tleXByZWZpeH0xLCAwKSArIEZJTEwoJHtrZXlwcmVmaXh9MiwgMCkgKyBGSUxMKCR7a2V5cHJlZml4fTMsIDApYCxcbiAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XVxuICAgICAgICAgIH0pKTtcbiAgXG4gICAgICAgICAga2V5cHJlZml4ID0gTWV0cmljc0hlbHBlci5uZXh0Q2hhcihrZXlwcmVmaXgpO1xuICAgICAgICB9KTsgICBcbiAgICAgIH0pO1xuICBcbiAgICAgIC8vIFdlIGNhbiBoYXZlIG11bHRpcGxlIGxvYWQgYmFsYW5jZXJzIHBlciB6b25lLCBzbyBhZGQgdGhlaXIgc3VjY2VzcyBjb3VudFxuICAgICAgLy8gbWV0cmljcyB0b2dldGhlclxuICAgICAgT2JqZWN0LmtleXMobWV0cmljc1BlckFaKS5mb3JFYWNoKChhekxldHRlcjogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG5cbiAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcbiAgICAgICAgXG4gICAgICAgIGlmIChtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICBcbiAgICAgICAgICBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdLmZvckVhY2goKG1ldHJpYzogSU1ldHJpYywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0ke2luZGV4fWBdID0gbWV0cmljO1xuICAgICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgICBzdWNjZXNzUGVyWm9uZVthekxldHRlcl0gPSBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgZXhwcmVzc2lvbjogT2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKFwiK1wiKSxcbiAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHN1Y2Nlc3NQZXJab25lW2F6TGV0dGVyXSA9IG1ldHJpY3NQZXJBWlthekxldHRlcl1bMF07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIFxuICAgICAgcmV0dXJuIHN1Y2Nlc3NQZXJab25lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZXMgdGhlIHRvdGFsIG51bWJlciBvZiBwcm9jZXNzZWQgYnl0ZXMgZm9yIGFsbCBBTEJzIGluIGVhY2ggem9uZVxuICAgICAqIEBwYXJhbSBhbGJzIFxuICAgICAqIEBwYXJhbSBwZXJpb2QgXG4gICAgICogQHBhcmFtIGF6TWFwcGVyIFxuICAgICAqIEByZXR1cm5zIFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRUb3RhbEFsYlJlcXVlc3RzUGVyWm9uZShcbiAgICAgIGFsYnM6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcltdLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgIGF6TWFwcGVyOiBBdmFpbGFiaWxpdHlab25lTWFwcGVyLFxuICAgICAgcHJlZml4Pzogc3RyaW5nXG4gICAgKSA6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfVxuICAgIHtcbiAgICAgIGxldCByZXF1ZXN0c1BlclpvbmU6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuICAgICAgbGV0IG1ldHJpY3NQZXJBWjoge1trZXk6IHN0cmluZ106IElNZXRyaWNbXX0gPSB7fTtcbiAgICAgIGxldCBrZXlwcmVmaXg6IHN0cmluZyA9IHByZWZpeCA/IHByZWZpeCA6IE1ldHJpY3NIZWxwZXIubmV4dENoYXIoKTtcblxuICAgICAgYWxicy5mb3JFYWNoKChhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcikgPT4ge1xuICBcbiAgICAgICAgYWxiLnZwYyEuYXZhaWxhYmlsaXR5Wm9uZXMuZm9yRWFjaCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgbGV0IGF6TGV0dGVyID0gYXZhaWxhYmlsaXR5Wm9uZS5zdWJzdHJpbmcoYXZhaWxhYmlsaXR5Wm9uZS5sZW5ndGggLSAxKTtcbiAgICAgICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkID0gYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuXG4gICAgICAgICAgaWYgKCEoYXpMZXR0ZXIgaW4gbWV0cmljc1BlckFaKSkge1xuICAgICAgICAgICAgbWV0cmljc1BlckFaW2F6TGV0dGVyXSA9IFtdO1xuICAgICAgICAgIH1cbiAgXG4gICAgICAgICAgbGV0IHJlcXVlc3RDb3VudDogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLnJlcXVlc3RDb3VudChcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgICAgICAgIEF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKVxuICAgICAgICAgICAgICAgICAgLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBTdGF0cy5TVU0sXG4gICAgICAgICAgICAgIHVuaXQ6IFVuaXQuQ09VTlQsXG4gICAgICAgICAgICAgIGNvbG9yOiBNZXRyaWNzSGVscGVyLmNvbG9yc1tpbmRleF1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgXG4gICAgICAgICAgbWV0cmljc1BlckFaW2F6TGV0dGVyXS5wdXNoKHJlcXVlc3RDb3VudCk7XG4gICAgICAgIH0pOyAgIFxuICAgICAgfSk7XG4gIFxuICAgICAgLy8gV2UgY2FuIGhhdmUgbXVsdGlwbGUgbG9hZCBiYWxhbmNlcnMgcGVyIHpvbmUsIHNvIGFkZCB0aGVpciBwcm9jZXNzZWQgYnl0ZXMgdG9nZXRoZXJcbiAgICAgIE9iamVjdC5rZXlzKG1ldHJpY3NQZXJBWikuZm9yRWFjaCgoYXpMZXR0ZXI6IHN0cmluZywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkID0gYXpNYXBwZXIuYXZhaWxhYmlsaXR5Wm9uZUlkRnJvbUF2YWlsYWJpbGl0eVpvbmVMZXR0ZXIoYXpMZXR0ZXIpO1xuXG4gICAgICAgIGlmIChtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdLmxlbmd0aCA+IDEpIHtcbiAgXG4gICAgICAgICAgbGV0IHVzaW5nTWV0cmljczoge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG4gICAgICAgICAgXG4gICAgICAgICAgbWV0cmljc1BlckFaW2F6TGV0dGVyXS5mb3JFYWNoKChtZXRyaWM6IElNZXRyaWMsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgJHtrZXlwcmVmaXh9JHtpbmRleH1gXSA9IG1ldHJpYztcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGtleXByZWZpeCA9IE1ldHJpY3NIZWxwZXIubmV4dENoYXIoa2V5cHJlZml4KTtcbiAgICAgICAgXG4gICAgICAgICAgcmVxdWVzdHNQZXJab25lW2F6TGV0dGVyXSA9IG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBleHByZXNzaW9uOiBPYmplY3Qua2V5cyh1c2luZ01ldHJpY3MpLmpvaW4oXCIrXCIpLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBjb2xvcjogTWV0cmljc0hlbHBlci5jb2xvcnNbaW5kZXhdXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgcmVxdWVzdHNQZXJab25lW2F6TGV0dGVyXSA9IG1ldHJpY3NQZXJBWlthekxldHRlcl1bMF07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICBcbiAgICAgIHJldHVybiByZXF1ZXN0c1BlclpvbmU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgdG90YWwgbnVtYmVyIG9mIHByb2Nlc3NlZCBieXRlcyBmb3IgYWxsIEFMQnMgaW4gZWFjaCB6b25lXG4gICAgICogQHBhcmFtIGFsYnMgXG4gICAgICogQHBhcmFtIHBlcmlvZCBcbiAgICAgKiBAcGFyYW0gYXpNYXBwZXIgXG4gICAgICogQHJldHVybnMgXG4gICAgICovXG4gICAgc3RhdGljIGdldFRvdGFsQWxiUHJvY2Vzc2VkQnl0ZXNQZXJab25lKFxuICAgICAgYWxiczogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyW10sXG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLFxuICAgICAgYXpNYXBwZXI6IEF2YWlsYWJpbGl0eVpvbmVNYXBwZXJcbiAgICApIDoge1trZXk6IHN0cmluZ106IElNZXRyaWN9XG4gICAge1xuICAgICAgbGV0IHByb2Nlc3NlZEJ5dGVzUGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG4gICAgICBsZXQgbWV0cmljc1BlckFaOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY1tdfSA9IHt9O1xuICAgICAgbGV0IGtleXByZWZpeDogc3RyaW5nID0gTWV0cmljc0hlbHBlci5uZXh0Q2hhcigpO1xuICBcbiAgICAgIGFsYnMuZm9yRWFjaCgoYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIpID0+IHtcbiAgXG4gICAgICAgIGFsYi52cGMhLmF2YWlsYWJpbGl0eVpvbmVzLmZvckVhY2goKGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgIGxldCBhekxldHRlciA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcblxuICAgICAgICAgIGlmICghKGF6TGV0dGVyIGluIG1ldHJpY3NQZXJBWikpIHtcbiAgICAgICAgICAgIG1ldHJpY3NQZXJBWlthekxldHRlcl0gPSBbXTtcbiAgICAgICAgICB9XG4gIFxuICAgICAgICAgIGxldCBwcm9jZXNzZWRCeXRlczogSU1ldHJpYyA9IGFsYi5tZXRyaWNzLnByb2Nlc3NlZEJ5dGVzKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVCxcbiAgICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICBcbiAgICAgICAgICBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdLnB1c2gocHJvY2Vzc2VkQnl0ZXMpO1xuICAgICAgICB9KTsgICBcbiAgICAgIH0pO1xuICBcbiAgICAgIC8vIFdlIGNhbiBoYXZlIG11bHRpcGxlIGxvYWQgYmFsYW5jZXJzIHBlciB6b25lLCBzbyBhZGQgdGhlaXIgcHJvY2Vzc2VkIGJ5dGVzIHRvZ2V0aGVyXG4gICAgICBPYmplY3Qua2V5cyhtZXRyaWNzUGVyQVopLmZvckVhY2goKGF6TGV0dGVyOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcblxuICAgICAgICBpZiAobWV0cmljc1BlckFaW2F6TGV0dGVyXS5sZW5ndGggPiAxKSB7XG5cbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICBcbiAgICAgICAgICBtZXRyaWNzUGVyQVpbYXpMZXR0ZXJdLmZvckVhY2goKG1ldHJpYzogSU1ldHJpYywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0ke2luZGV4fWBdID0gbWV0cmljO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAga2V5cHJlZml4ID0gTWV0cmljc0hlbHBlci5uZXh0Q2hhcihrZXlwcmVmaXgpO1xuICAgICAgICBcbiAgICAgICAgICBwcm9jZXNzZWRCeXRlc1BlclpvbmVbYXpMZXR0ZXJdID0gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgIGV4cHJlc3Npb246IE9iamVjdC5rZXlzKHVzaW5nTWV0cmljcykuam9pbihcIitcIiksXG4gICAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgIGNvbG9yOiBNZXRyaWNzSGVscGVyLmNvbG9yc1tpbmRleF1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBwcm9jZXNzZWRCeXRlc1BlclpvbmVbYXpMZXR0ZXJdID0gbWV0cmljc1BlckFaW2F6TGV0dGVyXVswXTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIFxuICAgICAgcmV0dXJuIHByb2Nlc3NlZEJ5dGVzUGVyWm9uZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGVzIGEgd2VpZ2h0ZWQgYXBwcm94aW1hdGlvbiBvZiB0aGUgbGF0ZW5jeSBhdCB0aGUgcHJvdmlkZWQgc3RhdGlzdGljIGZvciBhbGwgQUxCc1xuICAgICAqIGluIGVhY2ggem9uZS5cbiAgICAgKiBAcGFyYW0gYWxicyBcbiAgICAgKiBAcGFyYW0gc3RhdGlzdGljIFxuICAgICAqIEBwYXJhbSBwZXJpb2QgXG4gICAgICogQHBhcmFtIGF6TWFwcGVyIFxuICAgICAqIEByZXR1cm5zIFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRUb3RhbEFsYkxhdGVuY3lQZXJab25lKFxuICAgICAgYWxiczogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyW10sXG4gICAgICBzdGF0aXN0aWM6IHN0cmluZyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBhek1hcHBlcjogQXZhaWxhYmlsaXR5Wm9uZU1hcHBlclxuICAgICkgOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY31cbiAgICB7XG4gICAgICBsZXQgbGF0ZW5jeVBlclpvbmU6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuICAgICAgbGV0IGtleXByZWZpeDogc3RyaW5nID0gTWV0cmljc0hlbHBlci5uZXh0Q2hhcigpO1xuICAgICAgbGV0IHJlcXVlc3RDb3VudHNQZXJBWk1ldHJpY0tleXM6IHtba2V5OiBzdHJpbmddOiBzdHJpbmdbXX0gPSB7fTtcbiAgICAgIGxldCB3ZWlnaHRlZExhdGVuY3lQZXJBWjoge1trZXk6IHN0cmluZ106IElNZXRyaWNbXX0gPSB7fTtcbiAgXG4gICAgICBhbGJzLmZvckVhY2goKGFsYjogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyKSA9PiB7XG4gIFxuICAgICAgICBhbGIudnBjIS5hdmFpbGFiaWxpdHlab25lcy5mb3JFYWNoKChhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcpID0+IHtcblxuICAgICAgICAgIGxldCBhekxldHRlciA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG5cbiAgICAgICAgICBpZiAoIShhekxldHRlciBpbiB3ZWlnaHRlZExhdGVuY3lQZXJBWikpIHtcbiAgICAgICAgICAgIHdlaWdodGVkTGF0ZW5jeVBlckFaW2F6TGV0dGVyXSA9IFtdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghKGF6TGV0dGVyIGluIHJlcXVlc3RDb3VudHNQZXJBWk1ldHJpY0tleXMpKSB7XG4gICAgICAgICAgICByZXF1ZXN0Q291bnRzUGVyQVpNZXRyaWNLZXlzW2F6TGV0dGVyXSA9IFtdO1xuICAgICAgICAgIH1cbiAgIFxuICAgICAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQgPSBhek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG4gIFxuICAgICAgICAgIGxldCBsYXRlbmN5OiBJTWV0cmljID0gYWxiLm1ldHJpY3MudGFyZ2V0UmVzcG9uc2VUaW1lKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgICBzdGF0aXN0aWM6IHN0YXRpc3RpYyxcbiAgICAgICAgICAgICAgdW5pdDogVW5pdC5TRUNPTkRTXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBsZXQgcmVxdWVzdENvdW50OiBJTWV0cmljID0gYWxiLm1ldHJpY3MucmVxdWVzdENvdW50KFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpXG4gICAgICAgICAgICAgICAgICAubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgICBzdGF0aXN0aWM6IFN0YXRzLlNVTSxcbiAgICAgICAgICAgICAgdW5pdDogVW5pdC5DT1VOVFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICAgICAgICBcbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICB1c2luZ01ldHJpY3NbYCR7a2V5cHJlZml4fTFgXSA9IGxhdGVuY3k7XG4gICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSByZXF1ZXN0Q291bnQ7XG5cbiAgICAgICAgICBsZXQgd2VpZ2h0ZWRMYXRlbmN5OiBJTWV0cmljID0gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgIGV4cHJlc3Npb246IGAke2tleXByZWZpeH0xKiR7a2V5cHJlZml4fTJgLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWRcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHdlaWdodGVkTGF0ZW5jeVBlckFaW2F6TGV0dGVyXS5wdXNoKHdlaWdodGVkTGF0ZW5jeSk7XG4gICAgICAgICAgcmVxdWVzdENvdW50c1BlckFaTWV0cmljS2V5c1thekxldHRlcl0ucHVzaChgJHtrZXlwcmVmaXh9MmApO1xuICBcbiAgICAgICAgICBrZXlwcmVmaXggPSBNZXRyaWNzSGVscGVyLm5leHRDaGFyKGtleXByZWZpeCk7XG4gICAgICAgIH0pOyAgIFxuICAgICAgfSk7XG4gIFxuICAgICAgLy8gV2UgY2FuIGhhdmUgbXVsdGlwbGUgbG9hZCBiYWxhbmNlcnMgcGVyIHpvbmUsIGNvbWJpbmUgdGhlaXIgbGF0ZW5jeSBwZXIgem9uZVxuICAgICAgLy8gdG8gZ2V0IGFuIGF2ZXJhZ2UgbGF0ZW5jeSBwZXJjZW50aWxlIGxhdGVuY3ksIGxpa2UgYXZlcmFnZSBwOTlcbiAgICAgIE9iamVjdC5rZXlzKHdlaWdodGVkTGF0ZW5jeVBlckFaKS5mb3JFYWNoKChhekxldHRlcjogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQgPSBhek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG4gIFxuICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcblxuICAgICAgICB3ZWlnaHRlZExhdGVuY3lQZXJBWlthekxldHRlcl0uZm9yRWFjaCgobWV0cmljOiBJTWV0cmljLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0ke2luZGV4fWBdID0gbWV0cmljO1xuICAgICAgICB9KTtcblxuICAgICAgICBsZXQgbnVtZXJhdG9yID0gXCIoXCIgKyBPYmplY3Qua2V5cyh1c2luZ01ldHJpY3MpLmpvaW4oXCIrXCIpICsgXCIpXCI7XG4gICAgICAgIGxldCBkZW5vbWluYXRvcjogc3RyaW5nID0gXCIoXCIgKyByZXF1ZXN0Q291bnRzUGVyQVpNZXRyaWNLZXlzW2F6TGV0dGVyXS5qb2luKFwiK1wiKSArIFwiKVwiO1xuXG4gICAgICAgIGtleXByZWZpeCA9IE1ldHJpY3NIZWxwZXIubmV4dENoYXIoa2V5cHJlZml4KTtcbiAgICAgICAgXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXZSB3YW50IHRvIGNhbGN1bGF0ZSB0aGlzIGZvcm11bGFcbiAgICAgICAgICogXG4gICAgICAgICAqIChwOTlfMSAqIHJlcXVlc3RzXzEgKyBwOTlfMiAqIHJlcXVlc3RzXzIgKyBwOTlfMyAqIHJlcXVlc3RzXzMpIC8gKHJlcXVlc3RzXzEgKyByZXF1ZXN0c18yICsgcmVxdWVzdHNfMylcbiAgICAgICAgICogXG4gICAgICAgICAqIFRoaXMgd2lsbCBwcm92aWRlIGEgcmVxdWVzdCB3ZWlnaHRlZCBhcHByb3hpbWF0aW9uIG9mIHRoZSBwOTlcbiAgICAgICAgICogbGF0ZW5jeSBwZXIgQVpcbiAgICAgICAgICovIFxuICAgICAgICBsYXRlbmN5UGVyWm9uZVthekxldHRlcl0gPSBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgIGV4cHJlc3Npb246IFwiKFwiICsgbnVtZXJhdG9yICsgXCIvXCIgKyBkZW5vbWluYXRvciArIFwiKSAqIDEwMDBcIixcbiAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgIGNvbG9yOiBNZXRyaWNzSGVscGVyLmNvbG9yc1tpbmRleF1cbiAgICAgICAgfSk7XG5cbiAgICAgICAga2V5cHJlZml4ID0gTWV0cmljc0hlbHBlci5uZXh0Q2hhcihrZXlwcmVmaXgpO1xuICAgICAgfSk7XG4gIFxuICAgICAgcmV0dXJuIGxhdGVuY3lQZXJab25lO1xuICAgIH1cblxuICAgIHN0YXRpYyBnZXRXZWlnaHRlZExhdGVuY3laU2NvcmVQZXJab25lKFxuICAgICAgYWxiczogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyW10sXG4gICAgICBzdGF0aXN0aWM6IHN0cmluZyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBhek1hcHBlcjogSUF2YWlsYWJpbGl0eVpvbmVNYXBwZXJcbiAgICApIDoge1trZXk6IHN0cmluZ106IElNZXRyaWN9IHtcblxuICAgICAgbGV0IHdlaWdodGVkTGF0ZW5jeToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0gdGhpcy5nZXRUb3RhbEFsYkxhdGVuY3lQZXJab25lKGFsYnMsIHN0YXRpc3RpYywgcGVyaW9kLCBhek1hcHBlcik7XG4gICAgICBsZXQgenNjb3JlOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgIFxuICAgICAgT2JqZWN0LmtleXMod2VpZ2h0ZWRMYXRlbmN5KS5mb3JFYWNoKChhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgbGV0IGF6TGV0dGVyOiBzdHJpbmcgPSBhdmFpbGFiaWxpdHlab25lLnN1YnN0cmluZyhhdmFpbGFiaWxpdHlab25lLmxlbmd0aCAtIDEpO1xuICAgICAgICBsZXQgYXZhaWxhYmlsaXR5Wm9uZUlkOiBzdHJpbmcgPSBhek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG5cbiAgICAgICAgbGV0IHVzaW5nTWV0cmljczoge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG4gICAgICAgIGxldCBhek1ldHJpY0lkOiBzdHJpbmcgPSBgJHthekxldHRlcn0xX3pzY29yZWA7XG5cbiAgICAgICAgdXNpbmdNZXRyaWNzW2F6TWV0cmljSWRdID0gd2VpZ2h0ZWRMYXRlbmN5W2F2YWlsYWJpbGl0eVpvbmVdO1xuXG4gICAgICAgIE9iamVjdC5rZXlzKHdlaWdodGVkTGF0ZW5jeSkuZm9yRWFjaCgoYXo6IHN0cmluZywgbWV0cmljSW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgIGlmIChheiAhPSBhdmFpbGFiaWxpdHlab25lKSB7XG4gICAgICAgICAgICB1c2luZ01ldHJpY3NbYG90aGVyc18ke2F6TGV0dGVyfSR7bWV0cmljSW5kZXh9YF0gPSB3ZWlnaHRlZExhdGVuY3lbYXpdOyBcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHpzY29yZVthdmFpbGFiaWxpdHlab25lXSA9IG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgZXhwcmVzc2lvbjogYCgke2F6TWV0cmljSWR9IC0gQVZHKE1FVFJJQ1MoXCJvdGhlcnNfJHthekxldHRlcn1cIikpKSAvIEFWRyhTVERERVYoTUVUUklDUyhcIm90aGVyc18ke2F6TGV0dGVyfVwiKSkpYCxcbiAgICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgIGNvbG9yOiBNZXRyaWNzSGVscGVyLmNvbG9yc1tpbmRleF1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHpzY29yZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSBmYXVsdCByYXRlIHBlciBBWlxuICAgICAqIEBwYXJhbSByZXF1ZXN0c1BlclpvbmUgXG4gICAgICogQHBhcmFtIGZhdWx0c1BlclpvbmUgXG4gICAgICogQHBhcmFtIHBlcmlvZCBcbiAgICAgKiBAcGFyYW0gYXpNYXBwZXIgXG4gICAgICogQHJldHVybnMgVGhlIGZhdWx0IHJhdGUgcGVyIEFaIHVzaW5nIHRoZSBBWiBuYW1lIGxldHRlciBhcyB0aGUga2V5IGZvciBlYWNoIG1ldHJpY1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXRUb3RhbEFsYkZhdWx0UmF0ZVBlclpvbmUoXG4gICAgICBhbGJzOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJbXSxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBhek1hcHBlcjogQXZhaWxhYmlsaXR5Wm9uZU1hcHBlcixcbiAgICApIDoge1trZXk6IHN0cmluZ106IElNZXRyaWN9IHtcblxuICAgICAgbGV0IGZhdWx0UmF0ZU1ldHJpY3M6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IHt9O1xuICAgICAgbGV0IHJlcXVlc3RzUGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0gdGhpcy5nZXRUb3RhbEFsYlJlcXVlc3RzUGVyWm9uZShhbGJzLCBwZXJpb2QsIGF6TWFwcGVyLCBcImFcIik7XG4gICAgICBsZXQgZmF1bHRzUGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0gdGhpcy5nZXRUb3RhbEFsYkZhdWx0Q291bnRQZXJab25lKGFsYnMsIHBlcmlvZCwgYXpNYXBwZXIsIFwiZVwiKTtcblxuICAgICAgT2JqZWN0LmtleXMocmVxdWVzdHNQZXJab25lKS5mb3JFYWNoKChrZXk6IHN0cmluZywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICBpZiAoa2V5IGluIGZhdWx0c1BlclpvbmUpIHtcbiAgICAgICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcbiAgICAgICAgICBsZXQga2V5cHJlZml4ID0gJ3onICsga2V5O1xuICAgICAgICAgXG4gICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSBmYXVsdHNQZXJab25lW2tleV07XG4gICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0yYF0gPSByZXF1ZXN0c1BlclpvbmVba2V5XTtcblxuICAgICAgICAgIGxldCB6b25hbEZhdWx0UmF0ZTogSU1ldHJpYyA9IG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBleHByZXNzaW9uOiBgKCR7a2V5cHJlZml4fTEvJHtrZXlwcmVmaXh9MikgKiAxMDBgLFxuICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgIGxhYmVsOiBhek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihrZXkpLFxuICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgZmF1bHRSYXRlTWV0cmljc1trZXldID0gem9uYWxGYXVsdFJhdGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHpvbmUgXCIgKyBrZXkgKyBcIiBpcyBub3QgcHJlc2VudCBpbiB0aGUgZmF1bHRzUGVyWm9uZSBwYXJhbWV0ZXIuXCIpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgT2JqZWN0LmtleXMoZmF1bHRzUGVyWm9uZSkuZm9yRWFjaCgoa2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgaWYgKCEoa2V5IGluIHJlcXVlc3RzUGVyWm9uZSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgem9uZSBcIiArIGtleSArIFwiIGlzIG5vdCBwcmVzZW50IGluIHRoZSByZXF1ZXN0c1BlclpvbmUgcGFyYW1ldGVyLlwiKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBmYXVsdFJhdGVNZXRyaWNzO1xuICAgIH1cblxuICAgIHN0YXRpYyBnZXRUb3RhbEFsYjV4eENvdW50UGVyWm9uZShcbiAgICAgIGFsYnM6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcltdLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgIGF6TWFwcGVyOiBJQXZhaWxhYmlsaXR5Wm9uZU1hcHBlclxuICAgICkgOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30ge1xuXG4gICAgICBsZXQgZmF1bHRzUGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWNbXX0gPSB7fTtcbiAgICAgIGxldCBhZ2dyZWdhdGVGYXVsdHNQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSB7fTtcblxuICAgICAgYWxicy5mb3JFYWNoKChhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcikgPT4ge1xuXG4gICAgICAgIGFsYi52cGM/LmF2YWlsYWJpbGl0eVpvbmVzLmZvckVhY2goKGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZykgPT4ge1xuXG4gICAgICAgICAgaWYgKCEoYXZhaWxhYmlsaXR5Wm9uZSBpbiBmYXVsdHNQZXJab25lKSkge1xuICAgICAgICAgICAgZmF1bHRzUGVyWm9uZVthdmFpbGFiaWxpdHlab25lXSA9IFtdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGxldCBhekxldHRlciA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgbGV0IGF2YWlsYWJpbGl0eVpvbmVJZCA9IGF6TWFwcGVyLmF2YWlsYWJpbGl0eVpvbmVJZEZyb21BdmFpbGFiaWxpdHlab25lTGV0dGVyKGF6TGV0dGVyKTtcblxuICAgICAgICAgIGxldCBlbGI1eHg6IElNZXRyaWMgPSBhbGIubWV0cmljcy5odHRwQ29kZUVsYihcbiAgICAgICAgICAgIEh0dHBDb2RlRWxiLkVMQl81WFhfQ09VTlQsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICAgICAgICBBdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgICAgIExvYWRCYWxhbmNlcjogKGFsYiBhcyBJTG9hZEJhbGFuY2VyVjIgYXMgQmFzZUxvYWRCYWxhbmNlcilcbiAgICAgICAgICAgICAgICAgIC5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICAgIHN0YXRpc3RpYzogU3RhdHMuU1VNLFxuICAgICAgICAgICAgICB1bml0OiBVbml0LkNPVU5UXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBmYXVsdHNQZXJab25lW2F2YWlsYWJpbGl0eVpvbmVdLnB1c2goZWxiNXh4KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgT2JqZWN0LmtleXMoZmF1bHRzUGVyWm9uZSkuZm9yRWFjaCgoYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGxldCBhekxldHRlciA9IGF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKGF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSk7XG4gICAgICAgIGxldCBhdmFpbGFiaWxpdHlab25lSWQgPSBhek1hcHBlci5hdmFpbGFiaWxpdHlab25lSWRGcm9tQXZhaWxhYmlsaXR5Wm9uZUxldHRlcihhekxldHRlcik7XG5cbiAgICAgICAgbGV0IHVzaW5nTWV0cmljczoge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0ge307XG5cbiAgICAgICAgaWYgKGZhdWx0c1BlclpvbmVbYXZhaWxhYmlsaXR5Wm9uZV0ubGVuZ3RoID4gMSkge1xuXG4gICAgICAgICAgZmF1bHRzUGVyWm9uZVthdmFpbGFiaWxpdHlab25lXS5mb3JFYWNoKChtZXRyaWM6IElNZXRyaWMsIGZhdWx0SW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2F6TGV0dGVyfSR7ZmF1bHRJbmRleH1gXSA9IG1ldHJpYztcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGFnZ3JlZ2F0ZUZhdWx0c1BlclpvbmVbYXZhaWxhYmlsaXR5Wm9uZV0gPSBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgZXhwcmVzc2lvbjogT2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKFwiK1wiKSxcbiAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgY29sb3I6IE1ldHJpY3NIZWxwZXIuY29sb3JzW2luZGV4XSxcbiAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWRcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBhZ2dyZWdhdGVGYXVsdHNQZXJab25lW2F2YWlsYWJpbGl0eVpvbmVdID0gZmF1bHRzUGVyWm9uZVthdmFpbGFiaWxpdHlab25lXVswXTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBhZ2dyZWdhdGVGYXVsdHNQZXJab25lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB6b25hbCBwcm9jZXNzZWQgYnl0ZXMgbWV0cmljIGZvciB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICAgKiBAcGFyYW0gbG9hZEJhbGFuY2VyRnVsbE5hbWVcbiAgICAgKiBAcGFyYW0gYXZhaWxhYmlsaXR5Wm9uZU5hbWVcbiAgICAgKiBAcGFyYW0gcGVyaW9kXG4gICAgICogQHJldHVybnMgSU1ldHJpY1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXRQZXJBWlByb2Nlc3NlZEJ5dGVzTWV0cmljKFxuICAgICAgYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsXG4gICAgICBhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcsXG4gICAgICBhdmFpbGFiaWxpdHlab25lSWQ6IHN0cmluZyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBhZGRMb2FkQmFsYW5jZXJBcm5Ub0xhYmVsPzogYm9vbGVhblxuICAgICk6IElNZXRyaWMge1xuICAgICAgcmV0dXJuIGFsYi5tZXRyaWNzLnByb2Nlc3NlZEJ5dGVzKHtcbiAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICBkaW1lbnNpb25zTWFwOntcbiAgICAgICAgICAgICAgTG9hZEJhbGFuY2VyOiAoYWxiIGFzIElMb2FkQmFsYW5jZXJWMiBhcyBCYXNlTG9hZEJhbGFuY2VyKS5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgICAgICAgQXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQgKyAoYWRkTG9hZEJhbGFuY2VyQXJuVG9MYWJlbCA/IFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiA6IFwiXCIpXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgem9uYWwgcHJvY2Vzc2VkIGJ5dGVzIG1ldHJpYyBmb3IgdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyXG4gICAgICogQHBhcmFtIGxvYWRCYWxhbmNlckZ1bGxOYW1lXG4gICAgICogQHBhcmFtIGF2YWlsYWJpbGl0eVpvbmVOYW1lXG4gICAgICogQHBhcmFtIHBlcmlvZFxuICAgICAqIEByZXR1cm5zIElNZXRyaWNcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UmVnaW9uYWxQcm9jZXNzZWRCeXRlc01ldHJpYyhcbiAgICAgICAgYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsXG4gICAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICAgIGFkZExvYWRCYWxhbmNlckFybj86IGJvb2xlYW5cbiAgICAgICk6IElNZXRyaWMge1xuICAgICAgICByZXR1cm4gYWxiLm1ldHJpY3MucHJvY2Vzc2VkQnl0ZXMoe1xuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBkaW1lbnNpb25zTWFwOntcbiAgICAgICAgICAgICAgICBMb2FkQmFsYW5jZXI6IChhbGIgYXMgSUxvYWRCYWxhbmNlclYyIGFzIEJhc2VMb2FkQmFsYW5jZXIpLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiBBd3MuUkVHSU9OICsgKGFkZExvYWRCYWxhbmNlckFybiA/IFwiLVwiICsgYWxiLmxvYWRCYWxhbmNlckFybiA6IFwiXCIpXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVBWkF2YWlsYWJpbGl0eUltcGFjdEFsYXJtKFxuICAgICAgc2NvcGU6IElDb25zdHJ1Y3QsXG4gICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgXG4gICAgICBhdmFpbGFiaWxpdHlab25lSWQ6IHN0cmluZyxcbiAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZyxcbiAgICAgIHRocmVzaG9sZDogbnVtYmVyLFxuICAgICAga2V5cHJlZml4OiBzdHJpbmcsXG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLFxuICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IG51bWJlcixcbiAgICAgIGRhdGFwb2ludHNUb0FsYXJtOiBudW1iZXJcbiAgICApIDogSUFsYXJtIHtcbiAgICAgXG4gICAgICAvLyBDcmVhdGUgYSBmYXVsdCByYXRlIGFsYXJtIGZvciB0aGUgQUxCIGluIHRoZSBzcGVjaWZpZWQgQVpcbiAgICAgIHJldHVybiBuZXcgQWxhcm0oXG4gICAgICAgIHNjb3BlLFxuICAgICAgICBrZXlwcmVmaXggKyAnLWZhdWx0LXJhdGUtYWxhcm0nLFxuICAgICAgICB7XG4gICAgICAgICAgYWxhcm1OYW1lOlxuICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkICsgJy0nICsgYWxiLmxvYWRCYWxhbmNlckFybiArICctZmF1bHQtcmF0ZScsXG4gICAgICAgICAgYWN0aW9uc0VuYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgIG1ldHJpYzogQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmdldFBlckFaQXZhaWxhYmlsaXR5TWV0cmljKGFsYiwge1xuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkICsgJy0nICsgYWxiLmxvYWRCYWxhbmNlckFybiArICctZmF1bHQtcmF0ZScsXG4gICAgICAgICAgICBhdmFpbGFiaWxpdHlab25lOiBhdmFpbGFiaWxpdHlab25lLFxuICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkOiBhdmFpbGFiaWxpdHlab25lSWQsXG4gICAgICAgICAgICBtZXRyaWNUeXBlOiBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX1JBVEVcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBldmFsdWF0aW9uUGVyaW9kczogZXZhbHVhdGlvblBlcmlvZHMsXG4gICAgICAgICAgZGF0YXBvaW50c1RvQWxhcm06IGRhdGFwb2ludHNUb0FsYXJtLFxuICAgICAgICAgIHRocmVzaG9sZDogdGhyZXNob2xkLFxuICAgICAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9USFJFU0hPTEQsXG4gICAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogVHJlYXRNaXNzaW5nRGF0YS5JR05PUkVcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9XG4gIFxuICAgIHN0YXRpYyBjcmVhdGVBWkxhdGVuY3lJbXBhY3RBbGFybShcbiAgICAgIHNjb3BlOiBJQ29uc3RydWN0LFxuICAgICAgYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsIFxuICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkOiBzdHJpbmcsXG4gICAgICBhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcsXG4gICAgICB0aHJlc2hvbGQ6IG51bWJlcixcbiAgICAgIHN0YXRpc3RpYzogc3RyaW5nLFxuICAgICAga2V5cHJlZml4OiBzdHJpbmcsXG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLFxuICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IG51bWJlcixcbiAgICAgIGRhdGFwb2ludHNUb0FsYXJtOiBudW1iZXJcbiAgICApOiBJQWxhcm0ge1xuICAgICAgXG4gICAgICAvLyBDcmVhdGUgYSBmYXVsdCByYXRlIGFsYXJtIGZvciB0aGUgQUxCIGluIHRoZSBzcGVjaWZpZWQgQVpcbiAgICAgIHJldHVybiBuZXcgQWxhcm0oXG4gICAgICAgIHNjb3BlLFxuICAgICAgICBrZXlwcmVmaXggKyAnLWxhdGVuY3ktYWxhcm0nLFxuICAgICAgICB7XG4gICAgICAgICAgYWxhcm1OYW1lOlxuICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkICsgJy0nICsgYWxiLmxvYWRCYWxhbmNlckFybiArICctbGF0ZW5jeScsXG4gICAgICAgICAgYWN0aW9uc0VuYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgIG1ldHJpYzogQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmdldFBlckFaTGF0ZW5jeU1ldHJpYyh7XG4gICAgICAgICAgICBhbGI6IGFsYixcbiAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IGF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICAgICAgICBhdmFpbGFiaWxpdHlab25lSWQ6IGF2YWlsYWJpbGl0eVpvbmVJZCxcbiAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQgKyBcIi1cIiArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyBcIi10YXJnZXQtbGF0ZW5jeVwiLFxuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBzdGF0aXN0aWM6IHN0YXRpc3RpY1xuICAgICAgICAgIH0pLFxuICAgICAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiBldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTogZGF0YXBvaW50c1RvQWxhcm0sXG4gICAgICAgICAgdGhyZXNob2xkOiB0aHJlc2hvbGQsXG4gICAgICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX1RIUkVTSE9MRCxcbiAgICAgICAgICB0cmVhdE1pc3NpbmdEYXRhOiBUcmVhdE1pc3NpbmdEYXRhLklHTk9SRVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cbiAgXG4gICAgc3RhdGljIGNyZWF0ZUFaQXZhaWxhYmlsaXR5T3V0bGllckFsYXJtKFxuICAgICAgc2NvcGU6IElDb25zdHJ1Y3QsXG4gICAgICBhbGI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciwgXG4gICAgICBhbGdvcml0aG06IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXZhaWxhYmlsaXR5T3V0bGllckFsZ29yaXRobSxcbiAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogc3RyaW5nLFxuICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nLFxuICAgICAgdGhyZXNob2xkOiBudW1iZXIsXG4gICAgICBrZXlwcmVmaXg6IHN0cmluZyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICBldmFsdWF0aW9uUGVyaW9kczogbnVtYmVyLFxuICAgICAgZGF0YXBvaW50c1RvQWxhcm06IG51bWJlciAgIFxuICAgICkgOiBJQWxhcm0ge1xuICBcbiAgICAgIGxldCB1c2luZ01ldHJpY3M6IHsgW2tleTogc3RyaW5nXTogSU1ldHJpYyB9ID0ge307XG4gICAgICBsZXQgYXpNZXRyaWNJZDogc3RyaW5nID0gXCJcIjtcbiAgXG4gICAgICBhbGIudnBjIS5hdmFpbGFiaWxpdHlab25lcy5mb3JFYWNoKChhejogc3RyaW5nKSA9PiB7XG4gIFxuICAgICAgICBsZXQgYXpGYXVsdENvdW50ID0gQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmdldFBlckFaQXZhaWxhYmlsaXR5TWV0cmljKFxuICAgICAgICAgIGFsYixcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtZXRyaWNUeXBlOiBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX0NPVU5ULFxuICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZDogYXZhaWxhYmlsaXR5Wm9uZUlkLFxuICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2QsXG4gICAgICAgICAgICBsYWJlbDogYXZhaWxhYmlsaXR5Wm9uZUlkICsgXCItXCIgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgXCItZmF1bHQtY291bnRcIixcbiAgICAgICAgICAgIGtleXByZWZpeDoga2V5cHJlZml4XG4gICAgICAgICAgfVxuICAgICAgICApO1xuICBcbiAgICAgICAga2V5cHJlZml4ID0gTWV0cmljc0hlbHBlci5uZXh0Q2hhcihrZXlwcmVmaXgpO1xuICBcbiAgICAgICAgdXNpbmdNZXRyaWNzW2Ake2tleXByZWZpeH0xYF0gPSBhekZhdWx0Q291bnQ7XG4gIFxuICAgICAgICBpZiAoYXogPT0gYXZhaWxhYmlsaXR5Wm9uZSkge1xuICAgICAgICAgIGF6TWV0cmljSWQgPSBgJHtrZXlwcmVmaXh9MWA7XG4gICAgICAgIH1cbiAgXG4gICAgICAgIGtleXByZWZpeCA9IE1ldHJpY3NIZWxwZXIubmV4dENoYXIoa2V5cHJlZml4KTtcbiAgICAgIH0pO1xuICBcbiAgICAgIHN3aXRjaCAoYWxnb3JpdGhtKSB7XG4gICAgICAgIGNhc2UgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJBdmFpbGFiaWxpdHlPdXRsaWVyQWxnb3JpdGhtLlNUQVRJQzpcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gbmV3IEFsYXJtKFxuICAgICAgICAgICAgc2NvcGUsXG4gICAgICAgICAgICBrZXlwcmVmaXggKyAnLWF2YWlsYWJpbGl0eS1vdXRsaWVyLWFsYXJtJyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWxhcm1OYW1lOlxuICAgICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZCArICctJyArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyAnLWF2YWlsYWJpbGl0eS1pbXBhY3Qtb3V0bGllcicsXG4gICAgICAgICAgICAgIGFjdGlvbnNFbmFibGVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgbWV0cmljOiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGAoJHthek1ldHJpY0lkIX0vKCR7T2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKFwiK1wiKX0pKSAqIDEwMGAsXG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCArICctJyArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyAnLXBlcmNlbnQtb2YtZmF1bHRzJyxcbiAgICAgICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiBldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgICAgICAgICAgZGF0YXBvaW50c1RvQWxhcm06IGRhdGFwb2ludHNUb0FsYXJtLFxuICAgICAgICAgICAgICB0aHJlc2hvbGQ6IHRocmVzaG9sZCxcbiAgICAgICAgICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX09SX0VRVUFMX1RPX1RIUkVTSE9MRCxcbiAgICAgICAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogVHJlYXRNaXNzaW5nRGF0YS5JR05PUkVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgXG4gICAgc3RhdGljIGNyZWF0ZUFaTGF0ZW5jeU91dGxpZXJBbGFybShcbiAgICAgIHNjb3BlOiBJQ29uc3RydWN0LFxuICAgICAgYWxiOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsIFxuICAgICAgYWxnb3JpdGhtOiBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxhdGVuY3lPdXRsaWVyQWxnb3JpdGhtLFxuICAgICAgYXZhaWxhYmlsaXR5Wm9uZUlkOiBzdHJpbmcsXG4gICAgICBhdmFpbGFiaWxpdHlab25lOiBzdHJpbmcsXG4gICAgICBzdGF0aXN0aWM6IHN0cmluZyxcbiAgICAgIGxhdGVuY3lUaHJlc29sZDogbnVtYmVyLFxuICAgICAgb3V0bGllclRocmVzaG9sZDogbnVtYmVyLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbixcbiAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiBudW1iZXIsXG4gICAgICBkYXRhcG9pbnRzVG9BbGFybTogbnVtYmVyLFxuICAgICAga2V5cHJlZml4OiBzdHJpbmdcbiAgICApIDogSUFsYXJtIHtcbiAgXG4gICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuICAgICAgbGV0IGF6TWV0cmljSWQ6IHN0cmluZyA9IFwiXCI7XG4gIFxuICAgICAgc3dpdGNoIChhbGdvcml0aG0pXG4gICAgICB7XG4gICAgICAgIGNhc2UgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJMYXRlbmN5T3V0bGllckFsZ29yaXRobS5aX1NDT1JFOlxuICAgICAgICBkZWZhdWx0OlxuICBcbiAgICAgICAgICBhbGIudnBjIS5hdmFpbGFiaWxpdHlab25lcy5mb3JFYWNoKChhejogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gIFxuICAgICAgICAgICAgLy8gVGFyZ2V0IHJlc3BvbnNlIHRpbWVcbiAgICAgICAgICAgIGxldCB0YXJnZXRSZXNwb25zZVRpbWU6IElNZXRyaWMgPSBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3MuZ2V0UGVyQVpMYXRlbmN5TWV0cmljKHtcbiAgICAgICAgICAgICAgYWxiOiBhbGIsXG4gICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IGF6LFxuICAgICAgICAgICAgICBsYWJlbDogYXogKyBcIi10YXJnZXQtcmVzcG9uc2UtdGltZVwiLFxuICAgICAgICAgICAgICBzdGF0aXN0aWM6IHN0YXRpc3RpYyxcbiAgICAgICAgICAgICAgcGVyaW9kOiBwZXJpb2RcbiAgICAgICAgICAgIH0pO1xuICBcbiAgICAgICAgICAgIGlmIChheiA9PSBhdmFpbGFiaWxpdHlab25lKSB7ICAgICAgIFxuICAgICAgICAgICAgICBhek1ldHJpY0lkID0gYGEke2luZGV4fWBcbiAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzW2BhJHtpbmRleH1gXSA9IHRhcmdldFJlc3BvbnNlVGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYGIke2luZGV4fWBdID0gdGFyZ2V0UmVzcG9uc2VUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICBcbiAgICAgICAgICByZXR1cm4gbmV3IEFsYXJtKFxuICAgICAgICAgICAgc2NvcGUsXG4gICAgICAgICAgICBrZXlwcmVmaXggKyBcIi1sYXRlbmN5LW91dGxpZXItYWxhcm1cIixcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWxhcm1OYW1lOlxuICAgICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZCArICctJyArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyAnLWxhdGVuY3ktaW1wYWN0LW91dGxpZXInLFxuICAgICAgICAgICAgICBhY3Rpb25zRW5hYmxlZDogZmFsc2UsXG4gICAgICAgICAgICAgIG1ldHJpYzogbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgKCR7YXpNZXRyaWNJZCF9IC0gQVZHKE1FVFJJQ1MoXCJiXCIpKSkgLyBBVkcoU1REREVWKE1FVFJJQ1MoXCJiXCIpKSlgLFxuICAgICAgICAgICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBhdmFpbGFiaWxpdHlab25lSWQgKyAnLScgKyBhbGIubG9hZEJhbGFuY2VyQXJuICsgJy1sYXRlbmN5LXotc2NvcmUnLFxuICAgICAgICAgICAgICAgIHBlcmlvZDogcGVyaW9kLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IGV2YWx1YXRpb25QZXJpb2RzLFxuICAgICAgICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTogZGF0YXBvaW50c1RvQWxhcm0sXG4gICAgICAgICAgICAgIHRocmVzaG9sZDogb3V0bGllclRocmVzaG9sZCxcbiAgICAgICAgICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX09SX0VRVUFMX1RPX1RIUkVTSE9MRCxcbiAgICAgICAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogVHJlYXRNaXNzaW5nRGF0YS5JR05PUkVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICBjYXNlIEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTGF0ZW5jeU91dGxpZXJBbGdvcml0aG0uU1RBVElDOlxuICAgICAgICAgIFxuICAgICAgICAgIGFsYi52cGMhLmF2YWlsYWJpbGl0eVpvbmVzLmZvckVhY2goKGF6OiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIC8vIFRhcmdldCByZXNwb25zZSB0aW1lXG4gICAgICAgICAgICBsZXQgdGFyZ2V0UmVzcG9uc2VUaW1lOiBJTWV0cmljID0gQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmdldFBlckFaTGF0ZW5jeU1ldHJpYyh7XG4gICAgICAgICAgICAgIGFsYjogYWxiLFxuICAgICAgICAgICAgICBhdmFpbGFiaWxpdHlab25lOiBheixcbiAgICAgICAgICAgICAgbGFiZWw6IGF6ICsgXCItdGFyZ2V0LXJlc3BvbnNlLXRpbWVcIixcbiAgICAgICAgICAgICAgc3RhdGlzdGljOiBgVEMoJHtsYXRlbmN5VGhyZXNvbGR9OilgLFxuICAgICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZFxuICAgICAgICAgICAgfSk7XG4gIFxuICAgICAgICAgICAgaWYgKGF6ID09IGF2YWlsYWJpbGl0eVpvbmUpIHsgICAgICAgXG4gICAgICAgICAgICAgIGF6TWV0cmljSWQgPSBgYSR7aW5kZXh9YFxuICAgICAgICAgICAgICB1c2luZ01ldHJpY3NbYGEke2luZGV4fWBdID0gdGFyZ2V0UmVzcG9uc2VUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIHVzaW5nTWV0cmljc1tgYiR7aW5kZXh9YF0gPSB0YXJnZXRSZXNwb25zZVRpbWU7XG4gICAgICAgICAgICB9XG4gIFxuICAgICAgICAgIH0pO1xuICBcbiAgICAgICAgICByZXR1cm4gbmV3IEFsYXJtKFxuICAgICAgICAgICAgc2NvcGUsXG4gICAgICAgICAgICBrZXlwcmVmaXggKyBcIi1sYXRlbmN5LW91dGxpZXItYWxhcm1cIixcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWxhcm1OYW1lOlxuICAgICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmVJZCArICctJyArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyAnLWxhdGVuY3ktaW1wYWN0LW91dGxpZXInLFxuICAgICAgICAgICAgICBhY3Rpb25zRW5hYmxlZDogZmFsc2UsXG4gICAgICAgICAgICAgIG1ldHJpYzogbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBgKCR7YXpNZXRyaWNJZH0vKCR7T2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKFwiK1wiKX0pKSAqIDEwMGAsXG4gICAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgICAgICAgICAgbGFiZWw6IGF2YWlsYWJpbGl0eVpvbmVJZCArICctJyArIGFsYi5sb2FkQmFsYW5jZXJBcm4gKyAnLWxhdGVuY3ktc3RhdGljJyxcbiAgICAgICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiBldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgICAgICAgICAgZGF0YXBvaW50c1RvQWxhcm06IGRhdGFwb2ludHNUb0FsYXJtLFxuICAgICAgICAgICAgICB0aHJlc2hvbGQ6IG91dGxpZXJUaHJlc2hvbGQsXG4gICAgICAgICAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9PUl9FUVVBTF9UT19USFJFU0hPTEQsXG4gICAgICAgICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IFRyZWF0TWlzc2luZ0RhdGEuSUdOT1JFXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgZ2VuZXJhdGVMb2FkQmFsYW5jZXJXaWRnZXRzKFxuICAgICAgICBhbGJzOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJbXSxcbiAgICAgICAgYXpNYXBwZXI6IEF2YWlsYWJpbGl0eVpvbmVNYXBwZXIsXG4gICAgICAgIHBlcmlvZDogRHVyYXRpb24sXG4gICAgICAgIGxhdGVuY3lTdGF0aXN0aWM6IHN0cmluZyxcbiAgICAgICAgbGF0ZW5jeVRocmVzaG9sZDogbnVtYmVyLFxuICAgICAgICBmYXVsdFJhdGVUaHJlc2hvbGQ6IG51bWJlclxuICAgICAgKTogSVdpZGdldFtdIHtcbiAgICAgICAgbGV0IGFsYldpZGdldHM6IElXaWRnZXRbXSA9IFtdO1xuICAgIFxuICAgICAgICBsZXQgc3VjY2Vzc0NvdW50UGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0gXG4gICAgICAgICAgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmdldFRvdGFsQWxiU3VjY2Vzc0NvdW50UGVyWm9uZShhbGJzLCBwZXJpb2QsIGF6TWFwcGVyKTtcbiAgICAgICAgbGV0IGZhdWx0Q291bnRQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSBcbiAgICAgICAgICBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3MuZ2V0VG90YWxBbGJGYXVsdENvdW50UGVyWm9uZShhbGJzLCBwZXJpb2QsIGF6TWFwcGVyKTtcbiAgICAgICAgbGV0IHByb2Nlc3NlZEJ5dGVzUGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0gXG4gICAgICAgICAgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmdldFRvdGFsQWxiUHJvY2Vzc2VkQnl0ZXNQZXJab25lKGFsYnMsIHBlcmlvZCwgYXpNYXBwZXIpO1xuICAgICAgICBsZXQgbGF0ZW5jeVBlclpvbmU6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9IFxuICAgICAgICAgIEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTWV0cmljcy5nZXRUb3RhbEFsYkxhdGVuY3lQZXJab25lKGFsYnMsIGxhdGVuY3lTdGF0aXN0aWMsIHBlcmlvZCwgYXpNYXBwZXIpO1xuICAgICAgICBsZXQgcmVxdWVzdHNQZXJab25lOiB7W2tleTogc3RyaW5nXTogSU1ldHJpY30gPSBcbiAgICAgICAgICBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3MuZ2V0VG90YWxBbGJSZXF1ZXN0c1BlclpvbmUoYWxicywgcGVyaW9kLCBhek1hcHBlcik7ICBcbiAgICAgICAgbGV0IGZhdWx0UmF0ZVBlclpvbmU6IHtba2V5OiBzdHJpbmddOiBJTWV0cmljfSA9XG4gICAgICAgICAgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmdldFRvdGFsQWxiRmF1bHRSYXRlUGVyWm9uZShhbGJzLCBwZXJpb2QsIGF6TWFwcGVyKTsgIFxuICAgICAgICBsZXQgd2VpZ2h0ZWRMYXRlbmN5WlNjb3JlUGVyWm9uZToge1trZXk6IHN0cmluZ106IElNZXRyaWN9ID0gXG4gICAgICAgICAgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzLmdldFdlaWdodGVkTGF0ZW5jeVpTY29yZVBlclpvbmUoYWxicywgbGF0ZW5jeVN0YXRpc3RpYywgcGVyaW9kLCBhek1hcHBlcik7XG4gICAgXG4gICAgICAgIGFsYldpZGdldHMucHVzaChcbiAgICAgICAgICBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgICAgICAgaGVpZ2h0OiA4LFxuICAgICAgICAgICAgd2lkdGg6IDgsXG4gICAgICAgICAgICB0aXRsZTogRm4uc3ViKCcke0FXUzo6UmVnaW9ufSBab25hbCBTdWNjZXNzIENvdW50JyksXG4gICAgICAgICAgICByZWdpb246IEF3cy5SRUdJT04sXG4gICAgICAgICAgICBsZWZ0OiBPYmplY3QudmFsdWVzKHN1Y2Nlc3NDb3VudFBlclpvbmUpLFxuICAgICAgICAgICAgbGVmdFlBeGlzOiB7XG4gICAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgICAgbGFiZWw6ICdDb3VudCcsXG4gICAgICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICBcbiAgICAgICAgYWxiV2lkZ2V0cy5wdXNoKFxuICAgICAgICAgIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgICAgICBoZWlnaHQ6IDgsXG4gICAgICAgICAgICB3aWR0aDogOCxcbiAgICAgICAgICAgIHRpdGxlOiBGbi5zdWIoJyR7QVdTOjpSZWdpb259IFpvbmFsIFRhcmdldCA1eHggQ291bnQnKSxcbiAgICAgICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgICAgIGxlZnQ6IE9iamVjdC52YWx1ZXMoZmF1bHRDb3VudFBlclpvbmUpLFxuICAgICAgICAgICAgbGVmdFlBeGlzOiB7XG4gICAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgICAgbGFiZWw6ICdDb3VudCcsXG4gICAgICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcblxuICAgICAgICBhbGJXaWRnZXRzLnB1c2goXG4gICAgICAgICAgbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICAgIGhlaWdodDogOCxcbiAgICAgICAgICAgIHdpZHRoOiA4LFxuICAgICAgICAgICAgdGl0bGU6IEZuLnN1YignJHtBV1M6OlJlZ2lvbn0gWm9uYWwgRUxCIDV4eCBDb3VudCcpLFxuICAgICAgICAgICAgcmVnaW9uOiBBd3MuUkVHSU9OLFxuICAgICAgICAgICAgbGVmdDogT2JqZWN0LnZhbHVlcyh0aGlzLmdldFRvdGFsQWxiNXh4Q291bnRQZXJab25lKGFsYnMsIHBlcmlvZCwgYXpNYXBwZXIpKSxcbiAgICAgICAgICAgIGxlZnRZQXhpczoge1xuICAgICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICAgIGxhYmVsOiAnQ291bnQnLFxuICAgICAgICAgICAgICBzaG93VW5pdHM6IGZhbHNlLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgXG4gICAgICAgIGFsYldpZGdldHMucHVzaChcbiAgICAgICAgICBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgICAgICAgaGVpZ2h0OiA4LFxuICAgICAgICAgICAgd2lkdGg6IDgsXG4gICAgICAgICAgICB0aXRsZTogRm4uc3ViKCcke0FXUzo6UmVnaW9ufSBab25hbCBSZXF1ZXN0IENvdW50JyksXG4gICAgICAgICAgICByZWdpb246IEF3cy5SRUdJT04sXG4gICAgICAgICAgICBsZWZ0OiBPYmplY3QudmFsdWVzKHJlcXVlc3RzUGVyWm9uZSksXG4gICAgICAgICAgICBsZWZ0WUF4aXM6IHtcbiAgICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgICBsYWJlbDogJ0NvdW50JyxcbiAgICAgICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIFxuICAgICAgICBhbGJXaWRnZXRzLnB1c2goXG4gICAgICAgICAgbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICAgIGhlaWdodDogOCxcbiAgICAgICAgICAgIHdpZHRoOiA4LFxuICAgICAgICAgICAgdGl0bGU6IEZuLnN1YignJHtBV1M6OlJlZ2lvbn0gWm9uYWwgRmF1bHQgUmF0ZScpLFxuICAgICAgICAgICAgcmVnaW9uOiBBd3MuUkVHSU9OLFxuICAgICAgICAgICAgbGVmdDogT2JqZWN0LnZhbHVlcyhmYXVsdFJhdGVQZXJab25lKSxcbiAgICAgICAgICAgIGxlZnRZQXhpczoge1xuICAgICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICAgIGxhYmVsOiAnUGVyY2VudCcsXG4gICAgICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGVmdEFubm90YXRpb25zOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogXCJIaWdoIFNldmVyaXR5XCIsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGZhdWx0UmF0ZVRocmVzaG9sZCxcbiAgICAgICAgICAgICAgICBjb2xvcjogQ29sb3IuUkVEXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF0gICAgICAgXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICBcbiAgICAgICAgYWxiV2lkZ2V0cy5wdXNoKFxuICAgICAgICAgIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICAgICAgICBoZWlnaHQ6IDgsXG4gICAgICAgICAgICB3aWR0aDogOCxcbiAgICAgICAgICAgIHRpdGxlOiBGbi5zdWIoJyR7QVdTOjpSZWdpb259IFpvbmFsIFByb2Nlc3NlZCBCeXRlcycpLFxuICAgICAgICAgICAgcmVnaW9uOiBBd3MuUkVHSU9OLFxuICAgICAgICAgICAgbGVmdDogT2JqZWN0LnZhbHVlcyhwcm9jZXNzZWRCeXRlc1BlclpvbmUpLFxuICAgICAgICAgICAgbGVmdFlBeGlzOiB7XG4gICAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgICAgICAgbGFiZWw6ICdCeXRlcydcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIFxuICAgICAgICBhbGJXaWRnZXRzLnB1c2goXG4gICAgICAgICAgbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICAgIGhlaWdodDogOCxcbiAgICAgICAgICAgIHdpZHRoOiA4LFxuICAgICAgICAgICAgdGl0bGU6IEZuLnN1YignJHtBV1M6OlJlZ2lvbn0gWm9uYWwgVGFyZ2V0IFJlc3BvbnNlIFRpbWUgKCcgKyBsYXRlbmN5U3RhdGlzdGljICsgJyknKSxcbiAgICAgICAgICAgIHJlZ2lvbjogQXdzLlJFR0lPTixcbiAgICAgICAgICAgIGxlZnQ6IE9iamVjdC52YWx1ZXMobGF0ZW5jeVBlclpvbmUpLFxuICAgICAgICAgICAgbGVmdFlBeGlzOiB7XG4gICAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgICAgbGFiZWw6IFwiTWlsbGlzZWNvbmRzXCIsXG4gICAgICAgICAgICAgIHNob3dVbml0czogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGVmdEFubm90YXRpb25zOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogXCJIaWdoIFNldmVyaXR5XCIsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGxhdGVuY3lUaHJlc2hvbGQsXG4gICAgICAgICAgICAgICAgY29sb3I6IENvbG9yLlJFRFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcblxuICAgICAgICBhbGJXaWRnZXRzLnB1c2goXG4gICAgICAgICAgbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgICAgICAgIGhlaWdodDogOCxcbiAgICAgICAgICAgIHdpZHRoOiA4LFxuICAgICAgICAgICAgdGl0bGU6IEZuLnN1YignJHtBV1M6OlJlZ2lvbn0gWm9uYWwgTGF0ZW5jeSBaLVNjb3JlICgnICsgbGF0ZW5jeVN0YXRpc3RpYyArICcpJyksXG4gICAgICAgICAgICByZWdpb246IEF3cy5SRUdJT04sXG4gICAgICAgICAgICBsZWZ0OiBPYmplY3QudmFsdWVzKHdlaWdodGVkTGF0ZW5jeVpTY29yZVBlclpvbmUpLFxuICAgICAgICAgICAgbGVmdFlBeGlzOiB7XG4gICAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgICAgbGFiZWw6IFwiU2NvcmVcIixcbiAgICAgICAgICAgICAgc2hvd1VuaXRzOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsZWZ0QW5ub3RhdGlvbnM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGxhYmVsOiBcIkhpZ2ggU2V2ZXJpdHlcIixcbiAgICAgICAgICAgICAgICB2YWx1ZTogMyxcbiAgICAgICAgICAgICAgICBjb2xvcjogQ29sb3IuUkVEXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIFxuICAgICAgICByZXR1cm4gYWxiV2lkZ2V0cztcbiAgICAgIH1cbn1cbiJdfQ==