UNPKG

matrix-react-sdk

Version:
171 lines (167 loc) 21.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CARET_NODE_CHAR = void 0; exports.isCaretNode = isCaretNode; exports.needsCaretNodeAfter = needsCaretNodeAfter; exports.needsCaretNodeBefore = needsCaretNodeBefore; exports.renderModel = renderModel; var _parts = require("./parts"); /* Copyright 2019-2024 New Vector Ltd. Copyright 2019 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ function needsCaretNodeBefore(part, prevPart) { const isFirst = !prevPart || prevPart.type === _parts.Type.Newline; return !part.acceptsCaret && (isFirst || !prevPart.acceptsCaret); } function needsCaretNodeAfter(part, isLastOfLine) { return !part.acceptsCaret && isLastOfLine; } function insertAfter(node, nodeToInsert) { const next = node.nextSibling; if (next) { node.parentElement.insertBefore(nodeToInsert, next); } else { node.parentElement.appendChild(nodeToInsert); } } // Use a BOM marker for caret nodes. // On a first test, they seem to be filtered out when copying text out of the editor, // but this could be platform dependent. // As a precautionary measure, I chose the character that slate also uses. const CARET_NODE_CHAR = exports.CARET_NODE_CHAR = "\ufeff"; // a caret node is a node that allows the caret to be placed // where otherwise it wouldn't be possible // (e.g. next to a pill span without adjacent text node) function createCaretNode() { const span = document.createElement("span"); span.className = "caretNode"; span.appendChild(document.createTextNode(CARET_NODE_CHAR)); return span; } function updateCaretNode(node) { // ensure the caret node contains only a zero-width space if (node.textContent !== CARET_NODE_CHAR) { node.textContent = CARET_NODE_CHAR; } } function isCaretNode(node) { return !!node && node instanceof HTMLElement && node.tagName === "SPAN" && node.className === "caretNode"; } function removeNextSiblings(node) { if (!node) { return; } node = node.nextSibling; while (node) { const removeNode = node; node = node.nextSibling; removeNode.remove(); } } function removeChildren(parent) { const firstChild = parent.firstChild; if (firstChild) { removeNextSiblings(firstChild); firstChild.remove(); } } function reconcileLine(lineContainer, parts) { let currentNode = null; let prevPart; const lastPart = parts[parts.length - 1]; for (const part of parts) { const isFirst = !prevPart; currentNode = isFirst ? lineContainer.firstChild : currentNode.nextSibling; if (needsCaretNodeBefore(part, prevPart)) { if (isCaretNode(currentNode)) { updateCaretNode(currentNode); currentNode = currentNode.nextSibling; } else { lineContainer.insertBefore(createCaretNode(), currentNode); } } // remove nodes until matching current part while (currentNode && !part.canUpdateDOMNode(currentNode)) { const nextNode = currentNode.nextSibling; lineContainer.removeChild(currentNode); currentNode = nextNode; } // update or insert node for current part if (currentNode && part) { part.updateDOMNode(currentNode); } else if (part) { currentNode = part.toDOMNode(); // hooks up nextSibling for next iteration lineContainer.appendChild(currentNode); } if (needsCaretNodeAfter(part, part === lastPart)) { if (isCaretNode(currentNode?.nextSibling)) { currentNode = currentNode.nextSibling; updateCaretNode(currentNode); } else { const caretNode = createCaretNode(); insertAfter(currentNode, caretNode); currentNode = caretNode; } } prevPart = part; } removeNextSiblings(currentNode); } function reconcileEmptyLine(lineContainer) { // empty div needs to have a BR in it to give it height let foundBR = false; let partNode = lineContainer.firstChild; while (partNode) { const nextNode = partNode.nextSibling; if (!foundBR && partNode.tagName === "BR") { foundBR = true; } else { partNode.remove(); } partNode = nextNode; } if (!foundBR) { lineContainer.appendChild(document.createElement("br")); } } function renderModel(editor, model) { const lines = model.parts.reduce((linesArr, part) => { if (part.type === _parts.Type.Newline) { linesArr.push([]); } else { const lastLine = linesArr[linesArr.length - 1]; lastLine.push(part); } return linesArr; }, [[]]); lines.forEach((parts, i) => { // find first (and remove anything else) div without className // (as browsers insert these in contenteditable) line container let lineContainer = editor.childNodes[i]; while (lineContainer && (lineContainer.tagName !== "DIV" || !!lineContainer.className)) { editor.removeChild(lineContainer); lineContainer = editor.childNodes[i]; } if (!lineContainer) { lineContainer = document.createElement("div"); editor.appendChild(lineContainer); } if (parts.length) { reconcileLine(lineContainer, parts); } else { reconcileEmptyLine(lineContainer); } }); if (lines.length) { removeNextSiblings(editor.children[lines.length - 1]); } else { removeChildren(editor); } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcGFydHMiLCJyZXF1aXJlIiwibmVlZHNDYXJldE5vZGVCZWZvcmUiLCJwYXJ0IiwicHJldlBhcnQiLCJpc0ZpcnN0IiwidHlwZSIsIlR5cGUiLCJOZXdsaW5lIiwiYWNjZXB0c0NhcmV0IiwibmVlZHNDYXJldE5vZGVBZnRlciIsImlzTGFzdE9mTGluZSIsImluc2VydEFmdGVyIiwibm9kZSIsIm5vZGVUb0luc2VydCIsIm5leHQiLCJuZXh0U2libGluZyIsInBhcmVudEVsZW1lbnQiLCJpbnNlcnRCZWZvcmUiLCJhcHBlbmRDaGlsZCIsIkNBUkVUX05PREVfQ0hBUiIsImV4cG9ydHMiLCJjcmVhdGVDYXJldE5vZGUiLCJzcGFuIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50IiwiY2xhc3NOYW1lIiwiY3JlYXRlVGV4dE5vZGUiLCJ1cGRhdGVDYXJldE5vZGUiLCJ0ZXh0Q29udGVudCIsImlzQ2FyZXROb2RlIiwiSFRNTEVsZW1lbnQiLCJ0YWdOYW1lIiwicmVtb3ZlTmV4dFNpYmxpbmdzIiwicmVtb3ZlTm9kZSIsInJlbW92ZSIsInJlbW92ZUNoaWxkcmVuIiwicGFyZW50IiwiZmlyc3RDaGlsZCIsInJlY29uY2lsZUxpbmUiLCJsaW5lQ29udGFpbmVyIiwicGFydHMiLCJjdXJyZW50Tm9kZSIsImxhc3RQYXJ0IiwibGVuZ3RoIiwiY2FuVXBkYXRlRE9NTm9kZSIsIm5leHROb2RlIiwicmVtb3ZlQ2hpbGQiLCJ1cGRhdGVET01Ob2RlIiwidG9ET01Ob2RlIiwiY2FyZXROb2RlIiwicmVjb25jaWxlRW1wdHlMaW5lIiwiZm91bmRCUiIsInBhcnROb2RlIiwicmVuZGVyTW9kZWwiLCJlZGl0b3IiLCJtb2RlbCIsImxpbmVzIiwicmVkdWNlIiwibGluZXNBcnIiLCJwdXNoIiwibGFzdExpbmUiLCJmb3JFYWNoIiwiaSIsImNoaWxkTm9kZXMiLCJjaGlsZHJlbiJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lZGl0b3IvcmVuZGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAxOS0yMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMTkgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IHsgUGFydCwgVHlwZSB9IGZyb20gXCIuL3BhcnRzXCI7XG5pbXBvcnQgRWRpdG9yTW9kZWwgZnJvbSBcIi4vbW9kZWxcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIG5lZWRzQ2FyZXROb2RlQmVmb3JlKHBhcnQ6IFBhcnQsIHByZXZQYXJ0PzogUGFydCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGlzRmlyc3QgPSAhcHJldlBhcnQgfHwgcHJldlBhcnQudHlwZSA9PT0gVHlwZS5OZXdsaW5lO1xuICAgIHJldHVybiAhcGFydC5hY2NlcHRzQ2FyZXQgJiYgKGlzRmlyc3QgfHwgIXByZXZQYXJ0LmFjY2VwdHNDYXJldCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBuZWVkc0NhcmV0Tm9kZUFmdGVyKHBhcnQ6IFBhcnQsIGlzTGFzdE9mTGluZTogYm9vbGVhbik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhcGFydC5hY2NlcHRzQ2FyZXQgJiYgaXNMYXN0T2ZMaW5lO1xufVxuXG5mdW5jdGlvbiBpbnNlcnRBZnRlcihub2RlOiBDaGlsZE5vZGUsIG5vZGVUb0luc2VydDogQ2hpbGROb2RlKTogdm9pZCB7XG4gICAgY29uc3QgbmV4dCA9IG5vZGUubmV4dFNpYmxpbmc7XG4gICAgaWYgKG5leHQpIHtcbiAgICAgICAgbm9kZS5wYXJlbnRFbGVtZW50IS5pbnNlcnRCZWZvcmUobm9kZVRvSW5zZXJ0LCBuZXh0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBub2RlLnBhcmVudEVsZW1lbnQhLmFwcGVuZENoaWxkKG5vZGVUb0luc2VydCk7XG4gICAgfVxufVxuXG4vLyBVc2UgYSBCT00gbWFya2VyIGZvciBjYXJldCBub2Rlcy5cbi8vIE9uIGEgZmlyc3QgdGVzdCwgdGhleSBzZWVtIHRvIGJlIGZpbHRlcmVkIG91dCB3aGVuIGNvcHlpbmcgdGV4dCBvdXQgb2YgdGhlIGVkaXRvcixcbi8vIGJ1dCB0aGlzIGNvdWxkIGJlIHBsYXRmb3JtIGRlcGVuZGVudC5cbi8vIEFzIGEgcHJlY2F1dGlvbmFyeSBtZWFzdXJlLCBJIGNob3NlIHRoZSBjaGFyYWN0ZXIgdGhhdCBzbGF0ZSBhbHNvIHVzZXMuXG5leHBvcnQgY29uc3QgQ0FSRVRfTk9ERV9DSEFSID0gXCJcXHVmZWZmXCI7XG4vLyBhIGNhcmV0IG5vZGUgaXMgYSBub2RlIHRoYXQgYWxsb3dzIHRoZSBjYXJldCB0byBiZSBwbGFjZWRcbi8vIHdoZXJlIG90aGVyd2lzZSBpdCB3b3VsZG4ndCBiZSBwb3NzaWJsZVxuLy8gKGUuZy4gbmV4dCB0byBhIHBpbGwgc3BhbiB3aXRob3V0IGFkamFjZW50IHRleHQgbm9kZSlcbmZ1bmN0aW9uIGNyZWF0ZUNhcmV0Tm9kZSgpOiBIVE1MRWxlbWVudCB7XG4gICAgY29uc3Qgc3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xuICAgIHNwYW4uY2xhc3NOYW1lID0gXCJjYXJldE5vZGVcIjtcbiAgICBzcGFuLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKENBUkVUX05PREVfQ0hBUikpO1xuICAgIHJldHVybiBzcGFuO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVDYXJldE5vZGUobm9kZTogQ2hpbGROb2RlKTogdm9pZCB7XG4gICAgLy8gZW5zdXJlIHRoZSBjYXJldCBub2RlIGNvbnRhaW5zIG9ubHkgYSB6ZXJvLXdpZHRoIHNwYWNlXG4gICAgaWYgKG5vZGUudGV4dENvbnRlbnQgIT09IENBUkVUX05PREVfQ0hBUikge1xuICAgICAgICBub2RlLnRleHRDb250ZW50ID0gQ0FSRVRfTk9ERV9DSEFSO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQ2FyZXROb2RlKG5vZGU/OiBOb2RlIHwgbnVsbCk6IG5vZGUgaXMgSFRNTEVsZW1lbnQge1xuICAgIHJldHVybiAhIW5vZGUgJiYgbm9kZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmIG5vZGUudGFnTmFtZSA9PT0gXCJTUEFOXCIgJiYgbm9kZS5jbGFzc05hbWUgPT09IFwiY2FyZXROb2RlXCI7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZU5leHRTaWJsaW5ncyhub2RlOiBDaGlsZE5vZGUgfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKCFub2RlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbm9kZSA9IG5vZGUubmV4dFNpYmxpbmc7XG4gICAgd2hpbGUgKG5vZGUpIHtcbiAgICAgICAgY29uc3QgcmVtb3ZlTm9kZSA9IG5vZGU7XG4gICAgICAgIG5vZGUgPSBub2RlLm5leHRTaWJsaW5nO1xuICAgICAgICByZW1vdmVOb2RlLnJlbW92ZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcmVtb3ZlQ2hpbGRyZW4ocGFyZW50OiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgIGNvbnN0IGZpcnN0Q2hpbGQgPSBwYXJlbnQuZmlyc3RDaGlsZDtcbiAgICBpZiAoZmlyc3RDaGlsZCkge1xuICAgICAgICByZW1vdmVOZXh0U2libGluZ3MoZmlyc3RDaGlsZCk7XG4gICAgICAgIGZpcnN0Q2hpbGQucmVtb3ZlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiByZWNvbmNpbGVMaW5lKGxpbmVDb250YWluZXI6IENoaWxkTm9kZSwgcGFydHM6IFBhcnRbXSk6IHZvaWQge1xuICAgIGxldCBjdXJyZW50Tm9kZTogQ2hpbGROb2RlIHwgbnVsbCA9IG51bGw7XG4gICAgbGV0IHByZXZQYXJ0OiBQYXJ0IHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IGxhc3RQYXJ0ID0gcGFydHNbcGFydHMubGVuZ3RoIC0gMV07XG5cbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgICAgY29uc3QgaXNGaXJzdCA9ICFwcmV2UGFydDtcbiAgICAgICAgY3VycmVudE5vZGUgPSBpc0ZpcnN0ID8gbGluZUNvbnRhaW5lci5maXJzdENoaWxkIDogY3VycmVudE5vZGUhLm5leHRTaWJsaW5nO1xuXG4gICAgICAgIGlmIChuZWVkc0NhcmV0Tm9kZUJlZm9yZShwYXJ0LCBwcmV2UGFydCkpIHtcbiAgICAgICAgICAgIGlmIChpc0NhcmV0Tm9kZShjdXJyZW50Tm9kZSBhcyBFbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIHVwZGF0ZUNhcmV0Tm9kZShjdXJyZW50Tm9kZSEpO1xuICAgICAgICAgICAgICAgIGN1cnJlbnROb2RlID0gY3VycmVudE5vZGUhLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsaW5lQ29udGFpbmVyLmluc2VydEJlZm9yZShjcmVhdGVDYXJldE5vZGUoKSwgY3VycmVudE5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIHJlbW92ZSBub2RlcyB1bnRpbCBtYXRjaGluZyBjdXJyZW50IHBhcnRcbiAgICAgICAgd2hpbGUgKGN1cnJlbnROb2RlICYmICFwYXJ0LmNhblVwZGF0ZURPTU5vZGUoY3VycmVudE5vZGUpKSB7XG4gICAgICAgICAgICBjb25zdCBuZXh0Tm9kZSA9IGN1cnJlbnROb2RlLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgbGluZUNvbnRhaW5lci5yZW1vdmVDaGlsZChjdXJyZW50Tm9kZSk7XG4gICAgICAgICAgICBjdXJyZW50Tm9kZSA9IG5leHROb2RlO1xuICAgICAgICB9XG4gICAgICAgIC8vIHVwZGF0ZSBvciBpbnNlcnQgbm9kZSBmb3IgY3VycmVudCBwYXJ0XG4gICAgICAgIGlmIChjdXJyZW50Tm9kZSAmJiBwYXJ0KSB7XG4gICAgICAgICAgICBwYXJ0LnVwZGF0ZURPTU5vZGUoY3VycmVudE5vZGUpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnQpIHtcbiAgICAgICAgICAgIGN1cnJlbnROb2RlID0gcGFydC50b0RPTU5vZGUoKSBhcyBDaGlsZE5vZGU7XG4gICAgICAgICAgICAvLyBob29rcyB1cCBuZXh0U2libGluZyBmb3IgbmV4dCBpdGVyYXRpb25cbiAgICAgICAgICAgIGxpbmVDb250YWluZXIuYXBwZW5kQ2hpbGQoY3VycmVudE5vZGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG5lZWRzQ2FyZXROb2RlQWZ0ZXIocGFydCwgcGFydCA9PT0gbGFzdFBhcnQpKSB7XG4gICAgICAgICAgICBpZiAoaXNDYXJldE5vZGUoY3VycmVudE5vZGU/Lm5leHRTaWJsaW5nIGFzIEVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZSEubmV4dFNpYmxpbmc7XG4gICAgICAgICAgICAgICAgdXBkYXRlQ2FyZXROb2RlKGN1cnJlbnROb2RlIGFzIEhUTUxFbGVtZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FyZXROb2RlID0gY3JlYXRlQ2FyZXROb2RlKCk7XG4gICAgICAgICAgICAgICAgaW5zZXJ0QWZ0ZXIoY3VycmVudE5vZGUgYXMgSFRNTEVsZW1lbnQsIGNhcmV0Tm9kZSk7XG4gICAgICAgICAgICAgICAgY3VycmVudE5vZGUgPSBjYXJldE5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBwcmV2UGFydCA9IHBhcnQ7XG4gICAgfVxuXG4gICAgcmVtb3ZlTmV4dFNpYmxpbmdzKGN1cnJlbnROb2RlKTtcbn1cblxuZnVuY3Rpb24gcmVjb25jaWxlRW1wdHlMaW5lKGxpbmVDb250YWluZXI6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgLy8gZW1wdHkgZGl2IG5lZWRzIHRvIGhhdmUgYSBCUiBpbiBpdCB0byBnaXZlIGl0IGhlaWdodFxuICAgIGxldCBmb3VuZEJSID0gZmFsc2U7XG4gICAgbGV0IHBhcnROb2RlID0gbGluZUNvbnRhaW5lci5maXJzdENoaWxkO1xuICAgIHdoaWxlIChwYXJ0Tm9kZSkge1xuICAgICAgICBjb25zdCBuZXh0Tm9kZSA9IHBhcnROb2RlLm5leHRTaWJsaW5nO1xuICAgICAgICBpZiAoIWZvdW5kQlIgJiYgKHBhcnROb2RlIGFzIEhUTUxFbGVtZW50KS50YWdOYW1lID09PSBcIkJSXCIpIHtcbiAgICAgICAgICAgIGZvdW5kQlIgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFydE5vZGUucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcGFydE5vZGUgPSBuZXh0Tm9kZTtcbiAgICB9XG4gICAgaWYgKCFmb3VuZEJSKSB7XG4gICAgICAgIGxpbmVDb250YWluZXIuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImJyXCIpKTtcbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJNb2RlbChlZGl0b3I6IEhUTUxEaXZFbGVtZW50LCBtb2RlbDogRWRpdG9yTW9kZWwpOiB2b2lkIHtcbiAgICBjb25zdCBsaW5lcyA9IG1vZGVsLnBhcnRzLnJlZHVjZTxQYXJ0W11bXT4oXG4gICAgICAgIChsaW5lc0FyciwgcGFydCkgPT4ge1xuICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gVHlwZS5OZXdsaW5lKSB7XG4gICAgICAgICAgICAgICAgbGluZXNBcnIucHVzaChbXSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxhc3RMaW5lID0gbGluZXNBcnJbbGluZXNBcnIubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgbGFzdExpbmUucHVzaChwYXJ0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBsaW5lc0FycjtcbiAgICAgICAgfSxcbiAgICAgICAgW1tdXSxcbiAgICApO1xuICAgIGxpbmVzLmZvckVhY2goKHBhcnRzLCBpKSA9PiB7XG4gICAgICAgIC8vIGZpbmQgZmlyc3QgKGFuZCByZW1vdmUgYW55dGhpbmcgZWxzZSkgZGl2IHdpdGhvdXQgY2xhc3NOYW1lXG4gICAgICAgIC8vIChhcyBicm93c2VycyBpbnNlcnQgdGhlc2UgaW4gY29udGVudGVkaXRhYmxlKSBsaW5lIGNvbnRhaW5lclxuICAgICAgICBsZXQgbGluZUNvbnRhaW5lciA9IGVkaXRvci5jaGlsZE5vZGVzW2ldO1xuICAgICAgICB3aGlsZSAobGluZUNvbnRhaW5lciAmJiAoKDxFbGVtZW50PmxpbmVDb250YWluZXIpLnRhZ05hbWUgIT09IFwiRElWXCIgfHwgISEoPEVsZW1lbnQ+bGluZUNvbnRhaW5lcikuY2xhc3NOYW1lKSkge1xuICAgICAgICAgICAgZWRpdG9yLnJlbW92ZUNoaWxkKGxpbmVDb250YWluZXIpO1xuICAgICAgICAgICAgbGluZUNvbnRhaW5lciA9IGVkaXRvci5jaGlsZE5vZGVzW2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmICghbGluZUNvbnRhaW5lcikge1xuICAgICAgICAgICAgbGluZUNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgICAgICBlZGl0b3IuYXBwZW5kQ2hpbGQobGluZUNvbnRhaW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydHMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZWNvbmNpbGVMaW5lKGxpbmVDb250YWluZXIsIHBhcnRzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlY29uY2lsZUVtcHR5TGluZShsaW5lQ29udGFpbmVyIGFzIEhUTUxFbGVtZW50KTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChsaW5lcy5sZW5ndGgpIHtcbiAgICAgICAgcmVtb3ZlTmV4dFNpYmxpbmdzKGVkaXRvci5jaGlsZHJlbltsaW5lcy5sZW5ndGggLSAxXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmVtb3ZlQ2hpbGRyZW4oZWRpdG9y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