@nice2dev/ui-math 1.0.17 → 1.0.18

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 CHANGED
@@ -2,7 +2,175 @@ var T = Object.defineProperty;
2
2
  var R = (e, t, r) => t in e ? T(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
3
3
  var M = (e, t, r) => R(e, typeof t != "symbol" ? t + "" : t, r);
4
4
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
5
- import { createContext, useContext, useState, useRef, useCallback, useEffect } from "react";
5
+ import React, { createContext, useMemo, useContext, useState, useRef, useCallback, useEffect } from "react";
6
+ const translations = {
7
+ en: {
8
+ "calculator.matrixA": "Matrix A",
9
+ "calculator.matrixB": "Matrix B",
10
+ "calculator.exprPlaceholder": "Enter expression (e.g., x^2, sin(x))",
11
+ "calculator.differentiate": "Differentiate",
12
+ "calculator.integrate": "Integrate",
13
+ "calculator.convert": "Convert",
14
+ "plotter.quickAdd": "Quick add preset...",
15
+ "plotter.noPlots": "No plots added yet",
16
+ "plotter.grid": "Grid",
17
+ "plotter.axes": "Axes",
18
+ "editor.latexPlaceholder": "Enter LaTeX equation...",
19
+ "editor.clear": "Clear",
20
+ "editor.recognize": "Recognize",
21
+ "editor.recognizing": "Recognizing...",
22
+ "editor.handwritingNote": "Draw your equation above. Handwriting recognition requires external API integration."
23
+ },
24
+ pl: {
25
+ "calculator.matrixA": "Macierz A",
26
+ "calculator.matrixB": "Macierz B",
27
+ "calculator.exprPlaceholder": "Wprowadź wyrażenie (np. x^2, sin(x))",
28
+ "calculator.differentiate": "Różniczkuj",
29
+ "calculator.integrate": "Całkuj",
30
+ "calculator.convert": "Przelicz",
31
+ "plotter.quickAdd": "Szybko dodaj ustawienie...",
32
+ "plotter.noPlots": "Nie dodano jeszcze żadnych wykresów",
33
+ "plotter.grid": "Siatka",
34
+ "plotter.axes": "Osie",
35
+ "editor.latexPlaceholder": "Wprowadź równanie LaTeX...",
36
+ "editor.clear": "Wyczyść",
37
+ "editor.recognize": "Rozpoznaj",
38
+ "editor.recognizing": "Rozpoznawanie...",
39
+ "editor.handwritingNote": "Narysuj równanie powyżej. Rozpoznawanie pisma wymaga zewnętrznej integracji API."
40
+ },
41
+ de: {
42
+ "calculator.matrixA": "Matrix A",
43
+ "calculator.matrixB": "Matrix B",
44
+ "calculator.exprPlaceholder": "Ausdruck eingeben (z. B. x^2, sin(x))",
45
+ "calculator.differentiate": "Ableiten",
46
+ "calculator.integrate": "Integrieren",
47
+ "calculator.convert": "Umrechnen",
48
+ "plotter.quickAdd": "Voreinstellung schnell hinzufügen...",
49
+ "plotter.noPlots": "Noch keine Diagramme hinzugefügt",
50
+ "plotter.grid": "Raster",
51
+ "plotter.axes": "Achsen",
52
+ "editor.latexPlaceholder": "LaTeX-Gleichung eingeben...",
53
+ "editor.clear": "Löschen",
54
+ "editor.recognize": "Erkennen",
55
+ "editor.recognizing": "Erkennung läuft...",
56
+ "editor.handwritingNote": "Zeichnen Sie Ihre Gleichung oben. Die Handschrifterkennung erfordert eine externe API-Integration."
57
+ },
58
+ fr: {
59
+ "calculator.matrixA": "Matrice A",
60
+ "calculator.matrixB": "Matrice B",
61
+ "calculator.exprPlaceholder": "Saisir une expression (ex. x^2, sin(x))",
62
+ "calculator.differentiate": "Dériver",
63
+ "calculator.integrate": "Intégrer",
64
+ "calculator.convert": "Convertir",
65
+ "plotter.quickAdd": "Ajouter un préréglage rapide...",
66
+ "plotter.noPlots": "Aucun tracé ajouté pour le moment",
67
+ "plotter.grid": "Grille",
68
+ "plotter.axes": "Axes",
69
+ "editor.latexPlaceholder": "Saisir une équation LaTeX...",
70
+ "editor.clear": "Effacer",
71
+ "editor.recognize": "Reconnaître",
72
+ "editor.recognizing": "Reconnaissance...",
73
+ "editor.handwritingNote": "Dessinez votre équation ci-dessus. La reconnaissance d'écriture nécessite une intégration API externe."
74
+ },
75
+ es: {
76
+ "calculator.matrixA": "Matriz A",
77
+ "calculator.matrixB": "Matriz B",
78
+ "calculator.exprPlaceholder": "Introduce una expresión (p. ej. x^2, sin(x))",
79
+ "calculator.differentiate": "Derivar",
80
+ "calculator.integrate": "Integrar",
81
+ "calculator.convert": "Convertir",
82
+ "plotter.quickAdd": "Añadir preajuste rápido...",
83
+ "plotter.noPlots": "Aún no se ha añadido ningún gráfico",
84
+ "plotter.grid": "Cuadrícula",
85
+ "plotter.axes": "Ejes",
86
+ "editor.latexPlaceholder": "Introduce una ecuación LaTeX...",
87
+ "editor.clear": "Borrar",
88
+ "editor.recognize": "Reconocer",
89
+ "editor.recognizing": "Reconociendo...",
90
+ "editor.handwritingNote": "Dibuja tu ecuación arriba. El reconocimiento de escritura requiere integración con una API externa."
91
+ },
92
+ it: {
93
+ "calculator.matrixA": "Matrice A",
94
+ "calculator.matrixB": "Matrice B",
95
+ "calculator.exprPlaceholder": "Inserisci un’espressione (es. x^2, sin(x))",
96
+ "calculator.differentiate": "Derivare",
97
+ "calculator.integrate": "Integrare",
98
+ "calculator.convert": "Converti",
99
+ "plotter.quickAdd": "Aggiungi un preset rapido...",
100
+ "plotter.noPlots": "Nessun grafico aggiunto",
101
+ "plotter.grid": "Griglia",
102
+ "plotter.axes": "Assi",
103
+ "editor.latexPlaceholder": "Inserisci un’equazione LaTeX...",
104
+ "editor.clear": "Cancella",
105
+ "editor.recognize": "Riconosci",
106
+ "editor.recognizing": "Riconoscimento...",
107
+ "editor.handwritingNote": "Disegna la tua equazione qui sopra. Il riconoscimento della scrittura richiede un’integrazione API esterna."
108
+ },
109
+ pt: {
110
+ "calculator.matrixA": "Matriz A",
111
+ "calculator.matrixB": "Matriz B",
112
+ "calculator.exprPlaceholder": "Introduza uma expressão (p. ex. x^2, sin(x))",
113
+ "calculator.differentiate": "Derivar",
114
+ "calculator.integrate": "Integrar",
115
+ "calculator.convert": "Converter",
116
+ "plotter.quickAdd": "Adicionar predefinição rápida...",
117
+ "plotter.noPlots": "Ainda não foram adicionados gráficos",
118
+ "plotter.grid": "Grelha",
119
+ "plotter.axes": "Eixos",
120
+ "editor.latexPlaceholder": "Introduza uma equação LaTeX...",
121
+ "editor.clear": "Limpar",
122
+ "editor.recognize": "Reconhecer",
123
+ "editor.recognizing": "A reconhecer...",
124
+ "editor.handwritingNote": "Desenhe a sua equação acima. O reconhecimento de escrita requer integração com uma API externa."
125
+ },
126
+ cs: {
127
+ "calculator.matrixA": "Matice A",
128
+ "calculator.matrixB": "Matice B",
129
+ "calculator.exprPlaceholder": "Zadejte výraz (např. x^2, sin(x))",
130
+ "calculator.differentiate": "Derivovat",
131
+ "calculator.integrate": "Integrovat",
132
+ "calculator.convert": "Převést",
133
+ "plotter.quickAdd": "Rychle přidat předvolbu...",
134
+ "plotter.noPlots": "Zatím nebyl přidán žádný graf",
135
+ "plotter.grid": "Mřížka",
136
+ "plotter.axes": "Osy",
137
+ "editor.latexPlaceholder": "Zadejte rovnici v LaTeXu...",
138
+ "editor.clear": "Vymazat",
139
+ "editor.recognize": "Rozpoznat",
140
+ "editor.recognizing": "Rozpoznávání...",
141
+ "editor.handwritingNote": "Nakreslete svou rovnici výše. Rozpoznávání rukopisu vyžaduje externí integraci API."
142
+ },
143
+ uk: {
144
+ "calculator.matrixA": "Матриця A",
145
+ "calculator.matrixB": "Матриця B",
146
+ "calculator.exprPlaceholder": "Введіть вираз (напр. x^2, sin(x))",
147
+ "calculator.differentiate": "Диференціювати",
148
+ "calculator.integrate": "Інтегрувати",
149
+ "calculator.convert": "Перетворити",
150
+ "plotter.quickAdd": "Швидко додати пресет...",
151
+ "plotter.noPlots": "Поки що не додано жодного графіка",
152
+ "plotter.grid": "Сітка",
153
+ "plotter.axes": "Осі",
154
+ "editor.latexPlaceholder": "Введіть рівняння в LaTeX...",
155
+ "editor.clear": "Очистити",
156
+ "editor.recognize": "Розпізнати",
157
+ "editor.recognizing": "Розпізнавання...",
158
+ "editor.handwritingNote": "Намалюйте своє рівняння вище. Розпізнавання рукопису потребує зовнішньої інтеграції з API."
159
+ }
160
+ }, I18nContext = createContext({
161
+ locale: "en",
162
+ t: (e, t) => t ?? e
163
+ });
164
+ function NiceI18nProvider({ locale: e = "en", overrides: t, children: r }) {
165
+ const a = useMemo(() => {
166
+ const o = { ...translations.en, ...translations[e], ...t };
167
+ return { locale: e, t: (s, l) => o[s] ?? l ?? s };
168
+ }, [e, t]);
169
+ return React.createElement(I18nContext.Provider, { value: a }, r);
170
+ }
171
+ function useNiceTranslation() {
172
+ return useContext(I18nContext);
173
+ }
6
174
  const MATH_SYMBOLS = [
7
175
  // Greek lowercase
8
176
  { name: "alpha", latex: "\\alpha", category: "greek", preview: "α" },
@@ -267,16 +435,16 @@ class MathEditorService {
267
435
  }
268
436
  /** Update equation */
269
437
  updateEquation(t, r, a) {
270
- const n = this.equations.get(t);
271
- if (!n)
438
+ const o = this.equations.get(t);
439
+ if (!o)
272
440
  throw new Error(`Equation not found: ${t}`);
273
- const o = {
274
- ...n,
441
+ const n = {
442
+ ...o,
275
443
  latex: r,
276
- label: a ?? n.label,
444
+ label: a ?? o.label,
277
445
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
278
446
  };
279
- return this.equations.set(t, o), o;
447
+ return this.equations.set(t, n), n;
280
448
  }
281
449
  /** Delete equation */
282
450
  deleteEquation(t) {
@@ -310,13 +478,13 @@ class MathEditorService {
310
478
  /** Parse LaTeX and extract equations */
311
479
  parseLatex(t) {
312
480
  const r = [], a = /\\\[([\s\S]*?)\\\]/g;
313
- let n;
314
- for (; (n = a.exec(t)) !== null; )
315
- r.push(this.createEquation(n[1].trim()));
316
- const o = /\\begin\{equation\}([\s\S]*?)\\end\{equation\}/g;
317
- for (; (n = o.exec(t)) !== null; ) {
318
- const s = n[1].match(/\\label\{([^}]+)\}/), c = n[1].replace(/\\label\{[^}]+\}/, "").trim();
319
- r.push(this.createEquation(c, s == null ? void 0 : s[1]));
481
+ let o;
482
+ for (; (o = a.exec(t)) !== null; )
483
+ r.push(this.createEquation(o[1].trim()));
484
+ const n = /\\begin\{equation\}([\s\S]*?)\\end\{equation\}/g;
485
+ for (; (o = n.exec(t)) !== null; ) {
486
+ const s = o[1].match(/\\label\{([^}]+)\}/), l = o[1].replace(/\\label\{[^}]+\}/, "").trim();
487
+ r.push(this.createEquation(l, s == null ? void 0 : s[1]));
320
488
  }
321
489
  return r;
322
490
  }
@@ -441,62 +609,62 @@ function NiceMathEditor({
441
609
  initialLatex: t = "",
442
610
  onChange: r,
443
611
  className: a,
444
- style: n
612
+ style: o
445
613
  }) {
446
- const [o, s] = useState(t), [c, l] = useState("input"), i = useRef(null), d = useCallback(
447
- (y) => {
448
- s(y), r == null || r(y);
614
+ const { t: n } = useNiceTranslation(), [s, l] = useState(t), [x, i] = useState("input"), d = useRef(null), g = useCallback(
615
+ (p) => {
616
+ l(p), r == null || r(p);
449
617
  },
450
618
  [r]
451
- ), u = useCallback(
452
- (y) => {
453
- const g = i.current;
454
- if (!g) {
455
- d(o + y);
619
+ ), y = useCallback(
620
+ (p) => {
621
+ const f = d.current;
622
+ if (!f) {
623
+ g(s + p);
456
624
  return;
457
625
  }
458
- const m = g.selectionStart, p = g.selectionEnd, x = o.slice(0, m) + y + o.slice(p);
459
- d(x), setTimeout(() => {
460
- g.focus(), g.selectionStart = g.selectionEnd = m + y.length;
626
+ const c = f.selectionStart, u = f.selectionEnd, b = s.slice(0, c) + p + s.slice(u);
627
+ g(b), setTimeout(() => {
628
+ f.focus(), f.selectionStart = f.selectionEnd = c + p.length;
461
629
  }, 0);
462
630
  },
463
- [o, d]
631
+ [s, g]
464
632
  ), h = useCallback(
465
- (y) => {
466
- u(y.latex);
633
+ (p) => {
634
+ y(p.latex);
467
635
  },
468
- [u]
469
- ), b = {
636
+ [y]
637
+ ), w = {
470
638
  service: e,
471
- latex: o,
472
- setLatex: d,
473
- insertSymbol: u,
639
+ latex: s,
640
+ setLatex: g,
641
+ insertSymbol: y,
474
642
  insertTemplate: h,
475
- mode: c,
476
- setMode: l
643
+ mode: x,
644
+ setMode: i
477
645
  };
478
- return /* @__PURE__ */ jsx(MathEditorContext.Provider, { value: b, children: /* @__PURE__ */ jsxs("div", { className: a, style: { ...styles$3.container, ...n }, children: [
646
+ return /* @__PURE__ */ jsx(MathEditorContext.Provider, { value: w, children: /* @__PURE__ */ jsxs("div", { className: a, style: { ...styles$3.container, ...o }, children: [
479
647
  /* @__PURE__ */ jsx(Toolbar$1, {}),
480
648
  /* @__PURE__ */ jsxs("div", { style: styles$3.main, children: [
481
649
  /* @__PURE__ */ jsx(SymbolPalette, {}),
482
- /* @__PURE__ */ jsx("div", { style: styles$3.editor, children: c === "input" ? /* @__PURE__ */ jsxs(Fragment, { children: [
650
+ /* @__PURE__ */ jsx("div", { style: styles$3.editor, children: x === "input" ? /* @__PURE__ */ jsxs(Fragment, { children: [
483
651
  /* @__PURE__ */ jsx(
484
652
  "textarea",
485
653
  {
486
- ref: i,
487
- value: o,
488
- onChange: (y) => d(y.target.value),
489
- placeholder: "Enter LaTeX equation...",
654
+ ref: d,
655
+ value: s,
656
+ onChange: (p) => g(p.target.value),
657
+ placeholder: n("editor.latexPlaceholder", "Enter LaTeX equation..."),
490
658
  style: styles$3.input
491
659
  }
492
660
  ),
493
- /* @__PURE__ */ jsx(LatexPreview, { latex: o })
661
+ /* @__PURE__ */ jsx(LatexPreview, { latex: s })
494
662
  ] }) : /* @__PURE__ */ jsx(HandwritingCanvas, {}) })
495
663
  ] })
496
664
  ] }) });
497
665
  }
498
666
  function Toolbar$1() {
499
- const { mode: e, setMode: t, latex: r, insertTemplate: a } = useMathEditor(), [n, o] = useState(!1);
667
+ const { mode: e, setMode: t, latex: r, insertTemplate: a } = useMathEditor(), [o, n] = useState(!1);
500
668
  return /* @__PURE__ */ jsxs("div", { style: styles$3.toolbar, children: [
501
669
  /* @__PURE__ */ jsx(
502
670
  "button",
@@ -520,10 +688,19 @@ function Toolbar$1() {
520
688
  children: "✏️ Handwriting"
521
689
  }
522
690
  ),
523
- /* @__PURE__ */ jsx("div", { style: { borderLeft: "1px solid var(--nice-border, #ccc)", height: "24px", margin: "0 8px" } }),
691
+ /* @__PURE__ */ jsx(
692
+ "div",
693
+ {
694
+ style: {
695
+ borderLeft: "1px solid var(--nice-border, #ccc)",
696
+ height: "24px",
697
+ margin: "0 8px"
698
+ }
699
+ }
700
+ ),
524
701
  /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
525
- /* @__PURE__ */ jsx("button", { onClick: () => o(!n), style: styles$3.button, children: "📐 Templates ▾" }),
526
- n && /* @__PURE__ */ jsx(
702
+ /* @__PURE__ */ jsx("button", { onClick: () => n(!o), style: styles$3.button, children: "📐 Templates ▾" }),
703
+ o && /* @__PURE__ */ jsx(
527
704
  "div",
528
705
  {
529
706
  style: {
@@ -542,28 +719,38 @@ function Toolbar$1() {
542
719
  children: ["basic", "calculus", "algebra", "geometry", "statistics", "physics"].map(
543
720
  (s) => /* @__PURE__ */ jsxs("div", { children: [
544
721
  /* @__PURE__ */ jsx("div", { style: styles$3.categoryHeader, children: s }),
545
- EQUATION_TEMPLATES.filter((c) => c.category === s).map((c) => /* @__PURE__ */ jsxs(
722
+ EQUATION_TEMPLATES.filter((l) => l.category === s).map((l) => /* @__PURE__ */ jsxs(
546
723
  "div",
547
724
  {
548
725
  onClick: () => {
549
- a(c), o(!1);
726
+ a(l), n(!1);
550
727
  },
551
728
  style: {
552
729
  padding: "8px 12px",
553
730
  cursor: "pointer",
554
731
  borderBottom: "1px solid var(--nice-border, #eee)"
555
732
  },
556
- onMouseOver: (l) => l.target.style.backgroundColor = "var(--nice-bg-secondary, #f5f5f5)",
557
- onMouseOut: (l) => l.target.style.backgroundColor = "transparent",
733
+ onMouseOver: (x) => x.target.style.backgroundColor = "var(--nice-bg-secondary, #f5f5f5)",
734
+ onMouseOut: (x) => x.target.style.backgroundColor = "transparent",
558
735
  children: [
559
- /* @__PURE__ */ jsx("div", { style: { fontWeight: 500 }, children: c.name }),
560
- /* @__PURE__ */ jsxs("div", { style: { fontSize: "12px", color: "var(--nice-text-secondary, #666)", fontFamily: "monospace" }, children: [
561
- c.latex.substring(0, 40),
562
- c.latex.length > 40 ? "..." : ""
563
- ] })
736
+ /* @__PURE__ */ jsx("div", { style: { fontWeight: 500 }, children: l.name }),
737
+ /* @__PURE__ */ jsxs(
738
+ "div",
739
+ {
740
+ style: {
741
+ fontSize: "12px",
742
+ color: "var(--nice-text-secondary, #666)",
743
+ fontFamily: "monospace"
744
+ },
745
+ children: [
746
+ l.latex.substring(0, 40),
747
+ l.latex.length > 40 ? "..." : ""
748
+ ]
749
+ }
750
+ )
564
751
  ]
565
752
  },
566
- c.name
753
+ l.name
567
754
  ))
568
755
  ] }, s)
569
756
  )
@@ -594,127 +781,143 @@ function SymbolPalette() {
594
781
  "logic",
595
782
  "calculus",
596
783
  "matrices"
597
- ], n = getSymbolsByCategory(t);
784
+ ], o = getSymbolsByCategory(t);
598
785
  return /* @__PURE__ */ jsxs("div", { style: styles$3.sidebar, children: [
599
- /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", padding: "8px", gap: "4px" }, children: a.map((o) => /* @__PURE__ */ jsx(
786
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", padding: "8px", gap: "4px" }, children: a.map((n) => /* @__PURE__ */ jsx(
600
787
  "button",
601
788
  {
602
- onClick: () => r(o),
789
+ onClick: () => r(n),
603
790
  style: {
604
791
  padding: "4px 8px",
605
792
  fontSize: "11px",
606
793
  border: "1px solid var(--nice-border, #ddd)",
607
794
  borderRadius: "4px",
608
- backgroundColor: t === o ? "var(--nice-primary-hover, #1976d2)" : "var(--nice-bg, #fff)",
609
- color: t === o ? "var(--nice-bg, #fff)" : "var(--nice-text, #333)",
795
+ backgroundColor: t === n ? "var(--nice-primary-hover, #1976d2)" : "var(--nice-bg, #fff)",
796
+ color: t === n ? "var(--nice-bg, #fff)" : "var(--nice-text, #333)",
610
797
  cursor: "pointer"
611
798
  },
612
- children: o
799
+ children: n
613
800
  },
614
- o
801
+ n
615
802
  )) }),
616
- /* @__PURE__ */ jsx("div", { style: styles$3.symbolGrid, children: n.map((o) => /* @__PURE__ */ jsx(
803
+ /* @__PURE__ */ jsx("div", { style: styles$3.symbolGrid, children: o.map((n) => /* @__PURE__ */ jsx(
617
804
  "button",
618
805
  {
619
- onClick: () => e(o.latex),
806
+ onClick: () => e(n.latex),
620
807
  style: styles$3.symbolButton,
621
- title: `${o.name}: ${o.latex}`,
622
- children: o.preview || o.latex
808
+ title: `${n.name}: ${n.latex}`,
809
+ children: n.preview || n.latex
623
810
  },
624
- o.name
811
+ n.name
625
812
  )) })
626
813
  ] });
627
814
  }
628
815
  function LatexPreview({ latex: e }) {
629
816
  return /* @__PURE__ */ jsxs("div", { style: styles$3.preview, children: [
630
- /* @__PURE__ */ jsx("div", { style: { fontSize: "12px", color: "var(--nice-text-secondary, #666)", marginBottom: "8px" }, children: "Preview (requires KaTeX/MathJax integration):" }),
817
+ /* @__PURE__ */ jsx(
818
+ "div",
819
+ {
820
+ style: { fontSize: "12px", color: "var(--nice-text-secondary, #666)", marginBottom: "8px" },
821
+ children: "Preview (requires KaTeX/MathJax integration):"
822
+ }
823
+ ),
631
824
  /* @__PURE__ */ jsx("code", { style: { fontSize: "16px" }, children: e || "(empty)" })
632
825
  ] });
633
826
  }
634
827
  function HandwritingCanvas() {
635
- const { setLatex: e, setMode: t } = useMathEditor(), r = useRef(null), [a, n] = useState([]), [o, s] = useState([]), [c, l] = useState(!1), [i, d] = useState(!1), u = (m) => {
636
- const p = r.current;
637
- if (!p)
828
+ const { t: e } = useNiceTranslation(), { setLatex: t, setMode: r } = useMathEditor(), a = useRef(null), [o, n] = useState([]), [s, l] = useState([]), [x, i] = useState(!1), [d, g] = useState(!1), y = (c) => {
829
+ const u = a.current;
830
+ if (!u)
638
831
  return;
639
- l(!0);
640
- const x = p.getBoundingClientRect();
641
- s([
832
+ i(!0);
833
+ const b = u.getBoundingClientRect();
834
+ l([
642
835
  {
643
- x: m.clientX - x.left,
644
- y: m.clientY - x.top,
645
- pressure: m.pressure,
836
+ x: c.clientX - b.left,
837
+ y: c.clientY - b.top,
838
+ pressure: c.pressure,
646
839
  timestamp: Date.now()
647
840
  }
648
841
  ]);
649
- }, h = (m) => {
650
- if (!c)
842
+ }, h = (c) => {
843
+ if (!x)
651
844
  return;
652
- const p = r.current, x = p == null ? void 0 : p.getContext("2d");
653
- if (!p || !x)
845
+ const u = a.current, b = u == null ? void 0 : u.getContext("2d");
846
+ if (!u || !b)
654
847
  return;
655
- const w = p.getBoundingClientRect(), k = {
656
- x: m.clientX - w.left,
657
- y: m.clientY - w.top,
658
- pressure: m.pressure,
848
+ const k = u.getBoundingClientRect(), m = {
849
+ x: c.clientX - k.left,
850
+ y: c.clientY - k.top,
851
+ pressure: c.pressure,
659
852
  timestamp: Date.now()
660
853
  };
661
- if (s((f) => [...f, k]), o.length > 0) {
662
- const f = o[o.length - 1];
663
- x.beginPath(), x.moveTo(f.x, f.y), x.lineTo(k.x, k.y), x.strokeStyle = "var(--nice-text, #000)", x.lineWidth = 2, x.lineCap = "round", x.stroke();
854
+ if (l((v) => [...v, m]), s.length > 0) {
855
+ const v = s[s.length - 1];
856
+ b.beginPath(), b.moveTo(v.x, v.y), b.lineTo(m.x, m.y), b.strokeStyle = "var(--nice-text, #000)", b.lineWidth = 2, b.lineCap = "round", b.stroke();
664
857
  }
665
- }, b = () => {
666
- if (c) {
667
- if (l(!1), o.length > 1) {
668
- const m = {
858
+ }, w = () => {
859
+ if (x) {
860
+ if (i(!1), s.length > 1) {
861
+ const c = {
669
862
  id: Date.now().toString(),
670
- points: [...o]
863
+ points: [...s]
671
864
  };
672
- n((p) => [...p, m]);
865
+ n((u) => [...u, c]);
673
866
  }
674
- s([]);
867
+ l([]);
675
868
  }
676
- }, y = () => {
677
- const m = r.current, p = m == null ? void 0 : m.getContext("2d");
678
- p && m && p.clearRect(0, 0, m.width, m.height), n([]);
679
- }, g = async () => {
680
- if (a.length !== 0) {
681
- d(!0);
869
+ }, p = () => {
870
+ const c = a.current, u = c == null ? void 0 : c.getContext("2d");
871
+ u && c && u.clearRect(0, 0, c.width, c.height), n([]);
872
+ }, f = async () => {
873
+ if (o.length !== 0) {
874
+ g(!0);
682
875
  try {
683
- const m = await recognizeHandwriting(a);
684
- e(m.latex), t("input");
876
+ const c = await recognizeHandwriting(o);
877
+ t(c.latex), r("input");
685
878
  } finally {
686
- d(!1);
879
+ g(!1);
687
880
  }
688
881
  }
689
882
  };
690
883
  return useEffect(() => {
691
- const m = r.current;
692
- m && (m.width = m.offsetWidth, m.height = 200);
884
+ const c = a.current;
885
+ c && (c.width = c.offsetWidth, c.height = 200);
693
886
  }, []), /* @__PURE__ */ jsxs("div", { children: [
694
887
  /* @__PURE__ */ jsx(
695
888
  "canvas",
696
889
  {
697
- ref: r,
890
+ ref: a,
698
891
  style: styles$3.canvas,
699
- onPointerDown: u,
892
+ onPointerDown: y,
700
893
  onPointerMove: h,
701
- onPointerUp: b,
702
- onPointerLeave: b
894
+ onPointerUp: w,
895
+ onPointerLeave: w
703
896
  }
704
897
  ),
705
898
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", marginTop: "12px" }, children: [
706
- /* @__PURE__ */ jsx("button", { onClick: y, style: { ...styles$3.button, backgroundColor: "var(--nice-danger, #f44336)" }, children: "Clear" }),
707
899
  /* @__PURE__ */ jsx(
708
900
  "button",
709
901
  {
710
- onClick: g,
711
- disabled: a.length === 0 || i,
902
+ onClick: p,
903
+ style: { ...styles$3.button, backgroundColor: "var(--nice-danger, #f44336)" },
904
+ children: e("editor.clear", "Clear")
905
+ }
906
+ ),
907
+ /* @__PURE__ */ jsx(
908
+ "button",
909
+ {
910
+ onClick: f,
911
+ disabled: o.length === 0 || d,
712
912
  style: styles$3.button,
713
- children: i ? "Recognizing..." : "Recognize"
913
+ children: d ? e("editor.recognizing", "Recognizing...") : e("editor.recognize", "Recognize")
714
914
  }
715
915
  )
716
916
  ] }),
717
- /* @__PURE__ */ jsx("p", { style: { fontSize: "12px", color: "var(--nice-text-secondary, #666)", marginTop: "8px" }, children: "Draw your equation above. Handwriting recognition requires external API integration." })
917
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "12px", color: "var(--nice-text-secondary, #666)", marginTop: "8px" }, children: e(
918
+ "editor.handwritingNote",
919
+ "Draw your equation above. Handwriting recognition requires external API integration."
920
+ ) })
718
921
  ] });
719
922
  }
720
923
  const mathConstants = {
@@ -816,10 +1019,10 @@ class ExpressionParser {
816
1019
  const a = r[1];
817
1020
  if (this.pos += a.length, this.expr[this.pos] === "(") {
818
1021
  this.pos++;
819
- const n = [];
1022
+ const o = [];
820
1023
  for (; this.expr[this.pos] !== ")" && this.pos < this.expr.length; )
821
- n.push(this.parseAddSub()), this.expr[this.pos] === "," && this.pos++;
822
- return this.expr[this.pos] === ")" && this.pos++, { type: "call", name: a, args: n };
1024
+ o.push(this.parseAddSub()), this.expr[this.pos] === "," && this.pos++;
1025
+ return this.expr[this.pos] === ")" && this.pos++, { type: "call", name: a, args: o };
823
1026
  }
824
1027
  return { type: "variable", name: a };
825
1028
  }
@@ -836,18 +1039,18 @@ class ExpressionParser {
836
1039
  case "unary":
837
1040
  return t.op === "-" ? -this.evaluate(t.arg, r) : this.evaluate(t.arg, r);
838
1041
  case "binary": {
839
- const a = this.evaluate(t.left, r), n = this.evaluate(t.right, r);
1042
+ const a = this.evaluate(t.left, r), o = this.evaluate(t.right, r);
840
1043
  switch (t.op) {
841
1044
  case "+":
842
- return a + n;
1045
+ return a + o;
843
1046
  case "-":
844
- return a - n;
1047
+ return a - o;
845
1048
  case "*":
846
- return a * n;
1049
+ return a * o;
847
1050
  case "/":
848
- return a / n;
1051
+ return a / o;
849
1052
  case "^":
850
- return Math.pow(a, n);
1053
+ return Math.pow(a, o);
851
1054
  default:
852
1055
  return 0;
853
1056
  }
@@ -856,8 +1059,8 @@ class ExpressionParser {
856
1059
  const a = mathFunctions[t.name];
857
1060
  if (!a)
858
1061
  throw new Error(`Unknown function: ${t.name}`);
859
- const n = t.args.map((o) => this.evaluate(o, r));
860
- return a(...n);
1062
+ const o = t.args.map((n) => this.evaluate(n, r));
1063
+ return a(...o);
861
1064
  }
862
1065
  default:
863
1066
  return 0;
@@ -897,8 +1100,8 @@ class GraphService {
897
1100
  const a = this.plots.get(t);
898
1101
  if (!a)
899
1102
  throw new Error(`Plot not found: ${t}`);
900
- const n = { ...a, ...r, id: a.id };
901
- return this.plots.set(t, n), n;
1103
+ const o = { ...a, ...r, id: a.id };
1104
+ return this.plots.set(t, o), o;
902
1105
  }
903
1106
  /** Remove a plot */
904
1107
  removePlot(t) {
@@ -913,12 +1116,12 @@ class GraphService {
913
1116
  return this.plots.get(t);
914
1117
  }
915
1118
  /** Compute 2D function points */
916
- compute2DFunction(t, r, a, n) {
917
- const o = this.parser.parse(t), s = [], c = (r.max - r.min) / a;
918
- for (let l = 0; l <= a; l++) {
919
- const i = r.min + l * c;
1119
+ compute2DFunction(t, r, a, o) {
1120
+ const n = this.parser.parse(t), s = [], l = (r.max - r.min) / a;
1121
+ for (let x = 0; x <= a; x++) {
1122
+ const i = r.min + x * l;
920
1123
  try {
921
- const d = o({ x: i, ...n });
1124
+ const d = n({ x: i, ...o });
922
1125
  Number.isFinite(d) && s.push({ x: i, y: d });
923
1126
  } catch {
924
1127
  }
@@ -926,28 +1129,28 @@ class GraphService {
926
1129
  return s;
927
1130
  }
928
1131
  /** Compute 2D parametric curve */
929
- compute2DParametric(t, r, a, n, o) {
930
- const s = this.parser.parse(t), c = this.parser.parse(r), l = [], i = (a.max - a.min) / n;
931
- for (let d = 0; d <= n; d++) {
932
- const u = a.min + d * i;
1132
+ compute2DParametric(t, r, a, o, n) {
1133
+ const s = this.parser.parse(t), l = this.parser.parse(r), x = [], i = (a.max - a.min) / o;
1134
+ for (let d = 0; d <= o; d++) {
1135
+ const g = a.min + d * i;
933
1136
  try {
934
- const h = s({ t: u, ...o }), b = c({ t: u, ...o });
935
- Number.isFinite(h) && Number.isFinite(b) && l.push({ x: h, y: b });
1137
+ const y = s({ t: g, ...n }), h = l({ t: g, ...n });
1138
+ Number.isFinite(y) && Number.isFinite(h) && x.push({ x: y, y: h });
936
1139
  } catch {
937
1140
  }
938
1141
  }
939
- return l;
1142
+ return x;
940
1143
  }
941
1144
  /** Compute 2D polar curve */
942
- compute2DPolar(t, r, a, n) {
943
- const o = this.parser.parse(t), s = [], c = (r.max - r.min) / a;
944
- for (let l = 0; l <= a; l++) {
945
- const i = r.min + l * c;
1145
+ compute2DPolar(t, r, a, o) {
1146
+ const n = this.parser.parse(t), s = [], l = (r.max - r.min) / a;
1147
+ for (let x = 0; x <= a; x++) {
1148
+ const i = r.min + x * l;
946
1149
  try {
947
- const d = o({ theta: i, t: i, ...n });
1150
+ const d = n({ theta: i, t: i, ...o });
948
1151
  if (Number.isFinite(d)) {
949
- const u = d * Math.cos(i), h = d * Math.sin(i);
950
- s.push({ x: u, y: h });
1152
+ const g = d * Math.cos(i), y = d * Math.sin(i);
1153
+ s.push({ x: g, y });
951
1154
  }
952
1155
  } catch {
953
1156
  }
@@ -955,78 +1158,78 @@ class GraphService {
955
1158
  return s;
956
1159
  }
957
1160
  /** Compute 3D surface points */
958
- compute3DSurface(t, r, a, n, o) {
959
- const s = this.parser.parse(t), c = [], l = (r.max - r.min) / n, i = (a.max - a.min) / n;
960
- for (let d = 0; d <= n; d++) {
961
- const u = [], h = r.min + d * l;
962
- for (let b = 0; b <= n; b++) {
963
- const y = a.min + b * i;
1161
+ compute3DSurface(t, r, a, o, n) {
1162
+ const s = this.parser.parse(t), l = [], x = (r.max - r.min) / o, i = (a.max - a.min) / o;
1163
+ for (let d = 0; d <= o; d++) {
1164
+ const g = [], y = r.min + d * x;
1165
+ for (let h = 0; h <= o; h++) {
1166
+ const w = a.min + h * i;
964
1167
  try {
965
- const g = s({ x: h, y, ...o });
966
- Number.isFinite(g) ? u.push({ x: h, y, z: g }) : u.push({ x: h, y, z: 0 });
1168
+ const p = s({ x: y, y: w, ...n });
1169
+ Number.isFinite(p) ? g.push({ x: y, y: w, z: p }) : g.push({ x: y, y: w, z: 0 });
967
1170
  } catch {
968
- u.push({ x: h, y, z: 0 });
1171
+ g.push({ x: y, y: w, z: 0 });
969
1172
  }
970
1173
  }
971
- c.push(u);
1174
+ l.push(g);
972
1175
  }
973
- return c;
1176
+ return l;
974
1177
  }
975
1178
  /** Export plot data as SVG */
976
- exportSVG(t, r, a, n) {
977
- const s = a - 80, c = n - 40 * 2, l = (u) => 40 + (u - r.xRange.min) / (r.xRange.max - r.xRange.min) * s, i = (u) => n - 40 - (u - r.yRange.min) / (r.yRange.max - r.yRange.min) * c, d = [
978
- `<svg xmlns="http://www.w3.org/2000/svg" width="${a}" height="${n}">`,
1179
+ exportSVG(t, r, a, o) {
1180
+ const s = a - 80, l = o - 40 * 2, x = (g) => 40 + (g - r.xRange.min) / (r.xRange.max - r.xRange.min) * s, i = (g) => o - 40 - (g - r.yRange.min) / (r.yRange.max - r.yRange.min) * l, d = [
1181
+ `<svg xmlns="http://www.w3.org/2000/svg" width="${a}" height="${o}">`,
979
1182
  `<rect width="100%" height="100%" fill="rgb(${r.backgroundColor.r},${r.backgroundColor.g},${r.backgroundColor.b})"/>`
980
1183
  ];
981
1184
  if (r.showGrid) {
982
1185
  d.push('<g stroke="var(--nice-border, #ddd)" stroke-width="0.5">');
983
- for (let u = Math.ceil(r.xRange.min); u <= r.xRange.max; u++) {
984
- const h = l(u);
985
- d.push(`<line x1="${h}" y1="40" x2="${h}" y2="${n - 40}"/>`);
1186
+ for (let g = Math.ceil(r.xRange.min); g <= r.xRange.max; g++) {
1187
+ const y = x(g);
1188
+ d.push(`<line x1="${y}" y1="40" x2="${y}" y2="${o - 40}"/>`);
986
1189
  }
987
- for (let u = Math.ceil(r.yRange.min); u <= r.yRange.max; u++) {
988
- const h = i(u);
989
- d.push(`<line x1="40" y1="${h}" x2="${a - 40}" y2="${h}"/>`);
1190
+ for (let g = Math.ceil(r.yRange.min); g <= r.yRange.max; g++) {
1191
+ const y = i(g);
1192
+ d.push(`<line x1="40" y1="${y}" x2="${a - 40}" y2="${y}"/>`);
990
1193
  }
991
1194
  d.push("</g>");
992
1195
  }
993
1196
  if (r.showAxes) {
994
1197
  d.push('<g stroke="var(--nice-text, #333)" stroke-width="1">');
995
- const u = i(0), h = l(0);
996
- d.push(`<line x1="40" y1="${u}" x2="${a - 40}" y2="${u}"/>`), d.push(`<line x1="${h}" y1="40" x2="${h}" y2="${n - 40}"/>`), d.push("</g>");
1198
+ const g = i(0), y = x(0);
1199
+ d.push(`<line x1="40" y1="${g}" x2="${a - 40}" y2="${g}"/>`), d.push(`<line x1="${y}" y1="40" x2="${y}" y2="${o - 40}"/>`), d.push("</g>");
997
1200
  }
998
- for (const u of t.filter((h) => h.visible))
999
- if (u.type === "2d-function") {
1000
- const h = this.compute2DFunction(u.expression, r.xRange, u.resolution || 200);
1001
- if (h.length > 0) {
1002
- const b = h.map((y, g) => `${g === 0 ? "M" : "L"}${l(y.x)},${i(y.y)}`).join(" ");
1201
+ for (const g of t.filter((y) => y.visible))
1202
+ if (g.type === "2d-function") {
1203
+ const y = this.compute2DFunction(g.expression, r.xRange, g.resolution || 200);
1204
+ if (y.length > 0) {
1205
+ const h = y.map((w, p) => `${p === 0 ? "M" : "L"}${x(w.x)},${i(w.y)}`).join(" ");
1003
1206
  d.push(
1004
- `<path d="${b}" fill="none" stroke="rgb(${u.color.r},${u.color.g},${u.color.b})" stroke-width="${u.lineWidth}"/>`
1207
+ `<path d="${h}" fill="none" stroke="rgb(${g.color.r},${g.color.g},${g.color.b})" stroke-width="${g.lineWidth}"/>`
1005
1208
  );
1006
1209
  }
1007
1210
  }
1008
1211
  return r.showLabels && (d.push(
1009
- `<text x="${a / 2}" y="${n - 10}" text-anchor="middle" font-size="12">x</text>`
1212
+ `<text x="${a / 2}" y="${o - 10}" text-anchor="middle" font-size="12">x</text>`
1010
1213
  ), d.push(
1011
- `<text x="10" y="${n / 2}" text-anchor="middle" font-size="12" transform="rotate(-90,10,${n / 2})">y</text>`
1214
+ `<text x="10" y="${o / 2}" text-anchor="middle" font-size="12" transform="rotate(-90,10,${o / 2})">y</text>`
1012
1215
  )), d.push("</svg>"), d.join(`
1013
1216
  `);
1014
1217
  }
1015
1218
  /** Export as PNG (data URL) */
1016
- async exportPNG(t, r, a, n) {
1017
- const o = this.exportSVG(t, r, a, n);
1018
- return new Promise((s, c) => {
1019
- const l = new Image();
1020
- l.onload = () => {
1219
+ async exportPNG(t, r, a, o) {
1220
+ const n = this.exportSVG(t, r, a, o);
1221
+ return new Promise((s, l) => {
1222
+ const x = new Image();
1223
+ x.onload = () => {
1021
1224
  const i = document.createElement("canvas");
1022
- i.width = a, i.height = n;
1225
+ i.width = a, i.height = o;
1023
1226
  const d = i.getContext("2d");
1024
1227
  if (!d) {
1025
- c(new Error("Could not get canvas context"));
1228
+ l(new Error("Could not get canvas context"));
1026
1229
  return;
1027
1230
  }
1028
- d.drawImage(l, 0, 0), s(i.toDataURL("image/png"));
1029
- }, l.onerror = c, l.src = "data:image/svg+xml;base64," + btoa(o);
1231
+ d.drawImage(x, 0, 0), s(i.toDataURL("image/png"));
1232
+ }, x.onerror = l, x.src = "data:image/svg+xml;base64," + btoa(n);
1030
1233
  });
1031
1234
  }
1032
1235
  generateId() {
@@ -1190,9 +1393,9 @@ function NiceGraphPlotter({
1190
1393
  width: t = 800,
1191
1394
  height: r = 600,
1192
1395
  className: a,
1193
- style: n
1396
+ style: o
1194
1397
  }) {
1195
- const [o, s] = useState([]), [c, l] = useState({
1398
+ const [n, s] = useState([]), [l, x] = useState({
1196
1399
  xRange: { min: -10, max: 10 },
1197
1400
  yRange: { min: -10, max: 10 },
1198
1401
  zRange: { min: -5, max: 5 },
@@ -1210,40 +1413,40 @@ function NiceGraphPlotter({
1210
1413
  minValue: -5,
1211
1414
  maxValue: 5,
1212
1415
  speed: 1
1213
- }), u = useCallback(() => {
1416
+ }), g = useCallback(() => {
1214
1417
  s(e.getPlots());
1215
- }, [e]), h = useCallback((x) => {
1216
- l((w) => ({ ...w, ...x }));
1217
- }, []), b = useCallback((x) => {
1218
- d((w) => ({ ...w, ...x }));
1219
- }, []), y = useCallback(
1220
- (x) => {
1221
- e.addPlot(x), u();
1418
+ }, [e]), y = useCallback((u) => {
1419
+ x((b) => ({ ...b, ...u }));
1420
+ }, []), h = useCallback((u) => {
1421
+ d((b) => ({ ...b, ...u }));
1422
+ }, []), w = useCallback(
1423
+ (u) => {
1424
+ e.addPlot(u), g();
1222
1425
  },
1223
- [e, u]
1224
- ), g = useCallback(
1225
- (x) => {
1226
- e.removePlot(x), u();
1426
+ [e, g]
1427
+ ), p = useCallback(
1428
+ (u) => {
1429
+ e.removePlot(u), g();
1227
1430
  },
1228
- [e, u]
1229
- ), m = useCallback(
1230
- (x, w) => {
1231
- e.updatePlot(x, w), u();
1431
+ [e, g]
1432
+ ), f = useCallback(
1433
+ (u, b) => {
1434
+ e.updatePlot(u, b), g();
1232
1435
  },
1233
- [e, u]
1234
- ), p = {
1436
+ [e, g]
1437
+ ), c = {
1235
1438
  service: e,
1236
- plots: o,
1237
- view: c,
1238
- setView: h,
1239
- addPlot: y,
1240
- removePlot: g,
1241
- updatePlot: m,
1439
+ plots: n,
1440
+ view: l,
1441
+ setView: y,
1442
+ addPlot: w,
1443
+ removePlot: p,
1444
+ updatePlot: f,
1242
1445
  animation: i,
1243
- setAnimation: b,
1244
- refresh: u
1446
+ setAnimation: h,
1447
+ refresh: g
1245
1448
  };
1246
- return /* @__PURE__ */ jsx(GraphContext.Provider, { value: p, children: /* @__PURE__ */ jsxs("div", { className: a, style: { ...styles$2.container, ...n }, children: [
1449
+ return /* @__PURE__ */ jsx(GraphContext.Provider, { value: c, children: /* @__PURE__ */ jsxs("div", { className: a, style: { ...styles$2.container, ...o }, children: [
1247
1450
  /* @__PURE__ */ jsxs("div", { style: styles$2.sidebar, children: [
1248
1451
  /* @__PURE__ */ jsx(PlotControls, {}),
1249
1452
  /* @__PURE__ */ jsx(PlotList, {})
@@ -1255,11 +1458,11 @@ function NiceGraphPlotter({
1255
1458
  ] }) });
1256
1459
  }
1257
1460
  function PlotControls() {
1258
- const { addPlot: e } = useGraph(), [t, r] = useState("sin(x)"), [a, n] = useState("2d-function"), [o, s] = useState("cos(x)"), c = () => {
1259
- e({
1260
- type: a,
1261
- expression: t,
1262
- expressionY: a === "2d-parametric" ? o : void 0,
1461
+ const { t: e } = useNiceTranslation(), { addPlot: t } = useGraph(), [r, a] = useState("sin(x)"), [o, n] = useState("2d-function"), [s, l] = useState("cos(x)"), x = () => {
1462
+ t({
1463
+ type: o,
1464
+ expression: r,
1465
+ expressionY: o === "2d-parametric" ? s : void 0,
1263
1466
  color: {
1264
1467
  r: Math.floor(Math.random() * 200),
1265
1468
  g: Math.floor(Math.random() * 200),
@@ -1271,8 +1474,8 @@ function PlotControls() {
1271
1474
  /* @__PURE__ */ jsx("div", { style: { marginBottom: "8px" }, children: /* @__PURE__ */ jsxs(
1272
1475
  "select",
1273
1476
  {
1274
- value: a,
1275
- onChange: (l) => n(l.target.value),
1477
+ value: o,
1478
+ onChange: (i) => n(i.target.value),
1276
1479
  style: { ...styles$2.input, width: "100%" },
1277
1480
  children: [
1278
1481
  /* @__PURE__ */ jsx("option", { value: "2d-function", children: "y = f(x)" }),
@@ -1286,33 +1489,33 @@ function PlotControls() {
1286
1489
  "input",
1287
1490
  {
1288
1491
  type: "text",
1289
- value: t,
1290
- onChange: (l) => r(l.target.value),
1291
- placeholder: a === "2d-parametric" ? "x(t) = ..." : "Expression...",
1492
+ value: r,
1493
+ onChange: (i) => a(i.target.value),
1494
+ placeholder: o === "2d-parametric" ? "x(t) = ..." : "Expression...",
1292
1495
  style: { ...styles$2.input, width: "100%" }
1293
1496
  }
1294
1497
  ) }),
1295
- a === "2d-parametric" && /* @__PURE__ */ jsx("div", { style: { marginBottom: "8px" }, children: /* @__PURE__ */ jsx(
1498
+ o === "2d-parametric" && /* @__PURE__ */ jsx("div", { style: { marginBottom: "8px" }, children: /* @__PURE__ */ jsx(
1296
1499
  "input",
1297
1500
  {
1298
1501
  type: "text",
1299
- value: o,
1300
- onChange: (l) => s(l.target.value),
1502
+ value: s,
1503
+ onChange: (i) => l(i.target.value),
1301
1504
  placeholder: "y(t) = ...",
1302
1505
  style: { ...styles$2.input, width: "100%" }
1303
1506
  }
1304
1507
  ) }),
1305
- /* @__PURE__ */ jsx("button", { onClick: c, style: { ...styles$2.button, width: "100%" }, children: "+ Add Plot" }),
1508
+ /* @__PURE__ */ jsx("button", { onClick: x, style: { ...styles$2.button, width: "100%" }, children: "+ Add Plot" }),
1306
1509
  /* @__PURE__ */ jsxs(
1307
1510
  "select",
1308
1511
  {
1309
- onChange: (l) => {
1310
- const i = FUNCTION_PRESETS.find((d) => d.name === l.target.value);
1311
- i && e({
1312
- type: i.type,
1313
- expression: i.expression,
1314
- expressionY: i.expressionY,
1315
- label: i.name,
1512
+ onChange: (i) => {
1513
+ const d = FUNCTION_PRESETS.find((g) => g.name === i.target.value);
1514
+ d && t({
1515
+ type: d.type,
1516
+ expression: d.expression,
1517
+ expressionY: d.expressionY,
1518
+ label: d.name,
1316
1519
  color: {
1317
1520
  r: Math.floor(Math.random() * 200),
1318
1521
  g: Math.floor(Math.random() * 200),
@@ -1323,29 +1526,39 @@ function PlotControls() {
1323
1526
  style: { ...styles$2.input, width: "100%", marginTop: "8px" },
1324
1527
  value: "",
1325
1528
  children: [
1326
- /* @__PURE__ */ jsx("option", { value: "", disabled: !0, children: "Quick add preset..." }),
1327
- ["basic", "trigonometric", "exponential", "parametric", "polar", "3d"].map((l) => /* @__PURE__ */ jsx("optgroup", { label: l.charAt(0).toUpperCase() + l.slice(1), children: FUNCTION_PRESETS.filter((i) => i.category === l).map((i) => /* @__PURE__ */ jsxs("option", { value: i.name, children: [
1328
- i.name,
1529
+ /* @__PURE__ */ jsx("option", { value: "", disabled: !0, children: e("plotter.quickAdd", "Quick add preset...") }),
1530
+ ["basic", "trigonometric", "exponential", "parametric", "polar", "3d"].map((i) => /* @__PURE__ */ jsx("optgroup", { label: i.charAt(0).toUpperCase() + i.slice(1), children: FUNCTION_PRESETS.filter((d) => d.category === i).map((d) => /* @__PURE__ */ jsxs("option", { value: d.name, children: [
1531
+ d.name,
1329
1532
  ": ",
1330
- i.expression
1331
- ] }, i.name)) }, l))
1533
+ d.expression
1534
+ ] }, d.name)) }, i))
1332
1535
  ]
1333
1536
  }
1334
1537
  )
1335
1538
  ] });
1336
1539
  }
1337
1540
  function PlotList() {
1338
- const { plots: e, removePlot: t, updatePlot: r } = useGraph();
1541
+ const { t: e } = useNiceTranslation(), { plots: t, removePlot: r, updatePlot: a } = useGraph();
1339
1542
  return /* @__PURE__ */ jsxs("div", { style: styles$2.plotList, children: [
1340
- e.length === 0 && /* @__PURE__ */ jsx("div", { style: { color: "var(--nice-text-secondary, #666)", textAlign: "center", padding: "16px" }, children: "No plots added yet" }),
1341
- e.map((a) => /* @__PURE__ */ jsxs("div", { style: styles$2.plotItem, children: [
1543
+ t.length === 0 && /* @__PURE__ */ jsx(
1544
+ "div",
1545
+ {
1546
+ style: {
1547
+ color: "var(--nice-text-secondary, #666)",
1548
+ textAlign: "center",
1549
+ padding: "16px"
1550
+ },
1551
+ children: e("plotter.noPlots", "No plots added yet")
1552
+ }
1553
+ ),
1554
+ t.map((o) => /* @__PURE__ */ jsxs("div", { style: styles$2.plotItem, children: [
1342
1555
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "8px" }, children: [
1343
1556
  /* @__PURE__ */ jsx(
1344
1557
  "input",
1345
1558
  {
1346
1559
  type: "checkbox",
1347
- checked: a.visible,
1348
- onChange: (n) => r(a.id, { visible: n.target.checked })
1560
+ checked: o.visible,
1561
+ onChange: (n) => a(o.id, { visible: n.target.checked })
1349
1562
  }
1350
1563
  ),
1351
1564
  /* @__PURE__ */ jsx(
@@ -1355,15 +1568,15 @@ function PlotList() {
1355
1568
  width: "16px",
1356
1569
  height: "16px",
1357
1570
  borderRadius: "3px",
1358
- backgroundColor: `rgb(${a.color.r},${a.color.g},${a.color.b})`
1571
+ backgroundColor: `rgb(${o.color.r},${o.color.g},${o.color.b})`
1359
1572
  }
1360
1573
  }
1361
1574
  ),
1362
- /* @__PURE__ */ jsx("span", { style: { flex: 1, fontWeight: 500 }, children: a.label || a.expression }),
1575
+ /* @__PURE__ */ jsx("span", { style: { flex: 1, fontWeight: 500 }, children: o.label || o.expression }),
1363
1576
  /* @__PURE__ */ jsx(
1364
1577
  "button",
1365
1578
  {
1366
- onClick: () => t(a.id),
1579
+ onClick: () => r(o.id),
1367
1580
  style: {
1368
1581
  padding: "2px 6px",
1369
1582
  backgroundColor: "var(--nice-danger, #f44336)",
@@ -1377,23 +1590,33 @@ function PlotList() {
1377
1590
  }
1378
1591
  )
1379
1592
  ] }),
1380
- /* @__PURE__ */ jsx("div", { style: { fontSize: "12px", color: "var(--nice-text-secondary, #666)", fontFamily: "monospace" }, children: a.type === "2d-parametric" ? /* @__PURE__ */ jsxs(Fragment, { children: [
1381
- "x(t) = ",
1382
- a.expression,
1383
- /* @__PURE__ */ jsx("br", {}),
1384
- "y(t) = ",
1385
- a.expressionY
1386
- ] }) : a.expression })
1387
- ] }, a.id))
1593
+ /* @__PURE__ */ jsx(
1594
+ "div",
1595
+ {
1596
+ style: {
1597
+ fontSize: "12px",
1598
+ color: "var(--nice-text-secondary, #666)",
1599
+ fontFamily: "monospace"
1600
+ },
1601
+ children: o.type === "2d-parametric" ? /* @__PURE__ */ jsxs(Fragment, { children: [
1602
+ "x(t) = ",
1603
+ o.expression,
1604
+ /* @__PURE__ */ jsx("br", {}),
1605
+ "y(t) = ",
1606
+ o.expressionY
1607
+ ] }) : o.expression
1608
+ }
1609
+ )
1610
+ ] }, o.id))
1388
1611
  ] });
1389
1612
  }
1390
1613
  function GraphToolbar({ width: e, height: t }) {
1391
- const { service: r, plots: a, view: n, setView: o } = useGraph(), s = () => {
1392
- const l = r.exportSVG(a, n, e, t), i = new Blob([l], { type: "image/svg+xml" }), d = URL.createObjectURL(i), u = document.createElement("a");
1393
- u.href = d, u.download = "graph.svg", u.click(), URL.revokeObjectURL(d);
1394
- }, c = async () => {
1395
- const l = await r.exportPNG(a, n, e, t), i = document.createElement("a");
1396
- i.href = l, i.download = "graph.png", i.click();
1614
+ const { t: r } = useNiceTranslation(), { service: a, plots: o, view: n, setView: s } = useGraph(), l = () => {
1615
+ const i = a.exportSVG(o, n, e, t), d = new Blob([i], { type: "image/svg+xml" }), g = URL.createObjectURL(d), y = document.createElement("a");
1616
+ y.href = g, y.download = "graph.svg", y.click(), URL.revokeObjectURL(g);
1617
+ }, x = async () => {
1618
+ const i = await a.exportPNG(o, n, e, t), d = document.createElement("a");
1619
+ d.href = i, d.download = "graph.png", d.click();
1397
1620
  };
1398
1621
  return /* @__PURE__ */ jsxs("div", { style: styles$2.toolbar, children: [
1399
1622
  /* @__PURE__ */ jsxs("label", { style: { fontSize: "12px" }, children: [
@@ -1404,7 +1627,7 @@ function GraphToolbar({ width: e, height: t }) {
1404
1627
  {
1405
1628
  type: "number",
1406
1629
  value: n.xRange.min,
1407
- onChange: (l) => o({ xRange: { ...n.xRange, min: Number(l.target.value) } }),
1630
+ onChange: (i) => s({ xRange: { ...n.xRange, min: Number(i.target.value) } }),
1408
1631
  style: { ...styles$2.input, width: "50px" }
1409
1632
  }
1410
1633
  ),
@@ -1415,7 +1638,7 @@ function GraphToolbar({ width: e, height: t }) {
1415
1638
  {
1416
1639
  type: "number",
1417
1640
  value: n.xRange.max,
1418
- onChange: (l) => o({ xRange: { ...n.xRange, max: Number(l.target.value) } }),
1641
+ onChange: (i) => s({ xRange: { ...n.xRange, max: Number(i.target.value) } }),
1419
1642
  style: { ...styles$2.input, width: "50px" }
1420
1643
  }
1421
1644
  ),
@@ -1429,7 +1652,7 @@ function GraphToolbar({ width: e, height: t }) {
1429
1652
  {
1430
1653
  type: "number",
1431
1654
  value: n.yRange.min,
1432
- onChange: (l) => o({ yRange: { ...n.yRange, min: Number(l.target.value) } }),
1655
+ onChange: (i) => s({ yRange: { ...n.yRange, min: Number(i.target.value) } }),
1433
1656
  style: { ...styles$2.input, width: "50px" }
1434
1657
  }
1435
1658
  ),
@@ -1440,7 +1663,7 @@ function GraphToolbar({ width: e, height: t }) {
1440
1663
  {
1441
1664
  type: "number",
1442
1665
  value: n.yRange.max,
1443
- onChange: (l) => o({ yRange: { ...n.yRange, max: Number(l.target.value) } }),
1666
+ onChange: (i) => s({ yRange: { ...n.yRange, max: Number(i.target.value) } }),
1444
1667
  style: { ...styles$2.input, width: "50px" }
1445
1668
  }
1446
1669
  ),
@@ -1452,10 +1675,10 @@ function GraphToolbar({ width: e, height: t }) {
1452
1675
  {
1453
1676
  type: "checkbox",
1454
1677
  checked: n.showGrid,
1455
- onChange: (l) => o({ showGrid: l.target.checked })
1678
+ onChange: (i) => s({ showGrid: i.target.checked })
1456
1679
  }
1457
1680
  ),
1458
- "Grid"
1681
+ r("plotter.grid", "Grid")
1459
1682
  ] }),
1460
1683
  /* @__PURE__ */ jsxs("label", { style: { fontSize: "12px" }, children: [
1461
1684
  /* @__PURE__ */ jsx(
@@ -1463,95 +1686,109 @@ function GraphToolbar({ width: e, height: t }) {
1463
1686
  {
1464
1687
  type: "checkbox",
1465
1688
  checked: n.showAxes,
1466
- onChange: (l) => o({ showAxes: l.target.checked })
1689
+ onChange: (i) => s({ showAxes: i.target.checked })
1467
1690
  }
1468
1691
  ),
1469
- "Axes"
1692
+ r("plotter.axes", "Axes")
1470
1693
  ] }),
1471
1694
  /* @__PURE__ */ jsx("div", { style: { flex: 1 } }),
1472
- /* @__PURE__ */ jsx("button", { onClick: s, style: { ...styles$2.button, backgroundColor: "var(--nice-success, #4caf50)" }, children: "📥 SVG" }),
1473
- /* @__PURE__ */ jsx("button", { onClick: c, style: { ...styles$2.button, backgroundColor: "var(--nice-warning, #ff9800)" }, children: "📥 PNG" })
1695
+ /* @__PURE__ */ jsx(
1696
+ "button",
1697
+ {
1698
+ onClick: l,
1699
+ style: { ...styles$2.button, backgroundColor: "var(--nice-success, #4caf50)" },
1700
+ children: "📥 SVG"
1701
+ }
1702
+ ),
1703
+ /* @__PURE__ */ jsx(
1704
+ "button",
1705
+ {
1706
+ onClick: x,
1707
+ style: { ...styles$2.button, backgroundColor: "var(--nice-warning, #ff9800)" },
1708
+ children: "📥 PNG"
1709
+ }
1710
+ )
1474
1711
  ] });
1475
1712
  }
1476
1713
  function Canvas2D({ width: e, height: t }) {
1477
- const r = useRef(null), { service: a, plots: n, view: o, animation: s } = useGraph(), c = 40;
1714
+ const r = useRef(null), { service: a, plots: o, view: n, animation: s } = useGraph(), l = 40;
1478
1715
  return useEffect(() => {
1479
- const l = r.current, i = l == null ? void 0 : l.getContext("2d");
1480
- if (!l || !i)
1716
+ const x = r.current, i = x == null ? void 0 : x.getContext("2d");
1717
+ if (!x || !i)
1481
1718
  return;
1482
- i.fillStyle = `rgb(${o.backgroundColor.r},${o.backgroundColor.g},${o.backgroundColor.b})`, i.fillRect(0, 0, e, t);
1483
- const d = e - c * 2, u = t - c * 2, h = (g) => c + (g - o.xRange.min) / (o.xRange.max - o.xRange.min) * d, b = (g) => t - c - (g - o.yRange.min) / (o.yRange.max - o.yRange.min) * u;
1484
- if (o.showGrid) {
1719
+ i.fillStyle = `rgb(${n.backgroundColor.r},${n.backgroundColor.g},${n.backgroundColor.b})`, i.fillRect(0, 0, e, t);
1720
+ const d = e - l * 2, g = t - l * 2, y = (p) => l + (p - n.xRange.min) / (n.xRange.max - n.xRange.min) * d, h = (p) => t - l - (p - n.yRange.min) / (n.yRange.max - n.yRange.min) * g;
1721
+ if (n.showGrid) {
1485
1722
  i.strokeStyle = "var(--nice-border, #e0e0e0)", i.lineWidth = 0.5;
1486
- for (let g = Math.ceil(o.xRange.min); g <= o.xRange.max; g++) {
1487
- const m = h(g);
1488
- i.beginPath(), i.moveTo(m, c), i.lineTo(m, t - c), i.stroke();
1723
+ for (let p = Math.ceil(n.xRange.min); p <= n.xRange.max; p++) {
1724
+ const f = y(p);
1725
+ i.beginPath(), i.moveTo(f, l), i.lineTo(f, t - l), i.stroke();
1489
1726
  }
1490
- for (let g = Math.ceil(o.yRange.min); g <= o.yRange.max; g++) {
1491
- const m = b(g);
1492
- i.beginPath(), i.moveTo(c, m), i.lineTo(e - c, m), i.stroke();
1727
+ for (let p = Math.ceil(n.yRange.min); p <= n.yRange.max; p++) {
1728
+ const f = h(p);
1729
+ i.beginPath(), i.moveTo(l, f), i.lineTo(e - l, f), i.stroke();
1493
1730
  }
1494
1731
  }
1495
- if (o.showAxes) {
1732
+ if (n.showAxes) {
1496
1733
  i.strokeStyle = "var(--nice-text, #333)", i.lineWidth = 1;
1497
- const g = b(0);
1498
- i.beginPath(), i.moveTo(c, g), i.lineTo(e - c, g), i.stroke();
1499
- const m = h(0);
1500
- if (i.beginPath(), i.moveTo(m, c), i.lineTo(m, t - c), i.stroke(), o.showLabels) {
1501
- i.fillStyle = "var(--nice-text, #333)", i.font = "12px sans-serif", i.textAlign = "center", i.fillText("x", e - c + 15, g + 4), i.fillText("y", m, c - 10), i.font = "10px sans-serif";
1502
- for (let p = Math.ceil(o.xRange.min); p <= o.xRange.max; p++)
1503
- p !== 0 && i.fillText(String(p), h(p), g + 15);
1504
- for (let p = Math.ceil(o.yRange.min); p <= o.yRange.max; p++)
1505
- p !== 0 && (i.textAlign = "right", i.fillText(String(p), m - 5, b(p) + 4));
1734
+ const p = h(0);
1735
+ i.beginPath(), i.moveTo(l, p), i.lineTo(e - l, p), i.stroke();
1736
+ const f = y(0);
1737
+ if (i.beginPath(), i.moveTo(f, l), i.lineTo(f, t - l), i.stroke(), n.showLabels) {
1738
+ i.fillStyle = "var(--nice-text, #333)", i.font = "12px sans-serif", i.textAlign = "center", i.fillText("x", e - l + 15, p + 4), i.fillText("y", f, l - 10), i.font = "10px sans-serif";
1739
+ for (let c = Math.ceil(n.xRange.min); c <= n.xRange.max; c++)
1740
+ c !== 0 && i.fillText(String(c), y(c), p + 15);
1741
+ for (let c = Math.ceil(n.yRange.min); c <= n.yRange.max; c++)
1742
+ c !== 0 && (i.textAlign = "right", i.fillText(String(c), f - 5, h(c) + 4));
1506
1743
  }
1507
1744
  }
1508
- const y = s.isPlaying ? { [s.parameter]: s.currentValue } : {};
1509
- for (const g of n.filter((m) => m.visible)) {
1510
- const m = `rgb(${g.color.r},${g.color.g},${g.color.b})`;
1511
- i.strokeStyle = m, i.lineWidth = g.lineWidth || 2;
1512
- let p = [];
1513
- switch (g.type) {
1745
+ const w = s.isPlaying ? { [s.parameter]: s.currentValue } : {};
1746
+ for (const p of o.filter((f) => f.visible)) {
1747
+ const f = `rgb(${p.color.r},${p.color.g},${p.color.b})`;
1748
+ i.strokeStyle = f, i.lineWidth = p.lineWidth || 2;
1749
+ let c = [];
1750
+ switch (p.type) {
1514
1751
  case "2d-function":
1515
- p = a.compute2DFunction(
1516
- g.expression,
1517
- o.xRange,
1518
- g.resolution || 200,
1519
- y
1752
+ c = a.compute2DFunction(
1753
+ p.expression,
1754
+ n.xRange,
1755
+ p.resolution || 200,
1756
+ w
1520
1757
  );
1521
1758
  break;
1522
1759
  case "2d-parametric":
1523
- p = a.compute2DParametric(
1524
- g.expression,
1525
- g.expressionY || "sin(t)",
1526
- g.parameterRange || { min: 0, max: 2 * Math.PI },
1527
- g.resolution || 200,
1528
- y
1760
+ c = a.compute2DParametric(
1761
+ p.expression,
1762
+ p.expressionY || "sin(t)",
1763
+ p.parameterRange || { min: 0, max: 2 * Math.PI },
1764
+ p.resolution || 200,
1765
+ w
1529
1766
  );
1530
1767
  break;
1531
1768
  case "2d-polar":
1532
- p = a.compute2DPolar(
1533
- g.expression,
1534
- g.parameterRange || { min: 0, max: 2 * Math.PI },
1535
- g.resolution || 200,
1536
- y
1769
+ c = a.compute2DPolar(
1770
+ p.expression,
1771
+ p.parameterRange || { min: 0, max: 2 * Math.PI },
1772
+ p.resolution || 200,
1773
+ w
1537
1774
  );
1538
1775
  break;
1539
1776
  }
1540
- if (p.length > 0) {
1777
+ if (c.length > 0) {
1541
1778
  i.beginPath();
1542
- let x = !1;
1543
- for (const w of p) {
1544
- const k = h(w.x), f = b(w.y);
1545
- if (f < 0 || f > t) {
1546
- x = !1;
1779
+ let u = !1;
1780
+ for (const b of c) {
1781
+ const k = y(b.x), m = h(b.y);
1782
+ if (m < 0 || m > t) {
1783
+ u = !1;
1547
1784
  continue;
1548
1785
  }
1549
- x ? i.lineTo(k, f) : (i.moveTo(k, f), x = !0);
1786
+ u ? i.lineTo(k, m) : (i.moveTo(k, m), u = !0);
1550
1787
  }
1551
1788
  i.stroke();
1552
1789
  }
1553
1790
  }
1554
- }, [n, o, s, a, e, t]), /* @__PURE__ */ jsx("canvas", { ref: r, width: e, height: t, style: styles$2.canvas });
1791
+ }, [o, n, s, a, e, t]), /* @__PURE__ */ jsx("canvas", { ref: r, width: e, height: t, style: styles$2.canvas });
1555
1792
  }
1556
1793
  const UNITS = [
1557
1794
  // Length
@@ -1826,7 +2063,7 @@ const UNITS = [
1826
2063
  ], MatrixOps = {
1827
2064
  create(e, t, r = 0) {
1828
2065
  const a = [];
1829
- for (let n = 0; n < e; n++)
2066
+ for (let o = 0; o < e; o++)
1830
2067
  a.push(new Array(t).fill(r));
1831
2068
  return { rows: e, cols: t, data: a };
1832
2069
  },
@@ -1841,8 +2078,8 @@ const UNITS = [
1841
2078
  throw new Error("Matrix dimensions must match for addition");
1842
2079
  const r = this.create(e.rows, e.cols);
1843
2080
  for (let a = 0; a < e.rows; a++)
1844
- for (let n = 0; n < e.cols; n++)
1845
- r.data[a][n] = e.data[a][n] + t.data[a][n];
2081
+ for (let o = 0; o < e.cols; o++)
2082
+ r.data[a][o] = e.data[a][o] + t.data[a][o];
1846
2083
  return r;
1847
2084
  },
1848
2085
  subtract(e, t) {
@@ -1850,8 +2087,8 @@ const UNITS = [
1850
2087
  throw new Error("Matrix dimensions must match for subtraction");
1851
2088
  const r = this.create(e.rows, e.cols);
1852
2089
  for (let a = 0; a < e.rows; a++)
1853
- for (let n = 0; n < e.cols; n++)
1854
- r.data[a][n] = e.data[a][n] - t.data[a][n];
2090
+ for (let o = 0; o < e.cols; o++)
2091
+ r.data[a][o] = e.data[a][o] - t.data[a][o];
1855
2092
  return r;
1856
2093
  },
1857
2094
  multiply(e, t) {
@@ -1859,19 +2096,19 @@ const UNITS = [
1859
2096
  throw new Error("Matrix A columns must equal Matrix B rows for multiplication");
1860
2097
  const r = this.create(e.rows, t.cols);
1861
2098
  for (let a = 0; a < e.rows; a++)
1862
- for (let n = 0; n < t.cols; n++) {
1863
- let o = 0;
2099
+ for (let o = 0; o < t.cols; o++) {
2100
+ let n = 0;
1864
2101
  for (let s = 0; s < e.cols; s++)
1865
- o += e.data[a][s] * t.data[s][n];
1866
- r.data[a][n] = o;
2102
+ n += e.data[a][s] * t.data[s][o];
2103
+ r.data[a][o] = n;
1867
2104
  }
1868
2105
  return r;
1869
2106
  },
1870
2107
  scalar(e, t) {
1871
2108
  const r = this.create(e.rows, e.cols);
1872
2109
  for (let a = 0; a < e.rows; a++)
1873
- for (let n = 0; n < e.cols; n++)
1874
- r.data[a][n] = e.data[a][n] * t;
2110
+ for (let o = 0; o < e.cols; o++)
2111
+ r.data[a][o] = e.data[a][o] * t;
1875
2112
  return r;
1876
2113
  },
1877
2114
  transpose(e) {
@@ -1895,14 +2132,14 @@ const UNITS = [
1895
2132
  },
1896
2133
  minor(e, t, r) {
1897
2134
  const a = this.create(e.rows - 1, e.cols - 1);
1898
- let n = 0;
1899
- for (let o = 0; o < e.rows; o++) {
1900
- if (o === t)
2135
+ let o = 0;
2136
+ for (let n = 0; n < e.rows; n++) {
2137
+ if (n === t)
1901
2138
  continue;
1902
2139
  let s = 0;
1903
- for (let c = 0; c < e.cols; c++)
1904
- c !== r && (a.data[n][s] = e.data[o][c], s++);
1905
- n++;
2140
+ for (let l = 0; l < e.cols; l++)
2141
+ l !== r && (a.data[o][s] = e.data[n][l], s++);
2142
+ o++;
1906
2143
  }
1907
2144
  return a;
1908
2145
  },
@@ -1911,10 +2148,10 @@ const UNITS = [
1911
2148
  if (t === 0)
1912
2149
  throw new Error("Matrix is singular, cannot compute inverse");
1913
2150
  const r = e.rows, a = this.create(r, r);
1914
- for (let n = 0; n < r; n++)
1915
- for (let o = 0; o < r; o++) {
1916
- const s = Math.pow(-1, n + o), c = this.determinant(this.minor(e, n, o));
1917
- a.data[o][n] = s * c;
2151
+ for (let o = 0; o < r; o++)
2152
+ for (let n = 0; n < r; n++) {
2153
+ const s = Math.pow(-1, o + n), l = this.determinant(this.minor(e, o, n));
2154
+ a.data[n][o] = s * l;
1918
2155
  }
1919
2156
  return this.scalar(a, 1 / t);
1920
2157
  },
@@ -1929,11 +2166,11 @@ const UNITS = [
1929
2166
  eigenvalues2x2(e) {
1930
2167
  if (e.rows !== 2 || e.cols !== 2)
1931
2168
  throw new Error("Only 2x2 matrices supported for eigenvalues");
1932
- const t = e.data[0][0], r = e.data[0][1], a = e.data[1][0], n = e.data[1][1], o = t + n, s = t * n - r * a, c = o * o - 4 * s;
1933
- if (c < 0)
2169
+ const t = e.data[0][0], r = e.data[0][1], a = e.data[1][0], o = e.data[1][1], n = t + o, s = t * o - r * a, l = n * n - 4 * s;
2170
+ if (l < 0)
1934
2171
  throw new Error("Complex eigenvalues not supported");
1935
- const l = Math.sqrt(c);
1936
- return [(o + l) / 2, (o - l) / 2];
2172
+ const x = Math.sqrt(l);
2173
+ return [(n + x) / 2, (n - x) / 2];
1937
2174
  },
1938
2175
  toString(e, t = 4) {
1939
2176
  return e.data.map((r) => "[ " + r.map((a) => a.toFixed(t).padStart(10)).join(" ") + " ]").join(`
@@ -1951,25 +2188,25 @@ const UNITS = [
1951
2188
  /** Numerical integration using Simpson's rule */
1952
2189
  integrate(e, t, r, a = 1e3) {
1953
2190
  a % 2 !== 0 && a++;
1954
- const n = (r - t) / a;
1955
- let o = e(t) + e(r);
2191
+ const o = (r - t) / a;
2192
+ let n = e(t) + e(r);
1956
2193
  for (let s = 1; s < a; s++) {
1957
- const c = t + s * n;
1958
- o += s % 2 === 0 ? 2 * e(c) : 4 * e(c);
2194
+ const l = t + s * o;
2195
+ n += s % 2 === 0 ? 2 * e(l) : 4 * e(l);
1959
2196
  }
1960
- return n / 3 * o;
2197
+ return o / 3 * n;
1961
2198
  },
1962
2199
  /** Find root using Newton-Raphson method */
1963
2200
  findRoot(e, t, r = 1e-10, a = 100) {
1964
- let n = t;
1965
- for (let o = 0; o < a; o++) {
1966
- const s = e(n);
2201
+ let o = t;
2202
+ for (let n = 0; n < a; n++) {
2203
+ const s = e(o);
1967
2204
  if (Math.abs(s) < r)
1968
- return n;
1969
- const c = this.derivative(e, n);
1970
- if (c === 0)
2205
+ return o;
2206
+ const l = this.derivative(e, o);
2207
+ if (l === 0)
1971
2208
  throw new Error("Derivative is zero, Newton-Raphson failed");
1972
- n = n - s / c;
2209
+ o = o - s / l;
1973
2210
  }
1974
2211
  throw new Error("Newton-Raphson did not converge");
1975
2212
  },
@@ -1986,8 +2223,8 @@ const UNITS = [
1986
2223
  }
1987
2224
  const r = e.match(/^(-?\d+\.?\d*)\*x\^(\d+)$/);
1988
2225
  if (r) {
1989
- const a = parseFloat(r[1]), n = parseInt(r[2], 10), o = a * n;
1990
- return n === 1 ? String(o) : n === 2 ? `${o}*x` : `${o}*x^${n - 1}`;
2226
+ const a = parseFloat(r[1]), o = parseInt(r[2], 10), n = a * o;
2227
+ return o === 1 ? String(n) : o === 2 ? `${n}*x` : `${n}*x^${o - 1}`;
1991
2228
  }
1992
2229
  return e === "sin(x)" ? "cos(x)" : e === "cos(x)" ? "-sin(x)" : e === "e^x" || e === "exp(x)" ? "e^x" : e === "ln(x)" ? "1/x" : `d/dx(${e})`;
1993
2230
  },
@@ -2011,8 +2248,8 @@ const UNITS = [
2011
2248
  throw new Error("No real solutions (complex roots)");
2012
2249
  if (a === 0)
2013
2250
  return [-t / (2 * e)];
2014
- const n = Math.sqrt(a);
2015
- return [(-t + n) / (2 * e), (-t - n) / (2 * e)];
2251
+ const o = Math.sqrt(a);
2252
+ return [(-t + o) / (2 * e), (-t - o) / (2 * e)];
2016
2253
  }
2017
2254
  };
2018
2255
  class CalculatorService {
@@ -2080,20 +2317,20 @@ class CalculatorService {
2080
2317
  }
2081
2318
  /** Convert between number bases */
2082
2319
  convertBase(e, t, r) {
2083
- const a = { BIN: 2, OCT: 8, DEC: 10, HEX: 16 }, n = parseInt(e, a[t]);
2084
- if (isNaN(n))
2320
+ const a = { BIN: 2, OCT: 8, DEC: 10, HEX: 16 }, o = parseInt(e, a[t]);
2321
+ if (isNaN(o))
2085
2322
  throw new Error("Invalid number for base conversion");
2086
- return n.toString(a[r]).toUpperCase();
2323
+ return o.toString(a[r]).toUpperCase();
2087
2324
  }
2088
2325
  /** Convert units */
2089
2326
  convertUnits(e, t, r) {
2090
- const a = UNITS.find((s) => s.symbol === t), n = UNITS.find((s) => s.symbol === r);
2091
- if (!a || !n)
2327
+ const a = UNITS.find((s) => s.symbol === t), o = UNITS.find((s) => s.symbol === r);
2328
+ if (!a || !o)
2092
2329
  throw new Error("Unknown unit");
2093
- if (a.category !== n.category)
2330
+ if (a.category !== o.category)
2094
2331
  throw new Error("Cannot convert between different unit categories");
2095
- const o = a.toBase(e);
2096
- return n.fromBase(o);
2332
+ const n = a.toBase(e);
2333
+ return o.fromBase(n);
2097
2334
  }
2098
2335
  /** Get units by category */
2099
2336
  getUnitsByCategory(e) {
@@ -2182,40 +2419,40 @@ function NiceCalculator({
2182
2419
  className: t,
2183
2420
  style: r
2184
2421
  }) {
2185
- const [a, n] = useState("0"), [o, s] = useState("standard"), [c, l] = useState([]), [i, d] = useState(!1), u = useCallback(
2186
- (g) => {
2187
- i && /[0-9.]/.test(g) ? (n(g), d(!1)) : (n((m) => m === "0" && g !== "." ? g : m + g), d(!1));
2422
+ const [a, o] = useState("0"), [n, s] = useState("standard"), [l, x] = useState([]), [i, d] = useState(!1), g = useCallback(
2423
+ (p) => {
2424
+ i && /[0-9.]/.test(p) ? (o(p), d(!1)) : (o((f) => f === "0" && p !== "." ? p : f + p), d(!1));
2188
2425
  },
2189
2426
  [i]
2190
- ), h = useCallback(() => {
2191
- n("0"), d(!1);
2192
- }, []), b = useCallback(() => {
2427
+ ), y = useCallback(() => {
2428
+ o("0"), d(!1);
2429
+ }, []), h = useCallback(() => {
2193
2430
  try {
2194
- const g = e.evaluate(a), m = e.format(g);
2195
- e.addHistory(a, m, o), l(e.getHistory()), n(m), d(!0);
2431
+ const p = e.evaluate(a), f = e.format(p);
2432
+ e.addHistory(a, f, n), x(e.getHistory()), o(f), d(!0);
2196
2433
  } catch {
2197
- n("Error"), d(!0);
2434
+ o("Error"), d(!0);
2198
2435
  }
2199
- }, [a, o, e]), y = {
2436
+ }, [a, n, e]), w = {
2200
2437
  service: e,
2201
2438
  display: a,
2202
- setDisplay: n,
2203
- mode: o,
2439
+ setDisplay: o,
2440
+ mode: n,
2204
2441
  setMode: s,
2205
- history: c,
2206
- calculate: b,
2207
- appendDigit: u,
2208
- clear: h
2442
+ history: l,
2443
+ calculate: h,
2444
+ appendDigit: g,
2445
+ clear: y
2209
2446
  };
2210
- return /* @__PURE__ */ jsx(CalculatorContext.Provider, { value: y, children: /* @__PURE__ */ jsxs("div", { className: t, style: { ...styles$1.container, ...r }, children: [
2447
+ return /* @__PURE__ */ jsx(CalculatorContext.Provider, { value: w, children: /* @__PURE__ */ jsxs("div", { className: t, style: { ...styles$1.container, ...r }, children: [
2211
2448
  /* @__PURE__ */ jsx(ModeSelector, {}),
2212
2449
  /* @__PURE__ */ jsx(Display, {}),
2213
- o === "standard" && /* @__PURE__ */ jsx(StandardKeypad, {}),
2214
- o === "scientific" && /* @__PURE__ */ jsx(ScientificKeypad, {}),
2215
- o === "programmer" && /* @__PURE__ */ jsx(ProgrammerKeypad, {}),
2216
- o === "matrix" && /* @__PURE__ */ jsx(MatrixMode, {}),
2217
- o === "calculus" && /* @__PURE__ */ jsx(CalculusMode, {}),
2218
- o === "units" && /* @__PURE__ */ jsx(UnitsMode, {})
2450
+ n === "standard" && /* @__PURE__ */ jsx(StandardKeypad, {}),
2451
+ n === "scientific" && /* @__PURE__ */ jsx(ScientificKeypad, {}),
2452
+ n === "programmer" && /* @__PURE__ */ jsx(ProgrammerKeypad, {}),
2453
+ n === "matrix" && /* @__PURE__ */ jsx(MatrixMode, {}),
2454
+ n === "calculus" && /* @__PURE__ */ jsx(CalculusMode, {}),
2455
+ n === "units" && /* @__PURE__ */ jsx(UnitsMode, {})
2219
2456
  ] }) });
2220
2457
  }
2221
2458
  function ModeSelector() {
@@ -2246,11 +2483,11 @@ function Display() {
2246
2483
  return /* @__PURE__ */ jsx("div", { style: styles$1.display, children: /* @__PURE__ */ jsx("div", { style: styles$1.displayText, children: e }) });
2247
2484
  }
2248
2485
  function StandardKeypad() {
2249
- const { appendDigit: e, clear: t, calculate: r, setDisplay: a, display: n } = useCalculator(), o = [
2486
+ const { appendDigit: e, clear: t, calculate: r, setDisplay: a, display: o } = useCalculator(), n = [
2250
2487
  { label: "AC", action: t, style: styles$1.keyFunction },
2251
2488
  {
2252
2489
  label: "±",
2253
- action: () => a(n.startsWith("-") ? n.slice(1) : "-" + n),
2490
+ action: () => a(o.startsWith("-") ? o.slice(1) : "-" + o),
2254
2491
  style: styles$1.keyFunction
2255
2492
  },
2256
2493
  { label: "%", action: () => e("/100"), style: styles$1.keyFunction },
@@ -2269,13 +2506,19 @@ function StandardKeypad() {
2269
2506
  { label: "+", action: () => e("+"), style: styles$1.keyOperator },
2270
2507
  { label: "0", action: () => e("0") },
2271
2508
  { label: ".", action: () => e(".") },
2272
- { label: "⌫", action: () => a(n.length > 1 ? n.slice(0, -1) : "0") },
2509
+ { label: "⌫", action: () => a(o.length > 1 ? o.slice(0, -1) : "0") },
2273
2510
  { label: "=", action: r, style: styles$1.keyOperator }
2274
2511
  ];
2275
- return /* @__PURE__ */ jsx("div", { style: styles$1.keypad, children: o.map((s, c) => /* @__PURE__ */ jsx("button", { onClick: s.action, style: { ...styles$1.key, ...s.style || {} }, children: s.label }, c)) });
2512
+ return /* @__PURE__ */ jsx("div", { style: styles$1.keypad, children: n.map((s, l) => /* @__PURE__ */ jsx("button", { onClick: s.action, style: { ...styles$1.key, ...s.style || {} }, children: s.label }, l)) });
2276
2513
  }
2277
2514
  function ScientificKeypad() {
2278
- const { appendDigit: e, clear: t, calculate: r, setDisplay: a, display: n } = useCalculator(), o = [
2515
+ const {
2516
+ appendDigit: e,
2517
+ clear: t,
2518
+ calculate: r,
2519
+ setDisplay: a,
2520
+ display: o
2521
+ } = useCalculator(), n = [
2279
2522
  { label: "sin", action: () => e("sin(") },
2280
2523
  { label: "cos", action: () => e("cos(") },
2281
2524
  { label: "tan", action: () => e("tan(") },
@@ -2287,7 +2530,7 @@ function ScientificKeypad() {
2287
2530
  { label: "xʸ", action: () => e("^") },
2288
2531
  { label: "√", action: () => e("sqrt(") },
2289
2532
  { label: "eˣ", action: () => e("exp(") }
2290
- ], c = [
2533
+ ], l = [
2291
2534
  { label: "(", action: () => e("(") },
2292
2535
  { label: ")", action: () => e(")") },
2293
2536
  { label: "π", action: () => e("π") },
@@ -2295,12 +2538,12 @@ function ScientificKeypad() {
2295
2538
  { label: "AC", action: t }
2296
2539
  ];
2297
2540
  return /* @__PURE__ */ jsxs("div", { children: [
2298
- /* @__PURE__ */ jsx("div", { style: { ...styles$1.keypad, gridTemplateColumns: "repeat(5, 1fr)" }, children: [...o, ...s, ...c].map((l, i) => /* @__PURE__ */ jsx(
2541
+ /* @__PURE__ */ jsx("div", { style: { ...styles$1.keypad, gridTemplateColumns: "repeat(5, 1fr)" }, children: [...n, ...s, ...l].map((x, i) => /* @__PURE__ */ jsx(
2299
2542
  "button",
2300
2543
  {
2301
- onClick: l.action,
2544
+ onClick: x.action,
2302
2545
  style: { ...styles$1.key, ...styles$1.keyFunction, padding: "12px" },
2303
- children: l.label
2546
+ children: x.label
2304
2547
  },
2305
2548
  i
2306
2549
  )) }),
@@ -2308,40 +2551,51 @@ function ScientificKeypad() {
2308
2551
  ] });
2309
2552
  }
2310
2553
  function ProgrammerKeypad() {
2311
- const { display: e, setDisplay: t, service: r } = useCalculator(), [a, n] = useState("DEC"), o = (c) => {
2554
+ const { display: e, setDisplay: t, service: r } = useCalculator(), [a, o] = useState("DEC"), n = (l) => {
2312
2555
  try {
2313
- const l = r.convertBase(e, a, c);
2314
- t(l), n(c);
2556
+ const x = r.convertBase(e, a, l);
2557
+ t(x), o(l);
2315
2558
  } catch {
2316
2559
  t("Error");
2317
2560
  }
2318
2561
  }, s = a === "HEX" ? ["A", "B", "C", "D", "E", "F"] : [];
2319
2562
  return /* @__PURE__ */ jsxs("div", { children: [
2320
- /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: "4px", padding: "8px", backgroundColor: "var(--nice-bg-secondary, #252525)" }, children: ["BIN", "OCT", "DEC", "HEX"].map((c) => /* @__PURE__ */ jsx(
2321
- "button",
2563
+ /* @__PURE__ */ jsx(
2564
+ "div",
2322
2565
  {
2323
- onClick: () => o(c),
2324
2566
  style: {
2325
- flex: 1,
2567
+ display: "flex",
2568
+ gap: "4px",
2326
2569
  padding: "8px",
2327
- border: "none",
2328
- borderRadius: "4px",
2329
- backgroundColor: a === c ? "var(--nice-primary-hover, #1976d2)" : "var(--nice-border, #3c3c3c)",
2330
- color: "var(--nice-bg, #fff)",
2331
- cursor: "pointer"
2570
+ backgroundColor: "var(--nice-bg-secondary, #252525)"
2332
2571
  },
2333
- children: c
2334
- },
2335
- c
2336
- )) }),
2337
- s.length > 0 && /* @__PURE__ */ jsx("div", { style: { ...styles$1.keypad, gridTemplateColumns: "repeat(6, 1fr)" }, children: s.map((c) => /* @__PURE__ */ jsx(
2572
+ children: ["BIN", "OCT", "DEC", "HEX"].map((l) => /* @__PURE__ */ jsx(
2573
+ "button",
2574
+ {
2575
+ onClick: () => n(l),
2576
+ style: {
2577
+ flex: 1,
2578
+ padding: "8px",
2579
+ border: "none",
2580
+ borderRadius: "4px",
2581
+ backgroundColor: a === l ? "var(--nice-primary-hover, #1976d2)" : "var(--nice-border, #3c3c3c)",
2582
+ color: "var(--nice-bg, #fff)",
2583
+ cursor: "pointer"
2584
+ },
2585
+ children: l
2586
+ },
2587
+ l
2588
+ ))
2589
+ }
2590
+ ),
2591
+ s.length > 0 && /* @__PURE__ */ jsx("div", { style: { ...styles$1.keypad, gridTemplateColumns: "repeat(6, 1fr)" }, children: s.map((l) => /* @__PURE__ */ jsx(
2338
2592
  "button",
2339
2593
  {
2340
- onClick: () => t(e === "0" ? c : e + c),
2594
+ onClick: () => t(e === "0" ? l : e + l),
2341
2595
  style: styles$1.key,
2342
- children: c
2596
+ children: l
2343
2597
  },
2344
- c
2598
+ l
2345
2599
  )) }),
2346
2600
  /* @__PURE__ */ jsx("div", { style: { ...styles$1.keypad, gridTemplateColumns: "repeat(4, 1fr)" }, children: [
2347
2601
  "7",
@@ -2360,63 +2614,63 @@ function ProgrammerKeypad() {
2360
2614
  "NOT",
2361
2615
  "<<",
2362
2616
  ">>"
2363
- ].map((c) => {
2364
- const l = ["AND", "OR", "XOR", "NOT", "<<", ">>"].includes(c);
2617
+ ].map((l) => {
2618
+ const x = ["AND", "OR", "XOR", "NOT", "<<", ">>"].includes(l);
2365
2619
  return /* @__PURE__ */ jsx(
2366
2620
  "button",
2367
2621
  {
2368
- onClick: () => t(e === "0" ? c : e + c),
2369
- style: { ...styles$1.key, ...l ? styles$1.keyFunction : {} },
2370
- children: c
2622
+ onClick: () => t(e === "0" ? l : e + l),
2623
+ style: { ...styles$1.key, ...x ? styles$1.keyFunction : {} },
2624
+ children: l
2371
2625
  },
2372
- c
2626
+ l
2373
2627
  );
2374
2628
  }) })
2375
2629
  ] });
2376
2630
  }
2377
2631
  function MatrixMode() {
2378
- const [e, t] = useState(MatrixOps.create(2, 2)), [r, a] = useState(MatrixOps.create(2, 2)), [n, o] = useState(""), s = (l, i, d, u, h) => {
2379
- const b = { ...l, data: l.data.map((y) => [...y]) };
2380
- b.data[d][u] = parseFloat(h) || 0, i(b);
2381
- };
2632
+ const { t: e } = useNiceTranslation(), [t, r] = useState(MatrixOps.create(2, 2)), [a, o] = useState(MatrixOps.create(2, 2)), [n, s] = useState(""), l = (i, d, g, y, h) => {
2633
+ const w = { ...i, data: i.data.map((p) => [...p]) };
2634
+ w.data[g][y] = parseFloat(h) || 0, d(w);
2635
+ }, x = [
2636
+ { label: "A + B", fn: () => MatrixOps.toString(MatrixOps.add(t, a)) },
2637
+ { label: "A - B", fn: () => MatrixOps.toString(MatrixOps.subtract(t, a)) },
2638
+ { label: "A × B", fn: () => MatrixOps.toString(MatrixOps.multiply(t, a)) },
2639
+ { label: "det(A)", fn: () => MatrixOps.determinant(t).toFixed(4) },
2640
+ { label: "Aᵀ", fn: () => MatrixOps.toString(MatrixOps.transpose(t)) },
2641
+ { label: "A⁻¹", fn: () => MatrixOps.toString(MatrixOps.inverse(t)) }
2642
+ ];
2382
2643
  return /* @__PURE__ */ jsxs("div", { style: { padding: "12px", backgroundColor: "var(--nice-bg-secondary, #252525)" }, children: [
2383
2644
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "12px", marginBottom: "12px" }, children: [
2384
2645
  /* @__PURE__ */ jsxs("div", { children: [
2385
- /* @__PURE__ */ jsx("div", { style: { color: "var(--nice-text-secondary, #888)", marginBottom: "4px" }, children: "Matrix A" }),
2646
+ /* @__PURE__ */ jsx("div", { style: { color: "var(--nice-text-secondary, #888)", marginBottom: "4px" }, children: e("calculator.matrixA", "Matrix A") }),
2386
2647
  /* @__PURE__ */ jsx(
2387
2648
  MatrixInput,
2388
2649
  {
2389
- matrix: e,
2390
- onChange: (l, i, d) => s(e, t, l, i, d)
2650
+ matrix: t,
2651
+ onChange: (i, d, g) => l(t, r, i, d, g)
2391
2652
  }
2392
2653
  )
2393
2654
  ] }),
2394
2655
  /* @__PURE__ */ jsxs("div", { children: [
2395
- /* @__PURE__ */ jsx("div", { style: { color: "var(--nice-text-secondary, #888)", marginBottom: "4px" }, children: "Matrix B" }),
2656
+ /* @__PURE__ */ jsx("div", { style: { color: "var(--nice-text-secondary, #888)", marginBottom: "4px" }, children: e("calculator.matrixB", "Matrix B") }),
2396
2657
  /* @__PURE__ */ jsx(
2397
2658
  MatrixInput,
2398
2659
  {
2399
- matrix: r,
2400
- onChange: (l, i, d) => s(r, a, l, i, d)
2660
+ matrix: a,
2661
+ onChange: (i, d, g) => l(a, o, i, d, g)
2401
2662
  }
2402
2663
  )
2403
2664
  ] })
2404
2665
  ] }),
2405
- /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: "4px", flexWrap: "wrap", marginBottom: "12px" }, children: [
2406
- { label: "A + B", fn: () => MatrixOps.toString(MatrixOps.add(e, r)) },
2407
- { label: "A - B", fn: () => MatrixOps.toString(MatrixOps.subtract(e, r)) },
2408
- { label: "A × B", fn: () => MatrixOps.toString(MatrixOps.multiply(e, r)) },
2409
- { label: "det(A)", fn: () => MatrixOps.determinant(e).toFixed(4) },
2410
- { label: "Aᵀ", fn: () => MatrixOps.toString(MatrixOps.transpose(e)) },
2411
- { label: "A⁻¹", fn: () => MatrixOps.toString(MatrixOps.inverse(e)) }
2412
- ].map((l) => /* @__PURE__ */ jsx(
2666
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: "4px", flexWrap: "wrap", marginBottom: "12px" }, children: x.map((i) => /* @__PURE__ */ jsx(
2413
2667
  "button",
2414
2668
  {
2415
2669
  onClick: () => {
2416
2670
  try {
2417
- o(l.fn());
2418
- } catch (i) {
2419
- o(i.message);
2671
+ s(i.fn());
2672
+ } catch (d) {
2673
+ s(d.message);
2420
2674
  }
2421
2675
  },
2422
2676
  style: {
@@ -2427,11 +2681,17 @@ function MatrixMode() {
2427
2681
  borderRadius: "4px",
2428
2682
  cursor: "pointer"
2429
2683
  },
2430
- children: l.label
2684
+ children: i.label
2431
2685
  },
2432
- l.label
2686
+ i.label
2433
2687
  )) }),
2434
- n && /* @__PURE__ */ jsx("pre", { style: { color: "var(--nice-bg, #fff)", fontFamily: "monospace", whiteSpace: "pre-wrap" }, children: n })
2688
+ n && /* @__PURE__ */ jsx(
2689
+ "pre",
2690
+ {
2691
+ style: { color: "var(--nice-bg, #fff)", fontFamily: "monospace", whiteSpace: "pre-wrap" },
2692
+ children: n
2693
+ }
2694
+ )
2435
2695
  ] });
2436
2696
  }
2437
2697
  function MatrixInput({
@@ -2443,12 +2703,12 @@ function MatrixInput({
2443
2703
  {
2444
2704
  style: { display: "grid", gridTemplateColumns: `repeat(${e.cols}, 50px)`, gap: "4px" },
2445
2705
  children: e.data.map(
2446
- (r, a) => r.map((n, o) => /* @__PURE__ */ jsx(
2706
+ (r, a) => r.map((o, n) => /* @__PURE__ */ jsx(
2447
2707
  "input",
2448
2708
  {
2449
2709
  type: "number",
2450
- value: n,
2451
- onChange: (s) => t(a, o, s.target.value),
2710
+ value: o,
2711
+ onChange: (s) => t(a, n, s.target.value),
2452
2712
  style: {
2453
2713
  width: "100%",
2454
2714
  padding: "4px",
@@ -2459,22 +2719,22 @@ function MatrixInput({
2459
2719
  borderRadius: "4px"
2460
2720
  }
2461
2721
  },
2462
- `${a}-${o}`
2722
+ `${a}-${n}`
2463
2723
  ))
2464
2724
  )
2465
2725
  }
2466
2726
  );
2467
2727
  }
2468
2728
  function CalculusMode() {
2469
- const [e, t] = useState("x^2"), [r, a] = useState("");
2729
+ const { t: e } = useNiceTranslation(), [t, r] = useState("x^2"), [a, o] = useState("");
2470
2730
  return /* @__PURE__ */ jsxs("div", { style: { padding: "12px", backgroundColor: "var(--nice-bg-secondary, #252525)" }, children: [
2471
2731
  /* @__PURE__ */ jsx(
2472
2732
  "input",
2473
2733
  {
2474
2734
  type: "text",
2475
- value: e,
2476
- onChange: (n) => t(n.target.value),
2477
- placeholder: "Enter expression (e.g., x^2, sin(x))",
2735
+ value: t,
2736
+ onChange: (n) => r(n.target.value),
2737
+ placeholder: e("calculator.exprPlaceholder", "Enter expression (e.g., x^2, sin(x))"),
2478
2738
  style: {
2479
2739
  width: "100%",
2480
2740
  padding: "8px",
@@ -2490,7 +2750,7 @@ function CalculusMode() {
2490
2750
  /* @__PURE__ */ jsx(
2491
2751
  "button",
2492
2752
  {
2493
- onClick: () => a(`d/dx(${e}) = ${CalculusOps.symbolicDerivative(e)}`),
2753
+ onClick: () => o(`d/dx(${t}) = ${CalculusOps.symbolicDerivative(t)}`),
2494
2754
  style: {
2495
2755
  padding: "8px 12px",
2496
2756
  backgroundColor: "var(--nice-success, #4caf50)",
@@ -2499,13 +2759,13 @@ function CalculusMode() {
2499
2759
  borderRadius: "4px",
2500
2760
  cursor: "pointer"
2501
2761
  },
2502
- children: "Differentiate"
2762
+ children: e("calculator.differentiate", "Differentiate")
2503
2763
  }
2504
2764
  ),
2505
2765
  /* @__PURE__ */ jsx(
2506
2766
  "button",
2507
2767
  {
2508
- onClick: () => a(`∫(${e})dx = ${CalculusOps.symbolicIntegral(e)}`),
2768
+ onClick: () => o(`∫(${t})dx = ${CalculusOps.symbolicIntegral(t)}`),
2509
2769
  style: {
2510
2770
  padding: "8px 12px",
2511
2771
  backgroundColor: "var(--nice-primary, #2196f3)",
@@ -2514,11 +2774,11 @@ function CalculusMode() {
2514
2774
  borderRadius: "4px",
2515
2775
  cursor: "pointer"
2516
2776
  },
2517
- children: "Integrate"
2777
+ children: e("calculator.integrate", "Integrate")
2518
2778
  }
2519
2779
  )
2520
2780
  ] }),
2521
- r && /* @__PURE__ */ jsx(
2781
+ a && /* @__PURE__ */ jsx(
2522
2782
  "div",
2523
2783
  {
2524
2784
  style: {
@@ -2528,29 +2788,29 @@ function CalculusMode() {
2528
2788
  backgroundColor: "var(--nice-bg, #1e1e1e)",
2529
2789
  borderRadius: "4px"
2530
2790
  },
2531
- children: r
2791
+ children: a
2532
2792
  }
2533
2793
  )
2534
2794
  ] });
2535
2795
  }
2536
2796
  function UnitsMode() {
2537
- const { service: e } = useCalculator(), [t, r] = useState("1"), [a, n] = useState("m"), [o, s] = useState("ft"), [c, l] = useState("Length"), [i, d] = useState(""), u = e.getUnitCategories(), h = e.getUnitsByCategory(c), b = () => {
2797
+ const { t: e } = useNiceTranslation(), { service: t } = useCalculator(), [r, a] = useState("1"), [o, n] = useState("m"), [s, l] = useState("ft"), [x, i] = useState("Length"), [d, g] = useState(""), y = t.getUnitCategories(), h = t.getUnitsByCategory(x), w = () => {
2538
2798
  try {
2539
- const y = e.convertUnits(parseFloat(t), a, o);
2540
- d(`${t} ${a} = ${e.format(y)} ${o}`);
2541
- } catch (y) {
2542
- d(y.message);
2799
+ const p = t.convertUnits(parseFloat(r), o, s);
2800
+ g(`${r} ${o} = ${t.format(p)} ${s}`);
2801
+ } catch (p) {
2802
+ g(p.message);
2543
2803
  }
2544
2804
  };
2545
2805
  return /* @__PURE__ */ jsxs("div", { style: { padding: "12px", backgroundColor: "var(--nice-bg-secondary, #252525)" }, children: [
2546
2806
  /* @__PURE__ */ jsx(
2547
2807
  "select",
2548
2808
  {
2549
- value: c,
2550
- onChange: (y) => {
2551
- l(y.target.value);
2552
- const g = e.getUnitsByCategory(y.target.value);
2553
- g.length >= 2 && (n(g[0].symbol), s(g[1].symbol));
2809
+ value: x,
2810
+ onChange: (p) => {
2811
+ i(p.target.value);
2812
+ const f = t.getUnitsByCategory(p.target.value);
2813
+ f.length >= 2 && (n(f[0].symbol), l(f[1].symbol));
2554
2814
  },
2555
2815
  style: {
2556
2816
  width: "100%",
@@ -2561,7 +2821,7 @@ function UnitsMode() {
2561
2821
  border: "1px solid var(--nice-text-secondary, #555)",
2562
2822
  borderRadius: "4px"
2563
2823
  },
2564
- children: u.map((y) => /* @__PURE__ */ jsx("option", { value: y, children: y }, y))
2824
+ children: y.map((p) => /* @__PURE__ */ jsx("option", { value: p, children: p }, p))
2565
2825
  }
2566
2826
  ),
2567
2827
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", alignItems: "center", marginBottom: "12px" }, children: [
@@ -2569,8 +2829,8 @@ function UnitsMode() {
2569
2829
  "input",
2570
2830
  {
2571
2831
  type: "number",
2572
- value: t,
2573
- onChange: (y) => r(y.target.value),
2832
+ value: r,
2833
+ onChange: (p) => a(p.target.value),
2574
2834
  style: {
2575
2835
  flex: 1,
2576
2836
  padding: "8px",
@@ -2584,8 +2844,8 @@ function UnitsMode() {
2584
2844
  /* @__PURE__ */ jsx(
2585
2845
  "select",
2586
2846
  {
2587
- value: a,
2588
- onChange: (y) => n(y.target.value),
2847
+ value: o,
2848
+ onChange: (p) => n(p.target.value),
2589
2849
  style: {
2590
2850
  padding: "8px",
2591
2851
  backgroundColor: "var(--nice-border, #3c3c3c)",
@@ -2593,12 +2853,12 @@ function UnitsMode() {
2593
2853
  border: "1px solid var(--nice-text-secondary, #555)",
2594
2854
  borderRadius: "4px"
2595
2855
  },
2596
- children: h.map((y) => /* @__PURE__ */ jsxs("option", { value: y.symbol, children: [
2597
- y.name,
2856
+ children: h.map((p) => /* @__PURE__ */ jsxs("option", { value: p.symbol, children: [
2857
+ p.name,
2598
2858
  " (",
2599
- y.symbol,
2859
+ p.symbol,
2600
2860
  ")"
2601
- ] }, y.symbol))
2861
+ ] }, p.symbol))
2602
2862
  }
2603
2863
  )
2604
2864
  ] }),
@@ -2607,8 +2867,8 @@ function UnitsMode() {
2607
2867
  /* @__PURE__ */ jsx(
2608
2868
  "select",
2609
2869
  {
2610
- value: o,
2611
- onChange: (y) => s(y.target.value),
2870
+ value: s,
2871
+ onChange: (p) => l(p.target.value),
2612
2872
  style: {
2613
2873
  flex: 1,
2614
2874
  padding: "8px",
@@ -2617,19 +2877,19 @@ function UnitsMode() {
2617
2877
  border: "1px solid var(--nice-text-secondary, #555)",
2618
2878
  borderRadius: "4px"
2619
2879
  },
2620
- children: h.map((y) => /* @__PURE__ */ jsxs("option", { value: y.symbol, children: [
2621
- y.name,
2880
+ children: h.map((p) => /* @__PURE__ */ jsxs("option", { value: p.symbol, children: [
2881
+ p.name,
2622
2882
  " (",
2623
- y.symbol,
2883
+ p.symbol,
2624
2884
  ")"
2625
- ] }, y.symbol))
2885
+ ] }, p.symbol))
2626
2886
  }
2627
2887
  )
2628
2888
  ] }),
2629
2889
  /* @__PURE__ */ jsx(
2630
2890
  "button",
2631
2891
  {
2632
- onClick: b,
2892
+ onClick: w,
2633
2893
  style: {
2634
2894
  width: "100%",
2635
2895
  padding: "12px",
@@ -2640,10 +2900,21 @@ function UnitsMode() {
2640
2900
  fontSize: "16px",
2641
2901
  cursor: "pointer"
2642
2902
  },
2643
- children: "Convert"
2903
+ children: e("calculator.convert", "Convert")
2644
2904
  }
2645
2905
  ),
2646
- i && /* @__PURE__ */ jsx("div", { style: { marginTop: "12px", color: "var(--nice-bg, #fff)", fontSize: "18px", textAlign: "center" }, children: i })
2906
+ d && /* @__PURE__ */ jsx(
2907
+ "div",
2908
+ {
2909
+ style: {
2910
+ marginTop: "12px",
2911
+ color: "var(--nice-bg, #fff)",
2912
+ fontSize: "18px",
2913
+ textAlign: "center"
2914
+ },
2915
+ children: d
2916
+ }
2917
+ )
2647
2918
  ] });
2648
2919
  }
2649
2920
  const GeoMath = {
@@ -2658,8 +2929,8 @@ const GeoMath = {
2658
2929
  /** Angle between three points (vertex at p2) */
2659
2930
  angle(e, t, r) {
2660
2931
  const a = Math.atan2(e.y - t.y, e.x - t.x);
2661
- let o = Math.atan2(r.y - t.y, r.x - t.x) - a;
2662
- return o < 0 && (o += 2 * Math.PI), o;
2932
+ let n = Math.atan2(r.y - t.y, r.x - t.x) - a;
2933
+ return n < 0 && (n += 2 * Math.PI), n;
2663
2934
  },
2664
2935
  /** Angle in degrees */
2665
2936
  angleDegrees(e, t, r) {
@@ -2667,63 +2938,63 @@ const GeoMath = {
2667
2938
  },
2668
2939
  /** Point on line closest to given point */
2669
2940
  closestPointOnLine(e, t, r) {
2670
- const a = t.x - e.x, n = t.y - e.y, o = ((r.x - e.x) * a + (r.y - e.y) * n) / (a * a + n * n);
2671
- return { x: e.x + o * a, y: e.y + o * n };
2941
+ const a = t.x - e.x, o = t.y - e.y, n = ((r.x - e.x) * a + (r.y - e.y) * o) / (a * a + o * o);
2942
+ return { x: e.x + n * a, y: e.y + n * o };
2672
2943
  },
2673
2944
  /** Line-line intersection */
2674
2945
  lineIntersection(e, t, r, a) {
2675
- const n = (e.x - t.x) * (r.y - a.y) - (e.y - t.y) * (r.x - a.x);
2676
- if (Math.abs(n) < 1e-10)
2946
+ const o = (e.x - t.x) * (r.y - a.y) - (e.y - t.y) * (r.x - a.x);
2947
+ if (Math.abs(o) < 1e-10)
2677
2948
  return null;
2678
- const o = ((e.x - r.x) * (r.y - a.y) - (e.y - r.y) * (r.x - a.x)) / n;
2949
+ const n = ((e.x - r.x) * (r.y - a.y) - (e.y - r.y) * (r.x - a.x)) / o;
2679
2950
  return {
2680
- x: e.x + o * (t.x - e.x),
2681
- y: e.y + o * (t.y - e.y)
2951
+ x: e.x + n * (t.x - e.x),
2952
+ y: e.y + n * (t.y - e.y)
2682
2953
  };
2683
2954
  },
2684
2955
  /** Circle-line intersection */
2685
2956
  circleLineIntersection(e, t, r, a) {
2686
- const n = a.x - r.x, o = a.y - r.y, s = r.x - e.x, c = r.y - e.y, l = n * n + o * o, i = 2 * (s * n + c * o), d = s * s + c * c - t * t, u = i * i - 4 * l * d;
2687
- if (u < 0)
2957
+ const o = a.x - r.x, n = a.y - r.y, s = r.x - e.x, l = r.y - e.y, x = o * o + n * n, i = 2 * (s * o + l * n), d = s * s + l * l - t * t, g = i * i - 4 * x * d;
2958
+ if (g < 0)
2688
2959
  return [];
2689
- const h = Math.sqrt(u), b = (-i - h) / (2 * l), y = (-i + h) / (2 * l), g = [];
2690
- return b >= 0 && b <= 1 && g.push({ x: r.x + b * n, y: r.y + b * o }), y >= 0 && y <= 1 && Math.abs(y - b) > 1e-10 && g.push({ x: r.x + y * n, y: r.y + y * o }), g;
2960
+ const y = Math.sqrt(g), h = (-i - y) / (2 * x), w = (-i + y) / (2 * x), p = [];
2961
+ return h >= 0 && h <= 1 && p.push({ x: r.x + h * o, y: r.y + h * n }), w >= 0 && w <= 1 && Math.abs(w - h) > 1e-10 && p.push({ x: r.x + w * o, y: r.y + w * n }), p;
2691
2962
  },
2692
2963
  /** Circle-circle intersection */
2693
2964
  circleCircleIntersection(e, t, r, a) {
2694
- const n = this.distance(e, r);
2695
- if (n > t + a || n < Math.abs(t - a) || n === 0)
2965
+ const o = this.distance(e, r);
2966
+ if (o > t + a || o < Math.abs(t - a) || o === 0)
2696
2967
  return [];
2697
- const o = (t * t - a * a + n * n) / (2 * n), s = Math.sqrt(t * t - o * o), c = e.x + o * (r.x - e.x) / n, l = e.y + o * (r.y - e.y) / n;
2968
+ const n = (t * t - a * a + o * o) / (2 * o), s = Math.sqrt(t * t - n * n), l = e.x + n * (r.x - e.x) / o, x = e.y + n * (r.y - e.y) / o;
2698
2969
  return [
2699
- { x: c + s * (r.y - e.y) / n, y: l - s * (r.x - e.x) / n },
2700
- { x: c - s * (r.y - e.y) / n, y: l + s * (r.x - e.x) / n }
2970
+ { x: l + s * (r.y - e.y) / o, y: x - s * (r.x - e.x) / o },
2971
+ { x: l - s * (r.y - e.y) / o, y: x + s * (r.x - e.x) / o }
2701
2972
  ];
2702
2973
  },
2703
2974
  /** Perpendicular line through point */
2704
2975
  perpendicularThrough(e, t, r) {
2705
2976
  this.closestPointOnLine(e, t, r);
2706
- const a = t.x - e.x, n = t.y - e.y;
2977
+ const a = t.x - e.x, o = t.y - e.y;
2707
2978
  return {
2708
2979
  p1: r,
2709
- p2: { x: r.x - n, y: r.y + a }
2980
+ p2: { x: r.x - o, y: r.y + a }
2710
2981
  };
2711
2982
  },
2712
2983
  /** Parallel line through point */
2713
2984
  parallelThrough(e, t, r) {
2714
- const a = t.x - e.x, n = t.y - e.y;
2985
+ const a = t.x - e.x, o = t.y - e.y;
2715
2986
  return {
2716
2987
  p1: r,
2717
- p2: { x: r.x + a, y: r.y + n }
2988
+ p2: { x: r.x + a, y: r.y + o }
2718
2989
  };
2719
2990
  },
2720
2991
  /** Angle bisector */
2721
2992
  angleBisector(e, t, r) {
2722
- const a = Math.atan2(e.y - t.y, e.x - t.x), n = Math.atan2(r.y - t.y, r.x - t.x);
2723
- let o = (a + n) / 2;
2724
- return Math.abs(n - a) > Math.PI && (o += Math.PI), {
2725
- x: t.x + Math.cos(o),
2726
- y: t.y + Math.sin(o)
2993
+ const a = Math.atan2(e.y - t.y, e.x - t.x), o = Math.atan2(r.y - t.y, r.x - t.x);
2994
+ let n = (a + o) / 2;
2995
+ return Math.abs(o - a) > Math.PI && (n += Math.PI), {
2996
+ x: t.x + Math.cos(n),
2997
+ y: t.y + Math.sin(n)
2727
2998
  };
2728
2999
  },
2729
3000
  /** Reflect point over line */
@@ -2736,10 +3007,10 @@ const GeoMath = {
2736
3007
  },
2737
3008
  /** Rotate point around center */
2738
3009
  rotate(e, t, r) {
2739
- const a = Math.cos(r), n = Math.sin(r), o = e.x - t.x, s = e.y - t.y;
3010
+ const a = Math.cos(r), o = Math.sin(r), n = e.x - t.x, s = e.y - t.y;
2740
3011
  return {
2741
- x: t.x + o * a - s * n,
2742
- y: t.y + o * n + s * a
3012
+ x: t.x + n * a - s * o,
3013
+ y: t.y + n * o + s * a
2743
3014
  };
2744
3015
  },
2745
3016
  /** Translate point */
@@ -2758,8 +3029,8 @@ const GeoMath = {
2758
3029
  let t = 0;
2759
3030
  const r = e.length;
2760
3031
  for (let a = 0; a < r; a++) {
2761
- const n = (a + 1) % r;
2762
- t += e[a].x * e[n].y, t -= e[n].x * e[a].y;
3032
+ const o = (a + 1) % r;
3033
+ t += e[a].x * e[o].y, t -= e[o].x * e[a].y;
2763
3034
  }
2764
3035
  return Math.abs(t) / 2;
2765
3036
  },
@@ -2768,22 +3039,22 @@ const GeoMath = {
2768
3039
  let t = 0;
2769
3040
  const r = e.length;
2770
3041
  for (let a = 0; a < r; a++) {
2771
- const n = (a + 1) % r;
2772
- t += this.distance(e[a], e[n]);
3042
+ const o = (a + 1) % r;
3043
+ t += this.distance(e[a], e[o]);
2773
3044
  }
2774
3045
  return t;
2775
3046
  },
2776
3047
  /** Triangle circumcenter */
2777
3048
  circumcenter(e, t, r) {
2778
- const a = 2 * (e.x * (t.y - r.y) + t.x * (r.y - e.y) + r.x * (e.y - t.y)), n = ((e.x ** 2 + e.y ** 2) * (t.y - r.y) + (t.x ** 2 + t.y ** 2) * (r.y - e.y) + (r.x ** 2 + r.y ** 2) * (e.y - t.y)) / a, o = ((e.x ** 2 + e.y ** 2) * (r.x - t.x) + (t.x ** 2 + t.y ** 2) * (e.x - r.x) + (r.x ** 2 + r.y ** 2) * (t.x - e.x)) / a;
2779
- return { x: n, y: o };
3049
+ const a = 2 * (e.x * (t.y - r.y) + t.x * (r.y - e.y) + r.x * (e.y - t.y)), o = ((e.x ** 2 + e.y ** 2) * (t.y - r.y) + (t.x ** 2 + t.y ** 2) * (r.y - e.y) + (r.x ** 2 + r.y ** 2) * (e.y - t.y)) / a, n = ((e.x ** 2 + e.y ** 2) * (r.x - t.x) + (t.x ** 2 + t.y ** 2) * (e.x - r.x) + (r.x ** 2 + r.y ** 2) * (t.x - e.x)) / a;
3050
+ return { x: o, y: n };
2780
3051
  },
2781
3052
  /** Triangle incenter */
2782
3053
  incenter(e, t, r) {
2783
- const a = this.distance(e, t), n = this.distance(t, r), o = this.distance(r, e), s = a + n + o;
3054
+ const a = this.distance(e, t), o = this.distance(t, r), n = this.distance(r, e), s = a + o + n;
2784
3055
  return {
2785
- x: (n * e.x + o * t.x + a * r.x) / s,
2786
- y: (n * e.y + o * t.y + a * r.y) / s
3056
+ x: (o * e.x + n * t.x + a * r.x) / s,
3057
+ y: (o * e.y + n * t.y + a * r.y) / s
2787
3058
  };
2788
3059
  },
2789
3060
  /** Triangle centroid */
@@ -2822,8 +3093,8 @@ class GeometryService {
2822
3093
  deleteElement(t) {
2823
3094
  var r;
2824
3095
  this.elements.delete(t);
2825
- for (const [a, n] of this.elements)
2826
- (r = n.dependencies) != null && r.includes(t) && this.deleteElement(a);
3096
+ for (const [a, o] of this.elements)
3097
+ (r = o.dependencies) != null && r.includes(t) && this.deleteElement(a);
2827
3098
  }
2828
3099
  /** Get all elements */
2829
3100
  getAllElements() {
@@ -2928,91 +3199,91 @@ class GeometryService {
2928
3199
  }
2929
3200
  /** Create midpoint */
2930
3201
  createMidpoint(t, r) {
2931
- const a = this.getPoint(t), n = this.getPoint(r);
2932
- if (!a || !n)
3202
+ const a = this.getPoint(t), o = this.getPoint(r);
3203
+ if (!a || !o)
2933
3204
  return null;
2934
- const o = GeoMath.midpoint(a, n), s = this.createPoint(o.x, o.y);
3205
+ const n = GeoMath.midpoint(a, o), s = this.createPoint(n.x, n.y);
2935
3206
  return s.dependencies = [t, r], s.color = { r: 0, g: 150, b: 0 }, s;
2936
3207
  }
2937
3208
  /** Create perpendicular */
2938
3209
  createPerpendicular(t, r, a) {
2939
- const n = this.getPoint(t), o = this.getPoint(r), s = this.getPoint(a);
2940
- if (!n || !o || !s)
3210
+ const o = this.getPoint(t), n = this.getPoint(r), s = this.getPoint(a);
3211
+ if (!o || !n || !s)
2941
3212
  return null;
2942
- const c = GeoMath.perpendicularThrough(n, o, s), l = this.createPoint(c.p2.x, c.p2.y), i = this.createLine(a, l.id);
3213
+ const l = GeoMath.perpendicularThrough(o, n, s), x = this.createPoint(l.p2.x, l.p2.y), i = this.createLine(a, x.id);
2943
3214
  return i.dependencies = [t, r, a], i;
2944
3215
  }
2945
3216
  /** Create parallel */
2946
3217
  createParallel(t, r, a) {
2947
- const n = this.getPoint(t), o = this.getPoint(r), s = this.getPoint(a);
2948
- if (!n || !o || !s)
3218
+ const o = this.getPoint(t), n = this.getPoint(r), s = this.getPoint(a);
3219
+ if (!o || !n || !s)
2949
3220
  return null;
2950
- const c = GeoMath.parallelThrough(n, o, s), l = this.createPoint(c.p2.x, c.p2.y), i = this.createLine(a, l.id);
3221
+ const l = GeoMath.parallelThrough(o, n, s), x = this.createPoint(l.p2.x, l.p2.y), i = this.createLine(a, x.id);
2951
3222
  return i.dependencies = [t, r, a], i;
2952
3223
  }
2953
3224
  /** Create intersection point */
2954
3225
  createIntersection(t, r) {
2955
- const a = this.elements.get(t), n = this.elements.get(r);
2956
- if (!a || !n)
3226
+ const a = this.elements.get(t), o = this.elements.get(r);
3227
+ if (!a || !o)
2957
3228
  return [];
2958
- const o = [], s = (i) => {
3229
+ const n = [], s = (i) => {
2959
3230
  if (i.type === "line" || i.type === "segment" || i.type === "ray") {
2960
- const d = i, u = this.getPoint(d.point1Id ?? d.originId), h = this.getPoint(d.point2Id ?? d.throughId);
2961
- if (u && h)
2962
- return [u, h];
3231
+ const d = i, g = this.getPoint(d.point1Id ?? d.originId), y = this.getPoint(d.point2Id ?? d.throughId);
3232
+ if (g && y)
3233
+ return [g, y];
2963
3234
  }
2964
3235
  return null;
2965
- }, c = s(a), l = s(n);
2966
- if (c && l) {
2967
- const i = GeoMath.lineIntersection(c[0], c[1], l[0], l[1]);
3236
+ }, l = s(a), x = s(o);
3237
+ if (l && x) {
3238
+ const i = GeoMath.lineIntersection(l[0], l[1], x[0], x[1]);
2968
3239
  if (i) {
2969
3240
  const d = this.createPoint(i.x, i.y);
2970
- d.dependencies = [t, r], d.color = { r: 255, g: 0, b: 0 }, o.push(d);
3241
+ d.dependencies = [t, r], d.color = { r: 255, g: 0, b: 0 }, n.push(d);
2971
3242
  }
2972
3243
  }
2973
- if (a.type === "circle" && l) {
3244
+ if (a.type === "circle" && x) {
2974
3245
  const i = a, d = this.getPoint(i.centerId);
2975
3246
  if (d) {
2976
- const u = GeoMath.circleLineIntersection(d, i.radius, l[0], l[1]);
2977
- for (const h of u) {
2978
- const b = this.createPoint(h.x, h.y);
2979
- b.dependencies = [t, r], b.color = { r: 255, g: 0, b: 0 }, o.push(b);
3247
+ const g = GeoMath.circleLineIntersection(d, i.radius, x[0], x[1]);
3248
+ for (const y of g) {
3249
+ const h = this.createPoint(y.x, y.y);
3250
+ h.dependencies = [t, r], h.color = { r: 255, g: 0, b: 0 }, n.push(h);
2980
3251
  }
2981
3252
  }
2982
3253
  }
2983
- if (a.type === "circle" && n.type === "circle") {
2984
- const i = a, d = n, u = this.getPoint(i.centerId), h = this.getPoint(d.centerId);
2985
- if (u && h) {
2986
- const b = GeoMath.circleCircleIntersection(u, i.radius, h, d.radius);
2987
- for (const y of b) {
2988
- const g = this.createPoint(y.x, y.y);
2989
- g.dependencies = [t, r], g.color = { r: 255, g: 0, b: 0 }, o.push(g);
3254
+ if (a.type === "circle" && o.type === "circle") {
3255
+ const i = a, d = o, g = this.getPoint(i.centerId), y = this.getPoint(d.centerId);
3256
+ if (g && y) {
3257
+ const h = GeoMath.circleCircleIntersection(g, i.radius, y, d.radius);
3258
+ for (const w of h) {
3259
+ const p = this.createPoint(w.x, w.y);
3260
+ p.dependencies = [t, r], p.color = { r: 255, g: 0, b: 0 }, n.push(p);
2990
3261
  }
2991
3262
  }
2992
3263
  }
2993
- return o;
3264
+ return n;
2994
3265
  }
2995
3266
  /** Calculate measurement */
2996
3267
  calculateMeasurement(t, r) {
2997
3268
  switch (t) {
2998
3269
  case "distance": {
2999
- const a = this.getPoint(r[0]), n = this.getPoint(r[1]);
3000
- if (a && n)
3001
- return GeoMath.distance(a, n);
3270
+ const a = this.getPoint(r[0]), o = this.getPoint(r[1]);
3271
+ if (a && o)
3272
+ return GeoMath.distance(a, o);
3002
3273
  break;
3003
3274
  }
3004
3275
  case "angle": {
3005
- const a = this.getPoint(r[0]), n = this.getPoint(r[1]), o = this.getPoint(r[2]);
3006
- if (a && n && o)
3007
- return GeoMath.angleDegrees(a, n, o);
3276
+ const a = this.getPoint(r[0]), o = this.getPoint(r[1]), n = this.getPoint(r[2]);
3277
+ if (a && o && n)
3278
+ return GeoMath.angleDegrees(a, o, n);
3008
3279
  break;
3009
3280
  }
3010
3281
  case "area":
3011
3282
  case "perimeter": {
3012
3283
  const a = this.elements.get(r[0]);
3013
3284
  if ((a == null ? void 0 : a.type) === "polygon") {
3014
- const n = a.pointIds.map((o) => this.getPoint(o)).filter(Boolean);
3015
- return t === "area" ? GeoMath.polygonArea(n) : GeoMath.polygonPerimeter(n);
3285
+ const o = a.pointIds.map((n) => this.getPoint(n)).filter(Boolean);
3286
+ return t === "area" ? GeoMath.polygonArea(o) : GeoMath.polygonPerimeter(o);
3016
3287
  }
3017
3288
  break;
3018
3289
  }
@@ -3021,75 +3292,75 @@ class GeometryService {
3021
3292
  }
3022
3293
  /** Export to SVG */
3023
3294
  exportSVG(t, r, a) {
3024
- const n = [
3295
+ const o = [
3025
3296
  `<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${r}" viewBox="0 0 ${t} ${r}">`
3026
3297
  ];
3027
- n.push(
3298
+ o.push(
3028
3299
  `<rect width="100%" height="100%" fill="rgb(${a.backgroundColor.r},${a.backgroundColor.g},${a.backgroundColor.b})"/>`
3029
3300
  );
3030
- const o = (s, c) => ({
3301
+ const n = (s, l) => ({
3031
3302
  x: t / 2 + (s - a.centerX) * a.scale,
3032
- y: r / 2 - (c - a.centerY) * a.scale
3303
+ y: r / 2 - (l - a.centerY) * a.scale
3033
3304
  });
3034
3305
  if (a.showGrid) {
3035
- n.push('<g stroke="var(--nice-border, #ddd)" stroke-width="0.5">');
3306
+ o.push('<g stroke="var(--nice-border, #ddd)" stroke-width="0.5">');
3036
3307
  for (let s = Math.floor(-t / 2 / a.scale + a.centerX); s <= t / 2 / a.scale + a.centerX; s += a.gridSpacing) {
3037
- const c = o(s, 0);
3038
- n.push(`<line x1="${c.x}" y1="0" x2="${c.x}" y2="${r}"/>`);
3308
+ const l = n(s, 0);
3309
+ o.push(`<line x1="${l.x}" y1="0" x2="${l.x}" y2="${r}"/>`);
3039
3310
  }
3040
3311
  for (let s = Math.floor(-r / 2 / a.scale + a.centerY); s <= r / 2 / a.scale + a.centerY; s += a.gridSpacing) {
3041
- const c = o(0, s);
3042
- n.push(`<line x1="0" y1="${c.y}" x2="${t}" y2="${c.y}"/>`);
3312
+ const l = n(0, s);
3313
+ o.push(`<line x1="0" y1="${l.y}" x2="${t}" y2="${l.y}"/>`);
3043
3314
  }
3044
- n.push("</g>");
3315
+ o.push("</g>");
3045
3316
  }
3046
3317
  if (a.showAxes) {
3047
- const s = o(0, 0);
3048
- n.push('<g stroke="var(--nice-text, #333)" stroke-width="1">'), n.push(`<line x1="0" y1="${s.y}" x2="${t}" y2="${s.y}"/>`), n.push(`<line x1="${s.x}" y1="0" x2="${s.x}" y2="${r}"/>`), n.push("</g>");
3318
+ const s = n(0, 0);
3319
+ o.push('<g stroke="var(--nice-text, #333)" stroke-width="1">'), o.push(`<line x1="0" y1="${s.y}" x2="${t}" y2="${s.y}"/>`), o.push(`<line x1="${s.x}" y1="0" x2="${s.x}" y2="${r}"/>`), o.push("</g>");
3049
3320
  }
3050
3321
  for (const s of this.getAllElements()) {
3051
3322
  if (!s.visible)
3052
3323
  continue;
3053
- const c = `rgb(${s.color.r},${s.color.g},${s.color.b})`;
3324
+ const l = `rgb(${s.color.r},${s.color.g},${s.color.b})`;
3054
3325
  switch (s.type) {
3055
3326
  case "point": {
3056
- const l = o(s.x, s.y);
3057
- n.push(`<circle cx="${l.x}" cy="${l.y}" r="${s.size}" fill="${c}"/>`), s.label && n.push(`<text x="${l.x + 8}" y="${l.y - 8}" font-size="12">${s.label}</text>`);
3327
+ const x = n(s.x, s.y);
3328
+ o.push(`<circle cx="${x.x}" cy="${x.y}" r="${s.size}" fill="${l}"/>`), s.label && o.push(`<text x="${x.x + 8}" y="${x.y - 8}" font-size="12">${s.label}</text>`);
3058
3329
  break;
3059
3330
  }
3060
3331
  case "segment": {
3061
- const l = this.getPoint(s.point1Id), i = this.getPoint(s.point2Id);
3062
- if (l && i) {
3063
- const d = o(l.x, l.y), u = o(i.x, i.y);
3064
- n.push(
3065
- `<line x1="${d.x}" y1="${d.y}" x2="${u.x}" y2="${u.y}" stroke="${c}" stroke-width="${s.width}"/>`
3332
+ const x = this.getPoint(s.point1Id), i = this.getPoint(s.point2Id);
3333
+ if (x && i) {
3334
+ const d = n(x.x, x.y), g = n(i.x, i.y);
3335
+ o.push(
3336
+ `<line x1="${d.x}" y1="${d.y}" x2="${g.x}" y2="${g.y}" stroke="${l}" stroke-width="${s.width}"/>`
3066
3337
  );
3067
3338
  }
3068
3339
  break;
3069
3340
  }
3070
3341
  case "circle": {
3071
- const l = this.getPoint(s.centerId);
3072
- if (l) {
3073
- const i = o(l.x, l.y), d = s.radius * a.scale, u = s.fill ? `rgba(${s.fill.r},${s.fill.g},${s.fill.b},${s.fill.a ?? 0.2})` : "none";
3074
- n.push(
3075
- `<circle cx="${i.x}" cy="${i.y}" r="${d}" fill="${u}" stroke="${c}" stroke-width="${s.width}"/>`
3342
+ const x = this.getPoint(s.centerId);
3343
+ if (x) {
3344
+ const i = n(x.x, x.y), d = s.radius * a.scale, g = s.fill ? `rgba(${s.fill.r},${s.fill.g},${s.fill.b},${s.fill.a ?? 0.2})` : "none";
3345
+ o.push(
3346
+ `<circle cx="${i.x}" cy="${i.y}" r="${d}" fill="${g}" stroke="${l}" stroke-width="${s.width}"/>`
3076
3347
  );
3077
3348
  }
3078
3349
  break;
3079
3350
  }
3080
3351
  case "polygon": {
3081
- const l = s.pointIds.map((i) => this.getPoint(i)).filter(Boolean);
3082
- if (l.length > 0) {
3083
- const d = l.map((h) => o(h.x, h.y)).map((h, b) => `${b === 0 ? "M" : "L"}${h.x},${h.y}`).join(" ") + " Z", u = s.fill ? `rgba(${s.fill.r},${s.fill.g},${s.fill.b},${s.fill.a ?? 0.2})` : "none";
3084
- n.push(
3085
- `<path d="${d}" fill="${u}" stroke="${c}" stroke-width="${s.width}"/>`
3352
+ const x = s.pointIds.map((i) => this.getPoint(i)).filter(Boolean);
3353
+ if (x.length > 0) {
3354
+ const d = x.map((y) => n(y.x, y.y)).map((y, h) => `${h === 0 ? "M" : "L"}${y.x},${y.y}`).join(" ") + " Z", g = s.fill ? `rgba(${s.fill.r},${s.fill.g},${s.fill.b},${s.fill.a ?? 0.2})` : "none";
3355
+ o.push(
3356
+ `<path d="${d}" fill="${g}" stroke="${l}" stroke-width="${s.width}"/>`
3086
3357
  );
3087
3358
  }
3088
3359
  break;
3089
3360
  }
3090
3361
  }
3091
3362
  }
3092
- return n.push("</svg>"), n.join(`
3363
+ return o.push("</svg>"), o.join(`
3093
3364
  `);
3094
3365
  }
3095
3366
  generateId() {
@@ -3164,9 +3435,9 @@ function NiceGeometry({
3164
3435
  width: t = 800,
3165
3436
  height: r = 600,
3166
3437
  className: a,
3167
- style: n
3438
+ style: o
3168
3439
  }) {
3169
- const [o, s] = useState([]), [c, l] = useState("point"), [i, d] = useState([]), [u, h] = useState({
3440
+ const [n, s] = useState([]), [l, x] = useState("point"), [i, d] = useState([]), [g, y] = useState({
3170
3441
  centerX: 0,
3171
3442
  centerY: 0,
3172
3443
  scale: 40,
@@ -3176,26 +3447,26 @@ function NiceGeometry({
3176
3447
  snapToGrid: !0,
3177
3448
  snapToPoints: !0,
3178
3449
  backgroundColor: { r: 255, g: 255, b: 255 }
3179
- }), b = useCallback(() => {
3450
+ }), h = useCallback(() => {
3180
3451
  s(e.getAllElements());
3181
- }, [e]), y = useCallback((m) => {
3182
- h((p) => ({ ...p, ...m }));
3452
+ }, [e]), w = useCallback((f) => {
3453
+ y((c) => ({ ...c, ...f }));
3183
3454
  }, []);
3184
3455
  useEffect(() => {
3185
- b();
3186
- }, [b]);
3187
- const g = {
3456
+ h();
3457
+ }, [h]);
3458
+ const p = {
3188
3459
  service: e,
3189
- elements: o,
3190
- tool: c,
3191
- setTool: l,
3192
- view: u,
3193
- setView: y,
3460
+ elements: n,
3461
+ tool: l,
3462
+ setTool: x,
3463
+ view: g,
3464
+ setView: w,
3194
3465
  selectedIds: i,
3195
3466
  setSelectedIds: d,
3196
- refresh: b
3467
+ refresh: h
3197
3468
  };
3198
- return /* @__PURE__ */ jsx(GeometryContext.Provider, { value: g, children: /* @__PURE__ */ jsxs("div", { className: a, style: { ...styles.container, ...n }, children: [
3469
+ return /* @__PURE__ */ jsx(GeometryContext.Provider, { value: p, children: /* @__PURE__ */ jsxs("div", { className: a, style: { ...styles.container, ...o }, children: [
3199
3470
  /* @__PURE__ */ jsx(Toolbar, {}),
3200
3471
  /* @__PURE__ */ jsxs("div", { style: styles.main, children: [
3201
3472
  /* @__PURE__ */ jsx(Canvas, { width: t, height: r }),
@@ -3237,186 +3508,186 @@ function Toolbar() {
3237
3508
  )) });
3238
3509
  }
3239
3510
  function Canvas({ width: e, height: t }) {
3240
- const r = useRef(null), { service: a, elements: n, tool: o, view: s, selectedIds: c, setSelectedIds: l, refresh: i } = useGeometry(), [d, u] = useState([]), h = useCallback(
3241
- (m, p) => {
3242
- const x = (m - e / 2) / s.scale + s.centerX, w = -(p - t / 2) / s.scale + s.centerY;
3511
+ const r = useRef(null), { service: a, elements: o, tool: n, view: s, selectedIds: l, setSelectedIds: x, refresh: i } = useGeometry(), [d, g] = useState([]), y = useCallback(
3512
+ (f, c) => {
3513
+ const u = (f - e / 2) / s.scale + s.centerX, b = -(c - t / 2) / s.scale + s.centerY;
3243
3514
  return s.snapToGrid ? {
3244
- x: Math.round(x / s.gridSpacing) * s.gridSpacing,
3245
- y: Math.round(w / s.gridSpacing) * s.gridSpacing
3246
- } : { x, y: w };
3515
+ x: Math.round(u / s.gridSpacing) * s.gridSpacing,
3516
+ y: Math.round(b / s.gridSpacing) * s.gridSpacing
3517
+ } : { x: u, y: b };
3247
3518
  },
3248
3519
  [e, t, s]
3249
- ), b = useCallback(
3250
- (m, p) => ({
3251
- x: e / 2 + (m - s.centerX) * s.scale,
3252
- y: t / 2 - (p - s.centerY) * s.scale
3520
+ ), h = useCallback(
3521
+ (f, c) => ({
3522
+ x: e / 2 + (f - s.centerX) * s.scale,
3523
+ y: t / 2 - (c - s.centerY) * s.scale
3253
3524
  }),
3254
3525
  [e, t, s]
3255
- ), y = useCallback(
3256
- (m) => {
3257
- var w;
3258
- const p = (w = r.current) == null ? void 0 : w.getBoundingClientRect();
3259
- if (!p)
3526
+ ), w = useCallback(
3527
+ (f) => {
3528
+ var b;
3529
+ const c = (b = r.current) == null ? void 0 : b.getBoundingClientRect();
3530
+ if (!c)
3260
3531
  return;
3261
- const x = h(m.clientX - p.left, m.clientY - p.top);
3262
- switch (o) {
3532
+ const u = y(f.clientX - c.left, f.clientY - c.top);
3533
+ switch (n) {
3263
3534
  case "point": {
3264
- a.createPoint(x.x, x.y), i();
3535
+ a.createPoint(u.x, u.y), i();
3265
3536
  break;
3266
3537
  }
3267
3538
  case "segment":
3268
3539
  case "line":
3269
3540
  case "ray": {
3270
- const k = g(x);
3541
+ const k = p(u);
3271
3542
  if (k)
3272
- u((f) => {
3273
- const v = [...f, k.id];
3274
- return v.length === 2 ? (o === "segment" ? a.createSegment(v[0], v[1]) : o === "line" ? a.createLine(v[0], v[1]) : o === "ray" && a.createRay(v[0], v[1]), i(), []) : v;
3543
+ g((m) => {
3544
+ const v = [...m, k.id];
3545
+ return v.length === 2 ? (n === "segment" ? a.createSegment(v[0], v[1]) : n === "line" ? a.createLine(v[0], v[1]) : n === "ray" && a.createRay(v[0], v[1]), i(), []) : v;
3275
3546
  });
3276
3547
  else {
3277
- const f = a.createPoint(x.x, x.y);
3278
- u((v) => {
3279
- const C = [...v, f.id];
3280
- return C.length === 2 ? (o === "segment" ? a.createSegment(C[0], C[1]) : o === "line" ? a.createLine(C[0], C[1]) : o === "ray" && a.createRay(C[0], C[1]), i(), []) : C;
3548
+ const m = a.createPoint(u.x, u.y);
3549
+ g((v) => {
3550
+ const C = [...v, m.id];
3551
+ return C.length === 2 ? (n === "segment" ? a.createSegment(C[0], C[1]) : n === "line" ? a.createLine(C[0], C[1]) : n === "ray" && a.createRay(C[0], C[1]), i(), []) : C;
3281
3552
  }), i();
3282
3553
  }
3283
3554
  break;
3284
3555
  }
3285
3556
  case "circle": {
3286
- const k = g(x);
3557
+ const k = p(u);
3287
3558
  if (k)
3288
- u((f) => {
3289
- if (f.length === 0)
3559
+ g((m) => {
3560
+ if (m.length === 0)
3290
3561
  return [k.id];
3291
- const v = a.getPoint(f[0]);
3562
+ const v = a.getPoint(m[0]);
3292
3563
  if (v) {
3293
- const C = GeoMath.distance(v, x);
3294
- a.createCircle(f[0], C), i();
3564
+ const C = GeoMath.distance(v, u);
3565
+ a.createCircle(m[0], C), i();
3295
3566
  }
3296
3567
  return [];
3297
3568
  });
3298
3569
  else if (d.length === 1) {
3299
- const f = a.getPoint(d[0]);
3300
- if (f) {
3301
- const v = GeoMath.distance(f, x);
3302
- a.createCircle(d[0], v), i(), u([]);
3570
+ const m = a.getPoint(d[0]);
3571
+ if (m) {
3572
+ const v = GeoMath.distance(m, u);
3573
+ a.createCircle(d[0], v), i(), g([]);
3303
3574
  }
3304
3575
  } else {
3305
- const f = a.createPoint(x.x, x.y);
3306
- u([f.id]), i();
3576
+ const m = a.createPoint(u.x, u.y);
3577
+ g([m.id]), i();
3307
3578
  }
3308
3579
  break;
3309
3580
  }
3310
3581
  case "midpoint": {
3311
- const k = g(x);
3312
- k && u((f) => {
3313
- const v = [...f, k.id];
3582
+ const k = p(u);
3583
+ k && g((m) => {
3584
+ const v = [...m, k.id];
3314
3585
  return v.length === 2 ? (a.createMidpoint(v[0], v[1]), i(), []) : v;
3315
3586
  });
3316
3587
  break;
3317
3588
  }
3318
3589
  case "select": {
3319
- const k = g(x);
3320
- l(k ? [k.id] : []);
3590
+ const k = p(u);
3591
+ x(k ? [k.id] : []);
3321
3592
  break;
3322
3593
  }
3323
3594
  }
3324
3595
  },
3325
- [o, a, i, h, d, l]
3326
- ), g = (m) => {
3327
- for (const x of n)
3328
- if (x.type === "point" && GeoMath.distance(x, m) < 0.5)
3329
- return x;
3596
+ [n, a, i, y, d, x]
3597
+ ), p = (f) => {
3598
+ for (const u of o)
3599
+ if (u.type === "point" && GeoMath.distance(u, f) < 0.5)
3600
+ return u;
3330
3601
  };
3331
3602
  return useEffect(() => {
3332
- const m = r.current, p = m == null ? void 0 : m.getContext("2d");
3333
- if (!(!m || !p)) {
3334
- if (p.fillStyle = `rgb(${s.backgroundColor.r},${s.backgroundColor.g},${s.backgroundColor.b})`, p.fillRect(0, 0, e, t), s.showGrid) {
3335
- p.strokeStyle = "var(--nice-border, #e0e0e0)", p.lineWidth = 0.5;
3336
- const x = s.gridSpacing * s.scale, w = (e / 2 - s.centerX * s.scale) % x, k = (t / 2 + s.centerY * s.scale) % x;
3337
- for (let f = w; f < e; f += x)
3338
- p.beginPath(), p.moveTo(f, 0), p.lineTo(f, t), p.stroke();
3339
- for (let f = k; f < t; f += x)
3340
- p.beginPath(), p.moveTo(0, f), p.lineTo(e, f), p.stroke();
3603
+ const f = r.current, c = f == null ? void 0 : f.getContext("2d");
3604
+ if (!(!f || !c)) {
3605
+ if (c.fillStyle = `rgb(${s.backgroundColor.r},${s.backgroundColor.g},${s.backgroundColor.b})`, c.fillRect(0, 0, e, t), s.showGrid) {
3606
+ c.strokeStyle = "var(--nice-border, #e0e0e0)", c.lineWidth = 0.5;
3607
+ const u = s.gridSpacing * s.scale, b = (e / 2 - s.centerX * s.scale) % u, k = (t / 2 + s.centerY * s.scale) % u;
3608
+ for (let m = b; m < e; m += u)
3609
+ c.beginPath(), c.moveTo(m, 0), c.lineTo(m, t), c.stroke();
3610
+ for (let m = k; m < t; m += u)
3611
+ c.beginPath(), c.moveTo(0, m), c.lineTo(e, m), c.stroke();
3341
3612
  }
3342
3613
  if (s.showAxes) {
3343
- const x = b(0, 0);
3344
- p.strokeStyle = "var(--nice-text, #333)", p.lineWidth = 1, p.beginPath(), p.moveTo(0, x.y), p.lineTo(e, x.y), p.stroke(), p.beginPath(), p.moveTo(x.x, 0), p.lineTo(x.x, t), p.stroke();
3614
+ const u = h(0, 0);
3615
+ c.strokeStyle = "var(--nice-text, #333)", c.lineWidth = 1, c.beginPath(), c.moveTo(0, u.y), c.lineTo(e, u.y), c.stroke(), c.beginPath(), c.moveTo(u.x, 0), c.lineTo(u.x, t), c.stroke();
3345
3616
  }
3346
- for (const x of n) {
3347
- if (!x.visible)
3617
+ for (const u of o) {
3618
+ if (!u.visible)
3348
3619
  continue;
3349
- const w = `rgb(${x.color.r},${x.color.g},${x.color.b})`, k = c.includes(x.id);
3350
- switch (x.type) {
3620
+ const b = `rgb(${u.color.r},${u.color.g},${u.color.b})`, k = l.includes(u.id);
3621
+ switch (u.type) {
3351
3622
  case "point": {
3352
- const f = b(x.x, x.y);
3353
- p.beginPath(), p.arc(f.x, f.y, k ? x.size + 2 : x.size, 0, 2 * Math.PI), p.fillStyle = k ? "var(--nice-primary-hover, #1976d2)" : w, p.fill(), x.label && (p.fillStyle = "var(--nice-text, #333)", p.font = "12px sans-serif", p.fillText(x.label, f.x + 8, f.y - 8));
3623
+ const m = h(u.x, u.y);
3624
+ c.beginPath(), c.arc(m.x, m.y, k ? u.size + 2 : u.size, 0, 2 * Math.PI), c.fillStyle = k ? "var(--nice-primary-hover, #1976d2)" : b, c.fill(), u.label && (c.fillStyle = "var(--nice-text, #333)", c.font = "12px sans-serif", c.fillText(u.label, m.x + 8, m.y - 8));
3354
3625
  break;
3355
3626
  }
3356
3627
  case "segment": {
3357
- const f = a.getPoint(x.point1Id), v = a.getPoint(x.point2Id);
3358
- if (f && v) {
3359
- const C = b(f.x, f.y), S = b(v.x, v.y);
3360
- p.strokeStyle = w, p.lineWidth = x.width, p.beginPath(), p.moveTo(C.x, C.y), p.lineTo(S.x, S.y), p.stroke();
3628
+ const m = a.getPoint(u.point1Id), v = a.getPoint(u.point2Id);
3629
+ if (m && v) {
3630
+ const C = h(m.x, m.y), S = h(v.x, v.y);
3631
+ c.strokeStyle = b, c.lineWidth = u.width, c.beginPath(), c.moveTo(C.x, C.y), c.lineTo(S.x, S.y), c.stroke();
3361
3632
  }
3362
3633
  break;
3363
3634
  }
3364
3635
  case "line": {
3365
- const f = a.getPoint(x.point1Id), v = a.getPoint(x.point2Id);
3366
- if (f && v) {
3367
- const C = v.x - f.x, S = v.y - f.y, $ = -1e3, j = 1e3, P = b(f.x + $ * C, f.y + $ * S), B = b(f.x + j * C, f.y + j * S);
3368
- p.strokeStyle = w, p.lineWidth = x.width, p.beginPath(), p.moveTo(P.x, P.y), p.lineTo(B.x, B.y), p.stroke();
3636
+ const m = a.getPoint(u.point1Id), v = a.getPoint(u.point2Id);
3637
+ if (m && v) {
3638
+ const C = v.x - m.x, S = v.y - m.y, P = -1e3, $ = 1e3, j = h(m.x + P * C, m.y + P * S), B = h(m.x + $ * C, m.y + $ * S);
3639
+ c.strokeStyle = b, c.lineWidth = u.width, c.beginPath(), c.moveTo(j.x, j.y), c.lineTo(B.x, B.y), c.stroke();
3369
3640
  }
3370
3641
  break;
3371
3642
  }
3372
3643
  case "circle": {
3373
- const f = a.getPoint(x.centerId);
3374
- if (f) {
3375
- const v = b(f.x, f.y), C = x.radius * s.scale;
3376
- p.beginPath(), p.arc(v.x, v.y, C, 0, 2 * Math.PI), x.fill && (p.fillStyle = `rgba(${x.fill.r},${x.fill.g},${x.fill.b},${x.fill.a ?? 0.2})`, p.fill()), p.strokeStyle = w, p.lineWidth = x.width, p.stroke();
3644
+ const m = a.getPoint(u.centerId);
3645
+ if (m) {
3646
+ const v = h(m.x, m.y), C = u.radius * s.scale;
3647
+ c.beginPath(), c.arc(v.x, v.y, C, 0, 2 * Math.PI), u.fill && (c.fillStyle = `rgba(${u.fill.r},${u.fill.g},${u.fill.b},${u.fill.a ?? 0.2})`, c.fill()), c.strokeStyle = b, c.lineWidth = u.width, c.stroke();
3377
3648
  }
3378
3649
  break;
3379
3650
  }
3380
3651
  case "polygon": {
3381
- const f = x.pointIds.map((v) => a.getPoint(v)).filter(Boolean);
3382
- if (f.length > 0) {
3383
- p.beginPath();
3384
- const v = b(f[0].x, f[0].y);
3385
- p.moveTo(v.x, v.y);
3386
- for (let C = 1; C < f.length; C++) {
3387
- const S = b(f[C].x, f[C].y);
3388
- p.lineTo(S.x, S.y);
3652
+ const m = u.pointIds.map((v) => a.getPoint(v)).filter(Boolean);
3653
+ if (m.length > 0) {
3654
+ c.beginPath();
3655
+ const v = h(m[0].x, m[0].y);
3656
+ c.moveTo(v.x, v.y);
3657
+ for (let C = 1; C < m.length; C++) {
3658
+ const S = h(m[C].x, m[C].y);
3659
+ c.lineTo(S.x, S.y);
3389
3660
  }
3390
- p.closePath(), x.fill && (p.fillStyle = `rgba(${x.fill.r},${x.fill.g},${x.fill.b},${x.fill.a ?? 0.2})`, p.fill()), p.strokeStyle = w, p.lineWidth = x.width, p.stroke();
3661
+ c.closePath(), u.fill && (c.fillStyle = `rgba(${u.fill.r},${u.fill.g},${u.fill.b},${u.fill.a ?? 0.2})`, c.fill()), c.strokeStyle = b, c.lineWidth = u.width, c.stroke();
3391
3662
  }
3392
3663
  break;
3393
3664
  }
3394
3665
  }
3395
3666
  }
3396
3667
  if (d.length > 0) {
3397
- p.fillStyle = "rgba(25, 118, 210, 0.3)";
3398
- for (const x of d) {
3399
- const w = a.getPoint(x);
3400
- if (w) {
3401
- const k = b(w.x, w.y);
3402
- p.beginPath(), p.arc(k.x, k.y, 12, 0, 2 * Math.PI), p.fill();
3668
+ c.fillStyle = "rgba(25, 118, 210, 0.3)";
3669
+ for (const u of d) {
3670
+ const b = a.getPoint(u);
3671
+ if (b) {
3672
+ const k = h(b.x, b.y);
3673
+ c.beginPath(), c.arc(k.x, k.y, 12, 0, 2 * Math.PI), c.fill();
3403
3674
  }
3404
3675
  }
3405
3676
  }
3406
3677
  }
3407
- }, [n, s, e, t, c, d, a, b]), /* @__PURE__ */ jsx(
3678
+ }, [o, s, e, t, l, d, a, h]), /* @__PURE__ */ jsx(
3408
3679
  "canvas",
3409
3680
  {
3410
3681
  ref: r,
3411
3682
  width: e,
3412
3683
  height: t,
3413
3684
  style: styles.canvas,
3414
- onClick: y
3685
+ onClick: w
3415
3686
  }
3416
3687
  );
3417
3688
  }
3418
3689
  function StatusBar({ width: e, height: t }) {
3419
- const { tool: r, elements: a, view: n, service: o } = useGeometry(), [s, c] = useState(null), l = {
3690
+ const { tool: r, elements: a, view: o, service: n } = useGeometry(), [s, l] = useState(null), x = {
3420
3691
  select: "Select",
3421
3692
  point: "Point",
3422
3693
  line: "Line",
@@ -3442,7 +3713,7 @@ function StatusBar({ width: e, height: t }) {
3442
3713
  return /* @__PURE__ */ jsxs("div", { style: styles.statusBar, children: [
3443
3714
  /* @__PURE__ */ jsxs("span", { children: [
3444
3715
  "Tool: ",
3445
- l[r]
3716
+ x[r]
3446
3717
  ] }),
3447
3718
  /* @__PURE__ */ jsx("span", { style: { margin: "0 16px" }, children: "|" }),
3448
3719
  /* @__PURE__ */ jsxs("span", { children: [
@@ -3457,7 +3728,7 @@ function StatusBar({ width: e, height: t }) {
3457
3728
  /* @__PURE__ */ jsx("span", { style: { margin: "0 16px" }, children: "|" }),
3458
3729
  /* @__PURE__ */ jsxs("span", { children: [
3459
3730
  "Scale: ",
3460
- n.scale.toFixed(1),
3731
+ o.scale.toFixed(1),
3461
3732
  "x"
3462
3733
  ] })
3463
3734
  ] });
@@ -3477,6 +3748,7 @@ export {
3477
3748
  NiceCalculator,
3478
3749
  NiceGeometry,
3479
3750
  NiceGraphPlotter,
3751
+ NiceI18nProvider,
3480
3752
  NiceMathEditor,
3481
3753
  createCalculatorService,
3482
3754
  createGeometryService,
@@ -3487,5 +3759,6 @@ export {
3487
3759
  useCalculator,
3488
3760
  useGeometry,
3489
3761
  useGraph,
3490
- useMathEditor
3762
+ useMathEditor,
3763
+ useNiceTranslation
3491
3764
  };