@plait/mind 0.23.1 → 0.24.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.
@@ -1,11 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Directive, Input, Component, ChangeDetectionStrategy, NgModule, NgZone, HostListener } from '@angular/core';
2
+ import { Component, ChangeDetectionStrategy, NgModule, NgZone, Directive, Input, HostListener } from '@angular/core';
3
3
  import * as i2 from '@plait/core';
4
- import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, RectangleClient, PlaitElement, PlaitPluginKey, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Path, PlaitBoard, depthFirstRecursion, getIsRecursionFunc, drawLinearPath, drawBezierPath, createG, updateForeignObject, drawRoundRectangle, getRectangleByElements, getSelectedElements, NODE_TO_PARENT, distanceBetweenPointAndRectangle, createForeignObject, createText, PlaitPointerType, PlaitPluginElementComponent, NODE_TO_INDEX, PlaitModule, isMainPointer, transformPoint, toPoint, getHitElements, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, BOARD_TO_HOST, throttleRAF, BoardTransforms, removeSelectedElement, PlaitHistoryBoard, hotkeys, PRESS_AND_MOVE_BUFFER, MERGING, ResizeCursorClass } from '@plait/core';
5
- import { MindLayoutType, isIndentedLayout, AbstractNode, getNonAbstractChildren, isStandardLayout, isLeftLayout, isRightLayout, isVerticalLogicLayout, isHorizontalLogicLayout, isTopLayout, isBottomLayout, isHorizontalLayout, getCorrectStartEnd, getAbstractLayout, ConnectingPosition, GlobalLayout } from '@plait/layouts';
4
+ import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, RectangleClient, PlaitElement, PlaitPluginKey, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, PlaitBoard, Path, PlaitNode, PlaitContextService, depthFirstRecursion, getIsRecursionFunc, drawLinearPath, drawBezierPath, createG, updateForeignObject, drawRoundRectangle, getRectangleByElements, getSelectedElements, NODE_TO_PARENT, distanceBetweenPointAndRectangle, createForeignObject, createText, PlaitPointerType, PlaitPluginElementComponent, NODE_TO_INDEX, PlaitModule, isMainPointer, transformPoint, toPoint, getHitElements, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, BOARD_TO_HOST, throttleRAF, BoardTransforms, removeSelectedElement, PlaitHistoryBoard, hotkeys, PRESS_AND_MOVE_BUFFER, MERGING, ResizeCursorClass } from '@plait/core';
5
+ import { MindLayoutType, isIndentedLayout, AbstractNode, isStandardLayout, isHorizontalLogicLayout, isVerticalLogicLayout, getNonAbstractChildren, isLeftLayout, isRightLayout, isTopLayout, isBottomLayout, isHorizontalLayout, getCorrectStartEnd, ConnectingPosition, getAbstractLayout, GlobalLayout } from '@plait/layouts';
6
6
  import { PlaitMarkEditor, MarkTypes, DEFAULT_FONT_SIZE, TEXT_DEFAULT_HEIGHT, buildText, getTextSize, TextManage, ExitOrigin, TextModule, getTextFromClipboard } from '@plait/text';
7
7
  import { fromEvent, Subject } from 'rxjs';
8
8
  import { Node as Node$1, Path as Path$1 } from 'slate';
9
+ import { __awaiter } from 'tslib';
9
10
  import { isKeyHotkey } from 'is-hotkey';
10
11
  import { pointsOnBezierCurves } from 'points-on-curve';
11
12
  import { take, filter } from 'rxjs/operators';
@@ -232,10 +233,10 @@ const NodeSpace = {
232
233
  return (NodeSpace.getEmojiLeftSpace(board, element) +
233
234
  getEmojisWidthHeight(board, element).width +
234
235
  getSpaceEmojiAndText(element) +
235
- NodeSpace.getNodeResizableWidth(board, element) +
236
+ NodeSpace.getNodeDynamicWidth(board, element) +
236
237
  nodeAndText);
237
238
  }
238
- return nodeAndText + NodeSpace.getNodeResizableWidth(board, element) + nodeAndText;
239
+ return nodeAndText + NodeSpace.getNodeDynamicWidth(board, element) + nodeAndText;
239
240
  },
240
241
  getNodeHeight(board, element) {
241
242
  const nodeAndText = getVerticalSpaceBetweenNodeAndText(board, element);
@@ -244,12 +245,23 @@ const NodeSpace = {
244
245
  }
245
246
  return nodeAndText + element.height + nodeAndText;
246
247
  },
247
- getNodeResizableWidth(board, element) {
248
+ getNodeDynamicWidth(board, element) {
248
249
  var _a;
249
250
  const width = element.manualWidth || element.width;
250
251
  const imageWidth = MindElement.hasImage(element) ? (_a = element.data.image) === null || _a === void 0 ? void 0 : _a.width : 0;
251
252
  return Math.max(width, imageWidth);
252
253
  },
254
+ /**
255
+ * use this when upload image first or resize image
256
+ * @param board
257
+ * @param element
258
+ * @param imageWidth
259
+ * @returns
260
+ */
261
+ getNodeNewDynamicWidth(board, element, imageWidth) {
262
+ const width = element.manualWidth || element.width;
263
+ return Math.max(width, imageWidth);
264
+ },
253
265
  getNodeResizableMinWidth(board, element) {
254
266
  const minTopicWidth = NodeSpace.getNodeTopicMinWidth(board, element);
255
267
  if (MindElement.hasImage(element) && element.data.image.width > minTopicWidth) {
@@ -349,7 +361,7 @@ function getTopicRectangleByNode(board, node) {
349
361
  function getTopicRectangleByElement(board, nodeRectangle, element) {
350
362
  const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
351
363
  const y = nodeRectangle.y + NodeSpace.getTextTopSpace(board, element);
352
- const width = NodeSpace.getNodeResizableWidth(board, element);
364
+ const width = NodeSpace.getNodeDynamicWidth(board, element);
353
365
  const height = Math.ceil(element.height);
354
366
  return { height, width, x, y };
355
367
  }
@@ -671,28 +683,6 @@ const adjustNodeToRoot = (board, node) => {
671
683
  return Object.assign(Object.assign({}, newElement), { layout: (_a = newElement.layout) !== null && _a !== void 0 ? _a : MindLayoutType.right, isRoot: true, type: 'mindmap' });
672
684
  };
673
685
 
674
- const BOARD_TO_SELECTED_IMAGE_ELEMENT = new WeakMap();
675
- const getSelectedImageElement = (board) => {
676
- return BOARD_TO_SELECTED_IMAGE_ELEMENT.get(board);
677
- };
678
- const addSelectedImageElement = (board, element) => {
679
- BOARD_TO_SELECTED_IMAGE_ELEMENT.set(board, element);
680
- };
681
- const removeSelectedImageElement = (board) => {
682
- BOARD_TO_SELECTED_IMAGE_ELEMENT.delete(board);
683
- };
684
- const setImageFocus = (board, element, isFocus) => {
685
- if (isFocus) {
686
- addSelectedImageElement(board, element);
687
- }
688
- else {
689
- removeSelectedImageElement(board);
690
- }
691
- const elementComponent = PlaitElement.getComponent(element);
692
- elementComponent.imageDrawer.componentRef.instance.isFocus = isFocus;
693
- elementComponent.imageDrawer.componentRef.instance.cdr.markForCheck();
694
- };
695
-
696
686
  const DefaultAbstractNodeStyle = {
697
687
  branch: { color: GRAY_COLOR, width: 2 },
698
688
  shape: {
@@ -711,8 +701,94 @@ const DefaultNodeStyle = {
711
701
  }
712
702
  };
713
703
 
714
- const getAvailableProperty = (board, element, propertyKey) => {
715
- return element[propertyKey];
704
+ const setAbstractsByRefs = (board, abstractRefs) => {
705
+ abstractRefs.forEach((newProperty, element) => {
706
+ const start = element.start + newProperty.start;
707
+ const end = element.end + newProperty.end;
708
+ const path = PlaitBoard.findPath(board, element);
709
+ if (start > end) {
710
+ Transforms.removeNode(board, path);
711
+ }
712
+ else {
713
+ Transforms.setNode(board, { start, end }, path);
714
+ }
715
+ });
716
+ };
717
+ const setAbstractByStandardLayout = (board, element) => {
718
+ const rightNodeCount = element.rightNodeCount;
719
+ const abstract = element.children.find(child => {
720
+ return AbstractNode.isAbstract(child) && child.end >= rightNodeCount && child.start < rightNodeCount;
721
+ });
722
+ if (abstract) {
723
+ const path = PlaitBoard.findPath(board, abstract);
724
+ Transforms.setNode(board, { end: rightNodeCount - 1 }, path);
725
+ }
726
+ };
727
+ const insertAbstract = (board, elements) => {
728
+ let elementGroup = getFirstLevelElement(elements);
729
+ const { parentElements, abstractIncludedGroups } = divideElementByParent(elementGroup);
730
+ abstractIncludedGroups.forEach((group, index) => {
731
+ const groupParent = parentElements[index];
732
+ setAbstractByElements(board, groupParent, group);
733
+ });
734
+ };
735
+ const setAbstractByElements = (board, groupParent, group) => {
736
+ const indexArray = group.map(child => groupParent.children.indexOf(child)).sort((a, b) => a - b);
737
+ const rightNodeCount = groupParent === null || groupParent === void 0 ? void 0 : groupParent.rightNodeCount;
738
+ const start = indexArray[0], end = indexArray[indexArray.length - 1];
739
+ if (isStandardLayout(MindQueries.getLayoutByElement(groupParent)) &&
740
+ rightNodeCount &&
741
+ start < rightNodeCount &&
742
+ end >= rightNodeCount) {
743
+ const childrenLength = groupParent.children.length;
744
+ const path = [...PlaitBoard.findPath(board, groupParent), childrenLength];
745
+ const leftChildren = indexArray.filter(index => index >= rightNodeCount);
746
+ const rightChildren = indexArray.filter(index => index < rightNodeCount);
747
+ insertAbstractNode(board, path, rightChildren[0], rightChildren[rightChildren.length - 1]);
748
+ insertAbstractNode(board, Path.next(path), leftChildren[0], leftChildren[leftChildren.length - 1]);
749
+ }
750
+ else {
751
+ const path = [...PlaitBoard.findPath(board, groupParent), groupParent.children.length];
752
+ insertAbstractNode(board, path, start, end);
753
+ }
754
+ };
755
+ const insertAbstractNode = (board, path, start, end) => {
756
+ const mindElement = createMindElement('概要', 28, 20, {
757
+ strokeWidth: DefaultAbstractNodeStyle.branch.width,
758
+ branchWidth: DefaultAbstractNodeStyle.branch.width
759
+ });
760
+ mindElement.start = start;
761
+ mindElement.end = end;
762
+ Transforms.insertNode(board, mindElement, path);
763
+ clearSelectedElement(board);
764
+ addSelectedElement(board, mindElement);
765
+ };
766
+
767
+ const setLayout = (board, layout, path) => {
768
+ correctLogicLayoutNode(board, layout, path);
769
+ const element = PlaitNode.get(board, path);
770
+ if (PlaitMind.isMind(element) && isStandardLayout(layout)) {
771
+ MindTransforms.setAbstractByStandardLayout(board, element);
772
+ }
773
+ Transforms.setNode(board, { layout }, path);
774
+ };
775
+ const correctLogicLayoutNode = (board, layout, path) => {
776
+ var _a;
777
+ const node = PlaitNode.get(board, path);
778
+ if (node && layout) {
779
+ (_a = node.children) === null || _a === void 0 ? void 0 : _a.forEach((value, index) => {
780
+ var _a;
781
+ if (value.layout) {
782
+ if ((isHorizontalLogicLayout(layout) && isVerticalLogicLayout(value.layout)) ||
783
+ (isVerticalLogicLayout(layout) && isHorizontalLogicLayout(value.layout))) {
784
+ Transforms.setNode(board, { layout: null }, [...path, index]);
785
+ }
786
+ if ((_a = value.children) === null || _a === void 0 ? void 0 : _a.length) {
787
+ correctLogicLayoutNode(board, layout, [...path, index]);
788
+ }
789
+ }
790
+ });
791
+ }
716
792
  };
717
793
 
718
794
  const separateChildren = (parentElement) => {
@@ -882,84 +958,324 @@ const isChildOfAbstract = (board, element) => {
882
958
  return !!ancestors.find((value) => AbstractNode.isAbstract(value));
883
959
  };
884
960
 
885
- /**
886
- * Processing of branch color, width, style, etc. of the mind node
887
- */
888
- const getBranchColorByMindElement = (board, element) => {
889
- if (AbstractNode.isAbstract(element) || isChildOfAbstract(board, element)) {
890
- return getAbstractBranchColor(board, element);
891
- }
892
- const branchColor = getAvailableProperty(board, element, 'branchColor');
893
- return branchColor || getDefaultBranchColor(board, element);
961
+ const normalizeWidthAndHeight = (board, element, width, height) => {
962
+ const minWidth = NodeSpace.getNodeTopicMinWidth(board, element, element.isRoot);
963
+ const newWidth = width < minWidth * board.viewport.zoom ? minWidth : width / board.viewport.zoom;
964
+ const newHeight = height / board.viewport.zoom;
965
+ return { width: newWidth, height: newHeight };
894
966
  };
895
- const getBranchShapeByMindElement = (board, element) => {
896
- const branchShape = getAvailableProperty(board, element, 'branchShape');
897
- return branchShape || BranchShape.bight;
967
+ const setTopic = (board, element, topic, width, height) => {
968
+ const newElement = Object.assign({ data: Object.assign(Object.assign({}, element.data), { topic }) }, normalizeWidthAndHeight(board, element, width, height));
969
+ const path = PlaitBoard.findPath(board, element);
970
+ Transforms.setNode(board, newElement, path);
898
971
  };
899
- const getBranchWidthByMindElement = (board, element) => {
900
- const branchWidth = getAvailableProperty(board, element, 'branchWidth');
901
- return branchWidth || BRANCH_WIDTH;
972
+ const setNodeManualWidth = (board, element, width, height) => {
973
+ const path = PlaitBoard.findPath(board, element);
974
+ const { width: normalizedWidth, height: normalizedHeight } = normalizeWidthAndHeight(board, element, width, height);
975
+ const newElement = { manualWidth: normalizedWidth, height: normalizedHeight };
976
+ Transforms.setNode(board, newElement, path);
902
977
  };
903
- const getAbstractBranchWidth = (board, element) => {
904
- if (!isNullOrUndefined(element.branchWidth)) {
905
- return element.branchWidth;
978
+ const setTopicSize = (board, element, width, height) => {
979
+ const newElement = Object.assign({}, normalizeWidthAndHeight(board, element, width, height));
980
+ let isEqualWidth = Math.ceil(element.width) === Math.ceil(newElement.width);
981
+ let isEqualHeight = Math.ceil(element.height) === Math.ceil(newElement.height);
982
+ if (element.manualWidth) {
983
+ isEqualWidth = true;
906
984
  }
907
- return DefaultAbstractNodeStyle.branch.width;
908
- };
909
- const getAbstractBranchColor = (board, element) => {
910
- if (element.branchColor) {
911
- return element.branchColor;
985
+ if (!isEqualWidth || !isEqualHeight) {
986
+ const path = PlaitBoard.findPath(board, element);
987
+ Transforms.setNode(board, newElement, path);
912
988
  }
913
- return DefaultAbstractNodeStyle.branch.color;
914
989
  };
915
- const getNextBranchColor = (board, root) => {
916
- const index = root.children.length;
917
- return getDefaultBranchColorByIndex(board, index);
990
+ const removeElements = (board, elements) => {
991
+ const deletableElements = getFirstLevelElement(elements);
992
+ deletableElements
993
+ .map(element => {
994
+ const path = PlaitBoard.findPath(board, element);
995
+ const ref = board.pathRef(path);
996
+ return () => {
997
+ Transforms.removeNode(board, ref.current);
998
+ ref.unref();
999
+ };
1000
+ })
1001
+ .forEach(action => {
1002
+ action();
1003
+ });
918
1004
  };
919
- const getDefaultBranchColor = (board, element) => {
920
- const path = PlaitBoard.findPath(board, element);
921
- return getDefaultBranchColorByIndex(board, path[1]);
1005
+ const insertNodes = (board, elements, path) => {
1006
+ const pathRef = board.pathRef(path);
1007
+ elements.forEach(element => {
1008
+ if (pathRef.current) {
1009
+ Transforms.insertNode(board, element, pathRef.current);
1010
+ }
1011
+ });
1012
+ pathRef.unref();
922
1013
  };
923
- const getDefaultBranchColorByIndex = (board, index) => {
924
- const themeColor = getMindThemeColor(board);
925
- const length = themeColor.branchColors.length;
926
- const remainder = index % length;
927
- return themeColor.branchColors[remainder];
1014
+ const insertAbstractNodes = (board, validAbstractRefs, elements, path) => {
1015
+ var _a;
1016
+ const parent = PlaitNode.get(board, Path$1.parent(path));
1017
+ const abstractPath = [...Path$1.parent(path), (_a = parent.children) === null || _a === void 0 ? void 0 : _a.length];
1018
+ const abstracts = validAbstractRefs.map(refs => {
1019
+ const { start, end } = getRelativeStartEndByAbstractRef(refs, elements);
1020
+ return Object.assign(Object.assign({}, refs.abstract), { start: start + path[path.length - 1], end: end + path[path.length - 1] });
1021
+ });
1022
+ insertNodes(board, abstracts, abstractPath);
928
1023
  };
929
- const getMindThemeColor = (board) => {
930
- const themeColors = PlaitBoard.getThemeColors(board);
931
- const themeColor = themeColors.find(val => val.mode === board.theme.themeColorMode);
932
- if (themeColor && MindThemeColor.isMindThemeColor(themeColor)) {
933
- return themeColor;
934
- }
935
- else {
936
- return MindDefaultThemeColor;
937
- }
1024
+ const setRightNodeCountByRefs = (board, refs) => {
1025
+ refs.forEach(ref => {
1026
+ Transforms.setNode(board, { rightNodeCount: ref.rightNodeCount }, ref.path);
1027
+ });
938
1028
  };
939
1029
 
940
- const getStrokeByMindElement = (board, element) => {
941
- if (PlaitMind.isMind(element)) {
942
- const defaultRootStroke = getMindThemeColor(board).rootFill;
943
- return element.strokeColor || defaultRootStroke;
944
- }
945
- if (AbstractNode.isAbstract(element) || isChildOfAbstract(board, element)) {
946
- return element.strokeColor || DefaultAbstractNodeStyle.shape.strokeColor;
947
- }
948
- return getAvailableProperty(board, element, 'strokeColor') || getDefaultBranchColor(board, element);
949
- };
950
- const getStrokeWidthByElement = (board, element) => {
951
- const strokeWidth = element.strokeWidth ||
952
- (AbstractNode.isAbstract(element) ? DefaultAbstractNodeStyle.shape.strokeWidth : DefaultNodeStyle.shape.strokeWidth);
953
- return strokeWidth;
1030
+ const addEmoji = (board, element, emojiItem) => {
1031
+ const emojis = element.data.emojis || [];
1032
+ const newEmojis = [...emojis];
1033
+ newEmojis.push(emojiItem);
1034
+ const newElement = {
1035
+ data: Object.assign(Object.assign({}, element.data), { emojis: newEmojis })
1036
+ };
1037
+ const path = PlaitBoard.findPath(board, element);
1038
+ Transforms.setNode(board, newElement, path);
954
1039
  };
955
- const getFillByElement = (board, element) => {
956
- if (element.fill) {
957
- return element.fill;
1040
+ const removeEmoji = (board, element, emojiItem) => {
1041
+ const emojis = element.data.emojis.filter(value => value !== emojiItem);
1042
+ const newElement = {
1043
+ data: { topic: element.data.topic }
1044
+ };
1045
+ if (MindElement.hasImage(element)) {
1046
+ newElement.data.image = element.data.image;
958
1047
  }
959
- const defaultRootFill = getMindThemeColor(board).rootFill;
960
- return element.isRoot ? defaultRootFill : DefaultNodeStyle.shape.fill;
1048
+ if (emojis.length > 0) {
1049
+ newElement.data.emojis = emojis;
1050
+ }
1051
+ const path = PlaitBoard.findPath(board, element);
1052
+ Transforms.setNode(board, newElement, path);
961
1053
  };
962
- const getShapeByElement = (board, element) => {
1054
+ const replaceEmoji = (board, element, oldEmoji, newEmoji) => {
1055
+ const newElement = {
1056
+ data: Object.assign({}, element.data)
1057
+ };
1058
+ const newEmojis = element.data.emojis.map(value => {
1059
+ if (value === oldEmoji) {
1060
+ return newEmoji;
1061
+ }
1062
+ return value;
1063
+ });
1064
+ newElement.data.emojis = newEmojis;
1065
+ const path = PlaitBoard.findPath(board, element);
1066
+ Transforms.setNode(board, newElement, path);
1067
+ };
1068
+
1069
+ /**
1070
+ * 1. return new node height if height changed
1071
+ * 2. new height is effected by zoom
1072
+ */
1073
+ const getNewNodeHeight = (board, element, newNodeDynamicWidth) => {
1074
+ const textManage = PlaitElement.getComponent(element).textManage;
1075
+ const { height } = textManage.getSize();
1076
+ textManage.updateWidth(newNodeDynamicWidth);
1077
+ const { height: newHeight } = textManage.getSize();
1078
+ if (!element.manualWidth) {
1079
+ textManage.updateWidth(0);
1080
+ }
1081
+ if (height !== newHeight) {
1082
+ return newHeight;
1083
+ }
1084
+ return undefined;
1085
+ };
1086
+
1087
+ const removeImage = (board, element) => {
1088
+ setImageFocus(board, element, false);
1089
+ const newElement = {
1090
+ data: Object.assign({}, element.data)
1091
+ };
1092
+ delete newElement.data.image;
1093
+ const path = PlaitBoard.findPath(board, element);
1094
+ const newDynamicWidth = NodeSpace.getNodeNewDynamicWidth(board, element, 0);
1095
+ const newHeight = getNewNodeHeight(board, element, newDynamicWidth);
1096
+ if (newHeight) {
1097
+ newElement.height = newHeight / board.viewport.zoom;
1098
+ }
1099
+ Transforms.setNode(board, newElement, path);
1100
+ };
1101
+ const setImage = (board, element, imageItem) => {
1102
+ const newElement = {
1103
+ data: Object.assign(Object.assign({}, element.data), { image: imageItem })
1104
+ };
1105
+ const newDynamicWidth = NodeSpace.getNodeNewDynamicWidth(board, element, imageItem.width);
1106
+ const newHeight = getNewNodeHeight(board, element, newDynamicWidth);
1107
+ if (newHeight) {
1108
+ newElement.height = newHeight / board.viewport.zoom;
1109
+ }
1110
+ const path = PlaitBoard.findPath(board, element);
1111
+ Transforms.setNode(board, newElement, path);
1112
+ };
1113
+
1114
+ const MindTransforms = {
1115
+ setLayout,
1116
+ setTopic,
1117
+ setTopicSize,
1118
+ setNodeManualWidth,
1119
+ addEmoji,
1120
+ removeEmoji,
1121
+ replaceEmoji,
1122
+ insertAbstract,
1123
+ setAbstractsByRefs,
1124
+ setAbstractByStandardLayout,
1125
+ removeElements,
1126
+ insertNodes,
1127
+ insertAbstractNodes,
1128
+ setRightNodeCountByRefs,
1129
+ removeImage,
1130
+ setImage
1131
+ };
1132
+
1133
+ const PICTURE_ACCEPTED_UPLOAD_SIZE = 20;
1134
+ const acceptImageTypes = ['png', 'jpeg', 'gif', 'bmp'];
1135
+ const DEFAULT_IMAGE_WIDTH = 240;
1136
+
1137
+ const BOARD_TO_SELECTED_IMAGE_ELEMENT = new WeakMap();
1138
+ const getSelectedImageElement = (board) => {
1139
+ return BOARD_TO_SELECTED_IMAGE_ELEMENT.get(board);
1140
+ };
1141
+ const addSelectedImageElement = (board, element) => {
1142
+ BOARD_TO_SELECTED_IMAGE_ELEMENT.set(board, element);
1143
+ };
1144
+ const removeSelectedImageElement = (board) => {
1145
+ BOARD_TO_SELECTED_IMAGE_ELEMENT.delete(board);
1146
+ };
1147
+ const setImageFocus = (board, element, isFocus) => {
1148
+ if (isFocus) {
1149
+ addSelectedImageElement(board, element);
1150
+ }
1151
+ else {
1152
+ removeSelectedImageElement(board);
1153
+ }
1154
+ const elementComponent = PlaitElement.getComponent(element);
1155
+ elementComponent.imageDrawer.componentRef.instance.isFocus = isFocus;
1156
+ elementComponent.imageDrawer.componentRef.instance.cdr.markForCheck();
1157
+ };
1158
+ const selectImage = (board, element, acceptImageTypes = ['png', 'jpeg', 'gif', 'bmp']) => {
1159
+ const inputFile = document.createElement('input');
1160
+ inputFile.setAttribute('type', 'file');
1161
+ const acceptImageTypesString = '.' + acceptImageTypes.join(',.');
1162
+ inputFile.setAttribute('accept', acceptImageTypesString);
1163
+ inputFile.onchange = (event) => {
1164
+ buildImage(board, element, event.target.files[0]);
1165
+ };
1166
+ inputFile.click();
1167
+ };
1168
+ const buildImage = (board, element, imageFile) => __awaiter(void 0, void 0, void 0, function* () {
1169
+ let width = 0, height = 0;
1170
+ yield getImageSize(imageFile).then((value) => {
1171
+ width = value.width;
1172
+ height = value.height;
1173
+ });
1174
+ let imageItem = null;
1175
+ const url = URL.createObjectURL(imageFile);
1176
+ const context = PlaitBoard.getComponent(board).viewContainerRef.injector.get(PlaitContextService);
1177
+ context.setUploadingFile({ url, file: imageFile });
1178
+ imageItem = {
1179
+ url,
1180
+ width,
1181
+ height
1182
+ };
1183
+ MindTransforms.setImage(board, element, imageItem);
1184
+ });
1185
+ function getImageSize(file, defaultImageWidth = DEFAULT_IMAGE_WIDTH) {
1186
+ return new Promise((resolve, reject) => {
1187
+ const image = new Image();
1188
+ image.src = URL.createObjectURL(file);
1189
+ image.onload = function () {
1190
+ const width = defaultImageWidth;
1191
+ const height = (defaultImageWidth * image.naturalHeight) / image.naturalWidth;
1192
+ resolve(image.naturalWidth > defaultImageWidth ? { width, height } : { width: image.naturalWidth, height: image.naturalHeight });
1193
+ };
1194
+ });
1195
+ }
1196
+
1197
+ const getAvailableProperty = (board, element, propertyKey) => {
1198
+ return element[propertyKey];
1199
+ };
1200
+
1201
+ /**
1202
+ * Processing of branch color, width, style, etc. of the mind node
1203
+ */
1204
+ const getBranchColorByMindElement = (board, element) => {
1205
+ if (AbstractNode.isAbstract(element) || isChildOfAbstract(board, element)) {
1206
+ return getAbstractBranchColor(board, element);
1207
+ }
1208
+ const branchColor = getAvailableProperty(board, element, 'branchColor');
1209
+ return branchColor || getDefaultBranchColor(board, element);
1210
+ };
1211
+ const getBranchShapeByMindElement = (board, element) => {
1212
+ const branchShape = getAvailableProperty(board, element, 'branchShape');
1213
+ return branchShape || BranchShape.bight;
1214
+ };
1215
+ const getBranchWidthByMindElement = (board, element) => {
1216
+ const branchWidth = getAvailableProperty(board, element, 'branchWidth');
1217
+ return branchWidth || BRANCH_WIDTH;
1218
+ };
1219
+ const getAbstractBranchWidth = (board, element) => {
1220
+ if (!isNullOrUndefined(element.branchWidth)) {
1221
+ return element.branchWidth;
1222
+ }
1223
+ return DefaultAbstractNodeStyle.branch.width;
1224
+ };
1225
+ const getAbstractBranchColor = (board, element) => {
1226
+ if (element.branchColor) {
1227
+ return element.branchColor;
1228
+ }
1229
+ return DefaultAbstractNodeStyle.branch.color;
1230
+ };
1231
+ const getNextBranchColor = (board, root) => {
1232
+ const index = root.children.length;
1233
+ return getDefaultBranchColorByIndex(board, index);
1234
+ };
1235
+ const getDefaultBranchColor = (board, element) => {
1236
+ const path = PlaitBoard.findPath(board, element);
1237
+ return getDefaultBranchColorByIndex(board, path[1]);
1238
+ };
1239
+ const getDefaultBranchColorByIndex = (board, index) => {
1240
+ const themeColor = getMindThemeColor(board);
1241
+ const length = themeColor.branchColors.length;
1242
+ const remainder = index % length;
1243
+ return themeColor.branchColors[remainder];
1244
+ };
1245
+ const getMindThemeColor = (board) => {
1246
+ const themeColors = PlaitBoard.getThemeColors(board);
1247
+ const themeColor = themeColors.find(val => val.mode === board.theme.themeColorMode);
1248
+ if (themeColor && MindThemeColor.isMindThemeColor(themeColor)) {
1249
+ return themeColor;
1250
+ }
1251
+ else {
1252
+ return MindDefaultThemeColor;
1253
+ }
1254
+ };
1255
+
1256
+ const getStrokeByMindElement = (board, element) => {
1257
+ if (PlaitMind.isMind(element)) {
1258
+ const defaultRootStroke = getMindThemeColor(board).rootFill;
1259
+ return element.strokeColor || defaultRootStroke;
1260
+ }
1261
+ if (AbstractNode.isAbstract(element) || isChildOfAbstract(board, element)) {
1262
+ return element.strokeColor || DefaultAbstractNodeStyle.shape.strokeColor;
1263
+ }
1264
+ return getAvailableProperty(board, element, 'strokeColor') || getDefaultBranchColor(board, element);
1265
+ };
1266
+ const getStrokeWidthByElement = (board, element) => {
1267
+ const strokeWidth = element.strokeWidth ||
1268
+ (AbstractNode.isAbstract(element) ? DefaultAbstractNodeStyle.shape.strokeWidth : DefaultNodeStyle.shape.strokeWidth);
1269
+ return strokeWidth;
1270
+ };
1271
+ const getFillByElement = (board, element) => {
1272
+ if (element.fill) {
1273
+ return element.fill;
1274
+ }
1275
+ const defaultRootFill = getMindThemeColor(board).rootFill;
1276
+ return element.isRoot ? defaultRootFill : DefaultNodeStyle.shape.fill;
1277
+ };
1278
+ const getShapeByElement = (board, element) => {
963
1279
  const shape = getAvailableProperty(board, element, 'shape');
964
1280
  return shape || MindElementShape.roundRectangle;
965
1281
  };
@@ -1810,6 +2126,73 @@ const deleteElementsHandleRightNodeCount = (board, deletableElements, effectedRi
1810
2126
  return effectedRightNodeCount;
1811
2127
  };
1812
2128
 
2129
+ const getLayoutOptions = (board) => {
2130
+ function getMainAxle(element, parent) {
2131
+ const strokeWidth = element.strokeWidth || STROKE_WIDTH;
2132
+ if (element.isRoot) {
2133
+ return BASE * 12;
2134
+ }
2135
+ if (parent && parent.isRoot()) {
2136
+ return BASE * 3 + strokeWidth / 2;
2137
+ }
2138
+ return BASE * 3 + strokeWidth / 2;
2139
+ }
2140
+ function getSecondAxle(element, parent) {
2141
+ const strokeWidth = element.strokeWidth || STROKE_WIDTH;
2142
+ if (element.isRoot) {
2143
+ return BASE * 10 + strokeWidth / 2;
2144
+ }
2145
+ return BASE * 6 + strokeWidth / 2;
2146
+ }
2147
+ return {
2148
+ getHeight(element) {
2149
+ return NodeSpace.getNodeHeight(board, element);
2150
+ },
2151
+ getWidth(element) {
2152
+ return NodeSpace.getNodeWidth(board, element);
2153
+ },
2154
+ getHorizontalGap(element, parent) {
2155
+ const _layout = (parent && parent.layout) || getRootLayout(element);
2156
+ const isHorizontal = isHorizontalLayout(_layout);
2157
+ const strokeWidth = element.strokeWidth || STROKE_WIDTH;
2158
+ if (isIndentedLayout(_layout)) {
2159
+ return BASE * 4 + strokeWidth;
2160
+ }
2161
+ if (!isHorizontal) {
2162
+ return getMainAxle(element, parent);
2163
+ }
2164
+ else {
2165
+ return getSecondAxle(element, parent);
2166
+ }
2167
+ },
2168
+ getVerticalGap(element, parent) {
2169
+ const _layout = (parent && parent.layout) || getRootLayout(element);
2170
+ if (isIndentedLayout(_layout)) {
2171
+ return BASE;
2172
+ }
2173
+ const isHorizontal = isHorizontalLayout(_layout);
2174
+ if (isHorizontal) {
2175
+ return getMainAxle(element, parent);
2176
+ }
2177
+ else {
2178
+ return getSecondAxle(element, parent);
2179
+ }
2180
+ },
2181
+ getVerticalConnectingPosition(element, parent) {
2182
+ if (element.shape === MindElementShape.underline && parent && isHorizontalLogicLayout(parent.layout)) {
2183
+ return ConnectingPosition.bottom;
2184
+ }
2185
+ return undefined;
2186
+ },
2187
+ getExtendHeight(node) {
2188
+ return BASE * 6;
2189
+ },
2190
+ getIndentedCrossLevelGap() {
2191
+ return BASE * 2;
2192
+ }
2193
+ };
2194
+ };
2195
+
1813
2196
  /**
1814
2197
  * get correctly layout:
1815
2198
  * 1. root is standard -> left or right
@@ -2106,307 +2489,84 @@ function drawAbstractLink(board, node, isHorizontal) {
2106
2489
  stroke: branchColor,
2107
2490
  strokeWidth: branchWidth
2108
2491
  });
2109
- g.appendChild(polyline);
2110
- g.appendChild(straightLine);
2111
- return g;
2112
- }
2113
- const link = PlaitBoard.getRoughSVG(board).path(`M${bezierBeginPoint[0]},${bezierBeginPoint[1]} Q${c1[0]},${c1[1]} ${bezierConnectorPoint[0]},${bezierConnectorPoint[1]} Q${c2[0]},${c2[1]} ${bezierEndPoint[0]},${bezierEndPoint[1]} M${abstractConnectorPoint[0]},${abstractConnectorPoint[1]} L${bezierConnectorPoint[0]},${bezierConnectorPoint[1]}`, {
2114
- stroke: branchColor,
2115
- strokeWidth: branchWidth
2116
- });
2117
- return link;
2118
- }
2119
-
2120
- class EmojiDrawer {
2121
- constructor(board, viewContainerRef) {
2122
- this.board = board;
2123
- this.viewContainerRef = viewContainerRef;
2124
- this.componentRef = null;
2125
- }
2126
- draw(emoji, element) {
2127
- this.destroy();
2128
- const componentType = this.board.drawEmoji(emoji, element);
2129
- this.componentRef = this.viewContainerRef.createComponent(componentType);
2130
- this.componentRef.instance.emojiItem = emoji;
2131
- this.componentRef.instance.board = this.board;
2132
- this.componentRef.instance.element = element;
2133
- this.componentRef.instance.fontSize = getEmojiFontSize(element);
2134
- }
2135
- get nativeElement() {
2136
- if (this.componentRef) {
2137
- return this.componentRef.instance.nativeElement;
2138
- }
2139
- else {
2140
- return null;
2141
- }
2142
- }
2143
- destroy() {
2144
- if (this.componentRef) {
2145
- this.componentRef.destroy();
2146
- this.componentRef = null;
2147
- }
2148
- }
2149
- }
2150
- class NodeEmojisDrawer {
2151
- constructor(board, viewContainerRef) {
2152
- this.board = board;
2153
- this.viewContainerRef = viewContainerRef;
2154
- this.emojiDrawers = [];
2155
- }
2156
- drawEmojis(element) {
2157
- this.destroy();
2158
- if (MindElement.hasEmojis(element)) {
2159
- this.g = createG();
2160
- this.g.classList.add('emojis');
2161
- const foreignRectangle = getEmojiForeignRectangle(this.board, element);
2162
- const foreignObject = createForeignObject(foreignRectangle.x, foreignRectangle.y, foreignRectangle.width, foreignRectangle.height);
2163
- this.g.append(foreignObject);
2164
- const container = document.createElement('div');
2165
- container.classList.add('node-emojis-container');
2166
- foreignObject.append(container);
2167
- this.emojiDrawers = element.data.emojis.map(emojiItem => {
2168
- const drawer = new EmojiDrawer(this.board, this.viewContainerRef);
2169
- drawer.draw(emojiItem, element);
2170
- return drawer;
2171
- });
2172
- this.emojiDrawers.forEach(drawer => {
2173
- container.append(drawer.nativeElement);
2174
- });
2175
- return this.g;
2176
- }
2177
- return undefined;
2178
- }
2179
- destroy() {
2180
- if (this.g) {
2181
- this.g.remove();
2182
- }
2183
- this.emojiDrawers.forEach(drawer => drawer.destroy());
2184
- this.emojiDrawers = [];
2185
- }
2186
- }
2187
-
2188
- const setAbstractsByRefs = (board, abstractRefs) => {
2189
- abstractRefs.forEach((newProperty, element) => {
2190
- const start = element.start + newProperty.start;
2191
- const end = element.end + newProperty.end;
2192
- const path = PlaitBoard.findPath(board, element);
2193
- if (start > end) {
2194
- Transforms.removeNode(board, path);
2195
- }
2196
- else {
2197
- Transforms.setNode(board, { start, end }, path);
2198
- }
2199
- });
2200
- };
2201
- const setAbstractByStandardLayout = (board, element) => {
2202
- const rightNodeCount = element.rightNodeCount;
2203
- const abstract = element.children.find(child => {
2204
- return AbstractNode.isAbstract(child) && child.end >= rightNodeCount && child.start < rightNodeCount;
2205
- });
2206
- if (abstract) {
2207
- const path = PlaitBoard.findPath(board, abstract);
2208
- Transforms.setNode(board, { end: rightNodeCount - 1 }, path);
2209
- }
2210
- };
2211
- const insertAbstract = (board, elements) => {
2212
- let elementGroup = getFirstLevelElement(elements);
2213
- const { parentElements, abstractIncludedGroups } = divideElementByParent(elementGroup);
2214
- abstractIncludedGroups.forEach((group, index) => {
2215
- const groupParent = parentElements[index];
2216
- setAbstractByElements(board, groupParent, group);
2217
- });
2218
- };
2219
- const setAbstractByElements = (board, groupParent, group) => {
2220
- const indexArray = group.map(child => groupParent.children.indexOf(child)).sort((a, b) => a - b);
2221
- const rightNodeCount = groupParent === null || groupParent === void 0 ? void 0 : groupParent.rightNodeCount;
2222
- const start = indexArray[0], end = indexArray[indexArray.length - 1];
2223
- if (isStandardLayout(MindQueries.getLayoutByElement(groupParent)) &&
2224
- rightNodeCount &&
2225
- start < rightNodeCount &&
2226
- end >= rightNodeCount) {
2227
- const childrenLength = groupParent.children.length;
2228
- const path = [...PlaitBoard.findPath(board, groupParent), childrenLength];
2229
- const leftChildren = indexArray.filter(index => index >= rightNodeCount);
2230
- const rightChildren = indexArray.filter(index => index < rightNodeCount);
2231
- insertAbstractNode(board, path, rightChildren[0], rightChildren[rightChildren.length - 1]);
2232
- insertAbstractNode(board, Path.next(path), leftChildren[0], leftChildren[leftChildren.length - 1]);
2233
- }
2234
- else {
2235
- const path = [...PlaitBoard.findPath(board, groupParent), groupParent.children.length];
2236
- insertAbstractNode(board, path, start, end);
2237
- }
2238
- };
2239
- const insertAbstractNode = (board, path, start, end) => {
2240
- const mindElement = createMindElement('概要', 28, 20, {
2241
- strokeWidth: DefaultAbstractNodeStyle.branch.width,
2242
- branchWidth: DefaultAbstractNodeStyle.branch.width
2243
- });
2244
- mindElement.start = start;
2245
- mindElement.end = end;
2246
- Transforms.insertNode(board, mindElement, path);
2247
- clearSelectedElement(board);
2248
- addSelectedElement(board, mindElement);
2249
- };
2250
-
2251
- const setLayout = (board, layout, path) => {
2252
- correctLogicLayoutNode(board, layout, path);
2253
- const element = PlaitNode.get(board, path);
2254
- if (PlaitMind.isMind(element) && isStandardLayout(layout)) {
2255
- MindTransforms.setAbstractByStandardLayout(board, element);
2256
- }
2257
- Transforms.setNode(board, { layout }, path);
2258
- };
2259
- const correctLogicLayoutNode = (board, layout, path) => {
2260
- var _a;
2261
- const node = PlaitNode.get(board, path);
2262
- if (node && layout) {
2263
- (_a = node.children) === null || _a === void 0 ? void 0 : _a.forEach((value, index) => {
2264
- var _a;
2265
- if (value.layout) {
2266
- if ((isHorizontalLogicLayout(layout) && isVerticalLogicLayout(value.layout)) ||
2267
- (isVerticalLogicLayout(layout) && isHorizontalLogicLayout(value.layout))) {
2268
- Transforms.setNode(board, { layout: null }, [...path, index]);
2269
- }
2270
- if ((_a = value.children) === null || _a === void 0 ? void 0 : _a.length) {
2271
- correctLogicLayoutNode(board, layout, [...path, index]);
2272
- }
2273
- }
2274
- });
2275
- }
2276
- };
2277
-
2278
- const normalizeWidthAndHeight = (board, element, width, height) => {
2279
- const minWidth = NodeSpace.getNodeTopicMinWidth(board, element, element.isRoot);
2280
- const newWidth = width < minWidth * board.viewport.zoom ? minWidth : width / board.viewport.zoom;
2281
- const newHeight = height / board.viewport.zoom;
2282
- return { width: newWidth, height: newHeight };
2283
- };
2284
- const setTopic = (board, element, topic, width, height) => {
2285
- const newElement = Object.assign({ data: Object.assign(Object.assign({}, element.data), { topic }) }, normalizeWidthAndHeight(board, element, width, height));
2286
- const path = PlaitBoard.findPath(board, element);
2287
- Transforms.setNode(board, newElement, path);
2288
- };
2289
- const setNodeManualWidth = (board, element, width, height) => {
2290
- const path = PlaitBoard.findPath(board, element);
2291
- const { width: normalizedWidth, height: normalizedHeight } = normalizeWidthAndHeight(board, element, width, height);
2292
- const newElement = { manualWidth: normalizedWidth, height: normalizedHeight };
2293
- Transforms.setNode(board, newElement, path);
2294
- };
2295
- const setTopicSize = (board, element, width, height) => {
2296
- const newElement = Object.assign({}, normalizeWidthAndHeight(board, element, width, height));
2297
- let isEqualWidth = Math.ceil(element.width) === Math.ceil(newElement.width);
2298
- let isEqualHeight = Math.ceil(element.height) === Math.ceil(newElement.height);
2299
- if (element.manualWidth) {
2300
- isEqualWidth = true;
2301
- }
2302
- if (!isEqualWidth || !isEqualHeight) {
2303
- const path = PlaitBoard.findPath(board, element);
2304
- Transforms.setNode(board, newElement, path);
2305
- }
2306
- };
2307
- const removeElements = (board, elements) => {
2308
- const deletableElements = getFirstLevelElement(elements);
2309
- deletableElements
2310
- .map(element => {
2311
- const path = PlaitBoard.findPath(board, element);
2312
- const ref = board.pathRef(path);
2313
- return () => {
2314
- Transforms.removeNode(board, ref.current);
2315
- ref.unref();
2316
- };
2317
- })
2318
- .forEach(action => {
2319
- action();
2320
- });
2321
- };
2322
- const insertNodes = (board, elements, path) => {
2323
- const pathRef = board.pathRef(path);
2324
- elements.forEach(element => {
2325
- if (pathRef.current) {
2326
- Transforms.insertNode(board, element, pathRef.current);
2327
- }
2328
- });
2329
- pathRef.unref();
2330
- };
2331
- const insertAbstractNodes = (board, validAbstractRefs, elements, path) => {
2332
- var _a;
2333
- const parent = PlaitNode.get(board, Path$1.parent(path));
2334
- const abstractPath = [...Path$1.parent(path), (_a = parent.children) === null || _a === void 0 ? void 0 : _a.length];
2335
- const abstracts = validAbstractRefs.map(refs => {
2336
- const { start, end } = getRelativeStartEndByAbstractRef(refs, elements);
2337
- return Object.assign(Object.assign({}, refs.abstract), { start: start + path[path.length - 1], end: end + path[path.length - 1] });
2338
- });
2339
- insertNodes(board, abstracts, abstractPath);
2340
- };
2341
- const setRightNodeCountByRefs = (board, refs) => {
2342
- refs.forEach(ref => {
2343
- Transforms.setNode(board, { rightNodeCount: ref.rightNodeCount }, ref.path);
2344
- });
2345
- };
2346
-
2347
- const addEmoji = (board, element, emojiItem) => {
2348
- const emojis = element.data.emojis || [];
2349
- const newEmojis = [...emojis];
2350
- newEmojis.push(emojiItem);
2351
- const newElement = {
2352
- data: Object.assign(Object.assign({}, element.data), { emojis: newEmojis })
2353
- };
2354
- const path = PlaitBoard.findPath(board, element);
2355
- Transforms.setNode(board, newElement, path);
2356
- };
2357
- const removeEmoji = (board, element, emojiItem) => {
2358
- const emojis = element.data.emojis.filter(value => value !== emojiItem);
2359
- const newElement = {
2360
- data: Object.assign({}, element.data)
2361
- };
2362
- if (emojis.length > 0) {
2363
- newElement.data.emojis = emojis;
2492
+ g.appendChild(polyline);
2493
+ g.appendChild(straightLine);
2494
+ return g;
2364
2495
  }
2365
- const path = PlaitBoard.findPath(board, element);
2366
- Transforms.setNode(board, newElement, path);
2367
- };
2368
- const replaceEmoji = (board, element, oldEmoji, newEmoji) => {
2369
- const newElement = {
2370
- data: Object.assign({}, element.data)
2371
- };
2372
- const newEmojis = element.data.emojis.map(value => {
2373
- if (value === oldEmoji) {
2374
- return newEmoji;
2375
- }
2376
- return value;
2496
+ const link = PlaitBoard.getRoughSVG(board).path(`M${bezierBeginPoint[0]},${bezierBeginPoint[1]} Q${c1[0]},${c1[1]} ${bezierConnectorPoint[0]},${bezierConnectorPoint[1]} Q${c2[0]},${c2[1]} ${bezierEndPoint[0]},${bezierEndPoint[1]} M${abstractConnectorPoint[0]},${abstractConnectorPoint[1]} L${bezierConnectorPoint[0]},${bezierConnectorPoint[1]}`, {
2497
+ stroke: branchColor,
2498
+ strokeWidth: branchWidth
2377
2499
  });
2378
- newElement.data.emojis = newEmojis;
2379
- const path = PlaitBoard.findPath(board, element);
2380
- Transforms.setNode(board, newElement, path);
2381
- };
2382
-
2383
- const removeImage = (board, element) => {
2384
- setImageFocus(board, element, false);
2385
- const newElement = {
2386
- data: Object.assign({}, element.data)
2387
- };
2388
- delete newElement.data.image;
2389
- const path = PlaitBoard.findPath(board, element);
2390
- Transforms.setNode(board, newElement, path);
2391
- };
2500
+ return link;
2501
+ }
2392
2502
 
2393
- const MindTransforms = {
2394
- setLayout,
2395
- setTopic,
2396
- setTopicSize,
2397
- setNodeManualWidth,
2398
- addEmoji,
2399
- removeEmoji,
2400
- replaceEmoji,
2401
- insertAbstract,
2402
- setAbstractsByRefs,
2403
- setAbstractByStandardLayout,
2404
- removeElements,
2405
- insertNodes,
2406
- insertAbstractNodes,
2407
- setRightNodeCountByRefs,
2408
- removeImage
2409
- };
2503
+ class EmojiDrawer {
2504
+ constructor(board, viewContainerRef) {
2505
+ this.board = board;
2506
+ this.viewContainerRef = viewContainerRef;
2507
+ this.componentRef = null;
2508
+ }
2509
+ draw(emoji, element) {
2510
+ this.destroy();
2511
+ const componentType = this.board.drawEmoji(emoji, element);
2512
+ this.componentRef = this.viewContainerRef.createComponent(componentType);
2513
+ this.componentRef.instance.emojiItem = emoji;
2514
+ this.componentRef.instance.board = this.board;
2515
+ this.componentRef.instance.element = element;
2516
+ this.componentRef.instance.fontSize = getEmojiFontSize(element);
2517
+ }
2518
+ get nativeElement() {
2519
+ if (this.componentRef) {
2520
+ return this.componentRef.instance.nativeElement;
2521
+ }
2522
+ else {
2523
+ return null;
2524
+ }
2525
+ }
2526
+ destroy() {
2527
+ if (this.componentRef) {
2528
+ this.componentRef.destroy();
2529
+ this.componentRef = null;
2530
+ }
2531
+ }
2532
+ }
2533
+ class NodeEmojisDrawer {
2534
+ constructor(board, viewContainerRef) {
2535
+ this.board = board;
2536
+ this.viewContainerRef = viewContainerRef;
2537
+ this.emojiDrawers = [];
2538
+ }
2539
+ drawEmojis(element) {
2540
+ this.destroy();
2541
+ if (MindElement.hasEmojis(element)) {
2542
+ this.g = createG();
2543
+ this.g.classList.add('emojis');
2544
+ const foreignRectangle = getEmojiForeignRectangle(this.board, element);
2545
+ const foreignObject = createForeignObject(foreignRectangle.x, foreignRectangle.y, foreignRectangle.width, foreignRectangle.height);
2546
+ this.g.append(foreignObject);
2547
+ const container = document.createElement('div');
2548
+ container.classList.add('node-emojis-container');
2549
+ foreignObject.append(container);
2550
+ this.emojiDrawers = element.data.emojis.map(emojiItem => {
2551
+ const drawer = new EmojiDrawer(this.board, this.viewContainerRef);
2552
+ drawer.draw(emojiItem, element);
2553
+ return drawer;
2554
+ });
2555
+ this.emojiDrawers.forEach(drawer => {
2556
+ container.append(drawer.nativeElement);
2557
+ });
2558
+ return this.g;
2559
+ }
2560
+ return undefined;
2561
+ }
2562
+ destroy() {
2563
+ if (this.g) {
2564
+ this.g.remove();
2565
+ }
2566
+ this.emojiDrawers.forEach(drawer => drawer.destroy());
2567
+ this.emojiDrawers = [];
2568
+ }
2569
+ }
2410
2570
 
2411
2571
  class BaseDrawer {
2412
2572
  constructor(board) {
@@ -2765,36 +2925,6 @@ class CollapseDrawer extends BaseDrawer {
2765
2925
  }
2766
2926
  }
2767
2927
 
2768
- class MindImageBaseComponent {
2769
- get nativeElement() {
2770
- return this.elementRef.nativeElement;
2771
- }
2772
- constructor(elementRef, cdr) {
2773
- this.elementRef = elementRef;
2774
- this.cdr = cdr;
2775
- this.isFocus = false;
2776
- }
2777
- ngOnInit() { }
2778
- }
2779
- MindImageBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindImageBaseComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
2780
- MindImageBaseComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: MindImageBaseComponent, inputs: { imageItem: "imageItem", board: "board", element: "element", isFocus: "isFocus" }, host: { classAttribute: "mind-node-image" }, ngImport: i0 });
2781
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindImageBaseComponent, decorators: [{
2782
- type: Directive,
2783
- args: [{
2784
- host: {
2785
- class: 'mind-node-image'
2786
- }
2787
- }]
2788
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { imageItem: [{
2789
- type: Input
2790
- }], board: [{
2791
- type: Input
2792
- }], element: [{
2793
- type: Input
2794
- }], isFocus: [{
2795
- type: Input
2796
- }] } });
2797
-
2798
2928
  class NodeImageDrawer {
2799
2929
  constructor(board, viewContainerRef) {
2800
2930
  this.board = board;
@@ -2808,9 +2938,9 @@ class NodeImageDrawer {
2808
2938
  }
2809
2939
  this.g = createG();
2810
2940
  const foreignRectangle = getImageForeignRectangle(this.board, element);
2811
- const foreignObject = createForeignObject(foreignRectangle.x, foreignRectangle.y, foreignRectangle.width, foreignRectangle.height);
2812
- this.g.append(foreignObject);
2813
- const componentType = this.board.getPluginOptions(WithMindPluginKey).imageComponentType || MindImageBaseComponent;
2941
+ this.foreignObject = createForeignObject(foreignRectangle.x, foreignRectangle.y, foreignRectangle.width, foreignRectangle.height);
2942
+ this.g.append(this.foreignObject);
2943
+ const componentType = this.board.getPluginOptions(WithMindPluginKey).imageComponentType;
2814
2944
  if (!componentType) {
2815
2945
  throw new Error('Not implement drawEmoji method error.');
2816
2946
  }
@@ -2819,7 +2949,7 @@ class NodeImageDrawer {
2819
2949
  this.componentRef.instance.element = element;
2820
2950
  this.componentRef.instance.imageItem = element.data.image;
2821
2951
  this.componentRef.instance.cdr.markForCheck();
2822
- foreignObject.append(this.componentRef.instance.nativeElement);
2952
+ this.foreignObject.append(this.componentRef.instance.nativeElement);
2823
2953
  nodeG.appendChild(this.g);
2824
2954
  }
2825
2955
  updateImage(nodeG, previous, current) {
@@ -2834,6 +2964,10 @@ class NodeImageDrawer {
2834
2964
  }
2835
2965
  const currentForeignObject = getImageForeignRectangle(this.board, current);
2836
2966
  updateForeignObject(this.g, currentForeignObject.width, currentForeignObject.height, currentForeignObject.x, currentForeignObject.y);
2967
+ // solve image lose on move node
2968
+ if (this.foreignObject.children.length === 0) {
2969
+ this.foreignObject.append(this.componentRef.instance.nativeElement);
2970
+ }
2837
2971
  (_a = this.componentRef) === null || _a === void 0 ? void 0 : _a.instance.cdr.markForCheck();
2838
2972
  }
2839
2973
  destroy() {
@@ -2997,13 +3131,17 @@ class MindNodeComponent extends PlaitPluginElementComponent {
2997
3131
  this.textManage.draw(this.element.data.topic);
2998
3132
  this.g.append(this.textManage.g);
2999
3133
  if (this.element.manualWidth) {
3000
- const width = NodeSpace.getNodeResizableWidth(this.board, this.element);
3134
+ const width = NodeSpace.getNodeDynamicWidth(this.board, this.element);
3001
3135
  this.textManage.updateWidth(width);
3002
3136
  }
3003
3137
  }
3004
3138
  updateTopic() {
3005
3139
  this.textManage.updateText(this.element.data.topic);
3006
3140
  this.textManage.updateRectangle();
3141
+ if (this.element.manualWidth) {
3142
+ const width = NodeSpace.getNodeDynamicWidth(this.board, this.element);
3143
+ this.textManage.updateWidth(width);
3144
+ }
3007
3145
  }
3008
3146
  editTopic() {
3009
3147
  this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: true });
@@ -3052,73 +3190,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
3052
3190
  }]
3053
3191
  }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
3054
3192
 
3055
- const getLayoutOptions = (board) => {
3056
- function getMainAxle(element, parent) {
3057
- const strokeWidth = element.strokeWidth || STROKE_WIDTH;
3058
- if (element.isRoot) {
3059
- return BASE * 12;
3060
- }
3061
- if (parent && parent.isRoot()) {
3062
- return BASE * 3 + strokeWidth / 2;
3063
- }
3064
- return BASE * 3 + strokeWidth / 2;
3065
- }
3066
- function getSecondAxle(element, parent) {
3067
- const strokeWidth = element.strokeWidth || STROKE_WIDTH;
3068
- if (element.isRoot) {
3069
- return BASE * 10 + strokeWidth / 2;
3070
- }
3071
- return BASE * 6 + strokeWidth / 2;
3072
- }
3073
- return {
3074
- getHeight(element) {
3075
- return NodeSpace.getNodeHeight(board, element);
3076
- },
3077
- getWidth(element) {
3078
- return NodeSpace.getNodeWidth(board, element);
3079
- },
3080
- getHorizontalGap(element, parent) {
3081
- const _layout = (parent && parent.layout) || getRootLayout(element);
3082
- const isHorizontal = isHorizontalLayout(_layout);
3083
- const strokeWidth = element.strokeWidth || STROKE_WIDTH;
3084
- if (isIndentedLayout(_layout)) {
3085
- return BASE * 4 + strokeWidth;
3086
- }
3087
- if (!isHorizontal) {
3088
- return getMainAxle(element, parent);
3089
- }
3090
- else {
3091
- return getSecondAxle(element, parent);
3092
- }
3093
- },
3094
- getVerticalGap(element, parent) {
3095
- const _layout = (parent && parent.layout) || getRootLayout(element);
3096
- if (isIndentedLayout(_layout)) {
3097
- return BASE;
3098
- }
3099
- const isHorizontal = isHorizontalLayout(_layout);
3100
- if (isHorizontal) {
3101
- return getMainAxle(element, parent);
3102
- }
3103
- else {
3104
- return getSecondAxle(element, parent);
3105
- }
3106
- },
3107
- getVerticalConnectingPosition(element, parent) {
3108
- if (element.shape === MindElementShape.underline && parent && isHorizontalLogicLayout(parent.layout)) {
3109
- return ConnectingPosition.bottom;
3110
- }
3111
- return undefined;
3112
- },
3113
- getExtendHeight(node) {
3114
- return BASE * 6;
3115
- },
3116
- getIndentedCrossLevelGap() {
3117
- return BASE * 2;
3118
- }
3119
- };
3120
- };
3121
-
3122
3193
  class PlaitMindComponent extends MindNodeComponent {
3123
3194
  ngOnInit() {
3124
3195
  this.updateMindLayout();
@@ -3845,7 +3916,7 @@ const withNodeHoverDetect = (board) => {
3845
3916
  };
3846
3917
 
3847
3918
  const withNodeImage = (board) => {
3848
- const { keydown, mousedown, globalMouseup } = board;
3919
+ const { keydown, mousedown, globalMouseup, insertFragment } = board;
3849
3920
  board.mousedown = (event) => {
3850
3921
  const selectedImageElement = getSelectedImageElement(board);
3851
3922
  if (PlaitBoard.isReadonly(board) || !isMainPointer(event) || !PlaitBoard.isPointer(board, PlaitPointerType.selection)) {
@@ -3871,7 +3942,6 @@ const withNodeImage = (board) => {
3871
3942
  if (hitImage) {
3872
3943
  temporaryDisableSelection(board);
3873
3944
  setImageFocus(board, hitElements[0], true);
3874
- clearSelectedElement(board);
3875
3945
  }
3876
3946
  mousedown(event);
3877
3947
  };
@@ -3895,6 +3965,21 @@ const withNodeImage = (board) => {
3895
3965
  }
3896
3966
  globalMouseup(event);
3897
3967
  };
3968
+ board.insertFragment = (data, targetPoint) => {
3969
+ const selectedElements = getSelectedElements(board);
3970
+ const isSelectedImage = !!getSelectedImageElement(board);
3971
+ const isSingleSelection = selectedElements.length === 1 && MindElement.isMindElement(board, selectedElements[0]);
3972
+ if ((data === null || data === void 0 ? void 0 : data.files.length) && (isSingleSelection || isSelectedImage)) {
3973
+ const selectedElement = (selectedElements[0] || getSelectedImageElement(board));
3974
+ const acceptImageArray = acceptImageTypes.map(type => 'image/' + type);
3975
+ if (acceptImageArray.includes(data === null || data === void 0 ? void 0 : data.files[0].type)) {
3976
+ const imageFile = data.files[0];
3977
+ buildImage(board, selectedElement, imageFile);
3978
+ return;
3979
+ }
3980
+ }
3981
+ insertFragment(data, targetPoint);
3982
+ };
3898
3983
  return board;
3899
3984
  };
3900
3985
 
@@ -3924,7 +4009,7 @@ const withNodeResize = (board) => {
3924
4009
  addResizing(board, targetElement);
3925
4010
  targetElementRef = {
3926
4011
  minWidth: NodeSpace.getNodeResizableMinWidth(board, targetElement),
3927
- currentWidth: NodeSpace.getNodeResizableWidth(board, targetElement),
4012
+ currentWidth: NodeSpace.getNodeDynamicWidth(board, targetElement),
3928
4013
  path: PlaitBoard.findPath(board, targetElement),
3929
4014
  textManage: PlaitElement.getComponent(targetElement).textManage
3930
4015
  };
@@ -3940,7 +4025,7 @@ const withNodeResize = (board) => {
3940
4025
  const offsetX = endPoint[0] - startPoint[0];
3941
4026
  const zoom = board.viewport.zoom;
3942
4027
  let resizedWidth = targetElementRef.currentWidth + offsetX / zoom;
3943
- if (resizedWidth < targetElementRef.minWidth) {
4028
+ if (resizedWidth <= targetElementRef.minWidth) {
3944
4029
  resizedWidth = targetElementRef.minWidth;
3945
4030
  }
3946
4031
  const newTarget = PlaitNode.get(board, targetElementRef.path);
@@ -4167,6 +4252,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
4167
4252
  args: ['mousedown']
4168
4253
  }] } });
4169
4254
 
4255
+ class MindImageBaseComponent {
4256
+ set imageItem(value) {
4257
+ this.afterImageItemChange(this._imageItem, value);
4258
+ this._imageItem = value;
4259
+ }
4260
+ get imageItem() {
4261
+ return this._imageItem;
4262
+ }
4263
+ get nativeElement() {
4264
+ return this.elementRef.nativeElement;
4265
+ }
4266
+ constructor(elementRef, cdr) {
4267
+ this.elementRef = elementRef;
4268
+ this.cdr = cdr;
4269
+ this.isFocus = false;
4270
+ }
4271
+ }
4272
+ MindImageBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindImageBaseComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
4273
+ MindImageBaseComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: MindImageBaseComponent, inputs: { imageItem: "imageItem", board: "board", element: "element", isFocus: "isFocus" }, host: { classAttribute: "mind-node-image" }, ngImport: i0 });
4274
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindImageBaseComponent, decorators: [{
4275
+ type: Directive,
4276
+ args: [{
4277
+ host: {
4278
+ class: 'mind-node-image'
4279
+ }
4280
+ }]
4281
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { imageItem: [{
4282
+ type: Input
4283
+ }], board: [{
4284
+ type: Input
4285
+ }], element: [{
4286
+ type: Input
4287
+ }], isFocus: [{
4288
+ type: Input
4289
+ }] } });
4290
+
4170
4291
  /*
4171
4292
  * Public API Surface of mind
4172
4293
  */
@@ -4175,5 +4296,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
4175
4296
  * Generated bundle index. Do not edit.
4176
4297
  */
4177
4298
 
4178
- export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_FONT_FAMILY, BRANCH_WIDTH, BaseDrawer, BranchShape, DEFAULT_FONT_FAMILY, DefaultAbstractNodeStyle, DefaultNodeStyle, ELEMENT_TO_NODE, EXTEND_DIAMETER, EXTEND_OFFSET, GRAY_COLOR, INHERIT_ATTRIBUTE_KEYS, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindColorfulThemeColor, MindDarkThemeColor, MindDefaultThemeColor, MindElement, MindElementShape, MindEmojiBaseComponent, MindImageBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindRetroThemeColor, MindSoftThemeColor, MindStarryThemeColor, MindThemeColor, MindThemeColors, MindTransforms, PRIMARY_COLOR, PlaitMind, PlaitMindComponent, QUICK_INSERT_CIRCLE_COLOR, QUICK_INSERT_CIRCLE_OFFSET, QUICK_INSERT_INNER_CROSS_COLOR, ROOT_TOPIC_FONT_SIZE, ROOT_TOPIC_HEIGHT, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, TRANSPARENT, WithMindPluginKey, addActiveOnDragOrigin, addSelectedImageElement, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, canSetAbstract, copyNewNode, correctLayoutByDirection, createDefaultMind, createEmptyMind, createMindElement, deleteElementHandleAbstract, deleteElementsHandleRightNodeCount, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNode, editTopic, extractNodesText, findLastChild, findLocationLeftIndex, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchShapeByMindElement, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getEmojiForeignRectangle, getEmojiRectangle, getFillByElement, getFirstLevelElement, getHitAbstractHandle, getImageForeignRectangle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getMindThemeColor, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getSelectedImageElement, getShapeByElement, getStrokeByMindElement, getStrokeWidthByElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildOfAbstract, isChildRight, isChildUp, isCorrectLayout, isDragging, isDropStandardRight, isHitEmojis, isHitImage, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, removeActiveOnDragOrigin, removeSelectedImageElement, separateChildren, setImageFocus, setIsDragging, temporaryDisableSelection, withMind, withMindExtend };
4299
+ export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_FONT_FAMILY, BRANCH_WIDTH, BaseDrawer, BranchShape, DEFAULT_FONT_FAMILY, DefaultAbstractNodeStyle, DefaultNodeStyle, ELEMENT_TO_NODE, EXTEND_DIAMETER, EXTEND_OFFSET, GRAY_COLOR, INHERIT_ATTRIBUTE_KEYS, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindColorfulThemeColor, MindDarkThemeColor, MindDefaultThemeColor, MindElement, MindElementShape, MindEmojiBaseComponent, MindImageBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindRetroThemeColor, MindSoftThemeColor, MindStarryThemeColor, MindThemeColor, MindThemeColors, MindTransforms, NodeSpace, PRIMARY_COLOR, PlaitMind, PlaitMindComponent, QUICK_INSERT_CIRCLE_COLOR, QUICK_INSERT_CIRCLE_OFFSET, QUICK_INSERT_INNER_CROSS_COLOR, ROOT_TOPIC_FONT_SIZE, ROOT_TOPIC_HEIGHT, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, TRANSPARENT, WithMindPluginKey, addActiveOnDragOrigin, addSelectedImageElement, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, buildImage, canSetAbstract, copyNewNode, correctLayoutByDirection, createDefaultMind, createEmptyMind, createMindElement, deleteElementHandleAbstract, deleteElementsHandleRightNodeCount, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNode, editTopic, extractNodesText, findLastChild, findLocationLeftIndex, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchShapeByMindElement, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getEmojiFontSize, getEmojiForeignRectangle, getEmojiRectangle, getEmojisWidthHeight, getFillByElement, getFirstLevelElement, getFontSizeBySlateElement, getHitAbstractHandle, getImageForeignRectangle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutOptions, getLayoutReverseDirection, getLocationScope, getMindThemeColor, getNewNodeHeight, getNextBranchColor, getNodeDefaultFontSize, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getSelectedImageElement, getShapeByElement, getStrokeByMindElement, getStrokeWidthByElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildOfAbstract, isChildRight, isChildUp, isCorrectLayout, isDragging, isDropStandardRight, isHitEmojis, isHitImage, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, removeActiveOnDragOrigin, removeSelectedImageElement, selectImage, separateChildren, setImageFocus, setIsDragging, temporaryDisableSelection, withMind, withMindExtend };
4179
4300
  //# sourceMappingURL=plait-mind.mjs.map