cdk-monitoring-constructs
Version:
[](https://badge.fury.io/js/cdk-monitoring-constructs) [](https://m
104 lines • 17.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScaleAlarms = void 0;
const aws_cdk_lib_1 = require("aws-cdk-lib");
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
const SupportedMetricPeriods = [
aws_cdk_lib_1.Duration.minutes(1),
aws_cdk_lib_1.Duration.minutes(5),
aws_cdk_lib_1.Duration.minutes(15),
aws_cdk_lib_1.Duration.hours(1),
aws_cdk_lib_1.Duration.hours(6),
aws_cdk_lib_1.Duration.days(1),
aws_cdk_lib_1.Duration.days(7),
];
/**
* Creates a function that clones alarms to be more scaled using the multiplication factors
* provided. This function can be provided to the `cloneAlarms` method of
* {@link MonitoringFacade}.
*
* This can be used with scaling factors less than 1.0 to create more aggressive alarms, which
* can be useful to provide early detection and trigger change rollbacks.
*
* If the datapoints to alarm would be scaled to such a small number that it can't effectively be
* alarmed, the metric period will be reduced to the next smallest duration and the required
* datapoint count will scale up accordingly.
*
* @param props The properties for configuring the function.
* @returns A function that clones alarms and applies scaling factors.
*/
function ScaleAlarms(props) {
return function (alarm) {
let thresholdMultiplierToUse = 1;
if (props.thresholdMultiplier) {
const comparisonOperator = alarm.alarmDefinition.addAlarmProps.comparisonOperator;
switch (comparisonOperator) {
case aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD:
case aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD:
thresholdMultiplierToUse = props.thresholdMultiplier;
break;
case aws_cloudwatch_1.ComparisonOperator.LESS_THAN_OR_EQUAL_TO_THRESHOLD:
case aws_cloudwatch_1.ComparisonOperator.LESS_THAN_THRESHOLD:
thresholdMultiplierToUse = 1.0 / props.thresholdMultiplier;
break;
case aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_UPPER_THRESHOLD:
case aws_cloudwatch_1.ComparisonOperator.LESS_THAN_LOWER_THRESHOLD:
case aws_cloudwatch_1.ComparisonOperator.LESS_THAN_LOWER_OR_GREATER_THAN_UPPER_THRESHOLD:
// Don't modify thresholds for anomaly detection models.
thresholdMultiplierToUse = 1;
break;
default:
throw new Error(`Comparison operator ${comparisonOperator} is not supported by ScaleAlarms.`);
}
}
let cloneThreshold = alarm.alarmDefinition.addAlarmProps.threshold * thresholdMultiplierToUse;
let cloneEvaluationPeriods = alarm.alarmDefinition.evaluationPeriods *
(props.evaluationPeriodsMultiplier ??
props.datapointsToAlarmMultiplier ??
1);
let cloneDatapointsToAlarm = alarm.alarmDefinition.datapointsToAlarm *
(props.datapointsToAlarmMultiplier ?? 1);
// If the tightened datapoints to alarm is now so small that we can't effectively alarm on it,
// reduce the metric period to the next smallest duration and scale up the datapoint count accordingly.
let clonePeriod = alarm.alarmDefinition.addAlarmProps.period;
if (cloneEvaluationPeriods < 2 || cloneDatapointsToAlarm < 2) {
const originalPeriod = alarm.alarmDefinition.addAlarmProps.period ??
alarm.alarmDefinition.metric.period;
const nextSmallestPeriod = findNextSmallestPeriod(originalPeriod);
if (nextSmallestPeriod) {
clonePeriod = nextSmallestPeriod;
const datapointScaleFactor = originalPeriod.toSeconds() / nextSmallestPeriod.toSeconds();
cloneEvaluationPeriods = cloneEvaluationPeriods * datapointScaleFactor;
cloneDatapointsToAlarm = cloneDatapointsToAlarm * datapointScaleFactor;
// If the metric uses SUM or N, we also need to scale the threshold down.
if ("statistic" in alarm.alarmDefinition.metric) {
if (alarm.alarmDefinition.metric.statistic === aws_cloudwatch_1.Stats.SUM ||
alarm.alarmDefinition.metric.statistic === aws_cloudwatch_1.Stats.SAMPLE_COUNT) {
cloneThreshold = cloneThreshold / datapointScaleFactor;
}
}
}
}
cloneEvaluationPeriods = Math.max(1, Math.round(cloneEvaluationPeriods));
cloneDatapointsToAlarm = Math.max(1, Math.round(cloneDatapointsToAlarm));
return {
...alarm.alarmDefinition.addAlarmProps,
disambiguator: props.disambiguator,
threshold: cloneThreshold,
evaluationPeriods: cloneEvaluationPeriods,
datapointsToAlarm: cloneDatapointsToAlarm,
period: clonePeriod,
};
};
}
exports.ScaleAlarms = ScaleAlarms;
function findNextSmallestPeriod(originalPeriod) {
for (let index = SupportedMetricPeriods.length - 1; index >= 0; index--) {
const current = SupportedMetricPeriods[index];
if (current.toSeconds() < originalPeriod.toSeconds()) {
return current;
}
}
return undefined;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2NhbGVBbGFybXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJTY2FsZUFsYXJtcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBdUM7QUFDdkMsK0RBQXVFO0FBR3ZFLE1BQU0sc0JBQXNCLEdBQUc7SUFDN0Isc0JBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ25CLHNCQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNuQixzQkFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7SUFDcEIsc0JBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ2pCLHNCQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUNqQixzQkFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDaEIsc0JBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0NBQ2pCLENBQUM7QUF3Q0Y7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxTQUFnQixXQUFXLENBQUMsS0FBdUI7SUFDakQsT0FBTyxVQUFVLEtBQTBCO1FBQ3pDLElBQUksd0JBQXdCLEdBQVcsQ0FBQyxDQUFDO1FBQ3pDLElBQUksS0FBSyxDQUFDLG1CQUFtQixFQUFFO1lBQzdCLE1BQU0sa0JBQWtCLEdBQ3RCLEtBQUssQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLGtCQUFrQixDQUFDO1lBQ3pELFFBQVEsa0JBQWtCLEVBQUU7Z0JBQzFCLEtBQUssbUNBQWtCLENBQUMsa0NBQWtDLENBQUM7Z0JBQzNELEtBQUssbUNBQWtCLENBQUMsc0JBQXNCO29CQUM1Qyx3QkFBd0IsR0FBRyxLQUFLLENBQUMsbUJBQW1CLENBQUM7b0JBQ3JELE1BQU07Z0JBQ1IsS0FBSyxtQ0FBa0IsQ0FBQywrQkFBK0IsQ0FBQztnQkFDeEQsS0FBSyxtQ0FBa0IsQ0FBQyxtQkFBbUI7b0JBQ3pDLHdCQUF3QixHQUFHLEdBQUcsR0FBRyxLQUFLLENBQUMsbUJBQW1CLENBQUM7b0JBQzNELE1B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QUMsRUFBRSxLQUFLLEVBQUUsRUFBRTtRQUN2RSxNQUFNLE9BQU8sR0FBRyxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QyxJQUFJLE9BQU8sQ0FBQyxTQUFTLEVBQUUsR0FBRyxjQUFjLENBQUMsU0FBUyxFQUFFLEVBQUU7WUFDcEQsT0FBTyxPQUFPLENBQUM7U0FDaEI7S0FDRjtJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEdXJhdGlvbiB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgQ29tcGFyaXNvbk9wZXJhdG9yLCBTdGF0cyB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaFwiO1xuaW1wb3J0IHsgQWxhcm1DbG9uZUZ1bmN0aW9uLCBBbGFybVdpdGhBbm5vdGF0aW9uIH0gZnJvbSBcIi4uLy4uXCI7XG5cbmNvbnN0IFN1cHBvcnRlZE1ldHJpY1BlcmlvZHMgPSBbXG4gIER1cmF0aW9uLm1pbnV0ZXMoMSksXG4gIER1cmF0aW9uLm1pbnV0ZXMoNSksXG4gIER1cmF0aW9uLm1pbnV0ZXMoMTUpLFxuICBEdXJhdGlvbi5ob3VycygxKSxcbiAgRHVyYXRpb24uaG91cnMoNiksXG4gIER1cmF0aW9uLmRheXMoMSksXG4gIER1cmF0aW9uLmRheXMoNyksXG5dO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGNvbmZpZ3VyaW5nIGEgZnVuY3Rpb24gdGhhdCBjbG9uZXMgYWxhcm1zIHRvIGJlIHNjYWxlZCBieSBtdWx0aXBsaWNhdGlvbiBmYWN0b3JzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNjYWxlQWxhcm1zUHJvcHMge1xuICAvKipcbiAgICogVGhlIGRpc2FtYmlndWF0b3IgdG8gYXNzaWduIHRvIHRoZSBhbGFybXMgY2xvbmVkIGJ5IHRoZSBmdW5jdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IGRpc2FtYmlndWF0b3I6IHN0cmluZztcblxuICAvKipcbiAgICogQSBtdWx0aXBsaWNhdGlvbiBmYWN0b3IgdG8gYXBwbHkgdG8gdGhlIHRocmVzaG9sZCBvZiB0aGUgY2xvbmVkIGFsYXJtcy5cbiAgICpcbiAgICogVGhyZXNob2xkIHNjYWxpbmcgZG9lcyBub3QgYXBwbHkgdG8gdGhyZXNob2xkcyBvbiBhbm9tYWx5IGRldGVjdGlvbiBhbGFybXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gMS4wXG4gICAqL1xuICByZWFkb25seSB0aHJlc2hvbGRNdWx0aXBsaWVyPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBBIG11bHRpcGxpY2F0aW9uIGZhY3RvciB0byBhcHBseSB0byB0aGUgZGF0YXBvaW50c1RvQWxhcm0gcHJvcGVydHkgb2YgdGhlIGNsb25lZCBhbGFybXMuXG4gICAqXG4gICAqIFdoZW4gY29uZmlndXJlZCB3aXRoIGEgdmFsdWUgbGVzcyB0aGF0IDEuMCwgdGhlIGNsb25lZCBhbGFybSAqbWF5KiB1c2UgYSBtZXRyaWMgd2l0aCBhIG1vcmVcbiAgICogZ3JhbnVsYXIgcGVyaW9kIHNvIHRoYXQgdGhlIHJlc3VsdCB3aWxsIHVzZSBhIHJlYXNvbmFibGUgbnVtYmVyIG9mIGRhdGFwb2ludHMuIEluIHRoaXMgY2FzZSxcbiAgICogdGhlIGBkYXRhcG9pbnRzVG9BbGFybWAgYW5kIGBldmFsdWF0aW9uUGVyaW9kc2AgYXJlIGluY3JlYXNlZCBieSB0aGUgc2FtZSBmYWN0b3IgdGhhdCB0aGVcbiAgICogcGVyaW9kIGlzIGRlY3JlYXNlZC4gSXQgd2lsbCBhbHNvIHNjYWxlIGB0aHJlc2hvbGRgIGZvciBtZXRyaWNzIHVzaW5nIHRoZSBTVU0gb3IgU0FNUExFX0NPVU5UXG4gICAqIHN0YXRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIDEuMFxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YXBvaW50c1RvQWxhcm1NdWx0aXBsaWVyPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBBIG11bHRpcGxpY2F0aW9uIGZhY3RvciB0byBhcHBseSB0byB0aGUgYGV2YWx1YXRpb25QZXJpb2RzYCBwcm9wZXJ0eSBvZiB0aGUgY2xvbmVkIGFsYXJtcy5cbiAgICogQGRlZmF1bHQgLSBTYW1lIGFzIGRhdGFwb2ludHNUb0FsYXJtTXVsdGlwbGllci5cbiAgICovXG4gIHJlYWRvbmx5IGV2YWx1YXRpb25QZXJpb2RzTXVsdGlwbGllcj86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBjbG9uZXMgYWxhcm1zIHRvIGJlIG1vcmUgc2NhbGVkIHVzaW5nIHRoZSBtdWx0aXBsaWNhdGlvbiBmYWN0b3JzXG4gKiBwcm92aWRlZC4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgcHJvdmlkZWQgdG8gdGhlIGBjbG9uZUFsYXJtc2AgbWV0aG9kIG9mXG4gKiB7QGxpbmsgTW9uaXRvcmluZ0ZhY2FkZX0uXG4gKlxuICogVGhpcyBjYW4gYmUgdXNlZCB3aXRoIHNjYWxpbmcgZmFjdG9ycyBsZXNzIHRoYW4gMS4wIHRvIGNyZWF0ZSBtb3JlIGFnZ3Jlc3NpdmUgYWxhcm1zLCB3aGljaFxuICogY2FuIGJlIHVzZWZ1bCB0byBwcm92aWRlIGVhcmx5IGRldGVjdGlvbiBhbmQgdHJpZ2dlciBjaGFuZ2Ugcm9sbGJhY2tzLlxuICpcbiAqIElmIHRoZSBkYXRhcG9pbnRzIHRvIGFsYXJtIHdvdWxkIGJlIHNjYWxlZCB0byBzdWNoIGEgc21hbGwgbnVtYmVyIHRoYXQgaXQgY2FuJ3QgZWZmZWN0aXZlbHkgYmVcbiAqIGFsYXJtZWQsIHRoZSBtZXRyaWMgcGVyaW9kIHdpbGwgYmUgcmVkdWNlZCB0byB0aGUgbmV4dCBzbWFsbGVzdCBkdXJhdGlvbiBhbmQgdGhlIHJlcXVpcmVkXG4gKiBkYXRhcG9pbnQgY291bnQgd2lsbCBzY2FsZSB1cCBhY2NvcmRpbmdseS5cbiAqXG4gKiBAcGFyYW0gcHJvcHMgVGhlIHByb3BlcnRpZXMgZm9yIGNvbmZpZ3VyaW5nIHRoZSBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIEEgZnVuY3Rpb24gdGhhdCBjbG9uZXMgYWxhcm1zIGFuZCBhcHBsaWVzIHNjYWxpbmcgZmFjdG9ycy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFNjYWxlQWxhcm1zKHByb3BzOiBTY2FsZUFsYXJtc1Byb3BzKTogQWxhcm1DbG9uZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChhbGFybTogQWxhcm1XaXRoQW5ub3RhdGlvbikge1xuICAgIGxldCB0aHJlc2hvbGRNdWx0aXBsaWVyVG9Vc2U6IG51bWJlciA9IDE7XG4gICAgaWYgKHByb3BzLnRocmVzaG9sZE11bHRpcGxpZXIpIHtcbiAgICAgIGNvbnN0IGNvbXBhcmlzb25PcGVyYXRvciA9XG4gICAgICAgIGFsYXJtLmFsYXJtRGVmaW5pdGlvbi5hZGRBbGFybVByb3BzLmNvbXBhcmlzb25PcGVyYXRvcjtcbiAgICAgIHN3aXRjaCAoY29tcGFyaXNvbk9wZXJhdG9yKSB7XG4gICAgICAgIGNhc2UgQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9PUl9FUVVBTF9UT19USFJFU0hPTEQ6XG4gICAgICAgIGNhc2UgQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9USFJFU0hPTEQ6XG4gICAgICAgICAgdGhyZXNob2xkTXVsdGlwbGllclRvVXNlID0gcHJvcHMudGhyZXNob2xkTXVsdGlwbGllcjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBDb21wYXJpc29uT3BlcmF0b3IuTEVTU19USEFOX09SX0VRVUFMX1RPX1RIUkVTSE9MRDpcbiAgICAgICAgY2FzZSBDb21wYXJpc29uT3BlcmF0b3IuTEVTU19USEFOX1RIUkVTSE9MRDpcbiAgICAgICAgICB0aHJlc2hvbGRNdWx0aXBsaWVyVG9Vc2UgPSAxLjAgLyBwcm9wcy50aHJlc2hvbGRNdWx0aXBsaWVyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIENvbXBhcmlzb25PcGVyYXRvci5HUkVBVEVSX1RIQU5fVVBQRVJfVEhSRVNIT0xEOlxuICAgICAgICBjYXNlIENvbXBhcmlzb25PcGVyYXRvci5MRVNTX1RIQU5fTE9XRVJfVEhSRVNIT0xEOlxuICAgICAgICBjYXNlIENvbXBhcmlzb25PcGVyYXRvci5MRVNTX1RIQU5fTE9XRVJfT1JfR1JFQVRFUl9USEFOX1VQUEVSX1RIUkVTSE9MRDpcbiAgICAgICAgICAvLyBEb24ndCBtb2RpZnkgdGhyZXNob2xkcyBmb3IgYW5vbWFseSBkZXRlY3Rpb24gbW9kZWxzLlxuICAgICAgICAgIHRocmVzaG9sZE11bHRpcGxpZXJUb1VzZSA9IDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYENvbXBhcmlzb24gb3BlcmF0b3IgJHtjb21wYXJpc29uT3BlcmF0b3J9IGlzIG5vdCBzdXBwb3J0ZWQgYnkgU2NhbGVBbGFybXMuYCxcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICBsZXQgY2xvbmVUaHJlc2hvbGQgPVxuICAgICAgYWxhcm0uYWxhcm1EZWZpbml0aW9uLmFkZEFsYXJtUHJvcHMudGhyZXNob2xkICogdGhyZXNob2xkTXVsdGlwbGllclRvVXNlO1xuXG4gICAgbGV0IGNsb25lRXZhbHVhdGlvblBlcmlvZHMgPVxuICAgICAgYWxhcm0uYWxhcm1EZWZpbml0aW9uLmV2YWx1YXRpb25QZXJpb2RzICpcbiAgICAgIChwcm9wcy5ldmFsdWF0aW9uUGVyaW9kc011bHRpcGxpZXIgPz9cbiAgICAgICAgcHJvcHMuZGF0YXBvaW50c1RvQWxhcm1NdWx0aXBsaWVyID8/XG4gICAgICAgIDEpO1xuICAgIGxldCBjbG9uZURhdGFwb2ludHNUb0FsYXJtID1cbiAgICAgIGFsYXJtLmFsYXJtRGVmaW5pdGlvbi5kYXRhcG9pbnRzVG9BbGFybSAqXG4gICAgICAocHJvcHMuZGF0YXBvaW50c1RvQWxhcm1NdWx0aXBsaWVyID8/IDEpO1xuXG4gICAgLy8gSWYgdGhlIHRpZ2h0ZW5lZCBkYXRhcG9pbnRzIHRvIGFsYXJtIGlzIG5vdyBzbyBzbWFsbCB0aGF0IHdlIGNhbid0IGVmZmVjdGl2ZWx5IGFsYXJtIG9uIGl0LFxuICAgIC8vIHJlZHVjZSB0aGUgbWV0cmljIHBlcmlvZCB0byB0aGUgbmV4dCBzbWFsbGVzdCBkdXJhdGlvbiBhbmQgc2NhbGUgdXAgdGhlIGRhdGFwb2ludCBjb3VudCBhY2NvcmRpbmdseS5cbiAgICBsZXQgY2xvbmVQZXJpb2QgPSBhbGFybS5hbGFybURlZmluaXRpb24uYWRkQWxhcm1Qcm9wcy5wZXJpb2Q7XG4gICAgaWYgKGNsb25lRXZhbHVhdGlvblBlcmlvZHMgPCAyIHx8IGNsb25lRGF0YXBvaW50c1RvQWxhcm0gPCAyKSB7XG4gICAgICBjb25zdCBvcmlnaW5hbFBlcmlvZCA9XG4gICAgICAgIGFsYXJtLmFsYXJtRGVmaW5pdGlvbi5hZGRBbGFybVByb3BzLnBlcmlvZCA/P1xuICAgICAgICBhbGFybS5hbGFybURlZmluaXRpb24ubWV0cmljLnBlcmlvZDtcblxuICAgICAgY29uc3QgbmV4dFNtYWxsZXN0UGVyaW9kID0gZmluZE5leHRTbWFsbGVzdFBlcmlvZChvcmlnaW5hbFBlcmlvZCk7XG4gICAgICBpZiAobmV4dFNtYWxsZXN0UGVyaW9kKSB7XG4gICAgICAgIGNsb25lUGVyaW9kID0gbmV4dFNtYWxsZXN0UGVyaW9kO1xuICAgICAgICBjb25zdCBkYXRhcG9pbnRTY2FsZUZhY3RvciA9XG4gICAgICAgICAgb3JpZ2luYWxQZXJpb2QudG9TZWNvbmRzKCkgLyBuZXh0U21hbGxlc3RQZXJpb2QudG9TZWNvbmRzKCk7XG4gICAgICAgIGNsb25lRXZhbHVhdGlvblBlcmlvZHMgPSBjbG9uZUV2YWx1YXRpb25QZXJpb2RzICogZGF0YXBvaW50U2NhbGVGYWN0b3I7XG4gICAgICAgIGNsb25lRGF0YXBvaW50c1RvQWxhcm0gPSBjbG9uZURhdGFwb2ludHNUb0FsYXJtICogZGF0YXBvaW50U2NhbGVGYWN0b3I7XG5cbiAgICAgICAgLy8gSWYgdGhlIG1ldHJpYyB1c2VzIFNVTSBvciBOLCB3ZSBhbHNvIG5lZWQgdG8gc2NhbGUgdGhlIHRocmVzaG9sZCBkb3duLlxuICAgICAgICBpZiAoXCJzdGF0aXN0aWNcIiBpbiBhbGFybS5hbGFybURlZmluaXRpb24ubWV0cmljKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgYWxhcm0uYWxhcm1EZWZpbml0aW9uLm1ldHJpYy5zdGF0aXN0aWMgPT09IFN0YXRzLlNVTSB8fFxuICAgICAgICAgICAgYWxhcm0uYWxhcm1EZWZpbml0aW9uLm1ldHJpYy5zdGF0aXN0aWMgPT09IFN0YXRzLlNBTVBMRV9DT1VOVFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY2xvbmVUaHJlc2hvbGQgPSBjbG9uZVRocmVzaG9sZCAvIGRhdGFwb2ludFNjYWxlRmFjdG9yO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNsb25lRXZhbHVhdGlvblBlcmlvZHMgPSBNYXRoLm1heCgxLCBNYXRoLnJvdW5kKGNsb25lRXZhbHVhdGlvblBlcmlvZHMpKTtcbiAgICBjbG9uZURhdGFwb2ludHNUb0FsYXJtID0gTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChjbG9uZURhdGFwb2ludHNUb0FsYXJtKSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uYWxhcm0uYWxhcm1EZWZpbml0aW9uLmFkZEFsYXJtUHJvcHMsXG4gICAgICBkaXNhbWJpZ3VhdG9yOiBwcm9wcy5kaXNhbWJpZ3VhdG9yLFxuICAgICAgdGhyZXNob2xkOiBjbG9uZVRocmVzaG9sZCxcbiAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiBjbG9uZUV2YWx1YXRpb25QZXJpb2RzLFxuICAgICAgZGF0YXBvaW50c1RvQWxhcm06IGNsb25lRGF0YXBvaW50c1RvQWxhcm0sXG4gICAgICBwZXJpb2Q6IGNsb25lUGVyaW9kLFxuICAgIH07XG4gIH07XG59XG5cbmZ1bmN0aW9uIGZpbmROZXh0U21hbGxlc3RQZXJpb2Qob3JpZ2luYWxQZXJpb2Q6IER1cmF0aW9uKSB7XG4gIGZvciAobGV0IGluZGV4ID0gU3VwcG9ydGVkTWV0cmljUGVyaW9kcy5sZW5ndGggLSAxOyBpbmRleCA+PSAwOyBpbmRleC0tKSB7XG4gICAgY29uc3QgY3VycmVudCA9IFN1cHBvcnRlZE1ldHJpY1BlcmlvZHNbaW5kZXhdO1xuICAgIGlmIChjdXJyZW50LnRvU2Vjb25kcygpIDwgb3JpZ2luYWxQZXJpb2QudG9TZWNvbmRzKCkpIHtcbiAgICAgIHJldHVybiBjdXJyZW50O1xuICAgIH1cbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuIl19