UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

201 lines 21.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const string_fragments_1 = require("../string-fragments"); const token_1 = require("../token"); // Details for encoding and decoding Tokens into native types; should not be exported exports.BEGIN_STRING_TOKEN_MARKER = '${Token['; exports.BEGIN_LIST_TOKEN_MARKER = '#{Token['; exports.END_TOKEN_MARKER = ']}'; exports.VALID_KEY_CHARS = 'a-zA-Z0-9:._-'; const QUOTED_BEGIN_STRING_TOKEN_MARKER = regexQuote(exports.BEGIN_STRING_TOKEN_MARKER); const QUOTED_BEGIN_LIST_TOKEN_MARKER = regexQuote(exports.BEGIN_LIST_TOKEN_MARKER); const QUOTED_END_TOKEN_MARKER = regexQuote(exports.END_TOKEN_MARKER); const STRING_TOKEN_REGEX = new RegExp(`${QUOTED_BEGIN_STRING_TOKEN_MARKER}([${exports.VALID_KEY_CHARS}]+)${QUOTED_END_TOKEN_MARKER}`, 'g'); const LIST_TOKEN_REGEX = new RegExp(`${QUOTED_BEGIN_LIST_TOKEN_MARKER}([${exports.VALID_KEY_CHARS}]+)${QUOTED_END_TOKEN_MARKER}`, 'g'); /** * A string with markers in it that can be resolved to external values */ class TokenString { constructor(str, re) { this.str = str; this.re = re; } /** * Returns a `TokenString` for this string. */ static forString(s) { return new TokenString(s, STRING_TOKEN_REGEX); } /** * Returns a `TokenString` for this string (must be the first string element of the list) */ static forListToken(s) { return new TokenString(s, LIST_TOKEN_REGEX); } /** * Split string on markers, substituting markers with Tokens */ split(lookup) { const ret = new string_fragments_1.TokenizedStringFragments(); let rest = 0; this.re.lastIndex = 0; // Reset let m = this.re.exec(this.str); while (m) { if (m.index > rest) { ret.addLiteral(this.str.substring(rest, m.index)); } ret.addToken(lookup(m[1])); rest = this.re.lastIndex; m = this.re.exec(this.str); } if (rest < this.str.length) { ret.addLiteral(this.str.substring(rest)); } return ret; } /** * Indicates if this string includes tokens. */ test() { this.re.lastIndex = 0; // Reset return this.re.test(this.str); } } exports.TokenString = TokenString; /** * Quote a string for use in a regex */ function regexQuote(s) { return s.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"); } exports.regexQuote = regexQuote; /** * Concatenator that disregards the input * * Can be used when traversing the tokens is important, but the * result isn't. */ class NullConcat { join(_left, _right) { return undefined; } } exports.NullConcat = NullConcat; function containsListTokenElement(xs) { return xs.some(x => typeof (x) === 'string' && TokenString.forListToken(x).test()); } exports.containsListTokenElement = containsListTokenElement; /** * Returns true if obj is a token (i.e. has the resolve() method or is a string * that includes token markers), or it's a listifictaion of a Token string. * * @param obj The object to test. */ function unresolved(obj) { if (typeof (obj) === 'string') { return TokenString.forString(obj).test(); } else if (typeof obj === 'number') { return extractTokenDouble(obj) !== undefined; } else if (Array.isArray(obj) && obj.length === 1) { return typeof (obj[0]) === 'string' && TokenString.forListToken(obj[0]).test(); } else { return token_1.isResolvableObject(obj); } } exports.unresolved = unresolved; /** * Bit pattern in the top 16 bits of a double to indicate a Token * * An IEEE double in LE memory order looks like this (grouped * into octets, then grouped into 32-bit words): * * mmmmmmmm.mmmmmmmm.mmmmmmmm.mmmmmmmm | mmmmmmmm.mmmmmmmm.EEEEmmmm.sEEEEEEE * * - m: mantissa (52 bits) * - E: exponent (11 bits) * - s: sign (1 bit) * * We put the following marker into the top 16 bits (exponent and sign), and * use the mantissa part to encode the token index. To save some bit twiddling * we use all top 16 bits for the tag. That loses us 4 mantissa bits to store * information in but we still have 48, which is going to be plenty for any * number of tokens to be created during the lifetime of any CDK application. * * Can't have all bits set because that makes a NaN, so unset the least * significant exponent bit. * * Currently not supporting BE architectures. */ // tslint:disable-next-line:no-bitwise const DOUBLE_TOKEN_MARKER_BITS = 0xFBFF << 16; /** * Highest encodable number */ const MAX_ENCODABLE_INTEGER = Math.pow(2, 48) - 1; /** * Get 2^32 as a number, so we can do multiplication and div instead of bit shifting * * Necessary because in JavaScript, bit operations implicitly convert * to int32 and we need them to work on "int64"s. * * So instead of x >> 32, we do Math.floor(x / 2^32), and vice versa. */ const BITS32 = Math.pow(2, 32); /** * Return a special Double value that encodes the given nonnegative integer * * We use this to encode Token ordinals. */ function createTokenDouble(x) { if (Math.floor(x) !== x || x < 0) { throw new Error('Can only encode positive integers'); } if (x > MAX_ENCODABLE_INTEGER) { throw new Error(`Got an index too large to encode: ${x}`); } const buf = new ArrayBuffer(8); const ints = new Uint32Array(buf); // tslint:disable:no-bitwise ints[0] = x & 0x0000FFFFFFFF; // Bottom 32 bits of number // This needs an "x >> 32" but that will make it a 32-bit number instead // of a 64-bit number. ints[1] = (shr32(x) & 0xFFFF) | DOUBLE_TOKEN_MARKER_BITS; // Top 16 bits of number and the mask // tslint:enable:no-bitwise return (new Float64Array(buf))[0]; } exports.createTokenDouble = createTokenDouble; /** * Shift a 64-bit int right 32 bits */ function shr32(x) { return Math.floor(x / BITS32); } /** * Shift a 64-bit left 32 bits */ function shl32(x) { return x * BITS32; } /** * Extract the encoded integer out of the special Double value * * Returns undefined if the float is a not an encoded token. */ function extractTokenDouble(encoded) { const buf = new ArrayBuffer(8); (new Float64Array(buf))[0] = encoded; const ints = new Uint32Array(buf); // tslint:disable:no-bitwise if ((ints[1] & 0xFFFF0000) !== DOUBLE_TOKEN_MARKER_BITS) { return undefined; } // Must use + instead of | here (bitwise operations // will force 32-bits integer arithmetic, + will not). return ints[0] + shl32(ints[1] & 0xFFFF); // tslint:enable:no-bitwise } exports.extractTokenDouble = extractTokenDouble; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJlbmNvZGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUNBLDBEQUErRDtBQUMvRCxvQ0FBOEM7QUFFOUMscUZBQXFGO0FBRXhFLFFBQUEseUJBQXlCLEdBQUcsVUFBVSxDQUFDO0FBQ3ZDLFFBQUEsdUJBQXVCLEdBQUcsVUFBVSxDQUFDO0FBQ3JDLFFBQUEsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO0FBRXhCLFFBQUEsZUFBZSxHQUFHLGVBQWUsQ0FBQztBQUUvQyxNQUFNLGdDQUFnQyxHQUFHLFVBQVUsQ0FBQyxpQ0FBeUIsQ0FBQyxDQUFDO0FBQy9FLE1BQU0sOEJBQThCLEdBQUcsVUFBVSxDQUFDLCtCQUF1QixDQUFDLENBQUM7QUFDM0UsTUFBTSx1QkFBdUIsR0FBRyxVQUFVLENBQUMsd0JBQWdCLENBQUMsQ0FBQztBQUU3RCxNQUFNLGtCQUFrQixHQUFHLElBQUksTUFBTSxDQUFDLEdBQUcsZ0NBQWdDLEtBQUssdUJBQWUsTUFBTSx1QkFBdUIsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ25JLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxNQUFNLENBQUMsR0FBRyw4QkFBOEIsS0FBSyx1QkFBZSxNQUFNLHVCQUF1QixFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFFL0g7O0dBRUc7QUFDSCxNQUFhLFdBQVc7SUFldEIsWUFBNkIsR0FBVyxFQUFtQixFQUFVO1FBQXhDLFFBQUcsR0FBSCxHQUFHLENBQVE7UUFBbUIsT0FBRSxHQUFGLEVBQUUsQ0FBUTtJQUNyRSxDQUFDO0lBZkQ7O09BRUc7SUFDSSxNQUFNLENBQUMsU0FBUyxDQUFDLENBQVM7UUFDL0IsT0FBTyxJQUFJLFdBQVcsQ0FBQyxDQUFDLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsWUFBWSxDQUFDLENBQVM7UUFDbEMsT0FBTyxJQUFJLFdBQVcs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d0JBQXdCLENBQUMsQ0FBQyxxQ0FBcUM7SUFDL0YsMkJBQTJCO0lBRTNCLE9BQU8sQ0FBQyxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BDLENBQUM7QUFwQkQsOENBb0JDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLEtBQUssQ0FBQyxDQUFTO0lBQ3RCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUM7QUFDaEMsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxLQUFLLENBQUMsQ0FBUztJQUN0QixPQUFPLENBQUMsR0FBRyxNQUFNLENBQUM7QUFDcEIsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixrQkFBa0IsQ0FBQyxPQUFlO0lBQ2hELE1BQU0sR0FBRyxHQUFHLElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQy9CLENBQUMsSUFBSSxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUM7SUFFckMsTUFBTSxJQUFJLEdBQUcsSUFBSSxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFbEMsNEJBQTRCO0lBQzVCLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLEtBQUssd0JBQXdCLEVBQUU7UUFDdkQsT0FBTyxTQUFTLENBQUM7S0FDbEI7SUFFRCxtREFBbUQ7SUFDbkQsc0RBQXNEO0lBQ3RELE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUM7SUFDekMsMkJBQTJCO0FBQzdCLENBQUM7QUFmRCxnREFlQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IElGcmFnbWVudENvbmNhdGVuYXRvciwgSVJlc29sdmFibGUgfSBmcm9tIFwiLi4vcmVzb2x2YWJsZVwiO1xuaW1wb3J0IHsgVG9rZW5pemVkU3RyaW5nRnJhZ21lbnRzIH0gZnJvbSBcIi4uL3N0cmluZy1mcmFnbWVudHNcIjtcbmltcG9ydCB7IGlzUmVzb2x2YWJsZU9iamVjdCB9IGZyb20gXCIuLi90b2tlblwiO1xuXG4vLyBEZXRhaWxzIGZvciBlbmNvZGluZyBhbmQgZGVjb2RpbmcgVG9rZW5zIGludG8gbmF0aXZlIHR5cGVzOyBzaG91bGQgbm90IGJlIGV4cG9ydGVkXG5cbmV4cG9ydCBjb25zdCBCRUdJTl9TVFJJTkdfVE9LRU5fTUFSS0VSID0gJyR7VG9rZW5bJztcbmV4cG9ydCBjb25zdCBCRUdJTl9MSVNUX1RPS0VOX01BUktFUiA9ICcje1Rva2VuWyc7XG5leHBvcnQgY29uc3QgRU5EX1RPS0VOX01BUktFUiA9ICddfSc7XG5cbmV4cG9ydCBjb25zdCBWQUxJRF9LRVlfQ0hBUlMgPSAnYS16QS1aMC05Oi5fLSc7XG5cbmNvbnN0IFFVT1RFRF9CRUdJTl9TVFJJTkdfVE9LRU5fTUFSS0VSID0gcmVnZXhRdW90ZShCRUdJTl9TVFJJTkdfVE9LRU5fTUFSS0VSKTtcbmNvbnN0IFFVT1RFRF9CRUdJTl9MSVNUX1RPS0VOX01BUktFUiA9IHJlZ2V4UXVvdGUoQkVHSU5fTElTVF9UT0tFTl9NQVJLRVIpO1xuY29uc3QgUVVPVEVEX0VORF9UT0tFTl9NQVJLRVIgPSByZWdleFF1b3RlKEVORF9UT0tFTl9NQVJLRVIpO1xuXG5jb25zdCBTVFJJTkdfVE9LRU5fUkVHRVggPSBuZXcgUmVnRXhwKGAke1FVT1RFRF9CRUdJTl9TVFJJTkdfVE9LRU5fTUFSS0VSfShbJHtWQUxJRF9LRVlfQ0hBUlN9XSspJHtRVU9URURfRU5EX1RPS0VOX01BUktFUn1gLCAnZycpO1xuY29uc3QgTElTVF9UT0tFTl9SRUdFWCA9IG5ldyBSZWdFeHAoYCR7UVVPVEVEX0JFR0lOX0xJU1RfVE9LRU5fTUFSS0VSfShbJHtWQUxJRF9LRVlfQ0hBUlN9XSspJHtRVU9URURfRU5EX1RPS0VOX01BUktFUn1gLCAnZycpO1xuXG4vKipcbiAqIEEgc3RyaW5nIHdpdGggbWFya2VycyBpbiBpdCB0aGF0IGNhbiBiZSByZXNvbHZlZCB0byBleHRlcm5hbCB2YWx1ZXNcbiAqL1xuZXhwb3J0IGNsYXNzIFRva2VuU3RyaW5nIHtcbiAgLyoqXG4gICAqIFJldHVybnMgYSBgVG9rZW5TdHJpbmdgIGZvciB0aGlzIHN0cmluZy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZm9yU3RyaW5nKHM6IHN0cmluZykge1xuICAgIHJldHVybiBuZXcgVG9rZW5TdHJpbmcocywgU1RSSU5HX1RPS0VOX1JFR0VYKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgYFRva2VuU3RyaW5nYCBmb3IgdGhpcyBzdHJpbmcgKG11c3QgYmUgdGhlIGZpcnN0IHN0cmluZyBlbGVtZW50IG9mIHRoZSBsaXN0KVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmb3JMaXN0VG9rZW4oczogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBUb2tlblN0cmluZyhzLCBMSVNUX1RPS0VOX1JFR0VYKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgc3RyOiBzdHJpbmcsIHByaXZhdGUgcmVhZG9ubHkgcmU6IFJlZ0V4cCkge1xuICB9XG5cbiAgLyoqXG4gICAqIFNwbGl0IHN0cmluZyBvbiBtYXJrZXJzLCBzdWJzdGl0dXRpbmcgbWFya2VycyB3aXRoIFRva2Vuc1xuICAgKi9cbiAgcHVibGljIHNwbGl0KGxvb2t1cDogKGlkOiBzdHJpbmcpID0+IElSZXNvbHZhYmxlKTogVG9rZW5pemVkU3RyaW5nRnJhZ21lbnRzIHtcbiAgICBjb25zdCByZXQgPSBuZXcgVG9rZW5pemVkU3RyaW5nRnJhZ21lbnRzKCk7XG5cbiAgICBsZXQgcmVzdCA9IDA7XG4gICAgdGhpcy5yZS5sYXN0SW5kZXggPSAwOyAvLyBSZXNldFxuICAgIGxldCBtID0gdGhpcy5yZS5leGVjKHRoaXMuc3RyKTtcbiAgICB3aGlsZSAobSkge1xuICAgICAgaWYgKG0uaW5kZXggPiByZXN0KSB7XG4gICAgICAgIHJldC5hZGRMaXRlcmFsKHRoaXMuc3RyLnN1YnN0cmluZyhyZXN0LCBtLmluZGV4KSk7XG4gICAgICB9XG5cbiAgICAgIHJldC5hZGRUb2tlbihsb29rdXAobVsxXSkpO1xuXG4gICAgICByZXN0ID0gdGhpcy5yZS5sYXN0SW5kZXg7XG4gICAgICBtID0gdGhpcy5yZS5leGVjKHRoaXMuc3RyKTtcbiAgICB9XG5cbiAgICBpZiAocmVzdCA8IHRoaXMuc3RyLmxlbmd0aCkge1xuICAgICAgcmV0LmFkZExpdGVyYWwodGhpcy5zdHIuc3Vic3RyaW5nKHJlc3QpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyBpZiB0aGlzIHN0cmluZyBpbmNsdWRlcyB0b2tlbnMuXG4gICAqL1xuICBwdWJsaWMgdGVzdCgpOiBib29sZWFuIHtcbiAgICB0aGlzLnJlLmxhc3RJbmRleCA9IDA7IC8vIFJlc2V0XG4gICAgcmV0dXJuIHRoaXMucmUudGVzdCh0aGlzLnN0cik7XG4gIH1cbn1cblxuLyoqXG4gKiBRdW90ZSBhIHN0cmluZyBmb3IgdXNlIGluIGEgcmVnZXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2V4UXVvdGUoczogc3RyaW5nKSB7XG4gIHJldHVybiBzLnJlcGxhY2UoL1suPyorXiRbXFxdXFxcXCgpe318LV0vZywgXCJcXFxcJCZcIik7XG59XG5cbi8qKlxuICogQ29uY2F0ZW5hdG9yIHRoYXQgZGlzcmVnYXJkcyB0aGUgaW5wdXRcbiAqXG4gKiBDYW4gYmUgdXNlZCB3aGVuIHRyYXZlcnNpbmcgdGhlIHRva2VucyBpcyBpbXBvcnRhbnQsIGJ1dCB0aGVcbiAqIHJlc3VsdCBpc24ndC5cbiAqL1xuZXhwb3J0IGNsYXNzIE51bGxDb25jYXQgaW1wbGVtZW50cyBJRnJhZ21lbnRDb25jYXRlbmF0b3Ige1xuICBwdWJsaWMgam9pbihfbGVmdDogYW55IHwgdW5kZWZpbmVkLCBfcmlnaHQ6IGFueSB8IHVuZGVmaW5lZCk6IGFueSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY29udGFpbnNMaXN0VG9rZW5FbGVtZW50KHhzOiBhbnlbXSkge1xuICByZXR1cm4geHMuc29tZSh4ID0+IHR5cGVvZih4KSA9PT0gJ3N0cmluZycgJiYgVG9rZW5TdHJpbmcuZm9yTGlzdFRva2VuKHgpLnRlc3QoKSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIG9iaiBpcyBhIHRva2VuIChpLmUuIGhhcyB0aGUgcmVzb2x2ZSgpIG1ldGhvZCBvciBpcyBhIHN0cmluZ1xuICogdGhhdCBpbmNsdWRlcyB0b2tlbiBtYXJrZXJzKSwgb3IgaXQncyBhIGxpc3RpZmljdGFpb24gb2YgYSBUb2tlbiBzdHJpbmcuXG4gKlxuICogQHBhcmFtIG9iaiBUaGUgb2JqZWN0IHRvIHRlc3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bnJlc29sdmVkKG9iajogYW55KTogYm9vbGVhbiB7XG4gIGlmICh0eXBlb2Yob2JqKSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gVG9rZW5TdHJpbmcuZm9yU3RyaW5nKG9iaikudGVzdCgpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBvYmogPT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIGV4dHJhY3RUb2tlbkRvdWJsZShvYmopICE9PSB1bmRlZmluZWQ7XG4gIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShvYmopICYmIG9iai5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gdHlwZW9mKG9ialswXSkgPT09ICdzdHJpbmcnICYmIFRva2VuU3RyaW5nLmZvckxpc3RUb2tlbihvYmpbMF0pLnRlc3QoKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gaXNSZXNvbHZhYmxlT2JqZWN0KG9iaik7XG4gIH1cbn1cblxuLyoqXG4gKiBCaXQgcGF0dGVybiBpbiB0aGUgdG9wIDE2IGJpdHMgb2YgYSBkb3VibGUgdG8gaW5kaWNhdGUgYSBUb2tlblxuICpcbiAqIEFuIElFRUUgZG91YmxlIGluIExFIG1lbW9yeSBvcmRlciBsb29rcyBsaWtlIHRoaXMgKGdyb3VwZWRcbiAqIGludG8gb2N0ZXRzLCB0aGVuIGdyb3VwZWQgaW50byAzMi1iaXQgd29yZHMpOlxuICpcbiAqIG1tbW1tbW1tLm1tbW1tbW1tLm1tbW1tbW1tLm1tbW1tbW1tIHwgbW1tbW1tbW0ubW1tbW1tbW0uRUVFRW1tbW0uc0VFRUVFRUVcbiAqXG4gKiAtIG06IG1hbnRpc3NhICg1MiBiaXRzKVxuICogLSBFOiBleHBvbmVudCAoMTEgYml0cylcbiAqIC0gczogc2lnbiAoMSBiaXQpXG4gKlxuICogV2UgcHV0IHRoZSBmb2xsb3dpbmcgbWFya2VyIGludG8gdGhlIHRvcCAxNiBiaXRzIChleHBvbmVudCBhbmQgc2lnbiksIGFuZFxuICogdXNlIHRoZSBtYW50aXNzYSBwYXJ0IHRvIGVuY29kZSB0aGUgdG9rZW4gaW5kZXguIFRvIHNhdmUgc29tZSBiaXQgdHdpZGRsaW5nXG4gKiB3ZSB1c2UgYWxsIHRvcCAxNiBiaXRzIGZvciB0aGUgdGFnLiBUaGF0IGxvc2VzIHVzIDQgbWFudGlzc2EgYml0cyB0byBzdG9yZVxuICogaW5mb3JtYXRpb24gaW4gYnV0IHdlIHN0aWxsIGhhdmUgNDgsIHdoaWNoIGlzIGdvaW5nIHRvIGJlIHBsZW50eSBmb3IgYW55XG4gKiBudW1iZXIgb2YgdG9rZW5zIHRvIGJlIGNyZWF0ZWQgZHVyaW5nIHRoZSBsaWZldGltZSBvZiBhbnkgQ0RLIGFwcGxpY2F0aW9uLlxuICpcbiAqIENhbid0IGhhdmUgYWxsIGJpdHMgc2V0IGJlY2F1c2UgdGhhdCBtYWtlcyBhIE5hTiwgc28gdW5zZXQgdGhlIGxlYXN0XG4gKiBzaWduaWZpY2FudCBleHBvbmVudCBiaXQuXG4gKlxuICogQ3VycmVudGx5IG5vdCBzdXBwb3J0aW5nIEJFIGFyY2hpdGVjdHVyZXMuXG4gKi9cbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1iaXR3aXNlXG5jb25zdCBET1VCTEVfVE9LRU5fTUFSS0VSX0JJVFMgPSAweEZCRkYgPDwgMTY7XG5cbi8qKlxuICogSGlnaGVzdCBlbmNvZGFibGUgbnVtYmVyXG4gKi9cbmNvbnN0IE1BWF9FTkNPREFCTEVfSU5URUdFUiA9IE1hdGgucG93KDIsIDQ4KSAtIDE7XG5cbi8qKlxuICogR2V0IDJeMzIgYXMgYSBudW1iZXIsIHNvIHdlIGNhbiBkbyBtdWx0aXBsaWNhdGlvbiBhbmQgZGl2IGluc3RlYWQgb2YgYml0IHNoaWZ0aW5nXG4gKlxuICogTmVjZXNzYXJ5IGJlY2F1c2UgaW4gSmF2YVNjcmlwdCwgYml0IG9wZXJhdGlvbnMgaW1wbGljaXRseSBjb252ZXJ0XG4gKiB0byBpbnQzMiBhbmQgd2UgbmVlZCB0aGVtIHRvIHdvcmsgb24gXCJpbnQ2NFwicy5cbiAqXG4gKiBTbyBpbnN0ZWFkIG9mIHggPj4gMzIsIHdlIGRvIE1hdGguZmxvb3IoeCAvIDJeMzIpLCBhbmQgdmljZSB2ZXJzYS5cbiAqL1xuY29uc3QgQklUUzMyID0gTWF0aC5wb3coMiwgMzIpO1xuXG4vKipcbiAqIFJldHVybiBhIHNwZWNpYWwgRG91YmxlIHZhbHVlIHRoYXQgZW5jb2RlcyB0aGUgZ2l2ZW4gbm9ubmVnYXRpdmUgaW50ZWdlclxuICpcbiAqIFdlIHVzZSB0aGlzIHRvIGVuY29kZSBUb2tlbiBvcmRpbmFscy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVRva2VuRG91YmxlKHg6IG51bWJlcikge1xuICBpZiAoTWF0aC5mbG9vcih4KSAhPT0geCB8fCB4IDwgMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG9ubHkgZW5jb2RlIHBvc2l0aXZlIGludGVnZXJzJyk7XG4gIH1cbiAgaWYgKHggPiBNQVhfRU5DT0RBQkxFX0lOVEVHRVIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEdvdCBhbiBpbmRleCB0b28gbGFyZ2UgdG8gZW5jb2RlOiAke3h9YCk7XG4gIH1cblxuICBjb25zdCBidWYgPSBuZXcgQXJyYXlCdWZmZXIoOCk7XG4gIGNvbnN0IGludHMgPSBuZXcgVWludDMyQXJyYXkoYnVmKTtcblxuICAvLyB0c2xpbnQ6ZGlzYWJsZTpuby1iaXR3aXNlXG4gIGludHNbMF0gPSAgeCAmIDB4MDAwMEZGRkZGRkZGOyAvLyBCb3R0b20gMzIgYml0cyBvZiBudW1iZXJcblxuICAvLyBUaGlzIG5lZWRzIGFuIFwieCA+PiAzMlwiIGJ1dCB0aGF0IHdpbGwgbWFrZSBpdCBhIDMyLWJpdCBudW1iZXIgaW5zdGVhZFxuICAvLyBvZiBhIDY0LWJpdCBudW1iZXIuXG4gIGludHNbMV0gPSAoc2hyMzIoeCkgJiAweEZGRkYpIHwgRE9VQkxFX1RPS0VOX01BUktFUl9CSVRTOyAvLyBUb3AgMTYgYml0cyBvZiBudW1iZXIgYW5kIHRoZSBtYXNrXG4gIC8vIHRzbGludDplbmFibGU6bm8tYml0d2lzZVxuXG4gIHJldHVybiAobmV3IEZsb2F0NjRBcnJheShidWYpKVswXTtcbn1cblxuLyoqXG4gKiBTaGlmdCBhIDY0LWJpdCBpbnQgcmlnaHQgMzIgYml0c1xuICovXG5mdW5jdGlvbiBzaHIzMih4OiBudW1iZXIpIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IoeCAvIEJJVFMzMik7XG59XG5cbi8qKlxuICogU2hpZnQgYSA2NC1iaXQgbGVmdCAzMiBiaXRzXG4gKi9cbmZ1bmN0aW9uIHNobDMyKHg6IG51bWJlcikge1xuICByZXR1cm4geCAqIEJJVFMzMjtcbn1cblxuLyoqXG4gKiBFeHRyYWN0IHRoZSBlbmNvZGVkIGludGVnZXIgb3V0IG9mIHRoZSBzcGVjaWFsIERvdWJsZSB2YWx1ZVxuICpcbiAqIFJldHVybnMgdW5kZWZpbmVkIGlmIHRoZSBmbG9hdCBpcyBhIG5vdCBhbiBlbmNvZGVkIHRva2VuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFRva2VuRG91YmxlKGVuY29kZWQ6IG51bWJlcik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcig4KTtcbiAgKG5ldyBGbG9hdDY0QXJyYXkoYnVmKSlbMF0gPSBlbmNvZGVkO1xuXG4gIGNvbnN0IGludHMgPSBuZXcgVWludDMyQXJyYXkoYnVmKTtcblxuICAvLyB0c2xpbnQ6ZGlzYWJsZTpuby1iaXR3aXNlXG4gIGlmICgoaW50c1sxXSAmIDB4RkZGRjAwMDApICE9PSBET1VCTEVfVE9LRU5fTUFSS0VSX0JJVFMpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gTXVzdCB1c2UgKyBpbnN0ZWFkIG9mIHwgaGVyZSAoYml0d2lzZSBvcGVyYXRpb25zXG4gIC8vIHdpbGwgZm9yY2UgMzItYml0cyBpbnRlZ2VyIGFyaXRobWV0aWMsICsgd2lsbCBub3QpLlxuICByZXR1cm4gaW50c1swXSArIHNobDMyKGludHNbMV0gJiAweEZGRkYpO1xuICAvLyB0c2xpbnQ6ZW5hYmxlOm5vLWJpdHdpc2Vcbn1cbiJdfQ==