@aws-cdk/core
Version:
AWS Cloud Development Kit Core Library
165 lines • 18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenMap = void 0;
const token_1 = require("../token");
const encoding_1 = require("./encoding");
const glob = global;
const STRING_SYMBOL = Symbol.for('@aws-cdk/core.TokenMap.STRING');
const LIST_SYMBOL = Symbol.for('@aws-cdk/core.TokenMap.LIST');
const NUMBER_SYMBOL = Symbol.for('@aws-cdk/core.TokenMap.NUMBER');
/**
* Central place where we keep a mapping from Tokens to their String representation
*
* The string representation is used to embed token into strings,
* and stored to be able to reverse that mapping.
*
* All instances of TokenStringMap share the same storage, so that this process
* works even when different copies of the library are loaded.
*/
class TokenMap {
constructor() {
this.stringTokenMap = new Map();
this.numberTokenMap = new Map();
this.tokenCounter = 0;
}
/**
* Singleton instance of the token string map
*/
static instance() {
if (!glob.__cdkTokenMap) {
glob.__cdkTokenMap = new TokenMap();
}
return glob.__cdkTokenMap;
}
/**
* Generate a unique string for this Token, returning a key
*
* Every call for the same Token will produce a new unique string, no
* attempt is made to deduplicate. Token objects should cache the
* value themselves, if required.
*
* The token can choose (part of) its own representation string with a
* hint. This may be used to produce aesthetically pleasing and
* recognizable token representations for humans.
*/
registerString(token, displayHint) {
return cachedValue(token, STRING_SYMBOL, () => {
const key = this.registerStringKey(token, displayHint);
return `${encoding_1.BEGIN_STRING_TOKEN_MARKER}${key}${encoding_1.END_TOKEN_MARKER}`;
});
}
/**
* Generate a unique string for this Token, returning a key
*/
registerList(token, displayHint) {
return cachedValue(token, LIST_SYMBOL, () => {
const key = this.registerStringKey(token, displayHint);
return [`${encoding_1.BEGIN_LIST_TOKEN_MARKER}${key}${encoding_1.END_TOKEN_MARKER}`];
});
}
/**
* Create a unique number representation for this Token and return it
*/
registerNumber(token) {
return cachedValue(token, NUMBER_SYMBOL, () => {
return this.registerNumberKey(token);
});
}
/**
* Lookup a token from an encoded value
*/
tokenFromEncoding(x) {
if (typeof x === 'string') {
return this.lookupString(x);
}
if (Array.isArray(x)) {
return this.lookupList(x);
}
if (token_1.Token.isUnresolved(x)) {
return x;
}
return undefined;
}
/**
* Reverse a string representation into a Token object
*/
lookupString(s) {
const fragments = this.splitString(s);
if (fragments.tokens.length > 0 && fragments.length === 1) {
return fragments.firstToken;
}
return undefined;
}
/**
* Reverse a string representation into a Token object
*/
lookupList(xs) {
if (xs.length !== 1) {
return undefined;
}
const str = encoding_1.TokenString.forListToken(xs[0]);
const fragments = str.split(this.lookupToken.bind(this));
if (fragments.length === 1) {
return fragments.firstToken;
}
return undefined;
}
/**
* Split a string into literals and Tokens
*/
splitString(s) {
const str = encoding_1.TokenString.forString(s);
return str.split(this.lookupToken.bind(this));
}
/**
* Reverse a number encoding into a Token, or undefined if the number wasn't a Token
*/
lookupNumberToken(x) {
const tokenIndex = encoding_1.extractTokenDouble(x);
if (tokenIndex === undefined) {
return undefined;
}
const t = this.numberTokenMap.get(tokenIndex);
if (t === undefined) {
throw new Error('Encoded representation of unknown number Token found');
}
return t;
}
/**
* Find a Token by key.
*
* This excludes the token markers.
*/
lookupToken(key) {
const token = this.stringTokenMap.get(key);
if (!token) {
throw new Error(`Unrecognized token key: ${key}`);
}
return token;
}
registerStringKey(token, displayHint) {
const counter = this.tokenCounter++;
const representation = (displayHint || 'TOKEN').replace(new RegExp(`[^${encoding_1.VALID_KEY_CHARS}]`, 'g'), '.');
const key = `${representation}.${counter}`;
this.stringTokenMap.set(key, token);
return key;
}
registerNumberKey(token) {
const counter = this.tokenCounter++;
this.numberTokenMap.set(counter, token);
return encoding_1.createTokenDouble(counter);
}
}
exports.TokenMap = TokenMap;
/**
* Get a cached value for an object, storing it on the object in a symbol
*/
function cachedValue(x, sym, prod) {
let cached = x[sym];
if (cached === undefined) {
cached = prod();
Object.defineProperty(x, sym, { value: cached });
}
return cached;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4tbWFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidG9rZW4tbWFwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLG9DQUFpQztBQUNqQyx5Q0FHb0I7QUFFcEIsTUFBTSxJQUFJLEdBQUcsTUFBYSxDQUFDO0FBRTNCLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsK0JBQStCLENBQUMsQ0FBQztBQUNsRSxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLDZCQUE2QixDQUFDLENBQUM7QUFDOUQsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO0FBRWxFOzs7Ozs7OztHQVFHO0FBQ0gsTUFBYSxRQUFRO0lBQXJCO1FBV21CLG1CQUFjLEdBQUcsSUFBSSxHQUFHLEVBQXVCLENBQUM7UUFDaEQsbUJBQWMsR0FBRyxJQUFJLEdBQUcsRUFBdUIsQ0FBQztRQUN6RCxpQkFBWSxHQUFHLENBQUMsQ0FBQztJQXNIM0IsQ0FBQztJQWxJQzs7T0FFRztJQUNJLE1BQU0sQ0FBQyxRQUFRO1FBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxRQUFRLEVBQUUsQ0FBQztTQUNyQztRQUNELE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QixDQUFDO0lBTUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLGNBQWMsQ0FBQyxLQUFrQixFQUFFLFdBQW9CO1FBQzVELE9BQU8sV0FBVyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsR0FBRyxFQUFFO1lBQzVDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDdkQsT0FBTyxHQUFHLG9DQUF5QixHQUFHLEdBQUcsR0FBRywyQkFBZ0IsRUFBRSxDQUFDO1FBQ2pFLENBQUMsQ0FBQyxDQUFDO0lBQ0ws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QUM7SUFDcEMsSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFO1FBQ3hCLE1BQU0sR0FBRyxJQUFJLEVBQUUsQ0FBQztRQUNoQixNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztLQUNsRDtJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJUmVzb2x2YWJsZSB9IGZyb20gJy4uL3Jlc29sdmFibGUnO1xuaW1wb3J0IHsgVG9rZW5pemVkU3RyaW5nRnJhZ21lbnRzIH0gZnJvbSAnLi4vc3RyaW5nLWZyYWdtZW50cyc7XG5pbXBvcnQgeyBUb2tlbiB9IGZyb20gJy4uL3Rva2VuJztcbmltcG9ydCB7XG4gIEJFR0lOX0xJU1RfVE9LRU5fTUFSS0VSLCBCRUdJTl9TVFJJTkdfVE9LRU5fTUFSS0VSLCBjcmVhdGVUb2tlbkRvdWJsZSxcbiAgRU5EX1RPS0VOX01BUktFUiwgZXh0cmFjdFRva2VuRG91YmxlLCBUb2tlblN0cmluZywgVkFMSURfS0VZX0NIQVJTLFxufSBmcm9tICcuL2VuY29kaW5nJztcblxuY29uc3QgZ2xvYiA9IGdsb2JhbCBhcyBhbnk7XG5cbmNvbnN0IFNUUklOR19TWU1CT0wgPSBTeW1ib2wuZm9yKCdAYXdzLWNkay9jb3JlLlRva2VuTWFwLlNUUklORycpO1xuY29uc3QgTElTVF9TWU1CT0wgPSBTeW1ib2wuZm9yKCdAYXdzLWNkay9jb3JlLlRva2VuTWFwLkxJU1QnKTtcbmNvbnN0IE5VTUJFUl9TWU1CT0wgPSBTeW1ib2wuZm9yKCdAYXdzLWNkay9jb3JlLlRva2VuTWFwLk5VTUJFUicpO1xuXG4vKipcbiAqIENlbnRyYWwgcGxhY2Ugd2hlcmUgd2Uga2VlcCBhIG1hcHBpbmcgZnJvbSBUb2tlbnMgdG8gdGhlaXIgU3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gKlxuICogVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBpcyB1c2VkIHRvIGVtYmVkIHRva2VuIGludG8gc3RyaW5ncyxcbiAqIGFuZCBzdG9yZWQgdG8gYmUgYWJsZSB0byByZXZlcnNlIHRoYXQgbWFwcGluZy5cbiAqXG4gKiBBbGwgaW5zdGFuY2VzIG9mIFRva2VuU3RyaW5nTWFwIHNoYXJlIHRoZSBzYW1lIHN0b3JhZ2UsIHNvIHRoYXQgdGhpcyBwcm9jZXNzXG4gKiB3b3JrcyBldmVuIHdoZW4gZGlmZmVyZW50IGNvcGllcyBvZiB0aGUgbGlicmFyeSBhcmUgbG9hZGVkLlxuICovXG5leHBvcnQgY2xhc3MgVG9rZW5NYXAge1xuICAvKipcbiAgICogU2luZ2xldG9uIGluc3RhbmNlIG9mIHRoZSB0b2tlbiBzdHJpbmcgbWFwXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGluc3RhbmNlKCk6IFRva2VuTWFwIHtcbiAgICBpZiAoIWdsb2IuX19jZGtUb2tlbk1hcCkge1xuICAgICAgZ2xvYi5fX2Nka1Rva2VuTWFwID0gbmV3IFRva2VuTWFwKCk7XG4gICAgfVxuICAgIHJldHVybiBnbG9iLl9fY2RrVG9rZW5NYXA7XG4gIH1cblxuICBwcml2YXRlIHJlYWRvbmx5IHN0cmluZ1Rva2VuTWFwID0gbmV3IE1hcDxzdHJpbmcsIElSZXNvbHZhYmxlPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IG51bWJlclRva2VuTWFwID0gbmV3IE1hcDxudW1iZXIsIElSZXNvbHZhYmxlPigpO1xuICBwcml2YXRlIHRva2VuQ291bnRlciA9IDA7XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIGEgdW5pcXVlIHN0cmluZyBmb3IgdGhpcyBUb2tlbiwgcmV0dXJuaW5nIGEga2V5XG4gICAqXG4gICAqIEV2ZXJ5IGNhbGwgZm9yIHRoZSBzYW1lIFRva2VuIHdpbGwgcHJvZHVjZSBhIG5ldyB1bmlxdWUgc3RyaW5nLCBub1xuICAgKiBhdHRlbXB0IGlzIG1hZGUgdG8gZGVkdXBsaWNhdGUuIFRva2VuIG9iamVjdHMgc2hvdWxkIGNhY2hlIHRoZVxuICAgKiB2YWx1ZSB0aGVtc2VsdmVzLCBpZiByZXF1aXJlZC5cbiAgICpcbiAgICogVGhlIHRva2VuIGNhbiBjaG9vc2UgKHBhcnQgb2YpIGl0cyBvd24gcmVwcmVzZW50YXRpb24gc3RyaW5nIHdpdGggYVxuICAgKiBoaW50LiBUaGlzIG1heSBiZSB1c2VkIHRvIHByb2R1Y2UgYWVzdGhldGljYWxseSBwbGVhc2luZyBhbmRcbiAgICogcmVjb2duaXphYmxlIHRva2VuIHJlcHJlc2VudGF0aW9ucyBmb3IgaHVtYW5zLlxuICAgKi9cbiAgcHVibGljIHJlZ2lzdGVyU3RyaW5nKHRva2VuOiBJUmVzb2x2YWJsZSwgZGlzcGxheUhpbnQ/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBjYWNoZWRWYWx1ZSh0b2tlbiwgU1RSSU5HX1NZTUJPTCwgKCkgPT4ge1xuICAgICAgY29uc3Qga2V5ID0gdGhpcy5yZWdpc3RlclN0cmluZ0tleSh0b2tlbiwgZGlzcGxheUhpbnQpO1xuICAgICAgcmV0dXJuIGAke0JFR0lOX1NUUklOR19UT0tFTl9NQVJLRVJ9JHtrZXl9JHtFTkRfVE9LRU5fTUFSS0VSfWA7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgYSB1bmlxdWUgc3RyaW5nIGZvciB0aGlzIFRva2VuLCByZXR1cm5pbmcgYSBrZXlcbiAgICovXG4gIHB1YmxpYyByZWdpc3Rlckxpc3QodG9rZW46IElSZXNvbHZhYmxlLCBkaXNwbGF5SGludD86IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gY2FjaGVkVmFsdWUodG9rZW4sIExJU1RfU1lNQk9MLCAoKSA9PiB7XG4gICAgICBjb25zdCBrZXkgPSB0aGlzLnJlZ2lzdGVyU3RyaW5nS2V5KHRva2VuLCBkaXNwbGF5SGludCk7XG4gICAgICByZXR1cm4gW2Ake0JFR0lOX0xJU1RfVE9LRU5fTUFSS0VSfSR7a2V5fSR7RU5EX1RPS0VOX01BUktFUn1gXTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSB1bmlxdWUgbnVtYmVyIHJlcHJlc2VudGF0aW9uIGZvciB0aGlzIFRva2VuIGFuZCByZXR1cm4gaXRcbiAgICovXG4gIHB1YmxpYyByZWdpc3Rlck51bWJlcih0b2tlbjogSVJlc29sdmFibGUpOiBudW1iZXIge1xuICAgIHJldHVybiBjYWNoZWRWYWx1ZSh0b2tlbiwgTlVNQkVSX1NZTUJPTCwgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVnaXN0ZXJOdW1iZXJLZXkodG9rZW4pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIExvb2t1cCBhIHRva2VuIGZyb20gYW4gZW5jb2RlZCB2YWx1ZVxuICAgKi9cbiAgcHVibGljIHRva2VuRnJvbUVuY29kaW5nKHg6IGFueSk6IElSZXNvbHZhYmxlIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodHlwZW9mIHggPT09ICdzdHJpbmcnKSB7IHJldHVybiB0aGlzLmxvb2t1cFN0cmluZyh4KTsgfVxuICAgIGlmIChBcnJheS5pc0FycmF5KHgpKSB7IHJldHVybiB0aGlzLmxvb2t1cExpc3QoeCk7IH1cbiAgICBpZiAoVG9rZW4uaXNVbnJlc29sdmVkKHgpKSB7IHJldHVybiB4OyB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXZlcnNlIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGludG8gYSBUb2tlbiBvYmplY3RcbiAgICovXG4gIHB1YmxpYyBsb29rdXBTdHJpbmcoczogc3RyaW5nKTogSVJlc29sdmFibGUgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGZyYWdtZW50cyA9IHRoaXMuc3BsaXRTdHJpbmcocyk7XG4gICAgaWYgKGZyYWdtZW50cy50b2tlbnMubGVuZ3RoID4gMCAmJiBmcmFnbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4gZnJhZ21lbnRzLmZpcnN0VG9rZW47XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogUmV2ZXJzZSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBpbnRvIGEgVG9rZW4gb2JqZWN0XG4gICAqL1xuICBwdWJsaWMgbG9va3VwTGlzdCh4czogc3RyaW5nW10pOiBJUmVzb2x2YWJsZSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHhzLmxlbmd0aCAhPT0gMSkgeyByZXR1cm4gdW5kZWZpbmVkOyB9XG4gICAgY29uc3Qgc3RyID0gVG9rZW5TdHJpbmcuZm9yTGlzdFRva2VuKHhzWzBdKTtcbiAgICBjb25zdCBmcmFnbWVudHMgPSBzdHIuc3BsaXQodGhpcy5sb29rdXBUb2tlbi5iaW5kKHRoaXMpKTtcbiAgICBpZiAoZnJhZ21lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIGZyYWdtZW50cy5maXJzdFRva2VuO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFNwbGl0IGEgc3RyaW5nIGludG8gbGl0ZXJhbHMgYW5kIFRva2Vuc1xuICAgKi9cbiAgcHVibGljIHNwbGl0U3RyaW5nKHM6IHN0cmluZyk6IFRva2VuaXplZFN0cmluZ0ZyYWdtZW50cyB7XG4gICAgY29uc3Qgc3RyID0gVG9rZW5TdHJpbmcuZm9yU3RyaW5nKHMpO1xuICAgIHJldHVybiBzdHIuc3BsaXQodGhpcy5sb29rdXBUb2tlbi5iaW5kKHRoaXMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXZlcnNlIGEgbnVtYmVyIGVuY29kaW5nIGludG8gYSBUb2tlbiwgb3IgdW5kZWZpbmVkIGlmIHRoZSBudW1iZXIgd2Fzbid0IGEgVG9rZW5cbiAgICovXG4gIHB1YmxpYyBsb29rdXBOdW1iZXJUb2tlbih4OiBudW1iZXIpOiBJUmVzb2x2YWJsZSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgdG9rZW5JbmRleCA9IGV4dHJhY3RUb2tlbkRvdWJsZSh4KTtcbiAgICBpZiAodG9rZW5JbmRleCA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH1cbiAgICBjb25zdCB0ID0gdGhpcy5udW1iZXJUb2tlbk1hcC5nZXQodG9rZW5JbmRleCk7XG4gICAgaWYgKHQgPT09IHVuZGVmaW5lZCkgeyB0aHJvdyBuZXcgRXJyb3IoJ0VuY29kZWQgcmVwcmVzZW50YXRpb24gb2YgdW5rbm93biBudW1iZXIgVG9rZW4gZm91bmQnKTsgfVxuICAgIHJldHVybiB0O1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmQgYSBUb2tlbiBieSBrZXkuXG4gICAqXG4gICAqIFRoaXMgZXhjbHVkZXMgdGhlIHRva2VuIG1hcmtlcnMuXG4gICAqL1xuICBwdWJsaWMgbG9va3VwVG9rZW4oa2V5OiBzdHJpbmcpOiBJUmVzb2x2YWJsZSB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnN0cmluZ1Rva2VuTWFwLmdldChrZXkpO1xuICAgIGlmICghdG9rZW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5yZWNvZ25pemVkIHRva2VuIGtleTogJHtrZXl9YCk7XG4gICAgfVxuICAgIHJldHVybiB0b2tlbjtcbiAgfVxuXG4gIHByaXZhdGUgcmVnaXN0ZXJTdHJpbmdLZXkodG9rZW46IElSZXNvbHZhYmxlLCBkaXNwbGF5SGludD86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgY291bnRlciA9IHRoaXMudG9rZW5Db3VudGVyKys7XG4gICAgY29uc3QgcmVwcmVzZW50YXRpb24gPSAoZGlzcGxheUhpbnQgfHwgJ1RPS0VOJykucmVwbGFjZShuZXcgUmVnRXhwKGBbXiR7VkFMSURfS0VZX0NIQVJTfV1gLCAnZycpLCAnLicpO1xuICAgIGNvbnN0IGtleSA9IGAke3JlcHJlc2VudGF0aW9ufS4ke2NvdW50ZXJ9YDtcbiAgICB0aGlzLnN0cmluZ1Rva2VuTWFwLnNldChrZXksIHRva2VuKTtcbiAgICByZXR1cm4ga2V5O1xuICB9XG5cbiAgcHJpdmF0ZSByZWdpc3Rlck51bWJlcktleSh0b2tlbjogSVJlc29sdmFibGUpOiBudW1iZXIge1xuICAgIGNvbnN0IGNvdW50ZXIgPSB0aGlzLnRva2VuQ291bnRlcisrO1xuICAgIHRoaXMubnVtYmVyVG9rZW5NYXAuc2V0KGNvdW50ZXIsIHRva2VuKTtcbiAgICByZXR1cm4gY3JlYXRlVG9rZW5Eb3VibGUoY291bnRlcik7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgYSBjYWNoZWQgdmFsdWUgZm9yIGFuIG9iamVjdCwgc3RvcmluZyBpdCBvbiB0aGUgb2JqZWN0IGluIGEgc3ltYm9sXG4gKi9cbmZ1bmN0aW9uIGNhY2hlZFZhbHVlPEEgZXh0ZW5kcyBvYmplY3QsIEI+KHg6IEEsIHN5bTogc3ltYm9sLCBwcm9kOiAoKSA9PiBCKSB7XG4gIGxldCBjYWNoZWQgPSAoeCBhcyBhbnkpW3N5bSBhcyBhbnldO1xuICBpZiAoY2FjaGVkID09PSB1bmRlZmluZWQpIHtcbiAgICBjYWNoZWQgPSBwcm9kKCk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHgsIHN5bSwgeyB2YWx1ZTogY2FjaGVkIH0pO1xuICB9XG4gIHJldHVybiBjYWNoZWQ7XG59XG4iXX0=