qmk_firmware/assets/chunks/VPLocalSearchBox.BqX9KCf2.js

5148 lines
186 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Y as __vitePreload, j as ref, x as watch, an as unrefElement, ao as tryOnScopeDispose, d as defineComponent, G as shallowRef, ap as computedAsync, h as computed, aq as useSessionStorage, ar as useLocalStorage, y as watchEffect, as as watchDebounced, k as onMounted, S as nextTick, R as onKeyStroke, a6 as useRouter, at as useEventListener, Z as useScrollLock, V as inBrowser, au as onBeforeUnmount, o as openBlock, b as createBlock, l as createBaseVNode, a2 as withModifiers, m as unref, av as withDirectives, aw as vModelText, ax as isRef, c as createElementBlock, n as normalizeClass, e as createCommentVNode, E as renderList, F as Fragment, a as createTextVNode, t as toDisplayString, ay as Teleport, p as pushScopeId, q as popScopeId, az as markRaw, aA as createApp, ac as dataSymbol, ai as pathToFile, aB as escapeRegExp, _ as _export_sfc } from "./framework.DyMmIvSC.js";
import { u as useData, c as createSearchTranslate } from "./theme.DAZguuVX.js";
const localSearchIndex = { "root": () => __vitePreload(() => import("./@localSearchIndexroot.IZbmEDha.js"), true ? [] : void 0) };
/*!
* tabbable 6.2.0
* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
*/
var candidateSelectors = ["input:not([inert])", "select:not([inert])", "textarea:not([inert])", "a[href]:not([inert])", "button:not([inert])", "[tabindex]:not(slot):not([inert])", "audio[controls]:not([inert])", "video[controls]:not([inert])", '[contenteditable]:not([contenteditable="false"]):not([inert])', "details>summary:first-of-type:not([inert])", "details:not([inert])"];
var candidateSelector = /* @__PURE__ */ candidateSelectors.join(",");
var NoElement = typeof Element === "undefined";
var matches = NoElement ? function() {
} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
var getRootNode = !NoElement && Element.prototype.getRootNode ? function(element) {
var _element$getRootNode;
return element === null || element === void 0 ? void 0 : (_element$getRootNode = element.getRootNode) === null || _element$getRootNode === void 0 ? void 0 : _element$getRootNode.call(element);
} : function(element) {
return element === null || element === void 0 ? void 0 : element.ownerDocument;
};
var isInert = function isInert2(node, lookUp) {
var _node$getAttribute;
if (lookUp === void 0) {
lookUp = true;
}
var inertAtt = node === null || node === void 0 ? void 0 : (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.call(node, "inert");
var inert = inertAtt === "" || inertAtt === "true";
var result = inert || lookUp && node && isInert2(node.parentNode);
return result;
};
var isContentEditable = function isContentEditable2(node) {
var _node$getAttribute2;
var attValue = node === null || node === void 0 ? void 0 : (_node$getAttribute2 = node.getAttribute) === null || _node$getAttribute2 === void 0 ? void 0 : _node$getAttribute2.call(node, "contenteditable");
return attValue === "" || attValue === "true";
};
var getCandidates = function getCandidates2(el, includeContainer, filter) {
if (isInert(el)) {
return [];
}
var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector));
if (includeContainer && matches.call(el, candidateSelector)) {
candidates.unshift(el);
}
candidates = candidates.filter(filter);
return candidates;
};
var getCandidatesIteratively = function getCandidatesIteratively2(elements, includeContainer, options) {
var candidates = [];
var elementsToCheck = Array.from(elements);
while (elementsToCheck.length) {
var element = elementsToCheck.shift();
if (isInert(element, false)) {
continue;
}
if (element.tagName === "SLOT") {
var assigned = element.assignedElements();
var content = assigned.length ? assigned : element.children;
var nestedCandidates = getCandidatesIteratively2(content, true, options);
if (options.flatten) {
candidates.push.apply(candidates, nestedCandidates);
} else {
candidates.push({
scopeParent: element,
candidates: nestedCandidates
});
}
} else {
var validCandidate = matches.call(element, candidateSelector);
if (validCandidate && options.filter(element) && (includeContainer || !elements.includes(element))) {
candidates.push(element);
}
var shadowRoot = element.shadowRoot || // check for an undisclosed shadow
typeof options.getShadowRoot === "function" && options.getShadowRoot(element);
var validShadowRoot = !isInert(shadowRoot, false) && (!options.shadowRootFilter || options.shadowRootFilter(element));
if (shadowRoot && validShadowRoot) {
var _nestedCandidates = getCandidatesIteratively2(shadowRoot === true ? element.children : shadowRoot.children, true, options);
if (options.flatten) {
candidates.push.apply(candidates, _nestedCandidates);
} else {
candidates.push({
scopeParent: element,
candidates: _nestedCandidates
});
}
} else {
elementsToCheck.unshift.apply(elementsToCheck, element.children);
}
}
}
return candidates;
};
var hasTabIndex = function hasTabIndex2(node) {
return !isNaN(parseInt(node.getAttribute("tabindex"), 10));
};
var getTabIndex = function getTabIndex2(node) {
if (!node) {
throw new Error("No node provided");
}
if (node.tabIndex < 0) {
if ((/^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && !hasTabIndex(node)) {
return 0;
}
}
return node.tabIndex;
};
var getSortOrderTabIndex = function getSortOrderTabIndex2(node, isScope) {
var tabIndex = getTabIndex(node);
if (tabIndex < 0 && isScope && !hasTabIndex(node)) {
return 0;
}
return tabIndex;
};
var sortOrderedTabbables = function sortOrderedTabbables2(a, b) {
return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex;
};
var isInput = function isInput2(node) {
return node.tagName === "INPUT";
};
var isHiddenInput = function isHiddenInput2(node) {
return isInput(node) && node.type === "hidden";
};
var isDetailsWithSummary = function isDetailsWithSummary2(node) {
var r = node.tagName === "DETAILS" && Array.prototype.slice.apply(node.children).some(function(child) {
return child.tagName === "SUMMARY";
});
return r;
};
var getCheckedRadio = function getCheckedRadio2(nodes, form) {
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].checked && nodes[i].form === form) {
return nodes[i];
}
}
};
var isTabbableRadio = function isTabbableRadio2(node) {
if (!node.name) {
return true;
}
var radioScope = node.form || getRootNode(node);
var queryRadios = function queryRadios2(name) {
return radioScope.querySelectorAll('input[type="radio"][name="' + name + '"]');
};
var radioSet;
if (typeof window !== "undefined" && typeof window.CSS !== "undefined" && typeof window.CSS.escape === "function") {
radioSet = queryRadios(window.CSS.escape(node.name));
} else {
try {
radioSet = queryRadios(node.name);
} catch (err) {
console.error("Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s", err.message);
return false;
}
}
var checked = getCheckedRadio(radioSet, node.form);
return !checked || checked === node;
};
var isRadio = function isRadio2(node) {
return isInput(node) && node.type === "radio";
};
var isNonTabbableRadio = function isNonTabbableRadio2(node) {
return isRadio(node) && !isTabbableRadio(node);
};
var isNodeAttached = function isNodeAttached2(node) {
var _nodeRoot;
var nodeRoot = node && getRootNode(node);
var nodeRootHost = (_nodeRoot = nodeRoot) === null || _nodeRoot === void 0 ? void 0 : _nodeRoot.host;
var attached = false;
if (nodeRoot && nodeRoot !== node) {
var _nodeRootHost, _nodeRootHost$ownerDo, _node$ownerDocument;
attached = !!((_nodeRootHost = nodeRootHost) !== null && _nodeRootHost !== void 0 && (_nodeRootHost$ownerDo = _nodeRootHost.ownerDocument) !== null && _nodeRootHost$ownerDo !== void 0 && _nodeRootHost$ownerDo.contains(nodeRootHost) || node !== null && node !== void 0 && (_node$ownerDocument = node.ownerDocument) !== null && _node$ownerDocument !== void 0 && _node$ownerDocument.contains(node));
while (!attached && nodeRootHost) {
var _nodeRoot2, _nodeRootHost2, _nodeRootHost2$ownerD;
nodeRoot = getRootNode(nodeRootHost);
nodeRootHost = (_nodeRoot2 = nodeRoot) === null || _nodeRoot2 === void 0 ? void 0 : _nodeRoot2.host;
attached = !!((_nodeRootHost2 = nodeRootHost) !== null && _nodeRootHost2 !== void 0 && (_nodeRootHost2$ownerD = _nodeRootHost2.ownerDocument) !== null && _nodeRootHost2$ownerD !== void 0 && _nodeRootHost2$ownerD.contains(nodeRootHost));
}
}
return attached;
};
var isZeroArea = function isZeroArea2(node) {
var _node$getBoundingClie = node.getBoundingClientRect(), width = _node$getBoundingClie.width, height = _node$getBoundingClie.height;
return width === 0 && height === 0;
};
var isHidden = function isHidden2(node, _ref) {
var displayCheck = _ref.displayCheck, getShadowRoot = _ref.getShadowRoot;
if (getComputedStyle(node).visibility === "hidden") {
return true;
}
var isDirectSummary = matches.call(node, "details>summary:first-of-type");
var nodeUnderDetails = isDirectSummary ? node.parentElement : node;
if (matches.call(nodeUnderDetails, "details:not([open]) *")) {
return true;
}
if (!displayCheck || displayCheck === "full" || displayCheck === "legacy-full") {
if (typeof getShadowRoot === "function") {
var originalNode = node;
while (node) {
var parentElement = node.parentElement;
var rootNode = getRootNode(node);
if (parentElement && !parentElement.shadowRoot && getShadowRoot(parentElement) === true) {
return isZeroArea(node);
} else if (node.assignedSlot) {
node = node.assignedSlot;
} else if (!parentElement && rootNode !== node.ownerDocument) {
node = rootNode.host;
} else {
node = parentElement;
}
}
node = originalNode;
}
if (isNodeAttached(node)) {
return !node.getClientRects().length;
}
if (displayCheck !== "legacy-full") {
return true;
}
} else if (displayCheck === "non-zero-area") {
return isZeroArea(node);
}
return false;
};
var isDisabledFromFieldset = function isDisabledFromFieldset2(node) {
if (/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(node.tagName)) {
var parentNode = node.parentElement;
while (parentNode) {
if (parentNode.tagName === "FIELDSET" && parentNode.disabled) {
for (var i = 0; i < parentNode.children.length; i++) {
var child = parentNode.children.item(i);
if (child.tagName === "LEGEND") {
return matches.call(parentNode, "fieldset[disabled] *") ? true : !child.contains(node);
}
}
return true;
}
parentNode = parentNode.parentElement;
}
}
return false;
};
var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable2(options, node) {
if (node.disabled || // we must do an inert look up to filter out any elements inside an inert ancestor
// because we're limited in the type of selectors we can use in JSDom (see related
// note related to `candidateSelectors`)
isInert(node) || isHiddenInput(node) || isHidden(node, options) || // For a details element with a summary, the summary element gets the focus
isDetailsWithSummary(node) || isDisabledFromFieldset(node)) {
return false;
}
return true;
};
var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable2(options, node) {
if (isNonTabbableRadio(node) || getTabIndex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
return false;
}
return true;
};
var isValidShadowRootTabbable = function isValidShadowRootTabbable2(shadowHostNode) {
var tabIndex = parseInt(shadowHostNode.getAttribute("tabindex"), 10);
if (isNaN(tabIndex) || tabIndex >= 0) {
return true;
}
return false;
};
var sortByOrder = function sortByOrder2(candidates) {
var regularTabbables = [];
var orderedTabbables = [];
candidates.forEach(function(item, i) {
var isScope = !!item.scopeParent;
var element = isScope ? item.scopeParent : item;
var candidateTabindex = getSortOrderTabIndex(element, isScope);
var elements = isScope ? sortByOrder2(item.candidates) : element;
if (candidateTabindex === 0) {
isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element);
} else {
orderedTabbables.push({
documentOrder: i,
tabIndex: candidateTabindex,
item,
isScope,
content: elements
});
}
});
return orderedTabbables.sort(sortOrderedTabbables).reduce(function(acc, sortable) {
sortable.isScope ? acc.push.apply(acc, sortable.content) : acc.push(sortable.content);
return acc;
}, []).concat(regularTabbables);
};
var tabbable = function tabbable2(container, options) {
options = options || {};
var candidates;
if (options.getShadowRoot) {
candidates = getCandidatesIteratively([container], options.includeContainer, {
filter: isNodeMatchingSelectorTabbable.bind(null, options),
flatten: false,
getShadowRoot: options.getShadowRoot,
shadowRootFilter: isValidShadowRootTabbable
});
} else {
candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
}
return sortByOrder(candidates);
};
var focusable = function focusable2(container, options) {
options = options || {};
var candidates;
if (options.getShadowRoot) {
candidates = getCandidatesIteratively([container], options.includeContainer, {
filter: isNodeMatchingSelectorFocusable.bind(null, options),
flatten: true,
getShadowRoot: options.getShadowRoot
});
} else {
candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorFocusable.bind(null, options));
}
return candidates;
};
var isTabbable = function isTabbable2(node, options) {
options = options || {};
if (!node) {
throw new Error("No node provided");
}
if (matches.call(node, candidateSelector) === false) {
return false;
}
return isNodeMatchingSelectorTabbable(options, node);
};
var focusableCandidateSelector = /* @__PURE__ */ candidateSelectors.concat("iframe").join(",");
var isFocusable = function isFocusable2(node, options) {
options = options || {};
if (!node) {
throw new Error("No node provided");
}
if (matches.call(node, focusableCandidateSelector) === false) {
return false;
}
return isNodeMatchingSelectorFocusable(options, node);
};
/*!
* focus-trap 7.5.4
* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
*/
function ownKeys(e, r) {
var t = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r && (o = o.filter(function(r2) {
return Object.getOwnPropertyDescriptor(e, r2).enumerable;
})), t.push.apply(t, o);
}
return t;
}
function _objectSpread2(e) {
for (var r = 1; r < arguments.length; r++) {
var t = null != arguments[r] ? arguments[r] : {};
r % 2 ? ownKeys(Object(t), true).forEach(function(r2) {
_defineProperty(e, r2, t[r2]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r2) {
Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2));
});
}
return e;
}
function _defineProperty(obj, key, value) {
key = _toPropertyKey(key);
if (key in obj) {
Object.defineProperty(obj, key, {
value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _toPrimitive(input, hint) {
if (typeof input !== "object" || input === null)
return input;
var prim = input[Symbol.toPrimitive];
if (prim !== void 0) {
var res = prim.call(input, hint || "default");
if (typeof res !== "object")
return res;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return (hint === "string" ? String : Number)(input);
}
function _toPropertyKey(arg) {
var key = _toPrimitive(arg, "string");
return typeof key === "symbol" ? key : String(key);
}
var activeFocusTraps = {
activateTrap: function activateTrap(trapStack, trap) {
if (trapStack.length > 0) {
var activeTrap = trapStack[trapStack.length - 1];
if (activeTrap !== trap) {
activeTrap.pause();
}
}
var trapIndex = trapStack.indexOf(trap);
if (trapIndex === -1) {
trapStack.push(trap);
} else {
trapStack.splice(trapIndex, 1);
trapStack.push(trap);
}
},
deactivateTrap: function deactivateTrap(trapStack, trap) {
var trapIndex = trapStack.indexOf(trap);
if (trapIndex !== -1) {
trapStack.splice(trapIndex, 1);
}
if (trapStack.length > 0) {
trapStack[trapStack.length - 1].unpause();
}
}
};
var isSelectableInput = function isSelectableInput2(node) {
return node.tagName && node.tagName.toLowerCase() === "input" && typeof node.select === "function";
};
var isEscapeEvent = function isEscapeEvent2(e) {
return (e === null || e === void 0 ? void 0 : e.key) === "Escape" || (e === null || e === void 0 ? void 0 : e.key) === "Esc" || (e === null || e === void 0 ? void 0 : e.keyCode) === 27;
};
var isTabEvent = function isTabEvent2(e) {
return (e === null || e === void 0 ? void 0 : e.key) === "Tab" || (e === null || e === void 0 ? void 0 : e.keyCode) === 9;
};
var isKeyForward = function isKeyForward2(e) {
return isTabEvent(e) && !e.shiftKey;
};
var isKeyBackward = function isKeyBackward2(e) {
return isTabEvent(e) && e.shiftKey;
};
var delay = function delay2(fn) {
return setTimeout(fn, 0);
};
var findIndex = function findIndex2(arr, fn) {
var idx = -1;
arr.every(function(value, i) {
if (fn(value)) {
idx = i;
return false;
}
return true;
});
return idx;
};
var valueOrHandler = function valueOrHandler2(value) {
for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
params[_key - 1] = arguments[_key];
}
return typeof value === "function" ? value.apply(void 0, params) : value;
};
var getActualTarget = function getActualTarget2(event) {
return event.target.shadowRoot && typeof event.composedPath === "function" ? event.composedPath()[0] : event.target;
};
var internalTrapStack = [];
var createFocusTrap = function createFocusTrap2(elements, userOptions) {
var doc = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.document) || document;
var trapStack = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.trapStack) || internalTrapStack;
var config = _objectSpread2({
returnFocusOnDeactivate: true,
escapeDeactivates: true,
delayInitialFocus: true,
isKeyForward,
isKeyBackward
}, userOptions);
var state = {
// containers given to createFocusTrap()
// @type {Array<HTMLElement>}
containers: [],
// list of objects identifying tabbable nodes in `containers` in the trap
// NOTE: it's possible that a group has no tabbable nodes if nodes get removed while the trap
// is active, but the trap should never get to a state where there isn't at least one group
// with at least one tabbable node in it (that would lead to an error condition that would
// result in an error being thrown)
// @type {Array<{
// container: HTMLElement,
// tabbableNodes: Array<HTMLElement>, // empty if none
// focusableNodes: Array<HTMLElement>, // empty if none
// posTabIndexesFound: boolean,
// firstTabbableNode: HTMLElement|undefined,
// lastTabbableNode: HTMLElement|undefined,
// firstDomTabbableNode: HTMLElement|undefined,
// lastDomTabbableNode: HTMLElement|undefined,
// nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined
// }>}
containerGroups: [],
// same order/length as `containers` list
// references to objects in `containerGroups`, but only those that actually have
// tabbable nodes in them
// NOTE: same order as `containers` and `containerGroups`, but __not necessarily__
// the same length
tabbableGroups: [],
nodeFocusedBeforeActivation: null,
mostRecentlyFocusedNode: null,
active: false,
paused: false,
// timer ID for when delayInitialFocus is true and initial focus in this trap
// has been delayed during activation
delayInitialFocusTimer: void 0,
// the most recent KeyboardEvent for the configured nav key (typically [SHIFT+]TAB), if any
recentNavEvent: void 0
};
var trap;
var getOption = function getOption2(configOverrideOptions, optionName, configOptionName) {
return configOverrideOptions && configOverrideOptions[optionName] !== void 0 ? configOverrideOptions[optionName] : config[configOptionName || optionName];
};
var findContainerIndex = function findContainerIndex2(element, event) {
var composedPath = typeof (event === null || event === void 0 ? void 0 : event.composedPath) === "function" ? event.composedPath() : void 0;
return state.containerGroups.findIndex(function(_ref) {
var container = _ref.container, tabbableNodes = _ref.tabbableNodes;
return container.contains(element) || // fall back to explicit tabbable search which will take into consideration any
// web components if the `tabbableOptions.getShadowRoot` option was used for
// the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't
// look inside web components even if open)
(composedPath === null || composedPath === void 0 ? void 0 : composedPath.includes(container)) || tabbableNodes.find(function(node) {
return node === element;
});
});
};
var getNodeForOption = function getNodeForOption2(optionName) {
var optionValue = config[optionName];
if (typeof optionValue === "function") {
for (var _len2 = arguments.length, params = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
params[_key2 - 1] = arguments[_key2];
}
optionValue = optionValue.apply(void 0, params);
}
if (optionValue === true) {
optionValue = void 0;
}
if (!optionValue) {
if (optionValue === void 0 || optionValue === false) {
return optionValue;
}
throw new Error("`".concat(optionName, "` was specified but was not a node, or did not return a node"));
}
var node = optionValue;
if (typeof optionValue === "string") {
node = doc.querySelector(optionValue);
if (!node) {
throw new Error("`".concat(optionName, "` as selector refers to no known node"));
}
}
return node;
};
var getInitialFocusNode = function getInitialFocusNode2() {
var node = getNodeForOption("initialFocus");
if (node === false) {
return false;
}
if (node === void 0 || !isFocusable(node, config.tabbableOptions)) {
if (findContainerIndex(doc.activeElement) >= 0) {
node = doc.activeElement;
} else {
var firstTabbableGroup = state.tabbableGroups[0];
var firstTabbableNode = firstTabbableGroup && firstTabbableGroup.firstTabbableNode;
node = firstTabbableNode || getNodeForOption("fallbackFocus");
}
}
if (!node) {
throw new Error("Your focus-trap needs to have at least one focusable element");
}
return node;
};
var updateTabbableNodes = function updateTabbableNodes2() {
state.containerGroups = state.containers.map(function(container) {
var tabbableNodes = tabbable(container, config.tabbableOptions);
var focusableNodes = focusable(container, config.tabbableOptions);
var firstTabbableNode = tabbableNodes.length > 0 ? tabbableNodes[0] : void 0;
var lastTabbableNode = tabbableNodes.length > 0 ? tabbableNodes[tabbableNodes.length - 1] : void 0;
var firstDomTabbableNode = focusableNodes.find(function(node) {
return isTabbable(node);
});
var lastDomTabbableNode = focusableNodes.slice().reverse().find(function(node) {
return isTabbable(node);
});
var posTabIndexesFound = !!tabbableNodes.find(function(node) {
return getTabIndex(node) > 0;
});
return {
container,
tabbableNodes,
focusableNodes,
/** True if at least one node with positive `tabindex` was found in this container. */
posTabIndexesFound,
/** First tabbable node in container, __tabindex__ order; `undefined` if none. */
firstTabbableNode,
/** Last tabbable node in container, __tabindex__ order; `undefined` if none. */
lastTabbableNode,
// NOTE: DOM order is NOT NECESSARILY "document position" order, but figuring that out
// would require more than just https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
// because that API doesn't work with Shadow DOM as well as it should (@see
// https://github.com/whatwg/dom/issues/320) and since this first/last is only needed, so far,
// to address an edge case related to positive tabindex support, this seems like a much easier,
// "close enough most of the time" alternative for positive tabindexes which should generally
// be avoided anyway...
/** First tabbable node in container, __DOM__ order; `undefined` if none. */
firstDomTabbableNode,
/** Last tabbable node in container, __DOM__ order; `undefined` if none. */
lastDomTabbableNode,
/**
* Finds the __tabbable__ node that follows the given node in the specified direction,
* in this container, if any.
* @param {HTMLElement} node
* @param {boolean} [forward] True if going in forward tab order; false if going
* in reverse.
* @returns {HTMLElement|undefined} The next tabbable node, if any.
*/
nextTabbableNode: function nextTabbableNode(node) {
var forward = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
var nodeIdx = tabbableNodes.indexOf(node);
if (nodeIdx < 0) {
if (forward) {
return focusableNodes.slice(focusableNodes.indexOf(node) + 1).find(function(el) {
return isTabbable(el);
});
}
return focusableNodes.slice(0, focusableNodes.indexOf(node)).reverse().find(function(el) {
return isTabbable(el);
});
}
return tabbableNodes[nodeIdx + (forward ? 1 : -1)];
}
};
});
state.tabbableGroups = state.containerGroups.filter(function(group) {
return group.tabbableNodes.length > 0;
});
if (state.tabbableGroups.length <= 0 && !getNodeForOption("fallbackFocus")) {
throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");
}
if (state.containerGroups.find(function(g) {
return g.posTabIndexesFound;
}) && state.containerGroups.length > 1) {
throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.");
}
};
var getActiveElement = function getActiveElement2(el) {
var activeElement = el.activeElement;
if (!activeElement) {
return;
}
if (activeElement.shadowRoot && activeElement.shadowRoot.activeElement !== null) {
return getActiveElement2(activeElement.shadowRoot);
}
return activeElement;
};
var tryFocus = function tryFocus2(node) {
if (node === false) {
return;
}
if (node === getActiveElement(document)) {
return;
}
if (!node || !node.focus) {
tryFocus2(getInitialFocusNode());
return;
}
node.focus({
preventScroll: !!config.preventScroll
});
state.mostRecentlyFocusedNode = node;
if (isSelectableInput(node)) {
node.select();
}
};
var getReturnFocusNode = function getReturnFocusNode2(previousActiveElement) {
var node = getNodeForOption("setReturnFocus", previousActiveElement);
return node ? node : node === false ? false : previousActiveElement;
};
var findNextNavNode = function findNextNavNode2(_ref2) {
var target = _ref2.target, event = _ref2.event, _ref2$isBackward = _ref2.isBackward, isBackward = _ref2$isBackward === void 0 ? false : _ref2$isBackward;
target = target || getActualTarget(event);
updateTabbableNodes();
var destinationNode = null;
if (state.tabbableGroups.length > 0) {
var containerIndex = findContainerIndex(target, event);
var containerGroup = containerIndex >= 0 ? state.containerGroups[containerIndex] : void 0;
if (containerIndex < 0) {
if (isBackward) {
destinationNode = state.tabbableGroups[state.tabbableGroups.length - 1].lastTabbableNode;
} else {
destinationNode = state.tabbableGroups[0].firstTabbableNode;
}
} else if (isBackward) {
var startOfGroupIndex = findIndex(state.tabbableGroups, function(_ref3) {
var firstTabbableNode = _ref3.firstTabbableNode;
return target === firstTabbableNode;
});
if (startOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target, false))) {
startOfGroupIndex = containerIndex;
}
if (startOfGroupIndex >= 0) {
var destinationGroupIndex = startOfGroupIndex === 0 ? state.tabbableGroups.length - 1 : startOfGroupIndex - 1;
var destinationGroup = state.tabbableGroups[destinationGroupIndex];
destinationNode = getTabIndex(target) >= 0 ? destinationGroup.lastTabbableNode : destinationGroup.lastDomTabbableNode;
} else if (!isTabEvent(event)) {
destinationNode = containerGroup.nextTabbableNode(target, false);
}
} else {
var lastOfGroupIndex = findIndex(state.tabbableGroups, function(_ref4) {
var lastTabbableNode = _ref4.lastTabbableNode;
return target === lastTabbableNode;
});
if (lastOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target))) {
lastOfGroupIndex = containerIndex;
}
if (lastOfGroupIndex >= 0) {
var _destinationGroupIndex = lastOfGroupIndex === state.tabbableGroups.length - 1 ? 0 : lastOfGroupIndex + 1;
var _destinationGroup = state.tabbableGroups[_destinationGroupIndex];
destinationNode = getTabIndex(target) >= 0 ? _destinationGroup.firstTabbableNode : _destinationGroup.firstDomTabbableNode;
} else if (!isTabEvent(event)) {
destinationNode = containerGroup.nextTabbableNode(target);
}
}
} else {
destinationNode = getNodeForOption("fallbackFocus");
}
return destinationNode;
};
var checkPointerDown = function checkPointerDown2(e) {
var target = getActualTarget(e);
if (findContainerIndex(target, e) >= 0) {
return;
}
if (valueOrHandler(config.clickOutsideDeactivates, e)) {
trap.deactivate({
// NOTE: by setting `returnFocus: false`, deactivate() will do nothing,
// which will result in the outside click setting focus to the node
// that was clicked (and if not focusable, to "nothing"); by setting
// `returnFocus: true`, we'll attempt to re-focus the node originally-focused
// on activation (or the configured `setReturnFocus` node), whether the
// outside click was on a focusable node or not
returnFocus: config.returnFocusOnDeactivate
});
return;
}
if (valueOrHandler(config.allowOutsideClick, e)) {
return;
}
e.preventDefault();
};
var checkFocusIn = function checkFocusIn2(event) {
var target = getActualTarget(event);
var targetContained = findContainerIndex(target, event) >= 0;
if (targetContained || target instanceof Document) {
if (targetContained) {
state.mostRecentlyFocusedNode = target;
}
} else {
event.stopImmediatePropagation();
var nextNode;
var navAcrossContainers = true;
if (state.mostRecentlyFocusedNode) {
if (getTabIndex(state.mostRecentlyFocusedNode) > 0) {
var mruContainerIdx = findContainerIndex(state.mostRecentlyFocusedNode);
var tabbableNodes = state.containerGroups[mruContainerIdx].tabbableNodes;
if (tabbableNodes.length > 0) {
var mruTabIdx = tabbableNodes.findIndex(function(node) {
return node === state.mostRecentlyFocusedNode;
});
if (mruTabIdx >= 0) {
if (config.isKeyForward(state.recentNavEvent)) {
if (mruTabIdx + 1 < tabbableNodes.length) {
nextNode = tabbableNodes[mruTabIdx + 1];
navAcrossContainers = false;
}
} else {
if (mruTabIdx - 1 >= 0) {
nextNode = tabbableNodes[mruTabIdx - 1];
navAcrossContainers = false;
}
}
}
}
} else {
if (!state.containerGroups.some(function(g) {
return g.tabbableNodes.some(function(n) {
return getTabIndex(n) > 0;
});
})) {
navAcrossContainers = false;
}
}
} else {
navAcrossContainers = false;
}
if (navAcrossContainers) {
nextNode = findNextNavNode({
// move FROM the MRU node, not event-related node (which will be the node that is
// outside the trap causing the focus escape we're trying to fix)
target: state.mostRecentlyFocusedNode,
isBackward: config.isKeyBackward(state.recentNavEvent)
});
}
if (nextNode) {
tryFocus(nextNode);
} else {
tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
}
}
state.recentNavEvent = void 0;
};
var checkKeyNav = function checkKeyNav2(event) {
var isBackward = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false;
state.recentNavEvent = event;
var destinationNode = findNextNavNode({
event,
isBackward
});
if (destinationNode) {
if (isTabEvent(event)) {
event.preventDefault();
}
tryFocus(destinationNode);
}
};
var checkKey = function checkKey2(event) {
if (isEscapeEvent(event) && valueOrHandler(config.escapeDeactivates, event) !== false) {
event.preventDefault();
trap.deactivate();
return;
}
if (config.isKeyForward(event) || config.isKeyBackward(event)) {
checkKeyNav(event, config.isKeyBackward(event));
}
};
var checkClick = function checkClick2(e) {
var target = getActualTarget(e);
if (findContainerIndex(target, e) >= 0) {
return;
}
if (valueOrHandler(config.clickOutsideDeactivates, e)) {
return;
}
if (valueOrHandler(config.allowOutsideClick, e)) {
return;
}
e.preventDefault();
e.stopImmediatePropagation();
};
var addListeners = function addListeners2() {
if (!state.active) {
return;
}
activeFocusTraps.activateTrap(trapStack, trap);
state.delayInitialFocusTimer = config.delayInitialFocus ? delay(function() {
tryFocus(getInitialFocusNode());
}) : tryFocus(getInitialFocusNode());
doc.addEventListener("focusin", checkFocusIn, true);
doc.addEventListener("mousedown", checkPointerDown, {
capture: true,
passive: false
});
doc.addEventListener("touchstart", checkPointerDown, {
capture: true,
passive: false
});
doc.addEventListener("click", checkClick, {
capture: true,
passive: false
});
doc.addEventListener("keydown", checkKey, {
capture: true,
passive: false
});
return trap;
};
var removeListeners = function removeListeners2() {
if (!state.active) {
return;
}
doc.removeEventListener("focusin", checkFocusIn, true);
doc.removeEventListener("mousedown", checkPointerDown, true);
doc.removeEventListener("touchstart", checkPointerDown, true);
doc.removeEventListener("click", checkClick, true);
doc.removeEventListener("keydown", checkKey, true);
return trap;
};
var checkDomRemoval = function checkDomRemoval2(mutations) {
var isFocusedNodeRemoved = mutations.some(function(mutation) {
var removedNodes = Array.from(mutation.removedNodes);
return removedNodes.some(function(node) {
return node === state.mostRecentlyFocusedNode;
});
});
if (isFocusedNodeRemoved) {
tryFocus(getInitialFocusNode());
}
};
var mutationObserver = typeof window !== "undefined" && "MutationObserver" in window ? new MutationObserver(checkDomRemoval) : void 0;
var updateObservedNodes = function updateObservedNodes2() {
if (!mutationObserver) {
return;
}
mutationObserver.disconnect();
if (state.active && !state.paused) {
state.containers.map(function(container) {
mutationObserver.observe(container, {
subtree: true,
childList: true
});
});
}
};
trap = {
get active() {
return state.active;
},
get paused() {
return state.paused;
},
activate: function activate(activateOptions) {
if (state.active) {
return this;
}
var onActivate = getOption(activateOptions, "onActivate");
var onPostActivate = getOption(activateOptions, "onPostActivate");
var checkCanFocusTrap = getOption(activateOptions, "checkCanFocusTrap");
if (!checkCanFocusTrap) {
updateTabbableNodes();
}
state.active = true;
state.paused = false;
state.nodeFocusedBeforeActivation = doc.activeElement;
onActivate === null || onActivate === void 0 || onActivate();
var finishActivation = function finishActivation2() {
if (checkCanFocusTrap) {
updateTabbableNodes();
}
addListeners();
updateObservedNodes();
onPostActivate === null || onPostActivate === void 0 || onPostActivate();
};
if (checkCanFocusTrap) {
checkCanFocusTrap(state.containers.concat()).then(finishActivation, finishActivation);
return this;
}
finishActivation();
return this;
},
deactivate: function deactivate(deactivateOptions) {
if (!state.active) {
return this;
}
var options = _objectSpread2({
onDeactivate: config.onDeactivate,
onPostDeactivate: config.onPostDeactivate,
checkCanReturnFocus: config.checkCanReturnFocus
}, deactivateOptions);
clearTimeout(state.delayInitialFocusTimer);
state.delayInitialFocusTimer = void 0;
removeListeners();
state.active = false;
state.paused = false;
updateObservedNodes();
activeFocusTraps.deactivateTrap(trapStack, trap);
var onDeactivate = getOption(options, "onDeactivate");
var onPostDeactivate = getOption(options, "onPostDeactivate");
var checkCanReturnFocus = getOption(options, "checkCanReturnFocus");
var returnFocus = getOption(options, "returnFocus", "returnFocusOnDeactivate");
onDeactivate === null || onDeactivate === void 0 || onDeactivate();
var finishDeactivation = function finishDeactivation2() {
delay(function() {
if (returnFocus) {
tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
}
onPostDeactivate === null || onPostDeactivate === void 0 || onPostDeactivate();
});
};
if (returnFocus && checkCanReturnFocus) {
checkCanReturnFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation)).then(finishDeactivation, finishDeactivation);
return this;
}
finishDeactivation();
return this;
},
pause: function pause(pauseOptions) {
if (state.paused || !state.active) {
return this;
}
var onPause = getOption(pauseOptions, "onPause");
var onPostPause = getOption(pauseOptions, "onPostPause");
state.paused = true;
onPause === null || onPause === void 0 || onPause();
removeListeners();
updateObservedNodes();
onPostPause === null || onPostPause === void 0 || onPostPause();
return this;
},
unpause: function unpause(unpauseOptions) {
if (!state.paused || !state.active) {
return this;
}
var onUnpause = getOption(unpauseOptions, "onUnpause");
var onPostUnpause = getOption(unpauseOptions, "onPostUnpause");
state.paused = false;
onUnpause === null || onUnpause === void 0 || onUnpause();
updateTabbableNodes();
addListeners();
updateObservedNodes();
onPostUnpause === null || onPostUnpause === void 0 || onPostUnpause();
return this;
},
updateContainerElements: function updateContainerElements(containerElements) {
var elementsAsArray = [].concat(containerElements).filter(Boolean);
state.containers = elementsAsArray.map(function(element) {
return typeof element === "string" ? doc.querySelector(element) : element;
});
if (state.active) {
updateTabbableNodes();
}
updateObservedNodes();
return this;
}
};
trap.updateContainerElements(elements);
return trap;
};
function useFocusTrap(target, options = {}) {
let trap;
const { immediate, ...focusTrapOptions } = options;
const hasFocus = ref(false);
const isPaused = ref(false);
const activate = (opts) => trap && trap.activate(opts);
const deactivate = (opts) => trap && trap.deactivate(opts);
const pause = () => {
if (trap) {
trap.pause();
isPaused.value = true;
}
};
const unpause = () => {
if (trap) {
trap.unpause();
isPaused.value = false;
}
};
watch(
() => unrefElement(target),
(el) => {
if (!el)
return;
trap = createFocusTrap(el, {
...focusTrapOptions,
onActivate() {
hasFocus.value = true;
if (options.onActivate)
options.onActivate();
},
onDeactivate() {
hasFocus.value = false;
if (options.onDeactivate)
options.onDeactivate();
}
});
if (immediate)
activate();
},
{ flush: "post" }
);
tryOnScopeDispose(() => deactivate());
return {
hasFocus,
isPaused,
activate,
deactivate,
pause,
unpause
};
}
class DOMIterator {
/**
* @param {HTMLElement|HTMLElement[]|NodeList|string} ctx - The context DOM
* element, an array of DOM elements, a NodeList or a selector
* @param {boolean} [iframes=true] - A boolean indicating if iframes should
* be handled
* @param {string[]} [exclude=[]] - An array containing exclusion selectors
* for iframes
* @param {number} [iframesTimeout=5000] - A number indicating the ms to
* wait before an iframe should be skipped, in case the load event isn't
* fired. This also applies if the user is offline and the resource of the
* iframe is online (either by the browsers "offline" mode or because
* there's no internet connection)
*/
constructor(ctx, iframes = true, exclude = [], iframesTimeout = 5e3) {
this.ctx = ctx;
this.iframes = iframes;
this.exclude = exclude;
this.iframesTimeout = iframesTimeout;
}
/**
* Checks if the specified DOM element matches the selector
* @param {HTMLElement} element - The DOM element
* @param {string|string[]} selector - The selector or an array with
* selectors
* @return {boolean}
* @access public
*/
static matches(element, selector) {
const selectors = typeof selector === "string" ? [selector] : selector, fn = element.matches || element.matchesSelector || element.msMatchesSelector || element.mozMatchesSelector || element.oMatchesSelector || element.webkitMatchesSelector;
if (fn) {
let match = false;
selectors.every((sel) => {
if (fn.call(element, sel)) {
match = true;
return false;
}
return true;
});
return match;
} else {
return false;
}
}
/**
* Returns all contexts filtered by duplicates (even nested)
* @return {HTMLElement[]} - An array containing DOM contexts
* @access protected
*/
getContexts() {
let ctx, filteredCtx = [];
if (typeof this.ctx === "undefined" || !this.ctx) {
ctx = [];
} else if (NodeList.prototype.isPrototypeOf(this.ctx)) {
ctx = Array.prototype.slice.call(this.ctx);
} else if (Array.isArray(this.ctx)) {
ctx = this.ctx;
} else if (typeof this.ctx === "string") {
ctx = Array.prototype.slice.call(
document.querySelectorAll(this.ctx)
);
} else {
ctx = [this.ctx];
}
ctx.forEach((ctx2) => {
const isDescendant = filteredCtx.filter((contexts) => {
return contexts.contains(ctx2);
}).length > 0;
if (filteredCtx.indexOf(ctx2) === -1 && !isDescendant) {
filteredCtx.push(ctx2);
}
});
return filteredCtx;
}
/**
* @callback DOMIterator~getIframeContentsSuccessCallback
* @param {HTMLDocument} contents - The contentDocument of the iframe
*/
/**
* Calls the success callback function with the iframe document. If it can't
* be accessed it calls the error callback function
* @param {HTMLElement} ifr - The iframe DOM element
* @param {DOMIterator~getIframeContentsSuccessCallback} successFn
* @param {function} [errorFn]
* @access protected
*/
getIframeContents(ifr, successFn, errorFn = () => {
}) {
let doc;
try {
const ifrWin = ifr.contentWindow;
doc = ifrWin.document;
if (!ifrWin || !doc) {
throw new Error("iframe inaccessible");
}
} catch (e) {
errorFn();
}
if (doc) {
successFn(doc);
}
}
/**
* Checks if an iframe is empty (if about:blank is the shown page)
* @param {HTMLElement} ifr - The iframe DOM element
* @return {boolean}
* @access protected
*/
isIframeBlank(ifr) {
const bl = "about:blank", src = ifr.getAttribute("src").trim(), href = ifr.contentWindow.location.href;
return href === bl && src !== bl && src;
}
/**
* Observes the onload event of an iframe and calls the success callback or
* the error callback if the iframe is inaccessible. If the event isn't
* fired within the specified {@link DOMIterator#iframesTimeout}, then it'll
* call the error callback too
* @param {HTMLElement} ifr - The iframe DOM element
* @param {DOMIterator~getIframeContentsSuccessCallback} successFn
* @param {function} errorFn
* @access protected
*/
observeIframeLoad(ifr, successFn, errorFn) {
let called = false, tout = null;
const listener = () => {
if (called) {
return;
}
called = true;
clearTimeout(tout);
try {
if (!this.isIframeBlank(ifr)) {
ifr.removeEventListener("load", listener);
this.getIframeContents(ifr, successFn, errorFn);
}
} catch (e) {
errorFn();
}
};
ifr.addEventListener("load", listener);
tout = setTimeout(listener, this.iframesTimeout);
}
/**
* Callback when the iframe is ready
* @callback DOMIterator~onIframeReadySuccessCallback
* @param {HTMLDocument} contents - The contentDocument of the iframe
*/
/**
* Callback if the iframe can't be accessed
* @callback DOMIterator~onIframeReadyErrorCallback
*/
/**
* Calls the callback if the specified iframe is ready for DOM access
* @param {HTMLElement} ifr - The iframe DOM element
* @param {DOMIterator~onIframeReadySuccessCallback} successFn - Success
* callback
* @param {DOMIterator~onIframeReadyErrorCallback} errorFn - Error callback
* @see {@link http://stackoverflow.com/a/36155560/3894981} for
* background information
* @access protected
*/
onIframeReady(ifr, successFn, errorFn) {
try {
if (ifr.contentWindow.document.readyState === "complete") {
if (this.isIframeBlank(ifr)) {
this.observeIframeLoad(ifr, successFn, errorFn);
} else {
this.getIframeContents(ifr, successFn, errorFn);
}
} else {
this.observeIframeLoad(ifr, successFn, errorFn);
}
} catch (e) {
errorFn();
}
}
/**
* Callback when all iframes are ready for DOM access
* @callback DOMIterator~waitForIframesDoneCallback
*/
/**
* Iterates over all iframes and calls the done callback when all of them
* are ready for DOM access (including nested ones)
* @param {HTMLElement} ctx - The context DOM element
* @param {DOMIterator~waitForIframesDoneCallback} done - Done callback
*/
waitForIframes(ctx, done) {
let eachCalled = 0;
this.forEachIframe(ctx, () => true, (ifr) => {
eachCalled++;
this.waitForIframes(ifr.querySelector("html"), () => {
if (!--eachCalled) {
done();
}
});
}, (handled) => {
if (!handled) {
done();
}
});
}
/**
* Callback allowing to filter an iframe. Must return true when the element
* should remain, otherwise false
* @callback DOMIterator~forEachIframeFilterCallback
* @param {HTMLElement} iframe - The iframe DOM element
*/
/**
* Callback for each iframe content
* @callback DOMIterator~forEachIframeEachCallback
* @param {HTMLElement} content - The iframe document
*/
/**
* Callback if all iframes inside the context were handled
* @callback DOMIterator~forEachIframeEndCallback
* @param {number} handled - The number of handled iframes (those who
* wheren't filtered)
*/
/**
* Iterates over all iframes inside the specified context and calls the
* callbacks when they're ready. Filters iframes based on the instance
* exclusion selectors
* @param {HTMLElement} ctx - The context DOM element
* @param {DOMIterator~forEachIframeFilterCallback} filter - Filter callback
* @param {DOMIterator~forEachIframeEachCallback} each - Each callback
* @param {DOMIterator~forEachIframeEndCallback} [end] - End callback
* @access protected
*/
forEachIframe(ctx, filter, each, end = () => {
}) {
let ifr = ctx.querySelectorAll("iframe"), open = ifr.length, handled = 0;
ifr = Array.prototype.slice.call(ifr);
const checkEnd = () => {
if (--open <= 0) {
end(handled);
}
};
if (!open) {
checkEnd();
}
ifr.forEach((ifr2) => {
if (DOMIterator.matches(ifr2, this.exclude)) {
checkEnd();
} else {
this.onIframeReady(ifr2, (con) => {
if (filter(ifr2)) {
handled++;
each(con);
}
checkEnd();
}, checkEnd);
}
});
}
/**
* Creates a NodeIterator on the specified context
* @see {@link https://developer.mozilla.org/en/docs/Web/API/NodeIterator}
* @param {HTMLElement} ctx - The context DOM element
* @param {DOMIterator~whatToShow} whatToShow
* @param {DOMIterator~filterCb} filter
* @return {NodeIterator}
* @access protected
*/
createIterator(ctx, whatToShow, filter) {
return document.createNodeIterator(ctx, whatToShow, filter, false);
}
/**
* Creates an instance of DOMIterator in an iframe
* @param {HTMLDocument} contents - Iframe document
* @return {DOMIterator}
* @access protected
*/
createInstanceOnIframe(contents) {
return new DOMIterator(contents.querySelector("html"), this.iframes);
}
/**
* Checks if an iframe occurs between two nodes, more specifically if an
* iframe occurs before the specified node and after the specified prevNode
* @param {HTMLElement} node - The node that should occur after the iframe
* @param {HTMLElement} prevNode - The node that should occur before the
* iframe
* @param {HTMLElement} ifr - The iframe to check against
* @return {boolean}
* @access protected
*/
compareNodeIframe(node, prevNode, ifr) {
const compCurr = node.compareDocumentPosition(ifr), prev = Node.DOCUMENT_POSITION_PRECEDING;
if (compCurr & prev) {
if (prevNode !== null) {
const compPrev = prevNode.compareDocumentPosition(ifr), after = Node.DOCUMENT_POSITION_FOLLOWING;
if (compPrev & after) {
return true;
}
} else {
return true;
}
}
return false;
}
/**
* @typedef {DOMIterator~getIteratorNodeReturn}
* @type {object.<string>}
* @property {HTMLElement} prevNode - The previous node or null if there is
* no
* @property {HTMLElement} node - The current node
*/
/**
* Returns the previous and current node of the specified iterator
* @param {NodeIterator} itr - The iterator
* @return {DOMIterator~getIteratorNodeReturn}
* @access protected
*/
getIteratorNode(itr) {
const prevNode = itr.previousNode();
let node;
if (prevNode === null) {
node = itr.nextNode();
} else {
node = itr.nextNode() && itr.nextNode();
}
return {
prevNode,
node
};
}
/**
* An array containing objects. The object key "val" contains an iframe
* DOM element. The object key "handled" contains a boolean indicating if
* the iframe was handled already.
* It wouldn't be enough to save all open or all already handled iframes.
* The information of open iframes is necessary because they may occur after
* all other text nodes (and compareNodeIframe would never be true). The
* information of already handled iframes is necessary as otherwise they may
* be handled multiple times
* @typedef DOMIterator~checkIframeFilterIfr
* @type {object[]}
*/
/**
* Checks if an iframe wasn't handled already and if so, calls
* {@link DOMIterator#compareNodeIframe} to check if it should be handled.
* Information wheter an iframe was or wasn't handled is given within the
* <code>ifr</code> dictionary
* @param {HTMLElement} node - The node that should occur after the iframe
* @param {HTMLElement} prevNode - The node that should occur before the
* iframe
* @param {HTMLElement} currIfr - The iframe to check
* @param {DOMIterator~checkIframeFilterIfr} ifr - The iframe dictionary.
* Will be manipulated (by reference)
* @return {boolean} Returns true when it should be handled, otherwise false
* @access protected
*/
checkIframeFilter(node, prevNode, currIfr, ifr) {
let key = false, handled = false;
ifr.forEach((ifrDict, i) => {
if (ifrDict.val === currIfr) {
key = i;
handled = ifrDict.handled;
}
});
if (this.compareNodeIframe(node, prevNode, currIfr)) {
if (key === false && !handled) {
ifr.push({
val: currIfr,
handled: true
});
} else if (key !== false && !handled) {
ifr[key].handled = true;
}
return true;
}
if (key === false) {
ifr.push({
val: currIfr,
handled: false
});
}
return false;
}
/**
* Creates an iterator on all open iframes in the specified array and calls
* the end callback when finished
* @param {DOMIterator~checkIframeFilterIfr} ifr
* @param {DOMIterator~whatToShow} whatToShow
* @param {DOMIterator~forEachNodeCallback} eCb - Each callback
* @param {DOMIterator~filterCb} fCb
* @access protected
*/
handleOpenIframes(ifr, whatToShow, eCb, fCb) {
ifr.forEach((ifrDict) => {
if (!ifrDict.handled) {
this.getIframeContents(ifrDict.val, (con) => {
this.createInstanceOnIframe(con).forEachNode(
whatToShow,
eCb,
fCb
);
});
}
});
}
/**
* Iterates through all nodes in the specified context and handles iframe
* nodes at the correct position
* @param {DOMIterator~whatToShow} whatToShow
* @param {HTMLElement} ctx - The context
* @param {DOMIterator~forEachNodeCallback} eachCb - Each callback
* @param {DOMIterator~filterCb} filterCb - Filter callback
* @param {DOMIterator~forEachNodeEndCallback} doneCb - End callback
* @access protected
*/
iterateThroughNodes(whatToShow, ctx, eachCb, filterCb, doneCb) {
const itr = this.createIterator(ctx, whatToShow, filterCb);
let ifr = [], elements = [], node, prevNode, retrieveNodes = () => {
({
prevNode,
node
} = this.getIteratorNode(itr));
return node;
};
while (retrieveNodes()) {
if (this.iframes) {
this.forEachIframe(ctx, (currIfr) => {
return this.checkIframeFilter(node, prevNode, currIfr, ifr);
}, (con) => {
this.createInstanceOnIframe(con).forEachNode(
whatToShow,
(ifrNode) => elements.push(ifrNode),
filterCb
);
});
}
elements.push(node);
}
elements.forEach((node2) => {
eachCb(node2);
});
if (this.iframes) {
this.handleOpenIframes(ifr, whatToShow, eachCb, filterCb);
}
doneCb();
}
/**
* Callback for each node
* @callback DOMIterator~forEachNodeCallback
* @param {HTMLElement} node - The DOM text node element
*/
/**
* Callback if all contexts were handled
* @callback DOMIterator~forEachNodeEndCallback
*/
/**
* Iterates over all contexts and initializes
* {@link DOMIterator#iterateThroughNodes iterateThroughNodes} on them
* @param {DOMIterator~whatToShow} whatToShow
* @param {DOMIterator~forEachNodeCallback} each - Each callback
* @param {DOMIterator~filterCb} filter - Filter callback
* @param {DOMIterator~forEachNodeEndCallback} done - End callback
* @access public
*/
forEachNode(whatToShow, each, filter, done = () => {
}) {
const contexts = this.getContexts();
let open = contexts.length;
if (!open) {
done();
}
contexts.forEach((ctx) => {
const ready = () => {
this.iterateThroughNodes(whatToShow, ctx, each, filter, () => {
if (--open <= 0) {
done();
}
});
};
if (this.iframes) {
this.waitForIframes(ctx, ready);
} else {
ready();
}
});
}
/**
* Callback to filter nodes. Can return e.g. NodeFilter.FILTER_ACCEPT or
* NodeFilter.FILTER_REJECT
* @see {@link http://tinyurl.com/zdczmm2}
* @callback DOMIterator~filterCb
* @param {HTMLElement} node - The node to filter
*/
/**
* @typedef DOMIterator~whatToShow
* @see {@link http://tinyurl.com/zfqqkx2}
* @type {number}
*/
}
let Mark$1 = class Mark {
// eslint-disable-line no-unused-vars
/**
* @param {HTMLElement|HTMLElement[]|NodeList|string} ctx - The context DOM
* element, an array of DOM elements, a NodeList or a selector
*/
constructor(ctx) {
this.ctx = ctx;
this.ie = false;
const ua = window.navigator.userAgent;
if (ua.indexOf("MSIE") > -1 || ua.indexOf("Trident") > -1) {
this.ie = true;
}
}
/**
* Options defined by the user. They will be initialized from one of the
* public methods. See {@link Mark#mark}, {@link Mark#markRegExp},
* {@link Mark#markRanges} and {@link Mark#unmark} for option properties.
* @type {object}
* @param {object} [val] - An object that will be merged with defaults
* @access protected
*/
set opt(val) {
this._opt = Object.assign({}, {
"element": "",
"className": "",
"exclude": [],
"iframes": false,
"iframesTimeout": 5e3,
"separateWordSearch": true,
"diacritics": true,
"synonyms": {},
"accuracy": "partially",
"acrossElements": false,
"caseSensitive": false,
"ignoreJoiners": false,
"ignoreGroups": 0,
"ignorePunctuation": [],
"wildcards": "disabled",
"each": () => {
},
"noMatch": () => {
},
"filter": () => true,
"done": () => {
},
"debug": false,
"log": window.console
}, val);
}
get opt() {
return this._opt;
}
/**
* An instance of DOMIterator
* @type {DOMIterator}
* @access protected
*/
get iterator() {
return new DOMIterator(
this.ctx,
this.opt.iframes,
this.opt.exclude,
this.opt.iframesTimeout
);
}
/**
* Logs a message if log is enabled
* @param {string} msg - The message to log
* @param {string} [level="debug"] - The log level, e.g. <code>warn</code>
* <code>error</code>, <code>debug</code>
* @access protected
*/
log(msg, level = "debug") {
const log = this.opt.log;
if (!this.opt.debug) {
return;
}
if (typeof log === "object" && typeof log[level] === "function") {
log[level](`mark.js: ${msg}`);
}
}
/**
* Escapes a string for usage within a regular expression
* @param {string} str - The string to escape
* @return {string}
* @access protected
*/
escapeStr(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
/**
* Creates a regular expression string to match the specified search
* term including synonyms, diacritics and accuracy if defined
* @param {string} str - The search term to be used
* @return {string}
* @access protected
*/
createRegExp(str) {
if (this.opt.wildcards !== "disabled") {
str = this.setupWildcardsRegExp(str);
}
str = this.escapeStr(str);
if (Object.keys(this.opt.synonyms).length) {
str = this.createSynonymsRegExp(str);
}
if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {
str = this.setupIgnoreJoinersRegExp(str);
}
if (this.opt.diacritics) {
str = this.createDiacriticsRegExp(str);
}
str = this.createMergedBlanksRegExp(str);
if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {
str = this.createJoinersRegExp(str);
}
if (this.opt.wildcards !== "disabled") {
str = this.createWildcardsRegExp(str);
}
str = this.createAccuracyRegExp(str);
return str;
}
/**
* Creates a regular expression string to match the defined synonyms
* @param {string} str - The search term to be used
* @return {string}
* @access protected
*/
createSynonymsRegExp(str) {
const syn = this.opt.synonyms, sens = this.opt.caseSensitive ? "" : "i", joinerPlaceholder = this.opt.ignoreJoiners || this.opt.ignorePunctuation.length ? "\0" : "";
for (let index in syn) {
if (syn.hasOwnProperty(index)) {
const value = syn[index], k1 = this.opt.wildcards !== "disabled" ? this.setupWildcardsRegExp(index) : this.escapeStr(index), k2 = this.opt.wildcards !== "disabled" ? this.setupWildcardsRegExp(value) : this.escapeStr(value);
if (k1 !== "" && k2 !== "") {
str = str.replace(
new RegExp(
`(${this.escapeStr(k1)}|${this.escapeStr(k2)})`,
`gm${sens}`
),
joinerPlaceholder + `(${this.processSynomyms(k1)}|${this.processSynomyms(k2)})` + joinerPlaceholder
);
}
}
}
return str;
}
/**
* Setup synonyms to work with ignoreJoiners and or ignorePunctuation
* @param {string} str - synonym key or value to process
* @return {string} - processed synonym string
*/
processSynomyms(str) {
if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {
str = this.setupIgnoreJoinersRegExp(str);
}
return str;
}
/**
* Sets up the regular expression string to allow later insertion of
* wildcard regular expression matches
* @param {string} str - The search term to be used
* @return {string}
* @access protected
*/
setupWildcardsRegExp(str) {
str = str.replace(/(?:\\)*\?/g, (val) => {
return val.charAt(0) === "\\" ? "?" : "";
});
return str.replace(/(?:\\)*\*/g, (val) => {
return val.charAt(0) === "\\" ? "*" : "";
});
}
/**
* Sets up the regular expression string to allow later insertion of
* wildcard regular expression matches
* @param {string} str - The search term to be used
* @return {string}
* @access protected
*/
createWildcardsRegExp(str) {
let spaces = this.opt.wildcards === "withSpaces";
return str.replace(/\u0001/g, spaces ? "[\\S\\s]?" : "\\S?").replace(/\u0002/g, spaces ? "[\\S\\s]*?" : "\\S*");
}
/**
* Sets up the regular expression string to allow later insertion of
* designated characters (soft hyphens & zero width characters)
* @param {string} str - The search term to be used
* @return {string}
* @access protected
*/
setupIgnoreJoinersRegExp(str) {
return str.replace(/[^(|)\\]/g, (val, indx, original) => {
let nextChar = original.charAt(indx + 1);
if (/[(|)\\]/.test(nextChar) || nextChar === "") {
return val;
} else {
return val + "\0";
}
});
}
/**
* Creates a regular expression string to allow ignoring of designated
* characters (soft hyphens, zero width characters & punctuation) based on
* the specified option values of <code>ignorePunctuation</code> and
* <code>ignoreJoiners</code>
* @param {string} str - The search term to be used
* @return {string}
* @access protected
*/
createJoinersRegExp(str) {
let joiner = [];
const ignorePunctuation = this.opt.ignorePunctuation;
if (Array.isArray(ignorePunctuation) && ignorePunctuation.length) {
joiner.push(this.escapeStr(ignorePunctuation.join("")));
}
if (this.opt.ignoreJoiners) {
joiner.push("\\u00ad\\u200b\\u200c\\u200d");
}
return joiner.length ? str.split(/\u0000+/).join(`[${joiner.join("")}]*`) : str;
}
/**
* Creates a regular expression string to match diacritics
* @param {string} str - The search term to be used
* @return {string}
* @access protected
*/
createDiacriticsRegExp(str) {
const sens = this.opt.caseSensitive ? "" : "i", dct = this.opt.caseSensitive ? [
"aàáảãạăằắẳẵặâầấẩẫậäåāą",
"AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ",
"cçćč",
"CÇĆČ",
"dđď",
"DĐĎ",
"eèéẻẽẹêềếểễệëěēę",
"EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ",
"iìíỉĩịîïī",
"IÌÍỈĨỊÎÏĪ",
"lł",
"LŁ",
"nñňń",
"NÑŇŃ",
"oòóỏõọôồốổỗộơởỡớờợöøō",
"OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ",
"rř",
"RŘ",
"sšśșş",
"SŠŚȘŞ",
"tťțţ",
"TŤȚŢ",
"uùúủũụưừứửữựûüůū",
"UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ",
"yýỳỷỹỵÿ",
"YÝỲỶỸỴŸ",
"zžżź",
"ZŽŻŹ"
] : [
"aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ",
"cçćčCÇĆČ",
"dđďDĐĎ",
"eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ",
"iìíỉĩịîïīIÌÍỈĨỊÎÏĪ",
"lłLŁ",
"nñňńNÑŇŃ",
"oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ",
"rřRŘ",
"sšśșşSŠŚȘŞ",
"tťțţTŤȚŢ",
"uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ",
"yýỳỷỹỵÿYÝỲỶỸỴŸ",
"zžżźZŽŻŹ"
];
let handled = [];
str.split("").forEach((ch) => {
dct.every((dct2) => {
if (dct2.indexOf(ch) !== -1) {
if (handled.indexOf(dct2) > -1) {
return false;
}
str = str.replace(
new RegExp(`[${dct2}]`, `gm${sens}`),
`[${dct2}]`
);
handled.push(dct2);
}
return true;
});
});
return str;
}
/**
* Creates a regular expression string that merges whitespace characters
* including subsequent ones into a single pattern, one or multiple
* whitespaces
* @param {string} str - The search term to be used
* @return {string}
* @access protected
*/
createMergedBlanksRegExp(str) {
return str.replace(/[\s]+/gmi, "[\\s]+");
}
/**
* Creates a regular expression string to match the specified string with
* the defined accuracy. As in the regular expression of "exactly" can be
* a group containing a blank at the beginning, all regular expressions will
* be created with two groups. The first group can be ignored (may contain
* the said blank), the second contains the actual match
* @param {string} str - The searm term to be used
* @return {str}
* @access protected
*/
createAccuracyRegExp(str) {
const chars = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿";
let acc = this.opt.accuracy, val = typeof acc === "string" ? acc : acc.value, ls = typeof acc === "string" ? [] : acc.limiters, lsJoin = "";
ls.forEach((limiter) => {
lsJoin += `|${this.escapeStr(limiter)}`;
});
switch (val) {
case "partially":
default:
return `()(${str})`;
case "complementary":
lsJoin = "\\s" + (lsJoin ? lsJoin : this.escapeStr(chars));
return `()([^${lsJoin}]*${str}[^${lsJoin}]*)`;
case "exactly":
return `(^|\\s${lsJoin})(${str})(?=$|\\s${lsJoin})`;
}
}
/**
* @typedef Mark~separatedKeywords
* @type {object.<string>}
* @property {array.<string>} keywords - The list of keywords
* @property {number} length - The length
*/
/**
* Returns a list of keywords dependent on whether separate word search
* was defined. Also it filters empty keywords
* @param {array} sv - The array of keywords
* @return {Mark~separatedKeywords}
* @access protected
*/
getSeparatedKeywords(sv) {
let stack = [];
sv.forEach((kw) => {
if (!this.opt.separateWordSearch) {
if (kw.trim() && stack.indexOf(kw) === -1) {
stack.push(kw);
}
} else {
kw.split(" ").forEach((kwSplitted) => {
if (kwSplitted.trim() && stack.indexOf(kwSplitted) === -1) {
stack.push(kwSplitted);
}
});
}
});
return {
// sort because of https://git.io/v6USg
"keywords": stack.sort((a, b) => {
return b.length - a.length;
}),
"length": stack.length
};
}
/**
* Check if a value is a number
* @param {number|string} value - the value to check;
* numeric strings allowed
* @return {boolean}
* @access protected
*/
isNumeric(value) {
return Number(parseFloat(value)) == value;
}
/**
* @typedef Mark~rangeObject
* @type {object}
* @property {number} start - The start position within the composite value
* @property {number} length - The length of the string to mark within the
* composite value.
*/
/**
* @typedef Mark~setOfRanges
* @type {object[]}
* @property {Mark~rangeObject}
*/
/**
* Returns a processed list of integer offset indexes that do not overlap
* each other, and remove any string values or additional elements
* @param {Mark~setOfRanges} array - unprocessed raw array
* @return {Mark~setOfRanges} - processed array with any invalid entries
* removed
* @throws Will throw an error if an array of objects is not passed
* @access protected
*/
checkRanges(array) {
if (!Array.isArray(array) || Object.prototype.toString.call(array[0]) !== "[object Object]") {
this.log("markRanges() will only accept an array of objects");
this.opt.noMatch(array);
return [];
}
const stack = [];
let last2 = 0;
array.sort((a, b) => {
return a.start - b.start;
}).forEach((item) => {
let { start, end, valid } = this.callNoMatchOnInvalidRanges(item, last2);
if (valid) {
item.start = start;
item.length = end - start;
stack.push(item);
last2 = end;
}
});
return stack;
}
/**
* @typedef Mark~validObject
* @type {object}
* @property {number} start - The start position within the composite value
* @property {number} end - The calculated end position within the composite
* value.
* @property {boolean} valid - boolean value indicating that the start and
* calculated end range is valid
*/
/**
* Initial validation of ranges for markRanges. Preliminary checks are done
* to ensure the start and length values exist and are not zero or non-
* numeric
* @param {Mark~rangeObject} range - the current range object
* @param {number} last - last index of range
* @return {Mark~validObject}
* @access protected
*/
callNoMatchOnInvalidRanges(range, last2) {
let start, end, valid = false;
if (range && typeof range.start !== "undefined") {
start = parseInt(range.start, 10);
end = start + parseInt(range.length, 10);
if (this.isNumeric(range.start) && this.isNumeric(range.length) && end - last2 > 0 && end - start > 0) {
valid = true;
} else {
this.log(
`Ignoring invalid or overlapping range: ${JSON.stringify(range)}`
);
this.opt.noMatch(range);
}
} else {
this.log(`Ignoring invalid range: ${JSON.stringify(range)}`);
this.opt.noMatch(range);
}
return {
start,
end,
valid
};
}
/**
* Check valid range for markRanges. Check ranges with access to the context
* string. Range values are double checked, lengths that extend the mark
* beyond the string length are limitied and ranges containing only
* whitespace are ignored
* @param {Mark~rangeObject} range - the current range object
* @param {number} originalLength - original length of the context string
* @param {string} string - current content string
* @return {Mark~validObject}
* @access protected
*/
checkWhitespaceRanges(range, originalLength, string) {
let end, valid = true, max = string.length, offset = originalLength - max, start = parseInt(range.start, 10) - offset;
start = start > max ? max : start;
end = start + parseInt(range.length, 10);
if (end > max) {
end = max;
this.log(`End range automatically set to the max value of ${max}`);
}
if (start < 0 || end - start < 0 || start > max || end > max) {
valid = false;
this.log(`Invalid range: ${JSON.stringify(range)}`);
this.opt.noMatch(range);
} else if (string.substring(start, end).replace(/\s+/g, "") === "") {
valid = false;
this.log("Skipping whitespace only range: " + JSON.stringify(range));
this.opt.noMatch(range);
}
return {
start,
end,
valid
};
}
/**
* @typedef Mark~getTextNodesDict
* @type {object.<string>}
* @property {string} value - The composite value of all text nodes
* @property {object[]} nodes - An array of objects
* @property {number} nodes.start - The start position within the composite
* value
* @property {number} nodes.end - The end position within the composite
* value
* @property {HTMLElement} nodes.node - The DOM text node element
*/
/**
* Callback
* @callback Mark~getTextNodesCallback
* @param {Mark~getTextNodesDict}
*/
/**
* Calls the callback with an object containing all text nodes (including
* iframe text nodes) with start and end positions and the composite value
* of them (string)
* @param {Mark~getTextNodesCallback} cb - Callback
* @access protected
*/
getTextNodes(cb) {
let val = "", nodes = [];
this.iterator.forEachNode(NodeFilter.SHOW_TEXT, (node) => {
nodes.push({
start: val.length,
end: (val += node.textContent).length,
node
});
}, (node) => {
if (this.matchesExclude(node.parentNode)) {
return NodeFilter.FILTER_REJECT;
} else {
return NodeFilter.FILTER_ACCEPT;
}
}, () => {
cb({
value: val,
nodes
});
});
}
/**
* Checks if an element matches any of the specified exclude selectors. Also
* it checks for elements in which no marks should be performed (e.g.
* script and style tags) and optionally already marked elements
* @param {HTMLElement} el - The element to check
* @return {boolean}
* @access protected
*/
matchesExclude(el) {
return DOMIterator.matches(el, this.opt.exclude.concat([
// ignores the elements itself, not their childrens (selector *)
"script",
"style",
"title",
"head",
"html"
]));
}
/**
* Wraps the instance element and class around matches that fit the start
* and end positions within the node
* @param {HTMLElement} node - The DOM text node
* @param {number} start - The position where to start wrapping
* @param {number} end - The position where to end wrapping
* @return {HTMLElement} Returns the splitted text node that will appear
* after the wrapped text node
* @access protected
*/
wrapRangeInTextNode(node, start, end) {
const hEl = !this.opt.element ? "mark" : this.opt.element, startNode = node.splitText(start), ret = startNode.splitText(end - start);
let repl = document.createElement(hEl);
repl.setAttribute("data-markjs", "true");
if (this.opt.className) {
repl.setAttribute("class", this.opt.className);
}
repl.textContent = startNode.textContent;
startNode.parentNode.replaceChild(repl, startNode);
return ret;
}
/**
* @typedef Mark~wrapRangeInMappedTextNodeDict
* @type {object.<string>}
* @property {string} value - The composite value of all text nodes
* @property {object[]} nodes - An array of objects
* @property {number} nodes.start - The start position within the composite
* value
* @property {number} nodes.end - The end position within the composite
* value
* @property {HTMLElement} nodes.node - The DOM text node element
*/
/**
* Each callback
* @callback Mark~wrapMatchesEachCallback
* @param {HTMLElement} node - The wrapped DOM element
* @param {number} lastIndex - The last matching position within the
* composite value of text nodes
*/
/**
* Filter callback
* @callback Mark~wrapMatchesFilterCallback
* @param {HTMLElement} node - The matching text node DOM element
*/
/**
* Determines matches by start and end positions using the text node
* dictionary even across text nodes and calls
* {@link Mark#wrapRangeInTextNode} to wrap them
* @param {Mark~wrapRangeInMappedTextNodeDict} dict - The dictionary
* @param {number} start - The start position of the match
* @param {number} end - The end position of the match
* @param {Mark~wrapMatchesFilterCallback} filterCb - Filter callback
* @param {Mark~wrapMatchesEachCallback} eachCb - Each callback
* @access protected
*/
wrapRangeInMappedTextNode(dict, start, end, filterCb, eachCb) {
dict.nodes.every((n, i) => {
const sibl = dict.nodes[i + 1];
if (typeof sibl === "undefined" || sibl.start > start) {
if (!filterCb(n.node)) {
return false;
}
const s = start - n.start, e = (end > n.end ? n.end : end) - n.start, startStr = dict.value.substr(0, n.start), endStr = dict.value.substr(e + n.start);
n.node = this.wrapRangeInTextNode(n.node, s, e);
dict.value = startStr + endStr;
dict.nodes.forEach((k, j) => {
if (j >= i) {
if (dict.nodes[j].start > 0 && j !== i) {
dict.nodes[j].start -= e;
}
dict.nodes[j].end -= e;
}
});
end -= e;
eachCb(n.node.previousSibling, n.start);
if (end > n.end) {
start = n.end;
} else {
return false;
}
}
return true;
});
}
/**
* Filter callback before each wrapping
* @callback Mark~wrapMatchesFilterCallback
* @param {string} match - The matching string
* @param {HTMLElement} node - The text node where the match occurs
*/
/**
* Callback for each wrapped element
* @callback Mark~wrapMatchesEachCallback
* @param {HTMLElement} element - The marked DOM element
*/
/**
* Callback on end
* @callback Mark~wrapMatchesEndCallback
*/
/**
* Wraps the instance element and class around matches within single HTML
* elements in all contexts
* @param {RegExp} regex - The regular expression to be searched for
* @param {number} ignoreGroups - A number indicating the amount of RegExp
* matching groups to ignore
* @param {Mark~wrapMatchesFilterCallback} filterCb
* @param {Mark~wrapMatchesEachCallback} eachCb
* @param {Mark~wrapMatchesEndCallback} endCb
* @access protected
*/
wrapMatches(regex, ignoreGroups, filterCb, eachCb, endCb) {
const matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1;
this.getTextNodes((dict) => {
dict.nodes.forEach((node) => {
node = node.node;
let match;
while ((match = regex.exec(node.textContent)) !== null && match[matchIdx] !== "") {
if (!filterCb(match[matchIdx], node)) {
continue;
}
let pos = match.index;
if (matchIdx !== 0) {
for (let i = 1; i < matchIdx; i++) {
pos += match[i].length;
}
}
node = this.wrapRangeInTextNode(
node,
pos,
pos + match[matchIdx].length
);
eachCb(node.previousSibling);
regex.lastIndex = 0;
}
});
endCb();
});
}
/**
* Callback for each wrapped element
* @callback Mark~wrapMatchesAcrossElementsEachCallback
* @param {HTMLElement} element - The marked DOM element
*/
/**
* Filter callback before each wrapping
* @callback Mark~wrapMatchesAcrossElementsFilterCallback
* @param {string} match - The matching string
* @param {HTMLElement} node - The text node where the match occurs
*/
/**
* Callback on end
* @callback Mark~wrapMatchesAcrossElementsEndCallback
*/
/**
* Wraps the instance element and class around matches across all HTML
* elements in all contexts
* @param {RegExp} regex - The regular expression to be searched for
* @param {number} ignoreGroups - A number indicating the amount of RegExp
* matching groups to ignore
* @param {Mark~wrapMatchesAcrossElementsFilterCallback} filterCb
* @param {Mark~wrapMatchesAcrossElementsEachCallback} eachCb
* @param {Mark~wrapMatchesAcrossElementsEndCallback} endCb
* @access protected
*/
wrapMatchesAcrossElements(regex, ignoreGroups, filterCb, eachCb, endCb) {
const matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1;
this.getTextNodes((dict) => {
let match;
while ((match = regex.exec(dict.value)) !== null && match[matchIdx] !== "") {
let start = match.index;
if (matchIdx !== 0) {
for (let i = 1; i < matchIdx; i++) {
start += match[i].length;
}
}
const end = start + match[matchIdx].length;
this.wrapRangeInMappedTextNode(dict, start, end, (node) => {
return filterCb(match[matchIdx], node);
}, (node, lastIndex) => {
regex.lastIndex = lastIndex;
eachCb(node);
});
}
endCb();
});
}
/**
* Callback for each wrapped element
* @callback Mark~wrapRangeFromIndexEachCallback
* @param {HTMLElement} element - The marked DOM element
* @param {Mark~rangeObject} range - the current range object; provided
* start and length values will be numeric integers modified from the
* provided original ranges.
*/
/**
* Filter callback before each wrapping
* @callback Mark~wrapRangeFromIndexFilterCallback
* @param {HTMLElement} node - The text node which includes the range
* @param {Mark~rangeObject} range - the current range object
* @param {string} match - string extracted from the matching range
* @param {number} counter - A counter indicating the number of all marks
*/
/**
* Callback on end
* @callback Mark~wrapRangeFromIndexEndCallback
*/
/**
* Wraps the indicated ranges across all HTML elements in all contexts
* @param {Mark~setOfRanges} ranges
* @param {Mark~wrapRangeFromIndexFilterCallback} filterCb
* @param {Mark~wrapRangeFromIndexEachCallback} eachCb
* @param {Mark~wrapRangeFromIndexEndCallback} endCb
* @access protected
*/
wrapRangeFromIndex(ranges, filterCb, eachCb, endCb) {
this.getTextNodes((dict) => {
const originalLength = dict.value.length;
ranges.forEach((range, counter) => {
let { start, end, valid } = this.checkWhitespaceRanges(
range,
originalLength,
dict.value
);
if (valid) {
this.wrapRangeInMappedTextNode(dict, start, end, (node) => {
return filterCb(
node,
range,
dict.value.substring(start, end),
counter
);
}, (node) => {
eachCb(node, range);
});
}
});
endCb();
});
}
/**
* Unwraps the specified DOM node with its content (text nodes or HTML)
* without destroying possibly present events (using innerHTML) and
* normalizes the parent at the end (merge splitted text nodes)
* @param {HTMLElement} node - The DOM node to unwrap
* @access protected
*/
unwrapMatches(node) {
const parent = node.parentNode;
let docFrag = document.createDocumentFragment();
while (node.firstChild) {
docFrag.appendChild(node.removeChild(node.firstChild));
}
parent.replaceChild(docFrag, node);
if (!this.ie) {
parent.normalize();
} else {
this.normalizeTextNode(parent);
}
}
/**
* Normalizes text nodes. It's a workaround for the native normalize method
* that has a bug in IE (see attached link). Should only be used in IE
* browsers as it's slower than the native method.
* @see {@link http://tinyurl.com/z5asa8c}
* @param {HTMLElement} node - The DOM node to normalize
* @access protected
*/
normalizeTextNode(node) {
if (!node) {
return;
}
if (node.nodeType === 3) {
while (node.nextSibling && node.nextSibling.nodeType === 3) {
node.nodeValue += node.nextSibling.nodeValue;
node.parentNode.removeChild(node.nextSibling);
}
} else {
this.normalizeTextNode(node.firstChild);
}
this.normalizeTextNode(node.nextSibling);
}
/**
* Callback when finished
* @callback Mark~commonDoneCallback
* @param {number} totalMatches - The number of marked elements
*/
/**
* @typedef Mark~commonOptions
* @type {object.<string>}
* @property {string} [element="mark"] - HTML element tag name
* @property {string} [className] - An optional class name
* @property {string[]} [exclude] - An array with exclusion selectors.
* Elements matching those selectors will be ignored
* @property {boolean} [iframes=false] - Whether to search inside iframes
* @property {Mark~commonDoneCallback} [done]
* @property {boolean} [debug=false] - Wheter to log messages
* @property {object} [log=window.console] - Where to log messages (only if
* debug is true)
*/
/**
* Callback for each marked element
* @callback Mark~markRegExpEachCallback
* @param {HTMLElement} element - The marked DOM element
*/
/**
* Callback if there were no matches
* @callback Mark~markRegExpNoMatchCallback
* @param {RegExp} regexp - The regular expression
*/
/**
* Callback to filter matches
* @callback Mark~markRegExpFilterCallback
* @param {HTMLElement} textNode - The text node which includes the match
* @param {string} match - The matching string for the RegExp
* @param {number} counter - A counter indicating the number of all marks
*/
/**
* These options also include the common options from
* {@link Mark~commonOptions}
* @typedef Mark~markRegExpOptions
* @type {object.<string>}
* @property {Mark~markRegExpEachCallback} [each]
* @property {Mark~markRegExpNoMatchCallback} [noMatch]
* @property {Mark~markRegExpFilterCallback} [filter]
*/
/**
* Marks a custom regular expression
* @param {RegExp} regexp - The regular expression
* @param {Mark~markRegExpOptions} [opt] - Optional options object
* @access public
*/
markRegExp(regexp, opt) {
this.opt = opt;
this.log(`Searching with expression "${regexp}"`);
let totalMatches = 0, fn = "wrapMatches";
const eachCb = (element) => {
totalMatches++;
this.opt.each(element);
};
if (this.opt.acrossElements) {
fn = "wrapMatchesAcrossElements";
}
this[fn](regexp, this.opt.ignoreGroups, (match, node) => {
return this.opt.filter(node, match, totalMatches);
}, eachCb, () => {
if (totalMatches === 0) {
this.opt.noMatch(regexp);
}
this.opt.done(totalMatches);
});
}
/**
* Callback for each marked element
* @callback Mark~markEachCallback
* @param {HTMLElement} element - The marked DOM element
*/
/**
* Callback if there were no matches
* @callback Mark~markNoMatchCallback
* @param {RegExp} term - The search term that was not found
*/
/**
* Callback to filter matches
* @callback Mark~markFilterCallback
* @param {HTMLElement} textNode - The text node which includes the match
* @param {string} match - The matching term
* @param {number} totalCounter - A counter indicating the number of all
* marks
* @param {number} termCounter - A counter indicating the number of marks
* for the specific match
*/
/**
* @typedef Mark~markAccuracyObject
* @type {object.<string>}
* @property {string} value - A accuracy string value
* @property {string[]} limiters - A custom array of limiters. For example
* <code>["-", ","]</code>
*/
/**
* @typedef Mark~markAccuracySetting
* @type {string}
* @property {"partially"|"complementary"|"exactly"|Mark~markAccuracyObject}
* [accuracy="partially"] - Either one of the following string values:
* <ul>
* <li><i>partially</i>: When searching for "lor" only "lor" inside
* "lorem" will be marked</li>
* <li><i>complementary</i>: When searching for "lor" the whole word
* "lorem" will be marked</li>
* <li><i>exactly</i>: When searching for "lor" only those exact words
* will be marked. In this example nothing inside "lorem". This value
* is equivalent to the previous option <i>wordBoundary</i></li>
* </ul>
* Or an object containing two properties:
* <ul>
* <li><i>value</i>: One of the above named string values</li>
* <li><i>limiters</i>: A custom array of string limiters for accuracy
* "exactly" or "complementary"</li>
* </ul>
*/
/**
* @typedef Mark~markWildcardsSetting
* @type {string}
* @property {"disabled"|"enabled"|"withSpaces"}
* [wildcards="disabled"] - Set to any of the following string values:
* <ul>
* <li><i>disabled</i>: Disable wildcard usage</li>
* <li><i>enabled</i>: When searching for "lor?m", the "?" will match zero
* or one non-space character (e.g. "lorm", "loram", "lor3m", etc). When
* searching for "lor*m", the "*" will match zero or more non-space
* characters (e.g. "lorm", "loram", "lor123m", etc).</li>
* <li><i>withSpaces</i>: When searching for "lor?m", the "?" will
* match zero or one space or non-space character (e.g. "lor m", "loram",
* etc). When searching for "lor*m", the "*" will match zero or more space
* or non-space characters (e.g. "lorm", "lore et dolor ipsum", "lor: m",
* etc).</li>
* </ul>
*/
/**
* @typedef Mark~markIgnorePunctuationSetting
* @type {string[]}
* @property {string} The strings in this setting will contain punctuation
* marks that will be ignored:
* <ul>
* <li>These punctuation marks can be between any characters, e.g. setting
* this option to <code>["'"]</code> would match "Worlds", "World's" and
* "Wo'rlds"</li>
* <li>One or more apostrophes between the letters would still produce a
* match (e.g. "W'o''r'l'd's").</li>
* <li>A typical setting for this option could be as follows:
* <pre>ignorePunctuation: ":;.,-_(){}[]!'\"+=".split(""),</pre> This
* setting includes common punctuation as well as a minus, en-dash,
* em-dash and figure-dash
* ({@link https://en.wikipedia.org/wiki/Dash#Figure_dash ref}), as well
* as an underscore.</li>
* </ul>
*/
/**
* These options also include the common options from
* {@link Mark~commonOptions}
* @typedef Mark~markOptions
* @type {object.<string>}
* @property {boolean} [separateWordSearch=true] - Whether to search for
* each word separated by a blank instead of the complete term
* @property {boolean} [diacritics=true] - If diacritic characters should be
* matched. ({@link https://en.wikipedia.org/wiki/Diacritic Diacritics})
* @property {object} [synonyms] - An object with synonyms. The key will be
* a synonym for the value and the value for the key
* @property {Mark~markAccuracySetting} [accuracy]
* @property {Mark~markWildcardsSetting} [wildcards]
* @property {boolean} [acrossElements=false] - Whether to find matches
* across HTML elements. By default, only matches within single HTML
* elements will be found
* @property {boolean} [ignoreJoiners=false] - Whether to ignore word
* joiners inside of key words. These include soft-hyphens, zero-width
* space, zero-width non-joiners and zero-width joiners.
* @property {Mark~markIgnorePunctuationSetting} [ignorePunctuation]
* @property {Mark~markEachCallback} [each]
* @property {Mark~markNoMatchCallback} [noMatch]
* @property {Mark~markFilterCallback} [filter]
*/
/**
* Marks the specified search terms
* @param {string|string[]} [sv] - Search value, either a search string or
* an array containing multiple search strings
* @param {Mark~markOptions} [opt] - Optional options object
* @access public
*/
mark(sv, opt) {
this.opt = opt;
let totalMatches = 0, fn = "wrapMatches";
const {
keywords: kwArr,
length: kwArrLen
} = this.getSeparatedKeywords(typeof sv === "string" ? [sv] : sv), sens = this.opt.caseSensitive ? "" : "i", handler = (kw) => {
let regex = new RegExp(this.createRegExp(kw), `gm${sens}`), matches2 = 0;
this.log(`Searching with expression "${regex}"`);
this[fn](regex, 1, (term, node) => {
return this.opt.filter(node, kw, totalMatches, matches2);
}, (element) => {
matches2++;
totalMatches++;
this.opt.each(element);
}, () => {
if (matches2 === 0) {
this.opt.noMatch(kw);
}
if (kwArr[kwArrLen - 1] === kw) {
this.opt.done(totalMatches);
} else {
handler(kwArr[kwArr.indexOf(kw) + 1]);
}
});
};
if (this.opt.acrossElements) {
fn = "wrapMatchesAcrossElements";
}
if (kwArrLen === 0) {
this.opt.done(totalMatches);
} else {
handler(kwArr[0]);
}
}
/**
* Callback for each marked element
* @callback Mark~markRangesEachCallback
* @param {HTMLElement} element - The marked DOM element
* @param {array} range - array of range start and end points
*/
/**
* Callback if a processed range is invalid, out-of-bounds, overlaps another
* range, or only matches whitespace
* @callback Mark~markRangesNoMatchCallback
* @param {Mark~rangeObject} range - a range object
*/
/**
* Callback to filter matches
* @callback Mark~markRangesFilterCallback
* @param {HTMLElement} node - The text node which includes the range
* @param {array} range - array of range start and end points
* @param {string} match - string extracted from the matching range
* @param {number} counter - A counter indicating the number of all marks
*/
/**
* These options also include the common options from
* {@link Mark~commonOptions}
* @typedef Mark~markRangesOptions
* @type {object.<string>}
* @property {Mark~markRangesEachCallback} [each]
* @property {Mark~markRangesNoMatchCallback} [noMatch]
* @property {Mark~markRangesFilterCallback} [filter]
*/
/**
* Marks an array of objects containing a start with an end or length of the
* string to mark
* @param {Mark~setOfRanges} rawRanges - The original (preprocessed)
* array of objects
* @param {Mark~markRangesOptions} [opt] - Optional options object
* @access public
*/
markRanges(rawRanges, opt) {
this.opt = opt;
let totalMatches = 0, ranges = this.checkRanges(rawRanges);
if (ranges && ranges.length) {
this.log(
"Starting to mark with the following ranges: " + JSON.stringify(ranges)
);
this.wrapRangeFromIndex(
ranges,
(node, range, match, counter) => {
return this.opt.filter(node, range, match, counter);
},
(element, range) => {
totalMatches++;
this.opt.each(element, range);
},
() => {
this.opt.done(totalMatches);
}
);
} else {
this.opt.done(totalMatches);
}
}
/**
* Removes all marked elements inside the context with their HTML and
* normalizes the parent at the end
* @param {Mark~commonOptions} [opt] - Optional options object
* @access public
*/
unmark(opt) {
this.opt = opt;
let sel = this.opt.element ? this.opt.element : "*";
sel += "[data-markjs]";
if (this.opt.className) {
sel += `.${this.opt.className}`;
}
this.log(`Removal selector "${sel}"`);
this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT, (node) => {
this.unwrapMatches(node);
}, (node) => {
const matchesSel = DOMIterator.matches(node, sel), matchesExclude = this.matchesExclude(node);
if (!matchesSel || matchesExclude) {
return NodeFilter.FILTER_REJECT;
} else {
return NodeFilter.FILTER_ACCEPT;
}
}, this.opt.done);
}
};
function Mark2(ctx) {
const instance = new Mark$1(ctx);
this.mark = (sv, opt) => {
instance.mark(sv, opt);
return this;
};
this.markRegExp = (sv, opt) => {
instance.markRegExp(sv, opt);
return this;
};
this.markRanges = (sv, opt) => {
instance.markRanges(sv, opt);
return this;
};
this.unmark = (opt) => {
instance.unmark(opt);
return this;
};
return this;
}
var __assign = function() {
__assign = Object.assign || function __assign2(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s)
if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P ? value : new P(function(resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function(resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() {
if (t[0] & 1)
throw t[1];
return t[1];
}, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
return this;
}), g;
function verb(n) {
return function(v) {
return step([n, v]);
};
}
function step(op) {
if (f)
throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _)
try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
return t;
if (y = 0, t)
op = [op[0] & 2, t.value];
switch (op[0]) {
case 0:
case 1:
t = op;
break;
case 4:
_.label++;
return { value: op[1], done: false };
case 5:
_.label++;
y = op[1];
op = [0];
continue;
case 7:
op = _.ops.pop();
_.trys.pop();
continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
_ = 0;
continue;
}
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
_.label = op[1];
break;
}
if (op[0] === 6 && _.label < t[1]) {
_.label = t[1];
t = op;
break;
}
if (t && _.label < t[2]) {
_.label = t[2];
_.ops.push(op);
break;
}
if (t[2])
_.ops.pop();
_.trys.pop();
continue;
}
op = body.call(thisArg, _);
} catch (e) {
op = [6, e];
y = 0;
} finally {
f = t = 0;
}
if (op[0] & 5)
throw op[1];
return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m)
return m.call(o);
if (o && typeof o.length === "number")
return {
next: function() {
if (o && i >= o.length)
o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m)
return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
ar.push(r.value);
} catch (error) {
e = { error };
} finally {
try {
if (r && !r.done && (m = i["return"]))
m.call(i);
} finally {
if (e)
throw e.error;
}
}
return ar;
}
typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
var ENTRIES = "ENTRIES";
var KEYS = "KEYS";
var VALUES = "VALUES";
var LEAF = "";
var TreeIterator = (
/** @class */
function() {
function TreeIterator2(set, type) {
var node = set._tree;
var keys = Array.from(node.keys());
this.set = set;
this._type = type;
this._path = keys.length > 0 ? [{ node, keys }] : [];
}
TreeIterator2.prototype.next = function() {
var value = this.dive();
this.backtrack();
return value;
};
TreeIterator2.prototype.dive = function() {
if (this._path.length === 0) {
return { done: true, value: void 0 };
}
var _a2 = last$1(this._path), node = _a2.node, keys = _a2.keys;
if (last$1(keys) === LEAF) {
return { done: false, value: this.result() };
}
var child = node.get(last$1(keys));
this._path.push({ node: child, keys: Array.from(child.keys()) });
return this.dive();
};
TreeIterator2.prototype.backtrack = function() {
if (this._path.length === 0) {
return;
}
var keys = last$1(this._path).keys;
keys.pop();
if (keys.length > 0) {
return;
}
this._path.pop();
this.backtrack();
};
TreeIterator2.prototype.key = function() {
return this.set._prefix + this._path.map(function(_a2) {
var keys = _a2.keys;
return last$1(keys);
}).filter(function(key) {
return key !== LEAF;
}).join("");
};
TreeIterator2.prototype.value = function() {
return last$1(this._path).node.get(LEAF);
};
TreeIterator2.prototype.result = function() {
switch (this._type) {
case VALUES:
return this.value();
case KEYS:
return this.key();
default:
return [this.key(), this.value()];
}
};
TreeIterator2.prototype[Symbol.iterator] = function() {
return this;
};
return TreeIterator2;
}()
);
var last$1 = function(array) {
return array[array.length - 1];
};
var fuzzySearch = function(node, query, maxDistance) {
var results = /* @__PURE__ */ new Map();
if (query === void 0)
return results;
var n = query.length + 1;
var m = n + maxDistance;
var matrix = new Uint8Array(m * n).fill(maxDistance + 1);
for (var j = 0; j < n; ++j)
matrix[j] = j;
for (var i = 1; i < m; ++i)
matrix[i * n] = i;
recurse(node, query, maxDistance, results, matrix, 1, n, "");
return results;
};
var recurse = function(node, query, maxDistance, results, matrix, m, n, prefix) {
var e_1, _a2;
var offset = m * n;
try {
key:
for (var _b = __values(node.keys()), _c = _b.next(); !_c.done; _c = _b.next()) {
var key = _c.value;
if (key === LEAF) {
var distance = matrix[offset - 1];
if (distance <= maxDistance) {
results.set(prefix, [node.get(key), distance]);
}
} else {
var i = m;
for (var pos = 0; pos < key.length; ++pos, ++i) {
var char = key[pos];
var thisRowOffset = n * i;
var prevRowOffset = thisRowOffset - n;
var minDistance = matrix[thisRowOffset];
var jmin = Math.max(0, i - maxDistance - 1);
var jmax = Math.min(n - 1, i + maxDistance);
for (var j = jmin; j < jmax; ++j) {
var different = char !== query[j];
var rpl = matrix[prevRowOffset + j] + +different;
var del = matrix[prevRowOffset + j + 1] + 1;
var ins = matrix[thisRowOffset + j] + 1;
var dist = matrix[thisRowOffset + j + 1] = Math.min(rpl, del, ins);
if (dist < minDistance)
minDistance = dist;
}
if (minDistance > maxDistance) {
continue key;
}
}
recurse(node.get(key), query, maxDistance, results, matrix, i, n, prefix + key);
}
}
} catch (e_1_1) {
e_1 = { error: e_1_1 };
} finally {
try {
if (_c && !_c.done && (_a2 = _b.return))
_a2.call(_b);
} finally {
if (e_1)
throw e_1.error;
}
}
};
var SearchableMap = (
/** @class */
function() {
function SearchableMap2(tree, prefix) {
if (tree === void 0) {
tree = /* @__PURE__ */ new Map();
}
if (prefix === void 0) {
prefix = "";
}
this._size = void 0;
this._tree = tree;
this._prefix = prefix;
}
SearchableMap2.prototype.atPrefix = function(prefix) {
var e_1, _a2;
if (!prefix.startsWith(this._prefix)) {
throw new Error("Mismatched prefix");
}
var _b = __read(trackDown(this._tree, prefix.slice(this._prefix.length)), 2), node = _b[0], path = _b[1];
if (node === void 0) {
var _c = __read(last(path), 2), parentNode = _c[0], key = _c[1];
try {
for (var _d = __values(parentNode.keys()), _e = _d.next(); !_e.done; _e = _d.next()) {
var k = _e.value;
if (k !== LEAF && k.startsWith(key)) {
var node_1 = /* @__PURE__ */ new Map();
node_1.set(k.slice(key.length), parentNode.get(k));
return new SearchableMap2(node_1, prefix);
}
}
} catch (e_1_1) {
e_1 = { error: e_1_1 };
} finally {
try {
if (_e && !_e.done && (_a2 = _d.return))
_a2.call(_d);
} finally {
if (e_1)
throw e_1.error;
}
}
}
return new SearchableMap2(node, prefix);
};
SearchableMap2.prototype.clear = function() {
this._size = void 0;
this._tree.clear();
};
SearchableMap2.prototype.delete = function(key) {
this._size = void 0;
return remove(this._tree, key);
};
SearchableMap2.prototype.entries = function() {
return new TreeIterator(this, ENTRIES);
};
SearchableMap2.prototype.forEach = function(fn) {
var e_2, _a2;
try {
for (var _b = __values(this), _c = _b.next(); !_c.done; _c = _b.next()) {
var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
fn(key, value, this);
}
} catch (e_2_1) {
e_2 = { error: e_2_1 };
} finally {
try {
if (_c && !_c.done && (_a2 = _b.return))
_a2.call(_b);
} finally {
if (e_2)
throw e_2.error;
}
}
};
SearchableMap2.prototype.fuzzyGet = function(key, maxEditDistance) {
return fuzzySearch(this._tree, key, maxEditDistance);
};
SearchableMap2.prototype.get = function(key) {
var node = lookup(this._tree, key);
return node !== void 0 ? node.get(LEAF) : void 0;
};
SearchableMap2.prototype.has = function(key) {
var node = lookup(this._tree, key);
return node !== void 0 && node.has(LEAF);
};
SearchableMap2.prototype.keys = function() {
return new TreeIterator(this, KEYS);
};
SearchableMap2.prototype.set = function(key, value) {
if (typeof key !== "string") {
throw new Error("key must be a string");
}
this._size = void 0;
var node = createPath(this._tree, key);
node.set(LEAF, value);
return this;
};
Object.defineProperty(SearchableMap2.prototype, "size", {
/**
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size
*/
get: function() {
if (this._size) {
return this._size;
}
this._size = 0;
var iter = this.entries();
while (!iter.next().done)
this._size += 1;
return this._size;
},
enumerable: false,
configurable: true
});
SearchableMap2.prototype.update = function(key, fn) {
if (typeof key !== "string") {
throw new Error("key must be a string");
}
this._size = void 0;
var node = createPath(this._tree, key);
node.set(LEAF, fn(node.get(LEAF)));
return this;
};
SearchableMap2.prototype.fetch = function(key, initial) {
if (typeof key !== "string") {
throw new Error("key must be a string");
}
this._size = void 0;
var node = createPath(this._tree, key);
var value = node.get(LEAF);
if (value === void 0) {
node.set(LEAF, value = initial());
}
return value;
};
SearchableMap2.prototype.values = function() {
return new TreeIterator(this, VALUES);
};
SearchableMap2.prototype[Symbol.iterator] = function() {
return this.entries();
};
SearchableMap2.from = function(entries) {
var e_3, _a2;
var tree = new SearchableMap2();
try {
for (var entries_1 = __values(entries), entries_1_1 = entries_1.next(); !entries_1_1.done; entries_1_1 = entries_1.next()) {
var _b = __read(entries_1_1.value, 2), key = _b[0], value = _b[1];
tree.set(key, value);
}
} catch (e_3_1) {
e_3 = { error: e_3_1 };
} finally {
try {
if (entries_1_1 && !entries_1_1.done && (_a2 = entries_1.return))
_a2.call(entries_1);
} finally {
if (e_3)
throw e_3.error;
}
}
return tree;
};
SearchableMap2.fromObject = function(object) {
return SearchableMap2.from(Object.entries(object));
};
return SearchableMap2;
}()
);
var trackDown = function(tree, key, path) {
var e_4, _a2;
if (path === void 0) {
path = [];
}
if (key.length === 0 || tree == null) {
return [tree, path];
}
try {
for (var _b = __values(tree.keys()), _c = _b.next(); !_c.done; _c = _b.next()) {
var k = _c.value;
if (k !== LEAF && key.startsWith(k)) {
path.push([tree, k]);
return trackDown(tree.get(k), key.slice(k.length), path);
}
}
} catch (e_4_1) {
e_4 = { error: e_4_1 };
} finally {
try {
if (_c && !_c.done && (_a2 = _b.return))
_a2.call(_b);
} finally {
if (e_4)
throw e_4.error;
}
}
path.push([tree, key]);
return trackDown(void 0, "", path);
};
var lookup = function(tree, key) {
var e_5, _a2;
if (key.length === 0 || tree == null) {
return tree;
}
try {
for (var _b = __values(tree.keys()), _c = _b.next(); !_c.done; _c = _b.next()) {
var k = _c.value;
if (k !== LEAF && key.startsWith(k)) {
return lookup(tree.get(k), key.slice(k.length));
}
}
} catch (e_5_1) {
e_5 = { error: e_5_1 };
} finally {
try {
if (_c && !_c.done && (_a2 = _b.return))
_a2.call(_b);
} finally {
if (e_5)
throw e_5.error;
}
}
};
var createPath = function(node, key) {
var e_6, _a2;
var keyLength = key.length;
outer:
for (var pos = 0; node && pos < keyLength; ) {
try {
for (var _b = (e_6 = void 0, __values(node.keys())), _c = _b.next(); !_c.done; _c = _b.next()) {
var k = _c.value;
if (k !== LEAF && key[pos] === k[0]) {
var len = Math.min(keyLength - pos, k.length);
var offset = 1;
while (offset < len && key[pos + offset] === k[offset])
++offset;
var child_1 = node.get(k);
if (offset === k.length) {
node = child_1;
} else {
var intermediate = /* @__PURE__ */ new Map();
intermediate.set(k.slice(offset), child_1);
node.set(key.slice(pos, pos + offset), intermediate);
node.delete(k);
node = intermediate;
}
pos += offset;
continue outer;
}
}
} catch (e_6_1) {
e_6 = { error: e_6_1 };
} finally {
try {
if (_c && !_c.done && (_a2 = _b.return))
_a2.call(_b);
} finally {
if (e_6)
throw e_6.error;
}
}
var child = /* @__PURE__ */ new Map();
node.set(key.slice(pos), child);
return child;
}
return node;
};
var remove = function(tree, key) {
var _a2 = __read(trackDown(tree, key), 2), node = _a2[0], path = _a2[1];
if (node === void 0) {
return;
}
node.delete(LEAF);
if (node.size === 0) {
cleanup(path);
} else if (node.size === 1) {
var _b = __read(node.entries().next().value, 2), key_1 = _b[0], value = _b[1];
merge(path, key_1, value);
}
};
var cleanup = function(path) {
if (path.length === 0) {
return;
}
var _a2 = __read(last(path), 2), node = _a2[0], key = _a2[1];
node.delete(key);
if (node.size === 0) {
cleanup(path.slice(0, -1));
} else if (node.size === 1) {
var _b = __read(node.entries().next().value, 2), key_2 = _b[0], value = _b[1];
if (key_2 !== LEAF) {
merge(path.slice(0, -1), key_2, value);
}
}
};
var merge = function(path, key, value) {
if (path.length === 0) {
return;
}
var _a2 = __read(last(path), 2), node = _a2[0], nodeKey = _a2[1];
node.set(nodeKey + key, value);
node.delete(nodeKey);
};
var last = function(array) {
return array[array.length - 1];
};
var _a;
var OR = "or";
var AND = "and";
var AND_NOT = "and_not";
var MiniSearch = (
/** @class */
function() {
function MiniSearch2(options) {
if ((options === null || options === void 0 ? void 0 : options.fields) == null) {
throw new Error('MiniSearch: option "fields" must be provided');
}
var autoVacuum = options.autoVacuum == null || options.autoVacuum === true ? defaultAutoVacuumOptions : options.autoVacuum;
this._options = __assign(__assign(__assign({}, defaultOptions), options), { autoVacuum, searchOptions: __assign(__assign({}, defaultSearchOptions), options.searchOptions || {}), autoSuggestOptions: __assign(__assign({}, defaultAutoSuggestOptions), options.autoSuggestOptions || {}) });
this._index = new SearchableMap();
this._documentCount = 0;
this._documentIds = /* @__PURE__ */ new Map();
this._idToShortId = /* @__PURE__ */ new Map();
this._fieldIds = {};
this._fieldLength = /* @__PURE__ */ new Map();
this._avgFieldLength = [];
this._nextId = 0;
this._storedFields = /* @__PURE__ */ new Map();
this._dirtCount = 0;
this._currentVacuum = null;
this._enqueuedVacuum = null;
this._enqueuedVacuumConditions = defaultVacuumConditions;
this.addFields(this._options.fields);
}
MiniSearch2.prototype.add = function(document2) {
var e_1, _a2, e_2, _b, e_3, _c;
var _d = this._options, extractField = _d.extractField, tokenize = _d.tokenize, processTerm = _d.processTerm, fields = _d.fields, idField = _d.idField;
var id = extractField(document2, idField);
if (id == null) {
throw new Error('MiniSearch: document does not have ID field "'.concat(idField, '"'));
}
if (this._idToShortId.has(id)) {
throw new Error("MiniSearch: duplicate ID ".concat(id));
}
var shortDocumentId = this.addDocumentId(id);
this.saveStoredFields(shortDocumentId, document2);
try {
for (var fields_1 = __values(fields), fields_1_1 = fields_1.next(); !fields_1_1.done; fields_1_1 = fields_1.next()) {
var field = fields_1_1.value;
var fieldValue = extractField(document2, field);
if (fieldValue == null)
continue;
var tokens = tokenize(fieldValue.toString(), field);
var fieldId = this._fieldIds[field];
var uniqueTerms = new Set(tokens).size;
this.addFieldLength(shortDocumentId, fieldId, this._documentCount - 1, uniqueTerms);
try {
for (var tokens_1 = (e_2 = void 0, __values(tokens)), tokens_1_1 = tokens_1.next(); !tokens_1_1.done; tokens_1_1 = tokens_1.next()) {
var term = tokens_1_1.value;
var processedTerm = processTerm(term, field);
if (Array.isArray(processedTerm)) {
try {
for (var processedTerm_1 = (e_3 = void 0, __values(processedTerm)), processedTerm_1_1 = processedTerm_1.next(); !processedTerm_1_1.done; processedTerm_1_1 = processedTerm_1.next()) {
var t = processedTerm_1_1.value;
this.addTerm(fieldId, shortDocumentId, t);
}
} catch (e_3_1) {
e_3 = { error: e_3_1 };
} finally {
try {
if (processedTerm_1_1 && !processedTerm_1_1.done && (_c = processedTerm_1.return))
_c.call(processedTerm_1);
} finally {
if (e_3)
throw e_3.error;
}
}
} else if (processedTerm) {
this.addTerm(fieldId, shortDocumentId, processedTerm);
}
}
} catch (e_2_1) {
e_2 = { error: e_2_1 };
} finally {
try {
if (tokens_1_1 && !tokens_1_1.done && (_b = tokens_1.return))
_b.call(tokens_1);
} finally {
if (e_2)
throw e_2.error;
}
}
}
} catch (e_1_1) {
e_1 = { error: e_1_1 };
} finally {
try {
if (fields_1_1 && !fields_1_1.done && (_a2 = fields_1.return))
_a2.call(fields_1);
} finally {
if (e_1)
throw e_1.error;
}
}
};
MiniSearch2.prototype.addAll = function(documents) {
var e_4, _a2;
try {
for (var documents_1 = __values(documents), documents_1_1 = documents_1.next(); !documents_1_1.done; documents_1_1 = documents_1.next()) {
var document_1 = documents_1_1.value;
this.add(document_1);
}
} catch (e_4_1) {
e_4 = { error: e_4_1 };
} finally {
try {
if (documents_1_1 && !documents_1_1.done && (_a2 = documents_1.return))
_a2.call(documents_1);
} finally {
if (e_4)
throw e_4.error;
}
}
};
MiniSearch2.prototype.addAllAsync = function(documents, options) {
var _this = this;
if (options === void 0) {
options = {};
}
var _a2 = options.chunkSize, chunkSize = _a2 === void 0 ? 10 : _a2;
var acc = { chunk: [], promise: Promise.resolve() };
var _b = documents.reduce(function(_a3, document2, i) {
var chunk2 = _a3.chunk, promise2 = _a3.promise;
chunk2.push(document2);
if ((i + 1) % chunkSize === 0) {
return {
chunk: [],
promise: promise2.then(function() {
return new Promise(function(resolve) {
return setTimeout(resolve, 0);
});
}).then(function() {
return _this.addAll(chunk2);
})
};
} else {
return { chunk: chunk2, promise: promise2 };
}
}, acc), chunk = _b.chunk, promise = _b.promise;
return promise.then(function() {
return _this.addAll(chunk);
});
};
MiniSearch2.prototype.remove = function(document2) {
var e_5, _a2, e_6, _b, e_7, _c;
var _d = this._options, tokenize = _d.tokenize, processTerm = _d.processTerm, extractField = _d.extractField, fields = _d.fields, idField = _d.idField;
var id = extractField(document2, idField);
if (id == null) {
throw new Error('MiniSearch: document does not have ID field "'.concat(idField, '"'));
}
var shortId = this._idToShortId.get(id);
if (shortId == null) {
throw new Error("MiniSearch: cannot remove document with ID ".concat(id, ": it is not in the index"));
}
try {
for (var fields_2 = __values(fields), fields_2_1 = fields_2.next(); !fields_2_1.done; fields_2_1 = fields_2.next()) {
var field = fields_2_1.value;
var fieldValue = extractField(document2, field);
if (fieldValue == null)
continue;
var tokens = tokenize(fieldValue.toString(), field);
var fieldId = this._fieldIds[field];
var uniqueTerms = new Set(tokens).size;
this.removeFieldLength(shortId, fieldId, this._documentCount, uniqueTerms);
try {
for (var tokens_2 = (e_6 = void 0, __values(tokens)), tokens_2_1 = tokens_2.next(); !tokens_2_1.done; tokens_2_1 = tokens_2.next()) {
var term = tokens_2_1.value;
var processedTerm = processTerm(term, field);
if (Array.isArray(processedTerm)) {
try {
for (var processedTerm_2 = (e_7 = void 0, __values(processedTerm)), processedTerm_2_1 = processedTerm_2.next(); !processedTerm_2_1.done; processedTerm_2_1 = processedTerm_2.next()) {
var t = processedTerm_2_1.value;
this.removeTerm(fieldId, shortId, t);
}
} catch (e_7_1) {
e_7 = { error: e_7_1 };
} finally {
try {
if (processedTerm_2_1 && !processedTerm_2_1.done && (_c = processedTerm_2.return))
_c.call(processedTerm_2);
} finally {
if (e_7)
throw e_7.error;
}
}
} else if (processedTerm) {
this.removeTerm(fieldId, shortId, processedTerm);
}
}
} catch (e_6_1) {
e_6 = { error: e_6_1 };
} finally {
try {
if (tokens_2_1 && !tokens_2_1.done && (_b = tokens_2.return))
_b.call(tokens_2);
} finally {
if (e_6)
throw e_6.error;
}
}
}
} catch (e_5_1) {
e_5 = { error: e_5_1 };
} finally {
try {
if (fields_2_1 && !fields_2_1.done && (_a2 = fields_2.return))
_a2.call(fields_2);
} finally {
if (e_5)
throw e_5.error;
}
}
this._storedFields.delete(shortId);
this._documentIds.delete(shortId);
this._idToShortId.delete(id);
this._fieldLength.delete(shortId);
this._documentCount -= 1;
};
MiniSearch2.prototype.removeAll = function(documents) {
var e_8, _a2;
if (documents) {
try {
for (var documents_2 = __values(documents), documents_2_1 = documents_2.next(); !documents_2_1.done; documents_2_1 = documents_2.next()) {
var document_2 = documents_2_1.value;
this.remove(document_2);
}
} catch (e_8_1) {
e_8 = { error: e_8_1 };
} finally {
try {
if (documents_2_1 && !documents_2_1.done && (_a2 = documents_2.return))
_a2.call(documents_2);
} finally {
if (e_8)
throw e_8.error;
}
}
} else if (arguments.length > 0) {
throw new Error("Expected documents to be present. Omit the argument to remove all documents.");
} else {
this._index = new SearchableMap();
this._documentCount = 0;
this._documentIds = /* @__PURE__ */ new Map();
this._idToShortId = /* @__PURE__ */ new Map();
this._fieldLength = /* @__PURE__ */ new Map();
this._avgFieldLength = [];
this._storedFields = /* @__PURE__ */ new Map();
this._nextId = 0;
}
};
MiniSearch2.prototype.discard = function(id) {
var _this = this;
var shortId = this._idToShortId.get(id);
if (shortId == null) {
throw new Error("MiniSearch: cannot discard document with ID ".concat(id, ": it is not in the index"));
}
this._idToShortId.delete(id);
this._documentIds.delete(shortId);
this._storedFields.delete(shortId);
(this._fieldLength.get(shortId) || []).forEach(function(fieldLength, fieldId) {
_this.removeFieldLength(shortId, fieldId, _this._documentCount, fieldLength);
});
this._fieldLength.delete(shortId);
this._documentCount -= 1;
this._dirtCount += 1;
this.maybeAutoVacuum();
};
MiniSearch2.prototype.maybeAutoVacuum = function() {
if (this._options.autoVacuum === false) {
return;
}
var _a2 = this._options.autoVacuum, minDirtFactor = _a2.minDirtFactor, minDirtCount = _a2.minDirtCount, batchSize = _a2.batchSize, batchWait = _a2.batchWait;
this.conditionalVacuum({ batchSize, batchWait }, { minDirtCount, minDirtFactor });
};
MiniSearch2.prototype.discardAll = function(ids) {
var e_9, _a2;
var autoVacuum = this._options.autoVacuum;
try {
this._options.autoVacuum = false;
try {
for (var ids_1 = __values(ids), ids_1_1 = ids_1.next(); !ids_1_1.done; ids_1_1 = ids_1.next()) {
var id = ids_1_1.value;
this.discard(id);
}
} catch (e_9_1) {
e_9 = { error: e_9_1 };
} finally {
try {
if (ids_1_1 && !ids_1_1.done && (_a2 = ids_1.return))
_a2.call(ids_1);
} finally {
if (e_9)
throw e_9.error;
}
}
} finally {
this._options.autoVacuum = autoVacuum;
}
this.maybeAutoVacuum();
};
MiniSearch2.prototype.replace = function(updatedDocument) {
var _a2 = this._options, idField = _a2.idField, extractField = _a2.extractField;
var id = extractField(updatedDocument, idField);
this.discard(id);
this.add(updatedDocument);
};
MiniSearch2.prototype.vacuum = function(options) {
if (options === void 0) {
options = {};
}
return this.conditionalVacuum(options);
};
MiniSearch2.prototype.conditionalVacuum = function(options, conditions) {
var _this = this;
if (this._currentVacuum) {
this._enqueuedVacuumConditions = this._enqueuedVacuumConditions && conditions;
if (this._enqueuedVacuum != null) {
return this._enqueuedVacuum;
}
this._enqueuedVacuum = this._currentVacuum.then(function() {
var conditions2 = _this._enqueuedVacuumConditions;
_this._enqueuedVacuumConditions = defaultVacuumConditions;
return _this.performVacuuming(options, conditions2);
});
return this._enqueuedVacuum;
}
if (this.vacuumConditionsMet(conditions) === false) {
return Promise.resolve();
}
this._currentVacuum = this.performVacuuming(options);
return this._currentVacuum;
};
MiniSearch2.prototype.performVacuuming = function(options, conditions) {
return __awaiter(this, void 0, void 0, function() {
var initialDirtCount, batchSize, batchWait_1, i, _a2, _b, _c, term, fieldsData, fieldsData_1, fieldsData_1_1, _d, fieldId, fieldIndex, fieldIndex_1, fieldIndex_1_1, _e, shortId, e_10_1;
var e_10, _f, e_11, _g, e_12, _h;
return __generator(this, function(_j) {
switch (_j.label) {
case 0:
initialDirtCount = this._dirtCount;
if (!this.vacuumConditionsMet(conditions))
return [3, 10];
batchSize = options.batchSize || defaultVacuumOptions.batchSize;
batchWait_1 = options.batchWait || defaultVacuumOptions.batchWait;
i = 1;
_j.label = 1;
case 1:
_j.trys.push([1, 7, 8, 9]);
_a2 = __values(this._index), _b = _a2.next();
_j.label = 2;
case 2:
if (!!_b.done)
return [3, 6];
_c = __read(_b.value, 2), term = _c[0], fieldsData = _c[1];
try {
for (fieldsData_1 = (e_11 = void 0, __values(fieldsData)), fieldsData_1_1 = fieldsData_1.next(); !fieldsData_1_1.done; fieldsData_1_1 = fieldsData_1.next()) {
_d = __read(fieldsData_1_1.value, 2), fieldId = _d[0], fieldIndex = _d[1];
try {
for (fieldIndex_1 = (e_12 = void 0, __values(fieldIndex)), fieldIndex_1_1 = fieldIndex_1.next(); !fieldIndex_1_1.done; fieldIndex_1_1 = fieldIndex_1.next()) {
_e = __read(fieldIndex_1_1.value, 1), shortId = _e[0];
if (this._documentIds.has(shortId)) {
continue;
}
if (fieldIndex.size <= 1) {
fieldsData.delete(fieldId);
} else {
fieldIndex.delete(shortId);
}
}
} catch (e_12_1) {
e_12 = { error: e_12_1 };
} finally {
try {
if (fieldIndex_1_1 && !fieldIndex_1_1.done && (_h = fieldIndex_1.return))
_h.call(fieldIndex_1);
} finally {
if (e_12)
throw e_12.error;
}
}
}
} catch (e_11_1) {
e_11 = { error: e_11_1 };
} finally {
try {
if (fieldsData_1_1 && !fieldsData_1_1.done && (_g = fieldsData_1.return))
_g.call(fieldsData_1);
} finally {
if (e_11)
throw e_11.error;
}
}
if (this._index.get(term).size === 0) {
this._index.delete(term);
}
if (!(i % batchSize === 0))
return [3, 4];
return [4, new Promise(function(resolve) {
return setTimeout(resolve, batchWait_1);
})];
case 3:
_j.sent();
_j.label = 4;
case 4:
i += 1;
_j.label = 5;
case 5:
_b = _a2.next();
return [3, 2];
case 6:
return [3, 9];
case 7:
e_10_1 = _j.sent();
e_10 = { error: e_10_1 };
return [3, 9];
case 8:
try {
if (_b && !_b.done && (_f = _a2.return))
_f.call(_a2);
} finally {
if (e_10)
throw e_10.error;
}
return [
7
/*endfinally*/
];
case 9:
this._dirtCount -= initialDirtCount;
_j.label = 10;
case 10:
return [4, null];
case 11:
_j.sent();
this._currentVacuum = this._enqueuedVacuum;
this._enqueuedVacuum = null;
return [
2
/*return*/
];
}
});
});
};
MiniSearch2.prototype.vacuumConditionsMet = function(conditions) {
if (conditions == null) {
return true;
}
var minDirtCount = conditions.minDirtCount, minDirtFactor = conditions.minDirtFactor;
minDirtCount = minDirtCount || defaultAutoVacuumOptions.minDirtCount;
minDirtFactor = minDirtFactor || defaultAutoVacuumOptions.minDirtFactor;
return this.dirtCount >= minDirtCount && this.dirtFactor >= minDirtFactor;
};
Object.defineProperty(MiniSearch2.prototype, "isVacuuming", {
/**
* Is `true` if a vacuuming operation is ongoing, `false` otherwise
*/
get: function() {
return this._currentVacuum != null;
},
enumerable: false,
configurable: true
});
Object.defineProperty(MiniSearch2.prototype, "dirtCount", {
/**
* The number of documents discarded since the most recent vacuuming
*/
get: function() {
return this._dirtCount;
},
enumerable: false,
configurable: true
});
Object.defineProperty(MiniSearch2.prototype, "dirtFactor", {
/**
* A number between 0 and 1 giving an indication about the proportion of
* documents that are discarded, and can therefore be cleaned up by vacuuming.
* A value close to 0 means that the index is relatively clean, while a higher
* value means that the index is relatively dirty, and vacuuming could release
* memory.
*/
get: function() {
return this._dirtCount / (1 + this._documentCount + this._dirtCount);
},
enumerable: false,
configurable: true
});
MiniSearch2.prototype.has = function(id) {
return this._idToShortId.has(id);
};
MiniSearch2.prototype.getStoredFields = function(id) {
var shortId = this._idToShortId.get(id);
if (shortId == null) {
return void 0;
}
return this._storedFields.get(shortId);
};
MiniSearch2.prototype.search = function(query, searchOptions) {
var e_13, _a2;
if (searchOptions === void 0) {
searchOptions = {};
}
var rawResults = this.executeQuery(query, searchOptions);
var results = [];
try {
for (var rawResults_1 = __values(rawResults), rawResults_1_1 = rawResults_1.next(); !rawResults_1_1.done; rawResults_1_1 = rawResults_1.next()) {
var _b = __read(rawResults_1_1.value, 2), docId = _b[0], _c = _b[1], score = _c.score, terms = _c.terms, match = _c.match;
var quality = terms.length || 1;
var result = {
id: this._documentIds.get(docId),
score: score * quality,
terms: Object.keys(match),
queryTerms: terms,
match
};
Object.assign(result, this._storedFields.get(docId));
if (searchOptions.filter == null || searchOptions.filter(result)) {
results.push(result);
}
}
} catch (e_13_1) {
e_13 = { error: e_13_1 };
} finally {
try {
if (rawResults_1_1 && !rawResults_1_1.done && (_a2 = rawResults_1.return))
_a2.call(rawResults_1);
} finally {
if (e_13)
throw e_13.error;
}
}
if (query === MiniSearch2.wildcard && searchOptions.boostDocument == null && this._options.searchOptions.boostDocument == null) {
return results;
}
results.sort(byScore);
return results;
};
MiniSearch2.prototype.autoSuggest = function(queryString, options) {
var e_14, _a2, e_15, _b;
if (options === void 0) {
options = {};
}
options = __assign(__assign({}, this._options.autoSuggestOptions), options);
var suggestions = /* @__PURE__ */ new Map();
try {
for (var _c = __values(this.search(queryString, options)), _d = _c.next(); !_d.done; _d = _c.next()) {
var _e = _d.value, score = _e.score, terms = _e.terms;
var phrase = terms.join(" ");
var suggestion = suggestions.get(phrase);
if (suggestion != null) {
suggestion.score += score;
suggestion.count += 1;
} else {
suggestions.set(phrase, { score, terms, count: 1 });
}
}
} catch (e_14_1) {
e_14 = { error: e_14_1 };
} finally {
try {
if (_d && !_d.done && (_a2 = _c.return))
_a2.call(_c);
} finally {
if (e_14)
throw e_14.error;
}
}
var results = [];
try {
for (var suggestions_1 = __values(suggestions), suggestions_1_1 = suggestions_1.next(); !suggestions_1_1.done; suggestions_1_1 = suggestions_1.next()) {
var _f = __read(suggestions_1_1.value, 2), suggestion = _f[0], _g = _f[1], score = _g.score, terms = _g.terms, count = _g.count;
results.push({ suggestion, terms, score: score / count });
}
} catch (e_15_1) {
e_15 = { error: e_15_1 };
} finally {
try {
if (suggestions_1_1 && !suggestions_1_1.done && (_b = suggestions_1.return))
_b.call(suggestions_1);
} finally {
if (e_15)
throw e_15.error;
}
}
results.sort(byScore);
return results;
};
Object.defineProperty(MiniSearch2.prototype, "documentCount", {
/**
* Total number of documents available to search
*/
get: function() {
return this._documentCount;
},
enumerable: false,
configurable: true
});
Object.defineProperty(MiniSearch2.prototype, "termCount", {
/**
* Number of terms in the index
*/
get: function() {
return this._index.size;
},
enumerable: false,
configurable: true
});
MiniSearch2.loadJSON = function(json, options) {
if (options == null) {
throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");
}
return this.loadJS(JSON.parse(json), options);
};
MiniSearch2.getDefault = function(optionName) {
if (defaultOptions.hasOwnProperty(optionName)) {
return getOwnProperty(defaultOptions, optionName);
} else {
throw new Error('MiniSearch: unknown option "'.concat(optionName, '"'));
}
};
MiniSearch2.loadJS = function(js, options) {
var e_16, _a2, e_17, _b, e_18, _c;
var index = js.index, documentCount = js.documentCount, nextId = js.nextId, documentIds = js.documentIds, fieldIds = js.fieldIds, fieldLength = js.fieldLength, averageFieldLength = js.averageFieldLength, storedFields = js.storedFields, dirtCount = js.dirtCount, serializationVersion = js.serializationVersion;
if (serializationVersion !== 1 && serializationVersion !== 2) {
throw new Error("MiniSearch: cannot deserialize an index created with an incompatible version");
}
var miniSearch = new MiniSearch2(options);
miniSearch._documentCount = documentCount;
miniSearch._nextId = nextId;
miniSearch._documentIds = objectToNumericMap(documentIds);
miniSearch._idToShortId = /* @__PURE__ */ new Map();
miniSearch._fieldIds = fieldIds;
miniSearch._fieldLength = objectToNumericMap(fieldLength);
miniSearch._avgFieldLength = averageFieldLength;
miniSearch._storedFields = objectToNumericMap(storedFields);
miniSearch._dirtCount = dirtCount || 0;
miniSearch._index = new SearchableMap();
try {
for (var _d = __values(miniSearch._documentIds), _e = _d.next(); !_e.done; _e = _d.next()) {
var _f = __read(_e.value, 2), shortId = _f[0], id = _f[1];
miniSearch._idToShortId.set(id, shortId);
}
} catch (e_16_1) {
e_16 = { error: e_16_1 };
} finally {
try {
if (_e && !_e.done && (_a2 = _d.return))
_a2.call(_d);
} finally {
if (e_16)
throw e_16.error;
}
}
try {
for (var index_1 = __values(index), index_1_1 = index_1.next(); !index_1_1.done; index_1_1 = index_1.next()) {
var _g = __read(index_1_1.value, 2), term = _g[0], data = _g[1];
var dataMap = /* @__PURE__ */ new Map();
try {
for (var _h = (e_18 = void 0, __values(Object.keys(data))), _j = _h.next(); !_j.done; _j = _h.next()) {
var fieldId = _j.value;
var indexEntry = data[fieldId];
if (serializationVersion === 1) {
indexEntry = indexEntry.ds;
}
dataMap.set(parseInt(fieldId, 10), objectToNumericMap(indexEntry));
}
} catch (e_18_1) {
e_18 = { error: e_18_1 };
} finally {
try {
if (_j && !_j.done && (_c = _h.return))
_c.call(_h);
} finally {
if (e_18)
throw e_18.error;
}
}
miniSearch._index.set(term, dataMap);
}
} catch (e_17_1) {
e_17 = { error: e_17_1 };
} finally {
try {
if (index_1_1 && !index_1_1.done && (_b = index_1.return))
_b.call(index_1);
} finally {
if (e_17)
throw e_17.error;
}
}
return miniSearch;
};
MiniSearch2.prototype.executeQuery = function(query, searchOptions) {
var _this = this;
if (searchOptions === void 0) {
searchOptions = {};
}
if (query === MiniSearch2.wildcard) {
return this.executeWildcardQuery(searchOptions);
}
if (typeof query !== "string") {
var options_1 = __assign(__assign(__assign({}, searchOptions), query), { queries: void 0 });
var results_1 = query.queries.map(function(subquery) {
return _this.executeQuery(subquery, options_1);
});
return this.combineResults(results_1, options_1.combineWith);
}
var _a2 = this._options, tokenize = _a2.tokenize, processTerm = _a2.processTerm, globalSearchOptions = _a2.searchOptions;
var options = __assign(__assign({ tokenize, processTerm }, globalSearchOptions), searchOptions);
var searchTokenize = options.tokenize, searchProcessTerm = options.processTerm;
var terms = searchTokenize(query).flatMap(function(term) {
return searchProcessTerm(term);
}).filter(function(term) {
return !!term;
});
var queries = terms.map(termToQuerySpec(options));
var results = queries.map(function(query2) {
return _this.executeQuerySpec(query2, options);
});
return this.combineResults(results, options.combineWith);
};
MiniSearch2.prototype.executeQuerySpec = function(query, searchOptions) {
var e_19, _a2, e_20, _b;
var options = __assign(__assign({}, this._options.searchOptions), searchOptions);
var boosts = (options.fields || this._options.fields).reduce(function(boosts2, field) {
var _a3;
return __assign(__assign({}, boosts2), (_a3 = {}, _a3[field] = getOwnProperty(options.boost, field) || 1, _a3));
}, {});
var boostDocument = options.boostDocument, weights = options.weights, maxFuzzy = options.maxFuzzy, bm25params = options.bm25;
var _c = __assign(__assign({}, defaultSearchOptions.weights), weights), fuzzyWeight = _c.fuzzy, prefixWeight = _c.prefix;
var data = this._index.get(query.term);
var results = this.termResults(query.term, query.term, 1, data, boosts, boostDocument, bm25params);
var prefixMatches;
var fuzzyMatches;
if (query.prefix) {
prefixMatches = this._index.atPrefix(query.term);
}
if (query.fuzzy) {
var fuzzy = query.fuzzy === true ? 0.2 : query.fuzzy;
var maxDistance = fuzzy < 1 ? Math.min(maxFuzzy, Math.round(query.term.length * fuzzy)) : fuzzy;
if (maxDistance)
fuzzyMatches = this._index.fuzzyGet(query.term, maxDistance);
}
if (prefixMatches) {
try {
for (var prefixMatches_1 = __values(prefixMatches), prefixMatches_1_1 = prefixMatches_1.next(); !prefixMatches_1_1.done; prefixMatches_1_1 = prefixMatches_1.next()) {
var _d = __read(prefixMatches_1_1.value, 2), term = _d[0], data_1 = _d[1];
var distance = term.length - query.term.length;
if (!distance) {
continue;
}
fuzzyMatches === null || fuzzyMatches === void 0 ? void 0 : fuzzyMatches.delete(term);
var weight = prefixWeight * term.length / (term.length + 0.3 * distance);
this.termResults(query.term, term, weight, data_1, boosts, boostDocument, bm25params, results);
}
} catch (e_19_1) {
e_19 = { error: e_19_1 };
} finally {
try {
if (prefixMatches_1_1 && !prefixMatches_1_1.done && (_a2 = prefixMatches_1.return))
_a2.call(prefixMatches_1);
} finally {
if (e_19)
throw e_19.error;
}
}
}
if (fuzzyMatches) {
try {
for (var _e = __values(fuzzyMatches.keys()), _f = _e.next(); !_f.done; _f = _e.next()) {
var term = _f.value;
var _g = __read(fuzzyMatches.get(term), 2), data_2 = _g[0], distance = _g[1];
if (!distance) {
continue;
}
var weight = fuzzyWeight * term.length / (term.length + distance);
this.termResults(query.term, term, weight, data_2, boosts, boostDocument, bm25params, results);
}
} catch (e_20_1) {
e_20 = { error: e_20_1 };
} finally {
try {
if (_f && !_f.done && (_b = _e.return))
_b.call(_e);
} finally {
if (e_20)
throw e_20.error;
}
}
}
return results;
};
MiniSearch2.prototype.executeWildcardQuery = function(searchOptions) {
var e_21, _a2;
var results = /* @__PURE__ */ new Map();
var options = __assign(__assign({}, this._options.searchOptions), searchOptions);
try {
for (var _b = __values(this._documentIds), _c = _b.next(); !_c.done; _c = _b.next()) {
var _d = __read(_c.value, 2), shortId = _d[0], id = _d[1];
var score = options.boostDocument ? options.boostDocument(id, "", this._storedFields.get(shortId)) : 1;
results.set(shortId, {
score,
terms: [],
match: {}
});
}
} catch (e_21_1) {
e_21 = { error: e_21_1 };
} finally {
try {
if (_c && !_c.done && (_a2 = _b.return))
_a2.call(_b);
} finally {
if (e_21)
throw e_21.error;
}
}
return results;
};
MiniSearch2.prototype.combineResults = function(results, combineWith) {
if (combineWith === void 0) {
combineWith = OR;
}
if (results.length === 0) {
return /* @__PURE__ */ new Map();
}
var operator = combineWith.toLowerCase();
return results.reduce(combinators[operator]) || /* @__PURE__ */ new Map();
};
MiniSearch2.prototype.toJSON = function() {
var e_22, _a2, e_23, _b;
var index = [];
try {
for (var _c = __values(this._index), _d = _c.next(); !_d.done; _d = _c.next()) {
var _e = __read(_d.value, 2), term = _e[0], fieldIndex = _e[1];
var data = {};
try {
for (var fieldIndex_2 = (e_23 = void 0, __values(fieldIndex)), fieldIndex_2_1 = fieldIndex_2.next(); !fieldIndex_2_1.done; fieldIndex_2_1 = fieldIndex_2.next()) {
var _f = __read(fieldIndex_2_1.value, 2), fieldId = _f[0], freqs = _f[1];
data[fieldId] = Object.fromEntries(freqs);
}
} catch (e_23_1) {
e_23 = { error: e_23_1 };
} finally {
try {
if (fieldIndex_2_1 && !fieldIndex_2_1.done && (_b = fieldIndex_2.return))
_b.call(fieldIndex_2);
} finally {
if (e_23)
throw e_23.error;
}
}
index.push([term, data]);
}
} catch (e_22_1) {
e_22 = { error: e_22_1 };
} finally {
try {
if (_d && !_d.done && (_a2 = _c.return))
_a2.call(_c);
} finally {
if (e_22)
throw e_22.error;
}
}
return {
documentCount: this._documentCount,
nextId: this._nextId,
documentIds: Object.fromEntries(this._documentIds),
fieldIds: this._fieldIds,
fieldLength: Object.fromEntries(this._fieldLength),
averageFieldLength: this._avgFieldLength,
storedFields: Object.fromEntries(this._storedFields),
dirtCount: this._dirtCount,
index,
serializationVersion: 2
};
};
MiniSearch2.prototype.termResults = function(sourceTerm, derivedTerm, termWeight, fieldTermData, fieldBoosts, boostDocumentFn, bm25params, results) {
var e_24, _a2, e_25, _b, _c;
if (results === void 0) {
results = /* @__PURE__ */ new Map();
}
if (fieldTermData == null)
return results;
try {
for (var _d = __values(Object.keys(fieldBoosts)), _e = _d.next(); !_e.done; _e = _d.next()) {
var field = _e.value;
var fieldBoost = fieldBoosts[field];
var fieldId = this._fieldIds[field];
var fieldTermFreqs = fieldTermData.get(fieldId);
if (fieldTermFreqs == null)
continue;
var matchingFields = fieldTermFreqs.size;
var avgFieldLength = this._avgFieldLength[fieldId];
try {
for (var _f = (e_25 = void 0, __values(fieldTermFreqs.keys())), _g = _f.next(); !_g.done; _g = _f.next()) {
var docId = _g.value;
if (!this._documentIds.has(docId)) {
this.removeTerm(fieldId, docId, derivedTerm);
matchingFields -= 1;
continue;
}
var docBoost = boostDocumentFn ? boostDocumentFn(this._documentIds.get(docId), derivedTerm, this._storedFields.get(docId)) : 1;
if (!docBoost)
continue;
var termFreq = fieldTermFreqs.get(docId);
var fieldLength = this._fieldLength.get(docId)[fieldId];
var rawScore = calcBM25Score(termFreq, matchingFields, this._documentCount, fieldLength, avgFieldLength, bm25params);
var weightedScore = termWeight * fieldBoost * docBoost * rawScore;
var result = results.get(docId);
if (result) {
result.score += weightedScore;
assignUniqueTerm(result.terms, sourceTerm);
var match = getOwnProperty(result.match, derivedTerm);
if (match) {
match.push(field);
} else {
result.match[derivedTerm] = [field];
}
} else {
results.set(docId, {
score: weightedScore,
terms: [sourceTerm],
match: (_c = {}, _c[derivedTerm] = [field], _c)
});
}
}
} catch (e_25_1) {
e_25 = { error: e_25_1 };
} finally {
try {
if (_g && !_g.done && (_b = _f.return))
_b.call(_f);
} finally {
if (e_25)
throw e_25.error;
}
}
}
} catch (e_24_1) {
e_24 = { error: e_24_1 };
} finally {
try {
if (_e && !_e.done && (_a2 = _d.return))
_a2.call(_d);
} finally {
if (e_24)
throw e_24.error;
}
}
return results;
};
MiniSearch2.prototype.addTerm = function(fieldId, documentId, term) {
var indexData = this._index.fetch(term, createMap);
var fieldIndex = indexData.get(fieldId);
if (fieldIndex == null) {
fieldIndex = /* @__PURE__ */ new Map();
fieldIndex.set(documentId, 1);
indexData.set(fieldId, fieldIndex);
} else {
var docs = fieldIndex.get(documentId);
fieldIndex.set(documentId, (docs || 0) + 1);
}
};
MiniSearch2.prototype.removeTerm = function(fieldId, documentId, term) {
if (!this._index.has(term)) {
this.warnDocumentChanged(documentId, fieldId, term);
return;
}
var indexData = this._index.fetch(term, createMap);
var fieldIndex = indexData.get(fieldId);
if (fieldIndex == null || fieldIndex.get(documentId) == null) {
this.warnDocumentChanged(documentId, fieldId, term);
} else if (fieldIndex.get(documentId) <= 1) {
if (fieldIndex.size <= 1) {
indexData.delete(fieldId);
} else {
fieldIndex.delete(documentId);
}
} else {
fieldIndex.set(documentId, fieldIndex.get(documentId) - 1);
}
if (this._index.get(term).size === 0) {
this._index.delete(term);
}
};
MiniSearch2.prototype.warnDocumentChanged = function(shortDocumentId, fieldId, term) {
var e_26, _a2;
try {
for (var _b = __values(Object.keys(this._fieldIds)), _c = _b.next(); !_c.done; _c = _b.next()) {
var fieldName = _c.value;
if (this._fieldIds[fieldName] === fieldId) {
this._options.logger("warn", "MiniSearch: document with ID ".concat(this._documentIds.get(shortDocumentId), ' has changed before removal: term "').concat(term, '" was not present in field "').concat(fieldName, '". Removing a document after it has changed can corrupt the index!'), "version_conflict");
return;
}
}
} catch (e_26_1) {
e_26 = { error: e_26_1 };
} finally {
try {
if (_c && !_c.done && (_a2 = _b.return))
_a2.call(_b);
} finally {
if (e_26)
throw e_26.error;
}
}
};
MiniSearch2.prototype.addDocumentId = function(documentId) {
var shortDocumentId = this._nextId;
this._idToShortId.set(documentId, shortDocumentId);
this._documentIds.set(shortDocumentId, documentId);
this._documentCount += 1;
this._nextId += 1;
return shortDocumentId;
};
MiniSearch2.prototype.addFields = function(fields) {
for (var i = 0; i < fields.length; i++) {
this._fieldIds[fields[i]] = i;
}
};
MiniSearch2.prototype.addFieldLength = function(documentId, fieldId, count, length) {
var fieldLengths = this._fieldLength.get(documentId);
if (fieldLengths == null)
this._fieldLength.set(documentId, fieldLengths = []);
fieldLengths[fieldId] = length;
var averageFieldLength = this._avgFieldLength[fieldId] || 0;
var totalFieldLength = averageFieldLength * count + length;
this._avgFieldLength[fieldId] = totalFieldLength / (count + 1);
};
MiniSearch2.prototype.removeFieldLength = function(documentId, fieldId, count, length) {
if (count === 1) {
this._avgFieldLength[fieldId] = 0;
return;
}
var totalFieldLength = this._avgFieldLength[fieldId] * count - length;
this._avgFieldLength[fieldId] = totalFieldLength / (count - 1);
};
MiniSearch2.prototype.saveStoredFields = function(documentId, doc) {
var e_27, _a2;
var _b = this._options, storeFields = _b.storeFields, extractField = _b.extractField;
if (storeFields == null || storeFields.length === 0) {
return;
}
var documentFields = this._storedFields.get(documentId);
if (documentFields == null)
this._storedFields.set(documentId, documentFields = {});
try {
for (var storeFields_1 = __values(storeFields), storeFields_1_1 = storeFields_1.next(); !storeFields_1_1.done; storeFields_1_1 = storeFields_1.next()) {
var fieldName = storeFields_1_1.value;
var fieldValue = extractField(doc, fieldName);
if (fieldValue !== void 0)
documentFields[fieldName] = fieldValue;
}
} catch (e_27_1) {
e_27 = { error: e_27_1 };
} finally {
try {
if (storeFields_1_1 && !storeFields_1_1.done && (_a2 = storeFields_1.return))
_a2.call(storeFields_1);
} finally {
if (e_27)
throw e_27.error;
}
}
};
MiniSearch2.wildcard = Symbol("*");
return MiniSearch2;
}()
);
var getOwnProperty = function(object, property) {
return Object.prototype.hasOwnProperty.call(object, property) ? object[property] : void 0;
};
var combinators = (_a = {}, _a[OR] = function(a, b) {
var e_28, _a2;
try {
for (var _b = __values(b.keys()), _c = _b.next(); !_c.done; _c = _b.next()) {
var docId = _c.value;
var existing = a.get(docId);
if (existing == null) {
a.set(docId, b.get(docId));
} else {
var _d = b.get(docId), score = _d.score, terms = _d.terms, match = _d.match;
existing.score = existing.score + score;
existing.match = Object.assign(existing.match, match);
assignUniqueTerms(existing.terms, terms);
}
}
} catch (e_28_1) {
e_28 = { error: e_28_1 };
} finally {
try {
if (_c && !_c.done && (_a2 = _b.return))
_a2.call(_b);
} finally {
if (e_28)
throw e_28.error;
}
}
return a;
}, _a[AND] = function(a, b) {
var e_29, _a2;
var combined = /* @__PURE__ */ new Map();
try {
for (var _b = __values(b.keys()), _c = _b.next(); !_c.done; _c = _b.next()) {
var docId = _c.value;
var existing = a.get(docId);
if (existing == null)
continue;
var _d = b.get(docId), score = _d.score, terms = _d.terms, match = _d.match;
assignUniqueTerms(existing.terms, terms);
combined.set(docId, {
score: existing.score + score,
terms: existing.terms,
match: Object.assign(existing.match, match)
});
}
} catch (e_29_1) {
e_29 = { error: e_29_1 };
} finally {
try {
if (_c && !_c.done && (_a2 = _b.return))
_a2.call(_b);
} finally {
if (e_29)
throw e_29.error;
}
}
return combined;
}, _a[AND_NOT] = function(a, b) {
var e_30, _a2;
try {
for (var _b = __values(b.keys()), _c = _b.next(); !_c.done; _c = _b.next()) {
var docId = _c.value;
a.delete(docId);
}
} catch (e_30_1) {
e_30 = { error: e_30_1 };
} finally {
try {
if (_c && !_c.done && (_a2 = _b.return))
_a2.call(_b);
} finally {
if (e_30)
throw e_30.error;
}
}
return a;
}, _a);
var defaultBM25params = { k: 1.2, b: 0.7, d: 0.5 };
var calcBM25Score = function(termFreq, matchingCount, totalCount, fieldLength, avgFieldLength, bm25params) {
var k = bm25params.k, b = bm25params.b, d = bm25params.d;
var invDocFreq = Math.log(1 + (totalCount - matchingCount + 0.5) / (matchingCount + 0.5));
return invDocFreq * (d + termFreq * (k + 1) / (termFreq + k * (1 - b + b * fieldLength / avgFieldLength)));
};
var termToQuerySpec = function(options) {
return function(term, i, terms) {
var fuzzy = typeof options.fuzzy === "function" ? options.fuzzy(term, i, terms) : options.fuzzy || false;
var prefix = typeof options.prefix === "function" ? options.prefix(term, i, terms) : options.prefix === true;
return { term, fuzzy, prefix };
};
};
var defaultOptions = {
idField: "id",
extractField: function(document2, fieldName) {
return document2[fieldName];
},
tokenize: function(text) {
return text.split(SPACE_OR_PUNCTUATION);
},
processTerm: function(term) {
return term.toLowerCase();
},
fields: void 0,
searchOptions: void 0,
storeFields: [],
logger: function(level, message) {
if (typeof (console === null || console === void 0 ? void 0 : console[level]) === "function")
console[level](message);
},
autoVacuum: true
};
var defaultSearchOptions = {
combineWith: OR,
prefix: false,
fuzzy: false,
maxFuzzy: 6,
boost: {},
weights: { fuzzy: 0.45, prefix: 0.375 },
bm25: defaultBM25params
};
var defaultAutoSuggestOptions = {
combineWith: AND,
prefix: function(term, i, terms) {
return i === terms.length - 1;
}
};
var defaultVacuumOptions = { batchSize: 1e3, batchWait: 10 };
var defaultVacuumConditions = { minDirtFactor: 0.1, minDirtCount: 20 };
var defaultAutoVacuumOptions = __assign(__assign({}, defaultVacuumOptions), defaultVacuumConditions);
var assignUniqueTerm = function(target, term) {
if (!target.includes(term))
target.push(term);
};
var assignUniqueTerms = function(target, source) {
var e_31, _a2;
try {
for (var source_1 = __values(source), source_1_1 = source_1.next(); !source_1_1.done; source_1_1 = source_1.next()) {
var term = source_1_1.value;
if (!target.includes(term))
target.push(term);
}
} catch (e_31_1) {
e_31 = { error: e_31_1 };
} finally {
try {
if (source_1_1 && !source_1_1.done && (_a2 = source_1.return))
_a2.call(source_1);
} finally {
if (e_31)
throw e_31.error;
}
}
};
var byScore = function(_a2, _b) {
var a = _a2.score;
var b = _b.score;
return b - a;
};
var createMap = function() {
return /* @__PURE__ */ new Map();
};
var objectToNumericMap = function(object) {
var e_32, _a2;
var map = /* @__PURE__ */ new Map();
try {
for (var _b = __values(Object.keys(object)), _c = _b.next(); !_c.done; _c = _b.next()) {
var key = _c.value;
map.set(parseInt(key, 10), object[key]);
}
} catch (e_32_1) {
e_32 = { error: e_32_1 };
} finally {
try {
if (_c && !_c.done && (_a2 = _b.return))
_a2.call(_b);
} finally {
if (e_32)
throw e_32.error;
}
}
return map;
};
var SPACE_OR_PUNCTUATION = /[\n\r -#%-*,-/:;?@[-\]_{}\u00A0\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u1680\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2000-\u200A\u2010-\u2029\u202F-\u2043\u2045-\u2051\u2053-\u205F\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u3000-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]+/u;
class LRUCache {
constructor(max = 10) {
__publicField(this, "max");
__publicField(this, "cache");
this.max = max;
this.cache = /* @__PURE__ */ new Map();
}
get(key) {
let item = this.cache.get(key);
if (item !== void 0) {
this.cache.delete(key);
this.cache.set(key, item);
}
return item;
}
set(key, val) {
if (this.cache.has(key))
this.cache.delete(key);
else if (this.cache.size === this.max)
this.cache.delete(this.first());
this.cache.set(key, val);
}
first() {
return this.cache.keys().next().value;
}
clear() {
this.cache.clear();
}
}
const _withScopeId = (n) => (pushScopeId("data-v-43c4f204"), n = n(), popScopeId(), n);
const _hoisted_1 = ["aria-owns"];
const _hoisted_2 = { class: "shell" };
const _hoisted_3 = ["title"];
const _hoisted_4 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("span", {
"aria-hidden": "true",
class: "vpi-search search-icon local-search-icon"
}, null, -1));
const _hoisted_5 = [
_hoisted_4
];
const _hoisted_6 = { class: "search-actions before" };
const _hoisted_7 = ["title"];
const _hoisted_8 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("span", { class: "vpi-arrow-left local-search-icon" }, null, -1));
const _hoisted_9 = [
_hoisted_8
];
const _hoisted_10 = ["placeholder"];
const _hoisted_11 = { class: "search-actions" };
const _hoisted_12 = ["title"];
const _hoisted_13 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("span", { class: "vpi-layout-list local-search-icon" }, null, -1));
const _hoisted_14 = [
_hoisted_13
];
const _hoisted_15 = ["disabled", "title"];
const _hoisted_16 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("span", { class: "vpi-delete local-search-icon" }, null, -1));
const _hoisted_17 = [
_hoisted_16
];
const _hoisted_18 = ["id", "role", "aria-labelledby"];
const _hoisted_19 = ["aria-selected"];
const _hoisted_20 = ["href", "aria-label", "onMouseenter", "onFocusin"];
const _hoisted_21 = { class: "titles" };
const _hoisted_22 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("span", { class: "title-icon" }, "#", -1));
const _hoisted_23 = ["innerHTML"];
const _hoisted_24 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("span", { class: "vpi-chevron-right local-search-icon" }, null, -1));
const _hoisted_25 = { class: "title main" };
const _hoisted_26 = ["innerHTML"];
const _hoisted_27 = {
key: 0,
class: "excerpt-wrapper"
};
const _hoisted_28 = {
key: 0,
class: "excerpt",
inert: ""
};
const _hoisted_29 = ["innerHTML"];
const _hoisted_30 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("div", { class: "excerpt-gradient-bottom" }, null, -1));
const _hoisted_31 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("div", { class: "excerpt-gradient-top" }, null, -1));
const _hoisted_32 = {
key: 0,
class: "no-results"
};
const _hoisted_33 = { class: "search-keyboard-shortcuts" };
const _hoisted_34 = ["aria-label"];
const _hoisted_35 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("span", { class: "vpi-arrow-up navigate-icon" }, null, -1));
const _hoisted_36 = [
_hoisted_35
];
const _hoisted_37 = ["aria-label"];
const _hoisted_38 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("span", { class: "vpi-arrow-down navigate-icon" }, null, -1));
const _hoisted_39 = [
_hoisted_38
];
const _hoisted_40 = ["aria-label"];
const _hoisted_41 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("span", { class: "vpi-corner-down-left navigate-icon" }, null, -1));
const _hoisted_42 = [
_hoisted_41
];
const _hoisted_43 = ["aria-label"];
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "VPLocalSearchBox",
emits: ["close"],
setup(__props, { emit: __emit }) {
var _a2, _b;
const emit = __emit;
const el = shallowRef();
const resultsEl = shallowRef();
const searchIndexData = shallowRef(localSearchIndex);
const vitePressData = useData();
const { activate } = useFocusTrap(el, {
immediate: true,
allowOutsideClick: true,
clickOutsideDeactivates: true,
escapeDeactivates: true
});
const { localeIndex, theme } = vitePressData;
const searchIndex = computedAsync(
async () => {
var _a3, _b2, _c, _d, _e, _f, _g, _h, _i;
return markRaw(
MiniSearch.loadJSON(
(_c = await ((_b2 = (_a3 = searchIndexData.value)[localeIndex.value]) == null ? void 0 : _b2.call(_a3))) == null ? void 0 : _c.default,
{
fields: ["title", "titles", "text"],
storeFields: ["title", "titles"],
searchOptions: {
fuzzy: 0.2,
prefix: true,
boost: { title: 4, text: 2, titles: 1 },
...((_d = theme.value.search) == null ? void 0 : _d.provider) === "local" && ((_f = (_e = theme.value.search.options) == null ? void 0 : _e.miniSearch) == null ? void 0 : _f.searchOptions)
},
...((_g = theme.value.search) == null ? void 0 : _g.provider) === "local" && ((_i = (_h = theme.value.search.options) == null ? void 0 : _h.miniSearch) == null ? void 0 : _i.options)
}
)
);
}
);
const disableQueryPersistence = computed(() => {
var _a3, _b2;
return ((_a3 = theme.value.search) == null ? void 0 : _a3.provider) === "local" && ((_b2 = theme.value.search.options) == null ? void 0 : _b2.disableQueryPersistence) === true;
});
const filterText = disableQueryPersistence.value ? ref("") : useSessionStorage("vitepress:local-search-filter", "");
const showDetailedList = useLocalStorage(
"vitepress:local-search-detailed-list",
((_a2 = theme.value.search) == null ? void 0 : _a2.provider) === "local" && ((_b = theme.value.search.options) == null ? void 0 : _b.detailedView) === true
);
const disableDetailedView = computed(() => {
var _a3, _b2, _c;
return ((_a3 = theme.value.search) == null ? void 0 : _a3.provider) === "local" && (((_b2 = theme.value.search.options) == null ? void 0 : _b2.disableDetailedView) === true || ((_c = theme.value.search.options) == null ? void 0 : _c.detailedView) === false);
});
const buttonText = computed(() => {
var _a3, _b2, _c, _d, _e, _f, _g;
const options = ((_a3 = theme.value.search) == null ? void 0 : _a3.options) ?? theme.value.algolia;
return ((_e = (_d = (_c = (_b2 = options == null ? void 0 : options.locales) == null ? void 0 : _b2[localeIndex.value]) == null ? void 0 : _c.translations) == null ? void 0 : _d.button) == null ? void 0 : _e.buttonText) || ((_g = (_f = options == null ? void 0 : options.translations) == null ? void 0 : _f.button) == null ? void 0 : _g.buttonText) || "Search";
});
watchEffect(() => {
if (disableDetailedView.value) {
showDetailedList.value = false;
}
});
const results = shallowRef([]);
const enableNoResults = ref(false);
watch(filterText, () => {
enableNoResults.value = false;
});
const mark = computedAsync(async () => {
if (!resultsEl.value)
return;
return markRaw(new Mark2(resultsEl.value));
}, null);
const cache = new LRUCache(16);
watchDebounced(
() => [searchIndex.value, filterText.value, showDetailedList.value],
async ([index, filterTextValue, showDetailedListValue], old, onCleanup) => {
var _a3, _b2, _c, _d;
if ((old == null ? void 0 : old[0]) !== index) {
cache.clear();
}
let canceled = false;
onCleanup(() => {
canceled = true;
});
if (!index)
return;
results.value = index.search(filterTextValue).slice(0, 16);
enableNoResults.value = true;
const mods = showDetailedListValue ? await Promise.all(results.value.map((r) => fetchExcerpt(r.id))) : [];
if (canceled)
return;
for (const { id, mod } of mods) {
const mapId = id.slice(0, id.indexOf("#"));
let map = cache.get(mapId);
if (map)
continue;
map = /* @__PURE__ */ new Map();
cache.set(mapId, map);
const comp = mod.default ?? mod;
if ((comp == null ? void 0 : comp.render) || (comp == null ? void 0 : comp.setup)) {
const app = createApp(comp);
app.config.warnHandler = () => {
};
app.provide(dataSymbol, vitePressData);
Object.defineProperties(app.config.globalProperties, {
$frontmatter: {
get() {
return vitePressData.frontmatter.value;
}
},
$params: {
get() {
return vitePressData.page.value.params;
}
}
});
const div = document.createElement("div");
app.mount(div);
const headings = div.querySelectorAll("h1, h2, h3, h4, h5, h6");
headings.forEach((el2) => {
var _a4;
const href = (_a4 = el2.querySelector("a")) == null ? void 0 : _a4.getAttribute("href");
const anchor = (href == null ? void 0 : href.startsWith("#")) && href.slice(1);
if (!anchor)
return;
let html = "";
while ((el2 = el2.nextElementSibling) && !/^h[1-6]$/i.test(el2.tagName))
html += el2.outerHTML;
map.set(anchor, html);
});
app.unmount();
}
if (canceled)
return;
}
const terms = /* @__PURE__ */ new Set();
results.value = results.value.map((r) => {
const [id, anchor] = r.id.split("#");
const map = cache.get(id);
const text = (map == null ? void 0 : map.get(anchor)) ?? "";
for (const term in r.match) {
terms.add(term);
}
return { ...r, text };
});
await nextTick();
if (canceled)
return;
await new Promise((r) => {
var _a4;
(_a4 = mark.value) == null ? void 0 : _a4.unmark({
done: () => {
var _a5;
(_a5 = mark.value) == null ? void 0 : _a5.markRegExp(formMarkRegex(terms), { done: r });
}
});
});
const excerpts = ((_a3 = el.value) == null ? void 0 : _a3.querySelectorAll(".result .excerpt")) ?? [];
for (const excerpt of excerpts) {
(_b2 = excerpt.querySelector('mark[data-markjs="true"]')) == null ? void 0 : _b2.scrollIntoView({ block: "center" });
}
(_d = (_c = resultsEl.value) == null ? void 0 : _c.firstElementChild) == null ? void 0 : _d.scrollIntoView({ block: "start" });
},
{ debounce: 200, immediate: true }
);
async function fetchExcerpt(id) {
const file = pathToFile(id.slice(0, id.indexOf("#")));
try {
if (!file)
throw new Error(`Cannot find file for id: ${id}`);
return { id, mod: await __vitePreload(() => import(
/*@vite-ignore*/
file
), true ? [] : void 0) };
} catch (e) {
console.error(e);
return { id, mod: {} };
}
}
const searchInput = ref();
const disableReset = computed(() => {
var _a3;
return ((_a3 = filterText.value) == null ? void 0 : _a3.length) <= 0;
});
function focusSearchInput(select = true) {
var _a3, _b2;
(_a3 = searchInput.value) == null ? void 0 : _a3.focus();
select && ((_b2 = searchInput.value) == null ? void 0 : _b2.select());
}
onMounted(() => {
focusSearchInput();
});
function onSearchBarClick(event) {
if (event.pointerType === "mouse") {
focusSearchInput();
}
}
const selectedIndex = ref(-1);
const disableMouseOver = ref(false);
watch(results, (r) => {
selectedIndex.value = r.length ? 0 : -1;
scrollToSelectedResult();
});
function scrollToSelectedResult() {
nextTick(() => {
const selectedEl = document.querySelector(".result.selected");
if (selectedEl) {
selectedEl.scrollIntoView({
block: "nearest"
});
}
});
}
onKeyStroke("ArrowUp", (event) => {
event.preventDefault();
selectedIndex.value--;
if (selectedIndex.value < 0) {
selectedIndex.value = results.value.length - 1;
}
disableMouseOver.value = true;
scrollToSelectedResult();
});
onKeyStroke("ArrowDown", (event) => {
event.preventDefault();
selectedIndex.value++;
if (selectedIndex.value >= results.value.length) {
selectedIndex.value = 0;
}
disableMouseOver.value = true;
scrollToSelectedResult();
});
const router = useRouter();
onKeyStroke("Enter", (e) => {
if (e.isComposing)
return;
if (e.target instanceof HTMLButtonElement && e.target.type !== "submit")
return;
const selectedPackage = results.value[selectedIndex.value];
if (e.target instanceof HTMLInputElement && !selectedPackage) {
e.preventDefault();
return;
}
if (selectedPackage) {
router.go(selectedPackage.id);
emit("close");
}
});
onKeyStroke("Escape", () => {
emit("close");
});
const defaultTranslations = {
modal: {
displayDetails: "Display detailed list",
resetButtonTitle: "Reset search",
backButtonTitle: "Close search",
noResultsText: "No results for",
footer: {
selectText: "to select",
selectKeyAriaLabel: "enter",
navigateText: "to navigate",
navigateUpKeyAriaLabel: "up arrow",
navigateDownKeyAriaLabel: "down arrow",
closeText: "to close",
closeKeyAriaLabel: "escape"
}
}
};
const translate = createSearchTranslate(defaultTranslations);
onMounted(() => {
window.history.pushState(null, "", null);
});
useEventListener("popstate", (event) => {
event.preventDefault();
emit("close");
});
const isLocked = useScrollLock(inBrowser ? document.body : null);
onMounted(() => {
nextTick(() => {
isLocked.value = true;
nextTick().then(() => activate());
});
});
onBeforeUnmount(() => {
isLocked.value = false;
});
function resetSearch() {
filterText.value = "";
nextTick().then(() => focusSearchInput(false));
}
function formMarkRegex(terms) {
return new RegExp(
[...terms].sort((a, b) => b.length - a.length).map((term) => `(${escapeRegExp(term)})`).join("|"),
"gi"
);
}
return (_ctx, _cache) => {
var _a3, _b2, _c, _d;
return openBlock(), createBlock(Teleport, { to: "body" }, [
createBaseVNode("div", {
ref_key: "el",
ref: el,
role: "button",
"aria-owns": ((_a3 = results.value) == null ? void 0 : _a3.length) ? "localsearch-list" : void 0,
"aria-expanded": "true",
"aria-haspopup": "listbox",
"aria-labelledby": "localsearch-label",
class: "VPLocalSearchBox"
}, [
createBaseVNode("div", {
class: "backdrop",
onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("close"))
}),
createBaseVNode("div", _hoisted_2, [
createBaseVNode("form", {
class: "search-bar",
onPointerup: _cache[4] || (_cache[4] = ($event) => onSearchBarClick($event)),
onSubmit: _cache[5] || (_cache[5] = withModifiers(() => {
}, ["prevent"]))
}, [
createBaseVNode("label", {
title: buttonText.value,
id: "localsearch-label",
for: "localsearch-input"
}, _hoisted_5, 8, _hoisted_3),
createBaseVNode("div", _hoisted_6, [
createBaseVNode("button", {
class: "back-button",
title: unref(translate)("modal.backButtonTitle"),
onClick: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("close"))
}, _hoisted_9, 8, _hoisted_7)
]),
withDirectives(createBaseVNode("input", {
ref_key: "searchInput",
ref: searchInput,
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => isRef(filterText) ? filterText.value = $event : null),
placeholder: buttonText.value,
id: "localsearch-input",
"aria-labelledby": "localsearch-label",
class: "search-input"
}, null, 8, _hoisted_10), [
[vModelText, unref(filterText)]
]),
createBaseVNode("div", _hoisted_11, [
!disableDetailedView.value ? (openBlock(), createElementBlock("button", {
key: 0,
class: normalizeClass(["toggle-layout-button", { "detailed-list": unref(showDetailedList) }]),
type: "button",
title: unref(translate)("modal.displayDetails"),
onClick: _cache[3] || (_cache[3] = ($event) => selectedIndex.value > -1 && (showDetailedList.value = !unref(showDetailedList)))
}, _hoisted_14, 10, _hoisted_12)) : createCommentVNode("", true),
createBaseVNode("button", {
class: "clear-button",
type: "reset",
disabled: disableReset.value,
title: unref(translate)("modal.resetButtonTitle"),
onClick: resetSearch
}, _hoisted_17, 8, _hoisted_15)
])
], 32),
createBaseVNode("ul", {
ref_key: "resultsEl",
ref: resultsEl,
id: ((_b2 = results.value) == null ? void 0 : _b2.length) ? "localsearch-list" : void 0,
role: ((_c = results.value) == null ? void 0 : _c.length) ? "listbox" : void 0,
"aria-labelledby": ((_d = results.value) == null ? void 0 : _d.length) ? "localsearch-label" : void 0,
class: "results",
onMousemove: _cache[7] || (_cache[7] = ($event) => disableMouseOver.value = false)
}, [
(openBlock(true), createElementBlock(Fragment, null, renderList(results.value, (p, index) => {
return openBlock(), createElementBlock("li", {
key: p.id,
role: "option",
"aria-selected": selectedIndex.value === index ? "true" : "false"
}, [
createBaseVNode("a", {
href: p.id,
class: normalizeClass(["result", {
selected: selectedIndex.value === index
}]),
"aria-label": [...p.titles, p.title].join(" > "),
onMouseenter: ($event) => !disableMouseOver.value && (selectedIndex.value = index),
onFocusin: ($event) => selectedIndex.value = index,
onClick: _cache[6] || (_cache[6] = ($event) => _ctx.$emit("close"))
}, [
createBaseVNode("div", null, [
createBaseVNode("div", _hoisted_21, [
_hoisted_22,
(openBlock(true), createElementBlock(Fragment, null, renderList(p.titles, (t, index2) => {
return openBlock(), createElementBlock("span", {
key: index2,
class: "title"
}, [
createBaseVNode("span", {
class: "text",
innerHTML: t
}, null, 8, _hoisted_23),
_hoisted_24
]);
}), 128)),
createBaseVNode("span", _hoisted_25, [
createBaseVNode("span", {
class: "text",
innerHTML: p.title
}, null, 8, _hoisted_26)
])
]),
unref(showDetailedList) ? (openBlock(), createElementBlock("div", _hoisted_27, [
p.text ? (openBlock(), createElementBlock("div", _hoisted_28, [
createBaseVNode("div", {
class: "vp-doc",
innerHTML: p.text
}, null, 8, _hoisted_29)
])) : createCommentVNode("", true),
_hoisted_30,
_hoisted_31
])) : createCommentVNode("", true)
])
], 42, _hoisted_20)
], 8, _hoisted_19);
}), 128)),
unref(filterText) && !results.value.length && enableNoResults.value ? (openBlock(), createElementBlock("li", _hoisted_32, [
createTextVNode(toDisplayString(unref(translate)("modal.noResultsText")) + ' "', 1),
createBaseVNode("strong", null, toDisplayString(unref(filterText)), 1),
createTextVNode('" ')
])) : createCommentVNode("", true)
], 40, _hoisted_18),
createBaseVNode("div", _hoisted_33, [
createBaseVNode("span", null, [
createBaseVNode("kbd", {
"aria-label": unref(translate)("modal.footer.navigateUpKeyAriaLabel")
}, _hoisted_36, 8, _hoisted_34),
createBaseVNode("kbd", {
"aria-label": unref(translate)("modal.footer.navigateDownKeyAriaLabel")
}, _hoisted_39, 8, _hoisted_37),
createTextVNode(" " + toDisplayString(unref(translate)("modal.footer.navigateText")), 1)
]),
createBaseVNode("span", null, [
createBaseVNode("kbd", {
"aria-label": unref(translate)("modal.footer.selectKeyAriaLabel")
}, _hoisted_42, 8, _hoisted_40),
createTextVNode(" " + toDisplayString(unref(translate)("modal.footer.selectText")), 1)
]),
createBaseVNode("span", null, [
createBaseVNode("kbd", {
"aria-label": unref(translate)("modal.footer.closeKeyAriaLabel")
}, "esc", 8, _hoisted_43),
createTextVNode(" " + toDisplayString(unref(translate)("modal.footer.closeText")), 1)
])
])
])
], 8, _hoisted_1)
]);
};
}
});
const VPLocalSearchBox = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-43c4f204"]]);
export {
VPLocalSearchBox as default
};