@stephen-riley/pcre
Version:
Perl compatible regular expressions for JavaScript
411 lines (339 loc) • 44.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _libpcre = _interopRequireDefault(require("../../dist/libpcre2.js"));
var _assert = _interopRequireDefault(require("assert"));
var _util = require("util");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const utf16Decoder = new _util.TextDecoder('utf-16');
let initialized = false;
const cfunc = {};
const ptrSym = Symbol('ptr');
const nametableSym = Symbol('nametable');
const patternSym = Symbol('pattern');
const PCRE2_NO_MATCH = -1;
const PCRE2_ERROR_NOMEMORY = -48;
const PCRE2_SUBSTITUTE_GLOBAL = 0x00000100;
const MAX_OUTPUT_BUFFER_SIZE = 1 * 1024 * 1024;
class PCRE {
static async init() {
await _libpcre.default.loaded;
Object.assign(cfunc, {
malloc(bytes) {
return _libpcre.default._malloc(bytes);
},
free(ptr) {
return _libpcre.default._free(ptr);
},
version: _libpcre.default.cwrap('version', 'number', ['number']),
compile: _libpcre.default.cwrap('compile', 'number', ['array', 'number', 'string']),
destroyCode: _libpcre.default.cwrap('destroyCode', null, ['number']),
lastErrorMessage: _libpcre.default.cwrap('lastErrorMessage', 'number', ['number', 'number']),
lastErrorOffset: _libpcre.default.cwrap('lastErrorOffset', 'number'),
match: _libpcre.default.cwrap('match', 'number', ['number', 'array', 'number', 'number']),
substitute: _libpcre.default.cwrap('substitute', 'number', ['number', 'array', 'number', 'number', 'number', 'number', 'array', 'number', 'number', 'number']),
createMatchData: _libpcre.default.cwrap('createMatchData', 'number', ['number']),
destroyMatchData: _libpcre.default.cwrap('destroyMatchData', null, ['number']),
getOvectorCount: _libpcre.default.cwrap('getOvectorCount', 'number', ['number']),
getOvectorPtr: _libpcre.default.cwrap('getOvectorPointer', 'number', ['number']),
getCaptureCount: _libpcre.default.cwrap('getCaptureCount', 'number', ['number']),
getMatchNameCount: _libpcre.default.cwrap('getMatchNameCount', 'number', ['number']),
getMatchNameTableEntrySize: _libpcre.default.cwrap('getMatchNameTableEntrySize', 'number', ['number']),
getMatchNameTable: _libpcre.default.cwrap('getMatchNameTable', 'number', ['number'])
});
initialized = true;
}
static version() {
(0, _assert.default)(initialized);
const len = cfunc.version(0);
const ptr = allocateStringBuffer(len);
cfunc.version(ptr);
return copyAndFreeStringBuffer(ptr, len);
}
constructor(pattern, flags = '') {
(0, _assert.default)(initialized);
const patternBuffer = Buffer.from(pattern, 'utf16le');
const ptr = cfunc.compile(patternBuffer, patternBuffer.length / 2, flags);
if (ptr === 0) {
const {
errorMessage,
offset
} = this.getLastError();
const err = new Error(errorMessage);
err.offset = offset;
throw err;
}
this[ptrSym] = ptr;
this[patternSym] = pattern; // extract the nametable
const nameCount = this.getMatchNameCount();
const entrySize = this.getMatchNameTableEntrySize();
const tableBuf = this.getMatchNameTable();
this[nametableSym] = convertNameTable(tableBuf, nameCount, entrySize);
}
destroy() {
if (this[ptrSym] === 0) return;
cfunc.destroyCode(this[ptrSym]);
this[ptrSym] = 0;
}
getLastError() {
const errMsgBufLen = 256;
const errMsgBuf = allocateStringBuffer(errMsgBufLen);
const actualErrMsgLen = cfunc.lastErrorMessage(errMsgBuf, errMsgBufLen);
const errorMessage = copyAndFreeStringBuffer(errMsgBuf, actualErrMsgLen);
const offset = cfunc.lastErrorOffset();
return {
errorMessage,
offset
};
}
createMatchData() {
return cfunc.createMatchData(this[ptrSym]);
}
destroyMatchData(matchDataPtr) {
cfunc.destroyMatchData(matchDataPtr);
}
exec(subject, options) {
if (options) {
return this.matchAll(subject);
} else {
return this.match(subject);
}
}
match(subject, start) {
(0, _assert.default)(this[ptrSym]);
if (start >= subject.length) {
return null;
}
const startOffset = start || 0;
const subjectBuffer = Buffer.from(subject, 'utf16le');
const matchDataPtr = this.createMatchData();
const result = cfunc.match(this[ptrSym], subjectBuffer, subjectBuffer.length / 2, startOffset, matchDataPtr);
if (result < 0) {
this.destroyMatchData(matchDataPtr);
if (result === PCRE2_NO_MATCH) {
return null;
} else {
const msg = getPCRE2Error(result);
const err = new Error(msg);
err.code = result;
throw err;
}
} // extract the matches from the pcre2_match_data block
const matchCount = this.getOvectorCount(matchDataPtr);
const vectorPtr = this.getOvectorPtr(matchDataPtr);
const matches = convertOVector(subject, vectorPtr, matchCount); // merge in nametable entries
const results = { ...matches
};
for (let i in matches) {
if (i in this[nametableSym]) {
const name = this[nametableSym][i];
results[name] = matches[i];
}
}
this.destroyMatchData(matchDataPtr);
results.length = matchCount;
return results;
}
matchAll(subject) {
let safety = 1000;
let results = [];
let iter;
let start = 0;
while ((iter = this.match(subject, start)) !== null) {
results.push(iter);
start = iter[0].end;
safety--;
(0, _assert.default)(safety > 0, 'safety limit exceeded');
}
return results;
}
substituteAll(subject, replacement) {
return this.substitute(subject, replacement, 0, PCRE2_SUBSTITUTE_GLOBAL);
}
substitute(subject, replacement, startOffset, options) {
(0, _assert.default)(this[ptrSym]);
if (startOffset >= subject.length) {
return null;
}
startOffset = startOffset || 0;
options = options || 0;
const subjectBuffer = Buffer.from(subject, 'utf16le');
const matchDataPtr = this.createMatchData();
const replacementBuffer = Buffer.from(replacement, 'utf16le');
let factor = 1.5;
for (;;) {
// This size is in character units, not bytes
const outputBufferSize = Math.trunc(subject.length * factor);
if (outputBufferSize > MAX_OUTPUT_BUFFER_SIZE) {
return PCRE2_ERROR_NOMEMORY;
}
const outputBuffer = allocateStringBuffer(outputBufferSize);
const result = cfunc.substitute(this[ptrSym], subjectBuffer, subjectBuffer.length / 2, startOffset, matchDataPtr, options, replacementBuffer, replacementBuffer.length / 2, outputBuffer, outputBufferSize);
if (result < 0) {
this.destroyMatchData(matchDataPtr);
if (result === PCRE2_ERROR_NOMEMORY) {
cfunc.free(outputBuffer);
factor *= 2;
continue;
} else {
cfunc.free(outputBuffer);
const msg = getPCRE2Error(result);
const err = new Error(msg);
err.code = result;
throw err;
}
}
return copyAndFreeStringBuffer(outputBuffer, result);
}
}
getOvectorCount(matchDataPtr) {
(0, _assert.default)(matchDataPtr);
return cfunc.getOvectorCount(matchDataPtr);
}
getOvectorPtr(matchDataPtr) {
(0, _assert.default)(matchDataPtr);
return cfunc.getOvectorPtr(matchDataPtr);
}
getCaptureCount() {
if (this[ptrSym] === 0) return;
return cfunc.getCaptureCount(this[ptrSym]);
}
getMatchNameCount() {
if (this[ptrSym] === 0) return;
return cfunc.getMatchNameCount(this[ptrSym]);
}
getMatchNameTableEntrySize() {
if (this[ptrSym] === 0) return;
return cfunc.getMatchNameTableEntrySize(this[ptrSym]);
}
getMatchNameTable() {
if (this[ptrSym] === 0) return;
return cfunc.getMatchNameTable(this[ptrSym]);
}
}
exports.default = PCRE;
function allocateStringBuffer(len) {
return cfunc.malloc(len * 2);
}
function copyStringBuffer(ptr, len) {
len = _libpcre.default.HEAPU16[ptr / 2 + (len - 1)] === 0 ? len - 1 : len;
const encodedString = _libpcre.default.HEAP8.subarray(ptr, ptr + len * 2);
return utf16Decoder.decode(encodedString);
}
function copyAndFreeStringBuffer(ptr, len) {
const string = copyStringBuffer(ptr, len);
cfunc.free(ptr);
return string;
}
function convertOVector(subject, vectorPtr, vectorCount) {
const table = [];
for (let i = 0; i < vectorCount; i++) {
let ptr = vectorPtr + i * 4 * 2;
const start = _libpcre.default.getValue(ptr, 'i32', false);
const end = _libpcre.default.getValue(ptr + 4, 'i32', false);
const match = subject.substring(start, end);
table.push({
start,
end,
match
});
}
return table;
}
function convertNameTable(nameTablePtr, entries, entrySize) {
const table = {};
for (let i = 0; i < entries; i++) {
let ptr = nameTablePtr + entrySize * i * 2;
const index = _libpcre.default.getValue(ptr, 'i16', false);
const name = copyStringBuffer(ptr + 2, utf16lelen(ptr + 2));
table[index] = name;
}
return table;
}
function utf16lelen(ptr) {
let len = 0;
while (_libpcre.default.getValue(ptr, 'i16', false) !== 0) {
len++;
ptr += 2;
}
return len;
}
const ERRORS = {
"-1": "PCRE2_ERROR_NOMATCH",
"-2": "PCRE2_ERROR_PARTIAL",
"-3": "PCRE2_ERROR_UTF8_ERR1",
"-4": "PCRE2_ERROR_UTF8_ERR2",
"-5": "PCRE2_ERROR_UTF8_ERR3",
"-6": "PCRE2_ERROR_UTF8_ERR4",
"-7": "PCRE2_ERROR_UTF8_ERR5",
"-8": "PCRE2_ERROR_UTF8_ERR6",
"-9": "PCRE2_ERROR_UTF8_ERR7",
"-10": "PCRE2_ERROR_UTF8_ERR8",
"-11": "PCRE2_ERROR_UTF8_ERR9",
"-12": "PCRE2_ERROR_UTF8_ERR10",
"-13": "PCRE2_ERROR_UTF8_ERR11",
"-14": "PCRE2_ERROR_UTF8_ERR12",
"-15": "PCRE2_ERROR_UTF8_ERR13",
"-16": "PCRE2_ERROR_UTF8_ERR14",
"-17": "PCRE2_ERROR_UTF8_ERR15",
"-18": "PCRE2_ERROR_UTF8_ERR16",
"-19": "PCRE2_ERROR_UTF8_ERR17",
"-20": "PCRE2_ERROR_UTF8_ERR18",
"-21": "PCRE2_ERROR_UTF8_ERR19",
"-22": "PCRE2_ERROR_UTF8_ERR20",
"-23": "PCRE2_ERROR_UTF8_ERR21",
"-24": "PCRE2_ERROR_UTF16_ERR1",
"-25": "PCRE2_ERROR_UTF16_ERR2",
"-26": "PCRE2_ERROR_UTF16_ERR3",
"-27": "PCRE2_ERROR_UTF32_ERR1",
"-28": "PCRE2_ERROR_UTF32_ERR2",
"-29": "PCRE2_ERROR_BADDATA",
"-30": "PCRE2_ERROR_MIXEDTABLES",
"-31": "PCRE2_ERROR_BADMAGIC",
"-32": "PCRE2_ERROR_BADMODE",
"-33": "PCRE2_ERROR_BADOFFSET",
"-34": "PCRE2_ERROR_BADOPTION",
"-35": "PCRE2_ERROR_BADREPLACEMENT",
"-36": "PCRE2_ERROR_BADUTFOFFSET",
"-37": "PCRE2_ERROR_CALLOUT",
"-38": "PCRE2_ERROR_DFA_BADRESTART",
"-39": "PCRE2_ERROR_DFA_RECURSE",
"-40": "PCRE2_ERROR_DFA_UCOND",
"-41": "PCRE2_ERROR_DFA_UFUNC",
"-42": "PCRE2_ERROR_DFA_UITEM",
"-43": "PCRE2_ERROR_DFA_WSSIZE",
"-44": "PCRE2_ERROR_INTERNAL",
"-45": "PCRE2_ERROR_JIT_BADOPTION",
"-46": "PCRE2_ERROR_JIT_STACKLIMIT",
"-47": "PCRE2_ERROR_MATCHLIMIT",
"-48": "PCRE2_ERROR_NOMEMORY",
"-49": "PCRE2_ERROR_NOSUBSTRING",
"-50": "PCRE2_ERROR_NOUNIQUESUBSTRING",
"-51": "PCRE2_ERROR_NULL",
"-52": "PCRE2_ERROR_RECURSELOOP",
"-53": "PCRE2_ERROR_DEPTHLIMIT",
"-54": "PCRE2_ERROR_UNAVAILABLE",
"-55": "PCRE2_ERROR_UNSET",
"-56": "PCRE2_ERROR_BADOFFSETLIMIT",
"-57": "PCRE2_ERROR_BADREPESCAPE",
"-58": "PCRE2_ERROR_REPMISSINGBRACE",
"-59": "PCRE2_ERROR_BADSUBSTITUTION",
"-60": "PCRE2_ERROR_BADSUBSPATTERN",
"-61": "PCRE2_ERROR_TOOMANYREPLACE",
"-62": "PCRE2_ERROR_BADSERIALIZEDDATA",
"-63": "PCRE2_ERROR_HEAPLIMIT",
"-64": "PCRE2_ERROR_CONVERT_SYNTAX",
"-65": "PCRE2_ERROR_INTERNAL_DUPMATCH",
"-66": "PCRE2_ERROR_DFA_UINVALID_UTF"
};
function getPCRE2Error(result) {
const code = `${result}`;
if (code in ERRORS) {
return ERRORS[code];
} else {
return "UNKNOWN";
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvUENSRS5qcyJdLCJuYW1lcyI6WyJ1dGYxNkRlY29kZXIiLCJUZXh0RGVjb2RlciIsImluaXRpYWxpemVkIiwiY2Z1bmMiLCJwdHJTeW0iLCJTeW1ib2wiLCJuYW1ldGFibGVTeW0iLCJwYXR0ZXJuU3ltIiwiUENSRTJfTk9fTUFUQ0giLCJQQ1JFMl9FUlJPUl9OT01FTU9SWSIsIlBDUkUyX1NVQlNUSVRVVEVfR0xPQkFMIiwiTUFYX09VVFBVVF9CVUZGRVJfU0laRSIsIlBDUkUiLCJpbml0IiwibGlicGNyZTIiLCJsb2FkZWQiLCJPYmplY3QiLCJhc3NpZ24iLCJtYWxsb2MiLCJieXRlcyIsIl9tYWxsb2MiLCJmcmVlIiwicHRyIiwiX2ZyZWUiLCJ2ZXJzaW9uIiwiY3dyYXAiLCJjb21waWxlIiwiZGVzdHJveUNvZGUiLCJsYXN0RXJyb3JNZXNzYWdlIiwibGFzdEVycm9yT2Zmc2V0IiwibWF0Y2giLCJzdWJzdGl0dXRlIiwiY3JlYXRlTWF0Y2hEYXRhIiwiZGVzdHJveU1hdGNoRGF0YSIsImdldE92ZWN0b3JDb3VudCIsImdldE92ZWN0b3JQdHIiLCJnZXRDYXB0dXJlQ291bnQiLCJnZXRNYXRjaE5hbWVDb3VudCIsImdldE1hdGNoTmFtZVRhYmxlRW50cnlTaXplIiwiZ2V0TWF0Y2hOYW1lVGFibGUiLCJsZW4iLCJhbGxvY2F0ZVN0cmluZ0J1ZmZlciIsImNvcHlBbmRGcmVlU3RyaW5nQnVmZmVyIiwiY29uc3RydWN0b3IiLCJwYXR0ZXJuIiwiZmxhZ3MiLCJwYXR0ZXJuQnVmZmVyIiwiQnVmZmVyIiwiZnJvbSIsImxlbmd0aCIsImVycm9yTWVzc2FnZSIsIm9mZnNldCIsImdldExhc3RFcnJvciIsImVyciIsIkVycm9yIiwibmFtZUNvdW50IiwiZW50cnlTaXplIiwidGFibGVCdWYiLCJjb252ZXJ0TmFtZVRhYmxlIiwiZGVzdHJveSIsImVyck1zZ0J1ZkxlbiIsImVyck1zZ0J1ZiIsImFjdHVhbEVyck1zZ0xlbiIsIm1hdGNoRGF0YVB0ciIsImV4ZWMiLCJzdWJqZWN0Iiwib3B0aW9ucyIsIm1hdGNoQWxsIiwic3RhcnQiLCJzdGFydE9mZnNldCIsInN1YmplY3RCdWZmZXIiLCJyZXN1bHQiLCJtc2ciLCJnZXRQQ1JFMkVycm9yIiwiY29kZSIsIm1hdGNoQ291bnQiLCJ2ZWN0b3JQdHIiLCJtYXRjaGVzIiwiY29udmVydE9WZWN0b3IiLCJyZXN1bHRzIiwiaSIsIm5hbWUiLCJzYWZldHkiLCJpdGVyIiwicHVzaCIsImVuZCIsInN1YnN0aXR1dGVBbGwiLCJyZXBsYWNlbWVudCIsInJlcGxhY2VtZW50QnVmZmVyIiwiZmFjdG9yIiwib3V0cHV0QnVmZmVyU2l6ZSIsIk1hdGgiLCJ0cnVuYyIsIm91dHB1dEJ1ZmZlciIsImNvcHlTdHJpbmdCdWZmZXIiLCJIRUFQVTE2IiwiZW5jb2RlZFN0cmluZyIsIkhFQVA4Iiwic3ViYXJyYXkiLCJkZWNvZGUiLCJzdHJpbmciLCJ2ZWN0b3JDb3VudCIsInRhYmxlIiwiZ2V0VmFsdWUiLCJzdWJzdHJpbmciLCJuYW1lVGFibGVQdHIiLCJlbnRyaWVzIiwiaW5kZXgiLCJ1dGYxNmxlbGVuIiwiRVJST1JTIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSxZQUFZLEdBQUcsSUFBSUMsaUJBQUosQ0FBZ0IsUUFBaEIsQ0FBckI7QUFDQSxJQUFJQyxXQUFXLEdBQUcsS0FBbEI7QUFDQSxNQUFNQyxLQUFLLEdBQUcsRUFBZDtBQUVBLE1BQU1DLE1BQU0sR0FBR0MsTUFBTSxDQUFDLEtBQUQsQ0FBckI7QUFDQSxNQUFNQyxZQUFZLEdBQUdELE1BQU0sQ0FBQyxXQUFELENBQTNCO0FBQ0EsTUFBTUUsVUFBVSxHQUFHRixNQUFNLENBQUMsU0FBRCxDQUF6QjtBQUVBLE1BQU1HLGNBQWMsR0FBRyxDQUFDLENBQXhCO0FBQ0EsTUFBTUMsb0JBQW9CLEdBQUcsQ0FBQyxFQUE5QjtBQUNBLE1BQU1DLHVCQUF1QixHQUFHLFVBQWhDO0FBRUEsTUFBTUMsc0JBQXNC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QUQsQ0FBYjtBQUNELEdBRkQsTUFHSztBQUNILFdBQU8sU0FBUDtBQUNEO0FBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbGlicGNyZTIgZnJvbSAnLi4vLi4vZGlzdC9saWJwY3JlMi5qcydcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0J1xuaW1wb3J0IHsgVGV4dERlY29kZXIgfSBmcm9tICd1dGlsJ1xuXG5jb25zdCB1dGYxNkRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoJ3V0Zi0xNicpXG5sZXQgaW5pdGlhbGl6ZWQgPSBmYWxzZVxuY29uc3QgY2Z1bmMgPSB7fVxuXG5jb25zdCBwdHJTeW0gPSBTeW1ib2woJ3B0cicpXG5jb25zdCBuYW1ldGFibGVTeW0gPSBTeW1ib2woJ25hbWV0YWJsZScpXG5jb25zdCBwYXR0ZXJuU3ltID0gU3ltYm9sKCdwYXR0ZXJuJylcblxuY29uc3QgUENSRTJfTk9fTUFUQ0ggPSAtMVxuY29uc3QgUENSRTJfRVJST1JfTk9NRU1PUlkgPSAtNDhcbmNvbnN0IFBDUkUyX1NVQlNUSVRVVEVfR0xPQkFMID0gMHgwMDAwMDEwMFxuXG5jb25zdCBNQVhfT1VUUFVUX0JVRkZFUl9TSVpFID0gMSAqIDEwMjQgKiAxMDI0XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBDUkUge1xuICBzdGF0aWMgYXN5bmMgaW5pdCgpIHtcbiAgICBhd2FpdCBsaWJwY3JlMi5sb2FkZWRcblxuICAgIE9iamVjdC5hc3NpZ24oY2Z1bmMsIHtcbiAgICAgIG1hbGxvYyhieXRlcykgeyByZXR1cm4gbGlicGNyZTIuX21hbGxvYyhieXRlcykgfSxcbiAgICAgIGZyZWUocHRyKSB7IHJldHVybiBsaWJwY3JlMi5fZnJlZShwdHIpIH0sXG4gICAgICB2ZXJzaW9uOiBsaWJwY3JlMi5jd3JhcCgndmVyc2lvbicsICdudW1iZXInLCBbJ251bWJlciddKSxcbiAgICAgIGNvbXBpbGU6IGxpYnBjcmUyLmN3cmFwKCdjb21waWxlJywgJ251bWJlcicsIFsnYXJyYXknLCAnbnVtYmVyJywgJ3N0cmluZyddKSxcbiAgICAgIGRlc3Ryb3lDb2RlOiBsaWJwY3JlMi5jd3JhcCgnZGVzdHJveUNvZGUnLCBudWxsLCBbJ251bWJlciddKSxcbiAgICAgIGxhc3RFcnJvck1lc3NhZ2U6IGxpYnBjcmUyLmN3cmFwKCdsYXN0RXJyb3JNZXNzYWdlJywgJ251bWJlcicsIFsnbnVtYmVyJywgJ251bWJlciddKSxcbiAgICAgIGxhc3RFcnJvck9mZnNldDogbGlicGNyZTIuY3dyYXAoJ2xhc3RFcnJvck9mZnNldCcsICdudW1iZXInKSxcbiAgICAgIG1hdGNoOiBsaWJwY3JlMi5jd3JhcCgnbWF0Y2gnLCAnbnVtYmVyJywgWydudW1iZXInLCAnYXJyYXknLCAnbnVtYmVyJywgJ251bWJlciddKSxcbiAgICAgIHN1YnN0aXR1dGU6IGxpYnBjcmUyLmN3cmFwKCdzdWJzdGl0dXRlJywgJ251bWJlcicsIFsnbnVtYmVyJywgJ2FycmF5JywgJ251bWJlcicsICdudW1iZXInLCAnbnVtYmVyJywgJ251bWJlcicsICdhcnJheScsICdudW1iZXInLCAnbnVtYmVyJywgJ251bWJlciddKSxcbiAgICAgIGNyZWF0ZU1hdGNoRGF0YTogbGlicGNyZTIuY3dyYXAoJ2NyZWF0ZU1hdGNoRGF0YScsICdudW1iZXInLCBbJ251bWJlciddKSxcbiAgICAgIGRlc3Ryb3lNYXRjaERhdGE6IGxpYnBjcmUyLmN3cmFwKCdkZXN0cm95TWF0Y2hEYXRhJywgbnVsbCwgWydudW1iZXInXSksXG4gICAgICBnZXRPdmVjdG9yQ291bnQ6IGxpYnBjcmUyLmN3cmFwKCdnZXRPdmVjdG9yQ291bnQnLCAnbnVtYmVyJywgWydudW1iZXInXSksXG4gICAgICBnZXRPdmVjdG9yUHRyOiBsaWJwY3JlMi5jd3JhcCgnZ2V0T3ZlY3RvclBvaW50ZXInLCAnbnVtYmVyJywgWydudW1iZXInXSksXG4gICAgICBnZXRDYXB0dXJlQ291bnQ6IGxpYnBjcmUyLmN3cmFwKCdnZXRDYXB0dXJlQ291bnQnLCAnbnVtYmVyJywgWydudW1iZXInXSksXG4gICAgICBnZXRNYXRjaE5hbWVDb3VudDogbGlicGNyZTIuY3dyYXAoJ2dldE1hdGNoTmFtZUNvdW50JywgJ251bWJlcicsIFsnbnVtYmVyJ10pLFxuICAgICAgZ2V0TWF0Y2hOYW1lVGFibGVFbnRyeVNpemU6IGxpYnBjcmUyLmN3cmFwKCdnZXRNYXRjaE5hbWVUYWJsZUVudHJ5U2l6ZScsICdudW1iZXInLCBbJ251bWJlciddKSxcbiAgICAgIGdldE1hdGNoTmFtZVRhYmxlOiBsaWJwY3JlMi5jd3JhcCgnZ2V0TWF0Y2hOYW1lVGFibGUnLCAnbnVtYmVyJywgWydudW1iZXInXSksXG4gICAgfSlcblxuICAgIGluaXRpYWxpemVkID0gdHJ1ZVxuICB9XG5cbiAgc3RhdGljIHZlcnNpb24oKSB7XG4gICAgYXNzZXJ0KGluaXRpYWxpemVkKVxuICAgIGNvbnN0IGxlbiA9IGNmdW5jLnZlcnNpb24oMClcbiAgICBjb25zdCBwdHIgPSBhbGxvY2F0ZVN0cmluZ0J1ZmZlcihsZW4pXG4gICAgY2Z1bmMudmVyc2lvbihwdHIpXG4gICAgcmV0dXJuIGNvcHlBbmRGcmVlU3RyaW5nQnVmZmVyKHB0ciwgbGVuKVxuICB9XG5cbiAgY29uc3RydWN0b3IocGF0dGVybiwgZmxhZ3MgPSAnJykge1xuICAgIGFzc2VydChpbml0aWFsaXplZClcbiAgICBjb25zdCBwYXR0ZXJuQnVmZmVyID0gQnVmZmVyLmZyb20ocGF0dGVybiwgJ3V0ZjE2bGUnKVxuICAgIGNvbnN0IHB0ciA9IGNmdW5jLmNvbXBpbGUocGF0dGVybkJ1ZmZlciwgcGF0dGVybkJ1ZmZlci5sZW5ndGggLyAyLCBmbGFncylcblxuICAgIGlmIChwdHIgPT09IDApIHtcbiAgICAgIGNvbnN0IHsgZXJyb3JNZXNzYWdlLCBvZmZzZXQgfSA9IHRoaXMuZ2V0TGFzdEVycm9yKClcbiAgICAgIGNvbnN0IGVyciA9IG5ldyBFcnJvcihlcnJvck1lc3NhZ2UpXG4gICAgICBlcnIub2Zmc2V0ID0gb2Zmc2V0XG4gICAgICB0aHJvdyBlcnJcbiAgICB9XG5cbiAgICB0aGlzW3B0clN5bV0gPSBwdHJcbiAgICB0aGlzW3BhdHRlcm5TeW1dID0gcGF0dGVyblxuXG4gICAgLy8gZXh0cmFjdCB0aGUgbmFtZXRhYmxlIFxuICAgIGNvbnN0IG5hbWVDb3VudCA9IHRoaXMuZ2V0TWF0Y2hOYW1lQ291bnQoKVxuICAgIGNvbnN0IGVudHJ5U2l6ZSA9IHRoaXMuZ2V0TWF0Y2hOYW1lVGFibGVFbnRyeVNpemUoKVxuICAgIGNvbnN0IHRhYmxlQnVmID0gdGhpcy5nZXRNYXRjaE5hbWVUYWJsZSgpXG4gICAgdGhpc1tuYW1ldGFibGVTeW1dID0gY29udmVydE5hbWVUYWJsZSh0YWJsZUJ1ZiwgbmFtZUNvdW50LCBlbnRyeVNpemUpXG4gIH1cblxuICBkZXN0cm95KCkge1xuICAgIGlmICh0aGlzW3B0clN5bV0gPT09IDApIHJldHVyblxuICAgIGNmdW5jLmRlc3Ryb3lDb2RlKHRoaXNbcHRyU3ltXSlcbiAgICB0aGlzW3B0clN5bV0gPSAwXG4gIH1cblxuICBnZXRMYXN0RXJyb3IoKSB7XG4gICAgY29uc3QgZXJyTXNnQnVmTGVuID0gMjU2XG4gICAgY29uc3QgZXJyTXNnQnVmID0gYWxsb2NhdGVTdHJpbmdCdWZmZXIoZXJyTXNnQnVmTGVuKVxuICAgIGNvbnN0IGFjdHVhbEVyck1zZ0xlbiA9IGNmdW5jLmxhc3RFcnJvck1lc3NhZ2UoZXJyTXNnQnVmLCBlcnJNc2dCdWZMZW4pXG4gICAgY29uc3QgZXJyb3JNZXNzYWdlID0gY29weUFuZEZyZWVTdHJpbmdCdWZmZXIoZXJyTXNnQnVmLCBhY3R1YWxFcnJNc2dMZW4pXG4gICAgY29uc3Qgb2Zmc2V0ID0gY2Z1bmMubGFzdEVycm9yT2Zmc2V0KClcblxuICAgIHJldHVybiB7IGVycm9yTWVzc2FnZSwgb2Zmc2V0IH1cbiAgfVxuXG4gIGNyZWF0ZU1hdGNoRGF0YSgpIHtcbiAgICByZXR1cm4gY2Z1bmMuY3JlYXRlTWF0Y2hEYXRhKHRoaXNbcHRyU3ltXSlcbiAgfVxuXG4gIGRlc3Ryb3lNYXRjaERhdGEobWF0Y2hEYXRhUHRyKSB7XG4gICAgY2Z1bmMuZGVzdHJveU1hdGNoRGF0YShtYXRjaERhdGFQdHIpXG4gIH1cblxuICBleGVjKHN1YmplY3QsIG9wdGlvbnMpIHtcbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgcmV0dXJuIHRoaXMubWF0Y2hBbGwoc3ViamVjdClcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5tYXRjaChzdWJqZWN0KVxuICAgIH1cbiAgfVxuXG4gIG1hdGNoKHN1YmplY3QsIHN0YXJ0KSB7XG4gICAgYXNzZXJ0KHRoaXNbcHRyU3ltXSlcblxuICAgIGlmIChzdGFydCA+PSBzdWJqZWN0Lmxlbmd0aCkge1xuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG5cbiAgICBjb25zdCBzdGFydE9mZnNldCA9IHN0YXJ0IHx8IDBcblxuICAgIGNvbnN0IHN1YmplY3RCdWZmZXIgPSBCdWZmZXIuZnJvbShzdWJqZWN0LCAndXRmMTZsZScpXG5cbiAgICBjb25zdCBtYXRjaERhdGFQdHIgPSB0aGlzLmNyZWF0ZU1hdGNoRGF0YSgpXG5cbiAgICBjb25zdCByZXN1bHQgPSBjZnVuYy5tYXRjaChcbiAgICAgIHRoaXNbcHRyU3ltXSxcbiAgICAgIHN1YmplY3RCdWZmZXIsXG4gICAgICBzdWJqZWN0QnVmZmVyLmxlbmd0aCAvIDIsXG4gICAgICBzdGFydE9mZnNldCxcbiAgICAgIG1hdGNoRGF0YVB0clxuICAgIClcblxuICAgIGlmIChyZXN1bHQgPCAwKSB7XG4gICAgICB0aGlzLmRlc3Ryb3lNYXRjaERhdGEobWF0Y2hEYXRhUHRyKVxuXG4gICAgICBpZiAocmVzdWx0ID09PSBQQ1JFMl9OT19NQVRDSCkge1xuICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGNvbnN0IG1zZyA9IGdldFBDUkUyRXJyb3IocmVzdWx0KVxuICAgICAgICBjb25zdCBlcnIgPSBuZXcgRXJyb3IobXNnKVxuICAgICAgICBlcnIuY29kZSA9IHJlc3VsdFxuICAgICAgICB0aHJvdyBlcnJcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBleHRyYWN0IHRoZSBtYXRjaGVzIGZyb20gdGhlIHBjcmUyX21hdGNoX2RhdGEgYmxvY2tcbiAgICBjb25zdCBtYXRjaENvdW50ID0gdGhpcy5nZXRPdmVjdG9yQ291bnQobWF0Y2hEYXRhUHRyKVxuICAgIGNvbnN0IHZlY3RvclB0ciA9IHRoaXMuZ2V0T3ZlY3RvclB0cihtYXRjaERhdGFQdHIpXG4gICAgY29uc3QgbWF0Y2hlcyA9IGNvbnZlcnRPVmVjdG9yKHN1YmplY3QsIHZlY3RvclB0ciwgbWF0Y2hDb3VudClcblxuICAgIC8vIG1lcmdlIGluIG5hbWV0YWJsZSBlbnRyaWVzXG4gICAgY29uc3QgcmVzdWx0cyA9IHsgLi4ubWF0Y2hlcyB9XG4gICAgZm9yIChsZXQgaSBpbiBtYXRjaGVzKSB7XG4gICAgICBpZiAoaSBpbiB0aGlzW25hbWV0YWJsZVN5bV0pIHtcbiAgICAgICAgY29uc3QgbmFtZSA9IHRoaXNbbmFtZXRhYmxlU3ltXVtpXVxuICAgICAgICByZXN1bHRzW25hbWVdID0gbWF0Y2hlc1tpXVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZGVzdHJveU1hdGNoRGF0YShtYXRjaERhdGFQdHIpXG5cbiAgICByZXN1bHRzLmxlbmd0aCA9IG1hdGNoQ291bnRcbiAgICByZXR1cm4gcmVzdWx0c1xuICB9XG5cbiAgbWF0Y2hBbGwoc3ViamVjdCkge1xuICAgIGxldCBzYWZldHkgPSAxMDAwXG5cbiAgICBsZXQgcmVzdWx0cyA9IFtdXG4gICAgbGV0IGl0ZXJcbiAgICBsZXQgc3RhcnQgPSAwXG5cbiAgICB3aGlsZSAoKGl0ZXIgPSB0aGlzLm1hdGNoKHN1YmplY3QsIHN0YXJ0KSkgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdHMucHVzaChpdGVyKVxuICAgICAgc3RhcnQgPSBpdGVyWzBdLmVuZFxuXG4gICAgICBzYWZldHktLVxuICAgICAgYXNzZXJ0KHNhZmV0eSA+IDAsICdzYWZldHkgbGltaXQgZXhjZWVkZWQnKVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRzXG4gIH1cblxuICBzdWJzdGl0dXRlQWxsKHN1YmplY3QsIHJlcGxhY2VtZW50KSB7XG4gICAgcmV0dXJuIHRoaXMuc3Vic3RpdHV0ZShzdWJqZWN0LCByZXBsYWNlbWVudCwgMCwgUENSRTJfU1VCU1RJVFVURV9HTE9CQUwpXG4gIH1cblxuICBzdWJzdGl0dXRlKHN1YmplY3QsIHJlcGxhY2VtZW50LCBzdGFydE9mZnNldCwgb3B0aW9ucykge1xuICAgIGFzc2VydCh0aGlzW3B0clN5bV0pXG5cbiAgICBpZiAoc3RhcnRPZmZzZXQgPj0gc3ViamVjdC5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgc3RhcnRPZmZzZXQgPSBzdGFydE9mZnNldCB8fCAwXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwgMFxuXG4gICAgY29uc3Qgc3ViamVjdEJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHN1YmplY3QsICd1dGYxNmxlJylcblxuICAgIGNvbnN0IG1hdGNoRGF0YVB0ciA9IHRoaXMuY3JlYXRlTWF0Y2hEYXRhKClcblxuICAgIGNvbnN0IHJlcGxhY2VtZW50QnVmZmVyID0gQnVmZmVyLmZyb20ocmVwbGFjZW1lbnQsICd1dGYxNmxlJylcblxuICAgIGxldCBmYWN0b3IgPSAxLjVcblxuICAgIGZvciAoOyA7KSB7XG4gICAgICAvLyBUaGlzIHNpemUgaXMgaW4gY2hhcmFjdGVyIHVuaXRzLCBub3QgYnl0ZXNcbiAgICAgIGNvbnN0IG91dHB1dEJ1ZmZlclNpemUgPSBNYXRoLnRydW5jKHN1YmplY3QubGVuZ3RoICogZmFjdG9yKVxuXG4gICAgICBpZiAob3V0cHV0QnVmZmVyU2l6ZSA+IE1BWF9PVVRQVVRfQlVGRkVSX1NJWkUpIHtcbiAgICAgICAgcmV0dXJuIFBDUkUyX0VSUk9SX05PTUVNT1JZXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG91dHB1dEJ1ZmZlciA9IGFsbG9jYXRlU3RyaW5nQnVmZmVyKG91dHB1dEJ1ZmZlclNpemUpXG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGNmdW5jLnN1YnN0aXR1dGUoXG4gICAgICAgIHRoaXNbcHRyU3ltXSxcbiAgICAgICAgc3ViamVjdEJ1ZmZlcixcbiAgICAgICAgc3ViamVjdEJ1ZmZlci5sZW5ndGggLyAyLFxuICAgICAgICBzdGFydE9mZnNldCxcbiAgICAgICAgbWF0Y2hEYXRhUHRyLFxuICAgICAgICBvcHRpb25zLFxuICAgICAgICByZXBsYWNlbWVudEJ1ZmZlcixcbiAgICAgICAgcmVwbGFjZW1lbnRCdWZmZXIubGVuZ3RoIC8gMixcbiAgICAgICAgb3V0cHV0QnVmZmVyLFxuICAgICAgICBvdXRwdXRCdWZmZXJTaXplKVxuXG4gICAgICBpZiAocmVzdWx0IDwgMCkge1xuICAgICAgICB0aGlzLmRlc3Ryb3lNYXRjaERhdGEobWF0Y2hEYXRhUHRyKVxuXG4gICAgICAgIGlmIChyZXN1bHQgPT09IFBDUkUyX0VSUk9SX05PTUVNT1JZKSB7XG4gICAgICAgICAgY2Z1bmMuZnJlZShvdXRwdXRCdWZmZXIpXG4gICAgICAgICAgZmFjdG9yICo9IDJcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGNmdW5jLmZyZWUob3V0cHV0QnVmZmVyKVxuICAgICAgICAgIGNvbnN0IG1zZyA9IGdldFBDUkUyRXJyb3IocmVzdWx0KVxuICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBFcnJvcihtc2cpXG4gICAgICAgICAgZXJyLmNvZGUgPSByZXN1bHRcbiAgICAgICAgICB0aHJvdyBlcnJcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gY29weUFuZEZyZWVTdHJpbmdCdWZmZXIob3V0cHV0QnVmZmVyLCByZXN1bHQpXG4gICAgfVxuICB9XG5cbiAgZ2V0T3ZlY3RvckNvdW50KG1hdGNoRGF0YVB0cikge1xuICAgIGFzc2VydChtYXRjaERhdGFQdHIpXG4gICAgcmV0dXJuIGNmdW5jLmdldE92ZWN0b3JDb3VudChtYXRjaERhdGFQdHIpXG4gIH1cblxuICBnZXRPdmVjdG9yUHRyKG1hdGNoRGF0YVB0cikge1xuICAgIGFzc2VydChtYXRjaERhdGFQdHIpXG4gICAgcmV0dXJuIGNmdW5jLmdldE92ZWN0b3JQdHIobWF0Y2hEYXRhUHRyKVxuICB9XG5cbiAgZ2V0Q2FwdHVyZUNvdW50KCkge1xuICAgIGlmICh0aGlzW3B0clN5bV0gPT09IDApIHJldHVyblxuICAgIHJldHVybiBjZnVuYy5nZXRDYXB0dXJlQ291bnQodGhpc1twdHJTeW1dKVxuICB9XG5cbiAgZ2V0TWF0Y2hOYW1lQ291bnQoKSB7XG4gICAgaWYgKHRoaXNbcHRyU3ltXSA9PT0gMCkgcmV0dXJuXG4gICAgcmV0dXJuIGNmdW5jLmdldE1hdGNoTmFtZUNvdW50KHRoaXNbcHRyU3ltXSlcbiAgfVxuXG4gIGdldE1hdGNoTmFtZVRhYmxlRW50cnlTaXplKCkge1xuICAgIGlmICh0aGlzW3B0clN5bV0gPT09IDApIHJldHVyblxuICAgIHJldHVybiBjZnVuYy5nZXRNYXRjaE5hbWVUYWJsZUVudHJ5U2l6ZSh0aGlzW3B0clN5bV0pXG4gIH1cblxuICBnZXRNYXRjaE5hbWVUYWJsZSgpIHtcbiAgICBpZiAodGhpc1twdHJTeW1dID09PSAwKSByZXR1cm5cbiAgICByZXR1cm4gY2Z1bmMuZ2V0TWF0Y2hOYW1lVGFibGUodGhpc1twdHJTeW1dKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG9jYXRlU3RyaW5nQnVmZmVyKGxlbikge1xuICByZXR1cm4gY2Z1bmMubWFsbG9jKGxlbiAqIDIpXG59XG5cbmZ1bmN0aW9uIGNvcHlTdHJpbmdCdWZmZXIocHRyLCBsZW4pIHtcbiAgbGVuID0gbGlicGNyZTIuSEVBUFUxNlsocHRyIC8gMikgKyAobGVuIC0gMSldID09PSAwID8gbGVuIC0gMSA6IGxlblxuICBjb25zdCBlbmNvZGVkU3RyaW5nID0gbGlicGNyZTIuSEVBUDguc3ViYXJyYXkocHRyLCBwdHIgKyAobGVuICogMikpXG4gIHJldHVybiB1dGYxNkRlY29kZXIuZGVjb2RlKGVuY29kZWRTdHJpbmcpXG59XG5cbmZ1bmN0aW9uIGNvcHlBbmRGcmVlU3RyaW5nQnVmZmVyKHB0ciwgbGVuKSB7XG4gIGNvbnN0IHN0cmluZyA9IGNvcHlTdHJpbmdCdWZmZXIocHRyLCBsZW4pXG4gIGNmdW5jLmZyZWUocHRyKVxuICByZXR1cm4gc3RyaW5nXG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRPVmVjdG9yKHN1YmplY3QsIHZlY3RvclB0ciwgdmVjdG9yQ291bnQpIHtcbiAgY29uc3QgdGFibGUgPSBbXVxuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdmVjdG9yQ291bnQ7IGkrKykge1xuICAgIGxldCBwdHIgPSB2ZWN0b3JQdHIgKyBpICogNCAqIDJcbiAgICBjb25zdCBzdGFydCA9IGxpYnBjcmUyLmdldFZhbHVlKHB0ciwgJ2kzMicsIGZhbHNlKVxuICAgIGNvbnN0IGVuZCA9IGxpYnBjcmUyLmdldFZhbHVlKHB0ciArIDQsICdpMzInLCBmYWxzZSlcbiAgICBjb25zdCBtYXRjaCA9IHN1YmplY3Quc3Vic3RyaW5nKHN0YXJ0LCBlbmQpXG4gICAgdGFibGUucHVzaCh7IHN0YXJ0LCBlbmQsIG1hdGNoIH0pXG4gIH1cblxuICByZXR1cm4gdGFibGVcbn1cblxuZnVuY3Rpb24gY29udmVydE5hbWVUYWJsZShuYW1lVGFibGVQdHIsIGVudHJpZXMsIGVudHJ5U2l6ZSkge1xuICBjb25zdCB0YWJsZSA9IHt9XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbnRyaWVzOyBpKyspIHtcbiAgICBsZXQgcHRyID0gbmFtZVRhYmxlUHRyICsgZW50cnlTaXplICogaSAqIDJcblxuICAgIGNvbnN0IGluZGV4ID0gbGlicGNyZTIuZ2V0VmFsdWUocHRyLCAnaTE2JywgZmFsc2UpXG4gICAgY29uc3QgbmFtZSA9IGNvcHlTdHJpbmdCdWZmZXIocHRyICsgMiwgdXRmMTZsZWxlbihwdHIgKyAyKSlcbiAgICB0YWJsZVtpbmRleF0gPSBuYW1lXG4gIH1cblxuICByZXR1cm4gdGFibGVcbn1cblxuZnVuY3Rpb24gdXRmMTZsZWxlbihwdHIpIHtcbiAgbGV0IGxlbiA9IDBcbiAgd2hpbGUgKGxpYnBjcmUyLmdldFZhbHVlKHB0ciwgJ2kxNicsIGZhbHNlKSAhPT0gMCkge1xuICAgIGxlbisrXG4gICAgcHRyICs9IDJcbiAgfVxuICByZXR1cm4gbGVuXG59XG5cbmNvbnN0IEVSUk9SUyA9IHtcbiAgXCItMVwiOiBcIlBDUkUyX0VSUk9SX05PTUFUQ0hcIixcbiAgXCItMlwiOiBcIlBDUkUyX0VSUk9SX1BBUlRJQUxcIixcbiAgXCItM1wiOiBcIlBDUkUyX0VSUk9SX1VURjhfRVJSMVwiLFxuICBcIi00XCI6IFwiUENSRTJfRVJST1JfVVRGOF9FUlIyXCIsXG4gIFwiLTVcIjogXCJQQ1JFMl9FUlJPUl9VVEY4X0VSUjNcIixcbiAgXCItNlwiOiBcIlBDUkUyX0VSUk9SX1VURjhfRVJSNFwiLFxuICBcIi03XCI6IFwiUENSRTJfRVJST1JfVVRGOF9FUlI1XCIsXG4gIFwiLThcIjogXCJQQ1JFMl9FUlJPUl9VVEY4X0VSUjZcIixcbiAgXCItOVwiOiBcIlBDUkUyX0VSUk9SX1VURjhfRVJSN1wiLFxuICBcIi0xMFwiOiBcIlBDUkUyX0VSUk9SX1VURjhfRVJSOFwiLFxuICBcIi0xMVwiOiBcIlBDUkUyX0VSUk9SX1VURjhfRVJSOVwiLFxuICBcIi0xMlwiOiBcIlBDUkUyX0VSUk9SX1VURjhfRVJSMTBcIixcbiAgXCItMTNcIjogXCJQQ1JFMl9FUlJPUl9VVEY4X0VSUjExXCIsXG4gIFwiLTE0XCI6IFwiUENSRTJfRVJST1JfVVRGOF9FUlIxMlwiLFxuICBcIi0xNVwiOiBcIlBDUkUyX0VSUk9SX1VURjhfRVJSMTNcIixcbiAgXCItMTZcIjogXCJQQ1JFMl9FUlJPUl9VVEY4X0VSUjE0XCIsXG4gIFwiLTE3XCI6IFwiUENSRTJfRVJST1JfVVRGOF9FUlIxNVwiLFxuICBcIi0xOFwiOiBcIlBDUkUyX0VSUk9SX1VURjhfRVJSMTZcIixcbiAgXCItMTlcIjogXCJQQ1JFMl9FUlJPUl9VVEY4X0VSUjE3XCIsXG4gIFwiLTIwXCI6IFwiUENSRTJfRVJST1JfVVRGOF9FUlIxOFwiLFxuICBcIi0yMVwiOiBcIlBDUkUyX0VSUk9SX1VURjhfRVJSMTlcIixcbiAgXCItMjJcIjogXCJQQ1JFMl9FUlJPUl9VVEY4X0VSUjIwXCIsXG4gIFwiLTIzXCI6IFwiUENSRTJfRVJST1JfVVRGOF9FUlIyMVwiLFxuICBcIi0yNFwiOiBcIlBDUkUyX0VSUk9SX1VURjE2X0VSUjFcIixcbiAgXCItMjVcIjogXCJQQ1JFMl9FUlJPUl9VVEYxNl9FUlIyXCIsXG4gIFwiLTI2XCI6IFwiUENSRTJfRVJST1JfVVRGMTZfRVJSM1wiLFxuICBcIi0yN1wiOiBcIlBDUkUyX0VSUk9SX1VURjMyX0VSUjFcIixcbiAgXCItMjhcIjogXCJQQ1JFMl9FUlJPUl9VVEYzMl9FUlIyXCIsXG4gIFwiLTI5XCI6IFwiUENSRTJfRVJST1JfQkFEREFUQVwiLFxuICBcIi0zMFwiOiBcIlBDUkUyX0VSUk9SX01JWEVEVEFCTEVTXCIsXG4gIFwiLTMxXCI6IFwiUENSRTJfRVJST1JfQkFETUFHSUNcIixcbiAgXCItMzJcIjogXCJQQ1JFMl9FUlJPUl9CQURNT0RFXCIsXG4gIFwiLTMzXCI6IFwiUENSRTJfRVJST1JfQkFET0ZGU0VUXCIsXG4gIFwiLTM0XCI6IFwiUENSRTJfRVJST1JfQkFET1BUSU9OXCIsXG4gIFwiLTM1XCI6IFwiUENSRTJfRVJST1JfQkFEUkVQTEFDRU1FTlRcIixcbiAgXCItMzZcIjogXCJQQ1JFMl9FUlJPUl9CQURVVEZPRkZTRVRcIixcbiAgXCItMzdcIjogXCJQQ1JFMl9FUlJPUl9DQUxMT1VUXCIsXG4gIFwiLTM4XCI6IFwiUENSRTJfRVJST1JfREZBX0JBRFJFU1RBUlRcIixcbiAgXCItMzlcIjogXCJQQ1JFMl9FUlJPUl9ERkFfUkVDVVJTRVwiLFxuICBcIi00MFwiOiBcIlBDUkUyX0VSUk9SX0RGQV9VQ09ORFwiLFxuICBcIi00MVwiOiBcIlBDUkUyX0VSUk9SX0RGQV9VRlVOQ1wiLFxuICBcIi00MlwiOiBcIlBDUkUyX0VSUk9SX0RGQV9VSVRFTVwiLFxuICBcIi00M1wiOiBcIlBDUkUyX0VSUk9SX0RGQV9XU1NJWkVcIixcbiAgXCItNDRcIjogXCJQQ1JFMl9FUlJPUl9JTlRFUk5BTFwiLFxuICBcIi00NVwiOiBcIlBDUkUyX0VSUk9SX0pJVF9CQURPUFRJT05cIixcbiAgXCItNDZcIjogXCJQQ1JFMl9FUlJPUl9KSVRfU1RBQ0tMSU1JVFwiLFxuICBcIi00N1wiOiBcIlBDUkUyX0VSUk9SX01BVENITElNSVRcIixcbiAgXCItNDhcIjogXCJQQ1JFMl9FUlJPUl9OT01FTU9SWVwiLFxuICBcIi00OVwiOiBcIlBDUkUyX0VSUk9SX05PU1VCU1RSSU5HXCIsXG4gIFwiLTUwXCI6IFwiUENSRTJfRVJST1JfTk9VTklRVUVTVUJTVFJJTkdcIixcbiAgXCItNTFcIjogXCJQQ1JFMl9FUlJPUl9OVUxMXCIsXG4gIFwiLTUyXCI6IFwiUENSRTJfRVJST1JfUkVDVVJTRUxPT1BcIixcbiAgXCItNTNcIjogXCJQQ1JFMl9FUlJPUl9ERVBUSExJTUlUXCIsXG4gIFwiLTU0XCI6IFwiUENSRTJfRVJST1JfVU5BVkFJTEFCTEVcIixcbiAgXCItNTVcIjogXCJQQ1JFMl9FUlJPUl9VTlNFVFwiLFxuICBcIi01NlwiOiBcIlBDUkUyX0VSUk9SX0JBRE9GRlNFVExJTUlUXCIsXG4gIFwiLTU3XCI6IFwiUENSRTJfRVJST1JfQkFEUkVQRVNDQVBFXCIsXG4gIFwiLTU4XCI6IFwiUENSRTJfRVJST1JfUkVQTUlTU0lOR0JSQUNFXCIsXG4gIFwiLTU5XCI6IFwiUENSRTJfRVJST1JfQkFEU1VCU1RJVFVUSU9OXCIsXG4gIFwiLTYwXCI6IFwiUENSRTJfRVJST1JfQkFEU1VCU1BBVFRFUk5cIixcbiAgXCItNjFcIjogXCJQQ1JFMl9FUlJPUl9UT09NQU5ZUkVQTEFDRVwiLFxuICBcIi02MlwiOiBcIlBDUkUyX0VSUk9SX0JBRFNFUklBTElaRUREQVRBXCIsXG4gIFwiLTYzXCI6IFwiUENSRTJfRVJST1JfSEVBUExJTUlUXCIsXG4gIFwiLTY0XCI6IFwiUENSRTJfRVJST1JfQ09OVkVSVF9TWU5UQVhcIixcbiAgXCItNjVcIjogXCJQQ1JFMl9FUlJPUl9JTlRFUk5BTF9EVVBNQVRDSFwiLFxuICBcIi02NlwiOiBcIlBDUkUyX0VSUk9SX0RGQV9VSU5WQUxJRF9VVEZcIixcbn1cblxuZnVuY3Rpb24gZ2V0UENSRTJFcnJvcihyZXN1bHQpIHtcbiAgY29uc3QgY29kZSA9IGAke3Jlc3VsdH1gXG5cbiAgaWYgKGNvZGUgaW4gRVJST1JTKSB7XG4gICAgcmV0dXJuIEVSUk9SU1tjb2RlXVxuICB9XG4gIGVsc2Uge1xuICAgIHJldHVybiBcIlVOS05PV05cIlxuICB9XG59XG4iXX0=