@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.
@@ -665,6 +665,158 @@ function createEmptyDocument() {
665
665
  };
666
666
  }
667
667
 
668
+ // src/editor/accentCommands.ts
669
+ var ACCENT_COMMANDS = {
670
+ vec: {
671
+ id: "vec",
672
+ englishTex: "\\vec",
673
+ arabicTex: "\\arabvec",
674
+ placement: "over",
675
+ label: "\u20D7",
676
+ title: "\u0633\u0647\u0645 \u0641\u0648\u0642"
677
+ },
678
+ hat: {
679
+ id: "hat",
680
+ englishTex: "\\hat",
681
+ arabicTex: "\\hat",
682
+ placement: "over",
683
+ label: "\u02C6",
684
+ title: "\u0642\u0628\u0639\u0629"
685
+ },
686
+ tilde: {
687
+ id: "tilde",
688
+ englishTex: "\\tilde",
689
+ arabicTex: "\\tilde",
690
+ placement: "over",
691
+ label: "\u02DC",
692
+ title: "\u0645\u062F\u0629"
693
+ },
694
+ dot: {
695
+ id: "dot",
696
+ englishTex: "\\dot",
697
+ arabicTex: "\\dot",
698
+ placement: "over",
699
+ label: "\u02D9",
700
+ title: "\u0646\u0642\u0637\u0629 \u0641\u0648\u0642"
701
+ },
702
+ ddot: {
703
+ id: "ddot",
704
+ englishTex: "\\ddot",
705
+ arabicTex: "\\ddot",
706
+ placement: "over",
707
+ label: "\xA8",
708
+ title: "\u0646\u0642\u0637\u062A\u0627\u0646 \u0641\u0648\u0642"
709
+ },
710
+ dddot: {
711
+ id: "dddot",
712
+ englishTex: "\\dddot",
713
+ arabicTex: "\\dddot",
714
+ placement: "over",
715
+ label: "\u20DB",
716
+ title: "\u062B\u0644\u0627\u062B \u0646\u0642\u0627\u0637 \u0641\u0648\u0642"
717
+ },
718
+ bar: {
719
+ id: "bar",
720
+ englishTex: "\\bar",
721
+ arabicTex: "\\bar",
722
+ placement: "over",
723
+ label: "\xAF",
724
+ title: "\u062E\u0637 \u0641\u0648\u0642"
725
+ },
726
+ check: {
727
+ id: "check",
728
+ englishTex: "\\check",
729
+ arabicTex: "\\check",
730
+ placement: "over",
731
+ label: "\u02C7",
732
+ title: "\u0639\u0644\u0627\u0645\u0629 \u062A\u062D\u0642\u0642"
733
+ },
734
+ breve: {
735
+ id: "breve",
736
+ englishTex: "\\breve",
737
+ arabicTex: "\\breve",
738
+ placement: "over",
739
+ label: "\u02D8",
740
+ title: "\u0642\u0648\u0633 \u0642\u0635\u064A\u0631"
741
+ },
742
+ acute: {
743
+ id: "acute",
744
+ englishTex: "\\acute",
745
+ arabicTex: "\\grave",
746
+ placement: "over",
747
+ label: "\xB4",
748
+ title: "\u0646\u0628\u0631\u0629 \u062D\u0627\u062F\u0629"
749
+ },
750
+ grave: {
751
+ id: "grave",
752
+ englishTex: "\\grave",
753
+ arabicTex: "\\acute",
754
+ placement: "over",
755
+ label: "`",
756
+ title: "\u0646\u0628\u0631\u0629 \u062B\u0642\u064A\u0644\u0629"
757
+ },
758
+ overline: {
759
+ id: "overline",
760
+ englishTex: "\\overline",
761
+ arabicTex: "\\overline",
762
+ placement: "over",
763
+ label: "\u203E",
764
+ title: "\u062E\u0637 \u0639\u0644\u0648\u064A \u0645\u0645\u062A\u062F"
765
+ },
766
+ underline: {
767
+ id: "underline",
768
+ englishTex: "\\underline",
769
+ arabicTex: "\\underline",
770
+ placement: "under",
771
+ label: "_",
772
+ title: "\u062E\u0637 \u0633\u0641\u0644\u064A"
773
+ },
774
+ overleftarrow: {
775
+ id: "overleftarrow",
776
+ englishTex: "\\overleftarrow",
777
+ arabicTex: "\\overrightarrow",
778
+ placement: "over",
779
+ label: "\u2190",
780
+ title: "\u0633\u0647\u0645 \u0639\u0644\u0648\u064A \u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631"
781
+ },
782
+ overrightarrow: {
783
+ id: "overrightarrow",
784
+ englishTex: "\\overrightarrow",
785
+ arabicTex: "\\overleftarrow",
786
+ placement: "over",
787
+ label: "\u2192",
788
+ title: "\u0633\u0647\u0645 \u0639\u0644\u0648\u064A \u0625\u0644\u0649 \u0627\u0644\u064A\u0645\u064A\u0646"
789
+ },
790
+ overleftrightarrow: {
791
+ id: "overleftrightarrow",
792
+ englishTex: "\\overleftrightarrow",
793
+ arabicTex: "\\overleftrightarrow",
794
+ placement: "over",
795
+ label: "\u2194",
796
+ title: "\u0633\u0647\u0645 \u0639\u0644\u0648\u064A \u0645\u0632\u062F\u0648\u062C \u0627\u0644\u0627\u062A\u062C\u0627\u0647"
797
+ }
798
+ };
799
+ function accentCommandSpec(id) {
800
+ return Object.prototype.hasOwnProperty.call(ACCENT_COMMANDS, id) ? ACCENT_COMMANDS[id] : null;
801
+ }
802
+ function accentCommandsList() {
803
+ return Object.values(ACCENT_COMMANDS);
804
+ }
805
+ function accentCommandIdFromTex(tex) {
806
+ const normalized = tex.startsWith("\\") ? tex : `\\${tex}`;
807
+ for (const spec of Object.values(ACCENT_COMMANDS)) {
808
+ if (spec.englishTex === normalized) {
809
+ return spec.id;
810
+ }
811
+ }
812
+ for (const spec of Object.values(ACCENT_COMMANDS)) {
813
+ if (spec.arabicTex === normalized) {
814
+ return spec.id;
815
+ }
816
+ }
817
+ return null;
818
+ }
819
+
668
820
  // src/editor/atomicCommands.ts
669
821
  var ATOMIC_COMMANDS = {
670
822
  ///////////////////////// Functions ////////////////////////////////
@@ -1085,7 +1237,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1085
1237
  id: "neq",
1086
1238
  category: "operators1",
1087
1239
  Tex: "\\neq",
1088
- mirror: false,
1240
+ mirror: true,
1089
1241
  Label: "\u2260",
1090
1242
  title: "\u0644\u0627 \u064A\u0633\u0627\u0648\u064A",
1091
1243
  svg_path: null
@@ -1095,6 +1247,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1095
1247
  category: "operators1",
1096
1248
  Tex: "\\approx",
1097
1249
  mirror: false,
1250
+ displayMirror: true,
1098
1251
  Label: "\u2248",
1099
1252
  title: "\u062A\u0642\u0631\u064A\u0628\u0627 \u064A\u0633\u0627\u0648\u064A",
1100
1253
  svg_path: null
@@ -1104,6 +1257,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1104
1257
  category: "operators1",
1105
1258
  Tex: "\\sim",
1106
1259
  mirror: false,
1260
+ displayMirror: true,
1107
1261
  Label: "\u223C",
1108
1262
  title: "\u0645\u0634\u0627\u0628\u0647",
1109
1263
  svg_path: null
@@ -1122,6 +1276,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1122
1276
  category: "operators1",
1123
1277
  Tex: "\\leq",
1124
1278
  mirror: true,
1279
+ displayMirror: false,
1125
1280
  Label: "\u2264",
1126
1281
  title: "\u0623\u0635\u063A\u0631 \u0645\u0646 \u0623\u0648 \u064A\u0633\u0627\u0648\u064A",
1127
1282
  svg_path: null
@@ -1131,6 +1286,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1131
1286
  category: "operators1",
1132
1287
  Tex: "\\geq",
1133
1288
  mirror: true,
1289
+ displayMirror: false,
1134
1290
  Label: "\u2265",
1135
1291
  title: "\u0623\u0643\u0628\u0631 \u0645\u0646 \u0623\u0648 \u064A\u0633\u0627\u0648\u064A",
1136
1292
  svg_path: null
@@ -1140,6 +1296,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1140
1296
  category: "operators1",
1141
1297
  Tex: "\\coloneqq",
1142
1298
  mirror: true,
1299
+ displayMirror: false,
1143
1300
  Label: "\u2254",
1144
1301
  title: "\u064A\u0639\u0631\u0641 \u0628\u0623\u0646\u0647 \u064A\u0633\u0627\u0648\u064A",
1145
1302
  svg_path: null
@@ -1149,6 +1306,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1149
1306
  category: "operators1",
1150
1307
  Tex: "\\eqqcolon",
1151
1308
  mirror: true,
1309
+ displayMirror: false,
1152
1310
  Label: "\u2255",
1153
1311
  title: "\u064A\u0633\u0627\u0648\u064A \u0628\u0627\u0644\u062A\u0639\u0631\u064A\u0641",
1154
1312
  svg_path: null
@@ -1159,6 +1317,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1159
1317
  category: "operators2",
1160
1318
  Tex: "\\propto",
1161
1319
  mirror: true,
1320
+ displayMirror: false,
1162
1321
  Label: "\u221D",
1163
1322
  title: "\u064A\u062A\u0646\u0627\u0633\u0628 \u0645\u0639",
1164
1323
  svg_path: null
@@ -1168,6 +1327,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1168
1327
  category: "operators2",
1169
1328
  Tex: "\\in",
1170
1329
  mirror: true,
1330
+ displayMirror: false,
1171
1331
  Label: "\u2208",
1172
1332
  title: "\u064A\u0646\u062A\u0645\u064A \u0625\u0644\u0649",
1173
1333
  svg_path: null
@@ -1177,6 +1337,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1177
1337
  category: "operators2",
1178
1338
  Tex: "\\notin",
1179
1339
  mirror: false,
1340
+ displayMirror: true,
1180
1341
  Label: "\u2209",
1181
1342
  title: "\u0644\u0627 \u064A\u0646\u062A\u0645\u064A \u0625\u0644\u0649",
1182
1343
  svg_path: null
@@ -1186,6 +1347,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1186
1347
  category: "operators2",
1187
1348
  Tex: "\\subset",
1188
1349
  mirror: true,
1350
+ displayMirror: false,
1189
1351
  Label: "\u2282",
1190
1352
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0645\u0646",
1191
1353
  svg_path: null
@@ -1195,6 +1357,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1195
1357
  category: "operators2",
1196
1358
  Tex: "\\supset",
1197
1359
  mirror: true,
1360
+ displayMirror: false,
1198
1361
  Label: "\u2283",
1199
1362
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0644\u0640",
1200
1363
  svg_path: null
@@ -1204,6 +1367,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1204
1367
  category: "operators2",
1205
1368
  Tex: "\\subseteq",
1206
1369
  mirror: true,
1370
+ displayMirror: false,
1207
1371
  Label: "\u2286",
1208
1372
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1209
1373
  svg_path: null
@@ -1213,6 +1377,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1213
1377
  category: "operators2",
1214
1378
  Tex: "\\supseteq",
1215
1379
  mirror: true,
1380
+ displayMirror: false,
1216
1381
  Label: "\u2287",
1217
1382
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1218
1383
  svg_path: null
@@ -1222,6 +1387,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1222
1387
  category: "operators2",
1223
1388
  Tex: "\\cap",
1224
1389
  mirror: false,
1390
+ displayMirror: true,
1225
1391
  Label: "\u2229",
1226
1392
  title: "\u062A\u0642\u0627\u0637\u0639",
1227
1393
  svg_path: null
@@ -1231,6 +1397,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1231
1397
  category: "operators2",
1232
1398
  Tex: "\\cup",
1233
1399
  mirror: false,
1400
+ displayMirror: true,
1234
1401
  Label: "\u222A",
1235
1402
  title: "\u0627\u062A\u062D\u0627\u062F",
1236
1403
  svg_path: null
@@ -1240,6 +1407,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1240
1407
  category: "operators2",
1241
1408
  Tex: "\\emptyset",
1242
1409
  mirror: false,
1410
+ displayMirror: true,
1243
1411
  Label: "\u2205",
1244
1412
  title: "\u0627\u0644\u0645\u062C\u0645\u0648\u0639\u0629 \u0627\u0644\u062E\u0627\u0644\u064A\u0629",
1245
1413
  svg_path: null
@@ -1249,6 +1417,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1249
1417
  category: "operators2",
1250
1418
  Tex: "\\nsubseteq",
1251
1419
  mirror: true,
1420
+ displayMirror: false,
1252
1421
  Label: "\u2288",
1253
1422
  title: "\u0644\u064A\u0633\u062A \u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1254
1423
  svg_path: null
@@ -1258,6 +1427,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1258
1427
  category: "operators2",
1259
1428
  Tex: "\\nsupseteq",
1260
1429
  mirror: true,
1430
+ displayMirror: false,
1261
1431
  Label: "\u2289",
1262
1432
  title: "\u0644\u064A\u0633\u062A \u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1263
1433
  svg_path: null
@@ -1469,6 +1639,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1469
1639
  category: "integrals",
1470
1640
  Tex: "\\iint",
1471
1641
  mirror: true,
1642
+ displayMirror: false,
1472
1643
  Label: "\u222C",
1473
1644
  title: "\u062A\u0643\u0627\u0645\u0644 \u0645\u0632\u062F\u0648\u062C",
1474
1645
  svg_path: null
@@ -1478,6 +1649,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1478
1649
  category: "integrals",
1479
1650
  Tex: "\\iiint",
1480
1651
  mirror: true,
1652
+ displayMirror: false,
1481
1653
  Label: "\u222D",
1482
1654
  title: "\u062A\u0643\u0627\u0645\u0644 \u062B\u0644\u0627\u062B\u064A",
1483
1655
  svg_path: null
@@ -1487,6 +1659,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1487
1659
  category: "integrals",
1488
1660
  Tex: "\\iiiint",
1489
1661
  mirror: true,
1662
+ displayMirror: false,
1490
1663
  Label: "\u2A0C",
1491
1664
  title: "\u062A\u0643\u0627\u0645\u0644 \u0631\u0628\u0627\u0639\u064A",
1492
1665
  svg_path: null
@@ -1496,6 +1669,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1496
1669
  category: "integrals",
1497
1670
  Tex: "\\oint",
1498
1671
  mirror: true,
1672
+ displayMirror: false,
1499
1673
  Label: "\u222E",
1500
1674
  title: "\u062A\u0643\u0627\u0645\u0644 \u0645\u063A\u0644\u0642",
1501
1675
  svg_path: null
@@ -1505,6 +1679,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1505
1679
  category: "integrals",
1506
1680
  Tex: "\\oiint",
1507
1681
  mirror: true,
1682
+ displayMirror: false,
1508
1683
  Label: "\u222F",
1509
1684
  title: "\u062A\u0643\u0627\u0645\u0644 \u0633\u0637\u062D\u064A \u0645\u063A\u0644\u0642",
1510
1685
  svg_path: null
@@ -1514,6 +1689,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1514
1689
  category: "integrals",
1515
1690
  Tex: "\\oiiint",
1516
1691
  mirror: true,
1692
+ displayMirror: false,
1517
1693
  Label: "\u2230",
1518
1694
  title: "\u062A\u0643\u0627\u0645\u0644 \u062D\u062C\u0645\u064A \u0645\u063A\u0644\u0642",
1519
1695
  svg_path: null
@@ -1615,6 +1791,9 @@ function createEditorNode(kind, expr) {
1615
1791
  denominator: null,
1616
1792
  radicand: null,
1617
1793
  rootIndex: null,
1794
+ overExpr: null,
1795
+ underExpr: null,
1796
+ baseExpr: null,
1618
1797
  envName: null,
1619
1798
  matrixStyle: null,
1620
1799
  matrixRows: null,
@@ -1643,6 +1822,26 @@ function createSqrtNode() {
1643
1822
  rootIndex: createEditorChain()
1644
1823
  };
1645
1824
  }
1825
+ function createOversetNode() {
1826
+ return {
1827
+ ...createEditorNode("overset", ""),
1828
+ overExpr: createEditorChain(),
1829
+ baseExpr: createEditorChain()
1830
+ };
1831
+ }
1832
+ function createUndersetNode() {
1833
+ return {
1834
+ ...createEditorNode("underset", ""),
1835
+ underExpr: createEditorChain(),
1836
+ baseExpr: createEditorChain()
1837
+ };
1838
+ }
1839
+ function createAccentNode(accentId) {
1840
+ return {
1841
+ ...createEditorNode("accent", accentId),
1842
+ baseExpr: createEditorChain()
1843
+ };
1844
+ }
1646
1845
  function createGridEnvNode(envName, rows, columns, columnAlignments) {
1647
1846
  const safeRows = Math.max(1, Math.min(12, Math.trunc(rows)));
1648
1847
  const safeColumns = Math.max(1, Math.min(12, Math.trunc(columns)));
@@ -1707,6 +1906,15 @@ function collectNodeIds(chain, ids) {
1707
1906
  if (node.radicand) {
1708
1907
  collectNodeIds(node.radicand, ids);
1709
1908
  }
1909
+ if (node.overExpr) {
1910
+ collectNodeIds(node.overExpr, ids);
1911
+ }
1912
+ if (node.underExpr) {
1913
+ collectNodeIds(node.underExpr, ids);
1914
+ }
1915
+ if (node.baseExpr) {
1916
+ collectNodeIds(node.baseExpr, ids);
1917
+ }
1710
1918
  if (node.matrixRows) {
1711
1919
  for (const row of node.matrixRows) {
1712
1920
  for (const cell of row) {
@@ -1871,6 +2079,22 @@ function renderMatrixRowsArabic(node, options) {
1871
2079
  }
1872
2080
  return `\\begin{${envName}}${rows.join(" \\\\\n")}\\end{${envName}}`;
1873
2081
  }
2082
+ function renderAccentEnglish(command, accent, base, options) {
2083
+ const baseTex = base ? renderChainEnglish(base, options) : "";
2084
+ const accentTex = accent ? renderChainEnglish(accent, options) : "";
2085
+ if (accentTex === "") {
2086
+ return baseTex;
2087
+ }
2088
+ return `\\${command}{${accentTex}}{${baseTex}}`;
2089
+ }
2090
+ function renderAccentArabic(command, accent, base, options) {
2091
+ const baseTex = base ? renderChainArabic(base, options) : "";
2092
+ const accentTex = accent ? renderChainArabic(accent, options) : "";
2093
+ if (accentTex === "") {
2094
+ return baseTex;
2095
+ }
2096
+ return `\\${command}{${accentTex}}{${baseTex}}`;
2097
+ }
1874
2098
  function escapeText(s) {
1875
2099
  return s.replace(/\\/g, "\\textbackslash{}").replace(/[{}]/g, "\\$&");
1876
2100
  }
@@ -1900,6 +2124,19 @@ function renderNodeEnglish(node, options) {
1900
2124
  const body = `\\sqrt${optionalRootIndexEnglish(node, options)}{${renderChainEnglish(node.radicand, options)}}`;
1901
2125
  return `${body}${latinScripts(node, options)}`;
1902
2126
  }
2127
+ if (node.kind === "overset" && node.baseExpr) {
2128
+ const body = renderAccentEnglish("overset", node.overExpr, node.baseExpr, options);
2129
+ return `${body}${latinScripts(node, options)}`;
2130
+ }
2131
+ if (node.kind === "underset" && node.baseExpr) {
2132
+ const body = renderAccentEnglish("underset", node.underExpr, node.baseExpr, options);
2133
+ return `${body}${latinScripts(node, options)}`;
2134
+ }
2135
+ if (node.kind === "accent" && node.baseExpr) {
2136
+ const cmd = accentCommandSpec(node.expr)?.englishTex ?? `\\${node.expr}`;
2137
+ const body = `${cmd}{${renderChainEnglish(node.baseExpr, options)}}`;
2138
+ return `${body}${latinScripts(node, options)}`;
2139
+ }
1903
2140
  if (node.kind === "env") {
1904
2141
  return `${renderMatrixRowsEnglish(node, options)}${latinScripts(node, options)}`;
1905
2142
  }
@@ -1932,6 +2169,19 @@ function renderNodeArabic(node, options) {
1932
2169
  const content = `\\arabsqrt${optionalRootIndexArabic(node, options)}{${renderChainArabic(node.radicand, options)}}`;
1933
2170
  return arabicScripts(node, content, options);
1934
2171
  }
2172
+ if (node.kind === "overset" && node.baseExpr) {
2173
+ const content = renderAccentArabic("overset", node.overExpr, node.baseExpr, options);
2174
+ return arabicScripts(node, content, options);
2175
+ }
2176
+ if (node.kind === "underset" && node.baseExpr) {
2177
+ const content = renderAccentArabic("underset", node.underExpr, node.baseExpr, options);
2178
+ return arabicScripts(node, content, options);
2179
+ }
2180
+ if (node.kind === "accent" && node.baseExpr) {
2181
+ const cmd = accentCommandSpec(node.expr)?.arabicTex ?? `\\${node.expr}`;
2182
+ const content = `${cmd}{${renderChainArabic(node.baseExpr, options)}}`;
2183
+ return arabicScripts(node, content, options);
2184
+ }
1935
2185
  if (node.kind === "env") {
1936
2186
  return arabicScripts(node, renderMatrixRowsArabic(node, options), options);
1937
2187
  }
@@ -1988,6 +2238,35 @@ function collectCaretPositions(chain) {
1988
2238
  if (node.radicand) {
1989
2239
  walkChain(node.radicand);
1990
2240
  }
2241
+ if (node.kind === "overset") {
2242
+ if (node.overExpr) {
2243
+ walkChain(node.overExpr);
2244
+ }
2245
+ if (node.baseExpr) {
2246
+ walkChain(node.baseExpr);
2247
+ }
2248
+ } else if (node.kind === "underset") {
2249
+ if (node.baseExpr) {
2250
+ walkChain(node.baseExpr);
2251
+ }
2252
+ if (node.underExpr) {
2253
+ walkChain(node.underExpr);
2254
+ }
2255
+ } else if (node.kind === "accent") {
2256
+ if (node.baseExpr) {
2257
+ walkChain(node.baseExpr);
2258
+ }
2259
+ } else {
2260
+ if (node.overExpr) {
2261
+ walkChain(node.overExpr);
2262
+ }
2263
+ if (node.underExpr) {
2264
+ walkChain(node.underExpr);
2265
+ }
2266
+ if (node.baseExpr) {
2267
+ walkChain(node.baseExpr);
2268
+ }
2269
+ }
1991
2270
  if (node.matrixRows) {
1992
2271
  for (const row of node.matrixRows) {
1993
2272
  for (const cell of row) {
@@ -2121,6 +2400,42 @@ function findChainById(root, chainId) {
2121
2400
  return nested;
2122
2401
  }
2123
2402
  }
2403
+ if (node.overExpr) {
2404
+ if (node.overExpr.id === chainId) {
2405
+ return {
2406
+ chain: node.overExpr,
2407
+ relation: { kind: "overExpr", ownerNodeId: node.id, ownerChainId: root.id }
2408
+ };
2409
+ }
2410
+ const nested = findChainById(node.overExpr, chainId);
2411
+ if (nested) {
2412
+ return nested;
2413
+ }
2414
+ }
2415
+ if (node.underExpr) {
2416
+ if (node.underExpr.id === chainId) {
2417
+ return {
2418
+ chain: node.underExpr,
2419
+ relation: { kind: "underExpr", ownerNodeId: node.id, ownerChainId: root.id }
2420
+ };
2421
+ }
2422
+ const nested = findChainById(node.underExpr, chainId);
2423
+ if (nested) {
2424
+ return nested;
2425
+ }
2426
+ }
2427
+ if (node.baseExpr) {
2428
+ if (node.baseExpr.id === chainId) {
2429
+ return {
2430
+ chain: node.baseExpr,
2431
+ relation: { kind: "baseExpr", ownerNodeId: node.id, ownerChainId: root.id }
2432
+ };
2433
+ }
2434
+ const nested = findChainById(node.baseExpr, chainId);
2435
+ if (nested) {
2436
+ return nested;
2437
+ }
2438
+ }
2124
2439
  if (node.matrixRows) {
2125
2440
  for (let rowIndex = 0; rowIndex < node.matrixRows.length; rowIndex += 1) {
2126
2441
  const row = node.matrixRows[rowIndex];
@@ -2194,6 +2509,24 @@ function findNodeById(root, nodeId) {
2194
2509
  return nested;
2195
2510
  }
2196
2511
  }
2512
+ if (node.overExpr) {
2513
+ const nested = findNodeById(node.overExpr, nodeId);
2514
+ if (nested) {
2515
+ return nested;
2516
+ }
2517
+ }
2518
+ if (node.underExpr) {
2519
+ const nested = findNodeById(node.underExpr, nodeId);
2520
+ if (nested) {
2521
+ return nested;
2522
+ }
2523
+ }
2524
+ if (node.baseExpr) {
2525
+ const nested = findNodeById(node.baseExpr, nodeId);
2526
+ if (nested) {
2527
+ return nested;
2528
+ }
2529
+ }
2197
2530
  if (node.matrixRows) {
2198
2531
  for (const row of node.matrixRows) {
2199
2532
  for (const cell of row) {
@@ -2229,6 +2562,15 @@ function nodeChildChains(node) {
2229
2562
  if (node.radicand) {
2230
2563
  chains.push(node.radicand);
2231
2564
  }
2565
+ if (node.overExpr) {
2566
+ chains.push(node.overExpr);
2567
+ }
2568
+ if (node.underExpr) {
2569
+ chains.push(node.underExpr);
2570
+ }
2571
+ if (node.baseExpr) {
2572
+ chains.push(node.baseExpr);
2573
+ }
2232
2574
  if (node.matrixRows) {
2233
2575
  for (const row of node.matrixRows) {
2234
2576
  chains.push(...row);
@@ -2599,6 +2941,91 @@ function derivativeTemplateInitialCaret(englishFrac) {
2599
2941
  };
2600
2942
  }
2601
2943
 
2944
+ // src/editor/limitsTemplates.ts
2945
+ var LIMITS_SERIES_TEMPLATE_IDS = /* @__PURE__ */ new Set([
2946
+ "sum",
2947
+ "prod",
2948
+ "lim",
2949
+ "max",
2950
+ "min",
2951
+ "sup",
2952
+ "inf"
2953
+ ]);
2954
+ function isLimitsSeriesTemplateId(commandId) {
2955
+ return LIMITS_SERIES_TEMPLATE_IDS.has(commandId);
2956
+ }
2957
+ function syncChainIds2(english, arabic) {
2958
+ arabic.id = english.id;
2959
+ const limit = Math.min(english.nodes.length, arabic.nodes.length);
2960
+ for (let index = 0; index < limit; index += 1) {
2961
+ arabic.nodes[index].id = english.nodes[index].id;
2962
+ }
2963
+ }
2964
+ function syncOversetIds(english, arabic) {
2965
+ arabic.id = english.id;
2966
+ if (english.overExpr && arabic.overExpr) {
2967
+ syncChainIds2(english.overExpr, arabic.overExpr);
2968
+ }
2969
+ if (english.baseExpr && arabic.baseExpr) {
2970
+ syncChainIds2(english.baseExpr, arabic.baseExpr);
2971
+ }
2972
+ }
2973
+ function syncUndersetIds(english, arabic) {
2974
+ arabic.id = english.id;
2975
+ if (english.underExpr && arabic.underExpr) {
2976
+ syncChainIds2(english.underExpr, arabic.underExpr);
2977
+ }
2978
+ if (english.baseExpr && arabic.baseExpr) {
2979
+ syncChainIds2(english.baseExpr, arabic.baseExpr);
2980
+ }
2981
+ }
2982
+ function buildLimitsSeriesTemplate(commandId) {
2983
+ if (!isLimitsSeriesTemplateId(commandId)) {
2984
+ throw new Error(`BuTeX: unsupported limits-series template id: ${commandId}`);
2985
+ }
2986
+ const englishOp = createAtomicCommandNode(commandId);
2987
+ const arabicOp = createAtomicCommandNode(commandId);
2988
+ arabicOp.id = englishOp.id;
2989
+ const englishOverset = createOversetNode();
2990
+ const arabicOverset = createOversetNode();
2991
+ syncOversetIds(englishOverset, arabicOverset);
2992
+ englishOverset.baseExpr = createEditorChain([englishOp]);
2993
+ arabicOverset.baseExpr = createEditorChain([arabicOp]);
2994
+ syncChainIds2(englishOverset.baseExpr, arabicOverset.baseExpr);
2995
+ const englishUnderset = createUndersetNode();
2996
+ const arabicUnderset = createUndersetNode();
2997
+ syncUndersetIds(englishUnderset, arabicUnderset);
2998
+ englishUnderset.baseExpr = createEditorChain([englishOverset]);
2999
+ arabicUnderset.baseExpr = createEditorChain([arabicOverset]);
3000
+ syncChainIds2(englishUnderset.baseExpr, arabicUnderset.baseExpr);
3001
+ return { english: englishUnderset, arabic: arabicUnderset };
3002
+ }
3003
+ function buildAccentPairTemplate() {
3004
+ const englishOverset = createOversetNode();
3005
+ const arabicOverset = createOversetNode();
3006
+ syncOversetIds(englishOverset, arabicOverset);
3007
+ const englishUnderset = createUndersetNode();
3008
+ const arabicUnderset = createUndersetNode();
3009
+ syncUndersetIds(englishUnderset, arabicUnderset);
3010
+ englishUnderset.baseExpr = createEditorChain([englishOverset]);
3011
+ arabicUnderset.baseExpr = createEditorChain([arabicOverset]);
3012
+ syncChainIds2(englishUnderset.baseExpr, arabicUnderset.baseExpr);
3013
+ return { english: englishUnderset, arabic: arabicUnderset };
3014
+ }
3015
+ function accentPairTemplateInitialCaret(englishUnderset) {
3016
+ const overset = englishUnderset.baseExpr?.nodes[0];
3017
+ return {
3018
+ chainId: overset?.baseExpr?.id ?? englishUnderset.underExpr?.id ?? "",
3019
+ index: 0
3020
+ };
3021
+ }
3022
+ function limitsSeriesTemplateInitialCaret(englishUnderset) {
3023
+ return {
3024
+ chainId: englishUnderset.underExpr?.id ?? englishUnderset.baseExpr?.id ?? "",
3025
+ index: 0
3026
+ };
3027
+ }
3028
+
2602
3029
  // src/editor/uiLocale.ts
2603
3030
  var ENGLISH_COMMAND_TITLES = {
2604
3031
  cos: "Cosine",
@@ -2642,6 +3069,24 @@ var ENGLISH_COMMAND_TITLES = {
2642
3069
  quadSpace: "Large space",
2643
3070
  qquadSpace: "Extra-large space"
2644
3071
  };
3072
+ var ENGLISH_ACCENT_TITLES = {
3073
+ vec: "Vector arrow",
3074
+ hat: "Hat",
3075
+ tilde: "Tilde",
3076
+ dot: "Dot",
3077
+ ddot: "Double dot",
3078
+ dddot: "Triple dot",
3079
+ bar: "Bar",
3080
+ check: "Check",
3081
+ breve: "Breve",
3082
+ acute: "Acute",
3083
+ grave: "Grave",
3084
+ overline: "Overline",
3085
+ underline: "Underline",
3086
+ overleftarrow: "Over left arrow",
3087
+ overrightarrow: "Over right arrow",
3088
+ overleftrightarrow: "Over left-right arrow"
3089
+ };
2645
3090
  var ENGLISH_OPERATOR_TITLES = {
2646
3091
  inf: "Infinity",
2647
3092
  times: "Multiplication",
@@ -2715,6 +3160,10 @@ var EQUATION_EDITOR_MESSAGES = {
2715
3160
  insertBraces: "\u0625\u062F\u0631\u0627\u062C \u062D\u0627\u0635\u0631\u062A\u064A\u0646",
2716
3161
  insertFraction: "\u0625\u062F\u0631\u0627\u062C \u0643\u0633\u0631",
2717
3162
  insertRoot: "\u0625\u062F\u0631\u0627\u062C \u062C\u0630\u0631",
3163
+ insertOverset: "\u0625\u062F\u0631\u0627\u062C \u0641\u0648\u0642",
3164
+ insertUnderset: "\u0625\u062F\u0631\u0627\u062C \u062A\u062D\u062A",
3165
+ insertAccentPair: "\u0625\u062F\u0631\u0627\u062C \u0641\u0648\u0642 \u0648\u062A\u062D\u062A",
3166
+ insertAccents: "\u0625\u062F\u0631\u0627\u062C \u0644\u0643\u0646\u0629",
2718
3167
  environments: "\u0627\u0644\u0628\u064A\u0626\u0627\u062A",
2719
3168
  insertEnvironment: "\u0625\u062F\u0631\u0627\u062C \u0628\u064A\u0626\u0629 \u0634\u0628\u0643\u064A\u0629",
2720
3169
  environmentType: "\u0646\u0648\u0639 \u0627\u0644\u0628\u064A\u0626\u0629",
@@ -2822,6 +3271,10 @@ var EQUATION_EDITOR_MESSAGES = {
2822
3271
  insertBraces: "Insert braces",
2823
3272
  insertFraction: "Insert fraction",
2824
3273
  insertRoot: "Insert root",
3274
+ insertOverset: "Insert overset",
3275
+ insertUnderset: "Insert underset",
3276
+ insertAccentPair: "Insert overset and underset",
3277
+ insertAccents: "Insert accent",
2825
3278
  environments: "Environments",
2826
3279
  insertEnvironment: "Insert grid environment",
2827
3280
  environmentType: "Environment type",
@@ -2922,6 +3375,9 @@ function atomicCommandTitle(spec, locale) {
2922
3375
  function atomicOperatorCommandTitle(spec, locale) {
2923
3376
  return locale === "en" ? ENGLISH_OPERATOR_TITLES[spec.id] ?? spec.title : spec.title;
2924
3377
  }
3378
+ function accentCommandTitle(spec, locale) {
3379
+ return locale === "en" ? ENGLISH_ACCENT_TITLES[spec.id] ?? spec.title : spec.title;
3380
+ }
2925
3381
 
2926
3382
  // src/editor/state.ts
2927
3383
  function ensureSyncEntry(session, nodeId) {
@@ -2956,7 +3412,7 @@ function syncSelectionToCaret(session) {
2956
3412
  session.selectedNodeId = located.relation.ownerNodeId;
2957
3413
  return;
2958
3414
  }
2959
- 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") {
3415
+ 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") {
2960
3416
  session.selectedNodeId = located.relation.ownerNodeId;
2961
3417
  return;
2962
3418
  }
@@ -3313,6 +3769,106 @@ function moveCaretVertical(session, direction) {
3313
3769
  appendDebug(next, "moveCaretVertical", "sqrt-radicand-down-exit");
3314
3770
  return next;
3315
3771
  }
3772
+ if (located.relation.kind === "overExpr" && ownerLocated && ownerNode && ownerNode.baseExpr) {
3773
+ if (direction === "down") {
3774
+ next.caret = {
3775
+ chainId: ownerNode.baseExpr.id,
3776
+ index: ownerNode.baseExpr.nodes.length
3777
+ };
3778
+ next.selectedStructureNodeId = null;
3779
+ syncSelectionToCaret(next);
3780
+ appendDebug(next, "moveCaretVertical", "overset-over->base");
3781
+ return next;
3782
+ }
3783
+ next.caret = {
3784
+ chainId: ownerLocated.chain.id,
3785
+ index: ownerLocated.index
3786
+ };
3787
+ next.selectedStructureNodeId = null;
3788
+ syncSelectionToCaret(next);
3789
+ appendDebug(next, "moveCaretVertical", "overset-over-up-exit");
3790
+ return next;
3791
+ }
3792
+ if (located.relation.kind === "baseExpr" && ownerLocated && ownerNode && ownerNode.kind === "overset" && ownerNode.overExpr) {
3793
+ if (direction === "up") {
3794
+ next.caret = {
3795
+ chainId: ownerNode.overExpr.id,
3796
+ index: ownerNode.overExpr.nodes.length
3797
+ };
3798
+ next.selectedStructureNodeId = null;
3799
+ syncSelectionToCaret(next);
3800
+ appendDebug(next, "moveCaretVertical", "overset-base->over");
3801
+ return next;
3802
+ }
3803
+ next.caret = {
3804
+ chainId: ownerLocated.chain.id,
3805
+ index: ownerLocated.index + 1
3806
+ };
3807
+ next.selectedStructureNodeId = null;
3808
+ syncSelectionToCaret(next);
3809
+ appendDebug(next, "moveCaretVertical", "overset-base-down-exit");
3810
+ return next;
3811
+ }
3812
+ if (located.relation.kind === "baseExpr" && ownerLocated && ownerNode && ownerNode.kind === "underset" && ownerNode.underExpr) {
3813
+ if (direction === "down") {
3814
+ next.caret = {
3815
+ chainId: ownerNode.underExpr.id,
3816
+ index: ownerNode.underExpr.nodes.length
3817
+ };
3818
+ next.selectedStructureNodeId = null;
3819
+ syncSelectionToCaret(next);
3820
+ appendDebug(next, "moveCaretVertical", "underset-base->under");
3821
+ return next;
3822
+ }
3823
+ next.caret = {
3824
+ chainId: ownerLocated.chain.id,
3825
+ index: ownerLocated.index
3826
+ };
3827
+ next.selectedStructureNodeId = null;
3828
+ syncSelectionToCaret(next);
3829
+ appendDebug(next, "moveCaretVertical", "underset-base-up-exit");
3830
+ return next;
3831
+ }
3832
+ if (located.relation.kind === "underExpr" && ownerLocated && ownerNode && ownerNode.baseExpr) {
3833
+ if (direction === "up") {
3834
+ next.caret = {
3835
+ chainId: ownerNode.baseExpr.id,
3836
+ index: ownerNode.baseExpr.nodes.length
3837
+ };
3838
+ next.selectedStructureNodeId = null;
3839
+ syncSelectionToCaret(next);
3840
+ appendDebug(next, "moveCaretVertical", "underset-under->base");
3841
+ return next;
3842
+ }
3843
+ next.caret = {
3844
+ chainId: ownerLocated.chain.id,
3845
+ index: ownerLocated.index + 1
3846
+ };
3847
+ next.selectedStructureNodeId = null;
3848
+ syncSelectionToCaret(next);
3849
+ appendDebug(next, "moveCaretVertical", "underset-under-down-exit");
3850
+ return next;
3851
+ }
3852
+ if (located.relation.kind === "baseExpr" && ownerLocated && ownerNode && ownerNode.kind === "accent") {
3853
+ if (direction === "up") {
3854
+ next.caret = {
3855
+ chainId: ownerLocated.chain.id,
3856
+ index: ownerLocated.index
3857
+ };
3858
+ next.selectedStructureNodeId = null;
3859
+ syncSelectionToCaret(next);
3860
+ appendDebug(next, "moveCaretVertical", "accent-base-up-exit");
3861
+ return next;
3862
+ }
3863
+ next.caret = {
3864
+ chainId: ownerLocated.chain.id,
3865
+ index: ownerLocated.index + 1
3866
+ };
3867
+ next.selectedStructureNodeId = null;
3868
+ syncSelectionToCaret(next);
3869
+ appendDebug(next, "moveCaretVertical", "accent-base-down-exit");
3870
+ return next;
3871
+ }
3316
3872
  if (located.relation.kind === "matrixCell" && ownerLocated && ownerNode?.matrixRows) {
3317
3873
  const rowIndex = located.relation.rowIndex ?? 0;
3318
3874
  const columnIndex = located.relation.columnIndex ?? 0;
@@ -3690,6 +4246,119 @@ function insertSqrt(session) {
3690
4246
  appendDebug(next, "insertSqrt", "");
3691
4247
  return next;
3692
4248
  }
4249
+ function insertOverset(session) {
4250
+ const base = replaceSelectionFirst(session);
4251
+ const next = cloneEditorSession(base);
4252
+ const englishNode = createOversetNode();
4253
+ const arabicNode = createOversetNode();
4254
+ arabicNode.id = englishNode.id;
4255
+ if (arabicNode.overExpr && englishNode.overExpr) {
4256
+ arabicNode.overExpr.id = englishNode.overExpr.id;
4257
+ }
4258
+ if (arabicNode.baseExpr && englishNode.baseExpr) {
4259
+ arabicNode.baseExpr.id = englishNode.baseExpr.id;
4260
+ }
4261
+ insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);
4262
+ next.caret = {
4263
+ chainId: englishNode.overExpr ? englishNode.overExpr.id : next.caret.chainId,
4264
+ index: 0
4265
+ };
4266
+ next.selectedStructureNodeId = null;
4267
+ syncSelectionToCaret(next);
4268
+ appendDebug(next, "insertOverset", "");
4269
+ return next;
4270
+ }
4271
+ function insertUnderset(session) {
4272
+ const base = replaceSelectionFirst(session);
4273
+ const next = cloneEditorSession(base);
4274
+ const englishNode = createUndersetNode();
4275
+ const arabicNode = createUndersetNode();
4276
+ arabicNode.id = englishNode.id;
4277
+ if (arabicNode.underExpr && englishNode.underExpr) {
4278
+ arabicNode.underExpr.id = englishNode.underExpr.id;
4279
+ }
4280
+ if (arabicNode.baseExpr && englishNode.baseExpr) {
4281
+ arabicNode.baseExpr.id = englishNode.baseExpr.id;
4282
+ }
4283
+ insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);
4284
+ next.caret = {
4285
+ chainId: englishNode.underExpr ? englishNode.underExpr.id : next.caret.chainId,
4286
+ index: 0
4287
+ };
4288
+ next.selectedStructureNodeId = null;
4289
+ syncSelectionToCaret(next);
4290
+ appendDebug(next, "insertUnderset", "");
4291
+ return next;
4292
+ }
4293
+ function insertLimitsSeriesTemplate(session, commandId) {
4294
+ const base = replaceSelectionFirst(session);
4295
+ const next = cloneEditorSession(base);
4296
+ const { english, arabic } = buildLimitsSeriesTemplate(commandId);
4297
+ insertMirroredNode(next, next.caret.chainId, next.caret.index, english, arabic);
4298
+ syncSubtreeRecursive(next, english, arabic);
4299
+ next.caret = limitsSeriesTemplateInitialCaret(english);
4300
+ next.selectedStructureNodeId = null;
4301
+ syncSelectionToCaret(next);
4302
+ appendDebug(next, "insertLimitsSeriesTemplate", commandId);
4303
+ return next;
4304
+ }
4305
+ function insertAccentPair(session) {
4306
+ const base = replaceSelectionFirst(session);
4307
+ const next = cloneEditorSession(base);
4308
+ const { english, arabic } = buildAccentPairTemplate();
4309
+ insertMirroredNode(next, next.caret.chainId, next.caret.index, english, arabic);
4310
+ syncSubtreeRecursive(next, english, arabic);
4311
+ next.caret = accentPairTemplateInitialCaret(english);
4312
+ next.selectedStructureNodeId = null;
4313
+ syncSelectionToCaret(next);
4314
+ appendDebug(next, "insertAccentPair", "");
4315
+ return next;
4316
+ }
4317
+ function insertAccent(session, accentId) {
4318
+ const next = cloneEditorSession(session);
4319
+ const englishNode = createAccentNode(accentId);
4320
+ const arabicNode = createAccentNode(accentId);
4321
+ arabicNode.id = englishNode.id;
4322
+ if (arabicNode.baseExpr && englishNode.baseExpr) {
4323
+ arabicNode.baseExpr.id = englishNode.baseExpr.id;
4324
+ }
4325
+ if (isSelectionActive(next.selection) && next.selection) {
4326
+ const sel = next.selection;
4327
+ const { start, end } = normalizeSelection(sel);
4328
+ const englishLocated = findChainById(next.englishTree, sel.chainId);
4329
+ const arabicLocated = findChainById(next.arabicTree, sel.chainId);
4330
+ if (englishLocated && arabicLocated && end > start) {
4331
+ const count = end - start;
4332
+ const englishWrapped = englishLocated.chain.nodes.splice(start, count);
4333
+ const arabicWrapped = arabicLocated.chain.nodes.splice(start, count);
4334
+ englishNode.baseExpr.nodes = englishWrapped;
4335
+ arabicNode.baseExpr.nodes = arabicWrapped;
4336
+ englishLocated.chain.nodes.splice(start, 0, englishNode);
4337
+ arabicLocated.chain.nodes.splice(start, 0, arabicNode);
4338
+ syncSubtreeRecursive(next, englishNode, arabicNode);
4339
+ next.caret = {
4340
+ chainId: englishNode.baseExpr.id,
4341
+ index: englishWrapped.length
4342
+ };
4343
+ next.selection = null;
4344
+ next.selectedStructureNodeId = null;
4345
+ syncSelectionToCaret(next);
4346
+ appendDebug(next, "insertAccent", `${accentId}:wrap`);
4347
+ return next;
4348
+ }
4349
+ }
4350
+ insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);
4351
+ syncSubtreeRecursive(next, englishNode, arabicNode);
4352
+ next.caret = {
4353
+ chainId: englishNode.baseExpr ? englishNode.baseExpr.id : next.caret.chainId,
4354
+ index: 0
4355
+ };
4356
+ next.selection = null;
4357
+ next.selectedStructureNodeId = null;
4358
+ syncSelectionToCaret(next);
4359
+ appendDebug(next, "insertAccent", `${accentId}:empty`);
4360
+ return next;
4361
+ }
3693
4362
  function insertMatrixEnv(session, style, rows, columns) {
3694
4363
  return insertGridEnv(session, style, rows, columns);
3695
4364
  }
@@ -3937,7 +4606,7 @@ function deleteBackward(session) {
3937
4606
  if (!previousNode) {
3938
4607
  return session;
3939
4608
  }
3940
- if ((previousNode.kind === "delimiter" || previousNode.kind === "frac" || previousNode.kind === "sqrt" || previousNode.kind === "env") && next.selectedStructureNodeId !== previousNode.id) {
4609
+ 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) {
3941
4610
  next.selectedStructureNodeId = previousNode.id;
3942
4611
  next.selectedNodeId = previousNode.id;
3943
4612
  appendDebug(next, "deleteBackward", "selected structure");
@@ -4427,6 +5096,168 @@ function buildSqrtNodeBody(node, buildChain, side) {
4427
5096
  return wrap;
4428
5097
  }
4429
5098
 
5099
+ // src/editor/display/overset.ts
5100
+ var OVERSET_CSS = `
5101
+ .overset {
5102
+ display: inline-flex;
5103
+ flex-direction: column;
5104
+ align-items: center;
5105
+ justify-content: center;
5106
+ vertical-align: middle;
5107
+ margin: 0 2px;
5108
+ min-width: 1.2em;
5109
+ }
5110
+
5111
+ .overset-over {
5112
+ display: inline-flex;
5113
+ justify-content: center;
5114
+ align-items: center;
5115
+ min-height: 0.85em;
5116
+ padding: 0 2px;
5117
+ font-size: 0.72em;
5118
+ line-height: 1.1;
5119
+ }
5120
+
5121
+ .overset-base {
5122
+ display: inline-flex;
5123
+ justify-content: center;
5124
+ align-items: center;
5125
+ min-height: 1.05em;
5126
+ padding: 0 2px;
5127
+ }
5128
+ `.trim();
5129
+ function buildOversetNodeBody(node, buildChain) {
5130
+ const wrap = document.createElement("span");
5131
+ wrap.className = "overset";
5132
+ const over = document.createElement("span");
5133
+ over.className = "overset-over";
5134
+ if (node.overExpr) {
5135
+ over.appendChild(buildChain(node.overExpr));
5136
+ }
5137
+ const base = document.createElement("span");
5138
+ base.className = "overset-base";
5139
+ if (node.baseExpr) {
5140
+ base.appendChild(buildChain(node.baseExpr));
5141
+ }
5142
+ wrap.appendChild(over);
5143
+ wrap.appendChild(base);
5144
+ return wrap;
5145
+ }
5146
+
5147
+ // src/editor/display/underset.ts
5148
+ var UNDERSET_CSS = `
5149
+ .underset {
5150
+ display: inline-flex;
5151
+ flex-direction: column;
5152
+ align-items: center;
5153
+ justify-content: center;
5154
+ vertical-align: middle;
5155
+ margin: 0 2px;
5156
+ min-width: 1.2em;
5157
+ }
5158
+
5159
+ .underset-base {
5160
+ display: inline-flex;
5161
+ justify-content: center;
5162
+ align-items: center;
5163
+ min-height: 1.05em;
5164
+ padding: 0 2px;
5165
+ }
5166
+
5167
+ .underset-under {
5168
+ display: inline-flex;
5169
+ justify-content: center;
5170
+ align-items: center;
5171
+ min-height: 0.85em;
5172
+ padding: 0 2px;
5173
+ font-size: 0.72em;
5174
+ line-height: 1.1;
5175
+ }
5176
+ `.trim();
5177
+ function buildUndersetNodeBody(node, buildChain) {
5178
+ const wrap = document.createElement("span");
5179
+ wrap.className = "underset";
5180
+ const base = document.createElement("span");
5181
+ base.className = "underset-base";
5182
+ if (node.baseExpr) {
5183
+ base.appendChild(buildChain(node.baseExpr));
5184
+ }
5185
+ const under = document.createElement("span");
5186
+ under.className = "underset-under";
5187
+ if (node.underExpr) {
5188
+ under.appendChild(buildChain(node.underExpr));
5189
+ }
5190
+ wrap.appendChild(base);
5191
+ wrap.appendChild(under);
5192
+ return wrap;
5193
+ }
5194
+
5195
+ // src/editor/display/accent.ts
5196
+ var ACCENT_CSS = `
5197
+ .math-accent {
5198
+ display: inline-flex;
5199
+ flex-direction: column;
5200
+ align-items: center;
5201
+ justify-content: center;
5202
+ vertical-align: middle;
5203
+ margin: 0 2px;
5204
+ min-width: 1.1em;
5205
+ }
5206
+
5207
+ .math-accent-chrome {
5208
+ display: inline-flex;
5209
+ justify-content: center;
5210
+ align-items: center;
5211
+ min-height: 0.7em;
5212
+ padding: 0 2px;
5213
+ font-size: 0.85em;
5214
+ line-height: 1;
5215
+ color: var(--butex-script-color, #475569);
5216
+ user-select: none;
5217
+ }
5218
+
5219
+ .math-accent-base {
5220
+ display: inline-flex;
5221
+ justify-content: center;
5222
+ align-items: center;
5223
+ min-height: 1.05em;
5224
+ padding: 0 2px;
5225
+ }
5226
+
5227
+ .math-accent--under .math-accent-chrome {
5228
+ min-height: 0.45em;
5229
+ border-top: 1.5px solid currentColor;
5230
+ width: 100%;
5231
+ font-size: 0;
5232
+ color: var(--butex-surface-fg, #0f172a);
5233
+ }
5234
+ `.trim();
5235
+ function buildAccentNodeBody(node, buildChain) {
5236
+ const wrap = document.createElement("span");
5237
+ const spec = accentCommandSpec(node.expr);
5238
+ const placement = spec?.placement ?? "over";
5239
+ wrap.className = placement === "under" ? "math-accent math-accent--under" : "math-accent math-accent--over";
5240
+ const chrome = document.createElement("span");
5241
+ chrome.className = "math-accent-chrome";
5242
+ chrome.setAttribute("aria-hidden", "true");
5243
+ if (placement === "over") {
5244
+ chrome.textContent = spec?.label ?? "\u02C6";
5245
+ }
5246
+ const base = document.createElement("span");
5247
+ base.className = "math-accent-base";
5248
+ if (node.baseExpr) {
5249
+ base.appendChild(buildChain(node.baseExpr));
5250
+ }
5251
+ if (placement === "under") {
5252
+ wrap.appendChild(base);
5253
+ wrap.appendChild(chrome);
5254
+ } else {
5255
+ wrap.appendChild(chrome);
5256
+ wrap.appendChild(base);
5257
+ }
5258
+ return wrap;
5259
+ }
5260
+
4430
5261
  // src/editor/display/env.ts
4431
5262
  var WRAPPERS = {
4432
5263
  matrix: { left: "", right: "" },
@@ -4799,6 +5630,15 @@ function buildNodeBody(node, buildChain, side, digitForm = "western", uiLocale =
4799
5630
  if (node.kind === "sqrt") {
4800
5631
  return buildSqrtNodeBody(node, buildChain, side);
4801
5632
  }
5633
+ if (node.kind === "overset") {
5634
+ return buildOversetNodeBody(node, buildChain);
5635
+ }
5636
+ if (node.kind === "underset") {
5637
+ return buildUndersetNodeBody(node, buildChain);
5638
+ }
5639
+ if (node.kind === "accent") {
5640
+ return buildAccentNodeBody(node, buildChain);
5641
+ }
4802
5642
  if (node.kind === "env") {
4803
5643
  return buildMatrixEnvNodeBody(node, buildChain, side);
4804
5644
  }
@@ -4998,6 +5838,12 @@ ${FRAC_CSS}
4998
5838
 
4999
5839
  ${SQRT_CSS}
5000
5840
 
5841
+ ${OVERSET_CSS}
5842
+
5843
+ ${UNDERSET_CSS}
5844
+
5845
+ ${ACCENT_CSS}
5846
+
5001
5847
  ${MATRIX_ENV_CSS}
5002
5848
 
5003
5849
  ${ATOMIC_COMMAND_CSS}
@@ -5717,6 +6563,26 @@ function createEditorRuntime(options) {
5717
6563
  applyStructural((prev) => insertSqrt(prev));
5718
6564
  surfaceEl.focus();
5719
6565
  },
6566
+ insertOverset: () => {
6567
+ applyStructural((prev) => insertOverset(prev));
6568
+ surfaceEl.focus();
6569
+ },
6570
+ insertUnderset: () => {
6571
+ applyStructural((prev) => insertUnderset(prev));
6572
+ surfaceEl.focus();
6573
+ },
6574
+ insertLimitsSeriesTemplate: (commandId) => {
6575
+ applyStructural((prev) => insertLimitsSeriesTemplate(prev, commandId));
6576
+ surfaceEl.focus();
6577
+ },
6578
+ insertAccentPair: () => {
6579
+ applyStructural((prev) => insertAccentPair(prev));
6580
+ surfaceEl.focus();
6581
+ },
6582
+ insertAccent: (accentId) => {
6583
+ applyStructural((prev) => insertAccent(prev, accentId));
6584
+ surfaceEl.focus();
6585
+ },
5720
6586
  insertAtomicCommand: (commandId) => {
5721
6587
  applyStructural((prev) => insertAtomicCommand(prev, commandId));
5722
6588
  surfaceEl.focus();
@@ -6043,6 +6909,56 @@ function commandToEditorNode(node) {
6043
6909
  }
6044
6910
  return { editable: true, node: sqrt };
6045
6911
  }
6912
+ if (node.name === "\\overset" && node.mandatoryArgs.length >= 2) {
6913
+ const overset = createOversetNode();
6914
+ const overExpr = chainToEditorChain(node.mandatoryArgs[0]);
6915
+ const baseExpr = chainToEditorChain(node.mandatoryArgs[1]);
6916
+ if (!overExpr.editable) {
6917
+ return overExpr;
6918
+ }
6919
+ if (!baseExpr.editable) {
6920
+ return baseExpr;
6921
+ }
6922
+ overset.overExpr = overExpr.chain;
6923
+ overset.baseExpr = baseExpr.chain;
6924
+ const scripts = attachScripts(node, overset);
6925
+ if (scripts) {
6926
+ return scripts;
6927
+ }
6928
+ return { editable: true, node: overset };
6929
+ }
6930
+ if (node.name === "\\underset" && node.mandatoryArgs.length >= 2) {
6931
+ const underset = createUndersetNode();
6932
+ const underExpr = chainToEditorChain(node.mandatoryArgs[0]);
6933
+ const baseExpr = chainToEditorChain(node.mandatoryArgs[1]);
6934
+ if (!underExpr.editable) {
6935
+ return underExpr;
6936
+ }
6937
+ if (!baseExpr.editable) {
6938
+ return baseExpr;
6939
+ }
6940
+ underset.underExpr = underExpr.chain;
6941
+ underset.baseExpr = baseExpr.chain;
6942
+ const scripts = attachScripts(node, underset);
6943
+ if (scripts) {
6944
+ return scripts;
6945
+ }
6946
+ return { editable: true, node: underset };
6947
+ }
6948
+ const accentId = accentCommandIdFromTex(node.name);
6949
+ if (accentId && node.mandatoryArgs.length >= 1) {
6950
+ const accent = createAccentNode(accentId);
6951
+ const baseExpr = chainToEditorChain(node.mandatoryArgs[0]);
6952
+ if (!baseExpr.editable) {
6953
+ return baseExpr;
6954
+ }
6955
+ accent.baseExpr = baseExpr.chain;
6956
+ const scripts = attachScripts(node, accent);
6957
+ if (scripts) {
6958
+ return scripts;
6959
+ }
6960
+ return { editable: true, node: accent };
6961
+ }
6046
6962
  const atomicId = commandIdForTex(node.name);
6047
6963
  if (atomicId && node.optionalArgs.length === 0 && node.mandatoryArgs.length === 0) {
6048
6964
  const atomic = createEditorNode("atomicCommand", atomicId);
@@ -6179,6 +7095,21 @@ function editorEnvToAstNode(node) {
6179
7095
  const scripts = attachAstScripts(node, env);
6180
7096
  return scripts ?? { ok: true, node: env };
6181
7097
  }
7098
+ function accentChainForExport(accent) {
7099
+ if (!accent) {
7100
+ return { ok: true, chain: new ChainNode([]) };
7101
+ }
7102
+ return editorChainToAstChain(accent);
7103
+ }
7104
+ function nodeFromAccentBase(command, accent, base) {
7105
+ if (accent.chain.length > 0) {
7106
+ return new CommandNode(command, [], [accent, base]);
7107
+ }
7108
+ if (base.chain.length === 1) {
7109
+ return base.chain[0];
7110
+ }
7111
+ return new DelimiterNode("", base, "");
7112
+ }
6182
7113
  function editorNodeToAstNode(node) {
6183
7114
  let astNode;
6184
7115
  if (node.kind === "char") {
@@ -6217,6 +7148,36 @@ function editorNodeToAstNode(node) {
6217
7148
  optionalArgs.push(rootIndex.chain);
6218
7149
  }
6219
7150
  astNode = new CommandNode("\\sqrt", optionalArgs, [radicand.chain]);
7151
+ } else if (node.kind === "overset" && node.baseExpr) {
7152
+ const accent = accentChainForExport(node.overExpr);
7153
+ if (!accent.ok) {
7154
+ return accent;
7155
+ }
7156
+ const baseExpr = editorChainToAstChain(node.baseExpr);
7157
+ if (!baseExpr.ok) {
7158
+ return baseExpr;
7159
+ }
7160
+ astNode = nodeFromAccentBase("\\overset", accent.chain, baseExpr.chain);
7161
+ } else if (node.kind === "underset" && node.baseExpr) {
7162
+ const accent = accentChainForExport(node.underExpr);
7163
+ if (!accent.ok) {
7164
+ return accent;
7165
+ }
7166
+ const baseExpr = editorChainToAstChain(node.baseExpr);
7167
+ if (!baseExpr.ok) {
7168
+ return baseExpr;
7169
+ }
7170
+ astNode = nodeFromAccentBase("\\underset", accent.chain, baseExpr.chain);
7171
+ } else if (node.kind === "accent" && node.baseExpr) {
7172
+ const tex = accentCommandSpec(node.expr)?.englishTex;
7173
+ if (!tex) {
7174
+ 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}` };
7175
+ }
7176
+ const baseExpr = editorChainToAstChain(node.baseExpr);
7177
+ if (!baseExpr.ok) {
7178
+ return baseExpr;
7179
+ }
7180
+ astNode = new CommandNode(tex, [], [baseExpr.chain]);
6220
7181
  } else if (node.kind === "atomicCommand") {
6221
7182
  const tex = atomicCommandSpec(node.expr)?.englishTex;
6222
7183
  if (!tex) {
@@ -6738,7 +7699,10 @@ function documentInlineText(inlines) {
6738
7699
  // src/mathjax/svgPatcher.ts
6739
7700
  var SVG_ARABSQRT_SELECTOR = 'mjx-container[jax="SVG"] svg .mjx-rtl-mirror[data-mjx-rtl-root="true"]';
6740
7701
  var ARABSQRT_SELECTOR = '.mjx-rtl-mirror[data-mjx-rtl-root="true"]';
7702
+ var SVG_PREVIEW_MIRROR_SELECTOR = 'mjx-container[jax="SVG"] svg .butex-preview-mirror';
7703
+ var PREVIEW_MIRROR_SELECTOR = ".butex-preview-mirror";
6741
7704
  var PATCHED_ATTR = "data-butex-svg-arabsqrt";
7705
+ var MIRROR_PATCHED_ATTR = "data-butex-svg-mirror";
6742
7706
  var ROOT_INDEX_SCALE = 0.72;
6743
7707
  var ROOT_INDEX_GAP_FACTOR = 0.08;
6744
7708
  var ROOT_INDEX_MIN_GAP = 2;
@@ -6763,11 +7727,12 @@ function directSvgElementChildren(element) {
6763
7727
  return Array.from(element.children).filter((child) => child instanceof SVGElement);
6764
7728
  }
6765
7729
  function boxFor(element) {
6766
- if (!(element instanceof SVGGraphicsElement) || typeof element.getBBox !== "function") {
7730
+ const candidate = element;
7731
+ if (typeof candidate.getBBox !== "function") {
6767
7732
  return null;
6768
7733
  }
6769
7734
  try {
6770
- const box = element.getBBox();
7735
+ const box = candidate.getBBox();
6771
7736
  return {
6772
7737
  x: box.x,
6773
7738
  y: box.y,
@@ -7011,6 +7976,31 @@ function patchArabSqrtRoot(root) {
7011
7976
  root.setAttribute(PATCHED_ATTR, "patched");
7012
7977
  rootNode.setAttribute(PATCHED_ATTR, "patched");
7013
7978
  }
7979
+ function patchPreviewMirror(element) {
7980
+ if (element.getAttribute(MIRROR_PATCHED_ATTR) === "patched") {
7981
+ return;
7982
+ }
7983
+ const box = boxFor(element);
7984
+ if (!box || box.width <= 0) {
7985
+ return;
7986
+ }
7987
+ const [tx, ty] = readTranslate(element);
7988
+ const mirrorX = tx + 2 * box.x + box.width;
7989
+ element.setAttribute(
7990
+ "transform",
7991
+ `translate(${roundSvg(mirrorX)},${roundSvg(ty)}) scale(-1,1)`
7992
+ );
7993
+ element.setAttribute(MIRROR_PATCHED_ATTR, "patched");
7994
+ }
7995
+ function collectPreviewMirrors(root) {
7996
+ let mirrors = Array.from(root.querySelectorAll(SVG_PREVIEW_MIRROR_SELECTOR));
7997
+ if (!mirrors.length) {
7998
+ mirrors = Array.from(root.querySelectorAll(PREVIEW_MIRROR_SELECTOR)).filter((candidate) => {
7999
+ return candidate.closest('mjx-container[jax="SVG"]') != null;
8000
+ });
8001
+ }
8002
+ return mirrors;
8003
+ }
7014
8004
  function patchBuTeXSvgMath(root) {
7015
8005
  if (typeof root.querySelectorAll !== "function") {
7016
8006
  return;
@@ -7022,6 +8012,7 @@ function patchBuTeXSvgMath(root) {
7022
8012
  });
7023
8013
  }
7024
8014
  roots.sort((a, b) => rootDepth(b) - rootDepth(a)).forEach((arabSqrtRoot) => patchArabSqrtRoot(arabSqrtRoot));
8015
+ collectPreviewMirrors(root).forEach((mirror) => patchPreviewMirror(mirror));
7025
8016
  }
7026
8017
 
7027
8018
  // src/mathjax/renderIsland.ts
@@ -7316,6 +8307,29 @@ var WIDGET_CHROME_CSS = `
7316
8307
  padding-top: 1px;
7317
8308
  }
7318
8309
 
8310
+ .butex-widget .toolbar-accent-icon {
8311
+ display: inline-flex;
8312
+ flex-direction: column;
8313
+ align-items: center;
8314
+ justify-content: center;
8315
+ min-width: 14px;
8316
+ font-size: 10px;
8317
+ line-height: 1;
8318
+ gap: 1px;
8319
+ }
8320
+
8321
+ .butex-widget .toolbar-accent-icon--over span:first-child,
8322
+ .butex-widget .toolbar-accent-icon--under span:last-child {
8323
+ font-size: 8px;
8324
+ opacity: 0.85;
8325
+ }
8326
+
8327
+ .butex-widget .toolbar-accent-icon--pair span:first-child,
8328
+ .butex-widget .toolbar-accent-icon--pair span:last-child {
8329
+ font-size: 8px;
8330
+ opacity: 0.85;
8331
+ }
8332
+
7319
8333
  .butex-widget .matrix-command-menu {
7320
8334
  position: relative;
7321
8335
  display: inline-flex;
@@ -8057,6 +9071,7 @@ var CHARACTER_FONT_OPTIONS = [
8057
9071
  { id: "diwani", label: "\u062F\u064A\u0648" },
8058
9072
  { id: "diwaniOutline", label: "\u0638\u0644" }
8059
9073
  ];
9074
+ var ACCENT_COMMANDS_LIST = accentCommandsList();
8060
9075
  var FUNCTION_COMMANDS = atomicCommandsByCategory("function");
8061
9076
  var LIMITS_SERIES_COMMANDS = atomicCommandsByCategory("limits_series");
8062
9077
  var FUNCTION2_COMMANDS = atomicCommandsByCategory("function2");
@@ -8204,6 +9219,7 @@ var ButexEditor = forwardRef(
8204
9219
  const [operator2MenuOpen, setOperator2MenuOpen] = useState(false);
8205
9220
  const [operator3MenuOpen, setOperator3MenuOpen] = useState(false);
8206
9221
  const [dotMenuOpen, setDotMenuOpen] = useState(false);
9222
+ const [accentMenuOpen, setAccentMenuOpen] = useState(false);
8207
9223
  const [integralMenuOpen, setIntegralMenuOpen] = useState(false);
8208
9224
  const [selectedDigitForm2, setSelectedDigitForm] = useState("western");
8209
9225
  const [selectedCharacterFont, setSelectedCharacterFont] = useState("default");
@@ -8473,7 +9489,78 @@ ${arabic || currentMessages.empty}`;
8473
9489
  /* @__PURE__ */ jsx("button", { id: "insert-sqrt", className: "icon-btn", type: "button", title: messages.insertRoot, "aria-label": messages.insertRoot, onClick: () => {
8474
9490
  runtimeRef.current?.insertSqrt();
8475
9491
  focusSurface();
8476
- }, children: /* @__PURE__ */ jsx("span", { className: "toolbar-sqrt-icon", "aria-hidden": "true", children: "\u221A" }) })
9492
+ }, children: /* @__PURE__ */ jsx("span", { className: "toolbar-sqrt-icon", "aria-hidden": "true", children: "\u221A" }) }),
9493
+ /* @__PURE__ */ jsx("button", { id: "insert-overset", className: "icon-btn", type: "button", title: messages.insertOverset, "aria-label": messages.insertOverset, onClick: () => {
9494
+ runtimeRef.current?.insertOverset();
9495
+ focusSurface();
9496
+ }, children: /* @__PURE__ */ jsxs("span", { className: "toolbar-accent-icon toolbar-accent-icon--over", "aria-hidden": "true", children: [
9497
+ /* @__PURE__ */ jsx("span", { children: "\u2217" }),
9498
+ /* @__PURE__ */ jsx("span", { children: "\u25A1" })
9499
+ ] }) }),
9500
+ /* @__PURE__ */ jsx("button", { id: "insert-underset", className: "icon-btn", type: "button", title: messages.insertUnderset, "aria-label": messages.insertUnderset, onClick: () => {
9501
+ runtimeRef.current?.insertUnderset();
9502
+ focusSurface();
9503
+ }, children: /* @__PURE__ */ jsxs("span", { className: "toolbar-accent-icon toolbar-accent-icon--under", "aria-hidden": "true", children: [
9504
+ /* @__PURE__ */ jsx("span", { children: "\u25A1" }),
9505
+ /* @__PURE__ */ jsx("span", { children: "\u2217" })
9506
+ ] }) }),
9507
+ /* @__PURE__ */ jsx("button", { id: "insert-accent-pair", className: "icon-btn", type: "button", title: messages.insertAccentPair, "aria-label": messages.insertAccentPair, onClick: () => {
9508
+ runtimeRef.current?.insertAccentPair();
9509
+ focusSurface();
9510
+ }, children: /* @__PURE__ */ jsxs("span", { className: "toolbar-accent-icon toolbar-accent-icon--pair", "aria-hidden": "true", children: [
9511
+ /* @__PURE__ */ jsx("span", { children: "\u2217" }),
9512
+ /* @__PURE__ */ jsx("span", { children: "\u25A1" }),
9513
+ /* @__PURE__ */ jsx("span", { children: "\u2217" })
9514
+ ] }) }),
9515
+ /* @__PURE__ */ jsxs(
9516
+ "div",
9517
+ {
9518
+ className: "function-command-menu operator-command-menu",
9519
+ onBlur: (event) => {
9520
+ const nextFocus = event.relatedTarget;
9521
+ if (!(nextFocus instanceof Node) || !event.currentTarget.contains(nextFocus)) {
9522
+ setAccentMenuOpen(false);
9523
+ }
9524
+ },
9525
+ children: [
9526
+ /* @__PURE__ */ jsx(
9527
+ "button",
9528
+ {
9529
+ id: "insert-accents",
9530
+ className: "icon-btn function-command-btn operator-command-btn",
9531
+ type: "button",
9532
+ title: messages.insertAccents,
9533
+ "aria-label": messages.insertAccents,
9534
+ "aria-haspopup": "listbox",
9535
+ "aria-expanded": accentMenuOpen,
9536
+ onClick: () => setAccentMenuOpen((open) => !open),
9537
+ children: /* @__PURE__ */ jsxs("span", { className: "toolbar-accent-icon toolbar-accent-icon--over", "aria-hidden": "true", children: [
9538
+ /* @__PURE__ */ jsx("span", { children: "\u02C6" }),
9539
+ /* @__PURE__ */ jsx("span", { children: "\u25A1" })
9540
+ ] })
9541
+ }
9542
+ ),
9543
+ /* @__PURE__ */ jsx("div", { className: "function-command-options operator-command-options", role: "listbox", "aria-label": messages.insertAccents, hidden: !accentMenuOpen, children: ACCENT_COMMANDS_LIST.map((command) => /* @__PURE__ */ jsx(
9544
+ "button",
9545
+ {
9546
+ className: "function-command-option operator-command-option",
9547
+ type: "button",
9548
+ role: "option",
9549
+ title: accentCommandTitle(command, uiLocale),
9550
+ "aria-label": accentCommandTitle(command, uiLocale),
9551
+ onMouseDown: (event) => event.preventDefault(),
9552
+ onClick: () => {
9553
+ runtimeRef.current?.insertAccent(command.id);
9554
+ setAccentMenuOpen(false);
9555
+ focusSurface();
9556
+ },
9557
+ children: /* @__PURE__ */ jsx("span", { className: "operator-command-label", children: command.label })
9558
+ },
9559
+ command.id
9560
+ )) })
9561
+ ]
9562
+ }
9563
+ )
8477
9564
  ] }),
8478
9565
  /* @__PURE__ */ jsx("div", { className: "toolbar-group toolbar-environments", role: "group", "aria-label": messages.environments, children: /* @__PURE__ */ jsxs(
8479
9566
  "div",
@@ -8801,7 +9888,7 @@ ${arabic || currentMessages.empty}`;
8801
9888
  "aria-label": atomicCommandTitle(command, uiLocale),
8802
9889
  onMouseDown: (event) => event.preventDefault(),
8803
9890
  onClick: () => {
8804
- runtimeRef.current?.insertAtomicCommand(command.id);
9891
+ runtimeRef.current?.insertLimitsSeriesTemplate(command.id);
8805
9892
  setLimitsSeriesMenuOpen(false);
8806
9893
  focusSurface();
8807
9894
  },