UNPKG

@aws-cdk/aws-events-targets

Version:

Event targets for Amazon EventBridge

112 lines 16.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.addToDeadLetterQueueResourcePolicy = exports.addLambdaPermission = exports.singletonEventRole = exports.bindBaseTargetConfig = void 0; const iam = require("@aws-cdk/aws-iam"); const core_1 = require("@aws-cdk/core"); // keep this import separate from other imports to reduce chance for merge conflicts with v2-main // eslint-disable-next-line no-duplicate-imports, import/order const core_2 = require("@aws-cdk/core"); /** * Bind props to base rule target config. * @internal */ function bindBaseTargetConfig(props) { let { deadLetterQueue, retryAttempts, maxEventAge } = props; return { deadLetterConfig: deadLetterQueue ? { arn: deadLetterQueue?.queueArn } : undefined, retryPolicy: retryAttempts || maxEventAge ? { maximumRetryAttempts: retryAttempts, maximumEventAgeInSeconds: maxEventAge?.toSeconds({ integral: true }), } : undefined, }; } exports.bindBaseTargetConfig = bindBaseTargetConfig; /** * Obtain the Role for the EventBridge event * * If a role already exists, it will be returned. This ensures that if multiple * events have the same target, they will share a role. * @internal */ function singletonEventRole(scope) { const id = 'EventsRole'; const existing = scope.node.tryFindChild(id); if (existing) { return existing; } const role = new iam.Role(scope, id, { roleName: core_1.PhysicalName.GENERATE_IF_NEEDED, assumedBy: new iam.ServicePrincipal('events.amazonaws.com'), }); return role; } exports.singletonEventRole = singletonEventRole; /** * Allows a Lambda function to be called from a rule * @internal */ function addLambdaPermission(rule, handler) { let scope; let node = handler.permissionsNode; let permissionId = `AllowEventRule${core_1.Names.nodeUniqueId(rule.node)}`; if (rule instanceof core_2.Construct) { // Place the Permission resource in the same stack as Rule rather than the Function // This is to reduce circular dependency when the lambda handler and the rule are across stacks. scope = rule; node = rule.node; permissionId = `AllowEventRule${core_1.Names.nodeUniqueId(handler.node)}`; } if (!node.tryFindChild(permissionId)) { handler.addPermission(permissionId, { scope, action: 'lambda:InvokeFunction', principal: new iam.ServicePrincipal('events.amazonaws.com'), sourceArn: rule.ruleArn, }); } } exports.addLambdaPermission = addLambdaPermission; /** * Allow a rule to send events with failed invocation to an Amazon SQS queue. * @internal */ function addToDeadLetterQueueResourcePolicy(rule, queue) { if (!sameEnvDimension(rule.env.region, queue.env.region)) { throw new Error(`Cannot assign Dead Letter Queue in region ${queue.env.region} to the rule ${core_1.Names.nodeUniqueId(rule.node)} in region ${rule.env.region}. Both the queue and the rule must be in the same region.`); } // Skip Resource Policy creation if the Queue is not in the same account. // There is no way to add a target onto an imported rule, so we can assume we will run the following code only // in the account where the rule is created. if (sameEnvDimension(rule.env.account, queue.env.account)) { const policyStatementId = `AllowEventRule${core_1.Names.nodeUniqueId(rule.node)}`; queue.addToResourcePolicy(new iam.PolicyStatement({ sid: policyStatementId, principals: [new iam.ServicePrincipal('events.amazonaws.com')], effect: iam.Effect.ALLOW, actions: ['sqs:SendMessage'], resources: [queue.queueArn], conditions: { ArnEquals: { 'aws:SourceArn': rule.ruleArn, }, }, })); } else { core_1.Annotations.of(rule).addWarning(`Cannot add a resource policy to your dead letter queue associated with rule ${rule.ruleName} because the queue is in a different account. You must add the resource policy manually to the dead letter queue in account ${queue.env.account}.`); } } exports.addToDeadLetterQueueResourcePolicy = addToDeadLetterQueueResourcePolicy; /** * Whether two string probably contain the same environment dimension (region or account) * * Used to compare either accounts or regions, and also returns true if both * are unresolved (in which case both are expted to be "current region" or "current account"). * @internal */ function sameEnvDimension(dim1, dim2) { return [core_1.TokenComparison.SAME, core_1.TokenComparison.BOTH_UNRESOLVED].includes(core_1.Token.compareStrings(dim1, dim2)); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0Esd0NBQXdDO0FBR3hDLHdDQUE4SDtBQUU5SCxpR0FBaUc7QUFDakcsOERBQThEO0FBQzlELHdDQUEwQztBQXVDMUM7OztHQUdHO0FBQ0gsU0FBZ0Isb0JBQW9CLENBQUMsS0FBc0I7SUFDekQsSUFBSSxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLEdBQUcsS0FBSyxDQUFDO0lBRTVELE9BQU87UUFDTCxnQkFBZ0IsRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUztRQUNsRixXQUFXLEVBQUUsYUFBYSxJQUFJLFdBQVc7WUFDdkMsQ0FBQyxDQUFDO2dCQUNBLG9CQUFvQixFQUFFLGFBQWE7Z0JBQ25DLHdCQUF3QixFQUFFLFdBQVcsRUFBRSxTQUFTLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUM7YUFDckU7WUFDRCxDQUFDLENBQUMsU0FBUztLQUNkLENBQUM7QUFDSixDQUFDO0FBWkQsb0RBWUM7QUFHRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixrQkFBa0IsQ0FBQyxLQUFpQjtJQUNsRCxNQUFNLEVBQUUsR0FBRyxZQUFZLENBQUM7SUFDeEIsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFjLENBQUM7SUFDMUQsSUFBSSxRQUFRLEVBQUU7UUFBRSxPQUFPLFFBQVEsQ0FBQztLQUFFO0lBRWxDLE1BQU0sSUFBSSxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFrQixFQUFFLEVBQUUsRUFBRTtRQUNoRCxRQUFRLEVBQUUsbUJBQVksQ0FBQyxrQkFBa0I7UUFDekMsU0FBUyxFQUFFLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLHNCQUFzQixD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SUFBSSxFQUFFLHNCQUFlLENBQUMsZUFBZSxDQUFDLENBQUMsUUFBUSxDQUFDLFlBQUssQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDNUcsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGV2ZW50cyBmcm9tICdAYXdzLWNkay9hd3MtZXZlbnRzJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdAYXdzLWNkay9hd3MtaWFtJztcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICdAYXdzLWNkay9hd3MtbGFtYmRhJztcbmltcG9ydCAqIGFzIHNxcyBmcm9tICdAYXdzLWNkay9hd3Mtc3FzJztcbmltcG9ydCB7IEFubm90YXRpb25zLCBDb25zdHJ1Y3ROb2RlLCBJQ29uc3RydWN0LCBOYW1lcywgVG9rZW4sIFRva2VuQ29tcGFyaXNvbiwgRHVyYXRpb24sIFBoeXNpY2FsTmFtZSB9IGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1xuXG4vLyBrZWVwIHRoaXMgaW1wb3J0IHNlcGFyYXRlIGZyb20gb3RoZXIgaW1wb3J0cyB0byByZWR1Y2UgY2hhbmNlIGZvciBtZXJnZSBjb25mbGljdHMgd2l0aCB2Mi1tYWluXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZHVwbGljYXRlLWltcG9ydHMsIGltcG9ydC9vcmRlclxuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnQGF3cy1jZGsvY29yZSc7XG5cbi8qKlxuICogVGhlIGdlbmVyaWMgcHJvcGVydGllcyBmb3IgYW4gUnVsZVRhcmdldFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRhcmdldEJhc2VQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgU1FTIHF1ZXVlIHRvIGJlIHVzZWQgYXMgZGVhZExldHRlclF1ZXVlLlxuICAgKiBDaGVjayBvdXQgdGhlIFtjb25zaWRlcmF0aW9ucyBmb3IgdXNpbmcgYSBkZWFkLWxldHRlciBxdWV1ZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2V2ZW50YnJpZGdlL2xhdGVzdC91c2VyZ3VpZGUvcnVsZS1kbHEuaHRtbCNkbHEtY29uc2lkZXJhdGlvbnMpLlxuICAgKlxuICAgKiBUaGUgZXZlbnRzIG5vdCBzdWNjZXNzZnVsbHkgZGVsaXZlcmVkIGFyZSBhdXRvbWF0aWNhbGx5IHJldHJpZWQgZm9yIGEgc3BlY2lmaWVkIHBlcmlvZCBvZiB0aW1lLFxuICAgKiBkZXBlbmRpbmcgb24gdGhlIHJldHJ5IHBvbGljeSBvZiB0aGUgdGFyZ2V0LlxuICAgKiBJZiBhbiBldmVudCBpcyBub3QgZGVsaXZlcmVkIGJlZm9yZSBhbGwgcmV0cnkgYXR0ZW1wdHMgYXJlIGV4aGF1c3RlZCwgaXQgd2lsbCBiZSBzZW50IHRvIHRoZSBkZWFkIGxldHRlciBxdWV1ZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBkZWFkLWxldHRlciBxdWV1ZVxuICAgKi9cbiAgcmVhZG9ubHkgZGVhZExldHRlclF1ZXVlPzogc3FzLklRdWV1ZTtcbiAgLyoqXG4gICAqIFRoZSBtYXhpbXVtIGFnZSBvZiBhIHJlcXVlc3QgdGhhdCBMYW1iZGEgc2VuZHMgdG8gYSBmdW5jdGlvbiBmb3JcbiAgICogcHJvY2Vzc2luZy5cbiAgICpcbiAgICogTWluaW11bSB2YWx1ZSBvZiA2MC5cbiAgICogTWF4aW11bSB2YWx1ZSBvZiA4NjQwMC5cbiAgICpcbiAgICogQGRlZmF1bHQgRHVyYXRpb24uaG91cnMoMjQpXG4gICAqL1xuICByZWFkb25seSBtYXhFdmVudEFnZT86IER1cmF0aW9uO1xuXG4gIC8qKlxuICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgdGltZXMgdG8gcmV0cnkgd2hlbiB0aGUgZnVuY3Rpb24gcmV0dXJucyBhbiBlcnJvci5cbiAgICpcbiAgICogTWluaW11bSB2YWx1ZSBvZiAwLlxuICAgKiBNYXhpbXVtIHZhbHVlIG9mIDE4NS5cbiAgICpcbiAgICogQGRlZmF1bHQgMTg1XG4gICAqL1xuICByZWFkb25seSByZXRyeUF0dGVtcHRzPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEJpbmQgcHJvcHMgdG8gYmFzZSBydWxlIHRhcmdldCBjb25maWcuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJpbmRCYXNlVGFyZ2V0Q29uZmlnKHByb3BzOiBUYXJnZXRCYXNlUHJvcHMpIHtcbiAgbGV0IHsgZGVhZExldHRlclF1ZXVlLCByZXRyeUF0dGVtcHRzLCBtYXhFdmVudEFnZSB9ID0gcHJvcHM7XG5cbiAgcmV0dXJuIHtcbiAgICBkZWFkTGV0dGVyQ29uZmlnOiBkZWFkTGV0dGVyUXVldWUgPyB7IGFybjogZGVhZExldHRlclF1ZXVlPy5xdWV1ZUFybiB9IDogdW5kZWZpbmVkLFxuICAgIHJldHJ5UG9saWN5OiByZXRyeUF0dGVtcHRzIHx8IG1heEV2ZW50QWdlXG4gICAgICA/IHtcbiAgICAgICAgbWF4aW11bVJldHJ5QXR0ZW1wdHM6IHJldHJ5QXR0ZW1wdHMsXG4gICAgICAgIG1heGltdW1FdmVudEFnZUluU2Vjb25kczogbWF4RXZlbnRBZ2U/LnRvU2Vjb25kcyh7IGludGVncmFsOiB0cnVlIH0pLFxuICAgICAgfVxuICAgICAgOiB1bmRlZmluZWQsXG4gIH07XG59XG5cblxuLyoqXG4gKiBPYnRhaW4gdGhlIFJvbGUgZm9yIHRoZSBFdmVudEJyaWRnZSBldmVudFxuICpcbiAqIElmIGEgcm9sZSBhbHJlYWR5IGV4aXN0cywgaXQgd2lsbCBiZSByZXR1cm5lZC4gVGhpcyBlbnN1cmVzIHRoYXQgaWYgbXVsdGlwbGVcbiAqIGV2ZW50cyBoYXZlIHRoZSBzYW1lIHRhcmdldCwgdGhleSB3aWxsIHNoYXJlIGEgcm9sZS5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gc2luZ2xldG9uRXZlbnRSb2xlKHNjb3BlOiBJQ29uc3RydWN0KTogaWFtLklSb2xlIHtcbiAgY29uc3QgaWQgPSAnRXZlbnRzUm9sZSc7XG4gIGNvbnN0IGV4aXN0aW5nID0gc2NvcGUubm9kZS50cnlGaW5kQ2hpbGQoaWQpIGFzIGlhbS5JUm9sZTtcbiAgaWYgKGV4aXN0aW5nKSB7IHJldHVybiBleGlzdGluZzsgfVxuXG4gIGNvbnN0IHJvbGUgPSBuZXcgaWFtLlJvbGUoc2NvcGUgYXMgQ29uc3RydWN0LCBpZCwge1xuICAgIHJvbGVOYW1lOiBQaHlzaWNhbE5hbWUuR0VORVJBVEVfSUZfTkVFREVELFxuICAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdldmVudHMuYW1hem9uYXdzLmNvbScpLFxuICB9KTtcblxuICByZXR1cm4gcm9sZTtcbn1cblxuLyoqXG4gKiBBbGxvd3MgYSBMYW1iZGEgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIGZyb20gYSBydWxlXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZExhbWJkYVBlcm1pc3Npb24ocnVsZTogZXZlbnRzLklSdWxlLCBoYW5kbGVyOiBsYW1iZGEuSUZ1bmN0aW9uKTogdm9pZCB7XG4gIGxldCBzY29wZTogQ29uc3RydWN0IHwgdW5kZWZpbmVkO1xuICBsZXQgbm9kZTogQ29uc3RydWN0Tm9kZSA9IGhhbmRsZXIucGVybWlzc2lvbnNOb2RlO1xuICBsZXQgcGVybWlzc2lvbklkID0gYEFsbG93RXZlbnRSdWxlJHtOYW1lcy5ub2RlVW5pcXVlSWQocnVsZS5ub2RlKX1gO1xuICBpZiAocnVsZSBpbnN0YW5jZW9mIENvbnN0cnVjdCkge1xuICAgIC8vIFBsYWNlIHRoZSBQZXJtaXNzaW9uIHJlc291cmNlIGluIHRoZSBzYW1lIHN0YWNrIGFzIFJ1bGUgcmF0aGVyIHRoYW4gdGhlIEZ1bmN0aW9uXG4gICAgLy8gVGhpcyBpcyB0byByZWR1Y2UgY2lyY3VsYXIgZGVwZW5kZW5jeSB3aGVuIHRoZSBsYW1iZGEgaGFuZGxlciBhbmQgdGhlIHJ1bGUgYXJlIGFjcm9zcyBzdGFja3MuXG4gICAgc2NvcGUgPSBydWxlO1xuICAgIG5vZGUgPSBydWxlLm5vZGU7XG4gICAgcGVybWlzc2lvbklkID0gYEFsbG93RXZlbnRSdWxlJHtOYW1lcy5ub2RlVW5pcXVlSWQoaGFuZGxlci5ub2RlKX1gO1xuICB9XG4gIGlmICghbm9kZS50cnlGaW5kQ2hpbGQocGVybWlzc2lvbklkKSkge1xuICAgIGhhbmRsZXIuYWRkUGVybWlzc2lvbihwZXJtaXNzaW9uSWQsIHtcbiAgICAgIHNjb3BlLFxuICAgICAgYWN0aW9uOiAnbGFtYmRhOkludm9rZUZ1bmN0aW9uJyxcbiAgICAgIHByaW5jaXBhbDogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdldmVudHMuYW1hem9uYXdzLmNvbScpLFxuICAgICAgc291cmNlQXJuOiBydWxlLnJ1bGVBcm4sXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBBbGxvdyBhIHJ1bGUgdG8gc2VuZCBldmVudHMgd2l0aCBmYWlsZWQgaW52b2NhdGlvbiB0byBhbiBBbWF6b24gU1FTIHF1ZXVlLlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRUb0RlYWRMZXR0ZXJRdWV1ZVJlc291cmNlUG9saWN5KHJ1bGU6IGV2ZW50cy5JUnVsZSwgcXVldWU6IHNxcy5JUXVldWUpIHtcbiAgaWYgKCFzYW1lRW52RGltZW5zaW9uKHJ1bGUuZW52LnJlZ2lvbiwgcXVldWUuZW52LnJlZ2lvbikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBhc3NpZ24gRGVhZCBMZXR0ZXIgUXVldWUgaW4gcmVnaW9uICR7cXVldWUuZW52LnJlZ2lvbn0gdG8gdGhlIHJ1bGUgJHtOYW1lcy5ub2RlVW5pcXVlSWQocnVsZS5ub2RlKX0gaW4gcmVnaW9uICR7cnVsZS5lbnYucmVnaW9ufS4gQm90aCB0aGUgcXVldWUgYW5kIHRoZSBydWxlIG11c3QgYmUgaW4gdGhlIHNhbWUgcmVnaW9uLmApO1xuICB9XG5cbiAgLy8gU2tpcCBSZXNvdXJjZSBQb2xpY3kgY3JlYXRpb24gaWYgdGhlIFF1ZXVlIGlzIG5vdCBpbiB0aGUgc2FtZSBhY2NvdW50LlxuICAvLyBUaGVyZSBpcyBubyB3YXkgdG8gYWRkIGEgdGFyZ2V0IG9udG8gYW4gaW1wb3J0ZWQgcnVsZSwgc28gd2UgY2FuIGFzc3VtZSB3ZSB3aWxsIHJ1biB0aGUgZm9sbG93aW5nIGNvZGUgb25seVxuICAvLyBpbiB0aGUgYWNjb3VudCB3aGVyZSB0aGUgcnVsZSBpcyBjcmVhdGVkLlxuICBpZiAoc2FtZUVudkRpbWVuc2lvbihydWxlLmVudi5hY2NvdW50LCBxdWV1ZS5lbnYuYWNjb3VudCkpIHtcbiAgICBjb25zdCBwb2xpY3lTdGF0ZW1lbnRJZCA9IGBBbGxvd0V2ZW50UnVsZSR7TmFtZXMubm9kZVVuaXF1ZUlkKHJ1bGUubm9kZSl9YDtcblxuICAgIHF1ZXVlLmFkZFRvUmVzb3VyY2VQb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgc2lkOiBwb2xpY3lTdGF0ZW1lbnRJZCxcbiAgICAgIHByaW5jaXBhbHM6IFtuZXcgaWFtLlNlcnZpY2VQcmluY2lwYWwoJ2V2ZW50cy5hbWF6b25hd3MuY29tJyldLFxuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgYWN0aW9uczogWydzcXM6U2VuZE1lc3NhZ2UnXSxcbiAgICAgIHJlc291cmNlczogW3F1ZXVlLnF1ZXVlQXJuXSxcbiAgICAgIGNvbmRpdGlvbnM6IHtcbiAgICAgICAgQXJuRXF1YWxzOiB7XG4gICAgICAgICAgJ2F3czpTb3VyY2VBcm4nOiBydWxlLnJ1bGVBcm4sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pKTtcbiAgfSBlbHNlIHtcbiAgICBBbm5vdGF0aW9ucy5vZihydWxlKS5hZGRXYXJuaW5nKGBDYW5ub3QgYWRkIGEgcmVzb3VyY2UgcG9saWN5IHRvIHlvdXIgZGVhZCBsZXR0ZXIgcXVldWUgYXNzb2NpYXRlZCB3aXRoIHJ1bGUgJHtydWxlLnJ1bGVOYW1lfSBiZWNhdXNlIHRoZSBxdWV1ZSBpcyBpbiBhIGRpZmZlcmVudCBhY2NvdW50LiBZb3UgbXVzdCBhZGQgdGhlIHJlc291cmNlIHBvbGljeSBtYW51YWxseSB0byB0aGUgZGVhZCBsZXR0ZXIgcXVldWUgaW4gYWNjb3VudCAke3F1ZXVlLmVudi5hY2NvdW50fS5gKTtcbiAgfVxufVxuXG5cbi8qKlxuICogV2hldGhlciB0d28gc3RyaW5nIHByb2JhYmx5IGNvbnRhaW4gdGhlIHNhbWUgZW52aXJvbm1lbnQgZGltZW5zaW9uIChyZWdpb24gb3IgYWNjb3VudClcbiAqXG4gKiBVc2VkIHRvIGNvbXBhcmUgZWl0aGVyIGFjY291bnRzIG9yIHJlZ2lvbnMsIGFuZCBhbHNvIHJldHVybnMgdHJ1ZSBpZiBib3RoXG4gKiBhcmUgdW5yZXNvbHZlZCAoaW4gd2hpY2ggY2FzZSBib3RoIGFyZSBleHB0ZWQgdG8gYmUgXCJjdXJyZW50IHJlZ2lvblwiIG9yIFwiY3VycmVudCBhY2NvdW50XCIpLlxuICogQGludGVybmFsXG4gKi9cbmZ1bmN0aW9uIHNhbWVFbnZEaW1lbnNpb24oZGltMTogc3RyaW5nLCBkaW0yOiBzdHJpbmcpIHtcbiAgcmV0dXJuIFtUb2tlbkNvbXBhcmlzb24uU0FNRSwgVG9rZW5Db21wYXJpc29uLkJPVEhfVU5SRVNPTFZFRF0uaW5jbHVkZXMoVG9rZW4uY29tcGFyZVN0cmluZ3MoZGltMSwgZGltMikpO1xufSJdfQ==