@tscircuit/schematic-viewer 2.0.52 → 2.0.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bun.lockb CHANGED
Binary file
package/dist/index.js CHANGED
@@ -851,7 +851,7 @@ import { su as su5 } from "@tscircuit/soup-util";
851
851
  // package.json
852
852
  var package_default = {
853
853
  name: "@tscircuit/schematic-viewer",
854
- version: "2.0.51",
854
+ version: "2.0.53",
855
855
  main: "dist/index.js",
856
856
  type: "module",
857
857
  scripts: {
@@ -878,7 +878,7 @@ var package_default = {
878
878
  "react-dom": "^19.1.0",
879
879
  "react-reconciler": "^0.31.0",
880
880
  semver: "^7.7.2",
881
- tscircuit: "^0.0.1149",
881
+ tscircuit: "^0.0.1194",
882
882
  tsup: "^8.3.5",
883
883
  vite: "^6.0.3"
884
884
  },
@@ -904,7 +904,9 @@ var ViewMenu = ({
904
904
  isVisible,
905
905
  onClose,
906
906
  showGroups,
907
- onToggleGroups
907
+ onToggleGroups,
908
+ showGrid,
909
+ onToggleGrid
908
910
  }) => {
909
911
  const hasGroups = useMemo(() => {
910
912
  if (!circuitJson || circuitJson.length === 0) return false;
@@ -1034,6 +1036,53 @@ var ViewMenu = ({
1034
1036
  children: "No groups found in this schematic"
1035
1037
  }
1036
1038
  ),
1039
+ /* @__PURE__ */ jsxs3(
1040
+ "div",
1041
+ {
1042
+ onClick: () => onToggleGrid(!showGrid),
1043
+ onTouchEnd: (e) => {
1044
+ e.preventDefault();
1045
+ onToggleGrid(!showGrid);
1046
+ },
1047
+ style: {
1048
+ padding: "8px 12px",
1049
+ cursor: "pointer",
1050
+ fontSize: "13px",
1051
+ color: "#000000",
1052
+ fontFamily: "sans-serif",
1053
+ display: "flex",
1054
+ alignItems: "center",
1055
+ gap: "8px"
1056
+ },
1057
+ onMouseEnter: (e) => {
1058
+ e.currentTarget.style.backgroundColor = "#f0f0f0";
1059
+ },
1060
+ onMouseLeave: (e) => {
1061
+ e.currentTarget.style.backgroundColor = "transparent";
1062
+ },
1063
+ children: [
1064
+ /* @__PURE__ */ jsx4(
1065
+ "div",
1066
+ {
1067
+ style: {
1068
+ width: "16px",
1069
+ height: "16px",
1070
+ border: "2px solid #000",
1071
+ borderRadius: "2px",
1072
+ backgroundColor: "transparent",
1073
+ display: "flex",
1074
+ alignItems: "center",
1075
+ justifyContent: "center",
1076
+ fontSize: "10px",
1077
+ fontWeight: "bold"
1078
+ },
1079
+ children: showGrid && "\u2713"
1080
+ }
1081
+ ),
1082
+ "Show Grid"
1083
+ ]
1084
+ }
1085
+ ),
1037
1086
  /* @__PURE__ */ jsxs3(
1038
1087
  "div",
1039
1088
  {
@@ -2211,6 +2260,7 @@ var SchematicViewer = ({
2211
2260
  } = useSpiceSimulation(hasSpiceSimRun ? spiceString : null);
2212
2261
  const [editModeEnabled, setEditModeEnabled] = useState6(defaultEditMode);
2213
2262
  const [snapToGrid, setSnapToGrid] = useState6(true);
2263
+ const [showGrid, setShowGrid] = useState6(debugGrid);
2214
2264
  const [isInteractionEnabled, setIsInteractionEnabled] = useState6(
2215
2265
  !clickToInteractEnabled
2216
2266
  );
@@ -2289,13 +2339,13 @@ var SchematicViewer = ({
2289
2339
  return convertCircuitJsonToSchematicSvg(circuitJson, {
2290
2340
  width: containerWidth,
2291
2341
  height: containerHeight || 720,
2292
- grid: !debugGrid ? void 0 : {
2342
+ grid: !showGrid ? void 0 : {
2293
2343
  cellSize: 1,
2294
2344
  labelCells: true
2295
2345
  },
2296
2346
  colorOverrides
2297
2347
  });
2298
- }, [circuitJsonKey, containerWidth, containerHeight]);
2348
+ }, [circuitJsonKey, containerWidth, containerHeight, showGrid]);
2299
2349
  const containerBackgroundColor = useMemo5(() => {
2300
2350
  const match = svgString.match(
2301
2351
  /<svg[^>]*style="[^"]*background-color:\s*([^;\"]+)/i
@@ -2500,7 +2550,9 @@ var SchematicViewer = ({
2500
2550
  setShowSchematicGroups(value);
2501
2551
  setStoredBoolean("schematic_viewer_show_groups", value);
2502
2552
  }
2503
- }
2553
+ },
2554
+ showGrid,
2555
+ onToggleGrid: setShowGrid
2504
2556
  }
2505
2557
  ),
2506
2558
  spiceSimulationEnabled && /* @__PURE__ */ jsx11(SpiceSimulationIcon, { onClick: () => setShowSpiceOverlay(true) }),
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/components/SchematicViewer.tsx","../lib/hooks/useChangeSchematicComponentLocationsInSvg.ts","../lib/utils/get-component-offset-due-to-events.ts","../lib/hooks/useChangeSchematicTracesForMovedComponents.ts","../lib/hooks/useSchematicGroupsOverlay.ts","../lib/utils/debug.ts","../lib/hooks/use-resize-handling.ts","../lib/hooks/useComponentDragging.ts","../lib/utils/z-index-map.ts","../lib/components/EditIcon.tsx","../lib/components/GridIcon.tsx","../lib/components/ViewMenuIcon.tsx","../lib/components/ViewMenu.tsx","../package.json","../lib/components/SpiceIcon.tsx","../lib/components/SpiceSimulationIcon.tsx","../lib/components/SpicePlot.tsx","../lib/components/SpiceSimulationOverlay.tsx","../lib/hooks/useSpiceSimulation.ts","../lib/workers/spice-simulation.worker.blob.js","../lib/utils/spice-utils.ts","../lib/hooks/useLocalStorage.ts","../lib/components/MouseTracker.tsx","../lib/components/SchematicComponentMouseTarget.tsx","../lib/hooks/useMouseEventsOverBoundingBox.ts","../lib/components/AnalogSimulationViewer.tsx"],"sourcesContent":["import {\n convertCircuitJsonToSchematicSvg,\n type ColorOverrides,\n} from \"circuit-to-svg\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { useChangeSchematicComponentLocationsInSvg } from \"lib/hooks/useChangeSchematicComponentLocationsInSvg\"\nimport { useChangeSchematicTracesForMovedComponents } from \"lib/hooks/useChangeSchematicTracesForMovedComponents\"\nimport { useSchematicGroupsOverlay } from \"lib/hooks/useSchematicGroupsOverlay\"\nimport { enableDebug } from \"lib/utils/debug\"\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport {\n fromString,\n identity,\n toString as transformToString,\n} from \"transformation-matrix\"\nimport { useMouseMatrixTransform } from \"use-mouse-matrix-transform\"\nimport { useResizeHandling } from \"../hooks/use-resize-handling\"\nimport { useComponentDragging } from \"../hooks/useComponentDragging\"\nimport type { ManualEditEvent } from \"../types/edit-events\"\nimport { EditIcon } from \"./EditIcon\"\nimport { GridIcon } from \"./GridIcon\"\nimport { ViewMenuIcon } from \"./ViewMenuIcon\"\nimport { ViewMenu } from \"./ViewMenu\"\nimport type { CircuitJson } from \"circuit-json\"\nimport { SpiceSimulationIcon } from \"./SpiceSimulationIcon\"\nimport { SpiceSimulationOverlay } from \"./SpiceSimulationOverlay\"\nimport { zIndexMap } from \"../utils/z-index-map\"\nimport { useSpiceSimulation } from \"../hooks/useSpiceSimulation\"\nimport { getSpiceFromCircuitJson } from \"../utils/spice-utils\"\nimport { getStoredBoolean, setStoredBoolean } from \"lib/hooks/useLocalStorage\"\nimport { MouseTracker } from \"./MouseTracker\"\nimport { SchematicComponentMouseTarget } from \"./SchematicComponentMouseTarget\"\n\ninterface Props {\n circuitJson: CircuitJson\n containerStyle?: React.CSSProperties\n editEvents?: ManualEditEvent[]\n onEditEvent?: (event: ManualEditEvent) => void\n defaultEditMode?: boolean\n debugGrid?: boolean\n editingEnabled?: boolean\n debug?: boolean\n clickToInteractEnabled?: boolean\n colorOverrides?: ColorOverrides\n spiceSimulationEnabled?: boolean\n disableGroups?: boolean\n onSchematicComponentClicked?: (options: {\n schematicComponentId: string\n event: MouseEvent\n }) => void\n}\n\nexport const SchematicViewer = ({\n circuitJson,\n containerStyle,\n editEvents: unappliedEditEvents = [],\n onEditEvent,\n defaultEditMode = false,\n debugGrid = false,\n editingEnabled = false,\n debug = false,\n clickToInteractEnabled = false,\n colorOverrides,\n spiceSimulationEnabled = false,\n disableGroups = false,\n onSchematicComponentClicked,\n}: Props) => {\n if (debug) {\n enableDebug()\n }\n const [showSpiceOverlay, setShowSpiceOverlay] = useState(false)\n const [spiceSimOptions, setSpiceSimOptions] = useState({\n showVoltage: true,\n showCurrent: false,\n startTime: 0, // in ms\n duration: 20, // in ms\n })\n\n const getCircuitHash = (circuitJson: CircuitJson) => {\n return `${circuitJson?.length || 0}_${(circuitJson as any)?.editCount || 0}`\n }\n\n const circuitJsonKey = useMemo(\n () => getCircuitHash(circuitJson),\n [circuitJson],\n )\n\n const spiceString = useMemo(() => {\n if (!spiceSimulationEnabled) return null\n try {\n return getSpiceFromCircuitJson(circuitJson, spiceSimOptions)\n } catch (e) {\n console.error(\"Failed to generate SPICE string\", e)\n return null\n }\n }, [\n circuitJsonKey,\n spiceSimulationEnabled,\n spiceSimOptions.startTime,\n spiceSimOptions.duration,\n ])\n\n const [hasSpiceSimRun, setHasSpiceSimRun] = useState(false)\n\n useEffect(() => {\n setHasSpiceSimRun(false)\n }, [circuitJsonKey])\n\n const {\n plotData,\n nodes,\n isLoading: isSpiceSimLoading,\n error: spiceSimError,\n } = useSpiceSimulation(hasSpiceSimRun ? spiceString : null)\n\n const [editModeEnabled, setEditModeEnabled] = useState(defaultEditMode)\n const [snapToGrid, setSnapToGrid] = useState(true)\n const [isInteractionEnabled, setIsInteractionEnabled] = useState<boolean>(\n !clickToInteractEnabled,\n )\n const [showViewMenu, setShowViewMenu] = useState(false)\n const [showSchematicGroups, setShowSchematicGroups] = useState(() => {\n if (disableGroups) return false\n return getStoredBoolean(\"schematic_viewer_show_groups\", false)\n })\n const [isHoveringClickableComponent, setIsHoveringClickableComponent] =\n useState(false)\n const hoveringComponentsRef = useRef<Set<string>>(new Set())\n\n const handleComponentHoverChange = useCallback(\n (componentId: string, isHovering: boolean) => {\n if (isHovering) {\n hoveringComponentsRef.current.add(componentId)\n } else {\n hoveringComponentsRef.current.delete(componentId)\n }\n setIsHoveringClickableComponent(hoveringComponentsRef.current.size > 0)\n },\n [],\n )\n const svgDivRef = useRef<HTMLDivElement>(null)\n const touchStartRef = useRef<{ x: number; y: number } | null>(null)\n\n const schematicComponentIds = useMemo(() => {\n try {\n return (\n su(circuitJson)\n .schematic_component?.list()\n ?.map((component) => component.schematic_component_id as string) ?? []\n )\n } catch (err) {\n console.error(\"Failed to derive schematic component ids\", err)\n return []\n }\n }, [circuitJsonKey, circuitJson])\n\n const handleTouchStart = (e: React.TouchEvent) => {\n const touch = e.touches[0]\n touchStartRef.current = {\n x: touch.clientX,\n y: touch.clientY,\n }\n }\n\n const handleTouchEnd = (e: React.TouchEvent) => {\n const touch = e.changedTouches[0]\n const start = touchStartRef.current\n if (!start) return\n\n const deltaX = Math.abs(touch.clientX - start.x)\n const deltaY = Math.abs(touch.clientY - start.y)\n\n if (deltaX < 10 && deltaY < 10) {\n e.preventDefault()\n setIsInteractionEnabled(true)\n }\n\n touchStartRef.current = null\n }\n\n const [internalEditEvents, setInternalEditEvents] = useState<\n ManualEditEvent[]\n >([])\n const circuitJsonRef = useRef<CircuitJson>(circuitJson)\n\n useEffect(() => {\n const circuitHash = getCircuitHash(circuitJson)\n const circuitHashRef = getCircuitHash(circuitJsonRef.current)\n\n if (circuitHash !== circuitHashRef) {\n setInternalEditEvents([])\n circuitJsonRef.current = circuitJson\n }\n }, [circuitJson])\n\n const {\n ref: containerRef,\n cancelDrag,\n transform: svgToScreenProjection,\n } = useMouseMatrixTransform({\n onSetTransform(transform) {\n if (!svgDivRef.current) return\n svgDivRef.current.style.transform = transformToString(transform)\n },\n // @ts-ignore disabled is a valid prop but not typed\n enabled: isInteractionEnabled && !showSpiceOverlay,\n })\n\n const { containerWidth, containerHeight } = useResizeHandling(containerRef)\n const svgString = useMemo(() => {\n if (!containerWidth || !containerHeight) return \"\"\n\n return convertCircuitJsonToSchematicSvg(circuitJson as any, {\n width: containerWidth,\n height: containerHeight || 720,\n grid: !debugGrid\n ? undefined\n : {\n cellSize: 1,\n labelCells: true,\n },\n colorOverrides,\n })\n }, [circuitJsonKey, containerWidth, containerHeight])\n\n const containerBackgroundColor = useMemo(() => {\n const match = svgString.match(\n /<svg[^>]*style=\"[^\"]*background-color:\\s*([^;\\\"]+)/i,\n )\n return match?.[1] ?? \"transparent\"\n }, [svgString])\n\n const realToSvgProjection = useMemo(() => {\n if (!svgString) return identity()\n const transformString = svgString.match(\n /data-real-to-screen-transform=\"([^\"]+)\"/,\n )?.[1]!\n\n try {\n return fromString(transformString)\n } catch (e) {\n console.error(e)\n return identity()\n }\n }, [svgString])\n\n const handleEditEvent = (event: ManualEditEvent) => {\n setInternalEditEvents((prev) => [...prev, event])\n if (onEditEvent) {\n onEditEvent(event)\n }\n }\n\n const editEventsWithUnappliedEditEvents = useMemo(() => {\n return [...unappliedEditEvents, ...internalEditEvents]\n }, [unappliedEditEvents, internalEditEvents])\n\n const {\n handleMouseDown,\n handleTouchStart: handleComponentTouchStart,\n isDragging,\n activeEditEvent,\n } = useComponentDragging({\n onEditEvent: handleEditEvent,\n cancelDrag,\n realToSvgProjection,\n svgToScreenProjection,\n circuitJson,\n editEvents: editEventsWithUnappliedEditEvents,\n enabled: editModeEnabled && isInteractionEnabled && !showSpiceOverlay,\n snapToGrid,\n })\n\n useChangeSchematicComponentLocationsInSvg({\n svgDivRef,\n editEvents: editEventsWithUnappliedEditEvents,\n realToSvgProjection,\n svgToScreenProjection,\n activeEditEvent,\n })\n\n useChangeSchematicTracesForMovedComponents({\n svgDivRef,\n circuitJson,\n activeEditEvent,\n editEvents: editEventsWithUnappliedEditEvents,\n })\n\n // Add group overlays when enabled\n useSchematicGroupsOverlay({\n svgDivRef,\n circuitJson,\n circuitJsonKey,\n showGroups: showSchematicGroups && !disableGroups,\n })\n\n // keep the latest touch handler without re-rendering the svg div\n const handleComponentTouchStartRef = useRef(handleComponentTouchStart)\n useEffect(() => {\n handleComponentTouchStartRef.current = handleComponentTouchStart\n }, [handleComponentTouchStart])\n\n const svgDiv = useMemo(\n () => (\n <div\n ref={svgDivRef}\n style={{\n pointerEvents: clickToInteractEnabled\n ? isInteractionEnabled\n ? \"auto\"\n : \"none\"\n : \"auto\",\n transformOrigin: \"0 0\",\n }}\n className={\n onSchematicComponentClicked\n ? \"schematic-component-clickable\"\n : undefined\n }\n onTouchStart={(e) => {\n if (editModeEnabled && isInteractionEnabled && !showSpiceOverlay) {\n handleComponentTouchStartRef.current(e)\n }\n }}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: <explanation>\n dangerouslySetInnerHTML={{ __html: svgString }}\n />\n ),\n [\n svgString,\n isInteractionEnabled,\n clickToInteractEnabled,\n editModeEnabled,\n showSpiceOverlay,\n ],\n )\n\n return (\n <MouseTracker>\n {onSchematicComponentClicked && (\n <style>\n {`.schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }`}\n </style>\n )}\n <div\n ref={containerRef}\n style={{\n position: \"relative\",\n backgroundColor: containerBackgroundColor,\n overflow: \"hidden\",\n cursor: showSpiceOverlay\n ? \"auto\"\n : isDragging\n ? \"grabbing\"\n : clickToInteractEnabled && !isInteractionEnabled\n ? \"pointer\"\n : isHoveringClickableComponent && onSchematicComponentClicked\n ? \"pointer\"\n : \"grab\",\n minHeight: \"300px\",\n ...containerStyle,\n }}\n onWheelCapture={(e) => {\n if (showSpiceOverlay) {\n e.stopPropagation()\n }\n }}\n onMouseDown={(e) => {\n if (clickToInteractEnabled && !isInteractionEnabled) {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n handleMouseDown(e)\n }}\n onMouseDownCapture={(e) => {\n if (clickToInteractEnabled && !isInteractionEnabled) {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n }}\n onTouchStart={(e) => {\n if (showSpiceOverlay) return\n handleTouchStart(e)\n }}\n onTouchEnd={(e) => {\n if (showSpiceOverlay) return\n handleTouchEnd(e)\n }}\n >\n {!isInteractionEnabled && clickToInteractEnabled && (\n <div\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n setIsInteractionEnabled(true)\n }}\n style={{\n position: \"absolute\",\n inset: 0,\n cursor: \"pointer\",\n zIndex: zIndexMap.clickToInteractOverlay,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"all\",\n touchAction: \"pan-x pan-y pinch-zoom\",\n }}\n >\n <div\n style={{\n backgroundColor: \"rgba(0, 0, 0, 0.8)\",\n color: \"white\",\n padding: \"12px 24px\",\n borderRadius: \"8px\",\n fontSize: \"16px\",\n fontFamily: \"sans-serif\",\n pointerEvents: \"none\",\n }}\n >\n {typeof window !== \"undefined\" &&\n (\"ontouchstart\" in window || navigator.maxTouchPoints > 0)\n ? \"Touch to Interact\"\n : \"Click to Interact\"}\n </div>\n </div>\n )}\n <ViewMenuIcon\n active={showViewMenu}\n onClick={() => setShowViewMenu(!showViewMenu)}\n />\n {editingEnabled && (\n <EditIcon\n active={editModeEnabled}\n onClick={() => setEditModeEnabled(!editModeEnabled)}\n />\n )}\n {editingEnabled && editModeEnabled && (\n <GridIcon\n active={snapToGrid}\n onClick={() => setSnapToGrid(!snapToGrid)}\n />\n )}\n <ViewMenu\n circuitJson={circuitJson}\n circuitJsonKey={circuitJsonKey}\n isVisible={showViewMenu}\n onClose={() => setShowViewMenu(false)}\n showGroups={showSchematicGroups}\n onToggleGroups={(value) => {\n if (!disableGroups) {\n setShowSchematicGroups(value)\n setStoredBoolean(\"schematic_viewer_show_groups\", value)\n }\n }}\n />\n {spiceSimulationEnabled && (\n <SpiceSimulationIcon onClick={() => setShowSpiceOverlay(true)} />\n )}\n {showSpiceOverlay && (\n <SpiceSimulationOverlay\n spiceString={spiceString}\n onClose={() => setShowSpiceOverlay(false)}\n plotData={plotData}\n nodes={nodes}\n isLoading={isSpiceSimLoading}\n error={spiceSimError}\n simOptions={spiceSimOptions}\n onSimOptionsChange={(options) => {\n setHasSpiceSimRun(true)\n setSpiceSimOptions(options)\n }}\n hasRun={hasSpiceSimRun}\n />\n )}\n {onSchematicComponentClicked &&\n schematicComponentIds.map((componentId) => (\n <SchematicComponentMouseTarget\n key={componentId}\n componentId={componentId}\n svgDivRef={svgDivRef}\n containerRef={containerRef}\n showOutline={true}\n circuitJsonKey={circuitJsonKey}\n onHoverChange={handleComponentHoverChange}\n onComponentClick={(id, event) => {\n onSchematicComponentClicked?.({\n schematicComponentId: id,\n event,\n })\n }}\n />\n ))}\n {svgDiv}\n </div>\n </MouseTracker>\n )\n}\n","import { su } from \"@tscircuit/soup-util\"\nimport type {\n ManualEditEvent,\n EditSchematicComponentLocationEventWithElement,\n} from \"lib/types/edit-events\"\nimport { type Matrix, compose, applyToPoint } from \"transformation-matrix\"\nimport { useEffect, useRef } from \"react\"\nimport { getComponentOffsetDueToEvents } from \"lib/utils/get-component-offset-due-to-events\"\nimport type { CircuitJson } from \"circuit-json\"\n\n/**\n * This hook automatically applies the edit events to the schematic components\n * inside the svg div.\n *\n * Schematic components are \"<g>\" elements with a \"data-circuit-json-type\"\n * attribute equal to \"schematic_component\", these elements also have a\n * data-schematic-component-id attribute equal to the schematic_component_id\n */\nexport const useChangeSchematicComponentLocationsInSvg = ({\n svgDivRef,\n realToSvgProjection,\n svgToScreenProjection,\n activeEditEvent,\n editEvents,\n}: {\n svgDivRef: React.RefObject<HTMLDivElement | null>\n realToSvgProjection: Matrix\n svgToScreenProjection: Matrix\n activeEditEvent: EditSchematicComponentLocationEventWithElement | null\n editEvents: ManualEditEvent[]\n}) => {\n // Keep track of the last known SVG content\n const lastSvgContentRef = useRef<string | null>(null)\n\n useEffect(() => {\n const svg = svgDivRef.current\n if (!svg) return\n\n // Create a MutationObserver to watch for changes in the div's content\n const observer = new MutationObserver((mutations) => {\n // Check if the SVG content has changed\n const currentSvgContent = svg.innerHTML\n if (currentSvgContent !== lastSvgContentRef.current) {\n lastSvgContentRef.current = currentSvgContent\n\n // Apply the transforms\n applyTransforms()\n }\n })\n\n // Function to apply transforms to components\n const applyTransforms = () => {\n const componentsThatHaveBeenMoved = new Set<string>()\n for (const event of editEvents) {\n if (\n \"edit_event_type\" in event &&\n event.edit_event_type === \"edit_schematic_component_location\"\n ) {\n componentsThatHaveBeenMoved.add(event.schematic_component_id)\n }\n }\n if (activeEditEvent) {\n componentsThatHaveBeenMoved.add(activeEditEvent.schematic_component_id)\n }\n\n // Reset all transforms\n const allComponents = svg.querySelectorAll(\n '[data-circuit-json-type=\"schematic_component\"]',\n )\n\n for (const component of Array.from(allComponents)) {\n const schematic_component_id = component.getAttribute(\n \"data-schematic-component-id\",\n )!\n\n const offsetMm = getComponentOffsetDueToEvents({\n editEvents: [\n ...editEvents,\n ...(activeEditEvent ? [activeEditEvent] : []),\n ],\n schematic_component_id,\n })\n\n const offsetPx = {\n x: offsetMm.x * realToSvgProjection.a,\n y: offsetMm.y * realToSvgProjection.d,\n }\n\n const style: any = (component as any).style\n style.transform = `translate(${offsetPx.x}px, ${offsetPx.y}px)`\n if (\n activeEditEvent?.schematic_component_id === schematic_component_id\n ) {\n style.outline = \"solid 2px rgba(255,0,0,0.5)\"\n style.outlineOffset = \"5px\"\n } else if (style.outline) {\n style.outline = \"\"\n }\n }\n }\n\n // Start observing the div for changes\n observer.observe(svg, {\n childList: true, // Watch for changes to the child elements\n subtree: false, // Watch for changes in the entire subtree\n characterData: false, // Watch for changes to text content\n })\n\n // Apply transforms immediately on mount or when editEvents change\n applyTransforms()\n\n // Cleanup function\n return () => {\n observer.disconnect()\n }\n }, [svgDivRef, editEvents, activeEditEvent]) // Dependencies remain the same\n}\n","import type {\n EditSchematicComponentLocationEvent,\n EditSchematicComponentLocationEventWithElement,\n ManualEditEvent,\n} from \"lib/types/edit-events\"\n\n/**\n * Returns the total offset of a component due to a set of edit events in\n * mm\n */\nexport const getComponentOffsetDueToEvents = ({\n editEvents,\n schematic_component_id,\n}: {\n editEvents: ManualEditEvent[]\n schematic_component_id: string\n}) => {\n const editEventsForComponent: EditSchematicComponentLocationEvent[] =\n editEvents\n .filter(\n (event) =>\n \"schematic_component_id\" in event &&\n event.schematic_component_id === schematic_component_id,\n )\n .filter(\n (event) =>\n \"edit_event_type\" in event &&\n event.edit_event_type === \"edit_schematic_component_location\",\n )\n\n const totalOffsetX = editEventsForComponent.reduce((acc, event) => {\n return acc + event.new_center.x - event.original_center.x\n }, 0)\n\n const totalOffsetY = editEventsForComponent.reduce((acc, event) => {\n return acc + event.new_center.y - event.original_center.y\n }, 0)\n\n return {\n x: totalOffsetX,\n y: totalOffsetY,\n }\n}\n","import { useEffect, useRef } from \"react\"\nimport { su } from \"@tscircuit/soup-util\"\nimport type { ManualEditEvent } from \"../types/edit-events\"\nimport type { CircuitJson } from \"circuit-json\"\n\n/**\n * This hook makes traces dashed when their connected components are being moved\n */\nexport const useChangeSchematicTracesForMovedComponents = ({\n svgDivRef,\n circuitJson,\n activeEditEvent,\n editEvents,\n}: {\n svgDivRef: React.RefObject<HTMLDivElement | null>\n circuitJson: CircuitJson\n activeEditEvent: ManualEditEvent | null\n editEvents: ManualEditEvent[]\n}) => {\n // Keep track of the last known SVG content\n const lastSvgContentRef = useRef<string | null>(null)\n\n useEffect(() => {\n const svg = svgDivRef.current\n if (!svg) return\n\n const updateTraceStyles = () => {\n // Reset all traces to solid\n const allTraces = svg.querySelectorAll(\n '[data-circuit-json-type=\"schematic_trace\"] path',\n )\n\n // Reset all traces to solid\n for (const trace of Array.from(allTraces)) {\n trace.setAttribute(\"stroke-dasharray\", \"0\")\n ;(trace as any).style.animation = \"\"\n }\n\n // If there's an active edit event, make connected traces dashed\n for (const editEvent of [\n ...editEvents,\n ...(activeEditEvent ? [activeEditEvent] : []),\n ]) {\n if (\n \"schematic_component_id\" in editEvent &&\n editEvent.edit_event_type === \"edit_schematic_component_location\"\n ) {\n const sch_component = su(circuitJson).schematic_component.get(\n editEvent.schematic_component_id,\n )\n if (!sch_component) return\n\n const src_ports = su(circuitJson).source_port.list({\n source_component_id: sch_component.source_component_id,\n })\n const src_port_ids = new Set(src_ports.map((sp) => sp.source_port_id))\n const src_traces = su(circuitJson)\n .source_trace.list()\n .filter((st) =>\n st.connected_source_port_ids?.some((spi: string) =>\n src_port_ids.has(spi),\n ),\n )\n const src_trace_ids = new Set(\n src_traces.map((st) => st.source_trace_id),\n )\n const schematic_traces = su(circuitJson)\n .schematic_trace.list()\n .filter((st) => src_trace_ids.has(st.source_trace_id!))\n\n // Make the connected traces dashed\n schematic_traces.forEach((trace) => {\n const traceElements = svg.querySelectorAll(\n `[data-schematic-trace-id=\"${trace.schematic_trace_id}\"] path`,\n )\n for (const traceElement of Array.from(traceElements)) {\n if (traceElement.getAttribute(\"class\")?.includes(\"invisible\"))\n continue\n traceElement.setAttribute(\"stroke-dasharray\", \"20,20\")\n ;(traceElement as any).style.animation =\n \"dash-animation 350ms linear infinite, pulse-animation 900ms linear infinite\"\n\n if (!svg.querySelector(\"style#dash-animation\")) {\n const style = document.createElement(\"style\")\n style.id = \"dash-animation\"\n style.textContent = `\n @keyframes dash-animation {\n to {\n stroke-dashoffset: -40;\n }\n }\n @keyframes pulse-animation {\n 0% { opacity: 0.6; }\n 50% { opacity: 0.2; }\n 100% { opacity: 0.6; }\n }\n `\n svg.appendChild(style)\n }\n }\n })\n }\n }\n }\n\n // Apply styles immediately\n updateTraceStyles()\n\n // Cleanup function\n const observer = new MutationObserver(updateTraceStyles)\n observer.observe(svg, {\n childList: true, // Watch for changes to the child elements\n subtree: false, // Watch for changes in the entire subtree\n characterData: false, // Watch for changes to text content\n })\n\n return () => {\n observer.disconnect()\n }\n }, [svgDivRef, activeEditEvent, circuitJson, editEvents])\n}\n","import { useEffect } from \"react\"\nimport { su } from \"@tscircuit/soup-util\"\nimport type { CircuitJson } from \"circuit-json\"\n\ninterface UseSchematicGroupsOverlayOptions {\n svgDivRef: React.RefObject<HTMLDivElement | null>\n circuitJson: CircuitJson\n circuitJsonKey: string\n showGroups: boolean\n}\n\nconst GROUP_COLORS = [\n \"#8B0000\", // Dark Red\n \"#2F4F4F\", // Dark Slate Gray\n \"#191970\", // Midnight Blue\n \"#006400\", // Dark Green\n \"#FF4500\", // Dark Orange\n \"#800080\", // Purple\n \"#2E8B57\", // Sea Green\n \"#B8860B\", // Dark Goldenrod\n \"#C71585\", // Medium Violet Red\n \"#008B8B\", // Dark Cyan\n]\n\nexport const useSchematicGroupsOverlay = (\n options: UseSchematicGroupsOverlayOptions,\n) => {\n const { svgDivRef, circuitJson, circuitJsonKey, showGroups } = options\n\n useEffect(() => {\n // Always clean up existing overlays first\n if (svgDivRef.current) {\n const existingOverlays = svgDivRef.current.querySelectorAll(\n \".schematic-group-overlay\",\n )\n existingOverlays.forEach((overlay) => overlay.remove())\n }\n\n if (\n !svgDivRef.current ||\n !showGroups ||\n !circuitJson ||\n circuitJson.length === 0\n ) {\n return\n }\n\n // Small delay to ensure SVG is rendered when groups are enabled from localStorage\n const timeoutId = setTimeout(() => {\n if (!svgDivRef.current) return\n\n const svg = svgDivRef.current.querySelector(\"svg\")\n if (!svg) {\n return\n }\n\n const existingOverlays = svg.querySelectorAll(\".schematic-group-overlay\")\n existingOverlays.forEach((overlay) => overlay.remove())\n\n try {\n const sourceGroups =\n su(circuitJson)\n .source_group?.list()\n .filter((x) => !!!x.is_subcircuit) || []\n const schematicComponents =\n su(circuitJson).schematic_component?.list() || []\n\n const sourceGroupHierarchy = new Map<string, string[]>()\n sourceGroups.forEach((group) => {\n const groupWithParent = group as any\n if (groupWithParent.parent_source_group_id) {\n const children =\n sourceGroupHierarchy.get(\n groupWithParent.parent_source_group_id,\n ) || []\n children.push(group.source_group_id)\n sourceGroupHierarchy.set(\n groupWithParent.parent_source_group_id,\n children,\n )\n }\n })\n\n const getAllDescendantSourceGroups = (\n sourceGroupId: string,\n ): string[] => {\n const descendants: string[] = []\n const children = sourceGroupHierarchy.get(sourceGroupId) || []\n for (const child of children) {\n descendants.push(child)\n descendants.push(...getAllDescendantSourceGroups(child))\n }\n return descendants\n }\n\n const getGroupDepthLevel = (sourceGroupId: string): number => {\n const groupWithParent = sourceGroups.find(\n (g) => g.source_group_id === sourceGroupId,\n ) as any\n if (!groupWithParent?.parent_source_group_id) {\n return 0\n }\n return 1 + getGroupDepthLevel(groupWithParent.parent_source_group_id)\n }\n\n const hasMeaningfulGroups =\n sourceGroups.length > 0 &&\n sourceGroups.some((group) => group.name && group.name.trim() !== \"\")\n\n let groupsToRender: Array<{\n id: string\n name: string\n components: any[]\n color: string\n depthLevel: number\n hasChildren: boolean\n sourceGroupId?: string\n }> = []\n\n if (hasMeaningfulGroups) {\n const groupMap = new Map<string, any[]>()\n\n for (const comp of schematicComponents) {\n const sourceComp = su(circuitJson).source_component.get(\n comp.source_component_id!,\n )\n if (sourceComp?.source_group_id) {\n if (!groupMap.has(sourceComp.source_group_id)) {\n groupMap.set(sourceComp.source_group_id, [])\n }\n groupMap.get(sourceComp.source_group_id)!.push(comp)\n }\n }\n\n sourceGroups.forEach((group, index) => {\n let groupComponents = groupMap.get(group.source_group_id) || []\n\n const descendantGroups = getAllDescendantSourceGroups(\n group.source_group_id,\n )\n for (const descendantGroupId of descendantGroups) {\n const descendantComponents = groupMap.get(descendantGroupId) || []\n groupComponents = [...groupComponents, ...descendantComponents]\n }\n\n if (groupComponents.length > 0) {\n const depthLevel = getGroupDepthLevel(group.source_group_id)\n const hasChildren =\n getAllDescendantSourceGroups(group.source_group_id).length > 0\n\n if (group.name?.startsWith(\"unnamed_board\")) return\n groupsToRender.push({\n id: group.source_group_id,\n name: group.name || `Group ${index + 1}`,\n components: groupComponents,\n color: GROUP_COLORS[index % GROUP_COLORS.length],\n depthLevel,\n hasChildren,\n sourceGroupId: group.source_group_id,\n })\n }\n })\n }\n // else {\n // const componentTypeGroups = new Map<string, any[]>()\n\n // for (const comp of schematicComponents) {\n // const sourceComp = su(circuitJson).source_component.get(comp.source_component_id)\n // if (sourceComp) {\n // const componentType = sourceComp.ftype || \"other\"\n // if (!componentTypeGroups.has(componentType)) {\n // componentTypeGroups.set(componentType, [])\n // }\n // componentTypeGroups.get(componentType)!.push(comp)\n // }\n // }\n // // groupsToRender = Array.from(componentTypeGroups.entries()).map(\n // // ([type, components], index) => ({\n // // id: `type_${type}`,\n // // name: `${type.charAt(0).toUpperCase() + type.slice(1)}s`,\n // // components,\n // // color: GROUP_COLORS[index % GROUP_COLORS.length],\n // // depthLevel: 0,\n // // hasChildren: false,\n // // }),\n // // )\n // }\n\n const viewBox = svg.viewBox.baseVal\n const svgRect = svg.getBoundingClientRect()\n const scale =\n Math.min(\n svgRect.width / viewBox.width,\n svgRect.height / viewBox.height,\n ) || 1\n\n groupsToRender.sort((a, b) => a.depthLevel - b.depthLevel)\n\n groupsToRender.forEach((group) => {\n if (group.components.length === 0) return\n\n const groupBounds = calculateGroupBounds(group.components, svg)\n if (!groupBounds) return\n\n const basePadding = Math.max(\n 8,\n Math.min(25, 15 / Math.max(scale, 0.3)),\n )\n const hierarchyPadding = group.hasChildren ? basePadding * 0.6 : 0\n const totalPadding = basePadding + hierarchyPadding\n\n const baseStrokeWidth = Math.max(1, 2 / Math.max(scale, 0.5))\n const strokeWidth =\n group.depthLevel === 0 ? baseStrokeWidth : baseStrokeWidth * 0.7\n\n const baseDashSize = Math.max(4, 8 / Math.max(scale, 0.5))\n const dashMultiplier = group.hasChildren ? 1.3 : 1\n const dashSize = baseDashSize * dashMultiplier\n const gapSize = dashSize * 0.5\n\n const groupOverlay = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"rect\",\n )\n groupOverlay.setAttribute(\"class\", \"schematic-group-overlay\")\n groupOverlay.setAttribute(\n \"x\",\n (groupBounds.minX - totalPadding).toString(),\n )\n groupOverlay.setAttribute(\n \"y\",\n (groupBounds.minY - totalPadding).toString(),\n )\n groupOverlay.setAttribute(\n \"width\",\n (groupBounds.maxX - groupBounds.minX + totalPadding * 2).toString(),\n )\n groupOverlay.setAttribute(\n \"height\",\n (groupBounds.maxY - groupBounds.minY + totalPadding * 2).toString(),\n )\n groupOverlay.setAttribute(\"fill\", \"none\")\n groupOverlay.setAttribute(\"stroke\", group.color)\n groupOverlay.setAttribute(\"stroke-width\", strokeWidth.toString())\n groupOverlay.setAttribute(\n \"stroke-dasharray\",\n `${dashSize},${gapSize}`,\n )\n groupOverlay.setAttribute(\"opacity\", \"0.8\")\n groupOverlay.setAttribute(\"rx\", \"0\")\n groupOverlay.setAttribute(\"ry\", \"0\")\n\n const baseFontSize = Math.max(\n 6,\n Math.min(20, 14 / Math.max(scale, 0.2)),\n )\n const fontSizeReduction =\n group.depthLevel === 0 || group.depthLevel === 1\n ? 0\n : group.depthLevel * 0.2\n const fontSize = baseFontSize * (1 - fontSizeReduction)\n\n const labelPadding = Math.max(1, fontSize * 0.2)\n const labelText = group.name\n\n const tempText = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"text\",\n )\n tempText.setAttribute(\"font-size\", fontSize.toString())\n tempText.setAttribute(\"font-family\", \"Arial, sans-serif\")\n tempText.textContent = labelText\n svg.appendChild(tempText)\n const textBBox = tempText.getBBox()\n svg.removeChild(tempText)\n\n const labelWidth = textBBox.width + labelPadding * 2\n const labelHeight = fontSize + labelPadding * 2\n const labelX = groupBounds.minX - totalPadding\n const labelY = groupBounds.minY - totalPadding - labelHeight\n\n const labelBg = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"rect\",\n )\n labelBg.setAttribute(\"class\", \"schematic-group-overlay\")\n labelBg.setAttribute(\"x\", labelX.toString())\n labelBg.setAttribute(\"y\", (labelY - labelHeight).toString())\n labelBg.setAttribute(\"width\", labelWidth.toString())\n labelBg.setAttribute(\"height\", labelHeight.toString())\n labelBg.setAttribute(\"fill\", \"transparent\")\n labelBg.setAttribute(\"rx\", \"0\")\n labelBg.setAttribute(\"ry\", \"0\")\n\n const groupLabel = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"text\",\n )\n groupLabel.setAttribute(\"class\", \"schematic-group-overlay\")\n groupLabel.setAttribute(\"x\", (labelX + labelPadding).toString())\n groupLabel.setAttribute(\n \"y\",\n (labelY + labelHeight - labelPadding).toString(),\n )\n groupLabel.setAttribute(\"fill\", group.color)\n groupLabel.setAttribute(\"font-size\", fontSize.toString())\n groupLabel.setAttribute(\"font-family\", \"Arial, sans-serif\")\n groupLabel.setAttribute(\n \"font-weight\",\n group.depthLevel === 0 ? \"600\" : \"500\",\n )\n groupLabel.setAttribute(\"stroke\", group.color)\n groupLabel.setAttribute(\n \"stroke-width\",\n Math.max(0.2, fontSize * 0.02).toString(),\n )\n groupLabel.textContent = labelText\n\n svg.appendChild(groupOverlay)\n svg.appendChild(labelBg)\n svg.appendChild(groupLabel)\n })\n } catch (error) {\n console.error(\"Error creating group overlays:\", error)\n }\n }, 10) // Small delay to ensure SVG is ready\n\n return () => clearTimeout(timeoutId)\n }, [svgDivRef, circuitJsonKey, showGroups])\n}\n\nfunction calculateGroupBounds(components: any[], svg: SVGElement) {\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity\n\n for (const component of components) {\n let componentElement = svg.querySelector(\n `g[data-schematic-component-id=\"${component.schematic_component_id}\"]`,\n )\n\n if (!componentElement) {\n componentElement = svg.querySelector(\n `[data-schematic-component-id=\"${component.schematic_component_id}\"]`,\n )\n }\n\n if (componentElement) {\n const bbox = (componentElement as SVGGraphicsElement).getBBox()\n minX = Math.min(minX, bbox.x)\n minY = Math.min(minY, bbox.y)\n maxX = Math.max(maxX, bbox.x + bbox.width)\n maxY = Math.max(maxY, bbox.y + bbox.height)\n }\n }\n\n if (minX === Infinity) {\n return null\n }\n\n const bounds = { minX, minY, maxX, maxY }\n return bounds\n}\n","import Debug from \"debug\"\n\nexport const debug = Debug(\"schematic-viewer\")\n\nexport const enableDebug = () => {\n Debug.enable(\"schematic-viewer*\")\n}\n\nexport default debug\n","import { useEffect, useState } from \"react\"\n\nexport const useResizeHandling = (\n containerRef: React.RefObject<HTMLElement>,\n) => {\n const [containerWidth, setContainerWidth] = useState(0)\n const [containerHeight, setContainerHeight] = useState(0)\n\n useEffect(() => {\n if (!containerRef.current) return\n\n const updateDimensions = () => {\n const rect = containerRef.current?.getBoundingClientRect()\n setContainerWidth(rect?.width || 0)\n setContainerHeight(rect?.height || 0)\n }\n\n // Set initial dimensions\n updateDimensions()\n\n // Add resize listener\n const resizeObserver = new ResizeObserver(updateDimensions)\n resizeObserver.observe(containerRef.current)\n\n // Fallback to window resize\n window.addEventListener(\"resize\", updateDimensions)\n\n return () => {\n resizeObserver.disconnect()\n window.removeEventListener(\"resize\", updateDimensions)\n }\n }, [])\n\n return { containerWidth, containerHeight }\n}\n","import { su } from \"@tscircuit/soup-util\"\nimport Debug from \"lib/utils/debug\"\nimport { getComponentOffsetDueToEvents } from \"lib/utils/get-component-offset-due-to-events\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\nimport { type Matrix, compose } from \"transformation-matrix\"\nimport type {\n EditSchematicComponentLocationEventWithElement,\n ManualEditEvent,\n} from \"../types/edit-events\"\n\nconst debug = Debug.extend(\"useComponentDragging\")\n\nexport const useComponentDragging = ({\n onEditEvent,\n editEvents = [],\n circuitJson,\n cancelDrag,\n svgToScreenProjection,\n realToSvgProjection,\n enabled = false,\n snapToGrid = false,\n}: {\n circuitJson: any[]\n editEvents: ManualEditEvent[]\n /** The projection returned from use-mouse-matrix-transform, indicating zoom on svg */\n svgToScreenProjection: Matrix\n /** The projection returned from circuit-to-svg, mm to svg */\n realToSvgProjection: Matrix\n onEditEvent?: (event: ManualEditEvent) => void\n cancelDrag?: () => void\n enabled?: boolean\n snapToGrid?: boolean\n}): {\n handleMouseDown: (e: React.MouseEvent) => void\n handleTouchStart: (e: React.TouchEvent) => void\n isDragging: boolean\n activeEditEvent: EditSchematicComponentLocationEventWithElement | null\n} => {\n const [activeEditEvent, setActiveEditEvent] =\n useState<EditSchematicComponentLocationEventWithElement | null>(null)\n const realToScreenProjection = compose(\n realToSvgProjection,\n svgToScreenProjection,\n )\n\n /**\n * Drag start position in screen space\n */\n const dragStartPosRef = useRef<{\n x: number\n y: number\n } | null>(null)\n\n const activeEditEventRef =\n useRef<EditSchematicComponentLocationEventWithElement | null>(null)\n\n // Store the latest positions of components being tracked\n const componentPositionsRef = useRef<Map<string, { x: number; y: number }>>(\n new Map(),\n )\n\n // Update position map with the latest positions from edit events\n useEffect(() => {\n // Process completed edit events to track latest positions\n editEvents.forEach((event) => {\n if (\n \"edit_event_type\" in event &&\n event.edit_event_type === \"edit_schematic_component_location\" &&\n !event.in_progress\n ) {\n componentPositionsRef.current.set(event.schematic_component_id, {\n ...event.new_center,\n })\n }\n })\n }, [editEvents])\n\n const startDrag = useCallback(\n (clientX: number, clientY: number, target: Element) => {\n if (!enabled) return false\n\n const componentGroup = target.closest(\n '[data-circuit-json-type=\"schematic_component\"]',\n )\n if (!componentGroup) return false\n\n const schematic_component_id = componentGroup.getAttribute(\n \"data-schematic-component-id\",\n )\n if (!schematic_component_id) return false\n\n if (cancelDrag) cancelDrag()\n\n const schematic_component = su(circuitJson).schematic_component.get(\n schematic_component_id,\n )\n if (!schematic_component) return false\n\n dragStartPosRef.current = { x: clientX, y: clientY }\n\n let current_position: { x: number; y: number }\n const trackedPosition = componentPositionsRef.current.get(\n schematic_component_id,\n )\n\n if (trackedPosition) {\n current_position = { ...trackedPosition }\n } else {\n const editEventOffset = getComponentOffsetDueToEvents({\n editEvents,\n schematic_component_id: schematic_component_id,\n })\n\n current_position = {\n x: schematic_component.center.x + editEventOffset.x,\n y: schematic_component.center.y + editEventOffset.y,\n }\n\n componentPositionsRef.current.set(schematic_component_id, {\n ...current_position,\n })\n }\n\n const newEditEvent: EditSchematicComponentLocationEventWithElement = {\n edit_event_id: Math.random().toString(36).substr(2, 9),\n edit_event_type: \"edit_schematic_component_location\",\n schematic_component_id: schematic_component_id,\n original_center: current_position,\n new_center: { ...current_position },\n in_progress: true,\n created_at: Date.now(),\n _element: componentGroup as any,\n }\n\n activeEditEventRef.current = newEditEvent\n setActiveEditEvent(newEditEvent)\n return true\n },\n [cancelDrag, enabled, circuitJson, editEvents],\n )\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n startDrag(e.clientX, e.clientY, e.target as Element)\n },\n [startDrag],\n )\n\n const handleTouchStart = useCallback(\n (e: React.TouchEvent) => {\n if (e.touches.length !== 1) return\n const touch = e.touches[0]\n if (startDrag(touch.clientX, touch.clientY, e.target as Element)) {\n e.preventDefault()\n }\n },\n [startDrag],\n )\n\n const updateDragPosition = useCallback(\n (clientX: number, clientY: number) => {\n if (!activeEditEventRef.current || !dragStartPosRef.current) return\n\n const screenDelta = {\n x: clientX - dragStartPosRef.current.x,\n y: clientY - dragStartPosRef.current.y,\n }\n\n const mmDelta = {\n x: screenDelta.x / realToScreenProjection.a,\n y: screenDelta.y / realToScreenProjection.d,\n }\n\n let newCenter = {\n x: activeEditEventRef.current.original_center.x + mmDelta.x,\n y: activeEditEventRef.current.original_center.y + mmDelta.y,\n }\n if (snapToGrid) {\n const snap = (v: number) => Math.round(v * 10) / 10\n newCenter = { x: snap(newCenter.x), y: snap(newCenter.y) }\n }\n\n const newEditEvent = {\n ...activeEditEventRef.current,\n new_center: newCenter,\n }\n\n activeEditEventRef.current = newEditEvent\n setActiveEditEvent(newEditEvent)\n },\n [realToScreenProjection, snapToGrid],\n )\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => updateDragPosition(e.clientX, e.clientY),\n [updateDragPosition],\n )\n\n const handleTouchMove = useCallback(\n (e: TouchEvent) => {\n if (e.touches.length !== 1 || !activeEditEventRef.current) return\n e.preventDefault()\n const touch = e.touches[0]\n updateDragPosition(touch.clientX, touch.clientY)\n },\n [updateDragPosition],\n )\n\n const endDrag = useCallback(() => {\n if (!activeEditEventRef.current) return\n const finalEvent = {\n ...activeEditEventRef.current,\n in_progress: false,\n }\n\n componentPositionsRef.current.set(finalEvent.schematic_component_id, {\n ...finalEvent.new_center,\n })\n\n debug(\"endDrag calling onEditEvent with new edit event\", {\n newEditEvent: finalEvent,\n })\n if (onEditEvent) onEditEvent(finalEvent)\n activeEditEventRef.current = null\n dragStartPosRef.current = null\n setActiveEditEvent(null)\n }, [onEditEvent])\n\n const handleMouseUp = useCallback(() => endDrag(), [endDrag])\n const handleTouchEnd = useCallback(() => endDrag(), [endDrag])\n\n useEffect(() => {\n window.addEventListener(\"mousemove\", handleMouseMove)\n window.addEventListener(\"mouseup\", handleMouseUp)\n window.addEventListener(\"touchmove\", handleTouchMove, { passive: false })\n window.addEventListener(\"touchend\", handleTouchEnd)\n return () => {\n window.removeEventListener(\"mousemove\", handleMouseMove)\n window.removeEventListener(\"mouseup\", handleMouseUp)\n window.removeEventListener(\"touchmove\", handleTouchMove)\n window.removeEventListener(\"touchend\", handleTouchEnd)\n }\n }, [handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd])\n\n return {\n handleMouseDown,\n handleTouchStart,\n isDragging: !!activeEditEventRef.current,\n activeEditEvent: activeEditEvent,\n }\n}\n","export const zIndexMap = {\n schematicEditIcon: 50,\n schematicGridIcon: 49,\n spiceSimulationIcon: 50,\n viewMenuIcon: 48,\n viewMenu: 55,\n viewMenuBackdrop: 54,\n clickToInteractOverlay: 100,\n schematicComponentHoverOutline: 47,\n}\n","import { zIndexMap } from \"../utils/z-index-map\"\n\nexport const EditIcon = ({\n onClick,\n active,\n}: { onClick: () => void; active: boolean }) => {\n const handleInteraction = (e: React.MouseEvent | React.TouchEvent) => {\n e.preventDefault()\n onClick()\n }\n\n return (\n <div\n onClick={handleInteraction}\n onTouchEnd={handleInteraction}\n title={active ? \"Disable edit mode\" : \"Enable edit mode\"}\n style={{\n position: \"absolute\",\n top: \"16px\",\n right: \"64px\",\n backgroundColor: active ? \"#4CAF50\" : \"#fff\",\n color: active ? \"#fff\" : \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.schematicEditIcon,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\" />\n <path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\" />\n </svg>\n </div>\n )\n}\n","import { zIndexMap } from \"../utils/z-index-map\"\n\nexport const GridIcon = ({\n onClick,\n active,\n}: { onClick: () => void; active: boolean }) => {\n const handleInteraction = (e: React.MouseEvent | React.TouchEvent) => {\n e.preventDefault()\n onClick()\n }\n\n return (\n <div\n onClick={handleInteraction}\n onTouchEnd={handleInteraction}\n title={active ? \"Hide grid\" : \"Show grid\"}\n style={{\n position: \"absolute\",\n top: \"56px\",\n right: \"64px\",\n backgroundColor: active ? \"#4CAF50\" : \"#fff\",\n color: active ? \"#fff\" : \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.schematicGridIcon,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM14 14h7v7h-7z\" />\n </svg>\n </div>\n )\n}\n","import { zIndexMap } from \"../utils/z-index-map\"\n\nexport const ViewMenuIcon = ({\n onClick,\n active,\n}: { onClick: () => void; active: boolean }) => {\n const handleInteraction = (e: React.MouseEvent | React.TouchEvent) => {\n e.preventDefault()\n onClick()\n }\n\n return (\n <div\n onClick={handleInteraction}\n onTouchEnd={handleInteraction}\n title={active ? \"Hide view menu\" : \"Show view menu\"}\n style={{\n position: \"absolute\",\n top: \"16px\",\n right: \"16px\",\n backgroundColor: active ? \"#4CAF50\" : \"#fff\",\n color: active ? \"#fff\" : \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.viewMenuIcon,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\n </svg>\n </div>\n )\n}\n","import { useMemo } from \"react\"\nimport { su } from \"@tscircuit/soup-util\"\nimport type { CircuitJson } from \"circuit-json\"\nimport { zIndexMap } from \"../utils/z-index-map\"\nimport packageJson from \"../../package.json\"\n\ninterface ViewMenuProps {\n circuitJson: CircuitJson\n circuitJsonKey: string\n isVisible: boolean\n onClose: () => void\n showGroups: boolean\n onToggleGroups: (show: boolean) => void\n}\n\nexport const ViewMenu = ({\n circuitJson,\n circuitJsonKey,\n isVisible,\n onClose,\n showGroups,\n onToggleGroups,\n}: ViewMenuProps) => {\n const hasGroups = useMemo(() => {\n if (!circuitJson || circuitJson.length === 0) return false\n\n try {\n // Check if there are explicit groups\n const sourceGroups = su(circuitJson).source_group?.list() || []\n if (sourceGroups.length > 0) return true\n\n // Check if we can create virtual groups by component type\n const schematicComponents =\n su(circuitJson).schematic_component?.list() || []\n if (schematicComponents.length > 1) {\n const componentTypes = new Set()\n for (const comp of schematicComponents) {\n const sourceComp = su(circuitJson).source_component.get(\n comp.source_component_id!,\n )\n if (sourceComp?.ftype) {\n componentTypes.add(sourceComp.ftype)\n }\n }\n return componentTypes.size > 1 // Only show if there are multiple types\n }\n\n return false\n } catch (error) {\n console.error(\"Error checking for groups:\", error)\n return false\n }\n }, [circuitJsonKey])\n\n if (!isVisible) return null\n\n return (\n <>\n {/* Backdrop */}\n <div\n onClick={onClose}\n onTouchEnd={(e) => {\n e.preventDefault()\n onClose()\n }}\n style={{\n position: \"absolute\",\n inset: 0,\n backgroundColor: \"transparent\",\n zIndex: zIndexMap.viewMenuBackdrop,\n }}\n />\n\n {/* Menu */}\n <div\n style={{\n position: \"absolute\",\n top: \"56px\",\n right: \"16px\",\n backgroundColor: \"#ffffff\",\n color: \"#000000\",\n border: \"1px solid #ccc\",\n borderRadius: \"4px\",\n boxShadow: \"0 4px 12px rgba(0,0,0,0.1)\",\n minWidth: \"200px\",\n zIndex: zIndexMap.viewMenu,\n }}\n >\n {/* Groups Toggle Option */}\n <div\n onClick={() => {\n if (hasGroups) {\n onToggleGroups(!showGroups)\n }\n }}\n onTouchEnd={(e) => {\n e.preventDefault()\n if (hasGroups) {\n onToggleGroups(!showGroups)\n }\n }}\n style={{\n padding: \"8px 12px\",\n cursor: hasGroups ? \"pointer\" : \"not-allowed\",\n opacity: hasGroups ? 1 : 0.5,\n fontSize: \"13px\",\n color: \"#000000\",\n fontFamily: \"sans-serif\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n }}\n onMouseEnter={(e) => {\n if (hasGroups) {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\"\n }\n }}\n onMouseLeave={(e) => {\n if (hasGroups) {\n e.currentTarget.style.backgroundColor = \"transparent\"\n }\n }}\n >\n <div\n style={{\n width: \"16px\",\n height: \"16px\",\n border: \"2px solid #000\",\n borderRadius: \"2px\",\n backgroundColor: \"transparent\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"10px\",\n fontWeight: \"bold\",\n }}\n >\n {showGroups && \"✓\"}\n </div>\n View Schematic Groups\n </div>\n\n {!hasGroups && (\n <div\n style={{\n padding: \"8px 12px\",\n fontSize: \"11px\",\n color: \"#666\",\n fontStyle: \"italic\",\n }}\n >\n No groups found in this schematic\n </div>\n )}\n\n {/* Version Info */}\n <div\n style={{\n padding: \"4px 8px\",\n fontSize: \"12px\",\n color: \"#999\",\n borderTop: \"1px solid #eee\",\n textAlign: \"center\",\n }}\n >\n v{String(packageJson?.version)}\n </div>\n </div>\n </>\n )\n}\n","{\n \"name\": \"@tscircuit/schematic-viewer\",\n \"version\": \"2.0.51\",\n \"main\": \"dist/index.js\",\n \"type\": \"module\",\n \"scripts\": {\n \"start\": \"cosmos\",\n \"build:webworker\": \"tsup --config tsup-webworker.config.ts\",\n \"build:blob-url\": \"bun scripts/build-worker-blob-url.ts\",\n \"build\": \"bun run build:webworker && bun run build:blob-url && tsup-node ./lib/index.ts --dts --format esm --sourcemap\",\n \"build:site\": \"cosmos-export\",\n \"vercel-build\": \"bun run build:webworker && bun run build:blob-url && bun run build:site\",\n \"format\": \"biome format --write .\",\n \"format:check\": \"biome format .\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^1.9.4\",\n \"@types/bun\": \"latest\",\n \"@types/debug\": \"^4.1.12\",\n \"@types/react\": \"^19.0.1\",\n \"@types/react-dom\": \"^19.0.2\",\n \"@types/recharts\": \"^2.0.1\",\n \"@vitejs/plugin-react\": \"^4.3.4\",\n \"react\": \"^19.1.0\",\n \"react-cosmos\": \"^6.2.1\",\n \"react-cosmos-plugin-vite\": \"^6.2.0\",\n \"react-dom\": \"^19.1.0\",\n \"react-reconciler\": \"^0.31.0\",\n \"semver\": \"^7.7.2\",\n \"tscircuit\": \"^0.0.1149\",\n \"tsup\": \"^8.3.5\",\n \"vite\": \"^6.0.3\"\n },\n \"peerDependencies\": {\n \"typescript\": \"^5.0.0\",\n \"tscircuit\": \"*\"\n },\n \"dependencies\": {\n \"chart.js\": \"^4.5.0\",\n \"circuit-json-to-spice\": \"^0.0.30\",\n \"debug\": \"^4.4.0\",\n \"performance-now\": \"^2.1.0\",\n \"react-chartjs-2\": \"^5.3.0\",\n \"use-mouse-matrix-transform\": \"^1.2.2\"\n }\n}\n","export const SpiceIcon = () => (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M3 12h2.5l2.5-9 4 18 4-9h5.5\" />\n </svg>\n)\n","import { SpiceIcon } from \"./SpiceIcon\"\nimport { zIndexMap } from \"../utils/z-index-map\"\n\nexport const SpiceSimulationIcon = ({\n onClick,\n}: {\n onClick: () => void\n}) => {\n return (\n <div\n onClick={onClick}\n title=\"Run SPICE simulation\"\n style={{\n position: \"absolute\",\n top: \"16px\",\n right: \"112px\",\n backgroundColor: \"#fff\",\n color: \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.spiceSimulationIcon,\n }}\n >\n <SpiceIcon />\n </div>\n )\n}\n","import { useMemo } from \"react\"\nimport {\n Chart as ChartJS,\n type ChartOptions,\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n Title,\n Tooltip,\n Legend,\n} from \"chart.js\"\nimport { Line } from \"react-chartjs-2\"\nimport type { PlotPoint } from \"../hooks/useSpiceSimulation\"\n\nChartJS.register(\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n Title,\n Tooltip,\n Legend,\n)\n\nconst colors = [\"#8884d8\", \"#82ca9d\", \"#ffc658\", \"#ff7300\", \"#387908\"]\n\nconst formatTimeWithUnits = (seconds: number) => {\n if (seconds === 0) return \"0s\"\n const absSeconds = Math.abs(seconds)\n\n let unit = \"s\"\n let scale = 1\n if (absSeconds < 1e-12) {\n unit = \"fs\"\n scale = 1e15\n } else if (absSeconds < 1e-9) {\n unit = \"ps\"\n scale = 1e12\n } else if (absSeconds < 1e-6) {\n unit = \"ns\"\n scale = 1e9\n } else if (absSeconds < 1e-3) {\n unit = \"us\"\n scale = 1e6\n } else if (absSeconds < 1) {\n unit = \"ms\"\n scale = 1e3\n }\n\n return `${parseFloat((seconds * scale).toPrecision(3))}${unit}`\n}\n\nexport const SpicePlot = ({\n plotData,\n nodes,\n isLoading,\n error,\n hasRun,\n}: {\n plotData: PlotPoint[]\n nodes: string[]\n isLoading: boolean\n error: string | null\n hasRun: boolean\n}) => {\n const yAxisLabel = useMemo(() => {\n const hasVoltage = nodes.some((n) => n.toLowerCase().startsWith(\"v(\"))\n const hasCurrent = nodes.some((n) => n.toLowerCase().startsWith(\"i(\"))\n if (hasVoltage && hasCurrent) return \"Value\"\n if (hasVoltage) return \"Voltage (V)\"\n if (hasCurrent) return \"Current (A)\"\n return \"Value\"\n }, [nodes])\n\n if (isLoading) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n Running simulation...\n </div>\n )\n }\n\n if (!hasRun) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n Click \"Run\" to start the simulation.\n </div>\n )\n }\n\n if (error) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"red\",\n }}\n >\n Error: {error}\n </div>\n )\n }\n\n if (plotData.length === 0) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n No data to plot. Check simulation output or SPICE netlist.\n </div>\n )\n }\n\n const chartData = {\n datasets: nodes.map((node, i) => ({\n label: node,\n data: plotData.map((p) => ({\n x: Number(p.name),\n y: p[node] as number,\n })),\n borderColor: colors[i % colors.length],\n backgroundColor: colors[i % colors.length],\n fill: false,\n tension: 0.1,\n })),\n }\n\n const options: ChartOptions<\"line\"> = {\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n position: \"top\" as const,\n labels: {\n font: {\n family: \"sans-serif\",\n },\n },\n },\n title: {\n display: false,\n },\n tooltip: {\n callbacks: {\n title: (tooltipItems) => {\n if (tooltipItems.length > 0) {\n const item = tooltipItems[0]\n return formatTimeWithUnits(item.parsed.x as number)\n }\n return \"\"\n },\n },\n },\n },\n scales: {\n x: {\n type: \"linear\",\n title: {\n display: true,\n text: \"Time\",\n font: {\n family: \"sans-serif\",\n },\n },\n ticks: {\n callback: (value) => formatTimeWithUnits(value as number),\n font: {\n family: \"sans-serif\",\n },\n },\n },\n y: {\n title: {\n display: true,\n text: yAxisLabel,\n font: {\n family: \"sans-serif\",\n },\n },\n ticks: {\n font: {\n family: \"sans-serif\",\n },\n },\n },\n },\n }\n\n return (\n <div style={{ position: \"relative\", height: \"300px\", width: \"100%\" }}>\n <Line options={options} data={chartData} />\n </div>\n )\n}\n","import { SpicePlot } from \"./SpicePlot\"\nimport type { PlotPoint } from \"../hooks/useSpiceSimulation\"\nimport { useEffect, useState } from \"react\"\n\ninterface SpiceSimulationOverlayProps {\n spiceString: string | null\n onClose: () => void\n plotData: PlotPoint[]\n nodes: string[]\n isLoading: boolean\n error: string | null\n simOptions: {\n showVoltage: boolean\n showCurrent: boolean\n startTime: number\n duration: number\n }\n onSimOptionsChange: (\n options: SpiceSimulationOverlayProps[\"simOptions\"],\n ) => void\n hasRun: boolean\n}\n\nexport const SpiceSimulationOverlay = ({\n spiceString,\n onClose,\n plotData,\n nodes,\n isLoading,\n error,\n simOptions,\n onSimOptionsChange,\n hasRun,\n}: SpiceSimulationOverlayProps) => {\n const [startTimeDraft, setStartTimeDraft] = useState(\n String(simOptions.startTime),\n )\n const [durationDraft, setDurationDraft] = useState(\n String(simOptions.duration),\n )\n\n useEffect(() => {\n setStartTimeDraft(String(simOptions.startTime))\n setDurationDraft(String(simOptions.duration))\n }, [simOptions.startTime, simOptions.duration])\n\n const handleRerun = () => {\n onSimOptionsChange({\n ...simOptions,\n startTime: Number(startTimeDraft),\n duration: Number(durationDraft),\n })\n }\n\n const filteredNodes = nodes.filter((node) => {\n const isVoltage = node.toLowerCase().startsWith(\"v(\")\n const isCurrent = node.toLowerCase().startsWith(\"i(\")\n if (simOptions.showVoltage && isVoltage) return true\n if (simOptions.showCurrent && isCurrent) return true\n return false\n })\n\n return (\n <div\n style={{\n position: \"fixed\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: \"rgba(0, 0, 0, 0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex: 1002,\n fontFamily: \"sans-serif\",\n }}\n >\n <div\n style={{\n backgroundColor: \"white\",\n padding: \"24px\",\n borderRadius: \"12px\",\n width: \"90%\",\n maxWidth: \"900px\",\n boxShadow: \"0 4px 20px rgba(0, 0, 0, 0.15)\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: \"24px\",\n borderBottom: \"1px solid #eee\",\n paddingBottom: \"16px\",\n }}\n >\n <h2\n style={{\n margin: 0,\n fontSize: \"22px\",\n fontWeight: 600,\n color: \"#333\",\n }}\n >\n SPICE Simulation\n </h2>\n <button\n onClick={onClose}\n style={{\n background: \"none\",\n border: \"none\",\n fontSize: \"28px\",\n cursor: \"pointer\",\n color: \"#888\",\n padding: 0,\n lineHeight: 1,\n }}\n >\n &times;\n </button>\n </div>\n <div>\n <SpicePlot\n plotData={plotData}\n nodes={filteredNodes}\n isLoading={isLoading}\n error={error}\n hasRun={hasRun}\n />\n </div>\n <div\n style={{\n marginTop: \"16px\",\n padding: \"12px\",\n backgroundColor: \"#f7f7f7\",\n borderRadius: \"6px\",\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"24px\",\n alignItems: \"center\",\n fontSize: \"14px\",\n }}\n >\n <div style={{ display: \"flex\", gap: \"16px\" }}>\n <label\n style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}\n >\n <input\n type=\"checkbox\"\n checked={simOptions.showVoltage}\n onChange={(e) =>\n onSimOptionsChange({\n ...simOptions,\n showVoltage: e.target.checked,\n })\n }\n />\n Voltage\n </label>\n <label\n style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}\n >\n <input\n type=\"checkbox\"\n checked={simOptions.showCurrent}\n onChange={(e) =>\n onSimOptionsChange({\n ...simOptions,\n showCurrent: e.target.checked,\n })\n }\n />\n Current\n </label>\n </div>\n <div style={{ display: \"flex\", gap: \"16px\", alignItems: \"center\" }}>\n <label htmlFor=\"startTime\">Start Time (ms):</label>\n <input\n id=\"startTime\"\n type=\"number\"\n value={startTimeDraft}\n onChange={(e) => setStartTimeDraft(e.target.value)}\n style={{\n width: \"80px\",\n padding: \"4px 8px\",\n borderRadius: \"4px\",\n border: \"1px solid #ccc\",\n }}\n />\n <label htmlFor=\"duration\">Duration (ms):</label>\n <input\n id=\"duration\"\n type=\"number\"\n value={durationDraft}\n onChange={(e) => setDurationDraft(e.target.value)}\n style={{\n width: \"80px\",\n padding: \"4px 8px\",\n borderRadius: \"4px\",\n border: \"1px solid #ccc\",\n }}\n />\n <button\n onClick={handleRerun}\n style={{\n padding: \"4px 12px\",\n borderRadius: \"4px\",\n border: \"1px solid #ccc\",\n backgroundColor: \"#f0f0f0\",\n cursor: \"pointer\",\n }}\n >\n {hasRun ? \"Rerun\" : \"Run\"}\n </button>\n </div>\n </div>\n <div style={{ marginTop: \"24px\" }}>\n <h3\n style={{\n marginTop: 0,\n marginBottom: \"12px\",\n fontSize: \"18px\",\n fontWeight: 600,\n color: \"#333\",\n }}\n >\n SPICE Netlist\n </h3>\n <pre\n style={{\n backgroundColor: \"#fafafa\",\n padding: \"16px\",\n borderRadius: \"6px\",\n maxHeight: \"150px\",\n overflowY: \"auto\",\n border: \"1px solid #eee\",\n color: \"#333\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n }}\n >\n {spiceString}\n </pre>\n </div>\n </div>\n </div>\n )\n}\n","import { useState, useEffect } from \"react\"\nimport type * as EecircuitEngine from \"../types/eecircuit-engine\"\n// @ts-ignore\nimport { getSpiceSimulationWorkerBlobUrl } from \"../workers/spice-simulation.worker.blob.js\"\n\n// Types from eecircuit-engine interface\ntype RealDataType = {\n name: string\n type: string\n values: number[]\n}\ntype ComplexNumber = {\n real: number\n img: number\n}\ntype ComplexDataType = {\n name: string\n type: string\n values: ComplexNumber[]\n}\ntype EecEngineResult =\n | {\n header: string\n numVariables: number\n variableNames: string[]\n numPoints: number\n dataType: \"real\"\n data: RealDataType[]\n }\n | {\n header: string\n numVariables: number\n variableNames: string[]\n numPoints: number\n dataType: \"complex\"\n data: ComplexDataType[]\n }\n\nexport interface PlotPoint {\n name: string // time or sweep variable\n [key: string]: number | string\n}\n\nconst parseEecEngineOutput = (\n result: EecEngineResult,\n): { plotData: PlotPoint[]; nodes: string[] } => {\n const columnData: Record<string, number[]> = {}\n\n if (result.dataType === \"real\") {\n result.data.forEach((col) => {\n columnData[col.name] = col.values\n })\n } else if (result.dataType === \"complex\") {\n result.data.forEach((col) => {\n // For now, plot the real part of complex numbers\n columnData[col.name] = col.values.map((v) => v.real)\n })\n } else {\n throw new Error(\"Unsupported data type in simulation result\")\n }\n\n const timeKey = Object.keys(columnData).find(\n (k) => k.toLowerCase() === \"time\" || k.toLowerCase() === \"frequency\",\n )\n if (!timeKey) {\n throw new Error(\"No time or frequency data in simulation result\")\n }\n const timeValues = columnData[timeKey]\n const probedVariables = Object.keys(columnData).filter((k) => k !== timeKey)\n const plotableNodes = probedVariables\n\n const plotData: PlotPoint[] = timeValues.map((t: number, i: number) => {\n const point: PlotPoint = { name: t.toExponential(2) }\n probedVariables.forEach((variable) => {\n point[variable] = columnData[variable][i]\n })\n return point\n })\n\n return { plotData, nodes: plotableNodes }\n}\n\ntype WorkerMessage =\n | {\n type: \"result\"\n result: EecEngineResult\n }\n | { type: \"error\"; error: string }\n\nexport const useSpiceSimulation = (spiceString: string | null) => {\n const [plotData, setPlotData] = useState<PlotPoint[]>([])\n const [nodes, setNodes] = useState<string[]>([])\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n if (!spiceString) {\n setIsLoading(false)\n setPlotData([])\n setNodes([])\n setError(null)\n return\n }\n setIsLoading(true)\n setError(null)\n setPlotData([])\n setNodes([])\n\n const workerUrl = getSpiceSimulationWorkerBlobUrl()\n\n if (!workerUrl) {\n setError(\"Could not create SPICE simulation worker.\")\n setIsLoading(false)\n return\n }\n\n const worker = new Worker(workerUrl, { type: \"module\" })\n\n worker.onmessage = (event: MessageEvent<WorkerMessage>) => {\n if (event.data.type === \"result\") {\n try {\n const { plotData: parsedData, nodes: parsedNodes } =\n parseEecEngineOutput(event.data.result)\n setPlotData(parsedData)\n setNodes(parsedNodes)\n } catch (e: any) {\n setError(e.message || \"Failed to parse simulation result\")\n console.error(e)\n }\n } else if (event.data.type === \"error\") {\n setError(event.data.error)\n }\n setIsLoading(false)\n }\n\n worker.onerror = (err) => {\n setError(err.message)\n setIsLoading(false)\n }\n\n worker.postMessage({ spiceString })\n\n return () => {\n worker.terminate()\n }\n }, [spiceString])\n\n return { plotData, nodes, isLoading, error }\n}\n","// This file is generated by scripts/build-worker-blob-url.ts\n// Do not edit this file directly.\n\nconst b64 = \"dmFyIGU9bnVsbCxzPWFzeW5jKCk9Pihhd2FpdCBpbXBvcnQoImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vZWVjaXJjdWl0LWVuZ2luZUAxLjUuMi8rZXNtIikpLlNpbXVsYXRpb24sYz1hc3luYygpPT57aWYoZSYmZS5pc0luaXRpYWxpemVkKCkpcmV0dXJuO2xldCBpPWF3YWl0IHMoKTtlPW5ldyBpLGF3YWl0IGUuc3RhcnQoKX07c2VsZi5vbm1lc3NhZ2U9YXN5bmMgaT0+e3RyeXtpZihhd2FpdCBjKCksIWUpdGhyb3cgbmV3IEVycm9yKCJTaW11bGF0aW9uIG5vdCBpbml0aWFsaXplZCIpO2xldCB0PWkuZGF0YS5zcGljZVN0cmluZyxhPXQubWF0Y2goL3dyZGF0YVxzKyhcUyspXHMrKC4qKS9pKTtpZihhKXtsZXQgbz1gLnByb2JlICR7YVsyXS50cmltKCkuc3BsaXQoL1xzKy8pLmpvaW4oIiAiKX1gO3Q9dC5yZXBsYWNlKC93cmRhdGEuKi9pLG8pfWVsc2UgaWYoIXQubWF0Y2goL1wucHJvYmUvaSkpdGhyb3cgdC5tYXRjaCgvcGxvdFxzKyguKikvaSk/bmV3IEVycm9yKCJUaGUgJ3Bsb3QnIGNvbW1hbmQgaXMgbm90IHN1cHBvcnRlZCBmb3IgZGF0YSBleHRyYWN0aW9uLiBQbGVhc2UgdXNlICd3cmRhdGEgPGZpbGVuYW1lPiA8dmFyMT4gLi4uJyBvciAnLnByb2JlIDx2YXIxPiAuLi4nIGluc3RlYWQuIik6bmV3IEVycm9yKCJObyAnLnByb2JlJyBvciAnd3JkYXRhJyBjb21tYW5kIGZvdW5kIGluIFNQSUNFIGZpbGUuIFVzZSAnd3JkYXRhIDxmaWxlbmFtZT4gPHZhcjE+IC4uLicgdG8gc3BlY2lmeSBvdXRwdXQuIik7ZS5zZXROZXRMaXN0KHQpO2xldCBuPWF3YWl0IGUucnVuU2ltKCk7c2VsZi5wb3N0TWVzc2FnZSh7dHlwZToicmVzdWx0IixyZXN1bHQ6bn0pfWNhdGNoKHQpe3NlbGYucG9zdE1lc3NhZ2Uoe3R5cGU6ImVycm9yIixlcnJvcjp0Lm1lc3NhZ2V9KX19Owo=\";\n\nlet blobUrl = null;\n\nexport const getSpiceSimulationWorkerBlobUrl = () => {\n if (typeof window === \"undefined\") return null;\n if (blobUrl) return blobUrl;\n\n try {\n const blob = new Blob([atob(b64)], { type: \"application/javascript\" });\n blobUrl = URL.createObjectURL(blob);\n return blobUrl;\n } catch (e) {\n console.error(\"Failed to create blob URL for worker\", e);\n return null;\n }\n};\n","import { circuitJsonToSpice } from \"circuit-json-to-spice\"\nimport type { CircuitJson } from \"circuit-json\"\n\nexport interface SpiceSimOptions {\n showVoltage: boolean\n showCurrent: boolean\n startTime: number // in ms\n duration: number // in ms\n}\n\nconst formatSimTime = (seconds: number): string => {\n if (seconds === 0) return \"0\"\n const absSeconds = Math.abs(seconds)\n\n const precision = (v: number) => v.toPrecision(4)\n\n if (absSeconds >= 1) return precision(seconds)\n if (absSeconds >= 1e-3) return `${precision(seconds * 1e3)}m`\n if (absSeconds >= 1e-6) return `${precision(seconds * 1e6)}u`\n if (absSeconds >= 1e-9) return `${precision(seconds * 1e9)}n`\n if (absSeconds >= 1e-12) return `${precision(seconds * 1e12)}p`\n if (absSeconds >= 1e-15) return `${precision(seconds * 1e15)}f`\n\n return seconds.toExponential(3)\n}\n\nexport const getSpiceFromCircuitJson = (\n circuitJson: CircuitJson,\n options?: Partial<SpiceSimOptions>,\n): string => {\n const spiceNetlist = circuitJsonToSpice(circuitJson as any)\n const baseSpiceString = spiceNetlist.toSpiceString()\n\n const lines = baseSpiceString.split(\"\\n\").filter((l) => l.trim() !== \"\")\n const componentLines = lines.filter(\n (l) => !l.startsWith(\"*\") && !l.startsWith(\".\") && l.trim() !== \"\",\n )\n\n const allNodes = new Set<string>()\n const capacitorNodes = new Set<string>()\n const componentNamesToProbeCurrent = new Set<string>()\n\n for (const line of componentLines) {\n const parts = line.trim().split(/\\s+/)\n if (parts.length < 3) continue\n\n const componentName = parts[0]\n const componentType = componentName[0].toUpperCase()\n let nodesOnLine: string[] = []\n\n if ([\"R\", \"C\", \"L\", \"V\", \"I\", \"D\"].includes(componentType)) {\n nodesOnLine = parts.slice(1, 3)\n // Only probe current on voltage sources\n if (componentType === \"V\") {\n componentNamesToProbeCurrent.add(componentName)\n }\n } else if (componentType === \"Q\" && parts.length >= 4) {\n // BJT\n nodesOnLine = parts.slice(1, 4)\n } else if (componentType === \"M\" && parts.length >= 5) {\n // MOSFET\n nodesOnLine = parts.slice(1, 5)\n } else if (componentType === \"X\") {\n // Subcircuit\n // Assume last part is model name, everything in between is a node\n nodesOnLine = parts.slice(1, -1)\n } else {\n continue\n }\n\n nodesOnLine.forEach((node) => allNodes.add(node))\n\n if (componentType === \"C\") {\n nodesOnLine.forEach((node) => capacitorNodes.add(node))\n }\n }\n\n // Do not probe/set IC for ground\n allNodes.delete(\"0\")\n capacitorNodes.delete(\"0\")\n\n const icLines = Array.from(capacitorNodes).map((node) => `.ic V(${node})=0`)\n\n const probes: string[] = []\n const probeVoltages = Array.from(allNodes).map((node) => `V(${node})`)\n probes.push(...probeVoltages)\n const probeCurrents = Array.from(componentNamesToProbeCurrent).map(\n (name) => `I(${name})`,\n )\n probes.push(...probeCurrents)\n\n const probeLine = probes.length > 0 ? `.probe ${probes.join(\" \")}` : \"\"\n\n const tstart_ms = options?.startTime ?? 0\n const duration_ms = options?.duration ?? 20\n const tstart = tstart_ms * 1e-3 // s\n const duration = duration_ms * 1e-3 // s\n\n const tstop = tstart + duration\n const tstep = duration / 50\n const tranLine = `.tran ${formatSimTime(tstep)} ${formatSimTime(\n tstop,\n )} ${formatSimTime(tstart)} UIC`\n\n const endStatement = \".end\"\n const originalLines = baseSpiceString.split(\"\\n\")\n let endIndex = -1\n for (let i = originalLines.length - 1; i >= 0; i--) {\n if (originalLines[i].trim().toLowerCase().startsWith(endStatement)) {\n endIndex = i\n break\n }\n }\n\n const injectionLines = [...icLines, probeLine, tranLine].filter(Boolean)\n\n let finalLines: string[]\n\n if (endIndex !== -1) {\n const beforeEnd = originalLines.slice(0, endIndex)\n const endLineAndAfter = originalLines.slice(endIndex)\n finalLines = [...beforeEnd, ...injectionLines, ...endLineAndAfter]\n } else {\n finalLines = [...originalLines, ...injectionLines, endStatement]\n }\n\n return finalLines.join(\"\\n\")\n}\n","import { useCallback } from \"react\"\n\nexport const STORAGE_KEYS = {\n IS_SHOWING_SCHEMATIC_GROUPS: \"schematic_viewer_show_groups\",\n} as const\n\nexport const getStoredBoolean = (\n key: string,\n defaultValue: boolean,\n): boolean => {\n if (typeof window === \"undefined\") return defaultValue\n try {\n const stored = localStorage.getItem(key)\n return stored !== null ? JSON.parse(stored) : defaultValue\n } catch {\n return defaultValue\n }\n}\n\nexport const setStoredBoolean = (key: string, value: boolean): void => {\n if (typeof window === \"undefined\") return\n try {\n localStorage.setItem(key, JSON.stringify(value))\n } catch {}\n}\n\nexport const useLocalStorage = () => {\n const getBoolean = useCallback(\n (key: string, defaultValue: boolean): boolean => {\n return getStoredBoolean(key, defaultValue)\n },\n [],\n )\n\n const setBoolean = useCallback((key: string, value: boolean): void => {\n setStoredBoolean(key, value)\n }, [])\n\n return {\n getBoolean,\n setBoolean,\n }\n}\n\nexport const useLocalStorageValue = (key: string, defaultValue: boolean) => {\n const { getBoolean, setBoolean } = useLocalStorage()\n\n const getValue = useCallback(() => {\n return getBoolean(key, defaultValue)\n }, [getBoolean, key, defaultValue])\n\n const setValue = useCallback(\n (value: boolean) => {\n setBoolean(key, value)\n },\n [setBoolean, key],\n )\n\n return {\n getValue,\n setValue,\n }\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n type ReactNode,\n} from \"react\"\n\nexport interface BoundingBoxBounds {\n minX: number\n maxX: number\n minY: number\n maxY: number\n}\n\ninterface BoundingBoxRegistration {\n bounds: BoundingBoxBounds | null\n onClick?: ((event: MouseEvent) => void) | undefined\n}\n\nexport interface MouseTrackerContextValue {\n registerBoundingBox: (\n id: string,\n registration: BoundingBoxRegistration,\n ) => void\n updateBoundingBox: (id: string, registration: BoundingBoxRegistration) => void\n unregisterBoundingBox: (id: string) => void\n subscribe: (listener: () => void) => () => void\n isHovering: (id: string) => boolean\n}\n\nexport const MouseTrackerContext =\n createContext<MouseTrackerContextValue | null>(null)\n\nconst DRAG_THRESHOLD_PX = 5\n\nconst boundsAreEqual = (\n a: BoundingBoxBounds | null | undefined,\n b: BoundingBoxBounds | null | undefined,\n) => {\n if (!a && !b) return true\n if (!a || !b) return false\n return (\n a.minX === b.minX &&\n a.maxX === b.maxX &&\n a.minY === b.minY &&\n a.maxY === b.maxY\n )\n}\n\nexport const MouseTracker = ({ children }: { children: ReactNode }) => {\n const existingContext = useContext(MouseTrackerContext)\n\n if (existingContext) {\n return <>{children}</>\n }\n\n const storeRef = useRef({\n pointer: null as { x: number; y: number } | null,\n boundingBoxes: new Map<string, BoundingBoxRegistration>(),\n hoveringIds: new Set<string>(),\n subscribers: new Set<() => void>(),\n mouseDownPosition: null as { x: number; y: number } | null,\n })\n\n const notifySubscribers = useCallback(() => {\n for (const callback of storeRef.current.subscribers) {\n callback()\n }\n }, [])\n\n const updateHovering = useCallback(() => {\n const pointer = storeRef.current.pointer\n const newHovering = new Set<string>()\n\n if (pointer) {\n for (const [id, registration] of storeRef.current.boundingBoxes) {\n const bounds = registration.bounds\n if (!bounds) continue\n if (\n pointer.x >= bounds.minX &&\n pointer.x <= bounds.maxX &&\n pointer.y >= bounds.minY &&\n pointer.y <= bounds.maxY\n ) {\n newHovering.add(id)\n }\n }\n }\n\n const prevHovering = storeRef.current.hoveringIds\n if (\n newHovering.size === prevHovering.size &&\n [...newHovering].every((id) => prevHovering.has(id))\n ) {\n return\n }\n\n storeRef.current.hoveringIds = newHovering\n notifySubscribers()\n }, [notifySubscribers])\n\n const registerBoundingBox = useCallback(\n (id: string, registration: BoundingBoxRegistration) => {\n storeRef.current.boundingBoxes.set(id, registration)\n updateHovering()\n },\n [updateHovering],\n )\n\n const updateBoundingBox = useCallback(\n (id: string, registration: BoundingBoxRegistration) => {\n const existing = storeRef.current.boundingBoxes.get(id)\n if (\n existing &&\n boundsAreEqual(existing.bounds, registration.bounds) &&\n existing.onClick === registration.onClick\n ) {\n return\n }\n storeRef.current.boundingBoxes.set(id, registration)\n updateHovering()\n },\n [updateHovering],\n )\n\n const unregisterBoundingBox = useCallback(\n (id: string) => {\n const removed = storeRef.current.boundingBoxes.delete(id)\n if (removed) {\n updateHovering()\n }\n },\n [updateHovering],\n )\n\n const subscribe = useCallback((listener: () => void) => {\n storeRef.current.subscribers.add(listener)\n return () => {\n storeRef.current.subscribers.delete(listener)\n }\n }, [])\n\n const isHovering = useCallback((id: string) => {\n return storeRef.current.hoveringIds.has(id)\n }, [])\n\n useEffect(() => {\n const handlePointerPosition = (event: PointerEvent | MouseEvent) => {\n const { clientX, clientY } = event\n const pointer = storeRef.current.pointer\n if (pointer && pointer.x === clientX && pointer.y === clientY) {\n return\n }\n storeRef.current.pointer = { x: clientX, y: clientY }\n updateHovering()\n }\n\n const handlePointerLeave = () => {\n if (storeRef.current.pointer === null) return\n storeRef.current.pointer = null\n storeRef.current.mouseDownPosition = null\n updateHovering()\n }\n\n const handleMouseDown = (event: MouseEvent) => {\n storeRef.current.mouseDownPosition = {\n x: event.clientX,\n y: event.clientY,\n }\n }\n\n const handleClick = (event: MouseEvent) => {\n const { clientX, clientY } = event\n const mouseDownPos = storeRef.current.mouseDownPosition\n\n // Check if this was a drag (movement > threshold)\n if (mouseDownPos) {\n const distance = Math.sqrt(\n Math.pow(clientX - mouseDownPos.x, 2) +\n Math.pow(clientY - mouseDownPos.y, 2),\n )\n if (distance > DRAG_THRESHOLD_PX) {\n // This was a drag, not a click - don't trigger onClick\n storeRef.current.mouseDownPosition = null\n return\n }\n }\n\n storeRef.current.mouseDownPosition = null\n\n for (const registration of storeRef.current.boundingBoxes.values()) {\n const bounds = registration.bounds\n if (!bounds) continue\n if (\n clientX >= bounds.minX &&\n clientX <= bounds.maxX &&\n clientY >= bounds.minY &&\n clientY <= bounds.maxY\n ) {\n registration.onClick?.(event)\n }\n }\n }\n\n window.addEventListener(\"pointermove\", handlePointerPosition, {\n passive: true,\n })\n window.addEventListener(\"pointerdown\", handlePointerPosition, {\n passive: true,\n })\n window.addEventListener(\"pointerup\", handlePointerPosition, {\n passive: true,\n })\n window.addEventListener(\"pointerleave\", handlePointerLeave)\n window.addEventListener(\"pointercancel\", handlePointerLeave)\n window.addEventListener(\"blur\", handlePointerLeave)\n window.addEventListener(\"mousedown\", handleMouseDown, { passive: true })\n window.addEventListener(\"click\", handleClick, { passive: true })\n\n return () => {\n window.removeEventListener(\"pointermove\", handlePointerPosition)\n window.removeEventListener(\"pointerdown\", handlePointerPosition)\n window.removeEventListener(\"pointerup\", handlePointerPosition)\n window.removeEventListener(\"pointerleave\", handlePointerLeave)\n window.removeEventListener(\"pointercancel\", handlePointerLeave)\n window.removeEventListener(\"blur\", handlePointerLeave)\n window.removeEventListener(\"mousedown\", handleMouseDown)\n window.removeEventListener(\"click\", handleClick)\n }\n }, [updateHovering])\n\n const value = useMemo<MouseTrackerContextValue>(\n () => ({\n registerBoundingBox,\n updateBoundingBox,\n unregisterBoundingBox,\n subscribe,\n isHovering,\n }),\n [\n registerBoundingBox,\n updateBoundingBox,\n unregisterBoundingBox,\n subscribe,\n isHovering,\n ],\n )\n\n return (\n <MouseTrackerContext.Provider value={value}>\n {children}\n </MouseTrackerContext.Provider>\n )\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\nimport { useMouseEventsOverBoundingBox } from \"../hooks/useMouseEventsOverBoundingBox\"\nimport type { BoundingBoxBounds } from \"./MouseTracker\"\nimport { zIndexMap } from \"../utils/z-index-map\"\n\ninterface RelativeRect {\n left: number\n top: number\n width: number\n height: number\n}\n\ninterface Measurement {\n bounds: BoundingBoxBounds\n rect: RelativeRect\n}\n\nconst areMeasurementsEqual = (a: Measurement | null, b: Measurement | null) => {\n if (!a && !b) return true\n if (!a || !b) return false\n return (\n Math.abs(a.bounds.minX - b.bounds.minX) < 0.5 &&\n Math.abs(a.bounds.maxX - b.bounds.maxX) < 0.5 &&\n Math.abs(a.bounds.minY - b.bounds.minY) < 0.5 &&\n Math.abs(a.bounds.maxY - b.bounds.maxY) < 0.5 &&\n Math.abs(a.rect.left - b.rect.left) < 0.5 &&\n Math.abs(a.rect.top - b.rect.top) < 0.5 &&\n Math.abs(a.rect.width - b.rect.width) < 0.5 &&\n Math.abs(a.rect.height - b.rect.height) < 0.5\n )\n}\n\ninterface Props {\n componentId: string\n svgDivRef: React.RefObject<HTMLDivElement | null>\n containerRef: React.RefObject<HTMLDivElement | null>\n onComponentClick?: (componentId: string, event: MouseEvent) => void\n onHoverChange?: (componentId: string, isHovering: boolean) => void\n showOutline: boolean\n circuitJsonKey: string\n}\n\nexport const SchematicComponentMouseTarget = ({\n componentId,\n svgDivRef,\n containerRef,\n onComponentClick,\n onHoverChange,\n showOutline,\n circuitJsonKey,\n}: Props) => {\n const [measurement, setMeasurement] = useState<Measurement | null>(null)\n const frameRef = useRef<number | null>(null)\n\n const measure = useCallback(() => {\n frameRef.current = null\n const svgDiv = svgDivRef.current\n const container = containerRef.current\n if (!svgDiv || !container) {\n setMeasurement((prev) => (prev ? null : prev))\n return\n }\n const element = svgDiv.querySelector<SVGGraphicsElement | HTMLElement>(\n `[data-schematic-component-id=\"${componentId}\"]`,\n )\n if (!element) {\n setMeasurement((prev) => (prev ? null : prev))\n return\n }\n\n const elementRect = element.getBoundingClientRect()\n const containerRect = container.getBoundingClientRect()\n\n const nextMeasurement: Measurement = {\n bounds: {\n minX: elementRect.left,\n maxX: elementRect.right,\n minY: elementRect.top,\n maxY: elementRect.bottom,\n },\n rect: {\n left: elementRect.left - containerRect.left,\n top: elementRect.top - containerRect.top,\n width: elementRect.width,\n height: elementRect.height,\n },\n }\n\n setMeasurement((prev) =>\n areMeasurementsEqual(prev, nextMeasurement) ? prev : nextMeasurement,\n )\n }, [componentId, containerRef, svgDivRef])\n\n const scheduleMeasure = useCallback(() => {\n if (frameRef.current !== null) return\n frameRef.current = window.requestAnimationFrame(measure)\n }, [measure])\n\n useEffect(() => {\n scheduleMeasure()\n }, [scheduleMeasure, circuitJsonKey])\n\n useEffect(() => {\n scheduleMeasure()\n const svgDiv = svgDivRef.current\n const container = containerRef.current\n if (!svgDiv || !container) return\n\n const resizeObserver =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(() => {\n scheduleMeasure()\n })\n : null\n resizeObserver?.observe(container)\n resizeObserver?.observe(svgDiv)\n\n const mutationObserver =\n typeof MutationObserver !== \"undefined\"\n ? new MutationObserver(() => {\n scheduleMeasure()\n })\n : null\n mutationObserver?.observe(svgDiv, {\n attributes: true,\n attributeFilter: [\"style\", \"transform\"],\n subtree: true,\n childList: true,\n })\n\n window.addEventListener(\"scroll\", scheduleMeasure, true)\n window.addEventListener(\"resize\", scheduleMeasure)\n\n return () => {\n resizeObserver?.disconnect()\n mutationObserver?.disconnect()\n window.removeEventListener(\"scroll\", scheduleMeasure, true)\n window.removeEventListener(\"resize\", scheduleMeasure)\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current)\n frameRef.current = null\n }\n }\n }, [scheduleMeasure, svgDivRef, containerRef])\n\n const handleClick = useCallback(\n (event: MouseEvent) => {\n if (onComponentClick) {\n onComponentClick(componentId, event)\n }\n },\n [componentId, onComponentClick],\n )\n\n const bounds = measurement?.bounds ?? null\n\n const { hovering } = useMouseEventsOverBoundingBox({\n bounds,\n onClick: onComponentClick ? handleClick : undefined,\n })\n\n // Notify parent of hover state changes\n useEffect(() => {\n if (onHoverChange) {\n onHoverChange(componentId, hovering)\n }\n }, [hovering, componentId, onHoverChange])\n\n if (!measurement || !hovering || !showOutline) {\n return null\n }\n\n const rect = measurement.rect\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n border: \"1.5px solid rgba(51, 153, 255, 0.9)\",\n pointerEvents: \"none\",\n zIndex: zIndexMap.schematicComponentHoverOutline,\n }}\n />\n )\n}\n","import {\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from \"react\"\nimport {\n MouseTrackerContext,\n type BoundingBoxBounds,\n} from \"../components/MouseTracker\"\n\ninterface UseMouseEventsOverBoundingBoxOptions {\n bounds: BoundingBoxBounds | null\n onClick?: (event: MouseEvent) => void\n}\n\nexport const useMouseEventsOverBoundingBox = (\n options: UseMouseEventsOverBoundingBoxOptions,\n) => {\n const context = useContext(MouseTrackerContext)\n\n if (!context) {\n throw new Error(\n \"useMouseEventsOverBoundingBox must be used within a MouseTracker\",\n )\n }\n\n const id = useId()\n const latestOptionsRef = useRef(options)\n latestOptionsRef.current = options\n\n const handleClick = useMemo(\n () => (event: MouseEvent) => {\n latestOptionsRef.current.onClick?.(event)\n },\n [],\n )\n\n useEffect(() => {\n context.registerBoundingBox(id, {\n bounds: latestOptionsRef.current.bounds,\n onClick: latestOptionsRef.current.onClick ? handleClick : undefined,\n })\n return () => {\n context.unregisterBoundingBox(id)\n }\n }, [context, handleClick, id])\n\n useEffect(() => {\n context.updateBoundingBox(id, {\n bounds: latestOptionsRef.current.bounds,\n onClick: latestOptionsRef.current.onClick ? handleClick : undefined,\n })\n }, [\n context,\n handleClick,\n id,\n options.bounds?.minX,\n options.bounds?.maxX,\n options.bounds?.minY,\n options.bounds?.maxY,\n options.onClick,\n ])\n\n const hovering = useSyncExternalStore(\n context.subscribe,\n () => context.isHovering(id),\n () => false,\n )\n\n return { hovering }\n}\n","import {\n convertCircuitJsonToSchematicSimulationSvg,\n type ColorOverrides,\n} from \"circuit-to-svg\"\nimport { useEffect, useState, useMemo, useRef } from \"react\"\nimport { useResizeHandling } from \"../hooks/use-resize-handling\"\nimport { useMouseMatrixTransform } from \"use-mouse-matrix-transform\"\nimport { toString as transformToString } from \"transformation-matrix\"\nimport type { CircuitJson } from \"circuit-json\"\n\ninterface Props {\n circuitJson: CircuitJson\n containerStyle?: React.CSSProperties\n colorOverrides?: ColorOverrides\n width?: number\n height?: number\n className?: string\n}\n\nexport const AnalogSimulationViewer = ({\n circuitJson: inputCircuitJson,\n containerStyle,\n colorOverrides,\n width,\n height,\n className,\n}: Props) => {\n const [circuitJson, setCircuitJson] = useState<CircuitJson | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n const [svgObjectUrl, setSvgObjectUrl] = useState<string | null>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const imgRef = useRef<HTMLImageElement>(null)\n\n const { containerWidth, containerHeight } = useResizeHandling(\n containerRef as React.RefObject<HTMLElement>,\n )\n\n const [isDragging, setIsDragging] = useState(false)\n\n const {\n ref: transformRef,\n cancelDrag: _cancelDrag,\n transform: _svgToScreenProjection,\n } = useMouseMatrixTransform({\n onSetTransform(transform) {\n if (imgRef.current) {\n imgRef.current.style.transform = transformToString(transform)\n }\n },\n })\n\n const effectiveWidth = width || containerWidth || 1000\n const effectiveHeight = height || containerHeight || 600\n\n // Set CircuitJSON from props\n useEffect(() => {\n setIsLoading(true)\n setError(null)\n setCircuitJson(inputCircuitJson)\n setIsLoading(false)\n }, [inputCircuitJson])\n\n // Find simulation experiment ID from circuit JSON\n const simulationExperimentId = useMemo(() => {\n if (!circuitJson) return null\n const simulationElement = circuitJson.find(\n (el) => el.type === \"simulation_experiment\",\n )\n return simulationElement?.simulation_experiment_id || null\n }, [circuitJson])\n\n // Find simulation graph IDs from circuit JSON\n const simulationGraphIds = useMemo(() => {\n if (!circuitJson) return []\n return circuitJson\n .filter((el) => el.type === \"simulation_transient_voltage_graph\")\n .map((el) => el.simulation_transient_voltage_graph_id)\n }, [circuitJson])\n\n // Generate SVG from CircuitJSON\n const simulationSvg = useMemo(() => {\n if (\n !circuitJson ||\n !effectiveWidth ||\n !effectiveHeight ||\n !simulationExperimentId\n )\n return \"\"\n\n try {\n return convertCircuitJsonToSchematicSimulationSvg({\n circuitJson,\n simulation_experiment_id: simulationExperimentId,\n simulation_transient_voltage_graph_ids: simulationGraphIds,\n width: effectiveWidth,\n height: effectiveHeight,\n schematicOptions: { colorOverrides },\n })\n } catch (fallbackErr) {\n console.error(\"Failed to generate fallback schematic SVG:\", fallbackErr)\n return \"\"\n }\n }, [\n circuitJson,\n effectiveWidth,\n effectiveHeight,\n colorOverrides,\n simulationExperimentId,\n simulationGraphIds,\n ])\n\n // Create/revoke object URL whenever the SVG changes\n useEffect(() => {\n if (!simulationSvg) {\n setSvgObjectUrl(null)\n return\n }\n\n try {\n const blob = new Blob([simulationSvg], { type: \"image/svg+xml\" })\n const url = URL.createObjectURL(blob)\n setSvgObjectUrl(url)\n return () => {\n URL.revokeObjectURL(url)\n }\n } catch (error) {\n console.error(\"Failed to create SVG object URL:\", error)\n setSvgObjectUrl(null)\n }\n }, [simulationSvg])\n\n const containerBackgroundColor = useMemo(() => {\n if (!simulationSvg) return \"transparent\"\n const match = simulationSvg.match(\n /<svg[^>]*style=\"[^\"]*background-color:\\s*([^;\\\"]+)/i,\n )\n return match?.[1] ?? \"transparent\"\n }, [simulationSvg])\n\n const handleMouseDown = (_e: React.MouseEvent) => {\n setIsDragging(true)\n }\n\n const handleTouchStart = (_e: React.TouchEvent) => {\n setIsDragging(true)\n }\n\n useEffect(() => {\n const handleMouseUp = () => {\n setIsDragging(false)\n }\n\n const handleTouchEnd = () => {\n setIsDragging(false)\n }\n\n window.addEventListener(\"mouseup\", handleMouseUp)\n window.addEventListener(\"touchend\", handleTouchEnd)\n\n return () => {\n window.removeEventListener(\"mouseup\", handleMouseUp)\n window.removeEventListener(\"touchend\", handleTouchEnd)\n }\n }, [])\n\n if (isLoading) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"#f5f5f5\",\n minHeight: \"300px\",\n fontFamily: \"sans-serif\",\n fontSize: \"16px\",\n color: \"#666\",\n ...containerStyle,\n }}\n className={className}\n >\n Loading circuit...\n </div>\n )\n }\n\n if (error) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"#fef2f2\",\n minHeight: \"300px\",\n fontFamily: \"sans-serif\",\n fontSize: \"16px\",\n color: \"#dc2626\",\n ...containerStyle,\n }}\n className={className}\n >\n <div style={{ textAlign: \"center\", padding: \"20px\" }}>\n <div style={{ fontWeight: \"bold\", marginBottom: \"8px\" }}>\n Circuit Conversion Error\n </div>\n <div style={{ fontSize: \"14px\" }}>{error}</div>\n </div>\n </div>\n )\n }\n\n if (!simulationSvg) {\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"#f8fafc\",\n minHeight: \"300px\",\n fontFamily: \"sans-serif\",\n gap: \"12px\",\n ...containerStyle,\n }}\n className={className}\n >\n <div style={{ fontSize: \"16px\", color: \"#475569\", fontWeight: 500 }}>\n No Simulation Found\n </div>\n <div style={{ fontSize: \"14px\", color: \"#64748b\" }}>\n Use{\" \"}\n <code\n style={{\n backgroundColor: \"#e2e8f0\",\n padding: \"2px 6px\",\n borderRadius: \"4px\",\n fontFamily: \"monospace\",\n fontSize: \"13px\",\n }}\n >\n {\"<analogsimulation />\"}\n </code>{\" \"}\n to create simulations\n </div>\n </div>\n )\n }\n\n return (\n <div\n ref={(node) => {\n containerRef.current = node\n transformRef.current = node\n }}\n style={{\n position: \"relative\",\n backgroundColor: containerBackgroundColor,\n overflow: \"hidden\",\n minHeight: \"300px\",\n cursor: isDragging ? \"grabbing\" : \"grab\",\n ...containerStyle,\n }}\n className={className}\n onMouseDown={handleMouseDown}\n onTouchStart={handleTouchStart}\n >\n {svgObjectUrl ? (\n <img\n ref={imgRef}\n src={svgObjectUrl}\n alt=\"Circuit Simulation\"\n style={{\n transformOrigin: \"0 0\",\n width: \"100%\",\n height: \"100%\",\n display: \"block\",\n objectFit: \"contain\",\n }}\n />\n ) : (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100%\",\n minHeight: \"300px\",\n color: \"#666\",\n fontFamily: \"sans-serif\",\n }}\n >\n Failed to render SVG\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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","names":["su","useEffect","useRef","su","useEffect","su","useCallback","useEffect","useMemo","useRef","useState","useEffect","su","useEffect","useRef","useState","compose","debug","su","jsx","jsx","jsxs","su","jsx","jsxs","su","jsx","jsx","useMemo","jsx","jsxs","useEffect","useState","jsx","jsxs","useState","useEffect","useState","useEffect","useCallback","useCallback","useEffect","useMemo","useRef","Fragment","jsx","useCallback","useEffect","useRef","useState","useContext","useEffect","useMemo","useRef","useContext","useRef","useMemo","useEffect","jsx","useState","useRef","useCallback","useEffect","jsx","jsxs","debug","useState","circuitJson","useMemo","useEffect","useRef","useCallback","su","useEffect","useState","useMemo","useRef","useMouseMatrixTransform","transformToString","jsx","jsxs","useState","useRef","useEffect","useMemo","error"]}
1
+ {"version":3,"sources":["../lib/components/SchematicViewer.tsx","../lib/hooks/useChangeSchematicComponentLocationsInSvg.ts","../lib/utils/get-component-offset-due-to-events.ts","../lib/hooks/useChangeSchematicTracesForMovedComponents.ts","../lib/hooks/useSchematicGroupsOverlay.ts","../lib/utils/debug.ts","../lib/hooks/use-resize-handling.ts","../lib/hooks/useComponentDragging.ts","../lib/utils/z-index-map.ts","../lib/components/EditIcon.tsx","../lib/components/GridIcon.tsx","../lib/components/ViewMenuIcon.tsx","../lib/components/ViewMenu.tsx","../package.json","../lib/components/SpiceIcon.tsx","../lib/components/SpiceSimulationIcon.tsx","../lib/components/SpicePlot.tsx","../lib/components/SpiceSimulationOverlay.tsx","../lib/hooks/useSpiceSimulation.ts","../lib/workers/spice-simulation.worker.blob.js","../lib/utils/spice-utils.ts","../lib/hooks/useLocalStorage.ts","../lib/components/MouseTracker.tsx","../lib/components/SchematicComponentMouseTarget.tsx","../lib/hooks/useMouseEventsOverBoundingBox.ts","../lib/components/AnalogSimulationViewer.tsx"],"sourcesContent":["import {\n convertCircuitJsonToSchematicSvg,\n type ColorOverrides,\n} from \"circuit-to-svg\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { useChangeSchematicComponentLocationsInSvg } from \"lib/hooks/useChangeSchematicComponentLocationsInSvg\"\nimport { useChangeSchematicTracesForMovedComponents } from \"lib/hooks/useChangeSchematicTracesForMovedComponents\"\nimport { useSchematicGroupsOverlay } from \"lib/hooks/useSchematicGroupsOverlay\"\nimport { enableDebug } from \"lib/utils/debug\"\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport {\n fromString,\n identity,\n toString as transformToString,\n} from \"transformation-matrix\"\nimport { useMouseMatrixTransform } from \"use-mouse-matrix-transform\"\nimport { useResizeHandling } from \"../hooks/use-resize-handling\"\nimport { useComponentDragging } from \"../hooks/useComponentDragging\"\nimport type { ManualEditEvent } from \"../types/edit-events\"\nimport { EditIcon } from \"./EditIcon\"\nimport { GridIcon } from \"./GridIcon\"\nimport { ViewMenuIcon } from \"./ViewMenuIcon\"\nimport { ViewMenu } from \"./ViewMenu\"\nimport type { CircuitJson } from \"circuit-json\"\nimport { SpiceSimulationIcon } from \"./SpiceSimulationIcon\"\nimport { SpiceSimulationOverlay } from \"./SpiceSimulationOverlay\"\nimport { zIndexMap } from \"../utils/z-index-map\"\nimport { useSpiceSimulation } from \"../hooks/useSpiceSimulation\"\nimport { getSpiceFromCircuitJson } from \"../utils/spice-utils\"\nimport { getStoredBoolean, setStoredBoolean } from \"lib/hooks/useLocalStorage\"\nimport { MouseTracker } from \"./MouseTracker\"\nimport { SchematicComponentMouseTarget } from \"./SchematicComponentMouseTarget\"\n\ninterface Props {\n circuitJson: CircuitJson\n containerStyle?: React.CSSProperties\n editEvents?: ManualEditEvent[]\n onEditEvent?: (event: ManualEditEvent) => void\n defaultEditMode?: boolean\n debugGrid?: boolean\n editingEnabled?: boolean\n debug?: boolean\n clickToInteractEnabled?: boolean\n colorOverrides?: ColorOverrides\n spiceSimulationEnabled?: boolean\n disableGroups?: boolean\n onSchematicComponentClicked?: (options: {\n schematicComponentId: string\n event: MouseEvent\n }) => void\n}\n\nexport const SchematicViewer = ({\n circuitJson,\n containerStyle,\n editEvents: unappliedEditEvents = [],\n onEditEvent,\n defaultEditMode = false,\n debugGrid = false,\n editingEnabled = false,\n debug = false,\n clickToInteractEnabled = false,\n colorOverrides,\n spiceSimulationEnabled = false,\n disableGroups = false,\n onSchematicComponentClicked,\n}: Props) => {\n if (debug) {\n enableDebug()\n }\n const [showSpiceOverlay, setShowSpiceOverlay] = useState(false)\n const [spiceSimOptions, setSpiceSimOptions] = useState({\n showVoltage: true,\n showCurrent: false,\n startTime: 0, // in ms\n duration: 20, // in ms\n })\n\n const getCircuitHash = (circuitJson: CircuitJson) => {\n return `${circuitJson?.length || 0}_${(circuitJson as any)?.editCount || 0}`\n }\n\n const circuitJsonKey = useMemo(\n () => getCircuitHash(circuitJson),\n [circuitJson],\n )\n\n const spiceString = useMemo(() => {\n if (!spiceSimulationEnabled) return null\n try {\n return getSpiceFromCircuitJson(circuitJson, spiceSimOptions)\n } catch (e) {\n console.error(\"Failed to generate SPICE string\", e)\n return null\n }\n }, [\n circuitJsonKey,\n spiceSimulationEnabled,\n spiceSimOptions.startTime,\n spiceSimOptions.duration,\n ])\n\n const [hasSpiceSimRun, setHasSpiceSimRun] = useState(false)\n\n useEffect(() => {\n setHasSpiceSimRun(false)\n }, [circuitJsonKey])\n\n const {\n plotData,\n nodes,\n isLoading: isSpiceSimLoading,\n error: spiceSimError,\n } = useSpiceSimulation(hasSpiceSimRun ? spiceString : null)\n\n const [editModeEnabled, setEditModeEnabled] = useState(defaultEditMode)\n const [snapToGrid, setSnapToGrid] = useState(true)\n const [showGrid, setShowGrid] = useState(debugGrid)\n const [isInteractionEnabled, setIsInteractionEnabled] = useState<boolean>(\n !clickToInteractEnabled,\n )\n const [showViewMenu, setShowViewMenu] = useState(false)\n const [showSchematicGroups, setShowSchematicGroups] = useState(() => {\n if (disableGroups) return false\n return getStoredBoolean(\"schematic_viewer_show_groups\", false)\n })\n const [isHoveringClickableComponent, setIsHoveringClickableComponent] =\n useState(false)\n const hoveringComponentsRef = useRef<Set<string>>(new Set())\n\n const handleComponentHoverChange = useCallback(\n (componentId: string, isHovering: boolean) => {\n if (isHovering) {\n hoveringComponentsRef.current.add(componentId)\n } else {\n hoveringComponentsRef.current.delete(componentId)\n }\n setIsHoveringClickableComponent(hoveringComponentsRef.current.size > 0)\n },\n [],\n )\n const svgDivRef = useRef<HTMLDivElement>(null)\n const touchStartRef = useRef<{ x: number; y: number } | null>(null)\n\n const schematicComponentIds = useMemo(() => {\n try {\n return (\n su(circuitJson)\n .schematic_component?.list()\n ?.map((component) => component.schematic_component_id as string) ?? []\n )\n } catch (err) {\n console.error(\"Failed to derive schematic component ids\", err)\n return []\n }\n }, [circuitJsonKey, circuitJson])\n\n const handleTouchStart = (e: React.TouchEvent) => {\n const touch = e.touches[0]\n touchStartRef.current = {\n x: touch.clientX,\n y: touch.clientY,\n }\n }\n\n const handleTouchEnd = (e: React.TouchEvent) => {\n const touch = e.changedTouches[0]\n const start = touchStartRef.current\n if (!start) return\n\n const deltaX = Math.abs(touch.clientX - start.x)\n const deltaY = Math.abs(touch.clientY - start.y)\n\n if (deltaX < 10 && deltaY < 10) {\n e.preventDefault()\n setIsInteractionEnabled(true)\n }\n\n touchStartRef.current = null\n }\n\n const [internalEditEvents, setInternalEditEvents] = useState<\n ManualEditEvent[]\n >([])\n const circuitJsonRef = useRef<CircuitJson>(circuitJson)\n\n useEffect(() => {\n const circuitHash = getCircuitHash(circuitJson)\n const circuitHashRef = getCircuitHash(circuitJsonRef.current)\n\n if (circuitHash !== circuitHashRef) {\n setInternalEditEvents([])\n circuitJsonRef.current = circuitJson\n }\n }, [circuitJson])\n\n const {\n ref: containerRef,\n cancelDrag,\n transform: svgToScreenProjection,\n } = useMouseMatrixTransform({\n onSetTransform(transform) {\n if (!svgDivRef.current) return\n svgDivRef.current.style.transform = transformToString(transform)\n },\n // @ts-ignore disabled is a valid prop but not typed\n enabled: isInteractionEnabled && !showSpiceOverlay,\n })\n\n const { containerWidth, containerHeight } = useResizeHandling(containerRef)\n const svgString = useMemo(() => {\n if (!containerWidth || !containerHeight) return \"\"\n\n return convertCircuitJsonToSchematicSvg(circuitJson as any, {\n width: containerWidth,\n height: containerHeight || 720,\n grid: !showGrid\n ? undefined\n : {\n cellSize: 1,\n labelCells: true,\n },\n colorOverrides,\n })\n }, [circuitJsonKey, containerWidth, containerHeight, showGrid])\n\n const containerBackgroundColor = useMemo(() => {\n const match = svgString.match(\n /<svg[^>]*style=\"[^\"]*background-color:\\s*([^;\\\"]+)/i,\n )\n return match?.[1] ?? \"transparent\"\n }, [svgString])\n\n const realToSvgProjection = useMemo(() => {\n if (!svgString) return identity()\n const transformString = svgString.match(\n /data-real-to-screen-transform=\"([^\"]+)\"/,\n )?.[1]!\n\n try {\n return fromString(transformString)\n } catch (e) {\n console.error(e)\n return identity()\n }\n }, [svgString])\n\n const handleEditEvent = (event: ManualEditEvent) => {\n setInternalEditEvents((prev) => [...prev, event])\n if (onEditEvent) {\n onEditEvent(event)\n }\n }\n\n const editEventsWithUnappliedEditEvents = useMemo(() => {\n return [...unappliedEditEvents, ...internalEditEvents]\n }, [unappliedEditEvents, internalEditEvents])\n\n const {\n handleMouseDown,\n handleTouchStart: handleComponentTouchStart,\n isDragging,\n activeEditEvent,\n } = useComponentDragging({\n onEditEvent: handleEditEvent,\n cancelDrag,\n realToSvgProjection,\n svgToScreenProjection,\n circuitJson,\n editEvents: editEventsWithUnappliedEditEvents,\n enabled: editModeEnabled && isInteractionEnabled && !showSpiceOverlay,\n snapToGrid,\n })\n\n useChangeSchematicComponentLocationsInSvg({\n svgDivRef,\n editEvents: editEventsWithUnappliedEditEvents,\n realToSvgProjection,\n svgToScreenProjection,\n activeEditEvent,\n })\n\n useChangeSchematicTracesForMovedComponents({\n svgDivRef,\n circuitJson,\n activeEditEvent,\n editEvents: editEventsWithUnappliedEditEvents,\n })\n\n // Add group overlays when enabled\n useSchematicGroupsOverlay({\n svgDivRef,\n circuitJson,\n circuitJsonKey,\n showGroups: showSchematicGroups && !disableGroups,\n })\n\n // keep the latest touch handler without re-rendering the svg div\n const handleComponentTouchStartRef = useRef(handleComponentTouchStart)\n useEffect(() => {\n handleComponentTouchStartRef.current = handleComponentTouchStart\n }, [handleComponentTouchStart])\n\n const svgDiv = useMemo(\n () => (\n <div\n ref={svgDivRef}\n style={{\n pointerEvents: clickToInteractEnabled\n ? isInteractionEnabled\n ? \"auto\"\n : \"none\"\n : \"auto\",\n transformOrigin: \"0 0\",\n }}\n className={\n onSchematicComponentClicked\n ? \"schematic-component-clickable\"\n : undefined\n }\n onTouchStart={(e) => {\n if (editModeEnabled && isInteractionEnabled && !showSpiceOverlay) {\n handleComponentTouchStartRef.current(e)\n }\n }}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: <explanation>\n dangerouslySetInnerHTML={{ __html: svgString }}\n />\n ),\n [\n svgString,\n isInteractionEnabled,\n clickToInteractEnabled,\n editModeEnabled,\n showSpiceOverlay,\n ],\n )\n\n return (\n <MouseTracker>\n {onSchematicComponentClicked && (\n <style>\n {`.schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }`}\n </style>\n )}\n <div\n ref={containerRef}\n style={{\n position: \"relative\",\n backgroundColor: containerBackgroundColor,\n overflow: \"hidden\",\n cursor: showSpiceOverlay\n ? \"auto\"\n : isDragging\n ? \"grabbing\"\n : clickToInteractEnabled && !isInteractionEnabled\n ? \"pointer\"\n : isHoveringClickableComponent && onSchematicComponentClicked\n ? \"pointer\"\n : \"grab\",\n minHeight: \"300px\",\n ...containerStyle,\n }}\n onWheelCapture={(e) => {\n if (showSpiceOverlay) {\n e.stopPropagation()\n }\n }}\n onMouseDown={(e) => {\n if (clickToInteractEnabled && !isInteractionEnabled) {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n handleMouseDown(e)\n }}\n onMouseDownCapture={(e) => {\n if (clickToInteractEnabled && !isInteractionEnabled) {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n }}\n onTouchStart={(e) => {\n if (showSpiceOverlay) return\n handleTouchStart(e)\n }}\n onTouchEnd={(e) => {\n if (showSpiceOverlay) return\n handleTouchEnd(e)\n }}\n >\n {!isInteractionEnabled && clickToInteractEnabled && (\n <div\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n setIsInteractionEnabled(true)\n }}\n style={{\n position: \"absolute\",\n inset: 0,\n cursor: \"pointer\",\n zIndex: zIndexMap.clickToInteractOverlay,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"all\",\n touchAction: \"pan-x pan-y pinch-zoom\",\n }}\n >\n <div\n style={{\n backgroundColor: \"rgba(0, 0, 0, 0.8)\",\n color: \"white\",\n padding: \"12px 24px\",\n borderRadius: \"8px\",\n fontSize: \"16px\",\n fontFamily: \"sans-serif\",\n pointerEvents: \"none\",\n }}\n >\n {typeof window !== \"undefined\" &&\n (\"ontouchstart\" in window || navigator.maxTouchPoints > 0)\n ? \"Touch to Interact\"\n : \"Click to Interact\"}\n </div>\n </div>\n )}\n <ViewMenuIcon\n active={showViewMenu}\n onClick={() => setShowViewMenu(!showViewMenu)}\n />\n {editingEnabled && (\n <EditIcon\n active={editModeEnabled}\n onClick={() => setEditModeEnabled(!editModeEnabled)}\n />\n )}\n {editingEnabled && editModeEnabled && (\n <GridIcon\n active={snapToGrid}\n onClick={() => setSnapToGrid(!snapToGrid)}\n />\n )}\n <ViewMenu\n circuitJson={circuitJson}\n circuitJsonKey={circuitJsonKey}\n isVisible={showViewMenu}\n onClose={() => setShowViewMenu(false)}\n showGroups={showSchematicGroups}\n onToggleGroups={(value) => {\n if (!disableGroups) {\n setShowSchematicGroups(value)\n setStoredBoolean(\"schematic_viewer_show_groups\", value)\n }\n }}\n showGrid={showGrid}\n onToggleGrid={setShowGrid}\n />\n {spiceSimulationEnabled && (\n <SpiceSimulationIcon onClick={() => setShowSpiceOverlay(true)} />\n )}\n {showSpiceOverlay && (\n <SpiceSimulationOverlay\n spiceString={spiceString}\n onClose={() => setShowSpiceOverlay(false)}\n plotData={plotData}\n nodes={nodes}\n isLoading={isSpiceSimLoading}\n error={spiceSimError}\n simOptions={spiceSimOptions}\n onSimOptionsChange={(options) => {\n setHasSpiceSimRun(true)\n setSpiceSimOptions(options)\n }}\n hasRun={hasSpiceSimRun}\n />\n )}\n {onSchematicComponentClicked &&\n schematicComponentIds.map((componentId) => (\n <SchematicComponentMouseTarget\n key={componentId}\n componentId={componentId}\n svgDivRef={svgDivRef}\n containerRef={containerRef}\n showOutline={true}\n circuitJsonKey={circuitJsonKey}\n onHoverChange={handleComponentHoverChange}\n onComponentClick={(id, event) => {\n onSchematicComponentClicked?.({\n schematicComponentId: id,\n event,\n })\n }}\n />\n ))}\n {svgDiv}\n </div>\n </MouseTracker>\n )\n}\n","import { su } from \"@tscircuit/soup-util\"\nimport type {\n ManualEditEvent,\n EditSchematicComponentLocationEventWithElement,\n} from \"lib/types/edit-events\"\nimport { type Matrix, compose, applyToPoint } from \"transformation-matrix\"\nimport { useEffect, useRef } from \"react\"\nimport { getComponentOffsetDueToEvents } from \"lib/utils/get-component-offset-due-to-events\"\nimport type { CircuitJson } from \"circuit-json\"\n\n/**\n * This hook automatically applies the edit events to the schematic components\n * inside the svg div.\n *\n * Schematic components are \"<g>\" elements with a \"data-circuit-json-type\"\n * attribute equal to \"schematic_component\", these elements also have a\n * data-schematic-component-id attribute equal to the schematic_component_id\n */\nexport const useChangeSchematicComponentLocationsInSvg = ({\n svgDivRef,\n realToSvgProjection,\n svgToScreenProjection,\n activeEditEvent,\n editEvents,\n}: {\n svgDivRef: React.RefObject<HTMLDivElement | null>\n realToSvgProjection: Matrix\n svgToScreenProjection: Matrix\n activeEditEvent: EditSchematicComponentLocationEventWithElement | null\n editEvents: ManualEditEvent[]\n}) => {\n // Keep track of the last known SVG content\n const lastSvgContentRef = useRef<string | null>(null)\n\n useEffect(() => {\n const svg = svgDivRef.current\n if (!svg) return\n\n // Create a MutationObserver to watch for changes in the div's content\n const observer = new MutationObserver((mutations) => {\n // Check if the SVG content has changed\n const currentSvgContent = svg.innerHTML\n if (currentSvgContent !== lastSvgContentRef.current) {\n lastSvgContentRef.current = currentSvgContent\n\n // Apply the transforms\n applyTransforms()\n }\n })\n\n // Function to apply transforms to components\n const applyTransforms = () => {\n const componentsThatHaveBeenMoved = new Set<string>()\n for (const event of editEvents) {\n if (\n \"edit_event_type\" in event &&\n event.edit_event_type === \"edit_schematic_component_location\"\n ) {\n componentsThatHaveBeenMoved.add(event.schematic_component_id)\n }\n }\n if (activeEditEvent) {\n componentsThatHaveBeenMoved.add(activeEditEvent.schematic_component_id)\n }\n\n // Reset all transforms\n const allComponents = svg.querySelectorAll(\n '[data-circuit-json-type=\"schematic_component\"]',\n )\n\n for (const component of Array.from(allComponents)) {\n const schematic_component_id = component.getAttribute(\n \"data-schematic-component-id\",\n )!\n\n const offsetMm = getComponentOffsetDueToEvents({\n editEvents: [\n ...editEvents,\n ...(activeEditEvent ? [activeEditEvent] : []),\n ],\n schematic_component_id,\n })\n\n const offsetPx = {\n x: offsetMm.x * realToSvgProjection.a,\n y: offsetMm.y * realToSvgProjection.d,\n }\n\n const style: any = (component as any).style\n style.transform = `translate(${offsetPx.x}px, ${offsetPx.y}px)`\n if (\n activeEditEvent?.schematic_component_id === schematic_component_id\n ) {\n style.outline = \"solid 2px rgba(255,0,0,0.5)\"\n style.outlineOffset = \"5px\"\n } else if (style.outline) {\n style.outline = \"\"\n }\n }\n }\n\n // Start observing the div for changes\n observer.observe(svg, {\n childList: true, // Watch for changes to the child elements\n subtree: false, // Watch for changes in the entire subtree\n characterData: false, // Watch for changes to text content\n })\n\n // Apply transforms immediately on mount or when editEvents change\n applyTransforms()\n\n // Cleanup function\n return () => {\n observer.disconnect()\n }\n }, [svgDivRef, editEvents, activeEditEvent]) // Dependencies remain the same\n}\n","import type {\n EditSchematicComponentLocationEvent,\n EditSchematicComponentLocationEventWithElement,\n ManualEditEvent,\n} from \"lib/types/edit-events\"\n\n/**\n * Returns the total offset of a component due to a set of edit events in\n * mm\n */\nexport const getComponentOffsetDueToEvents = ({\n editEvents,\n schematic_component_id,\n}: {\n editEvents: ManualEditEvent[]\n schematic_component_id: string\n}) => {\n const editEventsForComponent: EditSchematicComponentLocationEvent[] =\n editEvents\n .filter(\n (event) =>\n \"schematic_component_id\" in event &&\n event.schematic_component_id === schematic_component_id,\n )\n .filter(\n (event) =>\n \"edit_event_type\" in event &&\n event.edit_event_type === \"edit_schematic_component_location\",\n )\n\n const totalOffsetX = editEventsForComponent.reduce((acc, event) => {\n return acc + event.new_center.x - event.original_center.x\n }, 0)\n\n const totalOffsetY = editEventsForComponent.reduce((acc, event) => {\n return acc + event.new_center.y - event.original_center.y\n }, 0)\n\n return {\n x: totalOffsetX,\n y: totalOffsetY,\n }\n}\n","import { useEffect, useRef } from \"react\"\nimport { su } from \"@tscircuit/soup-util\"\nimport type { ManualEditEvent } from \"../types/edit-events\"\nimport type { CircuitJson } from \"circuit-json\"\n\n/**\n * This hook makes traces dashed when their connected components are being moved\n */\nexport const useChangeSchematicTracesForMovedComponents = ({\n svgDivRef,\n circuitJson,\n activeEditEvent,\n editEvents,\n}: {\n svgDivRef: React.RefObject<HTMLDivElement | null>\n circuitJson: CircuitJson\n activeEditEvent: ManualEditEvent | null\n editEvents: ManualEditEvent[]\n}) => {\n // Keep track of the last known SVG content\n const lastSvgContentRef = useRef<string | null>(null)\n\n useEffect(() => {\n const svg = svgDivRef.current\n if (!svg) return\n\n const updateTraceStyles = () => {\n // Reset all traces to solid\n const allTraces = svg.querySelectorAll(\n '[data-circuit-json-type=\"schematic_trace\"] path',\n )\n\n // Reset all traces to solid\n for (const trace of Array.from(allTraces)) {\n trace.setAttribute(\"stroke-dasharray\", \"0\")\n ;(trace as any).style.animation = \"\"\n }\n\n // If there's an active edit event, make connected traces dashed\n for (const editEvent of [\n ...editEvents,\n ...(activeEditEvent ? [activeEditEvent] : []),\n ]) {\n if (\n \"schematic_component_id\" in editEvent &&\n editEvent.edit_event_type === \"edit_schematic_component_location\"\n ) {\n const sch_component = su(circuitJson).schematic_component.get(\n editEvent.schematic_component_id,\n )\n if (!sch_component) return\n\n const src_ports = su(circuitJson).source_port.list({\n source_component_id: sch_component.source_component_id,\n })\n const src_port_ids = new Set(src_ports.map((sp) => sp.source_port_id))\n const src_traces = su(circuitJson)\n .source_trace.list()\n .filter((st) =>\n st.connected_source_port_ids?.some((spi: string) =>\n src_port_ids.has(spi),\n ),\n )\n const src_trace_ids = new Set(\n src_traces.map((st) => st.source_trace_id),\n )\n const schematic_traces = su(circuitJson)\n .schematic_trace.list()\n .filter((st) => src_trace_ids.has(st.source_trace_id!))\n\n // Make the connected traces dashed\n schematic_traces.forEach((trace) => {\n const traceElements = svg.querySelectorAll(\n `[data-schematic-trace-id=\"${trace.schematic_trace_id}\"] path`,\n )\n for (const traceElement of Array.from(traceElements)) {\n if (traceElement.getAttribute(\"class\")?.includes(\"invisible\"))\n continue\n traceElement.setAttribute(\"stroke-dasharray\", \"20,20\")\n ;(traceElement as any).style.animation =\n \"dash-animation 350ms linear infinite, pulse-animation 900ms linear infinite\"\n\n if (!svg.querySelector(\"style#dash-animation\")) {\n const style = document.createElement(\"style\")\n style.id = \"dash-animation\"\n style.textContent = `\n @keyframes dash-animation {\n to {\n stroke-dashoffset: -40;\n }\n }\n @keyframes pulse-animation {\n 0% { opacity: 0.6; }\n 50% { opacity: 0.2; }\n 100% { opacity: 0.6; }\n }\n `\n svg.appendChild(style)\n }\n }\n })\n }\n }\n }\n\n // Apply styles immediately\n updateTraceStyles()\n\n // Cleanup function\n const observer = new MutationObserver(updateTraceStyles)\n observer.observe(svg, {\n childList: true, // Watch for changes to the child elements\n subtree: false, // Watch for changes in the entire subtree\n characterData: false, // Watch for changes to text content\n })\n\n return () => {\n observer.disconnect()\n }\n }, [svgDivRef, activeEditEvent, circuitJson, editEvents])\n}\n","import { useEffect } from \"react\"\nimport { su } from \"@tscircuit/soup-util\"\nimport type { CircuitJson } from \"circuit-json\"\n\ninterface UseSchematicGroupsOverlayOptions {\n svgDivRef: React.RefObject<HTMLDivElement | null>\n circuitJson: CircuitJson\n circuitJsonKey: string\n showGroups: boolean\n}\n\nconst GROUP_COLORS = [\n \"#8B0000\", // Dark Red\n \"#2F4F4F\", // Dark Slate Gray\n \"#191970\", // Midnight Blue\n \"#006400\", // Dark Green\n \"#FF4500\", // Dark Orange\n \"#800080\", // Purple\n \"#2E8B57\", // Sea Green\n \"#B8860B\", // Dark Goldenrod\n \"#C71585\", // Medium Violet Red\n \"#008B8B\", // Dark Cyan\n]\n\nexport const useSchematicGroupsOverlay = (\n options: UseSchematicGroupsOverlayOptions,\n) => {\n const { svgDivRef, circuitJson, circuitJsonKey, showGroups } = options\n\n useEffect(() => {\n // Always clean up existing overlays first\n if (svgDivRef.current) {\n const existingOverlays = svgDivRef.current.querySelectorAll(\n \".schematic-group-overlay\",\n )\n existingOverlays.forEach((overlay) => overlay.remove())\n }\n\n if (\n !svgDivRef.current ||\n !showGroups ||\n !circuitJson ||\n circuitJson.length === 0\n ) {\n return\n }\n\n // Small delay to ensure SVG is rendered when groups are enabled from localStorage\n const timeoutId = setTimeout(() => {\n if (!svgDivRef.current) return\n\n const svg = svgDivRef.current.querySelector(\"svg\")\n if (!svg) {\n return\n }\n\n const existingOverlays = svg.querySelectorAll(\".schematic-group-overlay\")\n existingOverlays.forEach((overlay) => overlay.remove())\n\n try {\n const sourceGroups =\n su(circuitJson)\n .source_group?.list()\n .filter((x) => !!!x.is_subcircuit) || []\n const schematicComponents =\n su(circuitJson).schematic_component?.list() || []\n\n const sourceGroupHierarchy = new Map<string, string[]>()\n sourceGroups.forEach((group) => {\n const groupWithParent = group as any\n if (groupWithParent.parent_source_group_id) {\n const children =\n sourceGroupHierarchy.get(\n groupWithParent.parent_source_group_id,\n ) || []\n children.push(group.source_group_id)\n sourceGroupHierarchy.set(\n groupWithParent.parent_source_group_id,\n children,\n )\n }\n })\n\n const getAllDescendantSourceGroups = (\n sourceGroupId: string,\n ): string[] => {\n const descendants: string[] = []\n const children = sourceGroupHierarchy.get(sourceGroupId) || []\n for (const child of children) {\n descendants.push(child)\n descendants.push(...getAllDescendantSourceGroups(child))\n }\n return descendants\n }\n\n const getGroupDepthLevel = (sourceGroupId: string): number => {\n const groupWithParent = sourceGroups.find(\n (g) => g.source_group_id === sourceGroupId,\n ) as any\n if (!groupWithParent?.parent_source_group_id) {\n return 0\n }\n return 1 + getGroupDepthLevel(groupWithParent.parent_source_group_id)\n }\n\n const hasMeaningfulGroups =\n sourceGroups.length > 0 &&\n sourceGroups.some((group) => group.name && group.name.trim() !== \"\")\n\n let groupsToRender: Array<{\n id: string\n name: string\n components: any[]\n color: string\n depthLevel: number\n hasChildren: boolean\n sourceGroupId?: string\n }> = []\n\n if (hasMeaningfulGroups) {\n const groupMap = new Map<string, any[]>()\n\n for (const comp of schematicComponents) {\n const sourceComp = su(circuitJson).source_component.get(\n comp.source_component_id!,\n )\n if (sourceComp?.source_group_id) {\n if (!groupMap.has(sourceComp.source_group_id)) {\n groupMap.set(sourceComp.source_group_id, [])\n }\n groupMap.get(sourceComp.source_group_id)!.push(comp)\n }\n }\n\n sourceGroups.forEach((group, index) => {\n let groupComponents = groupMap.get(group.source_group_id) || []\n\n const descendantGroups = getAllDescendantSourceGroups(\n group.source_group_id,\n )\n for (const descendantGroupId of descendantGroups) {\n const descendantComponents = groupMap.get(descendantGroupId) || []\n groupComponents = [...groupComponents, ...descendantComponents]\n }\n\n if (groupComponents.length > 0) {\n const depthLevel = getGroupDepthLevel(group.source_group_id)\n const hasChildren =\n getAllDescendantSourceGroups(group.source_group_id).length > 0\n\n if (group.name?.startsWith(\"unnamed_board\")) return\n groupsToRender.push({\n id: group.source_group_id,\n name: group.name || `Group ${index + 1}`,\n components: groupComponents,\n color: GROUP_COLORS[index % GROUP_COLORS.length],\n depthLevel,\n hasChildren,\n sourceGroupId: group.source_group_id,\n })\n }\n })\n }\n // else {\n // const componentTypeGroups = new Map<string, any[]>()\n\n // for (const comp of schematicComponents) {\n // const sourceComp = su(circuitJson).source_component.get(comp.source_component_id)\n // if (sourceComp) {\n // const componentType = sourceComp.ftype || \"other\"\n // if (!componentTypeGroups.has(componentType)) {\n // componentTypeGroups.set(componentType, [])\n // }\n // componentTypeGroups.get(componentType)!.push(comp)\n // }\n // }\n // // groupsToRender = Array.from(componentTypeGroups.entries()).map(\n // // ([type, components], index) => ({\n // // id: `type_${type}`,\n // // name: `${type.charAt(0).toUpperCase() + type.slice(1)}s`,\n // // components,\n // // color: GROUP_COLORS[index % GROUP_COLORS.length],\n // // depthLevel: 0,\n // // hasChildren: false,\n // // }),\n // // )\n // }\n\n const viewBox = svg.viewBox.baseVal\n const svgRect = svg.getBoundingClientRect()\n const scale =\n Math.min(\n svgRect.width / viewBox.width,\n svgRect.height / viewBox.height,\n ) || 1\n\n groupsToRender.sort((a, b) => a.depthLevel - b.depthLevel)\n\n groupsToRender.forEach((group) => {\n if (group.components.length === 0) return\n\n const groupBounds = calculateGroupBounds(group.components, svg)\n if (!groupBounds) return\n\n const basePadding = Math.max(\n 8,\n Math.min(25, 15 / Math.max(scale, 0.3)),\n )\n const hierarchyPadding = group.hasChildren ? basePadding * 0.6 : 0\n const totalPadding = basePadding + hierarchyPadding\n\n const baseStrokeWidth = Math.max(1, 2 / Math.max(scale, 0.5))\n const strokeWidth =\n group.depthLevel === 0 ? baseStrokeWidth : baseStrokeWidth * 0.7\n\n const baseDashSize = Math.max(4, 8 / Math.max(scale, 0.5))\n const dashMultiplier = group.hasChildren ? 1.3 : 1\n const dashSize = baseDashSize * dashMultiplier\n const gapSize = dashSize * 0.5\n\n const groupOverlay = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"rect\",\n )\n groupOverlay.setAttribute(\"class\", \"schematic-group-overlay\")\n groupOverlay.setAttribute(\n \"x\",\n (groupBounds.minX - totalPadding).toString(),\n )\n groupOverlay.setAttribute(\n \"y\",\n (groupBounds.minY - totalPadding).toString(),\n )\n groupOverlay.setAttribute(\n \"width\",\n (groupBounds.maxX - groupBounds.minX + totalPadding * 2).toString(),\n )\n groupOverlay.setAttribute(\n \"height\",\n (groupBounds.maxY - groupBounds.minY + totalPadding * 2).toString(),\n )\n groupOverlay.setAttribute(\"fill\", \"none\")\n groupOverlay.setAttribute(\"stroke\", group.color)\n groupOverlay.setAttribute(\"stroke-width\", strokeWidth.toString())\n groupOverlay.setAttribute(\n \"stroke-dasharray\",\n `${dashSize},${gapSize}`,\n )\n groupOverlay.setAttribute(\"opacity\", \"0.8\")\n groupOverlay.setAttribute(\"rx\", \"0\")\n groupOverlay.setAttribute(\"ry\", \"0\")\n\n const baseFontSize = Math.max(\n 6,\n Math.min(20, 14 / Math.max(scale, 0.2)),\n )\n const fontSizeReduction =\n group.depthLevel === 0 || group.depthLevel === 1\n ? 0\n : group.depthLevel * 0.2\n const fontSize = baseFontSize * (1 - fontSizeReduction)\n\n const labelPadding = Math.max(1, fontSize * 0.2)\n const labelText = group.name\n\n const tempText = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"text\",\n )\n tempText.setAttribute(\"font-size\", fontSize.toString())\n tempText.setAttribute(\"font-family\", \"Arial, sans-serif\")\n tempText.textContent = labelText\n svg.appendChild(tempText)\n const textBBox = tempText.getBBox()\n svg.removeChild(tempText)\n\n const labelWidth = textBBox.width + labelPadding * 2\n const labelHeight = fontSize + labelPadding * 2\n const labelX = groupBounds.minX - totalPadding\n const labelY = groupBounds.minY - totalPadding - labelHeight\n\n const labelBg = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"rect\",\n )\n labelBg.setAttribute(\"class\", \"schematic-group-overlay\")\n labelBg.setAttribute(\"x\", labelX.toString())\n labelBg.setAttribute(\"y\", (labelY - labelHeight).toString())\n labelBg.setAttribute(\"width\", labelWidth.toString())\n labelBg.setAttribute(\"height\", labelHeight.toString())\n labelBg.setAttribute(\"fill\", \"transparent\")\n labelBg.setAttribute(\"rx\", \"0\")\n labelBg.setAttribute(\"ry\", \"0\")\n\n const groupLabel = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"text\",\n )\n groupLabel.setAttribute(\"class\", \"schematic-group-overlay\")\n groupLabel.setAttribute(\"x\", (labelX + labelPadding).toString())\n groupLabel.setAttribute(\n \"y\",\n (labelY + labelHeight - labelPadding).toString(),\n )\n groupLabel.setAttribute(\"fill\", group.color)\n groupLabel.setAttribute(\"font-size\", fontSize.toString())\n groupLabel.setAttribute(\"font-family\", \"Arial, sans-serif\")\n groupLabel.setAttribute(\n \"font-weight\",\n group.depthLevel === 0 ? \"600\" : \"500\",\n )\n groupLabel.setAttribute(\"stroke\", group.color)\n groupLabel.setAttribute(\n \"stroke-width\",\n Math.max(0.2, fontSize * 0.02).toString(),\n )\n groupLabel.textContent = labelText\n\n svg.appendChild(groupOverlay)\n svg.appendChild(labelBg)\n svg.appendChild(groupLabel)\n })\n } catch (error) {\n console.error(\"Error creating group overlays:\", error)\n }\n }, 10) // Small delay to ensure SVG is ready\n\n return () => clearTimeout(timeoutId)\n }, [svgDivRef, circuitJsonKey, showGroups])\n}\n\nfunction calculateGroupBounds(components: any[], svg: SVGElement) {\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity\n\n for (const component of components) {\n let componentElement = svg.querySelector(\n `g[data-schematic-component-id=\"${component.schematic_component_id}\"]`,\n )\n\n if (!componentElement) {\n componentElement = svg.querySelector(\n `[data-schematic-component-id=\"${component.schematic_component_id}\"]`,\n )\n }\n\n if (componentElement) {\n const bbox = (componentElement as SVGGraphicsElement).getBBox()\n minX = Math.min(minX, bbox.x)\n minY = Math.min(minY, bbox.y)\n maxX = Math.max(maxX, bbox.x + bbox.width)\n maxY = Math.max(maxY, bbox.y + bbox.height)\n }\n }\n\n if (minX === Infinity) {\n return null\n }\n\n const bounds = { minX, minY, maxX, maxY }\n return bounds\n}\n","import Debug from \"debug\"\n\nexport const debug = Debug(\"schematic-viewer\")\n\nexport const enableDebug = () => {\n Debug.enable(\"schematic-viewer*\")\n}\n\nexport default debug\n","import { useEffect, useState } from \"react\"\n\nexport const useResizeHandling = (\n containerRef: React.RefObject<HTMLElement>,\n) => {\n const [containerWidth, setContainerWidth] = useState(0)\n const [containerHeight, setContainerHeight] = useState(0)\n\n useEffect(() => {\n if (!containerRef.current) return\n\n const updateDimensions = () => {\n const rect = containerRef.current?.getBoundingClientRect()\n setContainerWidth(rect?.width || 0)\n setContainerHeight(rect?.height || 0)\n }\n\n // Set initial dimensions\n updateDimensions()\n\n // Add resize listener\n const resizeObserver = new ResizeObserver(updateDimensions)\n resizeObserver.observe(containerRef.current)\n\n // Fallback to window resize\n window.addEventListener(\"resize\", updateDimensions)\n\n return () => {\n resizeObserver.disconnect()\n window.removeEventListener(\"resize\", updateDimensions)\n }\n }, [])\n\n return { containerWidth, containerHeight }\n}\n","import { su } from \"@tscircuit/soup-util\"\nimport Debug from \"lib/utils/debug\"\nimport { getComponentOffsetDueToEvents } from \"lib/utils/get-component-offset-due-to-events\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\nimport { type Matrix, compose } from \"transformation-matrix\"\nimport type {\n EditSchematicComponentLocationEventWithElement,\n ManualEditEvent,\n} from \"../types/edit-events\"\n\nconst debug = Debug.extend(\"useComponentDragging\")\n\nexport const useComponentDragging = ({\n onEditEvent,\n editEvents = [],\n circuitJson,\n cancelDrag,\n svgToScreenProjection,\n realToSvgProjection,\n enabled = false,\n snapToGrid = false,\n}: {\n circuitJson: any[]\n editEvents: ManualEditEvent[]\n /** The projection returned from use-mouse-matrix-transform, indicating zoom on svg */\n svgToScreenProjection: Matrix\n /** The projection returned from circuit-to-svg, mm to svg */\n realToSvgProjection: Matrix\n onEditEvent?: (event: ManualEditEvent) => void\n cancelDrag?: () => void\n enabled?: boolean\n snapToGrid?: boolean\n}): {\n handleMouseDown: (e: React.MouseEvent) => void\n handleTouchStart: (e: React.TouchEvent) => void\n isDragging: boolean\n activeEditEvent: EditSchematicComponentLocationEventWithElement | null\n} => {\n const [activeEditEvent, setActiveEditEvent] =\n useState<EditSchematicComponentLocationEventWithElement | null>(null)\n const realToScreenProjection = compose(\n realToSvgProjection,\n svgToScreenProjection,\n )\n\n /**\n * Drag start position in screen space\n */\n const dragStartPosRef = useRef<{\n x: number\n y: number\n } | null>(null)\n\n const activeEditEventRef =\n useRef<EditSchematicComponentLocationEventWithElement | null>(null)\n\n // Store the latest positions of components being tracked\n const componentPositionsRef = useRef<Map<string, { x: number; y: number }>>(\n new Map(),\n )\n\n // Update position map with the latest positions from edit events\n useEffect(() => {\n // Process completed edit events to track latest positions\n editEvents.forEach((event) => {\n if (\n \"edit_event_type\" in event &&\n event.edit_event_type === \"edit_schematic_component_location\" &&\n !event.in_progress\n ) {\n componentPositionsRef.current.set(event.schematic_component_id, {\n ...event.new_center,\n })\n }\n })\n }, [editEvents])\n\n const startDrag = useCallback(\n (clientX: number, clientY: number, target: Element) => {\n if (!enabled) return false\n\n const componentGroup = target.closest(\n '[data-circuit-json-type=\"schematic_component\"]',\n )\n if (!componentGroup) return false\n\n const schematic_component_id = componentGroup.getAttribute(\n \"data-schematic-component-id\",\n )\n if (!schematic_component_id) return false\n\n if (cancelDrag) cancelDrag()\n\n const schematic_component = su(circuitJson).schematic_component.get(\n schematic_component_id,\n )\n if (!schematic_component) return false\n\n dragStartPosRef.current = { x: clientX, y: clientY }\n\n let current_position: { x: number; y: number }\n const trackedPosition = componentPositionsRef.current.get(\n schematic_component_id,\n )\n\n if (trackedPosition) {\n current_position = { ...trackedPosition }\n } else {\n const editEventOffset = getComponentOffsetDueToEvents({\n editEvents,\n schematic_component_id: schematic_component_id,\n })\n\n current_position = {\n x: schematic_component.center.x + editEventOffset.x,\n y: schematic_component.center.y + editEventOffset.y,\n }\n\n componentPositionsRef.current.set(schematic_component_id, {\n ...current_position,\n })\n }\n\n const newEditEvent: EditSchematicComponentLocationEventWithElement = {\n edit_event_id: Math.random().toString(36).substr(2, 9),\n edit_event_type: \"edit_schematic_component_location\",\n schematic_component_id: schematic_component_id,\n original_center: current_position,\n new_center: { ...current_position },\n in_progress: true,\n created_at: Date.now(),\n _element: componentGroup as any,\n }\n\n activeEditEventRef.current = newEditEvent\n setActiveEditEvent(newEditEvent)\n return true\n },\n [cancelDrag, enabled, circuitJson, editEvents],\n )\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n startDrag(e.clientX, e.clientY, e.target as Element)\n },\n [startDrag],\n )\n\n const handleTouchStart = useCallback(\n (e: React.TouchEvent) => {\n if (e.touches.length !== 1) return\n const touch = e.touches[0]\n if (startDrag(touch.clientX, touch.clientY, e.target as Element)) {\n e.preventDefault()\n }\n },\n [startDrag],\n )\n\n const updateDragPosition = useCallback(\n (clientX: number, clientY: number) => {\n if (!activeEditEventRef.current || !dragStartPosRef.current) return\n\n const screenDelta = {\n x: clientX - dragStartPosRef.current.x,\n y: clientY - dragStartPosRef.current.y,\n }\n\n const mmDelta = {\n x: screenDelta.x / realToScreenProjection.a,\n y: screenDelta.y / realToScreenProjection.d,\n }\n\n let newCenter = {\n x: activeEditEventRef.current.original_center.x + mmDelta.x,\n y: activeEditEventRef.current.original_center.y + mmDelta.y,\n }\n if (snapToGrid) {\n const snap = (v: number) => Math.round(v * 10) / 10\n newCenter = { x: snap(newCenter.x), y: snap(newCenter.y) }\n }\n\n const newEditEvent = {\n ...activeEditEventRef.current,\n new_center: newCenter,\n }\n\n activeEditEventRef.current = newEditEvent\n setActiveEditEvent(newEditEvent)\n },\n [realToScreenProjection, snapToGrid],\n )\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => updateDragPosition(e.clientX, e.clientY),\n [updateDragPosition],\n )\n\n const handleTouchMove = useCallback(\n (e: TouchEvent) => {\n if (e.touches.length !== 1 || !activeEditEventRef.current) return\n e.preventDefault()\n const touch = e.touches[0]\n updateDragPosition(touch.clientX, touch.clientY)\n },\n [updateDragPosition],\n )\n\n const endDrag = useCallback(() => {\n if (!activeEditEventRef.current) return\n const finalEvent = {\n ...activeEditEventRef.current,\n in_progress: false,\n }\n\n componentPositionsRef.current.set(finalEvent.schematic_component_id, {\n ...finalEvent.new_center,\n })\n\n debug(\"endDrag calling onEditEvent with new edit event\", {\n newEditEvent: finalEvent,\n })\n if (onEditEvent) onEditEvent(finalEvent)\n activeEditEventRef.current = null\n dragStartPosRef.current = null\n setActiveEditEvent(null)\n }, [onEditEvent])\n\n const handleMouseUp = useCallback(() => endDrag(), [endDrag])\n const handleTouchEnd = useCallback(() => endDrag(), [endDrag])\n\n useEffect(() => {\n window.addEventListener(\"mousemove\", handleMouseMove)\n window.addEventListener(\"mouseup\", handleMouseUp)\n window.addEventListener(\"touchmove\", handleTouchMove, { passive: false })\n window.addEventListener(\"touchend\", handleTouchEnd)\n return () => {\n window.removeEventListener(\"mousemove\", handleMouseMove)\n window.removeEventListener(\"mouseup\", handleMouseUp)\n window.removeEventListener(\"touchmove\", handleTouchMove)\n window.removeEventListener(\"touchend\", handleTouchEnd)\n }\n }, [handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd])\n\n return {\n handleMouseDown,\n handleTouchStart,\n isDragging: !!activeEditEventRef.current,\n activeEditEvent: activeEditEvent,\n }\n}\n","export const zIndexMap = {\n schematicEditIcon: 50,\n schematicGridIcon: 49,\n spiceSimulationIcon: 50,\n viewMenuIcon: 48,\n viewMenu: 55,\n viewMenuBackdrop: 54,\n clickToInteractOverlay: 100,\n schematicComponentHoverOutline: 47,\n}\n","import { zIndexMap } from \"../utils/z-index-map\"\n\nexport const EditIcon = ({\n onClick,\n active,\n}: { onClick: () => void; active: boolean }) => {\n const handleInteraction = (e: React.MouseEvent | React.TouchEvent) => {\n e.preventDefault()\n onClick()\n }\n\n return (\n <div\n onClick={handleInteraction}\n onTouchEnd={handleInteraction}\n title={active ? \"Disable edit mode\" : \"Enable edit mode\"}\n style={{\n position: \"absolute\",\n top: \"16px\",\n right: \"64px\",\n backgroundColor: active ? \"#4CAF50\" : \"#fff\",\n color: active ? \"#fff\" : \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.schematicEditIcon,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\" />\n <path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\" />\n </svg>\n </div>\n )\n}\n","import { zIndexMap } from \"../utils/z-index-map\"\n\nexport const GridIcon = ({\n onClick,\n active,\n}: { onClick: () => void; active: boolean }) => {\n const handleInteraction = (e: React.MouseEvent | React.TouchEvent) => {\n e.preventDefault()\n onClick()\n }\n\n return (\n <div\n onClick={handleInteraction}\n onTouchEnd={handleInteraction}\n title={active ? \"Hide grid\" : \"Show grid\"}\n style={{\n position: \"absolute\",\n top: \"56px\",\n right: \"64px\",\n backgroundColor: active ? \"#4CAF50\" : \"#fff\",\n color: active ? \"#fff\" : \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.schematicGridIcon,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM14 14h7v7h-7z\" />\n </svg>\n </div>\n )\n}\n","import { zIndexMap } from \"../utils/z-index-map\"\n\nexport const ViewMenuIcon = ({\n onClick,\n active,\n}: { onClick: () => void; active: boolean }) => {\n const handleInteraction = (e: React.MouseEvent | React.TouchEvent) => {\n e.preventDefault()\n onClick()\n }\n\n return (\n <div\n onClick={handleInteraction}\n onTouchEnd={handleInteraction}\n title={active ? \"Hide view menu\" : \"Show view menu\"}\n style={{\n position: \"absolute\",\n top: \"16px\",\n right: \"16px\",\n backgroundColor: active ? \"#4CAF50\" : \"#fff\",\n color: active ? \"#fff\" : \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.viewMenuIcon,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\n </svg>\n </div>\n )\n}\n","import { useMemo } from \"react\"\nimport { su } from \"@tscircuit/soup-util\"\nimport type { CircuitJson } from \"circuit-json\"\nimport { zIndexMap } from \"../utils/z-index-map\"\nimport packageJson from \"../../package.json\"\n\ninterface ViewMenuProps {\n circuitJson: CircuitJson\n circuitJsonKey: string\n isVisible: boolean\n onClose: () => void\n showGroups: boolean\n onToggleGroups: (show: boolean) => void\n showGrid: boolean\n onToggleGrid: (show: boolean) => void\n}\n\nexport const ViewMenu = ({\n circuitJson,\n circuitJsonKey,\n isVisible,\n onClose,\n showGroups,\n onToggleGroups,\n showGrid,\n onToggleGrid,\n}: ViewMenuProps) => {\n const hasGroups = useMemo(() => {\n if (!circuitJson || circuitJson.length === 0) return false\n\n try {\n // Check if there are explicit groups\n const sourceGroups = su(circuitJson).source_group?.list() || []\n if (sourceGroups.length > 0) return true\n\n // Check if we can create virtual groups by component type\n const schematicComponents =\n su(circuitJson).schematic_component?.list() || []\n if (schematicComponents.length > 1) {\n const componentTypes = new Set()\n for (const comp of schematicComponents) {\n const sourceComp = su(circuitJson).source_component.get(\n comp.source_component_id!,\n )\n if (sourceComp?.ftype) {\n componentTypes.add(sourceComp.ftype)\n }\n }\n return componentTypes.size > 1 // Only show if there are multiple types\n }\n\n return false\n } catch (error) {\n console.error(\"Error checking for groups:\", error)\n return false\n }\n }, [circuitJsonKey])\n\n if (!isVisible) return null\n\n return (\n <>\n {/* Backdrop */}\n <div\n onClick={onClose}\n onTouchEnd={(e) => {\n e.preventDefault()\n onClose()\n }}\n style={{\n position: \"absolute\",\n inset: 0,\n backgroundColor: \"transparent\",\n zIndex: zIndexMap.viewMenuBackdrop,\n }}\n />\n\n {/* Menu */}\n <div\n style={{\n position: \"absolute\",\n top: \"56px\",\n right: \"16px\",\n backgroundColor: \"#ffffff\",\n color: \"#000000\",\n border: \"1px solid #ccc\",\n borderRadius: \"4px\",\n boxShadow: \"0 4px 12px rgba(0,0,0,0.1)\",\n minWidth: \"200px\",\n zIndex: zIndexMap.viewMenu,\n }}\n >\n {/* Groups Toggle Option */}\n <div\n onClick={() => {\n if (hasGroups) {\n onToggleGroups(!showGroups)\n }\n }}\n onTouchEnd={(e) => {\n e.preventDefault()\n if (hasGroups) {\n onToggleGroups(!showGroups)\n }\n }}\n style={{\n padding: \"8px 12px\",\n cursor: hasGroups ? \"pointer\" : \"not-allowed\",\n opacity: hasGroups ? 1 : 0.5,\n fontSize: \"13px\",\n color: \"#000000\",\n fontFamily: \"sans-serif\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n }}\n onMouseEnter={(e) => {\n if (hasGroups) {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\"\n }\n }}\n onMouseLeave={(e) => {\n if (hasGroups) {\n e.currentTarget.style.backgroundColor = \"transparent\"\n }\n }}\n >\n <div\n style={{\n width: \"16px\",\n height: \"16px\",\n border: \"2px solid #000\",\n borderRadius: \"2px\",\n backgroundColor: \"transparent\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"10px\",\n fontWeight: \"bold\",\n }}\n >\n {showGroups && \"✓\"}\n </div>\n View Schematic Groups\n </div>\n\n {!hasGroups && (\n <div\n style={{\n padding: \"8px 12px\",\n fontSize: \"11px\",\n color: \"#666\",\n fontStyle: \"italic\",\n }}\n >\n No groups found in this schematic\n </div>\n )}\n\n {/* Grid Toggle Option */}\n <div\n onClick={() => onToggleGrid(!showGrid)}\n onTouchEnd={(e) => {\n e.preventDefault()\n onToggleGrid(!showGrid)\n }}\n style={{\n padding: \"8px 12px\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n color: \"#000000\",\n fontFamily: \"sans-serif\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\"\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\"\n }}\n >\n <div\n style={{\n width: \"16px\",\n height: \"16px\",\n border: \"2px solid #000\",\n borderRadius: \"2px\",\n backgroundColor: \"transparent\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"10px\",\n fontWeight: \"bold\",\n }}\n >\n {showGrid && \"✓\"}\n </div>\n Show Grid\n </div>\n\n {/* Version Info */}\n <div\n style={{\n padding: \"4px 8px\",\n fontSize: \"12px\",\n color: \"#999\",\n borderTop: \"1px solid #eee\",\n textAlign: \"center\",\n }}\n >\n v{String(packageJson?.version)}\n </div>\n </div>\n </>\n )\n}\n","{\n \"name\": \"@tscircuit/schematic-viewer\",\n \"version\": \"2.0.53\",\n \"main\": \"dist/index.js\",\n \"type\": \"module\",\n \"scripts\": {\n \"start\": \"cosmos\",\n \"build:webworker\": \"tsup --config tsup-webworker.config.ts\",\n \"build:blob-url\": \"bun scripts/build-worker-blob-url.ts\",\n \"build\": \"bun run build:webworker && bun run build:blob-url && tsup-node ./lib/index.ts --dts --format esm --sourcemap\",\n \"build:site\": \"cosmos-export\",\n \"vercel-build\": \"bun run build:webworker && bun run build:blob-url && bun run build:site\",\n \"format\": \"biome format --write .\",\n \"format:check\": \"biome format .\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^1.9.4\",\n \"@types/bun\": \"latest\",\n \"@types/debug\": \"^4.1.12\",\n \"@types/react\": \"^19.0.1\",\n \"@types/react-dom\": \"^19.0.2\",\n \"@types/recharts\": \"^2.0.1\",\n \"@vitejs/plugin-react\": \"^4.3.4\",\n \"react\": \"^19.1.0\",\n \"react-cosmos\": \"^6.2.1\",\n \"react-cosmos-plugin-vite\": \"^6.2.0\",\n \"react-dom\": \"^19.1.0\",\n \"react-reconciler\": \"^0.31.0\",\n \"semver\": \"^7.7.2\",\n \"tscircuit\": \"^0.0.1194\",\n \"tsup\": \"^8.3.5\",\n \"vite\": \"^6.0.3\"\n },\n \"peerDependencies\": {\n \"typescript\": \"^5.0.0\",\n \"tscircuit\": \"*\"\n },\n \"dependencies\": {\n \"chart.js\": \"^4.5.0\",\n \"circuit-json-to-spice\": \"^0.0.30\",\n \"debug\": \"^4.4.0\",\n \"performance-now\": \"^2.1.0\",\n \"react-chartjs-2\": \"^5.3.0\",\n \"use-mouse-matrix-transform\": \"^1.2.2\"\n }\n}\n","export const SpiceIcon = () => (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M3 12h2.5l2.5-9 4 18 4-9h5.5\" />\n </svg>\n)\n","import { SpiceIcon } from \"./SpiceIcon\"\nimport { zIndexMap } from \"../utils/z-index-map\"\n\nexport const SpiceSimulationIcon = ({\n onClick,\n}: {\n onClick: () => void\n}) => {\n return (\n <div\n onClick={onClick}\n title=\"Run SPICE simulation\"\n style={{\n position: \"absolute\",\n top: \"16px\",\n right: \"112px\",\n backgroundColor: \"#fff\",\n color: \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.spiceSimulationIcon,\n }}\n >\n <SpiceIcon />\n </div>\n )\n}\n","import { useMemo } from \"react\"\nimport {\n Chart as ChartJS,\n type ChartOptions,\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n Title,\n Tooltip,\n Legend,\n} from \"chart.js\"\nimport { Line } from \"react-chartjs-2\"\nimport type { PlotPoint } from \"../hooks/useSpiceSimulation\"\n\nChartJS.register(\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n Title,\n Tooltip,\n Legend,\n)\n\nconst colors = [\"#8884d8\", \"#82ca9d\", \"#ffc658\", \"#ff7300\", \"#387908\"]\n\nconst formatTimeWithUnits = (seconds: number) => {\n if (seconds === 0) return \"0s\"\n const absSeconds = Math.abs(seconds)\n\n let unit = \"s\"\n let scale = 1\n if (absSeconds < 1e-12) {\n unit = \"fs\"\n scale = 1e15\n } else if (absSeconds < 1e-9) {\n unit = \"ps\"\n scale = 1e12\n } else if (absSeconds < 1e-6) {\n unit = \"ns\"\n scale = 1e9\n } else if (absSeconds < 1e-3) {\n unit = \"us\"\n scale = 1e6\n } else if (absSeconds < 1) {\n unit = \"ms\"\n scale = 1e3\n }\n\n return `${parseFloat((seconds * scale).toPrecision(3))}${unit}`\n}\n\nexport const SpicePlot = ({\n plotData,\n nodes,\n isLoading,\n error,\n hasRun,\n}: {\n plotData: PlotPoint[]\n nodes: string[]\n isLoading: boolean\n error: string | null\n hasRun: boolean\n}) => {\n const yAxisLabel = useMemo(() => {\n const hasVoltage = nodes.some((n) => n.toLowerCase().startsWith(\"v(\"))\n const hasCurrent = nodes.some((n) => n.toLowerCase().startsWith(\"i(\"))\n if (hasVoltage && hasCurrent) return \"Value\"\n if (hasVoltage) return \"Voltage (V)\"\n if (hasCurrent) return \"Current (A)\"\n return \"Value\"\n }, [nodes])\n\n if (isLoading) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n Running simulation...\n </div>\n )\n }\n\n if (!hasRun) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n Click \"Run\" to start the simulation.\n </div>\n )\n }\n\n if (error) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"red\",\n }}\n >\n Error: {error}\n </div>\n )\n }\n\n if (plotData.length === 0) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n No data to plot. Check simulation output or SPICE netlist.\n </div>\n )\n }\n\n const chartData = {\n datasets: nodes.map((node, i) => ({\n label: node,\n data: plotData.map((p) => ({\n x: Number(p.name),\n y: p[node] as number,\n })),\n borderColor: colors[i % colors.length],\n backgroundColor: colors[i % colors.length],\n fill: false,\n tension: 0.1,\n })),\n }\n\n const options: ChartOptions<\"line\"> = {\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n position: \"top\" as const,\n labels: {\n font: {\n family: \"sans-serif\",\n },\n },\n },\n title: {\n display: false,\n },\n tooltip: {\n callbacks: {\n title: (tooltipItems) => {\n if (tooltipItems.length > 0) {\n const item = tooltipItems[0]\n return formatTimeWithUnits(item.parsed.x as number)\n }\n return \"\"\n },\n },\n },\n },\n scales: {\n x: {\n type: \"linear\",\n title: {\n display: true,\n text: \"Time\",\n font: {\n family: \"sans-serif\",\n },\n },\n ticks: {\n callback: (value) => formatTimeWithUnits(value as number),\n font: {\n family: \"sans-serif\",\n },\n },\n },\n y: {\n title: {\n display: true,\n text: yAxisLabel,\n font: {\n family: \"sans-serif\",\n },\n },\n ticks: {\n font: {\n family: \"sans-serif\",\n },\n },\n },\n },\n }\n\n return (\n <div style={{ position: \"relative\", height: \"300px\", width: \"100%\" }}>\n <Line options={options} data={chartData} />\n </div>\n )\n}\n","import { SpicePlot } from \"./SpicePlot\"\nimport type { PlotPoint } from \"../hooks/useSpiceSimulation\"\nimport { useEffect, useState } from \"react\"\n\ninterface SpiceSimulationOverlayProps {\n spiceString: string | null\n onClose: () => void\n plotData: PlotPoint[]\n nodes: string[]\n isLoading: boolean\n error: string | null\n simOptions: {\n showVoltage: boolean\n showCurrent: boolean\n startTime: number\n duration: number\n }\n onSimOptionsChange: (\n options: SpiceSimulationOverlayProps[\"simOptions\"],\n ) => void\n hasRun: boolean\n}\n\nexport const SpiceSimulationOverlay = ({\n spiceString,\n onClose,\n plotData,\n nodes,\n isLoading,\n error,\n simOptions,\n onSimOptionsChange,\n hasRun,\n}: SpiceSimulationOverlayProps) => {\n const [startTimeDraft, setStartTimeDraft] = useState(\n String(simOptions.startTime),\n )\n const [durationDraft, setDurationDraft] = useState(\n String(simOptions.duration),\n )\n\n useEffect(() => {\n setStartTimeDraft(String(simOptions.startTime))\n setDurationDraft(String(simOptions.duration))\n }, [simOptions.startTime, simOptions.duration])\n\n const handleRerun = () => {\n onSimOptionsChange({\n ...simOptions,\n startTime: Number(startTimeDraft),\n duration: Number(durationDraft),\n })\n }\n\n const filteredNodes = nodes.filter((node) => {\n const isVoltage = node.toLowerCase().startsWith(\"v(\")\n const isCurrent = node.toLowerCase().startsWith(\"i(\")\n if (simOptions.showVoltage && isVoltage) return true\n if (simOptions.showCurrent && isCurrent) return true\n return false\n })\n\n return (\n <div\n style={{\n position: \"fixed\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: \"rgba(0, 0, 0, 0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex: 1002,\n fontFamily: \"sans-serif\",\n }}\n >\n <div\n style={{\n backgroundColor: \"white\",\n padding: \"24px\",\n borderRadius: \"12px\",\n width: \"90%\",\n maxWidth: \"900px\",\n boxShadow: \"0 4px 20px rgba(0, 0, 0, 0.15)\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: \"24px\",\n borderBottom: \"1px solid #eee\",\n paddingBottom: \"16px\",\n }}\n >\n <h2\n style={{\n margin: 0,\n fontSize: \"22px\",\n fontWeight: 600,\n color: \"#333\",\n }}\n >\n SPICE Simulation\n </h2>\n <button\n onClick={onClose}\n style={{\n background: \"none\",\n border: \"none\",\n fontSize: \"28px\",\n cursor: \"pointer\",\n color: \"#888\",\n padding: 0,\n lineHeight: 1,\n }}\n >\n &times;\n </button>\n </div>\n <div>\n <SpicePlot\n plotData={plotData}\n nodes={filteredNodes}\n isLoading={isLoading}\n error={error}\n hasRun={hasRun}\n />\n </div>\n <div\n style={{\n marginTop: \"16px\",\n padding: \"12px\",\n backgroundColor: \"#f7f7f7\",\n borderRadius: \"6px\",\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"24px\",\n alignItems: \"center\",\n fontSize: \"14px\",\n }}\n >\n <div style={{ display: \"flex\", gap: \"16px\" }}>\n <label\n style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}\n >\n <input\n type=\"checkbox\"\n checked={simOptions.showVoltage}\n onChange={(e) =>\n onSimOptionsChange({\n ...simOptions,\n showVoltage: e.target.checked,\n })\n }\n />\n Voltage\n </label>\n <label\n style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}\n >\n <input\n type=\"checkbox\"\n checked={simOptions.showCurrent}\n onChange={(e) =>\n onSimOptionsChange({\n ...simOptions,\n showCurrent: e.target.checked,\n })\n }\n />\n Current\n </label>\n </div>\n <div style={{ display: \"flex\", gap: \"16px\", alignItems: \"center\" }}>\n <label htmlFor=\"startTime\">Start Time (ms):</label>\n <input\n id=\"startTime\"\n type=\"number\"\n value={startTimeDraft}\n onChange={(e) => setStartTimeDraft(e.target.value)}\n style={{\n width: \"80px\",\n padding: \"4px 8px\",\n borderRadius: \"4px\",\n border: \"1px solid #ccc\",\n }}\n />\n <label htmlFor=\"duration\">Duration (ms):</label>\n <input\n id=\"duration\"\n type=\"number\"\n value={durationDraft}\n onChange={(e) => setDurationDraft(e.target.value)}\n style={{\n width: \"80px\",\n padding: \"4px 8px\",\n borderRadius: \"4px\",\n border: \"1px solid #ccc\",\n }}\n />\n <button\n onClick={handleRerun}\n style={{\n padding: \"4px 12px\",\n borderRadius: \"4px\",\n border: \"1px solid #ccc\",\n backgroundColor: \"#f0f0f0\",\n cursor: \"pointer\",\n }}\n >\n {hasRun ? \"Rerun\" : \"Run\"}\n </button>\n </div>\n </div>\n <div style={{ marginTop: \"24px\" }}>\n <h3\n style={{\n marginTop: 0,\n marginBottom: \"12px\",\n fontSize: \"18px\",\n fontWeight: 600,\n color: \"#333\",\n }}\n >\n SPICE Netlist\n </h3>\n <pre\n style={{\n backgroundColor: \"#fafafa\",\n padding: \"16px\",\n borderRadius: \"6px\",\n maxHeight: \"150px\",\n overflowY: \"auto\",\n border: \"1px solid #eee\",\n color: \"#333\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n }}\n >\n {spiceString}\n </pre>\n </div>\n </div>\n </div>\n )\n}\n","import { useState, useEffect } from \"react\"\nimport type * as EecircuitEngine from \"../types/eecircuit-engine\"\n// @ts-ignore\nimport { getSpiceSimulationWorkerBlobUrl } from \"../workers/spice-simulation.worker.blob.js\"\n\n// Types from eecircuit-engine interface\ntype RealDataType = {\n name: string\n type: string\n values: number[]\n}\ntype ComplexNumber = {\n real: number\n img: number\n}\ntype ComplexDataType = {\n name: string\n type: string\n values: ComplexNumber[]\n}\ntype EecEngineResult =\n | {\n header: string\n numVariables: number\n variableNames: string[]\n numPoints: number\n dataType: \"real\"\n data: RealDataType[]\n }\n | {\n header: string\n numVariables: number\n variableNames: string[]\n numPoints: number\n dataType: \"complex\"\n data: ComplexDataType[]\n }\n\nexport interface PlotPoint {\n name: string // time or sweep variable\n [key: string]: number | string\n}\n\nconst parseEecEngineOutput = (\n result: EecEngineResult,\n): { plotData: PlotPoint[]; nodes: string[] } => {\n const columnData: Record<string, number[]> = {}\n\n if (result.dataType === \"real\") {\n result.data.forEach((col) => {\n columnData[col.name] = col.values\n })\n } else if (result.dataType === \"complex\") {\n result.data.forEach((col) => {\n // For now, plot the real part of complex numbers\n columnData[col.name] = col.values.map((v) => v.real)\n })\n } else {\n throw new Error(\"Unsupported data type in simulation result\")\n }\n\n const timeKey = Object.keys(columnData).find(\n (k) => k.toLowerCase() === \"time\" || k.toLowerCase() === \"frequency\",\n )\n if (!timeKey) {\n throw new Error(\"No time or frequency data in simulation result\")\n }\n const timeValues = columnData[timeKey]\n const probedVariables = Object.keys(columnData).filter((k) => k !== timeKey)\n const plotableNodes = probedVariables\n\n const plotData: PlotPoint[] = timeValues.map((t: number, i: number) => {\n const point: PlotPoint = { name: t.toExponential(2) }\n probedVariables.forEach((variable) => {\n point[variable] = columnData[variable][i]\n })\n return point\n })\n\n return { plotData, nodes: plotableNodes }\n}\n\ntype WorkerMessage =\n | {\n type: \"result\"\n result: EecEngineResult\n }\n | { type: \"error\"; error: string }\n\nexport const useSpiceSimulation = (spiceString: string | null) => {\n const [plotData, setPlotData] = useState<PlotPoint[]>([])\n const [nodes, setNodes] = useState<string[]>([])\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n if (!spiceString) {\n setIsLoading(false)\n setPlotData([])\n setNodes([])\n setError(null)\n return\n }\n setIsLoading(true)\n setError(null)\n setPlotData([])\n setNodes([])\n\n const workerUrl = getSpiceSimulationWorkerBlobUrl()\n\n if (!workerUrl) {\n setError(\"Could not create SPICE simulation worker.\")\n setIsLoading(false)\n return\n }\n\n const worker = new Worker(workerUrl, { type: \"module\" })\n\n worker.onmessage = (event: MessageEvent<WorkerMessage>) => {\n if (event.data.type === \"result\") {\n try {\n const { plotData: parsedData, nodes: parsedNodes } =\n parseEecEngineOutput(event.data.result)\n setPlotData(parsedData)\n setNodes(parsedNodes)\n } catch (e: any) {\n setError(e.message || \"Failed to parse simulation result\")\n console.error(e)\n }\n } else if (event.data.type === \"error\") {\n setError(event.data.error)\n }\n setIsLoading(false)\n }\n\n worker.onerror = (err) => {\n setError(err.message)\n setIsLoading(false)\n }\n\n worker.postMessage({ spiceString })\n\n return () => {\n worker.terminate()\n }\n }, [spiceString])\n\n return { plotData, nodes, isLoading, error }\n}\n","// This file is generated by scripts/build-worker-blob-url.ts\n// Do not edit this file directly.\n\nconst b64 = \"dmFyIGU9bnVsbCxzPWFzeW5jKCk9Pihhd2FpdCBpbXBvcnQoImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vZWVjaXJjdWl0LWVuZ2luZUAxLjUuMi8rZXNtIikpLlNpbXVsYXRpb24sYz1hc3luYygpPT57aWYoZSYmZS5pc0luaXRpYWxpemVkKCkpcmV0dXJuO2xldCBpPWF3YWl0IHMoKTtlPW5ldyBpLGF3YWl0IGUuc3RhcnQoKX07c2VsZi5vbm1lc3NhZ2U9YXN5bmMgaT0+e3RyeXtpZihhd2FpdCBjKCksIWUpdGhyb3cgbmV3IEVycm9yKCJTaW11bGF0aW9uIG5vdCBpbml0aWFsaXplZCIpO2xldCB0PWkuZGF0YS5zcGljZVN0cmluZyxhPXQubWF0Y2goL3dyZGF0YVxzKyhcUyspXHMrKC4qKS9pKTtpZihhKXtsZXQgbz1gLnByb2JlICR7YVsyXS50cmltKCkuc3BsaXQoL1xzKy8pLmpvaW4oIiAiKX1gO3Q9dC5yZXBsYWNlKC93cmRhdGEuKi9pLG8pfWVsc2UgaWYoIXQubWF0Y2goL1wucHJvYmUvaSkpdGhyb3cgdC5tYXRjaCgvcGxvdFxzKyguKikvaSk/bmV3IEVycm9yKCJUaGUgJ3Bsb3QnIGNvbW1hbmQgaXMgbm90IHN1cHBvcnRlZCBmb3IgZGF0YSBleHRyYWN0aW9uLiBQbGVhc2UgdXNlICd3cmRhdGEgPGZpbGVuYW1lPiA8dmFyMT4gLi4uJyBvciAnLnByb2JlIDx2YXIxPiAuLi4nIGluc3RlYWQuIik6bmV3IEVycm9yKCJObyAnLnByb2JlJyBvciAnd3JkYXRhJyBjb21tYW5kIGZvdW5kIGluIFNQSUNFIGZpbGUuIFVzZSAnd3JkYXRhIDxmaWxlbmFtZT4gPHZhcjE+IC4uLicgdG8gc3BlY2lmeSBvdXRwdXQuIik7ZS5zZXROZXRMaXN0KHQpO2xldCBuPWF3YWl0IGUucnVuU2ltKCk7c2VsZi5wb3N0TWVzc2FnZSh7dHlwZToicmVzdWx0IixyZXN1bHQ6bn0pfWNhdGNoKHQpe3NlbGYucG9zdE1lc3NhZ2Uoe3R5cGU6ImVycm9yIixlcnJvcjp0Lm1lc3NhZ2V9KX19Owo=\";\n\nlet blobUrl = null;\n\nexport const getSpiceSimulationWorkerBlobUrl = () => {\n if (typeof window === \"undefined\") return null;\n if (blobUrl) return blobUrl;\n\n try {\n const blob = new Blob([atob(b64)], { type: \"application/javascript\" });\n blobUrl = URL.createObjectURL(blob);\n return blobUrl;\n } catch (e) {\n console.error(\"Failed to create blob URL for worker\", e);\n return null;\n }\n};\n","import { circuitJsonToSpice } from \"circuit-json-to-spice\"\nimport type { CircuitJson } from \"circuit-json\"\n\nexport interface SpiceSimOptions {\n showVoltage: boolean\n showCurrent: boolean\n startTime: number // in ms\n duration: number // in ms\n}\n\nconst formatSimTime = (seconds: number): string => {\n if (seconds === 0) return \"0\"\n const absSeconds = Math.abs(seconds)\n\n const precision = (v: number) => v.toPrecision(4)\n\n if (absSeconds >= 1) return precision(seconds)\n if (absSeconds >= 1e-3) return `${precision(seconds * 1e3)}m`\n if (absSeconds >= 1e-6) return `${precision(seconds * 1e6)}u`\n if (absSeconds >= 1e-9) return `${precision(seconds * 1e9)}n`\n if (absSeconds >= 1e-12) return `${precision(seconds * 1e12)}p`\n if (absSeconds >= 1e-15) return `${precision(seconds * 1e15)}f`\n\n return seconds.toExponential(3)\n}\n\nexport const getSpiceFromCircuitJson = (\n circuitJson: CircuitJson,\n options?: Partial<SpiceSimOptions>,\n): string => {\n const spiceNetlist = circuitJsonToSpice(circuitJson as any)\n const baseSpiceString = spiceNetlist.toSpiceString()\n\n const lines = baseSpiceString.split(\"\\n\").filter((l) => l.trim() !== \"\")\n const componentLines = lines.filter(\n (l) => !l.startsWith(\"*\") && !l.startsWith(\".\") && l.trim() !== \"\",\n )\n\n const allNodes = new Set<string>()\n const capacitorNodes = new Set<string>()\n const componentNamesToProbeCurrent = new Set<string>()\n\n for (const line of componentLines) {\n const parts = line.trim().split(/\\s+/)\n if (parts.length < 3) continue\n\n const componentName = parts[0]\n const componentType = componentName[0].toUpperCase()\n let nodesOnLine: string[] = []\n\n if ([\"R\", \"C\", \"L\", \"V\", \"I\", \"D\"].includes(componentType)) {\n nodesOnLine = parts.slice(1, 3)\n // Only probe current on voltage sources\n if (componentType === \"V\") {\n componentNamesToProbeCurrent.add(componentName)\n }\n } else if (componentType === \"Q\" && parts.length >= 4) {\n // BJT\n nodesOnLine = parts.slice(1, 4)\n } else if (componentType === \"M\" && parts.length >= 5) {\n // MOSFET\n nodesOnLine = parts.slice(1, 5)\n } else if (componentType === \"X\") {\n // Subcircuit\n // Assume last part is model name, everything in between is a node\n nodesOnLine = parts.slice(1, -1)\n } else {\n continue\n }\n\n nodesOnLine.forEach((node) => allNodes.add(node))\n\n if (componentType === \"C\") {\n nodesOnLine.forEach((node) => capacitorNodes.add(node))\n }\n }\n\n // Do not probe/set IC for ground\n allNodes.delete(\"0\")\n capacitorNodes.delete(\"0\")\n\n const icLines = Array.from(capacitorNodes).map((node) => `.ic V(${node})=0`)\n\n const probes: string[] = []\n const probeVoltages = Array.from(allNodes).map((node) => `V(${node})`)\n probes.push(...probeVoltages)\n const probeCurrents = Array.from(componentNamesToProbeCurrent).map(\n (name) => `I(${name})`,\n )\n probes.push(...probeCurrents)\n\n const probeLine = probes.length > 0 ? `.probe ${probes.join(\" \")}` : \"\"\n\n const tstart_ms = options?.startTime ?? 0\n const duration_ms = options?.duration ?? 20\n const tstart = tstart_ms * 1e-3 // s\n const duration = duration_ms * 1e-3 // s\n\n const tstop = tstart + duration\n const tstep = duration / 50\n const tranLine = `.tran ${formatSimTime(tstep)} ${formatSimTime(\n tstop,\n )} ${formatSimTime(tstart)} UIC`\n\n const endStatement = \".end\"\n const originalLines = baseSpiceString.split(\"\\n\")\n let endIndex = -1\n for (let i = originalLines.length - 1; i >= 0; i--) {\n if (originalLines[i].trim().toLowerCase().startsWith(endStatement)) {\n endIndex = i\n break\n }\n }\n\n const injectionLines = [...icLines, probeLine, tranLine].filter(Boolean)\n\n let finalLines: string[]\n\n if (endIndex !== -1) {\n const beforeEnd = originalLines.slice(0, endIndex)\n const endLineAndAfter = originalLines.slice(endIndex)\n finalLines = [...beforeEnd, ...injectionLines, ...endLineAndAfter]\n } else {\n finalLines = [...originalLines, ...injectionLines, endStatement]\n }\n\n return finalLines.join(\"\\n\")\n}\n","import { useCallback } from \"react\"\n\nexport const STORAGE_KEYS = {\n IS_SHOWING_SCHEMATIC_GROUPS: \"schematic_viewer_show_groups\",\n} as const\n\nexport const getStoredBoolean = (\n key: string,\n defaultValue: boolean,\n): boolean => {\n if (typeof window === \"undefined\") return defaultValue\n try {\n const stored = localStorage.getItem(key)\n return stored !== null ? JSON.parse(stored) : defaultValue\n } catch {\n return defaultValue\n }\n}\n\nexport const setStoredBoolean = (key: string, value: boolean): void => {\n if (typeof window === \"undefined\") return\n try {\n localStorage.setItem(key, JSON.stringify(value))\n } catch {}\n}\n\nexport const useLocalStorage = () => {\n const getBoolean = useCallback(\n (key: string, defaultValue: boolean): boolean => {\n return getStoredBoolean(key, defaultValue)\n },\n [],\n )\n\n const setBoolean = useCallback((key: string, value: boolean): void => {\n setStoredBoolean(key, value)\n }, [])\n\n return {\n getBoolean,\n setBoolean,\n }\n}\n\nexport const useLocalStorageValue = (key: string, defaultValue: boolean) => {\n const { getBoolean, setBoolean } = useLocalStorage()\n\n const getValue = useCallback(() => {\n return getBoolean(key, defaultValue)\n }, [getBoolean, key, defaultValue])\n\n const setValue = useCallback(\n (value: boolean) => {\n setBoolean(key, value)\n },\n [setBoolean, key],\n )\n\n return {\n getValue,\n setValue,\n }\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n type ReactNode,\n} from \"react\"\n\nexport interface BoundingBoxBounds {\n minX: number\n maxX: number\n minY: number\n maxY: number\n}\n\ninterface BoundingBoxRegistration {\n bounds: BoundingBoxBounds | null\n onClick?: ((event: MouseEvent) => void) | undefined\n}\n\nexport interface MouseTrackerContextValue {\n registerBoundingBox: (\n id: string,\n registration: BoundingBoxRegistration,\n ) => void\n updateBoundingBox: (id: string, registration: BoundingBoxRegistration) => void\n unregisterBoundingBox: (id: string) => void\n subscribe: (listener: () => void) => () => void\n isHovering: (id: string) => boolean\n}\n\nexport const MouseTrackerContext =\n createContext<MouseTrackerContextValue | null>(null)\n\nconst DRAG_THRESHOLD_PX = 5\n\nconst boundsAreEqual = (\n a: BoundingBoxBounds | null | undefined,\n b: BoundingBoxBounds | null | undefined,\n) => {\n if (!a && !b) return true\n if (!a || !b) return false\n return (\n a.minX === b.minX &&\n a.maxX === b.maxX &&\n a.minY === b.minY &&\n a.maxY === b.maxY\n )\n}\n\nexport const MouseTracker = ({ children }: { children: ReactNode }) => {\n const existingContext = useContext(MouseTrackerContext)\n\n if (existingContext) {\n return <>{children}</>\n }\n\n const storeRef = useRef({\n pointer: null as { x: number; y: number } | null,\n boundingBoxes: new Map<string, BoundingBoxRegistration>(),\n hoveringIds: new Set<string>(),\n subscribers: new Set<() => void>(),\n mouseDownPosition: null as { x: number; y: number } | null,\n })\n\n const notifySubscribers = useCallback(() => {\n for (const callback of storeRef.current.subscribers) {\n callback()\n }\n }, [])\n\n const updateHovering = useCallback(() => {\n const pointer = storeRef.current.pointer\n const newHovering = new Set<string>()\n\n if (pointer) {\n for (const [id, registration] of storeRef.current.boundingBoxes) {\n const bounds = registration.bounds\n if (!bounds) continue\n if (\n pointer.x >= bounds.minX &&\n pointer.x <= bounds.maxX &&\n pointer.y >= bounds.minY &&\n pointer.y <= bounds.maxY\n ) {\n newHovering.add(id)\n }\n }\n }\n\n const prevHovering = storeRef.current.hoveringIds\n if (\n newHovering.size === prevHovering.size &&\n [...newHovering].every((id) => prevHovering.has(id))\n ) {\n return\n }\n\n storeRef.current.hoveringIds = newHovering\n notifySubscribers()\n }, [notifySubscribers])\n\n const registerBoundingBox = useCallback(\n (id: string, registration: BoundingBoxRegistration) => {\n storeRef.current.boundingBoxes.set(id, registration)\n updateHovering()\n },\n [updateHovering],\n )\n\n const updateBoundingBox = useCallback(\n (id: string, registration: BoundingBoxRegistration) => {\n const existing = storeRef.current.boundingBoxes.get(id)\n if (\n existing &&\n boundsAreEqual(existing.bounds, registration.bounds) &&\n existing.onClick === registration.onClick\n ) {\n return\n }\n storeRef.current.boundingBoxes.set(id, registration)\n updateHovering()\n },\n [updateHovering],\n )\n\n const unregisterBoundingBox = useCallback(\n (id: string) => {\n const removed = storeRef.current.boundingBoxes.delete(id)\n if (removed) {\n updateHovering()\n }\n },\n [updateHovering],\n )\n\n const subscribe = useCallback((listener: () => void) => {\n storeRef.current.subscribers.add(listener)\n return () => {\n storeRef.current.subscribers.delete(listener)\n }\n }, [])\n\n const isHovering = useCallback((id: string) => {\n return storeRef.current.hoveringIds.has(id)\n }, [])\n\n useEffect(() => {\n const handlePointerPosition = (event: PointerEvent | MouseEvent) => {\n const { clientX, clientY } = event\n const pointer = storeRef.current.pointer\n if (pointer && pointer.x === clientX && pointer.y === clientY) {\n return\n }\n storeRef.current.pointer = { x: clientX, y: clientY }\n updateHovering()\n }\n\n const handlePointerLeave = () => {\n if (storeRef.current.pointer === null) return\n storeRef.current.pointer = null\n storeRef.current.mouseDownPosition = null\n updateHovering()\n }\n\n const handleMouseDown = (event: MouseEvent) => {\n storeRef.current.mouseDownPosition = {\n x: event.clientX,\n y: event.clientY,\n }\n }\n\n const handleClick = (event: MouseEvent) => {\n const { clientX, clientY } = event\n const mouseDownPos = storeRef.current.mouseDownPosition\n\n // Check if this was a drag (movement > threshold)\n if (mouseDownPos) {\n const distance = Math.sqrt(\n Math.pow(clientX - mouseDownPos.x, 2) +\n Math.pow(clientY - mouseDownPos.y, 2),\n )\n if (distance > DRAG_THRESHOLD_PX) {\n // This was a drag, not a click - don't trigger onClick\n storeRef.current.mouseDownPosition = null\n return\n }\n }\n\n storeRef.current.mouseDownPosition = null\n\n for (const registration of storeRef.current.boundingBoxes.values()) {\n const bounds = registration.bounds\n if (!bounds) continue\n if (\n clientX >= bounds.minX &&\n clientX <= bounds.maxX &&\n clientY >= bounds.minY &&\n clientY <= bounds.maxY\n ) {\n registration.onClick?.(event)\n }\n }\n }\n\n window.addEventListener(\"pointermove\", handlePointerPosition, {\n passive: true,\n })\n window.addEventListener(\"pointerdown\", handlePointerPosition, {\n passive: true,\n })\n window.addEventListener(\"pointerup\", handlePointerPosition, {\n passive: true,\n })\n window.addEventListener(\"pointerleave\", handlePointerLeave)\n window.addEventListener(\"pointercancel\", handlePointerLeave)\n window.addEventListener(\"blur\", handlePointerLeave)\n window.addEventListener(\"mousedown\", handleMouseDown, { passive: true })\n window.addEventListener(\"click\", handleClick, { passive: true })\n\n return () => {\n window.removeEventListener(\"pointermove\", handlePointerPosition)\n window.removeEventListener(\"pointerdown\", handlePointerPosition)\n window.removeEventListener(\"pointerup\", handlePointerPosition)\n window.removeEventListener(\"pointerleave\", handlePointerLeave)\n window.removeEventListener(\"pointercancel\", handlePointerLeave)\n window.removeEventListener(\"blur\", handlePointerLeave)\n window.removeEventListener(\"mousedown\", handleMouseDown)\n window.removeEventListener(\"click\", handleClick)\n }\n }, [updateHovering])\n\n const value = useMemo<MouseTrackerContextValue>(\n () => ({\n registerBoundingBox,\n updateBoundingBox,\n unregisterBoundingBox,\n subscribe,\n isHovering,\n }),\n [\n registerBoundingBox,\n updateBoundingBox,\n unregisterBoundingBox,\n subscribe,\n isHovering,\n ],\n )\n\n return (\n <MouseTrackerContext.Provider value={value}>\n {children}\n </MouseTrackerContext.Provider>\n )\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\nimport { useMouseEventsOverBoundingBox } from \"../hooks/useMouseEventsOverBoundingBox\"\nimport type { BoundingBoxBounds } from \"./MouseTracker\"\nimport { zIndexMap } from \"../utils/z-index-map\"\n\ninterface RelativeRect {\n left: number\n top: number\n width: number\n height: number\n}\n\ninterface Measurement {\n bounds: BoundingBoxBounds\n rect: RelativeRect\n}\n\nconst areMeasurementsEqual = (a: Measurement | null, b: Measurement | null) => {\n if (!a && !b) return true\n if (!a || !b) return false\n return (\n Math.abs(a.bounds.minX - b.bounds.minX) < 0.5 &&\n Math.abs(a.bounds.maxX - b.bounds.maxX) < 0.5 &&\n Math.abs(a.bounds.minY - b.bounds.minY) < 0.5 &&\n Math.abs(a.bounds.maxY - b.bounds.maxY) < 0.5 &&\n Math.abs(a.rect.left - b.rect.left) < 0.5 &&\n Math.abs(a.rect.top - b.rect.top) < 0.5 &&\n Math.abs(a.rect.width - b.rect.width) < 0.5 &&\n Math.abs(a.rect.height - b.rect.height) < 0.5\n )\n}\n\ninterface Props {\n componentId: string\n svgDivRef: React.RefObject<HTMLDivElement | null>\n containerRef: React.RefObject<HTMLDivElement | null>\n onComponentClick?: (componentId: string, event: MouseEvent) => void\n onHoverChange?: (componentId: string, isHovering: boolean) => void\n showOutline: boolean\n circuitJsonKey: string\n}\n\nexport const SchematicComponentMouseTarget = ({\n componentId,\n svgDivRef,\n containerRef,\n onComponentClick,\n onHoverChange,\n showOutline,\n circuitJsonKey,\n}: Props) => {\n const [measurement, setMeasurement] = useState<Measurement | null>(null)\n const frameRef = useRef<number | null>(null)\n\n const measure = useCallback(() => {\n frameRef.current = null\n const svgDiv = svgDivRef.current\n const container = containerRef.current\n if (!svgDiv || !container) {\n setMeasurement((prev) => (prev ? null : prev))\n return\n }\n const element = svgDiv.querySelector<SVGGraphicsElement | HTMLElement>(\n `[data-schematic-component-id=\"${componentId}\"]`,\n )\n if (!element) {\n setMeasurement((prev) => (prev ? null : prev))\n return\n }\n\n const elementRect = element.getBoundingClientRect()\n const containerRect = container.getBoundingClientRect()\n\n const nextMeasurement: Measurement = {\n bounds: {\n minX: elementRect.left,\n maxX: elementRect.right,\n minY: elementRect.top,\n maxY: elementRect.bottom,\n },\n rect: {\n left: elementRect.left - containerRect.left,\n top: elementRect.top - containerRect.top,\n width: elementRect.width,\n height: elementRect.height,\n },\n }\n\n setMeasurement((prev) =>\n areMeasurementsEqual(prev, nextMeasurement) ? prev : nextMeasurement,\n )\n }, [componentId, containerRef, svgDivRef])\n\n const scheduleMeasure = useCallback(() => {\n if (frameRef.current !== null) return\n frameRef.current = window.requestAnimationFrame(measure)\n }, [measure])\n\n useEffect(() => {\n scheduleMeasure()\n }, [scheduleMeasure, circuitJsonKey])\n\n useEffect(() => {\n scheduleMeasure()\n const svgDiv = svgDivRef.current\n const container = containerRef.current\n if (!svgDiv || !container) return\n\n const resizeObserver =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(() => {\n scheduleMeasure()\n })\n : null\n resizeObserver?.observe(container)\n resizeObserver?.observe(svgDiv)\n\n const mutationObserver =\n typeof MutationObserver !== \"undefined\"\n ? new MutationObserver(() => {\n scheduleMeasure()\n })\n : null\n mutationObserver?.observe(svgDiv, {\n attributes: true,\n attributeFilter: [\"style\", \"transform\"],\n subtree: true,\n childList: true,\n })\n\n window.addEventListener(\"scroll\", scheduleMeasure, true)\n window.addEventListener(\"resize\", scheduleMeasure)\n\n return () => {\n resizeObserver?.disconnect()\n mutationObserver?.disconnect()\n window.removeEventListener(\"scroll\", scheduleMeasure, true)\n window.removeEventListener(\"resize\", scheduleMeasure)\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current)\n frameRef.current = null\n }\n }\n }, [scheduleMeasure, svgDivRef, containerRef])\n\n const handleClick = useCallback(\n (event: MouseEvent) => {\n if (onComponentClick) {\n onComponentClick(componentId, event)\n }\n },\n [componentId, onComponentClick],\n )\n\n const bounds = measurement?.bounds ?? null\n\n const { hovering } = useMouseEventsOverBoundingBox({\n bounds,\n onClick: onComponentClick ? handleClick : undefined,\n })\n\n // Notify parent of hover state changes\n useEffect(() => {\n if (onHoverChange) {\n onHoverChange(componentId, hovering)\n }\n }, [hovering, componentId, onHoverChange])\n\n if (!measurement || !hovering || !showOutline) {\n return null\n }\n\n const rect = measurement.rect\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n border: \"1.5px solid rgba(51, 153, 255, 0.9)\",\n pointerEvents: \"none\",\n zIndex: zIndexMap.schematicComponentHoverOutline,\n }}\n />\n )\n}\n","import {\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from \"react\"\nimport {\n MouseTrackerContext,\n type BoundingBoxBounds,\n} from \"../components/MouseTracker\"\n\ninterface UseMouseEventsOverBoundingBoxOptions {\n bounds: BoundingBoxBounds | null\n onClick?: (event: MouseEvent) => void\n}\n\nexport const useMouseEventsOverBoundingBox = (\n options: UseMouseEventsOverBoundingBoxOptions,\n) => {\n const context = useContext(MouseTrackerContext)\n\n if (!context) {\n throw new Error(\n \"useMouseEventsOverBoundingBox must be used within a MouseTracker\",\n )\n }\n\n const id = useId()\n const latestOptionsRef = useRef(options)\n latestOptionsRef.current = options\n\n const handleClick = useMemo(\n () => (event: MouseEvent) => {\n latestOptionsRef.current.onClick?.(event)\n },\n [],\n )\n\n useEffect(() => {\n context.registerBoundingBox(id, {\n bounds: latestOptionsRef.current.bounds,\n onClick: latestOptionsRef.current.onClick ? handleClick : undefined,\n })\n return () => {\n context.unregisterBoundingBox(id)\n }\n }, [context, handleClick, id])\n\n useEffect(() => {\n context.updateBoundingBox(id, {\n bounds: latestOptionsRef.current.bounds,\n onClick: latestOptionsRef.current.onClick ? handleClick : undefined,\n })\n }, [\n context,\n handleClick,\n id,\n options.bounds?.minX,\n options.bounds?.maxX,\n options.bounds?.minY,\n options.bounds?.maxY,\n options.onClick,\n ])\n\n const hovering = useSyncExternalStore(\n context.subscribe,\n () => context.isHovering(id),\n () => false,\n )\n\n return { hovering }\n}\n","import {\n convertCircuitJsonToSchematicSimulationSvg,\n type ColorOverrides,\n} from \"circuit-to-svg\"\nimport { useEffect, useState, useMemo, useRef } from \"react\"\nimport { useResizeHandling } from \"../hooks/use-resize-handling\"\nimport { useMouseMatrixTransform } from \"use-mouse-matrix-transform\"\nimport { toString as transformToString } from \"transformation-matrix\"\nimport type { CircuitJson } from \"circuit-json\"\n\ninterface Props {\n circuitJson: CircuitJson\n containerStyle?: React.CSSProperties\n colorOverrides?: ColorOverrides\n width?: number\n height?: number\n className?: string\n}\n\nexport const AnalogSimulationViewer = ({\n circuitJson: inputCircuitJson,\n containerStyle,\n colorOverrides,\n width,\n height,\n className,\n}: Props) => {\n const [circuitJson, setCircuitJson] = useState<CircuitJson | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n const [svgObjectUrl, setSvgObjectUrl] = useState<string | null>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const imgRef = useRef<HTMLImageElement>(null)\n\n const { containerWidth, containerHeight } = useResizeHandling(\n containerRef as React.RefObject<HTMLElement>,\n )\n\n const [isDragging, setIsDragging] = useState(false)\n\n const {\n ref: transformRef,\n cancelDrag: _cancelDrag,\n transform: _svgToScreenProjection,\n } = useMouseMatrixTransform({\n onSetTransform(transform) {\n if (imgRef.current) {\n imgRef.current.style.transform = transformToString(transform)\n }\n },\n })\n\n const effectiveWidth = width || containerWidth || 1000\n const effectiveHeight = height || containerHeight || 600\n\n // Set CircuitJSON from props\n useEffect(() => {\n setIsLoading(true)\n setError(null)\n setCircuitJson(inputCircuitJson)\n setIsLoading(false)\n }, [inputCircuitJson])\n\n // Find simulation experiment ID from circuit JSON\n const simulationExperimentId = useMemo(() => {\n if (!circuitJson) return null\n const simulationElement = circuitJson.find(\n (el) => el.type === \"simulation_experiment\",\n )\n return simulationElement?.simulation_experiment_id || null\n }, [circuitJson])\n\n // Find simulation graph IDs from circuit JSON\n const simulationGraphIds = useMemo(() => {\n if (!circuitJson) return []\n return circuitJson\n .filter((el) => el.type === \"simulation_transient_voltage_graph\")\n .map((el) => el.simulation_transient_voltage_graph_id)\n }, [circuitJson])\n\n // Generate SVG from CircuitJSON\n const simulationSvg = useMemo(() => {\n if (\n !circuitJson ||\n !effectiveWidth ||\n !effectiveHeight ||\n !simulationExperimentId\n )\n return \"\"\n\n try {\n return convertCircuitJsonToSchematicSimulationSvg({\n circuitJson,\n simulation_experiment_id: simulationExperimentId,\n simulation_transient_voltage_graph_ids: simulationGraphIds,\n width: effectiveWidth,\n height: effectiveHeight,\n schematicOptions: { colorOverrides },\n })\n } catch (fallbackErr) {\n console.error(\"Failed to generate fallback schematic SVG:\", fallbackErr)\n return \"\"\n }\n }, [\n circuitJson,\n effectiveWidth,\n effectiveHeight,\n colorOverrides,\n simulationExperimentId,\n simulationGraphIds,\n ])\n\n // Create/revoke object URL whenever the SVG changes\n useEffect(() => {\n if (!simulationSvg) {\n setSvgObjectUrl(null)\n return\n }\n\n try {\n const blob = new Blob([simulationSvg], { type: \"image/svg+xml\" })\n const url = URL.createObjectURL(blob)\n setSvgObjectUrl(url)\n return () => {\n URL.revokeObjectURL(url)\n }\n } catch (error) {\n console.error(\"Failed to create SVG object URL:\", error)\n setSvgObjectUrl(null)\n }\n }, [simulationSvg])\n\n const containerBackgroundColor = useMemo(() => {\n if (!simulationSvg) return \"transparent\"\n const match = simulationSvg.match(\n /<svg[^>]*style=\"[^\"]*background-color:\\s*([^;\\\"]+)/i,\n )\n return match?.[1] ?? \"transparent\"\n }, [simulationSvg])\n\n const handleMouseDown = (_e: React.MouseEvent) => {\n setIsDragging(true)\n }\n\n const handleTouchStart = (_e: React.TouchEvent) => {\n setIsDragging(true)\n }\n\n useEffect(() => {\n const handleMouseUp = () => {\n setIsDragging(false)\n }\n\n const handleTouchEnd = () => {\n setIsDragging(false)\n }\n\n window.addEventListener(\"mouseup\", handleMouseUp)\n window.addEventListener(\"touchend\", handleTouchEnd)\n\n return () => {\n window.removeEventListener(\"mouseup\", handleMouseUp)\n window.removeEventListener(\"touchend\", handleTouchEnd)\n }\n }, [])\n\n if (isLoading) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"#f5f5f5\",\n minHeight: \"300px\",\n fontFamily: \"sans-serif\",\n fontSize: \"16px\",\n color: \"#666\",\n ...containerStyle,\n }}\n className={className}\n >\n Loading circuit...\n </div>\n )\n }\n\n if (error) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"#fef2f2\",\n minHeight: \"300px\",\n fontFamily: \"sans-serif\",\n fontSize: \"16px\",\n color: \"#dc2626\",\n ...containerStyle,\n }}\n className={className}\n >\n <div style={{ textAlign: \"center\", padding: \"20px\" }}>\n <div style={{ fontWeight: \"bold\", marginBottom: \"8px\" }}>\n Circuit Conversion Error\n </div>\n <div style={{ fontSize: \"14px\" }}>{error}</div>\n </div>\n </div>\n )\n }\n\n if (!simulationSvg) {\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"#f8fafc\",\n minHeight: \"300px\",\n fontFamily: \"sans-serif\",\n gap: \"12px\",\n ...containerStyle,\n }}\n className={className}\n >\n <div style={{ fontSize: \"16px\", color: \"#475569\", fontWeight: 500 }}>\n No Simulation Found\n </div>\n <div style={{ fontSize: \"14px\", color: \"#64748b\" }}>\n Use{\" \"}\n <code\n style={{\n backgroundColor: \"#e2e8f0\",\n padding: \"2px 6px\",\n borderRadius: \"4px\",\n fontFamily: \"monospace\",\n fontSize: \"13px\",\n }}\n >\n {\"<analogsimulation />\"}\n </code>{\" \"}\n to create simulations\n </div>\n </div>\n )\n }\n\n return (\n <div\n ref={(node) => {\n containerRef.current = node\n transformRef.current = node\n }}\n style={{\n position: \"relative\",\n backgroundColor: containerBackgroundColor,\n overflow: \"hidden\",\n minHeight: \"300px\",\n cursor: isDragging ? \"grabbing\" : \"grab\",\n ...containerStyle,\n }}\n className={className}\n onMouseDown={handleMouseDown}\n onTouchStart={handleTouchStart}\n >\n {svgObjectUrl ? (\n <img\n ref={imgRef}\n src={svgObjectUrl}\n alt=\"Circuit Simulation\"\n style={{\n transformOrigin: \"0 0\",\n width: \"100%\",\n height: \"100%\",\n display: \"block\",\n objectFit: \"contain\",\n }}\n />\n ) : (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100%\",\n minHeight: \"300px\",\n color: \"#666\",\n fontFamily: \"sans-serif\",\n }}\n >\n Failed to render SVG\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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","names":["su","useEffect","useRef","su","useEffect","su","useCallback","useEffect","useMemo","useRef","useState","useEffect","su","useEffect","useRef","useState","compose","debug","su","jsx","jsx","jsxs","su","jsx","jsxs","su","jsx","jsx","useMemo","jsx","jsxs","useEffect","useState","jsx","jsxs","useState","useEffect","useState","useEffect","useCallback","useCallback","useEffect","useMemo","useRef","Fragment","jsx","useCallback","useEffect","useRef","useState","useContext","useEffect","useMemo","useRef","useContext","useRef","useMemo","useEffect","jsx","useState","useRef","useCallback","useEffect","jsx","jsxs","debug","useState","circuitJson","useMemo","useEffect","useRef","useCallback","su","useEffect","useState","useMemo","useRef","useMouseMatrixTransform","transformToString","jsx","jsxs","useState","useRef","useEffect","useMemo","error"]}
@@ -115,6 +115,7 @@ export const SchematicViewer = ({
115
115
 
116
116
  const [editModeEnabled, setEditModeEnabled] = useState(defaultEditMode)
117
117
  const [snapToGrid, setSnapToGrid] = useState(true)
118
+ const [showGrid, setShowGrid] = useState(debugGrid)
118
119
  const [isInteractionEnabled, setIsInteractionEnabled] = useState<boolean>(
119
120
  !clickToInteractEnabled,
120
121
  )
@@ -213,7 +214,7 @@ export const SchematicViewer = ({
213
214
  return convertCircuitJsonToSchematicSvg(circuitJson as any, {
214
215
  width: containerWidth,
215
216
  height: containerHeight || 720,
216
- grid: !debugGrid
217
+ grid: !showGrid
217
218
  ? undefined
218
219
  : {
219
220
  cellSize: 1,
@@ -221,7 +222,7 @@ export const SchematicViewer = ({
221
222
  },
222
223
  colorOverrides,
223
224
  })
224
- }, [circuitJsonKey, containerWidth, containerHeight])
225
+ }, [circuitJsonKey, containerWidth, containerHeight, showGrid])
225
226
 
226
227
  const containerBackgroundColor = useMemo(() => {
227
228
  const match = svgString.match(
@@ -454,6 +455,8 @@ export const SchematicViewer = ({
454
455
  setStoredBoolean("schematic_viewer_show_groups", value)
455
456
  }
456
457
  }}
458
+ showGrid={showGrid}
459
+ onToggleGrid={setShowGrid}
457
460
  />
458
461
  {spiceSimulationEnabled && (
459
462
  <SpiceSimulationIcon onClick={() => setShowSpiceOverlay(true)} />
@@ -11,6 +11,8 @@ interface ViewMenuProps {
11
11
  onClose: () => void
12
12
  showGroups: boolean
13
13
  onToggleGroups: (show: boolean) => void
14
+ showGrid: boolean
15
+ onToggleGrid: (show: boolean) => void
14
16
  }
15
17
 
16
18
  export const ViewMenu = ({
@@ -20,6 +22,8 @@ export const ViewMenu = ({
20
22
  onClose,
21
23
  showGroups,
22
24
  onToggleGroups,
25
+ showGrid,
26
+ onToggleGrid,
23
27
  }: ViewMenuProps) => {
24
28
  const hasGroups = useMemo(() => {
25
29
  if (!circuitJson || circuitJson.length === 0) return false
@@ -153,6 +157,49 @@ export const ViewMenu = ({
153
157
  </div>
154
158
  )}
155
159
 
160
+ {/* Grid Toggle Option */}
161
+ <div
162
+ onClick={() => onToggleGrid(!showGrid)}
163
+ onTouchEnd={(e) => {
164
+ e.preventDefault()
165
+ onToggleGrid(!showGrid)
166
+ }}
167
+ style={{
168
+ padding: "8px 12px",
169
+ cursor: "pointer",
170
+ fontSize: "13px",
171
+ color: "#000000",
172
+ fontFamily: "sans-serif",
173
+ display: "flex",
174
+ alignItems: "center",
175
+ gap: "8px",
176
+ }}
177
+ onMouseEnter={(e) => {
178
+ e.currentTarget.style.backgroundColor = "#f0f0f0"
179
+ }}
180
+ onMouseLeave={(e) => {
181
+ e.currentTarget.style.backgroundColor = "transparent"
182
+ }}
183
+ >
184
+ <div
185
+ style={{
186
+ width: "16px",
187
+ height: "16px",
188
+ border: "2px solid #000",
189
+ borderRadius: "2px",
190
+ backgroundColor: "transparent",
191
+ display: "flex",
192
+ alignItems: "center",
193
+ justifyContent: "center",
194
+ fontSize: "10px",
195
+ fontWeight: "bold",
196
+ }}
197
+ >
198
+ {showGrid && "✓"}
199
+ </div>
200
+ Show Grid
201
+ </div>
202
+
156
203
  {/* Version Info */}
157
204
  <div
158
205
  style={{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/schematic-viewer",
3
- "version": "2.0.52",
3
+ "version": "2.0.54",
4
4
  "main": "dist/index.js",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -27,7 +27,7 @@
27
27
  "react-dom": "^19.1.0",
28
28
  "react-reconciler": "^0.31.0",
29
29
  "semver": "^7.7.2",
30
- "tscircuit": "^0.0.1149",
30
+ "tscircuit": "^0.0.1194",
31
31
  "tsup": "^8.3.5",
32
32
  "vite": "^6.0.3"
33
33
  },