@almadar/ui 2.52.0 → 2.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22132,6 +22132,26 @@ var CodeBlock = React125__namespace.default.memo(
22132
22132
  const codeRef = React125.useRef(null);
22133
22133
  const savedScrollLeftRef = React125.useRef(0);
22134
22134
  const [copied, setCopied] = React125.useState(false);
22135
+ const [editableValue, setEditableValue] = React125.useState(code);
22136
+ const [editableTextareaKey, setEditableTextareaKey] = React125.useState(0);
22137
+ const lastPropCodeRef = React125.useRef(code);
22138
+ const editableTextareaRef = React125.useRef(null);
22139
+ const editableOverlayRef = React125.useRef(null);
22140
+ React125.useEffect(() => {
22141
+ if (code !== lastPropCodeRef.current) {
22142
+ lastPropCodeRef.current = code;
22143
+ setEditableValue(code);
22144
+ setEditableTextareaKey((k) => k + 1);
22145
+ }
22146
+ }, [code]);
22147
+ const handleEditableScroll = React125.useCallback(() => {
22148
+ const ta = editableTextareaRef.current;
22149
+ const ov = editableOverlayRef.current;
22150
+ if (ta && ov) {
22151
+ ov.scrollTop = ta.scrollTop;
22152
+ ov.scrollLeft = ta.scrollLeft;
22153
+ }
22154
+ }, []);
22135
22155
  const isFoldable = foldableProp ?? (language === "orb" || language === "json");
22136
22156
  const [collapsed, setCollapsed] = React125.useState(() => /* @__PURE__ */ new Set());
22137
22157
  const foldRegions = React125.useMemo(
@@ -22292,33 +22312,106 @@ var CodeBlock = React125__namespace.default.memo(
22292
22312
  }
22293
22313
  ),
22294
22314
  editable ? (
22295
- /* GAP-51: editable mode composes the Textarea atom. Plain text editing,
22296
- no Prism highlighting overlay (follow-up). The textarea is uncontrolled
22297
- on the value side: we pass `code` as the initial value and forward
22298
- every keystroke via onChange the consumer is responsible for
22299
- debouncing and re-deriving `code` only after the user stops typing
22300
- so the cursor doesn't fight a re-render. */
22301
- /* @__PURE__ */ jsxRuntime.jsx(
22302
- Textarea,
22315
+ /* GAP-77: editable mode = transparent Textarea on top + Prism-highlighted
22316
+ overlay underneath. The textarea is uncontrolled (defaultValue + key)
22317
+ to avoid cursor jumps; the overlay reads `editableValue` which is
22318
+ mirrored from the textarea via onChange. Both elements share IDENTICAL
22319
+ font / line-height / padding so the highlighted text aligns with the
22320
+ textarea's invisible glyphs.
22321
+
22322
+ Scroll sync: the overlay has `pointer-events: none` and the textarea
22323
+ scrolls; `handleEditableScroll` keeps the overlay's scroll matched. */
22324
+ /* @__PURE__ */ jsxRuntime.jsxs(
22325
+ Box,
22303
22326
  {
22304
- defaultValue: code,
22305
- onChange: (e) => onChange?.(e.target.value),
22306
- spellCheck: false,
22307
22327
  style: {
22308
- fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
22309
- fontSize: "13px",
22310
- lineHeight: "1.5",
22328
+ position: "relative",
22311
22329
  backgroundColor: "#1e1e1e",
22312
- color: "#e6e6e6",
22313
22330
  borderRadius: hasHeader ? "0 0 0.5rem 0.5rem" : "0.5rem",
22314
- border: "none",
22315
- padding: "1rem",
22316
- resize: "none",
22317
22331
  minHeight: "160px",
22318
22332
  maxHeight,
22319
- width: "100%",
22320
- outline: "none"
22321
- }
22333
+ overflow: "hidden"
22334
+ },
22335
+ children: [
22336
+ /* @__PURE__ */ jsxRuntime.jsx(
22337
+ "div",
22338
+ {
22339
+ ref: editableOverlayRef,
22340
+ "aria-hidden": true,
22341
+ style: {
22342
+ position: "absolute",
22343
+ inset: 0,
22344
+ overflow: "hidden",
22345
+ pointerEvents: "none",
22346
+ maxHeight
22347
+ },
22348
+ children: /* @__PURE__ */ jsxRuntime.jsx(
22349
+ SyntaxHighlighter__default.default,
22350
+ {
22351
+ PreTag: "div",
22352
+ language,
22353
+ style: activeStyle,
22354
+ customStyle: {
22355
+ backgroundColor: "transparent",
22356
+ borderRadius: 0,
22357
+ padding: "1rem",
22358
+ margin: 0,
22359
+ whiteSpace: "pre",
22360
+ minWidth: "100%",
22361
+ minHeight: "160px",
22362
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
22363
+ fontSize: "13px",
22364
+ lineHeight: "1.5"
22365
+ },
22366
+ codeTagProps: {
22367
+ style: {
22368
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
22369
+ fontSize: "13px",
22370
+ lineHeight: "1.5"
22371
+ }
22372
+ },
22373
+ children: editableValue || " "
22374
+ }
22375
+ )
22376
+ }
22377
+ ),
22378
+ /* @__PURE__ */ jsxRuntime.jsx(
22379
+ Textarea,
22380
+ {
22381
+ ref: editableTextareaRef,
22382
+ defaultValue: code,
22383
+ onChange: (e) => {
22384
+ setEditableValue(e.target.value);
22385
+ onChange?.(e.target.value);
22386
+ },
22387
+ onScroll: handleEditableScroll,
22388
+ spellCheck: false,
22389
+ style: {
22390
+ position: "relative",
22391
+ zIndex: 1,
22392
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
22393
+ fontSize: "13px",
22394
+ lineHeight: "1.5",
22395
+ backgroundColor: "transparent",
22396
+ color: "transparent",
22397
+ caretColor: "#e6e6e6",
22398
+ borderRadius: hasHeader ? "0 0 0.5rem 0.5rem" : "0.5rem",
22399
+ border: "none",
22400
+ padding: "1rem",
22401
+ resize: "none",
22402
+ minHeight: "160px",
22403
+ maxHeight,
22404
+ width: "100%",
22405
+ height: "100%",
22406
+ outline: "none",
22407
+ whiteSpace: "pre",
22408
+ overflowWrap: "normal",
22409
+ overflow: "auto"
22410
+ }
22411
+ },
22412
+ editableTextareaKey
22413
+ )
22414
+ ]
22322
22415
  }
22323
22416
  )
22324
22417
  ) : /* @__PURE__ */ jsxRuntime.jsx(
@@ -48449,7 +48542,7 @@ function OrbInspector({ node, schema, editable = false, onSchemaChange, onClose
48449
48542
  onBlur: (e) => handlePropChange(propName, e.target.value)
48450
48543
  }
48451
48544
  ) : /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", className: "text-[11px] text-muted-foreground", children: [
48452
- displayValue || (ps.types?.join(" | ") ?? "string"),
48545
+ displayValue || "\u2014",
48453
48546
  ps.required ? " *" : ""
48454
48547
  ] })
48455
48548
  ] }, propName);
@@ -49140,545 +49233,103 @@ AvlCosmicZoom.displayName = "AvlCosmicZoom";
49140
49233
 
49141
49234
  // components/organisms/avl/AvlOrbitalsCosmicZoom.tsx
49142
49235
  init_avl_schema_parser();
49143
- init_Box();
49144
- init_Typography();
49145
- var UNIT_DISPLAY_W = 240;
49146
- var UNIT_DISPLAY_H = 160;
49147
- function layoutOrbitals(count, containerW, containerH) {
49148
- if (count === 0) return [];
49149
- if (count === 1) return [{ cx: containerW / 2, cy: containerH / 2 }];
49150
- const cols = Math.min(count, Math.ceil(Math.sqrt(count)));
49151
- const rows = Math.ceil(count / cols);
49152
- const cellW = containerW / (cols + 0.3);
49153
- const cellH = containerH / (rows + 0.3);
49154
- const originX = (containerW - cols * cellW) / 2 + cellW / 2;
49155
- const originY = (containerH - rows * cellH) / 2 + cellH / 2;
49156
- return Array.from({ length: count }, (_, i) => ({
49157
- cx: originX + i % cols * cellW,
49158
- cy: originY + Math.floor(i / cols) * cellH
49159
- }));
49160
- }
49161
- var avlOczWireId = 0;
49162
- var EventWireOverlay = ({
49163
- orbitalViews,
49164
- crossLinks,
49165
- color,
49166
- animated,
49167
- containerW,
49168
- containerH
49236
+ init_avl_zoom_state();
49237
+ init_types();
49238
+ var SWIM_GUTTER2 = 120;
49239
+ var CENTER_W2 = 360;
49240
+ var AvlTraitScene = ({
49241
+ data,
49242
+ color = "var(--color-primary)",
49243
+ onTransitionClick
49169
49244
  }) => {
49170
- const ids = React125__namespace.default.useMemo(() => {
49171
- avlOczWireId += 1;
49172
- return { arrow: `avl-ocz-wire-${avlOczWireId}-arrow` };
49173
- }, []);
49174
- const posMap = React125.useMemo(() => {
49175
- const m = /* @__PURE__ */ new Map();
49176
- for (const ov of orbitalViews) m.set(ov.name, { cx: ov.cx, cy: ov.cy });
49177
- return m;
49178
- }, [orbitalViews]);
49179
- const wiresByPair = React125.useMemo(() => {
49180
- const map = /* @__PURE__ */ new Map();
49181
- for (const link of crossLinks) {
49182
- const key = `${link.emitterOrbital}__${link.listenerOrbital}`;
49183
- const arr = map.get(key) ?? [];
49184
- arr.push(link);
49185
- map.set(key, arr);
49186
- }
49187
- return map;
49188
- }, [crossLinks]);
49189
- const orbitalR = UNIT_DISPLAY_W * 0.38;
49190
- return /* @__PURE__ */ jsxRuntime.jsxs(
49191
- "svg",
49192
- {
49193
- style: {
49194
- position: "absolute",
49195
- inset: 0,
49196
- width: "100%",
49197
- height: "100%",
49198
- pointerEvents: "none",
49199
- overflow: "visible"
49200
- },
49201
- viewBox: `0 0 ${containerW} ${containerH}`,
49202
- preserveAspectRatio: "xMidYMid meet",
49203
- children: [
49204
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
49205
- "marker",
49206
- {
49207
- id: ids.arrow,
49208
- markerWidth: "8",
49209
- markerHeight: "6",
49210
- refX: "7",
49211
- refY: "3",
49212
- orient: "auto",
49213
- markerUnits: "strokeWidth",
49214
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0,0 L8,3 L0,6 Z", fill: color, opacity: 0.6 })
49215
- }
49216
- ) }),
49217
- animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
49218
- @keyframes avl-ocz-flow {
49219
- from { stroke-dashoffset: 20; }
49220
- to { stroke-dashoffset: 0; }
49221
- }
49222
- ` }),
49223
- Array.from(wiresByPair.entries()).map(
49224
- ([pairKey, links]) => links.map((link, wireIdx) => {
49225
- const fromPos = posMap.get(link.emitterOrbital);
49226
- const toPos = posMap.get(link.listenerOrbital);
49227
- if (!fromPos || !toPos) return null;
49228
- const dx = toPos.cx - fromPos.cx;
49229
- const dy = toPos.cy - fromPos.cy;
49230
- const dist = Math.sqrt(dx * dx + dy * dy) || 1;
49231
- const nx = dx / dist;
49232
- const ny = dy / dist;
49233
- const x1 = fromPos.cx + nx * orbitalR;
49234
- const y1 = fromPos.cy + ny * orbitalR;
49235
- const x2 = toPos.cx - nx * (orbitalR + 6);
49236
- const y2 = toPos.cy - ny * (orbitalR + 6);
49237
- const offset = 25 + wireIdx * 18;
49238
- const { cpx, cpy } = curveControlPoint(x1, y1, x2, y2, offset);
49239
- const pathD = `M${x1},${y1} Q${cpx},${cpy} ${x2},${y2}`;
49240
- const t = 0.5;
49241
- const lx = (1 - t) * (1 - t) * x1 + 2 * (1 - t) * t * cpx + t * t * x2;
49242
- const ly = (1 - t) * (1 - t) * y1 + 2 * (1 - t) * t * cpy + t * t * y2;
49243
- const labelW = link.eventName.length * 5.5 + 12;
49244
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49245
- /* @__PURE__ */ jsxRuntime.jsx(
49246
- "path",
49247
- {
49248
- d: pathD,
49249
- fill: "none",
49250
- stroke: color,
49251
- strokeWidth: 1.2,
49252
- strokeDasharray: animated ? "6 4" : "4 3",
49253
- markerEnd: `url(#${ids.arrow})`,
49254
- opacity: 0.5,
49255
- style: animated ? { animation: "avl-ocz-flow 1.5s linear infinite" } : void 0
49256
- }
49257
- ),
49258
- /* @__PURE__ */ jsxRuntime.jsx(
49259
- "rect",
49260
- {
49261
- x: lx - labelW / 2,
49262
- y: ly - 8,
49263
- width: labelW,
49264
- height: 14,
49265
- rx: 3,
49266
- fill: "var(--color-background, #fff)",
49267
- stroke: color,
49268
- strokeWidth: 0.5,
49269
- opacity: 0.9
49270
- }
49271
- ),
49272
- /* @__PURE__ */ jsxRuntime.jsx(
49273
- "text",
49274
- {
49275
- x: lx,
49276
- y: ly + 3,
49277
- textAnchor: "middle",
49278
- fill: color,
49279
- fontSize: 7,
49280
- fontWeight: 600,
49281
- fontFamily: "monospace",
49282
- opacity: 0.8,
49283
- children: link.eventName
49284
- }
49285
- )
49286
- ] }, `${pairKey}-${wireIdx}`);
49287
- })
49288
- )
49289
- ]
49290
- }
49291
- );
49292
- };
49293
- var InfoPanel = ({ view, crossLinks, color }) => {
49294
- const emitsOut = crossLinks.filter((l) => l.emitterOrbital === view.name);
49295
- const listensIn = crossLinks.filter((l) => l.listenerOrbital === view.name);
49296
- return /* @__PURE__ */ jsxRuntime.jsxs(
49297
- Box,
49298
- {
49299
- position: "absolute",
49300
- rounded: "lg",
49301
- paddingX: "md",
49302
- paddingY: "sm",
49303
- bg: "overlay",
49304
- style: {
49305
- left: view.cx - 120,
49306
- top: view.cy + UNIT_DISPLAY_H / 2 + 4,
49307
- width: 240,
49308
- border: `1px solid ${color}`,
49309
- zIndex: 20,
49310
- pointerEvents: "none"
49311
- },
49312
- children: [
49313
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { weight: "semibold", style: { marginBottom: 4, color }, children: view.name }),
49314
- /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "small", style: { opacity: 0.7, color }, children: [
49315
- "Entity: ",
49316
- view.entityName,
49317
- " (",
49318
- view.fieldCount,
49319
- " fields, ",
49320
- view.persistence,
49321
- ")"
49322
- ] }),
49323
- /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "small", style: { opacity: 0.7, color }, children: [
49324
- "Traits: ",
49325
- view.traits.map((t) => t.name).join(", ") || "none"
49326
- ] }),
49327
- view.pages.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "small", style: { opacity: 0.7, color }, children: [
49328
- "Pages: ",
49329
- view.pages.map((p2) => p2.name).join(", ")
49330
- ] }),
49331
- emitsOut.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "small", style: { opacity: 0.7, color }, children: [
49332
- "Emits \u2192 ",
49333
- emitsOut.map((l) => `${l.eventName} \u2192 ${l.listenerOrbital}`).join(", ")
49334
- ] }),
49335
- listensIn.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "small", style: { opacity: 0.7, color }, children: [
49336
- "Listens \u2190 ",
49337
- listensIn.map((l) => `${l.eventName} \u2190 ${l.emitterOrbital}`).join(", ")
49338
- ] })
49339
- ]
49340
- }
49341
- );
49342
- };
49343
- var AvlOrbitalsCosmicZoom = ({
49344
- schema: schemaProp,
49345
- className,
49346
- color = "var(--color-primary, #4A90D9)",
49347
- animated = true,
49348
- width = "100%",
49349
- height = 450,
49350
- highlightedOrbital,
49351
- onOrbitalSelect,
49352
- minZoom = 0.4,
49353
- maxZoom = 3
49354
- }) => {
49355
- const parsedSchema = React125.useMemo(() => {
49356
- if (typeof schemaProp === "string") return JSON.parse(schemaProp);
49357
- return schemaProp;
49358
- }, [schemaProp]);
49359
- const { orbitals, crossLinks } = React125.useMemo(
49360
- () => parseApplicationLevel(parsedSchema),
49361
- [parsedSchema]
49362
- );
49363
- const containerW = typeof width === "number" ? width : 800;
49364
- const containerH = typeof height === "number" ? height : 450;
49365
- const positions = React125.useMemo(
49366
- () => layoutOrbitals(orbitals.length, containerW, containerH),
49367
- [orbitals.length, containerW, containerH]
49368
- );
49369
- const orbitalViews = React125.useMemo(
49370
- () => orbitals.map((o, i) => ({
49371
- name: o.name,
49372
- entityName: o.entityName,
49373
- fieldCount: o.fieldCount,
49374
- persistence: o.persistence || "persistent",
49375
- traits: o.traitNames.map((n) => ({ name: n })),
49376
- pages: o.pageNames.map((n) => ({ name: n })),
49377
- cx: positions[i]?.cx ?? 0,
49378
- cy: positions[i]?.cy ?? 0
49379
- })),
49380
- [orbitals, positions]
49381
- );
49382
- const [selected, setSelected] = React125.useState(null);
49383
- const handleSelect = React125.useCallback(
49384
- (name) => {
49385
- setSelected((prev) => prev === name ? null : name);
49386
- onOrbitalSelect?.(name);
49387
- },
49388
- [onOrbitalSelect]
49389
- );
49390
- const selectedView = orbitalViews.find((o) => o.name === selected);
49391
- const [zoom, setZoom] = React125.useState(1);
49392
- const [pan, setPan] = React125.useState({ x: 0, y: 0 });
49393
- const dragStateRef = React125.useRef(null);
49394
- const transformWrapperRef = React125.useRef(null);
49395
- const clampZoom = React125.useCallback(
49396
- (z) => Math.max(minZoom, Math.min(maxZoom, z)),
49397
- [minZoom, maxZoom]
49398
- );
49399
- const handlePointerDown = React125.useCallback((e) => {
49400
- if (e.target.closest("[data-orbital-tile]")) return;
49401
- dragStateRef.current = {
49402
- startX: e.clientX,
49403
- startY: e.clientY,
49404
- panX: pan.x,
49405
- panY: pan.y
49406
- };
49407
- e.target.setPointerCapture(e.pointerId);
49408
- }, [pan]);
49409
- const handlePointerMove = React125.useCallback((e) => {
49410
- const drag = dragStateRef.current;
49411
- if (!drag) return;
49412
- setPan({
49413
- x: drag.panX + (e.clientX - drag.startX),
49414
- y: drag.panY + (e.clientY - drag.startY)
49415
- });
49416
- }, []);
49417
- const handlePointerUp = React125.useCallback((e) => {
49418
- if (!dragStateRef.current) return;
49419
- dragStateRef.current = null;
49420
- try {
49421
- e.target.releasePointerCapture(e.pointerId);
49422
- } catch {
49423
- }
49424
- }, []);
49425
- const panRef = React125.useRef(pan);
49426
- const zoomRef = React125.useRef(zoom);
49427
- React125.useEffect(() => {
49428
- panRef.current = pan;
49429
- }, [pan]);
49430
- React125.useEffect(() => {
49431
- zoomRef.current = zoom;
49432
- }, [zoom]);
49433
- React125.useEffect(() => {
49434
- const wrapper = transformWrapperRef.current;
49435
- if (!wrapper) return;
49436
- const wheelListener = (e) => {
49437
- e.preventDefault();
49438
- const rect = wrapper.getBoundingClientRect();
49439
- const cursorX = e.clientX - rect.left;
49440
- const cursorY = e.clientY - rect.top;
49441
- const currentZoom = zoomRef.current;
49442
- const currentPan = panRef.current;
49443
- const worldX = (cursorX - currentPan.x) / currentZoom;
49444
- const worldY = (cursorY - currentPan.y) / currentZoom;
49445
- const delta = e.deltaY > 0 ? -0.1 : 0.1;
49446
- const nextZoom = clampZoom(currentZoom * (1 + delta));
49447
- const nextPanX = cursorX - worldX * nextZoom;
49448
- const nextPanY = cursorY - worldY * nextZoom;
49449
- setZoom(nextZoom);
49450
- setPan({ x: nextPanX, y: nextPanY });
49451
- };
49452
- wrapper.addEventListener("wheel", wheelListener, { passive: false });
49453
- return () => wrapper.removeEventListener("wheel", wheelListener);
49454
- }, [clampZoom]);
49455
- const zoomIn = React125.useCallback(() => setZoom((z) => clampZoom(z * 1.2)), [clampZoom]);
49456
- const zoomOut = React125.useCallback(() => setZoom((z) => clampZoom(z / 1.2)), [clampZoom]);
49457
- const resetZoom = React125.useCallback(() => {
49458
- setZoom(1);
49459
- setPan({ x: 0, y: 0 });
49460
- }, []);
49461
- return /* @__PURE__ */ jsxRuntime.jsxs(
49462
- Box,
49463
- {
49464
- className,
49465
- position: "relative",
49466
- overflow: "visible",
49467
- style: { width, height: containerH },
49468
- children: [
49469
- /* @__PURE__ */ jsxRuntime.jsx(
49470
- "div",
49471
- {
49472
- ref: transformWrapperRef,
49473
- onPointerDown: handlePointerDown,
49474
- onPointerMove: handlePointerMove,
49475
- onPointerUp: handlePointerUp,
49476
- onPointerCancel: handlePointerUp,
49477
- style: {
49478
- position: "absolute",
49479
- inset: 0,
49480
- overflow: "hidden",
49481
- cursor: dragStateRef.current ? "grabbing" : "grab",
49482
- touchAction: "none"
49483
- },
49484
- children: /* @__PURE__ */ jsxRuntime.jsxs(
49485
- "div",
49486
- {
49487
- style: {
49488
- position: "absolute",
49489
- inset: 0,
49490
- transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,
49491
- transformOrigin: "0 0"
49492
- },
49493
- children: [
49494
- /* @__PURE__ */ jsxRuntime.jsx(
49495
- EventWireOverlay,
49496
- {
49497
- orbitalViews,
49498
- crossLinks,
49499
- color,
49500
- animated,
49501
- containerW,
49502
- containerH
49503
- }
49504
- ),
49505
- orbitalViews.map((view) => {
49506
- const isHighlighted = view.name === highlightedOrbital;
49507
- return /* @__PURE__ */ jsxRuntime.jsx(
49508
- Box,
49509
- {
49510
- role: "button",
49511
- tabIndex: 0,
49512
- "data-orbital-tile": "true",
49513
- onClick: () => handleSelect(view.name),
49514
- onKeyDown: (e) => {
49515
- if (e.key === "Enter" || e.key === " ") handleSelect(view.name);
49516
- },
49517
- "aria-label": `Orbital: ${view.name}${isHighlighted ? " (highlighted)" : ""}`,
49518
- position: "absolute",
49519
- style: {
49520
- left: view.cx - UNIT_DISPLAY_W / 2,
49521
- top: view.cy - UNIT_DISPLAY_H / 2,
49522
- width: UNIT_DISPLAY_W,
49523
- height: UNIT_DISPLAY_H,
49524
- cursor: "pointer",
49525
- transition: "transform 0.2s ease, filter 0.2s ease, box-shadow 0.3s ease",
49526
- transform: selected === view.name ? "scale(1.05)" : "scale(1)",
49527
- filter: selected && selected !== view.name ? "opacity(0.5)" : "none",
49528
- // GAP-52: persistent highlight ring (independent from user selection)
49529
- boxShadow: isHighlighted ? `0 0 0 3px ${color}, 0 0 24px 4px ${color}` : "none",
49530
- borderRadius: isHighlighted ? "12px" : void 0,
49531
- zIndex: isHighlighted ? 11 : selected === view.name ? 10 : 1
49532
- },
49533
- children: /* @__PURE__ */ jsxRuntime.jsx(
49534
- AvlOrbitalUnit,
49535
- {
49536
- entityName: view.entityName,
49537
- fields: view.fieldCount,
49538
- persistence: view.persistence,
49539
- traits: view.traits,
49540
- pages: view.pages,
49541
- color,
49542
- animated: animated && (selected === view.name || isHighlighted)
49543
- }
49544
- )
49545
- },
49546
- view.name
49547
- );
49548
- }),
49549
- selectedView && /* @__PURE__ */ jsxRuntime.jsx(
49550
- InfoPanel,
49551
- {
49552
- view: selectedView,
49553
- crossLinks,
49554
- color
49555
- }
49556
- )
49557
- ]
49558
- }
49559
- )
49560
- }
49561
- ),
49562
- /* @__PURE__ */ jsxRuntime.jsxs(
49563
- Box,
49564
- {
49565
- position: "absolute",
49566
- style: {
49567
- top: 12,
49568
- right: 12,
49569
- display: "flex",
49570
- flexDirection: "column",
49571
- gap: 4,
49572
- zIndex: 30
49573
- },
49574
- children: [
49575
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "sm", onClick: zoomIn, title: "Zoom in", action: "COSMIC_ZOOM_IN", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "plus", size: "sm" }) }),
49576
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "sm", onClick: zoomOut, title: "Zoom out", action: "COSMIC_ZOOM_OUT", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "minus", size: "sm" }) }),
49577
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "sm", onClick: resetZoom, title: "Reset", action: "COSMIC_ZOOM_RESET", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "maximize", size: "sm" }) })
49578
- ]
49579
- }
49580
- )
49581
- ]
49582
- }
49583
- );
49584
- };
49585
- AvlOrbitalsCosmicZoom.displayName = "AvlOrbitalsCosmicZoom";
49586
- init_types();
49587
- var SWIM_GUTTER2 = 120;
49588
- var CENTER_W2 = 360;
49589
- var AvlTraitScene = ({
49590
- data,
49591
- color = "var(--color-primary)",
49592
- onTransitionClick
49593
- }) => {
49594
- const [layout, setLayout] = React125.useState(null);
49595
- const dataKey = React125.useMemo(() => JSON.stringify(data), [data]);
49596
- React125.useEffect(() => {
49597
- computeTraitLayout(data).then(setLayout).catch(console.error);
49598
- }, [dataKey]);
49599
- if (!layout) {
49600
- 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..." }) });
49601
- }
49602
- const hasExternal = data.listenedEvents.length > 0 || data.emittedEvents.length > 0;
49603
- const machineOffsetX = hasExternal ? 0 : 30;
49604
- const padding = 20;
49605
- const availW = CENTER_W2 - padding * 2;
49606
- const availH = 300;
49607
- const scale = Math.min(1, availW / layout.width, availH / layout.height);
49608
- const scaledW = layout.width * scale;
49609
- const scaledH = layout.height * scale;
49610
- const offsetX = padding + (availW - scaledW) / 2;
49611
- const offsetY = 50 + (availH - scaledH) / 2;
49612
- const machineHeight = scaledH + 100;
49613
- const renderMachine = /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49614
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: CENTER_W2 / 2, y: 20, textAnchor: "middle", fill: color, fontSize: 20, fontWeight: "700", fontFamily: "inherit", children: data.name }),
49615
- /* @__PURE__ */ jsxRuntime.jsxs("text", { x: CENTER_W2 / 2, y: 38, textAnchor: "middle", fill: color, fontSize: 11, opacity: 0.5, fontFamily: "inherit", children: [
49616
- "linked to ",
49617
- data.linkedEntity
49618
- ] }),
49619
- /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
49620
- /* @__PURE__ */ jsxRuntime.jsx("marker", { id: "traitArrowV2", 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: exports.CONNECTION_COLORS.forward.color, opacity: 0.7 }) }),
49621
- /* @__PURE__ */ jsxRuntime.jsx("marker", { id: "traitArrowBack", 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: exports.CONNECTION_COLORS.backward.color, opacity: 0.5 }) })
49622
- ] }),
49623
- /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${offsetX},${offsetY}) scale(${scale})`, children: [
49624
- layout.edges.map((edge) => {
49625
- const conn = edge.isSelf ? exports.CONNECTION_COLORS.selfLoop : edge.isBackward ? exports.CONNECTION_COLORS.backward : exports.CONNECTION_COLORS.forward;
49626
- const marker = edge.isBackward || edge.isSelf ? "url(#traitArrowBack)" : "url(#traitArrowV2)";
49627
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49628
- /* @__PURE__ */ jsxRuntime.jsx(
49629
- "path",
49630
- {
49631
- d: edgePath(edge.points),
49632
- fill: "none",
49633
- stroke: conn.color,
49634
- strokeWidth: conn.width,
49635
- strokeDasharray: conn.dash === "none" ? void 0 : conn.dash,
49636
- opacity: 0.5,
49637
- markerEnd: marker
49638
- }
49639
- ),
49640
- /* @__PURE__ */ jsxRuntime.jsx(
49641
- AvlTransitionLane,
49642
- {
49643
- x: edge.labelX,
49644
- y: edge.labelY,
49645
- event: edge.event,
49646
- guard: edge.guardExpr,
49647
- effects: edge.effects.map((e) => ({ type: e.type })),
49648
- width: edge.labelW,
49649
- isBackward: edge.isBackward,
49650
- isSelfLoop: edge.isSelf,
49651
- color,
49652
- onTransitionClick: onTransitionClick ? () => onTransitionClick(edge.index, {
49653
- x: edge.labelX + offsetX + (hasExternal ? SWIM_GUTTER2 : machineOffsetX),
49654
- y: edge.labelY + offsetY
49655
- }) : void 0
49656
- }
49657
- )
49658
- ] }, edge.id);
49659
- }),
49660
- layout.nodes.map((node) => /* @__PURE__ */ jsxRuntime.jsx("g", { children: /* @__PURE__ */ jsxRuntime.jsx(
49661
- AvlState,
49662
- {
49663
- x: node.x,
49664
- y: node.y,
49665
- width: node.width,
49666
- height: node.height,
49667
- name: node.id,
49668
- isInitial: node.isInitial,
49669
- isTerminal: node.isTerminal,
49670
- role: node.role,
49671
- transitionCount: node.transitionCount,
49672
- color
49673
- }
49674
- ) }, node.id))
49675
- ] })
49676
- ] });
49677
- if (!hasExternal) {
49678
- return /* @__PURE__ */ jsxRuntime.jsx("g", { transform: `translate(${machineOffsetX}, 0)`, children: renderMachine });
49679
- }
49680
- return /* @__PURE__ */ jsxRuntime.jsx(
49681
- AvlSwimLane,
49245
+ const [layout, setLayout] = React125.useState(null);
49246
+ const dataKey = React125.useMemo(() => JSON.stringify(data), [data]);
49247
+ React125.useEffect(() => {
49248
+ computeTraitLayout(data).then(setLayout).catch(console.error);
49249
+ }, [dataKey]);
49250
+ if (!layout) {
49251
+ 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..." }) });
49252
+ }
49253
+ const hasExternal = data.listenedEvents.length > 0 || data.emittedEvents.length > 0;
49254
+ const machineOffsetX = hasExternal ? 0 : 30;
49255
+ const padding = 20;
49256
+ const availW = CENTER_W2 - padding * 2;
49257
+ const availH = 300;
49258
+ const scale = Math.min(1, availW / layout.width, availH / layout.height);
49259
+ const scaledW = layout.width * scale;
49260
+ const scaledH = layout.height * scale;
49261
+ const offsetX = padding + (availW - scaledW) / 2;
49262
+ const offsetY = 50 + (availH - scaledH) / 2;
49263
+ const machineHeight = scaledH + 100;
49264
+ const renderMachine = /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49265
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: CENTER_W2 / 2, y: 20, textAnchor: "middle", fill: color, fontSize: 20, fontWeight: "700", fontFamily: "inherit", children: data.name }),
49266
+ /* @__PURE__ */ jsxRuntime.jsxs("text", { x: CENTER_W2 / 2, y: 38, textAnchor: "middle", fill: color, fontSize: 11, opacity: 0.5, fontFamily: "inherit", children: [
49267
+ "linked to ",
49268
+ data.linkedEntity
49269
+ ] }),
49270
+ /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
49271
+ /* @__PURE__ */ jsxRuntime.jsx("marker", { id: "traitArrowV2", 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: exports.CONNECTION_COLORS.forward.color, opacity: 0.7 }) }),
49272
+ /* @__PURE__ */ jsxRuntime.jsx("marker", { id: "traitArrowBack", 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: exports.CONNECTION_COLORS.backward.color, opacity: 0.5 }) })
49273
+ ] }),
49274
+ /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${offsetX},${offsetY}) scale(${scale})`, children: [
49275
+ layout.edges.map((edge) => {
49276
+ const conn = edge.isSelf ? exports.CONNECTION_COLORS.selfLoop : edge.isBackward ? exports.CONNECTION_COLORS.backward : exports.CONNECTION_COLORS.forward;
49277
+ const marker = edge.isBackward || edge.isSelf ? "url(#traitArrowBack)" : "url(#traitArrowV2)";
49278
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49279
+ /* @__PURE__ */ jsxRuntime.jsx(
49280
+ "path",
49281
+ {
49282
+ d: edgePath(edge.points),
49283
+ fill: "none",
49284
+ stroke: conn.color,
49285
+ strokeWidth: conn.width,
49286
+ strokeDasharray: conn.dash === "none" ? void 0 : conn.dash,
49287
+ opacity: 0.5,
49288
+ markerEnd: marker
49289
+ }
49290
+ ),
49291
+ /* @__PURE__ */ jsxRuntime.jsx(
49292
+ AvlTransitionLane,
49293
+ {
49294
+ x: edge.labelX,
49295
+ y: edge.labelY,
49296
+ event: edge.event,
49297
+ guard: edge.guardExpr,
49298
+ effects: edge.effects.map((e) => ({ type: e.type })),
49299
+ width: edge.labelW,
49300
+ isBackward: edge.isBackward,
49301
+ isSelfLoop: edge.isSelf,
49302
+ color,
49303
+ onTransitionClick: onTransitionClick ? () => onTransitionClick(edge.index, {
49304
+ x: edge.labelX + offsetX + (hasExternal ? SWIM_GUTTER2 : machineOffsetX),
49305
+ y: edge.labelY + offsetY
49306
+ }) : void 0
49307
+ }
49308
+ )
49309
+ ] }, edge.id);
49310
+ }),
49311
+ layout.nodes.map((node) => /* @__PURE__ */ jsxRuntime.jsx("g", { children: /* @__PURE__ */ jsxRuntime.jsx(
49312
+ AvlState,
49313
+ {
49314
+ x: node.x,
49315
+ y: node.y,
49316
+ width: node.width,
49317
+ height: node.height,
49318
+ name: node.id,
49319
+ isInitial: node.isInitial,
49320
+ isTerminal: node.isTerminal,
49321
+ role: node.role,
49322
+ transitionCount: node.transitionCount,
49323
+ color
49324
+ }
49325
+ ) }, node.id))
49326
+ ] })
49327
+ ] });
49328
+ if (!hasExternal) {
49329
+ return /* @__PURE__ */ jsxRuntime.jsx("g", { transform: `translate(${machineOffsetX}, 0)`, children: renderMachine });
49330
+ }
49331
+ return /* @__PURE__ */ jsxRuntime.jsx(
49332
+ AvlSwimLane,
49682
49333
  {
49683
49334
  listenedEvents: data.listenedEvents,
49684
49335
  emittedEvents: data.emittedEvents,
@@ -49873,63 +49524,670 @@ var AvlTransitionScene = ({
49873
49524
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49874
49525
  /* @__PURE__ */ jsxRuntime.jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: "GUARD" }),
49875
49526
  /* @__PURE__ */ jsxRuntime.jsx(
49876
- "polygon",
49527
+ "polygon",
49528
+ {
49529
+ points: `${CONTENT_LEFT + 6},${secY + 22} ${CONTENT_LEFT + 2},${secY + 26} ${CONTENT_LEFT + 6},${secY + 30} ${CONTENT_LEFT + 10},${secY + 26}`,
49530
+ fill: "none",
49531
+ stroke: color,
49532
+ strokeWidth: 1,
49533
+ opacity: 0.5
49534
+ }
49535
+ ),
49536
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: CONTENT_LEFT + 18, y: secY + 29, fill: color, fontSize: 12, fontWeight: 400, opacity: 0.6, fontFamily: "inherit", children: data.guard.label })
49537
+ ] });
49538
+ })(),
49539
+ hasEffects && (() => {
49540
+ const secY = cardY + headerH + sectionGap + triggerH + guardH;
49541
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49542
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: "EFFECTS" }),
49543
+ effects.map((eff, i) => {
49544
+ const rowY = secY + 22 + i * effectRowH;
49545
+ const effectType = mapEffectType(eff.type);
49546
+ const argsText = eff.args.length > 0 ? eff.args.join(" \xB7 ") : "";
49547
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49548
+ /* @__PURE__ */ jsxRuntime.jsx(
49549
+ AvlEffect,
49550
+ {
49551
+ x: CONTENT_LEFT + 10,
49552
+ y: rowY + 6,
49553
+ effectType,
49554
+ size: 10,
49555
+ showBackground: true
49556
+ }
49557
+ ),
49558
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: CONTENT_LEFT + 28, y: rowY + 10, fill: color, fontSize: 12, fontWeight: 500, opacity: 0.8, fontFamily: "inherit", children: eff.type }),
49559
+ argsText && /* @__PURE__ */ jsxRuntime.jsx("text", { x: CONTENT_LEFT + 28 + eff.type.length * 7 + 8, y: rowY + 10, fill: color, fontSize: 10, fontWeight: 400, opacity: 0.5, fontFamily: "monospace", children: argsText })
49560
+ ] }, `eff-${i}`);
49561
+ })
49562
+ ] });
49563
+ })(),
49564
+ hasSlots && (() => {
49565
+ const secY = cardY + headerH + sectionGap + triggerH + guardH + effectsH;
49566
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49567
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: "SLOTS" }),
49568
+ data.slotTargets.map((slot, i) => {
49569
+ const rowY = secY + 22 + i * 22;
49570
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49571
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: CONTENT_LEFT, y: rowY - 4, width: CARD_W - 56, height: 18, rx: 4, fill: color, fillOpacity: 0.04 }),
49572
+ /* @__PURE__ */ jsxRuntime.jsxs("text", { x: CONTENT_LEFT + 8, y: rowY + 8, fill: color, fontSize: 11, fontFamily: "inherit", children: [
49573
+ slot.name,
49574
+ ": ",
49575
+ slot.pattern
49576
+ ] })
49577
+ ] }, `slot-${i}`);
49578
+ })
49579
+ ] });
49580
+ })()
49581
+ ] });
49582
+ };
49583
+ AvlTransitionScene.displayName = "AvlTransitionScene";
49584
+
49585
+ // components/organisms/avl/AvlOrbitalsCosmicZoom.tsx
49586
+ init_Box();
49587
+ init_Stack();
49588
+ init_Typography();
49589
+ var UNIT_DISPLAY_W = 240;
49590
+ var UNIT_DISPLAY_H = 160;
49591
+ function layoutOrbitals(count, containerW, containerH) {
49592
+ if (count === 0) return [];
49593
+ if (count === 1) return [{ cx: containerW / 2, cy: containerH / 2 }];
49594
+ const cols = Math.min(count, Math.ceil(Math.sqrt(count)));
49595
+ const rows = Math.ceil(count / cols);
49596
+ const cellW = containerW / (cols + 0.3);
49597
+ const cellH = containerH / (rows + 0.3);
49598
+ const originX = (containerW - cols * cellW) / 2 + cellW / 2;
49599
+ const originY = (containerH - rows * cellH) / 2 + cellH / 2;
49600
+ return Array.from({ length: count }, (_, i) => ({
49601
+ cx: originX + i % cols * cellW,
49602
+ cy: originY + Math.floor(i / cols) * cellH
49603
+ }));
49604
+ }
49605
+ var avlOczWireId = 0;
49606
+ var EventWireOverlay = ({
49607
+ orbitalViews,
49608
+ crossLinks,
49609
+ color,
49610
+ animated,
49611
+ containerW,
49612
+ containerH
49613
+ }) => {
49614
+ const ids = React125__namespace.default.useMemo(() => {
49615
+ avlOczWireId += 1;
49616
+ return { arrow: `avl-ocz-wire-${avlOczWireId}-arrow` };
49617
+ }, []);
49618
+ const posMap = React125.useMemo(() => {
49619
+ const m = /* @__PURE__ */ new Map();
49620
+ for (const ov of orbitalViews) m.set(ov.name, { cx: ov.cx, cy: ov.cy });
49621
+ return m;
49622
+ }, [orbitalViews]);
49623
+ const wiresByPair = React125.useMemo(() => {
49624
+ const map = /* @__PURE__ */ new Map();
49625
+ for (const link of crossLinks) {
49626
+ const key = `${link.emitterOrbital}__${link.listenerOrbital}`;
49627
+ const arr = map.get(key) ?? [];
49628
+ arr.push(link);
49629
+ map.set(key, arr);
49630
+ }
49631
+ return map;
49632
+ }, [crossLinks]);
49633
+ const orbitalR = UNIT_DISPLAY_W * 0.38;
49634
+ return /* @__PURE__ */ jsxRuntime.jsxs(
49635
+ "svg",
49636
+ {
49637
+ style: {
49638
+ position: "absolute",
49639
+ inset: 0,
49640
+ width: "100%",
49641
+ height: "100%",
49642
+ pointerEvents: "none",
49643
+ overflow: "visible"
49644
+ },
49645
+ viewBox: `0 0 ${containerW} ${containerH}`,
49646
+ preserveAspectRatio: "xMidYMid meet",
49647
+ children: [
49648
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
49649
+ "marker",
49650
+ {
49651
+ id: ids.arrow,
49652
+ markerWidth: "8",
49653
+ markerHeight: "6",
49654
+ refX: "7",
49655
+ refY: "3",
49656
+ orient: "auto",
49657
+ markerUnits: "strokeWidth",
49658
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0,0 L8,3 L0,6 Z", fill: color, opacity: 0.6 })
49659
+ }
49660
+ ) }),
49661
+ animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
49662
+ @keyframes avl-ocz-flow {
49663
+ from { stroke-dashoffset: 20; }
49664
+ to { stroke-dashoffset: 0; }
49665
+ }
49666
+ ` }),
49667
+ Array.from(wiresByPair.entries()).map(
49668
+ ([pairKey, links]) => links.map((link, wireIdx) => {
49669
+ const fromPos = posMap.get(link.emitterOrbital);
49670
+ const toPos = posMap.get(link.listenerOrbital);
49671
+ if (!fromPos || !toPos) return null;
49672
+ const dx = toPos.cx - fromPos.cx;
49673
+ const dy = toPos.cy - fromPos.cy;
49674
+ const dist = Math.sqrt(dx * dx + dy * dy) || 1;
49675
+ const nx = dx / dist;
49676
+ const ny = dy / dist;
49677
+ const x1 = fromPos.cx + nx * orbitalR;
49678
+ const y1 = fromPos.cy + ny * orbitalR;
49679
+ const x2 = toPos.cx - nx * (orbitalR + 6);
49680
+ const y2 = toPos.cy - ny * (orbitalR + 6);
49681
+ const offset = 25 + wireIdx * 18;
49682
+ const { cpx, cpy } = curveControlPoint(x1, y1, x2, y2, offset);
49683
+ const pathD = `M${x1},${y1} Q${cpx},${cpy} ${x2},${y2}`;
49684
+ const t = 0.5;
49685
+ const lx = (1 - t) * (1 - t) * x1 + 2 * (1 - t) * t * cpx + t * t * x2;
49686
+ const ly = (1 - t) * (1 - t) * y1 + 2 * (1 - t) * t * cpy + t * t * y2;
49687
+ const labelW = link.eventName.length * 5.5 + 12;
49688
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49689
+ /* @__PURE__ */ jsxRuntime.jsx(
49690
+ "path",
49691
+ {
49692
+ d: pathD,
49693
+ fill: "none",
49694
+ stroke: color,
49695
+ strokeWidth: 1.2,
49696
+ strokeDasharray: animated ? "6 4" : "4 3",
49697
+ markerEnd: `url(#${ids.arrow})`,
49698
+ opacity: 0.5,
49699
+ style: animated ? { animation: "avl-ocz-flow 1.5s linear infinite" } : void 0
49700
+ }
49701
+ ),
49702
+ /* @__PURE__ */ jsxRuntime.jsx(
49703
+ "rect",
49704
+ {
49705
+ x: lx - labelW / 2,
49706
+ y: ly - 8,
49707
+ width: labelW,
49708
+ height: 14,
49709
+ rx: 3,
49710
+ fill: "var(--color-background, #fff)",
49711
+ stroke: color,
49712
+ strokeWidth: 0.5,
49713
+ opacity: 0.9
49714
+ }
49715
+ ),
49716
+ /* @__PURE__ */ jsxRuntime.jsx(
49717
+ "text",
49718
+ {
49719
+ x: lx,
49720
+ y: ly + 3,
49721
+ textAnchor: "middle",
49722
+ fill: color,
49723
+ fontSize: 7,
49724
+ fontWeight: 600,
49725
+ fontFamily: "monospace",
49726
+ opacity: 0.8,
49727
+ children: link.eventName
49728
+ }
49729
+ )
49730
+ ] }, `${pairKey}-${wireIdx}`);
49731
+ })
49732
+ )
49733
+ ]
49734
+ }
49735
+ );
49736
+ };
49737
+ var AvlOrbitalsCosmicZoom = ({
49738
+ schema: schemaProp,
49739
+ className,
49740
+ color = "var(--color-primary, #4A90D9)",
49741
+ animated = true,
49742
+ width = "100%",
49743
+ height = 450,
49744
+ highlightedOrbital,
49745
+ onOrbitalSelect,
49746
+ minZoom = 0.4,
49747
+ maxZoom = 3
49748
+ }) => {
49749
+ const parsedSchema = React125.useMemo(() => {
49750
+ if (typeof schemaProp === "string") return JSON.parse(schemaProp);
49751
+ return schemaProp;
49752
+ }, [schemaProp]);
49753
+ const { orbitals, crossLinks } = React125.useMemo(
49754
+ () => parseApplicationLevel(parsedSchema),
49755
+ [parsedSchema]
49756
+ );
49757
+ const containerW = typeof width === "number" ? width : 800;
49758
+ const containerH = typeof height === "number" ? height : 450;
49759
+ const positions = React125.useMemo(
49760
+ () => layoutOrbitals(orbitals.length, containerW, containerH),
49761
+ [orbitals.length, containerW, containerH]
49762
+ );
49763
+ const orbitalViews = React125.useMemo(
49764
+ () => orbitals.map((o, i) => ({
49765
+ name: o.name,
49766
+ entityName: o.entityName,
49767
+ fieldCount: o.fieldCount,
49768
+ persistence: o.persistence || "persistent",
49769
+ traits: o.traitNames.map((n) => ({ name: n })),
49770
+ pages: o.pageNames.map((n) => ({ name: n })),
49771
+ cx: positions[i]?.cx ?? 0,
49772
+ cy: positions[i]?.cy ?? 0
49773
+ })),
49774
+ [orbitals, positions]
49775
+ );
49776
+ const [state, dispatch] = React125.useReducer(zoomReducer, initialZoomState);
49777
+ const drilledForHighlightRef = React125.useRef(false);
49778
+ React125.useEffect(() => {
49779
+ if (!highlightedOrbital) return;
49780
+ if (drilledForHighlightRef.current) return;
49781
+ drilledForHighlightRef.current = true;
49782
+ dispatch({ type: "ZOOM_INTO_ORBITAL", orbital: highlightedOrbital, targetPosition: { x: 0, y: 0 } });
49783
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
49784
+ }, [highlightedOrbital]);
49785
+ const breadcrumbs = React125.useMemo(() => getBreadcrumbs(state), [state]);
49786
+ const handleSelect = React125.useCallback(
49787
+ (name) => {
49788
+ dispatch({ type: "ZOOM_INTO_ORBITAL", orbital: name, targetPosition: { x: 0, y: 0 } });
49789
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
49790
+ onOrbitalSelect?.(name);
49791
+ },
49792
+ [onOrbitalSelect]
49793
+ );
49794
+ const handleTraitSelect = React125.useCallback((traitName) => {
49795
+ dispatch({ type: "ZOOM_INTO_TRAIT", trait: traitName, targetPosition: { x: 0, y: 0 } });
49796
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
49797
+ }, []);
49798
+ const handleTransitionSelect = React125.useCallback((transitionIndex) => {
49799
+ dispatch({ type: "ZOOM_INTO_TRANSITION", transitionIndex, targetPosition: { x: 0, y: 0 } });
49800
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
49801
+ }, []);
49802
+ const handleZoomOut = React125.useCallback(() => {
49803
+ dispatch({ type: "ZOOM_OUT" });
49804
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
49805
+ }, []);
49806
+ const handleBreadcrumbClick = React125.useCallback((targetLevel) => {
49807
+ const order = ["application", "orbital", "trait", "transition"];
49808
+ const currentIdx = order.indexOf(state.level);
49809
+ const targetIdx = order.indexOf(targetLevel);
49810
+ const steps = currentIdx - targetIdx;
49811
+ for (let i = 0; i < steps; i++) {
49812
+ dispatch({ type: "ZOOM_OUT" });
49813
+ }
49814
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
49815
+ }, [state.level]);
49816
+ React125.useEffect(() => {
49817
+ if (state.level === "application") return;
49818
+ const onKey = (e) => {
49819
+ if (e.key === "Escape") handleZoomOut();
49820
+ };
49821
+ window.addEventListener("keydown", onKey);
49822
+ return () => window.removeEventListener("keydown", onKey);
49823
+ }, [handleZoomOut, state.level]);
49824
+ const orbitalLevelData = React125.useMemo(() => {
49825
+ if (!state.selectedOrbital) return null;
49826
+ return parseOrbitalLevel(parsedSchema, state.selectedOrbital);
49827
+ }, [parsedSchema, state.selectedOrbital]);
49828
+ const traitLevelData = React125.useMemo(() => {
49829
+ if (!state.selectedOrbital || !state.selectedTrait) return null;
49830
+ return parseTraitLevel(parsedSchema, state.selectedOrbital, state.selectedTrait);
49831
+ }, [parsedSchema, state.selectedOrbital, state.selectedTrait]);
49832
+ const transitionLevelData = React125.useMemo(() => {
49833
+ if (!state.selectedOrbital || !state.selectedTrait || state.selectedTransition === null) return null;
49834
+ return parseTransitionLevel(
49835
+ parsedSchema,
49836
+ state.selectedOrbital,
49837
+ state.selectedTrait,
49838
+ state.selectedTransition
49839
+ );
49840
+ }, [parsedSchema, state.selectedOrbital, state.selectedTrait, state.selectedTransition]);
49841
+ const [zoom, setZoom] = React125.useState(1);
49842
+ const [pan, setPan] = React125.useState({ x: 0, y: 0 });
49843
+ const dragStateRef = React125.useRef(null);
49844
+ const transformWrapperRef = React125.useRef(null);
49845
+ const clampZoom = React125.useCallback(
49846
+ (z) => Math.max(minZoom, Math.min(maxZoom, z)),
49847
+ [minZoom, maxZoom]
49848
+ );
49849
+ const handlePointerDown = React125.useCallback((e) => {
49850
+ if (e.target.closest("[data-orbital-tile]")) return;
49851
+ dragStateRef.current = {
49852
+ startX: e.clientX,
49853
+ startY: e.clientY,
49854
+ panX: pan.x,
49855
+ panY: pan.y
49856
+ };
49857
+ e.target.setPointerCapture(e.pointerId);
49858
+ }, [pan]);
49859
+ const handlePointerMove = React125.useCallback((e) => {
49860
+ const drag = dragStateRef.current;
49861
+ if (!drag) return;
49862
+ setPan({
49863
+ x: drag.panX + (e.clientX - drag.startX),
49864
+ y: drag.panY + (e.clientY - drag.startY)
49865
+ });
49866
+ }, []);
49867
+ const handlePointerUp = React125.useCallback((e) => {
49868
+ if (!dragStateRef.current) return;
49869
+ dragStateRef.current = null;
49870
+ try {
49871
+ e.target.releasePointerCapture(e.pointerId);
49872
+ } catch {
49873
+ }
49874
+ }, []);
49875
+ const panRef = React125.useRef(pan);
49876
+ const zoomRef = React125.useRef(zoom);
49877
+ React125.useEffect(() => {
49878
+ panRef.current = pan;
49879
+ }, [pan]);
49880
+ React125.useEffect(() => {
49881
+ zoomRef.current = zoom;
49882
+ }, [zoom]);
49883
+ React125.useEffect(() => {
49884
+ const wrapper = transformWrapperRef.current;
49885
+ if (!wrapper) return;
49886
+ const wheelListener = (e) => {
49887
+ e.preventDefault();
49888
+ const rect = wrapper.getBoundingClientRect();
49889
+ const cursorX = e.clientX - rect.left;
49890
+ const cursorY = e.clientY - rect.top;
49891
+ const currentZoom = zoomRef.current;
49892
+ const currentPan = panRef.current;
49893
+ const worldX = (cursorX - currentPan.x) / currentZoom;
49894
+ const worldY = (cursorY - currentPan.y) / currentZoom;
49895
+ const delta = e.deltaY > 0 ? -0.1 : 0.1;
49896
+ const nextZoom = clampZoom(currentZoom * (1 + delta));
49897
+ const nextPanX = cursorX - worldX * nextZoom;
49898
+ const nextPanY = cursorY - worldY * nextZoom;
49899
+ setZoom(nextZoom);
49900
+ setPan({ x: nextPanX, y: nextPanY });
49901
+ };
49902
+ wrapper.addEventListener("wheel", wheelListener, { passive: false });
49903
+ return () => wrapper.removeEventListener("wheel", wheelListener);
49904
+ }, [clampZoom]);
49905
+ const zoomIn = React125.useCallback(() => setZoom((z) => clampZoom(z * 1.2)), [clampZoom]);
49906
+ const zoomOut = React125.useCallback(() => setZoom((z) => clampZoom(z / 1.2)), [clampZoom]);
49907
+ const resetZoom = React125.useCallback(() => {
49908
+ setZoom(1);
49909
+ setPan({ x: 0, y: 0 });
49910
+ }, []);
49911
+ return /* @__PURE__ */ jsxRuntime.jsxs(
49912
+ Box,
49913
+ {
49914
+ className,
49915
+ position: "relative",
49916
+ overflow: "visible",
49917
+ style: { width, height: containerH },
49918
+ children: [
49919
+ /* @__PURE__ */ jsxRuntime.jsx(
49920
+ Box,
49877
49921
  {
49878
- points: `${CONTENT_LEFT + 6},${secY + 22} ${CONTENT_LEFT + 2},${secY + 26} ${CONTENT_LEFT + 6},${secY + 30} ${CONTENT_LEFT + 10},${secY + 26}`,
49879
- fill: "none",
49880
- stroke: color,
49881
- strokeWidth: 1,
49882
- opacity: 0.5
49922
+ position: "absolute",
49923
+ style: {
49924
+ top: 12,
49925
+ left: 12,
49926
+ zIndex: 30,
49927
+ background: "var(--color-card, rgba(255,255,255,0.92))",
49928
+ padding: "4px 12px",
49929
+ borderRadius: 6,
49930
+ border: `1px solid ${color}`
49931
+ },
49932
+ children: /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", align: "center", children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxRuntime.jsxs(React125__namespace.default.Fragment, { children: [
49933
+ i > 0 && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", style: { opacity: 0.5, color }, children: "/" }),
49934
+ i < breadcrumbs.length - 1 ? /* @__PURE__ */ jsxRuntime.jsx(
49935
+ Box,
49936
+ {
49937
+ as: "span",
49938
+ onClick: () => handleBreadcrumbClick(crumb.level),
49939
+ style: { cursor: "pointer" },
49940
+ children: /* @__PURE__ */ jsxRuntime.jsx(
49941
+ Typography,
49942
+ {
49943
+ variant: "small",
49944
+ style: { color, textDecoration: "underline" },
49945
+ children: crumb.label
49946
+ }
49947
+ )
49948
+ }
49949
+ ) : /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", style: { color }, children: crumb.label })
49950
+ ] }, crumb.level)) })
49883
49951
  }
49884
49952
  ),
49885
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: CONTENT_LEFT + 18, y: secY + 29, fill: color, fontSize: 12, fontWeight: 400, opacity: 0.6, fontFamily: "inherit", children: data.guard.label })
49886
- ] });
49887
- })(),
49888
- hasEffects && (() => {
49889
- const secY = cardY + headerH + sectionGap + triggerH + guardH;
49890
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49891
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: "EFFECTS" }),
49892
- effects.map((eff, i) => {
49893
- const rowY = secY + 22 + i * effectRowH;
49894
- const effectType = mapEffectType(eff.type);
49895
- const argsText = eff.args.length > 0 ? eff.args.join(" \xB7 ") : "";
49896
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49897
- /* @__PURE__ */ jsxRuntime.jsx(
49898
- AvlEffect,
49953
+ state.level !== "application" && /* @__PURE__ */ jsxRuntime.jsx(
49954
+ Box,
49955
+ {
49956
+ position: "absolute",
49957
+ style: {
49958
+ bottom: 12,
49959
+ right: 12,
49960
+ zIndex: 30,
49961
+ background: "var(--color-card, rgba(255,255,255,0.85))",
49962
+ padding: "2px 8px",
49963
+ borderRadius: 4,
49964
+ opacity: 0.8
49965
+ },
49966
+ children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", style: { color }, children: "Press Esc to zoom out" })
49967
+ }
49968
+ ),
49969
+ state.level === "application" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
49970
+ /* @__PURE__ */ jsxRuntime.jsx(
49971
+ "div",
49972
+ {
49973
+ ref: transformWrapperRef,
49974
+ onPointerDown: handlePointerDown,
49975
+ onPointerMove: handlePointerMove,
49976
+ onPointerUp: handlePointerUp,
49977
+ onPointerCancel: handlePointerUp,
49978
+ style: {
49979
+ position: "absolute",
49980
+ inset: 0,
49981
+ overflow: "hidden",
49982
+ cursor: dragStateRef.current ? "grabbing" : "grab",
49983
+ touchAction: "none"
49984
+ },
49985
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
49986
+ "div",
49987
+ {
49988
+ style: {
49989
+ position: "absolute",
49990
+ inset: 0,
49991
+ transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,
49992
+ transformOrigin: "0 0"
49993
+ },
49994
+ children: [
49995
+ /* @__PURE__ */ jsxRuntime.jsx(
49996
+ EventWireOverlay,
49997
+ {
49998
+ orbitalViews,
49999
+ crossLinks,
50000
+ color,
50001
+ animated,
50002
+ containerW,
50003
+ containerH
50004
+ }
50005
+ ),
50006
+ orbitalViews.map((view) => {
50007
+ const isHighlighted = view.name === highlightedOrbital;
50008
+ return /* @__PURE__ */ jsxRuntime.jsx(
50009
+ Box,
50010
+ {
50011
+ role: "button",
50012
+ tabIndex: 0,
50013
+ "data-orbital-tile": "true",
50014
+ onClick: () => handleSelect(view.name),
50015
+ onKeyDown: (e) => {
50016
+ if (e.key === "Enter" || e.key === " ") handleSelect(view.name);
50017
+ },
50018
+ "aria-label": `Orbital: ${view.name}${isHighlighted ? " (highlighted)" : ""}`,
50019
+ position: "absolute",
50020
+ style: {
50021
+ left: view.cx - UNIT_DISPLAY_W / 2,
50022
+ top: view.cy - UNIT_DISPLAY_H / 2,
50023
+ width: UNIT_DISPLAY_W,
50024
+ height: UNIT_DISPLAY_H,
50025
+ cursor: "pointer",
50026
+ transition: "transform 0.2s ease, filter 0.2s ease, box-shadow 0.3s ease",
50027
+ // GAP-52: persistent highlight ring (independent from user selection)
50028
+ boxShadow: isHighlighted ? `0 0 0 3px ${color}, 0 0 24px 4px ${color}` : "none",
50029
+ borderRadius: isHighlighted ? "12px" : void 0,
50030
+ zIndex: isHighlighted ? 11 : 1
50031
+ },
50032
+ children: /* @__PURE__ */ jsxRuntime.jsx(
50033
+ AvlOrbitalUnit,
50034
+ {
50035
+ entityName: view.entityName,
50036
+ fields: view.fieldCount,
50037
+ persistence: view.persistence,
50038
+ traits: view.traits,
50039
+ pages: view.pages,
50040
+ color,
50041
+ animated: animated && isHighlighted
50042
+ }
50043
+ )
50044
+ },
50045
+ view.name
50046
+ );
50047
+ })
50048
+ ]
50049
+ }
50050
+ )
50051
+ }
50052
+ ),
50053
+ /* @__PURE__ */ jsxRuntime.jsxs(
50054
+ Box,
50055
+ {
50056
+ position: "absolute",
50057
+ style: {
50058
+ top: 12,
50059
+ right: 12,
50060
+ display: "flex",
50061
+ flexDirection: "column",
50062
+ gap: 4,
50063
+ zIndex: 30
50064
+ },
50065
+ children: [
50066
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "sm", onClick: zoomIn, title: "Zoom in", action: "COSMIC_ZOOM_IN", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "plus", size: "sm" }) }),
50067
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "sm", onClick: zoomOut, title: "Zoom out", action: "COSMIC_ZOOM_OUT", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "minus", size: "sm" }) }),
50068
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "sm", onClick: resetZoom, title: "Reset", action: "COSMIC_ZOOM_RESET", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "maximize", size: "sm" }) })
50069
+ ]
50070
+ }
50071
+ )
50072
+ ] }),
50073
+ state.level === "orbital" && orbitalLevelData && /* @__PURE__ */ jsxRuntime.jsxs(
50074
+ Box,
50075
+ {
50076
+ position: "absolute",
50077
+ style: {
50078
+ inset: 0,
50079
+ paddingTop: 56,
50080
+ paddingBottom: 24,
50081
+ paddingLeft: 24,
50082
+ paddingRight: 24,
50083
+ display: "flex",
50084
+ alignItems: "stretch",
50085
+ justifyContent: "center",
50086
+ gap: 24
50087
+ },
50088
+ children: [
50089
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { style: { flex: 1, maxWidth: 720, display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
50090
+ AvlOrbitalUnit,
50091
+ {
50092
+ entityName: orbitalLevelData.entity.name,
50093
+ fields: orbitalLevelData.entity.fields.length,
50094
+ persistence: orbitalLevelData.entity.persistence || "persistent",
50095
+ traits: orbitalLevelData.traits.map((t) => ({ name: t.name })),
50096
+ pages: orbitalLevelData.pages.map((p2) => ({ name: p2.name })),
50097
+ color,
50098
+ animated
50099
+ }
50100
+ ) }),
50101
+ /* @__PURE__ */ jsxRuntime.jsxs(
50102
+ Box,
50103
+ {
50104
+ style: {
50105
+ width: 220,
50106
+ padding: 12,
50107
+ display: "flex",
50108
+ flexDirection: "column",
50109
+ gap: 8,
50110
+ borderLeft: `1px solid ${color}`,
50111
+ opacity: 0.95
50112
+ },
50113
+ children: [
50114
+ /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", weight: "semibold", style: { color, marginBottom: 4 }, children: [
50115
+ "Traits (",
50116
+ orbitalLevelData.traits.length,
50117
+ ")"
50118
+ ] }),
50119
+ orbitalLevelData.traits.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "small", style: { opacity: 0.6, color }, children: "No traits" }),
50120
+ orbitalLevelData.traits.map((trait) => /* @__PURE__ */ jsxRuntime.jsx(
50121
+ Button,
50122
+ {
50123
+ variant: "ghost",
50124
+ size: "sm",
50125
+ onClick: () => handleTraitSelect(trait.name),
50126
+ action: "COSMIC_DRILL_TRAIT",
50127
+ children: trait.name
50128
+ },
50129
+ trait.name
50130
+ )),
50131
+ orbitalLevelData.pages.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
50132
+ /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", weight: "semibold", style: { color, marginTop: 12 }, children: [
50133
+ "Pages (",
50134
+ orbitalLevelData.pages.length,
50135
+ ")"
50136
+ ] }),
50137
+ orbitalLevelData.pages.map((page) => /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "small", style: { opacity: 0.7, color }, children: page.name }, page.name))
50138
+ ] })
50139
+ ]
50140
+ }
50141
+ )
50142
+ ]
50143
+ }
50144
+ ),
50145
+ state.level === "trait" && traitLevelData && /* @__PURE__ */ jsxRuntime.jsx(
50146
+ Box,
50147
+ {
50148
+ position: "absolute",
50149
+ style: {
50150
+ inset: 0,
50151
+ paddingTop: 56,
50152
+ paddingBottom: 24,
50153
+ paddingLeft: 24,
50154
+ paddingRight: 24
50155
+ },
50156
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 600 400", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
50157
+ AvlTraitScene,
49899
50158
  {
49900
- x: CONTENT_LEFT + 10,
49901
- y: rowY + 6,
49902
- effectType,
49903
- size: 10,
49904
- showBackground: true
50159
+ data: traitLevelData,
50160
+ color,
50161
+ onTransitionClick: (idx) => handleTransitionSelect(idx)
49905
50162
  }
49906
- ),
49907
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: CONTENT_LEFT + 28, y: rowY + 10, fill: color, fontSize: 12, fontWeight: 500, opacity: 0.8, fontFamily: "inherit", children: eff.type }),
49908
- argsText && /* @__PURE__ */ jsxRuntime.jsx("text", { x: CONTENT_LEFT + 28 + eff.type.length * 7 + 8, y: rowY + 10, fill: color, fontSize: 10, fontWeight: 400, opacity: 0.5, fontFamily: "monospace", children: argsText })
49909
- ] }, `eff-${i}`);
49910
- })
49911
- ] });
49912
- })(),
49913
- hasSlots && (() => {
49914
- const secY = cardY + headerH + sectionGap + triggerH + guardH + effectsH;
49915
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49916
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: "SLOTS" }),
49917
- data.slotTargets.map((slot, i) => {
49918
- const rowY = secY + 22 + i * 22;
49919
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49920
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: CONTENT_LEFT, y: rowY - 4, width: CARD_W - 56, height: 18, rx: 4, fill: color, fillOpacity: 0.04 }),
49921
- /* @__PURE__ */ jsxRuntime.jsxs("text", { x: CONTENT_LEFT + 8, y: rowY + 8, fill: color, fontSize: 11, fontFamily: "inherit", children: [
49922
- slot.name,
49923
- ": ",
49924
- slot.pattern
49925
- ] })
49926
- ] }, `slot-${i}`);
49927
- })
49928
- ] });
49929
- })()
49930
- ] });
50163
+ ) })
50164
+ }
50165
+ ),
50166
+ state.level === "transition" && transitionLevelData && /* @__PURE__ */ jsxRuntime.jsx(
50167
+ Box,
50168
+ {
50169
+ position: "absolute",
50170
+ style: {
50171
+ inset: 0,
50172
+ paddingTop: 56,
50173
+ paddingBottom: 24,
50174
+ paddingLeft: 24,
50175
+ paddingRight: 24
50176
+ },
50177
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 600 400", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
50178
+ AvlTransitionScene,
50179
+ {
50180
+ data: transitionLevelData,
50181
+ color
50182
+ }
50183
+ ) })
50184
+ }
50185
+ )
50186
+ ]
50187
+ }
50188
+ );
49931
50189
  };
49932
- AvlTransitionScene.displayName = "AvlTransitionScene";
50190
+ AvlOrbitalsCosmicZoom.displayName = "AvlOrbitalsCosmicZoom";
49933
50191
  var AvlClickTarget = ({
49934
50192
  x,
49935
50193
  y,