UNPKG

cdk-monitoring-constructs

Version:

[![NPM version](https://badge.fury.io/js/cdk-monitoring-constructs.svg)](https://badge.fury.io/js/cdk-monitoring-constructs) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.github.cdklabs/cdkmonitoringconstructs/badge.svg)](https://m

250 lines 49 kB
"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 = (0, 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.cpuP100UtilisationMetric = this.baseServiceMetricFactory.metricClusterCpuUtilisationInPercent(common_1.MetricStatistic.P100); this.memoryUtilisationMetric = this.baseServiceMetricFactory.metricClusterMemoryUtilisationInPercent(); this.memoryP100UtilisationMetric = this.baseServiceMetricFactory.metricClusterMemoryUtilisationInPercent(common_1.MetricStatistic.P100); 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.addCpuP100UsageAlarm) { const alarmProps = props.addCpuP100UsageAlarm[disambiguator]; const createdAlarm = this.usageAlarmFactory.addMaxCpuUsagePercentAlarm(this.cpuP100UtilisationMetric, alarmProps, disambiguator, common_1.UsageType.P100); 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.addMemoryP100UsageAlarm) { const alarmProps = props.addMemoryP100UsageAlarm[disambiguator]; const createdAlarm = this.usageAlarmFactory.addMemoryUsagePercentAlarm(this.memoryP100UtilisationMetric, alarmProps, common_1.UsageType.P100, 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, this.cpuP100UtilisationMetric], leftYAxis: common_1.PercentageAxisFromZeroToHundred, leftAnnotations: this.cpuUsageAnnotations, }); } createMemoryWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Memory Utilization", left: [this.memoryUtilisationMetric, this.memoryP100UtilisationMetric], 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: "10.0.0" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRWMyU2VydmljZU1vbml0b3JpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJFYzJTZXJ2aWNlTW9uaXRvcmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLCtEQUtvQztBQWFwQyx5RUFBc0U7QUFDdEUseUNBeUJzQjtBQUN0QiwrQ0FHeUI7QUFDekIsNERBSzhCO0FBNkc5QixNQUFhLG9CQUFxQixTQUFRLG1CQUFVO0lBK0JsRCxZQUFZLEtBQXNCLEVBQUUsS0FBc0M7UUFDeEUsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVwQixJQUFJLENBQUMsZUFBZTtZQUNsQixLQUFLLENBQUMsWUFBWSxLQUFLLFNBQVMsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFNBQVMsQ0FBQztRQUV0RSxNQUFNLGNBQWMsR0FBRyxJQUFJLG9DQUF3QixDQUFDO1lBQ2xELEdBQUcsS0FBSztZQUNSLGNBQWMsRUFBRSxLQUFLLENBQUMsVUFBVTtTQUNqQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBRXZELElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFDakQsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksbURBQXdCLENBQzFELElBQUksQ0FBQyxhQUFhLEVBQ2xCLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FDOUIsQ0FBQztRQUNGLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyx5QkFBeUIsR0FBRyxJQUFBLG1EQUErQixFQUM5RCxJQUFJLENBQUMsYUFBYSxFQUNsQixLQUFLLENBQUMsWUFBYSxFQUNuQixLQUFLLENBQUMsV0FBWSxFQUNsQixLQUFLLENBQUMsNENBQTRDLENBQ25ELENBQUM7WUFDRixJQUFJLENBQUMsc0JBQXNCO2dCQUN6QixJ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RSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUM7UUFDM0MsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUN4QyxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsK0JBQStCLEVBQUUsQ0FBQztZQUN6QyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBQ2xELENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBQzlCLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDeEMsQ0FBQztRQUVELE9BQU8sSUFBSSw0QkFBVyxDQUFDO1lBQ3JCLEtBQUs7WUFDTCxNQUFNO1lBQ04sS0FBSyxFQUFFLFdBQVc7WUFDbEIsSUFBSTtZQUNKLFNBQVMsRUFBRSwwQkFBaUI7WUFDNUIsS0FBSztZQUNMLFVBQVUsRUFBRSw4QkFBcUI7U0FDbEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0gsb0JBQW9CLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDaEQsT0FBTyxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2xELENBQUM7O0FBaldILG9EQWtXQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEdyYXBoV2lkZ2V0LFxuICBIb3Jpem9udGFsQW5ub3RhdGlvbixcbiAgSU1ldHJpYyxcbiAgSVdpZGdldCxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoXCI7XG5pbXBvcnQgeyBFYzJTZXJ2aWNlLCBJQmFzZVNlcnZpY2UgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjc1wiO1xuaW1wb3J0IHtcbiAgQXBwbGljYXRpb25Mb2FkQmFsYW5jZWRFYzJTZXJ2aWNlLFxuICBOZXR3b3JrTG9hZEJhbGFuY2VkRWMyU2VydmljZSxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lY3MtcGF0dGVybnNcIjtcbmltcG9ydCB7XG4gIElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcixcbiAgSUFwcGxpY2F0aW9uVGFyZ2V0R3JvdXAsXG4gIElOZXR3b3JrTG9hZEJhbGFuY2VyLFxuICBJTmV0d29ya1RhcmdldEdyb3VwLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjJcIjtcblxuaW1wb3J0IHsgQmFzZVNlcnZpY2VNZXRyaWNGYWN0b3J5IH0gZnJvbSBcIi4vQmFzZVNlcnZpY2VNZXRyaWNGYWN0b3J5XCI7XG5pbXBvcnQge1xuICBCYXNlTW9uaXRvcmluZ1Byb3BzLFxuICBDb3VudEF4aXNGcm9tWmVybyxcbiAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCxcbiAgSGVhbHRoeVRhc2tDb3VudFRocmVzaG9sZCxcbiAgSGVhbHRoeVRhc2tQZXJjZW50VGhyZXNob2xkLFxuICBNZXRyaWNGYWN0b3J5LFxuICBNZXRyaWNTdGF0aXN0aWMsXG4gIE1ldHJpY1dpdGhBbGFybVN1cHBvcnQsXG4gIE1pblByb2Nlc3NlZEJ5dGVzVGhyZXNob2xkLFxuICBNb25pdG9yaW5nLFxuICBNb25pdG9yaW5nU2NvcGUsXG4gIE5ldXRyYWxDb2xvcixcbiAgUGVyY2VudGFnZUF4aXNGcm9tWmVyb1RvSHVuZHJlZCxcbiAgUXVhcnRlcldpZHRoLFxuICBSdW5uaW5nVGFza0NvdW50VGhyZXNob2xkLFxuICBTaXplQXhpc0J5dGVzRnJvbVplcm8sXG4gIFRhc2tIZWFsdGhBbGFybUZhY3RvcnksXG4gIFRoaXJkV2lkdGgsXG4gIFRocm91Z2hwdXRBbGFybUZhY3RvcnksXG4gIFVuaGVhbHRoeVRhc2tDb3VudFRocmVzaG9sZCxcbiAgVXNhZ2VBbGFybUZhY3RvcnksXG4gIFVzYWdlVGhyZXNob2xkLFxuICBVc2FnZVR5cGUsXG59IGZyb20gXCIuLi8uLi9jb21tb25cIjtcbmltcG9ydCB7XG4gIE1vbml0b3JpbmdIZWFkZXJXaWRnZXQsXG4gIE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSxcbn0gZnJvbSBcIi4uLy4uL2Rhc2hib2FyZFwiO1xuaW1wb3J0IHtcbiAgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5UHJvcHMsXG4gIElMb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5LFxuICBOZXR3b3JrTG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeVByb3BzLFxuICBjcmVhdGVMb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5LFxufSBmcm9tIFwiLi4vYXdzLWxvYWRiYWxhbmNpbmdcIjtcblxuZXhwb3J0IGludGVyZmFjZSBCYXNlRWMyU2VydmljZUFsYXJtcyB7XG4gIC8qKlxuICAgKiBNaW5pbXVtIG51bWJlciBvZiB0YXNrcywgYXMgc3BlY2lmaWVkIGluIHlvdXIgYXV0byBzY2FsaW5nIGNvbmZpZy5cbiAgICovXG4gIHJlYWRvbmx5IG1pbkF1dG9TY2FsaW5nVGFza0NvdW50PzogbnVtYmVyO1xuICAvKipcbiAgICogTWF4aW11bSBudW1iZXIgb2YgdGFza3MsIGFzIHNwZWNpZmllZCBpbiB5b3VyIGF1dG8gc2NhbGluZyBjb25maWcuXG4gICAqL1xuICByZWFkb25seSBtYXhBdXRvU2NhbGluZ1Rhc2tDb3VudD86IG51bWJlcjtcbiAgcmVhZG9ubHkgYWRkQ3B1VXNhZ2VBbGFybT86IFJlY29yZDxzdHJpbmcsIFVzYWdlVGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkTWVtb3J5VXNhZ2VBbGFybT86IFJlY29yZDxzdHJpbmcsIFVzYWdlVGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkQ3B1UDEwMFVzYWdlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBVc2FnZVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZE1lbW9yeVAxMDBVc2FnZUFsYXJtPzogUmVjb3JkPHN0cmluZywgVXNhZ2VUaHJlc2hvbGQ+O1xuXG4gIC8qKlxuICAgKiBDb250YWluZXIgSW5zaWdodHMgbmVlZHMgdG8gYmUgZW5hYmxlZCBmb3IgdGhlIGNsdXN0ZXIgZm9yIHRoaXMgYWxhcm0uXG4gICAqL1xuICByZWFkb25seSBhZGRSdW5uaW5nVGFza0NvdW50QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBSdW5uaW5nVGFza0NvdW50VGhyZXNob2xkPjtcbiAgLyoqXG4gICAqIENvbnRhaW5lciBJbnNpZ2h0cyBuZWVkcyB0byBiZSBlbmFibGVkIGZvciB0aGUgY2x1c3RlciBmb3IgdGhpcyBhbGFybS5cbiAgICovXG4gIHJlYWRvbmx5IGFkZEVwaGVybWFsU3RvcmFnZVVzYWdlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBVc2FnZVRocmVzaG9sZD47XG59XG5cbi8qKlxuICogTW9uaXRvcmluZyBwcm9wcyBmb3IgYW55IHR5cGUgb2YgRUMyIHNlcnZpY2UuXG4gKi9cbmludGVyZmFjZSBCYXNlRWMyU2VydmljZU1vbml0b3JpbmdQcm9wc1xuICBleHRlbmRzIEJhc2VNb25pdG9yaW5nUHJvcHMsXG4gICAgQmFzZUVjMlNlcnZpY2VBbGFybXMge31cblxuLyoqXG4gKiBNb25pdG9yaW5nIHByb3BzIGZvciBTaW1wbGUgRUMyIHNlcnZpY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2ltcGxlRWMyU2VydmljZU1vbml0b3JpbmdQcm9wc1xuICBleHRlbmRzIEJhc2VFYzJTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzIHtcbiAgcmVhZG9ubHkgZWMyU2VydmljZTogRWMyU2VydmljZTtcbn1cblxuLyoqXG4gKiBCYXNlIG9mIE1vbml0b3JpbmcgcHJvcHMgZm9yIGxvYWQtYmFsYW5jZWQgRUMyIHNlcnZpY2UuXG4gKi9cbmludGVyZmFjZSBCYXNlTG9hZEJhbGFuY2VkRWMyU2VydmljZU1vbml0b3JpbmdQcm9wc1xuICBleHRlbmRzIEJhc2VFYzJTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzIHtcbiAgcmVhZG9ubHkgYWRkSGVhbHRoeVRhc2tDb3VudEFsYXJtPzogUmVjb3JkPHN0cmluZywgSGVhbHRoeVRhc2tDb3VudFRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFVuaGVhbHRoeVRhc2tDb3VudEFsYXJtPzogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBVbmhlYWx0aHlUYXNrQ291bnRUaHJlc2hvbGRcbiAgPjtcbiAgcmVhZG9ubHkgYWRkSGVhbHRoeVRhc2tQZXJjZW50QWxhcm0/OiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIEhlYWx0aHlUYXNrUGVyY2VudFRocmVzaG9sZFxuICA+O1xuICByZWFkb25seSBhZGRNaW5Qcm9jZXNzZWRCeXRlc0FsYXJtPzogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBNaW5Qcm9jZXNzZWRCeXRlc1RocmVzaG9sZFxuICA+O1xuXG4gIC8qKlxuICAgKiBJbnZlcnQgdGhlIHN0YXRpc3RpY3Mgb2YgYEhlYWx0aHlIb3N0Q291bnRgIGFuZCBgVW5IZWFsdGh5SG9zdENvdW50YC5cbiAgICpcbiAgICogV2hlbiBgaW52ZXJ0TG9hZEJhbGFuY2VyVGFza0NvdW50TWV0cmljc1N0YXRpc3RpY3NgIGlzIHNldCB0byBmYWxzZSwgdGhlIG1pbmltdW0gb2YgYEhlYWx0aHlIb3N0Q291bnRgIGFuZCB0aGUgbWF4aW11bSBvZiBgVW5IZWFsdGh5SG9zdENvdW50YCBhcmUgbW9uaXRvcmVkLlxuICAgKiBXaGVuIGBpbnZlcnRMb2FkQmFsYW5jZXJUYXNrQ291bnRNZXRyaWNzU3RhdGlzdGljc2AgaXMgc2V0IHRvIHRydWUsIHRoZSBtYXhpbXVtIG9mIGBIZWFsdGh5SG9zdENvdW50YCBhbmQgdGhlIG1pbmltdW0gb2YgYFVuSGVhbHRoeUhvc3RDb3VudGAgYXJlIG1vbml0b3JlZC5cbiAgICpcbiAgICogYGludmVydExvYWRCYWxhbmNlclRhc2tDb3VudE1ldHJpY3NTdGF0aXN0aWNzYCBpcyByZWNvbW1lbmRlZCB0byBzZXQgdG8gdHJ1ZSBhcyBwZXIgdGhlIGd1aWRlbGluZXMgYXRcbmh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy9sYXRlc3QvbmV0d29yay9sb2FkLWJhbGFuY2VyLWNsb3Vkd2F0Y2gtbWV0cmljcy5odG1sI21ldHJpYy1zdGF0aXN0aWNzXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBpbnZlcnRMb2FkQmFsYW5jZXJUYXNrQ291bnRNZXRyaWNzU3RhdGlzdGljcz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogTW9uaXRvcmluZyBwcm9wcyBmb3IgbG9hZC1iYWxhbmNlZCBFQzIgc2VydmljZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFYzJTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzXG4gIGV4dGVuZHMgQmFzZUxvYWRCYWxhbmNlZEVjMlNlcnZpY2VNb25pdG9yaW5nUHJvcHMge1xuICByZWFkb25seSBlYzJTZXJ2aWNlOlxuICAgIHwgTmV0d29ya0xvYWRCYWxhbmNlZEVjMlNlcnZpY2VcbiAgICB8IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VkRWMyU2VydmljZTtcbn1cblxuLyoqXG4gKiBNb25pdG9yaW5nIHByb3BzIGZvciBFQzIgc2VydmljZSB3aXRoIG5ldHdvcmsgbG9hZCBiYWxhbmNlciBhbmQgcGxhaW4gc2VydmljZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFYzJOZXR3b3JrTG9hZEJhbGFuY2VyTW9uaXRvcmluZ1Byb3BzXG4gIGV4dGVuZHMgTmV0d29ya0xvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgICBCYXNlTG9hZEJhbGFuY2VkRWMyU2VydmljZU1vbml0b3JpbmdQcm9wcyB7XG4gIHJlYWRvbmx5IGVjMlNlcnZpY2U6IEVjMlNlcnZpY2U7XG59XG5cbi8qKlxuICogTW9uaXRvcmluZyBwcm9wcyBmb3IgRUMyIHNlcnZpY2Ugd2l0aCBhcHBsaWNhdGlvbiBsb2FkIGJhbGFuY2VyIGFuZCBwbGFpbiBzZXJ2aWNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVjMkFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTW9uaXRvcmluZ1Byb3BzXG4gIGV4dGVuZHMgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5UHJvcHMsXG4gICAgQmFzZUxvYWRCYWxhbmNlZEVjMlNlcnZpY2VNb25pdG9yaW5nUHJvcHMge1xuICByZWFkb25seSBlYzJTZXJ2aWNlOiBFYzJTZXJ2aWNlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEN1c3RvbUVjMlNlcnZpY2VNb25pdG9yaW5nUHJvcHNcbiAgZXh0ZW5kcyBCYXNlTG9hZEJhbGFuY2VkRWMyU2VydmljZU1vbml0b3JpbmdQcm9wcyB7XG4gIHJlYWRvbmx5IGVjMlNlcnZpY2U6IElCYXNlU2VydmljZTtcbiAgcmVhZG9ubHkgbG9hZEJhbGFuY2VyPzogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyIHwgSU5ldHdvcmtMb2FkQmFsYW5jZXI7XG4gIHJlYWRvbmx5IHRhcmdldEdyb3VwPzogSUFwcGxpY2F0aW9uVGFyZ2V0R3JvdXAgfCBJTmV0d29ya1RhcmdldEdyb3VwO1xufVxuXG5leHBvcnQgY2xhc3MgRWMyU2VydmljZU1vbml0b3JpbmcgZXh0ZW5kcyBNb25pdG9yaW5nIHtcbiAgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcblxuICByZWFkb25seSBtZXRyaWNGYWN0b3J5OiBNZXRyaWNGYWN0b3J5O1xuICByZWFkb25seSBiYXNlU2VydmljZU1ldHJpY0ZhY3Rvcnk6IEJhc2VTZXJ2aWNlTWV0cmljRmFjdG9yeTtcbiAgcmVhZG9ubHkgbG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeT86IElMb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5O1xuXG4gIHJlYWRvbmx5IHRhc2tIZWFsdGhBbGFybUZhY3Rvcnk6IFRhc2tIZWFsdGhBbGFybUZhY3Rvcnk7XG4gIHJlYWRvbmx5IHRocm91Z2hwdXRBbGFybUZhY3Rvcnk6IFRocm91Z2hwdXRBbGFybUZhY3Rvcnk7XG4gIHJlYWRvbmx5IHRhc2tIZWFsdGhBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgdXNhZ2VBbGFybUZhY3Rvcnk6IFVzYWdlQWxhcm1GYWN0b3J5O1xuICByZWFkb25seSBjcHVVc2FnZUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICByZWFkb25seSBtZW1vcnlVc2FnZUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICByZWFkb25seSBwcm9jZXNzZWRCeXRlc0Fubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuXG4gIHJlYWRvbmx5IGhlYWx0aHlUYXNrQ291bnRNZXRyaWM/OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSB1bmhlYWx0aHlUYXNrQ291bnRNZXRyaWM/OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBoZWFsdGh5VGFza1BlcmNlbnRNZXRyaWM/OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBjcHVVdGlsaXNhdGlvbk1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgY3B1UDEwMFV0aWxpc2F0aW9uTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBtZW1vcnlVdGlsaXNhdGlvbk1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbWVtb3J5UDEwMFV0aWxpc2F0aW9uTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBydW5uaW5nVGFza0NvdW50TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBlcGhlbWVyYWxTdG9yYWdlVXNhZ2VNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGFjdGl2ZVRjcEZsb3dDb3VudE1ldHJpYz86IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG5ld1RjcEZsb3dDb3VudE1ldHJpYz86IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IHVuaGVhbHRoeVJvdXRpbmdGbG93Q291bnRNZXRyaWM/OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBwcm9jZXNzZWRCeXRlc01ldHJpYz86IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG5cbiAgcHJpdmF0ZSBoYXNMb2FkQmFsYW5jZXI6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IE1vbml0b3JpbmdTY29wZSwgcHJvcHM6IEN1c3RvbUVjMlNlcnZpY2VNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgcHJvcHMpO1xuXG4gICAgdGhpcy5oYXNMb2FkQmFsYW5jZXIgPVxuICAgICAgcHJvcHMubG9hZEJhbGFuY2VyICE9PSB1bmRlZmluZWQgJiYgcHJvcHMudGFyZ2V0R3JvdXAgIT09IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IG5hbWluZ1N0cmF0ZWd5ID0gbmV3IE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSh7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIG5hbWVkQ29uc3RydWN0OiBwcm9wcy5lYzJTZXJ2aWNlLFxuICAgIH0pO1xuICAgIHRoaXMudGl0bGUgPSBuYW1pbmdTdHJhdGVneS5yZXNvbHZlSHVtYW5SZWFkYWJsZU5hbWUoKTtcblxuICAgIHRoaXMubWV0cmljRmFjdG9yeSA9IHNjb3BlLmNyZWF0ZU1ldHJpY0ZhY3RvcnkoKTtcbiAgICB0aGlzLmJhc2VTZXJ2aWNlTWV0cmljRmFjdG9yeSA9IG5ldyBCYXNlU2VydmljZU1ldHJpY0ZhY3RvcnkoXG4gICAgICB0aGlzLm1ldHJpY0ZhY3RvcnksXG4gICAgICB7IHNlcnZpY2U6IHByb3BzLmVjMlNlcnZpY2UgfSxcbiAgICApO1xuICAgIGlmICh0aGlzLmhhc0xvYWRCYWxhbmNlcikge1xuICAgICAgdGhpcy5sb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5ID0gY3JlYXRlTG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeShcbiAgICAgICAgdGhpcy5tZXRyaWNGYWN0b3J5LFxuICAgICAgICBwcm9wcy5sb2FkQmFsYW5jZXIhLFxuICAgICAgICBwcm9wcy50YXJnZXRHcm91cCEsXG4gICAgICAgIHByb3BzLmludmVydExvYWRCYWxhbmNlclRhc2tDb3VudE1ldHJpY3NTdGF0aXN0aWNzLFxuICAgICAgKTtcbiAgICAgIHRoaXMuaGVhbHRoeVRhc2tDb3VudE1ldHJpYyA9XG4gICAgICAgIHRoaXMubG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeS5tZXRyaWNIZWFsdGh5VGFza0NvdW50KCk7XG4gICAgICB0aGlzLnVuaGVhbHRoeVRhc2tDb3VudE1ldHJpYyA9XG4gICAgICAgIHRoaXMubG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeS5tZXRyaWNVbmhlYWx0aHlUYXNrQ291bnQoKTtcbiAgICAgIHRoaXMuaGVhbHRoeVRhc2tQZXJjZW50TWV0cmljID1cbiAgICAgICAgdGhpcy5sb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5Lm1ldHJpY0hlYWx0aHlUYXNrSW5QZXJjZW50KCk7XG4gICAgICB0aGlzLmFjdGl2ZVRjcEZsb3dDb3VudE1ldHJpYyA9XG4gICAgICAgIHRoaXMubG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeS5tZXRyaWNBY3RpdmVDb25uZWN0aW9uQ291bnQoKTtcbiAgICAgIHRoaXMubmV3VGNwRmxvd0NvdW50TWV0cmljID1cbiAgICAgICAgdGhpcy5sb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5Lm1ldHJpY05ld0Nvbm5lY3Rpb25Db3VudCgpO1xuICAgICAgdGhpcy51bmhlYWx0aHlSb3V0aW5nRmxvd0NvdW50TWV0cmljID1cbiAgICAgICAgdGhpcy5sb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5Lm1ldHJpY1VuaGVhbHRoeVJvdXRpbmdDb3VudCgpO1xuICAgICAgdGhpcy5wcm9jZXNzZWRCeXRlc01ldHJpYyA9XG4gICAgICAgIHRoaXMubG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeS5tZXRyaWNQcm9jZXNzZWRCeXRlc01pbigpO1xuICAgIH1cbiAgICB0aGlzLmNwdVV0aWxpc2F0aW9uTWV0cmljID1cbiAgICAgIHRoaXMuYmFzZVNlcnZpY2VNZXRyaWNGYWN0b3J5Lm1ldHJpY0NsdXN0ZXJDcHVVdGlsaXNhdGlvbkluUGVyY2VudCgpO1xuICAgIHRoaXMuY3B1UDEwMFV0aWxpc2F0aW9uTWV0cmljID1cbiAgICAgIHRoaXMuYmFzZVNlcnZpY2VNZXRyaWNGYWN0b3J5Lm1ldHJpY0NsdXN0ZXJDcHVVdGlsaXNhdGlvbkluUGVyY2VudChcbiAgICAgICAgTWV0cmljU3RhdGlzdGljLlAxMDAsXG4gICAgICApO1xuICAgIHRoaXMubWVtb3J5VXRpbGlzYXRpb25NZXRyaWMgPVxuICAgICAgdGhpcy5iYXNlU2VydmljZU1ldHJpY0ZhY3RvcnkubWV0cmljQ2x1c3Rlck1lbW9yeVV0aWxpc2F0aW9uSW5QZXJjZW50KCk7XG4gICAgdGhpcy5tZW1vcnlQMTAwVXRpbGlzYXRpb25NZXRyaWMgPVxuICAgICAgdGhpcy5iYXNlU2VydmljZU1ldHJpY0ZhY3RvcnkubWV0cmljQ2x1c3Rlck1lbW9yeVV0aWxpc2F0aW9uSW5QZXJjZW50KFxuICAgICAgICBNZXRyaWNTdGF0aXN0aWMuUDEwMCxcbiAgICAgICk7XG4gICAgdGhpcy5ydW5uaW5nVGFza0NvdW50TWV0cmljID1cbiAgICAgIHRoaXMuYmFzZVNlcnZpY2VNZXRyaWNGYWN0b3J5Lm1ldHJpY1J1bm5pbmdUYXNrQ291bnQoKTtcbiAgICB0aGlzLmVwaGVtZXJhbFN0b3JhZ2VVc2FnZU1ldHJpYyA9XG4gICAgICB0aGlzLmJhc2VTZXJ2aWNlTWV0cmljRmFjdG9yeS5tZXRyaWNFcGhlbWVyYWxTdG9yYWdlVXNhZ2VJblBlcmNlbnQoKTtcblxuICAgIGNvbnN0IGFsYXJtRmFjdG9yeSA9IHRoaXMuY3JlYXRlQWxhcm1GYWN0b3J5KFxuICAgICAgbmFtaW5nU3RyYXRlZ3kucmVzb2x2ZUFsYXJtRnJpZW5kbHlOYW1lKCksXG4gICAgKTtcbiAgICB0aGlzLnRhc2tIZWFsdGhBbGFybUZhY3RvcnkgPSBuZXcgVGFza0hlYWx0aEFsYXJtRmFjdG9yeShhbGFybUZhY3RvcnkpO1xuICAgIHRoaXMudGhyb3VnaHB1dEFsYXJtRmFjdG9yeSA9IG5ldyBUaHJvdWdocHV0QWxhcm1GYWN0b3J5KGFsYXJtRmFjdG9yeSk7XG4gICAgdGhpcy50YXNrSGVhbHRoQW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLnVzYWdlQWxhcm1GYWN0b3J5ID0gbmV3IFVzYWdlQWxhcm1GYWN0b3J5KGFsYXJtRmFjdG9yeSk7XG4gICAgdGhpcy5jcHVVc2FnZUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5tZW1vcnlVc2FnZUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5wcm9jZXNzZWRCeXRlc0Fubm90YXRpb25zID0gW107XG5cbiAgICBpZiAocHJvcHMubWluQXV0b1NjYWxpbmdUYXNrQ291bnQpIHtcbiAgICAgIC8vIFRPRE86IHVzZSBhbm5vdGF0aW9uIHN0cmF0ZWd5IHRvIGNyZWF0ZSBuZXV0cmFsIGFubm90YXRpb25cbiAgICAgIHRoaXMudGFza0hlYWx0aEFubm90YXRpb25zLnB1c2goe1xuICAgICAgICB2YWx1ZTogcHJvcHMubWluQXV0b1NjYWxpbmdUYXNrQ291bnQsXG4gICAgICAgIGxhYmVsOiBcIkF1dG9TY2FsaW5nOiBNaW5cIixcbiAgICAgICAgY29sb3I6IE5ldXRyYWxDb2xvcixcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAocHJvcHMubWF4QXV0b1NjYWxpbmdUYXNrQ291bnQpIHtcbiAgICAgIC8vIFRPRE86IHVzZSBhbm5vdGF0aW9uIHN0cmF0ZWd5IHRvIGNyZWF0ZSBuZXV0cmFsIGFubm90YXRpb25cbiAgICAgIHRoaXMudGFza0hlYWx0aEFubm90YXRpb25zLnB1c2goe1xuICAgICAgICB2YWx1ZTogcHJvcHMubWF4QXV0b1NjYWxpbmdUYXNrQ291bnQsXG4gICAgICAgIGxhYmVsOiBcIkF1dG9TY2FsaW5nOiBNYXhcIixcbiAgICAgICAgY29sb3I6IE5ldXRyYWxDb2xvcixcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmhhc0xvYWRCYWxhbmNlcikge1xuICAgICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZEhlYWx0aHlUYXNrQ291bnRBbGFybSkge1xuICAgICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkSGVhbHRoeVRhc2tDb3VudEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPVxuICAgICAgICAgIHRoaXMudGFza0hlYWx0aEFsYXJtRmFjdG9yeS5hZGRIZWFsdGh5VGFza0NvdW50QWxhcm0oXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgdGhpcy5oZWFsdGh5VGFza0NvdW50TWV0cmljISxcbiAgICAgICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgICAgICk7XG4gICAgICAgIHRoaXMudGFza0hlYWx0aEFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkVW5oZWFsdGh5VGFza0NvdW50QWxhcm0pIHtcbiAgICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZFVuaGVhbHRoeVRhc2tDb3VudEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPVxuICAgICAgICAgIHRoaXMudGFza0hlYWx0aEFsYXJtRmFjdG9yeS5hZGRVbmhlYWx0aHlUYXNrQ291bnRBbGFybShcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICB0aGlzLnVuaGVhbHRoeVRhc2tDb3VudE1ldHJpYyEsXG4gICAgICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICAgICApO1xuICAgICAgICB0aGlzLnRhc2tIZWFsdGhBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZEhlYWx0aHlUYXNrUGVyY2VudEFsYXJtKSB7XG4gICAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRIZWFsdGh5VGFza1BlcmNlbnRBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID1cbiAgICAgICAgICB0aGlzLnRhc2tIZWFsdGhBbGFybUZhY3RvcnkuYWRkSGVhbHRoeVRhc2tQZXJjZW50QWxhcm0oXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgdGhpcy5oZWFsdGh5VGFza1BlcmNlbnRNZXRyaWMhLFxuICAgICAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkQ3B1VXNhZ2VBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZENwdVVzYWdlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLnVzYWdlQWxhcm1GYWN0b3J5LmFkZE1heENwdVVzYWdlUGVyY2VudEFsYXJtKFxuICAgICAgICB0aGlzLmNwdVV0aWxpc2F0aW9uTWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuY3B1VXNhZ2VBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZENwdVAxMDBVc2FnZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkQ3B1UDEwMFVzYWdlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLnVzYWdlQWxhcm1GYWN0b3J5LmFkZE1heENwdVVzYWdlUGVyY2VudEFsYXJtKFxuICAgICAgICB0aGlzLmNwdVAxMDBVdGlsaXNhdGlvbk1ldHJpYyxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICAgVXNhZ2VUeXBlLlAxMDAsXG4gICAgICApO1xuICAgICAgdGhpcy5jcHVVc2FnZUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkTWVtb3J5VXNhZ2VBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZE1lbW9yeVVzYWdlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLnVzYWdlQWxhcm1GYWN0b3J5LmFkZE1heE1lbW9yeVVzYWdlUGVyY2VudEFsYXJtKFxuICAgICAgICB0aGlzLm1lbW9yeVV0aWxpc2F0aW9uTWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMubWVtb3J5VXNhZ2VBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZE1lbW9yeVAxMDBVc2FnZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkTWVtb3J5UDEwMFVzYWdlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLnVzYWdlQWxhcm1GYWN0b3J5LmFkZE1lbW9yeVVzYWdlUGVyY2VudEFsYXJtKFxuICAgICAgICB0aGlzLm1lbW9yeVAxMDBVdGlsaXNhdGlvbk1ldHJpYyxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgVXNhZ2VUeXBlLlAxMDAsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy5tZW1vcnlVc2FnZUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRSdW5uaW5nVGFza0NvdW50QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRSdW5uaW5nVGFza0NvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLnRhc2tIZWFsdGhBbGFybUZhY3RvcnkuYWRkUnVubmluZ1Rhc2tDb3VudEFsYXJtKFxuICAgICAgICB0aGlzLnJ1bm5pbmdUYXNrQ291bnRNZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy50YXNrSGVhbHRoQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRFcGhlcm1hbFN0b3JhZ2VVc2FnZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkRXBoZXJtYWxTdG9yYWdlVXNhZ2VBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMudXNhZ2VBbGFybUZhY3RvcnkuYWRkTWF4RGlza1VzYWdlUGVyY2VudEFsYXJtKFxuICAgICAgICB0aGlzLmVwaGVtZXJhbFN0b3JhZ2VVc2FnZU1ldHJpYyxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaGFzTG9hZEJhbGFuY2VyKSB7XG4gICAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkTWluUHJvY2Vzc2VkQnl0ZXNBbGFybSkge1xuICAgICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkTWluUHJvY2Vzc2VkQnl0ZXNBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID1cbiAgICAgICAgICB0aGlzLnRocm91Z2hwdXRBbGFybUZhY3RvcnkuYWRkTWluUHJvY2Vzc2VkQnl0ZXNBbGFybShcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NlZEJ5dGVzTWV0cmljISxcbiAgICAgICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgICAgICk7XG4gICAgICAgIHRoaXMucHJvY2Vzc2VkQnl0ZXNBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHByb3BzLnVzZUNyZWF0ZWRBbGFybXM/LmNvbnN1bWUodGhpcy5jcmVhdGVkQWxhcm1zKCkpO1xuICB9XG5cbiAgc3VtbWFyeVdpZGdldHMoKTogSVdpZGdldFtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy5jcmVhdGVUaXRsZVdpZGdldCgpLFxuICAgICAgdGhpcy5jcmVhdGVDcHVXaWRnZXQoVGhpcmRXaWR0aCwgRGVmYXVsdFN1bW1hcnlXaWRnZXRIZWlnaHQpLFxuICAgICAgdGhpcy5jcmVhdGVNZW1vcnlXaWRnZXQoVGhpcmRXaWR0aCwgRGVmYXVsdFN1bW1hcnlXaWRnZXRIZWlnaHQpLFxuICAgICAgdGhpcy5jcmVhdGVUYXNrSGVhbHRoV2lkZ2V0KFRoaXJkV2lkdGgsIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0KSxcbiAgICBdO1xuICB9XG5cbiAgd2lkZ2V0cygpOiBJV2lkZ2V0W10ge1xuICAgIGNvbnN0IGJhc2VXaWRnZXQgPSBbXG4gICAgICB0aGlzLmNyZWF0ZVRpdGxlV2lkZ2V0KCksXG4gICAgICB0aGlzLmNyZWF0ZUNwdVdpZGdldChcbiAgICAgICAgdGhpcy5oYXNMb2FkQmFsYW5jZXIgPyBRdWFydGVyV2lkdGggOiBUaGlyZFdpZHRoLFxuICAgICAgICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gICAgICApLFxuICAgICAgdGhpcy5jcmVhdGVNZW1vcnlXaWRnZXQoXG4gICAgICAgIHRoaXMuaGFzTG9hZEJhbGFuY2VyID8gUXVhcnRlcldpZHRoIDogVGhpcmRXaWR0aCxcbiAgICAgICAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICAgICAgKSxcbiAgICBdO1xuXG4gICAgaWYgKHRoaXMuaGFzTG9hZEJhbGFuY2VyKSB7XG4gICAgICByZXR1cm4gYmFzZVdpZGdldC5jb25jYXQoW1xuICAgICAgICB0aGlzLmNyZWF0ZVRjcEZsb3dzV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgICAgdGhpcy5jcmVhdGVUYXNrSGVhbHRoV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgIF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYmFzZVdpZGdldC5jb25jYXQoXG4gICAgICAgIHRoaXMuY3JlYXRlVGFza0hlYWx0aFdpZGdldChUaGlyZFdpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBjcmVhdGVUaXRsZVdpZGdldCgpIHtcbiAgICByZXR1cm4gbmV3IE1vbml0b3JpbmdIZWFkZXJXaWRnZXQoe1xuICAgICAgZmFtaWx5OiBcIkVjMiBTZXJ2aWNlXCIsXG4gICAgICB0aXRsZTogdGhpcy50aXRsZSxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUNwdVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJDUFUgVXRpbGl6YXRpb25cIixcbiAgICAgIGxlZnQ6IFt0aGlzLmNwdVV0aWxpc2F0aW9uTWV0cmljLCB0aGlzLmNwdVAxMDBVdGlsaXNhdGlvbk1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IFBlcmNlbnRhZ2VBeGlzRnJvbVplcm9Ub0h1bmRyZWQsXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMuY3B1VXNhZ2VBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZU1lbW9yeVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJNZW1vcnkgVXRpbGl6YXRpb25cIixcbiAgICAgIGxlZnQ6IFt0aGlzLm1lbW9yeVV0aWxpc2F0aW9uTWV0cmljLCB0aGlzLm1lbW9yeVAxMDBVdGlsaXNhdGlvbk1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IFBlcmNlbnRhZ2VBeGlzRnJvbVplcm9Ub0h1bmRyZWQsXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMubWVtb3J5VXNhZ2VBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZVRhc2tIZWFsdGhXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICBjb25zdCBsZWZ0ID0gW3RoaXMucnVubmluZ1Rhc2tDb3VudE1ldHJpY107XG5cbiAgICBpZiAodGhpcy5oZWFsdGh5VGFza0NvdW50TWV0cmljKSB7XG4gICAgICBsZWZ0LnB1c2godGhpcy5oZWFsdGh5VGFza0NvdW50TWV0cmljKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy51bmhlYWx0aHlUYXNrQ291bnRNZXRyaWMpIHtcbiAgICAgIGxlZnQucHVzaCh0aGlzLnVuaGVhbHRoeVRhc2tDb3VudE1ldHJpYyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiB0aGlzLmhhc0xvYWRCYWxhbmNlciA/IFwiVGFzayBIZWFsdGhcIiA6IFwiVGFzayBDb3VudFwiLFxuICAgICAgbGVmdCxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMudGFza0hlYWx0aEFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlVGNwRmxvd3NXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICBjb25zdCBsZWZ0OiBJTWV0cmljW10gPSBbXTtcbiAgICBjb25zdCByaWdodDogSU1ldHJpY1tdID0gW107XG5cbiAgICBpZiAodGhpcy5hY3RpdmVUY3BGbG93Q291bnRNZXRyaWMpIHtcbiAgICAgIGxlZnQucHVzaCh0aGlzLmFjdGl2ZVRjcEZsb3dDb3VudE1ldHJpYyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubmV3VGNwRmxvd0NvdW50TWV0cmljKSB7XG4gICAgICBsZWZ0LnB1c2godGhpcy5uZXdUY3BGbG93Q291bnRNZXRyaWMpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnVuaGVhbHRoeVJvdXRpbmdGbG93Q291bnRNZXRyaWMpIHtcbiAgICAgIGxlZnQucHVzaCh0aGlzLnVuaGVhbHRoeVJvdXRpbmdGbG93Q291bnRNZXRyaWMpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnByb2Nlc3NlZEJ5dGVzTWV0cmljKSB7XG4gICAgICByaWdodC5wdXNoKHRoaXMucHJvY2Vzc2VkQnl0ZXNNZXRyaWMpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJUQ1AgRmxvd3NcIixcbiAgICAgIGxlZnQsXG4gICAgICBsZWZ0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgICAgcmlnaHQsXG4gICAgICByaWdodFlBeGlzOiBTaXplQXhpc0J5dGVzRnJvbVplcm8sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgdXNlIHtAc2VlIGNyZWF0ZVRjcEZsb3dzV2lkZ2V0fSBpbnN0ZWFkLlxuICAgKi9cbiAgY3JlYXRlVHBjRmxvd3NXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVUY3BGbG93c1dpZGdldCh3aWR0aCwgaGVpZ2h0KTtcbiAgfVxufVxuIl19