@tscircuit/pcb-viewer 1.11.293 → 1.11.294

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 applyToPoint16, inverse as inverse5 } from "transformation-matrix";
12376
+ import { applyToPoint as applyToPoint14, 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";
@@ -12650,7 +12650,13 @@ var ElementOverlayBox = ({
12650
12650
  )) });
12651
12651
  };
12652
12652
 
12653
- // src/components/AnchorOffsetOverlay/Board/index.tsx
12653
+ // src/components/AnchorOffsetOverlay/common/guards.ts
12654
+ var isPcbComponent = (element) => element?.type === "pcb_component";
12655
+ var isPcbGroup = (element) => element?.type === "pcb_group";
12656
+ var isPcbPanel = (element) => element?.type === "pcb_panel";
12657
+ var isPcbBoard = (element) => element?.type === "pcb_board";
12658
+
12659
+ // src/components/AnchorOffsetOverlay/AnchorOffsetOverlay.tsx
12654
12660
  import { applyToPoint as applyToPoint12 } from "transformation-matrix";
12655
12661
 
12656
12662
  // src/components/AnchorOffsetOverlay/common/constants.ts
@@ -12676,67 +12682,15 @@ var COLORS = {
12676
12682
  LABEL_TEXT: "white"
12677
12683
  };
12678
12684
 
12679
- // src/components/AnchorOffsetOverlay/common/guards.ts
12680
- var isPcbComponent = (element) => element?.type === "pcb_component";
12681
- var isPcbGroup = (element) => element?.type === "pcb_group";
12682
- var isPcbPanel = (element) => element?.type === "pcb_panel";
12683
- var isPcbBoard = (element) => element?.type === "pcb_board";
12684
-
12685
- // src/components/AnchorOffsetOverlay/Board/index.tsx
12685
+ // src/components/AnchorOffsetOverlay/AnchorOffsetOverlay.tsx
12686
12686
  import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
12687
- var BoardAnchorOffsetOverlay = ({
12688
- elements,
12689
- highlightedPrimitives,
12687
+ var AnchorOffsetOverlay = ({
12688
+ targets,
12690
12689
  transform,
12691
12690
  containerWidth,
12692
12691
  containerHeight
12693
12692
  }) => {
12694
- const boards = elements.filter((el) => isPcbBoard(el));
12695
- const components = elements.filter(
12696
- (el) => isPcbComponent(el)
12697
- );
12698
- const groups = elements.filter((el) => isPcbGroup(el));
12699
- const hoveredComponentIds = highlightedPrimitives.map((primitive) => {
12700
- if (isPcbComponent(primitive._parent_pcb_component)) {
12701
- return primitive._parent_pcb_component.pcb_component_id;
12702
- }
12703
- if (isPcbComponent(primitive._element)) {
12704
- return primitive._element.pcb_component_id;
12705
- }
12706
- return null;
12707
- }).filter((id) => Boolean(id));
12708
- const hoveredGroupIds = /* @__PURE__ */ new Set();
12709
- hoveredComponentIds.forEach((componentId) => {
12710
- const component = components.find((c) => c.pcb_component_id === componentId);
12711
- if (component?.pcb_group_id) {
12712
- hoveredGroupIds.add(component.pcb_group_id);
12713
- }
12714
- });
12715
- const isShowingAnchorOffsets = useGlobalStore(
12716
- (state) => state.is_showing_group_anchor_offsets
12717
- );
12718
- if (!isShowingAnchorOffsets && hoveredComponentIds.length === 0) {
12719
- return null;
12720
- }
12721
- const componentTargets = components.map((component) => {
12722
- const boardId = component.positioned_relative_to_pcb_board_id;
12723
- if (!boardId) return null;
12724
- const board = boards.find((b) => b.pcb_board_id === boardId);
12725
- return board ? { component, board, type: "component" } : null;
12726
- }).filter(
12727
- (target) => Boolean(target)
12728
- );
12729
- const groupTargets = groups.map((group) => {
12730
- const boardId = group.positioned_relative_to_pcb_board_id;
12731
- if (!boardId || !group.center) return null;
12732
- const board = boards.find((b) => b.pcb_board_id === boardId);
12733
- return board ? { group, board, type: "group" } : null;
12734
- }).filter(
12735
- (target) => Boolean(target)
12736
- );
12737
- const targets = [...componentTargets, ...groupTargets];
12738
12693
  if (targets.length === 0) return null;
12739
- const shouldShowAllTargets = hoveredComponentIds.length === 0;
12740
12694
  const labelStyle = {
12741
12695
  color: COLORS.LABEL_TEXT,
12742
12696
  mixBlendMode: "difference",
@@ -12745,15 +12699,13 @@ var BoardAnchorOffsetOverlay = ({
12745
12699
  fontFamily: "monospace",
12746
12700
  fontWeight: "bold"
12747
12701
  };
12748
- const targetEntries = targets.filter((target) => {
12749
- if (target.type === "component") {
12750
- return shouldShowAllTargets || hoveredComponentIds.includes(target.component.pcb_component_id);
12751
- } else {
12752
- return shouldShowAllTargets || hoveredGroupIds.has(target.group.pcb_group_id);
12702
+ const anchorScreens = /* @__PURE__ */ new Map();
12703
+ targets.forEach((target) => {
12704
+ if (!anchorScreens.has(target.anchor_id)) {
12705
+ const screenPoint = applyToPoint12(transform, target.anchor);
12706
+ anchorScreens.set(target.anchor_id, screenPoint);
12753
12707
  }
12754
12708
  });
12755
- if (targetEntries.length === 0) return null;
12756
- const boardAnchorScreens = /* @__PURE__ */ new Map();
12757
12709
  return /* @__PURE__ */ jsx12(
12758
12710
  "div",
12759
12711
  {
@@ -12779,33 +12731,11 @@ var BoardAnchorOffsetOverlay = ({
12779
12731
  width: containerWidth,
12780
12732
  height: containerHeight,
12781
12733
  children: [
12782
- targetEntries.map((target) => {
12783
- const anchorPosition = target.board.center;
12784
- const anchorKey = target.board.pcb_board_id;
12785
- let targetCenter;
12786
- let targetId;
12787
- let displayOffsetX;
12788
- let displayOffsetY;
12789
- if (target.type === "component") {
12790
- targetCenter = target.component.center;
12791
- targetId = target.component.pcb_component_id;
12792
- displayOffsetX = target.component.display_offset_x;
12793
- displayOffsetY = target.component.display_offset_y;
12794
- } else {
12795
- if (!target.group.center) return null;
12796
- targetCenter = {
12797
- x: target.group.anchor_position?.x ?? target.group.center.x,
12798
- y: target.group.anchor_position?.y ?? target.group.center.y
12799
- };
12800
- targetId = target.group.pcb_group_id;
12801
- displayOffsetX = target.group.display_offset_x;
12802
- displayOffsetY = target.group.display_offset_y;
12803
- }
12804
- if (!boardAnchorScreens.has(anchorKey)) {
12805
- const screenPoint = applyToPoint12(transform, anchorPosition);
12806
- boardAnchorScreens.set(anchorKey, screenPoint);
12807
- }
12808
- const anchorMarkerScreen = boardAnchorScreens.get(anchorKey);
12734
+ targets.map((target) => {
12735
+ const anchorPosition = target.anchor;
12736
+ const anchorKey = target.anchor_id;
12737
+ const targetCenter = target.target;
12738
+ const anchorMarkerScreen = anchorScreens.get(anchorKey);
12809
12739
  const targetScreen = applyToPoint12(transform, targetCenter);
12810
12740
  const offsetX = targetCenter.x - anchorPosition.x;
12811
12741
  const offsetY = targetCenter.y - anchorPosition.y;
@@ -12817,8 +12747,8 @@ var BoardAnchorOffsetOverlay = ({
12817
12747
  const yLabelOffset = isTargetRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
12818
12748
  const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
12819
12749
  const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
12820
- const xLabelText = `${displayOffsetX ?? offsetX.toFixed(2)}mm`;
12821
- const yLabelText = `${displayOffsetY ?? offsetY.toFixed(2)}mm`;
12750
+ const xLabelText = `${target.display_offset_x ?? offsetX.toFixed(2)}mm`;
12751
+ const yLabelText = `${target.display_offset_y ?? offsetY.toFixed(2)}mm`;
12822
12752
  return /* @__PURE__ */ jsxs9("g", { children: [
12823
12753
  /* @__PURE__ */ jsx12(
12824
12754
  "line",
@@ -12844,7 +12774,7 @@ var BoardAnchorOffsetOverlay = ({
12844
12774
  strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
12845
12775
  }
12846
12776
  ),
12847
- target.type === "component" ? /* @__PURE__ */ jsx12(
12777
+ target.type === "component" || target.type === "board" ? /* @__PURE__ */ jsx12(
12848
12778
  "circle",
12849
12779
  {
12850
12780
  cx: targetScreen.x,
@@ -12854,30 +12784,33 @@ var BoardAnchorOffsetOverlay = ({
12854
12784
  stroke: COLORS.COMPONENT_MARKER_STROKE,
12855
12785
  strokeWidth: 1
12856
12786
  }
12857
- ) : /* @__PURE__ */ jsxs9(Fragment5, { children: [
12858
- /* @__PURE__ */ jsx12(
12859
- "line",
12860
- {
12861
- x1: targetScreen.x - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12862
- y1: targetScreen.y,
12863
- x2: targetScreen.x + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12864
- y2: targetScreen.y,
12865
- stroke: COLORS.OFFSET_LINE,
12866
- strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
12867
- }
12868
- ),
12869
- /* @__PURE__ */ jsx12(
12870
- "line",
12871
- {
12872
- x1: targetScreen.x,
12873
- y1: targetScreen.y - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12874
- x2: targetScreen.x,
12875
- y2: targetScreen.y + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12876
- stroke: COLORS.OFFSET_LINE,
12877
- strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
12878
- }
12879
- )
12880
- ] }),
12787
+ ) : (
12788
+ // assumes "group"
12789
+ /* @__PURE__ */ jsxs9(Fragment5, { children: [
12790
+ /* @__PURE__ */ jsx12(
12791
+ "line",
12792
+ {
12793
+ x1: targetScreen.x - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12794
+ y1: targetScreen.y,
12795
+ x2: targetScreen.x + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12796
+ y2: targetScreen.y,
12797
+ stroke: COLORS.OFFSET_LINE,
12798
+ strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
12799
+ }
12800
+ ),
12801
+ /* @__PURE__ */ jsx12(
12802
+ "line",
12803
+ {
12804
+ x1: targetScreen.x,
12805
+ y1: targetScreen.y - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12806
+ x2: targetScreen.x,
12807
+ y2: targetScreen.y + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12808
+ stroke: COLORS.OFFSET_LINE,
12809
+ strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
12810
+ }
12811
+ )
12812
+ ] })
12813
+ ),
12881
12814
  shouldShowXLabel && /* @__PURE__ */ jsx12(
12882
12815
  "foreignObject",
12883
12816
  {
@@ -12914,34 +12847,32 @@ var BoardAnchorOffsetOverlay = ({
12914
12847
  )
12915
12848
  }
12916
12849
  )
12917
- ] }, `${target.board.pcb_board_id}-${targetId}-${target.type}`);
12850
+ ] }, target.id);
12918
12851
  }),
12919
- Array.from(boardAnchorScreens.entries()).map(
12920
- ([boardId, anchorScreen]) => /* @__PURE__ */ jsxs9("g", { children: [
12921
- /* @__PURE__ */ jsx12(
12922
- "line",
12923
- {
12924
- x1: anchorScreen.x - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12925
- y1: anchorScreen.y,
12926
- x2: anchorScreen.x + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12927
- y2: anchorScreen.y,
12928
- stroke: COLORS.OFFSET_LINE,
12929
- strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
12930
- }
12931
- ),
12932
- /* @__PURE__ */ jsx12(
12933
- "line",
12934
- {
12935
- x1: anchorScreen.x,
12936
- y1: anchorScreen.y - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12937
- x2: anchorScreen.x,
12938
- y2: anchorScreen.y + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12939
- stroke: COLORS.OFFSET_LINE,
12940
- strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
12941
- }
12942
- )
12943
- ] }, `anchor-${boardId}`)
12944
- )
12852
+ Array.from(anchorScreens.entries()).map(([anchorId, anchorScreen]) => /* @__PURE__ */ jsxs9("g", { children: [
12853
+ /* @__PURE__ */ jsx12(
12854
+ "line",
12855
+ {
12856
+ x1: anchorScreen.x - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12857
+ y1: anchorScreen.y,
12858
+ x2: anchorScreen.x + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12859
+ y2: anchorScreen.y,
12860
+ stroke: COLORS.OFFSET_LINE,
12861
+ strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
12862
+ }
12863
+ ),
12864
+ /* @__PURE__ */ jsx12(
12865
+ "line",
12866
+ {
12867
+ x1: anchorScreen.x,
12868
+ y1: anchorScreen.y - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12869
+ x2: anchorScreen.x,
12870
+ y2: anchorScreen.y + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
12871
+ stroke: COLORS.OFFSET_LINE,
12872
+ strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
12873
+ }
12874
+ )
12875
+ ] }, `anchor-${anchorId}`))
12945
12876
  ]
12946
12877
  }
12947
12878
  )
@@ -12949,9 +12880,107 @@ var BoardAnchorOffsetOverlay = ({
12949
12880
  );
12950
12881
  };
12951
12882
 
12952
- // src/components/AnchorOffsetOverlay/Group/index.tsx
12953
- import { applyToPoint as applyToPoint13 } from "transformation-matrix";
12954
- import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
12883
+ // src/components/AnchorOffsetOverlay/BoardAnchorOffsetOverlay.tsx
12884
+ import { jsx as jsx13 } from "react/jsx-runtime";
12885
+ var BoardAnchorOffsetOverlay = ({
12886
+ elements,
12887
+ highlightedPrimitives,
12888
+ transform,
12889
+ containerWidth,
12890
+ containerHeight
12891
+ }) => {
12892
+ const boards = elements.filter((el) => isPcbBoard(el));
12893
+ const components = elements.filter(
12894
+ (el) => isPcbComponent(el)
12895
+ );
12896
+ const groups = elements.filter((el) => isPcbGroup(el));
12897
+ const hoveredComponentIds = highlightedPrimitives.map((primitive) => {
12898
+ if (isPcbComponent(primitive._parent_pcb_component)) {
12899
+ return primitive._parent_pcb_component.pcb_component_id;
12900
+ }
12901
+ if (isPcbComponent(primitive._element)) {
12902
+ return primitive._element.pcb_component_id;
12903
+ }
12904
+ return null;
12905
+ }).filter((id) => Boolean(id));
12906
+ const hoveredGroupIds = /* @__PURE__ */ new Set();
12907
+ hoveredComponentIds.forEach((componentId) => {
12908
+ const component = components.find((c) => c.pcb_component_id === componentId);
12909
+ if (component?.pcb_group_id) {
12910
+ hoveredGroupIds.add(component.pcb_group_id);
12911
+ }
12912
+ });
12913
+ const isShowingAnchorOffsets = useGlobalStore(
12914
+ (state) => state.is_showing_group_anchor_offsets
12915
+ );
12916
+ if (!isShowingAnchorOffsets && hoveredComponentIds.length === 0) {
12917
+ return null;
12918
+ }
12919
+ const componentTargets = components.map((component) => {
12920
+ const boardId = component.positioned_relative_to_pcb_board_id;
12921
+ if (!boardId) return null;
12922
+ const board = boards.find((b) => b.pcb_board_id === boardId);
12923
+ return board ? { component, board, type: "component" } : null;
12924
+ }).filter(
12925
+ (target) => Boolean(target)
12926
+ );
12927
+ const groupTargets = groups.map((group) => {
12928
+ const boardId = group.positioned_relative_to_pcb_board_id;
12929
+ if (!boardId || !group.center) return null;
12930
+ const board = boards.find((b) => b.pcb_board_id === boardId);
12931
+ return board ? { group, board, type: "group" } : null;
12932
+ }).filter(
12933
+ (target) => Boolean(target)
12934
+ );
12935
+ const targets = [...componentTargets, ...groupTargets];
12936
+ if (targets.length === 0) return null;
12937
+ const shouldShowAllTargets = hoveredComponentIds.length === 0;
12938
+ const targetEntries = targets.filter((target) => {
12939
+ if (target.type === "component") {
12940
+ return shouldShowAllTargets || hoveredComponentIds.includes(target.component.pcb_component_id);
12941
+ } else {
12942
+ return shouldShowAllTargets || hoveredGroupIds.has(target.group.pcb_group_id);
12943
+ }
12944
+ });
12945
+ if (targetEntries.length === 0) return null;
12946
+ const sharedTargets = targetEntries.map((target) => {
12947
+ if (target.type === "component") {
12948
+ return {
12949
+ id: `${target.board.pcb_board_id}-${target.component.pcb_component_id}-${target.type}`,
12950
+ anchor: target.board.center,
12951
+ anchor_id: target.board.pcb_board_id,
12952
+ target: target.component.center,
12953
+ type: "component",
12954
+ display_offset_x: target.component.display_offset_x,
12955
+ display_offset_y: target.component.display_offset_y
12956
+ };
12957
+ }
12958
+ return {
12959
+ id: `${target.board.pcb_board_id}-${target.group.pcb_group_id}-${target.type}`,
12960
+ anchor: target.board.center,
12961
+ anchor_id: target.board.pcb_board_id,
12962
+ target: {
12963
+ x: target.group.anchor_position?.x ?? target.group.center.x,
12964
+ y: target.group.anchor_position?.y ?? target.group.center.y
12965
+ },
12966
+ type: "group",
12967
+ display_offset_x: target.group.display_offset_x,
12968
+ display_offset_y: target.group.display_offset_y
12969
+ };
12970
+ }).filter((t) => Boolean(t));
12971
+ return /* @__PURE__ */ jsx13(
12972
+ AnchorOffsetOverlay,
12973
+ {
12974
+ targets: sharedTargets,
12975
+ transform,
12976
+ containerWidth,
12977
+ containerHeight
12978
+ }
12979
+ );
12980
+ };
12981
+
12982
+ // src/components/AnchorOffsetOverlay/GroupAnchorOffsetOverlay.tsx
12983
+ import { jsx as jsx14 } from "react/jsx-runtime";
12955
12984
  var GroupAnchorOffsetOverlay = ({
12956
12985
  elements,
12957
12986
  highlightedPrimitives,
@@ -13033,14 +13062,6 @@ var GroupAnchorOffsetOverlay = ({
13033
13062
  const targets = [...componentTargets, ...groupTargets];
13034
13063
  if (targets.length === 0) return null;
13035
13064
  const shouldShowAllTargets = hoveredComponentIds.length === 0;
13036
- const labelStyle = {
13037
- color: COLORS.LABEL_TEXT,
13038
- mixBlendMode: "difference",
13039
- pointerEvents: "none",
13040
- fontSize: VISUAL_CONFIG.LABEL_FONT_SIZE,
13041
- fontFamily: "monospace",
13042
- fontWeight: "bold"
13043
- };
13044
13065
  const targetEntries = targets.filter((target) => {
13045
13066
  if (target.type === "component") {
13046
13067
  return shouldShowAllTargets || hoveredComponentIds.includes(target.component.pcb_component_id);
@@ -13049,218 +13070,46 @@ var GroupAnchorOffsetOverlay = ({
13049
13070
  }
13050
13071
  });
13051
13072
  if (targetEntries.length === 0) return null;
13052
- const groupAnchorScreens = /* @__PURE__ */ new Map();
13053
- targetEntries.forEach((target) => {
13054
- if (!target.parentGroup.anchor_position) return;
13055
- const anchorScreen = applyToPoint13(
13056
- transform,
13057
- target.parentGroup.anchor_position
13058
- );
13059
- groupAnchorScreens.set(target.parentGroup.pcb_group_id, anchorScreen);
13060
- });
13061
- return /* @__PURE__ */ jsx13(
13062
- "div",
13073
+ const sharedTargets = targetEntries.map((target) => {
13074
+ const anchor = target.parentGroup.anchor_position;
13075
+ if (!anchor) return null;
13076
+ if (target.type === "component") {
13077
+ if (!target.component.center) return null;
13078
+ return {
13079
+ id: `${target.parentGroup.pcb_group_id}-${target.component.pcb_component_id}-${target.type}`,
13080
+ anchor,
13081
+ anchor_id: target.parentGroup.pcb_group_id,
13082
+ target: target.component.center,
13083
+ type: "component",
13084
+ display_offset_x: target.component.display_offset_x,
13085
+ display_offset_y: target.component.display_offset_y
13086
+ };
13087
+ }
13088
+ if (!target.group.center) return null;
13089
+ return {
13090
+ id: `${target.parentGroup.pcb_group_id}-${target.group.pcb_group_id}-${target.type}`,
13091
+ anchor,
13092
+ anchor_id: target.parentGroup.pcb_group_id,
13093
+ target: target.group.center,
13094
+ type: "group",
13095
+ display_offset_x: target.group.display_offset_x,
13096
+ display_offset_y: target.group.display_offset_y
13097
+ };
13098
+ }).filter((t) => Boolean(t));
13099
+ return /* @__PURE__ */ jsx14(
13100
+ AnchorOffsetOverlay,
13063
13101
  {
13064
- style: {
13065
- position: "absolute",
13066
- left: 0,
13067
- top: 0,
13068
- width: containerWidth,
13069
- height: containerHeight,
13070
- overflow: "hidden",
13071
- pointerEvents: "none",
13072
- zIndex: zIndexMap.dimensionOverlay
13073
- },
13074
- children: /* @__PURE__ */ jsxs10(
13075
- "svg",
13076
- {
13077
- style: {
13078
- position: "absolute",
13079
- left: 0,
13080
- top: 0,
13081
- pointerEvents: "none"
13082
- },
13083
- width: containerWidth,
13084
- height: containerHeight,
13085
- children: [
13086
- targetEntries.map((target) => {
13087
- const anchor = target.parentGroup.anchor_position;
13088
- if (!anchor) return null;
13089
- const anchorMarkerPosition = { x: anchor.x, y: anchor.y };
13090
- let targetCenter = null;
13091
- let targetId;
13092
- let displayOffsetX;
13093
- let displayOffsetY;
13094
- if (target.type === "component") {
13095
- const center = target.component.center;
13096
- if (!center) return null;
13097
- targetCenter = { x: center.x, y: center.y };
13098
- targetId = target.component.pcb_component_id;
13099
- displayOffsetX = target.component.display_offset_x;
13100
- displayOffsetY = target.component.display_offset_y;
13101
- } else {
13102
- if (!target.group.center) return null;
13103
- targetCenter = {
13104
- x: target.group.center.x,
13105
- y: target.group.center.y
13106
- };
13107
- targetId = target.group.pcb_group_id;
13108
- displayOffsetX = target.group.display_offset_x;
13109
- displayOffsetY = target.group.display_offset_y;
13110
- }
13111
- const offsetX = targetCenter.x - anchorMarkerPosition.x;
13112
- const offsetY = targetCenter.y - anchorMarkerPosition.y;
13113
- const anchorMarkerScreen = applyToPoint13(
13114
- transform,
13115
- anchorMarkerPosition
13116
- );
13117
- const targetScreen = applyToPoint13(transform, targetCenter);
13118
- const xLineLength = Math.abs(targetScreen.x - anchorMarkerScreen.x);
13119
- const yLineLength = Math.abs(targetScreen.y - anchorMarkerScreen.y);
13120
- const isTargetAboveAnchor = targetScreen.y < anchorMarkerScreen.y;
13121
- const isTargetRightOfAnchor = targetScreen.x > anchorMarkerScreen.x;
13122
- const xLabelOffset = isTargetAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
13123
- const yLabelOffset = isTargetRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
13124
- const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
13125
- const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
13126
- const xLabelText = displayOffsetX ? displayOffsetX : `${offsetX.toFixed(2)}mm`;
13127
- const yLabelText = displayOffsetY ? displayOffsetY : `${offsetY.toFixed(2)}mm`;
13128
- return /* @__PURE__ */ jsxs10(
13129
- "g",
13130
- {
13131
- children: [
13132
- /* @__PURE__ */ jsx13(
13133
- "line",
13134
- {
13135
- x1: anchorMarkerScreen.x,
13136
- y1: anchorMarkerScreen.y,
13137
- x2: targetScreen.x,
13138
- y2: anchorMarkerScreen.y,
13139
- stroke: COLORS.OFFSET_LINE,
13140
- strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
13141
- strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
13142
- }
13143
- ),
13144
- /* @__PURE__ */ jsx13(
13145
- "line",
13146
- {
13147
- x1: targetScreen.x,
13148
- y1: anchorMarkerScreen.y,
13149
- x2: targetScreen.x,
13150
- y2: targetScreen.y,
13151
- stroke: COLORS.OFFSET_LINE,
13152
- strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
13153
- strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
13154
- }
13155
- ),
13156
- target.type === "component" ? /* @__PURE__ */ jsx13(
13157
- "circle",
13158
- {
13159
- cx: targetScreen.x,
13160
- cy: targetScreen.y,
13161
- r: VISUAL_CONFIG.COMPONENT_MARKER_RADIUS,
13162
- fill: COLORS.COMPONENT_MARKER_FILL,
13163
- stroke: COLORS.COMPONENT_MARKER_STROKE,
13164
- strokeWidth: 1
13165
- }
13166
- ) : /* @__PURE__ */ jsxs10(Fragment6, { children: [
13167
- /* @__PURE__ */ jsx13(
13168
- "line",
13169
- {
13170
- x1: targetScreen.x - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13171
- y1: targetScreen.y,
13172
- x2: targetScreen.x + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13173
- y2: targetScreen.y,
13174
- stroke: COLORS.OFFSET_LINE,
13175
- strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
13176
- }
13177
- ),
13178
- /* @__PURE__ */ jsx13(
13179
- "line",
13180
- {
13181
- x1: targetScreen.x,
13182
- y1: targetScreen.y - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13183
- x2: targetScreen.x,
13184
- y2: targetScreen.y + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13185
- stroke: COLORS.OFFSET_LINE,
13186
- strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
13187
- }
13188
- )
13189
- ] }),
13190
- shouldShowXLabel && /* @__PURE__ */ jsx13(
13191
- "foreignObject",
13192
- {
13193
- x: Math.min(anchorMarkerScreen.x, targetScreen.x),
13194
- y: anchorMarkerScreen.y + xLabelOffset,
13195
- width: Math.abs(targetScreen.x - anchorMarkerScreen.x),
13196
- height: 20,
13197
- style: { overflow: "visible" },
13198
- children: /* @__PURE__ */ jsx13("div", { style: { ...labelStyle, textAlign: "center" }, children: xLabelText })
13199
- }
13200
- ),
13201
- shouldShowYLabel && /* @__PURE__ */ jsx13(
13202
- "foreignObject",
13203
- {
13204
- x: targetScreen.x + yLabelOffset,
13205
- y: Math.min(anchorMarkerScreen.y, targetScreen.y),
13206
- width: 20,
13207
- height: Math.abs(targetScreen.y - anchorMarkerScreen.y),
13208
- style: { overflow: "visible" },
13209
- children: /* @__PURE__ */ jsx13(
13210
- "div",
13211
- {
13212
- style: {
13213
- ...labelStyle,
13214
- display: "flex",
13215
- alignItems: "center",
13216
- height: "100%"
13217
- },
13218
- children: yLabelText
13219
- }
13220
- )
13221
- }
13222
- )
13223
- ]
13224
- },
13225
- `${target.parentGroup.pcb_group_id}-${targetId}-${target.type}`
13226
- );
13227
- }),
13228
- Array.from(groupAnchorScreens.entries()).map(
13229
- ([groupId, anchorScreen]) => /* @__PURE__ */ jsxs10("g", { children: [
13230
- /* @__PURE__ */ jsx13(
13231
- "line",
13232
- {
13233
- x1: anchorScreen.x - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13234
- y1: anchorScreen.y,
13235
- x2: anchorScreen.x + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13236
- y2: anchorScreen.y,
13237
- stroke: COLORS.OFFSET_LINE,
13238
- strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
13239
- }
13240
- ),
13241
- /* @__PURE__ */ jsx13(
13242
- "line",
13243
- {
13244
- x1: anchorScreen.x,
13245
- y1: anchorScreen.y - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13246
- x2: anchorScreen.x,
13247
- y2: anchorScreen.y + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13248
- stroke: COLORS.OFFSET_LINE,
13249
- strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
13250
- }
13251
- )
13252
- ] }, `anchor-${groupId}`)
13253
- )
13254
- ]
13255
- }
13256
- )
13102
+ targets: sharedTargets,
13103
+ transform,
13104
+ containerWidth,
13105
+ containerHeight
13257
13106
  }
13258
13107
  );
13259
13108
  };
13260
13109
 
13261
- // src/components/AnchorOffsetOverlay/ComponentBoundingBox/index.tsx
13262
- import { applyToPoint as applyToPoint14 } from "transformation-matrix";
13263
- import { Fragment as Fragment7, jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
13110
+ // src/components/AnchorOffsetOverlay/ComponentBoundingBoxOverlay.tsx
13111
+ import { applyToPoint as applyToPoint13 } from "transformation-matrix";
13112
+ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
13264
13113
  var calculateComponentBoundingBox = (component, elements) => {
13265
13114
  const componentId = component.pcb_component_id;
13266
13115
  const padsAndHoles = elements.filter(
@@ -13303,7 +13152,7 @@ var ComponentBoundingBoxOverlay = ({
13303
13152
  renderData.push({ component, bbox, group });
13304
13153
  }
13305
13154
  if (renderData.length === 0) return null;
13306
- return /* @__PURE__ */ jsx14(
13155
+ return /* @__PURE__ */ jsx15(
13307
13156
  "div",
13308
13157
  {
13309
13158
  style: {
@@ -13316,18 +13165,18 @@ var ComponentBoundingBoxOverlay = ({
13316
13165
  pointerEvents: "none",
13317
13166
  zIndex: zIndexMap.dimensionOverlay
13318
13167
  },
13319
- children: /* @__PURE__ */ jsx14(
13168
+ children: /* @__PURE__ */ jsx15(
13320
13169
  "svg",
13321
13170
  {
13322
13171
  style: { position: "absolute", left: 0, top: 0, pointerEvents: "none" },
13323
13172
  width: containerWidth,
13324
13173
  height: containerHeight,
13325
13174
  children: renderData.map(({ component, bbox, group }) => {
13326
- const topLeft = applyToPoint14(transform, {
13175
+ const topLeft = applyToPoint13(transform, {
13327
13176
  x: bbox.minX,
13328
13177
  y: bbox.maxY
13329
13178
  });
13330
- const bottomRight = applyToPoint14(transform, {
13179
+ const bottomRight = applyToPoint13(transform, {
13331
13180
  x: bbox.maxX,
13332
13181
  y: bbox.minY
13333
13182
  });
@@ -13341,38 +13190,9 @@ var ComponentBoundingBoxOverlay = ({
13341
13190
  x: (bbox.minX + bbox.maxX) / 2,
13342
13191
  y: (bbox.minY + bbox.maxY) / 2
13343
13192
  };
13344
- const componentCenterScreen = applyToPoint14(transform, componentCenter);
13345
- const groupAnchor = group?.anchor_position;
13346
- const groupAnchorScreen = groupAnchor ? applyToPoint14(transform, groupAnchor) : null;
13347
- const hasGroupOffset = group && groupAnchorScreen && (component.position_mode === "relative_to_group_anchor" || component.pcb_group_id);
13348
- let displayOffsetX = component.display_offset_x;
13349
- let displayOffsetY = component.display_offset_y;
13350
- if (!displayOffsetX && groupAnchor) {
13351
- const dx = componentCenter.x - groupAnchor.x;
13352
- displayOffsetX = `\u0394x: ${dx.toFixed(2)}mm`;
13353
- }
13354
- if (!displayOffsetY && groupAnchor) {
13355
- const dy = componentCenter.y - groupAnchor.y;
13356
- displayOffsetY = `\u0394y: ${dy.toFixed(2)}mm`;
13357
- }
13358
- const xLineLength = groupAnchorScreen ? Math.abs(componentCenterScreen.x - groupAnchorScreen.x) : 0;
13359
- const yLineLength = groupAnchorScreen ? Math.abs(componentCenterScreen.y - groupAnchorScreen.y) : 0;
13360
- const isTargetAboveAnchor = groupAnchorScreen ? componentCenterScreen.y < groupAnchorScreen.y : false;
13361
- const isTargetRightOfAnchor = groupAnchorScreen ? componentCenterScreen.x > groupAnchorScreen.x : false;
13362
- const xLabelOffset = isTargetAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
13363
- const yLabelOffset = isTargetRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
13364
- const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
13365
- const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
13366
- const labelStyle = {
13367
- color: COLORS.LABEL_TEXT,
13368
- mixBlendMode: "difference",
13369
- pointerEvents: "none",
13370
- fontSize: VISUAL_CONFIG.LABEL_FONT_SIZE,
13371
- fontFamily: "monospace",
13372
- fontWeight: "bold"
13373
- };
13374
- return /* @__PURE__ */ jsxs11("g", { children: [
13375
- /* @__PURE__ */ jsx14(
13193
+ const componentCenterScreen = applyToPoint13(transform, componentCenter);
13194
+ return /* @__PURE__ */ jsxs10("g", { children: [
13195
+ /* @__PURE__ */ jsx15(
13376
13196
  "rect",
13377
13197
  {
13378
13198
  x: screenBbox.x,
@@ -13385,7 +13205,7 @@ var ComponentBoundingBoxOverlay = ({
13385
13205
  strokeDasharray: "4,4"
13386
13206
  }
13387
13207
  ),
13388
- /* @__PURE__ */ jsx14(
13208
+ /* @__PURE__ */ jsx15(
13389
13209
  "line",
13390
13210
  {
13391
13211
  x1: componentCenterScreen.x - 6,
@@ -13396,7 +13216,7 @@ var ComponentBoundingBoxOverlay = ({
13396
13216
  strokeWidth: 1.5
13397
13217
  }
13398
13218
  ),
13399
- /* @__PURE__ */ jsx14(
13219
+ /* @__PURE__ */ jsx15(
13400
13220
  "line",
13401
13221
  {
13402
13222
  x1: componentCenterScreen.x,
@@ -13407,7 +13227,7 @@ var ComponentBoundingBoxOverlay = ({
13407
13227
  strokeWidth: 1.5
13408
13228
  }
13409
13229
  ),
13410
- /* @__PURE__ */ jsx14(
13230
+ /* @__PURE__ */ jsx15(
13411
13231
  "circle",
13412
13232
  {
13413
13233
  cx: componentCenterScreen.x,
@@ -13417,92 +13237,7 @@ var ComponentBoundingBoxOverlay = ({
13417
13237
  stroke: COLORS.COMPONENT_MARKER_STROKE,
13418
13238
  strokeWidth: 1
13419
13239
  }
13420
- ),
13421
- hasGroupOffset && groupAnchorScreen && /* @__PURE__ */ jsxs11(Fragment7, { children: [
13422
- /* @__PURE__ */ jsx14(
13423
- "line",
13424
- {
13425
- x1: groupAnchorScreen.x,
13426
- y1: groupAnchorScreen.y,
13427
- x2: componentCenterScreen.x,
13428
- y2: groupAnchorScreen.y,
13429
- stroke: COLORS.OFFSET_LINE,
13430
- strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
13431
- strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
13432
- }
13433
- ),
13434
- /* @__PURE__ */ jsx14(
13435
- "line",
13436
- {
13437
- x1: componentCenterScreen.x,
13438
- y1: groupAnchorScreen.y,
13439
- x2: componentCenterScreen.x,
13440
- y2: componentCenterScreen.y,
13441
- stroke: COLORS.OFFSET_LINE,
13442
- strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
13443
- strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
13444
- }
13445
- ),
13446
- /* @__PURE__ */ jsx14(
13447
- "line",
13448
- {
13449
- x1: groupAnchorScreen.x - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13450
- y1: groupAnchorScreen.y,
13451
- x2: groupAnchorScreen.x + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13452
- y2: groupAnchorScreen.y,
13453
- stroke: COLORS.OFFSET_LINE,
13454
- strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
13455
- }
13456
- ),
13457
- /* @__PURE__ */ jsx14(
13458
- "line",
13459
- {
13460
- x1: groupAnchorScreen.x,
13461
- y1: groupAnchorScreen.y - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13462
- x2: groupAnchorScreen.x,
13463
- y2: groupAnchorScreen.y + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13464
- stroke: COLORS.OFFSET_LINE,
13465
- strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
13466
- }
13467
- ),
13468
- shouldShowXLabel && /* @__PURE__ */ jsx14(
13469
- "foreignObject",
13470
- {
13471
- x: Math.min(groupAnchorScreen.x, componentCenterScreen.x),
13472
- y: groupAnchorScreen.y + xLabelOffset,
13473
- width: Math.abs(
13474
- componentCenterScreen.x - groupAnchorScreen.x
13475
- ),
13476
- height: 20,
13477
- style: { overflow: "visible" },
13478
- children: /* @__PURE__ */ jsx14("div", { style: { ...labelStyle, textAlign: "center" }, children: displayOffsetX })
13479
- }
13480
- ),
13481
- shouldShowYLabel && /* @__PURE__ */ jsx14(
13482
- "foreignObject",
13483
- {
13484
- x: componentCenterScreen.x + yLabelOffset,
13485
- y: Math.min(groupAnchorScreen.y, componentCenterScreen.y),
13486
- width: 20,
13487
- height: Math.abs(
13488
- componentCenterScreen.y - groupAnchorScreen.y
13489
- ),
13490
- style: { overflow: "visible" },
13491
- children: /* @__PURE__ */ jsx14(
13492
- "div",
13493
- {
13494
- style: {
13495
- ...labelStyle,
13496
- display: "flex",
13497
- alignItems: "center",
13498
- height: "100%"
13499
- },
13500
- children: displayOffsetY
13501
- }
13502
- )
13503
- }
13504
- )
13505
- ] })
13240
+ )
13506
13241
  ] }, component.pcb_component_id);
13507
13242
  })
13508
13243
  }
@@ -13511,9 +13246,8 @@ var ComponentBoundingBoxOverlay = ({
13511
13246
  );
13512
13247
  };
13513
13248
 
13514
- // src/components/AnchorOffsetOverlay/Panel/index.tsx
13515
- import { applyToPoint as applyToPoint15 } from "transformation-matrix";
13516
- import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
13249
+ // src/components/AnchorOffsetOverlay/PanelAnchorOffsetOverlay.tsx
13250
+ import { jsx as jsx16 } from "react/jsx-runtime";
13517
13251
  var PanelAnchorOffsetOverlay = ({
13518
13252
  elements,
13519
13253
  highlightedPrimitives,
@@ -13546,182 +13280,35 @@ var PanelAnchorOffsetOverlay = ({
13546
13280
  );
13547
13281
  if (boardTargets.length === 0) return null;
13548
13282
  const shouldShowAllTargets = hoveredBoardIds.length === 0;
13549
- const labelStyle = {
13550
- color: COLORS.LABEL_TEXT,
13551
- mixBlendMode: "difference",
13552
- pointerEvents: "none",
13553
- fontSize: VISUAL_CONFIG.LABEL_FONT_SIZE,
13554
- fontFamily: "monospace",
13555
- fontWeight: "bold"
13556
- };
13557
13283
  const targetEntries = boardTargets.filter((target) => {
13558
13284
  return shouldShowAllTargets || hoveredBoardIds.includes(target.board.pcb_board_id);
13559
13285
  });
13560
13286
  if (targetEntries.length === 0) return null;
13561
- const panelAnchorScreens = /* @__PURE__ */ new Map();
13562
- return /* @__PURE__ */ jsx15(
13563
- "div",
13287
+ const sharedTargets = targetEntries.map((target) => {
13288
+ if (!target.board.center) return null;
13289
+ return {
13290
+ id: `${target.panel.pcb_panel_id}-${target.board.pcb_board_id}-${target.type}`,
13291
+ anchor: target.panel.center,
13292
+ anchor_id: target.panel.pcb_panel_id,
13293
+ target: target.board.center,
13294
+ type: "board",
13295
+ display_offset_x: target.board.display_offset_x,
13296
+ display_offset_y: target.board.display_offset_y
13297
+ };
13298
+ }).filter((t) => Boolean(t));
13299
+ return /* @__PURE__ */ jsx16(
13300
+ AnchorOffsetOverlay,
13564
13301
  {
13565
- style: {
13566
- position: "absolute",
13567
- left: 0,
13568
- top: 0,
13569
- width: containerWidth,
13570
- height: containerHeight,
13571
- overflow: "hidden",
13572
- pointerEvents: "none",
13573
- zIndex: zIndexMap.dimensionOverlay
13574
- },
13575
- children: /* @__PURE__ */ jsxs12(
13576
- "svg",
13577
- {
13578
- style: {
13579
- position: "absolute",
13580
- left: 0,
13581
- top: 0,
13582
- pointerEvents: "none"
13583
- },
13584
- width: containerWidth,
13585
- height: containerHeight,
13586
- children: [
13587
- targetEntries.map((target) => {
13588
- const anchorPosition = target.panel.center;
13589
- const anchorKey = target.panel.pcb_panel_id;
13590
- let targetCenter;
13591
- let targetId;
13592
- let displayOffsetX;
13593
- let displayOffsetY;
13594
- targetCenter = target.board.center;
13595
- targetId = target.board.pcb_board_id;
13596
- displayOffsetX = target.board.display_offset_x;
13597
- displayOffsetY = target.board.display_offset_y;
13598
- if (!panelAnchorScreens.has(anchorKey)) {
13599
- const screenPoint = applyToPoint15(transform, anchorPosition);
13600
- panelAnchorScreens.set(anchorKey, screenPoint);
13601
- }
13602
- const anchorMarkerScreen = panelAnchorScreens.get(anchorKey);
13603
- const targetScreen = applyToPoint15(transform, targetCenter);
13604
- const offsetX = targetCenter.x - anchorPosition.x;
13605
- const offsetY = targetCenter.y - anchorPosition.y;
13606
- const xLineLength = Math.abs(targetScreen.x - anchorMarkerScreen.x);
13607
- const yLineLength = Math.abs(targetScreen.y - anchorMarkerScreen.y);
13608
- const isTargetAboveAnchor = targetScreen.y < anchorMarkerScreen.y;
13609
- const isTargetRightOfAnchor = targetScreen.x > anchorMarkerScreen.x;
13610
- const xLabelOffset = isTargetAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
13611
- const yLabelOffset = isTargetRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
13612
- const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
13613
- const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
13614
- const xLabelText = `${displayOffsetX ?? offsetX.toFixed(2)}mm`;
13615
- const yLabelText = `${displayOffsetY ?? offsetY.toFixed(2)}mm`;
13616
- return /* @__PURE__ */ jsxs12("g", { children: [
13617
- /* @__PURE__ */ jsx15(
13618
- "line",
13619
- {
13620
- x1: anchorMarkerScreen.x,
13621
- y1: anchorMarkerScreen.y,
13622
- x2: targetScreen.x,
13623
- y2: anchorMarkerScreen.y,
13624
- stroke: COLORS.OFFSET_LINE,
13625
- strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
13626
- strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
13627
- }
13628
- ),
13629
- /* @__PURE__ */ jsx15(
13630
- "line",
13631
- {
13632
- x1: targetScreen.x,
13633
- y1: anchorMarkerScreen.y,
13634
- x2: targetScreen.x,
13635
- y2: targetScreen.y,
13636
- stroke: COLORS.OFFSET_LINE,
13637
- strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
13638
- strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
13639
- }
13640
- ),
13641
- /* @__PURE__ */ jsx15(
13642
- "circle",
13643
- {
13644
- cx: targetScreen.x,
13645
- cy: targetScreen.y,
13646
- r: VISUAL_CONFIG.COMPONENT_MARKER_RADIUS,
13647
- fill: COLORS.COMPONENT_MARKER_FILL,
13648
- stroke: COLORS.COMPONENT_MARKER_STROKE,
13649
- strokeWidth: 1
13650
- }
13651
- ),
13652
- shouldShowXLabel && /* @__PURE__ */ jsx15(
13653
- "foreignObject",
13654
- {
13655
- x: Math.min(anchorMarkerScreen.x, targetScreen.x),
13656
- y: anchorMarkerScreen.y + xLabelOffset,
13657
- width: Math.abs(targetScreen.x - anchorMarkerScreen.x),
13658
- height: 20,
13659
- style: { overflow: "visible" },
13660
- children: /* @__PURE__ */ jsx15("div", { style: { ...labelStyle, textAlign: "center" }, children: xLabelText })
13661
- }
13662
- ),
13663
- shouldShowYLabel && /* @__PURE__ */ jsx15(
13664
- "foreignObject",
13665
- {
13666
- x: targetScreen.x + yLabelOffset,
13667
- y: Math.min(anchorMarkerScreen.y, targetScreen.y),
13668
- width: VISUAL_CONFIG.Y_LABEL_MIN_WIDTH,
13669
- height: Math.abs(targetScreen.y - anchorMarkerScreen.y),
13670
- style: { overflow: "visible" },
13671
- children: /* @__PURE__ */ jsx15(
13672
- "div",
13673
- {
13674
- style: {
13675
- ...labelStyle,
13676
- display: "flex",
13677
- alignItems: "center",
13678
- justifyContent: isTargetRightOfAnchor ? "flex-start" : "flex-end",
13679
- whiteSpace: "nowrap",
13680
- padding: "0 4px",
13681
- height: "100%"
13682
- },
13683
- children: yLabelText
13684
- }
13685
- )
13686
- }
13687
- )
13688
- ] }, `${target.panel.pcb_panel_id}-${targetId}-${target.type}`);
13689
- }),
13690
- Array.from(panelAnchorScreens.entries()).map(
13691
- ([panelId, anchorScreen]) => /* @__PURE__ */ jsxs12("g", { children: [
13692
- /* @__PURE__ */ jsx15(
13693
- "line",
13694
- {
13695
- x1: anchorScreen.x - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13696
- y1: anchorScreen.y,
13697
- x2: anchorScreen.x + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13698
- y2: anchorScreen.y,
13699
- stroke: COLORS.OFFSET_LINE,
13700
- strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
13701
- }
13702
- ),
13703
- /* @__PURE__ */ jsx15(
13704
- "line",
13705
- {
13706
- x1: anchorScreen.x,
13707
- y1: anchorScreen.y - VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13708
- x2: anchorScreen.x,
13709
- y2: anchorScreen.y + VISUAL_CONFIG.ANCHOR_MARKER_SIZE,
13710
- stroke: COLORS.OFFSET_LINE,
13711
- strokeWidth: VISUAL_CONFIG.ANCHOR_MARKER_STROKE_WIDTH
13712
- }
13713
- )
13714
- ] }, `anchor-${panelId}`)
13715
- )
13716
- ]
13717
- }
13718
- )
13302
+ targets: sharedTargets,
13303
+ transform,
13304
+ containerWidth,
13305
+ containerHeight
13719
13306
  }
13720
13307
  );
13721
13308
  };
13722
13309
 
13723
13310
  // src/components/MouseElementTracker.tsx
13724
- import { Fragment as Fragment8, jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
13311
+ import { Fragment as Fragment6, jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
13725
13312
  var getPolygonBoundingBox = (points) => {
13726
13313
  if (points.length === 0) return null;
13727
13314
  let minX = points[0].x;
@@ -13867,7 +13454,7 @@ var MouseElementTracker = ({
13867
13454
  h = "h" in primitive ? primitive.h : "r" in primitive ? primitive.r * 2 : "rX" in primitive && "rY" in primitive ? primitive.rY * 2 : 0;
13868
13455
  }
13869
13456
  if (!basePoint) continue;
13870
- const screenPos = applyToPoint16(transform, basePoint);
13457
+ const screenPos = applyToPoint14(transform, basePoint);
13871
13458
  const screenSize = {
13872
13459
  w: w * transform.a,
13873
13460
  h: h * transform.a
@@ -13892,7 +13479,7 @@ var MouseElementTracker = ({
13892
13479
  }, [mousedPrimitives, transform]);
13893
13480
  const handleInteraction = (x, y, transform2, primitives2) => {
13894
13481
  setMousePos({ x, y });
13895
- const rwPoint = applyToPoint16(inverse5(transform2), { x, y });
13482
+ const rwPoint = applyToPoint14(inverse5(transform2), { x, y });
13896
13483
  const newMousedPrimitives = getPrimitivesUnderPoint(
13897
13484
  primitives2,
13898
13485
  rwPoint,
@@ -13907,7 +13494,7 @@ var MouseElementTracker = ({
13907
13494
  setMousedPrimitives(newMousedPrimitives);
13908
13495
  onMouseHoverOverPrimitives(newMousedPrimitives);
13909
13496
  };
13910
- return /* @__PURE__ */ jsxs13(
13497
+ return /* @__PURE__ */ jsxs11(
13911
13498
  "div",
13912
13499
  {
13913
13500
  ref: containerRef,
@@ -13931,7 +13518,7 @@ var MouseElementTracker = ({
13931
13518
  },
13932
13519
  children: [
13933
13520
  children,
13934
- /* @__PURE__ */ jsx16(
13521
+ /* @__PURE__ */ jsx17(
13935
13522
  ElementOverlayBox,
13936
13523
  {
13937
13524
  elements,
@@ -13939,8 +13526,8 @@ var MouseElementTracker = ({
13939
13526
  highlightedPrimitives
13940
13527
  }
13941
13528
  ),
13942
- transform && /* @__PURE__ */ jsxs13(Fragment8, { children: [
13943
- /* @__PURE__ */ jsx16(
13529
+ transform && /* @__PURE__ */ jsxs11(Fragment6, { children: [
13530
+ /* @__PURE__ */ jsx17(
13944
13531
  BoardAnchorOffsetOverlay,
13945
13532
  {
13946
13533
  elements,
@@ -13950,7 +13537,7 @@ var MouseElementTracker = ({
13950
13537
  containerHeight: height
13951
13538
  }
13952
13539
  ),
13953
- /* @__PURE__ */ jsx16(
13540
+ /* @__PURE__ */ jsx17(
13954
13541
  GroupAnchorOffsetOverlay,
13955
13542
  {
13956
13543
  elements,
@@ -13960,7 +13547,7 @@ var MouseElementTracker = ({
13960
13547
  containerHeight: height
13961
13548
  }
13962
13549
  ),
13963
- /* @__PURE__ */ jsx16(
13550
+ /* @__PURE__ */ jsx17(
13964
13551
  ComponentBoundingBoxOverlay,
13965
13552
  {
13966
13553
  elements,
@@ -13970,7 +13557,7 @@ var MouseElementTracker = ({
13970
13557
  containerHeight: height
13971
13558
  }
13972
13559
  ),
13973
- /* @__PURE__ */ jsx16(
13560
+ /* @__PURE__ */ jsx17(
13974
13561
  PanelAnchorOffsetOverlay,
13975
13562
  {
13976
13563
  elements,
@@ -13987,10 +13574,10 @@ var MouseElementTracker = ({
13987
13574
  };
13988
13575
 
13989
13576
  // src/components/PcbGroupOverlay.tsx
13990
- import { applyToPoint as applyToPoint17 } from "transformation-matrix";
13577
+ import { applyToPoint as applyToPoint15 } from "transformation-matrix";
13991
13578
  import { identity as identity8 } from "transformation-matrix";
13992
13579
  import { useRef as useRef9, useEffect as useEffect12 } from "react";
13993
- import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
13580
+ import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
13994
13581
  var GROUP_COLORS = [
13995
13582
  "rgb(255, 100, 100)",
13996
13583
  "rgb(100, 255, 100)",
@@ -14145,10 +13732,10 @@ var PcbGroupOverlay = ({
14145
13732
  minY -= totalPadding;
14146
13733
  maxY += totalPadding;
14147
13734
  }
14148
- const topLeft = applyToPoint17(transform, { x: minX, y: maxY });
14149
- const topRight = applyToPoint17(transform, { x: maxX, y: maxY });
14150
- const bottomLeft = applyToPoint17(transform, { x: minX, y: minY });
14151
- const bottomRight = applyToPoint17(transform, { x: maxX, y: minY });
13735
+ const topLeft = applyToPoint15(transform, { x: minX, y: maxY });
13736
+ const topRight = applyToPoint15(transform, { x: maxX, y: maxY });
13737
+ const bottomLeft = applyToPoint15(transform, { x: minX, y: minY });
13738
+ const bottomRight = applyToPoint15(transform, { x: maxX, y: minY });
14152
13739
  const groupColor = GROUP_COLORS[groupIndex % GROUP_COLORS.length];
14153
13740
  ctx.strokeStyle = groupColor;
14154
13741
  ctx.lineWidth = 2;
@@ -14198,7 +13785,7 @@ var PcbGroupOverlay = ({
14198
13785
  x: group.anchor_position[0] ?? 0,
14199
13786
  y: group.anchor_position[1] ?? 0
14200
13787
  } : { x: group.anchor_position.x, y: group.anchor_position.y };
14201
- const anchorScreenPos = applyToPoint17(transform, anchorPositionValue);
13788
+ const anchorScreenPos = applyToPoint15(transform, anchorPositionValue);
14202
13789
  ctx.strokeStyle = "white";
14203
13790
  ctx.lineWidth = 1.5;
14204
13791
  ctx.setLineDash([]);
@@ -14223,14 +13810,14 @@ var PcbGroupOverlay = ({
14223
13810
  is_showing_group_anchor_offsets,
14224
13811
  hoveredComponentIds
14225
13812
  ]);
14226
- return /* @__PURE__ */ jsxs14(
13813
+ return /* @__PURE__ */ jsxs12(
14227
13814
  "div",
14228
13815
  {
14229
13816
  ref: containerRef,
14230
13817
  style: { position: "relative", width: "100%", height: "100%" },
14231
13818
  children: [
14232
13819
  children,
14233
- /* @__PURE__ */ jsx17(
13820
+ /* @__PURE__ */ jsx18(
14234
13821
  "canvas",
14235
13822
  {
14236
13823
  ref: canvasRef,
@@ -14250,9 +13837,9 @@ var PcbGroupOverlay = ({
14250
13837
  };
14251
13838
 
14252
13839
  // src/components/RatsNestOverlay.tsx
14253
- import { applyToPoint as applyToPoint18, identity as identity9 } from "transformation-matrix";
13840
+ import { applyToPoint as applyToPoint16, identity as identity9 } from "transformation-matrix";
14254
13841
  import { useMemo as useMemo6 } from "react";
14255
- import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
13842
+ import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
14256
13843
  var RatsNestOverlay = ({ transform, soup, children }) => {
14257
13844
  const isShowingRatsNest = useGlobalStore((s) => s.is_showing_rats_nest);
14258
13845
  const { netMap, idToNetMap } = useMemo6(
@@ -14315,9 +13902,9 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
14315
13902
  }, [soup, netMap, idToNetMap, isShowingRatsNest]);
14316
13903
  if (!soup || !isShowingRatsNest) return children;
14317
13904
  if (!transform) transform = identity9();
14318
- return /* @__PURE__ */ jsxs15("div", { style: { position: "relative" }, children: [
13905
+ return /* @__PURE__ */ jsxs13("div", { style: { position: "relative" }, children: [
14319
13906
  children,
14320
- /* @__PURE__ */ jsx18(
13907
+ /* @__PURE__ */ jsx19(
14321
13908
  "svg",
14322
13909
  {
14323
13910
  style: {
@@ -14331,9 +13918,9 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
14331
13918
  zIndex: zIndexMap.ratsNestOverlay
14332
13919
  },
14333
13920
  children: ratsNestLines.map(({ key, startPoint, endPoint, isInNet }) => {
14334
- const transformedStart = applyToPoint18(transform, startPoint);
14335
- const transformedEnd = applyToPoint18(transform, endPoint);
14336
- return /* @__PURE__ */ jsx18(
13921
+ const transformedStart = applyToPoint16(transform, startPoint);
13922
+ const transformedEnd = applyToPoint16(transform, endPoint);
13923
+ return /* @__PURE__ */ jsx19(
14337
13924
  "line",
14338
13925
  {
14339
13926
  x1: transformedStart.x,
@@ -14359,7 +13946,7 @@ import { css as css3 } from "@emotion/css";
14359
13946
  // package.json
14360
13947
  var package_default = {
14361
13948
  name: "@tscircuit/pcb-viewer",
14362
- version: "1.11.292",
13949
+ version: "1.11.293",
14363
13950
  main: "dist/index.js",
14364
13951
  type: "module",
14365
13952
  repository: "tscircuit/pcb-viewer",
@@ -14465,9 +14052,9 @@ var useIsSmallScreen = () => {
14465
14052
  };
14466
14053
 
14467
14054
  // src/components/ToolbarOverlay.tsx
14468
- import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
14055
+ import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
14469
14056
  var LayerButton = ({ name, selected, onClick }) => {
14470
- return /* @__PURE__ */ jsxs16(
14057
+ return /* @__PURE__ */ jsxs14(
14471
14058
  "div",
14472
14059
  {
14473
14060
  className: css3`
@@ -14483,8 +14070,8 @@ var LayerButton = ({ name, selected, onClick }) => {
14483
14070
  `,
14484
14071
  onClick,
14485
14072
  children: [
14486
- /* @__PURE__ */ jsx19("span", { style: { marginRight: 2, opacity: selected ? 1 : 0 }, children: "\u2022" }),
14487
- /* @__PURE__ */ jsx19(
14073
+ /* @__PURE__ */ jsx20("span", { style: { marginRight: 2, opacity: selected ? 1 : 0 }, children: "\u2022" }),
14074
+ /* @__PURE__ */ jsx20(
14488
14075
  "span",
14489
14076
  {
14490
14077
  style: {
@@ -14504,7 +14091,7 @@ var ToolbarButton = ({
14504
14091
  isSmallScreen,
14505
14092
  onClick,
14506
14093
  ...props
14507
- }) => /* @__PURE__ */ jsx19(
14094
+ }) => /* @__PURE__ */ jsx20(
14508
14095
  "div",
14509
14096
  {
14510
14097
  ...props,
@@ -14541,7 +14128,7 @@ var CheckboxMenuItem = ({
14541
14128
  checked,
14542
14129
  onClick
14543
14130
  }) => {
14544
- return /* @__PURE__ */ jsxs16(
14131
+ return /* @__PURE__ */ jsxs14(
14545
14132
  "div",
14546
14133
  {
14547
14134
  className: css3`
@@ -14568,15 +14155,15 @@ var CheckboxMenuItem = ({
14568
14155
  onClick();
14569
14156
  },
14570
14157
  children: [
14571
- /* @__PURE__ */ jsx19("input", { type: "checkbox", checked, onChange: () => {
14158
+ /* @__PURE__ */ jsx20("input", { type: "checkbox", checked, onChange: () => {
14572
14159
  }, readOnly: true }),
14573
- /* @__PURE__ */ jsx19("span", { style: { color: "#eee" }, children: label })
14160
+ /* @__PURE__ */ jsx20("span", { style: { color: "#eee" }, children: label })
14574
14161
  ]
14575
14162
  }
14576
14163
  );
14577
14164
  };
14578
14165
  var RadioMenuItem = ({ label, checked, onClick }) => {
14579
- return /* @__PURE__ */ jsxs16(
14166
+ return /* @__PURE__ */ jsxs14(
14580
14167
  "div",
14581
14168
  {
14582
14169
  className: css3`
@@ -14603,9 +14190,9 @@ var RadioMenuItem = ({ label, checked, onClick }) => {
14603
14190
  onClick();
14604
14191
  },
14605
14192
  children: [
14606
- /* @__PURE__ */ jsx19("input", { type: "radio", checked, onChange: () => {
14193
+ /* @__PURE__ */ jsx20("input", { type: "radio", checked, onChange: () => {
14607
14194
  }, readOnly: true }),
14608
- /* @__PURE__ */ jsx19("span", { style: { color: "#eee" }, children: label })
14195
+ /* @__PURE__ */ jsx20("span", { style: { color: "#eee" }, children: label })
14609
14196
  ]
14610
14197
  }
14611
14198
  );
@@ -14757,7 +14344,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14757
14344
  setErrorsOpen(false);
14758
14345
  }
14759
14346
  }, [isViewMenuOpen]);
14760
- return /* @__PURE__ */ jsxs16(
14347
+ return /* @__PURE__ */ jsxs14(
14761
14348
  "div",
14762
14349
  {
14763
14350
  style: { position: "relative", zIndex: "999 !important" },
@@ -14765,7 +14352,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14765
14352
  onMouseLeave: handleMouseLeave,
14766
14353
  children: [
14767
14354
  children,
14768
- /* @__PURE__ */ jsxs16(
14355
+ /* @__PURE__ */ jsxs14(
14769
14356
  "div",
14770
14357
  {
14771
14358
  style: {
@@ -14786,7 +14373,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14786
14373
  ]
14787
14374
  }
14788
14375
  ),
14789
- /* @__PURE__ */ jsxs16(
14376
+ /* @__PURE__ */ jsxs14(
14790
14377
  "div",
14791
14378
  {
14792
14379
  "data-toolbar-overlay": true,
@@ -14809,7 +14396,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14809
14396
  fontFamily: "sans-serif"
14810
14397
  },
14811
14398
  children: [
14812
- /* @__PURE__ */ jsxs16(
14399
+ /* @__PURE__ */ jsxs14(
14813
14400
  ToolbarButton,
14814
14401
  {
14815
14402
  isSmallScreen,
@@ -14820,10 +14407,10 @@ var ToolbarOverlay = ({ children, elements }) => {
14820
14407
  }
14821
14408
  },
14822
14409
  children: [
14823
- /* @__PURE__ */ jsxs16("div", { children: [
14410
+ /* @__PURE__ */ jsxs14("div", { children: [
14824
14411
  "layer:",
14825
14412
  " ",
14826
- /* @__PURE__ */ jsx19(
14413
+ /* @__PURE__ */ jsx20(
14827
14414
  "span",
14828
14415
  {
14829
14416
  style: {
@@ -14835,7 +14422,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14835
14422
  }
14836
14423
  )
14837
14424
  ] }),
14838
- isLayerMenuOpen && /* @__PURE__ */ jsx19("div", { style: { marginTop: 4, minWidth: 120 }, children: processedLayers.map((layer) => /* @__PURE__ */ jsx19(
14425
+ isLayerMenuOpen && /* @__PURE__ */ jsx20("div", { style: { marginTop: 4, minWidth: 120 }, children: processedLayers.map((layer) => /* @__PURE__ */ jsx20(
14839
14426
  LayerButton,
14840
14427
  {
14841
14428
  name: layer,
@@ -14849,7 +14436,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14849
14436
  ]
14850
14437
  }
14851
14438
  ),
14852
- /* @__PURE__ */ jsx19(
14439
+ /* @__PURE__ */ jsx20(
14853
14440
  ToolbarButton,
14854
14441
  {
14855
14442
  isSmallScreen,
@@ -14858,13 +14445,13 @@ var ToolbarOverlay = ({ children, elements }) => {
14858
14445
  ...errorCount > 0 ? { color: "red" } : {}
14859
14446
  },
14860
14447
  onClick: handleErrorsToggle,
14861
- children: /* @__PURE__ */ jsxs16("div", { children: [
14448
+ children: /* @__PURE__ */ jsxs14("div", { children: [
14862
14449
  errorCount,
14863
14450
  " errors"
14864
14451
  ] })
14865
14452
  }
14866
14453
  ),
14867
- isErrorsOpen && errorCount > 0 && /* @__PURE__ */ jsx19(
14454
+ isErrorsOpen && errorCount > 0 && /* @__PURE__ */ jsx20(
14868
14455
  "div",
14869
14456
  {
14870
14457
  style: {
@@ -14884,14 +14471,14 @@ var ToolbarOverlay = ({ children, elements }) => {
14884
14471
  },
14885
14472
  children: errorElements.map((e, i) => {
14886
14473
  const errorId = e.pcb_trace_error_id || `error_${i}_${e.error_type}_${e.message?.slice(0, 20)}`;
14887
- return /* @__PURE__ */ jsxs16(
14474
+ return /* @__PURE__ */ jsxs14(
14888
14475
  "div",
14889
14476
  {
14890
14477
  style: {
14891
14478
  borderBottom: i < errorElements.length - 1 ? "1px solid #444" : "none"
14892
14479
  },
14893
14480
  children: [
14894
- /* @__PURE__ */ jsxs16(
14481
+ /* @__PURE__ */ jsxs14(
14895
14482
  "div",
14896
14483
  {
14897
14484
  style: {
@@ -14942,7 +14529,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14942
14529
  }
14943
14530
  },
14944
14531
  children: [
14945
- /* @__PURE__ */ jsx19(
14532
+ /* @__PURE__ */ jsx20(
14946
14533
  "div",
14947
14534
  {
14948
14535
  style: {
@@ -14956,7 +14543,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14956
14543
  children: e.error_type
14957
14544
  }
14958
14545
  ),
14959
- /* @__PURE__ */ jsx19(
14546
+ /* @__PURE__ */ jsx20(
14960
14547
  "div",
14961
14548
  {
14962
14549
  style: {
@@ -14971,7 +14558,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14971
14558
  children: e.message
14972
14559
  }
14973
14560
  ),
14974
- /* @__PURE__ */ jsx19(
14561
+ /* @__PURE__ */ jsx20(
14975
14562
  "div",
14976
14563
  {
14977
14564
  ref: (el) => {
@@ -14991,7 +14578,7 @@ var ToolbarOverlay = ({ children, elements }) => {
14991
14578
  ]
14992
14579
  }
14993
14580
  ),
14994
- /* @__PURE__ */ jsx19(
14581
+ /* @__PURE__ */ jsx20(
14995
14582
  "div",
14996
14583
  {
14997
14584
  ref: (el) => {
@@ -15004,7 +14591,7 @@ var ToolbarOverlay = ({ children, elements }) => {
15004
14591
  backgroundColor: "#1a1a1a",
15005
14592
  borderTop: "1px solid #444"
15006
14593
  },
15007
- children: /* @__PURE__ */ jsx19(
14594
+ children: /* @__PURE__ */ jsx20(
15008
14595
  "div",
15009
14596
  {
15010
14597
  style: {
@@ -15027,58 +14614,58 @@ var ToolbarOverlay = ({ children, elements }) => {
15027
14614
  })
15028
14615
  }
15029
14616
  ),
15030
- /* @__PURE__ */ jsx19(
14617
+ /* @__PURE__ */ jsx20(
15031
14618
  ToolbarButton,
15032
14619
  {
15033
14620
  isSmallScreen,
15034
14621
  style: {},
15035
14622
  onClick: handleEditTraceToggle,
15036
- children: /* @__PURE__ */ jsxs16("div", { children: [
14623
+ children: /* @__PURE__ */ jsxs14("div", { children: [
15037
14624
  editModes.in_draw_trace_mode ? "\u2716 " : "",
15038
14625
  "Edit Traces"
15039
14626
  ] })
15040
14627
  }
15041
14628
  ),
15042
- /* @__PURE__ */ jsx19(
14629
+ /* @__PURE__ */ jsx20(
15043
14630
  ToolbarButton,
15044
14631
  {
15045
14632
  isSmallScreen,
15046
14633
  style: {},
15047
14634
  onClick: handleMoveComponentToggle,
15048
- children: /* @__PURE__ */ jsxs16("div", { children: [
14635
+ children: /* @__PURE__ */ jsxs14("div", { children: [
15049
14636
  editModes.in_move_footprint_mode ? "\u2716 " : "",
15050
14637
  "Move Components"
15051
14638
  ] })
15052
14639
  }
15053
14640
  ),
15054
- /* @__PURE__ */ jsx19(
14641
+ /* @__PURE__ */ jsx20(
15055
14642
  ToolbarButton,
15056
14643
  {
15057
14644
  isSmallScreen,
15058
14645
  style: {},
15059
14646
  onClick: handleRatsNestToggle,
15060
- children: /* @__PURE__ */ jsxs16("div", { children: [
14647
+ children: /* @__PURE__ */ jsxs14("div", { children: [
15061
14648
  viewSettings.is_showing_rats_nest ? "\u2716 " : "",
15062
14649
  "Rats Nest"
15063
14650
  ] })
15064
14651
  }
15065
14652
  ),
15066
- /* @__PURE__ */ jsx19(
14653
+ /* @__PURE__ */ jsx20(
15067
14654
  ToolbarButton,
15068
14655
  {
15069
14656
  isSmallScreen,
15070
14657
  style: measureToolArmed ? { backgroundColor: "#444" } : {},
15071
14658
  onClick: handleMeasureToolClick,
15072
- children: /* @__PURE__ */ jsx19("div", { children: "\u{1F4CF}" })
14659
+ children: /* @__PURE__ */ jsx20("div", { children: "\u{1F4CF}" })
15073
14660
  }
15074
14661
  ),
15075
- /* @__PURE__ */ jsx19(
14662
+ /* @__PURE__ */ jsx20(
15076
14663
  ToolbarButton,
15077
14664
  {
15078
14665
  isSmallScreen,
15079
14666
  onClick: handleViewMenuToggle,
15080
- children: /* @__PURE__ */ jsxs16("div", { children: [
15081
- /* @__PURE__ */ jsxs16(
14667
+ children: /* @__PURE__ */ jsxs14("div", { children: [
14668
+ /* @__PURE__ */ jsxs14(
15082
14669
  "div",
15083
14670
  {
15084
14671
  style: {
@@ -15088,7 +14675,7 @@ var ToolbarOverlay = ({ children, elements }) => {
15088
14675
  },
15089
14676
  children: [
15090
14677
  "View",
15091
- /* @__PURE__ */ jsx19(
14678
+ /* @__PURE__ */ jsx20(
15092
14679
  "span",
15093
14680
  {
15094
14681
  style: {
@@ -15103,8 +14690,8 @@ var ToolbarOverlay = ({ children, elements }) => {
15103
14690
  ]
15104
14691
  }
15105
14692
  ),
15106
- isViewMenuOpen && /* @__PURE__ */ jsxs16("div", { style: { marginTop: 4, minWidth: 120 }, children: [
15107
- /* @__PURE__ */ jsx19(
14693
+ isViewMenuOpen && /* @__PURE__ */ jsxs14("div", { style: { marginTop: 4, minWidth: 120 }, children: [
14694
+ /* @__PURE__ */ jsx20(
15108
14695
  CheckboxMenuItem,
15109
14696
  {
15110
14697
  label: "Show All Trace Lengths",
@@ -15116,7 +14703,7 @@ var ToolbarOverlay = ({ children, elements }) => {
15116
14703
  }
15117
14704
  }
15118
14705
  ),
15119
- /* @__PURE__ */ jsx19(
14706
+ /* @__PURE__ */ jsx20(
15120
14707
  CheckboxMenuItem,
15121
14708
  {
15122
14709
  label: "Show Autorouting Animation",
@@ -15128,7 +14715,7 @@ var ToolbarOverlay = ({ children, elements }) => {
15128
14715
  }
15129
14716
  }
15130
14717
  ),
15131
- /* @__PURE__ */ jsx19(
14718
+ /* @__PURE__ */ jsx20(
15132
14719
  CheckboxMenuItem,
15133
14720
  {
15134
14721
  label: "Show DRC Errors",
@@ -15138,7 +14725,7 @@ var ToolbarOverlay = ({ children, elements }) => {
15138
14725
  }
15139
14726
  }
15140
14727
  ),
15141
- /* @__PURE__ */ jsx19(
14728
+ /* @__PURE__ */ jsx20(
15142
14729
  CheckboxMenuItem,
15143
14730
  {
15144
14731
  label: "Show Copper Pours",
@@ -15150,7 +14737,7 @@ var ToolbarOverlay = ({ children, elements }) => {
15150
14737
  }
15151
14738
  }
15152
14739
  ),
15153
- /* @__PURE__ */ jsx19(
14740
+ /* @__PURE__ */ jsx20(
15154
14741
  CheckboxMenuItem,
15155
14742
  {
15156
14743
  label: "Show Solder Mask",
@@ -15160,7 +14747,7 @@ var ToolbarOverlay = ({ children, elements }) => {
15160
14747
  }
15161
14748
  }
15162
14749
  ),
15163
- /* @__PURE__ */ jsx19(
14750
+ /* @__PURE__ */ jsx20(
15164
14751
  CheckboxMenuItem,
15165
14752
  {
15166
14753
  label: "Show Group Anchor Offsets",
@@ -15172,7 +14759,7 @@ var ToolbarOverlay = ({ children, elements }) => {
15172
14759
  }
15173
14760
  }
15174
14761
  ),
15175
- /* @__PURE__ */ jsx19(
14762
+ /* @__PURE__ */ jsx20(
15176
14763
  CheckboxMenuItem,
15177
14764
  {
15178
14765
  label: "Show PCB Groups",
@@ -15182,8 +14769,8 @@ var ToolbarOverlay = ({ children, elements }) => {
15182
14769
  }
15183
14770
  }
15184
14771
  ),
15185
- viewSettings.is_showing_pcb_groups && /* @__PURE__ */ jsxs16("div", { style: { marginLeft: 16 }, children: [
15186
- /* @__PURE__ */ jsx19(
14772
+ viewSettings.is_showing_pcb_groups && /* @__PURE__ */ jsxs14("div", { style: { marginLeft: 16 }, children: [
14773
+ /* @__PURE__ */ jsx20(
15187
14774
  RadioMenuItem,
15188
14775
  {
15189
14776
  label: "Show All Groups",
@@ -15193,7 +14780,7 @@ var ToolbarOverlay = ({ children, elements }) => {
15193
14780
  }
15194
14781
  }
15195
14782
  ),
15196
- /* @__PURE__ */ jsx19(
14783
+ /* @__PURE__ */ jsx20(
15197
14784
  RadioMenuItem,
15198
14785
  {
15199
14786
  label: "Show Named Groups",
@@ -15217,7 +14804,7 @@ var ToolbarOverlay = ({ children, elements }) => {
15217
14804
  };
15218
14805
 
15219
14806
  // src/components/CanvasElementsRenderer.tsx
15220
- import { jsx as jsx20 } from "react/jsx-runtime";
14807
+ import { jsx as jsx21 } from "react/jsx-runtime";
15221
14808
  var CanvasElementsRenderer = (props) => {
15222
14809
  const { transform, elements } = props;
15223
14810
  const hoveredErrorId = useGlobalStore((state) => state.hovered_error_id);
@@ -15305,14 +14892,14 @@ var CanvasElementsRenderer = (props) => {
15305
14892
  },
15306
14893
  [connectivityMap]
15307
14894
  );
15308
- return /* @__PURE__ */ jsx20(
14895
+ return /* @__PURE__ */ jsx21(
15309
14896
  MouseElementTracker,
15310
14897
  {
15311
14898
  elements: elementsToRender,
15312
14899
  transform,
15313
14900
  primitives: primitivesWithoutInteractionMetadata,
15314
14901
  onMouseHoverOverPrimitives: onMouseOverPrimitives,
15315
- children: /* @__PURE__ */ jsx20(
14902
+ children: /* @__PURE__ */ jsx21(
15316
14903
  EditPlacementOverlay,
15317
14904
  {
15318
14905
  disabled: !props.allowEditing,
@@ -15321,7 +14908,7 @@ var CanvasElementsRenderer = (props) => {
15321
14908
  cancelPanDrag: props.cancelPanDrag,
15322
14909
  onCreateEditEvent: props.onCreateEditEvent,
15323
14910
  onModifyEditEvent: props.onModifyEditEvent,
15324
- children: /* @__PURE__ */ jsx20(
14911
+ children: /* @__PURE__ */ jsx21(
15325
14912
  EditTraceHintOverlay,
15326
14913
  {
15327
14914
  disabled: !props.allowEditing,
@@ -15330,29 +14917,29 @@ var CanvasElementsRenderer = (props) => {
15330
14917
  cancelPanDrag: props.cancelPanDrag,
15331
14918
  onCreateEditEvent: props.onCreateEditEvent,
15332
14919
  onModifyEditEvent: props.onModifyEditEvent,
15333
- children: /* @__PURE__ */ jsx20(
14920
+ children: /* @__PURE__ */ jsx21(
15334
14921
  DimensionOverlay,
15335
14922
  {
15336
14923
  transform,
15337
14924
  focusOnHover: props.focusOnHover,
15338
14925
  primitives: primitivesWithoutInteractionMetadata,
15339
- children: /* @__PURE__ */ jsx20(ToolbarOverlay, { elements, children: /* @__PURE__ */ jsx20(ErrorOverlay, { transform, elements, children: /* @__PURE__ */ jsx20(RatsNestOverlay, { transform, soup: elements, children: /* @__PURE__ */ jsx20(
14926
+ children: /* @__PURE__ */ jsx21(ToolbarOverlay, { elements, children: /* @__PURE__ */ jsx21(ErrorOverlay, { transform, elements, children: /* @__PURE__ */ jsx21(RatsNestOverlay, { transform, soup: elements, children: /* @__PURE__ */ jsx21(
15340
14927
  PcbGroupOverlay,
15341
14928
  {
15342
14929
  transform,
15343
14930
  elements,
15344
14931
  hoveredComponentIds,
15345
- children: /* @__PURE__ */ jsx20(
14932
+ children: /* @__PURE__ */ jsx21(
15346
14933
  DebugGraphicsOverlay,
15347
14934
  {
15348
14935
  transform,
15349
14936
  debugGraphics: props.debugGraphics,
15350
- children: /* @__PURE__ */ jsx20(
14937
+ children: /* @__PURE__ */ jsx21(
15351
14938
  WarningGraphicsOverlay,
15352
14939
  {
15353
14940
  transform,
15354
14941
  elements,
15355
- children: /* @__PURE__ */ jsx20(
14942
+ children: /* @__PURE__ */ jsx21(
15356
14943
  CanvasPrimitiveRenderer,
15357
14944
  {
15358
14945
  transform,
@@ -15421,7 +15008,7 @@ var calculateCircuitJsonKey = (circuitJson) => {
15421
15008
  };
15422
15009
 
15423
15010
  // src/PCBViewer.tsx
15424
- import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
15011
+ import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
15425
15012
  var defaultTransform = compose7(translate11(400, 300), scale5(40, -40));
15426
15013
  var PCBViewer = ({
15427
15014
  circuitJson,
@@ -15515,20 +15102,20 @@ var PCBViewer = ({
15515
15102
  }),
15516
15103
  [initialState, disablePcbGroups]
15517
15104
  );
15518
- return /* @__PURE__ */ jsxs17(
15105
+ return /* @__PURE__ */ jsxs15(
15519
15106
  "div",
15520
15107
  {
15521
15108
  ref: transformRef,
15522
15109
  style: { position: "relative" },
15523
15110
  onContextMenu: (event) => event.preventDefault(),
15524
15111
  children: [
15525
- /* @__PURE__ */ jsx21("div", { ref, children: /* @__PURE__ */ jsxs17(
15112
+ /* @__PURE__ */ jsx22("div", { ref, children: /* @__PURE__ */ jsxs15(
15526
15113
  ContextProviders,
15527
15114
  {
15528
15115
  initialState: mergedInitialState,
15529
15116
  disablePcbGroups,
15530
15117
  children: [
15531
- /* @__PURE__ */ jsx21(
15118
+ /* @__PURE__ */ jsx22(
15532
15119
  CanvasElementsRenderer,
15533
15120
  {
15534
15121
  transform,
@@ -15553,11 +15140,11 @@ var PCBViewer = ({
15553
15140
  },
15554
15141
  refDimensions.width
15555
15142
  ),
15556
- /* @__PURE__ */ jsx21(ToastContainer, {})
15143
+ /* @__PURE__ */ jsx22(ToastContainer, {})
15557
15144
  ]
15558
15145
  }
15559
15146
  ) }),
15560
- clickToInteractEnabled && !isInteractionEnabled && /* @__PURE__ */ jsx21(
15147
+ clickToInteractEnabled && !isInteractionEnabled && /* @__PURE__ */ jsx22(
15561
15148
  "div",
15562
15149
  {
15563
15150
  onClick: () => {
@@ -15594,7 +15181,7 @@ var PCBViewer = ({
15594
15181
  justifyContent: "center",
15595
15182
  touchAction: "pan-x pan-y pinch-zoom"
15596
15183
  },
15597
- children: /* @__PURE__ */ jsx21(
15184
+ children: /* @__PURE__ */ jsx22(
15598
15185
  "div",
15599
15186
  {
15600
15187
  style: {