@markput/react 0.1.0

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.
package/index.js ADDED
@@ -0,0 +1,1755 @@
1
+ import "./index.css";
2
+ import { jsx as m, Fragment as oe, jsxs as ie } from "react/jsx-runtime";
3
+ import ae, { createContext as ce, useContext as N, useEffect as x, useState as A, useRef as I, memo as W, useCallback as R, useImperativeHandle as le, useMemo as ue, forwardRef as de } from "react";
4
+ function he(t) {
5
+ return t ? Object.fromEntries(
6
+ Object.entries(t).map(([e, n]) => e.startsWith("data") && e.length > 4 && e[4] === e[4].toUpperCase() ? [`data-${e.slice(4).replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase()}`, n] : [e, n])
7
+ ) : {};
8
+ }
9
+ const fe = {
10
+ container: "div",
11
+ span: "span"
12
+ };
13
+ function Z(t, e) {
14
+ return e.props.slots?.[t] ? e.props.slots[t] : fe[t];
15
+ }
16
+ function J(t, e) {
17
+ const n = e.props.slotProps?.[t];
18
+ return n ? he(n) : void 0;
19
+ }
20
+ function ge(...t) {
21
+ return t.filter(Boolean).join(" ") || void 0;
22
+ }
23
+ function pe(...t) {
24
+ const e = t.reduce((n, s) => (s && Object.assign(n, s), n), {});
25
+ return Object.keys(e).length > 0 ? e : void 0;
26
+ }
27
+ function Q(t) {
28
+ if (t == null) throw new Error("Value must be a non nullable!");
29
+ }
30
+ var k = /* @__PURE__ */ ((t) => (t.UP = "ArrowUp", t.DOWN = "ArrowDown", t.LEFT = "ArrowLeft", t.RIGHT = "ArrowRight", t.END = "End", t.HOME = "Home", t.PAGE_DOWN = "PageDown", t.PAGE_UP = "PageUp", t.ENTER = "Enter", t.TAB = "Tab", t.SPACE = " ", t.BACKSPACE = "Backspace", t.DELETE = "Delete", t.COMMA = ",", t.ESC = "Escape", t))(k || {});
31
+ const me = "@", ve = "@[__value__](__meta__)", y = {
32
+ Value: "__value__",
33
+ Meta: "__meta__",
34
+ Nested: "__nested__"
35
+ }, w = {
36
+ Value: "value",
37
+ Meta: "meta",
38
+ Nested: "nested"
39
+ };
40
+ function xe(t, e) {
41
+ const { segments: n, gapTypes: s, counts: r, valueGapIndices: o } = ye(t);
42
+ ke(r, t);
43
+ const i = r.value === 2, { segments: a, gapTypes: c } = i ? Se(n, s, o) : { segments: n, gapTypes: s };
44
+ return {
45
+ markup: t,
46
+ index: e,
47
+ segments: a,
48
+ gapTypes: c,
49
+ hasNested: r.nested === 1,
50
+ hasTwoValues: i,
51
+ segmentGlobalIndices: Array.from({ length: a.length })
52
+ // Will be populated by MarkupRegistry
53
+ };
54
+ }
55
+ function ye(t) {
56
+ const e = [], n = [], s = [], r = {
57
+ value: 0,
58
+ meta: 0,
59
+ nested: 0
60
+ }, o = [], i = [w.Value, w.Meta, w.Nested];
61
+ for (const l of i) {
62
+ const h = j[l];
63
+ let u = t.indexOf(h);
64
+ for (; u !== -1; )
65
+ o.push({ type: l, position: u }), u = t.indexOf(h, u + h.length);
66
+ }
67
+ o.sort((l, h) => l.position - h.position);
68
+ let a = 0;
69
+ for (const l of o) {
70
+ const h = t.substring(a, l.position);
71
+ h.length > 0 && e.push(h), n.push(l.type), r[l.type]++, l.type === w.Value && s.push(n.length - 1), a = l.position + j[l.type].length;
72
+ }
73
+ const c = t.substring(a);
74
+ return c.length > 0 && e.push(c), {
75
+ segments: e,
76
+ gapTypes: n,
77
+ counts: r,
78
+ valueGapIndices: s
79
+ };
80
+ }
81
+ function ke(t, e) {
82
+ const n = [
83
+ { count: t.value, max: 2, name: y.Value },
84
+ { count: t.meta, max: 1, name: y.Meta },
85
+ { count: t.nested, max: 1, name: y.Nested }
86
+ ];
87
+ for (const { count: s, max: r, name: o } of n)
88
+ if (s > r)
89
+ throw new Error(`Invalid markup: "${e}". Max ${r} "${o}" placeholders, got ${s}`);
90
+ if (t.value === 0 && t.nested === 0)
91
+ throw new Error(
92
+ `Invalid markup: "${e}". Need at least one "${y.Value}" or "${y.Nested}"`
93
+ );
94
+ }
95
+ const j = {
96
+ [w.Value]: y.Value,
97
+ [w.Meta]: y.Meta,
98
+ [w.Nested]: y.Nested
99
+ };
100
+ function Se(t, e, n) {
101
+ if (n.length !== 2)
102
+ return { segments: t, gapTypes: e };
103
+ const [s, r] = n, o = [], i = t[s], a = t[s + 1];
104
+ i && a && o.push(u(i, a, t[s + 2]));
105
+ for (let d = s + 2; d < r; d++)
106
+ o.push(t[d]);
107
+ const c = t[r], l = t[r + 1];
108
+ c && l && o.push(u(c, l, t[r + 2]));
109
+ const h = e.filter((d) => d !== w.Value);
110
+ return { segments: o, gapTypes: h };
111
+ function u(d, g, E) {
112
+ if (!E) return [d, g, ""];
113
+ const L = E.charAt(0), re = L && !g.includes(L) && !E.startsWith(d) ? L : "";
114
+ return [d, g, re];
115
+ }
116
+ }
117
+ class Ce {
118
+ markups;
119
+ descriptors;
120
+ /** Deduplicated list of unique segment definitions (static strings or dynamic patterns) */
121
+ segments = [];
122
+ /** Map from first segment index to descriptors that start with this segment (for O(1) lookup) */
123
+ firstSegmentIndexMap = /* @__PURE__ */ new Map();
124
+ constructor(e) {
125
+ this.markups = e;
126
+ const n = /* @__PURE__ */ new Map();
127
+ this.descriptors = e.map((s, r) => {
128
+ if (s === void 0)
129
+ return null;
130
+ const o = xe(s, r);
131
+ return o.segments.forEach((i, a) => {
132
+ this.processSegment(o, i, a, n);
133
+ }), this.addToFirstSegmentIndexMap(o), o;
134
+ }).filter((s) => s !== null);
135
+ }
136
+ /**
137
+ * Adds a descriptor to the firstSegmentIndexMap using its first segment's global index
138
+ */
139
+ addToFirstSegmentIndexMap(e) {
140
+ const n = e.segmentGlobalIndices[0];
141
+ if (n === void 0) return;
142
+ const s = this.firstSegmentIndexMap.get(n);
143
+ s ? s.push(e) : this.firstSegmentIndexMap.set(n, [e]);
144
+ }
145
+ processSegment(e, n, s, r) {
146
+ const o = this.getSegmentKey(n);
147
+ if (!o) return;
148
+ this.registerSegment(n, o, r);
149
+ const i = r.get(o);
150
+ if (e.segmentGlobalIndices[s] = i, typeof n != "string") {
151
+ const [a, c] = n;
152
+ a && this.registerSegment(a, a, r), c && this.registerSegment(c, c, r);
153
+ }
154
+ }
155
+ registerSegment(e, n, s) {
156
+ if (!s.has(n)) {
157
+ const r = this.segments.length;
158
+ this.segments.push(e), s.set(n, r);
159
+ }
160
+ }
161
+ /**
162
+ * Gets a unique key for a segment definition
163
+ * For static segments (strings), returns the string itself if non-empty
164
+ * For dynamic segments (arrays), returns before|after|exclusions if before or after is non-empty
165
+ * Returns empty string for segments that should be ignored
166
+ */
167
+ getSegmentKey(e) {
168
+ if (typeof e == "string")
169
+ return e;
170
+ const [n, s, r] = e;
171
+ return n || s ? `${n}|${s}|${r}` : "";
172
+ }
173
+ }
174
+ function K(t, e) {
175
+ if (!e)
176
+ return t;
177
+ let n = 5381;
178
+ for (let s = 0; s < e.length; s++)
179
+ n = n * 33 ^ e.charCodeAt(s);
180
+ return n = n >>> 0, t * 1e6 + (n & 1048575);
181
+ }
182
+ class we {
183
+ constructor(e, n) {
184
+ if (this.descriptor = e, this.expectedSegmentIndex = 1, this.start = n.start, this.end = n.end, e.segments.length === 1 && (this.expectedSegmentIndex = NaN, this.gaps.value = { start: this.start, end: this.end }), e.hasTwoValues && n.captured) {
185
+ this.captured = n.captured;
186
+ const s = n.start + n.value.indexOf(n.captured), r = s + n.captured.length;
187
+ this.gaps.value = { start: s, end: r };
188
+ }
189
+ }
190
+ gaps = {};
191
+ /** Captured value from first dynamic segment (for hasTwoValues patterns) */
192
+ captured;
193
+ /**
194
+ * Index of expected next segment:
195
+ * - >= 0: active, waiting for segment at this index
196
+ * - NaN: completed successfully
197
+ * - -1: invalid, should be discarded
198
+ */
199
+ expectedSegmentIndex;
200
+ start;
201
+ end;
202
+ /**
203
+ * Check if the match is invalid and should be discarded
204
+ */
205
+ get isInvalid() {
206
+ return this.expectedSegmentIndex === -1;
207
+ }
208
+ /**
209
+ * Check if the pattern is completed (computed property)
210
+ */
211
+ get isCompleted() {
212
+ return isNaN(this.expectedSegmentIndex);
213
+ }
214
+ /**
215
+ * Check if the match is waiting for the last segment (high priority)
216
+ */
217
+ get isAwaitingLastSegment() {
218
+ return this.expectedSegmentIndex === this.descriptor.segments.length - 1;
219
+ }
220
+ /**
221
+ * Get the next expected segment index
222
+ */
223
+ get nextSegment() {
224
+ if (this.isCompleted || this.isInvalid)
225
+ return;
226
+ const e = this.descriptor.segmentGlobalIndices[this.expectedSegmentIndex], n = this.descriptor.segments[this.expectedSegmentIndex];
227
+ if (typeof n == "object" && this.descriptor.hasTwoValues && this.captured && this.isAwaitingLastSegment) {
228
+ const [s, r] = n, o = s + this.captured + r;
229
+ return K(e, o);
230
+ }
231
+ return e;
232
+ }
233
+ /**
234
+ * Update state with new segment by setting gap positions
235
+ */
236
+ processNext(e) {
237
+ const n = this.end, s = e.start, r = this.descriptor.gapTypes[this.expectedSegmentIndex - 1];
238
+ if (s < n) {
239
+ this.expectedSegmentIndex = -1;
240
+ return;
241
+ }
242
+ this.gaps[r] = { start: n, end: s }, this.end = e.end, this.expectedSegmentIndex++, this.expectedSegmentIndex >= this.descriptor.segments.length && (this.expectedSegmentIndex = NaN);
243
+ }
244
+ /**
245
+ * Checks if this match conflicts with another match (overlaps and cannot nest properly)
246
+ */
247
+ conflictsWith(e) {
248
+ return !e || this.start >= e.end ? !1 : !e.descriptor.hasNested || e.gaps.nested === void 0 ? !0 : !(this.start >= e.gaps.nested.start && this.end <= e.gaps.nested.end);
249
+ }
250
+ }
251
+ class Te {
252
+ constructor(e) {
253
+ this.registry = e;
254
+ }
255
+ pendingStates = /* @__PURE__ */ new Map();
256
+ completingStates = /* @__PURE__ */ new Map();
257
+ completedStates = [];
258
+ /** Main method that converts found segments into structured matches */
259
+ process(e) {
260
+ this.pendingStates.clear(), this.completingStates.clear(), this.completedStates.length = 0;
261
+ for (const n of e)
262
+ this.processWaitingStates(n), this.tryStartNewStates(n);
263
+ return this.completedStates.map((n) => n.match);
264
+ }
265
+ /**
266
+ * Process states waiting for this segment
267
+ * Try states by priority until one is valid, keeping rejected states for later attempts
268
+ * Process completing states first (higher priority), then pending states
269
+ * Process only one state per call
270
+ */
271
+ processWaitingStates(e) {
272
+ const n = this.dequeueWaitingMatch(e);
273
+ if (n && (n.processNext(e), !n.isInvalid)) {
274
+ if (n.isCompleted) return this.addToCompleted(n);
275
+ this.addToWaiting(n);
276
+ }
277
+ }
278
+ tryStartNewStates(e) {
279
+ this.registry.firstSegmentIndexMap.get(e.index)?.forEach((n) => {
280
+ const s = new we(n, e);
281
+ if (!s.isInvalid) {
282
+ if (s.isCompleted) return this.addToCompleted(s);
283
+ this.addToWaiting(s);
284
+ }
285
+ });
286
+ }
287
+ /**
288
+ * Gets the next waiting match for the given segment
289
+ * Uses value-specific index for dynamic segments, base index for static segments
290
+ */
291
+ dequeueWaitingMatch(e) {
292
+ const n = e.captured ? K(e.index, e.value) : e.index, s = this.completingStates.get(n);
293
+ if (s?.length) return s.pop();
294
+ const r = this.pendingStates.get(n);
295
+ if (r?.length) return r.pop();
296
+ }
297
+ /**
298
+ * Adds a state to the waiting list for the next expected segment
299
+ */
300
+ addToWaiting(e) {
301
+ const n = e.nextSegment;
302
+ if (e.isAwaitingLastSegment) {
303
+ const s = this.completingStates.get(n) || [];
304
+ s.length === 0 && this.completingStates.set(n, s), s.push(e);
305
+ } else {
306
+ const s = this.pendingStates.get(n) || [];
307
+ s.length === 0 && this.pendingStates.set(n, s), s.push(e);
308
+ }
309
+ }
310
+ /**
311
+ * Add match to position-indexed array, replacing any existing match at the same position
312
+ * Uses binary search to find insertion point and maintains sorted order
313
+ * Relies on processing order to determine which match to keep
314
+ */
315
+ addToCompleted(e) {
316
+ const n = e.start;
317
+ let s = 0, r = this.completedStates.length;
318
+ for (; s < r; ) {
319
+ const o = Math.floor((s + r) / 2);
320
+ this.completedStates[o].position < n ? s = o + 1 : r = o;
321
+ }
322
+ s < this.completedStates.length && this.completedStates[s].position === n ? this.completedStates[s].match = e : this.completedStates.splice(s, 0, { position: n, match: e });
323
+ }
324
+ }
325
+ const b = (t) => t.replace(/[.*+?^${}()|[\]\\\\]/g, "\\$&");
326
+ function Ee(t, e, n) {
327
+ const s = b(t), r = b(e), o = b(e + n);
328
+ return `${s}([^${o}]+?)${r}`;
329
+ }
330
+ class be {
331
+ staticRegex;
332
+ staticToIndex;
333
+ dynamicRegex;
334
+ dynamicEntries;
335
+ dynamicIndices;
336
+ constructor(e) {
337
+ this.initializeDual(e);
338
+ }
339
+ initializeDual(e) {
340
+ const n = [], s = [], r = /* @__PURE__ */ new Map();
341
+ if (e.forEach((o, i) => {
342
+ typeof o == "string" ? (n.push(o), r.set(o, i)) : s.push(o);
343
+ }), n.length > 0) {
344
+ const i = [...n].sort((a, c) => c.length - a.length).map(b);
345
+ this.staticRegex = new RegExp(`(?:${i.join("|")})`, "gu"), this.staticToIndex = r;
346
+ }
347
+ if (s.length > 0) {
348
+ const o = /* @__PURE__ */ new Set(), i = [];
349
+ s.forEach((a) => {
350
+ const c = e.indexOf(a);
351
+ if (typeof a == "string")
352
+ i.push({ index: c, pattern: b(a), definition: a });
353
+ else {
354
+ const [l, h, u] = a;
355
+ o.add(c);
356
+ const g = Ee(l, h, u).replace("(", `(?<content${c}>`);
357
+ i.push({ index: c, pattern: g, definition: a });
358
+ }
359
+ }), i.sort((a, c) => {
360
+ const l = typeof a.definition == "string" ? a.definition.length : a.pattern.length;
361
+ return (typeof c.definition == "string" ? c.definition.length : c.pattern.length) - l;
362
+ }), this.dynamicEntries = i, this.dynamicIndices = o, this.dynamicRegex = new RegExp(i.map((a, c) => `(?<seg${c}>${a.pattern})`).join("|"), "gu");
363
+ }
364
+ }
365
+ search(e) {
366
+ const n = [], s = [];
367
+ if (this.staticRegex && this.staticToIndex)
368
+ for (const o of e.matchAll(this.staticRegex)) {
369
+ const i = this.staticToIndex.get(o[0]);
370
+ i !== void 0 && n.push({
371
+ index: i,
372
+ start: o.index,
373
+ end: o.index + o[0].length,
374
+ value: o[0]
375
+ });
376
+ }
377
+ if (this.dynamicRegex && this.dynamicEntries && this.dynamicIndices)
378
+ for (const o of e.matchAll(this.dynamicRegex)) {
379
+ const i = o[0], a = o.index;
380
+ let c, l;
381
+ if (o.groups) {
382
+ for (let h = 0; h < this.dynamicEntries.length; h++)
383
+ if (o.groups[`seg${h}`] !== void 0) {
384
+ c = this.dynamicEntries[h].index, this.dynamicIndices.has(c) && (l = o.groups[`content${c}`]);
385
+ break;
386
+ }
387
+ }
388
+ c !== void 0 && s.push({
389
+ index: c,
390
+ start: a,
391
+ end: a + i.length,
392
+ value: i,
393
+ captured: l
394
+ });
395
+ }
396
+ const r = [...s];
397
+ for (const o of n)
398
+ s.some(
399
+ (a) => o.start < a.end && o.end > a.start
400
+ ) || r.push(o);
401
+ return r.sort((o, i) => o.start - i.start), r;
402
+ }
403
+ }
404
+ const Y = (t, e = 0, n = t.length) => ({
405
+ type: "text",
406
+ content: t.substring(e, n),
407
+ position: { start: e, end: n }
408
+ });
409
+ class Ie {
410
+ // Instance fields - only what's needed for single pass
411
+ input;
412
+ // ===== PUBLIC API =====
413
+ /**
414
+ * Builds nested token tree from pre-processed matches in a single pass
415
+ *
416
+ * Algorithm:
417
+ * 1. Iterate through matches in order
418
+ * 2. For each match:
419
+ * - Close any parents whose content ends before this match
420
+ * - Skip matches that conflict with the last accepted match
421
+ * - Add text token before this match
422
+ * - Create mark token and push to appropriate parent
423
+ * - If match has nested content, push to active parents stack
424
+ * 3. After all matches, close remaining parents and add final text
425
+ *
426
+ * Complexity: O(M) where M is number of matches
427
+ * Memory: O(D) for active parents stack where D is nesting depth
428
+ */
429
+ build(e, n) {
430
+ return this.input = n, e.length === 0 ? [this.createTextToken(0, n.length)] : this.buildSinglePass(e);
431
+ }
432
+ // ===== SINGLE-PASS ALGORITHM =====
433
+ /**
434
+ * Builds token tree in a single pass through matches
435
+ *
436
+ * This is the core algorithm that processes matches sequentially,
437
+ * maintaining a stack of active parents and creating tokens directly.
438
+ */
439
+ buildSinglePass(e) {
440
+ const n = [], s = [];
441
+ let r = null, o = 0;
442
+ for (const i of e) {
443
+ if (r && i.conflictsWith(r))
444
+ continue;
445
+ for (r = i; s.length > 0; ) {
446
+ const l = s[s.length - 1], h = this.getContentBounds(l.match);
447
+ if (h.end <= i.start)
448
+ this.finalizeParent(l, h.end), s.pop(), s.length > 0 ? s[s.length - 1].token.children.push(l.token) : n.push(l.token);
449
+ else
450
+ break;
451
+ }
452
+ const a = s.length > 0 ? s[s.length - 1] : null;
453
+ if (a) {
454
+ const l = this.createTextToken(a.textPos, i.start);
455
+ a.token.children.push(l), a.textPos = i.end;
456
+ } else {
457
+ const l = this.createTextToken(o, i.start);
458
+ n.push(l), o = i.end;
459
+ }
460
+ const c = this.createMarkToken(i);
461
+ if (this.hasNestedContent(i)) {
462
+ const l = this.getContentBounds(i);
463
+ s.push({
464
+ match: i,
465
+ token: c,
466
+ textPos: l.start
467
+ });
468
+ } else
469
+ a ? a.token.children.push(c) : n.push(c);
470
+ }
471
+ for (; s.length > 0; ) {
472
+ const i = s.pop(), a = this.getContentBounds(i.match);
473
+ this.finalizeParent(i, a.end), s.length > 0 ? s[s.length - 1].token.children.push(i.token) : n.push(i.token);
474
+ }
475
+ return n.push(this.createTextToken(o, this.input.length)), n;
476
+ }
477
+ /**
478
+ * Finalizes a parent token by adding final text token if needed
479
+ */
480
+ finalizeParent(e, n) {
481
+ const s = this.createTextToken(e.textPos, n);
482
+ e.token.children.push(s), e.token.children.some((o) => o.type === "mark") || (e.token.children = []);
483
+ }
484
+ /**
485
+ * Creates a mark token from a match (without children - those are added later)
486
+ */
487
+ createMarkToken(e) {
488
+ const n = this.extractSubstring(e.gaps.value?.start, e.gaps.value?.end), s = this.extractSubstring(e.gaps.nested?.start, e.gaps.nested?.end), r = this.extractSubstring(e.gaps.meta?.start, e.gaps.meta?.end), o = s || void 0, i = e.gaps.meta !== void 0 ? r : void 0, a = n || o || "";
489
+ return {
490
+ type: "mark",
491
+ content: this.input.substring(e.start, e.end),
492
+ children: [],
493
+ // Will be populated if match has nested content
494
+ descriptor: e.descriptor,
495
+ value: a,
496
+ meta: i,
497
+ position: { start: e.start, end: e.end },
498
+ nested: this.createNestedInfo(e, o)
499
+ };
500
+ }
501
+ // ===== UTILITY METHODS =====
502
+ /**
503
+ * Gets the content boundaries for a match
504
+ * Priority: nested content if present, otherwise value content
505
+ */
506
+ getContentBounds(e) {
507
+ return e.gaps.nested ? e.gaps.nested : e.gaps.value ? e.gaps.value : {
508
+ start: e.start,
509
+ end: e.start
510
+ };
511
+ }
512
+ /**
513
+ * Checks if a match has nested content capability
514
+ */
515
+ hasNestedContent(e) {
516
+ return e.gaps.nested !== void 0;
517
+ }
518
+ /**
519
+ * Extracts substring safely, returns empty string if positions are undefined
520
+ */
521
+ extractSubstring(e, n) {
522
+ return e !== void 0 && n !== void 0 ? this.input.substring(e, n) : "";
523
+ }
524
+ /**
525
+ * Creates a text token for a range in the input
526
+ */
527
+ createTextToken(e, n) {
528
+ return Y(this.input, e, n);
529
+ }
530
+ /**
531
+ * Creates nested info object if nested content exists
532
+ */
533
+ createNestedInfo(e, n) {
534
+ if (!(!n || e.gaps.nested === void 0))
535
+ return {
536
+ content: n,
537
+ start: e.gaps.nested.start,
538
+ end: e.gaps.nested.end
539
+ };
540
+ }
541
+ }
542
+ function $(t, e) {
543
+ let n = t;
544
+ return e.value !== void 0 && (n = n.replaceAll(y.Value, e.value)), e.meta !== void 0 && (n = n.replaceAll(y.Meta, e.meta)), e.nested !== void 0 && (n = n.replaceAll(y.Nested, e.nested)), n;
545
+ }
546
+ function T(t) {
547
+ let e = "";
548
+ for (const n of t) {
549
+ if (n.type === "text") {
550
+ e += n.content;
551
+ continue;
552
+ }
553
+ const s = n.descriptor.markup, r = s.includes(y.Nested) ? n.children.length > 0 ? T(n.children) : n.nested?.content : void 0;
554
+ e += $(s, {
555
+ value: n.value,
556
+ meta: n.meta,
557
+ nested: r
558
+ });
559
+ }
560
+ return e;
561
+ }
562
+ function G(t, e) {
563
+ let n = "";
564
+ for (const s of t)
565
+ if (s.type === "text")
566
+ n += s.content;
567
+ else if (s.children.length > 0) {
568
+ const r = G(s.children, e), o = {
569
+ ...s,
570
+ value: r
571
+ };
572
+ n += e(o);
573
+ } else
574
+ n += e(s);
575
+ return n;
576
+ }
577
+ class O {
578
+ registry;
579
+ segmentMatcher;
580
+ patternMatcher;
581
+ treeBuilder;
582
+ /**
583
+ * Creates a new Parser instance with the specified markup patterns
584
+ *
585
+ * @param markups - Array of markup pattern strings with placeholders (can include undefined values):
586
+ * - `__value__` - main content (plain text, no nesting)
587
+ * - `__meta__` - metadata (plain text, no nesting)
588
+ * - `__nested__` - content supporting nested structures
589
+ * - `undefined` - skipped, but original array indices are preserved for descriptor matching
590
+ *
591
+ * @example
592
+ * ```typescript
593
+ * const parser = new Parser([
594
+ * '@[__value__](__meta__)', // @[label](value) - descriptor.index = 0
595
+ * undefined, // skipped
596
+ * '#[__nested__]', // #[nested content] - descriptor.index = 2
597
+ * '**__nested__**' // **bold text** - descriptor.index = 3
598
+ * ])
599
+ * ```
600
+ */
601
+ constructor(e) {
602
+ this.registry = new Ce(e), this.segmentMatcher = new be(this.registry.segments), this.patternMatcher = new Te(this.registry), this.treeBuilder = new Ie();
603
+ }
604
+ /**
605
+ * Parses text into tokens (static convenience method)
606
+ *
607
+ * @param value - Text to parse
608
+ * @param options - Options with markup patterns
609
+ * @returns Array of tokens (TextToken and MarkToken)
610
+ *
611
+ * @example
612
+ * ```typescript
613
+ * const tokens = Parser.parse('Hello @[world]', {
614
+ * markup: ['@[__value__]']
615
+ * })
616
+ * ```
617
+ */
618
+ static parse(e, n) {
619
+ const s = n?.markup;
620
+ return !s || s.length === 0 ? [Y(e)] : new O(s).parse(e);
621
+ }
622
+ /**
623
+ * Converts tokens back to text (static convenience method)
624
+ *
625
+ * @param tokens - Array of tokens to convert
626
+ * @returns Reconstructed text string
627
+ *
628
+ * @example
629
+ * ```typescript
630
+ * const text = Parser.stringify(tokens)
631
+ * ```
632
+ */
633
+ static stringify(e) {
634
+ return T(e);
635
+ }
636
+ /**
637
+ * Parses text into a nested token tree
638
+ *
639
+ * This is the main parsing method. It processes the input text through
640
+ * three stages:
641
+ * 1. Segment matching - finds all markup segments (O(N + M))
642
+ * 2. Pattern matching - builds complete patterns from segments (O(M))
643
+ * 3. Tree building - constructs nested token tree (O(M·D))
644
+ *
645
+ * @param value - Text to parse
646
+ * @returns Array of tokens representing the parsed structure
647
+ *
648
+ * @example
649
+ * ```typescript
650
+ * const parser = new Parser(['@[__value__](__meta__)'])
651
+ * const tokens = parser.parse('Hello @[world](test)')
652
+ * // Returns: [
653
+ * // TextToken('Hello '),
654
+ * // MarkToken('@[world](test)', value='world', meta='test'),
655
+ * // TextToken('')
656
+ * // ]
657
+ * ```
658
+ */
659
+ parse(e) {
660
+ const n = this.segmentMatcher.search(e), s = this.patternMatcher.process(n);
661
+ return this.treeBuilder.build(s, e);
662
+ }
663
+ /**
664
+ * Converts tokens back to the original text
665
+ *
666
+ * This is the inverse operation of parse(). It reconstructs the original
667
+ * text from a token tree, preserving all markup and structure.
668
+ *
669
+ * @param tokens - Array of tokens to convert
670
+ * @returns Reconstructed text string
671
+ *
672
+ * @example
673
+ * ```typescript
674
+ * const text = 'Hello @[world](test)'
675
+ * const tokens = parser.parse(text)
676
+ * const reconstructed = parser.stringify(tokens)
677
+ * console.log(reconstructed === text) // true
678
+ * ```
679
+ */
680
+ stringify(e) {
681
+ return T(e);
682
+ }
683
+ /**
684
+ * Transforms annotated text by processing all mark tokens with a callback
685
+ *
686
+ * This method parses the text, recursively processes all MarkTokens
687
+ * (including nested ones) with the provided callback, and returns
688
+ * the transformed text.
689
+ *
690
+ * @param value - Annotated text to process
691
+ * @param callback - Function to transform each MarkToken
692
+ * @returns Transformed text
693
+ *
694
+ * @example
695
+ * ```typescript
696
+ * // Extract all values
697
+ * const text = '@[Hello](world) and #[tag]'
698
+ * const result = parser.transform(text, mark => mark.value)
699
+ * // Returns: 'Hello and tag'
700
+ *
701
+ * // Custom transformation
702
+ * const result = parser.transform(text, mark =>
703
+ * mark.meta ? `${mark.value}:${mark.meta}` : mark.value
704
+ * )
705
+ * // Returns: 'Hello:world and tag'
706
+ * ```
707
+ */
708
+ transform(e, n) {
709
+ const s = this.parse(e);
710
+ return G(s, n);
711
+ }
712
+ /**
713
+ * Escapes markup segments in the given text using backslash
714
+ *
715
+ * This method uses the registry's unique segments and escapes them by adding
716
+ * a backslash before each character of each segment, preventing them from being
717
+ * parsed as markup when the text is processed again.
718
+ *
719
+ * @param text - Text to escape segments in
720
+ * @returns Text with escaped segments
721
+ *
722
+ * @example
723
+ * ```typescript
724
+ * const parser = new Parser(['**__nested__**', '@[__value__]'])
725
+ * const escaped = parser.escape('Hello **world** and @[user]')
726
+ * // Returns: 'Hello \*\*world\*\* and \@[user]'
727
+ * ```
728
+ */
729
+ escape(e) {
730
+ return this.registry.segments.filter((n) => typeof n == "string").sort((n, s) => s.length - n.length).reduce((n, s) => n.replaceAll(s, s.replace(/(.)/g, "\\$1")), e);
731
+ }
732
+ /**
733
+ * Unescapes markup patterns in the given text
734
+ *
735
+ * This method removes escape characters from segments that were previously
736
+ * escaped using escape(), allowing the patterns to be parsed normally.
737
+ *
738
+ * @param text - Text to unescape patterns in
739
+ * @returns Text with unescaped patterns
740
+ *
741
+ * @example
742
+ * ```typescript
743
+ * const parser = new Parser(['**__nested__**', '@[__value__]'])
744
+ * const unescaped = parser.unescape('Hello \*\*world\*\* and \@[user]')
745
+ * // Returns: 'Hello **world** and @[user]'
746
+ * ```
747
+ */
748
+ unescape(e) {
749
+ return e.replaceAll(/\\(.)/g, "$1");
750
+ }
751
+ }
752
+ function kt(t, e, n) {
753
+ if (!n.length) return t;
754
+ const s = new O(n).parse(t);
755
+ return G(s, e);
756
+ }
757
+ function Me(t = "", e = "") {
758
+ if (t === e) return {};
759
+ let n;
760
+ for (let r = 0; r < t.length; r++)
761
+ if (t[r] !== e[r]) {
762
+ n = r;
763
+ break;
764
+ }
765
+ let s;
766
+ for (let r = 1; r <= t.length; r++)
767
+ if (t.at(-r) !== e.at(-r)) {
768
+ s = t.length - r + 1;
769
+ break;
770
+ }
771
+ return { left: n, right: s };
772
+ }
773
+ function q(t, e) {
774
+ let n = -1, s = t.length;
775
+ for (; s - n > 1; ) {
776
+ const r = Math.round((n + s) / 2);
777
+ t[r] <= e ? n = r : s = r;
778
+ }
779
+ return t[n] == e && (s = n), [n, s].filter((r) => t[r] !== void 0);
780
+ }
781
+ function Pe(t, e) {
782
+ if (Object.is(t, e))
783
+ return !0;
784
+ if (typeof t != "object" || t === null || typeof e != "object" || e === null)
785
+ return !1;
786
+ const n = Object.keys(t);
787
+ if (n.length !== Object.keys(e).length)
788
+ return !1;
789
+ for (let s = 0; s < n.length; s++)
790
+ if (!Object.prototype.hasOwnProperty.call(e, n[s]) || !Object.is(t[n[s]], e[n[s]]))
791
+ return !1;
792
+ return !0;
793
+ }
794
+ function Ne(t, e, n, s) {
795
+ return t.slice(0, n) + e + t.slice(n + s.length);
796
+ }
797
+ function _(t, e) {
798
+ const s = {
799
+ prev: 2,
800
+ self: 1,
801
+ next: 0
802
+ }[t], { focus: r } = e.nodes, [o, , i] = e.tokens.splice(r.index - s, 3), a = (o.type === "text", o.content), c = (i.type === "text", i.content);
803
+ e.tokens = e.tokens.toSpliced(r.index - s, 0, {
804
+ type: "text",
805
+ content: a + c,
806
+ position: {
807
+ start: o.position.start,
808
+ end: i.position.end
809
+ }
810
+ });
811
+ let l = r;
812
+ for (let u = 0; u < s; u++)
813
+ l = l.prev;
814
+ const h = l.length;
815
+ e.recovery = { anchor: l.prev, caret: h }, e.props.onChange?.(T(e.tokens));
816
+ }
817
+ class Ae {
818
+ #t = /* @__PURE__ */ new Map();
819
+ send(e, n) {
820
+ this.#e(e).forEach((s) => s(n));
821
+ }
822
+ on(e, n) {
823
+ return this.#e(e).add(n), () => this.#e(e).delete(n);
824
+ }
825
+ #e(e) {
826
+ return this.#t.has(e) || this.#t.set(e, /* @__PURE__ */ new Set()), this.#t.get(e);
827
+ }
828
+ }
829
+ const p = {
830
+ STORE_UPDATED: Symbol(),
831
+ ClearTrigger: Symbol(),
832
+ CheckTrigger: Symbol(),
833
+ Change: Symbol(),
834
+ Parse: Symbol(),
835
+ Delete: Symbol(),
836
+ Select: Symbol()
837
+ };
838
+ class S {
839
+ static get isSelectedPosition() {
840
+ const e = window.getSelection();
841
+ if (e)
842
+ return e.isCollapsed;
843
+ }
844
+ static getCurrentPosition() {
845
+ return window.getSelection()?.anchorOffset ?? 0;
846
+ }
847
+ //TODO get span from state?
848
+ static getFocusedSpan() {
849
+ return window.getSelection()?.anchorNode?.textContent ?? "";
850
+ }
851
+ static getSelectedNode() {
852
+ const e = window.getSelection()?.anchorNode;
853
+ if (e) return e;
854
+ throw new Error("Anchor node of selection is not exists!");
855
+ }
856
+ //TODO add the returned type: "{left: CSSProperties["left"], top: CSSProperties["top"]}"?
857
+ static getAbsolutePosition() {
858
+ const e = window.getSelection()?.getRangeAt(0).getBoundingClientRect?.();
859
+ return e ? { left: e.left, top: e.top + e.height + 1 } : { left: 0, top: 0 };
860
+ }
861
+ static trySetIndex(e, n) {
862
+ try {
863
+ this.setIndex(e, n);
864
+ } catch (s) {
865
+ console.error(s);
866
+ }
867
+ }
868
+ static setIndex(e, n) {
869
+ const s = window.getSelection();
870
+ if (!s?.anchorNode || !s.rangeCount) return;
871
+ const r = s.getRangeAt(0);
872
+ r?.setStart(e.firstChild || e, n), r?.setEnd(e.firstChild || e, n);
873
+ }
874
+ static getCaretIndex(e) {
875
+ let n = 0;
876
+ const s = window.getSelection();
877
+ if (!s?.rangeCount) return n;
878
+ const r = s.getRangeAt(0), o = r.cloneRange();
879
+ return o.selectNodeContents(e), o.setEnd(r.endContainer, r.endOffset), n = o.toString().length, n;
880
+ }
881
+ static setCaretToEnd(e) {
882
+ if (!e) return;
883
+ window.getSelection()?.setPosition(e, 1);
884
+ }
885
+ static getIndex() {
886
+ return window.getSelection()?.anchorOffset ?? NaN;
887
+ }
888
+ static setIndex1(e) {
889
+ const n = window.getSelection();
890
+ if (!n?.anchorNode || !n.rangeCount) return;
891
+ const s = n.getRangeAt(0);
892
+ s?.setStart(s.startContainer.firstChild || s.startContainer, e), s?.setEnd(s.startContainer.firstChild || s.startContainer, e);
893
+ }
894
+ setCaretRightTo(e, n) {
895
+ const r = window.getSelection()?.getRangeAt(0);
896
+ r?.setStart(r.endContainer, n), r?.setEnd(r.endContainer, n);
897
+ }
898
+ }
899
+ const Oe = new RegExp(/^\w*/);
900
+ class U {
901
+ span;
902
+ node;
903
+ dividedText;
904
+ constructor() {
905
+ const e = S.getCurrentPosition();
906
+ this.node = S.getSelectedNode(), this.span = S.getFocusedSpan(), this.dividedText = this.getDividedTextBy(e);
907
+ }
908
+ /**
909
+ * Find overlay match in text using provided options and trigger extractor.
910
+ * @template T - Type of option objects
911
+ * @param options - Array of options to search through
912
+ * @param getTrigger - Function that extracts trigger from each option
913
+ * @returns OverlayMatch with correct option type or undefined
914
+ *
915
+ * @example
916
+ * // React usage
917
+ * TriggerFinder.find(options, (opt) => opt.slotProps?.overlay?.trigger ?? '@')
918
+ *
919
+ * @example
920
+ * // Other framework usage
921
+ * TriggerFinder.find(vueOptions, (opt) => opt.overlay?.trigger ?? '@')
922
+ */
923
+ static find(e, n) {
924
+ if (e && S.isSelectedPosition)
925
+ return new U().find(e, n);
926
+ }
927
+ getDividedTextBy(e) {
928
+ return { left: this.span.slice(0, e), right: this.span.slice(e) };
929
+ }
930
+ /**
931
+ * Find overlay match in provided options.
932
+ * @template T - Type of option objects
933
+ * @param options - Array of options
934
+ * @param getTrigger - Function to extract trigger from each option
935
+ */
936
+ find(e, n) {
937
+ for (let s = 0; s < e.length; s++) {
938
+ const r = e[s], o = n(r, s);
939
+ if (!o) continue;
940
+ const i = this.matchInTextVia(o);
941
+ if (i)
942
+ return {
943
+ value: i.word,
944
+ source: i.annotation,
945
+ index: i.index,
946
+ span: this.span,
947
+ node: this.node,
948
+ option: r
949
+ };
950
+ }
951
+ }
952
+ matchInTextVia(e = "@") {
953
+ const n = this.matchRightPart(), s = this.matchLeftPart(e);
954
+ if (s)
955
+ return {
956
+ word: s.word + n.word,
957
+ annotation: s.annotation + n.word,
958
+ index: s.index
959
+ };
960
+ }
961
+ matchRightPart() {
962
+ const { right: e } = this.dividedText;
963
+ return { word: e.match(Oe)?.[0] };
964
+ }
965
+ matchLeftPart(e) {
966
+ const n = this.makeTriggerRegex(e), { left: s } = this.dividedText, r = s.match(n);
967
+ if (!r) return;
968
+ const [o, i] = r;
969
+ return { word: i, annotation: o, index: r.index ?? 0 };
970
+ }
971
+ //TODO new overlayMatch option if (isSpaceBeforeRequired) append space check for not first words '\\s'
972
+ makeTriggerRegex(e) {
973
+ const n = b(e) + "(\\w*)$";
974
+ return new RegExp(n);
975
+ }
976
+ }
977
+ class M {
978
+ #t;
979
+ #e;
980
+ get target() {
981
+ return this.#t;
982
+ }
983
+ set target(e) {
984
+ this.#t = e;
985
+ }
986
+ get next() {
987
+ return new M(this.target?.nextSibling, this.#e);
988
+ }
989
+ get prev() {
990
+ return new M(this.target?.previousSibling, this.#e);
991
+ }
992
+ get isSpan() {
993
+ return this.index % 2 === 0;
994
+ }
995
+ get isMark() {
996
+ return !this.isSpan;
997
+ }
998
+ get isEditable() {
999
+ return this.target?.isContentEditable ?? !1;
1000
+ }
1001
+ get isCaretAtBeginning() {
1002
+ return this.target ? S.getCaretIndex(this.target) === 0 : void 0;
1003
+ }
1004
+ get isCaretAtEnd() {
1005
+ return this.target ? S.getCaretIndex(this.target) === this.target.textContent?.length : void 0;
1006
+ }
1007
+ get index() {
1008
+ return this.target?.parentElement ? [...this.target.parentElement.children].indexOf(this.target) : -1;
1009
+ }
1010
+ get caret() {
1011
+ return this.target ? S.getCaretIndex(this.target) : -1;
1012
+ }
1013
+ set caret(e) {
1014
+ this.target && S.trySetIndex(this.target, e);
1015
+ }
1016
+ get length() {
1017
+ return this.target?.textContent?.length ?? -1;
1018
+ }
1019
+ get content() {
1020
+ return this.target?.textContent ?? "";
1021
+ }
1022
+ set content(e) {
1023
+ this.target && (this.target.textContent = e ?? "");
1024
+ }
1025
+ get head() {
1026
+ return this.#e.refs.container?.firstChild;
1027
+ }
1028
+ get tail() {
1029
+ return this.#e.refs.container?.lastChild;
1030
+ }
1031
+ get isFocused() {
1032
+ return this.target === document.activeElement;
1033
+ }
1034
+ constructor(e, n) {
1035
+ this.target = e, this.#e = n;
1036
+ }
1037
+ setCaretToEnd() {
1038
+ S.setCaretToEnd(this.target);
1039
+ }
1040
+ focus() {
1041
+ this.target?.focus();
1042
+ }
1043
+ clear() {
1044
+ this.target = void 0;
1045
+ }
1046
+ }
1047
+ class Le {
1048
+ #t = 1;
1049
+ #e = /* @__PURE__ */ new WeakMap();
1050
+ get(e) {
1051
+ return this.#e.has(e) ? this.#e.get(e) : (this.#e.set(e, this.#t), this.#t++);
1052
+ }
1053
+ }
1054
+ class B {
1055
+ // Utils domain
1056
+ bus = new Ae();
1057
+ key = new Le();
1058
+ // Config domain
1059
+ props;
1060
+ // Document domain
1061
+ tokens = [];
1062
+ parser;
1063
+ previousValue;
1064
+ // Navigation domain
1065
+ nodes = {
1066
+ focus: new M(void 0, this),
1067
+ input: new M(void 0, this)
1068
+ };
1069
+ recovery;
1070
+ // UI domain
1071
+ refs = {
1072
+ container: null,
1073
+ overlay: null,
1074
+ setContainer: (e) => {
1075
+ this.refs.container = e;
1076
+ },
1077
+ setOverlay: (e) => {
1078
+ this.refs.overlay = e;
1079
+ }
1080
+ };
1081
+ selecting;
1082
+ // Overlay domain
1083
+ overlayMatch;
1084
+ constructor(e) {
1085
+ this.props = e;
1086
+ }
1087
+ static create = (e) => new Proxy(new B(e), { set: De });
1088
+ }
1089
+ const _e = /* @__PURE__ */ new Set(["bus", "refs", "nodes", "key"]);
1090
+ function De(t, e, n, s) {
1091
+ return _e.has(String(e)) ? !1 : (t[e] === n || (t[e] = n, t.bus.send(p.STORE_UPDATED, s)), !0);
1092
+ }
1093
+ const P = ce(void 0);
1094
+ P.displayName = "StoreContext";
1095
+ function v(t, e, n) {
1096
+ typeof t == "string" ? $e(t, e, n) : Re(t, e, n);
1097
+ }
1098
+ function Re(t, e, n) {
1099
+ const s = N(P);
1100
+ Q(s), x(() => s.bus.on(t, e), n);
1101
+ }
1102
+ function $e(t, e, n) {
1103
+ const s = N(P);
1104
+ x(() => (s?.refs.container?.addEventListener(t, e), () => s?.refs.container?.removeEventListener(t, e)), n);
1105
+ }
1106
+ function f(t, e) {
1107
+ const n = N(P);
1108
+ Q(n);
1109
+ const [s, r] = A(() => t?.(n));
1110
+ return v(
1111
+ p.STORE_UPDATED,
1112
+ () => {
1113
+ r((o) => {
1114
+ const i = t?.(n);
1115
+ return e && Pe(o, i) ? o : i;
1116
+ });
1117
+ },
1118
+ []
1119
+ ), t ? s : n;
1120
+ }
1121
+ const Ve = (t) => {
1122
+ const e = ae.createContext(void 0);
1123
+ e.displayName = t;
1124
+ const n = o(e), s = e.Provider;
1125
+ return [n, s, e];
1126
+ function o(i) {
1127
+ return () => {
1128
+ const a = N(i);
1129
+ if (a) return a;
1130
+ throw new Error(`The context ${i.displayName} didn't found!`);
1131
+ };
1132
+ }
1133
+ }, [H, X] = Ve("NodeProvider");
1134
+ function ee(t, e, n, s) {
1135
+ const r = f((c) => t === "mark" ? c.props.Mark : c.props.Overlay), o = t === "mark" ? e?.mark : e?.overlay;
1136
+ let i;
1137
+ o !== void 0 ? typeof o == "function" ? i = o(n) : i = o : i = n ?? {};
1138
+ const a = i.slot || r || s;
1139
+ if (!a)
1140
+ throw new Error(
1141
+ `No ${t} component found. Provide either option.${t}.slot, global ${t === "mark" ? "Mark" : "Overlay"}, or a defaultComponent.`
1142
+ );
1143
+ return [a, i];
1144
+ }
1145
+ function Fe() {
1146
+ const t = H(), { options: e, key: n } = f((c) => ({ options: c.props.options, key: c.key }), !0), s = e?.[t.descriptor.index], r = t.children.map((c) => /* @__PURE__ */ m(z, { mark: c, isNested: !0 }, n.get(c))), o = {
1147
+ value: t.value,
1148
+ meta: t.meta,
1149
+ nested: t.nested?.content,
1150
+ children: t.children.length > 0 ? r : void 0
1151
+ }, [i, a] = ee("mark", s, o);
1152
+ return /* @__PURE__ */ m(i, { ...a });
1153
+ }
1154
+ const We = () => {
1155
+ const t = H(), e = I(null), { readOnly: n, SpanComponent: s, spanProps: r } = f(
1156
+ (o) => ({
1157
+ readOnly: o.props.readOnly,
1158
+ SpanComponent: Z("span", o),
1159
+ spanProps: J("span", o)
1160
+ }),
1161
+ !0
1162
+ );
1163
+ if (t.type !== "text")
1164
+ throw new Error("TextSpan component expects a TextToken");
1165
+ return /* @__PURE__ */ m(
1166
+ s,
1167
+ {
1168
+ ...r,
1169
+ ref: e,
1170
+ contentEditable: !n,
1171
+ onPaste: Ge,
1172
+ suppressContentEditableWarning: !0,
1173
+ children: t.content
1174
+ }
1175
+ );
1176
+ };
1177
+ function Ge(t) {
1178
+ t.preventDefault();
1179
+ const e = t.clipboardData.getData("text");
1180
+ document.execCommand("insertText", !1, e);
1181
+ }
1182
+ const z = W(({ mark: t, isNested: e = !1 }) => t.type === "mark" ? /* @__PURE__ */ m(X, { value: t, children: /* @__PURE__ */ m(Fe, {}) }) : e ? /* @__PURE__ */ m(oe, { children: t.content }) : /* @__PURE__ */ m(X, { value: t, children: /* @__PURE__ */ m(We, {}) }));
1183
+ z.displayName = "Token";
1184
+ const te = W(() => {
1185
+ const { className: t, style: e, tokens: n, bus: s, key: r, ContainerComponent: o, containerProps: i, refs: a } = f(
1186
+ (c) => ({
1187
+ className: c.props.className,
1188
+ style: c.props.style,
1189
+ tokens: c.tokens,
1190
+ bus: c.bus,
1191
+ key: c.key,
1192
+ refs: c.refs,
1193
+ ContainerComponent: Z("container", c),
1194
+ containerProps: J("container", c)
1195
+ }),
1196
+ !0
1197
+ );
1198
+ return v("input", () => s.send(p.Change), []), /* @__PURE__ */ m(o, { ref: a.setContainer, ...i, className: t, style: e, children: n.map((c) => /* @__PURE__ */ m(z, { mark: c }, r.get(c))) });
1199
+ });
1200
+ te.displayName = "Container";
1201
+ function Ue() {
1202
+ const { match: t, bus: e } = f(
1203
+ (n) => ({
1204
+ match: n.overlayMatch,
1205
+ bus: n.bus
1206
+ }),
1207
+ !0
1208
+ );
1209
+ x(() => {
1210
+ if (!t) return;
1211
+ const n = (s) => {
1212
+ s.key === k.ESC && e.send(p.ClearTrigger);
1213
+ };
1214
+ return window.addEventListener("keydown", n), () => window.removeEventListener("keydown", n);
1215
+ }, [t, e]);
1216
+ }
1217
+ function Be() {
1218
+ const t = f(), e = f((n) => n.overlayMatch);
1219
+ x(() => {
1220
+ if (!e) return;
1221
+ const n = (s) => {
1222
+ const r = s.target;
1223
+ t.refs.overlay?.contains(r) || t.refs.container?.contains(r) || t.bus.send(p.ClearTrigger);
1224
+ };
1225
+ return document.addEventListener("click", n), () => document.removeEventListener("click", n);
1226
+ }, [e]);
1227
+ }
1228
+ function C(t, e, n = []) {
1229
+ v(
1230
+ "keydown",
1231
+ (s) => {
1232
+ s.key === t && e(s);
1233
+ },
1234
+ n
1235
+ );
1236
+ }
1237
+ function He() {
1238
+ const t = f();
1239
+ C(k.LEFT, e), C(k.RIGHT, n), C(k.DELETE, s), C(k.BACKSPACE, s), C(k.DELETE, o), C(k.BACKSPACE, r), v("keydown", i, []), v("paste", l, []), x(() => {
1240
+ const u = t.refs.container;
1241
+ if (!u) return;
1242
+ const d = (g) => {
1243
+ c(g);
1244
+ };
1245
+ return u.addEventListener("beforeinput", d, !0), () => u.removeEventListener("beforeinput", d, !0);
1246
+ }, []);
1247
+ function e(u) {
1248
+ const { focus: d } = t.nodes;
1249
+ if (d.isMark && !d.isEditable || d.isCaretAtBeginning) {
1250
+ const g = d.prev;
1251
+ g.focus(), g.isFocused || (g.prev.focus(), u.preventDefault()), d.setCaretToEnd();
1252
+ }
1253
+ }
1254
+ function n(u) {
1255
+ const { focus: d } = t.nodes;
1256
+ if (d.isMark && !d.isEditable || d.isCaretAtEnd) {
1257
+ const g = d.next;
1258
+ g.focus(), g.isFocused || (g.next.focus(), u.preventDefault());
1259
+ }
1260
+ }
1261
+ function s() {
1262
+ t.nodes.focus.isMark && _("self", t);
1263
+ }
1264
+ function r(u) {
1265
+ t.nodes.focus.isSpan && t.nodes.focus.isCaretAtBeginning && t.nodes.focus.prev.target && (u.preventDefault(), _("prev", t));
1266
+ }
1267
+ function o(u) {
1268
+ t.nodes.focus.isSpan && t.nodes.focus.isCaretAtEnd && t.nodes.focus.next.target && (u.preventDefault(), _("next", t));
1269
+ }
1270
+ function i(u) {
1271
+ if ((u.ctrlKey || u.metaKey) && u.code === "KeyA") {
1272
+ u.preventDefault();
1273
+ const d = window.getSelection(), g = t.refs.container?.firstChild, E = t.refs.container?.lastChild;
1274
+ if (!d || !g || !E) return;
1275
+ d.setBaseAndExtent(g, 0, E, 1), t.selecting = "all";
1276
+ }
1277
+ }
1278
+ function a() {
1279
+ const u = window.getSelection(), d = t.refs.container;
1280
+ if (!u?.rangeCount || !d?.firstChild || !d?.lastChild) return !1;
1281
+ try {
1282
+ const g = u.getRangeAt(0);
1283
+ return d.contains(g.startContainer) && d.contains(g.endContainer) && g.toString().length > 0;
1284
+ } catch {
1285
+ return !1;
1286
+ }
1287
+ }
1288
+ function c(u) {
1289
+ if (t.selecting !== "all" || !a()) {
1290
+ t.selecting === "all" && (t.selecting = void 0);
1291
+ return;
1292
+ }
1293
+ if (u.inputType === "insertFromPaste") return;
1294
+ u.preventDefault();
1295
+ const d = u.inputType.startsWith("delete") ? "" : u.data ?? "";
1296
+ h(d);
1297
+ }
1298
+ function l(u) {
1299
+ if (t.selecting !== "all" || !a()) {
1300
+ t.selecting === "all" && (t.selecting = void 0);
1301
+ return;
1302
+ }
1303
+ u.preventDefault();
1304
+ const d = u.clipboardData?.getData("text/plain") ?? "";
1305
+ h(d);
1306
+ }
1307
+ function h(u) {
1308
+ t.nodes.focus.target = null, t.selecting = void 0, t.props.onChange?.(u), t.props.value === void 0 && (t.tokens = t.parser?.parse(u) ?? [
1309
+ {
1310
+ type: "text",
1311
+ content: u,
1312
+ position: { start: 0, end: u.length }
1313
+ }
1314
+ ]), queueMicrotask(() => {
1315
+ const d = t.refs.container?.firstChild;
1316
+ d && (t.recovery = {
1317
+ anchor: t.nodes.focus,
1318
+ caret: u.length
1319
+ }, d.focus());
1320
+ });
1321
+ }
1322
+ }
1323
+ function ze() {
1324
+ const t = f();
1325
+ v(
1326
+ p.Change,
1327
+ () => {
1328
+ const { onChange: e } = t.props;
1329
+ if (!t.nodes.focus.target) return;
1330
+ const n = t.tokens[t.nodes.focus.index];
1331
+ n.type === "text" ? n.content = t.nodes.focus.content : n.type === "mark" && (n.value = t.nodes.focus.content), e?.(T(t.tokens)), t.bus.send(p.Parse);
1332
+ },
1333
+ []
1334
+ ), v(
1335
+ p.Delete,
1336
+ ({ token: e }) => {
1337
+ const { onChange: n } = t.props;
1338
+ t.tokens.splice(t.tokens.indexOf(e), 1), n?.(T(t.tokens));
1339
+ },
1340
+ []
1341
+ ), v(
1342
+ p.Select,
1343
+ (e) => {
1344
+ const { Mark: n, onChange: s } = t.props, {
1345
+ mark: r,
1346
+ match: { option: o, span: i, index: a, source: c }
1347
+ } = e, l = r.type === "mark" ? $(o.markup, {
1348
+ value: r.value,
1349
+ meta: r.meta
1350
+ }) : $(o.markup, {
1351
+ value: r.content
1352
+ }), h = Ne(i, l, a, c);
1353
+ if (t.recovery = n ? { caret: 0, anchor: t.nodes.input.next, isNext: !0 } : { caret: a + l.length, anchor: t.nodes.input }, t.nodes.input.target) {
1354
+ t.nodes.input.content = h;
1355
+ const u = t.tokens[t.nodes.input.index];
1356
+ u.type === "text" && (u.content = h), t.nodes.focus.target = t.nodes.input.target, t.nodes.input.clear(), s?.(T(t.tokens)), t.bus.send(p.Parse);
1357
+ }
1358
+ },
1359
+ []
1360
+ );
1361
+ }
1362
+ const je = () => {
1363
+ const t = f();
1364
+ v("focusin", (e) => t.nodes.focus.target = e.target, []), v("focusout", (e) => t.nodes.focus.target = void 0, []);
1365
+ }, qe = () => {
1366
+ const t = f(), e = f((n) => n.tokens);
1367
+ v(
1368
+ "click",
1369
+ () => {
1370
+ e.length === 1 && e[0].type === "text" && e[0].content === "" && t.refs.container?.firstElementChild?.focus();
1371
+ },
1372
+ [e]
1373
+ );
1374
+ }, Xe = () => {
1375
+ const t = f(), e = f((s) => s.tokens), n = t.props.Mark ? [e] : void 0;
1376
+ x(() => {
1377
+ if (!t.recovery) return;
1378
+ const { anchor: s, caret: r, isNext: o } = t.recovery;
1379
+ switch (!0) {
1380
+ case (o && !s.target):
1381
+ t.nodes.focus.tail.focus();
1382
+ break;
1383
+ case o:
1384
+ s.prev.focus();
1385
+ break;
1386
+ case !s.target:
1387
+ t.nodes.focus.head.focus();
1388
+ break;
1389
+ default:
1390
+ s.next.focus();
1391
+ }
1392
+ t.nodes.focus.caret = r, t.recovery = void 0;
1393
+ }, n);
1394
+ };
1395
+ function Ze() {
1396
+ const t = f(), e = I(!1), n = I(null);
1397
+ x(() => {
1398
+ const s = (r) => {
1399
+ n.current = r.target, e.current = !0;
1400
+ };
1401
+ return document.addEventListener("mousedown", s), () => document.removeEventListener("mousedown", s);
1402
+ }, []), x(() => {
1403
+ const s = (r) => {
1404
+ const o = e.current, i = !t.refs.container?.contains(n.current) || n.current !== r.target, a = window.getSelection()?.containsNode(t.refs.container, !0);
1405
+ o && i && a && (t.selecting = "drag");
1406
+ };
1407
+ return document.addEventListener("mousemove", s), () => document.removeEventListener("mousemove", s);
1408
+ }, []), x(() => {
1409
+ const s = () => {
1410
+ e.current = !1, n.current = null, t.selecting = void 0;
1411
+ };
1412
+ return document.addEventListener("mouseup", s), () => document.removeEventListener("mouseup", s);
1413
+ }, []), Je();
1414
+ }
1415
+ function Je() {
1416
+ const t = f(), e = f((n) => n.selecting);
1417
+ x(() => {
1418
+ if (e !== "drag") return;
1419
+ const n = [...t.refs.container.children], s = n.map((r) => r.contentEditable);
1420
+ return n.forEach((r) => r.contentEditable = "false"), () => n.forEach((r, o) => r.contentEditable = s[o]);
1421
+ }, [e]);
1422
+ }
1423
+ function Qe() {
1424
+ const t = f(), e = R(() => {
1425
+ const n = t.props.showOverlayOn, s = "selectionChange";
1426
+ (n === s || n.includes(s)) && t.bus.send(p.CheckTrigger);
1427
+ }, []);
1428
+ v(
1429
+ "focusin",
1430
+ () => {
1431
+ document.addEventListener("selectionchange", e);
1432
+ },
1433
+ []
1434
+ ), v(
1435
+ "focusout",
1436
+ () => {
1437
+ document.removeEventListener("selectionchange", e);
1438
+ },
1439
+ []
1440
+ ), v(
1441
+ p.Change,
1442
+ () => {
1443
+ const n = t.props.showOverlayOn, s = "change";
1444
+ (n === s || n.includes(s)) && t.bus.send(p.CheckTrigger);
1445
+ },
1446
+ []
1447
+ );
1448
+ }
1449
+ const Ke = () => {
1450
+ const t = f();
1451
+ v(p.ClearTrigger, (e) => t.overlayMatch = void 0, []), v(
1452
+ p.CheckTrigger,
1453
+ (e) => t.overlayMatch = U.find(t.props.options, (n) => n.overlay?.trigger),
1454
+ []
1455
+ );
1456
+ }, Ye = () => {
1457
+ const t = f(), e = I(!1), { value: n, options: s } = f(
1458
+ (r) => ({
1459
+ value: r.props.value,
1460
+ options: r.props.Mark ? r.props.options : void 0
1461
+ }),
1462
+ !0
1463
+ );
1464
+ x(() => {
1465
+ const r = s?.map((i) => i.markup);
1466
+ if (r && r.some(Boolean) ? t.parser = new O(r) : t.parser = void 0, e.current) {
1467
+ t.bus.send(p.Parse);
1468
+ return;
1469
+ }
1470
+ const o = n ?? t.props.defaultValue ?? "";
1471
+ t.parser ? t.tokens = t.parser.parse(o) : t.tokens = [
1472
+ {
1473
+ type: "text",
1474
+ content: o,
1475
+ position: { start: 0, end: o.length }
1476
+ }
1477
+ ], e.current = !0;
1478
+ }, [n, s]), v(
1479
+ p.Parse,
1480
+ () => {
1481
+ t.tokens = t.nodes.focus.target ? et(t) : tt(t);
1482
+ },
1483
+ []
1484
+ );
1485
+ };
1486
+ function et(t) {
1487
+ const { focus: e } = t.nodes;
1488
+ if (!t.parser)
1489
+ return t.tokens;
1490
+ const n = t.parser.parse(e.content);
1491
+ return n.length === 1 ? t.tokens : t.tokens.toSpliced(e.index, 1, ...n);
1492
+ }
1493
+ function tt(t) {
1494
+ const {
1495
+ props: { value: e }
1496
+ } = t, n = nt(t), s = Me(t.previousValue, e);
1497
+ switch (t.previousValue = e, !0) {
1498
+ //Mark removing happen
1499
+ case (s.left && n.includes(s.left) && s.right && Math.abs(s.left - s.right) > 1): {
1500
+ const r = n.indexOf(s.left), o = D(t, r - 1, r);
1501
+ return t.tokens.toSpliced(r - 1, 2, ...o);
1502
+ }
1503
+ //Changing in label
1504
+ case s.left !== void 0: {
1505
+ const [r] = q(n, s.left), o = D(t, r);
1506
+ return o.length === 1 ? t.tokens : t.tokens.toSpliced(r, 1, ...o);
1507
+ }
1508
+ case s.right !== void 0: {
1509
+ const [r] = q(n, s.right), o = D(t, r);
1510
+ return o.length === 1 ? t.tokens : t.tokens.toSpliced(r, 1, ...o);
1511
+ }
1512
+ default:
1513
+ return ne(t, e ?? "");
1514
+ }
1515
+ }
1516
+ function D(t, ...e) {
1517
+ let n = "";
1518
+ for (const s of e) {
1519
+ const r = t.tokens[s];
1520
+ n += r.content;
1521
+ }
1522
+ return ne(t, n);
1523
+ }
1524
+ function nt(t) {
1525
+ let e = 0;
1526
+ return t.tokens.map((n) => {
1527
+ const s = n.content.length;
1528
+ return e += s, e - s;
1529
+ }) ?? [];
1530
+ }
1531
+ function ne(t, e) {
1532
+ return t.parser ? t.parser.parse(e) : [
1533
+ {
1534
+ type: "text",
1535
+ content: e,
1536
+ position: { start: 0, end: e.length }
1537
+ }
1538
+ ];
1539
+ }
1540
+ const st = (t) => ({
1541
+ get container() {
1542
+ return t.refs.container;
1543
+ },
1544
+ get overlay() {
1545
+ return t.refs.overlay;
1546
+ },
1547
+ focus() {
1548
+ t.nodes.focus.head?.focus();
1549
+ }
1550
+ });
1551
+ function rt(t) {
1552
+ const e = f();
1553
+ le(t, () => st(e), [e]);
1554
+ }
1555
+ const ot = ({ inRef: t }) => (rt(t), ze(), Ye(), je(), He(), qe(), Xe(), Ke(), Qe(), Ue(), Be(), Ze(), null), it = "_Container_1lmfr_1", at = "_Suggestions_1lmfr_10", ct = "_suggestionActive_1lmfr_38", V = {
1556
+ Container: it,
1557
+ Suggestions: at,
1558
+ suggestionActive: ct
1559
+ }, lt = [
1560
+ {
1561
+ markup: ve,
1562
+ overlay: {
1563
+ trigger: me,
1564
+ data: []
1565
+ }
1566
+ }
1567
+ ], ut = ({ props: t, children: e }) => {
1568
+ const n = dt(t), [s] = A(() => B.create(n));
1569
+ return x(() => {
1570
+ s.props = n;
1571
+ }), /* @__PURE__ */ m(P.Provider, { value: s, children: e });
1572
+ };
1573
+ function dt(t) {
1574
+ const e = ge(V.Container, t.className, t.slotProps?.container?.className), n = pe(t.style, t.slotProps?.container?.style);
1575
+ return {
1576
+ value: t.value,
1577
+ defaultValue: t.defaultValue,
1578
+ onChange: t.onChange,
1579
+ readOnly: t.readOnly,
1580
+ options: t.options ?? lt,
1581
+ showOverlayOn: t.showOverlayOn ?? "change",
1582
+ className: e,
1583
+ style: n,
1584
+ Mark: t.Mark,
1585
+ Overlay: t.Overlay,
1586
+ slots: t.slots,
1587
+ slotProps: t.slotProps
1588
+ };
1589
+ }
1590
+ function ht() {
1591
+ const t = f(), e = f((o) => o.overlayMatch), n = S.getAbsolutePosition(), s = R(() => t.bus.send(p.ClearTrigger), []), r = R(
1592
+ (o) => {
1593
+ const i = {
1594
+ type: "mark",
1595
+ value: o.value,
1596
+ meta: o.meta,
1597
+ content: "",
1598
+ position: { start: e.index, end: e.index + e.span.length },
1599
+ descriptor: {
1600
+ index: 0,
1601
+ // TODO: get correct index
1602
+ markup: e.option.markup
1603
+ },
1604
+ // TODO: fix typing
1605
+ children: [],
1606
+ nested: void 0
1607
+ };
1608
+ t.bus.send(p.Select, { mark: i, match: e }), t.bus.send(p.ClearTrigger);
1609
+ },
1610
+ [e]
1611
+ );
1612
+ return { match: e, style: n, select: r, close: s, ref: { current: t.refs.overlay } };
1613
+ }
1614
+ const ft = () => {
1615
+ const { match: t, select: e, style: n, ref: s } = ht(), [r, o] = A(NaN), i = t.option.overlay?.data || [], a = ue(
1616
+ () => i.filter((l) => l.toLowerCase().indexOf(t.value.toLowerCase()) > -1),
1617
+ [t.value, i]
1618
+ ), c = a.length;
1619
+ return C(
1620
+ k.UP,
1621
+ (l) => {
1622
+ l.preventDefault(), o((h) => isNaN(h) ? 0 : (c + (h - 1) % c) % c);
1623
+ },
1624
+ [c]
1625
+ ), C(
1626
+ k.DOWN,
1627
+ (l) => {
1628
+ l.preventDefault(), o((h) => isNaN(h) ? 0 : (h + 1) % c);
1629
+ },
1630
+ [c]
1631
+ ), C(
1632
+ k.ENTER,
1633
+ (l) => {
1634
+ l.preventDefault();
1635
+ const h = a[r];
1636
+ e({ value: h, meta: r.toString() });
1637
+ },
1638
+ [a, r]
1639
+ ), a.length ? /* @__PURE__ */ m("ul", { ref: s, className: V.Suggestions, style: n, children: a.map((l, h) => {
1640
+ const u = h === r ? V.suggestionActive : void 0;
1641
+ return /* @__PURE__ */ m(
1642
+ "li",
1643
+ {
1644
+ ref: (d) => u && d?.scrollIntoView(!1),
1645
+ className: u,
1646
+ onClick: (d) => e({ value: l, meta: h.toString() }),
1647
+ children: l
1648
+ },
1649
+ l
1650
+ );
1651
+ }) }) : null;
1652
+ }, se = W(() => {
1653
+ const t = f(), e = f((o) => o.overlayMatch), n = f((o) => o.overlayMatch ? o.key.get(o.overlayMatch.option) : void 0), [s, r] = ee("overlay", e?.option, void 0, ft);
1654
+ if (x(() => {
1655
+ t.nodes.input.target = t.nodes.focus.target;
1656
+ }, [n]), n) return /* @__PURE__ */ m(s, { ...r ?? {} }, n);
1657
+ });
1658
+ se.displayName = "Whisper";
1659
+ const gt = (t, e) => /* @__PURE__ */ ie(ut, { props: t, children: [
1660
+ /* @__PURE__ */ m(te, {}),
1661
+ /* @__PURE__ */ m(se, {}),
1662
+ /* @__PURE__ */ m(ot, { inRef: e })
1663
+ ] }), St = de(gt);
1664
+ function F(t, e, n = 0, s) {
1665
+ for (const r of t) {
1666
+ if (r === e) return { depth: n, parent: s };
1667
+ if (r.type === "mark") {
1668
+ const o = F(r.children, e, n + 1, r);
1669
+ if (o) return o;
1670
+ }
1671
+ }
1672
+ }
1673
+ class pt {
1674
+ ref;
1675
+ #t;
1676
+ #e;
1677
+ readOnly;
1678
+ constructor(e) {
1679
+ this.ref = e.ref, this.#t = e.store, this.#e = e.token;
1680
+ }
1681
+ // ─── Data Properties ─────────────────────────────────────────────────────────
1682
+ /** Displayed text of the mark */
1683
+ get content() {
1684
+ return this.#e.content;
1685
+ }
1686
+ set content(e) {
1687
+ this.#e.content = e, this.#n();
1688
+ }
1689
+ /** Data value associated with the mark */
1690
+ get value() {
1691
+ return this.#e.value;
1692
+ }
1693
+ set value(e) {
1694
+ this.#e.value = e ?? "", this.#n();
1695
+ }
1696
+ /** Optional metadata for the mark */
1697
+ get meta() {
1698
+ return this.#e.meta;
1699
+ }
1700
+ set meta(e) {
1701
+ this.#e.meta = e, this.#n();
1702
+ }
1703
+ // ─── Navigation Properties ───────────────────────────────────────────────────
1704
+ /** Nesting depth (0 for root-level marks) */
1705
+ get depth() {
1706
+ return F(this.#t.tokens, this.#e).depth;
1707
+ }
1708
+ /** Whether this mark has nested children */
1709
+ get hasChildren() {
1710
+ return this.#e.children.length > 0;
1711
+ }
1712
+ /** Parent mark token (undefined for root-level marks) */
1713
+ get parent() {
1714
+ return F(this.#t.tokens, this.#e)?.parent;
1715
+ }
1716
+ /** Child tokens of this mark */
1717
+ get tokens() {
1718
+ return this.#e.children;
1719
+ }
1720
+ // ─── Mutation Methods ────────────────────────────────────────────────────────
1721
+ /** Update multiple properties in a single operation */
1722
+ change = (e) => {
1723
+ this.#e.content = e.content, this.#e.value = e.value ?? "", e.meta !== void 0 && (this.#e.meta = e.meta), this.#n();
1724
+ };
1725
+ /** Delete this mark from the editor */
1726
+ remove = () => this.#t.bus.send(p.Delete, { token: this.#e });
1727
+ // ─── Private ─────────────────────────────────────────────────────────────────
1728
+ #n() {
1729
+ this.#t.bus.send(p.Change, { node: this.#e });
1730
+ }
1731
+ }
1732
+ const Ct = (t = {}) => {
1733
+ const e = f(), n = H(), s = I();
1734
+ if (n.type !== "mark")
1735
+ throw new Error("useMark can only be used with mark tokens");
1736
+ const [r] = A(() => new pt({ ref: s, store: e, token: n }));
1737
+ mt(s, t, n);
1738
+ const o = f((i) => i.props.readOnly);
1739
+ return x(() => {
1740
+ r.readOnly = o;
1741
+ }, [o]), r;
1742
+ };
1743
+ function mt(t, e, n) {
1744
+ x(() => {
1745
+ t.current && !e.controlled && (t.current.textContent = n.content);
1746
+ }, []);
1747
+ }
1748
+ export {
1749
+ St as MarkedInput,
1750
+ $ as annotate,
1751
+ kt as denote,
1752
+ v as useListener,
1753
+ Ct as useMark,
1754
+ ht as useOverlay
1755
+ };