UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

114 lines 14.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const reference_1 = require("../reference"); const CFN_REFERENCE_SYMBOL = Symbol.for('@aws-cdk/core.CfnReference'); /** * A Token that represents a CloudFormation reference to another resource * * If these references are used in a different stack from where they are * defined, appropriate CloudFormation `Export`s and `Fn::ImportValue`s will be * synthesized automatically instead of the regular CloudFormation references. * * Additionally, the dependency between the stacks will be recorded, and the toolkit * will make sure to deploy producing stack before the consuming stack. * * This magic happens in the prepare() phase, where consuming stacks will call * `consumeFromStack` on these Tokens and if they happen to be exported by a different * Stack, we'll register the dependency. */ class CfnReference extends reference_1.Reference { constructor(value, displayName, target) { // prepend scope path to display name super(value, target, displayName); this.replacementTokens = new Map(); Object.defineProperty(this, CFN_REFERENCE_SYMBOL, { value: true }); } /** * Check whether this is actually a Reference */ static isCfnReference(x) { return CFN_REFERENCE_SYMBOL in x; } /** * Return the CfnReference for the indicated target * * Will make sure that multiple invocations for the same target and intrinsic * return the same CfnReference. Because CfnReferences accumulate state in * the prepare() phase (for the purpose of cross-stack references), it's * important that the state isn't lost if it's lazily created, like so: * * Lazy.stringValue({ produce: () => new CfnReference(...) }) */ static for(target, attribute) { return CfnReference.singletonReference(target, attribute, () => { const cfnIntrinsic = attribute === 'Ref' ? { Ref: target.logicalId } : { 'Fn::GetAtt': [target.logicalId, attribute] }; return new CfnReference(cfnIntrinsic, attribute, target); }); } /** * Return a CfnReference that references a pseudo referencd */ static forPseudo(pseudoName, scope) { return CfnReference.singletonReference(scope, `Pseudo:${pseudoName}`, () => { const cfnIntrinsic = { Ref: pseudoName }; return new CfnReference(cfnIntrinsic, pseudoName, scope); }); } /** * Get or create the table */ static singletonReference(target, attribKey, fresh) { let attribs = CfnReference.referenceTable.get(target); if (!attribs) { attribs = new Map(); CfnReference.referenceTable.set(target, attribs); } let ref = attribs.get(attribKey); if (!ref) { ref = fresh(); attribs.set(attribKey, ref); } return ref; } resolve(context) { // If we have a special token for this consuming stack, resolve that. Otherwise resolve as if // we are in the same stack. const consumingStack = stack_1.Stack.of(context.scope); const token = this.replacementTokens.get(consumingStack); // if (!token && this.isCrossStackReference(consumingStack) && !context.preparing) { // tslint:disable-next-line:max-line-length // throw new Error(`Cross-stack reference (${context.scope.node.path} -> ${this.target.node.path}) has not been assigned a value--call prepare() first`); // } if (token) { return token.resolve(context); } else { return super.resolve(context); } } hasValueForStack(stack) { return this.replacementTokens.has(stack); } assignValueForStack(stack, value) { if (this.hasValueForStack(stack)) { throw new Error(`Cannot assign a reference value twice to the same stack. Use hasValueForStack to check first`); } this.replacementTokens.set(stack, value); } /** * Implementation of toString() that will use the display name */ toString() { return token_1.Token.asString(this, { displayHint: `${this.target.node.id}.${this.displayName}` }); } } exports.CfnReference = CfnReference; /** * Static table where we keep singleton CfnReference instances */ CfnReference.referenceTable = new Map(); const stack_1 = require("../stack"); const token_1 = require("../token"); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2ZuLXJlZmVyZW5jZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNmbi1yZWZlcmVuY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw0Q0FBeUM7QUFFekMsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDLENBQUM7QUFFdEU7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQWEsWUFBYSxTQUFRLHFCQUFTO0lBOER6QyxZQUFzQixLQUFVLEVBQUUsV0FBbUIsRUFBRSxNQUFrQjtRQUN2RSxxQ0FBcUM7UUFDckMsS0FBSyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFFbEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksR0FBRyxFQUFzQixDQUFDO1FBRXZELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLG9CQUFvQixFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDckUsQ0FBQztJQXBFRDs7T0FFRztJQUNJLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBYztRQUN6QyxPQUFPLG9CQUFvQixJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFrQixFQUFFLFNBQWlCO1FBQ3JELE9BQU8sWUFBWSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFO1lBQzdELE1BQU0sWUFBWSxHQUFHLFNBQVMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLEVBQUUsQ0FBRSxNQUFNLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBRSxFQUFDLENBQUM7WUFDeEgsT0FBTyxJQUFJLFlBQVksQ0FBQyxZQUFZLEVBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzNELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ksTUFBTSxDQUFDLFNBQVMsQ0FBQyxVQUFrQixFQUFFLEtBQWdCO1FBQzFELE9BQU8sWUFBWSxDQUFDLGtCQUFrQixDQUFDLEtBQUssRUFBRSxVQUFVLFVBQVUsRUFBRSxFQUFFLEdBQUcsRUFBRTtZQUN6RSxNQUFNLFlBQVksR0FBRyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsQ0FBQztZQUN6QyxPQUFPLElBQUksWUFBWSxDQUFDLFlBQVksRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDM0QsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBT0Q7O09BRUc7SUFDSyxNQUFNLENBQUMsa0JBQWtCLENBQUMsTUFBaUIsRUFBRSxTQUFpQixFQUFFLEtBQXlCO1FBQy9GLElBQUksT0FBTyxHQUFHLFlBQVksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDWixPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUNwQixZQUFZLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7U0FDbEQ7UUFDRCxJQUFJLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxHQUFHLEVBQUU7WUFDUixHQUFHLEdBQUcsS0FBSyxFQUFFLENBQUM7WUFDZCxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQztTQUM3QjtRQUNELE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQWdCTSxPQUFPLENBQUMsT0FBd0I7UUFDckMsNkZBQTZGO1FBQzdGLDRCQUE0QjtRQUM1QixNQUFNLGNBQWMsR0FBRyxhQUFLLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMvQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBRXpELG9GQUFvRjtRQUNwRiwyQ0FBMkM7UUFDM0MsMkpBQTJKO1FBQzNKLElBQUk7UUFFSixJQUFJLEtBQUssRUFBRTtZQUNULE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUMvQjthQUFNO1lBQ0wsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQy9CO0lBQ0gsQ0FBQztJQUVNLGdCQUFnQixDQUFDLEtBQVk7UUFDbEMsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFTSxtQkFBbUIsQ0FBQyxLQUFZLEVBQUUsS0FBa0I7UUFDekQsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDaEMsTUFBTSxJQUFJLEtBQUssQ0FBQyw4RkFBOEYsQ0FBQyxDQUFDO1NBQ2pIO1FBRUQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUNEOztPQUVHO0lBQ0ksUUFBUTtRQUNiLE9BQU8sYUFBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUU7WUFDMUIsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7U0FDMUQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUEzR0gsb0NBNEdDO0FBekVDOztHQUVHO0FBQ1ksMkJBQWMsR0FBRyxJQUFJLEdBQUcsRUFBd0MsQ0FBQztBQTJFbEYsb0NBQWlDO0FBQ2pDLG9DQUFpQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlZmVyZW5jZSB9IGZyb20gXCIuLi9yZWZlcmVuY2VcIjtcblxuY29uc3QgQ0ZOX1JFRkVSRU5DRV9TWU1CT0wgPSBTeW1ib2wuZm9yKCdAYXdzLWNkay9jb3JlLkNmblJlZmVyZW5jZScpO1xuXG4vKipcbiAqIEEgVG9rZW4gdGhhdCByZXByZXNlbnRzIGEgQ2xvdWRGb3JtYXRpb24gcmVmZXJlbmNlIHRvIGFub3RoZXIgcmVzb3VyY2VcbiAqXG4gKiBJZiB0aGVzZSByZWZlcmVuY2VzIGFyZSB1c2VkIGluIGEgZGlmZmVyZW50IHN0YWNrIGZyb20gd2hlcmUgdGhleSBhcmVcbiAqIGRlZmluZWQsIGFwcHJvcHJpYXRlIENsb3VkRm9ybWF0aW9uIGBFeHBvcnRgcyBhbmQgYEZuOjpJbXBvcnRWYWx1ZWBzIHdpbGwgYmVcbiAqIHN5bnRoZXNpemVkIGF1dG9tYXRpY2FsbHkgaW5zdGVhZCBvZiB0aGUgcmVndWxhciBDbG91ZEZvcm1hdGlvbiByZWZlcmVuY2VzLlxuICpcbiAqIEFkZGl0aW9uYWxseSwgdGhlIGRlcGVuZGVuY3kgYmV0d2VlbiB0aGUgc3RhY2tzIHdpbGwgYmUgcmVjb3JkZWQsIGFuZCB0aGUgdG9vbGtpdFxuICogd2lsbCBtYWtlIHN1cmUgdG8gZGVwbG95IHByb2R1Y2luZyBzdGFjayBiZWZvcmUgdGhlIGNvbnN1bWluZyBzdGFjay5cbiAqXG4gKiBUaGlzIG1hZ2ljIGhhcHBlbnMgaW4gdGhlIHByZXBhcmUoKSBwaGFzZSwgd2hlcmUgY29uc3VtaW5nIHN0YWNrcyB3aWxsIGNhbGxcbiAqIGBjb25zdW1lRnJvbVN0YWNrYCBvbiB0aGVzZSBUb2tlbnMgYW5kIGlmIHRoZXkgaGFwcGVuIHRvIGJlIGV4cG9ydGVkIGJ5IGEgZGlmZmVyZW50XG4gKiBTdGFjaywgd2UnbGwgcmVnaXN0ZXIgdGhlIGRlcGVuZGVuY3kuXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5SZWZlcmVuY2UgZXh0ZW5kcyBSZWZlcmVuY2Uge1xuICAvKipcbiAgICogQ2hlY2sgd2hldGhlciB0aGlzIGlzIGFjdHVhbGx5IGEgUmVmZXJlbmNlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGlzQ2ZuUmVmZXJlbmNlKHg6IElSZXNvbHZhYmxlKTogeCBpcyBDZm5SZWZlcmVuY2Uge1xuICAgIHJldHVybiBDRk5fUkVGRVJFTkNFX1NZTUJPTCBpbiB4O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgQ2ZuUmVmZXJlbmNlIGZvciB0aGUgaW5kaWNhdGVkIHRhcmdldFxuICAgKlxuICAgKiBXaWxsIG1ha2Ugc3VyZSB0aGF0IG11bHRpcGxlIGludm9jYXRpb25zIGZvciB0aGUgc2FtZSB0YXJnZXQgYW5kIGludHJpbnNpY1xuICAgKiByZXR1cm4gdGhlIHNhbWUgQ2ZuUmVmZXJlbmNlLiBCZWNhdXNlIENmblJlZmVyZW5jZXMgYWNjdW11bGF0ZSBzdGF0ZSBpblxuICAgKiB0aGUgcHJlcGFyZSgpIHBoYXNlIChmb3IgdGhlIHB1cnBvc2Ugb2YgY3Jvc3Mtc3RhY2sgcmVmZXJlbmNlcyksIGl0J3NcbiAgICogaW1wb3J0YW50IHRoYXQgdGhlIHN0YXRlIGlzbid0IGxvc3QgaWYgaXQncyBsYXppbHkgY3JlYXRlZCwgbGlrZSBzbzpcbiAgICpcbiAgICogICAgIExhenkuc3RyaW5nVmFsdWUoeyBwcm9kdWNlOiAoKSA9PiBuZXcgQ2ZuUmVmZXJlbmNlKC4uLikgfSlcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZm9yKHRhcmdldDogQ2ZuRWxlbWVudCwgYXR0cmlidXRlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gQ2ZuUmVmZXJlbmNlLnNpbmdsZXRvblJlZmVyZW5jZSh0YXJnZXQsIGF0dHJpYnV0ZSwgKCkgPT4ge1xuICAgICAgY29uc3QgY2ZuSW50cmluc2ljID0gYXR0cmlidXRlID09PSAnUmVmJyA/IHsgUmVmOiB0YXJnZXQubG9naWNhbElkIH0gOiB7ICdGbjo6R2V0QXR0JzogWyB0YXJnZXQubG9naWNhbElkLCBhdHRyaWJ1dGUgXX07XG4gICAgICByZXR1cm4gbmV3IENmblJlZmVyZW5jZShjZm5JbnRyaW5zaWMsIGF0dHJpYnV0ZSwgdGFyZ2V0KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBDZm5SZWZlcmVuY2UgdGhhdCByZWZlcmVuY2VzIGEgcHNldWRvIHJlZmVyZW5jZFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmb3JQc2V1ZG8ocHNldWRvTmFtZTogc3RyaW5nLCBzY29wZTogQ29uc3RydWN0KSB7XG4gICAgcmV0dXJuIENmblJlZmVyZW5jZS5zaW5nbGV0b25SZWZlcmVuY2Uoc2NvcGUsIGBQc2V1ZG86JHtwc2V1ZG9OYW1lfWAsICgpID0+IHtcbiAgICAgIGNvbnN0IGNmbkludHJpbnNpYyA9IHsgUmVmOiBwc2V1ZG9OYW1lIH07XG4gICAgICByZXR1cm4gbmV3IENmblJlZmVyZW5jZShjZm5JbnRyaW5zaWMsIHBzZXVkb05hbWUsIHNjb3BlKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGF0aWMgdGFibGUgd2hlcmUgd2Uga2VlcCBzaW5nbGV0b24gQ2ZuUmVmZXJlbmNlIGluc3RhbmNlc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgcmVmZXJlbmNlVGFibGUgPSBuZXcgTWFwPENvbnN0cnVjdCwgTWFwPHN0cmluZywgQ2ZuUmVmZXJlbmNlPj4oKTtcblxuICAvKipcbiAgICogR2V0IG9yIGNyZWF0ZSB0aGUgdGFibGVcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHNpbmdsZXRvblJlZmVyZW5jZSh0YXJnZXQ6IENvbnN0cnVjdCwgYXR0cmliS2V5OiBzdHJpbmcsIGZyZXNoOiAoKSA9PiBDZm5SZWZlcmVuY2UpIHtcbiAgICBsZXQgYXR0cmlicyA9IENmblJlZmVyZW5jZS5yZWZlcmVuY2VUYWJsZS5nZXQodGFyZ2V0KTtcbiAgICBpZiAoIWF0dHJpYnMpIHtcbiAgICAgIGF0dHJpYnMgPSBuZXcgTWFwKCk7XG4gICAgICBDZm5SZWZlcmVuY2UucmVmZXJlbmNlVGFibGUuc2V0KHRhcmdldCwgYXR0cmlicyk7XG4gICAgfVxuICAgIGxldCByZWYgPSBhdHRyaWJzLmdldChhdHRyaWJLZXkpO1xuICAgIGlmICghcmVmKSB7XG4gICAgICByZWYgPSBmcmVzaCgpO1xuICAgICAgYXR0cmlicy5zZXQoYXR0cmliS2V5LCByZWYpO1xuICAgIH1cbiAgICByZXR1cm4gcmVmO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBUb2tlbnMgdGhhdCBzaG91bGQgYmUgcmV0dXJuZWQgZm9yIGVhY2ggY29uc3VtaW5nIHN0YWNrIChhcyBkZWNpZGVkIGJ5IHRoZSBwcm9kdWNpbmcgU3RhY2spXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHJlcGxhY2VtZW50VG9rZW5zOiBNYXA8U3RhY2ssIElSZXNvbHZhYmxlPjtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IodmFsdWU6IGFueSwgZGlzcGxheU5hbWU6IHN0cmluZywgdGFyZ2V0OiBJQ29uc3RydWN0KSB7XG4gICAgLy8gcHJlcGVuZCBzY29wZSBwYXRoIHRvIGRpc3BsYXkgbmFtZVxuICAgIHN1cGVyKHZhbHVlLCB0YXJnZXQsIGRpc3BsYXlOYW1lKTtcblxuICAgIHRoaXMucmVwbGFjZW1lbnRUb2tlbnMgPSBuZXcgTWFwPFN0YWNrLCBJUmVzb2x2YWJsZT4oKTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBDRk5fUkVGRVJFTkNFX1NZTUJPTCwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIHB1YmxpYyByZXNvbHZlKGNvbnRleHQ6IElSZXNvbHZlQ29udGV4dCk6IGFueSB7XG4gICAgLy8gSWYgd2UgaGF2ZSBhIHNwZWNpYWwgdG9rZW4gZm9yIHRoaXMgY29uc3VtaW5nIHN0YWNrLCByZXNvbHZlIHRoYXQuIE90aGVyd2lzZSByZXNvbHZlIGFzIGlmXG4gICAgLy8gd2UgYXJlIGluIHRoZSBzYW1lIHN0YWNrLlxuICAgIGNvbnN0IGNvbnN1bWluZ1N0YWNrID0gU3RhY2sub2YoY29udGV4dC5zY29wZSk7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnJlcGxhY2VtZW50VG9rZW5zLmdldChjb25zdW1pbmdTdGFjayk7XG5cbiAgICAvLyBpZiAoIXRva2VuICYmIHRoaXMuaXNDcm9zc1N0YWNrUmVmZXJlbmNlKGNvbnN1bWluZ1N0YWNrKSAmJiAhY29udGV4dC5wcmVwYXJpbmcpIHtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG4gICAgLy8gICB0aHJvdyBuZXcgRXJyb3IoYENyb3NzLXN0YWNrIHJlZmVyZW5jZSAoJHtjb250ZXh0LnNjb3BlLm5vZGUucGF0aH0gLT4gJHt0aGlzLnRhcmdldC5ub2RlLnBhdGh9KSBoYXMgbm90IGJlZW4gYXNzaWduZWQgYSB2YWx1ZS0tY2FsbCBwcmVwYXJlKCkgZmlyc3RgKTtcbiAgICAvLyB9XG5cbiAgICBpZiAodG9rZW4pIHtcbiAgICAgIHJldHVybiB0b2tlbi5yZXNvbHZlKGNvbnRleHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc3VwZXIucmVzb2x2ZShjb250ZXh0KTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgaGFzVmFsdWVGb3JTdGFjayhzdGFjazogU3RhY2spIHtcbiAgICByZXR1cm4gdGhpcy5yZXBsYWNlbWVudFRva2Vucy5oYXMoc3RhY2spO1xuICB9XG5cbiAgcHVibGljIGFzc2lnblZhbHVlRm9yU3RhY2soc3RhY2s6IFN0YWNrLCB2YWx1ZTogSVJlc29sdmFibGUpIHtcbiAgICBpZiAodGhpcy5oYXNWYWx1ZUZvclN0YWNrKHN0YWNrKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgYXNzaWduIGEgcmVmZXJlbmNlIHZhbHVlIHR3aWNlIHRvIHRoZSBzYW1lIHN0YWNrLiBVc2UgaGFzVmFsdWVGb3JTdGFjayB0byBjaGVjayBmaXJzdGApO1xuICAgIH1cblxuICAgIHRoaXMucmVwbGFjZW1lbnRUb2tlbnMuc2V0KHN0YWNrLCB2YWx1ZSk7XG4gIH1cbiAgLyoqXG4gICAqIEltcGxlbWVudGF0aW9uIG9mIHRvU3RyaW5nKCkgdGhhdCB3aWxsIHVzZSB0aGUgZGlzcGxheSBuYW1lXG4gICAqL1xuICBwdWJsaWMgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gVG9rZW4uYXNTdHJpbmcodGhpcywge1xuICAgICAgZGlzcGxheUhpbnQ6IGAke3RoaXMudGFyZ2V0Lm5vZGUuaWR9LiR7dGhpcy5kaXNwbGF5TmFtZX1gXG4gICAgfSk7XG4gIH1cbn1cblxuaW1wb3J0IHsgQ2ZuRWxlbWVudCB9IGZyb20gXCIuLi9jZm4tZWxlbWVudFwiO1xuaW1wb3J0IHsgQ29uc3RydWN0LCBJQ29uc3RydWN0IH0gZnJvbSBcIi4uL2NvbnN0cnVjdC1jb21wYXRcIjtcbmltcG9ydCB7IElSZXNvbHZhYmxlLCBJUmVzb2x2ZUNvbnRleHQgfSBmcm9tIFwiLi4vcmVzb2x2YWJsZVwiO1xuaW1wb3J0IHsgU3RhY2sgfSBmcm9tIFwiLi4vc3RhY2tcIjtcbmltcG9ydCB7IFRva2VuIH0gZnJvbSBcIi4uL3Rva2VuXCI7XG4iXX0=