cdk-monitoring-constructs
Version:
[](https://badge.fury.io/js/cdk-monitoring-constructs) [](https://m
441 lines • 87.4 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.LambdaFunctionMonitoring = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
const LambdaFunctionEnhancedMetricFactory_1 = require("./LambdaFunctionEnhancedMetricFactory");
const LambdaFunctionMetricFactory_1 = require("./LambdaFunctionMetricFactory");
const common_1 = require("../../common");
const dashboard_1 = require("../../dashboard");
class LambdaFunctionMonitoring extends common_1.Monitoring {
constructor(scope, props) {
super(scope, props);
this.namingStrategy = new dashboard_1.MonitoringNamingStrategy({
...props,
namedConstruct: props.lambdaFunction,
fallbackConstructName: this.resolveFunctionName(props.lambdaFunction),
});
this.title = this.namingStrategy.resolveHumanReadableName();
this.functionUrl = scope
.createAwsConsoleUrlFactory()
.getLambdaFunctionUrl(props.lambdaFunction.functionName);
this.alarmFactory = this.createAlarmFactory(this.namingStrategy.resolveAlarmFriendlyName());
this.errorAlarmFactory = new common_1.ErrorAlarmFactory(this.alarmFactory);
this.latencyAlarmFactory = new common_1.LatencyAlarmFactory(this.alarmFactory);
this.tpsAlarmFactory = new common_1.TpsAlarmFactory(this.alarmFactory);
this.taskHealthAlarmFactory = new common_1.TaskHealthAlarmFactory(this.alarmFactory);
this.ageAlarmFactory = new common_1.AgeAlarmFactory(this.alarmFactory);
this.usageAlarmFactory = new common_1.UsageAlarmFactory(this.alarmFactory);
this.latencyAnnotations = [];
this.errorCountAnnotations = [];
this.errorRateAnnotations = [];
this.invocationCountAnnotations = [];
this.invocationRateAnnotations = [];
this.tpsAnnotations = [];
this.cpuTotalTimeAnnotations = [];
this.memoryUsageAnnotations = [];
this.maxIteratorAgeAnnotations = [];
this.maxOffsetLagAnnotations = [];
this.metricFactory = new LambdaFunctionMetricFactory_1.LambdaFunctionMetricFactory(scope.createMetricFactory(), props);
this.tpsMetric = this.metricFactory.metricInvocationRate(common_1.RateComputationMethod.PER_SECOND);
this.p50LatencyMetric = this.metricFactory.metricLatencyInMillis(common_1.LatencyType.P50);
this.p90LatencyMetric = this.metricFactory.metricLatencyInMillis(common_1.LatencyType.P90);
this.p99LatencyMetric = this.metricFactory.metricLatencyInMillis(common_1.LatencyType.P99);
this.maxLatencyMetric = this.metricFactory.metricLatencyInMillis(common_1.LatencyType.MAX);
this.faultCountMetric = this.metricFactory.metricFaultCount();
this.faultRateMetric = this.metricFactory.metricFaultRate();
this.invocationCountMetric = this.metricFactory.metricInvocationCount();
this.throttlesCountMetric = this.metricFactory.metricThrottlesCount();
this.throttlesRateMetric = this.metricFactory.metricThrottlesRate();
this.concurrentExecutionsCountMetric =
this.metricFactory.metricConcurrentExecutions();
this.provisionedConcurrencySpilloverInvocationsCountMetric =
this.metricFactory.metricProvisionedConcurrencySpilloverInvocations();
this.provisionedConcurrencySpilloverInvocationsRateMetric =
this.metricFactory.metricProvisionedConcurrencySpilloverRate();
this.isIterator = props.isIterator ?? true;
this.maxIteratorAgeMetric =
this.metricFactory.metricMaxIteratorAgeInMillis();
this.isOffsetLag = props.isOffsetLag ?? false;
this.maxOffsetLagMetric =
this.metricFactory.metricMaxOffsetLagInNumberOfRecords();
this.lambdaInsightsEnabled = props.lambdaInsightsEnabled ?? false;
if (props.lambdaInsightsEnabled) {
this.enhancedMetricFactory = new LambdaFunctionEnhancedMetricFactory_1.LambdaFunctionEnhancedMetricFactory(scope.createMetricFactory(), props);
this.enhancedMonitoringMaxCpuTotalTimeMetric =
this.enhancedMetricFactory.enhancedMetricMaxCpuTotalTime();
this.enhancedMonitoringP90CpuTotalTimeMetric =
this.enhancedMetricFactory.enhancedMetricP90CpuTotalTime();
this.enhancedMonitoringAvgCpuTotalTimeMetric =
this.enhancedMetricFactory.enhancedMetricAvgCpuTotalTime();
this.enhancedMonitoringMaxMemoryUtilizationMetric =
this.enhancedMetricFactory.enhancedMetricMaxMemoryUtilization();
this.enhancedMonitoringP90MemoryUtilizationMetric =
this.enhancedMetricFactory.enhancedMetricP90MemoryUtilization();
this.enhancedMonitoringAvgMemoryUtilizationMetric =
this.enhancedMetricFactory.enhancedMetricAvgMemoryUtilization();
this.enhancedMetricFunctionCostMetric =
this.enhancedMetricFactory.enhancedMetricFunctionCost();
for (const disambiguator in props.addEnhancedMonitoringMaxCpuTotalTimeAlarm) {
const alarmProps = props.addEnhancedMonitoringMaxCpuTotalTimeAlarm[disambiguator];
const createdAlarm = this.latencyAlarmFactory.addDurationAlarm(
/* eslint-disable @typescript-eslint/no-non-null-assertion */
this.enhancedMonitoringMaxCpuTotalTimeMetric,
/* eslint-enable @typescript-eslint/no-non-null-assertion */
common_1.LatencyType.P100, alarmProps, disambiguator);
this.cpuTotalTimeAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addEnhancedMonitoringP90CpuTotalTimeAlarm) {
const alarmProps = props.addEnhancedMonitoringP90CpuTotalTimeAlarm[disambiguator];
const createdAlarm = this.latencyAlarmFactory.addDurationAlarm(
/* eslint-disable @typescript-eslint/no-non-null-assertion */
this.enhancedMonitoringP90CpuTotalTimeMetric,
/* eslint-enable @typescript-eslint/no-non-null-assertion */
common_1.LatencyType.P90, alarmProps, disambiguator);
this.cpuTotalTimeAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addEnhancedMonitoringAvgCpuTotalTimeAlarm) {
const alarmProps = props.addEnhancedMonitoringAvgCpuTotalTimeAlarm[disambiguator];
const createdAlarm = this.latencyAlarmFactory.addDurationAlarm(
/* eslint-disable @typescript-eslint/no-non-null-assertion */
this.enhancedMonitoringAvgCpuTotalTimeMetric,
/* eslint-enable @typescript-eslint/no-non-null-assertion */
common_1.LatencyType.AVERAGE, alarmProps, disambiguator);
this.cpuTotalTimeAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addEnhancedMonitoringMaxMemoryUtilizationAlarm) {
const alarmProps = props.addEnhancedMonitoringMaxMemoryUtilizationAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxMemoryUsagePercentAlarm(
/* eslint-disable @typescript-eslint/no-non-null-assertion */
this.enhancedMonitoringMaxMemoryUtilizationMetric,
/* eslint-enable @typescript-eslint/no-non-null-assertion */
alarmProps, disambiguator);
this.memoryUsageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addEnhancedMonitoringP90MemoryUtilizationAlarm) {
const alarmProps = props.addEnhancedMonitoringP90MemoryUtilizationAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMemoryUsagePercentAlarm(
/* eslint-disable @typescript-eslint/no-non-null-assertion */
this.enhancedMonitoringP90MemoryUtilizationMetric,
/* eslint-enable @typescript-eslint/no-non-null-assertion */
alarmProps, common_1.UsageType.P90, disambiguator);
this.memoryUsageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addEnhancedMonitoringAvgMemoryUtilizationAlarm) {
const alarmProps = props.addEnhancedMonitoringAvgMemoryUtilizationAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMemoryUsagePercentAlarm(
/* eslint-disable @typescript-eslint/no-non-null-assertion */
this.enhancedMonitoringAvgMemoryUtilizationMetric,
/* eslint-enable @typescript-eslint/no-non-null-assertion */
alarmProps, common_1.UsageType.AVERAGE, disambiguator);
this.memoryUsageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
}
for (const disambiguator in props.addLatencyP50Alarm) {
const alarmProps = props.addLatencyP50Alarm[disambiguator];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(this.p50LatencyMetric, common_1.LatencyType.P50, this.convertToLatencyThreshold(alarmProps, props.lambdaFunction), disambiguator);
this.latencyAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addLatencyP90Alarm) {
const alarmProps = props.addLatencyP90Alarm[disambiguator];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(this.p90LatencyMetric, common_1.LatencyType.P90, this.convertToLatencyThreshold(alarmProps, props.lambdaFunction), disambiguator);
this.latencyAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addLatencyP99Alarm) {
const alarmProps = props.addLatencyP99Alarm[disambiguator];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(this.p99LatencyMetric, common_1.LatencyType.P99, this.convertToLatencyThreshold(alarmProps, props.lambdaFunction), disambiguator);
this.latencyAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addMaxLatencyAlarm) {
const alarmProps = props.addMaxLatencyAlarm[disambiguator];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(this.maxLatencyMetric, common_1.LatencyType.MAX, this.convertToLatencyThreshold(alarmProps, props.lambdaFunction), disambiguator);
this.latencyAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addFaultCountAlarm) {
const alarmProps = props.addFaultCountAlarm[disambiguator];
const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(this.faultCountMetric, common_1.ErrorType.FAULT, alarmProps, disambiguator);
this.errorCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addFaultRateAlarm) {
const alarmProps = props.addFaultRateAlarm[disambiguator];
const createdAlarm = this.errorAlarmFactory.addErrorRateAlarm(this.faultRateMetric, 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);
}
for (const disambiguator in props.addThrottlesCountAlarm) {
const alarmProps = props.addThrottlesCountAlarm[disambiguator];
const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(this.throttlesCountMetric, common_1.ErrorType.THROTTLED, alarmProps, disambiguator);
this.invocationCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addThrottlesRateAlarm) {
const alarmProps = props.addThrottlesRateAlarm[disambiguator];
const createdAlarm = this.errorAlarmFactory.addErrorRateAlarm(this.throttlesRateMetric, common_1.ErrorType.THROTTLED, alarmProps, disambiguator);
this.invocationRateAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addMinInvocationsCountAlarm) {
const alarmProps = props.addMinInvocationsCountAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMinUsageCountAlarm(this.invocationCountMetric, alarmProps, disambiguator);
this.invocationCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addConcurrentExecutionsCountAlarm) {
const alarmProps = props.addConcurrentExecutionsCountAlarm[disambiguator];
const createdAlarm = this.taskHealthAlarmFactory.addRunningTaskCountAlarm(this.concurrentExecutionsCountMetric, alarmProps, disambiguator);
this.invocationCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addProvisionedConcurrencySpilloverInvocationsCountAlarm) {
const alarmProps = props.addProvisionedConcurrencySpilloverInvocationsCountAlarm[disambiguator];
const createdAlarm = this.taskHealthAlarmFactory.addRunningTaskCountAlarm(this.provisionedConcurrencySpilloverInvocationsCountMetric, alarmProps, disambiguator);
this.invocationCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addProvisionedConcurrencySpilloverInvocationsRateAlarm) {
const alarmProps = props.addProvisionedConcurrencySpilloverInvocationsRateAlarm[disambiguator];
const createdAlarm = this.taskHealthAlarmFactory.addRunningTaskRateAlarm(this.provisionedConcurrencySpilloverInvocationsRateMetric, alarmProps, disambiguator);
this.invocationRateAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addMaxIteratorAgeAlarm) {
if (!this.isIterator) {
throw new Error("addMaxIteratorAgeAlarm is not applicable if isIterator is not true");
}
const alarmProps = props.addMaxIteratorAgeAlarm[disambiguator];
const createdAlarm = this.ageAlarmFactory.addIteratorMaxAgeAlarm(this.maxIteratorAgeMetric, alarmProps, disambiguator);
this.maxIteratorAgeAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addMaxOffsetLagAlarm) {
if (!this.isOffsetLag) {
throw new Error("addMaxOffsetLagAlarm is not applicable if isOffsetLag is not true");
}
const alarmProps = props.addMaxOffsetLagAlarm[disambiguator];
const createdAlarm = this.ageAlarmFactory.addMaxOffsetLagAlarm(this.maxOffsetLagMetric, alarmProps, disambiguator);
this.maxOffsetLagAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
props.useCreatedAlarms?.consume(this.createdAlarms());
}
convertToLatencyThreshold(latencyProps, lambdaFunction) {
if ("maxLatency" in latencyProps) {
return latencyProps;
}
const { maxLatencyPercentageOfTimeout, ...rest } = latencyProps;
const timeout = lambdaFunction.timeout ?? aws_cdk_lib_1.Duration.seconds(3);
return {
...rest,
maxLatency: aws_cdk_lib_1.Duration.millis(Math.floor((timeout.toMilliseconds() * maxLatencyPercentageOfTimeout) / 100)),
};
}
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() {
const widgets = [
this.createTitleWidget(),
new aws_cloudwatch_1.Row(this.createTpsWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), this.createLatencyWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), this.createErrorRateWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight), this.createRateWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight)),
];
let secondRowWidgetWidth;
if (this.isIterator && this.isOffsetLag) {
secondRowWidgetWidth = common_1.QuarterWidth;
}
else if (this.isIterator || this.isOffsetLag) {
secondRowWidgetWidth = common_1.ThirdWidth;
}
else {
secondRowWidgetWidth = common_1.HalfWidth;
}
const secondRow = new aws_cloudwatch_1.Row(this.createInvocationWidget(secondRowWidgetWidth, common_1.DefaultGraphWidgetHeight), this.createErrorCountWidget(secondRowWidgetWidth, common_1.DefaultGraphWidgetHeight));
if (this.isIterator) {
secondRow.addWidget(this.createIteratorAgeWidget(secondRowWidgetWidth, common_1.DefaultGraphWidgetHeight));
}
if (this.isOffsetLag) {
secondRow.addWidget(this.createOffsetLagWidget(secondRowWidgetWidth, common_1.DefaultGraphWidgetHeight));
}
widgets.push(secondRow);
if (this.lambdaInsightsEnabled) {
widgets.push(new aws_cloudwatch_1.Row(this.createLambdaInsightsCpuWidget(common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight), this.createLambdaInsightsMemoryWidget(common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight), this.createLambdaInsightsFunctionCostWidget(common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight)));
}
return widgets;
}
createTitleWidget() {
return new dashboard_1.MonitoringHeaderWidget({
family: "Lambda Function",
title: this.title,
goToLinkUrl: this.functionUrl,
});
}
createTpsWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "TPS",
left: [this.tpsMetric],
leftYAxis: common_1.RateAxisFromZero,
leftAnnotations: this.tpsAnnotations,
});
}
createLatencyWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Latency",
left: [
this.p50LatencyMetric,
this.p90LatencyMetric,
this.p99LatencyMetric,
],
leftYAxis: common_1.TimeAxisMillisFromZero,
leftAnnotations: this.latencyAnnotations,
});
}
createErrorCountWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Errors",
left: [this.faultCountMetric],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.errorCountAnnotations,
});
}
createErrorRateWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Errors (rate)",
left: [this.faultRateMetric],
leftYAxis: common_1.RateAxisFromZero,
leftAnnotations: this.errorRateAnnotations,
});
}
createRateWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Rates",
left: [
this.throttlesRateMetric,
this.provisionedConcurrencySpilloverInvocationsRateMetric,
],
leftYAxis: common_1.RateAxisFromZero,
leftAnnotations: this.invocationRateAnnotations,
});
}
createInvocationWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Invocations",
left: [
this.invocationCountMetric,
this.throttlesCountMetric,
this.concurrentExecutionsCountMetric,
this.provisionedConcurrencySpilloverInvocationsCountMetric,
],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.invocationCountAnnotations,
});
}
createIteratorAgeWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Iterator",
left: [this.maxIteratorAgeMetric],
leftYAxis: common_1.TimeAxisMillisFromZero,
leftAnnotations: this.maxIteratorAgeAnnotations,
});
}
createOffsetLagWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "OffsetLag",
left: [this.maxOffsetLagMetric],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.maxOffsetLagAnnotations,
});
}
createLambdaInsightsCpuWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "CPU Total Time",
left: [
/* eslint-disable @typescript-eslint/no-non-null-assertion */
this.enhancedMonitoringMaxCpuTotalTimeMetric,
this.enhancedMonitoringP90CpuTotalTimeMetric,
this.enhancedMonitoringAvgCpuTotalTimeMetric,
],
leftYAxis: common_1.TimeAxisMillisFromZero,
leftAnnotations: this.cpuTotalTimeAnnotations,
});
}
createLambdaInsightsMemoryWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Memory Utilization",
left: [
/* eslint-disable @typescript-eslint/no-non-null-assertion */
this.enhancedMonitoringMaxMemoryUtilizationMetric,
this.enhancedMonitoringP90MemoryUtilizationMetric,
this.enhancedMonitoringAvgMemoryUtilizationMetric,
],
leftYAxis: common_1.PercentageAxisFromZeroToHundred,
leftAnnotations: this.memoryUsageAnnotations,
});
}
createLambdaInsightsFunctionCostWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Function Cost",
/* eslint-disable @typescript-eslint/no-non-null-assertion */
left: [this.enhancedMetricFunctionCostMetric],
/* eslint-enable @typescript-eslint/no-non-null-assertion */
leftYAxis: common_1.MegabyteMillisecondAxisFromZero,
});
}
resolveFunctionName(lambdaFunction) {
// try to take the name (if specified) instead of token
return lambdaFunction.node.defaultChild?.functionName;
}
}
exports.LambdaFunctionMonitoring = LambdaFunctionMonitoring;
_a = JSII_RTTI_SYMBOL_1;
LambdaFunctionMonitoring[_a] = { fqn: "cdk-monitoring-constructs.LambdaFunctionMonitoring", version: "9.7.1" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTGFtYmRhRnVuY3Rpb25Nb25pdG9yaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiTGFtYmRhRnVuY3Rpb25Nb25pdG9yaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNkNBQXVDO0FBQ3ZDLCtEQUtvQztBQUdwQywrRkFBNEY7QUFDNUYsK0VBR3VDO0FBQ3ZDLHlDQXVDc0I7QUFDdEIsK0NBR3lCO0FBK0Z6QixNQUFhLHdCQUF5QixTQUFRLG1CQUFVO0lBc0R0RCxZQUFZLEtBQXNCLEVBQUUsS0FBb0M7UUFDdEUsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVwQixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksb0NBQXdCLENBQUM7WUFDakQsR0FBRyxLQUFLO1lBQ1IsY0FBYyxFQUFFLEtBQUssQ0FBQyxjQUFjO1lBQ3BDLHFCQUFxQixFQUFFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDO1NBQ3RFLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQzVELElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSzthQUNyQiwwQkFBMEIsRUFBRTthQUM1QixvQkFBb0IsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRTNELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUN6QyxJQUFJLENBQUMsY0FBYyxDQUFDLHdCQUF3QixFQUFFLENBQy9DLENBQUM7UUFDRixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSwwQkFBaUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDbEUsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksNEJBQW1CLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3RFLElBQUksQ0FBQyxlQUFlLEdBQUcs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QkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEdXJhdGlvbiB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHtcbiAgR3JhcGhXaWRnZXQsXG4gIEhvcml6b250YWxBbm5vdGF0aW9uLFxuICBJV2lkZ2V0LFxuICBSb3csXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaFwiO1xuaW1wb3J0IHsgQ2ZuRnVuY3Rpb24sIEZ1bmN0aW9uLCBJRnVuY3Rpb24gfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYVwiO1xuXG5pbXBvcnQgeyBMYW1iZGFGdW5jdGlvbkVuaGFuY2VkTWV0cmljRmFjdG9yeSB9IGZyb20gXCIuL0xhbWJkYUZ1bmN0aW9uRW5oYW5jZWRNZXRyaWNGYWN0b3J5XCI7XG5pbXBvcnQge1xuICBMYW1iZGFGdW5jdGlvbk1ldHJpY0ZhY3RvcnksXG4gIExhbWJkYUZ1bmN0aW9uTWV0cmljRmFjdG9yeVByb3BzLFxufSBmcm9tIFwiLi9MYW1iZGFGdW5jdGlvbk1ldHJpY0ZhY3RvcnlcIjtcbmltcG9ydCB7XG4gIEFnZUFsYXJtRmFjdG9yeSxcbiAgQWxhcm1GYWN0b3J5LFxuICBCYXNlTW9uaXRvcmluZ1Byb3BzLFxuICBDb3VudEF4aXNGcm9tWmVybyxcbiAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCxcbiAgRHVyYXRpb25UaHJlc2hvbGQsXG4gIEVycm9yQWxhcm1GYWN0b3J5LFxuICBFcnJvckNvdW50VGhyZXNob2xkLFxuICBFcnJvclJhdGVUaHJlc2hvbGQsXG4gIEVycm9yVHlwZSxcbiAgSGFsZldpZHRoLFxuICBIaWdoVHBzVGhyZXNob2xkLFxuICBMYXRlbmN5QWxhcm1GYWN0b3J5LFxuICBMYXRlbmN5VGhyZXNob2xkLFxuICBMYXRlbmN5VGltZW91dFBlcmNlbnRhZ2VUaHJlc2hvbGQsXG4gIExhdGVuY3lUeXBlLFxuICBMb3dUcHNUaHJlc2hvbGQsXG4gIE1heEFnZVRocmVzaG9sZCxcbiAgTWF4T2Zmc2V0TGFnVGhyZXNob2xkLFxuICBNZWdhYnl0ZU1pbGxpc2Vjb25kQXhpc0Zyb21aZXJvLFxuICBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0LFxuICBNaW5Vc2FnZUNvdW50VGhyZXNob2xkLFxuICBNb25pdG9yaW5nLFxuICBNb25pdG9yaW5nU2NvcGUsXG4gIFBlcmNlbnRhZ2VBeGlzRnJvbVplcm9Ub0h1bmRyZWQsXG4gIFF1YXJ0ZXJXaWR0aCxcbiAgUmF0ZUF4aXNGcm9tWmVybyxcbiAgUmF0ZUNvbXB1dGF0aW9uTWV0aG9kLFxuICBSdW5uaW5nVGFza0NvdW50VGhyZXNob2xkLFxuICBSdW5uaW5nVGFza1JhdGVUaHJlc2hvbGQsXG4gIFRhc2tIZWFsdGhBbGFybUZhY3RvcnksXG4gIFRoaXJkV2lkdGgsXG4gIFRpbWVBeGlzTWlsbGlzRnJvbVplcm8sXG4gIFRwc0FsYXJtRmFjdG9yeSxcbiAgVXNhZ2VBbGFybUZhY3RvcnksXG4gIFVzYWdlVGhyZXNob2xkLFxuICBVc2FnZVR5cGUsXG59IGZyb20gXCIuLi8uLi9jb21tb25cIjtcbmltcG9ydCB7XG4gIE1vbml0b3JpbmdIZWFkZXJXaWRnZXQsXG4gIE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSxcbn0gZnJvbSBcIi4uLy4uL2Rhc2hib2FyZFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIExhbWJkYUZ1bmN0aW9uTW9uaXRvcmluZ09wdGlvbnMgZXh0ZW5kcyBCYXNlTW9uaXRvcmluZ1Byb3BzIHtcbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGF0IHRoZSBMYW1iZGEgZnVuY3Rpb24gaGFuZGxlcyBhbiBldmVudCBzb3VyY2UgKGUuZy4gRHluYW1vREIgZXZlbnQgc3RyZWFtKS5cbiAgICogVGhpcyBpbXBhY3RzIHdoYXQgd2lkZ2V0cyBhcmUgc2hvd24sIGFzIHdlbGwgYXMgdmFsaWRhdGVzIHRoZSBhYmlsaXR5IHRvIHVzZSBhZGRNYXhJdGVyYXRvckFnZUFsYXJtLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGlzSXRlcmF0b3I/OiBib29sZWFuO1xuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgdGhlIExhbWJkYSBmdW5jdGlvbiBoYW5kbGVzIGFuIGV2ZW50IHNvdXJjZSB3aGljaCB1c2VzIG9mZnNldHMgZm9yIHJlY29yZHMgKGUuZy4gS2Fma2Egc3RyZWFtcykuXG4gICAqIFRoaXMgaW1wYWN0cyB3aGF0IHdpZGdldHMgYXJlIHNob3duLCBhcyB3ZWxsIGFzIHZhbGlkYXRlcyB0aGUgYWJpbGl0eSB0byB1c2UgYWRkTWF4T2Zmc2V0TGFnQWxhcm0uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGlzT2Zmc2V0TGFnPzogYm9vbGVhbjtcblxuICByZWFkb25seSBhZGRMYXRlbmN5UDUwQWxhcm0/OiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIExhdGVuY3lUaHJlc2hvbGQgfCBMYXRlbmN5VGltZW91dFBlcmNlbnRhZ2VUaHJlc2hvbGRcbiAgPjtcbiAgcmVhZG9ubHkgYWRkTGF0ZW5jeVA5MEFsYXJtPzogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBMYXRlbmN5VGhyZXNob2xkIHwgTGF0ZW5jeVRpbWVvdXRQZXJjZW50YWdlVGhyZXNob2xkXG4gID47XG4gIHJlYWRvbmx5IGFkZExhdGVuY3lQOTlBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgTGF0ZW5jeVRocmVzaG9sZCB8IExhdGVuY3lUaW1lb3V0UGVyY2VudGFnZVRocmVzaG9sZFxuICA+O1xuICByZWFkb25seSBhZGRNYXhMYXRlbmN5QWxhcm0/OiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIExhdGVuY3lUaHJlc2hvbGQgfCBMYXRlbmN5VGltZW91dFBlcmNlbnRhZ2VUaHJlc2hvbGRcbiAgPjtcblxuICByZWFkb25seSBhZGRGYXVsdENvdW50QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvckNvdW50VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkRmF1bHRSYXRlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvclJhdGVUaHJlc2hvb