@ansidev-oss/vitepress-theme-ansidev 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/dist/client/Donation-D9Xn0MPt.js +76 -0
  3. package/dist/client/GoogleAnalytics-Dp3EGn1x.js +29 -0
  4. package/dist/client/VPAlgoliaSearchBox-DXE-LCVf.js +126 -0
  5. package/dist/client/VPCarbonAds-Czmm53YE.js +31 -0
  6. package/dist/client/VPLocalSearchBox-ihwA4uH-.js +4086 -0
  7. package/dist/client/composables/date.d.ts +2 -0
  8. package/dist/client/composables/index.d.ts +4 -0
  9. package/dist/client/composables/locale.d.ts +3 -0
  10. package/dist/client/composables/project.d.ts +13 -0
  11. package/dist/client/composables/rank.d.ts +1 -0
  12. package/dist/client/composables/slug.d.ts +2 -0
  13. package/dist/client/index-BtT3qA6T.js +12663 -0
  14. package/dist/client/index-CCR5sUM8.js +10688 -0
  15. package/dist/client/index-CZCdwVUW.js +7566 -0
  16. package/dist/client/index.d.ts +6 -0
  17. package/dist/client/index.js +5 -0
  18. package/dist/client/plugins/donation/index.d.ts +19 -0
  19. package/dist/client/plugins/google-analytics/index.d.ts +8 -0
  20. package/dist/client/plugins/i18n/index.d.ts +53 -0
  21. package/dist/client/styles.css +1 -0
  22. package/dist/client/types/index.d.ts +45 -0
  23. package/dist/node/composables.d.mts +30 -0
  24. package/dist/node/composables.mjs +51 -0
  25. package/dist/node/config.d.mts +46 -0
  26. package/dist/node/config.mjs +47 -0
  27. package/package.json +87 -0
  28. package/src/client/components/EmptyFooter.vue +3 -0
  29. package/src/client/components/Footer.vue +87 -0
  30. package/src/client/components/Link.vue +31 -0
  31. package/src/client/components/LocaleSwitcher.vue +59 -0
  32. package/src/client/components/PostDate.vue +42 -0
  33. package/src/client/components/PostItem.vue +33 -0
  34. package/src/client/components/PostList.vue +23 -0
  35. package/src/client/components/ProjectCard.vue +68 -0
  36. package/src/client/components/ProjectList.vue +23 -0
  37. package/src/client/components/RouterLink.vue +19 -0
  38. package/src/client/components/StatusBadge.vue +56 -0
  39. package/src/client/components/TermBadge.vue +29 -0
  40. package/src/client/components/TermLink.vue +25 -0
  41. package/src/client/composables/date.ts +12 -0
  42. package/src/client/composables/index.ts +4 -0
  43. package/src/client/composables/locale.ts +7 -0
  44. package/src/client/composables/project.ts +30 -0
  45. package/src/client/composables/rank.ts +13 -0
  46. package/src/client/composables/slug.ts +12 -0
  47. package/src/client/index.ts +43 -0
  48. package/src/client/layouts/Layout.vue +25 -0
  49. package/src/client/pages/ArchivesPage.vue +43 -0
  50. package/src/client/pages/CategoriesPage.vue +30 -0
  51. package/src/client/pages/HomePage.vue +18 -0
  52. package/src/client/pages/Page.vue +20 -0
  53. package/src/client/pages/PostsPage.vue +23 -0
  54. package/src/client/pages/ProjectsPage.vue +65 -0
  55. package/src/client/pages/TagsPage.vue +30 -0
  56. package/src/client/plugins/donation/components/Donation.vue +43 -0
  57. package/src/client/plugins/donation/components/DonationButton.vue +22 -0
  58. package/src/client/plugins/donation/index.ts +42 -0
  59. package/src/client/plugins/google-analytics/components/GoogleAnalytics.vue +52 -0
  60. package/src/client/plugins/google-analytics/index.ts +8 -0
  61. package/src/client/plugins/i18n/index.ts +13 -0
  62. package/src/client/plugins/i18n/locales/en.json +25 -0
  63. package/src/client/plugins/i18n/locales/vi.json +25 -0
  64. package/src/client/styles/index.css +30 -0
  65. package/src/client/types/index.ts +50 -0
  66. package/src/node/composables/index.ts +3 -0
  67. package/src/node/composables/markdown.ts +14 -0
  68. package/src/node/composables/route.ts +26 -0
  69. package/src/node/composables/slug.ts +40 -0
  70. package/src/node/composables/types.ts +7 -0
  71. package/src/node/config.ts +79 -0
  72. package/src/vite-env.d.ts +7 -0
@@ -0,0 +1,4086 @@
1
+ import { shallowRef as Z, watch as Le, computed as Se, toValue as He, readonly as Et, defineComponent as Tt, ref as ue, watchEffect as It, onMounted as Ne, nextTick as de, onBeforeUnmount as kt, openBlock as B, createBlock as Nt, Teleport as Ft, createElementVNode as T, withModifiers as Rt, unref as C, withDirectives as At, isRef as Ot, vModelText as Ct, createElementBlock as H, normalizeClass as qe, createCommentVNode as me, Fragment as Ge, renderList as Qe, createTextVNode as fe, toDisplayString as he, markRaw as Ye, createApp as Mt } from "vue";
2
+ import Lt from "@localSearchIndex";
3
+ import { t as Dt, u as Pt, n as zt, a as Vt, i as jt, s as Ze, b as ct, c as Xe, d as $t, e as Bt, w as Wt, o as ge, f as Kt, g as Jt, h as Ut, _ as Ht } from "./index-CZCdwVUW.js";
4
+ import { useRouter as qt, dataSymbol as Gt, inBrowser as Qt } from "vitepress";
5
+ import Yt from "@siteData";
6
+ var ut = ["input:not([inert]):not([inert] *)", "select:not([inert]):not([inert] *)", "textarea:not([inert]):not([inert] *)", "a[href]:not([inert]):not([inert] *)", "button:not([inert]):not([inert] *)", "[tabindex]:not(slot):not([inert]):not([inert] *)", "audio[controls]:not([inert]):not([inert] *)", "video[controls]:not([inert]):not([inert] *)", '[contenteditable]:not([contenteditable="false"]):not([inert]):not([inert] *)', "details>summary:first-of-type:not([inert]):not([inert] *)", "details:not([inert]):not([inert] *)"], _e = /* @__PURE__ */ ut.join(","), dt = typeof Element > "u", X = dt ? function() {
7
+ } : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector, xe = !dt && Element.prototype.getRootNode ? function(a) {
8
+ var e;
9
+ return a == null || (e = a.getRootNode) === null || e === void 0 ? void 0 : e.call(a);
10
+ } : function(a) {
11
+ return a?.ownerDocument;
12
+ }, Ee = function(e, t) {
13
+ var n;
14
+ t === void 0 && (t = !0);
15
+ var r = e == null || (n = e.getAttribute) === null || n === void 0 ? void 0 : n.call(e, "inert"), s = r === "" || r === "true", i = s || t && e && // closest does not exist on shadow roots, so we fall back to a manual
16
+ // lookup upward, in case it is not defined.
17
+ (typeof e.closest == "function" ? e.closest("[inert]") : Ee(e.parentNode));
18
+ return i;
19
+ }, Zt = function(e) {
20
+ var t, n = e == null || (t = e.getAttribute) === null || t === void 0 ? void 0 : t.call(e, "contenteditable");
21
+ return n === "" || n === "true";
22
+ }, ft = function(e, t, n) {
23
+ if (Ee(e))
24
+ return [];
25
+ var r = Array.prototype.slice.apply(e.querySelectorAll(_e));
26
+ return t && X.call(e, _e) && r.unshift(e), r = r.filter(n), r;
27
+ }, Te = function(e, t, n) {
28
+ for (var r = [], s = Array.from(e); s.length; ) {
29
+ var i = s.shift();
30
+ if (!Ee(i, !1))
31
+ if (i.tagName === "SLOT") {
32
+ var o = i.assignedElements(), l = o.length ? o : i.children, c = Te(l, !0, n);
33
+ n.flatten ? r.push.apply(r, c) : r.push({
34
+ scopeParent: i,
35
+ candidates: c
36
+ });
37
+ } else {
38
+ var f = X.call(i, _e);
39
+ f && n.filter(i) && (t || !e.includes(i)) && r.push(i);
40
+ var p = i.shadowRoot || // check for an undisclosed shadow
41
+ typeof n.getShadowRoot == "function" && n.getShadowRoot(i), v = !Ee(p, !1) && (!n.shadowRootFilter || n.shadowRootFilter(i));
42
+ if (p && v) {
43
+ var y = Te(p === !0 ? i.children : p.children, !0, n);
44
+ n.flatten ? r.push.apply(r, y) : r.push({
45
+ scopeParent: i,
46
+ candidates: y
47
+ });
48
+ } else
49
+ s.unshift.apply(s, i.children);
50
+ }
51
+ }
52
+ return r;
53
+ }, ht = function(e) {
54
+ return !isNaN(parseInt(e.getAttribute("tabindex"), 10));
55
+ }, Y = function(e) {
56
+ if (!e)
57
+ throw new Error("No node provided");
58
+ return e.tabIndex < 0 && (/^(AUDIO|VIDEO|DETAILS)$/.test(e.tagName) || Zt(e)) && !ht(e) ? 0 : e.tabIndex;
59
+ }, Xt = function(e, t) {
60
+ var n = Y(e);
61
+ return n < 0 && t && !ht(e) ? 0 : n;
62
+ }, en = function(e, t) {
63
+ return e.tabIndex === t.tabIndex ? e.documentOrder - t.documentOrder : e.tabIndex - t.tabIndex;
64
+ }, pt = function(e) {
65
+ return e.tagName === "INPUT";
66
+ }, tn = function(e) {
67
+ return pt(e) && e.type === "hidden";
68
+ }, nn = function(e) {
69
+ var t = e.tagName === "DETAILS" && Array.prototype.slice.apply(e.children).some(function(n) {
70
+ return n.tagName === "SUMMARY";
71
+ });
72
+ return t;
73
+ }, rn = function(e, t) {
74
+ for (var n = 0; n < e.length; n++)
75
+ if (e[n].checked && e[n].form === t)
76
+ return e[n];
77
+ }, sn = function(e) {
78
+ if (!e.name)
79
+ return !0;
80
+ var t = e.form || xe(e), n = function(o) {
81
+ return t.querySelectorAll('input[type="radio"][name="' + o + '"]');
82
+ }, r;
83
+ if (typeof window < "u" && typeof window.CSS < "u" && typeof window.CSS.escape == "function")
84
+ r = n(window.CSS.escape(e.name));
85
+ else
86
+ try {
87
+ r = n(e.name);
88
+ } catch (i) {
89
+ return 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", i.message), !1;
90
+ }
91
+ var s = rn(r, e.form);
92
+ return !s || s === e;
93
+ }, an = function(e) {
94
+ return pt(e) && e.type === "radio";
95
+ }, on = function(e) {
96
+ return an(e) && !sn(e);
97
+ }, ln = function(e) {
98
+ var t, n = e && xe(e), r = (t = n) === null || t === void 0 ? void 0 : t.host, s = !1;
99
+ if (n && n !== e) {
100
+ var i, o, l;
101
+ for (s = !!((i = r) !== null && i !== void 0 && (o = i.ownerDocument) !== null && o !== void 0 && o.contains(r) || e != null && (l = e.ownerDocument) !== null && l !== void 0 && l.contains(e)); !s && r; ) {
102
+ var c, f, p;
103
+ n = xe(r), r = (c = n) === null || c === void 0 ? void 0 : c.host, s = !!((f = r) !== null && f !== void 0 && (p = f.ownerDocument) !== null && p !== void 0 && p.contains(r));
104
+ }
105
+ }
106
+ return s;
107
+ }, et = function(e) {
108
+ var t = e.getBoundingClientRect(), n = t.width, r = t.height;
109
+ return n === 0 && r === 0;
110
+ }, cn = function(e, t) {
111
+ var n = t.displayCheck, r = t.getShadowRoot;
112
+ if (n === "full-native" && "checkVisibility" in e) {
113
+ var s = e.checkVisibility({
114
+ // Checking opacity might be desirable for some use cases, but natively,
115
+ // opacity zero elements _are_ focusable and tabbable.
116
+ checkOpacity: !1,
117
+ opacityProperty: !1,
118
+ contentVisibilityAuto: !0,
119
+ visibilityProperty: !0,
120
+ // This is an alias for `visibilityProperty`. Contemporary browsers
121
+ // support both. However, this alias has wider browser support (Chrome
122
+ // >= 105 and Firefox >= 106, vs. Chrome >= 121 and Firefox >= 122), so
123
+ // we include it anyway.
124
+ checkVisibilityCSS: !0
125
+ });
126
+ return !s;
127
+ }
128
+ if (getComputedStyle(e).visibility === "hidden")
129
+ return !0;
130
+ var i = X.call(e, "details>summary:first-of-type"), o = i ? e.parentElement : e;
131
+ if (X.call(o, "details:not([open]) *"))
132
+ return !0;
133
+ if (!n || n === "full" || // full-native can run this branch when it falls through in case
134
+ // Element#checkVisibility is unsupported
135
+ n === "full-native" || n === "legacy-full") {
136
+ if (typeof r == "function") {
137
+ for (var l = e; e; ) {
138
+ var c = e.parentElement, f = xe(e);
139
+ if (c && !c.shadowRoot && r(c) === !0)
140
+ return et(e);
141
+ e.assignedSlot ? e = e.assignedSlot : !c && f !== e.ownerDocument ? e = f.host : e = c;
142
+ }
143
+ e = l;
144
+ }
145
+ if (ln(e))
146
+ return !e.getClientRects().length;
147
+ if (n !== "legacy-full")
148
+ return !0;
149
+ } else if (n === "non-zero-area")
150
+ return et(e);
151
+ return !1;
152
+ }, un = function(e) {
153
+ if (/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(e.tagName))
154
+ for (var t = e.parentElement; t; ) {
155
+ if (t.tagName === "FIELDSET" && t.disabled) {
156
+ for (var n = 0; n < t.children.length; n++) {
157
+ var r = t.children.item(n);
158
+ if (r.tagName === "LEGEND")
159
+ return X.call(t, "fieldset[disabled] *") ? !0 : !r.contains(e);
160
+ }
161
+ return !0;
162
+ }
163
+ t = t.parentElement;
164
+ }
165
+ return !1;
166
+ }, Ie = function(e, t) {
167
+ return !(t.disabled || tn(t) || cn(t, e) || // For a details element with a summary, the summary element gets the focus
168
+ nn(t) || un(t));
169
+ }, De = function(e, t) {
170
+ return !(on(t) || Y(t) < 0 || !Ie(e, t));
171
+ }, dn = function(e) {
172
+ var t = parseInt(e.getAttribute("tabindex"), 10);
173
+ return !!(isNaN(t) || t >= 0);
174
+ }, vt = function(e) {
175
+ var t = [], n = [];
176
+ return e.forEach(function(r, s) {
177
+ var i = !!r.scopeParent, o = i ? r.scopeParent : r, l = Xt(o, i), c = i ? vt(r.candidates) : o;
178
+ l === 0 ? i ? t.push.apply(t, c) : t.push(o) : n.push({
179
+ documentOrder: s,
180
+ tabIndex: l,
181
+ item: r,
182
+ isScope: i,
183
+ content: c
184
+ });
185
+ }), n.sort(en).reduce(function(r, s) {
186
+ return s.isScope ? r.push.apply(r, s.content) : r.push(s.content), r;
187
+ }, []).concat(t);
188
+ }, fn = function(e, t) {
189
+ t = t || {};
190
+ var n;
191
+ return t.getShadowRoot ? n = Te([e], t.includeContainer, {
192
+ filter: De.bind(null, t),
193
+ flatten: !1,
194
+ getShadowRoot: t.getShadowRoot,
195
+ shadowRootFilter: dn
196
+ }) : n = ft(e, t.includeContainer, De.bind(null, t)), vt(n);
197
+ }, hn = function(e, t) {
198
+ t = t || {};
199
+ var n;
200
+ return t.getShadowRoot ? n = Te([e], t.includeContainer, {
201
+ filter: Ie.bind(null, t),
202
+ flatten: !0,
203
+ getShadowRoot: t.getShadowRoot
204
+ }) : n = ft(e, t.includeContainer, Ie.bind(null, t)), n;
205
+ }, te = function(e, t) {
206
+ if (t = t || {}, !e)
207
+ throw new Error("No node provided");
208
+ return X.call(e, _e) === !1 ? !1 : De(t, e);
209
+ }, pn = /* @__PURE__ */ ut.concat("iframe:not([inert]):not([inert] *)").join(","), Fe = function(e, t) {
210
+ if (t = t || {}, !e)
211
+ throw new Error("No node provided");
212
+ return X.call(e, pn) === !1 ? !1 : Ie(t, e);
213
+ };
214
+ function Pe(a, e) {
215
+ (e == null || e > a.length) && (e = a.length);
216
+ for (var t = 0, n = Array(e); t < e; t++) n[t] = a[t];
217
+ return n;
218
+ }
219
+ function vn(a) {
220
+ if (Array.isArray(a)) return Pe(a);
221
+ }
222
+ function tt(a, e) {
223
+ var t = typeof Symbol < "u" && a[Symbol.iterator] || a["@@iterator"];
224
+ if (!t) {
225
+ if (Array.isArray(a) || (t = mt(a)) || e) {
226
+ t && (a = t);
227
+ var n = 0, r = function() {
228
+ };
229
+ return {
230
+ s: r,
231
+ n: function() {
232
+ return n >= a.length ? {
233
+ done: !0
234
+ } : {
235
+ done: !1,
236
+ value: a[n++]
237
+ };
238
+ },
239
+ e: function(l) {
240
+ throw l;
241
+ },
242
+ f: r
243
+ };
244
+ }
245
+ throw new TypeError(`Invalid attempt to iterate non-iterable instance.
246
+ In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`);
247
+ }
248
+ var s, i = !0, o = !1;
249
+ return {
250
+ s: function() {
251
+ t = t.call(a);
252
+ },
253
+ n: function() {
254
+ var l = t.next();
255
+ return i = l.done, l;
256
+ },
257
+ e: function(l) {
258
+ o = !0, s = l;
259
+ },
260
+ f: function() {
261
+ try {
262
+ i || t.return == null || t.return();
263
+ } finally {
264
+ if (o) throw s;
265
+ }
266
+ }
267
+ };
268
+ }
269
+ function mn(a, e, t) {
270
+ return (e = Sn(e)) in a ? Object.defineProperty(a, e, {
271
+ value: t,
272
+ enumerable: !0,
273
+ configurable: !0,
274
+ writable: !0
275
+ }) : a[e] = t, a;
276
+ }
277
+ function gn(a) {
278
+ if (typeof Symbol < "u" && a[Symbol.iterator] != null || a["@@iterator"] != null) return Array.from(a);
279
+ }
280
+ function bn() {
281
+ throw new TypeError(`Invalid attempt to spread non-iterable instance.
282
+ In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`);
283
+ }
284
+ function nt(a, e) {
285
+ var t = Object.keys(a);
286
+ if (Object.getOwnPropertySymbols) {
287
+ var n = Object.getOwnPropertySymbols(a);
288
+ e && (n = n.filter(function(r) {
289
+ return Object.getOwnPropertyDescriptor(a, r).enumerable;
290
+ })), t.push.apply(t, n);
291
+ }
292
+ return t;
293
+ }
294
+ function it(a) {
295
+ for (var e = 1; e < arguments.length; e++) {
296
+ var t = arguments[e] != null ? arguments[e] : {};
297
+ e % 2 ? nt(Object(t), !0).forEach(function(n) {
298
+ mn(a, n, t[n]);
299
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(a, Object.getOwnPropertyDescriptors(t)) : nt(Object(t)).forEach(function(n) {
300
+ Object.defineProperty(a, n, Object.getOwnPropertyDescriptor(t, n));
301
+ });
302
+ }
303
+ return a;
304
+ }
305
+ function yn(a) {
306
+ return vn(a) || gn(a) || mt(a) || bn();
307
+ }
308
+ function wn(a, e) {
309
+ if (typeof a != "object" || !a) return a;
310
+ var t = a[Symbol.toPrimitive];
311
+ if (t !== void 0) {
312
+ var n = t.call(a, e);
313
+ if (typeof n != "object") return n;
314
+ throw new TypeError("@@toPrimitive must return a primitive value.");
315
+ }
316
+ return (e === "string" ? String : Number)(a);
317
+ }
318
+ function Sn(a) {
319
+ var e = wn(a, "string");
320
+ return typeof e == "symbol" ? e : e + "";
321
+ }
322
+ function mt(a, e) {
323
+ if (a) {
324
+ if (typeof a == "string") return Pe(a, e);
325
+ var t = {}.toString.call(a).slice(8, -1);
326
+ return t === "Object" && a.constructor && (t = a.constructor.name), t === "Map" || t === "Set" ? Array.from(a) : t === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? Pe(a, e) : void 0;
327
+ }
328
+ }
329
+ var W = {
330
+ // Returns the trap from the top of the stack.
331
+ getActiveTrap: function(e) {
332
+ return e?.length > 0 ? e[e.length - 1] : null;
333
+ },
334
+ // Pauses the currently active trap, then adds a new trap to the stack.
335
+ activateTrap: function(e, t) {
336
+ var n = W.getActiveTrap(e);
337
+ t !== n && W.pauseTrap(e);
338
+ var r = e.indexOf(t);
339
+ r === -1 || e.splice(r, 1), e.push(t);
340
+ },
341
+ // Removes the trap from the top of the stack, then unpauses the next trap down.
342
+ deactivateTrap: function(e, t) {
343
+ var n = e.indexOf(t);
344
+ n !== -1 && e.splice(n, 1), W.unpauseTrap(e);
345
+ },
346
+ // Pauses the trap at the top of the stack.
347
+ pauseTrap: function(e) {
348
+ var t = W.getActiveTrap(e);
349
+ t?._setPausedState(!0);
350
+ },
351
+ // Unpauses the trap at the top of the stack.
352
+ unpauseTrap: function(e) {
353
+ var t = W.getActiveTrap(e);
354
+ t && !t._isManuallyPaused() && t._setPausedState(!1);
355
+ }
356
+ }, _n = function(e) {
357
+ return e.tagName && e.tagName.toLowerCase() === "input" && typeof e.select == "function";
358
+ }, xn = function(e) {
359
+ return e?.key === "Escape" || e?.key === "Esc" || e?.keyCode === 27;
360
+ }, ve = function(e) {
361
+ return e?.key === "Tab" || e?.keyCode === 9;
362
+ }, En = function(e) {
363
+ return ve(e) && !e.shiftKey;
364
+ }, Tn = function(e) {
365
+ return ve(e) && e.shiftKey;
366
+ }, rt = function(e) {
367
+ return setTimeout(e, 0);
368
+ }, pe = function(e) {
369
+ for (var t = arguments.length, n = new Array(t > 1 ? t - 1 : 0), r = 1; r < t; r++)
370
+ n[r - 1] = arguments[r];
371
+ return typeof e == "function" ? e.apply(void 0, n) : e;
372
+ }, be = function(e) {
373
+ return e.target.shadowRoot && typeof e.composedPath == "function" ? e.composedPath()[0] : e.target;
374
+ }, In = [], kn = function(e, t) {
375
+ var n = t?.document || document, r = t?.trapStack || In, s = it({
376
+ returnFocusOnDeactivate: !0,
377
+ escapeDeactivates: !0,
378
+ delayInitialFocus: !0,
379
+ isolateSubtrees: !1,
380
+ isKeyForward: En,
381
+ isKeyBackward: Tn
382
+ }, t), i = {
383
+ // containers given to createFocusTrap()
384
+ /** @type {Array<HTMLElement>} */
385
+ containers: [],
386
+ // list of objects identifying tabbable nodes in `containers` in the trap
387
+ // NOTE: it's possible that a group has no tabbable nodes if nodes get removed while the trap
388
+ // is active, but the trap should never get to a state where there isn't at least one group
389
+ // with at least one tabbable node in it (that would lead to an error condition that would
390
+ // result in an error being thrown)
391
+ /** @type {Array<{
392
+ * container: HTMLElement,
393
+ * tabbableNodes: Array<HTMLElement>, // empty if none
394
+ * focusableNodes: Array<HTMLElement>, // empty if none
395
+ * posTabIndexesFound: boolean,
396
+ * firstTabbableNode: HTMLElement|undefined,
397
+ * lastTabbableNode: HTMLElement|undefined,
398
+ * firstDomTabbableNode: HTMLElement|undefined,
399
+ * lastDomTabbableNode: HTMLElement|undefined,
400
+ * nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined
401
+ * }>}
402
+ */
403
+ containerGroups: [],
404
+ // same order/length as `containers` list
405
+ // references to objects in `containerGroups`, but only those that actually have
406
+ // tabbable nodes in them
407
+ // NOTE: same order as `containers` and `containerGroups`, but __not necessarily__
408
+ // the same length
409
+ tabbableGroups: [],
410
+ // references to nodes that are siblings to the ancestors of this trap's containers.
411
+ /** @type {Set<HTMLElement>} */
412
+ adjacentElements: /* @__PURE__ */ new Set(),
413
+ // references to nodes that were inert or aria-hidden before the trap was activated.
414
+ /** @type {Set<HTMLElement>} */
415
+ alreadySilent: /* @__PURE__ */ new Set(),
416
+ nodeFocusedBeforeActivation: null,
417
+ mostRecentlyFocusedNode: null,
418
+ active: !1,
419
+ paused: !1,
420
+ manuallyPaused: !1,
421
+ // timer ID for when delayInitialFocus is true and initial focus in this trap
422
+ // has been delayed during activation
423
+ delayInitialFocusTimer: void 0,
424
+ // the most recent KeyboardEvent for the configured nav key (typically [SHIFT+]TAB), if any
425
+ recentNavEvent: void 0
426
+ }, o, l = function(u, d, b) {
427
+ return u && u[d] !== void 0 ? u[d] : s[b || d];
428
+ }, c = function(u, d) {
429
+ var b = typeof d?.composedPath == "function" ? d.composedPath() : void 0;
430
+ return i.containerGroups.findIndex(function(I) {
431
+ var m = I.container, h = I.tabbableNodes;
432
+ return m.contains(u) || b?.includes(m) || h.find(function(g) {
433
+ return g === u;
434
+ });
435
+ });
436
+ }, f = function(u) {
437
+ var d = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, b = d.hasFallback, I = b === void 0 ? !1 : b, m = d.params, h = m === void 0 ? [] : m, g = s[u];
438
+ if (typeof g == "function" && (g = g.apply(void 0, yn(h))), g === !0 && (g = void 0), !g) {
439
+ if (g === void 0 || g === !1)
440
+ return g;
441
+ throw new Error("`".concat(u, "` was specified but was not a node, or did not return a node"));
442
+ }
443
+ var E = g;
444
+ if (typeof g == "string") {
445
+ try {
446
+ E = n.querySelector(g);
447
+ } catch (k) {
448
+ throw new Error("`".concat(u, '` appears to be an invalid selector; error="').concat(k.message, '"'));
449
+ }
450
+ if (!E && !I)
451
+ throw new Error("`".concat(u, "` as selector refers to no known node"));
452
+ }
453
+ return E;
454
+ }, p = function() {
455
+ var u = f("initialFocus", {
456
+ hasFallback: !0
457
+ });
458
+ if (u === !1)
459
+ return !1;
460
+ if (u === void 0 || u && !Fe(u, s.tabbableOptions))
461
+ if (c(n.activeElement) >= 0)
462
+ u = n.activeElement;
463
+ else {
464
+ var d = i.tabbableGroups[0], b = d && d.firstTabbableNode;
465
+ u = b || f("fallbackFocus");
466
+ }
467
+ else u === null && (u = f("fallbackFocus"));
468
+ if (!u)
469
+ throw new Error("Your focus-trap needs to have at least one focusable element");
470
+ return u;
471
+ }, v = function() {
472
+ if (i.containerGroups = i.containers.map(function(u) {
473
+ var d = fn(u, s.tabbableOptions), b = hn(u, s.tabbableOptions), I = d.length > 0 ? d[0] : void 0, m = d.length > 0 ? d[d.length - 1] : void 0, h = b.find(function(k) {
474
+ return te(k);
475
+ }), g = b.slice().reverse().find(function(k) {
476
+ return te(k);
477
+ }), E = !!d.find(function(k) {
478
+ return Y(k) > 0;
479
+ });
480
+ return {
481
+ container: u,
482
+ tabbableNodes: d,
483
+ focusableNodes: b,
484
+ /** True if at least one node with positive `tabindex` was found in this container. */
485
+ posTabIndexesFound: E,
486
+ /** First tabbable node in container, __tabindex__ order; `undefined` if none. */
487
+ firstTabbableNode: I,
488
+ /** Last tabbable node in container, __tabindex__ order; `undefined` if none. */
489
+ lastTabbableNode: m,
490
+ // NOTE: DOM order is NOT NECESSARILY "document position" order, but figuring that out
491
+ // would require more than just https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
492
+ // because that API doesn't work with Shadow DOM as well as it should (@see
493
+ // https://github.com/whatwg/dom/issues/320) and since this first/last is only needed, so far,
494
+ // to address an edge case related to positive tabindex support, this seems like a much easier,
495
+ // "close enough most of the time" alternative for positive tabindexes which should generally
496
+ // be avoided anyway...
497
+ /** First tabbable node in container, __DOM__ order; `undefined` if none. */
498
+ firstDomTabbableNode: h,
499
+ /** Last tabbable node in container, __DOM__ order; `undefined` if none. */
500
+ lastDomTabbableNode: g,
501
+ /**
502
+ * Finds the __tabbable__ node that follows the given node in the specified direction,
503
+ * in this container, if any.
504
+ * @param {HTMLElement} node
505
+ * @param {boolean} [forward] True if going in forward tab order; false if going
506
+ * in reverse.
507
+ * @returns {HTMLElement|undefined} The next tabbable node, if any.
508
+ */
509
+ nextTabbableNode: function(R) {
510
+ var P = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : !0, D = d.indexOf(R);
511
+ return D < 0 ? P ? b.slice(b.indexOf(R) + 1).find(function($) {
512
+ return te($);
513
+ }) : b.slice(0, b.indexOf(R)).reverse().find(function($) {
514
+ return te($);
515
+ }) : d[D + (P ? 1 : -1)];
516
+ }
517
+ };
518
+ }), i.tabbableGroups = i.containerGroups.filter(function(u) {
519
+ return u.tabbableNodes.length > 0;
520
+ }), i.tabbableGroups.length <= 0 && !f("fallbackFocus"))
521
+ throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");
522
+ if (i.containerGroups.find(function(u) {
523
+ return u.posTabIndexesFound;
524
+ }) && i.containerGroups.length > 1)
525
+ 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.");
526
+ }, y = function(u) {
527
+ var d = u.activeElement;
528
+ if (d)
529
+ return d.shadowRoot && d.shadowRoot.activeElement !== null ? y(d.shadowRoot) : d;
530
+ }, S = function(u) {
531
+ if (u !== !1 && u !== y(document)) {
532
+ if (!u || !u.focus) {
533
+ S(p());
534
+ return;
535
+ }
536
+ u.focus({
537
+ preventScroll: !!s.preventScroll
538
+ }), i.mostRecentlyFocusedNode = u, _n(u) && u.select();
539
+ }
540
+ }, w = function(u) {
541
+ var d = f("setReturnFocus", {
542
+ params: [u]
543
+ });
544
+ return d || (d === !1 ? !1 : u);
545
+ }, _ = function(u) {
546
+ var d = u.target, b = u.event, I = u.isBackward, m = I === void 0 ? !1 : I;
547
+ d = d || be(b), v();
548
+ var h = null;
549
+ if (i.tabbableGroups.length > 0) {
550
+ var g = c(d, b), E = g >= 0 ? i.containerGroups[g] : void 0;
551
+ if (g < 0)
552
+ m ? h = i.tabbableGroups[i.tabbableGroups.length - 1].lastTabbableNode : h = i.tabbableGroups[0].firstTabbableNode;
553
+ else if (m) {
554
+ var k = i.tabbableGroups.findIndex(function(J) {
555
+ var U = J.firstTabbableNode;
556
+ return d === U;
557
+ });
558
+ if (k < 0 && (E.container === d || Fe(d, s.tabbableOptions) && !te(d, s.tabbableOptions) && !E.nextTabbableNode(d, !1)) && (k = g), k >= 0) {
559
+ var R = k === 0 ? i.tabbableGroups.length - 1 : k - 1, P = i.tabbableGroups[R];
560
+ h = Y(d) >= 0 ? P.lastTabbableNode : P.lastDomTabbableNode;
561
+ } else ve(b) || (h = E.nextTabbableNode(d, !1));
562
+ } else {
563
+ var D = i.tabbableGroups.findIndex(function(J) {
564
+ var U = J.lastTabbableNode;
565
+ return d === U;
566
+ });
567
+ if (D < 0 && (E.container === d || Fe(d, s.tabbableOptions) && !te(d, s.tabbableOptions) && !E.nextTabbableNode(d)) && (D = g), D >= 0) {
568
+ var $ = D === i.tabbableGroups.length - 1 ? 0 : D + 1, A = i.tabbableGroups[$];
569
+ h = Y(d) >= 0 ? A.firstTabbableNode : A.firstDomTabbableNode;
570
+ } else ve(b) || (h = E.nextTabbableNode(d));
571
+ }
572
+ } else
573
+ h = f("fallbackFocus");
574
+ return h;
575
+ }, N = function(u) {
576
+ var d = be(u);
577
+ if (!(c(d, u) >= 0)) {
578
+ if (pe(s.clickOutsideDeactivates, u)) {
579
+ o.deactivate({
580
+ // NOTE: by setting `returnFocus: false`, deactivate() will do nothing,
581
+ // which will result in the outside click setting focus to the node
582
+ // that was clicked (and if not focusable, to "nothing"); by setting
583
+ // `returnFocus: true`, we'll attempt to re-focus the node originally-focused
584
+ // on activation (or the configured `setReturnFocus` node), whether the
585
+ // outside click was on a focusable node or not
586
+ returnFocus: s.returnFocusOnDeactivate
587
+ });
588
+ return;
589
+ }
590
+ pe(s.allowOutsideClick, u) || u.preventDefault();
591
+ }
592
+ }, F = function(u) {
593
+ var d = be(u), b = c(d, u) >= 0;
594
+ if (b || d instanceof Document)
595
+ b && (i.mostRecentlyFocusedNode = d);
596
+ else {
597
+ u.stopImmediatePropagation();
598
+ var I, m = !0;
599
+ if (i.mostRecentlyFocusedNode)
600
+ if (Y(i.mostRecentlyFocusedNode) > 0) {
601
+ var h = c(i.mostRecentlyFocusedNode), g = i.containerGroups[h].tabbableNodes;
602
+ if (g.length > 0) {
603
+ var E = g.findIndex(function(k) {
604
+ return k === i.mostRecentlyFocusedNode;
605
+ });
606
+ E >= 0 && (s.isKeyForward(i.recentNavEvent) ? E + 1 < g.length && (I = g[E + 1], m = !1) : E - 1 >= 0 && (I = g[E - 1], m = !1));
607
+ }
608
+ } else
609
+ i.containerGroups.some(function(k) {
610
+ return k.tabbableNodes.some(function(R) {
611
+ return Y(R) > 0;
612
+ });
613
+ }) || (m = !1);
614
+ else
615
+ m = !1;
616
+ m && (I = _({
617
+ // move FROM the MRU node, not event-related node (which will be the node that is
618
+ // outside the trap causing the focus escape we're trying to fix)
619
+ target: i.mostRecentlyFocusedNode,
620
+ isBackward: s.isKeyBackward(i.recentNavEvent)
621
+ })), S(I || i.mostRecentlyFocusedNode || p());
622
+ }
623
+ i.recentNavEvent = void 0;
624
+ }, G = function(u) {
625
+ var d = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : !1;
626
+ i.recentNavEvent = u;
627
+ var b = _({
628
+ event: u,
629
+ isBackward: d
630
+ });
631
+ b && (ve(u) && u.preventDefault(), S(b));
632
+ }, z = function(u) {
633
+ (s.isKeyForward(u) || s.isKeyBackward(u)) && G(u, s.isKeyBackward(u));
634
+ }, j = function(u) {
635
+ xn(u) && pe(s.escapeDeactivates, u) !== !1 && (u.preventDefault(), o.deactivate());
636
+ }, L = function(u) {
637
+ var d = be(u);
638
+ c(d, u) >= 0 || pe(s.clickOutsideDeactivates, u) || pe(s.allowOutsideClick, u) || (u.preventDefault(), u.stopImmediatePropagation());
639
+ }, V = function() {
640
+ if (i.active)
641
+ return W.activateTrap(r, o), i.delayInitialFocusTimer = s.delayInitialFocus ? rt(function() {
642
+ S(p());
643
+ }) : S(p()), n.addEventListener("focusin", F, !0), n.addEventListener("mousedown", N, {
644
+ capture: !0,
645
+ passive: !1
646
+ }), n.addEventListener("touchstart", N, {
647
+ capture: !0,
648
+ passive: !1
649
+ }), n.addEventListener("click", L, {
650
+ capture: !0,
651
+ passive: !1
652
+ }), n.addEventListener("keydown", z, {
653
+ capture: !0,
654
+ passive: !1
655
+ }), n.addEventListener("keydown", j), o;
656
+ }, O = function(u) {
657
+ i.active && !i.paused && o._setSubtreeIsolation(!1), i.adjacentElements.clear(), i.alreadySilent.clear();
658
+ var d = /* @__PURE__ */ new Set(), b = /* @__PURE__ */ new Set(), I = tt(u), m;
659
+ try {
660
+ for (I.s(); !(m = I.n()).done; ) {
661
+ var h = m.value;
662
+ d.add(h);
663
+ for (var g = typeof ShadowRoot < "u" && h.getRootNode() instanceof ShadowRoot, E = h; E; ) {
664
+ d.add(E);
665
+ var k = E.parentElement, R = [];
666
+ k ? R = k.children : !k && g && (R = E.getRootNode().children, k = E.getRootNode().host, g = typeof ShadowRoot < "u" && k.getRootNode() instanceof ShadowRoot);
667
+ var P = tt(R), D;
668
+ try {
669
+ for (P.s(); !(D = P.n()).done; ) {
670
+ var $ = D.value;
671
+ b.add($);
672
+ }
673
+ } catch (A) {
674
+ P.e(A);
675
+ } finally {
676
+ P.f();
677
+ }
678
+ E = k;
679
+ }
680
+ }
681
+ } catch (A) {
682
+ I.e(A);
683
+ } finally {
684
+ I.f();
685
+ }
686
+ d.forEach(function(A) {
687
+ b.delete(A);
688
+ }), i.adjacentElements = b;
689
+ }, K = function() {
690
+ if (i.active)
691
+ return n.removeEventListener("focusin", F, !0), n.removeEventListener("mousedown", N, !0), n.removeEventListener("touchstart", N, !0), n.removeEventListener("click", L, !0), n.removeEventListener("keydown", z, !0), n.removeEventListener("keydown", j), o;
692
+ }, se = function(u) {
693
+ var d = u.some(function(b) {
694
+ var I = Array.from(b.removedNodes);
695
+ return I.some(function(m) {
696
+ return m === i.mostRecentlyFocusedNode;
697
+ });
698
+ });
699
+ d && S(p());
700
+ }, ae = typeof window < "u" && "MutationObserver" in window ? new MutationObserver(se) : void 0, ee = function() {
701
+ ae && (ae.disconnect(), i.active && !i.paused && i.containers.map(function(u) {
702
+ ae.observe(u, {
703
+ subtree: !0,
704
+ childList: !0
705
+ });
706
+ }));
707
+ };
708
+ return o = {
709
+ get active() {
710
+ return i.active;
711
+ },
712
+ get paused() {
713
+ return i.paused;
714
+ },
715
+ activate: function(u) {
716
+ if (i.active)
717
+ return this;
718
+ var d = l(u, "onActivate"), b = l(u, "onPostActivate"), I = l(u, "checkCanFocusTrap"), m = W.getActiveTrap(r), h = !1;
719
+ if (m && !m.paused) {
720
+ var g;
721
+ (g = m._setSubtreeIsolation) === null || g === void 0 || g.call(m, !1), h = !0;
722
+ }
723
+ try {
724
+ I || v(), i.active = !0, i.paused = !1, i.nodeFocusedBeforeActivation = y(n), d?.();
725
+ var E = function() {
726
+ I && v(), V(), ee(), s.isolateSubtrees && o._setSubtreeIsolation(!0), b?.();
727
+ };
728
+ if (I)
729
+ return I(i.containers.concat()).then(E, E), this;
730
+ E();
731
+ } catch (R) {
732
+ if (m === W.getActiveTrap(r) && h) {
733
+ var k;
734
+ (k = m._setSubtreeIsolation) === null || k === void 0 || k.call(m, !0);
735
+ }
736
+ throw R;
737
+ }
738
+ return this;
739
+ },
740
+ deactivate: function(u) {
741
+ if (!i.active)
742
+ return this;
743
+ var d = it({
744
+ onDeactivate: s.onDeactivate,
745
+ onPostDeactivate: s.onPostDeactivate,
746
+ checkCanReturnFocus: s.checkCanReturnFocus
747
+ }, u);
748
+ clearTimeout(i.delayInitialFocusTimer), i.delayInitialFocusTimer = void 0, i.paused || o._setSubtreeIsolation(!1), i.alreadySilent.clear(), K(), i.active = !1, i.paused = !1, ee(), W.deactivateTrap(r, o);
749
+ var b = l(d, "onDeactivate"), I = l(d, "onPostDeactivate"), m = l(d, "checkCanReturnFocus"), h = l(d, "returnFocus", "returnFocusOnDeactivate");
750
+ b?.();
751
+ var g = function() {
752
+ rt(function() {
753
+ h && S(w(i.nodeFocusedBeforeActivation)), I?.();
754
+ });
755
+ };
756
+ return h && m ? (m(w(i.nodeFocusedBeforeActivation)).then(g, g), this) : (g(), this);
757
+ },
758
+ pause: function(u) {
759
+ return i.active ? (i.manuallyPaused = !0, this._setPausedState(!0, u)) : this;
760
+ },
761
+ unpause: function(u) {
762
+ return i.active ? (i.manuallyPaused = !1, r[r.length - 1] !== this ? this : this._setPausedState(!1, u)) : this;
763
+ },
764
+ updateContainerElements: function(u) {
765
+ var d = [].concat(u).filter(Boolean);
766
+ return i.containers = d.map(function(b) {
767
+ return typeof b == "string" ? n.querySelector(b) : b;
768
+ }), s.isolateSubtrees && O(i.containers), i.active && (v(), s.isolateSubtrees && !i.paused && o._setSubtreeIsolation(!0)), ee(), this;
769
+ }
770
+ }, Object.defineProperties(o, {
771
+ _isManuallyPaused: {
772
+ value: function() {
773
+ return i.manuallyPaused;
774
+ }
775
+ },
776
+ _setPausedState: {
777
+ value: function(u, d) {
778
+ if (i.paused === u)
779
+ return this;
780
+ if (i.paused = u, u) {
781
+ var b = l(d, "onPause"), I = l(d, "onPostPause");
782
+ b?.(), K(), ee(), o._setSubtreeIsolation(!1), I?.();
783
+ } else {
784
+ var m = l(d, "onUnpause"), h = l(d, "onPostUnpause");
785
+ m?.(), o._setSubtreeIsolation(!0), v(), V(), ee(), h?.();
786
+ }
787
+ return this;
788
+ }
789
+ },
790
+ _setSubtreeIsolation: {
791
+ value: function(u) {
792
+ s.isolateSubtrees && i.adjacentElements.forEach(function(d) {
793
+ var b;
794
+ u ? s.isolateSubtrees === "aria-hidden" ? ((d.ariaHidden === "true" || ((b = d.getAttribute("aria-hidden")) === null || b === void 0 ? void 0 : b.toLowerCase()) === "true") && i.alreadySilent.add(d), d.setAttribute("aria-hidden", "true")) : ((d.inert || d.hasAttribute("inert")) && i.alreadySilent.add(d), d.setAttribute("inert", !0)) : i.alreadySilent.has(d) || (s.isolateSubtrees === "aria-hidden" ? d.removeAttribute("aria-hidden") : d.removeAttribute("inert"));
795
+ });
796
+ }
797
+ }
798
+ }), o.updateContainerElements(e), o;
799
+ };
800
+ function Nn(a, e = {}) {
801
+ let t;
802
+ const { immediate: n, ...r } = e, s = Z(!1), i = Z(!1), o = (p) => t && t.activate(p), l = (p) => t && t.deactivate(p), c = () => {
803
+ t && (t.pause(), i.value = !0);
804
+ }, f = () => {
805
+ t && (t.unpause(), i.value = !1);
806
+ };
807
+ return Le(Se(() => Dt(He(a)).map((p) => {
808
+ const v = He(p);
809
+ return typeof v == "string" ? v : Pt(v);
810
+ }).filter(zt)), (p) => {
811
+ if (p.length)
812
+ if (!t)
813
+ t = kn(p, {
814
+ ...r,
815
+ onActivate() {
816
+ s.value = !0, e.onActivate && e.onActivate();
817
+ },
818
+ onDeactivate() {
819
+ s.value = !1, e.onDeactivate && e.onDeactivate();
820
+ }
821
+ }), n && o();
822
+ else {
823
+ const v = t?.active;
824
+ t?.updateContainerElements(p), !v && n && o();
825
+ }
826
+ }, { flush: "post" }), Vt(() => l()), {
827
+ hasFocus: s,
828
+ isPaused: i,
829
+ activate: o,
830
+ deactivate: l,
831
+ pause: c,
832
+ unpause: f
833
+ };
834
+ }
835
+ class ie {
836
+ /**
837
+ * @param {HTMLElement|HTMLElement[]|NodeList|string} ctx - The context DOM
838
+ * element, an array of DOM elements, a NodeList or a selector
839
+ * @param {boolean} [iframes=true] - A boolean indicating if iframes should
840
+ * be handled
841
+ * @param {string[]} [exclude=[]] - An array containing exclusion selectors
842
+ * for iframes
843
+ * @param {number} [iframesTimeout=5000] - A number indicating the ms to
844
+ * wait before an iframe should be skipped, in case the load event isn't
845
+ * fired. This also applies if the user is offline and the resource of the
846
+ * iframe is online (either by the browsers "offline" mode or because
847
+ * there's no internet connection)
848
+ */
849
+ constructor(e, t = !0, n = [], r = 5e3) {
850
+ this.ctx = e, this.iframes = t, this.exclude = n, this.iframesTimeout = r;
851
+ }
852
+ /**
853
+ * Checks if the specified DOM element matches the selector
854
+ * @param {HTMLElement} element - The DOM element
855
+ * @param {string|string[]} selector - The selector or an array with
856
+ * selectors
857
+ * @return {boolean}
858
+ * @access public
859
+ */
860
+ static matches(e, t) {
861
+ const n = typeof t == "string" ? [t] : t, r = e.matches || e.matchesSelector || e.msMatchesSelector || e.mozMatchesSelector || e.oMatchesSelector || e.webkitMatchesSelector;
862
+ if (r) {
863
+ let s = !1;
864
+ return n.every((i) => r.call(e, i) ? (s = !0, !1) : !0), s;
865
+ } else
866
+ return !1;
867
+ }
868
+ /**
869
+ * Returns all contexts filtered by duplicates (even nested)
870
+ * @return {HTMLElement[]} - An array containing DOM contexts
871
+ * @access protected
872
+ */
873
+ getContexts() {
874
+ let e, t = [];
875
+ return typeof this.ctx > "u" || !this.ctx ? e = [] : NodeList.prototype.isPrototypeOf(this.ctx) ? e = Array.prototype.slice.call(this.ctx) : Array.isArray(this.ctx) ? e = this.ctx : typeof this.ctx == "string" ? e = Array.prototype.slice.call(
876
+ document.querySelectorAll(this.ctx)
877
+ ) : e = [this.ctx], e.forEach((n) => {
878
+ const r = t.filter((s) => s.contains(n)).length > 0;
879
+ t.indexOf(n) === -1 && !r && t.push(n);
880
+ }), t;
881
+ }
882
+ /**
883
+ * @callback DOMIterator~getIframeContentsSuccessCallback
884
+ * @param {HTMLDocument} contents - The contentDocument of the iframe
885
+ */
886
+ /**
887
+ * Calls the success callback function with the iframe document. If it can't
888
+ * be accessed it calls the error callback function
889
+ * @param {HTMLElement} ifr - The iframe DOM element
890
+ * @param {DOMIterator~getIframeContentsSuccessCallback} successFn
891
+ * @param {function} [errorFn]
892
+ * @access protected
893
+ */
894
+ getIframeContents(e, t, n = () => {
895
+ }) {
896
+ let r;
897
+ try {
898
+ const s = e.contentWindow;
899
+ if (r = s.document, !s || !r)
900
+ throw new Error("iframe inaccessible");
901
+ } catch {
902
+ n();
903
+ }
904
+ r && t(r);
905
+ }
906
+ /**
907
+ * Checks if an iframe is empty (if about:blank is the shown page)
908
+ * @param {HTMLElement} ifr - The iframe DOM element
909
+ * @return {boolean}
910
+ * @access protected
911
+ */
912
+ isIframeBlank(e) {
913
+ const t = "about:blank", n = e.getAttribute("src").trim();
914
+ return e.contentWindow.location.href === t && n !== t && n;
915
+ }
916
+ /**
917
+ * Observes the onload event of an iframe and calls the success callback or
918
+ * the error callback if the iframe is inaccessible. If the event isn't
919
+ * fired within the specified {@link DOMIterator#iframesTimeout}, then it'll
920
+ * call the error callback too
921
+ * @param {HTMLElement} ifr - The iframe DOM element
922
+ * @param {DOMIterator~getIframeContentsSuccessCallback} successFn
923
+ * @param {function} errorFn
924
+ * @access protected
925
+ */
926
+ observeIframeLoad(e, t, n) {
927
+ let r = !1, s = null;
928
+ const i = () => {
929
+ if (!r) {
930
+ r = !0, clearTimeout(s);
931
+ try {
932
+ this.isIframeBlank(e) || (e.removeEventListener("load", i), this.getIframeContents(e, t, n));
933
+ } catch {
934
+ n();
935
+ }
936
+ }
937
+ };
938
+ e.addEventListener("load", i), s = setTimeout(i, this.iframesTimeout);
939
+ }
940
+ /**
941
+ * Callback when the iframe is ready
942
+ * @callback DOMIterator~onIframeReadySuccessCallback
943
+ * @param {HTMLDocument} contents - The contentDocument of the iframe
944
+ */
945
+ /**
946
+ * Callback if the iframe can't be accessed
947
+ * @callback DOMIterator~onIframeReadyErrorCallback
948
+ */
949
+ /**
950
+ * Calls the callback if the specified iframe is ready for DOM access
951
+ * @param {HTMLElement} ifr - The iframe DOM element
952
+ * @param {DOMIterator~onIframeReadySuccessCallback} successFn - Success
953
+ * callback
954
+ * @param {DOMIterator~onIframeReadyErrorCallback} errorFn - Error callback
955
+ * @see {@link http://stackoverflow.com/a/36155560/3894981} for
956
+ * background information
957
+ * @access protected
958
+ */
959
+ onIframeReady(e, t, n) {
960
+ try {
961
+ e.contentWindow.document.readyState === "complete" ? this.isIframeBlank(e) ? this.observeIframeLoad(e, t, n) : this.getIframeContents(e, t, n) : this.observeIframeLoad(e, t, n);
962
+ } catch {
963
+ n();
964
+ }
965
+ }
966
+ /**
967
+ * Callback when all iframes are ready for DOM access
968
+ * @callback DOMIterator~waitForIframesDoneCallback
969
+ */
970
+ /**
971
+ * Iterates over all iframes and calls the done callback when all of them
972
+ * are ready for DOM access (including nested ones)
973
+ * @param {HTMLElement} ctx - The context DOM element
974
+ * @param {DOMIterator~waitForIframesDoneCallback} done - Done callback
975
+ */
976
+ waitForIframes(e, t) {
977
+ let n = 0;
978
+ this.forEachIframe(e, () => !0, (r) => {
979
+ n++, this.waitForIframes(r.querySelector("html"), () => {
980
+ --n || t();
981
+ });
982
+ }, (r) => {
983
+ r || t();
984
+ });
985
+ }
986
+ /**
987
+ * Callback allowing to filter an iframe. Must return true when the element
988
+ * should remain, otherwise false
989
+ * @callback DOMIterator~forEachIframeFilterCallback
990
+ * @param {HTMLElement} iframe - The iframe DOM element
991
+ */
992
+ /**
993
+ * Callback for each iframe content
994
+ * @callback DOMIterator~forEachIframeEachCallback
995
+ * @param {HTMLElement} content - The iframe document
996
+ */
997
+ /**
998
+ * Callback if all iframes inside the context were handled
999
+ * @callback DOMIterator~forEachIframeEndCallback
1000
+ * @param {number} handled - The number of handled iframes (those who
1001
+ * wheren't filtered)
1002
+ */
1003
+ /**
1004
+ * Iterates over all iframes inside the specified context and calls the
1005
+ * callbacks when they're ready. Filters iframes based on the instance
1006
+ * exclusion selectors
1007
+ * @param {HTMLElement} ctx - The context DOM element
1008
+ * @param {DOMIterator~forEachIframeFilterCallback} filter - Filter callback
1009
+ * @param {DOMIterator~forEachIframeEachCallback} each - Each callback
1010
+ * @param {DOMIterator~forEachIframeEndCallback} [end] - End callback
1011
+ * @access protected
1012
+ */
1013
+ forEachIframe(e, t, n, r = () => {
1014
+ }) {
1015
+ let s = e.querySelectorAll("iframe"), i = s.length, o = 0;
1016
+ s = Array.prototype.slice.call(s);
1017
+ const l = () => {
1018
+ --i <= 0 && r(o);
1019
+ };
1020
+ i || l(), s.forEach((c) => {
1021
+ ie.matches(c, this.exclude) ? l() : this.onIframeReady(c, (f) => {
1022
+ t(c) && (o++, n(f)), l();
1023
+ }, l);
1024
+ });
1025
+ }
1026
+ /**
1027
+ * Creates a NodeIterator on the specified context
1028
+ * @see {@link https://developer.mozilla.org/en/docs/Web/API/NodeIterator}
1029
+ * @param {HTMLElement} ctx - The context DOM element
1030
+ * @param {DOMIterator~whatToShow} whatToShow
1031
+ * @param {DOMIterator~filterCb} filter
1032
+ * @return {NodeIterator}
1033
+ * @access protected
1034
+ */
1035
+ createIterator(e, t, n) {
1036
+ return document.createNodeIterator(e, t, n, !1);
1037
+ }
1038
+ /**
1039
+ * Creates an instance of DOMIterator in an iframe
1040
+ * @param {HTMLDocument} contents - Iframe document
1041
+ * @return {DOMIterator}
1042
+ * @access protected
1043
+ */
1044
+ createInstanceOnIframe(e) {
1045
+ return new ie(e.querySelector("html"), this.iframes);
1046
+ }
1047
+ /**
1048
+ * Checks if an iframe occurs between two nodes, more specifically if an
1049
+ * iframe occurs before the specified node and after the specified prevNode
1050
+ * @param {HTMLElement} node - The node that should occur after the iframe
1051
+ * @param {HTMLElement} prevNode - The node that should occur before the
1052
+ * iframe
1053
+ * @param {HTMLElement} ifr - The iframe to check against
1054
+ * @return {boolean}
1055
+ * @access protected
1056
+ */
1057
+ compareNodeIframe(e, t, n) {
1058
+ const r = e.compareDocumentPosition(n), s = Node.DOCUMENT_POSITION_PRECEDING;
1059
+ if (r & s)
1060
+ if (t !== null) {
1061
+ const i = t.compareDocumentPosition(n), o = Node.DOCUMENT_POSITION_FOLLOWING;
1062
+ if (i & o)
1063
+ return !0;
1064
+ } else
1065
+ return !0;
1066
+ return !1;
1067
+ }
1068
+ /**
1069
+ * @typedef {DOMIterator~getIteratorNodeReturn}
1070
+ * @type {object.<string>}
1071
+ * @property {HTMLElement} prevNode - The previous node or null if there is
1072
+ * no
1073
+ * @property {HTMLElement} node - The current node
1074
+ */
1075
+ /**
1076
+ * Returns the previous and current node of the specified iterator
1077
+ * @param {NodeIterator} itr - The iterator
1078
+ * @return {DOMIterator~getIteratorNodeReturn}
1079
+ * @access protected
1080
+ */
1081
+ getIteratorNode(e) {
1082
+ const t = e.previousNode();
1083
+ let n;
1084
+ return t === null ? n = e.nextNode() : n = e.nextNode() && e.nextNode(), {
1085
+ prevNode: t,
1086
+ node: n
1087
+ };
1088
+ }
1089
+ /**
1090
+ * An array containing objects. The object key "val" contains an iframe
1091
+ * DOM element. The object key "handled" contains a boolean indicating if
1092
+ * the iframe was handled already.
1093
+ * It wouldn't be enough to save all open or all already handled iframes.
1094
+ * The information of open iframes is necessary because they may occur after
1095
+ * all other text nodes (and compareNodeIframe would never be true). The
1096
+ * information of already handled iframes is necessary as otherwise they may
1097
+ * be handled multiple times
1098
+ * @typedef DOMIterator~checkIframeFilterIfr
1099
+ * @type {object[]}
1100
+ */
1101
+ /**
1102
+ * Checks if an iframe wasn't handled already and if so, calls
1103
+ * {@link DOMIterator#compareNodeIframe} to check if it should be handled.
1104
+ * Information wheter an iframe was or wasn't handled is given within the
1105
+ * <code>ifr</code> dictionary
1106
+ * @param {HTMLElement} node - The node that should occur after the iframe
1107
+ * @param {HTMLElement} prevNode - The node that should occur before the
1108
+ * iframe
1109
+ * @param {HTMLElement} currIfr - The iframe to check
1110
+ * @param {DOMIterator~checkIframeFilterIfr} ifr - The iframe dictionary.
1111
+ * Will be manipulated (by reference)
1112
+ * @return {boolean} Returns true when it should be handled, otherwise false
1113
+ * @access protected
1114
+ */
1115
+ checkIframeFilter(e, t, n, r) {
1116
+ let s = !1, i = !1;
1117
+ return r.forEach((o, l) => {
1118
+ o.val === n && (s = l, i = o.handled);
1119
+ }), this.compareNodeIframe(e, t, n) ? (s === !1 && !i ? r.push({
1120
+ val: n,
1121
+ handled: !0
1122
+ }) : s !== !1 && !i && (r[s].handled = !0), !0) : (s === !1 && r.push({
1123
+ val: n,
1124
+ handled: !1
1125
+ }), !1);
1126
+ }
1127
+ /**
1128
+ * Creates an iterator on all open iframes in the specified array and calls
1129
+ * the end callback when finished
1130
+ * @param {DOMIterator~checkIframeFilterIfr} ifr
1131
+ * @param {DOMIterator~whatToShow} whatToShow
1132
+ * @param {DOMIterator~forEachNodeCallback} eCb - Each callback
1133
+ * @param {DOMIterator~filterCb} fCb
1134
+ * @access protected
1135
+ */
1136
+ handleOpenIframes(e, t, n, r) {
1137
+ e.forEach((s) => {
1138
+ s.handled || this.getIframeContents(s.val, (i) => {
1139
+ this.createInstanceOnIframe(i).forEachNode(
1140
+ t,
1141
+ n,
1142
+ r
1143
+ );
1144
+ });
1145
+ });
1146
+ }
1147
+ /**
1148
+ * Iterates through all nodes in the specified context and handles iframe
1149
+ * nodes at the correct position
1150
+ * @param {DOMIterator~whatToShow} whatToShow
1151
+ * @param {HTMLElement} ctx - The context
1152
+ * @param {DOMIterator~forEachNodeCallback} eachCb - Each callback
1153
+ * @param {DOMIterator~filterCb} filterCb - Filter callback
1154
+ * @param {DOMIterator~forEachNodeEndCallback} doneCb - End callback
1155
+ * @access protected
1156
+ */
1157
+ iterateThroughNodes(e, t, n, r, s) {
1158
+ const i = this.createIterator(t, e, r);
1159
+ let o = [], l = [], c, f, p = () => ({
1160
+ prevNode: f,
1161
+ node: c
1162
+ } = this.getIteratorNode(i), c);
1163
+ for (; p(); )
1164
+ this.iframes && this.forEachIframe(t, (v) => this.checkIframeFilter(c, f, v, o), (v) => {
1165
+ this.createInstanceOnIframe(v).forEachNode(
1166
+ e,
1167
+ (y) => l.push(y),
1168
+ r
1169
+ );
1170
+ }), l.push(c);
1171
+ l.forEach((v) => {
1172
+ n(v);
1173
+ }), this.iframes && this.handleOpenIframes(o, e, n, r), s();
1174
+ }
1175
+ /**
1176
+ * Callback for each node
1177
+ * @callback DOMIterator~forEachNodeCallback
1178
+ * @param {HTMLElement} node - The DOM text node element
1179
+ */
1180
+ /**
1181
+ * Callback if all contexts were handled
1182
+ * @callback DOMIterator~forEachNodeEndCallback
1183
+ */
1184
+ /**
1185
+ * Iterates over all contexts and initializes
1186
+ * {@link DOMIterator#iterateThroughNodes iterateThroughNodes} on them
1187
+ * @param {DOMIterator~whatToShow} whatToShow
1188
+ * @param {DOMIterator~forEachNodeCallback} each - Each callback
1189
+ * @param {DOMIterator~filterCb} filter - Filter callback
1190
+ * @param {DOMIterator~forEachNodeEndCallback} done - End callback
1191
+ * @access public
1192
+ */
1193
+ forEachNode(e, t, n, r = () => {
1194
+ }) {
1195
+ const s = this.getContexts();
1196
+ let i = s.length;
1197
+ i || r(), s.forEach((o) => {
1198
+ const l = () => {
1199
+ this.iterateThroughNodes(e, o, t, n, () => {
1200
+ --i <= 0 && r();
1201
+ });
1202
+ };
1203
+ this.iframes ? this.waitForIframes(o, l) : l();
1204
+ });
1205
+ }
1206
+ /**
1207
+ * Callback to filter nodes. Can return e.g. NodeFilter.FILTER_ACCEPT or
1208
+ * NodeFilter.FILTER_REJECT
1209
+ * @see {@link http://tinyurl.com/zdczmm2}
1210
+ * @callback DOMIterator~filterCb
1211
+ * @param {HTMLElement} node - The node to filter
1212
+ */
1213
+ /**
1214
+ * @typedef DOMIterator~whatToShow
1215
+ * @see {@link http://tinyurl.com/zfqqkx2}
1216
+ * @type {number}
1217
+ */
1218
+ }
1219
+ let Fn = class {
1220
+ // eslint-disable-line no-unused-vars
1221
+ /**
1222
+ * @param {HTMLElement|HTMLElement[]|NodeList|string} ctx - The context DOM
1223
+ * element, an array of DOM elements, a NodeList or a selector
1224
+ */
1225
+ constructor(e) {
1226
+ this.ctx = e, this.ie = !1;
1227
+ const t = window.navigator.userAgent;
1228
+ (t.indexOf("MSIE") > -1 || t.indexOf("Trident") > -1) && (this.ie = !0);
1229
+ }
1230
+ /**
1231
+ * Options defined by the user. They will be initialized from one of the
1232
+ * public methods. See {@link Mark#mark}, {@link Mark#markRegExp},
1233
+ * {@link Mark#markRanges} and {@link Mark#unmark} for option properties.
1234
+ * @type {object}
1235
+ * @param {object} [val] - An object that will be merged with defaults
1236
+ * @access protected
1237
+ */
1238
+ set opt(e) {
1239
+ this._opt = Object.assign({}, {
1240
+ element: "",
1241
+ className: "",
1242
+ exclude: [],
1243
+ iframes: !1,
1244
+ iframesTimeout: 5e3,
1245
+ separateWordSearch: !0,
1246
+ diacritics: !0,
1247
+ synonyms: {},
1248
+ accuracy: "partially",
1249
+ acrossElements: !1,
1250
+ caseSensitive: !1,
1251
+ ignoreJoiners: !1,
1252
+ ignoreGroups: 0,
1253
+ ignorePunctuation: [],
1254
+ wildcards: "disabled",
1255
+ each: () => {
1256
+ },
1257
+ noMatch: () => {
1258
+ },
1259
+ filter: () => !0,
1260
+ done: () => {
1261
+ },
1262
+ debug: !1,
1263
+ log: window.console
1264
+ }, e);
1265
+ }
1266
+ get opt() {
1267
+ return this._opt;
1268
+ }
1269
+ /**
1270
+ * An instance of DOMIterator
1271
+ * @type {DOMIterator}
1272
+ * @access protected
1273
+ */
1274
+ get iterator() {
1275
+ return new ie(
1276
+ this.ctx,
1277
+ this.opt.iframes,
1278
+ this.opt.exclude,
1279
+ this.opt.iframesTimeout
1280
+ );
1281
+ }
1282
+ /**
1283
+ * Logs a message if log is enabled
1284
+ * @param {string} msg - The message to log
1285
+ * @param {string} [level="debug"] - The log level, e.g. <code>warn</code>
1286
+ * <code>error</code>, <code>debug</code>
1287
+ * @access protected
1288
+ */
1289
+ log(e, t = "debug") {
1290
+ const n = this.opt.log;
1291
+ this.opt.debug && typeof n == "object" && typeof n[t] == "function" && n[t](`mark.js: ${e}`);
1292
+ }
1293
+ /**
1294
+ * Escapes a string for usage within a regular expression
1295
+ * @param {string} str - The string to escape
1296
+ * @return {string}
1297
+ * @access protected
1298
+ */
1299
+ escapeStr(e) {
1300
+ return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
1301
+ }
1302
+ /**
1303
+ * Creates a regular expression string to match the specified search
1304
+ * term including synonyms, diacritics and accuracy if defined
1305
+ * @param {string} str - The search term to be used
1306
+ * @return {string}
1307
+ * @access protected
1308
+ */
1309
+ createRegExp(e) {
1310
+ return this.opt.wildcards !== "disabled" && (e = this.setupWildcardsRegExp(e)), e = this.escapeStr(e), Object.keys(this.opt.synonyms).length && (e = this.createSynonymsRegExp(e)), (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) && (e = this.setupIgnoreJoinersRegExp(e)), this.opt.diacritics && (e = this.createDiacriticsRegExp(e)), e = this.createMergedBlanksRegExp(e), (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) && (e = this.createJoinersRegExp(e)), this.opt.wildcards !== "disabled" && (e = this.createWildcardsRegExp(e)), e = this.createAccuracyRegExp(e), e;
1311
+ }
1312
+ /**
1313
+ * Creates a regular expression string to match the defined synonyms
1314
+ * @param {string} str - The search term to be used
1315
+ * @return {string}
1316
+ * @access protected
1317
+ */
1318
+ createSynonymsRegExp(e) {
1319
+ const t = this.opt.synonyms, n = this.opt.caseSensitive ? "" : "i", r = this.opt.ignoreJoiners || this.opt.ignorePunctuation.length ? "\0" : "";
1320
+ for (let s in t)
1321
+ if (t.hasOwnProperty(s)) {
1322
+ const i = t[s], o = this.opt.wildcards !== "disabled" ? this.setupWildcardsRegExp(s) : this.escapeStr(s), l = this.opt.wildcards !== "disabled" ? this.setupWildcardsRegExp(i) : this.escapeStr(i);
1323
+ o !== "" && l !== "" && (e = e.replace(
1324
+ new RegExp(
1325
+ `(${this.escapeStr(o)}|${this.escapeStr(l)})`,
1326
+ `gm${n}`
1327
+ ),
1328
+ r + `(${this.processSynomyms(o)}|${this.processSynomyms(l)})` + r
1329
+ ));
1330
+ }
1331
+ return e;
1332
+ }
1333
+ /**
1334
+ * Setup synonyms to work with ignoreJoiners and or ignorePunctuation
1335
+ * @param {string} str - synonym key or value to process
1336
+ * @return {string} - processed synonym string
1337
+ */
1338
+ processSynomyms(e) {
1339
+ return (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) && (e = this.setupIgnoreJoinersRegExp(e)), e;
1340
+ }
1341
+ /**
1342
+ * Sets up the regular expression string to allow later insertion of
1343
+ * wildcard regular expression matches
1344
+ * @param {string} str - The search term to be used
1345
+ * @return {string}
1346
+ * @access protected
1347
+ */
1348
+ setupWildcardsRegExp(e) {
1349
+ return e = e.replace(/(?:\\)*\?/g, (t) => t.charAt(0) === "\\" ? "?" : ""), e.replace(/(?:\\)*\*/g, (t) => t.charAt(0) === "\\" ? "*" : "");
1350
+ }
1351
+ /**
1352
+ * Sets up the regular expression string to allow later insertion of
1353
+ * wildcard regular expression matches
1354
+ * @param {string} str - The search term to be used
1355
+ * @return {string}
1356
+ * @access protected
1357
+ */
1358
+ createWildcardsRegExp(e) {
1359
+ let t = this.opt.wildcards === "withSpaces";
1360
+ return e.replace(/\u0001/g, t ? "[\\S\\s]?" : "\\S?").replace(/\u0002/g, t ? "[\\S\\s]*?" : "\\S*");
1361
+ }
1362
+ /**
1363
+ * Sets up the regular expression string to allow later insertion of
1364
+ * designated characters (soft hyphens & zero width characters)
1365
+ * @param {string} str - The search term to be used
1366
+ * @return {string}
1367
+ * @access protected
1368
+ */
1369
+ setupIgnoreJoinersRegExp(e) {
1370
+ return e.replace(/[^(|)\\]/g, (t, n, r) => {
1371
+ let s = r.charAt(n + 1);
1372
+ return /[(|)\\]/.test(s) || s === "" ? t : t + "\0";
1373
+ });
1374
+ }
1375
+ /**
1376
+ * Creates a regular expression string to allow ignoring of designated
1377
+ * characters (soft hyphens, zero width characters & punctuation) based on
1378
+ * the specified option values of <code>ignorePunctuation</code> and
1379
+ * <code>ignoreJoiners</code>
1380
+ * @param {string} str - The search term to be used
1381
+ * @return {string}
1382
+ * @access protected
1383
+ */
1384
+ createJoinersRegExp(e) {
1385
+ let t = [];
1386
+ const n = this.opt.ignorePunctuation;
1387
+ return Array.isArray(n) && n.length && t.push(this.escapeStr(n.join(""))), this.opt.ignoreJoiners && t.push("\\u00ad\\u200b\\u200c\\u200d"), t.length ? e.split(/\u0000+/).join(`[${t.join("")}]*`) : e;
1388
+ }
1389
+ /**
1390
+ * Creates a regular expression string to match diacritics
1391
+ * @param {string} str - The search term to be used
1392
+ * @return {string}
1393
+ * @access protected
1394
+ */
1395
+ createDiacriticsRegExp(e) {
1396
+ const t = this.opt.caseSensitive ? "" : "i", n = this.opt.caseSensitive ? [
1397
+ "aàáảãạăằắẳẵặâầấẩẫậäåāą",
1398
+ "AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ",
1399
+ "cçćč",
1400
+ "CÇĆČ",
1401
+ "dđď",
1402
+ "DĐĎ",
1403
+ "eèéẻẽẹêềếểễệëěēę",
1404
+ "EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ",
1405
+ "iìíỉĩịîïī",
1406
+ "IÌÍỈĨỊÎÏĪ",
1407
+ "lł",
1408
+ "LŁ",
1409
+ "nñňń",
1410
+ "NÑŇŃ",
1411
+ "oòóỏõọôồốổỗộơởỡớờợöøō",
1412
+ "OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ",
1413
+ "rř",
1414
+ "RŘ",
1415
+ "sšśșş",
1416
+ "SŠŚȘŞ",
1417
+ "tťțţ",
1418
+ "TŤȚŢ",
1419
+ "uùúủũụưừứửữựûüůū",
1420
+ "UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ",
1421
+ "yýỳỷỹỵÿ",
1422
+ "YÝỲỶỸỴŸ",
1423
+ "zžżź",
1424
+ "ZŽŻŹ"
1425
+ ] : [
1426
+ "aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ",
1427
+ "cçćčCÇĆČ",
1428
+ "dđďDĐĎ",
1429
+ "eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ",
1430
+ "iìíỉĩịîïīIÌÍỈĨỊÎÏĪ",
1431
+ "lłLŁ",
1432
+ "nñňńNÑŇŃ",
1433
+ "oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ",
1434
+ "rřRŘ",
1435
+ "sšśșşSŠŚȘŞ",
1436
+ "tťțţTŤȚŢ",
1437
+ "uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ",
1438
+ "yýỳỷỹỵÿYÝỲỶỸỴŸ",
1439
+ "zžżźZŽŻŹ"
1440
+ ];
1441
+ let r = [];
1442
+ return e.split("").forEach((s) => {
1443
+ n.every((i) => {
1444
+ if (i.indexOf(s) !== -1) {
1445
+ if (r.indexOf(i) > -1)
1446
+ return !1;
1447
+ e = e.replace(
1448
+ new RegExp(`[${i}]`, `gm${t}`),
1449
+ `[${i}]`
1450
+ ), r.push(i);
1451
+ }
1452
+ return !0;
1453
+ });
1454
+ }), e;
1455
+ }
1456
+ /**
1457
+ * Creates a regular expression string that merges whitespace characters
1458
+ * including subsequent ones into a single pattern, one or multiple
1459
+ * whitespaces
1460
+ * @param {string} str - The search term to be used
1461
+ * @return {string}
1462
+ * @access protected
1463
+ */
1464
+ createMergedBlanksRegExp(e) {
1465
+ return e.replace(/[\s]+/gmi, "[\\s]+");
1466
+ }
1467
+ /**
1468
+ * Creates a regular expression string to match the specified string with
1469
+ * the defined accuracy. As in the regular expression of "exactly" can be
1470
+ * a group containing a blank at the beginning, all regular expressions will
1471
+ * be created with two groups. The first group can be ignored (may contain
1472
+ * the said blank), the second contains the actual match
1473
+ * @param {string} str - The searm term to be used
1474
+ * @return {str}
1475
+ * @access protected
1476
+ */
1477
+ createAccuracyRegExp(e) {
1478
+ const t = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿";
1479
+ let n = this.opt.accuracy, r = typeof n == "string" ? n : n.value, s = typeof n == "string" ? [] : n.limiters, i = "";
1480
+ switch (s.forEach((o) => {
1481
+ i += `|${this.escapeStr(o)}`;
1482
+ }), r) {
1483
+ case "partially":
1484
+ default:
1485
+ return `()(${e})`;
1486
+ case "complementary":
1487
+ return i = "\\s" + (i || this.escapeStr(t)), `()([^${i}]*${e}[^${i}]*)`;
1488
+ case "exactly":
1489
+ return `(^|\\s${i})(${e})(?=$|\\s${i})`;
1490
+ }
1491
+ }
1492
+ /**
1493
+ * @typedef Mark~separatedKeywords
1494
+ * @type {object.<string>}
1495
+ * @property {array.<string>} keywords - The list of keywords
1496
+ * @property {number} length - The length
1497
+ */
1498
+ /**
1499
+ * Returns a list of keywords dependent on whether separate word search
1500
+ * was defined. Also it filters empty keywords
1501
+ * @param {array} sv - The array of keywords
1502
+ * @return {Mark~separatedKeywords}
1503
+ * @access protected
1504
+ */
1505
+ getSeparatedKeywords(e) {
1506
+ let t = [];
1507
+ return e.forEach((n) => {
1508
+ this.opt.separateWordSearch ? n.split(" ").forEach((r) => {
1509
+ r.trim() && t.indexOf(r) === -1 && t.push(r);
1510
+ }) : n.trim() && t.indexOf(n) === -1 && t.push(n);
1511
+ }), {
1512
+ // sort because of https://git.io/v6USg
1513
+ keywords: t.sort((n, r) => r.length - n.length),
1514
+ length: t.length
1515
+ };
1516
+ }
1517
+ /**
1518
+ * Check if a value is a number
1519
+ * @param {number|string} value - the value to check;
1520
+ * numeric strings allowed
1521
+ * @return {boolean}
1522
+ * @access protected
1523
+ */
1524
+ isNumeric(e) {
1525
+ return Number(parseFloat(e)) == e;
1526
+ }
1527
+ /**
1528
+ * @typedef Mark~rangeObject
1529
+ * @type {object}
1530
+ * @property {number} start - The start position within the composite value
1531
+ * @property {number} length - The length of the string to mark within the
1532
+ * composite value.
1533
+ */
1534
+ /**
1535
+ * @typedef Mark~setOfRanges
1536
+ * @type {object[]}
1537
+ * @property {Mark~rangeObject}
1538
+ */
1539
+ /**
1540
+ * Returns a processed list of integer offset indexes that do not overlap
1541
+ * each other, and remove any string values or additional elements
1542
+ * @param {Mark~setOfRanges} array - unprocessed raw array
1543
+ * @return {Mark~setOfRanges} - processed array with any invalid entries
1544
+ * removed
1545
+ * @throws Will throw an error if an array of objects is not passed
1546
+ * @access protected
1547
+ */
1548
+ checkRanges(e) {
1549
+ if (!Array.isArray(e) || Object.prototype.toString.call(e[0]) !== "[object Object]")
1550
+ return this.log("markRanges() will only accept an array of objects"), this.opt.noMatch(e), [];
1551
+ const t = [];
1552
+ let n = 0;
1553
+ return e.sort((r, s) => r.start - s.start).forEach((r) => {
1554
+ let { start: s, end: i, valid: o } = this.callNoMatchOnInvalidRanges(r, n);
1555
+ o && (r.start = s, r.length = i - s, t.push(r), n = i);
1556
+ }), t;
1557
+ }
1558
+ /**
1559
+ * @typedef Mark~validObject
1560
+ * @type {object}
1561
+ * @property {number} start - The start position within the composite value
1562
+ * @property {number} end - The calculated end position within the composite
1563
+ * value.
1564
+ * @property {boolean} valid - boolean value indicating that the start and
1565
+ * calculated end range is valid
1566
+ */
1567
+ /**
1568
+ * Initial validation of ranges for markRanges. Preliminary checks are done
1569
+ * to ensure the start and length values exist and are not zero or non-
1570
+ * numeric
1571
+ * @param {Mark~rangeObject} range - the current range object
1572
+ * @param {number} last - last index of range
1573
+ * @return {Mark~validObject}
1574
+ * @access protected
1575
+ */
1576
+ callNoMatchOnInvalidRanges(e, t) {
1577
+ let n, r, s = !1;
1578
+ return e && typeof e.start < "u" ? (n = parseInt(e.start, 10), r = n + parseInt(e.length, 10), this.isNumeric(e.start) && this.isNumeric(e.length) && r - t > 0 && r - n > 0 ? s = !0 : (this.log(
1579
+ `Ignoring invalid or overlapping range: ${JSON.stringify(e)}`
1580
+ ), this.opt.noMatch(e))) : (this.log(`Ignoring invalid range: ${JSON.stringify(e)}`), this.opt.noMatch(e)), {
1581
+ start: n,
1582
+ end: r,
1583
+ valid: s
1584
+ };
1585
+ }
1586
+ /**
1587
+ * Check valid range for markRanges. Check ranges with access to the context
1588
+ * string. Range values are double checked, lengths that extend the mark
1589
+ * beyond the string length are limitied and ranges containing only
1590
+ * whitespace are ignored
1591
+ * @param {Mark~rangeObject} range - the current range object
1592
+ * @param {number} originalLength - original length of the context string
1593
+ * @param {string} string - current content string
1594
+ * @return {Mark~validObject}
1595
+ * @access protected
1596
+ */
1597
+ checkWhitespaceRanges(e, t, n) {
1598
+ let r, s = !0, i = n.length, o = t - i, l = parseInt(e.start, 10) - o;
1599
+ return l = l > i ? i : l, r = l + parseInt(e.length, 10), r > i && (r = i, this.log(`End range automatically set to the max value of ${i}`)), l < 0 || r - l < 0 || l > i || r > i ? (s = !1, this.log(`Invalid range: ${JSON.stringify(e)}`), this.opt.noMatch(e)) : n.substring(l, r).replace(/\s+/g, "") === "" && (s = !1, this.log("Skipping whitespace only range: " + JSON.stringify(e)), this.opt.noMatch(e)), {
1600
+ start: l,
1601
+ end: r,
1602
+ valid: s
1603
+ };
1604
+ }
1605
+ /**
1606
+ * @typedef Mark~getTextNodesDict
1607
+ * @type {object.<string>}
1608
+ * @property {string} value - The composite value of all text nodes
1609
+ * @property {object[]} nodes - An array of objects
1610
+ * @property {number} nodes.start - The start position within the composite
1611
+ * value
1612
+ * @property {number} nodes.end - The end position within the composite
1613
+ * value
1614
+ * @property {HTMLElement} nodes.node - The DOM text node element
1615
+ */
1616
+ /**
1617
+ * Callback
1618
+ * @callback Mark~getTextNodesCallback
1619
+ * @param {Mark~getTextNodesDict}
1620
+ */
1621
+ /**
1622
+ * Calls the callback with an object containing all text nodes (including
1623
+ * iframe text nodes) with start and end positions and the composite value
1624
+ * of them (string)
1625
+ * @param {Mark~getTextNodesCallback} cb - Callback
1626
+ * @access protected
1627
+ */
1628
+ getTextNodes(e) {
1629
+ let t = "", n = [];
1630
+ this.iterator.forEachNode(NodeFilter.SHOW_TEXT, (r) => {
1631
+ n.push({
1632
+ start: t.length,
1633
+ end: (t += r.textContent).length,
1634
+ node: r
1635
+ });
1636
+ }, (r) => this.matchesExclude(r.parentNode) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT, () => {
1637
+ e({
1638
+ value: t,
1639
+ nodes: n
1640
+ });
1641
+ });
1642
+ }
1643
+ /**
1644
+ * Checks if an element matches any of the specified exclude selectors. Also
1645
+ * it checks for elements in which no marks should be performed (e.g.
1646
+ * script and style tags) and optionally already marked elements
1647
+ * @param {HTMLElement} el - The element to check
1648
+ * @return {boolean}
1649
+ * @access protected
1650
+ */
1651
+ matchesExclude(e) {
1652
+ return ie.matches(e, this.opt.exclude.concat([
1653
+ // ignores the elements itself, not their childrens (selector *)
1654
+ "script",
1655
+ "style",
1656
+ "title",
1657
+ "head",
1658
+ "html"
1659
+ ]));
1660
+ }
1661
+ /**
1662
+ * Wraps the instance element and class around matches that fit the start
1663
+ * and end positions within the node
1664
+ * @param {HTMLElement} node - The DOM text node
1665
+ * @param {number} start - The position where to start wrapping
1666
+ * @param {number} end - The position where to end wrapping
1667
+ * @return {HTMLElement} Returns the splitted text node that will appear
1668
+ * after the wrapped text node
1669
+ * @access protected
1670
+ */
1671
+ wrapRangeInTextNode(e, t, n) {
1672
+ const r = this.opt.element ? this.opt.element : "mark", s = e.splitText(t), i = s.splitText(n - t);
1673
+ let o = document.createElement(r);
1674
+ return o.setAttribute("data-markjs", "true"), this.opt.className && o.setAttribute("class", this.opt.className), o.textContent = s.textContent, s.parentNode.replaceChild(o, s), i;
1675
+ }
1676
+ /**
1677
+ * @typedef Mark~wrapRangeInMappedTextNodeDict
1678
+ * @type {object.<string>}
1679
+ * @property {string} value - The composite value of all text nodes
1680
+ * @property {object[]} nodes - An array of objects
1681
+ * @property {number} nodes.start - The start position within the composite
1682
+ * value
1683
+ * @property {number} nodes.end - The end position within the composite
1684
+ * value
1685
+ * @property {HTMLElement} nodes.node - The DOM text node element
1686
+ */
1687
+ /**
1688
+ * Each callback
1689
+ * @callback Mark~wrapMatchesEachCallback
1690
+ * @param {HTMLElement} node - The wrapped DOM element
1691
+ * @param {number} lastIndex - The last matching position within the
1692
+ * composite value of text nodes
1693
+ */
1694
+ /**
1695
+ * Filter callback
1696
+ * @callback Mark~wrapMatchesFilterCallback
1697
+ * @param {HTMLElement} node - The matching text node DOM element
1698
+ */
1699
+ /**
1700
+ * Determines matches by start and end positions using the text node
1701
+ * dictionary even across text nodes and calls
1702
+ * {@link Mark#wrapRangeInTextNode} to wrap them
1703
+ * @param {Mark~wrapRangeInMappedTextNodeDict} dict - The dictionary
1704
+ * @param {number} start - The start position of the match
1705
+ * @param {number} end - The end position of the match
1706
+ * @param {Mark~wrapMatchesFilterCallback} filterCb - Filter callback
1707
+ * @param {Mark~wrapMatchesEachCallback} eachCb - Each callback
1708
+ * @access protected
1709
+ */
1710
+ wrapRangeInMappedTextNode(e, t, n, r, s) {
1711
+ e.nodes.every((i, o) => {
1712
+ const l = e.nodes[o + 1];
1713
+ if (typeof l > "u" || l.start > t) {
1714
+ if (!r(i.node))
1715
+ return !1;
1716
+ const c = t - i.start, f = (n > i.end ? i.end : n) - i.start, p = e.value.substr(0, i.start), v = e.value.substr(f + i.start);
1717
+ if (i.node = this.wrapRangeInTextNode(i.node, c, f), e.value = p + v, e.nodes.forEach((y, S) => {
1718
+ S >= o && (e.nodes[S].start > 0 && S !== o && (e.nodes[S].start -= f), e.nodes[S].end -= f);
1719
+ }), n -= f, s(i.node.previousSibling, i.start), n > i.end)
1720
+ t = i.end;
1721
+ else
1722
+ return !1;
1723
+ }
1724
+ return !0;
1725
+ });
1726
+ }
1727
+ /**
1728
+ * Filter callback before each wrapping
1729
+ * @callback Mark~wrapMatchesFilterCallback
1730
+ * @param {string} match - The matching string
1731
+ * @param {HTMLElement} node - The text node where the match occurs
1732
+ */
1733
+ /**
1734
+ * Callback for each wrapped element
1735
+ * @callback Mark~wrapMatchesEachCallback
1736
+ * @param {HTMLElement} element - The marked DOM element
1737
+ */
1738
+ /**
1739
+ * Callback on end
1740
+ * @callback Mark~wrapMatchesEndCallback
1741
+ */
1742
+ /**
1743
+ * Wraps the instance element and class around matches within single HTML
1744
+ * elements in all contexts
1745
+ * @param {RegExp} regex - The regular expression to be searched for
1746
+ * @param {number} ignoreGroups - A number indicating the amount of RegExp
1747
+ * matching groups to ignore
1748
+ * @param {Mark~wrapMatchesFilterCallback} filterCb
1749
+ * @param {Mark~wrapMatchesEachCallback} eachCb
1750
+ * @param {Mark~wrapMatchesEndCallback} endCb
1751
+ * @access protected
1752
+ */
1753
+ wrapMatches(e, t, n, r, s) {
1754
+ const i = t === 0 ? 0 : t + 1;
1755
+ this.getTextNodes((o) => {
1756
+ o.nodes.forEach((l) => {
1757
+ l = l.node;
1758
+ let c;
1759
+ for (; (c = e.exec(l.textContent)) !== null && c[i] !== ""; ) {
1760
+ if (!n(c[i], l))
1761
+ continue;
1762
+ let f = c.index;
1763
+ if (i !== 0)
1764
+ for (let p = 1; p < i; p++)
1765
+ f += c[p].length;
1766
+ l = this.wrapRangeInTextNode(
1767
+ l,
1768
+ f,
1769
+ f + c[i].length
1770
+ ), r(l.previousSibling), e.lastIndex = 0;
1771
+ }
1772
+ }), s();
1773
+ });
1774
+ }
1775
+ /**
1776
+ * Callback for each wrapped element
1777
+ * @callback Mark~wrapMatchesAcrossElementsEachCallback
1778
+ * @param {HTMLElement} element - The marked DOM element
1779
+ */
1780
+ /**
1781
+ * Filter callback before each wrapping
1782
+ * @callback Mark~wrapMatchesAcrossElementsFilterCallback
1783
+ * @param {string} match - The matching string
1784
+ * @param {HTMLElement} node - The text node where the match occurs
1785
+ */
1786
+ /**
1787
+ * Callback on end
1788
+ * @callback Mark~wrapMatchesAcrossElementsEndCallback
1789
+ */
1790
+ /**
1791
+ * Wraps the instance element and class around matches across all HTML
1792
+ * elements in all contexts
1793
+ * @param {RegExp} regex - The regular expression to be searched for
1794
+ * @param {number} ignoreGroups - A number indicating the amount of RegExp
1795
+ * matching groups to ignore
1796
+ * @param {Mark~wrapMatchesAcrossElementsFilterCallback} filterCb
1797
+ * @param {Mark~wrapMatchesAcrossElementsEachCallback} eachCb
1798
+ * @param {Mark~wrapMatchesAcrossElementsEndCallback} endCb
1799
+ * @access protected
1800
+ */
1801
+ wrapMatchesAcrossElements(e, t, n, r, s) {
1802
+ const i = t === 0 ? 0 : t + 1;
1803
+ this.getTextNodes((o) => {
1804
+ let l;
1805
+ for (; (l = e.exec(o.value)) !== null && l[i] !== ""; ) {
1806
+ let c = l.index;
1807
+ if (i !== 0)
1808
+ for (let p = 1; p < i; p++)
1809
+ c += l[p].length;
1810
+ const f = c + l[i].length;
1811
+ this.wrapRangeInMappedTextNode(o, c, f, (p) => n(l[i], p), (p, v) => {
1812
+ e.lastIndex = v, r(p);
1813
+ });
1814
+ }
1815
+ s();
1816
+ });
1817
+ }
1818
+ /**
1819
+ * Callback for each wrapped element
1820
+ * @callback Mark~wrapRangeFromIndexEachCallback
1821
+ * @param {HTMLElement} element - The marked DOM element
1822
+ * @param {Mark~rangeObject} range - the current range object; provided
1823
+ * start and length values will be numeric integers modified from the
1824
+ * provided original ranges.
1825
+ */
1826
+ /**
1827
+ * Filter callback before each wrapping
1828
+ * @callback Mark~wrapRangeFromIndexFilterCallback
1829
+ * @param {HTMLElement} node - The text node which includes the range
1830
+ * @param {Mark~rangeObject} range - the current range object
1831
+ * @param {string} match - string extracted from the matching range
1832
+ * @param {number} counter - A counter indicating the number of all marks
1833
+ */
1834
+ /**
1835
+ * Callback on end
1836
+ * @callback Mark~wrapRangeFromIndexEndCallback
1837
+ */
1838
+ /**
1839
+ * Wraps the indicated ranges across all HTML elements in all contexts
1840
+ * @param {Mark~setOfRanges} ranges
1841
+ * @param {Mark~wrapRangeFromIndexFilterCallback} filterCb
1842
+ * @param {Mark~wrapRangeFromIndexEachCallback} eachCb
1843
+ * @param {Mark~wrapRangeFromIndexEndCallback} endCb
1844
+ * @access protected
1845
+ */
1846
+ wrapRangeFromIndex(e, t, n, r) {
1847
+ this.getTextNodes((s) => {
1848
+ const i = s.value.length;
1849
+ e.forEach((o, l) => {
1850
+ let { start: c, end: f, valid: p } = this.checkWhitespaceRanges(
1851
+ o,
1852
+ i,
1853
+ s.value
1854
+ );
1855
+ p && this.wrapRangeInMappedTextNode(s, c, f, (v) => t(
1856
+ v,
1857
+ o,
1858
+ s.value.substring(c, f),
1859
+ l
1860
+ ), (v) => {
1861
+ n(v, o);
1862
+ });
1863
+ }), r();
1864
+ });
1865
+ }
1866
+ /**
1867
+ * Unwraps the specified DOM node with its content (text nodes or HTML)
1868
+ * without destroying possibly present events (using innerHTML) and
1869
+ * normalizes the parent at the end (merge splitted text nodes)
1870
+ * @param {HTMLElement} node - The DOM node to unwrap
1871
+ * @access protected
1872
+ */
1873
+ unwrapMatches(e) {
1874
+ const t = e.parentNode;
1875
+ let n = document.createDocumentFragment();
1876
+ for (; e.firstChild; )
1877
+ n.appendChild(e.removeChild(e.firstChild));
1878
+ t.replaceChild(n, e), this.ie ? this.normalizeTextNode(t) : t.normalize();
1879
+ }
1880
+ /**
1881
+ * Normalizes text nodes. It's a workaround for the native normalize method
1882
+ * that has a bug in IE (see attached link). Should only be used in IE
1883
+ * browsers as it's slower than the native method.
1884
+ * @see {@link http://tinyurl.com/z5asa8c}
1885
+ * @param {HTMLElement} node - The DOM node to normalize
1886
+ * @access protected
1887
+ */
1888
+ normalizeTextNode(e) {
1889
+ if (e) {
1890
+ if (e.nodeType === 3)
1891
+ for (; e.nextSibling && e.nextSibling.nodeType === 3; )
1892
+ e.nodeValue += e.nextSibling.nodeValue, e.parentNode.removeChild(e.nextSibling);
1893
+ else
1894
+ this.normalizeTextNode(e.firstChild);
1895
+ this.normalizeTextNode(e.nextSibling);
1896
+ }
1897
+ }
1898
+ /**
1899
+ * Callback when finished
1900
+ * @callback Mark~commonDoneCallback
1901
+ * @param {number} totalMatches - The number of marked elements
1902
+ */
1903
+ /**
1904
+ * @typedef Mark~commonOptions
1905
+ * @type {object.<string>}
1906
+ * @property {string} [element="mark"] - HTML element tag name
1907
+ * @property {string} [className] - An optional class name
1908
+ * @property {string[]} [exclude] - An array with exclusion selectors.
1909
+ * Elements matching those selectors will be ignored
1910
+ * @property {boolean} [iframes=false] - Whether to search inside iframes
1911
+ * @property {Mark~commonDoneCallback} [done]
1912
+ * @property {boolean} [debug=false] - Wheter to log messages
1913
+ * @property {object} [log=window.console] - Where to log messages (only if
1914
+ * debug is true)
1915
+ */
1916
+ /**
1917
+ * Callback for each marked element
1918
+ * @callback Mark~markRegExpEachCallback
1919
+ * @param {HTMLElement} element - The marked DOM element
1920
+ */
1921
+ /**
1922
+ * Callback if there were no matches
1923
+ * @callback Mark~markRegExpNoMatchCallback
1924
+ * @param {RegExp} regexp - The regular expression
1925
+ */
1926
+ /**
1927
+ * Callback to filter matches
1928
+ * @callback Mark~markRegExpFilterCallback
1929
+ * @param {HTMLElement} textNode - The text node which includes the match
1930
+ * @param {string} match - The matching string for the RegExp
1931
+ * @param {number} counter - A counter indicating the number of all marks
1932
+ */
1933
+ /**
1934
+ * These options also include the common options from
1935
+ * {@link Mark~commonOptions}
1936
+ * @typedef Mark~markRegExpOptions
1937
+ * @type {object.<string>}
1938
+ * @property {Mark~markRegExpEachCallback} [each]
1939
+ * @property {Mark~markRegExpNoMatchCallback} [noMatch]
1940
+ * @property {Mark~markRegExpFilterCallback} [filter]
1941
+ */
1942
+ /**
1943
+ * Marks a custom regular expression
1944
+ * @param {RegExp} regexp - The regular expression
1945
+ * @param {Mark~markRegExpOptions} [opt] - Optional options object
1946
+ * @access public
1947
+ */
1948
+ markRegExp(e, t) {
1949
+ this.opt = t, this.log(`Searching with expression "${e}"`);
1950
+ let n = 0, r = "wrapMatches";
1951
+ const s = (i) => {
1952
+ n++, this.opt.each(i);
1953
+ };
1954
+ this.opt.acrossElements && (r = "wrapMatchesAcrossElements"), this[r](e, this.opt.ignoreGroups, (i, o) => this.opt.filter(o, i, n), s, () => {
1955
+ n === 0 && this.opt.noMatch(e), this.opt.done(n);
1956
+ });
1957
+ }
1958
+ /**
1959
+ * Callback for each marked element
1960
+ * @callback Mark~markEachCallback
1961
+ * @param {HTMLElement} element - The marked DOM element
1962
+ */
1963
+ /**
1964
+ * Callback if there were no matches
1965
+ * @callback Mark~markNoMatchCallback
1966
+ * @param {RegExp} term - The search term that was not found
1967
+ */
1968
+ /**
1969
+ * Callback to filter matches
1970
+ * @callback Mark~markFilterCallback
1971
+ * @param {HTMLElement} textNode - The text node which includes the match
1972
+ * @param {string} match - The matching term
1973
+ * @param {number} totalCounter - A counter indicating the number of all
1974
+ * marks
1975
+ * @param {number} termCounter - A counter indicating the number of marks
1976
+ * for the specific match
1977
+ */
1978
+ /**
1979
+ * @typedef Mark~markAccuracyObject
1980
+ * @type {object.<string>}
1981
+ * @property {string} value - A accuracy string value
1982
+ * @property {string[]} limiters - A custom array of limiters. For example
1983
+ * <code>["-", ","]</code>
1984
+ */
1985
+ /**
1986
+ * @typedef Mark~markAccuracySetting
1987
+ * @type {string}
1988
+ * @property {"partially"|"complementary"|"exactly"|Mark~markAccuracyObject}
1989
+ * [accuracy="partially"] - Either one of the following string values:
1990
+ * <ul>
1991
+ * <li><i>partially</i>: When searching for "lor" only "lor" inside
1992
+ * "lorem" will be marked</li>
1993
+ * <li><i>complementary</i>: When searching for "lor" the whole word
1994
+ * "lorem" will be marked</li>
1995
+ * <li><i>exactly</i>: When searching for "lor" only those exact words
1996
+ * will be marked. In this example nothing inside "lorem". This value
1997
+ * is equivalent to the previous option <i>wordBoundary</i></li>
1998
+ * </ul>
1999
+ * Or an object containing two properties:
2000
+ * <ul>
2001
+ * <li><i>value</i>: One of the above named string values</li>
2002
+ * <li><i>limiters</i>: A custom array of string limiters for accuracy
2003
+ * "exactly" or "complementary"</li>
2004
+ * </ul>
2005
+ */
2006
+ /**
2007
+ * @typedef Mark~markWildcardsSetting
2008
+ * @type {string}
2009
+ * @property {"disabled"|"enabled"|"withSpaces"}
2010
+ * [wildcards="disabled"] - Set to any of the following string values:
2011
+ * <ul>
2012
+ * <li><i>disabled</i>: Disable wildcard usage</li>
2013
+ * <li><i>enabled</i>: When searching for "lor?m", the "?" will match zero
2014
+ * or one non-space character (e.g. "lorm", "loram", "lor3m", etc). When
2015
+ * searching for "lor*m", the "*" will match zero or more non-space
2016
+ * characters (e.g. "lorm", "loram", "lor123m", etc).</li>
2017
+ * <li><i>withSpaces</i>: When searching for "lor?m", the "?" will
2018
+ * match zero or one space or non-space character (e.g. "lor m", "loram",
2019
+ * etc). When searching for "lor*m", the "*" will match zero or more space
2020
+ * or non-space characters (e.g. "lorm", "lore et dolor ipsum", "lor: m",
2021
+ * etc).</li>
2022
+ * </ul>
2023
+ */
2024
+ /**
2025
+ * @typedef Mark~markIgnorePunctuationSetting
2026
+ * @type {string[]}
2027
+ * @property {string} The strings in this setting will contain punctuation
2028
+ * marks that will be ignored:
2029
+ * <ul>
2030
+ * <li>These punctuation marks can be between any characters, e.g. setting
2031
+ * this option to <code>["'"]</code> would match "Worlds", "World's" and
2032
+ * "Wo'rlds"</li>
2033
+ * <li>One or more apostrophes between the letters would still produce a
2034
+ * match (e.g. "W'o''r'l'd's").</li>
2035
+ * <li>A typical setting for this option could be as follows:
2036
+ * <pre>ignorePunctuation: ":;.,-–—‒_(){}[]!'\"+=".split(""),</pre> This
2037
+ * setting includes common punctuation as well as a minus, en-dash,
2038
+ * em-dash and figure-dash
2039
+ * ({@link https://en.wikipedia.org/wiki/Dash#Figure_dash ref}), as well
2040
+ * as an underscore.</li>
2041
+ * </ul>
2042
+ */
2043
+ /**
2044
+ * These options also include the common options from
2045
+ * {@link Mark~commonOptions}
2046
+ * @typedef Mark~markOptions
2047
+ * @type {object.<string>}
2048
+ * @property {boolean} [separateWordSearch=true] - Whether to search for
2049
+ * each word separated by a blank instead of the complete term
2050
+ * @property {boolean} [diacritics=true] - If diacritic characters should be
2051
+ * matched. ({@link https://en.wikipedia.org/wiki/Diacritic Diacritics})
2052
+ * @property {object} [synonyms] - An object with synonyms. The key will be
2053
+ * a synonym for the value and the value for the key
2054
+ * @property {Mark~markAccuracySetting} [accuracy]
2055
+ * @property {Mark~markWildcardsSetting} [wildcards]
2056
+ * @property {boolean} [acrossElements=false] - Whether to find matches
2057
+ * across HTML elements. By default, only matches within single HTML
2058
+ * elements will be found
2059
+ * @property {boolean} [ignoreJoiners=false] - Whether to ignore word
2060
+ * joiners inside of key words. These include soft-hyphens, zero-width
2061
+ * space, zero-width non-joiners and zero-width joiners.
2062
+ * @property {Mark~markIgnorePunctuationSetting} [ignorePunctuation]
2063
+ * @property {Mark~markEachCallback} [each]
2064
+ * @property {Mark~markNoMatchCallback} [noMatch]
2065
+ * @property {Mark~markFilterCallback} [filter]
2066
+ */
2067
+ /**
2068
+ * Marks the specified search terms
2069
+ * @param {string|string[]} [sv] - Search value, either a search string or
2070
+ * an array containing multiple search strings
2071
+ * @param {Mark~markOptions} [opt] - Optional options object
2072
+ * @access public
2073
+ */
2074
+ mark(e, t) {
2075
+ this.opt = t;
2076
+ let n = 0, r = "wrapMatches";
2077
+ const {
2078
+ keywords: s,
2079
+ length: i
2080
+ } = this.getSeparatedKeywords(typeof e == "string" ? [e] : e), o = this.opt.caseSensitive ? "" : "i", l = (c) => {
2081
+ let f = new RegExp(this.createRegExp(c), `gm${o}`), p = 0;
2082
+ this.log(`Searching with expression "${f}"`), this[r](f, 1, (v, y) => this.opt.filter(y, c, n, p), (v) => {
2083
+ p++, n++, this.opt.each(v);
2084
+ }, () => {
2085
+ p === 0 && this.opt.noMatch(c), s[i - 1] === c ? this.opt.done(n) : l(s[s.indexOf(c) + 1]);
2086
+ });
2087
+ };
2088
+ this.opt.acrossElements && (r = "wrapMatchesAcrossElements"), i === 0 ? this.opt.done(n) : l(s[0]);
2089
+ }
2090
+ /**
2091
+ * Callback for each marked element
2092
+ * @callback Mark~markRangesEachCallback
2093
+ * @param {HTMLElement} element - The marked DOM element
2094
+ * @param {array} range - array of range start and end points
2095
+ */
2096
+ /**
2097
+ * Callback if a processed range is invalid, out-of-bounds, overlaps another
2098
+ * range, or only matches whitespace
2099
+ * @callback Mark~markRangesNoMatchCallback
2100
+ * @param {Mark~rangeObject} range - a range object
2101
+ */
2102
+ /**
2103
+ * Callback to filter matches
2104
+ * @callback Mark~markRangesFilterCallback
2105
+ * @param {HTMLElement} node - The text node which includes the range
2106
+ * @param {array} range - array of range start and end points
2107
+ * @param {string} match - string extracted from the matching range
2108
+ * @param {number} counter - A counter indicating the number of all marks
2109
+ */
2110
+ /**
2111
+ * These options also include the common options from
2112
+ * {@link Mark~commonOptions}
2113
+ * @typedef Mark~markRangesOptions
2114
+ * @type {object.<string>}
2115
+ * @property {Mark~markRangesEachCallback} [each]
2116
+ * @property {Mark~markRangesNoMatchCallback} [noMatch]
2117
+ * @property {Mark~markRangesFilterCallback} [filter]
2118
+ */
2119
+ /**
2120
+ * Marks an array of objects containing a start with an end or length of the
2121
+ * string to mark
2122
+ * @param {Mark~setOfRanges} rawRanges - The original (preprocessed)
2123
+ * array of objects
2124
+ * @param {Mark~markRangesOptions} [opt] - Optional options object
2125
+ * @access public
2126
+ */
2127
+ markRanges(e, t) {
2128
+ this.opt = t;
2129
+ let n = 0, r = this.checkRanges(e);
2130
+ r && r.length ? (this.log(
2131
+ "Starting to mark with the following ranges: " + JSON.stringify(r)
2132
+ ), this.wrapRangeFromIndex(
2133
+ r,
2134
+ (s, i, o, l) => this.opt.filter(s, i, o, l),
2135
+ (s, i) => {
2136
+ n++, this.opt.each(s, i);
2137
+ },
2138
+ () => {
2139
+ this.opt.done(n);
2140
+ }
2141
+ )) : this.opt.done(n);
2142
+ }
2143
+ /**
2144
+ * Removes all marked elements inside the context with their HTML and
2145
+ * normalizes the parent at the end
2146
+ * @param {Mark~commonOptions} [opt] - Optional options object
2147
+ * @access public
2148
+ */
2149
+ unmark(e) {
2150
+ this.opt = e;
2151
+ let t = this.opt.element ? this.opt.element : "*";
2152
+ t += "[data-markjs]", this.opt.className && (t += `.${this.opt.className}`), this.log(`Removal selector "${t}"`), this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT, (n) => {
2153
+ this.unwrapMatches(n);
2154
+ }, (n) => {
2155
+ const r = ie.matches(n, t), s = this.matchesExclude(n);
2156
+ return !r || s ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT;
2157
+ }, this.opt.done);
2158
+ }
2159
+ };
2160
+ function Rn(a) {
2161
+ const e = new Fn(a);
2162
+ return this.mark = (t, n) => (e.mark(t, n), this), this.markRegExp = (t, n) => (e.markRegExp(t, n), this), this.markRanges = (t, n) => (e.markRanges(t, n), this), this.unmark = (t) => (e.unmark(t), this), this;
2163
+ }
2164
+ const An = "ENTRIES", gt = "KEYS", bt = "VALUES", M = "";
2165
+ class Re {
2166
+ constructor(e, t) {
2167
+ const n = e._tree, r = Array.from(n.keys());
2168
+ this.set = e, this._type = t, this._path = r.length > 0 ? [{ node: n, keys: r }] : [];
2169
+ }
2170
+ next() {
2171
+ const e = this.dive();
2172
+ return this.backtrack(), e;
2173
+ }
2174
+ dive() {
2175
+ if (this._path.length === 0)
2176
+ return { done: !0, value: void 0 };
2177
+ const { node: e, keys: t } = ne(this._path);
2178
+ if (ne(t) === M)
2179
+ return { done: !1, value: this.result() };
2180
+ const n = e.get(ne(t));
2181
+ return this._path.push({ node: n, keys: Array.from(n.keys()) }), this.dive();
2182
+ }
2183
+ backtrack() {
2184
+ if (this._path.length === 0)
2185
+ return;
2186
+ const e = ne(this._path).keys;
2187
+ e.pop(), !(e.length > 0) && (this._path.pop(), this.backtrack());
2188
+ }
2189
+ key() {
2190
+ return this.set._prefix + this._path.map(({ keys: e }) => ne(e)).filter((e) => e !== M).join("");
2191
+ }
2192
+ value() {
2193
+ return ne(this._path).node.get(M);
2194
+ }
2195
+ result() {
2196
+ switch (this._type) {
2197
+ case bt:
2198
+ return this.value();
2199
+ case gt:
2200
+ return this.key();
2201
+ default:
2202
+ return [this.key(), this.value()];
2203
+ }
2204
+ }
2205
+ [Symbol.iterator]() {
2206
+ return this;
2207
+ }
2208
+ }
2209
+ const ne = (a) => a[a.length - 1], On = (a, e, t) => {
2210
+ const n = /* @__PURE__ */ new Map();
2211
+ if (e === void 0)
2212
+ return n;
2213
+ const r = e.length + 1, s = r + t, i = new Uint8Array(s * r).fill(t + 1);
2214
+ for (let o = 0; o < r; ++o)
2215
+ i[o] = o;
2216
+ for (let o = 1; o < s; ++o)
2217
+ i[o * r] = o;
2218
+ return yt(a, e, t, n, i, 1, r, ""), n;
2219
+ }, yt = (a, e, t, n, r, s, i, o) => {
2220
+ const l = s * i;
2221
+ e: for (const c of a.keys())
2222
+ if (c === M) {
2223
+ const f = r[l - 1];
2224
+ f <= t && n.set(o, [a.get(c), f]);
2225
+ } else {
2226
+ let f = s;
2227
+ for (let p = 0; p < c.length; ++p, ++f) {
2228
+ const v = c[p], y = i * f, S = y - i;
2229
+ let w = r[y];
2230
+ const _ = Math.max(0, f - t - 1), N = Math.min(i - 1, f + t);
2231
+ for (let F = _; F < N; ++F) {
2232
+ const G = v !== e[F], z = r[S + F] + +G, j = r[S + F + 1] + 1, L = r[y + F] + 1, V = r[y + F + 1] = Math.min(z, j, L);
2233
+ V < w && (w = V);
2234
+ }
2235
+ if (w > t)
2236
+ continue e;
2237
+ }
2238
+ yt(a.get(c), e, t, n, r, f, i, o + c);
2239
+ }
2240
+ };
2241
+ class q {
2242
+ /**
2243
+ * The constructor is normally called without arguments, creating an empty
2244
+ * map. In order to create a {@link SearchableMap} from an iterable or from an
2245
+ * object, check {@link SearchableMap.from} and {@link
2246
+ * SearchableMap.fromObject}.
2247
+ *
2248
+ * The constructor arguments are for internal use, when creating derived
2249
+ * mutable views of a map at a prefix.
2250
+ */
2251
+ constructor(e = /* @__PURE__ */ new Map(), t = "") {
2252
+ this._size = void 0, this._tree = e, this._prefix = t;
2253
+ }
2254
+ /**
2255
+ * Creates and returns a mutable view of this {@link SearchableMap},
2256
+ * containing only entries that share the given prefix.
2257
+ *
2258
+ * ### Usage:
2259
+ *
2260
+ * ```javascript
2261
+ * let map = new SearchableMap()
2262
+ * map.set("unicorn", 1)
2263
+ * map.set("universe", 2)
2264
+ * map.set("university", 3)
2265
+ * map.set("unique", 4)
2266
+ * map.set("hello", 5)
2267
+ *
2268
+ * let uni = map.atPrefix("uni")
2269
+ * uni.get("unique") // => 4
2270
+ * uni.get("unicorn") // => 1
2271
+ * uni.get("hello") // => undefined
2272
+ *
2273
+ * let univer = map.atPrefix("univer")
2274
+ * univer.get("unique") // => undefined
2275
+ * univer.get("universe") // => 2
2276
+ * univer.get("university") // => 3
2277
+ * ```
2278
+ *
2279
+ * @param prefix The prefix
2280
+ * @return A {@link SearchableMap} representing a mutable view of the original
2281
+ * Map at the given prefix
2282
+ */
2283
+ atPrefix(e) {
2284
+ if (!e.startsWith(this._prefix))
2285
+ throw new Error("Mismatched prefix");
2286
+ const [t, n] = ke(this._tree, e.slice(this._prefix.length));
2287
+ if (t === void 0) {
2288
+ const [r, s] = $e(n);
2289
+ for (const i of r.keys())
2290
+ if (i !== M && i.startsWith(s)) {
2291
+ const o = /* @__PURE__ */ new Map();
2292
+ return o.set(i.slice(s.length), r.get(i)), new q(o, e);
2293
+ }
2294
+ }
2295
+ return new q(t, e);
2296
+ }
2297
+ /**
2298
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear
2299
+ */
2300
+ clear() {
2301
+ this._size = void 0, this._tree.clear();
2302
+ }
2303
+ /**
2304
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete
2305
+ * @param key Key to delete
2306
+ */
2307
+ delete(e) {
2308
+ return this._size = void 0, Cn(this._tree, e);
2309
+ }
2310
+ /**
2311
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries
2312
+ * @return An iterator iterating through `[key, value]` entries.
2313
+ */
2314
+ entries() {
2315
+ return new Re(this, An);
2316
+ }
2317
+ /**
2318
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach
2319
+ * @param fn Iteration function
2320
+ */
2321
+ forEach(e) {
2322
+ for (const [t, n] of this)
2323
+ e(t, n, this);
2324
+ }
2325
+ /**
2326
+ * Returns a Map of all the entries that have a key within the given edit
2327
+ * distance from the search key. The keys of the returned Map are the matching
2328
+ * keys, while the values are two-element arrays where the first element is
2329
+ * the value associated to the key, and the second is the edit distance of the
2330
+ * key to the search key.
2331
+ *
2332
+ * ### Usage:
2333
+ *
2334
+ * ```javascript
2335
+ * let map = new SearchableMap()
2336
+ * map.set('hello', 'world')
2337
+ * map.set('hell', 'yeah')
2338
+ * map.set('ciao', 'mondo')
2339
+ *
2340
+ * // Get all entries that match the key 'hallo' with a maximum edit distance of 2
2341
+ * map.fuzzyGet('hallo', 2)
2342
+ * // => Map(2) { 'hello' => ['world', 1], 'hell' => ['yeah', 2] }
2343
+ *
2344
+ * // In the example, the "hello" key has value "world" and edit distance of 1
2345
+ * // (change "e" to "a"), the key "hell" has value "yeah" and edit distance of 2
2346
+ * // (change "e" to "a", delete "o")
2347
+ * ```
2348
+ *
2349
+ * @param key The search key
2350
+ * @param maxEditDistance The maximum edit distance (Levenshtein)
2351
+ * @return A Map of the matching keys to their value and edit distance
2352
+ */
2353
+ fuzzyGet(e, t) {
2354
+ return On(this._tree, e, t);
2355
+ }
2356
+ /**
2357
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get
2358
+ * @param key Key to get
2359
+ * @return Value associated to the key, or `undefined` if the key is not
2360
+ * found.
2361
+ */
2362
+ get(e) {
2363
+ const t = ze(this._tree, e);
2364
+ return t !== void 0 ? t.get(M) : void 0;
2365
+ }
2366
+ /**
2367
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has
2368
+ * @param key Key
2369
+ * @return True if the key is in the map, false otherwise
2370
+ */
2371
+ has(e) {
2372
+ const t = ze(this._tree, e);
2373
+ return t !== void 0 && t.has(M);
2374
+ }
2375
+ /**
2376
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys
2377
+ * @return An `Iterable` iterating through keys
2378
+ */
2379
+ keys() {
2380
+ return new Re(this, gt);
2381
+ }
2382
+ /**
2383
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set
2384
+ * @param key Key to set
2385
+ * @param value Value to associate to the key
2386
+ * @return The {@link SearchableMap} itself, to allow chaining
2387
+ */
2388
+ set(e, t) {
2389
+ if (typeof e != "string")
2390
+ throw new Error("key must be a string");
2391
+ return this._size = void 0, Ae(this._tree, e).set(M, t), this;
2392
+ }
2393
+ /**
2394
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size
2395
+ */
2396
+ get size() {
2397
+ if (this._size)
2398
+ return this._size;
2399
+ this._size = 0;
2400
+ const e = this.entries();
2401
+ for (; !e.next().done; )
2402
+ this._size += 1;
2403
+ return this._size;
2404
+ }
2405
+ /**
2406
+ * Updates the value at the given key using the provided function. The function
2407
+ * is called with the current value at the key, and its return value is used as
2408
+ * the new value to be set.
2409
+ *
2410
+ * ### Example:
2411
+ *
2412
+ * ```javascript
2413
+ * // Increment the current value by one
2414
+ * searchableMap.update('somekey', (currentValue) => currentValue == null ? 0 : currentValue + 1)
2415
+ * ```
2416
+ *
2417
+ * If the value at the given key is or will be an object, it might not require
2418
+ * re-assignment. In that case it is better to use `fetch()`, because it is
2419
+ * faster.
2420
+ *
2421
+ * @param key The key to update
2422
+ * @param fn The function used to compute the new value from the current one
2423
+ * @return The {@link SearchableMap} itself, to allow chaining
2424
+ */
2425
+ update(e, t) {
2426
+ if (typeof e != "string")
2427
+ throw new Error("key must be a string");
2428
+ this._size = void 0;
2429
+ const n = Ae(this._tree, e);
2430
+ return n.set(M, t(n.get(M))), this;
2431
+ }
2432
+ /**
2433
+ * Fetches the value of the given key. If the value does not exist, calls the
2434
+ * given function to create a new value, which is inserted at the given key
2435
+ * and subsequently returned.
2436
+ *
2437
+ * ### Example:
2438
+ *
2439
+ * ```javascript
2440
+ * const map = searchableMap.fetch('somekey', () => new Map())
2441
+ * map.set('foo', 'bar')
2442
+ * ```
2443
+ *
2444
+ * @param key The key to update
2445
+ * @param initial A function that creates a new value if the key does not exist
2446
+ * @return The existing or new value at the given key
2447
+ */
2448
+ fetch(e, t) {
2449
+ if (typeof e != "string")
2450
+ throw new Error("key must be a string");
2451
+ this._size = void 0;
2452
+ const n = Ae(this._tree, e);
2453
+ let r = n.get(M);
2454
+ return r === void 0 && n.set(M, r = t()), r;
2455
+ }
2456
+ /**
2457
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values
2458
+ * @return An `Iterable` iterating through values.
2459
+ */
2460
+ values() {
2461
+ return new Re(this, bt);
2462
+ }
2463
+ /**
2464
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/@@iterator
2465
+ */
2466
+ [Symbol.iterator]() {
2467
+ return this.entries();
2468
+ }
2469
+ /**
2470
+ * Creates a {@link SearchableMap} from an `Iterable` of entries
2471
+ *
2472
+ * @param entries Entries to be inserted in the {@link SearchableMap}
2473
+ * @return A new {@link SearchableMap} with the given entries
2474
+ */
2475
+ static from(e) {
2476
+ const t = new q();
2477
+ for (const [n, r] of e)
2478
+ t.set(n, r);
2479
+ return t;
2480
+ }
2481
+ /**
2482
+ * Creates a {@link SearchableMap} from the iterable properties of a JavaScript object
2483
+ *
2484
+ * @param object Object of entries for the {@link SearchableMap}
2485
+ * @return A new {@link SearchableMap} with the given entries
2486
+ */
2487
+ static fromObject(e) {
2488
+ return q.from(Object.entries(e));
2489
+ }
2490
+ }
2491
+ const ke = (a, e, t = []) => {
2492
+ if (e.length === 0 || a == null)
2493
+ return [a, t];
2494
+ for (const n of a.keys())
2495
+ if (n !== M && e.startsWith(n))
2496
+ return t.push([a, n]), ke(a.get(n), e.slice(n.length), t);
2497
+ return t.push([a, e]), ke(void 0, "", t);
2498
+ }, ze = (a, e) => {
2499
+ if (e.length === 0 || a == null)
2500
+ return a;
2501
+ for (const t of a.keys())
2502
+ if (t !== M && e.startsWith(t))
2503
+ return ze(a.get(t), e.slice(t.length));
2504
+ }, Ae = (a, e) => {
2505
+ const t = e.length;
2506
+ e: for (let n = 0; a && n < t; ) {
2507
+ for (const s of a.keys())
2508
+ if (s !== M && e[n] === s[0]) {
2509
+ const i = Math.min(t - n, s.length);
2510
+ let o = 1;
2511
+ for (; o < i && e[n + o] === s[o]; )
2512
+ ++o;
2513
+ const l = a.get(s);
2514
+ if (o === s.length)
2515
+ a = l;
2516
+ else {
2517
+ const c = /* @__PURE__ */ new Map();
2518
+ c.set(s.slice(o), l), a.set(e.slice(n, n + o), c), a.delete(s), a = c;
2519
+ }
2520
+ n += o;
2521
+ continue e;
2522
+ }
2523
+ const r = /* @__PURE__ */ new Map();
2524
+ return a.set(e.slice(n), r), r;
2525
+ }
2526
+ return a;
2527
+ }, Cn = (a, e) => {
2528
+ const [t, n] = ke(a, e);
2529
+ if (t !== void 0) {
2530
+ if (t.delete(M), t.size === 0)
2531
+ wt(n);
2532
+ else if (t.size === 1) {
2533
+ const [r, s] = t.entries().next().value;
2534
+ St(n, r, s);
2535
+ }
2536
+ }
2537
+ }, wt = (a) => {
2538
+ if (a.length === 0)
2539
+ return;
2540
+ const [e, t] = $e(a);
2541
+ if (e.delete(t), e.size === 0)
2542
+ wt(a.slice(0, -1));
2543
+ else if (e.size === 1) {
2544
+ const [n, r] = e.entries().next().value;
2545
+ n !== M && St(a.slice(0, -1), n, r);
2546
+ }
2547
+ }, St = (a, e, t) => {
2548
+ if (a.length === 0)
2549
+ return;
2550
+ const [n, r] = $e(a);
2551
+ n.set(r + e, t), n.delete(r);
2552
+ }, $e = (a) => a[a.length - 1], Be = "or", _t = "and", Mn = "and_not";
2553
+ class re {
2554
+ /**
2555
+ * @param options Configuration options
2556
+ *
2557
+ * ### Examples:
2558
+ *
2559
+ * ```javascript
2560
+ * // Create a search engine that indexes the 'title' and 'text' fields of your
2561
+ * // documents:
2562
+ * const miniSearch = new MiniSearch({ fields: ['title', 'text'] })
2563
+ * ```
2564
+ *
2565
+ * ### ID Field:
2566
+ *
2567
+ * ```javascript
2568
+ * // Your documents are assumed to include a unique 'id' field, but if you want
2569
+ * // to use a different field for document identification, you can set the
2570
+ * // 'idField' option:
2571
+ * const miniSearch = new MiniSearch({ idField: 'key', fields: ['title', 'text'] })
2572
+ * ```
2573
+ *
2574
+ * ### Options and defaults:
2575
+ *
2576
+ * ```javascript
2577
+ * // The full set of options (here with their default value) is:
2578
+ * const miniSearch = new MiniSearch({
2579
+ * // idField: field that uniquely identifies a document
2580
+ * idField: 'id',
2581
+ *
2582
+ * // extractField: function used to get the value of a field in a document.
2583
+ * // By default, it assumes the document is a flat object with field names as
2584
+ * // property keys and field values as string property values, but custom logic
2585
+ * // can be implemented by setting this option to a custom extractor function.
2586
+ * extractField: (document, fieldName) => document[fieldName],
2587
+ *
2588
+ * // tokenize: function used to split fields into individual terms. By
2589
+ * // default, it is also used to tokenize search queries, unless a specific
2590
+ * // `tokenize` search option is supplied. When tokenizing an indexed field,
2591
+ * // the field name is passed as the second argument.
2592
+ * tokenize: (string, _fieldName) => string.split(SPACE_OR_PUNCTUATION),
2593
+ *
2594
+ * // processTerm: function used to process each tokenized term before
2595
+ * // indexing. It can be used for stemming and normalization. Return a falsy
2596
+ * // value in order to discard a term. By default, it is also used to process
2597
+ * // search queries, unless a specific `processTerm` option is supplied as a
2598
+ * // search option. When processing a term from a indexed field, the field
2599
+ * // name is passed as the second argument.
2600
+ * processTerm: (term, _fieldName) => term.toLowerCase(),
2601
+ *
2602
+ * // searchOptions: default search options, see the `search` method for
2603
+ * // details
2604
+ * searchOptions: undefined,
2605
+ *
2606
+ * // fields: document fields to be indexed. Mandatory, but not set by default
2607
+ * fields: undefined
2608
+ *
2609
+ * // storeFields: document fields to be stored and returned as part of the
2610
+ * // search results.
2611
+ * storeFields: []
2612
+ * })
2613
+ * ```
2614
+ */
2615
+ constructor(e) {
2616
+ if (e?.fields == null)
2617
+ throw new Error('MiniSearch: option "fields" must be provided');
2618
+ const t = e.autoVacuum == null || e.autoVacuum === !0 ? Me : e.autoVacuum;
2619
+ this._options = {
2620
+ ...Ce,
2621
+ ...e,
2622
+ autoVacuum: t,
2623
+ searchOptions: { ...st, ...e.searchOptions || {} },
2624
+ autoSuggestOptions: { ...Vn, ...e.autoSuggestOptions || {} }
2625
+ }, this._index = new q(), 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 = je, this.addFields(this._options.fields);
2626
+ }
2627
+ /**
2628
+ * Adds a document to the index
2629
+ *
2630
+ * @param document The document to be indexed
2631
+ */
2632
+ add(e) {
2633
+ const { extractField: t, stringifyField: n, tokenize: r, processTerm: s, fields: i, idField: o } = this._options, l = t(e, o);
2634
+ if (l == null)
2635
+ throw new Error(`MiniSearch: document does not have ID field "${o}"`);
2636
+ if (this._idToShortId.has(l))
2637
+ throw new Error(`MiniSearch: duplicate ID ${l}`);
2638
+ const c = this.addDocumentId(l);
2639
+ this.saveStoredFields(c, e);
2640
+ for (const f of i) {
2641
+ const p = t(e, f);
2642
+ if (p == null)
2643
+ continue;
2644
+ const v = r(n(p, f), f), y = this._fieldIds[f], S = new Set(v).size;
2645
+ this.addFieldLength(c, y, this._documentCount - 1, S);
2646
+ for (const w of v) {
2647
+ const _ = s(w, f);
2648
+ if (Array.isArray(_))
2649
+ for (const N of _)
2650
+ this.addTerm(y, c, N);
2651
+ else _ && this.addTerm(y, c, _);
2652
+ }
2653
+ }
2654
+ }
2655
+ /**
2656
+ * Adds all the given documents to the index
2657
+ *
2658
+ * @param documents An array of documents to be indexed
2659
+ */
2660
+ addAll(e) {
2661
+ for (const t of e)
2662
+ this.add(t);
2663
+ }
2664
+ /**
2665
+ * Adds all the given documents to the index asynchronously.
2666
+ *
2667
+ * Returns a promise that resolves (to `undefined`) when the indexing is done.
2668
+ * This method is useful when index many documents, to avoid blocking the main
2669
+ * thread. The indexing is performed asynchronously and in chunks.
2670
+ *
2671
+ * @param documents An array of documents to be indexed
2672
+ * @param options Configuration options
2673
+ * @return A promise resolving to `undefined` when the indexing is done
2674
+ */
2675
+ addAllAsync(e, t = {}) {
2676
+ const { chunkSize: n = 10 } = t, r = { chunk: [], promise: Promise.resolve() }, { chunk: s, promise: i } = e.reduce(({ chunk: o, promise: l }, c, f) => (o.push(c), (f + 1) % n === 0 ? {
2677
+ chunk: [],
2678
+ promise: l.then(() => new Promise((p) => setTimeout(p, 0))).then(() => this.addAll(o))
2679
+ } : { chunk: o, promise: l }), r);
2680
+ return i.then(() => this.addAll(s));
2681
+ }
2682
+ /**
2683
+ * Removes the given document from the index.
2684
+ *
2685
+ * The document to remove must NOT have changed between indexing and removal,
2686
+ * otherwise the index will be corrupted.
2687
+ *
2688
+ * This method requires passing the full document to be removed (not just the
2689
+ * ID), and immediately removes the document from the inverted index, allowing
2690
+ * memory to be released. A convenient alternative is {@link
2691
+ * MiniSearch#discard}, which needs only the document ID, and has the same
2692
+ * visible effect, but delays cleaning up the index until the next vacuuming.
2693
+ *
2694
+ * @param document The document to be removed
2695
+ */
2696
+ remove(e) {
2697
+ const { tokenize: t, processTerm: n, extractField: r, stringifyField: s, fields: i, idField: o } = this._options, l = r(e, o);
2698
+ if (l == null)
2699
+ throw new Error(`MiniSearch: document does not have ID field "${o}"`);
2700
+ const c = this._idToShortId.get(l);
2701
+ if (c == null)
2702
+ throw new Error(`MiniSearch: cannot remove document with ID ${l}: it is not in the index`);
2703
+ for (const f of i) {
2704
+ const p = r(e, f);
2705
+ if (p == null)
2706
+ continue;
2707
+ const v = t(s(p, f), f), y = this._fieldIds[f], S = new Set(v).size;
2708
+ this.removeFieldLength(c, y, this._documentCount, S);
2709
+ for (const w of v) {
2710
+ const _ = n(w, f);
2711
+ if (Array.isArray(_))
2712
+ for (const N of _)
2713
+ this.removeTerm(y, c, N);
2714
+ else _ && this.removeTerm(y, c, _);
2715
+ }
2716
+ }
2717
+ this._storedFields.delete(c), this._documentIds.delete(c), this._idToShortId.delete(l), this._fieldLength.delete(c), this._documentCount -= 1;
2718
+ }
2719
+ /**
2720
+ * Removes all the given documents from the index. If called with no arguments,
2721
+ * it removes _all_ documents from the index.
2722
+ *
2723
+ * @param documents The documents to be removed. If this argument is omitted,
2724
+ * all documents are removed. Note that, for removing all documents, it is
2725
+ * more efficient to call this method with no arguments than to pass all
2726
+ * documents.
2727
+ */
2728
+ removeAll(e) {
2729
+ if (e)
2730
+ for (const t of e)
2731
+ this.remove(t);
2732
+ else {
2733
+ if (arguments.length > 0)
2734
+ throw new Error("Expected documents to be present. Omit the argument to remove all documents.");
2735
+ this._index = new q(), 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;
2736
+ }
2737
+ }
2738
+ /**
2739
+ * Discards the document with the given ID, so it won't appear in search results
2740
+ *
2741
+ * It has the same visible effect of {@link MiniSearch.remove} (both cause the
2742
+ * document to stop appearing in searches), but a different effect on the
2743
+ * internal data structures:
2744
+ *
2745
+ * - {@link MiniSearch#remove} requires passing the full document to be
2746
+ * removed as argument, and removes it from the inverted index immediately.
2747
+ *
2748
+ * - {@link MiniSearch#discard} instead only needs the document ID, and
2749
+ * works by marking the current version of the document as discarded, so it
2750
+ * is immediately ignored by searches. This is faster and more convenient
2751
+ * than {@link MiniSearch#remove}, but the index is not immediately
2752
+ * modified. To take care of that, vacuuming is performed after a certain
2753
+ * number of documents are discarded, cleaning up the index and allowing
2754
+ * memory to be released.
2755
+ *
2756
+ * After discarding a document, it is possible to re-add a new version, and
2757
+ * only the new version will appear in searches. In other words, discarding
2758
+ * and re-adding a document works exactly like removing and re-adding it. The
2759
+ * {@link MiniSearch.replace} method can also be used to replace a document
2760
+ * with a new version.
2761
+ *
2762
+ * #### Details about vacuuming
2763
+ *
2764
+ * Repetite calls to this method would leave obsolete document references in
2765
+ * the index, invisible to searches. Two mechanisms take care of cleaning up:
2766
+ * clean up during search, and vacuuming.
2767
+ *
2768
+ * - Upon search, whenever a discarded ID is found (and ignored for the
2769
+ * results), references to the discarded document are removed from the
2770
+ * inverted index entries for the search terms. This ensures that subsequent
2771
+ * searches for the same terms do not need to skip these obsolete references
2772
+ * again.
2773
+ *
2774
+ * - In addition, vacuuming is performed automatically by default (see the
2775
+ * `autoVacuum` field in {@link Options}) after a certain number of
2776
+ * documents are discarded. Vacuuming traverses all terms in the index,
2777
+ * cleaning up all references to discarded documents. Vacuuming can also be
2778
+ * triggered manually by calling {@link MiniSearch#vacuum}.
2779
+ *
2780
+ * @param id The ID of the document to be discarded
2781
+ */
2782
+ discard(e) {
2783
+ const t = this._idToShortId.get(e);
2784
+ if (t == null)
2785
+ throw new Error(`MiniSearch: cannot discard document with ID ${e}: it is not in the index`);
2786
+ this._idToShortId.delete(e), this._documentIds.delete(t), this._storedFields.delete(t), (this._fieldLength.get(t) || []).forEach((n, r) => {
2787
+ this.removeFieldLength(t, r, this._documentCount, n);
2788
+ }), this._fieldLength.delete(t), this._documentCount -= 1, this._dirtCount += 1, this.maybeAutoVacuum();
2789
+ }
2790
+ maybeAutoVacuum() {
2791
+ if (this._options.autoVacuum === !1)
2792
+ return;
2793
+ const { minDirtFactor: e, minDirtCount: t, batchSize: n, batchWait: r } = this._options.autoVacuum;
2794
+ this.conditionalVacuum({ batchSize: n, batchWait: r }, { minDirtCount: t, minDirtFactor: e });
2795
+ }
2796
+ /**
2797
+ * Discards the documents with the given IDs, so they won't appear in search
2798
+ * results
2799
+ *
2800
+ * It is equivalent to calling {@link MiniSearch#discard} for all the given
2801
+ * IDs, but with the optimization of triggering at most one automatic
2802
+ * vacuuming at the end.
2803
+ *
2804
+ * Note: to remove all documents from the index, it is faster and more
2805
+ * convenient to call {@link MiniSearch.removeAll} with no argument, instead
2806
+ * of passing all IDs to this method.
2807
+ */
2808
+ discardAll(e) {
2809
+ const t = this._options.autoVacuum;
2810
+ try {
2811
+ this._options.autoVacuum = !1;
2812
+ for (const n of e)
2813
+ this.discard(n);
2814
+ } finally {
2815
+ this._options.autoVacuum = t;
2816
+ }
2817
+ this.maybeAutoVacuum();
2818
+ }
2819
+ /**
2820
+ * It replaces an existing document with the given updated version
2821
+ *
2822
+ * It works by discarding the current version and adding the updated one, so
2823
+ * it is functionally equivalent to calling {@link MiniSearch#discard}
2824
+ * followed by {@link MiniSearch#add}. The ID of the updated document should
2825
+ * be the same as the original one.
2826
+ *
2827
+ * Since it uses {@link MiniSearch#discard} internally, this method relies on
2828
+ * vacuuming to clean up obsolete document references from the index, allowing
2829
+ * memory to be released (see {@link MiniSearch#discard}).
2830
+ *
2831
+ * @param updatedDocument The updated document to replace the old version
2832
+ * with
2833
+ */
2834
+ replace(e) {
2835
+ const { idField: t, extractField: n } = this._options, r = n(e, t);
2836
+ this.discard(r), this.add(e);
2837
+ }
2838
+ /**
2839
+ * Triggers a manual vacuuming, cleaning up references to discarded documents
2840
+ * from the inverted index
2841
+ *
2842
+ * Vacuuming is only useful for applications that use the {@link
2843
+ * MiniSearch#discard} or {@link MiniSearch#replace} methods.
2844
+ *
2845
+ * By default, vacuuming is performed automatically when needed (controlled by
2846
+ * the `autoVacuum` field in {@link Options}), so there is usually no need to
2847
+ * call this method, unless one wants to make sure to perform vacuuming at a
2848
+ * specific moment.
2849
+ *
2850
+ * Vacuuming traverses all terms in the inverted index in batches, and cleans
2851
+ * up references to discarded documents from the posting list, allowing memory
2852
+ * to be released.
2853
+ *
2854
+ * The method takes an optional object as argument with the following keys:
2855
+ *
2856
+ * - `batchSize`: the size of each batch (1000 by default)
2857
+ *
2858
+ * - `batchWait`: the number of milliseconds to wait between batches (10 by
2859
+ * default)
2860
+ *
2861
+ * On large indexes, vacuuming could have a non-negligible cost: batching
2862
+ * avoids blocking the thread for long, diluting this cost so that it is not
2863
+ * negatively affecting the application. Nonetheless, this method should only
2864
+ * be called when necessary, and relying on automatic vacuuming is usually
2865
+ * better.
2866
+ *
2867
+ * It returns a promise that resolves (to undefined) when the clean up is
2868
+ * completed. If vacuuming is already ongoing at the time this method is
2869
+ * called, a new one is enqueued immediately after the ongoing one, and a
2870
+ * corresponding promise is returned. However, no more than one vacuuming is
2871
+ * enqueued on top of the ongoing one, even if this method is called more
2872
+ * times (enqueuing multiple ones would be useless).
2873
+ *
2874
+ * @param options Configuration options for the batch size and delay. See
2875
+ * {@link VacuumOptions}.
2876
+ */
2877
+ vacuum(e = {}) {
2878
+ return this.conditionalVacuum(e);
2879
+ }
2880
+ conditionalVacuum(e, t) {
2881
+ return this._currentVacuum ? (this._enqueuedVacuumConditions = this._enqueuedVacuumConditions && t, this._enqueuedVacuum != null ? this._enqueuedVacuum : (this._enqueuedVacuum = this._currentVacuum.then(() => {
2882
+ const n = this._enqueuedVacuumConditions;
2883
+ return this._enqueuedVacuumConditions = je, this.performVacuuming(e, n);
2884
+ }), this._enqueuedVacuum)) : this.vacuumConditionsMet(t) === !1 ? Promise.resolve() : (this._currentVacuum = this.performVacuuming(e), this._currentVacuum);
2885
+ }
2886
+ async performVacuuming(e, t) {
2887
+ const n = this._dirtCount;
2888
+ if (this.vacuumConditionsMet(t)) {
2889
+ const r = e.batchSize || Ve.batchSize, s = e.batchWait || Ve.batchWait;
2890
+ let i = 1;
2891
+ for (const [o, l] of this._index) {
2892
+ for (const [c, f] of l)
2893
+ for (const [p] of f)
2894
+ this._documentIds.has(p) || (f.size <= 1 ? l.delete(c) : f.delete(p));
2895
+ this._index.get(o).size === 0 && this._index.delete(o), i % r === 0 && await new Promise((c) => setTimeout(c, s)), i += 1;
2896
+ }
2897
+ this._dirtCount -= n;
2898
+ }
2899
+ await null, this._currentVacuum = this._enqueuedVacuum, this._enqueuedVacuum = null;
2900
+ }
2901
+ vacuumConditionsMet(e) {
2902
+ if (e == null)
2903
+ return !0;
2904
+ let { minDirtCount: t, minDirtFactor: n } = e;
2905
+ return t = t || Me.minDirtCount, n = n || Me.minDirtFactor, this.dirtCount >= t && this.dirtFactor >= n;
2906
+ }
2907
+ /**
2908
+ * Is `true` if a vacuuming operation is ongoing, `false` otherwise
2909
+ */
2910
+ get isVacuuming() {
2911
+ return this._currentVacuum != null;
2912
+ }
2913
+ /**
2914
+ * The number of documents discarded since the most recent vacuuming
2915
+ */
2916
+ get dirtCount() {
2917
+ return this._dirtCount;
2918
+ }
2919
+ /**
2920
+ * A number between 0 and 1 giving an indication about the proportion of
2921
+ * documents that are discarded, and can therefore be cleaned up by vacuuming.
2922
+ * A value close to 0 means that the index is relatively clean, while a higher
2923
+ * value means that the index is relatively dirty, and vacuuming could release
2924
+ * memory.
2925
+ */
2926
+ get dirtFactor() {
2927
+ return this._dirtCount / (1 + this._documentCount + this._dirtCount);
2928
+ }
2929
+ /**
2930
+ * Returns `true` if a document with the given ID is present in the index and
2931
+ * available for search, `false` otherwise
2932
+ *
2933
+ * @param id The document ID
2934
+ */
2935
+ has(e) {
2936
+ return this._idToShortId.has(e);
2937
+ }
2938
+ /**
2939
+ * Returns the stored fields (as configured in the `storeFields` constructor
2940
+ * option) for the given document ID. Returns `undefined` if the document is
2941
+ * not present in the index.
2942
+ *
2943
+ * @param id The document ID
2944
+ */
2945
+ getStoredFields(e) {
2946
+ const t = this._idToShortId.get(e);
2947
+ if (t != null)
2948
+ return this._storedFields.get(t);
2949
+ }
2950
+ /**
2951
+ * Search for documents matching the given search query.
2952
+ *
2953
+ * The result is a list of scored document IDs matching the query, sorted by
2954
+ * descending score, and each including data about which terms were matched and
2955
+ * in which fields.
2956
+ *
2957
+ * ### Basic usage:
2958
+ *
2959
+ * ```javascript
2960
+ * // Search for "zen art motorcycle" with default options: terms have to match
2961
+ * // exactly, and individual terms are joined with OR
2962
+ * miniSearch.search('zen art motorcycle')
2963
+ * // => [ { id: 2, score: 2.77258, match: { ... } }, { id: 4, score: 1.38629, match: { ... } } ]
2964
+ * ```
2965
+ *
2966
+ * ### Restrict search to specific fields:
2967
+ *
2968
+ * ```javascript
2969
+ * // Search only in the 'title' field
2970
+ * miniSearch.search('zen', { fields: ['title'] })
2971
+ * ```
2972
+ *
2973
+ * ### Field boosting:
2974
+ *
2975
+ * ```javascript
2976
+ * // Boost a field
2977
+ * miniSearch.search('zen', { boost: { title: 2 } })
2978
+ * ```
2979
+ *
2980
+ * ### Prefix search:
2981
+ *
2982
+ * ```javascript
2983
+ * // Search for "moto" with prefix search (it will match documents
2984
+ * // containing terms that start with "moto" or "neuro")
2985
+ * miniSearch.search('moto neuro', { prefix: true })
2986
+ * ```
2987
+ *
2988
+ * ### Fuzzy search:
2989
+ *
2990
+ * ```javascript
2991
+ * // Search for "ismael" with fuzzy search (it will match documents containing
2992
+ * // terms similar to "ismael", with a maximum edit distance of 0.2 term.length
2993
+ * // (rounded to nearest integer)
2994
+ * miniSearch.search('ismael', { fuzzy: 0.2 })
2995
+ * ```
2996
+ *
2997
+ * ### Combining strategies:
2998
+ *
2999
+ * ```javascript
3000
+ * // Mix of exact match, prefix search, and fuzzy search
3001
+ * miniSearch.search('ismael mob', {
3002
+ * prefix: true,
3003
+ * fuzzy: 0.2
3004
+ * })
3005
+ * ```
3006
+ *
3007
+ * ### Advanced prefix and fuzzy search:
3008
+ *
3009
+ * ```javascript
3010
+ * // Perform fuzzy and prefix search depending on the search term. Here
3011
+ * // performing prefix and fuzzy search only on terms longer than 3 characters
3012
+ * miniSearch.search('ismael mob', {
3013
+ * prefix: term => term.length > 3
3014
+ * fuzzy: term => term.length > 3 ? 0.2 : null
3015
+ * })
3016
+ * ```
3017
+ *
3018
+ * ### Combine with AND:
3019
+ *
3020
+ * ```javascript
3021
+ * // Combine search terms with AND (to match only documents that contain both
3022
+ * // "motorcycle" and "art")
3023
+ * miniSearch.search('motorcycle art', { combineWith: 'AND' })
3024
+ * ```
3025
+ *
3026
+ * ### Combine with AND_NOT:
3027
+ *
3028
+ * There is also an AND_NOT combinator, that finds documents that match the
3029
+ * first term, but do not match any of the other terms. This combinator is
3030
+ * rarely useful with simple queries, and is meant to be used with advanced
3031
+ * query combinations (see later for more details).
3032
+ *
3033
+ * ### Filtering results:
3034
+ *
3035
+ * ```javascript
3036
+ * // Filter only results in the 'fiction' category (assuming that 'category'
3037
+ * // is a stored field)
3038
+ * miniSearch.search('motorcycle art', {
3039
+ * filter: (result) => result.category === 'fiction'
3040
+ * })
3041
+ * ```
3042
+ *
3043
+ * ### Wildcard query
3044
+ *
3045
+ * Searching for an empty string (assuming the default tokenizer) returns no
3046
+ * results. Sometimes though, one needs to match all documents, like in a
3047
+ * "wildcard" search. This is possible by passing the special value
3048
+ * {@link MiniSearch.wildcard} as the query:
3049
+ *
3050
+ * ```javascript
3051
+ * // Return search results for all documents
3052
+ * miniSearch.search(MiniSearch.wildcard)
3053
+ * ```
3054
+ *
3055
+ * Note that search options such as `filter` and `boostDocument` are still
3056
+ * applied, influencing which results are returned, and their order:
3057
+ *
3058
+ * ```javascript
3059
+ * // Return search results for all documents in the 'fiction' category
3060
+ * miniSearch.search(MiniSearch.wildcard, {
3061
+ * filter: (result) => result.category === 'fiction'
3062
+ * })
3063
+ * ```
3064
+ *
3065
+ * ### Advanced combination of queries:
3066
+ *
3067
+ * It is possible to combine different subqueries with OR, AND, and AND_NOT,
3068
+ * and even with different search options, by passing a query expression
3069
+ * tree object as the first argument, instead of a string.
3070
+ *
3071
+ * ```javascript
3072
+ * // Search for documents that contain "zen" and ("motorcycle" or "archery")
3073
+ * miniSearch.search({
3074
+ * combineWith: 'AND',
3075
+ * queries: [
3076
+ * 'zen',
3077
+ * {
3078
+ * combineWith: 'OR',
3079
+ * queries: ['motorcycle', 'archery']
3080
+ * }
3081
+ * ]
3082
+ * })
3083
+ *
3084
+ * // Search for documents that contain ("apple" or "pear") but not "juice" and
3085
+ * // not "tree"
3086
+ * miniSearch.search({
3087
+ * combineWith: 'AND_NOT',
3088
+ * queries: [
3089
+ * {
3090
+ * combineWith: 'OR',
3091
+ * queries: ['apple', 'pear']
3092
+ * },
3093
+ * 'juice',
3094
+ * 'tree'
3095
+ * ]
3096
+ * })
3097
+ * ```
3098
+ *
3099
+ * Each node in the expression tree can be either a string, or an object that
3100
+ * supports all {@link SearchOptions} fields, plus a `queries` array field for
3101
+ * subqueries.
3102
+ *
3103
+ * Note that, while this can become complicated to do by hand for complex or
3104
+ * deeply nested queries, it provides a formalized expression tree API for
3105
+ * external libraries that implement a parser for custom query languages.
3106
+ *
3107
+ * @param query Search query
3108
+ * @param searchOptions Search options. Each option, if not given, defaults to the corresponding value of `searchOptions` given to the constructor, or to the library default.
3109
+ */
3110
+ search(e, t = {}) {
3111
+ const { searchOptions: n } = this._options, r = { ...n, ...t }, s = this.executeQuery(e, t), i = [];
3112
+ for (const [o, { score: l, terms: c, match: f }] of s) {
3113
+ const p = c.length || 1, v = {
3114
+ id: this._documentIds.get(o),
3115
+ score: l * p,
3116
+ terms: Object.keys(f),
3117
+ queryTerms: c,
3118
+ match: f
3119
+ };
3120
+ Object.assign(v, this._storedFields.get(o)), (r.filter == null || r.filter(v)) && i.push(v);
3121
+ }
3122
+ return e === re.wildcard && r.boostDocument == null || i.sort(ot), i;
3123
+ }
3124
+ /**
3125
+ * Provide suggestions for the given search query
3126
+ *
3127
+ * The result is a list of suggested modified search queries, derived from the
3128
+ * given search query, each with a relevance score, sorted by descending score.
3129
+ *
3130
+ * By default, it uses the same options used for search, except that by
3131
+ * default it performs prefix search on the last term of the query, and
3132
+ * combine terms with `'AND'` (requiring all query terms to match). Custom
3133
+ * options can be passed as a second argument. Defaults can be changed upon
3134
+ * calling the {@link MiniSearch} constructor, by passing a
3135
+ * `autoSuggestOptions` option.
3136
+ *
3137
+ * ### Basic usage:
3138
+ *
3139
+ * ```javascript
3140
+ * // Get suggestions for 'neuro':
3141
+ * miniSearch.autoSuggest('neuro')
3142
+ * // => [ { suggestion: 'neuromancer', terms: [ 'neuromancer' ], score: 0.46240 } ]
3143
+ * ```
3144
+ *
3145
+ * ### Multiple words:
3146
+ *
3147
+ * ```javascript
3148
+ * // Get suggestions for 'zen ar':
3149
+ * miniSearch.autoSuggest('zen ar')
3150
+ * // => [
3151
+ * // { suggestion: 'zen archery art', terms: [ 'zen', 'archery', 'art' ], score: 1.73332 },
3152
+ * // { suggestion: 'zen art', terms: [ 'zen', 'art' ], score: 1.21313 }
3153
+ * // ]
3154
+ * ```
3155
+ *
3156
+ * ### Fuzzy suggestions:
3157
+ *
3158
+ * ```javascript
3159
+ * // Correct spelling mistakes using fuzzy search:
3160
+ * miniSearch.autoSuggest('neromancer', { fuzzy: 0.2 })
3161
+ * // => [ { suggestion: 'neuromancer', terms: [ 'neuromancer' ], score: 1.03998 } ]
3162
+ * ```
3163
+ *
3164
+ * ### Filtering:
3165
+ *
3166
+ * ```javascript
3167
+ * // Get suggestions for 'zen ar', but only within the 'fiction' category
3168
+ * // (assuming that 'category' is a stored field):
3169
+ * miniSearch.autoSuggest('zen ar', {
3170
+ * filter: (result) => result.category === 'fiction'
3171
+ * })
3172
+ * // => [
3173
+ * // { suggestion: 'zen archery art', terms: [ 'zen', 'archery', 'art' ], score: 1.73332 },
3174
+ * // { suggestion: 'zen art', terms: [ 'zen', 'art' ], score: 1.21313 }
3175
+ * // ]
3176
+ * ```
3177
+ *
3178
+ * @param queryString Query string to be expanded into suggestions
3179
+ * @param options Search options. The supported options and default values
3180
+ * are the same as for the {@link MiniSearch#search} method, except that by
3181
+ * default prefix search is performed on the last term in the query, and terms
3182
+ * are combined with `'AND'`.
3183
+ * @return A sorted array of suggestions sorted by relevance score.
3184
+ */
3185
+ autoSuggest(e, t = {}) {
3186
+ t = { ...this._options.autoSuggestOptions, ...t };
3187
+ const n = /* @__PURE__ */ new Map();
3188
+ for (const { score: s, terms: i } of this.search(e, t)) {
3189
+ const o = i.join(" "), l = n.get(o);
3190
+ l != null ? (l.score += s, l.count += 1) : n.set(o, { score: s, terms: i, count: 1 });
3191
+ }
3192
+ const r = [];
3193
+ for (const [s, { score: i, terms: o, count: l }] of n)
3194
+ r.push({ suggestion: s, terms: o, score: i / l });
3195
+ return r.sort(ot), r;
3196
+ }
3197
+ /**
3198
+ * Total number of documents available to search
3199
+ */
3200
+ get documentCount() {
3201
+ return this._documentCount;
3202
+ }
3203
+ /**
3204
+ * Number of terms in the index
3205
+ */
3206
+ get termCount() {
3207
+ return this._index.size;
3208
+ }
3209
+ /**
3210
+ * Deserializes a JSON index (serialized with `JSON.stringify(miniSearch)`)
3211
+ * and instantiates a MiniSearch instance. It should be given the same options
3212
+ * originally used when serializing the index.
3213
+ *
3214
+ * ### Usage:
3215
+ *
3216
+ * ```javascript
3217
+ * // If the index was serialized with:
3218
+ * let miniSearch = new MiniSearch({ fields: ['title', 'text'] })
3219
+ * miniSearch.addAll(documents)
3220
+ *
3221
+ * const json = JSON.stringify(miniSearch)
3222
+ * // It can later be deserialized like this:
3223
+ * miniSearch = MiniSearch.loadJSON(json, { fields: ['title', 'text'] })
3224
+ * ```
3225
+ *
3226
+ * @param json JSON-serialized index
3227
+ * @param options configuration options, same as the constructor
3228
+ * @return An instance of MiniSearch deserialized from the given JSON.
3229
+ */
3230
+ static loadJSON(e, t) {
3231
+ if (t == null)
3232
+ throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");
3233
+ return this.loadJS(JSON.parse(e), t);
3234
+ }
3235
+ /**
3236
+ * Async equivalent of {@link MiniSearch.loadJSON}
3237
+ *
3238
+ * This function is an alternative to {@link MiniSearch.loadJSON} that returns
3239
+ * a promise, and loads the index in batches, leaving pauses between them to avoid
3240
+ * blocking the main thread. It tends to be slower than the synchronous
3241
+ * version, but does not block the main thread, so it can be a better choice
3242
+ * when deserializing very large indexes.
3243
+ *
3244
+ * @param json JSON-serialized index
3245
+ * @param options configuration options, same as the constructor
3246
+ * @return A Promise that will resolve to an instance of MiniSearch deserialized from the given JSON.
3247
+ */
3248
+ static async loadJSONAsync(e, t) {
3249
+ if (t == null)
3250
+ throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");
3251
+ return this.loadJSAsync(JSON.parse(e), t);
3252
+ }
3253
+ /**
3254
+ * Returns the default value of an option. It will throw an error if no option
3255
+ * with the given name exists.
3256
+ *
3257
+ * @param optionName Name of the option
3258
+ * @return The default value of the given option
3259
+ *
3260
+ * ### Usage:
3261
+ *
3262
+ * ```javascript
3263
+ * // Get default tokenizer
3264
+ * MiniSearch.getDefault('tokenize')
3265
+ *
3266
+ * // Get default term processor
3267
+ * MiniSearch.getDefault('processTerm')
3268
+ *
3269
+ * // Unknown options will throw an error
3270
+ * MiniSearch.getDefault('notExisting')
3271
+ * // => throws 'MiniSearch: unknown option "notExisting"'
3272
+ * ```
3273
+ */
3274
+ static getDefault(e) {
3275
+ if (Ce.hasOwnProperty(e))
3276
+ return Oe(Ce, e);
3277
+ throw new Error(`MiniSearch: unknown option "${e}"`);
3278
+ }
3279
+ /**
3280
+ * @ignore
3281
+ */
3282
+ static loadJS(e, t) {
3283
+ const { index: n, documentIds: r, fieldLength: s, storedFields: i, serializationVersion: o } = e, l = this.instantiateMiniSearch(e, t);
3284
+ l._documentIds = ye(r), l._fieldLength = ye(s), l._storedFields = ye(i);
3285
+ for (const [c, f] of l._documentIds)
3286
+ l._idToShortId.set(f, c);
3287
+ for (const [c, f] of n) {
3288
+ const p = /* @__PURE__ */ new Map();
3289
+ for (const v of Object.keys(f)) {
3290
+ let y = f[v];
3291
+ o === 1 && (y = y.ds), p.set(parseInt(v, 10), ye(y));
3292
+ }
3293
+ l._index.set(c, p);
3294
+ }
3295
+ return l;
3296
+ }
3297
+ /**
3298
+ * @ignore
3299
+ */
3300
+ static async loadJSAsync(e, t) {
3301
+ const { index: n, documentIds: r, fieldLength: s, storedFields: i, serializationVersion: o } = e, l = this.instantiateMiniSearch(e, t);
3302
+ l._documentIds = await we(r), l._fieldLength = await we(s), l._storedFields = await we(i);
3303
+ for (const [f, p] of l._documentIds)
3304
+ l._idToShortId.set(p, f);
3305
+ let c = 0;
3306
+ for (const [f, p] of n) {
3307
+ const v = /* @__PURE__ */ new Map();
3308
+ for (const y of Object.keys(p)) {
3309
+ let S = p[y];
3310
+ o === 1 && (S = S.ds), v.set(parseInt(y, 10), await we(S));
3311
+ }
3312
+ ++c % 1e3 === 0 && await xt(0), l._index.set(f, v);
3313
+ }
3314
+ return l;
3315
+ }
3316
+ /**
3317
+ * @ignore
3318
+ */
3319
+ static instantiateMiniSearch(e, t) {
3320
+ const { documentCount: n, nextId: r, fieldIds: s, averageFieldLength: i, dirtCount: o, serializationVersion: l } = e;
3321
+ if (l !== 1 && l !== 2)
3322
+ throw new Error("MiniSearch: cannot deserialize an index created with an incompatible version");
3323
+ const c = new re(t);
3324
+ return c._documentCount = n, c._nextId = r, c._idToShortId = /* @__PURE__ */ new Map(), c._fieldIds = s, c._avgFieldLength = i, c._dirtCount = o || 0, c._index = new q(), c;
3325
+ }
3326
+ /**
3327
+ * @ignore
3328
+ */
3329
+ executeQuery(e, t = {}) {
3330
+ if (e === re.wildcard)
3331
+ return this.executeWildcardQuery(t);
3332
+ if (typeof e != "string") {
3333
+ const v = { ...t, ...e, queries: void 0 }, y = e.queries.map((S) => this.executeQuery(S, v));
3334
+ return this.combineResults(y, v.combineWith);
3335
+ }
3336
+ const { tokenize: n, processTerm: r, searchOptions: s } = this._options, i = { tokenize: n, processTerm: r, ...s, ...t }, { tokenize: o, processTerm: l } = i, p = o(e).flatMap((v) => l(v)).filter((v) => !!v).map(zn(i)).map((v) => this.executeQuerySpec(v, i));
3337
+ return this.combineResults(p, i.combineWith);
3338
+ }
3339
+ /**
3340
+ * @ignore
3341
+ */
3342
+ executeQuerySpec(e, t) {
3343
+ const n = { ...this._options.searchOptions, ...t }, r = (n.fields || this._options.fields).reduce((w, _) => ({ ...w, [_]: Oe(n.boost, _) || 1 }), {}), { boostDocument: s, weights: i, maxFuzzy: o, bm25: l } = n, { fuzzy: c, prefix: f } = { ...st.weights, ...i }, p = this._index.get(e.term), v = this.termResults(e.term, e.term, 1, e.termBoost, p, r, s, l);
3344
+ let y, S;
3345
+ if (e.prefix && (y = this._index.atPrefix(e.term)), e.fuzzy) {
3346
+ const w = e.fuzzy === !0 ? 0.2 : e.fuzzy, _ = w < 1 ? Math.min(o, Math.round(e.term.length * w)) : w;
3347
+ _ && (S = this._index.fuzzyGet(e.term, _));
3348
+ }
3349
+ if (y)
3350
+ for (const [w, _] of y) {
3351
+ const N = w.length - e.term.length;
3352
+ if (!N)
3353
+ continue;
3354
+ S?.delete(w);
3355
+ const F = f * w.length / (w.length + 0.3 * N);
3356
+ this.termResults(e.term, w, F, e.termBoost, _, r, s, l, v);
3357
+ }
3358
+ if (S)
3359
+ for (const w of S.keys()) {
3360
+ const [_, N] = S.get(w);
3361
+ if (!N)
3362
+ continue;
3363
+ const F = c * w.length / (w.length + N);
3364
+ this.termResults(e.term, w, F, e.termBoost, _, r, s, l, v);
3365
+ }
3366
+ return v;
3367
+ }
3368
+ /**
3369
+ * @ignore
3370
+ */
3371
+ executeWildcardQuery(e) {
3372
+ const t = /* @__PURE__ */ new Map(), n = { ...this._options.searchOptions, ...e };
3373
+ for (const [r, s] of this._documentIds) {
3374
+ const i = n.boostDocument ? n.boostDocument(s, "", this._storedFields.get(r)) : 1;
3375
+ t.set(r, {
3376
+ score: i,
3377
+ terms: [],
3378
+ match: {}
3379
+ });
3380
+ }
3381
+ return t;
3382
+ }
3383
+ /**
3384
+ * @ignore
3385
+ */
3386
+ combineResults(e, t = Be) {
3387
+ if (e.length === 0)
3388
+ return /* @__PURE__ */ new Map();
3389
+ const n = t.toLowerCase(), r = Ln[n];
3390
+ if (!r)
3391
+ throw new Error(`Invalid combination operator: ${t}`);
3392
+ return e.reduce(r) || /* @__PURE__ */ new Map();
3393
+ }
3394
+ /**
3395
+ * Allows serialization of the index to JSON, to possibly store it and later
3396
+ * deserialize it with {@link MiniSearch.loadJSON}.
3397
+ *
3398
+ * Normally one does not directly call this method, but rather call the
3399
+ * standard JavaScript `JSON.stringify()` passing the {@link MiniSearch}
3400
+ * instance, and JavaScript will internally call this method. Upon
3401
+ * deserialization, one must pass to {@link MiniSearch.loadJSON} the same
3402
+ * options used to create the original instance that was serialized.
3403
+ *
3404
+ * ### Usage:
3405
+ *
3406
+ * ```javascript
3407
+ * // Serialize the index:
3408
+ * let miniSearch = new MiniSearch({ fields: ['title', 'text'] })
3409
+ * miniSearch.addAll(documents)
3410
+ * const json = JSON.stringify(miniSearch)
3411
+ *
3412
+ * // Later, to deserialize it:
3413
+ * miniSearch = MiniSearch.loadJSON(json, { fields: ['title', 'text'] })
3414
+ * ```
3415
+ *
3416
+ * @return A plain-object serializable representation of the search index.
3417
+ */
3418
+ toJSON() {
3419
+ const e = [];
3420
+ for (const [t, n] of this._index) {
3421
+ const r = {};
3422
+ for (const [s, i] of n)
3423
+ r[s] = Object.fromEntries(i);
3424
+ e.push([t, r]);
3425
+ }
3426
+ return {
3427
+ documentCount: this._documentCount,
3428
+ nextId: this._nextId,
3429
+ documentIds: Object.fromEntries(this._documentIds),
3430
+ fieldIds: this._fieldIds,
3431
+ fieldLength: Object.fromEntries(this._fieldLength),
3432
+ averageFieldLength: this._avgFieldLength,
3433
+ storedFields: Object.fromEntries(this._storedFields),
3434
+ dirtCount: this._dirtCount,
3435
+ index: e,
3436
+ serializationVersion: 2
3437
+ };
3438
+ }
3439
+ /**
3440
+ * @ignore
3441
+ */
3442
+ termResults(e, t, n, r, s, i, o, l, c = /* @__PURE__ */ new Map()) {
3443
+ if (s == null)
3444
+ return c;
3445
+ for (const f of Object.keys(i)) {
3446
+ const p = i[f], v = this._fieldIds[f], y = s.get(v);
3447
+ if (y == null)
3448
+ continue;
3449
+ let S = y.size;
3450
+ const w = this._avgFieldLength[v];
3451
+ for (const _ of y.keys()) {
3452
+ if (!this._documentIds.has(_)) {
3453
+ this.removeTerm(v, _, t), S -= 1;
3454
+ continue;
3455
+ }
3456
+ const N = o ? o(this._documentIds.get(_), t, this._storedFields.get(_)) : 1;
3457
+ if (!N)
3458
+ continue;
3459
+ const F = y.get(_), G = this._fieldLength.get(_)[v], z = Pn(F, S, this._documentCount, G, w, l), j = n * r * p * N * z, L = c.get(_);
3460
+ if (L) {
3461
+ L.score += j, jn(L.terms, e);
3462
+ const V = Oe(L.match, t);
3463
+ V ? V.push(f) : L.match[t] = [f];
3464
+ } else
3465
+ c.set(_, {
3466
+ score: j,
3467
+ terms: [e],
3468
+ match: { [t]: [f] }
3469
+ });
3470
+ }
3471
+ }
3472
+ return c;
3473
+ }
3474
+ /**
3475
+ * @ignore
3476
+ */
3477
+ addTerm(e, t, n) {
3478
+ const r = this._index.fetch(n, lt);
3479
+ let s = r.get(e);
3480
+ if (s == null)
3481
+ s = /* @__PURE__ */ new Map(), s.set(t, 1), r.set(e, s);
3482
+ else {
3483
+ const i = s.get(t);
3484
+ s.set(t, (i || 0) + 1);
3485
+ }
3486
+ }
3487
+ /**
3488
+ * @ignore
3489
+ */
3490
+ removeTerm(e, t, n) {
3491
+ if (!this._index.has(n)) {
3492
+ this.warnDocumentChanged(t, e, n);
3493
+ return;
3494
+ }
3495
+ const r = this._index.fetch(n, lt), s = r.get(e);
3496
+ s == null || s.get(t) == null ? this.warnDocumentChanged(t, e, n) : s.get(t) <= 1 ? s.size <= 1 ? r.delete(e) : s.delete(t) : s.set(t, s.get(t) - 1), this._index.get(n).size === 0 && this._index.delete(n);
3497
+ }
3498
+ /**
3499
+ * @ignore
3500
+ */
3501
+ warnDocumentChanged(e, t, n) {
3502
+ for (const r of Object.keys(this._fieldIds))
3503
+ if (this._fieldIds[r] === t) {
3504
+ this._options.logger("warn", `MiniSearch: document with ID ${this._documentIds.get(e)} has changed before removal: term "${n}" was not present in field "${r}". Removing a document after it has changed can corrupt the index!`, "version_conflict");
3505
+ return;
3506
+ }
3507
+ }
3508
+ /**
3509
+ * @ignore
3510
+ */
3511
+ addDocumentId(e) {
3512
+ const t = this._nextId;
3513
+ return this._idToShortId.set(e, t), this._documentIds.set(t, e), this._documentCount += 1, this._nextId += 1, t;
3514
+ }
3515
+ /**
3516
+ * @ignore
3517
+ */
3518
+ addFields(e) {
3519
+ for (let t = 0; t < e.length; t++)
3520
+ this._fieldIds[e[t]] = t;
3521
+ }
3522
+ /**
3523
+ * @ignore
3524
+ */
3525
+ addFieldLength(e, t, n, r) {
3526
+ let s = this._fieldLength.get(e);
3527
+ s == null && this._fieldLength.set(e, s = []), s[t] = r;
3528
+ const o = (this._avgFieldLength[t] || 0) * n + r;
3529
+ this._avgFieldLength[t] = o / (n + 1);
3530
+ }
3531
+ /**
3532
+ * @ignore
3533
+ */
3534
+ removeFieldLength(e, t, n, r) {
3535
+ if (n === 1) {
3536
+ this._avgFieldLength[t] = 0;
3537
+ return;
3538
+ }
3539
+ const s = this._avgFieldLength[t] * n - r;
3540
+ this._avgFieldLength[t] = s / (n - 1);
3541
+ }
3542
+ /**
3543
+ * @ignore
3544
+ */
3545
+ saveStoredFields(e, t) {
3546
+ const { storeFields: n, extractField: r } = this._options;
3547
+ if (n == null || n.length === 0)
3548
+ return;
3549
+ let s = this._storedFields.get(e);
3550
+ s == null && this._storedFields.set(e, s = {});
3551
+ for (const i of n) {
3552
+ const o = r(t, i);
3553
+ o !== void 0 && (s[i] = o);
3554
+ }
3555
+ }
3556
+ }
3557
+ re.wildcard = /* @__PURE__ */ Symbol("*");
3558
+ const Oe = (a, e) => Object.prototype.hasOwnProperty.call(a, e) ? a[e] : void 0, Ln = {
3559
+ [Be]: (a, e) => {
3560
+ for (const t of e.keys()) {
3561
+ const n = a.get(t);
3562
+ if (n == null)
3563
+ a.set(t, e.get(t));
3564
+ else {
3565
+ const { score: r, terms: s, match: i } = e.get(t);
3566
+ n.score = n.score + r, n.match = Object.assign(n.match, i), at(n.terms, s);
3567
+ }
3568
+ }
3569
+ return a;
3570
+ },
3571
+ [_t]: (a, e) => {
3572
+ const t = /* @__PURE__ */ new Map();
3573
+ for (const n of e.keys()) {
3574
+ const r = a.get(n);
3575
+ if (r == null)
3576
+ continue;
3577
+ const { score: s, terms: i, match: o } = e.get(n);
3578
+ at(r.terms, i), t.set(n, {
3579
+ score: r.score + s,
3580
+ terms: r.terms,
3581
+ match: Object.assign(r.match, o)
3582
+ });
3583
+ }
3584
+ return t;
3585
+ },
3586
+ [Mn]: (a, e) => {
3587
+ for (const t of e.keys())
3588
+ a.delete(t);
3589
+ return a;
3590
+ }
3591
+ }, Dn = { k: 1.2, b: 0.7, d: 0.5 }, Pn = (a, e, t, n, r, s) => {
3592
+ const { k: i, b: o, d: l } = s;
3593
+ return Math.log(1 + (t - e + 0.5) / (e + 0.5)) * (l + a * (i + 1) / (a + i * (1 - o + o * n / r)));
3594
+ }, zn = (a) => (e, t, n) => {
3595
+ const r = typeof a.fuzzy == "function" ? a.fuzzy(e, t, n) : a.fuzzy || !1, s = typeof a.prefix == "function" ? a.prefix(e, t, n) : a.prefix === !0, i = typeof a.boostTerm == "function" ? a.boostTerm(e, t, n) : 1;
3596
+ return { term: e, fuzzy: r, prefix: s, termBoost: i };
3597
+ }, Ce = {
3598
+ idField: "id",
3599
+ extractField: (a, e) => a[e],
3600
+ stringifyField: (a, e) => a.toString(),
3601
+ tokenize: (a) => a.split($n),
3602
+ processTerm: (a) => a.toLowerCase(),
3603
+ fields: void 0,
3604
+ searchOptions: void 0,
3605
+ storeFields: [],
3606
+ logger: (a, e) => {
3607
+ typeof console?.[a] == "function" && console[a](e);
3608
+ },
3609
+ autoVacuum: !0
3610
+ }, st = {
3611
+ combineWith: Be,
3612
+ prefix: !1,
3613
+ fuzzy: !1,
3614
+ maxFuzzy: 6,
3615
+ boost: {},
3616
+ weights: { fuzzy: 0.45, prefix: 0.375 },
3617
+ bm25: Dn
3618
+ }, Vn = {
3619
+ combineWith: _t,
3620
+ prefix: (a, e, t) => e === t.length - 1
3621
+ }, Ve = { batchSize: 1e3, batchWait: 10 }, je = { minDirtFactor: 0.1, minDirtCount: 20 }, Me = { ...Ve, ...je }, jn = (a, e) => {
3622
+ a.includes(e) || a.push(e);
3623
+ }, at = (a, e) => {
3624
+ for (const t of e)
3625
+ a.includes(t) || a.push(t);
3626
+ }, ot = ({ score: a }, { score: e }) => e - a, lt = () => /* @__PURE__ */ new Map(), ye = (a) => {
3627
+ const e = /* @__PURE__ */ new Map();
3628
+ for (const t of Object.keys(a))
3629
+ e.set(parseInt(t, 10), a[t]);
3630
+ return e;
3631
+ }, we = async (a) => {
3632
+ const e = /* @__PURE__ */ new Map();
3633
+ let t = 0;
3634
+ for (const n of Object.keys(a))
3635
+ e.set(parseInt(n, 10), a[n]), ++t % 1e3 === 0 && await xt(0);
3636
+ return e;
3637
+ }, xt = (a) => new Promise((e) => setTimeout(e, a)), $n = /[\n\r\p{Z}\p{P}]+/u;
3638
+ Z(Et(Yt));
3639
+ function Bn(a) {
3640
+ let e = a.replace(/\.html$/, "");
3641
+ if (e = decodeURIComponent(e), e = e.replace(/\/$/, "/index"), jt) {
3642
+ e = Ze(e.slice(1).replace(/\//g, "_") || "index") + ".md";
3643
+ let n = __VP_HASH_MAP__[e.toLowerCase()];
3644
+ if (n || (e = e.endsWith("_index.md") ? e.slice(0, -9) + ".md" : e.slice(0, -3) + "_index.md", n = __VP_HASH_MAP__[e.toLowerCase()]), !n)
3645
+ return null;
3646
+ e = `/${__ASSETS_DIR__}/${e}.${n}.js`;
3647
+ } else
3648
+ e = `./${Ze(e.slice(1).replace(/\//g, "_"))}.md.js`;
3649
+ return e;
3650
+ }
3651
+ class Wn {
3652
+ max;
3653
+ cache;
3654
+ constructor(e = 10) {
3655
+ this.max = e, this.cache = /* @__PURE__ */ new Map();
3656
+ }
3657
+ get(e) {
3658
+ let t = this.cache.get(e);
3659
+ return t !== void 0 && (this.cache.delete(e), this.cache.set(e, t)), t;
3660
+ }
3661
+ set(e, t) {
3662
+ this.cache.has(e) ? this.cache.delete(e) : this.cache.size === this.max && this.cache.delete(this.first()), this.cache.set(e, t);
3663
+ }
3664
+ first() {
3665
+ return this.cache.keys().next().value;
3666
+ }
3667
+ clear() {
3668
+ this.cache.clear();
3669
+ }
3670
+ }
3671
+ function Kn(a) {
3672
+ const { localeIndex: e, theme: t } = ct();
3673
+ function n(r) {
3674
+ const s = r.split("."), i = t.value.search?.options, o = i && typeof i == "object", l = o && i.locales?.[e.value]?.translations || null, c = o && i.translations || null;
3675
+ let f = l, p = c, v = a;
3676
+ const y = s.pop();
3677
+ for (const S of s) {
3678
+ let w = null;
3679
+ const _ = v?.[S];
3680
+ _ && (w = v = _);
3681
+ const N = p?.[S];
3682
+ N && (w = p = N);
3683
+ const F = f?.[S];
3684
+ F && (w = f = F), _ || (v = w), N || (p = w), F || (f = w);
3685
+ }
3686
+ return f?.[y] ?? p?.[y] ?? v?.[y] ?? "";
3687
+ }
3688
+ return n;
3689
+ }
3690
+ const Jn = ["aria-owns"], Un = { class: "shell" }, Hn = ["title"], qn = { class: "search-actions before" }, Gn = ["title"], Qn = ["aria-activedescendant", "aria-controls", "placeholder"], Yn = { class: "search-actions" }, Zn = ["title"], Xn = ["disabled", "title"], ei = ["id", "role", "aria-labelledby"], ti = ["id", "aria-selected"], ni = ["href", "aria-label", "onMouseenter", "onFocusin", "data-index"], ii = { class: "titles" }, ri = ["innerHTML"], si = { class: "title main" }, ai = ["innerHTML"], oi = {
3691
+ key: 0,
3692
+ class: "excerpt-wrapper"
3693
+ }, li = {
3694
+ key: 0,
3695
+ class: "excerpt",
3696
+ inert: ""
3697
+ }, ci = ["innerHTML"], ui = {
3698
+ key: 0,
3699
+ class: "no-results"
3700
+ }, di = { class: "search-keyboard-shortcuts" }, fi = ["aria-label"], hi = ["aria-label"], pi = ["aria-label"], vi = ["aria-label"], mi = /* @__PURE__ */ Tt({
3701
+ __name: "VPLocalSearchBox",
3702
+ emits: ["close"],
3703
+ setup(a, { emit: e }) {
3704
+ const t = e, n = Z(), r = Z(), s = Z(Lt), i = ct(), { activate: o } = Nn(n, {
3705
+ immediate: !0,
3706
+ allowOutsideClick: !0,
3707
+ clickOutsideDeactivates: !0,
3708
+ escapeDeactivates: !0
3709
+ }), { localeIndex: l, theme: c } = i, f = Xe(
3710
+ async () => Ye(
3711
+ re.loadJSON(
3712
+ (await s.value[l.value]?.())?.default,
3713
+ {
3714
+ fields: ["title", "titles", "text"],
3715
+ storeFields: ["title", "titles"],
3716
+ searchOptions: {
3717
+ fuzzy: 0.2,
3718
+ prefix: !0,
3719
+ boost: { title: 4, text: 2, titles: 1 },
3720
+ ...c.value.search?.provider === "local" && c.value.search.options?.miniSearch?.searchOptions
3721
+ },
3722
+ ...c.value.search?.provider === "local" && c.value.search.options?.miniSearch?.options
3723
+ }
3724
+ )
3725
+ )
3726
+ ), v = Se(() => c.value.search?.provider === "local" && c.value.search.options?.disableQueryPersistence === !0).value ? ue("") : $t("vitepress:local-search-filter", ""), y = Bt(
3727
+ "vitepress:local-search-detailed-list",
3728
+ c.value.search?.provider === "local" && c.value.search.options?.detailedView === !0
3729
+ ), S = Se(() => c.value.search?.provider === "local" && (c.value.search.options?.disableDetailedView === !0 || c.value.search.options?.detailedView === !1));
3730
+ It(() => {
3731
+ S.value && (y.value = !1);
3732
+ });
3733
+ const w = Z([]), _ = ue(!1);
3734
+ Le(v, () => {
3735
+ _.value = !1;
3736
+ });
3737
+ const N = Xe(async () => {
3738
+ if (r.value)
3739
+ return Ye(new Rn(r.value));
3740
+ }, null), F = new Wn(16);
3741
+ Wt(
3742
+ () => [f.value, v.value, y.value],
3743
+ async ([m, h, g], E, k) => {
3744
+ E?.[0] !== m && F.clear();
3745
+ let R = !1;
3746
+ if (k(() => {
3747
+ R = !0;
3748
+ }), !m) return;
3749
+ w.value = m.search(h).slice(0, 16), _.value = !0;
3750
+ const P = g ? await Promise.all(w.value.map((A) => G(A.id))) : [];
3751
+ if (R) return;
3752
+ for (const { id: A, mod: J } of P) {
3753
+ const U = A.slice(0, A.indexOf("#"));
3754
+ let oe = F.get(U);
3755
+ if (oe) continue;
3756
+ oe = /* @__PURE__ */ new Map(), F.set(U, oe);
3757
+ const le = J.default ?? J;
3758
+ if (le?.render || le?.setup) {
3759
+ const Q = Mt(le);
3760
+ Q.config.warnHandler = () => {
3761
+ }, Q.provide(Gt, i), Object.defineProperties(Q.config.globalProperties, {
3762
+ $frontmatter: {
3763
+ get() {
3764
+ return i.frontmatter.value;
3765
+ }
3766
+ },
3767
+ $params: {
3768
+ get() {
3769
+ return i.page.value.params;
3770
+ }
3771
+ }
3772
+ });
3773
+ const We = document.createElement("div");
3774
+ Q.mount(We), We.querySelectorAll("h1, h2, h3, h4, h5, h6").forEach((ce) => {
3775
+ const Ke = ce.querySelector("a")?.getAttribute("href"), Je = Ke?.startsWith("#") && Ke.slice(1);
3776
+ if (!Je) return;
3777
+ let Ue = "";
3778
+ for (; (ce = ce.nextElementSibling) && !/^h[1-6]$/i.test(ce.tagName); )
3779
+ Ue += ce.outerHTML;
3780
+ oe.set(Je, Ue);
3781
+ }), Q.unmount();
3782
+ }
3783
+ if (R) return;
3784
+ }
3785
+ const D = /* @__PURE__ */ new Set();
3786
+ if (w.value = w.value.map((A) => {
3787
+ const [J, U] = A.id.split("#"), le = F.get(J)?.get(U) ?? "";
3788
+ for (const Q in A.match)
3789
+ D.add(Q);
3790
+ return { ...A, text: le };
3791
+ }), await de(), R) return;
3792
+ await new Promise((A) => {
3793
+ N.value?.unmark({
3794
+ done: () => {
3795
+ N.value?.markRegExp(b(D), { done: A });
3796
+ }
3797
+ });
3798
+ });
3799
+ const $ = n.value?.querySelectorAll(".result .excerpt") ?? [];
3800
+ for (const A of $)
3801
+ A.querySelector('mark[data-markjs="true"]')?.scrollIntoView({ block: "center" });
3802
+ r.value?.firstElementChild?.scrollIntoView({ block: "start" });
3803
+ },
3804
+ { debounce: 200, immediate: !0 }
3805
+ );
3806
+ async function G(m) {
3807
+ const h = Bn(m.slice(0, m.indexOf("#")));
3808
+ try {
3809
+ if (!h) throw new Error(`Cannot find file for id: ${m}`);
3810
+ return { id: m, mod: await import(
3811
+ /*@vite-ignore*/
3812
+ h
3813
+ ) };
3814
+ } catch (g) {
3815
+ return console.error(g), { id: m, mod: {} };
3816
+ }
3817
+ }
3818
+ const z = ue(), j = Se(() => v.value?.length <= 0);
3819
+ function L(m = !0) {
3820
+ z.value?.focus(), m && z.value?.select();
3821
+ }
3822
+ Ne(() => {
3823
+ L();
3824
+ });
3825
+ function V(m) {
3826
+ m.pointerType === "mouse" && L();
3827
+ }
3828
+ const O = ue(-1), K = ue(!0);
3829
+ Le(w, (m) => {
3830
+ O.value = m.length ? 0 : -1, se();
3831
+ });
3832
+ function se() {
3833
+ de(() => {
3834
+ document.querySelector(".result.selected")?.scrollIntoView({ block: "nearest" });
3835
+ });
3836
+ }
3837
+ ge("ArrowUp", (m) => {
3838
+ m.preventDefault(), O.value--, O.value < 0 && (O.value = w.value.length - 1), K.value = !0, se();
3839
+ }), ge("ArrowDown", (m) => {
3840
+ m.preventDefault(), O.value++, O.value >= w.value.length && (O.value = 0), K.value = !0, se();
3841
+ });
3842
+ const ae = qt();
3843
+ ge("Enter", (m) => {
3844
+ if (m.isComposing || m.target instanceof HTMLButtonElement && m.target.type !== "submit")
3845
+ return;
3846
+ const h = w.value[O.value];
3847
+ if (m.target instanceof HTMLInputElement && !h) {
3848
+ m.preventDefault();
3849
+ return;
3850
+ }
3851
+ h && (ae.go(h.id), t("close"));
3852
+ }), ge("Escape", () => {
3853
+ t("close");
3854
+ });
3855
+ const x = Kn({
3856
+ button: {
3857
+ buttonText: "Search"
3858
+ },
3859
+ modal: {
3860
+ displayDetails: "Display detailed list",
3861
+ resetButtonTitle: "Reset search",
3862
+ backButtonTitle: "Close search",
3863
+ noResultsText: "No results for",
3864
+ footer: {
3865
+ selectText: "to select",
3866
+ selectKeyAriaLabel: "enter",
3867
+ navigateText: "to navigate",
3868
+ navigateUpKeyAriaLabel: "up arrow",
3869
+ navigateDownKeyAriaLabel: "down arrow",
3870
+ closeText: "to close",
3871
+ closeKeyAriaLabel: "escape"
3872
+ }
3873
+ }
3874
+ });
3875
+ Ne(() => {
3876
+ window.history.pushState(null, "", null);
3877
+ }), Kt("popstate", (m) => {
3878
+ m.preventDefault(), t("close");
3879
+ });
3880
+ const u = Jt(Qt ? document.body : null);
3881
+ Ne(() => {
3882
+ de(() => {
3883
+ u.value = !0, de().then(() => o());
3884
+ });
3885
+ }), kt(() => {
3886
+ u.value = !1;
3887
+ });
3888
+ function d() {
3889
+ v.value = "", de().then(() => L(!1));
3890
+ }
3891
+ function b(m) {
3892
+ return new RegExp(
3893
+ [...m].sort((h, g) => g.length - h.length).map((h) => `(${Ut(h)})`).join("|"),
3894
+ "gi"
3895
+ );
3896
+ }
3897
+ function I(m) {
3898
+ if (!K.value) return;
3899
+ const h = m.target?.closest(".result"), g = Number.parseInt(h?.dataset.index);
3900
+ g >= 0 && g !== O.value && (O.value = g), K.value = !1;
3901
+ }
3902
+ return (m, h) => (B(), Nt(Ft, { to: "body" }, [
3903
+ T("div", {
3904
+ ref_key: "el",
3905
+ ref: n,
3906
+ role: "button",
3907
+ "aria-owns": w.value?.length ? "localsearch-list" : void 0,
3908
+ "aria-expanded": "true",
3909
+ "aria-haspopup": "listbox",
3910
+ "aria-labelledby": "localsearch-label",
3911
+ class: "VPLocalSearchBox"
3912
+ }, [
3913
+ T("div", {
3914
+ class: "backdrop",
3915
+ onClick: h[0] || (h[0] = (g) => m.$emit("close"))
3916
+ }),
3917
+ T("div", Un, [
3918
+ T("form", {
3919
+ class: "search-bar",
3920
+ onPointerup: h[4] || (h[4] = (g) => V(g)),
3921
+ onSubmit: h[5] || (h[5] = Rt(() => {
3922
+ }, ["prevent"]))
3923
+ }, [
3924
+ T("label", {
3925
+ title: C(x)("button.buttonText"),
3926
+ id: "localsearch-label",
3927
+ for: "localsearch-input"
3928
+ }, [...h[7] || (h[7] = [
3929
+ T("span", {
3930
+ "aria-hidden": "true",
3931
+ class: "vpi-search search-icon local-search-icon"
3932
+ }, null, -1)
3933
+ ])], 8, Hn),
3934
+ T("div", qn, [
3935
+ T("button", {
3936
+ class: "back-button",
3937
+ title: C(x)("modal.backButtonTitle"),
3938
+ onClick: h[1] || (h[1] = (g) => m.$emit("close"))
3939
+ }, [...h[8] || (h[8] = [
3940
+ T("span", { class: "vpi-arrow-left local-search-icon" }, null, -1)
3941
+ ])], 8, Gn)
3942
+ ]),
3943
+ At(T("input", {
3944
+ ref_key: "searchInput",
3945
+ ref: z,
3946
+ "onUpdate:modelValue": h[2] || (h[2] = (g) => Ot(v) ? v.value = g : null),
3947
+ "aria-activedescendant": O.value > -1 ? "localsearch-item-" + O.value : void 0,
3948
+ "aria-autocomplete": "both",
3949
+ "aria-controls": w.value?.length ? "localsearch-list" : void 0,
3950
+ "aria-labelledby": "localsearch-label",
3951
+ autocapitalize: "off",
3952
+ autocomplete: "off",
3953
+ autocorrect: "off",
3954
+ class: "search-input",
3955
+ id: "localsearch-input",
3956
+ enterkeyhint: "go",
3957
+ maxlength: "64",
3958
+ placeholder: C(x)("button.buttonText"),
3959
+ spellcheck: "false",
3960
+ type: "search"
3961
+ }, null, 8, Qn), [
3962
+ [Ct, C(v)]
3963
+ ]),
3964
+ T("div", Yn, [
3965
+ S.value ? me("", !0) : (B(), H("button", {
3966
+ key: 0,
3967
+ class: qe(["toggle-layout-button", { "detailed-list": C(y) }]),
3968
+ type: "button",
3969
+ title: C(x)("modal.displayDetails"),
3970
+ onClick: h[3] || (h[3] = (g) => O.value > -1 && (y.value = !C(y)))
3971
+ }, [...h[9] || (h[9] = [
3972
+ T("span", { class: "vpi-layout-list local-search-icon" }, null, -1)
3973
+ ])], 10, Zn)),
3974
+ T("button", {
3975
+ class: "clear-button",
3976
+ type: "reset",
3977
+ disabled: j.value,
3978
+ title: C(x)("modal.resetButtonTitle"),
3979
+ onClick: d
3980
+ }, [...h[10] || (h[10] = [
3981
+ T("span", { class: "vpi-delete local-search-icon" }, null, -1)
3982
+ ])], 8, Xn)
3983
+ ])
3984
+ ], 32),
3985
+ T("ul", {
3986
+ ref_key: "resultsEl",
3987
+ ref: r,
3988
+ id: w.value?.length ? "localsearch-list" : void 0,
3989
+ role: w.value?.length ? "listbox" : void 0,
3990
+ "aria-labelledby": w.value?.length ? "localsearch-label" : void 0,
3991
+ class: "results",
3992
+ onMousemove: I
3993
+ }, [
3994
+ (B(!0), H(Ge, null, Qe(w.value, (g, E) => (B(), H("li", {
3995
+ key: g.id,
3996
+ id: "localsearch-item-" + E,
3997
+ "aria-selected": O.value === E ? "true" : "false",
3998
+ role: "option"
3999
+ }, [
4000
+ T("a", {
4001
+ href: g.id,
4002
+ class: qe(["result", {
4003
+ selected: O.value === E
4004
+ }]),
4005
+ "aria-label": [...g.titles, g.title].join(" > "),
4006
+ onMouseenter: (k) => !K.value && (O.value = E),
4007
+ onFocusin: (k) => O.value = E,
4008
+ onClick: h[6] || (h[6] = (k) => m.$emit("close")),
4009
+ "data-index": E
4010
+ }, [
4011
+ T("div", null, [
4012
+ T("div", ii, [
4013
+ h[12] || (h[12] = T("span", { class: "title-icon" }, "#", -1)),
4014
+ (B(!0), H(Ge, null, Qe(g.titles, (k, R) => (B(), H("span", {
4015
+ key: R,
4016
+ class: "title"
4017
+ }, [
4018
+ T("span", {
4019
+ class: "text",
4020
+ innerHTML: k
4021
+ }, null, 8, ri),
4022
+ h[11] || (h[11] = T("span", { class: "vpi-chevron-right local-search-icon" }, null, -1))
4023
+ ]))), 128)),
4024
+ T("span", si, [
4025
+ T("span", {
4026
+ class: "text",
4027
+ innerHTML: g.title
4028
+ }, null, 8, ai)
4029
+ ])
4030
+ ]),
4031
+ C(y) ? (B(), H("div", oi, [
4032
+ g.text ? (B(), H("div", li, [
4033
+ T("div", {
4034
+ class: "vp-doc",
4035
+ innerHTML: g.text
4036
+ }, null, 8, ci)
4037
+ ])) : me("", !0),
4038
+ h[13] || (h[13] = T("div", { class: "excerpt-gradient-bottom" }, null, -1)),
4039
+ h[14] || (h[14] = T("div", { class: "excerpt-gradient-top" }, null, -1))
4040
+ ])) : me("", !0)
4041
+ ])
4042
+ ], 42, ni)
4043
+ ], 8, ti))), 128)),
4044
+ C(v) && !w.value.length && _.value ? (B(), H("li", ui, [
4045
+ fe(he(C(x)("modal.noResultsText")) + ' "', 1),
4046
+ T("strong", null, he(C(v)), 1),
4047
+ h[15] || (h[15] = fe('" ', -1))
4048
+ ])) : me("", !0)
4049
+ ], 40, ei),
4050
+ T("div", di, [
4051
+ T("span", null, [
4052
+ T("kbd", {
4053
+ "aria-label": C(x)("modal.footer.navigateUpKeyAriaLabel")
4054
+ }, [...h[16] || (h[16] = [
4055
+ T("span", { class: "vpi-arrow-up navigate-icon" }, null, -1)
4056
+ ])], 8, fi),
4057
+ T("kbd", {
4058
+ "aria-label": C(x)("modal.footer.navigateDownKeyAriaLabel")
4059
+ }, [...h[17] || (h[17] = [
4060
+ T("span", { class: "vpi-arrow-down navigate-icon" }, null, -1)
4061
+ ])], 8, hi),
4062
+ fe(" " + he(C(x)("modal.footer.navigateText")), 1)
4063
+ ]),
4064
+ T("span", null, [
4065
+ T("kbd", {
4066
+ "aria-label": C(x)("modal.footer.selectKeyAriaLabel")
4067
+ }, [...h[18] || (h[18] = [
4068
+ T("span", { class: "vpi-corner-down-left navigate-icon" }, null, -1)
4069
+ ])], 8, pi),
4070
+ fe(" " + he(C(x)("modal.footer.selectText")), 1)
4071
+ ]),
4072
+ T("span", null, [
4073
+ T("kbd", {
4074
+ "aria-label": C(x)("modal.footer.closeKeyAriaLabel")
4075
+ }, "esc", 8, vi),
4076
+ fe(" " + he(C(x)("modal.footer.closeText")), 1)
4077
+ ])
4078
+ ])
4079
+ ])
4080
+ ], 8, Jn)
4081
+ ]));
4082
+ }
4083
+ }), Ei = /* @__PURE__ */ Ht(mi, [["__scopeId", "data-v-b3462fe7"]]);
4084
+ export {
4085
+ Ei as default
4086
+ };