@formulaxjs/kity-runtime 0.3.0 → 0.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.
@@ -5072,6 +5072,22 @@ var FormulaX = (() => {
5072
5072
  }
5073
5073
  });
5074
5074
 
5075
+ // src/i18n.ts
5076
+ function normalizeFormulaXLocale(locale) {
5077
+ if (locale === "zh_CN") {
5078
+ return "zh_CN";
5079
+ }
5080
+ return DEFAULT_FORMULAX_LOCALE;
5081
+ }
5082
+ var FORMULAX_LOCALES, DEFAULT_FORMULAX_LOCALE;
5083
+ var init_i18n = __esm({
5084
+ "src/i18n.ts"() {
5085
+ "use strict";
5086
+ FORMULAX_LOCALES = ["en_US", "zh_CN"];
5087
+ DEFAULT_FORMULAX_LOCALE = "en_US";
5088
+ }
5089
+ });
5090
+
5075
5091
  // src/vendor/kity-formula/binary-expression.ts
5076
5092
  var BinaryExpressionModule, createBinaryExpressionClass;
5077
5093
  var init_binary_expression = __esm({
@@ -5936,15 +5952,13 @@ var FormulaX = (() => {
5936
5952
  });
5937
5953
 
5938
5954
  // src/vendor/kity-formula/font-installer.ts
5939
- var MAIN_FONT_FAMILY, FontInstallerModule, createFontInstallerClass;
5955
+ var FontInstallerModule, createFontInstallerClass;
5940
5956
  var init_font_installer = __esm({
5941
5957
  "src/vendor/kity-formula/font-installer.ts"() {
5942
5958
  "use strict";
5943
- MAIN_FONT_FAMILY = "KF AMS MAIN";
5944
5959
  FontInstallerModule = class {
5945
5960
  static create(kity26, FontManager, fontConfig, checkerTemplate) {
5946
5961
  let nodeList = [];
5947
- let checkerNode = null;
5948
5962
  return kity26.createClass("FontInstaller", {
5949
5963
  constructor: function(doc, resource) {
5950
5964
  const normalized = typeof resource === "string" ? { path: resource } : resource ?? {};
@@ -5954,26 +5968,22 @@ var FormulaX = (() => {
5954
5968
  },
5955
5969
  mount: function(callback) {
5956
5970
  const fontList = FontManager.getFontList();
5971
+ let count = 0;
5957
5972
  kity26.Utils.each(fontList, (fontInfo) => {
5973
+ count += 1;
5958
5974
  fontInfo.meta.src = resolveFontSource(this.fonts, this.resource, fontInfo.meta.src);
5959
5975
  this.createFontStyle(fontInfo);
5960
- if (fontInfo.meta.fontFamily === MAIN_FONT_FAMILY) {
5961
- checkerNode = createFontCheckerNode(this.doc);
5962
- return;
5963
- }
5964
5976
  applyFonts(this.doc, fontInfo);
5977
+ count -= 1;
5978
+ if (count === 0) {
5979
+ complete(this.doc, callback);
5980
+ }
5965
5981
  });
5966
- complete(this.doc, callback);
5967
5982
  },
5968
5983
  createFontStyle: function(fontInfo) {
5969
- const styleId = createFontStyleId(fontInfo);
5970
- if (this.doc.getElementById(styleId)) {
5971
- return;
5972
- }
5973
5984
  const stylesheet = this.doc.createElement("style");
5974
5985
  const tpl = '@font-face{\nfont-family: "${fontFamily}";\nsrc: url("${src}");\n}';
5975
5986
  stylesheet.setAttribute("type", "text/css");
5976
- stylesheet.id = styleId;
5977
5987
  stylesheet.innerHTML = tpl.replace("${fontFamily}", fontInfo.meta.fontFamily).replace("${src}", fontInfo.meta.src);
5978
5988
  this.doc.head.appendChild(stylesheet);
5979
5989
  }
@@ -5990,29 +6000,34 @@ var FormulaX = (() => {
5990
6000
  }
5991
6001
  return resourceBase + originalSrc;
5992
6002
  }
5993
- function createFontStyleId(fontInfo) {
5994
- const raw = `${fontInfo.meta.fontFamily}::${fontInfo.meta.src}`;
5995
- let hash = 0;
5996
- for (let index = 0; index < raw.length; index += 1) {
5997
- hash = (hash << 5) - hash + raw.charCodeAt(index) | 0;
5998
- }
5999
- return `formulax-kity-font-${Math.abs(hash).toString(36)}`;
6000
- }
6001
- function waitForFontsReady(doc) {
6003
+ function waitForFontsReady(doc, fontList) {
6002
6004
  const view = doc.defaultView ?? window;
6003
6005
  if (view.document.fonts) {
6004
- return view.document.fonts.ready.then(() => void 0);
6006
+ const fontLoadPromises = fontList.map((fontInfo) => {
6007
+ return view.document.fonts.load(`50px "${fontInfo.meta.fontFamily}"`);
6008
+ });
6009
+ return Promise.all(fontLoadPromises).then(() => view.document.fonts.ready).then(() => {
6010
+ return new Promise((resolve) => {
6011
+ requestAnimationFrame(() => {
6012
+ requestAnimationFrame(() => {
6013
+ resolve();
6014
+ });
6015
+ });
6016
+ });
6017
+ });
6005
6018
  }
6006
6019
  return Promise.resolve();
6007
6020
  }
6008
6021
  function complete(doc, callback) {
6009
6022
  const view = doc.defaultView ?? window;
6010
- waitForFontsReady(doc).then(() => {
6011
- return waitForNextFrames(view, 2);
6012
- }).then(() => {
6013
- initFontSystemInfo(doc);
6014
- removeTmpNode();
6015
- callback();
6023
+ const fontList = FontManager.getFontList();
6024
+ const fontArray = Object.values(fontList);
6025
+ waitForFontsReady(doc, fontArray).then(() => {
6026
+ view.setTimeout(() => {
6027
+ initFontSystemInfo(doc);
6028
+ removeTmpNode();
6029
+ callback();
6030
+ }, 100);
6016
6031
  }).catch(() => {
6017
6032
  view.setTimeout(() => {
6018
6033
  initFontSystemInfo(doc);
@@ -6033,37 +6048,12 @@ var FormulaX = (() => {
6033
6048
  doc.body.appendChild(node);
6034
6049
  nodeList.push(node);
6035
6050
  }
6036
- function createFontCheckerNode(doc) {
6037
- if (checkerNode) {
6038
- return checkerNode;
6039
- }
6040
- const node = doc.createElement("div");
6041
- node.style.cssText = "position: absolute; top: 0; left: -100000px;";
6042
- node.innerHTML = checkerTemplate.join("");
6043
- doc.body.appendChild(node);
6044
- checkerNode = node;
6045
- return node;
6046
- }
6047
- function waitForNextFrames(view, frameCount) {
6048
- if (typeof view.requestAnimationFrame !== "function") {
6049
- return Promise.resolve();
6050
- }
6051
- return new Promise((resolve) => {
6052
- const step = (remaining) => {
6053
- if (remaining <= 0) {
6054
- resolve();
6055
- return;
6056
- }
6057
- view.requestAnimationFrame(() => {
6058
- step(remaining - 1);
6059
- });
6060
- };
6061
- step(frameCount);
6062
- });
6063
- }
6064
6051
  function initFontSystemInfo(doc) {
6065
- const activeCheckerNode = checkerNode ?? createFontCheckerNode(doc);
6066
- const rectBox = activeCheckerNode.getElementsByTagName("text")[0].getBBox();
6052
+ const tmpNode = doc.createElement("div");
6053
+ tmpNode.style.cssText = "position: absolute; top: 0; left: -100000px;";
6054
+ tmpNode.innerHTML = checkerTemplate.join("");
6055
+ doc.body.appendChild(tmpNode);
6056
+ const rectBox = tmpNode.getElementsByTagName("text")[0].getBBox();
6067
6057
  fontConfig.spaceHeight = rectBox.height;
6068
6058
  fontConfig.topSpace = -rectBox.y - fontConfig.baseline;
6069
6059
  fontConfig.bottomSpace = fontConfig.spaceHeight - fontConfig.topSpace - fontConfig.baseHeight;
@@ -6072,8 +6062,7 @@ var FormulaX = (() => {
6072
6062
  fontConfig.meanlinePosition = (fontConfig.topSpace + fontConfig.meanline) / fontConfig.spaceHeight;
6073
6063
  fontConfig.ascenderPosition = fontConfig.topSpace / fontConfig.spaceHeight;
6074
6064
  fontConfig.descenderPosition = (fontConfig.topSpace + fontConfig.baseHeight) / fontConfig.spaceHeight;
6075
- activeCheckerNode.parentNode?.removeChild(activeCheckerNode);
6076
- checkerNode = null;
6065
+ doc.body.removeChild(tmpNode);
6077
6066
  }
6078
6067
  function removeTmpNode() {
6079
6068
  kity26.Utils.each(nodeList, (node) => {
@@ -6156,11 +6145,11 @@ var FormulaX = (() => {
6156
6145
  bg;
6157
6146
  exp;
6158
6147
  config;
6159
- constructor(kity26, exp, config2) {
6148
+ constructor(kity26, exp, config) {
6160
6149
  this.wrap = new kity26.Group();
6161
6150
  this.bg = new kity26.Rect(0, 0, 0, 0).fill("transparent");
6162
6151
  this.exp = exp;
6163
- this.config = config2;
6152
+ this.config = config;
6164
6153
  this.wrap.setAttr("data-type", "kf-exp-wrap");
6165
6154
  this.bg.setAttr("data-type", "kf-exp-wrap-bg");
6166
6155
  this.wrap.addShape(this.bg);
@@ -6189,14 +6178,14 @@ var FormulaX = (() => {
6189
6178
  static create(kity26, GTYPE2, FontManager, FontInstaller, FPaper, Output) {
6190
6179
  const Formula = kity26.createClass("Formula", {
6191
6180
  base: FPaper,
6192
- constructor: function(container, config2) {
6181
+ constructor: function(container, config) {
6193
6182
  if (this.__FORMULAX_PRESERVE_CALL_BASE__) {
6194
6183
  this.callBase(container);
6195
6184
  }
6196
6185
  FPaper.call(this, container);
6197
6186
  this.expressions = [];
6198
6187
  this.fontInstaller = new FontInstaller(this);
6199
- this.config = kity26.Utils.extend({}, DEFAULT_OPTIONS, config2);
6188
+ this.config = kity26.Utils.extend({}, DEFAULT_OPTIONS, config);
6200
6189
  this.initEnvironment();
6201
6190
  this.initInnerFont();
6202
6191
  },
@@ -13661,7 +13650,7 @@ var FormulaX = (() => {
13661
13650
  value: function() {
13662
13651
  const kf7 = window2.kf;
13663
13652
  const CONSTRUCT_MAPPING = {};
13664
- const CURSOR_CHAR3 = "\uF155";
13653
+ const CURSOR_CHAR4 = "\uF155";
13665
13654
  class Assembly {
13666
13655
  formula;
13667
13656
  constructor(formula) {
@@ -13698,7 +13687,7 @@ var FormulaX = (() => {
13698
13687
  if (tree.name.indexOf("text") === -1) {
13699
13688
  for (let i2 = 0, len = operand.length; i2 < len; i2 += 1) {
13700
13689
  currentOperand = operand[i2];
13701
- if (currentOperand === CURSOR_CHAR3) {
13690
+ if (currentOperand === CURSOR_CHAR4) {
13702
13691
  cursorLocation.push(i2);
13703
13692
  if (!Object.prototype.hasOwnProperty.call(selectInfo, "startOffset")) {
13704
13693
  selectInfo.startOffset = i2;
@@ -16870,6 +16859,35 @@ var FormulaX = (() => {
16870
16859
  }
16871
16860
  Object.keys(list).forEach((key) => callback(list[key], key));
16872
16861
  }
16862
+ function translateToolbarText(value, locale) {
16863
+ if (locale === "zh_CN") {
16864
+ return value;
16865
+ }
16866
+ const normalizedValue = value.replace(/<br\s*\/?>/gi, "").trim();
16867
+ const translatedValue = zhCnToEnUsText.get(normalizedValue);
16868
+ if (!translatedValue) {
16869
+ return value;
16870
+ }
16871
+ const lineBreakMatch = value.match(/<br\s*\/?>/i);
16872
+ return lineBreakMatch ? `${translatedValue}${lineBreakMatch[0]}` : translatedValue;
16873
+ }
16874
+ function localizeToolbarConfig(value, locale) {
16875
+ if (Array.isArray(value)) {
16876
+ return value.map((item) => localizeToolbarConfig(item, locale));
16877
+ }
16878
+ if (!value || typeof value !== "object") {
16879
+ return value;
16880
+ }
16881
+ const result = {};
16882
+ for (const [key, currentValue] of Object.entries(value)) {
16883
+ if ((key === "label" || key === "title") && typeof currentValue === "string") {
16884
+ result[key] = translateToolbarText(currentValue, locale);
16885
+ continue;
16886
+ }
16887
+ result[key] = localizeToolbarConfig(currentValue, locale);
16888
+ }
16889
+ return result;
16890
+ }
16873
16891
  function getUnicodeContents(keySet) {
16874
16892
  let result = [];
16875
16893
  each(keySet, function(key) {
@@ -16889,7 +16907,13 @@ var FormulaX = (() => {
16889
16907
  });
16890
16908
  return result;
16891
16909
  }
16892
- var UI_ELE_TYPE, BOX_TYPE2, OTHER_POSITION, config, toolbar_config_default;
16910
+ function createToolbarConfig(locale = DEFAULT_FORMULAX_LOCALE) {
16911
+ return localizeToolbarConfig(
16912
+ baseToolbarConfig,
16913
+ normalizeFormulaXLocale(locale)
16914
+ );
16915
+ }
16916
+ var UI_ELE_TYPE, BOX_TYPE2, OTHER_POSITION, zhCnToEnUsText, baseToolbarConfig, toolbar_config_default;
16893
16917
  var init_toolbar_config = __esm({
16894
16918
  "src/legacy/toolbar-config.ts"() {
16895
16919
  "use strict";
@@ -16898,10 +16922,45 @@ var FormulaX = (() => {
16898
16922
  init_other_position();
16899
16923
  init_toolbar_assets();
16900
16924
  init_formula_symbols();
16925
+ init_i18n();
16901
16926
  UI_ELE_TYPE = legacyEleType;
16902
16927
  BOX_TYPE2 = legacyBoxType;
16903
16928
  OTHER_POSITION = legacyOtherPosition;
16904
- config = [{
16929
+ zhCnToEnUsText = /* @__PURE__ */ new Map([
16930
+ ["\u9884\u8BBE", "Presets"],
16931
+ ["\u9884\u8BBE\u516C\u5F0F", "Preset formulas"],
16932
+ ["\u4E8C\u6B21\u516C\u5F0F", "Quadratic formula"],
16933
+ ["\u4E8C\u9879\u5F0F\u5B9A\u7406", "Binomial theorem"],
16934
+ ["\u52FE\u80A1\u5B9A\u7406", "Pythagorean theorem"],
16935
+ ["\u57FA\u7840\u6570\u5B66", "Basic math"],
16936
+ ["\u5E0C\u814A\u5B57\u6BCD", "Greek letters"],
16937
+ ["\u6C42\u53CD\u5173\u7CFB\u8FD0\u7B97\u7B26", "Negated operators"],
16938
+ ["\u5B57\u6BCD\u7C7B\u7B26\u53F7", "Letter-like symbols"],
16939
+ ["\u7BAD\u5934", "Arrows"],
16940
+ ["\u624B\u5199\u4F53", "Script"],
16941
+ ["\u5206\u6570", "Fraction"],
16942
+ ["\u5E38\u7528\u5206\u6570", "Common fractions"],
16943
+ ["\u4E0A\u4E0B\u6807", "Scripts"],
16944
+ ["\u4E0A\u6807\u548C\u4E0B\u6807", "Superscripts and subscripts"],
16945
+ ["\u5E38\u7528\u7684\u4E0A\u6807\u548C\u4E0B\u6807", "Common superscripts and subscripts"],
16946
+ ["\u6839\u5F0F", "Radicals"],
16947
+ ["\u5E38\u7528\u6839\u5F0F", "Common radicals"],
16948
+ ["\u79EF\u5206", "Integrals"],
16949
+ ["\u5927\u578B\u8FD0\u7B97\u7B26", "Large operators"],
16950
+ ["\u6C42\u548C", "Summations"],
16951
+ ["\u62EC\u53F7", "Brackets"],
16952
+ ["\u65B9\u62EC\u53F7", "Brackets"],
16953
+ ["\u51FD\u6570", "Functions"],
16954
+ ["\u4E09\u89D2\u51FD\u6570", "Trigonometric functions"],
16955
+ ["\u5E38\u7528\u51FD\u6570", "Common functions"],
16956
+ ["\u5C0F\u5199", "Lowercase"],
16957
+ ["\u5927\u5199", "Uppercase"],
16958
+ ["\u53D8\u4F53", "Variants"],
16959
+ ["\u82B1\u4F53", "Fraktur"],
16960
+ ["\u53CC\u7EBF", "Double-struck"],
16961
+ ["\u7F57\u9A6C", "Roman"]
16962
+ ]);
16963
+ baseToolbarConfig = [{
16905
16964
  type: UI_ELE_TYPE.DRAPDOWN_BOX,
16906
16965
  options: {
16907
16966
  button: {
@@ -17307,7 +17366,7 @@ var FormulaX = (() => {
17307
17366
  }];
17308
17367
  (function() {
17309
17368
  let tmp = [], otherImageSrc = resolveToolbarAssetPath("other.png"), currentConf = [];
17310
- each(config, function(conf) {
17369
+ each(baseToolbarConfig, function(conf) {
17311
17370
  if (conf.type === UI_ELE_TYPE.DELIMITER) {
17312
17371
  return;
17313
17372
  }
@@ -17379,7 +17438,7 @@ var FormulaX = (() => {
17379
17438
  "aleph",
17380
17439
  "beth",
17381
17440
  "blacksquare"
17382
- ], configList = config[2].options.box.group[0].items;
17441
+ ], configList = baseToolbarConfig[2].options.box.group[0].items;
17383
17442
  configList.push({
17384
17443
  title: "\u57FA\u7840\u6570\u5B66",
17385
17444
  content: getUnicodeContents(list)
@@ -17395,7 +17454,7 @@ var FormulaX = (() => {
17395
17454
  }, {
17396
17455
  title: "\u53D8\u4F53",
17397
17456
  values: ["digamma", "varepsilon", "varkappa", "varphi", "varpi", "varrho", "varsigma", "vartheta"]
17398
- }], greekConfigList = config[2].options.box.group[1].items;
17457
+ }], greekConfigList = baseToolbarConfig[2].options.box.group[1].items;
17399
17458
  greekConfigList.push({
17400
17459
  title: greekList[0].title,
17401
17460
  content: getUnicodeContents(greekList[0].values)
@@ -17444,7 +17503,7 @@ var FormulaX = (() => {
17444
17503
  "nVDash",
17445
17504
  "nexists"
17446
17505
  ]
17447
- }], greekConfigList = config[2].options.box.group[2].items;
17506
+ }], greekConfigList = baseToolbarConfig[2].options.box.group[2].items;
17448
17507
  greekConfigList.push({
17449
17508
  title: greekList[0].title,
17450
17509
  content: getUnicodeContents(greekList[0].values)
@@ -17470,7 +17529,7 @@ var FormulaX = (() => {
17470
17529
  "Game",
17471
17530
  "Im",
17472
17531
  "Re"
17473
- ], configList = config[2].options.box.group[3].items;
17532
+ ], configList = baseToolbarConfig[2].options.box.group[3].items;
17474
17533
  configList.push({
17475
17534
  title: "\u5B57\u6BCD\u7C7B\u7B26\u53F7",
17476
17535
  content: getUnicodeContents(list)
@@ -17538,7 +17597,7 @@ var FormulaX = (() => {
17538
17597
  "twoheadleftarrow",
17539
17598
  "twoheadrightarrow",
17540
17599
  "rightsquigarrow"
17541
- ], configList = config[2].options.box.group[4].items;
17600
+ ], configList = baseToolbarConfig[2].options.box.group[4].items;
17542
17601
  configList.push({
17543
17602
  title: "\u7BAD\u5934",
17544
17603
  content: getUnicodeContents(list)
@@ -17717,7 +17776,7 @@ var FormulaX = (() => {
17717
17776
  "y",
17718
17777
  "z"
17719
17778
  ]
17720
- }], configList = config[2].options.box.group[5].items;
17779
+ }], configList = baseToolbarConfig[2].options.box.group[5].items;
17721
17780
  each(list[0].values, function(item, index) {
17722
17781
  list[0].values[index] = "mathcal{" + item + "}";
17723
17782
  });
@@ -17747,7 +17806,7 @@ var FormulaX = (() => {
17747
17806
  content: getUnicodeContents(list[3].values)
17748
17807
  });
17749
17808
  })();
17750
- toolbar_config_default = config;
17809
+ toolbar_config_default = createToolbarConfig;
17751
17810
  }
17752
17811
  });
17753
17812
 
@@ -17790,6 +17849,7 @@ var FormulaX = (() => {
17790
17849
  init_toolbar();
17791
17850
  init_scrollbar();
17792
17851
  init_toolbar_config();
17852
+ init_i18n();
17793
17853
  $$8 = createLegacyUiUtils();
17794
17854
  VIEW_STATE = legacyUiDef.VIEW_STATE;
17795
17855
  DEFAULT_EDIT_AREA_HEIGHT = 100;
@@ -17820,7 +17880,8 @@ var FormulaX = (() => {
17820
17880
  this.initScrollEvent();
17821
17881
  },
17822
17882
  initComponents() {
17823
- this.components.toolbar = new toolbar_default(this, this.kfEditor, toolbar_config_default);
17883
+ const toolbarConfig = toolbar_config_default(normalizeFormulaXLocale(this.options.locale));
17884
+ this.components.toolbar = new toolbar_default(this, this.kfEditor, toolbarConfig);
17824
17885
  this.components.scrollbar = new scrollbar_default(this, this.kfEditor);
17825
17886
  },
17826
17887
  updateContainerSize(container, toolbar, editArea) {
@@ -19087,6 +19148,21 @@ var FormulaX = (() => {
19087
19148
  });
19088
19149
 
19089
19150
  // src/legacy/syntax.ts
19151
+ function clampOffset(offset, maxOffset) {
19152
+ return Math.max(0, Math.min(offset, maxOffset));
19153
+ }
19154
+ function normalizeCursorRecord(objTree, cursor) {
19155
+ const fallbackGroupId = objTree.mapping.root.strGroup.attr.id;
19156
+ const targetGroupId = cursor.groupId && objTree.mapping[cursor.groupId] ? cursor.groupId : fallbackGroupId;
19157
+ const operandCount = objTree.mapping[targetGroupId].strGroup.operand.length;
19158
+ const startOffset = clampOffset(cursor.startOffset, operandCount);
19159
+ const endOffset = clampOffset(cursor.endOffset, operandCount);
19160
+ return {
19161
+ groupId: targetGroupId,
19162
+ startOffset: Math.min(startOffset, endOffset),
19163
+ endOffset: Math.max(startOffset, endOffset)
19164
+ };
19165
+ }
19090
19166
  var CURSOR_CHAR2, kity19, SyntaxComponent, syntax_default;
19091
19167
  var init_syntax = __esm({
19092
19168
  "src/legacy/syntax.ts"() {
@@ -19147,10 +19223,14 @@ var FormulaX = (() => {
19147
19223
  },
19148
19224
  updateObjTree(objTree) {
19149
19225
  const selectInfo = objTree.select;
19226
+ this.objTree = objTree;
19150
19227
  if (selectInfo?.groupId) {
19151
19228
  this.updateCursor(selectInfo.groupId, selectInfo.startOffset, selectInfo.endOffset);
19229
+ return;
19230
+ }
19231
+ if (this.record.cursor.groupId !== null) {
19232
+ this.record.cursor = normalizeCursorRecord(objTree, this.record.cursor);
19152
19233
  }
19153
- this.objTree = objTree;
19154
19234
  },
19155
19235
  hasCursorInfo() {
19156
19236
  return this.record.cursor.groupId !== null;
@@ -19196,7 +19276,8 @@ var FormulaX = (() => {
19196
19276
  return this.objTree;
19197
19277
  },
19198
19278
  getGroupObject(id) {
19199
- return this.objTree.mapping[id].objGroup || null;
19279
+ const groupInfo = this.objTree.mapping[id];
19280
+ return groupInfo ? groupInfo.objGroup : null;
19200
19281
  },
19201
19282
  getCursorRecord() {
19202
19283
  return kity19.Utils.extend({}, this.record.cursor);
@@ -19272,7 +19353,7 @@ var FormulaX = (() => {
19272
19353
  return this.hasRootplaceholder();
19273
19354
  },
19274
19355
  serialization() {
19275
- const cursor = this.record.cursor;
19356
+ const cursor = normalizeCursorRecord(this.objTree, this.record.cursor);
19276
19357
  const objGroup = this.objTree.mapping[cursor.groupId];
19277
19358
  const curStrGroup = objGroup.strGroup;
19278
19359
  let strStartIndex = Math.min(cursor.endOffset, cursor.startOffset);
@@ -19308,11 +19389,12 @@ var FormulaX = (() => {
19308
19389
  endOffset = startOffset;
19309
19390
  startOffset = tmp;
19310
19391
  }
19311
- this.record.cursor = {
19392
+ const nextCursor = {
19312
19393
  groupId,
19313
19394
  startOffset,
19314
19395
  endOffset
19315
19396
  };
19397
+ this.record.cursor = this.objTree ? normalizeCursorRecord(this.objTree, nextCursor) : nextCursor;
19316
19398
  },
19317
19399
  leftMove() {
19318
19400
  this.components.move.leftMove();
@@ -19353,12 +19435,20 @@ var FormulaX = (() => {
19353
19435
  });
19354
19436
 
19355
19437
  // src/legacy/input.ts
19356
- var KEY_CODE, kity20, InputComponent, input_default;
19438
+ function insertCursorMarkers(value, selectionStart, selectionEnd) {
19439
+ const normalizedStart = Math.max(0, Math.min(selectionStart ?? value.length, value.length));
19440
+ const normalizedEnd = Math.max(0, Math.min(selectionEnd ?? normalizedStart, value.length));
19441
+ const rangeStart = Math.min(normalizedStart, normalizedEnd);
19442
+ const rangeEnd = Math.max(normalizedStart, normalizedEnd);
19443
+ return value.slice(0, rangeStart) + CURSOR_CHAR3 + value.slice(rangeStart, rangeEnd) + CURSOR_CHAR3 + value.slice(rangeEnd);
19444
+ }
19445
+ var KEY_CODE, CURSOR_CHAR3, kity20, InputComponent, input_default;
19357
19446
  var init_input = __esm({
19358
19447
  "src/legacy/input.ts"() {
19359
19448
  "use strict";
19360
19449
  init_legacy_utils();
19361
19450
  init_legacy_input_filter();
19451
+ init_legacy_sysconf();
19362
19452
  init_runtime_interop();
19363
19453
  KEY_CODE = {
19364
19454
  LEFT: 37,
@@ -19366,6 +19456,7 @@ var FormulaX = (() => {
19366
19456
  DELETE: 8,
19367
19457
  INPUT: 229
19368
19458
  };
19459
+ CURSOR_CHAR3 = legacySysconf.cursorCharacter;
19369
19460
  kity20 = getLegacyKity();
19370
19461
  InputComponent = kity20.createClass("InputComponent", {
19371
19462
  constructor(parentComponent, kfEditor) {
@@ -19538,7 +19629,12 @@ var FormulaX = (() => {
19538
19629
  return `${e.shiftKey ? "s+" : ""}${e.keyCode}`;
19539
19630
  },
19540
19631
  processingInput() {
19541
- this.restruct(this.inputBox.value);
19632
+ const latexWithCursor = insertCursorMarkers(
19633
+ this.inputBox.value,
19634
+ this.inputBox.selectionStart,
19635
+ this.inputBox.selectionEnd
19636
+ );
19637
+ this.restruct(latexWithCursor);
19542
19638
  this.kfEditor.requestService("ui.update.canvas.view");
19543
19639
  },
19544
19640
  restruct(latexStr) {
@@ -20088,6 +20184,8 @@ var FormulaX = (() => {
20088
20184
  // src/index.ts
20089
20185
  var index_exports = {};
20090
20186
  __export(index_exports, {
20187
+ DEFAULT_FORMULAX_LOCALE: () => DEFAULT_FORMULAX_LOCALE,
20188
+ FORMULAX_LOCALES: () => FORMULAX_LOCALES,
20091
20189
  FormulaXEditor: () => FormulaXEditor,
20092
20190
  addEvent: () => addEvent,
20093
20191
  createElement: () => createElement,
@@ -20117,6 +20215,7 @@ var FormulaX = (() => {
20117
20215
  legacyUiDef: () => legacyUiDef,
20118
20216
  legacyUiUtils: () => legacyUiUtils,
20119
20217
  mountKityEditor: () => mountKityEditor,
20218
+ normalizeFormulaXLocale: () => normalizeFormulaXLocale,
20120
20219
  normalizeMouseEvent: () => normalizeMouseEvent,
20121
20220
  publish: () => publish,
20122
20221
  subscribe: () => subscribe
@@ -23603,6 +23702,7 @@ var FormulaX = (() => {
23603
23702
 
23604
23703
  // src/create-editor.ts
23605
23704
  init_toolbar_assets();
23705
+ init_i18n();
23606
23706
  var DEFAULT_LATEX = "x=\\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}";
23607
23707
  var DEFAULT_EDITOR_HEIGHT = "auto";
23608
23708
  var KITY_STYLE_ID = "formulax-kity-editor-styles";
@@ -23753,6 +23853,7 @@ var FormulaX = (() => {
23753
23853
  const createEditorStart = markFormulaXPerf("fx:create-kity-editor:total");
23754
23854
  const fontsize = options.render?.fontsize ?? 40;
23755
23855
  const editorHeight = normalizeCssSize(options.height, DEFAULT_EDITOR_HEIGHT);
23856
+ const locale = normalizeFormulaXLocale(options.locale ?? DEFAULT_FORMULAX_LOCALE);
23756
23857
  const assets = resolveEditorAssets(options.assets);
23757
23858
  try {
23758
23859
  const stylesheetInserted = ensureKityStylesheet(document, assets.styles.editor);
@@ -23781,6 +23882,9 @@ var FormulaX = (() => {
23781
23882
  render: {
23782
23883
  fontsize
23783
23884
  },
23885
+ ui: {
23886
+ locale
23887
+ },
23784
23888
  resource: {
23785
23889
  path: "",
23786
23890
  fonts: assets.fonts
@@ -23863,6 +23967,7 @@ var FormulaX = (() => {
23863
23967
 
23864
23968
  // src/index.ts
23865
23969
  init_dom_utils();
23970
+ init_i18n();
23866
23971
  init_legacy_box_type();
23867
23972
  init_legacy_component();
23868
23973
  init_legacy_ele_type();