cdk-nag
Version:
Check CDK v2 applications for best practices using a combination on available rule packs.
164 lines • 25.4 kB
JavaScript
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.NagPack = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
const aws_cdk_lib_1 = require("aws-cdk-lib");
const ignore_suppression_conditions_1 = require("./ignore-suppression-conditions");
const nag_logger_1 = require("./nag-logger");
const nag_rules_1 = require("./nag-rules");
const nag_suppression_helper_1 = require("./utils/nag-suppression-helper");
/**
* Base class for all rule packs.
*/
class NagPack {
constructor(props) {
this.loggers = new Array();
this.packName = '';
this.userGlobalSuppressionIgnore = props?.suppressionIgnoreCondition;
this.loggers.push(new nag_logger_1.AnnotationLogger({
verbose: props?.verbose,
logIgnores: props?.logIgnores,
}));
if (props?.reports ?? true) {
const formats = props?.reportFormats
? props.reportFormats
: [nag_logger_1.NagReportFormat.CSV];
this.loggers.push(new nag_logger_1.NagReportLogger({ formats }));
}
if (props?.additionalLoggers) {
this.loggers.push(...props.additionalLoggers);
}
}
get readPackName() {
return this.packName;
}
/**
* Create a rule to be used in the NagPack.
* @param params The @IApplyRule interface with rule details.
*/
applyRule(params) {
if (this.packName === '') {
throw Error('The NagPack does not have a pack name, therefore the rule could not be applied. Set a packName in the NagPack constructor.');
}
const allSuppressions = nag_suppression_helper_1.NagSuppressionHelper.getSuppressions(params.node);
const ruleSuffix = params.ruleSuffixOverride
? params.ruleSuffixOverride
: params.rule.name;
const ruleId = `${this.packName}-${ruleSuffix}`;
const base = {
nagPackName: this.packName,
resource: params.node,
ruleId: ruleId,
ruleOriginalName: params.rule.name,
ruleInfo: params.info,
ruleExplanation: params.explanation,
ruleLevel: params.level,
};
try {
const ruleCompliance = params.rule(params.node);
if (ruleCompliance === nag_rules_1.NagRuleCompliance.COMPLIANT) {
this.loggers.forEach((t) => t.onCompliance(base));
}
else if (this.isNonCompliant(ruleCompliance)) {
const findings = this.asFindings(ruleCompliance);
for (const findingId of findings) {
const suppressionReason = this.ignoreRule(allSuppressions, ruleId, findingId, params.node, params.level, params.ignoreSuppressionCondition);
if (suppressionReason) {
this.loggers.forEach((t) => t.onSuppressed({
...base,
suppressionReason,
findingId,
}));
}
else {
this.loggers.forEach((t) => t.onNonCompliance({
...base,
findingId,
}));
}
}
}
else if (ruleCompliance === nag_rules_1.NagRuleCompliance.NOT_APPLICABLE) {
this.loggers.forEach((t) => t.onNotApplicable({
...base,
}));
}
}
catch (error) {
const reason = this.ignoreRule(allSuppressions, ruleId, '', params.node, params.level, params.ignoreSuppressionCondition, true);
if (reason) {
this.loggers.forEach((t) => t.onSuppressedError({
...base,
errorMessage: error.message,
errorSuppressionReason: reason,
}));
}
else {
this.loggers.forEach((t) => t.onError({
...base,
errorMessage: error.message,
}));
}
}
}
/**
* Check whether a specific rule should be ignored.
* @param suppressions The suppressions listed in the cdk-nag metadata.
* @param ruleId The id of the rule to ignore.
* @param resource The resource being evaluated.
* @param findingId The id of the finding that is being checked.
* @param validationFailure Whether the rule is being checked due to a validation failure.
* @returns The reason the rule was ignored, or an empty string.
*/
ignoreRule(suppressions, ruleId, findingId, resource, level, ignoreSuppressionCondition, validationFailure = false) {
for (let suppression of suppressions) {
if (nag_suppression_helper_1.NagSuppressionHelper.doesApply(suppression, ruleId, findingId) ||
// If this is marked as an exception, also check for a suppression on VALIDATION_FAILURE_ID
(validationFailure &&
nag_suppression_helper_1.NagSuppressionHelper.doesApply(suppression, nag_rules_1.VALIDATION_FAILURE_ID, ruleId))) {
const ignoreMessage = new ignore_suppression_conditions_1.SuppressionIgnoreOr(this.userGlobalSuppressionIgnore ?? new ignore_suppression_conditions_1.SuppressionIgnoreNever(), this.packGlobalSuppressionIgnore ?? new ignore_suppression_conditions_1.SuppressionIgnoreNever(), ignoreSuppressionCondition ?? new ignore_suppression_conditions_1.SuppressionIgnoreNever()).createMessage({
resource,
reason: suppression.reason,
ruleId,
findingId,
ruleLevel: level,
});
if (ignoreMessage) {
let id = findingId ? `${ruleId}[${findingId}]` : `${ruleId}`;
aws_cdk_lib_1.Annotations.of(resource).addInfo(`The suppression for ${id} was ignored for the following reason(s).\n\t${ignoreMessage}`);
}
else {
if (!suppression.appliesTo) {
// the rule is not granular so it always applies
return suppression.reason;
}
else {
return `[${findingId}] ${suppression.reason}`;
}
}
}
}
return '';
}
isNonCompliant(ruleResult) {
return (ruleResult === nag_rules_1.NagRuleCompliance.NON_COMPLIANT ||
Array.isArray(ruleResult));
}
asFindings(ruleResult) {
if (Array.isArray(ruleResult)) {
return ruleResult;
}
else {
return [''];
}
}
}
exports.NagPack = NagPack;
_a = JSII_RTTI_SYMBOL_1;
NagPack[_a] = { fqn: "cdk-nag.NagPack", version: "2.36.41" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFnLXBhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmFnLXBhY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQTs7O0VBR0U7QUFDRiw2Q0FBZ0U7QUFFaEUsbUZBSXlDO0FBRXpDLDZDQU1zQjtBQUN0QiwyQ0FNcUI7QUFDckIsMkVBQXNFO0FBd0V0RTs7R0FFRztBQUNILE1BQXNCLE9BQU87SUFNM0IsWUFBWSxLQUFvQjtRQUx0QixZQUFPLEdBQUcsSUFBSSxLQUFLLEVBQWMsQ0FBQztRQUNsQyxhQUFRLEdBQUcsRUFBRSxDQUFDO1FBS3RCLElBQUksQ0FBQywyQkFBMkIsR0FBRyxLQUFLLEVBQUUsMEJBQTBCLENBQUM7UUFDckUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQ2YsSUFBSSw2QkFBZ0IsQ0FBQztZQUNuQixPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU87WUFDdkIsVUFBVSxFQUFFLEtBQUssRUFBRSxVQUFVO1NBQzlCLENBQUMsQ0FDSCxDQUFDO1FBQ0YsSUFBSSxLQUFLLEVBQUUsT0FBTyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQzNCLE1BQU0sT0FBTyxHQUFHLEtBQUssRUFBRSxhQUFhO2dCQUNsQyxDQUFDLENBQUMsS0FBSyxDQUFDLGFBQWE7Z0JBQ3JCLENBQUMsQ0FBQyxDQUFDLDRCQUFlLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDMUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSw0QkFBZSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3RELENBQUM7UUFDRCxJQUFJLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDaEQsQ0FBQztJQUNILENBQUM7SUFFRCxJQUFXLFlBQVk7UUFDckIsT0FBTyxJQUFJLENBQUMsUUFB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VSxDQUFDO1FBQ3BCLENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7O0FBck1ILDBCQXNNQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4qL1xuaW1wb3J0IHsgQW5ub3RhdGlvbnMsIENmblJlc291cmNlLCBJQXNwZWN0IH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgSUNvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHtcbiAgSU5hZ1N1cHByZXNzaW9uSWdub3JlLFxuICBTdXBwcmVzc2lvbklnbm9yZU5ldmVyLFxuICBTdXBwcmVzc2lvbklnbm9yZU9yLFxufSBmcm9tICcuL2lnbm9yZS1zdXBwcmVzc2lvbi1jb25kaXRpb25zJztcbmltcG9ydCB7IE5hZ1BhY2tTdXBwcmVzc2lvbiB9IGZyb20gJy4vbW9kZWxzL25hZy1zdXBwcmVzc2lvbic7XG5pbXBvcnQge1xuICBBbm5vdGF0aW9uTG9nZ2VyLFxuICBJTmFnTG9nZ2VyLFxuICBOYWdMb2dnZXJCYXNlRGF0YSxcbiAgTmFnUmVwb3J0Rm9ybWF0LFxuICBOYWdSZXBvcnRMb2dnZXIsXG59IGZyb20gJy4vbmFnLWxvZ2dlcic7XG5pbXBvcnQge1xuICBOYWdNZXNzYWdlTGV2ZWwsXG4gIE5hZ1J1bGVDb21wbGlhbmNlLFxuICBOYWdSdWxlRmluZGluZ3MsXG4gIE5hZ1J1bGVSZXN1bHQsXG4gIFZBTElEQVRJT05fRkFJTFVSRV9JRCxcbn0gZnJvbSAnLi9uYWctcnVsZXMnO1xuaW1wb3J0IHsgTmFnU3VwcHJlc3Npb25IZWxwZXIgfSBmcm9tICcuL3V0aWxzL25hZy1zdXBwcmVzc2lvbi1oZWxwZXInO1xuXG4vKipcbiAqIEludGVyZmFjZSBmb3IgY3JlYXRpbmcgYSBOYWdQYWNrLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5hZ1BhY2tQcm9wcyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIG9yIG5vdCB0byBlbmFibGUgZXh0ZW5kZWQgZXhwbGFuYXRvcnkgZGVzY3JpcHRpb25zIG9uIHdhcm5pbmcsIGVycm9yLCBhbmQgbG9nZ2VkIGlnbm9yZSBtZXNzYWdlcyAoZGVmYXVsdDogZmFsc2UpLlxuICAgKi9cbiAgcmVhZG9ubHkgdmVyYm9zZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgb3Igbm90IHRvIGxvZyBzdXBwcmVzc2VkIHJ1bGUgdmlvbGF0aW9ucyBhcyBpbmZvcm1hdGlvbmFsIG1lc3NhZ2VzIChkZWZhdWx0OiBmYWxzZSkuXG4gICAqL1xuICByZWFkb25seSBsb2dJZ25vcmVzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciBvciBub3QgdG8gZ2VuZXJhdGUgY29tcGxpYW5jZSByZXBvcnRzIGZvciBhcHBsaWVkIFN0YWNrcyBpbiB0aGUgQXBwJ3Mgb3V0cHV0IGRpcmVjdG9yeSAoZGVmYXVsdDogdHJ1ZSkuXG4gICAqL1xuICByZWFkb25seSByZXBvcnRzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogSWYgcmVwb3J0cyBhcmUgZW5hYmxlZCwgdGhlIG91dHB1dCBmb3JtYXRzIG9mIGNvbXBsaWFuY2UgcmVwb3J0cyBpbiB0aGUgQXBwJ3Mgb3V0cHV0IGRpcmVjdG9yeSAoZGVmYXVsdDogb25seSBDU1YpLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVwb3J0Rm9ybWF0cz86IE5hZ1JlcG9ydEZvcm1hdFtdO1xuXG4gIC8qKlxuICAgKiBDb25kaXRpb25hbGx5IHByZXZlbnQgcnVsZXMgZnJvbSBiZWluZyBzdXBwcmVzc2VkIChkZWZhdWx0OiBubyB1c2VyIHByb3ZpZGVkIGNvbmRpdGlvbikuXG4gICAqL1xuICByZWFkb25seSBzdXBwcmVzc2lvbklnbm9yZUNvbmRpdGlvbj86IElOYWdTdXBwcmVzc2lvbklnbm9yZTtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBOYWdMb2dnZXJzIGZvciBsb2dnaW5nIHJ1bGUgdmFsaWRhdGlvbiBvdXRwdXRzLlxuICAgKi9cbiAgcmVhZG9ubHkgYWRkaXRpb25hbExvZ2dlcnM/OiBJTmFnTG9nZ2VyW107XG59XG5cbi8qKlxuICogSW50ZXJmYWNlIGZvciBKU0lJIGludGVyb3BlcmFiaWxpdHkgZm9yIHBhc3NpbmcgcGFyYW1ldGVycyBhbmQgdGhlIFJ1bGUgQ2FsbGJhY2sgdG8gQGFwcGx5UnVsZSBtZXRob2QuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSUFwcGx5UnVsZSB7XG4gIC8qKlxuICAgKiBPdmVycmlkZSBmb3IgdGhlIHN1ZmZpeCBvZiB0aGUgUnVsZSBJRCBmb3IgdGhpcyBydWxlXG4gICAqL1xuICBydWxlU3VmZml4T3ZlcnJpZGU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBXaHkgdGhlIHJ1bGUgd2FzIHRyaWdnZXJlZC5cbiAgICovXG4gIGluZm86IHN0cmluZztcbiAgLyoqXG4gICAqIFdoeSB0aGUgcnVsZSBleGlzdHMuXG4gICAqL1xuICBleHBsYW5hdGlvbjogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGFubm90YXRpb25zIG1lc3NhZ2UgbGV2ZWwgdG8gYXBwbHkgdG8gdGhlIHJ1bGUgaWYgdHJpZ2dlcmVkLlxuICAgKi9cbiAgbGV2ZWw6IE5hZ01lc3NhZ2VMZXZlbDtcbiAgLyoqXG4gICAqIEEgY29uZGl0aW9uIGluIHdoaWNoIGEgc3VwcHJlc3Npb24gc2hvdWxkIGJlIGlnbm9yZWQuXG4gICAqL1xuICBpZ25vcmVTdXBwcmVzc2lvbkNvbmRpdGlvbj86IElOYWdTdXBwcmVzc2lvbklnbm9yZTtcbiAgLyoqXG4gICAqIFRoZSBDZm5SZXNvdXJjZSB0byBjaGVja1xuICAgKi9cbiAgbm9kZTogQ2ZuUmVzb3VyY2U7XG4gIC8qKlxuICAgKiBUaGUgY2FsbGJhY2sgdG8gdGhlIHJ1bGUuXG4gICAqIEBwYXJhbSBub2RlIFRoZSBDZm5SZXNvdXJjZSB0byBjaGVjay5cbiAgICovXG4gIHJ1bGUobm9kZTogQ2ZuUmVzb3VyY2UpOiBOYWdSdWxlUmVzdWx0O1xufVxuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGFsbCBydWxlIHBhY2tzLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgTmFnUGFjayBpbXBsZW1lbnRzIElBc3BlY3Qge1xuICBwcm90ZWN0ZWQgbG9nZ2VycyA9IG5ldyBBcnJheTxJTmFnTG9nZ2VyPigpO1xuICBwcm90ZWN0ZWQgcGFja05hbWUgPSAnJztcbiAgcHJvdGVjdGVkIHVzZXJHbG9iYWxTdXBwcmVzc2lvbklnbm9yZT86IElOYWdTdXBwcmVzc2lvbklnbm9yZTtcbiAgcHJvdGVjdGVkIHBhY2tHbG9iYWxTdXBwcmVzc2lvbklnbm9yZT86IElOYWdTdXBwcmVzc2lvbklnbm9yZTtcblxuICBjb25zdHJ1Y3Rvcihwcm9wcz86IE5hZ1BhY2tQcm9wcykge1xuICAgIHRoaXMudXNlckdsb2JhbFN1cHByZXNzaW9uSWdub3JlID0gcHJvcHM/LnN1cHByZXNzaW9uSWdub3JlQ29uZGl0aW9uO1xuICAgIHRoaXMubG9nZ2Vycy5wdXNoKFxuICAgICAgbmV3IEFubm90YXRpb25Mb2dnZXIoe1xuICAgICAgICB2ZXJib3NlOiBwcm9wcz8udmVyYm9zZSxcbiAgICAgICAgbG9nSWdub3JlczogcHJvcHM/LmxvZ0lnbm9yZXMsXG4gICAgICB9KVxuICAgICk7XG4gICAgaWYgKHByb3BzPy5yZXBvcnRzID8/IHRydWUpIHtcbiAgICAgIGNvbnN0IGZvcm1hdHMgPSBwcm9wcz8ucmVwb3J0Rm9ybWF0c1xuICAgICAgICA/IHByb3BzLnJlcG9ydEZvcm1hdHNcbiAgICAgICAgOiBbTmFnUmVwb3J0Rm9ybWF0LkNTVl07XG4gICAgICB0aGlzLmxvZ2dlcnMucHVzaChuZXcgTmFnUmVwb3J0TG9nZ2VyKHsgZm9ybWF0cyB9KSk7XG4gICAgfVxuICAgIGlmIChwcm9wcz8uYWRkaXRpb25hbExvZ2dlcnMpIHtcbiAgICAgIHRoaXMubG9nZ2Vycy5wdXNoKC4uLnByb3BzLmFkZGl0aW9uYWxMb2dnZXJzKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0IHJlYWRQYWNrTmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnBhY2tOYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIEFsbCBhc3BlY3RzIGNhbiB2aXNpdCBhbiBJQ29uc3RydWN0LlxuICAgKi9cbiAgcHVibGljIGFic3RyYWN0IHZpc2l0KG5vZGU6IElDb25zdHJ1Y3QpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBydWxlIHRvIGJlIHVzZWQgaW4gdGhlIE5hZ1BhY2suXG4gICAqIEBwYXJhbSBwYXJhbXMgVGhlIEBJQXBwbHlSdWxlIGludGVyZmFjZSB3aXRoIHJ1bGUgZGV0YWlscy5cbiAgICovXG4gIHByb3RlY3RlZCBhcHBseVJ1bGUocGFyYW1zOiBJQXBwbHlSdWxlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucGFja05hbWUgPT09ICcnKSB7XG4gICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgJ1RoZSBOYWdQYWNrIGRvZXMgbm90IGhhdmUgYSBwYWNrIG5hbWUsIHRoZXJlZm9yZSB0aGUgcnVsZSBjb3VsZCBub3QgYmUgYXBwbGllZC4gU2V0IGEgcGFja05hbWUgaW4gdGhlIE5hZ1BhY2sgY29uc3RydWN0b3IuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgYWxsU3VwcHJlc3Npb25zID0gTmFnU3VwcHJlc3Npb25IZWxwZXIuZ2V0U3VwcHJlc3Npb25zKHBhcmFtcy5ub2RlKTtcbiAgICBjb25zdCBydWxlU3VmZml4ID0gcGFyYW1zLnJ1bGVTdWZmaXhPdmVycmlkZVxuICAgICAgPyBwYXJhbXMucnVsZVN1ZmZpeE92ZXJyaWRlXG4gICAgICA6IHBhcmFtcy5ydWxlLm5hbWU7XG4gICAgY29uc3QgcnVsZUlkID0gYCR7dGhpcy5wYWNrTmFtZX0tJHtydWxlU3VmZml4fWA7XG4gICAgY29uc3QgYmFzZTogTmFnTG9nZ2VyQmFzZURhdGEgPSB7XG4gICAgICBuYWdQYWNrTmFtZTogdGhpcy5wYWNrTmFtZSxcbiAgICAgIHJlc291cmNlOiBwYXJhbXMubm9kZSxcbiAgICAgIHJ1bGVJZDogcnVsZUlkLFxuICAgICAgcnVsZU9yaWdpbmFsTmFtZTogcGFyYW1zLnJ1bGUubmFtZSxcbiAgICAgIHJ1bGVJbmZvOiBwYXJhbXMuaW5mbyxcbiAgICAgIHJ1bGVFeHBsYW5hdGlvbjogcGFyYW1zLmV4cGxhbmF0aW9uLFxuICAgICAgcnVsZUxldmVsOiBwYXJhbXMubGV2ZWwsXG4gICAgfTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcnVsZUNvbXBsaWFuY2UgPSBwYXJhbXMucnVsZShwYXJhbXMubm9kZSk7XG4gICAgICBpZiAocnVsZUNvbXBsaWFuY2UgPT09IE5hZ1J1bGVDb21wbGlhbmNlLkNPTVBMSUFOVCkge1xuICAgICAgICB0aGlzLmxvZ2dlcnMuZm9yRWFjaCgodCkgPT4gdC5vbkNvbXBsaWFuY2UoYmFzZSkpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmlzTm9uQ29tcGxpYW50KHJ1bGVDb21wbGlhbmNlKSkge1xuICAgICAgICBjb25zdCBmaW5kaW5ncyA9IHRoaXMuYXNGaW5kaW5ncyhydWxlQ29tcGxpYW5jZSk7XG4gICAgICAgIGZvciAoY29uc3QgZmluZGluZ0lkIG9mIGZpbmRpbmdzKSB7XG4gICAgICAgICAgY29uc3Qgc3VwcHJlc3Npb25SZWFzb24gPSB0aGlzLmlnbm9yZVJ1bGUoXG4gICAgICAgICAgICBhbGxTdXBwcmVzc2lvbnMsXG4gICAgICAgICAgICBydWxlSWQsXG4gICAgICAgICAgICBmaW5kaW5nSWQsXG4gICAgICAgICAgICBwYXJhbXMubm9kZSxcbiAgICAgICAgICAgIHBhcmFtcy5sZXZlbCxcbiAgICAgICAgICAgIHBhcmFtcy5pZ25vcmVTdXBwcmVzc2lvbkNvbmRpdGlvblxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHN1cHByZXNzaW9uUmVhc29uKSB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlcnMuZm9yRWFjaCgodCkgPT5cbiAgICAgICAgICAgICAgdC5vblN1cHByZXNzZWQoe1xuICAgICAgICAgICAgICAgIC4uLmJhc2UsXG4gICAgICAgICAgICAgICAgc3VwcHJlc3Npb25SZWFzb24sXG4gICAgICAgICAgICAgICAgZmluZGluZ0lkLFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXJzLmZvckVhY2goKHQpID0+XG4gICAgICAgICAgICAgIHQub25Ob25Db21wbGlhbmNlKHtcbiAgICAgICAgICAgICAgICAuLi5iYXNlLFxuICAgICAgICAgICAgICAgIGZpbmRpbmdJZCxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHJ1bGVDb21wbGlhbmNlID09PSBOYWdSdWxlQ29tcGxpYW5jZS5OT1RfQVBQTElDQUJMRSkge1xuICAgICAgICB0aGlzLmxvZ2dlcnMuZm9yRWFjaCgodCkgPT5cbiAgICAgICAgICB0Lm9uTm90QXBwbGljYWJsZSh7XG4gICAgICAgICAgICAuLi5iYXNlLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IHJlYXNvbiA9IHRoaXMuaWdub3JlUnVsZShcbiAgICAgICAgYWxsU3VwcHJlc3Npb25zLFxuICAgICAgICBydWxlSWQsXG4gICAgICAgICcnLFxuICAgICAgICBwYXJhbXMubm9kZSxcbiAgICAgICAgcGFyYW1zLmxldmVsLFxuICAgICAgICBwYXJhbXMuaWdub3JlU3VwcHJlc3Npb25Db25kaXRpb24sXG4gICAgICAgIHRydWVcbiAgICAgICk7XG4gICAgICBpZiAocmVhc29uKSB7XG4gICAgICAgIHRoaXMubG9nZ2Vycy5mb3JFYWNoKCh0KSA9PlxuICAgICAgICAgIHQub25TdXBwcmVzc2VkRXJyb3Ioe1xuICAgICAgICAgICAgLi4uYmFzZSxcbiAgICAgICAgICAgIGVycm9yTWVzc2FnZTogKGVycm9yIGFzIEVycm9yKS5tZXNzYWdlLFxuICAgICAgICAgICAgZXJyb3JTdXBwcmVzc2lvblJlYXNvbjogcmVhc29uLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxvZ2dlcnMuZm9yRWFjaCgodCkgPT5cbiAgICAgICAgICB0Lm9uRXJyb3Ioe1xuICAgICAgICAgICAgLi4uYmFzZSxcbiAgICAgICAgICAgIGVycm9yTWVzc2FnZTogKGVycm9yIGFzIEVycm9yKS5tZXNzYWdlLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIHdoZXRoZXIgYSBzcGVjaWZpYyBydWxlIHNob3VsZCBiZSBpZ25vcmVkLlxuICAgKiBAcGFyYW0gc3VwcHJlc3Npb25zIFRoZSBzdXBwcmVzc2lvbnMgbGlzdGVkIGluIHRoZSBjZGstbmFnIG1ldGFkYXRhLlxuICAgKiBAcGFyYW0gcnVsZUlkIFRoZSBpZCBvZiB0aGUgcnVsZSB0byBpZ25vcmUuXG4gICAqIEBwYXJhbSByZXNvdXJjZSBUaGUgcmVzb3VyY2UgYmVpbmcgZXZhbHVhdGVkLlxuICAgKiBAcGFyYW0gZmluZGluZ0lkIFRoZSBpZCBvZiB0aGUgZmluZGluZyB0aGF0IGlzIGJlaW5nIGNoZWNrZWQuXG4gICAqIEBwYXJhbSB2YWxpZGF0aW9uRmFpbHVyZSBXaGV0aGVyIHRoZSBydWxlIGlzIGJlaW5nIGNoZWNrZWQgZHVlIHRvIGEgdmFsaWRhdGlvbiBmYWlsdXJlLlxuICAgKiBAcmV0dXJucyBUaGUgcmVhc29uIHRoZSBydWxlIHdhcyBpZ25vcmVkLCBvciBhbiBlbXB0eSBzdHJpbmcuXG4gICAqL1xuICBwcm90ZWN0ZWQgaWdub3JlUnVsZShcbiAgICBzdXBwcmVzc2lvbnM6IE5hZ1BhY2tTdXBwcmVzc2lvbltdLFxuICAgIHJ1bGVJZDogc3RyaW5nLFxuICAgIGZpbmRpbmdJZDogc3RyaW5nLFxuICAgIHJlc291cmNlOiBDZm5SZXNvdXJjZSxcbiAgICBsZXZlbDogTmFnTWVzc2FnZUxldmVsLFxuICAgIGlnbm9yZVN1cHByZXNzaW9uQ29uZGl0aW9uPzogSU5hZ1N1cHByZXNzaW9uSWdub3JlLFxuICAgIHZhbGlkYXRpb25GYWlsdXJlOiBib29sZWFuID0gZmFsc2VcbiAgKTogc3RyaW5nIHtcbiAgICBmb3IgKGxldCBzdXBwcmVzc2lvbiBvZiBzdXBwcmVzc2lvbnMpIHtcbiAgICAgIGlmIChcbiAgICAgICAgTmFnU3VwcHJlc3Npb25IZWxwZXIuZG9lc0FwcGx5KHN1cHByZXNzaW9uLCBydWxlSWQsIGZpbmRpbmdJZCkgfHxcbiAgICAgICAgLy8gSWYgdGhpcyBpcyBtYXJrZWQgYXMgYW4gZXhjZXB0aW9uLCBhbHNvIGNoZWNrIGZvciBhIHN1cHByZXNzaW9uIG9uIFZBTElEQVRJT05fRkFJTFVSRV9JRFxuICAgICAgICAodmFsaWRhdGlvbkZhaWx1cmUgJiZcbiAgICAgICAgICBOYWdTdXBwcmVzc2lvbkhlbHBlci5kb2VzQXBwbHkoXG4gICAgICAgICAgICBzdXBwcmVzc2lvbixcbiAgICAgICAgICAgIFZBTElEQVRJT05fRkFJTFVSRV9JRCxcbiAgICAgICAgICAgIHJ1bGVJZFxuICAgICAgICAgICkpXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgaWdub3JlTWVzc2FnZSA9IG5ldyBTdXBwcmVzc2lvbklnbm9yZU9yKFxuICAgICAgICAgIHRoaXMudXNlckdsb2JhbFN1cHByZXNzaW9uSWdub3JlID8/IG5ldyBTdXBwcmVzc2lvbklnbm9yZU5ldmVyKCksXG4gICAgICAgICAgdGhpcy5wYWNrR2xvYmFsU3VwcHJlc3Npb25JZ25vcmUgPz8gbmV3IFN1cHByZXNzaW9uSWdub3JlTmV2ZXIoKSxcbiAgICAgICAgICBpZ25vcmVTdXBwcmVzc2lvbkNvbmRpdGlvbiA/PyBuZXcgU3VwcHJlc3Npb25JZ25vcmVOZXZlcigpXG4gICAgICAgICkuY3JlYXRlTWVzc2FnZSh7XG4gICAgICAgICAgcmVzb3VyY2UsXG4gICAgICAgICAgcmVhc29uOiBzdXBwcmVzc2lvbi5yZWFzb24sXG4gICAgICAgICAgcnVsZUlkLFxuICAgICAgICAgIGZpbmRpbmdJZCxcbiAgICAgICAgICBydWxlTGV2ZWw6IGxldmVsLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGlnbm9yZU1lc3NhZ2UpIHtcbiAgICAgICAgICBsZXQgaWQgPSBmaW5kaW5nSWQgPyBgJHtydWxlSWR9WyR7ZmluZGluZ0lkfV1gIDogYCR7cnVsZUlkfWA7XG4gICAgICAgICAgQW5ub3RhdGlvbnMub2YocmVzb3VyY2UpLmFkZEluZm8oXG4gICAgICAgICAgICBgVGhlIHN1cHByZXNzaW9uIGZvciAke2lkfSB3YXMgaWdub3JlZCBmb3IgdGhlIGZvbGxvd2luZyByZWFzb24ocykuXFxuXFx0JHtpZ25vcmVNZXNzYWdlfWBcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICghc3VwcHJlc3Npb24uYXBwbGllc1RvKSB7XG4gICAgICAgICAgICAvLyB0aGUgcnVsZSBpcyBub3QgZ3JhbnVsYXIgc28gaXQgYWx3YXlzIGFwcGxpZXNcbiAgICAgICAgICAgIHJldHVybiBzdXBwcmVzc2lvbi5yZWFzb247XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBgWyR7ZmluZGluZ0lkfV0gJHtzdXBwcmVzc2lvbi5yZWFzb259YDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgcHJpdmF0ZSBpc05vbkNvbXBsaWFudChydWxlUmVzdWx0OiBOYWdSdWxlUmVzdWx0KSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHJ1bGVSZXN1bHQgPT09IE5hZ1J1bGVDb21wbGlhbmNlLk5PTl9DT01QTElBTlQgfHxcbiAgICAgIEFycmF5LmlzQXJyYXkocnVsZVJlc3VsdClcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc0ZpbmRpbmdzKHJ1bGVSZXN1bHQ6IE5hZ1J1bGVSZXN1bHQpOiBOYWdSdWxlRmluZGluZ3Mge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHJ1bGVSZXN1bHQpKSB7XG4gICAgICByZXR1cm4gcnVsZVJlc3VsdDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFsnJ107XG4gICAgfVxuICB9XG59XG4iXX0=
;