cdk-monitoring-constructs
Version:
[](https://badge.fury.io/js/cdk-monitoring-constructs) [](https://m
234 lines • 44.1 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Ec2ServiceMonitoring = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
const BaseServiceMetricFactory_1 = require("./BaseServiceMetricFactory");
const common_1 = require("../../common");
const dashboard_1 = require("../../dashboard");
const aws_loadbalancing_1 = require("../aws-loadbalancing");
class Ec2ServiceMonitoring extends common_1.Monitoring {
constructor(scope, props) {
super(scope, props);
this.hasLoadBalancer =
props.loadBalancer !== undefined && props.targetGroup !== undefined;
const namingStrategy = new dashboard_1.MonitoringNamingStrategy({
...props,
namedConstruct: props.ec2Service,
});
this.title = namingStrategy.resolveHumanReadableName();
this.metricFactory = scope.createMetricFactory();
this.baseServiceMetricFactory = new BaseServiceMetricFactory_1.BaseServiceMetricFactory(this.metricFactory, { service: props.ec2Service });
if (this.hasLoadBalancer) {
this.loadBalancerMetricFactory = aws_loadbalancing_1.createLoadBalancerMetricFactory(this.metricFactory, props.loadBalancer, props.targetGroup, props.invertLoadBalancerTaskCountMetricsStatistics);
this.healthyTaskCountMetric =
this.loadBalancerMetricFactory.metricHealthyTaskCount();
this.unhealthyTaskCountMetric =
this.loadBalancerMetricFactory.metricUnhealthyTaskCount();
this.healthyTaskPercentMetric =
this.loadBalancerMetricFactory.metricHealthyTaskInPercent();
this.activeTcpFlowCountMetric =
this.loadBalancerMetricFactory.metricActiveConnectionCount();
this.newTcpFlowCountMetric =
this.loadBalancerMetricFactory.metricNewConnectionCount();
this.unhealthyRoutingFlowCountMetric =
this.loadBalancerMetricFactory.metricUnhealthyRoutingCount();
this.processedBytesMetric =
this.loadBalancerMetricFactory.metricProcessedBytesMin();
}
this.cpuUtilisationMetric =
this.baseServiceMetricFactory.metricClusterCpuUtilisationInPercent();
this.memoryUtilisationMetric =
this.baseServiceMetricFactory.metricClusterMemoryUtilisationInPercent();
this.runningTaskCountMetric =
this.baseServiceMetricFactory.metricRunningTaskCount();
this.ephemeralStorageUsageMetric =
this.baseServiceMetricFactory.metricEphemeralStorageUsageInPercent();
const alarmFactory = this.createAlarmFactory(namingStrategy.resolveAlarmFriendlyName());
this.taskHealthAlarmFactory = new common_1.TaskHealthAlarmFactory(alarmFactory);
this.throughputAlarmFactory = new common_1.ThroughputAlarmFactory(alarmFactory);
this.taskHealthAnnotations = [];
this.usageAlarmFactory = new common_1.UsageAlarmFactory(alarmFactory);
this.cpuUsageAnnotations = [];
this.memoryUsageAnnotations = [];
this.processedBytesAnnotations = [];
if (props.minAutoScalingTaskCount) {
// TODO: use annotation strategy to create neutral annotation
this.taskHealthAnnotations.push({
value: props.minAutoScalingTaskCount,
label: "AutoScaling: Min",
color: common_1.NeutralColor,
});
}
if (props.maxAutoScalingTaskCount) {
// TODO: use annotation strategy to create neutral annotation
this.taskHealthAnnotations.push({
value: props.maxAutoScalingTaskCount,
label: "AutoScaling: Max",
color: common_1.NeutralColor,
});
}
if (this.hasLoadBalancer) {
for (const disambiguator in props.addHealthyTaskCountAlarm) {
const alarmProps = props.addHealthyTaskCountAlarm[disambiguator];
const createdAlarm = this.taskHealthAlarmFactory.addHealthyTaskCountAlarm(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.healthyTaskCountMetric, alarmProps, disambiguator);
this.taskHealthAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addUnhealthyTaskCountAlarm) {
const alarmProps = props.addUnhealthyTaskCountAlarm[disambiguator];
const createdAlarm = this.taskHealthAlarmFactory.addUnhealthyTaskCountAlarm(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.unhealthyTaskCountMetric, alarmProps, disambiguator);
this.taskHealthAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addHealthyTaskPercentAlarm) {
const alarmProps = props.addHealthyTaskPercentAlarm[disambiguator];
const createdAlarm = this.taskHealthAlarmFactory.addHealthyTaskPercentAlarm(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.healthyTaskPercentMetric, alarmProps, disambiguator);
this.addAlarm(createdAlarm);
}
}
for (const disambiguator in props.addCpuUsageAlarm) {
const alarmProps = props.addCpuUsageAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxCpuUsagePercentAlarm(this.cpuUtilisationMetric, alarmProps, disambiguator);
this.cpuUsageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addMemoryUsageAlarm) {
const alarmProps = props.addMemoryUsageAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxMemoryUsagePercentAlarm(this.memoryUtilisationMetric, alarmProps, disambiguator);
this.memoryUsageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addRunningTaskCountAlarm) {
const alarmProps = props.addRunningTaskCountAlarm[disambiguator];
const createdAlarm = this.taskHealthAlarmFactory.addRunningTaskCountAlarm(this.runningTaskCountMetric, alarmProps, disambiguator);
this.taskHealthAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addEphermalStorageUsageAlarm) {
const alarmProps = props.addEphermalStorageUsageAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxDiskUsagePercentAlarm(this.ephemeralStorageUsageMetric, alarmProps, disambiguator);
this.addAlarm(createdAlarm);
}
if (this.hasLoadBalancer) {
for (const disambiguator in props.addMinProcessedBytesAlarm) {
const alarmProps = props.addMinProcessedBytesAlarm[disambiguator];
const createdAlarm = this.throughputAlarmFactory.addMinProcessedBytesAlarm(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.processedBytesMetric, alarmProps, disambiguator);
this.processedBytesAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
}
props.useCreatedAlarms?.consume(this.createdAlarms());
}
summaryWidgets() {
return [
this.createTitleWidget(),
this.createCpuWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
this.createMemoryWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
this.createTaskHealthWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
];
}
widgets() {
const baseWidget = [
this.createTitleWidget(),
this.createCpuWidget(this.hasLoadBalancer ? common_1.QuarterWidth : common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight),
this.createMemoryWidget(this.hasLoadBalancer ? common_1.QuarterWidth : common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight),
];
if (this.hasLoadBalancer) {
return baseWidget.concat([
this.createTcpFlowsWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createTaskHealthWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
]);
}
else {
return baseWidget.concat(this.createTaskHealthWidget(common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight));
}
}
createTitleWidget() {
return new dashboard_1.MonitoringHeaderWidget({
family: "Ec2 Service",
title: this.title,
});
}
createCpuWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "CPU Utilization",
left: [this.cpuUtilisationMetric],
leftYAxis: common_1.PercentageAxisFromZeroToHundred,
leftAnnotations: this.cpuUsageAnnotations,
});
}
createMemoryWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Memory Utilization",
left: [this.memoryUtilisationMetric],
leftYAxis: common_1.PercentageAxisFromZeroToHundred,
leftAnnotations: this.memoryUsageAnnotations,
});
}
createTaskHealthWidget(width, height) {
const left = [this.runningTaskCountMetric];
if (this.healthyTaskCountMetric) {
left.push(this.healthyTaskCountMetric);
}
if (this.unhealthyTaskCountMetric) {
left.push(this.unhealthyTaskCountMetric);
}
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: this.hasLoadBalancer ? "Task Health" : "Task Count",
left,
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.taskHealthAnnotations,
});
}
createTcpFlowsWidget(width, height) {
const left = [];
const right = [];
if (this.activeTcpFlowCountMetric) {
left.push(this.activeTcpFlowCountMetric);
}
if (this.newTcpFlowCountMetric) {
left.push(this.newTcpFlowCountMetric);
}
if (this.unhealthyRoutingFlowCountMetric) {
left.push(this.unhealthyRoutingFlowCountMetric);
}
if (this.processedBytesMetric) {
right.push(this.processedBytesMetric);
}
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "TCP Flows",
left,
leftYAxis: common_1.CountAxisFromZero,
right,
rightYAxis: common_1.SizeAxisBytesFromZero,
});
}
/**
* @deprecated use {@see createTcpFlowsWidget} instead.
*/
createTpcFlowsWidget(width, height) {
return this.createTcpFlowsWidget(width, height);
}
}
exports.Ec2ServiceMonitoring = Ec2ServiceMonitoring;
_a = JSII_RTTI_SYMBOL_1;
Ec2ServiceMonitoring[_a] = { fqn: "cdk-monitoring-constructs.Ec2ServiceMonitoring", version: "9.15.2" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRWMyU2VydmljZU1vbml0b3JpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJFYzJTZXJ2aWNlTW9uaXRvcmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLCtEQUtvQztBQWFwQyx5RUFBc0U7QUFDdEUseUNBdUJzQjtBQUN0QiwrQ0FHeUI7QUFDekIsNERBSzhCO0FBMkc5QixNQUFhLG9CQUFxQixTQUFRLG1CQUFVO0lBNkJsRCxZQUFZLEtBQXNCLEVBQUUsS0FBc0M7UUFDeEUsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVwQixJQUFJLENBQUMsZUFBZTtZQUNsQixLQUFLLENBQUMsWUFBWSxLQUFLLFNBQVMsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFNBQVMsQ0FBQztRQUV0RSxNQUFNLGNBQWMsR0FBRyxJQUFJLG9DQUF3QixDQUFDO1lBQ2xELEdBQUcsS0FBSztZQUNSLGNBQWMsRUFBRSxLQUFLLENBQUMsVUFBVTtTQUNqQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBRXZELElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFDakQsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksbURBQXdCLENBQzFELElBQUksQ0FBQyxhQUFhLEVBQ2xCLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FDOUIsQ0FBQztRQUNGLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUN4QixJQUFJLENBQUMseUJBQXlCLEdBQUcsbURBQStCLENBQzlELElBQUksQ0FBQyxhQUFhLEVBQ2xCLEtBQUssQ0FBQyxZQUFhLEVBQ25CLEtBQUssQ0FBQyxXQUFZLEVBQ2xCLEtBQUssQ0FBQyw0Q0FBNEMsQ0FDbkQsQ0FBQztZQUNGLElBQUksQ0FBQyxzQkFBc0I7Z0JBQ3pCLElBQUksQ0FBQyx5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QUMsSUFBSSxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1NBQ2pEO1FBRUQsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUU7WUFDN0IsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQztTQUN2QztRQUVELE9BQU8sSUFBSSw0QkFBVyxDQUFDO1lBQ3JCLEtBQUs7WUFDTCxNQUFNO1lBQ04sS0FBSyxFQUFFLFdBQVc7WUFDbEIsSUFBSTtZQUNKLFNBQVMsRUFBRSwwQkFBaUI7WUFDNUIsS0FBSztZQUNMLFVBQVUsRUFBRSw4QkFBcUI7U0FDbEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0gsb0JBQW9CLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDaEQsT0FBTyxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2xELENBQUM7O0FBalVILG9EQWtVQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEdyYXBoV2lkZ2V0LFxuICBIb3Jpem9udGFsQW5ub3RhdGlvbixcbiAgSU1ldHJpYyxcbiAgSVdpZGdldCxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoXCI7XG5pbXBvcnQgeyBFYzJTZXJ2aWNlLCBJQmFzZVNlcnZpY2UgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjc1wiO1xuaW1wb3J0IHtcbiAgQXBwbGljYXRpb25Mb2FkQmFsYW5jZWRFYzJTZXJ2aWNlLFxuICBOZXR3b3JrTG9hZEJhbGFuY2VkRWMyU2VydmljZSxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lY3MtcGF0dGVybnNcIjtcbmltcG9ydCB7XG4gIElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcixcbiAgSUFwcGxpY2F0aW9uVGFyZ2V0R3JvdXAsXG4gIElOZXR3b3JrTG9hZEJhbGFuY2VyLFxuICBJTmV0d29ya1RhcmdldEdyb3VwLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjJcIjtcblxuaW1wb3J0IHsgQmFzZVNlcnZpY2VNZXRyaWNGYWN0b3J5IH0gZnJvbSBcIi4vQmFzZVNlcnZpY2VNZXRyaWNGYWN0b3J5XCI7XG5pbXBvcnQge1xuICBCYXNlTW9uaXRvcmluZ1Byb3BzLFxuICBDb3VudEF4aXNGcm9tWmVybyxcbiAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCxcbiAgSGVhbHRoeVRhc2tDb3VudFRocmVzaG9sZCxcbiAgSGVhbHRoeVRhc2tQZXJjZW50VGhyZXNob2xkLFxuICBNZXRyaWNGYWN0b3J5LFxuICBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0LFxuICBNaW5Qcm9jZXNzZWRCeXRlc1RocmVzaG9sZCxcbiAgTW9uaXRvcmluZyxcbiAgTW9uaXRvcmluZ1Njb3BlLFxuICBOZXV0cmFsQ29sb3IsXG4gIFBlcmNlbnRhZ2VBeGlzRnJvbVplcm9Ub0h1bmRyZWQsXG4gIFF1YXJ0ZXJXaWR0aCxcbiAgUnVubmluZ1Rhc2tDb3VudFRocmVzaG9sZCxcbiAgU2l6ZUF4aXNCeXRlc0Zyb21aZXJvLFxuICBUYXNrSGVhbHRoQWxhcm1GYWN0b3J5LFxuICBUaGlyZFdpZHRoLFxuICBUaHJvdWdocHV0QWxhcm1GYWN0b3J5LFxuICBVbmhlYWx0aHlUYXNrQ291bnRUaHJlc2hvbGQsXG4gIFVzYWdlQWxhcm1GYWN0b3J5LFxuICBVc2FnZVRocmVzaG9sZCxcbn0gZnJvbSBcIi4uLy4uL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgTW9uaXRvcmluZ0hlYWRlcldpZGdldCxcbiAgTW9uaXRvcmluZ05hbWluZ1N0cmF0ZWd5LFxufSBmcm9tIFwiLi4vLi4vZGFzaGJvYXJkXCI7XG5pbXBvcnQge1xuICBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgSUxvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnksXG4gIE5ldHdvcmtMb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5UHJvcHMsXG4gIGNyZWF0ZUxvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnksXG59IGZyb20gXCIuLi9hd3MtbG9hZGJhbGFuY2luZ1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VFYzJTZXJ2aWNlQWxhcm1zIHtcbiAgLyoqXG4gICAqIE1pbmltdW0gbnVtYmVyIG9mIHRhc2tzLCBhcyBzcGVjaWZpZWQgaW4geW91ciBhdXRvIHNjYWxpbmcgY29uZmlnLlxuICAgKi9cbiAgcmVhZG9ubHkgbWluQXV0b1NjYWxpbmdUYXNrQ291bnQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBNYXhpbXVtIG51bWJlciBvZiB0YXNrcywgYXMgc3BlY2lmaWVkIGluIHlvdXIgYXV0byBzY2FsaW5nIGNvbmZpZy5cbiAgICovXG4gIHJlYWRvbmx5IG1heEF1dG9TY2FsaW5nVGFza0NvdW50PzogbnVtYmVyO1xuICByZWFkb25seSBhZGRDcHVVc2FnZUFsYXJtPzogUmVjb3JkPHN0cmluZywgVXNhZ2VUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRNZW1vcnlVc2FnZUFsYXJtPzogUmVjb3JkPHN0cmluZywgVXNhZ2VUaHJlc2hvbGQ+O1xuXG4gIC8qKlxuICAgKiBDb250YWluZXIgSW5zaWdodHMgbmVlZHMgdG8gYmUgZW5hYmxlZCBmb3IgdGhlIGNsdXN0ZXIgZm9yIHRoaXMgYWxhcm0uXG4gICAqL1xuICByZWFkb25seSBhZGRSdW5uaW5nVGFza0NvdW50QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBSdW5uaW5nVGFza0NvdW50VGhyZXNob2xkPjtcbiAgLyoqXG4gICAqIENvbnRhaW5lciBJbnNpZ2h0cyBuZWVkcyB0byBiZSBlbmFibGVkIGZvciB0aGUgY2x1c3RlciBmb3IgdGhpcyBhbGFybS5cbiAgICovXG4gIHJlYWRvbmx5IGFkZEVwaGVybWFsU3RvcmFnZVVzYWdlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBVc2FnZVRocmVzaG9sZD47XG59XG5cbi8qKlxuICogTW9uaXRvcmluZyBwcm9wcyBmb3IgYW55IHR5cGUgb2YgRUMyIHNlcnZpY2UuXG4gKi9cbmludGVyZmFjZSBCYXNlRWMyU2VydmljZU1vbml0b3JpbmdQcm9wc1xuICBleHRlbmRzIEJhc2VNb25pdG9yaW5nUHJvcHMsXG4gICAgQmFzZUVjMlNlcnZpY2VBbGFybXMge31cblxuLyoqXG4gKiBNb25pdG9yaW5nIHByb3BzIGZvciBTaW1wbGUgRUMyIHNlcnZpY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2ltcGxlRWMyU2VydmljZU1vbml0b3JpbmdQcm9wc1xuICBleHRlbmRzIEJhc2VFYzJTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzIHtcbiAgcmVhZG9ubHkgZWMyU2VydmljZTogRWMyU2VydmljZTtcbn1cblxuLyoqXG4gKiBCYXNlIG9mIE1vbml0b3JpbmcgcHJvcHMgZm9yIGxvYWQtYmFsYW5jZWQgRUMyIHNlcnZpY2UuXG4gKi9cbmludGVyZmFjZSBCYXNlTG9hZEJhbGFuY2VkRWMyU2VydmljZU1vbml0b3JpbmdQcm9wc1xuICBleHRlbmRzIEJhc2VFYzJTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzIHtcbiAgcmVhZG9ubHkgYWRkSGVhbHRoeVRhc2tDb3VudEFsYXJtPzogUmVjb3JkPHN0cmluZywgSGVhbHRoeVRhc2tDb3VudFRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFVuaGVhbHRoeVRhc2tDb3VudEFsYXJtPzogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBVbmhlYWx0aHlUYXNrQ291bnRUaHJlc2hvbGRcbiAgPjtcbiAgcmVhZG9ubHkgYWRkSGVhbHRoeVRhc2tQZXJjZW50QWxhcm0/OiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIEhlYWx0aHlUYXNrUGVyY2VudFRocmVzaG9sZFxuICA+O1xuICByZWFkb25seSBhZGRNaW5Qcm9jZXNzZWRCeXRlc0FsYXJtPzogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBNaW5Qcm9jZXNzZWRCeXRlc1RocmVzaG9sZFxuICA+O1xuXG4gIC8qKlxuICAgKiBJbnZlcnQgdGhlIHN0YXRpc3RpY3Mgb2YgYEhlYWx0aHlIb3N0Q291bnRgIGFuZCBgVW5IZWFsdGh5SG9zdENvdW50YC5cbiAgICpcbiAgICogV2hlbiBgaW52ZXJ0TG9hZEJhbGFuY2VyVGFza0NvdW50TWV0cmljc1N0YXRpc3RpY3NgIGlzIHNldCB0byBmYWxzZSwgdGhlIG1pbmltdW0gb2YgYEhlYWx0aHlIb3N0Q291bnRgIGFuZCB0aGUgbWF4aW11bSBvZiBgVW5IZWFsdGh5SG9zdENvdW50YCBhcmUgbW9uaXRvcmVkLlxuICAgKiBXaGVuIGBpbnZlcnRMb2FkQmFsYW5jZXJUYXNrQ291bnRNZXRyaWNzU3RhdGlzdGljc2AgaXMgc2V0IHRvIHRydWUsIHRoZSBtYXhpbXVtIG9mIGBIZWFsdGh5SG9zdENvdW50YCBhbmQgdGhlIG1pbmltdW0gb2YgYFVuSGVhbHRoeUhvc3RDb3VudGAgYXJlIG1vbml0b3JlZC5cbiAgICpcbiAgICogYGludmVydExvYWRCYWxhbmNlclRhc2tDb3VudE1ldHJpY3NTdGF0aXN0aWNzYCBpcyByZWNvbW1lbmRlZCB0byBzZXQgdG8gdHJ1ZSBhcyBwZXIgdGhlIGd1aWRlbGluZXMgYXRcbmh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy9sYXRlc3QvbmV0d29yay9sb2FkLWJhbGFuY2VyLWNsb3Vkd2F0Y2gtbWV0cmljcy5odG1sI21ldHJpYy1zdGF0aXN0aWNzXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBpbnZlcnRMb2FkQmFsYW5jZXJUYXNrQ291bnRNZXRyaWNzU3RhdGlzdGljcz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogTW9uaXRvcmluZyBwcm9wcyBmb3IgbG9hZC1iYWxhbmNlZCBFQzIgc2VydmljZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFYzJTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzXG4gIGV4dGVuZHMgQmFzZUxvYWRCYWxhbmNlZEVjMlNlcnZpY2VNb25pdG9yaW5nUHJvcHMge1xuICByZWFkb25seSBlYzJTZXJ2aWNlOlxuICAgIHwgTmV0d29ya0xvYWRCYWxhbmNlZEVjMlNlcnZpY2VcbiAgICB8IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VkRWMyU2VydmljZTtcbn1cblxuLyoqXG4gKiBNb25pdG9yaW5nIHByb3BzIGZvciBFQzIgc2VydmljZSB3aXRoIG5ldHdvcmsgbG9hZCBiYWxhbmNlciBhbmQgcGxhaW4gc2VydmljZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFYzJOZXR3b3JrTG9hZEJhbGFuY2VyTW9uaXRvcmluZ1Byb3BzXG4gIGV4dGVuZHMgTmV0d29ya0xvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgICBCYXNlTG9hZEJhbGFuY2VkRWMyU2VydmljZU1vbml0b3JpbmdQcm9wcyB7XG4gIHJlYWRvbmx5IGVjMlNlcnZpY2U6IEVjMlNlcnZpY2U7XG59XG5cbi8qKlxuICogTW9uaXRvcmluZyBwcm9wcyBmb3IgRUMyIHNlcnZpY2Ugd2l0aCBhcHBsaWNhdGlvbiBsb2FkIGJhbGFuY2VyIGFuZCBwbGFpbiBzZXJ2aWNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVjMkFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTW9uaXRvcmluZ1Byb3BzXG4gIGV4dGVuZHMgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5UHJvcHMsXG4gICAgQmFzZUxvYWRCYWxhbmNlZEVjMlNlcnZpY2VNb25pdG9yaW5nUHJvcHMge1xuICByZWFkb25seSBlYzJTZXJ2aWNlOiBFYzJTZXJ2aWNlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEN1c3RvbUVjMlNlcnZpY2VNb25pdG9yaW5nUHJvcHNcbiAgZXh0ZW5kcyBCYXNlTG9hZEJhbGFuY2VkRWMyU2VydmljZU1vbml0b3JpbmdQcm9wcyB7XG4gIHJlYWRvbmx5IGVjMlNlcnZpY2U6IElCYXNlU2VydmljZTtcbiAgcmVhZG9ubHkgbG9hZEJhbGFuY2VyPzogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyIHwgSU5ldHdvcmtMb2FkQmFsYW5jZXI7XG4gIHJlYWRvbmx5IHRhcmdldEdyb3VwPzogSUFwcGxpY2F0aW9uVGFyZ2V0R3JvdXAgfCBJTmV0d29ya1RhcmdldEdyb3VwO1xufVxuXG5leHBvcnQgY2xhc3MgRWMyU2VydmljZU1vbml0b3JpbmcgZXh0ZW5kcyBNb25pdG9yaW5nIHtcbiAgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcblxuICByZWFkb25seSBtZXRyaWNGYWN0b3J5OiBNZXRyaWNGYWN0b3J5O1xuICByZWFkb25seSBiYXNlU2VydmljZU1ldHJpY0ZhY3Rvcnk6IEJhc2VTZXJ2aWNlTWV0cmljRmFjdG9yeTtcbiAgcmVhZG9ubHkgbG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeT86IElMb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5O1xuXG4gIHJlYWRvbmx5IHRhc2tIZWFsdGhBbGFybUZhY3Rvcnk6IFRhc2tIZWFsdGhBbGFybUZhY3Rvcnk7XG4gIHJlYWRvbmx5IHRocm91Z2hwdXRBbGFybUZhY3Rvcnk6IFRocm91Z2hwdXRBbGFybUZhY3Rvcnk7XG4gIHJlYWRvbmx5IHRhc2tIZWFsdGhBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgdXNhZ2VBbGFybUZhY3Rvcnk6IFVzYWdlQWxhcm1GYWN0b3J5O1xuICByZWFkb25seSBjcHVVc2FnZUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICByZWFkb25seSBtZW1vcnlVc2FnZUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICByZWFkb25seSBwcm9jZXNzZWRCeXRlc0Fubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuXG4gIHJlYWRvbmx5IGhlYWx0aHlUYXNrQ291bnRNZXRyaWM/OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSB1bmhlYWx0aHlUYXNrQ291bnRNZXRyaWM/OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBoZWFsdGh5VGFza1BlcmNlbnRNZXRyaWM/OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBjcHVVdGlsaXNhdGlvbk1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbWVtb3J5VXRpbGlzYXRpb25NZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IHJ1bm5pbmdUYXNrQ291bnRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGVwaGVtZXJhbFN0b3JhZ2VVc2FnZU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgYWN0aXZlVGNwRmxvd0NvdW50TWV0cmljPzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbmV3VGNwRmxvd0NvdW50TWV0cmljPzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgdW5oZWFsdGh5Um91dGluZ0Zsb3dDb3VudE1ldHJpYz86IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IHByb2Nlc3NlZEJ5dGVzTWV0cmljPzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcblxuICBwcml2YXRlIGhhc0xvYWRCYWxhbmNlcjogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogTW9uaXRvcmluZ1Njb3BlLCBwcm9wczogQ3VzdG9tRWMyU2VydmljZU1vbml0b3JpbmdQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBwcm9wcyk7XG5cbiAgICB0aGlzLmhhc0xvYWRCYWxhbmNlciA9XG4gICAgICBwcm9wcy5sb2FkQmFsYW5jZXIgIT09IHVuZGVmaW5lZCAmJiBwcm9wcy50YXJnZXRHcm91cCAhPT0gdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgbmFtaW5nU3RyYXRlZ3kgPSBuZXcgTW9uaXRvcmluZ05hbWluZ1N0cmF0ZWd5KHtcbiAgICAgIC4uLnByb3BzLFxuICAgICAgbmFtZWRDb25zdHJ1Y3Q6IHByb3BzLmVjMlNlcnZpY2UsXG4gICAgfSk7XG4gICAgdGhpcy50aXRsZSA9IG5hbWluZ1N0cmF0ZWd5LnJlc29sdmVIdW1hblJlYWRhYmxlTmFtZSgpO1xuXG4gICAgdGhpcy5tZXRyaWNGYWN0b3J5ID0gc2NvcGUuY3JlYXRlTWV0cmljRmFjdG9yeSgpO1xuICAgIHRoaXMuYmFzZVNlcnZpY2VNZXRyaWNGYWN0b3J5ID0gbmV3IEJhc2VTZXJ2aWNlTWV0cmljRmFjdG9yeShcbiAgICAgIHRoaXMubWV0cmljRmFjdG9yeSxcbiAgICAgIHsgc2VydmljZTogcHJvcHMuZWMyU2VydmljZSB9LFxuICAgICk7XG4gICAgaWYgKHRoaXMuaGFzTG9hZEJhbGFuY2VyKSB7XG4gICAgICB0aGlzLmxvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnkgPSBjcmVhdGVMb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5KFxuICAgICAgICB0aGlzLm1ldHJpY0ZhY3RvcnksXG4gICAgICAgIHByb3BzLmxvYWRCYWxhbmNlciEsXG4gICAgICAgIHByb3BzLnRhcmdldEdyb3VwISxcbiAgICAgICAgcHJvcHMuaW52ZXJ0TG9hZEJhbGFuY2VyVGFza0NvdW50TWV0cmljc1N0YXRpc3RpY3MsXG4gICAgICApO1xuICAgICAgdGhpcy5oZWFsdGh5VGFza0NvdW50TWV0cmljID1cbiAgICAgICAgdGhpcy5sb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5Lm1ldHJpY0hlYWx0aHlUYXNrQ291bnQoKTtcbiAgICAgIHRoaXMudW5oZWFsdGh5VGFza0NvdW50TWV0cmljID1cbiAgICAgICAgdGhpcy5sb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5Lm1ldHJpY1VuaGVhbHRoeVRhc2tDb3VudCgpO1xuICAgICAgdGhpcy5oZWFsdGh5VGFza1BlcmNlbnRNZXRyaWMgPVxuICAgICAgICB0aGlzLmxvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnkubWV0cmljSGVhbHRoeVRhc2tJblBlcmNlbnQoKTtcbiAgICAgIHRoaXMuYWN0aXZlVGNwRmxvd0NvdW50TWV0cmljID1cbiAgICAgICAgdGhpcy5sb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5Lm1ldHJpY0FjdGl2ZUNvbm5lY3Rpb25Db3VudCgpO1xuICAgICAgdGhpcy5uZXdUY3BGbG93Q291bnRNZXRyaWMgPVxuICAgICAgICB0aGlzLmxvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnkubWV0cmljTmV3Q29ubmVjdGlvbkNvdW50KCk7XG4gICAgICB0aGlzLnVuaGVhbHRoeVJvdXRpbmdGbG93Q291bnRNZXRyaWMgPVxuICAgICAgICB0aGlzLmxvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnkubWV0cmljVW5oZWFsdGh5Um91dGluZ0NvdW50KCk7XG4gICAgICB0aGlzLnByb2Nlc3NlZEJ5dGVzTWV0cmljID1cbiAgICAgICAgdGhpcy5sb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5Lm1ldHJpY1Byb2Nlc3NlZEJ5dGVzTWluKCk7XG4gICAgfVxuICAgIHRoaXMuY3B1VXRpbGlzYXRpb25NZXRyaWMgPVxuICAgICAgdGhpcy5iYXNlU2VydmljZU1ldHJpY0ZhY3RvcnkubWV0cmljQ2x1c3RlckNwdVV0aWxpc2F0aW9uSW5QZXJjZW50KCk7XG4gICAgdGhpcy5tZW1vcnlVdGlsaXNhdGlvbk1ldHJpYyA9XG4gICAgICB0aGlzLmJhc2VTZXJ2aWNlTWV0cmljRmFjdG9yeS5tZXRyaWNDbHVzdGVyTWVtb3J5VXRpbGlzYXRpb25JblBlcmNlbnQoKTtcbiAgICB0aGlzLnJ1bm5pbmdUYXNrQ291bnRNZXRyaWMgPVxuICAgICAgdGhpcy5iYXNlU2VydmljZU1ldHJpY0ZhY3RvcnkubWV0cmljUnVubmluZ1Rhc2tDb3VudCgpO1xuICAgIHRoaXMuZXBoZW1lcmFsU3RvcmFnZVVzYWdlTWV0cmljID1cbiAgICAgIHRoaXMuYmFzZVNlcnZpY2VNZXRyaWNGYWN0b3J5Lm1ldHJpY0VwaGVtZXJhbFN0b3JhZ2VVc2FnZUluUGVyY2VudCgpO1xuXG4gICAgY29uc3QgYWxhcm1GYWN0b3J5ID0gdGhpcy5jcmVhdGVBbGFybUZhY3RvcnkoXG4gICAgICBuYW1pbmdTdHJhdGVneS5yZXNvbHZlQWxhcm1GcmllbmRseU5hbWUoKSxcbiAgICApO1xuICAgIHRoaXMudGFza0hlYWx0aEFsYXJtRmFjdG9yeSA9IG5ldyBUYXNrSGVhbHRoQWxhcm1GYWN0b3J5KGFsYXJtRmFjdG9yeSk7XG4gICAgdGhpcy50aHJvdWdocHV0QWxhcm1GYWN0b3J5ID0gbmV3IFRocm91Z2hwdXRBbGFybUZhY3RvcnkoYWxhcm1GYWN0b3J5KTtcbiAgICB0aGlzLnRhc2tIZWFsdGhBbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMudXNhZ2VBbGFybUZhY3RvcnkgPSBuZXcgVXNhZ2VBbGFybUZhY3RvcnkoYWxhcm1GYWN0b3J5KTtcbiAgICB0aGlzLmNwdVVzYWdlQW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLm1lbW9yeVVzYWdlQW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLnByb2Nlc3NlZEJ5dGVzQW5ub3RhdGlvbnMgPSBbXTtcblxuICAgIGlmIChwcm9wcy5taW5BdXRvU2NhbGluZ1Rhc2tDb3VudCkge1xuICAgICAgLy8gVE9ETzogdXNlIGFubm90YXRpb24gc3RyYXRlZ3kgdG8gY3JlYXRlIG5ldXRyYWwgYW5ub3RhdGlvblxuICAgICAgdGhpcy50YXNrSGVhbHRoQW5ub3RhdGlvbnMucHVzaCh7XG4gICAgICAgIHZhbHVlOiBwcm9wcy5taW5BdXRvU2NhbGluZ1Rhc2tDb3VudCxcbiAgICAgICAgbGFiZWw6IFwiQXV0b1NjYWxpbmc6IE1pblwiLFxuICAgICAgICBjb2xvcjogTmV1dHJhbENvbG9yLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChwcm9wcy5tYXhBdXRvU2NhbGluZ1Rhc2tDb3VudCkge1xuICAgICAgLy8gVE9ETzogdXNlIGFubm90YXRpb24gc3RyYXRlZ3kgdG8gY3JlYXRlIG5ldXRyYWwgYW5ub3RhdGlvblxuICAgICAgdGhpcy50YXNrSGVhbHRoQW5ub3RhdGlvbnMucHVzaCh7XG4gICAgICAgIHZhbHVlOiBwcm9wcy5tYXhBdXRvU2NhbGluZ1Rhc2tDb3VudCxcbiAgICAgICAgbGFiZWw6IFwiQXV0b1NjYWxpbmc6IE1heFwiLFxuICAgICAgICBjb2xvcjogTmV1dHJhbENvbG9yLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaGFzTG9hZEJhbGFuY2VyKSB7XG4gICAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkSGVhbHRoeVRhc2tDb3VudEFsYXJtKSB7XG4gICAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRIZWFsdGh5VGFza0NvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9XG4gICAgICAgICAgdGhpcy50YXNrSGVhbHRoQWxhcm1GYWN0b3J5LmFkZEhlYWx0aHlUYXNrQ291bnRBbGFybShcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICB0aGlzLmhlYWx0aHlUYXNrQ291bnRNZXRyaWMhLFxuICAgICAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICAgICAgKTtcbiAgICAgICAgdGhpcy50YXNrSGVhbHRoQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRVbmhlYWx0aHlUYXNrQ291bnRBbGFybSkge1xuICAgICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkVW5oZWFsdGh5VGFza0NvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9XG4gICAgICAgICAgdGhpcy50YXNrSGVhbHRoQWxhcm1GYWN0b3J5LmFkZFVuaGVhbHRoeVRhc2tDb3VudEFsYXJtKFxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgIHRoaXMudW5oZWFsdGh5VGFza0NvdW50TWV0cmljISxcbiAgICAgICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgICAgICk7XG4gICAgICAgIHRoaXMudGFza0hlYWx0aEFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkSGVhbHRoeVRhc2tQZXJjZW50QWxhcm0pIHtcbiAgICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZEhlYWx0aHlUYXNrUGVyY2VudEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPVxuICAgICAgICAgIHRoaXMudGFza0hlYWx0aEFsYXJtRmFjdG9yeS5hZGRIZWFsdGh5VGFza1BlcmNlbnRBbGFybShcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICB0aGlzLmhlYWx0aHlUYXNrUGVyY2VudE1ldHJpYyEsXG4gICAgICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgICB9XG4gICAgfVxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRDcHVVc2FnZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkQ3B1VXNhZ2VBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMudXNhZ2VBbGFybUZhY3RvcnkuYWRkTWF4Q3B1VXNhZ2VQZXJjZW50QWxhcm0oXG4gICAgICAgIHRoaXMuY3B1VXRpbGlzYXRpb25NZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy5jcHVVc2FnZUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkTWVtb3J5VXNhZ2VBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZE1lbW9yeVVzYWdlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLnVzYWdlQWxhcm1GYWN0b3J5LmFkZE1heE1lbW9yeVVzYWdlUGVyY2VudEFsYXJtKFxuICAgICAgICB0aGlzLm1lbW9yeVV0aWxpc2F0aW9uTWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMubWVtb3J5VXNhZ2VBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkUnVubmluZ1Rhc2tDb3VudEFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkUnVubmluZ1Rhc2tDb3VudEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy50YXNrSGVhbHRoQWxhcm1GYWN0b3J5LmFkZFJ1bm5pbmdUYXNrQ291bnRBbGFybShcbiAgICAgICAgdGhpcy5ydW5uaW5nVGFza0NvdW50TWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMudGFza0hlYWx0aEFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkRXBoZXJtYWxTdG9yYWdlVXNhZ2VBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZEVwaGVybWFsU3RvcmFnZVVzYWdlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLnVzYWdlQWxhcm1GYWN0b3J5LmFkZE1heERpc2tVc2FnZVBlcmNlbnRBbGFybShcbiAgICAgICAgdGhpcy5lcGhlbWVyYWxTdG9yYWdlVXNhZ2VNZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmhhc0xvYWRCYWxhbmNlcikge1xuICAgICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZE1pblByb2Nlc3NlZEJ5dGVzQWxhcm0pIHtcbiAgICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZE1pblByb2Nlc3NlZEJ5dGVzQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9XG4gICAgICAgICAgdGhpcy50aHJvdWdocHV0QWxhcm1GYWN0b3J5LmFkZE1pblByb2Nlc3NlZEJ5dGVzQWxhcm0oXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgdGhpcy5wcm9jZXNzZWRCeXRlc01ldHJpYyEsXG4gICAgICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICAgICApO1xuICAgICAgICB0aGlzLnByb2Nlc3NlZEJ5dGVzQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcm9wcy51c2VDcmVhdGVkQWxhcm1zPy5jb25zdW1lKHRoaXMuY3JlYXRlZEFsYXJtcygpKTtcbiAgfVxuXG4gIHN1bW1hcnlXaWRnZXRzKCk6IElXaWRnZXRbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMuY3JlYXRlVGl0bGVXaWRnZXQoKSxcbiAgICAgIHRoaXMuY3JlYXRlQ3B1V2lkZ2V0KFRoaXJkV2lkdGgsIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0KSxcbiAgICAgIHRoaXMuY3JlYXRlTWVtb3J5V2lkZ2V0KFRoaXJkV2lkdGgsIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0KSxcbiAgICAgIHRoaXMuY3JlYXRlVGFza0hlYWx0aFdpZGdldChUaGlyZFdpZHRoLCBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCksXG4gICAgXTtcbiAgfVxuXG4gIHdpZGdldHMoKTogSVdpZGdldFtdIHtcbiAgICBjb25zdCBiYXNlV2lkZ2V0ID0gW1xuICAgICAgdGhpcy5jcmVhdGVUaXRsZVdpZGdldCgpLFxuICAgICAgdGhpcy5jcmVhdGVDcHVXaWRnZXQoXG4gICAgICAgIHRoaXMuaGFzTG9hZEJhbGFuY2VyID8gUXVhcnRlcldpZHRoIDogVGhpcmRXaWR0aCxcbiAgICAgICAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICAgICAgKSxcbiAgICAgIHRoaXMuY3JlYXRlTWVtb3J5V2lkZ2V0KFxuICAgICAgICB0aGlzLmhhc0xvYWRCYWxhbmNlciA/IFF1YXJ0ZXJXaWR0aCA6IFRoaXJkV2lkdGgsXG4gICAgICAgIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCxcbiAgICAgICksXG4gICAgXTtcblxuICAgIGlmICh0aGlzLmhhc0xvYWRCYWxhbmNlcikge1xuICAgICAgcmV0dXJuIGJhc2VXaWRnZXQuY29uY2F0KFtcbiAgICAgICAgdGhpcy5jcmVhdGVUY3BGbG93c1dpZGdldChRdWFydGVyV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICAgIHRoaXMuY3JlYXRlVGFza0hlYWx0aFdpZGdldChRdWFydGVyV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICBdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGJhc2VXaWRnZXQuY29uY2F0KFxuICAgICAgICB0aGlzLmNyZWF0ZVRhc2tIZWFsdGhXaWRnZXQoVGhpcmRXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgY3JlYXRlVGl0bGVXaWRnZXQoKSB7XG4gICAgcmV0dXJuIG5ldyBNb25pdG9yaW5nSGVhZGVyV2lkZ2V0KHtcbiAgICAgIGZhbWlseTogXCJFYzIgU2VydmljZVwiLFxuICAgICAgdGl0bGU6IHRoaXMudGl0bGUsXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVDcHVXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiQ1BVIFV0aWxpemF0aW9uXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5jcHVVdGlsaXNhdGlvbk1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IFBlcmNlbnRhZ2VBeGlzRnJvbVplcm9Ub0h1bmRyZWQsXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMuY3B1VXNhZ2VBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZU1lbW9yeVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJNZW1vcnkgVXRpbGl6YXRpb25cIixcbiAgICAgIGxlZnQ6IFt0aGlzLm1lbW9yeVV0aWxpc2F0aW9uTWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogUGVyY2VudGFnZUF4aXNGcm9tWmVyb1RvSHVuZHJlZCxcbiAgICAgIGxlZnRBbm5vdGF0aW9uczogdGhpcy5tZW1vcnlVc2FnZUFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlVGFza0hlYWx0aFdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIGNvbnN0IGxlZnQgPSBbdGhpcy5ydW5uaW5nVGFza0NvdW50TWV0cmljXTtcblxuICAgIGlmICh0aGlzLmhlYWx0aHlUYXNrQ291bnRNZXRyaWMpIHtcbiAgICAgIGxlZnQucHVzaCh0aGlzLmhlYWx0aHlUYXNrQ291bnRNZXRyaWMpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnVuaGVhbHRoeVRhc2tDb3VudE1ldHJpYykge1xuICAgICAgbGVmdC5wdXNoKHRoaXMudW5oZWFsdGh5VGFza0NvdW50TWV0cmljKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IHRoaXMuaGFzTG9hZEJhbGFuY2VyID8gXCJUYXNrIEhlYWx0aFwiIDogXCJUYXNrIENvdW50XCIsXG4gICAgICBsZWZ0LFxuICAgICAgbGVmdFlBeGlzOiBDb3VudEF4aXNGcm9tWmVybyxcbiAgICAgIGxlZnRBbm5vdGF0aW9uczogdGhpcy50YXNrSGVhbHRoQW5ub3RhdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVUY3BGbG93c1dpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIGNvbnN0IGxlZnQ6IElNZXRyaWNbXSA9IFtdO1xuICAgIGNvbnN0IHJpZ2h0OiBJTWV0cmljW10gPSBbXTtcblxuICAgIGlmICh0aGlzLmFjdGl2ZVRjcEZsb3dDb3VudE1ldHJpYykge1xuICAgICAgbGVmdC5wdXNoKHRoaXMuYWN0aXZlVGNwRmxvd0NvdW50TWV0cmljKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5uZXdUY3BGbG93Q291bnRNZXRyaWMpIHtcbiAgICAgIGxlZnQucHVzaCh0aGlzLm5ld1RjcEZsb3dDb3VudE1ldHJpYyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudW5oZWFsdGh5Um91dGluZ0Zsb3dDb3VudE1ldHJpYykge1xuICAgICAgbGVmdC5wdXNoKHRoaXMudW5oZWFsdGh5Um91dGluZ0Zsb3dDb3VudE1ldHJpYyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucHJvY2Vzc2VkQnl0ZXNNZXRyaWMpIHtcbiAgICAgIHJpZ2h0LnB1c2godGhpcy5wcm9jZXNzZWRCeXRlc01ldHJpYyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIlRDUCBGbG93c1wiLFxuICAgICAgbGVmdCxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgICByaWdodCxcbiAgICAgIHJpZ2h0WUF4aXM6IFNpemVBeGlzQnl0ZXNGcm9tWmVybyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCB1c2Uge0BzZWUgY3JlYXRlVGNwRmxvd3NXaWRnZXR9IGluc3RlYWQuXG4gICAqL1xuICBjcmVhdGVUcGNGbG93c1dpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZVRjcEZsb3dzV2lkZ2V0KHdpZHRoLCBoZWlnaHQpO1xuICB9XG59XG4iXX0=