@synclineapi/editor 4.0.1 → 4.0.3

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.
@@ -0,0 +1,4635 @@
1
+ var De = Object.defineProperty;
2
+ var He = (s, e, t) => e in s ? De(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
+ var g = (s, e, t) => He(s, typeof e != "symbol" ? e + "" : e, t);
4
+ const Re = {
5
+ typescript: "//",
6
+ javascript: "//",
7
+ css: "//",
8
+ json: "",
9
+ markdown: "",
10
+ text: ""
11
+ }, se = /* @__PURE__ */ new Set([
12
+ "function",
13
+ "const",
14
+ "let",
15
+ "var",
16
+ "return",
17
+ "if",
18
+ "else",
19
+ "for",
20
+ "while",
21
+ "class",
22
+ "import",
23
+ "export",
24
+ "default",
25
+ "async",
26
+ "await",
27
+ "new",
28
+ "this",
29
+ "typeof",
30
+ "instanceof",
31
+ "try",
32
+ "catch",
33
+ "finally",
34
+ "throw",
35
+ "extends",
36
+ "interface",
37
+ "type",
38
+ "readonly",
39
+ "private",
40
+ "public",
41
+ "protected",
42
+ "static",
43
+ "override",
44
+ "implements",
45
+ "enum",
46
+ "namespace",
47
+ "declare",
48
+ "abstract",
49
+ "as",
50
+ "from",
51
+ "of",
52
+ "in",
53
+ "void",
54
+ "switch",
55
+ "case",
56
+ "break",
57
+ "continue",
58
+ "do",
59
+ "delete",
60
+ "yield",
61
+ "super",
62
+ "null",
63
+ "true",
64
+ "false",
65
+ "undefined",
66
+ "require",
67
+ "constructor"
68
+ ]), Be = /* @__PURE__ */ new Set([
69
+ "function",
70
+ "const",
71
+ "let",
72
+ "var",
73
+ "return",
74
+ "if",
75
+ "else",
76
+ "for",
77
+ "while",
78
+ "class",
79
+ "import",
80
+ "export",
81
+ "default",
82
+ "async",
83
+ "await",
84
+ "new",
85
+ "this",
86
+ "typeof",
87
+ "instanceof",
88
+ "try",
89
+ "catch",
90
+ "finally",
91
+ "throw",
92
+ "extends",
93
+ "as",
94
+ "from",
95
+ "of",
96
+ "in",
97
+ "void",
98
+ "switch",
99
+ "case",
100
+ "break",
101
+ "continue",
102
+ "do",
103
+ "delete",
104
+ "yield",
105
+ "super",
106
+ "null",
107
+ "true",
108
+ "false",
109
+ "undefined",
110
+ "require",
111
+ "constructor",
112
+ "static"
113
+ ]), je = /* @__PURE__ */ new Set([
114
+ // At-rules (without @)
115
+ "media",
116
+ "keyframes",
117
+ "import",
118
+ "charset",
119
+ "supports",
120
+ "layer",
121
+ "container",
122
+ "namespace",
123
+ "page",
124
+ // Position values
125
+ "static",
126
+ "relative",
127
+ "absolute",
128
+ "fixed",
129
+ "sticky",
130
+ // Display values
131
+ "block",
132
+ "inline",
133
+ "flex",
134
+ "grid",
135
+ "none",
136
+ "contents",
137
+ "table",
138
+ // Overflow / visibility
139
+ "hidden",
140
+ "visible",
141
+ "scroll",
142
+ "clip",
143
+ "auto",
144
+ // Text / font values
145
+ "bold",
146
+ "normal",
147
+ "italic",
148
+ "underline",
149
+ "uppercase",
150
+ "lowercase",
151
+ "capitalize",
152
+ "left",
153
+ "right",
154
+ "center",
155
+ "justify",
156
+ // Sizing keywords
157
+ "inherit",
158
+ "initial",
159
+ "unset",
160
+ "revert",
161
+ // Misc values
162
+ "pointer",
163
+ "default",
164
+ "transparent",
165
+ "solid",
166
+ "dashed",
167
+ "dotted",
168
+ "double",
169
+ "cover",
170
+ "contain",
171
+ "no-repeat",
172
+ "repeat",
173
+ // CSS functions (used as values)
174
+ "var",
175
+ "calc",
176
+ "min",
177
+ "max",
178
+ "clamp"
179
+ ]), Pe = /* @__PURE__ */ new Set(["null", "true", "false"]), pe = /* @__PURE__ */ new Set(), oe = /* @__PURE__ */ new Set([
180
+ "number",
181
+ "string",
182
+ "boolean",
183
+ "any",
184
+ "never",
185
+ "unknown",
186
+ "object",
187
+ "Promise",
188
+ "Array",
189
+ "Map",
190
+ "Set",
191
+ "Record",
192
+ "Partial",
193
+ "Required",
194
+ "Readonly",
195
+ "HTMLElement",
196
+ "KeyboardEvent",
197
+ "Float64Array",
198
+ "EventListener",
199
+ "Document",
200
+ "Window",
201
+ "Node",
202
+ "Element",
203
+ "Event",
204
+ "MouseEvent",
205
+ "CustomEvent"
206
+ ]), $e = /* @__PURE__ */ new Set([
207
+ "number",
208
+ "string",
209
+ "boolean",
210
+ "object",
211
+ "Promise",
212
+ "Array",
213
+ "Map",
214
+ "Set",
215
+ "HTMLElement",
216
+ "KeyboardEvent",
217
+ "Float64Array",
218
+ "EventListener",
219
+ "Document",
220
+ "Window",
221
+ "Node",
222
+ "Element",
223
+ "Event",
224
+ "MouseEvent",
225
+ "CustomEvent"
226
+ ]), We = /* @__PURE__ */ new Set(), Ne = /* @__PURE__ */ new Set(), he = /* @__PURE__ */ new Set(), Me = {
227
+ typescript: se,
228
+ javascript: Be,
229
+ css: je,
230
+ json: Pe,
231
+ markdown: pe,
232
+ text: pe
233
+ }, Ee = {
234
+ typescript: oe,
235
+ javascript: $e,
236
+ css: We,
237
+ json: Ne,
238
+ markdown: he,
239
+ text: he
240
+ };
241
+ function ue(s, e) {
242
+ return {
243
+ fileId: s,
244
+ doc: [...e],
245
+ cur: { row: 0, col: 0 },
246
+ sel: null,
247
+ dirty: !1,
248
+ undoStack: [],
249
+ redoStack: [],
250
+ scrollTop: 0
251
+ };
252
+ }
253
+ function L(s, e = 300) {
254
+ const t = {
255
+ doc: [...s.doc],
256
+ cur: { ...s.cur },
257
+ sel: s.sel ? { ...s.sel } : null
258
+ };
259
+ s.undoStack.push(t), s.undoStack.length > e && s.undoStack.shift(), s.redoStack = [], s.dirty = !0;
260
+ }
261
+ function Oe(s) {
262
+ if (!s.undoStack.length) return !1;
263
+ const e = {
264
+ doc: [...s.doc],
265
+ cur: { ...s.cur },
266
+ sel: s.sel ? { ...s.sel } : null
267
+ };
268
+ s.redoStack.push(e);
269
+ const t = s.undoStack.pop();
270
+ return s.doc = t.doc, s.cur = t.cur, s.sel = t.sel, !0;
271
+ }
272
+ function Fe(s) {
273
+ if (!s.redoStack.length) return !1;
274
+ const e = {
275
+ doc: [...s.doc],
276
+ cur: { ...s.cur },
277
+ sel: s.sel ? { ...s.sel } : null
278
+ };
279
+ s.undoStack.push(e);
280
+ const t = s.redoStack.pop();
281
+ return s.doc = t.doc, s.cur = t.cur, s.sel = t.sel, !0;
282
+ }
283
+ function S(s) {
284
+ const { doc: e, cur: t } = s;
285
+ t.row = Math.max(0, Math.min(e.length - 1, t.row)), t.col = Math.max(0, Math.min((e[t.row] ?? "").length, t.col));
286
+ }
287
+ function $(s) {
288
+ const { ar: e, ac: t, fr: i, fc: n } = s;
289
+ return e < i || e === i && t <= n ? s : { ar: i, ac: n, fr: e, fc: t };
290
+ }
291
+ function fe(s, e, t) {
292
+ if (!s) return null;
293
+ const i = $(s);
294
+ return e < i.ar || e > i.fr ? null : {
295
+ start: e === i.ar ? i.ac : 0,
296
+ end: e === i.fr ? i.fc : t
297
+ };
298
+ }
299
+ function Ue(s) {
300
+ if (!s.sel) return 0;
301
+ const e = $(s.sel);
302
+ let t = 0;
303
+ for (let i = e.ar; i <= e.fr; i++) {
304
+ const n = s.doc[i] ?? "", r = i === e.ar ? e.ac : 0, o = i === e.fr ? e.fc : n.length;
305
+ t += o - r;
306
+ }
307
+ return t;
308
+ }
309
+ function ge(s) {
310
+ if (!s.sel) return "";
311
+ const e = $(s.sel), t = [];
312
+ for (let i = e.ar; i <= e.fr; i++) {
313
+ const n = s.doc[i] ?? "";
314
+ t.push(n.slice(i === e.ar ? e.ac : 0, i === e.fr ? e.fc : n.length));
315
+ }
316
+ return t.join(`
317
+ `);
318
+ }
319
+ function G(s) {
320
+ const e = s.sel;
321
+ if (!e) return s.cur;
322
+ const t = $(e), i = (s.doc[t.ar] ?? "").slice(0, t.ac), n = (s.doc[t.fr] ?? "").slice(t.fc);
323
+ return s.doc.splice(t.ar, t.fr - t.ar + 1, i + n), s.sel = null, { row: t.ar, col: t.ac };
324
+ }
325
+ function Ge(s, e, t) {
326
+ if (!t || s.length <= e) return [s];
327
+ const i = [];
328
+ let n = 0;
329
+ for (; n < s.length; ) {
330
+ if (s.length - n <= e) {
331
+ i.push(s.slice(n));
332
+ break;
333
+ }
334
+ const r = n + e;
335
+ let o = -1;
336
+ for (let l = r; l > n; l--)
337
+ if (s[l - 1] === " ") {
338
+ o = l;
339
+ break;
340
+ }
341
+ o === -1 ? (i.push(s.slice(n, r)), n = r) : (i.push(s.slice(n, o)), n = o);
342
+ }
343
+ return i;
344
+ }
345
+ function ze(s, e, t, i) {
346
+ const n = [], r = [], o = [];
347
+ let l = -1;
348
+ for (let a = 0; a < s.length; a++) {
349
+ if (a > 0 && a <= l) {
350
+ o.push(r.length), n.push([s[a] ?? ""]);
351
+ continue;
352
+ }
353
+ o.push(r.length);
354
+ const c = Ge(s[a] ?? "", e, t);
355
+ n.push(c), c.forEach((d, h) => r.push({ docLine: a, segIdx: h, text: d })), i.has(a) && (l = i.get(a));
356
+ }
357
+ return { segments: n, visualRows: r, docToVisArr: o };
358
+ }
359
+ function F(s, e, t) {
360
+ const i = s.segments[e] ?? [""];
361
+ let n = t;
362
+ for (let r = 0; r < i.length; r++) {
363
+ if (n <= i[r].length || r === i.length - 1)
364
+ return {
365
+ visRow: s.docToVisArr[e] + r,
366
+ colInSeg: Math.min(n, i[r].length)
367
+ };
368
+ n -= i[r].length;
369
+ }
370
+ return { visRow: s.docToVisArr[e] ?? 0, colInSeg: 0 };
371
+ }
372
+ function Y(s, e, t) {
373
+ var o;
374
+ const i = s.visualRows[e];
375
+ if (!i) return { row: 0, col: 0 };
376
+ const n = s.segments[i.docLine] ?? [""];
377
+ let r = Math.min(t, ((o = n[i.segIdx]) == null ? void 0 : o.length) ?? 0);
378
+ for (let l = 0; l < i.segIdx; l++) r += n[l].length;
379
+ return { row: i.docLine, col: r };
380
+ }
381
+ function ae(s, e = {}) {
382
+ var d, h;
383
+ const t = [], i = s.length;
384
+ let n = 0;
385
+ const r = (p, f, _) => {
386
+ _ > f && t.push({ cls: p, start: f, end: _ });
387
+ }, o = Me[e.language ?? "typescript"] ?? se, l = Ee[e.language ?? "typescript"] ?? oe, a = (d = e.extraKeywords) != null && d.size ? /* @__PURE__ */ new Set([...o, ...e.extraKeywords]) : o, c = (h = e.extraTypes) != null && h.size ? /* @__PURE__ */ new Set([...l, ...e.extraTypes]) : l;
388
+ for (; n < i; ) {
389
+ if (s[n] === "/" && s[n + 1] === "/") {
390
+ r("cmt", n, i);
391
+ break;
392
+ }
393
+ if (s[n] === "*" || s[n] === "/" && s[n + 1] === "*") {
394
+ r("cmt", n, i);
395
+ break;
396
+ }
397
+ if (s[n] === "@") {
398
+ let p = n + 1;
399
+ for (; p < i && /\w/.test(s[p]); ) p++;
400
+ r("dec", n, p), n = p;
401
+ continue;
402
+ }
403
+ if (s[n] === '"' || s[n] === "'" || s[n] === "`") {
404
+ const p = s[n];
405
+ let f = n + 1;
406
+ for (; f < i; ) {
407
+ if (s[f] === "\\") {
408
+ f += 2;
409
+ continue;
410
+ }
411
+ if (s[f] === p) {
412
+ f++;
413
+ break;
414
+ }
415
+ f++;
416
+ }
417
+ r("str", n, f), n = f;
418
+ continue;
419
+ }
420
+ if (/\d/.test(s[n]) && (n === 0 || !/\w/.test(s[n - 1]))) {
421
+ let p = n;
422
+ for (; p < i && /[\d._xXa-fA-F]/.test(s[p]); ) p++;
423
+ r("num", n, p), n = p;
424
+ continue;
425
+ }
426
+ if (/[a-zA-Z_$]/.test(s[n])) {
427
+ let p = n;
428
+ for (; p < i && /[\w$]/.test(s[p]); ) p++;
429
+ const f = s.slice(n, p);
430
+ a.has(f) ? r("kw", n, p) : c.has(f) ? r("typ", n, p) : p < i && s[p] === "(" ? r("fn", n, p) : /^[A-Z]/.test(f) && r("cls", n, p), n = p;
431
+ continue;
432
+ }
433
+ if (/[=<>!&|+\-*/%^~?:,;.[\]{}()]/.test(s[n])) {
434
+ r("op", n, n + 1), n++;
435
+ continue;
436
+ }
437
+ n++;
438
+ }
439
+ return t;
440
+ }
441
+ function Le(s, e) {
442
+ const t = new Array(s.length).fill("");
443
+ for (const i of e)
444
+ for (let n = i.start; n < i.end; n++) t[n] = i.cls;
445
+ return t;
446
+ }
447
+ class qe {
448
+ constructor(e = 5e3) {
449
+ g(this, "_cache", /* @__PURE__ */ new Map());
450
+ g(this, "_maxSize");
451
+ // ── Performance counters ──────────────────────────────────
452
+ g(this, "_hits", 0);
453
+ g(this, "_misses", 0);
454
+ g(this, "_evictions", 0);
455
+ this._maxSize = e;
456
+ }
457
+ /** Live snapshot of cache performance. Useful for observability. */
458
+ get metrics() {
459
+ return {
460
+ hits: this._hits,
461
+ misses: this._misses,
462
+ evictions: this._evictions,
463
+ size: this._cache.size
464
+ };
465
+ }
466
+ get(e, t) {
467
+ const i = this._cache.get(e);
468
+ return i && i.src === t ? (this._hits++, i.segs) : (this._misses++, null);
469
+ }
470
+ set(e, t, i) {
471
+ this._cache.size >= this._maxSize && (this._cache.delete(this._cache.keys().next().value), this._evictions++), this._cache.set(e, { src: t, segs: i });
472
+ }
473
+ invalidateLine(e, t) {
474
+ for (let i = 0; i < t; i++)
475
+ this._cache.delete(`${e}:${i}`);
476
+ }
477
+ /** Clear all cached entries and reset performance counters. */
478
+ clear() {
479
+ this._cache.clear(), this._hits = 0, this._misses = 0, this._evictions = 0;
480
+ }
481
+ /** Reset performance counters without clearing cached entries. */
482
+ resetMetrics() {
483
+ this._hits = 0, this._misses = 0, this._evictions = 0;
484
+ }
485
+ }
486
+ const Ke = {
487
+ id: "",
488
+ name: "VR Dark",
489
+ description: "Default deep dark theme",
490
+ light: !1,
491
+ tokens: {
492
+ bg0: "#0d0d0f",
493
+ bg1: "#111115",
494
+ bg2: "#16161b",
495
+ bg3: "#1d1d24",
496
+ bg4: "#24242d",
497
+ border: "rgba(255,255,255,.07)",
498
+ border2: "rgba(255,255,255,.12)",
499
+ border3: "rgba(255,255,255,.19)",
500
+ text: "#c9c7c0",
501
+ text2: "#8b8994",
502
+ text3: "#4e4c58",
503
+ accent: "#6e9fff",
504
+ accent2: "#2f5db0",
505
+ green: "#4ec9a0",
506
+ orange: "#d4976e",
507
+ purple: "#b48eff",
508
+ red: "#f28b82",
509
+ yellow: "#e8c97a",
510
+ cur: "#6e9fff",
511
+ curGlow: "rgba(110,159,255,.65)",
512
+ curLineBg: "rgba(255,255,255,.032)",
513
+ curLineGutter: "#181820",
514
+ gutterBg: "#0f0f12",
515
+ gutterHover: "#181820",
516
+ gutterBorder: "rgba(255,255,255,.06)",
517
+ gutterNum: "#4e4c58",
518
+ gutterNumAct: "#9997a2",
519
+ selBg: "rgba(110,159,255,.22)",
520
+ wordHlBg: "rgba(200,198,210,.09)",
521
+ wordHlBorder: "rgba(200,198,210,.28)",
522
+ bmBorder: "rgba(110,159,255,.65)",
523
+ foldBg: "rgba(110,159,255,.07)",
524
+ foldBorder: "rgba(110,159,255,.30)",
525
+ findBg: "rgba(234,180,86,.18)",
526
+ findBorder: "rgba(234,180,86,.50)",
527
+ findCurBg: "rgba(234,180,86,.80)",
528
+ findCurBorder: "rgba(234,180,86,.95)",
529
+ findCurText: "#1a1000",
530
+ fileActiveBg: "rgba(110,159,255,.11)",
531
+ fileActiveText: "#6e9fff",
532
+ mmBg: "#0d0d0f",
533
+ mmSlider: "rgba(255,255,255,.07)",
534
+ mmDim: "rgba(0,0,0,.30)",
535
+ mmEdge: "rgba(255,255,255,.18)",
536
+ indentGuide: "rgba(255,255,255,.06)",
537
+ tokKw: "#6e9fff",
538
+ tokStr: "#4ec9a0",
539
+ tokCmt: "#4e4c58",
540
+ tokFn: "#d4976e",
541
+ tokNum: "#b48eff",
542
+ tokCls: "#e8c97a",
543
+ tokOp: "#55536a",
544
+ tokTyp: "#6ec9d4",
545
+ tokDec: "#f28b82"
546
+ }
547
+ }, Ve = {
548
+ id: "vscode-dark",
549
+ name: "VSCode Dark+",
550
+ description: "Visual Studio Code dark",
551
+ light: !1,
552
+ tokens: {
553
+ bg0: "#1e1e1e",
554
+ bg1: "#252526",
555
+ bg2: "#1e1e1e",
556
+ bg3: "#2d2d30",
557
+ bg4: "#3a3a3d",
558
+ border: "rgba(255,255,255,.09)",
559
+ border2: "rgba(255,255,255,.15)",
560
+ border3: "rgba(255,255,255,.24)",
561
+ text: "#d4d4d4",
562
+ text2: "#9a9a9a",
563
+ text3: "#505050",
564
+ accent: "#569cd6",
565
+ accent2: "#0e639c",
566
+ green: "#4ec9b0",
567
+ orange: "#ce9178",
568
+ purple: "#c586c0",
569
+ red: "#f44747",
570
+ yellow: "#dcdcaa",
571
+ cur: "#aeafad",
572
+ curGlow: "rgba(174,175,173,.40)",
573
+ curLineBg: "rgba(255,255,255,.038)",
574
+ curLineGutter: "#282828",
575
+ gutterBg: "#1e1e1e",
576
+ gutterHover: "#282828",
577
+ gutterBorder: "rgba(255,255,255,.07)",
578
+ gutterNum: "#838383",
579
+ gutterNumAct: "#c8c8c8",
580
+ selBg: "rgba(38,79,120,.65)",
581
+ wordHlBg: "rgba(173,214,255,.06)",
582
+ wordHlBorder: "rgba(173,214,255,.28)",
583
+ bmBorder: "rgba(86,156,214,.70)",
584
+ foldBg: "rgba(86,156,214,.07)",
585
+ foldBorder: "rgba(86,156,214,.35)",
586
+ findBg: "rgba(255,215,0,.13)",
587
+ findBorder: "rgba(255,215,0,.52)",
588
+ findCurBg: "#f6f6a0",
589
+ findCurBorder: "#d4d400",
590
+ findCurText: "#000",
591
+ fileActiveBg: "rgba(255,255,255,.07)",
592
+ fileActiveText: "#d4d4d4",
593
+ mmBg: "#1e1e1e",
594
+ mmSlider: "rgba(255,255,255,.07)",
595
+ mmDim: "rgba(0,0,0,.32)",
596
+ mmEdge: "rgba(255,255,255,.20)",
597
+ indentGuide: "rgba(255,255,255,.07)",
598
+ tokKw: "#569cd6",
599
+ tokStr: "#ce9178",
600
+ tokCmt: "#6a9955",
601
+ tokFn: "#dcdcaa",
602
+ tokNum: "#b5cea8",
603
+ tokCls: "#4ec9b0",
604
+ tokOp: "#d4d4d4",
605
+ tokTyp: "#4ec9b0",
606
+ tokDec: "#9cdcfe"
607
+ }
608
+ }, Ye = {
609
+ id: "monokai",
610
+ name: "Monokai",
611
+ description: "Classic Sublime Text theme",
612
+ light: !1,
613
+ tokens: {
614
+ bg0: "#272822",
615
+ bg1: "#1e1f1c",
616
+ bg2: "#272822",
617
+ bg3: "#3a3930",
618
+ bg4: "#48473d",
619
+ border: "rgba(255,255,255,.08)",
620
+ border2: "rgba(255,255,255,.13)",
621
+ border3: "rgba(255,255,255,.20)",
622
+ text: "#f8f8f2",
623
+ text2: "#a8a7a0",
624
+ text3: "#58574e",
625
+ accent: "#a6e22e",
626
+ accent2: "#3d5a10",
627
+ green: "#a6e22e",
628
+ orange: "#fd971f",
629
+ purple: "#ae81ff",
630
+ red: "#f92672",
631
+ yellow: "#e6db74",
632
+ cur: "#f8f8f2",
633
+ curGlow: "rgba(248,248,242,.25)",
634
+ curLineBg: "rgba(255,255,255,.042)",
635
+ curLineGutter: "#2c2d27",
636
+ gutterBg: "#1e1f1c",
637
+ gutterHover: "#2c2d27",
638
+ gutterBorder: "rgba(255,255,255,.06)",
639
+ gutterNum: "#6e6d64",
640
+ gutterNumAct: "#cccac0",
641
+ selBg: "rgba(73,72,62,.80)",
642
+ wordHlBg: "rgba(248,248,242,.06)",
643
+ wordHlBorder: "rgba(248,248,242,.22)",
644
+ bmBorder: "rgba(166,226,46,.65)",
645
+ foldBg: "rgba(166,226,46,.07)",
646
+ foldBorder: "rgba(166,226,46,.30)",
647
+ findBg: "rgba(230,219,116,.16)",
648
+ findBorder: "rgba(230,219,116,.52)",
649
+ findCurBg: "#e6db74",
650
+ findCurBorder: "#c9be50",
651
+ findCurText: "#272822",
652
+ fileActiveBg: "rgba(166,226,46,.10)",
653
+ fileActiveText: "#a6e22e",
654
+ mmBg: "#1e1f1c",
655
+ mmSlider: "rgba(255,255,255,.06)",
656
+ mmDim: "rgba(0,0,0,.32)",
657
+ mmEdge: "rgba(255,255,255,.18)",
658
+ indentGuide: "rgba(255,255,255,.06)",
659
+ tokKw: "#f92672",
660
+ tokStr: "#e6db74",
661
+ tokCmt: "#75715e",
662
+ tokFn: "#a6e22e",
663
+ tokNum: "#ae81ff",
664
+ tokCls: "#66d9e8",
665
+ tokOp: "#f8f8f2",
666
+ tokTyp: "#66d9e8",
667
+ tokDec: "#fd971f"
668
+ }
669
+ }, Je = {
670
+ id: "dracula",
671
+ name: "Dracula",
672
+ description: "Purple-tinted dark theme",
673
+ light: !1,
674
+ tokens: {
675
+ bg0: "#282a36",
676
+ bg1: "#21222c",
677
+ bg2: "#282a36",
678
+ bg3: "#333545",
679
+ bg4: "#44475a",
680
+ border: "rgba(255,255,255,.08)",
681
+ border2: "rgba(255,255,255,.14)",
682
+ border3: "rgba(255,255,255,.22)",
683
+ text: "#f8f8f2",
684
+ text2: "#b2b5c8",
685
+ text3: "#5a5e78",
686
+ accent: "#bd93f9",
687
+ accent2: "#5b3fa8",
688
+ green: "#50fa7b",
689
+ orange: "#ffb86c",
690
+ purple: "#bd93f9",
691
+ red: "#ff5555",
692
+ yellow: "#f1fa8c",
693
+ cur: "#f8f8f2",
694
+ curGlow: "rgba(189,147,249,.55)",
695
+ curLineBg: "rgba(255,255,255,.045)",
696
+ curLineGutter: "#2f3144",
697
+ gutterBg: "#21222c",
698
+ gutterHover: "#2f3144",
699
+ gutterBorder: "rgba(255,255,255,.07)",
700
+ gutterNum: "#5e638a",
701
+ gutterNumAct: "#f8f8f2",
702
+ selBg: "rgba(68,71,90,.85)",
703
+ wordHlBg: "rgba(248,248,242,.05)",
704
+ wordHlBorder: "rgba(248,248,242,.20)",
705
+ bmBorder: "rgba(189,147,249,.70)",
706
+ foldBg: "rgba(189,147,249,.08)",
707
+ foldBorder: "rgba(189,147,249,.35)",
708
+ findBg: "rgba(241,250,140,.14)",
709
+ findBorder: "rgba(241,250,140,.52)",
710
+ findCurBg: "#f1fa8c",
711
+ findCurBorder: "#d4dc50",
712
+ findCurText: "#282a36",
713
+ fileActiveBg: "rgba(189,147,249,.12)",
714
+ fileActiveText: "#bd93f9",
715
+ mmBg: "#21222c",
716
+ mmSlider: "rgba(255,255,255,.07)",
717
+ mmDim: "rgba(0,0,0,.32)",
718
+ mmEdge: "rgba(255,255,255,.20)",
719
+ indentGuide: "rgba(255,255,255,.07)",
720
+ tokKw: "#ff79c6",
721
+ tokStr: "#f1fa8c",
722
+ tokCmt: "#6272a4",
723
+ tokFn: "#50fa7b",
724
+ tokNum: "#bd93f9",
725
+ tokCls: "#8be9fd",
726
+ tokOp: "#f8f8f2",
727
+ tokTyp: "#8be9fd",
728
+ tokDec: "#ffb86c"
729
+ }
730
+ }, Xe = {
731
+ id: "github-light",
732
+ name: "GitHub Light",
733
+ description: "GitHub's clean light theme",
734
+ light: !0,
735
+ tokens: {
736
+ bg0: "#ffffff",
737
+ bg1: "#f6f8fa",
738
+ bg2: "#ffffff",
739
+ bg3: "#f0f3f6",
740
+ bg4: "#e7eaee",
741
+ border: "#d0d7de",
742
+ border2: "#bdc4cc",
743
+ border3: "#aab1ba",
744
+ text: "#1f2328",
745
+ text2: "#57606a",
746
+ text3: "#8c959f",
747
+ accent: "#0969da",
748
+ accent2: "#0550ae",
749
+ green: "#1a7f37",
750
+ orange: "#bc4c00",
751
+ purple: "#8250df",
752
+ red: "#cf222e",
753
+ yellow: "#7d4e00",
754
+ cur: "#0969da",
755
+ curGlow: "rgba(9,105,218,.30)",
756
+ curLineBg: "rgba(9,105,218,.055)",
757
+ curLineGutter: "#ebf0f8",
758
+ gutterBg: "#f6f8fa",
759
+ gutterHover: "#eaedf1",
760
+ gutterBorder: "#d0d7de",
761
+ gutterNum: "#9da5b0",
762
+ gutterNumAct: "#1f2328",
763
+ selBg: "rgba(9,105,218,.15)",
764
+ wordHlBg: "rgba(9,105,218,.07)",
765
+ wordHlBorder: "rgba(9,105,218,.28)",
766
+ bmBorder: "rgba(9,105,218,.60)",
767
+ foldBg: "rgba(9,105,218,.06)",
768
+ foldBorder: "rgba(9,105,218,.28)",
769
+ findBg: "rgba(180,100,0,.09)",
770
+ findBorder: "rgba(180,100,0,.42)",
771
+ findCurBg: "rgba(180,100,0,.75)",
772
+ findCurBorder: "rgba(180,100,0,.95)",
773
+ findCurText: "#fff",
774
+ fileActiveBg: "rgba(9,105,218,.09)",
775
+ fileActiveText: "#0969da",
776
+ mmBg: "#f6f8fa",
777
+ mmSlider: "rgba(0,0,0,.06)",
778
+ mmDim: "rgba(0,0,0,.055)",
779
+ mmEdge: "rgba(0,0,0,.18)",
780
+ indentGuide: "rgba(0,0,0,.09)",
781
+ tokKw: "#cf222e",
782
+ tokStr: "#0a3069",
783
+ tokCmt: "#6e7781",
784
+ tokFn: "#8250df",
785
+ tokNum: "#0550ae",
786
+ tokCls: "#953800",
787
+ tokOp: "#1f2328",
788
+ tokTyp: "#0550ae",
789
+ tokDec: "#0969da"
790
+ }
791
+ }, Ze = {
792
+ id: "solarized-light",
793
+ name: "Solarized Light",
794
+ description: "Warm precision light theme",
795
+ light: !0,
796
+ tokens: {
797
+ bg0: "#fdf6e3",
798
+ bg1: "#eee8d5",
799
+ bg2: "#fdf6e3",
800
+ bg3: "#e5dfcc",
801
+ bg4: "#dad4c1",
802
+ border: "#cdc7b4",
803
+ border2: "#bab4a2",
804
+ border3: "#a9a390",
805
+ text: "#002b36",
806
+ text2: "#586e75",
807
+ text3: "#93a1a1",
808
+ accent: "#268bd2",
809
+ accent2: "#1a6fa8",
810
+ green: "#859900",
811
+ orange: "#cb4b16",
812
+ purple: "#6c71c4",
813
+ red: "#dc322f",
814
+ yellow: "#b58900",
815
+ cur: "#268bd2",
816
+ curGlow: "rgba(38,139,210,.32)",
817
+ curLineBg: "rgba(38,139,210,.07)",
818
+ curLineGutter: "#e2dcc8",
819
+ gutterBg: "#eee8d5",
820
+ gutterHover: "#e2dcc8",
821
+ gutterBorder: "#cdc7b4",
822
+ gutterNum: "#93a1a1",
823
+ gutterNumAct: "#002b36",
824
+ selBg: "rgba(38,139,210,.18)",
825
+ wordHlBg: "rgba(38,139,210,.08)",
826
+ wordHlBorder: "rgba(38,139,210,.28)",
827
+ bmBorder: "rgba(38,139,210,.58)",
828
+ foldBg: "rgba(38,139,210,.07)",
829
+ foldBorder: "rgba(38,139,210,.28)",
830
+ findBg: "rgba(181,137,0,.11)",
831
+ findBorder: "rgba(181,137,0,.42)",
832
+ findCurBg: "rgba(181,137,0,.75)",
833
+ findCurBorder: "rgba(181,137,0,.95)",
834
+ findCurText: "#fff",
835
+ fileActiveBg: "rgba(38,139,210,.10)",
836
+ fileActiveText: "#268bd2",
837
+ mmBg: "#eee8d5",
838
+ mmSlider: "rgba(0,0,0,.06)",
839
+ mmDim: "rgba(0,0,0,.055)",
840
+ mmEdge: "rgba(0,0,0,.16)",
841
+ indentGuide: "rgba(0,0,0,.08)",
842
+ tokKw: "#859900",
843
+ tokStr: "#2aa198",
844
+ tokCmt: "#93a1a1",
845
+ tokFn: "#268bd2",
846
+ tokNum: "#d33682",
847
+ tokCls: "#b58900",
848
+ tokOp: "#657b83",
849
+ tokTyp: "#268bd2",
850
+ tokDec: "#cb4b16"
851
+ }
852
+ }, Qe = {
853
+ id: "mdx-dark",
854
+ name: "MDX Dark",
855
+ description: "Catppuccin Mocha — matches .smdx-dark MDX editor chrome, single-colour tokens",
856
+ light: !1,
857
+ tokens: {
858
+ bg0: "#181825",
859
+ bg1: "#1e1e2e",
860
+ bg2: "#1e1e2e",
861
+ bg3: "#2a2a3c",
862
+ bg4: "#313147",
863
+ border: "#374151",
864
+ border2: "rgba(129,140,248,.22)",
865
+ border3: "rgba(129,140,248,.40)",
866
+ text: "#e2e8f0",
867
+ text2: "#94a3b8",
868
+ text3: "#475569",
869
+ accent: "#818cf8",
870
+ accent2: "#6366f1",
871
+ green: "#c3e88d",
872
+ orange: "#f78c6c",
873
+ purple: "#c792ea",
874
+ red: "#f07178",
875
+ yellow: "#ffcb6b",
876
+ cur: "#818cf8",
877
+ curGlow: "rgba(129,140,248,.55)",
878
+ curLineBg: "rgba(129,140,248,.055)",
879
+ curLineGutter: "#252540",
880
+ gutterBg: "#181825",
881
+ gutterHover: "#252540",
882
+ gutterBorder: "#374151",
883
+ gutterNum: "#475569",
884
+ gutterNumAct: "#94a3b8",
885
+ selBg: "rgba(129,140,248,.24)",
886
+ wordHlBg: "rgba(226,232,240,.07)",
887
+ wordHlBorder: "rgba(226,232,240,.25)",
888
+ bmBorder: "rgba(137,221,255,.70)",
889
+ foldBg: "rgba(129,140,248,.07)",
890
+ foldBorder: "rgba(129,140,248,.30)",
891
+ findBg: "rgba(251,191,36,.16)",
892
+ findBorder: "rgba(251,191,36,.50)",
893
+ findCurBg: "rgba(251,191,36,.85)",
894
+ findCurBorder: "rgba(251,191,36,.95)",
895
+ findCurText: "#1a1000",
896
+ fileActiveBg: "rgba(129,140,248,.12)",
897
+ fileActiveText: "#818cf8",
898
+ mmBg: "#181825",
899
+ mmSlider: "rgba(255,255,255,.07)",
900
+ mmDim: "rgba(0,0,0,.30)",
901
+ mmEdge: "rgba(255,255,255,.18)",
902
+ indentGuide: "rgba(255,255,255,.06)",
903
+ // All tokens match prose text — single-colour, distraction-free editing
904
+ tokKw: "#e2e8f0",
905
+ tokStr: "#e2e8f0",
906
+ tokCmt: "#e2e8f0",
907
+ tokFn: "#e2e8f0",
908
+ tokNum: "#e2e8f0",
909
+ tokCls: "#e2e8f0",
910
+ tokOp: "#e2e8f0",
911
+ tokTyp: "#e2e8f0",
912
+ tokDec: "#e2e8f0"
913
+ }
914
+ }, et = {
915
+ id: "mdx-light",
916
+ name: "MDX Light",
917
+ description: "Clean light — matches default .smdx-editor MDX chrome, single-colour tokens",
918
+ light: !0,
919
+ tokens: {
920
+ bg0: "#f1f5f9",
921
+ bg1: "#ffffff",
922
+ bg2: "#ffffff",
923
+ bg3: "#f8fafc",
924
+ bg4: "#f1f5f9",
925
+ border: "#e2e8f0",
926
+ border2: "rgba(99,102,241,.20)",
927
+ border3: "rgba(99,102,241,.40)",
928
+ text: "#1e293b",
929
+ text2: "#64748b",
930
+ text3: "#94a3b8",
931
+ accent: "#6366f1",
932
+ accent2: "#4f46e5",
933
+ green: "#15803d",
934
+ orange: "#c2410c",
935
+ purple: "#7c3aed",
936
+ red: "#dc2626",
937
+ yellow: "#b45309",
938
+ cur: "#6366f1",
939
+ curGlow: "rgba(99,102,241,.35)",
940
+ curLineBg: "rgba(99,102,241,.05)",
941
+ curLineGutter: "#eef2ff",
942
+ gutterBg: "#f8fafc",
943
+ gutterHover: "#eef2ff",
944
+ gutterBorder: "#e2e8f0",
945
+ gutterNum: "#94a3b8",
946
+ gutterNumAct: "#475569",
947
+ selBg: "rgba(99,102,241,.18)",
948
+ wordHlBg: "rgba(99,102,241,.07)",
949
+ wordHlBorder: "rgba(99,102,241,.30)",
950
+ bmBorder: "rgba(14,116,144,.60)",
951
+ foldBg: "rgba(99,102,241,.06)",
952
+ foldBorder: "rgba(99,102,241,.28)",
953
+ findBg: "rgba(180,83,9,.09)",
954
+ findBorder: "rgba(180,83,9,.40)",
955
+ findCurBg: "rgba(180,83,9,.75)",
956
+ findCurBorder: "rgba(180,83,9,.95)",
957
+ findCurText: "#ffffff",
958
+ fileActiveBg: "rgba(99,102,241,.10)",
959
+ fileActiveText: "#6366f1",
960
+ mmBg: "#f8fafc",
961
+ mmSlider: "rgba(0,0,0,.06)",
962
+ mmDim: "rgba(0,0,0,.05)",
963
+ mmEdge: "rgba(0,0,0,.18)",
964
+ indentGuide: "rgba(0,0,0,.08)",
965
+ // All tokens match prose text — single-colour, distraction-free editing
966
+ tokKw: "#1e293b",
967
+ tokStr: "#1e293b",
968
+ tokCmt: "#1e293b",
969
+ tokFn: "#1e293b",
970
+ tokNum: "#1e293b",
971
+ tokCls: "#1e293b",
972
+ tokOp: "#1e293b",
973
+ tokTyp: "#1e293b",
974
+ tokDec: "#1e293b"
975
+ }
976
+ }, tt = [
977
+ Ke,
978
+ Ve,
979
+ Ye,
980
+ Je,
981
+ Xe,
982
+ Ze,
983
+ Qe,
984
+ et
985
+ ], it = {
986
+ bg0: "--bg0",
987
+ bg1: "--bg1",
988
+ bg2: "--bg2",
989
+ bg3: "--bg3",
990
+ bg4: "--bg4",
991
+ border: "--border",
992
+ border2: "--border2",
993
+ border3: "--border3",
994
+ text: "--text",
995
+ text2: "--text2",
996
+ text3: "--text3",
997
+ accent: "--accent",
998
+ accent2: "--accent2",
999
+ green: "--green",
1000
+ orange: "--orange",
1001
+ purple: "--purple",
1002
+ red: "--red",
1003
+ yellow: "--yellow",
1004
+ cur: "--cur",
1005
+ curGlow: "--cur-glow",
1006
+ curLineBg: "--cur-line-bg",
1007
+ curLineGutter: "--cur-line-gutter",
1008
+ gutterBg: "--gutter-bg",
1009
+ gutterHover: "--gutter-hover",
1010
+ gutterBorder: "--gutter-border",
1011
+ gutterNum: "--gutter-num",
1012
+ gutterNumAct: "--gutter-num-act",
1013
+ selBg: "--sel-bg",
1014
+ wordHlBg: "--word-hl-bg",
1015
+ wordHlBorder: "--word-hl-border",
1016
+ bmBorder: "--bm-border",
1017
+ foldBg: "--fold-bg",
1018
+ foldBorder: "--fold-border",
1019
+ findBg: "--find-bg",
1020
+ findBorder: "--find-border",
1021
+ findCurBg: "--find-cur-bg",
1022
+ findCurBorder: "--find-cur-border",
1023
+ findCurText: "--find-cur-text",
1024
+ fileActiveBg: "--file-active-bg",
1025
+ fileActiveText: "--file-active-text",
1026
+ mmBg: "--mm-bg",
1027
+ mmSlider: "--mm-slider",
1028
+ mmDim: "--mm-dim",
1029
+ mmEdge: "--mm-edge",
1030
+ indentGuide: "--indent-guide",
1031
+ tokKw: "--tok-kw",
1032
+ tokStr: "--tok-str",
1033
+ tokCmt: "--tok-cmt",
1034
+ tokFn: "--tok-fn",
1035
+ tokNum: "--tok-num",
1036
+ tokCls: "--tok-cls",
1037
+ tokOp: "--tok-op",
1038
+ tokTyp: "--tok-typ",
1039
+ tokDec: "--tok-dec"
1040
+ };
1041
+ class nt {
1042
+ constructor(e) {
1043
+ g(this, "_registry", /* @__PURE__ */ new Map());
1044
+ g(this, "_activeId", "");
1045
+ g(this, "_root");
1046
+ this._root = e;
1047
+ for (const t of tt)
1048
+ this._registry.set(t.id, t);
1049
+ }
1050
+ /** Register a custom or override theme. */
1051
+ register(e) {
1052
+ this._registry.set(e.id, e);
1053
+ }
1054
+ /** Apply a theme by id or by definition. */
1055
+ apply(e) {
1056
+ let t;
1057
+ typeof e == "string" ? (t = this._registry.get(e), t || (console.warn(`[syncline-editor] Unknown theme: "${e}". Falling back to VR Dark.`), t = this._registry.get(""))) : (t = e, this._registry.set(t.id, t)), this._activeId = t.id, this._applyTokens(t.tokens);
1058
+ }
1059
+ get activeId() {
1060
+ return this._activeId;
1061
+ }
1062
+ get activeTheme() {
1063
+ return this._registry.get(this._activeId);
1064
+ }
1065
+ get allIds() {
1066
+ return [...this._registry.keys()];
1067
+ }
1068
+ get all() {
1069
+ return [...this._registry.values()];
1070
+ }
1071
+ _applyTokens(e) {
1072
+ const t = this._root.style;
1073
+ for (const [i, n] of Object.entries(it))
1074
+ t.setProperty(n, e[i]);
1075
+ }
1076
+ }
1077
+ const rt = `
1078
+ /* ── Reset ── */
1079
+ *,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
1080
+
1081
+ /* ── Host element ── */
1082
+ :host,.sl-host{
1083
+ display:flex;flex-direction:column;
1084
+ height:100%;overflow:hidden;
1085
+ font-family:var(--sans,'Geist',system-ui,sans-serif);
1086
+ color:var(--text,#c9c7c0);
1087
+ background:var(--bg0,#0d0d0f);
1088
+
1089
+ /* Default token vars (can be overridden by theme) */
1090
+ --sans:'Geist',system-ui,sans-serif;
1091
+ --mono:'JetBrains Mono',monospace;
1092
+
1093
+ /* ── VR Dark defaults ── */
1094
+ --bg0:#0d0d0f; --bg1:#111115; --bg2:#16161b; --bg3:#1d1d24; --bg4:#24242d;
1095
+ --border:rgba(255,255,255,.07);
1096
+ --border2:rgba(255,255,255,.12);
1097
+ --border3:rgba(255,255,255,.19);
1098
+ --text:#c9c7c0; --text2:#8b8994; --text3:#4e4c58;
1099
+ --accent:#6e9fff; --accent2:#2f5db0;
1100
+ --green:#4ec9a0; --orange:#d4976e; --purple:#b48eff;
1101
+ --red:#f28b82; --yellow:#e8c97a;
1102
+ --cur:#6e9fff; --cur-glow:rgba(110,159,255,.65);
1103
+ --cur-line-bg:rgba(255,255,255,.032);
1104
+ --cur-line-gutter:#181820;
1105
+ --gutter-bg:#0f0f12; --gutter-hover:#181820;
1106
+ --gutter-border:rgba(255,255,255,.06);
1107
+ --gutter-num:#4e4c58; --gutter-num-act:#9997a2;
1108
+ --sel-bg:rgba(110,159,255,.22);
1109
+ --word-hl-bg:rgba(200,198,210,.09);
1110
+ --word-hl-border:rgba(200,198,210,.28);
1111
+ --bm-border:rgba(110,159,255,.65);
1112
+ --fold-bg:rgba(110,159,255,.07);
1113
+ --fold-border:rgba(110,159,255,.30);
1114
+ --find-bg:rgba(234,180,86,.18);
1115
+ --find-border:rgba(234,180,86,.50);
1116
+ --find-cur-bg:rgba(234,180,86,.80);
1117
+ --find-cur-border:rgba(234,180,86,.95);
1118
+ --find-cur-text:#1a1000;
1119
+ --file-active-bg:rgba(110,159,255,.11);
1120
+ --file-active-text:#6e9fff;
1121
+ --mm-bg:#0d0d0f; --mm-slider:rgba(255,255,255,.07);
1122
+ --mm-dim:rgba(0,0,0,.30); --mm-edge:rgba(255,255,255,.18);
1123
+ --indent-guide:rgba(255,255,255,.06);
1124
+ --tok-kw:#6e9fff; --tok-str:#4ec9a0; --tok-cmt:#4e4c58;
1125
+ --tok-fn:#d4976e; --tok-num:#b48eff; --tok-cls:#e8c97a;
1126
+ --tok-op:#55536a; --tok-typ:#6ec9d4; --tok-dec:#f28b82;
1127
+ }
1128
+
1129
+ /* ── Layout ── */
1130
+ .sl-layout{display:flex;flex:1;overflow:hidden}
1131
+ .sl-ed-pane{flex:1;display:flex;flex-direction:column;overflow:hidden;position:relative;background:var(--bg2)}
1132
+
1133
+ /* ── Hidden textarea (input capture) ── */
1134
+ .sl-input{position:fixed;left:-9999px;top:0;width:200px;height:40px;
1135
+ opacity:0;resize:none;border:none;outline:none;padding:0;margin:0;
1136
+ font-size:16px;background:transparent;color:transparent;
1137
+ caret-color:transparent;pointer-events:none}
1138
+
1139
+ /* ── Editor scroll container ── */
1140
+ .sl-editor{flex:1;overflow-y:scroll;overflow-x:auto;position:relative;
1141
+ cursor:text;scrollbar-width:thin;scrollbar-color:var(--border3) transparent}
1142
+ .sl-editor::-webkit-scrollbar{width:10px;height:8px}
1143
+ .sl-editor::-webkit-scrollbar-track{background:transparent}
1144
+ .sl-editor::-webkit-scrollbar-thumb{background:var(--border3);border-radius:5px;border:2px solid var(--bg2)}
1145
+ .sl-spacer{position:absolute;left:0;top:0;width:1px;pointer-events:none}
1146
+ .sl-vp{position:absolute;left:0;right:0;overflow-x:hidden;will-change:transform}
1147
+
1148
+ /* ── Editor row ── */
1149
+ .sl-er{display:flex;align-items:stretch;position:relative}
1150
+ .sl-er:hover .sl-eg{background:var(--gutter-hover)}
1151
+ .sl-er.sl-cur-row{background:var(--cur-line-bg)}
1152
+ .sl-er.sl-cur-row .sl-eg{background:var(--cur-line-gutter)!important}
1153
+ .sl-eg{min-width:60px;font-family:var(--mono);font-size:11px;color:var(--gutter-num);
1154
+ user-select:none;border-right:1px solid var(--gutter-border);
1155
+ background:var(--gutter-bg);flex-shrink:0;position:sticky;left:0;z-index:2;
1156
+ display:flex;flex-direction:column;justify-content:flex-start;
1157
+ transition:background .12s,color .12s}
1158
+ .sl-er.sl-cur-row .sl-eg{color:var(--gutter-num-act)}
1159
+ .sl-egn{height:22px;line-height:22px;padding-right:10px;text-align:right;display:block}
1160
+ .sl-er.sl-wrap-cont .sl-egn{visibility:hidden}
1161
+ .sl-el{flex:1;font-family:var(--mono);font-size:13px;line-height:22px;
1162
+ color:var(--text);position:relative;min-width:0}
1163
+ .sl-cl{display:block;height:22px;line-height:22px;
1164
+ padding:0 20px 0 14px;white-space:pre;position:relative}
1165
+ .sl-wrap-mode .sl-cl{white-space:pre-wrap;word-break:break-all;height:auto;overflow-wrap:anywhere}
1166
+
1167
+ /* ── Cursor ── */
1168
+ .sl-cur{display:inline;width:0;height:0;position:relative}
1169
+ .sl-cur::after{content:'';position:absolute;left:0;top:2px;width:2px;height:18px;
1170
+ background:var(--cur);border-radius:1px;
1171
+ box-shadow:0 0 8px var(--cur-glow);
1172
+ animation:sl-blink 1.05s step-end infinite;pointer-events:none}
1173
+ @keyframes sl-blink{0%,100%{opacity:1}45%,55%{opacity:0}}
1174
+
1175
+ /* ── Multi-cursor extra beams ── */
1176
+ .sl-cur-extra{display:inline;width:0;height:0;position:relative}
1177
+ .sl-cur-extra::after{content:'';position:absolute;left:0;top:2px;width:2px;height:18px;
1178
+ background:var(--cur);border-radius:1px;
1179
+ box-shadow:0 0 8px var(--cur-glow);
1180
+ animation:sl-blink 1.05s step-end infinite;pointer-events:none}
1181
+
1182
+ /* ── Snippet tab-stop ghost markers ── */
1183
+ .sl-snip-stop{display:inline;width:0;height:0;position:relative}
1184
+ .sl-snip-stop::after{content:'';position:absolute;left:0;top:2px;width:2px;height:18px;
1185
+ background:var(--cur);border-radius:1px;opacity:0.28;pointer-events:none}
1186
+
1187
+ /* ── Overlays ── */
1188
+ .sl-sh{background:var(--sel-bg);border-radius:2px}
1189
+ .sl-fh{background:var(--find-bg);box-shadow:0 0 0 1px var(--find-border);border-radius:2px}
1190
+ .sl-fh.sl-fh-cur{background:var(--find-cur-bg);box-shadow:0 0 0 1px var(--find-cur-border);color:var(--find-cur-text)}
1191
+ .sl-wh{background:var(--word-hl-bg);box-shadow:0 0 0 1px var(--word-hl-border);border-radius:2px}
1192
+ .sl-bm{box-shadow:0 0 0 1px var(--bm-border);border-radius:2px}
1193
+ .sl-ig{position:absolute;top:0;bottom:0;width:1px;background:var(--indent-guide);pointer-events:none}
1194
+
1195
+ /* ── Code folding ── */
1196
+ .sl-fold-btn{position:absolute;left:3px;top:4px;width:13px;height:13px;border-radius:3px;
1197
+ display:flex;align-items:center;justify-content:center;font-size:9px;
1198
+ color:var(--gutter-num);cursor:pointer;opacity:0;
1199
+ transition:opacity .15s,background .1s;user-select:none;line-height:1}
1200
+ .sl-er:hover .sl-fold-btn{opacity:1}
1201
+ .sl-fold-btn:hover{background:var(--border3);color:var(--gutter-num-act)}
1202
+ .sl-folded{background:var(--fold-bg);border-bottom:1px dashed var(--fold-border)}
1203
+
1204
+ /* ── Syntax tokens ── */
1205
+ .kw{color:var(--tok-kw)}.str{color:var(--tok-str)}.cmt{color:var(--tok-cmt);font-style:italic}
1206
+ .fn{color:var(--tok-fn)}.num{color:var(--tok-num)}.cls{color:var(--tok-cls)}
1207
+ .op{color:var(--tok-op)}.typ{color:var(--tok-typ)}.dec{color:var(--tok-dec)}
1208
+
1209
+ /* ── Minimap ── */
1210
+ .sl-minimap{background:var(--mm-bg);border-left:1px solid var(--border);
1211
+ overflow:hidden;position:relative;flex-shrink:0;cursor:pointer;user-select:none}
1212
+ .sl-minimap canvas{display:block;position:absolute;top:0;left:0}
1213
+ .sl-mm-slider{position:absolute;left:0;right:0;pointer-events:none}
1214
+
1215
+ /* ── Status bar ── */
1216
+ .sl-statusbar{height:26px;background:var(--accent2);display:flex;align-items:center;
1217
+ padding:0 6px;font-size:11px;color:rgba(255,255,255,.85);flex-shrink:0;gap:0}
1218
+ .sl-sb-item{display:flex;align-items:center;gap:4px;padding:0 8px;height:100%;
1219
+ cursor:pointer;transition:background .1s;white-space:nowrap;border-radius:3px}
1220
+ .sl-sb-item:hover{background:rgba(255,255,255,.15)}
1221
+ .sl-sb-item.sl-no-click{cursor:default}
1222
+ .sl-sb-item.sl-no-click:hover{background:transparent}
1223
+ .sl-sb-sep{width:1px;height:14px;background:rgba(255,255,255,.22);margin:0 1px;flex-shrink:0}
1224
+ .sl-sb-right{margin-left:auto;display:flex;align-items:center}
1225
+ .sl-sb-wrap.sl-on{font-weight:700}
1226
+
1227
+ /* ── Placeholder ── */
1228
+ .sl-placeholder{position:absolute;top:0;right:0;pointer-events:none;user-select:none;
1229
+ color:var(--text3);white-space:pre;overflow:hidden;z-index:1}
1230
+
1231
+ /* ── Go to Line bar ── */
1232
+ .sl-gtl-bar{position:absolute;top:0;left:50%;z-index:50;background:var(--bg3);
1233
+ border:1px solid var(--border3);border-top:none;border-radius:0 0 10px 10px;
1234
+ display:flex;align-items:center;gap:8px;padding:8px 12px;
1235
+ transform:translateX(-50%) translateY(-100%);transition:transform .18s,box-shadow .18s;pointer-events:none}
1236
+ .sl-gtl-bar.sl-open{transform:translateX(-50%) translateY(0);pointer-events:all;box-shadow:0 8px 28px rgba(0,0,0,.4)}
1237
+ .sl-gtl-label{font-size:12px;color:var(--text2);white-space:nowrap}
1238
+ .sl-gtl-input{width:72px;background:var(--bg4);border:1px solid var(--border3);
1239
+ border-radius:5px;padding:4px 8px;font-size:12px;font-family:var(--mono);
1240
+ color:var(--text);outline:none;transition:border-color .15s;text-align:center}
1241
+ .sl-gtl-input:focus{border-color:var(--accent)}
1242
+ .sl-gtl-input.sl-gtl-err{border-color:#e05252}
1243
+ .sl-gtl-hint{font-size:11px;color:var(--text3);font-family:var(--mono);min-width:40px}
1244
+
1245
+ /* ── Find + Replace bar ── */
1246
+ .sl-find-bar{position:absolute;top:0;right:125px;z-index:50;background:var(--bg3);
1247
+ border:1px solid var(--border3);border-top:none;border-radius:0 0 10px 10px;
1248
+ display:flex;flex-direction:column;overflow:hidden;
1249
+ transform:translateY(-100%);transition:transform .18s,box-shadow .18s;pointer-events:none}
1250
+ .sl-find-bar.sl-open{transform:translateY(0);pointer-events:all;box-shadow:0 8px 28px rgba(0,0,0,.4)}
1251
+ .sl-find-row{display:flex;align-items:center;gap:6px;padding:7px 10px}
1252
+ .sl-find-row+.sl-find-row{border-top:1px solid var(--border)}
1253
+ .sl-find-bar input{width:180px;background:var(--bg4);border:1px solid var(--border3);
1254
+ border-radius:5px;padding:4px 8px;font-size:12px;font-family:var(--mono);
1255
+ color:var(--text);outline:none;transition:border-color .15s}
1256
+ .sl-find-bar input:focus{border-color:var(--accent)}
1257
+ .sl-find-btn{padding:3px 8px;font-size:11px;border:1px solid var(--border3);
1258
+ border-radius:4px;background:transparent;color:var(--text2);cursor:pointer;
1259
+ transition:background .1s;white-space:nowrap}
1260
+ .sl-find-btn:hover{background:var(--border3);color:var(--text)}
1261
+ .sl-find-btn.sl-active{background:var(--accent);border-color:var(--accent);color:#fff}
1262
+ .sl-find-count{font-size:11px;color:var(--text3);font-family:var(--mono);min-width:52px}
1263
+ .sl-find-x{font-size:14px;color:var(--text3);cursor:pointer;padding:2px 5px;
1264
+ border-radius:3px;margin-left:2px}
1265
+ .sl-find-x:hover{color:var(--text);background:var(--border3)}
1266
+
1267
+ /* ── Autocomplete popup (VS Code-style with optional description panel) ── */
1268
+ .sl-ac-popup{position:fixed;z-index:400;background:var(--bg3);
1269
+ border:1px solid var(--border3);border-radius:8px;overflow:hidden;
1270
+ box-shadow:0 12px 40px rgba(0,0,0,.55);
1271
+ display:flex;flex-direction:row;
1272
+ animation:sl-acIn .1s ease;pointer-events:all}
1273
+ @keyframes sl-acIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
1274
+ /* Left: item list */
1275
+ .sl-ac-list{min-width:240px;max-width:300px;max-height:320px;overflow-y:auto;flex-shrink:0}
1276
+ .sl-ac-list::-webkit-scrollbar{width:4px}
1277
+ .sl-ac-list::-webkit-scrollbar-thumb{background:var(--border3);border-radius:2px}
1278
+ .sl-ac-item{display:flex;align-items:center;gap:8px;padding:4px 10px;font-size:12px;
1279
+ font-family:var(--mono);cursor:pointer;color:var(--text2);transition:background .07s;
1280
+ white-space:nowrap}
1281
+ .sl-ac-item:hover,.sl-ac-item.sl-sel{background:var(--bg4);color:var(--text)}
1282
+ .sl-ac-badge{width:18px;height:18px;border-radius:4px;display:flex;align-items:center;
1283
+ justify-content:center;font-size:9px;font-weight:700;flex-shrink:0;font-family:var(--sans)}
1284
+ .sl-ac-badge.kw{background:rgba(110,159,255,.18);color:var(--tok-kw)}
1285
+ .sl-ac-badge.fn{background:rgba(212,151,110,.18);color:var(--tok-fn)}
1286
+ .sl-ac-badge.typ{background:rgba(110,201,212,.18);color:var(--tok-typ)}
1287
+ .sl-ac-badge.cls{background:rgba(232,201,122,.18);color:var(--tok-cls)}
1288
+ .sl-ac-badge.var{background:rgba(78,201,160,.18);color:var(--tok-str)}
1289
+ .sl-ac-badge.snip{background:rgba(155,100,255,.18);color:#a78bfa}
1290
+ .sl-ac-badge.emmet{background:rgba(255,140,0,.18);color:#fb923c}
1291
+ .sl-ac-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1292
+ .sl-ac-detail{font-size:10px;color:var(--text3);flex-shrink:0;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-left:4px}
1293
+ /* Right: description / docs panel */
1294
+ .sl-ac-desc{width:260px;max-height:320px;overflow-y:auto;
1295
+ border-left:1px solid var(--border3);padding:10px 12px;flex-shrink:0}
1296
+ .sl-ac-desc::-webkit-scrollbar{width:4px}
1297
+ .sl-ac-desc::-webkit-scrollbar-thumb{background:var(--border3);border-radius:2px}
1298
+ .sl-ac-desc-body{margin:0;font-size:11.5px;font-family:var(--mono);
1299
+ color:var(--text2);line-height:1.6;white-space:pre-wrap;word-break:break-word}
1300
+
1301
+ /* ── Hover documentation tooltip ── */
1302
+ .sl-hover-tip{position:fixed;z-index:500;background:var(--bg3);
1303
+ border:1px solid var(--border3);border-radius:8px;
1304
+ box-shadow:0 8px 32px rgba(0,0,0,.55);
1305
+ max-width:380px;min-width:180px;padding:10px 14px;
1306
+ pointer-events:all;cursor:default;
1307
+ animation:sl-hoverIn .12s ease}
1308
+ @keyframes sl-hoverIn{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}
1309
+ .sl-ht-sig{display:flex;align-items:baseline;flex-wrap:wrap;gap:8px;margin-bottom:5px}
1310
+ .sl-ht-title{font-size:12.5px;font-family:var(--mono);font-weight:600;color:var(--tok-fn)}
1311
+ .sl-ht-type{font-size:11px;font-family:var(--mono);color:var(--tok-typ);opacity:.9;word-break:break-all}
1312
+ .sl-ht-body{font-size:12px;font-family:var(--sans);color:var(--text2);line-height:1.55;
1313
+ max-height:120px;overflow-y:auto}
1314
+ .sl-ht-body::-webkit-scrollbar{width:3px}
1315
+ .sl-ht-body::-webkit-scrollbar-thumb{background:var(--border3);border-radius:2px}
1316
+ .sl-hover-tip .sl-ht-divider{height:1px;background:var(--border);margin:6px 0}
1317
+
1318
+ /* ── Emmet tooltip ── */
1319
+ .sl-emmet-tip{position:fixed;z-index:600;background:var(--bg3);
1320
+ border:1px solid var(--border3);border-radius:6px;padding:4px 10px;
1321
+ font-size:11px;font-family:var(--mono);color:var(--accent);
1322
+ pointer-events:none;box-shadow:0 4px 16px rgba(0,0,0,.45);
1323
+ white-space:nowrap;max-width:400px;overflow:hidden;text-overflow:ellipsis}
1324
+
1325
+ /* ── Theme picker ── */
1326
+ .sl-theme-overlay{position:fixed;inset:0;z-index:700;
1327
+ background:rgba(0,0,0,.50);backdrop-filter:blur(2px)}
1328
+ .sl-theme-panel{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);
1329
+ z-index:701;background:var(--bg2);border:1px solid var(--border3);
1330
+ border-radius:14px;overflow:hidden;width:420px;
1331
+ box-shadow:0 32px 80px rgba(0,0,0,.65),0 0 0 1px var(--border2)}
1332
+ .sl-theme-header{padding:16px 20px 12px;display:flex;align-items:center;
1333
+ justify-content:space-between;border-bottom:1px solid var(--border)}
1334
+ .sl-theme-title{font-size:13px;font-weight:600;color:var(--text);letter-spacing:.01em}
1335
+ .sl-theme-close{width:24px;height:24px;border-radius:6px;display:flex;align-items:center;
1336
+ justify-content:center;font-size:14px;color:var(--text3);cursor:pointer;
1337
+ transition:background .1s,color .1s}
1338
+ .sl-theme-close:hover{background:var(--border3);color:var(--text)}
1339
+ .sl-theme-list{padding:8px 8px 10px}
1340
+ .sl-theme-item{display:flex;align-items:center;gap:14px;padding:10px 12px;
1341
+ border-radius:9px;cursor:pointer;transition:background .1s;
1342
+ border:1px solid transparent;margin-bottom:2px}
1343
+ .sl-theme-item:hover{background:var(--bg4)}
1344
+ .sl-theme-item.sl-active{background:var(--bg4);border-color:var(--border3)}
1345
+ .sl-theme-check{width:18px;height:18px;margin-left:auto;color:var(--accent);
1346
+ font-size:13px;font-weight:700;flex-shrink:0;opacity:0}
1347
+ .sl-theme-item.sl-active .sl-theme-check{opacity:1}
1348
+ .sl-theme-swatch{width:46px;height:30px;border-radius:7px;flex-shrink:0;
1349
+ overflow:hidden;border:1px solid rgba(0,0,0,.15);
1350
+ display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr}
1351
+ .sl-theme-swatch span{display:block}
1352
+ .sl-theme-name{font-size:13px;color:var(--text);font-weight:500;line-height:1.3}
1353
+ .sl-theme-desc{font-size:11px;color:var(--text3);margin-top:2px}
1354
+ .sl-theme-tag{display:inline-block;font-size:9px;font-weight:600;letter-spacing:.08em;
1355
+ text-transform:uppercase;padding:1px 5px;border-radius:3px;margin-left:6px;
1356
+ background:var(--border3);color:var(--text3);vertical-align:middle}
1357
+ .sl-theme-tag.sl-light{background:rgba(255,200,50,.15);color:#b58900}
1358
+
1359
+ /* ── Empty state ── */
1360
+ .sl-empty{flex:1;display:flex;flex-direction:column;align-items:center;
1361
+ justify-content:center;gap:10px;color:var(--text3);font-size:13px}
1362
+ `;
1363
+ function I(s, e, t) {
1364
+ const i = document.createElement(s);
1365
+ return e && (i.className = e), i;
1366
+ }
1367
+ function V(s) {
1368
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1369
+ }
1370
+ function X(s, e = document.documentElement) {
1371
+ return getComputedStyle(e).getPropertyValue(s).trim();
1372
+ }
1373
+ function be(s, e) {
1374
+ const t = s.replace("#", ""), i = parseInt(t.slice(0, 2), 16), n = parseInt(t.slice(2, 4), 16), r = parseInt(t.slice(4, 6), 16);
1375
+ return `rgba(${i},${n},${r},${e})`;
1376
+ }
1377
+ function me(s) {
1378
+ return s.split(`
1379
+ `);
1380
+ }
1381
+ function A(s) {
1382
+ return s.join(`
1383
+ `);
1384
+ }
1385
+ function _e(s) {
1386
+ return (s.match(/^(\s*)/) ?? ["", ""])[1];
1387
+ }
1388
+ function J(s) {
1389
+ return " ".repeat(Math.max(0, s));
1390
+ }
1391
+ function Ie(s) {
1392
+ return /[\w$]/.test(s);
1393
+ }
1394
+ function le(s, e, t = Ie) {
1395
+ let i = e;
1396
+ for (; i > 0 && t(s[i - 1]); ) i--;
1397
+ return i;
1398
+ }
1399
+ function ce(s, e, t = Ie) {
1400
+ let i = e;
1401
+ for (; i < s.length && t(s[i]); ) i++;
1402
+ return i;
1403
+ }
1404
+ function Z(s, e) {
1405
+ let t = 0, i = null;
1406
+ return (...n) => {
1407
+ const r = Date.now(), o = e - (r - t);
1408
+ o <= 0 ? (i !== null && (clearTimeout(i), i = null), t = r, s(...n)) : i === null && (i = setTimeout(() => {
1409
+ t = Date.now(), i = null, s(...n);
1410
+ }, o));
1411
+ };
1412
+ }
1413
+ const st = {
1414
+ fontSize: [8, 72, 13],
1415
+ lineHeight: [14, 64, 22],
1416
+ tabSize: [1, 16, 2],
1417
+ wrapColumn: [20, 500, 80],
1418
+ maxCompletions: [1, 50, 14],
1419
+ autocompletePrefixLength: [1, 10, 2],
1420
+ gutterWidth: [30, 200, 60],
1421
+ minimapWidth: [60, 300, 120],
1422
+ cursorBlinkRate: [200, 5e3, 1050],
1423
+ maxUndoHistory: [10, 5e3, 300],
1424
+ undoBatchMs: [0, 5e3, 700]
1425
+ };
1426
+ function ot(s, e, t, i) {
1427
+ const n = Number(s);
1428
+ return Number.isFinite(n) ? Math.max(e, Math.min(t, Math.round(n))) : i;
1429
+ }
1430
+ function ye(s) {
1431
+ const e = { ...s };
1432
+ for (const [t, i] of Object.entries(st))
1433
+ if (t in s && s[t] !== void 0) {
1434
+ const [n, r, o] = i;
1435
+ e[t] = ot(s[t], n, r, o);
1436
+ }
1437
+ return e;
1438
+ }
1439
+ const Q = { "(": ")", "{": "}", "[": "]" }, ee = { ")": "(", "}": "{", "]": "[" };
1440
+ function at(s, e) {
1441
+ const { row: t, col: i } = e, n = s[t] ?? "";
1442
+ let r = n[i], o = i;
1443
+ if (!Q[r] && !ee[r] && (r = n[i - 1], o = i - 1), !r) return null;
1444
+ if (Q[r]) {
1445
+ const l = Q[r];
1446
+ let a = 0;
1447
+ for (let c = t; c < Math.min(s.length, t + 500); c++) {
1448
+ const d = s[c] ?? "", h = c === t ? o : 0;
1449
+ for (let p = h; p < d.length; p++)
1450
+ if (d[p] === r) a++;
1451
+ else if (d[p] === l && (a--, a === 0))
1452
+ return {
1453
+ open: { row: t, col: o },
1454
+ close: { row: c, col: p }
1455
+ };
1456
+ }
1457
+ } else if (ee[r]) {
1458
+ const l = ee[r];
1459
+ let a = 0;
1460
+ for (let c = t; c >= Math.max(0, t - 500); c--) {
1461
+ const d = s[c] ?? "", h = c === t ? o : d.length - 1;
1462
+ for (let p = h; p >= 0; p--)
1463
+ if (d[p] === r) a++;
1464
+ else if (d[p] === l && (a--, a === 0))
1465
+ return {
1466
+ open: { row: c, col: p },
1467
+ close: { row: t, col: o }
1468
+ };
1469
+ }
1470
+ }
1471
+ return null;
1472
+ }
1473
+ function lt(s, e) {
1474
+ const t = s[e] ?? "";
1475
+ let i = 0;
1476
+ for (const n of t)
1477
+ n === "{" ? i++ : n === "}" && i--;
1478
+ return i > 0;
1479
+ }
1480
+ function ct(s, e) {
1481
+ let t = 0;
1482
+ for (let i = e; i < s.length; i++)
1483
+ for (const n of s[i] ?? "")
1484
+ if (n === "{") t++;
1485
+ else if (n === "}" && (t--, t === 0))
1486
+ return i;
1487
+ return null;
1488
+ }
1489
+ function dt(s, e, t) {
1490
+ const i = new Map(s);
1491
+ if (i.has(t))
1492
+ i.delete(t);
1493
+ else {
1494
+ const n = ct(e, t);
1495
+ n !== null && n > t && i.set(t, n);
1496
+ }
1497
+ return i;
1498
+ }
1499
+ const pt = /* @__PURE__ */ new Set([
1500
+ "img",
1501
+ "input",
1502
+ "br",
1503
+ "hr",
1504
+ "meta",
1505
+ "link",
1506
+ "area",
1507
+ "base",
1508
+ "col",
1509
+ "embed",
1510
+ "param",
1511
+ "source",
1512
+ "track",
1513
+ "wbr"
1514
+ ]);
1515
+ function ve(s) {
1516
+ const e = s.trim();
1517
+ if (!e) return null;
1518
+ try {
1519
+ const t = ne(e);
1520
+ return t === e ? null : t;
1521
+ } catch {
1522
+ return null;
1523
+ }
1524
+ }
1525
+ function ne(s) {
1526
+ if (s.includes(">")) {
1527
+ const t = s.indexOf(">");
1528
+ return te(s.slice(0, t), ne(s.slice(t + 1)));
1529
+ }
1530
+ if (s.includes("+"))
1531
+ return s.split("+").map((t) => ne(t.trim())).join(`
1532
+ `);
1533
+ const e = s.match(/^(.+)\*(\d+)$/);
1534
+ if (e) {
1535
+ const t = parseInt(e[2], 10);
1536
+ return Array.from({ length: t }, (i, n) => te(e[1], `$${n + 1}`)).join(`
1537
+ `);
1538
+ }
1539
+ return te(s, "$1");
1540
+ }
1541
+ function te(s, e) {
1542
+ const t = s.match(/#([\w-]+)/), i = s.match(/\.([\w.-]+)/g), n = s.match(/\[([^\]]+)\]/);
1543
+ let r = s.replace(/#[\w-]+/g, "").replace(/\.[\w.-]+/g, "").replace(/\[[^\]]+\]/g, "").trim() || "div", o = "";
1544
+ return t && (o += ` id="${t[1]}"`), i && (o += ` class="${i.map((l) => l.slice(1)).join(" ")}"`), n && (o += ` ${n[1]}`), pt.has(r) ? `<${r}${o}>` : `<${r}${o}>${e}</${r}>`;
1545
+ }
1546
+ function we(s, e) {
1547
+ let t = e;
1548
+ for (; t > 0 && /[\w#.[\]*>+{}()$@:-]/.test(s[t - 1]); ) t--;
1549
+ const i = s.slice(t, e);
1550
+ return i.length < 2 ? null : { abbr: i, start: t };
1551
+ }
1552
+ const ht = [
1553
+ {
1554
+ label: "fn",
1555
+ kind: "snip",
1556
+ detail: "function declaration",
1557
+ description: `Declares a named function.
1558
+
1559
+ function name(params) {
1560
+ // body
1561
+ }`,
1562
+ body: `function $1($2) {
1563
+ $3
1564
+ }`
1565
+ },
1566
+ {
1567
+ label: "afn",
1568
+ kind: "snip",
1569
+ detail: "arrow function",
1570
+ description: `Declares a const arrow function.
1571
+
1572
+ const name = (params) => {
1573
+ // body
1574
+ };`,
1575
+ body: `const $1 = ($2) => {
1576
+ $3
1577
+ };`
1578
+ },
1579
+ {
1580
+ label: "asyncfn",
1581
+ kind: "snip",
1582
+ detail: "async function",
1583
+ description: `Declares an async function returning a Promise.
1584
+
1585
+ async function name(params): Promise<T> {
1586
+ // body
1587
+ }`,
1588
+ body: `async function $1($2): Promise<$3> {
1589
+ $4
1590
+ }`
1591
+ },
1592
+ {
1593
+ label: "cl",
1594
+ kind: "snip",
1595
+ detail: "class declaration",
1596
+ description: `Declares a class with a constructor.
1597
+
1598
+ class Name {
1599
+ constructor(params) { ... }
1600
+ }`,
1601
+ body: `class $1 {
1602
+ constructor($2) {
1603
+ $3
1604
+ }
1605
+ }`
1606
+ },
1607
+ {
1608
+ label: "forof",
1609
+ kind: "snip",
1610
+ detail: "for…of loop",
1611
+ description: `Iterates over the values of an iterable (array, string, Map, etc.).
1612
+
1613
+ for (const item of iterable) { ... }`,
1614
+ body: `for (const $1 of $2) {
1615
+ $3
1616
+ }`
1617
+ },
1618
+ {
1619
+ label: "forin",
1620
+ kind: "snip",
1621
+ detail: "for…in loop",
1622
+ description: `Iterates over the enumerable property keys of an object.
1623
+
1624
+ for (const key in object) { ... }`,
1625
+ body: `for (const $1 in $2) {
1626
+ $3
1627
+ }`
1628
+ },
1629
+ {
1630
+ label: "trycatch",
1631
+ kind: "snip",
1632
+ detail: "try / catch block",
1633
+ description: `Wraps code in a try/catch to handle runtime errors.
1634
+
1635
+ try {
1636
+ ...
1637
+ } catch (error) {
1638
+ ...
1639
+ }`,
1640
+ body: `try {
1641
+ $1
1642
+ } catch ($2error) {
1643
+ $3
1644
+ }`
1645
+ },
1646
+ {
1647
+ label: "promise",
1648
+ kind: "snip",
1649
+ detail: "new Promise",
1650
+ description: `Creates a new Promise with resolve and reject handlers.
1651
+
1652
+ new Promise<T>((resolve, reject) => { ... })`,
1653
+ body: `new Promise<$1>((resolve, reject) => {
1654
+ $2
1655
+ })`
1656
+ },
1657
+ {
1658
+ label: "imp",
1659
+ kind: "snip",
1660
+ detail: "import statement",
1661
+ description: `Adds a named import from a module.
1662
+
1663
+ import { name } from 'module';`,
1664
+ body: "import { $1 } from '$2';"
1665
+ },
1666
+ {
1667
+ label: "iface",
1668
+ kind: "snip",
1669
+ detail: "interface (TypeScript)",
1670
+ description: `Declares a TypeScript interface.
1671
+
1672
+ interface Name {
1673
+ field: Type;
1674
+ }`,
1675
+ body: `interface $1 {
1676
+ $2: $3;
1677
+ }`,
1678
+ language: ["typescript"]
1679
+ },
1680
+ {
1681
+ label: "ife",
1682
+ kind: "snip",
1683
+ detail: "immediately-invoked function expression",
1684
+ description: `An IIFE — defines and immediately calls a function.
1685
+
1686
+ ((params) => {
1687
+ ...
1688
+ })(args);`,
1689
+ body: `(($1) => {
1690
+ $2
1691
+ })($3);`
1692
+ },
1693
+ {
1694
+ label: "sw",
1695
+ kind: "snip",
1696
+ detail: "switch statement",
1697
+ description: `A switch/case statement with a default branch.
1698
+
1699
+ switch (expr) {
1700
+ case value:
1701
+ ...
1702
+ break;
1703
+ default:
1704
+ ...
1705
+ }`,
1706
+ body: `switch ($1) {
1707
+ case $2:
1708
+ $3
1709
+ break;
1710
+ default:
1711
+ $4
1712
+ }`
1713
+ }
1714
+ ], ut = [
1715
+ {
1716
+ label: "flex",
1717
+ kind: "snip",
1718
+ detail: "flexbox container",
1719
+ description: `Sets up a flex container with centered alignment.
1720
+
1721
+ display: flex;
1722
+ align-items: center;
1723
+ justify-content: center;`,
1724
+ body: `display: flex;
1725
+ align-items: $1center;
1726
+ justify-content: $2center;`,
1727
+ language: ["css"]
1728
+ },
1729
+ {
1730
+ label: "grid",
1731
+ kind: "snip",
1732
+ detail: "CSS grid",
1733
+ description: `Sets up a CSS grid with equal columns and gap.
1734
+
1735
+ display: grid;
1736
+ grid-template-columns: repeat(3, 1fr);
1737
+ gap: 16px;`,
1738
+ body: `display: grid;
1739
+ grid-template-columns: $1repeat(3, 1fr);
1740
+ gap: $2;`,
1741
+ language: ["css"]
1742
+ },
1743
+ {
1744
+ label: "media",
1745
+ kind: "snip",
1746
+ detail: "@media query",
1747
+ description: `A responsive media query breakpoint.
1748
+
1749
+ @media (max-width: 768px) {
1750
+ ...
1751
+ }`,
1752
+ body: `@media ($1max-width: 768px) {
1753
+ $2
1754
+ }`,
1755
+ language: ["css"]
1756
+ },
1757
+ {
1758
+ label: "anim",
1759
+ kind: "snip",
1760
+ detail: "@keyframes animation",
1761
+ description: `A CSS keyframes animation block.
1762
+
1763
+ @keyframes name {
1764
+ from { ... }
1765
+ to { ... }
1766
+ }`,
1767
+ body: `@keyframes $1 {
1768
+ from { $2 }
1769
+ to { $3 }
1770
+ }`,
1771
+ language: ["css"]
1772
+ },
1773
+ {
1774
+ label: "var",
1775
+ kind: "snip",
1776
+ detail: "CSS custom property",
1777
+ description: `Declares a CSS custom property (variable).
1778
+
1779
+ --name: value;`,
1780
+ body: "--$1: $2;",
1781
+ language: ["css"]
1782
+ }
1783
+ ], ft = [
1784
+ {
1785
+ label: "accordion",
1786
+ kind: "snip",
1787
+ detail: "HTML details/summary",
1788
+ description: `An accessible accordion using the native <details> and <summary> elements.
1789
+
1790
+ <details>
1791
+ <summary>Title</summary>
1792
+ <div>content</div>
1793
+ </details>`,
1794
+ body: `<details>
1795
+ <summary>$1Title</summary>
1796
+ <div>
1797
+ $2
1798
+ </div>
1799
+ </details>`
1800
+ },
1801
+ {
1802
+ label: "card",
1803
+ kind: "snip",
1804
+ detail: "card component",
1805
+ description: "A generic card component with header, body, and footer sections.",
1806
+ body: `<div class="card">
1807
+ <div class="card-header">$1</div>
1808
+ <div class="card-body">$2</div>
1809
+ <div class="card-footer">$3</div>
1810
+ </div>`
1811
+ },
1812
+ {
1813
+ label: "navbar",
1814
+ kind: "snip",
1815
+ detail: "navigation bar",
1816
+ description: `A simple navigation bar with anchor links.
1817
+
1818
+ <nav class="navbar">
1819
+ <a href="#">Home</a> ...
1820
+ </nav>`,
1821
+ body: `<nav class="navbar">
1822
+ <a href="$1#">Home</a>
1823
+ <a href="$2#">About</a>
1824
+ <a href="$3#">Contact</a>
1825
+ </nav>`
1826
+ },
1827
+ {
1828
+ label: "modal",
1829
+ kind: "snip",
1830
+ detail: "modal dialog",
1831
+ description: `A modal dialog layout with header, body, and footer.
1832
+
1833
+ <div class="modal">
1834
+ <div class="modal-dialog"> ... </div>
1835
+ </div>`,
1836
+ body: `<div class="modal">
1837
+ <div class="modal-dialog">
1838
+ <div class="modal-header">$1</div>
1839
+ <div class="modal-body">$2</div>
1840
+ <div class="modal-footer">$3</div>
1841
+ </div>
1842
+ </div>`
1843
+ },
1844
+ {
1845
+ label: "table",
1846
+ kind: "snip",
1847
+ detail: "HTML table",
1848
+ description: `A semantic HTML table with thead and tbody.
1849
+
1850
+ <table>
1851
+ <thead><tr><th>...</th></tr></thead>
1852
+ <tbody><tr><td>...</td></tr></tbody>
1853
+ </table>`,
1854
+ body: `<table>
1855
+ <thead>
1856
+ <tr>
1857
+ <th>$1</th>
1858
+ </tr>
1859
+ </thead>
1860
+ <tbody>
1861
+ <tr>
1862
+ <td>$2</td>
1863
+ </tr>
1864
+ </tbody>
1865
+ </table>`
1866
+ }
1867
+ ];
1868
+ function gt(s) {
1869
+ const e = [...ft];
1870
+ return (s === "typescript" || s === "javascript") && e.push(...ht.filter((t) => !t.language || (Array.isArray(t.language) ? t.language.includes(s) : t.language === s))), s === "css" && e.push(...ut), e;
1871
+ }
1872
+ function bt(s, e, t) {
1873
+ let i = e;
1874
+ for (; i > 0 && /\w/.test(s[i - 1]); ) i--;
1875
+ const n = s.slice(i, e);
1876
+ if (!n) return null;
1877
+ const r = t.find((o) => o.kind === "snip" && o.label === n);
1878
+ return r ? { snippet: r, start: i } : null;
1879
+ }
1880
+ function mt() {
1881
+ return { cursors: [], searchWord: "", lastMatchRow: -1, lastMatchCol: -1 };
1882
+ }
1883
+ function ke(s, e, t, i) {
1884
+ s.cursors.some((r) => r.row === e && r.col === t) || s.cursors.push({ row: e, col: t, sel: i });
1885
+ }
1886
+ function xe(s) {
1887
+ s.cursors = [], s.searchWord = "", s.lastMatchRow = -1, s.lastMatchCol = -1;
1888
+ }
1889
+ function _t(s, e, t, i, n) {
1890
+ const r = [
1891
+ { row: e, col: t, isPrimary: !0, idx: 0 },
1892
+ ...i.map((d, h) => ({ row: d.row, col: d.col, isPrimary: !1, idx: h + 1 }))
1893
+ ];
1894
+ r.sort((d, h) => h.row !== d.row ? h.row - d.row : h.col - d.col);
1895
+ const o = s.map((d) => d);
1896
+ let l = e, a = t;
1897
+ const c = i.map((d) => ({ ...d }));
1898
+ for (const d of r) {
1899
+ const h = o[d.row] ?? "";
1900
+ o[d.row] = h.slice(0, d.col) + n + h.slice(d.col);
1901
+ for (const p of r)
1902
+ p !== d && p.row === d.row && p.col >= d.col && (p.col += n.length);
1903
+ d.col += n.length, d.isPrimary ? (l = d.row, a = d.col) : (c[d.idx - 1].row = d.row, c[d.idx - 1].col = d.col);
1904
+ }
1905
+ return { doc: o, primaryRow: l, primaryCol: a, extraCursors: c };
1906
+ }
1907
+ function yt(s, e, t, i) {
1908
+ const n = [
1909
+ { row: e, col: t, isPrimary: !0, idx: 0 },
1910
+ ...i.map((c, d) => ({ row: c.row, col: c.col, isPrimary: !1, idx: d + 1 }))
1911
+ ];
1912
+ n.sort((c, d) => d.row !== c.row ? d.row - c.row : d.col - c.col);
1913
+ const r = s.map((c) => c);
1914
+ let o = e, l = t;
1915
+ const a = i.map((c) => ({ ...c }));
1916
+ for (const c of n) {
1917
+ if (c.col <= 0) continue;
1918
+ const d = r[c.row] ?? "";
1919
+ r[c.row] = d.slice(0, c.col - 1) + d.slice(c.col);
1920
+ for (const h of n)
1921
+ h !== c && h.row === c.row && h.col > c.col && h.col--;
1922
+ c.col--, c.isPrimary ? (o = c.row, l = c.col) : a[c.idx - 1].col = c.col;
1923
+ }
1924
+ return { doc: r, primaryRow: o, primaryCol: l, extraCursors: a };
1925
+ }
1926
+ function vt(s, e, t, i, n) {
1927
+ let r = s.searchWord;
1928
+ if (!r) {
1929
+ if (n && n.ar === n.fr && (r = (e[n.ar] ?? "").slice(n.ac, n.fc)), !r) {
1930
+ const a = e[t] ?? "", c = le(a, i), d = ce(a, i);
1931
+ r = a.slice(c, d);
1932
+ }
1933
+ if (!r) return null;
1934
+ s.searchWord = r, s.lastMatchRow = t, s.lastMatchCol = i;
1935
+ }
1936
+ const o = s.lastMatchRow, l = s.lastMatchCol;
1937
+ for (let a = o; a < e.length; a++) {
1938
+ const c = e[a] ?? "";
1939
+ let h = a === o ? l : 0;
1940
+ for (; h <= c.length - r.length; ) {
1941
+ const p = c.indexOf(r, h);
1942
+ if (p < 0) break;
1943
+ const f = p === 0 || !/\w/.test(c[p - 1]), _ = p + r.length >= c.length || !/\w/.test(c[p + r.length]);
1944
+ if (f && _)
1945
+ return s.lastMatchRow = a, s.lastMatchCol = p + r.length, {
1946
+ word: r,
1947
+ sel: { ar: a, ac: p, fr: a, fc: p + r.length },
1948
+ row: a,
1949
+ col: p + r.length
1950
+ };
1951
+ h = p + 1;
1952
+ }
1953
+ }
1954
+ for (let a = 0; a <= o; a++) {
1955
+ const c = e[a] ?? "", d = a === o ? l : c.length;
1956
+ let h = 0;
1957
+ for (; h < d; ) {
1958
+ const p = c.indexOf(r, h);
1959
+ if (p < 0 || p >= d) break;
1960
+ const f = p === 0 || !/\w/.test(c[p - 1]), _ = p + r.length >= c.length || !/\w/.test(c[p + r.length]);
1961
+ if (f && _)
1962
+ return s.lastMatchRow = a, s.lastMatchCol = p + r.length, {
1963
+ word: r,
1964
+ sel: { ar: a, ac: p, fr: a, fc: p + r.length },
1965
+ row: a,
1966
+ col: p + r.length
1967
+ };
1968
+ h = p + 1;
1969
+ }
1970
+ }
1971
+ return null;
1972
+ }
1973
+ function wt(s, e, t) {
1974
+ if (!e) return [];
1975
+ const i = [];
1976
+ for (let n = 0; n < s.length; n++) {
1977
+ const r = s[n] ?? "";
1978
+ if (t.useRegex)
1979
+ try {
1980
+ const o = new RegExp(e, t.caseSensitive ? "g" : "gi");
1981
+ let l;
1982
+ for (; (l = o.exec(r)) !== null && (i.push({ row: n, col: l.index, len: l[0].length }), !!l[0].length); )
1983
+ ;
1984
+ } catch {
1985
+ }
1986
+ else {
1987
+ const o = t.caseSensitive ? r : r.toLowerCase(), l = t.caseSensitive ? e : e.toLowerCase();
1988
+ let a = 0;
1989
+ for (; ; ) {
1990
+ const c = o.indexOf(l, a);
1991
+ if (c === -1) break;
1992
+ i.push({ row: n, col: c, len: e.length }), a = c + 1;
1993
+ }
1994
+ }
1995
+ }
1996
+ return i;
1997
+ }
1998
+ function kt(s, e, t, i) {
1999
+ const n = e[t];
2000
+ if (!n) return s;
2001
+ const r = [...s], o = r[n.row] ?? "";
2002
+ return r[n.row] = o.slice(0, n.col) + i + o.slice(n.col + n.len), r;
2003
+ }
2004
+ function xt(s, e, t) {
2005
+ const i = [...s];
2006
+ for (let n = e.length - 1; n >= 0; n--) {
2007
+ const r = e[n], o = i[r.row] ?? "";
2008
+ i[r.row] = o.slice(0, r.col) + t + o.slice(r.col + r.len);
2009
+ }
2010
+ return i;
2011
+ }
2012
+ function Tt(s, e, t) {
2013
+ return s.length ? (e + t + s.length) % s.length : -1;
2014
+ }
2015
+ function Ct(s, e, t, i) {
2016
+ if (i) return [];
2017
+ const n = s[e] ?? "", r = le(n, t), o = ce(n, t), l = n.slice(r, o);
2018
+ if (!l || l.length < 2) return [];
2019
+ const a = [];
2020
+ for (let c = 0; c < s.length; c++) {
2021
+ const d = s[c] ?? "";
2022
+ let h = 0;
2023
+ for (; h <= d.length - l.length; ) {
2024
+ const p = d.indexOf(l, h);
2025
+ if (p < 0) break;
2026
+ const f = p === 0 || !/\w/.test(d[p - 1]), _ = p + l.length >= d.length || !/\w/.test(d[p + l.length]);
2027
+ f && _ && !(c === e && p === r) && a.push({ row: c, col: p, len: l.length }), h = p + 1;
2028
+ }
2029
+ }
2030
+ return a;
2031
+ }
2032
+ const re = [
2033
+ { label: "console.log", kind: "fn", detail: "void" },
2034
+ { label: "console.error", kind: "fn", detail: "void" },
2035
+ { label: "console.warn", kind: "fn", detail: "void" },
2036
+ { label: "console.info", kind: "fn", detail: "void" },
2037
+ { label: "console.table", kind: "fn", detail: "void" },
2038
+ { label: "document.getElementById", kind: "fn", detail: "HTMLElement | null" },
2039
+ { label: "document.querySelector", kind: "fn", detail: "Element | null" },
2040
+ { label: "document.querySelectorAll", kind: "fn", detail: "NodeList" },
2041
+ { label: "document.createElement", kind: "fn", detail: "HTMLElement" },
2042
+ { label: "document.createTextNode", kind: "fn", detail: "Text" },
2043
+ { label: "addEventListener", kind: "fn", detail: "(ev, cb) => void" },
2044
+ { label: "removeEventListener", kind: "fn", detail: "(ev, cb) => void" },
2045
+ { label: "requestAnimationFrame", kind: "fn", detail: "(cb) => number" },
2046
+ { label: "cancelAnimationFrame", kind: "fn", detail: "(id) => void" },
2047
+ { label: "setTimeout", kind: "fn", detail: "(cb, ms) => id" },
2048
+ { label: "clearTimeout", kind: "fn", detail: "(id) => void" },
2049
+ { label: "setInterval", kind: "fn", detail: "(cb, ms) => id" },
2050
+ { label: "clearInterval", kind: "fn", detail: "(id) => void" },
2051
+ { label: "JSON.stringify", kind: "fn", detail: "string" },
2052
+ { label: "JSON.parse", kind: "fn", detail: "any" },
2053
+ { label: "Math.max", kind: "fn", detail: "number" },
2054
+ { label: "Math.min", kind: "fn", detail: "number" },
2055
+ { label: "Math.floor", kind: "fn", detail: "number" },
2056
+ { label: "Math.ceil", kind: "fn", detail: "number" },
2057
+ { label: "Math.round", kind: "fn", detail: "number" },
2058
+ { label: "Math.abs", kind: "fn", detail: "number" },
2059
+ { label: "Math.pow", kind: "fn", detail: "number" },
2060
+ { label: "Math.sqrt", kind: "fn", detail: "number" },
2061
+ { label: "Math.random", kind: "fn", detail: "number" },
2062
+ { label: "Object.keys", kind: "fn", detail: "string[]" },
2063
+ { label: "Object.values", kind: "fn", detail: "any[]" },
2064
+ { label: "Object.entries", kind: "fn", detail: "[string, any][]" },
2065
+ { label: "Object.assign", kind: "fn", detail: "T & U" },
2066
+ { label: "Object.freeze", kind: "fn", detail: "Readonly<T>" },
2067
+ { label: "Object.create", kind: "fn", detail: "object" },
2068
+ { label: "Array.from", kind: "fn", detail: "T[]" },
2069
+ { label: "Array.isArray", kind: "fn", detail: "boolean" },
2070
+ { label: "Promise.all", kind: "fn", detail: "Promise<T[]>" },
2071
+ { label: "Promise.resolve", kind: "fn", detail: "Promise<T>" },
2072
+ { label: "Promise.reject", kind: "fn", detail: "Promise<never>" },
2073
+ { label: "Promise.allSettled", kind: "fn", detail: "Promise<...>" },
2074
+ { label: "parseInt", kind: "fn", detail: "number" },
2075
+ { label: "parseFloat", kind: "fn", detail: "number" },
2076
+ { label: "isNaN", kind: "fn", detail: "boolean" },
2077
+ { label: "isFinite", kind: "fn", detail: "boolean" },
2078
+ { label: "encodeURIComponent", kind: "fn", detail: "string" },
2079
+ { label: "decodeURIComponent", kind: "fn", detail: "string" },
2080
+ { label: "structuredClone", kind: "fn", detail: "T" },
2081
+ { label: "queueMicrotask", kind: "fn", detail: "void" },
2082
+ { label: "fetch", kind: "fn", detail: "Promise<Response>" }
2083
+ ], St = [
2084
+ // ── Layout ────────────────────────────────────────────────
2085
+ { label: "display", kind: "var", detail: "property" },
2086
+ { label: "position", kind: "var", detail: "property" },
2087
+ { label: "top", kind: "var", detail: "property" },
2088
+ { label: "right", kind: "var", detail: "property" },
2089
+ { label: "bottom", kind: "var", detail: "property" },
2090
+ { label: "left", kind: "var", detail: "property" },
2091
+ { label: "width", kind: "var", detail: "property" },
2092
+ { label: "height", kind: "var", detail: "property" },
2093
+ { label: "min-width", kind: "var", detail: "property" },
2094
+ { label: "max-width", kind: "var", detail: "property" },
2095
+ { label: "min-height", kind: "var", detail: "property" },
2096
+ { label: "max-height", kind: "var", detail: "property" },
2097
+ { label: "z-index", kind: "var", detail: "property" },
2098
+ { label: "overflow", kind: "var", detail: "property" },
2099
+ { label: "overflow-x", kind: "var", detail: "property" },
2100
+ { label: "overflow-y", kind: "var", detail: "property" },
2101
+ { label: "box-sizing", kind: "var", detail: "property" },
2102
+ // ── Flexbox ───────────────────────────────────────────────
2103
+ { label: "flex", kind: "var", detail: "property" },
2104
+ { label: "flex-direction", kind: "var", detail: "property" },
2105
+ { label: "flex-wrap", kind: "var", detail: "property" },
2106
+ { label: "flex-grow", kind: "var", detail: "property" },
2107
+ { label: "flex-shrink", kind: "var", detail: "property" },
2108
+ { label: "flex-basis", kind: "var", detail: "property" },
2109
+ { label: "flex-flow", kind: "var", detail: "property" },
2110
+ { label: "align-items", kind: "var", detail: "property" },
2111
+ { label: "align-content", kind: "var", detail: "property" },
2112
+ { label: "align-self", kind: "var", detail: "property" },
2113
+ { label: "justify-content", kind: "var", detail: "property" },
2114
+ { label: "justify-items", kind: "var", detail: "property" },
2115
+ { label: "justify-self", kind: "var", detail: "property" },
2116
+ { label: "gap", kind: "var", detail: "property" },
2117
+ { label: "row-gap", kind: "var", detail: "property" },
2118
+ { label: "column-gap", kind: "var", detail: "property" },
2119
+ // ── Grid ──────────────────────────────────────────────────
2120
+ { label: "grid", kind: "var", detail: "property" },
2121
+ { label: "grid-template", kind: "var", detail: "property" },
2122
+ { label: "grid-template-columns", kind: "var", detail: "property" },
2123
+ { label: "grid-template-rows", kind: "var", detail: "property" },
2124
+ { label: "grid-template-areas", kind: "var", detail: "property" },
2125
+ { label: "grid-column", kind: "var", detail: "property" },
2126
+ { label: "grid-row", kind: "var", detail: "property" },
2127
+ { label: "grid-area", kind: "var", detail: "property" },
2128
+ { label: "grid-auto-flow", kind: "var", detail: "property" },
2129
+ // ── Spacing ───────────────────────────────────────────────
2130
+ { label: "margin", kind: "var", detail: "property" },
2131
+ { label: "margin-top", kind: "var", detail: "property" },
2132
+ { label: "margin-right", kind: "var", detail: "property" },
2133
+ { label: "margin-bottom", kind: "var", detail: "property" },
2134
+ { label: "margin-left", kind: "var", detail: "property" },
2135
+ { label: "padding", kind: "var", detail: "property" },
2136
+ { label: "padding-top", kind: "var", detail: "property" },
2137
+ { label: "padding-right", kind: "var", detail: "property" },
2138
+ { label: "padding-bottom", kind: "var", detail: "property" },
2139
+ { label: "padding-left", kind: "var", detail: "property" },
2140
+ // ── Typography ────────────────────────────────────────────
2141
+ { label: "color", kind: "var", detail: "property" },
2142
+ { label: "font", kind: "var", detail: "property" },
2143
+ { label: "font-family", kind: "var", detail: "property" },
2144
+ { label: "font-size", kind: "var", detail: "property" },
2145
+ { label: "font-weight", kind: "var", detail: "property" },
2146
+ { label: "font-style", kind: "var", detail: "property" },
2147
+ { label: "line-height", kind: "var", detail: "property" },
2148
+ { label: "text-align", kind: "var", detail: "property" },
2149
+ { label: "text-decoration", kind: "var", detail: "property" },
2150
+ { label: "text-transform", kind: "var", detail: "property" },
2151
+ { label: "letter-spacing", kind: "var", detail: "property" },
2152
+ { label: "word-spacing", kind: "var", detail: "property" },
2153
+ { label: "white-space", kind: "var", detail: "property" },
2154
+ { label: "word-break", kind: "var", detail: "property" },
2155
+ { label: "word-wrap", kind: "var", detail: "property" },
2156
+ { label: "text-overflow", kind: "var", detail: "property" },
2157
+ // ── Background ────────────────────────────────────────────
2158
+ { label: "background", kind: "var", detail: "property" },
2159
+ { label: "background-color", kind: "var", detail: "property" },
2160
+ { label: "background-image", kind: "var", detail: "property" },
2161
+ { label: "background-size", kind: "var", detail: "property" },
2162
+ { label: "background-position", kind: "var", detail: "property" },
2163
+ { label: "background-repeat", kind: "var", detail: "property" },
2164
+ { label: "background-clip", kind: "var", detail: "property" },
2165
+ { label: "background-attachment", kind: "var", detail: "property" },
2166
+ // ── Border ────────────────────────────────────────────────
2167
+ { label: "border", kind: "var", detail: "property" },
2168
+ { label: "border-width", kind: "var", detail: "property" },
2169
+ { label: "border-style", kind: "var", detail: "property" },
2170
+ { label: "border-color", kind: "var", detail: "property" },
2171
+ { label: "border-radius", kind: "var", detail: "property" },
2172
+ { label: "border-top", kind: "var", detail: "property" },
2173
+ { label: "border-right", kind: "var", detail: "property" },
2174
+ { label: "border-bottom", kind: "var", detail: "property" },
2175
+ { label: "border-left", kind: "var", detail: "property" },
2176
+ { label: "outline", kind: "var", detail: "property" },
2177
+ { label: "outline-width", kind: "var", detail: "property" },
2178
+ { label: "outline-style", kind: "var", detail: "property" },
2179
+ { label: "outline-color", kind: "var", detail: "property" },
2180
+ { label: "outline-offset", kind: "var", detail: "property" },
2181
+ // ── Effects ───────────────────────────────────────────────
2182
+ { label: "opacity", kind: "var", detail: "property" },
2183
+ { label: "box-shadow", kind: "var", detail: "property" },
2184
+ { label: "text-shadow", kind: "var", detail: "property" },
2185
+ { label: "filter", kind: "var", detail: "property" },
2186
+ { label: "backdrop-filter", kind: "var", detail: "property" },
2187
+ { label: "transform", kind: "var", detail: "property" },
2188
+ { label: "transform-origin", kind: "var", detail: "property" },
2189
+ { label: "transition", kind: "var", detail: "property" },
2190
+ { label: "animation", kind: "var", detail: "property" },
2191
+ { label: "animation-name", kind: "var", detail: "property" },
2192
+ { label: "animation-duration", kind: "var", detail: "property" },
2193
+ { label: "animation-timing-function", kind: "var", detail: "property" },
2194
+ { label: "animation-delay", kind: "var", detail: "property" },
2195
+ { label: "animation-iteration-count", kind: "var", detail: "property" },
2196
+ { label: "animation-fill-mode", kind: "var", detail: "property" },
2197
+ // ── Interaction ───────────────────────────────────────────
2198
+ { label: "cursor", kind: "var", detail: "property" },
2199
+ { label: "pointer-events", kind: "var", detail: "property" },
2200
+ { label: "user-select", kind: "var", detail: "property" },
2201
+ { label: "resize", kind: "var", detail: "property" },
2202
+ // ── Misc ──────────────────────────────────────────────────
2203
+ { label: "visibility", kind: "var", detail: "property" },
2204
+ { label: "content", kind: "var", detail: "property" },
2205
+ { label: "list-style", kind: "var", detail: "property" },
2206
+ { label: "will-change", kind: "var", detail: "property" },
2207
+ { label: "appearance", kind: "var", detail: "property" },
2208
+ { label: "clip-path", kind: "var", detail: "property" },
2209
+ { label: "object-fit", kind: "var", detail: "property" },
2210
+ { label: "object-position", kind: "var", detail: "property" },
2211
+ { label: "scroll-behavior", kind: "var", detail: "property" },
2212
+ { label: "aspect-ratio", kind: "var", detail: "property" },
2213
+ // ── CSS functions ─────────────────────────────────────────
2214
+ { label: "var", kind: "fn", detail: "css fn" },
2215
+ { label: "calc", kind: "fn", detail: "css fn" },
2216
+ { label: "min", kind: "fn", detail: "css fn" },
2217
+ { label: "max", kind: "fn", detail: "css fn" },
2218
+ { label: "clamp", kind: "fn", detail: "css fn" },
2219
+ { label: "rgb", kind: "fn", detail: "css fn" },
2220
+ { label: "rgba", kind: "fn", detail: "css fn" },
2221
+ { label: "hsl", kind: "fn", detail: "css fn" },
2222
+ { label: "hsla", kind: "fn", detail: "css fn" },
2223
+ { label: "oklch", kind: "fn", detail: "css fn" },
2224
+ { label: "linear-gradient", kind: "fn", detail: "css fn" },
2225
+ { label: "radial-gradient", kind: "fn", detail: "css fn" },
2226
+ { label: "conic-gradient", kind: "fn", detail: "css fn" },
2227
+ { label: "translate", kind: "fn", detail: "css fn" },
2228
+ { label: "scale", kind: "fn", detail: "css fn" },
2229
+ { label: "rotate", kind: "fn", detail: "css fn" },
2230
+ { label: "skew", kind: "fn", detail: "css fn" },
2231
+ { label: "matrix", kind: "fn", detail: "css fn" },
2232
+ { label: "perspective", kind: "fn", detail: "css fn" },
2233
+ { label: "url", kind: "fn", detail: "css fn" },
2234
+ { label: "attr", kind: "fn", detail: "css fn" },
2235
+ { label: "env", kind: "fn", detail: "css fn" },
2236
+ { label: "repeat", kind: "fn", detail: "css fn" },
2237
+ { label: "minmax", kind: "fn", detail: "css fn" },
2238
+ { label: "fit-content", kind: "fn", detail: "css fn" }
2239
+ ], Mt = {
2240
+ typescript: re,
2241
+ javascript: re,
2242
+ css: St,
2243
+ json: [],
2244
+ markdown: [],
2245
+ text: []
2246
+ };
2247
+ function Te(s, e, t) {
2248
+ const i = Me[s] ?? se, n = Ee[s] ?? oe, r = Mt[s] ?? re;
2249
+ return [
2250
+ ...[...i, ...e].map((o) => ({ label: o, kind: "kw", detail: "keyword" })),
2251
+ ...[...n, ...t].map((o) => ({ label: o, kind: "typ", detail: "type" })),
2252
+ ...r
2253
+ ];
2254
+ }
2255
+ function Et(s, e) {
2256
+ const t = /* @__PURE__ */ new Set();
2257
+ for (const i of s) {
2258
+ const n = i.match(/[a-zA-Z_$][\w$]*/g) ?? [];
2259
+ for (const r of n)
2260
+ r !== e && r.length > 2 && t.add(r);
2261
+ }
2262
+ return t;
2263
+ }
2264
+ function Ce(s, e) {
2265
+ return s.language ? Array.isArray(s.language) ? s.language.includes(e) : s.language === e : !0;
2266
+ }
2267
+ function Lt(s, e, t = {}, i = 0, n = 0) {
2268
+ if (e.length < 2) return [];
2269
+ const r = e.toLowerCase(), {
2270
+ language: o = "typescript",
2271
+ extraKeywords: l = [],
2272
+ extraTypes: a = [],
2273
+ completions: c = [],
2274
+ replaceBuiltins: d = !1,
2275
+ maxResults: h = 14
2276
+ } = t, p = c.filter((y) => y.kind === "snip" && !!y.body && Ce(y, o)), f = c.filter((y) => !(y.kind === "snip" && y.body) && Ce(y, o)), _ = p.filter((y) => y.label.toLowerCase().startsWith(r));
2277
+ let b;
2278
+ if (t.provideCompletions) {
2279
+ const y = {
2280
+ line: s[i] ?? "",
2281
+ col: n,
2282
+ prefix: e,
2283
+ language: o,
2284
+ doc: s
2285
+ };
2286
+ let D;
2287
+ try {
2288
+ D = t.provideCompletions(y);
2289
+ } catch (R) {
2290
+ console.error("[syncline-editor] provideCompletions threw an error:", R), D = null;
2291
+ }
2292
+ b = D != null ? [...D, ...f] : [...d ? [] : Te(o, l, a), ...f];
2293
+ } else
2294
+ b = d ? f : [...Te(o, l, a), ...f];
2295
+ const v = new Set(b.map((y) => y.label)), u = b.filter(
2296
+ (y) => y.label.toLowerCase().startsWith(r) && y.label !== e
2297
+ ), T = new Set(_.map((y) => y.label)), w = [...Et(s, e)].filter((y) => y.toLowerCase().startsWith(r) && !v.has(y) && !T.has(y)).slice(0, 8).map((y) => ({ label: y, kind: "var", detail: "in file" }));
2298
+ return [
2299
+ ..._,
2300
+ ...u.filter((y) => !T.has(y.label)),
2301
+ ...w
2302
+ ].slice(0, h);
2303
+ }
2304
+ function It(s, e, t = !1) {
2305
+ let i = e;
2306
+ for (; i > 0 && (t ? /[\w$.\-]/ : /[\w$.]/).test(s[i - 1]); ) i--;
2307
+ return { prefix: s.slice(i, e), start: i };
2308
+ }
2309
+ function At(s, e) {
2310
+ const t = (r) => /[\w$]/.test(r);
2311
+ let i = e;
2312
+ for (; i < s.length && t(s[i]); ) i++;
2313
+ let n = e;
2314
+ for (; n > 0 && t(s[n - 1]); ) n--;
2315
+ if (n === i) return "";
2316
+ if (n > 0 && s[n - 1] === ".") {
2317
+ let r = n - 1, o = r;
2318
+ for (; o > 0 && t(s[o - 1]); ) o--;
2319
+ if (o < r)
2320
+ return s.slice(o, i);
2321
+ }
2322
+ return s.slice(n, i);
2323
+ }
2324
+ const Dt = {
2325
+ // ── console ───────────────────────────────────────────────
2326
+ console: {
2327
+ title: "console",
2328
+ type: "Console",
2329
+ body: "Provides access to the browser's debugging console. Useful for logging, timing, profiling, and inspecting values during development.",
2330
+ language: ["typescript", "javascript"]
2331
+ },
2332
+ "console.log": {
2333
+ title: "console.log()",
2334
+ type: "(...data: any[]) => void",
2335
+ body: "Outputs a message to the web console. Accepts any number of arguments — objects are logged as expandable trees, primitives as their string form.",
2336
+ language: ["typescript", "javascript"]
2337
+ },
2338
+ "console.error": {
2339
+ title: "console.error()",
2340
+ type: "(...data: any[]) => void",
2341
+ body: "Logs an error message to the console, typically rendered in red with a stack trace. Use for unrecoverable failures.",
2342
+ language: ["typescript", "javascript"]
2343
+ },
2344
+ "console.warn": {
2345
+ title: "console.warn()",
2346
+ type: "(...data: any[]) => void",
2347
+ body: "Logs a warning message to the console, typically rendered in yellow. Use for non-fatal issues or deprecation notices.",
2348
+ language: ["typescript", "javascript"]
2349
+ },
2350
+ "console.info": {
2351
+ title: "console.info()",
2352
+ type: "(...data: any[]) => void",
2353
+ body: "Logs an informational message. Behaves identically to console.log in most environments.",
2354
+ language: ["typescript", "javascript"]
2355
+ },
2356
+ "console.table": {
2357
+ title: "console.table()",
2358
+ type: "(data: any, columns?: string[]) => void",
2359
+ body: "Displays an array or object as a formatted table in the console. Optionally restrict displayed columns.",
2360
+ language: ["typescript", "javascript"]
2361
+ },
2362
+ "console.time": {
2363
+ title: "console.time()",
2364
+ type: "(label?: string) => void",
2365
+ body: "Starts a timer with the given label. Call console.timeEnd() with the same label to log the elapsed time.",
2366
+ language: ["typescript", "javascript"]
2367
+ },
2368
+ "console.timeEnd": {
2369
+ title: "console.timeEnd()",
2370
+ type: "(label?: string) => void",
2371
+ body: "Stops the timer started by console.time() and logs the elapsed duration in milliseconds.",
2372
+ language: ["typescript", "javascript"]
2373
+ },
2374
+ "console.group": {
2375
+ title: "console.group()",
2376
+ type: "(...label: any[]) => void",
2377
+ body: "Creates a new inline group in the console output, indenting subsequent messages until console.groupEnd() is called.",
2378
+ language: ["typescript", "javascript"]
2379
+ },
2380
+ "console.groupEnd": {
2381
+ title: "console.groupEnd()",
2382
+ type: "() => void",
2383
+ body: "Closes the current inline group in the console, exiting the indented group created by console.group().",
2384
+ language: ["typescript", "javascript"]
2385
+ },
2386
+ // ── Math ──────────────────────────────────────────────────
2387
+ Math: {
2388
+ title: "Math",
2389
+ type: "namespace Math",
2390
+ body: "A built-in object with properties and methods for mathematical constants and functions. Not a constructor — all properties and methods are static.",
2391
+ language: ["typescript", "javascript"]
2392
+ },
2393
+ "Math.max": {
2394
+ title: "Math.max()",
2395
+ type: "(...values: number[]) => number",
2396
+ body: "Returns the largest of the given numbers. Returns -Infinity if no arguments, or NaN if any argument is not a number.",
2397
+ language: ["typescript", "javascript"]
2398
+ },
2399
+ "Math.min": {
2400
+ title: "Math.min()",
2401
+ type: "(...values: number[]) => number",
2402
+ body: "Returns the smallest of the given numbers. Returns Infinity if no arguments, or NaN if any argument is not a number.",
2403
+ language: ["typescript", "javascript"]
2404
+ },
2405
+ "Math.floor": {
2406
+ title: "Math.floor()",
2407
+ type: "(x: number) => number",
2408
+ body: "Returns the largest integer less than or equal to x. Rounds toward negative infinity.",
2409
+ language: ["typescript", "javascript"]
2410
+ },
2411
+ "Math.ceil": {
2412
+ title: "Math.ceil()",
2413
+ type: "(x: number) => number",
2414
+ body: "Returns the smallest integer greater than or equal to x. Rounds toward positive infinity.",
2415
+ language: ["typescript", "javascript"]
2416
+ },
2417
+ "Math.round": {
2418
+ title: "Math.round()",
2419
+ type: "(x: number) => number",
2420
+ body: "Returns the value of x rounded to the nearest integer. Values with a fractional part of exactly 0.5 round up.",
2421
+ language: ["typescript", "javascript"]
2422
+ },
2423
+ "Math.abs": {
2424
+ title: "Math.abs()",
2425
+ type: "(x: number) => number",
2426
+ body: "Returns the absolute (non-negative) value of x.",
2427
+ language: ["typescript", "javascript"]
2428
+ },
2429
+ "Math.sqrt": {
2430
+ title: "Math.sqrt()",
2431
+ type: "(x: number) => number",
2432
+ body: "Returns the square root of x. Returns NaN if x is negative.",
2433
+ language: ["typescript", "javascript"]
2434
+ },
2435
+ "Math.pow": {
2436
+ title: "Math.pow()",
2437
+ type: "(base: number, exponent: number) => number",
2438
+ body: "Returns base raised to the power of exponent. Equivalent to the ** operator.",
2439
+ language: ["typescript", "javascript"]
2440
+ },
2441
+ "Math.random": {
2442
+ title: "Math.random()",
2443
+ type: "() => number",
2444
+ body: "Returns a pseudo-random floating-point number in the range [0, 1). Not cryptographically secure — use crypto.getRandomValues() for security-sensitive code.",
2445
+ language: ["typescript", "javascript"]
2446
+ },
2447
+ "Math.PI": {
2448
+ title: "Math.PI",
2449
+ type: "number",
2450
+ body: "The ratio of a circle's circumference to its diameter: approximately 3.14159265358979.",
2451
+ language: ["typescript", "javascript"]
2452
+ },
2453
+ "Math.trunc": {
2454
+ title: "Math.trunc()",
2455
+ type: "(x: number) => number",
2456
+ body: "Returns the integer part of x by removing any fractional digits. Does not round — simply truncates toward zero.",
2457
+ language: ["typescript", "javascript"]
2458
+ },
2459
+ "Math.sign": {
2460
+ title: "Math.sign()",
2461
+ type: "(x: number) => number",
2462
+ body: "Returns 1 if x is positive, -1 if x is negative, 0 if x is zero, or NaN if x is not a number.",
2463
+ language: ["typescript", "javascript"]
2464
+ },
2465
+ "Math.clamp": {
2466
+ title: "Math.clamp()",
2467
+ type: "(value: number, min: number, max: number) => number",
2468
+ body: "Clamps value between min and max. Note: not yet standard — use Math.min(Math.max(value, min), max) for compatibility.",
2469
+ language: ["typescript", "javascript"]
2470
+ },
2471
+ // ── JSON ──────────────────────────────────────────────────
2472
+ JSON: {
2473
+ title: "JSON",
2474
+ type: "namespace JSON",
2475
+ body: "Provides methods for parsing and serializing JSON (JavaScript Object Notation). All methods are static.",
2476
+ language: ["typescript", "javascript"]
2477
+ },
2478
+ "JSON.stringify": {
2479
+ title: "JSON.stringify()",
2480
+ type: "(value: any, replacer?: any, space?: string | number) => string",
2481
+ body: "Converts a JavaScript value to a JSON string. Pass a number or string as the third argument to pretty-print with indentation. Throws on circular references.",
2482
+ language: ["typescript", "javascript"]
2483
+ },
2484
+ "JSON.parse": {
2485
+ title: "JSON.parse()",
2486
+ type: "(text: string, reviver?: (key: string, value: any) => any) => any",
2487
+ body: "Parses a JSON string and returns the corresponding JavaScript value. Throws SyntaxError if the string is not valid JSON.",
2488
+ language: ["typescript", "javascript"]
2489
+ },
2490
+ // ── Array ─────────────────────────────────────────────────
2491
+ Array: {
2492
+ title: "Array",
2493
+ type: "interface Array<T>",
2494
+ body: "Represents an ordered list of values. Provides methods for traversal, mutation, searching, and transformation.",
2495
+ language: ["typescript", "javascript"]
2496
+ },
2497
+ "Array.from": {
2498
+ title: "Array.from()",
2499
+ type: "<T>(arrayLike: Iterable<T> | ArrayLike<T>, mapFn?: (v: T, i: number) => T) => T[]",
2500
+ body: "Creates a new Array from an array-like or iterable object (e.g. NodeList, Set, Map, string). Optionally applies a mapping function.",
2501
+ language: ["typescript", "javascript"]
2502
+ },
2503
+ "Array.isArray": {
2504
+ title: "Array.isArray()",
2505
+ type: "(value: unknown) => value is any[]",
2506
+ body: "Returns true if the given value is an Array. More reliable than instanceof Array across iframe boundaries.",
2507
+ language: ["typescript", "javascript"]
2508
+ },
2509
+ // ── Object ────────────────────────────────────────────────
2510
+ Object: {
2511
+ title: "Object",
2512
+ type: "interface Object",
2513
+ body: "The base class of all JavaScript objects. Provides static methods for working with object properties, prototypes, and descriptors.",
2514
+ language: ["typescript", "javascript"]
2515
+ },
2516
+ "Object.keys": {
2517
+ title: "Object.keys()",
2518
+ type: "(obj: object) => string[]",
2519
+ body: "Returns an array of an object's own enumerable string-keyed property names, in insertion order.",
2520
+ language: ["typescript", "javascript"]
2521
+ },
2522
+ "Object.values": {
2523
+ title: "Object.values()",
2524
+ type: "(obj: object) => any[]",
2525
+ body: "Returns an array of an object's own enumerable string-keyed property values, in insertion order.",
2526
+ language: ["typescript", "javascript"]
2527
+ },
2528
+ "Object.entries": {
2529
+ title: "Object.entries()",
2530
+ type: "(obj: object) => [string, any][]",
2531
+ body: "Returns an array of [key, value] pairs for all own enumerable string-keyed properties of an object.",
2532
+ language: ["typescript", "javascript"]
2533
+ },
2534
+ "Object.assign": {
2535
+ title: "Object.assign()",
2536
+ type: "<T, U>(target: T, source: U) => T & U",
2537
+ body: "Copies own enumerable properties from one or more source objects into a target object. Returns the modified target. Does a shallow copy.",
2538
+ language: ["typescript", "javascript"]
2539
+ },
2540
+ "Object.freeze": {
2541
+ title: "Object.freeze()",
2542
+ type: "<T>(obj: T) => Readonly<T>",
2543
+ body: "Freezes an object — prevents adding, removing, or changing its properties. Returns the same object. Shallow — nested objects are not frozen.",
2544
+ language: ["typescript", "javascript"]
2545
+ },
2546
+ "Object.create": {
2547
+ title: "Object.create()",
2548
+ type: "(proto: object | null, propertiesObject?: PropertyDescriptorMap) => any",
2549
+ body: "Creates a new object with the specified prototype object and optional property descriptors.",
2550
+ language: ["typescript", "javascript"]
2551
+ },
2552
+ "Object.fromEntries": {
2553
+ title: "Object.fromEntries()",
2554
+ type: "<T>(entries: Iterable<[string, T]>) => Record<string, T>",
2555
+ body: "Creates an object from an array of [key, value] pairs or any iterable of key-value entries. The inverse of Object.entries().",
2556
+ language: ["typescript", "javascript"]
2557
+ },
2558
+ // ── Promise ───────────────────────────────────────────────
2559
+ Promise: {
2560
+ title: "Promise",
2561
+ type: "interface Promise<T>",
2562
+ body: "Represents an asynchronous operation that will eventually complete (or fail) and produce a value. Use .then(), .catch(), and .finally() to handle outcomes.",
2563
+ language: ["typescript", "javascript"]
2564
+ },
2565
+ "Promise.all": {
2566
+ title: "Promise.all()",
2567
+ type: "<T>(promises: Iterable<Promise<T>>) => Promise<T[]>",
2568
+ body: "Waits for all promises to resolve and returns an array of results. If any promise rejects, the entire result rejects immediately (fail-fast).",
2569
+ language: ["typescript", "javascript"]
2570
+ },
2571
+ "Promise.allSettled": {
2572
+ title: "Promise.allSettled()",
2573
+ type: "<T>(promises: Iterable<Promise<T>>) => Promise<PromiseSettledResult<T>[]>",
2574
+ body: 'Waits for all promises to settle (resolve or reject) and returns an array of result objects, each with a status of "fulfilled" or "rejected". Never rejects.',
2575
+ language: ["typescript", "javascript"]
2576
+ },
2577
+ "Promise.race": {
2578
+ title: "Promise.race()",
2579
+ type: "<T>(promises: Iterable<Promise<T>>) => Promise<T>",
2580
+ body: "Returns a promise that resolves or rejects as soon as one of the given promises resolves or rejects, with that value or reason.",
2581
+ language: ["typescript", "javascript"]
2582
+ },
2583
+ "Promise.resolve": {
2584
+ title: "Promise.resolve()",
2585
+ type: "<T>(value: T | PromiseLike<T>) => Promise<T>",
2586
+ body: "Returns a Promise object that is resolved with the given value. If the value is a thenable, the returned promise follows it.",
2587
+ language: ["typescript", "javascript"]
2588
+ },
2589
+ "Promise.reject": {
2590
+ title: "Promise.reject()",
2591
+ type: "(reason?: any) => Promise<never>",
2592
+ body: "Returns a Promise that is rejected with the given reason. Useful for creating pre-rejected promises in control flow.",
2593
+ language: ["typescript", "javascript"]
2594
+ },
2595
+ // ── Timers ────────────────────────────────────────────────
2596
+ setTimeout: {
2597
+ title: "setTimeout()",
2598
+ type: "(callback: () => void, delay?: number, ...args: any[]) => number",
2599
+ body: "Executes a function after a specified delay in milliseconds. Returns a timer ID that can be passed to clearTimeout() to cancel.",
2600
+ language: ["typescript", "javascript"]
2601
+ },
2602
+ clearTimeout: {
2603
+ title: "clearTimeout()",
2604
+ type: "(id: number) => void",
2605
+ body: "Cancels a timeout previously established by setTimeout(), preventing its callback from running.",
2606
+ language: ["typescript", "javascript"]
2607
+ },
2608
+ setInterval: {
2609
+ title: "setInterval()",
2610
+ type: "(callback: () => void, delay?: number, ...args: any[]) => number",
2611
+ body: "Repeatedly executes a function with a fixed time delay between each call. Returns a timer ID for cancellation via clearInterval().",
2612
+ language: ["typescript", "javascript"]
2613
+ },
2614
+ clearInterval: {
2615
+ title: "clearInterval()",
2616
+ type: "(id: number) => void",
2617
+ body: "Cancels a repeating timer established by setInterval().",
2618
+ language: ["typescript", "javascript"]
2619
+ },
2620
+ requestAnimationFrame: {
2621
+ title: "requestAnimationFrame()",
2622
+ type: "(callback: (timestamp: DOMHighResTimeStamp) => void) => number",
2623
+ body: "Schedules a callback to run before the next browser repaint. Ideal for animations — the browser can batch and throttle calls to 60fps or the display refresh rate.",
2624
+ language: ["typescript", "javascript"]
2625
+ },
2626
+ cancelAnimationFrame: {
2627
+ title: "cancelAnimationFrame()",
2628
+ type: "(id: number) => void",
2629
+ body: "Cancels an animation frame request previously scheduled with requestAnimationFrame().",
2630
+ language: ["typescript", "javascript"]
2631
+ },
2632
+ queueMicrotask: {
2633
+ title: "queueMicrotask()",
2634
+ type: "(callback: () => void) => void",
2635
+ body: "Queues a microtask to be executed before the next task in the event loop. Runs after the current JavaScript execution but before any setTimeout callbacks.",
2636
+ language: ["typescript", "javascript"]
2637
+ },
2638
+ // ── Network ───────────────────────────────────────────────
2639
+ fetch: {
2640
+ title: "fetch()",
2641
+ type: "(input: RequestInfo | URL, init?: RequestInit) => Promise<Response>",
2642
+ body: "Fetches a resource from the network. Returns a Promise that resolves to a Response. Use .json(), .text(), or .blob() on the response to read the body.",
2643
+ language: ["typescript", "javascript"]
2644
+ },
2645
+ // ── Global utils ──────────────────────────────────────────
2646
+ parseInt: {
2647
+ title: "parseInt()",
2648
+ type: "(string: string, radix?: number) => number",
2649
+ body: "Parses a string and returns an integer in the specified radix (base). Always provide the radix (typically 10) to avoid unexpected behavior with leading zeros.",
2650
+ language: ["typescript", "javascript"]
2651
+ },
2652
+ parseFloat: {
2653
+ title: "parseFloat()",
2654
+ type: "(string: string) => number",
2655
+ body: "Parses a string and returns a floating-point number. Returns NaN if the string cannot be converted.",
2656
+ language: ["typescript", "javascript"]
2657
+ },
2658
+ isNaN: {
2659
+ title: "isNaN()",
2660
+ type: "(value: number) => boolean",
2661
+ body: "Returns true if the value is NaN (Not a Number). Note: coerces the argument to number first — use Number.isNaN() for strict checking without coercion.",
2662
+ language: ["typescript", "javascript"]
2663
+ },
2664
+ isFinite: {
2665
+ title: "isFinite()",
2666
+ type: "(value: number) => boolean",
2667
+ body: "Returns true if the value is a finite number. Returns false for ±Infinity and NaN. Coerces the argument to number first.",
2668
+ language: ["typescript", "javascript"]
2669
+ },
2670
+ encodeURIComponent: {
2671
+ title: "encodeURIComponent()",
2672
+ type: "(uriComponent: string | number | boolean) => string",
2673
+ body: "Encodes a URI component by replacing special characters with their UTF-8 escape sequences. Use for encoding query string values before appending to a URL.",
2674
+ language: ["typescript", "javascript"]
2675
+ },
2676
+ decodeURIComponent: {
2677
+ title: "decodeURIComponent()",
2678
+ type: "(encodedURIComponent: string) => string",
2679
+ body: "Decodes a URI component that was previously encoded with encodeURIComponent(). Throws URIError on malformed sequences.",
2680
+ language: ["typescript", "javascript"]
2681
+ },
2682
+ structuredClone: {
2683
+ title: "structuredClone()",
2684
+ type: "<T>(value: T, options?: StructuredSerializeOptions) => T",
2685
+ body: "Creates a deep clone of the given value using the structured clone algorithm. Handles cycles, Maps, Sets, Dates, and typed arrays. Does not clone functions or class instances.",
2686
+ language: ["typescript", "javascript"]
2687
+ },
2688
+ // ── DOM ───────────────────────────────────────────────────
2689
+ "document.getElementById": {
2690
+ title: "document.getElementById()",
2691
+ type: "(elementId: string) => HTMLElement | null",
2692
+ body: "Returns the first element in the document with the specified ID, or null if not found. IDs must be unique per document.",
2693
+ language: ["typescript", "javascript"]
2694
+ },
2695
+ "document.querySelector": {
2696
+ title: "document.querySelector()",
2697
+ type: "(selectors: string) => Element | null",
2698
+ body: "Returns the first Element matching the given CSS selector string, or null if no match. Use querySelectorAll() for all matches.",
2699
+ language: ["typescript", "javascript"]
2700
+ },
2701
+ "document.querySelectorAll": {
2702
+ title: "document.querySelectorAll()",
2703
+ type: "(selectors: string) => NodeListOf<Element>",
2704
+ body: "Returns a static NodeList of all Elements matching the given CSS selector string. Does not update as the document changes.",
2705
+ language: ["typescript", "javascript"]
2706
+ },
2707
+ "document.createElement": {
2708
+ title: "document.createElement()",
2709
+ type: "<K extends keyof HTMLElementTagNameMap>(tagName: K) => HTMLElementTagNameMap[K]",
2710
+ body: "Creates a new HTML element with the specified tag name. The element is not attached to the DOM until you call appendChild() or similar.",
2711
+ language: ["typescript", "javascript"]
2712
+ },
2713
+ addEventListener: {
2714
+ title: "addEventListener()",
2715
+ type: "(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions) => void",
2716
+ body: "Registers an event listener on the target element. The listener is called whenever the specified event fires. Remember to call removeEventListener() to clean up.",
2717
+ language: ["typescript", "javascript"]
2718
+ },
2719
+ removeEventListener: {
2720
+ title: "removeEventListener()",
2721
+ type: "(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions) => void",
2722
+ body: "Removes an event listener previously added with addEventListener(). The listener reference must be the same function object.",
2723
+ language: ["typescript", "javascript"]
2724
+ },
2725
+ // ── TypeScript keywords ────────────────────────────────────
2726
+ const: {
2727
+ title: "const",
2728
+ type: "keyword",
2729
+ body: "Declares a block-scoped variable that cannot be reassigned. The binding is immutable — but for objects and arrays, their contents can still be mutated.",
2730
+ language: ["typescript", "javascript"]
2731
+ },
2732
+ let: {
2733
+ title: "let",
2734
+ type: "keyword",
2735
+ body: "Declares a block-scoped variable that can be reassigned. Prefer const for bindings that never change.",
2736
+ language: ["typescript", "javascript"]
2737
+ },
2738
+ var: {
2739
+ title: "var",
2740
+ type: "keyword",
2741
+ body: "Declares a function-scoped (or globally-scoped) variable. Hoisted to the top of its scope. Prefer const or let in modern code.",
2742
+ language: ["typescript", "javascript"]
2743
+ },
2744
+ function: {
2745
+ title: "function",
2746
+ type: "keyword",
2747
+ body: "Defines a named function declaration, or introduces a function expression. Function declarations are hoisted; expressions are not.",
2748
+ language: ["typescript", "javascript"]
2749
+ },
2750
+ class: {
2751
+ title: "class",
2752
+ type: "keyword",
2753
+ body: "Declares a class — a blueprint for creating objects with shared methods and properties. Classes support extends, implements, constructors, getters, setters, and static members.",
2754
+ language: ["typescript", "javascript"]
2755
+ },
2756
+ async: {
2757
+ title: "async",
2758
+ type: "keyword",
2759
+ body: "Marks a function as asynchronous, making it return a Promise implicitly. Enables the use of the await keyword inside the function body.",
2760
+ language: ["typescript", "javascript"]
2761
+ },
2762
+ await: {
2763
+ title: "await",
2764
+ type: "keyword",
2765
+ body: "Pauses execution of an async function until the Promise settles, then returns the resolved value. Must be used inside an async function.",
2766
+ language: ["typescript", "javascript"]
2767
+ },
2768
+ return: {
2769
+ title: "return",
2770
+ type: "keyword",
2771
+ body: "Exits the current function and optionally returns a value to the caller. In an async function, the value is wrapped in a resolved Promise.",
2772
+ language: ["typescript", "javascript"]
2773
+ },
2774
+ interface: {
2775
+ title: "interface",
2776
+ type: "keyword",
2777
+ body: "Defines a TypeScript interface — a named contract describing the shape of an object. Interfaces can be extended, merged (declaration merging), and implemented by classes.",
2778
+ language: ["typescript"]
2779
+ },
2780
+ type: {
2781
+ title: "type",
2782
+ type: "keyword",
2783
+ body: "Declares a TypeScript type alias — a name for any type expression including unions, intersections, tuples, mapped types, and conditional types.",
2784
+ language: ["typescript"]
2785
+ },
2786
+ extends: {
2787
+ title: "extends",
2788
+ type: "keyword",
2789
+ body: "Establishes inheritance (class extends Base) or constrains a generic type parameter (T extends object). Also used in conditional types (T extends U ? X : Y).",
2790
+ language: ["typescript", "javascript"]
2791
+ },
2792
+ implements: {
2793
+ title: "implements",
2794
+ type: "keyword",
2795
+ body: "Declares that a class satisfies the shape of one or more interfaces. TypeScript verifies at compile time that all required members are present.",
2796
+ language: ["typescript"]
2797
+ },
2798
+ export: {
2799
+ title: "export",
2800
+ type: "keyword",
2801
+ body: "Makes a declaration (variable, function, class, type, interface) available for import in other modules. Use export default for a single primary export.",
2802
+ language: ["typescript", "javascript"]
2803
+ },
2804
+ import: {
2805
+ title: "import",
2806
+ type: "keyword",
2807
+ body: "Imports bindings from another module. Supports named imports ({ foo, bar }), default imports (Foo), namespace imports (* as Foo), and side-effect imports.",
2808
+ language: ["typescript", "javascript"]
2809
+ },
2810
+ typeof: {
2811
+ title: "typeof",
2812
+ type: "keyword",
2813
+ body: 'Returns a string describing the type of its operand at runtime ("string", "number", "boolean", "object", "function", "undefined", "symbol", "bigint"). In TypeScript, also used as a type operator to capture the type of a value.',
2814
+ language: ["typescript", "javascript"]
2815
+ },
2816
+ instanceof: {
2817
+ title: "instanceof",
2818
+ type: "keyword",
2819
+ body: "Tests whether an object has a given constructor in its prototype chain. Returns true if the object is an instance of the constructor.",
2820
+ language: ["typescript", "javascript"]
2821
+ },
2822
+ new: {
2823
+ title: "new",
2824
+ type: "keyword",
2825
+ body: "Creates a new instance of a class or constructor function. Allocates memory, sets the prototype, calls the constructor with `this` bound to the new object, and returns it.",
2826
+ language: ["typescript", "javascript"]
2827
+ },
2828
+ throw: {
2829
+ title: "throw",
2830
+ type: "keyword",
2831
+ body: "Throws a user-defined exception, stopping execution of the current function and propagating up the call stack until caught by a try...catch block.",
2832
+ language: ["typescript", "javascript"]
2833
+ },
2834
+ try: {
2835
+ title: "try...catch...finally",
2836
+ type: "keyword",
2837
+ body: "Wraps code that might throw an exception. The catch block handles errors; the finally block always runs whether or not an error occurred.",
2838
+ language: ["typescript", "javascript"]
2839
+ },
2840
+ // ── TypeScript built-in types ──────────────────────────────
2841
+ string: {
2842
+ title: "string",
2843
+ type: "primitive type",
2844
+ body: 'Represents a sequence of UTF-16 code units. In TypeScript, the string type accepts any text value. Literal types like "hello" narrow to specific string values.',
2845
+ language: ["typescript"]
2846
+ },
2847
+ number: {
2848
+ title: "number",
2849
+ type: "primitive type",
2850
+ body: "Represents a double-precision 64-bit IEEE 754 floating-point value. Includes integers, decimals, NaN, and Infinity. TypeScript does not have a separate int type.",
2851
+ language: ["typescript"]
2852
+ },
2853
+ boolean: {
2854
+ title: "boolean",
2855
+ type: "primitive type",
2856
+ body: "Represents a logical true or false value. Literal types true and false narrow to specific boolean values.",
2857
+ language: ["typescript"]
2858
+ },
2859
+ any: {
2860
+ title: "any",
2861
+ type: "TypeScript type",
2862
+ body: "Disables type checking for a value — allows any operation without compile errors. Avoid using any; prefer unknown when the type is genuinely uncertain.",
2863
+ language: ["typescript"]
2864
+ },
2865
+ unknown: {
2866
+ title: "unknown",
2867
+ type: "TypeScript type",
2868
+ body: "The type-safe alternative to any. You cannot perform operations on an unknown value without first narrowing its type with typeof, instanceof, or a type guard.",
2869
+ language: ["typescript"]
2870
+ },
2871
+ void: {
2872
+ title: "void",
2873
+ type: "TypeScript type",
2874
+ body: "Represents the absence of a value, typically used as the return type of functions that do not return anything meaningful.",
2875
+ language: ["typescript"]
2876
+ },
2877
+ never: {
2878
+ title: "never",
2879
+ type: "TypeScript type",
2880
+ body: "A type with no values — used for functions that never return (throw or infinite loop) and for exhaustive checks in union type switches.",
2881
+ language: ["typescript"]
2882
+ },
2883
+ Record: {
2884
+ title: "Record<K, V>",
2885
+ type: "type Record<K extends keyof any, T> = { [P in K]: T }",
2886
+ body: "A utility type that constructs an object type whose keys are of type K and values are of type V. Useful for dictionaries and lookup tables.",
2887
+ language: ["typescript"]
2888
+ },
2889
+ Partial: {
2890
+ title: "Partial<T>",
2891
+ type: "type Partial<T> = { [P in keyof T]?: T[P] }",
2892
+ body: "A utility type that makes all properties of T optional. Useful for update payloads, patches, and configuration objects with defaults.",
2893
+ language: ["typescript"]
2894
+ },
2895
+ Required: {
2896
+ title: "Required<T>",
2897
+ type: "type Required<T> = { [P in keyof T]-?: T[P] }",
2898
+ body: "A utility type that makes all properties of T required (removes optionality). The inverse of Partial<T>.",
2899
+ language: ["typescript"]
2900
+ },
2901
+ Readonly: {
2902
+ title: "Readonly<T>",
2903
+ type: "type Readonly<T> = { readonly [P in keyof T]: T[P] }",
2904
+ body: "A utility type that makes all properties of T readonly. Prevents property reassignment at the type level.",
2905
+ language: ["typescript"]
2906
+ },
2907
+ ReturnType: {
2908
+ title: "ReturnType<T>",
2909
+ type: "type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any",
2910
+ body: "A utility type that extracts the return type of a function type T.",
2911
+ language: ["typescript"]
2912
+ },
2913
+ Omit: {
2914
+ title: "Omit<T, K>",
2915
+ type: "type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>",
2916
+ body: "A utility type that constructs a type by picking all properties from T then removing those in K.",
2917
+ language: ["typescript"]
2918
+ },
2919
+ Pick: {
2920
+ title: "Pick<T, K>",
2921
+ type: "type Pick<T, K extends keyof T> = { [P in K]: T[P] }",
2922
+ body: "A utility type that constructs a type by picking the set of properties K from T.",
2923
+ language: ["typescript"]
2924
+ },
2925
+ NonNullable: {
2926
+ title: "NonNullable<T>",
2927
+ type: "type NonNullable<T> = T extends null | undefined ? never : T",
2928
+ body: "A utility type that removes null and undefined from the type T.",
2929
+ language: ["typescript"]
2930
+ },
2931
+ keyof: {
2932
+ title: "keyof",
2933
+ type: "TypeScript type operator",
2934
+ body: 'Produces a union type of all property keys of an object type. keyof { a: string; b: number } is "a" | "b".',
2935
+ language: ["typescript"]
2936
+ }
2937
+ };
2938
+ function Ht(s, e) {
2939
+ const t = Dt[s];
2940
+ return !t || t.language && !(Array.isArray(t.language) ? t.language : [t.language]).includes(e) ? null : t;
2941
+ }
2942
+ function Rt(s) {
2943
+ var q, K, M, B;
2944
+ const { vr: e, visIdx: t, curVisRow: i, wm: n, foldedLines: r, isFoldable: o, opts: l } = s, { docLine: a, segIdx: c, text: d } = e, h = t === i, p = a === ((q = n.visualRows[i]) == null ? void 0 : q.docLine), f = c > 0, _ = ((K = n.segments[a]) == null ? void 0 : K.slice(0, c).reduce((k, x) => k + x.length, 0)) ?? 0, b = s.docSel ? fe(s.docSel, a, ((M = (n.segments[a] ?? [""])[c]) == null ? void 0 : M.length) ?? 0) : null;
2945
+ let v = null;
2946
+ if (b) {
2947
+ const k = ((B = (n.segments[a] ?? [""])[c]) == null ? void 0 : B.length) ?? 0, x = fe(s.docSel, a, k + _);
2948
+ if (x) {
2949
+ const E = x.start - _, H = x.end - _;
2950
+ H > 0 && E < d.length && (v = { start: Math.max(0, E), end: Math.min(d.length, H) });
2951
+ }
2952
+ }
2953
+ const u = s.findMatches.filter((k) => k.row === a).map((k) => {
2954
+ var W, j;
2955
+ const x = k.col - _, E = k.col + k.len - _;
2956
+ if (E <= 0 || x >= d.length) return null;
2957
+ const H = s.findIdx >= 0 && ((W = s.findMatches[s.findIdx]) == null ? void 0 : W.row) === k.row && ((j = s.findMatches[s.findIdx]) == null ? void 0 : j.col) === k.col;
2958
+ return { start: Math.max(0, x), end: Math.min(d.length, E), isCur: H };
2959
+ }).filter(Boolean), T = s.wordHighlights.filter((k) => k.row === a).map((k) => {
2960
+ const x = k.col - _, E = k.col + k.len - _;
2961
+ return E <= 0 || x >= d.length ? null : { start: Math.max(0, x), end: Math.min(d.length, E) };
2962
+ }).filter(Boolean), m = [];
2963
+ if (s.bracketMatch) {
2964
+ for (const k of [s.bracketMatch.open, s.bracketMatch.close])
2965
+ if (k.row === a) {
2966
+ const x = k.col - _;
2967
+ x >= 0 && x < d.length && m.push({ start: x, end: x + 1 });
2968
+ }
2969
+ }
2970
+ const w = [], y = [];
2971
+ for (const k of s.extraCursors) {
2972
+ const x = F(n, k.row, k.col);
2973
+ if (x.visRow === t && w.push(x.colInSeg), k.sel) {
2974
+ const E = jt(k.sel);
2975
+ if (a >= E.ar && a <= E.fr) {
2976
+ const H = a === E.ar ? E.ac - _ : -_, W = a === E.fr ? E.fc - _ : d.length + 999;
2977
+ W > 0 && H < d.length && y.push({ start: Math.max(0, H), end: Math.min(d.length, W) });
2978
+ }
2979
+ }
2980
+ }
2981
+ const D = Bt(d, l.renderWhitespace), R = h || v || u.length || w.length || T.length || m.length || y.length || s.snippetStopCols.length > 0;
2982
+ let C;
2983
+ if (R)
2984
+ C = $t(
2985
+ D,
2986
+ h ? s.curColInSeg : -1,
2987
+ v,
2988
+ u,
2989
+ w,
2990
+ s.snippetStopCols,
2991
+ T,
2992
+ m,
2993
+ y,
2994
+ l.tokeniserOpts
2995
+ );
2996
+ else {
2997
+ const k = `${a}:${c}:${l.renderWhitespace}`;
2998
+ let x = s.tokenCache.get(k, D);
2999
+ x || (x = ae(D, l.tokeniserOpts), s.tokenCache.set(k, D, x)), C = Pt(D, x) || "&#8203;";
3000
+ }
3001
+ let U = "";
3002
+ if (c === 0 && l.showIndentGuides) {
3003
+ const k = (d.match(/^(\s*)/) ?? ["", ""])[1].length, x = Math.floor(k / l.tabSize);
3004
+ for (let E = 1; E < x; E++) {
3005
+ const H = l.codePaddingLeft + E * l.tabSize * l.charWidth;
3006
+ U += `<span class="sl-ig" style="left:${H}px"></span>`;
3007
+ }
3008
+ }
3009
+ let P = "";
3010
+ if (c === 0 && o) {
3011
+ const k = r.has(a);
3012
+ P = `<span class="sl-fold-btn" data-row="${a}">${k ? "▸" : "▾"}</span>`;
3013
+ }
3014
+ const N = r.has(a) && c === 0, O = c === 0 ? String(a + 1) : "";
3015
+ return `<div class="${[
3016
+ "sl-er",
3017
+ l.highlightActiveLine && p ? "sl-cur-row" : "",
3018
+ f ? "sl-wrap-cont" : "",
3019
+ N ? "sl-folded" : ""
3020
+ ].filter(Boolean).join(" ")}" style="height:${l.lineHeight}px" data-v="${t}" data-doc="${a}"><div class="sl-eg" style="position:relative">${P}<span class="sl-egn">${O}</span></div><div class="sl-el"><span class="sl-cl">${U}${C}</span></div></div>`;
3021
+ }
3022
+ function Bt(s, e) {
3023
+ if (e === "none") return s;
3024
+ if (e === "all")
3025
+ return s.replace(/ /g, "·").replace(/\t/g, "→");
3026
+ const t = (s.match(/^ +/) ?? [""])[0].length, i = (s.match(/ +$/) ?? [""])[0].length;
3027
+ let n = s;
3028
+ return t && (n = "·".repeat(t) + n.slice(t)), i && (n = n.slice(0, n.length - i) + "·".repeat(i)), n.replace(/\t/g, "→");
3029
+ }
3030
+ function jt(s) {
3031
+ return s.ar < s.fr || s.ar === s.fr && s.ac <= s.fc ? s : { ar: s.fr, ac: s.fc, fr: s.ar, fc: s.ac };
3032
+ }
3033
+ function Pt(s, e) {
3034
+ if (!s) return "";
3035
+ const t = Le(s, e);
3036
+ let i = "", n = 0, r = t[0];
3037
+ const o = (l) => {
3038
+ if (l <= n) return;
3039
+ const a = V(s.slice(n, l));
3040
+ i += r ? `<span class="${r}">${a}</span>` : a;
3041
+ };
3042
+ for (let l = 1; l <= s.length; l++) {
3043
+ const a = l < s.length ? t[l] : null;
3044
+ a !== r && (o(l), n = l, r = a ?? "");
3045
+ }
3046
+ return i;
3047
+ }
3048
+ function $t(s, e, t, i, n, r, o, l, a, c) {
3049
+ if (s.length === 0) {
3050
+ let u = e >= 0 ? '<span class="sl-cur"></span>' : "";
3051
+ for (const T of n) u += '<span class="sl-cur-extra"></span>';
3052
+ for (const T of r) u += '<span class="sl-snip-stop"></span>';
3053
+ return u || "&#8203;";
3054
+ }
3055
+ const d = ae(s, c), h = Le(s, d);
3056
+ let p = "", f = 0, _ = "", b = "";
3057
+ const v = (u) => {
3058
+ if (u <= f) return;
3059
+ const T = V(s.slice(f, u)), m = [_, b].filter(Boolean).join(" ");
3060
+ p += m ? `<span class="${m}">${T}</span>` : T;
3061
+ };
3062
+ for (let u = 0; u <= s.length; u++) {
3063
+ e === u && (v(u), f = u, p += '<span class="sl-cur"></span>');
3064
+ for (const C of n)
3065
+ C === u && (v(u), f = u, p += '<span class="sl-cur-extra"></span>');
3066
+ for (const C of r)
3067
+ C === u && (v(u), f = u, p += '<span class="sl-snip-stop"></span>');
3068
+ if (u === s.length) {
3069
+ v(u);
3070
+ break;
3071
+ }
3072
+ const T = h[u], m = i.find((C) => u >= C.start && u < C.end), w = t && u >= t.start && u < t.end || a.some((C) => u >= C.start && u < C.end), y = !w && !m && o.some((C) => u >= C.start && u < C.end), D = !w && !m && l.some((C) => u >= C.start && u < C.end);
3073
+ let R = "";
3074
+ w ? R = "sl-sh" : m ? R = "sl-fh" + (m.isCur ? " sl-fh-cur" : "") : D ? R = "sl-bm" : y && (R = "sl-wh"), (R !== _ || T !== b) && (v(u), f = u, _ = R, b = T);
3075
+ }
3076
+ return p || "&#8203;";
3077
+ }
3078
+ function ie(s, e, t, i, n) {
3079
+ const r = Math.max(0, s * n - t), o = Math.max(0, s * 2 - i), a = (r > 0 ? e / r : 0) * o, c = Math.max(20, t / n * 2), d = e / n * 2 - a;
3080
+ return { mmScroll: a, sliderTop: d, sliderHeight: c };
3081
+ }
3082
+ function Wt(s, e, t, i, n) {
3083
+ const r = Math.max(0, e * n - t), o = Math.max(0, e * 2 - i);
3084
+ if (r <= 0) return 0;
3085
+ const l = 2 / n - o / r;
3086
+ if (Math.abs(l) < 1e-9) {
3087
+ const a = Math.max(20, t / n * 2);
3088
+ return Math.max(0, Math.min(r, s / Math.max(1, i - a) * r));
3089
+ }
3090
+ return Math.max(0, Math.min(r, s / l));
3091
+ }
3092
+ function Nt(s, e, t, i, n, r) {
3093
+ const o = Math.max(0, e * r - i), l = Math.max(0, e * 2 - n);
3094
+ if (o <= 0) return 0;
3095
+ const a = t / o * l, c = (s + a) / 2;
3096
+ return Math.max(0, Math.min(o, c * r - i / 2));
3097
+ }
3098
+ function Se(s) {
3099
+ const e = (t) => {
3100
+ const i = s(t);
3101
+ return i.startsWith("#") && i.length === 7 ? be(i, 0.85) : i;
3102
+ };
3103
+ return {
3104
+ kw: e("--tok-kw"),
3105
+ fn: e("--tok-fn"),
3106
+ cls: e("--tok-cls"),
3107
+ typ: e("--tok-typ"),
3108
+ str: e("--tok-str"),
3109
+ num: e("--tok-num"),
3110
+ cmt: e("--tok-cmt"),
3111
+ dec: e("--tok-dec"),
3112
+ op: e("--tok-op"),
3113
+ txt: (() => {
3114
+ const t = s("--text2");
3115
+ return t.startsWith("#") && t.length === 7 ? be(t, 0.28) : "rgba(150,148,140,0.28)";
3116
+ })()
3117
+ };
3118
+ }
3119
+ function Ot(s) {
3120
+ var q, K;
3121
+ const {
3122
+ canvas: e,
3123
+ doc: t,
3124
+ firstLine: i,
3125
+ lastLine: n,
3126
+ subPx: r,
3127
+ wrapperWidth: o,
3128
+ canvasHeight: l,
3129
+ cursorRow: a,
3130
+ sel: c,
3131
+ findMatches: d,
3132
+ findIdx: h,
3133
+ sliderTop: p,
3134
+ sliderHeight: f,
3135
+ colors: _,
3136
+ getCssVar: b,
3137
+ dpr: v
3138
+ } = s, u = e.getContext("2d");
3139
+ if (!u) return;
3140
+ u.setTransform(v, 0, 0, v, 0, 0);
3141
+ const T = b("--mm-bg") || "#0d0d0f", m = b("--mm-dim") || "rgba(0,0,0,.30)", w = b("--mm-edge") || "rgba(255,255,255,.18)", y = b("--mm-slider") || "rgba(255,255,255,.07)", D = b("--sel-bg") || "rgba(110,159,255,.22)", R = b("--cur-line-bg") || "rgba(255,255,255,.05)", C = b("--find-border") || "rgba(234,180,86,.50)", U = b("--find-cur-bg") || "rgba(234,180,86,.80)", P = (M) => (M - i) * 2;
3142
+ if (u.fillStyle = T, u.fillRect(0, 0, o, l), a >= i && a < n && (u.fillStyle = R, u.fillRect(0, P(a), o, 2)), c) {
3143
+ const M = Math.max(i, c.ar), B = Math.min(n - 1, c.fr);
3144
+ B >= M && (u.fillStyle = D, u.fillRect(0, P(M), o, (B - M + 1) * 2));
3145
+ }
3146
+ for (const M of d) {
3147
+ if (M.row < i || M.row >= n) continue;
3148
+ const B = h >= 0 && ((q = d[h]) == null ? void 0 : q.row) === M.row && ((K = d[h]) == null ? void 0 : K.col) === M.col;
3149
+ u.fillStyle = B ? U : C, u.fillRect(
3150
+ 3 + M.col * 1.1,
3151
+ P(M.row),
3152
+ Math.max(3, M.len * 1.1),
3153
+ 2
3154
+ );
3155
+ }
3156
+ const N = Math.floor((o - 3) / 1.1);
3157
+ for (let M = i; M < n; M++) {
3158
+ const B = t[M] ?? "";
3159
+ if (!B.trim()) continue;
3160
+ const k = P(M), x = 1.5, E = ae(B);
3161
+ let H = 0;
3162
+ for (const j of E) {
3163
+ if (j.start >= N) break;
3164
+ j.start > H && (u.fillStyle = _.txt, u.fillRect(3 + H * 1.1, k, (Math.min(j.start, N) - H) * 1.1, x));
3165
+ const Ae = _[j.cls] ?? _.txt, de = Math.min(j.end, N) - j.start;
3166
+ de > 0 && (u.fillStyle = Ae, u.fillRect(3 + j.start * 1.1, k, de * 1.1, x)), H = Math.max(H, Math.min(j.end, N));
3167
+ }
3168
+ const W = Math.min(B.length, N);
3169
+ H < W && (u.fillStyle = _.txt, u.fillRect(3 + H * 1.1, k, (W - H) * 1.1, x));
3170
+ }
3171
+ const O = p + r, z = O + f;
3172
+ u.fillStyle = m, O > 0 && u.fillRect(0, 0, o, O), z < l && u.fillRect(0, z, o, l - z), u.fillStyle = y, u.fillRect(0, O, o, f), u.fillStyle = w, u.fillRect(0, Math.max(0, O), o, 1), u.fillRect(0, Math.max(0, z - 1), o, 1);
3173
+ }
3174
+ const Ft = {
3175
+ value: "",
3176
+ language: "typescript",
3177
+ theme: "",
3178
+ showGutter: !0,
3179
+ showMinimap: !0,
3180
+ showStatusBar: !0,
3181
+ wordWrap: !1,
3182
+ wrapColumn: 80,
3183
+ fontFamily: "'JetBrains Mono', monospace",
3184
+ fontSize: 13,
3185
+ lineHeight: 22,
3186
+ tabSize: 2,
3187
+ insertSpaces: !0,
3188
+ maxUndoHistory: 300,
3189
+ showIndentGuides: !0,
3190
+ bracketMatching: !0,
3191
+ codeFolding: !0,
3192
+ emmet: !0,
3193
+ snippetExpansion: !0,
3194
+ autocomplete: !0,
3195
+ multiCursor: !0,
3196
+ find: !0,
3197
+ findReplace: !0,
3198
+ wordSelection: !0,
3199
+ wordHighlight: !0,
3200
+ highlightActiveLine: !0,
3201
+ autocompletePrefixLength: 2,
3202
+ readOnly: !1,
3203
+ extraKeywords: [],
3204
+ extraTypes: [],
3205
+ completions: [],
3206
+ replaceBuiltins: !1,
3207
+ maxCompletions: 14,
3208
+ autoClosePairs: { "(": ")", "[": "]", "{": "}", '"': '"', "'": "'", "`": "`" },
3209
+ lineCommentToken: "",
3210
+ wordSeparators: "",
3211
+ undoBatchMs: 700,
3212
+ gutterWidth: 60,
3213
+ minimapWidth: 120,
3214
+ cursorBlinkRate: 1050,
3215
+ cursorStyle: "line",
3216
+ renderWhitespace: "none",
3217
+ tokenColors: {},
3218
+ hover: !0,
3219
+ placeholder: "",
3220
+ goToLine: !1
3221
+ };
3222
+ class Ut {
3223
+ // ── Constructor ───────────────────────────────────────────
3224
+ constructor(e, t = {}) {
3225
+ // ── DOM ───────────────────────────────────────────────────
3226
+ g(this, "_host");
3227
+ g(this, "_shadow");
3228
+ g(this, "_editorEl");
3229
+ g(this, "_spacerEl");
3230
+ g(this, "_vpEl");
3231
+ g(this, "_inputEl");
3232
+ g(this, "_minimapWrap");
3233
+ g(this, "_mmCanvas");
3234
+ g(this, "_mmSlider");
3235
+ g(this, "_statusBar");
3236
+ g(this, "_findBar");
3237
+ g(this, "_findInput");
3238
+ g(this, "_replaceInput");
3239
+ g(this, "_findCount");
3240
+ g(this, "_replaceRow");
3241
+ g(this, "_acPopup");
3242
+ g(this, "_emmetTip");
3243
+ g(this, "_snippetTip");
3244
+ g(this, "_hoverTip");
3245
+ g(this, "_themeOverlay");
3246
+ g(this, "_themePanel");
3247
+ g(this, "_placeholderEl");
3248
+ g(this, "_goToLineBar");
3249
+ g(this, "_goToLineInput");
3250
+ g(this, "_goToLineHint");
3251
+ // ── State ─────────────────────────────────────────────────
3252
+ g(this, "_config");
3253
+ g(this, "_tab", ue(1, [""]));
3254
+ g(this, "_wm", { segments: [[""]], visualRows: [{ docLine: 0, segIdx: 0, text: "" }], docToVisArr: [0] });
3255
+ g(this, "_foldedLines", /* @__PURE__ */ new Map());
3256
+ g(this, "_tokenCache", new qe());
3257
+ g(this, "_themeManager");
3258
+ // Find
3259
+ g(this, "_findMatches", []);
3260
+ g(this, "_findIdx", -1);
3261
+ g(this, "_findCaseSensitive", !1);
3262
+ g(this, "_findRegex", !1);
3263
+ // Highlights
3264
+ g(this, "_wordHighlights", []);
3265
+ g(this, "_bracketMatch", null);
3266
+ // Autocomplete
3267
+ g(this, "_acItems", []);
3268
+ g(this, "_acSel", 0);
3269
+ g(this, "_acPrefix", "");
3270
+ g(this, "_acStartCol", 0);
3271
+ g(this, "_emmetAcStartCol", 0);
3272
+ // start col of the emmet abbreviation (may differ from _acStartCol)
3273
+ // Multi-cursor
3274
+ g(this, "_mc", mt());
3275
+ g(this, "_extraCursors", []);
3276
+ // Mouse drag
3277
+ g(this, "_isDragging", !1);
3278
+ g(this, "_dragAnchor", null);
3279
+ // Hover
3280
+ g(this, "_hoverTimer", null);
3281
+ g(this, "_hoverPinned", !1);
3282
+ // Minimap drag
3283
+ g(this, "_mmDragMode", "none");
3284
+ g(this, "_mmDragStartY", 0);
3285
+ g(this, "_mmDragStartScroll", 0);
3286
+ g(this, "_mmSliderOffset", 0);
3287
+ g(this, "_mmColors");
3288
+ // Undo batching
3289
+ g(this, "_lastInputTime", 0);
3290
+ // Dynamic styles
3291
+ g(this, "_dynamicStyleEl");
3292
+ // Emmet
3293
+ g(this, "_emmetExpanded", null);
3294
+ // Snippets
3295
+ g(this, "_snippetExpanded", null);
3296
+ /** Active snippet tab-stop session. Cleared on click, Escape, or structural edit. */
3297
+ g(this, "_snippetSession", null);
3298
+ // ── Lifecycle / performance ───────────────────────────────
3299
+ /** Pending debounce timer ID for autocomplete re-computation. */
3300
+ g(this, "_acDebounceTimer", null);
3301
+ /** Pending requestAnimationFrame ID for coalesced renders. */
3302
+ g(this, "_rafId", null);
3303
+ // ── Bound window listener refs ────────────────────────────
3304
+ // Stored as named references so they can be removed precisely in destroy().
3305
+ g(this, "_onWinMouseUp");
3306
+ g(this, "_onWinResize");
3307
+ g(this, "_onEditorScroll");
3308
+ g(this, "_onWinMmMouseMove");
3309
+ g(this, "_onWinMmMouseUp");
3310
+ // ── ResizeObserver — tracks container size changes ────────
3311
+ g(this, "_ro", null);
3312
+ g(this, "_onFoldBtnClick", (e) => {
3313
+ const t = e.target.closest(".sl-fold-btn");
3314
+ if (!t) return;
3315
+ e.preventDefault(), e.stopPropagation();
3316
+ const i = parseInt(t.dataset.row ?? "0", 10);
3317
+ this._foldedLines = dt(this._foldedLines, this._tab.doc, i), this._tokenCache.clear(), this._rebuildWrapMap(), this._render();
3318
+ });
3319
+ this._config = { ...Ft, ...ye(t) }, this._onWinMouseUp = () => {
3320
+ this._isDragging = !1, this._dragAnchor = null;
3321
+ }, this._onEditorScroll = Z(() => {
3322
+ this._hideHover(), this._scheduleRender(), this._updateMinimap();
3323
+ }, 16), this._onWinResize = Z(() => {
3324
+ this._config.wordWrap && this._rebuildWrapMap(), this._scheduleRender();
3325
+ }, 100), this._onWinMmMouseMove = (a) => {
3326
+ if (this._mmDragMode === "none") return;
3327
+ const c = this._minimapWrap.clientHeight;
3328
+ if (this._mmDragMode === "slider") {
3329
+ const d = a.clientY - this._minimapWrap.getBoundingClientRect().top;
3330
+ this._editorEl.scrollTop = Wt(
3331
+ d - this._mmSliderOffset,
3332
+ this._tab.doc.length,
3333
+ this._editorEl.clientHeight,
3334
+ c,
3335
+ this._config.lineHeight
3336
+ );
3337
+ } else {
3338
+ const d = a.clientY - this._mmDragStartY, h = Math.max(0, this._tab.doc.length * this._config.lineHeight - this._editorEl.clientHeight);
3339
+ this._editorEl.scrollTop = Math.max(0, Math.min(h, this._mmDragStartScroll + d / 2 * this._config.lineHeight));
3340
+ }
3341
+ this._render();
3342
+ }, this._onWinMmMouseUp = () => {
3343
+ this._mmDragMode !== "none" && (this._mmDragMode = "none", this._minimapWrap.style.cursor = "pointer");
3344
+ }, this._host = e, this._host.classList.add("sl-host"), this._shadow = this._host.attachShadow({ mode: "open" });
3345
+ const i = I("style");
3346
+ i.textContent = rt, this._shadow.appendChild(i), this._dynamicStyleEl = I("style"), this._shadow.appendChild(this._dynamicStyleEl), this._themeManager = new nt(this._host);
3347
+ const n = typeof this._config.theme == "string" ? this._config.theme : this._config.theme;
3348
+ this._themeManager.apply(n);
3349
+ const r = I("div", "sl-layout"), o = I("div", "sl-ed-pane");
3350
+ this._inputEl = I("textarea", "sl-input"), this._inputEl.setAttribute("autocomplete", "off"), this._inputEl.setAttribute("autocorrect", "off"), this._inputEl.setAttribute("autocapitalize", "off"), this._inputEl.setAttribute("spellcheck", "false"), this._inputEl.setAttribute("role", "textbox"), this._inputEl.setAttribute("aria-multiline", "true"), this._inputEl.setAttribute("aria-label", "Code editor"), this._inputEl.setAttribute("aria-readonly", String(!!this._config.readOnly)), this._inputEl.setAttribute("aria-haspopup", "listbox"), this._editorEl = I("div", "sl-editor"), this._spacerEl = I("div", "sl-spacer"), this._vpEl = I("div", "sl-vp"), this._editorEl.appendChild(this._spacerEl), this._editorEl.appendChild(this._vpEl), this._findBar = this._buildFindBar(), this._findInput = this._findBar.querySelector(".sl-find-input"), this._replaceInput = this._findBar.querySelector(".sl-find-replace-input"), this._findCount = this._findBar.querySelector(".sl-find-count"), this._replaceRow = this._findBar.querySelector(".sl-replace-row"), this._goToLineBar = this._buildGoToLineBar(), this._goToLineInput = this._goToLineBar.querySelector(".sl-gtl-input"), this._goToLineHint = this._goToLineBar.querySelector(".sl-gtl-hint"), this._placeholderEl = I("div", "sl-placeholder"), this._placeholderEl.textContent = this._config.placeholder, this._placeholderEl.style.display = "none", o.appendChild(this._inputEl), o.appendChild(this._findBar), o.appendChild(this._goToLineBar), o.appendChild(this._placeholderEl), o.appendChild(this._editorEl), this._minimapWrap = I("div", "sl-minimap"), this._minimapWrap.style.width = `${this._config.minimapWidth}px`, this._mmCanvas = I("canvas", ""), this._mmSlider = I("div", "sl-mm-slider"), this._minimapWrap.appendChild(this._mmCanvas), this._minimapWrap.appendChild(this._mmSlider), r.appendChild(o), this._config.showMinimap && r.appendChild(this._minimapWrap), this._statusBar = this._buildStatusBar(), this._acPopup = I("div", "sl-ac-popup"), this._acPopup.setAttribute("role", "listbox"), this._acPopup.setAttribute("aria-label", "Code suggestions"), this._acPopup.style.display = "none", this._emmetTip = I("div", "sl-emmet-tip"), this._emmetTip.style.display = "none", this._snippetTip = I("div", "sl-emmet-tip"), this._snippetTip.style.display = "none", this._hoverTip = I("div", "sl-hover-tip"), this._hoverTip.style.display = "none", this._hoverTip.addEventListener("mouseenter", () => {
3351
+ this._hoverPinned = !0;
3352
+ }), this._hoverTip.addEventListener("mouseleave", () => {
3353
+ this._hoverPinned = !1, this._hideHover();
3354
+ }), this._themeOverlay = I("div", "sl-theme-overlay"), this._themeOverlay.style.display = "none", this._themePanel = I("div", "sl-theme-panel"), this._themeOverlay.appendChild(this._themePanel), this._shadow.appendChild(r), this._config.showStatusBar && this._shadow.appendChild(this._statusBar), this._shadow.appendChild(this._acPopup), this._shadow.appendChild(this._emmetTip), this._shadow.appendChild(this._snippetTip), this._shadow.appendChild(this._hoverTip), this._shadow.appendChild(this._themeOverlay);
3355
+ const l = typeof this._config.value == "string" ? me(this._config.value) : this._config.value;
3356
+ this._tab = ue(1, l.length ? l : [""]), this._mmColors = Se((a) => X(a, this._host)), this._bindEditorEvents(), this._bindMinimapEvents(), this._bindFindEvents(), this._applyDynamicStyles(), typeof ResizeObserver < "u" && (this._ro = new ResizeObserver(Z(() => {
3357
+ this._config.wordWrap && (this._rebuildWrapMap(), this._scheduleRender());
3358
+ }, 60)), this._ro.observe(this._host)), this._rebuildWrapMap(), this._render();
3359
+ }
3360
+ // ── Public API ────────────────────────────────────────────
3361
+ getValue() {
3362
+ return A(this._tab.doc);
3363
+ }
3364
+ setValue(e) {
3365
+ var t, i;
3366
+ L(this._tab, this._config.maxUndoHistory), this._tab.doc = me(e), this._tab.cur = { row: 0, col: 0 }, this._tab.sel = null, this._tokenCache.clear(), this._foldedLines.clear(), this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, e);
3367
+ }
3368
+ getCursor() {
3369
+ return { ...this._tab.cur };
3370
+ }
3371
+ setCursor(e) {
3372
+ this._tab.cur = { ...e }, S(this._tab), this._scrollIntoView(), this._render();
3373
+ }
3374
+ getSelection() {
3375
+ return this._tab.sel ? { ...this._tab.sel } : null;
3376
+ }
3377
+ setSelection(e) {
3378
+ this._tab.sel = e, this._render();
3379
+ }
3380
+ insertText(e) {
3381
+ this._config.readOnly || (this._insertStr(e, !1), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render());
3382
+ }
3383
+ setTheme(e) {
3384
+ this._themeManager.apply(e), this._applyTokenOverrides(), this._mmColors = Se((t) => X(t, this._host)), this._tokenCache.clear(), this._render();
3385
+ }
3386
+ updateConfig(e) {
3387
+ const t = ye(e);
3388
+ if (t.autoClosePairs !== void 0) {
3389
+ const i = t.autoClosePairs;
3390
+ this._config.autoClosePairs = Object.keys(i).length === 0 ? {} : { ...this._config.autoClosePairs, ...i };
3391
+ const { autoClosePairs: n, ...r } = t;
3392
+ Object.assign(this._config, r);
3393
+ } else
3394
+ Object.assign(this._config, t);
3395
+ if (t.readOnly !== void 0 && this._inputEl.setAttribute("aria-readonly", String(!!t.readOnly)), e.theme !== void 0 && this.setTheme(e.theme), (e.wordWrap !== void 0 || e.wrapColumn !== void 0) && this._rebuildWrapMap(), e.showMinimap !== void 0) {
3396
+ const i = this._shadow.querySelector(".sl-layout");
3397
+ e.showMinimap ? i.contains(this._minimapWrap) || i.appendChild(this._minimapWrap) : this._minimapWrap.remove();
3398
+ }
3399
+ e.showStatusBar !== void 0 && (e.showStatusBar ? this._shadow.contains(this._statusBar) || this._shadow.appendChild(this._statusBar) : this._statusBar.remove()), (e.fontFamily !== void 0 || e.fontSize !== void 0 || e.lineHeight !== void 0 || e.cursorBlinkRate !== void 0 || e.cursorStyle !== void 0 || e.gutterWidth !== void 0 || e.minimapWidth !== void 0 || e.showGutter !== void 0 || e.tokenColors !== void 0) && this._applyDynamicStyles(), (e.language !== void 0 || e.extraKeywords !== void 0 || e.extraTypes !== void 0 || e.renderWhitespace !== void 0 || e.completions !== void 0) && this._tokenCache.clear(), e.find === !1 ? this._closeFind() : e.findReplace === !1 && (this._replaceRow.style.display = "none"), e.goToLine === !1 && this._closeGoToLine(), e.placeholder !== void 0 && (this._placeholderEl.textContent = e.placeholder), this._render();
3400
+ }
3401
+ focus() {
3402
+ this._focusInput();
3403
+ }
3404
+ getThemes() {
3405
+ return this._themeManager.allIds;
3406
+ }
3407
+ registerTheme(e) {
3408
+ this._themeManager.register(e);
3409
+ }
3410
+ undo() {
3411
+ var e, t;
3412
+ Oe(this._tab) && (this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (t = (e = this._config).onChange) == null || t.call(e, A(this._tab.doc)));
3413
+ }
3414
+ redo() {
3415
+ var e, t;
3416
+ Fe(this._tab) && (this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (t = (e = this._config).onChange) == null || t.call(e, A(this._tab.doc)));
3417
+ }
3418
+ executeCommand(e) {
3419
+ const t = this._config.readOnly;
3420
+ switch (e) {
3421
+ case "undo":
3422
+ t || this.undo();
3423
+ break;
3424
+ case "redo":
3425
+ t || this.redo();
3426
+ break;
3427
+ case "selectAll":
3428
+ this._selectAll();
3429
+ break;
3430
+ case "copy":
3431
+ this._doCopy();
3432
+ break;
3433
+ case "cut":
3434
+ t || this._doCut();
3435
+ break;
3436
+ case "toggleComment":
3437
+ t || this._toggleComment();
3438
+ break;
3439
+ case "duplicateLine":
3440
+ t || this._duplicateLine();
3441
+ break;
3442
+ case "deleteLine":
3443
+ t || this._deleteLine();
3444
+ break;
3445
+ case "toggleWordWrap":
3446
+ this._toggleWrap();
3447
+ break;
3448
+ case "find":
3449
+ this._config.find && this._openFind(!1);
3450
+ break;
3451
+ case "findReplace":
3452
+ this._config.find && this._config.findReplace && this._openFind(!0);
3453
+ break;
3454
+ case "indentLine":
3455
+ t || this._indentSel();
3456
+ break;
3457
+ case "outdentLine":
3458
+ t || this._unindentSel();
3459
+ break;
3460
+ default:
3461
+ console.warn(`[syncline-editor] executeCommand: unknown command "${e}"`);
3462
+ break;
3463
+ }
3464
+ }
3465
+ destroy() {
3466
+ var t;
3467
+ this._acDebounceTimer !== null && (clearTimeout(this._acDebounceTimer), this._acDebounceTimer = null), this._hoverTimer !== null && (clearTimeout(this._hoverTimer), this._hoverTimer = null), this._rafId !== null && (cancelAnimationFrame(this._rafId), this._rafId = null), window.removeEventListener("mouseup", this._onWinMouseUp), window.removeEventListener("resize", this._onWinResize), window.removeEventListener("mousemove", this._onWinMmMouseMove), window.removeEventListener("mouseup", this._onWinMmMouseUp), (t = this._ro) == null || t.disconnect();
3468
+ const e = this._mmCanvas.getContext("2d");
3469
+ e && e.clearRect(0, 0, this._mmCanvas.width, this._mmCanvas.height), this._shadow.innerHTML = "", this._host.classList.remove("sl-host");
3470
+ }
3471
+ // ── DOM builders ──────────────────────────────────────────
3472
+ _buildFindBar() {
3473
+ const e = I("div", "sl-find-bar");
3474
+ return e.innerHTML = `
3475
+ <div class="sl-find-row">
3476
+ <input class="sl-find-input" placeholder="Find…" autocomplete="off" spellcheck="false">
3477
+ <span class="sl-find-count">–</span>
3478
+ <button class="sl-find-btn sl-find-prev" title="Previous">↑</button>
3479
+ <button class="sl-find-btn sl-find-next" title="Next">↓</button>
3480
+ <button class="sl-find-btn sl-find-case" title="Match case">Aa</button>
3481
+ <button class="sl-find-btn sl-find-regex" title="Regex">.*</button>
3482
+ <span class="sl-find-x sl-find-close">✕</span>
3483
+ </div>
3484
+ <div class="sl-find-row sl-replace-row" style="display:none">
3485
+ <input class="sl-find-replace-input" placeholder="Replace…" autocomplete="off" spellcheck="false">
3486
+ <button class="sl-find-btn sl-replace-one">Replace</button>
3487
+ <button class="sl-find-btn sl-replace-all">All</button>
3488
+ </div>
3489
+ `, e;
3490
+ }
3491
+ _buildGoToLineBar() {
3492
+ const e = I("div", "sl-gtl-bar");
3493
+ e.innerHTML = `
3494
+ <span class="sl-gtl-label">Go to line</span>
3495
+ <input class="sl-gtl-input" type="text" inputmode="numeric" autocomplete="off" spellcheck="false" placeholder="…">
3496
+ <span class="sl-gtl-hint"></span>
3497
+ <span class="sl-find-x sl-gtl-close" title="Close">✕</span>
3498
+ `;
3499
+ const t = e.querySelector(".sl-gtl-input"), i = e.querySelector(".sl-gtl-hint");
3500
+ return t.addEventListener("input", () => {
3501
+ const n = parseInt(t.value, 10), r = !isNaN(n) && n >= 1 && n <= this._tab.doc.length;
3502
+ t.classList.toggle("sl-gtl-err", t.value !== "" && !r), i.textContent = `(1–${this._tab.doc.length})`;
3503
+ }), t.addEventListener("keydown", (n) => {
3504
+ var r, o;
3505
+ if (n.key === "Enter") {
3506
+ n.preventDefault();
3507
+ const l = parseInt(t.value, 10);
3508
+ !isNaN(l) && l >= 1 && l <= this._tab.doc.length && (this._tab.cur.row = l - 1, this._tab.cur.col = Math.min(this._tab.cur.col, (this._tab.doc[l - 1] ?? "").length), S(this._tab), this._tab.sel = null, this._closeGoToLine(), this._scrollIntoView(), this._render(), (o = (r = this._config).onCursorChange) == null || o.call(r, { ...this._tab.cur }));
3509
+ } else n.key === "Escape" && (n.preventDefault(), this._closeGoToLine());
3510
+ n.stopPropagation();
3511
+ }), e.querySelector(".sl-gtl-close").addEventListener("click", () => this._closeGoToLine()), e;
3512
+ }
3513
+ _openGoToLine() {
3514
+ if (this._goToLineBar.classList.contains("sl-open")) {
3515
+ this._closeGoToLine();
3516
+ return;
3517
+ }
3518
+ this._goToLineHint.textContent = `(1–${this._tab.doc.length})`, this._goToLineInput.value = String(this._tab.cur.row + 1), this._goToLineInput.classList.remove("sl-gtl-err"), this._goToLineBar.classList.add("sl-open"), this._goToLineInput.focus(), this._goToLineInput.select();
3519
+ }
3520
+ _closeGoToLine() {
3521
+ this._goToLineBar.classList.remove("sl-open"), this._focusInput();
3522
+ }
3523
+ _buildStatusBar() {
3524
+ const e = I("div", "sl-statusbar");
3525
+ return e.innerHTML = `
3526
+ <div class="sl-sb-item sl-no-click sl-sb-lang">⬡ TypeScript</div>
3527
+ <div class="sl-sb-sep"></div>
3528
+ <div class="sl-sb-item sl-no-click sl-sb-pos">Ln 1, Col 1</div>
3529
+ <div class="sl-sb-sep"></div>
3530
+ <div class="sl-sb-item sl-no-click sl-sb-sel"></div>
3531
+ <div class="sl-sb-sep sl-sb-sel-sep" style="display:none"></div>
3532
+ <div class="sl-sb-item sl-no-click sl-sb-lines">1 line</div>
3533
+ <div class="sl-sb-sep"></div>
3534
+ <div class="sl-sb-item sl-no-click">UTF-8 LF</div>
3535
+ <div class="sl-sb-right">
3536
+ <div class="sl-sb-item sl-no-click sl-sb-mc" style="display:none">⊕ <span class="sl-sb-mc-count">1</span> cursors</div>
3537
+ <div class="sl-sb-item sl-sb-wrap sl-sb-wrap-btn">⇥ Wrap: OFF</div>
3538
+ <div class="sl-sb-sep"></div>
3539
+ <div class="sl-sb-item sl-sb-theme-btn">🎨 Theme</div>
3540
+ <div class="sl-sb-sep"></div>
3541
+ <div class="sl-sb-item sl-no-click sl-sb-undo">↩0 ↪0</div>
3542
+ </div>
3543
+ `, e.querySelector(".sl-sb-wrap-btn").addEventListener("click", () => this._toggleWrap()), e.querySelector(".sl-sb-theme-btn").addEventListener("click", () => this._openThemePicker()), e;
3544
+ }
3545
+ // ── Dynamic styles ────────────────────────────────────────
3546
+ _applyDynamicStyles() {
3547
+ const {
3548
+ fontFamily: e,
3549
+ fontSize: t,
3550
+ lineHeight: i,
3551
+ cursorBlinkRate: n,
3552
+ cursorStyle: r,
3553
+ gutterWidth: o,
3554
+ minimapWidth: l,
3555
+ showGutter: a
3556
+ } = this._config, c = Math.max(2, i - 4), d = Math.floor((i - c) / 2);
3557
+ let h = "";
3558
+ r === "block" ? h = `width:${7.82}px;opacity:.5;border-radius:1px;` : r === "underline" && (h = `width:${7.82}px;height:2px;top:${i - 2}px;border-radius:0;`);
3559
+ const p = a ? o : 0;
3560
+ this._dynamicStyleEl.textContent = `
3561
+ .sl-el{font-family:${e};font-size:${t}px;line-height:${i}px}
3562
+ .sl-cl{height:${i}px;line-height:${i}px}
3563
+ .sl-egn{height:${i}px;line-height:${i}px}
3564
+ .sl-eg{min-width:${p}px;width:${p}px;${a ? "" : "display:none"}}
3565
+ .sl-cur::after{height:${c}px;top:${d}px;animation-duration:${n}ms;${h}}
3566
+ .sl-cur-extra::after{height:${c}px;top:${d}px;animation-duration:${n}ms;${h}}
3567
+ `, this._applyTokenOverrides(), this._minimapWrap.style.width = `${l}px`, this._placeholderEl.style.left = `${p + 14}px`, this._placeholderEl.style.fontFamily = e, this._placeholderEl.style.fontSize = `${t}px`, this._placeholderEl.style.lineHeight = `${i}px`;
3568
+ }
3569
+ /**
3570
+ * Apply tokenColors overrides as inline styles on the host element.
3571
+ * Must be called AFTER the theme has applied its own inline styles so
3572
+ * our values win (last writer wins for element.style.setProperty).
3573
+ * When a token field is empty/absent, restore the active theme's value.
3574
+ */
3575
+ _applyTokenOverrides() {
3576
+ const e = this._config.tokenColors ?? {}, t = this._themeManager.activeTheme, i = this._host.style, n = (o, l, a) => {
3577
+ i.setProperty(o, l || a);
3578
+ }, r = t == null ? void 0 : t.tokens;
3579
+ n("--tok-kw", e.keyword, (r == null ? void 0 : r.tokKw) ?? ""), n("--tok-str", e.string, (r == null ? void 0 : r.tokStr) ?? ""), n("--tok-cmt", e.comment, (r == null ? void 0 : r.tokCmt) ?? ""), n("--tok-fn", e.function, (r == null ? void 0 : r.tokFn) ?? ""), n("--tok-num", e.number, (r == null ? void 0 : r.tokNum) ?? ""), n("--tok-cls", e.class, (r == null ? void 0 : r.tokCls) ?? ""), n("--tok-op", e.operator, (r == null ? void 0 : r.tokOp) ?? ""), n("--tok-typ", e.type, (r == null ? void 0 : r.tokTyp) ?? ""), n("--tok-dec", e.decorator, (r == null ? void 0 : r.tokDec) ?? "");
3580
+ }
3581
+ // ── Core render ───────────────────────────────────────────
3582
+ /**
3583
+ * Schedule a render on the next animation frame.
3584
+ * Multiple calls within a single frame are coalesced into one render —
3585
+ * ideal for scroll and resize handlers which can fire at 60+ Hz.
3586
+ */
3587
+ _scheduleRender() {
3588
+ this._rafId === null && (this._rafId = requestAnimationFrame(() => {
3589
+ this._rafId = null, this._render();
3590
+ }));
3591
+ }
3592
+ _render() {
3593
+ const { doc: e, cur: t, sel: i } = this._tab, { lineHeight: n } = this._config;
3594
+ this._wordHighlights = this._config.wordHighlight ? Ct(e, t.row, t.col, i) : [], this._bracketMatch = this._config.bracketMatching ? at(e, t) : null;
3595
+ const r = this._wm.visualRows.length;
3596
+ if (this._spacerEl.style.height = `${r * n}px`, this._config.wordWrap)
3597
+ this._spacerEl.style.width = "", this._vpEl.style.width = "";
3598
+ else {
3599
+ const f = e.reduce((v, u) => Math.max(v, u.length), 0), _ = this._config.showGutter ? this._config.gutterWidth : 0, b = Math.max(
3600
+ this._editorEl.clientWidth,
3601
+ _ + 14 + Math.ceil(f * 7.82) + 20 + 64
3602
+ );
3603
+ this._spacerEl.style.width = `${b}px`, this._vpEl.style.width = `${b}px`;
3604
+ }
3605
+ const o = this._editorEl.scrollTop, l = this._editorEl.clientHeight, a = Math.max(0, Math.floor(o / n) - 6), c = Math.min(r - 1, Math.ceil((o + l) / n) + 6);
3606
+ this._vpEl.style.transform = `translateY(${a * n}px)`;
3607
+ const d = F(this._wm, t.row, t.col), h = /* @__PURE__ */ new Map();
3608
+ if (this._snippetSession)
3609
+ for (let f = this._snippetSession.idx + 1; f < this._snippetSession.stops.length; f++) {
3610
+ const _ = this._snippetSession.stops[f], b = F(this._wm, _.row, _.col), v = h.get(b.visRow) ?? [];
3611
+ v.push(b.colInSeg), h.set(b.visRow, v);
3612
+ }
3613
+ let p = "";
3614
+ for (let f = a; f <= c; f++) {
3615
+ const _ = this._wm.visualRows[f];
3616
+ _ && (p += Rt({
3617
+ vr: _,
3618
+ visIdx: f,
3619
+ curVisRow: d.visRow,
3620
+ curColInSeg: d.colInSeg,
3621
+ docSel: i,
3622
+ findMatches: this._findMatches,
3623
+ findIdx: this._findIdx,
3624
+ wordHighlights: this._wordHighlights,
3625
+ bracketMatch: this._bracketMatch,
3626
+ extraCursors: this._extraCursors,
3627
+ snippetStopCols: h.get(f) ?? [],
3628
+ foldedLines: this._foldedLines,
3629
+ isFoldable: this._config.codeFolding && lt(e, _.docLine),
3630
+ wm: this._wm,
3631
+ tokenCache: this._tokenCache,
3632
+ opts: {
3633
+ tokeniserOpts: {
3634
+ language: this._config.language,
3635
+ extraKeywords: new Set(this._config.extraKeywords),
3636
+ extraTypes: new Set(this._config.extraTypes)
3637
+ },
3638
+ showIndentGuides: this._config.showIndentGuides,
3639
+ highlightActiveLine: this._config.highlightActiveLine,
3640
+ charWidth: 7.82,
3641
+ codePaddingLeft: 14,
3642
+ tabSize: this._config.tabSize,
3643
+ lineHeight: n,
3644
+ renderWhitespace: this._config.renderWhitespace
3645
+ }
3646
+ }));
3647
+ }
3648
+ if (this._vpEl.innerHTML = p, this._updateStatusBar(), this._updateMinimap(), this._config.placeholder) {
3649
+ const f = this._tab.doc.length === 1 && this._tab.doc[0] === "";
3650
+ this._placeholderEl.style.display = f ? "" : "none";
3651
+ } else
3652
+ this._placeholderEl.style.display = "none";
3653
+ }
3654
+ // ── Status bar ────────────────────────────────────────────
3655
+ _updateStatusBar() {
3656
+ if (!this._config.showStatusBar) return;
3657
+ const { cur: e, doc: t, undoStack: i, redoStack: n } = this._tab, r = this._config.language, o = {
3658
+ typescript: "TypeScript",
3659
+ javascript: "JavaScript",
3660
+ css: "CSS",
3661
+ json: "JSON",
3662
+ markdown: "Markdown",
3663
+ text: "Text"
3664
+ }, l = (p) => this._statusBar.querySelector(p);
3665
+ l(".sl-sb-lang").textContent = `⬡ ${o[r] ?? r}`, l(".sl-sb-pos").textContent = `Ln ${e.row + 1}, Col ${e.col + 1}`, l(".sl-sb-lines").textContent = `${t.length.toLocaleString()} lines`;
3666
+ const a = Ue(this._tab), c = l(".sl-sb-sel"), d = l(".sl-sb-sel-sep");
3667
+ c.textContent = a ? `${a.toLocaleString()} selected` : "", d.style.display = a ? "" : "none", l(".sl-sb-undo").textContent = `↩${i.length} ↪${n.length}`;
3668
+ const h = l(".sl-sb-mc");
3669
+ this._extraCursors.length ? (h.style.display = "", l(".sl-sb-mc-count").textContent = String(this._extraCursors.length + 1)) : h.style.display = "none";
3670
+ }
3671
+ // ── Minimap ───────────────────────────────────────────────
3672
+ _updateMinimap() {
3673
+ if (!this._config.showMinimap) return;
3674
+ const e = this._minimapWrap.clientWidth, t = this._minimapWrap.clientHeight;
3675
+ if (!e || !t) return;
3676
+ const i = this._tab.doc, n = i.length, r = Math.min(window.devicePixelRatio || 1, 2), o = this._config.lineHeight, { mmScroll: l, sliderTop: a, sliderHeight: c } = ie(
3677
+ n,
3678
+ this._editorEl.scrollTop,
3679
+ this._editorEl.clientHeight,
3680
+ t,
3681
+ o
3682
+ ), d = l / 2, h = Math.floor(d), p = Math.ceil(t / 2) + 2, f = Math.min(n, h + p), _ = (f - h) * 2, b = (d - h) * 2, v = Math.round(e * r), u = Math.round(_ * r);
3683
+ (this._mmCanvas.width !== v || this._mmCanvas.height !== u) && (this._mmCanvas.width = v, this._mmCanvas.height = u, this._mmCanvas.style.width = `${e}px`, this._mmCanvas.style.height = `${_}px`), this._mmCanvas.style.transform = `translateY(${-b}px)`, Ot({
3684
+ canvas: this._mmCanvas,
3685
+ doc: i,
3686
+ firstLine: h,
3687
+ lastLine: f,
3688
+ subPx: b,
3689
+ wrapperWidth: e,
3690
+ canvasHeight: _,
3691
+ cursorRow: this._tab.cur.row,
3692
+ sel: this._tab.sel,
3693
+ findMatches: this._findMatches,
3694
+ findIdx: this._findIdx,
3695
+ sliderTop: a,
3696
+ sliderHeight: c,
3697
+ colors: this._mmColors,
3698
+ getCssVar: (T) => X(T, this._host),
3699
+ dpr: r
3700
+ }), this._mmSlider.style.top = `${Math.max(0, Math.min(t - c, a))}px`, this._mmSlider.style.height = `${c}px`;
3701
+ }
3702
+ // ── WrapMap ───────────────────────────────────────────────
3703
+ _rebuildWrapMap() {
3704
+ let e;
3705
+ if (this._config.wordWrap) {
3706
+ const t = this._config.showGutter ? this._config.gutterWidth : 0, i = this._editorEl.clientWidth;
3707
+ if (i > 0) {
3708
+ const n = i - t - 14 - 20;
3709
+ e = Math.max(20, Math.floor(n / 7.82));
3710
+ } else
3711
+ e = this._config.wrapColumn;
3712
+ } else
3713
+ e = 9999;
3714
+ this._wm = ze(
3715
+ this._tab.doc,
3716
+ e,
3717
+ this._config.wordWrap,
3718
+ this._foldedLines
3719
+ );
3720
+ }
3721
+ // ── Scroll ────────────────────────────────────────────────
3722
+ _scrollIntoView() {
3723
+ const e = this._tab.cur, i = F(this._wm, e.row, e.col).visRow * this._config.lineHeight, n = i + this._config.lineHeight, r = this._editorEl.scrollTop, o = this._editorEl.clientHeight, l = this._config.lineHeight * 3;
3724
+ i < r + l ? this._editorEl.scrollTop = Math.max(0, i - l) : n > r + o - l && (this._editorEl.scrollTop = n - o + l);
3725
+ }
3726
+ // ── Input helpers ─────────────────────────────────────────
3727
+ _focusInput() {
3728
+ this._inputEl.style.pointerEvents = "auto", this._inputEl.focus(), this._inputEl.style.pointerEvents = "none";
3729
+ }
3730
+ _insertStr(e, t) {
3731
+ var d, h;
3732
+ const i = Date.now();
3733
+ (!t || i - this._lastInputTime > this._config.undoBatchMs) && L(this._tab, this._config.maxUndoHistory), this._lastInputTime = i, this._tab.sel && (this._tab.cur = G(this._tab));
3734
+ const { doc: n, cur: r } = this._tab, o = e.split(`
3735
+ `), l = n[r.row] ?? "", a = l.slice(0, r.col), c = l.slice(r.col);
3736
+ if (o.length === 1)
3737
+ n[r.row] = a + e + c, r.col += e.length;
3738
+ else {
3739
+ const p = [a + o[0]];
3740
+ for (let f = 1; f < o.length - 1; f++) p.push(o[f]);
3741
+ p.push(o[o.length - 1] + c), n.splice(r.row, 1, ...p), r.row += o.length - 1, r.col = o[o.length - 1].length;
3742
+ }
3743
+ this._tokenCache.invalidateLine(r.row, (this._wm.segments[r.row] ?? [""]).length), this._tab.dirty = !0, (h = (d = this._config).onChange) == null || h.call(d, A(n));
3744
+ }
3745
+ _doBackspace() {
3746
+ var i;
3747
+ if (L(this._tab, this._config.maxUndoHistory), this._tab.sel) {
3748
+ this._tab.cur = G(this._tab), this._tokenCache.clear(), this._tab.dirty = !0;
3749
+ return;
3750
+ }
3751
+ const { doc: e, cur: t } = this._tab;
3752
+ if (t.col > 0) {
3753
+ const n = e[t.row] ?? "", r = n.slice(0, t.col), o = r.length >= 2 && r.endsWith(" ") && !r.trim() ? 2 : 1;
3754
+ e[t.row] = n.slice(0, t.col - o) + n.slice(t.col), t.col -= o, this._tokenCache.invalidateLine(t.row, ((i = this._wm.segments[t.row]) == null ? void 0 : i.length) ?? 1);
3755
+ } else if (t.row > 0) {
3756
+ const n = (e[t.row - 1] ?? "").length;
3757
+ e[t.row - 1] += e[t.row] ?? "", e.splice(t.row, 1), t.row--, t.col = n, this._tokenCache.clear();
3758
+ }
3759
+ this._tab.dirty = !0;
3760
+ }
3761
+ _doEnter() {
3762
+ L(this._tab, this._config.maxUndoHistory), this._tab.sel && (this._tab.cur = G(this._tab));
3763
+ const { doc: e, cur: t } = this._tab, i = e[t.row] ?? "", n = i.slice(0, t.col), r = i.slice(t.col), o = _e(i), l = n.trimEnd().endsWith("{") ? J(this._config.tabSize) : "";
3764
+ e[t.row] = n, n.trimEnd().endsWith("{") && r.trimStart() === "}" ? e.splice(t.row + 1, 0, o + l, o + r) : e.splice(t.row + 1, 0, o + l + r), t.row++, t.col = o.length + l.length, this._tokenCache.clear(), this._tab.dirty = !0;
3765
+ }
3766
+ _doDelete() {
3767
+ var n;
3768
+ if (L(this._tab, this._config.maxUndoHistory), this._tab.sel) {
3769
+ this._tab.cur = G(this._tab), this._tokenCache.clear(), this._tab.dirty = !0;
3770
+ return;
3771
+ }
3772
+ const { doc: e, cur: t } = this._tab, i = e[t.row] ?? "";
3773
+ t.col < i.length ? (e[t.row] = i.slice(0, t.col) + i.slice(t.col + 1), this._tokenCache.invalidateLine(t.row, ((n = this._wm.segments[t.row]) == null ? void 0 : n.length) ?? 1)) : t.row < e.length - 1 && (e[t.row] = i + (e[t.row + 1] ?? ""), e.splice(t.row + 1, 1), this._tokenCache.clear()), this._tab.dirty = !0;
3774
+ }
3775
+ // ── Editing commands ──────────────────────────────────────
3776
+ _selectAll() {
3777
+ const e = this._tab.doc, t = e.length - 1;
3778
+ this._tab.sel = { ar: 0, ac: 0, fr: t, fc: (e[t] ?? "").length }, this._tab.cur = { row: t, col: (e[t] ?? "").length }, this._render();
3779
+ }
3780
+ _doCopy() {
3781
+ var t;
3782
+ const e = ge(this._tab);
3783
+ e && ((t = navigator.clipboard) == null || t.writeText(e).catch(() => {
3784
+ }));
3785
+ }
3786
+ _doCut() {
3787
+ var t, i, n;
3788
+ const e = ge(this._tab);
3789
+ e && ((t = navigator.clipboard) == null || t.writeText(e).catch(() => {
3790
+ }), L(this._tab, this._config.maxUndoHistory), this._tab.cur = G(this._tab), this._tokenCache.clear(), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (n = (i = this._config).onChange) == null || n.call(i, A(this._tab.doc)));
3791
+ }
3792
+ _toggleComment() {
3793
+ var r, o;
3794
+ L(this._tab, this._config.maxUndoHistory);
3795
+ const e = this._getSelRows(), t = this._config.lineCommentToken || Re[this._config.language] || "";
3796
+ if (!t) return;
3797
+ const i = t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), n = e.every((l) => (this._tab.doc[l] ?? "").trimStart().startsWith(t));
3798
+ e.forEach((l) => {
3799
+ var c;
3800
+ const a = this._tab.doc[l] ?? "";
3801
+ this._tab.doc[l] = n ? a.replace(new RegExp(`^(\\s*)${i}\\s?`), "$1") : a.replace(/^(\s*)/, `$1${t} `), this._tokenCache.invalidateLine(l, ((c = this._wm.segments[l]) == null ? void 0 : c.length) ?? 1);
3802
+ }), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (o = (r = this._config).onChange) == null || o.call(r, A(this._tab.doc));
3803
+ }
3804
+ _duplicateLine() {
3805
+ var t, i;
3806
+ L(this._tab, this._config.maxUndoHistory);
3807
+ const e = this._tab.cur.row;
3808
+ this._tab.doc.splice(e + 1, 0, this._tab.doc[e] ?? ""), this._tab.cur.row++, this._tokenCache.clear(), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, A(this._tab.doc));
3809
+ }
3810
+ _deleteLine() {
3811
+ var i, n;
3812
+ L(this._tab, this._config.maxUndoHistory);
3813
+ const { doc: e, cur: t } = this._tab;
3814
+ e.length > 1 ? e.splice(t.row, 1) : (e[0] = "", t.col = 0), this._tokenCache.clear(), this._tab.dirty = !0, S(this._tab), this._rebuildWrapMap(), this._render(), (n = (i = this._config).onChange) == null || n.call(i, A(this._tab.doc));
3815
+ }
3816
+ _indentSel() {
3817
+ var t, i;
3818
+ if (!this._tab.sel) {
3819
+ this._insertStr(J(this._config.tabSize), !1);
3820
+ return;
3821
+ }
3822
+ L(this._tab, this._config.maxUndoHistory);
3823
+ const e = J(this._config.tabSize);
3824
+ this._getSelRows().forEach((n) => {
3825
+ var r;
3826
+ this._tab.doc[n] = e + (this._tab.doc[n] ?? ""), this._tokenCache.invalidateLine(n, ((r = this._wm.segments[n]) == null ? void 0 : r.length) ?? 1);
3827
+ }), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, A(this._tab.doc));
3828
+ }
3829
+ _unindentSel() {
3830
+ var t, i;
3831
+ L(this._tab, this._config.maxUndoHistory);
3832
+ const e = this._config.tabSize;
3833
+ this._getSelRows().forEach((n) => {
3834
+ var o;
3835
+ const r = this._tab.doc[n] ?? "";
3836
+ r.startsWith(J(e)) ? this._tab.doc[n] = r.slice(e) : r.startsWith(" ") && (this._tab.doc[n] = r.slice(1)), this._tokenCache.invalidateLine(n, ((o = this._wm.segments[n]) == null ? void 0 : o.length) ?? 1);
3837
+ }), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, A(this._tab.doc));
3838
+ }
3839
+ _toggleWrap() {
3840
+ this._config.wordWrap = !this._config.wordWrap, this._vpEl.classList.toggle("sl-wrap-mode", this._config.wordWrap);
3841
+ const e = this._statusBar.querySelector(".sl-sb-wrap-btn");
3842
+ e && (e.textContent = `⇥ Wrap: ${this._config.wordWrap ? "ON" : "OFF"}`, e.classList.toggle("sl-on", this._config.wordWrap)), this._tokenCache.clear(), this._rebuildWrapMap(), this._render();
3843
+ }
3844
+ _getSelRows() {
3845
+ if (!this._tab.sel) return [this._tab.cur.row];
3846
+ const e = $(this._tab.sel), t = [];
3847
+ for (let i = e.ar; i <= e.fr; i++) t.push(i);
3848
+ return t;
3849
+ }
3850
+ // ── Mouse position helper ─────────────────────────────────
3851
+ _posFromMouse(e) {
3852
+ var c;
3853
+ const t = this._editorEl.getBoundingClientRect(), i = e.clientY - t.top + this._editorEl.scrollTop, n = this._config.showGutter ? this._config.gutterWidth : 0, r = e.clientX - t.left - n - 14, o = this._config.lineHeight, l = Math.max(0, Math.min(this._wm.visualRows.length - 1, Math.floor(i / o))), a = Math.max(0, Math.min(
3854
+ (((c = this._wm.visualRows[l]) == null ? void 0 : c.text) ?? "").length,
3855
+ Math.round(r / 7.82)
3856
+ ));
3857
+ return Y(this._wm, l, a);
3858
+ }
3859
+ // ── Find ──────────────────────────────────────────────────
3860
+ _openFind(e) {
3861
+ this._findBar.classList.add("sl-open"), this._replaceRow.style.display = e && this._config.findReplace ? "" : "none", this._findInput.focus(), this._findInput.select(), this._runFind(this._findInput.value), this._findMatches.length ? (this._findIdx = -1, this._navFind(1)) : this._render();
3862
+ }
3863
+ _closeFind() {
3864
+ this._findBar.classList.remove("sl-open"), this._findMatches = [], this._findIdx = -1, this._findCount.textContent = "–", this._focusInput(), this._render();
3865
+ }
3866
+ _runFind(e) {
3867
+ this._findMatches = wt(this._tab.doc, e, {
3868
+ caseSensitive: this._findCaseSensitive,
3869
+ useRegex: this._findRegex
3870
+ });
3871
+ }
3872
+ _navFind(e) {
3873
+ if (!this._findMatches.length) {
3874
+ this._findCount.textContent = "0/0";
3875
+ return;
3876
+ }
3877
+ this._findIdx = Tt(this._findMatches, this._findIdx, e);
3878
+ const t = this._findMatches[this._findIdx];
3879
+ this._tab.cur = { row: t.row, col: t.col }, this._tab.sel = { ar: t.row, ac: t.col, fr: t.row, fc: t.col + t.len }, this._scrollIntoView(), this._render(), this._findCount.textContent = `${this._findIdx + 1}/${this._findMatches.length}`;
3880
+ }
3881
+ // ── Autocomplete ──────────────────────────────────────────
3882
+ _acVisible() {
3883
+ return this._acPopup.style.display !== "none";
3884
+ }
3885
+ _acHide() {
3886
+ this._acPopup.style.display = "none", this._acItems = [];
3887
+ }
3888
+ /**
3889
+ * Schedule an autocomplete refresh after a brief debounce pause.
3890
+ * Prevents the suggestion engine running on every single keystroke —
3891
+ * only fires when the user pauses for `AC_DEBOUNCE_MS` milliseconds.
3892
+ * Call `_acTriggerNow()` directly when an immediate refresh is required
3893
+ * (e.g., on explicit Ctrl+Space or arrow-key navigation).
3894
+ */
3895
+ _acTrigger() {
3896
+ if (!this._config.autocomplete) {
3897
+ this._acHide();
3898
+ return;
3899
+ }
3900
+ this._acDebounceTimer !== null && clearTimeout(this._acDebounceTimer), this._acDebounceTimer = setTimeout(() => {
3901
+ this._acDebounceTimer = null, this._acTriggerNow();
3902
+ }, 120);
3903
+ }
3904
+ /** Run an autocomplete refresh immediately (no debounce). */
3905
+ _acTriggerNow() {
3906
+ if (!this._config.autocomplete) {
3907
+ this._acHide();
3908
+ return;
3909
+ }
3910
+ const { cur: e, doc: t } = this._tab, i = t[e.row] ?? "", n = this._config.language === "css", { prefix: r, start: o } = It(i, e.col, n);
3911
+ this._acPrefix = r, this._acStartCol = o;
3912
+ const l = [];
3913
+ if (this._config.emmet) {
3914
+ const c = we(i, e.col);
3915
+ if (c) {
3916
+ const d = ve(c.abbr);
3917
+ if (d) {
3918
+ this._emmetAcStartCol = c.start;
3919
+ const h = d.replace(/\n/g, "↵ ").slice(0, 60);
3920
+ l.push({ label: c.abbr, kind: "emmet", detail: h, body: d });
3921
+ }
3922
+ }
3923
+ }
3924
+ const a = r.length >= this._config.autocompletePrefixLength ? Lt(t, r, {
3925
+ language: this._config.language,
3926
+ extraKeywords: this._config.extraKeywords,
3927
+ extraTypes: this._config.extraTypes,
3928
+ completions: this._allCompletions(),
3929
+ replaceBuiltins: this._config.replaceBuiltins,
3930
+ maxResults: this._config.maxCompletions,
3931
+ provideCompletions: this._config.provideCompletions
3932
+ }, e.row, e.col) : [];
3933
+ if (this._acItems = [...l, ...a], !this._acItems.length) {
3934
+ this._acHide();
3935
+ return;
3936
+ }
3937
+ this._acSel = 0, this._renderAcPopup();
3938
+ }
3939
+ _renderAcPopup() {
3940
+ const e = (a) => {
3941
+ switch (a) {
3942
+ case "kw":
3943
+ return "K";
3944
+ case "fn":
3945
+ return "f";
3946
+ case "typ":
3947
+ return "T";
3948
+ case "cls":
3949
+ return "C";
3950
+ case "snip":
3951
+ return "S";
3952
+ case "emmet":
3953
+ return "E";
3954
+ default:
3955
+ return "·";
3956
+ }
3957
+ }, t = this._acItems[this._acSel];
3958
+ let i = "";
3959
+ t != null && t.description ? i = t.description : (t == null ? void 0 : t.kind) === "snip" && t.body ? i = t.body.replace(/\$\d/g, "▌") : (t == null ? void 0 : t.kind) === "emmet" && t.body && (i = t.body);
3960
+ const n = this._acItems.map((a, c) => {
3961
+ const d = c === this._acSel;
3962
+ return `<div class="sl-ac-item${d ? " sl-sel" : ""}" data-i="${c}" role="option" aria-selected="${d}"><span class="sl-ac-badge ${a.kind}">${e(a.kind)}</span><span class="sl-ac-label">${a.label}</span><span class="sl-ac-detail">${a.detail ?? ""}</span></div>`;
3963
+ }).join(""), r = i ? `<div class="sl-ac-desc"><pre class="sl-ac-desc-body">${i.replace(/</g, "&lt;")}</pre></div>` : "";
3964
+ this._acPopup.innerHTML = `<div class="sl-ac-list">${n}</div>` + r, this._acPopup.style.display = "flex", this._posAcPopup();
3965
+ const o = this._acPopup.querySelector(".sl-ac-list"), l = this._acPopup.querySelector(".sl-ac-item.sl-sel");
3966
+ if (o && l) {
3967
+ const a = l.offsetTop, c = a + l.offsetHeight;
3968
+ c > o.scrollTop + o.clientHeight ? o.scrollTop = c - o.clientHeight : a < o.scrollTop && (o.scrollTop = a);
3969
+ }
3970
+ this._acPopup.querySelectorAll(".sl-ac-item").forEach((a) => {
3971
+ a.addEventListener("mousedown", (c) => {
3972
+ c.preventDefault(), this._acSel = parseInt(a.dataset.i ?? "0", 10), this._acAccept();
3973
+ });
3974
+ });
3975
+ }
3976
+ _posAcPopup() {
3977
+ const e = this._editorEl.getBoundingClientRect(), t = F(this._wm, this._tab.cur.row, this._tab.cur.col), i = this._config.showGutter ? this._config.gutterWidth : 0, n = e.left + i + 14 + this._acStartCol * 7.82, r = e.top + (t.visRow * this._config.lineHeight - this._editorEl.scrollTop) + this._config.lineHeight + 2, l = !!this._acPopup.querySelector(".sl-ac-desc") ? 620 : 300, a = Math.min(this._acItems.length * 28 + 8, 320), c = r + a > window.innerHeight - 16;
3978
+ this._acPopup.style.left = `${Math.min(n, window.innerWidth - l - 16)}px`, this._acPopup.style.top = `${c ? r - this._config.lineHeight - 2 - a : r}px`;
3979
+ }
3980
+ _acAccept() {
3981
+ const e = this._acItems[this._acSel];
3982
+ if (!e) return;
3983
+ if (this._acHide(), e.kind === "emmet" && e.body) {
3984
+ L(this._tab, this._config.maxUndoHistory), this._expandBodyAt(e.body, this._emmetAcStartCol);
3985
+ return;
3986
+ }
3987
+ if (e.body) {
3988
+ L(this._tab, this._config.maxUndoHistory), this._expandBodyAt(e.body, this._acStartCol);
3989
+ return;
3990
+ }
3991
+ const t = e.label.slice(this._acPrefix.length);
3992
+ this._insertStr(t, !1), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render();
3993
+ }
3994
+ // ── Emmet ─────────────────────────────────────────────────
3995
+ _emmetCheck() {
3996
+ if (this._emmetTip.style.display = "none", !this._config.emmet) {
3997
+ this._emmetExpanded = null;
3998
+ return;
3999
+ }
4000
+ const { cur: e, doc: t } = this._tab, i = t[e.row] ?? "", n = we(i, e.col);
4001
+ if (!n) {
4002
+ this._emmetExpanded = null;
4003
+ return;
4004
+ }
4005
+ const r = ve(n.abbr);
4006
+ if (!r) {
4007
+ this._emmetExpanded = null;
4008
+ return;
4009
+ }
4010
+ this._emmetExpanded = { abbr: n.abbr, result: r, start: n.start };
4011
+ }
4012
+ _emmetAccept() {
4013
+ if (!this._emmetExpanded || this._emmetTip.style.display === "none") return !1;
4014
+ const { abbr: e, result: t, start: i } = this._emmetExpanded;
4015
+ return L(this._tab, this._config.maxUndoHistory), this._emmetExpanded = null, this._emmetTip.style.display = "none", this._expandBodyAt(t, i), !0;
4016
+ }
4017
+ // ── Snippets / Completions ────────────────────────────────
4018
+ /** Returns built-in snippets for the current language merged with user completions.
4019
+ * When `replaceBuiltins` is true the language built-ins are suppressed so only
4020
+ * the caller-supplied completions (e.g. MDX_SNIPPETS) are active. */
4021
+ _allCompletions() {
4022
+ return [...this._config.replaceBuiltins ? [] : gt(this._config.language), ...this._config.completions];
4023
+ }
4024
+ _snippetCheck() {
4025
+ if (this._snippetTip.style.display = "none", !this._config.snippetExpansion) {
4026
+ this._snippetExpanded = null;
4027
+ return;
4028
+ }
4029
+ const { cur: e, doc: t } = this._tab, i = t[e.row] ?? "", n = bt(i, e.col, this._allCompletions());
4030
+ if (!n) {
4031
+ this._snippetExpanded = null;
4032
+ return;
4033
+ }
4034
+ this._snippetExpanded = { snippet: n.snippet, start: n.start };
4035
+ }
4036
+ _snippetAccept() {
4037
+ if (!this._snippetExpanded || this._snippetTip.style.display === "none") return !1;
4038
+ const { snippet: e, start: t } = this._snippetExpanded;
4039
+ return e.body ? (L(this._tab, this._config.maxUndoHistory), this._snippetExpanded = null, this._snippetTip.style.display = "none", this._expandBodyAt(e.body, t), !0) : !1;
4040
+ }
4041
+ /**
4042
+ * Expand a snippet/emmet body template at the current cursor position.
4043
+ * `triggerStart` is the column where the trigger word begins.
4044
+ * `cur.col` must be at the end of the trigger (emmet) or at `triggerStart`
4045
+ * when the prefix was already stripped (snippet accepted from popup).
4046
+ * Everything between `triggerStart` and `cur.col` is replaced by `body`.
4047
+ */
4048
+ _expandBodyAt(e, t) {
4049
+ var u, T;
4050
+ const { doc: i, cur: n } = this._tab, r = n.row, o = i[n.row] ?? "", l = o.slice(0, t), a = o.slice(n.col), c = _e(o), d = e.split(`
4051
+ `).map((m, w) => w === 0 ? m : c + m), h = d.join(`
4052
+ `), p = [], f = /\$(\d+)/g;
4053
+ let _;
4054
+ for (; (_ = f.exec(h)) !== null; ) {
4055
+ const m = parseInt(_[1], 10), y = h.slice(0, _.index).split(`
4056
+ `), D = y.length - 1, R = y[D].length, C = (y[D].match(/\$\d+/g) ?? []).join("").length, U = r + D, P = (D === 0 ? t : c.length) + (R - C);
4057
+ p.push({ n: m, row: U, col: P });
4058
+ }
4059
+ p.sort((m, w) => m.n === 0 ? 1 : w.n === 0 ? -1 : m.n - w.n);
4060
+ const b = d.map((m) => m.replace(/\$\d+/g, "")), v = b.length === 1 ? [l + b[0] + a] : [l + b[0], ...b.slice(1, -1), b[b.length - 1] + a];
4061
+ i.splice(n.row, 1, ...v), p.length > 0 ? (this._snippetSession = { stops: p.map((m) => ({ row: m.row, col: m.col })), idx: 0 }, n.row = p[0].row, n.col = p[0].col) : (this._snippetSession = null, n.row += v.length - 1, n.col = (v[v.length - 1] ?? "").length - a.length), this._tokenCache.clear(), this._tab.dirty = !0, this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (T = (u = this._config).onChange) == null || T.call(u, A(this._tab.doc));
4062
+ }
4063
+ // ── Theme picker ──────────────────────────────────────────
4064
+ _openThemePicker() {
4065
+ var t;
4066
+ const e = this._themeManager.all;
4067
+ this._themePanel.innerHTML = `
4068
+ <div class="sl-theme-header">
4069
+ <div class="sl-theme-title">Color Theme</div>
4070
+ <div class="sl-theme-close">✕</div>
4071
+ </div>
4072
+ <div class="sl-theme-list">
4073
+ ${e.map((i) => `
4074
+ <div class="sl-theme-item${i.id === this._themeManager.activeId ? " sl-active" : ""}" data-id="${i.id}">
4075
+ <div class="sl-theme-swatch">
4076
+ ${i.tokens.bg0 ? `<span style="background:${i.tokens.bg0}"></span>` : ""}
4077
+ <span style="background:${i.tokens.accent}"></span>
4078
+ <span style="background:${i.tokens.tokStr}"></span>
4079
+ <span style="background:${i.tokens.tokFn}"></span>
4080
+ </div>
4081
+ <div>
4082
+ <div class="sl-theme-name">${i.name}<span class="sl-theme-tag${i.light ? " sl-light" : ""}">${i.light ? "Light" : "Dark"}</span></div>
4083
+ <div class="sl-theme-desc">${i.description}</div>
4084
+ </div>
4085
+ <div class="sl-theme-check">✓</div>
4086
+ </div>
4087
+ `).join("")}
4088
+ </div>
4089
+ `, this._themeOverlay.style.display = "block", (t = this._themePanel.querySelector(".sl-theme-close")) == null || t.addEventListener("click", () => {
4090
+ this._themeOverlay.style.display = "none";
4091
+ }), this._themeOverlay.addEventListener("click", (i) => {
4092
+ i.target === this._themeOverlay && (this._themeOverlay.style.display = "none");
4093
+ }, { once: !0 }), this._themePanel.querySelectorAll(".sl-theme-item").forEach((i) => {
4094
+ i.addEventListener("click", () => {
4095
+ const n = i.dataset.id ?? "";
4096
+ this.setTheme(n), this._themePanel.querySelectorAll(".sl-theme-item").forEach((r) => r.classList.remove("sl-active")), i.classList.add("sl-active");
4097
+ });
4098
+ });
4099
+ }
4100
+ // ── Event binding ─────────────────────────────────────────
4101
+ _bindEditorEvents() {
4102
+ this._vpEl.addEventListener("mousedown", this._onFoldBtnClick), this._editorEl.addEventListener("mousedown", (e) => {
4103
+ if (e.button !== 0) return;
4104
+ e.preventDefault(), this._focusInput(), this._acHide(), this._snippetSession = null, this._emmetTip.style.display = "none", e.altKey || (xe(this._mc), this._extraCursors = []);
4105
+ const t = this._posFromMouse(e);
4106
+ if (this._tab.cur = { ...t }, e.detail === 3)
4107
+ this._tab.sel = { ar: t.row, ac: 0, fr: t.row, fc: (this._tab.doc[t.row] ?? "").length }, this._tab.cur.col = this._tab.sel.fc;
4108
+ else if (e.detail === 2 && this._config.wordSelection) {
4109
+ const i = this._tab.doc[t.row] ?? "", n = le(i, t.col, this._isWordChar.bind(this)), r = ce(i, t.col, this._isWordChar.bind(this));
4110
+ n !== r ? (this._tab.sel = { ar: t.row, ac: n, fr: t.row, fc: r }, this._tab.cur.col = r) : this._tab.sel = null;
4111
+ } else {
4112
+ if (e.altKey && this._config.multiCursor) {
4113
+ ke(this._mc, t.row, t.col, null), this._extraCursors = [...this._mc.cursors], this._render();
4114
+ return;
4115
+ }
4116
+ this._tab.sel = null, this._isDragging = !0, this._dragAnchor = { ...t };
4117
+ }
4118
+ S(this._tab), this._render();
4119
+ }), this._editorEl.addEventListener("mousemove", (e) => {
4120
+ if (this._config.hover && !this._hoverPinned && !this._isDragging && this._scheduleHover(e), !this._isDragging || !this._dragAnchor) return;
4121
+ const t = this._posFromMouse(e);
4122
+ this._tab.cur = { ...t }, t.row !== this._dragAnchor.row || t.col !== this._dragAnchor.col ? this._tab.sel = { ar: this._dragAnchor.row, ac: this._dragAnchor.col, fr: t.row, fc: t.col } : this._tab.sel = null, S(this._tab), this._render();
4123
+ }), this._editorEl.addEventListener("mouseleave", () => {
4124
+ this._hoverPinned || this._hideHover();
4125
+ }), window.addEventListener("mouseup", this._onWinMouseUp), this._editorEl.addEventListener("scroll", this._onEditorScroll, { passive: !0 }), window.addEventListener("resize", this._onWinResize), this._inputEl.addEventListener("keydown", (e) => this._onKeyDown(e)), this._inputEl.addEventListener("input", (e) => this._onInput(e)), this._inputEl.addEventListener("paste", (e) => {
4126
+ var i;
4127
+ if (e.preventDefault(), this._config.readOnly) return;
4128
+ const t = (i = e.clipboardData ?? window.clipboardData) == null ? void 0 : i.getData("text/plain");
4129
+ t && (this._insertStr(t, !1), this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render());
4130
+ }), this._editorEl.addEventListener("mousedown", () => setTimeout(() => this._focusInput(), 0)), this._inputEl.addEventListener("focus", () => {
4131
+ var e, t;
4132
+ return (t = (e = this._config).onFocus) == null ? void 0 : t.call(e);
4133
+ }), this._inputEl.addEventListener("blur", () => {
4134
+ var e, t;
4135
+ return (t = (e = this._config).onBlur) == null ? void 0 : t.call(e);
4136
+ });
4137
+ }
4138
+ _onKeyDown(e) {
4139
+ var o, l, a, c, d, h, p, f, _;
4140
+ const t = e.ctrlKey || e.metaKey, i = e.shiftKey, n = e.altKey, r = this._config.readOnly;
4141
+ if (this._hideHover(), this._acVisible()) {
4142
+ if (e.key === "ArrowDown") {
4143
+ e.preventDefault(), this._acSel = Math.min(this._acItems.length - 1, this._acSel + 1), this._renderAcPopup();
4144
+ return;
4145
+ }
4146
+ if (e.key === "ArrowUp") {
4147
+ e.preventDefault(), this._acSel = Math.max(0, this._acSel - 1), this._renderAcPopup();
4148
+ return;
4149
+ }
4150
+ if (e.key === "Tab" || e.key === "Enter") {
4151
+ e.preventDefault(), this._acAccept();
4152
+ return;
4153
+ }
4154
+ if (e.key === "Escape") {
4155
+ this._acHide();
4156
+ return;
4157
+ }
4158
+ }
4159
+ if (n && (e.key === "z" || e.key === "Z" || e.key === "Ω")) {
4160
+ e.preventDefault(), this._toggleWrap();
4161
+ return;
4162
+ }
4163
+ if (t && e.key === "z" && !i) {
4164
+ e.preventDefault(), r || this.undo();
4165
+ return;
4166
+ }
4167
+ if (t && (e.key === "y" || i && e.key === "z")) {
4168
+ e.preventDefault(), r || this.redo();
4169
+ return;
4170
+ }
4171
+ if (t && e.key === "a") {
4172
+ e.preventDefault(), this._selectAll();
4173
+ return;
4174
+ }
4175
+ if (t && e.key === "c") {
4176
+ e.preventDefault(), this._doCopy();
4177
+ return;
4178
+ }
4179
+ if (t && e.key === "x") {
4180
+ e.preventDefault(), r || this._doCut();
4181
+ return;
4182
+ }
4183
+ if (t && e.key === "f") {
4184
+ e.preventDefault(), this._config.find && this._openFind(!1);
4185
+ return;
4186
+ }
4187
+ if (t && e.key === "h") {
4188
+ e.preventDefault(), this._config.find && this._config.findReplace && this._openFind(!0);
4189
+ return;
4190
+ }
4191
+ if (t && e.key === "g") {
4192
+ e.preventDefault(), this._config.goToLine && this._openGoToLine();
4193
+ return;
4194
+ }
4195
+ if (t && e.key === "d") {
4196
+ e.preventDefault(), !r && this._config.multiCursor && this._ctrlD();
4197
+ return;
4198
+ }
4199
+ if (t && i && e.key === "d") {
4200
+ e.preventDefault(), r || this._duplicateLine();
4201
+ return;
4202
+ }
4203
+ if (t && e.key === "/") {
4204
+ e.preventDefault(), r || this._toggleComment();
4205
+ return;
4206
+ }
4207
+ if (t && e.key === "k") {
4208
+ e.preventDefault(), r || this._deleteLine();
4209
+ return;
4210
+ }
4211
+ if (e.key === "Escape") {
4212
+ this._tab.sel = null, this._acHide(), this._closeFind(), this._closeGoToLine(), this._emmetTip.style.display = "none", this._snippetTip.style.display = "none", this._snippetExpanded = null, this._snippetSession = null, xe(this._mc), this._extraCursors = [], this._mc.searchWord = "", this._render();
4213
+ return;
4214
+ }
4215
+ if (r) {
4216
+ this._handleArrowKeys(e, t, i);
4217
+ return;
4218
+ }
4219
+ if (e.key === "Tab") {
4220
+ if (e.preventDefault(), this._snippetSession) {
4221
+ if (i) {
4222
+ if (this._snippetSession.idx > 0) {
4223
+ this._snippetSession.idx--;
4224
+ const b = this._snippetSession.stops[this._snippetSession.idx];
4225
+ this._tab.cur.row = b.row, this._tab.cur.col = b.col, this._tab.sel = null, S(this._tab), this._scrollIntoView(), this._render();
4226
+ }
4227
+ } else if (this._snippetSession.idx++, this._snippetSession.idx >= this._snippetSession.stops.length)
4228
+ this._snippetSession = null;
4229
+ else {
4230
+ const b = this._snippetSession.stops[this._snippetSession.idx];
4231
+ this._tab.cur.row = b.row, this._tab.cur.col = b.col, this._tab.sel = null, S(this._tab), this._scrollIntoView(), this._render();
4232
+ }
4233
+ return;
4234
+ }
4235
+ if (!i && this._emmetAccept() || !i && this._snippetAccept()) return;
4236
+ i ? this._unindentSel() : this._indentSel(), S(this._tab), this._scrollIntoView(), this._rebuildWrapMap(), this._render();
4237
+ return;
4238
+ }
4239
+ if (e.key === "Backspace") {
4240
+ if (e.preventDefault(), this._extraCursors.length) {
4241
+ this._snippetSession = null;
4242
+ const b = yt(
4243
+ this._tab.doc,
4244
+ this._tab.cur.row,
4245
+ this._tab.cur.col,
4246
+ this._extraCursors
4247
+ );
4248
+ this._tab.doc = b.doc, this._tab.cur.row = b.primaryRow, this._tab.cur.col = b.primaryCol, this._extraCursors = b.extraCursors, this._mc.cursors = b.extraCursors;
4249
+ } else {
4250
+ if (this._snippetSession) {
4251
+ const b = this._snippetSession.stops[this._snippetSession.idx];
4252
+ if (this._tab.cur.row === b.row && this._tab.cur.col > b.col) {
4253
+ for (let v = this._snippetSession.idx + 1; v < this._snippetSession.stops.length; v++) {
4254
+ const u = this._snippetSession.stops[v];
4255
+ u.row === b.row && u.col >= this._tab.cur.col && u.col--;
4256
+ }
4257
+ b.col--;
4258
+ } else
4259
+ this._snippetSession = null;
4260
+ }
4261
+ this._doBackspace();
4262
+ }
4263
+ this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), this._acTrigger(), this._emmetCheck(), this._snippetCheck(), (l = (o = this._config).onChange) == null || l.call(o, A(this._tab.doc));
4264
+ return;
4265
+ }
4266
+ if (e.key === "Delete") {
4267
+ e.preventDefault(), this._snippetSession = null, this._doDelete(), this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (c = (a = this._config).onChange) == null || c.call(a, A(this._tab.doc));
4268
+ return;
4269
+ }
4270
+ if (e.key === "Enter") {
4271
+ e.preventDefault(), this._snippetSession = null, this._doEnter(), this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (h = (d = this._config).onChange) == null || h.call(d, A(this._tab.doc));
4272
+ return;
4273
+ }
4274
+ if (!t && !n && this._config.autoClosePairs[e.key]) {
4275
+ e.preventDefault(), L(this._tab, this._config.maxUndoHistory), this._tab.sel && (this._tab.cur = G(this._tab));
4276
+ const { doc: b, cur: v } = this._tab, u = b[v.row] ?? "";
4277
+ b[v.row] = u.slice(0, v.col) + e.key + this._config.autoClosePairs[e.key] + u.slice(v.col), v.col++, this._tokenCache.invalidateLine(v.row, ((p = this._wm.segments[v.row]) == null ? void 0 : p.length) ?? 1), this._tab.dirty = !0, this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (_ = (f = this._config).onChange) == null || _.call(f, A(this._tab.doc));
4278
+ return;
4279
+ }
4280
+ if (!t && !n && Object.values(this._config.autoClosePairs).includes(e.key)) {
4281
+ const { doc: b, cur: v } = this._tab;
4282
+ if ((b[v.row] ?? "")[v.col] === e.key) {
4283
+ e.preventDefault(), v.col++, S(this._tab), this._scrollIntoView(), this._render();
4284
+ return;
4285
+ }
4286
+ }
4287
+ if (i && n && !t && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
4288
+ e.preventDefault(), this._duplicateLines(e.key === "ArrowDown");
4289
+ return;
4290
+ }
4291
+ if (n && !t && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
4292
+ e.preventDefault(), this._moveLines(e.key === "ArrowUp");
4293
+ return;
4294
+ }
4295
+ this._handleArrowKeys(e, t, i);
4296
+ }
4297
+ _handleArrowKeys(e, t, i) {
4298
+ var f, _, b, v, u, T;
4299
+ const { doc: n, cur: r } = this._tab, o = this._config.lineHeight, l = e.metaKey, a = e.ctrlKey, c = e.altKey, d = (m, w) => {
4300
+ if (i) {
4301
+ this._tab.sel || (this._tab.sel = { ar: r.row, ac: r.col, fr: r.row, fc: r.col }), r.row = m, r.col = w;
4302
+ const y = this._tab.sel;
4303
+ y.fr = m, y.fc = w, y.ar === y.fr && y.ac === y.fc && (this._tab.sel = null);
4304
+ } else
4305
+ this._tab.sel = null, r.row = m, r.col = w;
4306
+ }, h = (m) => {
4307
+ const y = (n[m] ?? "").search(/\S/);
4308
+ return y === -1 || r.col === y ? 0 : y;
4309
+ }, p = () => ({ row: n.length - 1, col: (n[n.length - 1] ?? "").length });
4310
+ switch (e.key) {
4311
+ case "ArrowRight":
4312
+ if (e.preventDefault(), this._tab.sel && !i) {
4313
+ const m = $(this._tab.sel);
4314
+ r.row = m.fr, r.col = m.fc, this._tab.sel = null;
4315
+ break;
4316
+ }
4317
+ if (l)
4318
+ d(r.row, (n[r.row] ?? "").length);
4319
+ else if (a || c) {
4320
+ const m = n[r.row] ?? "";
4321
+ if (r.col >= m.length)
4322
+ r.row < n.length - 1 && d(r.row + 1, 0);
4323
+ else {
4324
+ const w = this._wordSkipRight(m, r.col);
4325
+ d(r.row, w);
4326
+ }
4327
+ } else r.col < (n[r.row] ?? "").length ? d(r.row, r.col + 1) : r.row < n.length - 1 && d(r.row + 1, 0);
4328
+ break;
4329
+ case "ArrowLeft":
4330
+ if (e.preventDefault(), this._tab.sel && !i) {
4331
+ const m = $(this._tab.sel);
4332
+ r.row = m.ar, r.col = m.ac, this._tab.sel = null;
4333
+ break;
4334
+ }
4335
+ if (l)
4336
+ d(r.row, h(r.row));
4337
+ else if (a || c)
4338
+ if (r.col === 0)
4339
+ r.row > 0 && d(r.row - 1, (n[r.row - 1] ?? "").length);
4340
+ else {
4341
+ const m = this._wordSkipLeft(n[r.row] ?? "", r.col);
4342
+ d(r.row, m);
4343
+ }
4344
+ else r.col > 0 ? d(r.row, r.col - 1) : r.row > 0 && d(r.row - 1, (n[r.row - 1] ?? "").length);
4345
+ break;
4346
+ case "ArrowDown":
4347
+ if (e.preventDefault(), l) {
4348
+ const m = p();
4349
+ d(m.row, m.col);
4350
+ } else if (this._config.wordWrap) {
4351
+ const m = F(this._wm, r.row, r.col), w = Math.min(this._wm.visualRows.length - 1, m.visRow + 1), y = Y(this._wm, w, Math.min(m.colInSeg, (((f = this._wm.visualRows[w]) == null ? void 0 : f.text) ?? "").length));
4352
+ d(y.row, y.col);
4353
+ } else {
4354
+ const m = Math.min(n.length - 1, r.row + 1);
4355
+ d(m, Math.min(r.col, (n[m] ?? "").length));
4356
+ }
4357
+ break;
4358
+ case "ArrowUp":
4359
+ if (e.preventDefault(), l)
4360
+ d(0, 0);
4361
+ else if (this._config.wordWrap) {
4362
+ const m = F(this._wm, r.row, r.col), w = Math.max(0, m.visRow - 1), y = Y(this._wm, w, Math.min(m.colInSeg, (((_ = this._wm.visualRows[w]) == null ? void 0 : _.text) ?? "").length));
4363
+ d(y.row, y.col);
4364
+ } else {
4365
+ const m = Math.max(0, r.row - 1);
4366
+ d(m, Math.min(r.col, (n[m] ?? "").length));
4367
+ }
4368
+ break;
4369
+ case "Home":
4370
+ e.preventDefault(), a ? d(0, 0) : d(r.row, h(r.row));
4371
+ break;
4372
+ case "End":
4373
+ if (e.preventDefault(), a) {
4374
+ const m = p();
4375
+ d(m.row, m.col);
4376
+ } else
4377
+ d(r.row, (n[r.row] ?? "").length);
4378
+ break;
4379
+ case "PageDown":
4380
+ e.preventDefault();
4381
+ {
4382
+ const m = Math.max(1, Math.floor(this._editorEl.clientHeight / o) - 1), w = Math.min(n.length - 1, r.row + m);
4383
+ d(w, Math.min(r.col, (n[w] ?? "").length)), this._editorEl.scrollTop += this._editorEl.clientHeight - o;
4384
+ break;
4385
+ }
4386
+ case "PageUp":
4387
+ e.preventDefault();
4388
+ {
4389
+ const m = Math.max(1, Math.floor(this._editorEl.clientHeight / o) - 1), w = Math.max(0, r.row - m);
4390
+ d(w, Math.min(r.col, (n[w] ?? "").length)), this._editorEl.scrollTop -= this._editorEl.clientHeight - o;
4391
+ break;
4392
+ }
4393
+ default:
4394
+ return;
4395
+ }
4396
+ S(this._tab), this._scrollIntoView(), this._acHide(), (v = (b = this._config).onCursorChange) == null || v.call(b, { ...this._tab.cur }), (T = (u = this._config).onSelectionChange) == null || T.call(u, this._tab.sel ? { ...this._tab.sel } : null), this._render();
4397
+ }
4398
+ _isWordChar(e) {
4399
+ const t = this._config.wordSeparators;
4400
+ return t ? e.trim() !== "" && !t.includes(e) : /[\w$]/.test(e);
4401
+ }
4402
+ _wordSkipRight(e, t) {
4403
+ let i = t;
4404
+ const n = e.length;
4405
+ for (; i < n && /\s/.test(e[i]); ) i++;
4406
+ if (i >= n) return i;
4407
+ if (/\w/.test(e[i]))
4408
+ for (; i < n && /\w/.test(e[i]); ) i++;
4409
+ else
4410
+ for (; i < n && /[^\w\s]/.test(e[i]); ) i++;
4411
+ return i;
4412
+ }
4413
+ _wordSkipLeft(e, t) {
4414
+ let i = t;
4415
+ for (; i > 0 && /\s/.test(e[i - 1]); ) i--;
4416
+ if (i <= 0) return i;
4417
+ if (/\w/.test(e[i - 1]))
4418
+ for (; i > 0 && /\w/.test(e[i - 1]); ) i--;
4419
+ else
4420
+ for (; i > 0 && /[^\w\s]/.test(e[i - 1]); ) i--;
4421
+ return i;
4422
+ }
4423
+ // ── Move lines ────────────────────────────────────────────
4424
+ _duplicateLines(e) {
4425
+ var a, c, d, h;
4426
+ const { doc: t, cur: i } = this._tab, n = this._tab.sel;
4427
+ let r = i.row, o = i.row;
4428
+ if (n) {
4429
+ const p = $(n);
4430
+ r = p.ar, o = p.fr, p.fc === 0 && p.fr > p.ar && o--;
4431
+ }
4432
+ L(this._tab, this._config.maxUndoHistory);
4433
+ const l = t.slice(r, o + 1);
4434
+ e ? (t.splice(o + 1, 0, ...l), i.row += l.length, n && (n.ar += l.length, n.fr += l.length)) : t.splice(r, 0, ...l), this._tab.dirty = !0, this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (c = (a = this._config).onChange) == null || c.call(a, A(this._tab.doc)), (h = (d = this._config).onCursorChange) == null || h.call(d, { ...this._tab.cur });
4435
+ }
4436
+ _moveLines(e) {
4437
+ var l, a, c, d;
4438
+ const { doc: t, cur: i } = this._tab, n = this._tab.sel;
4439
+ let r = i.row, o = i.row;
4440
+ if (n) {
4441
+ const h = $(n);
4442
+ r = h.ar, o = h.fr, h.fc === 0 && h.fr > h.ar && o--;
4443
+ }
4444
+ if (e) {
4445
+ if (r === 0) return;
4446
+ L(this._tab, this._config.maxUndoHistory);
4447
+ const h = t.splice(r, o - r + 1);
4448
+ t.splice(r - 1, 0, ...h), i.row--, n && (n.ar--, n.fr--);
4449
+ } else {
4450
+ if (o >= t.length - 1) return;
4451
+ L(this._tab, this._config.maxUndoHistory);
4452
+ const h = t.splice(r, o - r + 1);
4453
+ t.splice(r + 1, 0, ...h), i.row++, n && (n.ar++, n.fr++);
4454
+ }
4455
+ this._tab.dirty = !0, this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (a = (l = this._config).onChange) == null || a.call(l, A(this._tab.doc)), (d = (c = this._config).onCursorChange) == null || d.call(c, { ...this._tab.cur });
4456
+ }
4457
+ // ── Hover documentation ────────────────────────────────────
4458
+ _scheduleHover(e) {
4459
+ this._hoverTip.style.display !== "none" && (this._hoverTip.style.display = "none"), this._hoverTimer !== null && (clearTimeout(this._hoverTimer), this._hoverTimer = null);
4460
+ const { clientX: t, clientY: i } = e;
4461
+ this._hoverTimer = setTimeout(() => {
4462
+ this._hoverTimer = null, this._doHover(t, i);
4463
+ }, 500);
4464
+ }
4465
+ _doHover(e, t) {
4466
+ var _, b, v;
4467
+ if (!this._config.hover) return;
4468
+ const i = this._editorEl.getBoundingClientRect(), n = t - i.top + this._editorEl.scrollTop, r = this._config.showGutter ? this._config.gutterWidth : 0, o = e - i.left - r - 14, l = this._config.lineHeight, a = Math.max(0, Math.min(this._wm.visualRows.length - 1, Math.floor(n / l))), c = Math.max(0, Math.min(
4469
+ (((_ = this._wm.visualRows[a]) == null ? void 0 : _.text) ?? "").length,
4470
+ Math.round(o / 7.82)
4471
+ )), d = Y(this._wm, a, c), h = this._tab.doc[d.row] ?? "", p = At(h, d.col);
4472
+ if (!p) return;
4473
+ let f = Ht(p, this._config.language);
4474
+ if (!f) {
4475
+ const u = this._config.completions.find((T) => T.label === p);
4476
+ u && (u.description || u.detail) && (f = {
4477
+ title: u.label,
4478
+ type: u.detail,
4479
+ body: u.description ?? ""
4480
+ });
4481
+ }
4482
+ if (!f) {
4483
+ const u = (v = (b = this._config).provideHover) == null ? void 0 : v.call(b, {
4484
+ word: p,
4485
+ row: d.row,
4486
+ col: d.col,
4487
+ line: h,
4488
+ language: this._config.language,
4489
+ doc: this._tab.doc
4490
+ });
4491
+ u && (f = u);
4492
+ }
4493
+ f && this._showHoverTip(f, e, t);
4494
+ }
4495
+ _showHoverTip(e, t, i) {
4496
+ const n = this._hoverTip;
4497
+ let r = '<div class="sl-ht-sig">';
4498
+ r += `<span class="sl-ht-title">${V(e.title)}</span>`, e.type && (r += `<code class="sl-ht-type">${V(e.type)}</code>`), r += "</div>", e.title && e.body && (r += '<div class="sl-ht-divider"></div>'), e.body && (r += `<div class="sl-ht-body">${V(e.body)}</div>`), n.innerHTML = r, n.style.display = "block";
4499
+ const o = 12, l = 18, a = n.offsetWidth || 300, c = n.offsetHeight || 80;
4500
+ let d = t, h = i + l;
4501
+ h + c > window.innerHeight - o && (h = i - c - 8), d + a > window.innerWidth - o && (d = window.innerWidth - a - o), d < o && (d = o), n.style.left = `${d}px`, n.style.top = `${Math.max(o, h)}px`;
4502
+ }
4503
+ _hideHover() {
4504
+ this._hoverTimer !== null && (clearTimeout(this._hoverTimer), this._hoverTimer = null), this._hoverPinned = !1, this._hoverTip.style.display = "none";
4505
+ }
4506
+ _onInput(e) {
4507
+ var r, o, l, a;
4508
+ if (this._config.readOnly) {
4509
+ e.target.value = "";
4510
+ return;
4511
+ }
4512
+ const t = e.target, i = t.value;
4513
+ if (t.value = "", !i || i === "Ω") return;
4514
+ const n = i.replace(/[\x00-\x08\x0a-\x1f\x7f]/g, "");
4515
+ if (n) {
4516
+ if (this._extraCursors.length) {
4517
+ this._snippetSession = null;
4518
+ const c = _t(
4519
+ this._tab.doc,
4520
+ this._tab.cur.row,
4521
+ this._tab.cur.col,
4522
+ this._extraCursors,
4523
+ n
4524
+ );
4525
+ this._tab.doc = c.doc, this._tab.cur.row = c.primaryRow, this._tab.cur.col = c.primaryCol, this._extraCursors = c.extraCursors, this._mc.cursors = c.extraCursors, this._tab.dirty = !0, (o = (r = this._config).onChange) == null || o.call(r, A(this._tab.doc));
4526
+ } else {
4527
+ const c = this._tab.cur.row, d = this._tab.cur.col;
4528
+ if (this._insertStr(n, !0), this._snippetSession) {
4529
+ const h = this._snippetSession, p = h.stops[h.idx];
4530
+ if (this._tab.cur.row === p.row) {
4531
+ const f = this._tab.cur.col - d;
4532
+ for (let _ = h.idx + 1; _ < h.stops.length; _++) {
4533
+ const b = h.stops[_];
4534
+ b.row === c && b.col >= d && (b.col += f);
4535
+ }
4536
+ p.col = this._tab.cur.col;
4537
+ } else
4538
+ this._snippetSession = null;
4539
+ }
4540
+ }
4541
+ this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), this._acTrigger(), this._emmetCheck(), this._snippetCheck(), (a = (l = this._config).onCursorChange) == null || a.call(l, { ...this._tab.cur });
4542
+ }
4543
+ }
4544
+ _ctrlD() {
4545
+ if (!this._config.multiCursor) return;
4546
+ const e = vt(
4547
+ this._mc,
4548
+ this._tab.doc,
4549
+ this._tab.cur.row,
4550
+ this._tab.cur.col,
4551
+ this._tab.sel
4552
+ );
4553
+ e && (!this._mc.cursors.length || e.word !== this._mc.searchWord ? (this._tab.sel = e.sel, this._tab.cur.col = e.col) : (ke(this._mc, e.row, e.col, e.sel), this._extraCursors = [...this._mc.cursors]), this._mc.searchWord = e.word, this._mc.lastMatchRow = e.row, this._mc.lastMatchCol = e.col, this._scrollIntoView(), this._render());
4554
+ }
4555
+ // ── Find event binding ────────────────────────────────────
4556
+ _bindFindEvents() {
4557
+ var e, t, i, n, r, o, l;
4558
+ this._findInput.addEventListener("input", () => {
4559
+ this._runFind(this._findInput.value), this._findIdx = -1, this._findMatches.length ? this._navFind(1) : (this._findCount.textContent = "0/0", this._render());
4560
+ }), this._findInput.addEventListener("keydown", (a) => {
4561
+ a.key === "Enter" ? a.shiftKey ? this._navFind(-1) : this._navFind(1) : a.key === "Escape" && this._closeFind(), a.stopPropagation();
4562
+ }), this._replaceInput.addEventListener("keydown", (a) => {
4563
+ a.key === "Enter" ? this._doReplaceOne() : a.key === "Escape" && this._closeFind(), a.stopPropagation();
4564
+ }), (e = this._findBar.querySelector(".sl-find-prev")) == null || e.addEventListener("click", () => this._navFind(-1)), (t = this._findBar.querySelector(".sl-find-next")) == null || t.addEventListener("click", () => this._navFind(1)), (i = this._findBar.querySelector(".sl-find-close")) == null || i.addEventListener("click", () => this._closeFind()), (n = this._findBar.querySelector(".sl-find-case")) == null || n.addEventListener("click", (a) => {
4565
+ this._findCaseSensitive = !this._findCaseSensitive, a.target.classList.toggle("sl-active", this._findCaseSensitive), this._runFind(this._findInput.value), this._findIdx = -1, this._findMatches.length ? this._navFind(1) : (this._findCount.textContent = "0/0", this._render());
4566
+ }), (r = this._findBar.querySelector(".sl-find-regex")) == null || r.addEventListener("click", (a) => {
4567
+ this._findRegex = !this._findRegex, a.target.classList.toggle("sl-active", this._findRegex), this._runFind(this._findInput.value), this._findIdx = -1, this._findMatches.length ? this._navFind(1) : (this._findCount.textContent = "0/0", this._render());
4568
+ }), (o = this._findBar.querySelector(".sl-replace-one")) == null || o.addEventListener("click", () => this._doReplaceOne()), (l = this._findBar.querySelector(".sl-replace-all")) == null || l.addEventListener("click", () => this._doReplaceAll());
4569
+ }
4570
+ _doReplaceOne() {
4571
+ var e, t;
4572
+ this._findIdx < 0 || !this._findMatches.length || (L(this._tab, this._config.maxUndoHistory), this._tab.doc = kt(this._tab.doc, this._findMatches, this._findIdx, this._replaceInput.value), this._tokenCache.clear(), this._tab.dirty = !0, this._runFind(this._findInput.value), this._findMatches.length ? (this._findIdx >= this._findMatches.length && (this._findIdx = 0), this._navFind(0)) : (this._findCount.textContent = "0/0", this._rebuildWrapMap(), this._render()), (t = (e = this._config).onChange) == null || t.call(e, A(this._tab.doc)));
4573
+ }
4574
+ _doReplaceAll() {
4575
+ var t, i;
4576
+ if (!this._findMatches.length) return;
4577
+ const e = this._findMatches.length;
4578
+ L(this._tab, this._config.maxUndoHistory), this._tab.doc = xt(this._tab.doc, this._findMatches, this._replaceInput.value), this._tokenCache.clear(), this._tab.dirty = !0, this._findMatches = [], this._findIdx = -1, this._findCount.textContent = `0/0 (${e} replaced)`, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, A(this._tab.doc));
4579
+ }
4580
+ // ── Minimap events ────────────────────────────────────────
4581
+ _bindMinimapEvents() {
4582
+ const e = this._minimapWrap;
4583
+ e.addEventListener("mousemove", (t) => {
4584
+ if (this._mmDragMode !== "none") return;
4585
+ const i = t.clientY - e.getBoundingClientRect().top, { sliderTop: n, sliderHeight: r } = ie(
4586
+ this._tab.doc.length,
4587
+ this._editorEl.scrollTop,
4588
+ this._editorEl.clientHeight,
4589
+ e.clientHeight,
4590
+ this._config.lineHeight
4591
+ );
4592
+ e.style.cursor = i >= n && i <= n + r ? "grab" : "pointer";
4593
+ }), e.addEventListener("mousedown", (t) => {
4594
+ t.preventDefault();
4595
+ const i = e.clientHeight, n = t.clientY - e.getBoundingClientRect().top, { sliderTop: r, sliderHeight: o } = ie(
4596
+ this._tab.doc.length,
4597
+ this._editorEl.scrollTop,
4598
+ this._editorEl.clientHeight,
4599
+ i,
4600
+ this._config.lineHeight
4601
+ );
4602
+ if (n >= r && n <= r + o)
4603
+ this._mmDragMode = "slider", this._mmSliderOffset = n - r, this._mmDragStartY = t.clientY, this._mmDragStartScroll = this._editorEl.scrollTop, e.style.cursor = "grabbing";
4604
+ else {
4605
+ this._mmDragMode = "jump";
4606
+ const l = Nt(
4607
+ n,
4608
+ this._tab.doc.length,
4609
+ this._editorEl.scrollTop,
4610
+ this._editorEl.clientHeight,
4611
+ i,
4612
+ this._config.lineHeight
4613
+ );
4614
+ this._editorEl.scrollTop = l, this._mmDragStartY = t.clientY, this._mmDragStartScroll = l, this._render();
4615
+ }
4616
+ }), window.addEventListener("mousemove", this._onWinMmMouseMove), window.addEventListener("mouseup", this._onWinMmMouseUp);
4617
+ }
4618
+ }
4619
+ function zt(s, e) {
4620
+ return new Ut(s, e);
4621
+ }
4622
+ export {
4623
+ tt as BUILT_IN_THEMES,
4624
+ Ut as SynclineEditor,
4625
+ Je as THEME_DRACULA,
4626
+ Xe as THEME_GITHUB_LIGHT,
4627
+ Qe as THEME_MDX_DARK,
4628
+ et as THEME_MDX_LIGHT,
4629
+ Ye as THEME_MONOKAI,
4630
+ Ze as THEME_SOLARIZED_LIGHT,
4631
+ Ke as THEME_VR_DARK,
4632
+ Ve as THEME_VSCODE_DARK,
4633
+ zt as createEditor
4634
+ };
4635
+ //# sourceMappingURL=syncline-editor.es.js.map