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

236 lines 37.6 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.KinesisDataAnalyticsMonitoring = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch"); const KinesisDataAnalyticsMetricFactory_1 = require("./KinesisDataAnalyticsMetricFactory"); const common_1 = require("../../common"); const dashboard_1 = require("../../dashboard"); class KinesisDataAnalyticsMonitoring extends common_1.Monitoring { constructor(scope, props) { super(scope, props); const namingStrategy = new dashboard_1.MonitoringNamingStrategy({ ...props, fallbackConstructName: props.application, }); this.title = namingStrategy.resolveHumanReadableName(); this.kinesisDataAnalyticsUrl = scope .createAwsConsoleUrlFactory() .getKinesisAnalyticsUrl(props.application); const alarmFactory = this.createAlarmFactory(namingStrategy.resolveAlarmFriendlyName()); this.kdaAlarmFactory = new common_1.KinesisDataAnalyticsAlarmFactory(alarmFactory); this.downtimeAnnotations = []; this.fullRestartAnnotations = []; this.fullRestartRateAnnotations = []; this.backPressuredTimeMsPerSecondAnnotations = []; this.checkpointFailureCountAnnotations = []; this.checkpointFailureRateAnnotations = []; const metricFactory = new KinesisDataAnalyticsMetricFactory_1.KinesisDataAnalyticsMetricFactory(scope.createMetricFactory(), props); this.cpuUtilizationPercentMetric = metricFactory.metricCpuUtilizationPercent(); this.downtimeMsMetric = metricFactory.metricDowntimeMs(); this.fullRestartsCountMetric = metricFactory.metricFullRestartsCount(); this.heapMemoryUtilizationPercentMetric = metricFactory.metricHeapMemoryUtilizationPercent(); this.kpusCountMetric = metricFactory.metricKPUsCount(); this.lastCheckpointDurationMsMetric = metricFactory.metricLastCheckpointDurationMs(); this.lastCheckpointSizeBytesMetric = metricFactory.metricLastCheckpointSizeBytes(); this.numberOfFailedCheckpointsCountMetric = metricFactory.metricNumberOfFailedCheckpointsCount(); this.oldGenerationGCCountMetric = metricFactory.metricOldGenerationGCCount(); this.oldGenerationGCTimeMsMetric = metricFactory.metricOldGenerationGCTimeMs(); this.checkpointFailureRateMetric = metricFactory.metricCheckpointFailureRate(); this.fullRestartRateMetric = metricFactory.metricFullRestartRate(); this.backPressuredTimeMsPerSecondMetric = metricFactory.metricBackPressuredTimeMsPerSecond(); for (const disambiguator in props.addDowntimeAlarm) { const alarmProps = props.addDowntimeAlarm[disambiguator]; const createdAlarm = this.kdaAlarmFactory.addDowntimeAlarm(this.downtimeMsMetric, alarmProps, disambiguator); this.downtimeAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addFullRestartCountAlarm) { const alarmProps = props.addFullRestartCountAlarm[disambiguator]; const createdAlarm = this.kdaAlarmFactory.addFullRestartAlarm(this.fullRestartsCountMetric, alarmProps, disambiguator); this.fullRestartAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addFullRestartRateAlarm) { const alarmProps = props.addFullRestartRateAlarm[disambiguator]; const createdAlarm = this.kdaAlarmFactory.addFullRestartRateAlarm(this.fullRestartRateMetric, alarmProps, disambiguator); this.fullRestartRateAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addBackPressuredTimeMsPerSecondAlarm) { const alarmProps = props.addBackPressuredTimeMsPerSecondAlarm[disambiguator]; const createdAlarm = this.kdaAlarmFactory.addBackPressuredTimeMsPerSecondAlarm(this.backPressuredTimeMsPerSecondMetric, alarmProps, disambiguator); this.backPressuredTimeMsPerSecondAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addCheckpointFailureCountAlarm) { const alarmProps = props.addCheckpointFailureCountAlarm[disambiguator]; const createdAlarm = this.kdaAlarmFactory.addCheckpointFailureCountAlarm(this.numberOfFailedCheckpointsCountMetric, alarmProps, disambiguator); this.checkpointFailureCountAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } for (const disambiguator in props.addCheckpointFailureRateAlarm) { const alarmProps = props.addCheckpointFailureRateAlarm[disambiguator]; const createdAlarm = this.kdaAlarmFactory.addCheckpointFailureRateAlarm(this.checkpointFailureRateMetric, alarmProps, disambiguator); this.checkpointFailureRateAnnotations.push(createdAlarm.annotation); this.addAlarm(createdAlarm); } props.useCreatedAlarms?.consume(this.createdAlarms()); } summaryWidgets() { return [ this.createTitleWidget(), ...this.createSummaryWidgetRow(common_1.DefaultSummaryWidgetHeight), ]; } widgets() { return [ this.createTitleWidget(), ...this.createSummaryWidgetRow(common_1.DefaultGraphWidgetHeight), ...this.createCheckpointAndGcWidgets(), ]; } createTitleWidget() { return new dashboard_1.MonitoringHeaderWidget({ family: "Kinesis Data Analytics", title: this.title, goToLinkUrl: this.kinesisDataAnalyticsUrl, }); } createKPUWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "KPU Usage", left: [this.kpusCountMetric], leftYAxis: common_1.CountAxisFromZero, }); } createResourceUtilizationWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Resource Utilization", left: [ this.cpuUtilizationPercentMetric, this.heapMemoryUtilizationPercentMetric, ], leftYAxis: common_1.PercentageAxisFromZeroToHundred, }); } createDownTimeWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Down Time", left: [this.downtimeMsMetric], leftYAxis: common_1.TimeAxisMillisFromZero, leftAnnotations: this.downtimeAnnotations, }); } createFullRestartsWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Full Restarts", left: [this.fullRestartsCountMetric], leftYAxis: common_1.CountAxisFromZero, leftAnnotations: this.fullRestartAnnotations, right: [this.fullRestartRateMetric], rightYAxis: common_1.RateAxisFromZero, rightAnnotations: this.fullRestartRateAnnotations, }); } createBackPressuredTimeWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Back Pressured Time", left: [this.backPressuredTimeMsPerSecondMetric], leftYAxis: common_1.TimeAxisMillisFromZero, leftAnnotations: this.backPressuredTimeMsPerSecondAnnotations, }); } createNumberOfFailedCheckpointsWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Checkpoint Failures", left: [this.numberOfFailedCheckpointsCountMetric], leftYAxis: common_1.CountAxisFromZero, leftAnnotations: this.checkpointFailureCountAnnotations, right: [this.checkpointFailureRateMetric], rightYAxis: common_1.RateAxisFromZero, rightAnnotations: this.checkpointFailureRateAnnotations, }); } createLastCheckpointDurationWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Checkpoint Duration", left: [this.lastCheckpointDurationMsMetric], leftYAxis: common_1.TimeAxisMillisFromZero, }); } createLastCheckpointSizeWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Checkpoint Size", left: [this.lastCheckpointSizeBytesMetric], leftYAxis: common_1.SizeAxisBytesFromZero, }); } createGarbageCollectionWidget(width, height) { return new aws_cloudwatch_1.GraphWidget({ width, height, title: "Garbage Collection", left: [this.oldGenerationGCCountMetric], leftYAxis: common_1.CountAxisFromZero, right: [this.oldGenerationGCTimeMsMetric], rightYAxis: common_1.TimeAxisMillisFromZero, }); } createSummaryWidgetRow(height) { return [ // KPUs this.createKPUWidget(common_1.QuarterWidth, height), // CPU And Heap Usage this.createResourceUtilizationWidget(common_1.QuarterWidth, height), // Down Time and Up Time this.createDownTimeWidget(common_1.QuarterWidth, height), // Full Restarts this.createFullRestartsWidget(common_1.QuarterWidth, height), ]; } createCheckpointAndGcWidgets() { return [ // Back Pressure this.createBackPressuredTimeWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), // Checkpointing this.createNumberOfFailedCheckpointsWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), // Checkpoint Duration this.createLastCheckpointDurationWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), // Checkpoint Size this.createLastCheckpointSizeWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), // Garbage Collection this.createGarbageCollectionWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), ]; } } exports.KinesisDataAnalyticsMonitoring = KinesisDataAnalyticsMonitoring; _a = JSII_RTTI_SYMBOL_1; KinesisDataAnalyticsMonitoring[_a] = { fqn: "cdk-monitoring-constructs.KinesisDataAnalyticsMonitoring", version: "10.0.0" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0RBSW9DO0FBRXBDLDJGQUc2QztBQUM3Qyx5Q0FtQnNCO0FBQ3RCLCtDQUd5QjtBQXdCekIsTUFBYSw4QkFBK0IsU0FBUSxtQkFBVTtJQTBCNUQsWUFDRSxLQUFzQixFQUN0QixLQUEwQztRQUUxQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXBCLE1BQU0sY0FBYyxHQUFHLElBQUksb0NBQXdCLENBQUM7WUFDbEQsR0FBRyxLQUFLO1lBQ1IscUJBQXFCLEVBQUUsS0FBSyxDQUFDLFdBQVc7U0FDekMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLEtBQUssR0FBRyxjQUFjLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztRQUN2RCxJQUFJLENBQUMsdUJBQXVCLEdBQUcsS0FBSzthQUNqQywwQkFBMEIsRUFBRTthQUM1QixzQkFBc0IsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFN0MsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUMxQyxjQUFjLENBQUMsd0JBQXdCLEVBQUUsQ0FDMUMsQ0FBQztRQUNGLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSx5Q0FBZ0MsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMxRSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxFQUFFLENBQUM7UUFDakMsSUFBSSxDQUFDLDBCQUEwQixHQUFHLEVBQUUsQ0FBQztRQUNyQyxJQUFJLENBQUMsdUNBQXVDLEdBQUcsRUFBRSxDQUFDO1FBQ2xELElBQUksQ0FBQyxpQ0FBaUMsR0FBRyxFQUFFLENBQUM7UUFDNUMsSUFBSSxDQUFDLGdDQUFnQyxHQUFHLEVBQUUsQ0FBQztRQUUzQyxNQUFNLGFBQWEsR0FBRyxJQUFJLHFFQUFpQyxDQUN6RCxLQUFLLENBQUMsbUJBQW1CLEVBQUUsRUFDM0IsS0FBSyxDQUNOLENBQUM7UUFFRixJQUFJLENBQUMsMkJBQTJCO1lBQzlCLGFBQWEsQ0FBQywyQkFBMkIsRUFBRSxDQUFDO1FBQzlDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxhQUFhLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN6RCxJQUFJLENBQUMsdUJBQXVCLEdBQUcsYUFBYSxDQUFDLHVCQUF1QixFQUFFLENBQUM7UUFDdkUsSUFBSSxDQUFDLGtDQUFrQztZQUNyQyxhQUFhLENBQUMsa0NBQWtDLEVBQUUsQ0FBQztRQUNyRCxJQUFJLENBQUMsZUFBZSxHQUFHLGFBQWEsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2RCxJQUFJLENBQUMsOEJBQThCO1lBQ2pDLGFBQWEsQ0FBQyw4QkFBOEIsRUFBRSxDQUFDO1FBQ2pELElBQUksQ0FBQyw2QkFBNkI7WUFDaEMsYUFBYSxDQUFDLDZCQUE2QixFQUFFLENBQUM7UUFDaEQsSUFBSSxDQUFDLG9DQUFvQztZQUN2QyxhQUFhLENBQUMsb0NBQW9DLEVBQUUsQ0FBQztRQUN2RCxJQUFJLENBQUMsMEJBQTBCO1lBQzdCLGFBQWEsQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQzdDLElBQUksQ0FBQywyQkFBMkI7WUFDOUIsYUFBYSxDQUFDLDJCQUEyQixFQUFFLENBQUM7UUFDOUMsSUFBSSxDQUFDLDJCQUEyQjtZQUM5QixhQUFhLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztRQUM5QyxJQUFJLENBQUMscUJBQXFCLEdBQUcsYUFBYSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDbkUsSUFBSSxDQUFDLGtDQUFrQztZQUNyQyxhQUFhLENBQUMsa0NBQWtDLEVBQUUsQ0FBQztRQUVyRCxLQUFLLE1BQU0sYUFBYSxJQUFJLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ25ELE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN6RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGdCQUFnQixDQUN4RCxJQUFJLENBQUMsZ0JBQWdCLEVBQ3JCLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztZQUNGLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3ZELElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDOUIsQ0FBQztRQUVELEtBQUssTUFBTSxhQUFhLElBQUksS0FBSyxDQUFDLHdCQUF3QixFQUFFLENBQUM7WUFDM0QsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLHdCQUF3QixDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ2pFLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsbUJBQW1CLENBQzNELElBQUksQ0FBQyx1QkFBdUIsRUFDNUIsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1lBQ0YsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDMUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM5QixDQUFDO1FBRUQsS0FBSyxNQUFNLGFBQWEsSUFBSSxLQUFLLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztZQUMxRCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsdUJBQXVCLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDaEUsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyx1QkFBdUIsQ0FDL0QsSUFBSSxDQUFDLHFCQUFxQixFQUMxQixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7WUFDRixJQUFJLENBQUMsMEJBQTBCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUM5RCxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzlCLENBQUM7UUFFRCxLQUFLLE1BQU0sYUFBYSxJQUFJLEtBQUssQ0FBQyxvQ0FBb0MsRUFBRSxDQUFDO1lBQ3ZFLE1BQU0sVUFBVSxHQUNkLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUM1RCxNQUFNLFlBQVksR0FDaEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxvQ0FBb0MsQ0FDdkQsSUFBSSxDQUFDLGtDQUFrQyxFQUN2QyxVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7WUFDSixJQUFJLENBQUMsdUNBQXVDLENBQUMsSUFBSSxDQUMvQyxZQUFZLENBQUMsVUFBVSxDQUN4QixDQUFDO1lBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM5QixDQUFDO1FBRUQsS0FBSyxNQUFNLGFBQWEsSUFBSSxLQUFLLENBQUMsOEJBQThCLEVBQUUsQ0FBQztZQUNqRSxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsOEJBQThCLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDdkUsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyw4QkFBOEIsQ0FDdEUsSUFBSSxDQUFDLG9DQUFvQyxFQUN6QyxVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7WUFDRixJQUFJLENBQUMsaUNBQWlDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNyRSxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzlCLENBQUM7UUFFRCxLQUFLLE1BQU0sYUFBYSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsRUFBRSxDQUFDO1lBQ2hFLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyw2QkFBNkIsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN0RSxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLDZCQUE2QixDQUNyRSxJQUFJLENBQUMsMkJBQTJCLEVBQ2hDLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztZQUNGLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3BFLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDOUIsQ0FBQztRQUVELEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVELGNBQWM7UUFDWixPQUFPO1lBQ0wsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQ3hCLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLG1DQUEwQixDQUFDO1NBQzNELENBQUM7SUFDSixDQUFDO0lBRUQsT0FBTztRQUNMLE9BQU87WUFDTCxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDeEIsR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsaUNBQXdCLENBQUM7WUFDeEQsR0FBRyxJQUFJLENBQUMsNEJBQTRCLEVBQUU7U0FDdkMsQ0FBQztJQUNKLENBQUM7SUFFRCxpQkFBaUI7UUFDZixPQUFPLElBQUksa0NBQXNCLENBQUM7WUFDaEMsTUFBTSxFQUFFLHdCQUF3QjtZQUNoQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7WUFDakIsV0FBVyxFQUFFLElBQUksQ0FBQyx1QkFBdUI7U0FDMUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGVBQWUsQ0FBQyxLQUFhLEVBQUUsTUFBYztRQUMzQyxPQUFPLElBQUksNEJBQVcsQ0FBQztZQUNyQixLQUFLO1lBQ0wsTUFBTTtZQUNOLEtBQUssRUFBRSxXQUFXO1lBQ2xCLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUM7WUFDNUIsU0FBUyxFQUFFLDBCQUFpQjtTQUM3QixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsK0JBQStCLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDM0QsT0FBTyxJQUFJLDRCQUFXLENBQUM7WUFDckIsS0FBSztZQUNMLE1BQU07WUFDTixLQUFLLEVBQUUsc0JBQXNCO1lBQzdCLElBQUksRUFBRTtnQkFDSixJQUFJLENBQUMsMkJBQTJCO2dCQUNoQyxJQUFJLENBQUMsa0NBQWtDO2FBQ3hDO1lBQ0QsU0FBUyxFQUFFLHdDQUErQjtTQUMzQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsb0JBQW9CLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDaEQsT0FBTyxJQUFJLDRCQUFXLENBQUM7WUFDckIsS0FBSztZQUNMLE1BQU07WUFDTixLQUFLLEVBQUUsV0FBVztZQUNsQixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7WUFDN0IsU0FBUyxFQUFFLCtCQUFzQjtZQUNqQyxlQUFlLEVBQUUsSUFBSSxDQUFDLG1CQUFtQjtTQUMxQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsd0JBQXdCLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDcEQsT0FBTyxJQUFJLDRCQUFXLENBQUM7WUFDckIsS0FBSztZQUNMLE1BQU07WUFDTixLQUFLLEVBQUUsZUFBZTtZQUN0QixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUM7WUFDcEMsU0FBUyxFQUFFLDBCQUFpQjtZQUM1QixlQUFlLEVBQUUsSUFBSSxDQUFDLHNCQUFzQjtZQUM1QyxLQUFLLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUM7WUFDbkMsVUFBVSxFQUFFLHlCQUFnQjtZQUM1QixnQkFBZ0IsRUFBRSxJQUFJLENBQUMsMEJBQTBCO1NBQ2xELENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCw2QkFBNkIsQ0FBQyxLQUFhLEVBQUUsTUFBYztRQUN6RCxPQUFPLElBQUksNEJBQVcsQ0FBQztZQUNyQixLQUFLO1lBQ0wsTUFBTTtZQUNOLEtBQUssRUFBRSxxQkFBcUI7WUFDNUIsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxDQUFDO1lBQy9DLFNBQVMsRUFBRSwrQkFBc0I7WUFDakMsZUFBZSxFQUFFLElBQUksQ0FBQyx1Q0FBdUM7U0FDOUQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHFDQUFxQyxDQUFDLEtBQWEsRUFBRSxNQUFjO1FBQ2pFLE9BQU8sSUFBSSw0QkFBVyxDQUFDO1lBQ3JCLEtBQUs7WUFDTCxNQUFNO1lBQ04sS0FBSyxFQUFFLHFCQUFxQjtZQUM1QixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsb0NBQW9DLENBQUM7WUFDakQsU0FBUyxFQUFFLDBCQUFpQjtZQUM1QixlQUFlLEVBQUUsSUFBSSxDQUFDLGlDQUFpQztZQUN2RCxLQUFLLEVBQUUsQ0FBQyxJQUFJLENBQUMsMkJBQTJCLENBQUM7WUFDekMsVUFBVSxFQUFFLHlCQUFnQjtZQUM1QixnQkFBZ0IsRUFBRSxJQUFJLENBQUMsZ0NBQWdDO1NBQ3hELENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxrQ0FBa0MsQ0FBQyxLQUFhLEVBQUUsTUFBYztRQUM5RCxPQUFPLElBQUksNEJBQVcsQ0FBQztZQUNyQixLQUFLO1lBQ0wsTUFBTTtZQUNOLEtBQUssRUFBRSxxQkFBcUI7WUFDNUIsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLDhCQUE4QixDQUFDO1lBQzNDLFNBQVMsRUFBRSwrQkFBc0I7U0FDbEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELDhCQUE4QixDQUFDLEtBQWEsRUFBRSxNQUFjO1FBQzFELE9BQU8sSUFBSSw0QkFBVyxDQUFDO1lBQ3JCLEtBQUs7WUFDTCxNQUFNO1lBQ04sS0FBSyxFQUFFLGlCQUFpQjtZQUN4QixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsNkJBQTZCLENBQUM7WUFDMUMsU0FBUyxFQUFFLDhCQUFxQjtTQUNqQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsNkJBQTZCLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDekQsT0FBTyxJQUFJLDRCQUFXLENBQUM7WUFDckIsS0FBSztZQUNMLE1BQU07WUFDTixLQUFLLEVBQUUsb0JBQW9CO1lBQzNCLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQztZQUN2QyxTQUFTLEVBQUUsMEJBQWlCO1lBQzVCLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQywyQkFBMkIsQ0FBQztZQUN6QyxVQUFVLEVBQUUsK0JBQXNCO1NBQ25DLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxzQkFBc0IsQ0FBQyxNQUFjO1FBQzNDLE9BQU87WUFDTCxPQUFPO1lBQ1AsSUFBSSxDQUFDLGVBQWUsQ0FBQyxxQkFBWSxFQUFFLE1BQU0sQ0FBQztZQUMxQyxxQkFBcUI7WUFDckIsSUFBSSxDQUFDLCtCQUErQixDQUFDLHFCQUFZLEVBQUUsTUFBTSxDQUFDO1lBQzFELHdCQUF3QjtZQUN4QixJQUFJLENBQUMsb0JBQW9CLENBQUMscUJBQVksRUFBRSxNQUFNLENBQUM7WUFDL0MsZ0JBQWdCO1lBQ2hCLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxxQkFBWSxFQUFFLE1BQU0sQ0FBQztTQUNwRCxDQUFDO0lBQ0osQ0FBQztJQUVPLDRCQUE0QjtRQUNsQyxPQUFPO1lBQ0wsZ0JBQWdCO1lBQ2hCLElBQUksQ0FBQyw2QkFBNkIsQ0FDaEMscUJBQVksRUFDWixpQ0FBd0IsQ0FDekI7WUFDRCxnQkFBZ0I7WUFDaEIsSUFBSSxDQUFDLHFDQUFxQyxDQUN4QyxxQkFBWSxFQUNaLGlDQUF3QixDQUN6QjtZQUNELHNCQUFzQjtZQUN0QixJQUFJLENBQUMsa0NBQWtDLENBQ3JDLHFCQUFZLEVBQ1osaUNBQXdCLENBQ3pCO1lBQ0Qsa0JBQWtCO1lBQ2xCLElBQUksQ0FBQyw4QkFBOEIsQ0FDakMscUJBQVksRUFDWixpQ0FBd0IsQ0FDekI7WUFDRCxxQkFBcUI7WUFDckIsSUFBSSxDQUFDLDZCQUE2QixDQUNoQyxxQkFBWSxFQUNaLGlDQUF3QixDQUN6QjtTQUNGLENBQUM7SUFDSixDQUFDOztBQWxVSCx3RUFtVUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFdpZGdldCxcbiAgSG9yaXpvbnRhbEFubm90YXRpb24sXG4gIElXaWRnZXQsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaFwiO1xuXG5pbXBvcnQge1xuICBLaW5lc2lzRGF0YUFuYWx5dGljc01ldHJpY0ZhY3RvcnksXG4gIEtpbmVzaXNEYXRhQW5hbHl0aWNzTWV0cmljRmFjdG9yeVByb3BzLFxufSBmcm9tIFwiLi9LaW5lc2lzRGF0YUFuYWx5dGljc01ldHJpY0ZhY3RvcnlcIjtcbmltcG9ydCB7XG4gIEJhc2VNb25pdG9yaW5nUHJvcHMsXG4gIENvdW50QXhpc0Zyb21aZXJvLFxuICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0LFxuICBFcnJvckNvdW50VGhyZXNob2xkLFxuICBFcnJvclJhdGVUaHJlc2hvbGQsXG4gIEZ1bGxSZXN0YXJ0Q291bnRUaHJlc2hvbGQsXG4gIEtpbmVzaXNEYXRhQW5hbHl0aWNzQWxhcm1GYWN0b3J5LFxuICBNYXhCYWNrUHJlc3N1cmVkVGltZU1zUGVyU2Vjb25kVGhyZXNob2xkLFxuICBNYXhEb3dudGltZVRocmVzaG9sZCxcbiAgTWV0cmljV2l0aEFsYXJtU3VwcG9ydCxcbiAgTW9uaXRvcmluZyxcbiAgTW9uaXRvcmluZ1Njb3BlLFxuICBQZXJjZW50YWdlQXhpc0Zyb21aZXJvVG9IdW5kcmVkLFxuICBRdWFydGVyV2lkdGgsXG4gIFJhdGVBeGlzRnJvbVplcm8sXG4gIFNpemVBeGlzQnl0ZXNGcm9tWmVybyxcbiAgVGltZUF4aXNNaWxsaXNGcm9tWmVybyxcbn0gZnJvbSBcIi4uLy4uL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgTW9uaXRvcmluZ0hlYWRlcldpZGdldCxcbiAgTW9uaXRvcmluZ05hbWluZ1N0cmF0ZWd5LFxufSBmcm9tIFwiLi4vLi4vZGFzaGJvYXJkXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nT3B0aW9uc1xuICBleHRlbmRzIEJhc2VNb25pdG9yaW5nUHJvcHMge1xuICByZWFkb25seSBhZGREb3dudGltZUFsYXJtPzogUmVjb3JkPHN0cmluZywgTWF4RG93bnRpbWVUaHJlc2hvbGQ+O1xuXG4gIHJlYWRvbmx5IGFkZEZ1bGxSZXN0YXJ0Q291bnRBbGFybT86IFJlY29yZDxzdHJpbmcsIEZ1bGxSZXN0YXJ0Q291bnRUaHJlc2hvbGQ+O1xuXG4gIHJlYWRvbmx5IGFkZEZ1bGxSZXN0YXJ0UmF0ZUFsYXJtPzogUmVjb3JkPHN0cmluZywgRXJyb3JSYXRlVGhyZXNob2xkPjtcblxuICByZWFkb25seSBhZGRCYWNrUHJlc3N1cmVkVGltZU1zUGVyU2Vjb25kQWxhcm0/OiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIE1heEJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRUaHJlc2hvbGRcbiAgPjtcblxuICByZWFkb25seSBhZGRDaGVja3BvaW50RmFpbHVyZUNvdW50QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvckNvdW50VGhyZXNob2xkPjtcblxuICByZWFkb25seSBhZGRDaGVja3BvaW50RmFpbHVyZVJhdGVBbGFybT86IFJlY29yZDxzdHJpbmcsIEVycm9yUmF0ZVRocmVzaG9sZD47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nUHJvcHNcbiAgZXh0ZW5kcyBLaW5lc2lzRGF0YUFuYWx5dGljc01ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgICBLaW5lc2lzRGF0YUFuYWx5dGljc01vbml0b3JpbmdPcHRpb25zIHt9XG5cbmV4cG9ydCBjbGFzcyBLaW5lc2lzRGF0YUFuYWx5dGljc01vbml0b3JpbmcgZXh0ZW5kcyBNb25pdG9yaW5nIHtcbiAgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcbiAgcmVhZG9ubHkga2luZXNpc0RhdGFBbmFseXRpY3NVcmw/OiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkga2RhQWxhcm1GYWN0b3J5OiBLaW5lc2lzRGF0YUFuYWx5dGljc0FsYXJtRmFjdG9yeTtcbiAgcmVhZG9ubHkgZG93bnRpbWVBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgZnVsbFJlc3RhcnRBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgZnVsbFJlc3RhcnRSYXRlQW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IGJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgY2hlY2twb2ludEZhaWx1cmVDb3VudEFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICByZWFkb25seSBjaGVja3BvaW50RmFpbHVyZVJhdGVBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcblxuICByZWFkb25seSBjcHVVdGlsaXphdGlvblBlcmNlbnRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGRvd250aW1lTXNNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGZ1bGxSZXN0YXJ0c0NvdW50TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBoZWFwTWVtb3J5VXRpbGl6YXRpb25QZXJjZW50TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBrcHVzQ291bnRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGxhc3RDaGVja3BvaW50RHVyYXRpb25Nc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbGFzdENoZWNrcG9pbnRTaXplQnl0ZXNNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG51bWJlck9mRmFpbGVkQ2hlY2twb2ludHNDb3VudE1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgb2xkR2VuZXJhdGlvbkdDQ291bnRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG9sZEdlbmVyYXRpb25HQ1RpbWVNc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgY2hlY2twb2ludEZhaWx1cmVSYXRlTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBmdWxsUmVzdGFydFJhdGVNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IE1vbml0b3JpbmdTY29wZSxcbiAgICBwcm9wczogS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nUHJvcHMsXG4gICkge1xuICAgIHN1cGVyKHNjb3BlLCBwcm9wcyk7XG5cbiAgICBjb25zdCBuYW1pbmdTdHJhdGVneSA9IG5ldyBNb25pdG9yaW5nTmFtaW5nU3RyYXRlZ3koe1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBmYWxsYmFja0NvbnN0cnVjdE5hbWU6IHByb3BzLmFwcGxpY2F0aW9uLFxuICAgIH0pO1xuICAgIHRoaXMudGl0bGUgPSBuYW1pbmdTdHJhdGVneS5yZXNvbHZlSHVtYW5SZWFkYWJsZU5hbWUoKTtcbiAgICB0aGlzLmtpbmVzaXNEYXRhQW5hbHl0aWNzVXJsID0gc2NvcGVcbiAgICAgIC5jcmVhdGVBd3NDb25zb2xlVXJsRmFjdG9yeSgpXG4gICAgICAuZ2V0S2luZXNpc0FuYWx5dGljc1VybChwcm9wcy5hcHBsaWNhdGlvbik7XG5cbiAgICBjb25zdCBhbGFybUZhY3RvcnkgPSB0aGlzLmNyZWF0ZUFsYXJtRmFjdG9yeShcbiAgICAgIG5hbWluZ1N0cmF0ZWd5LnJlc29sdmVBbGFybUZyaWVuZGx5TmFtZSgpLFxuICAgICk7XG4gICAgdGhpcy5rZGFBbGFybUZhY3RvcnkgPSBuZXcgS2luZXNpc0RhdGFBbmFseXRpY3NBbGFybUZhY3RvcnkoYWxhcm1GYWN0b3J5KTtcbiAgICB0aGlzLmRvd250aW1lQW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmZ1bGxSZXN0YXJ0QW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmZ1bGxSZXN0YXJ0UmF0ZUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5iYWNrUHJlc3N1cmVkVGltZU1zUGVyU2Vjb25kQW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmNoZWNrcG9pbnRGYWlsdXJlQ291bnRBbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMuY2hlY2twb2ludEZhaWx1cmVSYXRlQW5ub3RhdGlvbnMgPSBbXTtcblxuICAgIGNvbnN0IG1ldHJpY0ZhY3RvcnkgPSBuZXcgS2luZXNpc0RhdGFBbmFseXRpY3NNZXRyaWNGYWN0b3J5KFxuICAgICAgc2NvcGUuY3JlYXRlTWV0cmljRmFjdG9yeSgpLFxuICAgICAgcHJvcHMsXG4gICAgKTtcblxuICAgIHRoaXMuY3B1VXRpbGl6YXRpb25QZXJjZW50TWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljQ3B1VXRpbGl6YXRpb25QZXJjZW50KCk7XG4gICAgdGhpcy5kb3dudGltZU1zTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNEb3dudGltZU1zKCk7XG4gICAgdGhpcy5mdWxsUmVzdGFydHNDb3VudE1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljRnVsbFJlc3RhcnRzQ291bnQoKTtcbiAgICB0aGlzLmhlYXBNZW1vcnlVdGlsaXphdGlvblBlcmNlbnRNZXRyaWMgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNIZWFwTWVtb3J5VXRpbGl6YXRpb25QZXJjZW50KCk7XG4gICAgdGhpcy5rcHVzQ291bnRNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0tQVXNDb3VudCgpO1xuICAgIHRoaXMubGFzdENoZWNrcG9pbnREdXJhdGlvbk1zTWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljTGFzdENoZWNrcG9pbnREdXJhdGlvbk1zKCk7XG4gICAgdGhpcy5sYXN0Q2hlY2twb2ludFNpemVCeXRlc01ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0xhc3RDaGVja3BvaW50U2l6ZUJ5dGVzKCk7XG4gICAgdGhpcy5udW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzQ291bnRNZXRyaWMgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNOdW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzQ291bnQoKTtcbiAgICB0aGlzLm9sZEdlbmVyYXRpb25HQ0NvdW50TWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljT2xkR2VuZXJhdGlvbkdDQ291bnQoKTtcbiAgICB0aGlzLm9sZEdlbmVyYXRpb25HQ1RpbWVNc01ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY09sZEdlbmVyYXRpb25HQ1RpbWVNcygpO1xuICAgIHRoaXMuY2hlY2twb2ludEZhaWx1cmVSYXRlTWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljQ2hlY2twb2ludEZhaWx1cmVSYXRlKCk7XG4gICAgdGhpcy5mdWxsUmVzdGFydFJhdGVNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0Z1bGxSZXN0YXJ0UmF0ZSgpO1xuICAgIHRoaXMuYmFja1ByZXNzdXJlZFRpbWVNc1BlclNlY29uZE1ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0JhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmQoKTtcblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGREb3dudGltZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkRG93bnRpbWVBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMua2RhQWxhcm1GYWN0b3J5LmFkZERvd250aW1lQWxhcm0oXG4gICAgICAgIHRoaXMuZG93bnRpbWVNc01ldHJpYyxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmRvd250aW1lQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZEZ1bGxSZXN0YXJ0Q291bnRBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZEZ1bGxSZXN0YXJ0Q291bnRBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMua2RhQWxhcm1GYWN0b3J5LmFkZEZ1bGxSZXN0YXJ0QWxhcm0oXG4gICAgICAgIHRoaXMuZnVsbFJlc3RhcnRzQ291bnRNZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy5mdWxsUmVzdGFydEFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRGdWxsUmVzdGFydFJhdGVBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZEZ1bGxSZXN0YXJ0UmF0ZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5rZGFBbGFybUZhY3RvcnkuYWRkRnVsbFJlc3RhcnRSYXRlQWxhcm0oXG4gICAgICAgIHRoaXMuZnVsbFJlc3RhcnRSYXRlTWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuZnVsbFJlc3RhcnRSYXRlQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZEJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9XG4gICAgICAgIHByb3BzLmFkZEJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9XG4gICAgICAgIHRoaXMua2RhQWxhcm1GYWN0b3J5LmFkZEJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRBbGFybShcbiAgICAgICAgICB0aGlzLmJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRNZXRyaWMsXG4gICAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgICApO1xuICAgICAgdGhpcy5iYWNrUHJlc3N1cmVkVGltZU1zUGVyU2Vjb25kQW5ub3RhdGlvbnMucHVzaChcbiAgICAgICAgY3JlYXRlZEFsYXJtLmFubm90YXRpb24sXG4gICAgICApO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRDaGVja3BvaW50RmFpbHVyZUNvdW50QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRDaGVja3BvaW50RmFpbHVyZUNvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmtkYUFsYXJtRmFjdG9yeS5hZGRDaGVja3BvaW50RmFpbHVyZUNvdW50QWxhcm0oXG4gICAgICAgIHRoaXMubnVtYmVyT2ZGYWlsZWRDaGVja3BvaW50c0NvdW50TWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuY2hlY2twb2ludEZhaWx1cmVDb3VudEFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRDaGVja3BvaW50RmFpbHVyZVJhdGVBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZENoZWNrcG9pbnRGYWlsdXJlUmF0ZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5rZGFBbGFybUZhY3RvcnkuYWRkQ2hlY2twb2ludEZhaWx1cmVSYXRlQWxhcm0oXG4gICAgICAgIHRoaXMuY2hlY2twb2ludEZhaWx1cmVSYXRlTWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuY2hlY2twb2ludEZhaWx1cmVSYXRlQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgcHJvcHMudXNlQ3JlYXRlZEFsYXJtcz8uY29uc3VtZSh0aGlzLmNyZWF0ZWRBbGFybXMoKSk7XG4gIH1cblxuICBzdW1tYXJ5V2lkZ2V0cygpOiBJV2lkZ2V0W10ge1xuICAgIHJldHVybiBbXG4gICAgICB0aGlzLmNyZWF0ZVRpdGxlV2lkZ2V0KCksXG4gICAgICAuLi50aGlzLmNyZWF0ZVN1bW1hcnlXaWRnZXRSb3coRGVmYXVsdFN1bW1hcnlXaWRnZXRIZWlnaHQpLFxuICAgIF07XG4gIH1cblxuICB3aWRnZXRzKCk6IElXaWRnZXRbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMuY3JlYXRlVGl0bGVXaWRnZXQoKSxcbiAgICAgIC4uLnRoaXMuY3JlYXRlU3VtbWFyeVdpZGdldFJvdyhEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgLi4udGhpcy5jcmVhdGVDaGVja3BvaW50QW5kR2NXaWRnZXRzKCksXG4gICAgXTtcbiAgfVxuXG4gIGNyZWF0ZVRpdGxlV2lkZ2V0KCkge1xuICAgIHJldHVybiBuZXcgTW9uaXRvcmluZ0hlYWRlcldpZGdldCh7XG4gICAgICBmYW1pbHk6IFwiS2luZXNpcyBEYXRhIEFuYWx5dGljc1wiLFxuICAgICAgdGl0bGU6IHRoaXMudGl0bGUsXG4gICAgICBnb1RvTGlua1VybDogdGhpcy5raW5lc2lzRGF0YUFuYWx5dGljc1VybCxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUtQVVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJLUFUgVXNhZ2VcIixcbiAgICAgIGxlZnQ6IFt0aGlzLmtwdXNDb3VudE1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlUmVzb3VyY2VVdGlsaXphdGlvbldpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJSZXNvdXJjZSBVdGlsaXphdGlvblwiLFxuICAgICAgbGVmdDogW1xuICAgICAgICB0aGlzLmNwdVV0aWxpemF0aW9uUGVyY2VudE1ldHJpYyxcbiAgICAgICAgdGhpcy5oZWFwTWVtb3J5VXRpbGl6YXRpb25QZXJjZW50TWV0cmljLFxuICAgICAgXSxcbiAgICAgIGxlZnRZQXhpczogUGVyY2VudGFnZUF4aXNGcm9tWmVyb1RvSHVuZHJlZCxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZURvd25UaW1lV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkRvd24gVGltZVwiLFxuICAgICAgbGVmdDogW3RoaXMuZG93bnRpbWVNc01ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IFRpbWVBeGlzTWlsbGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMuZG93bnRpbWVBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUZ1bGxSZXN0YXJ0c1dpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJGdWxsIFJlc3RhcnRzXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5mdWxsUmVzdGFydHNDb3VudE1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgICAgbGVmdEFubm90YXRpb25zOiB0aGlzLmZ1bGxSZXN0YXJ0QW5ub3RhdGlvbnMsXG4gICAgICByaWdodDogW3RoaXMuZnVsbFJlc3RhcnRSYXRlTWV0cmljXSxcbiAgICAgIHJpZ2h0WUF4aXM6IFJhdGVBeGlzRnJvbVplcm8sXG4gICAgICByaWdodEFubm90YXRpb25zOiB0aGlzLmZ1bGxSZXN0YXJ0UmF0ZUFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlQmFja1ByZXNzdXJlZFRpbWVXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiQmFjayBQcmVzc3VyZWQgVGltZVwiLFxuICAgICAgbGVmdDogW3RoaXMuYmFja1ByZXNzdXJlZFRpbWVNc1BlclNlY29uZE1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IFRpbWVBeGlzTWlsbGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMuYmFja1ByZXNzdXJlZFRpbWVNc1BlclNlY29uZEFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlTnVtYmVyT2ZGYWlsZWRDaGVja3BvaW50c1dpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJDaGVja3BvaW50IEZhaWx1cmVzXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5udW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzQ291bnRNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBDb3VudEF4aXNGcm9tWmVybyxcbiAgICAgIGxlZnRBbm5vdGF0aW9uczogdGhpcy5jaGVja3BvaW50RmFpbHVyZUNvdW50QW5ub3RhdGlvbnMsXG4gICAgICByaWdodDogW3RoaXMuY2hlY2twb2ludEZhaWx1cmVSYXRlTWV0cmljXSxcbiAgICAgIHJpZ2h0WUF4aXM6IFJhdGVBeGlzRnJvbVplcm8sXG4gICAgICByaWdodEFubm90YXRpb25zOiB0aGlzLmNoZWNrcG9pbnRGYWlsdXJlUmF0ZUFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlTGFzdENoZWNrcG9pbnREdXJhdGlvbldpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJDaGVja3BvaW50IER1cmF0aW9uXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5sYXN0Q2hlY2twb2ludER1cmF0aW9uTXNNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBUaW1lQXhpc01pbGxpc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlTGFzdENoZWNrcG9pbnRTaXplV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkNoZWNrcG9pbnQgU2l6ZVwiLFxuICAgICAgbGVmdDogW3RoaXMubGFzdENoZWNrcG9pbnRTaXplQnl0ZXNNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBTaXplQXhpc0J5dGVzRnJvbVplcm8sXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVHYXJiYWdlQ29sbGVjdGlvbldpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJHYXJiYWdlIENvbGxlY3Rpb25cIixcbiAgICAgIGxlZnQ6IFt0aGlzLm9sZEdlbmVyYXRpb25HQ0NvdW50TWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgICByaWdodDogW3RoaXMub2xkR2VuZXJhdGlvbkdDVGltZU1zTWV0cmljXSxcbiAgICAgIHJpZ2h0WUF4aXM6IFRpbWVBeGlzTWlsbGlzRnJvbVplcm8sXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVN1bW1hcnlXaWRnZXRSb3coaGVpZ2h0OiBudW1iZXIpOiBHcmFwaFdpZGdldFtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgLy8gS1BVc1xuICAgICAgdGhpcy5jcmVhdGVLUFVXaWRnZXQoUXVhcnRlcldpZHRoLCBoZWlnaHQpLFxuICAgICAgLy8gQ1BVIEFuZCBIZWFwIFVzYWdlXG4gICAgICB0aGlzLmNyZWF0ZVJlc291cmNlVXRpbGl6YXRpb25XaWRnZXQoUXVhcnRlcldpZHRoLCBoZWlnaHQpLFxuICAgICAgLy8gRG93biBUaW1lIGFuZCBVcCBUaW1lXG4gICAgICB0aGlzLmNyZWF0ZURvd25UaW1lV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgaGVpZ2h0KSxcbiAgICAgIC8vIEZ1bGwgUmVzdGFydHNcbiAgICAgIHRoaXMuY3JlYXRlRnVsbFJlc3RhcnRzV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgaGVpZ2h0KSxcbiAgICBdO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVDaGVja3BvaW50QW5kR2NXaWRnZXRzKCk6IEdyYXBoV2lkZ2V0W10ge1xuICAgIHJldHVybiBbXG4gICAgICAvLyBCYWNrIFByZXNzdXJlXG4gICAgICB0aGlzLmNyZWF0ZUJhY2tQcmVzc3VyZWRUaW1lV2lkZ2V0KFxuICAgICAgICBRdWFydGVyV2lkdGgsXG4gICAgICAgIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCxcbiAgICAgICksXG4gICAgICAvLyBDaGVja3BvaW50aW5nXG4gICAgICB0aGlzLmNyZWF0ZU51bWJlck9mRmFpbGVkQ2hlY2twb2ludHNXaWRnZXQoXG4gICAgICAgIFF1YXJ0ZXJXaWR0aCxcbiAgICAgICAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICAgICAgKSxcbiAgICAgIC8vIENoZWNrcG9pbnQgRHVyYXRpb25cbiAgICAgIHRoaXMuY3JlYXRlTGFzdENoZWNrcG9pbnREdXJhdGlvbldpZGdldChcbiAgICAgICAgUXVhcnRlcldpZHRoLFxuICAgICAgICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gICAgICApLFxuICAgICAgLy8gQ2hlY2twb2ludCBTaXplXG4gICAgICB0aGlzLmNyZWF0ZUxhc3RDaGVja3BvaW50U2l6ZVdpZGdldChcbiAgICAgICAgUXVhcnRlcldpZHRoLFxuICAgICAgICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gICAgICApLFxuICAgICAgLy8gR2FyYmFnZSBDb2xsZWN0aW9uXG4gICAgICB0aGlzLmNyZWF0ZUdhcmJhZ2VDb2xsZWN0aW9uV2lkZ2V0KFxuICAgICAgICBRdWFydGVyV2lkdGgsXG4gICAgICAgIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCxcbiAgICAgICksXG4gICAgXTtcbiAgfVxufVxuIl19