@plait/mind 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/drawer/{emoji.drawer.d.ts → emojis.drawer.d.ts} +2 -1
  2. package/esm2020/base/emoji-base.component.mjs +3 -3
  3. package/esm2020/drawer/emojis.drawer.mjs +73 -0
  4. package/esm2020/interfaces/element.mjs +6 -1
  5. package/esm2020/mind.component.mjs +3 -3
  6. package/esm2020/mind.module.mjs +4 -4
  7. package/esm2020/node.component.mjs +11 -15
  8. package/esm2020/plugins/with-abstract-resize.mjs +6 -2
  9. package/esm2020/plugins/with-mind-create.mjs +5 -4
  10. package/esm2020/plugins/with-mind.mjs +9 -4
  11. package/esm2020/plugins/with-node-dnd.mjs +13 -12
  12. package/esm2020/transforms/index.mjs +4 -3
  13. package/esm2020/transforms/node.mjs +11 -8
  14. package/esm2020/utils/dnd/common.mjs +29 -1
  15. package/esm2020/utils/dnd/detector.mjs +1 -7
  16. package/esm2020/utils/draw/abstract-outline.mjs +75 -0
  17. package/esm2020/utils/draw/node-dnd.mjs +133 -0
  18. package/esm2020/utils/draw/node-link/abstract-link.mjs +54 -0
  19. package/esm2020/utils/draw/node-link/draw-link.mjs +9 -0
  20. package/esm2020/utils/draw/node-link/indented-link.mjs +54 -0
  21. package/esm2020/utils/draw/node-link/logic-link.mjs +67 -0
  22. package/esm2020/utils/draw/node-shape.mjs +21 -0
  23. package/esm2020/utils/draw/node-topic.mjs +32 -0
  24. package/esm2020/utils/index.mjs +4 -2
  25. package/esm2020/utils/mind.mjs +2 -27
  26. package/esm2020/utils/node/common.mjs +6 -0
  27. package/esm2020/utils/node/index.mjs +4 -0
  28. package/esm2020/utils/node/right-node-count.mjs +45 -0
  29. package/esm2020/utils/node-style/branch.mjs +6 -1
  30. package/fesm2015/plait-mind.mjs +985 -911
  31. package/fesm2015/plait-mind.mjs.map +1 -1
  32. package/fesm2020/plait-mind.mjs +1005 -931
  33. package/fesm2020/plait-mind.mjs.map +1 -1
  34. package/interfaces/element.d.ts +5 -0
  35. package/node.component.d.ts +1 -1
  36. package/package.json +1 -1
  37. package/transforms/index.d.ts +1 -0
  38. package/transforms/node.d.ts +2 -0
  39. package/utils/dnd/common.d.ts +5 -1
  40. package/utils/dnd/detector.d.ts +0 -6
  41. package/{draw/abstract.d.ts → utils/draw/abstract-outline.d.ts} +2 -2
  42. package/utils/{dnd/draw.d.ts → draw/node-dnd.d.ts} +1 -5
  43. package/{draw/link → utils/draw/node-link}/abstract-link.d.ts +1 -1
  44. package/utils/draw/node-link/draw-link.d.ts +3 -0
  45. package/{draw → utils/draw/node-link}/indented-link.d.ts +1 -1
  46. package/utils/draw/node-link/logic-link.d.ts +3 -0
  47. package/{draw/node.d.ts → utils/draw/node-shape.d.ts} +2 -2
  48. package/{draw/topic.d.ts → utils/draw/node-topic.d.ts} +3 -3
  49. package/utils/index.d.ts +3 -1
  50. package/utils/mind.d.ts +0 -2
  51. package/utils/{node.d.ts → node/common.d.ts} +1 -1
  52. package/utils/node/index.d.ts +3 -0
  53. package/utils/node/right-node-count.d.ts +9 -0
  54. package/utils/node-style/branch.d.ts +1 -0
  55. package/draw/link/logic-link.d.ts +0 -3
  56. package/esm2020/draw/abstract.mjs +0 -75
  57. package/esm2020/draw/indented-link.mjs +0 -45
  58. package/esm2020/draw/link/abstract-link.mjs +0 -38
  59. package/esm2020/draw/link/logic-link.mjs +0 -54
  60. package/esm2020/draw/node.mjs +0 -21
  61. package/esm2020/draw/topic.mjs +0 -32
  62. package/esm2020/drawer/emoji.drawer.mjs +0 -73
  63. package/esm2020/utils/dnd/draw.mjs +0 -161
  64. package/esm2020/utils/node.mjs +0 -6
@@ -1,14 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Component, ChangeDetectionStrategy, NgModule, Directive, Input } from '@angular/core';
3
3
  import * as i2 from '@plait/core';
4
- import { PlaitBoard, PlaitNode, NODE_TO_PARENT, Path, distanceBetweenPointAndRectangle, RectangleClient, ELEMENT_TO_COMPONENT, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, PlaitElement, depthFirstRecursion, drawRoundRectangle, createG, getRectangleByElements, getSelectedElements, drawAbstractRoundRectangle, PlaitPluginElementComponent, PlaitPointerType, NODE_TO_INDEX, createText, IS_TEXT_EDITABLE, MERGING, transformPoint, toPoint, PlaitModule, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, BOARD_TO_HOST, throttleRAF, updateForeignObject as updateForeignObject$1, BoardTransforms, Selection, removeSelectedElement, PlaitHistoryBoard, hotkeys } from '@plait/core';
5
- import { MindLayoutType, AbstractNode, getAbstractLayout, isIndentedLayout, isStandardLayout, isLeftLayout, isRightLayout, getNonAbstractChildren, isTopLayout, isVerticalLogicLayout, isHorizontalLogicLayout, isBottomLayout, isHorizontalLayout, getCorrectStartEnd, ConnectingPosition, GlobalLayout } from '@plait/layouts';
4
+ import { distanceBetweenPointAndRectangle, RectangleClient, PlaitElement, PlaitBoard, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, depthFirstRecursion, Path, drawRoundRectangle, drawLinearPath, createG, PlaitNode, getRectangleByElements, getSelectedElements, NODE_TO_PARENT, drawAbstractRoundRectangle, PlaitPluginElementComponent, PlaitPointerType, NODE_TO_INDEX, createText, IS_TEXT_EDITABLE, MERGING, transformPoint, toPoint, PlaitModule, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, isMainPointer, BOARD_TO_HOST, throttleRAF, updateForeignObject as updateForeignObject$1, BoardTransforms, Selection, removeSelectedElement, PlaitHistoryBoard, hotkeys } from '@plait/core';
5
+ import { MindLayoutType, isIndentedLayout, getNonAbstractChildren, isStandardLayout, AbstractNode, isLeftLayout, isRightLayout, isTopLayout, isVerticalLogicLayout, isHorizontalLogicLayout, isBottomLayout, isHorizontalLayout, getCorrectStartEnd, getAbstractLayout, ConnectingPosition, GlobalLayout } from '@plait/layouts';
6
6
  import { getSizeByText, ROOT_DEFAULT_HEIGHT, TEXT_DEFAULT_HEIGHT, updateForeignObject, drawRichtext, createForeignObject, updateRichText, setFullSelectionAndFocus, getRichtextContentSize, hasEditableTarget, RichtextModule } from '@plait/richtext';
7
7
  import { fromEvent, Subject, timer } from 'rxjs';
8
8
  import { take, takeUntil, filter, debounceTime } from 'rxjs/operators';
9
9
  import { Node, Path as Path$1, Editor, Operation } from 'slate';
10
- import { pointsOnBezierCurves } from 'points-on-curve';
11
10
  import { isKeyHotkey } from 'is-hotkey';
11
+ import { pointsOnBezierCurves } from 'points-on-curve';
12
12
  import * as i1 from '@angular/common';
13
13
  import { CommonModule } from '@angular/common';
14
14
 
@@ -93,122 +93,310 @@ var MindPointerType;
93
93
  MindPointerType["mind"] = "mind";
94
94
  })(MindPointerType || (MindPointerType = {}));
95
95
 
96
- /**
97
- * get correctly layout:
98
- * 1. root is standard -> left or right
99
- * 2. correct layout by incorrect layout direction
100
- * @param element
101
- */
102
- const getCorrectLayoutByElement = (board, element) => {
103
- const ancestors = MindElement.getAncestors(board, element);
104
- ancestors.unshift(element);
105
- const root = ancestors[ancestors.length - 1];
106
- let rootLayout = getRootLayout(root);
107
- if (PlaitMind.isMind(element)) {
108
- return rootLayout;
109
- }
96
+ function getRectangleByNode(node) {
97
+ const x = node.x + node.hGap;
98
+ let y = node.y + node.vGap;
99
+ const width = node.width - node.hGap * 2;
100
+ const height = node.height - node.vGap * 2;
101
+ return {
102
+ x,
103
+ y,
104
+ width,
105
+ height
106
+ };
107
+ }
108
+ function getRectangleByElement(board, originPoint, element) {
109
+ const nodeRectangle = {
110
+ x: originPoint[0],
111
+ y: originPoint[1],
112
+ width: NodeSpace.getNodeWidth(board, element),
113
+ height: NodeSpace.getNodeHeight(board, element)
114
+ };
115
+ return nodeRectangle;
116
+ }
117
+ function isHitMindElement(board, point, element) {
110
118
  const node = MindElement.getNode(element);
111
- let correctRootLayout = rootLayout;
112
- if (rootLayout === MindLayoutType.standard) {
113
- correctRootLayout = node.left ? MindLayoutType.left : MindLayoutType.right;
119
+ if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
120
+ return true;
114
121
  }
115
- let layout = null;
116
- const elementWithLayout = ancestors.find(value => value.layout || AbstractNode.isAbstract(value));
117
- if (elementWithLayout) {
118
- if (AbstractNode.isAbstract(elementWithLayout)) {
119
- const parent = MindElement.getParent(elementWithLayout);
120
- const parentLayout = getCorrectLayoutByElement(board, parent);
121
- layout = getAbstractLayout(parentLayout);
122
- }
123
- else {
124
- layout = elementWithLayout === null || elementWithLayout === void 0 ? void 0 : elementWithLayout.layout;
125
- }
122
+ else {
123
+ return false;
126
124
  }
127
- if (layout === MindLayoutType.standard || !layout) {
128
- return correctRootLayout;
125
+ }
126
+
127
+ function getEmojisWidthHeight(board, element) {
128
+ const options = board.getMindOptions();
129
+ const count = element.data.emojis.length;
130
+ const fontSize = getEmojiFontSize(element);
131
+ return {
132
+ width: fontSize * count + count * 2 * options.emojiPadding + (count - 1) * options.spaceBetweenEmojis,
133
+ height: element.height
134
+ };
135
+ }
136
+ function getEmojiFontSize(element) {
137
+ if (PlaitMind.isMind(element)) {
138
+ return 18 + 2;
129
139
  }
130
140
  else {
131
- const incorrectDirection = getInCorrectLayoutDirection(correctRootLayout, layout);
132
- if (incorrectDirection) {
133
- return correctLayoutByDirection(layout, incorrectDirection);
134
- }
135
- else {
136
- return layout;
137
- }
141
+ return 14 + 2;
138
142
  }
143
+ }
144
+
145
+ function getEmojiRectangle(board, element) {
146
+ let { x, y } = getRectangleByNode(MindElement.getNode(element));
147
+ x = x + NodeSpace.getEmojiLeftSpace(board, element);
148
+ const { width, height } = getEmojisWidthHeight(board, element);
149
+ return {
150
+ x,
151
+ y,
152
+ width,
153
+ height
154
+ };
155
+ }
156
+ function getEmojiForeignRectangle(board, element) {
157
+ let { x, y } = getRectangleByNode(MindElement.getNode(element));
158
+ x = x + NodeSpace.getEmojiLeftSpace(board, element);
159
+ const { width, height } = getEmojisWidthHeight(board, element);
160
+ return {
161
+ x,
162
+ y,
163
+ width,
164
+ height: height + NodeSpace.getEmojiTopSpace(element) * 2
165
+ };
166
+ }
167
+ const isHitEmojis = (board, element, point) => {
168
+ return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), getEmojiRectangle(board, element));
139
169
  };
140
170
 
141
- const getBranchLayouts = (board, element) => {
142
- const layouts = [];
143
- if (element.layout) {
144
- // TODO: getCorrectLayoutByElement 含有递归操作,getBranchLayouts 本身也有递归操作,有待优化
145
- layouts.unshift(getCorrectLayoutByElement(board, element));
146
- }
147
- let parent = MindElement.findParent(element);
148
- while (parent) {
149
- if (parent.layout) {
150
- layouts.unshift(parent.layout);
151
- }
152
- parent = MindElement.findParent(parent);
171
+ function enterNodeEditing(element) {
172
+ const component = PlaitElement.getComponent(element);
173
+ component.startEditText(false, false);
174
+ }
175
+
176
+ const adjustRootToNode = (board, node) => {
177
+ const newNode = Object.assign({}, node);
178
+ delete newNode.isRoot;
179
+ delete newNode.rightNodeCount;
180
+ delete newNode.type;
181
+ const text = Node.string(node.data.topic.children[0]) || ' ';
182
+ const { width, height } = getSizeByText(text, PlaitBoard.getViewportContainer(board), TOPIC_DEFAULT_MAX_WORD_COUNT);
183
+ newNode.width = Math.max(width, NODE_MIN_WIDTH);
184
+ newNode.height = height;
185
+ if (newNode.layout === MindLayoutType.standard) {
186
+ delete newNode.layout;
153
187
  }
154
- return layouts;
188
+ return newNode;
155
189
  };
156
-
157
- const getAvailableSubLayoutsByElement = (board, element) => {
158
- const parentElement = MindElement.findParent(element);
159
- if (parentElement) {
160
- const branchLayouts = getBranchLayouts(board, parentElement);
161
- if (branchLayouts[0] === MindLayoutType.standard) {
162
- const node = MindElement.getNode(element);
163
- branchLayouts[0] = node.left ? MindLayoutType.left : MindLayoutType.right;
164
- }
165
- const currentLayoutDirections = getBranchDirectionsByLayouts(branchLayouts);
166
- let availableSubLayouts = getAvailableSubLayoutsByLayoutDirections(currentLayoutDirections);
167
- const parentLayout = [branchLayouts[branchLayouts.length - 1]];
168
- const parentDirections = getBranchDirectionsByLayouts(parentLayout);
169
- const parentAvailableSubLayouts = getAvailableSubLayoutsByLayoutDirections(parentDirections);
170
- availableSubLayouts = availableSubLayouts.filter(layout => parentAvailableSubLayouts.some(parentAvailableSubLayout => parentAvailableSubLayout === layout));
171
- return availableSubLayouts;
190
+ const adjustAbstractToNode = (node) => {
191
+ const newNode = Object.assign({}, node);
192
+ delete newNode.start;
193
+ delete newNode.end;
194
+ return newNode;
195
+ };
196
+ const adjustNodeToRoot = (board, node) => {
197
+ var _a;
198
+ const newElement = Object.assign({}, node);
199
+ let text = Node.string(newElement.data.topic);
200
+ if (!text) {
201
+ text = '思维导图';
202
+ newElement.data.topic = { children: [{ text }] };
172
203
  }
173
- return undefined;
204
+ newElement === null || newElement === void 0 ? true : delete newElement.strokeColor;
205
+ newElement === null || newElement === void 0 ? true : delete newElement.fill;
206
+ newElement === null || newElement === void 0 ? true : delete newElement.shape;
207
+ newElement === null || newElement === void 0 ? true : delete newElement.strokeWidth;
208
+ const { width, height } = getSizeByText(text, PlaitBoard.getViewportContainer(board), TOPIC_DEFAULT_MAX_WORD_COUNT, ROOT_TOPIC_FONT_SIZE);
209
+ newElement.width = Math.max(width, NODE_MIN_WIDTH);
210
+ newElement.height = height;
211
+ return Object.assign(Object.assign({}, newElement), { layout: (_a = newElement.layout) !== null && _a !== void 0 ? _a : MindLayoutType.right, isCollapsed: false, isRoot: true, type: 'mindmap' });
174
212
  };
175
213
 
176
- const getBranchDirectionsByLayouts = (branchLayouts) => {
177
- const branchDirections = [];
178
- branchLayouts.forEach(l => {
179
- const directions = LayoutDirectionsMap[l];
180
- directions.forEach(d => {
181
- if (!branchDirections.includes(d) && !branchDirections.includes(getLayoutReverseDirection(d))) {
182
- branchDirections.push(d);
183
- }
184
- });
185
- });
186
- return branchDirections;
187
- };
188
- const isCorrectLayout = (root, layout) => {
189
- const rootLayout = root.layout || getDefaultLayout();
190
- return !getInCorrectLayoutDirection(rootLayout, layout);
214
+ const createEmptyMind = (board, point) => {
215
+ const element = createMindElement('', 0, 0, { layout: MindLayoutType.right });
216
+ const rootElement = adjustNodeToRoot(board, element);
217
+ rootElement.points = [point];
218
+ return rootElement;
191
219
  };
192
- const isMixedLayout = (parentLayout, layout) => {
193
- return (!isIndentedLayout(parentLayout) && isIndentedLayout(layout)) || (isIndentedLayout(parentLayout) && !isIndentedLayout(layout));
220
+ const createDefaultMind = (point, rightNodeCount, layout) => {
221
+ const root = createMindElement('思维导图', 72, ROOT_DEFAULT_HEIGHT, { shape: MindElementShape.roundRectangle, layout });
222
+ root.rightNodeCount = rightNodeCount;
223
+ root.isRoot = true;
224
+ root.type = 'mindmap';
225
+ root.points = [point];
226
+ const children = [1, 1, 1].map(() => {
227
+ return createMindElement('新建节点', 56, TEXT_DEFAULT_HEIGHT, { shape: MindElementShape.roundRectangle });
228
+ });
229
+ root.children = children;
230
+ return root;
194
231
  };
195
- const getInCorrectLayoutDirection = (rootLayout, layout) => {
196
- const directions = LayoutDirectionsMap[rootLayout];
197
- const subLayoutDirections = LayoutDirectionsMap[layout];
198
- if (!subLayoutDirections) {
199
- throw new Error(`unexpected layout: ${layout} on correct layout`);
232
+ const createMindElement = (text, width, height, options) => {
233
+ const newElement = {
234
+ id: idCreator(),
235
+ data: {
236
+ topic: { children: [{ text }] }
237
+ },
238
+ children: [],
239
+ width,
240
+ height,
241
+ fill: options.fill,
242
+ strokeColor: options.strokeColor,
243
+ strokeWidth: options.strokeWidth,
244
+ shape: options.shape
245
+ };
246
+ if (options.fill) {
247
+ newElement.fill = options.fill;
200
248
  }
201
- return subLayoutDirections.find(d => directions.includes(getLayoutReverseDirection(d)));
249
+ if (options.strokeColor) {
250
+ newElement.strokeColor = options.strokeColor;
251
+ }
252
+ if (!isNullOrUndefined(options.strokeWidth)) {
253
+ newElement.strokeWidth = options.strokeWidth;
254
+ }
255
+ if (options.shape) {
256
+ newElement.shape = options.shape;
257
+ }
258
+ if (options.layout) {
259
+ newElement.layout = options.layout;
260
+ }
261
+ if (options.branchColor) {
262
+ newElement.branchColor = options.branchColor;
263
+ }
264
+ if (!isNullOrUndefined(options.branchWidth)) {
265
+ newElement.branchWidth = options.branchWidth;
266
+ }
267
+ return newElement;
202
268
  };
203
- const correctLayoutByDirection = (layout, direction) => {
204
- const isHorizontal = direction === LayoutDirection.left || direction === LayoutDirection.right ? true : false;
205
- let inverseDirectionLayout = MindLayoutType.standard;
206
- switch (layout) {
207
- case MindLayoutType.left:
208
- inverseDirectionLayout = MindLayoutType.right;
209
- break;
210
- case MindLayoutType.right:
211
- inverseDirectionLayout = MindLayoutType.left;
269
+
270
+ const getChildrenCount = (element) => {
271
+ const count = element.children.reduce((p, c) => {
272
+ return p + getChildrenCount(c);
273
+ }, 0);
274
+ return count + element.children.length;
275
+ };
276
+ const isChildElement = (origin, child) => {
277
+ let parent = MindElement.findParent(child);
278
+ while (parent) {
279
+ if (parent === origin) {
280
+ return true;
281
+ }
282
+ parent = MindElement.findParent(parent);
283
+ }
284
+ return false;
285
+ };
286
+ const getFirstLevelElement = (elements) => {
287
+ let result = [];
288
+ elements.forEach(element => {
289
+ const isChild = elements.some(node => {
290
+ return isChildElement(node, element);
291
+ });
292
+ if (!isChild) {
293
+ result.push(element);
294
+ }
295
+ });
296
+ return result;
297
+ };
298
+ const isChildRight = (node, child) => {
299
+ return node.x < child.x;
300
+ };
301
+ const isChildUp = (node, child) => {
302
+ return node.y > child.y;
303
+ };
304
+ const copyNewNode = (node) => {
305
+ const newNode = Object.assign({}, node);
306
+ newNode.id = idCreator();
307
+ newNode.children = [];
308
+ for (const childNode of node.children) {
309
+ newNode.children.push(copyNewNode(childNode));
310
+ }
311
+ return newNode;
312
+ };
313
+ const extractNodesText = (node) => {
314
+ let str = '';
315
+ if (node) {
316
+ str += Node.string(node.data.topic.children[0]) + ' ';
317
+ for (const childNode of node.children) {
318
+ str += extractNodesText(childNode);
319
+ }
320
+ }
321
+ return str;
322
+ };
323
+ // layoutLevel 用来表示插入兄弟节点还是子节点
324
+ const insertMindElement = (board, inheritNode, path) => {
325
+ let fill, strokeColor, strokeWidth, shape = MindElementShape.roundRectangle;
326
+ if (!inheritNode.isRoot) {
327
+ fill = inheritNode.fill;
328
+ strokeColor = inheritNode.strokeColor;
329
+ strokeWidth = inheritNode.strokeWidth;
330
+ }
331
+ shape = inheritNode.shape;
332
+ const newElement = createMindElement('', NODE_MIN_WIDTH, TEXT_DEFAULT_HEIGHT, { fill, strokeColor, strokeWidth, shape });
333
+ Transforms.insertNode(board, newElement, path);
334
+ clearSelectedElement(board);
335
+ addSelectedElement(board, newElement);
336
+ setTimeout(() => {
337
+ enterNodeEditing(newElement);
338
+ });
339
+ };
340
+ const findLastChild = (child) => {
341
+ let result = child;
342
+ while (result.children.length !== 0) {
343
+ result = result.children[result.children.length - 1];
344
+ }
345
+ return result;
346
+ };
347
+ const divideElementByParent = (elements) => {
348
+ const abstractIncludedGroups = [];
349
+ const parentElements = [];
350
+ for (let i = 0; i < elements.length; i++) {
351
+ const parent = MindElement.getParent(elements[i]);
352
+ const parentIndex = parentElements.indexOf(parent);
353
+ if (parentIndex === -1) {
354
+ parentElements.push(parent);
355
+ abstractIncludedGroups.push([elements[i]]);
356
+ }
357
+ else {
358
+ abstractIncludedGroups[parentIndex].push(elements[i]);
359
+ }
360
+ }
361
+ return { parentElements, abstractIncludedGroups };
362
+ };
363
+
364
+ const getBranchDirectionsByLayouts = (branchLayouts) => {
365
+ const branchDirections = [];
366
+ branchLayouts.forEach(l => {
367
+ const directions = LayoutDirectionsMap[l];
368
+ directions.forEach(d => {
369
+ if (!branchDirections.includes(d) && !branchDirections.includes(getLayoutReverseDirection(d))) {
370
+ branchDirections.push(d);
371
+ }
372
+ });
373
+ });
374
+ return branchDirections;
375
+ };
376
+ const isCorrectLayout = (root, layout) => {
377
+ const rootLayout = root.layout || getDefaultLayout();
378
+ return !getInCorrectLayoutDirection(rootLayout, layout);
379
+ };
380
+ const isMixedLayout = (parentLayout, layout) => {
381
+ return (!isIndentedLayout(parentLayout) && isIndentedLayout(layout)) || (isIndentedLayout(parentLayout) && !isIndentedLayout(layout));
382
+ };
383
+ const getInCorrectLayoutDirection = (rootLayout, layout) => {
384
+ const directions = LayoutDirectionsMap[rootLayout];
385
+ const subLayoutDirections = LayoutDirectionsMap[layout];
386
+ if (!subLayoutDirections) {
387
+ throw new Error(`unexpected layout: ${layout} on correct layout`);
388
+ }
389
+ return subLayoutDirections.find(d => directions.includes(getLayoutReverseDirection(d)));
390
+ };
391
+ const correctLayoutByDirection = (layout, direction) => {
392
+ const isHorizontal = direction === LayoutDirection.left || direction === LayoutDirection.right ? true : false;
393
+ let inverseDirectionLayout = MindLayoutType.standard;
394
+ switch (layout) {
395
+ case MindLayoutType.left:
396
+ inverseDirectionLayout = MindLayoutType.right;
397
+ break;
398
+ case MindLayoutType.right:
399
+ inverseDirectionLayout = MindLayoutType.left;
212
400
  break;
213
401
  case MindLayoutType.downward:
214
402
  inverseDirectionLayout = MindLayoutType.upward;
@@ -276,523 +464,44 @@ const getRootLayout = (root) => {
276
464
  return root.layout || getDefaultLayout();
277
465
  };
278
466
 
279
- const getLayoutByElement = (element) => {
280
- const layout = element.layout;
281
- if (layout) {
282
- return layout;
283
- }
284
- const parent = !PlaitMind.isMind(element) && MindElement.getParent(element);
285
- if (AbstractNode.isAbstract(element) && parent) {
286
- return getAbstractLayout(getLayoutByElement(parent));
467
+ const getAvailableProperty = (board, element, propertyKey) => {
468
+ const ancestors = MindElement.getAncestors(board, element);
469
+ ancestors.unshift(element);
470
+ const ancestor = ancestors.find(value => value[propertyKey]);
471
+ if (ancestor) {
472
+ return ancestor[propertyKey];
287
473
  }
288
- if (parent) {
289
- return getLayoutByElement(parent);
474
+ else {
475
+ return undefined;
290
476
  }
291
- return getDefaultLayout();
292
477
  };
293
478
 
294
- const MindQueries = {
295
- getAvailableSubLayoutsByElement,
296
- getBranchLayouts,
297
- getLayoutByElement,
298
- getCorrectLayoutByElement
479
+ /**
480
+ * Processing of branch color, width, style, etc. of the mind node
481
+ */
482
+ const getBranchColorByMindElement = (board, element) => {
483
+ const branchColor = getAvailableProperty(board, element, 'branchColor');
484
+ return branchColor || getDefaultBranchColor(board, element);
299
485
  };
300
-
301
- const PlaitMind = {
302
- isMind: (value) => {
303
- return value.type === 'mindmap';
486
+ const getBranchShapeByMindElement = (board, element) => {
487
+ const branchShape = getAvailableProperty(board, element, 'branchShape');
488
+ return branchShape || BranchShape.bight;
489
+ };
490
+ const getBranchWidthByMindElement = (board, element) => {
491
+ const branchWidth = getAvailableProperty(board, element, 'branchWidth');
492
+ return branchWidth || BRANCH_WIDTH;
493
+ };
494
+ const getAbstractBranchWidth = (board, element) => {
495
+ if (!isNullOrUndefined(element.branchWidth)) {
496
+ return element.branchWidth;
304
497
  }
498
+ return DefaultAbstractNodeStyle.branchWidth;
305
499
  };
306
- const MindElement = {
307
- hasLayout(value, layout) {
308
- const _layout = MindQueries.getLayoutByElement(value);
309
- return _layout === layout;
310
- },
311
- isIndentedLayout(value) {
312
- const _layout = MindQueries.getLayoutByElement(value);
313
- return isIndentedLayout(_layout);
314
- },
315
- isMindElement(board, element) {
316
- const path = PlaitBoard.findPath(board, element);
317
- const rootElement = PlaitNode.get(board, path.slice(0, 1));
318
- if (PlaitMind.isMind(rootElement)) {
319
- return true;
320
- }
321
- else {
322
- return false;
323
- }
324
- },
325
- getParent(node) {
326
- if (PlaitMind.isMind(node)) {
327
- throw new Error('mind root node can not get parent');
328
- }
329
- const parent = NODE_TO_PARENT.get(node);
330
- return parent;
331
- },
332
- findParent(node) {
333
- if (PlaitMind.isMind(node)) {
334
- return undefined;
335
- }
336
- const parent = NODE_TO_PARENT.get(node);
337
- return parent;
338
- },
339
- getRoot(board, element) {
340
- const path = PlaitBoard.findPath(board, element);
341
- return PlaitNode.get(board, path.slice(0, 1));
342
- },
343
- getAncestors(board, element) {
344
- const path = PlaitBoard.findPath(board, element);
345
- const parents = [];
346
- for (const p of Path.ancestors(path, { reverse: true })) {
347
- const n = PlaitNode.get(board, p);
348
- if (n && !PlaitBoard.isBoard(n)) {
349
- parents.push(n);
350
- }
351
- }
352
- return parents;
353
- },
354
- getNode(element) {
355
- const node = ELEMENT_TO_NODE.get(element);
356
- if (!node) {
357
- throw new Error(`can not get node from ${JSON.stringify(element)}`);
358
- }
359
- return node;
360
- },
361
- findParentNode(element) {
362
- if (PlaitMind.isMind(element)) {
363
- return undefined;
364
- }
365
- const parent = MindElement.getParent(element);
366
- return MindElement.getNode(parent);
367
- },
368
- hasEmojis(element) {
369
- if (element.data.emojis) {
370
- return true;
371
- }
372
- else {
373
- return false;
374
- }
375
- },
376
- getEmojis(element) {
377
- return element.data.emojis;
500
+ const getAbstractBranchColor = (board, element) => {
501
+ if (element.branchColor) {
502
+ return element.branchColor;
378
503
  }
379
- };
380
- var MindElementShape;
381
- (function (MindElementShape) {
382
- MindElementShape["roundRectangle"] = "round-rectangle";
383
- MindElementShape["underline"] = "underline";
384
- })(MindElementShape || (MindElementShape = {}));
385
-
386
- function getEmojisWidthHeight(board, element) {
387
- const options = board.getMindOptions();
388
- const count = element.data.emojis.length;
389
- const fontSize = getEmojiFontSize(element);
390
- return {
391
- width: fontSize * count + count * 2 * options.emojiPadding + (count - 1) * options.spaceBetweenEmojis,
392
- height: element.height
393
- };
394
- }
395
- function getEmojiFontSize(element) {
396
- if (PlaitMind.isMind(element)) {
397
- return 18 + 2;
398
- }
399
- else {
400
- return 14 + 2;
401
- }
402
- }
403
-
404
- const NodeDefaultSpace = {
405
- horizontal: {
406
- nodeAndText: BASE * 3,
407
- emojiAndText: BASE * 1.5
408
- },
409
- vertical: {
410
- nodeAndText: BASE * 1.5
411
- }
412
- };
413
- const RootDefaultSpace = {
414
- horizontal: {
415
- nodeAndText: BASE * 4,
416
- emojiAndText: BASE * 2
417
- },
418
- vertical: {
419
- nodeAndText: BASE * 2
420
- }
421
- };
422
- const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
423
- const isMind = PlaitMind.isMind(element);
424
- const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
425
- return nodeAndText;
426
- };
427
- const getVerticalSpaceBetweenNodeAndText = (element) => {
428
- const isMind = PlaitMind.isMind(element);
429
- const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
430
- return nodeAndText;
431
- };
432
- const getSpaceEmojiAndText = (element) => {
433
- const isMind = PlaitMind.isMind(element);
434
- const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
435
- return emojiAndText;
436
- };
437
- const NodeSpace = {
438
- getNodeWidth(board, element) {
439
- const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
440
- if (MindElement.hasEmojis(element)) {
441
- return (NodeSpace.getEmojiLeftSpace(board, element) +
442
- getEmojisWidthHeight(board, element).width +
443
- getSpaceEmojiAndText(element) +
444
- element.width +
445
- nodeAndText);
446
- }
447
- return nodeAndText + element.width + nodeAndText;
448
- },
449
- getNodeHeight(board, element) {
450
- const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
451
- return nodeAndText + element.height + nodeAndText;
452
- },
453
- getTextLeftSpace(board, element) {
454
- const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
455
- if (MindElement.hasEmojis(element)) {
456
- return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
457
- }
458
- else {
459
- return nodeAndText;
460
- }
461
- },
462
- getTextTopSpace(element) {
463
- const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
464
- return nodeAndText;
465
- },
466
- getEmojiLeftSpace(board, element) {
467
- const options = board.getMindOptions();
468
- const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
469
- return nodeAndText - options.emojiPadding;
470
- },
471
- getEmojiTopSpace(element) {
472
- const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
473
- return nodeAndText;
474
- }
475
- };
476
-
477
- function getRectangleByNode(node) {
478
- const x = node.x + node.hGap;
479
- let y = node.y + node.vGap;
480
- const width = node.width - node.hGap * 2;
481
- const height = node.height - node.vGap * 2;
482
- return {
483
- x,
484
- y,
485
- width,
486
- height
487
- };
488
- }
489
- function getRectangleByElement(board, originPoint, element) {
490
- const nodeRectangle = {
491
- x: originPoint[0],
492
- y: originPoint[1],
493
- width: NodeSpace.getNodeWidth(board, element),
494
- height: NodeSpace.getNodeHeight(board, element)
495
- };
496
- return nodeRectangle;
497
- }
498
- function isHitMindElement(board, point, element) {
499
- const node = MindElement.getNode(element);
500
- if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
501
- return true;
502
- }
503
- else {
504
- return false;
505
- }
506
- }
507
-
508
- function getEmojiRectangle(board, element) {
509
- let { x, y } = getRectangleByNode(MindElement.getNode(element));
510
- x = x + NodeSpace.getEmojiLeftSpace(board, element);
511
- const { width, height } = getEmojisWidthHeight(board, element);
512
- return {
513
- x,
514
- y,
515
- width,
516
- height
517
- };
518
- }
519
- function getEmojiForeignRectangle(board, element) {
520
- let { x, y } = getRectangleByNode(MindElement.getNode(element));
521
- x = x + NodeSpace.getEmojiLeftSpace(board, element);
522
- const { width, height } = getEmojisWidthHeight(board, element);
523
- return {
524
- x,
525
- y,
526
- width,
527
- height: height + NodeSpace.getEmojiTopSpace(element) * 2
528
- };
529
- }
530
- const isHitEmojis = (board, element, point) => {
531
- return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), getEmojiRectangle(board, element));
532
- };
533
-
534
- function getTopicRectangleByNode(board, node) {
535
- let nodeRectangle = getRectangleByNode(node);
536
- return getTopicRectangleByElement(board, nodeRectangle, node.origin);
537
- }
538
- function getTopicRectangleByElement(board, nodeRectangle, element) {
539
- const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
540
- const y = nodeRectangle.y + NodeSpace.getTextTopSpace(element);
541
- const width = Math.ceil(element.width);
542
- const height = Math.ceil(element.height);
543
- return { height, width, x, y };
544
- }
545
-
546
- function enterNodeEditing(element) {
547
- const component = ELEMENT_TO_COMPONENT.get(element);
548
- component.startEditText(false, false);
549
- }
550
-
551
- const adjustRootToNode = (board, node) => {
552
- const newNode = Object.assign({}, node);
553
- delete newNode.isRoot;
554
- delete newNode.rightNodeCount;
555
- delete newNode.type;
556
- const text = Node.string(node.data.topic.children[0]) || ' ';
557
- const { width, height } = getSizeByText(text, PlaitBoard.getViewportContainer(board), TOPIC_DEFAULT_MAX_WORD_COUNT);
558
- newNode.width = Math.max(width, NODE_MIN_WIDTH);
559
- newNode.height = height;
560
- if (newNode.layout === MindLayoutType.standard) {
561
- delete newNode.layout;
562
- }
563
- return newNode;
564
- };
565
- const adjustAbstractToNode = (node) => {
566
- const newNode = Object.assign({}, node);
567
- delete newNode.start;
568
- delete newNode.end;
569
- return newNode;
570
- };
571
- const adjustNodeToRoot = (board, node) => {
572
- var _a;
573
- const newElement = Object.assign({}, node);
574
- let text = Node.string(newElement.data.topic);
575
- if (!text) {
576
- text = '思维导图';
577
- newElement.data.topic = { children: [{ text }] };
578
- }
579
- newElement === null || newElement === void 0 ? true : delete newElement.strokeColor;
580
- newElement === null || newElement === void 0 ? true : delete newElement.fill;
581
- newElement === null || newElement === void 0 ? true : delete newElement.shape;
582
- newElement === null || newElement === void 0 ? true : delete newElement.strokeWidth;
583
- const { width, height } = getSizeByText(text, PlaitBoard.getViewportContainer(board), TOPIC_DEFAULT_MAX_WORD_COUNT, ROOT_TOPIC_FONT_SIZE);
584
- newElement.width = Math.max(width, NODE_MIN_WIDTH);
585
- newElement.height = height;
586
- return Object.assign(Object.assign({}, newElement), { layout: (_a = newElement.layout) !== null && _a !== void 0 ? _a : MindLayoutType.right, isCollapsed: false, isRoot: true, type: 'mindmap' });
587
- };
588
-
589
- const createEmptyMind = (board, point) => {
590
- const element = createMindElement('', 0, 0, { layout: MindLayoutType.right });
591
- const rootElement = adjustNodeToRoot(board, element);
592
- rootElement.points = [point];
593
- return rootElement;
594
- };
595
- const createDefaultMind = (point, rightNodeCount, layout) => {
596
- const root = createMindElement('思维导图', 72, ROOT_DEFAULT_HEIGHT, { shape: MindElementShape.roundRectangle, layout });
597
- root.rightNodeCount = rightNodeCount;
598
- root.isRoot = true;
599
- root.type = 'mindmap';
600
- root.points = [point];
601
- const children = [1, 1, 1].map(() => {
602
- return createMindElement('新建节点', 56, TEXT_DEFAULT_HEIGHT, { shape: MindElementShape.roundRectangle });
603
- });
604
- root.children = children;
605
- return root;
606
- };
607
- const createMindElement = (text, width, height, options) => {
608
- const newElement = {
609
- id: idCreator(),
610
- data: {
611
- topic: { children: [{ text }] }
612
- },
613
- children: [],
614
- width,
615
- height,
616
- fill: options.fill,
617
- strokeColor: options.strokeColor,
618
- strokeWidth: options.strokeWidth,
619
- shape: options.shape
620
- };
621
- if (options.fill) {
622
- newElement.fill = options.fill;
623
- }
624
- if (options.strokeColor) {
625
- newElement.strokeColor = options.strokeColor;
626
- }
627
- if (!isNullOrUndefined(options.strokeWidth)) {
628
- newElement.strokeWidth = options.strokeWidth;
629
- }
630
- if (options.shape) {
631
- newElement.shape = options.shape;
632
- }
633
- if (options.layout) {
634
- newElement.layout = options.layout;
635
- }
636
- if (options.branchColor) {
637
- newElement.branchColor = options.branchColor;
638
- }
639
- if (!isNullOrUndefined(options.branchWidth)) {
640
- newElement.branchWidth = options.branchWidth;
641
- }
642
- return newElement;
643
- };
644
-
645
- const getChildrenCount = (element) => {
646
- const count = element.children.reduce((p, c) => {
647
- return p + getChildrenCount(c);
648
- }, 0);
649
- return count + element.children.length;
650
- };
651
- const isChildElement = (origin, child) => {
652
- let parent = MindElement.findParent(child);
653
- while (parent) {
654
- if (parent === origin) {
655
- return true;
656
- }
657
- parent = MindElement.findParent(parent);
658
- }
659
- return false;
660
- };
661
- const getFirstLevelElement = (elements) => {
662
- let result = [];
663
- elements.forEach(element => {
664
- const isChild = elements.some(node => {
665
- return isChildElement(node, element);
666
- });
667
- if (!isChild) {
668
- result.push(element);
669
- }
670
- });
671
- return result;
672
- };
673
- const isChildRight = (node, child) => {
674
- return node.x < child.x;
675
- };
676
- const isChildUp = (node, child) => {
677
- return node.y > child.y;
678
- };
679
- const copyNewNode = (node) => {
680
- const newNode = Object.assign({}, node);
681
- newNode.id = idCreator();
682
- newNode.children = [];
683
- for (const childNode of node.children) {
684
- newNode.children.push(copyNewNode(childNode));
685
- }
686
- return newNode;
687
- };
688
- const extractNodesText = (node) => {
689
- let str = '';
690
- if (node) {
691
- str += Node.string(node.data.topic.children[0]) + ' ';
692
- for (const childNode of node.children) {
693
- str += extractNodesText(childNode);
694
- }
695
- }
696
- return str;
697
- };
698
- const changeRightNodeCount = (board, parentPath, changeNumber) => {
699
- const _rightNodeCount = board.children[parentPath[0]].rightNodeCount;
700
- Transforms.setNode(board, {
701
- rightNodeCount: changeNumber >= 0
702
- ? _rightNodeCount + changeNumber
703
- : _rightNodeCount + changeNumber < 0
704
- ? 0
705
- : _rightNodeCount + changeNumber
706
- }, parentPath);
707
- };
708
- const isInRightBranchOfStandardLayout = (selectedElement) => {
709
- const parentElement = MindElement.findParent(selectedElement);
710
- if (parentElement) {
711
- const nodeIndex = parentElement.children.findIndex(item => item.id === selectedElement.id);
712
- if (parentElement.isRoot &&
713
- getRootLayout(parentElement) === MindLayoutType.standard &&
714
- parentElement.rightNodeCount &&
715
- nodeIndex <= parentElement.rightNodeCount - 1) {
716
- return true;
717
- }
718
- }
719
- return false;
720
- };
721
- // layoutLevel 用来表示插入兄弟节点还是子节点
722
- const insertMindElement = (board, inheritNode, path) => {
723
- let fill, strokeColor, strokeWidth, shape = MindElementShape.roundRectangle;
724
- if (!inheritNode.isRoot) {
725
- fill = inheritNode.fill;
726
- strokeColor = inheritNode.strokeColor;
727
- strokeWidth = inheritNode.strokeWidth;
728
- }
729
- shape = inheritNode.shape;
730
- const newElement = createMindElement('', NODE_MIN_WIDTH, TEXT_DEFAULT_HEIGHT, { fill, strokeColor, strokeWidth, shape });
731
- Transforms.insertNode(board, newElement, path);
732
- clearSelectedElement(board);
733
- addSelectedElement(board, newElement);
734
- setTimeout(() => {
735
- enterNodeEditing(newElement);
736
- });
737
- };
738
- const findLastChild = (child) => {
739
- let result = child;
740
- while (result.children.length !== 0) {
741
- result = result.children[result.children.length - 1];
742
- }
743
- return result;
744
- };
745
- const divideElementByParent = (elements) => {
746
- const abstractIncludedGroups = [];
747
- const parentElements = [];
748
- for (let i = 0; i < elements.length; i++) {
749
- const parent = MindElement.getParent(elements[i]);
750
- const parentIndex = parentElements.indexOf(parent);
751
- if (parentIndex === -1) {
752
- parentElements.push(parent);
753
- abstractIncludedGroups.push([elements[i]]);
754
- }
755
- else {
756
- abstractIncludedGroups[parentIndex].push(elements[i]);
757
- }
758
- }
759
- return { parentElements, abstractIncludedGroups };
760
- };
761
-
762
- const getAvailableProperty = (board, element, propertyKey) => {
763
- const ancestors = MindElement.getAncestors(board, element);
764
- ancestors.unshift(element);
765
- const ancestor = ancestors.find(value => value[propertyKey]);
766
- if (ancestor) {
767
- return ancestor[propertyKey];
768
- }
769
- else {
770
- return undefined;
771
- }
772
- };
773
-
774
- /**
775
- * Processing of branch color, width, style, etc. of the mind node
776
- */
777
- const getBranchColorByMindElement = (board, element) => {
778
- const branchColor = getAvailableProperty(board, element, 'branchColor');
779
- return branchColor || getDefaultBranchColor(board, element);
780
- };
781
- const getBranchWidthByMindElement = (board, element) => {
782
- const branchWidth = getAvailableProperty(board, element, 'branchWidth');
783
- return branchWidth || BRANCH_WIDTH;
784
- };
785
- const getAbstractBranchWidth = (board, element) => {
786
- if (!isNullOrUndefined(element.branchWidth)) {
787
- return element.branchWidth;
788
- }
789
- return DefaultAbstractNodeStyle.branchWidth;
790
- };
791
- const getAbstractBranchColor = (board, element) => {
792
- if (element.branchColor) {
793
- return element.branchColor;
794
- }
795
- return DefaultAbstractNodeStyle.branchColor;
504
+ return DefaultAbstractNodeStyle.branchColor;
796
505
  };
797
506
  const getNextBranchColor = (root) => {
798
507
  const index = root.children.length;
@@ -870,13 +579,32 @@ const isDragging = (board) => {
870
579
  const setIsDragging = (board, state) => {
871
580
  IS_DRAGGING.set(board, state);
872
581
  };
582
+ const hasPreviousOrNextOfDropPath = (parent, target, dropPath) => {
583
+ const children = getNonAbstractChildren(parent);
584
+ let hasPreviousNode = dropPath[dropPath.length - 1] !== 0;
585
+ let hasNextNode = dropPath[dropPath.length - 1] !== ((children === null || children === void 0 ? void 0 : children.length) || 0);
586
+ if (PlaitMind.isMind(parent) && isStandardLayout(getRootLayout(parent))) {
587
+ const dropStandardRightBottom = target === parent.children[parent.rightNodeCount - 1] && dropPath[dropPath.length - 1] === parent.rightNodeCount;
588
+ const dropStandardLeftTop = target === parent.children[parent.rightNodeCount] && dropPath[dropPath.length - 1] === parent.rightNodeCount;
589
+ if (dropStandardRightBottom) {
590
+ hasPreviousNode = true;
591
+ hasNextNode = false;
592
+ }
593
+ if (dropStandardLeftTop) {
594
+ hasPreviousNode = false;
595
+ hasNextNode = true;
596
+ }
597
+ }
598
+ if (parent.isCollapsed) {
599
+ hasNextNode = false;
600
+ hasPreviousNode = false;
601
+ }
602
+ return {
603
+ hasPreviousNode,
604
+ hasNextNode
605
+ };
606
+ };
873
607
 
874
- /**
875
- *
876
- * @param targetNode
877
- * @param centerPoint
878
- * @returns DetectResult[] | null
879
- */
880
608
  const directionCorrector = (board, node, detectResults) => {
881
609
  if (!node.origin.isRoot && !AbstractNode.isAbstract(node.origin)) {
882
610
  const parentLayout = MindQueries.getCorrectLayoutByElement(board, node === null || node === void 0 ? void 0 : node.parent.origin);
@@ -1276,9 +1004,57 @@ const transformPlacement = (placement, direction) => {
1276
1004
  placement[1] = VerticalPlacement.bottom;
1277
1005
  }
1278
1006
  }
1279
- };
1007
+ };
1008
+
1009
+ function drawIndentedLink(board, node, child, defaultStroke = null, needDrawUnderline = true, defaultStrokeWidth) {
1010
+ const branchShape = getBranchShapeByMindElement(board, node.origin);
1011
+ const branchWidth = defaultStrokeWidth || getBranchWidthByMindElement(board, child.origin);
1012
+ const branchColor = defaultStroke || getBranchColorByMindElement(board, child.origin);
1013
+ const isUnderlineShape = getShapeByElement(board, child.origin) === MindElementShape.underline;
1014
+ let beginX, beginY, endX, endY, beginNode = node, endNode = child;
1015
+ const beginRectangle = getRectangleByNode(beginNode);
1016
+ const endRectangle = getRectangleByNode(endNode);
1017
+ beginX = beginNode.x + beginNode.width / 2;
1018
+ beginY = isChildUp(node, child) ? beginRectangle.y : beginRectangle.y + beginRectangle.height;
1019
+ endX = node.left ? endNode.x + endNode.hGap + endRectangle.width : endNode.x + endNode.hGap;
1020
+ endY = isUnderlineShape ? endNode.y + endNode.height - endNode.vGap : endNode.y + endNode.height / 2;
1021
+ //根据位置,设置正负参数
1022
+ let plusMinus = isChildUp(node, child) ? (node.left ? [-1, -1] : [1, -1]) : node.left ? [-1, 1] : [1, 1];
1023
+ const layout = MindQueries.getCorrectLayoutByElement(board, node.origin);
1024
+ if (beginNode.origin.isRoot) {
1025
+ if (layout === MindLayoutType.leftBottomIndented || layout === MindLayoutType.rightBottomIndented) {
1026
+ beginY += branchWidth;
1027
+ }
1028
+ if (layout === MindLayoutType.leftTopIndented || layout === MindLayoutType.rightTopIndented) {
1029
+ beginY -= branchWidth;
1030
+ }
1031
+ }
1032
+ let curve = [
1033
+ [beginX, beginY],
1034
+ [beginX, beginY],
1035
+ [beginX, beginY],
1036
+ [beginX, endY - (endNode.hGap * 3 * plusMinus[1]) / 5],
1037
+ [beginX, endY - (endNode.hGap * plusMinus[1]) / 5],
1038
+ [beginX + (endNode.hGap * plusMinus[0]) / 4, endY],
1039
+ [beginX + (endNode.hGap * plusMinus[0] * 3) / 5, endY],
1040
+ isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
1041
+ isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
1042
+ isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY]
1043
+ ];
1044
+ if (branchShape === BranchShape.polyline) {
1045
+ const polylinePoints = [
1046
+ [beginX, beginY],
1047
+ [beginX, endY],
1048
+ [endX, endY]
1049
+ ];
1050
+ return drawLinearPath(polylinePoints, { stroke: branchColor, strokeWidth: branchWidth });
1051
+ }
1052
+ const points = pointsOnBezierCurves(curve);
1053
+ return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
1054
+ }
1280
1055
 
1281
- function drawLogicLink(board, node, parent, isHorizontal, defaultStroke = null, defaultStrokeWidth) {
1056
+ function drawLogicLink(board, parent, node, isHorizontal, defaultStroke = null, defaultStrokeWidth) {
1057
+ const branchShape = getBranchShapeByMindElement(board, parent.origin);
1282
1058
  const branchColor = defaultStroke || getBranchColorByMindElement(board, node.origin);
1283
1059
  const branchWidth = defaultStrokeWidth || getBranchWidthByMindElement(board, node.origin);
1284
1060
  const hasStraightLine = !parent.origin.isRoot;
@@ -1322,9 +1098,27 @@ function drawLogicLink(board, node, parent, isHorizontal, defaultStroke = null,
1322
1098
  const underlineEnd = moveXOfPoint(endPoint, nodeClient.width, linkDirection);
1323
1099
  const underline = hasUnderlineShape && isHorizontal ? [underlineEnd, underlineEnd, underlineEnd] : [];
1324
1100
  const points = pointsOnBezierCurves([...straightLine, ...curve, ...underline]);
1101
+ if (branchShape === BranchShape.polyline) {
1102
+ const buffer = 8;
1103
+ const movePoint = moveXOfPoint(beginPoint2, buffer, linkDirection);
1104
+ const polylinePoints = [
1105
+ ...straightLine,
1106
+ movePoint,
1107
+ isHorizontal ? [movePoint[0], endPoint[1]] : [endPoint[0], movePoint[1]],
1108
+ endPoint,
1109
+ ...underline
1110
+ ];
1111
+ return drawLinearPath(polylinePoints, { stroke: branchColor, strokeWidth: branchWidth });
1112
+ }
1325
1113
  return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
1326
1114
  }
1327
1115
 
1116
+ function drawLink(board, parentNode, node, isHorizontal, needDrawUnderline, defaultStroke, defaultStrokeWidth) {
1117
+ return MindElement.isIndentedLayout(parentNode.origin)
1118
+ ? drawIndentedLink(board, parentNode, node, defaultStroke, needDrawUnderline, defaultStrokeWidth)
1119
+ : drawLogicLink(board, parentNode, node, isHorizontal, defaultStroke, defaultStrokeWidth);
1120
+ }
1121
+
1328
1122
  const drawFakeDragNode = (board, activeComponent, offsetX, offsetY) => {
1329
1123
  var _a;
1330
1124
  const dragFakeNodeG = createG();
@@ -1333,17 +1127,17 @@ const drawFakeDragNode = (board, activeComponent, offsetX, offsetY) => {
1333
1127
  const textRectangle = getTopicRectangleByNode(board, activeComponent.node);
1334
1128
  const fakeNodeG = drawRoundRectangleByNode(board, fakeDraggingNode);
1335
1129
  const richtextG = (_a = activeComponent.richtextG) === null || _a === void 0 ? void 0 : _a.cloneNode(true);
1336
- updateForeignObject(richtextG, textRectangle.width + BASE * 10, textRectangle.height, textRectangle.x + offsetX, textRectangle.y + offsetY);
1130
+ updateForeignObject(richtextG, textRectangle.width, textRectangle.height, textRectangle.x + offsetX, textRectangle.y + offsetY);
1337
1131
  dragFakeNodeG === null || dragFakeNodeG === void 0 ? void 0 : dragFakeNodeG.append(fakeNodeG);
1338
1132
  dragFakeNodeG === null || dragFakeNodeG === void 0 ? void 0 : dragFakeNodeG.append(richtextG);
1339
1133
  return dragFakeNodeG;
1340
1134
  };
1341
- const drawFakeDropNodeByPath = (board, target, path) => {
1135
+ const drawFakeDropNode = (board, target, path) => {
1342
1136
  const fakeDropNodeG = createG();
1343
1137
  const parent = PlaitNode.get(board, Path.parent(path));
1344
1138
  const layout = MindQueries.getLayoutByElement(parent);
1345
1139
  const isHorizontal = isHorizontalLayout(layout);
1346
- const { hasNextNode, hasPreviousNode } = getPreviousAndNextByPath(parent, target, path);
1140
+ const { hasNextNode, hasPreviousNode } = hasPreviousOrNextOfDropPath(parent, target, path);
1347
1141
  const width = 30;
1348
1142
  const height = 12;
1349
1143
  let fakeNode, centerPoint, basicNode, linkDirection;
@@ -1430,38 +1224,11 @@ const drawFakeDropNodeByPath = (board, target, path) => {
1430
1224
  fill: PRIMARY_COLOR,
1431
1225
  fillStyle: 'solid'
1432
1226
  });
1433
- const link = MindElement.isIndentedLayout(parent)
1434
- ? drawIndentedLink(board, MindElement.getNode(parent), fakeNode, PRIMARY_COLOR, false, STROKE_WIDTH)
1435
- : drawLogicLink(board, fakeNode, MindElement.getNode(parent), isHorizontal, PRIMARY_COLOR, STROKE_WIDTH);
1227
+ const link = drawLink(board, MindElement.getNode(parent), fakeNode, isHorizontal, false, PRIMARY_COLOR, STROKE_WIDTH);
1436
1228
  fakeDropNodeG === null || fakeDropNodeG === void 0 ? void 0 : fakeDropNodeG.appendChild(link);
1437
1229
  fakeDropNodeG === null || fakeDropNodeG === void 0 ? void 0 : fakeDropNodeG.appendChild(fakeRectangleG);
1438
1230
  return fakeDropNodeG;
1439
1231
  };
1440
- const getPreviousAndNextByPath = (parent, target, path) => {
1441
- const children = getNonAbstractChildren(parent);
1442
- let hasPreviousNode = path[path.length - 1] !== 0;
1443
- let hasNextNode = path[path.length - 1] !== ((children === null || children === void 0 ? void 0 : children.length) || 0);
1444
- if (PlaitMind.isMind(parent) && isStandardLayout(getRootLayout(parent))) {
1445
- const dropStandardRightBottom = target === parent.children[parent.rightNodeCount - 1] && path[path.length - 1] === parent.rightNodeCount;
1446
- const dropStandardLeftTop = target === parent.children[parent.rightNodeCount] && path[path.length - 1] === parent.rightNodeCount;
1447
- if (dropStandardRightBottom) {
1448
- hasPreviousNode = true;
1449
- hasNextNode = false;
1450
- }
1451
- if (dropStandardLeftTop) {
1452
- hasPreviousNode = false;
1453
- hasNextNode = true;
1454
- }
1455
- }
1456
- if (parent.isCollapsed) {
1457
- hasNextNode = false;
1458
- hasPreviousNode = false;
1459
- }
1460
- return {
1461
- hasPreviousNode,
1462
- hasNextNode
1463
- };
1464
- };
1465
1232
 
1466
1233
  const separateChildren = (parentElement) => {
1467
1234
  const rightNodeCount = parentElement.rightNodeCount;
@@ -1581,271 +1348,551 @@ isExtendPreviousNode = true, effectedAbstracts = new Map()) => {
1581
1348
  newProperties.end = newProperties.end + step;
1582
1349
  });
1583
1350
  }
1584
- if (!hasPreviousNode) {
1585
- return effectedAbstracts;
1351
+ if (!hasPreviousNode) {
1352
+ return effectedAbstracts;
1353
+ }
1354
+ const selectedElement = PlaitNode.get(board, Path.previous(path));
1355
+ const correspondingAbstract = getCorrespondingAbstract(selectedElement);
1356
+ const isDragToLast = !isExtendPreviousNode && correspondingAbstract && correspondingAbstract.end === path[path.length - 1] - 1;
1357
+ if (correspondingAbstract && !isDragToLast) {
1358
+ let newProperties = effectedAbstracts.get(correspondingAbstract);
1359
+ if (!newProperties) {
1360
+ newProperties = { start: 0, end: 0 };
1361
+ effectedAbstracts.set(correspondingAbstract, newProperties);
1362
+ }
1363
+ newProperties.end = newProperties.end + step;
1364
+ }
1365
+ return effectedAbstracts;
1366
+ };
1367
+ const deleteElementHandleAbstract = (board, deletableElements, effectedAbstracts = new Map()) => {
1368
+ deletableElements.forEach(node => {
1369
+ if (!PlaitMind.isMind(node)) {
1370
+ const behindAbstracts = getBehindAbstracts(node).filter(abstract => !deletableElements.includes(abstract));
1371
+ if (behindAbstracts.length) {
1372
+ behindAbstracts.forEach(abstract => {
1373
+ let newProperties = effectedAbstracts.get(abstract);
1374
+ if (!newProperties) {
1375
+ newProperties = { start: 0, end: 0 };
1376
+ effectedAbstracts.set(abstract, newProperties);
1377
+ }
1378
+ newProperties.start = newProperties.start - 1;
1379
+ newProperties.end = newProperties.end - 1;
1380
+ });
1381
+ }
1382
+ const correspondingAbstract = getCorrespondingAbstract(node);
1383
+ if (correspondingAbstract && !deletableElements.includes(correspondingAbstract)) {
1384
+ let newProperties = effectedAbstracts.get(correspondingAbstract);
1385
+ if (!newProperties) {
1386
+ newProperties = { start: 0, end: 0 };
1387
+ effectedAbstracts.set(correspondingAbstract, newProperties);
1388
+ }
1389
+ newProperties.end = newProperties.end - 1;
1390
+ }
1391
+ }
1392
+ });
1393
+ return effectedAbstracts;
1394
+ };
1395
+
1396
+ var AbstractHandlePosition;
1397
+ (function (AbstractHandlePosition) {
1398
+ AbstractHandlePosition["start"] = "start";
1399
+ AbstractHandlePosition["end"] = "end";
1400
+ })(AbstractHandlePosition || (AbstractHandlePosition = {}));
1401
+ var AbstractResizeState;
1402
+ (function (AbstractResizeState) {
1403
+ AbstractResizeState["start"] = "start";
1404
+ AbstractResizeState["resizing"] = "resizing";
1405
+ AbstractResizeState["end"] = "end";
1406
+ })(AbstractResizeState || (AbstractResizeState = {}));
1407
+
1408
+ const getRectangleByResizingLocation = (abstractRectangle, location, activeHandlePosition, isHorizontal) => {
1409
+ if (isHorizontal) {
1410
+ if (activeHandlePosition === AbstractHandlePosition.start) {
1411
+ return Object.assign(Object.assign({}, abstractRectangle), { y: location, height: abstractRectangle.height + abstractRectangle.y - location });
1412
+ }
1413
+ else {
1414
+ return Object.assign(Object.assign({}, abstractRectangle), { height: location - abstractRectangle.y });
1415
+ }
1416
+ }
1417
+ else {
1418
+ if (activeHandlePosition === AbstractHandlePosition.start) {
1419
+ return Object.assign(Object.assign({}, abstractRectangle), { x: location, width: abstractRectangle.width + abstractRectangle.x - location });
1420
+ }
1421
+ else {
1422
+ return Object.assign(Object.assign({}, abstractRectangle), { width: location - abstractRectangle.x });
1423
+ }
1424
+ }
1425
+ };
1426
+ const getLocationScope = (board, handlePosition, parentChildren, element, parent, isHorizontal) => {
1427
+ const node = MindElement.getNode(element);
1428
+ const { start, end } = getCorrectStartEnd(node.origin, parent);
1429
+ const startNode = parentChildren[start];
1430
+ const endNode = parentChildren[end];
1431
+ if (handlePosition === AbstractHandlePosition.start) {
1432
+ const abstractNode = parentChildren.filter(child => AbstractNode.isAbstract(child) && child.end < element.start);
1433
+ let minNode;
1434
+ if (abstractNode.length) {
1435
+ const index = abstractNode
1436
+ .map(node => {
1437
+ const { end } = getCorrectStartEnd(node, parent);
1438
+ return end;
1439
+ })
1440
+ .sort((a, b) => b - a)[0];
1441
+ minNode = parentChildren[index + 1];
1442
+ }
1443
+ else {
1444
+ minNode = parentChildren[0];
1445
+ }
1446
+ const minNodeRectangle = getRectangleByElements(board, [minNode], true);
1447
+ const endNodeRectangle = getRectangleByElements(board, [endNode], false);
1448
+ if (isHorizontal) {
1449
+ return {
1450
+ max: endNodeRectangle.y - ABSTRACT_INCLUDED_OUTLINE_OFFSET,
1451
+ min: minNodeRectangle.y - ABSTRACT_INCLUDED_OUTLINE_OFFSET
1452
+ };
1453
+ }
1454
+ else {
1455
+ return {
1456
+ max: endNodeRectangle.x - ABSTRACT_INCLUDED_OUTLINE_OFFSET,
1457
+ min: minNodeRectangle.x - ABSTRACT_INCLUDED_OUTLINE_OFFSET
1458
+ };
1459
+ }
1460
+ }
1461
+ else {
1462
+ const abstractNode = parentChildren.filter(child => AbstractNode.isAbstract(child) && child.start > element.end);
1463
+ let maxNode;
1464
+ if (abstractNode.length) {
1465
+ const index = abstractNode
1466
+ .map(node => {
1467
+ const { start } = getCorrectStartEnd(node, parent);
1468
+ return start;
1469
+ })
1470
+ .sort((a, b) => a - b)[0];
1471
+ maxNode = parentChildren[index - 1];
1472
+ }
1473
+ else {
1474
+ const children = parentChildren.filter(child => !AbstractNode.isAbstract(child));
1475
+ maxNode = parentChildren[children.length - 1];
1476
+ }
1477
+ const maxNodeRectangle = getRectangleByElements(board, [maxNode], true);
1478
+ const startNodeRectangle = getRectangleByElements(board, [startNode], false);
1479
+ if (isHorizontal) {
1480
+ return {
1481
+ max: maxNodeRectangle.y + maxNodeRectangle.height + ABSTRACT_INCLUDED_OUTLINE_OFFSET,
1482
+ min: startNodeRectangle.y + startNodeRectangle.height + ABSTRACT_INCLUDED_OUTLINE_OFFSET
1483
+ };
1484
+ }
1485
+ else {
1486
+ return {
1487
+ max: maxNodeRectangle.x + maxNodeRectangle.width + ABSTRACT_INCLUDED_OUTLINE_OFFSET,
1488
+ min: startNodeRectangle.x + startNodeRectangle.width + ABSTRACT_INCLUDED_OUTLINE_OFFSET
1489
+ };
1490
+ }
1491
+ }
1492
+ };
1493
+ const getHitAbstractHandle = (board, element, point) => {
1494
+ const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
1495
+ const isHorizontal = isHorizontalLayout(nodeLayout);
1496
+ const parentElement = MindElement.getParent(element);
1497
+ const includedElements = parentElement.children.slice(element.start, element.end + 1);
1498
+ let abstractRectangle = getRectangleByElements(board, includedElements, true);
1499
+ abstractRectangle = RectangleClient.getOutlineRectangle(abstractRectangle, -ABSTRACT_INCLUDED_OUTLINE_OFFSET);
1500
+ const startHandleRec = getAbstractHandleRectangle(abstractRectangle, isHorizontal, AbstractHandlePosition.start);
1501
+ const endHandleRec = getAbstractHandleRectangle(abstractRectangle, isHorizontal, AbstractHandlePosition.end);
1502
+ const pointRec = RectangleClient.toRectangleClient([point, point]);
1503
+ if (RectangleClient.isHit(pointRec, startHandleRec))
1504
+ return AbstractHandlePosition.start;
1505
+ if (RectangleClient.isHit(pointRec, endHandleRec))
1506
+ return AbstractHandlePosition.end;
1507
+ return undefined;
1508
+ };
1509
+ const getAbstractHandleRectangle = (rectangle, isHorizontal, position) => {
1510
+ let result;
1511
+ if (position === AbstractHandlePosition.start) {
1512
+ const location = isHorizontal ? rectangle.y : rectangle.x;
1513
+ result = getRectangleByResizingLocation(rectangle, location + ABSTRACT_HANDLE_MASK_WIDTH / 2, AbstractHandlePosition.end, isHorizontal);
1514
+ result = getRectangleByResizingLocation(result, location - ABSTRACT_HANDLE_MASK_WIDTH / 2, position, isHorizontal);
1515
+ }
1516
+ else {
1517
+ const location = isHorizontal ? rectangle.y + rectangle.height : rectangle.x + rectangle.width;
1518
+ result = getRectangleByResizingLocation(rectangle, location - ABSTRACT_HANDLE_MASK_WIDTH / 2, AbstractHandlePosition.start, isHorizontal);
1519
+ result = getRectangleByResizingLocation(result, location + ABSTRACT_HANDLE_MASK_WIDTH / 2, position, isHorizontal);
1520
+ }
1521
+ return result;
1522
+ };
1523
+ function findLocationLeftIndex(board, parentChildren, location, isHorizontal) {
1524
+ const children = parentChildren.filter(child => {
1525
+ return !AbstractNode.isAbstract(child);
1526
+ });
1527
+ const recArray = children.map(child => {
1528
+ return getRectangleByElements(board, [child], false);
1529
+ });
1530
+ const firstRec = getRectangleByElements(board, [children[0]], true);
1531
+ const fakeLeftRec = {
1532
+ x: firstRec.x - firstRec.width,
1533
+ y: firstRec.y - firstRec.height,
1534
+ width: firstRec.width,
1535
+ height: firstRec.height
1536
+ };
1537
+ const lastRec = getRectangleByElements(board, [children[children.length - 1]], true);
1538
+ const fakeRightRec = {
1539
+ x: lastRec.x + lastRec.width,
1540
+ y: lastRec.y + lastRec.height,
1541
+ width: lastRec.width,
1542
+ height: lastRec.height
1543
+ };
1544
+ recArray.push(fakeRightRec);
1545
+ recArray.unshift(fakeLeftRec);
1546
+ for (let i = 0; i < recArray.length - 1; i++) {
1547
+ const recXOrY = isHorizontal ? recArray[i].y : recArray[i].x;
1548
+ const recWidthOrHeight = isHorizontal ? recArray[i].height : recArray[i].width;
1549
+ if (location >= recXOrY + recWidthOrHeight / 2 &&
1550
+ location <= recArray[i + 1][isHorizontal ? 'y' : 'x'] + recArray[i + 1][isHorizontal ? 'height' : 'width'] / 2) {
1551
+ return i - 1;
1552
+ }
1553
+ }
1554
+ return 0;
1555
+ }
1556
+ function handleTouchedAbstract(board, touchedAbstract, endPoint) {
1557
+ let touchedHandle;
1558
+ const abstract = getSelectedElements(board)
1559
+ .filter(element => AbstractNode.isAbstract(element))
1560
+ .find(element => {
1561
+ touchedHandle = getHitAbstractHandle(board, element, endPoint);
1562
+ return touchedHandle;
1563
+ });
1564
+ if (touchedAbstract === abstract) {
1565
+ return touchedAbstract;
1566
+ }
1567
+ if (touchedAbstract) {
1568
+ const component = PlaitElement.getComponent(touchedAbstract);
1569
+ component.updateAbstractIncludedOutline();
1570
+ touchedAbstract = undefined;
1571
+ }
1572
+ if (abstract) {
1573
+ touchedAbstract = abstract;
1574
+ const component = PlaitElement.getComponent(touchedAbstract);
1575
+ component.updateAbstractIncludedOutline(touchedHandle);
1586
1576
  }
1587
- const selectedElement = PlaitNode.get(board, Path.previous(path));
1588
- const correspondingAbstract = getCorrespondingAbstract(selectedElement);
1589
- const isDragToLast = !isExtendPreviousNode && correspondingAbstract && correspondingAbstract.end === path[path.length - 1] - 1;
1590
- if (correspondingAbstract && !isDragToLast) {
1591
- let newProperties = effectedAbstracts.get(correspondingAbstract);
1592
- if (!newProperties) {
1593
- newProperties = { start: 0, end: 0 };
1594
- effectedAbstracts.set(correspondingAbstract, newProperties);
1577
+ return touchedAbstract;
1578
+ }
1579
+
1580
+ const isInRightBranchOfStandardLayout = (selectedElement) => {
1581
+ const parentElement = MindElement.findParent(selectedElement);
1582
+ if (parentElement) {
1583
+ const nodeIndex = parentElement.children.findIndex(item => item.id === selectedElement.id);
1584
+ if (parentElement.isRoot &&
1585
+ getRootLayout(parentElement) === MindLayoutType.standard &&
1586
+ parentElement.rightNodeCount &&
1587
+ nodeIndex <= parentElement.rightNodeCount - 1) {
1588
+ return true;
1595
1589
  }
1596
- newProperties.end = newProperties.end + step;
1597
1590
  }
1598
- return effectedAbstracts;
1591
+ return false;
1599
1592
  };
1600
- const deleteElementHandleAbstract = (board, deletableElements, effectedAbstracts = new Map()) => {
1601
- deletableElements.forEach(node => {
1602
- if (!PlaitMind.isMind(node)) {
1603
- const behindAbstracts = getBehindAbstracts(node).filter(abstract => !deletableElements.includes(abstract));
1604
- if (behindAbstracts.length) {
1605
- behindAbstracts.forEach(abstract => {
1606
- let newProperties = effectedAbstracts.get(abstract);
1607
- if (!newProperties) {
1608
- newProperties = { start: 0, end: 0 };
1609
- effectedAbstracts.set(abstract, newProperties);
1610
- }
1611
- newProperties.start = newProperties.start - 1;
1612
- newProperties.end = newProperties.end - 1;
1613
- });
1593
+ const insertElementHandleRightNodeCount = (board, path, insertCount, effectedRightNodeCount = []) => {
1594
+ let index = effectedRightNodeCount.findIndex(ref => Path.equals(ref.path, path));
1595
+ const mind = PlaitNode.get(board, path);
1596
+ if (index === -1) {
1597
+ effectedRightNodeCount.push({ path, rightNodeCount: mind.rightNodeCount + insertCount });
1598
+ }
1599
+ else {
1600
+ effectedRightNodeCount[index].rightNodeCount += insertCount;
1601
+ }
1602
+ return effectedRightNodeCount;
1603
+ };
1604
+ const deleteElementsHandleRightNodeCount = (board, deletableElements, effectedRightNodeCount = []) => {
1605
+ deletableElements.forEach(element => {
1606
+ if (isInRightBranchOfStandardLayout(element)) {
1607
+ const mind = MindElement.getParent(element);
1608
+ const path = PlaitBoard.findPath(board, mind);
1609
+ let index = effectedRightNodeCount.findIndex(ref => Path.equals(ref.path, path));
1610
+ if (index === -1) {
1611
+ effectedRightNodeCount.push({ path, rightNodeCount: mind.rightNodeCount - 1 });
1614
1612
  }
1615
- const correspondingAbstract = getCorrespondingAbstract(node);
1616
- if (correspondingAbstract && !deletableElements.includes(correspondingAbstract)) {
1617
- let newProperties = effectedAbstracts.get(correspondingAbstract);
1618
- if (!newProperties) {
1619
- newProperties = { start: 0, end: 0 };
1620
- effectedAbstracts.set(correspondingAbstract, newProperties);
1621
- }
1622
- newProperties.end = newProperties.end - 1;
1613
+ else {
1614
+ effectedRightNodeCount[index].rightNodeCount -= 1;
1623
1615
  }
1624
1616
  }
1625
1617
  });
1626
- return effectedAbstracts;
1618
+ return effectedRightNodeCount;
1627
1619
  };
1628
1620
 
1629
- var AbstractHandlePosition;
1630
- (function (AbstractHandlePosition) {
1631
- AbstractHandlePosition["start"] = "start";
1632
- AbstractHandlePosition["end"] = "end";
1633
- })(AbstractHandlePosition || (AbstractHandlePosition = {}));
1634
- var AbstractResizeState;
1635
- (function (AbstractResizeState) {
1636
- AbstractResizeState["start"] = "start";
1637
- AbstractResizeState["resizing"] = "resizing";
1638
- AbstractResizeState["end"] = "end";
1639
- })(AbstractResizeState || (AbstractResizeState = {}));
1640
-
1641
- const getRectangleByResizingLocation = (abstractRectangle, location, activeHandlePosition, isHorizontal) => {
1642
- if (isHorizontal) {
1643
- if (activeHandlePosition === AbstractHandlePosition.start) {
1644
- return Object.assign(Object.assign({}, abstractRectangle), { y: location, height: abstractRectangle.height + abstractRectangle.y - location });
1621
+ /**
1622
+ * get correctly layout:
1623
+ * 1. root is standard -> left or right
1624
+ * 2. correct layout by incorrect layout direction
1625
+ * @param element
1626
+ */
1627
+ const getCorrectLayoutByElement = (board, element) => {
1628
+ const ancestors = MindElement.getAncestors(board, element);
1629
+ ancestors.unshift(element);
1630
+ const root = ancestors[ancestors.length - 1];
1631
+ let rootLayout = getRootLayout(root);
1632
+ if (PlaitMind.isMind(element)) {
1633
+ return rootLayout;
1634
+ }
1635
+ const node = MindElement.getNode(element);
1636
+ let correctRootLayout = rootLayout;
1637
+ if (rootLayout === MindLayoutType.standard) {
1638
+ correctRootLayout = node.left ? MindLayoutType.left : MindLayoutType.right;
1639
+ }
1640
+ let layout = null;
1641
+ const elementWithLayout = ancestors.find(value => value.layout || AbstractNode.isAbstract(value));
1642
+ if (elementWithLayout) {
1643
+ if (AbstractNode.isAbstract(elementWithLayout)) {
1644
+ const parent = MindElement.getParent(elementWithLayout);
1645
+ const parentLayout = getCorrectLayoutByElement(board, parent);
1646
+ layout = getAbstractLayout(parentLayout);
1645
1647
  }
1646
1648
  else {
1647
- return Object.assign(Object.assign({}, abstractRectangle), { height: location - abstractRectangle.y });
1649
+ layout = elementWithLayout === null || elementWithLayout === void 0 ? void 0 : elementWithLayout.layout;
1648
1650
  }
1649
1651
  }
1652
+ if (layout === MindLayoutType.standard || !layout) {
1653
+ return correctRootLayout;
1654
+ }
1650
1655
  else {
1651
- if (activeHandlePosition === AbstractHandlePosition.start) {
1652
- return Object.assign(Object.assign({}, abstractRectangle), { x: location, width: abstractRectangle.width + abstractRectangle.x - location });
1656
+ const incorrectDirection = getInCorrectLayoutDirection(correctRootLayout, layout);
1657
+ if (incorrectDirection) {
1658
+ return correctLayoutByDirection(layout, incorrectDirection);
1653
1659
  }
1654
1660
  else {
1655
- return Object.assign(Object.assign({}, abstractRectangle), { width: location - abstractRectangle.x });
1661
+ return layout;
1656
1662
  }
1657
1663
  }
1658
1664
  };
1659
- const getLocationScope = (board, handlePosition, parentChildren, element, parent, isHorizontal) => {
1660
- const node = MindElement.getNode(element);
1661
- const { start, end } = getCorrectStartEnd(node.origin, parent);
1662
- const startNode = parentChildren[start];
1663
- const endNode = parentChildren[end];
1664
- if (handlePosition === AbstractHandlePosition.start) {
1665
- const abstractNode = parentChildren.filter(child => AbstractNode.isAbstract(child) && child.end < element.start);
1666
- let minNode;
1667
- if (abstractNode.length) {
1668
- const index = abstractNode
1669
- .map(node => {
1670
- const { end } = getCorrectStartEnd(node, parent);
1671
- return end;
1672
- })
1673
- .sort((a, b) => b - a)[0];
1674
- minNode = parentChildren[index + 1];
1665
+
1666
+ const getBranchLayouts = (board, element) => {
1667
+ const layouts = [];
1668
+ if (element.layout) {
1669
+ // TODO: getCorrectLayoutByElement 含有递归操作,getBranchLayouts 本身也有递归操作,有待优化
1670
+ layouts.unshift(getCorrectLayoutByElement(board, element));
1671
+ }
1672
+ let parent = MindElement.findParent(element);
1673
+ while (parent) {
1674
+ if (parent.layout) {
1675
+ layouts.unshift(parent.layout);
1675
1676
  }
1676
- else {
1677
- minNode = parentChildren[0];
1677
+ parent = MindElement.findParent(parent);
1678
+ }
1679
+ return layouts;
1680
+ };
1681
+
1682
+ const getAvailableSubLayoutsByElement = (board, element) => {
1683
+ const parentElement = MindElement.findParent(element);
1684
+ if (parentElement) {
1685
+ const branchLayouts = getBranchLayouts(board, parentElement);
1686
+ if (branchLayouts[0] === MindLayoutType.standard) {
1687
+ const node = MindElement.getNode(element);
1688
+ branchLayouts[0] = node.left ? MindLayoutType.left : MindLayoutType.right;
1678
1689
  }
1679
- const minNodeRectangle = getRectangleByElements(board, [minNode], true);
1680
- const endNodeRectangle = getRectangleByElements(board, [endNode], false);
1681
- if (isHorizontal) {
1682
- return {
1683
- max: endNodeRectangle.y - ABSTRACT_INCLUDED_OUTLINE_OFFSET,
1684
- min: minNodeRectangle.y - ABSTRACT_INCLUDED_OUTLINE_OFFSET
1685
- };
1690
+ const currentLayoutDirections = getBranchDirectionsByLayouts(branchLayouts);
1691
+ let availableSubLayouts = getAvailableSubLayoutsByLayoutDirections(currentLayoutDirections);
1692
+ const parentLayout = [branchLayouts[branchLayouts.length - 1]];
1693
+ const parentDirections = getBranchDirectionsByLayouts(parentLayout);
1694
+ const parentAvailableSubLayouts = getAvailableSubLayoutsByLayoutDirections(parentDirections);
1695
+ availableSubLayouts = availableSubLayouts.filter(layout => parentAvailableSubLayouts.some(parentAvailableSubLayout => parentAvailableSubLayout === layout));
1696
+ return availableSubLayouts;
1697
+ }
1698
+ return undefined;
1699
+ };
1700
+
1701
+ const getLayoutByElement = (element) => {
1702
+ const layout = element.layout;
1703
+ if (layout) {
1704
+ return layout;
1705
+ }
1706
+ const parent = !PlaitMind.isMind(element) && MindElement.getParent(element);
1707
+ if (AbstractNode.isAbstract(element) && parent) {
1708
+ return getAbstractLayout(getLayoutByElement(parent));
1709
+ }
1710
+ if (parent) {
1711
+ return getLayoutByElement(parent);
1712
+ }
1713
+ return getDefaultLayout();
1714
+ };
1715
+
1716
+ const MindQueries = {
1717
+ getAvailableSubLayoutsByElement,
1718
+ getBranchLayouts,
1719
+ getLayoutByElement,
1720
+ getCorrectLayoutByElement
1721
+ };
1722
+
1723
+ const PlaitMind = {
1724
+ isMind: (value) => {
1725
+ return value.type === 'mindmap';
1726
+ }
1727
+ };
1728
+ const MindElement = {
1729
+ hasLayout(value, layout) {
1730
+ const _layout = MindQueries.getLayoutByElement(value);
1731
+ return _layout === layout;
1732
+ },
1733
+ isIndentedLayout(value) {
1734
+ const _layout = MindQueries.getLayoutByElement(value);
1735
+ return isIndentedLayout(_layout);
1736
+ },
1737
+ isMindElement(board, element) {
1738
+ const path = PlaitBoard.findPath(board, element);
1739
+ const rootElement = PlaitNode.get(board, path.slice(0, 1));
1740
+ if (PlaitMind.isMind(rootElement)) {
1741
+ return true;
1686
1742
  }
1687
1743
  else {
1688
- return {
1689
- max: endNodeRectangle.x - ABSTRACT_INCLUDED_OUTLINE_OFFSET,
1690
- min: minNodeRectangle.x - ABSTRACT_INCLUDED_OUTLINE_OFFSET
1691
- };
1744
+ return false;
1692
1745
  }
1693
- }
1694
- else {
1695
- const abstractNode = parentChildren.filter(child => AbstractNode.isAbstract(child) && child.start > element.end);
1696
- let maxNode;
1697
- if (abstractNode.length) {
1698
- const index = abstractNode
1699
- .map(node => {
1700
- const { start } = getCorrectStartEnd(node, parent);
1701
- return start;
1702
- })
1703
- .sort((a, b) => a - b)[0];
1704
- maxNode = parentChildren[index - 1];
1746
+ },
1747
+ getParent(node) {
1748
+ if (PlaitMind.isMind(node)) {
1749
+ throw new Error('mind root node can not get parent');
1750
+ }
1751
+ const parent = NODE_TO_PARENT.get(node);
1752
+ return parent;
1753
+ },
1754
+ findParent(node) {
1755
+ if (PlaitMind.isMind(node)) {
1756
+ return undefined;
1757
+ }
1758
+ const parent = NODE_TO_PARENT.get(node);
1759
+ return parent;
1760
+ },
1761
+ getRoot(board, element) {
1762
+ const path = PlaitBoard.findPath(board, element);
1763
+ return PlaitNode.get(board, path.slice(0, 1));
1764
+ },
1765
+ getAncestors(board, element) {
1766
+ const path = PlaitBoard.findPath(board, element);
1767
+ const parents = [];
1768
+ for (const p of Path.ancestors(path, { reverse: true })) {
1769
+ const n = PlaitNode.get(board, p);
1770
+ if (n && !PlaitBoard.isBoard(n)) {
1771
+ parents.push(n);
1772
+ }
1705
1773
  }
1706
- else {
1707
- const children = parentChildren.filter(child => !AbstractNode.isAbstract(child));
1708
- maxNode = parentChildren[children.length - 1];
1774
+ return parents;
1775
+ },
1776
+ getNode(element) {
1777
+ const node = ELEMENT_TO_NODE.get(element);
1778
+ if (!node) {
1779
+ throw new Error(`can not get node from ${JSON.stringify(element)}`);
1709
1780
  }
1710
- const maxNodeRectangle = getRectangleByElements(board, [maxNode], true);
1711
- const startNodeRectangle = getRectangleByElements(board, [startNode], false);
1712
- if (isHorizontal) {
1713
- return {
1714
- max: maxNodeRectangle.y + maxNodeRectangle.height + ABSTRACT_INCLUDED_OUTLINE_OFFSET,
1715
- min: startNodeRectangle.y + startNodeRectangle.height + ABSTRACT_INCLUDED_OUTLINE_OFFSET
1716
- };
1781
+ return node;
1782
+ },
1783
+ findParentNode(element) {
1784
+ if (PlaitMind.isMind(element)) {
1785
+ return undefined;
1786
+ }
1787
+ const parent = MindElement.getParent(element);
1788
+ return MindElement.getNode(parent);
1789
+ },
1790
+ hasEmojis(element) {
1791
+ if (element.data.emojis) {
1792
+ return true;
1717
1793
  }
1718
1794
  else {
1719
- return {
1720
- max: maxNodeRectangle.x + maxNodeRectangle.width + ABSTRACT_INCLUDED_OUTLINE_OFFSET,
1721
- min: startNodeRectangle.x + startNodeRectangle.width + ABSTRACT_INCLUDED_OUTLINE_OFFSET
1722
- };
1795
+ return false;
1723
1796
  }
1797
+ },
1798
+ getEmojis(element) {
1799
+ return element.data.emojis;
1724
1800
  }
1725
1801
  };
1726
- const getHitAbstractHandle = (board, element, point) => {
1727
- const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
1728
- const isHorizontal = isHorizontalLayout(nodeLayout);
1729
- const parentElement = MindElement.getParent(element);
1730
- const includedElements = parentElement.children.slice(element.start, element.end + 1);
1731
- let abstractRectangle = getRectangleByElements(board, includedElements, true);
1732
- abstractRectangle = RectangleClient.getOutlineRectangle(abstractRectangle, -ABSTRACT_INCLUDED_OUTLINE_OFFSET);
1733
- const startHandleRec = getAbstractHandleRectangle(abstractRectangle, isHorizontal, AbstractHandlePosition.start);
1734
- const endHandleRec = getAbstractHandleRectangle(abstractRectangle, isHorizontal, AbstractHandlePosition.end);
1735
- const pointRec = RectangleClient.toRectangleClient([point, point]);
1736
- if (RectangleClient.isHit(pointRec, startHandleRec))
1737
- return AbstractHandlePosition.start;
1738
- if (RectangleClient.isHit(pointRec, endHandleRec))
1739
- return AbstractHandlePosition.end;
1740
- return undefined;
1741
- };
1742
- const getAbstractHandleRectangle = (rectangle, isHorizontal, position) => {
1743
- let result;
1744
- if (position === AbstractHandlePosition.start) {
1745
- const location = isHorizontal ? rectangle.y : rectangle.x;
1746
- result = getRectangleByResizingLocation(rectangle, location + ABSTRACT_HANDLE_MASK_WIDTH / 2, AbstractHandlePosition.end, isHorizontal);
1747
- result = getRectangleByResizingLocation(result, location - ABSTRACT_HANDLE_MASK_WIDTH / 2, position, isHorizontal);
1802
+ var MindElementShape;
1803
+ (function (MindElementShape) {
1804
+ MindElementShape["roundRectangle"] = "round-rectangle";
1805
+ MindElementShape["underline"] = "underline";
1806
+ })(MindElementShape || (MindElementShape = {}));
1807
+ var BranchShape;
1808
+ (function (BranchShape) {
1809
+ BranchShape["bight"] = "bight";
1810
+ BranchShape["polyline"] = "polyline";
1811
+ })(BranchShape || (BranchShape = {}));
1812
+
1813
+ const NodeDefaultSpace = {
1814
+ horizontal: {
1815
+ nodeAndText: BASE * 3,
1816
+ emojiAndText: BASE * 1.5
1817
+ },
1818
+ vertical: {
1819
+ nodeAndText: BASE * 1.5
1748
1820
  }
1749
- else {
1750
- const location = isHorizontal ? rectangle.y + rectangle.height : rectangle.x + rectangle.width;
1751
- result = getRectangleByResizingLocation(rectangle, location - ABSTRACT_HANDLE_MASK_WIDTH / 2, AbstractHandlePosition.start, isHorizontal);
1752
- result = getRectangleByResizingLocation(result, location + ABSTRACT_HANDLE_MASK_WIDTH / 2, position, isHorizontal);
1821
+ };
1822
+ const RootDefaultSpace = {
1823
+ horizontal: {
1824
+ nodeAndText: BASE * 4,
1825
+ emojiAndText: BASE * 2
1826
+ },
1827
+ vertical: {
1828
+ nodeAndText: BASE * 2
1753
1829
  }
1754
- return result;
1755
1830
  };
1756
- function findLocationLeftIndex(board, parentChildren, location, isHorizontal) {
1757
- const children = parentChildren.filter(child => {
1758
- return !AbstractNode.isAbstract(child);
1759
- });
1760
- const recArray = children.map(child => {
1761
- return getRectangleByElements(board, [child], false);
1762
- });
1763
- const firstRec = getRectangleByElements(board, [children[0]], true);
1764
- const fakeLeftRec = {
1765
- x: firstRec.x - firstRec.width,
1766
- y: firstRec.y - firstRec.height,
1767
- width: firstRec.width,
1768
- height: firstRec.height
1769
- };
1770
- const lastRec = getRectangleByElements(board, [children[children.length - 1]], true);
1771
- const fakeRightRec = {
1772
- x: lastRec.x + lastRec.width,
1773
- y: lastRec.y + lastRec.height,
1774
- width: lastRec.width,
1775
- height: lastRec.height
1776
- };
1777
- recArray.push(fakeRightRec);
1778
- recArray.unshift(fakeLeftRec);
1779
- for (let i = 0; i < recArray.length - 1; i++) {
1780
- const recXOrY = isHorizontal ? recArray[i].y : recArray[i].x;
1781
- const recWidthOrHeight = isHorizontal ? recArray[i].height : recArray[i].width;
1782
- if (location >= recXOrY + recWidthOrHeight / 2 &&
1783
- location <= recArray[i + 1][isHorizontal ? 'y' : 'x'] + recArray[i + 1][isHorizontal ? 'height' : 'width'] / 2) {
1784
- return i - 1;
1831
+ const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
1832
+ const isMind = PlaitMind.isMind(element);
1833
+ const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
1834
+ return nodeAndText;
1835
+ };
1836
+ const getVerticalSpaceBetweenNodeAndText = (element) => {
1837
+ const isMind = PlaitMind.isMind(element);
1838
+ const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
1839
+ return nodeAndText;
1840
+ };
1841
+ const getSpaceEmojiAndText = (element) => {
1842
+ const isMind = PlaitMind.isMind(element);
1843
+ const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
1844
+ return emojiAndText;
1845
+ };
1846
+ const NodeSpace = {
1847
+ getNodeWidth(board, element) {
1848
+ const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
1849
+ if (MindElement.hasEmojis(element)) {
1850
+ return (NodeSpace.getEmojiLeftSpace(board, element) +
1851
+ getEmojisWidthHeight(board, element).width +
1852
+ getSpaceEmojiAndText(element) +
1853
+ element.width +
1854
+ nodeAndText);
1785
1855
  }
1786
- }
1787
- return 0;
1788
- }
1789
- function handleTouchedAbstract(board, touchedAbstract, endPoint) {
1790
- let touchedHandle;
1791
- const abstract = getSelectedElements(board)
1792
- .filter(element => AbstractNode.isAbstract(element))
1793
- .find(element => {
1794
- touchedHandle = getHitAbstractHandle(board, element, endPoint);
1795
- return touchedHandle;
1796
- });
1797
- if (touchedAbstract === abstract) {
1798
- return touchedAbstract;
1799
- }
1800
- if (touchedAbstract) {
1801
- const component = PlaitElement.getComponent(touchedAbstract);
1802
- component.updateAbstractIncludedOutline();
1803
- touchedAbstract = undefined;
1804
- }
1805
- if (abstract) {
1806
- touchedAbstract = abstract;
1807
- const component = PlaitElement.getComponent(touchedAbstract);
1808
- component.updateAbstractIncludedOutline(touchedHandle);
1809
- }
1810
- return touchedAbstract;
1811
- }
1812
-
1813
- function drawIndentedLink(board, node, child, defaultStroke = null, needDrawUnderline = true, defaultStrokeWidth) {
1814
- const branchWidth = defaultStrokeWidth || getBranchWidthByMindElement(board, child.origin);
1815
- const branchColor = defaultStroke || getBranchColorByMindElement(board, child.origin);
1816
- const isUnderlineShape = getShapeByElement(board, child.origin) === MindElementShape.underline;
1817
- let beginX, beginY, endX, endY, beginNode = node, endNode = child;
1818
- const beginRectangle = getRectangleByNode(beginNode);
1819
- const endRectangle = getRectangleByNode(endNode);
1820
- beginX = beginNode.x + beginNode.width / 2;
1821
- beginY = isChildUp(node, child) ? beginRectangle.y : beginRectangle.y + beginRectangle.height;
1822
- endX = node.left ? endNode.x + endNode.hGap + endRectangle.width : endNode.x + endNode.hGap;
1823
- endY = isUnderlineShape ? endNode.y + endNode.height - endNode.vGap : endNode.y + endNode.height / 2;
1824
- //根据位置,设置正负参数
1825
- let plusMinus = isChildUp(node, child) ? (node.left ? [-1, -1] : [1, -1]) : node.left ? [-1, 1] : [1, 1];
1826
- const layout = MindQueries.getCorrectLayoutByElement(board, node.origin);
1827
- if (beginNode.origin.isRoot) {
1828
- if (layout === MindLayoutType.leftBottomIndented || layout === MindLayoutType.rightBottomIndented) {
1829
- beginY += branchWidth;
1856
+ return nodeAndText + element.width + nodeAndText;
1857
+ },
1858
+ getNodeHeight(board, element) {
1859
+ const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
1860
+ return nodeAndText + element.height + nodeAndText;
1861
+ },
1862
+ getTextLeftSpace(board, element) {
1863
+ const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
1864
+ if (MindElement.hasEmojis(element)) {
1865
+ return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
1830
1866
  }
1831
- if (layout === MindLayoutType.leftTopIndented || layout === MindLayoutType.rightTopIndented) {
1832
- beginY -= branchWidth;
1867
+ else {
1868
+ return nodeAndText;
1833
1869
  }
1870
+ },
1871
+ getTextTopSpace(element) {
1872
+ const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
1873
+ return nodeAndText;
1874
+ },
1875
+ getEmojiLeftSpace(board, element) {
1876
+ const options = board.getMindOptions();
1877
+ const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
1878
+ return nodeAndText - options.emojiPadding;
1879
+ },
1880
+ getEmojiTopSpace(element) {
1881
+ const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
1882
+ return nodeAndText;
1834
1883
  }
1835
- let curve = [
1836
- [beginX, beginY],
1837
- [beginX, beginY],
1838
- [beginX, beginY],
1839
- [beginX, endY - (endNode.hGap * 3 * plusMinus[1]) / 5],
1840
- [beginX, endY - (endNode.hGap * plusMinus[1]) / 5],
1841
- [beginX + (endNode.hGap * plusMinus[0]) / 4, endY],
1842
- [beginX + (endNode.hGap * plusMinus[0] * 3) / 5, endY],
1843
- isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
1844
- isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
1845
- isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY]
1846
- ];
1847
- const points = pointsOnBezierCurves(curve);
1848
- return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
1884
+ };
1885
+
1886
+ function getTopicRectangleByNode(board, node) {
1887
+ let nodeRectangle = getRectangleByNode(node);
1888
+ return getTopicRectangleByElement(board, nodeRectangle, node.origin);
1889
+ }
1890
+ function getTopicRectangleByElement(board, nodeRectangle, element) {
1891
+ const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
1892
+ const y = nodeRectangle.y + NodeSpace.getTextTopSpace(element);
1893
+ const width = Math.ceil(element.width);
1894
+ const height = Math.ceil(element.height);
1895
+ return { height, width, x, y };
1849
1896
  }
1850
1897
 
1851
1898
  function drawTopicByNode(board, node, viewContainerRef) {
@@ -1882,6 +1929,7 @@ function drawAbstractLink(board, node, isHorizontal) {
1882
1929
  const branchWidth = getAbstractBranchWidth(board, node.origin);
1883
1930
  const branchColor = getAbstractBranchColor(board, node.origin);
1884
1931
  const parent = node.parent;
1932
+ const branchShape = getBranchShapeByMindElement(board, parent.origin);
1885
1933
  const abstractRectangle = getRectangleByNode(node);
1886
1934
  let includedElements = parent.children.slice(node.origin.start, node.origin.end + 1).map(node => {
1887
1935
  return node.origin;
@@ -1903,6 +1951,20 @@ function drawAbstractLink(board, node, isHorizontal) {
1903
1951
  bezierEndPoint = moveXOfPoint(bezierEndPoint, linkPadding, linkDirection);
1904
1952
  let c2 = moveXOfPoint(bezierEndPoint, curveDistance, linkDirection);
1905
1953
  let bezierConnectorPoint = moveXOfPoint(abstractConnectorPoint, -linkPadding, linkDirection);
1954
+ if (branchShape === BranchShape.polyline) {
1955
+ const g = createG();
1956
+ const polyline = drawLinearPath([bezierBeginPoint, c1, bezierConnectorPoint, c2, bezierEndPoint], {
1957
+ stroke: branchColor,
1958
+ strokeWidth: branchWidth
1959
+ });
1960
+ const straightLine = drawLinearPath([abstractConnectorPoint, bezierConnectorPoint], {
1961
+ stroke: branchColor,
1962
+ strokeWidth: branchWidth
1963
+ });
1964
+ g.appendChild(polyline);
1965
+ g.appendChild(straightLine);
1966
+ return g;
1967
+ }
1906
1968
  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]}`, {
1907
1969
  stroke: branchColor,
1908
1970
  strokeWidth: branchWidth
@@ -2089,16 +2151,14 @@ const setTopicSize = (board, element, width, height) => {
2089
2151
  Transforms.setNode(board, newElement, path);
2090
2152
  };
2091
2153
  const removeElements = (board, elements) => {
2092
- const deletableElements = getFirstLevelElement(elements).reverse();
2093
- //翻转,从下到上修改,防止找不到 path
2154
+ const deletableElements = getFirstLevelElement(elements);
2094
2155
  deletableElements
2095
2156
  .map(element => {
2096
2157
  const path = PlaitBoard.findPath(board, element);
2158
+ const ref = board.pathRef(path);
2097
2159
  return () => {
2098
- if (isInRightBranchOfStandardLayout(element)) {
2099
- changeRightNodeCount(board, path.slice(0, 1), -1);
2100
- }
2101
- Transforms.removeNode(board, path);
2160
+ Transforms.removeNode(board, ref.current);
2161
+ ref.unref();
2102
2162
  };
2103
2163
  })
2104
2164
  .forEach(action => {
@@ -2124,6 +2184,11 @@ const insertAbstractNodes = (board, validAbstractRefs, elements, path) => {
2124
2184
  });
2125
2185
  insertNodes(board, abstracts, abstractPath);
2126
2186
  };
2187
+ const setRightNodeCountByRefs = (board, refs) => {
2188
+ refs.forEach(ref => {
2189
+ Transforms.setNode(board, { rightNodeCount: ref.rightNodeCount }, ref.path);
2190
+ });
2191
+ };
2127
2192
 
2128
2193
  const addEmoji = (board, element, emojiItem) => {
2129
2194
  const emojis = element.data.emojis || [];
@@ -2173,7 +2238,8 @@ const MindTransforms = {
2173
2238
  setAbstractByStandardLayout,
2174
2239
  removeElements,
2175
2240
  insertNodes,
2176
- insertAbstractNodes
2241
+ insertAbstractNodes,
2242
+ setRightNodeCountByRefs
2177
2243
  };
2178
2244
 
2179
2245
  function drawAbstractIncludedOutline(board, roughSVG, element, activeHandlePosition, resizingLocation) {
@@ -2581,11 +2647,8 @@ class MindNodeComponent extends PlaitPluginElementComponent {
2581
2647
  if (AbstractNode.isAbstract(this.node.origin)) {
2582
2648
  this.linkG = drawAbstractLink(this.board, this.node, isHorizontalLayout(layout));
2583
2649
  }
2584
- else if (MindElement.isIndentedLayout(parent)) {
2585
- this.linkG = drawIndentedLink(this.board, parentNode, this.node);
2586
- }
2587
2650
  else {
2588
- this.linkG = drawLogicLink(this.board, this.node, parentNode, isHorizontalLayout(layout));
2651
+ this.linkG = drawLink(this.board, parentNode, this.node, isHorizontalLayout(layout));
2589
2652
  }
2590
2653
  this.g.append(this.linkG);
2591
2654
  }
@@ -2988,8 +3051,8 @@ class MindNodeComponent extends PlaitPluginElementComponent {
2988
3051
  }
2989
3052
  }
2990
3053
  }
2991
- MindNodeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: MindNodeComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
2992
- MindNodeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: MindNodeComponent, selector: "plait-mind-node", usesInheritance: true, ngImport: i0, template: `
3054
+ MindNodeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindNodeComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
3055
+ MindNodeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: MindNodeComponent, selector: "plait-mind-node", usesInheritance: true, ngImport: i0, template: `
2993
3056
  <plait-children
2994
3057
  *ngIf="!element.isCollapsed"
2995
3058
  [board]="board"
@@ -2998,7 +3061,7 @@ MindNodeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", vers
2998
3061
  [parentG]="parentG"
2999
3062
  ></plait-children>
3000
3063
  `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.PlaitChildrenElement, selector: "plait-children", inputs: ["board", "parent", "effect", "parentG"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3001
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: MindNodeComponent, decorators: [{
3064
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindNodeComponent, decorators: [{
3002
3065
  type: Component,
3003
3066
  args: [{
3004
3067
  selector: 'plait-mind-node',
@@ -3108,11 +3171,11 @@ class PlaitMindComponent extends MindNodeComponent {
3108
3171
  });
3109
3172
  }
3110
3173
  }
3111
- PlaitMindComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: PlaitMindComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
3112
- PlaitMindComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: PlaitMindComponent, selector: "plait-mind", usesInheritance: true, ngImport: i0, template: `
3174
+ PlaitMindComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitMindComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
3175
+ PlaitMindComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: PlaitMindComponent, selector: "plait-mind", usesInheritance: true, ngImport: i0, template: `
3113
3176
  <plait-children [board]="board" [parent]="element" [effect]="effect" [parentG]="rootG"></plait-children>
3114
3177
  `, isInline: true, dependencies: [{ kind: "component", type: i2.PlaitChildrenElement, selector: "plait-children", inputs: ["board", "parent", "effect", "parentG"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3115
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: PlaitMindComponent, decorators: [{
3178
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitMindComponent, decorators: [{
3116
3179
  type: Component,
3117
3180
  args: [{
3118
3181
  selector: 'plait-mind',
@@ -3125,10 +3188,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
3125
3188
 
3126
3189
  class MindModule {
3127
3190
  }
3128
- MindModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: MindModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3129
- MindModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.2", ngImport: i0, type: MindModule, declarations: [PlaitMindComponent, MindNodeComponent], imports: [CommonModule, RichtextModule, PlaitModule], exports: [PlaitMindComponent, MindNodeComponent] });
3130
- MindModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: MindModule, imports: [CommonModule, RichtextModule, PlaitModule] });
3131
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: MindModule, decorators: [{
3191
+ MindModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3192
+ MindModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: MindModule, declarations: [PlaitMindComponent, MindNodeComponent], imports: [CommonModule, RichtextModule, PlaitModule], exports: [PlaitMindComponent, MindNodeComponent] });
3193
+ MindModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, imports: [CommonModule, RichtextModule, PlaitModule] });
3194
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, decorators: [{
3132
3195
  type: NgModule,
3133
3196
  args: [{
3134
3197
  declarations: [PlaitMindComponent, MindNodeComponent],
@@ -3197,7 +3260,7 @@ const withDnd = (board) => {
3197
3260
  dropTarget = detectDropTarget(board, detectPoint, dropTarget, [...activeElements, ...correspondingElements]);
3198
3261
  if (dropTarget === null || dropTarget === void 0 ? void 0 : dropTarget.target) {
3199
3262
  targetPath = getPathByDropTarget(board, dropTarget);
3200
- fakeDropNodeG = drawFakeDropNodeByPath(board, dropTarget.target, targetPath);
3263
+ fakeDropNodeG = drawFakeDropNode(board, dropTarget.target, targetPath);
3201
3264
  PlaitBoard.getHost(board).appendChild(fakeDropNodeG);
3202
3265
  }
3203
3266
  const offsetX = endPoint[0] - startPoint[0];
@@ -3240,6 +3303,14 @@ const withDnd = (board) => {
3240
3303
  const effectedAbstracts = deleteElementHandleAbstract(board, elements);
3241
3304
  insertElementHandleAbstract(board, targetPath, normalElements.length, false, effectedAbstracts);
3242
3305
  MindTransforms.setAbstractsByRefs(board, effectedAbstracts);
3306
+ let refs = deleteElementsHandleRightNodeCount(board, elements);
3307
+ const shouldChangeRoot = isInRightBranchOfStandardLayout(dropTarget === null || dropTarget === void 0 ? void 0 : dropTarget.target) &&
3308
+ targetElementPathRef.current &&
3309
+ (Path.isSibling(targetPath, targetElementPathRef.current) || Path.equals(targetPath, targetElementPathRef.current));
3310
+ if (shouldChangeRoot && targetElementPathRef.current) {
3311
+ refs = insertElementHandleRightNodeCount(board, targetElementPathRef.current.slice(0, 1), normalElements.length, refs);
3312
+ }
3313
+ MindTransforms.setRightNodeCountByRefs(board, refs);
3243
3314
  MindTransforms.removeElements(board, elements);
3244
3315
  let insertPath = targetPathRef.current;
3245
3316
  const parentPath = Path.parent(targetPathRef.current || targetPath);
@@ -3252,12 +3323,6 @@ const withDnd = (board) => {
3252
3323
  if (abstractRefs.length) {
3253
3324
  MindTransforms.insertAbstractNodes(board, abstractRefs, normalElements, insertPath);
3254
3325
  }
3255
- const shouldChangeRoot = isInRightBranchOfStandardLayout(dropTarget === null || dropTarget === void 0 ? void 0 : dropTarget.target) &&
3256
- targetElementPathRef.current &&
3257
- (Path.isSibling(targetPath, targetElementPathRef.current) || Path.equals(targetPath, targetElementPathRef.current));
3258
- if (shouldChangeRoot && targetElementPathRef.current) {
3259
- changeRightNodeCount(board, targetElementPathRef.current.slice(0, 1), normalElements.length);
3260
- }
3261
3326
  if (targetElementPathRef.current &&
3262
3327
  targetPathRef.current &&
3263
3328
  Path.isAncestor(targetElementPathRef.current, targetPathRef.current) &&
@@ -3266,10 +3331,9 @@ const withDnd = (board) => {
3266
3331
  }
3267
3332
  targetElementPathRef.unref();
3268
3333
  targetPathRef.unref();
3269
- const selectedElements = getSelectedElements(board);
3270
3334
  let setActiveElements = [];
3271
3335
  depthFirstRecursion(board, node => {
3272
- const isSelected = selectedElements.some(element => element.id === node.id);
3336
+ const isSelected = activeElements.some(element => element.id === node.id);
3273
3337
  if (isSelected) {
3274
3338
  setActiveElements.push(node);
3275
3339
  }
@@ -3398,6 +3462,10 @@ const withAbstract = (board) => {
3398
3462
  let startPoint;
3399
3463
  let newProperty;
3400
3464
  board.mousedown = (event) => {
3465
+ if (!isMainPointer(event)) {
3466
+ mousedown(event);
3467
+ return;
3468
+ }
3401
3469
  const activeAbstractElements = getSelectedElements(board).filter(element => AbstractNode.isAbstract(element));
3402
3470
  const host = BOARD_TO_HOST.get(board);
3403
3471
  const point = transformPoint(board, toPoint(event.x, event.y, host));
@@ -3551,6 +3619,7 @@ const withCreateMind = (board) => {
3551
3619
  const targetPoint = transformPoint(board, toPoint(movingPoint[0], movingPoint[1], PlaitBoard.getHost(board)));
3552
3620
  const emptyMind = createEmptyMind(board, targetPoint);
3553
3621
  Transforms.insertNode(board, emptyMind, [board.children.length]);
3622
+ addSelectedElement(board, emptyMind);
3554
3623
  BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
3555
3624
  }
3556
3625
  destroy();
@@ -3644,7 +3713,8 @@ const withMind = (board) => {
3644
3713
  }
3645
3714
  else {
3646
3715
  if (isInRightBranchOfStandardLayout(selectedElement)) {
3647
- changeRightNodeCount(board, selectedElementPath.slice(0, 1), 1);
3716
+ const refs = insertElementHandleRightNodeCount(board, selectedElementPath.slice(0, 1), 1);
3717
+ MindTransforms.setRightNodeCountByRefs(board, refs);
3648
3718
  }
3649
3719
  const abstractRefs = insertElementHandleAbstract(board, Path.next(selectedElementPath));
3650
3720
  MindTransforms.setAbstractsByRefs(board, abstractRefs);
@@ -3657,6 +3727,8 @@ const withMind = (board) => {
3657
3727
  const deletableElements = getFirstLevelElement(selectedElements).reverse();
3658
3728
  const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
3659
3729
  MindTransforms.setAbstractsByRefs(board, abstractRefs);
3730
+ const refs = deleteElementsHandleRightNodeCount(board, selectedElements);
3731
+ MindTransforms.setRightNodeCountByRefs(board, refs);
3660
3732
  MindTransforms.removeElements(board, selectedElements);
3661
3733
  let activeElement;
3662
3734
  const firstLevelElements = getFirstLevelElement(selectedElements);
@@ -3762,6 +3834,8 @@ const withMind = (board) => {
3762
3834
  const deletableElements = getFirstLevelElement(selectedElements).reverse();
3763
3835
  const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
3764
3836
  MindTransforms.setAbstractsByRefs(board, abstractRefs);
3837
+ const refs = deleteElementsHandleRightNodeCount(board, selectedElements);
3838
+ MindTransforms.setRightNodeCountByRefs(board, refs);
3765
3839
  MindTransforms.removeElements(board, selectedElements);
3766
3840
  deleteFragment(data);
3767
3841
  };
@@ -3780,9 +3854,9 @@ class MindEmojiBaseComponent {
3780
3854
  this.elementRef.nativeElement.style.fontSize = `${this.fontSize}px`;
3781
3855
  }
3782
3856
  }
3783
- MindEmojiBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: MindEmojiBaseComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
3784
- MindEmojiBaseComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: MindEmojiBaseComponent, inputs: { fontSize: "fontSize", emojiItem: "emojiItem", board: "board", element: "element" }, host: { classAttribute: "mind-node-emoji" }, ngImport: i0 });
3785
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: MindEmojiBaseComponent, decorators: [{
3857
+ MindEmojiBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindEmojiBaseComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
3858
+ MindEmojiBaseComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: MindEmojiBaseComponent, inputs: { fontSize: "fontSize", emojiItem: "emojiItem", board: "board", element: "element" }, host: { classAttribute: "mind-node-emoji" }, ngImport: i0 });
3859
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindEmojiBaseComponent, decorators: [{
3786
3860
  type: Directive,
3787
3861
  args: [{
3788
3862
  host: {
@@ -3807,5 +3881,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
3807
3881
  * Generated bundle index. Do not edit.
3808
3882
  */
3809
3883
 
3810
- export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_COLORS, BRANCH_WIDTH, BaseDrawer, DefaultAbstractNodeStyle, DefaultNodeStyle, DefaultRootStyle, ELEMENT_TO_NODE, EXTEND_OFFSET, EXTEND_RADIUS, GRAY_COLOR, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindElement, MindElementShape, MindEmojiBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindTransforms, NODE_MIN_WIDTH, PRIMARY_COLOR, PlaitMind, PlaitMindComponent, QUICK_INSERT_CIRCLE_COLOR, QUICK_INSERT_CIRCLE_OFFSET, QUICK_INSERT_INNER_CROSS_COLOR, ROOT_TOPIC_FONT_SIZE, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, TRANSPARENT, addActiveOnDragOrigin, canSetAbstract, changeRightNodeCount, copyNewNode, correctLayoutByDirection, deleteElementHandleAbstract, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNodeByPath, extractNodesText, findLastChild, findLocationLeftIndex, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getEmojiForeignRectangle, getEmojiRectangle, getFirstLevelElement, getHitAbstractHandle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getPreviousAndNextByPath, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getShapeByElement, getStrokeByMindElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, insertElementHandleAbstract, insertMindElement, isChildElement, isChildRight, isChildUp, isCorrectLayout, isDragging, isHitEmojis, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, readjustmentDropTarget, removeActiveOnDragOrigin, separateChildren, setIsDragging, withMind, withMindExtend };
3884
+ export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_COLORS, BRANCH_WIDTH, BaseDrawer, BranchShape, DefaultAbstractNodeStyle, DefaultNodeStyle, DefaultRootStyle, ELEMENT_TO_NODE, EXTEND_OFFSET, EXTEND_RADIUS, GRAY_COLOR, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindElement, MindElementShape, MindEmojiBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindTransforms, NODE_MIN_WIDTH, PRIMARY_COLOR, PlaitMind, PlaitMindComponent, QUICK_INSERT_CIRCLE_COLOR, QUICK_INSERT_CIRCLE_OFFSET, QUICK_INSERT_INNER_CROSS_COLOR, ROOT_TOPIC_FONT_SIZE, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, TRANSPARENT, addActiveOnDragOrigin, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, canSetAbstract, copyNewNode, correctLayoutByDirection, createDefaultMind, createEmptyMind, createMindElement, deleteElementHandleAbstract, deleteElementsHandleRightNodeCount, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNode, enterNodeEditing, extractNodesText, findLastChild, findLocationLeftIndex, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchShapeByMindElement, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getEmojiForeignRectangle, getEmojiRectangle, getFirstLevelElement, getHitAbstractHandle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getShapeByElement, getStrokeByMindElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildRight, isChildUp, isCorrectLayout, isDragging, isHitEmojis, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, readjustmentDropTarget, removeActiveOnDragOrigin, separateChildren, setIsDragging, withMind, withMindExtend };
3811
3885
  //# sourceMappingURL=plait-mind.mjs.map