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

288 lines 59.6 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.RdsClusterMonitoring = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch"); const RdsClusterMetricFactory_1 = require("./RdsClusterMetricFactory"); const common_1 = require("../../common"); const dashboard_1 = require("../../dashboard"); const DefaultLatencyTypesToRender = [ common_1.LatencyType.P50, common_1.LatencyType.P90, common_1.LatencyType.P99, ]; class RdsClusterMonitoring extends common_1.Monitoring { constructor(scope, props) { super(scope, props); const metricFactory = new RdsClusterMetricFactory_1.RdsClusterMetricFactory(scope.createMetricFactory(), props); this.connectionsMetric = metricFactory.metricTotalConnectionCount(); this.diskSpaceUsageMetric = metricFactory.metricDiskSpaceUsageInPercent(); this.cpuUsageMetric = metricFactory.metricAverageCpuUsageInPercent(); this.readIopsMetric = metricFactory.metricReadIOPS(); this.writeIopsMetric = metricFactory.metricWriteIOPS(); this.selectLatencyMetrics = {}; this.insertLatencyMetrics = {}; this.updateLatencyMetrics = {}; this.deleteLatencyMetrics = {}; this.commitLatencyMetrics = {}; this.latencyTypesToRender = [ ...(props.latencyTypesToRender ?? DefaultLatencyTypesToRender), ]; Object.values(common_1.LatencyType).forEach((latencyType) => { this.selectLatencyMetrics[latencyType] = metricFactory.metricSelectLatencyInMillis(latencyType); this.insertLatencyMetrics[latencyType] = metricFactory.metricInsertLatencyInMillis(latencyType); this.updateLatencyMetrics[latencyType] = metricFactory.metricUpdateLatencyInMillis(latencyType); this.deleteLatencyMetrics[latencyType] = metricFactory.metricDeleteLatencyInMillis(latencyType); this.commitLatencyMetrics[latencyType] = metricFactory.metricCommitLatencyInMillis(latencyType); }); const namingStrategy = new dashboard_1.MonitoringNamingStrategy({ ...props, fallbackConstructName: metricFactory.clusterIdentifier, namedConstruct: props.cluster, }); this.title = namingStrategy.resolveHumanReadableName(); this.url = scope .createAwsConsoleUrlFactory() .getRdsClusterUrl(metricFactory.clusterIdentifier); const alarmFactory = this.createAlarmFactory(namingStrategy.resolveAlarmFriendlyName()); this.usageAlarmFactory = new common_1.UsageAlarmFactory(alarmFactory); this.connectionAlarmFactory = new common_1.ConnectionAlarmFactory(alarmFactory); this.latencyAlarmFactory = new common_1.LatencyAlarmFactory(alarmFactory); this.usageAnnotations = []; this.connectionAnnotations = []; this.readLatencyAnnotations = []; this.writeLatencyAnnotations = []; this.iopsAnnotations = []; for (const disambiguator in props.addDiskSpaceUsageAlarm) { const alarmProps = props.addDiskSpaceUsageAlarm[disambiguator]; const createdAlarm = this.usageAlarmFactory.addMaxDiskUsagePercentAlarm(this.diskSpaceUsageMetric, alarmProps, disambiguator); this.usageAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addCpuUsageAlarm) { const alarmProps = props.addCpuUsageAlarm[disambiguator]; const createdAlarm = this.usageAlarmFactory.addMaxCpuUsagePercentAlarm(this.cpuUsageMetric, alarmProps, disambiguator); this.usageAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addMinConnectionCountAlarm) { const alarmProps = props.addMinConnectionCountAlarm[disambiguator]; const createdAlarm = this.connectionAlarmFactory.addMinConnectionCountAlarm(this.connectionsMetric, alarmProps, disambiguator); this.connectionAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addMaxConnectionCountAlarm) { const alarmProps = props.addMaxConnectionCountAlarm[disambiguator]; const createdAlarm = this.connectionAlarmFactory.addMaxConnectionCountAlarm(this.connectionsMetric, alarmProps, disambiguator); this.connectionAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } const selectLatencyAlarmDefinitions = { [common_1.LatencyType.P50]: props.addSelectLatencyP50Alarm, [common_1.LatencyType.P70]: props.addSelectLatencyP70Alarm, [common_1.LatencyType.P90]: props.addSelectLatencyP90Alarm, [common_1.LatencyType.P95]: props.addSelectLatencyP95Alarm, [common_1.LatencyType.P99]: props.addSelectLatencyP99Alarm, [common_1.LatencyType.P999]: props.addSelectLatencyP999Alarm, [common_1.LatencyType.P9999]: props.addSelectLatencyP9999Alarm, [common_1.LatencyType.P100]: props.addSelectLatencyP100Alarm, [common_1.LatencyType.AVERAGE]: props.addSelectLatencyAverageAlarm, }; const insertLatencyAlarmDefinitions = { [common_1.LatencyType.P50]: props.addInsertLatencyP50Alarm, [common_1.LatencyType.P70]: props.addInsertLatencyP70Alarm, [common_1.LatencyType.P90]: props.addInsertLatencyP90Alarm, [common_1.LatencyType.P95]: props.addInsertLatencyP95Alarm, [common_1.LatencyType.P99]: props.addInsertLatencyP99Alarm, [common_1.LatencyType.P999]: props.addInsertLatencyP999Alarm, [common_1.LatencyType.P9999]: props.addInsertLatencyP9999Alarm, [common_1.LatencyType.P100]: props.addInsertLatencyP100Alarm, [common_1.LatencyType.AVERAGE]: props.addInsertLatencyAverageAlarm, }; const updateLatencyAlarmDefinitions = { [common_1.LatencyType.P50]: props.addUpdateLatencyP50Alarm, [common_1.LatencyType.P70]: props.addUpdateLatencyP70Alarm, [common_1.LatencyType.P90]: props.addUpdateLatencyP90Alarm, [common_1.LatencyType.P95]: props.addUpdateLatencyP95Alarm, [common_1.LatencyType.P99]: props.addUpdateLatencyP99Alarm, [common_1.LatencyType.P999]: props.addUpdateLatencyP999Alarm, [common_1.LatencyType.P9999]: props.addUpdateLatencyP9999Alarm, [common_1.LatencyType.P100]: props.addUpdateLatencyP100Alarm, [common_1.LatencyType.AVERAGE]: props.addUpdateLatencyAverageAlarm, }; const deleteLatencyAlarmDefinitions = { [common_1.LatencyType.P50]: props.addDeleteLatencyP50Alarm, [common_1.LatencyType.P70]: props.addDeleteLatencyP70Alarm, [common_1.LatencyType.P90]: props.addDeleteLatencyP90Alarm, [common_1.LatencyType.P95]: props.addDeleteLatencyP95Alarm, [common_1.LatencyType.P99]: props.addDeleteLatencyP99Alarm, [common_1.LatencyType.P999]: props.addDeleteLatencyP999Alarm, [common_1.LatencyType.P9999]: props.addDeleteLatencyP9999Alarm, [common_1.LatencyType.P100]: props.addDeleteLatencyP100Alarm, [common_1.LatencyType.AVERAGE]: props.addDeleteLatencyAverageAlarm, }; const commitLatencyAlarmDefinitions = { [common_1.LatencyType.P50]: props.addCommitLatencyP50Alarm, [common_1.LatencyType.P70]: props.addCommitLatencyP70Alarm, [common_1.LatencyType.P90]: props.addCommitLatencyP90Alarm, [common_1.LatencyType.P95]: props.addCommitLatencyP95Alarm, [common_1.LatencyType.P99]: props.addCommitLatencyP99Alarm, [common_1.LatencyType.P999]: props.addCommitLatencyP999Alarm, [common_1.LatencyType.P9999]: props.addCommitLatencyP9999Alarm, [common_1.LatencyType.P100]: props.addCommitLatencyP100Alarm, [common_1.LatencyType.AVERAGE]: props.addCommitLatencyAverageAlarm, }; for (const [latencyType, alarmDefinition] of Object.entries(selectLatencyAlarmDefinitions)) { for (const disambiguator in alarmDefinition) { const alarmProps = alarmDefinition[disambiguator]; const latencyTypeEnum = latencyType; const metric = this.selectLatencyMetrics[latencyTypeEnum]; const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(metric, latencyTypeEnum, alarmProps, disambiguator, "Select"); this.readLatencyAnnotations.push(createdAlarm.annotation); this.latencyTypesToRender.push(latencyTypeEnum); this.addAlarm(createdAlarm); } } for (const [latencyType, alarmDefinition] of Object.entries(insertLatencyAlarmDefinitions)) { for (const disambiguator in alarmDefinition) { const alarmProps = alarmDefinition[disambiguator]; const latencyTypeEnum = latencyType; const metric = this.insertLatencyMetrics[latencyTypeEnum]; const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(metric, latencyTypeEnum, alarmProps, disambiguator, "Insert"); this.writeLatencyAnnotations.push(createdAlarm.annotation); this.latencyTypesToRender.push(latencyTypeEnum); this.addAlarm(createdAlarm); } } for (const [latencyType, alarmDefinition] of Object.entries(updateLatencyAlarmDefinitions)) { for (const disambiguator in alarmDefinition) { const alarmProps = alarmDefinition[disambiguator]; const latencyTypeEnum = latencyType; const metric = this.updateLatencyMetrics[latencyTypeEnum]; const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(metric, latencyTypeEnum, alarmProps, disambiguator, "Update"); this.writeLatencyAnnotations.push(createdAlarm.annotation); this.latencyTypesToRender.push(latencyTypeEnum); this.addAlarm(createdAlarm); } } for (const [latencyType, alarmDefinition] of Object.entries(deleteLatencyAlarmDefinitions)) { for (const disambiguator in alarmDefinition) { const alarmProps = alarmDefinition[disambiguator]; const latencyTypeEnum = latencyType; const metric = this.deleteLatencyMetrics[latencyTypeEnum]; const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(metric, latencyTypeEnum, alarmProps, disambiguator, "Delete"); this.writeLatencyAnnotations.push(createdAlarm.annotation); this.latencyTypesToRender.push(latencyTypeEnum); this.addAlarm(createdAlarm); } } for (const [latencyType, alarmDefinition] of Object.entries(commitLatencyAlarmDefinitions)) { for (const disambiguator in alarmDefinition) { const alarmProps = alarmDefinition[disambiguator]; const latencyTypeEnum = latencyType; const metric = this.commitLatencyMetrics[latencyTypeEnum]; const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(metric, latencyTypeEnum, alarmProps, disambiguator, "Commit"); this.writeLatencyAnnotations.push(createdAlarm.annotation); this.latencyTypesToRender.push(latencyTypeEnum); this.addAlarm(createdAlarm); } } for (const disambiguator in props.addReadIOPSAlarm) { const alarmProps = props.addReadIOPSAlarm[disambiguator]; const createdAlarm = this.usageAlarmFactory.addMaxReadIOPSAlarm(this.readIopsMetric, alarmProps, disambiguator); this.usageAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addWriteIOPSAlarm) { const alarmProps = props.addWriteIOPSAlarm[disambiguator]; const createdAlarm = this.usageAlarmFactory.addMaxWriteIOPSAlarm(this.writeIopsMetric, alarmProps, disambiguator); this.usageAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } props.useCreatedAlarms?.consume(this.createdAlarms()); } summaryWidgets() { return [ this.createTitleWidget(), this.createCpuAndDiskUsageWidget(common_1.QuarterWidth, common_1.DefaultSummaryWidgetHeight), this.createConnectionsWidget(common_1.QuarterWidth, common_1.DefaultSummaryWidgetHeight), this.createLatencyWidget(common_1.QuarterWidth, common_1.DefaultSummaryWidgetHeight), this.createIOPSWidget(common_1.QuarterWidth, common_1.DefaultSummaryWidgetHeight), ]; } widgets() { return [ this.createTitleWidget(), this.createCpuAndDiskUsageWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), this.createConnectionsWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), this.createLatencyWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), this.createIOPSWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), ]; } createTitleWidget() { return new dashboard_1.MonitoringHeaderWidget({ family: "RDS Cluster", title: this.title, goToLinkUrl: this.url, }); } createCpuAndDiskUsageWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "CPU/Disk Usage", left: [this.cpuUsageMetric, this.diskSpaceUsageMetric], leftYAxis: common_1.PercentageAxisFromZeroToHundred, leftAnnotations: this.usageAnnotations, }); } createConnectionsWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Connections", left: [this.connectionsMetric], leftYAxis: common_1.CountAxisFromZero, leftAnnotations: this.connectionAnnotations, }); } createLatencyWidget(width, height) { const left = Array.from(new Set(this.latencyTypesToRender)) .sort() .reduce((metrics, type) => { metrics.push(this.selectLatencyMetrics[type], this.insertLatencyMetrics[type], this.updateLatencyMetrics[type], this.deleteLatencyMetrics[type], this.commitLatencyMetrics[type]); return metrics; }, []); return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Query Duration", left, leftYAxis: common_1.TimeAxisMillisFromZero, leftAnnotations: [ ...this.readLatencyAnnotations, ...this.writeLatencyAnnotations, ], }); } createIOPSWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "IOPS", left: [this.readIopsMetric, this.writeIopsMetric], leftYAxis: common_1.CountAxisFromZero, leftAnnotations: this.iopsAnnotations, }); } } exports.RdsClusterMonitoring = RdsClusterMonitoring; _a = JSII_RTTI_SYMBOL_1; RdsClusterMonitoring[_a] = { fqn: "cdk-monitoring-constructs.RdsClusterMonitoring", version: "10.0.0" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmRzQ2x1c3Rlck1vbml0b3JpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJSZHNDbHVzdGVyTW9uaXRvcmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLCtEQUlvQztBQUVwQyx1RUFHbUM7QUFDbkMseUNBb0JzQjtBQUN0QiwrQ0FHeUI7QUFFekIsTUFBTSwyQkFBMkIsR0FBRztJQUNsQyxvQkFBVyxDQUFDLEdBQUc7SUFDZixvQkFBVyxDQUFDLEdBQUc7SUFDZixvQkFBVyxDQUFDLEdBQUc7Q0FDaEIsQ0FBQztBQWdGRixNQUFhLG9CQUFxQixTQUFRLG1CQUFVO0lBMkJsRCxZQUFZLEtBQXNCLEVBQUUsS0FBZ0M7UUFDbEUsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVwQixNQUFNLGFBQWEsR0FBRyxJQUFJLGlEQUF1QixDQUMvQyxLQUFLLENBQUMsbUJBQW1CLEVBQUUsRUFDM0IsS0FBSyxDQUNOLENBQUM7UUFDRixJQUFJLENBQUMsaUJBQWlCLEdBQUcsYUFBYSxDQUFDLDBCQUEwQixFQUFFLENBQUM7UUFDcEUsSUFBSSxDQUFDLG9CQUFvQixHQUFHLGFBQWEsQ0FBQyw2QkFBNkIsRUFBRSxDQUFDO1FBQzFFLElBQUksQ0FBQyxjQUFjLEdBQUcsYUFBYSxDQUFDLDhCQUE4QixFQUFFLENBQUM7UUFDckUsSUFBSSxDQUFDLGNBQWMsR0FBRyxhQUFhLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDckQsSUFBSSxDQUFDLGVBQWUsR0FBRyxhQUFhLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFdkQsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsb0JBQW9CLEdBQUcsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsb0JBQW9CLEdB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QUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMseUJBQXlCO1lBQ25ELENBQUMsb0JBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLENBQUMsMEJBQTBCO1lBQ3JELENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMseUJBQXlCO1lBQ25ELENBQUMsb0JBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLENBQUMsNEJBQTRCO1NBQzFELENBQUM7UUFFRixNQUFNLDZCQUE2QixHQUFHO1lBQ3BDLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMseUJBQXlCO1lBQ25ELENBQUMsb0JBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLENBQUMsMEJBQTBCO1lBQ3JELENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMseUJBQXlCO1lBQ25ELENBQUMsb0JBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLENBQUMsNEJBQTRCO1NBQzFELENBQUM7UUFFRixNQUFNLDZCQUE2QixHQUFHO1lBQ3BDLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMseUJBQXlCO1lBQ25ELENBQUMsb0JBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLENBQUMsMEJBQTBCO1lBQ3JELENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMseUJBQXlCO1lBQ25ELENBQUMsb0JBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLENBQUMsNEJBQTRCO1NBQzFELENBQUM7UUFFRixNQUFNLDZCQUE2QixHQUFHO1lBQ3BDLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMs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LENBQUM7SUFDTCxDQUFDOztBQXBaSCxvREFxWkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFdpZGdldCxcbiAgSG9yaXpvbnRhbEFubm90YXRpb24sXG4gIElXaWRnZXQsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaFwiO1xuXG5pbXBvcnQge1xuICBSZHNDbHVzdGVyTWV0cmljRmFjdG9yeSxcbiAgUmRzQ2x1c3Rlck1ldHJpY0ZhY3RvcnlQcm9wcyxcbn0gZnJvbSBcIi4vUmRzQ2x1c3Rlck1ldHJpY0ZhY3RvcnlcIjtcbmltcG9ydCB7XG4gIEJhc2VNb25pdG9yaW5nUHJvcHMsXG4gIENvbm5lY3Rpb25BbGFybUZhY3RvcnksXG4gIENvdW50QXhpc0Zyb21aZXJvLFxuICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0LFxuICBIaWdoQ29ubmVjdGlvbkNvdW50VGhyZXNob2xkLFxuICBMYXRlbmN5QWxhcm1GYWN0b3J5LFxuICBMYXRlbmN5VGhyZXNob2xkLFxuICBMYXRlbmN5VHlwZSxcbiAgTG93Q29ubmVjdGlvbkNvdW50VGhyZXNob2xkLFxuICBNYXhVc2FnZUNvdW50VGhyZXNob2xkLFxuICBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0LFxuICBNb25pdG9yaW5nLFxuICBNb25pdG9yaW5nU2NvcGUsXG4gIFBlcmNlbnRhZ2VBeGlzRnJvbVplcm9Ub0h1bmRyZWQsXG4gIFF1YXJ0ZXJXaWR0aCxcbiAgVGltZUF4aXNNaWxsaXNGcm9tWmVybyxcbiAgVXNhZ2VBbGFybUZhY3RvcnksXG4gIFVzYWdlVGhyZXNob2xkLFxufSBmcm9tIFwiLi4vLi4vY29tbW9uXCI7XG5pbXBvcnQge1xuICBNb25pdG9yaW5nSGVhZGVyV2lkZ2V0LFxuICBNb25pdG9yaW5nTmFtaW5nU3RyYXRlZ3ksXG59IGZyb20gXCIuLi8uLi9kYXNoYm9hcmRcIjtcblxuY29uc3QgRGVmYXVsdExhdGVuY3lUeXBlc1RvUmVuZGVyID0gW1xuICBMYXRlbmN5VHlwZS5QNTAsXG4gIExhdGVuY3lUeXBlLlA5MCxcbiAgTGF0ZW5jeVR5cGUuUDk5LFxuXTtcblxuZXhwb3J0IGludGVyZmFjZSBSZHNDbHVzdGVyTW9uaXRvcmluZ09wdGlvbnMgZXh0ZW5kcyBCYXNlTW9uaXRvcmluZ1Byb3BzIHtcbiAgcmVhZG9ubHkgYWRkRGlza1NwYWNlVXNhZ2VBbGFybT86IFJlY29yZDxzdHJpbmcsIFVzYWdlVGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkQ3B1VXNhZ2VBbGFybT86IFJlY29yZDxzdHJpbmcsIFVzYWdlVGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkTWluQ29ubmVjdGlvbkNvdW50QWxhcm0/OiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIExvd0Nvbm5lY3Rpb25Db3VudFRocmVzaG9sZFxuICA+O1xuICByZWFkb25seSBhZGRNYXhDb25uZWN0aW9uQ291bnRBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgSGlnaENvbm5lY3Rpb25Db3VudFRocmVzaG9sZFxuICA+O1xuICByZWFkb25seSBhZGRSZWFkSU9QU0FsYXJtPzogUmVjb3JkPHN0cmluZywgTWF4VXNhZ2VDb3VudFRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFdyaXRlSU9QU0FsYXJtPzogUmVjb3JkPHN0cmluZywgTWF4VXNhZ2VDb3VudFRocmVzaG9sZD47XG5cbiAgcmVhZG9ubHkgYWRkU2VsZWN0TGF0ZW5jeVA1MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFNlbGVjdExhdGVuY3lQNzBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRTZWxlY3RMYXRlbmN5UDkwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkU2VsZWN0TGF0ZW5jeVA5NUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFNlbGVjdExhdGVuY3lQOTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRTZWxlY3RMYXRlbmN5UDk5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFNlbGVjdExhdGVuY3lQOTk5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFNlbGVjdExhdGVuY3lQMTAwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkU2VsZWN0TGF0ZW5jeUF2ZXJhZ2VBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuXG4gIHJlYWRvbmx5IGFkZEluc2VydExhdGVuY3lQNTBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbnNlcnRMYXRlbmN5UDcwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSW5zZXJ0TGF0ZW5jeVA5MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZEluc2VydExhdGVuY3lQOTVBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbnNlcnRMYXRlbmN5UDk5QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSW5zZXJ0TGF0ZW5jeVA5OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbnNlcnRMYXRlbmN5UDk5OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbnNlcnRMYXRlbmN5UDEwMEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZEluc2VydExhdGVuY3lBdmVyYWdlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcblxuICByZWFkb25seSBhZGRVcGRhdGVMYXRlbmN5UDUwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkVXBkYXRlTGF0ZW5jeVA3MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFVwZGF0ZUxhdGVuY3lQOTBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRVcGRhdGVMYXRlbmN5UDk1QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkVXBkYXRlTGF0ZW5jeVA5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFVwZGF0ZUxhdGVuY3lQOTk5QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkVXBkYXRlTGF0ZW5jeVA5OTk5QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkVXBkYXRlTGF0ZW5jeVAxMDBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRVcGRhdGVMYXRlbmN5QXZlcmFnZUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG5cbiAgcmVhZG9ubHkgYWRkRGVsZXRlTGF0ZW5jeVA1MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZERlbGV0ZUxhdGVuY3lQNzBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGREZWxldGVMYXRlbmN5UDkwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkRGVsZXRlTGF0ZW5jeVA5NUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZERlbGV0ZUxhdGVuY3lQOTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGREZWxldGVMYXRlbmN5UDk5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZERlbGV0ZUxhdGVuY3lQOTk5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZERlbGV0ZUxhdGVuY3lQMTAwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkRGVsZXRlTGF0ZW5jeUF2ZXJhZ2VBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuXG4gIHJlYWRvbmx5IGFkZENvbW1pdExhdGVuY3lQNTBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRDb21taXRMYXRlbmN5UDcwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkQ29tbWl0TGF0ZW5jeVA5MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZENvbW1pdExhdGVuY3lQOTVBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRDb21taXRMYXRlbmN5UDk5QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkQ29tbWl0TGF0ZW5jeVA5OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRDb21taXRMYXRlbmN5UDk5OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRDb21taXRMYXRlbmN5UDEwMEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZENvbW1pdExhdGVuY3lBdmVyYWdlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcblxuICAvKipcbiAgICogWW91IGNhbiBzcGVjaWZ5IHdoYXQgbGF0ZW5jeSB0eXBlcyB5b3Ugd2FudCB0byBiZSByZW5kZXJlZCBpbiB0aGUgZGFzaGJvYXJkcy5cbiAgICogTm90ZTogYW55IGxhdGVuY3kgdHlwZSB3aXRoIGFuIGFsYXJtIHdpbGwgYmUgYWxzbyBhZGRlZCBhdXRvbWF0aWNhbGx5LlxuICAgKiBJZiB0aGUgbGlzdCBpcyB1bmRlZmluZWQsIGRlZmF1bHQgdmFsdWVzIHdpbGwgYmUgc2hvd24uXG4gICAqIElmIHRoZSBsaXN0IGlzIGVtcHR5LCBvbmx5IHRoZSBsYXRlbmN5IHR5cGVzIHdpdGggYW4gYWxhcm0gd2lsbCBiZSBzaG93biAoaWYgYW55KS5cbiAgICogQGRlZmF1bHQgLSBwOTAgZm9yIGFsbCBvcGVyYXRpb24gdHlwZXNcbiAgICovXG4gIHJlYWRvbmx5IGxhdGVuY3lUeXBlc1RvUmVuZGVyPzogTGF0ZW5jeVR5cGVbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZHNDbHVzdGVyTW9uaXRvcmluZ1Byb3BzXG4gIGV4dGVuZHMgUmRzQ2x1c3Rlck1ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgICBSZHNDbHVzdGVyTW9uaXRvcmluZ09wdGlvbnMge31cblxuZXhwb3J0IGNsYXNzIFJkc0NsdXN0ZXJNb25pdG9yaW5nIGV4dGVuZHMgTW9uaXRvcmluZyB7XG4gIHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHVybD86IHN0cmluZztcblxuICByZWFkb25seSB1c2FnZUFsYXJtRmFjdG9yeTogVXNhZ2VBbGFybUZhY3Rvcnk7XG4gIHJlYWRvbmx5IGNvbm5lY3Rpb25BbGFybUZhY3Rvcnk6IENvbm5lY3Rpb25BbGFybUZhY3Rvcnk7XG4gIHJlYWRvbmx5IGxhdGVuY3lBbGFybUZhY3Rvcnk6IExhdGVuY3lBbGFybUZhY3Rvcnk7XG4gIHJlYWRvbmx5IHVzYWdlQW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IGNvbm5lY3Rpb25Bbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgcmVhZExhdGVuY3lBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgd3JpdGVMYXRlbmN5QW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IGlvcHNBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcblxuICByZWFkb25seSBjb25uZWN0aW9uc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgZGlza1NwYWNlVXNhZ2VNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGNwdVVzYWdlTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSByZWFkSW9wc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgd3JpdGVJb3BzTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuXG4gIC8vIGtleXMgYXJlIExhdGVuY3lUeXBlLCBidXQgSlNJSSBkb2Vzbid0IGxpa2Ugbm9uLXN0cmluZyB0eXBlc1xuICByZWFkb25seSBzZWxlY3RMYXRlbmN5TWV0cmljczogUmVjb3JkPHN0cmluZywgTWV0cmljV2l0aEFsYXJtU3VwcG9ydD47XG4gIHJlYWRvbmx5IGluc2VydExhdGVuY3lNZXRyaWNzOiBSZWNvcmQ8c3RyaW5nLCBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0PjtcbiAgcmVhZG9ubHkgdXBkYXRlTGF0ZW5jeU1ldHJpY3M6IFJlY29yZDxzdHJpbmcsIE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ+O1xuICByZWFkb25seSBkZWxldGVMYXRlbmN5TWV0cmljczogUmVjb3JkPHN0cmluZywgTWV0cmljV2l0aEFsYXJtU3VwcG9ydD47XG4gIHJlYWRvbmx5IGNvbW1pdExhdGVuY3lNZXRyaWNzOiBSZWNvcmQ8c3RyaW5nLCBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0PjtcbiAgcmVhZG9ubHkgbGF0ZW5jeVR5cGVzVG9SZW5kZXI6IHN0cmluZ1tdO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBNb25pdG9yaW5nU2NvcGUsIHByb3BzOiBSZHNDbHVzdGVyTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIHByb3BzKTtcblxuICAgIGNvbnN0IG1ldHJpY0ZhY3RvcnkgPSBuZXcgUmRzQ2x1c3Rlck1ldHJpY0ZhY3RvcnkoXG4gICAgICBzY29wZS5jcmVhdGVNZXRyaWNGYWN0b3J5KCksXG4gICAgICBwcm9wcyxcbiAgICApO1xuICAgIHRoaXMuY29ubmVjdGlvbnNNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY1RvdGFsQ29ubmVjdGlvbkNvdW50KCk7XG4gICAgdGhpcy5kaXNrU3BhY2VVc2FnZU1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljRGlza1NwYWNlVXNhZ2VJblBlcmNlbnQoKTtcbiAgICB0aGlzLmNwdVVzYWdlTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNBdmVyYWdlQ3B1VXNhZ2VJblBlcmNlbnQoKTtcbiAgICB0aGlzLnJlYWRJb3BzTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNSZWFkSU9QUygpO1xuICAgIHRoaXMud3JpdGVJb3BzTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNXcml0ZUlPUFMoKTtcblxuICAgIHRoaXMuc2VsZWN0TGF0ZW5jeU1ldHJpY3MgPSB7fTtcbiAgICB0aGlzLmluc2VydExhdGVuY3lNZXRyaWNzID0ge307XG4gICAgdGhpcy51cGRhdGVMYXRlbmN5TWV0cmljcyA9IHt9O1xuICAgIHRoaXMuZGVsZXRlTGF0ZW5jeU1ldHJpY3MgPSB7fTtcbiAgICB0aGlzLmNvbW1pdExhdGVuY3lNZXRyaWNzID0ge307XG4gICAgdGhpcy5sYXRlbmN5VHlwZXNUb1JlbmRlciA9IFtcbiAgICAgIC4uLihwcm9wcy5sYXRlbmN5VHlwZXNUb1JlbmRlciA/PyBEZWZhdWx0TGF0ZW5jeVR5cGVzVG9SZW5kZXIpLFxuICAgIF07XG5cbiAgICBPYmplY3QudmFsdWVzKExhdGVuY3lUeXBlKS5mb3JFYWNoKChsYXRlbmN5VHlwZSkgPT4ge1xuICAgICAgdGhpcy5zZWxlY3RMYXRlbmN5TWV0cmljc1tsYXRlbmN5VHlwZV0gPVxuICAgICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY1NlbGVjdExhdGVuY3lJbk1pbGxpcyhsYXRlbmN5VHlwZSk7XG4gICAgICB0aGlzLmluc2VydExhdGVuY3lNZXRyaWNzW2xhdGVuY3lUeXBlXSA9XG4gICAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljSW5zZXJ0TGF0ZW5jeUluTWlsbGlzKGxhdGVuY3lUeXBlKTtcbiAgICAgIHRoaXMudXBkYXRlTGF0ZW5jeU1ldHJpY3NbbGF0ZW5jeVR5cGVdID1cbiAgICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNVcGRhdGVMYXRlbmN5SW5NaWxsaXMobGF0ZW5jeVR5cGUpO1xuICAgICAgdGhpcy5kZWxldGVMYXRlbmN5TWV0cmljc1tsYXRlbmN5VHlwZV0gPVxuICAgICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0RlbGV0ZUxhdGVuY3lJbk1pbGxpcyhsYXRlbmN5VHlwZSk7XG4gICAgICB0aGlzLmNvbW1pdExhdGVuY3lNZXRyaWNzW2xhdGVuY3lUeXBlXSA9XG4gICAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljQ29tbWl0TGF0ZW5jeUluTWlsbGlzKGxhdGVuY3lUeXBlKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IG5hbWluZ1N0cmF0ZWd5ID0gbmV3IE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSh7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIGZhbGxiYWNrQ29uc3RydWN0TmFtZTogbWV0cmljRmFjdG9yeS5jbHVzdGVySWRlbnRpZmllcixcbiAgICAgIG5hbWVkQ29uc3RydWN0OiBwcm9wcy5jbHVzdGVyLFxuICAgIH0pO1xuICAgIHRoaXMudGl0bGUgPSBuYW1pbmdTdHJhdGVneS5yZXNvbHZlSHVtYW5SZWFkYWJsZU5hbWUoKTtcbiAgICB0aGlzLnVybCA9IHNjb3BlXG4gICAgICAuY3JlYXRlQXdzQ29uc29sZVVybEZhY3RvcnkoKVxuICAgICAgLmdldFJkc0NsdXN0ZXJVcmwobWV0cmljRmFjdG9yeS5jbHVzdGVySWRlbnRpZmllcik7XG4gICAgY29uc3QgYWxhcm1GYWN0b3J5ID0gdGhpcy5jcmVhdGVBbGFybUZhY3RvcnkoXG4gICAgICBuYW1pbmdTdHJhdGVneS5yZXNvbHZlQWxhcm1GcmllbmRseU5hbWUoKSxcbiAgICApO1xuICAgIHRoaXMudXNhZ2VBbGFybUZhY3RvcnkgPSBuZXcgVXNhZ2VBbGFybUZhY3RvcnkoYWxhcm1GYWN0b3J5KTtcbiAgICB0aGlzLmNvbm5lY3Rpb25BbGFybUZhY3RvcnkgPSBuZXcgQ29ubmVjdGlvbkFsYXJtRmFjdG9yeShhbGFybUZhY3RvcnkpO1xuICAgIHRoaXMubGF0ZW5jeUFsYXJtRmFjdG9yeSA9IG5ldyBMYXRlbmN5QWxhcm1GYWN0b3J5KGFsYXJtRmFjdG9yeSk7XG5cbiAgICB0aGlzLnVzYWdlQW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmNvbm5lY3Rpb25Bbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMucmVhZExhdGVuY3lBbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMud3JpdGVMYXRlbmN5QW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmlvcHNBbm5vdGF0aW9ucyA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZERpc2tTcGFjZVVzYWdlQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGREaXNrU3BhY2VVc2FnZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy51c2FnZUFsYXJtRmFjdG9yeS5hZGRNYXhEaXNrVXNhZ2VQZXJjZW50QWxhcm0oXG4gICAgICAgIHRoaXMuZGlza1NwYWNlVXNhZ2VNZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy51c2FnZUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRDcHVVc2FnZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkQ3B1VXNhZ2VBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMudXNhZ2VBbGFybUZhY3RvcnkuYWRkTWF4Q3B1VXNhZ2VQZXJjZW50QWxhcm0oXG4gICAgICAgIHRoaXMuY3B1VXNhZ2VNZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy51c2FnZUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRNaW5Db25uZWN0aW9uQ291bnRBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZE1pbkNvbm5lY3Rpb25Db3VudEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID1cbiAgICAgICAgdGhpcy5jb25uZWN0aW9uQWxhcm1GYWN0b3J5LmFkZE1pbkNvbm5lY3Rpb25Db3VudEFsYXJtKFxuICAgICAgICAgIHRoaXMuY29ubmVjdGlvbnNNZXRyaWMsXG4gICAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgICApO1xuICAgICAgdGhpcy5jb25uZWN0aW9uQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZE1heENvbm5lY3Rpb25Db3VudEFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkTWF4Q29ubmVjdGlvbkNvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPVxuICAgICAgICB0aGlzLmNvbm5lY3Rpb25BbGFybUZhY3RvcnkuYWRkTWF4Q29ubmVjdGlvbkNvdW50QWxhcm0oXG4gICAgICAgICAgdGhpcy5jb25uZWN0aW9uc01ldHJpYyxcbiAgICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICAgICk7XG4gICAgICB0aGlzLmNvbm5lY3Rpb25Bbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWxlY3RMYXRlbmN5QWxhcm1EZWZpbml0aW9ucyA9IHtcbiAgICAgIFtMYXRlbmN5VHlwZS5QNTBdOiBwcm9wcy5hZGRTZWxlY3RMYXRlbmN5UDUwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDcwXTogcHJvcHMuYWRkU2VsZWN0TGF0ZW5jeVA3MEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5MF06IHByb3BzLmFkZFNlbGVjdExhdGVuY3lQOTBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTVdOiBwcm9wcy5hZGRTZWxlY3RMYXRlbmN5UDk1QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5XTogcHJvcHMuYWRkU2VsZWN0TGF0ZW5jeVA5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5OTldOiBwcm9wcy5hZGRTZWxlY3RMYXRlbmN5UDk5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5OTk5XTogcHJvcHMuYWRkU2VsZWN0TGF0ZW5jeVA5OTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDEwMF06IHByb3BzLmFkZFNlbGVjdExhdGVuY3lQMTAwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuQVZFUkFHRV06IHByb3BzLmFkZFNlbGVjdExhdGVuY3lBdmVyYWdlQWxhcm0sXG4gICAgfTtcblxuICAgIGNvbnN0IGluc2VydExhdGVuY3lBbGFybURlZmluaXRpb25zID0ge1xuICAgICAgW0xhdGVuY3lUeXBlLlA1MF06IHByb3BzLmFkZEluc2VydExhdGVuY3lQNTBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QNzBdOiBwcm9wcy5hZGRJbnNlcnRMYXRlbmN5UDcwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDkwXTogcHJvcHMuYWRkSW5zZXJ0TGF0ZW5jeVA5MEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5NV06IHByb3BzLmFkZEluc2VydExhdGVuY3lQOTVBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTldOiBwcm9wcy5hZGRJbnNlcnRMYXRlbmN5UDk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5OV06IHByb3BzLmFkZEluc2VydExhdGVuY3lQOTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5OTldOiBwcm9wcy5hZGRJbnNlcnRMYXRlbmN5UDk5OTlBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QMTAwXTogcHJvcHMuYWRkSW5zZXJ0TGF0ZW5jeVAxMDBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5BVkVSQUdFXTogcHJvcHMuYWRkSW5zZXJ0TGF0ZW5jeUF2ZXJhZ2VBbGFybSxcbiAgICB9O1xuXG4gICAgY29uc3QgdXBkYXRlTGF0ZW5jeUFsYXJtRGVmaW5pdGlvbnMgPSB7XG4gICAgICBbTGF0ZW5jeVR5cGUuUDUwXTogcHJvcHMuYWRkVXBkYXRlTGF0ZW5jeVA1MEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA3MF06IHByb3BzLmFkZFVwZGF0ZUxhdGVuY3lQNzBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTBdOiBwcm9wcy5hZGRVcGRhdGVMYXRlbmN5UDkwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk1XTogcHJvcHMuYWRkVXBkYXRlTGF0ZW5jeVA5NUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5OV06IHByb3BzLmFkZFVwZGF0ZUxhdGVuY3lQOTlBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTk5XTogcHJvcHMuYWRkVXBkYXRlTGF0ZW5jeVA5OTlBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTk5OV06IHByb3BzLmFkZFVwZGF0ZUxhdGVuY3lQOTk5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlAxMDBdOiBwcm9wcy5hZGRVcGRhdGVMYXRlbmN5UDEwMEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLkFWRVJBR0VdOiBwcm9wcy5hZGRVcGRhdGVMYXRlbmN5QXZlcmFnZUFsYXJtLFxuICAgIH07XG5cbiAgICBjb25zdCBkZWxldGVMYXRlbmN5QWxhcm1EZWZpbml0aW9ucyA9IHtcbiAgICAgIFtMYXRlbmN5VHlwZS5QNTBdOiBwcm9wcy5hZGREZWxldGVMYXRlbmN5UDUwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDcwXTogcHJvcHMuYWRkRGVsZXRlTGF0ZW5jeVA3MEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5MF06IHByb3BzLmFkZERlbGV0ZUxhdGVuY3lQOTBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTVdOiBwcm9wcy5hZGREZWxldGVMYXRlbmN5UDk1QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5XTogcHJvcHMuYWRkRGVsZXRlTGF0ZW5jeVA5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5OTldOiBwcm9wcy5hZGREZWxldGVMYXRlbmN5UDk5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5OTk5XTogcHJvcHMuYWRkRGVsZXRlTGF0ZW5jeVA5OTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDEwMF06IHByb3BzLmFkZERlbGV0ZUxhdGVuY3lQMTAwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuQVZFUkFHRV06IHByb3BzLmFkZERlbGV0ZUxhdGVuY3lBdmVyYWdlQWxhcm0sXG4gICAgfTtcblxuICAgIGNvbnN0IGNvbW1pdExhdGVuY3lBbGFybURlZmluaXRpb25zID0ge1xuICAgICAgW0xhdGVuY3lUeXBlLlA1MF06IHByb3BzLmFkZENvbW1pdExhdGVuY3lQNTBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QNzBdOiBwcm9wcy5hZGRDb21taXRMYXRlbmN5UDcwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDkwXTogcHJvcHMuYWRkQ29tbWl0TGF0ZW5jeVA5MEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5NV06IHByb3BzLmFkZENvbW1pdExhdGVuY3lQOTVBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTldOiBwcm9wcy5hZGRDb21taXRMYXRlbmN5UDk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5OV06IHByb3BzLmFkZENvbW1pdExhdGVuY3lQOTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5OTldOiBwcm9wcy5hZGRDb21taXRMYXRlbmN5UDk5OTlBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QMTAwXTogcHJvcHMuYWRkQ29tbWl0TGF0ZW5jeVAxMDBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5BVkVSQUdFXTogcHJvcHMuYWRkQ29tbWl0TGF0ZW5jeUF2ZXJhZ2VBbGFybSxcbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBbbGF0ZW5jeVR5cGUsIGFsYXJtRGVmaW5pdGlvbl0gb2YgT2JqZWN0LmVudHJpZXMoXG4gICAgICBzZWxlY3RMYXRlbmN