matrix-react-sdk
Version:
SDK for matrix.org using React
246 lines (213 loc) • 21.4 kB
JavaScript
;
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=