@almadar/ui 2.31.0 → 2.33.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/avl/index.cjs +1049 -1086
  2. package/dist/avl/index.d.cts +352 -78
  3. package/dist/avl/index.d.ts +18 -3
  4. package/dist/avl/index.js +1029 -1086
  5. package/dist/components/atoms/index.d.ts +0 -1
  6. package/dist/components/index.cjs +1146 -1847
  7. package/dist/components/index.js +266 -952
  8. package/dist/components/molecules/avl/AvlBackwardEdge.d.ts +8 -0
  9. package/dist/components/molecules/avl/AvlBindingEdge.d.ts +9 -0
  10. package/dist/components/molecules/avl/AvlEventWireEdge.d.ts +14 -0
  11. package/dist/components/molecules/avl/AvlOrbitalNode.d.ts +12 -0
  12. package/dist/components/molecules/avl/AvlPageEdge.d.ts +8 -0
  13. package/dist/components/molecules/avl/AvlTransitionEdge.d.ts +16 -0
  14. package/dist/components/molecules/avl/BehaviorView.d.ts +12 -0
  15. package/dist/components/molecules/avl/DetailView.d.ts +13 -0
  16. package/dist/components/molecules/avl/MiniStateMachine.d.ts +14 -0
  17. package/dist/components/molecules/avl/ModuleCard.d.ts +14 -0
  18. package/dist/components/molecules/avl/SystemNode.d.ts +12 -0
  19. package/dist/components/molecules/avl/avl-canvas-types.d.ts +36 -0
  20. package/dist/components/molecules/avl/avl-elk-layout.d.ts +55 -0
  21. package/dist/components/molecules/avl/avl-flow-converter.d.ts +17 -0
  22. package/dist/components/molecules/avl/avl-story-schemas.d.ts +34 -0
  23. package/dist/components/molecules/avl/avl-zoom-band.d.ts +19 -0
  24. package/dist/components/molecules/avl/index.d.ts +15 -0
  25. package/dist/components/molecules/index.d.ts +0 -1
  26. package/dist/components/organisms/avl/AvlCosmicZoom.d.ts +10 -7
  27. package/dist/components/organisms/avl/FlowCanvas.d.ts +32 -0
  28. package/dist/components/organisms/avl/ZoomBreadcrumb.d.ts +16 -0
  29. package/dist/components/organisms/avl/ZoomLegend.d.ts +10 -0
  30. package/dist/components/organisms/avl/index.d.ts +5 -2
  31. package/dist/hooks/useUISlots.d.ts +2 -0
  32. package/dist/providers/index.cjs +148 -149
  33. package/dist/providers/index.js +39 -40
  34. package/dist/runtime/index.cjs +1045 -1020
  35. package/dist/runtime/index.js +260 -235
  36. package/package.json +2 -6
  37. package/dist/components/atoms/flow/FlowLabel.d.ts +0 -23
  38. package/dist/components/atoms/flow/FlowMinimap.d.ts +0 -28
  39. package/dist/components/atoms/flow/FlowNodeShell.d.ts +0 -25
  40. package/dist/components/atoms/flow/FlowPort.d.ts +0 -26
  41. package/dist/components/atoms/flow/FlowWire.d.ts +0 -39
  42. package/dist/components/atoms/flow/index.d.ts +0 -13
  43. package/dist/components/molecules/flow/BehaviorNode.d.ts +0 -28
  44. package/dist/components/molecules/flow/EffectNode.d.ts +0 -26
  45. package/dist/components/molecules/flow/EventWireEdge.d.ts +0 -23
  46. package/dist/components/molecules/flow/ExprNode.d.ts +0 -27
  47. package/dist/components/molecules/flow/FlowStateNode.d.ts +0 -18
  48. package/dist/components/molecules/flow/NodePalette.d.ts +0 -36
  49. package/dist/components/molecules/flow/OrbitalNode.d.ts +0 -31
  50. package/dist/components/molecules/flow/TransitionEdge.d.ts +0 -26
  51. package/dist/components/molecules/flow/index.d.ts +0 -8
  52. package/dist/components/molecules/svg/AIGenerates.d.ts +0 -7
  53. package/dist/components/molecules/svg/ClosedCircuit.d.ts +0 -7
  54. package/dist/components/molecules/svg/CommunityOwnership.d.ts +0 -7
  55. package/dist/components/molecules/svg/CompileAnywhere.d.ts +0 -7
  56. package/dist/components/molecules/svg/ComposableModels.d.ts +0 -7
  57. package/dist/components/molecules/svg/DescribeProveDeploy.d.ts +0 -7
  58. package/dist/components/molecules/svg/DomainGrid.d.ts +0 -7
  59. package/dist/components/molecules/svg/EventBus.d.ts +0 -7
  60. package/dist/components/molecules/svg/OrbitalUnit.d.ts +0 -7
  61. package/dist/components/molecules/svg/PlanVerifyRemember.d.ts +0 -7
  62. package/dist/components/molecules/svg/ProveCorrect.d.ts +0 -7
  63. package/dist/components/molecules/svg/ServiceLayers.d.ts +0 -7
  64. package/dist/components/molecules/svg/SharedReality.d.ts +0 -7
  65. package/dist/components/molecules/svg/StandardLibrary.d.ts +0 -7
  66. package/dist/components/molecules/svg/StateMachine.d.ts +0 -7
  67. package/dist/components/molecules/svg/WorldModel.d.ts +0 -7
  68. package/dist/components/molecules/svg/index.d.ts +0 -16
  69. package/dist/components/organisms/avl/AvlApplicationScene.d.ts +0 -17
  70. package/dist/components/organisms/avl/AvlOrbitalScene.d.ts +0 -21
  71. package/dist/flow/index.cjs +0 -3832
  72. package/dist/flow/index.d.cts +0 -367
  73. package/dist/flow/index.d.ts +0 -10
  74. package/dist/flow/index.js +0 -3793
  75. package/dist/illustrations/index.cjs +0 -7651
  76. package/dist/illustrations/index.d.cts +0 -544
  77. package/dist/illustrations/index.d.ts +0 -59
  78. package/dist/illustrations/index.js +0 -7594
@@ -3,9 +3,10 @@
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var React8 = require('react');
5
5
  require('@react-three/drei');
6
+ var ELK = require('elkjs/lib/elk.bundled.js');
7
+ var react = require('@xyflow/react');
6
8
  require('@react-three/fiber');
7
9
  require('three');
8
- var ELK = require('elkjs/lib/elk.bundled.js');
9
10
 
10
11
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
12
 
@@ -692,7 +693,7 @@ var AvlEffect = ({
692
693
  className,
693
694
  showBackground = false
694
695
  }) => {
695
- const category = EFFECT_TYPE_TO_CATEGORY[effectType];
696
+ const category = EFFECT_TYPE_TO_CATEGORY[effectType] ?? "control";
696
697
  const catColors = EFFECT_CATEGORY_COLORS[category];
697
698
  const iconColor = showBackground ? catColors.color : color;
698
699
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { className, opacity, children: [
@@ -3603,113 +3604,6 @@ var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
3603
3604
  function cn(...inputs) {
3604
3605
  return twMerge(clsx(inputs));
3605
3606
  }
3606
- var variantStyles = {
3607
- h1: "text-4xl font-bold tracking-tight text-foreground",
3608
- h2: "text-3xl font-bold tracking-tight text-foreground",
3609
- h3: "text-2xl font-bold text-foreground",
3610
- h4: "text-xl font-bold text-foreground",
3611
- h5: "text-lg font-bold text-foreground",
3612
- h6: "text-base font-bold text-foreground",
3613
- heading: "text-2xl font-bold text-foreground",
3614
- subheading: "text-lg font-semibold text-foreground",
3615
- body1: "text-base font-normal text-foreground",
3616
- body2: "text-sm font-normal text-foreground",
3617
- body: "text-base font-normal text-foreground",
3618
- caption: "text-xs font-normal text-muted-foreground",
3619
- overline: "text-xs uppercase tracking-wide font-bold text-muted-foreground",
3620
- small: "text-sm font-normal text-foreground",
3621
- large: "text-lg font-medium text-foreground",
3622
- label: "text-sm font-medium text-foreground"
3623
- };
3624
- var colorStyles = {
3625
- primary: "text-foreground",
3626
- secondary: "text-muted-foreground",
3627
- muted: "text-muted-foreground",
3628
- error: "text-error",
3629
- success: "text-success",
3630
- warning: "text-warning",
3631
- inherit: "text-inherit"
3632
- };
3633
- var weightStyles = {
3634
- light: "font-light",
3635
- normal: "font-normal",
3636
- medium: "font-medium",
3637
- semibold: "font-semibold",
3638
- bold: "font-bold"
3639
- };
3640
- var defaultElements = {
3641
- h1: "h1",
3642
- h2: "h2",
3643
- h3: "h3",
3644
- h4: "h4",
3645
- h5: "h5",
3646
- h6: "h6",
3647
- heading: "h2",
3648
- subheading: "h3",
3649
- body1: "p",
3650
- body2: "p",
3651
- body: "p",
3652
- caption: "span",
3653
- overline: "span",
3654
- small: "span",
3655
- large: "p",
3656
- label: "span"
3657
- };
3658
- var typographySizeStyles = {
3659
- xs: "text-xs",
3660
- sm: "text-sm",
3661
- md: "text-base",
3662
- lg: "text-lg",
3663
- xl: "text-xl",
3664
- "2xl": "text-2xl",
3665
- "3xl": "text-3xl"
3666
- };
3667
- var overflowStyles = {
3668
- visible: "overflow-visible",
3669
- hidden: "overflow-hidden",
3670
- wrap: "break-words overflow-hidden",
3671
- "clamp-2": "overflow-hidden line-clamp-2",
3672
- "clamp-3": "overflow-hidden line-clamp-3"
3673
- };
3674
- var Typography = ({
3675
- variant: variantProp,
3676
- level,
3677
- color = "primary",
3678
- align,
3679
- weight,
3680
- size,
3681
- truncate = false,
3682
- overflow,
3683
- as,
3684
- id,
3685
- className,
3686
- style,
3687
- content,
3688
- children
3689
- }) => {
3690
- const variant = variantProp ?? (level ? `h${level}` : "body1");
3691
- const Component = as || defaultElements[variant];
3692
- const Comp = Component;
3693
- return /* @__PURE__ */ jsxRuntime.jsx(
3694
- Comp,
3695
- {
3696
- id,
3697
- className: cn(
3698
- variantStyles[variant],
3699
- colorStyles[color],
3700
- weight && weightStyles[weight],
3701
- size && typographySizeStyles[size],
3702
- align && `text-${align}`,
3703
- truncate && "truncate overflow-hidden text-ellipsis",
3704
- overflow && overflowStyles[overflow],
3705
- className
3706
- ),
3707
- style,
3708
- children: children ?? content
3709
- }
3710
- );
3711
- };
3712
- Typography.displayName = "Typography";
3713
3607
  var EventBusContext = React8.createContext(null);
3714
3608
 
3715
3609
  // hooks/useEventBus.ts
@@ -3979,83 +3873,6 @@ var Box = React8__default.default.forwardRef(
3979
3873
  }
3980
3874
  );
3981
3875
  Box.displayName = "Box";
3982
- var gapStyles = {
3983
- none: "gap-0",
3984
- xs: "gap-1",
3985
- sm: "gap-2",
3986
- md: "gap-4",
3987
- lg: "gap-6",
3988
- xl: "gap-8",
3989
- "2xl": "gap-12"
3990
- };
3991
- var alignStyles = {
3992
- start: "items-start",
3993
- center: "items-center",
3994
- end: "items-end",
3995
- stretch: "items-stretch",
3996
- baseline: "items-baseline"
3997
- };
3998
- var justifyStyles = {
3999
- start: "justify-start",
4000
- center: "justify-center",
4001
- end: "justify-end",
4002
- between: "justify-between",
4003
- around: "justify-around",
4004
- evenly: "justify-evenly"
4005
- };
4006
- var Stack = ({
4007
- direction = "vertical",
4008
- gap = "md",
4009
- align = "stretch",
4010
- justify = "start",
4011
- wrap = false,
4012
- reverse = false,
4013
- flex = false,
4014
- className,
4015
- style,
4016
- children,
4017
- as: Component = "div",
4018
- onClick,
4019
- onKeyDown,
4020
- role,
4021
- tabIndex,
4022
- action,
4023
- actionPayload,
4024
- responsive = false
4025
- }) => {
4026
- const eventBus = useEventBus();
4027
- const handleClick = (e) => {
4028
- if (action) {
4029
- eventBus.emit(`UI:${action}`, actionPayload ?? {});
4030
- }
4031
- onClick?.(e);
4032
- };
4033
- const isHorizontal = direction === "horizontal";
4034
- const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
4035
- const Comp = Component;
4036
- return /* @__PURE__ */ jsxRuntime.jsx(
4037
- Comp,
4038
- {
4039
- className: cn(
4040
- "flex",
4041
- directionClass,
4042
- gapStyles[gap],
4043
- alignStyles[align],
4044
- justifyStyles[justify],
4045
- wrap && "flex-wrap",
4046
- flex && "flex-1",
4047
- className
4048
- ),
4049
- style,
4050
- onClick: action || onClick ? handleClick : void 0,
4051
- onKeyDown,
4052
- role,
4053
- tabIndex,
4054
- children
4055
- }
4056
- );
4057
- };
4058
- var HStack = (props) => /* @__PURE__ */ jsxRuntime.jsx(Stack, { direction: "horizontal", ...props });
4059
3876
 
4060
3877
  // components/molecules/avl/avl-layout.ts
4061
3878
  function ringPositions(cx, cy, r2, count, startAngle = -Math.PI / 2) {
@@ -5607,6 +5424,31 @@ var AvlBehaviorGlyph = ({
5607
5424
  };
5608
5425
  AvlBehaviorGlyph.displayName = "AvlBehaviorGlyph";
5609
5426
 
5427
+ // components/molecules/avl/avl-canvas-types.ts
5428
+ var ZOOM_BAND_THRESHOLDS = {
5429
+ system: [0.1, 0.4],
5430
+ module: [0.4, 1],
5431
+ behavior: [1, 2.5],
5432
+ detail: [2.5, 5]
5433
+ };
5434
+ function computeZoomBand(zoom) {
5435
+ if (zoom < ZOOM_BAND_THRESHOLDS.module[0]) return "system";
5436
+ if (zoom < ZOOM_BAND_THRESHOLDS.behavior[0]) return "module";
5437
+ if (zoom < ZOOM_BAND_THRESHOLDS.detail[0]) return "behavior";
5438
+ return "detail";
5439
+ }
5440
+ function zoomProgress(zoom, band) {
5441
+ const [min, max] = ZOOM_BAND_THRESHOLDS[band];
5442
+ const clamped = Math.max(min, Math.min(max, zoom));
5443
+ const range = max - min;
5444
+ if (range === 0) return 1;
5445
+ return (clamped - min) / range;
5446
+ }
5447
+ var ZoomBandContext = React8.createContext("module");
5448
+ function useZoomBand() {
5449
+ return React8.useContext(ZoomBandContext);
5450
+ }
5451
+
5610
5452
  // components/organisms/avl/avl-schema-parser.ts
5611
5453
  function getEntity(orbital) {
5612
5454
  const entity = orbital.entity;
@@ -5858,508 +5700,57 @@ function parseTransitionLevel(schema, orbitalName, traitName, transitionIndex) {
5858
5700
  };
5859
5701
  }
5860
5702
 
5861
- // components/organisms/avl/avl-zoom-state.ts
5862
- var initialZoomState = {
5863
- level: "application",
5864
- selectedOrbital: null,
5865
- selectedTrait: null,
5866
- selectedTransition: null,
5867
- animating: false,
5868
- animationDirection: "in",
5869
- animationTarget: null
5870
- };
5871
- function zoomReducer(state, action) {
5872
- switch (action.type) {
5873
- case "ZOOM_INTO_ORBITAL": {
5874
- if (state.level !== "application" || state.animating) return state;
5875
- return {
5876
- ...state,
5877
- animating: true,
5878
- animationDirection: "in",
5879
- animationTarget: { x: action.targetPosition.x, y: action.targetPosition.y, scale: 3 },
5880
- selectedOrbital: action.orbital
5881
- };
5882
- }
5883
- case "ZOOM_INTO_TRAIT": {
5884
- if (state.level !== "orbital" || state.animating) return state;
5885
- return {
5886
- ...state,
5887
- animating: true,
5888
- animationDirection: "in",
5889
- animationTarget: { x: action.targetPosition.x, y: action.targetPosition.y, scale: 3 },
5890
- selectedTrait: action.trait
5891
- };
5892
- }
5893
- case "ZOOM_INTO_TRANSITION": {
5894
- if (state.level !== "trait" || state.animating) return state;
5895
- return {
5896
- ...state,
5897
- animating: true,
5898
- animationDirection: "in",
5899
- animationTarget: { x: action.targetPosition.x, y: action.targetPosition.y, scale: 3 },
5900
- selectedTransition: action.transitionIndex
5901
- };
5902
- }
5903
- case "ZOOM_OUT": {
5904
- if (state.level === "application" || state.animating) return state;
5905
- return {
5906
- ...state,
5907
- animating: true,
5908
- animationDirection: "out",
5909
- animationTarget: { x: 300, y: 200, scale: 0.3 }
5910
- };
5703
+ // components/molecules/avl/avl-flow-converter.ts
5704
+ var NODE_SPACING = 350;
5705
+ function schemaToFlowGraph(schema) {
5706
+ const appData = parseApplicationLevel(schema);
5707
+ const nodes = [];
5708
+ const edges = [];
5709
+ const count = appData.orbitals.length;
5710
+ const cols = Math.ceil(Math.sqrt(count));
5711
+ for (let i = 0; i < appData.orbitals.length; i++) {
5712
+ const orb = appData.orbitals[i];
5713
+ const orbitalDetail = parseOrbitalLevel(schema, orb.name);
5714
+ if (!orbitalDetail) continue;
5715
+ const traitDetails = {};
5716
+ for (const traitName of orb.traitNames) {
5717
+ const td = parseTraitLevel(schema, orb.name, traitName);
5718
+ if (td) traitDetails[traitName] = td;
5911
5719
  }
5912
- case "ANIMATION_COMPLETE": {
5913
- if (!state.animating) return state;
5914
- if (state.animationDirection === "in") {
5915
- const nextLevel = state.level === "application" ? "orbital" : state.level === "orbital" ? "trait" : "transition";
5916
- return {
5917
- ...state,
5918
- level: nextLevel,
5919
- animating: false,
5920
- animationTarget: null
5921
- };
5922
- }
5923
- if (state.level === "transition") {
5924
- return {
5925
- ...state,
5926
- level: "trait",
5927
- selectedTransition: null,
5928
- animating: false,
5929
- animationTarget: null
5930
- };
5931
- }
5932
- if (state.level === "trait") {
5933
- return {
5934
- ...state,
5935
- level: "orbital",
5936
- selectedTrait: null,
5937
- animating: false,
5938
- animationTarget: null
5939
- };
5940
- }
5941
- if (state.level === "orbital") {
5942
- return {
5943
- ...state,
5944
- level: "application",
5945
- selectedOrbital: null,
5946
- animating: false,
5947
- animationTarget: null
5948
- };
5720
+ const col = i % cols;
5721
+ const row = Math.floor(i / cols);
5722
+ nodes.push({
5723
+ id: orb.name,
5724
+ type: "orbital",
5725
+ position: { x: col * NODE_SPACING, y: row * NODE_SPACING },
5726
+ data: {
5727
+ orbitalName: orb.name,
5728
+ entityName: orb.entityName,
5729
+ persistence: orb.persistence,
5730
+ fields: orbitalDetail.entity.fields,
5731
+ traits: orbitalDetail.traits,
5732
+ pages: orbitalDetail.pages,
5733
+ traitDetails,
5734
+ externalLinks: orbitalDetail.externalLinks
5949
5735
  }
5950
- return state;
5951
- }
5952
- case "SWITCH_TRAIT": {
5953
- if (state.level !== "trait" || state.animating) return state;
5954
- return {
5955
- ...state,
5956
- selectedTrait: action.trait,
5957
- selectedTransition: null
5958
- };
5959
- }
5960
- case "RESET": {
5961
- return initialZoomState;
5962
- }
5963
- default:
5964
- return state;
5965
- }
5966
- }
5967
- function getBreadcrumbs(state) {
5968
- const crumbs = [{ label: "Application", level: "application" }];
5969
- if (state.selectedOrbital) {
5970
- crumbs.push({ label: state.selectedOrbital, level: "orbital" });
5971
- }
5972
- if (state.selectedTrait) {
5973
- crumbs.push({ label: state.selectedTrait, level: "trait" });
5974
- }
5975
- if (state.selectedTransition !== null) {
5976
- crumbs.push({ label: `Transition #${state.selectedTransition}`, level: "transition" });
5736
+ });
5977
5737
  }
5978
- return crumbs;
5979
- }
5980
- var AvlClickTarget = ({
5981
- x,
5982
- y,
5983
- width,
5984
- height,
5985
- onClick,
5986
- onHover,
5987
- cursor = "pointer",
5988
- glowColor = "var(--color-primary)",
5989
- label,
5990
- children
5991
- }) => {
5992
- const [hovering, setHovering] = React8.useState(false);
5993
- const handleMouseEnter = React8.useCallback(() => {
5994
- setHovering(true);
5995
- onHover?.(true);
5996
- }, [onHover]);
5997
- const handleMouseLeave = React8.useCallback(() => {
5998
- setHovering(false);
5999
- onHover?.(false);
6000
- }, [onHover]);
6001
- const handleKeyDown = React8.useCallback((e) => {
6002
- if (e.key === "Enter" || e.key === " ") {
6003
- e.preventDefault();
6004
- onClick();
6005
- }
6006
- }, [onClick]);
6007
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6008
- hovering && /* @__PURE__ */ jsxRuntime.jsx(
6009
- "rect",
6010
- {
6011
- x: x - 4,
6012
- y: y - 4,
6013
- width: width + 8,
6014
- height: height + 8,
6015
- rx: 8,
6016
- fill: glowColor,
6017
- opacity: 0.08
6018
- }
6019
- ),
6020
- children,
6021
- /* @__PURE__ */ jsxRuntime.jsx(
6022
- "rect",
6023
- {
6024
- x,
6025
- y,
6026
- width,
6027
- height,
6028
- fill: "transparent",
6029
- style: { cursor },
6030
- pointerEvents: "all",
6031
- onClick,
6032
- onMouseEnter: handleMouseEnter,
6033
- onMouseLeave: handleMouseLeave,
6034
- onKeyDown: handleKeyDown,
6035
- tabIndex: 0,
6036
- role: "button",
6037
- "aria-label": label
5738
+ for (const link of appData.crossLinks) {
5739
+ edges.push({
5740
+ id: `ew-${link.emitterOrbital}-${link.listenerOrbital}-${link.eventName}`,
5741
+ source: link.emitterOrbital,
5742
+ target: link.listenerOrbital,
5743
+ type: "eventWire",
5744
+ data: {
5745
+ edgeKind: "eventWire",
5746
+ event: link.eventName,
5747
+ fromTrait: link.emitterTrait,
5748
+ toTrait: link.listenerTrait
6038
5749
  }
6039
- )
6040
- ] });
6041
- };
6042
- AvlClickTarget.displayName = "AvlClickTarget";
6043
- var ORBITAL_R = 60;
6044
- var ENTITY_R = 14;
6045
- function bundleCrossLinks(links) {
6046
- const bundles = /* @__PURE__ */ new Map();
6047
- for (const link of links) {
6048
- const key = [link.emitterOrbital, link.listenerOrbital].sort().join("::");
6049
- if (!bundles.has(key)) bundles.set(key, []);
6050
- bundles.get(key).push(link);
5750
+ });
6051
5751
  }
6052
- return bundles;
5752
+ return { nodes, edges };
6053
5753
  }
6054
- var AvlApplicationScene = ({
6055
- data,
6056
- color = "var(--color-primary)",
6057
- onOrbitalClick
6058
- }) => {
6059
- const posMap = /* @__PURE__ */ new Map();
6060
- data.orbitals.forEach((o) => posMap.set(o.name, o.position));
6061
- const bundles = bundleCrossLinks(data.crossLinks);
6062
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6063
- Array.from(bundles.entries()).map(([key, links]) => {
6064
- const first = links[0];
6065
- const fromPos = posMap.get(first.emitterOrbital);
6066
- const toPos = posMap.get(first.listenerOrbital);
6067
- if (!fromPos || !toPos) return null;
6068
- const cp = curveControlPoint(fromPos.x, fromPos.y, toPos.x, toPos.y, 40);
6069
- const midX = cp.cpx;
6070
- const midY = cp.cpy;
6071
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { opacity: 0.5, children: [
6072
- /* @__PURE__ */ jsxRuntime.jsx(
6073
- "path",
6074
- {
6075
- d: `M${fromPos.x},${fromPos.y} Q${midX},${midY} ${toPos.x},${toPos.y}`,
6076
- fill: "none",
6077
- stroke: color,
6078
- strokeWidth: 1.5,
6079
- strokeDasharray: "6 3",
6080
- markerEnd: "url(#cosmicArrow)"
6081
- }
6082
- ),
6083
- links.map((link, i) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6084
- /* @__PURE__ */ jsxRuntime.jsx(
6085
- AvlEffect,
6086
- {
6087
- x: midX - 12,
6088
- y: midY - 10 + i * 16,
6089
- effectType: "emit",
6090
- size: 8,
6091
- color
6092
- }
6093
- ),
6094
- /* @__PURE__ */ jsxRuntime.jsx(
6095
- "text",
6096
- {
6097
- x: midX + 2,
6098
- y: midY - 6 + i * 16,
6099
- fill: color,
6100
- fontSize: 7,
6101
- opacity: 0.7,
6102
- children: link.eventName
6103
- }
6104
- )
6105
- ] }, `${key}-${i}`))
6106
- ] }, key);
6107
- }),
6108
- data.orbitals.map((orbital) => {
6109
- const { x, y } = orbital.position;
6110
- const traitAngleStart = -60;
6111
- const traitAngleStep = orbital.traitNames.length > 1 ? 120 / (orbital.traitNames.length - 1) : 0;
6112
- const pageAngleStart = -Math.PI / 3;
6113
- const pageAngleStep = orbital.pageNames.length > 1 ? Math.PI * 0.8 / (orbital.pageNames.length - 1) : 0;
6114
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6115
- /* @__PURE__ */ jsxRuntime.jsx(AvlOrbital, { cx: x, cy: y, r: ORBITAL_R, label: orbital.name, color }),
6116
- orbital.traitNames.map((trait, i) => /* @__PURE__ */ jsxRuntime.jsx(
6117
- AvlTrait,
6118
- {
6119
- cx: x,
6120
- cy: y,
6121
- rx: 25 + i * 10,
6122
- ry: 12 + i * 4,
6123
- rotation: traitAngleStart + i * traitAngleStep,
6124
- color,
6125
- opacity: 0.4
6126
- },
6127
- trait
6128
- )),
6129
- /* @__PURE__ */ jsxRuntime.jsx(
6130
- AvlEntity,
6131
- {
6132
- x,
6133
- y,
6134
- r: ENTITY_R,
6135
- fieldCount: orbital.fieldCount,
6136
- persistence: orbital.persistence,
6137
- color
6138
- }
6139
- ),
6140
- orbital.pageNames.map((page, i) => {
6141
- const angle = pageAngleStart + i * pageAngleStep;
6142
- const px = x + (ORBITAL_R + 12) * Math.cos(angle);
6143
- const py = y + (ORBITAL_R + 12) * Math.sin(angle);
6144
- return /* @__PURE__ */ jsxRuntime.jsx(AvlPage, { x: px, y: py, size: 6, label: page, color }, page);
6145
- }),
6146
- onOrbitalClick && /* @__PURE__ */ jsxRuntime.jsx(
6147
- AvlClickTarget,
6148
- {
6149
- x: x - ORBITAL_R,
6150
- y: y - ORBITAL_R,
6151
- width: ORBITAL_R * 2,
6152
- height: ORBITAL_R * 2,
6153
- onClick: () => onOrbitalClick(orbital.name, { x, y }),
6154
- label: `Orbital: ${orbital.name} (${orbital.traitNames.length} traits, ${orbital.pageNames.length} pages)`,
6155
- glowColor: color,
6156
- children: /* @__PURE__ */ jsxRuntime.jsx("rect", { x: 0, y: 0, width: 0, height: 0, fill: "transparent" })
6157
- }
6158
- )
6159
- ] }, orbital.name);
6160
- }),
6161
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("marker", { id: "cosmicArrow", viewBox: "0 0 10 10", refX: "8", refY: "5", markerWidth: "6", markerHeight: "6", orient: "auto-start-reverse", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M 0 0 L 10 5 L 0 10 z", fill: color, opacity: 0.5 }) }) })
6162
- ] });
6163
- };
6164
- AvlApplicationScene.displayName = "AvlApplicationScene";
6165
- var CX = 300;
6166
- var CY = 200;
6167
- var VIEWBOX_H = 400;
6168
- var ORBITAL_R2 = 130;
6169
- var ENTITY_R2 = 24;
6170
- var AvlOrbitalScene = ({
6171
- data,
6172
- color = "var(--color-primary)",
6173
- highlightedTrait,
6174
- onTraitClick,
6175
- onTraitHighlight
6176
- }) => {
6177
- const traitAngleStart = -Math.PI / 3;
6178
- const traitAngleStep = data.traits.length > 1 ? Math.PI * 1.2 / (data.traits.length - 1) : 0;
6179
- const pageAngleStart = -Math.PI / 3;
6180
- const pageAngleStep = data.pages.length > 1 ? Math.PI * 0.8 / (data.pages.length - 1) : 0;
6181
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6182
- /* @__PURE__ */ jsxRuntime.jsx(AvlOrbital, { cx: CX, cy: CY, r: ORBITAL_R2, label: data.name, color }),
6183
- data.traits.map((trait, i) => {
6184
- const rotation = traitAngleStart + i * traitAngleStep;
6185
- const rotationDeg = rotation * 180 / Math.PI;
6186
- const baseRx = 55 + i * 20;
6187
- const baseRy = 24 + i * 8;
6188
- const labelX = CX - baseRx - 10;
6189
- const labelY = CY;
6190
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6191
- /* @__PURE__ */ jsxRuntime.jsx(
6192
- AvlTrait,
6193
- {
6194
- cx: CX,
6195
- cy: CY,
6196
- rx: baseRx,
6197
- ry: baseRy,
6198
- rotation: rotationDeg,
6199
- label: trait.name,
6200
- color,
6201
- opacity: highlightedTrait ? highlightedTrait === trait.name ? 1 : 0.25 : 0.7
6202
- }
6203
- ),
6204
- onTraitClick && /* @__PURE__ */ jsxRuntime.jsx(
6205
- AvlClickTarget,
6206
- {
6207
- x: CX - baseRx,
6208
- y: CY - baseRy,
6209
- width: baseRx * 2,
6210
- height: baseRy * 2,
6211
- onClick: () => onTraitClick(trait.name, { x: CX, y: CY }),
6212
- label: `Trait: ${trait.name} (${trait.stateCount} states)`,
6213
- glowColor: color,
6214
- children: /* @__PURE__ */ jsxRuntime.jsx("rect", { x: 0, y: 0, width: 0, height: 0, fill: "transparent" })
6215
- }
6216
- ),
6217
- /* @__PURE__ */ jsxRuntime.jsxs(
6218
- "text",
6219
- {
6220
- x: labelX - 20,
6221
- y: labelY + 12,
6222
- textAnchor: "end",
6223
- fill: color,
6224
- fontSize: 7,
6225
- opacity: 0.4,
6226
- transform: `rotate(${-rotationDeg},${labelX - 20},${labelY + 12})`,
6227
- children: [
6228
- trait.stateCount,
6229
- "s ",
6230
- trait.eventCount,
6231
- "e"
6232
- ]
6233
- }
6234
- )
6235
- ] }, trait.name);
6236
- }),
6237
- /* @__PURE__ */ jsxRuntime.jsx(
6238
- AvlEntity,
6239
- {
6240
- x: CX,
6241
- y: CY,
6242
- r: ENTITY_R2,
6243
- fieldCount: data.entity.fields.length,
6244
- persistence: data.entity.persistence,
6245
- color
6246
- }
6247
- ),
6248
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: CX, y: CY + ENTITY_R2 + 16, textAnchor: "middle", fill: color, fontSize: 10, fontWeight: "bold", children: data.entity.name }),
6249
- data.entity.fields.slice(0, 8).map((field, i) => {
6250
- const angle = -Math.PI / 2 + Math.PI * 2 * i / Math.min(data.entity.fields.length, 8);
6251
- const fx = CX + (ENTITY_R2 + 30) * Math.cos(angle);
6252
- const fy = CY + (ENTITY_R2 + 30) * Math.sin(angle);
6253
- return /* @__PURE__ */ jsxRuntime.jsx(
6254
- "text",
6255
- {
6256
- x: fx,
6257
- y: fy,
6258
- textAnchor: "middle",
6259
- dominantBaseline: "central",
6260
- fill: color,
6261
- fontSize: 7,
6262
- opacity: 0.5,
6263
- children: field.name
6264
- },
6265
- field.name
6266
- );
6267
- }),
6268
- data.pages.map((page, i) => {
6269
- const angle = pageAngleStart + i * pageAngleStep;
6270
- const px = CX + (ORBITAL_R2 + 15) * Math.cos(angle);
6271
- const py = CY + (ORBITAL_R2 + 15) * Math.sin(angle);
6272
- return /* @__PURE__ */ jsxRuntime.jsx(AvlPage, { x: px, y: py, label: page.route, color }, page.name);
6273
- }),
6274
- data.traits.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("g", { children: data.traits.map((trait, i) => {
6275
- const pillW = 70;
6276
- const gap = 8;
6277
- const totalW = data.traits.length * pillW + (data.traits.length - 1) * gap;
6278
- const startX = CX - totalW / 2;
6279
- const px = startX + i * (pillW + gap);
6280
- const py = VIEWBOX_H - 30;
6281
- const isHighlighted = highlightedTrait === trait.name;
6282
- return /* @__PURE__ */ jsxRuntime.jsxs(
6283
- "g",
6284
- {
6285
- style: { cursor: "pointer" },
6286
- onClick: () => onTraitClick?.(trait.name, { x: CX, y: CY }),
6287
- onMouseEnter: () => onTraitHighlight?.(trait.name),
6288
- onMouseLeave: () => onTraitHighlight?.(null),
6289
- children: [
6290
- /* @__PURE__ */ jsxRuntime.jsx(
6291
- "rect",
6292
- {
6293
- x: px,
6294
- y: py,
6295
- width: pillW,
6296
- height: 22,
6297
- rx: 11,
6298
- fill: isHighlighted ? color : "transparent",
6299
- stroke: color,
6300
- strokeWidth: isHighlighted ? 1.5 : 0.8,
6301
- opacity: isHighlighted ? 0.15 : 0.3
6302
- }
6303
- ),
6304
- /* @__PURE__ */ jsxRuntime.jsx(
6305
- "text",
6306
- {
6307
- x: px + pillW / 2,
6308
- y: py + 14,
6309
- textAnchor: "middle",
6310
- fill: color,
6311
- fontSize: 8,
6312
- fontWeight: isHighlighted ? "bold" : "normal",
6313
- opacity: isHighlighted ? 1 : 0.6,
6314
- children: trait.name.length > 10 ? trait.name.slice(0, 9) + "\u2026" : trait.name
6315
- }
6316
- )
6317
- ]
6318
- },
6319
- `tab-${trait.name}`
6320
- );
6321
- }) }),
6322
- data.externalLinks.map((link, i) => {
6323
- const isOut = link.direction === "out";
6324
- const edgeX = isOut ? 580 : 20;
6325
- const y = 50 + i * 24;
6326
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { opacity: 0.3, children: [
6327
- /* @__PURE__ */ jsxRuntime.jsx(
6328
- "line",
6329
- {
6330
- x1: isOut ? CX + ORBITAL_R2 + 10 : edgeX,
6331
- y1: y,
6332
- x2: isOut ? edgeX : CX - ORBITAL_R2 - 10,
6333
- y2: y,
6334
- stroke: color,
6335
- strokeWidth: 1,
6336
- strokeDasharray: "6 3"
6337
- }
6338
- ),
6339
- /* @__PURE__ */ jsxRuntime.jsxs(
6340
- "text",
6341
- {
6342
- x: isOut ? 585 : 5,
6343
- y: y + 4,
6344
- textAnchor: isOut ? "start" : "start",
6345
- fill: color,
6346
- fontSize: 7,
6347
- opacity: 0.7,
6348
- children: [
6349
- isOut ? "emit" : "listen",
6350
- ": ",
6351
- link.eventName,
6352
- " (",
6353
- link.targetOrbital,
6354
- ")"
6355
- ]
6356
- }
6357
- )
6358
- ] }, `ext-${i}`);
6359
- })
6360
- ] });
6361
- };
6362
- AvlOrbitalScene.displayName = "AvlOrbitalScene";
6363
5754
  function stateWidth(transitionCount) {
6364
5755
  if (transitionCount >= 5) return 160;
6365
5756
  if (transitionCount >= 3) return 130;
@@ -6367,7 +5758,7 @@ function stateWidth(transitionCount) {
6367
5758
  }
6368
5759
  var STATE_H = 40;
6369
5760
  var elk = new ELK__default.default();
6370
- async function computeLayout(data) {
5761
+ async function computeTraitLayout(data) {
6371
5762
  const transitionCounts = {};
6372
5763
  for (const s of data.states) transitionCounts[s.name] = 0;
6373
5764
  for (const t of data.transitions) {
@@ -6490,17 +5881,898 @@ function edgePath(points) {
6490
5881
  for (let i = 1; i < points.length; i++) d += ` L ${points[i].x},${points[i].y}`;
6491
5882
  return d;
6492
5883
  }
6493
- var SWIM_GUTTER = 120;
6494
- var CENTER_W = 360;
6495
- var AvlTraitScene = ({
6496
- data,
6497
- color = "var(--color-primary)",
6498
- onTransitionClick
6499
- }) => {
6500
- const [layout, setLayout] = React8.useState(null);
5884
+ function toFieldKind(type) {
5885
+ const normalized = type.toLowerCase();
5886
+ if (["string", "number", "boolean", "date", "enum", "object", "array"].includes(normalized)) {
5887
+ return normalized;
5888
+ }
5889
+ return "string";
5890
+ }
5891
+ var SystemNode = ({ data }) => {
5892
+ const { orbitalName, fields, traits, pages, persistence } = data;
5893
+ const allStates = traits.flatMap((t) => {
5894
+ const detail = data.traitDetails[t.name];
5895
+ if (!detail) return [];
5896
+ return detail.states;
5897
+ });
5898
+ const fieldDots = fields.slice(0, 8);
5899
+ const stateChain = allStates.slice(0, 6);
5900
+ const pageDots = pages.slice(0, 3);
5901
+ const transitionCounts = {};
5902
+ for (const t of traits) {
5903
+ const detail = data.traitDetails[t.name];
5904
+ if (!detail) continue;
5905
+ for (const s of detail.states) transitionCounts[s.name] = 0;
5906
+ for (const tr of detail.transitions) {
5907
+ transitionCounts[tr.from] = (transitionCounts[tr.from] ?? 0) + 1;
5908
+ transitionCounts[tr.to] = (transitionCounts[tr.to] ?? 0) + 1;
5909
+ }
5910
+ }
5911
+ const maxTC = Math.max(...Object.values(transitionCounts), 0);
5912
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5913
+ "div",
5914
+ {
5915
+ className: "rounded-lg border border-[var(--color-border)] bg-[var(--color-card)] px-3 py-2 shadow-sm",
5916
+ style: { minWidth: 160, maxWidth: 220 },
5917
+ children: [
5918
+ /* @__PURE__ */ jsxRuntime.jsx(react.Handle, { type: "target", position: react.Position.Left, className: "!w-2 !h-2 !bg-orange-400" }),
5919
+ /* @__PURE__ */ jsxRuntime.jsx(react.Handle, { type: "source", position: react.Position.Right, className: "!w-2 !h-2 !bg-orange-400" }),
5920
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 mb-1", children: [
5921
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 14, height: 14, viewBox: "0 0 20 20", children: /* @__PURE__ */ jsxRuntime.jsx(AvlEntity, { x: 10, y: 10, r: 8, persistence }) }),
5922
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] font-semibold text-[var(--color-foreground)] truncate flex-1", children: orbitalName })
5923
+ ] }),
5924
+ fieldDots.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("svg", { width: fieldDots.length * 10 + 2, height: 10, viewBox: `0 0 ${fieldDots.length * 10 + 2} 10`, className: "mb-1", children: fieldDots.map((f, i) => /* @__PURE__ */ jsxRuntime.jsx(AvlFieldType, { x: i * 10 + 5, y: 5, kind: toFieldKind(f.type), size: 4 }, f.name)) }),
5925
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
5926
+ stateChain.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("svg", { width: stateChain.length * 14 + 2, height: 10, viewBox: `0 0 ${stateChain.length * 14 + 2} 10`, children: stateChain.map((s, i) => {
5927
+ const tc = transitionCounts[s.name] ?? 0;
5928
+ const role = getStateRole(s.name, s.isInitial, s.isTerminal, tc, maxTC);
5929
+ return /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
5930
+ /* @__PURE__ */ jsxRuntime.jsx(AvlState, { x: i * 14 + 1, y: 1, width: 10, height: 8, name: "", role, isInitial: s.isInitial, isTerminal: s.isTerminal }),
5931
+ i < stateChain.length - 1 && /* @__PURE__ */ jsxRuntime.jsx("line", { x1: i * 14 + 12, y1: 5, x2: i * 14 + 15, y2: 5, stroke: "var(--color-border)", strokeWidth: 0.5 })
5932
+ ] }, s.name);
5933
+ }) }),
5934
+ pageDots.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("svg", { width: pageDots.length * 10, height: 10, viewBox: `0 0 ${pageDots.length * 10} 10`, children: pageDots.map((p, i) => /* @__PURE__ */ jsxRuntime.jsx(AvlPage, { x: i * 10 + 4, y: 4, size: 5 }, p.name)) })
5935
+ ] })
5936
+ ]
5937
+ }
5938
+ );
5939
+ };
5940
+ SystemNode.displayName = "SystemNode";
5941
+ var NODE_W = 24;
5942
+ var NODE_H = 16;
5943
+ var GAP = 8;
5944
+ var ARROW_W = 16;
5945
+ var MiniStateMachine = ({ data, className }) => {
5946
+ const states = data.states;
5947
+ if (states.length === 0) return null;
5948
+ const transitionCounts = {};
5949
+ for (const s of states) transitionCounts[s.name] = 0;
5950
+ for (const t of data.transitions) {
5951
+ transitionCounts[t.from] = (transitionCounts[t.from] ?? 0) + 1;
5952
+ transitionCounts[t.to] = (transitionCounts[t.to] ?? 0) + 1;
5953
+ }
5954
+ const maxTC = Math.max(...Object.values(transitionCounts), 0);
5955
+ const effectTypes = /* @__PURE__ */ new Set();
5956
+ for (const t of data.transitions) {
5957
+ for (const e of t.effects) effectTypes.add(e.type);
5958
+ }
5959
+ const effectList = Array.from(effectTypes).slice(0, 6);
5960
+ const totalW = states.length * NODE_W + (states.length - 1) * (GAP + ARROW_W + GAP);
5961
+ const svgW = Math.max(totalW + 4, 60);
5962
+ const svgH = NODE_H + (effectList.length > 0 ? 18 : 4);
5963
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: svgW, height: svgH, viewBox: `0 0 ${svgW} ${svgH}`, className, children: [
5964
+ states.map((s, i) => {
5965
+ const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
5966
+ const tc = transitionCounts[s.name] ?? 0;
5967
+ const role = getStateRole(s.name, s.isInitial, s.isTerminal, tc, maxTC);
5968
+ return /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
5969
+ /* @__PURE__ */ jsxRuntime.jsx(
5970
+ AvlState,
5971
+ {
5972
+ x,
5973
+ y: 0,
5974
+ width: NODE_W,
5975
+ height: NODE_H,
5976
+ name: "",
5977
+ role,
5978
+ isInitial: s.isInitial,
5979
+ isTerminal: s.isTerminal
5980
+ }
5981
+ ),
5982
+ i < states.length - 1 && /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
5983
+ /* @__PURE__ */ jsxRuntime.jsx(
5984
+ "line",
5985
+ {
5986
+ x1: x + NODE_W + GAP,
5987
+ y1: NODE_H / 2,
5988
+ x2: x + NODE_W + GAP + ARROW_W - 3,
5989
+ y2: NODE_H / 2,
5990
+ stroke: "var(--color-muted-foreground)",
5991
+ strokeWidth: 1,
5992
+ opacity: 0.4
5993
+ }
5994
+ ),
5995
+ /* @__PURE__ */ jsxRuntime.jsx(
5996
+ "polygon",
5997
+ {
5998
+ points: `${x + NODE_W + GAP + ARROW_W - 3},${NODE_H / 2 - 2.5} ${x + NODE_W + GAP + ARROW_W},${NODE_H / 2} ${x + NODE_W + GAP + ARROW_W - 3},${NODE_H / 2 + 2.5}`,
5999
+ fill: "var(--color-muted-foreground)",
6000
+ opacity: 0.4
6001
+ }
6002
+ )
6003
+ ] })
6004
+ ] }, s.name);
6005
+ }),
6006
+ effectList.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("g", { children: effectList.map((et, i) => /* @__PURE__ */ jsxRuntime.jsx(
6007
+ AvlEffect,
6008
+ {
6009
+ x: 2 + i * 14,
6010
+ y: NODE_H + 4,
6011
+ effectType: et,
6012
+ size: 10,
6013
+ showBackground: true
6014
+ },
6015
+ et
6016
+ )) })
6017
+ ] });
6018
+ };
6019
+ MiniStateMachine.displayName = "MiniStateMachine";
6020
+ function toFieldKind2(type) {
6021
+ const normalized = type.toLowerCase();
6022
+ if (["string", "number", "boolean", "date", "enum", "object", "array"].includes(normalized)) {
6023
+ return normalized;
6024
+ }
6025
+ return "string";
6026
+ }
6027
+ var PERSISTENCE_BORDER = {
6028
+ persistent: "border-l-[3px] border-l-blue-500 border-solid",
6029
+ runtime: "border-l-[3px] border-l-blue-500 border-dashed",
6030
+ singleton: "border-l-[3px] border-l-blue-500 border-double",
6031
+ instance: "border-l-[3px] border-l-blue-500 border-dotted"
6032
+ };
6033
+ var PERSISTENCE_ICON = {
6034
+ persistent: "\u26C1",
6035
+ // ⛁ cylinder
6036
+ runtime: "\u27F3",
6037
+ // ⟳ cycle
6038
+ singleton: "\u25CE",
6039
+ // ◎ double ring
6040
+ instance: "\u22A1"
6041
+ // ⊡ box
6042
+ };
6043
+ var ModuleCard = ({ data }) => {
6044
+ const {
6045
+ orbitalName,
6046
+ entityName,
6047
+ persistence,
6048
+ fields,
6049
+ traits,
6050
+ pages,
6051
+ traitDetails,
6052
+ externalLinks
6053
+ } = data;
6054
+ const cols = Math.min(3, Math.max(2, Math.ceil(fields.length / 3)));
6055
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6056
+ "div",
6057
+ {
6058
+ className: "rounded-lg border border-[var(--color-border)] bg-[var(--color-card)] shadow-sm overflow-hidden",
6059
+ style: { minWidth: 280, maxWidth: 400 },
6060
+ children: [
6061
+ /* @__PURE__ */ jsxRuntime.jsx(react.Handle, { type: "target", position: react.Position.Left, className: "!w-2.5 !h-2.5 !bg-orange-400" }),
6062
+ /* @__PURE__ */ jsxRuntime.jsx(react.Handle, { type: "source", position: react.Position.Right, className: "!w-2.5 !h-2.5 !bg-orange-400" }),
6063
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-2 border-b border-[var(--color-border)]", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[15px] font-bold text-[var(--color-foreground)]", children: orbitalName }) }),
6064
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `px-3 py-2 border-b border-[var(--color-border)] ${PERSISTENCE_BORDER[persistence] ?? ""}`, children: [
6065
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 mb-1.5", children: [
6066
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 18, height: 18, viewBox: "0 0 20 20", children: /* @__PURE__ */ jsxRuntime.jsx(AvlEntity, { x: 10, y: 10, r: 8, persistence }) }),
6067
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[13px] font-semibold text-[var(--color-foreground)]", children: entityName }),
6068
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto text-[10px] opacity-50", title: persistence, children: PERSISTENCE_ICON[persistence] ?? "" })
6069
+ ] }),
6070
+ fields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `grid gap-x-3 gap-y-0.5`, style: { gridTemplateColumns: `repeat(${cols}, 1fr)` }, children: fields.map((f) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
6071
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 14, height: 14, viewBox: "0 0 16 16", children: /* @__PURE__ */ jsxRuntime.jsx(AvlFieldType, { x: 8, y: 8, kind: toFieldKind2(f.type), size: 6 }) }),
6072
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-[var(--color-muted-foreground)] truncate", children: f.name })
6073
+ ] }, f.name)) })
6074
+ ] }),
6075
+ traits.map((trait) => {
6076
+ const detail = traitDetails[trait.name];
6077
+ const traitEmits = externalLinks.filter((l) => l.direction === "out" && l.traitName === trait.name);
6078
+ const traitListens = externalLinks.filter((l) => l.direction === "in" && l.traitName === trait.name);
6079
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-2 border-b border-[var(--color-border)]", children: [
6080
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[12px] font-semibold text-[var(--color-foreground)] mb-1", children: trait.name }),
6081
+ detail && /* @__PURE__ */ jsxRuntime.jsx(MiniStateMachine, { data: detail, className: "mb-1" }),
6082
+ (traitEmits.length > 0 || traitListens.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-[9px] mt-1", children: [
6083
+ traitListens.map((l) => /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: CONNECTION_COLORS.emitListen.color }, children: [
6084
+ "\u25C0~~",
6085
+ " ",
6086
+ l.eventName
6087
+ ] }, l.eventName)),
6088
+ traitListens.length > 0 && traitEmits.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1" }),
6089
+ traitEmits.map((l) => /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: CONNECTION_COLORS.emitListen.color }, className: "ml-auto", children: [
6090
+ l.eventName,
6091
+ " ",
6092
+ "~~\u25B6"
6093
+ ] }, l.eventName))
6094
+ ] })
6095
+ ] }, trait.name);
6096
+ }),
6097
+ pages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1.5 flex items-center gap-2 flex-wrap", children: pages.map((p) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
6098
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 10, height: 10, viewBox: "0 0 12 12", children: /* @__PURE__ */ jsxRuntime.jsx(AvlPage, { x: 6, y: 6, size: 5 }) }),
6099
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono text-[var(--color-muted-foreground)]", children: p.route })
6100
+ ] }, p.name)) })
6101
+ ]
6102
+ }
6103
+ );
6104
+ };
6105
+ ModuleCard.displayName = "ModuleCard";
6106
+ var SWIM_GUTTER = 120;
6107
+ var CENTER_W = 360;
6108
+ var BehaviorView = ({ data }) => {
6109
+ const [layout, setLayout] = React8.useState(null);
6110
+ const traitName = data.traits[0]?.name;
6111
+ const traitData = traitName ? data.traitDetails[traitName] : void 0;
6112
+ const dataKey = React8.useMemo(() => JSON.stringify(traitData), [traitData]);
6113
+ React8.useEffect(() => {
6114
+ if (!traitData) return;
6115
+ computeTraitLayout(traitData).then(setLayout).catch(console.error);
6116
+ }, [dataKey]);
6117
+ if (!traitData) {
6118
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-[var(--color-border)] bg-[var(--color-card)] p-4 text-center text-[var(--color-muted-foreground)] text-sm", children: "No trait data" });
6119
+ }
6120
+ if (!layout) {
6121
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-[var(--color-border)] bg-[var(--color-card)] p-4 text-center text-[var(--color-muted-foreground)] text-sm", children: "Computing layout..." });
6122
+ }
6123
+ const hasExternal = traitData.listenedEvents.length > 0 || traitData.emittedEvents.length > 0;
6124
+ const viewW = hasExternal ? SWIM_GUTTER + CENTER_W + SWIM_GUTTER : CENTER_W + 60;
6125
+ const machineOffsetX = hasExternal ? 0 : 30;
6126
+ const padding = 20;
6127
+ const availW = CENTER_W - padding * 2;
6128
+ const availH = 300;
6129
+ const scale = Math.min(1, availW / layout.width, availH / layout.height);
6130
+ const scaledH = layout.height * scale;
6131
+ const scaledW = layout.width * scale;
6132
+ const offsetX = padding + (availW - scaledW) / 2;
6133
+ const offsetY = 50 + (availH - scaledH) / 2;
6134
+ const machineHeight = scaledH + 100;
6135
+ const renderMachine = /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6136
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: CENTER_W / 2, y: 20, textAnchor: "middle", fill: "var(--color-foreground)", fontSize: 18, fontWeight: "700", fontFamily: "inherit", children: traitData.name }),
6137
+ /* @__PURE__ */ jsxRuntime.jsxs("text", { x: CENTER_W / 2, y: 36, textAnchor: "middle", fill: "var(--color-muted-foreground)", fontSize: 11, opacity: 0.5, fontFamily: "inherit", children: [
6138
+ "on ",
6139
+ traitData.linkedEntity
6140
+ ] }),
6141
+ /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
6142
+ /* @__PURE__ */ jsxRuntime.jsx("marker", { id: "bvArrow", viewBox: "0 0 10 10", refX: "9", refY: "5", markerWidth: "6", markerHeight: "6", orient: "auto-start-reverse", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M 0 0 L 10 5 L 0 10 z", fill: CONNECTION_COLORS.forward.color, opacity: 0.7 }) }),
6143
+ /* @__PURE__ */ jsxRuntime.jsx("marker", { id: "bvArrowBack", viewBox: "0 0 10 10", refX: "9", refY: "5", markerWidth: "6", markerHeight: "6", orient: "auto-start-reverse", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M 0 0 L 10 5 L 0 10 z", fill: CONNECTION_COLORS.backward.color, opacity: 0.5 }) })
6144
+ ] }),
6145
+ /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${offsetX},${offsetY}) scale(${scale})`, children: [
6146
+ layout.edges.map((edge) => {
6147
+ const conn = edge.isSelf ? CONNECTION_COLORS.selfLoop : edge.isBackward ? CONNECTION_COLORS.backward : CONNECTION_COLORS.forward;
6148
+ const marker = edge.isBackward || edge.isSelf ? "url(#bvArrowBack)" : "url(#bvArrow)";
6149
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6150
+ /* @__PURE__ */ jsxRuntime.jsx(
6151
+ "path",
6152
+ {
6153
+ d: edgePath(edge.points),
6154
+ fill: "none",
6155
+ stroke: conn.color,
6156
+ strokeWidth: conn.width,
6157
+ strokeDasharray: conn.dash === "none" ? void 0 : conn.dash,
6158
+ opacity: 0.5,
6159
+ markerEnd: marker
6160
+ }
6161
+ ),
6162
+ /* @__PURE__ */ jsxRuntime.jsx(
6163
+ AvlTransitionLane,
6164
+ {
6165
+ x: edge.labelX,
6166
+ y: edge.labelY,
6167
+ event: edge.event,
6168
+ guard: edge.guardExpr,
6169
+ effects: edge.effects.map((e) => ({ type: e.type })),
6170
+ width: edge.labelW,
6171
+ isBackward: edge.isBackward,
6172
+ isSelfLoop: edge.isSelf
6173
+ }
6174
+ )
6175
+ ] }, edge.id);
6176
+ }),
6177
+ layout.nodes.map((node) => /* @__PURE__ */ jsxRuntime.jsx(
6178
+ AvlState,
6179
+ {
6180
+ x: node.x,
6181
+ y: node.y,
6182
+ width: node.width,
6183
+ height: node.height,
6184
+ name: node.id,
6185
+ isInitial: node.isInitial,
6186
+ isTerminal: node.isTerminal,
6187
+ role: node.role,
6188
+ transitionCount: node.transitionCount
6189
+ },
6190
+ node.id
6191
+ ))
6192
+ ] })
6193
+ ] });
6194
+ const svgH = machineHeight + 20;
6195
+ if (!hasExternal) {
6196
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-[var(--color-border)] bg-[var(--color-card)] overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: viewW, height: svgH, viewBox: `0 0 ${viewW} ${svgH}`, children: /* @__PURE__ */ jsxRuntime.jsx("g", { transform: `translate(${machineOffsetX}, 0)`, children: renderMachine }) }) });
6197
+ }
6198
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-[var(--color-border)] bg-[var(--color-card)] overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: viewW, height: svgH, viewBox: `0 0 ${viewW} ${svgH}`, children: /* @__PURE__ */ jsxRuntime.jsx(
6199
+ AvlSwimLane,
6200
+ {
6201
+ listenedEvents: traitData.listenedEvents,
6202
+ emittedEvents: traitData.emittedEvents,
6203
+ centerWidth: CENTER_W,
6204
+ height: machineHeight,
6205
+ children: renderMachine
6206
+ }
6207
+ ) }) });
6208
+ };
6209
+ BehaviorView.displayName = "BehaviorView";
6210
+ var DetailView = ({ data }) => {
6211
+ const traitName = data.traits[0]?.name;
6212
+ const traitData = traitName ? data.traitDetails[traitName] : void 0;
6213
+ if (!traitData || traitData.transitions.length === 0) {
6214
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border-2 border-[var(--color-border)] bg-[var(--color-card)] p-4 text-center text-[var(--color-muted-foreground)] text-sm", children: "No transition data" });
6215
+ }
6216
+ const transition = traitData.transitions[0];
6217
+ const fromState = traitData.states.find((s) => s.name === transition.from);
6218
+ const toState = traitData.states.find((s) => s.name === transition.to);
6219
+ const transitionCounts = {};
6220
+ for (const s of traitData.states) transitionCounts[s.name] = 0;
6221
+ for (const t of traitData.transitions) {
6222
+ transitionCounts[t.from] = (transitionCounts[t.from] ?? 0) + 1;
6223
+ transitionCounts[t.to] = (transitionCounts[t.to] ?? 0) + 1;
6224
+ }
6225
+ const maxTC = Math.max(...Object.values(transitionCounts), 0);
6226
+ const fromRole = getStateRole(transition.from, fromState?.isInitial, fromState?.isTerminal, transitionCounts[transition.from] ?? 0, maxTC);
6227
+ const toRole = getStateRole(transition.to, toState?.isInitial, toState?.isTerminal, transitionCounts[transition.to] ?? 0, maxTC);
6228
+ const hasGuard = transition.guard != null;
6229
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border-2 border-[var(--color-border)] bg-[var(--color-card)] overflow-hidden", style: { minWidth: 380, maxWidth: 500 }, children: [
6230
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-3 border-b border-[var(--color-border)] bg-[var(--color-background)]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
6231
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 90, height: 32, viewBox: "0 0 90 32", children: /* @__PURE__ */ jsxRuntime.jsx(AvlState, { x: 0, y: 0, width: 80, height: 28, name: transition.from, role: fromRole, isInitial: fromState?.isInitial, isTerminal: fromState?.isTerminal }) }),
6232
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: 24, height: 16, viewBox: "0 0 24 16", children: [
6233
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: 0, y1: 8, x2: 18, y2: 8, stroke: "var(--color-muted-foreground)", strokeWidth: 2 }),
6234
+ /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "18,4 24,8 18,12", fill: "var(--color-muted-foreground)" })
6235
+ ] }),
6236
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 90, height: 32, viewBox: "0 0 90 32", children: /* @__PURE__ */ jsxRuntime.jsx(AvlState, { x: 0, y: 0, width: 80, height: 28, name: transition.to, role: toRole, isInitial: toState?.isInitial, isTerminal: toState?.isTerminal }) })
6237
+ ] }) }),
6238
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-3 space-y-3", children: [
6239
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6240
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] uppercase tracking-wider text-[var(--color-muted-foreground)] mb-1", children: "Trigger" }),
6241
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
6242
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 16, height: 16, viewBox: "0 0 16 16", children: /* @__PURE__ */ jsxRuntime.jsx(AvlEvent, { x: 8, y: 8, size: 7 }) }),
6243
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[14px] font-semibold text-[var(--color-foreground)]", children: transition.event })
6244
+ ] })
6245
+ ] }),
6246
+ hasGuard && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6247
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] uppercase tracking-wider text-[var(--color-muted-foreground)] mb-1", children: "Guard" }),
6248
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
6249
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 14, height: 14, viewBox: "0 0 14 14", children: /* @__PURE__ */ jsxRuntime.jsx(AvlGuard, { x: 7, y: 7, size: 6 }) }),
6250
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] font-mono text-[var(--color-muted-foreground)] opacity-60", children: typeof transition.guard === "string" ? transition.guard : JSON.stringify(transition.guard) })
6251
+ ] })
6252
+ ] }),
6253
+ transition.effects.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6254
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] uppercase tracking-wider text-[var(--color-muted-foreground)] mb-1", children: "Effects" }),
6255
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1.5", children: transition.effects.map((effect, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-1.5", children: [
6256
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-[var(--color-muted-foreground)] w-3 text-right mt-0.5", children: [
6257
+ i + 1,
6258
+ "."
6259
+ ] }),
6260
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 18, height: 18, viewBox: "0 0 20 20", children: /* @__PURE__ */ jsxRuntime.jsx(AvlEffect, { x: 10, y: 10, effectType: effect.type, size: 8, showBackground: true }) }),
6261
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] text-[var(--color-foreground)]", children: effect.type })
6262
+ ] }, i)) })
6263
+ ] })
6264
+ ] })
6265
+ ] });
6266
+ };
6267
+ DetailView.displayName = "DetailView";
6268
+ var AvlOrbitalNode = (props) => {
6269
+ const band = useZoomBand();
6270
+ const data = props.data;
6271
+ switch (band) {
6272
+ case "system":
6273
+ return /* @__PURE__ */ jsxRuntime.jsx(SystemNode, { data });
6274
+ case "module":
6275
+ return /* @__PURE__ */ jsxRuntime.jsx(ModuleCard, { data });
6276
+ case "behavior":
6277
+ return /* @__PURE__ */ jsxRuntime.jsx(BehaviorView, { data });
6278
+ case "detail":
6279
+ return /* @__PURE__ */ jsxRuntime.jsx(DetailView, { data });
6280
+ }
6281
+ };
6282
+ AvlOrbitalNode.displayName = "AvlOrbitalNode";
6283
+ var AvlTransitionEdge = ({
6284
+ id,
6285
+ sourceX,
6286
+ sourceY,
6287
+ targetX,
6288
+ targetY,
6289
+ sourcePosition,
6290
+ targetPosition,
6291
+ data,
6292
+ markerEnd,
6293
+ style
6294
+ }) => {
6295
+ const [path, labelX, labelY] = react.getBezierPath({
6296
+ sourceX,
6297
+ sourceY,
6298
+ targetX,
6299
+ targetY,
6300
+ sourcePosition,
6301
+ targetPosition
6302
+ });
6303
+ const isBackward = targetX < sourceX;
6304
+ const connStyle = isBackward ? CONNECTION_COLORS.backward : CONNECTION_COLORS.forward;
6305
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6306
+ /* @__PURE__ */ jsxRuntime.jsx(
6307
+ react.BaseEdge,
6308
+ {
6309
+ id,
6310
+ path,
6311
+ markerEnd,
6312
+ style: {
6313
+ stroke: connStyle.color,
6314
+ strokeWidth: connStyle.width,
6315
+ strokeDasharray: connStyle.dash,
6316
+ ...style
6317
+ }
6318
+ }
6319
+ ),
6320
+ /* @__PURE__ */ jsxRuntime.jsx(react.EdgeLabelRenderer, { children: /* @__PURE__ */ jsxRuntime.jsxs(
6321
+ "div",
6322
+ {
6323
+ className: "absolute pointer-events-all nodrag nopan flex items-center gap-1",
6324
+ style: { transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)` },
6325
+ children: [
6326
+ data?.hasGuard && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-3 h-3 rotate-45 border border-amber-500 bg-amber-500/10 shrink-0", title: "Guard" }),
6327
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-0.5 text-[10px] font-medium rounded-full bg-[var(--color-card)] border border-[var(--color-border)] text-[var(--color-foreground)] truncate max-w-[160px]", children: data?.event ?? "" }),
6328
+ data?.hasEffects && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2.5 h-2.5 rounded-full bg-violet-500/80 shrink-0", title: "Effects" })
6329
+ ]
6330
+ }
6331
+ ) })
6332
+ ] });
6333
+ };
6334
+ AvlTransitionEdge.displayName = "AvlTransitionEdge";
6335
+ var AvlEventWireEdge = ({
6336
+ id,
6337
+ sourceX,
6338
+ sourceY,
6339
+ targetX,
6340
+ targetY,
6341
+ sourcePosition,
6342
+ targetPosition,
6343
+ data,
6344
+ markerEnd,
6345
+ style
6346
+ }) => {
6347
+ const [path, labelX, labelY] = react.getBezierPath({
6348
+ sourceX,
6349
+ sourceY,
6350
+ targetX,
6351
+ targetY,
6352
+ sourcePosition,
6353
+ targetPosition
6354
+ });
6355
+ const isCompatible = data?.compatible !== false;
6356
+ const wireColor = isCompatible ? CONNECTION_COLORS.emitListen.color : "#EF4444";
6357
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6358
+ /* @__PURE__ */ jsxRuntime.jsx(
6359
+ react.BaseEdge,
6360
+ {
6361
+ id,
6362
+ path,
6363
+ markerEnd,
6364
+ style: {
6365
+ stroke: wireColor,
6366
+ strokeWidth: CONNECTION_COLORS.emitListen.width,
6367
+ strokeDasharray: CONNECTION_COLORS.emitListen.dash,
6368
+ ...style
6369
+ }
6370
+ }
6371
+ ),
6372
+ /* @__PURE__ */ jsxRuntime.jsx(react.EdgeLabelRenderer, { children: /* @__PURE__ */ jsxRuntime.jsx(
6373
+ "div",
6374
+ {
6375
+ className: "absolute pointer-events-all nodrag nopan",
6376
+ style: { transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)` },
6377
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6378
+ "div",
6379
+ {
6380
+ className: "px-2 py-0.5 text-[10px] font-medium rounded-full border truncate max-w-[180px]",
6381
+ style: {
6382
+ color: wireColor,
6383
+ borderColor: wireColor,
6384
+ backgroundColor: `${wireColor}14`
6385
+ },
6386
+ children: data?.event ?? ""
6387
+ }
6388
+ )
6389
+ }
6390
+ ) })
6391
+ ] });
6392
+ };
6393
+ AvlEventWireEdge.displayName = "AvlEventWireEdge";
6394
+ var AvlBackwardEdge = ({
6395
+ id,
6396
+ sourceX,
6397
+ sourceY,
6398
+ targetX,
6399
+ targetY,
6400
+ sourcePosition,
6401
+ targetPosition,
6402
+ markerEnd,
6403
+ style
6404
+ }) => {
6405
+ const [path] = react.getBezierPath({
6406
+ sourceX,
6407
+ sourceY,
6408
+ targetX,
6409
+ targetY,
6410
+ sourcePosition,
6411
+ targetPosition
6412
+ });
6413
+ return /* @__PURE__ */ jsxRuntime.jsx(
6414
+ react.BaseEdge,
6415
+ {
6416
+ id,
6417
+ path,
6418
+ markerEnd,
6419
+ style: {
6420
+ stroke: CONNECTION_COLORS.backward.color,
6421
+ strokeWidth: CONNECTION_COLORS.backward.width,
6422
+ strokeDasharray: CONNECTION_COLORS.backward.dash,
6423
+ ...style
6424
+ }
6425
+ }
6426
+ );
6427
+ };
6428
+ AvlBackwardEdge.displayName = "AvlBackwardEdge";
6429
+ var PAGE_EDGE_COLOR = "#64748B";
6430
+ var AvlPageEdge = ({
6431
+ id,
6432
+ sourceX,
6433
+ sourceY,
6434
+ targetX,
6435
+ targetY,
6436
+ sourcePosition,
6437
+ targetPosition,
6438
+ markerEnd,
6439
+ style
6440
+ }) => {
6441
+ const [path] = react.getBezierPath({
6442
+ sourceX,
6443
+ sourceY,
6444
+ targetX,
6445
+ targetY,
6446
+ sourcePosition,
6447
+ targetPosition
6448
+ });
6449
+ return /* @__PURE__ */ jsxRuntime.jsx(
6450
+ react.BaseEdge,
6451
+ {
6452
+ id,
6453
+ path,
6454
+ markerEnd,
6455
+ style: {
6456
+ stroke: PAGE_EDGE_COLOR,
6457
+ strokeWidth: 1,
6458
+ ...style
6459
+ }
6460
+ }
6461
+ );
6462
+ };
6463
+ AvlPageEdge.displayName = "AvlPageEdge";
6464
+ var BINDING_COLOR = "#8B5CF6";
6465
+ var AvlBindingEdge = ({
6466
+ id,
6467
+ sourceX,
6468
+ sourceY,
6469
+ targetX,
6470
+ targetY,
6471
+ sourcePosition,
6472
+ targetPosition,
6473
+ markerEnd,
6474
+ style
6475
+ }) => {
6476
+ const [path, labelX, labelY] = react.getBezierPath({
6477
+ sourceX,
6478
+ sourceY,
6479
+ targetX,
6480
+ targetY,
6481
+ sourcePosition,
6482
+ targetPosition
6483
+ });
6484
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6485
+ /* @__PURE__ */ jsxRuntime.jsx(
6486
+ react.BaseEdge,
6487
+ {
6488
+ id,
6489
+ path,
6490
+ markerEnd,
6491
+ style: {
6492
+ stroke: BINDING_COLOR,
6493
+ strokeWidth: 1,
6494
+ strokeDasharray: "3 2",
6495
+ ...style
6496
+ }
6497
+ }
6498
+ ),
6499
+ /* @__PURE__ */ jsxRuntime.jsx(react.EdgeLabelRenderer, { children: /* @__PURE__ */ jsxRuntime.jsx(
6500
+ "div",
6501
+ {
6502
+ className: "absolute pointer-events-none nodrag nopan",
6503
+ style: { transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)` },
6504
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6505
+ "span",
6506
+ {
6507
+ className: "text-[9px] font-mono font-medium",
6508
+ style: { color: BINDING_COLOR },
6509
+ children: "@"
6510
+ }
6511
+ )
6512
+ }
6513
+ ) })
6514
+ ] });
6515
+ };
6516
+ AvlBindingEdge.displayName = "AvlBindingEdge";
6517
+ var BAND_LABELS = {
6518
+ system: "System",
6519
+ module: "Module",
6520
+ behavior: "Behavior",
6521
+ detail: "Detail"
6522
+ };
6523
+ var BAND_ICONS = {
6524
+ system: "\u25C9",
6525
+ // ◉ filled circle
6526
+ module: "\u25C9",
6527
+ // ◉ filled circle
6528
+ behavior: "\u25CE",
6529
+ // ◎ double circle
6530
+ detail: "\u26A1"
6531
+ // ⚡ lightning
6532
+ };
6533
+ var ZoomBreadcrumb = ({
6534
+ band,
6535
+ applicationName,
6536
+ orbitalName,
6537
+ traitName,
6538
+ eventName
6539
+ }) => {
6540
+ const segments = [];
6541
+ if (applicationName) {
6542
+ segments.push({ icon: "\u25C9", label: applicationName });
6543
+ }
6544
+ segments.push({ icon: BAND_ICONS[band], label: BAND_LABELS[band] });
6545
+ if (orbitalName && (band === "module" || band === "behavior" || band === "detail")) {
6546
+ segments.push({ icon: "\u25C9", label: orbitalName });
6547
+ }
6548
+ if (traitName && (band === "behavior" || band === "detail")) {
6549
+ segments.push({ icon: "\u25CE", label: traitName });
6550
+ }
6551
+ if (eventName && band === "detail") {
6552
+ segments.push({ icon: "\u26A1", label: eventName });
6553
+ }
6554
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-2 left-2 z-10 flex items-center gap-1 px-2 py-1 rounded-md bg-[var(--color-card)]/90 border border-[var(--color-border)] text-[11px] text-[var(--color-muted-foreground)] backdrop-blur-sm", children: segments.map((seg, i) => /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
6555
+ i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-40", children: ">" }),
6556
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-60", children: seg.icon }),
6557
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: seg.label })
6558
+ ] }, i)) });
6559
+ };
6560
+ ZoomBreadcrumb.displayName = "ZoomBreadcrumb";
6561
+ var BAND_LEGENDS = {
6562
+ system: [
6563
+ { icon: "\u25C9", label: "Entity" },
6564
+ { icon: "\u25CF\u25B2\u25A0\u25C6", label: "Field types" },
6565
+ { icon: "\u25CF\u2501\u25CF", label: "State chain" },
6566
+ { icon: "\u25A0", label: "Page" },
6567
+ { icon: "\u2500 \u2500", label: "Event wire" }
6568
+ ],
6569
+ module: [
6570
+ { icon: "\u25C9", label: "Entity" },
6571
+ { icon: "\u26C1", label: "Persistence" },
6572
+ { icon: "\u25CF\u25B2\u25A0\u25C6\u25CB\u2B21\u2261", label: "Field types" },
6573
+ { icon: "\u2501\u25CF\u2501", label: "State machine" },
6574
+ { icon: "\u229E\u270E\u26C1\u{1F4E1}", label: "Effects" },
6575
+ { icon: "\u25A0", label: "Page" },
6576
+ { icon: "\u25C0\u301C\u301C / \u301C\u301C\u25B6", label: "Emit/Listen" }
6577
+ ],
6578
+ behavior: [
6579
+ { icon: "\u25CF green", label: "Initial state" },
6580
+ { icon: "\u25CF red", label: "Terminal state" },
6581
+ { icon: "\u25CF blue", label: "Hub state" },
6582
+ { icon: "\u26A1", label: "Event" },
6583
+ { icon: "\u25C7", label: "Guard" },
6584
+ { icon: "\u229E\u270E\u26C1\u{1F4E1}\u{1F514}", label: "Effects" },
6585
+ { icon: "\u2500 \u2500 orange", label: "Emit/Listen" }
6586
+ ],
6587
+ detail: [
6588
+ { icon: "\u26A1", label: "Trigger event" },
6589
+ { icon: "\u25C7", label: "Guard diamond" },
6590
+ { icon: "\u229E", label: "render-ui" },
6591
+ { icon: "\u270E", label: "set" },
6592
+ { icon: "\u26C1", label: "persist" },
6593
+ { icon: "\u{1F4E1}", label: "emit" },
6594
+ { icon: "@", label: "Binding" },
6595
+ { icon: "\u25CF\u25B2\u25A0", label: "Field types" }
6596
+ ]
6597
+ };
6598
+ var ZoomLegend = ({ band }) => {
6599
+ const [collapsed, setCollapsed] = React8.useState(true);
6600
+ const items = BAND_LEGENDS[band];
6601
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-2 left-2 z-10", children: [
6602
+ /* @__PURE__ */ jsxRuntime.jsx(
6603
+ "button",
6604
+ {
6605
+ onClick: () => setCollapsed(!collapsed),
6606
+ className: "px-2 py-1 text-[10px] rounded-md bg-[var(--color-card)]/90 border border-[var(--color-border)] text-[var(--color-muted-foreground)] backdrop-blur-sm cursor-pointer hover:bg-[var(--color-card)]",
6607
+ children: collapsed ? "Legend" : "Hide"
6608
+ }
6609
+ ),
6610
+ !collapsed && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 px-2 py-1.5 rounded-md bg-[var(--color-card)]/95 border border-[var(--color-border)] backdrop-blur-sm space-y-0.5", children: items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-[var(--color-muted-foreground)]", children: [
6611
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-70 w-6 text-center", children: item.icon }),
6612
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label })
6613
+ ] }, i)) })
6614
+ ] });
6615
+ };
6616
+ ZoomLegend.displayName = "ZoomLegend";
6617
+ var NODE_TYPES = {
6618
+ orbital: AvlOrbitalNode
6619
+ };
6620
+ var EDGE_TYPES = {
6621
+ transition: AvlTransitionEdge,
6622
+ eventWire: AvlEventWireEdge,
6623
+ backward: AvlBackwardEdge,
6624
+ page: AvlPageEdge,
6625
+ binding: AvlBindingEdge
6626
+ };
6627
+ function bandToZoomLevel(band) {
6628
+ switch (band) {
6629
+ case "system":
6630
+ return "application";
6631
+ case "module":
6632
+ return "orbital";
6633
+ case "behavior":
6634
+ return "trait";
6635
+ case "detail":
6636
+ return "transition";
6637
+ }
6638
+ }
6639
+ function FlowCanvasInner({
6640
+ schema: schemaProp,
6641
+ className,
6642
+ color = "var(--color-primary)",
6643
+ width = "100%",
6644
+ height = 500,
6645
+ onZoomChange,
6646
+ focusTarget,
6647
+ initialOrbital
6648
+ }) {
6649
+ const parsedSchema = React8.useMemo(() => {
6650
+ if (typeof schemaProp === "string") return JSON.parse(schemaProp);
6651
+ return schemaProp;
6652
+ }, [schemaProp]);
6653
+ const { nodes: initialNodes, edges: initialEdges } = React8.useMemo(
6654
+ () => schemaToFlowGraph(parsedSchema),
6655
+ [parsedSchema]
6656
+ );
6657
+ const [nodes, , onNodesChange] = react.useNodesState(initialNodes);
6658
+ const [edges, , onEdgesChange] = react.useEdgesState(initialEdges);
6659
+ const [band, setBand] = React8.useState("module");
6660
+ const reactFlow = react.useReactFlow();
6661
+ const handleViewportChange = React8.useCallback((viewport) => {
6662
+ const newBand = computeZoomBand(viewport.zoom);
6663
+ setBand((prev) => {
6664
+ if (prev !== newBand) {
6665
+ onZoomChange?.(bandToZoomLevel(newBand), {});
6666
+ return newBand;
6667
+ }
6668
+ return prev;
6669
+ });
6670
+ }, [onZoomChange]);
6671
+ React8.useEffect(() => {
6672
+ if (!focusTarget) return;
6673
+ const targetNode = nodes.find(
6674
+ (n) => focusTarget.type === "orbital" && n.id === focusTarget.name
6675
+ );
6676
+ if (targetNode) {
6677
+ reactFlow.fitView({ nodes: [targetNode], duration: 500, padding: 0.5 });
6678
+ }
6679
+ }, [focusTarget, nodes, reactFlow]);
6680
+ React8.useEffect(() => {
6681
+ if (!initialOrbital) return;
6682
+ const targetNode = nodes.find((n) => n.id === initialOrbital);
6683
+ if (targetNode) {
6684
+ requestAnimationFrame(() => {
6685
+ reactFlow.fitView({ nodes: [targetNode], duration: 0, padding: 0.3 });
6686
+ });
6687
+ }
6688
+ }, [initialOrbital]);
6689
+ return /* @__PURE__ */ jsxRuntime.jsx(ZoomBandContext.Provider, { value: band, children: /* @__PURE__ */ jsxRuntime.jsxs(
6690
+ Box,
6691
+ {
6692
+ className: `relative ${className ?? ""}`,
6693
+ style: { width, height, "--avl-color": color },
6694
+ children: [
6695
+ /* @__PURE__ */ jsxRuntime.jsxs(
6696
+ react.ReactFlow,
6697
+ {
6698
+ nodes,
6699
+ edges,
6700
+ nodeTypes: NODE_TYPES,
6701
+ edgeTypes: EDGE_TYPES,
6702
+ onNodesChange,
6703
+ onEdgesChange,
6704
+ onViewportChange: handleViewportChange,
6705
+ minZoom: 0.1,
6706
+ maxZoom: 5,
6707
+ fitView: true,
6708
+ nodesDraggable: true,
6709
+ elementsSelectable: true,
6710
+ proOptions: { hideAttribution: true },
6711
+ style: { background: "var(--color-background)" },
6712
+ children: [
6713
+ /* @__PURE__ */ jsxRuntime.jsx(
6714
+ react.Controls,
6715
+ {
6716
+ showInteractive: false,
6717
+ style: {
6718
+ background: "var(--color-card)",
6719
+ border: "1px solid var(--color-border)",
6720
+ borderRadius: "var(--radius-md)"
6721
+ }
6722
+ }
6723
+ ),
6724
+ /* @__PURE__ */ jsxRuntime.jsx(
6725
+ react.Background,
6726
+ {
6727
+ variant: react.BackgroundVariant.Dots,
6728
+ gap: 20,
6729
+ size: 1,
6730
+ color: "var(--color-border)"
6731
+ }
6732
+ )
6733
+ ]
6734
+ }
6735
+ ),
6736
+ /* @__PURE__ */ jsxRuntime.jsx(ZoomBreadcrumb, { band }),
6737
+ /* @__PURE__ */ jsxRuntime.jsx(ZoomLegend, { band })
6738
+ ]
6739
+ }
6740
+ ) });
6741
+ }
6742
+ var FlowCanvas = (props) => {
6743
+ return /* @__PURE__ */ jsxRuntime.jsx(react.ReactFlowProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(FlowCanvasInner, { ...props }) });
6744
+ };
6745
+ FlowCanvas.displayName = "FlowCanvas";
6746
+ var AvlCosmicZoom = (props) => {
6747
+ return /* @__PURE__ */ jsxRuntime.jsx(
6748
+ FlowCanvas,
6749
+ {
6750
+ schema: props.schema,
6751
+ className: props.className,
6752
+ color: props.color,
6753
+ animated: props.animated,
6754
+ width: props.width,
6755
+ height: props.height ?? 400,
6756
+ onZoomChange: props.onZoomChange,
6757
+ focusTarget: props.focusTarget,
6758
+ initialOrbital: props.initialOrbital,
6759
+ initialTrait: props.initialTrait,
6760
+ stateCoverage: props.stateCoverage
6761
+ }
6762
+ );
6763
+ };
6764
+ AvlCosmicZoom.displayName = "AvlCosmicZoom";
6765
+ var SWIM_GUTTER2 = 120;
6766
+ var CENTER_W2 = 360;
6767
+ var AvlTraitScene = ({
6768
+ data,
6769
+ color = "var(--color-primary)",
6770
+ onTransitionClick
6771
+ }) => {
6772
+ const [layout, setLayout] = React8.useState(null);
6501
6773
  const dataKey = React8.useMemo(() => JSON.stringify(data), [data]);
6502
6774
  React8.useEffect(() => {
6503
- computeLayout(data).then(setLayout).catch(console.error);
6775
+ computeTraitLayout(data).then(setLayout).catch(console.error);
6504
6776
  }, [dataKey]);
6505
6777
  if (!layout) {
6506
6778
  return /* @__PURE__ */ jsxRuntime.jsx("g", { children: /* @__PURE__ */ jsxRuntime.jsx("text", { x: 300, y: 200, textAnchor: "middle", fill: color, fontSize: 12, opacity: 0.5, children: "Computing layout..." }) });
@@ -6508,7 +6780,7 @@ var AvlTraitScene = ({
6508
6780
  const hasExternal = data.listenedEvents.length > 0 || data.emittedEvents.length > 0;
6509
6781
  const machineOffsetX = hasExternal ? 0 : 30;
6510
6782
  const padding = 20;
6511
- const availW = CENTER_W - padding * 2;
6783
+ const availW = CENTER_W2 - padding * 2;
6512
6784
  const availH = 300;
6513
6785
  const scale = Math.min(1, availW / layout.width, availH / layout.height);
6514
6786
  const scaledW = layout.width * scale;
@@ -6517,8 +6789,8 @@ var AvlTraitScene = ({
6517
6789
  const offsetY = 50 + (availH - scaledH) / 2;
6518
6790
  const machineHeight = scaledH + 100;
6519
6791
  const renderMachine = /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6520
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: CENTER_W / 2, y: 20, textAnchor: "middle", fill: color, fontSize: 20, fontWeight: "700", fontFamily: "inherit", children: data.name }),
6521
- /* @__PURE__ */ jsxRuntime.jsxs("text", { x: CENTER_W / 2, y: 38, textAnchor: "middle", fill: color, fontSize: 11, opacity: 0.5, fontFamily: "inherit", children: [
6792
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: CENTER_W2 / 2, y: 20, textAnchor: "middle", fill: color, fontSize: 20, fontWeight: "700", fontFamily: "inherit", children: data.name }),
6793
+ /* @__PURE__ */ jsxRuntime.jsxs("text", { x: CENTER_W2 / 2, y: 38, textAnchor: "middle", fill: color, fontSize: 11, opacity: 0.5, fontFamily: "inherit", children: [
6522
6794
  "linked to ",
6523
6795
  data.linkedEntity
6524
6796
  ] }),
@@ -6556,7 +6828,7 @@ var AvlTraitScene = ({
6556
6828
  isSelfLoop: edge.isSelf,
6557
6829
  color,
6558
6830
  onTransitionClick: onTransitionClick ? () => onTransitionClick(edge.index, {
6559
- x: edge.labelX + offsetX + (hasExternal ? SWIM_GUTTER : machineOffsetX),
6831
+ x: edge.labelX + offsetX + (hasExternal ? SWIM_GUTTER2 : machineOffsetX),
6560
6832
  y: edge.labelY + offsetY
6561
6833
  }) : void 0
6562
6834
  }
@@ -6588,7 +6860,7 @@ var AvlTraitScene = ({
6588
6860
  {
6589
6861
  listenedEvents: data.listenedEvents,
6590
6862
  emittedEvents: data.emittedEvents,
6591
- centerWidth: CENTER_W,
6863
+ centerWidth: CENTER_W2,
6592
6864
  height: machineHeight,
6593
6865
  color,
6594
6866
  children: renderMachine
@@ -6596,9 +6868,9 @@ var AvlTraitScene = ({
6596
6868
  );
6597
6869
  };
6598
6870
  AvlTraitScene.displayName = "AvlTraitScene";
6599
- var CX2 = 300;
6871
+ var CX = 300;
6600
6872
  var CARD_W = 440;
6601
- var CARD_X = CX2 - CARD_W / 2;
6873
+ var CARD_X = CX - CARD_W / 2;
6602
6874
  var SECTION_LEFT = CARD_X + 16;
6603
6875
  var CONTENT_LEFT = CARD_X + 24;
6604
6876
  function flattenEffect(node) {
@@ -6715,7 +6987,7 @@ var AvlTransitionScene = ({
6715
6987
  /* @__PURE__ */ jsxRuntime.jsx(
6716
6988
  "text",
6717
6989
  {
6718
- x: CX2,
6990
+ x: CX,
6719
6991
  y: cardY + 32,
6720
6992
  textAnchor: "middle",
6721
6993
  fill: color,
@@ -6833,405 +7105,77 @@ var AvlTransitionScene = ({
6833
7105
  ] });
6834
7106
  };
6835
7107
  AvlTransitionScene.displayName = "AvlTransitionScene";
6836
- var APPLICATION_ITEMS = [
6837
- {
6838
- label: "Orbital",
6839
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: y, r: 8, fill: "none", stroke: c, strokeWidth: 1.5 })
6840
- },
6841
- {
6842
- label: "Entity",
6843
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6844
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: y, r: 5, fill: c, opacity: 0.2 }),
6845
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: y, r: 5, fill: "none", stroke: c, strokeWidth: 1.5 })
6846
- ] })
6847
- },
6848
- {
6849
- label: "Trait",
6850
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsx("ellipse", { cx: x, cy: y, rx: 10, ry: 5, fill: "none", stroke: c, strokeWidth: 1, strokeDasharray: "3 1.5" })
6851
- },
6852
- {
6853
- label: "Page",
6854
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsx("rect", { x: x - 3, y: y - 3, width: 6, height: 6, fill: c, opacity: 0.3, stroke: c, strokeWidth: 1 })
6855
- },
6856
- {
6857
- label: "Event flow",
6858
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6859
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: x - 10, y1: y, x2: x + 10, y2: y, stroke: c, strokeWidth: 1, strokeDasharray: "4 2" }),
6860
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: `${x + 10},${y} ${x + 6},${y - 3} ${x + 6},${y + 3}`, fill: c, opacity: 0.5 })
6861
- ] })
6862
- }
6863
- ];
6864
- var ORBITAL_ITEMS = [
6865
- {
6866
- label: "Orbital boundary",
6867
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: y, r: 8, fill: "none", stroke: c, strokeWidth: 1.5 })
6868
- },
6869
- {
6870
- label: "Entity (nucleus)",
6871
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6872
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: y, r: 5, fill: c, opacity: 0.15 }),
6873
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: y, r: 5, fill: "none", stroke: c, strokeWidth: 2 }),
6874
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: x, y1: y - 7, x2: x, y2: y - 9, stroke: c, strokeWidth: 0.8, opacity: 0.5 })
6875
- ] })
6876
- },
6877
- {
6878
- label: "Trait ring",
6879
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsx("ellipse", { cx: x, cy: y, rx: 10, ry: 5, fill: "none", stroke: c, strokeWidth: 1, strokeDasharray: "3 1.5" })
6880
- },
6881
- {
6882
- label: "Page",
6883
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsx("rect", { x: x - 3, y: y - 3, width: 6, height: 6, fill: c, opacity: 0.3, stroke: c, strokeWidth: 1 })
6884
- },
6885
- {
6886
- label: "External link",
6887
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsx("line", { x1: x - 8, y1: y, x2: x + 8, y2: y, stroke: c, strokeWidth: 1, strokeDasharray: "4 2", opacity: 0.4 })
6888
- }
6889
- ];
6890
- var TRAIT_ITEMS = [
6891
- {
6892
- label: "State",
6893
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsx("rect", { x: x - 12, y: y - 6, width: 24, height: 12, rx: 6, fill: "none", stroke: c, strokeWidth: 1.5 })
6894
- },
6895
- {
6896
- label: "Initial state",
6897
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6898
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x - 10, cy: y, r: 3, fill: c }),
6899
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: x - 4, y: y - 6, width: 20, height: 12, rx: 6, fill: "none", stroke: c, strokeWidth: 1.5 })
6900
- ] })
6901
- },
6902
- {
6903
- label: "Transition",
6904
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6905
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: x - 10, y1: y, x2: x + 8, y2: y, stroke: c, strokeWidth: 1.2, opacity: 0.5 }),
6906
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: `${x + 10},${y} ${x + 6},${y - 3} ${x + 6},${y + 3}`, fill: c, opacity: 0.5 })
6907
- ] })
6908
- },
6909
- {
6910
- label: "Event + effects",
6911
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsx("rect", { x: x - 14, y: y - 7, width: 28, height: 14, rx: 3, fill: "var(--color-surface, white)", stroke: c, strokeWidth: 0.8 })
6912
- },
6913
- {
6914
- label: "Emit (external)",
6915
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: y, r: 3, fill: c, opacity: 0.5, children: /* @__PURE__ */ jsxRuntime.jsx("animate", { attributeName: "r", values: "2;4;2", dur: "1.5s", repeatCount: "indefinite" }) })
6916
- }
6917
- ];
6918
- var TRANSITION_ITEMS = [
6919
- {
6920
- label: "State",
6921
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsx("rect", { x: x - 12, y: y - 6, width: 24, height: 12, rx: 6, fill: "none", stroke: c, strokeWidth: 1.5 })
6922
- },
6923
- {
6924
- label: "Effect",
6925
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6926
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: y, r: 5, fill: c, opacity: 0.15 }),
6927
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: y, r: 5, fill: "none", stroke: c, strokeWidth: 1 })
6928
- ] })
6929
- },
6930
- {
6931
- label: "Slot target",
6932
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsx("rect", { x: x - 10, y: y - 5, width: 20, height: 10, rx: 2, fill: c, opacity: 0.1, stroke: c, strokeWidth: 0.8 })
6933
- },
6934
- {
6935
- label: "Binding (@path)",
6936
- render: (x, y, c) => /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: y, r: 5, fill: "none", stroke: c, strokeWidth: 1, strokeDasharray: "2 1.5", opacity: 0.6 })
6937
- }
6938
- ];
6939
- var ITEMS_BY_LEVEL = {
6940
- application: APPLICATION_ITEMS,
6941
- orbital: ORBITAL_ITEMS,
6942
- trait: TRAIT_ITEMS,
6943
- transition: TRANSITION_ITEMS
6944
- };
6945
- var AvlLegend = ({
6946
- level,
6947
- color = "var(--color-primary)",
6948
- x = 10,
6949
- y = 360
7108
+ var AvlClickTarget = ({
7109
+ x,
7110
+ y,
7111
+ width,
7112
+ height,
7113
+ onClick,
7114
+ onHover,
7115
+ cursor = "pointer",
7116
+ glowColor = "var(--color-primary)",
7117
+ label,
7118
+ children
6950
7119
  }) => {
6951
- const items = ITEMS_BY_LEVEL[level];
6952
- const itemSpacing = 16;
6953
- const legendH = items.length * itemSpacing + 16;
6954
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { opacity: 0.6, children: [
7120
+ const [hovering, setHovering] = React8.useState(false);
7121
+ const handleMouseEnter = React8.useCallback(() => {
7122
+ setHovering(true);
7123
+ onHover?.(true);
7124
+ }, [onHover]);
7125
+ const handleMouseLeave = React8.useCallback(() => {
7126
+ setHovering(false);
7127
+ onHover?.(false);
7128
+ }, [onHover]);
7129
+ const handleKeyDown = React8.useCallback((e) => {
7130
+ if (e.key === "Enter" || e.key === " ") {
7131
+ e.preventDefault();
7132
+ onClick();
7133
+ }
7134
+ }, [onClick]);
7135
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
7136
+ hovering && /* @__PURE__ */ jsxRuntime.jsx(
7137
+ "rect",
7138
+ {
7139
+ x: x - 4,
7140
+ y: y - 4,
7141
+ width: width + 8,
7142
+ height: height + 8,
7143
+ rx: 8,
7144
+ fill: glowColor,
7145
+ opacity: 0.08
7146
+ }
7147
+ ),
7148
+ children,
6955
7149
  /* @__PURE__ */ jsxRuntime.jsx(
6956
7150
  "rect",
6957
7151
  {
6958
7152
  x,
6959
- y: y - legendH + 10,
6960
- width: 130,
6961
- height: legendH,
6962
- rx: 6,
6963
- fill: "var(--color-surface, white)",
6964
- stroke: color,
6965
- strokeWidth: 0.5,
6966
- opacity: 0.8
7153
+ y,
7154
+ width,
7155
+ height,
7156
+ fill: "transparent",
7157
+ style: { cursor },
7158
+ pointerEvents: "all",
7159
+ onClick,
7160
+ onMouseEnter: handleMouseEnter,
7161
+ onMouseLeave: handleMouseLeave,
7162
+ onKeyDown: handleKeyDown,
7163
+ tabIndex: 0,
7164
+ role: "button",
7165
+ "aria-label": label
6967
7166
  }
6968
- ),
6969
- items.map((item, i) => {
6970
- const iy = y - legendH + 22 + i * itemSpacing;
6971
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
6972
- item.render(x + 18, iy, color),
6973
- /* @__PURE__ */ jsxRuntime.jsx(
6974
- "text",
6975
- {
6976
- x: x + 35,
6977
- y: iy + 4,
6978
- fill: color,
6979
- fontSize: 8,
6980
- opacity: 0.8,
6981
- children: item.label
6982
- }
6983
- )
6984
- ] }, item.label);
6985
- })
7167
+ )
6986
7168
  ] });
6987
7169
  };
6988
- AvlLegend.displayName = "AvlLegend";
6989
- var VIEWBOX_W = 600;
6990
- var VIEWBOX_H2 = 400;
6991
- var ANIMATION_DURATION = 600;
6992
- var AvlCosmicZoom = ({
6993
- schema: schemaProp,
6994
- className,
6995
- color = "var(--color-primary)",
6996
- animated = true,
6997
- initialOrbital,
6998
- initialTrait,
6999
- onZoomChange,
7000
- width = "100%",
7001
- height = 400,
7002
- stateCoverage
7003
- }) => {
7004
- const schema = React8.useMemo(() => {
7005
- if (typeof schemaProp === "string") {
7006
- try {
7007
- return JSON.parse(schemaProp);
7008
- } catch {
7009
- return { name: "Error", orbitals: [] };
7010
- }
7011
- }
7012
- return schemaProp;
7013
- }, [schemaProp]);
7014
- const [state, dispatch] = React8.useReducer(zoomReducer, initialZoomState);
7015
- const sceneRef = React8.useRef(null);
7016
- const [transitionStyle, setTransitionStyle] = React8.useState({});
7017
- React8.useEffect(() => {
7018
- if (initialOrbital) {
7019
- dispatch({ type: "ZOOM_INTO_ORBITAL", orbital: initialOrbital, targetPosition: { x: VIEWBOX_W / 2, y: VIEWBOX_H2 / 2 } });
7020
- setTimeout(() => dispatch({ type: "ANIMATION_COMPLETE" }), 0);
7021
- if (initialTrait) {
7022
- setTimeout(() => {
7023
- dispatch({ type: "ZOOM_INTO_TRAIT", trait: initialTrait, targetPosition: { x: VIEWBOX_W / 2, y: VIEWBOX_H2 / 2 } });
7024
- setTimeout(() => dispatch({ type: "ANIMATION_COMPLETE" }), 0);
7025
- }, 10);
7026
- }
7027
- }
7028
- }, [initialOrbital, initialTrait]);
7029
- React8.useEffect(() => {
7030
- onZoomChange?.(state.level, {
7031
- orbital: state.selectedOrbital ?? void 0,
7032
- trait: state.selectedTrait ?? void 0
7033
- });
7034
- }, [state.level, state.selectedOrbital, state.selectedTrait, onZoomChange]);
7035
- React8.useEffect(() => {
7036
- if (!state.animating || !animated) {
7037
- if (state.animating) {
7038
- dispatch({ type: "ANIMATION_COMPLETE" });
7039
- }
7040
- setTransitionStyle({});
7041
- return;
7042
- }
7043
- const target = state.animationTarget;
7044
- if (!target) return;
7045
- if (state.animationDirection === "in") {
7046
- setTransitionStyle({
7047
- transform: `scale(${target.scale}) translate(${-(target.x - VIEWBOX_W / 2)}px, ${-(target.y - VIEWBOX_H2 / 2)}px)`,
7048
- transformOrigin: `${target.x}px ${target.y}px`,
7049
- transition: `transform ${ANIMATION_DURATION}ms cubic-bezier(0.4, 0, 0.2, 1), opacity ${ANIMATION_DURATION}ms ease`,
7050
- opacity: 0.3
7051
- });
7052
- } else {
7053
- setTransitionStyle({
7054
- transform: `scale(${target.scale})`,
7055
- transformOrigin: "center center",
7056
- transition: `transform ${ANIMATION_DURATION}ms cubic-bezier(0.4, 0, 0.2, 1), opacity ${ANIMATION_DURATION}ms ease`,
7057
- opacity: 0.3
7058
- });
7059
- }
7060
- const timer = setTimeout(() => {
7061
- dispatch({ type: "ANIMATION_COMPLETE" });
7062
- setTransitionStyle({});
7063
- }, ANIMATION_DURATION);
7064
- return () => clearTimeout(timer);
7065
- }, [state.animating, state.animationDirection, state.animationTarget, animated]);
7066
- const handleKeyDown = React8.useCallback((e) => {
7067
- if (e.key === "Escape") {
7068
- dispatch({ type: "ZOOM_OUT" });
7069
- }
7070
- }, []);
7071
- const handleOrbitalClick = React8.useCallback((name, pos) => {
7072
- dispatch({ type: "ZOOM_INTO_ORBITAL", orbital: name, targetPosition: pos });
7073
- }, []);
7074
- const handleTraitClick = React8.useCallback((name, pos) => {
7075
- dispatch({ type: "ZOOM_INTO_TRAIT", trait: name, targetPosition: pos });
7076
- }, []);
7077
- const handleTraitSwitch = React8.useCallback((name) => {
7078
- dispatch({ type: "SWITCH_TRAIT", trait: name });
7079
- }, []);
7080
- const [highlightedTrait, setHighlightedTrait] = React8__default.default.useState(null);
7081
- const handleTransitionClick = React8.useCallback((index, pos) => {
7082
- dispatch({ type: "ZOOM_INTO_TRANSITION", transitionIndex: index, targetPosition: pos });
7083
- }, []);
7084
- const handleBreadcrumbClick = React8.useCallback((targetLevel) => {
7085
- const levelOrder = ["application", "orbital", "trait", "transition"];
7086
- const currentIdx = levelOrder.indexOf(state.level);
7087
- const targetIdx = levelOrder.indexOf(targetLevel);
7088
- if (targetIdx < currentIdx) {
7089
- dispatch({ type: "ZOOM_OUT" });
7090
- }
7091
- }, [state.level]);
7092
- const sceneContent = React8.useMemo(() => {
7093
- switch (state.level) {
7094
- case "application": {
7095
- const data = parseApplicationLevel(schema);
7096
- return /* @__PURE__ */ jsxRuntime.jsx(
7097
- AvlApplicationScene,
7098
- {
7099
- data,
7100
- color,
7101
- onOrbitalClick: handleOrbitalClick
7102
- }
7103
- );
7104
- }
7105
- case "orbital": {
7106
- if (!state.selectedOrbital) return null;
7107
- const data = parseOrbitalLevel(schema, state.selectedOrbital);
7108
- if (!data) return null;
7109
- return /* @__PURE__ */ jsxRuntime.jsx(
7110
- AvlOrbitalScene,
7111
- {
7112
- data,
7113
- color,
7114
- highlightedTrait,
7115
- onTraitClick: handleTraitClick,
7116
- onTraitHighlight: setHighlightedTrait
7117
- }
7118
- );
7119
- }
7120
- case "trait": {
7121
- if (!state.selectedOrbital || !state.selectedTrait) return null;
7122
- const data = parseTraitLevel(schema, state.selectedOrbital, state.selectedTrait);
7123
- if (!data) return null;
7124
- return /* @__PURE__ */ jsxRuntime.jsx(
7125
- AvlTraitScene,
7126
- {
7127
- data,
7128
- color,
7129
- onTransitionClick: handleTransitionClick
7130
- }
7131
- );
7132
- }
7133
- case "transition": {
7134
- if (!state.selectedOrbital || !state.selectedTrait || state.selectedTransition === null) return null;
7135
- const data = parseTransitionLevel(schema, state.selectedOrbital, state.selectedTrait, state.selectedTransition);
7136
- if (!data) return null;
7137
- return /* @__PURE__ */ jsxRuntime.jsx(
7138
- AvlTransitionScene,
7139
- {
7140
- data,
7141
- color
7142
- }
7143
- );
7144
- }
7145
- default:
7146
- return null;
7147
- }
7148
- }, [state.level, state.selectedOrbital, state.selectedTrait, state.selectedTransition, schema, color, handleOrbitalClick, handleTraitClick, handleTransitionClick, highlightedTrait, setHighlightedTrait]);
7149
- const breadcrumbs = getBreadcrumbs(state);
7150
- return /* @__PURE__ */ jsxRuntime.jsxs(
7151
- Box,
7152
- {
7153
- className: `relative ${className ?? ""}`,
7154
- style: { width, height: typeof height === "number" ? `${height}px` : height },
7155
- onKeyDown: handleKeyDown,
7156
- tabIndex: 0,
7157
- children: [
7158
- /* @__PURE__ */ jsxRuntime.jsx(
7159
- HStack,
7160
- {
7161
- gap: "xs",
7162
- align: "center",
7163
- className: "absolute top-2 left-2 z-10 bg-surface/80 backdrop-blur rounded-md px-3 py-1.5",
7164
- children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
7165
- i > 0 && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "muted", className: "mx-1", children: "/" }),
7166
- i < breadcrumbs.length - 1 ? /* @__PURE__ */ jsxRuntime.jsx(
7167
- Box,
7168
- {
7169
- as: "span",
7170
- className: "cursor-pointer hover:underline",
7171
- onClick: () => handleBreadcrumbClick(crumb.level),
7172
- children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "muted", children: crumb.label })
7173
- }
7174
- ) : /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "primary", className: "font-bold", children: crumb.label })
7175
- ] }, crumb.level))
7176
- }
7177
- ),
7178
- state.level === "trait" && state.selectedOrbital && (() => {
7179
- const orbData = parseOrbitalLevel(schema, state.selectedOrbital);
7180
- if (!orbData || orbData.traits.length <= 1) return null;
7181
- return /* @__PURE__ */ jsxRuntime.jsx(
7182
- HStack,
7183
- {
7184
- gap: "xs",
7185
- align: "center",
7186
- className: "absolute top-2 right-2 z-10 bg-surface/80 backdrop-blur rounded-md px-1.5 py-1",
7187
- children: orbData.traits.map((t) => /* @__PURE__ */ jsxRuntime.jsx(
7188
- Box,
7189
- {
7190
- as: "button",
7191
- className: `px-2.5 py-1 rounded-md text-xs font-medium transition-all cursor-pointer border-none ${t.name === state.selectedTrait ? "bg-primary text-primary-foreground" : "bg-transparent text-muted-foreground hover:text-foreground hover:bg-surface"}`,
7192
- onClick: () => handleTraitSwitch(t.name),
7193
- children: t.name
7194
- },
7195
- t.name
7196
- ))
7197
- }
7198
- );
7199
- })(),
7200
- state.level !== "application" && /* @__PURE__ */ jsxRuntime.jsx(
7201
- Typography,
7202
- {
7203
- variant: "small",
7204
- color: "muted",
7205
- className: "absolute bottom-2 right-2 z-10 bg-surface/60 backdrop-blur rounded px-2 py-1",
7206
- children: "Press Esc to zoom out"
7207
- }
7208
- ),
7209
- /* @__PURE__ */ jsxRuntime.jsxs(
7210
- "svg",
7211
- {
7212
- viewBox: `0 0 ${VIEWBOX_W} ${VIEWBOX_H2}`,
7213
- xmlns: "http://www.w3.org/2000/svg",
7214
- className: "w-full h-full",
7215
- role: "img",
7216
- "aria-label": `${schema.name} orbital visualization - ${state.level} level`,
7217
- children: [
7218
- /* @__PURE__ */ jsxRuntime.jsx("g", { ref: sceneRef, style: transitionStyle, children: sceneContent }),
7219
- /* @__PURE__ */ jsxRuntime.jsx(AvlLegend, { level: state.level, color })
7220
- ]
7221
- }
7222
- )
7223
- ]
7224
- }
7225
- );
7226
- };
7227
- AvlCosmicZoom.displayName = "AvlCosmicZoom";
7170
+ AvlClickTarget.displayName = "AvlClickTarget";
7228
7171
 
7229
7172
  exports.AVL_FIELD_TYPE_SHAPES = AVL_FIELD_TYPE_SHAPES;
7230
7173
  exports.AVL_OPERATOR_COLORS = AVL_OPERATOR_COLORS;
7231
7174
  exports.AvlApplication = AvlApplication;
7232
- exports.AvlApplicationScene = AvlApplicationScene;
7175
+ exports.AvlBackwardEdge = AvlBackwardEdge;
7233
7176
  exports.AvlBehaviorGlyph = AvlBehaviorGlyph;
7234
7177
  exports.AvlBinding = AvlBinding;
7178
+ exports.AvlBindingEdge = AvlBindingEdge;
7235
7179
  exports.AvlBindingRef = AvlBindingRef;
7236
7180
  exports.AvlClickTarget = AvlClickTarget;
7237
7181
  exports.AvlClosedCircuit = AvlClosedCircuit;
@@ -7240,6 +7184,7 @@ exports.AvlEffect = AvlEffect;
7240
7184
  exports.AvlEmitListen = AvlEmitListen;
7241
7185
  exports.AvlEntity = AvlEntity;
7242
7186
  exports.AvlEvent = AvlEvent;
7187
+ exports.AvlEventWireEdge = AvlEventWireEdge;
7243
7188
  exports.AvlExprTree = AvlExprTree;
7244
7189
  exports.AvlField = AvlField;
7245
7190
  exports.AvlFieldType = AvlFieldType;
@@ -7247,9 +7192,10 @@ exports.AvlGuard = AvlGuard;
7247
7192
  exports.AvlLiteral = AvlLiteral;
7248
7193
  exports.AvlOperator = AvlOperator;
7249
7194
  exports.AvlOrbital = AvlOrbital;
7250
- exports.AvlOrbitalScene = AvlOrbitalScene;
7195
+ exports.AvlOrbitalNode = AvlOrbitalNode;
7251
7196
  exports.AvlOrbitalUnit = AvlOrbitalUnit;
7252
7197
  exports.AvlPage = AvlPage;
7198
+ exports.AvlPageEdge = AvlPageEdge;
7253
7199
  exports.AvlPersistence = AvlPersistence;
7254
7200
  exports.AvlSExpr = AvlSExpr;
7255
7201
  exports.AvlSlotMap = AvlSlotMap;
@@ -7259,15 +7205,29 @@ exports.AvlSwimLane = AvlSwimLane;
7259
7205
  exports.AvlTrait = AvlTrait;
7260
7206
  exports.AvlTraitScene = AvlTraitScene;
7261
7207
  exports.AvlTransition = AvlTransition;
7208
+ exports.AvlTransitionEdge = AvlTransitionEdge;
7262
7209
  exports.AvlTransitionLane = AvlTransitionLane;
7263
7210
  exports.AvlTransitionScene = AvlTransitionScene;
7211
+ exports.BehaviorView = BehaviorView;
7264
7212
  exports.CONNECTION_COLORS = CONNECTION_COLORS;
7265
7213
  exports.DOMAIN_COLORS = DOMAIN_COLORS;
7214
+ exports.DetailView = DetailView;
7266
7215
  exports.EFFECT_CATEGORY_COLORS = EFFECT_CATEGORY_COLORS;
7267
7216
  exports.EFFECT_TYPE_TO_CATEGORY = EFFECT_TYPE_TO_CATEGORY;
7217
+ exports.FlowCanvas = FlowCanvas;
7218
+ exports.MiniStateMachine = MiniStateMachine;
7219
+ exports.ModuleCard = ModuleCard;
7268
7220
  exports.STATE_COLORS = STATE_COLORS;
7221
+ exports.SystemNode = SystemNode;
7222
+ exports.ZOOM_BAND_THRESHOLDS = ZOOM_BAND_THRESHOLDS;
7223
+ exports.ZoomBandContext = ZoomBandContext;
7224
+ exports.ZoomBreadcrumb = ZoomBreadcrumb;
7225
+ exports.ZoomLegend = ZoomLegend;
7269
7226
  exports.arcPath = arcPath;
7227
+ exports.computeTraitLayout = computeTraitLayout;
7228
+ exports.computeZoomBand = computeZoomBand;
7270
7229
  exports.curveControlPoint = curveControlPoint;
7230
+ exports.edgePath = edgePath;
7271
7231
  exports.getStateRole = getStateRole;
7272
7232
  exports.gridPositions = gridPositions;
7273
7233
  exports.parseApplicationLevel = parseApplicationLevel;
@@ -7276,3 +7236,6 @@ exports.parseTraitLevel = parseTraitLevel;
7276
7236
  exports.parseTransitionLevel = parseTransitionLevel;
7277
7237
  exports.radialPositions = radialPositions;
7278
7238
  exports.ringPositions = ringPositions;
7239
+ exports.schemaToFlowGraph = schemaToFlowGraph;
7240
+ exports.useZoomBand = useZoomBand;
7241
+ exports.zoomProgress = zoomProgress;