UNPKG

matrix-react-sdk

Version:
182 lines (178 loc) 21.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.getLineAndNodePosition = getLineAndNodePosition; exports.setCaretPosition = setCaretPosition; exports.setSelection = setSelection; var _render = require("./render"); var _range = _interopRequireDefault(require("./range")); 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 setSelection(editor, model, selection) { if (selection instanceof _range.default) { setDocumentRangeSelection(editor, model, selection); } else { setCaretPosition(editor, model, selection); } } function setDocumentRangeSelection(editor, model, range) { const sel = document.getSelection(); sel.removeAllRanges(); const selectionRange = document.createRange(); const start = getNodeAndOffsetForPosition(editor, model, range.start); selectionRange.setStart(start.node, start.offset); const end = getNodeAndOffsetForPosition(editor, model, range.end); selectionRange.setEnd(end.node, end.offset); sel.addRange(selectionRange); } function setCaretPosition(editor, model, caretPosition) { if (model.isEmpty) return; // selection can't possibly be wrong, so avoid a reflow const range = document.createRange(); const { node, offset } = getNodeAndOffsetForPosition(editor, model, caretPosition); range.setStart(node, offset); range.collapse(true); const sel = document.getSelection(); if (sel.rangeCount === 1) { const existingRange = sel.getRangeAt(0); if (existingRange.startContainer === range.startContainer && existingRange.startOffset === range.startOffset && existingRange.collapsed === range.collapsed) { // If the selection matches, it's important to leave it alone. // Recreating the selection state in at least Chrome can cause // strange side effects, like touch bar flickering on every key. // See https://github.com/vector-im/element-web/issues/9299 return; } } sel.removeAllRanges(); sel.addRange(range); } function getNodeAndOffsetForPosition(editor, model, position) { const { offset, lineIndex, nodeIndex } = getLineAndNodePosition(model, position); const lineNode = editor.childNodes[lineIndex]; let focusNode; // empty line with just a <br> if (nodeIndex === -1) { focusNode = lineNode; } else { focusNode = lineNode.childNodes[nodeIndex]; // make sure we have a text node if (focusNode.nodeType === Node.ELEMENT_NODE && focusNode.firstChild) { focusNode = focusNode.firstChild; } } return { node: focusNode, offset }; } function getLineAndNodePosition(model, caretPosition) { const { parts } = model; const partIndex = caretPosition.index; let { offset } = caretPosition; const lineResult = findNodeInLineForPart(parts, partIndex, offset); const { lineIndex } = lineResult; let { nodeIndex } = lineResult; // we're at an empty line between a newline part // and another newline part or end/start of parts. // set offset to 0 so it gets set to the <br> inside the line container if (nodeIndex === -1) { offset = 0; } else { // move caret out of uneditable part (into caret node, or empty line br) if needed ({ nodeIndex, offset } = moveOutOfUnselectablePart(parts, partIndex, nodeIndex, offset)); } return { lineIndex, nodeIndex, offset }; } function findNodeInLineForPart(parts, partIndex, offset) { let lineIndex = 0; let nodeIndex = -1; let prevPart; // go through to parts up till (and including) the index // to find newline parts for (let i = 0; i <= partIndex; ++i) { const part = parts[i]; if (part.type === _parts.Type.Newline) { // don't jump over the linebreak if the offset is before it if (i == partIndex && offset === 0) { continue; } lineIndex += 1; nodeIndex = -1; prevPart = undefined; } else { nodeIndex += 1; if ((0, _render.needsCaretNodeBefore)(part, prevPart)) { nodeIndex += 1; } // only jump over caret node if we're not at our destination node already, // as we'll assume in moveOutOfUnselectablePart that nodeIndex // refers to the node corresponding to the part, // and not an adjacent caret node if (i < partIndex) { const nextPart = parts[i + 1]; const isLastOfLine = !nextPart || nextPart.type === _parts.Type.Newline; if ((0, _render.needsCaretNodeAfter)(part, isLastOfLine)) { nodeIndex += 1; } } prevPart = part; } } return { lineIndex, nodeIndex }; } function moveOutOfUnselectablePart(parts, partIndex, nodeIndex, offset) { // move caret before or after unselectable part const part = parts[partIndex]; if (part && !part.acceptsCaret) { if (offset === 0) { nodeIndex -= 1; const prevPart = parts[partIndex - 1]; // if the previous node is a caret node, it's empty // so the offset can stay at 0 // only when it's not, we need to set the offset // at the end of the node if (!(0, _render.needsCaretNodeBefore)(part, prevPart)) { offset = prevPart.text.length; } } else { nodeIndex += 1; offset = 0; } } return { nodeIndex, offset }; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVuZGVyIiwicmVxdWlyZSIsIl9yYW5nZSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfcGFydHMiLCJzZXRTZWxlY3Rpb24iLCJlZGl0b3IiLCJtb2RlbCIsInNlbGVjdGlvbiIsIlJhbmdlIiwic2V0RG9jdW1lbnRSYW5nZVNlbGVjdGlvbiIsInNldENhcmV0UG9zaXRpb24iLCJyYW5nZSIsInNlbCIsImRvY3VtZW50IiwiZ2V0U2VsZWN0aW9uIiwicmVtb3ZlQWxsUmFuZ2VzIiwic2VsZWN0aW9uUmFuZ2UiLCJjcmVhdGVSYW5nZSIsInN0YXJ0IiwiZ2V0Tm9kZUFuZE9mZnNldEZvclBvc2l0aW9uIiwic2V0U3RhcnQiLCJub2RlIiwib2Zmc2V0IiwiZW5kIiwic2V0RW5kIiwiYWRkUmFuZ2UiLCJjYXJldFBvc2l0aW9uIiwiaXNFbXB0eSIsImNvbGxhcHNlIiwicmFuZ2VDb3VudCIsImV4aXN0aW5nUmFuZ2UiLCJnZXRSYW5nZUF0Iiwic3RhcnRDb250YWluZXIiLCJzdGFydE9mZnNldCIsImNvbGxhcHNlZCIsInBvc2l0aW9uIiwibGluZUluZGV4Iiwibm9kZUluZGV4IiwiZ2V0TGluZUFuZE5vZGVQb3NpdGlvbiIsImxpbmVOb2RlIiwiY2hpbGROb2RlcyIsImZvY3VzTm9kZSIsIm5vZGVUeXBlIiwiTm9kZSIsIkVMRU1FTlRfTk9ERSIsImZpcnN0Q2hpbGQiLCJwYXJ0cyIsInBhcnRJbmRleCIsImluZGV4IiwibGluZVJlc3VsdCIsImZpbmROb2RlSW5MaW5lRm9yUGFydCIsIm1vdmVPdXRPZlVuc2VsZWN0YWJsZVBhcnQiLCJwcmV2UGFydCIsImkiLCJwYXJ0IiwidHlwZSIsIlR5cGUiLCJOZXdsaW5lIiwidW5kZWZpbmVkIiwibmVlZHNDYXJldE5vZGVCZWZvcmUiLCJuZXh0UGFydCIsImlzTGFzdE9mTGluZSIsIm5lZWRzQ2FyZXROb2RlQWZ0ZXIiLCJhY2NlcHRzQ2FyZXQiLCJ0ZXh0IiwibGVuZ3RoIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2VkaXRvci9jYXJldC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuQ29weXJpZ2h0IDIwMTktMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDE5IFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCB7IG5lZWRzQ2FyZXROb2RlQmVmb3JlLCBuZWVkc0NhcmV0Tm9kZUFmdGVyIH0gZnJvbSBcIi4vcmVuZGVyXCI7XG5pbXBvcnQgUmFuZ2UgZnJvbSBcIi4vcmFuZ2VcIjtcbmltcG9ydCBFZGl0b3JNb2RlbCBmcm9tIFwiLi9tb2RlbFwiO1xuaW1wb3J0IERvY3VtZW50UG9zaXRpb24sIHsgSVBvc2l0aW9uIH0gZnJvbSBcIi4vcG9zaXRpb25cIjtcbmltcG9ydCB7IFBhcnQsIFR5cGUgfSBmcm9tIFwiLi9wYXJ0c1wiO1xuXG5leHBvcnQgdHlwZSBDYXJldCA9IFJhbmdlIHwgRG9jdW1lbnRQb3NpdGlvbjtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldFNlbGVjdGlvbihlZGl0b3I6IEhUTUxEaXZFbGVtZW50LCBtb2RlbDogRWRpdG9yTW9kZWwsIHNlbGVjdGlvbjogUmFuZ2UgfCBJUG9zaXRpb24pOiB2b2lkIHtcbiAgICBpZiAoc2VsZWN0aW9uIGluc3RhbmNlb2YgUmFuZ2UpIHtcbiAgICAgICAgc2V0RG9jdW1lbnRSYW5nZVNlbGVjdGlvbihlZGl0b3IsIG1vZGVsLCBzZWxlY3Rpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHNldENhcmV0UG9zaXRpb24oZWRpdG9yLCBtb2RlbCwgc2VsZWN0aW9uKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHNldERvY3VtZW50UmFuZ2VTZWxlY3Rpb24oZWRpdG9yOiBIVE1MRGl2RWxlbWVudCwgbW9kZWw6IEVkaXRvck1vZGVsLCByYW5nZTogUmFuZ2UpOiB2b2lkIHtcbiAgICBjb25zdCBzZWwgPSBkb2N1bWVudC5nZXRTZWxlY3Rpb24oKSE7XG4gICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgIGNvbnN0IHNlbGVjdGlvblJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICBjb25zdCBzdGFydCA9IGdldE5vZGVBbmRPZmZzZXRGb3JQb3NpdGlvbihlZGl0b3IsIG1vZGVsLCByYW5nZS5zdGFydCk7XG4gICAgc2VsZWN0aW9uUmFuZ2Uuc2V0U3RhcnQoc3RhcnQubm9kZSwgc3RhcnQub2Zmc2V0KTtcbiAgICBjb25zdCBlbmQgPSBnZXROb2RlQW5kT2Zmc2V0Rm9yUG9zaXRpb24oZWRpdG9yLCBtb2RlbCwgcmFuZ2UuZW5kKTtcbiAgICBzZWxlY3Rpb25SYW5nZS5zZXRFbmQoZW5kLm5vZGUsIGVuZC5vZmZzZXQpO1xuICAgIHNlbC5hZGRSYW5nZShzZWxlY3Rpb25SYW5nZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRDYXJldFBvc2l0aW9uKGVkaXRvcjogSFRNTERpdkVsZW1lbnQsIG1vZGVsOiBFZGl0b3JNb2RlbCwgY2FyZXRQb3NpdGlvbjogSVBvc2l0aW9uKTogdm9pZCB7XG4gICAgaWYgKG1vZGVsLmlzRW1wdHkpIHJldHVybjsgLy8gc2VsZWN0aW9uIGNhbid0IHBvc3NpYmx5IGJlIHdyb25nLCBzbyBhdm9pZCBhIHJlZmxvd1xuXG4gICAgY29uc3QgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIGNvbnN0IHsgbm9kZSwgb2Zmc2V0IH0gPSBnZXROb2RlQW5kT2Zmc2V0Rm9yUG9zaXRpb24oZWRpdG9yLCBtb2RlbCwgY2FyZXRQb3NpdGlvbik7XG4gICAgcmFuZ2Uuc2V0U3RhcnQobm9kZSwgb2Zmc2V0KTtcbiAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTtcblxuICAgIGNvbnN0IHNlbCA9IGRvY3VtZW50LmdldFNlbGVjdGlvbigpITtcbiAgICBpZiAoc2VsLnJhbmdlQ291bnQgPT09IDEpIHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdSYW5nZSA9IHNlbC5nZXRSYW5nZUF0KDApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICBleGlzdGluZ1JhbmdlLnN0YXJ0Q29udGFpbmVyID09PSByYW5nZS5zdGFydENvbnRhaW5lciAmJlxuICAgICAgICAgICAgZXhpc3RpbmdSYW5nZS5zdGFydE9mZnNldCA9PT0gcmFuZ2Uuc3RhcnRPZmZzZXQgJiZcbiAgICAgICAgICAgIGV4aXN0aW5nUmFuZ2UuY29sbGFwc2VkID09PSByYW5nZS5jb2xsYXBzZWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyBJZiB0aGUgc2VsZWN0aW9uIG1hdGNoZXMsIGl0J3MgaW1wb3J0YW50IHRvIGxlYXZlIGl0IGFsb25lLlxuICAgICAgICAgICAgLy8gUmVjcmVhdGluZyB0aGUgc2VsZWN0aW9uIHN0YXRlIGluIGF0IGxlYXN0IENocm9tZSBjYW4gY2F1c2VcbiAgICAgICAgICAgIC8vIHN0cmFuZ2Ugc2lkZSBlZmZlY3RzLCBsaWtlIHRvdWNoIGJhciBmbGlja2VyaW5nIG9uIGV2ZXJ5IGtleS5cbiAgICAgICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vdmVjdG9yLWltL2VsZW1lbnQtd2ViL2lzc3Vlcy85Mjk5XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgIHNlbC5hZGRSYW5nZShyYW5nZSk7XG59XG5cbmZ1bmN0aW9uIGdldE5vZGVBbmRPZmZzZXRGb3JQb3NpdGlvbihcbiAgICBlZGl0b3I6IEhUTUxEaXZFbGVtZW50LFxuICAgIG1vZGVsOiBFZGl0b3JNb2RlbCxcbiAgICBwb3NpdGlvbjogSVBvc2l0aW9uLFxuKToge1xuICAgIG5vZGU6IE5vZGU7XG4gICAgb2Zmc2V0OiBudW1iZXI7XG59IHtcbiAgICBjb25zdCB7IG9mZnNldCwgbGluZUluZGV4LCBub2RlSW5kZXggfSA9IGdldExpbmVBbmROb2RlUG9zaXRpb24obW9kZWwsIHBvc2l0aW9uKTtcbiAgICBjb25zdCBsaW5lTm9kZSA9IGVkaXRvci5jaGlsZE5vZGVzW2xpbmVJbmRleF07XG5cbiAgICBsZXQgZm9jdXNOb2RlO1xuICAgIC8vIGVtcHR5IGxpbmUgd2l0aCBqdXN0IGEgPGJyPlxuICAgIGlmIChub2RlSW5kZXggPT09IC0xKSB7XG4gICAgICAgIGZvY3VzTm9kZSA9IGxpbmVOb2RlO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGZvY3VzTm9kZSA9IGxpbmVOb2RlLmNoaWxkTm9kZXNbbm9kZUluZGV4XTtcbiAgICAgICAgLy8gbWFrZSBzdXJlIHdlIGhhdmUgYSB0ZXh0IG5vZGVcbiAgICAgICAgaWYgKGZvY3VzTm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUgJiYgZm9jdXNOb2RlLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgIGZvY3VzTm9kZSA9IGZvY3VzTm9kZS5maXJzdENoaWxkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IG5vZGU6IGZvY3VzTm9kZSwgb2Zmc2V0IH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMaW5lQW5kTm9kZVBvc2l0aW9uKFxuICAgIG1vZGVsOiBFZGl0b3JNb2RlbCxcbiAgICBjYXJldFBvc2l0aW9uOiBJUG9zaXRpb24sXG4pOiB7XG4gICAgb2Zmc2V0OiBudW1iZXI7XG4gICAgbGluZUluZGV4OiBudW1iZXI7XG4gICAgbm9kZUluZGV4OiBudW1iZXI7XG59IHtcbiAgICBjb25zdCB7IHBhcnRzIH0gPSBtb2RlbDtcbiAgICBjb25zdCBwYXJ0SW5kZXggPSBjYXJldFBvc2l0aW9uLmluZGV4O1xuICAgIGxldCB7IG9mZnNldCB9ID0gY2FyZXRQb3NpdGlvbjtcbiAgICBjb25zdCBsaW5lUmVzdWx0ID0gZmluZE5vZGVJbkxpbmVGb3JQYXJ0KHBhcnRzLCBwYXJ0SW5kZXgsIG9mZnNldCk7XG4gICAgY29uc3QgeyBsaW5lSW5kZXggfSA9IGxpbmVSZXN1bHQ7XG4gICAgbGV0IHsgbm9kZUluZGV4IH0gPSBsaW5lUmVzdWx0O1xuICAgIC8vIHdlJ3JlIGF0IGFuIGVtcHR5IGxpbmUgYmV0d2VlbiBhIG5ld2xpbmUgcGFydFxuICAgIC8vIGFuZCBhbm90aGVyIG5ld2xpbmUgcGFydCBvciBlbmQvc3RhcnQgb2YgcGFydHMuXG4gICAgLy8gc2V0IG9mZnNldCB0byAwIHNvIGl0IGdldHMgc2V0IHRvIHRoZSA8YnI+IGluc2lkZSB0aGUgbGluZSBjb250YWluZXJcbiAgICBpZiAobm9kZUluZGV4ID09PSAtMSkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG1vdmUgY2FyZXQgb3V0IG9mIHVuZWRpdGFibGUgcGFydCAoaW50byBjYXJldCBub2RlLCBvciBlbXB0eSBsaW5lIGJyKSBpZiBuZWVkZWRcbiAgICAgICAgKHsgbm9kZUluZGV4LCBvZmZzZXQgfSA9IG1vdmVPdXRPZlVuc2VsZWN0YWJsZVBhcnQocGFydHMsIHBhcnRJbmRleCwgbm9kZUluZGV4LCBvZmZzZXQpKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgbGluZUluZGV4LCBub2RlSW5kZXgsIG9mZnNldCB9O1xufVxuXG5mdW5jdGlvbiBmaW5kTm9kZUluTGluZUZvclBhcnQoXG4gICAgcGFydHM6IFBhcnRbXSxcbiAgICBwYXJ0SW5kZXg6IG51bWJlcixcbiAgICBvZmZzZXQ6IG51bWJlcixcbik6IHsgbGluZUluZGV4OiBudW1iZXI7IG5vZGVJbmRleDogbnVtYmVyIH0ge1xuICAgIGxldCBsaW5lSW5kZXggPSAwO1xuICAgIGxldCBub2RlSW5kZXggPSAtMTtcblxuICAgIGxldCBwcmV2UGFydDogUGFydCB8IHVuZGVmaW5lZDtcbiAgICAvLyBnbyB0aHJvdWdoIHRvIHBhcnRzIHVwIHRpbGwgKGFuZCBpbmNsdWRpbmcpIHRoZSBpbmRleFxuICAgIC8vIHRvIGZpbmQgbmV3bGluZSBwYXJ0c1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IHBhcnRJbmRleDsgKytpKSB7XG4gICAgICAgIGNvbnN0IHBhcnQgPSBwYXJ0c1tpXTtcbiAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gVHlwZS5OZXdsaW5lKSB7XG4gICAgICAgICAgICAvLyBkb24ndCBqdW1wIG92ZXIgdGhlIGxpbmVicmVhayBpZiB0aGUgb2Zmc2V0IGlzIGJlZm9yZSBpdFxuICAgICAgICAgICAgaWYgKGkgPT0gcGFydEluZGV4ICYmIG9mZnNldCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGluZUluZGV4ICs9IDE7XG4gICAgICAgICAgICBub2RlSW5kZXggPSAtMTtcbiAgICAgICAgICAgIHByZXZQYXJ0ID0gdW5kZWZpbmVkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbm9kZUluZGV4ICs9IDE7XG4gICAgICAgICAgICBpZiAobmVlZHNDYXJldE5vZGVCZWZvcmUocGFydCwgcHJldlBhcnQpKSB7XG4gICAgICAgICAgICAgICAgbm9kZUluZGV4ICs9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBvbmx5IGp1bXAgb3ZlciBjYXJldCBub2RlIGlmIHdlJ3JlIG5vdCBhdCBvdXIgZGVzdGluYXRpb24gbm9kZSBhbHJlYWR5LFxuICAgICAgICAgICAgLy8gYXMgd2UnbGwgYXNzdW1lIGluIG1vdmVPdXRPZlVuc2VsZWN0YWJsZVBhcnQgdGhhdCBub2RlSW5kZXhcbiAgICAgICAgICAgIC8vIHJlZmVycyB0byB0aGUgbm9kZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBwYXJ0LFxuICAgICAgICAgICAgLy8gYW5kIG5vdCBhbiBhZGphY2VudCBjYXJldCBub2RlXG4gICAgICAgICAgICBpZiAoaSA8IHBhcnRJbmRleCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5leHRQYXJ0ID0gcGFydHNbaSArIDFdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGlzTGFzdE9mTGluZSA9ICFuZXh0UGFydCB8fCBuZXh0UGFydC50eXBlID09PSBUeXBlLk5ld2xpbmU7XG4gICAgICAgICAgICAgICAgaWYgKG5lZWRzQ2FyZXROb2RlQWZ0ZXIocGFydCwgaXNMYXN0T2ZMaW5lKSkge1xuICAgICAgICAgICAgICAgICAgICBub2RlSW5kZXggKz0gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwcmV2UGFydCA9IHBhcnQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyBsaW5lSW5kZXgsIG5vZGVJbmRleCB9O1xufVxuXG5mdW5jdGlvbiBtb3ZlT3V0T2ZVbnNlbGVjdGFibGVQYXJ0KFxuICAgIHBhcnRzOiBQYXJ0W10sXG4gICAgcGFydEluZGV4OiBudW1iZXIsXG4gICAgbm9kZUluZGV4OiBudW1iZXIsXG4gICAgb2Zmc2V0OiBudW1iZXIsXG4pOiB7IG9mZnNldDogbnVtYmVyOyBub2RlSW5kZXg6IG51bWJlciB9IHtcbiAgICAvLyBtb3ZlIGNhcmV0IGJlZm9yZSBvciBhZnRlciB1bnNlbGVjdGFibGUgcGFydFxuICAgIGNvbnN0IHBhcnQgPSBwYXJ0c1twYXJ0SW5kZXhdO1xuICAgIGlmIChwYXJ0ICYmICFwYXJ0LmFjY2VwdHNDYXJldCkge1xuICAgICAgICBpZiAob2Zmc2V0ID09PSAwKSB7XG4gICAgICAgICAgICBub2RlSW5kZXggLT0gMTtcbiAgICAgICAgICAgIGNvbnN0IHByZXZQYXJ0ID0gcGFydHNbcGFydEluZGV4IC0gMV07XG4gICAgICAgICAgICAvLyBpZiB0aGUgcHJldmlvdXMgbm9kZSBpcyBhIGNhcmV0IG5vZGUsIGl0J3MgZW1wdHlcbiAgICAgICAgICAgIC8vIHNvIHRoZSBvZmZzZXQgY2FuIHN0YXkgYXQgMFxuICAgICAgICAgICAgLy8gb25seSB3aGVuIGl0J3Mgbm90LCB3ZSBuZWVkIHRvIHNldCB0aGUgb2Zmc2V0XG4gICAgICAgICAgICAvLyBhdCB0aGUgZW5kIG9mIHRoZSBub2RlXG4gICAgICAgICAgICBpZiAoIW5lZWRzQ2FyZXROb2RlQmVmb3JlKHBhcnQsIHByZXZQYXJ0KSkge1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IHByZXZQYXJ0LnRleHQubGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbm9kZUluZGV4ICs9IDE7XG4gICAgICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IG5vZGVJbmRleCwgb2Zmc2V0IH07XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQVFBLElBQUFBLE9BQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLE1BQUEsR0FBQUMsc0JBQUEsQ0FBQUYsT0FBQTtBQUdBLElBQUFHLE1BQUEsR0FBQUgsT0FBQTtBQVpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQVVPLFNBQVNJLFlBQVlBLENBQUNDLE1BQXNCLEVBQUVDLEtBQWtCLEVBQUVDLFNBQTRCLEVBQVE7RUFDekcsSUFBSUEsU0FBUyxZQUFZQyxjQUFLLEVBQUU7SUFDNUJDLHlCQUF5QixDQUFDSixNQUFNLEVBQUVDLEtBQUssRUFBRUMsU0FBUyxDQUFDO0VBQ3ZELENBQUMsTUFBTTtJQUNIRyxnQkFBZ0IsQ0FBQ0wsTUFBTSxFQUFFQyxLQUFLLEVBQUVDLFNBQVMsQ0FBQztFQUM5QztBQUNKO0FBRUEsU0FBU0UseUJBQXlCQSxDQUFDSixNQUFzQixFQUFFQyxLQUFrQixFQUFFSyxLQUFZLEVBQVE7RUFDL0YsTUFBTUMsR0FBRyxHQUFHQyxRQUFRLENBQUNDLFlBQVksQ0FBQyxDQUFFO0VBQ3BDRixHQUFHLENBQUNHLGVBQWUsQ0FBQyxDQUFDO0VBQ3JCLE1BQU1DLGNBQWMsR0FBR0gsUUFBUSxDQUFDSSxXQUFXLENBQUMsQ0FBQztFQUM3QyxNQUFNQyxLQUFLLEdBQUdDLDJCQUEyQixDQUFDZCxNQUFNLEVBQUVDLEtBQUssRUFBRUssS0FBSyxDQUFDTyxLQUFL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