UNPKG

@angular/core

Version:

Angular - the core framework

218 lines • 29.5 kB
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { assertNumber, assertString } from '../../util/assert'; import { ELEMENT_MARKER, I18nCreateOpCode, ICU_MARKER, } from '../interfaces/i18n'; import { getInstructionFromIcuCreateOpCode, getParentFromIcuCreateOpCode, getRefFromIcuCreateOpCode, } from './i18n_util'; /** * Converts `I18nCreateOpCodes` array into a human readable format. * * This function is attached to the `I18nCreateOpCodes.debug` property if `ngDevMode` is enabled. * This function provides a human readable view of the opcodes. This is useful when debugging the * application as well as writing more readable tests. * * @param this `I18nCreateOpCodes` if attached as a method. * @param opcodes `I18nCreateOpCodes` if invoked as a function. */ export function i18nCreateOpCodesToString(opcodes) { const createOpCodes = opcodes || (Array.isArray(this) ? this : []); let lines = []; for (let i = 0; i < createOpCodes.length; i++) { const opCode = createOpCodes[i++]; const text = createOpCodes[i]; const isComment = (opCode & I18nCreateOpCode.COMMENT) === I18nCreateOpCode.COMMENT; const appendNow = (opCode & I18nCreateOpCode.APPEND_EAGERLY) === I18nCreateOpCode.APPEND_EAGERLY; const index = opCode >>> I18nCreateOpCode.SHIFT; lines.push(`lView[${index}] = document.${isComment ? 'createComment' : 'createText'}(${JSON.stringify(text)});`); if (appendNow) { lines.push(`parent.appendChild(lView[${index}]);`); } } return lines; } /** * Converts `I18nUpdateOpCodes` array into a human readable format. * * This function is attached to the `I18nUpdateOpCodes.debug` property if `ngDevMode` is enabled. * This function provides a human readable view of the opcodes. This is useful when debugging the * application as well as writing more readable tests. * * @param this `I18nUpdateOpCodes` if attached as a method. * @param opcodes `I18nUpdateOpCodes` if invoked as a function. */ export function i18nUpdateOpCodesToString(opcodes) { const parser = new OpCodeParser(opcodes || (Array.isArray(this) ? this : [])); let lines = []; function consumeOpCode(value) { const ref = value >>> 2 /* I18nUpdateOpCode.SHIFT_REF */; const opCode = value & 3 /* I18nUpdateOpCode.MASK_OPCODE */; switch (opCode) { case 0 /* I18nUpdateOpCode.Text */: return `(lView[${ref}] as Text).textContent = $$$`; case 1 /* I18nUpdateOpCode.Attr */: const attrName = parser.consumeString(); const sanitizationFn = parser.consumeFunction(); const value = sanitizationFn ? `(${sanitizationFn})($$$)` : '$$$'; return `(lView[${ref}] as Element).setAttribute('${attrName}', ${value})`; case 2 /* I18nUpdateOpCode.IcuSwitch */: return `icuSwitchCase(${ref}, $$$)`; case 3 /* I18nUpdateOpCode.IcuUpdate */: return `icuUpdateCase(${ref})`; } throw new Error('unexpected OpCode'); } while (parser.hasMore()) { let mask = parser.consumeNumber(); let size = parser.consumeNumber(); const end = parser.i + size; const statements = []; let statement = ''; while (parser.i < end) { let value = parser.consumeNumberOrString(); if (typeof value === 'string') { statement += value; } else if (value < 0) { // Negative numbers are ref indexes // Here `i` refers to current binding index. It is to signify that the value is relative, // rather than absolute. statement += '${lView[i' + value + ']}'; } else { // Positive numbers are operations. const opCodeText = consumeOpCode(value); statements.push(opCodeText.replace('$$$', '`' + statement + '`') + ';'); statement = ''; } } lines.push(`if (mask & 0b${mask.toString(2)}) { ${statements.join(' ')} }`); } return lines; } /** * Converts `I18nCreateOpCodes` array into a human readable format. * * This function is attached to the `I18nCreateOpCodes.debug` if `ngDevMode` is enabled. This * function provides a human readable view of the opcodes. This is useful when debugging the * application as well as writing more readable tests. * * @param this `I18nCreateOpCodes` if attached as a method. * @param opcodes `I18nCreateOpCodes` if invoked as a function. */ export function icuCreateOpCodesToString(opcodes) { const parser = new OpCodeParser(opcodes || (Array.isArray(this) ? this : [])); let lines = []; function consumeOpCode(opCode) { const parent = getParentFromIcuCreateOpCode(opCode); const ref = getRefFromIcuCreateOpCode(opCode); switch (getInstructionFromIcuCreateOpCode(opCode)) { case 0 /* IcuCreateOpCode.AppendChild */: return `(lView[${parent}] as Element).appendChild(lView[${lastRef}])`; case 1 /* IcuCreateOpCode.Attr */: return `(lView[${ref}] as Element).setAttribute("${parser.consumeString()}", "${parser.consumeString()}")`; } throw new Error('Unexpected OpCode: ' + getInstructionFromIcuCreateOpCode(opCode)); } let lastRef = -1; while (parser.hasMore()) { let value = parser.consumeNumberStringOrMarker(); if (value === ICU_MARKER) { const text = parser.consumeString(); lastRef = parser.consumeNumber(); lines.push(`lView[${lastRef}] = document.createComment("${text}")`); } else if (value === ELEMENT_MARKER) { const text = parser.consumeString(); lastRef = parser.consumeNumber(); lines.push(`lView[${lastRef}] = document.createElement("${text}")`); } else if (typeof value === 'string') { lastRef = parser.consumeNumber(); lines.push(`lView[${lastRef}] = document.createTextNode("${value}")`); } else if (typeof value === 'number') { const line = consumeOpCode(value); line && lines.push(line); } else { throw new Error('Unexpected value'); } } return lines; } /** * Converts `I18nRemoveOpCodes` array into a human readable format. * * This function is attached to the `I18nRemoveOpCodes.debug` if `ngDevMode` is enabled. This * function provides a human readable view of the opcodes. This is useful when debugging the * application as well as writing more readable tests. * * @param this `I18nRemoveOpCodes` if attached as a method. * @param opcodes `I18nRemoveOpCodes` if invoked as a function. */ export function i18nRemoveOpCodesToString(opcodes) { const removeCodes = opcodes || (Array.isArray(this) ? this : []); let lines = []; for (let i = 0; i < removeCodes.length; i++) { const nodeOrIcuIndex = removeCodes[i]; if (nodeOrIcuIndex > 0) { // Positive numbers are `RNode`s. lines.push(`remove(lView[${nodeOrIcuIndex}])`); } else { // Negative numbers are ICUs lines.push(`removeNestedICU(${~nodeOrIcuIndex})`); } } return lines; } class OpCodeParser { constructor(codes) { this.i = 0; this.codes = codes; } hasMore() { return this.i < this.codes.length; } consumeNumber() { let value = this.codes[this.i++]; assertNumber(value, 'expecting number in OpCode'); return value; } consumeString() { let value = this.codes[this.i++]; assertString(value, 'expecting string in OpCode'); return value; } consumeFunction() { let value = this.codes[this.i++]; if (value === null || typeof value === 'function') { return value; } throw new Error('expecting function in OpCode'); } consumeNumberOrString() { let value = this.codes[this.i++]; if (typeof value === 'string') { return value; } assertNumber(value, 'expecting number or string in OpCode'); return value; } consumeNumberStringOrMarker() { let value = this.codes[this.i++]; if (typeof value === 'string' || typeof value === 'number' || value == ICU_MARKER || value == ELEMENT_MARKER) { return value; } assertNumber(value, 'expecting number, string, ICU_MARKER or ELEMENT_MARKER in OpCode'); return value; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaTE4bl9kZWJ1Zy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3JlbmRlcjMvaTE4bi9pMThuX2RlYnVnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBQyxZQUFZLEVBQUUsWUFBWSxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDN0QsT0FBTyxFQUNMLGNBQWMsRUFDZCxnQkFBZ0IsRUFLaEIsVUFBVSxHQUdYLE1BQU0sb0JBQW9CLENBQUM7QUFFNUIsT0FBTyxFQUNMLGlDQUFpQyxFQUNqQyw0QkFBNEIsRUFDNUIseUJBQXlCLEdBQzFCLE1BQU0sYUFBYSxDQUFDO0FBRXJCOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSx5QkFBeUIsQ0FFdkMsT0FBMkI7SUFFM0IsTUFBTSxhQUFhLEdBQXNCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUUsRUFBVSxDQUFDLENBQUM7SUFDL0YsSUFBSSxLQUFLLEdBQWEsRUFBRSxDQUFDO0lBQ3pCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDOUMsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFRLENBQUM7UUFDekMsTUFBTSxJQUFJLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBVyxDQUFDO1FBQ3hDLE1BQU0sU0FBUyxHQUFHLENBQUMsTUFBTSxHQUFHLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxLQUFLLGdCQUFnQixDQUFDLE9BQU8sQ0FBQztRQUNuRixNQUFNLFNBQVMsR0FDYixDQUFDLE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsS0FBSyxnQkFBZ0Is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ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge2Fzc2VydE51bWJlciwgYXNzZXJ0U3RyaW5nfSBmcm9tICcuLi8uLi91dGlsL2Fzc2VydCc7XG5pbXBvcnQge1xuICBFTEVNRU5UX01BUktFUixcbiAgSTE4bkNyZWF0ZU9wQ29kZSxcbiAgSTE4bkNyZWF0ZU9wQ29kZXMsXG4gIEkxOG5SZW1vdmVPcENvZGVzLFxuICBJMThuVXBkYXRlT3BDb2RlLFxuICBJMThuVXBkYXRlT3BDb2RlcyxcbiAgSUNVX01BUktFUixcbiAgSWN1Q3JlYXRlT3BDb2RlLFxuICBJY3VDcmVhdGVPcENvZGVzLFxufSBmcm9tICcuLi9pbnRlcmZhY2VzL2kxOG4nO1xuXG5pbXBvcnQge1xuICBnZXRJbnN0cnVjdGlvbkZyb21JY3VDcmVhdGVPcENvZGUsXG4gIGdldFBhcmVudEZyb21JY3VDcmVhdGVPcENvZGUsXG4gIGdldFJlZkZyb21JY3VDcmVhdGVPcENvZGUsXG59IGZyb20gJy4vaTE4bl91dGlsJztcblxuLyoqXG4gKiBDb252ZXJ0cyBgSTE4bkNyZWF0ZU9wQ29kZXNgIGFycmF5IGludG8gYSBodW1hbiByZWFkYWJsZSBmb3JtYXQuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBpcyBhdHRhY2hlZCB0byB0aGUgYEkxOG5DcmVhdGVPcENvZGVzLmRlYnVnYCBwcm9wZXJ0eSBpZiBgbmdEZXZNb2RlYCBpcyBlbmFibGVkLlxuICogVGhpcyBmdW5jdGlvbiBwcm92aWRlcyBhIGh1bWFuIHJlYWRhYmxlIHZpZXcgb2YgdGhlIG9wY29kZXMuIFRoaXMgaXMgdXNlZnVsIHdoZW4gZGVidWdnaW5nIHRoZVxuICogYXBwbGljYXRpb24gYXMgd2VsbCBhcyB3cml0aW5nIG1vcmUgcmVhZGFibGUgdGVzdHMuXG4gKlxuICogQHBhcmFtIHRoaXMgYEkxOG5DcmVhdGVPcENvZGVzYCBpZiBhdHRhY2hlZCBhcyBhIG1ldGhvZC5cbiAqIEBwYXJhbSBvcGNvZGVzIGBJMThuQ3JlYXRlT3BDb2Rlc2AgaWYgaW52b2tlZCBhcyBhIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaTE4bkNyZWF0ZU9wQ29kZXNUb1N0cmluZyhcbiAgdGhpczogSTE4bkNyZWF0ZU9wQ29kZXMgfCB2b2lkLFxuICBvcGNvZGVzPzogSTE4bkNyZWF0ZU9wQ29kZXMsXG4pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGNyZWF0ZU9wQ29kZXM6IEkxOG5DcmVhdGVPcENvZGVzID0gb3Bjb2RlcyB8fCAoQXJyYXkuaXNBcnJheSh0aGlzKSA/IHRoaXMgOiAoW10gYXMgYW55KSk7XG4gIGxldCBsaW5lczogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjcmVhdGVPcENvZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgb3BDb2RlID0gY3JlYXRlT3BDb2Rlc1tpKytdIGFzIGFueTtcbiAgICBjb25zdCB0ZXh0ID0gY3JlYXRlT3BDb2Rlc1tpXSBhcyBzdHJpbmc7XG4gICAgY29uc3QgaXNDb21tZW50ID0gKG9wQ29kZSAmIEkxOG5DcmVhdGVPcENvZGUuQ09NTUVOVCkgPT09IEkxOG5DcmVhdGVPcENvZGUuQ09NTUVOVDtcbiAgICBjb25zdCBhcHBlbmROb3cgPVxuICAgICAgKG9wQ29kZSAmIEkxOG5DcmVhdGVPcENvZGUuQVBQRU5EX0VBR0VSTFkpID09PSBJMThuQ3JlYXRlT3BDb2RlLkFQUEVORF9FQUdFUkxZO1xuICAgIGNvbnN0IGluZGV4ID0gb3BDb2RlID4+PiBJMThuQ3JlYXRlT3BDb2RlLlNISUZUO1xuICAgIGxpbmVzLnB1c2goXG4gICAgICBgbFZpZXdbJHtpbmRleH1dID0gZG9jdW1lbnQuJHtpc0NvbW1lbnQgPyAnY3JlYXRlQ29tbWVudCcgOiAnY3JlYXRlVGV4dCd9KCR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIHRleHQsXG4gICAgICApfSk7YCxcbiAgICApO1xuICAgIGlmIChhcHBlbmROb3cpIHtcbiAgICAgIGxpbmVzLnB1c2goYHBhcmVudC5hcHBlbmRDaGlsZChsVmlld1ske2luZGV4fV0pO2ApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbGluZXM7XG59XG5cbi8qKlxuICogQ29udmVydHMgYEkxOG5VcGRhdGVPcENvZGVzYCBhcnJheSBpbnRvIGEgaHVtYW4gcmVhZGFibGUgZm9ybWF0LlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgYXR0YWNoZWQgdG8gdGhlIGBJMThuVXBkYXRlT3BDb2Rlcy5kZWJ1Z2AgcHJvcGVydHkgaWYgYG5nRGV2TW9kZWAgaXMgZW5hYmxlZC5cbiAqIFRoaXMgZnVuY3Rpb24gcHJvdmlkZXMgYSBodW1hbiByZWFkYWJsZSB2aWV3IG9mIHRoZSBvcGNvZGVzLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIGRlYnVnZ2luZyB0aGVcbiAqIGFwcGxpY2F0aW9uIGFzIHdlbGwgYXMgd3JpdGluZyBtb3JlIHJlYWRhYmxlIHRlc3RzLlxuICpcbiAqIEBwYXJhbSB0aGlzIGBJMThuVXBkYXRlT3BDb2Rlc2AgaWYgYXR0YWNoZWQgYXMgYSBtZXRob2QuXG4gKiBAcGFyYW0gb3Bjb2RlcyBgSTE4blVwZGF0ZU9wQ29kZXNgIGlmIGludm9rZWQgYXMgYSBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGkxOG5VcGRhdGVPcENvZGVzVG9TdHJpbmcoXG4gIHRoaXM6IEkxOG5VcGRhdGVPcENvZGVzIHwgdm9pZCxcbiAgb3Bjb2Rlcz86IEkxOG5VcGRhdGVPcENvZGVzLFxuKTogc3RyaW5nW10ge1xuICBjb25zdCBwYXJzZXIgPSBuZXcgT3BDb2RlUGFyc2VyKG9wY29kZXMgfHwgKEFycmF5LmlzQXJyYXkodGhpcykgPyB0aGlzIDogW10pKTtcbiAgbGV0IGxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGZ1bmN0aW9uIGNvbnN1bWVPcENvZGUodmFsdWU6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgcmVmID0gdmFsdWUgPj4+IEkxOG5VcGRhdGVPcENvZGUuU0hJRlRfUkVGO1xuICAgIGNvbnN0IG9wQ29kZSA9IHZhbHVlICYgSTE4blVwZGF0ZU9wQ29kZS5NQVNLX09QQ09ERTtcbiAgICBzd2l0Y2ggKG9wQ29kZSkge1xuICAgICAgY2FzZSBJMThuVXBkYXRlT3BDb2RlLlRleHQ6XG4gICAgICAgIHJldHVybiBgKGxWaWV3WyR7cmVmfV0gYXMgVGV4dCkudGV4dENvbnRlbnQgPSAkJCRgO1xuICAgICAgY2FzZSBJMThuVXBkYXRlT3BDb2RlLkF0dHI6XG4gICAgICAgIGNvbnN0IGF0dHJOYW1lID0gcGFyc2VyLmNvbnN1bWVTdHJpbmcoKTtcbiAgICAgICAgY29uc3Qgc2FuaXRpemF0aW9uRm4gPSBwYXJzZXIuY29uc3VtZUZ1bmN0aW9uKCk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gc2FuaXRpemF0aW9uRm4gPyBgKCR7c2FuaXRpemF0aW9uRm59KSgkJCQpYCA6ICckJCQnO1xuICAgICAgICByZXR1cm4gYChsVmlld1ske3JlZn1dIGFzIEVsZW1lbnQpLnNldEF0dHJpYnV0ZSgnJHthdHRyTmFtZX0nLCAke3ZhbHVlfSlgO1xuICAgICAgY2FzZSBJMThuVXBkYXRlT3BDb2RlLkljdVN3aXRjaDpcbiAgICAgICAgcmV0dXJuIGBpY3VTd2l0Y2hDYXNlKCR7cmVmfSwgJCQkKWA7XG4gICAgICBjYXNlIEkxOG5VcGRhdGVPcENvZGUuSWN1VXBkYXRlOlxuICAgICAgICByZXR1cm4gYGljdVVwZGF0ZUNhc2UoJHtyZWZ9KWA7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcigndW5leHBlY3RlZCBPcENvZGUnKTtcbiAgfVxuXG4gIHdoaWxlIChwYXJzZXIuaGFzTW9yZSgpKSB7XG4gICAgbGV0IG1hc2sgPSBwYXJzZXIuY29uc3VtZU51bWJlcigpO1xuICAgIGxldCBzaXplID0gcGFyc2VyLmNvbnN1bWVOdW1iZXIoKTtcbiAgICBjb25zdCBlbmQgPSBwYXJzZXIuaSArIHNpemU7XG4gICAgY29uc3Qgc3RhdGVtZW50czogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgc3RhdGVtZW50ID0gJyc7XG4gICAgd2hpbGUgKHBhcnNlci5pIDwgZW5kKSB7XG4gICAgICBsZXQgdmFsdWUgPSBwYXJzZXIuY29uc3VtZU51bWJlck9yU3RyaW5nKCk7XG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICBzdGF0ZW1lbnQgKz0gdmFsdWU7XG4gICAgICB9IGVsc2UgaWYgKHZhbHVlIDwgMCkge1xuICAgICAgICAvLyBOZWdhdGl2ZSBudW1iZXJzIGFyZSByZWYgaW5kZXhlc1xuICAgICAgICAvLyBIZXJlIGBpYCByZWZlcnMgdG8gY3VycmVudCBiaW5kaW5nIGluZGV4LiBJdCBpcyB0byBzaWduaWZ5IHRoYXQgdGhlIHZhbHVlIGlzIHJlbGF0aXZlLFxuICAgICAgICAvLyByYXRoZXIgdGhhbiBhYnNvbHV0ZS5cbiAgICAgICAgc3RhdGVtZW50ICs9ICcke2xWaWV3W2knICsgdmFsdWUgKyAnXX0nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gUG9zaXRpdmUgbnVtYmVycyBhcmUgb3BlcmF0aW9ucy5cbiAgICAgICAgY29uc3Qgb3BDb2RlVGV4dCA9IGNvbnN1bWVPcENvZGUodmFsdWUpO1xuICAgICAgICBzdGF0ZW1lbnRzLnB1c2gob3BDb2RlVGV4dC5yZXBsYWNlKCckJCQnLCAnYCcgKyBzdGF0ZW1lbnQgKyAnYCcpICsgJzsnKTtcbiAgICAgICAgc3RhdGVtZW50ID0gJyc7XG4gICAgICB9XG4gICAgfVxuICAgIGxpbmVzLnB1c2goYGlmIChtYXNrICYgMGIke21hc2sudG9TdHJpbmcoMil9KSB7ICR7c3RhdGVtZW50cy5qb2luKCcgJyl9IH1gKTtcbiAgfVxuICByZXR1cm4gbGluZXM7XG59XG5cbi8qKlxuICogQ29udmVydHMgYEkxOG5DcmVhdGVPcENvZGVzYCBhcnJheSBpbnRvIGEgaHVtYW4gcmVhZGFibGUgZm9ybWF0LlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgYXR0YWNoZWQgdG8gdGhlIGBJMThuQ3JlYXRlT3BDb2Rlcy5kZWJ1Z2AgaWYgYG5nRGV2TW9kZWAgaXMgZW5hYmxlZC4gVGhpc1xuICogZnVuY3Rpb24gcHJvdmlkZXMgYSBodW1hbiByZWFkYWJsZSB2aWV3IG9mIHRoZSBvcGNvZGVzLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIGRlYnVnZ2luZyB0aGVcbiAqIGFwcGxpY2F0aW9uIGFzIHdlbGwgYXMgd3JpdGluZyBtb3JlIHJlYWRhYmxlIHRlc3RzLlxuICpcbiAqIEBwYXJhbSB0aGlzIGBJMThuQ3JlYXRlT3BDb2Rlc2AgaWYgYXR0YWNoZWQgYXMgYSBtZXRob2QuXG4gKiBAcGFyYW0gb3Bjb2RlcyBgSTE4bkNyZWF0ZU9wQ29kZXNgIGlmIGludm9rZWQgYXMgYSBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGljdUNyZWF0ZU9wQ29kZXNUb1N0cmluZyhcbiAgdGhpczogSWN1Q3JlYXRlT3BDb2RlcyB8IHZvaWQsXG4gIG9wY29kZXM/OiBJY3VDcmVhdGVPcENvZGVzLFxuKTogc3RyaW5nW10ge1xuICBjb25zdCBwYXJzZXIgPSBuZXcgT3BDb2RlUGFyc2VyKG9wY29kZXMgfHwgKEFycmF5LmlzQXJyYXkodGhpcykgPyB0aGlzIDogW10pKTtcbiAgbGV0IGxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGZ1bmN0aW9uIGNvbnN1bWVPcENvZGUob3BDb2RlOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGNvbnN0IHBhcmVudCA9IGdldFBhcmVudEZyb21JY3VDcmVhdGVPcENvZGUob3BDb2RlKTtcbiAgICBjb25zdCByZWYgPSBnZXRSZWZGcm9tSWN1Q3JlYXRlT3BDb2RlKG9wQ29kZSk7XG4gICAgc3dpdGNoIChnZXRJbnN0cnVjdGlvbkZyb21JY3VDcmVhdGVPcENvZGUob3BDb2RlKSkge1xuICAgICAgY2FzZSBJY3VDcmVhdGVPcENvZGUuQXBwZW5kQ2hpbGQ6XG4gICAgICAgIHJldHVybiBgKGxWaWV3WyR7cGFyZW50fV0gYXMgRWxlbWVudCkuYXBwZW5kQ2hpbGQobFZpZXdbJHtsYXN0UmVmfV0pYDtcbiAgICAgIGNhc2UgSWN1Q3JlYXRlT3BDb2RlLkF0dHI6XG4gICAgICAgIHJldHVybiBgKGxWaWV3WyR7cmVmfV0gYXMgRWxlbWVudCkuc2V0QXR0cmlidXRlKFwiJHtwYXJzZXIuY29uc3VtZVN0cmluZygpfVwiLCBcIiR7cGFyc2VyLmNvbnN1bWVTdHJpbmcoKX1cIilgO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgT3BDb2RlOiAnICsgZ2V0SW5zdHJ1Y3Rpb25Gcm9tSWN1Q3JlYXRlT3BDb2RlKG9wQ29kZSkpO1xuICB9XG5cbiAgbGV0IGxhc3RSZWYgPSAtMTtcbiAgd2hpbGUgKHBhcnNlci5oYXNNb3JlKCkpIHtcbiAgICBsZXQgdmFsdWUgPSBwYXJzZXIuY29uc3VtZU51bWJlclN0cmluZ09yTWFya2VyKCk7XG4gICAgaWYgKHZhbHVlID09PSBJQ1VfTUFSS0VSKSB7XG4gICAgICBjb25zdCB0ZXh0ID0gcGFyc2VyLmNvbnN1bWVTdHJpbmcoKTtcbiAgICAgIGxhc3RSZWYgPSBwYXJzZXIuY29uc3VtZU51bWJlcigpO1xuICAgICAgbGluZXMucHVzaChgbFZpZXdbJHtsYXN0UmVmfV0gPSBkb2N1bWVudC5jcmVhdGVDb21tZW50KFwiJHt0ZXh0fVwiKWApO1xuICAgIH0gZWxzZSBpZiAodmFsdWUgPT09IEVMRU1FTlRfTUFSS0VSKSB7XG4gICAgICBjb25zdCB0ZXh0ID0gcGFyc2VyLmNvbnN1bWVTdHJpbmcoKTtcbiAgICAgIGxhc3RSZWYgPSBwYXJzZXIuY29uc3VtZU51bWJlcigpO1xuICAgICAgbGluZXMucHVzaChgbFZpZXdbJHtsYXN0UmVmfV0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiJHt0ZXh0fVwiKWApO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgbGFzdFJlZiA9IHBhcnNlci5jb25zdW1lTnVtYmVyKCk7XG4gICAgICBsaW5lcy5wdXNoKGBsVmlld1ske2xhc3RSZWZ9XSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFwiJHt2YWx1ZX1cIilgKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIGNvbnN0IGxpbmUgPSBjb25zdW1lT3BDb2RlKHZhbHVlKTtcbiAgICAgIGxpbmUgJiYgbGluZXMucHVzaChsaW5lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIHZhbHVlJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGxpbmVzO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGBJMThuUmVtb3ZlT3BDb2Rlc2AgYXJyYXkgaW50byBhIGh1bWFuIHJlYWRhYmxlIGZvcm1hdC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGF0dGFjaGVkIHRvIHRoZSBgSTE4blJlbW92ZU9wQ29kZXMuZGVidWdgIGlmIGBuZ0Rldk1vZGVgIGlzIGVuYWJsZWQuIFRoaXNcbiAqIGZ1bmN0aW9uIHByb3ZpZGVzIGEgaHVtYW4gcmVhZGFibGUgdmlldyBvZiB0aGUgb3Bjb2Rlcy4gVGhpcyBpcyB1c2VmdWwgd2hlbiBkZWJ1Z2dpbmcgdGhlXG4gKiBhcHBsaWNhdGlvbiBhcyB3ZWxsIGFzIHdyaXRpbmcgbW9yZSByZWFkYWJsZSB0ZXN0cy5cbiAqXG4gKiBAcGFyYW0gdGhpcyBgSTE4blJlbW92ZU9wQ29kZXNgIGlmIGF0dGFjaGVkIGFzIGEgbWV0aG9kLlxuICogQHBhcmFtIG9wY29kZXMgYEkxOG5SZW1vdmVPcENvZGVzYCBpZiBpbnZva2VkIGFzIGEgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpMThuUmVtb3ZlT3BDb2Rlc1RvU3RyaW5nKFxuICB0aGlzOiBJMThuUmVtb3ZlT3BDb2RlcyB8IHZvaWQsXG4gIG9wY29kZXM/OiBJMThuUmVtb3ZlT3BDb2Rlcyxcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgcmVtb3ZlQ29kZXMgPSBvcGNvZGVzIHx8IChBcnJheS5pc0FycmF5KHRoaXMpID8gdGhpcyA6IFtdKTtcbiAgbGV0IGxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmVtb3ZlQ29kZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBub2RlT3JJY3VJbmRleCA9IHJlbW92ZUNvZGVzW2ldIGFzIG51bWJlcjtcbiAgICBpZiAobm9kZU9ySWN1SW5kZXggPiAwKSB7XG4gICAgICAvLyBQb3NpdGl2ZSBudW1iZXJzIGFyZSBgUk5vZGVgcy5cbiAgICAgIGxpbmVzLnB1c2goYHJlbW92ZShsVmlld1ske25vZGVPckljdUluZGV4fV0pYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5lZ2F0aXZlIG51bWJlcnMgYXJlIElDVXNcbiAgICAgIGxpbmVzLnB1c2goYHJlbW92ZU5lc3RlZElDVSgke35ub2RlT3JJY3VJbmRleH0pYCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGxpbmVzO1xufVxuXG5jbGFzcyBPcENvZGVQYXJzZXIge1xuICBpOiBudW1iZXIgPSAwO1xuICBjb2RlczogYW55W107XG5cbiAgY29uc3RydWN0b3IoY29kZXM6IGFueVtdKSB7XG4gICAgdGhpcy5jb2RlcyA9IGNvZGVzO1xuICB9XG5cbiAgaGFzTW9yZSgpIHtcbiAgICByZXR1cm4gdGhpcy5pIDwgdGhpcy5jb2Rlcy5sZW5ndGg7XG4gIH1cblxuICBjb25zdW1lTnVtYmVyKCk6IG51bWJlciB7XG4gICAgbGV0IHZhbHVlID0gdGhpcy5jb2Rlc1t0aGlzLmkrK107XG4gICAgYXNzZXJ0TnVtYmVyKHZhbHVlLCAnZXhwZWN0aW5nIG51bWJlciBpbiBPcENvZGUnKTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBjb25zdW1lU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgbGV0IHZhbHVlID0gdGhpcy5jb2Rlc1t0aGlzLmkrK107XG4gICAgYXNzZXJ0U3RyaW5nKHZhbHVlLCAnZXhwZWN0aW5nIHN0cmluZyBpbiBPcENvZGUnKTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBjb25zdW1lRnVuY3Rpb24oKTogRnVuY3Rpb24gfCBudWxsIHtcbiAgICBsZXQgdmFsdWUgPSB0aGlzLmNvZGVzW3RoaXMuaSsrXTtcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcignZXhwZWN0aW5nIGZ1bmN0aW9uIGluIE9wQ29kZScpO1xuICB9XG5cbiAgY29uc3VtZU51bWJlck9yU3RyaW5nKCk6IG51bWJlciB8IHN0cmluZyB7XG4gICAgbGV0IHZhbHVlID0gdGhpcy5jb2Rlc1t0aGlzLmkrK107XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgYXNzZXJ0TnVtYmVyKHZhbHVlLCAnZXhwZWN0aW5nIG51bWJlciBvciBzdHJpbmcgaW4gT3BDb2RlJyk7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgY29uc3VtZU51bWJlclN0cmluZ09yTWFya2VyKCk6IG51bWJlciB8IHN0cmluZyB8IElDVV9NQVJLRVIgfCBFTEVNRU5UX01BUktFUiB7XG4gICAgbGV0IHZhbHVlID0gdGhpcy5jb2Rlc1t0aGlzLmkrK107XG4gICAgaWYgKFxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fFxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyB8fFxuICAgICAgdmFsdWUgPT0gSUNVX01BUktFUiB8fFxuICAgICAgdmFsdWUgPT0gRUxFTUVOVF9NQVJLRVJcbiAgICApIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgYXNzZXJ0TnVtYmVyKHZhbHVlLCAnZXhwZWN0aW5nIG51bWJlciwgc3RyaW5nLCBJQ1VfTUFSS0VSIG9yIEVMRU1FTlRfTUFSS0VSIGluIE9wQ29kZScpO1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxufVxuIl19