UNPKG

matrix-react-sdk

Version:
246 lines (213 loc) 21.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.setSelection = setSelection; exports.setCaretPosition = setCaretPosition; exports.getLineAndNodePosition = getLineAndNodePosition; var _render = require("./render"); var _range = _interopRequireDefault(require("./range")); /* Copyright 2019 New Vector Ltd Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ function setSelection(editor /*: HTMLDivElement*/ , model /*: EditorModel*/ , selection /*: Range | IPosition*/ ) { if (selection instanceof _range.default) { setDocumentRangeSelection(editor, model, selection); } else { setCaretPosition(editor, model, selection); } } function setDocumentRangeSelection(editor /*: HTMLDivElement*/ , model /*: EditorModel*/ , range /*: 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 /*: HTMLDivElement*/ , model /*: EditorModel*/ , caretPosition /*: IPosition*/ ) { 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 /*: HTMLDivElement*/ , model /*: EditorModel*/ , position /*: IPosition*/ ) { 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 /*: EditorModel*/ , caretPosition /*: IPosition*/ ) { const { parts } = model; const partIndex = caretPosition.index; const lineResult = findNodeInLineForPart(parts, partIndex); const { lineIndex } = lineResult; let { nodeIndex } = lineResult; let { offset } = caretPosition; // 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 } = moveOutOfUneditablePart(parts, partIndex, nodeIndex, offset)); } return { lineIndex, nodeIndex, offset }; } function findNodeInLineForPart(parts /*: Part[]*/ , partIndex /*: number*/ ) { let lineIndex = 0; let nodeIndex = -1; let prevPart = null; // 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 === "newline") { lineIndex += 1; nodeIndex = -1; prevPart = null; } 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 moveOutOfUneditablePart 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 === "newline"; if ((0, _render.needsCaretNodeAfter)(part, isLastOfLine)) { nodeIndex += 1; } } prevPart = part; } } return { lineIndex, nodeIndex }; } function moveOutOfUneditablePart(parts /*: Part[]*/ , partIndex /*: number*/ , nodeIndex /*: number*/ , offset /*: number*/ ) { // move caret before or after uneditable part const part = parts[partIndex]; if (part && !part.canEdit) { 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lZGl0b3IvY2FyZXQudHMiXSwibmFtZXMiOlsic2V0U2VsZWN0aW9uIiwiZWRpdG9yIiwibW9kZWwiLCJzZWxlY3Rpb24iLCJSYW5nZSIsInNldERvY3VtZW50UmFuZ2VTZWxlY3Rpb24iLCJzZXRDYXJldFBvc2l0aW9uIiwicmFuZ2UiLCJzZWwiLCJkb2N1bWVudCIsImdldFNlbGVjdGlvbiIsInJlbW92ZUFsbFJhbmdlcyIsInNlbGVjdGlvblJhbmdlIiwiY3JlYXRlUmFuZ2UiLCJzdGFydCIsImdldE5vZGVBbmRPZmZzZXRGb3JQb3NpdGlvbiIsInNldFN0YXJ0Iiwibm9kZSIsIm9mZnNldCIsImVuZCIsInNldEVuZCIsImFkZFJhbmdlIiwiY2FyZXRQb3NpdGlvbiIsImNvbGxhcHNlIiwicmFuZ2VDb3VudCIsImV4aXN0aW5nUmFuZ2UiLCJnZXRSYW5nZUF0Iiwic3RhcnRDb250YWluZXIiLCJzdGFydE9mZnNldCIsImNvbGxhcHNlZCIsInBvc2l0aW9uIiwibGluZUluZGV4Iiwibm9kZUluZGV4IiwiZ2V0TGluZUFuZE5vZGVQb3NpdGlvbiIsImxpbmVOb2RlIiwiY2hpbGROb2RlcyIsImZvY3VzTm9kZSIsIm5vZGVUeXBlIiwiTm9kZSIsIkVMRU1FTlRfTk9ERSIsImZpcnN0Q2hpbGQiLCJwYXJ0cyIsInBhcnRJbmRleCIsImluZGV4IiwibGluZVJlc3VsdCIsImZpbmROb2RlSW5MaW5lRm9yUGFydCIsIm1vdmVPdXRPZlVuZWRpdGFibGVQYXJ0IiwicHJldlBhcnQiLCJpIiwicGFydCIsInR5cGUiLCJuZXh0UGFydCIsImlzTGFzdE9mTGluZSIsImNhbkVkaXQiLCJ0ZXh0IiwibGVuZ3RoIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQWlCQTs7QUFDQTs7QUFsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFVTyxTQUFTQSxZQUFU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USxHQUFHRSxJQUFYO0FBQ0g7QUFDSjs7QUFFRCxTQUFPO0FBQUNsQixJQUFBQSxTQUFEO0FBQVlDLElBQUFBO0FBQVosR0FBUDtBQUNIOztBQUVELFNBQVNjLHVCQUFULENBQWlDTDtBQUFqQztBQUFBLEVBQWdEQztBQUFoRDtBQUFBLEVBQW1FVjtBQUFuRTtBQUFBLEVBQXNGZDtBQUF0RjtBQUFBLEVBQXNHO0FBQ2xHO0FBQ0EsUUFBTStCLElBQUksR0FBR1IsS0FBSyxDQUFDQyxTQUFELENBQWxCOztBQUNBLE1BQUlPLElBQUksSUFBSSxDQUFDQSxJQUFJLENBQUNJLE9BQWxCLEVBQTJCO0FBQ3ZCLFFBQUluQyxNQUFNLEtBQUssQ0FBZixFQUFrQjtBQUNkYyxNQUFBQSxTQUFTLElBQUksQ0FBYjtBQUNBLFlBQU1lLFFBQVEsR0FBR04sS0FBSyxDQUFDQyxTQUFTLEdBQUcsQ0FBYixDQUF0QixDQUZjLENBR2Q7QUFDQTtBQUNBO0FBQ0E7O0FBQ0EsVUFBSSxDQUFDLGtDQUFxQk8sSUFBckIsRUFBMkJGLFFBQTNCLENBQUwsRUFBMkM7QUFDdkM3QixRQUFBQSxNQUFNLEdBQUc2QixRQUFRLENBQUNPLElBQVQsQ0FBY0MsTUFBdkI7QUFDSDtBQUNKLEtBVkQsTUFVTztBQUNIdkIsTUFBQUEsU0FBUyxJQUFJLENBQWI7QUFDQWQsTUFBQUEsTUFBTSxHQUFHLENBQVQ7QUFDSDtBQUNKOztBQUNELFNBQU87QUFBQ2MsSUFBQUEsU0FBRDtBQUFZZCxJQUFBQTtBQUFaLEdBQVA7QUFDSCIsInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAxOSBOZXcgVmVjdG9yIEx0ZFxuQ29weXJpZ2h0IDIwMTkgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4qL1xuXG5pbXBvcnQge25lZWRzQ2FyZXROb2RlQmVmb3JlLCBuZWVkc0NhcmV0Tm9kZUFmdGVyfSBmcm9tIFwiLi9yZW5kZXJcIjtcbmltcG9ydCBSYW5nZSBmcm9tIFwiLi9yYW5nZVwiO1xuaW1wb3J0IEVkaXRvck1vZGVsIGZyb20gXCIuL21vZGVsXCI7XG5pbXBvcnQgRG9jdW1lbnRQb3NpdGlvbiwge0lQb3NpdGlvbn0gZnJvbSBcIi4vcG9zaXRpb25cIjtcbmltcG9ydCB7UGFydH0gZnJvbSBcIi4vcGFydHNcIjtcblxuZXhwb3J0IHR5cGUgQ2FyZXQgPSBSYW5nZSB8IERvY3VtZW50UG9zaXRpb247XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRTZWxlY3Rpb24oZWRpdG9yOiBIVE1MRGl2RWxlbWVudCwgbW9kZWw6IEVkaXRvck1vZGVsLCBzZWxlY3Rpb246IFJhbmdlIHwgSVBvc2l0aW9uKSB7XG4gICAgaWYgKHNlbGVjdGlvbiBpbnN0YW5jZW9mIFJhbmdlKSB7XG4gICAgICAgIHNldERvY3VtZW50UmFuZ2VTZWxlY3Rpb24oZWRpdG9yLCBtb2RlbCwgc2VsZWN0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBzZXRDYXJldFBvc2l0aW9uKGVkaXRvciwgbW9kZWwsIHNlbGVjdGlvbik7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBzZXREb2N1bWVudFJhbmdlU2VsZWN0aW9uKGVkaXRvcjogSFRNTERpdkVsZW1lbnQsIG1vZGVsOiBFZGl0b3JNb2RlbCwgcmFuZ2U6IFJhbmdlKSB7XG4gICAgY29uc3Qgc2VsID0gZG9jdW1lbnQuZ2V0U2VsZWN0aW9uKCk7XG4gICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgIGNvbnN0IHNlbGVjdGlvblJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICBjb25zdCBzdGFydCA9IGdldE5vZGVBbmRPZmZzZXRGb3JQb3NpdGlvbihlZGl0b3IsIG1vZGVsLCByYW5nZS5zdGFydCk7XG4gICAgc2VsZWN0aW9uUmFuZ2Uuc2V0U3RhcnQoc3RhcnQubm9kZSwgc3RhcnQub2Zmc2V0KTtcbiAgICBjb25zdCBlbmQgPSBnZXROb2RlQW5kT2Zmc2V0Rm9yUG9zaXRpb24oZWRpdG9yLCBtb2RlbCwgcmFuZ2UuZW5kKTtcbiAgICBzZWxlY3Rpb25SYW5nZS5zZXRFbmQoZW5kLm5vZGUsIGVuZC5vZmZzZXQpO1xuICAgIHNlbC5hZGRSYW5nZShzZWxlY3Rpb25SYW5nZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRDYXJldFBvc2l0aW9uKGVkaXRvcjogSFRNTERpdkVsZW1lbnQsIG1vZGVsOiBFZGl0b3JNb2RlbCwgY2FyZXRQb3NpdGlvbjogSVBvc2l0aW9uKSB7XG4gICAgY29uc3QgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIGNvbnN0IHtub2RlLCBvZmZzZXR9ID0gZ2V0Tm9kZUFuZE9mZnNldEZvclBvc2l0aW9uKGVkaXRvciwgbW9kZWwsIGNhcmV0UG9zaXRpb24pO1xuICAgIHJhbmdlLnNldFN0YXJ0KG5vZGUsIG9mZnNldCk7XG4gICAgcmFuZ2UuY29sbGFwc2UodHJ1ZSk7XG5cbiAgICBjb25zdCBzZWwgPSBkb2N1bWVudC5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoc2VsLnJhbmdlQ291bnQgPT09IDEpIHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdSYW5nZSA9IHNlbC5nZXRSYW5nZUF0KDApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICBleGlzdGluZ1JhbmdlLnN0YXJ0Q29udGFpbmVyID09PSByYW5nZS5zdGFydENvbnRhaW5lciAmJlxuICAgICAgICAgICAgZXhpc3RpbmdSYW5nZS5zdGFydE9mZnNldCA9PT0gcmFuZ2Uuc3RhcnRPZmZzZXQgJiZcbiAgICAgICAgICAgIGV4aXN0aW5nUmFuZ2UuY29sbGFwc2VkID09PSByYW5nZS5jb2xsYXBzZWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyBJZiB0aGUgc2VsZWN0aW9uIG1hdGNoZXMsIGl0J3MgaW1wb3J0YW50IHRvIGxlYXZlIGl0IGFsb25lLlxuICAgICAgICAgICAgLy8gUmVjcmVhdGluZyB0aGUgc2VsZWN0aW9uIHN0YXRlIGluIGF0IGxlYXN0IENocm9tZSBjYW4gY2F1c2VcbiAgICAgICAgICAgIC8vIHN0cmFuZ2Ugc2lkZSBlZmZlY3RzLCBsaWtlIHRvdWNoIGJhciBmbGlja2VyaW5nIG9uIGV2ZXJ5IGtleS5cbiAgICAgICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vdmVjdG9yLWltL2VsZW1lbnQtd2ViL2lzc3Vlcy85Mjk5XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgIHNlbC5hZGRSYW5nZShyYW5nZSk7XG59XG5cbmZ1bmN0aW9uIGdldE5vZGVBbmRPZmZzZXRGb3JQb3NpdGlvbihlZGl0b3I6IEhUTUxEaXZFbGVtZW50LCBtb2RlbDogRWRpdG9yTW9kZWwsIHBvc2l0aW9uOiBJUG9zaXRpb24pIHtcbiAgICBjb25zdCB7b2Zmc2V0LCBsaW5lSW5kZXgsIG5vZGVJbmRleH0gPSBnZXRMaW5lQW5kTm9kZVBvc2l0aW9uKG1vZGVsLCBwb3NpdGlvbik7XG4gICAgY29uc3QgbGluZU5vZGUgPSBlZGl0b3IuY2hpbGROb2Rlc1tsaW5lSW5kZXhdO1xuXG4gICAgbGV0IGZvY3VzTm9kZTtcbiAgICAvLyBlbXB0eSBsaW5lIHdpdGgganVzdCBhIDxicj5cbiAgICBpZiAobm9kZUluZGV4ID09PSAtMSkge1xuICAgICAgICBmb2N1c05vZGUgPSBsaW5lTm9kZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBmb2N1c05vZGUgPSBsaW5lTm9kZS5jaGlsZE5vZGVzW25vZGVJbmRleF07XG4gICAgICAgIC8vIG1ha2Ugc3VyZSB3ZSBoYXZlIGEgdGV4dCBub2RlXG4gICAgICAgIGlmIChmb2N1c05vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmIGZvY3VzTm9kZS5maXJzdENoaWxkKSB7XG4gICAgICAgICAgICBmb2N1c05vZGUgPSBmb2N1c05vZGUuZmlyc3RDaGlsZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge25vZGU6IGZvY3VzTm9kZSwgb2Zmc2V0fTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldExpbmVBbmROb2RlUG9zaXRpb24obW9kZWw6IEVkaXRvck1vZGVsLCBjYXJldFBvc2l0aW9uOiBJUG9zaXRpb24pIHtcbiAgICBjb25zdCB7cGFydHN9ID0gbW9kZWw7XG4gICAgY29uc3QgcGFydEluZGV4ID0gY2FyZXRQb3NpdGlvbi5pbmRleDtcbiAgICBjb25zdCBsaW5lUmVzdWx0ID0gZmluZE5vZGVJbkxpbmVGb3JQYXJ0KHBhcnRzLCBwYXJ0SW5kZXgpO1xuICAgIGNvbnN0IHtsaW5lSW5kZXh9ID0gbGluZVJlc3VsdDtcbiAgICBsZXQge25vZGVJbmRleH0gPSBsaW5lUmVzdWx0O1xuICAgIGxldCB7b2Zmc2V0fSA9IGNhcmV0UG9zaXRpb247XG4gICAgLy8gd2UncmUgYXQgYW4gZW1wdHkgbGluZSBiZXR3ZWVuIGEgbmV3bGluZSBwYXJ0XG4gICAgLy8gYW5kIGFub3RoZXIgbmV3bGluZSBwYXJ0IG9yIGVuZC9zdGFydCBvZiBwYXJ0cy5cbiAgICAvLyBzZXQgb2Zmc2V0IHRvIDAgc28gaXQgZ2V0cyBzZXQgdG8gdGhlIDxicj4gaW5zaWRlIHRoZSBsaW5lIGNvbnRhaW5lclxuICAgIGlmIChub2RlSW5kZXggPT09IC0xKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gbW92ZSBjYXJldCBvdXQgb2YgdW5lZGl0YWJsZSBwYXJ0IChpbnRvIGNhcmV0IG5vZGUsIG9yIGVtcHR5IGxpbmUgYnIpIGlmIG5lZWRlZFxuICAgICAgICAoe25vZGVJbmRleCwgb2Zmc2V0fSA9IG1vdmVPdXRPZlVuZWRpdGFibGVQYXJ0KHBhcnRzLCBwYXJ0SW5kZXgsIG5vZGVJbmRleCwgb2Zmc2V0KSk7XG4gICAgfVxuICAgIHJldHVybiB7bGluZUluZGV4LCBub2RlSW5kZXgsIG9mZnNldH07XG59XG5cbmZ1bmN0aW9uIGZpbmROb2RlSW5MaW5lRm9yUGFydChwYXJ0czogUGFydFtdLCBwYXJ0SW5kZXg6IG51bWJlcikge1xuICAgIGxldCBsaW5lSW5kZXggPSAwO1xuICAgIGxldCBub2RlSW5kZXggPSAtMTtcblxuICAgIGxldCBwcmV2UGFydCA9IG51bGw7XG4gICAgLy8gZ28gdGhyb3VnaCB0byBwYXJ0cyB1cCB0aWxsIChhbmQgaW5jbHVkaW5nKSB0aGUgaW5kZXhcbiAgICAvLyB0byBmaW5kIG5ld2xpbmUgcGFydHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8PSBwYXJ0SW5kZXg7ICsraSkge1xuICAgICAgICBjb25zdCBwYXJ0ID0gcGFydHNbaV07XG4gICAgICAgIGlmIChwYXJ0LnR5cGUgPT09IFwibmV3bGluZVwiKSB7XG4gICAgICAgICAgICBsaW5lSW5kZXggKz0gMTtcbiAgICAgICAgICAgIG5vZGVJbmRleCA9IC0xO1xuICAgICAgICAgICAgcHJldlBhcnQgPSBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbm9kZUluZGV4ICs9IDE7XG4gICAgICAgICAgICBpZiAobmVlZHNDYXJldE5vZGVCZWZvcmUocGFydCwgcHJldlBhcnQpKSB7XG4gICAgICAgICAgICAgICAgbm9kZUluZGV4ICs9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBvbmx5IGp1bXAgb3ZlciBjYXJldCBub2RlIGlmIHdlJ3JlIG5vdCBhdCBvdXIgZGVzdGluYXRpb24gbm9kZSBhbHJlYWR5LFxuICAgICAgICAgICAgLy8gYXMgd2UnbGwgYXNzdW1lIGluIG1vdmVPdXRPZlVuZWRpdGFibGVQYXJ0IHRoYXQgbm9kZUluZGV4XG4gICAgICAgICAgICAvLyByZWZlcnMgdG8gdGhlIG5vZGUgIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHBhcnQsXG4gICAgICAgICAgICAvLyBhbmQgbm90IGFuIGFkamFjZW50IGNhcmV0IG5vZGVcbiAgICAgICAgICAgIGlmIChpIDwgcGFydEluZGV4KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV4dFBhcnQgPSBwYXJ0c1tpICsgMV07XG4gICAgICAgICAgICAgICAgY29uc3QgaXNMYXN0T2ZMaW5lID0gIW5leHRQYXJ0IHx8IG5leHRQYXJ0LnR5cGUgPT09IFwibmV3bGluZVwiO1xuICAgICAgICAgICAgICAgIGlmIChuZWVkc0NhcmV0Tm9kZUFmdGVyKHBhcnQsIGlzTGFzdE9mTGluZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZUluZGV4ICs9IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcHJldlBhcnQgPSBwYXJ0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtsaW5lSW5kZXgsIG5vZGVJbmRleH07XG59XG5cbmZ1bmN0aW9uIG1vdmVPdXRPZlVuZWRpdGFibGVQYXJ0KHBhcnRzOiBQYXJ0W10sIHBhcnRJbmRleDogbnVtYmVyLCBub2RlSW5kZXg6IG51bWJlciwgb2Zmc2V0OiBudW1iZXIpIHtcbiAgICAvLyBtb3ZlIGNhcmV0IGJlZm9yZSBvciBhZnRlciB1bmVkaXRhYmxlIHBhcnRcbiAgICBjb25zdCBwYXJ0ID0gcGFydHNbcGFydEluZGV4XTtcbiAgICBpZiAocGFydCAmJiAhcGFydC5jYW5FZGl0KSB7XG4gICAgICAgIGlmIChvZmZzZXQgPT09IDApIHtcbiAgICAgICAgICAgIG5vZGVJbmRleCAtPSAxO1xuICAgICAgICAgICAgY29uc3QgcHJldlBhcnQgPSBwYXJ0c1twYXJ0SW5kZXggLSAxXTtcbiAgICAgICAgICAgIC8vIGlmIHRoZSBwcmV2aW91cyBub2RlIGlzIGEgY2FyZXQgbm9kZSwgaXQncyBlbXB0eVxuICAgICAgICAgICAgLy8gc28gdGhlIG9mZnNldCBjYW4gc3RheSBhdCAwXG4gICAgICAgICAgICAvLyBvbmx5IHdoZW4gaXQncyBub3QsIHdlIG5lZWQgdG8gc2V0IHRoZSBvZmZzZXRcbiAgICAgICAgICAgIC8vIGF0IHRoZSBlbmQgb2YgdGhlIG5vZGVcbiAgICAgICAgICAgIGlmICghbmVlZHNDYXJldE5vZGVCZWZvcmUocGFydCwgcHJldlBhcnQpKSB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gcHJldlBhcnQudGV4dC5sZW5ndGg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBub2RlSW5kZXggKz0gMTtcbiAgICAgICAgICAgIG9mZnNldCA9IDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtub2RlSW5kZXgsIG9mZnNldH07XG59XG4iXX0=