UNPKG

cdk-monitoring-constructs

Version:

[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/cdklabs/cdk-monitoring-constructs) [![NPM version](https://badge.fury.io/js/cdk-monitoring-constructs.svg)](https://badge

216 lines 39.9 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 common_1 = require("../../common"); const dashboard_1 = require("../../dashboard"); const aws_loadbalancing_1 = require("../aws-loadbalancing"); const BaseServiceMetricFactory_1 = require("./BaseServiceMetricFactory"); 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); 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.processedBytesMetric = this.loadBalancerMetricFactory.metricProcessedBytesMin(); } this.runningTaskCountMetric = this.baseServiceMetricFactory.metricRunningTaskCount(); this.cpuUtilisationMetric = this.baseServiceMetricFactory.metricClusterCpuUtilisationInPercent(); this.memoryUtilisationMetric = this.baseServiceMetricFactory.metricClusterMemoryUtilisationInPercent(); 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.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.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); } 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.createTpcFlowsWidget(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, }); } createTpcFlowsWidget(width, height) { const left = []; const right = []; if (this.activeTcpFlowCountMetric) { left.push(this.activeTcpFlowCountMetric); } if (this.newTcpFlowCountMetric) { left.push(this.newTcpFlowCountMetric); } 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, }); } } exports.Ec2ServiceMonitoring = Ec2ServiceMonitoring; _a = JSII_RTTI_SYMBOL_1; Ec2ServiceMonitoring[_a] = { fqn: "cdk-monitoring-constructs.Ec2ServiceMonitoring", version: "1.21.0" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRWMyU2VydmljZU1vbml0b3JpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJFYzJTZXJ2aWNlTW9uaXRvcmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLCtEQUtvQztBQWFwQyx5Q0F1QnNCO0FBQ3RCLCtDQUd5QjtBQUN6Qiw0REFLOEI7QUFDOUIseUVBQXNFO0FBeUZ0RSxNQUFhLG9CQUFxQixTQUFRLG1CQUFVO0lBMkJsRCxZQUFZLEtBQXNCLEVBQUUsS0FBc0M7UUFDeEUsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVwQixJQUFJLENBQUMsZUFBZTtZQUNsQixLQUFLLENBQUMsWUFBWSxLQUFLLFNBQVMsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFNBQVMsQ0FBQztRQUV0RSxNQUFNLGNBQWMsR0FBRyxJQUFJLG9DQUF3QixDQUFDO1lBQ2xELEdBQUcsS0FBSztZQUNSLGNBQWMsRUFBRSxLQUFLLENBQUMsVUFBVTtTQUNqQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBRXZELElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFDakQsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksbURBQXdCLENBQzFELElBQUksQ0FBQyxhQUFhLEVBQ2xCLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FDOUIsQ0FBQztRQUNGLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUN4QixJQUFJLENBQUMseUJBQXlCLEdBQUcsbURBQStCLENBQzlELElBQUksQ0FBQyxhQUFhLEVBQ2xCLEtBQUssQ0FBQyxZQUFZLEVBQ2xCLEtBQUssQ0FBQyxXQUFXLENBQ2xCLENBQUM7WUFDRixJQUFJLENBQUMsc0JBQXNCO2dCQUN6QixJQUFJLENBQUMseUJBQXlCLENBQUMsc0JBQXNCLEVBQUUs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TTtZQUNOLEtBQUssRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLFlBQVk7WUFDMUQsSUFBSTtZQUNKLFNBQVMsRUFBRSwwQkFBaUI7WUFDNUIsZUFBZSxFQUFFLElBQUksQ0FBQyxxQkFBcUI7U0FDNUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVTLG9CQUFvQixDQUFDLEtBQWEsRUFBRSxNQUFjO1FBQzFELE1BQU0sSUFBSSxHQUFjLEVBQUUsQ0FBQztRQUMzQixNQUFNLEtBQUssR0FBYyxFQUFFLENBQUM7UUFFNUIsSUFBSSxJQUFJLENBQUMsd0JBQXdCLEVBQUU7WUFDakMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQztTQUMxQztRQUVELElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFO1lBQzlCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUM7U0FDdkM7UUFFRCxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtZQUM3QixLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1NBQ3ZDO1FBRUQsT0FBTyxJQUFJLDRCQUFXLENBQUM7WUFDckIsS0FBSztZQUNMLE1BQU07WUFDTixLQUFLLEVBQUUsV0FBVztZQUNsQixJQUFJO1lBQ0osU0FBUyxFQUFFLDBCQUFpQjtZQUM1QixLQUFLO1lBQ0wsVUFBVSxFQUFFLDhCQUFxQjtTQUNsQyxDQUFDLENBQUM7SUFDTCxDQUFDOztBQXRTSCxvREF1U0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFdpZGdldCxcbiAgSG9yaXpvbnRhbEFubm90YXRpb24sXG4gIElNZXRyaWMsXG4gIElXaWRnZXQsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaFwiO1xuaW1wb3J0IHsgRWMyU2VydmljZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZWNzXCI7XG5pbXBvcnQge1xuICBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlZEVjMlNlcnZpY2UsXG4gIE5ldHdvcmtMb2FkQmFsYW5jZWRFYzJTZXJ2aWNlLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjcy1wYXR0ZXJuc1wiO1xuaW1wb3J0IHtcbiAgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsXG4gIEFwcGxpY2F0aW9uVGFyZ2V0R3JvdXAsXG4gIE5ldHdvcmtMb2FkQmFsYW5jZXIsXG4gIE5ldHdvcmtUYXJnZXRHcm91cCxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lbGFzdGljbG9hZGJhbGFuY2luZ3YyXCI7XG5cbmltcG9ydCB7XG4gIEJhc2VNb25pdG9yaW5nUHJvcHMsXG4gIENvdW50QXhpc0Zyb21aZXJvLFxuICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0LFxuICBIZWFsdGh5VGFza0NvdW50VGhyZXNob2xkLFxuICBIZWFsdGh5VGFza1BlcmNlbnRUaHJlc2hvbGQsXG4gIE1ldHJpY0ZhY3RvcnksXG4gIE1ldHJpY1dpdGhBbGFybVN1cHBvcnQsXG4gIE1pblByb2Nlc3NlZEJ5dGVzVGhyZXNob2xkLFxuICBNb25pdG9yaW5nLFxuICBNb25pdG9yaW5nU2NvcGUsXG4gIE5ldXRyYWxDb2xvcixcbiAgUGVyY2VudGFnZUF4aXNGcm9tWmVyb1RvSHVuZHJlZCxcbiAgUXVhcnRlcldpZHRoLFxuICBSdW5uaW5nVGFza0NvdW50VGhyZXNob2xkLFxuICBTaXplQXhpc0J5dGVzRnJvbVplcm8sXG4gIFRhc2tIZWFsdGhBbGFybUZhY3RvcnksXG4gIFRoaXJkV2lkdGgsXG4gIFRocm91Z2hwdXRBbGFybUZhY3RvcnksXG4gIFVuaGVhbHRoeVRhc2tDb3VudFRocmVzaG9sZCxcbiAgVXNhZ2VBbGFybUZhY3RvcnksXG4gIFVzYWdlVGhyZXNob2xkLFxufSBmcm9tIFwiLi4vLi4vY29tbW9uXCI7XG5pbXBvcnQge1xuICBNb25pdG9yaW5nSGVhZGVyV2lkZ2V0LFxuICBNb25pdG9yaW5nTmFtaW5nU3RyYXRlZ3ksXG59IGZyb20gXCIuLi8uLi9kYXNoYm9hcmRcIjtcbmltcG9ydCB7XG4gIEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeVByb3BzLFxuICBJTG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeSxcbiAgTmV0d29ya0xvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgY3JlYXRlTG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeSxcbn0gZnJvbSBcIi4uL2F3cy1sb2FkYmFsYW5jaW5nXCI7XG5pbXBvcnQgeyBCYXNlU2VydmljZU1ldHJpY0ZhY3RvcnkgfSBmcm9tIFwiLi9CYXNlU2VydmljZU1ldHJpY0ZhY3RvcnlcIjtcblxuZXhwb3J0IGludGVyZmFjZSBCYXNlRWMyU2VydmljZUFsYXJtcyB7XG4gIC8qKlxuICAgKiBtaW5pbXVtIG51bWJlciBvZiB0YXNrcywgYXMgc3BlY2lmaWVkIGluIHlvdXIgYXV0byBzY2FsaW5nIGNvbmZpZ1xuICAgKi9cbiAgcmVhZG9ubHkgbWluQXV0b1NjYWxpbmdUYXNrQ291bnQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBtYXhpbXVtIG51bWJlciBvZiB0YXNrcywgYXMgc3BlY2lmaWVkIGluIHlvdXIgYXV0byBzY2FsaW5nIGNvbmZpZ1xuICAgKi9cbiAgcmVhZG9ubHkgbWF4QXV0b1NjYWxpbmdUYXNrQ291bnQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBDb250YWluZXIgSW5zaWdodHMgbmVlZHMgdG8gYmUgZW5hYmxlZCBmb3IgdGhlIGNsdXN0ZXIgZm9yIHRoaXMgYWxhcm1cbiAgICovXG4gIHJlYWRvbmx5IGFkZFJ1bm5pbmdUYXNrQ291bnRBbGFybT86IFJlY29yZDxzdHJpbmcsIFJ1bm5pbmdUYXNrQ291bnRUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRDcHVVc2FnZUFsYXJtPzogUmVjb3JkPHN0cmluZywgVXNhZ2VUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRNZW1vcnlVc2FnZUFsYXJtPzogUmVjb3JkPHN0cmluZywgVXNhZ2VUaHJlc2hvbGQ+O1xufVxuXG4vKipcbiAqIE1vbml0b3JpbmcgcHJvcHMgZm9yIGFueSB0eXBlIG9mIEVDMiBzZXJ2aWNlLlxuICovXG5pbnRlcmZhY2UgQmFzZUVjMlNlcnZpY2VNb25pdG9yaW5nUHJvcHNcbiAgZXh0ZW5kcyBCYXNlTW9uaXRvcmluZ1Byb3BzLFxuICAgIEJhc2VFYzJTZXJ2aWNlQWxhcm1zIHt9XG5cbi8qKlxuICogTW9uaXRvcmluZyBwcm9wcyBmb3IgU2ltcGxlIEVDMiBzZXJ2aWNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNpbXBsZUVjMlNlcnZpY2VNb25pdG9yaW5nUHJvcHNcbiAgZXh0ZW5kcyBCYXNlRWMyU2VydmljZU1vbml0b3JpbmdQcm9wcyB7XG4gIHJlYWRvbmx5IGVjMlNlcnZpY2U6IEVjMlNlcnZpY2U7XG59XG5cbi8qKlxuICogQmFzZSBvZiBNb25pdG9yaW5nIHByb3BzIGZvciBsb2FkLWJhbGFuY2VkIEVDMiBzZXJ2aWNlLlxuICovXG5pbnRlcmZhY2UgQmFzZUxvYWRCYWxhbmNlZEVjMlNlcnZpY2VNb25pdG9yaW5nUHJvcHNcbiAgZXh0ZW5kcyBCYXNlRWMyU2VydmljZU1vbml0b3JpbmdQcm9wcyB7XG4gIHJlYWRvbmx5IGFkZEhlYWx0aHlUYXNrQ291bnRBbGFybT86IFJlY29yZDxzdHJpbmcsIEhlYWx0aHlUYXNrQ291bnRUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRVbmhlYWx0aHlUYXNrQ291bnRBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgVW5oZWFsdGh5VGFza0NvdW50VGhyZXNob2xkXG4gID47XG4gIHJlYWRvbmx5IGFkZEhlYWx0aHlUYXNrUGVyY2VudEFsYXJtPzogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBIZWFsdGh5VGFza1BlcmNlbnRUaHJlc2hvbGRcbiAgPjtcbiAgcmVhZG9ubHkgYWRkTWluUHJvY2Vzc2VkQnl0ZXNBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgTWluUHJvY2Vzc2VkQnl0ZXNUaHJlc2hvbGRcbiAgPjtcbn1cblxuLyoqXG4gKiBNb25pdG9yaW5nIHByb3BzIGZvciBsb2FkLWJhbGFuY2VkIEVDMiBzZXJ2aWNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVjMlNlcnZpY2VNb25pdG9yaW5nUHJvcHNcbiAgZXh0ZW5kcyBCYXNlTG9hZEJhbGFuY2VkRWMyU2VydmljZU1vbml0b3JpbmdQcm9wcyB7XG4gIHJlYWRvbmx5IGVjMlNlcnZpY2U6XG4gICAgfCBOZXR3b3JrTG9hZEJhbGFuY2VkRWMyU2VydmljZVxuICAgIHwgQXBwbGljYXRpb25Mb2FkQmFsYW5jZWRFYzJTZXJ2aWNlO1xufVxuXG4vKipcbiAqIE1vbml0b3JpbmcgcHJvcHMgZm9yIEVDMiBzZXJ2aWNlIHdpdGggbmV0d29yayBsb2FkIGJhbGFuY2VyIGFuZCBwbGFpbiBzZXJ2aWNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVjMk5ldHdvcmtMb2FkQmFsYW5jZXJNb25pdG9yaW5nUHJvcHNcbiAgZXh0ZW5kcyBOZXR3b3JrTG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeVByb3BzLFxuICAgIEJhc2VMb2FkQmFsYW5jZWRFYzJTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzIHtcbiAgcmVhZG9ubHkgZWMyU2VydmljZTogRWMyU2VydmljZTtcbn1cblxuLyoqXG4gKiBNb25pdG9yaW5nIHByb3BzIGZvciBFQzIgc2VydmljZSB3aXRoIGFwcGxpY2F0aW9uIGxvYWQgYmFsYW5jZXIgYW5kIHBsYWluIHNlcnZpY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRWMyQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNb25pdG9yaW5nUHJvcHNcbiAgZXh0ZW5kcyBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgICBCYXNlTG9hZEJhbGFuY2VkRWMyU2VydmljZU1vbml0b3JpbmdQcm9wcyB7XG4gIHJlYWRvbmx5IGVjMlNlcnZpY2U6IEVjMlNlcnZpY2U7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3VzdG9tRWMyU2VydmljZU1vbml0b3JpbmdQcm9wc1xuICBleHRlbmRzIEJhc2VMb2FkQmFsYW5jZWRFYzJTZXJ2aWNlTW9uaXRvcmluZ1Byb3BzIHtcbiAgcmVhZG9ubHkgZWMyU2VydmljZTogRWMyU2VydmljZTtcbiAgcmVhZG9ubHkgbG9hZEJhbGFuY2VyPzogQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIgfCBOZXR3b3JrTG9hZEJhbGFuY2VyO1xuICByZWFkb25seSB0YXJnZXRHcm91cD86IEFwcGxpY2F0aW9uVGFyZ2V0R3JvdXAgfCBOZXR3b3JrVGFyZ2V0R3JvdXA7XG59XG5cbmV4cG9ydCBjbGFzcyBFYzJTZXJ2aWNlTW9uaXRvcmluZyBleHRlbmRzIE1vbml0b3Jpbmcge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbWV0cmljRmFjdG9yeTogTWV0cmljRmFjdG9yeTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGJhc2VTZXJ2aWNlTWV0cmljRmFjdG9yeTogQmFzZVNlcnZpY2VNZXRyaWNGYWN0b3J5O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeT86IElMb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5O1xuXG4gIHByb3RlY3RlZCByZWFkb25seSB0YXNrSGVhbHRoQWxhcm1GYWN0b3J5OiBUYXNrSGVhbHRoQWxhcm1GYWN0b3J5O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgdGhyb3VnaHB1dEFsYXJtRmFjdG9yeTogVGhyb3VnaHB1dEFsYXJtRmFjdG9yeTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHRhc2tIZWFsdGhBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHVzYWdlQWxhcm1GYWN0b3J5OiBVc2FnZUFsYXJtRmFjdG9yeTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNwdVVzYWdlQW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHByb3RlY3RlZCByZWFkb25seSBtZW1vcnlVc2FnZUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcHJvY2Vzc2VkQnl0ZXNBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaGVhbHRoeVRhc2tDb3VudE1ldHJpYz86IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHByb3RlY3RlZCByZWFkb25seSB1bmhlYWx0aHlUYXNrQ291bnRNZXRyaWM/OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaGVhbHRoeVRhc2tQZXJjZW50TWV0cmljPzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHJ1bm5pbmdUYXNrQ291bnRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHByb3RlY3RlZCByZWFkb25seSBjcHVVdGlsaXNhdGlvbk1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IG1lbW9yeVV0aWxpc2F0aW9uTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYWN0aXZlVGNwRmxvd0NvdW50TWV0cmljPzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IG5ld1RjcEZsb3dDb3VudE1ldHJpYz86IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHByb3RlY3RlZCByZWFkb25seSBwcm9jZXNzZWRCeXRlc01ldHJpYz86IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG5cbiAgcHJpdmF0ZSBoYXNMb2FkQmFsYW5jZXI6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IE1vbml0b3JpbmdTY29wZSwgcHJvcHM6IEN1c3RvbUVjMlNlcnZpY2VNb25pdG9yaW5nUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgcHJvcHMpO1xuXG4gICAgdGhpcy5oYXNMb2FkQmFsYW5jZXIgPVxuICAgICAgcHJvcHMubG9hZEJhbGFuY2VyICE9PSB1bmRlZmluZWQgJiYgcHJvcHMudGFyZ2V0R3JvdXAgIT09IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IG5hbWluZ1N0cmF0ZWd5ID0gbmV3IE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSh7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIG5hbWVkQ29uc3RydWN0OiBwcm9wcy5lYzJTZXJ2aWNlLFxuICAgIH0pO1xuICAgIHRoaXMudGl0bGUgPSBuYW1pbmdTdHJhdGVneS5yZXNvbHZlSHVtYW5SZWFkYWJsZU5hbWUoKTtcblxuICAgIHRoaXMubWV0cmljRmFjdG9yeSA9IHNjb3BlLmNyZWF0ZU1ldHJpY0ZhY3RvcnkoKTtcbiAgICB0aGlzLmJhc2VTZXJ2aWNlTWV0cmljRmFjdG9yeSA9IG5ldyBCYXNlU2VydmljZU1ldHJpY0ZhY3RvcnkoXG4gICAgICB0aGlzLm1ldHJpY0ZhY3RvcnksXG4gICAgICB7IHNlcnZpY2U6IHByb3BzLmVjMlNlcnZpY2UgfVxuICAgICk7XG4gICAgaWYgKHRoaXMuaGFzTG9hZEJhbGFuY2VyKSB7XG4gICAgICB0aGlzLmxvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnkgPSBjcmVhdGVMb2FkQmFsYW5jZXJNZXRyaWNGYWN0b3J5KFxuICAgICAgICB0aGlzLm1ldHJpY0ZhY3RvcnksXG4gICAgICAgIHByb3BzLmxvYWRCYWxhbmNlcixcbiAgICAgICAgcHJvcHMudGFyZ2V0R3JvdXBcbiAgICAgICk7XG4gICAgICB0aGlzLmhlYWx0aHlUYXNrQ291bnRNZXRyaWMgPVxuICAgICAgICB0aGlzLmxvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnkubWV0cmljSGVhbHRoeVRhc2tDb3VudCgpO1xuICAgICAgdGhpcy51bmhlYWx0aHlUYXNrQ291bnRNZXRyaWMgPVxuICAgICAgICB0aGlzLmxvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnkubWV0cmljVW5oZWFsdGh5VGFza0NvdW50KCk7XG4gICAgICB0aGlzLmhlYWx0aHlUYXNrUGVyY2VudE1ldHJpYyA9XG4gICAgICAgIHRoaXMubG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeS5tZXRyaWNIZWFsdGh5VGFza0luUGVyY2VudCgpO1xuICAgICAgdGhpcy5hY3RpdmVUY3BGbG93Q291bnRNZXRyaWMgPVxuICAgICAgICB0aGlzLmxvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnkubWV0cmljQWN0aXZlQ29ubmVjdGlvbkNvdW50KCk7XG4gICAgICB0aGlzLm5ld1RjcEZsb3dDb3VudE1ldHJpYyA9XG4gICAgICAgIHRoaXMubG9hZEJhbGFuY2VyTWV0cmljRmFjdG9yeS5tZXRyaWNOZXdDb25uZWN0aW9uQ291bnQoKTtcbiAgICAgIHRoaXMucHJvY2Vzc2VkQnl0ZXNNZXRyaWMgPVxuICAgICAgICB0aGlzLmxvYWRCYWxhbmNlck1ldHJpY0ZhY3RvcnkubWV0cmljUHJvY2Vzc2VkQnl0ZXNNaW4oKTtcbiAgICB9XG4gICAgdGhpcy5ydW5uaW5nVGFza0NvdW50TWV0cmljID1cbiAgICAgIHRoaXMuYmFzZVNlcnZpY2VNZXRyaWNGYWN0b3J5Lm1ldHJpY1J1bm5pbmdUYXNrQ291bnQoKTtcbiAgICB0aGlzLmNwdVV0aWxpc2F0aW9uTWV0cmljID1cbiAgICAgIHRoaXMuYmFzZVNlcnZpY2VNZXRyaWNGYWN0b3J5Lm1ldHJpY0NsdXN0ZXJDcHVVdGlsaXNhdGlvbkluUGVyY2VudCgpO1xuICAgIHRoaXMubWVtb3J5VXRpbGlzYXRpb25NZXRyaWMgPVxuICAgICAgdGhpcy5iYXNlU2VydmljZU1ldHJpY0ZhY3RvcnkubWV0cmljQ2x1c3Rlck1lbW9yeVV0aWxpc2F0aW9uSW5QZXJjZW50KCk7XG5cbiAgICBjb25zdCBhbGFybUZhY3RvcnkgPSB0aGlzLmNyZWF0ZUFsYXJtRmFjdG9yeShcbiAgICAgIG5hbWluZ1N0cmF0ZWd5LnJlc29sdmVBbGFybUZyaWVuZGx5TmFtZSgpXG4gICAgKTtcbiAgICB0aGlzLnRhc2tIZWFsdGhBbGFybUZhY3RvcnkgPSBuZXcgVGFza0hlYWx0aEFsYXJtRmFjdG9yeShhbGFybUZhY3RvcnkpO1xuICAgIHRoaXMudGhyb3VnaHB1dEFsYXJtRmFjdG9yeSA9IG5ldyBUaHJvdWdocHV0QWxhcm1GYWN0b3J5KGFsYXJtRmFjdG9yeSk7XG4gICAgdGhpcy50YXNrSGVhbHRoQW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLnVzYWdlQWxhcm1GYWN0b3J5ID0gbmV3IFVzYWdlQWxhcm1GYWN0b3J5KGFsYXJtRmFjdG9yeSk7XG4gICAgdGhpcy5jcHVVc2FnZUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5tZW1vcnlVc2FnZUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5wcm9jZXNzZWRCeXRlc0Fubm90YXRpb25zID0gW107XG5cbiAgICBpZiAocHJvcHMubWluQXV0b1NjYWxpbmdUYXNrQ291bnQpIHtcbiAgICAgIC8vIFRPRE86IHVzZSBhbm5vdGF0aW9uIHN0cmF0ZWd5IHRvIGNyZWF0ZSBuZXV0cmFsIGFubm90YXRpb25cbiAgICAgIHRoaXMudGFza0hlYWx0aEFubm90YXRpb25zLnB1c2goe1xuICAgICAgICB2YWx1ZTogcHJvcHMubWluQXV0b1NjYWxpbmdUYXNrQ291bnQsXG4gICAgICAgIGxhYmVsOiBcIkF1dG9TY2FsaW5nOiBNaW5cIixcbiAgICAgICAgY29sb3I6IE5ldXRyYWxDb2xvcixcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAocHJvcHMubWF4QXV0b1NjYWxpbmdUYXNrQ291bnQpIHtcbiAgICAgIC8vIFRPRE86IHVzZSBhbm5vdGF0aW9uIHN0cmF0ZWd5IHRvIGNyZWF0ZSBuZXV0cmFsIGFubm90YXRpb25cbiAgICAgIHRoaXMudGFza0hlYWx0aEFubm90YXRpb25zLnB1c2goe1xuICAgICAgICB2YWx1ZTogcHJvcHMubWF4QXV0b1NjYWxpbmdUYXNrQ291bnQsXG4gICAgICAgIGxhYmVsOiBcIkF1dG9TY2FsaW5nOiBNYXhcIixcbiAgICAgICAgY29sb3I6IE5ldXRyYWxDb2xvcixcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmhhc0xvYWRCYWxhbmNlcikge1xuICAgICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZEhlYWx0aHlUYXNrQ291bnRBbGFybSkge1xuICAgICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkSGVhbHRoeVRhc2tDb3VudEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPVxuICAgICAgICAgIHRoaXMudGFza0hlYWx0aEFsYXJtRmFjdG9yeS5hZGRIZWFsdGh5VGFza0NvdW50QWxhcm0oXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgdGhpcy5oZWFsdGh5VGFza0NvdW50TWV0cmljISxcbiAgICAgICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICAgICAgKTtcbiAgICAgICAgdGhpcy50YXNrSGVhbHRoQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRVbmhlYWx0aHlUYXNrQ291bnRBbGFybSkge1xuICAgICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkVW5oZWFsdGh5VGFza0NvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9XG4gICAgICAgICAgdGhpcy50YXNrSGVhbHRoQWxhcm1GYWN0b3J5LmFkZFVuaGVhbHRoeVRhc2tDb3VudEFsYXJtKFxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgIHRoaXMudW5oZWFsdGh5VGFza0NvdW50TWV0cmljISxcbiAgICAgICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICAgICAgKTtcbiAgICAgICAgdGhpcy50YXNrSGVhbHRoQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRIZWFsdGh5VGFza1BlcmNlbnRBbGFybSkge1xuICAgICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkSGVhbHRoeVRhc2tQZXJjZW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9XG4gICAgICAgICAgdGhpcy50YXNrSGVhbHRoQWxhcm1GYWN0b3J5LmFkZEhlYWx0aHlUYXNrUGVyY2VudEFsYXJtKFxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgIHRoaXMuaGVhbHRoeVRhc2tQZXJjZW50TWV0cmljISxcbiAgICAgICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRSdW5uaW5nVGFza0NvdW50QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRSdW5uaW5nVGFza0NvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLnRhc2tIZWFsdGhBbGFybUZhY3RvcnkuYWRkUnVubmluZ1Rhc2tDb3VudEFsYXJtKFxuICAgICAgICB0aGlzLnJ1bm5pbmdUYXNrQ291bnRNZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3JcbiAgICAgICk7XG4gICAgICB0aGlzLnRhc2tIZWFsdGhBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZENwdVVzYWdlQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRDcHVVc2FnZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy51c2FnZUFsYXJtRmFjdG9yeS5hZGRNYXhDcHVVc2FnZVBlcmNlbnRBbGFybShcbiAgICAgICAgdGhpcy5jcHVVdGlsaXNhdGlvbk1ldHJpYyxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvclxuICAgICAgKTtcbiAgICAgIHRoaXMuY3B1VXNhZ2VBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZE1lbW9yeVVzYWdlQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRNZW1vcnlVc2FnZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy51c2FnZUFsYXJtRmFjdG9yeS5hZGRNYXhNZW1vcnlVc2FnZVBlcmNlbnRBbGFybShcbiAgICAgICAgdGhpcy5tZW1vcnlVdGlsaXNhdGlvbk1ldHJpYyxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvclxuICAgICAgKTtcbiAgICAgIHRoaXMubWVtb3J5VXNhZ2VBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5oYXNMb2FkQmFsYW5jZXIpIHtcbiAgICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRNaW5Qcm9jZXNzZWRCeXRlc0FsYXJtKSB7XG4gICAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRNaW5Qcm9jZXNzZWRCeXRlc0FsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPVxuICAgICAgICAgIHRoaXMudGhyb3VnaHB1dEFsYXJtRmFjdG9yeS5hZGRNaW5Qcm9jZXNzZWRCeXRlc0FsYXJtKFxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgIHRoaXMucHJvY2Vzc2VkQnl0ZXNNZXRyaWMhLFxuICAgICAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgICAgIGRpc2FtYmlndWF0b3JcbiAgICAgICAgICApO1xuICAgICAgICB0aGlzLnByb2Nlc3NlZEJ5dGVzQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcm9wcy51c2VDcmVhdGVkQWxhcm1zPy5jb25zdW1lKHRoaXMuY3JlYXRlZEFsYXJtcygpKTtcbiAgfVxuXG4gIHN1bW1hcnlXaWRnZXRzKCk6IElXaWRnZXRbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMuY3JlYXRlVGl0bGVXaWRnZXQoKSxcbiAgICAgIHRoaXMuY3JlYXRlQ3B1V2lkZ2V0KFRoaXJkV2lkdGgsIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0KSxcbiAgICAgIHRoaXMuY3JlYXRlTWVtb3J5V2lkZ2V0KFRoaXJkV2lkdGgsIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0KSxcbiAgICAgIHRoaXMuY3JlYXRlVGFza0hlYWx0aFdpZGdldChUaGlyZFdpZHRoLCBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCksXG4gICAgXTtcbiAgfVxuXG4gIHdpZGdldHMoKTogSVdpZGdldFtdIHtcbiAgICBjb25zdCBiYXNlV2lkZ2V0ID0gW1xuICAgICAgdGhpcy5jcmVhdGVUaXRsZVdpZGdldCgpLFxuICAgICAgdGhpcy5jcmVhdGVDcHVXaWRnZXQoXG4gICAgICAgIHRoaXMuaGFzTG9hZEJhbGFuY2VyID8gUXVhcnRlcldpZHRoIDogVGhpcmRXaWR0aCxcbiAgICAgICAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0XG4gICAgICApLFxuICAgICAgdGhpcy5jcmVhdGVNZW1vcnlXaWRnZXQoXG4gICAgICAgIHRoaXMuaGFzTG9hZEJhbGFuY2VyID8gUXVhcnRlcldpZHRoIDogVGhpcmRXaWR0aCxcbiAgICAgICAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0XG4gICAgICApLFxuICAgIF07XG5cbiAgICBpZiAodGhpcy5oYXNMb2FkQmFsYW5jZXIpIHtcbiAgICAgIHJldHVybiBiYXNlV2lkZ2V0LmNvbmNhdChbXG4gICAgICAgIHRoaXMuY3JlYXRlVHBjRmxvd3NXaWRnZXQoUXVhcnRlcldpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgICB0aGlzLmNyZWF0ZVRhc2tIZWFsdGhXaWRnZXQoUXVhcnRlcldpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBiYXNlV2lkZ2V0LmNvbmNhdChcbiAgICAgICAgdGhpcy5jcmVhdGVUYXNrSGVhbHRoV2lkZ2V0KFRoaXJkV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodClcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZVRpdGxlV2lkZ2V0KCkge1xuICAgIHJldHVybiBuZXcgTW9uaXRvcmluZ0hlYWRlcldpZGdldCh7XG4gICAgICBmYW1pbHk6IFwiRWMyIFNlcnZpY2VcIixcbiAgICAgIHRpdGxlOiB0aGlzLnRpdGxlLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZUNwdVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJDUFUgVXRpbGl6YXRpb25cIixcbiAgICAgIGxlZnQ6IFt0aGlzLmNwdVV0aWxpc2F0aW9uTWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogUGVyY2VudGFnZUF4aXNGcm9tWmVyb1RvSHVuZHJlZCxcbiAgICAgIGxlZnRBbm5vdGF0aW9uczogdGhpcy5jcHVVc2FnZUFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZU1lbW9yeVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJNZW1vcnkgVXRpbGl6YXRpb25cIixcbiAgICAgIGxlZnQ6IFt0aGlzLm1lbW9yeVV0aWxpc2F0aW9uTWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogUGVyY2VudGFnZUF4aXNGcm9tWmVyb1RvSHVuZHJlZCxcbiAgICAgIGxlZnRBbm5vdGF0aW9uczogdGhpcy5tZW1vcnlVc2FnZUFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZVRhc2tIZWFsdGhXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICBjb25zdCBsZWZ0ID0gW3RoaXMucnVubmluZ1Rhc2tDb3VudE1ldHJpY107XG5cbiAgICBpZiAodGhpcy5oZWFsdGh5VGFza0NvdW50TWV0cmljKSB7XG4gICAgICBsZWZ0LnB1c2godGhpcy5oZWFsdGh5VGFza0NvdW50TWV0cmljKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy51bmhlYWx0aHlUYXNrQ291bnRNZXRyaWMpIHtcbiAgICAgIGxlZnQucHVzaCh0aGlzLnVuaGVhbHRoeVRhc2tDb3VudE1ldHJpYyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiB0aGlzLmhhc0xvYWRCYWxhbmNlciA/IFwiVGFzayBIZWFsdGhcIiA6IFwiVGFzayBDb3VudFwiLFxuICAgICAgbGVmdCxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMudGFza0hlYWx0aEFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZVRwY0Zsb3dzV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgY29uc3QgbGVmdDogSU1ldHJpY1tdID0gW107XG4gICAgY29uc3QgcmlnaHQ6IElNZXRyaWNbXSA9IFtdO1xuXG4gICAgaWYgKHRoaXMuYWN0aXZlVGNwRmxvd0NvdW50TWV0cmljKSB7XG4gICAgICBsZWZ0LnB1c2godGhpcy5hY3RpdmVUY3BGbG93Q291bnRNZXRyaWMpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm5ld1RjcEZsb3dDb3VudE1ldHJpYykge1xuICAgICAgbGVmdC5wdXNoKHRoaXMubmV3VGNwRmxvd0NvdW50TWV0cmljKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wcm9jZXNzZWRCeXRlc01ldHJpYykge1xuICAgICAgcmlnaHQucHVzaCh0aGlzLnByb2Nlc3NlZEJ5dGVzTWV0cmljKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiVENQIEZsb3dzXCIsXG4gICAgICBsZWZ0LFxuICAgICAgbGVmdFlBeGlzOiBDb3VudEF4aXNGcm9tWmVybyxcbiAgICAgIHJpZ2h0LFxuICAgICAgcmlnaHRZQXhpczogU2l6ZUF4aXNCeXRlc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG59XG4iXX0=