aws-cdk
Version:
AWS CDK CLI, the command line tool for CDK apps
95 lines • 16.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.findCloudWatchLogGroups = findCloudWatchLogGroups;
const private_1 = require("../../../../@aws-cdk/tmp-toolkit-helpers/src/api/io/private");
const util_1 = require("../../util");
const cloudformation_1 = require("../cloudformation");
const environment_1 = require("../environment");
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, ioHelper, 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_1.EnvironmentAccess(sdkProvider, toolkit_info_1.DEFAULT_TOOLKIT_STACK_NAME, ioHelper).accessStackForLookup(stackArtifact)).sdk;
}
catch (e) {
await ioHelper.notify(private_1.IO.DEFAULT_TOOLKIT_DEBUG.msg(`Failed to access SDK environment: ${(0, util_1.formatErrorMessage)(e)}`));
sdk = (await sdkProvider.forEnvironment(resolvedEnv, mode_1.Mode.ForReading)).sdk;
}
const listStackResources = new cloudformation_1.LazyListStackResources(sdk, stackArtifact.stackName);
const evaluateCfnTemplate = new cloudformation_1.EvaluateCloudFormationTemplate({
stackArtifact,
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmluZC1jbG91ZHdhdGNoLWxvZ3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJmaW5kLWNsb3Vkd2F0Y2gtbG9ncy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXNDQSwwREFpQ0M7QUFwRUQseUZBQWlGO0FBQ2pGLHFDQUFnRDtBQUVoRCxzREFBMkY7QUFDM0YsZ0RBQW1EO0FBQ25ELHlDQUFzQztBQUN0QyxrREFBNkQ7QUFFN0QsMkZBQTJGO0FBQzNGLE1BQU0sMEJBQTBCLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSx3QkFBd0IsRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO0FBMEJ2RyxLQUFLLFVBQVUsdUJBQXVCLENBQzNDLFdBQXdCLEVBQ3hCLFFBQWtCLEVBQ2xCLGFBQTBDO0lBRTFDLElBQUksR0FBUSxDQUFDO0lBQ2IsTUFBTSxXQUFXLEdBQUcsTUFBTSxXQUFXLENBQUMsa0JBQWtCLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3BGLHdFQUF3RTtJQUN4RSxJQUFJLENBQUM7UUFDSCxHQUFHLEdBQUcsQ0FBQyxNQUFNLElBQUksK0JBQWlCLENBQUMsV0FBVyxFQUFFLHlDQUEwQixFQUFFLFFBQVEsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQ2pJLENBQUM7SUFBQyxPQUFPLENBQU0sRUFBRSxDQUFDO1FBQ2hCLE1BQU0sUUFBUSxDQUFDLE1BQU0sQ0FBQyxZQUFFLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLHFDQUFxQyxJQUFBLHlCQUFrQixFQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2xILEdBQUcsR0FBRyxDQUFDLE1BQU0sV0FBVyxDQUFDLGNBQWMsQ0FBQyxXQUFXLEVBQUUsV0FBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQzdFLENBQUM7SUFFRCxNQUFNLGtCQUFrQixHQUFHLElBQUksdUNBQXNCLENBQUMs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Q0FBQztZQUNyRSxJQUFJLFlBQVksRUFBRSxDQUFDO2dCQUNqQixhQUFhLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ25DLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sYUFBYSxDQUFDO0FBQ3ZCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IENsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdCwgRW52aXJvbm1lbnQgfSBmcm9tICdAYXdzLWNkay9jeC1hcGknO1xuaW1wb3J0IHR5cGUgeyBTdGFja1Jlc291cmNlU3VtbWFyeSB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1jbG91ZGZvcm1hdGlvbic7XG5pbXBvcnQgdHlwZSB7IElvSGVscGVyIH0gZnJvbSAnLi4vLi4vLi4vLi4vQGF3cy1jZGsvdG1wLXRvb2xraXQtaGVscGVycy9zcmMvYXBpL2lvL3ByaXZhdGUnO1xuaW1wb3J0IHsgSU8gfSBmcm9tICcuLi8uLi8uLi8uLi9AYXdzLWNkay90bXAtdG9vbGtpdC1oZWxwZXJzL3NyYy9hcGkvaW8vcHJpdmF0ZSc7XG5pbXBvcnQgeyBmb3JtYXRFcnJvck1lc3NhZ2UgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB0eXBlIHsgU0RLLCBTZGtQcm92aWRlciB9IGZyb20gJy4uL2F3cy1hdXRoJztcbmltcG9ydCB7IEV2YWx1YXRlQ2xvdWRGb3JtYXRpb25UZW1wbGF0ZSwgTGF6eUxpc3RTdGFja1Jlc291cmNlcyB9IGZyb20gJy4uL2Nsb3VkZm9ybWF0aW9uJztcbmltcG9ydCB7IEVudmlyb25tZW50QWNjZXNzIH0gZnJvbSAnLi4vZW52aXJvbm1lbnQnO1xuaW1wb3J0IHsgTW9kZSB9IGZyb20gJy4uL3BsdWdpbi9tb2RlJztcbmltcG9ydCB7IERFRkFVTFRfVE9PTEtJVF9TVEFDS19OQU1FIH0gZnJvbSAnLi4vdG9vbGtpdC1pbmZvJztcblxuLy8gcmVzb3VyY2UgdHlwZXMgdGhhdCBoYXZlIGFzc29jaWF0ZWQgQ2xvdWRXYXRjaCBMb2cgR3JvdXBzIHRoYXQgc2hvdWxkIF9ub3RfIGJlIG1vbml0b3JlZFxuY29uc3QgSUdOT1JFX0xPR1NfUkVTT1VSQ0VfVFlQRVMgPSBbJ0FXUzo6RUMyOjpGbG93TG9nJywgJ0FXUzo6Q2xvdWRUcmFpbDo6VHJhaWwnLCAnQVdTOjpDb2RlQnVpbGQ6OlByb2plY3QnXTtcblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIG5lZWRlZCB0byBtb25pdG9yIENsb3VkV2F0Y2ggTG9nIEdyb3Vwc1xuICogZm91bmQgaW4gYSBnaXZlbiBDbG91ZEZvcm1hdGlvbiBTdGFja1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEZvdW5kTG9nR3JvdXBzUmVzdWx0IHtcbiAgLyoqXG4gICAqIFRoZSByZXNvbHZlZCBlbnZpcm9ubWVudCAoYWNjb3VudC9yZWdpb24pIHRoYXQgdGhlIGxvZ1xuICAgKiBncm91cHMgYXJlIGRlcGxveWVkIGluXG4gICAqL1xuICByZWFkb25seSBlbnY6IEVudmlyb25tZW50O1xuXG4gIC8qKlxuICAgKiBUaGUgU0RLIHRoYXQgY2FuIGJlIHVzZWQgdG8gcmVhZCBldmVudHMgZnJvbSB0aGUgQ2xvdWRXYXRjaFxuICAgKiBMb2cgR3JvdXBzIGluIHRoZSBnaXZlbiBlbnZpcm9ubWVudFxuICAgKi9cbiAgcmVhZG9ubHkgc2RrOiBTREs7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lcyBvZiB0aGUgcmVsZXZhbnQgQ2xvdWRXYXRjaCBMb2cgR3JvdXBzXG4gICAqIGluIHRoZSBnaXZlbiBDbG91ZEZvcm1hdGlvbiB0ZW1wbGF0ZVxuICAgKi9cbiAgcmVhZG9ubHkgbG9nR3JvdXBOYW1lczogc3RyaW5nW107XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmaW5kQ2xvdWRXYXRjaExvZ0dyb3VwcyhcbiAgc2RrUHJvdmlkZXI6IFNka1Byb3ZpZGVyLFxuICBpb0hlbHBlcjogSW9IZWxwZXIsXG4gIHN0YWNrQXJ0aWZhY3Q6IENsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdCxcbik6IFByb21pc2U8Rm91bmRMb2dHcm91cHNSZXN1bHQ+IHtcbiAgbGV0IHNkazogU0RLO1xuICBjb25zdCByZXNvbHZlZEVudiA9IGF3YWl0IHNka1Byb3ZpZGVyLnJlc29sdmVFbnZpcm9ubWVudChzdGFja0FydGlmYWN0LmVudmlyb25tZW50KTtcbiAgLy8gdHJ5IHRvIGFzc3VtZSB0aGUgbG9va3VwIHJvbGUgYW5kIGZhbGxiYWNrIHRvIHRoZSBkZWZhdWx0IGNyZWRlbnRpYWxzXG4gIHRyeSB7XG4gICAgc2RrID0gKGF3YWl0IG5ldyBFbnZpcm9ubWVudEFjY2VzcyhzZGtQcm92aWRlciwgREVGQVVMVF9UT09MS0lUX1NUQUNLX05BTUUsIGlvSGVscGVyKS5hY2Nlc3NTdGFja0Zvckxvb2t1cChzdGFja0FydGlmYWN0KSkuc2RrO1xuICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICBhd2FpdCBpb0hlbHBlci5ub3RpZnkoSU8uREVGQVVMVF9UT09MS0lUX0RFQlVHLm1zZyhgRmFpbGVkIHRvIGFjY2VzcyBTREsgZW52aXJvbm1lbnQ6ICR7Zm9ybWF0RXJyb3JNZXNzYWdlKGUpfWApKTtcbiAgICBzZGsgPSAoYXdhaXQgc2RrUHJvdmlkZXIuZm9yRW52aXJvbm1lbnQocmVzb2x2ZWRFbnYsIE1vZGUuRm9yUmVhZGluZykpLnNkaztcbiAgfVxuXG4gIGNvbnN0IGxpc3RTdGFja1Jlc291cmNlcyA9IG5ldyBMYXp5TGlzdFN0YWNrUmVzb3VyY2VzKHNkaywgc3RhY2tBcnRpZmFjdC5zdGFja05hbWUpO1xuICBjb25zdCBldmFsdWF0ZUNmblRlbXBsYXRlID0gbmV3IEV2YWx1YXRlQ2xvdWRGb3JtYXRpb25UZW1wbGF0ZSh7XG4gICAgc3RhY2tBcnRpZmFjdCxcbiAgICBwYXJhbWV0ZXJzOiB7fSxcbiAgICBhY2NvdW50OiByZXNvbHZlZEVudi5hY2NvdW50LFxuICAgIHJlZ2lvbjogcmVzb2x2ZWRFbnYucmVnaW9uLFxuICAgIHBhcnRpdGlvbjogKGF3YWl0IHNkay5jdXJyZW50QWNjb3VudCgpKS5wYXJ0aXRpb24sXG4gICAgc2RrLFxuICB9KTtcblxuICBjb25zdCBzdGFja1Jlc291cmNlcyA9IGF3YWl0IGxpc3RTdGFja1Jlc291cmNlcy5saXN0U3RhY2tSZXNvdXJjZXMoKTtcbiAgY29uc3QgbG9nR3JvdXBOYW1lcyA9IGZpbmRBbGxMb2dHcm91cE5hbWVzKHN0YWNrUmVzb3VyY2VzLCBldmFsdWF0ZUNmblRlbXBsYXRlKTtcblxuICByZXR1cm4ge1xuICAgIGVudjogcmVzb2x2ZWRFbnYsXG4gICAgc2RrLFxuICAgIGxvZ0dyb3VwTmFtZXMsXG4gIH07XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgQ2xvdWRXYXRjaCBMb2cgR3JvdXAgaXMgYXNzb2NpYXRlZFxuICogd2l0aCBhbiBpZ25vcmVkIHJlc291cmNlXG4gKi9cbmZ1bmN0aW9uIGlzUmVmZXJlbmNlZEZyb21JZ25vcmVkUmVzb3VyY2UoXG4gIGxvZ0dyb3VwUmVzb3VyY2U6IFN0YWNrUmVzb3VyY2VTdW1tYXJ5LFxuICBldmFsdWF0ZUNmblRlbXBsYXRlOiBFdmFsdWF0ZUNsb3VkRm9ybWF0aW9uVGVtcGxhdGUsXG4pOiBib29sZWFuIHtcbiAgY29uc3QgcmVzb3VyY2VzUmVmZXJlbmNpbmdMb2dHcm91cCA9IGV2YWx1YXRlQ2ZuVGVtcGxhdGUuZmluZFJlZmVyZW5jZXNUbyhsb2dHcm91cFJlc291cmNlLkxvZ2ljYWxSZXNvdXJjZUlkISk7XG4gIHJldHVybiByZXNvdXJjZXNSZWZlcmVuY2luZ0xvZ0dyb3VwLnNvbWUoKHJlZmVyZW5jZSkgPT4ge1xuICAgIHJldHVybiBJR05PUkVfTE9HU19SRVNPVVJDRV9UWVBFUy5pbmNsdWRlcyhyZWZlcmVuY2UuVHlwZSk7XG4gIH0pO1xufVxuXG50eXBlIENsb3VkV2F0Y2hMb2dzUmVzb2x2ZXIgPSAoXG4gIHJlc291cmNlOiBTdGFja1Jlc291cmNlU3VtbWFyeSxcbiAgZXZhbHVhdGVDZm5UZW1wbGF0ZTogRXZhbHVhdGVDbG91ZEZvcm1hdGlvblRlbXBsYXRlLFxuKSA9PiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbmNvbnN0IGNsb3VkV2F0Y2hMb2dzUmVzb2x2ZXJzOiBSZWNvcmQ8c3RyaW5nLCBDbG91ZFdhdGNoTG9nc1Jlc29sdmVyPiA9IHtcbiAgJ0FXUzo6TG9nczo6TG9nR3JvdXAnOiAocmVzb3VyY2UsIGV2YWx1YXRlQ2ZuVGVtcGxhdGUpID0+IHtcbiAgICBpZiAoaXNSZWZlcmVuY2VkRnJvbUlnbm9yZWRSZXNvdXJjZShyZXNvdXJjZSwgZXZhbHVhdGVDZm5UZW1wbGF0ZSkpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiByZXNvdXJjZS5QaHlzaWNhbFJlc291cmNlSWQ/LnRvU3RyaW5nKCk7XG4gIH0sXG5cbiAgLy8gUmVzb3VyY2UgdHlwZXMgdGhhdCB3aWxsIGNyZWF0ZSBhIENsb3VkV2F0Y2ggbG9nIGdyb3VwIHdpdGggYSBzcGVjaWZpYyBuYW1lIGlmIG9uZSBpcyBub3QgcHJvdmlkZWQuXG4gIC8vIFRoZSBrZXlzIGFyZSBDRk4gcmVzb3VyY2UgdHlwZXMsIGFuZCB0aGUgdmFsdWVzIGFyZSB0aGUgbmFtZSBvZiB0aGUgcGh5c2ljYWwgbmFtZSBwcm9wZXJ0eSBvZiB0aGF0IHJlc291cmNlXG4gIC8vIGFuZCB0aGUgc2VydmljZSBuYW1lIHRoYXQgaXMgdXNlZCBpbiB0aGUgYXV0b21hdGljYWxseSBjcmVhdGVkIENsb3VkV2F0Y2ggbG9nIGdyb3VwLlxuICAnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJzogKHJlc291cmNlLCBldmFsdWF0ZUNmblRlbXBsYXRlKSA9PiB7XG4gICAgY29uc3QgbG9nZ2luZ0NvbmZpZyA9IGV2YWx1YXRlQ2ZuVGVtcGxhdGUuZ2V0UmVzb3VyY2VQcm9wZXJ0eShyZXNvdXJjZS5Mb2dpY2FsUmVzb3VyY2VJZCEsICdMb2dnaW5nQ29uZmlnJyk7XG4gICAgaWYgKGxvZ2dpbmdDb25maWc/LkxvZ0dyb3VwKSB7XG4gICAgICAvLyBpZiBMb2dHcm91cCBpcyBhIHN0cmluZyB0aGVuIHVzZSBpdCBhcyB0aGUgTG9nR3JvdXBOYW1lIGFzIGl0IGlzIHJlZmVycmVkIGJ5IExvZ0dyb3VwLmZyb21Mb2dHcm91cEFybiBpbiBDREtcbiAgICAgIGlmICh0eXBlb2YgbG9nZ2luZ0NvbmZpZy5Mb2dHcm91cCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGxvZ2dpbmdDb25maWcuTG9nR3JvdXA7XG4gICAgICB9XG5cbiAgICAgIC8vIGlmIHsgUmVmOiAnLi4uJyB9IGlzIHVzZWQgdGhlbiB0cnkgdG8gcmVzb2x2ZSB0aGUgTG9nR3JvdXBOYW1lIGZyb20gdGhlIHJlZmVyZW5jZWQgcmVzb3VyY2UgaW4gdGhlIHRlbXBsYXRlXG4gICAgICBpZiAodHlwZW9mIGxvZ2dpbmdDb25maWcuTG9nR3JvdXAgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmIChsb2dnaW5nQ29uZmlnLkxvZ0dyb3VwLlJlZikge1xuICAgICAgICAgIHJldHVybiBldmFsdWF0ZUNmblRlbXBsYXRlLmdldFJlc291cmNlUHJvcGVydHkobG9nZ2luZ0NvbmZpZy5Mb2dHcm91cC5SZWYsICdMb2dHcm91cE5hbWUnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBgL2F3cy9sYW1iZGEvJHtyZXNvdXJjZS5QaHlzaWNhbFJlc291cmNlSWR9YDtcbiAgfSxcbn07XG5cbi8qKlxuICogRmluZCBhbGwgQ2xvdWRXYXRjaCBMb2cgR3JvdXBzIGluIHRoZSBkZXBsb3llZCB0ZW1wbGF0ZS5cbiAqIFRoaXMgd2lsbCBmaW5kIGJvdGggZXhwbGljaXRseSBjcmVhdGVkIExvZyBHcm91cHMgKGV4Y2x1ZGluZyB0aG9zZSBhc3NvY2lhdGVkIHdpdGggaWdub3JlZCByZXNvdXJjZXMpXG4gKiBhbmQgTG9nIEdyb3VwcyBjcmVhdGVkIGltcGxpY2l0bHkgKGkuZS4gTGFtYmRhIEZ1bmN0aW9ucylcbiAqL1xuZnVuY3Rpb24gZmluZEFsbExvZ0dyb3VwTmFtZXMoXG4gIHN0YWNrUmVzb3VyY2VzOiBTdGFja1Jlc291cmNlU3VtbWFyeVtdLFxuICBldmFsdWF0ZUNmblRlbXBsYXRlOiBFdmFsdWF0ZUNsb3VkRm9ybWF0aW9uVGVtcGxhdGUsXG4pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGxvZ0dyb3VwTmFtZXM6IHN0cmluZ1tdID0gW107XG5cbiAgZm9yIChjb25zdCByZXNvdXJjZSBvZiBzdGFja1Jlc291cmNlcykge1xuICAgIGNvbnN0IGxvZ0dyb3VwUmVzb2x2ZXIgPSBjbG91ZFdhdGNoTG9nc1Jlc29sdmVyc1tyZXNvdXJjZS5SZXNvdXJjZVR5cGUhXTtcbiAgICBpZiAobG9nR3JvdXBSZXNvbHZlcikge1xuICAgICAgY29uc3QgbG9nR3JvdXBOYW1lID0gbG9nR3JvdXBSZXNvbHZlcihyZXNvdXJjZSwgZXZhbHVhdGVDZm5UZW1wbGF0ZSk7XG4gICAgICBpZiAobG9nR3JvdXBOYW1lKSB7XG4gICAgICAgIGxvZ0dyb3VwTmFtZXMucHVzaChsb2dHcm91cE5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBsb2dHcm91cE5hbWVzO1xufVxuIl19