aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
96 lines • 16 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.findCloudWatchLogGroups = findCloudWatchLogGroups;
const logging_1 = require("../../logging");
const error_1 = require("../../util/error");
const environment_access_1 = require("../environment-access");
const evaluate_cloudformation_template_1 = require("../evaluate-cloudformation-template");
const mode_1 = require("../plugin/mode");
const toolkit_info_1 = require("../toolkit-info");
// resource types that have associated CloudWatch Log Groups that should _not_ be monitored
const IGNORE_LOGS_RESOURCE_TYPES = ['AWS::EC2::FlowLog', 'AWS::CloudTrail::Trail', 'AWS::CodeBuild::Project'];
async function findCloudWatchLogGroups(sdkProvider, stackArtifact) {
let sdk;
const resolvedEnv = await sdkProvider.resolveEnvironment(stackArtifact.environment);
// try to assume the lookup role and fallback to the default credentials
try {
sdk = (await new environment_access_1.EnvironmentAccess(sdkProvider, toolkit_info_1.DEFAULT_TOOLKIT_STACK_NAME).accessStackForLookup(stackArtifact)).sdk;
}
catch (e) {
(0, logging_1.debug)(`Failed to access SDK environment: ${(0, error_1.formatErrorMessage)(e)}`);
sdk = (await sdkProvider.forEnvironment(resolvedEnv, mode_1.Mode.ForReading)).sdk;
}
const listStackResources = new evaluate_cloudformation_template_1.LazyListStackResources(sdk, stackArtifact.stackName);
const evaluateCfnTemplate = new evaluate_cloudformation_template_1.EvaluateCloudFormationTemplate({
stackName: stackArtifact.stackName,
template: stackArtifact.template,
parameters: {},
account: resolvedEnv.account,
region: resolvedEnv.region,
partition: (await sdk.currentAccount()).partition,
sdk,
});
const stackResources = await listStackResources.listStackResources();
const logGroupNames = findAllLogGroupNames(stackResources, evaluateCfnTemplate);
return {
env: resolvedEnv,
sdk,
logGroupNames,
};
}
/**
* Determine if a CloudWatch Log Group is associated
* with an ignored resource
*/
function isReferencedFromIgnoredResource(logGroupResource, evaluateCfnTemplate) {
const resourcesReferencingLogGroup = evaluateCfnTemplate.findReferencesTo(logGroupResource.LogicalResourceId);
return resourcesReferencingLogGroup.some((reference) => {
return IGNORE_LOGS_RESOURCE_TYPES.includes(reference.Type);
});
}
const cloudWatchLogsResolvers = {
'AWS::Logs::LogGroup': (resource, evaluateCfnTemplate) => {
if (isReferencedFromIgnoredResource(resource, evaluateCfnTemplate)) {
return undefined;
}
return resource.PhysicalResourceId?.toString();
},
// Resource types that will create a CloudWatch log group with a specific name if one is not provided.
// The keys are CFN resource types, and the values are the name of the physical name property of that resource
// and the service name that is used in the automatically created CloudWatch log group.
'AWS::Lambda::Function': (resource, evaluateCfnTemplate) => {
const loggingConfig = evaluateCfnTemplate.getResourceProperty(resource.LogicalResourceId, 'LoggingConfig');
if (loggingConfig?.LogGroup) {
// if LogGroup is a string then use it as the LogGroupName as it is referred by LogGroup.fromLogGroupArn in CDK
if (typeof loggingConfig.LogGroup === 'string') {
return loggingConfig.LogGroup;
}
// if { Ref: '...' } is used then try to resolve the LogGroupName from the referenced resource in the template
if (typeof loggingConfig.LogGroup === 'object') {
if (loggingConfig.LogGroup.Ref) {
return evaluateCfnTemplate.getResourceProperty(loggingConfig.LogGroup.Ref, 'LogGroupName');
}
}
}
return `/aws/lambda/${resource.PhysicalResourceId}`;
},
};
/**
* Find all CloudWatch Log Groups in the deployed template.
* This will find both explicitly created Log Groups (excluding those associated with ignored resources)
* and Log Groups created implicitly (i.e. Lambda Functions)
*/
function findAllLogGroupNames(stackResources, evaluateCfnTemplate) {
const logGroupNames = [];
for (const resource of stackResources) {
const logGroupResolver = cloudWatchLogsResolvers[resource.ResourceType];
if (logGroupResolver) {
const logGroupName = logGroupResolver(resource, evaluateCfnTemplate);
if (logGroupName) {
logGroupNames.push(logGroupName);
}
}
}
return logGroupNames;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmluZC1jbG91ZHdhdGNoLWxvZ3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJmaW5kLWNsb3Vkd2F0Y2gtbG9ncy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXFDQSwwREFpQ0M7QUFwRUQsMkNBQXNDO0FBQ3RDLDRDQUFzRDtBQUV0RCw4REFBMEQ7QUFDMUQsMEZBQTZHO0FBQzdHLHlDQUFzQztBQUN0QyxrREFBNkQ7QUFFN0QsMkZBQTJGO0FBQzNGLE1BQU0sMEJBQTBCLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSx3QkFBd0IsRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO0FBMEJ2RyxLQUFLLFVBQVUsdUJBQXVCLENBQzNDLFdBQXdCLEVBQ3hCLGFBQTBDO0lBRTFDLElBQUksR0FBUSxDQUFDO0lBQ2IsTUFBTSxXQUFXLEdBQUcsTUFBTSxXQUFXLENBQUMsa0JBQWtCLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3BGLHdFQUF3RTtJQUN4RSxJQUFJLENBQUM7UUFDSCxHQUFHLEdBQUcsQ0FBQyxNQUFNLElBQUksc0NBQWlCLENBQUMsV0FBVyxFQUFFLHlDQUEwQixDQUFDLENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDdkgsQ0FBQztJQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7UUFDaEIsSUFBQSxlQUFLLEVBQUMscUNBQXFDLElBQUEsMEJBQWtCLEVBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3BFLEdBQUcsR0FBRyxDQUFDLE1BQU0sV0FBVyxDQUFDLGNBQWMsQ0FBQyxXQUFXLEVBQUUsV0FBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQzdFLENBQUM7SUFFRCxNQUFNLGtCQUFrQixHQUFHLElBQUkseURBQXNCLENBQUMsR0FBRyxFQUFFLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNwRixNQUFNLG1CQUFtQixHQUFHLElBQUksaUVBQThC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QUFZLEVBQUUsQ0FBQztnQkFDakIsYUFBYSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNuQyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLGFBQWEsQ0FBQztBQUN2QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBDbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QsIEVudmlyb25tZW50IH0gZnJvbSAnQGF3cy1jZGsvY3gtYXBpJztcbmltcG9ydCB0eXBlIHsgU3RhY2tSZXNvdXJjZVN1bW1hcnkgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtY2xvdWRmb3JtYXRpb24nO1xuaW1wb3J0IHsgZGVidWcgfSBmcm9tICcuLi8uLi9sb2dnaW5nJztcbmltcG9ydCB7IGZvcm1hdEVycm9yTWVzc2FnZSB9IGZyb20gJy4uLy4uL3V0aWwvZXJyb3InO1xuaW1wb3J0IHR5cGUgeyBTREssIFNka1Byb3ZpZGVyIH0gZnJvbSAnLi4vYXdzLWF1dGgnO1xuaW1wb3J0IHsgRW52aXJvbm1lbnRBY2Nlc3MgfSBmcm9tICcuLi9lbnZpcm9ubWVudC1hY2Nlc3MnO1xuaW1wb3J0IHsgRXZhbHVhdGVDbG91ZEZvcm1hdGlvblRlbXBsYXRlLCBMYXp5TGlzdFN0YWNrUmVzb3VyY2VzIH0gZnJvbSAnLi4vZXZhbHVhdGUtY2xvdWRmb3JtYXRpb24tdGVtcGxhdGUnO1xuaW1wb3J0IHsgTW9kZSB9IGZyb20gJy4uL3BsdWdpbi9tb2RlJztcbmltcG9ydCB7IERFRkFVTFRfVE9PTEtJVF9TVEFDS19OQU1FIH0gZnJvbSAnLi4vdG9vbGtpdC1pbmZvJztcblxuLy8gcmVzb3VyY2UgdHlwZXMgdGhhdCBoYXZlIGFzc29jaWF0ZWQgQ2xvdWRXYXRjaCBMb2cgR3JvdXBzIHRoYXQgc2hvdWxkIF9ub3RfIGJlIG1vbml0b3JlZFxuY29uc3QgSUdOT1JFX0xPR1NfUkVTT1VSQ0VfVFlQRVMgPSBbJ0FXUzo6RUMyOjpGbG93TG9nJywgJ0FXUzo6Q2xvdWRUcmFpbDo6VHJhaWwnLCAnQVdTOjpDb2RlQnVpbGQ6OlByb2plY3QnXTtcblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIG5lZWRlZCB0byBtb25pdG9yIENsb3VkV2F0Y2ggTG9nIEdyb3Vwc1xuICogZm91bmQgaW4gYSBnaXZlbiBDbG91ZEZvcm1hdGlvbiBTdGFja1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEZvdW5kTG9nR3JvdXBzUmVzdWx0IHtcbiAgLyoqXG4gICAqIFRoZSByZXNvbHZlZCBlbnZpcm9ubWVudCAoYWNjb3VudC9yZWdpb24pIHRoYXQgdGhlIGxvZ1xuICAgKiBncm91cHMgYXJlIGRlcGxveWVkIGluXG4gICAqL1xuICByZWFkb25seSBlbnY6IEVudmlyb25tZW50O1xuXG4gIC8qKlxuICAgKiBUaGUgU0RLIHRoYXQgY2FuIGJlIHVzZWQgdG8gcmVhZCBldmVudHMgZnJvbSB0aGUgQ2xvdWRXYXRjaFxuICAgKiBMb2cgR3JvdXBzIGluIHRoZSBnaXZlbiBlbnZpcm9ubWVudFxuICAgKi9cbiAgcmVhZG9ubHkgc2RrOiBTREs7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lcyBvZiB0aGUgcmVsZXZhbnQgQ2xvdWRXYXRjaCBMb2cgR3JvdXBzXG4gICAqIGluIHRoZSBnaXZlbiBDbG91ZEZvcm1hdGlvbiB0ZW1wbGF0ZVxuICAgKi9cbiAgcmVhZG9ubHkgbG9nR3JvdXBOYW1lczogc3RyaW5nW107XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmaW5kQ2xvdWRXYXRjaExvZ0dyb3VwcyhcbiAgc2RrUHJvdmlkZXI6IFNka1Byb3ZpZGVyLFxuICBzdGFja0FydGlmYWN0OiBDbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QsXG4pOiBQcm9taXNlPEZvdW5kTG9nR3JvdXBzUmVzdWx0PiB7XG4gIGxldCBzZGs6IFNESztcbiAgY29uc3QgcmVzb2x2ZWRFbnYgPSBhd2FpdCBzZGtQcm92aWRlci5yZXNvbHZlRW52aXJvbm1lbnQoc3RhY2tBcnRpZmFjdC5lbnZpcm9ubWVudCk7XG4gIC8vIHRyeSB0byBhc3N1bWUgdGhlIGxvb2t1cCByb2xlIGFuZCBmYWxsYmFjayB0byB0aGUgZGVmYXVsdCBjcmVkZW50aWFsc1xuICB0cnkge1xuICAgIHNkayA9IChhd2FpdCBuZXcgRW52aXJvbm1lbnRBY2Nlc3Moc2RrUHJvdmlkZXIsIERFRkFVTFRfVE9PTEtJVF9TVEFDS19OQU1FKS5hY2Nlc3NTdGFja0Zvckxvb2t1cChzdGFja0FydGlmYWN0KSkuc2RrO1xuICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICBkZWJ1ZyhgRmFpbGVkIHRvIGFjY2VzcyBTREsgZW52aXJvbm1lbnQ6ICR7Zm9ybWF0RXJyb3JNZXNzYWdlKGUpfWApO1xuICAgIHNkayA9IChhd2FpdCBzZGtQcm92aWRlci5mb3JFbnZpcm9ubWVudChyZXNvbHZlZEVudiwgTW9kZS5Gb3JSZWFkaW5nKSkuc2RrO1xuICB9XG5cbiAgY29uc3QgbGlzdFN0YWNrUmVzb3VyY2VzID0gbmV3IExhenlMaXN0U3RhY2tSZXNvdXJjZXMoc2RrLCBzdGFja0FydGlmYWN0LnN0YWNrTmFtZSk7XG4gIGNvbnN0IGV2YWx1YXRlQ2ZuVGVtcGxhdGUgPSBuZXcgRXZhbHVhdGVDbG91ZEZvcm1hdGlvblRlbXBsYXRlKHtcbiAgICBzdGFja05hbWU6IHN0YWNrQXJ0aWZhY3Quc3RhY2tOYW1lLFxuICAgIHRlbXBsYXRlOiBzdGFja0FydGlmYWN0LnRlbXBsYXRlLFxuICAgIHBhcmFtZXRlcnM6IHt9LFxuICAgIGFjY291bnQ6IHJlc29sdmVkRW52LmFjY291bnQsXG4gICAgcmVnaW9uOiByZXNvbHZlZEVudi5yZWdpb24sXG4gICAgcGFydGl0aW9uOiAoYXdhaXQgc2RrLmN1cnJlbnRBY2NvdW50KCkpLnBhcnRpdGlvbixcbiAgICBzZGssXG4gIH0pO1xuXG4gIGNvbnN0IHN0YWNrUmVzb3VyY2VzID0gYXdhaXQgbGlzdFN0YWNrUmVzb3VyY2VzLmxpc3RTdGFja1Jlc291cmNlcygpO1xuICBjb25zdCBsb2dHcm91cE5hbWVzID0gZmluZEFsbExvZ0dyb3VwTmFtZXMoc3RhY2tSZXNvdXJjZXMsIGV2YWx1YXRlQ2ZuVGVtcGxhdGUpO1xuXG4gIHJldHVybiB7XG4gICAgZW52OiByZXNvbHZlZEVudixcbiAgICBzZGssXG4gICAgbG9nR3JvdXBOYW1lcyxcbiAgfTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSBDbG91ZFdhdGNoIExvZyBHcm91cCBpcyBhc3NvY2lhdGVkXG4gKiB3aXRoIGFuIGlnbm9yZWQgcmVzb3VyY2VcbiAqL1xuZnVuY3Rpb24gaXNSZWZlcmVuY2VkRnJvbUlnbm9yZWRSZXNvdXJjZShcbiAgbG9nR3JvdXBSZXNvdXJjZTogU3RhY2tSZXNvdXJjZVN1bW1hcnksXG4gIGV2YWx1YXRlQ2ZuVGVtcGxhdGU6IEV2YWx1YXRlQ2xvdWRGb3JtYXRpb25UZW1wbGF0ZSxcbik6IGJvb2xlYW4ge1xuICBjb25zdCByZXNvdXJjZXNSZWZlcmVuY2luZ0xvZ0dyb3VwID0gZXZhbHVhdGVDZm5UZW1wbGF0ZS5maW5kUmVmZXJlbmNlc1RvKGxvZ0dyb3VwUmVzb3VyY2UuTG9naWNhbFJlc291cmNlSWQhKTtcbiAgcmV0dXJuIHJlc291cmNlc1JlZmVyZW5jaW5nTG9nR3JvdXAuc29tZSgocmVmZXJlbmNlKSA9PiB7XG4gICAgcmV0dXJuIElHTk9SRV9MT0dTX1JFU09VUkNFX1RZUEVTLmluY2x1ZGVzKHJlZmVyZW5jZS5UeXBlKTtcbiAgfSk7XG59XG5cbnR5cGUgQ2xvdWRXYXRjaExvZ3NSZXNvbHZlciA9IChcbiAgcmVzb3VyY2U6IFN0YWNrUmVzb3VyY2VTdW1tYXJ5LFxuICBldmFsdWF0ZUNmblRlbXBsYXRlOiBFdmFsdWF0ZUNsb3VkRm9ybWF0aW9uVGVtcGxhdGUsXG4pID0+IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuY29uc3QgY2xvdWRXYXRjaExvZ3NSZXNvbHZlcnM6IFJlY29yZDxzdHJpbmcsIENsb3VkV2F0Y2hMb2dzUmVzb2x2ZXI+ID0ge1xuICAnQVdTOjpMb2dzOjpMb2dHcm91cCc6IChyZXNvdXJjZSwgZXZhbHVhdGVDZm5UZW1wbGF0ZSkgPT4ge1xuICAgIGlmIChpc1JlZmVyZW5jZWRGcm9tSWdub3JlZFJlc291cmNlKHJlc291cmNlLCBldmFsdWF0ZUNmblRlbXBsYXRlKSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHJlc291cmNlLlBoeXNpY2FsUmVzb3VyY2VJZD8udG9TdHJpbmcoKTtcbiAgfSxcblxuICAvLyBSZXNvdXJjZSB0eXBlcyB0aGF0IHdpbGwgY3JlYXRlIGEgQ2xvdWRXYXRjaCBsb2cgZ3JvdXAgd2l0aCBhIHNwZWNpZmljIG5hbWUgaWYgb25lIGlzIG5vdCBwcm92aWRlZC5cbiAgLy8gVGhlIGtleXMgYXJlIENGTiByZXNvdXJjZSB0eXBlcywgYW5kIHRoZSB2YWx1ZXMgYXJlIHRoZSBuYW1lIG9mIHRoZSBwaHlzaWNhbCBuYW1lIHByb3BlcnR5IG9mIHRoYXQgcmVzb3VyY2VcbiAgLy8gYW5kIHRoZSBzZXJ2aWNlIG5hbWUgdGhhdCBpcyB1c2VkIGluIHRoZSBhdXRvbWF0aWNhbGx5IGNyZWF0ZWQgQ2xvdWRXYXRjaCBsb2cgZ3JvdXAuXG4gICdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nOiAocmVzb3VyY2UsIGV2YWx1YXRlQ2ZuVGVtcGxhdGUpID0+IHtcbiAgICBjb25zdCBsb2dnaW5nQ29uZmlnID0gZXZhbHVhdGVDZm5UZW1wbGF0ZS5nZXRSZXNvdXJjZVByb3BlcnR5KHJlc291cmNlLkxvZ2ljYWxSZXNvdXJjZUlkISwgJ0xvZ2dpbmdDb25maWcnKTtcbiAgICBpZiAobG9nZ2luZ0NvbmZpZz8uTG9nR3JvdXApIHtcbiAgICAgIC8vIGlmIExvZ0dyb3VwIGlzIGEgc3RyaW5nIHRoZW4gdXNlIGl0IGFzIHRoZSBMb2dHcm91cE5hbWUgYXMgaXQgaXMgcmVmZXJyZWQgYnkgTG9nR3JvdXAuZnJvbUxvZ0dyb3VwQXJuIGluIENES1xuICAgICAgaWYgKHR5cGVvZiBsb2dnaW5nQ29uZmlnLkxvZ0dyb3VwID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gbG9nZ2luZ0NvbmZpZy5Mb2dHcm91cDtcbiAgICAgIH1cblxuICAgICAgLy8gaWYgeyBSZWY6ICcuLi4nIH0gaXMgdXNlZCB0aGVuIHRyeSB0byByZXNvbHZlIHRoZSBMb2dHcm91cE5hbWUgZnJvbSB0aGUgcmVmZXJlbmNlZCByZXNvdXJjZSBpbiB0aGUgdGVtcGxhdGVcbiAgICAgIGlmICh0eXBlb2YgbG9nZ2luZ0NvbmZpZy5Mb2dHcm91cCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgaWYgKGxvZ2dpbmdDb25maWcuTG9nR3JvdXAuUmVmKSB7XG4gICAgICAgICAgcmV0dXJuIGV2YWx1YXRlQ2ZuVGVtcGxhdGUuZ2V0UmVzb3VyY2VQcm9wZXJ0eShsb2dnaW5nQ29uZmlnLkxvZ0dyb3VwLlJlZiwgJ0xvZ0dyb3VwTmFtZScpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGAvYXdzL2xhbWJkYS8ke3Jlc291cmNlLlBoeXNpY2FsUmVzb3VyY2VJZH1gO1xuICB9LFxufTtcblxuLyoqXG4gKiBGaW5kIGFsbCBDbG91ZFdhdGNoIExvZyBHcm91cHMgaW4gdGhlIGRlcGxveWVkIHRlbXBsYXRlLlxuICogVGhpcyB3aWxsIGZpbmQgYm90aCBleHBsaWNpdGx5IGNyZWF0ZWQgTG9nIEdyb3VwcyAoZXhjbHVkaW5nIHRob3NlIGFzc29jaWF0ZWQgd2l0aCBpZ25vcmVkIHJlc291cmNlcylcbiAqIGFuZCBMb2cgR3JvdXBzIGNyZWF0ZWQgaW1wbGljaXRseSAoaS5lLiBMYW1iZGEgRnVuY3Rpb25zKVxuICovXG5mdW5jdGlvbiBmaW5kQWxsTG9nR3JvdXBOYW1lcyhcbiAgc3RhY2tSZXNvdXJjZXM6IFN0YWNrUmVzb3VyY2VTdW1tYXJ5W10sXG4gIGV2YWx1YXRlQ2ZuVGVtcGxhdGU6IEV2YWx1YXRlQ2xvdWRGb3JtYXRpb25UZW1wbGF0ZSxcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgbG9nR3JvdXBOYW1lczogc3RyaW5nW10gPSBbXTtcblxuICBmb3IgKGNvbnN0IHJlc291cmNlIG9mIHN0YWNrUmVzb3VyY2VzKSB7XG4gICAgY29uc3QgbG9nR3JvdXBSZXNvbHZlciA9IGNsb3VkV2F0Y2hMb2dzUmVzb2x2ZXJzW3Jlc291cmNlLlJlc291cmNlVHlwZSFdO1xuICAgIGlmIChsb2dHcm91cFJlc29sdmVyKSB7XG4gICAgICBjb25zdCBsb2dHcm91cE5hbWUgPSBsb2dHcm91cFJlc29sdmVyKHJlc291cmNlLCBldmFsdWF0ZUNmblRlbXBsYXRlKTtcbiAgICAgIGlmIChsb2dHcm91cE5hbWUpIHtcbiAgICAgICAgbG9nR3JvdXBOYW1lcy5wdXNoKGxvZ0dyb3VwTmFtZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGxvZ0dyb3VwTmFtZXM7XG59XG4iXX0=