@rxflow/base 0.0.3 → 0.0.4-alpha.1
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/cjs/Flow.d.ts +1 -1
- package/cjs/Flow.d.ts.map +1 -1
- package/cjs/Flow.js +28 -10
- package/cjs/components/Legend/index.d.ts.map +1 -1
- package/cjs/components/Legend/index.js +2 -1
- package/cjs/components/Popover/index.d.ts +1 -9
- package/cjs/components/Popover/index.d.ts.map +1 -1
- package/cjs/components/Popover/index.js +14 -75
- package/cjs/components/Tooltip/index.d.ts +1 -10
- package/cjs/components/Tooltip/index.d.ts.map +1 -1
- package/cjs/components/Tooltip/index.js +11 -83
- package/cjs/edges/manhattan.d.ts.map +1 -1
- package/cjs/edges/manhattan.js +100 -30
- package/cjs/hoc/createFlow.d.ts +30 -4
- package/cjs/hoc/createFlow.d.ts.map +1 -1
- package/cjs/hoc/createFlow.js +45 -18
- package/cjs/hooks/index.d.ts +5 -2
- package/cjs/hooks/index.d.ts.map +1 -1
- package/cjs/hooks/index.js +44 -22
- package/cjs/hooks/props/index.d.ts +12 -0
- package/cjs/hooks/props/index.d.ts.map +1 -0
- package/cjs/hooks/props/index.js +49 -0
- package/cjs/hooks/props/useFlowProps.d.ts +23 -0
- package/cjs/hooks/props/useFlowProps.d.ts.map +1 -0
- package/cjs/hooks/props/useFlowProps.js +34 -0
- package/cjs/hooks/props/useGetFlowProps.d.ts +19 -0
- package/cjs/hooks/props/useGetFlowProps.d.ts.map +1 -0
- package/cjs/hooks/props/useGetFlowProps.js +38 -0
- package/cjs/hooks/props/useGetInputProps.d.ts +18 -0
- package/cjs/hooks/props/useGetInputProps.d.ts.map +1 -0
- package/cjs/hooks/props/useGetInputProps.js +38 -0
- package/cjs/hooks/props/useInputProps.d.ts +14 -0
- package/cjs/hooks/props/useInputProps.d.ts.map +1 -0
- package/cjs/hooks/props/useInputProps.js +33 -0
- package/cjs/hooks/useListenRender.js +4 -4
- package/cjs/hooks/useTheme.d.ts.map +1 -1
- package/cjs/hooks/useTheme.js +3 -2
- package/cjs/index.d.ts +6 -3
- package/cjs/index.d.ts.map +1 -1
- package/cjs/index.js +46 -14
- package/cjs/providers/FlowProvider.d.ts +7 -1
- package/cjs/providers/FlowProvider.d.ts.map +1 -1
- package/cjs/providers/FlowProvider.js +33 -14
- package/cjs/store/PropsStore.d.ts +11 -6
- package/cjs/store/PropsStore.d.ts.map +1 -1
- package/cjs/store/PropsStore.js +55 -39
- package/cjs/types/props.d.ts +83 -0
- package/cjs/types/props.d.ts.map +1 -0
- package/cjs/types/props.js +5 -0
- package/cjs/types.d.ts +5 -1
- package/cjs/types.d.ts.map +1 -1
- package/cjs/utils/wrapNodeTypes.d.ts +30 -0
- package/cjs/utils/wrapNodeTypes.d.ts.map +1 -0
- package/cjs/utils/wrapNodeTypes.js +56 -0
- package/cjs/workers/manhattan.worker.js +12534 -31
- package/cjs/workers/manhattan.worker.js.map +7 -0
- package/esm/Flow.d.ts +1 -1
- package/esm/Flow.d.ts.map +1 -1
- package/esm/Flow.js +30 -16
- package/esm/components/Legend/index.d.ts.map +1 -1
- package/esm/components/Legend/index.js +3 -2
- package/esm/components/Popover/index.d.ts +1 -9
- package/esm/components/Popover/index.d.ts.map +1 -1
- package/esm/components/Popover/index.js +16 -87
- package/esm/components/Tooltip/index.d.ts +1 -10
- package/esm/components/Tooltip/index.d.ts.map +1 -1
- package/esm/components/Tooltip/index.js +14 -97
- package/esm/edges/manhattan.d.ts.map +1 -1
- package/esm/edges/manhattan.js +95 -23
- package/esm/hoc/createFlow.d.ts +30 -4
- package/esm/hoc/createFlow.d.ts.map +1 -1
- package/esm/hoc/createFlow.js +48 -20
- package/esm/hooks/index.d.ts +5 -2
- package/esm/hooks/index.d.ts.map +1 -1
- package/esm/hooks/index.js +8 -3
- package/esm/hooks/props/index.d.ts +12 -0
- package/esm/hooks/props/index.d.ts.map +1 -0
- package/esm/hooks/props/index.js +12 -0
- package/esm/hooks/props/useFlowProps.d.ts +23 -0
- package/esm/hooks/props/useFlowProps.d.ts.map +1 -0
- package/esm/hooks/props/useFlowProps.js +29 -0
- package/esm/hooks/props/useGetFlowProps.d.ts +19 -0
- package/esm/hooks/props/useGetFlowProps.d.ts.map +1 -0
- package/esm/hooks/props/useGetFlowProps.js +31 -0
- package/esm/hooks/props/useGetInputProps.d.ts +18 -0
- package/esm/hooks/props/useGetInputProps.d.ts.map +1 -0
- package/esm/hooks/props/useGetInputProps.js +31 -0
- package/esm/hooks/props/useInputProps.d.ts +14 -0
- package/esm/hooks/props/useInputProps.d.ts.map +1 -0
- package/esm/hooks/props/useInputProps.js +27 -0
- package/esm/hooks/useListenRender.js +4 -4
- package/esm/hooks/useTheme.d.ts.map +1 -1
- package/esm/hooks/useTheme.js +3 -2
- package/esm/index.d.ts +6 -3
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +22 -3
- package/esm/providers/FlowProvider.d.ts +7 -1
- package/esm/providers/FlowProvider.d.ts.map +1 -1
- package/esm/providers/FlowProvider.js +36 -15
- package/esm/store/PropsStore.d.ts +11 -6
- package/esm/store/PropsStore.d.ts.map +1 -1
- package/esm/store/PropsStore.js +75 -34
- package/esm/types/props.d.ts +83 -0
- package/esm/types/props.d.ts.map +1 -0
- package/esm/types/props.js +1 -0
- package/esm/types.d.ts +5 -1
- package/esm/types.d.ts.map +1 -1
- package/esm/utils/wrapNodeTypes.d.ts +30 -0
- package/esm/utils/wrapNodeTypes.d.ts.map +1 -0
- package/esm/utils/wrapNodeTypes.js +55 -0
- package/esm/workers/manhattan.worker.js +1 -1
- package/esm/workers/manhattan.worker.js.map +7 -0
- package/package.json +5 -3
- package/cjs/hooks/props/useGetProps.d.ts +0 -6
- package/cjs/hooks/props/useGetProps.d.ts.map +0 -1
- package/cjs/hooks/props/useGetProps.js +0 -29
- package/cjs/hooks/props/useProps.d.ts +0 -2
- package/cjs/hooks/props/useProps.d.ts.map +0 -1
- package/cjs/hooks/props/useProps.js +0 -20
- package/cjs/hooks/props/usePropsSelector.d.ts +0 -13
- package/cjs/hooks/props/usePropsSelector.d.ts.map +0 -1
- package/cjs/hooks/props/usePropsSelector.js +0 -37
- package/esm/hooks/props/useGetProps.d.ts +0 -6
- package/esm/hooks/props/useGetProps.d.ts.map +0 -1
- package/esm/hooks/props/useGetProps.js +0 -21
- package/esm/hooks/props/useProps.d.ts +0 -2
- package/esm/hooks/props/useProps.d.ts.map +0 -1
- package/esm/hooks/props/useProps.js +0 -14
- package/esm/hooks/props/usePropsSelector.d.ts +0 -13
- package/esm/hooks/props/usePropsSelector.d.ts.map +0 -1
- package/esm/hooks/props/usePropsSelector.js +0 -31
package/cjs/Flow.d.ts
CHANGED
package/cjs/Flow.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Flow.d.ts","sourceRoot":"","sources":["Flow.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,8BAA8B,CAAC;AACtC,OAAO,EAAC,cAAc,EAAC,MAAM,SAAS,CAAC;AAQvC,OAAO,EAGL,IAAI,EAGJ,IAAI,EAOL,MAAM,eAAe,CAAC;AAavB,OAAO,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Flow.d.ts","sourceRoot":"","sources":["Flow.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,8BAA8B,CAAC;AACtC,OAAO,EAAC,cAAc,EAAC,MAAM,SAAS,CAAC;AAQvC,OAAO,EAGL,IAAI,EAGJ,IAAI,EAOL,MAAM,eAAe,CAAC;AAavB,OAAO,cAAc,CAAC;AA0HtB,wBAAgB,IAAI,CAAC,QAAQ,SAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,SAAS,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,2CAwNzH"}
|
package/cjs/Flow.js
CHANGED
|
@@ -29,12 +29,26 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
29
29
|
/**
|
|
30
30
|
* @author: yanxianliang
|
|
31
31
|
* @date: 2025-07-27 16:33
|
|
32
|
-
* @modified:2025/
|
|
32
|
+
* @modified:2025/1/17 by yanxianliang
|
|
33
33
|
* @desc: Flow
|
|
34
34
|
*
|
|
35
35
|
* Copyright (c) 2025 by yanxianliang, All Rights Reserved.
|
|
36
36
|
*/
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* ReactFlow 原生支持的属性列表
|
|
40
|
+
* 这些属性会透传给 ReactFlow
|
|
41
|
+
*/const REACT_FLOW_PROPS = [
|
|
42
|
+
// 核心数据
|
|
43
|
+
'defaultNodes', 'defaultEdges', 'defaultEdgeOptions',
|
|
44
|
+
// 视图控制
|
|
45
|
+
'fitView', 'fitViewOptions', 'minZoom', 'maxZoom', 'defaultViewport', 'snapToGrid', 'snapGrid', 'onlyRenderVisibleElements',
|
|
46
|
+
// 交互控制
|
|
47
|
+
'nodesDraggable', 'nodesConnectable', 'nodesFocusable', 'edgesFocusable', 'elementsSelectable', 'selectNodesOnDrag', 'panOnDrag', 'panOnScroll', 'panOnScrollSpeed', 'panOnScrollMode', 'zoomOnScroll', 'zoomOnPinch', 'zoomOnDoubleClick', 'preventScrolling', 'connectionMode', 'connectionLineType', 'connectionLineStyle', 'connectionLineComponent', 'connectionLineContainerStyle', 'connectionRadius', 'isValidConnection', 'nodeDragThreshold', 'autoPanOnConnect', 'autoPanOnNodeDrag', 'autoPanSpeed', 'selectionOnDrag', 'selectionMode', 'selectionKeyCode', 'multiSelectionKeyCode', 'zoomActivationKeyCode', 'panActivationKeyCode', 'deleteKeyCode', 'nodeExtent', 'translateExtent', 'elevateNodesOnSelect', 'elevateEdgesOnSelect', 'disableKeyboardA11y', 'noDragClassName', 'noWheelClassName', 'noPanClassName',
|
|
48
|
+
// 事件回调
|
|
49
|
+
'onNodeClick', 'onNodeDoubleClick', 'onNodeMouseEnter', 'onNodeMouseMove', 'onNodeMouseLeave', 'onNodeContextMenu', 'onNodeDragStart', 'onNodeDrag', 'onNodeDragStop', 'onNodesDelete', 'onEdgeClick', 'onEdgeDoubleClick', 'onEdgeMouseEnter', 'onEdgeMouseMove', 'onEdgeMouseLeave', 'onEdgeContextMenu', 'onEdgeUpdate', 'onEdgeUpdateStart', 'onEdgeUpdateEnd', 'onEdgesDelete', 'onConnect', 'onConnectStart', 'onConnectEnd', 'onClickConnectStart', 'onClickConnectEnd', 'onMove', 'onMoveStart', 'onMoveEnd', 'onSelectionChange', 'onSelectionDragStart', 'onSelectionDrag', 'onSelectionDragStop', 'onSelectionContextMenu', 'onSelectionStart', 'onSelectionEnd', 'onPaneClick', 'onPaneContextMenu', 'onPaneScroll', 'onPaneMouseEnter', 'onPaneMouseMove', 'onPaneMouseLeave', 'onInit', 'onError', 'onDelete', 'onBeforeDelete',
|
|
50
|
+
// 样式
|
|
51
|
+
'style', 'className', 'id', 'colorMode'];
|
|
38
52
|
const proOptions = {
|
|
39
53
|
hideAttribution: true
|
|
40
54
|
}; // 默认隐藏水印
|
|
@@ -64,8 +78,6 @@ function Flow(props) {
|
|
|
64
78
|
edges,
|
|
65
79
|
layout = _base.baseLayout,
|
|
66
80
|
autoCenter = false,
|
|
67
|
-
omitProps = [],
|
|
68
|
-
// 不向下透传的属性
|
|
69
81
|
forceLayout = !!props.layout,
|
|
70
82
|
// 是否强制布局,如果强制布局会监控节点的dimension改变事件,自动触发布局计算
|
|
71
83
|
getMiniMapNodeColor,
|
|
@@ -121,8 +133,17 @@ function Flow(props) {
|
|
|
121
133
|
flowProps: props
|
|
122
134
|
});
|
|
123
135
|
}, [nodes, edges, forceUpdateTimes]);
|
|
136
|
+
const edgeTypes = (0, _react2.useMemo)(() => {
|
|
137
|
+
return {
|
|
138
|
+
manhattan: _manhattan.ManhattanEdge,
|
|
139
|
+
...(props.edgeTypes || {})
|
|
140
|
+
};
|
|
141
|
+
}, [props.edgeTypes]);
|
|
124
142
|
const flowProps = (0, _react2.useMemo)(() => {
|
|
143
|
+
// 使用 pick 选择需要透传的属性,而不是 omit 排除
|
|
144
|
+
const passthroughProps = (0, _lodash.pick)(props, REACT_FLOW_PROPS);
|
|
125
145
|
const options = {
|
|
146
|
+
// 默认配置
|
|
126
147
|
selectNodesOnDrag: false,
|
|
127
148
|
preventScrolling: true,
|
|
128
149
|
panOnScroll: false,
|
|
@@ -135,14 +156,10 @@ function Flow(props) {
|
|
|
135
156
|
},
|
|
136
157
|
fitView: true,
|
|
137
158
|
onlyRenderVisibleElements,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
manhattan: _manhattan.ManhattanEdge,
|
|
141
|
-
...(props.edgeTypes || {})
|
|
142
|
-
}
|
|
159
|
+
// 透传 ReactFlow 原生属性
|
|
160
|
+
...passthroughProps
|
|
143
161
|
};
|
|
144
162
|
if (plugins?.scroller) {
|
|
145
|
-
// 只读模式也需要
|
|
146
163
|
options.zoomOnScroll = false;
|
|
147
164
|
options.panOnScroll = true;
|
|
148
165
|
options.panOnDrag = options.panOnDrag ?? [1, 2];
|
|
@@ -155,7 +172,7 @@ function Flow(props) {
|
|
|
155
172
|
options.elementsSelectable = false;
|
|
156
173
|
}
|
|
157
174
|
return options;
|
|
158
|
-
}, [props, _nodes, readOnly, onlyRenderVisibleElements]);
|
|
175
|
+
}, [props, _nodes, readOnly, onlyRenderVisibleElements, autoCenter, plugins?.scroller]);
|
|
159
176
|
const onNodesChange = (0, _ahooks.useMemoizedFn)(changes => {
|
|
160
177
|
if (forceLayout && (0, _hasDimensionsChange.hasDimensionsChange)(changes)) {
|
|
161
178
|
// 强制布局
|
|
@@ -194,6 +211,7 @@ function Flow(props) {
|
|
|
194
211
|
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.ReactFlow, {
|
|
195
212
|
nodeTypes: nodeTypes,
|
|
196
213
|
...flowProps,
|
|
214
|
+
edgeTypes: edgeTypes,
|
|
197
215
|
nodes: _nodes,
|
|
198
216
|
edges: _edges,
|
|
199
217
|
onNodesChange: onNodesChange,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":"AAYA,OAAO,cAAc,CAAC;AAKtB,OAAO,EAAC,cAAc,EAAkB,MAAM,aAAa,CAAC;AAE5D,eAAO,MAAM,MAAM;gBAIH,cAAc,CAAC,YAAY,CAAC;oDAkD3C,CAAA"}
|
|
@@ -15,6 +15,7 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
15
15
|
/*
|
|
16
16
|
* @author: yanxianliang
|
|
17
17
|
* @date: 2025-06-03 19:33
|
|
18
|
+
* @modified:2025/1/17 by yanxianliang
|
|
18
19
|
* @desc: 图例标准组件。按照节点类型进行分类展示。
|
|
19
20
|
*
|
|
20
21
|
* 遍历当前的nodes 列表,根据类型定义解析出图例列表。
|
|
@@ -29,7 +30,7 @@ const Legend = ({
|
|
|
29
30
|
const showAll = typeof showLegend === "boolean" ? true : showLegend?.showAll ?? true; // 默认值为 true
|
|
30
31
|
|
|
31
32
|
// 节点定义列表
|
|
32
|
-
const nodeTypeList = (0, _hooks.
|
|
33
|
+
const nodeTypeList = (0, _hooks.useFlowProps)(state => state.nodeTypes);
|
|
33
34
|
const legendList = (0, _react2.useMemo)(() => {
|
|
34
35
|
const showTypeList = [];
|
|
35
36
|
const nodeTypeSet = new Set();
|
|
@@ -1,11 +1,3 @@
|
|
|
1
1
|
import { PopoverProps } from "antd/es/popover";
|
|
2
|
-
|
|
3
|
-
export declare function Popover(props: PopoverProps & {
|
|
4
|
-
children: React.ReactElement<{
|
|
5
|
-
onMouseEnter?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
6
|
-
onMouseLeave?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
7
|
-
onPointerEnter?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
8
|
-
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
9
|
-
}>;
|
|
10
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function Popover(props: PopoverProps): import("react/jsx-runtime").JSX.Element;
|
|
11
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":"AASA,OAAO,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAO7C,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,2CAqB1C"}
|
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.Popover = Popover;
|
|
7
7
|
var _react = require("@xyflow/react");
|
|
8
|
-
var _ahooks = require("ahooks");
|
|
9
8
|
var _antd = require("antd");
|
|
10
9
|
var _react2 = _interopRequireWildcard(require("react"));
|
|
11
10
|
var _useNodeDragging = require("../../hooks/node/useNodeDragging");
|
|
@@ -23,83 +22,23 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
23
22
|
|
|
24
23
|
function Popover(props) {
|
|
25
24
|
const isNodeDragging = (0, _useNodeDragging.useNodeDragging)();
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
const showFirstRef = (0, _react2.useRef)(false); // 是否首次渲染过
|
|
32
|
-
|
|
25
|
+
const {
|
|
26
|
+
x,
|
|
27
|
+
y
|
|
28
|
+
} = (0, _react.useViewport)();
|
|
33
29
|
const {
|
|
34
30
|
children,
|
|
35
|
-
trigger = 'hover',
|
|
36
31
|
...rest
|
|
37
32
|
} = props;
|
|
38
|
-
(0, _react2.useMemo)(() => {
|
|
39
|
-
if (open) {
|
|
40
|
-
showFirstRef.current = true; // 初始化之后就不销毁了
|
|
41
|
-
}
|
|
42
|
-
}, [open]);
|
|
43
|
-
const _onMouseEnter = (0, _ahooks.useMemoizedFn)(event => {
|
|
44
|
-
if (!showFirstRef.current) {
|
|
45
|
-
setOpen(true);
|
|
46
|
-
}
|
|
47
|
-
children?.props?.onMouseEnter?.(event);
|
|
48
|
-
});
|
|
49
|
-
const _onMouseLeave = (0, _ahooks.useMemoizedFn)(event => {
|
|
50
|
-
setOpen(false);
|
|
51
|
-
children?.props?.onMouseLeave?.(event);
|
|
52
|
-
});
|
|
53
|
-
const _onClick = (0, _ahooks.useMemoizedFn)(event => {
|
|
54
|
-
if (!showFirstRef.current) {
|
|
55
|
-
setOpen(beforeOpen => !beforeOpen);
|
|
56
|
-
}
|
|
57
|
-
children?.props?.onClick?.(event);
|
|
58
|
-
});
|
|
59
|
-
const triggerActions = (0, _react2.useMemo)(() => {
|
|
60
|
-
return {
|
|
61
|
-
click: trigger === 'click' || trigger && Array.from(trigger) && trigger.indexOf('click') !== -1,
|
|
62
|
-
hover: trigger === 'hover' || trigger && Array.from(trigger) && trigger.indexOf('hover') !== -1
|
|
63
|
-
};
|
|
64
|
-
}, []);
|
|
65
33
|
const tooltipRef = (0, _react2.useRef)(null);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (open) {
|
|
77
|
-
setOpen(false);
|
|
78
|
-
}
|
|
79
|
-
}, [isNodeDragging]);
|
|
80
|
-
const cloneChildren = (0, _react2.useMemo)(() => {
|
|
81
|
-
return /*#__PURE__*/_react2.default.cloneElement(children, {
|
|
82
|
-
...children.props,
|
|
83
|
-
...(triggerActions.hover ? {
|
|
84
|
-
onMouseEnter: _onMouseEnter,
|
|
85
|
-
onMouseLeave: _onMouseLeave
|
|
86
|
-
} : {}),
|
|
87
|
-
...(triggerActions.click ? {
|
|
88
|
-
onClick: _onClick
|
|
89
|
-
} : {})
|
|
90
|
-
});
|
|
91
|
-
}, [children]);
|
|
92
|
-
if (open || showFirstRef.current) {
|
|
93
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Popover, {
|
|
94
|
-
ref: tooltipRef,
|
|
95
|
-
destroyOnHidden: true,
|
|
96
|
-
getPopupContainer: _getPopupContainer.getPopupContainer,
|
|
97
|
-
...rest,
|
|
98
|
-
trigger: trigger,
|
|
99
|
-
open: open,
|
|
100
|
-
onOpenChange: setOpen,
|
|
101
|
-
children: children
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
return cloneChildren;
|
|
34
|
+
(0, _react2.useLayoutEffect)(() => {
|
|
35
|
+
tooltipRef.current?.forceAlign();
|
|
36
|
+
}, [isNodeDragging, x, y]);
|
|
37
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Popover, {
|
|
38
|
+
ref: tooltipRef,
|
|
39
|
+
destroyOnHidden: true,
|
|
40
|
+
getPopupContainer: _getPopupContainer.getPopupContainer,
|
|
41
|
+
...rest,
|
|
42
|
+
children: children
|
|
43
|
+
});
|
|
105
44
|
}
|
|
@@ -1,12 +1,3 @@
|
|
|
1
1
|
import { TooltipProps } from "antd/es/tooltip";
|
|
2
|
-
|
|
3
|
-
export declare function Tooltip({ children, canTooltipShow, title, trigger, ...rest }: TooltipProps & {
|
|
4
|
-
children: React.ReactElement<{
|
|
5
|
-
onMouseEnter?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
6
|
-
onMouseLeave?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
7
|
-
onPointerEnter?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
8
|
-
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
9
|
-
}>;
|
|
10
|
-
canTooltipShow?: (e: React.MouseEvent<HTMLElement>) => void;
|
|
11
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function Tooltip({ children, ...rest }: TooltipProps): import("react/jsx-runtime").JSX.Element;
|
|
12
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":"AASA,OAAO,EAAC,YAAY,EAAa,MAAM,iBAAiB,CAAC;AAKzD,wBAAgB,OAAO,CACrB,EACE,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,YAAY,2CAmBhB"}
|
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.Tooltip = Tooltip;
|
|
7
7
|
var _react = require("@xyflow/react");
|
|
8
|
-
var _ahooks = require("ahooks");
|
|
9
8
|
var _antd = require("antd");
|
|
10
9
|
var _react2 = _interopRequireWildcard(require("react"));
|
|
11
10
|
var _useNodeDragging = require("../../hooks/node/useNodeDragging");
|
|
@@ -23,93 +22,22 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
23
22
|
|
|
24
23
|
function Tooltip({
|
|
25
24
|
children,
|
|
26
|
-
canTooltipShow,
|
|
27
|
-
title,
|
|
28
|
-
trigger = 'hover',
|
|
29
25
|
...rest
|
|
30
26
|
}) {
|
|
31
|
-
const isNodeDragging = (0, _useNodeDragging.useNodeDragging)();
|
|
32
|
-
const [open, setOpen] = (0, _ahooks.useControllableValue)(rest, {
|
|
33
|
-
valuePropName: 'open',
|
|
34
|
-
defaultValue: false,
|
|
35
|
-
trigger: 'onOpenChange'
|
|
36
|
-
});
|
|
37
|
-
const showFirstRef = (0, _react2.useRef)(false); // 是否首次渲染过
|
|
38
|
-
|
|
39
|
-
(0, _react2.useMemo)(() => {
|
|
40
|
-
if (open) {
|
|
41
|
-
showFirstRef.current = true; // 初始化之后就不销毁了
|
|
42
|
-
}
|
|
43
|
-
}, [open]);
|
|
44
|
-
(0, _react2.useEffect)(() => {
|
|
45
|
-
if (!title) {
|
|
46
|
-
setOpen(false);
|
|
47
|
-
}
|
|
48
|
-
}, [title]);
|
|
49
|
-
const _onMouseEnter = (0, _ahooks.useMemoizedFn)(event => {
|
|
50
|
-
if (!showFirstRef.current) {
|
|
51
|
-
const canShow = canTooltipShow?.(event) ?? true;
|
|
52
|
-
if (canShow && title) {
|
|
53
|
-
setOpen(true);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
children?.props?.onMouseEnter?.(event);
|
|
57
|
-
});
|
|
58
|
-
const _onMouseLeave = (0, _ahooks.useMemoizedFn)(event => {
|
|
59
|
-
setOpen(false);
|
|
60
|
-
children?.props?.onMouseLeave?.(event);
|
|
61
|
-
});
|
|
62
|
-
const triggerActions = (0, _react2.useMemo)(() => {
|
|
63
|
-
return {
|
|
64
|
-
click: trigger === 'click' || trigger && Array.from(trigger) && trigger.indexOf('click') !== -1,
|
|
65
|
-
hover: trigger === 'hover' || trigger && Array.from(trigger) && trigger.indexOf('hover') !== -1
|
|
66
|
-
};
|
|
67
|
-
}, []);
|
|
68
|
-
const _onClick = (0, _ahooks.useMemoizedFn)(event => {
|
|
69
|
-
if (!showFirstRef.current) {
|
|
70
|
-
setOpen(beforeOpen => !beforeOpen);
|
|
71
|
-
}
|
|
72
|
-
children?.props?.onClick?.(event);
|
|
73
|
-
});
|
|
74
27
|
const tooltipRef = (0, _react2.useRef)(null);
|
|
28
|
+
const isNodeDragging = (0, _useNodeDragging.useNodeDragging)();
|
|
75
29
|
const {
|
|
76
30
|
x,
|
|
77
31
|
y
|
|
78
32
|
} = (0, _react.useViewport)();
|
|
79
|
-
(0, _react2.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
const cloneChildren = (0, _react2.useMemo)(() => {
|
|
90
|
-
return /*#__PURE__*/_react2.default.cloneElement(children, {
|
|
91
|
-
...children.props,
|
|
92
|
-
...(triggerActions.hover ? {
|
|
93
|
-
onMouseEnter: _onMouseEnter,
|
|
94
|
-
onMouseLeave: _onMouseLeave
|
|
95
|
-
} : {}),
|
|
96
|
-
...(triggerActions.click ? {
|
|
97
|
-
onClick: _onClick
|
|
98
|
-
} : {})
|
|
99
|
-
});
|
|
100
|
-
}, [children]);
|
|
101
|
-
if (open || showFirstRef.current) {
|
|
102
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, {
|
|
103
|
-
ref: tooltipRef,
|
|
104
|
-
destroyOnHidden: true,
|
|
105
|
-
title: title,
|
|
106
|
-
getPopupContainer: _getPopupContainer.getPopupContainer,
|
|
107
|
-
...rest,
|
|
108
|
-
trigger: trigger,
|
|
109
|
-
open: open,
|
|
110
|
-
onOpenChange: setOpen,
|
|
111
|
-
children: children
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
return cloneChildren;
|
|
33
|
+
(0, _react2.useLayoutEffect)(() => {
|
|
34
|
+
tooltipRef.current?.forceAlign();
|
|
35
|
+
}, [isNodeDragging, x, y]);
|
|
36
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, {
|
|
37
|
+
ref: tooltipRef,
|
|
38
|
+
destroyOnHidden: true,
|
|
39
|
+
getPopupContainer: _getPopupContainer.getPopupContainer,
|
|
40
|
+
...rest,
|
|
41
|
+
children: children
|
|
42
|
+
});
|
|
115
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manhattan.d.ts","sourceRoot":"","sources":["manhattan.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAW,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"manhattan.d.ts","sourceRoot":"","sources":["manhattan.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAW,KAAK,SAAS,EAA2C,MAAM,eAAe,CAAC;AACjG,OAAO,EAAC,aAAa,EAAoC,MAAM,OAAO,CAAC;AAmKvE,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,SAAS,CAwJjD,CAAA"}
|
package/cjs/edges/manhattan.js
CHANGED
|
@@ -18,22 +18,74 @@ var _jsxRuntime = require("react/jsx-runtime");
|
|
|
18
18
|
* Copyright (c) 2025 by yanxianliang, All Rights Reserved.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* 判断是否为简单的就近连接场景
|
|
23
|
+
* 这些场景不需要复杂的 Manhattan 算法,直接使用 SmoothStep 即可
|
|
24
|
+
*
|
|
25
|
+
* 就近连接规则:
|
|
26
|
+
* - 右锚点 → 左锚点(source 在 target 左侧)
|
|
27
|
+
* - 左锚点 → 右锚点(source 在 target 右侧)
|
|
28
|
+
* - 下锚点 → 上锚点(source 在 target 上方)
|
|
29
|
+
* - 上锚点 → 下锚点(source 在 target 下方)
|
|
30
|
+
*/
|
|
31
|
+
function isSimpleConnection(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition) {
|
|
32
|
+
// 右 → 左:source 在左侧,target 在右侧
|
|
33
|
+
if (sourcePosition === _react.Position.Right && targetPosition === _react.Position.Left) {
|
|
34
|
+
return sourceX < targetX;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 左 → 右:source 在右侧,target 在左侧
|
|
38
|
+
if (sourcePosition === _react.Position.Left && targetPosition === _react.Position.Right) {
|
|
39
|
+
return sourceX > targetX;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 下 → 上:source 在上方,target 在下方
|
|
43
|
+
if (sourcePosition === _react.Position.Bottom && targetPosition === _react.Position.Top) {
|
|
44
|
+
return sourceY < targetY;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 上 → 下:source 在下方,target 在上方
|
|
48
|
+
if (sourcePosition === _react.Position.Top && targetPosition === _react.Position.Bottom) {
|
|
49
|
+
return sourceY > targetY;
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
21
54
|
// 全局 Worker 实例(单例)
|
|
22
55
|
let workerInstance = null;
|
|
23
56
|
let workerApi = null;
|
|
57
|
+
let workerInitFailed = false;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 创建 Worker
|
|
61
|
+
* 使用预编译的 .js bundle,不使用 type: 'module' 以获得更好的浏览器兼容性
|
|
62
|
+
*/
|
|
63
|
+
function tryCreateWorker() {
|
|
64
|
+
try {
|
|
65
|
+
return new Worker(new URL('../workers/manhattan.worker.js', import.meta.url));
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.warn('[ManhattanEdge] Worker creation failed:', error);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
24
71
|
|
|
25
72
|
// 获取或创建 Worker
|
|
26
73
|
function getWorker() {
|
|
27
74
|
if (typeof window === 'undefined') return null; // SSR 环境
|
|
75
|
+
if (workerInitFailed) return null; // 之前初始化失败,不再尝试
|
|
28
76
|
|
|
29
77
|
if (!workerInstance || !workerApi) {
|
|
30
78
|
try {
|
|
31
|
-
workerInstance =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
79
|
+
workerInstance = tryCreateWorker();
|
|
80
|
+
if (workerInstance) {
|
|
81
|
+
workerApi = (0, _comlink.wrap)(workerInstance);
|
|
82
|
+
} else {
|
|
83
|
+
workerInitFailed = true;
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
35
86
|
} catch (error) {
|
|
36
87
|
console.warn('[ManhattanEdge] Worker initialization failed, using main thread:', error);
|
|
88
|
+
workerInitFailed = true;
|
|
37
89
|
return null;
|
|
38
90
|
}
|
|
39
91
|
}
|
|
@@ -51,7 +103,8 @@ const perfStats = {
|
|
|
51
103
|
cacheHits: 0,
|
|
52
104
|
cacheMisses: 0,
|
|
53
105
|
workerCalculations: 0,
|
|
54
|
-
mainThreadCalculations: 0
|
|
106
|
+
mainThreadCalculations: 0,
|
|
107
|
+
simplePathCalculations: 0 // 简单路径(使用 SmoothStep)
|
|
55
108
|
};
|
|
56
109
|
|
|
57
110
|
// 生成缓存 key
|
|
@@ -75,17 +128,20 @@ function resetPerfStats() {
|
|
|
75
128
|
perfStats.cacheMisses = 0;
|
|
76
129
|
perfStats.workerCalculations = 0;
|
|
77
130
|
perfStats.mainThreadCalculations = 0;
|
|
131
|
+
perfStats.simplePathCalculations = 0;
|
|
78
132
|
}
|
|
79
133
|
|
|
80
134
|
// 打印统计
|
|
81
135
|
function logPerfStats() {
|
|
82
136
|
const totalDuration = performance.now() - perfStats.startTime;
|
|
83
137
|
const cacheHitRate = perfStats.totalEdges > 0 ? (perfStats.cacheHits / perfStats.totalEdges * 100).toFixed(1) : '0';
|
|
138
|
+
const simplePathRate = perfStats.totalEdges > 0 ? (perfStats.simplePathCalculations / perfStats.totalEdges * 100).toFixed(1) : '0';
|
|
84
139
|
console.log('=== Manhattan Edge Performance Stats ===');
|
|
85
140
|
console.log(`Total edges: ${perfStats.totalEdges}`);
|
|
86
141
|
console.log(`Completed: ${perfStats.completedEdges}`);
|
|
87
142
|
console.log(`Cache hits: ${perfStats.cacheHits} (${cacheHitRate}%)`);
|
|
88
143
|
console.log(`Cache misses: ${perfStats.cacheMisses}`);
|
|
144
|
+
console.log(`Simple paths (SmoothStep): ${perfStats.simplePathCalculations} (${simplePathRate}%)`);
|
|
89
145
|
console.log(`Worker calculations: ${perfStats.workerCalculations}`);
|
|
90
146
|
console.log(`Main thread calculations: ${perfStats.mainThreadCalculations}`);
|
|
91
147
|
console.log(`Total calculation time: ${perfStats.totalTime.toFixed(2)}ms`);
|
|
@@ -147,32 +203,48 @@ const ManhattanEdge = exports.ManhattanEdge = /*#__PURE__*/(0, _react2.memo)(({
|
|
|
147
203
|
if (!isMountedRef.current) return;
|
|
148
204
|
const startTime = performance.now();
|
|
149
205
|
let calculatedPath;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
206
|
+
|
|
207
|
+
// 前置判断:简单的就近连接场景直接使用 SmoothStep
|
|
208
|
+
if (isSimpleConnection(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition)) {
|
|
209
|
+
perfStats.simplePathCalculations++;
|
|
210
|
+
const [smoothPath] = (0, _react.getSmoothStepPath)({
|
|
211
|
+
sourceX,
|
|
212
|
+
sourceY,
|
|
213
|
+
sourcePosition,
|
|
214
|
+
targetX,
|
|
215
|
+
targetY,
|
|
216
|
+
targetPosition
|
|
217
|
+
});
|
|
218
|
+
calculatedPath = smoothPath;
|
|
219
|
+
} else {
|
|
220
|
+
// 复杂场景使用 Manhattan 算法
|
|
221
|
+
const params = {
|
|
222
|
+
sourceNodeId: source,
|
|
223
|
+
targetNodeId: target,
|
|
224
|
+
sourceX,
|
|
225
|
+
sourceY,
|
|
226
|
+
sourcePosition,
|
|
227
|
+
targetX,
|
|
228
|
+
targetY,
|
|
229
|
+
targetPosition,
|
|
230
|
+
nodeLookup: nodeLookup
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// 尝试使用 Worker,失败则回退到主线程
|
|
234
|
+
const worker = getWorker();
|
|
235
|
+
try {
|
|
236
|
+
if (worker) {
|
|
237
|
+
perfStats.workerCalculations++;
|
|
238
|
+
calculatedPath = await worker.calculatePath(params);
|
|
239
|
+
} else {
|
|
240
|
+
perfStats.mainThreadCalculations++;
|
|
241
|
+
calculatedPath = (0, _manhattan.getManHattanPath)(params);
|
|
242
|
+
}
|
|
243
|
+
} catch (error) {
|
|
244
|
+
// Fallback 到主线程
|
|
169
245
|
perfStats.mainThreadCalculations++;
|
|
170
246
|
calculatedPath = (0, _manhattan.getManHattanPath)(params);
|
|
171
247
|
}
|
|
172
|
-
} catch (error) {
|
|
173
|
-
// Fallback 到主线程
|
|
174
|
-
perfStats.mainThreadCalculations++;
|
|
175
|
-
calculatedPath = (0, _manhattan.getManHattanPath)(params);
|
|
176
248
|
}
|
|
177
249
|
const endTime = performance.now();
|
|
178
250
|
const duration = endTime - startTime;
|
|
@@ -201,8 +273,6 @@ const ManhattanEdge = exports.ManhattanEdge = /*#__PURE__*/(0, _react2.memo)(({
|
|
|
201
273
|
logPerfStats();
|
|
202
274
|
}
|
|
203
275
|
};
|
|
204
|
-
|
|
205
|
-
// 直接执行异步计算(Worker 已经是异步的)
|
|
206
276
|
calculatePath();
|
|
207
277
|
return () => {
|
|
208
278
|
isMountedRef.current = false;
|
package/cjs/hoc/createFlow.d.ts
CHANGED
|
@@ -1,14 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @author: yanxianliang
|
|
3
3
|
* @date: 2025-10-15 15:25
|
|
4
|
-
* @modified:2025/
|
|
4
|
+
* @modified:2025/1/17 by yanxianliang
|
|
5
5
|
* @desc: 创建 Flow 组件
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* 提供公共能力封装,支持双层 Props 存储
|
|
8
8
|
*
|
|
9
9
|
* Copyright (c) 2025 by yanxianliang, All Rights Reserved.
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
11
|
+
import { Edge, Node } from "@xyflow/react";
|
|
12
12
|
import React, { PropsWithChildren } from "react";
|
|
13
|
-
|
|
13
|
+
import { IBaseFlowProps } from "../types";
|
|
14
|
+
/**
|
|
15
|
+
* 创建 Flow 组件的工厂函数
|
|
16
|
+
*
|
|
17
|
+
* @param FlowComponent - 基础 Flow 组件
|
|
18
|
+
* @param usePropsTransform - Props 转换 hook,将输入 props 转换为 Flow props
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // 基础用法
|
|
22
|
+
* const MyFlow = createFlow(Flow);
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // 带 props 转换
|
|
26
|
+
* const BloodlineFlow = createFlow<IBloodlineFlowProps, BloodlineExtendProps>(
|
|
27
|
+
* Flow,
|
|
28
|
+
* (props) => {
|
|
29
|
+
* const { root, nodeTypes } = props;
|
|
30
|
+
* const nodes = useMemo(() => root ? [root] : [], [root]);
|
|
31
|
+
* return {
|
|
32
|
+
* ...props,
|
|
33
|
+
* nodes,
|
|
34
|
+
* nodeTypes: wrapNodeTypes(nodeTypes, BaseNodeWrapper),
|
|
35
|
+
* };
|
|
36
|
+
* }
|
|
37
|
+
* );
|
|
38
|
+
*/
|
|
39
|
+
export declare function createFlow<TInputProps = IBaseFlowProps, TExtendProps = {}, NodeType extends Node = Node, EdgeType extends Edge = Edge>(FlowComponent: React.ComponentType<IBaseFlowProps<NodeType, EdgeType> & TExtendProps>, usePropsTransform?: (props: PropsWithChildren<TInputProps>) => PropsWithChildren<IBaseFlowProps<NodeType, EdgeType> & TExtendProps>): (props: React.PropsWithChildren<TInputProps>) => import("react/jsx-runtime").JSX.Element;
|
|
14
40
|
//# sourceMappingURL=createFlow.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createFlow.d.ts","sourceRoot":"","sources":["createFlow.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"createFlow.d.ts","sourceRoot":"","sources":["createFlow.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,MAAM,eAAe,CAAC;AAEzC,OAAO,KAAK,EAAE,EAAC,iBAAiB,EAAC,MAAM,OAAO,CAAC;AAG/C,OAAO,EAAC,cAAc,EAAC,MAAM,UAAU,CAAC;AAwBxC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,UAAU,CACxB,WAAW,GAAG,cAAc,EAC5B,YAAY,GAAG,EAAE,EACjB,QAAQ,SAAS,IAAI,GAAG,IAAI,EAC5B,QAAQ,SAAS,IAAI,GAAG,IAAI,EAE5B,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAC,EACrF,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,WAAW,CAAC,KAAK,iBAAiB,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAC,4FA4BpI"}
|