cdk-monitoring-constructs
Version:
[](https://badge.fury.io/js/cdk-monitoring-constructs) [](https://m
336 lines • 61 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenSearchClusterMonitoring = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
const OpenSearchClusterMetricFactory_1 = require("./OpenSearchClusterMetricFactory");
const common_1 = require("../../common");
const dashboard_1 = require("../../dashboard");
class OpenSearchClusterMonitoring extends common_1.Monitoring {
constructor(scope, props) {
super(scope, props);
const namingStrategy = new dashboard_1.MonitoringNamingStrategy({
...props,
namedConstruct: props.domain,
});
this.title = namingStrategy.resolveHumanReadableName();
this.url = props.domain.domainName
? scope
.createAwsConsoleUrlFactory()
.getOpenSearchClusterUrl(props.domain.domainName)
: undefined;
const alarmPrefix = namingStrategy.resolveAlarmFriendlyName();
const indexingAlarmPrefix = `${alarmPrefix}-Indexing`;
const searchAlarmPrefix = `${alarmPrefix}-Search`;
const clusterAlarmPrefix = `${alarmPrefix}-Cluster`;
this.indexingLatencyAlarmFactory = new common_1.LatencyAlarmFactory(this.createAlarmFactory(indexingAlarmPrefix));
this.indexingLatencyAnnotations = [];
this.searchLatencyAlarmFactory = new common_1.LatencyAlarmFactory(this.createAlarmFactory(searchAlarmPrefix));
this.searchLatencyAnnotations = [];
this.clusterAlarmFactory = new common_1.OpenSearchClusterAlarmFactory(this.createAlarmFactory(clusterAlarmPrefix));
this.clusterAnnotations = [];
this.nodeAnnotations = [];
this.usageAlarmFactory = new common_1.UsageAlarmFactory(this.createAlarmFactory(alarmPrefix));
this.usageAnnotations = [];
this.masterUsageAnnotations = [];
const metricFactory = new OpenSearchClusterMetricFactory_1.OpenSearchClusterMetricFactory(scope.createMetricFactory(), props);
this.tpsMetric = metricFactory.metricSearchRate(common_1.RateComputationMethod.PER_SECOND);
this.p50IndexingLatencyMetric =
metricFactory.metricIndexingLatencyP50InMillis();
this.p90IndexingLatencyMetric =
metricFactory.metricIndexingLatencyP90InMillis();
this.p99IndexingLatencyMetric =
metricFactory.metricIndexingLatencyP99InMillis();
this.p50SearchLatencyMetric =
metricFactory.metricSearchLatencyP50InMillis();
this.p90SearchLatencyMetric =
metricFactory.metricSearchLatencyP90InMillis();
this.p99SearchLatencyMetric =
metricFactory.metricSearchLatencyP99InMillis();
this.clusterStatusRedMetric = metricFactory.metricClusterStatusRed();
this.clusterStatusYellowMetric = metricFactory.metricClusterStatusYellow();
this.diskSpaceUsageMetric = metricFactory.metricDiskSpaceUsageInPercent();
this.cpuUsageMetric = metricFactory.metricCpuUsage();
this.masterCpuUsageMetric = metricFactory.metricMasterCpuUsage();
this.jvmMemoryPressureMetric = metricFactory.metricJvmMemoryPressure();
this.masterJvmMemoryPressureMetric =
metricFactory.metricMasterJvmMemoryPressure();
this.indexWriteBlockedMetric =
metricFactory.metricClusterIndexWritesBlocked();
this.nodesMetric = metricFactory.metricNodes();
this.automatedSnapshotFailureMetric =
metricFactory.metricAutomatedSnapshotFailure();
this.kmsKeyErrorMetric = metricFactory.metricKmsKeyError();
this.kmsKeyInaccessibleMetric = metricFactory.metricKmsKeyInaccessible();
for (const disambiguator in props.addIndexingLatencyP50Alarm) {
const alarmProps = props.addIndexingLatencyP50Alarm[disambiguator];
const createdAlarm = this.indexingLatencyAlarmFactory.addLatencyAlarm(this.p50IndexingLatencyMetric, common_1.LatencyType.P50, alarmProps, disambiguator);
this.indexingLatencyAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addIndexingLatencyP90Alarm) {
const alarmProps = props.addIndexingLatencyP90Alarm[disambiguator];
const createdAlarm = this.indexingLatencyAlarmFactory.addLatencyAlarm(this.p90IndexingLatencyMetric, common_1.LatencyType.P90, alarmProps, disambiguator);
this.indexingLatencyAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addIndexingLatencyP99Alarm) {
const alarmProps = props.addIndexingLatencyP99Alarm[disambiguator];
const createdAlarm = this.indexingLatencyAlarmFactory.addLatencyAlarm(this.p99IndexingLatencyMetric, common_1.LatencyType.P99, alarmProps, disambiguator);
this.indexingLatencyAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addSearchLatencyP50Alarm) {
const alarmProps = props.addSearchLatencyP50Alarm[disambiguator];
const createdAlarm = this.searchLatencyAlarmFactory.addLatencyAlarm(this.p50SearchLatencyMetric, common_1.LatencyType.P50, alarmProps, disambiguator);
this.searchLatencyAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addSearchLatencyP90Alarm) {
const alarmProps = props.addSearchLatencyP90Alarm[disambiguator];
const createdAlarm = this.searchLatencyAlarmFactory.addLatencyAlarm(this.p90SearchLatencyMetric, common_1.LatencyType.P90, alarmProps, disambiguator);
this.searchLatencyAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addSearchLatencyP99Alarm) {
const alarmProps = props.addSearchLatencyP99Alarm[disambiguator];
const createdAlarm = this.searchLatencyAlarmFactory.addLatencyAlarm(this.p99SearchLatencyMetric, common_1.LatencyType.P99, alarmProps, disambiguator);
this.searchLatencyAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addClusterStatusAlarm) {
const alarmProps = props.addClusterStatusAlarm[disambiguator];
let createdAlarm;
switch (alarmProps.status) {
case common_1.OpenSearchClusterStatus.RED:
createdAlarm = this.clusterAlarmFactory.addClusterStatusAlarm(this.clusterStatusRedMetric, alarmProps, disambiguator);
break;
case common_1.OpenSearchClusterStatus.YELLOW:
createdAlarm = this.clusterAlarmFactory.addClusterStatusAlarm(this.clusterStatusYellowMetric, alarmProps, disambiguator);
break;
default:
throw new Error(`Unknown cluster status: ${alarmProps.status}`);
}
this.addAlarm(createdAlarm);
}
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.addCpuSpaceUsageAlarm) {
const alarmProps = props.addCpuSpaceUsageAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxCpuUsagePercentAlarm(this.cpuUsageMetric, alarmProps, disambiguator);
this.usageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addMasterCpuSpaceUsageAlarm) {
const alarmProps = props.addMasterCpuSpaceUsageAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxMasterCpuUsagePercentAlarm(this.masterCpuUsageMetric, alarmProps, disambiguator);
this.masterUsageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addJvmMemoryPressureAlarm) {
const alarmProps = props.addJvmMemoryPressureAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxMemoryUsagePercentAlarm(this.jvmMemoryPressureMetric, alarmProps, disambiguator);
this.usageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addMasterJvmMemoryPressureAlarm) {
const alarmProps = props.addMasterJvmMemoryPressureAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxMasterMemoryUsagePercentAlarm(this.masterJvmMemoryPressureMetric, alarmProps, disambiguator);
this.masterUsageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addClusterNodeCountAlarm) {
const alarmProps = props.addClusterNodeCountAlarm[disambiguator];
const createdAlarm = this.clusterAlarmFactory.addClusterNodeCountAlarm(this.nodesMetric, alarmProps, disambiguator);
this.nodeAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addClusterIndexWritesBlockedAlarm) {
const alarmProps = props.addClusterIndexWritesBlockedAlarm[disambiguator];
const createdAlarm = this.clusterAlarmFactory.addClusterIndexWritesBlockedAlarm(this.indexWriteBlockedMetric, alarmProps, disambiguator);
this.clusterAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addClusterAutomatedSnapshotFailureAlarm) {
const alarmProps = props.addClusterAutomatedSnapshotFailureAlarm[disambiguator];
const createdAlarm = this.clusterAlarmFactory.addAutomatedSnapshotFailureAlarm(this.automatedSnapshotFailureMetric, alarmProps, disambiguator);
this.clusterAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addKmsKeyErrorAlarm) {
const alarmProps = props.addKmsKeyErrorAlarm[disambiguator];
const createdAlarm = this.clusterAlarmFactory.addKmsKeyErrorAlarm(this.kmsKeyErrorMetric, alarmProps, disambiguator);
this.clusterAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addKmsKeyInaccessibleAlarm) {
const alarmProps = props.addKmsKeyInaccessibleAlarm[disambiguator];
const createdAlarm = this.clusterAlarmFactory.addKmsKeyInaccessibleAlarm(this.kmsKeyInaccessibleMetric, alarmProps, disambiguator);
this.clusterAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
props.useCreatedAlarms?.consume(this.createdAlarms());
}
summaryWidgets() {
// TODO: separate into individual widget methods
return [
// Title
new dashboard_1.MonitoringHeaderWidget({
family: "Elasticsearch Domain",
title: this.title,
goToLinkUrl: this.url,
}),
// Requests (TPS)
new aws_cloudwatch_1.GraphWidget({
width: common_1.QuarterWidth,
height: common_1.DefaultSummaryWidgetHeight,
title: "TPS",
left: [this.tpsMetric],
leftYAxis: common_1.RateAxisFromZero,
}),
// Indexing latency
new aws_cloudwatch_1.GraphWidget({
width: common_1.QuarterWidth,
height: common_1.DefaultSummaryWidgetHeight,
title: "Indexing Latency",
left: [
this.p50IndexingLatencyMetric,
this.p90IndexingLatencyMetric,
this.p99IndexingLatencyMetric,
],
leftYAxis: common_1.TimeAxisMillisFromZero,
leftAnnotations: this.indexingLatencyAnnotations,
}),
// Search latency
new aws_cloudwatch_1.GraphWidget({
width: common_1.QuarterWidth,
height: common_1.DefaultSummaryWidgetHeight,
title: "Search Latency",
left: [
this.p50SearchLatencyMetric,
this.p90SearchLatencyMetric,
this.p99SearchLatencyMetric,
],
leftYAxis: common_1.TimeAxisMillisFromZero,
leftAnnotations: this.searchLatencyAnnotations,
}),
// CPU, memory, and disk usage
new aws_cloudwatch_1.GraphWidget({
width: common_1.QuarterWidth,
height: common_1.DefaultSummaryWidgetHeight,
title: "CPU/Memory/Disk Usage",
left: [
this.cpuUsageMetric,
this.masterCpuUsageMetric,
this.jvmMemoryPressureMetric,
this.masterJvmMemoryPressureMetric,
this.diskSpaceUsageMetric,
],
leftYAxis: common_1.PercentageAxisFromZeroToHundred,
leftAnnotations: [
...this.usageAnnotations,
...this.masterUsageAnnotations,
],
}),
];
}
widgets() {
// TODO: separate into individual widget methods
return [
// Title
new dashboard_1.MonitoringHeaderWidget({
family: "Elasticsearch Domain",
title: this.title,
goToLinkUrl: this.url,
}),
new aws_cloudwatch_1.Row(
// Requests (TPS)
new aws_cloudwatch_1.GraphWidget({
width: common_1.QuarterWidth,
height: common_1.DefaultGraphWidgetHeight,
title: "TPS",
left: [this.tpsMetric],
leftYAxis: common_1.RateAxisFromZero,
}),
// Indexing latency
new aws_cloudwatch_1.GraphWidget({
width: common_1.QuarterWidth,
height: common_1.DefaultGraphWidgetHeight,
title: "Indexing Latency",
left: [
this.p50IndexingLatencyMetric,
this.p90IndexingLatencyMetric,
this.p99IndexingLatencyMetric,
],
leftAnnotations: this.indexingLatencyAnnotations,
}),
// Search latency
new aws_cloudwatch_1.GraphWidget({
width: common_1.QuarterWidth,
height: common_1.DefaultGraphWidgetHeight,
title: "Search Latency",
left: [
this.p50SearchLatencyMetric,
this.p90SearchLatencyMetric,
this.p99SearchLatencyMetric,
],
leftAnnotations: this.searchLatencyAnnotations,
}),
// Node count
new aws_cloudwatch_1.GraphWidget({
width: common_1.QuarterWidth,
height: common_1.DefaultGraphWidgetHeight,
title: "Node Count",
left: [this.nodesMetric],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.nodeAnnotations,
})),
new aws_cloudwatch_1.Row(
// CPU, memory, and disk usage
new aws_cloudwatch_1.GraphWidget({
width: common_1.ThirdWidth,
height: common_1.DefaultGraphWidgetHeight,
title: "CPU/Memory/Disk Usage",
left: [
this.cpuUsageMetric,
this.jvmMemoryPressureMetric,
this.diskSpaceUsageMetric,
],
leftYAxis: common_1.PercentageAxisFromZeroToHundred,
leftAnnotations: this.usageAnnotations,
}),
// Master CPU and memory
new aws_cloudwatch_1.GraphWidget({
width: common_1.ThirdWidth,
height: common_1.DefaultGraphWidgetHeight,
title: "Master CPU/Memory Usage",
left: [this.masterCpuUsageMetric, this.masterJvmMemoryPressureMetric],
leftYAxis: common_1.PercentageAxisFromZeroToHundred,
leftAnnotations: this.masterUsageAnnotations,
}),
// Index/Snapshot/KMS Errors
new aws_cloudwatch_1.GraphWidget({
width: common_1.ThirdWidth,
height: common_1.DefaultGraphWidgetHeight,
title: "Index/Snapshot/KMS Errors",
left: [
this.indexWriteBlockedMetric,
this.automatedSnapshotFailureMetric,
this.kmsKeyErrorMetric,
this.kmsKeyInaccessibleMetric,
],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.clusterAnnotations,
})),
];
}
}
exports.OpenSearchClusterMonitoring = OpenSearchClusterMonitoring;
_a = JSII_RTTI_SYMBOL_1;
OpenSearchClusterMonitoring[_a] = { fqn: "cdk-monitoring-constructs.OpenSearchClusterMonitoring", version: "9.15.2" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT3BlblNlYXJjaENsdXN0ZXJNb25pdG9yaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiT3BlblNlYXJjaENsdXN0ZXJNb25pdG9yaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0RBS29DO0FBRXBDLHFGQUcwQztBQUMxQyx5Q0EyQnNCO0FBQ3RCLCtDQUd5QjtBQTZDekIsTUFBYSwyQkFBNEIsU0FBUSxtQkFBVTtJQXNDekQsWUFBWSxLQUFzQixFQUFFLEtBQXVDO1FBQ3pFLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFcEIsTUFBTSxjQUFjLEdBQUcsSUFBSSxvQ0FBd0IsQ0FBQztZQUNsRCxHQUFHLEtBQUs7WUFDUixjQUFjLEVBQUUsS0FBSyxDQUFDLE1BQU07U0FDN0IsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLEtBQUssR0FBRyxjQUFjLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztRQUN2RCxJQUFJLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBVTtZQUNoQyxDQUFDLENBQUMsS0FBSztpQkFDRiwwQkFBMEIsRUFBRTtpQkFDNUIsdUJBQXVCLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7WUFDckQsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUVkLE1BQU0sV0FBVyxHQUFHLGNBQWMsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQzlELE1BQU0sbUJBQW1CLEdBQUcsR0FBRyxXQUFXLFdBQVcsQ0FBQztRQUN0RCxNQUFNLGlCQUFpQixHQUFHLEdBQUcsV0FBVyxTQUFTLENBQUM7UUFDbEQsTUFBTSxrQkFBa0IsR0FBRyxHQUFHLFdBQVcsVUFBVSxDQUFDO1FBRXBELElBQUksQ0FBQywyQkFBMkIsR0FBRyxJQUFJLDRCQUFtQixDQUN4RCxJQUFJLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsQ0FDN0MsQ0FBQztRQUNGLElBQUksQ0FBQywwQkFBMEIs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QUFFO29CQUNKLElBQUksQ0FBQyxjQUFjO29CQUNuQixJQUFJLENBQUMsdUJBQXVCO29CQUM1QixJQUFJLENBQUMsb0JBQW9CO2lCQUMxQjtnQkFDRCxTQUFTLEVBQUUsd0NBQStCO2dCQUMxQyxlQUFlLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjthQUN2QyxDQUFDO1lBQ0Ysd0JBQXdCO1lBQ3hCLElBQUksNEJBQVcsQ0FBQztnQkFDZCxLQUFLLEVBQUUsbUJBQVU7Z0JBQ2pCLE1BQU0sRUFBRSxpQ0FBd0I7Z0JBQ2hDLEtBQUssRUFBRSx5QkFBeUI7Z0JBQ2hDLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsNkJBQTZCLENBQUM7Z0JBQ3JFLFNBQVMsRUFBRSx3Q0FBK0I7Z0JBQzFDLGVBQWUsRUFBRSxJQUFJLENBQUMsc0JBQXNCO2FBQzdDLENBQUM7WUFDRiw0QkFBNEI7WUFDNUIsSUFBSSw0QkFBVyxDQUFDO2dCQUNkLEtBQUssRUFBRSxtQkFBVTtnQkFDakIsTUFBTSxFQUFFLGlDQUF3QjtnQkFDaEMsS0FBSyxFQUFFLDJCQUEyQjtnQkFDbEMsSUFBSSxFQUFFO29CQUNKLElBQUksQ0FBQyx1QkFBdUI7b0JBQzVCLElBQUksQ0FBQyw4QkFBOEI7b0JBQ25DLElBQUksQ0FBQyxpQkFBaUI7b0JBQ3RCLElBQUksQ0FBQyx3QkFBd0I7aUJBQzlCO2dCQUNELFNBQVMsRUFBRSwwQkFBaUI7Z0JBQzVCLGVBQWUsRUFBRSxJQUFJLENBQUMsa0JBQWtCO2FBQ3pDLENBQUMsQ0FDSDtTQUNGLENBQUM7SUFDSixDQUFDOztBQWhkSCxrRUFpZEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFdpZGdldCxcbiAgSG9yaXpvbnRhbEFubm90YXRpb24sXG4gIElXaWRnZXQsXG4gIFJvdyxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoXCI7XG5cbmltcG9ydCB7XG4gIE9wZW5TZWFyY2hDbHVzdGVyTWV0cmljRmFjdG9yeSxcbiAgT3BlblNlYXJjaENsdXN0ZXJNZXRyaWNGYWN0b3J5UHJvcHMsXG59IGZyb20gXCIuL09wZW5TZWFyY2hDbHVzdGVyTWV0cmljRmFjdG9yeVwiO1xuaW1wb3J0IHtcbiAgQmFzZU1vbml0b3JpbmdQcm9wcyxcbiAgQ291bnRBeGlzRnJvbVplcm8sXG4gIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCxcbiAgRGVmYXVsdFN1bW1hcnlXaWRnZXRIZWlnaHQsXG4gIExhdGVuY3lBbGFybUZhY3RvcnksXG4gIExhdGVuY3lUaHJlc2hvbGQsXG4gIExhdGVuY3lUeXBlLFxuICBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0LFxuICBNb25pdG9yaW5nLFxuICBNb25pdG9yaW5nU2NvcGUsXG4gIE9wZW5TZWFyY2hDbHVzdGVyQWxhcm1GYWN0b3J5LFxuICBPcGVuU2VhcmNoQ2x1c3RlckF1dG9tYXRlZFNuYXBzaG90RmFpbHVyZVRocmVzaG9sZCxcbiAgT3BlblNlYXJjaENsdXN0ZXJJbmRleFdyaXRlc0Jsb2NrZWRUaHJlc2hvbGQsXG4gIE9wZW5TZWFyY2hDbHVzdGVyTm9kZXNUaHJlc2hvbGQsXG4gIE9wZW5TZWFyY2hDbHVzdGVyU3RhdHVzLFxuICBPcGVuU2VhcmNoQ2x1c3RlclN0YXR1c0N1c3RvbWl6YXRpb24sXG4gIE9wZW5TZWFyY2hLbXNLZXlFcnJvclRocmVzaG9sZCxcbiAgT3BlblNlYXJjaEttc0tleUluYWNjZXNzaWJsZVRocmVzaG9sZCxcbiAgUGVyY2VudGFnZUF4aXNGcm9tWmVyb1RvSHVuZHJlZCxcbiAgUXVhcnRlcldpZHRoLFxuICBSYXRlQXhpc0Zyb21aZXJvLFxuICBSYXRlQ29tcHV0YXRpb25NZXRob2QsXG4gIFRoaXJkV2lkdGgsXG4gIFRpbWVBeGlzTWlsbGlzRnJvbVplcm8sXG4gIFVzYWdlQWxhcm1GYWN0b3J5LFxuICBVc2FnZVRocmVzaG9sZCxcbn0gZnJvbSBcIi4uLy4uL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgTW9uaXRvcmluZ0hlYWRlcldpZGdldCxcbiAgTW9uaXRvcmluZ05hbWluZ1N0cmF0ZWd5LFxufSBmcm9tIFwiLi4vLi4vZGFzaGJvYXJkXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlblNlYXJjaENsdXN0ZXJNb25pdG9yaW5nT3B0aW9uc1xuICBleHRlbmRzIEJhc2VNb25pdG9yaW5nUHJvcHMge1xuICByZWFkb25seSBhZGRJbmRleGluZ0xhdGVuY3lQNTBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbmRleGluZ0xhdGVuY3lQOTBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbmRleGluZ0xhdGVuY3lQOTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRTZWFyY2hMYXRlbmN5UDUwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkU2VhcmNoTGF0ZW5jeVA5MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFNlYXJjaExhdGVuY3lQOTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuXG4gIHJlYWRvbmx5IGFkZENsdXN0ZXJTdGF0dXNBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgT3BlblNlYXJjaENsdXN0ZXJTdGF0dXNDdXN0b21pemF0aW9uXG4gID47XG4gIHJlYWRvbmx5IGFkZERpc2tTcGFjZVVzYWdlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBVc2FnZVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZENwdVNwYWNlVXNhZ2VBbGFybT86IFJlY29yZDxzdHJpbmcsIFVzYWdlVGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkTWFzdGVyQ3B1U3BhY2VVc2FnZUFsYXJtPzogUmVjb3JkPHN0cmluZywgVXNhZ2VUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRKdm1NZW1vcnlQcmVzc3VyZUFsYXJtPzogUmVjb3JkPHN0cmluZywgVXNhZ2VUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRNYXN0ZXJKdm1NZW1vcnlQcmVzc3VyZUFsYXJtPzogUmVjb3JkPHN0cmluZywgVXNhZ2VUaHJlc2hvbGQ+O1xuXG4gIHJlYWRvbmx5IGFkZENsdXN0ZXJJbmRleFdyaXRlc0Jsb2NrZWRBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgT3BlblNlYXJjaENsdXN0ZXJJbmRleFdyaXRlc0Jsb2NrZWRUaHJlc2hvbGRcbiAgPjtcbiAgcmVhZG9ubHkgYWRkQ2x1c3Rlck5vZGVDb3VudEFsYXJtPzogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBPcGVuU2VhcmNoQ2x1c3Rlck5vZGVzVGhyZXNob2xkXG4gID47XG4gIHJlYWRvbmx5IGFkZENsdXN0ZXJBdXRvbWF0ZWRTbmFwc2hvdEZhaWx1cmVBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgT3BlblNlYXJjaENsdXN0ZXJBdXRvbWF0ZWRTbmFwc2hvdEZhaWx1cmVUaHJlc2hvbGRcbiAgPjtcblxuICByZWFkb25seSBhZGRLbXNLZXlFcnJvckFsYXJtPzogUmVjb3JkPHN0cmluZywgT3BlblNlYXJjaEttc0tleUVycm9yVGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkS21zS2V5SW5hY2Nlc3NpYmxlQWxhcm0/OiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIE9wZW5TZWFyY2hLbXNLZXlJbmFjY2Vzc2libGVUaHJlc2hvbGRcbiAgPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcGVuU2VhcmNoQ2x1c3Rlck1vbml0b3JpbmdQcm9wc1xuICBleHRlbmRzIE9wZW5TZWFyY2hDbHVzdGVyTWV0cmljRmFjdG9yeVByb3BzLFxuICAgIE9wZW5TZWFyY2hDbHVzdGVyTW9uaXRvcmluZ09wdGlvbnMge31cblxuZXhwb3J0IGNsYXNzIE9wZW5TZWFyY2hDbHVzdGVyTW9uaXRvcmluZyBleHRlbmRzIE1vbml0b3Jpbmcge1xuICByZWFkb25seSB0aXRsZTogc3RyaW5nO1xuICByZWFkb25seSB1cmw/OiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkgaW5kZXhpbmdMYXRlbmN5QWxhcm1GYWN0b3J5OiBMYXRlbmN5QWxhcm1GYWN0b3J5O1xuICByZWFkb25seSBpbmRleGluZ0xhdGVuY3lBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgc2VhcmNoTGF0ZW5jeUFsYXJtRmFjdG9yeTogTGF0ZW5jeUFsYXJtRmFjdG9yeTtcbiAgcmVhZG9ubHkgc2VhcmNoTGF0ZW5jeUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICByZWFkb25seSBjbHVzdGVyQWxhcm1GYWN0b3J5OiBPcGVuU2VhcmNoQ2x1c3RlckFsYXJtRmFjdG9yeTtcbiAgcmVhZG9ubHkgY2x1c3RlckFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICByZWFkb25seSBub2RlQW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IHVzYWdlQWxhcm1GYWN0b3J5OiBVc2FnZUFsYXJtRmFjdG9yeTtcbiAgcmVhZG9ubHkgdXNhZ2VBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgbWFzdGVyVXNhZ2VBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcblxuICByZWFkb25seSB0cHNNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IHA1MEluZGV4aW5nTGF0ZW5jeU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgcDkwSW5kZXhpbmdMYXRlbmN5TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBwOTlJbmRleGluZ0xhdGVuY3lNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IHA1MFNlYXJjaExhdGVuY3lNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IHA5MFNlYXJjaExhdGVuY3lNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IHA5OVNlYXJjaExhdGVuY3lNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG5cbiAgcmVhZG9ubHkgY2x1c3RlclN0YXR1c1JlZE1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgY2x1c3RlclN0YXR1c1llbGxvd01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcblxuICByZWFkb25seSBkaXNrU3BhY2VVc2FnZU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgY3B1VXNhZ2VNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG1hc3RlckNwdVVzYWdlTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBqdm1NZW1vcnlQcmVzc3VyZU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbWFzdGVySnZtTWVtb3J5UHJlc3N1cmVNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG5cbiAgcmVhZG9ubHkgaW5kZXhXcml0ZUJsb2NrZWRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG5vZGVzTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBhdXRvbWF0ZWRTbmFwc2hvdEZhaWx1cmVNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGttc0tleUVycm9yTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBrbXNLZXlJbmFjY2Vzc2libGVNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IE1vbml0b3JpbmdTY29wZSwgcHJvcHM6IE9wZW5TZWFyY2hDbHVzdGVyTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIHByb3BzKTtcblxuICAgIGNvbnN0IG5hbWluZ1N0cmF0ZWd5ID0gbmV3IE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSh7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIG5hbWVkQ29uc3RydWN0OiBwcm9wcy5kb21haW4sXG4gICAgfSk7XG4gICAgdGhpcy50aXRsZSA9IG5hbWluZ1N0cmF0ZWd5LnJlc29sdmVIdW1hblJlYWRhYmxlTmFtZSgpO1xuICAgIHRoaXMudXJsID0gcHJvcHMuZG9tYWluLmRvbWFpbk5hbWVcbiAgICAgID8gc2NvcGVcbiAgICAgICAgICAuY3JlYXRlQXdzQ29uc29sZVVybEZhY3RvcnkoKVxuICAgICAgICAgIC5nZXRPcGVuU2VhcmNoQ2x1c3RlclVybChwcm9wcy5kb21haW4uZG9tYWluTmFtZSlcbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgYWxhcm1QcmVmaXggPSBuYW1pbmdTdHJhdGVneS5yZXNvbHZlQWxhcm1GcmllbmRseU5hbWUoKTtcbiAgICBjb25zdCBpbmRleGluZ0FsYXJtUHJlZml4ID0gYCR7YWxhcm1QcmVmaXh9LUluZGV4aW5nYDtcbiAgICBjb25zdCBzZWFyY2hBbGFybVByZWZpeCA9IGAke2FsYXJtUHJlZml4fS1TZWFyY2hgO1xuICAgIGNvbnN0IGNsdXN0ZXJBbGFybVByZWZpeCA9IGAke2FsYXJtUHJlZml4fS1DbHVzdGVyYDtcblxuICAgIHRoaXMuaW5kZXhpbmdMYXRlbmN5QWxhcm1GYWN0b3J5ID0gbmV3IExhdGVuY3lBbGFybUZhY3RvcnkoXG4gICAgICB0aGlzLmNyZWF0ZUFsYXJtRmFjdG9yeShpbmRleGluZ0FsYXJtUHJlZml4KSxcbiAgICApO1xuICAgIHRoaXMuaW5kZXhpbmdMYXRlbmN5QW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLnNlYXJjaExhdGVuY3lBbGFybUZhY3RvcnkgPSBuZXcgTGF0ZW5jeUFsYXJtRmFjdG9yeShcbiAgICAgIHRoaXMuY3JlYXRlQWxhcm1GYWN0b3J5KHNlYXJjaEFsYXJtUHJlZml4KSxcbiAgICApO1xuICAgIHRoaXMuc2VhcmNoTGF0ZW5jeUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5jbHVzdGVyQWxhcm1GYWN0b3J5ID0gbmV3IE9wZW5TZWFyY2hDbHVzdGVyQWxhcm1GYWN0b3J5KFxuICAgICAgdGhpcy5jcmVhdGVBbGFybUZhY3RvcnkoY2x1c3RlckFsYXJtUHJlZml4KSxcbiAgICApO1xuICAgIHRoaXMuY2x1c3RlckFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5ub2RlQW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLnVzYWdlQWxhcm1GYWN0b3J5ID0gbmV3IFVzYWdlQWxhcm1GYWN0b3J5KFxuICAgICAgdGhpcy5jcmVhdGVBbGFybUZhY3RvcnkoYWxhcm1QcmVmaXgpLFxuICAgICk7XG4gICAgdGhpcy51c2FnZUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5tYXN0ZXJVc2FnZUFubm90YXRpb25zID0gW107XG5cbiAgICBjb25zdCBtZXRyaWNGYWN0b3J5ID0gbmV3IE9wZW5TZWFyY2hDbHVzdGVyTWV0cmljRmFjdG9yeShcbiAgICAgIHNjb3BlLmNyZWF0ZU1ldHJpY0ZhY3RvcnkoKSxcbiAgICAgIHByb3BzLFxuICAgICk7XG4gICAgdGhpcy50cHNNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY1NlYXJjaFJhdGUoXG4gICAgICBSYXRlQ29tcHV0YXRpb25NZXRob2QuUEVSX1NFQ09ORCxcbiAgICApO1xuICAgIHRoaXMucDUwSW5kZXhpbmdMYXRlbmN5TWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljSW5kZXhpbmdMYXRlbmN5UDUwSW5NaWxsaXMoKTtcbiAgICB0aGlzLnA5MEluZGV4aW5nTGF0ZW5jeU1ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0luZGV4aW5nTGF0ZW5jeVA5MEluTWlsbGlzKCk7XG4gICAgdGhpcy5wOTlJbmRleGluZ0xhdGVuY3lNZXRyaWMgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNJbmRleGluZ0xhdGVuY3lQOTlJbk1pbGxpcygpO1xuICAgIHRoaXMucDUwU2VhcmNoTGF0ZW5jeU1ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY1NlYXJjaExhdGVuY3lQNTBJbk1pbGxpcygpO1xuICAgIHRoaXMucDkwU2VhcmNoTGF0ZW5jeU1ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY1NlYXJjaExhdGVuY3lQOTBJbk1pbGxpcygpO1xuICAgIHRoaXMucDk5U2VhcmNoTGF0ZW5jeU1ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY1NlYXJjaExhdGVuY3lQOTlJbk1pbGxpcygpO1xuICAgIHRoaXMuY2x1c3RlclN0YXR1c1JlZE1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljQ2x1c3RlclN0YXR1c1JlZCgpO1xuICAgIHRoaXMuY2x1c3RlclN0YXR1c1llbGxvd01ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljQ2x1c3RlclN0YXR1c1llbGxvdygpO1xuICAgIHRoaXMuZGlza1NwYWNlVXNhZ2VNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0Rpc2tTcGFjZVVzYWdlSW5QZXJjZW50KCk7XG4gICAgdGhpcy5jcHVVc2FnZU1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljQ3B1VXNhZ2UoKTtcbiAgICB0aGlzLm1hc3RlckNwdVVzYWdlTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNNYXN0ZXJDcHVVc2FnZSgpO1xuICAgIHRoaXMuanZtTWVtb3J5UHJlc3N1cmVNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0p2bU1lbW9yeVByZXNzdXJlKCk7XG4gICAgdGhpcy5tYXN0ZXJKdm1NZW1vcnlQcmVzc3VyZU1ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY01hc3Rlckp2bU1lbW9yeVByZXNzdXJlKCk7XG4gICAgdGhpcy5pbmRleFdyaXRlQmxvY2tlZE1ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0NsdXN0ZXJJbmRleFdyaXRlc0Jsb2NrZWQoKTtcbiAgICB0aGlzLm5vZGVzTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNOb2RlcygpO1xuICAgIHRoaXMuYXV0b21hdGVkU25hcHNob3RGYWlsdXJlTWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljQXV0b21hdGVkU25hcHNob3RGYWlsdXJlKCk7XG4gICAgdGhpcy5rbXNLZXlFcnJvck1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljS21zS2V5RXJyb3IoKTtcbiAgICB0aGlzLmttc0tleUluYWNjZXNzaWJsZU1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljS21zS2V5SW5hY2Nlc3NpYmxlKCk7XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkSW5kZXhpbmdMYXRlbmN5UDUwQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRJbmRleGluZ0xhdGVuY3lQNTBBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMuaW5kZXhpbmdMYXRlbmN5QWxhcm1GYWN0b3J5LmFkZExhdGVuY3lBbGFybShcbiAgICAgICAgdGhpcy5wNTBJbmRleGluZ0xhdGVuY3lNZXRyaWMsXG4gICAgICAgIExhdGVuY3lUeXBlLlA1MCxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmluZGV4aW5nTGF0ZW5jeUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkSW5kZXhpbmdMYXRlbmN5UDkwQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRJbmRleGluZ0xhdGVuY3lQOTBBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMuaW5kZXhpbmdMYXRlbmN5QWxhcm1GYWN0b3J5LmFkZExhdGVuY3lBbGFybShcbiAgICAgICAgdGhpcy5wOTBJbmRleGluZ0xhdGVuY3lNZXRyaWMsXG4gICAgICAgIExhdGVuY3lUeXBlLlA5MCxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmluZGV4aW5nTGF0ZW5jeUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkSW5kZXhpbmdMYXRlbmN5UDk5QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRJbmRleGluZ0xhdGVuY3lQOTlBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMuaW5kZXhpbmdMYXRlbmN5QWxhcm1GYWN0b3J5LmFkZExhdGVuY3lBbGFybShcbiAgICAgICAgdGhpcy5wOTlJbmRleGluZ0xhdGVuY3lNZXRyaWMsXG4gICAgICAgIExhdGVuY3lUeXBlLlA5OSxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmluZGV4aW5nTGF0ZW5jeUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkU2VhcmNoTGF0ZW5jeVA1MEFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkU2VhcmNoTGF0ZW5jeVA1MEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5zZWFyY2hMYXRlbmN5QWxhcm1GYWN0b3J5LmFkZExhdGVuY3lBbGFybShcbiAgICAgICAgdGhpcy5wNTBTZWFyY2hMYXRlbmN5TWV0cmljLFxuICAgICAgICBMYXRlbmN5VHlwZS5QNTAsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy5zZWFyY2hMYXRlbmN5QW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRTZWFyY2hMYXRlbmN5UDkwQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRTZWFyY2hMYXRlbmN5UDkwQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLnNlYXJjaExhdGVuY3lBbGFybUZhY3RvcnkuYWRkTGF0ZW5jeUFsYXJtKFxuICAgICAgICB0aGlzLnA5MFNlYXJjaExhdGVuY3lNZXRyaWMsXG4gICAgICAgIExhdGVuY3lUeXBlLlA5MCxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLnNlYXJjaExhdGVuY3lBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZFNlYXJjaExhdGVuY3lQOTlBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZFNlYXJjaExhdGVuY3lQOTlBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMuc2VhcmNoTGF0ZW5jeUFsYXJtRmFjdG9yeS5hZGRMYXRlbmN5QWxhcm0oXG4gICAgICAgIHRoaXMucDk5U2VhcmNoTGF0ZW5jeU1ldHJpYyxcbiAgICAgICAgTGF0ZW5jeVR5cGUuUDk5LFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuc2VhcmNoTGF0ZW5jeUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkQ2x1c3RlclN0YXR1c0FsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkQ2x1c3RlclN0YXR1c0FsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgbGV0IGNyZWF0ZWRBbGFybTtcbiAgICAgIHN3aXRjaCAoYWxhcm1Qcm9wcy5zdGF0dXMpIHtcbiAgICAgICAgY2FzZSBPcGVuU2VhcmNoQ2x1c3RlclN0YXR1cy5SRUQ6XG4gICAgICAgICAgY3JlYXRlZEFsYXJtID0gdGhpcy5jbHVzdGVyQWxhcm1GYWN0b3J5LmFkZENsdXN0ZXJTdGF0dXNBbGFybShcbiAgICAgICAgICAgIHRoaXMuY2x1c3RlclN0YXR1c1JlZE1ldHJpYyxcbiAgICAgICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgT3BlblNlYXJjaENsdXN0ZXJTdGF0dXMuWUVMTE9XOlxuICAgICAgICAgIGNyZWF0ZWRBbGFybSA9IHRoaXMuY2x1c3RlckFsYXJtRmFjdG9yeS5hZGRDbHVzdGVyU3RhdHVzQWxhcm0oXG4gICAgICAgICAgICB0aGlzLmNsdXN0ZXJTdGF0dXNZZWxsb3dNZXRyaWMsXG4gICAgICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBjbHVzdGVyIHN0YXR1czogJHthbGFybVByb3BzLnN0YXR1c31gKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZERpc2tTcGFjZVVzYWdlQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGREaXNrU3BhY2VVc2FnZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy51c2FnZUFsYXJtRmFjdG9yeS5hZGRNYXhEaXNrVXNhZ2VQZXJjZW50QWxhcm0oXG4gICAgICAgIHRoaXMuZGlza1NwYWNlVXNhZ2VNZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy51c2FnZUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkQ3B1U3BhY2VVc2FnZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkQ3B1U3BhY2VVc2FnZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy51c2FnZUFsYXJtRmFjdG9yeS5hZGRNYXhDcHVVc2FnZVBlcmNlbnRBbGFybShcbiAgICAgICAgdGhpcy5jcHVVc2FnZU1ldHJpYyxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLnVzYWdlQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRNYXN0ZXJDcHVTcGFjZVVzYWdlQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRNYXN0ZXJDcHVTcGFjZVVzYWdlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPVxuICAgICAgICB0aGlzLnVzYWdlQWxhcm1GYWN0b3J5LmFkZE1heE1hc3RlckNwdVVzYWdlUGVyY2VudEFsYXJtKFxuICAgICAgICAgIHRoaXMubWFzdGVyQ3B1VXNhZ2VNZXRyaWMsXG4gICAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgICApO1x