alien-editor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +249 -0
  2. package/dist/alien-editor.js +2103 -0
  3. package/dist/alien-editor.umd.cjs +2 -0
  4. package/dist/index.d.ts +8 -0
  5. package/dist/nuxt.cjs +1 -0
  6. package/dist/nuxt.js +17 -0
  7. package/dist/src/components/AlienEditor.vue.d.ts +20 -0
  8. package/dist/src/components/blocks/BlockList.vue.d.ts +2 -0
  9. package/dist/src/components/blocks/BlockWrapper.vue.d.ts +21 -0
  10. package/dist/src/components/blocks/ButtonBlock.vue.d.ts +6 -0
  11. package/dist/src/components/blocks/CodeBlock.vue.d.ts +6 -0
  12. package/dist/src/components/blocks/DividerBlock.vue.d.ts +6 -0
  13. package/dist/src/components/blocks/HeadingBlock.vue.d.ts +8 -0
  14. package/dist/src/components/blocks/ImageBlock.vue.d.ts +8 -0
  15. package/dist/src/components/blocks/ListBlock.vue.d.ts +6 -0
  16. package/dist/src/components/blocks/ModuleBlock.vue.d.ts +8 -0
  17. package/dist/src/components/blocks/TextBlock.vue.d.ts +8 -0
  18. package/dist/src/components/blocks/VideoBlock.vue.d.ts +6 -0
  19. package/dist/src/components/modals/ImageUrlModal.vue.d.ts +2 -0
  20. package/dist/src/components/modals/LinkModal.vue.d.ts +2 -0
  21. package/dist/src/components/toolbar/AlienToolbar.vue.d.ts +2 -0
  22. package/dist/src/components/toolbar/ColorPicker.vue.d.ts +2 -0
  23. package/dist/src/components/toolbar/ModeToggle.vue.d.ts +2 -0
  24. package/dist/src/components/toolbar/ModuleDropdown.vue.d.ts +2 -0
  25. package/dist/src/components/toolbar/ToolbarButton.vue.d.ts +26 -0
  26. package/dist/src/composables/useBlocks.d.ts +13 -0
  27. package/dist/src/composables/useDragDrop.d.ts +16 -0
  28. package/dist/src/composables/useEditorState.d.ts +191 -0
  29. package/dist/src/composables/useFormatting.d.ts +14 -0
  30. package/dist/src/composables/useHistory.d.ts +9 -0
  31. package/dist/src/composables/useParser.d.ts +4 -0
  32. package/dist/src/composables/useSelection.d.ts +8 -0
  33. package/dist/src/composables/useSerializer.d.ts +7 -0
  34. package/dist/src/types/index.d.ts +116 -0
  35. package/dist/src/utils/tailwindMap.d.ts +12 -0
  36. package/dist/style.css +1 -0
  37. package/package.json +53 -0
@@ -0,0 +1,2103 @@
1
+ import { ref as k, defineComponent as A, openBlock as g, createElementBlock as b, withModifiers as m, normalizeClass as H, renderSlot as be, inject as E, computed as Q, unref as h, createElementVNode as o, withDirectives as _, vModelText as F, Fragment as N, renderList as V, toDisplayString as z, createCommentVNode as T, createVNode as S, withCtx as D, createTextVNode as re, createStaticVNode as Ie, onMounted as oe, watch as W, createBlock as U, resolveDynamicComponent as ce, nextTick as X, Teleport as me, onUnmounted as Ce, provide as Le } from "vue";
2
+ function Se() {
3
+ const l = k([]), e = k("edit"), t = k(null), n = k(null);
4
+ return { blocks: l, mode: e, activeBlockId: t, savedRange: n };
5
+ }
6
+ const Ae = 100;
7
+ function Te(l) {
8
+ const e = k([]), t = k([]);
9
+ function n() {
10
+ return {
11
+ blocks: JSON.parse(JSON.stringify(l.value)),
12
+ timestamp: Date.now()
13
+ };
14
+ }
15
+ function a() {
16
+ e.value.push(n()), e.value.length > Ae && e.value.shift(), t.value = [];
17
+ }
18
+ function p() {
19
+ e.value.length && (t.value.push(n()), l.value = e.value.pop().blocks);
20
+ }
21
+ function f() {
22
+ t.value.length && (e.value.push(n()), l.value = t.value.pop().blocks);
23
+ }
24
+ function v() {
25
+ return e.value.length > 0;
26
+ }
27
+ function d() {
28
+ return t.value.length > 0;
29
+ }
30
+ return { pushSnapshot: a, undo: p, redo: f, canUndo: v, canRedo: d };
31
+ }
32
+ function ye(l) {
33
+ function e() {
34
+ if (typeof window > "u") return;
35
+ const f = window.getSelection();
36
+ f && f.rangeCount > 0 && (l.value = f.getRangeAt(0).cloneRange());
37
+ }
38
+ function t() {
39
+ if (typeof window > "u" || !l.value) return;
40
+ const f = window.getSelection();
41
+ f && (f.removeAllRanges(), f.addRange(l.value));
42
+ }
43
+ function n() {
44
+ if (typeof window > "u") return null;
45
+ const f = window.getSelection();
46
+ return f && f.rangeCount > 0 ? f.getRangeAt(0) : null;
47
+ }
48
+ function a() {
49
+ if (typeof window > "u") return !0;
50
+ const f = window.getSelection();
51
+ return !f || f.isCollapsed;
52
+ }
53
+ function p() {
54
+ if (typeof window > "u") return null;
55
+ const f = window.getSelection();
56
+ return f && f.rangeCount > 0 ? f.toString() : null;
57
+ }
58
+ return { saveSelection: e, restoreSelection: t, getRange: n, isCollapsed: a, getSelectedText: p };
59
+ }
60
+ let Ee = 0;
61
+ function De() {
62
+ return `ae-${Date.now()}-${++Ee}`;
63
+ }
64
+ function ie(l, e = {}) {
65
+ const t = De();
66
+ switch (l) {
67
+ case "paragraph":
68
+ return { id: t, type: "paragraph", html: "", align: "left", classes: [], ...e };
69
+ case "blockquote":
70
+ return { id: t, type: "blockquote", html: "", align: "left", classes: [], ...e };
71
+ case "heading":
72
+ return { id: t, type: "heading", level: 2, html: "", align: "left", classes: [], ...e };
73
+ case "ordered-list":
74
+ return { id: t, type: "ordered-list", items: [""], ...e };
75
+ case "unordered-list":
76
+ return { id: t, type: "unordered-list", items: [""], ...e };
77
+ case "image":
78
+ return { id: t, type: "image", src: "", alt: "", classes: [], ...e };
79
+ case "video":
80
+ return { id: t, type: "video", src: "", classes: [], ...e };
81
+ case "code":
82
+ return { id: t, type: "code", code: "", language: "plaintext", ...e };
83
+ case "divider":
84
+ return { id: t, type: "divider", classes: [], ...e };
85
+ case "button":
86
+ return { id: t, type: "button", label: "Button", href: "#", classes: ["inline-block", "px-4", "py-2", "bg-blue-600", "text-white", "rounded"], ...e };
87
+ case "module":
88
+ return { id: t, type: "module", html: "", ...e };
89
+ default:
90
+ return { id: t, type: "paragraph", html: "", align: "left", classes: [] };
91
+ }
92
+ }
93
+ function Ue(l, e) {
94
+ function t(v, d, r = {}) {
95
+ e();
96
+ const u = l.value.findIndex((c) => c.id === v), i = ie(d, r);
97
+ return l.value.splice(u + 1, 0, i), i.id;
98
+ }
99
+ function n(v, d, r = {}) {
100
+ e();
101
+ const u = ie(d, r);
102
+ return l.value.splice(v, 0, u), u.id;
103
+ }
104
+ function a(v) {
105
+ const d = l.value.findIndex((r) => r.id === v);
106
+ d !== -1 && (e(), l.value.splice(d, 1));
107
+ }
108
+ function p(v, d) {
109
+ const r = l.value.findIndex((c) => c.id === v), u = l.value.findIndex((c) => c.id === d);
110
+ if (r === -1 || u === -1 || r === u) return;
111
+ e();
112
+ const [i] = l.value.splice(r, 1);
113
+ l.value.splice(u, 0, i);
114
+ }
115
+ function f(v, d) {
116
+ const r = l.value.find((u) => u.id === v);
117
+ r && Object.assign(r, d);
118
+ }
119
+ return { addBlockAfter: t, addBlockAt: n, removeBlock: a, moveBlock: p, updateBlock: f, createDefaultBlock: ie };
120
+ }
121
+ function He(l, e) {
122
+ const t = k({ draggedId: null, overId: null });
123
+ function n(d, r) {
124
+ t.value.draggedId = d, r.dataTransfer && (r.dataTransfer.effectAllowed = "move", r.dataTransfer.setData("text/plain", d));
125
+ }
126
+ function a(d, r) {
127
+ r.preventDefault(), r.dataTransfer && (r.dataTransfer.dropEffect = "move"), t.value.draggedId && t.value.draggedId !== d && (t.value.overId = d);
128
+ }
129
+ function p() {
130
+ t.value.overId = null;
131
+ }
132
+ function f(d) {
133
+ const { draggedId: r } = t.value;
134
+ r && r !== d && e(r, d), t.value = { draggedId: null, overId: null };
135
+ }
136
+ function v() {
137
+ t.value = { draggedId: null, overId: null };
138
+ }
139
+ return { dragState: t, onDragStart: n, onDragOver: a, onDragLeave: p, onDrop: f, onDragEnd: v };
140
+ }
141
+ function ue(l) {
142
+ return l === "left" ? "" : `text-${l}`;
143
+ }
144
+ function Z(l) {
145
+ const e = l.filter(Boolean);
146
+ return e.length ? ` class="${e.join(" ")}"` : "";
147
+ }
148
+ function ve(l) {
149
+ switch (l.type) {
150
+ case "paragraph": {
151
+ const e = l, t = [ue(e.align), ...e.classes].filter(Boolean);
152
+ return `<p${Z(t)}>${e.html || ""}</p>`;
153
+ }
154
+ case "blockquote": {
155
+ const e = l, t = ["border-l-4", "border-gray-300", "pl-4", "italic", ue(e.align), ...e.classes].filter(Boolean);
156
+ return `<blockquote${Z(t)}>${e.html || ""}</blockquote>`;
157
+ }
158
+ case "heading": {
159
+ const e = l, t = [ue(e.align), ...e.classes].filter(Boolean);
160
+ return `<h${e.level}${Z(t)}>${e.html || ""}</h${e.level}>`;
161
+ }
162
+ case "ordered-list":
163
+ return `<ol class="list-decimal list-inside">${l.items.map((n) => `<li>${n}</li>`).join("")}</ol>`;
164
+ case "unordered-list":
165
+ return `<ul class="list-disc list-inside">${l.items.map((n) => `<li>${n}</li>`).join("")}</ul>`;
166
+ case "image": {
167
+ const e = l, t = e.classes.filter(Boolean);
168
+ return e.src ? `<img src="${te(e.src)}" alt="${te(e.alt)}"${Z(t)} />` : "";
169
+ }
170
+ case "video": {
171
+ const e = l;
172
+ return e.src ? `<video src="${te(e.src)}" controls class="w-full"></video>` : "";
173
+ }
174
+ case "code": {
175
+ const e = l, t = e.code.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
176
+ return `<pre class="bg-gray-900 text-gray-100 p-4 rounded overflow-x-auto"><code class="language-${te(e.language)}">${t}</code></pre>`;
177
+ }
178
+ case "divider": {
179
+ const t = ["border-t", "border-gray-300", "my-4", ...l.classes].filter(Boolean);
180
+ return `<hr${Z(t)} />`;
181
+ }
182
+ case "button": {
183
+ const e = l, t = e.classes.filter(Boolean);
184
+ return `<a href="${te(e.href)}"${Z(t)}>${e.label || "Button"}</a>`;
185
+ }
186
+ case "module":
187
+ return l.html || "";
188
+ default:
189
+ return "";
190
+ }
191
+ }
192
+ function te(l) {
193
+ return l.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
194
+ }
195
+ function Re() {
196
+ function l(e) {
197
+ return e.map((t) => ve(t)).filter(Boolean).join(`
198
+ `);
199
+ }
200
+ return { serialize: l, serializeBlock: ve };
201
+ }
202
+ let je = 0;
203
+ function R() {
204
+ return `ae-p-${Date.now()}-${++je}`;
205
+ }
206
+ function de(l) {
207
+ return l.classList.contains("text-center") ? "center" : l.classList.contains("text-right") ? "right" : l.classList.contains("text-justify") ? "justify" : "left";
208
+ }
209
+ function G(l, e = []) {
210
+ const t = ["text-left", "text-center", "text-right", "text-justify"];
211
+ return Array.from(l.classList).filter((n) => ![...t, ...e].includes(n));
212
+ }
213
+ function ze() {
214
+ function l(e) {
215
+ var f, v, d;
216
+ if (!e || !e.trim())
217
+ return [];
218
+ if (typeof window > "u" || typeof DOMParser > "u")
219
+ return [{ id: R(), type: "paragraph", html: e, align: "left", classes: [] }];
220
+ const n = new DOMParser().parseFromString(`<body>${e}</body>`, "text/html"), a = Array.from(n.body.childNodes), p = [];
221
+ for (const r of a) {
222
+ if (r.nodeType === Node.TEXT_NODE) {
223
+ const c = (f = r.textContent) == null ? void 0 : f.trim();
224
+ c && p.push({ id: R(), type: "paragraph", html: c, align: "left", classes: [] });
225
+ continue;
226
+ }
227
+ const u = r, i = (v = u.tagName) == null ? void 0 : v.toLowerCase();
228
+ switch (!0) {
229
+ case i === "p": {
230
+ p.push({
231
+ id: R(),
232
+ type: "paragraph",
233
+ html: u.innerHTML,
234
+ align: de(u),
235
+ classes: G(u)
236
+ });
237
+ break;
238
+ }
239
+ case /^h[1-6]$/.test(i): {
240
+ const c = parseInt(i[1]);
241
+ p.push({
242
+ id: R(),
243
+ type: "heading",
244
+ level: c,
245
+ html: u.innerHTML,
246
+ align: de(u),
247
+ classes: G(u)
248
+ });
249
+ break;
250
+ }
251
+ case i === "blockquote": {
252
+ p.push({
253
+ id: R(),
254
+ type: "blockquote",
255
+ html: u.innerHTML,
256
+ align: de(u),
257
+ classes: G(u, ["border-l-4", "border-gray-300", "pl-4", "italic"])
258
+ });
259
+ break;
260
+ }
261
+ case i === "ul": {
262
+ const c = Array.from(u.querySelectorAll(":scope > li")).map((x) => x.innerHTML);
263
+ p.push({
264
+ id: R(),
265
+ type: "unordered-list",
266
+ items: c.length ? c : [""]
267
+ });
268
+ break;
269
+ }
270
+ case i === "ol": {
271
+ const c = Array.from(u.querySelectorAll(":scope > li")).map((x) => x.innerHTML);
272
+ p.push({
273
+ id: R(),
274
+ type: "ordered-list",
275
+ items: c.length ? c : [""]
276
+ });
277
+ break;
278
+ }
279
+ case i === "img": {
280
+ p.push({
281
+ id: R(),
282
+ type: "image",
283
+ src: u.getAttribute("src") || "",
284
+ alt: u.getAttribute("alt") || "",
285
+ classes: G(u)
286
+ });
287
+ break;
288
+ }
289
+ case i === "video": {
290
+ p.push({
291
+ id: R(),
292
+ type: "video",
293
+ src: u.getAttribute("src") || "",
294
+ classes: G(u, ["w-full"])
295
+ });
296
+ break;
297
+ }
298
+ case i === "pre": {
299
+ const c = u.querySelector("code"), x = (c == null ? void 0 : c.className.replace("language-", "")) || "plaintext", $ = document.createElement("div");
300
+ $.innerHTML = (c == null ? void 0 : c.innerHTML) || "", p.push({
301
+ id: R(),
302
+ type: "code",
303
+ code: $.textContent || "",
304
+ language: x
305
+ });
306
+ break;
307
+ }
308
+ case i === "hr": {
309
+ p.push({
310
+ id: R(),
311
+ type: "divider",
312
+ classes: G(u, ["border-t", "border-gray-300", "my-4"])
313
+ });
314
+ break;
315
+ }
316
+ case (i === "a" && ((d = u.dataset) == null ? void 0 : d.alienBlock) === "button"): {
317
+ p.push({
318
+ id: R(),
319
+ type: "button",
320
+ label: u.textContent || "Button",
321
+ href: u.getAttribute("href") || "#",
322
+ classes: Array.from(u.classList)
323
+ });
324
+ break;
325
+ }
326
+ default:
327
+ p.push({
328
+ id: R(),
329
+ type: "module",
330
+ html: u.outerHTML
331
+ });
332
+ }
333
+ }
334
+ return p;
335
+ }
336
+ return { parse: l };
337
+ }
338
+ const J = {
339
+ bold: "font-bold",
340
+ italic: "italic",
341
+ underline: "underline",
342
+ strikethrough: "line-through",
343
+ fontSizes: {
344
+ xs: "text-xs",
345
+ sm: "text-sm",
346
+ base: "text-base",
347
+ lg: "text-lg",
348
+ xl: "text-xl",
349
+ "2xl": "text-2xl",
350
+ "3xl": "text-3xl",
351
+ "4xl": "text-4xl",
352
+ "5xl": "text-5xl"
353
+ },
354
+ fontWeights: {
355
+ thin: "font-thin",
356
+ light: "font-light",
357
+ normal: "font-normal",
358
+ medium: "font-medium",
359
+ semibold: "font-semibold",
360
+ bold: "font-bold",
361
+ extrabold: "font-extrabold",
362
+ black: "font-black"
363
+ },
364
+ headingDefaults: {
365
+ 1: "text-5xl font-bold",
366
+ 2: "text-4xl font-bold",
367
+ 3: "text-3xl font-semibold",
368
+ 4: "text-2xl font-semibold",
369
+ 5: "text-xl font-medium",
370
+ 6: "text-lg font-medium"
371
+ },
372
+ align: {
373
+ left: "text-left",
374
+ center: "text-center",
375
+ right: "text-right",
376
+ justify: "text-justify"
377
+ }
378
+ };
379
+ function pe(l) {
380
+ const { restoreSelection: e, getRange: t, isCollapsed: n } = ye(l);
381
+ function a(I) {
382
+ let w = I;
383
+ for (; w; ) {
384
+ if (w.contentEditable === "true") {
385
+ w.dispatchEvent(new Event("input", { bubbles: !0 }));
386
+ return;
387
+ }
388
+ w = w.parentNode;
389
+ }
390
+ }
391
+ function p(I) {
392
+ e();
393
+ const w = t();
394
+ if (!w || n()) return;
395
+ const L = w.extractContents(), C = document.createElement("span");
396
+ C.className = I, C.appendChild(L), w.insertNode(C);
397
+ const M = document.createRange();
398
+ M.selectNodeContents(C);
399
+ const s = window.getSelection();
400
+ return s == null || s.removeAllRanges(), s == null || s.addRange(M), a(C), C;
401
+ }
402
+ function f(I) {
403
+ e();
404
+ const w = t();
405
+ if (!w) return null;
406
+ let L = w.commonAncestorContainer.nodeType === Node.TEXT_NODE ? w.commonAncestorContainer.parentElement : w.commonAncestorContainer;
407
+ for (; L && L.contentEditable !== "true"; ) {
408
+ const C = L;
409
+ if (C.tagName === "SPAN" && C.classList.contains(I))
410
+ return C;
411
+ L = L.parentNode;
412
+ }
413
+ return null;
414
+ }
415
+ function v(I) {
416
+ const w = f(I);
417
+ if (w) {
418
+ const L = w.parentNode;
419
+ for (; w.firstChild; )
420
+ L.insertBefore(w.firstChild, w);
421
+ L.removeChild(w), L.normalize(), a(L);
422
+ } else
423
+ p(I);
424
+ }
425
+ function d() {
426
+ v(J.bold);
427
+ }
428
+ function r() {
429
+ v(J.italic);
430
+ }
431
+ function u() {
432
+ v(J.underline);
433
+ }
434
+ function i() {
435
+ v(J.strikethrough);
436
+ }
437
+ function c(I) {
438
+ f(`text-${I}`) || p(`text-${I}`);
439
+ }
440
+ function x(I) {
441
+ p(`font-${I}`);
442
+ }
443
+ function $(I) {
444
+ p(I);
445
+ }
446
+ function P(I, w) {
447
+ e();
448
+ const L = t();
449
+ if (!L) return;
450
+ const C = document.createElement("a");
451
+ C.href = I, C.className = "text-blue-600 underline hover:text-blue-800", C.target = "_blank", C.rel = "noopener noreferrer", n() || L.deleteContents(), C.textContent = w || I, L.insertNode(C);
452
+ const M = document.createRange();
453
+ M.setStartAfter(C), M.collapse(!0);
454
+ const s = window.getSelection();
455
+ s == null || s.removeAllRanges(), s == null || s.addRange(M), a(C);
456
+ }
457
+ function K(I) {
458
+ return f(I) !== null;
459
+ }
460
+ return {
461
+ wrapSelectionWithClass: p,
462
+ toggleClass: v,
463
+ applyBold: d,
464
+ applyItalic: r,
465
+ applyUnderline: u,
466
+ applyStrikethrough: i,
467
+ applyFontSize: c,
468
+ applyFontWeight: x,
469
+ applyColor: $,
470
+ insertLink: P,
471
+ isActive: K
472
+ };
473
+ }
474
+ const Ne = ["title", "disabled"], j = /* @__PURE__ */ A({
475
+ __name: "ToolbarButton",
476
+ props: {
477
+ title: {},
478
+ active: { type: Boolean },
479
+ disabled: { type: Boolean }
480
+ },
481
+ emits: ["action"],
482
+ setup(l) {
483
+ return (e, t) => (g(), b("button", {
484
+ class: H(["ae-toolbar-btn inline-flex items-center justify-center w-8 h-8 rounded text-sm transition-colors", [
485
+ l.active ? "bg-gray-800 text-white" : "text-gray-600 hover:bg-gray-100 hover:text-gray-900",
486
+ l.disabled ? "opacity-40 cursor-not-allowed" : "cursor-pointer"
487
+ ]]),
488
+ title: l.title,
489
+ disabled: l.disabled,
490
+ onMousedown: t[0] || (t[0] = m((n) => e.$emit("action"), ["prevent"]))
491
+ }, [
492
+ be(e.$slots, "default")
493
+ ], 42, Ne));
494
+ }
495
+ }), Ke = {
496
+ key: 0,
497
+ class: "ae-color-picker relative"
498
+ }, Ve = { class: "p-2 border-b border-gray-100" }, qe = { class: "max-h-48 overflow-y-auto py-1" }, Oe = ["onMousedown"], _e = { class: "text-gray-700" }, Fe = { class: "text-gray-400 text-xs ml-auto" }, Pe = {
499
+ key: 0,
500
+ class: "px-3 py-2 text-sm text-gray-400 text-center"
501
+ }, We = /* @__PURE__ */ A({
502
+ __name: "ColorPicker",
503
+ setup(l) {
504
+ const e = E("alienEditor"), t = pe(e.savedRange), n = k(!1), a = k(""), p = Q(
505
+ () => e.colors.filter(
506
+ (r) => r.title.toLowerCase().includes(a.value.toLowerCase()) || r.key.toLowerCase().includes(a.value.toLowerCase())
507
+ )
508
+ );
509
+ function f(r) {
510
+ t.applyColor(r.class), n.value = !1, a.value = "";
511
+ }
512
+ function v() {
513
+ n.value = !n.value, n.value && (a.value = "");
514
+ }
515
+ function d() {
516
+ n.value = !1;
517
+ }
518
+ return (r, u) => h(e).colors.length ? (g(), b("div", Ke, [
519
+ o("button", {
520
+ class: "ae-toolbar-btn inline-flex items-center gap-1 px-2 h-8 rounded text-sm text-gray-600 hover:bg-gray-100 hover:text-gray-900 transition-colors",
521
+ title: "Text color",
522
+ onMousedown: m(v, ["prevent"])
523
+ }, [...u[3] || (u[3] = [
524
+ o("span", { class: "text-xs font-medium" }, "A", -1),
525
+ o("span", { class: "text-gray-400" }, "▾", -1)
526
+ ])], 32),
527
+ n.value ? (g(), b("div", {
528
+ key: 0,
529
+ class: "ae-color-dropdown absolute top-full left-0 mt-1 w-52 bg-white border border-gray-200 rounded-lg shadow-lg z-50",
530
+ onMousedown: u[2] || (u[2] = m(() => {
531
+ }, ["stop"]))
532
+ }, [
533
+ o("div", Ve, [
534
+ _(o("input", {
535
+ "onUpdate:modelValue": u[0] || (u[0] = (i) => a.value = i),
536
+ type: "text",
537
+ placeholder: "Search colors...",
538
+ class: "w-full text-sm border border-gray-200 rounded px-2 py-1 outline-none focus:border-blue-400",
539
+ onMousedown: u[1] || (u[1] = m(() => {
540
+ }, ["stop"]))
541
+ }, null, 544), [
542
+ [F, a.value]
543
+ ])
544
+ ]),
545
+ o("ul", qe, [
546
+ (g(!0), b(N, null, V(p.value, (i) => (g(), b("li", {
547
+ key: i.key,
548
+ class: "flex items-center gap-2 px-3 py-1.5 cursor-pointer hover:bg-gray-50 text-sm",
549
+ onMousedown: m((c) => f(i), ["prevent"])
550
+ }, [
551
+ o("span", {
552
+ class: H(["font-bold text-base", i.class])
553
+ }, "A", 2),
554
+ o("span", _e, z(i.title), 1),
555
+ o("span", Fe, z(i.key), 1)
556
+ ], 40, Oe))), 128)),
557
+ p.value.length === 0 ? (g(), b("li", Pe, " No colors found ")) : T("", !0)
558
+ ])
559
+ ], 32)) : T("", !0),
560
+ n.value ? (g(), b("div", {
561
+ key: 1,
562
+ class: "fixed inset-0 z-40",
563
+ onMousedown: d
564
+ }, null, 32)) : T("", !0)
565
+ ])) : T("", !0);
566
+ }
567
+ }), Je = {
568
+ key: 0,
569
+ class: "ae-module-dropdown relative"
570
+ }, Xe = { class: "p-2 border-b border-gray-100" }, Ye = { class: "max-h-60 overflow-y-auto py-1" }, Ze = ["onMousedown"], Ge = { class: "w-8 h-8 rounded bg-gray-100 flex items-center justify-center text-gray-500 text-xs flex-shrink-0 mt-0.5" }, Qe = { class: "text-sm font-medium text-gray-800" }, et = { class: "text-xs text-gray-400" }, tt = {
571
+ key: 0,
572
+ class: "px-3 py-2 text-sm text-gray-400 text-center"
573
+ }, ot = /* @__PURE__ */ A({
574
+ __name: "ModuleDropdown",
575
+ setup(l) {
576
+ const e = E("alienEditor"), t = k(!1), n = k(""), a = Q(
577
+ () => e.modules.filter(
578
+ (d) => d.title.toLowerCase().includes(n.value.toLowerCase()) || d.key.toLowerCase().includes(n.value.toLowerCase())
579
+ )
580
+ );
581
+ function p(d) {
582
+ var u;
583
+ const r = e.activeBlockId.value;
584
+ if (r)
585
+ e.addBlockAfter(r, "module", { html: d.module });
586
+ else {
587
+ const i = e.blocks.value, c = ((u = i[i.length - 1]) == null ? void 0 : u.id) ?? "";
588
+ c ? e.addBlockAfter(c, "module", { html: d.module }) : e.addBlockAt(0, "module", { html: d.module });
589
+ }
590
+ t.value = !1, n.value = "";
591
+ }
592
+ function f() {
593
+ t.value = !t.value, t.value && (n.value = "");
594
+ }
595
+ function v() {
596
+ t.value = !1;
597
+ }
598
+ return (d, r) => h(e).modules.length ? (g(), b("div", Je, [
599
+ o("button", {
600
+ class: "ae-toolbar-btn inline-flex items-center gap-1 px-2 h-8 rounded text-sm text-gray-600 hover:bg-gray-100 hover:text-gray-900 transition-colors",
601
+ title: "Insert module",
602
+ onMousedown: m(f, ["prevent"])
603
+ }, [...r[3] || (r[3] = [
604
+ o("span", { class: "text-xs font-medium" }, "{ }", -1),
605
+ o("span", { class: "text-gray-400" }, "▾", -1)
606
+ ])], 32),
607
+ t.value ? (g(), b("div", {
608
+ key: 0,
609
+ class: "ae-module-dropdown-panel absolute top-full left-0 mt-1 w-60 bg-white border border-gray-200 rounded-lg shadow-lg z-50",
610
+ onMousedown: r[2] || (r[2] = m(() => {
611
+ }, ["stop"]))
612
+ }, [
613
+ o("div", Xe, [
614
+ _(o("input", {
615
+ "onUpdate:modelValue": r[0] || (r[0] = (u) => n.value = u),
616
+ type: "text",
617
+ placeholder: "Search modules...",
618
+ class: "w-full text-sm border border-gray-200 rounded px-2 py-1 outline-none focus:border-blue-400",
619
+ onMousedown: r[1] || (r[1] = m(() => {
620
+ }, ["stop"]))
621
+ }, null, 544), [
622
+ [F, n.value]
623
+ ])
624
+ ]),
625
+ o("ul", Ye, [
626
+ (g(!0), b(N, null, V(a.value, (u) => (g(), b("li", {
627
+ key: u.key,
628
+ class: "flex items-start gap-2 px-3 py-2 cursor-pointer hover:bg-gray-50",
629
+ onMousedown: m((i) => p(u), ["prevent"])
630
+ }, [
631
+ o("div", Ge, z(u.key.slice(0, 2).toUpperCase()), 1),
632
+ o("div", null, [
633
+ o("p", Qe, z(u.title), 1),
634
+ o("p", et, z(u.key), 1)
635
+ ])
636
+ ], 40, Ze))), 128)),
637
+ a.value.length === 0 ? (g(), b("li", tt, " No modules found ")) : T("", !0)
638
+ ])
639
+ ], 32)) : T("", !0),
640
+ t.value ? (g(), b("div", {
641
+ key: 1,
642
+ class: "fixed inset-0 z-40",
643
+ onMousedown: v
644
+ }, null, 32)) : T("", !0)
645
+ ])) : T("", !0);
646
+ }
647
+ }), nt = { class: "ae-mode-toggle flex rounded-md border border-gray-200 overflow-hidden" }, lt = ["title", "onMousedown"], rt = /* @__PURE__ */ A({
648
+ __name: "ModeToggle",
649
+ setup(l) {
650
+ const e = E("alienEditor"), t = [
651
+ { key: "edit", label: "Edit", title: "Edit mode" },
652
+ { key: "code", label: "Code", title: "View raw HTML" },
653
+ { key: "preview", label: "Preview", title: "Preview rendered output" }
654
+ ];
655
+ return (n, a) => (g(), b("div", nt, [
656
+ (g(), b(N, null, V(t, (p) => o("button", {
657
+ key: p.key,
658
+ class: H(["px-3 py-1 text-xs font-medium transition-colors", h(e).mode.value === p.key ? "bg-gray-800 text-white" : "text-gray-600 hover:bg-gray-100"]),
659
+ title: p.title,
660
+ onMousedown: m((f) => h(e).mode.value = p.key, ["prevent"])
661
+ }, z(p.label), 43, lt)), 64))
662
+ ]));
663
+ }
664
+ }), st = { class: "relative" }, at = ["onMousedown"], it = { class: "relative" }, ut = ["onMousedown"], dt = { class: "relative" }, ct = ["onMousedown"], pt = { class: "relative" }, ft = ["onMousedown"], gt = { class: "ml-auto" }, vt = /* @__PURE__ */ A({
665
+ __name: "AlienToolbar",
666
+ setup(l) {
667
+ const e = E("alienEditor"), t = pe(e.savedRange), n = k(!1), a = [
668
+ { type: "paragraph", label: "Paragraph" },
669
+ { type: "heading", label: "Heading" },
670
+ { type: "unordered-list", label: "Bullet List" },
671
+ { type: "ordered-list", label: "Numbered List" },
672
+ { type: "blockquote", label: "Blockquote" },
673
+ { type: "code", label: "Code Block" },
674
+ { type: "image", label: "Image" },
675
+ { type: "video", label: "Video" },
676
+ { type: "button", label: "Button" },
677
+ { type: "divider", label: "Divider" }
678
+ ];
679
+ function p(M) {
680
+ var y;
681
+ const s = e.activeBlockId.value;
682
+ if (s)
683
+ e.addBlockAfter(s, M);
684
+ else {
685
+ const q = e.blocks.value, ne = (y = q[q.length - 1]) == null ? void 0 : y.id;
686
+ ne ? e.addBlockAfter(ne, M) : e.addBlockAt(0, M);
687
+ }
688
+ n.value = !1;
689
+ }
690
+ const f = k(!1), v = [1, 2, 3, 4, 5, 6];
691
+ function d(M) {
692
+ const s = e.activeBlockId.value;
693
+ if (!s) return;
694
+ const y = e.blocks.value.find((q) => q.id === s);
695
+ (y == null ? void 0 : y.type) === "heading" ? e.updateBlock(s, { level: M }) : (e.pushSnapshot(), e.updateBlock(s, { type: "heading", level: M, html: (y == null ? void 0 : y.html) ?? "" })), f.value = !1;
696
+ }
697
+ const r = k(!1), u = Object.entries(J.fontSizes), i = k(!1), c = Object.entries(J.fontWeights);
698
+ function x(M) {
699
+ const s = e.activeBlockId.value;
700
+ s && e.updateBlock(s, { align: M });
701
+ }
702
+ function $() {
703
+ e.saveSelection(), e.showLinkModal.value = !0;
704
+ }
705
+ function P() {
706
+ const M = e.activeBlockId.value;
707
+ M ? e.addBlockAfter(M, "image") : e.addBlockAt(e.blocks.value.length, "image");
708
+ }
709
+ function K() {
710
+ const M = e.activeBlockId.value;
711
+ M ? e.addBlockAfter(M, "divider") : e.addBlockAt(e.blocks.value.length, "divider");
712
+ }
713
+ const I = Q(() => e.activeBlockId.value ? e.blocks.value.find((M) => M.id === e.activeBlockId.value) ?? null : null), w = Q(() => {
714
+ var M;
715
+ return ((M = I.value) == null ? void 0 : M.align) ?? "left";
716
+ }), L = Q(() => e.mode.value === "edit");
717
+ function C() {
718
+ n.value = !1, f.value = !1, r.value = !1, i.value = !1;
719
+ }
720
+ return (M, s) => (g(), b("div", {
721
+ class: "ae-toolbar flex items-center gap-0.5 flex-wrap px-2 py-1.5 border-b border-gray-200 bg-white sticky top-0 z-20",
722
+ onMouseleave: C
723
+ }, [
724
+ L.value ? (g(), b(N, { key: 0 }, [
725
+ S(j, {
726
+ title: "Bold (Ctrl+B)",
727
+ onAction: s[0] || (s[0] = (y) => h(t).applyBold())
728
+ }, {
729
+ default: D(() => [...s[18] || (s[18] = [
730
+ o("strong", null, "B", -1)
731
+ ])]),
732
+ _: 1
733
+ }),
734
+ S(j, {
735
+ title: "Italic (Ctrl+I)",
736
+ onAction: s[1] || (s[1] = (y) => h(t).applyItalic())
737
+ }, {
738
+ default: D(() => [...s[19] || (s[19] = [
739
+ o("em", null, "I", -1)
740
+ ])]),
741
+ _: 1
742
+ }),
743
+ S(j, {
744
+ title: "Underline",
745
+ onAction: s[2] || (s[2] = (y) => h(t).applyUnderline())
746
+ }, {
747
+ default: D(() => [...s[20] || (s[20] = [
748
+ o("span", { class: "underline" }, "U", -1)
749
+ ])]),
750
+ _: 1
751
+ }),
752
+ S(j, {
753
+ title: "Strikethrough",
754
+ onAction: s[3] || (s[3] = (y) => h(t).applyStrikethrough())
755
+ }, {
756
+ default: D(() => [...s[21] || (s[21] = [
757
+ o("span", { class: "line-through" }, "S", -1)
758
+ ])]),
759
+ _: 1
760
+ }),
761
+ s[35] || (s[35] = o("div", { class: "ae-divider-v w-px h-5 bg-gray-200 mx-1" }, null, -1)),
762
+ o("div", st, [
763
+ o("button", {
764
+ class: "ae-toolbar-btn inline-flex items-center gap-1 px-2 h-8 rounded text-sm text-gray-600 hover:bg-gray-100 transition-colors",
765
+ title: "Heading level",
766
+ onMousedown: s[4] || (s[4] = m((y) => {
767
+ f.value = !f.value, r.value = !1, i.value = !1, n.value = !1;
768
+ }, ["prevent"]))
769
+ }, [...s[22] || (s[22] = [
770
+ re(" H ", -1),
771
+ o("span", { class: "text-gray-400 text-xs" }, "▾", -1)
772
+ ])], 32),
773
+ f.value ? (g(), b("div", {
774
+ key: 0,
775
+ class: "absolute top-full left-0 mt-1 bg-white border border-gray-200 rounded-lg shadow-lg z-50 py-1 min-w-[100px]",
776
+ onMousedown: s[5] || (s[5] = m(() => {
777
+ }, ["stop"]))
778
+ }, [
779
+ (g(), b(N, null, V(v, (y) => o("button", {
780
+ key: y,
781
+ class: "w-full text-left px-3 py-1.5 text-sm hover:bg-gray-50 flex items-center gap-2",
782
+ onMousedown: m((q) => d(y), ["prevent"])
783
+ }, [
784
+ o("span", {
785
+ class: H([h(J).headingDefaults[y], "leading-tight"])
786
+ }, "H" + z(y), 3)
787
+ ], 40, at)), 64))
788
+ ], 32)) : T("", !0)
789
+ ]),
790
+ o("div", it, [
791
+ o("button", {
792
+ class: "ae-toolbar-btn inline-flex items-center gap-1 px-2 h-8 rounded text-sm text-gray-600 hover:bg-gray-100 transition-colors",
793
+ title: "Font size",
794
+ onMousedown: s[6] || (s[6] = m((y) => {
795
+ r.value = !r.value, f.value = !1, i.value = !1, n.value = !1;
796
+ }, ["prevent"]))
797
+ }, [...s[23] || (s[23] = [
798
+ re(" Size ", -1),
799
+ o("span", { class: "text-gray-400 text-xs" }, "▾", -1)
800
+ ])], 32),
801
+ r.value ? (g(), b("div", {
802
+ key: 0,
803
+ class: "absolute top-full left-0 mt-1 bg-white border border-gray-200 rounded-lg shadow-lg z-50 py-1 min-w-[120px]",
804
+ onMousedown: s[7] || (s[7] = m(() => {
805
+ }, ["stop"]))
806
+ }, [
807
+ (g(!0), b(N, null, V(h(u), ([y]) => (g(), b("button", {
808
+ key: y,
809
+ class: H(["w-full text-left px-3 py-1 hover:bg-gray-50", `text-${y}`]),
810
+ onMousedown: m((q) => h(t).applyFontSize(y), ["prevent"])
811
+ }, z(y), 43, ut))), 128))
812
+ ], 32)) : T("", !0)
813
+ ]),
814
+ o("div", dt, [
815
+ o("button", {
816
+ class: "ae-toolbar-btn inline-flex items-center gap-1 px-2 h-8 rounded text-sm text-gray-600 hover:bg-gray-100 transition-colors",
817
+ title: "Font weight",
818
+ onMousedown: s[8] || (s[8] = m((y) => {
819
+ i.value = !i.value, f.value = !1, r.value = !1, n.value = !1;
820
+ }, ["prevent"]))
821
+ }, [...s[24] || (s[24] = [
822
+ re(" Weight ", -1),
823
+ o("span", { class: "text-gray-400 text-xs" }, "▾", -1)
824
+ ])], 32),
825
+ i.value ? (g(), b("div", {
826
+ key: 0,
827
+ class: "absolute top-full left-0 mt-1 bg-white border border-gray-200 rounded-lg shadow-lg z-50 py-1 min-w-[130px]",
828
+ onMousedown: s[9] || (s[9] = m(() => {
829
+ }, ["stop"]))
830
+ }, [
831
+ (g(!0), b(N, null, V(h(c), ([y]) => (g(), b("button", {
832
+ key: y,
833
+ class: H(["w-full text-left px-3 py-1 hover:bg-gray-50 text-sm", `font-${y}`]),
834
+ onMousedown: m((q) => h(t).applyFontWeight(y), ["prevent"])
835
+ }, z(y), 43, ct))), 128))
836
+ ], 32)) : T("", !0)
837
+ ]),
838
+ s[36] || (s[36] = o("div", { class: "ae-divider-v w-px h-5 bg-gray-200 mx-1" }, null, -1)),
839
+ S(j, {
840
+ title: "Align left",
841
+ active: w.value === "left",
842
+ onAction: s[10] || (s[10] = (y) => x("left"))
843
+ }, {
844
+ default: D(() => [...s[25] || (s[25] = [
845
+ o("svg", {
846
+ width: "14",
847
+ height: "14",
848
+ viewBox: "0 0 14 14",
849
+ fill: "currentColor"
850
+ }, [
851
+ o("rect", {
852
+ x: "0",
853
+ y: "1",
854
+ width: "14",
855
+ height: "2",
856
+ rx: "1"
857
+ }),
858
+ o("rect", {
859
+ x: "0",
860
+ y: "5",
861
+ width: "10",
862
+ height: "2",
863
+ rx: "1"
864
+ }),
865
+ o("rect", {
866
+ x: "0",
867
+ y: "9",
868
+ width: "14",
869
+ height: "2",
870
+ rx: "1"
871
+ }),
872
+ o("rect", {
873
+ x: "0",
874
+ y: "13",
875
+ width: "8",
876
+ height: "2",
877
+ rx: "1"
878
+ })
879
+ ], -1)
880
+ ])]),
881
+ _: 1
882
+ }, 8, ["active"]),
883
+ S(j, {
884
+ title: "Align center",
885
+ active: w.value === "center",
886
+ onAction: s[11] || (s[11] = (y) => x("center"))
887
+ }, {
888
+ default: D(() => [...s[26] || (s[26] = [
889
+ o("svg", {
890
+ width: "14",
891
+ height: "14",
892
+ viewBox: "0 0 14 14",
893
+ fill: "currentColor"
894
+ }, [
895
+ o("rect", {
896
+ x: "0",
897
+ y: "1",
898
+ width: "14",
899
+ height: "2",
900
+ rx: "1"
901
+ }),
902
+ o("rect", {
903
+ x: "2",
904
+ y: "5",
905
+ width: "10",
906
+ height: "2",
907
+ rx: "1"
908
+ }),
909
+ o("rect", {
910
+ x: "0",
911
+ y: "9",
912
+ width: "14",
913
+ height: "2",
914
+ rx: "1"
915
+ }),
916
+ o("rect", {
917
+ x: "3",
918
+ y: "13",
919
+ width: "8",
920
+ height: "2",
921
+ rx: "1"
922
+ })
923
+ ], -1)
924
+ ])]),
925
+ _: 1
926
+ }, 8, ["active"]),
927
+ S(j, {
928
+ title: "Align right",
929
+ active: w.value === "right",
930
+ onAction: s[12] || (s[12] = (y) => x("right"))
931
+ }, {
932
+ default: D(() => [...s[27] || (s[27] = [
933
+ o("svg", {
934
+ width: "14",
935
+ height: "14",
936
+ viewBox: "0 0 14 14",
937
+ fill: "currentColor"
938
+ }, [
939
+ o("rect", {
940
+ x: "0",
941
+ y: "1",
942
+ width: "14",
943
+ height: "2",
944
+ rx: "1"
945
+ }),
946
+ o("rect", {
947
+ x: "4",
948
+ y: "5",
949
+ width: "10",
950
+ height: "2",
951
+ rx: "1"
952
+ }),
953
+ o("rect", {
954
+ x: "0",
955
+ y: "9",
956
+ width: "14",
957
+ height: "2",
958
+ rx: "1"
959
+ }),
960
+ o("rect", {
961
+ x: "6",
962
+ y: "13",
963
+ width: "8",
964
+ height: "2",
965
+ rx: "1"
966
+ })
967
+ ], -1)
968
+ ])]),
969
+ _: 1
970
+ }, 8, ["active"]),
971
+ S(j, {
972
+ title: "Justify",
973
+ active: w.value === "justify",
974
+ onAction: s[13] || (s[13] = (y) => x("justify"))
975
+ }, {
976
+ default: D(() => [...s[28] || (s[28] = [
977
+ o("svg", {
978
+ width: "14",
979
+ height: "14",
980
+ viewBox: "0 0 14 14",
981
+ fill: "currentColor"
982
+ }, [
983
+ o("rect", {
984
+ x: "0",
985
+ y: "1",
986
+ width: "14",
987
+ height: "2",
988
+ rx: "1"
989
+ }),
990
+ o("rect", {
991
+ x: "0",
992
+ y: "5",
993
+ width: "14",
994
+ height: "2",
995
+ rx: "1"
996
+ }),
997
+ o("rect", {
998
+ x: "0",
999
+ y: "9",
1000
+ width: "14",
1001
+ height: "2",
1002
+ rx: "1"
1003
+ }),
1004
+ o("rect", {
1005
+ x: "0",
1006
+ y: "13",
1007
+ width: "14",
1008
+ height: "2",
1009
+ rx: "1"
1010
+ })
1011
+ ], -1)
1012
+ ])]),
1013
+ _: 1
1014
+ }, 8, ["active"]),
1015
+ s[37] || (s[37] = o("div", { class: "ae-divider-v w-px h-5 bg-gray-200 mx-1" }, null, -1)),
1016
+ S(j, {
1017
+ title: "Insert link",
1018
+ onAction: $
1019
+ }, {
1020
+ default: D(() => [...s[29] || (s[29] = [
1021
+ o("svg", {
1022
+ width: "14",
1023
+ height: "14",
1024
+ viewBox: "0 0 24 24",
1025
+ fill: "none",
1026
+ stroke: "currentColor",
1027
+ "stroke-width": "2"
1028
+ }, [
1029
+ o("path", { d: "M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71" }),
1030
+ o("path", { d: "M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71" })
1031
+ ], -1)
1032
+ ])]),
1033
+ _: 1
1034
+ }),
1035
+ S(j, {
1036
+ title: "Insert image",
1037
+ onAction: P
1038
+ }, {
1039
+ default: D(() => [...s[30] || (s[30] = [
1040
+ o("svg", {
1041
+ width: "14",
1042
+ height: "14",
1043
+ viewBox: "0 0 24 24",
1044
+ fill: "none",
1045
+ stroke: "currentColor",
1046
+ "stroke-width": "2"
1047
+ }, [
1048
+ o("rect", {
1049
+ x: "3",
1050
+ y: "3",
1051
+ width: "18",
1052
+ height: "18",
1053
+ rx: "2",
1054
+ ry: "2"
1055
+ }),
1056
+ o("circle", {
1057
+ cx: "8.5",
1058
+ cy: "8.5",
1059
+ r: "1.5"
1060
+ }),
1061
+ o("polyline", { points: "21 15 16 10 5 21" })
1062
+ ], -1)
1063
+ ])]),
1064
+ _: 1
1065
+ }),
1066
+ S(j, {
1067
+ title: "Insert divider",
1068
+ onAction: K
1069
+ }, {
1070
+ default: D(() => [...s[31] || (s[31] = [
1071
+ o("svg", {
1072
+ width: "14",
1073
+ height: "14",
1074
+ viewBox: "0 0 14 14",
1075
+ fill: "currentColor"
1076
+ }, [
1077
+ o("rect", {
1078
+ x: "0",
1079
+ y: "6",
1080
+ width: "14",
1081
+ height: "2",
1082
+ rx: "1"
1083
+ })
1084
+ ], -1)
1085
+ ])]),
1086
+ _: 1
1087
+ }),
1088
+ o("div", pt, [
1089
+ o("button", {
1090
+ class: "ae-toolbar-btn inline-flex items-center gap-1 px-2 h-8 rounded text-sm text-gray-600 hover:bg-gray-100 transition-colors",
1091
+ title: "Insert block",
1092
+ onMousedown: s[14] || (s[14] = m((y) => {
1093
+ n.value = !n.value, f.value = !1, r.value = !1, i.value = !1;
1094
+ }, ["prevent"]))
1095
+ }, [...s[32] || (s[32] = [
1096
+ re(" + Block ", -1),
1097
+ o("span", { class: "text-gray-400 text-xs" }, "▾", -1)
1098
+ ])], 32),
1099
+ n.value ? (g(), b("div", {
1100
+ key: 0,
1101
+ class: "absolute top-full left-0 mt-1 bg-white border border-gray-200 rounded-lg shadow-lg z-50 py-1 min-w-[150px]",
1102
+ onMousedown: s[15] || (s[15] = m(() => {
1103
+ }, ["stop"]))
1104
+ }, [
1105
+ (g(), b(N, null, V(a, (y) => o("button", {
1106
+ key: y.type,
1107
+ class: "w-full text-left px-3 py-1.5 text-sm hover:bg-gray-50",
1108
+ onMousedown: m((q) => p(y.type), ["prevent"])
1109
+ }, z(y.label), 41, ft)), 64))
1110
+ ], 32)) : T("", !0)
1111
+ ]),
1112
+ s[38] || (s[38] = o("div", { class: "ae-divider-v w-px h-5 bg-gray-200 mx-1" }, null, -1)),
1113
+ S(We),
1114
+ S(ot),
1115
+ s[39] || (s[39] = o("div", { class: "ae-divider-v w-px h-5 bg-gray-200 mx-1" }, null, -1)),
1116
+ S(j, {
1117
+ title: "Undo (Ctrl+Z)",
1118
+ disabled: !h(e).canUndo(),
1119
+ onAction: s[16] || (s[16] = (y) => h(e).undo())
1120
+ }, {
1121
+ default: D(() => [...s[33] || (s[33] = [
1122
+ o("svg", {
1123
+ width: "14",
1124
+ height: "14",
1125
+ viewBox: "0 0 24 24",
1126
+ fill: "none",
1127
+ stroke: "currentColor",
1128
+ "stroke-width": "2"
1129
+ }, [
1130
+ o("polyline", { points: "9 14 4 9 9 4" }),
1131
+ o("path", { d: "M20 20v-7a4 4 0 00-4-4H4" })
1132
+ ], -1)
1133
+ ])]),
1134
+ _: 1
1135
+ }, 8, ["disabled"]),
1136
+ S(j, {
1137
+ title: "Redo (Ctrl+Y)",
1138
+ disabled: !h(e).canRedo(),
1139
+ onAction: s[17] || (s[17] = (y) => h(e).redo())
1140
+ }, {
1141
+ default: D(() => [...s[34] || (s[34] = [
1142
+ o("svg", {
1143
+ width: "14",
1144
+ height: "14",
1145
+ viewBox: "0 0 24 24",
1146
+ fill: "none",
1147
+ stroke: "currentColor",
1148
+ "stroke-width": "2"
1149
+ }, [
1150
+ o("polyline", { points: "15 14 20 9 15 4" }),
1151
+ o("path", { d: "M4 20v-7a4 4 0 014-4h12" })
1152
+ ], -1)
1153
+ ])]),
1154
+ _: 1
1155
+ }, 8, ["disabled"]),
1156
+ s[40] || (s[40] = o("div", { class: "ae-divider-v w-px h-5 bg-gray-200 mx-1" }, null, -1))
1157
+ ], 64)) : T("", !0),
1158
+ o("div", gt, [
1159
+ S(rt)
1160
+ ])
1161
+ ], 32));
1162
+ }
1163
+ }), bt = {
1164
+ key: 0,
1165
+ class: "ae-drop-indicator absolute top-0 left-0 right-0 h-0.5 bg-blue-500 z-10 pointer-events-none"
1166
+ }, mt = { class: "ae-block-controls absolute left-0 top-1/2 -translate-y-1/2 -translate-x-full pr-1 opacity-0 group-hover:opacity-100 transition-opacity flex flex-col gap-0.5" }, yt = { class: "ae-block-content" }, xt = { class: "ae-block-actions absolute right-0 top-1/2 -translate-y-1/2 translate-x-full pl-1 opacity-0 group-hover:opacity-100 transition-opacity flex flex-col gap-0.5" }, ht = /* @__PURE__ */ A({
1167
+ __name: "BlockWrapper",
1168
+ props: {
1169
+ block: {}
1170
+ },
1171
+ setup(l) {
1172
+ const e = E("alienEditor");
1173
+ return (t, n) => (g(), b("div", {
1174
+ class: H(["ae-block-wrapper group relative", {
1175
+ "ae-block--drag-over": h(e).dragState.value.overId === l.block.id,
1176
+ "ae-block--dragging": h(e).dragState.value.draggedId === l.block.id
1177
+ }]),
1178
+ onDragover: n[5] || (n[5] = (a) => h(e).onDragOver(l.block.id, a)),
1179
+ onDragleave: n[6] || (n[6] = (a) => h(e).onDragLeave()),
1180
+ onDrop: n[7] || (n[7] = m((a) => h(e).onDrop(l.block.id), ["prevent"]))
1181
+ }, [
1182
+ h(e).dragState.value.overId === l.block.id ? (g(), b("div", bt)) : T("", !0),
1183
+ o("div", mt, [
1184
+ o("button", {
1185
+ class: "ae-drag-handle cursor-grab active:cursor-grabbing w-5 h-6 flex items-center justify-center text-gray-400 hover:text-gray-600 rounded hover:bg-gray-100",
1186
+ draggable: "true",
1187
+ title: "Drag to reorder",
1188
+ onMousedown: n[0] || (n[0] = m(() => {
1189
+ }, ["stop"])),
1190
+ onDragstart: n[1] || (n[1] = (a) => h(e).onDragStart(l.block.id, a)),
1191
+ onDragend: n[2] || (n[2] = (a) => h(e).onDragEnd())
1192
+ }, [...n[8] || (n[8] = [
1193
+ Ie('<svg width="10" height="16" viewBox="0 0 10 16" fill="currentColor"><circle cx="3" cy="3" r="1.5"></circle><circle cx="7" cy="3" r="1.5"></circle><circle cx="3" cy="8" r="1.5"></circle><circle cx="7" cy="8" r="1.5"></circle><circle cx="3" cy="13" r="1.5"></circle><circle cx="7" cy="13" r="1.5"></circle></svg>', 1)
1194
+ ])], 32)
1195
+ ]),
1196
+ o("div", yt, [
1197
+ be(t.$slots, "default")
1198
+ ]),
1199
+ o("div", xt, [
1200
+ o("button", {
1201
+ class: "ae-btn-add w-6 h-6 flex items-center justify-center text-gray-400 hover:text-green-600 hover:bg-green-50 rounded text-lg leading-none",
1202
+ title: "Add block below",
1203
+ onMousedown: n[3] || (n[3] = m((a) => h(e).addBlockAfter(l.block.id, "paragraph"), ["prevent"]))
1204
+ }, " + ", 32),
1205
+ o("button", {
1206
+ class: "ae-btn-delete w-6 h-6 flex items-center justify-center text-gray-400 hover:text-red-600 hover:bg-red-50 rounded text-sm leading-none",
1207
+ title: "Delete block",
1208
+ onMousedown: n[4] || (n[4] = m((a) => h(e).removeBlock(l.block.id), ["prevent"]))
1209
+ }, " × ", 32)
1210
+ ])
1211
+ ], 34));
1212
+ }
1213
+ }), kt = /* @__PURE__ */ A({
1214
+ __name: "TextBlock",
1215
+ props: {
1216
+ block: {}
1217
+ },
1218
+ setup(l) {
1219
+ const e = l, t = E("alienEditor"), n = k(null);
1220
+ let a = null, p = !1;
1221
+ oe(() => {
1222
+ n.value && n.value.innerHTML !== e.block.html && (n.value.innerHTML = e.block.html);
1223
+ }), W(
1224
+ () => e.block.html,
1225
+ (r) => {
1226
+ n.value && !p && n.value.innerHTML !== r && (n.value.innerHTML = r);
1227
+ }
1228
+ );
1229
+ function f() {
1230
+ n.value && (p = !0, t.updateBlock(e.block.id, { html: n.value.innerHTML }), p = !1, a && clearTimeout(a), a = setTimeout(() => {
1231
+ t.pushSnapshot();
1232
+ }, 500));
1233
+ }
1234
+ function v(r) {
1235
+ var u;
1236
+ if (r.key === "Enter" && !r.shiftKey) {
1237
+ r.preventDefault();
1238
+ const i = t.addBlockAfter(e.block.id, "paragraph");
1239
+ X(() => {
1240
+ const c = document.querySelector(`[data-block-id="${i}"]`);
1241
+ c == null || c.focus();
1242
+ });
1243
+ return;
1244
+ }
1245
+ if (r.key === "Backspace" && ((u = n.value) == null ? void 0 : u.innerHTML) === "") {
1246
+ r.preventDefault();
1247
+ const i = t.blocks.value, c = i.findIndex(($) => $.id === e.block.id), x = c > 0 ? i[c - 1].id : null;
1248
+ t.removeBlock(e.block.id), x && X(() => {
1249
+ const $ = document.querySelector(`[data-block-id="${x}"]`);
1250
+ $ == null || $.focus();
1251
+ });
1252
+ }
1253
+ }
1254
+ function d() {
1255
+ t.activeBlockId.value = e.block.id;
1256
+ }
1257
+ return (r, u) => (g(), U(ce(l.block.type === "blockquote" ? "blockquote" : "p"), {
1258
+ ref_key: "el",
1259
+ ref: n,
1260
+ "data-block-id": l.block.id,
1261
+ "data-placeholder": h(t).placeholder || "Type something...",
1262
+ contenteditable: "true",
1263
+ spellcheck: "true",
1264
+ class: H(["ae-text-block outline-none min-h-[1.5em] w-full", [
1265
+ l.block.align !== "left" ? `text-${l.block.align}` : "",
1266
+ ...l.block.classes,
1267
+ l.block.type === "blockquote" ? "border-l-4 border-gray-300 pl-4 italic text-gray-600" : ""
1268
+ ]]),
1269
+ onInput: f,
1270
+ onKeydown: v,
1271
+ onFocus: d,
1272
+ onMousedown: u[0] || (u[0] = (i) => h(t).saveSelection()),
1273
+ onKeyup: u[1] || (u[1] = (i) => h(t).saveSelection())
1274
+ }, null, 40, ["data-block-id", "data-placeholder", "class"]));
1275
+ }
1276
+ }), wt = { class: "ae-heading-block" }, $t = { class: "ae-heading-level-selector flex gap-1 mb-1 opacity-0 focus-within:opacity-100 hover:opacity-100 transition-opacity" }, Mt = ["onMousedown"], Bt = /* @__PURE__ */ A({
1277
+ __name: "HeadingBlock",
1278
+ props: {
1279
+ block: {}
1280
+ },
1281
+ setup(l) {
1282
+ const e = l, t = E("alienEditor"), n = k(null);
1283
+ let a = null, p = !1;
1284
+ const f = {
1285
+ 1: "text-5xl font-bold",
1286
+ 2: "text-4xl font-bold",
1287
+ 3: "text-3xl font-semibold",
1288
+ 4: "text-2xl font-semibold",
1289
+ 5: "text-xl font-medium",
1290
+ 6: "text-lg font-medium"
1291
+ };
1292
+ oe(() => {
1293
+ n.value && n.value.innerHTML !== e.block.html && (n.value.innerHTML = e.block.html);
1294
+ }), W(
1295
+ () => e.block.html,
1296
+ (i) => {
1297
+ n.value && !p && n.value.innerHTML !== i && (n.value.innerHTML = i);
1298
+ }
1299
+ );
1300
+ function v() {
1301
+ n.value && (p = !0, t.updateBlock(e.block.id, { html: n.value.innerHTML }), p = !1, a && clearTimeout(a), a = setTimeout(() => t.pushSnapshot(), 500));
1302
+ }
1303
+ function d(i) {
1304
+ var c;
1305
+ if (i.key === "Enter" && !i.shiftKey) {
1306
+ i.preventDefault();
1307
+ const x = t.addBlockAfter(e.block.id, "paragraph");
1308
+ X(() => {
1309
+ const $ = document.querySelector(`[data-block-id="${x}"]`);
1310
+ $ == null || $.focus();
1311
+ });
1312
+ }
1313
+ if (i.key === "Backspace" && ((c = n.value) == null ? void 0 : c.innerHTML) === "") {
1314
+ i.preventDefault();
1315
+ const x = t.blocks.value, $ = x.findIndex((K) => K.id === e.block.id), P = $ > 0 ? x[$ - 1].id : null;
1316
+ t.removeBlock(e.block.id), P && X(() => {
1317
+ const K = document.querySelector(`[data-block-id="${P}"]`);
1318
+ K == null || K.focus();
1319
+ });
1320
+ }
1321
+ }
1322
+ function r() {
1323
+ t.activeBlockId.value = e.block.id;
1324
+ }
1325
+ function u(i) {
1326
+ t.pushSnapshot(), t.updateBlock(e.block.id, { level: i });
1327
+ }
1328
+ return (i, c) => (g(), b("div", wt, [
1329
+ o("div", $t, [
1330
+ (g(), b(N, null, V([1, 2, 3, 4, 5, 6], (x) => o("button", {
1331
+ key: x,
1332
+ class: H(["text-xs px-1.5 py-0.5 rounded border transition-colors", l.block.level === x ? "bg-gray-800 text-white border-gray-800" : "border-gray-300 text-gray-500 hover:border-gray-500"]),
1333
+ onMousedown: m(($) => u(x), ["prevent"])
1334
+ }, " H" + z(x), 43, Mt)), 64))
1335
+ ]),
1336
+ (g(), U(ce(`h${l.block.level}`), {
1337
+ ref_key: "el",
1338
+ ref: n,
1339
+ "data-block-id": l.block.id,
1340
+ "data-placeholder": `Heading ${l.block.level}`,
1341
+ contenteditable: "true",
1342
+ spellcheck: "true",
1343
+ class: H(["ae-heading-content outline-none min-h-[1.2em] w-full", [
1344
+ f[l.block.level],
1345
+ l.block.align !== "left" ? `text-${l.block.align}` : "",
1346
+ ...l.block.classes
1347
+ ]]),
1348
+ onInput: v,
1349
+ onKeydown: d,
1350
+ onFocus: r,
1351
+ onMousedown: c[0] || (c[0] = (x) => h(t).saveSelection()),
1352
+ onKeyup: c[1] || (c[1] = (x) => h(t).saveSelection())
1353
+ }, null, 40, ["data-block-id", "data-placeholder", "class"]))
1354
+ ]));
1355
+ }
1356
+ }), It = ["onInput", "onKeydown"], Ct = /* @__PURE__ */ A({
1357
+ __name: "ListBlock",
1358
+ props: {
1359
+ block: {}
1360
+ },
1361
+ setup(l) {
1362
+ const e = l, t = E("alienEditor"), n = k([]);
1363
+ function a(d, r) {
1364
+ d && (n.value[r] = d);
1365
+ }
1366
+ function p(d, r) {
1367
+ const u = r.target, i = [...e.block.items];
1368
+ i[d] = u.innerHTML, t.updateBlock(e.block.id, { items: i });
1369
+ }
1370
+ function f(d, r) {
1371
+ const u = e.block.items;
1372
+ if (r.key === "Enter" && !r.shiftKey) {
1373
+ r.preventDefault(), t.pushSnapshot();
1374
+ const i = [...u];
1375
+ i.splice(d + 1, 0, ""), t.updateBlock(e.block.id, { items: i }), X(() => {
1376
+ var c;
1377
+ (c = n.value[d + 1]) == null || c.focus();
1378
+ });
1379
+ return;
1380
+ }
1381
+ if (r.key === "Backspace") {
1382
+ const i = r.target;
1383
+ if (i.innerHTML === "" && u.length > 1) {
1384
+ r.preventDefault(), t.pushSnapshot();
1385
+ const c = [...u];
1386
+ c.splice(d, 1), t.updateBlock(e.block.id, { items: c }), X(() => {
1387
+ var $;
1388
+ const x = Math.max(0, d - 1);
1389
+ ($ = n.value[x]) == null || $.focus();
1390
+ });
1391
+ } else if (i.innerHTML === "" && u.length === 1) {
1392
+ r.preventDefault(), t.pushSnapshot();
1393
+ const c = t.addBlockAfter(e.block.id, "paragraph");
1394
+ t.removeBlock(e.block.id), X(() => {
1395
+ const x = document.querySelector(`[data-block-id="${c}"]`);
1396
+ x == null || x.focus();
1397
+ });
1398
+ }
1399
+ }
1400
+ }
1401
+ function v() {
1402
+ t.activeBlockId.value = e.block.id;
1403
+ }
1404
+ return (d, r) => (g(), U(ce(l.block.type === "ordered-list" ? "ol" : "ul"), {
1405
+ class: H(["ae-list-block pl-6", l.block.type === "ordered-list" ? "list-decimal" : "list-disc"])
1406
+ }, {
1407
+ default: D(() => [
1408
+ (g(!0), b(N, null, V(l.block.items, (u, i) => (g(), b("li", {
1409
+ key: i,
1410
+ ref_for: !0,
1411
+ ref: (c) => a(c, i),
1412
+ contenteditable: "true",
1413
+ spellcheck: "true",
1414
+ class: "outline-none min-h-[1.5em]",
1415
+ "data-placeholder": "List item",
1416
+ onInput: (c) => p(i, c),
1417
+ onKeydown: (c) => f(i, c),
1418
+ onFocus: v,
1419
+ onMousedown: r[0] || (r[0] = (c) => h(t).saveSelection()),
1420
+ onKeyup: r[1] || (r[1] = (c) => h(t).saveSelection())
1421
+ }, null, 40, It))), 128))
1422
+ ]),
1423
+ _: 1
1424
+ }, 8, ["class"]));
1425
+ }
1426
+ }), Lt = { class: "ae-image-block" }, St = {
1427
+ key: 0,
1428
+ class: "relative group/img"
1429
+ }, At = ["src", "alt"], Tt = { class: "absolute inset-0 bg-black/0 group-hover/img:bg-black/20 transition-colors rounded flex items-center justify-center gap-2 opacity-0 group-hover/img:opacity-100" }, Et = ["value"], Dt = {
1430
+ key: 1,
1431
+ class: "ae-image-empty border-2 border-dashed border-gray-300 rounded-lg p-8 flex flex-col items-center gap-3 bg-gray-50"
1432
+ }, Ut = { class: "flex gap-2" }, Ht = {
1433
+ key: 0,
1434
+ class: "w-full flex gap-2"
1435
+ }, Rt = /* @__PURE__ */ A({
1436
+ __name: "ImageBlock",
1437
+ props: {
1438
+ block: {}
1439
+ },
1440
+ setup(l) {
1441
+ const e = l, t = E("alienEditor"), n = k(""), a = k(null), p = k(!1);
1442
+ function f(i) {
1443
+ var $;
1444
+ const c = ($ = i.target.files) == null ? void 0 : $[0];
1445
+ if (!c) return;
1446
+ t.onUpload(c);
1447
+ const x = URL.createObjectURL(c);
1448
+ t.updateBlock(e.block.id, { src: x, alt: c.name }), t.pushSnapshot();
1449
+ }
1450
+ function v() {
1451
+ const i = n.value.trim();
1452
+ i && (t.pushSnapshot(), t.updateBlock(e.block.id, { src: i }), p.value = !1, n.value = "");
1453
+ }
1454
+ function d(i) {
1455
+ i.key === "Enter" && v(), i.key === "Escape" && (p.value = !1, n.value = "");
1456
+ }
1457
+ function r(i) {
1458
+ t.updateBlock(e.block.id, { alt: i.target.value });
1459
+ }
1460
+ function u() {
1461
+ t.pushSnapshot(), t.updateBlock(e.block.id, { src: "" });
1462
+ }
1463
+ return (i, c) => (g(), b("div", Lt, [
1464
+ l.block.src ? (g(), b("div", St, [
1465
+ o("img", {
1466
+ src: l.block.src,
1467
+ alt: l.block.alt,
1468
+ class: H(["max-w-full rounded", l.block.classes])
1469
+ }, null, 10, At),
1470
+ o("div", Tt, [
1471
+ o("button", {
1472
+ class: "bg-white text-gray-700 text-xs px-2 py-1 rounded shadow hover:bg-gray-100",
1473
+ onMousedown: m(u, ["prevent"])
1474
+ }, " Replace ", 32)
1475
+ ]),
1476
+ o("input", {
1477
+ type: "text",
1478
+ value: l.block.alt,
1479
+ placeholder: "Alt text (optional)",
1480
+ class: "mt-1 w-full text-sm text-gray-500 border-0 border-b border-gray-200 outline-none focus:border-gray-400 bg-transparent",
1481
+ onChange: r,
1482
+ onMousedown: c[0] || (c[0] = m(() => {
1483
+ }, ["stop"]))
1484
+ }, null, 40, Et)
1485
+ ])) : (g(), b("div", Dt, [
1486
+ c[5] || (c[5] = o("svg", {
1487
+ class: "w-10 h-10 text-gray-400",
1488
+ fill: "none",
1489
+ stroke: "currentColor",
1490
+ viewBox: "0 0 24 24"
1491
+ }, [
1492
+ o("path", {
1493
+ "stroke-linecap": "round",
1494
+ "stroke-linejoin": "round",
1495
+ "stroke-width": "1.5",
1496
+ d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
1497
+ })
1498
+ ], -1)),
1499
+ c[6] || (c[6] = o("p", { class: "text-sm text-gray-500" }, "Upload an image or paste a URL", -1)),
1500
+ o("div", Ut, [
1501
+ o("button", {
1502
+ class: "text-sm px-3 py-1.5 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors",
1503
+ onMousedown: c[1] || (c[1] = m((x) => {
1504
+ var $;
1505
+ return ($ = a.value) == null ? void 0 : $.click();
1506
+ }, ["prevent"]))
1507
+ }, " Upload file ", 32),
1508
+ o("button", {
1509
+ class: "text-sm px-3 py-1.5 border border-gray-300 rounded hover:bg-gray-100 transition-colors",
1510
+ onMousedown: c[2] || (c[2] = m((x) => p.value = !p.value, ["prevent"]))
1511
+ }, " Paste URL ", 32)
1512
+ ]),
1513
+ p.value ? (g(), b("div", Ht, [
1514
+ _(o("input", {
1515
+ "onUpdate:modelValue": c[3] || (c[3] = (x) => n.value = x),
1516
+ type: "url",
1517
+ placeholder: "https://example.com/image.jpg",
1518
+ class: "flex-1 text-sm border border-gray-300 rounded px-3 py-1.5 outline-none focus:border-blue-500",
1519
+ onKeydown: d,
1520
+ onMousedown: c[4] || (c[4] = m(() => {
1521
+ }, ["stop"]))
1522
+ }, null, 544), [
1523
+ [F, n.value]
1524
+ ]),
1525
+ o("button", {
1526
+ class: "text-sm px-3 py-1.5 bg-blue-600 text-white rounded hover:bg-blue-700",
1527
+ onMousedown: m(v, ["prevent"])
1528
+ }, " Insert ", 32)
1529
+ ])) : T("", !0),
1530
+ o("input", {
1531
+ ref_key: "fileInput",
1532
+ ref: a,
1533
+ type: "file",
1534
+ accept: "image/*",
1535
+ class: "hidden",
1536
+ onChange: f
1537
+ }, null, 544)
1538
+ ]))
1539
+ ]));
1540
+ }
1541
+ }), jt = { class: "ae-video-block" }, zt = {
1542
+ key: 0,
1543
+ class: "relative group/vid"
1544
+ }, Nt = ["src"], Kt = {
1545
+ key: 1,
1546
+ class: "ae-video-empty border-2 border-dashed border-gray-300 rounded-lg p-8 flex flex-col items-center gap-3 bg-gray-50"
1547
+ }, Vt = { class: "w-full flex gap-2" }, qt = /* @__PURE__ */ A({
1548
+ __name: "VideoBlock",
1549
+ props: {
1550
+ block: {}
1551
+ },
1552
+ setup(l) {
1553
+ const e = l, t = E("alienEditor"), n = k("");
1554
+ function a() {
1555
+ const v = n.value.trim();
1556
+ v && (t.pushSnapshot(), t.updateBlock(e.block.id, { src: v }), n.value = "");
1557
+ }
1558
+ function p(v) {
1559
+ v.key === "Enter" && a();
1560
+ }
1561
+ function f() {
1562
+ t.pushSnapshot(), t.updateBlock(e.block.id, { src: "" });
1563
+ }
1564
+ return (v, d) => (g(), b("div", jt, [
1565
+ l.block.src ? (g(), b("div", zt, [
1566
+ o("video", {
1567
+ src: l.block.src,
1568
+ controls: "",
1569
+ class: H(["w-full rounded", l.block.classes])
1570
+ }, null, 10, Nt),
1571
+ o("button", {
1572
+ class: "absolute top-2 right-2 bg-red-600 text-white text-xs px-2 py-1 rounded opacity-0 group-hover/vid:opacity-100 transition-opacity",
1573
+ onMousedown: m(f, ["prevent"])
1574
+ }, " Remove ", 32)
1575
+ ])) : (g(), b("div", Kt, [
1576
+ d[2] || (d[2] = o("svg", {
1577
+ class: "w-10 h-10 text-gray-400",
1578
+ fill: "none",
1579
+ stroke: "currentColor",
1580
+ viewBox: "0 0 24 24"
1581
+ }, [
1582
+ o("path", {
1583
+ "stroke-linecap": "round",
1584
+ "stroke-linejoin": "round",
1585
+ "stroke-width": "1.5",
1586
+ d: "M15 10l4.553-2.069A1 1 0 0121 8.87v6.26a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"
1587
+ })
1588
+ ], -1)),
1589
+ d[3] || (d[3] = o("p", { class: "text-sm text-gray-500" }, "Paste a video URL", -1)),
1590
+ o("div", Vt, [
1591
+ _(o("input", {
1592
+ "onUpdate:modelValue": d[0] || (d[0] = (r) => n.value = r),
1593
+ type: "url",
1594
+ placeholder: "https://example.com/video.mp4",
1595
+ class: "flex-1 text-sm border border-gray-300 rounded px-3 py-1.5 outline-none focus:border-blue-500",
1596
+ onKeydown: p,
1597
+ onMousedown: d[1] || (d[1] = m(() => {
1598
+ }, ["stop"]))
1599
+ }, null, 544), [
1600
+ [F, n.value]
1601
+ ]),
1602
+ o("button", {
1603
+ class: "text-sm px-3 py-1.5 bg-blue-600 text-white rounded hover:bg-blue-700",
1604
+ onMousedown: m(a, ["prevent"])
1605
+ }, " Insert ", 32)
1606
+ ])
1607
+ ]))
1608
+ ]));
1609
+ }
1610
+ }), Ot = { class: "ae-code-block bg-gray-900 rounded-lg overflow-hidden" }, _t = { class: "flex items-center justify-between px-4 py-2 bg-gray-800 border-b border-gray-700" }, Ft = ["value"], Pt = ["value"], Wt = ["value"], Jt = /* @__PURE__ */ A({
1611
+ __name: "CodeBlock",
1612
+ props: {
1613
+ block: {}
1614
+ },
1615
+ setup(l) {
1616
+ const e = l, t = E("alienEditor"), n = [
1617
+ "plaintext",
1618
+ "javascript",
1619
+ "typescript",
1620
+ "html",
1621
+ "css",
1622
+ "scss",
1623
+ "python",
1624
+ "ruby",
1625
+ "php",
1626
+ "java",
1627
+ "go",
1628
+ "rust",
1629
+ "c",
1630
+ "cpp",
1631
+ "json",
1632
+ "yaml",
1633
+ "markdown",
1634
+ "bash",
1635
+ "shell",
1636
+ "sql"
1637
+ ];
1638
+ function a(v) {
1639
+ t.updateBlock(e.block.id, { code: v.target.value });
1640
+ }
1641
+ function p(v) {
1642
+ t.pushSnapshot(), t.updateBlock(e.block.id, { language: v.target.value });
1643
+ }
1644
+ function f() {
1645
+ t.activeBlockId.value = e.block.id;
1646
+ }
1647
+ return (v, d) => (g(), b("div", Ot, [
1648
+ o("div", _t, [
1649
+ o("select", {
1650
+ value: l.block.language,
1651
+ class: "bg-transparent text-gray-300 text-xs outline-none cursor-pointer",
1652
+ onChange: p,
1653
+ onMousedown: d[0] || (d[0] = m(() => {
1654
+ }, ["stop"]))
1655
+ }, [
1656
+ (g(), b(N, null, V(n, (r) => o("option", {
1657
+ key: r,
1658
+ value: r,
1659
+ class: "bg-gray-800"
1660
+ }, z(r), 9, Pt)), 64))
1661
+ ], 40, Ft),
1662
+ d[2] || (d[2] = o("div", { class: "flex gap-1.5" }, [
1663
+ o("div", { class: "w-3 h-3 rounded-full bg-red-500 opacity-70" }),
1664
+ o("div", { class: "w-3 h-3 rounded-full bg-yellow-500 opacity-70" }),
1665
+ o("div", { class: "w-3 h-3 rounded-full bg-green-500 opacity-70" })
1666
+ ], -1))
1667
+ ]),
1668
+ o("textarea", {
1669
+ value: l.block.code,
1670
+ class: "w-full bg-gray-900 text-gray-100 font-mono text-sm p-4 outline-none resize-none min-h-[120px] leading-relaxed",
1671
+ placeholder: "// Enter your code here...",
1672
+ spellcheck: "false",
1673
+ autocomplete: "off",
1674
+ autocorrect: "off",
1675
+ autocapitalize: "off",
1676
+ onInput: a,
1677
+ onFocus: f,
1678
+ onMousedown: d[1] || (d[1] = m(() => {
1679
+ }, ["stop"]))
1680
+ }, null, 40, Wt)
1681
+ ]));
1682
+ }
1683
+ }), Xt = /* @__PURE__ */ A({
1684
+ __name: "DividerBlock",
1685
+ props: {
1686
+ block: {}
1687
+ },
1688
+ setup(l) {
1689
+ return (e, t) => (g(), b("hr", {
1690
+ class: H(["ae-divider border-t border-gray-300 my-2 w-full", l.block.classes])
1691
+ }, null, 2));
1692
+ }
1693
+ }), Yt = { class: "ae-button-block" }, Zt = {
1694
+ key: 0,
1695
+ class: "flex flex-col gap-2 p-3 border border-gray-200 rounded-lg bg-gray-50"
1696
+ }, Gt = { class: "flex gap-2" }, Qt = { class: "flex gap-2 justify-end" }, eo = {
1697
+ key: 1,
1698
+ class: "flex items-center gap-2"
1699
+ }, to = ["href"], oo = /* @__PURE__ */ A({
1700
+ __name: "ButtonBlock",
1701
+ props: {
1702
+ block: {}
1703
+ },
1704
+ setup(l) {
1705
+ const e = l, t = E("alienEditor"), n = k(!1), a = k(e.block.label), p = k(e.block.href);
1706
+ function f() {
1707
+ a.value = e.block.label, p.value = e.block.href, n.value = !0;
1708
+ }
1709
+ function v() {
1710
+ t.pushSnapshot(), t.updateBlock(e.block.id, {
1711
+ label: a.value,
1712
+ href: p.value
1713
+ }), n.value = !1;
1714
+ }
1715
+ function d() {
1716
+ n.value = !1;
1717
+ }
1718
+ function r(u) {
1719
+ u.key === "Enter" && v(), u.key === "Escape" && d();
1720
+ }
1721
+ return (u, i) => (g(), b("div", Yt, [
1722
+ n.value ? (g(), b("div", Zt, [
1723
+ o("div", Gt, [
1724
+ _(o("input", {
1725
+ "onUpdate:modelValue": i[0] || (i[0] = (c) => a.value = c),
1726
+ type: "text",
1727
+ placeholder: "Button label",
1728
+ class: "flex-1 text-sm border border-gray-300 rounded px-3 py-1.5 outline-none focus:border-blue-500",
1729
+ onKeydown: r,
1730
+ onMousedown: i[1] || (i[1] = m(() => {
1731
+ }, ["stop"]))
1732
+ }, null, 544), [
1733
+ [F, a.value]
1734
+ ]),
1735
+ _(o("input", {
1736
+ "onUpdate:modelValue": i[2] || (i[2] = (c) => p.value = c),
1737
+ type: "url",
1738
+ placeholder: "https://...",
1739
+ class: "flex-1 text-sm border border-gray-300 rounded px-3 py-1.5 outline-none focus:border-blue-500",
1740
+ onKeydown: r,
1741
+ onMousedown: i[3] || (i[3] = m(() => {
1742
+ }, ["stop"]))
1743
+ }, null, 544), [
1744
+ [F, p.value]
1745
+ ])
1746
+ ]),
1747
+ o("div", Qt, [
1748
+ o("button", {
1749
+ class: "text-sm px-3 py-1 border border-gray-300 rounded hover:bg-gray-100",
1750
+ onMousedown: m(d, ["prevent"])
1751
+ }, " Cancel ", 32),
1752
+ o("button", {
1753
+ class: "text-sm px-3 py-1 bg-blue-600 text-white rounded hover:bg-blue-700",
1754
+ onMousedown: m(v, ["prevent"])
1755
+ }, " Save ", 32)
1756
+ ])
1757
+ ])) : (g(), b("div", eo, [
1758
+ o("a", {
1759
+ href: l.block.href,
1760
+ class: H(["inline-block", l.block.classes.length ? l.block.classes : ["px-4", "py-2", "bg-blue-600", "text-white", "rounded", "hover:bg-blue-700", "transition-colors"]]),
1761
+ onClick: i[4] || (i[4] = m(() => {
1762
+ }, ["prevent"]))
1763
+ }, z(l.block.label), 11, to),
1764
+ o("button", {
1765
+ class: "text-xs text-gray-400 hover:text-gray-600 underline",
1766
+ onMousedown: m(f, ["prevent"])
1767
+ }, " Edit ", 32)
1768
+ ]))
1769
+ ]));
1770
+ }
1771
+ }), no = /* @__PURE__ */ A({
1772
+ __name: "ModuleBlock",
1773
+ props: {
1774
+ block: {}
1775
+ },
1776
+ setup(l) {
1777
+ const e = l, t = E("alienEditor"), n = k(null);
1778
+ let a = null, p = !1;
1779
+ oe(() => {
1780
+ n.value && n.value.innerHTML !== e.block.html && (n.value.innerHTML = e.block.html);
1781
+ }), W(
1782
+ () => e.block.html,
1783
+ (d) => {
1784
+ n.value && !p && n.value.innerHTML !== d && (n.value.innerHTML = d);
1785
+ }
1786
+ );
1787
+ function f() {
1788
+ n.value && (p = !0, t.updateBlock(e.block.id, { html: n.value.innerHTML }), p = !1, a && clearTimeout(a), a = setTimeout(() => {
1789
+ t.pushSnapshot();
1790
+ }, 500));
1791
+ }
1792
+ function v() {
1793
+ t.activeBlockId.value = e.block.id;
1794
+ }
1795
+ return (d, r) => (g(), b("div", {
1796
+ ref_key: "el",
1797
+ ref: n,
1798
+ class: "ae-module-block outline-none",
1799
+ contenteditable: "true",
1800
+ spellcheck: "true",
1801
+ onInput: f,
1802
+ onFocus: v,
1803
+ onMousedown: r[0] || (r[0] = (u) => h(t).saveSelection()),
1804
+ onKeyup: r[1] || (r[1] = (u) => h(t).saveSelection())
1805
+ }, null, 544));
1806
+ }
1807
+ }), lo = { class: "ae-block-list" }, ro = /* @__PURE__ */ A({
1808
+ __name: "BlockList",
1809
+ setup(l) {
1810
+ const e = E("alienEditor");
1811
+ return (t, n) => (g(), b("div", lo, [
1812
+ (g(!0), b(N, null, V(h(e).blocks.value, (a) => (g(), U(ht, {
1813
+ key: a.id,
1814
+ block: a
1815
+ }, {
1816
+ default: D(() => [
1817
+ a.type === "paragraph" || a.type === "blockquote" ? (g(), U(kt, {
1818
+ key: 0,
1819
+ block: a
1820
+ }, null, 8, ["block"])) : a.type === "heading" ? (g(), U(Bt, {
1821
+ key: 1,
1822
+ block: a
1823
+ }, null, 8, ["block"])) : a.type === "ordered-list" || a.type === "unordered-list" ? (g(), U(Ct, {
1824
+ key: 2,
1825
+ block: a
1826
+ }, null, 8, ["block"])) : a.type === "image" ? (g(), U(Rt, {
1827
+ key: 3,
1828
+ block: a
1829
+ }, null, 8, ["block"])) : a.type === "video" ? (g(), U(qt, {
1830
+ key: 4,
1831
+ block: a
1832
+ }, null, 8, ["block"])) : a.type === "code" ? (g(), U(Jt, {
1833
+ key: 5,
1834
+ block: a
1835
+ }, null, 8, ["block"])) : a.type === "divider" ? (g(), U(Xt, {
1836
+ key: 6,
1837
+ block: a
1838
+ }, null, 8, ["block"])) : a.type === "button" ? (g(), U(oo, {
1839
+ key: 7,
1840
+ block: a
1841
+ }, null, 8, ["block"])) : a.type === "module" ? (g(), U(no, {
1842
+ key: 8,
1843
+ block: a
1844
+ }, null, 8, ["block"])) : T("", !0)
1845
+ ]),
1846
+ _: 2
1847
+ }, 1032, ["block"]))), 128))
1848
+ ]));
1849
+ }
1850
+ }), so = { class: "space-y-3" }, ao = { class: "flex gap-3 justify-end mt-6" }, io = ["disabled"], uo = /* @__PURE__ */ A({
1851
+ __name: "LinkModal",
1852
+ setup(l) {
1853
+ const e = E("alienEditor"), t = pe(e.savedRange), n = k(""), a = k("");
1854
+ W(e.showLinkModal, (d) => {
1855
+ d && (n.value = "", a.value = "");
1856
+ });
1857
+ function p() {
1858
+ n.value.trim() && (e.linkModalCallback.value ? e.linkModalCallback.value(n.value.trim(), a.value.trim()) : (e.pushSnapshot(), t.insertLink(n.value.trim(), a.value.trim())), f());
1859
+ }
1860
+ function f() {
1861
+ e.showLinkModal.value = !1, n.value = "", a.value = "";
1862
+ }
1863
+ function v(d) {
1864
+ d.key === "Enter" && p(), d.key === "Escape" && f();
1865
+ }
1866
+ return (d, r) => (g(), U(me, { to: "body" }, [
1867
+ h(e).showLinkModal.value ? (g(), b("div", {
1868
+ key: 0,
1869
+ class: "ae-modal-overlay fixed inset-0 bg-black/50 flex items-center justify-center z-[9999]",
1870
+ onMousedown: m(f, ["self"])
1871
+ }, [
1872
+ o("div", {
1873
+ class: "ae-modal bg-white rounded-xl shadow-2xl p-6 w-full max-w-md mx-4",
1874
+ onMousedown: r[2] || (r[2] = m(() => {
1875
+ }, ["stop"]))
1876
+ }, [
1877
+ r[5] || (r[5] = o("h3", { class: "text-lg font-semibold text-gray-900 mb-4" }, "Insert Link", -1)),
1878
+ o("div", so, [
1879
+ o("div", null, [
1880
+ r[3] || (r[3] = o("label", { class: "block text-sm font-medium text-gray-700 mb-1" }, "URL", -1)),
1881
+ _(o("input", {
1882
+ "onUpdate:modelValue": r[0] || (r[0] = (u) => n.value = u),
1883
+ type: "url",
1884
+ placeholder: "https://example.com",
1885
+ class: "w-full border border-gray-300 rounded-lg px-3 py-2 text-sm outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500",
1886
+ onKeydown: v
1887
+ }, null, 544), [
1888
+ [F, n.value]
1889
+ ])
1890
+ ]),
1891
+ o("div", null, [
1892
+ r[4] || (r[4] = o("label", { class: "block text-sm font-medium text-gray-700 mb-1" }, "Link text (optional)", -1)),
1893
+ _(o("input", {
1894
+ "onUpdate:modelValue": r[1] || (r[1] = (u) => a.value = u),
1895
+ type: "text",
1896
+ placeholder: "Leave empty to use URL as text",
1897
+ class: "w-full border border-gray-300 rounded-lg px-3 py-2 text-sm outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500",
1898
+ onKeydown: v
1899
+ }, null, 544), [
1900
+ [F, a.value]
1901
+ ])
1902
+ ])
1903
+ ]),
1904
+ o("div", ao, [
1905
+ o("button", {
1906
+ class: "px-4 py-2 text-sm border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors",
1907
+ onClick: f
1908
+ }, " Cancel "),
1909
+ o("button", {
1910
+ class: "px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors",
1911
+ disabled: !n.value.trim(),
1912
+ onClick: p
1913
+ }, " Insert Link ", 8, io)
1914
+ ])
1915
+ ], 32)
1916
+ ], 32)) : T("", !0)
1917
+ ]));
1918
+ }
1919
+ }), co = { class: "flex gap-3 justify-end mt-6" }, po = ["disabled"], fo = /* @__PURE__ */ A({
1920
+ __name: "ImageUrlModal",
1921
+ setup(l) {
1922
+ const e = E("alienEditor"), t = k("");
1923
+ W(e.showImageUrlModal, (f) => {
1924
+ f && (t.value = "");
1925
+ });
1926
+ function n() {
1927
+ if (t.value.trim()) {
1928
+ if (e.imageUrlCallback.value)
1929
+ e.imageUrlCallback.value(t.value.trim());
1930
+ else {
1931
+ const f = e.activeBlockId.value;
1932
+ f ? e.addBlockAfter(f, "image", { src: t.value.trim() }) : e.addBlockAt(e.blocks.value.length, "image", { src: t.value.trim() });
1933
+ }
1934
+ a();
1935
+ }
1936
+ }
1937
+ function a() {
1938
+ e.showImageUrlModal.value = !1, t.value = "";
1939
+ }
1940
+ function p(f) {
1941
+ f.key === "Enter" && n(), f.key === "Escape" && a();
1942
+ }
1943
+ return (f, v) => (g(), U(me, { to: "body" }, [
1944
+ h(e).showImageUrlModal.value ? (g(), b("div", {
1945
+ key: 0,
1946
+ class: "ae-modal-overlay fixed inset-0 bg-black/50 flex items-center justify-center z-[9999]",
1947
+ onMousedown: m(a, ["self"])
1948
+ }, [
1949
+ o("div", {
1950
+ class: "ae-modal bg-white rounded-xl shadow-2xl p-6 w-full max-w-md mx-4",
1951
+ onMousedown: v[1] || (v[1] = m(() => {
1952
+ }, ["stop"]))
1953
+ }, [
1954
+ v[3] || (v[3] = o("h3", { class: "text-lg font-semibold text-gray-900 mb-4" }, "Insert Image URL", -1)),
1955
+ o("div", null, [
1956
+ v[2] || (v[2] = o("label", { class: "block text-sm font-medium text-gray-700 mb-1" }, "Image URL", -1)),
1957
+ _(o("input", {
1958
+ "onUpdate:modelValue": v[0] || (v[0] = (d) => t.value = d),
1959
+ type: "url",
1960
+ placeholder: "https://example.com/image.jpg",
1961
+ class: "w-full border border-gray-300 rounded-lg px-3 py-2 text-sm outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500",
1962
+ onKeydown: p
1963
+ }, null, 544), [
1964
+ [F, t.value]
1965
+ ])
1966
+ ]),
1967
+ o("div", co, [
1968
+ o("button", {
1969
+ class: "px-4 py-2 text-sm border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors",
1970
+ onClick: a
1971
+ }, " Cancel "),
1972
+ o("button", {
1973
+ class: "px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors",
1974
+ disabled: !t.value.trim(),
1975
+ onClick: n
1976
+ }, " Insert Image ", 8, po)
1977
+ ])
1978
+ ], 32)
1979
+ ], 32)) : T("", !0)
1980
+ ]));
1981
+ }
1982
+ }), go = { class: "alien-editor ae-root border border-gray-200 rounded-xl bg-white shadow-sm" }, vo = {
1983
+ key: 0,
1984
+ class: "ae-edit-area min-h-[300px] px-8 py-6"
1985
+ }, bo = {
1986
+ key: 1,
1987
+ class: "ae-code-mode bg-gray-950 min-h-[300px] p-6"
1988
+ }, mo = ["value"], yo = {
1989
+ key: 2,
1990
+ class: "ae-preview-mode min-h-[300px] px-8 py-6 prose prose-gray max-w-none"
1991
+ }, xo = ["innerHTML"], ho = {
1992
+ key: 1,
1993
+ class: "text-gray-400 italic"
1994
+ }, ko = /* @__PURE__ */ A({
1995
+ __name: "AlienEditor",
1996
+ props: {
1997
+ modelValue: { default: "" },
1998
+ placeholder: { default: "Start writing..." },
1999
+ colors: { default: () => [] },
2000
+ modules: { default: () => [] }
2001
+ },
2002
+ emits: ["update:modelValue", "upload"],
2003
+ setup(l, { emit: e }) {
2004
+ const t = l, n = e, { blocks: a, mode: p, activeBlockId: f, savedRange: v } = Se(), { pushSnapshot: d, undo: r, redo: u, canUndo: i, canRedo: c } = Te(a), { saveSelection: x, restoreSelection: $ } = ye(v), { addBlockAfter: P, addBlockAt: K, removeBlock: I, moveBlock: w, updateBlock: L } = Ue(a, d), { dragState: C, onDragStart: M, onDragOver: s, onDragLeave: y, onDrop: q, onDragEnd: ne } = He(a, w), { serialize: xe } = Re(), { parse: se } = ze(), he = k(!1), ke = k(!1), we = k(null), $e = k(null), ee = Q(() => xe(a.value)), le = k("");
2005
+ let Y = null;
2006
+ W(p, (B, O) => {
2007
+ B === "code" ? le.value = ee.value : O === "code" && (Y && (clearTimeout(Y), Y = null), a.value = se(le.value));
2008
+ });
2009
+ function Me(B) {
2010
+ const O = B.target.value;
2011
+ le.value = O, Y && clearTimeout(Y), Y = setTimeout(() => {
2012
+ d(), a.value = se(O);
2013
+ }, 300);
2014
+ }
2015
+ let ae = !1;
2016
+ function fe(B) {
2017
+ const O = se(B);
2018
+ a.value = O;
2019
+ }
2020
+ oe(() => {
2021
+ fe(t.modelValue || ""), ae = !0;
2022
+ }), W(
2023
+ ee,
2024
+ (B) => {
2025
+ ae && n("update:modelValue", B);
2026
+ }
2027
+ ), W(
2028
+ () => t.modelValue,
2029
+ (B) => {
2030
+ if (!ae) return;
2031
+ const O = ee.value;
2032
+ B !== O && fe(B || "");
2033
+ }
2034
+ );
2035
+ function ge(B) {
2036
+ (B.ctrlKey || B.metaKey) && B.key === "z" && !B.shiftKey && (B.preventDefault(), r()), (B.ctrlKey || B.metaKey) && (B.key === "y" || B.shiftKey && B.key === "z") && (B.preventDefault(), u());
2037
+ }
2038
+ oe(() => document.addEventListener("keydown", ge)), Ce(() => document.removeEventListener("keydown", ge));
2039
+ const Be = {
2040
+ blocks: a,
2041
+ mode: p,
2042
+ activeBlockId: f,
2043
+ savedRange: v,
2044
+ colors: t.colors,
2045
+ modules: t.modules,
2046
+ placeholder: t.placeholder,
2047
+ pushSnapshot: d,
2048
+ undo: r,
2049
+ redo: u,
2050
+ canUndo: i,
2051
+ canRedo: c,
2052
+ updateBlock: L,
2053
+ addBlockAfter: P,
2054
+ addBlockAt: K,
2055
+ removeBlock: I,
2056
+ moveBlock: w,
2057
+ saveSelection: x,
2058
+ restoreSelection: $,
2059
+ onUpload: (B) => n("upload", B),
2060
+ showLinkModal: he,
2061
+ showImageUrlModal: ke,
2062
+ linkModalCallback: we,
2063
+ imageUrlCallback: $e,
2064
+ dragState: C,
2065
+ onDragStart: M,
2066
+ onDragOver: s,
2067
+ onDragLeave: y,
2068
+ onDrop: q,
2069
+ onDragEnd: ne
2070
+ };
2071
+ return Le("alienEditor", Be), (B, O) => (g(), b("div", go, [
2072
+ S(vt),
2073
+ h(p) === "edit" ? (g(), b("div", vo, [
2074
+ S(ro)
2075
+ ])) : h(p) === "code" ? (g(), b("div", bo, [
2076
+ o("textarea", {
2077
+ class: "w-full bg-transparent text-green-400 font-mono text-sm leading-relaxed resize-y outline-none min-h-[276px] whitespace-pre",
2078
+ value: le.value,
2079
+ onInput: Me,
2080
+ spellcheck: "false",
2081
+ autocomplete: "off",
2082
+ autocorrect: "off",
2083
+ autocapitalize: "off"
2084
+ }, null, 40, mo)
2085
+ ])) : (g(), b("div", yo, [
2086
+ ee.value ? (g(), b("div", {
2087
+ key: 0,
2088
+ innerHTML: ee.value
2089
+ }, null, 8, xo)) : (g(), b("p", ho, "Nothing to preview yet."))
2090
+ ])),
2091
+ S(uo),
2092
+ S(fo)
2093
+ ]));
2094
+ }
2095
+ }), $o = {
2096
+ install(l) {
2097
+ l.component("AlienEditor", ko);
2098
+ }
2099
+ };
2100
+ export {
2101
+ ko as AlienEditor,
2102
+ $o as default
2103
+ };