@rcarls/rc-textarea 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.
Files changed (28) hide show
  1. package/README.md +1311 -0
  2. package/dist/custom-elements.json +2103 -0
  3. package/dist/demo.css +85 -0
  4. package/dist/demo.js +40 -0
  5. package/dist/line-actions-controller-BsM6DJ0b.js +2334 -0
  6. package/dist/line-actions-controller-BsM6DJ0b.js.map +1 -0
  7. package/dist/rc-textarea-define.js +10 -0
  8. package/dist/rc-textarea-define.js.map +1 -0
  9. package/dist/rc-textarea.js +8 -0
  10. package/dist/rc-textarea.js.map +1 -0
  11. package/dist/types/packages/rc-textarea/src/blots.d.ts +39 -0
  12. package/dist/types/packages/rc-textarea/src/decoration.d.ts +65 -0
  13. package/dist/types/packages/rc-textarea/src/decoration.test.d.ts +1 -0
  14. package/dist/types/packages/rc-textarea/src/define.d.ts +1 -0
  15. package/dist/types/packages/rc-textarea/src/document.d.ts +19 -0
  16. package/dist/types/packages/rc-textarea/src/index.d.ts +7 -0
  17. package/dist/types/packages/rc-textarea/src/line-actions-controller.d.ts +91 -0
  18. package/dist/types/packages/rc-textarea/src/line-decorator.d.ts +57 -0
  19. package/dist/types/packages/rc-textarea/src/line-decorator.test.d.ts +1 -0
  20. package/dist/types/packages/rc-textarea/src/pattern-matcher.d.ts +23 -0
  21. package/dist/types/packages/rc-textarea/src/pattern-matcher.test.d.ts +1 -0
  22. package/dist/types/packages/rc-textarea/src/rc-textarea.d.ts +194 -0
  23. package/dist/types/packages/rc-textarea/src/rc-textarea.styles.d.ts +1 -0
  24. package/dist/types/packages/rc-textarea/src/rc-textarea.test.d.ts +0 -0
  25. package/dist/types/packages/rc-textarea/src/selection.d.ts +39 -0
  26. package/dist/types/packages/rc-textarea/src/test-helpers.d.ts +18 -0
  27. package/dist/types/packages/rc-textarea/src/types.d.ts +394 -0
  28. package/package.json +68 -0
@@ -0,0 +1,2334 @@
1
+ import { css as St, LitElement as tt, html as Lt } from "lit";
2
+ import { property as b } from "lit/decorators.js";
3
+ const Tt = St`
4
+ :host {
5
+ display: block;
6
+ box-sizing: border-box;
7
+ color-scheme: inherit;
8
+ }
9
+
10
+ :host([hidden]) {
11
+ display: none;
12
+ }
13
+
14
+ /* ── Root layout ──────────────────────────────────────────────────────── */
15
+
16
+ #root {
17
+ display: flex;
18
+ align-items: stretch;
19
+ border: var(--rc-textarea-border, 1px solid ButtonBorder);
20
+ border-radius: var(--rc-textarea-border-radius, 2px);
21
+ background: var(--rc-textarea-background, Field);
22
+ color: var(--rc-textarea-color, var(--rc-text, FieldText));
23
+ overflow: hidden;
24
+ min-height: var(--_rc-textarea-min-height, auto);
25
+ }
26
+
27
+ /* ── Gutter ───────────────────────────────────────────────────────────── */
28
+
29
+ #gutter {
30
+ display: none;
31
+ flex-shrink: 0;
32
+ background: var(--rc-textarea-gutter-bg, Canvas);
33
+ color: var(--rc-textarea-gutter-color, GrayText);
34
+ border-right: var(--rc-textarea-gutter-border, 1px solid ButtonBorder);
35
+ overflow: hidden;
36
+ user-select: none;
37
+ }
38
+
39
+ :host([line-numbers]) #gutter,
40
+ :host([list-numbers]) #gutter,
41
+ :host([gutter]) #gutter {
42
+ display: block;
43
+ }
44
+
45
+ #gutter-cells {
46
+ padding: var(--rc-textarea-padding, 0.5em);
47
+ padding-inline-end: var(--rc-textarea-gutter-padding-inline-end, 0.75em);
48
+ font-family: var(--rc-textarea-font-family, monospace);
49
+ font-size: var(--rc-textarea-font-size, 1em);
50
+ line-height: var(--rc-textarea-line-height, 1.5);
51
+ text-align: right;
52
+ min-width: 2.5ch;
53
+ }
54
+
55
+ .gutter-cell {
56
+ display: block;
57
+ white-space: pre;
58
+ }
59
+
60
+ .gutter-cell--active {
61
+ color: var(--rc-textarea-color, var(--rc-text, FieldText));
62
+ }
63
+
64
+ /* ── Editor area ──────────────────────────────────────────────────────── */
65
+
66
+ #editor-area {
67
+ position: relative;
68
+ flex: 1;
69
+ min-width: 0;
70
+ overflow: hidden;
71
+ }
72
+
73
+ #editor {
74
+ position: relative;
75
+ z-index: 1;
76
+ width: 100%;
77
+ min-height: 100%;
78
+ box-sizing: border-box;
79
+ padding: var(--rc-textarea-padding, 0.5em);
80
+ font-family: var(--rc-textarea-font-family, monospace);
81
+ font-size: var(--rc-textarea-font-size, 1em);
82
+ line-height: var(--rc-textarea-line-height, 1.5);
83
+ color: var(--rc-textarea-color, var(--rc-text, FieldText));
84
+ caret-color: var(
85
+ --rc-textarea-caret-color,
86
+ var(--rc-textarea-color, FieldText)
87
+ );
88
+ background: transparent;
89
+ outline: none;
90
+ overflow: auto;
91
+ resize: none;
92
+ white-space: pre;
93
+ word-break: normal;
94
+ overflow-wrap: normal;
95
+ tab-size: 4;
96
+ word-break: normal;
97
+ /* Prevent contenteditable from injecting <div> wrappers on Enter in some browsers */
98
+ -webkit-user-modify: read-write-plaintext-only;
99
+ }
100
+
101
+ :host([word-wrap]) #editor {
102
+ white-space: pre-wrap;
103
+ overflow-wrap: break-word;
104
+ word-break: normal;
105
+ }
106
+
107
+ :host([auto-grow]) #editor {
108
+ overflow: visible;
109
+ height: auto;
110
+ }
111
+
112
+ :host([auto-grow]) #root {
113
+ height: auto;
114
+ }
115
+
116
+ :host([read-only]) #root {
117
+ border: none;
118
+ background: transparent;
119
+ border-radius: 0;
120
+ }
121
+
122
+ :host([read-only]) #editor {
123
+ cursor: default;
124
+ padding: 0;
125
+ -webkit-user-modify: read-only;
126
+ }
127
+
128
+ /* Focus ring on the root when editor is focused */
129
+ #root:has(#editor:focus) {
130
+ outline: var(--rc-textarea-focus-outline, 2px solid Highlight);
131
+ outline-offset: -1px;
132
+ }
133
+
134
+ /* ── Slot (hidden lightDOM textarea) ──────────────────────────────────── */
135
+
136
+ ::slotted(textarea) {
137
+ /* Visually hidden but accessible to form submission.
138
+ Inline styles applied via JS take precedence and are more reliable,
139
+ but this provides a baseline in case of timing issues. */
140
+ position: absolute !important;
141
+ width: 1px !important;
142
+ height: 1px !important;
143
+ padding: 0 !important;
144
+ margin: -1px !important;
145
+ overflow: hidden !important;
146
+ clip: rect(0, 0, 0, 0) !important;
147
+ border: 0 !important;
148
+ opacity: 0 !important;
149
+ pointer-events: none !important;
150
+ }
151
+
152
+ /* ── Line structure ───────────────────────────────────────────────────── */
153
+
154
+ .v2-line {
155
+ position: relative;
156
+ display: block;
157
+ }
158
+
159
+ /* Active line highlight — opt-in via CSS custom property. */
160
+ .v2-line--active {
161
+ background: var(--rc-textarea-active-line-bg, transparent);
162
+ }
163
+
164
+ /* Error-lens style end-of-line message via ::after pseudo-element.
165
+ content: attr(data-message) is set when V2Document assigns data-message.
166
+ Using ::after keeps the annotation completely outside the DOM selection
167
+ and clipboard path — no user-select tricks needed. */
168
+ .v2-line[data-message]::after {
169
+ content: attr(data-message);
170
+ display: inline;
171
+ margin-left: 4ch;
172
+ white-space: nowrap;
173
+ pointer-events: none;
174
+ font-size: 0.875em;
175
+ opacity: 0.8;
176
+ font-style: italic;
177
+ }
178
+
179
+ /* ── Inline decoration spans ──────────────────────────────────────────── */
180
+
181
+ .v2-mark {
182
+ /* Base class; formatting applied via inline style by V2InlineBlot */
183
+ border-radius: 2px;
184
+ }
185
+
186
+ /* ── Widget spans ─────────────────────────────────────────────────────── */
187
+
188
+ .v2-widget {
189
+ display: inline-block;
190
+ user-select: none;
191
+ cursor: default;
192
+ vertical-align: middle;
193
+ }
194
+
195
+ /* ── Scrollbar sync between editor and gutter ─────────────────────────── */
196
+ /* Gutter doesn't scroll independently; editor scroll is handled in JS */
197
+ `;
198
+ var f = /* @__PURE__ */ ((n) => (n[n.TYPE = 3] = "TYPE", n[n.LEVEL = 12] = "LEVEL", n[n.ATTRIBUTE = 13] = "ATTRIBUTE", n[n.BLOT = 14] = "BLOT", n[n.INLINE = 7] = "INLINE", n[n.BLOCK = 11] = "BLOCK", n[n.BLOCK_BLOT = 10] = "BLOCK_BLOT", n[n.INLINE_BLOT = 6] = "INLINE_BLOT", n[n.BLOCK_ATTRIBUTE = 9] = "BLOCK_ATTRIBUTE", n[n.INLINE_ATTRIBUTE = 5] = "INLINE_ATTRIBUTE", n[n.ANY = 15] = "ANY", n))(f || {});
199
+ class T {
200
+ constructor(t, e, s = {}) {
201
+ this.attrName = t, this.keyName = e;
202
+ const i = f.TYPE & f.ATTRIBUTE;
203
+ this.scope = s.scope != null ? (
204
+ // Ignore type bits, force attribute bit
205
+ s.scope & f.LEVEL | i
206
+ ) : f.ATTRIBUTE, s.whitelist != null && (this.whitelist = s.whitelist);
207
+ }
208
+ static keys(t) {
209
+ return Array.from(t.attributes).map((e) => e.name);
210
+ }
211
+ add(t, e) {
212
+ return this.canAdd(t, e) ? (t.setAttribute(this.keyName, e), !0) : !1;
213
+ }
214
+ canAdd(t, e) {
215
+ return this.whitelist == null ? !0 : typeof e == "string" ? this.whitelist.indexOf(e.replace(/["']/g, "")) > -1 : this.whitelist.indexOf(e) > -1;
216
+ }
217
+ remove(t) {
218
+ t.removeAttribute(this.keyName);
219
+ }
220
+ value(t) {
221
+ const e = t.getAttribute(this.keyName);
222
+ return this.canAdd(t, e) && e ? e : "";
223
+ }
224
+ }
225
+ class S extends Error {
226
+ constructor(t) {
227
+ t = "[Parchment] " + t, super(t), this.message = t, this.name = this.constructor.name;
228
+ }
229
+ }
230
+ const ht = class j {
231
+ constructor() {
232
+ this.attributes = {}, this.classes = {}, this.tags = {}, this.types = {};
233
+ }
234
+ static find(t, e = !1) {
235
+ if (t == null)
236
+ return null;
237
+ if (this.blots.has(t))
238
+ return this.blots.get(t) || null;
239
+ if (e) {
240
+ let s = null;
241
+ try {
242
+ s = t.parentNode;
243
+ } catch {
244
+ return null;
245
+ }
246
+ return this.find(s, e);
247
+ }
248
+ return null;
249
+ }
250
+ create(t, e, s) {
251
+ const i = this.query(e);
252
+ if (i == null)
253
+ throw new S(`Unable to create ${e} blot`);
254
+ const r = i, o = (
255
+ // @ts-expect-error Fix me later
256
+ e instanceof Node || e.nodeType === Node.TEXT_NODE ? e : r.create(s)
257
+ ), a = new r(t, o, s);
258
+ return j.blots.set(a.domNode, a), a;
259
+ }
260
+ find(t, e = !1) {
261
+ return j.find(t, e);
262
+ }
263
+ query(t, e = f.ANY) {
264
+ let s;
265
+ return typeof t == "string" ? s = this.types[t] || this.attributes[t] : t instanceof Text || t.nodeType === Node.TEXT_NODE ? s = this.types.text : typeof t == "number" ? t & f.LEVEL & f.BLOCK ? s = this.types.block : t & f.LEVEL & f.INLINE && (s = this.types.inline) : t instanceof Element && ((t.getAttribute("class") || "").split(/\s+/).some((i) => (s = this.classes[i], !!s)), s = s || this.tags[t.tagName]), s == null ? null : "scope" in s && e & f.LEVEL & s.scope && e & f.TYPE & s.scope ? s : null;
266
+ }
267
+ register(...t) {
268
+ return t.map((e) => {
269
+ const s = "blotName" in e, i = "attrName" in e;
270
+ if (!s && !i)
271
+ throw new S("Invalid definition");
272
+ if (s && e.blotName === "abstract")
273
+ throw new S("Cannot register abstract class");
274
+ const r = s ? e.blotName : i ? e.attrName : void 0;
275
+ return this.types[r] = e, i ? typeof e.keyName == "string" && (this.attributes[e.keyName] = e) : s && (e.className && (this.classes[e.className] = e), e.tagName && (Array.isArray(e.tagName) ? e.tagName = e.tagName.map((o) => o.toUpperCase()) : e.tagName = e.tagName.toUpperCase(), (Array.isArray(e.tagName) ? e.tagName : [e.tagName]).forEach((o) => {
276
+ (this.tags[o] == null || e.className == null) && (this.tags[o] = e);
277
+ }))), e;
278
+ });
279
+ }
280
+ };
281
+ ht.blots = /* @__PURE__ */ new WeakMap();
282
+ let z = ht;
283
+ function et(n, t) {
284
+ return (n.getAttribute("class") || "").split(/\s+/).filter((e) => e.indexOf(`${t}-`) === 0);
285
+ }
286
+ class kt extends T {
287
+ static keys(t) {
288
+ return (t.getAttribute("class") || "").split(/\s+/).map((e) => e.split("-").slice(0, -1).join("-"));
289
+ }
290
+ add(t, e) {
291
+ return this.canAdd(t, e) ? (this.remove(t), t.classList.add(`${this.keyName}-${e}`), !0) : !1;
292
+ }
293
+ remove(t) {
294
+ et(t, this.keyName).forEach((e) => {
295
+ t.classList.remove(e);
296
+ }), t.classList.length === 0 && t.removeAttribute("class");
297
+ }
298
+ value(t) {
299
+ const e = (et(t, this.keyName)[0] || "").slice(this.keyName.length + 1);
300
+ return this.canAdd(t, e) ? e : "";
301
+ }
302
+ }
303
+ const Bt = kt;
304
+ function F(n) {
305
+ const t = n.split("-"), e = t.slice(1).map((s) => s[0].toUpperCase() + s.slice(1)).join("");
306
+ return t[0] + e;
307
+ }
308
+ class Dt extends T {
309
+ static keys(t) {
310
+ return (t.getAttribute("style") || "").split(";").map((e) => e.split(":")[0].trim());
311
+ }
312
+ add(t, e) {
313
+ return this.canAdd(t, e) ? (t.style[F(this.keyName)] = e, !0) : !1;
314
+ }
315
+ remove(t) {
316
+ t.style[F(this.keyName)] = "", t.getAttribute("style") || t.removeAttribute("style");
317
+ }
318
+ value(t) {
319
+ const e = t.style[F(this.keyName)];
320
+ return this.canAdd(t, e) ? e : "";
321
+ }
322
+ }
323
+ const It = Dt;
324
+ class Rt {
325
+ constructor(t) {
326
+ this.attributes = {}, this.domNode = t, this.build();
327
+ }
328
+ attribute(t, e) {
329
+ e ? t.add(this.domNode, e) && (t.value(this.domNode) != null ? this.attributes[t.attrName] = t : delete this.attributes[t.attrName]) : (t.remove(this.domNode), delete this.attributes[t.attrName]);
330
+ }
331
+ build() {
332
+ this.attributes = {};
333
+ const t = z.find(this.domNode);
334
+ if (t == null)
335
+ return;
336
+ const e = T.keys(this.domNode), s = Bt.keys(this.domNode), i = It.keys(this.domNode);
337
+ e.concat(s).concat(i).forEach((r) => {
338
+ const o = t.scroll.query(r, f.ATTRIBUTE);
339
+ o instanceof T && (this.attributes[o.attrName] = o);
340
+ });
341
+ }
342
+ copy(t) {
343
+ Object.keys(this.attributes).forEach((e) => {
344
+ const s = this.attributes[e].value(this.domNode);
345
+ t.format(e, s);
346
+ });
347
+ }
348
+ move(t) {
349
+ this.copy(t), Object.keys(this.attributes).forEach((e) => {
350
+ this.attributes[e].remove(this.domNode);
351
+ }), this.attributes = {};
352
+ }
353
+ values() {
354
+ return Object.keys(this.attributes).reduce(
355
+ (t, e) => (t[e] = this.attributes[e].value(this.domNode), t),
356
+ {}
357
+ );
358
+ }
359
+ }
360
+ const ut = Rt, dt = class {
361
+ constructor(t, e) {
362
+ this.scroll = t, this.domNode = e, z.blots.set(e, this), this.prev = null, this.next = null;
363
+ }
364
+ static create(t) {
365
+ if (this.tagName == null)
366
+ throw new S("Blot definition missing tagName");
367
+ let e, s;
368
+ return Array.isArray(this.tagName) ? (typeof t == "string" ? (s = t.toUpperCase(), parseInt(s, 10).toString() === s && (s = parseInt(s, 10))) : typeof t == "number" && (s = t), typeof s == "number" ? e = document.createElement(this.tagName[s - 1]) : s && this.tagName.indexOf(s) > -1 ? e = document.createElement(s) : e = document.createElement(this.tagName[0])) : e = document.createElement(this.tagName), this.className && e.classList.add(this.className), e;
369
+ }
370
+ // Hack for accessing inherited static methods
371
+ get statics() {
372
+ return this.constructor;
373
+ }
374
+ attach() {
375
+ }
376
+ clone() {
377
+ const t = this.domNode.cloneNode(!1);
378
+ return this.scroll.create(t);
379
+ }
380
+ detach() {
381
+ this.parent != null && this.parent.removeChild(this), z.blots.delete(this.domNode);
382
+ }
383
+ deleteAt(t, e) {
384
+ this.isolate(t, e).remove();
385
+ }
386
+ formatAt(t, e, s, i) {
387
+ const r = this.isolate(t, e);
388
+ if (this.scroll.query(s, f.BLOT) != null && i)
389
+ r.wrap(s, i);
390
+ else if (this.scroll.query(s, f.ATTRIBUTE) != null) {
391
+ const o = this.scroll.create(this.statics.scope);
392
+ r.wrap(o), o.format(s, i);
393
+ }
394
+ }
395
+ insertAt(t, e, s) {
396
+ const i = s == null ? this.scroll.create("text", e) : this.scroll.create(e, s), r = this.split(t);
397
+ this.parent.insertBefore(i, r || void 0);
398
+ }
399
+ isolate(t, e) {
400
+ const s = this.split(t);
401
+ if (s == null)
402
+ throw new Error("Attempt to isolate at end");
403
+ return s.split(e), s;
404
+ }
405
+ length() {
406
+ return 1;
407
+ }
408
+ offset(t = this.parent) {
409
+ return this.parent == null || this === t ? 0 : this.parent.children.offset(this) + this.parent.offset(t);
410
+ }
411
+ optimize(t) {
412
+ this.statics.requiredContainer && !(this.parent instanceof this.statics.requiredContainer) && this.wrap(this.statics.requiredContainer.blotName);
413
+ }
414
+ remove() {
415
+ this.domNode.parentNode != null && this.domNode.parentNode.removeChild(this.domNode), this.detach();
416
+ }
417
+ replaceWith(t, e) {
418
+ const s = typeof t == "string" ? this.scroll.create(t, e) : t;
419
+ return this.parent != null && (this.parent.insertBefore(s, this.next || void 0), this.remove()), s;
420
+ }
421
+ split(t, e) {
422
+ return t === 0 ? this : this.next;
423
+ }
424
+ update(t, e) {
425
+ }
426
+ wrap(t, e) {
427
+ const s = typeof t == "string" ? this.scroll.create(t, e) : t;
428
+ if (this.parent != null && this.parent.insertBefore(s, this.next || void 0), typeof s.appendChild != "function")
429
+ throw new S(`Cannot wrap ${t}`);
430
+ return s.appendChild(this), s;
431
+ }
432
+ };
433
+ dt.blotName = "abstract";
434
+ let ft = dt;
435
+ const pt = class extends ft {
436
+ /**
437
+ * Returns the value represented by domNode if it is this Blot's type
438
+ * No checking that domNode can represent this Blot type is required so
439
+ * applications needing it should check externally before calling.
440
+ */
441
+ static value(t) {
442
+ return !0;
443
+ }
444
+ /**
445
+ * Given location represented by node and offset from DOM Selection Range,
446
+ * return index to that location.
447
+ */
448
+ index(t, e) {
449
+ return this.domNode === t || this.domNode.compareDocumentPosition(t) & Node.DOCUMENT_POSITION_CONTAINED_BY ? Math.min(e, 1) : -1;
450
+ }
451
+ /**
452
+ * Given index to location within blot, return node and offset representing
453
+ * that location, consumable by DOM Selection Range
454
+ */
455
+ position(t, e) {
456
+ let s = Array.from(this.parent.domNode.childNodes).indexOf(this.domNode);
457
+ return t > 0 && (s += 1), [this.parent.domNode, s];
458
+ }
459
+ /**
460
+ * Return value represented by this blot
461
+ * Should not change without interaction from API or
462
+ * user change detectable by update()
463
+ */
464
+ value() {
465
+ return {
466
+ [this.statics.blotName]: this.statics.value(this.domNode) || !0
467
+ };
468
+ }
469
+ };
470
+ pt.scope = f.INLINE_BLOT;
471
+ let Pt = pt;
472
+ const W = Pt;
473
+ class Mt {
474
+ constructor() {
475
+ this.head = null, this.tail = null, this.length = 0;
476
+ }
477
+ append(...t) {
478
+ if (this.insertBefore(t[0], null), t.length > 1) {
479
+ const e = t.slice(1);
480
+ this.append(...e);
481
+ }
482
+ }
483
+ at(t) {
484
+ const e = this.iterator();
485
+ let s = e();
486
+ for (; s && t > 0; )
487
+ t -= 1, s = e();
488
+ return s;
489
+ }
490
+ contains(t) {
491
+ const e = this.iterator();
492
+ let s = e();
493
+ for (; s; ) {
494
+ if (s === t)
495
+ return !0;
496
+ s = e();
497
+ }
498
+ return !1;
499
+ }
500
+ indexOf(t) {
501
+ const e = this.iterator();
502
+ let s = e(), i = 0;
503
+ for (; s; ) {
504
+ if (s === t)
505
+ return i;
506
+ i += 1, s = e();
507
+ }
508
+ return -1;
509
+ }
510
+ insertBefore(t, e) {
511
+ t != null && (this.remove(t), t.next = e, e != null ? (t.prev = e.prev, e.prev != null && (e.prev.next = t), e.prev = t, e === this.head && (this.head = t)) : this.tail != null ? (this.tail.next = t, t.prev = this.tail, this.tail = t) : (t.prev = null, this.head = this.tail = t), this.length += 1);
512
+ }
513
+ offset(t) {
514
+ let e = 0, s = this.head;
515
+ for (; s != null; ) {
516
+ if (s === t)
517
+ return e;
518
+ e += s.length(), s = s.next;
519
+ }
520
+ return -1;
521
+ }
522
+ remove(t) {
523
+ this.contains(t) && (t.prev != null && (t.prev.next = t.next), t.next != null && (t.next.prev = t.prev), t === this.head && (this.head = t.next), t === this.tail && (this.tail = t.prev), this.length -= 1);
524
+ }
525
+ iterator(t = this.head) {
526
+ return () => {
527
+ const e = t;
528
+ return t != null && (t = t.next), e;
529
+ };
530
+ }
531
+ find(t, e = !1) {
532
+ const s = this.iterator();
533
+ let i = s();
534
+ for (; i; ) {
535
+ const r = i.length();
536
+ if (t < r || e && t === r && (i.next == null || i.next.length() !== 0))
537
+ return [i, t];
538
+ t -= r, i = s();
539
+ }
540
+ return [null, 0];
541
+ }
542
+ forEach(t) {
543
+ const e = this.iterator();
544
+ let s = e();
545
+ for (; s; )
546
+ t(s), s = e();
547
+ }
548
+ forEachAt(t, e, s) {
549
+ if (e <= 0)
550
+ return;
551
+ const [i, r] = this.find(t);
552
+ let o = t - r;
553
+ const a = this.iterator(i);
554
+ let l = a();
555
+ for (; l && o < t + e; ) {
556
+ const h = l.length();
557
+ t > o ? s(
558
+ l,
559
+ t - o,
560
+ Math.min(e, o + h - t)
561
+ ) : s(l, 0, Math.min(h, t + e - o)), o += h, l = a();
562
+ }
563
+ }
564
+ map(t) {
565
+ return this.reduce((e, s) => (e.push(t(s)), e), []);
566
+ }
567
+ reduce(t, e) {
568
+ const s = this.iterator();
569
+ let i = s();
570
+ for (; i; )
571
+ e = t(e, i), i = s();
572
+ return e;
573
+ }
574
+ }
575
+ function st(n, t) {
576
+ const e = t.find(n);
577
+ if (e)
578
+ return e;
579
+ try {
580
+ return t.create(n);
581
+ } catch {
582
+ const s = t.create(f.INLINE);
583
+ return Array.from(n.childNodes).forEach((i) => {
584
+ s.domNode.appendChild(i);
585
+ }), n.parentNode && n.parentNode.replaceChild(s.domNode, n), s.attach(), s;
586
+ }
587
+ }
588
+ const mt = class N extends ft {
589
+ constructor(t, e) {
590
+ super(t, e), this.uiNode = null, this.build();
591
+ }
592
+ appendChild(t) {
593
+ this.insertBefore(t);
594
+ }
595
+ attach() {
596
+ super.attach(), this.children.forEach((t) => {
597
+ t.attach();
598
+ });
599
+ }
600
+ attachUI(t) {
601
+ this.uiNode != null && this.uiNode.remove(), this.uiNode = t, N.uiClass && this.uiNode.classList.add(N.uiClass), this.uiNode.setAttribute("contenteditable", "false"), this.domNode.insertBefore(this.uiNode, this.domNode.firstChild);
602
+ }
603
+ /**
604
+ * Called during construction, should fill its own children LinkedList.
605
+ */
606
+ build() {
607
+ this.children = new Mt(), Array.from(this.domNode.childNodes).filter((t) => t !== this.uiNode).reverse().forEach((t) => {
608
+ try {
609
+ const e = st(t, this.scroll);
610
+ this.insertBefore(e, this.children.head || void 0);
611
+ } catch (e) {
612
+ if (e instanceof S)
613
+ return;
614
+ throw e;
615
+ }
616
+ });
617
+ }
618
+ deleteAt(t, e) {
619
+ if (t === 0 && e === this.length())
620
+ return this.remove();
621
+ this.children.forEachAt(t, e, (s, i, r) => {
622
+ s.deleteAt(i, r);
623
+ });
624
+ }
625
+ descendant(t, e = 0) {
626
+ const [s, i] = this.children.find(e);
627
+ return t.blotName == null && t(s) || t.blotName != null && s instanceof t ? [s, i] : s instanceof N ? s.descendant(t, i) : [null, -1];
628
+ }
629
+ descendants(t, e = 0, s = Number.MAX_VALUE) {
630
+ let i = [], r = s;
631
+ return this.children.forEachAt(
632
+ e,
633
+ s,
634
+ (o, a, l) => {
635
+ (t.blotName == null && t(o) || t.blotName != null && o instanceof t) && i.push(o), o instanceof N && (i = i.concat(
636
+ o.descendants(t, a, r)
637
+ )), r -= l;
638
+ }
639
+ ), i;
640
+ }
641
+ detach() {
642
+ this.children.forEach((t) => {
643
+ t.detach();
644
+ }), super.detach();
645
+ }
646
+ enforceAllowedChildren() {
647
+ let t = !1;
648
+ this.children.forEach((e) => {
649
+ t || this.statics.allowedChildren.some(
650
+ (s) => e instanceof s
651
+ ) || (e.statics.scope === f.BLOCK_BLOT ? (e.next != null && this.splitAfter(e), e.prev != null && this.splitAfter(e.prev), e.parent.unwrap(), t = !0) : e instanceof N ? e.unwrap() : e.remove());
652
+ });
653
+ }
654
+ formatAt(t, e, s, i) {
655
+ this.children.forEachAt(t, e, (r, o, a) => {
656
+ r.formatAt(o, a, s, i);
657
+ });
658
+ }
659
+ insertAt(t, e, s) {
660
+ const [i, r] = this.children.find(t);
661
+ if (i)
662
+ i.insertAt(r, e, s);
663
+ else {
664
+ const o = s == null ? this.scroll.create("text", e) : this.scroll.create(e, s);
665
+ this.appendChild(o);
666
+ }
667
+ }
668
+ insertBefore(t, e) {
669
+ t.parent != null && t.parent.children.remove(t);
670
+ let s = null;
671
+ this.children.insertBefore(t, e || null), t.parent = this, e != null && (s = e.domNode), (this.domNode.parentNode !== t.domNode || this.domNode.nextSibling !== s) && this.domNode.insertBefore(t.domNode, s), t.attach();
672
+ }
673
+ length() {
674
+ return this.children.reduce((t, e) => t + e.length(), 0);
675
+ }
676
+ moveChildren(t, e) {
677
+ this.children.forEach((s) => {
678
+ t.insertBefore(s, e);
679
+ });
680
+ }
681
+ optimize(t) {
682
+ if (super.optimize(t), this.enforceAllowedChildren(), this.uiNode != null && this.uiNode !== this.domNode.firstChild && this.domNode.insertBefore(this.uiNode, this.domNode.firstChild), this.children.length === 0)
683
+ if (this.statics.defaultChild != null) {
684
+ const e = this.scroll.create(this.statics.defaultChild.blotName);
685
+ this.appendChild(e);
686
+ } else
687
+ this.remove();
688
+ }
689
+ path(t, e = !1) {
690
+ const [s, i] = this.children.find(t, e), r = [[this, t]];
691
+ return s instanceof N ? r.concat(s.path(i, e)) : (s != null && r.push([s, i]), r);
692
+ }
693
+ removeChild(t) {
694
+ this.children.remove(t);
695
+ }
696
+ replaceWith(t, e) {
697
+ const s = typeof t == "string" ? this.scroll.create(t, e) : t;
698
+ return s instanceof N && this.moveChildren(s), super.replaceWith(s);
699
+ }
700
+ split(t, e = !1) {
701
+ if (!e) {
702
+ if (t === 0)
703
+ return this;
704
+ if (t === this.length())
705
+ return this.next;
706
+ }
707
+ const s = this.clone();
708
+ return this.parent && this.parent.insertBefore(s, this.next || void 0), this.children.forEachAt(t, this.length(), (i, r, o) => {
709
+ const a = i.split(r, e);
710
+ a != null && s.appendChild(a);
711
+ }), s;
712
+ }
713
+ splitAfter(t) {
714
+ const e = this.clone();
715
+ for (; t.next != null; )
716
+ e.appendChild(t.next);
717
+ return this.parent && this.parent.insertBefore(e, this.next || void 0), e;
718
+ }
719
+ unwrap() {
720
+ this.parent && this.moveChildren(this.parent, this.next || void 0), this.remove();
721
+ }
722
+ update(t, e) {
723
+ const s = [], i = [];
724
+ t.forEach((r) => {
725
+ r.target === this.domNode && r.type === "childList" && (s.push(...r.addedNodes), i.push(...r.removedNodes));
726
+ }), i.forEach((r) => {
727
+ if (r.parentNode != null && // @ts-expect-error Fix me later
728
+ r.tagName !== "IFRAME" && document.body.compareDocumentPosition(r) & Node.DOCUMENT_POSITION_CONTAINED_BY)
729
+ return;
730
+ const o = this.scroll.find(r);
731
+ o != null && (o.domNode.parentNode == null || o.domNode.parentNode === this.domNode) && o.detach();
732
+ }), s.filter((r) => r.parentNode === this.domNode && r !== this.uiNode).sort((r, o) => r === o ? 0 : r.compareDocumentPosition(o) & Node.DOCUMENT_POSITION_FOLLOWING ? 1 : -1).forEach((r) => {
733
+ let o = null;
734
+ r.nextSibling != null && (o = this.scroll.find(r.nextSibling));
735
+ const a = st(r, this.scroll);
736
+ (a.next !== o || a.next == null) && (a.parent != null && a.parent.removeChild(this), this.insertBefore(a, o || void 0));
737
+ }), this.enforceAllowedChildren();
738
+ }
739
+ };
740
+ mt.uiClass = "";
741
+ let zt = mt;
742
+ const L = zt;
743
+ function Ut(n, t) {
744
+ if (Object.keys(n).length !== Object.keys(t).length)
745
+ return !1;
746
+ for (const e in n)
747
+ if (n[e] !== t[e])
748
+ return !1;
749
+ return !0;
750
+ }
751
+ const w = class A extends L {
752
+ static create(t) {
753
+ return super.create(t);
754
+ }
755
+ static formats(t, e) {
756
+ const s = e.query(A.blotName);
757
+ if (!(s != null && t.tagName === s.tagName)) {
758
+ if (typeof this.tagName == "string")
759
+ return !0;
760
+ if (Array.isArray(this.tagName))
761
+ return t.tagName.toLowerCase();
762
+ }
763
+ }
764
+ constructor(t, e) {
765
+ super(t, e), this.attributes = new ut(this.domNode);
766
+ }
767
+ format(t, e) {
768
+ if (t === this.statics.blotName && !e)
769
+ this.children.forEach((s) => {
770
+ s instanceof A || (s = s.wrap(A.blotName, !0)), this.attributes.copy(s);
771
+ }), this.unwrap();
772
+ else {
773
+ const s = this.scroll.query(t, f.INLINE);
774
+ if (s == null)
775
+ return;
776
+ s instanceof T ? this.attributes.attribute(s, e) : e && (t !== this.statics.blotName || this.formats()[t] !== e) && this.replaceWith(t, e);
777
+ }
778
+ }
779
+ formats() {
780
+ const t = this.attributes.values(), e = this.statics.formats(this.domNode, this.scroll);
781
+ return e != null && (t[this.statics.blotName] = e), t;
782
+ }
783
+ formatAt(t, e, s, i) {
784
+ this.formats()[s] != null || this.scroll.query(s, f.ATTRIBUTE) ? this.isolate(t, e).format(s, i) : super.formatAt(t, e, s, i);
785
+ }
786
+ optimize(t) {
787
+ super.optimize(t);
788
+ const e = this.formats();
789
+ if (Object.keys(e).length === 0)
790
+ return this.unwrap();
791
+ const s = this.next;
792
+ s instanceof A && s.prev === this && Ut(e, s.formats()) && (s.moveChildren(this), s.remove());
793
+ }
794
+ replaceWith(t, e) {
795
+ const s = super.replaceWith(t, e);
796
+ return this.attributes.copy(s), s;
797
+ }
798
+ update(t, e) {
799
+ super.update(t, e), t.some(
800
+ (s) => s.target === this.domNode && s.type === "attributes"
801
+ ) && this.attributes.build();
802
+ }
803
+ wrap(t, e) {
804
+ const s = super.wrap(t, e);
805
+ return s instanceof A && this.attributes.move(s), s;
806
+ }
807
+ };
808
+ w.allowedChildren = [w, W], w.blotName = "inline", w.scope = f.INLINE_BLOT, w.tagName = "SPAN";
809
+ let Ht = w;
810
+ const gt = Ht, C = class X extends L {
811
+ static create(t) {
812
+ return super.create(t);
813
+ }
814
+ static formats(t, e) {
815
+ const s = e.query(X.blotName);
816
+ if (!(s != null && t.tagName === s.tagName)) {
817
+ if (typeof this.tagName == "string")
818
+ return !0;
819
+ if (Array.isArray(this.tagName))
820
+ return t.tagName.toLowerCase();
821
+ }
822
+ }
823
+ constructor(t, e) {
824
+ super(t, e), this.attributes = new ut(this.domNode);
825
+ }
826
+ format(t, e) {
827
+ const s = this.scroll.query(t, f.BLOCK);
828
+ s != null && (s instanceof T ? this.attributes.attribute(s, e) : t === this.statics.blotName && !e ? this.replaceWith(X.blotName) : e && (t !== this.statics.blotName || this.formats()[t] !== e) && this.replaceWith(t, e));
829
+ }
830
+ formats() {
831
+ const t = this.attributes.values(), e = this.statics.formats(this.domNode, this.scroll);
832
+ return e != null && (t[this.statics.blotName] = e), t;
833
+ }
834
+ formatAt(t, e, s, i) {
835
+ this.scroll.query(s, f.BLOCK) != null ? this.format(s, i) : super.formatAt(t, e, s, i);
836
+ }
837
+ insertAt(t, e, s) {
838
+ if (s == null || this.scroll.query(e, f.INLINE) != null)
839
+ super.insertAt(t, e, s);
840
+ else {
841
+ const i = this.split(t);
842
+ if (i != null) {
843
+ const r = this.scroll.create(e, s);
844
+ i.parent.insertBefore(r, i);
845
+ } else
846
+ throw new Error("Attempt to insertAt after block boundaries");
847
+ }
848
+ }
849
+ replaceWith(t, e) {
850
+ const s = super.replaceWith(t, e);
851
+ return this.attributes.copy(s), s;
852
+ }
853
+ update(t, e) {
854
+ super.update(t, e), t.some(
855
+ (s) => s.target === this.domNode && s.type === "attributes"
856
+ ) && this.attributes.build();
857
+ }
858
+ };
859
+ C.blotName = "block", C.scope = f.BLOCK_BLOT, C.tagName = "P", C.allowedChildren = [
860
+ gt,
861
+ C,
862
+ W
863
+ ];
864
+ let Kt = C;
865
+ const Y = Kt, J = class extends L {
866
+ checkMerge() {
867
+ return this.next !== null && this.next.statics.blotName === this.statics.blotName;
868
+ }
869
+ deleteAt(t, e) {
870
+ super.deleteAt(t, e), this.enforceAllowedChildren();
871
+ }
872
+ formatAt(t, e, s, i) {
873
+ super.formatAt(t, e, s, i), this.enforceAllowedChildren();
874
+ }
875
+ insertAt(t, e, s) {
876
+ super.insertAt(t, e, s), this.enforceAllowedChildren();
877
+ }
878
+ optimize(t) {
879
+ super.optimize(t), this.children.length > 0 && this.next != null && this.checkMerge() && (this.next.moveChildren(this), this.next.remove());
880
+ }
881
+ };
882
+ J.blotName = "container", J.scope = f.BLOCK_BLOT;
883
+ let qt = J;
884
+ const Wt = qt;
885
+ class $t extends W {
886
+ static formats(t, e) {
887
+ }
888
+ format(t, e) {
889
+ super.formatAt(0, this.length(), t, e);
890
+ }
891
+ formatAt(t, e, s, i) {
892
+ t === 0 && e === this.length() ? this.format(s, i) : super.formatAt(t, e, s, i);
893
+ }
894
+ formats() {
895
+ return this.statics.formats(this.domNode, this.scroll);
896
+ }
897
+ }
898
+ const Ft = $t, Gt = {
899
+ attributes: !0,
900
+ characterData: !0,
901
+ characterDataOldValue: !0,
902
+ childList: !0,
903
+ subtree: !0
904
+ }, Vt = 100, O = class extends L {
905
+ constructor(t, e) {
906
+ super(null, e), this.registry = t, this.scroll = this, this.build(), this.observer = new MutationObserver((s) => {
907
+ this.update(s);
908
+ }), this.observer.observe(this.domNode, Gt), this.attach();
909
+ }
910
+ create(t, e) {
911
+ return this.registry.create(this, t, e);
912
+ }
913
+ find(t, e = !1) {
914
+ const s = this.registry.find(t, e);
915
+ return s ? s.scroll === this ? s : e ? this.find(s.scroll.domNode.parentNode, !0) : null : null;
916
+ }
917
+ query(t, e = f.ANY) {
918
+ return this.registry.query(t, e);
919
+ }
920
+ register(...t) {
921
+ return this.registry.register(...t);
922
+ }
923
+ build() {
924
+ this.scroll != null && super.build();
925
+ }
926
+ detach() {
927
+ super.detach(), this.observer.disconnect();
928
+ }
929
+ deleteAt(t, e) {
930
+ this.update(), t === 0 && e === this.length() ? this.children.forEach((s) => {
931
+ s.remove();
932
+ }) : super.deleteAt(t, e);
933
+ }
934
+ formatAt(t, e, s, i) {
935
+ this.update(), super.formatAt(t, e, s, i);
936
+ }
937
+ insertAt(t, e, s) {
938
+ this.update(), super.insertAt(t, e, s);
939
+ }
940
+ optimize(t = [], e = {}) {
941
+ super.optimize(e);
942
+ const s = e.mutationsMap || /* @__PURE__ */ new WeakMap();
943
+ let i = Array.from(this.observer.takeRecords());
944
+ for (; i.length > 0; )
945
+ t.push(i.pop());
946
+ const r = (l, h = !0) => {
947
+ l == null || l === this || l.domNode.parentNode != null && (s.has(l.domNode) || s.set(l.domNode, []), h && r(l.parent));
948
+ }, o = (l) => {
949
+ s.has(l.domNode) && (l instanceof L && l.children.forEach(o), s.delete(l.domNode), l.optimize(e));
950
+ };
951
+ let a = t;
952
+ for (let l = 0; a.length > 0; l += 1) {
953
+ if (l >= Vt)
954
+ throw new Error("[Parchment] Maximum optimize iterations reached");
955
+ for (a.forEach((h) => {
956
+ const c = this.find(h.target, !0);
957
+ c != null && (c.domNode === h.target && (h.type === "childList" ? (r(this.find(h.previousSibling, !1)), Array.from(h.addedNodes).forEach((d) => {
958
+ const g = this.find(d, !1);
959
+ r(g, !1), g instanceof L && g.children.forEach((u) => {
960
+ r(u, !1);
961
+ });
962
+ })) : h.type === "attributes" && r(c.prev)), r(c));
963
+ }), this.children.forEach(o), a = Array.from(this.observer.takeRecords()), i = a.slice(); i.length > 0; )
964
+ t.push(i.pop());
965
+ }
966
+ }
967
+ update(t, e = {}) {
968
+ t = t || this.observer.takeRecords();
969
+ const s = /* @__PURE__ */ new WeakMap();
970
+ t.map((i) => {
971
+ const r = this.find(i.target, !0);
972
+ return r == null ? null : s.has(r.domNode) ? (s.get(r.domNode).push(i), null) : (s.set(r.domNode, [i]), r);
973
+ }).forEach((i) => {
974
+ i != null && i !== this && s.has(i.domNode) && i.update(s.get(i.domNode) || [], e);
975
+ }), e.mutationsMap = s, s.has(this.domNode) && super.update(s.get(this.domNode), e), this.optimize(t, e);
976
+ }
977
+ };
978
+ O.blotName = "scroll", O.defaultChild = Y, O.allowedChildren = [Y, Wt], O.scope = f.BLOCK_BLOT, O.tagName = "DIV";
979
+ let jt = O;
980
+ const Xt = jt, it = class vt extends W {
981
+ static create(t) {
982
+ return document.createTextNode(t);
983
+ }
984
+ static value(t) {
985
+ return t.data;
986
+ }
987
+ constructor(t, e) {
988
+ super(t, e), this.text = this.statics.value(this.domNode);
989
+ }
990
+ deleteAt(t, e) {
991
+ this.domNode.data = this.text = this.text.slice(0, t) + this.text.slice(t + e);
992
+ }
993
+ index(t, e) {
994
+ return this.domNode === t ? e : -1;
995
+ }
996
+ insertAt(t, e, s) {
997
+ s == null ? (this.text = this.text.slice(0, t) + e + this.text.slice(t), this.domNode.data = this.text) : super.insertAt(t, e, s);
998
+ }
999
+ length() {
1000
+ return this.text.length;
1001
+ }
1002
+ optimize(t) {
1003
+ super.optimize(t), this.text = this.statics.value(this.domNode), this.text.length === 0 ? this.remove() : this.next instanceof vt && this.next.prev === this && (this.insertAt(this.length(), this.next.value()), this.next.remove());
1004
+ }
1005
+ position(t, e = !1) {
1006
+ return [this.domNode, t];
1007
+ }
1008
+ split(t, e = !1) {
1009
+ if (!e) {
1010
+ if (t === 0)
1011
+ return this;
1012
+ if (t === this.length())
1013
+ return this.next;
1014
+ }
1015
+ const s = this.scroll.create(this.domNode.splitText(t));
1016
+ return this.parent.insertBefore(s, this.next || void 0), this.text = this.statics.value(this.domNode), s;
1017
+ }
1018
+ update(t, e) {
1019
+ t.some((s) => s.type === "characterData" && s.target === this.domNode) && (this.text = this.statics.value(this.domNode));
1020
+ }
1021
+ value() {
1022
+ return this.text;
1023
+ }
1024
+ };
1025
+ it.blotName = "text", it.scope = f.INLINE_BLOT;
1026
+ const Q = class Q extends Xt {
1027
+ constructor(t, e) {
1028
+ super(t, e), this.observer.disconnect();
1029
+ }
1030
+ // Suppress Parchment's automatic DOM reconciliation
1031
+ update(t, e) {
1032
+ }
1033
+ optimize(t, e) {
1034
+ }
1035
+ };
1036
+ Q.blotName = "v2-scroll";
1037
+ let Z = Q;
1038
+ const B = class B extends Y {
1039
+ };
1040
+ B.blotName = "v2-block", B.tagName = "DIV", B.className = "v2-line";
1041
+ let U = B;
1042
+ const D = class D extends gt {
1043
+ static create(t) {
1044
+ const e = super.create();
1045
+ return t && Yt(e, t), e;
1046
+ }
1047
+ };
1048
+ D.blotName = "v2-inline", D.tagName = "SPAN", D.className = "v2-mark";
1049
+ let H = D;
1050
+ function Yt(n, t) {
1051
+ if (t.className)
1052
+ for (const e of t.className.split(/\s+/).filter(Boolean))
1053
+ n.classList.add(e);
1054
+ t.bold && (n.style.fontWeight = "bold"), t.italic && (n.style.fontStyle = "italic"), t.color && (n.style.color = t.color), t.background && (n.style.backgroundColor = t.background), t.underline && (n.style.textDecoration = `${t.underline} underline`, t.underlineColor && (n.style.textDecorationColor = t.underlineColor));
1055
+ }
1056
+ const I = class I extends Ft {
1057
+ static create() {
1058
+ const t = super.create();
1059
+ return t.contentEditable = "false", t.setAttribute("aria-hidden", "true"), t;
1060
+ }
1061
+ };
1062
+ I.blotName = "v2-widget", I.tagName = "SPAN", I.className = "v2-widget";
1063
+ let K = I;
1064
+ function Jt() {
1065
+ const n = new z();
1066
+ return n.register(U, H, K), n;
1067
+ }
1068
+ function Zt(n, t, e, s, i) {
1069
+ if (t.length === 0) {
1070
+ n.appendChild(document.createElement("br"));
1071
+ return;
1072
+ }
1073
+ const r = /* @__PURE__ */ new Set([0, t.length]);
1074
+ for (const a of s)
1075
+ r.add(Math.max(0, a.from - e)), r.add(Math.min(t.length, a.to - e));
1076
+ for (const a of i) {
1077
+ const l = a.offset - e;
1078
+ l >= 0 && l <= t.length && r.add(l);
1079
+ }
1080
+ const o = [...r].sort((a, l) => a - l);
1081
+ for (let a = 0; a < o.length - 1; a++) {
1082
+ const l = o[a], h = o[a + 1];
1083
+ for (const u of i)
1084
+ u.offset - e === l && (u.side ?? "before") === "before" && n.appendChild(G(u));
1085
+ const c = t.slice(l, h);
1086
+ if (!c) continue;
1087
+ let d, g = 1 / 0;
1088
+ for (const u of s) {
1089
+ const m = u.from - e, p = u.to - e;
1090
+ if (m <= l && p >= h) {
1091
+ const k = p - m;
1092
+ k < g && (g = k, d = u);
1093
+ }
1094
+ }
1095
+ if (d) {
1096
+ const u = H.create(d);
1097
+ if (d.attributes)
1098
+ for (const [m, p] of Object.entries(d.attributes))
1099
+ u.setAttribute(m, p);
1100
+ u.appendChild(document.createTextNode(c)), n.appendChild(u);
1101
+ } else
1102
+ n.appendChild(document.createTextNode(c));
1103
+ for (const u of i)
1104
+ u.offset - e === h && u.side === "after" && n.appendChild(G(u));
1105
+ }
1106
+ for (const a of i)
1107
+ a.offset - e === t.length && (a.side ?? "before") === "before" && n.appendChild(G(a));
1108
+ }
1109
+ function G(n) {
1110
+ const t = K.create();
1111
+ return t.appendChild(n.create()), t;
1112
+ }
1113
+ class Qt {
1114
+ constructor(t) {
1115
+ const e = Jt();
1116
+ this.scroll = new Z(e, t);
1117
+ }
1118
+ /**
1119
+ * Rebuild the document tree from `value` + `decorations`.
1120
+ * Reuses existing `.v2-line` elements in place to preserve DOM identity
1121
+ * across renders (fixes DevTools node tracking and mouse gesture continuity).
1122
+ * Only the children of each line are replaced; the line element itself survives.
1123
+ */
1124
+ build(t, e) {
1125
+ const s = this.scroll.domNode, i = t.split(`
1126
+ `), r = Array.from(s.querySelectorAll(".v2-line")), o = /* @__PURE__ */ new Map(), a = [], l = [];
1127
+ for (const c of e)
1128
+ if (c.type === "line") {
1129
+ const d = o.get(c.line) ?? [];
1130
+ d.push(c), o.set(c.line, d);
1131
+ } else c.type === "mark" ? a.push(c) : l.push(c);
1132
+ a.sort((c, d) => c.from - d.from || c.to - d.to), l.sort((c, d) => c.offset - d.offset);
1133
+ let h = 0;
1134
+ for (let c = 0; c < i.length; c++) {
1135
+ const d = i[c], g = c + 1, u = h, m = u + d.length;
1136
+ let p;
1137
+ if (c < r.length) {
1138
+ for (p = r[c]; p.attributes.length > 0; )
1139
+ p.removeAttribute(p.attributes[0].name);
1140
+ for (p.className = "v2-line"; p.firstChild; )
1141
+ p.removeChild(p.firstChild);
1142
+ } else
1143
+ p = U.create(), s.appendChild(p);
1144
+ const k = o.get(g) ?? [];
1145
+ for (const v of k) {
1146
+ if (v.className)
1147
+ for (const E of v.className.split(/\s+/).filter(Boolean))
1148
+ p.classList.add(E);
1149
+ if (v.attributes)
1150
+ for (const [E, x] of Object.entries(v.attributes))
1151
+ p.setAttribute(E, x);
1152
+ }
1153
+ const Ct = a.filter((v) => v.from < m && v.to > u), Ot = l.filter(
1154
+ (v) => v.offset >= u && v.offset <= m
1155
+ );
1156
+ Zt(p, d, u, Ct, Ot);
1157
+ const $ = k.filter((v) => v.message);
1158
+ if ($.length > 0) {
1159
+ const v = $.map((x) => x.message).join(" · ");
1160
+ p.dataset.message = v, p.title = v;
1161
+ const E = [
1162
+ ...new Set(
1163
+ $.flatMap(
1164
+ (x) => x.messageClassName ? x.messageClassName.split(/\s+/).filter(Boolean) : []
1165
+ )
1166
+ )
1167
+ ];
1168
+ E.length > 0 && (p.dataset.messageClass = E.join(" "));
1169
+ }
1170
+ h += d.length + 1;
1171
+ }
1172
+ for (; s.children.length > i.length; )
1173
+ s.removeChild(s.lastChild);
1174
+ }
1175
+ destroy() {
1176
+ const t = this.scroll.domNode;
1177
+ for (; t.firstChild; )
1178
+ t.removeChild(t.firstChild);
1179
+ }
1180
+ }
1181
+ function te(n) {
1182
+ const t = Array.from(n.querySelectorAll(".v2-line"));
1183
+ return t.length > 0 ? t.map((e) => ee(e)).join(`
1184
+ `) : bt(n);
1185
+ }
1186
+ function ee(n) {
1187
+ let t = "";
1188
+ for (const e of n.childNodes) t += _t(e);
1189
+ return t;
1190
+ }
1191
+ function _t(n) {
1192
+ if (n.nodeType === Node.TEXT_NODE) return n.data;
1193
+ if (!(n instanceof Element) || n.classList.contains("v2-widget") || n.classList.contains("v2-line-message") || n.tagName === "BR") return "";
1194
+ let t = "";
1195
+ for (const e of n.childNodes) t += _t(e);
1196
+ return t;
1197
+ }
1198
+ function bt(n) {
1199
+ let t = "", e = !0;
1200
+ for (const s of n.childNodes)
1201
+ if (s.nodeType === Node.TEXT_NODE)
1202
+ t += s.data;
1203
+ else if (s instanceof HTMLElement) {
1204
+ if (s.tagName === "BR") {
1205
+ t += `
1206
+ `, e = !1;
1207
+ continue;
1208
+ }
1209
+ if (s.classList.contains("v2-widget")) continue;
1210
+ (s.tagName === "DIV" || s.tagName === "P") && !e && (t += `
1211
+ `), e = !1, t += bt(s);
1212
+ }
1213
+ return t;
1214
+ }
1215
+ function R(n) {
1216
+ if (n.nodeType === Node.TEXT_NODE) return n.length;
1217
+ if (!(n instanceof Element) || n.classList.contains("v2-widget") || n.tagName === "BR") return 0;
1218
+ let t = 0;
1219
+ for (const e of n.childNodes) t += R(e);
1220
+ return t;
1221
+ }
1222
+ function rt(n, t, e) {
1223
+ const s = Array.from(n.querySelectorAll(".v2-line"));
1224
+ let i = 0;
1225
+ for (let r = 0; r < s.length; r++) {
1226
+ r > 0 && i++;
1227
+ const o = s[r], a = yt(
1228
+ o,
1229
+ t,
1230
+ e,
1231
+ i
1232
+ );
1233
+ if (a.found) return a.offset;
1234
+ i += R(o);
1235
+ }
1236
+ return i;
1237
+ }
1238
+ function yt(n, t, e, s) {
1239
+ if (n === t) {
1240
+ if (n.nodeType === Node.TEXT_NODE)
1241
+ return { found: !0, offset: s + e };
1242
+ let i = s;
1243
+ const r = Array.from(n.childNodes);
1244
+ for (let o = 0; o < e && o < r.length; o++)
1245
+ i += R(r[o]);
1246
+ return { found: !0, offset: i };
1247
+ }
1248
+ if (n.nodeType === Node.TEXT_NODE)
1249
+ return { found: !1, offset: s + n.length };
1250
+ if (n instanceof Element) {
1251
+ if (n.classList.contains("v2-widget"))
1252
+ return { found: !1, offset: s };
1253
+ if (n.tagName === "BR")
1254
+ return { found: !1, offset: s };
1255
+ let i = s;
1256
+ for (const r of n.childNodes) {
1257
+ const o = yt(r, t, e, i);
1258
+ if (o.found) return o;
1259
+ i = o.offset;
1260
+ }
1261
+ return { found: !1, offset: i };
1262
+ }
1263
+ return { found: !1, offset: s };
1264
+ }
1265
+ function nt(n, t) {
1266
+ const e = Array.from(n.querySelectorAll(".v2-line"));
1267
+ let s = t;
1268
+ for (let r = 0; r < e.length; r++) {
1269
+ if (r > 0) {
1270
+ if (s === 0)
1271
+ return { node: e[r], offset: 0 };
1272
+ s--;
1273
+ }
1274
+ const o = e[r], a = R(o);
1275
+ if (s <= a) {
1276
+ const l = Nt(o, s);
1277
+ return l || { node: o, offset: o.childNodes.length };
1278
+ }
1279
+ s -= a;
1280
+ }
1281
+ const i = e[e.length - 1];
1282
+ return i ? { node: i, offset: i.childNodes.length } : { node: n, offset: n.childNodes.length };
1283
+ }
1284
+ function Nt(n, t) {
1285
+ if (n.nodeType === Node.TEXT_NODE) {
1286
+ const e = n;
1287
+ return t <= e.length ? { node: e, offset: t } : null;
1288
+ }
1289
+ if (n instanceof Element) {
1290
+ if (n.classList.contains("v2-widget") || n.tagName === "BR") return null;
1291
+ let e = 0;
1292
+ for (const s of n.childNodes) {
1293
+ const i = R(s);
1294
+ if (t <= i) {
1295
+ const r = Nt(s, t);
1296
+ return r || { node: n, offset: e + 1 };
1297
+ }
1298
+ t -= i, e++;
1299
+ }
1300
+ }
1301
+ return null;
1302
+ }
1303
+ function P(n) {
1304
+ const e = n.getRootNode().getSelection?.() ?? window.getSelection();
1305
+ if (!e || e.rangeCount === 0) return null;
1306
+ const s = e.getRangeAt(0);
1307
+ if (!n.contains(s.commonAncestorContainer)) return null;
1308
+ const i = rt(
1309
+ n,
1310
+ s.startContainer,
1311
+ s.startOffset
1312
+ ), r = rt(
1313
+ n,
1314
+ s.endContainer,
1315
+ s.endOffset
1316
+ );
1317
+ return { anchorOffset: i, focusOffset: r };
1318
+ }
1319
+ function se(n, t) {
1320
+ const e = nt(n, t.anchorOffset), s = nt(n, t.focusOffset);
1321
+ if (!(!e || !s))
1322
+ try {
1323
+ const i = window.getSelection();
1324
+ if (!i) return;
1325
+ const r = document.createRange();
1326
+ r.setStart(e.node, e.offset), r.setEnd(s.node, s.offset), i.removeAllRanges(), i.addRange(r);
1327
+ } catch {
1328
+ }
1329
+ }
1330
+ function M() {
1331
+ return crypto.randomUUID();
1332
+ }
1333
+ function Et(n, t) {
1334
+ let e = 0;
1335
+ for (; e < n.length && e < t.length && n[e] === t[e]; )
1336
+ e++;
1337
+ let s = n.length, i = t.length;
1338
+ for (; s > e && i > e && n[s - 1] === t[i - 1]; )
1339
+ s--, i--;
1340
+ return { start: e, removed: s - e, inserted: i - e };
1341
+ }
1342
+ function ot(n, t, e) {
1343
+ const s = e.start + e.removed, i = e.inserted - e.removed;
1344
+ if (t <= e.start) return { from: n, to: t };
1345
+ if (n >= s) return { from: n + i, to: t + i };
1346
+ const r = Math.min(n, e.start), o = Math.max(
1347
+ t > s ? t + i : e.start + e.inserted,
1348
+ e.start + e.inserted
1349
+ );
1350
+ return r >= o ? null : { from: r, to: o };
1351
+ }
1352
+ function ie(n, t) {
1353
+ let e = 0;
1354
+ for (let s = 0; s < t && s < n.length; s++)
1355
+ n[s] === `
1356
+ ` && e++;
1357
+ return e;
1358
+ }
1359
+ function re(n, t, e) {
1360
+ const s = Et(t, e), i = s.start + s.removed, r = t.slice(s.start, i), o = e.slice(s.start, s.start + s.inserted), a = (r.match(/\n/g) ?? []).length, h = (o.match(/\n/g) ?? []).length - a, c = ie(t, s.start) + 1, d = c + a, g = [];
1361
+ for (const u of n)
1362
+ if (u.type === "mark") {
1363
+ const m = ot(u.from, u.to, s);
1364
+ m && g.push({ ...u, from: m.from, to: m.to });
1365
+ } else if (u.type === "line")
1366
+ u.line < c ? g.push(u) : u.line <= d || g.push({ ...u, line: u.line + h });
1367
+ else {
1368
+ const m = ot(u.offset, u.offset + 1, s);
1369
+ m && g.push({ ...u, offset: m.from });
1370
+ }
1371
+ return g;
1372
+ }
1373
+ function ne(n, t) {
1374
+ if (n.length === 0) return !1;
1375
+ const e = Math.max(t.removed, t.inserted);
1376
+ return e > 50 && e > n.length * 0.5;
1377
+ }
1378
+ function V(n, t, e) {
1379
+ const s = Et(t, e);
1380
+ return ne(t, s) ? [] : re(n, t, e);
1381
+ }
1382
+ function at(n, t) {
1383
+ const e = crypto.randomUUID();
1384
+ return n.set(e, { ...t, id: e }), e;
1385
+ }
1386
+ function oe(n, t) {
1387
+ n.clear();
1388
+ for (const e of t) {
1389
+ const s = crypto.randomUUID();
1390
+ n.set(s, { ...e, id: s });
1391
+ }
1392
+ }
1393
+ function ae(n, t) {
1394
+ const e = [], s = [];
1395
+ for (const i of t) {
1396
+ let r = i.pattern.flags.includes("g") ? i.pattern.flags : i.pattern.flags + "g";
1397
+ i.captureGroups && !r.includes("d") && (r += "d");
1398
+ const o = new RegExp(i.pattern.source, r);
1399
+ let a;
1400
+ for (; (a = o.exec(n)) !== null; ) {
1401
+ if (a[0].length === 0) {
1402
+ o.lastIndex++;
1403
+ continue;
1404
+ }
1405
+ const l = a.index;
1406
+ if (i.captureGroups) {
1407
+ const h = a.indices?.groups;
1408
+ if (h)
1409
+ for (const [c, d] of Object.entries(i.captureGroups)) {
1410
+ const g = h[c];
1411
+ if (g === void 0) continue;
1412
+ const [u, m] = g;
1413
+ e.push({ type: "mark", from: u, to: m, ...d });
1414
+ }
1415
+ } else {
1416
+ const h = l + a[0].length;
1417
+ e.push({
1418
+ type: "mark",
1419
+ from: l,
1420
+ to: h,
1421
+ className: i.className,
1422
+ bold: i.bold,
1423
+ italic: i.italic,
1424
+ color: i.color,
1425
+ background: i.background,
1426
+ underline: i.underline,
1427
+ underlineColor: i.underlineColor,
1428
+ attributes: i.attributes
1429
+ });
1430
+ }
1431
+ if (i.createLineDecoration) {
1432
+ const h = i.createLineDecoration(a);
1433
+ if (h) {
1434
+ const c = n.slice(0, l).split(`
1435
+ `).length;
1436
+ s.push({ type: "line", line: c, ...h });
1437
+ }
1438
+ }
1439
+ }
1440
+ }
1441
+ return { markDecorations: e, lineDecorations: s };
1442
+ }
1443
+ var le = Object.defineProperty, ce = Object.getOwnPropertyDescriptor, y = (n, t, e, s) => {
1444
+ for (var i = s > 1 ? void 0 : s ? ce(t, e) : t, r = n.length - 1, o; r >= 0; r--)
1445
+ (o = n[r]) && (i = (s ? o(t, e, i) : o(i)) || i);
1446
+ return s && i && le(t, e, i), i;
1447
+ };
1448
+ const he = 100;
1449
+ function lt(n) {
1450
+ const t = document.createElement("div");
1451
+ t.innerHTML = n;
1452
+ const e = [];
1453
+ let s = 0;
1454
+ function i(r) {
1455
+ if (r.nodeType === Node.TEXT_NODE) {
1456
+ s += r.length;
1457
+ return;
1458
+ }
1459
+ if (!(r instanceof HTMLElement)) return;
1460
+ const o = r.tagName === "SPAN" && r.className, a = s;
1461
+ for (const l of r.childNodes)
1462
+ i(l);
1463
+ o && s > a && e.push({
1464
+ type: "mark",
1465
+ from: a,
1466
+ to: s,
1467
+ className: r.className
1468
+ });
1469
+ }
1470
+ for (const r of t.childNodes) i(r);
1471
+ return e;
1472
+ }
1473
+ const q = class q extends tt {
1474
+ constructor() {
1475
+ super(...arguments), this.lineNumbers = !1, this.listNumbers = !1, this.gutter = !1, this.wordWrap = !1, this.autoGrow = !1, this.readOnly = !1, this.label = null, this._value = "", this._initialValueResolved = !1, this._valueSetByHost = !1, this._document = null, this._textareaRef = null, this._pluginDecorations = /* @__PURE__ */ new Map(), this._patternDecorations = [], this._externalDecorations = [], this._patterns = /* @__PURE__ */ new Map(), this._plugin = null, this._pluginProperty = null, this._pluginApi = null, this._pluginSeq = 0, this._pluginSheets = /* @__PURE__ */ new Set(), this._savedSelection = null, this._rafHandle = null, this._composing = !1, this._isRendering = !1, this._activeLine = null, this._cursorCallbacks = /* @__PURE__ */ new Set(), this._docSelectionChangeHandler = () => {
1476
+ document.activeElement === this && this._onSelectionChange();
1477
+ }, this._undoStack = [], this._undoIndex = -1, this._resizeObserver = null, this._gutterLabels = [], this._onInputEvent = () => {
1478
+ this._composing || this._onInput();
1479
+ }, this._onSelectionChange = () => {
1480
+ const t = this._getEditorEl();
1481
+ if (!t) return;
1482
+ const e = P(t);
1483
+ if (e) {
1484
+ this._savedSelection = e, this.dispatchEvent(
1485
+ new CustomEvent("rc-textarea-select", {
1486
+ bubbles: !0,
1487
+ composed: !0,
1488
+ detail: {
1489
+ selectionStart: e.anchorOffset,
1490
+ selectionEnd: e.focusOffset
1491
+ }
1492
+ })
1493
+ ), this._updateActiveLine();
1494
+ const s = Math.min(e.anchorOffset, e.focusOffset), i = Math.max(e.anchorOffset, e.focusOffset);
1495
+ for (const r of this._cursorCallbacks) r(s, i);
1496
+ }
1497
+ }, this._onKeyDown = (t) => {
1498
+ if (t.key === "Tab" && !t.ctrlKey && !t.metaKey && !t.altKey) {
1499
+ t.preventDefault(), this._insertText(" ");
1500
+ return;
1501
+ }
1502
+ const e = (t.ctrlKey || t.metaKey) && t.key === "z" && !t.shiftKey, s = (t.ctrlKey || t.metaKey) && t.key === "y" || (t.ctrlKey || t.metaKey) && t.shiftKey && t.key === "z";
1503
+ if (e) {
1504
+ t.preventDefault(), this._undo();
1505
+ return;
1506
+ }
1507
+ s && (t.preventDefault(), this._redo());
1508
+ }, this._onPaste = (t) => {
1509
+ t.preventDefault();
1510
+ const e = t.clipboardData?.getData("text/plain") ?? "";
1511
+ if (!e) return;
1512
+ const s = e.replace(/\r\n/g, `
1513
+ `).replace(/\r/g, `
1514
+ `);
1515
+ this._insertText(s);
1516
+ };
1517
+ }
1518
+ get plugin() {
1519
+ return this._pluginProperty;
1520
+ }
1521
+ /** Declarative plugin hook for framework integrations. */
1522
+ set plugin(t) {
1523
+ const e = this._pluginProperty;
1524
+ t !== e && (this._pluginProperty = t, t ? this.usePlugin(t) : this.removePlugin(), this.requestUpdate("plugin", e));
1525
+ }
1526
+ get decorations() {
1527
+ return this._externalDecorations;
1528
+ }
1529
+ set decorations(t) {
1530
+ this._externalDecorations = t ?? [], this.requestUpdate();
1531
+ }
1532
+ get value() {
1533
+ return this._value;
1534
+ }
1535
+ set value(t) {
1536
+ const e = this._value;
1537
+ t !== this._value && (this._valueSetByHost = !0, this._initialValueResolved = !0, this._value = t, this._syncTextareaValue(), this._scheduleRender(), this.requestUpdate("value", e));
1538
+ }
1539
+ get defaultValue() {
1540
+ return this._defaultValue;
1541
+ }
1542
+ /** Initial uncontrolled editor value. */
1543
+ set defaultValue(t) {
1544
+ const e = this._defaultValue;
1545
+ this._defaultValue = t, !this._valueSetByHost && !this._initialValueResolved && t !== void 0 && (this._value = t, this._initialValueResolved = !0, this._syncTextareaValue(), this._scheduleRender()), this.requestUpdate("defaultValue", e);
1546
+ }
1547
+ // ── Lifecycle ─────────────────────────────────────────────────────────
1548
+ connectedCallback() {
1549
+ super.connectedCallback(), document.addEventListener(
1550
+ "selectionchange",
1551
+ this._docSelectionChangeHandler
1552
+ );
1553
+ }
1554
+ disconnectedCallback() {
1555
+ super.disconnectedCallback(), document.removeEventListener(
1556
+ "selectionchange",
1557
+ this._docSelectionChangeHandler
1558
+ ), this._plugin?.destroy?.(), this._plugin = null, this._pluginApi = null, this._clearPluginSheets(), this._cursorCallbacks.clear(), this._resizeObserver?.disconnect(), this._rafHandle !== null && (cancelAnimationFrame(this._rafHandle), this._rafHandle = null);
1559
+ }
1560
+ firstUpdated() {
1561
+ const t = this._getEditorEl();
1562
+ t && (this._document = new Qt(t), this._bindEditorEvents(t)), this._resizeObserver = new ResizeObserver(() => {
1563
+ this._syncGutter(), this._syncGutterHeights();
1564
+ }), this._resizeObserver.observe(this), this._scheduleRender();
1565
+ }
1566
+ updated(t) {
1567
+ if (t.has("readOnly")) {
1568
+ const e = this._getEditorEl();
1569
+ e && (e.contentEditable = this.readOnly ? "false" : "true"), this._syncGutterHeights();
1570
+ }
1571
+ if (t.has("label")) {
1572
+ const e = this._getEditorEl();
1573
+ e && this.label && e.setAttribute("aria-label", this.label);
1574
+ }
1575
+ }
1576
+ // ── Template ──────────────────────────────────────────────────────────
1577
+ render() {
1578
+ return Lt`
1579
+ <div id="root" part="root">
1580
+ <div id="gutter" part="gutter" aria-hidden="true">
1581
+ <div id="gutter-cells" part="gutter-cells"></div>
1582
+ </div>
1583
+ <div id="editor-area" part="editor-area">
1584
+ <div
1585
+ id="editor"
1586
+ part="editor"
1587
+ contenteditable=${this.readOnly ? "false" : "true"}
1588
+ role="textbox"
1589
+ aria-multiline="true"
1590
+ spellcheck="false"
1591
+ autocorrect="off"
1592
+ autocapitalize="off"
1593
+ aria-label=${this.label ?? ""}
1594
+ ></div>
1595
+ <slot @slotchange=${this._onSlotChange}></slot>
1596
+ </div>
1597
+ </div>
1598
+ `;
1599
+ }
1600
+ // ── Slot change — lightDOM textarea wiring ────────────────────────────
1601
+ _onSlotChange() {
1602
+ const t = this.shadowRoot?.querySelector(
1603
+ "slot"
1604
+ );
1605
+ if (!t) return;
1606
+ const e = t.assignedElements({ flatten: !0 }).find(
1607
+ (i) => i instanceof HTMLTextAreaElement
1608
+ );
1609
+ if (!e) return;
1610
+ this._textareaRef = new WeakRef(e), Object.assign(e.style, {
1611
+ position: "absolute",
1612
+ width: "1px",
1613
+ height: "1px",
1614
+ padding: "0",
1615
+ margin: "-1px",
1616
+ overflow: "hidden",
1617
+ clip: "rect(0,0,0,0)",
1618
+ border: "0",
1619
+ opacity: "0",
1620
+ pointerEvents: "none",
1621
+ tabIndex: "-1"
1622
+ }), e.setAttribute("aria-hidden", "true"), e.tabIndex = -1;
1623
+ const s = this._getEditorEl();
1624
+ if (s) {
1625
+ !this.label && e.getAttribute("aria-label") && s.setAttribute(
1626
+ "aria-label",
1627
+ e.getAttribute("aria-label")
1628
+ );
1629
+ const i = e.getAttribute("placeholder");
1630
+ i && s.setAttribute("aria-placeholder", i);
1631
+ }
1632
+ this._initialValueResolved ? e.value = this._value : (this._value = e.value, this._initialValueResolved = !0), e.addEventListener("invalid", () => {
1633
+ const i = this._getEditorEl();
1634
+ i && i.setAttribute("aria-invalid", "true");
1635
+ }), this._syncTypography(e), this._scheduleRender();
1636
+ }
1637
+ // ── Editor event binding ──────────────────────────────────────────────
1638
+ _bindEditorEvents(t) {
1639
+ t.addEventListener("compositionstart", () => {
1640
+ this._composing = !0;
1641
+ }), t.addEventListener("compositionend", () => {
1642
+ this._composing = !1, this._onInput();
1643
+ }), t.addEventListener("input", this._onInputEvent), t.addEventListener("keydown", this._onKeyDown), t.addEventListener("paste", this._onPaste), t.addEventListener("focus", () => {
1644
+ this.dispatchEvent(
1645
+ new CustomEvent("rc-textarea-focus", {
1646
+ bubbles: !0,
1647
+ composed: !0
1648
+ })
1649
+ );
1650
+ }), t.addEventListener("blur", () => {
1651
+ this.dispatchEvent(
1652
+ new CustomEvent("rc-textarea-blur", {
1653
+ bubbles: !0,
1654
+ composed: !0
1655
+ })
1656
+ ), this._activeLine?.classList.remove("v2-line--active"), this._activeLine = null;
1657
+ });
1658
+ }
1659
+ _onInput() {
1660
+ const t = this._getEditorEl();
1661
+ if (!t) return;
1662
+ const e = te(t);
1663
+ if (e === this._value) return;
1664
+ const s = this._value, i = this._savedSelection, r = V(
1665
+ [...this._pluginDecorations.values()],
1666
+ s,
1667
+ e
1668
+ );
1669
+ this._pluginDecorations.clear();
1670
+ for (const o of r) this._pluginDecorations.set(o.id, o);
1671
+ this._value = e, this._syncTextareaValue(!0), this._savedSelection = P(t), this._undoStack.length === 0 && (this._undoStack.push({
1672
+ value: s,
1673
+ anchorOffset: i?.anchorOffset ?? 0,
1674
+ focusOffset: i?.focusOffset ?? 0
1675
+ }), this._undoIndex = 0), this._pushUndo(this._savedSelection), this._dispatchChange(e), this._scheduleRender();
1676
+ }
1677
+ _updateActiveLine() {
1678
+ const t = this._getEditorEl();
1679
+ if (!t) return;
1680
+ const e = this.shadowRoot.getSelection?.() ?? window.getSelection();
1681
+ let s = null;
1682
+ if (e?.focusNode && t.contains(e.focusNode)) {
1683
+ let i = e.focusNode;
1684
+ for (; i && i !== t; ) {
1685
+ if (i instanceof HTMLElement && i.classList.contains("v2-line")) {
1686
+ s = i;
1687
+ break;
1688
+ }
1689
+ i = i.parentNode;
1690
+ }
1691
+ }
1692
+ s !== this._activeLine && (this._activeLine?.classList.remove("v2-line--active"), this._activeLine = s, this._activeLine?.classList.add("v2-line--active"), this._updateActiveGutterCell());
1693
+ }
1694
+ _updateActiveGutterCell() {
1695
+ const t = this.shadowRoot?.getElementById("gutter-cells");
1696
+ if (!t) return;
1697
+ const e = t.querySelector(".gutter-cell--active");
1698
+ if (e && e.classList.remove("gutter-cell--active"), this._activeLine) {
1699
+ const s = this._getEditorEl();
1700
+ if (!s) return;
1701
+ const i = s.querySelectorAll(".v2-line");
1702
+ for (let r = 0; r < i.length; r++)
1703
+ if (i[r] === this._activeLine) {
1704
+ const o = t.children[r];
1705
+ o && o.classList.add("gutter-cell--active");
1706
+ break;
1707
+ }
1708
+ }
1709
+ }
1710
+ _insertText(t) {
1711
+ const e = this._getEditorEl();
1712
+ if (e) {
1713
+ if (t.includes(`
1714
+ `)) {
1715
+ const s = P(e) ?? this._savedSelection, i = Math.min(s?.anchorOffset ?? 0, s?.focusOffset ?? 0), r = Math.max(s?.anchorOffset ?? 0, s?.focusOffset ?? 0), o = this._value, a = o.slice(0, i) + t + o.slice(r), l = i + t.length, h = V(
1716
+ [...this._pluginDecorations.values()],
1717
+ o,
1718
+ a
1719
+ );
1720
+ this._pluginDecorations.clear();
1721
+ for (const c of h) this._pluginDecorations.set(c.id, c);
1722
+ this._value = a, this._syncTextareaValue(!0), this._savedSelection = {
1723
+ anchorOffset: l,
1724
+ focusOffset: l
1725
+ }, this._undoStack.length === 0 && (this._undoStack.push({
1726
+ value: o,
1727
+ anchorOffset: s?.anchorOffset ?? 0,
1728
+ focusOffset: s?.focusOffset ?? 0
1729
+ }), this._undoIndex = 0), this._pushUndo(this._savedSelection), this._dispatchChange(a), this._scheduleRender();
1730
+ return;
1731
+ }
1732
+ document.execCommand("insertText", !1, t), this._onInput();
1733
+ }
1734
+ }
1735
+ /**
1736
+ * Wrap the current selection with `prefix` and `suffix`.
1737
+ * No-op when the selection is collapsed (no text selected).
1738
+ *
1739
+ * Uses the model path directly (not `execCommand`) because callers such as
1740
+ * toolbar buttons move focus away from the editor before this fires, which
1741
+ * clears the DOM selection. `_savedSelection` retains the last model-level
1742
+ * anchor/focus offsets.
1743
+ */
1744
+ wrapSelection(t, e) {
1745
+ const s = this._getEditorEl();
1746
+ if (!s) return;
1747
+ const i = P(s) ?? this._savedSelection;
1748
+ if (!i || i.anchorOffset === i.focusOffset) return;
1749
+ const r = Math.min(i.anchorOffset, i.focusOffset), o = Math.max(i.anchorOffset, i.focusOffset), a = this._value.slice(r, o), l = this._value, h = l.slice(0, r) + t + a + e + l.slice(o), c = V([...this._pluginDecorations.values()], l, h);
1750
+ this._pluginDecorations.clear();
1751
+ for (const d of c) this._pluginDecorations.set(d.id, d);
1752
+ this._value = h, this._syncTextareaValue(!0), this._savedSelection = {
1753
+ anchorOffset: r + t.length,
1754
+ focusOffset: r + t.length + a.length
1755
+ }, this._pushUndo(this._savedSelection), this._dispatchChange(h), this._scheduleRender();
1756
+ }
1757
+ /**
1758
+ * Replace the current selection with `text`.
1759
+ * When the selection is collapsed this is equivalent to `insertText`.
1760
+ */
1761
+ replaceSelection(t) {
1762
+ this._insertText(t);
1763
+ }
1764
+ // ── Undo/Redo ─────────────────────────────────────────────────────────
1765
+ /** Reset the undo/redo history. Call when the editor receives entirely new content. */
1766
+ clearHistory() {
1767
+ this._undoStack = [], this._undoIndex = -1;
1768
+ }
1769
+ _pushUndo(t) {
1770
+ const e = {
1771
+ value: this._value,
1772
+ anchorOffset: t?.anchorOffset ?? 0,
1773
+ focusOffset: t?.focusOffset ?? 0
1774
+ };
1775
+ this._undoStack = this._undoStack.slice(0, this._undoIndex + 1), this._undoStack.push(e), this._undoStack.length > he && this._undoStack.shift(), this._undoIndex = this._undoStack.length - 1;
1776
+ }
1777
+ _undo() {
1778
+ this._undoIndex <= 0 || (this._undoIndex--, this._applyUndoEntry(this._undoStack[this._undoIndex]));
1779
+ }
1780
+ _redo() {
1781
+ this._undoIndex >= this._undoStack.length - 1 || (this._undoIndex++, this._applyUndoEntry(this._undoStack[this._undoIndex]));
1782
+ }
1783
+ _applyUndoEntry(t) {
1784
+ this._value = t.value, this._savedSelection = {
1785
+ anchorOffset: t.anchorOffset,
1786
+ focusOffset: t.focusOffset
1787
+ }, this._syncTextareaValue(!0), this._dispatchChange(this._value), this._scheduleRender();
1788
+ }
1789
+ // ── Plugin API ────────────────────────────────────────────────────────
1790
+ usePlugin(t) {
1791
+ this._plugin?.destroy?.(), this._clearPluginSheets(), this._pluginDecorations.clear(), this._cursorCallbacks.clear(), this._pluginSeq++, this._plugin = t, this._pluginApi = this._buildPluginApi(), t.mount?.(this._pluginApi), this._scheduleRender();
1792
+ }
1793
+ removePlugin() {
1794
+ this._plugin?.destroy?.(), this._clearPluginSheets(), this._plugin = null, this._pluginApi = null, this._pluginDecorations.clear(), this._cursorCallbacks.clear(), this._pluginSeq++, this._scheduleRender();
1795
+ }
1796
+ /**
1797
+ * Build the `RCTextareaPluginAPI` object passed to the active plugin's
1798
+ * `mount()` call. Each getter delegates to the component's live state so the
1799
+ * API stays accurate across render frames without needing to be rebuilt.
1800
+ */
1801
+ _buildPluginApi() {
1802
+ const t = this;
1803
+ return {
1804
+ get host() {
1805
+ return t;
1806
+ },
1807
+ get value() {
1808
+ return t._value;
1809
+ },
1810
+ get selectionStart() {
1811
+ const e = t._savedSelection;
1812
+ return e ? Math.min(e.anchorOffset, e.focusOffset) : 0;
1813
+ },
1814
+ get selectionEnd() {
1815
+ const e = t._savedSelection;
1816
+ return e ? Math.max(e.anchorOffset, e.focusOffset) : 0;
1817
+ },
1818
+ getCursorRect() {
1819
+ const e = window.getSelection();
1820
+ if (!e?.focusNode) return null;
1821
+ const s = t._getEditorEl();
1822
+ if (!s || !s.contains(e.focusNode)) return null;
1823
+ try {
1824
+ const i = document.createRange();
1825
+ i.setStart(e.focusNode, e.focusOffset), i.collapse(!0);
1826
+ const r = i.getBoundingClientRect();
1827
+ return r.height > 0 ? r : null;
1828
+ } catch {
1829
+ return null;
1830
+ }
1831
+ },
1832
+ getWordAtCursor() {
1833
+ const e = t._savedSelection?.focusOffset ?? 0, s = t._value;
1834
+ if (!s) return null;
1835
+ let i = e;
1836
+ for (; i > 0 && /\w/.test(s[i - 1]); ) i--;
1837
+ let r = e;
1838
+ for (; r < s.length && /\w/.test(s[r]); ) r++;
1839
+ return i === r ? null : { word: s.slice(i, r), from: i, to: r };
1840
+ },
1841
+ onCursorMove(e) {
1842
+ return t._cursorCallbacks.add(e), () => {
1843
+ t._cursorCallbacks.delete(e);
1844
+ };
1845
+ },
1846
+ addDecoration(e) {
1847
+ return at(t._pluginDecorations, e);
1848
+ },
1849
+ removeDecoration(e) {
1850
+ t._pluginDecorations.delete(e);
1851
+ },
1852
+ clearDecorations() {
1853
+ t._pluginDecorations.clear();
1854
+ },
1855
+ setDecorations(e) {
1856
+ oe(t._pluginDecorations, e);
1857
+ },
1858
+ getDecorations() {
1859
+ return [...t._pluginDecorations.values()];
1860
+ },
1861
+ scheduleUpdate() {
1862
+ t._isRendering || t._scheduleRender();
1863
+ },
1864
+ adoptStyleSheet(e) {
1865
+ let s;
1866
+ typeof e == "string" ? (s = new CSSStyleSheet(), s.replaceSync(e)) : s = e;
1867
+ const i = t.shadowRoot;
1868
+ return i && !i.adoptedStyleSheets.includes(s) && (i.adoptedStyleSheets = [...i.adoptedStyleSheets, s]), t._pluginSheets.add(s), s;
1869
+ },
1870
+ removeStyleSheet(e) {
1871
+ const s = t.shadowRoot;
1872
+ s && (s.adoptedStyleSheets = s.adoptedStyleSheets.filter(
1873
+ (i) => i !== e
1874
+ )), t._pluginSheets.delete(e);
1875
+ },
1876
+ decorationsFromHtml(e) {
1877
+ return lt(e);
1878
+ },
1879
+ decorationsFromTokens(e, s) {
1880
+ const i = [];
1881
+ for (const r of e) {
1882
+ const o = s[r.type];
1883
+ o && i.push({ type: "mark", from: r.from, to: r.to, ...o });
1884
+ }
1885
+ return i;
1886
+ },
1887
+ insertText(e) {
1888
+ t._insertText(e);
1889
+ },
1890
+ wrapSelection(e, s) {
1891
+ t.wrapSelection(e, s);
1892
+ },
1893
+ replaceSelection(e) {
1894
+ t.replaceSelection(e);
1895
+ }
1896
+ };
1897
+ }
1898
+ _clearPluginSheets() {
1899
+ if (this._pluginSheets.size === 0) return;
1900
+ const t = this.shadowRoot;
1901
+ t && (t.adoptedStyleSheets = t.adoptedStyleSheets.filter(
1902
+ (e) => !this._pluginSheets.has(e)
1903
+ )), this._pluginSheets.clear();
1904
+ }
1905
+ // ── Pattern API ───────────────────────────────────────────────────────
1906
+ addPattern(t) {
1907
+ const e = M();
1908
+ return this._patterns.set(e, { ...t, id: e }), this._scheduleRender(), e;
1909
+ }
1910
+ removePattern(t) {
1911
+ this._patterns.delete(t), this._scheduleRender();
1912
+ }
1913
+ clearPatterns() {
1914
+ this._patterns.clear(), this._scheduleRender();
1915
+ }
1916
+ // ── Render pipeline ───────────────────────────────────────────────────
1917
+ _scheduleRender() {
1918
+ this._rafHandle === null && (this._rafHandle = requestAnimationFrame(() => {
1919
+ this._rafHandle = null, this._performRender();
1920
+ }));
1921
+ }
1922
+ async _performRender() {
1923
+ if (!this._document) return;
1924
+ this._isRendering = !0;
1925
+ const t = ++this._pluginSeq;
1926
+ try {
1927
+ let e = this._value;
1928
+ if (this._plugin && this._pluginApi && this._plugin.transform && this.readOnly) {
1929
+ const a = this._plugin.transform(this._value, this._pluginApi);
1930
+ typeof a == "string" && (e = a);
1931
+ }
1932
+ const { markDecorations: s, lineDecorations: i } = ae(e, [...this._patterns.values()]);
1933
+ if (this._patternDecorations = [
1934
+ ...s.map((a) => ({ ...a, id: M() })),
1935
+ ...i.map((a) => ({ ...a, id: M() }))
1936
+ ], this._plugin && this._pluginApi) {
1937
+ const a = this._pluginApi;
1938
+ if (this._plugin.update && (await this._plugin.update(e, a), t !== this._pluginSeq))
1939
+ return;
1940
+ if (this._plugin.highlight) {
1941
+ const l = await this._plugin.highlight(e, a);
1942
+ if (t !== this._pluginSeq) return;
1943
+ if (typeof l == "string") {
1944
+ const h = lt(l);
1945
+ for (const c of h)
1946
+ at(this._pluginDecorations, c);
1947
+ }
1948
+ }
1949
+ }
1950
+ const r = [
1951
+ ...this._pluginDecorations.values(),
1952
+ ...this._patternDecorations,
1953
+ ...this._externalDecorations.map((a) => ({ ...a, id: M() }))
1954
+ ], o = this._getEditorEl();
1955
+ if (!o) return;
1956
+ this._document.build(e, r), this._savedSelection && se(o, this._savedSelection), this._activeLine = null, this._updateActiveLine(), this._syncGutter(this._computeGutterLabels(r, e)), this._syncGutterHeights();
1957
+ } finally {
1958
+ this._isRendering = !1;
1959
+ }
1960
+ }
1961
+ // ── Gutter ────────────────────────────────────────────────────────────
1962
+ /**
1963
+ * Compute the label string for each gutter cell based on the current gutter
1964
+ * mode (`lineNumbers`, `listNumbers`, `gutter`) and any
1965
+ * `LineDecoration.gutterContent` overrides in `allDecorations`.
1966
+ *
1967
+ * Returns one entry per line (same length as `value.split('\n')`):
1968
+ * - `string` — the label to display
1969
+ * - `null` — render an empty cell
1970
+ */
1971
+ _computeGutterLabels(t, e = this._value) {
1972
+ const s = e.split(`
1973
+ `), i = /* @__PURE__ */ new Map();
1974
+ for (const o of t)
1975
+ o.type === "line" && o.gutterContent !== void 0 && i.set(o.line, o.gutterContent);
1976
+ let r = 0;
1977
+ return s.map((o, a) => {
1978
+ const l = a + 1;
1979
+ return i.has(l) ? i.get(l) : this.lineNumbers ? String(l) : this.listNumbers ? o.trim() === "" ? null : (r++, `${r}.`) : null;
1980
+ });
1981
+ }
1982
+ /**
1983
+ * Synchronize the pixel height of each gutter cell to match the
1984
+ * corresponding `.v2-line` element in the editor.
1985
+ *
1986
+ * In non-word-wrap mode the gutter uses a uniform `line-height` mirrored
1987
+ * from the editor's first line. In word-wrap mode each cell gets an explicit
1988
+ * `height` so wrapped lines stay vertically aligned with their gutter label.
1989
+ * Also copies the editor's computed `paddingTop`/`paddingBottom` to the
1990
+ * gutter to compensate for browser UA overrides on contenteditable.
1991
+ */
1992
+ _syncGutterHeights() {
1993
+ const t = this.shadowRoot?.getElementById("gutter-cells"), e = this._getEditorEl();
1994
+ if (!t || !e) return;
1995
+ const s = getComputedStyle(e), i = s.paddingTop, r = s.paddingBottom;
1996
+ t.style.paddingTop !== i && (t.style.paddingTop = i), t.style.paddingBottom !== r && (t.style.paddingBottom = r);
1997
+ const o = e.querySelectorAll(".v2-line"), a = t.children;
1998
+ if (!this.wordWrap) {
1999
+ if (o.length > 0) {
2000
+ const l = `${o[0].getBoundingClientRect().height}px`;
2001
+ t.style.lineHeight !== l && (t.style.lineHeight = l);
2002
+ }
2003
+ for (let l = 0; l < a.length; l++)
2004
+ a[l].style.height = "";
2005
+ return;
2006
+ }
2007
+ t.style.lineHeight && (t.style.lineHeight = "");
2008
+ for (let l = 0; l < o.length && l < a.length; l++) {
2009
+ const c = `${o[l].getBoundingClientRect().height}px`, d = a[l];
2010
+ d.style.height !== c && (d.style.height = c);
2011
+ }
2012
+ }
2013
+ /**
2014
+ * Add, remove, or update `.gutter-cell` spans so their count and text
2015
+ * content match `labels`. When `labels` is provided the cached
2016
+ * `_gutterLabels` is updated first; otherwise the cached labels are reused
2017
+ * (called by the `ResizeObserver` without a new render pass).
2018
+ */
2019
+ _syncGutter(t) {
2020
+ if (!this.lineNumbers && !this.listNumbers && !this.gutter) return;
2021
+ const e = this.shadowRoot?.getElementById("gutter-cells");
2022
+ if (!e) return;
2023
+ t !== void 0 && (this._gutterLabels = t);
2024
+ const s = this._gutterLabels;
2025
+ for (; e.children.length < s.length; ) {
2026
+ const i = document.createElement("span");
2027
+ i.className = "gutter-cell", e.appendChild(i);
2028
+ }
2029
+ for (; e.children.length > s.length; )
2030
+ e.removeChild(e.lastChild);
2031
+ for (let i = 0; i < s.length; i++) {
2032
+ const r = s[i] ?? "", o = e.children[i];
2033
+ o.textContent !== r && (o.textContent = r);
2034
+ }
2035
+ }
2036
+ // ── Typography sync ───────────────────────────────────────────────────
2037
+ _syncTypography(t) {
2038
+ const e = this._getEditorEl();
2039
+ if (!e) return;
2040
+ const s = window.getComputedStyle(t), i = [
2041
+ "fontFamily",
2042
+ "fontSize",
2043
+ "fontWeight",
2044
+ "fontStyle",
2045
+ "fontVariant",
2046
+ "lineHeight",
2047
+ "letterSpacing",
2048
+ "wordSpacing",
2049
+ "textIndent",
2050
+ "tabSize"
2051
+ ];
2052
+ if (!window.getComputedStyle(this).getPropertyValue("--rc-textarea-font-family"))
2053
+ for (const o of i) {
2054
+ const a = s[o];
2055
+ a && typeof a == "string" && (e.style[o] = a);
2056
+ }
2057
+ }
2058
+ // ── Form integration ──────────────────────────────────────────────────
2059
+ _syncTextareaValue(t = !1) {
2060
+ const e = this._textareaRef?.deref();
2061
+ e && (e.value = this._value, t && e.dispatchEvent(new InputEvent("input", { bubbles: !0 })));
2062
+ }
2063
+ _dispatchChange(t) {
2064
+ this.dispatchEvent(
2065
+ new CustomEvent("rc-textarea-change", {
2066
+ bubbles: !0,
2067
+ composed: !0,
2068
+ detail: { value: t }
2069
+ })
2070
+ );
2071
+ }
2072
+ // ── Helpers ───────────────────────────────────────────────────────────
2073
+ _getEditorEl() {
2074
+ return this.shadowRoot?.getElementById("editor");
2075
+ }
2076
+ };
2077
+ q.styles = Tt, q.shadowRootOptions = {
2078
+ ...tt.shadowRootOptions,
2079
+ delegatesFocus: !0
2080
+ };
2081
+ let _ = q;
2082
+ y([
2083
+ b({ type: Boolean, attribute: "line-numbers", reflect: !0 })
2084
+ ], _.prototype, "lineNumbers", 2);
2085
+ y([
2086
+ b({ type: Boolean, attribute: "list-numbers", reflect: !0 })
2087
+ ], _.prototype, "listNumbers", 2);
2088
+ y([
2089
+ b({ type: Boolean, attribute: "gutter", reflect: !0 })
2090
+ ], _.prototype, "gutter", 2);
2091
+ y([
2092
+ b({ type: Boolean, attribute: "word-wrap", reflect: !0 })
2093
+ ], _.prototype, "wordWrap", 2);
2094
+ y([
2095
+ b({ type: Boolean, attribute: "auto-grow", reflect: !0 })
2096
+ ], _.prototype, "autoGrow", 2);
2097
+ y([
2098
+ b({ type: Boolean, attribute: "read-only", reflect: !0 })
2099
+ ], _.prototype, "readOnly", 2);
2100
+ y([
2101
+ b({ type: String })
2102
+ ], _.prototype, "label", 2);
2103
+ y([
2104
+ b({ attribute: !1 })
2105
+ ], _.prototype, "plugin", 1);
2106
+ y([
2107
+ b({ attribute: !1 })
2108
+ ], _.prototype, "decorations", 1);
2109
+ y([
2110
+ b({ type: String })
2111
+ ], _.prototype, "value", 1);
2112
+ y([
2113
+ b({ type: String })
2114
+ ], _.prototype, "defaultValue", 1);
2115
+ function ye(n, t = {}) {
2116
+ const e = [];
2117
+ return {
2118
+ mount(s) {
2119
+ n.styles && s.adoptStyleSheet(n.styles);
2120
+ for (const i of t.watch ?? []) {
2121
+ const r = i(() => s.scheduleUpdate());
2122
+ r && e.push(r);
2123
+ }
2124
+ },
2125
+ destroy() {
2126
+ for (const s of e) s();
2127
+ e.length = 0;
2128
+ },
2129
+ update(s, i) {
2130
+ const r = s.split(`
2131
+ `), o = [];
2132
+ let a = 0;
2133
+ for (let l = 0; l < r.length; l++) {
2134
+ const h = r[l];
2135
+ for (const c of n.decorateLine(h, l))
2136
+ c.type === "mark" ? o.push({
2137
+ ...c,
2138
+ from: a + c.from,
2139
+ to: a + c.to
2140
+ }) : o.push(c);
2141
+ a += h.length + 1;
2142
+ }
2143
+ t.extraDecorations && o.push(...t.extraDecorations(s)), i.setDecorations(o);
2144
+ }
2145
+ };
2146
+ }
2147
+ const xt = new CSSStyleSheet();
2148
+ xt.replaceSync(`
2149
+ .rc-line-actions {
2150
+ display: inline-flex;
2151
+ align-items: center;
2152
+ gap: var(--rc-line-actions-gap, 2px);
2153
+ margin-left: var(--rc-line-actions-margin-start, 6px);
2154
+ vertical-align: middle;
2155
+ }
2156
+ .rc-line-action-btn {
2157
+ display: inline-flex;
2158
+ align-items: center;
2159
+ justify-content: center;
2160
+ padding: var(--rc-line-action-padding, 1px);
2161
+ border: var(--rc-line-action-border, none);
2162
+ border-radius: var(--rc-line-action-border-radius, 3px);
2163
+ background: var(--rc-line-action-bg, transparent);
2164
+ color: var(--rc-line-action-color, inherit);
2165
+ font-size: var(--rc-line-action-font-size, 1em);
2166
+ cursor: pointer;
2167
+ user-select: none;
2168
+ line-height: 1;
2169
+ opacity: var(--rc-line-action-opacity, 0.4);
2170
+ transition: opacity 0.1s;
2171
+ }
2172
+ .rc-line-action-btn:hover {
2173
+ opacity: var(--rc-line-action-hover-opacity, 1);
2174
+ background: var(--rc-line-action-hover-bg, transparent);
2175
+ color: var(--rc-line-action-hover-color, inherit);
2176
+ }
2177
+ `);
2178
+ const ct = "rc-line-actions-popover-style", ue = `
2179
+ .rc-line-actions-popover {
2180
+ position: fixed;
2181
+ z-index: 9999;
2182
+ display: flex;
2183
+ align-items: center;
2184
+ gap: var(--rc-line-actions-gap, 4px);
2185
+ padding: 4px 8px;
2186
+ background: var(--rc-line-action-bg, Canvas);
2187
+ border: var(--rc-line-action-border, 1px solid ButtonBorder);
2188
+ border-radius: var(--rc-line-action-border-radius, 4px);
2189
+ box-shadow: var(
2190
+ --rc-line-action-shadow,
2191
+ 0 2px 8px color-mix(in srgb, CanvasText 15%, transparent)
2192
+ );
2193
+ }
2194
+ .rc-line-actions-popover .rc-line-action-btn {
2195
+ display: inline-flex;
2196
+ align-items: center;
2197
+ justify-content: center;
2198
+ gap: 4px;
2199
+ padding: var(--rc-line-action-padding, 4px 6px);
2200
+ border: var(--rc-line-action-border, none);
2201
+ border-radius: var(--rc-line-action-border-radius, 3px);
2202
+ background: var(--rc-line-action-bg, transparent);
2203
+ color: var(--rc-line-action-color, ButtonText);
2204
+ font-size: var(--rc-line-action-font-size, 0.85em);
2205
+ cursor: pointer;
2206
+ user-select: none;
2207
+ line-height: 1.4;
2208
+ white-space: nowrap;
2209
+ }
2210
+ .rc-line-actions-popover .rc-line-action-btn:hover {
2211
+ background: var(--rc-line-action-hover-bg, ButtonFace);
2212
+ }
2213
+ `;
2214
+ class wt {
2215
+ constructor(t, e) {
2216
+ this._popover = null, this._lastActionsKey = "", this._api = t, this._options = e ?? {}, t.adoptStyleSheet(xt), this._blurHandler = () => this._hidePopover(), t.host.addEventListener("rc-textarea-blur", this._blurHandler);
2217
+ }
2218
+ /**
2219
+ * Call from plugin's `update()`. Pass the line index, its actions, the full
2220
+ * value, and the current render mode.
2221
+ *
2222
+ * - `'inline'`: returns a `WidgetDecoration[]` to merge into `setDecorations()`.
2223
+ * - `'popover'`: returns `[]` and manages a floating panel as a side effect.
2224
+ *
2225
+ * Passing an empty actions array hides the popover and returns `[]`.
2226
+ */
2227
+ getDecorations(t, e, s, i) {
2228
+ if (i === "popover")
2229
+ return e.length === 0 ? this._hidePopover() : this._showPopover(e), [];
2230
+ if (this._hidePopover(), e.length === 0) return [];
2231
+ const r = wt._lineEndOffset(s, t), o = [...e], a = { renderButton: this._options.renderButton, createIcon: this._options.createIcon };
2232
+ return [
2233
+ {
2234
+ type: "widget",
2235
+ offset: r,
2236
+ side: "after",
2237
+ create() {
2238
+ return de(o, a);
2239
+ }
2240
+ }
2241
+ ];
2242
+ }
2243
+ /**
2244
+ * Variant for `showOn: 'always'` — one entry per line with actions.
2245
+ *
2246
+ * In popover mode only the `activeLineIndex` line is shown; in inline mode
2247
+ * every line with non-empty actions gets a widget.
2248
+ */
2249
+ getDecorationsForLines(t, e, s, i) {
2250
+ if (s === "popover") {
2251
+ if (i === void 0)
2252
+ return this._hidePopover(), [];
2253
+ const o = t.get(i) ?? [];
2254
+ return this.getDecorations(i, o, e, "popover");
2255
+ }
2256
+ this._hidePopover();
2257
+ const r = [];
2258
+ for (const [o, a] of t)
2259
+ a.length > 0 && r.push(...this.getDecorations(o, a, e, "inline"));
2260
+ return r;
2261
+ }
2262
+ /** Remove the floating panel and detach all listeners. Call from plugin `destroy()`. */
2263
+ destroy() {
2264
+ this._hidePopover(), this._api.host.removeEventListener("rc-textarea-blur", this._blurHandler);
2265
+ }
2266
+ /** Derive the 0-based line index from a plain-text character offset. */
2267
+ static getActiveLineIndex(t, e) {
2268
+ return t.slice(0, e).split(`
2269
+ `).length - 1;
2270
+ }
2271
+ // ── Private helpers ───────────────────────────────────────────────────────
2272
+ /**
2273
+ * Character offset of the end of the given 0-based line (points at the
2274
+ * newline character, or end-of-string for the last line).
2275
+ */
2276
+ static _lineEndOffset(t, e) {
2277
+ const s = t.split(`
2278
+ `);
2279
+ let i = 0;
2280
+ for (let r = 0; r < e && r < s.length; r++)
2281
+ i += s[r].length + 1;
2282
+ return e < s.length && (i += s[e].length), i;
2283
+ }
2284
+ _showPopover(t) {
2285
+ const e = t.map((s) => s.id).join(",");
2286
+ if (!document.getElementById(ct)) {
2287
+ const s = document.createElement("style");
2288
+ s.id = ct, s.textContent = ue, document.head.appendChild(s);
2289
+ }
2290
+ this._popover || (this._popover = document.createElement("div"), this._popover.className = "rc-line-actions-popover", this._popover.addEventListener("mousedown", (s) => s.preventDefault()), document.body.appendChild(this._popover)), e !== this._lastActionsKey && (this._lastActionsKey = e, this._popover.innerHTML = "", fe(this._popover, t, this._options)), this._positionPopover();
2291
+ }
2292
+ _positionPopover() {
2293
+ if (!this._popover) return;
2294
+ const t = this._api.getCursorRect(), e = this._api.host.getBoundingClientRect();
2295
+ let s;
2296
+ const i = this._popover.offsetHeight || 32;
2297
+ t ? (s = t.bottom + 4, s + i > window.innerHeight && (s = t.top - i - 4)) : s = e.bottom + 4;
2298
+ const r = this._popover.offsetWidth || 120;
2299
+ let o = e.left;
2300
+ o = Math.min(o, window.innerWidth - r - 8), o = Math.max(o, 8), this._popover.style.top = `${s}px`, this._popover.style.left = `${o}px`;
2301
+ }
2302
+ _hidePopover() {
2303
+ this._popover && (this._popover.remove(), this._popover = null, this._lastActionsKey = "");
2304
+ }
2305
+ }
2306
+ function At(n, t) {
2307
+ const e = document.createElement("button");
2308
+ if (e.className = "rc-line-action-btn", e.type = "button", e.setAttribute("title", n.label), t.renderButton)
2309
+ t.renderButton(n, e);
2310
+ else if (n.icon) {
2311
+ const s = t.createIcon?.(n.icon) ?? null;
2312
+ s ? (e.setAttribute("aria-label", n.label), e.appendChild(s)) : (e.dataset.icon = n.icon, e.setAttribute("aria-label", n.label));
2313
+ } else
2314
+ e.textContent = n.label;
2315
+ return e.addEventListener("mousedown", (s) => s.preventDefault()), e.addEventListener("click", () => n.onClick()), e;
2316
+ }
2317
+ function de(n, t) {
2318
+ const e = document.createElement("span");
2319
+ e.className = "rc-line-actions";
2320
+ for (const s of n)
2321
+ e.appendChild(At(s, t));
2322
+ return e;
2323
+ }
2324
+ function fe(n, t, e) {
2325
+ for (const s of t)
2326
+ n.appendChild(At(s, e));
2327
+ }
2328
+ export {
2329
+ wt as L,
2330
+ _ as R,
2331
+ ye as c,
2332
+ ae as m
2333
+ };
2334
+ //# sourceMappingURL=line-actions-controller-BsM6DJ0b.js.map