@drghaliasri/butex 5.3.2 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1353,6 +1353,158 @@ function createEmptyDocument2() {
1353
1353
  };
1354
1354
  }
1355
1355
 
1356
+ // src/editor/accentCommands.ts
1357
+ var ACCENT_COMMANDS = {
1358
+ vec: {
1359
+ id: "vec",
1360
+ englishTex: "\\vec",
1361
+ arabicTex: "\\arabvec",
1362
+ placement: "over",
1363
+ label: "\u20D7",
1364
+ title: "\u0633\u0647\u0645 \u0641\u0648\u0642"
1365
+ },
1366
+ hat: {
1367
+ id: "hat",
1368
+ englishTex: "\\hat",
1369
+ arabicTex: "\\hat",
1370
+ placement: "over",
1371
+ label: "\u02C6",
1372
+ title: "\u0642\u0628\u0639\u0629"
1373
+ },
1374
+ tilde: {
1375
+ id: "tilde",
1376
+ englishTex: "\\tilde",
1377
+ arabicTex: "\\tilde",
1378
+ placement: "over",
1379
+ label: "\u02DC",
1380
+ title: "\u0645\u062F\u0629"
1381
+ },
1382
+ dot: {
1383
+ id: "dot",
1384
+ englishTex: "\\dot",
1385
+ arabicTex: "\\dot",
1386
+ placement: "over",
1387
+ label: "\u02D9",
1388
+ title: "\u0646\u0642\u0637\u0629 \u0641\u0648\u0642"
1389
+ },
1390
+ ddot: {
1391
+ id: "ddot",
1392
+ englishTex: "\\ddot",
1393
+ arabicTex: "\\ddot",
1394
+ placement: "over",
1395
+ label: "\xA8",
1396
+ title: "\u0646\u0642\u0637\u062A\u0627\u0646 \u0641\u0648\u0642"
1397
+ },
1398
+ dddot: {
1399
+ id: "dddot",
1400
+ englishTex: "\\dddot",
1401
+ arabicTex: "\\dddot",
1402
+ placement: "over",
1403
+ label: "\u20DB",
1404
+ title: "\u062B\u0644\u0627\u062B \u0646\u0642\u0627\u0637 \u0641\u0648\u0642"
1405
+ },
1406
+ bar: {
1407
+ id: "bar",
1408
+ englishTex: "\\bar",
1409
+ arabicTex: "\\bar",
1410
+ placement: "over",
1411
+ label: "\xAF",
1412
+ title: "\u062E\u0637 \u0641\u0648\u0642"
1413
+ },
1414
+ check: {
1415
+ id: "check",
1416
+ englishTex: "\\check",
1417
+ arabicTex: "\\check",
1418
+ placement: "over",
1419
+ label: "\u02C7",
1420
+ title: "\u0639\u0644\u0627\u0645\u0629 \u062A\u062D\u0642\u0642"
1421
+ },
1422
+ breve: {
1423
+ id: "breve",
1424
+ englishTex: "\\breve",
1425
+ arabicTex: "\\breve",
1426
+ placement: "over",
1427
+ label: "\u02D8",
1428
+ title: "\u0642\u0648\u0633 \u0642\u0635\u064A\u0631"
1429
+ },
1430
+ acute: {
1431
+ id: "acute",
1432
+ englishTex: "\\acute",
1433
+ arabicTex: "\\grave",
1434
+ placement: "over",
1435
+ label: "\xB4",
1436
+ title: "\u0646\u0628\u0631\u0629 \u062D\u0627\u062F\u0629"
1437
+ },
1438
+ grave: {
1439
+ id: "grave",
1440
+ englishTex: "\\grave",
1441
+ arabicTex: "\\acute",
1442
+ placement: "over",
1443
+ label: "`",
1444
+ title: "\u0646\u0628\u0631\u0629 \u062B\u0642\u064A\u0644\u0629"
1445
+ },
1446
+ overline: {
1447
+ id: "overline",
1448
+ englishTex: "\\overline",
1449
+ arabicTex: "\\overline",
1450
+ placement: "over",
1451
+ label: "\u203E",
1452
+ title: "\u062E\u0637 \u0639\u0644\u0648\u064A \u0645\u0645\u062A\u062F"
1453
+ },
1454
+ underline: {
1455
+ id: "underline",
1456
+ englishTex: "\\underline",
1457
+ arabicTex: "\\underline",
1458
+ placement: "under",
1459
+ label: "_",
1460
+ title: "\u062E\u0637 \u0633\u0641\u0644\u064A"
1461
+ },
1462
+ overleftarrow: {
1463
+ id: "overleftarrow",
1464
+ englishTex: "\\overleftarrow",
1465
+ arabicTex: "\\overrightarrow",
1466
+ placement: "over",
1467
+ label: "\u2190",
1468
+ title: "\u0633\u0647\u0645 \u0639\u0644\u0648\u064A \u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631"
1469
+ },
1470
+ overrightarrow: {
1471
+ id: "overrightarrow",
1472
+ englishTex: "\\overrightarrow",
1473
+ arabicTex: "\\overleftarrow",
1474
+ placement: "over",
1475
+ label: "\u2192",
1476
+ title: "\u0633\u0647\u0645 \u0639\u0644\u0648\u064A \u0625\u0644\u0649 \u0627\u0644\u064A\u0645\u064A\u0646"
1477
+ },
1478
+ overleftrightarrow: {
1479
+ id: "overleftrightarrow",
1480
+ englishTex: "\\overleftrightarrow",
1481
+ arabicTex: "\\overleftrightarrow",
1482
+ placement: "over",
1483
+ label: "\u2194",
1484
+ title: "\u0633\u0647\u0645 \u0639\u0644\u0648\u064A \u0645\u0632\u062F\u0648\u062C \u0627\u0644\u0627\u062A\u062C\u0627\u0647"
1485
+ }
1486
+ };
1487
+ function accentCommandSpec(id) {
1488
+ return Object.prototype.hasOwnProperty.call(ACCENT_COMMANDS, id) ? ACCENT_COMMANDS[id] : null;
1489
+ }
1490
+ function accentCommandsList() {
1491
+ return Object.values(ACCENT_COMMANDS);
1492
+ }
1493
+ function accentCommandIdFromTex(tex) {
1494
+ const normalized = tex.startsWith("\\") ? tex : `\\${tex}`;
1495
+ for (const spec of Object.values(ACCENT_COMMANDS)) {
1496
+ if (spec.englishTex === normalized) {
1497
+ return spec.id;
1498
+ }
1499
+ }
1500
+ for (const spec of Object.values(ACCENT_COMMANDS)) {
1501
+ if (spec.arabicTex === normalized) {
1502
+ return spec.id;
1503
+ }
1504
+ }
1505
+ return null;
1506
+ }
1507
+
1356
1508
  // src/editor/atomicCommands.ts
1357
1509
  var ATOMIC_COMMANDS = {
1358
1510
  ///////////////////////// Functions ////////////////////////////////
@@ -1773,7 +1925,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1773
1925
  id: "neq",
1774
1926
  category: "operators1",
1775
1927
  Tex: "\\neq",
1776
- mirror: false,
1928
+ mirror: true,
1777
1929
  Label: "\u2260",
1778
1930
  title: "\u0644\u0627 \u064A\u0633\u0627\u0648\u064A",
1779
1931
  svg_path: null
@@ -1783,6 +1935,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1783
1935
  category: "operators1",
1784
1936
  Tex: "\\approx",
1785
1937
  mirror: false,
1938
+ displayMirror: true,
1786
1939
  Label: "\u2248",
1787
1940
  title: "\u062A\u0642\u0631\u064A\u0628\u0627 \u064A\u0633\u0627\u0648\u064A",
1788
1941
  svg_path: null
@@ -1792,6 +1945,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1792
1945
  category: "operators1",
1793
1946
  Tex: "\\sim",
1794
1947
  mirror: false,
1948
+ displayMirror: true,
1795
1949
  Label: "\u223C",
1796
1950
  title: "\u0645\u0634\u0627\u0628\u0647",
1797
1951
  svg_path: null
@@ -1810,6 +1964,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1810
1964
  category: "operators1",
1811
1965
  Tex: "\\leq",
1812
1966
  mirror: true,
1967
+ displayMirror: false,
1813
1968
  Label: "\u2264",
1814
1969
  title: "\u0623\u0635\u063A\u0631 \u0645\u0646 \u0623\u0648 \u064A\u0633\u0627\u0648\u064A",
1815
1970
  svg_path: null
@@ -1819,6 +1974,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1819
1974
  category: "operators1",
1820
1975
  Tex: "\\geq",
1821
1976
  mirror: true,
1977
+ displayMirror: false,
1822
1978
  Label: "\u2265",
1823
1979
  title: "\u0623\u0643\u0628\u0631 \u0645\u0646 \u0623\u0648 \u064A\u0633\u0627\u0648\u064A",
1824
1980
  svg_path: null
@@ -1828,6 +1984,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1828
1984
  category: "operators1",
1829
1985
  Tex: "\\coloneqq",
1830
1986
  mirror: true,
1987
+ displayMirror: false,
1831
1988
  Label: "\u2254",
1832
1989
  title: "\u064A\u0639\u0631\u0641 \u0628\u0623\u0646\u0647 \u064A\u0633\u0627\u0648\u064A",
1833
1990
  svg_path: null
@@ -1837,6 +1994,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1837
1994
  category: "operators1",
1838
1995
  Tex: "\\eqqcolon",
1839
1996
  mirror: true,
1997
+ displayMirror: false,
1840
1998
  Label: "\u2255",
1841
1999
  title: "\u064A\u0633\u0627\u0648\u064A \u0628\u0627\u0644\u062A\u0639\u0631\u064A\u0641",
1842
2000
  svg_path: null
@@ -1847,6 +2005,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1847
2005
  category: "operators2",
1848
2006
  Tex: "\\propto",
1849
2007
  mirror: true,
2008
+ displayMirror: false,
1850
2009
  Label: "\u221D",
1851
2010
  title: "\u064A\u062A\u0646\u0627\u0633\u0628 \u0645\u0639",
1852
2011
  svg_path: null
@@ -1856,6 +2015,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1856
2015
  category: "operators2",
1857
2016
  Tex: "\\in",
1858
2017
  mirror: true,
2018
+ displayMirror: false,
1859
2019
  Label: "\u2208",
1860
2020
  title: "\u064A\u0646\u062A\u0645\u064A \u0625\u0644\u0649",
1861
2021
  svg_path: null
@@ -1865,6 +2025,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1865
2025
  category: "operators2",
1866
2026
  Tex: "\\notin",
1867
2027
  mirror: false,
2028
+ displayMirror: true,
1868
2029
  Label: "\u2209",
1869
2030
  title: "\u0644\u0627 \u064A\u0646\u062A\u0645\u064A \u0625\u0644\u0649",
1870
2031
  svg_path: null
@@ -1874,6 +2035,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1874
2035
  category: "operators2",
1875
2036
  Tex: "\\subset",
1876
2037
  mirror: true,
2038
+ displayMirror: false,
1877
2039
  Label: "\u2282",
1878
2040
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0645\u0646",
1879
2041
  svg_path: null
@@ -1883,6 +2045,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1883
2045
  category: "operators2",
1884
2046
  Tex: "\\supset",
1885
2047
  mirror: true,
2048
+ displayMirror: false,
1886
2049
  Label: "\u2283",
1887
2050
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0644\u0640",
1888
2051
  svg_path: null
@@ -1892,6 +2055,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1892
2055
  category: "operators2",
1893
2056
  Tex: "\\subseteq",
1894
2057
  mirror: true,
2058
+ displayMirror: false,
1895
2059
  Label: "\u2286",
1896
2060
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1897
2061
  svg_path: null
@@ -1901,6 +2065,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1901
2065
  category: "operators2",
1902
2066
  Tex: "\\supseteq",
1903
2067
  mirror: true,
2068
+ displayMirror: false,
1904
2069
  Label: "\u2287",
1905
2070
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1906
2071
  svg_path: null
@@ -1910,6 +2075,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1910
2075
  category: "operators2",
1911
2076
  Tex: "\\cap",
1912
2077
  mirror: false,
2078
+ displayMirror: true,
1913
2079
  Label: "\u2229",
1914
2080
  title: "\u062A\u0642\u0627\u0637\u0639",
1915
2081
  svg_path: null
@@ -1919,6 +2085,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1919
2085
  category: "operators2",
1920
2086
  Tex: "\\cup",
1921
2087
  mirror: false,
2088
+ displayMirror: true,
1922
2089
  Label: "\u222A",
1923
2090
  title: "\u0627\u062A\u062D\u0627\u062F",
1924
2091
  svg_path: null
@@ -1928,6 +2095,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1928
2095
  category: "operators2",
1929
2096
  Tex: "\\emptyset",
1930
2097
  mirror: false,
2098
+ displayMirror: true,
1931
2099
  Label: "\u2205",
1932
2100
  title: "\u0627\u0644\u0645\u062C\u0645\u0648\u0639\u0629 \u0627\u0644\u062E\u0627\u0644\u064A\u0629",
1933
2101
  svg_path: null
@@ -1937,6 +2105,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1937
2105
  category: "operators2",
1938
2106
  Tex: "\\nsubseteq",
1939
2107
  mirror: true,
2108
+ displayMirror: false,
1940
2109
  Label: "\u2288",
1941
2110
  title: "\u0644\u064A\u0633\u062A \u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1942
2111
  svg_path: null
@@ -1946,6 +2115,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1946
2115
  category: "operators2",
1947
2116
  Tex: "\\nsupseteq",
1948
2117
  mirror: true,
2118
+ displayMirror: false,
1949
2119
  Label: "\u2289",
1950
2120
  title: "\u0644\u064A\u0633\u062A \u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1951
2121
  svg_path: null
@@ -2157,6 +2327,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2157
2327
  category: "integrals",
2158
2328
  Tex: "\\iint",
2159
2329
  mirror: true,
2330
+ displayMirror: false,
2160
2331
  Label: "\u222C",
2161
2332
  title: "\u062A\u0643\u0627\u0645\u0644 \u0645\u0632\u062F\u0648\u062C",
2162
2333
  svg_path: null
@@ -2166,6 +2337,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2166
2337
  category: "integrals",
2167
2338
  Tex: "\\iiint",
2168
2339
  mirror: true,
2340
+ displayMirror: false,
2169
2341
  Label: "\u222D",
2170
2342
  title: "\u062A\u0643\u0627\u0645\u0644 \u062B\u0644\u0627\u062B\u064A",
2171
2343
  svg_path: null
@@ -2175,6 +2347,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2175
2347
  category: "integrals",
2176
2348
  Tex: "\\iiiint",
2177
2349
  mirror: true,
2350
+ displayMirror: false,
2178
2351
  Label: "\u2A0C",
2179
2352
  title: "\u062A\u0643\u0627\u0645\u0644 \u0631\u0628\u0627\u0639\u064A",
2180
2353
  svg_path: null
@@ -2184,6 +2357,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2184
2357
  category: "integrals",
2185
2358
  Tex: "\\oint",
2186
2359
  mirror: true,
2360
+ displayMirror: false,
2187
2361
  Label: "\u222E",
2188
2362
  title: "\u062A\u0643\u0627\u0645\u0644 \u0645\u063A\u0644\u0642",
2189
2363
  svg_path: null
@@ -2193,6 +2367,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2193
2367
  category: "integrals",
2194
2368
  Tex: "\\oiint",
2195
2369
  mirror: true,
2370
+ displayMirror: false,
2196
2371
  Label: "\u222F",
2197
2372
  title: "\u062A\u0643\u0627\u0645\u0644 \u0633\u0637\u062D\u064A \u0645\u063A\u0644\u0642",
2198
2373
  svg_path: null
@@ -2202,6 +2377,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2202
2377
  category: "integrals",
2203
2378
  Tex: "\\oiiint",
2204
2379
  mirror: true,
2380
+ displayMirror: false,
2205
2381
  Label: "\u2230",
2206
2382
  title: "\u062A\u0643\u0627\u0645\u0644 \u062D\u062C\u0645\u064A \u0645\u063A\u0644\u0642",
2207
2383
  svg_path: null
@@ -2303,6 +2479,9 @@ function createEditorNode(kind, expr) {
2303
2479
  denominator: null,
2304
2480
  radicand: null,
2305
2481
  rootIndex: null,
2482
+ overExpr: null,
2483
+ underExpr: null,
2484
+ baseExpr: null,
2306
2485
  envName: null,
2307
2486
  matrixStyle: null,
2308
2487
  matrixRows: null,
@@ -2331,6 +2510,26 @@ function createSqrtNode() {
2331
2510
  rootIndex: createEditorChain()
2332
2511
  };
2333
2512
  }
2513
+ function createOversetNode() {
2514
+ return {
2515
+ ...createEditorNode("overset", ""),
2516
+ overExpr: createEditorChain(),
2517
+ baseExpr: createEditorChain()
2518
+ };
2519
+ }
2520
+ function createUndersetNode() {
2521
+ return {
2522
+ ...createEditorNode("underset", ""),
2523
+ underExpr: createEditorChain(),
2524
+ baseExpr: createEditorChain()
2525
+ };
2526
+ }
2527
+ function createAccentNode(accentId) {
2528
+ return {
2529
+ ...createEditorNode("accent", accentId),
2530
+ baseExpr: createEditorChain()
2531
+ };
2532
+ }
2334
2533
  function createGridEnvNode(envName, rows, columns, columnAlignments) {
2335
2534
  const safeRows = Math.max(1, Math.min(12, Math.trunc(rows)));
2336
2535
  const safeColumns = Math.max(1, Math.min(12, Math.trunc(columns)));
@@ -2395,6 +2594,15 @@ function collectNodeIds(chain, ids) {
2395
2594
  if (node.radicand) {
2396
2595
  collectNodeIds(node.radicand, ids);
2397
2596
  }
2597
+ if (node.overExpr) {
2598
+ collectNodeIds(node.overExpr, ids);
2599
+ }
2600
+ if (node.underExpr) {
2601
+ collectNodeIds(node.underExpr, ids);
2602
+ }
2603
+ if (node.baseExpr) {
2604
+ collectNodeIds(node.baseExpr, ids);
2605
+ }
2398
2606
  if (node.matrixRows) {
2399
2607
  for (const row of node.matrixRows) {
2400
2608
  for (const cell of row) {
@@ -2531,6 +2739,22 @@ function renderMatrixRowsArabic(node, options) {
2531
2739
  }
2532
2740
  return `\\begin{${envName}}${rows.join(" \\\\\n")}\\end{${envName}}`;
2533
2741
  }
2742
+ function renderAccentEnglish(command, accent, base, options) {
2743
+ const baseTex = base ? renderChainEnglish(base, options) : "";
2744
+ const accentTex = accent ? renderChainEnglish(accent, options) : "";
2745
+ if (accentTex === "") {
2746
+ return baseTex;
2747
+ }
2748
+ return `\\${command}{${accentTex}}{${baseTex}}`;
2749
+ }
2750
+ function renderAccentArabic(command, accent, base, options) {
2751
+ const baseTex = base ? renderChainArabic(base, options) : "";
2752
+ const accentTex = accent ? renderChainArabic(accent, options) : "";
2753
+ if (accentTex === "") {
2754
+ return baseTex;
2755
+ }
2756
+ return `\\${command}{${accentTex}}{${baseTex}}`;
2757
+ }
2534
2758
  function escapeText(s) {
2535
2759
  return s.replace(/\\/g, "\\textbackslash{}").replace(/[{}]/g, "\\$&");
2536
2760
  }
@@ -2560,6 +2784,19 @@ function renderNodeEnglish(node, options) {
2560
2784
  const body = `\\sqrt${optionalRootIndexEnglish(node, options)}{${renderChainEnglish(node.radicand, options)}}`;
2561
2785
  return `${body}${latinScripts(node, options)}`;
2562
2786
  }
2787
+ if (node.kind === "overset" && node.baseExpr) {
2788
+ const body = renderAccentEnglish("overset", node.overExpr, node.baseExpr, options);
2789
+ return `${body}${latinScripts(node, options)}`;
2790
+ }
2791
+ if (node.kind === "underset" && node.baseExpr) {
2792
+ const body = renderAccentEnglish("underset", node.underExpr, node.baseExpr, options);
2793
+ return `${body}${latinScripts(node, options)}`;
2794
+ }
2795
+ if (node.kind === "accent" && node.baseExpr) {
2796
+ const cmd = accentCommandSpec(node.expr)?.englishTex ?? `\\${node.expr}`;
2797
+ const body = `${cmd}{${renderChainEnglish(node.baseExpr, options)}}`;
2798
+ return `${body}${latinScripts(node, options)}`;
2799
+ }
2563
2800
  if (node.kind === "env") {
2564
2801
  return `${renderMatrixRowsEnglish(node, options)}${latinScripts(node, options)}`;
2565
2802
  }
@@ -2592,6 +2829,19 @@ function renderNodeArabic(node, options) {
2592
2829
  const content = `\\arabsqrt${optionalRootIndexArabic(node, options)}{${renderChainArabic(node.radicand, options)}}`;
2593
2830
  return arabicScripts(node, content, options);
2594
2831
  }
2832
+ if (node.kind === "overset" && node.baseExpr) {
2833
+ const content = renderAccentArabic("overset", node.overExpr, node.baseExpr, options);
2834
+ return arabicScripts(node, content, options);
2835
+ }
2836
+ if (node.kind === "underset" && node.baseExpr) {
2837
+ const content = renderAccentArabic("underset", node.underExpr, node.baseExpr, options);
2838
+ return arabicScripts(node, content, options);
2839
+ }
2840
+ if (node.kind === "accent" && node.baseExpr) {
2841
+ const cmd = accentCommandSpec(node.expr)?.arabicTex ?? `\\${node.expr}`;
2842
+ const content = `${cmd}{${renderChainArabic(node.baseExpr, options)}}`;
2843
+ return arabicScripts(node, content, options);
2844
+ }
2595
2845
  if (node.kind === "env") {
2596
2846
  return arabicScripts(node, renderMatrixRowsArabic(node, options), options);
2597
2847
  }
@@ -2648,6 +2898,35 @@ function collectCaretPositions(chain) {
2648
2898
  if (node.radicand) {
2649
2899
  walkChain(node.radicand);
2650
2900
  }
2901
+ if (node.kind === "overset") {
2902
+ if (node.overExpr) {
2903
+ walkChain(node.overExpr);
2904
+ }
2905
+ if (node.baseExpr) {
2906
+ walkChain(node.baseExpr);
2907
+ }
2908
+ } else if (node.kind === "underset") {
2909
+ if (node.baseExpr) {
2910
+ walkChain(node.baseExpr);
2911
+ }
2912
+ if (node.underExpr) {
2913
+ walkChain(node.underExpr);
2914
+ }
2915
+ } else if (node.kind === "accent") {
2916
+ if (node.baseExpr) {
2917
+ walkChain(node.baseExpr);
2918
+ }
2919
+ } else {
2920
+ if (node.overExpr) {
2921
+ walkChain(node.overExpr);
2922
+ }
2923
+ if (node.underExpr) {
2924
+ walkChain(node.underExpr);
2925
+ }
2926
+ if (node.baseExpr) {
2927
+ walkChain(node.baseExpr);
2928
+ }
2929
+ }
2651
2930
  if (node.matrixRows) {
2652
2931
  for (const row of node.matrixRows) {
2653
2932
  for (const cell of row) {
@@ -2781,6 +3060,42 @@ function findChainById(root, chainId) {
2781
3060
  return nested;
2782
3061
  }
2783
3062
  }
3063
+ if (node.overExpr) {
3064
+ if (node.overExpr.id === chainId) {
3065
+ return {
3066
+ chain: node.overExpr,
3067
+ relation: { kind: "overExpr", ownerNodeId: node.id, ownerChainId: root.id }
3068
+ };
3069
+ }
3070
+ const nested = findChainById(node.overExpr, chainId);
3071
+ if (nested) {
3072
+ return nested;
3073
+ }
3074
+ }
3075
+ if (node.underExpr) {
3076
+ if (node.underExpr.id === chainId) {
3077
+ return {
3078
+ chain: node.underExpr,
3079
+ relation: { kind: "underExpr", ownerNodeId: node.id, ownerChainId: root.id }
3080
+ };
3081
+ }
3082
+ const nested = findChainById(node.underExpr, chainId);
3083
+ if (nested) {
3084
+ return nested;
3085
+ }
3086
+ }
3087
+ if (node.baseExpr) {
3088
+ if (node.baseExpr.id === chainId) {
3089
+ return {
3090
+ chain: node.baseExpr,
3091
+ relation: { kind: "baseExpr", ownerNodeId: node.id, ownerChainId: root.id }
3092
+ };
3093
+ }
3094
+ const nested = findChainById(node.baseExpr, chainId);
3095
+ if (nested) {
3096
+ return nested;
3097
+ }
3098
+ }
2784
3099
  if (node.matrixRows) {
2785
3100
  for (let rowIndex = 0; rowIndex < node.matrixRows.length; rowIndex += 1) {
2786
3101
  const row = node.matrixRows[rowIndex];
@@ -2854,6 +3169,24 @@ function findNodeById(root, nodeId) {
2854
3169
  return nested;
2855
3170
  }
2856
3171
  }
3172
+ if (node.overExpr) {
3173
+ const nested = findNodeById(node.overExpr, nodeId);
3174
+ if (nested) {
3175
+ return nested;
3176
+ }
3177
+ }
3178
+ if (node.underExpr) {
3179
+ const nested = findNodeById(node.underExpr, nodeId);
3180
+ if (nested) {
3181
+ return nested;
3182
+ }
3183
+ }
3184
+ if (node.baseExpr) {
3185
+ const nested = findNodeById(node.baseExpr, nodeId);
3186
+ if (nested) {
3187
+ return nested;
3188
+ }
3189
+ }
2857
3190
  if (node.matrixRows) {
2858
3191
  for (const row of node.matrixRows) {
2859
3192
  for (const cell of row) {
@@ -2889,6 +3222,15 @@ function nodeChildChains(node) {
2889
3222
  if (node.radicand) {
2890
3223
  chains.push(node.radicand);
2891
3224
  }
3225
+ if (node.overExpr) {
3226
+ chains.push(node.overExpr);
3227
+ }
3228
+ if (node.underExpr) {
3229
+ chains.push(node.underExpr);
3230
+ }
3231
+ if (node.baseExpr) {
3232
+ chains.push(node.baseExpr);
3233
+ }
2892
3234
  if (node.matrixRows) {
2893
3235
  for (const row of node.matrixRows) {
2894
3236
  chains.push(...row);
@@ -3259,6 +3601,91 @@ function derivativeTemplateInitialCaret(englishFrac) {
3259
3601
  };
3260
3602
  }
3261
3603
 
3604
+ // src/editor/limitsTemplates.ts
3605
+ var LIMITS_SERIES_TEMPLATE_IDS = /* @__PURE__ */ new Set([
3606
+ "sum",
3607
+ "prod",
3608
+ "lim",
3609
+ "max",
3610
+ "min",
3611
+ "sup",
3612
+ "inf"
3613
+ ]);
3614
+ function isLimitsSeriesTemplateId(commandId) {
3615
+ return LIMITS_SERIES_TEMPLATE_IDS.has(commandId);
3616
+ }
3617
+ function syncChainIds2(english, arabic) {
3618
+ arabic.id = english.id;
3619
+ const limit = Math.min(english.nodes.length, arabic.nodes.length);
3620
+ for (let index = 0; index < limit; index += 1) {
3621
+ arabic.nodes[index].id = english.nodes[index].id;
3622
+ }
3623
+ }
3624
+ function syncOversetIds(english, arabic) {
3625
+ arabic.id = english.id;
3626
+ if (english.overExpr && arabic.overExpr) {
3627
+ syncChainIds2(english.overExpr, arabic.overExpr);
3628
+ }
3629
+ if (english.baseExpr && arabic.baseExpr) {
3630
+ syncChainIds2(english.baseExpr, arabic.baseExpr);
3631
+ }
3632
+ }
3633
+ function syncUndersetIds(english, arabic) {
3634
+ arabic.id = english.id;
3635
+ if (english.underExpr && arabic.underExpr) {
3636
+ syncChainIds2(english.underExpr, arabic.underExpr);
3637
+ }
3638
+ if (english.baseExpr && arabic.baseExpr) {
3639
+ syncChainIds2(english.baseExpr, arabic.baseExpr);
3640
+ }
3641
+ }
3642
+ function buildLimitsSeriesTemplate(commandId) {
3643
+ if (!isLimitsSeriesTemplateId(commandId)) {
3644
+ throw new Error(`BuTeX: unsupported limits-series template id: ${commandId}`);
3645
+ }
3646
+ const englishOp = createAtomicCommandNode(commandId);
3647
+ const arabicOp = createAtomicCommandNode(commandId);
3648
+ arabicOp.id = englishOp.id;
3649
+ const englishOverset = createOversetNode();
3650
+ const arabicOverset = createOversetNode();
3651
+ syncOversetIds(englishOverset, arabicOverset);
3652
+ englishOverset.baseExpr = createEditorChain([englishOp]);
3653
+ arabicOverset.baseExpr = createEditorChain([arabicOp]);
3654
+ syncChainIds2(englishOverset.baseExpr, arabicOverset.baseExpr);
3655
+ const englishUnderset = createUndersetNode();
3656
+ const arabicUnderset = createUndersetNode();
3657
+ syncUndersetIds(englishUnderset, arabicUnderset);
3658
+ englishUnderset.baseExpr = createEditorChain([englishOverset]);
3659
+ arabicUnderset.baseExpr = createEditorChain([arabicOverset]);
3660
+ syncChainIds2(englishUnderset.baseExpr, arabicUnderset.baseExpr);
3661
+ return { english: englishUnderset, arabic: arabicUnderset };
3662
+ }
3663
+ function buildAccentPairTemplate() {
3664
+ const englishOverset = createOversetNode();
3665
+ const arabicOverset = createOversetNode();
3666
+ syncOversetIds(englishOverset, arabicOverset);
3667
+ const englishUnderset = createUndersetNode();
3668
+ const arabicUnderset = createUndersetNode();
3669
+ syncUndersetIds(englishUnderset, arabicUnderset);
3670
+ englishUnderset.baseExpr = createEditorChain([englishOverset]);
3671
+ arabicUnderset.baseExpr = createEditorChain([arabicOverset]);
3672
+ syncChainIds2(englishUnderset.baseExpr, arabicUnderset.baseExpr);
3673
+ return { english: englishUnderset, arabic: arabicUnderset };
3674
+ }
3675
+ function accentPairTemplateInitialCaret(englishUnderset) {
3676
+ const overset = englishUnderset.baseExpr?.nodes[0];
3677
+ return {
3678
+ chainId: overset?.baseExpr?.id ?? englishUnderset.underExpr?.id ?? "",
3679
+ index: 0
3680
+ };
3681
+ }
3682
+ function limitsSeriesTemplateInitialCaret(englishUnderset) {
3683
+ return {
3684
+ chainId: englishUnderset.underExpr?.id ?? englishUnderset.baseExpr?.id ?? "",
3685
+ index: 0
3686
+ };
3687
+ }
3688
+
3262
3689
  // src/editor/uiLocale.ts
3263
3690
  var ENGLISH_COMMAND_TITLES = {
3264
3691
  cos: "Cosine",
@@ -3302,6 +3729,24 @@ var ENGLISH_COMMAND_TITLES = {
3302
3729
  quadSpace: "Large space",
3303
3730
  qquadSpace: "Extra-large space"
3304
3731
  };
3732
+ var ENGLISH_ACCENT_TITLES = {
3733
+ vec: "Vector arrow",
3734
+ hat: "Hat",
3735
+ tilde: "Tilde",
3736
+ dot: "Dot",
3737
+ ddot: "Double dot",
3738
+ dddot: "Triple dot",
3739
+ bar: "Bar",
3740
+ check: "Check",
3741
+ breve: "Breve",
3742
+ acute: "Acute",
3743
+ grave: "Grave",
3744
+ overline: "Overline",
3745
+ underline: "Underline",
3746
+ overleftarrow: "Over left arrow",
3747
+ overrightarrow: "Over right arrow",
3748
+ overleftrightarrow: "Over left-right arrow"
3749
+ };
3305
3750
  var ENGLISH_OPERATOR_TITLES = {
3306
3751
  inf: "Infinity",
3307
3752
  times: "Multiplication",
@@ -3375,6 +3820,10 @@ var EQUATION_EDITOR_MESSAGES = {
3375
3820
  insertBraces: "\u0625\u062F\u0631\u0627\u062C \u062D\u0627\u0635\u0631\u062A\u064A\u0646",
3376
3821
  insertFraction: "\u0625\u062F\u0631\u0627\u062C \u0643\u0633\u0631",
3377
3822
  insertRoot: "\u0625\u062F\u0631\u0627\u062C \u062C\u0630\u0631",
3823
+ insertOverset: "\u0625\u062F\u0631\u0627\u062C \u0641\u0648\u0642",
3824
+ insertUnderset: "\u0625\u062F\u0631\u0627\u062C \u062A\u062D\u062A",
3825
+ insertAccentPair: "\u0625\u062F\u0631\u0627\u062C \u0641\u0648\u0642 \u0648\u062A\u062D\u062A",
3826
+ insertAccents: "\u0625\u062F\u0631\u0627\u062C \u0644\u0643\u0646\u0629",
3378
3827
  environments: "\u0627\u0644\u0628\u064A\u0626\u0627\u062A",
3379
3828
  insertEnvironment: "\u0625\u062F\u0631\u0627\u062C \u0628\u064A\u0626\u0629 \u0634\u0628\u0643\u064A\u0629",
3380
3829
  environmentType: "\u0646\u0648\u0639 \u0627\u0644\u0628\u064A\u0626\u0629",
@@ -3482,6 +3931,10 @@ var EQUATION_EDITOR_MESSAGES = {
3482
3931
  insertBraces: "Insert braces",
3483
3932
  insertFraction: "Insert fraction",
3484
3933
  insertRoot: "Insert root",
3934
+ insertOverset: "Insert overset",
3935
+ insertUnderset: "Insert underset",
3936
+ insertAccentPair: "Insert overset and underset",
3937
+ insertAccents: "Insert accent",
3485
3938
  environments: "Environments",
3486
3939
  insertEnvironment: "Insert grid environment",
3487
3940
  environmentType: "Environment type",
@@ -3582,6 +4035,9 @@ function atomicCommandTitle(spec, locale) {
3582
4035
  function atomicOperatorCommandTitle(spec, locale) {
3583
4036
  return locale === "en" ? ENGLISH_OPERATOR_TITLES[spec.id] ?? spec.title : spec.title;
3584
4037
  }
4038
+ function accentCommandTitle(spec, locale) {
4039
+ return locale === "en" ? ENGLISH_ACCENT_TITLES[spec.id] ?? spec.title : spec.title;
4040
+ }
3585
4041
 
3586
4042
  // src/editor/state.ts
3587
4043
  function ensureSyncEntry(session, nodeId) {
@@ -3616,7 +4072,7 @@ function syncSelectionToCaret(session) {
3616
4072
  session.selectedNodeId = located.relation.ownerNodeId;
3617
4073
  return;
3618
4074
  }
3619
- if (located.relation.kind === "inner" || located.relation.kind === "numerator" || located.relation.kind === "denominator" || located.relation.kind === "radicand" || located.relation.kind === "rootIndex" || located.relation.kind === "matrixCell") {
4075
+ if (located.relation.kind === "inner" || located.relation.kind === "numerator" || located.relation.kind === "denominator" || located.relation.kind === "radicand" || located.relation.kind === "rootIndex" || located.relation.kind === "overExpr" || located.relation.kind === "underExpr" || located.relation.kind === "baseExpr" || located.relation.kind === "matrixCell") {
3620
4076
  session.selectedNodeId = located.relation.ownerNodeId;
3621
4077
  return;
3622
4078
  }
@@ -3973,6 +4429,106 @@ function moveCaretVertical(session, direction) {
3973
4429
  appendDebug(next, "moveCaretVertical", "sqrt-radicand-down-exit");
3974
4430
  return next;
3975
4431
  }
4432
+ if (located.relation.kind === "overExpr" && ownerLocated && ownerNode && ownerNode.baseExpr) {
4433
+ if (direction === "down") {
4434
+ next.caret = {
4435
+ chainId: ownerNode.baseExpr.id,
4436
+ index: ownerNode.baseExpr.nodes.length
4437
+ };
4438
+ next.selectedStructureNodeId = null;
4439
+ syncSelectionToCaret(next);
4440
+ appendDebug(next, "moveCaretVertical", "overset-over->base");
4441
+ return next;
4442
+ }
4443
+ next.caret = {
4444
+ chainId: ownerLocated.chain.id,
4445
+ index: ownerLocated.index
4446
+ };
4447
+ next.selectedStructureNodeId = null;
4448
+ syncSelectionToCaret(next);
4449
+ appendDebug(next, "moveCaretVertical", "overset-over-up-exit");
4450
+ return next;
4451
+ }
4452
+ if (located.relation.kind === "baseExpr" && ownerLocated && ownerNode && ownerNode.kind === "overset" && ownerNode.overExpr) {
4453
+ if (direction === "up") {
4454
+ next.caret = {
4455
+ chainId: ownerNode.overExpr.id,
4456
+ index: ownerNode.overExpr.nodes.length
4457
+ };
4458
+ next.selectedStructureNodeId = null;
4459
+ syncSelectionToCaret(next);
4460
+ appendDebug(next, "moveCaretVertical", "overset-base->over");
4461
+ return next;
4462
+ }
4463
+ next.caret = {
4464
+ chainId: ownerLocated.chain.id,
4465
+ index: ownerLocated.index + 1
4466
+ };
4467
+ next.selectedStructureNodeId = null;
4468
+ syncSelectionToCaret(next);
4469
+ appendDebug(next, "moveCaretVertical", "overset-base-down-exit");
4470
+ return next;
4471
+ }
4472
+ if (located.relation.kind === "baseExpr" && ownerLocated && ownerNode && ownerNode.kind === "underset" && ownerNode.underExpr) {
4473
+ if (direction === "down") {
4474
+ next.caret = {
4475
+ chainId: ownerNode.underExpr.id,
4476
+ index: ownerNode.underExpr.nodes.length
4477
+ };
4478
+ next.selectedStructureNodeId = null;
4479
+ syncSelectionToCaret(next);
4480
+ appendDebug(next, "moveCaretVertical", "underset-base->under");
4481
+ return next;
4482
+ }
4483
+ next.caret = {
4484
+ chainId: ownerLocated.chain.id,
4485
+ index: ownerLocated.index
4486
+ };
4487
+ next.selectedStructureNodeId = null;
4488
+ syncSelectionToCaret(next);
4489
+ appendDebug(next, "moveCaretVertical", "underset-base-up-exit");
4490
+ return next;
4491
+ }
4492
+ if (located.relation.kind === "underExpr" && ownerLocated && ownerNode && ownerNode.baseExpr) {
4493
+ if (direction === "up") {
4494
+ next.caret = {
4495
+ chainId: ownerNode.baseExpr.id,
4496
+ index: ownerNode.baseExpr.nodes.length
4497
+ };
4498
+ next.selectedStructureNodeId = null;
4499
+ syncSelectionToCaret(next);
4500
+ appendDebug(next, "moveCaretVertical", "underset-under->base");
4501
+ return next;
4502
+ }
4503
+ next.caret = {
4504
+ chainId: ownerLocated.chain.id,
4505
+ index: ownerLocated.index + 1
4506
+ };
4507
+ next.selectedStructureNodeId = null;
4508
+ syncSelectionToCaret(next);
4509
+ appendDebug(next, "moveCaretVertical", "underset-under-down-exit");
4510
+ return next;
4511
+ }
4512
+ if (located.relation.kind === "baseExpr" && ownerLocated && ownerNode && ownerNode.kind === "accent") {
4513
+ if (direction === "up") {
4514
+ next.caret = {
4515
+ chainId: ownerLocated.chain.id,
4516
+ index: ownerLocated.index
4517
+ };
4518
+ next.selectedStructureNodeId = null;
4519
+ syncSelectionToCaret(next);
4520
+ appendDebug(next, "moveCaretVertical", "accent-base-up-exit");
4521
+ return next;
4522
+ }
4523
+ next.caret = {
4524
+ chainId: ownerLocated.chain.id,
4525
+ index: ownerLocated.index + 1
4526
+ };
4527
+ next.selectedStructureNodeId = null;
4528
+ syncSelectionToCaret(next);
4529
+ appendDebug(next, "moveCaretVertical", "accent-base-down-exit");
4530
+ return next;
4531
+ }
3976
4532
  if (located.relation.kind === "matrixCell" && ownerLocated && ownerNode?.matrixRows) {
3977
4533
  const rowIndex = located.relation.rowIndex ?? 0;
3978
4534
  const columnIndex = located.relation.columnIndex ?? 0;
@@ -4350,6 +4906,119 @@ function insertSqrt(session) {
4350
4906
  appendDebug(next, "insertSqrt", "");
4351
4907
  return next;
4352
4908
  }
4909
+ function insertOverset(session) {
4910
+ const base = replaceSelectionFirst(session);
4911
+ const next = cloneEditorSession(base);
4912
+ const englishNode = createOversetNode();
4913
+ const arabicNode = createOversetNode();
4914
+ arabicNode.id = englishNode.id;
4915
+ if (arabicNode.overExpr && englishNode.overExpr) {
4916
+ arabicNode.overExpr.id = englishNode.overExpr.id;
4917
+ }
4918
+ if (arabicNode.baseExpr && englishNode.baseExpr) {
4919
+ arabicNode.baseExpr.id = englishNode.baseExpr.id;
4920
+ }
4921
+ insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);
4922
+ next.caret = {
4923
+ chainId: englishNode.overExpr ? englishNode.overExpr.id : next.caret.chainId,
4924
+ index: 0
4925
+ };
4926
+ next.selectedStructureNodeId = null;
4927
+ syncSelectionToCaret(next);
4928
+ appendDebug(next, "insertOverset", "");
4929
+ return next;
4930
+ }
4931
+ function insertUnderset(session) {
4932
+ const base = replaceSelectionFirst(session);
4933
+ const next = cloneEditorSession(base);
4934
+ const englishNode = createUndersetNode();
4935
+ const arabicNode = createUndersetNode();
4936
+ arabicNode.id = englishNode.id;
4937
+ if (arabicNode.underExpr && englishNode.underExpr) {
4938
+ arabicNode.underExpr.id = englishNode.underExpr.id;
4939
+ }
4940
+ if (arabicNode.baseExpr && englishNode.baseExpr) {
4941
+ arabicNode.baseExpr.id = englishNode.baseExpr.id;
4942
+ }
4943
+ insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);
4944
+ next.caret = {
4945
+ chainId: englishNode.underExpr ? englishNode.underExpr.id : next.caret.chainId,
4946
+ index: 0
4947
+ };
4948
+ next.selectedStructureNodeId = null;
4949
+ syncSelectionToCaret(next);
4950
+ appendDebug(next, "insertUnderset", "");
4951
+ return next;
4952
+ }
4953
+ function insertLimitsSeriesTemplate(session, commandId) {
4954
+ const base = replaceSelectionFirst(session);
4955
+ const next = cloneEditorSession(base);
4956
+ const { english, arabic } = buildLimitsSeriesTemplate(commandId);
4957
+ insertMirroredNode(next, next.caret.chainId, next.caret.index, english, arabic);
4958
+ syncSubtreeRecursive(next, english, arabic);
4959
+ next.caret = limitsSeriesTemplateInitialCaret(english);
4960
+ next.selectedStructureNodeId = null;
4961
+ syncSelectionToCaret(next);
4962
+ appendDebug(next, "insertLimitsSeriesTemplate", commandId);
4963
+ return next;
4964
+ }
4965
+ function insertAccentPair(session) {
4966
+ const base = replaceSelectionFirst(session);
4967
+ const next = cloneEditorSession(base);
4968
+ const { english, arabic } = buildAccentPairTemplate();
4969
+ insertMirroredNode(next, next.caret.chainId, next.caret.index, english, arabic);
4970
+ syncSubtreeRecursive(next, english, arabic);
4971
+ next.caret = accentPairTemplateInitialCaret(english);
4972
+ next.selectedStructureNodeId = null;
4973
+ syncSelectionToCaret(next);
4974
+ appendDebug(next, "insertAccentPair", "");
4975
+ return next;
4976
+ }
4977
+ function insertAccent(session, accentId) {
4978
+ const next = cloneEditorSession(session);
4979
+ const englishNode = createAccentNode(accentId);
4980
+ const arabicNode = createAccentNode(accentId);
4981
+ arabicNode.id = englishNode.id;
4982
+ if (arabicNode.baseExpr && englishNode.baseExpr) {
4983
+ arabicNode.baseExpr.id = englishNode.baseExpr.id;
4984
+ }
4985
+ if (isSelectionActive(next.selection) && next.selection) {
4986
+ const sel = next.selection;
4987
+ const { start, end } = normalizeSelection(sel);
4988
+ const englishLocated = findChainById(next.englishTree, sel.chainId);
4989
+ const arabicLocated = findChainById(next.arabicTree, sel.chainId);
4990
+ if (englishLocated && arabicLocated && end > start) {
4991
+ const count = end - start;
4992
+ const englishWrapped = englishLocated.chain.nodes.splice(start, count);
4993
+ const arabicWrapped = arabicLocated.chain.nodes.splice(start, count);
4994
+ englishNode.baseExpr.nodes = englishWrapped;
4995
+ arabicNode.baseExpr.nodes = arabicWrapped;
4996
+ englishLocated.chain.nodes.splice(start, 0, englishNode);
4997
+ arabicLocated.chain.nodes.splice(start, 0, arabicNode);
4998
+ syncSubtreeRecursive(next, englishNode, arabicNode);
4999
+ next.caret = {
5000
+ chainId: englishNode.baseExpr.id,
5001
+ index: englishWrapped.length
5002
+ };
5003
+ next.selection = null;
5004
+ next.selectedStructureNodeId = null;
5005
+ syncSelectionToCaret(next);
5006
+ appendDebug(next, "insertAccent", `${accentId}:wrap`);
5007
+ return next;
5008
+ }
5009
+ }
5010
+ insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);
5011
+ syncSubtreeRecursive(next, englishNode, arabicNode);
5012
+ next.caret = {
5013
+ chainId: englishNode.baseExpr ? englishNode.baseExpr.id : next.caret.chainId,
5014
+ index: 0
5015
+ };
5016
+ next.selection = null;
5017
+ next.selectedStructureNodeId = null;
5018
+ syncSelectionToCaret(next);
5019
+ appendDebug(next, "insertAccent", `${accentId}:empty`);
5020
+ return next;
5021
+ }
4353
5022
  function insertMatrixEnv(session, style, rows, columns) {
4354
5023
  return insertGridEnv(session, style, rows, columns);
4355
5024
  }
@@ -4597,7 +5266,7 @@ function deleteBackward(session) {
4597
5266
  if (!previousNode) {
4598
5267
  return session;
4599
5268
  }
4600
- if ((previousNode.kind === "delimiter" || previousNode.kind === "frac" || previousNode.kind === "sqrt" || previousNode.kind === "env") && next.selectedStructureNodeId !== previousNode.id) {
5269
+ if ((previousNode.kind === "delimiter" || previousNode.kind === "frac" || previousNode.kind === "sqrt" || previousNode.kind === "overset" || previousNode.kind === "underset" || previousNode.kind === "accent" || previousNode.kind === "env") && next.selectedStructureNodeId !== previousNode.id) {
4601
5270
  next.selectedStructureNodeId = previousNode.id;
4602
5271
  next.selectedNodeId = previousNode.id;
4603
5272
  appendDebug(next, "deleteBackward", "selected structure");
@@ -5087,6 +5756,168 @@ function buildSqrtNodeBody(node, buildChain, side) {
5087
5756
  return wrap;
5088
5757
  }
5089
5758
 
5759
+ // src/editor/display/overset.ts
5760
+ var OVERSET_CSS = `
5761
+ .overset {
5762
+ display: inline-flex;
5763
+ flex-direction: column;
5764
+ align-items: center;
5765
+ justify-content: center;
5766
+ vertical-align: middle;
5767
+ margin: 0 2px;
5768
+ min-width: 1.2em;
5769
+ }
5770
+
5771
+ .overset-over {
5772
+ display: inline-flex;
5773
+ justify-content: center;
5774
+ align-items: center;
5775
+ min-height: 0.85em;
5776
+ padding: 0 2px;
5777
+ font-size: 0.72em;
5778
+ line-height: 1.1;
5779
+ }
5780
+
5781
+ .overset-base {
5782
+ display: inline-flex;
5783
+ justify-content: center;
5784
+ align-items: center;
5785
+ min-height: 1.05em;
5786
+ padding: 0 2px;
5787
+ }
5788
+ `.trim();
5789
+ function buildOversetNodeBody(node, buildChain) {
5790
+ const wrap = document.createElement("span");
5791
+ wrap.className = "overset";
5792
+ const over = document.createElement("span");
5793
+ over.className = "overset-over";
5794
+ if (node.overExpr) {
5795
+ over.appendChild(buildChain(node.overExpr));
5796
+ }
5797
+ const base = document.createElement("span");
5798
+ base.className = "overset-base";
5799
+ if (node.baseExpr) {
5800
+ base.appendChild(buildChain(node.baseExpr));
5801
+ }
5802
+ wrap.appendChild(over);
5803
+ wrap.appendChild(base);
5804
+ return wrap;
5805
+ }
5806
+
5807
+ // src/editor/display/underset.ts
5808
+ var UNDERSET_CSS = `
5809
+ .underset {
5810
+ display: inline-flex;
5811
+ flex-direction: column;
5812
+ align-items: center;
5813
+ justify-content: center;
5814
+ vertical-align: middle;
5815
+ margin: 0 2px;
5816
+ min-width: 1.2em;
5817
+ }
5818
+
5819
+ .underset-base {
5820
+ display: inline-flex;
5821
+ justify-content: center;
5822
+ align-items: center;
5823
+ min-height: 1.05em;
5824
+ padding: 0 2px;
5825
+ }
5826
+
5827
+ .underset-under {
5828
+ display: inline-flex;
5829
+ justify-content: center;
5830
+ align-items: center;
5831
+ min-height: 0.85em;
5832
+ padding: 0 2px;
5833
+ font-size: 0.72em;
5834
+ line-height: 1.1;
5835
+ }
5836
+ `.trim();
5837
+ function buildUndersetNodeBody(node, buildChain) {
5838
+ const wrap = document.createElement("span");
5839
+ wrap.className = "underset";
5840
+ const base = document.createElement("span");
5841
+ base.className = "underset-base";
5842
+ if (node.baseExpr) {
5843
+ base.appendChild(buildChain(node.baseExpr));
5844
+ }
5845
+ const under = document.createElement("span");
5846
+ under.className = "underset-under";
5847
+ if (node.underExpr) {
5848
+ under.appendChild(buildChain(node.underExpr));
5849
+ }
5850
+ wrap.appendChild(base);
5851
+ wrap.appendChild(under);
5852
+ return wrap;
5853
+ }
5854
+
5855
+ // src/editor/display/accent.ts
5856
+ var ACCENT_CSS = `
5857
+ .math-accent {
5858
+ display: inline-flex;
5859
+ flex-direction: column;
5860
+ align-items: center;
5861
+ justify-content: center;
5862
+ vertical-align: middle;
5863
+ margin: 0 2px;
5864
+ min-width: 1.1em;
5865
+ }
5866
+
5867
+ .math-accent-chrome {
5868
+ display: inline-flex;
5869
+ justify-content: center;
5870
+ align-items: center;
5871
+ min-height: 0.7em;
5872
+ padding: 0 2px;
5873
+ font-size: 0.85em;
5874
+ line-height: 1;
5875
+ color: var(--butex-script-color, #475569);
5876
+ user-select: none;
5877
+ }
5878
+
5879
+ .math-accent-base {
5880
+ display: inline-flex;
5881
+ justify-content: center;
5882
+ align-items: center;
5883
+ min-height: 1.05em;
5884
+ padding: 0 2px;
5885
+ }
5886
+
5887
+ .math-accent--under .math-accent-chrome {
5888
+ min-height: 0.45em;
5889
+ border-top: 1.5px solid currentColor;
5890
+ width: 100%;
5891
+ font-size: 0;
5892
+ color: var(--butex-surface-fg, #0f172a);
5893
+ }
5894
+ `.trim();
5895
+ function buildAccentNodeBody(node, buildChain) {
5896
+ const wrap = document.createElement("span");
5897
+ const spec = accentCommandSpec(node.expr);
5898
+ const placement = spec?.placement ?? "over";
5899
+ wrap.className = placement === "under" ? "math-accent math-accent--under" : "math-accent math-accent--over";
5900
+ const chrome = document.createElement("span");
5901
+ chrome.className = "math-accent-chrome";
5902
+ chrome.setAttribute("aria-hidden", "true");
5903
+ if (placement === "over") {
5904
+ chrome.textContent = spec?.label ?? "\u02C6";
5905
+ }
5906
+ const base = document.createElement("span");
5907
+ base.className = "math-accent-base";
5908
+ if (node.baseExpr) {
5909
+ base.appendChild(buildChain(node.baseExpr));
5910
+ }
5911
+ if (placement === "under") {
5912
+ wrap.appendChild(base);
5913
+ wrap.appendChild(chrome);
5914
+ } else {
5915
+ wrap.appendChild(chrome);
5916
+ wrap.appendChild(base);
5917
+ }
5918
+ return wrap;
5919
+ }
5920
+
5090
5921
  // src/editor/display/env.ts
5091
5922
  var WRAPPERS = {
5092
5923
  matrix: { left: "", right: "" },
@@ -5459,6 +6290,15 @@ function buildNodeBody(node, buildChain, side, digitForm = "western", uiLocale =
5459
6290
  if (node.kind === "sqrt") {
5460
6291
  return buildSqrtNodeBody(node, buildChain, side);
5461
6292
  }
6293
+ if (node.kind === "overset") {
6294
+ return buildOversetNodeBody(node, buildChain);
6295
+ }
6296
+ if (node.kind === "underset") {
6297
+ return buildUndersetNodeBody(node, buildChain);
6298
+ }
6299
+ if (node.kind === "accent") {
6300
+ return buildAccentNodeBody(node, buildChain);
6301
+ }
5462
6302
  if (node.kind === "env") {
5463
6303
  return buildMatrixEnvNodeBody(node, buildChain, side);
5464
6304
  }
@@ -5658,6 +6498,12 @@ ${FRAC_CSS}
5658
6498
 
5659
6499
  ${SQRT_CSS}
5660
6500
 
6501
+ ${OVERSET_CSS}
6502
+
6503
+ ${UNDERSET_CSS}
6504
+
6505
+ ${ACCENT_CSS}
6506
+
5661
6507
  ${MATRIX_ENV_CSS}
5662
6508
 
5663
6509
  ${ATOMIC_COMMAND_CSS}
@@ -6377,6 +7223,26 @@ function createEditorRuntime(options) {
6377
7223
  applyStructural((prev) => insertSqrt(prev));
6378
7224
  surfaceEl.focus();
6379
7225
  },
7226
+ insertOverset: () => {
7227
+ applyStructural((prev) => insertOverset(prev));
7228
+ surfaceEl.focus();
7229
+ },
7230
+ insertUnderset: () => {
7231
+ applyStructural((prev) => insertUnderset(prev));
7232
+ surfaceEl.focus();
7233
+ },
7234
+ insertLimitsSeriesTemplate: (commandId) => {
7235
+ applyStructural((prev) => insertLimitsSeriesTemplate(prev, commandId));
7236
+ surfaceEl.focus();
7237
+ },
7238
+ insertAccentPair: () => {
7239
+ applyStructural((prev) => insertAccentPair(prev));
7240
+ surfaceEl.focus();
7241
+ },
7242
+ insertAccent: (accentId) => {
7243
+ applyStructural((prev) => insertAccent(prev, accentId));
7244
+ surfaceEl.focus();
7245
+ },
6380
7246
  insertAtomicCommand: (commandId) => {
6381
7247
  applyStructural((prev) => insertAtomicCommand(prev, commandId));
6382
7248
  surfaceEl.focus();
@@ -6703,6 +7569,56 @@ function commandToEditorNode(node) {
6703
7569
  }
6704
7570
  return { editable: true, node: sqrt };
6705
7571
  }
7572
+ if (node.name === "\\overset" && node.mandatoryArgs.length >= 2) {
7573
+ const overset = createOversetNode();
7574
+ const overExpr = chainToEditorChain(node.mandatoryArgs[0]);
7575
+ const baseExpr = chainToEditorChain(node.mandatoryArgs[1]);
7576
+ if (!overExpr.editable) {
7577
+ return overExpr;
7578
+ }
7579
+ if (!baseExpr.editable) {
7580
+ return baseExpr;
7581
+ }
7582
+ overset.overExpr = overExpr.chain;
7583
+ overset.baseExpr = baseExpr.chain;
7584
+ const scripts = attachScripts(node, overset);
7585
+ if (scripts) {
7586
+ return scripts;
7587
+ }
7588
+ return { editable: true, node: overset };
7589
+ }
7590
+ if (node.name === "\\underset" && node.mandatoryArgs.length >= 2) {
7591
+ const underset = createUndersetNode();
7592
+ const underExpr = chainToEditorChain(node.mandatoryArgs[0]);
7593
+ const baseExpr = chainToEditorChain(node.mandatoryArgs[1]);
7594
+ if (!underExpr.editable) {
7595
+ return underExpr;
7596
+ }
7597
+ if (!baseExpr.editable) {
7598
+ return baseExpr;
7599
+ }
7600
+ underset.underExpr = underExpr.chain;
7601
+ underset.baseExpr = baseExpr.chain;
7602
+ const scripts = attachScripts(node, underset);
7603
+ if (scripts) {
7604
+ return scripts;
7605
+ }
7606
+ return { editable: true, node: underset };
7607
+ }
7608
+ const accentId = accentCommandIdFromTex(node.name);
7609
+ if (accentId && node.mandatoryArgs.length >= 1) {
7610
+ const accent = createAccentNode(accentId);
7611
+ const baseExpr = chainToEditorChain(node.mandatoryArgs[0]);
7612
+ if (!baseExpr.editable) {
7613
+ return baseExpr;
7614
+ }
7615
+ accent.baseExpr = baseExpr.chain;
7616
+ const scripts = attachScripts(node, accent);
7617
+ if (scripts) {
7618
+ return scripts;
7619
+ }
7620
+ return { editable: true, node: accent };
7621
+ }
6706
7622
  const atomicId = commandIdForTex(node.name);
6707
7623
  if (atomicId && node.optionalArgs.length === 0 && node.mandatoryArgs.length === 0) {
6708
7624
  const atomic = createEditorNode("atomicCommand", atomicId);
@@ -6839,6 +7755,21 @@ function editorEnvToAstNode(node) {
6839
7755
  const scripts = attachAstScripts(node, env);
6840
7756
  return scripts ?? { ok: true, node: env };
6841
7757
  }
7758
+ function accentChainForExport(accent) {
7759
+ if (!accent) {
7760
+ return { ok: true, chain: new ChainNode([]) };
7761
+ }
7762
+ return editorChainToAstChain(accent);
7763
+ }
7764
+ function nodeFromAccentBase(command, accent, base) {
7765
+ if (accent.chain.length > 0) {
7766
+ return new CommandNode(command, [], [accent, base]);
7767
+ }
7768
+ if (base.chain.length === 1) {
7769
+ return base.chain[0];
7770
+ }
7771
+ return new DelimiterNode("", base, "");
7772
+ }
6842
7773
  function editorNodeToAstNode(node) {
6843
7774
  let astNode;
6844
7775
  if (node.kind === "char") {
@@ -6877,6 +7808,36 @@ function editorNodeToAstNode(node) {
6877
7808
  optionalArgs.push(rootIndex.chain);
6878
7809
  }
6879
7810
  astNode = new CommandNode("\\sqrt", optionalArgs, [radicand.chain]);
7811
+ } else if (node.kind === "overset" && node.baseExpr) {
7812
+ const accent = accentChainForExport(node.overExpr);
7813
+ if (!accent.ok) {
7814
+ return accent;
7815
+ }
7816
+ const baseExpr = editorChainToAstChain(node.baseExpr);
7817
+ if (!baseExpr.ok) {
7818
+ return baseExpr;
7819
+ }
7820
+ astNode = nodeFromAccentBase("\\overset", accent.chain, baseExpr.chain);
7821
+ } else if (node.kind === "underset" && node.baseExpr) {
7822
+ const accent = accentChainForExport(node.underExpr);
7823
+ if (!accent.ok) {
7824
+ return accent;
7825
+ }
7826
+ const baseExpr = editorChainToAstChain(node.baseExpr);
7827
+ if (!baseExpr.ok) {
7828
+ return baseExpr;
7829
+ }
7830
+ astNode = nodeFromAccentBase("\\underset", accent.chain, baseExpr.chain);
7831
+ } else if (node.kind === "accent" && node.baseExpr) {
7832
+ const tex = accentCommandSpec(node.expr)?.englishTex;
7833
+ if (!tex) {
7834
+ return { ok: false, reason: `\u0644\u0643\u0646\u0629 \u0631\u064A\u0627\u0636\u064A\u0629 \u063A\u064A\u0631 \u0645\u062F\u0639\u0648\u0645\u0629 \u062D\u0627\u0644\u064A\u0627: ${node.expr}` };
7835
+ }
7836
+ const baseExpr = editorChainToAstChain(node.baseExpr);
7837
+ if (!baseExpr.ok) {
7838
+ return baseExpr;
7839
+ }
7840
+ astNode = new CommandNode(tex, [], [baseExpr.chain]);
6880
7841
  } else if (node.kind === "atomicCommand") {
6881
7842
  const tex = atomicCommandSpec(node.expr)?.englishTex;
6882
7843
  if (!tex) {
@@ -8867,7 +9828,10 @@ import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } fro
8867
9828
  // src/mathjax/svgPatcher.ts
8868
9829
  var SVG_ARABSQRT_SELECTOR = 'mjx-container[jax="SVG"] svg .mjx-rtl-mirror[data-mjx-rtl-root="true"]';
8869
9830
  var ARABSQRT_SELECTOR = '.mjx-rtl-mirror[data-mjx-rtl-root="true"]';
9831
+ var SVG_PREVIEW_MIRROR_SELECTOR = 'mjx-container[jax="SVG"] svg .butex-preview-mirror';
9832
+ var PREVIEW_MIRROR_SELECTOR = ".butex-preview-mirror";
8870
9833
  var PATCHED_ATTR = "data-butex-svg-arabsqrt";
9834
+ var MIRROR_PATCHED_ATTR = "data-butex-svg-mirror";
8871
9835
  var ROOT_INDEX_SCALE = 0.72;
8872
9836
  var ROOT_INDEX_GAP_FACTOR = 0.08;
8873
9837
  var ROOT_INDEX_MIN_GAP = 2;
@@ -8892,11 +9856,12 @@ function directSvgElementChildren(element) {
8892
9856
  return Array.from(element.children).filter((child) => child instanceof SVGElement);
8893
9857
  }
8894
9858
  function boxFor(element) {
8895
- if (!(element instanceof SVGGraphicsElement) || typeof element.getBBox !== "function") {
9859
+ const candidate = element;
9860
+ if (typeof candidate.getBBox !== "function") {
8896
9861
  return null;
8897
9862
  }
8898
9863
  try {
8899
- const box = element.getBBox();
9864
+ const box = candidate.getBBox();
8900
9865
  return {
8901
9866
  x: box.x,
8902
9867
  y: box.y,
@@ -9140,6 +10105,31 @@ function patchArabSqrtRoot(root) {
9140
10105
  root.setAttribute(PATCHED_ATTR, "patched");
9141
10106
  rootNode.setAttribute(PATCHED_ATTR, "patched");
9142
10107
  }
10108
+ function patchPreviewMirror(element) {
10109
+ if (element.getAttribute(MIRROR_PATCHED_ATTR) === "patched") {
10110
+ return;
10111
+ }
10112
+ const box = boxFor(element);
10113
+ if (!box || box.width <= 0) {
10114
+ return;
10115
+ }
10116
+ const [tx, ty] = readTranslate(element);
10117
+ const mirrorX = tx + 2 * box.x + box.width;
10118
+ element.setAttribute(
10119
+ "transform",
10120
+ `translate(${roundSvg(mirrorX)},${roundSvg(ty)}) scale(-1,1)`
10121
+ );
10122
+ element.setAttribute(MIRROR_PATCHED_ATTR, "patched");
10123
+ }
10124
+ function collectPreviewMirrors(root) {
10125
+ let mirrors = Array.from(root.querySelectorAll(SVG_PREVIEW_MIRROR_SELECTOR));
10126
+ if (!mirrors.length) {
10127
+ mirrors = Array.from(root.querySelectorAll(PREVIEW_MIRROR_SELECTOR)).filter((candidate) => {
10128
+ return candidate.closest('mjx-container[jax="SVG"]') != null;
10129
+ });
10130
+ }
10131
+ return mirrors;
10132
+ }
9143
10133
  function patchBuTeXSvgMath(root) {
9144
10134
  if (typeof root.querySelectorAll !== "function") {
9145
10135
  return;
@@ -9151,6 +10141,7 @@ function patchBuTeXSvgMath(root) {
9151
10141
  });
9152
10142
  }
9153
10143
  roots.sort((a, b) => rootDepth(b) - rootDepth(a)).forEach((arabSqrtRoot) => patchArabSqrtRoot(arabSqrtRoot));
10144
+ collectPreviewMirrors(root).forEach((mirror) => patchPreviewMirror(mirror));
9154
10145
  }
9155
10146
 
9156
10147
  // src/mathjax/renderIsland.ts
@@ -10917,6 +11908,29 @@ var WIDGET_CHROME_CSS = `
10917
11908
  padding-top: 1px;
10918
11909
  }
10919
11910
 
11911
+ .butex-widget .toolbar-accent-icon {
11912
+ display: inline-flex;
11913
+ flex-direction: column;
11914
+ align-items: center;
11915
+ justify-content: center;
11916
+ min-width: 14px;
11917
+ font-size: 10px;
11918
+ line-height: 1;
11919
+ gap: 1px;
11920
+ }
11921
+
11922
+ .butex-widget .toolbar-accent-icon--over span:first-child,
11923
+ .butex-widget .toolbar-accent-icon--under span:last-child {
11924
+ font-size: 8px;
11925
+ opacity: 0.85;
11926
+ }
11927
+
11928
+ .butex-widget .toolbar-accent-icon--pair span:first-child,
11929
+ .butex-widget .toolbar-accent-icon--pair span:last-child {
11930
+ font-size: 8px;
11931
+ opacity: 0.85;
11932
+ }
11933
+
10920
11934
  .butex-widget .matrix-command-menu {
10921
11935
  position: relative;
10922
11936
  display: inline-flex;
@@ -11653,6 +12667,7 @@ var CHARACTER_FONT_OPTIONS = [
11653
12667
  { id: "diwani", label: "\u062F\u064A\u0648" },
11654
12668
  { id: "diwaniOutline", label: "\u0638\u0644" }
11655
12669
  ];
12670
+ var ACCENT_COMMANDS_LIST = accentCommandsList();
11656
12671
  var FUNCTION_COMMANDS = atomicCommandsByCategory("function");
11657
12672
  var LIMITS_SERIES_COMMANDS = atomicCommandsByCategory("limits_series");
11658
12673
  var FUNCTION2_COMMANDS = atomicCommandsByCategory("function2");
@@ -11800,6 +12815,7 @@ var ButexEditor = forwardRef(
11800
12815
  const [operator2MenuOpen, setOperator2MenuOpen] = useState7(false);
11801
12816
  const [operator3MenuOpen, setOperator3MenuOpen] = useState7(false);
11802
12817
  const [dotMenuOpen, setDotMenuOpen] = useState7(false);
12818
+ const [accentMenuOpen, setAccentMenuOpen] = useState7(false);
11803
12819
  const [integralMenuOpen, setIntegralMenuOpen] = useState7(false);
11804
12820
  const [selectedDigitForm2, setSelectedDigitForm] = useState7("western");
11805
12821
  const [selectedCharacterFont, setSelectedCharacterFont] = useState7("default");
@@ -12069,7 +13085,78 @@ ${arabic || currentMessages.empty}`;
12069
13085
  /* @__PURE__ */ jsx12("button", { id: "insert-sqrt", className: "icon-btn", type: "button", title: messages.insertRoot, "aria-label": messages.insertRoot, onClick: () => {
12070
13086
  runtimeRef.current?.insertSqrt();
12071
13087
  focusSurface();
12072
- }, children: /* @__PURE__ */ jsx12("span", { className: "toolbar-sqrt-icon", "aria-hidden": "true", children: "\u221A" }) })
13088
+ }, children: /* @__PURE__ */ jsx12("span", { className: "toolbar-sqrt-icon", "aria-hidden": "true", children: "\u221A" }) }),
13089
+ /* @__PURE__ */ jsx12("button", { id: "insert-overset", className: "icon-btn", type: "button", title: messages.insertOverset, "aria-label": messages.insertOverset, onClick: () => {
13090
+ runtimeRef.current?.insertOverset();
13091
+ focusSurface();
13092
+ }, children: /* @__PURE__ */ jsxs10("span", { className: "toolbar-accent-icon toolbar-accent-icon--over", "aria-hidden": "true", children: [
13093
+ /* @__PURE__ */ jsx12("span", { children: "\u2217" }),
13094
+ /* @__PURE__ */ jsx12("span", { children: "\u25A1" })
13095
+ ] }) }),
13096
+ /* @__PURE__ */ jsx12("button", { id: "insert-underset", className: "icon-btn", type: "button", title: messages.insertUnderset, "aria-label": messages.insertUnderset, onClick: () => {
13097
+ runtimeRef.current?.insertUnderset();
13098
+ focusSurface();
13099
+ }, children: /* @__PURE__ */ jsxs10("span", { className: "toolbar-accent-icon toolbar-accent-icon--under", "aria-hidden": "true", children: [
13100
+ /* @__PURE__ */ jsx12("span", { children: "\u25A1" }),
13101
+ /* @__PURE__ */ jsx12("span", { children: "\u2217" })
13102
+ ] }) }),
13103
+ /* @__PURE__ */ jsx12("button", { id: "insert-accent-pair", className: "icon-btn", type: "button", title: messages.insertAccentPair, "aria-label": messages.insertAccentPair, onClick: () => {
13104
+ runtimeRef.current?.insertAccentPair();
13105
+ focusSurface();
13106
+ }, children: /* @__PURE__ */ jsxs10("span", { className: "toolbar-accent-icon toolbar-accent-icon--pair", "aria-hidden": "true", children: [
13107
+ /* @__PURE__ */ jsx12("span", { children: "\u2217" }),
13108
+ /* @__PURE__ */ jsx12("span", { children: "\u25A1" }),
13109
+ /* @__PURE__ */ jsx12("span", { children: "\u2217" })
13110
+ ] }) }),
13111
+ /* @__PURE__ */ jsxs10(
13112
+ "div",
13113
+ {
13114
+ className: "function-command-menu operator-command-menu",
13115
+ onBlur: (event) => {
13116
+ const nextFocus = event.relatedTarget;
13117
+ if (!(nextFocus instanceof Node) || !event.currentTarget.contains(nextFocus)) {
13118
+ setAccentMenuOpen(false);
13119
+ }
13120
+ },
13121
+ children: [
13122
+ /* @__PURE__ */ jsx12(
13123
+ "button",
13124
+ {
13125
+ id: "insert-accents",
13126
+ className: "icon-btn function-command-btn operator-command-btn",
13127
+ type: "button",
13128
+ title: messages.insertAccents,
13129
+ "aria-label": messages.insertAccents,
13130
+ "aria-haspopup": "listbox",
13131
+ "aria-expanded": accentMenuOpen,
13132
+ onClick: () => setAccentMenuOpen((open) => !open),
13133
+ children: /* @__PURE__ */ jsxs10("span", { className: "toolbar-accent-icon toolbar-accent-icon--over", "aria-hidden": "true", children: [
13134
+ /* @__PURE__ */ jsx12("span", { children: "\u02C6" }),
13135
+ /* @__PURE__ */ jsx12("span", { children: "\u25A1" })
13136
+ ] })
13137
+ }
13138
+ ),
13139
+ /* @__PURE__ */ jsx12("div", { className: "function-command-options operator-command-options", role: "listbox", "aria-label": messages.insertAccents, hidden: !accentMenuOpen, children: ACCENT_COMMANDS_LIST.map((command) => /* @__PURE__ */ jsx12(
13140
+ "button",
13141
+ {
13142
+ className: "function-command-option operator-command-option",
13143
+ type: "button",
13144
+ role: "option",
13145
+ title: accentCommandTitle(command, uiLocale),
13146
+ "aria-label": accentCommandTitle(command, uiLocale),
13147
+ onMouseDown: (event) => event.preventDefault(),
13148
+ onClick: () => {
13149
+ runtimeRef.current?.insertAccent(command.id);
13150
+ setAccentMenuOpen(false);
13151
+ focusSurface();
13152
+ },
13153
+ children: /* @__PURE__ */ jsx12("span", { className: "operator-command-label", children: command.label })
13154
+ },
13155
+ command.id
13156
+ )) })
13157
+ ]
13158
+ }
13159
+ )
12073
13160
  ] }),
12074
13161
  /* @__PURE__ */ jsx12("div", { className: "toolbar-group toolbar-environments", role: "group", "aria-label": messages.environments, children: /* @__PURE__ */ jsxs10(
12075
13162
  "div",
@@ -12397,7 +13484,7 @@ ${arabic || currentMessages.empty}`;
12397
13484
  "aria-label": atomicCommandTitle(command, uiLocale),
12398
13485
  onMouseDown: (event) => event.preventDefault(),
12399
13486
  onClick: () => {
12400
- runtimeRef.current?.insertAtomicCommand(command.id);
13487
+ runtimeRef.current?.insertLimitsSeriesTemplate(command.id);
12401
13488
  setLimitsSeriesMenuOpen(false);
12402
13489
  focusSurface();
12403
13490
  },