mce 0.18.5 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -151,7 +151,7 @@ var imageExts = Object.values({
151
151
  var imageExtRe = new RegExp(`\\.(?:${imageExts.map((v) => v.substring(1)).join("|")})`, "i");
152
152
  //#endregion
153
153
  //#region src/utils/create.ts
154
- var RECT_PATH$1 = "M0 0h24v24H0z";
154
+ var RECT_PATH = "M0 0h24v24H0z";
155
155
  var FLOW_CONNECTION_POINTS = [
156
156
  {
157
157
  idx: 0,
@@ -189,8 +189,9 @@ function createShapeElement(shape, fill, outline) {
189
189
  }
190
190
  };
191
191
  }
192
- function createTextElement(content, style) {
192
+ function createTextElement(content, style, fonts) {
193
193
  const box = measureText({
194
+ fonts,
194
195
  style,
195
196
  content
196
197
  }).boundingBox;
@@ -259,7 +260,7 @@ function createCardElement(title, options = {}) {
259
260
  borderRadius,
260
261
  overflow: "hidden"
261
262
  },
262
- shape: [{ data: RECT_PATH$1 }],
263
+ shape: [{ data: RECT_PATH }],
263
264
  fill,
264
265
  outline,
265
266
  children,
@@ -290,7 +291,7 @@ function createFlowNodeElement(label = "", options = {}) {
290
291
  },
291
292
  shape: {
292
293
  enabled: true,
293
- paths: [{ data: RECT_PATH$1 }],
294
+ paths: [{ data: RECT_PATH }],
294
295
  connectionPoints
295
296
  },
296
297
  fill,
@@ -313,7 +314,7 @@ function createStickyElement(content, options = {}) {
313
314
  color,
314
315
  fontSize
315
316
  },
316
- shape: [{ data: RECT_PATH$1 }],
317
+ shape: [{ data: RECT_PATH }],
317
318
  fill,
318
319
  text: { content: normalizeTextContent(content) },
319
320
  meta: {
@@ -322,6 +323,78 @@ function createStickyElement(content, options = {}) {
322
323
  }
323
324
  };
324
325
  }
326
+ /** A grid table backed by the native `table` element property; first row is a header. */
327
+ function createTableElement(rows = 3, cols = 3, options = {}) {
328
+ const { width = 360, height = 160 } = options;
329
+ const cells = [];
330
+ for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) cells.push({
331
+ row: r,
332
+ col: c,
333
+ children: [{
334
+ style: {
335
+ fontSize: 13,
336
+ color: "#333333",
337
+ textAlign: "center",
338
+ verticalAlign: "middle",
339
+ fontWeight: r === 0 ? 700 : 400
340
+ },
341
+ text: { content: normalizeTextContent(r === 0 ? `列 ${c + 1}` : "") },
342
+ meta: { inCanvasIs: "Element2D" }
343
+ }]
344
+ });
345
+ return {
346
+ style: {
347
+ width,
348
+ height
349
+ },
350
+ table: {
351
+ columns: Array.from({ length: cols }, () => ({ width: width / cols })),
352
+ rows: Array.from({ length: rows }, () => ({ height: height / rows })),
353
+ cells
354
+ },
355
+ meta: {
356
+ inPptIs: "Shape",
357
+ inCanvasIs: "Element2D",
358
+ inEditorIs: "Table"
359
+ }
360
+ };
361
+ }
362
+ /** A chart backed by the native `chart` element property (column/line/pie/…). */
363
+ function createChartElement(type = "column", options = {}) {
364
+ const { width = 360, height = 240, categories = [
365
+ "一月",
366
+ "二月",
367
+ "三月",
368
+ "四月",
369
+ "五月"
370
+ ], series = [{
371
+ name: "系列 1",
372
+ values: [
373
+ 40,
374
+ 70,
375
+ 55,
376
+ 90,
377
+ 60
378
+ ]
379
+ }] } = options;
380
+ return {
381
+ style: {
382
+ width,
383
+ height
384
+ },
385
+ chart: {
386
+ type,
387
+ categories,
388
+ series,
389
+ legend: "bottom"
390
+ },
391
+ meta: {
392
+ inPptIs: "Shape",
393
+ inCanvasIs: "Element2D",
394
+ inEditorIs: "Chart"
395
+ }
396
+ };
397
+ }
325
398
  //#endregion
326
399
  //#region src/utils/dnd.ts
327
400
  function addDragListener(downEvent, options = {}) {
@@ -5133,7 +5206,7 @@ var YDoc = class extends Observable {
5133
5206
  this.transact(() => {
5134
5207
  const childId = child.id;
5135
5208
  this._debug(`[removeChild][${childId}]`, child.name, oldIndex);
5136
- const index = childrenIds.toJSON().indexOf(childId);
5209
+ const index = childrenIds.toArray().indexOf(childId);
5137
5210
  if (index > -1) childrenIds.delete(index, 1);
5138
5211
  });
5139
5212
  });
@@ -5527,8 +5600,16 @@ var _0_context_default = defineMixin((editor, options) => {
5527
5600
  const { left = _left, top = _top } = drawboardDom.value?.getBoundingClientRect() ?? {};
5528
5601
  drawboardAabb.value = new Aabb2D(left, top, width, height);
5529
5602
  });
5603
+ let pointerRafId = null;
5604
+ let lastPointerEvent;
5530
5605
  function onMouseMove(event) {
5531
- drawboardPointer.value = new Vector2(event.clientX - drawboardAabb.value.left, event.clientY - drawboardAabb.value.top);
5606
+ lastPointerEvent = event;
5607
+ if (pointerRafId !== null) return;
5608
+ pointerRafId = requestAnimationFrame(() => {
5609
+ pointerRafId = null;
5610
+ const e = lastPointerEvent;
5611
+ drawboardPointer.value = new Vector2(e.clientX - drawboardAabb.value.left, e.clientY - drawboardAabb.value.top);
5612
+ });
5532
5613
  }
5533
5614
  onBeforeMount(() => {
5534
5615
  on("docSet", onSetDoc);
@@ -5539,6 +5620,7 @@ var _0_context_default = defineMixin((editor, options) => {
5539
5620
  off("docSet", onSetDoc);
5540
5621
  renderEngine.value.stop();
5541
5622
  document.removeEventListener("mousemove", onMouseMove);
5623
+ if (pointerRafId !== null) cancelAnimationFrame(pointerRafId);
5542
5624
  });
5543
5625
  };
5544
5626
  });
@@ -5608,6 +5690,10 @@ var en_default = {
5608
5690
  "ellipse": "Ellipse",
5609
5691
  "polygon": "Polygon",
5610
5692
  "star": "Star",
5693
+ "table": "Table",
5694
+ "chartBar": "Bar Chart",
5695
+ "chartLine": "Line Chart",
5696
+ "chartPie": "Pie Chart",
5611
5697
  "image": "Image",
5612
5698
  "video": "Video",
5613
5699
  "lottie": "Lottie",
@@ -5621,11 +5707,6 @@ var en_default = {
5621
5707
  "saveAs:png": "Save as PNG",
5622
5708
  "saveAs:jpeg": "Save as JPEG",
5623
5709
  "saveAs:webp": "Save as WEBP",
5624
- "saveAs:svg": "Save as SVG",
5625
- "saveAs:gif": "Save as GIF",
5626
- "saveAs:mp4": "Save as MP4",
5627
- "saveAs:pdf": "Save as PDF",
5628
- "saveAs:pptx": "Save as PPTX",
5629
5710
  "saveAs:json": "Save as JSON",
5630
5711
  "addSubNode": "Add sub node",
5631
5712
  "edit": "Edit",
@@ -5740,6 +5821,10 @@ var zh_Hans_default = {
5740
5821
  "ellipse": "椭圆",
5741
5822
  "polygon": "多边形",
5742
5823
  "star": "星形",
5824
+ "table": "表格",
5825
+ "chartBar": "柱状图",
5826
+ "chartLine": "折线图",
5827
+ "chartPie": "饼图",
5743
5828
  "image": "图片",
5744
5829
  "video": "视频",
5745
5830
  "lottie": "Lottie",
@@ -5753,11 +5838,6 @@ var zh_Hans_default = {
5753
5838
  "saveAs:png": "另存为 PNG",
5754
5839
  "saveAs:jpeg": "另存为 JPEG",
5755
5840
  "saveAs:webp": "另存为 WEBP",
5756
- "saveAs:svg": "另存为 SVG",
5757
- "saveAs:gif": "另存为 GIF",
5758
- "saveAs:mp4": "另存为 MP4",
5759
- "saveAs:pdf": "另存为 PDF",
5760
- "saveAs:pptx": "另存为 PPTX",
5761
5841
  "saveAs:json": "另存为 JSON",
5762
5842
  "addSubNode": "添加子节点",
5763
5843
  "edit": "编辑",
@@ -5843,6 +5923,10 @@ var zh_Hans_default = {
5843
5923
  //#region src/mixins/0.locale.ts
5844
5924
  var _0_locale_default = defineMixin((editor, options) => {
5845
5925
  const { locale } = options;
5926
+ const pluginMessages = ref({});
5927
+ function registerMessages(value) {
5928
+ pluginMessages.value = merge({}, pluginMessages.value, value);
5929
+ }
5846
5930
  const messages = computed(() => {
5847
5931
  const { locale: _locale, fallback: _fallback, messages = {} } = merge({
5848
5932
  locale: "en",
@@ -5854,8 +5938,8 @@ var _0_locale_default = defineMixin((editor, options) => {
5854
5938
  }, locale);
5855
5939
  return {
5856
5940
  locale: _locale,
5857
- localeMessages: messages[_locale],
5858
- fallbackMessages: messages[_fallback]
5941
+ localeMessages: merge({}, messages[_locale], pluginMessages.value[_locale]),
5942
+ fallbackMessages: merge({}, messages[_fallback], pluginMessages.value[_fallback])
5859
5943
  };
5860
5944
  });
5861
5945
  function t(key, fallback) {
@@ -5864,7 +5948,10 @@ var _0_locale_default = defineMixin((editor, options) => {
5864
5948
  if (value === void 0) console.warn(`[mce] Not found '${key}' key in '${locale}' locale messages.`);
5865
5949
  return value ?? key ?? fallback ?? "";
5866
5950
  }
5867
- Object.assign(editor, { t });
5951
+ Object.assign(editor, {
5952
+ t,
5953
+ registerMessages
5954
+ });
5868
5955
  });
5869
5956
  //#endregion
5870
5957
  //#region src/mixins/1.frame.ts
@@ -5986,10 +6073,17 @@ var _1_timeline_default = defineMixin((editor) => {
5986
6073
  //#endregion
5987
6074
  //#region src/mixins/1.upload.ts
5988
6075
  var _1_upload_default = defineMixin((editor, options) => {
6076
+ const objectUrls = /* @__PURE__ */ new Set();
5989
6077
  const upload = async (file) => {
5990
6078
  if (options.customUpload) return await options.customUpload(file);
5991
- return URL.createObjectURL(file);
6079
+ const url = URL.createObjectURL(file);
6080
+ objectUrls.add(url);
6081
+ return url;
5992
6082
  };
6083
+ editor.on("docSet", () => {
6084
+ objectUrls.forEach((url) => URL.revokeObjectURL(url));
6085
+ objectUrls.clear();
6086
+ });
5993
6087
  Object.assign(editor, { upload });
5994
6088
  });
5995
6089
  //#endregion
@@ -6100,11 +6194,13 @@ var _2_box_default = defineMixin((editor) => {
6100
6194
  };
6101
6195
  node.forEach((child) => {
6102
6196
  if (isElement(child)) {
6103
- const aabb = getAabb(child);
6104
- min.x = Math.min(min.x, aabb.left);
6105
- min.y = Math.min(min.y, aabb.top);
6106
- max.x = Math.max(max.x, aabb.left + aabb.width);
6107
- max.y = Math.max(max.y, aabb.top + aabb.height);
6197
+ const style = child.style;
6198
+ style.left, style.top, style.width, style.height, style.rotate;
6199
+ const box = child.globalAabb;
6200
+ min.x = Math.min(min.x, box.left);
6201
+ min.y = Math.min(min.y, box.top);
6202
+ max.x = Math.max(max.x, box.left + box.width);
6203
+ max.y = Math.max(max.y, box.top + box.height);
6108
6204
  }
6109
6205
  });
6110
6206
  aabb = new Aabb2D(min.x, min.y, max.x - min.x, max.y - min.y);
@@ -7229,6 +7325,7 @@ var autoNest_default = definePlugin((editor) => {
7229
7325
  const { getGlobalPointer, frames, isFrameNode, exec, root, elementSelection } = editor;
7230
7326
  let context;
7231
7327
  function nestIntoFrame(el, options) {
7328
+ if (el.meta?.inEditorIs?.startsWith("Workflow")) return;
7232
7329
  const pointer = options?.pointer;
7233
7330
  const frame1 = el.findAncestor((node) => isFrameNode(node, true));
7234
7331
  const aabb1 = el.globalAabb;
@@ -7917,7 +8014,11 @@ var aliases = {
7917
8014
  arrow: "M5 17.59L15.59 7H9V5h10v10h-2V8.41L6.41 19z",
7918
8015
  ellipse: "M12 20a8 8 0 0 1-8-8a8 8 0 0 1 8-8a8 8 0 0 1 8 8a8 8 0 0 1-8 8m0-18A10 10 0 0 0 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2",
7919
8016
  polygon: "M12 2L1 21h22M12 6l7.53 13H4.47",
7920
- star: "m12 15.39l-3.76 2.27l.99-4.28l-3.32-2.88l4.38-.37L12 6.09l1.71 4.04l4.38.37l-3.32 2.88l.99 4.28M22 9.24l-7.19-.61L12 2L9.19 8.63L2 9.24l5.45 4.73L5.82 21L12 17.27L18.18 21l-1.64-7.03z"
8017
+ star: "m12 15.39l-3.76 2.27l.99-4.28l-3.32-2.88l4.38-.37L12 6.09l1.71 4.04l4.38.37l-3.32 2.88l.99 4.28M22 9.24l-7.19-.61L12 2L9.19 8.63L2 9.24l5.45 4.73L5.82 21L12 17.27L18.18 21l-1.64-7.03z",
8018
+ table: "M4,3H20A2,2 0 0,1 22,5V19A2,2 0 0,1 20,21H4A2,2 0 0,1 2,19V5A2,2 0 0,1 4,3M4,7V11H8V7H4M10,7V11H14V7H10M16,7V11H20V7H16M4,13V17H8V13H4M10,13V17H14V13H10M16,13V17H20V13H16Z",
8019
+ chartBar: "M22,21H2V3H4V19H6V10H10V19H12V6H16V19H18V14H22V21Z",
8020
+ chartLine: "M3.5,18.49L9.5,12.48L13.5,16.48L22,6.92L20.59,5.51L13.5,13.47L9.5,9.47L2,16.99L3.5,18.49Z",
8021
+ chartPie: "M11,2V22C5.9,21.5 2,17.2 2,12C2,6.8 5.9,2.5 11,2M13,2V11H22C21.5,6.2 17.8,2.5 13,2M13,13V22C17.7,21.5 21.5,17.8 22,13H13Z"
7921
8022
  };
7922
8023
  var svg = { component: SvgIcon };
7923
8024
  //#endregion
@@ -8956,6 +9057,13 @@ var Layer_default = /* @__PURE__ */ defineComponent({
8956
9057
  const selected = computed(() => selection.value.some((v) => v.equal(props.node)));
8957
9058
  const children = computed(() => props.node.children);
8958
9059
  const childrenLength = computed(() => children.value.length);
9060
+ const openedShownCount = computed(() => {
9061
+ let n = 0;
9062
+ openedItems.forEach((v) => {
9063
+ if (v.value) n++;
9064
+ });
9065
+ return n;
9066
+ });
8959
9067
  const inputDom = ref();
8960
9068
  const isHoverElement = computed(() => props.node?.equal(hoverElement.value));
8961
9069
  const hovering = ref(false);
@@ -9092,7 +9200,7 @@ var Layer_default = /* @__PURE__ */ defineComponent({
9092
9200
  createElementVNode("div", { class: normalizeClass(["m-layer__action", {
9093
9201
  "m-layer__action--hover": hovering.value,
9094
9202
  "m-layer__action--show": hovering.value || unref(isLock)(props.node) || !unref(isVisible)(props.node)
9095
- }]) }, [props.root ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [Array.from(unref(openedItems).values()).filter((v) => v.value).length > 1 ? (openBlock(), createBlock(Btn_default, {
9203
+ }]) }, [props.root ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [openedShownCount.value > 1 ? (openBlock(), createBlock(Btn_default, {
9096
9204
  key: 0,
9097
9205
  icon: "",
9098
9206
  class: "m-layer__btn m-layer__btn--show",
@@ -10553,15 +10661,15 @@ var Ruler_default = /* @__PURE__ */ defineComponent({
10553
10661
  canvas,
10554
10662
  () => props.zoom,
10555
10663
  () => props.position,
10556
- () => props.selected,
10664
+ () => props.selected?.left,
10665
+ () => props.selected?.top,
10666
+ () => props.selected?.width,
10667
+ () => props.selected?.height,
10557
10668
  () => borderColor.value,
10558
10669
  () => textColor.value
10559
10670
  ], () => {
10560
10671
  render();
10561
- }, {
10562
- immediate: true,
10563
- deep: true
10564
- });
10672
+ }, { immediate: true });
10565
10673
  const resize = useDebounceFn(() => {
10566
10674
  if (!canvas.value) return;
10567
10675
  const _box = canvas.value.parentElement.getBoundingClientRect();
@@ -12830,19 +12938,29 @@ var Selection_default = /* @__PURE__ */ defineComponent({
12830
12938
  });
12831
12939
  const parentObbStyles = computed(() => {
12832
12940
  if (selection.value.length !== 1) return [];
12833
- const obbs = [];
12941
+ const result = [];
12834
12942
  selection.value[0]?.findAncestor((ancestor) => {
12835
- if (isElement(ancestor)) obbs.push(getObb(ancestor, "drawboard"));
12943
+ if (isElement(ancestor)) {
12944
+ const el = ancestor;
12945
+ result.push({
12946
+ id: el.instanceId,
12947
+ style: getObb(el, "drawboard").toCssStyle()
12948
+ });
12949
+ }
12836
12950
  return false;
12837
12951
  });
12838
- return obbs.map((obb) => obb.toCssStyle());
12952
+ return result;
12839
12953
  });
12840
12954
  const selectionObbStyles = computed(() => {
12841
12955
  if (state.value !== "selecting" && elementSelection.value.length === 1) return [];
12842
12956
  return elementSelection.value.map((el) => {
12957
+ const box = getObb(el, "drawboard");
12843
12958
  return {
12844
- ...getObb(el, "drawboard").toCssStyle(),
12845
- borderRadius: `${(el.style.borderRadius ?? 0) * camera.value.zoom.x}px`
12959
+ id: el.instanceId,
12960
+ style: {
12961
+ ...box.toCssStyle(),
12962
+ borderRadius: `${(el.style.borderRadius ?? 0) * camera.value.zoom.x}px`
12963
+ }
12846
12964
  };
12847
12965
  });
12848
12966
  });
@@ -12884,24 +13002,32 @@ var Selection_default = /* @__PURE__ */ defineComponent({
12884
13002
  return false;
12885
13003
  });
12886
13004
  function tip() {
12887
- const obb = elementSelection.value.length === 1 ? elementSelection.value[0].size : selectionObb.value;
13005
+ if (elementSelection.value.length === 1) {
13006
+ const el = elementSelection.value[0];
13007
+ const sw = el.style.width;
13008
+ const sh = el.style.height;
13009
+ const w = typeof sw === "number" ? sw : el.size.width;
13010
+ const h = typeof sh === "number" ? sh : el.size.height;
13011
+ return `${Number(w.toFixed(2))} × ${Number(h.toFixed(2))}`;
13012
+ }
13013
+ const obb = selectionObb.value;
12888
13014
  return `${Number(obb.width.toFixed(2))} × ${Number(obb.height.toFixed(2))}`;
12889
13015
  }
12890
13016
  __expose({ transform });
12891
13017
  return (_ctx, _cache) => {
12892
13018
  return openBlock(), createElementBlock("div", _hoisted_1$15, [
12893
- (openBlock(true), createElementBlock(Fragment, null, renderList(parentObbStyles.value, (style, index) => {
13019
+ (openBlock(true), createElementBlock(Fragment, null, renderList(parentObbStyles.value, (item) => {
12894
13020
  return openBlock(), createElementBlock("div", {
12895
- key: index,
13021
+ key: item.id,
12896
13022
  class: "m-selection__parent",
12897
- style: normalizeStyle(style)
13023
+ style: normalizeStyle(item.style)
12898
13024
  }, null, 4);
12899
13025
  }), 128)),
12900
- unref(state) !== "moving" && unref(state) !== "transforming" ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(selectionObbStyles.value, (style, index) => {
13026
+ unref(state) !== "moving" && unref(state) !== "transforming" ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(selectionObbStyles.value, (item) => {
12901
13027
  return openBlock(), createElementBlock("div", {
12902
- key: index,
13028
+ key: item.id,
12903
13029
  class: "m-selection__node",
12904
- style: normalizeStyle(style)
13030
+ style: normalizeStyle(item.style)
12905
13031
  }, null, 4);
12906
13032
  }), 128)) : createCommentVNode("", true),
12907
13033
  unref(state) === "selecting" || unref(state) === "painting" ? (openBlock(), createElementBlock("div", {
@@ -13011,11 +13137,20 @@ var selection_default = definePlugin((editor) => {
13011
13137
  }
13012
13138
  function marqueeSelect(marquee = selectionMarquee.value) {
13013
13139
  const area = new Obb2D(marquee);
13140
+ const obbCache = /* @__PURE__ */ new Map();
13141
+ const obbOf = (node) => {
13142
+ let obb = obbCache.get(node);
13143
+ if (!obb) {
13144
+ obb = getObb(node, "drawboard");
13145
+ obbCache.set(node, obb);
13146
+ }
13147
+ return obb;
13148
+ };
13014
13149
  selection.value = root.value?.children.flatMap((node) => {
13015
- if (isFrameNode(node, true) && !area.contains(getObb(node, "drawboard"))) return node.children;
13150
+ if (isFrameNode(node, true) && !area.contains(obbOf(node))) return node.children;
13016
13151
  return [node];
13017
13152
  }).filter((node) => {
13018
- return "isVisibleInTree" in node && node.isVisibleInTree() && getObb(node, "drawboard").overlap(area) && !isLock(node) && !node.findAncestor((ancestor) => isLock(ancestor));
13153
+ return "isVisibleInTree" in node && node.isVisibleInTree() && obbOf(node).overlap(area) && !isLock(node) && !node.findAncestor((ancestor) => isLock(ancestor));
13019
13154
  }) ?? [];
13020
13155
  }
13021
13156
  function groupSelection(inEditorIs) {
@@ -13341,6 +13476,46 @@ var shape_default = definePlugin((editor) => {
13341
13476
  {
13342
13477
  name: "star",
13343
13478
  handle: createHandle([{ data: "M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.62L12 2L9.19 8.62L2 9.24l5.45 4.73L5.82 21z" }])
13479
+ },
13480
+ {
13481
+ name: "table",
13482
+ handle: (start) => {
13483
+ addElement(createTableElement(), {
13484
+ position: start,
13485
+ active: true
13486
+ });
13487
+ return { end: () => activateTool(void 0) };
13488
+ }
13489
+ },
13490
+ {
13491
+ name: "chartBar",
13492
+ handle: (start) => {
13493
+ addElement(createChartElement("column"), {
13494
+ position: start,
13495
+ active: true
13496
+ });
13497
+ return { end: () => activateTool(void 0) };
13498
+ }
13499
+ },
13500
+ {
13501
+ name: "chartLine",
13502
+ handle: (start) => {
13503
+ addElement(createChartElement("line"), {
13504
+ position: start,
13505
+ active: true
13506
+ });
13507
+ return { end: () => activateTool(void 0) };
13508
+ }
13509
+ },
13510
+ {
13511
+ name: "chartPie",
13512
+ handle: (start) => {
13513
+ addElement(createChartElement("pie"), {
13514
+ position: start,
13515
+ active: true
13516
+ });
13517
+ return { end: () => activateTool(void 0) };
13518
+ }
13344
13519
  }
13345
13520
  ],
13346
13521
  hotkeys: [
@@ -16080,7 +16255,11 @@ var Toolbelt_default = /* @__PURE__ */ defineComponent({
16080
16255
  "arrow",
16081
16256
  "ellipse",
16082
16257
  "polygon",
16083
- "star"
16258
+ "star",
16259
+ "table",
16260
+ "chartBar",
16261
+ "chartLine",
16262
+ "chartPie"
16084
16263
  ].map((key, index) => {
16085
16264
  return {
16086
16265
  key,
@@ -16662,7 +16841,6 @@ function isEqualStyle(style1, style2) {
16662
16841
  const keys = Array.from(new Set([...keys1, ...keys2]));
16663
16842
  return !keys.length || keys.every((key) => style1[key] === style2[key]);
16664
16843
  }
16665
- var emojiRE = /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC2\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g;
16666
16844
  function parseHTML(html) {
16667
16845
  const template = document.createElement("template");
16668
16846
  template.innerHTML = html;
@@ -16929,10 +17107,6 @@ var TextEditor = class extends HTMLElement {
16929
17107
  }
16930
17108
  _getNewContent(content, newString = textContentToString(content), oldString = newString) {
16931
17109
  newString = normalizeCRLF(newString);
16932
- newString = newString.replace(emojiRE, (emoji) => {
16933
- if (Array.from(emoji).length > 1) return "?";
16934
- return emoji;
16935
- });
16936
17110
  oldString = normalizeCRLF(oldString);
16937
17111
  const oldStyles = textContentToCharStyles(content);
16938
17112
  const styles = [];
@@ -17001,7 +17175,7 @@ var TextEditor = class extends HTMLElement {
17001
17175
  }
17002
17176
  _onInput() {
17003
17177
  const newText = this._textarea.value;
17004
- this.text.content = this._getNewContent(this.text.content, newText, this._oldText);
17178
+ this.text.content = this._getNewContent(this.text.content, newText, textContentToString(this.text.content));
17005
17179
  this._oldText = newText;
17006
17180
  this.text.update();
17007
17181
  this._emit("update");
@@ -17569,7 +17743,7 @@ var typography_default = definePlugin((editor) => {
17569
17743
  return addElement(createTextElement(content, {
17570
17744
  fontSize: 64,
17571
17745
  ...style
17572
- }), {
17746
+ }, fonts), {
17573
17747
  sizeToFit: true,
17574
17748
  active: true,
17575
17749
  ...restOptions
@@ -17636,7 +17810,7 @@ var typography_default = definePlugin((editor) => {
17636
17810
  return false;
17637
17811
  },
17638
17812
  load: async (source) => {
17639
- return createTextElement(await source.text());
17813
+ return createTextElement(await source.text(), void 0, fonts);
17640
17814
  }
17641
17815
  }],
17642
17816
  tools: [{
@@ -17780,8 +17954,13 @@ var OUTPUT_PORT = {
17780
17954
  kind: "output"
17781
17955
  };
17782
17956
  function getWorkflowPorts(el) {
17783
- if (el.meta?.inEditorIs === "Frame") return [OUTPUT_PORT];
17784
- return [INPUT_PORT, OUTPUT_PORT];
17957
+ const custom = el.shape?.connectionPoints;
17958
+ if (custom?.length) return custom.map((p) => ({
17959
+ ...p,
17960
+ kind: p.x < .5 ? "input" : "output"
17961
+ }));
17962
+ if (el.meta?.inEditorIs?.startsWith("Workflow")) return [INPUT_PORT, OUTPUT_PORT];
17963
+ return [OUTPUT_PORT];
17785
17964
  }
17786
17965
  function toConnectionPoints(ports) {
17787
17966
  return ports.map(({ idx, x, y, ang }) => ({
@@ -17835,7 +18014,8 @@ var Workflow_default = /* @__PURE__ */ defineComponent({
17835
18014
  const selectedNode = computed(() => {
17836
18015
  if (mode.value !== "workflow") return void 0;
17837
18016
  const el = elementSelection.value[0];
17838
- return el && isConnectable(el) ? el : void 0;
18017
+ if (!el || !isConnectable(el) || el.getParent?.()?.id !== root.value?.id) return void 0;
18018
+ return el;
17839
18019
  });
17840
18020
  const ports = computed(() => {
17841
18021
  const el = selectedNode.value;
@@ -17902,10 +18082,11 @@ var Workflow_default = /* @__PURE__ */ defineComponent({
17902
18082
  document.removeEventListener("pointermove", onMove);
17903
18083
  document.removeEventListener("pointerup", onUp);
17904
18084
  const drop = toDrawboard(ev);
17905
- drag.value = void 0;
17906
18085
  const target = findNodeAt(drop, sourceId);
17907
- if (target) connect(port, sourceId, target.id, getWorkflowPorts(target));
17908
- else menu.value = {
18086
+ if (target) {
18087
+ drag.value = void 0;
18088
+ connect(port, sourceId, target.id, getWorkflowPorts(target));
18089
+ } else menu.value = {
17909
18090
  port,
17910
18091
  x: drop.x,
17911
18092
  y: drop.y,
@@ -17922,6 +18103,7 @@ var Workflow_default = /* @__PURE__ */ defineComponent({
17922
18103
  function chooseNodeType(type) {
17923
18104
  const m = menu.value;
17924
18105
  menu.value = void 0;
18106
+ drag.value = void 0;
17925
18107
  if (!m) return;
17926
18108
  const node = exec("addWorkflowNode", type);
17927
18109
  const w = node.style.width;
@@ -17932,6 +18114,7 @@ var Workflow_default = /* @__PURE__ */ defineComponent({
17932
18114
  }
17933
18115
  function closeMenu() {
17934
18116
  menu.value = void 0;
18117
+ drag.value = void 0;
17935
18118
  }
17936
18119
  const previewPath = computed(() => {
17937
18120
  const d = drag.value;
@@ -17997,7 +18180,6 @@ var DEFAULT_NODES = {
17997
18180
  body: ["输入分镜、动作、风格等内容,让 AI 自动完成视频生成。"]
17998
18181
  }
17999
18182
  };
18000
- var RECT_PATH = "M0 0h24v24H0z";
18001
18183
  //#endregion
18002
18184
  //#region src/plugins/index.ts
18003
18185
  var plugins = [
@@ -18066,18 +18248,16 @@ var plugins = [
18066
18248
  borderRadius: 20,
18067
18249
  padding: 28,
18068
18250
  fontSize: 16,
18069
- lineHeight: 1.6
18070
- },
18071
- shape: [{ data: RECT_PATH }],
18072
- fill: "#ffffff",
18073
- outline: {
18074
- color: "#ececf0",
18075
- width: 1
18251
+ lineHeight: 1.6,
18252
+ backgroundColor: "#ffffff",
18253
+ borderColor: "#ececf0",
18254
+ borderWidth: 1
18076
18255
  },
18077
18256
  text: { content: buildContent(t) },
18078
18257
  meta: {
18079
18258
  inPptIs: "Shape",
18080
- inCanvasIs: "Element2D"
18259
+ inCanvasIs: "Element2D",
18260
+ inEditorIs: `Workflow${type.charAt(0).toUpperCase()}${type.slice(1)}`
18081
18261
  }
18082
18262
  };
18083
18263
  }
@@ -18390,13 +18570,14 @@ var Editor = class Editor extends Observable {
18390
18570
  let result;
18391
18571
  if (typeof plugin === "function") result = plugin(this, options);
18392
18572
  else result = plugin;
18393
- const { name, events, commands = [], hotkeys = [], loaders = [], exporters = [], tools = [], components = [], setup } = result;
18573
+ const { name, events, commands = [], hotkeys = [], loaders = [], exporters = [], tools = [], components = [], messages, setup } = result;
18394
18574
  this.registerCommand(commands);
18395
18575
  this.registerHotkey(hotkeys);
18396
18576
  this.registerLoader(loaders);
18397
18577
  this.registerExporter(exporters);
18398
18578
  this.registerTool(tools);
18399
18579
  this.registerComponent(name, components);
18580
+ if (messages) this.registerMessages(messages);
18400
18581
  if (setup) this.setups.push(setup);
18401
18582
  if (events) for (const k in events) this.on(k, events[k]);
18402
18583
  }
@@ -18722,13 +18903,15 @@ var EditorLayout_default = /* @__PURE__ */ defineComponent({
18722
18903
  renderEngine.value.on("pointermove", onEnginePointerMove);
18723
18904
  renderEngine.value.on("pointerover", onEnginePointerOver);
18724
18905
  });
18906
+ let unbindRenderCanvas;
18725
18907
  onMounted(() => {
18726
- bindRenderCanvas(canvas.value, drawboardDom.value);
18908
+ unbindRenderCanvas = bindRenderCanvas(canvas.value, drawboardDom.value);
18727
18909
  });
18728
18910
  onBeforeUnmount(() => {
18729
18911
  renderEngine.value.off("pointerdown", onEnginePointerDown);
18730
18912
  renderEngine.value.off("pointermove", onEnginePointerMove);
18731
18913
  renderEngine.value.off("pointerover", onEnginePointerOver);
18914
+ unbindRenderCanvas?.();
18732
18915
  });
18733
18916
  function bindRenderCanvas(canvas, eventTarget) {
18734
18917
  function onRendered() {
@@ -19180,4 +19363,4 @@ var Dialog_default = /* @__PURE__ */ defineComponent({
19180
19363
  }
19181
19364
  });
19182
19365
  //#endregion
19183
- export { Cropper_default as Cropper, Dialog_default as Dialog, Doc, Editor, Layers_default as EditorLayers, EditorLayout_default as EditorLayout, LayoutItem_default as EditorLayoutItem, Toolbelt_default as EditorToolbelt, Menu_default as Menu, Ruler_default as Ruler, Scrollbar_default as Scrollbar, Transform_default as Transform, createCardElement, createFlowNodeElement, createImageElement, createShapeElement, createStickyElement, createTextElement, defineMixin, definePlugin, mixins, plugins, useEditor };
19366
+ export { Cropper_default as Cropper, Dialog_default as Dialog, Doc, Editor, Layers_default as EditorLayers, EditorLayout_default as EditorLayout, LayoutItem_default as EditorLayoutItem, Toolbelt_default as EditorToolbelt, Menu_default as Menu, Ruler_default as Ruler, Scrollbar_default as Scrollbar, Transform_default as Transform, createCardElement, createChartElement, createFlowNodeElement, createImageElement, createShapeElement, createStickyElement, createTableElement, createTextElement, defineMixin, definePlugin, mixins, plugins, useEditor };
@@ -29,6 +29,10 @@ declare const _default: {
29
29
  ellipse: string;
30
30
  polygon: string;
31
31
  star: string;
32
+ table: string;
33
+ chartBar: string;
34
+ chartLine: string;
35
+ chartPie: string;
32
36
  image: string;
33
37
  video: string;
34
38
  lottie: string;
@@ -42,11 +46,6 @@ declare const _default: {
42
46
  'saveAs:png': string;
43
47
  'saveAs:jpeg': string;
44
48
  'saveAs:webp': string;
45
- 'saveAs:svg': string;
46
- 'saveAs:gif': string;
47
- 'saveAs:mp4': string;
48
- 'saveAs:pdf': string;
49
- 'saveAs:pptx': string;
50
49
  'saveAs:json': string;
51
50
  addSubNode: string;
52
51
  edit: string;
@@ -29,6 +29,10 @@ declare const _default: {
29
29
  ellipse: string;
30
30
  polygon: string;
31
31
  star: string;
32
+ table: string;
33
+ chartBar: string;
34
+ chartLine: string;
35
+ chartPie: string;
32
36
  image: string;
33
37
  video: string;
34
38
  lottie: string;
@@ -42,11 +46,6 @@ declare const _default: {
42
46
  'saveAs:png': string;
43
47
  'saveAs:jpeg': string;
44
48
  'saveAs:webp': string;
45
- 'saveAs:svg': string;
46
- 'saveAs:gif': string;
47
- 'saveAs:mp4': string;
48
- 'saveAs:pdf': string;
49
- 'saveAs:pptx': string;
50
49
  'saveAs:json': string;
51
50
  addSubNode: string;
52
51
  edit: string;
@@ -3,6 +3,8 @@ declare global {
3
3
  type Translation = (key: string, fallback?: string) => string;
4
4
  interface Editor {
5
5
  t: Translation;
6
+ /** 插件追加自己的 i18n 文案,按 locale(如 en / zhHans)合并,避免全部聚合到核心 locale。 */
7
+ registerMessages: (messages: Partial<Record<string, LocaleMessages>>) => void;
6
8
  }
7
9
  interface LocaleMessages {
8
10
  [key: string]: LocaleMessages | string;
package/dist/plugin.d.ts CHANGED
@@ -31,6 +31,8 @@ export interface PluginObject {
31
31
  exporters?: Mce.Exporter[];
32
32
  tools?: Mce.Tool[];
33
33
  components?: PluginComponent[];
34
+ /** 插件追加的 i18n 文案,按 locale 合并(如 { en: {...}, zhHans: {...} })。 */
35
+ messages?: Partial<Record<string, Mce.LocaleMessages>>;
34
36
  setup?: () => void | Promise<void>;
35
37
  }
36
38
  export type Plugin = PluginObject | ((editor: Editor, options: Options) => PluginObject);
@@ -7,6 +7,10 @@ declare global {
7
7
  ellipse: [];
8
8
  polygon: [];
9
9
  star: [];
10
+ table: [];
11
+ chartBar: [];
12
+ chartLine: [];
13
+ chartPie: [];
10
14
  }
11
15
  }
12
16
  }
@@ -5,7 +5,7 @@ import 'modern-canvas'
5
5
  declare module 'modern-canvas' {
6
6
  interface Meta {
7
7
  inPptIs?: 'Pptx' | 'Picture' | 'Shape' | 'GroupShape' | 'Animation'
8
- inEditorIs?: 'Doc' | 'Frame' | 'Element' | 'Node'
8
+ inEditorIs?: 'Doc' | 'Frame' | 'Element' | 'Node' | `Workflow${string}`
9
9
  inCanvasIs?: 'Lottie2D' | 'Element2D' | 'Animation'
10
10
  lock?: boolean
11
11
  lockAspectRatio?: boolean
@@ -1,6 +1,7 @@
1
- import type { Element, Fill, Outline, ShapeConnectionPoint } from 'modern-idoc';
1
+ import type { Chart, ChartType, Element, Fill, Outline, ShapeConnectionPoint } from 'modern-idoc';
2
+ import type { Options } from 'modern-text';
2
3
  export declare function createShapeElement(shape?: Element['shape'], fill?: Fill, outline?: Outline): Element;
3
- export declare function createTextElement(content: string, style?: Record<string, any>): Element;
4
+ export declare function createTextElement(content: string, style?: Record<string, any>, fonts?: Options['fonts']): Element;
4
5
  export declare function createImageElement(image: string): Promise<Element>;
5
6
  export interface CreateCardElementOptions {
6
7
  /** Body text below the title. Omitted if empty. */
@@ -45,3 +46,17 @@ export interface CreateStickyElementOptions {
45
46
  }
46
47
  /** A solid colored note with top-aligned text, e.g. for whiteboard annotations. */
47
48
  export declare function createStickyElement(content: string, options?: CreateStickyElementOptions): Element;
49
+ export interface CreateTableElementOptions {
50
+ width?: number;
51
+ height?: number;
52
+ }
53
+ /** A grid table backed by the native `table` element property; first row is a header. */
54
+ export declare function createTableElement(rows?: number, cols?: number, options?: CreateTableElementOptions): Element;
55
+ export interface CreateChartElementOptions {
56
+ width?: number;
57
+ height?: number;
58
+ categories?: string[];
59
+ series?: Chart['series'];
60
+ }
61
+ /** A chart backed by the native `chart` element property (column/line/pie/…). */
62
+ export declare function createChartElement(type?: ChartType, options?: CreateChartElementOptions): Element;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mce",
3
3
  "type": "module",
4
- "version": "0.18.5",
4
+ "version": "0.19.0",
5
5
  "description": "A headless infinite canvas editor framework built on WebGL rendering, supports exporting to image, video, and PPT. Only the ESM.",
6
6
  "author": "wxm",
7
7
  "license": "MIT",
@@ -60,9 +60,9 @@
60
60
  "@vueuse/core": "^14.3.0",
61
61
  "diff": "^9.0.0",
62
62
  "lodash-es": "^4.18.1",
63
- "modern-canvas": "^0.19.1",
63
+ "modern-canvas": "^0.20.1",
64
64
  "modern-font": "^0.6.0",
65
- "modern-idoc": "^0.11.5",
65
+ "modern-idoc": "^0.11.8",
66
66
  "modern-text": "^2.0.3",
67
67
  "y-protocols": "^1.0.7",
68
68
  "yjs": "^13.6.30"