@flowgram.ai/renderer 0.1.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,3025 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var __decorateClass = (decorators, target, key, kind) => {
30
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
31
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
32
+ if (decorator = decorators[i])
33
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
34
+ if (kind && result) __defProp(target, key, result);
35
+ return result;
36
+ };
37
+
38
+ // src/index.ts
39
+ var src_exports = {};
40
+ __export(src_exports, {
41
+ FlowContextMenuLayer: () => FlowContextMenuLayer,
42
+ FlowDebugLayer: () => FlowDebugLayer,
43
+ FlowDragEntity: () => FlowDragEntity,
44
+ FlowDragLayer: () => FlowDragLayer,
45
+ FlowLabelsLayer: () => FlowLabelsLayer,
46
+ FlowLinesLayer: () => FlowLinesLayer,
47
+ FlowNodesContentLayer: () => FlowNodesContentLayer,
48
+ FlowNodesTransformLayer: () => FlowNodesTransformLayer,
49
+ FlowRendererCommandCategory: () => FlowRendererCommandCategory,
50
+ FlowRendererComponentType: () => FlowRendererComponentType,
51
+ FlowRendererContainerModule: () => FlowRendererContainerModule,
52
+ FlowRendererContribution: () => FlowRendererContribution,
53
+ FlowRendererKey: () => FlowRendererKey,
54
+ FlowRendererRegistry: () => FlowRendererRegistry,
55
+ FlowScrollBarLayer: () => FlowScrollBarLayer,
56
+ FlowScrollLimitLayer: () => FlowScrollLimitLayer,
57
+ FlowSelectConfigEntity: () => FlowSelectConfigEntity,
58
+ FlowSelectorBoundsLayer: () => FlowSelectorBoundsLayer,
59
+ FlowSelectorBoxLayer: () => FlowSelectorBoxLayer,
60
+ FlowTextKey: () => FlowTextKey,
61
+ MARK_ACTIVATED_ARROW_ID: () => MARK_ACTIVATED_ARROW_ID,
62
+ MARK_ARROW_ID: () => MARK_ARROW_ID,
63
+ ScrollBarEvents: () => ScrollBarEvents,
64
+ SelectorBoxConfigEntity: () => SelectorBoxConfigEntity,
65
+ createLines: () => createLines,
66
+ useBaseColor: () => useBaseColor
67
+ });
68
+ module.exports = __toCommonJS(src_exports);
69
+
70
+ // src/entities/flow-drag-entity.tsx
71
+ var import_document3 = require("@flowgram.ai/document");
72
+ var import_core2 = require("@flowgram.ai/core");
73
+ var import_utils = require("@flowgram.ai/utils");
74
+
75
+ // src/components/utils.tsx
76
+ var import_document2 = require("@flowgram.ai/document");
77
+
78
+ // src/hooks/use-base-color.ts
79
+ var import_document = require("@flowgram.ai/document");
80
+ var import_core = require("@flowgram.ai/core");
81
+ var BASE_DEFAULT_COLOR = "#BBBFC4";
82
+ var BASE_DEFAULT_ACTIVATED_COLOR = "#82A7FC";
83
+ function useBaseColor() {
84
+ const options = (0, import_core.useService)(import_document.FlowDocumentOptions);
85
+ return {
86
+ baseColor: options.constants?.[import_document.ConstantKeys.BASE_COLOR] || BASE_DEFAULT_COLOR,
87
+ baseActivatedColor: options.constants?.[import_document.ConstantKeys.BASE_ACTIVATED_COLOR] || BASE_DEFAULT_ACTIVATED_COLOR
88
+ };
89
+ }
90
+
91
+ // src/components/utils.tsx
92
+ var DEFAULT_LINE_ATTRS = {
93
+ stroke: BASE_DEFAULT_COLOR,
94
+ fill: "transparent",
95
+ strokeLinecap: "round",
96
+ strokeLinejoin: "round"
97
+ };
98
+ var DEFAULT_RADIUS = 16;
99
+ var DEFAULT_LABEL_ACTIVATE_HEIGHT = 32;
100
+ function getHorizontalVertices(line, xRadius = 16, yRadius = 20) {
101
+ const { from, to, type } = line || {};
102
+ const deltaY = Math.abs(to.y - from.y);
103
+ const deltaX = Math.abs(to.x - from.x);
104
+ const radiusXCount = deltaX / xRadius;
105
+ const radiusYCount = deltaY / yRadius;
106
+ let res = [];
107
+ if (radiusXCount < 1) {
108
+ return [];
109
+ }
110
+ switch (type) {
111
+ case import_document2.FlowTransitionLineEnum.DIVERGE_LINE:
112
+ case import_document2.FlowTransitionLineEnum.DRAGGING_LINE:
113
+ if (radiusXCount <= 1) {
114
+ return [
115
+ {
116
+ x: to.x,
117
+ y: from.y,
118
+ radiusX: deltaX
119
+ }
120
+ ];
121
+ }
122
+ res = [
123
+ {
124
+ x: from.x + yRadius,
125
+ y: from.y
126
+ },
127
+ {
128
+ x: from.x + yRadius,
129
+ y: to.y
130
+ }
131
+ ];
132
+ if (radiusXCount < 2) {
133
+ const firstRadius = deltaX - yRadius;
134
+ res = [
135
+ {
136
+ x: from.x + firstRadius,
137
+ y: from.y,
138
+ // 第一个圆角收缩 y 半径
139
+ radiusX: firstRadius
140
+ },
141
+ {
142
+ x: from.x + firstRadius,
143
+ y: to.y
144
+ }
145
+ ];
146
+ }
147
+ if (radiusYCount < 2) {
148
+ res[0].moveY = deltaY / 2;
149
+ res[1].moveY = deltaY / 2;
150
+ }
151
+ return res;
152
+ case import_document2.FlowTransitionLineEnum.MERGE_LINE:
153
+ if (radiusXCount < 2) {
154
+ return [
155
+ {
156
+ x: to.x,
157
+ y: from.y
158
+ }
159
+ ];
160
+ }
161
+ res = [
162
+ {
163
+ x: to.x - yRadius,
164
+ y: from.y
165
+ },
166
+ {
167
+ x: to.x - yRadius,
168
+ y: to.y
169
+ }
170
+ ];
171
+ if (radiusYCount < 2) {
172
+ res[0].moveY = deltaY / 2;
173
+ res[1].moveY = deltaY / 2;
174
+ }
175
+ return res;
176
+ default:
177
+ break;
178
+ }
179
+ return [];
180
+ }
181
+ function getVertices(line, xRadius = 16, yRadius = 20) {
182
+ const { from, to, type } = line || {};
183
+ const deltaY = Math.abs(to.y - from.y);
184
+ const deltaX = Math.abs(to.x - from.x);
185
+ const radiusYCount = deltaY / yRadius;
186
+ const radiusXCount = deltaX / xRadius;
187
+ let res = [];
188
+ if (radiusYCount < 1) {
189
+ return [];
190
+ }
191
+ switch (type) {
192
+ case import_document2.FlowTransitionLineEnum.DIVERGE_LINE:
193
+ case import_document2.FlowTransitionLineEnum.DRAGGING_LINE:
194
+ if (radiusYCount <= 1) {
195
+ return [
196
+ {
197
+ x: to.x,
198
+ y: from.y,
199
+ radiusY: deltaY
200
+ }
201
+ ];
202
+ }
203
+ res = [
204
+ {
205
+ x: from.x,
206
+ y: from.y + yRadius
207
+ },
208
+ {
209
+ x: to.x,
210
+ y: from.y + yRadius
211
+ }
212
+ ];
213
+ if (radiusYCount < 2) {
214
+ const firstRadius = deltaY - yRadius;
215
+ res = [
216
+ {
217
+ x: from.x,
218
+ y: from.y + firstRadius,
219
+ // 第一个圆角收缩 y 半径
220
+ radiusY: firstRadius
221
+ },
222
+ {
223
+ x: to.x,
224
+ y: from.y + firstRadius
225
+ }
226
+ ];
227
+ }
228
+ if (radiusXCount < 2) {
229
+ res[0].moveX = deltaX / 2;
230
+ res[1].moveX = deltaX / 2;
231
+ }
232
+ return res;
233
+ case import_document2.FlowTransitionLineEnum.MERGE_LINE:
234
+ if (radiusYCount < 2) {
235
+ return [
236
+ {
237
+ x: from.x,
238
+ y: to.y
239
+ }
240
+ ];
241
+ }
242
+ res = [
243
+ {
244
+ x: from.x,
245
+ y: to.y - yRadius
246
+ },
247
+ {
248
+ x: to.x,
249
+ y: to.y - yRadius
250
+ }
251
+ ];
252
+ if (radiusXCount < 2) {
253
+ res[0].moveX = deltaX / 2;
254
+ res[1].moveX = deltaX / 2;
255
+ }
256
+ return res;
257
+ default:
258
+ break;
259
+ }
260
+ return [];
261
+ }
262
+ function getTransitionLabelHoverWidth(data) {
263
+ const { isVertical } = data.entity;
264
+ if (isVertical) {
265
+ const nextWidth = data.entity.next?.firstChild && !data.entity.next.isInlineBlocks ? data.entity.next.firstChild.getData(import_document2.FlowNodeTransformData).size.width : data.entity.next?.getData(import_document2.FlowNodeTransformData).size.width;
266
+ const maxWidth = Math.max(
267
+ data.entity.getData(import_document2.FlowNodeTransformData)?.size.width ?? import_document2.DEFAULT_SPACING[import_document2.DefaultSpacingKey.HOVER_AREA_WIDTH],
268
+ nextWidth || 0
269
+ );
270
+ return maxWidth;
271
+ }
272
+ if (data.transform.next) {
273
+ return data.transform.next.inputPoint.x - data.transform.outputPoint.x;
274
+ }
275
+ return DEFAULT_LABEL_ACTIVATE_HEIGHT;
276
+ }
277
+ function getTransitionLabelHoverHeight(data) {
278
+ const { isVertical } = data.entity;
279
+ if (isVertical) {
280
+ if (data.transform.next) {
281
+ return data.transform.next.inputPoint.y - data.transform.outputPoint.y;
282
+ }
283
+ return DEFAULT_LABEL_ACTIVATE_HEIGHT;
284
+ }
285
+ const nextHeight = data.entity.next?.firstChild && !data.entity.next.isInlineBlocks ? data.entity.next.firstChild.getData(import_document2.FlowNodeTransformData).size.height : data.entity.next?.getData(import_document2.FlowNodeTransformData).size.height;
286
+ const maxHeight = Math.max(
287
+ data.entity.getData(import_document2.FlowNodeTransformData)?.size.height || 280,
288
+ nextHeight || 0
289
+ );
290
+ return maxHeight;
291
+ }
292
+
293
+ // src/entities/flow-drag-entity.tsx
294
+ var BRANCH_HOVER_HEIGHT = 64;
295
+ var SCROLL_DELTA = 4;
296
+ var SCROLL_INTERVAL = 20;
297
+ var SCROLL_BOUNDING = 20;
298
+ var EDITOR_LEFT_BAR_WIDTH = 60;
299
+ var FlowDragEntity = class extends import_core2.ConfigEntity {
300
+ constructor(conf) {
301
+ super(conf);
302
+ this.containerX = 0;
303
+ this.containerY = 0;
304
+ this.playgroundConfigEntity = this.entityManager.getEntity(
305
+ import_core2.PlaygroundConfigEntity,
306
+ true
307
+ );
308
+ }
309
+ get hasScroll() {
310
+ return Boolean(this._scrollXInterval || this._scrollYInterval);
311
+ }
312
+ isCollision(transition, rect, isBranch) {
313
+ const scale = this.playgroundConfigEntity.finalScale || 0;
314
+ if (isBranch) {
315
+ return this.isBranchCollision(transition, rect, scale);
316
+ }
317
+ return this.isNodeCollision(transition, rect, scale);
318
+ }
319
+ // 检测节点维度碰撞方法
320
+ isNodeCollision(transition, rect, scale) {
321
+ const { labels } = transition;
322
+ const { isVertical } = transition.entity;
323
+ const hasCollision = labels.some((label) => {
324
+ if (!label || ![
325
+ import_document3.FlowTransitionLabelEnum.ADDER_LABEL,
326
+ import_document3.FlowTransitionLabelEnum.COLLAPSE_ADDER_LABEL
327
+ ].includes(label.type)) {
328
+ return false;
329
+ }
330
+ const hoverWidth = isVertical ? transition.transform.bounds.width : DEFAULT_LABEL_ACTIVATE_HEIGHT;
331
+ const hoverHeight = isVertical ? DEFAULT_LABEL_ACTIVATE_HEIGHT : transition.transform.bounds.height;
332
+ const labelRect = new import_utils.Rectangle(
333
+ (label.offset.x - hoverWidth / 2) * scale,
334
+ (label.offset.y - hoverHeight / 2) * scale,
335
+ hoverWidth * scale,
336
+ hoverHeight * scale
337
+ );
338
+ return import_utils.Rectangle.intersects(labelRect, rect);
339
+ });
340
+ return {
341
+ hasCollision,
342
+ // 节点不关心 offsetType
343
+ labelOffsetType: void 0
344
+ };
345
+ }
346
+ // 检测分支维度碰撞
347
+ isBranchCollision(transition, rect, scale) {
348
+ const { labels } = transition;
349
+ const { isVertical } = transition.entity;
350
+ let labelOffsetType = import_document3.LABEL_SIDE_TYPE.NORMAL_BRANCH;
351
+ const hasCollision = labels.some((label) => {
352
+ if (!label || label.type !== import_document3.FlowTransitionLabelEnum.BRANCH_DRAGGING_LABEL) {
353
+ return false;
354
+ }
355
+ const hoverHeight = isVertical ? BRANCH_HOVER_HEIGHT : label.width || 0;
356
+ const hoverWidth = isVertical ? label.width || 0 : BRANCH_HOVER_HEIGHT;
357
+ const labelRect = new import_utils.Rectangle(
358
+ (label.offset.x - hoverWidth / 2) * scale,
359
+ (label.offset.y - hoverHeight / 2) * scale,
360
+ hoverWidth * scale,
361
+ hoverHeight * scale
362
+ );
363
+ const collision = import_utils.Rectangle.intersects(labelRect, rect);
364
+ if (collision) {
365
+ labelOffsetType = label.props.side;
366
+ }
367
+ return collision;
368
+ });
369
+ return {
370
+ hasCollision,
371
+ labelOffsetType
372
+ };
373
+ }
374
+ _startScrollX(origin, added) {
375
+ if (this._scrollXInterval) {
376
+ return;
377
+ }
378
+ const interval = window.setInterval(() => {
379
+ const current = this._scrollXInterval;
380
+ if (!current) return;
381
+ const scrollX = current.origin = added ? current.origin + SCROLL_DELTA : current.origin - SCROLL_DELTA;
382
+ this.playgroundConfigEntity.updateConfig({
383
+ scrollX
384
+ });
385
+ const playgroundConfig = this.playgroundConfigEntity.config;
386
+ if (playgroundConfig?.scrollX === scrollX) {
387
+ if (added) {
388
+ this.containerX += SCROLL_DELTA;
389
+ } else {
390
+ this.containerX -= SCROLL_DELTA;
391
+ }
392
+ this.setDomStyle();
393
+ }
394
+ }, SCROLL_INTERVAL);
395
+ this._scrollXInterval = { interval, origin };
396
+ }
397
+ _stopScrollX() {
398
+ if (this._scrollXInterval) {
399
+ clearInterval(this._scrollXInterval.interval);
400
+ this._scrollXInterval = void 0;
401
+ }
402
+ }
403
+ _startScrollY(origin, added) {
404
+ if (this._scrollYInterval) {
405
+ return;
406
+ }
407
+ const interval = window.setInterval(() => {
408
+ const current = this._scrollYInterval;
409
+ if (!current) return;
410
+ const scrollY = current.origin = added ? current.origin + SCROLL_DELTA : current.origin - SCROLL_DELTA;
411
+ this.playgroundConfigEntity.updateConfig({
412
+ scrollY
413
+ });
414
+ const playgroundConfig = this.playgroundConfigEntity.config;
415
+ if (playgroundConfig?.scrollY === scrollY) {
416
+ if (added) {
417
+ this.containerY += SCROLL_DELTA;
418
+ } else {
419
+ this.containerY -= SCROLL_DELTA;
420
+ }
421
+ this.setDomStyle();
422
+ }
423
+ }, SCROLL_INTERVAL);
424
+ this._scrollYInterval = { interval, origin };
425
+ }
426
+ _stopScrollY() {
427
+ if (this._scrollYInterval) {
428
+ clearInterval(this._scrollYInterval.interval);
429
+ this._scrollYInterval = void 0;
430
+ }
431
+ }
432
+ stopAllScroll() {
433
+ this._stopScrollX();
434
+ this._stopScrollY();
435
+ }
436
+ setDomStyle() {
437
+ this.containerDom.style.left = `${this.containerX}px`;
438
+ this.containerDom.style.top = `${this.containerY}px`;
439
+ }
440
+ scrollDirection(e, containerDom, x, y) {
441
+ const playgroundConfig = this.playgroundConfigEntity.config;
442
+ const currentScrollX = playgroundConfig.scrollX;
443
+ const currentScrollY = playgroundConfig.scrollY;
444
+ this.containerDom = containerDom;
445
+ this.containerX = x;
446
+ this.containerY = y;
447
+ const mouseToBottom = playgroundConfig.height + playgroundConfig.clientY - e.clientY;
448
+ if (mouseToBottom < SCROLL_BOUNDING) {
449
+ this._startScrollY(currentScrollY, true);
450
+ return 1 /* BOTTOM */;
451
+ }
452
+ const mouseToTop = e.clientY - playgroundConfig.clientY;
453
+ if (mouseToTop < SCROLL_BOUNDING) {
454
+ this._startScrollY(currentScrollY, false);
455
+ return 0 /* TOP */;
456
+ }
457
+ this._stopScrollY();
458
+ const mouseToRight = playgroundConfig.width + playgroundConfig.clientX - e.clientX;
459
+ if (mouseToRight < SCROLL_BOUNDING) {
460
+ this._startScrollX(currentScrollX, true);
461
+ return 3 /* RIGHT */;
462
+ }
463
+ const mouseToLeft = e.clientX - playgroundConfig.clientX;
464
+ if (mouseToLeft < SCROLL_BOUNDING + EDITOR_LEFT_BAR_WIDTH) {
465
+ this._startScrollX(currentScrollX, false);
466
+ return 2 /* LEFT */;
467
+ }
468
+ this._stopScrollX();
469
+ return void 0;
470
+ }
471
+ dispose() {
472
+ this.toDispose.dispose();
473
+ }
474
+ };
475
+ FlowDragEntity.type = "FlowDragEntity";
476
+
477
+ // src/entities/flow-select-config-entity.tsx
478
+ var import_document4 = require("@flowgram.ai/document");
479
+ var import_core3 = require("@flowgram.ai/core");
480
+ var import_utils3 = require("@flowgram.ai/utils");
481
+
482
+ // src/utils/find-selected-nodes.ts
483
+ var import_lodash = require("lodash");
484
+ function getNodePath(node) {
485
+ const path = [node];
486
+ node = node.parent;
487
+ while (node) {
488
+ path.push(node);
489
+ node = node.parent;
490
+ }
491
+ return path.reverse();
492
+ }
493
+ function findRealEntity(entity) {
494
+ while (entity.originParent) {
495
+ entity = entity.originParent;
496
+ }
497
+ return entity;
498
+ }
499
+ function findSelectedNodes(nodes) {
500
+ if (nodes.length === 0) return [];
501
+ const nodePathList = nodes.map((n) => getNodePath(n));
502
+ const minLength = Math.min(...nodePathList.map((n) => n.length));
503
+ let index = 0;
504
+ let selectedItems = [];
505
+ while (index < minLength) {
506
+ selectedItems = (0, import_lodash.uniq)(nodePathList.map((p) => p[index]));
507
+ if (selectedItems.length > 1) {
508
+ break;
509
+ }
510
+ index += 1;
511
+ }
512
+ return (0, import_lodash.uniq)(selectedItems.map((item) => findRealEntity(item)));
513
+ }
514
+
515
+ // src/entities/flow-select-config-entity.tsx
516
+ var BOUNDS_PADDING_DEFAULT = 10;
517
+ var FlowSelectConfigEntity = class extends import_core3.ConfigEntity {
518
+ constructor() {
519
+ super(...arguments);
520
+ this.boundsPadding = BOUNDS_PADDING_DEFAULT;
521
+ }
522
+ getDefaultConfig() {
523
+ return {
524
+ selectedNodes: []
525
+ };
526
+ }
527
+ get selectedNodes() {
528
+ return this.config.selectedNodes;
529
+ }
530
+ /**
531
+ * 选中节点
532
+ * @param nodes
533
+ */
534
+ set selectedNodes(nodes) {
535
+ nodes = findSelectedNodes(nodes);
536
+ if (nodes.length !== this.config.selectedNodes.length || nodes.some((n) => !this.config.selectedNodes.includes(n))) {
537
+ this.config.selectedNodes.forEach((oldNode) => {
538
+ if (!nodes.includes(oldNode)) {
539
+ oldNode.getData(import_document4.FlowNodeRenderData).activated = false;
540
+ }
541
+ });
542
+ nodes.forEach((node) => {
543
+ node.getData(import_document4.FlowNodeRenderData).activated = true;
544
+ });
545
+ if (import_utils3.Compare.isArrayShallowChanged(this.config.selectedNodes, nodes)) {
546
+ this.updateConfig({
547
+ selectedNodes: nodes
548
+ });
549
+ }
550
+ }
551
+ }
552
+ /**
553
+ * 清除选中节点
554
+ */
555
+ clearSelectedNodes() {
556
+ if (this.config.selectedNodes.length === 0) return;
557
+ this.config.selectedNodes.forEach((node) => {
558
+ node.getData(import_document4.FlowNodeRenderData).activated = false;
559
+ });
560
+ this.updateConfig({
561
+ selectedNodes: []
562
+ });
563
+ }
564
+ /**
565
+ * 通过选择框选中节点
566
+ * @param rect
567
+ * @param transforms
568
+ */
569
+ selectFromBounds(rect, transforms) {
570
+ const selectedNodes = [];
571
+ transforms.forEach((transform) => {
572
+ if (import_utils3.Rectangle.intersects(rect, transform.bounds)) {
573
+ if (transform.entity.originParent) {
574
+ selectedNodes.push(transform.entity.originParent);
575
+ } else {
576
+ selectedNodes.push(transform.entity);
577
+ }
578
+ }
579
+ });
580
+ this.selectedNodes = selectedNodes;
581
+ }
582
+ /**
583
+ * 获取选中节点外围的最大边框
584
+ */
585
+ getSelectedBounds() {
586
+ const nodes = this.selectedNodes;
587
+ if (nodes.length === 0) {
588
+ return import_utils3.Rectangle.EMPTY;
589
+ }
590
+ return import_utils3.Rectangle.enlarge(nodes.map((n) => n.getData(import_document4.FlowNodeTransformData).bounds)).pad(
591
+ this.boundsPadding
592
+ );
593
+ }
594
+ };
595
+ FlowSelectConfigEntity.type = "FlowSelectConfigEntity";
596
+
597
+ // src/entities/selector-box-config-entity.ts
598
+ var import_core4 = require("@flowgram.ai/core");
599
+ var import_utils4 = require("@flowgram.ai/utils");
600
+ var SelectorBoxConfigEntity = class extends import_core4.ConfigEntity {
601
+ get dragInfo() {
602
+ return this.config;
603
+ }
604
+ setDragInfo(info) {
605
+ this.updateConfig(info);
606
+ }
607
+ get disabled() {
608
+ return this.config && !!this.config.disabled;
609
+ }
610
+ set disabled(disabled) {
611
+ this.updateConfig({
612
+ disabled
613
+ });
614
+ }
615
+ get isStart() {
616
+ return this.dragInfo.isStart;
617
+ }
618
+ get isMoving() {
619
+ return this.dragInfo.isMoving;
620
+ }
621
+ get position() {
622
+ const { dragInfo } = this;
623
+ return {
624
+ x: dragInfo.startPos.x < dragInfo.endPos.x ? dragInfo.startPos.x : dragInfo.endPos.x,
625
+ y: dragInfo.startPos.y < dragInfo.endPos.y ? dragInfo.startPos.y : dragInfo.endPos.y
626
+ };
627
+ }
628
+ get size() {
629
+ const { dragInfo } = this;
630
+ return {
631
+ width: Math.abs(dragInfo.startPos.x - dragInfo.endPos.x),
632
+ height: Math.abs(dragInfo.startPos.y - dragInfo.endPos.y)
633
+ };
634
+ }
635
+ get collapsed() {
636
+ const { size } = this;
637
+ return size.width === 0 && size.height === 0;
638
+ }
639
+ collapse() {
640
+ this.setDragInfo({
641
+ ...this.dragInfo,
642
+ isMoving: false,
643
+ isStart: false
644
+ });
645
+ }
646
+ toRectangle(scale) {
647
+ const { position, size } = this;
648
+ return new import_utils4.Rectangle(
649
+ position.x / scale,
650
+ position.y / scale,
651
+ size.width / scale,
652
+ size.height / scale
653
+ );
654
+ }
655
+ };
656
+ SelectorBoxConfigEntity.type = "SelectorBoxConfigEntity";
657
+
658
+ // src/layers/flow-nodes-transform-layer.tsx
659
+ var import_inversify2 = require("inversify");
660
+ var import_utils6 = require("@flowgram.ai/utils");
661
+ var import_document5 = require("@flowgram.ai/document");
662
+ var import_core5 = require("@flowgram.ai/core");
663
+
664
+ // src/flow-renderer-resize-observer.ts
665
+ var import_inversify = require("inversify");
666
+ var import_utils5 = require("@flowgram.ai/utils");
667
+
668
+ // src/utils/element.ts
669
+ var import_lodash2 = require("lodash");
670
+ var isHidden = (dom) => {
671
+ if (!dom || (0, import_lodash2.isNil)(dom?.offsetParent)) {
672
+ return true;
673
+ }
674
+ const style = window.getComputedStyle(dom);
675
+ if (style?.display === "none") {
676
+ return true;
677
+ }
678
+ return false;
679
+ };
680
+ var isRectInit = (rect) => {
681
+ if (!rect) {
682
+ return false;
683
+ }
684
+ if (rect.bottom === 0 && rect.height === 0 && rect.left === 0 && rect.right === 0 && rect.top === 0 && rect.width === 0 && rect.x === 0 && rect.y === 0) {
685
+ return false;
686
+ }
687
+ return true;
688
+ };
689
+
690
+ // src/flow-renderer-resize-observer.ts
691
+ var FlowRendererResizeObserver = class {
692
+ /**
693
+ * 监听元素 size,并同步到 transform
694
+ * @param el
695
+ * @param transform
696
+ */
697
+ observe(el, transform) {
698
+ const observer = new ResizeObserver((entries) => {
699
+ window.requestAnimationFrame(() => {
700
+ if (!Array.isArray(entries) || !entries.length) {
701
+ return;
702
+ }
703
+ const entry = entries[0];
704
+ const { contentRect, target } = entry;
705
+ const isContentRectInit = isRectInit(contentRect);
706
+ const isLeaveDOMTree = !target.parentNode;
707
+ const isHiddenElement = isHidden(target.parentNode);
708
+ if (isContentRectInit && !isLeaveDOMTree && !isHiddenElement) {
709
+ transform.size = {
710
+ width: Math.round(contentRect.width * 10) / 10,
711
+ height: Math.round(contentRect.height * 10) / 10
712
+ };
713
+ }
714
+ });
715
+ });
716
+ observer.observe(el);
717
+ return import_utils5.Disposable.create(() => {
718
+ observer.unobserve(el);
719
+ });
720
+ }
721
+ };
722
+ FlowRendererResizeObserver = __decorateClass([
723
+ (0, import_inversify.injectable)()
724
+ ], FlowRendererResizeObserver);
725
+
726
+ // src/layers/flow-nodes-transform-layer.tsx
727
+ var FlowNodesTransformLayer = class extends import_core5.Layer {
728
+ constructor() {
729
+ super(...arguments);
730
+ this.node = import_utils6.domUtils.createDivWithClass("gedit-flow-nodes-layer");
731
+ // onViewportChange() {
732
+ // this.throttleUpdate()
733
+ // }
734
+ // throttleUpdate = throttle(() => {
735
+ // this.renderCache.getFromCache().forEach((cache) => cache.updateBounds())
736
+ // }, 100)
737
+ this.renderCache = import_utils6.Cache.create(
738
+ (transform) => {
739
+ const { renderState } = transform;
740
+ const { node } = renderState;
741
+ const { entity } = transform;
742
+ node.id = entity.id;
743
+ let resizeDispose;
744
+ const append = () => {
745
+ if (resizeDispose) return;
746
+ this.renderElement.appendChild(node);
747
+ if (!entity.getNodeMeta().autoResizeDisable) {
748
+ resizeDispose = this.resizeObserver.observe(node, transform);
749
+ }
750
+ };
751
+ const dispose = () => {
752
+ if (!resizeDispose) return;
753
+ if (node.parentElement) {
754
+ this.renderElement.removeChild(node);
755
+ }
756
+ resizeDispose.dispose();
757
+ resizeDispose = void 0;
758
+ };
759
+ append();
760
+ return {
761
+ dispose,
762
+ updateBounds: () => {
763
+ const { bounds } = transform;
764
+ const rawX = parseFloat(node.style.left);
765
+ const rawY = parseFloat(node.style.top);
766
+ if (!this.isCoordEqual(rawX, bounds.x) || !this.isCoordEqual(rawY, bounds.y)) {
767
+ node.style.left = `${bounds.x}px`;
768
+ node.style.top = `${bounds.y}px`;
769
+ }
770
+ }
771
+ };
772
+ }
773
+ );
774
+ }
775
+ get transformVisibles() {
776
+ return this.document.getRenderDatas(import_document5.FlowNodeTransformData, false);
777
+ }
778
+ /**
779
+ * 监听缩放,目前采用整体缩放
780
+ * @param scale
781
+ */
782
+ onZoom(scale) {
783
+ this.node.style.transform = `scale(${scale})`;
784
+ }
785
+ dispose() {
786
+ this.renderCache.dispose();
787
+ super.dispose();
788
+ }
789
+ isCoordEqual(a, b) {
790
+ const browserCoordEpsilon = 0.05;
791
+ return Math.abs(a - b) < browserCoordEpsilon;
792
+ }
793
+ onReady() {
794
+ this.node.style.zIndex = "10";
795
+ }
796
+ get visibeBounds() {
797
+ return this.transformVisibles.map((transform) => transform.bounds);
798
+ }
799
+ /**
800
+ * 更新节点的 bounds 数据
801
+ */
802
+ updateNodesBounds() {
803
+ this.renderCache.getMoreByItems(this.transformVisibles).forEach((render) => render.updateBounds());
804
+ }
805
+ autorun() {
806
+ if (this.documentTransformer.loading) return;
807
+ this.documentTransformer.refresh();
808
+ this.updateNodesBounds();
809
+ }
810
+ get renderElement() {
811
+ if (typeof this.options.renderElement === "function") {
812
+ const element = this.options.renderElement();
813
+ if (element) {
814
+ return element;
815
+ }
816
+ } else if (typeof this.options.renderElement !== "undefined") {
817
+ return this.options.renderElement;
818
+ }
819
+ return this.node;
820
+ }
821
+ };
822
+ __decorateClass([
823
+ (0, import_inversify2.inject)(import_document5.FlowDocument)
824
+ ], FlowNodesTransformLayer.prototype, "document", 2);
825
+ __decorateClass([
826
+ (0, import_inversify2.inject)(FlowRendererResizeObserver)
827
+ ], FlowNodesTransformLayer.prototype, "resizeObserver", 2);
828
+ __decorateClass([
829
+ (0, import_core5.observeEntity)(import_document5.FlowDocumentTransformerEntity)
830
+ ], FlowNodesTransformLayer.prototype, "documentTransformer", 2);
831
+ __decorateClass([
832
+ (0, import_core5.observeEntityDatas)(import_document5.FlowNodeEntity, import_document5.FlowNodeTransformData)
833
+ ], FlowNodesTransformLayer.prototype, "_transforms", 2);
834
+ FlowNodesTransformLayer = __decorateClass([
835
+ (0, import_inversify2.injectable)()
836
+ ], FlowNodesTransformLayer);
837
+
838
+ // src/layers/flow-nodes-content-layer.tsx
839
+ var import_react_dom = __toESM(require("react-dom"));
840
+ var import_react = __toESM(require("react"));
841
+ var import_inversify4 = require("inversify");
842
+ var import_utils7 = require("@flowgram.ai/utils");
843
+ var import_document6 = require("@flowgram.ai/document");
844
+ var import_core7 = require("@flowgram.ai/core");
845
+
846
+ // src/flow-renderer-registry.ts
847
+ var import_inversify3 = require("inversify");
848
+ var import_i18n = require("@flowgram.ai/i18n");
849
+ var import_core6 = require("@flowgram.ai/core");
850
+
851
+ // src/flow-renderer-contribution.ts
852
+ var FlowRendererContribution = Symbol("FlowRendererContribution");
853
+
854
+ // src/flow-renderer-registry.ts
855
+ var FlowRendererComponentType = /* @__PURE__ */ ((FlowRendererComponentType2) => {
856
+ FlowRendererComponentType2[FlowRendererComponentType2["REACT"] = 0] = "REACT";
857
+ FlowRendererComponentType2[FlowRendererComponentType2["DOM"] = 1] = "DOM";
858
+ FlowRendererComponentType2[FlowRendererComponentType2["TEXT"] = 2] = "TEXT";
859
+ return FlowRendererComponentType2;
860
+ })(FlowRendererComponentType || {});
861
+ var FlowRendererKey = /* @__PURE__ */ ((FlowRendererKey2) => {
862
+ FlowRendererKey2["NODE_RENDER"] = "node-render";
863
+ FlowRendererKey2["ADDER"] = "adder";
864
+ FlowRendererKey2["COLLAPSE"] = "collapse";
865
+ FlowRendererKey2["BRANCH_ADDER"] = "branch-adder";
866
+ FlowRendererKey2["TRY_CATCH_COLLAPSE"] = "try-catch-collapse";
867
+ FlowRendererKey2["DRAG_NODE"] = "drag-node";
868
+ FlowRendererKey2["DRAGGABLE_ADDER"] = "draggable-adder";
869
+ FlowRendererKey2["DRAG_HIGHLIGHT_ADDER"] = "drag-highlight-adder";
870
+ FlowRendererKey2["DRAG_BRANCH_HIGHLIGHT_ADDER"] = "drag-branch-highlight-adder";
871
+ FlowRendererKey2["SELECTOR_BOX_POPOVER"] = "selector-box-popover";
872
+ FlowRendererKey2["CONTEXT_MENU_POPOVER"] = "context-menu-popover";
873
+ FlowRendererKey2["SUB_CANVAS"] = "sub-canvas";
874
+ FlowRendererKey2["ARROW_RENDERER"] = "arrow-renderer";
875
+ FlowRendererKey2["MARKER_ARROW"] = "marker-arrow";
876
+ FlowRendererKey2["MARKER_ACTIVATE_ARROW"] = "marker-active-arrow";
877
+ return FlowRendererKey2;
878
+ })(FlowRendererKey || {});
879
+ var FlowTextKey = /* @__PURE__ */ ((FlowTextKey2) => {
880
+ FlowTextKey2["LOOP_END_TEXT"] = "loop-end-text";
881
+ FlowTextKey2["LOOP_TRAVERSE_TEXT"] = "loop-traverse-text";
882
+ FlowTextKey2["LOOP_WHILE_TEXT"] = "loop-while-text";
883
+ FlowTextKey2["TRY_START_TEXT"] = "try-start-text";
884
+ FlowTextKey2["TRY_END_TEXT"] = "try-end-text";
885
+ FlowTextKey2["CATCH_TEXT"] = "catch-text";
886
+ return FlowTextKey2;
887
+ })(FlowTextKey || {});
888
+ var FlowRendererCommandCategory = /* @__PURE__ */ ((FlowRendererCommandCategory2) => {
889
+ FlowRendererCommandCategory2["SELECTOR_BOX"] = "SELECTOR_BOX";
890
+ return FlowRendererCommandCategory2;
891
+ })(FlowRendererCommandCategory || {});
892
+ var FlowRendererRegistry = class {
893
+ constructor() {
894
+ this.componentsMap = /* @__PURE__ */ new Map();
895
+ this.textMap = /* @__PURE__ */ new Map();
896
+ this.contribs = [];
897
+ }
898
+ init() {
899
+ this.contribs.forEach((contrib) => contrib.registerRenderer?.(this));
900
+ }
901
+ /**
902
+ * 注册 组件数据
903
+ */
904
+ registerRendererComponents(renderKey, comp) {
905
+ this.componentsMap.set(renderKey, comp);
906
+ }
907
+ registerReactComponent(renderKey, renderer) {
908
+ this.componentsMap.set(renderKey, {
909
+ type: 0 /* REACT */,
910
+ renderer
911
+ });
912
+ }
913
+ /**
914
+ * 注册文案
915
+ */
916
+ registerText(configs) {
917
+ Object.entries(configs).forEach(([key, value]) => {
918
+ this.textMap.set(key, value);
919
+ });
920
+ }
921
+ getText(textKey) {
922
+ return import_i18n.I18n.t(textKey, { defaultValue: "" }) || this.textMap.get(textKey);
923
+ }
924
+ /**
925
+ * TODO: support memo
926
+ */
927
+ getRendererComponent(renderKey) {
928
+ const comp = this.componentsMap.get(renderKey);
929
+ if (!comp) {
930
+ throw new Error(`Unknown render key ${renderKey}`);
931
+ }
932
+ return comp;
933
+ }
934
+ tryToGetRendererComponent(renderKey) {
935
+ return this.componentsMap.get(renderKey);
936
+ }
937
+ /**
938
+ * 注册画布层
939
+ */
940
+ registerLayers(...layerRegistries) {
941
+ layerRegistries.forEach((layer) => this.pipeline.registerLayer(layer));
942
+ }
943
+ /**
944
+ * 根据配置注册画布
945
+ * @param layerRegistry
946
+ * @param options
947
+ */
948
+ registerLayer(layerRegistry, options) {
949
+ this.pipeline.registerLayer(layerRegistry, options);
950
+ }
951
+ };
952
+ __decorateClass([
953
+ (0, import_inversify3.multiInject)(FlowRendererContribution),
954
+ (0, import_inversify3.optional)()
955
+ ], FlowRendererRegistry.prototype, "contribs", 2);
956
+ __decorateClass([
957
+ (0, import_inversify3.inject)(import_core6.PipelineRegistry)
958
+ ], FlowRendererRegistry.prototype, "pipeline", 2);
959
+ FlowRendererRegistry = __decorateClass([
960
+ (0, import_inversify3.injectable)()
961
+ ], FlowRendererRegistry);
962
+
963
+ // src/layers/flow-nodes-content-layer.tsx
964
+ var FlowNodesContentLayer = class extends import_core7.Layer {
965
+ constructor() {
966
+ super(...arguments);
967
+ this.renderMemoCache = /* @__PURE__ */ new WeakMap();
968
+ this.node = import_utils7.domUtils.createDivWithClass("gedit-flow-nodes-layer");
969
+ this.reactPortals = import_utils7.Cache.create(
970
+ (data) => {
971
+ const { node, entity } = data;
972
+ const { config } = this;
973
+ const PortalRenderer = this.getPortalRenderer(data);
974
+ function Portal() {
975
+ import_react.default.useEffect(() => {
976
+ if (!entity.getNodeMeta().autoResizeDisable && node.clientWidth && node.clientHeight) {
977
+ const transform = entity.getData(import_document6.FlowNodeTransformData);
978
+ if (transform)
979
+ transform.size = {
980
+ width: node.clientWidth,
981
+ height: node.clientHeight
982
+ };
983
+ }
984
+ }, [entity, node]);
985
+ return import_react_dom.default.createPortal(
986
+ /* @__PURE__ */ import_react.default.createElement(import_core7.PlaygroundEntityContext.Provider, { value: entity }, /* @__PURE__ */ import_react.default.createElement(
987
+ PortalRenderer,
988
+ {
989
+ node: entity,
990
+ version: data?.version,
991
+ activated: data?.activated,
992
+ readonly: config.readonly,
993
+ disabled: config.disabled
994
+ }
995
+ )),
996
+ node
997
+ );
998
+ }
999
+ return {
1000
+ id: node.id || entity.id,
1001
+ dispose: () => {
1002
+ },
1003
+ Portal
1004
+ };
1005
+ }
1006
+ );
1007
+ }
1008
+ get renderStatesVisible() {
1009
+ return this.document.getRenderDatas(import_document6.FlowNodeRenderData, false);
1010
+ }
1011
+ getPortalRenderer(data) {
1012
+ const meta = data.entity.getNodeMeta();
1013
+ const renderer = this.rendererRegistry.getRendererComponent(
1014
+ meta.renderKey || "node-render" /* NODE_RENDER */
1015
+ );
1016
+ const reactRenderer = renderer.renderer;
1017
+ let memoCache = this.renderMemoCache.get(reactRenderer);
1018
+ if (!memoCache) {
1019
+ memoCache = import_react.default.memo(reactRenderer);
1020
+ this.renderMemoCache.set(reactRenderer, memoCache);
1021
+ }
1022
+ return memoCache;
1023
+ }
1024
+ /**
1025
+ * 监听缩放,目前采用整体缩放
1026
+ * @param scale
1027
+ */
1028
+ onZoom(scale) {
1029
+ this.node.style.transform = `scale(${scale})`;
1030
+ }
1031
+ dispose() {
1032
+ this.reactPortals.dispose();
1033
+ super.dispose();
1034
+ }
1035
+ onReady() {
1036
+ this.node.style.zIndex = "10";
1037
+ }
1038
+ /**
1039
+ * 监听readonly和 disabled 状态 并刷新layer, 并刷新节点
1040
+ */
1041
+ onReadonlyOrDisabledChange() {
1042
+ this.render();
1043
+ }
1044
+ getPortals() {
1045
+ return this.reactPortals.getMoreByItems(this.renderStatesVisible);
1046
+ }
1047
+ render() {
1048
+ if (this.documentTransformer.loading) return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null);
1049
+ this.documentTransformer.refresh();
1050
+ return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, this.getPortals().map((portal) => /* @__PURE__ */ import_react.default.createElement(portal.Portal, { key: portal.id })));
1051
+ }
1052
+ };
1053
+ __decorateClass([
1054
+ (0, import_inversify4.inject)(import_document6.FlowDocument)
1055
+ ], FlowNodesContentLayer.prototype, "document", 2);
1056
+ __decorateClass([
1057
+ (0, import_inversify4.inject)(FlowRendererRegistry)
1058
+ ], FlowNodesContentLayer.prototype, "rendererRegistry", 2);
1059
+ __decorateClass([
1060
+ (0, import_core7.observeEntity)(import_document6.FlowDocumentTransformerEntity)
1061
+ ], FlowNodesContentLayer.prototype, "documentTransformer", 2);
1062
+ __decorateClass([
1063
+ (0, import_core7.observeEntityDatas)(import_document6.FlowNodeEntity, import_document6.FlowNodeRenderData)
1064
+ ], FlowNodesContentLayer.prototype, "_renderStates", 2);
1065
+ FlowNodesContentLayer = __decorateClass([
1066
+ (0, import_inversify4.injectable)()
1067
+ ], FlowNodesContentLayer);
1068
+
1069
+ // src/layers/flow-lines-layer.tsx
1070
+ var import_react8 = __toESM(require("react"));
1071
+ var import_lodash4 = require("lodash");
1072
+ var import_inversify5 = require("inversify");
1073
+ var import_utils12 = require("@flowgram.ai/utils");
1074
+ var import_document9 = require("@flowgram.ai/document");
1075
+ var import_core9 = require("@flowgram.ai/core");
1076
+
1077
+ // src/components/LinesRenderer.tsx
1078
+ var import_react7 = __toESM(require("react"));
1079
+ var import_utils11 = require("@flowgram.ai/utils");
1080
+ var import_document7 = require("@flowgram.ai/document");
1081
+ var import_document8 = require("@flowgram.ai/document");
1082
+
1083
+ // src/components/StraightLine.tsx
1084
+ var import_react2 = __toESM(require("react"));
1085
+ function StraightLine(props) {
1086
+ const { from, to, activated, style } = props;
1087
+ const { baseColor, baseActivatedColor } = useBaseColor();
1088
+ return /* @__PURE__ */ import_react2.default.createElement(
1089
+ "path",
1090
+ {
1091
+ "data-line-id": props.lineId,
1092
+ d: `M ${from.x} ${from.y} L ${to.x} ${to.y}`,
1093
+ ...DEFAULT_LINE_ATTRS,
1094
+ stroke: activated ? baseActivatedColor : baseColor,
1095
+ style
1096
+ }
1097
+ );
1098
+ }
1099
+ var StraightLine_default = StraightLine;
1100
+
1101
+ // src/components/RoundedTurningLine.tsx
1102
+ var import_react5 = __toESM(require("react"));
1103
+ var import_lodash3 = require("lodash");
1104
+ var import_utils9 = require("@flowgram.ai/utils");
1105
+ var import_core8 = require("@flowgram.ai/core");
1106
+
1107
+ // src/components/MarkerArrow.tsx
1108
+ var import_react3 = __toESM(require("react"));
1109
+ var MARK_ARROW_ID = "$marker_arrow$";
1110
+ function MarkerArrow(props) {
1111
+ const { baseColor } = useBaseColor();
1112
+ return /* @__PURE__ */ import_react3.default.createElement(
1113
+ "marker",
1114
+ {
1115
+ "data-line-id": props.id,
1116
+ id: props.id || MARK_ARROW_ID,
1117
+ markerWidth: "11",
1118
+ markerHeight: "14",
1119
+ refX: "10",
1120
+ refY: "7",
1121
+ orient: "auto"
1122
+ },
1123
+ /* @__PURE__ */ import_react3.default.createElement(
1124
+ "path",
1125
+ {
1126
+ d: "M9.6 5.2C10.8 6.1 10.8 7.9 9.6 8.8L3.6 13.3C2.11672 14.4125 0 13.3541 0 11.5L0 2.5C0 0.645898 2.11672 -0.412461 3.6 0.7L9.6 5.2Z",
1127
+ fill: baseColor
1128
+ }
1129
+ )
1130
+ );
1131
+ }
1132
+ var MarkerArrow_default = MarkerArrow;
1133
+
1134
+ // src/components/MarkerActivatedArrow.tsx
1135
+ var import_react4 = __toESM(require("react"));
1136
+ var MARK_ACTIVATED_ARROW_ID = "$marker_arrow_activated$";
1137
+ function MarkerActivatedArrow(props) {
1138
+ const { baseActivatedColor } = useBaseColor();
1139
+ return /* @__PURE__ */ import_react4.default.createElement(
1140
+ "marker",
1141
+ {
1142
+ "data-line-id": props.id,
1143
+ id: props.id || MARK_ACTIVATED_ARROW_ID,
1144
+ markerWidth: "11",
1145
+ markerHeight: "14",
1146
+ refX: "10",
1147
+ refY: "7",
1148
+ orient: "auto"
1149
+ },
1150
+ /* @__PURE__ */ import_react4.default.createElement(
1151
+ "path",
1152
+ {
1153
+ d: "M9.6 5.2C10.8 6.1 10.8 7.9 9.6 8.8L3.6 13.3C2.11672 14.4125 0 13.3541 0 11.5L0 2.5C0 0.645898 2.11672 -0.412461 3.6 0.7L9.6 5.2Z",
1154
+ fill: baseActivatedColor
1155
+ }
1156
+ )
1157
+ );
1158
+ }
1159
+ var MarkerActivatedArrow_default = MarkerActivatedArrow;
1160
+
1161
+ // src/components/RoundedTurningLine.tsx
1162
+ function MarkerDefs(props) {
1163
+ const renderRegistry = (0, import_core8.useService)(FlowRendererRegistry);
1164
+ const ArrowRenderer = renderRegistry?.tryToGetRendererComponent(
1165
+ props.activated ? "marker-active-arrow" /* MARKER_ACTIVATE_ARROW */ : "marker-arrow" /* MARKER_ARROW */
1166
+ );
1167
+ if (ArrowRenderer) {
1168
+ return /* @__PURE__ */ import_react5.default.createElement(ArrowRenderer.renderer, { ...props });
1169
+ }
1170
+ if (props.activated) {
1171
+ return /* @__PURE__ */ import_react5.default.createElement("defs", null, /* @__PURE__ */ import_react5.default.createElement(MarkerActivatedArrow_default, { id: props.id }));
1172
+ }
1173
+ return /* @__PURE__ */ import_react5.default.createElement("defs", null, /* @__PURE__ */ import_react5.default.createElement(MarkerArrow_default, { id: props.id }));
1174
+ }
1175
+ function RoundedTurningLine(props) {
1176
+ const { vertices, radius = DEFAULT_RADIUS, hide, xRadius, yRadius, ...line } = props;
1177
+ const { from, to, arrow, activated, style } = line || {};
1178
+ const { baseActivatedColor, baseColor } = useBaseColor();
1179
+ const realVertices = vertices || (props.isHorizontal ? getHorizontalVertices(line, xRadius, yRadius) : getVertices(line, xRadius, yRadius));
1180
+ const middleStr = (0, import_react5.useMemo)(
1181
+ () => realVertices.map((point, idx) => {
1182
+ const prev = realVertices[idx - 1] || from;
1183
+ const next = realVertices[idx + 1] || to;
1184
+ const prevDelta = { x: Math.abs(prev.x - point.x), y: Math.abs(prev.y - point.y) };
1185
+ const nextDelta = { x: Math.abs(next.x - point.x), y: Math.abs(next.y - point.y) };
1186
+ const isRightAngleX = prevDelta.x === 0 && nextDelta.y === 0;
1187
+ const isRightAngleY = prevDelta.y === 0 && nextDelta.x === 0;
1188
+ const isRightAngle = isRightAngleX || isRightAngleY;
1189
+ if (!isRightAngle) {
1190
+ console.error(`vertex ${point.x},${point.y} is not right angle`);
1191
+ }
1192
+ const inPoint = new import_utils9.Point().copyFrom(point);
1193
+ const outPoint = new import_utils9.Point().copyFrom(point);
1194
+ const radiusX = (0, import_lodash3.isNil)(point.radiusX) ? radius : point.radiusX;
1195
+ const radiusY = (0, import_lodash3.isNil)(point.radiusY) ? radius : point.radiusY;
1196
+ let rx = radiusX;
1197
+ let ry = radiusY;
1198
+ if (isRightAngleX) {
1199
+ ry = Math.min(prevDelta.y, radiusY);
1200
+ const moveY = (0, import_lodash3.isNil)(point.moveY) ? ry : point.moveY;
1201
+ inPoint.y += from.y < point.y ? -moveY : +moveY;
1202
+ rx = Math.min(nextDelta.x, radiusX);
1203
+ const moveX = (0, import_lodash3.isNil)(point.moveX) ? rx : point.moveX;
1204
+ outPoint.x += to.x < point.x ? -moveX : +moveX;
1205
+ }
1206
+ if (isRightAngleY) {
1207
+ rx = Math.min(prevDelta.x, radiusX);
1208
+ const moveX = (0, import_lodash3.isNil)(point.moveX) ? rx : point.moveX;
1209
+ inPoint.x += from.x < point.x ? -moveX : +moveX;
1210
+ ry = Math.min(nextDelta.y, radiusY);
1211
+ const moveY = (0, import_lodash3.isNil)(point.moveY) ? ry : point.moveY;
1212
+ outPoint.y += to.y < point.y ? -moveY : +moveY;
1213
+ }
1214
+ const crossProduct = (point.x - inPoint.x) * (outPoint.y - inPoint.y) - (point.y - inPoint.y) * (outPoint.x - inPoint.x);
1215
+ const isClockWise = crossProduct > 0;
1216
+ return `L ${inPoint.x} ${inPoint.y} A ${rx} ${ry} 0 0 ${isClockWise ? 1 : 0} ${outPoint.x} ${outPoint.y}`;
1217
+ }).join(" "),
1218
+ [realVertices]
1219
+ );
1220
+ if (hide) {
1221
+ return null;
1222
+ }
1223
+ const pathStr = `M ${from.x} ${from.y} ${middleStr} L ${to.x} ${to.y}`;
1224
+ const markerId = activated ? `${MARK_ACTIVATED_ARROW_ID}${props.lineId}` : `${MARK_ARROW_ID}${props.lineId}`;
1225
+ return /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, arrow ? /* @__PURE__ */ import_react5.default.createElement(MarkerDefs, { id: markerId, activated }) : null, /* @__PURE__ */ import_react5.default.createElement(
1226
+ "path",
1227
+ {
1228
+ "data-line-id": props.lineId,
1229
+ d: pathStr,
1230
+ ...DEFAULT_LINE_ATTRS,
1231
+ stroke: activated ? baseActivatedColor : baseColor,
1232
+ ...arrow ? {
1233
+ markerEnd: `url(#${markerId})`
1234
+ } : {},
1235
+ style
1236
+ }
1237
+ ));
1238
+ }
1239
+ var RoundedTurningLine_default = RoundedTurningLine;
1240
+
1241
+ // src/components/CustomLine.tsx
1242
+ var import_react6 = __toESM(require("react"));
1243
+ function CustomLine(props) {
1244
+ const { renderKey, rendererRegistry, ...line } = props;
1245
+ if (!renderKey) {
1246
+ return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null);
1247
+ }
1248
+ const renderer = rendererRegistry.getRendererComponent(renderKey);
1249
+ if (!renderer) {
1250
+ return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null);
1251
+ }
1252
+ const Component = renderer.renderer;
1253
+ return /* @__PURE__ */ import_react6.default.createElement(Component, { lineId: props.lineId, ...line });
1254
+ }
1255
+ var CustomLine_default = CustomLine;
1256
+
1257
+ // src/components/LinesRenderer.tsx
1258
+ function createLines(props) {
1259
+ const { data, rendererRegistry, linesSave, dragService } = props;
1260
+ const { lines, entity } = data || {};
1261
+ const xRadius = (0, import_document8.getDefaultSpacing)(entity, import_document7.DefaultSpacingKey.ROUNDED_LINE_X_RADIUS);
1262
+ const yRadius = (0, import_document8.getDefaultSpacing)(entity, import_document7.DefaultSpacingKey.ROUNDED_LINE_Y_RADIUS);
1263
+ const renderLine = (line, index) => {
1264
+ const { renderData } = data;
1265
+ const { isVertical } = data.entity;
1266
+ const { lineActivated } = renderData || {};
1267
+ const draggingLineHide = (line.type === import_document7.FlowTransitionLineEnum.DRAGGING_LINE || line.isDraggingLine) && !dragService.isDroppableBranch(data.entity, line.side);
1268
+ const draggingLineActivated = (line.type === import_document7.FlowTransitionLineEnum.DRAGGING_LINE || line.isDraggingLine) && data.entity?.id === dragService.dropNodeId && line.side === dragService.labelSide;
1269
+ switch (line.type) {
1270
+ case import_document7.FlowTransitionLineEnum.STRAIGHT_LINE:
1271
+ return /* @__PURE__ */ import_react7.default.createElement(
1272
+ StraightLine_default,
1273
+ {
1274
+ key: `${data.entity.id}_${index}`,
1275
+ lineId: data.entity.id,
1276
+ activated: lineActivated,
1277
+ ...line
1278
+ }
1279
+ );
1280
+ case import_document7.FlowTransitionLineEnum.DIVERGE_LINE:
1281
+ case import_document7.FlowTransitionLineEnum.DRAGGING_LINE:
1282
+ case import_document7.FlowTransitionLineEnum.MERGE_LINE:
1283
+ case import_document7.FlowTransitionLineEnum.ROUNDED_LINE:
1284
+ return /* @__PURE__ */ import_react7.default.createElement(
1285
+ RoundedTurningLine_default,
1286
+ {
1287
+ key: `${data.entity.id}_${index}`,
1288
+ lineId: data.entity.id,
1289
+ isHorizontal: !isVertical,
1290
+ activated: lineActivated || draggingLineActivated,
1291
+ ...line,
1292
+ xRadius,
1293
+ yRadius,
1294
+ hide: draggingLineHide
1295
+ }
1296
+ );
1297
+ case import_document7.FlowTransitionLineEnum.CUSTOM_LINE:
1298
+ return /* @__PURE__ */ import_react7.default.createElement(
1299
+ CustomLine_default,
1300
+ {
1301
+ key: `${data.entity.id}_${index}`,
1302
+ lineId: data.entity.id,
1303
+ ...line,
1304
+ rendererRegistry
1305
+ }
1306
+ );
1307
+ default:
1308
+ break;
1309
+ }
1310
+ return void 0;
1311
+ };
1312
+ lines.forEach((line, index) => {
1313
+ const bounds = import_utils11.Rectangle.createRectangleWithTwoPoints(line.from, line.to).pad(10);
1314
+ if (props.isViewportVisible(bounds)) {
1315
+ const jsxEl = renderLine(line, index);
1316
+ if (jsxEl) linesSave.push(jsxEl);
1317
+ }
1318
+ });
1319
+ }
1320
+
1321
+ // src/layers/flow-lines-layer.tsx
1322
+ var FlowLinesLayer = class extends import_core9.Layer {
1323
+ constructor() {
1324
+ super(...arguments);
1325
+ this.node = import_utils12.domUtils.createDivWithClass("gedit-flow-lines-layer");
1326
+ /**
1327
+ * 可视区域变化
1328
+ */
1329
+ this.onViewportChange = (0, import_lodash4.throttle)(() => {
1330
+ this.render();
1331
+ }, 100);
1332
+ }
1333
+ get transitions() {
1334
+ return this.document.getRenderDatas(import_document9.FlowNodeTransitionData);
1335
+ }
1336
+ onZoom() {
1337
+ const svgContainer = this.node.querySelector("svg.flow-lines-container");
1338
+ svgContainer?.setAttribute?.("viewBox", this.viewBox);
1339
+ }
1340
+ onReady() {
1341
+ this.node.style.zIndex = "1";
1342
+ }
1343
+ get viewBox() {
1344
+ const ratio = 1e3 / this.config.finalScale;
1345
+ return `0 0 ${ratio} ${ratio}`;
1346
+ }
1347
+ render() {
1348
+ const allLines = [];
1349
+ const isViewportVisible = this.config.isViewportVisible.bind(this.config);
1350
+ if (this.documentTransformer.loading) return /* @__PURE__ */ import_react8.default.createElement(import_react8.default.Fragment, null);
1351
+ this.documentTransformer.refresh();
1352
+ this.transitions.forEach((transition) => {
1353
+ createLines({
1354
+ data: transition,
1355
+ rendererRegistry: this.rendererRegistry,
1356
+ isViewportVisible,
1357
+ linesSave: allLines,
1358
+ dragService: this.dragService
1359
+ });
1360
+ });
1361
+ const { activateLines = [], normalLines = [] } = (0, import_lodash4.groupBy)(
1362
+ allLines,
1363
+ (line) => line.props.activated ? "activateLines" : "normalLines"
1364
+ );
1365
+ const resultLines = [...normalLines, ...activateLines];
1366
+ return /* @__PURE__ */ import_react8.default.createElement(
1367
+ "svg",
1368
+ {
1369
+ className: "flow-lines-container",
1370
+ width: "1000",
1371
+ height: "1000",
1372
+ overflow: "visible",
1373
+ viewBox: this.viewBox,
1374
+ xmlns: "http://www.w3.org/2000/svg"
1375
+ },
1376
+ resultLines
1377
+ );
1378
+ }
1379
+ };
1380
+ __decorateClass([
1381
+ (0, import_inversify5.inject)(import_document9.FlowDocument)
1382
+ ], FlowLinesLayer.prototype, "document", 2);
1383
+ __decorateClass([
1384
+ (0, import_inversify5.inject)(import_document9.FlowDragService)
1385
+ ], FlowLinesLayer.prototype, "dragService", 2);
1386
+ __decorateClass([
1387
+ (0, import_inversify5.inject)(FlowRendererRegistry)
1388
+ ], FlowLinesLayer.prototype, "rendererRegistry", 2);
1389
+ __decorateClass([
1390
+ (0, import_core9.observeEntity)(import_document9.FlowDocumentTransformerEntity)
1391
+ ], FlowLinesLayer.prototype, "documentTransformer", 2);
1392
+ __decorateClass([
1393
+ (0, import_core9.observeEntity)(import_document9.FlowRendererStateEntity)
1394
+ ], FlowLinesLayer.prototype, "flowRenderState", 2);
1395
+ __decorateClass([
1396
+ (0, import_core9.observeEntityDatas)(import_document9.FlowNodeEntity, import_document9.FlowNodeTransitionData)
1397
+ ], FlowLinesLayer.prototype, "_transitions", 2);
1398
+ FlowLinesLayer = __decorateClass([
1399
+ (0, import_inversify5.injectable)()
1400
+ ], FlowLinesLayer);
1401
+
1402
+ // src/layers/flow-labels-layer.tsx
1403
+ var import_react14 = __toESM(require("react"));
1404
+ var import_lodash5 = require("lodash");
1405
+ var import_inversify6 = require("inversify");
1406
+ var import_utils16 = require("@flowgram.ai/utils");
1407
+ var import_document15 = require("@flowgram.ai/document");
1408
+ var import_core12 = require("@flowgram.ai/core");
1409
+
1410
+ // src/components/LabelsRenderer.tsx
1411
+ var import_react13 = __toESM(require("react"));
1412
+ var import_utils15 = require("@flowgram.ai/utils");
1413
+ var import_document14 = require("@flowgram.ai/document");
1414
+
1415
+ // src/components/CollapseAdder.tsx
1416
+ var import_react11 = __toESM(require("react"));
1417
+ var import_document12 = require("@flowgram.ai/document");
1418
+
1419
+ // src/components/Collapse.tsx
1420
+ var import_react9 = __toESM(require("react"));
1421
+ var import_document10 = require("@flowgram.ai/document");
1422
+ function Collapse(props) {
1423
+ const {
1424
+ data,
1425
+ rendererRegistry,
1426
+ forceVisible,
1427
+ hoverHeight = getTransitionLabelHoverHeight(data),
1428
+ hoverWidth = getTransitionLabelHoverWidth(data),
1429
+ wrapperStyle,
1430
+ ...restProps
1431
+ } = props;
1432
+ const { activateNode } = restProps;
1433
+ const [hoverActivated, setHoverActivated] = (0, import_react9.useState)(false);
1434
+ const activateData = activateNode?.getData(import_document10.FlowNodeRenderData);
1435
+ const handleMouseEnter = (0, import_react9.useCallback)(() => {
1436
+ setHoverActivated(true);
1437
+ activateData?.toggleMouseEnter();
1438
+ }, []);
1439
+ const handleMouseLeave = (0, import_react9.useCallback)(() => {
1440
+ setHoverActivated(false);
1441
+ activateData?.toggleMouseLeave();
1442
+ }, []);
1443
+ const collapseOpener = rendererRegistry.getRendererComponent("collapse" /* COLLAPSE */);
1444
+ const node = data.entity;
1445
+ const child = import_react9.default.createElement(
1446
+ collapseOpener.renderer,
1447
+ {
1448
+ node,
1449
+ collapseNode: node,
1450
+ ...restProps,
1451
+ hoverActivated
1452
+ }
1453
+ );
1454
+ const isChildVisible = data.collapsed || activateData?.hovered || hoverActivated || forceVisible;
1455
+ return /* @__PURE__ */ import_react9.default.createElement(
1456
+ "div",
1457
+ {
1458
+ className: "flow-canvas-collapse",
1459
+ onMouseEnter: handleMouseEnter,
1460
+ onMouseLeave: handleMouseLeave,
1461
+ style: {
1462
+ width: hoverWidth,
1463
+ height: hoverHeight,
1464
+ display: "flex",
1465
+ justifyContent: "center",
1466
+ alignItems: "center",
1467
+ ...wrapperStyle
1468
+ }
1469
+ },
1470
+ isChildVisible ? child : null
1471
+ );
1472
+ }
1473
+
1474
+ // src/components/Adder.tsx
1475
+ var import_react10 = __toESM(require("react"));
1476
+ var import_document11 = require("@flowgram.ai/document");
1477
+ var import_core10 = require("@flowgram.ai/core");
1478
+ var getFlowRenderKey = (node, { dragService }) => {
1479
+ if (dragService && dragService.dragging && dragService.isDroppableNode(node)) {
1480
+ if (dragService.dropNodeId === node.id) {
1481
+ return "drag-highlight-adder" /* DRAG_HIGHLIGHT_ADDER */;
1482
+ }
1483
+ return "draggable-adder" /* DRAGGABLE_ADDER */;
1484
+ }
1485
+ return "adder" /* ADDER */;
1486
+ };
1487
+ function Adder(props) {
1488
+ const {
1489
+ data,
1490
+ rendererRegistry,
1491
+ hoverHeight = getTransitionLabelHoverHeight(data),
1492
+ hoverWidth = getTransitionLabelHoverWidth(data),
1493
+ ...restProps
1494
+ } = props;
1495
+ const [hoverActivated, setHoverActivated] = (0, import_react10.useState)(false);
1496
+ const handleMouseEnter = (0, import_react10.useCallback)(() => setHoverActivated(true), []);
1497
+ const handleMouseLeave = (0, import_react10.useCallback)(() => setHoverActivated(false), []);
1498
+ const node = data.entity;
1499
+ const dragService = (0, import_core10.useService)(import_document11.FlowDragService);
1500
+ const flowRenderKey = getFlowRenderKey(node, { dragService });
1501
+ const adder = rendererRegistry.getRendererComponent(flowRenderKey);
1502
+ const from = node;
1503
+ const to = data.entity.document.renderTree.getOriginInfo(node).next;
1504
+ const renderTo = node.next;
1505
+ const child = import_react10.default.createElement(
1506
+ adder.renderer,
1507
+ {
1508
+ node,
1509
+ from,
1510
+ to,
1511
+ renderTo,
1512
+ hoverActivated,
1513
+ setHoverActivated,
1514
+ hoverWidth,
1515
+ hoverHeight,
1516
+ ...restProps
1517
+ }
1518
+ );
1519
+ return (
1520
+ // eslint-disable-next-line react/jsx-filename-extension
1521
+ /* @__PURE__ */ import_react10.default.createElement(
1522
+ "div",
1523
+ {
1524
+ className: "flow-canvas-adder",
1525
+ "data-testid": "sdk.flowcanvas.line.adder",
1526
+ "data-from": from.id,
1527
+ "data-to": to?.id ?? "",
1528
+ onMouseEnter: handleMouseEnter,
1529
+ onMouseLeave: handleMouseLeave,
1530
+ style: {
1531
+ width: hoverWidth,
1532
+ height: hoverHeight,
1533
+ display: "flex",
1534
+ justifyContent: "center",
1535
+ alignItems: "center"
1536
+ }
1537
+ },
1538
+ child
1539
+ )
1540
+ );
1541
+ }
1542
+
1543
+ // src/components/CollapseAdder.tsx
1544
+ function CollapseAdder(props) {
1545
+ const { data, rendererRegistry, ...restProps } = props;
1546
+ const { activateNode } = restProps;
1547
+ const [hoverActivated, setHoverActivated] = (0, import_react11.useState)(false);
1548
+ const activateData = activateNode?.getData(import_document12.FlowNodeRenderData);
1549
+ const handleMouseEnter = (0, import_react11.useCallback)(() => {
1550
+ setHoverActivated(true);
1551
+ }, []);
1552
+ const handleMouseLeave = (0, import_react11.useCallback)(() => {
1553
+ setHoverActivated(false);
1554
+ }, []);
1555
+ const isVertical = activateNode?.isVertical;
1556
+ const activated = activateData?.hovered || hoverActivated;
1557
+ if (isVertical) {
1558
+ return /* @__PURE__ */ import_react11.default.createElement(
1559
+ "div",
1560
+ {
1561
+ className: "flow-canvas-collapse-adder",
1562
+ onMouseEnter: handleMouseEnter,
1563
+ onMouseLeave: handleMouseLeave
1564
+ },
1565
+ (activated || data.collapsed) && /* @__PURE__ */ import_react11.default.createElement(
1566
+ Collapse,
1567
+ {
1568
+ forceVisible: true,
1569
+ ...props,
1570
+ wrapperStyle: {
1571
+ alignItems: "flex-end"
1572
+ },
1573
+ hoverHeight: 20
1574
+ }
1575
+ ),
1576
+ !data.collapsed && /* @__PURE__ */ import_react11.default.createElement(Adder, { ...props, hoverHeight: activated ? 20 : 40, hoverActivated: activated })
1577
+ );
1578
+ }
1579
+ return /* @__PURE__ */ import_react11.default.createElement(
1580
+ "div",
1581
+ {
1582
+ className: "flow-canvas-collapse-adder",
1583
+ onMouseEnter: handleMouseEnter,
1584
+ onMouseLeave: handleMouseLeave,
1585
+ style: {
1586
+ display: data.collapsed ? "block" : "flex"
1587
+ }
1588
+ },
1589
+ (activated || data.collapsed) && /* @__PURE__ */ import_react11.default.createElement(
1590
+ Collapse,
1591
+ {
1592
+ forceVisible: true,
1593
+ ...props,
1594
+ wrapperStyle: {
1595
+ justifyContent: "flex-end"
1596
+ },
1597
+ hoverWidth: 20
1598
+ }
1599
+ ),
1600
+ !data.collapsed && /* @__PURE__ */ import_react11.default.createElement(Adder, { ...props, hoverWidth: activated ? 20 : 40, hoverActivated: activated })
1601
+ );
1602
+ }
1603
+
1604
+ // src/components/BranchDraggableRenderer.tsx
1605
+ var import_react12 = __toESM(require("react"));
1606
+ var import_document13 = require("@flowgram.ai/document");
1607
+ var import_core11 = require("@flowgram.ai/core");
1608
+ var getFlowRenderKey2 = (node, { dragService, side }) => {
1609
+ if (dragService.isDragBranch && side && dragService.labelSide === side && dragService.isDroppableBranch(node, side)) {
1610
+ if (dragService.dropNodeId === node.id) {
1611
+ return "drag-branch-highlight-adder" /* DRAG_BRANCH_HIGHLIGHT_ADDER */;
1612
+ }
1613
+ return "draggable-adder" /* DRAGGABLE_ADDER */;
1614
+ }
1615
+ return "";
1616
+ };
1617
+ function BranchDraggableRenderer(props) {
1618
+ const { data, rendererRegistry, side, ...restProps } = props;
1619
+ const node = data.entity;
1620
+ const dragService = (0, import_core11.useService)(import_document13.FlowDragService);
1621
+ const flowRenderKey = getFlowRenderKey2(node, { side, dragService });
1622
+ if (!flowRenderKey) {
1623
+ return null;
1624
+ }
1625
+ const adder = rendererRegistry.getRendererComponent(flowRenderKey);
1626
+ const from = node;
1627
+ const to = data.entity.document.renderTree.getOriginInfo(node).next;
1628
+ const renderTo = node.next;
1629
+ const child = import_react12.default.createElement(
1630
+ adder.renderer,
1631
+ {
1632
+ node,
1633
+ from,
1634
+ to,
1635
+ renderTo,
1636
+ ...restProps
1637
+ }
1638
+ );
1639
+ return /* @__PURE__ */ import_react12.default.createElement("div", { className: "flow-canvas-branch-draggable-adder" }, child);
1640
+ }
1641
+
1642
+ // src/components/LabelsRenderer.tsx
1643
+ var TEXT_LABEL_STYLE = {
1644
+ fontSize: 12,
1645
+ color: "#8F959E",
1646
+ textAlign: "center",
1647
+ whiteSpace: "nowrap",
1648
+ backgroundColor: "var(--g-editor-background)",
1649
+ lineHeight: "20px"
1650
+ };
1651
+ var LABEL_MAX_WIDTH = 150;
1652
+ var LABEL_MAX_HEIGHT = 60;
1653
+ function getLabelBounds(offset) {
1654
+ return new import_utils15.Rectangle(
1655
+ offset.x - LABEL_MAX_WIDTH / 2,
1656
+ offset.y - LABEL_MAX_HEIGHT / 2,
1657
+ LABEL_MAX_WIDTH,
1658
+ LABEL_MAX_HEIGHT
1659
+ );
1660
+ }
1661
+ function createLabels(labelProps) {
1662
+ const { data, rendererRegistry, labelsSave, getLabelColor } = labelProps;
1663
+ const { labels, renderData } = data || {};
1664
+ const { activated } = renderData || {};
1665
+ const renderLabel = (label, index) => {
1666
+ const { offset, renderKey, props, rotate, type } = label || {};
1667
+ const offsetX = offset.x;
1668
+ const offsetY = offset.y;
1669
+ let child = null;
1670
+ switch (type) {
1671
+ case import_document14.FlowTransitionLabelEnum.BRANCH_DRAGGING_LABEL:
1672
+ child = /* @__PURE__ */ import_react13.default.createElement(
1673
+ BranchDraggableRenderer,
1674
+ {
1675
+ labelId: label.labelId || labelProps.data.entity.id,
1676
+ rendererRegistry,
1677
+ data,
1678
+ ...props
1679
+ }
1680
+ );
1681
+ break;
1682
+ case import_document14.FlowTransitionLabelEnum.ADDER_LABEL:
1683
+ child = /* @__PURE__ */ import_react13.default.createElement(
1684
+ Adder,
1685
+ {
1686
+ labelId: label.labelId || labelProps.data.entity.id,
1687
+ rendererRegistry,
1688
+ data,
1689
+ ...props
1690
+ }
1691
+ );
1692
+ break;
1693
+ case import_document14.FlowTransitionLabelEnum.COLLAPSE_LABEL:
1694
+ child = /* @__PURE__ */ import_react13.default.createElement(
1695
+ Collapse,
1696
+ {
1697
+ labelId: label.labelId || labelProps.data.entity.id,
1698
+ rendererRegistry,
1699
+ data,
1700
+ ...props
1701
+ }
1702
+ );
1703
+ break;
1704
+ case import_document14.FlowTransitionLabelEnum.COLLAPSE_ADDER_LABEL:
1705
+ child = /* @__PURE__ */ import_react13.default.createElement(
1706
+ CollapseAdder,
1707
+ {
1708
+ labelId: label.labelId || labelProps.data.entity.id,
1709
+ rendererRegistry,
1710
+ data,
1711
+ ...props
1712
+ }
1713
+ );
1714
+ break;
1715
+ case import_document14.FlowTransitionLabelEnum.TEXT_LABEL:
1716
+ if (!renderKey) {
1717
+ return null;
1718
+ }
1719
+ const text = rendererRegistry.getText(renderKey) || renderKey;
1720
+ child = /* @__PURE__ */ import_react13.default.createElement(
1721
+ "div",
1722
+ {
1723
+ "data-label-id": label.labelId || labelProps.data.entity.id,
1724
+ style: {
1725
+ ...TEXT_LABEL_STYLE,
1726
+ ...props?.style,
1727
+ color: getLabelColor(activated),
1728
+ transform: rotate ? `rotate(${rotate})` : void 0
1729
+ }
1730
+ },
1731
+ text
1732
+ );
1733
+ break;
1734
+ case import_document14.FlowTransitionLabelEnum.CUSTOM_LABEL:
1735
+ if (!renderKey) {
1736
+ return null;
1737
+ }
1738
+ try {
1739
+ const renderer = rendererRegistry.getRendererComponent(renderKey);
1740
+ child = import_react13.default.createElement(
1741
+ renderer.renderer,
1742
+ {
1743
+ node: data.entity,
1744
+ labelId: label.labelId || labelProps.data.entity.id,
1745
+ ...props
1746
+ }
1747
+ );
1748
+ } catch (err) {
1749
+ console.error(err);
1750
+ child = renderKey;
1751
+ }
1752
+ break;
1753
+ default:
1754
+ break;
1755
+ }
1756
+ return /* @__PURE__ */ import_react13.default.createElement(
1757
+ "div",
1758
+ {
1759
+ key: `${data.entity.id}${index}`,
1760
+ "data-label-id": label.labelId || labelProps.data.entity.id,
1761
+ style: {
1762
+ position: "absolute",
1763
+ left: offsetX,
1764
+ top: offsetY,
1765
+ transform: "translate(-50%, -50%)"
1766
+ }
1767
+ },
1768
+ child
1769
+ );
1770
+ };
1771
+ labels.forEach((label, index) => {
1772
+ if (labelProps.isViewportVisible(getLabelBounds(label.offset))) {
1773
+ labelsSave.push(renderLabel(label, index));
1774
+ }
1775
+ });
1776
+ }
1777
+
1778
+ // src/layers/flow-labels-layer.tsx
1779
+ var FlowLabelsLayer = class extends import_core12.Layer {
1780
+ constructor() {
1781
+ super(...arguments);
1782
+ this.node = import_utils16.domUtils.createDivWithClass("gedit-flow-labels-layer");
1783
+ /**
1784
+ * 可视区域变化
1785
+ */
1786
+ this.onViewportChange = (0, import_lodash5.throttle)(() => {
1787
+ this.render();
1788
+ }, 100);
1789
+ }
1790
+ get transitions() {
1791
+ return this.document.getRenderDatas(import_document15.FlowNodeTransitionData);
1792
+ }
1793
+ /**
1794
+ * 监听缩放,目前采用整体缩放
1795
+ * @param scale
1796
+ */
1797
+ onZoom(scale) {
1798
+ this.node.style.transform = `scale(${scale})`;
1799
+ }
1800
+ onReady() {
1801
+ this.node.style.zIndex = "9";
1802
+ }
1803
+ /**
1804
+ * 监听readonly和 disabled 状态 并刷新layer, 并刷新
1805
+ */
1806
+ onReadonlyOrDisabledChange() {
1807
+ this.render();
1808
+ }
1809
+ render() {
1810
+ const labels = [];
1811
+ if (this.documentTransformer?.loading) return /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null);
1812
+ this.documentTransformer?.refresh?.();
1813
+ const { baseActivatedColor, baseColor } = useBaseColor();
1814
+ const isViewportVisible = this.config.isViewportVisible.bind(this.config);
1815
+ this.transitions.forEach((transition) => {
1816
+ createLabels({
1817
+ data: transition,
1818
+ rendererRegistry: this.rendererRegistry,
1819
+ isViewportVisible,
1820
+ labelsSave: labels,
1821
+ getLabelColor: (activated) => activated ? baseActivatedColor : baseColor
1822
+ });
1823
+ });
1824
+ return /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null, labels);
1825
+ }
1826
+ };
1827
+ __decorateClass([
1828
+ (0, import_inversify6.inject)(import_document15.FlowDocument)
1829
+ ], FlowLabelsLayer.prototype, "document", 2);
1830
+ __decorateClass([
1831
+ (0, import_inversify6.inject)(FlowRendererRegistry)
1832
+ ], FlowLabelsLayer.prototype, "rendererRegistry", 2);
1833
+ __decorateClass([
1834
+ (0, import_core12.observeEntity)(import_document15.FlowDocumentTransformerEntity)
1835
+ ], FlowLabelsLayer.prototype, "documentTransformer", 2);
1836
+ __decorateClass([
1837
+ (0, import_core12.observeEntity)(import_document15.FlowRendererStateEntity)
1838
+ ], FlowLabelsLayer.prototype, "flowRenderState", 2);
1839
+ __decorateClass([
1840
+ (0, import_core12.observeEntityDatas)(import_document15.FlowNodeEntity, import_document15.FlowNodeTransitionData)
1841
+ ], FlowLabelsLayer.prototype, "_transitions", 2);
1842
+ FlowLabelsLayer = __decorateClass([
1843
+ (0, import_inversify6.injectable)()
1844
+ ], FlowLabelsLayer);
1845
+
1846
+ // src/layers/flow-debug-layer.tsx
1847
+ var import_inversify7 = require("inversify");
1848
+ var import_utils18 = require("@flowgram.ai/utils");
1849
+ var import_document16 = require("@flowgram.ai/document");
1850
+ var import_core13 = require("@flowgram.ai/core");
1851
+
1852
+ // src/utils/scroll-limit.ts
1853
+ var import_utils17 = require("@flowgram.ai/utils");
1854
+ var SCROLL_LIMIT_PADDING = -120;
1855
+ function getScrollViewport(scrollData, config) {
1856
+ const scale = config.finalScale;
1857
+ return new import_utils17.Rectangle(
1858
+ scrollData.scrollX / scale,
1859
+ scrollData.scrollY / scale,
1860
+ config.config.width / scale,
1861
+ config.config.height / scale
1862
+ ).pad(SCROLL_LIMIT_PADDING / scale, SCROLL_LIMIT_PADDING / scale);
1863
+ }
1864
+ function scrollLimit(scroll, boundsList, config, initScroll) {
1865
+ scroll = { ...scroll };
1866
+ const configData = config.config;
1867
+ const oldScroll = { scrollX: configData.scrollX, scrollY: configData.scrollY };
1868
+ if (boundsList.length === 0 || configData.width === 0 || configData.height === 0) return scroll;
1869
+ const viewport = getScrollViewport(scroll, config);
1870
+ const isVisible = boundsList.find((bounds) => import_utils17.Rectangle.isViewportVisible(bounds, viewport));
1871
+ if (!isVisible) {
1872
+ const oldViewport = getScrollViewport(oldScroll, config);
1873
+ const isOldVisible = boundsList.find(
1874
+ (bounds) => import_utils17.Rectangle.isViewportVisible(bounds, oldViewport)
1875
+ );
1876
+ if (!isOldVisible) {
1877
+ return initScroll();
1878
+ }
1879
+ return oldScroll;
1880
+ }
1881
+ return scroll;
1882
+ }
1883
+
1884
+ // src/utils/scroll-bar-events.tsx
1885
+ var ScrollBarEvents = Symbol("ScrollBarEvents");
1886
+
1887
+ // src/layers/flow-debug-layer.tsx
1888
+ var rgbTimes = 0;
1889
+ function randomColor(percent) {
1890
+ const max = Math.min(percent / 10 * 255, 255);
1891
+ rgbTimes += 1;
1892
+ const rgb = rgbTimes % 3;
1893
+ const random = () => Math.floor(Math.random() * max);
1894
+ return `rgb(${rgb === 0 ? random() : 0}, ${rgb === 1 ? random() : 0}, ${rgb === 2 ? random() : 0})`;
1895
+ }
1896
+ var FlowDebugLayer = class extends import_core13.Layer {
1897
+ constructor() {
1898
+ super(...arguments);
1899
+ this.node = document.createElement("div");
1900
+ this.viewport = import_utils18.domUtils.createDivWithClass("gedit-flow-debug-bounds");
1901
+ this.boundsNodes = import_utils18.domUtils.createDivWithClass("gedit-flow-debug-bounds");
1902
+ this.pointsNodes = import_utils18.domUtils.createDivWithClass("gedit-flow-debug-points");
1903
+ this.versionNodes = import_utils18.domUtils.createDivWithClass("gedit-flow-debug-versions gedit-hidden");
1904
+ /**
1905
+ * ?debug=xxxx, 则返回 xxxx
1906
+ */
1907
+ this.filterKey = window.location.search.match(/debug=([^&]+)/)?.[1] || "";
1908
+ this.originLine = document.createElement("div");
1909
+ this.domCache = /* @__PURE__ */ new WeakMap();
1910
+ }
1911
+ get transforms() {
1912
+ return this.document.getRenderDatas(import_document16.FlowNodeTransformData);
1913
+ }
1914
+ onReady() {
1915
+ this.node.style.zIndex = "20";
1916
+ import_utils18.domUtils.setStyle(this.originLine, {
1917
+ position: "absolute",
1918
+ width: 1,
1919
+ height: "100%",
1920
+ left: this.pipelineNode.style.left,
1921
+ top: 0,
1922
+ borderLeft: "1px dashed rgba(255, 0, 0, 0.5)"
1923
+ });
1924
+ this.pipelineNode.parentElement.appendChild(this.originLine);
1925
+ this.node.appendChild(this.viewport);
1926
+ this.node.appendChild(this.versionNodes);
1927
+ this.node.appendChild(this.boundsNodes);
1928
+ this.node.appendChild(this.pointsNodes);
1929
+ this.renderScrollViewportBounds();
1930
+ }
1931
+ onScroll() {
1932
+ this.originLine.style.left = this.pipelineNode.style.left;
1933
+ this.renderScrollViewportBounds();
1934
+ }
1935
+ onResize() {
1936
+ this.renderScrollViewportBounds();
1937
+ }
1938
+ onZoom(scale) {
1939
+ this.node.style.transform = `scale(${scale})`;
1940
+ this.renderScrollViewportBounds();
1941
+ }
1942
+ createBounds(transform, color, depth) {
1943
+ if (this.filterKey && transform.key.indexOf(this.filterKey) === -1) return;
1944
+ let cache = this.domCache.get(transform);
1945
+ const { bounds, inputPoint, outputPoint } = transform;
1946
+ if (!cache) {
1947
+ const bbox = import_utils18.domUtils.createDivWithClass("");
1948
+ const input = import_utils18.domUtils.createDivWithClass("");
1949
+ const output = import_utils18.domUtils.createDivWithClass("");
1950
+ const version = import_utils18.domUtils.createDivWithClass("");
1951
+ bbox.title = transform.key;
1952
+ input.title = transform.key + "(input)";
1953
+ output.title = transform.key + "(output)";
1954
+ version.title = transform.key;
1955
+ this.boundsNodes.appendChild(bbox);
1956
+ this.pointsNodes.appendChild(input);
1957
+ this.pointsNodes.appendChild(output);
1958
+ this.versionNodes.appendChild(version);
1959
+ transform.onDispose(() => {
1960
+ bbox.remove();
1961
+ input.remove();
1962
+ output.remove();
1963
+ });
1964
+ cache = { bbox, input, output, version, color };
1965
+ this.domCache.set(transform, cache);
1966
+ }
1967
+ import_utils18.domUtils.setStyle(cache.version, {
1968
+ position: "absolute",
1969
+ marginLeft: "-9px",
1970
+ marginTop: "-10px",
1971
+ borderRadius: 12,
1972
+ background: "#f54a45",
1973
+ padding: 4,
1974
+ color: "navajowhite",
1975
+ display: transform.renderState.hidden ? "none" : "block",
1976
+ zIndex: depth + 1e3,
1977
+ left: bounds.center.x,
1978
+ top: bounds.center.y
1979
+ });
1980
+ cache.version.innerHTML = transform.version.toString();
1981
+ import_utils18.domUtils.setStyle(cache.input, {
1982
+ position: "absolute",
1983
+ width: 10,
1984
+ height: 10,
1985
+ marginLeft: -5,
1986
+ marginTop: -5,
1987
+ borderRadius: 5,
1988
+ left: inputPoint.x,
1989
+ top: inputPoint.y,
1990
+ opacity: 0.4,
1991
+ zIndex: depth,
1992
+ backgroundColor: cache.color,
1993
+ whiteSpace: "nowrap",
1994
+ overflow: "visible"
1995
+ });
1996
+ cache.input.innerHTML = `${inputPoint.x},${inputPoint.y}`;
1997
+ import_utils18.domUtils.setStyle(cache.output, {
1998
+ position: "absolute",
1999
+ width: 10,
2000
+ height: 10,
2001
+ marginLeft: -5,
2002
+ marginTop: -5,
2003
+ borderRadius: 5,
2004
+ left: outputPoint.x,
2005
+ top: outputPoint.y,
2006
+ opacity: 0.4,
2007
+ zIndex: depth,
2008
+ backgroundColor: cache.color,
2009
+ whiteSpace: "nowrap",
2010
+ overflow: "visible"
2011
+ });
2012
+ cache.output.innerHTML = `${outputPoint.x},${outputPoint.y}`;
2013
+ import_utils18.domUtils.setStyle(cache.bbox, {
2014
+ position: "absolute",
2015
+ width: bounds.width,
2016
+ height: bounds.height,
2017
+ left: bounds.left,
2018
+ top: bounds.top,
2019
+ opacity: `${depth / 30}`,
2020
+ backgroundColor: cache.color
2021
+ });
2022
+ }
2023
+ /**
2024
+ * 显示 viewport 可滚动区域
2025
+ */
2026
+ renderScrollViewportBounds() {
2027
+ const viewportBounds = getScrollViewport(
2028
+ {
2029
+ scrollX: this.config.config.scrollX,
2030
+ scrollY: this.config.config.scrollY
2031
+ },
2032
+ this.config
2033
+ );
2034
+ import_utils18.domUtils.setStyle(this.viewport, {
2035
+ position: "absolute",
2036
+ width: viewportBounds.width - 2,
2037
+ height: viewportBounds.height - 2,
2038
+ left: viewportBounds.left + 1,
2039
+ top: viewportBounds.top + 1,
2040
+ border: "1px solid rgba(200, 200, 255, 0.5)"
2041
+ });
2042
+ }
2043
+ autorun() {
2044
+ if (this.documentTransformer.loading) return;
2045
+ this.documentTransformer.refresh();
2046
+ let color = randomColor(0);
2047
+ this.document.traverse((entity, depth) => {
2048
+ const transform = entity.getData(import_document16.FlowNodeTransformData);
2049
+ color = randomColor(depth);
2050
+ this.createBounds(transform, color, depth);
2051
+ });
2052
+ this.renderScrollViewportBounds();
2053
+ }
2054
+ };
2055
+ __decorateClass([
2056
+ (0, import_inversify7.inject)(import_document16.FlowDocument)
2057
+ ], FlowDebugLayer.prototype, "document", 2);
2058
+ __decorateClass([
2059
+ (0, import_core13.observeEntity)(import_document16.FlowDocumentTransformerEntity)
2060
+ ], FlowDebugLayer.prototype, "documentTransformer", 2);
2061
+ __decorateClass([
2062
+ (0, import_core13.observeEntityDatas)(import_document16.FlowNodeEntity, import_document16.FlowNodeTransformData)
2063
+ ], FlowDebugLayer.prototype, "_transforms", 2);
2064
+ FlowDebugLayer = __decorateClass([
2065
+ (0, import_inversify7.injectable)()
2066
+ ], FlowDebugLayer);
2067
+
2068
+ // src/layers/flow-scroll-bar-layer.tsx
2069
+ var import_inversify8 = require("inversify");
2070
+ var import_document17 = require("@flowgram.ai/document");
2071
+ var import_core14 = require("@flowgram.ai/core");
2072
+ var import_utils20 = require("@flowgram.ai/utils");
2073
+ var BORDER_WIDTH = 2;
2074
+ var BLOCK_OFFSET = 11;
2075
+ var SCROLL_BAR_WIDTH = "7px";
2076
+ var FlowScrollBarLayer = class extends import_core14.Layer {
2077
+ constructor() {
2078
+ super(...arguments);
2079
+ // @observeEntity(FlowDocumentTransformerEntity) readonly documentTransformer: FlowDocumentTransformerEntity
2080
+ // 右滚动区域
2081
+ this.rightScrollBar = import_utils20.domUtils.createDivWithClass("gedit-playground-scroll-right");
2082
+ // 右滚动条
2083
+ this.rightScrollBarBlock = import_utils20.domUtils.createDivWithClass("gedit-playground-scroll-right-block");
2084
+ // 底滚动区域
2085
+ this.bottomScrollBar = import_utils20.domUtils.createDivWithClass("gedit-playground-scroll-bottom");
2086
+ // 底滚动条
2087
+ this.bottomScrollBarBlock = import_utils20.domUtils.createDivWithClass(
2088
+ "gedit-playground-scroll-bottom-block"
2089
+ );
2090
+ // 总滚动距离
2091
+ this.sum = 0;
2092
+ // 初始 x 轴滚动距离
2093
+ this.initialScrollX = 0;
2094
+ // 初始 y 轴滚动距离
2095
+ this.initialScrollY = 0;
2096
+ this.bottomGrabDragger = new import_core14.PlaygroundDrag({
2097
+ onDragStart: (e) => {
2098
+ this.config.updateCursor("grabbing");
2099
+ this.sum = 0;
2100
+ this.initialScrollX = this.config.getViewport().x;
2101
+ this.onBoardingToast();
2102
+ },
2103
+ onDrag: (e) => {
2104
+ this.sum += e.movingDelta.x;
2105
+ this.playgroundConfigEntity.scroll(
2106
+ {
2107
+ scrollX: (this.initialScrollX + this.sum * this.viewportFullWidth / (this.clientViewportWidth - this.scrollBottomWidth)) * this.scale
2108
+ },
2109
+ false
2110
+ );
2111
+ },
2112
+ onDragEnd: (e) => {
2113
+ this.config.updateCursor("default");
2114
+ }
2115
+ });
2116
+ this.rightGrabDragger = new import_core14.PlaygroundDrag({
2117
+ onDragStart: (e) => {
2118
+ this.config.updateCursor("grabbing");
2119
+ this.sum = 0;
2120
+ this.initialScrollY = this.config.getViewport().y;
2121
+ this.onBoardingToast();
2122
+ },
2123
+ onDrag: (e) => {
2124
+ this.sum += e.movingDelta.y;
2125
+ this.playgroundConfigEntity.scroll(
2126
+ {
2127
+ scrollY: (this.initialScrollY + this.sum * this.viewportFullHeight / (this.clientViewportHeight - this.scrollRightHeight)) * this.scale
2128
+ },
2129
+ false
2130
+ );
2131
+ },
2132
+ onDragEnd: (e) => {
2133
+ this.config.updateCursor("default");
2134
+ }
2135
+ });
2136
+ }
2137
+ // 浏览器视图宽度
2138
+ get clientViewportWidth() {
2139
+ return this.viewportWidth * this.scale - BLOCK_OFFSET;
2140
+ }
2141
+ // 浏览器视图高度
2142
+ get clientViewportHeight() {
2143
+ return this.viewportHeight * this.scale - BLOCK_OFFSET;
2144
+ }
2145
+ // 视图的完整宽度
2146
+ get viewportFullWidth() {
2147
+ return this.mostLeft - this.mostRight;
2148
+ }
2149
+ // 视图的完整高度
2150
+ get viewportFullHeight() {
2151
+ return this.mostTop - this.mostBottom;
2152
+ }
2153
+ // 视图的可移动宽度
2154
+ get viewportMoveWidth() {
2155
+ return this.mostLeft - this.mostRight + this.width;
2156
+ }
2157
+ // 视图的可移动高度
2158
+ get viewportMoveHeight() {
2159
+ return this.mostTop - this.mostBottom + this.height;
2160
+ }
2161
+ getToLeft(scrollX) {
2162
+ return (scrollX - this.mostRight) / this.viewportMoveWidth * this.clientViewportWidth;
2163
+ }
2164
+ getToTop(scrollY) {
2165
+ return (scrollY - this.mostBottom) / this.viewportMoveHeight * this.clientViewportHeight;
2166
+ }
2167
+ clickRightScrollBar(e) {
2168
+ e.preventDefault();
2169
+ e.stopPropagation();
2170
+ const ratio = 1 - (e?.y || 0) / this.clientViewportHeight;
2171
+ const scrollY = (this.mostTop - this.viewportFullHeight * ratio) * this.scale;
2172
+ this.playgroundConfigEntity.scroll(
2173
+ {
2174
+ scrollY
2175
+ },
2176
+ false
2177
+ );
2178
+ }
2179
+ clickBottomScrollBar(e) {
2180
+ e.preventDefault();
2181
+ e.stopPropagation();
2182
+ const ratio = 1 - (e?.x || 0) / this.clientViewportWidth;
2183
+ const scrollX = (this.mostLeft - this.viewportFullWidth * ratio) * this.scale;
2184
+ this.playgroundConfigEntity.scroll(
2185
+ {
2186
+ scrollX
2187
+ },
2188
+ false
2189
+ );
2190
+ }
2191
+ onBoardingToast() {
2192
+ this.events?.dragStart();
2193
+ }
2194
+ changeScrollBarVisibility(scrollBar, status) {
2195
+ const addClassName = status === "show" /* Show */ ? "gedit-playground-scroll-show" : "gedit-playground-scroll-hidden";
2196
+ const delClassName = status === "show" /* Show */ ? "gedit-playground-scroll-hidden" : "gedit-playground-scroll-show";
2197
+ import_utils20.domUtils.addClass(scrollBar, addClassName);
2198
+ import_utils20.domUtils.delClass(scrollBar, delClassName);
2199
+ }
2200
+ onReady() {
2201
+ if (!this.options.getBounds) {
2202
+ this.options = {
2203
+ getBounds: () => {
2204
+ const document2 = this.flowDocument;
2205
+ if (!document2) return import_utils20.Rectangle.EMPTY;
2206
+ document2.transformer.refresh();
2207
+ return document2.root.getData(import_document17.FlowNodeTransformData).bounds;
2208
+ },
2209
+ showScrollBars: "whenScrolling"
2210
+ };
2211
+ }
2212
+ this.pipelineNode.parentNode.appendChild(this.rightScrollBar);
2213
+ this.pipelineNode.parentNode.appendChild(this.rightScrollBarBlock);
2214
+ this.pipelineNode.parentNode.appendChild(this.bottomScrollBar);
2215
+ this.pipelineNode.parentNode.appendChild(this.bottomScrollBarBlock);
2216
+ this.rightScrollBar.onclick = this.clickRightScrollBar.bind(this);
2217
+ this.bottomScrollBar.onclick = this.clickBottomScrollBar.bind(this);
2218
+ if (this.options.showScrollBars === "whenScrolling") {
2219
+ this.rightScrollBar.addEventListener("mouseenter", (e) => {
2220
+ this.changeScrollBarVisibility(this.rightScrollBarBlock, "show" /* Show */);
2221
+ });
2222
+ this.rightScrollBar.addEventListener("mouseleave", (e) => {
2223
+ this.changeScrollBarVisibility(this.rightScrollBarBlock, "hidden" /* Hidden */);
2224
+ });
2225
+ this.bottomScrollBar.addEventListener("mouseenter", (e) => {
2226
+ this.changeScrollBarVisibility(this.bottomScrollBarBlock, "show" /* Show */);
2227
+ });
2228
+ this.bottomScrollBar.addEventListener("mouseleave", (e) => {
2229
+ this.changeScrollBarVisibility(this.bottomScrollBarBlock, "hidden" /* Hidden */);
2230
+ });
2231
+ }
2232
+ this.bottomScrollBarBlock.addEventListener("mousedown", (e) => {
2233
+ this.bottomGrabDragger.start(e.clientX, e.clientY);
2234
+ e.stopPropagation();
2235
+ });
2236
+ this.rightScrollBarBlock.addEventListener("mousedown", (e) => {
2237
+ this.rightGrabDragger.start(e.clientX, e.clientY);
2238
+ e.stopPropagation();
2239
+ });
2240
+ }
2241
+ autorun() {
2242
+ if (this.hideTimeout) {
2243
+ clearTimeout(this.hideTimeout);
2244
+ }
2245
+ const viewportBounds = getScrollViewport(
2246
+ {
2247
+ scrollX: this.config.config.scrollX,
2248
+ scrollY: this.config.config.scrollY
2249
+ },
2250
+ this.config
2251
+ );
2252
+ const viewport = this.config.getViewport();
2253
+ this.viewportWidth = viewport.width;
2254
+ this.viewportHeight = viewport.height;
2255
+ const rootBounds = this.options.getBounds();
2256
+ this.width = rootBounds?.width || 0;
2257
+ this.height = rootBounds?.height || 0;
2258
+ const paddingLeftRight = (this.viewportWidth - viewportBounds.width) / 2 - BORDER_WIDTH;
2259
+ const paddingTopBottom = (this.viewportHeight - viewportBounds.height) / 2 - BORDER_WIDTH;
2260
+ const canvasTotalWidth = this.width + viewportBounds.width;
2261
+ const canvasTotalHeight = this.height + viewportBounds.height;
2262
+ const initialOffsetX = rootBounds.x;
2263
+ const initialOffsetY = rootBounds.y;
2264
+ this.mostLeft = this.width + initialOffsetX - paddingLeftRight;
2265
+ this.mostRight = this.mostLeft - canvasTotalWidth;
2266
+ this.mostTop = this.height + initialOffsetY - paddingTopBottom;
2267
+ this.mostBottom = this.mostTop - canvasTotalHeight;
2268
+ this.scale = this.config.finalScale;
2269
+ const calcViewportWidth = this.clientViewportWidth;
2270
+ const calcViewportHeight = this.clientViewportHeight;
2271
+ this.scrollBottomWidth = calcViewportWidth - calcViewportWidth * (this.mostLeft - this.mostRight) / this.viewportMoveWidth;
2272
+ this.scrollRightHeight = calcViewportHeight - calcViewportHeight * (this.mostTop - this.mostBottom) / this.viewportMoveHeight;
2273
+ const bottomBarToLeft = this.getToLeft(viewport.x);
2274
+ const rightBarToTop = this.getToTop(viewport.y);
2275
+ import_utils20.domUtils.setStyle(this.rightScrollBarBlock, {
2276
+ right: 2,
2277
+ top: rightBarToTop,
2278
+ background: "#1F2329",
2279
+ zIndex: 10,
2280
+ height: this.scrollRightHeight,
2281
+ width: SCROLL_BAR_WIDTH
2282
+ });
2283
+ import_utils20.domUtils.setStyle(this.bottomScrollBarBlock, {
2284
+ left: bottomBarToLeft,
2285
+ bottom: 2,
2286
+ background: "#1F2329",
2287
+ zIndex: 10,
2288
+ height: SCROLL_BAR_WIDTH,
2289
+ width: this.scrollBottomWidth
2290
+ });
2291
+ this.changeScrollBarVisibility(this.rightScrollBarBlock, "show" /* Show */);
2292
+ this.changeScrollBarVisibility(this.bottomScrollBarBlock, "show" /* Show */);
2293
+ if (this.options.showScrollBars === "whenScrolling") {
2294
+ this.hideTimeout = window.setTimeout(() => {
2295
+ this.changeScrollBarVisibility(this.rightScrollBarBlock, "hidden" /* Hidden */);
2296
+ this.changeScrollBarVisibility(this.bottomScrollBarBlock, "hidden" /* Hidden */);
2297
+ this.hideTimeout = void 0;
2298
+ }, 1e3);
2299
+ }
2300
+ }
2301
+ };
2302
+ __decorateClass([
2303
+ (0, import_inversify8.optional)(),
2304
+ (0, import_inversify8.inject)(ScrollBarEvents)
2305
+ ], FlowScrollBarLayer.prototype, "events", 2);
2306
+ __decorateClass([
2307
+ (0, import_inversify8.inject)(import_document17.FlowDocument),
2308
+ (0, import_inversify8.optional)()
2309
+ ], FlowScrollBarLayer.prototype, "flowDocument", 2);
2310
+ __decorateClass([
2311
+ (0, import_core14.observeEntity)(import_core14.PlaygroundConfigEntity)
2312
+ ], FlowScrollBarLayer.prototype, "playgroundConfigEntity", 2);
2313
+ FlowScrollBarLayer = __decorateClass([
2314
+ (0, import_inversify8.injectable)()
2315
+ ], FlowScrollBarLayer);
2316
+
2317
+ // src/layers/flow-drag-layer.tsx
2318
+ var import_react15 = __toESM(require("react"));
2319
+ var import_inversify9 = require("inversify");
2320
+ var import_utils22 = require("@flowgram.ai/utils");
2321
+ var import_document18 = require("@flowgram.ai/document");
2322
+ var import_core15 = require("@flowgram.ai/core");
2323
+ var import_core16 = require("@flowgram.ai/core");
2324
+ var DRAG_OFFSET = 10;
2325
+ var DEFAULT_DRAG_OFFSET_X = 8;
2326
+ var DEFAULT_DRAG_OFFSET_Y = 8;
2327
+ var FlowDragLayer = class extends import_core15.Layer {
2328
+ constructor() {
2329
+ super(...arguments);
2330
+ this.dragOffset = {
2331
+ x: DEFAULT_DRAG_OFFSET_X,
2332
+ y: DEFAULT_DRAG_OFFSET_Y
2333
+ };
2334
+ this.containerRef = import_react15.default.createRef();
2335
+ this.draggingNodeMask = document.createElement("div");
2336
+ this._dragger = new import_core16.PlaygroundDrag({
2337
+ onDrag: (e) => {
2338
+ this.handleMouseMove(e);
2339
+ },
2340
+ onDragEnd: () => {
2341
+ this.handleMouseUp();
2342
+ },
2343
+ stopGlobalEventNames: ["contextmenu"]
2344
+ });
2345
+ }
2346
+ get transitions() {
2347
+ const result = [];
2348
+ this.document.traverse((entity) => {
2349
+ result.push(entity.getData(import_document18.FlowNodeTransitionData));
2350
+ });
2351
+ return result;
2352
+ }
2353
+ get dragStartEntity() {
2354
+ return this.flowRenderStateEntity.getDragStartEntity();
2355
+ }
2356
+ set dragStartEntity(entity) {
2357
+ this.flowRenderStateEntity.setDragStartEntity(entity);
2358
+ }
2359
+ get dragEntities() {
2360
+ return this.flowRenderStateEntity.getDragEntities();
2361
+ }
2362
+ set dragEntities(entities) {
2363
+ this.flowRenderStateEntity.setDragEntities(entities);
2364
+ }
2365
+ isGrab() {
2366
+ const currentState = this.editorStateConfig.getCurrentState();
2367
+ return currentState === import_core15.EditorState.STATE_GRAB;
2368
+ }
2369
+ setDraggingStatus(status) {
2370
+ if (this.service.nodeDragIdsWithChildren.length) {
2371
+ this.service.nodeDragIdsWithChildren.forEach((_id) => {
2372
+ const node = this.entityManager.getEntityById(_id);
2373
+ const data = node?.getData(import_document18.FlowNodeRenderData);
2374
+ data.dragging = status;
2375
+ });
2376
+ }
2377
+ }
2378
+ dragEnable(e) {
2379
+ return Math.abs(e.clientX - this.initialPosition.x) > DRAG_OFFSET || Math.abs(e.clientY - this.initialPosition.y) > DRAG_OFFSET;
2380
+ }
2381
+ handleMouseMove(event) {
2382
+ if (this.dragStartEntity && this.dragEnable(event)) {
2383
+ this.setDraggingStatus(true);
2384
+ const scale = this.playgroundConfigEntity.finalScale;
2385
+ if (this.containerRef.current) {
2386
+ const dragNode = this.containerRef.current.children?.[0];
2387
+ const dragBlockX = event.clientX - (this.pipelineNode.offsetLeft || 0) - this.playgroundConfigEntity.config.clientX - (dragNode.clientWidth - this.dragOffset.x) * scale;
2388
+ const dragBlockY = event.clientY - (this.pipelineNode.offsetTop || 0) - this.playgroundConfigEntity.config.clientY - (dragNode.clientHeight - this.dragOffset.y) * scale;
2389
+ const isBranch = this.service.isDragBranch;
2390
+ const draggingRect = new import_utils22.Rectangle(
2391
+ dragBlockX,
2392
+ dragBlockY,
2393
+ dragNode.clientWidth * scale,
2394
+ dragNode.clientHeight * scale
2395
+ );
2396
+ let side;
2397
+ const collisionTransition = this.transitions.find((transition) => {
2398
+ if (transition?.entity?.parent?.collapsed) {
2399
+ return false;
2400
+ }
2401
+ const { hasCollision, labelOffsetType } = this.flowDragConfigEntity.isCollision(
2402
+ transition,
2403
+ draggingRect,
2404
+ isBranch
2405
+ );
2406
+ side = labelOffsetType;
2407
+ return hasCollision;
2408
+ });
2409
+ if (collisionTransition && (isBranch ? this.service.isDroppableBranch(collisionTransition.entity, side) : this.service.isDroppableNode(collisionTransition.entity)) && (!this.options.canDrop || this.options.canDrop({
2410
+ dragNodes: this.dragEntities,
2411
+ dropNode: collisionTransition.entity,
2412
+ isBranch
2413
+ }))) {
2414
+ this.flowRenderStateEntity.setNodeDroppingId(collisionTransition.entity.id);
2415
+ } else {
2416
+ this.flowRenderStateEntity.setNodeDroppingId("");
2417
+ }
2418
+ this.flowRenderStateEntity.setDragLabelSide(side);
2419
+ this.containerRef.current.style.visibility = "visible";
2420
+ this.pipelineNode.parentElement.appendChild(this.draggingNodeMask);
2421
+ this.containerRef.current.style.left = `${dragBlockX}px`;
2422
+ this.containerRef.current.style.top = `${dragBlockY}px`;
2423
+ this.containerRef.current.style.transformOrigin = "top left";
2424
+ this.containerRef.current.style.transform = `scale(${scale})`;
2425
+ this.flowDragConfigEntity.scrollDirection(
2426
+ event,
2427
+ this.containerRef.current,
2428
+ dragBlockX,
2429
+ dragBlockY
2430
+ );
2431
+ }
2432
+ }
2433
+ }
2434
+ handleMouseUp() {
2435
+ this.setDraggingStatus(false);
2436
+ if (this.dragStartEntity) {
2437
+ const activatedNodeId = this.service.dropNodeId;
2438
+ if (activatedNodeId) {
2439
+ if (this.service.isDragBranch) {
2440
+ this.service.dropBranch();
2441
+ } else {
2442
+ this.service.dropNode();
2443
+ this.selectConfigEntity.clearSelectedNodes();
2444
+ }
2445
+ }
2446
+ this.flowRenderStateEntity.setNodeDroppingId("");
2447
+ this.flowRenderStateEntity.setDragLabelSide();
2448
+ this.dragStartEntity = void 0;
2449
+ this.dragEntities = [];
2450
+ this.flowDragConfigEntity.stopAllScroll();
2451
+ }
2452
+ if (this.containerRef.current) {
2453
+ this.containerRef.current.style.visibility = "hidden";
2454
+ if (this.pipelineNode.parentElement.contains(this.draggingNodeMask)) {
2455
+ this.pipelineNode.parentElement.removeChild(this.draggingNodeMask);
2456
+ }
2457
+ }
2458
+ }
2459
+ /**
2460
+ * 开始拖拽事件
2461
+ * @param e
2462
+ */
2463
+ async startDrag(e, {
2464
+ dragStartEntity: startEntityFromProps,
2465
+ dragEntities
2466
+ }, options) {
2467
+ if (this.isGrab() || this.config.disabled || this.config.readonly) {
2468
+ return;
2469
+ }
2470
+ this.dragOffset.x = options?.dragOffsetX || DEFAULT_DRAG_OFFSET_X;
2471
+ this.dragOffset.y = options?.dragOffsetY || DEFAULT_DRAG_OFFSET_Y;
2472
+ const isIcon = startEntityFromProps.flowNodeType === import_document18.FlowNodeBaseType.BLOCK_ICON;
2473
+ const isOrderIcon = startEntityFromProps.flowNodeType === import_document18.FlowNodeBaseType.BLOCK_ORDER_ICON;
2474
+ const dragStartEntity = isIcon || isOrderIcon ? startEntityFromProps.parent : startEntityFromProps;
2475
+ if (!dragStartEntity.getData(import_document18.FlowNodeRenderData).draggable) {
2476
+ return;
2477
+ }
2478
+ this.initialPosition = {
2479
+ x: e.clientX,
2480
+ y: e.clientY
2481
+ };
2482
+ this.dragStartEntity = dragStartEntity;
2483
+ this.dragEntities = dragEntities || [this.dragStartEntity];
2484
+ return this._dragger.start(e.clientX, e.clientY);
2485
+ }
2486
+ onReady() {
2487
+ this.draggingNodeMask.style.width = "100%";
2488
+ this.draggingNodeMask.style.height = "100%";
2489
+ this.draggingNodeMask.style.position = "absolute";
2490
+ this.draggingNodeMask.classList.add("dragging-node");
2491
+ this.draggingNodeMask.style.zIndex = "99";
2492
+ this.draggingNodeMask.style.cursor = "pointer";
2493
+ this.dragNodeComp = this.rendererRegistry.getRendererComponent("drag-node" /* DRAG_NODE */);
2494
+ if (this.options.onDrop) {
2495
+ this.toDispose.push(this.service.onDrop(this.options.onDrop));
2496
+ }
2497
+ }
2498
+ render() {
2499
+ const DragComp = this.dragNodeComp.renderer;
2500
+ return /* @__PURE__ */ import_react15.default.createElement(
2501
+ "div",
2502
+ {
2503
+ ref: this.containerRef,
2504
+ style: { position: "absolute", zIndex: 99999, visibility: "hidden" },
2505
+ onMouseEnter: (e) => e.stopPropagation()
2506
+ },
2507
+ /* @__PURE__ */ import_react15.default.createElement(DragComp, { dragStart: this.dragStartEntity, dragNodes: this.dragEntities })
2508
+ );
2509
+ }
2510
+ };
2511
+ __decorateClass([
2512
+ (0, import_inversify9.inject)(import_document18.FlowDocument)
2513
+ ], FlowDragLayer.prototype, "document", 2);
2514
+ __decorateClass([
2515
+ (0, import_inversify9.inject)(import_document18.FlowDragService)
2516
+ ], FlowDragLayer.prototype, "service", 2);
2517
+ __decorateClass([
2518
+ (0, import_core15.observeEntityDatas)(import_document18.FlowNodeEntity, import_document18.FlowNodeTransformData)
2519
+ ], FlowDragLayer.prototype, "transforms", 2);
2520
+ __decorateClass([
2521
+ (0, import_core15.observeEntity)(import_core15.EditorStateConfigEntity)
2522
+ ], FlowDragLayer.prototype, "editorStateConfig", 2);
2523
+ __decorateClass([
2524
+ (0, import_core15.observeEntity)(import_core15.PlaygroundConfigEntity)
2525
+ ], FlowDragLayer.prototype, "playgroundConfigEntity", 2);
2526
+ __decorateClass([
2527
+ (0, import_core15.observeEntity)(FlowDragEntity)
2528
+ ], FlowDragLayer.prototype, "flowDragConfigEntity", 2);
2529
+ __decorateClass([
2530
+ (0, import_core15.observeEntity)(import_document18.FlowRendererStateEntity)
2531
+ ], FlowDragLayer.prototype, "flowRenderStateEntity", 2);
2532
+ __decorateClass([
2533
+ (0, import_core15.observeEntity)(FlowSelectConfigEntity)
2534
+ ], FlowDragLayer.prototype, "selectConfigEntity", 2);
2535
+ __decorateClass([
2536
+ (0, import_inversify9.inject)(FlowRendererRegistry)
2537
+ ], FlowDragLayer.prototype, "rendererRegistry", 2);
2538
+ FlowDragLayer = __decorateClass([
2539
+ (0, import_inversify9.injectable)()
2540
+ ], FlowDragLayer);
2541
+
2542
+ // src/layers/flow-selector-box-layer.tsx
2543
+ var import_inversify10 = require("inversify");
2544
+ var import_utils23 = require("@flowgram.ai/utils");
2545
+ var import_document19 = require("@flowgram.ai/document");
2546
+ var import_core17 = require("@flowgram.ai/core");
2547
+ var FlowSelectorBoxLayer = class extends import_core17.Layer {
2548
+ constructor() {
2549
+ super(...arguments);
2550
+ this.node = import_utils23.domUtils.createDivWithClass("gedit-selector-box-layer");
2551
+ /**
2552
+ * 选择框
2553
+ */
2554
+ this.selectorBox = this.createDOMCache("gedit-selector-box");
2555
+ /**
2556
+ * 用于遮挡鼠标,避免触发 hover
2557
+ */
2558
+ this.selectorBoxBlock = this.createDOMCache("gedit-selector-box-block");
2559
+ /**
2560
+ * 拖动选择框
2561
+ */
2562
+ this.selectboxDragger = new import_core17.PlaygroundDrag({
2563
+ onDragStart: (e) => {
2564
+ this.selectConfigEntity.clearSelectedNodes();
2565
+ const mousePos = this.playgroundConfigEntity.getPosFromMouseEvent(e);
2566
+ this.transformVisibles = this.flowDocument.getRenderDatas(import_document19.FlowNodeTransformData, false).filter((transform) => {
2567
+ const { entity } = transform;
2568
+ if (entity.originParent) {
2569
+ return this.nodeSelectable(entity, mousePos) && this.nodeSelectable(entity.originParent, mousePos);
2570
+ }
2571
+ return this.nodeSelectable(entity, mousePos);
2572
+ });
2573
+ this.selectorBoxConfigEntity.setDragInfo(e);
2574
+ this.updateSelectorBox(this.selectorBoxConfigEntity);
2575
+ },
2576
+ onDrag: (e) => {
2577
+ this.selectorBoxConfigEntity.setDragInfo(e);
2578
+ this.selectConfigEntity.selectFromBounds(
2579
+ this.selectorBoxConfigEntity.toRectangle(this.playgroundConfigEntity.finalScale),
2580
+ this.transformVisibles
2581
+ );
2582
+ this.updateSelectorBox(this.selectorBoxConfigEntity);
2583
+ },
2584
+ onDragEnd: (e) => {
2585
+ this.selectorBoxConfigEntity.setDragInfo(e);
2586
+ this.transformVisibles.length = 0;
2587
+ this.updateSelectorBox(this.selectorBoxConfigEntity);
2588
+ }
2589
+ });
2590
+ }
2591
+ onReady() {
2592
+ if (!this.options.canSelect) {
2593
+ this.options.canSelect = (e) => {
2594
+ const target = e.target;
2595
+ return target === this.pipelineNode || target === this.playgroundNode;
2596
+ };
2597
+ }
2598
+ this.toDispose.pushAll([
2599
+ this.selectConfigEntity.onConfigChanged(() => {
2600
+ this.selectionService.selection = this.selectConfigEntity.selectedNodes;
2601
+ }),
2602
+ this.selectionService.onSelectionChanged(() => {
2603
+ const selectedNodes = this.selectionService.selection.filter(
2604
+ (entity) => entity instanceof import_document19.FlowNodeEntity
2605
+ );
2606
+ this.selectConfigEntity.selectedNodes = selectedNodes;
2607
+ })
2608
+ ]);
2609
+ this.listenPlaygroundEvent(
2610
+ "mousedown",
2611
+ (e) => {
2612
+ if (!this.isEnabled()) return;
2613
+ if (this.options.canSelect && !this.options.canSelect(e, this.selectorBoxConfigEntity)) {
2614
+ return;
2615
+ }
2616
+ const currentState = this.editorStateConfig.getCurrentState();
2617
+ if (currentState === import_core17.EditorState.STATE_MOUSE_FRIENDLY_SELECT) {
2618
+ this.selectConfigEntity.clearSelectedNodes();
2619
+ }
2620
+ this.selectboxDragger.start(e.clientX, e.clientY, this.config);
2621
+ return true;
2622
+ },
2623
+ import_core17.PipelineLayerPriority.BASE_LAYER
2624
+ );
2625
+ }
2626
+ isEnabled() {
2627
+ const currentState = this.editorStateConfig.getCurrentState();
2628
+ const isMouseFriendly = currentState === import_core17.EditorState.STATE_MOUSE_FRIENDLY_SELECT;
2629
+ return !this.config.disabled && !this.config.readonly && // 鼠标友好模式下,需要按下 shift 启动框选
2630
+ (isMouseFriendly && this.editorStateConfig.isPressingShift || currentState === import_core17.EditorState.STATE_SELECT) && !this.selectorBoxConfigEntity.disabled;
2631
+ }
2632
+ /**
2633
+ * Destroy
2634
+ */
2635
+ dispose() {
2636
+ this.selectorBox.dispose();
2637
+ this.selectorBoxBlock.dispose();
2638
+ super.dispose();
2639
+ }
2640
+ updateSelectorBox(selector) {
2641
+ const node = this.selectorBox.get();
2642
+ const block = this.selectorBoxBlock.get();
2643
+ if (!this.isEnabled() && selector.isMoving) {
2644
+ this.selectorBoxConfigEntity.collapse();
2645
+ }
2646
+ if (!this.isEnabled() || !selector.isMoving) {
2647
+ node.setStyle({
2648
+ display: "none"
2649
+ });
2650
+ block.setStyle({
2651
+ display: "none"
2652
+ });
2653
+ } else {
2654
+ node.setStyle({
2655
+ display: "block",
2656
+ left: selector.position.x,
2657
+ top: selector.position.y,
2658
+ width: selector.size.width,
2659
+ height: selector.size.height
2660
+ });
2661
+ block.setStyle({
2662
+ display: "block",
2663
+ left: selector.position.x - 10,
2664
+ top: selector.position.y - 10,
2665
+ width: selector.size.width + 20,
2666
+ height: selector.size.height + 20
2667
+ });
2668
+ }
2669
+ }
2670
+ nodeSelectable(node, mousePos) {
2671
+ const selectable = node.getNodeMeta().selectable;
2672
+ if (typeof selectable === "function") {
2673
+ return selectable(node, mousePos);
2674
+ } else {
2675
+ return selectable;
2676
+ }
2677
+ }
2678
+ // autorun(): void {
2679
+ // this.updateSelectorBox(this.selectorBoxConfigEntity);
2680
+ // }
2681
+ };
2682
+ __decorateClass([
2683
+ (0, import_inversify10.inject)(import_document19.FlowDocument)
2684
+ ], FlowSelectorBoxLayer.prototype, "flowDocument", 2);
2685
+ __decorateClass([
2686
+ (0, import_inversify10.inject)(import_core17.ContextMenuService)
2687
+ ], FlowSelectorBoxLayer.prototype, "contextMenuService", 2);
2688
+ __decorateClass([
2689
+ (0, import_core17.observeEntity)(import_core17.PlaygroundConfigEntity)
2690
+ ], FlowSelectorBoxLayer.prototype, "playgroundConfigEntity", 2);
2691
+ __decorateClass([
2692
+ (0, import_inversify10.inject)(import_core17.SelectionService)
2693
+ ], FlowSelectorBoxLayer.prototype, "selectionService", 2);
2694
+ __decorateClass([
2695
+ (0, import_core17.observeEntity)(SelectorBoxConfigEntity)
2696
+ ], FlowSelectorBoxLayer.prototype, "selectorBoxConfigEntity", 2);
2697
+ __decorateClass([
2698
+ (0, import_core17.observeEntity)(FlowSelectConfigEntity)
2699
+ ], FlowSelectorBoxLayer.prototype, "selectConfigEntity", 2);
2700
+ __decorateClass([
2701
+ (0, import_core17.observeEntity)(import_core17.EditorStateConfigEntity)
2702
+ ], FlowSelectorBoxLayer.prototype, "editorStateConfig", 2);
2703
+ FlowSelectorBoxLayer = __decorateClass([
2704
+ (0, import_inversify10.injectable)()
2705
+ ], FlowSelectorBoxLayer);
2706
+
2707
+ // src/layers/flow-selector-bounds-layer.tsx
2708
+ var import_react16 = __toESM(require("react"));
2709
+ var import_inversify11 = require("inversify");
2710
+ var import_utils24 = require("@flowgram.ai/utils");
2711
+ var import_document20 = require("@flowgram.ai/document");
2712
+ var import_core18 = require("@flowgram.ai/core");
2713
+ var FlowSelectorBoundsLayer = class extends import_core18.Layer {
2714
+ constructor() {
2715
+ super(...arguments);
2716
+ this.node = import_utils24.domUtils.createDivWithClass("gedit-selector-bounds-layer");
2717
+ this.selectBoundsBackground = import_utils24.domUtils.createDivWithClass("gedit-selector-bounds-background");
2718
+ }
2719
+ onReady() {
2720
+ this.node.style.zIndex = "20";
2721
+ const { firstChild } = this.pipelineNode;
2722
+ if (this.options.boundsPadding !== void 0) {
2723
+ this.flowSelectConfigEntity.boundsPadding = this.options.boundsPadding;
2724
+ }
2725
+ if (this.options.backgroundClassName) {
2726
+ this.selectBoundsBackground.classList.add(this.options.backgroundClassName);
2727
+ }
2728
+ const selectorBoundsLayer = import_utils24.domUtils.createDivWithClass("gedit-playground-layer");
2729
+ selectorBoundsLayer.appendChild(this.selectBoundsBackground);
2730
+ this.pipelineNode.insertBefore(selectorBoundsLayer, firstChild);
2731
+ }
2732
+ onZoom(scale) {
2733
+ this.node.style.transform = `scale(${scale})`;
2734
+ this.selectBoundsBackground.parentElement.style.transform = `scale(${scale})`;
2735
+ }
2736
+ onViewportChange() {
2737
+ this.render();
2738
+ }
2739
+ isEnabled() {
2740
+ const currentState = this.editorStateConfig.getCurrentState();
2741
+ return currentState === import_core18.EditorState.STATE_SELECT;
2742
+ }
2743
+ // /**
2744
+ // * 渲染工具栏
2745
+ // */
2746
+ // renderCommandMenus(): JSX.Element[] {
2747
+ // return this.commandRegistry.commands
2748
+ // .filter(cmd => cmd.category === FlowRendererCommandCategory.SELECTOR_BOX)
2749
+ // .map(cmd => {
2750
+ // const CommandRenderer = this.rendererRegistry.getRendererComponent(
2751
+ // (cmd.icon as string) || cmd.id,
2752
+ // )?.renderer;
2753
+ //
2754
+ // return (
2755
+ // // eslint-disable-next-line react/jsx-filename-extension
2756
+ // <CommandRenderer
2757
+ // key={cmd.id}
2758
+ // disabled={!this.commandRegistry.isEnabled(cmd.id)}
2759
+ // command={cmd}
2760
+ // onClick={(e: any) => this.commandRegistry.executeCommand(cmd.id, e)}
2761
+ // />
2762
+ // );
2763
+ // })
2764
+ // .filter(c => c);
2765
+ // }
2766
+ render() {
2767
+ const {
2768
+ ignoreOneSelect,
2769
+ ignoreChildrenLength,
2770
+ SelectorBoxPopover: SelectorBoxPopoverFromOpts,
2771
+ disableBackground,
2772
+ CustomBoundsRenderer
2773
+ } = this.options;
2774
+ const bounds = this.flowSelectConfigEntity.getSelectedBounds();
2775
+ const selectedNodes = this.flowSelectConfigEntity.selectedNodes;
2776
+ const bg = this.selectBoundsBackground;
2777
+ const isDragging = !this.selectorBoxConfigEntity.isStart;
2778
+ if (bounds.width === 0 || bounds.height === 0 || // 选中单个的时候不显示
2779
+ ignoreOneSelect && selectedNodes.length === 1 && // 选中的节点不包含多个子节点
2780
+ (ignoreChildrenLength || selectedNodes[0].childrenLength <= 1)) {
2781
+ import_utils24.domUtils.setStyle(bg, {
2782
+ display: "none"
2783
+ });
2784
+ return /* @__PURE__ */ import_react16.default.createElement(import_react16.default.Fragment, null);
2785
+ }
2786
+ if (CustomBoundsRenderer) {
2787
+ return /* @__PURE__ */ import_react16.default.createElement(
2788
+ CustomBoundsRenderer,
2789
+ {
2790
+ bounds,
2791
+ config: this.config,
2792
+ flowSelectConfig: this.flowSelectConfigEntity,
2793
+ commandRegistry: this.commandRegistry
2794
+ }
2795
+ );
2796
+ }
2797
+ const style = {
2798
+ display: "block",
2799
+ left: bounds.left,
2800
+ top: bounds.top,
2801
+ width: bounds.width,
2802
+ height: bounds.height
2803
+ };
2804
+ if (!disableBackground) {
2805
+ import_utils24.domUtils.setStyle(bg, style);
2806
+ }
2807
+ let foregroundClassName = "gedit-selector-bounds-foreground";
2808
+ if (this.options.foregroundClassName) {
2809
+ foregroundClassName += " " + this.options.foregroundClassName;
2810
+ }
2811
+ const SelectorBoxPopover = SelectorBoxPopoverFromOpts || this.rendererRegistry.tryToGetRendererComponent("selector-box-popover" /* SELECTOR_BOX_POPOVER */)?.renderer;
2812
+ if (!isDragging || !SelectorBoxPopover)
2813
+ return /* @__PURE__ */ import_react16.default.createElement("div", { className: foregroundClassName, style });
2814
+ return /* @__PURE__ */ import_react16.default.createElement(
2815
+ SelectorBoxPopover,
2816
+ {
2817
+ bounds,
2818
+ config: this.config,
2819
+ flowSelectConfig: this.flowSelectConfigEntity,
2820
+ commandRegistry: this.commandRegistry
2821
+ },
2822
+ /* @__PURE__ */ import_react16.default.createElement("div", { className: foregroundClassName, style })
2823
+ );
2824
+ }
2825
+ };
2826
+ __decorateClass([
2827
+ (0, import_inversify11.inject)(FlowRendererRegistry)
2828
+ ], FlowSelectorBoundsLayer.prototype, "rendererRegistry", 2);
2829
+ __decorateClass([
2830
+ (0, import_inversify11.inject)(import_core18.CommandRegistry)
2831
+ ], FlowSelectorBoundsLayer.prototype, "commandRegistry", 2);
2832
+ __decorateClass([
2833
+ (0, import_core18.observeEntity)(FlowSelectConfigEntity)
2834
+ ], FlowSelectorBoundsLayer.prototype, "flowSelectConfigEntity", 2);
2835
+ __decorateClass([
2836
+ (0, import_core18.observeEntity)(import_core18.EditorStateConfigEntity)
2837
+ ], FlowSelectorBoundsLayer.prototype, "editorStateConfig", 2);
2838
+ __decorateClass([
2839
+ (0, import_core18.observeEntity)(SelectorBoxConfigEntity)
2840
+ ], FlowSelectorBoundsLayer.prototype, "selectorBoxConfigEntity", 2);
2841
+ __decorateClass([
2842
+ (0, import_core18.observeEntityDatas)(import_document20.FlowNodeEntity, import_document20.FlowNodeRenderData)
2843
+ ], FlowSelectorBoundsLayer.prototype, "renderStates", 2);
2844
+ __decorateClass([
2845
+ (0, import_core18.observeEntityDatas)(import_document20.FlowNodeEntity, import_document20.FlowNodeTransformData)
2846
+ ], FlowSelectorBoundsLayer.prototype, "_transforms", 2);
2847
+ FlowSelectorBoundsLayer = __decorateClass([
2848
+ (0, import_inversify11.injectable)()
2849
+ ], FlowSelectorBoundsLayer);
2850
+
2851
+ // src/layers/flow-context-menu-layer.tsx
2852
+ var import_react17 = __toESM(require("react"));
2853
+ var import_inversify12 = require("inversify");
2854
+ var import_core19 = require("@flowgram.ai/core");
2855
+ var import_utils25 = require("@flowgram.ai/utils");
2856
+ var FlowContextMenuLayer = class extends import_core19.Layer {
2857
+ constructor() {
2858
+ super(...arguments);
2859
+ this.node = import_utils25.domUtils.createDivWithClass("gedit-context-menu-layer");
2860
+ this.nodeRef = import_react17.default.createRef();
2861
+ }
2862
+ isEnabled() {
2863
+ const currentState = this.editorStateConfig.getCurrentState();
2864
+ return !this.config.disabled && !this.config.readonly && currentState === import_core19.EditorState.STATE_SELECT && !this.selectorBoxConfigEntity.disabled;
2865
+ }
2866
+ onReady() {
2867
+ this.node.style.zIndex = "30";
2868
+ this.node.style.display = "block";
2869
+ this.toDispose.pushAll([
2870
+ this.listenPlaygroundEvent(
2871
+ "contextmenu",
2872
+ (e) => {
2873
+ if (!this.isEnabled()) return;
2874
+ this.contextMenuService.rightPanelVisible = true;
2875
+ const bounds = this.flowSelectConfigEntity.getSelectedBounds();
2876
+ if (bounds.width === 0 || bounds.height === 0) {
2877
+ return;
2878
+ }
2879
+ e.stopPropagation();
2880
+ e.preventDefault();
2881
+ this.nodeRef.current?.setVisible(true);
2882
+ const dragBlockX = e.clientX - (this.pipelineNode.offsetLeft || 0) - this.playgroundConfigEntity.config.clientX;
2883
+ const dragBlockY = e.clientY - (this.pipelineNode.offsetTop || 0) - this.playgroundConfigEntity.config.clientY;
2884
+ this.node.style.left = `${dragBlockX}px`;
2885
+ this.node.style.top = `${dragBlockY}px`;
2886
+ },
2887
+ import_core19.PipelineLayerPriority.BASE_LAYER
2888
+ ),
2889
+ this.listenPlaygroundEvent("mousedown", () => {
2890
+ this.nodeRef.current?.setVisible(false);
2891
+ this.contextMenuService.rightPanelVisible = false;
2892
+ })
2893
+ ]);
2894
+ }
2895
+ onScroll() {
2896
+ this.nodeRef.current?.setVisible(false);
2897
+ }
2898
+ onZoom() {
2899
+ this.nodeRef.current?.setVisible(false);
2900
+ }
2901
+ /**
2902
+ * Destroy
2903
+ */
2904
+ dispose() {
2905
+ super.dispose();
2906
+ }
2907
+ /**
2908
+ * 渲染工具栏
2909
+ */
2910
+ renderCommandMenus() {
2911
+ return this.commandRegistry.commands.filter((cmd) => cmd.category === "SELECTOR_BOX" /* SELECTOR_BOX */).map((cmd) => {
2912
+ const CommandRenderer = this.rendererRegistry.getRendererComponent(
2913
+ cmd.icon || cmd.id
2914
+ )?.renderer;
2915
+ return /* @__PURE__ */ import_react17.default.createElement(
2916
+ CommandRenderer,
2917
+ {
2918
+ key: cmd.id,
2919
+ command: cmd,
2920
+ isContextMenu: true,
2921
+ disabled: !this.commandRegistry.isEnabled(cmd.id),
2922
+ onClick: (e) => this.commandRegistry.executeCommand(cmd.id, e)
2923
+ }
2924
+ );
2925
+ }).filter((c) => c);
2926
+ }
2927
+ render() {
2928
+ const SelectorBoxPopover = this.rendererRegistry.getRendererComponent(
2929
+ "context-menu-popover" /* CONTEXT_MENU_POPOVER */
2930
+ ).renderer;
2931
+ return /* @__PURE__ */ import_react17.default.createElement(SelectorBoxPopover, { ref: this.nodeRef, content: this.renderCommandMenus() });
2932
+ }
2933
+ };
2934
+ __decorateClass([
2935
+ (0, import_inversify12.inject)(import_core19.CommandRegistry)
2936
+ ], FlowContextMenuLayer.prototype, "commandRegistry", 2);
2937
+ __decorateClass([
2938
+ (0, import_inversify12.inject)(FlowRendererRegistry)
2939
+ ], FlowContextMenuLayer.prototype, "rendererRegistry", 2);
2940
+ __decorateClass([
2941
+ (0, import_inversify12.inject)(import_core19.ContextMenuService)
2942
+ ], FlowContextMenuLayer.prototype, "contextMenuService", 2);
2943
+ __decorateClass([
2944
+ (0, import_core19.observeEntity)(FlowSelectConfigEntity)
2945
+ ], FlowContextMenuLayer.prototype, "flowSelectConfigEntity", 2);
2946
+ __decorateClass([
2947
+ (0, import_inversify12.inject)(import_core19.SelectionService)
2948
+ ], FlowContextMenuLayer.prototype, "selectionService", 2);
2949
+ __decorateClass([
2950
+ (0, import_core19.observeEntity)(import_core19.PlaygroundConfigEntity)
2951
+ ], FlowContextMenuLayer.prototype, "playgroundConfigEntity", 2);
2952
+ __decorateClass([
2953
+ (0, import_core19.observeEntity)(import_core19.EditorStateConfigEntity)
2954
+ ], FlowContextMenuLayer.prototype, "editorStateConfig", 2);
2955
+ __decorateClass([
2956
+ (0, import_core19.observeEntity)(SelectorBoxConfigEntity)
2957
+ ], FlowContextMenuLayer.prototype, "selectorBoxConfigEntity", 2);
2958
+ FlowContextMenuLayer = __decorateClass([
2959
+ (0, import_inversify12.injectable)()
2960
+ ], FlowContextMenuLayer);
2961
+
2962
+ // src/layers/flow-scroll-limit-layer.tsx
2963
+ var import_inversify13 = require("inversify");
2964
+ var import_document21 = require("@flowgram.ai/document");
2965
+ var import_core20 = require("@flowgram.ai/core");
2966
+ var FlowScrollLimitLayer = class extends import_core20.Layer {
2967
+ getInitScroll() {
2968
+ return this.document.layout.getInitScroll(this.pipelineNode.getBoundingClientRect());
2969
+ }
2970
+ onReady() {
2971
+ const initScroll = () => this.getInitScroll();
2972
+ this.config.updateConfig(initScroll());
2973
+ this.config.addScrollLimit(
2974
+ (scroll) => scrollLimit(
2975
+ scroll,
2976
+ [this.document.root.getData(import_document21.FlowNodeTransformData).bounds],
2977
+ this.config,
2978
+ initScroll
2979
+ )
2980
+ );
2981
+ }
2982
+ };
2983
+ __decorateClass([
2984
+ (0, import_inversify13.inject)(import_document21.FlowDocument)
2985
+ ], FlowScrollLimitLayer.prototype, "document", 2);
2986
+ FlowScrollLimitLayer = __decorateClass([
2987
+ (0, import_inversify13.injectable)()
2988
+ ], FlowScrollLimitLayer);
2989
+
2990
+ // src/flow-renderer-container-module.ts
2991
+ var import_inversify14 = require("inversify");
2992
+ var FlowRendererContainerModule = new import_inversify14.ContainerModule((bind) => {
2993
+ bind(FlowRendererRegistry).toSelf().inSingletonScope();
2994
+ bind(FlowRendererResizeObserver).toSelf().inSingletonScope();
2995
+ });
2996
+ // Annotate the CommonJS export names for ESM import in node:
2997
+ 0 && (module.exports = {
2998
+ FlowContextMenuLayer,
2999
+ FlowDebugLayer,
3000
+ FlowDragEntity,
3001
+ FlowDragLayer,
3002
+ FlowLabelsLayer,
3003
+ FlowLinesLayer,
3004
+ FlowNodesContentLayer,
3005
+ FlowNodesTransformLayer,
3006
+ FlowRendererCommandCategory,
3007
+ FlowRendererComponentType,
3008
+ FlowRendererContainerModule,
3009
+ FlowRendererContribution,
3010
+ FlowRendererKey,
3011
+ FlowRendererRegistry,
3012
+ FlowScrollBarLayer,
3013
+ FlowScrollLimitLayer,
3014
+ FlowSelectConfigEntity,
3015
+ FlowSelectorBoundsLayer,
3016
+ FlowSelectorBoxLayer,
3017
+ FlowTextKey,
3018
+ MARK_ACTIVATED_ARROW_ID,
3019
+ MARK_ARROW_ID,
3020
+ ScrollBarEvents,
3021
+ SelectorBoxConfigEntity,
3022
+ createLines,
3023
+ useBaseColor
3024
+ });
3025
+ //# sourceMappingURL=index.js.map