cdk-monitoring-constructs
Version:
[](https://gitpod.io/#https://github.com/cdklabs/cdk-monitoring-constructs) [](https://badge
184 lines • 26.3 kB
JavaScript
"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 common_1 = require("../../common");
const dashboard_1 = require("../../dashboard");
const KinesisDataAnalyticsMetricFactory_1 = require("./KinesisDataAnalyticsMetricFactory");
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 = [];
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();
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);
}
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,
});
}
createNumberOfFailedCheckpointsWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Checkpoint Failures",
left: [this.numberOfFailedCheckpointsCountMetric],
leftYAxis: common_1.CountAxisFromZero,
});
}
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 [
// 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: "1.21.0" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0RBSW9DO0FBRXBDLHlDQWVzQjtBQUN0QiwrQ0FHeUI7QUFDekIsMkZBRzZDO0FBYTdDLE1BQWEsOEJBQStCLFNBQVEsbUJBQVU7SUFtQjVELFlBQ0UsS0FBc0IsRUFDdEIsS0FBMEM7UUFFMUMsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVwQixNQUFNLGNBQWMsR0FBRyxJQUFJLG9DQUF3QixDQUFDO1lBQ2xELEdBQUcsS0FBSztZQUNSLHFCQUFxQixFQUFFLEtBQUssQ0FBQyxXQUFXO1NBQ3pDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxLQUFLLEdBQUcsY0FBYyxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDdkQsSUFBSSxDQUFDLHVCQUF1QixHQUFHLEtBQUs7YUFDakMsMEJBQTBCLEVBQUU7YUFDNUIsc0JBQXNCLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRTdDLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FDMUMsY0FBYyxDQUFDLHdCQUF3QixFQUFFLENBQzFDLENBQUM7UUFDRixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUkseUNBQWdDLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDMUUsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEVBQUUsQ0FBQztRQUM5QixJQUFJLENBQUMsc0JBQXNCLEdBQUcsRUFBRSxDQUFDO1FBRWpDLE1BQU0sYUFBYSxHQUFHLElBQUkscUVBQWlDLENBQ3pELEtBQUssQ0FBQyxtQkFBbUIsRUFBRSxFQUMzQixLQUFLLENBQ04sQ0FBQztRQUVGLElBQUksQ0FBQywyQkFBMkI7WUFDOUIsYUFBYSxDQUFDLDJCQUEyQixFQUFFLENBQUM7UUFDOUMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLGFBQWEsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3pELElBQUksQ0FBQyx1QkFBdUIsR0FBRyxhQUFhLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUN2RSxJQUFJLENBQUMsa0NBQWtDO1lBQ3JDLGFBQWEsQ0FBQyxrQ0FBa0MsRUFBRSxDQUFDO1FBQ3JELElBQUksQ0FBQyxlQUFlLEdBQUcsYUFBYSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZELElBQUksQ0FBQyw4QkFBOEI7WUFDakMsYUFBYSxDQUFDLDhCQUE4QixFQUFFLENBQUM7UUFDakQsSUFBSSxDQUFDLDZCQUE2QjtZQUNoQyxhQUFhLENBQUMsNkJBQTZCLEVBQUUsQ0FBQztRQUNoRCxJQUFJLENBQUMsb0NBQW9DO1lBQ3ZDLGFBQWEsQ0FBQyxvQ0FBb0MsRUFBRSxDQUFDO1FBQ3ZELElBQUksQ0FBQywwQkFBMEI7WUFDN0IsYUFBYSxDQUFDLDBCQUEwQixFQUFFLENBQUM7UUFDN0MsSUFBSSxDQUFDLDJCQUEyQjtZQUM5QixhQUFhLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztRQUU5QyxLQUFLLE1BQU0sYUFBYSxJQUFJLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRTtZQUNsRCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDekQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FDeEQsSUFBSSxDQUFDLGdCQUFnQixFQUNyQixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7WUFDRixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN2RCxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1NBQzdCO1FBRUQsS0FBSyxNQUFNLGFBQWEsSUFBSSxLQUFLLENBQUMsd0JBQXdCLEVBQUU7WUFDMUQsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLHdCQUF3QixDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ2pFLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsbUJBQW1CLENBQzNELElBQUksQ0FBQyx1QkFBdUIsRUFDNUIsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1lBQ0YsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDMUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUM3QjtRQUVELEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVELGNBQWM7UUFDWixPQUFPO1lBQ0wsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQ3hCLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLG1DQUEwQixDQUFDO1NBQzNELENBQUM7SUFDSixDQUFDO0lBRUQsT0FBTztRQUNMLE9BQU87WUFDTCxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDeEIsR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsaUNBQXdCLENBQUM7WUFDeEQsR0FBRyxJQUFJLENBQUMsNEJBQTRCLEVBQUU7U0FDdkMsQ0FBQztJQUNKLENBQUM7SUFFUyxpQkFBaUI7UUFDekIsT0FBTyxJQUFJLGtDQUFzQixDQUFDO1lBQ2hDLE1BQU0sRUFBRSx3QkFBd0I7WUFDaEMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO1lBQ2pCLFdBQVcsRUFBRSxJQUFJLENBQUMsdUJBQXVCO1NBQzFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFUyxlQUFlLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDckQsT0FBTyxJQUFJLDRCQUFXLENBQUM7WUFDckIsS0FBSztZQUNMLE1BQU07WUFDTixLQUFLLEVBQUUsV0FBVztZQUNsQixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDO1lBQzVCLFNBQVMsRUFBRSwwQkFBaUI7U0FDN0IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVTLCtCQUErQixDQUFDLEtBQWEsRUFBRSxNQUFjO1FBQ3JFLE9BQU8sSUFBSSw0QkFBVyxDQUFDO1lBQ3JCLEtBQUs7WUFDTCxNQUFNO1lBQ04sS0FBSyxFQUFFLHNCQUFzQjtZQUM3QixJQUFJLEVBQUU7Z0JBQ0osSUFBSSxDQUFDLDJCQUEyQjtnQkFDaEMsSUFBSSxDQUFDLGtDQUFrQzthQUN4QztZQUNELFNBQVMsRUFBRSx3Q0FBK0I7U0FDM0MsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVTLG9CQUFvQixDQUFDLEtBQWEsRUFBRSxNQUFjO1FBQzFELE9BQU8sSUFBSSw0QkFBVyxDQUFDO1lBQ3JCLEtBQUs7WUFDTCxNQUFNO1lBQ04sS0FBSyxFQUFFLFdBQVc7WUFDbEIsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1lBQzdCLFNBQVMsRUFBRSwrQkFBc0I7WUFDakMsZUFBZSxFQUFFLElBQUksQ0FBQyxtQkFBbUI7U0FDMUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVTLHdCQUF3QixDQUFDLEtBQWEsRUFBRSxNQUFjO1FBQzlELE9BQU8sSUFBSSw0QkFBVyxDQUFDO1lBQ3JCLEtBQUs7WUFDTCxNQUFNO1lBQ04sS0FBSyxFQUFFLGVBQWU7WUFDdEIsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDO1lBQ3BDLFNBQVMsRUFBRSwwQkFBaUI7WUFDNUIsZUFBZSxFQUFFLElBQUksQ0FBQyxzQkFBc0I7U0FDN0MsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVTLHFDQUFxQyxDQUM3QyxLQUFhLEVBQ2IsTUFBYztRQUVkLE9BQU8sSUFBSSw0QkFBVyxDQUFDO1lBQ3JCLEtBQUs7WUFDTCxNQUFNO1lBQ04sS0FBSyxFQUFFLHFCQUFxQjtZQUM1QixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsb0NBQW9DLENBQUM7WUFDakQsU0FBUyxFQUFFLDBCQUFpQjtTQUM3QixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRVMsa0NBQWtDLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDeEUsT0FBTyxJQUFJLDRCQUFXLENBQUM7WUFDckIsS0FBSztZQUNMLE1BQU07WUFDTixLQUFLLEVBQUUscUJBQXFCO1lBQzVCLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyw4QkFBOEIsQ0FBQztZQUMzQyxTQUFTLEVBQUUsK0JBQXNCO1NBQ2xDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFUyw4QkFBOEIsQ0FBQyxLQUFhLEVBQUUsTUFBYztRQUNwRSxPQUFPLElBQUksNEJBQVcsQ0FBQztZQUNyQixLQUFLO1lBQ0wsTUFBTTtZQUNOLEtBQUssRUFBRSxpQkFBaUI7WUFDeEIsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLDZCQUE2QixDQUFDO1lBQzFDLFNBQVMsRUFBRSw4QkFBcUI7U0FDakMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVTLDZCQUE2QixDQUFDLEtBQWEsRUFBRSxNQUFjO1FBQ25FLE9BQU8sSUFBSSw0QkFBVyxDQUFDO1lBQ3JCLEtBQUs7WUFDTCxNQUFNO1lBQ04sS0FBSyxFQUFFLG9CQUFvQjtZQUMzQixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUM7WUFDdkMsU0FBUyxFQUFFLDBCQUFpQjtZQUM1QixLQUFLLEVBQUUsQ0FBQyxJQUFJLENBQUMsMkJBQTJCLENBQUM7WUFDekMsVUFBVSxFQUFFLCtCQUFzQjtTQUNuQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sc0JBQXNCLENBQUMsTUFBYztRQUMzQyxPQUFPO1lBQ0wsT0FBTztZQUNQLElBQUksQ0FBQyxlQUFlLENBQUMscUJBQVksRUFBRSxNQUFNLENBQUM7WUFDMUMscUJBQXFCO1lBQ3JCLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxxQkFBWSxFQUFFLE1BQU0sQ0FBQztZQUMxRCx3QkFBd0I7WUFDeEIsSUFBSSxDQUFDLG9CQUFvQixDQUFDLHFCQUFZLEVBQUUsTUFBTSxDQUFDO1lBQy9DLGdCQUFnQjtZQUNoQixJQUFJLENBQUMsd0JBQXdCLENBQUMscUJBQVksRUFBRSxNQUFNLENBQUM7U0FDcEQsQ0FBQztJQUNKLENBQUM7SUFFTyw0QkFBNEI7UUFDbEMsT0FBTztZQUNMLGdCQUFnQjtZQUNoQixJQUFJLENBQUMscUNBQXFDLENBQ3hDLHFCQUFZLEVBQ1osaUNBQXdCLENBQ3pCO1lBQ0Qsc0JBQXNCO1lBQ3RCLElBQUksQ0FBQyxrQ0FBa0MsQ0FDckMscUJBQVksRUFDWixpQ0FBd0IsQ0FDekI7WUFDRCxrQkFBa0I7WUFDbEIsSUFBSSxDQUFDLDhCQUE4QixDQUNqQyxxQkFBWSxFQUNaLGlDQUF3QixDQUN6QjtZQUNELHFCQUFxQjtZQUNyQixJQUFJLENBQUMsNkJBQTZCLENBQ2hDLHFCQUFZLEVBQ1osaUNBQXdCLENBQ3pCO1NBQ0YsQ0FBQztJQUNKLENBQUM7O0FBOU9ILHdFQStPQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEdyYXBoV2lkZ2V0LFxuICBIb3Jpem9udGFsQW5ub3RhdGlvbixcbiAgSVdpZGdldCxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoXCI7XG5cbmltcG9ydCB7XG4gIEJhc2VNb25pdG9yaW5nUHJvcHMsXG4gIENvdW50QXhpc0Zyb21aZXJvLFxuICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0LFxuICBGdWxsUmVzdGFydENvdW50VGhyZXNob2xkLFxuICBLaW5lc2lzRGF0YUFuYWx5dGljc0FsYXJtRmFjdG9yeSxcbiAgTWF4RG93bnRpbWVUaHJlc2hvbGQsXG4gIE1ldHJpY1dpdGhBbGFybVN1cHBvcnQsXG4gIE1vbml0b3JpbmcsXG4gIE1vbml0b3JpbmdTY29wZSxcbiAgUGVyY2VudGFnZUF4aXNGcm9tWmVyb1RvSHVuZHJlZCxcbiAgUXVhcnRlcldpZHRoLFxuICBTaXplQXhpc0J5dGVzRnJvbVplcm8sXG4gIFRpbWVBeGlzTWlsbGlzRnJvbVplcm8sXG59IGZyb20gXCIuLi8uLi9jb21tb25cIjtcbmltcG9ydCB7XG4gIE1vbml0b3JpbmdIZWFkZXJXaWRnZXQsXG4gIE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSxcbn0gZnJvbSBcIi4uLy4uL2Rhc2hib2FyZFwiO1xuaW1wb3J0IHtcbiAgS2luZXNpc0RhdGFBbmFseXRpY3NNZXRyaWNGYWN0b3J5LFxuICBLaW5lc2lzRGF0YUFuYWx5dGljc01ldHJpY0ZhY3RvcnlQcm9wcyxcbn0gZnJvbSBcIi4vS2luZXNpc0RhdGFBbmFseXRpY3NNZXRyaWNGYWN0b3J5XCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nT3B0aW9uc1xuICBleHRlbmRzIEJhc2VNb25pdG9yaW5nUHJvcHMge1xuICByZWFkb25seSBhZGREb3dudGltZUFsYXJtPzogUmVjb3JkPHN0cmluZywgTWF4RG93bnRpbWVUaHJlc2hvbGQ+O1xuXG4gIHJlYWRvbmx5IGFkZEZ1bGxSZXN0YXJ0Q291bnRBbGFybT86IFJlY29yZDxzdHJpbmcsIEZ1bGxSZXN0YXJ0Q291bnRUaHJlc2hvbGQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEtpbmVzaXNEYXRhQW5hbHl0aWNzTW9uaXRvcmluZ1Byb3BzXG4gIGV4dGVuZHMgS2luZXNpc0RhdGFBbmFseXRpY3NNZXRyaWNGYWN0b3J5UHJvcHMsXG4gICAgS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nT3B0aW9ucyB7fVxuXG5leHBvcnQgY2xhc3MgS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nIGV4dGVuZHMgTW9uaXRvcmluZyB7XG4gIHByb3RlY3RlZCByZWFkb25seSB0aXRsZTogc3RyaW5nO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkga2luZXNpc0RhdGFBbmFseXRpY3NVcmw/OiBzdHJpbmc7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGtkYUFsYXJtRmFjdG9yeTogS2luZXNpc0RhdGFBbmFseXRpY3NBbGFybUZhY3Rvcnk7XG4gIHByb3RlY3RlZCByZWFkb25seSBkb3dudGltZUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZnVsbFJlc3RhcnRBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY3B1VXRpbGl6YXRpb25QZXJjZW50TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZG93bnRpbWVNc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGZ1bGxSZXN0YXJ0c0NvdW50TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaGVhcE1lbW9yeVV0aWxpemF0aW9uUGVyY2VudE1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGtwdXNDb3VudE1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGxhc3RDaGVja3BvaW50RHVyYXRpb25Nc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGxhc3RDaGVja3BvaW50U2l6ZUJ5dGVzTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbnVtYmVyT2ZGYWlsZWRDaGVja3BvaW50c0NvdW50TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgb2xkR2VuZXJhdGlvbkdDQ291bnRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHByb3RlY3RlZCByZWFkb25seSBvbGRHZW5lcmF0aW9uR0NUaW1lTXNNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IE1vbml0b3JpbmdTY29wZSxcbiAgICBwcm9wczogS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nUHJvcHNcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIHByb3BzKTtcblxuICAgIGNvbnN0IG5hbWluZ1N0cmF0ZWd5ID0gbmV3IE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSh7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIGZhbGxiYWNrQ29uc3RydWN0TmFtZTogcHJvcHMuYXBwbGljYXRpb24sXG4gICAgfSk7XG4gICAgdGhpcy50aXRsZSA9IG5hbWluZ1N0cmF0ZWd5LnJlc29sdmVIdW1hblJlYWRhYmxlTmFtZSgpO1xuICAgIHRoaXMua2luZXNpc0RhdGFBbmFseXRpY3NVcmwgPSBzY29wZVxuICAgICAgLmNyZWF0ZUF3c0NvbnNvbGVVcmxGYWN0b3J5KClcbiAgICAgIC5nZXRLaW5lc2lzQW5hbHl0aWNzVXJsKHByb3BzLmFwcGxpY2F0aW9uKTtcblxuICAgIGNvbnN0IGFsYXJtRmFjdG9yeSA9IHRoaXMuY3JlYXRlQWxhcm1GYWN0b3J5KFxuICAgICAgbmFtaW5nU3RyYXRlZ3kucmVzb2x2ZUFsYXJtRnJpZW5kbHlOYW1lKClcbiAgICApO1xuICAgIHRoaXMua2RhQWxhcm1GYWN0b3J5ID0gbmV3IEtpbmVzaXNEYXRhQW5hbHl0aWNzQWxhcm1GYWN0b3J5KGFsYXJtRmFjdG9yeSk7XG4gICAgdGhpcy5kb3dudGltZUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5mdWxsUmVzdGFydEFubm90YXRpb25zID0gW107XG5cbiAgICBjb25zdCBtZXRyaWNGYWN0b3J5ID0gbmV3IEtpbmVzaXNEYXRhQW5hbHl0aWNzTWV0cmljRmFjdG9yeShcbiAgICAgIHNjb3BlLmNyZWF0ZU1ldHJpY0ZhY3RvcnkoKSxcbiAgICAgIHByb3BzXG4gICAgKTtcblxuICAgIHRoaXMuY3B1VXRpbGl6YXRpb25QZXJjZW50TWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljQ3B1VXRpbGl6YXRpb25QZXJjZW50KCk7XG4gICAgdGhpcy5kb3dudGltZU1zTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNEb3dudGltZU1zKCk7XG4gICAgdGhpcy5mdWxsUmVzdGFydHNDb3VudE1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljRnVsbFJlc3RhcnRzQ291bnQoKTtcbiAgICB0aGlzLmhlYXBNZW1vcnlVdGlsaXphdGlvblBlcmNlbnRNZXRyaWMgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNIZWFwTWVtb3J5VXRpbGl6YXRpb25QZXJjZW50KCk7XG4gICAgdGhpcy5rcHVzQ291bnRNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0tQVXNDb3VudCgpO1xuICAgIHRoaXMubGFzdENoZWNrcG9pbnREdXJhdGlvbk1zTWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljTGFzdENoZWNrcG9pbnREdXJhdGlvbk1zKCk7XG4gICAgdGhpcy5sYXN0Q2hlY2twb2ludFNpemVCeXRlc01ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0xhc3RDaGVja3BvaW50U2l6ZUJ5dGVzKCk7XG4gICAgdGhpcy5udW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzQ291bnRNZXRyaWMgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNOdW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzQ291bnQoKTtcbiAgICB0aGlzLm9sZEdlbmVyYXRpb25HQ0NvdW50TWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljT2xkR2VuZXJhdGlvbkdDQ291bnQoKTtcbiAgICB0aGlzLm9sZEdlbmVyYXRpb25HQ1RpbWVNc01ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY09sZEdlbmVyYXRpb25HQ1RpbWVNcygpO1xuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZERvd250aW1lQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGREb3dudGltZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5rZGFBbGFybUZhY3RvcnkuYWRkRG93bnRpbWVBbGFybShcbiAgICAgICAgdGhpcy5kb3dudGltZU1zTWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICApO1xuICAgICAgdGhpcy5kb3dudGltZUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRGdWxsUmVzdGFydENvdW50QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRGdWxsUmVzdGFydENvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmtkYUFsYXJtRmFjdG9yeS5hZGRGdWxsUmVzdGFydEFsYXJtKFxuICAgICAgICB0aGlzLmZ1bGxSZXN0YXJ0c0NvdW50TWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICApO1xuICAgICAgdGhpcy5mdWxsUmVzdGFydEFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIHByb3BzLnVzZUNyZWF0ZWRBbGFybXM/LmNvbnN1bWUodGhpcy5jcmVhdGVkQWxhcm1zKCkpO1xuICB9XG5cbiAgc3VtbWFyeVdpZGdldHMoKTogSVdpZGdldFtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy5jcmVhdGVUaXRsZVdpZGdldCgpLFxuICAgICAgLi4udGhpcy5jcmVhdGVTdW1tYXJ5V2lkZ2V0Um93KERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0KSxcbiAgICBdO1xuICB9XG5cbiAgd2lkZ2V0cygpOiBJV2lkZ2V0W10ge1xuICAgIHJldHVybiBbXG4gICAgICB0aGlzLmNyZWF0ZVRpdGxlV2lkZ2V0KCksXG4gICAgICAuLi50aGlzLmNyZWF0ZVN1bW1hcnlXaWRnZXRSb3coRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgIC4uLnRoaXMuY3JlYXRlQ2hlY2twb2ludEFuZEdjV2lkZ2V0cygpLFxuICAgIF07XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlVGl0bGVXaWRnZXQoKSB7XG4gICAgcmV0dXJuIG5ldyBNb25pdG9yaW5nSGVhZGVyV2lkZ2V0KHtcbiAgICAgIGZhbWlseTogXCJLaW5lc2lzIERhdGEgQW5hbHl0aWNzXCIsXG4gICAgICB0aXRsZTogdGhpcy50aXRsZSxcbiAgICAgIGdvVG9MaW5rVXJsOiB0aGlzLmtpbmVzaXNEYXRhQW5hbHl0aWNzVXJsLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZUtQVVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJLUFUgVXNhZ2VcIixcbiAgICAgIGxlZnQ6IFt0aGlzLmtwdXNDb3VudE1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZVJlc291cmNlVXRpbGl6YXRpb25XaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiUmVzb3VyY2UgVXRpbGl6YXRpb25cIixcbiAgICAgIGxlZnQ6IFtcbiAgICAgICAgdGhpcy5jcHVVdGlsaXphdGlvblBlcmNlbnRNZXRyaWMsXG4gICAgICAgIHRoaXMuaGVhcE1lbW9yeVV0aWxpemF0aW9uUGVyY2VudE1ldHJpYyxcbiAgICAgIF0sXG4gICAgICBsZWZ0WUF4aXM6IFBlcmNlbnRhZ2VBeGlzRnJvbVplcm9Ub0h1bmRyZWQsXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlRG93blRpbWVXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiRG93biBUaW1lXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5kb3dudGltZU1zTWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogVGltZUF4aXNNaWxsaXNGcm9tWmVybyxcbiAgICAgIGxlZnRBbm5vdGF0aW9uczogdGhpcy5kb3dudGltZUFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZUZ1bGxSZXN0YXJ0c1dpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJGdWxsIFJlc3RhcnRzXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5mdWxsUmVzdGFydHNDb3VudE1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgICAgbGVmdEFubm90YXRpb25zOiB0aGlzLmZ1bGxSZXN0YXJ0QW5ub3RhdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlTnVtYmVyT2ZGYWlsZWRDaGVja3BvaW50c1dpZGdldChcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyXG4gICkge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJDaGVja3BvaW50IEZhaWx1cmVzXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5udW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzQ291bnRNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBDb3VudEF4aXNGcm9tWmVybyxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjcmVhdGVMYXN0Q2hlY2twb2ludER1cmF0aW9uV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkNoZWNrcG9pbnQgRHVyYXRpb25cIixcbiAgICAgIGxlZnQ6IFt0aGlzLmxhc3RDaGVja3BvaW50RHVyYXRpb25Nc01ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IFRpbWVBeGlzTWlsbGlzRnJvbVplcm8sXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlTGFzdENoZWNrcG9pbnRTaXplV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkNoZWNrcG9pbnQgU2l6ZVwiLFxuICAgICAgbGVmdDogW3RoaXMubGFzdENoZWNrcG9pbnRTaXplQnl0ZXNNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBTaXplQXhpc0J5dGVzRnJvbVplcm8sXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlR2FyYmFnZUNvbGxlY3Rpb25XaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiR2FyYmFnZSBDb2xsZWN0aW9uXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5vbGRHZW5lcmF0aW9uR0NDb3VudE1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgICAgcmlnaHQ6IFt0aGlzLm9sZEdlbmVyYXRpb25HQ1RpbWVNc01ldHJpY10sXG4gICAgICByaWdodFlBeGlzOiBUaW1lQXhpc01pbGxpc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVTdW1tYXJ5V2lkZ2V0Um93KGhlaWdodDogbnVtYmVyKTogR3JhcGhXaWRnZXRbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC8vIEtQVXNcbiAgICAgIHRoaXMuY3JlYXRlS1BVV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgaGVpZ2h0KSxcbiAgICAgIC8vIENQVSBBbmQgSGVhcCBVc2FnZVxuICAgICAgdGhpcy5jcmVhdGVSZXNvdXJjZVV0aWxpemF0aW9uV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgaGVpZ2h0KSxcbiAgICAgIC8vIERvd24gVGltZSBhbmQgVXAgVGltZVxuICAgICAgdGhpcy5jcmVhdGVEb3duVGltZVdpZGdldChRdWFydGVyV2lkdGgsIGhlaWdodCksXG4gICAgICAvLyBGdWxsIFJlc3RhcnRzXG4gICAgICB0aGlzLmNyZWF0ZUZ1bGxSZXN0YXJ0c1dpZGdldChRdWFydGVyV2lkdGgsIGhlaWdodCksXG4gICAgXTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQ2hlY2twb2ludEFuZEdjV2lkZ2V0cygpOiBHcmFwaFdpZGdldFtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgLy8gQ2hlY2twb2ludGluZ1xuICAgICAgdGhpcy5jcmVhdGVOdW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzV2lkZ2V0KFxuICAgICAgICBRdWFydGVyV2lkdGgsXG4gICAgICAgIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodFxuICAgICAgKSxcbiAgICAgIC8vIENoZWNrcG9pbnQgRHVyYXRpb25cbiAgICAgIHRoaXMuY3JlYXRlTGFzdENoZWNrcG9pbnREdXJhdGlvbldpZGdldChcbiAgICAgICAgUXVhcnRlcldpZHRoLFxuICAgICAgICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHRcbiAgICAgICksXG4gICAgICAvLyBDaGVja3BvaW50IFNpemVcbiAgICAgIHRoaXMuY3JlYXRlTGFzdENoZWNrcG9pbnRTaXplV2lkZ2V0KFxuICAgICAgICBRdWFydGVyV2lkdGgsXG4gICAgICAgIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodFxuICAgICAgKSxcbiAgICAgIC8vIEdhcmJhZ2UgQ29sbGVjdGlvblxuICAgICAgdGhpcy5jcmVhdGVHYXJiYWdlQ29sbGVjdGlvbldpZGdldChcbiAgICAgICAgUXVhcnRlcldpZHRoLFxuICAgICAgICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHRcbiAgICAgICksXG4gICAgXTtcbiAgfVxufVxuIl19