@tscircuit/pcb-viewer 1.11.290 → 1.11.292

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -12373,7 +12373,7 @@ function ifSetsMatchExactly(set1, set2) {
12373
12373
 
12374
12374
  // src/components/MouseElementTracker.tsx
12375
12375
  import { useState as useState7, useMemo as useMemo5 } from "react";
12376
- import { applyToPoint as applyToPoint14, inverse as inverse5 } from "transformation-matrix";
12376
+ import { applyToPoint as applyToPoint15, inverse as inverse5 } from "transformation-matrix";
12377
12377
 
12378
12378
  // src/components/ElementOverlayBox.tsx
12379
12379
  import { useEffect as useEffect11, useState as useState6 } from "react";
@@ -12679,6 +12679,7 @@ var COLORS = {
12679
12679
  // src/components/AnchorOffsetOverlay/common/guards.ts
12680
12680
  var isPcbComponent = (element) => element?.type === "pcb_component";
12681
12681
  var isPcbGroup = (element) => element?.type === "pcb_group";
12682
+ var isPcbPanel = (element) => element?.type === "pcb_panel";
12682
12683
  var isPcbBoard = (element) => element?.type === "pcb_board";
12683
12684
 
12684
12685
  // src/components/AnchorOffsetOverlay/Board/index.tsx
@@ -13122,8 +13123,8 @@ var GroupAnchorOffsetOverlay = ({
13122
13123
  const yLabelOffset = isTargetRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
13123
13124
  const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
13124
13125
  const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
13125
- const xLabelText = `\u0394x: ${displayOffsetX ? displayOffsetX : offsetX.toFixed(2)}mm`;
13126
- const yLabelText = `\u0394y: ${displayOffsetY ? displayOffsetY : offsetY.toFixed(2)}mm`;
13126
+ const xLabelText = displayOffsetX ? displayOffsetX : `${offsetX.toFixed(2)}mm`;
13127
+ const yLabelText = displayOffsetY ? displayOffsetY : `${offsetY.toFixed(2)}mm`;
13127
13128
  return /* @__PURE__ */ jsxs10(
13128
13129
  "g",
13129
13130
  {
@@ -13257,8 +13258,217 @@ var GroupAnchorOffsetOverlay = ({
13257
13258
  );
13258
13259
  };
13259
13260
 
13261
+ // src/components/AnchorOffsetOverlay/Panel/index.tsx
13262
+ import { applyToPoint as applyToPoint14 } from "transformation-matrix";
13263
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
13264
+ var PanelAnchorOffsetOverlay = ({
13265
+ elements,
13266
+ highlightedPrimitives,
13267
+ transform,
13268
+ containerWidth,
13269
+ containerHeight
13270
+ }) => {
13271
+ const panels = elements.filter((el) => isPcbPanel(el));
13272
+ const boards = elements.filter((el) => isPcbBoard(el));
13273
+ const hoveredBoardIds = highlightedPrimitives.map((primitive) => {
13274
+ if (isPcbBoard(primitive._element)) {
13275
+ return primitive._element.pcb_board_id;
13276
+ }
13277
+ return null;
13278
+ }).filter((id) => Boolean(id));
13279
+ const isShowingAnchorOffsets = useGlobalStore(
13280
+ (state) => state.is_showing_group_anchor_offsets
13281
+ );
13282
+ if (!isShowingAnchorOffsets && hoveredBoardIds.length === 0) {
13283
+ return null;
13284
+ }
13285
+ const boardTargets = boards.map((board) => {
13286
+ const panelId = board.pcb_panel_id;
13287
+ const positionMode = board.position_mode;
13288
+ if (!panelId || positionMode !== "relative_to_panel_anchor") return null;
13289
+ const panel = panels.find((p) => p.pcb_panel_id === panelId);
13290
+ return panel ? { board, panel, type: "board" } : null;
13291
+ }).filter(
13292
+ (target) => Boolean(target)
13293
+ );
13294
+ if (boardTargets.length === 0) return null;
13295
+ const shouldShowAllTargets = hoveredBoardIds.length === 0;
13296
+ const labelStyle = {
13297
+ color: COLORS.LABEL_TEXT,
13298
+ mixBlendMode: "difference",
13299
+ pointerEvents: "none",
13300
+ fontSize: VISUAL_CONFIG.LABEL_FONT_SIZE,
13301
+ fontFamily: "monospace",
13302
+ fontWeight: "bold"
13303
+ };
13304
+ const targetEntries = boardTargets.filter((target) => {
13305
+ return shouldShowAllTargets || hoveredBoardIds.includes(target.board.pcb_board_id);
13306
+ });
13307
+ if (targetEntries.length === 0) return null;
13308
+ const panelAnchorScreens = /* @__PURE__ */ new Map();
13309
+ return /* @__PURE__ */ jsx14(
13310
+ "div",
13311
+ {
13312
+ style: {
13313
+ position: "absolute",
13314
+ left: 0,
13315
+ top: 0,
13316
+ width: containerWidth,
13317
+ height: containerHeight,
13318
+ overflow: "hidden",
13319
+ pointerEvents: "none",
13320
+ zIndex: zIndexMap.dimensionOverlay
13321
+ },
13322
+ children: /* @__PURE__ */ jsxs11(
13323
+ "svg",
13324
+ {
13325
+ style: {
13326
+ position: "absolute",
13327
+ left: 0,
13328
+ top: 0,
13329
+ pointerEvents: "none"
13330
+ },
13331
+ width: containerWidth,
13332
+ height: containerHeight,
13333
+ children: [
13334
+ targetEntries.map((target) => {
13335
+ const anchorPosition = target.panel.center;
13336
+ const anchorKey = target.panel.pcb_panel_id;
13337
+ let targetCenter;
13338
+ let targetId;
13339
+ let displayOffsetX;
13340
+ let displayOffsetY;
13341
+ targetCenter = target.board.center;
13342
+ targetId = target.board.pcb_board_id;
13343
+ displayOffsetX = target.board.display_offset_x;
13344
+ displayOffsetY = target.board.display_offset_y;
13345
+ if (!panelAnchorScreens.has(anchorKey)) {
13346
+ const screenPoint = applyToPoint14(transform, anchorPosition);
13347
+ panelAnchorScreens.set(anchorKey, screenPoint);
13348
+ }
13349
+ const anchorMarkerScreen = panelAnchorScreens.get(anchorKey);
13350
+ const targetScreen = applyToPoint14(transform, targetCenter);
13351
+ const offsetX = targetCenter.x - anchorPosition.x;
13352
+ const offsetY = targetCenter.y - anchorPosition.y;
13353
+ const xLineLength = Math.abs(targetScreen.x - anchorMarkerScreen.x);
13354
+ const yLineLength = Math.abs(targetScreen.y - anchorMarkerScreen.y);
13355
+ const isTargetAboveAnchor = targetScreen.y < anchorMarkerScreen.y;
13356
+ const isTargetRightOfAnchor = targetScreen.x > anchorMarkerScreen.x;
13357
+ const xLabelOffset = isTargetAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
13358
+ const yLabelOffset = isTargetRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
13359
+ const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
13360
+ const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
13361
+ const xLabelText = `${displayOffsetX ?? offsetX.toFixed(2)}mm`;
13362
+ const yLabelText = `${displayOffsetY ?? offsetY.toFixed(2)}mm`;
13363
+ return /* @__PURE__ */ jsxs11("g", { children: [
13364
+ /* @__PURE__ */ jsx14(
13365
+ "line",
13366
+ {
13367
+ x1: anchorMarkerScreen.x,
13368
+ y1: anchorMarkerScreen.y,
13369
+ x2: targetScreen.x,
13370
+ y2: anchorMarkerScreen.y,
13371
+ stroke: COLORS.OFFSET_LINE,
13372
+ strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
13373
+ strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
13374
+ }
13375
+ ),
13376
+ /* @__PURE__ */ jsx14(
13377
+ "line",
13378
+ {
13379
+ x1: targetScreen.x,
13380
+ y1: anchorMarkerScreen.y,
13381
+ x2: targetScreen.x,
13382
+ y2: targetScreen.y,
13383
+ stroke: COLORS.OFFSET_LINE,
13384
+ strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
13385
+ strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
13386
+ }
13387
+ ),
13388
+ /* @__PURE__ */ jsx14(
13389
+ "circle",
13390
+ {
13391
+ cx: targetScreen.x,
13392
+ cy: targetScreen.y,
13393
+ r: VISUAL_CONFIG.COMPONENT_MARKER_RADIUS,
13394
+ fill: COLORS.COMPONENT_MARKER_FILL,
13395
+ stroke: COLORS.COMPONENT_MARKER_STROKE,
13396
+ strokeWidth: 1
13397
+ }
13398
+ ),
13399
+ shouldShowXLabel && /* @__PURE__ */ jsx14(
13400
+ "foreignObject",
13401
+ {
13402
+ x: Math.min(anchorMarkerScreen.x, targetScreen.x),
13403
+ y: anchorMarkerScreen.y + xLabelOffset,
13404
+ width: Math.abs(targetScreen.x - anchorMarkerScreen.x),
13405
+ height: 20,
13406
+ style: { overflow: "visible" },
13407
+ children: /* @__PURE__ */ jsx14("div", { style: { ...labelStyle, textAlign: "center" }, children: xLabelText })
13408
+ }
13409
+ ),
13410
+ shouldShowYLabel && /* @__PURE__ */ jsx14(
13411
+ "foreignObject",
13412
+ {
13413
+ x: targetScreen.x + yLabelOffset,
13414
+ y: Math.min(anchorMarkerScreen.y, targetScreen.y),
13415
+ width: VISUAL_CONFIG.Y_LABEL_MIN_WIDTH,
13416
+ height: Math.abs(targetScreen.y - anchorMarkerScreen.y),
13417
+ style: { overflow: "visible" },
13418
+ children: /* @__PURE__ */ jsx14(
13419
+ "div",
13420
+ {
13421
+ style: {
13422
+ ...labelStyle,
13423
+ display: "flex",
13424
+ alignItems: "center",
13425
+ justifyContent: isTargetRightOfAnchor ? "flex-start" : "flex-end",
13426
+ whiteSpace: "nowrap",
13427
+ padding: "0 4px",
13428
+ height: "100%"
13429
+ },
13430
+ children: yLabelText
13431
+ }
13432
+ )
13433
+ }
13434
+ )
13435
+ ] }, `${target.panel.pcb_panel_id}-${targetId}-${target.type}`);
13436
+ }),
13437
+ Array.from(panelAnchorScreens.entries()).map(
13438
+ ([panelId, anchorScreen]) => /* @__PURE__ */ jsxs11("g", { children: [
13439
+ /* @__PURE__ */ jsx14(
13440
+ "line",
13441
+ {
13442
+ x1: anchorScreen.x - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13443
+ y1: anchorScreen.y,
13444
+ x2: anchorScreen.x + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13445
+ y2: anchorScreen.y,
13446
+ stroke: COLORS.OFFSET_LINE,
13447
+ strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
13448
+ }
13449
+ ),
13450
+ /* @__PURE__ */ jsx14(
13451
+ "line",
13452
+ {
13453
+ x1: anchorScreen.x,
13454
+ y1: anchorScreen.y - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13455
+ x2: anchorScreen.x,
13456
+ y2: anchorScreen.y + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13457
+ stroke: COLORS.OFFSET_LINE,
13458
+ strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
13459
+ }
13460
+ )
13461
+ ] }, `anchor-${panelId}`)
13462
+ )
13463
+ ]
13464
+ }
13465
+ )
13466
+ }
13467
+ );
13468
+ };
13469
+
13260
13470
  // src/components/MouseElementTracker.tsx
13261
- import { Fragment as Fragment7, jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
13471
+ import { Fragment as Fragment7, jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
13262
13472
  var getPolygonBoundingBox = (points) => {
13263
13473
  if (points.length === 0) return null;
13264
13474
  let minX = points[0].x;
@@ -13404,7 +13614,7 @@ var MouseElementTracker = ({
13404
13614
  h = "h" in primitive ? primitive.h : "r" in primitive ? primitive.r * 2 : "rX" in primitive && "rY" in primitive ? primitive.rY * 2 : 0;
13405
13615
  }
13406
13616
  if (!basePoint) continue;
13407
- const screenPos = applyToPoint14(transform, basePoint);
13617
+ const screenPos = applyToPoint15(transform, basePoint);
13408
13618
  const screenSize = {
13409
13619
  w: w * transform.a,
13410
13620
  h: h * transform.a
@@ -13429,7 +13639,7 @@ var MouseElementTracker = ({
13429
13639
  }, [mousedPrimitives, transform]);
13430
13640
  const handleInteraction = (x, y, transform2, primitives2) => {
13431
13641
  setMousePos({ x, y });
13432
- const rwPoint = applyToPoint14(inverse5(transform2), { x, y });
13642
+ const rwPoint = applyToPoint15(inverse5(transform2), { x, y });
13433
13643
  const newMousedPrimitives = getPrimitivesUnderPoint(
13434
13644
  primitives2,
13435
13645
  rwPoint,
@@ -13444,7 +13654,7 @@ var MouseElementTracker = ({
13444
13654
  setMousedPrimitives(newMousedPrimitives);
13445
13655
  onMouseHoverOverPrimitives(newMousedPrimitives);
13446
13656
  };
13447
- return /* @__PURE__ */ jsxs11(
13657
+ return /* @__PURE__ */ jsxs12(
13448
13658
  "div",
13449
13659
  {
13450
13660
  ref: containerRef,
@@ -13468,7 +13678,7 @@ var MouseElementTracker = ({
13468
13678
  },
13469
13679
  children: [
13470
13680
  children,
13471
- /* @__PURE__ */ jsx14(
13681
+ /* @__PURE__ */ jsx15(
13472
13682
  ElementOverlayBox,
13473
13683
  {
13474
13684
  elements,
@@ -13476,8 +13686,8 @@ var MouseElementTracker = ({
13476
13686
  highlightedPrimitives
13477
13687
  }
13478
13688
  ),
13479
- transform && /* @__PURE__ */ jsxs11(Fragment7, { children: [
13480
- /* @__PURE__ */ jsx14(
13689
+ transform && /* @__PURE__ */ jsxs12(Fragment7, { children: [
13690
+ /* @__PURE__ */ jsx15(
13481
13691
  BoardAnchorOffsetOverlay,
13482
13692
  {
13483
13693
  elements,
@@ -13487,7 +13697,7 @@ var MouseElementTracker = ({
13487
13697
  containerHeight: height
13488
13698
  }
13489
13699
  ),
13490
- /* @__PURE__ */ jsx14(
13700
+ /* @__PURE__ */ jsx15(
13491
13701
  GroupAnchorOffsetOverlay,
13492
13702
  {
13493
13703
  elements,
@@ -13496,6 +13706,16 @@ var MouseElementTracker = ({
13496
13706
  containerWidth: width,
13497
13707
  containerHeight: height
13498
13708
  }
13709
+ ),
13710
+ /* @__PURE__ */ jsx15(
13711
+ PanelAnchorOffsetOverlay,
13712
+ {
13713
+ elements,
13714
+ highlightedPrimitives,
13715
+ transform,
13716
+ containerWidth: width,
13717
+ containerHeight: height
13718
+ }
13499
13719
  )
13500
13720
  ] })
13501
13721
  ]
@@ -13504,10 +13724,10 @@ var MouseElementTracker = ({
13504
13724
  };
13505
13725
 
13506
13726
  // src/components/PcbGroupOverlay.tsx
13507
- import { applyToPoint as applyToPoint15 } from "transformation-matrix";
13727
+ import { applyToPoint as applyToPoint16 } from "transformation-matrix";
13508
13728
  import { identity as identity8 } from "transformation-matrix";
13509
13729
  import { useRef as useRef9, useEffect as useEffect12 } from "react";
13510
- import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
13730
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
13511
13731
  var GROUP_COLORS = [
13512
13732
  "rgb(255, 100, 100)",
13513
13733
  "rgb(100, 255, 100)",
@@ -13662,10 +13882,10 @@ var PcbGroupOverlay = ({
13662
13882
  minY -= totalPadding;
13663
13883
  maxY += totalPadding;
13664
13884
  }
13665
- const topLeft = applyToPoint15(transform, { x: minX, y: maxY });
13666
- const topRight = applyToPoint15(transform, { x: maxX, y: maxY });
13667
- const bottomLeft = applyToPoint15(transform, { x: minX, y: minY });
13668
- const bottomRight = applyToPoint15(transform, { x: maxX, y: minY });
13885
+ const topLeft = applyToPoint16(transform, { x: minX, y: maxY });
13886
+ const topRight = applyToPoint16(transform, { x: maxX, y: maxY });
13887
+ const bottomLeft = applyToPoint16(transform, { x: minX, y: minY });
13888
+ const bottomRight = applyToPoint16(transform, { x: maxX, y: minY });
13669
13889
  const groupColor = GROUP_COLORS[groupIndex % GROUP_COLORS.length];
13670
13890
  ctx.strokeStyle = groupColor;
13671
13891
  ctx.lineWidth = 2;
@@ -13715,7 +13935,7 @@ var PcbGroupOverlay = ({
13715
13935
  x: group.anchor_position[0] ?? 0,
13716
13936
  y: group.anchor_position[1] ?? 0
13717
13937
  } : { x: group.anchor_position.x, y: group.anchor_position.y };
13718
- const anchorScreenPos = applyToPoint15(transform, anchorPositionValue);
13938
+ const anchorScreenPos = applyToPoint16(transform, anchorPositionValue);
13719
13939
  ctx.strokeStyle = "white";
13720
13940
  ctx.lineWidth = 1.5;
13721
13941
  ctx.setLineDash([]);
@@ -13740,14 +13960,14 @@ var PcbGroupOverlay = ({
13740
13960
  is_showing_group_anchor_offsets,
13741
13961
  hoveredComponentIds
13742
13962
  ]);
13743
- return /* @__PURE__ */ jsxs12(
13963
+ return /* @__PURE__ */ jsxs13(
13744
13964
  "div",
13745
13965
  {
13746
13966
  ref: containerRef,
13747
13967
  style: { position: "relative", width: "100%", height: "100%" },
13748
13968
  children: [
13749
13969
  children,
13750
- /* @__PURE__ */ jsx15(
13970
+ /* @__PURE__ */ jsx16(
13751
13971
  "canvas",
13752
13972
  {
13753
13973
  ref: canvasRef,
@@ -13767,9 +13987,9 @@ var PcbGroupOverlay = ({
13767
13987
  };
13768
13988
 
13769
13989
  // src/components/RatsNestOverlay.tsx
13770
- import { applyToPoint as applyToPoint16, identity as identity9 } from "transformation-matrix";
13990
+ import { applyToPoint as applyToPoint17, identity as identity9 } from "transformation-matrix";
13771
13991
  import { useMemo as useMemo6 } from "react";
13772
- import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
13992
+ import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
13773
13993
  var RatsNestOverlay = ({ transform, soup, children }) => {
13774
13994
  const isShowingRatsNest = useGlobalStore((s) => s.is_showing_rats_nest);
13775
13995
  const { netMap, idToNetMap } = useMemo6(
@@ -13832,9 +14052,9 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
13832
14052
  }, [soup, netMap, idToNetMap, isShowingRatsNest]);
13833
14053
  if (!soup || !isShowingRatsNest) return children;
13834
14054
  if (!transform) transform = identity9();
13835
- return /* @__PURE__ */ jsxs13("div", { style: { position: "relative" }, children: [
14055
+ return /* @__PURE__ */ jsxs14("div", { style: { position: "relative" }, children: [
13836
14056
  children,
13837
- /* @__PURE__ */ jsx16(
14057
+ /* @__PURE__ */ jsx17(
13838
14058
  "svg",
13839
14059
  {
13840
14060
  style: {
@@ -13848,9 +14068,9 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
13848
14068
  zIndex: zIndexMap.ratsNestOverlay
13849
14069
  },
13850
14070
  children: ratsNestLines.map(({ key, startPoint, endPoint, isInNet }) => {
13851
- const transformedStart = applyToPoint16(transform, startPoint);
13852
- const transformedEnd = applyToPoint16(transform, endPoint);
13853
- return /* @__PURE__ */ jsx16(
14071
+ const transformedStart = applyToPoint17(transform, startPoint);
14072
+ const transformedEnd = applyToPoint17(transform, endPoint);
14073
+ return /* @__PURE__ */ jsx17(
13854
14074
  "line",
13855
14075
  {
13856
14076
  x1: transformedStart.x,
@@ -13876,7 +14096,7 @@ import { css as css3 } from "@emotion/css";
13876
14096
  // package.json
13877
14097
  var package_default = {
13878
14098
  name: "@tscircuit/pcb-viewer",
13879
- version: "1.11.289",
14099
+ version: "1.11.291",
13880
14100
  main: "dist/index.js",
13881
14101
  type: "module",
13882
14102
  repository: "tscircuit/pcb-viewer",
@@ -13929,7 +14149,7 @@ var package_default = {
13929
14149
  "@tscircuit/alphabet": "^0.0.9",
13930
14150
  "@tscircuit/math-utils": "^0.0.29",
13931
14151
  "@vitejs/plugin-react": "^5.0.2",
13932
- "circuit-json": "^0.0.333",
14152
+ "circuit-json": "^0.0.342",
13933
14153
  "circuit-to-svg": "^0.0.271",
13934
14154
  color: "^4.2.3",
13935
14155
  "react-supergrid": "^1.0.10",
@@ -13982,9 +14202,9 @@ var useIsSmallScreen = () => {
13982
14202
  };
13983
14203
 
13984
14204
  // src/components/ToolbarOverlay.tsx
13985
- import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
14205
+ import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
13986
14206
  var LayerButton = ({ name, selected, onClick }) => {
13987
- return /* @__PURE__ */ jsxs14(
14207
+ return /* @__PURE__ */ jsxs15(
13988
14208
  "div",
13989
14209
  {
13990
14210
  className: css3`
@@ -14000,8 +14220,8 @@ var LayerButton = ({ name, selected, onClick }) => {
14000
14220
  `,
14001
14221
  onClick,
14002
14222
  children: [
14003
- /* @__PURE__ */ jsx17("span", { style: { marginRight: 2, opacity: selected ? 1 : 0 }, children: "\u2022" }),
14004
- /* @__PURE__ */ jsx17(
14223
+ /* @__PURE__ */ jsx18("span", { style: { marginRight: 2, opacity: selected ? 1 : 0 }, children: "\u2022" }),
14224
+ /* @__PURE__ */ jsx18(
14005
14225
  "span",
14006
14226
  {
14007
14227
  style: {
@@ -14021,7 +14241,7 @@ var ToolbarButton = ({
14021
14241
  isSmallScreen,
14022
14242
  onClick,
14023
14243
  ...props
14024
- }) => /* @__PURE__ */ jsx17(
14244
+ }) => /* @__PURE__ */ jsx18(
14025
14245
  "div",
14026
14246
  {
14027
14247
  ...props,
@@ -14058,7 +14278,7 @@ var CheckboxMenuItem = ({
14058
14278
  checked,
14059
14279
  onClick
14060
14280
  }) => {
14061
- return /* @__PURE__ */ jsxs14(
14281
+ return /* @__PURE__ */ jsxs15(
14062
14282
  "div",
14063
14283
  {
14064
14284
  className: css3`
@@ -14085,15 +14305,15 @@ var CheckboxMenuItem = ({
14085
14305
  onClick();
14086
14306
  },
14087
14307
  children: [
14088
- /* @__PURE__ */ jsx17("input", { type: "checkbox", checked, onChange: () => {
14308
+ /* @__PURE__ */ jsx18("input", { type: "checkbox", checked, onChange: () => {
14089
14309
  }, readOnly: true }),
14090
- /* @__PURE__ */ jsx17("span", { style: { color: "#eee" }, children: label })
14310
+ /* @__PURE__ */ jsx18("span", { style: { color: "#eee" }, children: label })
14091
14311
  ]
14092
14312
  }
14093
14313
  );
14094
14314
  };
14095
14315
  var RadioMenuItem = ({ label, checked, onClick }) => {
14096
- return /* @__PURE__ */ jsxs14(
14316
+ return /* @__PURE__ */ jsxs15(
14097
14317
  "div",
14098
14318
  {
14099
14319
  className: css3`
@@ -14120,9 +14340,9 @@ var RadioMenuItem = ({ label, checked, onClick }) => {
14120
14340
  onClick();
14121
14341
  },
14122
14342
  children: [
14123
- /* @__PURE__ */ jsx17("input", { type: "radio", checked, onChange: () => {
14343
+ /* @__PURE__ */ jsx18("input", { type: "radio", checked, onChange: () => {
14124
14344
  }, readOnly: true }),
14125
- /* @__PURE__ */ jsx17("span", { style: { color: "#eee" }, children: label })
14345
+ /* @__PURE__ */ jsx18("span", { style: { color: "#eee" }, children: label })
14126
14346
  ]
14127
14347
  }
14128
14348
  );
@@ -14274,7 +14494,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14274
14494
  setErrorsOpen(false);
14275
14495
  }
14276
14496
  }, [isViewMenuOpen]);
14277
- return /* @__PURE__ */ jsxs14(
14497
+ return /* @__PURE__ */ jsxs15(
14278
14498
  "div",
14279
14499
  {
14280
14500
  style: { position: "relative", zIndex: "999 !important" },
@@ -14282,7 +14502,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14282
14502
  onMouseLeave: handleMouseLeave,
14283
14503
  children: [
14284
14504
  children,
14285
- /* @__PURE__ */ jsxs14(
14505
+ /* @__PURE__ */ jsxs15(
14286
14506
  "div",
14287
14507
  {
14288
14508
  style: {
@@ -14303,7 +14523,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14303
14523
  ]
14304
14524
  }
14305
14525
  ),
14306
- /* @__PURE__ */ jsxs14(
14526
+ /* @__PURE__ */ jsxs15(
14307
14527
  "div",
14308
14528
  {
14309
14529
  "data-toolbar-overlay": true,
@@ -14326,7 +14546,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14326
14546
  fontFamily: "sans-serif"
14327
14547
  },
14328
14548
  children: [
14329
- /* @__PURE__ */ jsxs14(
14549
+ /* @__PURE__ */ jsxs15(
14330
14550
  ToolbarButton,
14331
14551
  {
14332
14552
  isSmallScreen,
@@ -14337,10 +14557,10 @@ var ToolbarOverlay = ({ children, elements }) => {
14337
14557
  }
14338
14558
  },
14339
14559
  children: [
14340
- /* @__PURE__ */ jsxs14("div", { children: [
14560
+ /* @__PURE__ */ jsxs15("div", { children: [
14341
14561
  "layer:",
14342
14562
  " ",
14343
- /* @__PURE__ */ jsx17(
14563
+ /* @__PURE__ */ jsx18(
14344
14564
  "span",
14345
14565
  {
14346
14566
  style: {
@@ -14352,7 +14572,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14352
14572
  }
14353
14573
  )
14354
14574
  ] }),
14355
- isLayerMenuOpen && /* @__PURE__ */ jsx17("div", { style: { marginTop: 4, minWidth: 120 }, children: processedLayers.map((layer) => /* @__PURE__ */ jsx17(
14575
+ isLayerMenuOpen && /* @__PURE__ */ jsx18("div", { style: { marginTop: 4, minWidth: 120 }, children: processedLayers.map((layer) => /* @__PURE__ */ jsx18(
14356
14576
  LayerButton,
14357
14577
  {
14358
14578
  name: layer,
@@ -14366,7 +14586,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14366
14586
  ]
14367
14587
  }
14368
14588
  ),
14369
- /* @__PURE__ */ jsx17(
14589
+ /* @__PURE__ */ jsx18(
14370
14590
  ToolbarButton,
14371
14591
  {
14372
14592
  isSmallScreen,
@@ -14375,13 +14595,13 @@ var ToolbarOverlay = ({ children, elements }) => {
14375
14595
  ...errorCount > 0 ? { color: "red" } : {}
14376
14596
  },
14377
14597
  onClick: handleErrorsToggle,
14378
- children: /* @__PURE__ */ jsxs14("div", { children: [
14598
+ children: /* @__PURE__ */ jsxs15("div", { children: [
14379
14599
  errorCount,
14380
14600
  " errors"
14381
14601
  ] })
14382
14602
  }
14383
14603
  ),
14384
- isErrorsOpen && errorCount > 0 && /* @__PURE__ */ jsx17(
14604
+ isErrorsOpen && errorCount > 0 && /* @__PURE__ */ jsx18(
14385
14605
  "div",
14386
14606
  {
14387
14607
  style: {
@@ -14401,14 +14621,14 @@ var ToolbarOverlay = ({ children, elements }) => {
14401
14621
  },
14402
14622
  children: errorElements.map((e, i) => {
14403
14623
  const errorId = e.pcb_trace_error_id || `error_${i}_${e.error_type}_${e.message?.slice(0, 20)}`;
14404
- return /* @__PURE__ */ jsxs14(
14624
+ return /* @__PURE__ */ jsxs15(
14405
14625
  "div",
14406
14626
  {
14407
14627
  style: {
14408
14628
  borderBottom: i < errorElements.length - 1 ? "1px solid #444" : "none"
14409
14629
  },
14410
14630
  children: [
14411
- /* @__PURE__ */ jsxs14(
14631
+ /* @__PURE__ */ jsxs15(
14412
14632
  "div",
14413
14633
  {
14414
14634
  style: {
@@ -14459,7 +14679,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14459
14679
  }
14460
14680
  },
14461
14681
  children: [
14462
- /* @__PURE__ */ jsx17(
14682
+ /* @__PURE__ */ jsx18(
14463
14683
  "div",
14464
14684
  {
14465
14685
  style: {
@@ -14473,7 +14693,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14473
14693
  children: e.error_type
14474
14694
  }
14475
14695
  ),
14476
- /* @__PURE__ */ jsx17(
14696
+ /* @__PURE__ */ jsx18(
14477
14697
  "div",
14478
14698
  {
14479
14699
  style: {
@@ -14488,7 +14708,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14488
14708
  children: e.message
14489
14709
  }
14490
14710
  ),
14491
- /* @__PURE__ */ jsx17(
14711
+ /* @__PURE__ */ jsx18(
14492
14712
  "div",
14493
14713
  {
14494
14714
  ref: (el) => {
@@ -14508,7 +14728,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14508
14728
  ]
14509
14729
  }
14510
14730
  ),
14511
- /* @__PURE__ */ jsx17(
14731
+ /* @__PURE__ */ jsx18(
14512
14732
  "div",
14513
14733
  {
14514
14734
  ref: (el) => {
@@ -14521,7 +14741,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14521
14741
  backgroundColor: "#1a1a1a",
14522
14742
  borderTop: "1px solid #444"
14523
14743
  },
14524
- children: /* @__PURE__ */ jsx17(
14744
+ children: /* @__PURE__ */ jsx18(
14525
14745
  "div",
14526
14746
  {
14527
14747
  style: {
@@ -14544,58 +14764,58 @@ var ToolbarOverlay = ({ children, elements }) => {
14544
14764
  })
14545
14765
  }
14546
14766
  ),
14547
- /* @__PURE__ */ jsx17(
14767
+ /* @__PURE__ */ jsx18(
14548
14768
  ToolbarButton,
14549
14769
  {
14550
14770
  isSmallScreen,
14551
14771
  style: {},
14552
14772
  onClick: handleEditTraceToggle,
14553
- children: /* @__PURE__ */ jsxs14("div", { children: [
14773
+ children: /* @__PURE__ */ jsxs15("div", { children: [
14554
14774
  editModes.in_draw_trace_mode ? "\u2716 " : "",
14555
14775
  "Edit Traces"
14556
14776
  ] })
14557
14777
  }
14558
14778
  ),
14559
- /* @__PURE__ */ jsx17(
14779
+ /* @__PURE__ */ jsx18(
14560
14780
  ToolbarButton,
14561
14781
  {
14562
14782
  isSmallScreen,
14563
14783
  style: {},
14564
14784
  onClick: handleMoveComponentToggle,
14565
- children: /* @__PURE__ */ jsxs14("div", { children: [
14785
+ children: /* @__PURE__ */ jsxs15("div", { children: [
14566
14786
  editModes.in_move_footprint_mode ? "\u2716 " : "",
14567
14787
  "Move Components"
14568
14788
  ] })
14569
14789
  }
14570
14790
  ),
14571
- /* @__PURE__ */ jsx17(
14791
+ /* @__PURE__ */ jsx18(
14572
14792
  ToolbarButton,
14573
14793
  {
14574
14794
  isSmallScreen,
14575
14795
  style: {},
14576
14796
  onClick: handleRatsNestToggle,
14577
- children: /* @__PURE__ */ jsxs14("div", { children: [
14797
+ children: /* @__PURE__ */ jsxs15("div", { children: [
14578
14798
  viewSettings.is_showing_rats_nest ? "\u2716 " : "",
14579
14799
  "Rats Nest"
14580
14800
  ] })
14581
14801
  }
14582
14802
  ),
14583
- /* @__PURE__ */ jsx17(
14803
+ /* @__PURE__ */ jsx18(
14584
14804
  ToolbarButton,
14585
14805
  {
14586
14806
  isSmallScreen,
14587
14807
  style: measureToolArmed ? { backgroundColor: "#444" } : {},
14588
14808
  onClick: handleMeasureToolClick,
14589
- children: /* @__PURE__ */ jsx17("div", { children: "\u{1F4CF}" })
14809
+ children: /* @__PURE__ */ jsx18("div", { children: "\u{1F4CF}" })
14590
14810
  }
14591
14811
  ),
14592
- /* @__PURE__ */ jsx17(
14812
+ /* @__PURE__ */ jsx18(
14593
14813
  ToolbarButton,
14594
14814
  {
14595
14815
  isSmallScreen,
14596
14816
  onClick: handleViewMenuToggle,
14597
- children: /* @__PURE__ */ jsxs14("div", { children: [
14598
- /* @__PURE__ */ jsxs14(
14817
+ children: /* @__PURE__ */ jsxs15("div", { children: [
14818
+ /* @__PURE__ */ jsxs15(
14599
14819
  "div",
14600
14820
  {
14601
14821
  style: {
@@ -14605,7 +14825,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14605
14825
  },
14606
14826
  children: [
14607
14827
  "View",
14608
- /* @__PURE__ */ jsx17(
14828
+ /* @__PURE__ */ jsx18(
14609
14829
  "span",
14610
14830
  {
14611
14831
  style: {
@@ -14620,8 +14840,8 @@ var ToolbarOverlay = ({ children, elements }) => {
14620
14840
  ]
14621
14841
  }
14622
14842
  ),
14623
- isViewMenuOpen && /* @__PURE__ */ jsxs14("div", { style: { marginTop: 4, minWidth: 120 }, children: [
14624
- /* @__PURE__ */ jsx17(
14843
+ isViewMenuOpen && /* @__PURE__ */ jsxs15("div", { style: { marginTop: 4, minWidth: 120 }, children: [
14844
+ /* @__PURE__ */ jsx18(
14625
14845
  CheckboxMenuItem,
14626
14846
  {
14627
14847
  label: "Show All Trace Lengths",
@@ -14633,7 +14853,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14633
14853
  }
14634
14854
  }
14635
14855
  ),
14636
- /* @__PURE__ */ jsx17(
14856
+ /* @__PURE__ */ jsx18(
14637
14857
  CheckboxMenuItem,
14638
14858
  {
14639
14859
  label: "Show Autorouting Animation",
@@ -14645,7 +14865,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14645
14865
  }
14646
14866
  }
14647
14867
  ),
14648
- /* @__PURE__ */ jsx17(
14868
+ /* @__PURE__ */ jsx18(
14649
14869
  CheckboxMenuItem,
14650
14870
  {
14651
14871
  label: "Show DRC Errors",
@@ -14655,7 +14875,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14655
14875
  }
14656
14876
  }
14657
14877
  ),
14658
- /* @__PURE__ */ jsx17(
14878
+ /* @__PURE__ */ jsx18(
14659
14879
  CheckboxMenuItem,
14660
14880
  {
14661
14881
  label: "Show Copper Pours",
@@ -14667,7 +14887,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14667
14887
  }
14668
14888
  }
14669
14889
  ),
14670
- /* @__PURE__ */ jsx17(
14890
+ /* @__PURE__ */ jsx18(
14671
14891
  CheckboxMenuItem,
14672
14892
  {
14673
14893
  label: "Show Solder Mask",
@@ -14677,7 +14897,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14677
14897
  }
14678
14898
  }
14679
14899
  ),
14680
- /* @__PURE__ */ jsx17(
14900
+ /* @__PURE__ */ jsx18(
14681
14901
  CheckboxMenuItem,
14682
14902
  {
14683
14903
  label: "Show Group Anchor Offsets",
@@ -14689,7 +14909,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14689
14909
  }
14690
14910
  }
14691
14911
  ),
14692
- /* @__PURE__ */ jsx17(
14912
+ /* @__PURE__ */ jsx18(
14693
14913
  CheckboxMenuItem,
14694
14914
  {
14695
14915
  label: "Show PCB Groups",
@@ -14699,8 +14919,8 @@ var ToolbarOverlay = ({ children, elements }) => {
14699
14919
  }
14700
14920
  }
14701
14921
  ),
14702
- viewSettings.is_showing_pcb_groups && /* @__PURE__ */ jsxs14("div", { style: { marginLeft: 16 }, children: [
14703
- /* @__PURE__ */ jsx17(
14922
+ viewSettings.is_showing_pcb_groups && /* @__PURE__ */ jsxs15("div", { style: { marginLeft: 16 }, children: [
14923
+ /* @__PURE__ */ jsx18(
14704
14924
  RadioMenuItem,
14705
14925
  {
14706
14926
  label: "Show All Groups",
@@ -14710,7 +14930,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14710
14930
  }
14711
14931
  }
14712
14932
  ),
14713
- /* @__PURE__ */ jsx17(
14933
+ /* @__PURE__ */ jsx18(
14714
14934
  RadioMenuItem,
14715
14935
  {
14716
14936
  label: "Show Named Groups",
@@ -14734,7 +14954,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14734
14954
  };
14735
14955
 
14736
14956
  // src/components/CanvasElementsRenderer.tsx
14737
- import { jsx as jsx18 } from "react/jsx-runtime";
14957
+ import { jsx as jsx19 } from "react/jsx-runtime";
14738
14958
  var CanvasElementsRenderer = (props) => {
14739
14959
  const { transform, elements } = props;
14740
14960
  const hoveredErrorId = useGlobalStore((state) => state.hovered_error_id);
@@ -14822,14 +15042,14 @@ var CanvasElementsRenderer = (props) => {
14822
15042
  },
14823
15043
  [connectivityMap]
14824
15044
  );
14825
- return /* @__PURE__ */ jsx18(
15045
+ return /* @__PURE__ */ jsx19(
14826
15046
  MouseElementTracker,
14827
15047
  {
14828
15048
  elements: elementsToRender,
14829
15049
  transform,
14830
15050
  primitives: primitivesWithoutInteractionMetadata,
14831
15051
  onMouseHoverOverPrimitives: onMouseOverPrimitives,
14832
- children: /* @__PURE__ */ jsx18(
15052
+ children: /* @__PURE__ */ jsx19(
14833
15053
  EditPlacementOverlay,
14834
15054
  {
14835
15055
  disabled: !props.allowEditing,
@@ -14838,7 +15058,7 @@ var CanvasElementsRenderer = (props) => {
14838
15058
  cancelPanDrag: props.cancelPanDrag,
14839
15059
  onCreateEditEvent: props.onCreateEditEvent,
14840
15060
  onModifyEditEvent: props.onModifyEditEvent,
14841
- children: /* @__PURE__ */ jsx18(
15061
+ children: /* @__PURE__ */ jsx19(
14842
15062
  EditTraceHintOverlay,
14843
15063
  {
14844
15064
  disabled: !props.allowEditing,
@@ -14847,29 +15067,29 @@ var CanvasElementsRenderer = (props) => {
14847
15067
  cancelPanDrag: props.cancelPanDrag,
14848
15068
  onCreateEditEvent: props.onCreateEditEvent,
14849
15069
  onModifyEditEvent: props.onModifyEditEvent,
14850
- children: /* @__PURE__ */ jsx18(
15070
+ children: /* @__PURE__ */ jsx19(
14851
15071
  DimensionOverlay,
14852
15072
  {
14853
15073
  transform,
14854
15074
  focusOnHover: props.focusOnHover,
14855
15075
  primitives: primitivesWithoutInteractionMetadata,
14856
- children: /* @__PURE__ */ jsx18(ToolbarOverlay, { elements, children: /* @__PURE__ */ jsx18(ErrorOverlay, { transform, elements, children: /* @__PURE__ */ jsx18(RatsNestOverlay, { transform, soup: elements, children: /* @__PURE__ */ jsx18(
15076
+ children: /* @__PURE__ */ jsx19(ToolbarOverlay, { elements, children: /* @__PURE__ */ jsx19(ErrorOverlay, { transform, elements, children: /* @__PURE__ */ jsx19(RatsNestOverlay, { transform, soup: elements, children: /* @__PURE__ */ jsx19(
14857
15077
  PcbGroupOverlay,
14858
15078
  {
14859
15079
  transform,
14860
15080
  elements,
14861
15081
  hoveredComponentIds,
14862
- children: /* @__PURE__ */ jsx18(
15082
+ children: /* @__PURE__ */ jsx19(
14863
15083
  DebugGraphicsOverlay,
14864
15084
  {
14865
15085
  transform,
14866
15086
  debugGraphics: props.debugGraphics,
14867
- children: /* @__PURE__ */ jsx18(
15087
+ children: /* @__PURE__ */ jsx19(
14868
15088
  WarningGraphicsOverlay,
14869
15089
  {
14870
15090
  transform,
14871
15091
  elements,
14872
- children: /* @__PURE__ */ jsx18(
15092
+ children: /* @__PURE__ */ jsx19(
14873
15093
  CanvasPrimitiveRenderer,
14874
15094
  {
14875
15095
  transform,
@@ -14938,7 +15158,7 @@ var calculateCircuitJsonKey = (circuitJson) => {
14938
15158
  };
14939
15159
 
14940
15160
  // src/PCBViewer.tsx
14941
- import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
15161
+ import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
14942
15162
  var defaultTransform = compose7(translate11(400, 300), scale5(40, -40));
14943
15163
  var PCBViewer = ({
14944
15164
  circuitJson,
@@ -15032,20 +15252,20 @@ var PCBViewer = ({
15032
15252
  }),
15033
15253
  [initialState, disablePcbGroups]
15034
15254
  );
15035
- return /* @__PURE__ */ jsxs15(
15255
+ return /* @__PURE__ */ jsxs16(
15036
15256
  "div",
15037
15257
  {
15038
15258
  ref: transformRef,
15039
15259
  style: { position: "relative" },
15040
15260
  onContextMenu: (event) => event.preventDefault(),
15041
15261
  children: [
15042
- /* @__PURE__ */ jsx19("div", { ref, children: /* @__PURE__ */ jsxs15(
15262
+ /* @__PURE__ */ jsx20("div", { ref, children: /* @__PURE__ */ jsxs16(
15043
15263
  ContextProviders,
15044
15264
  {
15045
15265
  initialState: mergedInitialState,
15046
15266
  disablePcbGroups,
15047
15267
  children: [
15048
- /* @__PURE__ */ jsx19(
15268
+ /* @__PURE__ */ jsx20(
15049
15269
  CanvasElementsRenderer,
15050
15270
  {
15051
15271
  transform,
@@ -15070,11 +15290,11 @@ var PCBViewer = ({
15070
15290
  },
15071
15291
  refDimensions.width
15072
15292
  ),
15073
- /* @__PURE__ */ jsx19(ToastContainer, {})
15293
+ /* @__PURE__ */ jsx20(ToastContainer, {})
15074
15294
  ]
15075
15295
  }
15076
15296
  ) }),
15077
- clickToInteractEnabled && !isInteractionEnabled && /* @__PURE__ */ jsx19(
15297
+ clickToInteractEnabled && !isInteractionEnabled && /* @__PURE__ */ jsx20(
15078
15298
  "div",
15079
15299
  {
15080
15300
  onClick: () => {
@@ -15111,7 +15331,7 @@ var PCBViewer = ({
15111
15331
  justifyContent: "center",
15112
15332
  touchAction: "pan-x pan-y pinch-zoom"
15113
15333
  },
15114
- children: /* @__PURE__ */ jsx19(
15334
+ children: /* @__PURE__ */ jsx20(
15115
15335
  "div",
15116
15336
  {
15117
15337
  style: {