@01.software/sdk 0.4.3-dev.1774339118317 → 0.4.3-dev.1774340903661
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/ui/flow.cjs +124 -86
- package/dist/ui/flow.cjs.map +1 -1
- package/dist/ui/flow.js +126 -93
- package/dist/ui/flow.js.map +1 -1
- package/package.json +3 -3
package/dist/ui/flow.js
CHANGED
|
@@ -39,19 +39,6 @@ var __async = (__this, __arguments, generator) => {
|
|
|
39
39
|
});
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
// src/ui/Flow/index.tsx
|
|
43
|
-
import React2 from "react";
|
|
44
|
-
import {
|
|
45
|
-
ReactFlow,
|
|
46
|
-
ReactFlowProvider,
|
|
47
|
-
Background,
|
|
48
|
-
Controls,
|
|
49
|
-
MiniMap,
|
|
50
|
-
MarkerType,
|
|
51
|
-
useReactFlow,
|
|
52
|
-
useStoreApi
|
|
53
|
-
} from "@xyflow/react";
|
|
54
|
-
|
|
55
42
|
// src/ui/Flow/types.ts
|
|
56
43
|
function isDynamicNode(node) {
|
|
57
44
|
return node.type === "dynamic";
|
|
@@ -444,7 +431,21 @@ function clearTemplateCache() {
|
|
|
444
431
|
componentCache.clear();
|
|
445
432
|
}
|
|
446
433
|
|
|
447
|
-
// src/ui/Flow/
|
|
434
|
+
// src/ui/Flow/FlowRenderer.tsx
|
|
435
|
+
import React5 from "react";
|
|
436
|
+
import {
|
|
437
|
+
ReactFlow,
|
|
438
|
+
ReactFlowProvider,
|
|
439
|
+
Background,
|
|
440
|
+
Controls,
|
|
441
|
+
MiniMap
|
|
442
|
+
} from "@xyflow/react";
|
|
443
|
+
|
|
444
|
+
// src/ui/Flow/node-types-factory.tsx
|
|
445
|
+
import React3 from "react";
|
|
446
|
+
|
|
447
|
+
// src/ui/Flow/node-renderers.tsx
|
|
448
|
+
import React2 from "react";
|
|
448
449
|
function sanitizeUrl(url) {
|
|
449
450
|
if (!url) return url;
|
|
450
451
|
try {
|
|
@@ -455,11 +456,6 @@ function sanitizeUrl(url) {
|
|
|
455
456
|
return void 0;
|
|
456
457
|
}
|
|
457
458
|
}
|
|
458
|
-
function toMarkerType(value) {
|
|
459
|
-
if (value === "arrow") return MarkerType.Arrow;
|
|
460
|
-
if (value === "arrowclosed") return MarkerType.ArrowClosed;
|
|
461
|
-
return void 0;
|
|
462
|
-
}
|
|
463
459
|
function renderFieldValue(key, val, fieldDef) {
|
|
464
460
|
if (val == null || val === "") return null;
|
|
465
461
|
const fieldType = fieldDef == null ? void 0 : fieldDef.fieldType;
|
|
@@ -611,13 +607,15 @@ function DefaultFrameNode({ data }) {
|
|
|
611
607
|
)
|
|
612
608
|
);
|
|
613
609
|
}
|
|
610
|
+
|
|
611
|
+
// src/ui/Flow/node-types-factory.tsx
|
|
614
612
|
function createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrapper, renderNode) {
|
|
615
613
|
const types = {};
|
|
616
614
|
types.dynamic = ((props) => {
|
|
617
615
|
const d = props.data;
|
|
618
616
|
const typeDef = nodeTypeDefsMap == null ? void 0 : nodeTypeDefsMap.get(d.nodeTypeSlug);
|
|
619
617
|
const CustomRenderer = nodeRenderers == null ? void 0 : nodeRenderers[d.nodeTypeSlug];
|
|
620
|
-
const defaultRender = typeDef ? /* @__PURE__ */
|
|
618
|
+
const defaultRender = typeDef ? /* @__PURE__ */ React3.createElement(
|
|
621
619
|
EnhancedDynamicNode,
|
|
622
620
|
{
|
|
623
621
|
data: d,
|
|
@@ -625,7 +623,7 @@ function createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrap
|
|
|
625
623
|
width: props.width,
|
|
626
624
|
height: props.height
|
|
627
625
|
}
|
|
628
|
-
) : /* @__PURE__ */
|
|
626
|
+
) : /* @__PURE__ */ React3.createElement(DefaultDynamicNode, __spreadValues({}, props));
|
|
629
627
|
const slotProps = {
|
|
630
628
|
id: props.id,
|
|
631
629
|
nodeTypeSlug: d.nodeTypeSlug,
|
|
@@ -637,14 +635,14 @@ function createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrap
|
|
|
637
635
|
height: props.height,
|
|
638
636
|
defaultRender
|
|
639
637
|
};
|
|
640
|
-
let content = CustomRenderer ? /* @__PURE__ */
|
|
638
|
+
let content = CustomRenderer ? /* @__PURE__ */ React3.createElement(CustomRenderer, __spreadValues({}, slotProps)) : defaultRender;
|
|
641
639
|
if (renderNode) {
|
|
642
640
|
const result = renderNode(slotProps, content);
|
|
643
641
|
if (result !== null) content = result;
|
|
644
642
|
}
|
|
645
643
|
if (nodeWrapper) {
|
|
646
644
|
const Wrapper = nodeWrapper;
|
|
647
|
-
content = /* @__PURE__ */
|
|
645
|
+
content = /* @__PURE__ */ React3.createElement(
|
|
648
646
|
Wrapper,
|
|
649
647
|
{
|
|
650
648
|
id: props.id,
|
|
@@ -661,7 +659,7 @@ function createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrap
|
|
|
661
659
|
types.frame = frameRenderer ? ((props) => {
|
|
662
660
|
const d = props.data;
|
|
663
661
|
const Renderer = frameRenderer;
|
|
664
|
-
return /* @__PURE__ */
|
|
662
|
+
return /* @__PURE__ */ React3.createElement(
|
|
665
663
|
Renderer,
|
|
666
664
|
{
|
|
667
665
|
id: props.id,
|
|
@@ -685,7 +683,7 @@ function createEdgeTypes(edgeRenderers, edgeTypeDefsMap) {
|
|
|
685
683
|
types[slug] = ((props) => {
|
|
686
684
|
var _a;
|
|
687
685
|
const def = edgeTypeDefsMap == null ? void 0 : edgeTypeDefsMap.get(slug);
|
|
688
|
-
return /* @__PURE__ */
|
|
686
|
+
return /* @__PURE__ */ React3.createElement(
|
|
689
687
|
Renderer,
|
|
690
688
|
{
|
|
691
689
|
id: props.id,
|
|
@@ -702,6 +700,57 @@ function createEdgeTypes(edgeRenderers, edgeTypeDefsMap) {
|
|
|
702
700
|
}
|
|
703
701
|
return types;
|
|
704
702
|
}
|
|
703
|
+
|
|
704
|
+
// src/ui/Flow/edge-styles.ts
|
|
705
|
+
import { MarkerType } from "@xyflow/react";
|
|
706
|
+
function toMarkerType(value) {
|
|
707
|
+
if (value === "arrow") return MarkerType.Arrow;
|
|
708
|
+
if (value === "arrowclosed") return MarkerType.ArrowClosed;
|
|
709
|
+
return void 0;
|
|
710
|
+
}
|
|
711
|
+
var EDGE_TYPE_MAP = {
|
|
712
|
+
step: "step",
|
|
713
|
+
smoothstep: "smoothstep",
|
|
714
|
+
bezier: "default",
|
|
715
|
+
default: "default"
|
|
716
|
+
};
|
|
717
|
+
function applyEdgeStyles(edges, edgeTypeDefsMap) {
|
|
718
|
+
if (!(edgeTypeDefsMap == null ? void 0 : edgeTypeDefsMap.size)) return edges;
|
|
719
|
+
return edges.map((edge) => {
|
|
720
|
+
var _a;
|
|
721
|
+
const slug = edge.edgeTypeSlug;
|
|
722
|
+
if (!slug) return edge;
|
|
723
|
+
const def = edgeTypeDefsMap.get(slug);
|
|
724
|
+
if (!def) return edge;
|
|
725
|
+
const styled = __spreadValues({}, edge);
|
|
726
|
+
if (!styled.type && def.lineStyle) {
|
|
727
|
+
styled.type = (_a = EDGE_TYPE_MAP[def.lineStyle]) != null ? _a : "default";
|
|
728
|
+
}
|
|
729
|
+
styled.style = __spreadValues(__spreadValues(__spreadValues({}, def.color ? { stroke: def.color } : void 0), def.strokeWidth ? { strokeWidth: def.strokeWidth } : void 0), edge.style);
|
|
730
|
+
if (styled.animated == null && def.animated) styled.animated = true;
|
|
731
|
+
if (!styled.markerStart) {
|
|
732
|
+
const startType = toMarkerType(def.markerStart);
|
|
733
|
+
if (startType) {
|
|
734
|
+
styled.markerStart = __spreadValues({
|
|
735
|
+
type: startType
|
|
736
|
+
}, def.color ? { color: def.color } : void 0);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
if (!styled.markerEnd) {
|
|
740
|
+
const endType = toMarkerType(def.markerEnd);
|
|
741
|
+
if (endType) {
|
|
742
|
+
styled.markerEnd = __spreadValues({
|
|
743
|
+
type: endType
|
|
744
|
+
}, def.color ? { color: def.color } : void 0);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
return styled;
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// src/ui/Flow/focus-handler.tsx
|
|
752
|
+
import React4 from "react";
|
|
753
|
+
import { useReactFlow, useStoreApi } from "@xyflow/react";
|
|
705
754
|
function clampViewport(vp, cw, ch, extent) {
|
|
706
755
|
const left = -vp.x / vp.zoom;
|
|
707
756
|
const right = (cw - vp.x) / vp.zoom;
|
|
@@ -724,18 +773,19 @@ function FocusHandler({
|
|
|
724
773
|
responsive,
|
|
725
774
|
extent,
|
|
726
775
|
clampBounds,
|
|
727
|
-
minZoomProp
|
|
776
|
+
minZoomProp,
|
|
777
|
+
onInitialFit
|
|
728
778
|
}) {
|
|
729
779
|
const { setViewport } = useReactFlow();
|
|
730
780
|
const store = useStoreApi();
|
|
731
|
-
const containerRef =
|
|
781
|
+
const containerRef = React4.useRef(null);
|
|
732
782
|
const boundsKey = `${bounds.x},${bounds.y},${bounds.width},${bounds.height}`;
|
|
733
|
-
const boundsRef =
|
|
783
|
+
const boundsRef = React4.useRef(bounds);
|
|
734
784
|
boundsRef.current = bounds;
|
|
735
|
-
const [containerSize, setContainerSize] =
|
|
736
|
-
const prevBoundsKeyRef =
|
|
737
|
-
const prevSizeRef =
|
|
738
|
-
|
|
785
|
+
const [containerSize, setContainerSize] = React4.useState({ w: 0, h: 0 });
|
|
786
|
+
const prevBoundsKeyRef = React4.useRef(null);
|
|
787
|
+
const prevSizeRef = React4.useRef({ w: 0, h: 0 });
|
|
788
|
+
React4.useEffect(() => {
|
|
739
789
|
const el = containerRef.current;
|
|
740
790
|
if (!el) return;
|
|
741
791
|
const observer = new ResizeObserver((entries) => {
|
|
@@ -747,7 +797,7 @@ function FocusHandler({
|
|
|
747
797
|
observer.observe(el);
|
|
748
798
|
return () => observer.disconnect();
|
|
749
799
|
}, []);
|
|
750
|
-
|
|
800
|
+
React4.useEffect(() => {
|
|
751
801
|
if (containerSize.w === 0 || containerSize.h === 0) return;
|
|
752
802
|
const prevKey = prevBoundsKeyRef.current;
|
|
753
803
|
const prevSize = prevSizeRef.current;
|
|
@@ -780,10 +830,15 @@ function FocusHandler({
|
|
|
780
830
|
store.getState().setMinZoom(minZoomProp != null ? minZoomProp : 0.5);
|
|
781
831
|
}
|
|
782
832
|
let vp = { x, y, zoom };
|
|
783
|
-
if (
|
|
784
|
-
|
|
833
|
+
if (isInitial || isBoundsChange) {
|
|
834
|
+
setViewport(vp, { duration: isInitial ? 0 : duration });
|
|
835
|
+
onInitialFit == null ? void 0 : onInitialFit();
|
|
836
|
+
} else {
|
|
837
|
+
if (extent) {
|
|
838
|
+
vp = clampViewport(vp, containerSize.w, containerSize.h, extent);
|
|
839
|
+
}
|
|
840
|
+
setViewport(vp, { duration });
|
|
785
841
|
}
|
|
786
|
-
setViewport(vp, { duration });
|
|
787
842
|
}, [
|
|
788
843
|
boundsKey,
|
|
789
844
|
padding,
|
|
@@ -796,9 +851,10 @@ function FocusHandler({
|
|
|
796
851
|
setViewport,
|
|
797
852
|
clampBounds,
|
|
798
853
|
minZoomProp,
|
|
799
|
-
store
|
|
854
|
+
store,
|
|
855
|
+
onInitialFit
|
|
800
856
|
]);
|
|
801
|
-
return /* @__PURE__ */
|
|
857
|
+
return /* @__PURE__ */ React4.createElement(
|
|
802
858
|
"div",
|
|
803
859
|
{
|
|
804
860
|
ref: containerRef,
|
|
@@ -811,45 +867,8 @@ function FocusHandler({
|
|
|
811
867
|
}
|
|
812
868
|
);
|
|
813
869
|
}
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
smoothstep: "smoothstep",
|
|
817
|
-
bezier: "default",
|
|
818
|
-
default: "default"
|
|
819
|
-
};
|
|
820
|
-
function applyEdgeStyles(edges, edgeTypeDefsMap) {
|
|
821
|
-
if (!(edgeTypeDefsMap == null ? void 0 : edgeTypeDefsMap.size)) return edges;
|
|
822
|
-
return edges.map((edge) => {
|
|
823
|
-
var _a;
|
|
824
|
-
const slug = edge.edgeTypeSlug;
|
|
825
|
-
if (!slug) return edge;
|
|
826
|
-
const def = edgeTypeDefsMap.get(slug);
|
|
827
|
-
if (!def) return edge;
|
|
828
|
-
const styled = __spreadValues({}, edge);
|
|
829
|
-
if (!styled.type && def.lineStyle) {
|
|
830
|
-
styled.type = (_a = EDGE_TYPE_MAP[def.lineStyle]) != null ? _a : "default";
|
|
831
|
-
}
|
|
832
|
-
styled.style = __spreadValues(__spreadValues(__spreadValues({}, def.color ? { stroke: def.color } : void 0), def.strokeWidth ? { strokeWidth: def.strokeWidth } : void 0), edge.style);
|
|
833
|
-
if (styled.animated == null && def.animated) styled.animated = true;
|
|
834
|
-
if (!styled.markerStart) {
|
|
835
|
-
const startType = toMarkerType(def.markerStart);
|
|
836
|
-
if (startType) {
|
|
837
|
-
styled.markerStart = __spreadValues({
|
|
838
|
-
type: startType
|
|
839
|
-
}, def.color ? { color: def.color } : void 0);
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
if (!styled.markerEnd) {
|
|
843
|
-
const endType = toMarkerType(def.markerEnd);
|
|
844
|
-
if (endType) {
|
|
845
|
-
styled.markerEnd = __spreadValues({
|
|
846
|
-
type: endType
|
|
847
|
-
}, def.color ? { color: def.color } : void 0);
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
return styled;
|
|
851
|
-
});
|
|
852
|
-
}
|
|
870
|
+
|
|
871
|
+
// src/ui/Flow/FlowRenderer.tsx
|
|
853
872
|
function FlowRenderer({
|
|
854
873
|
data,
|
|
855
874
|
className,
|
|
@@ -887,15 +906,15 @@ function FlowRenderer({
|
|
|
887
906
|
maxZoom: maxZoomProp
|
|
888
907
|
}) {
|
|
889
908
|
var _a;
|
|
890
|
-
const nodeTypeDefsMap =
|
|
909
|
+
const nodeTypeDefsMap = React5.useMemo(() => {
|
|
891
910
|
if (!(nodeTypeDefs == null ? void 0 : nodeTypeDefs.length)) return void 0;
|
|
892
911
|
return new Map(nodeTypeDefs.map((d) => [d.slug, d]));
|
|
893
912
|
}, [nodeTypeDefs]);
|
|
894
|
-
const edgeTypeDefsMap =
|
|
913
|
+
const edgeTypeDefsMap = React5.useMemo(() => {
|
|
895
914
|
if (!(edgeTypeDefs == null ? void 0 : edgeTypeDefs.length)) return void 0;
|
|
896
915
|
return new Map(edgeTypeDefs.map((d) => [d.slug, d]));
|
|
897
916
|
}, [edgeTypeDefs]);
|
|
898
|
-
const nodeTypes =
|
|
917
|
+
const nodeTypes = React5.useMemo(
|
|
899
918
|
() => createNodeTypes(
|
|
900
919
|
nodeRenderers,
|
|
901
920
|
nodeTypeDefsMap,
|
|
@@ -905,15 +924,15 @@ function FlowRenderer({
|
|
|
905
924
|
),
|
|
906
925
|
[nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrapper, renderNode]
|
|
907
926
|
);
|
|
908
|
-
const customEdgeTypes =
|
|
927
|
+
const customEdgeTypes = React5.useMemo(
|
|
909
928
|
() => createEdgeTypes(edgeRenderers, edgeTypeDefsMap),
|
|
910
929
|
[edgeRenderers, edgeTypeDefsMap]
|
|
911
930
|
);
|
|
912
|
-
const mergedCSS =
|
|
931
|
+
const mergedCSS = React5.useMemo(() => {
|
|
913
932
|
if (!(nodeTypeDefs == null ? void 0 : nodeTypeDefs.length)) return "";
|
|
914
933
|
return nodeTypeDefs.filter((d) => d.customCSS).map((d) => d.customCSS).join("\n");
|
|
915
934
|
}, [nodeTypeDefs]);
|
|
916
|
-
const styledEdges =
|
|
935
|
+
const styledEdges = React5.useMemo(() => {
|
|
917
936
|
var _a2;
|
|
918
937
|
let edges = applyEdgeStyles((_a2 = data == null ? void 0 : data.edges) != null ? _a2 : [], edgeTypeDefsMap);
|
|
919
938
|
if (edgeRenderers) {
|
|
@@ -927,7 +946,7 @@ function FlowRenderer({
|
|
|
927
946
|
}
|
|
928
947
|
return edges;
|
|
929
948
|
}, [data == null ? void 0 : data.edges, edgeTypeDefsMap, edgeRenderers]);
|
|
930
|
-
const translateExtent =
|
|
949
|
+
const translateExtent = React5.useMemo(() => {
|
|
931
950
|
if (translateExtentProp) return translateExtentProp;
|
|
932
951
|
const es = clampBounds != null ? clampBounds : bounds;
|
|
933
952
|
if (!es) return void 0;
|
|
@@ -937,9 +956,22 @@ function FlowRenderer({
|
|
|
937
956
|
[es.x + es.width * (1 + ep), es.y + es.height * (1 + ep)]
|
|
938
957
|
];
|
|
939
958
|
}, [translateExtentProp, clampBounds, bounds, focusPadding]);
|
|
959
|
+
const boundsKey = bounds ? `${bounds.x},${bounds.y},${bounds.width},${bounds.height}` : "";
|
|
960
|
+
const extentReadyRef = React5.useRef(false);
|
|
961
|
+
const prevBoundsKeyRef = React5.useRef(boundsKey);
|
|
962
|
+
if (prevBoundsKeyRef.current !== boundsKey) {
|
|
963
|
+
prevBoundsKeyRef.current = boundsKey;
|
|
964
|
+
extentReadyRef.current = false;
|
|
965
|
+
}
|
|
966
|
+
const [, rerender] = React5.useReducer((x) => x + 1, 0);
|
|
967
|
+
const handleInitialFit = React5.useCallback(() => {
|
|
968
|
+
extentReadyRef.current = true;
|
|
969
|
+
rerender();
|
|
970
|
+
}, []);
|
|
971
|
+
const activeExtent = !bounds || extentReadyRef.current ? translateExtent : void 0;
|
|
940
972
|
if (!data) return null;
|
|
941
973
|
const resolvedDefaultViewport = defaultViewportProp != null ? defaultViewportProp : !fitView && data.viewport ? data.viewport : void 0;
|
|
942
|
-
return /* @__PURE__ */
|
|
974
|
+
return /* @__PURE__ */ React5.createElement(ReactFlowProvider, null, /* @__PURE__ */ React5.createElement(
|
|
943
975
|
"div",
|
|
944
976
|
{
|
|
945
977
|
className,
|
|
@@ -949,7 +981,7 @@ function FlowRenderer({
|
|
|
949
981
|
background: "transparent"
|
|
950
982
|
}, style)
|
|
951
983
|
},
|
|
952
|
-
/* @__PURE__ */
|
|
984
|
+
/* @__PURE__ */ React5.createElement(
|
|
953
985
|
ReactFlow,
|
|
954
986
|
{
|
|
955
987
|
nodes: (_a = data.nodes) != null ? _a : [],
|
|
@@ -958,7 +990,7 @@ function FlowRenderer({
|
|
|
958
990
|
edgeTypes: customEdgeTypes,
|
|
959
991
|
defaultViewport: resolvedDefaultViewport,
|
|
960
992
|
fitView: bounds ? false : fitView,
|
|
961
|
-
translateExtent,
|
|
993
|
+
translateExtent: activeExtent,
|
|
962
994
|
onNodeClick,
|
|
963
995
|
onNodeDoubleClick,
|
|
964
996
|
onNodeContextMenu,
|
|
@@ -979,16 +1011,16 @@ function FlowRenderer({
|
|
|
979
1011
|
maxZoom: maxZoomProp,
|
|
980
1012
|
proOptions: { hideAttribution: true }
|
|
981
1013
|
},
|
|
982
|
-
mergedCSS && /* @__PURE__ */
|
|
983
|
-
background && /* @__PURE__ */
|
|
984
|
-
controls && /* @__PURE__ */
|
|
985
|
-
minimap && /* @__PURE__ */
|
|
1014
|
+
mergedCSS && /* @__PURE__ */ React5.createElement("style", { dangerouslySetInnerHTML: { __html: mergedCSS } }),
|
|
1015
|
+
background && /* @__PURE__ */ React5.createElement(Background, null),
|
|
1016
|
+
controls && /* @__PURE__ */ React5.createElement(Controls, null),
|
|
1017
|
+
minimap && /* @__PURE__ */ React5.createElement(
|
|
986
1018
|
MiniMap,
|
|
987
1019
|
{
|
|
988
1020
|
nodeColor: minimapNodeColor
|
|
989
1021
|
}
|
|
990
1022
|
),
|
|
991
|
-
bounds && /* @__PURE__ */
|
|
1023
|
+
bounds && /* @__PURE__ */ React5.createElement(
|
|
992
1024
|
FocusHandler,
|
|
993
1025
|
{
|
|
994
1026
|
bounds,
|
|
@@ -998,7 +1030,8 @@ function FlowRenderer({
|
|
|
998
1030
|
responsive: responsiveFit != null ? responsiveFit : true,
|
|
999
1031
|
extent: translateExtent,
|
|
1000
1032
|
clampBounds,
|
|
1001
|
-
minZoomProp
|
|
1033
|
+
minZoomProp,
|
|
1034
|
+
onInitialFit: handleInitialFit
|
|
1002
1035
|
}
|
|
1003
1036
|
),
|
|
1004
1037
|
children
|