@sciexpr/vue 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,931 @@
1
+ import { ref as v, watch as q, shallowRef as te, defineComponent as B, useSlots as ae, openBlock as i, createElementBlock as d, normalizeClass as N, unref as S, toDisplayString as w, computed as F, inject as Y, provide as K, Fragment as C, renderList as $, createCommentVNode as M, renderSlot as oe, createTextVNode as le, createElementVNode as y, createBlock as G, Teleport as ne, normalizeStyle as H, withDirectives as D, vModelText as j, createVNode as se, nextTick as V, createStaticVNode as ce, vShow as Z, onMounted as ie, onUnmounted as re } from "vue";
2
+ import { KatexRenderer as Q, UnicodeRenderer as ue, MathMLRenderer as de } from "@sciexpr/renderer";
3
+ import { ParserRegistry as U } from "@sciexpr/parser";
4
+ import { AIPipeline as A } from "@sciexpr/ai";
5
+ import { ExpressionKind as me } from "@sciexpr/core";
6
+ function ut(e) {
7
+ const o = v(""), l = v(""), n = v(""), c = v(null), u = new U(), r = e.katexRenderer ?? new Q(), t = new ue(), s = new de();
8
+ function m(a) {
9
+ var b;
10
+ try {
11
+ const h = u.parse(a, { hint: "auto" });
12
+ if (!h || h.children.length === 0) {
13
+ o.value = "", c.value = null;
14
+ return;
15
+ }
16
+ const g = r.render(h, {
17
+ displayMode: e.displayMode,
18
+ ...e.renderOptions
19
+ });
20
+ o.value = g.value, (b = g.warnings) != null && b.length, l.value = s.render(h).value, n.value = t.render(h).value, c.value = null;
21
+ } catch (h) {
22
+ c.value = {
23
+ message: h instanceof Error ? h.message : String(h)
24
+ }, o.value = "";
25
+ }
26
+ }
27
+ return q(e.source, (a) => {
28
+ m(a);
29
+ }, { immediate: !0 }), {
30
+ html: o,
31
+ mathml: l,
32
+ unicode: n,
33
+ error: c,
34
+ render: m
35
+ };
36
+ }
37
+ function J(e) {
38
+ const o = v(""), l = v(null), n = te(null), c = new U(), u = new Q();
39
+ function r(t) {
40
+ var s;
41
+ try {
42
+ const m = c.parse(t, { hint: "auto" });
43
+ if (n.value = m, !m || m.children.length === 0) {
44
+ o.value = "", l.value = null;
45
+ return;
46
+ }
47
+ const a = u.render(m, {
48
+ displayMode: ((s = e.displayMode) == null ? void 0 : s.value) ?? !1
49
+ });
50
+ o.value = a.value, l.value = null;
51
+ } catch (m) {
52
+ l.value = {
53
+ message: m instanceof Error ? m.message : String(m)
54
+ }, o.value = t;
55
+ }
56
+ }
57
+ return q([e.source, e.displayMode ?? v(!1)], ([t]) => {
58
+ r(t);
59
+ }, { immediate: !0 }), { html: o, error: l, ast: n, render: r };
60
+ }
61
+ const pe = ["data-source"], be = ["title"], xe = ["innerHTML"], ve = /* @__PURE__ */ B({
62
+ __name: "Formula",
63
+ props: {
64
+ source: { default: "" },
65
+ displayMode: { type: Boolean, default: !1 },
66
+ throwOnError: { type: Boolean, default: !1 },
67
+ className: { default: "" },
68
+ fallbackText: { default: "" }
69
+ },
70
+ setup(e) {
71
+ var t, s, m;
72
+ const o = e, l = ae(), n = (m = (s = (t = l.default) == null ? void 0 : t.call(l)) == null ? void 0 : s[0]) == null ? void 0 : m.children, c = v(o.source || n || ""), { html: u, error: r } = J({
73
+ source: c,
74
+ displayMode: v(o.displayMode)
75
+ });
76
+ return (a, b) => (i(), d("span", {
77
+ class: N(["sciexpr-formula", o.className, {
78
+ "sciexpr-display": o.displayMode,
79
+ "sciexpr-error": S(r)
80
+ }]),
81
+ "data-source": c.value
82
+ }, [
83
+ S(r) ? (i(), d("span", {
84
+ key: 0,
85
+ class: "sciexpr-formula-error",
86
+ title: S(r).message
87
+ }, w(e.fallbackText || c.value), 9, be)) : (i(), d("span", {
88
+ key: 1,
89
+ innerHTML: S(u),
90
+ class: "sciexpr-formula-content"
91
+ }, null, 8, xe))
92
+ ], 10, pe));
93
+ }
94
+ }), E = (e, o) => {
95
+ const l = e.__vccOpts || e;
96
+ for (const [n, c] of o)
97
+ l[n] = c;
98
+ return l;
99
+ }, dt = /* @__PURE__ */ E(ve, [["__scopeId", "data-v-b2381271"]]);
100
+ function fe(e) {
101
+ const o = v(e.initialValue ?? ""), l = v(0), n = v(""), c = v(null), u = v(null), r = new U();
102
+ function t(g, I) {
103
+ o.value = g, I !== void 0 && (l.value = I);
104
+ }
105
+ function s(g) {
106
+ const I = o.value.slice(0, l.value), R = o.value.slice(l.value);
107
+ o.value = I + g + R, l.value += g.length;
108
+ }
109
+ function m(g, I) {
110
+ const R = o.value;
111
+ o.value = g + R + I, l.value = o.value.length;
112
+ }
113
+ function a() {
114
+ try {
115
+ const g = r.parse(o.value, { hint: "auto" });
116
+ return u.value = g, g;
117
+ } catch {
118
+ return u.value = null, null;
119
+ }
120
+ }
121
+ const b = F(() => o.value.trim().length === 0), h = F(() => o.value);
122
+ return {
123
+ // State
124
+ value: o,
125
+ cursor: l,
126
+ html: n,
127
+ ast: u,
128
+ error: c,
129
+ // Computed
130
+ isEmpty: b,
131
+ latexSource: h,
132
+ // Actions
133
+ handleInput: t,
134
+ insertText: s,
135
+ wrapSelection: m,
136
+ parse: a
137
+ };
138
+ }
139
+ function ye(e) {
140
+ const o = v([]), l = v(!1), n = v(0), c = v(""), u = e.pipeline ?? new A(), r = e.config ?? { enabled: !0, minTriggerLength: 2, maxItems: 10 };
141
+ async function t(b, h) {
142
+ if (!r.enabled) {
143
+ l.value = !1;
144
+ return;
145
+ }
146
+ const g = he(b, h);
147
+ if (!g || g.length < (r.minTriggerLength ?? 2)) {
148
+ l.value = !1;
149
+ return;
150
+ }
151
+ c.value = g;
152
+ const I = {
153
+ currentInput: b,
154
+ cursorPosition: h,
155
+ expressionType: me.Math
156
+ }, R = await u.getCompletions(I);
157
+ o.value = R.items.slice(0, r.maxItems ?? 10), l.value = o.value.length > 0, n.value = 0;
158
+ }
159
+ function s(b) {
160
+ return l.value = !1, b.text;
161
+ }
162
+ function m(b) {
163
+ b === "up" ? n.value = Math.max(0, n.value - 1) : n.value = Math.min(o.value.length - 1, n.value + 1);
164
+ }
165
+ function a() {
166
+ l.value = !1, o.value = [];
167
+ }
168
+ return {
169
+ suggestions: o,
170
+ visible: l,
171
+ selectedIndex: n,
172
+ query: c,
173
+ trigger: t,
174
+ select: s,
175
+ moveSelection: m,
176
+ close: a
177
+ };
178
+ }
179
+ function he(e, o) {
180
+ const l = e.slice(0, o), n = l.lastIndexOf("\\");
181
+ if (n !== -1) {
182
+ const r = l.slice(n).match(/^\\[a-zA-Z]*$/);
183
+ if (r) return r[0];
184
+ }
185
+ const c = l.match(/([a-zA-Z_]+)$/);
186
+ return c ? c[1] : "";
187
+ }
188
+ const O = Symbol("sciexpr-ai-pipeline");
189
+ function ge(e) {
190
+ const o = e ? new A(e) : Y(O, null);
191
+ function l(u) {
192
+ const r = new A(u);
193
+ K(O, r);
194
+ }
195
+ function n(u) {
196
+ o && K(O, new A({ completionProvider: u }));
197
+ }
198
+ function c(u) {
199
+ o && K(O, new A({ knowledgeBaseProvider: u }));
200
+ }
201
+ return {
202
+ pipeline: o,
203
+ provideAI: l,
204
+ setCompletionProvider: n,
205
+ setKnowledgeBase: c
206
+ };
207
+ }
208
+ const we = {
209
+ key: 0,
210
+ class: "sciexpr-toolbar-group-label"
211
+ }, ke = ["title", "disabled", "onClick"], Ce = /* @__PURE__ */ B({
212
+ __name: "Toolbar",
213
+ props: {
214
+ categories: {},
215
+ disabled: { type: Boolean },
216
+ compact: { type: Boolean }
217
+ },
218
+ emits: ["insert"],
219
+ setup(e, { emit: o }) {
220
+ const l = o, n = [
221
+ {
222
+ id: "fraction",
223
+ label: "Fraction & Script",
224
+ icon: "📐",
225
+ commands: [
226
+ { latex: "\\frac{}{}", label: "⅟", description: "Fraction" },
227
+ { latex: "^{}", label: "x²", description: "Superscript" },
228
+ { latex: "_{}", label: "x₂", description: "Subscript" },
229
+ { latex: "^{}_{}", label: "x²₁", description: "Both scripts" }
230
+ ]
231
+ },
232
+ {
233
+ id: "radical",
234
+ label: "Radicals",
235
+ icon: "√",
236
+ commands: [
237
+ { latex: "\\sqrt{}", label: "√x", description: "Square root" },
238
+ { latex: "\\sqrt[3]{}", label: "∛x", description: "Cube root" },
239
+ { latex: "\\sqrt[n]{}", label: "ⁿ√x", description: "Nth root" }
240
+ ]
241
+ },
242
+ {
243
+ id: "symbol",
244
+ label: "Operators",
245
+ icon: "∑",
246
+ commands: [
247
+ { latex: "\\sum_{}^{}", label: "∑", description: "Summation" },
248
+ { latex: "\\prod_{}^{}", label: "∏", description: "Product" },
249
+ { latex: "\\int_{}^{}", label: "∫", description: "Integral" },
250
+ { latex: "\\lim_{x \\to }{}", label: "lim", description: "Limit" },
251
+ { latex: "\\infty", label: "∞", description: "Infinity" },
252
+ { latex: "\\partial", label: "∂", description: "Partial derivative" }
253
+ ]
254
+ },
255
+ {
256
+ id: "greek",
257
+ label: "Greek",
258
+ icon: "α",
259
+ commands: [
260
+ { latex: "\\alpha", label: "α", description: "Alpha" },
261
+ { latex: "\\beta", label: "β", description: "Beta" },
262
+ { latex: "\\gamma", label: "γ", description: "Gamma" },
263
+ { latex: "\\delta", label: "δ", description: "Delta" },
264
+ { latex: "\\theta", label: "θ", description: "Theta" },
265
+ { latex: "\\lambda", label: "λ", description: "Lambda" },
266
+ { latex: "\\mu", label: "μ", description: "Mu" },
267
+ { latex: "\\pi", label: "π", description: "Pi" },
268
+ { latex: "\\sigma", label: "σ", description: "Sigma" },
269
+ { latex: "\\phi", label: "φ", description: "Phi" },
270
+ { latex: "\\omega", label: "ω", description: "Omega" }
271
+ ]
272
+ },
273
+ {
274
+ id: "matrix",
275
+ label: "Matrix",
276
+ icon: "▦",
277
+ commands: [
278
+ { latex: "\\begin{pmatrix} & \\\\ & \\end{pmatrix}", label: "( )", description: "pmatrix" },
279
+ { latex: "\\begin{bmatrix} & \\\\ & \\end{bmatrix}", label: "[ ]", description: "bmatrix" },
280
+ { latex: "\\begin{vmatrix} & \\\\ & \\end{vmatrix}", label: "| |", description: "vmatrix" }
281
+ ]
282
+ },
283
+ {
284
+ id: "chemistry",
285
+ label: "Chemistry",
286
+ icon: "⚗",
287
+ commands: [
288
+ { latex: "\\ce{H2O}", label: "H₂O", description: "Water" },
289
+ { latex: "\\ce{->}", label: "→", description: "Reaction arrow" },
290
+ { latex: "\\ce{<=>}", label: "⇌", description: "Equilibrium" },
291
+ { latex: "^{n+}", label: "ⁿ⁺", description: "Charge" }
292
+ ]
293
+ }
294
+ ];
295
+ function c(u) {
296
+ l("insert", u);
297
+ }
298
+ return (u, r) => (i(), d("div", {
299
+ class: N(["sciexpr-toolbar", { "sciexpr-toolbar-compact": e.compact }]),
300
+ role: "toolbar",
301
+ "aria-label": "Formula toolbar"
302
+ }, [
303
+ (i(), d(C, null, $(n, (t) => (i(), d(C, {
304
+ key: t.id
305
+ }, [
306
+ !e.categories || e.categories.includes(t.id) ? (i(), d("div", {
307
+ key: 0,
308
+ class: N(["sciexpr-toolbar-group", { "sciexpr-toolbar-group-compact": e.compact }])
309
+ }, [
310
+ e.compact ? M("", !0) : (i(), d("span", we, w(t.icon) + " " + w(t.label), 1)),
311
+ (i(!0), d(C, null, $(t.commands, (s) => (i(), d("button", {
312
+ key: s.latex,
313
+ class: N(["sciexpr-toolbar-btn", { "sciexpr-toolbar-btn-compact": e.compact }]),
314
+ title: s.description,
315
+ disabled: e.disabled,
316
+ type: "button",
317
+ onClick: (m) => c(s.latex)
318
+ }, [
319
+ oe(u.$slots, `btn-${s.label}`, { command: s }, () => [
320
+ le(w(s.label), 1)
321
+ ], !0)
322
+ ], 10, ke))), 128))
323
+ ], 2)) : M("", !0)
324
+ ], 64))), 64))
325
+ ], 2));
326
+ }
327
+ }), Se = /* @__PURE__ */ E(Ce, [["__scopeId", "data-v-329eccb9"]]), Ne = {
328
+ key: 0,
329
+ class: "sciexpr-preview-error"
330
+ }, _e = {
331
+ key: 1,
332
+ class: "sciexpr-preview-render"
333
+ }, $e = ["innerHTML"], Me = {
334
+ key: 2,
335
+ class: "sciexpr-preview-empty"
336
+ }, Ie = {
337
+ key: 3,
338
+ class: "sciexpr-preview-source"
339
+ }, Le = /* @__PURE__ */ B({
340
+ __name: "LivePreview",
341
+ props: {
342
+ source: {},
343
+ displayMode: { type: Boolean, default: !1 },
344
+ showSource: { type: Boolean, default: !1 }
345
+ },
346
+ setup(e) {
347
+ const o = e, l = v(o.source), n = v(o.displayMode);
348
+ q(() => o.source, (r) => {
349
+ l.value = r;
350
+ }), q(() => o.displayMode, (r) => {
351
+ n.value = r;
352
+ });
353
+ const { html: c, error: u } = J({
354
+ source: l,
355
+ displayMode: n
356
+ });
357
+ return (r, t) => (i(), d("div", {
358
+ class: N(["sciexpr-preview", { "sciexpr-preview-display": e.displayMode }])
359
+ }, [
360
+ S(u) ? (i(), d("div", Ne, [
361
+ t[0] || (t[0] = y("span", { class: "sciexpr-preview-error-icon" }, "⚠", -1)),
362
+ y("span", null, w(S(u).message), 1)
363
+ ])) : S(c) ? (i(), d("div", _e, [
364
+ y("span", { innerHTML: S(c) }, null, 8, $e)
365
+ ])) : (i(), d("div", Me, [...t[1] || (t[1] = [
366
+ y("span", { class: "sciexpr-preview-empty-text" }, "Preview", -1)
367
+ ])])),
368
+ e.showSource && e.source ? (i(), d("div", Ie, [
369
+ y("code", null, w(e.source), 1)
370
+ ])) : M("", !0)
371
+ ], 2));
372
+ }
373
+ }), Pe = /* @__PURE__ */ E(Le, [["__scopeId", "data-v-b3730bc4"]]), Te = ["aria-selected", "onClick", "onMouseenter"], Re = { class: "sciexpr-autocomplete-label" }, Be = {
374
+ key: 0,
375
+ class: "sciexpr-autocomplete-desc"
376
+ }, Ee = {
377
+ key: 1,
378
+ class: "sciexpr-autocomplete-source"
379
+ }, Ae = /* @__PURE__ */ B({
380
+ __name: "AutocompleteDropdown",
381
+ props: {
382
+ items: {},
383
+ visible: { type: Boolean },
384
+ selectedIndex: {},
385
+ position: {}
386
+ },
387
+ emits: ["select", "close"],
388
+ setup(e, { emit: o }) {
389
+ const l = o, n = Y(O, null);
390
+ function c(r) {
391
+ l("select", r);
392
+ }
393
+ function u(r) {
394
+ return {
395
+ symbol: "#0d6efd",
396
+ command: "#6f42c1",
397
+ template: "#198754",
398
+ correction: "#fd7e14",
399
+ formula: "#d63384"
400
+ }[r] ?? "#6c757d";
401
+ }
402
+ return (r, t) => (i(), G(ne, { to: "body" }, [
403
+ e.visible && e.items.length > 0 ? (i(), d("div", {
404
+ key: 0,
405
+ class: "sciexpr-autocomplete",
406
+ style: H(e.position ? { top: e.position.top + "px", left: e.position.left + "px" } : {}),
407
+ role: "listbox"
408
+ }, [
409
+ (i(!0), d(C, null, $(e.items, (s, m) => (i(), d("div", {
410
+ key: `${s.text}-${m}`,
411
+ class: N(["sciexpr-autocomplete-item", { selected: m === e.selectedIndex }]),
412
+ role: "option",
413
+ "aria-selected": m === e.selectedIndex,
414
+ onClick: (a) => c(s),
415
+ onMouseenter: (a) => r.$emit("select", s)
416
+ }, [
417
+ y("span", {
418
+ class: "sciexpr-autocomplete-category",
419
+ style: H({ background: u(s.category) })
420
+ }, w(s.category), 5),
421
+ y("span", Re, w(s.label), 1),
422
+ s.description ? (i(), d("span", Be, w(s.description), 1)) : M("", !0),
423
+ S(n) ? (i(), d("span", Ee, w(s.previewHtml ? "AI" : ""), 1)) : M("", !0)
424
+ ], 42, Te))), 128))
425
+ ], 4)) : M("", !0)
426
+ ]));
427
+ }
428
+ }), Oe = /* @__PURE__ */ E(Ae, [["__scopeId", "data-v-d18e03d1"]]), qe = { class: "sciexpr-editor-input-wrap" }, Fe = ["placeholder", "readonly", "rows"], He = /* @__PURE__ */ B({
429
+ __name: "FormulaEditor",
430
+ props: {
431
+ value: { default: "" },
432
+ displayMode: { type: Boolean, default: !1 },
433
+ readonly: { type: Boolean, default: !1 },
434
+ placeholder: { default: "Type LaTeX or chemical formula..." },
435
+ toolbar: {},
436
+ autocomplete: {},
437
+ showPreview: { type: Boolean, default: !0 },
438
+ showToolbar: { type: Boolean, default: !0 },
439
+ rows: { default: 3 }
440
+ },
441
+ emits: ["update:value", "change", "error"],
442
+ setup(e, { emit: o }) {
443
+ const l = e, n = o, c = v(null), u = v(null), r = v({ top: 0, left: 0 }), t = v(l.value);
444
+ q(() => l.value, (p) => {
445
+ t.value = p;
446
+ });
447
+ const s = fe({ initialValue: t.value }), { pipeline: m } = ge(), a = ye({
448
+ config: l.autocomplete,
449
+ pipeline: m
450
+ });
451
+ function b(p) {
452
+ const x = p.target, f = x.value, k = x.selectionStart;
453
+ t.value = f, s.value.value = f, s.cursor.value = k, n("update:value", f), n("change", f), a.trigger(f, k), W();
454
+ }
455
+ function h(p) {
456
+ if (a.visible.value) {
457
+ if (p.key === "ArrowDown") {
458
+ p.preventDefault(), a.moveSelection("down");
459
+ return;
460
+ }
461
+ if (p.key === "ArrowUp") {
462
+ p.preventDefault(), a.moveSelection("up");
463
+ return;
464
+ }
465
+ if (p.key === "Enter" || p.key === "Tab") {
466
+ p.preventDefault();
467
+ const x = a.suggestions.value[a.selectedIndex.value];
468
+ x && z(x.text);
469
+ return;
470
+ }
471
+ if (p.key === "Escape") {
472
+ a.close();
473
+ return;
474
+ }
475
+ }
476
+ (p.ctrlKey || p.metaKey) && (p.key === "b" && (p.preventDefault(), ee("\\mathbf{", "}")), p.key === "/" && (p.preventDefault(), R("\\frac{}{}")));
477
+ }
478
+ function g(p) {
479
+ R(p);
480
+ }
481
+ function I(p) {
482
+ z(p.text);
483
+ }
484
+ function R(p) {
485
+ const x = c.value;
486
+ if (!x) return;
487
+ const f = x.selectionStart, k = x.selectionEnd, L = t.value.slice(0, f), P = t.value.slice(k);
488
+ t.value = L + p + P, n("update:value", t.value), V(() => {
489
+ x.focus();
490
+ const _ = f + p.length;
491
+ x.setSelectionRange(_, _), a.close();
492
+ });
493
+ }
494
+ function z(p) {
495
+ const x = c.value;
496
+ if (!x) return;
497
+ const f = x.selectionStart, k = t.value.slice(0, f), L = k.lastIndexOf("\\");
498
+ let P;
499
+ if (L !== -1 && f - L < 30)
500
+ P = L;
501
+ else {
502
+ const T = k.match(/([a-zA-Z_]+)$/);
503
+ P = T ? f - T[0].length : f;
504
+ }
505
+ const _ = t.value.slice(f);
506
+ t.value = t.value.slice(0, P) + p + _, n("update:value", t.value), V(() => {
507
+ x.focus();
508
+ const T = P + p.length;
509
+ x.setSelectionRange(T, T), a.close();
510
+ });
511
+ }
512
+ function ee(p, x) {
513
+ const f = c.value;
514
+ if (!f) return;
515
+ const k = f.selectionStart, L = f.selectionEnd, P = t.value.slice(k, L) || "", _ = t.value.slice(0, k) + p + P + x + t.value.slice(L);
516
+ t.value = _, n("update:value", _), V(() => {
517
+ f.focus();
518
+ const T = k + p.length + P.length;
519
+ f.setSelectionRange(T, T);
520
+ });
521
+ }
522
+ function W() {
523
+ const p = c.value;
524
+ if (!p) return;
525
+ const x = p.getBoundingClientRect(), f = p.selectionStart, k = 20, L = 8, _ = t.value.slice(0, f).split(`
526
+ `), T = _[_.length - 1].length;
527
+ r.value = {
528
+ top: x.top + _.length * k + 24 + window.scrollY,
529
+ left: x.left + T * L + window.scrollX
530
+ };
531
+ }
532
+ return F(() => t.value.trim().length > 0), (p, x) => {
533
+ var f;
534
+ return i(), d("div", {
535
+ ref_key: "editorRef",
536
+ ref: u,
537
+ class: N(["sciexpr-editor", { "sciexpr-editor-display": e.displayMode }])
538
+ }, [
539
+ e.showToolbar && !e.readonly ? (i(), G(Se, {
540
+ key: 0,
541
+ categories: (f = e.toolbar) == null ? void 0 : f.categories,
542
+ onInsert: g
543
+ }, null, 8, ["categories"])) : M("", !0),
544
+ y("div", qe, [
545
+ D(y("textarea", {
546
+ ref_key: "textareaRef",
547
+ ref: c,
548
+ "onUpdate:modelValue": x[0] || (x[0] = (k) => t.value = k),
549
+ class: N(["sciexpr-editor-textarea", {
550
+ "sciexpr-editor-textarea-display": e.displayMode,
551
+ "sciexpr-editor-textarea-readonly": e.readonly
552
+ }]),
553
+ placeholder: e.placeholder,
554
+ readonly: e.readonly,
555
+ rows: e.rows,
556
+ "aria-label": "Formula input",
557
+ spellcheck: "false",
558
+ autocomplete: "off",
559
+ autocorrect: "off",
560
+ autocapitalize: "off",
561
+ onInput: b,
562
+ onKeydown: h,
563
+ onFocus: W
564
+ }, null, 42, Fe), [
565
+ [j, t.value]
566
+ ])
567
+ ]),
568
+ se(Oe, {
569
+ items: S(a).suggestions.value,
570
+ visible: S(a).visible.value,
571
+ "selected-index": S(a).selectedIndex.value,
572
+ position: r.value,
573
+ onSelect: I,
574
+ onClose: x[1] || (x[1] = (k) => S(a).close())
575
+ }, null, 8, ["items", "visible", "selected-index", "position"]),
576
+ e.showPreview ? (i(), G(Pe, {
577
+ key: 1,
578
+ source: t.value,
579
+ "display-mode": e.displayMode,
580
+ "show-source": !1
581
+ }, null, 8, ["source", "display-mode"])) : M("", !0)
582
+ ], 2);
583
+ };
584
+ }
585
+ }), mt = /* @__PURE__ */ E(He, [["__scopeId", "data-v-d6181c80"]]), De = { class: "sciexpr-symbol-panel" }, Ke = { class: "sciexpr-symbol-search" }, Ve = { class: "sciexpr-symbol-tabs" }, Ge = ["onClick"], Ue = { class: "sciexpr-symbol-grid" }, ze = ["title", "disabled", "onClick"], We = { class: "sciexpr-symbol-unicode" }, Ze = { class: "sciexpr-symbol-name" }, Xe = ["title", "disabled", "onClick"], Ye = { class: "sciexpr-symbol-unicode" }, je = { class: "sciexpr-symbol-name" }, Qe = /* @__PURE__ */ B({
586
+ __name: "SymbolPanel",
587
+ props: {
588
+ disabled: { type: Boolean }
589
+ },
590
+ emits: ["insert"],
591
+ setup(e, { emit: o }) {
592
+ const l = o, n = [
593
+ {
594
+ id: "greek-lower",
595
+ label: "Greek Lowercase",
596
+ symbols: [
597
+ { latex: "\\alpha", unicode: "α", name: "alpha" },
598
+ { latex: "\\beta", unicode: "β", name: "beta" },
599
+ { latex: "\\gamma", unicode: "γ", name: "gamma" },
600
+ { latex: "\\delta", unicode: "δ", name: "delta" },
601
+ { latex: "\\epsilon", unicode: "ε", name: "epsilon" },
602
+ { latex: "\\zeta", unicode: "ζ", name: "zeta" },
603
+ { latex: "\\eta", unicode: "η", name: "eta" },
604
+ { latex: "\\theta", unicode: "θ", name: "theta" },
605
+ { latex: "\\iota", unicode: "ι", name: "iota" },
606
+ { latex: "\\kappa", unicode: "κ", name: "kappa" },
607
+ { latex: "\\lambda", unicode: "λ", name: "lambda" },
608
+ { latex: "\\mu", unicode: "μ", name: "mu" },
609
+ { latex: "\\nu", unicode: "ν", name: "nu" },
610
+ { latex: "\\xi", unicode: "ξ", name: "xi" },
611
+ { latex: "\\pi", unicode: "π", name: "pi" },
612
+ { latex: "\\rho", unicode: "ρ", name: "rho" },
613
+ { latex: "\\sigma", unicode: "σ", name: "sigma" },
614
+ { latex: "\\tau", unicode: "τ", name: "tau" },
615
+ { latex: "\\phi", unicode: "φ", name: "phi" },
616
+ { latex: "\\chi", unicode: "χ", name: "chi" },
617
+ { latex: "\\psi", unicode: "ψ", name: "psi" },
618
+ { latex: "\\omega", unicode: "ω", name: "omega" }
619
+ ]
620
+ },
621
+ {
622
+ id: "greek-upper",
623
+ label: "Greek Uppercase",
624
+ symbols: [
625
+ { latex: "\\Gamma", unicode: "Γ", name: "Gamma" },
626
+ { latex: "\\Delta", unicode: "Δ", name: "Delta" },
627
+ { latex: "\\Theta", unicode: "Θ", name: "Theta" },
628
+ { latex: "\\Lambda", unicode: "Λ", name: "Lambda" },
629
+ { latex: "\\Xi", unicode: "Ξ", name: "Xi" },
630
+ { latex: "\\Pi", unicode: "Π", name: "Pi" },
631
+ { latex: "\\Sigma", unicode: "Σ", name: "Sigma" },
632
+ { latex: "\\Upsilon", unicode: "Υ", name: "Upsilon" },
633
+ { latex: "\\Phi", unicode: "Φ", name: "Phi" },
634
+ { latex: "\\Psi", unicode: "Ψ", name: "Psi" },
635
+ { latex: "\\Omega", unicode: "Ω", name: "Omega" }
636
+ ]
637
+ },
638
+ {
639
+ id: "operators",
640
+ label: "Operators & Relations",
641
+ symbols: [
642
+ { latex: "\\times", unicode: "×", name: "times" },
643
+ { latex: "\\div", unicode: "÷", name: "divide" },
644
+ { latex: "\\cdot", unicode: "·", name: "dot" },
645
+ { latex: "\\pm", unicode: "±", name: "plus-minus" },
646
+ { latex: "\\mp", unicode: "∓", name: "minus-plus" },
647
+ { latex: "\\leq", unicode: "≤", name: "leq" },
648
+ { latex: "\\geq", unicode: "≥", name: "geq" },
649
+ { latex: "\\neq", unicode: "≠", name: "neq" },
650
+ { latex: "\\approx", unicode: "≈", name: "approx" },
651
+ { latex: "\\equiv", unicode: "≡", name: "equiv" },
652
+ { latex: "\\sim", unicode: "∼", name: "sim" },
653
+ { latex: "\\propto", unicode: "∝", name: "propto" },
654
+ { latex: "\\ll", unicode: "≪", name: "ll" },
655
+ { latex: "\\gg", unicode: "≫", name: "gg" }
656
+ ]
657
+ },
658
+ {
659
+ id: "arrows",
660
+ label: "Arrows",
661
+ symbols: [
662
+ { latex: "\\to", unicode: "→", name: "to" },
663
+ { latex: "\\rightarrow", unicode: "→", name: "rightarrow" },
664
+ { latex: "\\leftarrow", unicode: "←", name: "leftarrow" },
665
+ { latex: "\\Rightarrow", unicode: "⇒", name: "Rightarrow" },
666
+ { latex: "\\Leftarrow", unicode: "⇐", name: "Leftarrow" },
667
+ { latex: "\\Leftrightarrow", unicode: "⇔", name: "Leftrightarrow" },
668
+ { latex: "\\mapsto", unicode: "↦", name: "mapsto" },
669
+ { latex: "\\uparrow", unicode: "↑", name: "uparrow" },
670
+ { latex: "\\downarrow", unicode: "↓", name: "downarrow" }
671
+ ]
672
+ },
673
+ {
674
+ id: "misc",
675
+ label: "Misc",
676
+ symbols: [
677
+ { latex: "\\infty", unicode: "∞", name: "infinity" },
678
+ { latex: "\\partial", unicode: "∂", name: "partial" },
679
+ { latex: "\\nabla", unicode: "∇", name: "nabla" },
680
+ { latex: "\\forall", unicode: "∀", name: "forall" },
681
+ { latex: "\\exists", unicode: "∃", name: "exists" },
682
+ { latex: "\\emptyset", unicode: "∅", name: "emptyset" },
683
+ { latex: "\\neg", unicode: "¬", name: "neg" },
684
+ { latex: "\\angle", unicode: "∠", name: "angle" },
685
+ { latex: "\\triangle", unicode: "△", name: "triangle" },
686
+ { latex: "\\square", unicode: "□", name: "square" },
687
+ { latex: "\\circ", unicode: "∘", name: "circle" },
688
+ { latex: "\\star", unicode: "★", name: "star" }
689
+ ]
690
+ },
691
+ {
692
+ id: "chemistry",
693
+ label: "Chemistry",
694
+ symbols: [
695
+ { latex: "\\ce{H2O}", unicode: "H₂O", name: "Water" },
696
+ { latex: "\\ce{CO2}", unicode: "CO₂", name: "Carbon dioxide" },
697
+ { latex: "\\ce{->}", unicode: "→", name: "Arrow right" },
698
+ { latex: "\\ce{<-}", unicode: "←", name: "Arrow left" },
699
+ { latex: "\\ce{<=>}", unicode: "⇌", name: "Equilibrium" },
700
+ { latex: "\\ce{<->}", unicode: "⇄", name: "Resonance" },
701
+ { latex: "\\ce{->[H2O]}", unicode: "→[H₂O]", name: "With condition" }
702
+ ]
703
+ }
704
+ ], c = v(n[0].id), u = v(""), r = F(() => {
705
+ if (!u.value) return n;
706
+ const s = u.value.toLowerCase();
707
+ return n.map((m) => ({
708
+ ...m,
709
+ symbols: m.symbols.filter(
710
+ (a) => a.name.toLowerCase().includes(s) || a.latex.toLowerCase().includes(s)
711
+ )
712
+ })).filter((m) => m.symbols.length > 0);
713
+ });
714
+ function t(s) {
715
+ l("insert", s);
716
+ }
717
+ return (s, m) => (i(), d("div", De, [
718
+ y("div", Ke, [
719
+ D(y("input", {
720
+ "onUpdate:modelValue": m[0] || (m[0] = (a) => u.value = a),
721
+ type: "text",
722
+ class: "sciexpr-symbol-search-input",
723
+ placeholder: "Search symbols..."
724
+ }, null, 512), [
725
+ [j, u.value]
726
+ ])
727
+ ]),
728
+ y("div", Ve, [
729
+ (i(), d(C, null, $(n, (a) => y("button", {
730
+ key: a.id,
731
+ class: N(["sciexpr-symbol-tab", { active: c.value === a.id }]),
732
+ onClick: (b) => c.value = a.id,
733
+ type: "button"
734
+ }, w(a.label), 11, Ge)), 64))
735
+ ]),
736
+ y("div", Ue, [
737
+ u.value ? (i(!0), d(C, { key: 0 }, $(r.value, (a) => (i(), d(C, {
738
+ key: a.id
739
+ }, [
740
+ (i(!0), d(C, null, $(a.symbols, (b) => (i(), d("button", {
741
+ key: b.latex,
742
+ class: N(["sciexpr-symbol-btn", { "sciexpr-symbol-btn-disabled": e.disabled }]),
743
+ title: `${b.name} — ${b.latex}`,
744
+ disabled: e.disabled,
745
+ type: "button",
746
+ onClick: (h) => t(b.latex)
747
+ }, [
748
+ y("span", We, w(b.unicode), 1),
749
+ y("span", Ze, w(b.name), 1)
750
+ ], 10, ze))), 128))
751
+ ], 64))), 128)) : (i(), d(C, { key: 1 }, $(n, (a) => (i(), d(C, {
752
+ key: a.id
753
+ }, [
754
+ c.value === a.id ? (i(!0), d(C, { key: 0 }, $(a.symbols, (b) => (i(), d("button", {
755
+ key: b.latex,
756
+ class: N(["sciexpr-symbol-btn", { "sciexpr-symbol-btn-disabled": e.disabled }]),
757
+ title: `${b.name} — ${b.latex}`,
758
+ disabled: e.disabled,
759
+ type: "button",
760
+ onClick: (h) => t(b.latex)
761
+ }, [
762
+ y("span", Ye, w(b.unicode), 1),
763
+ y("span", je, w(b.name), 1)
764
+ ], 10, Xe))), 128)) : M("", !0)
765
+ ], 64))), 64))
766
+ ])
767
+ ]));
768
+ }
769
+ }), pt = /* @__PURE__ */ E(Qe, [["__scopeId", "data-v-8a9ec119"]]), Je = { class: "sciexpr-element-grid" }, et = ["title", "disabled", "onClick"], tt = {
770
+ key: 0,
771
+ class: "sciexpr-element-number"
772
+ }, at = {
773
+ key: 1,
774
+ class: "sciexpr-element-symbol"
775
+ }, X = 18, ot = 6, lt = /* @__PURE__ */ B({
776
+ __name: "ElementTable",
777
+ props: {
778
+ disabled: { type: Boolean },
779
+ compact: { type: Boolean }
780
+ },
781
+ emits: ["insert"],
782
+ setup(e, { emit: o }) {
783
+ const l = o, n = [
784
+ // Row 1
785
+ { symbol: "H", name: "Hydrogen", atomicNumber: 1, row: 1, col: 1, block: "s" },
786
+ { symbol: "He", name: "Helium", atomicNumber: 2, row: 1, col: 18, block: "s" },
787
+ // Row 2
788
+ { symbol: "Li", name: "Lithium", atomicNumber: 3, row: 2, col: 1, block: "s" },
789
+ { symbol: "Be", name: "Beryllium", atomicNumber: 4, row: 2, col: 2, block: "s" },
790
+ { symbol: "B", name: "Boron", atomicNumber: 5, row: 2, col: 13, block: "p" },
791
+ { symbol: "C", name: "Carbon", atomicNumber: 6, row: 2, col: 14, block: "p" },
792
+ { symbol: "N", name: "Nitrogen", atomicNumber: 7, row: 2, col: 15, block: "p" },
793
+ { symbol: "O", name: "Oxygen", atomicNumber: 8, row: 2, col: 16, block: "p" },
794
+ { symbol: "F", name: "Fluorine", atomicNumber: 9, row: 2, col: 17, block: "p" },
795
+ { symbol: "Ne", name: "Neon", atomicNumber: 10, row: 2, col: 18, block: "p" },
796
+ // Row 3
797
+ { symbol: "Na", name: "Sodium", atomicNumber: 11, row: 3, col: 1, block: "s" },
798
+ { symbol: "Mg", name: "Magnesium", atomicNumber: 12, row: 3, col: 2, block: "s" },
799
+ { symbol: "Al", name: "Aluminium", atomicNumber: 13, row: 3, col: 13, block: "p" },
800
+ { symbol: "Si", name: "Silicon", atomicNumber: 14, row: 3, col: 14, block: "p" },
801
+ { symbol: "P", name: "Phosphorus", atomicNumber: 15, row: 3, col: 15, block: "p" },
802
+ { symbol: "S", name: "Sulfur", atomicNumber: 16, row: 3, col: 16, block: "p" },
803
+ { symbol: "Cl", name: "Chlorine", atomicNumber: 17, row: 3, col: 17, block: "p" },
804
+ { symbol: "Ar", name: "Argon", atomicNumber: 18, row: 3, col: 18, block: "p" },
805
+ // Row 4
806
+ { symbol: "K", name: "Potassium", atomicNumber: 19, row: 4, col: 1, block: "s" },
807
+ { symbol: "Ca", name: "Calcium", atomicNumber: 20, row: 4, col: 2, block: "s" },
808
+ // Transition metals (simplified)
809
+ { symbol: "Cr", name: "Chromium", atomicNumber: 24, row: 4, col: 6, block: "d" },
810
+ { symbol: "Mn", name: "Manganese", atomicNumber: 25, row: 4, col: 7, block: "d" },
811
+ { symbol: "Fe", name: "Iron", atomicNumber: 26, row: 4, col: 8, block: "d" },
812
+ { symbol: "Co", name: "Cobalt", atomicNumber: 27, row: 4, col: 9, block: "d" },
813
+ { symbol: "Ni", name: "Nickel", atomicNumber: 28, row: 4, col: 10, block: "d" },
814
+ { symbol: "Cu", name: "Copper", atomicNumber: 29, row: 4, col: 11, block: "d" },
815
+ { symbol: "Zn", name: "Zinc", atomicNumber: 30, row: 4, col: 12, block: "d" },
816
+ // P-block continued
817
+ { symbol: "Br", name: "Bromine", atomicNumber: 35, row: 4, col: 17, block: "p" },
818
+ // Row 5
819
+ { symbol: "Ag", name: "Silver", atomicNumber: 47, row: 5, col: 11, block: "d" },
820
+ { symbol: "Au", name: "Gold", atomicNumber: 79, row: 5, col: 11, block: "d" },
821
+ { symbol: "Hg", name: "Mercury", atomicNumber: 80, row: 5, col: 12, block: "d" },
822
+ { symbol: "I", name: "Iodine", atomicNumber: 53, row: 5, col: 17, block: "p" },
823
+ // Row 6
824
+ { symbol: "Pt", name: "Platinum", atomicNumber: 78, row: 6, col: 10, block: "d" },
825
+ { symbol: "Pb", name: "Lead", atomicNumber: 82, row: 6, col: 14, block: "p" }
826
+ ], c = F(() => {
827
+ const t = [];
828
+ for (let s = 0; s < ot; s++)
829
+ t.push(new Array(X).fill(null));
830
+ for (const s of n)
831
+ t[s.row - 1][s.col - 1] = s;
832
+ return t;
833
+ });
834
+ function u(t) {
835
+ return {
836
+ s: "#ff6b6b",
837
+ p: "#ffd93d",
838
+ d: "#6bcb77",
839
+ f: "#4d96ff"
840
+ }[t] ?? "#adb5bd";
841
+ }
842
+ function r(t) {
843
+ l("insert", t);
844
+ }
845
+ return (t, s) => (i(), d("div", {
846
+ class: N(["sciexpr-element-table", { "sciexpr-element-table-compact": e.compact }])
847
+ }, [
848
+ s[0] || (s[0] = ce('<div class="sciexpr-element-legend" data-v-a5437c7c><span class="legend-item" data-v-a5437c7c><span class="legend-dot" style="background:#ff6b6b;" data-v-a5437c7c></span> s-block</span><span class="legend-item" data-v-a5437c7c><span class="legend-dot" style="background:#ffd93d;" data-v-a5437c7c></span> p-block</span><span class="legend-item" data-v-a5437c7c><span class="legend-dot" style="background:#6bcb77;" data-v-a5437c7c></span> d-block</span><span class="legend-item" data-v-a5437c7c><span class="legend-dot" style="background:#4d96ff;" data-v-a5437c7c></span> f-block</span></div>', 1)),
849
+ y("div", Je, [
850
+ (i(!0), d(C, null, $(c.value, (m) => (i(), d(C, {
851
+ key: c.value.indexOf(m)
852
+ }, [
853
+ (i(!0), d(C, null, $(m, (a, b) => D((i(), d("button", {
854
+ key: b,
855
+ class: N(["sciexpr-element-cell", {
856
+ "sciexpr-element-cell-compact": e.compact,
857
+ "sciexpr-element-cell-disabled": e.disabled
858
+ }]),
859
+ style: H(a ? {
860
+ gridRow: a.row,
861
+ gridColumn: a.col,
862
+ "--block-color": u(a.block)
863
+ } : {}),
864
+ title: a ? `${a.name} (${a.atomicNumber})` : "",
865
+ disabled: e.disabled,
866
+ type: "button",
867
+ onClick: (h) => a && r(a.symbol)
868
+ }, [
869
+ a ? (i(), d("span", tt, w(a.atomicNumber), 1)) : M("", !0),
870
+ a ? (i(), d("span", at, w(a.symbol), 1)) : M("", !0)
871
+ ], 14, et)), [
872
+ [Z, a !== null]
873
+ ])), 128)),
874
+ (i(), d(C, null, $(X, (a) => D(y("div", {
875
+ key: "empty-" + a,
876
+ class: "sciexpr-element-cell sciexpr-element-empty",
877
+ style: H({ gridRow: c.value.indexOf(m) + 1, gridColumn: a })
878
+ }, null, 4), [
879
+ [Z, !m[a - 1]]
880
+ ])), 64))
881
+ ], 64))), 128))
882
+ ])
883
+ ], 2));
884
+ }
885
+ }), bt = /* @__PURE__ */ E(lt, [["__scopeId", "data-v-a5437c7c"]]);
886
+ function xt(e) {
887
+ function o(l) {
888
+ for (const n of e) {
889
+ const c = l.key.toLowerCase() === n.key.toLowerCase(), u = !!n.ctrl === (l.ctrlKey || l.metaKey), r = !!n.shift === l.shiftKey, t = !!n.alt === l.altKey;
890
+ if (c && u && r && t) {
891
+ l.preventDefault(), n.action();
892
+ return;
893
+ }
894
+ }
895
+ }
896
+ ie(() => {
897
+ window.addEventListener("keydown", o);
898
+ }), re(() => {
899
+ window.removeEventListener("keydown", o);
900
+ });
901
+ }
902
+ const vt = [
903
+ { key: "b", ctrl: !0, action: () => {
904
+ }, description: "Bold (\\mathbf{})" },
905
+ { key: "/", ctrl: !0, action: () => {
906
+ }, description: "Fraction (\\frac{}{})" },
907
+ { key: "s", ctrl: !0, shift: !0, action: () => {
908
+ }, description: "Square root (\\sqrt{})" },
909
+ { key: "1", ctrl: !0, action: () => {
910
+ }, description: "Subscript (_)" },
911
+ { key: "2", ctrl: !0, action: () => {
912
+ }, description: "Superscript (^)" }
913
+ ];
914
+ export {
915
+ O as AI_PIPELINE_KEY,
916
+ Oe as AutocompleteDropdown,
917
+ vt as BUILTIN_SHORTCUTS,
918
+ bt as ElementTable,
919
+ dt as Formula,
920
+ mt as FormulaEditor,
921
+ Se as FormulaToolbar,
922
+ Pe as LivePreview,
923
+ pt as SymbolPanel,
924
+ ge as useAIProvider,
925
+ ye as useAutocomplete,
926
+ J as useFormula,
927
+ fe as useFormulaEditor,
928
+ ut as useFormulaRender,
929
+ xt as useShortcuts
930
+ };
931
+ //# sourceMappingURL=index.mjs.map