cdk-monitoring-constructs
Version:
[](https://gitpod.io/#https://github.com/cdklabs/cdk-monitoring-constructs) [](https://badge
195 lines • 36.2 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApiGatewayMonitoring = 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 ApiGatewayMetricFactory_1 = require("./ApiGatewayMetricFactory");
const DefaultLatencyTypesToRender = [
common_1.LatencyType.P50,
common_1.LatencyType.P90,
common_1.LatencyType.P99,
];
class ApiGatewayMonitoring extends common_1.Monitoring {
constructor(scope, props) {
super(scope, props);
// used when humanReadableName is not provided by user
const fallbackNameArray = [props.api.restApiName];
fallbackNameArray.push(props.apiStage ?? "prod");
if (props.apiMethod) {
fallbackNameArray.push(props.apiMethod);
}
if (props.apiResource) {
fallbackNameArray.push(props.apiResource);
}
const namingStrategy = new dashboard_1.MonitoringNamingStrategy({
...props,
namedConstruct: props.api,
fallbackConstructName: fallbackNameArray
.join("-")
.replace(/[^a-zA-Z0-9-_]/g, ""),
humanReadableName: props.humanReadableName ?? fallbackNameArray.join(" "),
});
this.title = namingStrategy.resolveHumanReadableName();
this.alarmFactory = this.createAlarmFactory(namingStrategy.resolveAlarmFriendlyName());
this.errorAlarmFactory = new common_1.ErrorAlarmFactory(this.alarmFactory);
this.tpsAlarmFactory = new common_1.TpsAlarmFactory(this.alarmFactory);
this.latencyAlarmFactory = new common_1.LatencyAlarmFactory(this.alarmFactory);
this.tpsAnnotations = [];
this.latencyAnnotations = [];
this.errorCountAnnotations = [];
this.errorRateAnnotations = [];
const metricFactory = new ApiGatewayMetricFactory_1.ApiGatewayMetricFactory(scope.createMetricFactory(), props);
this.tpsMetric = metricFactory.metricTps();
this.latencyMetrics = {};
this.latencyTypesToRender = [
...(props.latencyTypesToRender ?? DefaultLatencyTypesToRender),
];
this.error4XXCountMetric = metricFactory.metric4XXErrorCount();
this.error4XXRateMetric = metricFactory.metric4XXErrorRate();
this.fault5XXCountMetric = metricFactory.metric5XXFaultCount();
this.fault5XXRateMetric = metricFactory.metric5XXFaultRate();
const latencyAlarmDefinitions = {
[common_1.LatencyType.P50]: props.addLatencyP50Alarm,
[common_1.LatencyType.P70]: props.addLatencyP70Alarm,
[common_1.LatencyType.P90]: props.addLatencyP90Alarm,
[common_1.LatencyType.P95]: props.addLatencyP95Alarm,
[common_1.LatencyType.P99]: props.addLatencyP99Alarm,
[common_1.LatencyType.P999]: props.addLatencyP999Alarm,
[common_1.LatencyType.P9999]: props.addLatencyP9999Alarm,
[common_1.LatencyType.P100]: props.addLatencyP100Alarm,
[common_1.LatencyType.TM50]: props.addLatencyTM50Alarm,
[common_1.LatencyType.TM70]: props.addLatencyTM70Alarm,
[common_1.LatencyType.TM90]: props.addLatencyTM90Alarm,
[common_1.LatencyType.TM95]: props.addLatencyTM95Alarm,
[common_1.LatencyType.TM99]: props.addLatencyTM99Alarm,
[common_1.LatencyType.TM999]: props.addLatencyTM999Alarm,
[common_1.LatencyType.TM9999]: props.addLatencyTM9999Alarm,
[common_1.LatencyType.AVERAGE]: props.addLatencyAverageAlarm,
};
Object.values(common_1.LatencyType).forEach((latencyType) => {
this.latencyMetrics[latencyType] =
metricFactory.metricLatencyInMillis(latencyType);
});
for (const [latencyType, alarmDefinition] of Object.entries(latencyAlarmDefinitions)) {
for (const disambiguator in alarmDefinition) {
const alarmProps = alarmDefinition[disambiguator];
const latencyTypeEnum = latencyType;
const metric = this.latencyMetrics[latencyTypeEnum];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(metric, latencyTypeEnum, alarmProps, disambiguator);
this.latencyAnnotations.push(createdAlarm.annotation);
this.latencyTypesToRender.push(latencyTypeEnum);
this.addAlarm(createdAlarm);
}
}
for (const disambiguator in props.add5XXFaultCountAlarm) {
const alarmProps = props.add5XXFaultCountAlarm[disambiguator];
const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(this.fault5XXCountMetric, common_1.ErrorType.FAULT, alarmProps, disambiguator);
this.errorCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.add4XXErrorCountAlarm) {
const alarmProps = props.add4XXErrorCountAlarm[disambiguator];
const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(this.error4XXCountMetric, common_1.ErrorType.ERROR, alarmProps, disambiguator);
this.errorCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.add4XXErrorRateAlarm) {
const alarmProps = props.add4XXErrorRateAlarm[disambiguator];
const createdAlarm = this.errorAlarmFactory.addErrorRateAlarm(this.error4XXRateMetric, common_1.ErrorType.ERROR, alarmProps, disambiguator);
this.errorRateAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.add5XXFaultRateAlarm) {
const alarmProps = props.add5XXFaultRateAlarm[disambiguator];
const createdAlarm = this.errorAlarmFactory.addErrorRateAlarm(this.fault5XXRateMetric, common_1.ErrorType.FAULT, alarmProps, disambiguator);
this.errorRateAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addLowTpsAlarm) {
const alarmProps = props.addLowTpsAlarm[disambiguator];
const createdAlarm = this.tpsAlarmFactory.addMinTpsAlarm(this.tpsMetric, alarmProps, disambiguator);
this.tpsAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addHighTpsAlarm) {
const alarmProps = props.addHighTpsAlarm[disambiguator];
const createdAlarm = this.tpsAlarmFactory.addMaxTpsAlarm(this.tpsMetric, alarmProps, disambiguator);
this.tpsAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
props.useCreatedAlarms?.consume(this.createdAlarms());
}
summaryWidgets() {
return [
this.createTitleWidget(),
this.createTpsWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
this.createLatencyWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
this.createErrorRateWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
];
}
widgets() {
return [
this.createTitleWidget(),
this.createTpsWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createLatencyWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createErrorCountWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createErrorRateWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
];
}
createTitleWidget() {
return new dashboard_1.MonitoringHeaderWidget({
family: "API Gateway Endpoint",
title: this.title,
});
}
createTpsWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "TPS",
left: [this.tpsMetric],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.tpsAnnotations,
});
}
createLatencyWidget(width, height) {
const left = Array.from(new Set(this.latencyTypesToRender))
.sort()
.map((type) => this.latencyMetrics[type]);
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Latency",
left,
leftYAxis: common_1.TimeAxisMillisFromZero,
leftAnnotations: this.latencyAnnotations,
});
}
createErrorCountWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Errors",
left: [this.error4XXCountMetric, this.fault5XXCountMetric],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.errorCountAnnotations,
});
}
createErrorRateWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Errors (rate)",
left: [this.error4XXRateMetric, this.fault5XXRateMetric],
leftYAxis: common_1.RateAxisFromZero,
leftAnnotations: this.errorRateAnnotations,
});
}
}
exports.ApiGatewayMonitoring = ApiGatewayMonitoring;
_a = JSII_RTTI_SYMBOL_1;
ApiGatewayMonitoring[_a] = { fqn: "cdk-monitoring-constructs.ApiGatewayMonitoring", version: "1.21.0" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXBpR2F0ZXdheU1vbml0b3JpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJBcGlHYXRld2F5TW9uaXRvcmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLCtEQUlvQztBQUVwQyx5Q0F1QnNCO0FBQ3RCLCtDQUd5QjtBQUN6Qix1RUFHbUM7QUFFbkMsTUFBTSwyQkFBMkIsR0FBRztJQUNsQyxvQkFBVyxDQUFDLEdBQUc7SUFDZixvQkFBVyxDQUFDLEdBQUc7SUFDZixvQkFBVyxDQUFDLEdBQUc7Q0FDaEIsQ0FBQztBQTBDRixNQUFhLG9CQUFxQixTQUFRLG1CQUFVO0lBdUJsRCxZQUFZLEtBQXNCLEVBQUUsS0FBZ0M7UUFDbEUsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVwQixzREFBc0Q7UUFDdEQsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDbEQsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLElBQUksTUFBTSxDQUFDLENBQUM7UUFDakQsSUFBSSxLQUFLLENBQUMsU0FBUyxFQUFFO1lBQ25CLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDekM7UUFDRCxJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUU7WUFDckIsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztTQUMzQztRQUVELE1BQU0sY0FBYyxHQUFHLElBQUksb0NBQXdCLENBQUM7WUFDbEQsR0FBRyxLQUFLO1lBQ1IsY0FBYyxFQUFFLEtBQUssQ0FBQyxHQUFHO1lBQ3pCLHFCQUFxQixFQUFFLGlCQUFpQjtpQkFDckMsSUFBSSxDQUFDLEdBQUcsQ0FBQztpQkFDVCxPQUFPLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxDQUFDO1lBQ2pDLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxpQkFBaUIsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1NBQzFFLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxLQUFLLEdBQUcsY0FBYyxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFFdkQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQ3pDLGNBQWMsQ0FBQyx3QkFBd0IsRUFBRSxDQUMxQyxDQUFDO1FBQ0YsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksMEJBQWlCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ2xFLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSx3QkFBZSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM5RCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSw0QkFBbUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFdEUsSUFBSSxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMscUJBQXFCLEdBQUcsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxFQUFFLENBQUM7UUFFL0IsTUFBTSxhQUFhLEdBQUcsSUFBSSxpREFBdUIsQ0FDL0MsS0FBSyxDQUFDLG1CQUFtQixFQUFFLEVBQzNCLEtBQUssQ0FDTixDQUFDO1FBRUYsSUFBSSxDQUFDLFNBQVMsR0FBRyxhQUFhLENBQUMsU0FBUyxFQUFFLENBQUM7UUFFM0MsSUFBSSxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLG9CQUFvQixHQUFHO1lBQzFCLEdBQUcsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLElBQUksMkJBQTJCLENBQUM7U0FDL0QsQ0FBQztRQUVGLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxhQUFhLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUMvRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsYUFBYSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDN0QsSUFBSSxDQUFDLG1CQUFtQixHQUFHLGFBQWEsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQy9ELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxhQUFhLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUU3RCxNQUFNLHVCQUF1QixHQUFHO1lBQzlCLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsa0JBQWtCO1lBQzNDLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsa0JBQWtCO1lBQzNDLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsa0JBQWtCO1lBQzNDLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsa0JBQWtCO1lBQzNDLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsa0JBQWtCO1lBQzNDLENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMsbUJBQW1CO1lBQzdDLENBQUMsb0JBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLENBQUMsb0JBQW9CO1lBQy9DLENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMsbUJBQW1CO1lBQzdDLENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMsbUJBQW1CO1lBQzdDLENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMsbUJBQW1CO1lBQzdDLENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMsbUJBQW1CO1lBQzdDLENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMsbUJBQW1CO1lBQzdDLENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMsbUJBQW1CO1lBQzdDLENBQUMsb0JBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLENBQUMsb0JBQW9C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ZUFBZSxFQUFFLElBQUksQ0FBQyxvQkFBb0I7U0FDM0MsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUFsUUgsb0RBbVFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgR3JhcGhXaWRnZXQsXG4gIEhvcml6b250YWxBbm5vdGF0aW9uLFxuICBJV2lkZ2V0LFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2hcIjtcblxuaW1wb3J0IHtcbiAgQWxhcm1GYWN0b3J5LFxuICBCYXNlTW9uaXRvcmluZ1Byb3BzLFxuICBDb3VudEF4aXNGcm9tWmVybyxcbiAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCxcbiAgRXJyb3JBbGFybUZhY3RvcnksXG4gIEVycm9yQ291bnRUaHJlc2hvbGQsXG4gIEVycm9yUmF0ZVRocmVzaG9sZCxcbiAgRXJyb3JUeXBlLFxuICBIaWdoVHBzVGhyZXNob2xkLFxuICBMYXRlbmN5QWxhcm1GYWN0b3J5LFxuICBMYXRlbmN5VGhyZXNob2xkLFxuICBMYXRlbmN5VHlwZSxcbiAgTG93VHBzVGhyZXNob2xkLFxuICBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0LFxuICBNb25pdG9yaW5nLFxuICBNb25pdG9yaW5nU2NvcGUsXG4gIFF1YXJ0ZXJXaWR0aCxcbiAgUmF0ZUF4aXNGcm9tWmVybyxcbiAgVGhpcmRXaWR0aCxcbiAgVGltZUF4aXNNaWxsaXNGcm9tWmVybyxcbiAgVHBzQWxhcm1GYWN0b3J5LFxufSBmcm9tIFwiLi4vLi4vY29tbW9uXCI7XG5pbXBvcnQge1xuICBNb25pdG9yaW5nSGVhZGVyV2lkZ2V0LFxuICBNb25pdG9yaW5nTmFtaW5nU3RyYXRlZ3ksXG59IGZyb20gXCIuLi8uLi9kYXNoYm9hcmRcIjtcbmltcG9ydCB7XG4gIEFwaUdhdGV3YXlNZXRyaWNGYWN0b3J5LFxuICBBcGlHYXRld2F5TWV0cmljRmFjdG9yeVByb3BzLFxufSBmcm9tIFwiLi9BcGlHYXRld2F5TWV0cmljRmFjdG9yeVwiO1xuXG5jb25zdCBEZWZhdWx0TGF0ZW5jeVR5cGVzVG9SZW5kZXIgPSBbXG4gIExhdGVuY3lUeXBlLlA1MCxcbiAgTGF0ZW5jeVR5cGUuUDkwLFxuICBMYXRlbmN5VHlwZS5QOTksXG5dO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFwaUdhdGV3YXlNb25pdG9yaW5nT3B0aW9ucyBleHRlbmRzIEJhc2VNb25pdG9yaW5nUHJvcHMge1xuICByZWFkb25seSBhZGQ0WFhFcnJvckNvdW50QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvckNvdW50VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkNFhYRXJyb3JSYXRlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvclJhdGVUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGQ1WFhGYXVsdENvdW50QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvckNvdW50VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkNVhYRmF1bHRSYXRlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvclJhdGVUaHJlc2hvbGQ+O1xuXG4gIHJlYWRvbmx5IGFkZExhdGVuY3lQNTBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRMYXRlbmN5UDcwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkTGF0ZW5jeVA5MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZExhdGVuY3lQOTVBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRMYXRlbmN5UDk5QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkTGF0ZW5jeVA5OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRMYXRlbmN5UDk5OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRMYXRlbmN5UDEwMEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZExhdGVuY3lUTTUwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkTGF0ZW5jeVRNNzBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRMYXRlbmN5VE05MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZExhdGVuY3lUTTk1QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkTGF0ZW5jeVRNOTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRMYXRlbmN5VE05OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRMYXRlbmN5VE05OTk5QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkTGF0ZW5jeUF2ZXJhZ2VBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuXG4gIHJlYWRvbmx5IGFkZExvd1Rwc0FsYXJtPzogUmVjb3JkPHN0cmluZywgTG93VHBzVGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSGlnaFRwc0FsYXJtPzogUmVjb3JkPHN0cmluZywgSGlnaFRwc1RocmVzaG9sZD47XG5cbiAgLyoqXG4gICAqIFlvdSBjYW4gc3BlY2lmeSB3aGF0IGxhdGVuY3kgdHlwZXMgeW91IHdhbnQgdG8gYmUgcmVuZGVyZWQgaW4gdGhlIGRhc2hib2FyZHMuXG4gICAqIE5vdGU6IGFueSBsYXRlbmN5IHR5cGUgd2l0aCBhbiBhbGFybSB3aWxsIGJlIGFsc28gYWRkZWQgYXV0b21hdGljYWxseS5cbiAgICogSWYgdGhlIGxpc3QgaXMgdW5kZWZpbmVkLCBkZWZhdWx0IHZhbHVlcyB3aWxsIGJlIHNob3duLlxuICAgKiBJZiB0aGUgbGlzdCBpcyBlbXB0eSwgb25seSB0aGUgbGF0ZW5jeSB0eXBlcyB3aXRoIGFuIGFsYXJtIHdpbGwgYmUgc2hvd24gKGlmIGFueSkuXG4gICAqIEBkZWZhdWx0IC0gcDUwLCBwOTAsIHA5OSAoQHNlZSBEZWZhdWx0TGF0ZW5jeVR5cGVzVG9SZW5kZXIpXG4gICAqL1xuICByZWFkb25seSBsYXRlbmN5VHlwZXNUb1JlbmRlcj86IExhdGVuY3lUeXBlW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXBpR2F0ZXdheU1vbml0b3JpbmdQcm9wc1xuICBleHRlbmRzIEFwaUdhdGV3YXlNZXRyaWNGYWN0b3J5UHJvcHMsXG4gICAgQXBpR2F0ZXdheU1vbml0b3JpbmdPcHRpb25zIHt9XG5cbmV4cG9ydCBjbGFzcyBBcGlHYXRld2F5TW9uaXRvcmluZyBleHRlbmRzIE1vbml0b3Jpbmcge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYWxhcm1GYWN0b3J5OiBBbGFybUZhY3Rvcnk7XG4gIHByb3RlY3RlZCByZWFkb25seSBlcnJvckFsYXJtRmFjdG9yeTogRXJyb3JBbGFybUZhY3Rvcnk7XG4gIHByb3RlY3RlZCByZWFkb25seSB0cHNBbGFybUZhY3Rvcnk6IFRwc0FsYXJtRmFjdG9yeTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGxhdGVuY3lBbGFybUZhY3Rvcnk6IExhdGVuY3lBbGFybUZhY3Rvcnk7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHRwc0Fubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbGF0ZW5jeUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZXJyb3JDb3VudEFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZXJyb3JSYXRlQW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHRwc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGVycm9yNFhYQ291bnRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHByb3RlY3RlZCByZWFkb25seSBlcnJvcjRYWFJhdGVNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHByb3RlY3RlZCByZWFkb25seSBmYXVsdDVYWENvdW50TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZmF1bHQ1WFhSYXRlTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuXG4gIC8vIGtleXMgYXJlIExhdGVuY3lUeXBlLCBidXQgSlNJSSBkb2Vzbid0IGxpa2Ugbm9uLXN0cmluZyB0eXBlc1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbGF0ZW5jeU1ldHJpY3M6IFJlY29yZDxzdHJpbmcsIE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ+O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbGF0ZW5jeVR5cGVzVG9SZW5kZXI6IHN0cmluZ1tdO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBNb25pdG9yaW5nU2NvcGUsIHByb3BzOiBBcGlHYXRld2F5TW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIHByb3BzKTtcblxuICAgIC8vIHVzZWQgd2hlbiBodW1hblJlYWRhYmxlTmFtZSBpcyBub3QgcHJvdmlkZWQgYnkgdXNlclxuICAgIGNvbnN0IGZhbGxiYWNrTmFtZUFycmF5ID0gW3Byb3BzLmFwaS5yZXN0QXBpTmFtZV07XG4gICAgZmFsbGJhY2tOYW1lQXJyYXkucHVzaChwcm9wcy5hcGlTdGFnZSA/PyBcInByb2RcIik7XG4gICAgaWYgKHByb3BzLmFwaU1ldGhvZCkge1xuICAgICAgZmFsbGJhY2tOYW1lQXJyYXkucHVzaChwcm9wcy5hcGlNZXRob2QpO1xuICAgIH1cbiAgICBpZiAocHJvcHMuYXBpUmVzb3VyY2UpIHtcbiAgICAgIGZhbGxiYWNrTmFtZUFycmF5LnB1c2gocHJvcHMuYXBpUmVzb3VyY2UpO1xuICAgIH1cblxuICAgIGNvbnN0IG5hbWluZ1N0cmF0ZWd5ID0gbmV3IE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSh7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIG5hbWVkQ29uc3RydWN0OiBwcm9wcy5hcGksXG4gICAgICBmYWxsYmFja0NvbnN0cnVjdE5hbWU6IGZhbGxiYWNrTmFtZUFycmF5XG4gICAgICAgIC5qb2luKFwiLVwiKVxuICAgICAgICAucmVwbGFjZSgvW15hLXpBLVowLTktX10vZywgXCJcIiksXG4gICAgICBodW1hblJlYWRhYmxlTmFtZTogcHJvcHMuaHVtYW5SZWFkYWJsZU5hbWUgPz8gZmFsbGJhY2tOYW1lQXJyYXkuam9pbihcIiBcIiksXG4gICAgfSk7XG5cbiAgICB0aGlzLnRpdGxlID0gbmFtaW5nU3RyYXRlZ3kucmVzb2x2ZUh1bWFuUmVhZGFibGVOYW1lKCk7XG5cbiAgICB0aGlzLmFsYXJtRmFjdG9yeSA9IHRoaXMuY3JlYXRlQWxhcm1GYWN0b3J5KFxuICAgICAgbmFtaW5nU3RyYXRlZ3kucmVzb2x2ZUFsYXJtRnJpZW5kbHlOYW1lKClcbiAgICApO1xuICAgIHRoaXMuZXJyb3JBbGFybUZhY3RvcnkgPSBuZXcgRXJyb3JBbGFybUZhY3RvcnkodGhpcy5hbGFybUZhY3RvcnkpO1xuICAgIHRoaXMudHBzQWxhcm1GYWN0b3J5ID0gbmV3IFRwc0FsYXJtRmFjdG9yeSh0aGlzLmFsYXJtRmFjdG9yeSk7XG4gICAgdGhpcy5sYXRlbmN5QWxhcm1GYWN0b3J5ID0gbmV3IExhdGVuY3lBbGFybUZhY3RvcnkodGhpcy5hbGFybUZhY3RvcnkpO1xuXG4gICAgdGhpcy50cHNBbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMubGF0ZW5jeUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5lcnJvckNvdW50QW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmVycm9yUmF0ZUFubm90YXRpb25zID0gW107XG5cbiAgICBjb25zdCBtZXRyaWNGYWN0b3J5ID0gbmV3IEFwaUdhdGV3YXlNZXRyaWNGYWN0b3J5KFxuICAgICAgc2NvcGUuY3JlYXRlTWV0cmljRmFjdG9yeSgpLFxuICAgICAgcHJvcHNcbiAgICApO1xuXG4gICAgdGhpcy50cHNNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY1RwcygpO1xuXG4gICAgdGhpcy5sYXRlbmN5TWV0cmljcyA9IHt9O1xuICAgIHRoaXMubGF0ZW5jeVR5cGVzVG9SZW5kZXIgPSBbXG4gICAgICAuLi4ocHJvcHMubGF0ZW5jeVR5cGVzVG9SZW5kZXIgPz8gRGVmYXVsdExhdGVuY3lUeXBlc1RvUmVuZGVyKSxcbiAgICBdO1xuXG4gICAgdGhpcy5lcnJvcjRYWENvdW50TWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWM0WFhFcnJvckNvdW50KCk7XG4gICAgdGhpcy5lcnJvcjRYWFJhdGVNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpYzRYWEVycm9yUmF0ZSgpO1xuICAgIHRoaXMuZmF1bHQ1WFhDb3VudE1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljNVhYRmF1bHRDb3VudCgpO1xuICAgIHRoaXMuZmF1bHQ1WFhSYXRlTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWM1WFhGYXVsdFJhdGUoKTtcblxuICAgIGNvbnN0IGxhdGVuY3lBbGFybURlZmluaXRpb25zID0ge1xuICAgICAgW0xhdGVuY3lUeXBlLlA1MF06IHByb3BzLmFkZExhdGVuY3lQNTBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QNzBdOiBwcm9wcy5hZGRMYXRlbmN5UDcwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDkwXTogcHJvcHMuYWRkTGF0ZW5jeVA5MEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5NV06IHByb3BzLmFkZExhdGVuY3lQOTVBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTldOiBwcm9wcy5hZGRMYXRlbmN5UDk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5OV06IHByb3BzLmFkZExhdGVuY3lQOTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5OTldOiBwcm9wcy5hZGRMYXRlbmN5UDk5OTlBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QMTAwXTogcHJvcHMuYWRkTGF0ZW5jeVAxMDBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5UTTUwXTogcHJvcHMuYWRkTGF0ZW5jeVRNNTBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5UTTcwXTogcHJvcHMuYWRkTGF0ZW5jeVRNNzBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5UTTkwXTogcHJvcHMuYWRkTGF0ZW5jeVRNOTBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5UTTk1XTogcHJvcHMuYWRkTGF0ZW5jeVRNOTVBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5UTTk5XTogcHJvcHMuYWRkTGF0ZW5jeVRNOTlBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5UTTk5OV06IHByb3BzLmFkZExhdGVuY3lUTTk5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlRNOTk5OV06IHByb3BzLmFkZExhdGVuY3lUTTk5OTlBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5BVkVSQUdFXTogcHJvcHMuYWRkTGF0ZW5jeUF2ZXJhZ2VBbGFybSxcbiAgICB9O1xuXG4gICAgT2JqZWN0LnZhbHVlcyhMYXRlbmN5VHlwZSkuZm9yRWFjaCgobGF0ZW5jeVR5cGUpID0+IHtcbiAgICAgIHRoaXMubGF0ZW5jeU1ldHJpY3NbbGF0ZW5jeVR5cGVdID1cbiAgICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNMYXRlbmN5SW5NaWxsaXMobGF0ZW5jeVR5cGUpO1xuICAgIH0pO1xuXG4gICAgZm9yIChjb25zdCBbbGF0ZW5jeVR5cGUsIGFsYXJtRGVmaW5pdGlvbl0gb2YgT2JqZWN0LmVudHJpZXMoXG4gICAgICBsYXRlbmN5QWxhcm1EZWZpbml0aW9uc1xuICAgICkpIHtcbiAgICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBhbGFybURlZmluaXRpb24pIHtcbiAgICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IGFsYXJtRGVmaW5pdGlvbltkaXNhbWJpZ3VhdG9yXTtcbiAgICAgICAgY29uc3QgbGF0ZW5jeVR5cGVFbnVtID0gbGF0ZW5jeVR5cGUgYXMgTGF0ZW5jeVR5cGU7XG4gICAgICAgIGNvbnN0IG1ldHJpYyA9IHRoaXMubGF0ZW5jeU1ldHJpY3NbbGF0ZW5jeVR5cGVFbnVtXTtcbiAgICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5sYXRlbmN5QWxhcm1GYWN0b3J5LmFkZExhdGVuY3lBbGFybShcbiAgICAgICAgICBtZXRyaWMsXG4gICAgICAgICAgbGF0ZW5jeVR5cGVFbnVtLFxuICAgICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgICAgZGlzYW1iaWd1YXRvclxuICAgICAgICApO1xuICAgICAgICB0aGlzLmxhdGVuY3lBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgICAgdGhpcy5sYXRlbmN5VHlwZXNUb1JlbmRlci5wdXNoKGxhdGVuY3lUeXBlRW51bSk7XG4gICAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkNVhYRmF1bHRDb3VudEFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkNVhYRmF1bHRDb3VudEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5lcnJvckFsYXJtRmFjdG9yeS5hZGRFcnJvckNvdW50QWxhcm0oXG4gICAgICAgIHRoaXMuZmF1bHQ1WFhDb3VudE1ldHJpYyxcbiAgICAgICAgRXJyb3JUeXBlLkZBVUxULFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICApO1xuICAgICAgdGhpcy5lcnJvckNvdW50QW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGQ0WFhFcnJvckNvdW50QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGQ0WFhFcnJvckNvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmVycm9yQWxhcm1GYWN0b3J5LmFkZEVycm9yQ291bnRBbGFybShcbiAgICAgICAgdGhpcy5lcnJvcjRYWENvdW50TWV0cmljLFxuICAgICAgICBFcnJvclR5cGUuRVJST1IsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3JcbiAgICAgICk7XG4gICAgICB0aGlzLmVycm9yQ291bnRBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZDRYWEVycm9yUmF0ZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkNFhYRXJyb3JSYXRlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmVycm9yQWxhcm1GYWN0b3J5LmFkZEVycm9yUmF0ZUFsYXJtKFxuICAgICAgICB0aGlzLmVycm9yNFhYUmF0ZU1ldHJpYyxcbiAgICAgICAgRXJyb3JUeXBlLkVSUk9SLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICApO1xuICAgICAgdGhpcy5lcnJvclJhdGVBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZDVYWEZhdWx0UmF0ZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkNVhYRmF1bHRSYXRlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmVycm9yQWxhcm1GYWN0b3J5LmFkZEVycm9yUmF0ZUFsYXJtKFxuICAgICAgICB0aGlzLmZhdWx0NVhYUmF0ZU1ldHJpYyxcbiAgICAgICAgRXJyb3JUeXBlLkZBVUxULFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICApO1xuICAgICAgdGhpcy5lcnJvclJhdGVBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZExvd1Rwc0FsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkTG93VHBzQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLnRwc0FsYXJtRmFjdG9yeS5hZGRNaW5UcHNBbGFybShcbiAgICAgICAgdGhpcy50cHNNZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3JcbiAgICAgICk7XG4gICAgICB0aGlzLnRwc0Fubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkSGlnaFRwc0FsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkSGlnaFRwc0FsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy50cHNBbGFybUZhY3RvcnkuYWRkTWF4VHBzQWxhcm0oXG4gICAgICAgIHRoaXMudHBzTWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICApO1xuICAgICAgdGhpcy50cHNBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG4gICAgcHJvcHMudXNlQ3JlYXRlZEFsYXJtcz8uY29uc3VtZSh0aGlzLmNyZWF0ZWRBbGFybXMoKSk7XG4gIH1cblxuICBzdW1tYXJ5V2lkZ2V0cygpOiBJV2lkZ2V0W10ge1xuICAgIHJldHVybiBbXG4gICAgICB0aGlzLmNyZWF0ZVRpdGxlV2lkZ2V0KCksXG4gICAgICB0aGlzLmNyZWF0ZVRwc1dpZGdldChUaGlyZFdpZHRoLCBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCksXG4gICAgICB0aGlzLmNyZWF0ZUxhdGVuY3lXaWRnZXQoVGhpcmRXaWR0aCwgRGVmYXVsdFN1bW1hcnlXaWRnZXRIZWlnaHQpLFxuICAgICAgdGhpcy5jcmVhdGVFcnJvclJhdGVXaWRnZXQoVGhpcmRXaWR0aCwgRGVmYXVsdFN1bW1hcnlXaWRnZXRIZWlnaHQpLFxuICAgIF07XG4gIH1cblxuICB3aWRnZXRzKCk6IElXaWRnZXRbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMuY3JlYXRlVGl0bGVXaWRnZXQoKSxcbiAgICAgIHRoaXMuY3JlYXRlVHBzV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgIHRoaXMuY3JlYXRlTGF0ZW5jeVdpZGdldChRdWFydGVyV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICB0aGlzLmNyZWF0ZUVycm9yQ291bnRXaWRnZXQoUXVhcnRlcldpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgdGhpcy5jcmVhdGVFcnJvclJhdGVXaWRnZXQoUXVhcnRlcldpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgIF07XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlVGl0bGVXaWRnZXQoKSB7XG4gICAgcmV0dXJuIG5ldyBNb25pdG9yaW5nSGVhZGVyV2lkZ2V0KHtcbiAgICAgIGZhbWlseTogXCJBUEkgR2F0ZXdheSBFbmRwb2ludFwiLFxuICAgICAgdGl0bGU6IHRoaXMudGl0bGUsXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlVHBzV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIlRQU1wiLFxuICAgICAgbGVmdDogW3RoaXMudHBzTWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMudHBzQW5ub3RhdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlTGF0ZW5jeVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIGNvbnN0IGxlZnQgPSBBcnJheS5mcm9tKG5ldyBTZXQodGhpcy5sYXRlbmN5VHlwZXNUb1JlbmRlcikpXG4gICAgICAuc29ydCgpXG4gICAgICAubWFwKCh0eXBlKSA9PiB0aGlzLmxhdGVuY3lNZXRyaWNzW3R5cGVdKTtcblxuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJMYXRlbmN5XCIsXG4gICAgICBsZWZ0LFxuICAgICAgbGVmdFlBeGlzOiBUaW1lQXhpc01pbGxpc0Zyb21aZXJvLFxuICAgICAgbGVmdEFubm90YXRpb25zOiB0aGlzLmxhdGVuY3lBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjcmVhdGVFcnJvckNvdW50V2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkVycm9yc1wiLFxuICAgICAgbGVmdDogW3RoaXMuZXJyb3I0WFhDb3VudE1ldHJpYywgdGhpcy5mYXVsdDVYWENvdW50TWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMuZXJyb3JDb3VudEFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZUVycm9yUmF0ZVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJFcnJvcnMgKHJhdGUpXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5lcnJvcjRYWFJhdGVNZXRyaWMsIHRoaXMuZmF1bHQ1WFhSYXRlTWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogUmF0ZUF4aXNGcm9tWmVybyxcbiAgICAgIGxlZnRBbm5vdGF0aW9uczogdGhpcy5lcnJvclJhdGVBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxufVxuIl19