@tscircuit/3d-viewer 0.0.638 → 0.0.640

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
@@ -19214,11 +19214,16 @@ function resolveFoldPcbs(circuitJson, foldPcbs) {
19214
19214
  );
19215
19215
  }
19216
19216
 
19217
- // src/utils/pick-cad-component.ts
19218
- var pickCadComponent = (scene, position, circuitJson) => {
19217
+ // src/utils/pick-scene-object.ts
19218
+ var getBoardName = (id, circuitJson) => circuitJson.some((e) => e.type === "pcb_panel" && e.pcb_panel_id === id) ? "Panel" : "Board";
19219
+ var pickSceneObject = (scene, position, circuitJson) => {
19219
19220
  let object = pickVisibleMesh(scene, position) ?? null;
19220
19221
  while (object) {
19221
- const cadComponentId = object.userData.cad_component_id;
19222
+ const {
19223
+ cad_component_id: cadComponentId,
19224
+ pcb_board_id: pcbBoardId,
19225
+ cad_cable_id: cadCableId
19226
+ } = object.userData;
19222
19227
  if (cadComponentId) {
19223
19228
  const cad = circuitJson.find(
19224
19229
  (e) => e.type === "cad_component" && e.cad_component_id === cadComponentId
@@ -19227,8 +19232,8 @@ var pickCadComponent = (scene, position, circuitJson) => {
19227
19232
  const metadata = getGlbComponentMetadata(object);
19228
19233
  if (metadata && metadata.cad_component_id === cadComponentId)
19229
19234
  return {
19230
- cad_component_id: cadComponentId,
19231
- componentName: metadata.componentName ?? cadComponentId
19235
+ objectId: cadComponentId,
19236
+ name: metadata.componentName ?? cadComponentId
19232
19237
  };
19233
19238
  return;
19234
19239
  }
@@ -19236,43 +19241,79 @@ var pickCadComponent = (scene, position, circuitJson) => {
19236
19241
  (e) => e.type === "source_component" && e.source_component_id === cad.source_component_id
19237
19242
  );
19238
19243
  return {
19239
- cad_component_id: cad.cad_component_id,
19240
- componentName: source?.type === "source_component" ? source.name : cad.cad_component_id
19244
+ objectId: cad.cad_component_id,
19245
+ name: source?.type === "source_component" ? source.name : cad.cad_component_id
19241
19246
  };
19242
19247
  }
19248
+ if (pcbBoardId)
19249
+ return {
19250
+ objectId: pcbBoardId,
19251
+ name: getBoardName(pcbBoardId, circuitJson)
19252
+ };
19253
+ if (cadCableId)
19254
+ return { objectId: cadCableId, name: object.userData.name ?? cadCableId };
19243
19255
  object = object.parent;
19244
19256
  }
19245
19257
  };
19246
19258
 
19247
- // src/hooks/useHiddenCadComponents.ts
19259
+ // src/hooks/useObjectVisibility.ts
19248
19260
  import { useState as useState2 } from "react";
19249
- var NO_HIDDEN_COMPONENTS = /* @__PURE__ */ new Set();
19250
- var useHiddenCadComponents = (circuitKey) => {
19261
+
19262
+ // src/utils/object-visibility.ts
19263
+ var ALL_OBJECTS_VISIBLE = { hiddenIds: /* @__PURE__ */ new Set() };
19264
+ var isObjectHidden = (visibility, id) => {
19265
+ if (!visibility) return false;
19266
+ if (id !== void 0 && visibility.hiddenIds.has(id)) return true;
19267
+ return visibility.isolatedId !== void 0 && visibility.isolatedId !== id;
19268
+ };
19269
+ var hasHiddenObjects = (visibility) => visibility.hiddenIds.size > 0 || visibility.isolatedId !== void 0;
19270
+
19271
+ // src/hooks/useObjectVisibility.ts
19272
+ var useObjectVisibility = (circuitKey) => {
19251
19273
  const [state, setState] = useState2({
19252
19274
  circuitKey,
19253
- ids: NO_HIDDEN_COMPONENTS
19275
+ visibility: ALL_OBJECTS_VISIBLE
19254
19276
  });
19255
- const hiddenCadComponentIds = state.circuitKey === circuitKey ? state.ids : NO_HIDDEN_COMPONENTS;
19277
+ const objectVisibility = state.circuitKey === circuitKey ? state.visibility : ALL_OBJECTS_VISIBLE;
19256
19278
  if (state.circuitKey !== circuitKey) {
19257
- setState({ circuitKey, ids: NO_HIDDEN_COMPONENTS });
19279
+ setState({ circuitKey, visibility: ALL_OBJECTS_VISIBLE });
19258
19280
  }
19281
+ const update = (next) => {
19282
+ setState((current) => ({
19283
+ circuitKey,
19284
+ visibility: next(
19285
+ current.circuitKey === circuitKey ? current.visibility : ALL_OBJECTS_VISIBLE
19286
+ )
19287
+ }));
19288
+ };
19259
19289
  return {
19260
- hiddenCadComponentIds,
19261
- hideComponent: (id) => {
19262
- setState((current) => ({
19263
- circuitKey,
19264
- ids: /* @__PURE__ */ new Set([
19265
- ...current.circuitKey === circuitKey ? current.ids : [],
19266
- id
19267
- ])
19290
+ objectVisibility,
19291
+ hideObject: (id) => {
19292
+ update((current) => ({
19293
+ ...current,
19294
+ hiddenIds: /* @__PURE__ */ new Set([...current.hiddenIds, id])
19268
19295
  }));
19269
19296
  },
19270
- unhideAllComponents: () => {
19271
- setState({ circuitKey, ids: NO_HIDDEN_COMPONENTS });
19297
+ isolateObject: (id) => {
19298
+ update((current) => ({ ...current, isolatedId: id }));
19299
+ },
19300
+ unhideAllObjects: () => {
19301
+ update(() => ALL_OBJECTS_VISIBLE);
19272
19302
  }
19273
19303
  };
19274
19304
  };
19275
19305
 
19306
+ // src/utils/find-model-object.ts
19307
+ var findModelObject = (root, objectId) => {
19308
+ let model;
19309
+ root.traverse((object) => {
19310
+ const { cad_component_id, cad_cable_id } = object.userData;
19311
+ if (!model && (cad_component_id ?? cad_cable_id) === objectId)
19312
+ model = object;
19313
+ });
19314
+ return model;
19315
+ };
19316
+
19276
19317
  // src/utils/configure-runtime-font.ts
19277
19318
  import { configureTextBuilder } from "troika-three-text";
19278
19319
 
@@ -19309,8 +19350,8 @@ function configureRuntimeFont() {
19309
19350
  }
19310
19351
 
19311
19352
  // src/CadViewer.tsx
19312
- import { useCallback as useCallback25, useContext as useContext13, useEffect as useEffect56, useRef as useRef30, useState as useState46 } from "react";
19313
- import * as THREE63 from "three";
19353
+ import { useCallback as useCallback25, useContext as useContext13, useEffect as useEffect57, useRef as useRef30, useState as useState46 } from "react";
19354
+ import * as THREE64 from "three";
19314
19355
 
19315
19356
  // src/assembly-explosion/use-assembly-explosion.ts
19316
19357
  import {
@@ -19564,7 +19605,7 @@ function AssemblyExplosionControl({
19564
19605
 
19565
19606
  // src/CadViewerJscad.tsx
19566
19607
  import { su as su12 } from "@tscircuit/circuit-json-util";
19567
- import { forwardRef as forwardRef3, useMemo as useMemo26 } from "react";
19608
+ import { forwardRef as forwardRef3, useMemo as useMemo27 } from "react";
19568
19609
 
19569
19610
  // src/utils/get-cad-pcb-context.ts
19570
19611
  var getCadPcbContext = (cad, circuitJson) => {
@@ -22303,7 +22344,7 @@ import * as THREE31 from "three";
22303
22344
  // package.json
22304
22345
  var package_default = {
22305
22346
  name: "@tscircuit/3d-viewer",
22306
- version: "0.0.637",
22347
+ version: "0.0.639",
22307
22348
  repository: {
22308
22349
  type: "git",
22309
22350
  url: "https://github.com/tscircuit/3d-viewer"
@@ -25775,9 +25816,36 @@ var ErrorBox = ({ parent }) => {
25775
25816
  return null;
25776
25817
  };
25777
25818
 
25819
+ // src/three-components/BoardGroup.tsx
25820
+ import { useEffect as useEffect30, useMemo as useMemo22 } from "react";
25821
+ import * as THREE35 from "three";
25822
+ import { jsx as jsx20 } from "react/jsx-runtime";
25823
+ var BoardGroup = ({
25824
+ pcbBoardId,
25825
+ hidden = false,
25826
+ children
25827
+ }) => {
25828
+ const scene = useThree();
25829
+ const group = useMemo22(() => new THREE35.Group(), []);
25830
+ group.name = "board";
25831
+ group.userData.pcb_board_id = pcbBoardId;
25832
+ group.visible = !hidden;
25833
+ useEffect30(() => {
25834
+ scene.rootObject.add(group);
25835
+ return () => {
25836
+ scene.rootObject.remove(group);
25837
+ };
25838
+ }, [scene.rootObject, group]);
25839
+ const context = useMemo22(
25840
+ () => ({ ...scene, rootObject: group }),
25841
+ [scene, group]
25842
+ );
25843
+ return /* @__PURE__ */ jsx20(ThreeContext.Provider, { value: context, children });
25844
+ };
25845
+
25778
25846
  // src/three-components/JscadBoardTextures.tsx
25779
25847
  import { su as su9 } from "@tscircuit/circuit-json-util";
25780
- import { useEffect as useEffect30, useMemo as useMemo23 } from "react";
25848
+ import { useEffect as useEffect31, useMemo as useMemo24 } from "react";
25781
25849
 
25782
25850
  // src/textures/open-via-holes-at-pads.ts
25783
25851
  import { CircuitToCanvasDrawer } from "circuit-to-canvas";
@@ -25933,12 +26001,12 @@ function clearViaHolesFromSurface({
25933
26001
 
25934
26002
  // src/textures/create-combined-board-textures.ts
25935
26003
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer12 } from "circuit-to-canvas";
25936
- import * as THREE47 from "three";
26004
+ import * as THREE48 from "three";
25937
26005
 
25938
26006
  // src/utils/pad-texture.ts
25939
26007
  import { su as su6 } from "@tscircuit/circuit-json-util";
25940
26008
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer2 } from "circuit-to-canvas";
25941
- import * as THREE35 from "three";
26009
+ import * as THREE36 from "three";
25942
26010
  function createPadTextureForLayer({
25943
26011
  layer,
25944
26012
  circuitJson,
@@ -26018,10 +26086,10 @@ function createPadTextureForLayer({
26018
26086
  drawSoldermaskTop: false,
26019
26087
  drawSoldermaskBottom: false
26020
26088
  });
26021
- const texture = new THREE35.CanvasTexture(canvas);
26089
+ const texture = new THREE36.CanvasTexture(canvas);
26022
26090
  texture.generateMipmaps = true;
26023
- texture.minFilter = THREE35.LinearMipmapLinearFilter;
26024
- texture.magFilter = THREE35.LinearFilter;
26091
+ texture.minFilter = THREE36.LinearMipmapLinearFilter;
26092
+ texture.magFilter = THREE36.LinearFilter;
26025
26093
  texture.anisotropy = 16;
26026
26094
  texture.needsUpdate = true;
26027
26095
  return texture;
@@ -26029,7 +26097,7 @@ function createPadTextureForLayer({
26029
26097
 
26030
26098
  // src/utils/panel-outline-texture.ts
26031
26099
  import { su as su7 } from "@tscircuit/circuit-json-util";
26032
- import * as THREE36 from "three";
26100
+ import * as THREE37 from "three";
26033
26101
  var resolvePanelIdForTexture = (circuitJson) => {
26034
26102
  const panels = circuitJson.filter(
26035
26103
  (e) => e.type === "pcb_panel"
@@ -26097,17 +26165,17 @@ function createPanelOutlineTextureForLayer({
26097
26165
  );
26098
26166
  }
26099
26167
  });
26100
- const texture = new THREE36.CanvasTexture(canvas);
26168
+ const texture = new THREE37.CanvasTexture(canvas);
26101
26169
  texture.generateMipmaps = true;
26102
- texture.minFilter = THREE36.LinearMipmapLinearFilter;
26103
- texture.magFilter = THREE36.LinearFilter;
26170
+ texture.minFilter = THREE37.LinearMipmapLinearFilter;
26171
+ texture.magFilter = THREE37.LinearFilter;
26104
26172
  texture.anisotropy = 16;
26105
26173
  texture.needsUpdate = true;
26106
26174
  return texture;
26107
26175
  }
26108
26176
 
26109
26177
  // src/utils/trace-texture.ts
26110
- import * as THREE37 from "three";
26178
+ import * as THREE38 from "three";
26111
26179
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer3 } from "circuit-to-canvas";
26112
26180
  import { getElementRenderLayers, su as su8 } from "@tscircuit/circuit-json-util";
26113
26181
  function createTraceTextureForLayer({
@@ -26193,10 +26261,10 @@ function createTraceTextureForLayer({
26193
26261
  drawSoldermaskTop: false,
26194
26262
  drawSoldermaskBottom: false
26195
26263
  });
26196
- const texture = new THREE37.CanvasTexture(canvas);
26264
+ const texture = new THREE38.CanvasTexture(canvas);
26197
26265
  texture.generateMipmaps = true;
26198
- texture.minFilter = THREE37.LinearMipmapLinearFilter;
26199
- texture.magFilter = THREE37.LinearFilter;
26266
+ texture.minFilter = THREE38.LinearMipmapLinearFilter;
26267
+ texture.magFilter = THREE38.LinearFilter;
26200
26268
  texture.anisotropy = 16;
26201
26269
  texture.needsUpdate = true;
26202
26270
  return texture;
@@ -26204,7 +26272,7 @@ function createTraceTextureForLayer({
26204
26272
 
26205
26273
  // src/textures/create-copper-pour-texture-for-layer.ts
26206
26274
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer4 } from "circuit-to-canvas";
26207
- import * as THREE38 from "three";
26275
+ import * as THREE39 from "three";
26208
26276
  var toRgb = (colorArr) => {
26209
26277
  const [r = 0, g = 0, b = 0] = colorArr;
26210
26278
  return `rgb(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(
@@ -26320,17 +26388,17 @@ function createCopperPourTextureForLayer({
26320
26388
  if (!onlyCoveredBySoldermask) {
26321
26389
  setColorAndDraw(uncoveredPours, uncoveredColor);
26322
26390
  }
26323
- const texture = new THREE38.CanvasTexture(canvas);
26391
+ const texture = new THREE39.CanvasTexture(canvas);
26324
26392
  texture.generateMipmaps = true;
26325
- texture.minFilter = THREE38.LinearMipmapLinearFilter;
26326
- texture.magFilter = THREE38.LinearFilter;
26393
+ texture.minFilter = THREE39.LinearMipmapLinearFilter;
26394
+ texture.magFilter = THREE39.LinearFilter;
26327
26395
  texture.anisotropy = 16;
26328
26396
  texture.needsUpdate = true;
26329
26397
  return texture;
26330
26398
  }
26331
26399
 
26332
26400
  // src/textures/create-copper-text-texture-for-layer.ts
26333
- import * as THREE39 from "three";
26401
+ import * as THREE40 from "three";
26334
26402
 
26335
26403
  // src/textures/copper-text/copper-text-drawing.ts
26336
26404
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer5 } from "circuit-to-canvas";
@@ -26445,17 +26513,17 @@ function createCopperTextTextureForLayer({
26445
26513
  elements,
26446
26514
  copperColor
26447
26515
  });
26448
- const texture = new THREE39.CanvasTexture(canvas);
26516
+ const texture = new THREE40.CanvasTexture(canvas);
26449
26517
  texture.generateMipmaps = true;
26450
- texture.minFilter = THREE39.LinearMipmapLinearFilter;
26451
- texture.magFilter = THREE39.LinearFilter;
26518
+ texture.minFilter = THREE40.LinearMipmapLinearFilter;
26519
+ texture.magFilter = THREE40.LinearFilter;
26452
26520
  texture.anisotropy = 16;
26453
26521
  texture.needsUpdate = true;
26454
26522
  return texture;
26455
26523
  }
26456
26524
 
26457
26525
  // src/textures/create-fabrication-note-texture-for-layer.ts
26458
- import * as THREE40 from "three";
26526
+ import * as THREE41 from "three";
26459
26527
 
26460
26528
  // src/textures/fabrication-note/fabrication-note-drawing.ts
26461
26529
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer6 } from "circuit-to-canvas";
@@ -26685,17 +26753,17 @@ function createFabricationNoteTextureForLayer({
26685
26753
  bounds,
26686
26754
  elements
26687
26755
  });
26688
- const texture = new THREE40.CanvasTexture(canvas);
26756
+ const texture = new THREE41.CanvasTexture(canvas);
26689
26757
  texture.generateMipmaps = true;
26690
- texture.minFilter = THREE40.LinearMipmapLinearFilter;
26691
- texture.magFilter = THREE40.LinearFilter;
26758
+ texture.minFilter = THREE41.LinearMipmapLinearFilter;
26759
+ texture.magFilter = THREE41.LinearFilter;
26692
26760
  texture.anisotropy = 16;
26693
26761
  texture.needsUpdate = true;
26694
26762
  return texture;
26695
26763
  }
26696
26764
 
26697
26765
  // src/textures/create-keepout-texture-for-layer.ts
26698
- import * as THREE41 from "three";
26766
+ import * as THREE42 from "three";
26699
26767
 
26700
26768
  // src/textures/keepout/keepout-drawing.ts
26701
26769
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer7 } from "circuit-to-canvas";
@@ -26770,17 +26838,17 @@ function createKeepoutTextureForLayer({
26770
26838
  elements,
26771
26839
  keepoutColor
26772
26840
  });
26773
- const texture = new THREE41.CanvasTexture(canvas);
26841
+ const texture = new THREE42.CanvasTexture(canvas);
26774
26842
  texture.generateMipmaps = true;
26775
- texture.minFilter = THREE41.LinearMipmapLinearFilter;
26776
- texture.magFilter = THREE41.LinearFilter;
26843
+ texture.minFilter = THREE42.LinearMipmapLinearFilter;
26844
+ texture.magFilter = THREE42.LinearFilter;
26777
26845
  texture.anisotropy = 16;
26778
26846
  texture.needsUpdate = true;
26779
26847
  return texture;
26780
26848
  }
26781
26849
 
26782
26850
  // src/textures/create-pcb-note-texture-for-layer.ts
26783
- import * as THREE42 from "three";
26851
+ import * as THREE43 from "three";
26784
26852
 
26785
26853
  // src/textures/pcb-note/pcb-note-drawing.ts
26786
26854
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer8 } from "circuit-to-canvas";
@@ -26934,17 +27002,17 @@ function createPcbNoteTextureForLayer({
26934
27002
  bounds,
26935
27003
  elements
26936
27004
  });
26937
- const texture = new THREE42.CanvasTexture(canvas);
27005
+ const texture = new THREE43.CanvasTexture(canvas);
26938
27006
  texture.generateMipmaps = true;
26939
- texture.minFilter = THREE42.LinearMipmapLinearFilter;
26940
- texture.magFilter = THREE42.LinearFilter;
27007
+ texture.minFilter = THREE43.LinearMipmapLinearFilter;
27008
+ texture.magFilter = THREE43.LinearFilter;
26941
27009
  texture.anisotropy = 16;
26942
27010
  texture.needsUpdate = true;
26943
27011
  return texture;
26944
27012
  }
26945
27013
 
26946
27014
  // src/textures/create-silkscreen-texture-for-layer.ts
26947
- import * as THREE43 from "three";
27015
+ import * as THREE44 from "three";
26948
27016
 
26949
27017
  // src/textures/silkscreen/silkscreen-drawing.ts
26950
27018
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer9 } from "circuit-to-canvas";
@@ -27095,21 +27163,21 @@ function createSilkscreenTextureForLayer({
27095
27163
  silkscreenColor,
27096
27164
  soldermaskVisible
27097
27165
  });
27098
- const texture = new THREE43.CanvasTexture(canvas);
27166
+ const texture = new THREE44.CanvasTexture(canvas);
27099
27167
  texture.generateMipmaps = true;
27100
- texture.minFilter = THREE43.LinearMipmapLinearFilter;
27101
- texture.magFilter = THREE43.LinearFilter;
27168
+ texture.minFilter = THREE44.LinearMipmapLinearFilter;
27169
+ texture.magFilter = THREE44.LinearFilter;
27102
27170
  texture.anisotropy = 16;
27103
27171
  texture.needsUpdate = true;
27104
27172
  return texture;
27105
27173
  }
27106
27174
 
27107
27175
  // src/textures/create-soldermask-texture-for-layer.ts
27108
- import * as THREE45 from "three";
27176
+ import * as THREE46 from "three";
27109
27177
 
27110
27178
  // src/textures/soldermask/soldermask-drawing.ts
27111
27179
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer10 } from "circuit-to-canvas";
27112
- import * as THREE44 from "three";
27180
+ import * as THREE45 from "three";
27113
27181
  var toRgb2 = (colorArr) => {
27114
27182
  const [r = 0, g = 0, b = 0] = colorArr;
27115
27183
  return `rgb(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(
@@ -27121,7 +27189,7 @@ var getSoldermaskPalette = (boardData) => {
27121
27189
  soldermaskColors[boardData.material] ?? colors.fr4SolderMaskGreen
27122
27190
  );
27123
27191
  const legacySoldermaskOverCopper = boardData.material === "fr1" ? toRgb2(colors.fr1TracesWithMaskCopper) : toRgb2(colors.fr4TracesWithMaskGreen);
27124
- const requestedSoldermaskColor = resolveSoldermaskColor(boardData.solder_mask_color) ?? (boardData.material === "flex" ? new THREE44.Color(toRgb2(colors.flexAmber)) : null);
27192
+ const requestedSoldermaskColor = resolveSoldermaskColor(boardData.solder_mask_color) ?? (boardData.material === "flex" ? new THREE45.Color(toRgb2(colors.flexAmber)) : null);
27125
27193
  if (!requestedSoldermaskColor) {
27126
27194
  return {
27127
27195
  soldermask: legacySoldermask,
@@ -27130,11 +27198,11 @@ var getSoldermaskPalette = (boardData) => {
27130
27198
  transparent: "rgba(0,0,0,0)"
27131
27199
  };
27132
27200
  }
27133
- const copperColor = new THREE44.Color().setRGB(
27201
+ const copperColor = new THREE45.Color().setRGB(
27134
27202
  colors.copper[0],
27135
27203
  colors.copper[1],
27136
27204
  colors.copper[2],
27137
- THREE44.SRGBColorSpace
27205
+ THREE45.SRGBColorSpace
27138
27206
  );
27139
27207
  return {
27140
27208
  soldermask: soldermaskColorToCss(requestedSoldermaskColor),
@@ -27269,17 +27337,17 @@ function createSoldermaskTextureForLayer({
27269
27337
  elements,
27270
27338
  boardData
27271
27339
  });
27272
- const texture = new THREE45.CanvasTexture(canvas);
27340
+ const texture = new THREE46.CanvasTexture(canvas);
27273
27341
  texture.generateMipmaps = true;
27274
- texture.minFilter = THREE45.LinearMipmapLinearFilter;
27275
- texture.magFilter = THREE45.LinearFilter;
27342
+ texture.minFilter = THREE46.LinearMipmapLinearFilter;
27343
+ texture.magFilter = THREE46.LinearFilter;
27276
27344
  texture.anisotropy = 16;
27277
27345
  texture.needsUpdate = true;
27278
27346
  return texture;
27279
27347
  }
27280
27348
 
27281
27349
  // src/textures/create-through-hole-texture-for-layer.ts
27282
- import * as THREE46 from "three";
27350
+ import * as THREE47 from "three";
27283
27351
 
27284
27352
  // src/textures/through-hole/through-hole-drawing.ts
27285
27353
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer11 } from "circuit-to-canvas";
@@ -27374,10 +27442,10 @@ function createThroughHoleTextureForLayer({
27374
27442
  elements,
27375
27443
  copperColor
27376
27444
  });
27377
- const texture = new THREE46.CanvasTexture(canvas);
27445
+ const texture = new THREE47.CanvasTexture(canvas);
27378
27446
  texture.generateMipmaps = true;
27379
- texture.minFilter = THREE46.LinearMipmapLinearFilter;
27380
- texture.magFilter = THREE46.LinearFilter;
27447
+ texture.minFilter = THREE47.LinearMipmapLinearFilter;
27448
+ texture.magFilter = THREE47.LinearFilter;
27381
27449
  texture.anisotropy = 16;
27382
27450
  texture.needsUpdate = true;
27383
27451
  return texture;
@@ -27499,10 +27567,10 @@ var createCombinedTexture = ({
27499
27567
  applySoldermaskSurfaceFilter(ctx, canvasWidth, canvasHeight, {
27500
27568
  includeReflection: layer === "top"
27501
27569
  });
27502
- const combinedTexture = new THREE47.CanvasTexture(canvas);
27570
+ const combinedTexture = new THREE48.CanvasTexture(canvas);
27503
27571
  combinedTexture.generateMipmaps = false;
27504
- combinedTexture.minFilter = THREE47.LinearFilter;
27505
- combinedTexture.magFilter = THREE47.LinearFilter;
27572
+ combinedTexture.minFilter = THREE48.LinearFilter;
27573
+ combinedTexture.magFilter = THREE48.LinearFilter;
27506
27574
  combinedTexture.premultiplyAlpha = true;
27507
27575
  combinedTexture.anisotropy = 16;
27508
27576
  combinedTexture.needsUpdate = true;
@@ -27538,11 +27606,11 @@ var createMaskedCopperMask = ({
27538
27606
  height
27539
27607
  );
27540
27608
  ctx.globalCompositeOperation = "source-over";
27541
- const maskTexture = new THREE47.CanvasTexture(canvas);
27542
- maskTexture.colorSpace = THREE47.NoColorSpace;
27609
+ const maskTexture = new THREE48.CanvasTexture(canvas);
27610
+ maskTexture.colorSpace = THREE48.NoColorSpace;
27543
27611
  maskTexture.generateMipmaps = false;
27544
- maskTexture.minFilter = THREE47.LinearFilter;
27545
- maskTexture.magFilter = THREE47.LinearFilter;
27612
+ maskTexture.minFilter = THREE48.LinearFilter;
27613
+ maskTexture.magFilter = THREE48.LinearFilter;
27546
27614
  maskTexture.premultiplyAlpha = false;
27547
27615
  maskTexture.needsUpdate = true;
27548
27616
  return maskTexture;
@@ -27692,7 +27760,7 @@ function createCombinedBoardTextures({
27692
27760
  }
27693
27761
 
27694
27762
  // src/textures/create-three-texture-meshes.ts
27695
- import * as THREE49 from "three";
27763
+ import * as THREE50 from "three";
27696
27764
 
27697
27765
  // src/board-surface-textures.ts
27698
27766
  var REALISTIC_BOARD_SURFACE_MATERIAL = {
@@ -27715,7 +27783,7 @@ var PAD_COPPER_TEXTURE_MATERIAL = {
27715
27783
  };
27716
27784
 
27717
27785
  // src/utils/create-board-relief-textures.ts
27718
- import * as THREE48 from "three";
27786
+ import * as THREE49 from "three";
27719
27787
  var PLAIN_SOLDERMASK_HEIGHT = 0.22;
27720
27788
  var MASKED_COPPER_HEIGHT = 0.7;
27721
27789
  var EXPOSED_COPPER_HEIGHT = 0.86;
@@ -27810,13 +27878,13 @@ var getBoardSurfaceProfile = (r, g, b, hasMaskedCopper) => {
27810
27878
  return PLAIN_SOLDERMASK_PROFILE;
27811
27879
  };
27812
27880
  var createDataTexture = (canvas) => {
27813
- const texture = new THREE48.CanvasTexture(canvas);
27814
- texture.colorSpace = THREE48.NoColorSpace;
27881
+ const texture = new THREE49.CanvasTexture(canvas);
27882
+ texture.colorSpace = THREE49.NoColorSpace;
27815
27883
  texture.generateMipmaps = false;
27816
- texture.minFilter = THREE48.LinearFilter;
27817
- texture.magFilter = THREE48.LinearFilter;
27818
- texture.wrapS = THREE48.ClampToEdgeWrapping;
27819
- texture.wrapT = THREE48.ClampToEdgeWrapping;
27884
+ texture.minFilter = THREE49.LinearFilter;
27885
+ texture.magFilter = THREE49.LinearFilter;
27886
+ texture.wrapS = THREE49.ClampToEdgeWrapping;
27887
+ texture.wrapT = THREE49.ClampToEdgeWrapping;
27820
27888
  texture.needsUpdate = true;
27821
27889
  return texture;
27822
27890
  };
@@ -27940,16 +28008,16 @@ function createTexturePlane(config, boardData) {
27940
28008
  } = config;
27941
28009
  if (!texture) return null;
27942
28010
  const boardOutlineBounds = calculateOutlineBounds(boardData);
27943
- const planeGeom = new THREE49.PlaneGeometry(
28011
+ const planeGeom = new THREE50.PlaneGeometry(
27944
28012
  boardOutlineBounds.width,
27945
28013
  boardOutlineBounds.height
27946
28014
  );
27947
- texture.colorSpace = THREE49.SRGBColorSpace;
28015
+ texture.colorSpace = THREE50.SRGBColorSpace;
27948
28016
  const sharedMaterialOptions = {
27949
28017
  map: texture,
27950
28018
  transparent: true,
27951
28019
  alphaTest: 0.08,
27952
- side: THREE49.FrontSide,
28020
+ side: THREE50.FrontSide,
27953
28021
  depthWrite: true,
27954
28022
  polygonOffset: usePolygonOffset,
27955
28023
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
@@ -27958,12 +28026,12 @@ function createTexturePlane(config, boardData) {
27958
28026
  opacity: isFaux ? FAUX_BOARD_OPACITY : 1
27959
28027
  };
27960
28028
  const reliefTextures = createBoardReliefTextures(texture, maskedCopperMask);
27961
- const material = new THREE49.MeshPhysicalMaterial({
28029
+ const material = new THREE50.MeshPhysicalMaterial({
27962
28030
  ...sharedMaterialOptions,
27963
28031
  bumpMap: reliefTextures?.bumpMap ?? null,
27964
28032
  bumpScale: REALISTIC_BOARD_SURFACE_MATERIAL.bumpScale,
27965
28033
  normalMap: reliefTextures?.normalMap ?? null,
27966
- normalScale: new THREE49.Vector2(
28034
+ normalScale: new THREE50.Vector2(
27967
28035
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale,
27968
28036
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale
27969
28037
  ),
@@ -27977,7 +28045,7 @@ function createTexturePlane(config, boardData) {
27977
28045
  clearcoatRoughness: REALISTIC_BOARD_SURFACE_MATERIAL.clearcoatRoughness,
27978
28046
  envMapIntensity: 0.18
27979
28047
  });
27980
- const mesh = new THREE49.Mesh(planeGeom, material);
28048
+ const mesh = new THREE50.Mesh(planeGeom, material);
27981
28049
  mesh.position.set(
27982
28050
  boardOutlineBounds.centerX,
27983
28051
  boardOutlineBounds.centerY,
@@ -28025,10 +28093,10 @@ function createTextureMeshes(textures, boardData, pcbThickness, isFaux = false)
28025
28093
  }
28026
28094
 
28027
28095
  // src/three-components/JscadBoardTextures.tsx
28028
- import * as THREE50 from "three";
28096
+ import * as THREE51 from "three";
28029
28097
 
28030
28098
  // src/hooks/useBoardTextureVisibility.ts
28031
- import { useMemo as useMemo22 } from "react";
28099
+ import { useMemo as useMemo23 } from "react";
28032
28100
  var useBoardTextureVisibility = (visibility) => {
28033
28101
  const {
28034
28102
  boardBody,
@@ -28041,7 +28109,7 @@ var useBoardTextureVisibility = (visibility) => {
28041
28109
  keepout,
28042
28110
  pcbNotes
28043
28111
  } = visibility;
28044
- return useMemo22(
28112
+ return useMemo23(
28045
28113
  () => ({
28046
28114
  boardBody,
28047
28115
  topCopper,
@@ -28103,7 +28171,7 @@ function JscadBoardTextures({
28103
28171
  const { rootObject } = useThree();
28104
28172
  const { visibility } = useLayerVisibility();
28105
28173
  const textureVisibility = useBoardTextureVisibility(visibility);
28106
- const boardData = useMemo23(() => {
28174
+ const boardData = useMemo24(() => {
28107
28175
  const panels = circuitJson.filter(
28108
28176
  (e) => e.type === "pcb_panel"
28109
28177
  );
@@ -28130,11 +28198,11 @@ function JscadBoardTextures({
28130
28198
  );
28131
28199
  return boardsNotInPanel.length > 0 ? boardsNotInPanel[0] : null;
28132
28200
  }, [circuitJson]);
28133
- const traceTextureResolution = useMemo23(() => {
28201
+ const traceTextureResolution = useMemo24(() => {
28134
28202
  if (!boardData) return TRACE_TEXTURE_RESOLUTION;
28135
28203
  return getLayerTextureResolution(boardData, TRACE_TEXTURE_RESOLUTION);
28136
28204
  }, [boardData]);
28137
- const textures = useMemo23(() => {
28205
+ const textures = useMemo24(() => {
28138
28206
  if (!boardData?.width || !boardData.height) return null;
28139
28207
  return createCombinedBoardTextures({
28140
28208
  circuitJson,
@@ -28143,7 +28211,7 @@ function JscadBoardTextures({
28143
28211
  visibility: textureVisibility
28144
28212
  });
28145
28213
  }, [circuitJson, boardData, traceTextureResolution, textureVisibility]);
28146
- useEffect30(() => {
28214
+ useEffect31(() => {
28147
28215
  if (!rootObject || !boardData || !textures) return;
28148
28216
  const meshes = [];
28149
28217
  const disposeTextureMaterial = (material) => {
@@ -28163,7 +28231,7 @@ function JscadBoardTextures({
28163
28231
  const typedMaterial = material;
28164
28232
  for (const prop of textureProps) {
28165
28233
  const texture = typedMaterial[prop];
28166
- if (texture && texture instanceof THREE50.Texture) {
28234
+ if (texture && texture instanceof THREE51.Texture) {
28167
28235
  texture.dispose();
28168
28236
  typedMaterial[prop] = null;
28169
28237
  }
@@ -28182,16 +28250,16 @@ function JscadBoardTextures({
28182
28250
  }) => {
28183
28251
  if (!texture) return null;
28184
28252
  const boardOutlineBounds = calculateOutlineBounds(boardData);
28185
- const planeGeom = new THREE50.PlaneGeometry(
28253
+ const planeGeom = new THREE51.PlaneGeometry(
28186
28254
  boardOutlineBounds.width,
28187
28255
  boardOutlineBounds.height
28188
28256
  );
28189
- texture.colorSpace = THREE50.SRGBColorSpace;
28257
+ texture.colorSpace = THREE51.SRGBColorSpace;
28190
28258
  const sharedMaterialOptions = {
28191
28259
  map: texture,
28192
28260
  transparent: true,
28193
28261
  alphaTest: 0.08,
28194
- side: THREE50.FrontSide,
28262
+ side: THREE51.FrontSide,
28195
28263
  depthWrite,
28196
28264
  polygonOffset: usePolygonOffset,
28197
28265
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
@@ -28202,12 +28270,12 @@ function JscadBoardTextures({
28202
28270
  texture,
28203
28271
  maskedCopperMask
28204
28272
  );
28205
- const material = new THREE50.MeshPhysicalMaterial({
28273
+ const material = new THREE51.MeshPhysicalMaterial({
28206
28274
  ...sharedMaterialOptions,
28207
28275
  bumpMap: reliefTextures?.bumpMap ?? null,
28208
28276
  bumpScale: REALISTIC_BOARD_SURFACE_MATERIAL.bumpScale,
28209
28277
  normalMap: reliefTextures?.normalMap ?? null,
28210
- normalScale: new THREE50.Vector2(
28278
+ normalScale: new THREE51.Vector2(
28211
28279
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale,
28212
28280
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale
28213
28281
  ),
@@ -28219,7 +28287,7 @@ function JscadBoardTextures({
28219
28287
  clearcoatRoughness: REALISTIC_BOARD_SURFACE_MATERIAL.clearcoatRoughness,
28220
28288
  envMapIntensity: 0.18
28221
28289
  });
28222
- const mesh = new THREE50.Mesh(planeGeom, material);
28290
+ const mesh = new THREE51.Mesh(planeGeom, material);
28223
28291
  mesh.position.set(
28224
28292
  boardOutlineBounds.centerX,
28225
28293
  boardOutlineBounds.centerY,
@@ -28269,7 +28337,7 @@ function JscadBoardTextures({
28269
28337
  for (const material of mesh.material) {
28270
28338
  disposeTextureMaterial(material);
28271
28339
  }
28272
- } else if (mesh.material instanceof THREE50.Material) {
28340
+ } else if (mesh.material instanceof THREE51.Material) {
28273
28341
  disposeTextureMaterial(mesh.material);
28274
28342
  }
28275
28343
  }
@@ -28281,8 +28349,8 @@ function JscadBoardTextures({
28281
28349
  }
28282
28350
 
28283
28351
  // src/three-components/STLModel.tsx
28284
- import { useState as useState19, useEffect as useEffect31, useMemo as useMemo24 } from "react";
28285
- import * as THREE51 from "three";
28352
+ import { useState as useState19, useEffect as useEffect32, useMemo as useMemo25 } from "react";
28353
+ import * as THREE52 from "three";
28286
28354
  import { STLLoader as STLLoader2 } from "three-stdlib";
28287
28355
  function STLModel({
28288
28356
  stlUrl,
@@ -28294,7 +28362,7 @@ function STLModel({
28294
28362
  }) {
28295
28363
  const { rootObject } = useThree();
28296
28364
  const [geom, setGeom] = useState19(null);
28297
- useEffect31(() => {
28365
+ useEffect32(() => {
28298
28366
  const loader = new STLLoader2();
28299
28367
  if (stlData) {
28300
28368
  try {
@@ -28312,18 +28380,18 @@ function STLModel({
28312
28380
  });
28313
28381
  }
28314
28382
  }, [stlUrl, stlData]);
28315
- const mesh = useMemo24(() => {
28383
+ const mesh = useMemo25(() => {
28316
28384
  if (!geom) return null;
28317
28385
  const isBoardLayer = layerType === "board";
28318
- const material = new THREE51.MeshStandardMaterial({
28319
- color: Array.isArray(color) ? new THREE51.Color(color[0], color[1], color[2]) : color,
28386
+ const material = new THREE52.MeshStandardMaterial({
28387
+ color: Array.isArray(color) ? new THREE52.Color(color[0], color[1], color[2]) : color,
28320
28388
  transparent: opacity !== 1,
28321
28389
  opacity,
28322
28390
  polygonOffset: isBoardLayer,
28323
28391
  polygonOffsetFactor: isBoardLayer ? 6 : 0,
28324
28392
  polygonOffsetUnits: isBoardLayer ? 6 : 0
28325
28393
  });
28326
- const createdMesh = new THREE51.Mesh(geom, material);
28394
+ const createdMesh = new THREE52.Mesh(geom, material);
28327
28395
  createdMesh.renderOrder = isBoardLayer ? -1 : 1;
28328
28396
  configureObjectShadows(createdMesh, {
28329
28397
  castShadow: !isBoardLayer && opacity === 1,
@@ -28331,7 +28399,7 @@ function STLModel({
28331
28399
  });
28332
28400
  return createdMesh;
28333
28401
  }, [geom, color, opacity, layerType]);
28334
- useEffect31(() => {
28402
+ useEffect32(() => {
28335
28403
  if (!rootObject || !mesh) return;
28336
28404
  rootObject.add(mesh);
28337
28405
  return () => {
@@ -28348,7 +28416,7 @@ function STLModel({
28348
28416
  }
28349
28417
 
28350
28418
  // src/three-components/VisibleSTLModel.tsx
28351
- import { jsx as jsx20 } from "react/jsx-runtime";
28419
+ import { jsx as jsx21 } from "react/jsx-runtime";
28352
28420
  function VisibleSTLModel({
28353
28421
  stlData,
28354
28422
  color,
@@ -28371,7 +28439,7 @@ function VisibleSTLModel({
28371
28439
  if (!shouldShow) {
28372
28440
  return null;
28373
28441
  }
28374
- return /* @__PURE__ */ jsx20(
28442
+ return /* @__PURE__ */ jsx21(
28375
28443
  STLModel,
28376
28444
  {
28377
28445
  stlData,
@@ -28385,8 +28453,8 @@ function VisibleSTLModel({
28385
28453
  // src/three-components/CadCable.tsx
28386
28454
  import { parseCableString } from "@tscircuit/cableprinter";
28387
28455
  import { createCableMeshes } from "jscad-electronics/cables";
28388
- import { useEffect as useEffect32, useMemo as useMemo25 } from "react";
28389
- import * as THREE52 from "three";
28456
+ import { useEffect as useEffect33, useMemo as useMemo26 } from "react";
28457
+ import * as THREE53 from "three";
28390
28458
  var isCadCableElement = (element) => {
28391
28459
  if (!element || typeof element !== "object") return false;
28392
28460
  const candidate = element;
@@ -28403,14 +28471,14 @@ var getConnectorPin1Side = ({
28403
28471
  const endpoint = end === "start" ? path[0] : path[path.length - 1];
28404
28472
  const adjacent = end === "start" ? path[1] : path[path.length - 2];
28405
28473
  if (!endpoint || !adjacent) return void 0;
28406
- const cableAxis = new THREE52.Vector3(
28474
+ const cableAxis = new THREE53.Vector3(
28407
28475
  adjacent.x - endpoint.x,
28408
28476
  adjacent.y - endpoint.y,
28409
28477
  adjacent.z - endpoint.z
28410
28478
  );
28411
28479
  if (cableAxis.lengthSq() < 1e-12) return void 0;
28412
28480
  cableAxis.normalize();
28413
- const pin1Side = new THREE52.Vector3(
28481
+ const pin1Side = new THREE53.Vector3(
28414
28482
  pin1Position.x - endpoint.x,
28415
28483
  pin1Position.y - endpoint.y,
28416
28484
  pin1Position.z - endpoint.z
@@ -28436,28 +28504,28 @@ var createCadCableObject = (cable) => {
28436
28504
  end: "end"
28437
28505
  })
28438
28506
  });
28439
- const group = new THREE52.Group();
28507
+ const group = new THREE53.Group();
28440
28508
  group.name = `cad-cable-${cable.cad_cable_id}`;
28441
- group.userData = { cadCableId: cable.cad_cable_id, name: cable.name };
28509
+ group.userData = { cad_cable_id: cable.cad_cable_id, name: cable.name };
28442
28510
  for (const cableMesh of cableMeshes) {
28443
- let geometry = new THREE52.BufferGeometry();
28511
+ let geometry = new THREE53.BufferGeometry();
28444
28512
  geometry.setAttribute(
28445
28513
  "position",
28446
- new THREE52.Float32BufferAttribute(cableMesh.positions, 3)
28514
+ new THREE53.Float32BufferAttribute(cableMesh.positions, 3)
28447
28515
  );
28448
28516
  geometry.setIndex(cableMesh.indices);
28449
28517
  if (!cableMesh.smooth) geometry = geometry.toNonIndexed();
28450
28518
  geometry.computeVertexNormals();
28451
28519
  const [red, green, blue, alpha] = cableMesh.color;
28452
- const material = new THREE52.MeshStandardMaterial({
28453
- color: new THREE52.Color(red, green, blue),
28520
+ const material = new THREE53.MeshStandardMaterial({
28521
+ color: new THREE53.Color(red, green, blue),
28454
28522
  metalness: cableMesh.material?.metalness ?? 0,
28455
28523
  roughness: cableMesh.material?.roughness ?? 0.7,
28456
28524
  opacity: alpha,
28457
28525
  transparent: alpha < 1,
28458
- side: THREE52.DoubleSide
28526
+ side: THREE53.DoubleSide
28459
28527
  });
28460
- const mesh = new THREE52.Mesh(geometry, material);
28528
+ const mesh = new THREE53.Mesh(geometry, material);
28461
28529
  mesh.name = `${group.name}:${cableMesh.name}`;
28462
28530
  configureObjectShadows(mesh, { castShadow: true, receiveShadow: true });
28463
28531
  group.add(mesh);
@@ -28466,7 +28534,7 @@ var createCadCableObject = (cable) => {
28466
28534
  };
28467
28535
  var disposeCadCableObject = (group) => {
28468
28536
  group.traverse((object) => {
28469
- if (!(object instanceof THREE52.Mesh)) return;
28537
+ if (!(object instanceof THREE53.Mesh)) return;
28470
28538
  object.geometry.dispose();
28471
28539
  const materials2 = Array.isArray(object.material) ? object.material : [object.material];
28472
28540
  for (const material of materials2) material.dispose();
@@ -28474,7 +28542,7 @@ var disposeCadCableObject = (group) => {
28474
28542
  };
28475
28543
  var CadCable = ({ cable }) => {
28476
28544
  const { rootObject } = useThree();
28477
- const cableObject = useMemo25(() => {
28545
+ const cableObject = useMemo26(() => {
28478
28546
  try {
28479
28547
  return createCadCableObject(cable);
28480
28548
  } catch (error) {
@@ -28482,7 +28550,7 @@ var CadCable = ({ cable }) => {
28482
28550
  return null;
28483
28551
  }
28484
28552
  }, [cable]);
28485
- useEffect32(() => {
28553
+ useEffect33(() => {
28486
28554
  if (!cableObject) return;
28487
28555
  rootObject.add(cableObject);
28488
28556
  return () => {
@@ -28598,7 +28666,7 @@ function addFauxBoardIfNeeded(circuitJson) {
28598
28666
  }
28599
28667
 
28600
28668
  // src/CadViewerJscad.tsx
28601
- import { jsx as jsx21, jsxs as jsxs6 } from "react/jsx-runtime";
28669
+ import { jsx as jsx22, jsxs as jsxs6 } from "react/jsx-runtime";
28602
28670
  var CadViewerJscad = forwardRef3(
28603
28671
  ({
28604
28672
  circuitJson,
@@ -28609,16 +28677,16 @@ var CadViewerJscad = forwardRef3(
28609
28677
  onCameraControllerReady,
28610
28678
  resolveStaticAsset,
28611
28679
  referenceObject,
28612
- hiddenCadComponentIds
28680
+ objectVisibility
28613
28681
  }, ref) => {
28614
28682
  const childrenSoup = useConvertChildrenToCircuitJson(children);
28615
- const internalCircuitJson = useMemo26(() => {
28683
+ const internalCircuitJson = useMemo27(() => {
28616
28684
  return addFauxBoardIfNeeded(
28617
28685
  circuitJson ?? childrenSoup
28618
28686
  );
28619
28687
  }, [circuitJson, childrenSoup]);
28620
28688
  const boardGeom = useBoardGeomBuilder(internalCircuitJson);
28621
- const isFauxBoard = useMemo26(() => {
28689
+ const isFauxBoard = useMemo27(() => {
28622
28690
  if (!internalCircuitJson) return false;
28623
28691
  try {
28624
28692
  const board = su12(internalCircuitJson).pcb_board.list()[0];
@@ -28627,7 +28695,7 @@ var CadViewerJscad = forwardRef3(
28627
28695
  return false;
28628
28696
  }
28629
28697
  }, [internalCircuitJson]);
28630
- const boardDimensions = useMemo26(() => {
28698
+ const boardDimensions = useMemo27(() => {
28631
28699
  if (!internalCircuitJson) return void 0;
28632
28700
  try {
28633
28701
  const board = su12(internalCircuitJson).pcb_board.list()[0];
@@ -28639,7 +28707,7 @@ var CadViewerJscad = forwardRef3(
28639
28707
  return void 0;
28640
28708
  }
28641
28709
  }, [internalCircuitJson]);
28642
- const boardCenter = useMemo26(() => {
28710
+ const boardCenter = useMemo27(() => {
28643
28711
  if (!internalCircuitJson) return void 0;
28644
28712
  try {
28645
28713
  const board = su12(internalCircuitJson).pcb_board.list()[0];
@@ -28651,7 +28719,7 @@ var CadViewerJscad = forwardRef3(
28651
28719
  return void 0;
28652
28720
  }
28653
28721
  }, [internalCircuitJson]);
28654
- const cameraSessionScope = useMemo26(() => {
28722
+ const cameraSessionScope = useMemo27(() => {
28655
28723
  if (!internalCircuitJson) return void 0;
28656
28724
  const board = su12(internalCircuitJson).pcb_board.list()[0];
28657
28725
  if (!board) return void 0;
@@ -28661,13 +28729,20 @@ var CadViewerJscad = forwardRef3(
28661
28729
  dimensions: boardDimensions
28662
28730
  });
28663
28731
  }, [internalCircuitJson, boardCenter, boardDimensions]);
28664
- const initialCameraPosition = useMemo26(() => {
28732
+ const initialCameraPosition = useMemo27(() => {
28665
28733
  return getInitialCameraPosition({ boardDimensions, boardCenter });
28666
28734
  }, [boardDimensions, boardCenter]);
28667
28735
  const pcbThickness = usePcbThickness(internalCircuitJson);
28668
28736
  const { stls: boardStls, loading } = useStlsFromGeom(boardGeom);
28669
- const cad_components = su12(internalCircuitJson).cad_component.list().filter((cad) => !hiddenCadComponentIds?.has(cad.cad_component_id));
28670
- const cadCables = getCadCables(internalCircuitJson);
28737
+ const renderedBoardId = useMemo27(() => {
28738
+ const panel = internalCircuitJson.find((e) => e.type === "pcb_panel");
28739
+ if (panel?.type === "pcb_panel") return panel.pcb_panel_id;
28740
+ return su12(internalCircuitJson).pcb_board.list().find((board) => !board.pcb_panel_id)?.pcb_board_id;
28741
+ }, [internalCircuitJson]);
28742
+ const cad_components = su12(internalCircuitJson).cad_component.list().filter((cad) => !isObjectHidden(objectVisibility, cad.cad_component_id));
28743
+ const cadCables = getCadCables(internalCircuitJson).filter(
28744
+ (cable) => !isObjectHidden(objectVisibility, cable.cad_cable_id)
28745
+ );
28671
28746
  return /* @__PURE__ */ jsxs6(
28672
28747
  CadViewerContainer,
28673
28748
  {
@@ -28682,29 +28757,38 @@ var CadViewerJscad = forwardRef3(
28682
28757
  onUserInteraction,
28683
28758
  onCameraControllerReady,
28684
28759
  children: [
28685
- boardStls.map(({ stlData, color, layerType }, index2) => /* @__PURE__ */ jsx21(
28686
- VisibleSTLModel,
28760
+ /* @__PURE__ */ jsxs6(
28761
+ BoardGroup,
28687
28762
  {
28688
- stlData,
28689
- color,
28690
- opacity: index2 === 0 ? isFauxBoard ? 0.8 : 0.95 : 1,
28691
- layerType
28692
- },
28693
- `board-${index2}`
28694
- )),
28695
- /* @__PURE__ */ jsx21(
28696
- JscadBoardTextures,
28697
- {
28698
- circuitJson: internalCircuitJson,
28699
- pcbThickness,
28700
- isFaux: isFauxBoard
28763
+ pcbBoardId: renderedBoardId,
28764
+ hidden: isObjectHidden(objectVisibility, renderedBoardId),
28765
+ children: [
28766
+ boardStls.map(({ stlData, color, layerType }, index2) => /* @__PURE__ */ jsx22(
28767
+ VisibleSTLModel,
28768
+ {
28769
+ stlData,
28770
+ color,
28771
+ opacity: index2 === 0 ? isFauxBoard ? 0.8 : 0.95 : 1,
28772
+ layerType
28773
+ },
28774
+ `board-${index2}`
28775
+ )),
28776
+ /* @__PURE__ */ jsx22(
28777
+ JscadBoardTextures,
28778
+ {
28779
+ circuitJson: internalCircuitJson,
28780
+ pcbThickness,
28781
+ isFaux: isFauxBoard
28782
+ }
28783
+ )
28784
+ ]
28701
28785
  }
28702
28786
  ),
28703
- cad_components.map((cad_component) => /* @__PURE__ */ jsx21(
28787
+ cad_components.map((cad_component) => /* @__PURE__ */ jsx22(
28704
28788
  ThreeErrorBoundary,
28705
28789
  {
28706
- fallback: ({ error }) => /* @__PURE__ */ jsx21(Error3d, { cad_component, error }),
28707
- children: /* @__PURE__ */ jsx21(
28790
+ fallback: ({ error }) => /* @__PURE__ */ jsx22(Error3d, { cad_component, error }),
28791
+ children: /* @__PURE__ */ jsx22(
28708
28792
  AnyCadComponent,
28709
28793
  {
28710
28794
  cad_component,
@@ -28716,7 +28800,7 @@ var CadViewerJscad = forwardRef3(
28716
28800
  },
28717
28801
  cad_component.cad_component_id
28718
28802
  )),
28719
- cadCables.map((cable) => /* @__PURE__ */ jsx21(CadCable, { cable }, cable.cad_cable_id))
28803
+ cadCables.map((cable) => /* @__PURE__ */ jsx22(CadCable, { cable }, cable.cad_cable_id))
28720
28804
  ]
28721
28805
  }
28722
28806
  );
@@ -29977,13 +30061,13 @@ function createStiffenerMesh({
29977
30061
  }
29978
30062
 
29979
30063
  // src/CadViewerManifold.tsx
29980
- import { useEffect as useEffect34, useMemo as useMemo28, useState as useState21 } from "react";
29981
- import * as THREE60 from "three";
30064
+ import { useEffect as useEffect35, useMemo as useMemo29, useState as useState21 } from "react";
30065
+ import * as THREE61 from "three";
29982
30066
 
29983
30067
  // src/hooks/useManifoldBoardBuilder.ts
29984
30068
  import { su as su16 } from "@tscircuit/circuit-json-util";
29985
- import { useEffect as useEffect33, useMemo as useMemo27, useRef as useRef10, useState as useState20 } from "react";
29986
- import * as THREE56 from "three";
30069
+ import { useEffect as useEffect34, useMemo as useMemo28, useRef as useRef10, useState as useState20 } from "react";
30070
+ import * as THREE57 from "three";
29987
30071
 
29988
30072
  // src/utils/manifold/create-manifold-board.ts
29989
30073
  var arePointsClockwise2 = (points) => {
@@ -30332,17 +30416,17 @@ function processNonPlatedHolesForManifold(Manifold, CrossSection, circuitJson, p
30332
30416
 
30333
30417
  // src/utils/manifold/process-plated-holes.ts
30334
30418
  import { su as su15 } from "@tscircuit/circuit-json-util";
30335
- import * as THREE54 from "three";
30419
+ import * as THREE55 from "three";
30336
30420
 
30337
30421
  // src/utils/manifold-mesh-to-three-geometry.ts
30338
- import * as THREE53 from "three";
30422
+ import * as THREE54 from "three";
30339
30423
  function manifoldMeshToThreeGeometry(manifoldMesh) {
30340
- const geometry = new THREE53.BufferGeometry();
30424
+ const geometry = new THREE54.BufferGeometry();
30341
30425
  geometry.setAttribute(
30342
30426
  "position",
30343
- new THREE53.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
30427
+ new THREE54.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
30344
30428
  );
30345
- geometry.setIndex(new THREE53.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
30429
+ geometry.setIndex(new THREE54.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
30346
30430
  if (manifoldMesh.runIndex && manifoldMesh.runIndex.length > 1 && manifoldMesh.runOriginalID) {
30347
30431
  for (let i = 0; i < manifoldMesh.runIndex.length - 1; i++) {
30348
30432
  const start = manifoldMesh.runIndex[i];
@@ -30376,7 +30460,7 @@ var createEllipsePoints = (width, height, segments) => {
30376
30460
  }
30377
30461
  return points;
30378
30462
  };
30379
- var COPPER_COLOR = new THREE54.Color(...colors.copper);
30463
+ var COPPER_COLOR = new THREE55.Color(...colors.copper);
30380
30464
  var PLATED_HOLE_LIP_HEIGHT = 0.05;
30381
30465
  var PLATED_HOLE_PAD_THICKNESS = 3e-3;
30382
30466
  var PLATED_HOLE_SURFACE_CLEARANCE = 5e-4;
@@ -31016,7 +31100,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
31016
31100
  }
31017
31101
 
31018
31102
  // src/utils/manifold/process-vias.ts
31019
- import * as THREE55 from "three";
31103
+ import * as THREE56 from "three";
31020
31104
 
31021
31105
  // src/utils/via-geoms.ts
31022
31106
  function createViaCopper2({
@@ -31054,7 +31138,7 @@ function createViaCopper2({
31054
31138
  }
31055
31139
 
31056
31140
  // src/utils/manifold/process-vias.ts
31057
- var COPPER_COLOR2 = new THREE55.Color(...colors.copper);
31141
+ var COPPER_COLOR2 = new THREE56.Color(...colors.copper);
31058
31142
  function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume, otherHoleDrills = []) {
31059
31143
  const viaBoardDrills = [];
31060
31144
  const pcbVias = getPcbVias(circuitJson);
@@ -31138,7 +31222,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
31138
31222
  const [error, setError] = useState20(null);
31139
31223
  const [isLoading, setIsLoading] = useState20(true);
31140
31224
  const manifoldInstancesForCleanup = useRef10([]);
31141
- const boardData = useMemo27(() => {
31225
+ const boardData = useMemo28(() => {
31142
31226
  const panels = circuitJson.filter(
31143
31227
  (e) => e.type === "pcb_panel"
31144
31228
  );
@@ -31163,15 +31247,15 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
31163
31247
  const boardsNotInPanel = boards.filter((b) => !b.pcb_panel_id);
31164
31248
  return boardsNotInPanel.length > 0 ? boardsNotInPanel[0] : null;
31165
31249
  }, [circuitJson]);
31166
- const isFauxBoard = useMemo27(() => {
31250
+ const isFauxBoard = useMemo28(() => {
31167
31251
  const boards = su16(circuitJson).pcb_board.list();
31168
31252
  return boards.length > 0 && boards[0].pcb_board_id === "faux-board";
31169
31253
  }, [circuitJson]);
31170
- const traceTextureResolution = useMemo27(() => {
31254
+ const traceTextureResolution = useMemo28(() => {
31171
31255
  if (!boardData) return TRACE_TEXTURE_RESOLUTION;
31172
31256
  return getLayerTextureResolution(boardData, TRACE_TEXTURE_RESOLUTION);
31173
31257
  }, [boardData]);
31174
- useEffect33(() => {
31258
+ useEffect34(() => {
31175
31259
  if (!manifoldJSModule || !boardData) {
31176
31260
  setGeoms(null);
31177
31261
  setPcbThickness(null);
@@ -31302,7 +31386,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
31302
31386
  {
31303
31387
  key: "plated-holes-union",
31304
31388
  geometry: cutPlatedGeom,
31305
- color: new THREE56.Color(
31389
+ color: new THREE57.Color(
31306
31390
  colors.copper[0],
31307
31391
  colors.copper[1],
31308
31392
  colors.copper[2]
@@ -31351,7 +31435,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
31351
31435
  manifoldInstancesForCleanup.current = [];
31352
31436
  };
31353
31437
  }, [manifoldJSModule, circuitJson, boardData]);
31354
- const textures = useMemo27(() => {
31438
+ const textures = useMemo28(() => {
31355
31439
  if (!boardData || !traceTextureResolution) return null;
31356
31440
  return createCombinedBoardTextures({
31357
31441
  circuitJson,
@@ -31372,7 +31456,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
31372
31456
  };
31373
31457
 
31374
31458
  // src/utils/flex-meshes.ts
31375
- import * as THREE57 from "three";
31459
+ import * as THREE58 from "three";
31376
31460
  function restoreOutlinePrecision(point, outline, tolerance) {
31377
31461
  let distanceSquared = tolerance * tolerance;
31378
31462
  let closest;
@@ -31407,7 +31491,7 @@ function meshToSurface(mesh, center, outline) {
31407
31491
  const triangles = [];
31408
31492
  for (let i = 0; i < position.count; i += 3) {
31409
31493
  const vertices = [0, 1, 2].map((j) => {
31410
- const v = new THREE57.Vector3().fromBufferAttribute(position, i + j);
31494
+ const v = new THREE58.Vector3().fromBufferAttribute(position, i + j);
31411
31495
  const localMagnitude = Math.max(
31412
31496
  1,
31413
31497
  Math.abs(v.x),
@@ -31430,7 +31514,7 @@ function meshToSurface(mesh, center, outline) {
31430
31514
  return { x: v.x - center.x, y: v.y - center.y, z: v.z };
31431
31515
  });
31432
31516
  const [a, b, c] = vertices;
31433
- const n = new THREE57.Vector3(b.x - a.x, b.y - a.y, b.z - a.z).cross(new THREE57.Vector3(c.x - a.x, c.y - a.y, c.z - a.z)).normalize();
31517
+ const n = new THREE58.Vector3(b.x - a.x, b.y - a.y, b.z - a.z).cross(new THREE58.Vector3(c.x - a.x, c.y - a.y, c.z - a.z)).normalize();
31434
31518
  triangles.push({
31435
31519
  vertices,
31436
31520
  normal: { x: n.x, y: n.y, z: n.z },
@@ -31453,13 +31537,13 @@ function surfaceToGeometry(surface, center) {
31453
31537
  normals.push(triangle.normal.x, triangle.normal.y, triangle.normal.z);
31454
31538
  uvs.push(triangle.uvs?.[i]?.u ?? 0, triangle.uvs?.[i]?.v ?? 0);
31455
31539
  });
31456
- const geometry = new THREE57.BufferGeometry();
31540
+ const geometry = new THREE58.BufferGeometry();
31457
31541
  geometry.setAttribute(
31458
31542
  "position",
31459
- new THREE57.Float32BufferAttribute(positions, 3)
31543
+ new THREE58.Float32BufferAttribute(positions, 3)
31460
31544
  );
31461
- geometry.setAttribute("normal", new THREE57.Float32BufferAttribute(normals, 3));
31462
- geometry.setAttribute("uv", new THREE57.Float32BufferAttribute(uvs, 2));
31545
+ geometry.setAttribute("normal", new THREE58.Float32BufferAttribute(normals, 3));
31546
+ geometry.setAttribute("uv", new THREE58.Float32BufferAttribute(uvs, 2));
31463
31547
  geometry.computeBoundingBox();
31464
31548
  geometry.computeBoundingSphere();
31465
31549
  return geometry;
@@ -31512,7 +31596,7 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
31512
31596
  z: mesh.position.z
31513
31597
  }));
31514
31598
  const uvs = vertices.map((p) => {
31515
- const local = new THREE57.Vector3(
31599
+ const local = new THREE58.Vector3(
31516
31600
  p.x + board.center.x,
31517
31601
  p.y + board.center.y,
31518
31602
  p.z
@@ -31536,7 +31620,7 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
31536
31620
  return result;
31537
31621
  }) : textureMeshes;
31538
31622
  for (const stiffener of stiffeners) {
31539
- const mesh = new THREE57.Mesh(
31623
+ const mesh = new THREE58.Mesh(
31540
31624
  surfaceToGeometry(
31541
31625
  createStiffenerMesh({
31542
31626
  stiffener,
@@ -31545,16 +31629,16 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
31545
31629
  }),
31546
31630
  board.center
31547
31631
  ),
31548
- new THREE57.MeshStandardMaterial({
31632
+ new THREE58.MeshStandardMaterial({
31549
31633
  color: stiffener.material === "fr4" ? "#879568" : stiffener.material === "polyimide" ? "#bd7f27" : "#b8bdc4",
31550
- side: THREE57.DoubleSide
31634
+ side: THREE58.DoubleSide
31551
31635
  })
31552
31636
  );
31553
31637
  mesh.name = "board-stiffener";
31554
31638
  configureObjectShadows(mesh);
31555
31639
  geometry.push(mesh);
31556
31640
  }
31557
- const bounds = new THREE57.Box3();
31641
+ const bounds = new THREE58.Box3();
31558
31642
  for (const mesh of [...geometry, ...textures]) bounds.expandByObject(mesh);
31559
31643
  return {
31560
31644
  geometryMeshes: geometry,
@@ -31571,11 +31655,11 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
31571
31655
  }
31572
31656
 
31573
31657
  // src/utils/manifold/create-three-geometry-meshes.ts
31574
- import * as THREE59 from "three";
31658
+ import * as THREE60 from "three";
31575
31659
 
31576
31660
  // src/utils/create-board-material.ts
31577
- import * as THREE58 from "three";
31578
- var DEFAULT_SIDE = THREE58.DoubleSide;
31661
+ import * as THREE59 from "three";
31662
+ var DEFAULT_SIDE = THREE59.DoubleSide;
31579
31663
  var createBoardMaterial = ({
31580
31664
  material,
31581
31665
  color,
@@ -31583,7 +31667,7 @@ var createBoardMaterial = ({
31583
31667
  isFaux = false
31584
31668
  }) => {
31585
31669
  if (material === "fr4") {
31586
- return new THREE58.MeshPhysicalMaterial({
31670
+ return new THREE59.MeshPhysicalMaterial({
31587
31671
  color,
31588
31672
  side,
31589
31673
  metalness: 0,
@@ -31601,7 +31685,7 @@ var createBoardMaterial = ({
31601
31685
  polygonOffsetUnits: 1
31602
31686
  });
31603
31687
  }
31604
- return new THREE58.MeshStandardMaterial({
31688
+ return new THREE59.MeshStandardMaterial({
31605
31689
  color,
31606
31690
  side,
31607
31691
  flatShading: true,
@@ -31620,12 +31704,12 @@ function createGeometryMeshes(geoms) {
31620
31704
  const meshes = [];
31621
31705
  if (!geoms) return meshes;
31622
31706
  if (geoms.board?.geometry) {
31623
- const mesh = new THREE59.Mesh(
31707
+ const mesh = new THREE60.Mesh(
31624
31708
  geoms.board.geometry,
31625
31709
  createBoardMaterial({
31626
31710
  material: geoms.board.material,
31627
31711
  color: geoms.board.color,
31628
- side: THREE59.DoubleSide,
31712
+ side: THREE60.DoubleSide,
31629
31713
  isFaux: geoms.board.isFaux
31630
31714
  })
31631
31715
  );
@@ -31636,11 +31720,11 @@ function createGeometryMeshes(geoms) {
31636
31720
  const createMeshesFromArray = (geomArray) => {
31637
31721
  if (geomArray) {
31638
31722
  for (const comp of geomArray) {
31639
- const mesh = new THREE59.Mesh(
31723
+ const mesh = new THREE60.Mesh(
31640
31724
  comp.geometry,
31641
- new THREE59.MeshStandardMaterial({
31725
+ new THREE60.MeshStandardMaterial({
31642
31726
  color: comp.color,
31643
- side: THREE59.DoubleSide,
31727
+ side: THREE60.DoubleSide,
31644
31728
  flatShading: true
31645
31729
  // Consistent with board
31646
31730
  })
@@ -31684,7 +31768,7 @@ function loadManifold() {
31684
31768
  }
31685
31769
 
31686
31770
  // src/CadViewerManifold.tsx
31687
- import { jsx as jsx22, jsxs as jsxs7 } from "react/jsx-runtime";
31771
+ import { jsx as jsx23, jsxs as jsxs7 } from "react/jsx-runtime";
31688
31772
  var BoardMeshes = ({
31689
31773
  geometryMeshes,
31690
31774
  textureMeshes
@@ -31712,14 +31796,14 @@ var BoardMeshes = ({
31712
31796
  const typedMaterial = material;
31713
31797
  for (const prop of textureProps) {
31714
31798
  const texture = typedMaterial[prop];
31715
- if (texture && texture instanceof THREE60.Texture) {
31799
+ if (texture && texture instanceof THREE61.Texture) {
31716
31800
  texture.dispose();
31717
31801
  }
31718
31802
  }
31719
31803
  material.dispose();
31720
31804
  }
31721
31805
  };
31722
- useEffect34(() => {
31806
+ useEffect35(() => {
31723
31807
  if (!rootObject) return;
31724
31808
  for (const mesh of geometryMeshes) {
31725
31809
  let shouldShow = true;
@@ -31741,7 +31825,7 @@ var BoardMeshes = ({
31741
31825
  }
31742
31826
  };
31743
31827
  }, [rootObject, geometryMeshes, visibility]);
31744
- useEffect34(() => {
31828
+ useEffect35(() => {
31745
31829
  if (!rootObject) return;
31746
31830
  for (const mesh of textureMeshes) {
31747
31831
  rootObject.add(mesh);
@@ -31767,17 +31851,17 @@ var CadViewerManifold = ({
31767
31851
  onCameraControllerReady,
31768
31852
  resolveStaticAsset,
31769
31853
  referenceObject,
31770
- hiddenCadComponentIds
31854
+ objectVisibility
31771
31855
  }) => {
31772
31856
  const childrenCircuitJson = useConvertChildrenToCircuitJson(children);
31773
- const circuitJson = useMemo28(() => {
31857
+ const circuitJson = useMemo29(() => {
31774
31858
  const rawCircuitJson = circuitJsonProp ?? childrenCircuitJson;
31775
31859
  return addFauxBoardIfNeeded(rawCircuitJson);
31776
31860
  }, [circuitJsonProp, childrenCircuitJson]);
31777
31861
  const [manifoldJSModule, setManifoldJSModule] = useState21(null);
31778
31862
  const [manifoldLoadingError, setManifoldLoadingError] = useState21(null);
31779
31863
  const { visibility } = useLayerVisibility();
31780
- useEffect34(() => {
31864
+ useEffect35(() => {
31781
31865
  let isActive = true;
31782
31866
  loadManifold().then((module) => {
31783
31867
  if (isActive) setManifoldJSModule(module);
@@ -31801,7 +31885,7 @@ var CadViewerManifold = ({
31801
31885
  boardData,
31802
31886
  isFauxBoard
31803
31887
  } = useManifoldBoardBuilder(manifoldJSModule, circuitJson, visibility);
31804
- const flex = useMemo28(() => {
31888
+ const flex = useMemo29(() => {
31805
31889
  try {
31806
31890
  const resolvedFoldPcbs = resolveFoldPcbs(circuitJson, foldPcbs);
31807
31891
  const posedJson = transformCircuitJsonCadComponents(circuitJson, {
@@ -31832,28 +31916,32 @@ var CadViewerManifold = ({
31832
31916
  circuitJson,
31833
31917
  foldPcbs
31834
31918
  ]);
31835
- const cadComponents = useMemo28(
31836
- () => su17(flex.posedJson).cad_component.list().filter((cad) => !hiddenCadComponentIds?.has(cad.cad_component_id)),
31837
- [flex.posedJson, hiddenCadComponentIds]
31919
+ const cadComponents = useMemo29(
31920
+ () => su17(flex.posedJson).cad_component.list().filter(
31921
+ (cad) => !isObjectHidden(objectVisibility, cad.cad_component_id)
31922
+ ),
31923
+ [flex.posedJson, objectVisibility]
31838
31924
  );
31839
- const cadCables = useMemo28(
31840
- () => getCadCables(flex.posedJson),
31841
- [flex.posedJson]
31925
+ const cadCables = useMemo29(
31926
+ () => getCadCables(flex.posedJson).filter(
31927
+ (cable) => !isObjectHidden(objectVisibility, cable.cad_cable_id)
31928
+ ),
31929
+ [flex.posedJson, objectVisibility]
31842
31930
  );
31843
- const boardDimensions = useMemo28(() => {
31931
+ const boardDimensions = useMemo29(() => {
31844
31932
  if (!boardData) return void 0;
31845
31933
  const bounds = calculateOutlineBounds(boardData);
31846
31934
  return { width: bounds.width, height: bounds.height };
31847
31935
  }, [boardData]);
31848
- const boardCenter = useMemo28(() => {
31936
+ const boardCenter = useMemo29(() => {
31849
31937
  if (!boardData) return void 0;
31850
31938
  const bounds = calculateOutlineBounds(boardData);
31851
31939
  return { x: bounds.centerX, y: bounds.centerY };
31852
31940
  }, [boardData]);
31853
- const initialCameraPosition = useMemo28(() => {
31941
+ const initialCameraPosition = useMemo29(() => {
31854
31942
  return getInitialCameraPosition({ boardDimensions, boardCenter });
31855
31943
  }, [boardDimensions, boardCenter]);
31856
- const cameraSessionScope = useMemo28(() => {
31944
+ const cameraSessionScope = useMemo29(() => {
31857
31945
  if (!boardData) return void 0;
31858
31946
  return JSON.stringify({
31859
31947
  pcbBoardId: boardData.pcb_board_id,
@@ -31879,7 +31967,7 @@ var CadViewerManifold = ({
31879
31967
  );
31880
31968
  }
31881
31969
  if (!manifoldJSModule) {
31882
- return /* @__PURE__ */ jsx22("div", { style: { padding: "1em" }, children: "Loading Manifold module..." });
31970
+ return /* @__PURE__ */ jsx23("div", { style: { padding: "1em" }, children: "Loading Manifold module..." });
31883
31971
  }
31884
31972
  if (builderError || flex.error) {
31885
31973
  return /* @__PURE__ */ jsxs7(
@@ -31900,7 +31988,7 @@ var CadViewerManifold = ({
31900
31988
  );
31901
31989
  }
31902
31990
  if (builderIsLoading) {
31903
- return /* @__PURE__ */ jsx22("div", { style: { padding: "1em" }, children: "Processing board geometry..." });
31991
+ return /* @__PURE__ */ jsx23("div", { style: { padding: "1em" }, children: "Processing board geometry..." });
31904
31992
  }
31905
31993
  return /* @__PURE__ */ jsxs7(
31906
31994
  CadViewerContainer,
@@ -31915,19 +32003,26 @@ var CadViewerManifold = ({
31915
32003
  onUserInteraction,
31916
32004
  onCameraControllerReady,
31917
32005
  children: [
31918
- /* @__PURE__ */ jsx22(
31919
- BoardMeshes,
32006
+ /* @__PURE__ */ jsx23(
32007
+ BoardGroup,
31920
32008
  {
31921
- geometryMeshes: flex.geometryMeshes,
31922
- textureMeshes: flex.textureMeshes
32009
+ pcbBoardId: boardData?.pcb_board_id,
32010
+ hidden: isObjectHidden(objectVisibility, boardData?.pcb_board_id),
32011
+ children: /* @__PURE__ */ jsx23(
32012
+ BoardMeshes,
32013
+ {
32014
+ geometryMeshes: flex.geometryMeshes,
32015
+ textureMeshes: flex.textureMeshes
32016
+ }
32017
+ )
31923
32018
  }
31924
32019
  ),
31925
- flex.bounds && /* @__PURE__ */ jsx22(FitCameraToComparison, { bounds: flex.bounds }),
31926
- cadComponents.map((cad_component) => /* @__PURE__ */ jsx22(
32020
+ flex.bounds && /* @__PURE__ */ jsx23(FitCameraToComparison, { bounds: flex.bounds }),
32021
+ cadComponents.map((cad_component) => /* @__PURE__ */ jsx23(
31927
32022
  ThreeErrorBoundary,
31928
32023
  {
31929
- fallback: ({ error }) => /* @__PURE__ */ jsx22(Error3d, { cad_component, error }),
31930
- children: /* @__PURE__ */ jsx22(
32024
+ fallback: ({ error }) => /* @__PURE__ */ jsx23(Error3d, { cad_component, error }),
32025
+ children: /* @__PURE__ */ jsx23(
31931
32026
  AnyCadComponent,
31932
32027
  {
31933
32028
  cad_component,
@@ -31938,7 +32033,7 @@ var CadViewerManifold = ({
31938
32033
  },
31939
32034
  cad_component.cad_component_id
31940
32035
  )),
31941
- cadCables.map((cable) => /* @__PURE__ */ jsx22(CadCable, { cable }, cable.cad_cable_id))
32036
+ cadCables.map((cable) => /* @__PURE__ */ jsx23(CadCable, { cable }, cable.cad_cable_id))
31942
32037
  ]
31943
32038
  }
31944
32039
  );
@@ -31946,14 +32041,14 @@ var CadViewerManifold = ({
31946
32041
  var CadViewerManifold_default = CadViewerManifold;
31947
32042
 
31948
32043
  // src/CadViewerGlb.tsx
31949
- import { useEffect as useEffect36, useMemo as useMemo30, useState as useState23 } from "react";
32044
+ import { useEffect as useEffect37, useMemo as useMemo31, useState as useState23 } from "react";
31950
32045
 
31951
32046
  // src/hooks/useGlbModel.ts
31952
- import { useEffect as useEffect35, useMemo as useMemo29, useState as useState22 } from "react";
32047
+ import { useEffect as useEffect36, useMemo as useMemo30, useState as useState22 } from "react";
31953
32048
  function useGlbModel(source) {
31954
- const request = useMemo29(() => ({ source }), [source]);
32049
+ const request = useMemo30(() => ({ source }), [source]);
31955
32050
  const [result, setResult] = useState22();
31956
- useEffect35(() => {
32051
+ useEffect36(() => {
31957
32052
  const controller = new AbortController();
31958
32053
  let model;
31959
32054
  loadGlbScene(request.source, controller.signal).then((loaded) => {
@@ -31976,17 +32071,17 @@ function useGlbModel(source) {
31976
32071
  }
31977
32072
 
31978
32073
  // src/CadViewerGlb.tsx
31979
- import * as THREE61 from "three";
31980
- import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs8 } from "react/jsx-runtime";
32074
+ import * as THREE62 from "three";
32075
+ import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs8 } from "react/jsx-runtime";
31981
32076
  function GlbScene({
31982
32077
  model,
31983
- hiddenCadComponentIds
32078
+ objectVisibility
31984
32079
  }) {
31985
32080
  const { rootObject } = useThree();
31986
32081
  const { addHoverable, removeHoverable } = useHover();
31987
32082
  const [hover, setHover] = useState23();
31988
- const bounds = useMemo30(() => {
31989
- const box = new THREE61.Box3().setFromObject(model);
32083
+ const bounds = useMemo31(() => {
32084
+ const box = new THREE62.Box3().setFromObject(model);
31990
32085
  if (box.isEmpty()) return;
31991
32086
  return {
31992
32087
  minX: box.min.x,
@@ -31997,24 +32092,29 @@ function GlbScene({
31997
32092
  maxZ: box.max.z
31998
32093
  };
31999
32094
  }, [model]);
32000
- useEffect36(() => {
32095
+ useEffect37(() => {
32001
32096
  rootObject.add(model);
32002
32097
  return () => {
32003
32098
  rootObject.remove(model);
32004
32099
  };
32005
32100
  }, [rootObject, model]);
32006
- useEffect36(() => {
32101
+ useEffect37(() => {
32007
32102
  setHover(void 0);
32008
- model.traverse((object) => {
32103
+ const applyVisibility = (object, inComponent) => {
32009
32104
  const id = object.userData.cad_component_id;
32010
32105
  if (typeof id === "string")
32011
- object.visible = !hiddenCadComponentIds?.has(id);
32012
- });
32013
- }, [model, hiddenCadComponentIds]);
32014
- useEffect36(() => {
32106
+ object.visible = !isObjectHidden(objectVisibility, id);
32107
+ else if (!inComponent && object instanceof THREE62.Mesh)
32108
+ object.visible = !isObjectHidden(objectVisibility, void 0);
32109
+ for (const child of object.children)
32110
+ applyVisibility(child, inComponent || typeof id === "string");
32111
+ };
32112
+ applyVisibility(model, false);
32113
+ }, [model, objectVisibility]);
32114
+ useEffect37(() => {
32015
32115
  const meshes = [];
32016
32116
  model.traverse((mesh) => {
32017
- if (!(mesh instanceof THREE61.Mesh)) return;
32117
+ if (!(mesh instanceof THREE62.Mesh)) return;
32018
32118
  let ancestor = mesh;
32019
32119
  while (ancestor) {
32020
32120
  if (!ancestor.visible) return;
@@ -32042,10 +32142,10 @@ function GlbScene({
32042
32142
  return () => {
32043
32143
  for (const mesh of meshes) removeHoverable(mesh);
32044
32144
  };
32045
- }, [model, hiddenCadComponentIds, addHoverable, removeHoverable]);
32145
+ }, [model, objectVisibility, addHoverable, removeHoverable]);
32046
32146
  return /* @__PURE__ */ jsxs8(Fragment5, { children: [
32047
- bounds && /* @__PURE__ */ jsx23(FitCameraToComparison, { bounds }),
32048
- hover && /* @__PURE__ */ jsx23(
32147
+ bounds && /* @__PURE__ */ jsx24(FitCameraToComparison, { bounds }),
32148
+ hover && /* @__PURE__ */ jsx24(
32049
32149
  Html,
32050
32150
  {
32051
32151
  position: hover.position,
@@ -32064,13 +32164,13 @@ function GlbScene({
32064
32164
  }
32065
32165
  function CadViewerGlb({
32066
32166
  source,
32067
- hiddenCadComponentIds,
32167
+ objectVisibility,
32068
32168
  ...containerProps
32069
32169
  }) {
32070
32170
  const result = useGlbModel(source);
32071
- const framing = useMemo30(() => {
32171
+ const framing = useMemo31(() => {
32072
32172
  if (!result?.model) return void 0;
32073
- const bounds = new THREE61.Box3().setFromObject(result.model);
32173
+ const bounds = new THREE62.Box3().setFromObject(result.model);
32074
32174
  if (bounds.isEmpty()) return void 0;
32075
32175
  return {
32076
32176
  boardDimensions: {
@@ -32083,20 +32183,14 @@ function CadViewerGlb({
32083
32183
  }
32084
32184
  };
32085
32185
  }, [result, source]);
32086
- if (!result) return /* @__PURE__ */ jsx23("div", { role: "status", children: "Loading 3D view..." });
32186
+ if (!result) return /* @__PURE__ */ jsx24("div", { role: "status", children: "Loading 3D view..." });
32087
32187
  if (result.error)
32088
32188
  return /* @__PURE__ */ jsxs8("div", { role: "alert", children: [
32089
32189
  "Unable to load 3D view: ",
32090
32190
  result.error
32091
32191
  ] });
32092
32192
  if (!result.model) return null;
32093
- return /* @__PURE__ */ jsx23(CadViewerContainer, { ...containerProps, ...framing, children: /* @__PURE__ */ jsx23(
32094
- GlbScene,
32095
- {
32096
- model: result.model,
32097
- hiddenCadComponentIds
32098
- }
32099
- ) });
32193
+ return /* @__PURE__ */ jsx24(CadViewerContainer, { ...containerProps, ...framing, children: /* @__PURE__ */ jsx24(GlbScene, { model: result.model, objectVisibility }) });
32100
32194
  }
32101
32195
 
32102
32196
  // node_modules/@radix-ui/react-dropdown-menu/dist/index.mjs
@@ -32198,7 +32292,7 @@ __name2(useComposedRefs, "useComposedRefs");
32198
32292
 
32199
32293
  // node_modules/@radix-ui/react-context/dist/index.mjs
32200
32294
  import * as React12 from "react";
32201
- import { jsx as jsx24 } from "react/jsx-runtime";
32295
+ import { jsx as jsx25 } from "react/jsx-runtime";
32202
32296
  var __defProp4 = Object.defineProperty;
32203
32297
  var __name3 = (target, value) => __defProp4(target, "name", { value, configurable: true });
32204
32298
  // @__NO_SIDE_EFFECTS__
@@ -32208,7 +32302,7 @@ function createContext22(rootComponentName, defaultContext) {
32208
32302
  const Provider = /* @__PURE__ */ __name3((props) => {
32209
32303
  const { children, ...context } = props;
32210
32304
  const value = React12.useMemo(() => context, Object.values(context));
32211
- return /* @__PURE__ */ jsx24(Context.Provider, { value, children });
32305
+ return /* @__PURE__ */ jsx25(Context.Provider, { value, children });
32212
32306
  }, "Provider");
32213
32307
  Provider.displayName = rootComponentName + "Provider";
32214
32308
  function useContext22(consumerName, options = {}) {
@@ -32235,7 +32329,7 @@ function createContextScope(scopeName, createContextScopeDeps = []) {
32235
32329
  const { scope, children, ...context } = props;
32236
32330
  const Context = scope?.[scopeName]?.[index2] || BaseContext;
32237
32331
  const value = React12.useMemo(() => context, Object.values(context));
32238
- return /* @__PURE__ */ jsx24(Context.Provider, { value, children });
32332
+ return /* @__PURE__ */ jsx25(Context.Provider, { value, children });
32239
32333
  }, "Provider");
32240
32334
  Provider.displayName = rootComponentName + "Provider";
32241
32335
  function useContext22(consumerName, scope, options = {}) {
@@ -32620,7 +32714,7 @@ var createSlottableError = /* @__PURE__ */ __name6((ownerName) => {
32620
32714
  var use = React16[" use ".trim().toString()];
32621
32715
 
32622
32716
  // node_modules/@radix-ui/react-primitive/dist/index.mjs
32623
- import { jsx as jsx25 } from "react/jsx-runtime";
32717
+ import { jsx as jsx26 } from "react/jsx-runtime";
32624
32718
  var __defProp8 = Object.defineProperty;
32625
32719
  var __name7 = (target, value) => __defProp8(target, "name", { value, configurable: true });
32626
32720
  var NODES = [
@@ -32650,7 +32744,7 @@ var Primitive = NODES.reduce((primitive, node) => {
32650
32744
  if (typeof window !== "undefined") {
32651
32745
  window[/* @__PURE__ */ Symbol.for("radix-ui")] = true;
32652
32746
  }
32653
- return /* @__PURE__ */ jsx25(Comp, { ...primitiveProps, ref: forwardedRef });
32747
+ return /* @__PURE__ */ jsx26(Comp, { ...primitiveProps, ref: forwardedRef });
32654
32748
  });
32655
32749
  Node2.displayName = `Primitive.${node}`;
32656
32750
  return { ...primitive, [node]: Node2 };
@@ -32665,9 +32759,9 @@ import * as React41 from "react";
32665
32759
 
32666
32760
  // node_modules/@radix-ui/react-collection/dist/index.mjs
32667
32761
  import * as React18 from "react";
32668
- import { jsx as jsx26 } from "react/jsx-runtime";
32669
- import * as React23 from "react";
32670
32762
  import { jsx as jsx27 } from "react/jsx-runtime";
32763
+ import * as React23 from "react";
32764
+ import { jsx as jsx28 } from "react/jsx-runtime";
32671
32765
  var __defProp9 = Object.defineProperty;
32672
32766
  var __name8 = (target, value) => __defProp9(target, "name", { value, configurable: true });
32673
32767
  // @__NO_SIDE_EFFECTS__
@@ -32682,7 +32776,7 @@ function createCollection(name) {
32682
32776
  const { scope, children } = props;
32683
32777
  const ref = React18.useRef(null);
32684
32778
  const itemMap = React18.useRef(/* @__PURE__ */ new Map()).current;
32685
- return /* @__PURE__ */ jsx26(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
32779
+ return /* @__PURE__ */ jsx27(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
32686
32780
  }, "CollectionProvider");
32687
32781
  CollectionProvider.displayName = PROVIDER_NAME;
32688
32782
  const COLLECTION_SLOT_NAME = name + "CollectionSlot";
@@ -32692,7 +32786,7 @@ function createCollection(name) {
32692
32786
  const { scope, children } = props;
32693
32787
  const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
32694
32788
  const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);
32695
- return /* @__PURE__ */ jsx26(CollectionSlotImpl, { ref: composedRefs, children });
32789
+ return /* @__PURE__ */ jsx27(CollectionSlotImpl, { ref: composedRefs, children });
32696
32790
  }
32697
32791
  );
32698
32792
  CollectionSlot.displayName = COLLECTION_SLOT_NAME;
@@ -32709,7 +32803,7 @@ function createCollection(name) {
32709
32803
  context.itemMap.set(ref, { ref, ...itemData });
32710
32804
  return () => void context.itemMap.delete(ref);
32711
32805
  });
32712
- return /* @__PURE__ */ jsx26(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
32806
+ return /* @__PURE__ */ jsx27(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
32713
32807
  }
32714
32808
  );
32715
32809
  CollectionItemSlot.displayName = ITEM_SLOT_NAME;
@@ -33065,12 +33159,12 @@ function createCollection2(name) {
33065
33159
  const [CollectionStatefulContextProvider, useStatefulCollectionContext] = createCollectionContext(PROVIDER_NAME);
33066
33160
  CollectionStatefulContextProvider.displayName = name + "CollectionStatefulContextProvider";
33067
33161
  const CollectionProvider = /* @__PURE__ */ __name8(({ state, ...props }) => {
33068
- return state ? /* @__PURE__ */ jsx27(CollectionProviderImpl, { ...props, state }) : /* @__PURE__ */ jsx27(CollectionInit, { ...props });
33162
+ return state ? /* @__PURE__ */ jsx28(CollectionProviderImpl, { ...props, state }) : /* @__PURE__ */ jsx28(CollectionInit, { ...props });
33069
33163
  }, "CollectionProvider");
33070
33164
  CollectionProvider.displayName = PROVIDER_NAME;
33071
33165
  const CollectionInit = /* @__PURE__ */ __name8((props) => {
33072
33166
  const state = useInitCollection();
33073
- return /* @__PURE__ */ jsx27(CollectionProviderImpl, { ...props, state });
33167
+ return /* @__PURE__ */ jsx28(CollectionProviderImpl, { ...props, state });
33074
33168
  }, "CollectionInit");
33075
33169
  CollectionInit.displayName = name + "CollectionInit";
33076
33170
  const CollectionProviderImpl = /* @__PURE__ */ __name8((props) => {
@@ -33110,7 +33204,7 @@ function createCollection2(name) {
33110
33204
  observer.disconnect();
33111
33205
  };
33112
33206
  }, [collectionElement, setCollection]);
33113
- return /* @__PURE__ */ jsx27(
33207
+ return /* @__PURE__ */ jsx28(
33114
33208
  CollectionStableContextProvider,
33115
33209
  {
33116
33210
  scope,
@@ -33119,7 +33213,7 @@ function createCollection2(name) {
33119
33213
  getCollection,
33120
33214
  setCollection,
33121
33215
  registryRef,
33122
- children: /* @__PURE__ */ jsx27(
33216
+ children: /* @__PURE__ */ jsx28(
33123
33217
  CollectionStatefulContextProvider,
33124
33218
  {
33125
33219
  scope,
@@ -33139,7 +33233,7 @@ function createCollection2(name) {
33139
33233
  const { scope, children } = props;
33140
33234
  const context = useStableCollectionContext(COLLECTION_SLOT_NAME, scope);
33141
33235
  const composedRefs = useComposedRefs(forwardedRef, context.collectionElementRef);
33142
- return /* @__PURE__ */ jsx27(CollectionSlotImpl, { ref: composedRefs, children });
33236
+ return /* @__PURE__ */ jsx28(CollectionSlotImpl, { ref: composedRefs, children });
33143
33237
  }
33144
33238
  );
33145
33239
  CollectionSlot.displayName = COLLECTION_SLOT_NAME;
@@ -33215,7 +33309,7 @@ function createCollection2(name) {
33215
33309
  });
33216
33310
  };
33217
33311
  }, [setCollection]);
33218
- return /* @__PURE__ */ jsx27(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
33312
+ return /* @__PURE__ */ jsx28(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
33219
33313
  }
33220
33314
  );
33221
33315
  CollectionItemSlot.displayName = ITEM_SLOT_NAME;
@@ -33296,7 +33390,7 @@ __name8(getChildListObserver, "getChildListObserver");
33296
33390
 
33297
33391
  // node_modules/@radix-ui/react-direction/dist/index.mjs
33298
33392
  import * as React19 from "react";
33299
- import { jsx as jsx28 } from "react/jsx-runtime";
33393
+ import { jsx as jsx29 } from "react/jsx-runtime";
33300
33394
  var __defProp10 = Object.defineProperty;
33301
33395
  var __name9 = (target, value) => __defProp10(target, "name", { value, configurable: true });
33302
33396
  var Direction = {
@@ -33334,7 +33428,7 @@ function useCallbackRef(callback) {
33334
33428
  __name10(useCallbackRef, "useCallbackRef");
33335
33429
 
33336
33430
  // node_modules/@radix-ui/react-dismissable-layer/dist/index.mjs
33337
- import { jsx as jsx29 } from "react/jsx-runtime";
33431
+ import { jsx as jsx30 } from "react/jsx-runtime";
33338
33432
  var __defProp12 = Object.defineProperty;
33339
33433
  var __name11 = (target, value) => __defProp12(target, "name", { value, configurable: true });
33340
33434
  var CONTEXT_UPDATE = "dismissableLayer.update";
@@ -33466,7 +33560,7 @@ var DismissableLayer = /* @__PURE__ */ React21.forwardRef(
33466
33560
  document.addEventListener(CONTEXT_UPDATE, handleUpdate);
33467
33561
  return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);
33468
33562
  }, []);
33469
- return /* @__PURE__ */ jsx29(
33563
+ return /* @__PURE__ */ jsx30(
33470
33564
  Primitive.div,
33471
33565
  {
33472
33566
  ...layerProps,
@@ -33715,7 +33809,7 @@ __name12(createFocusGuard, "createFocusGuard");
33715
33809
 
33716
33810
  // node_modules/@radix-ui/react-focus-scope/dist/index.mjs
33717
33811
  import * as React25 from "react";
33718
- import { jsx as jsx30 } from "react/jsx-runtime";
33812
+ import { jsx as jsx31 } from "react/jsx-runtime";
33719
33813
  var __defProp14 = Object.defineProperty;
33720
33814
  var __name13 = (target, value) => __defProp14(target, "name", { value, configurable: true });
33721
33815
  var AUTOFOCUS_ON_MOUNT = "focusScope.autoFocusOnMount";
@@ -33854,7 +33948,7 @@ var FocusScope = /* @__PURE__ */ React25.forwardRef(
33854
33948
  },
33855
33949
  [loop, trapped, focusScope.paused]
33856
33950
  );
33857
- return /* @__PURE__ */ jsx30(Primitive.div, { tabIndex: -1, ...scopeProps, ref: composedRefs, onKeyDown: handleKeyDown });
33951
+ return /* @__PURE__ */ jsx31(Primitive.div, { tabIndex: -1, ...scopeProps, ref: composedRefs, onKeyDown: handleKeyDown });
33858
33952
  }, "FocusScope")
33859
33953
  );
33860
33954
  var FocusScopeBranchContext = React25.createContext(null);
@@ -33862,7 +33956,7 @@ function FocusScopeBranchProvider({ registry, children }) {
33862
33956
  if (!registry) {
33863
33957
  return children;
33864
33958
  }
33865
- return /* @__PURE__ */ jsx30(FocusScopeBranchContext.Provider, { value: registry, children });
33959
+ return /* @__PURE__ */ jsx31(FocusScopeBranchContext.Provider, { value: registry, children });
33866
33960
  }
33867
33961
  __name13(FocusScopeBranchProvider, "FocusScopeBranchProvider");
33868
33962
  function useFocusScopeBranchRegistry() {
@@ -35955,7 +36049,7 @@ function useSize(element) {
35955
36049
  __name15(useSize, "useSize");
35956
36050
 
35957
36051
  // node_modules/@radix-ui/react-popper/dist/index.mjs
35958
- import { jsx as jsx31 } from "react/jsx-runtime";
36052
+ import { jsx as jsx32 } from "react/jsx-runtime";
35959
36053
  var __defProp17 = Object.defineProperty;
35960
36054
  var __name16 = (target, value) => __defProp17(target, "name", { value, configurable: true });
35961
36055
  var Sticky = {
@@ -35973,7 +36067,7 @@ var Popper = /* @__PURE__ */ __name16((props) => {
35973
36067
  const { __scopePopper, children } = props;
35974
36068
  const [anchor, setAnchor] = React29.useState(null);
35975
36069
  const [placementState, setPlacementState] = React29.useState(void 0);
35976
- return /* @__PURE__ */ jsx31(
36070
+ return /* @__PURE__ */ jsx32(
35977
36071
  PopperProvider,
35978
36072
  {
35979
36073
  scope: __scopePopper,
@@ -36016,7 +36110,7 @@ var PopperAnchor = /* @__PURE__ */ React29.forwardRef(
36016
36110
  const sideAndAlign = context.placementState && getSideAndAlignFromPlacement(context.placementState);
36017
36111
  const placedSide = sideAndAlign?.[0];
36018
36112
  const placedAlign = sideAndAlign?.[1];
36019
- return virtualRef ? null : /* @__PURE__ */ jsx31(
36113
+ return virtualRef ? null : /* @__PURE__ */ jsx32(
36020
36114
  Primitive.div,
36021
36115
  {
36022
36116
  "data-radix-popper-side": placedSide,
@@ -36140,7 +36234,7 @@ var PopperContent = /* @__PURE__ */ React29.forwardRef(
36140
36234
  useLayoutEffect2(() => {
36141
36235
  if (content) setContentZIndex(window.getComputedStyle(content).zIndex);
36142
36236
  }, [content]);
36143
- return /* @__PURE__ */ jsx31(
36237
+ return /* @__PURE__ */ jsx32(
36144
36238
  "div",
36145
36239
  {
36146
36240
  ref: refs.setFloating,
@@ -36164,7 +36258,7 @@ var PopperContent = /* @__PURE__ */ React29.forwardRef(
36164
36258
  }
36165
36259
  },
36166
36260
  dir: props.dir,
36167
- children: /* @__PURE__ */ jsx31(
36261
+ children: /* @__PURE__ */ jsx32(
36168
36262
  PopperContentProvider,
36169
36263
  {
36170
36264
  scope: __scopePopper,
@@ -36174,7 +36268,7 @@ var PopperContent = /* @__PURE__ */ React29.forwardRef(
36174
36268
  arrowX,
36175
36269
  arrowY,
36176
36270
  shouldHideArrow: cannotCenterArrow,
36177
- children: /* @__PURE__ */ jsx31(
36271
+ children: /* @__PURE__ */ jsx32(
36178
36272
  Primitive.div,
36179
36273
  {
36180
36274
  "data-side": placedSide,
@@ -36240,7 +36334,7 @@ __name16(getSideAndAlignFromPlacement, "getSideAndAlignFromPlacement");
36240
36334
  // node_modules/@radix-ui/react-portal/dist/index.mjs
36241
36335
  import * as React30 from "react";
36242
36336
  import * as ReactDOM4 from "react-dom";
36243
- import { jsx as jsx32 } from "react/jsx-runtime";
36337
+ import { jsx as jsx33 } from "react/jsx-runtime";
36244
36338
  var __defProp18 = Object.defineProperty;
36245
36339
  var __name17 = (target, value) => __defProp18(target, "name", { value, configurable: true });
36246
36340
  var Portal = /* @__PURE__ */ React30.forwardRef(
@@ -36249,7 +36343,7 @@ var Portal = /* @__PURE__ */ React30.forwardRef(
36249
36343
  const [mounted, setMounted] = React30.useState(false);
36250
36344
  useLayoutEffect2(() => setMounted(true), []);
36251
36345
  const container = containerProp || mounted && globalThis?.document?.body;
36252
- return container ? ReactDOM4.createPortal(/* @__PURE__ */ jsx32(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;
36346
+ return container ? ReactDOM4.createPortal(/* @__PURE__ */ jsx33(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;
36253
36347
  }, "Portal")
36254
36348
  );
36255
36349
 
@@ -36469,7 +36563,7 @@ __name19(useIsHydratedModern, "useIsHydratedModern");
36469
36563
  var useIsHydrated2 = typeof useReactSyncExternalStore === "function" ? useIsHydratedModern : useIsHydrated;
36470
36564
 
36471
36565
  // node_modules/@radix-ui/react-roving-focus/dist/index.mjs
36472
- import { jsx as jsx33 } from "react/jsx-runtime";
36566
+ import { jsx as jsx34 } from "react/jsx-runtime";
36473
36567
  var __defProp21 = Object.defineProperty;
36474
36568
  var __name20 = (target, value) => __defProp21(target, "name", { value, configurable: true });
36475
36569
  var ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
@@ -36492,7 +36586,7 @@ var [RovingFocusProvider, useRovingFocusContext] = createRovingFocusGroupContext
36492
36586
  var RovingFocusGroup = /* @__PURE__ */ React33.forwardRef(
36493
36587
  // blank line to reduce diff noise
36494
36588
  /* @__PURE__ */ __name20(function RovingFocusGroup2(props, forwardedRef) {
36495
- return /* @__PURE__ */ jsx33(Collection.Provider, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx33(Collection.Slot, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx33(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });
36589
+ return /* @__PURE__ */ jsx34(Collection.Provider, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx34(Collection.Slot, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx34(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });
36496
36590
  }, "RovingFocusGroup")
36497
36591
  );
36498
36592
  var RovingFocusGroupImpl = /* @__PURE__ */ React33.forwardRef(/* @__PURE__ */ __name20(function RovingFocusGroupImpl2(props, forwardedRef) {
@@ -36529,7 +36623,7 @@ var RovingFocusGroupImpl = /* @__PURE__ */ React33.forwardRef(/* @__PURE__ */ __
36529
36623
  return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);
36530
36624
  }
36531
36625
  }, [handleEntryFocus]);
36532
- return /* @__PURE__ */ jsx33(
36626
+ return /* @__PURE__ */ jsx34(
36533
36627
  RovingFocusProvider,
36534
36628
  {
36535
36629
  scope: __scopeRovingFocusGroup,
@@ -36550,7 +36644,7 @@ var RovingFocusGroupImpl = /* @__PURE__ */ React33.forwardRef(/* @__PURE__ */ __
36550
36644
  () => setFocusableItemsCount((prevCount) => prevCount - 1),
36551
36645
  []
36552
36646
  ),
36553
- children: /* @__PURE__ */ jsx33(
36647
+ children: /* @__PURE__ */ jsx34(
36554
36648
  Primitive.div,
36555
36649
  {
36556
36650
  tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,
@@ -36618,14 +36712,14 @@ var RovingFocusGroupItem = /* @__PURE__ */ React33.forwardRef(
36618
36712
  onFocusableItemAdd();
36619
36713
  return () => onFocusableItemRemove();
36620
36714
  }, [isHydrated, focusable, onFocusableItemAdd, onFocusableItemRemove]);
36621
- return /* @__PURE__ */ jsx33(
36715
+ return /* @__PURE__ */ jsx34(
36622
36716
  Collection.ItemSlot,
36623
36717
  {
36624
36718
  scope: __scopeRovingFocusGroup,
36625
36719
  id,
36626
36720
  focusable,
36627
36721
  active,
36628
- children: /* @__PURE__ */ jsx33(
36722
+ children: /* @__PURE__ */ jsx34(
36629
36723
  Primitive.span,
36630
36724
  {
36631
36725
  tabIndex: isCurrentTabStop ? 0 : -1,
@@ -37547,7 +37641,7 @@ ReactRemoveScroll.classNames = RemoveScroll.classNames;
37547
37641
  var Combination_default = ReactRemoveScroll;
37548
37642
 
37549
37643
  // node_modules/@radix-ui/react-menu/dist/index.mjs
37550
- import { jsx as jsx34 } from "react/jsx-runtime";
37644
+ import { jsx as jsx35 } from "react/jsx-runtime";
37551
37645
  var __defProp22 = Object.defineProperty;
37552
37646
  var __name21 = (target, value) => __defProp22(target, "name", { value, configurable: true });
37553
37647
  var Direction3 = {
@@ -37606,7 +37700,7 @@ var Menu = /* @__PURE__ */ __name21((props) => {
37606
37700
  window.addEventListener("blur", handleBlur);
37607
37701
  return () => window.removeEventListener("blur", handleBlur);
37608
37702
  }, [open, handleOpenChange]);
37609
- return /* @__PURE__ */ jsx34(Popper, { ...popperScope, children: /* @__PURE__ */ jsx34(
37703
+ return /* @__PURE__ */ jsx35(Popper, { ...popperScope, children: /* @__PURE__ */ jsx35(
37610
37704
  MenuProvider,
37611
37705
  {
37612
37706
  scope: __scopeMenu,
@@ -37614,7 +37708,7 @@ var Menu = /* @__PURE__ */ __name21((props) => {
37614
37708
  onOpenChange: handleOpenChange,
37615
37709
  content,
37616
37710
  onContentChange: setContent,
37617
- children: /* @__PURE__ */ jsx34(
37711
+ children: /* @__PURE__ */ jsx35(
37618
37712
  MenuRootProvider,
37619
37713
  {
37620
37714
  scope: __scopeMenu,
@@ -37632,7 +37726,7 @@ var MenuAnchor = /* @__PURE__ */ React41.forwardRef(
37632
37726
  /* @__PURE__ */ __name21(function MenuAnchor2(props, forwardedRef) {
37633
37727
  const { __scopeMenu, ...anchorProps } = props;
37634
37728
  const popperScope = usePopperScope(__scopeMenu);
37635
- return /* @__PURE__ */ jsx34(PopperAnchor, { ...popperScope, ...anchorProps, ref: forwardedRef });
37729
+ return /* @__PURE__ */ jsx35(PopperAnchor, { ...popperScope, ...anchorProps, ref: forwardedRef });
37636
37730
  }, "MenuAnchor")
37637
37731
  );
37638
37732
  var PORTAL_NAME = "MenuPortal";
@@ -37642,7 +37736,7 @@ var [PortalProvider, usePortalContext] = createMenuContext(PORTAL_NAME, {
37642
37736
  var MenuPortal = /* @__PURE__ */ __name21((props) => {
37643
37737
  const { __scopeMenu, forceMount, children, container } = props;
37644
37738
  const context = useMenuContext(PORTAL_NAME, __scopeMenu);
37645
- return /* @__PURE__ */ jsx34(PortalProvider, { scope: __scopeMenu, forceMount, children: /* @__PURE__ */ jsx34(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx34(Portal, { asChild: true, container, children }) }) });
37739
+ return /* @__PURE__ */ jsx35(PortalProvider, { scope: __scopeMenu, forceMount, children: /* @__PURE__ */ jsx35(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx35(Portal, { asChild: true, container, children }) }) });
37646
37740
  }, "MenuPortal");
37647
37741
  var CONTENT_NAME2 = "MenuContent";
37648
37742
  var [MenuContentProvider, useMenuContentContext] = createMenuContext(CONTENT_NAME2);
@@ -37652,7 +37746,7 @@ var MenuContent = /* @__PURE__ */ React41.forwardRef(
37652
37746
  const { forceMount = portalContext.forceMount, ...contentProps } = props;
37653
37747
  const context = useMenuContext(CONTENT_NAME2, props.__scopeMenu);
37654
37748
  const rootContext = useMenuRootContext(CONTENT_NAME2, props.__scopeMenu);
37655
- return /* @__PURE__ */ jsx34(Collection2.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx34(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx34(Collection2.Slot, { scope: props.__scopeMenu, children: rootContext.modal ? /* @__PURE__ */ jsx34(MenuRootContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx34(MenuRootContentNonModal, { ...contentProps, ref: forwardedRef }) }) }) });
37749
+ return /* @__PURE__ */ jsx35(Collection2.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx35(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx35(Collection2.Slot, { scope: props.__scopeMenu, children: rootContext.modal ? /* @__PURE__ */ jsx35(MenuRootContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx35(MenuRootContentNonModal, { ...contentProps, ref: forwardedRef }) }) }) });
37656
37750
  }, "MenuContent")
37657
37751
  );
37658
37752
  var MenuRootContentModal = /* @__PURE__ */ React41.forwardRef(
@@ -37665,7 +37759,7 @@ var MenuRootContentModal = /* @__PURE__ */ React41.forwardRef(
37665
37759
  const content = ref.current;
37666
37760
  if (content) return hideOthers(content);
37667
37761
  }, []);
37668
- return /* @__PURE__ */ jsx34(
37762
+ return /* @__PURE__ */ jsx35(
37669
37763
  MenuContentImpl,
37670
37764
  {
37671
37765
  ...props,
@@ -37685,7 +37779,7 @@ var MenuRootContentModal = /* @__PURE__ */ React41.forwardRef(
37685
37779
  );
37686
37780
  var MenuRootContentNonModal = /* @__PURE__ */ React41.forwardRef(/* @__PURE__ */ __name21(function MenuRootContentNonModal2(props, forwardedRef) {
37687
37781
  const context = useMenuContext(CONTENT_NAME2, props.__scopeMenu);
37688
- return /* @__PURE__ */ jsx34(
37782
+ return /* @__PURE__ */ jsx35(
37689
37783
  MenuContentImpl,
37690
37784
  {
37691
37785
  ...props,
@@ -37777,7 +37871,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
37777
37871
  const isMovingTowards = pointerDirRef.current === pointerGraceIntentRef.current?.side;
37778
37872
  return isMovingTowards && isPointerInGraceArea(event, pointerGraceIntentRef.current?.area);
37779
37873
  }, []);
37780
- return /* @__PURE__ */ jsx34(
37874
+ return /* @__PURE__ */ jsx35(
37781
37875
  MenuContentProvider,
37782
37876
  {
37783
37877
  scope: __scopeMenu,
@@ -37806,7 +37900,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
37806
37900
  onPointerGraceIntentChange: React41.useCallback((intent) => {
37807
37901
  pointerGraceIntentRef.current = intent;
37808
37902
  }, []),
37809
- children: /* @__PURE__ */ jsx34(FocusScopeBranchProvider, { registry: isModal ? branchRegistry : null, children: /* @__PURE__ */ jsx34(ScrollLockWrapper, { ...scrollLockWrapperProps, children: /* @__PURE__ */ jsx34(
37903
+ children: /* @__PURE__ */ jsx35(FocusScopeBranchProvider, { registry: isModal ? branchRegistry : null, children: /* @__PURE__ */ jsx35(ScrollLockWrapper, { ...scrollLockWrapperProps, children: /* @__PURE__ */ jsx35(
37810
37904
  FocusScope,
37811
37905
  {
37812
37906
  asChild: true,
@@ -37817,7 +37911,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
37817
37911
  contentRef.current?.focus({ preventScroll: true });
37818
37912
  }),
37819
37913
  onUnmountAutoFocus: onCloseAutoFocus,
37820
- children: /* @__PURE__ */ jsx34(
37914
+ children: /* @__PURE__ */ jsx35(
37821
37915
  DismissableLayer,
37822
37916
  {
37823
37917
  asChild: true,
@@ -37827,7 +37921,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
37827
37921
  onFocusOutside,
37828
37922
  onInteractOutside,
37829
37923
  onDismiss,
37830
- children: /* @__PURE__ */ jsx34(
37924
+ children: /* @__PURE__ */ jsx35(
37831
37925
  RovingFocusGroup,
37832
37926
  {
37833
37927
  asChild: true,
@@ -37841,7 +37935,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
37841
37935
  if (!rootContext.isUsingKeyboardRef.current) event.preventDefault();
37842
37936
  }),
37843
37937
  preventScrollOnEntryFocus: true,
37844
- children: /* @__PURE__ */ jsx34(
37938
+ children: /* @__PURE__ */ jsx35(
37845
37939
  PopperContent,
37846
37940
  {
37847
37941
  role: "menu",
@@ -37925,7 +38019,7 @@ var MenuItem = /* @__PURE__ */ React41.forwardRef(
37925
38019
  }
37926
38020
  }
37927
38021
  }, "handleSelect");
37928
- return /* @__PURE__ */ jsx34(
38022
+ return /* @__PURE__ */ jsx35(
37929
38023
  MenuItemImpl,
37930
38024
  {
37931
38025
  ...itemProps,
@@ -37971,13 +38065,13 @@ var MenuItemImpl = /* @__PURE__ */ React41.forwardRef(
37971
38065
  setTextContent((menuItem.textContent ?? "").trim());
37972
38066
  }
37973
38067
  }, [itemProps.children]);
37974
- return /* @__PURE__ */ jsx34(
38068
+ return /* @__PURE__ */ jsx35(
37975
38069
  Collection2.ItemSlot,
37976
38070
  {
37977
38071
  scope: __scopeMenu,
37978
38072
  disabled,
37979
38073
  textValue: textValue ?? textContent,
37980
- children: /* @__PURE__ */ jsx34(RovingFocusGroupItem, { asChild: true, ...rovingFocusGroupScope, focusable: !disabled, children: /* @__PURE__ */ jsx34(
38074
+ children: /* @__PURE__ */ jsx35(RovingFocusGroupItem, { asChild: true, ...rovingFocusGroupScope, focusable: !disabled, children: /* @__PURE__ */ jsx35(
37981
38075
  Primitive.div,
37982
38076
  {
37983
38077
  role: "menuitem",
@@ -38016,7 +38110,7 @@ var MenuCheckboxItem = /* @__PURE__ */ React41.forwardRef(
38016
38110
  // blank line to reduce diff noise
38017
38111
  /* @__PURE__ */ __name21(function MenuCheckboxItem2(props, forwardedRef) {
38018
38112
  const { checked = false, onCheckedChange, ...checkboxItemProps } = props;
38019
- return /* @__PURE__ */ jsx34(ItemIndicatorProvider, { scope: props.__scopeMenu, checked, children: /* @__PURE__ */ jsx34(
38113
+ return /* @__PURE__ */ jsx35(ItemIndicatorProvider, { scope: props.__scopeMenu, checked, children: /* @__PURE__ */ jsx35(
38020
38114
  MenuItem,
38021
38115
  {
38022
38116
  role: "menuitemcheckbox",
@@ -38047,7 +38141,7 @@ var [ItemIndicatorProvider, useItemIndicatorContext] = createMenuContext(
38047
38141
  var MenuSeparator = /* @__PURE__ */ React41.forwardRef(
38048
38142
  /* @__PURE__ */ __name21(function MenuSeparator2(props, forwardedRef) {
38049
38143
  const { __scopeMenu, ...separatorProps } = props;
38050
- return /* @__PURE__ */ jsx34(
38144
+ return /* @__PURE__ */ jsx35(
38051
38145
  Primitive.div,
38052
38146
  {
38053
38147
  role: "separator",
@@ -38071,7 +38165,7 @@ var MenuSub = /* @__PURE__ */ __name21((props) => {
38071
38165
  if (parentMenuContext.open === false) handleOpenChange(false);
38072
38166
  return () => handleOpenChange(false);
38073
38167
  }, [parentMenuContext.open, handleOpenChange]);
38074
- return /* @__PURE__ */ jsx34(Popper, { ...popperScope, children: /* @__PURE__ */ jsx34(
38168
+ return /* @__PURE__ */ jsx35(Popper, { ...popperScope, children: /* @__PURE__ */ jsx35(
38075
38169
  MenuProvider,
38076
38170
  {
38077
38171
  scope: __scopeMenu,
@@ -38079,7 +38173,7 @@ var MenuSub = /* @__PURE__ */ __name21((props) => {
38079
38173
  onOpenChange: handleOpenChange,
38080
38174
  content,
38081
38175
  onContentChange: setContent,
38082
- children: /* @__PURE__ */ jsx34(
38176
+ children: /* @__PURE__ */ jsx35(
38083
38177
  MenuSubProvider,
38084
38178
  {
38085
38179
  scope: __scopeMenu,
@@ -38116,7 +38210,7 @@ var MenuSubTrigger = /* @__PURE__ */ React41.forwardRef(
38116
38210
  };
38117
38211
  }, [pointerGraceTimerRef, onPointerGraceIntentChange]);
38118
38212
  const composedRefs = useComposedRefs(forwardedRef, subContext.onTriggerChange);
38119
- return /* @__PURE__ */ jsx34(MenuAnchor, { asChild: true, ...scope, children: /* @__PURE__ */ jsx34(
38213
+ return /* @__PURE__ */ jsx35(MenuAnchor, { asChild: true, ...scope, children: /* @__PURE__ */ jsx35(
38120
38214
  MenuItemImpl,
38121
38215
  {
38122
38216
  id: subContext.triggerId,
@@ -38209,7 +38303,7 @@ var MenuSubContent = /* @__PURE__ */ React41.forwardRef(
38209
38303
  const subContext = useMenuSubContext(SUB_CONTENT_NAME, props.__scopeMenu);
38210
38304
  const ref = React41.useRef(null);
38211
38305
  const composedRefs = useComposedRefs(forwardedRef, ref);
38212
- return /* @__PURE__ */ jsx34(Collection2.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx34(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx34(Collection2.Slot, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx34(
38306
+ return /* @__PURE__ */ jsx35(Collection2.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx35(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx35(Collection2.Slot, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx35(
38213
38307
  MenuContentImpl,
38214
38308
  {
38215
38309
  id: subContext.contentId,
@@ -38312,7 +38406,7 @@ function whenMouse(handler) {
38312
38406
  __name21(whenMouse, "whenMouse");
38313
38407
 
38314
38408
  // node_modules/@radix-ui/react-dropdown-menu/dist/index.mjs
38315
- import { jsx as jsx35 } from "react/jsx-runtime";
38409
+ import { jsx as jsx36 } from "react/jsx-runtime";
38316
38410
  var __defProp23 = Object.defineProperty;
38317
38411
  var __name22 = (target, value) => __defProp23(target, "name", { value, configurable: true });
38318
38412
  var DROPDOWN_MENU_NAME = "DropdownMenu";
@@ -38340,7 +38434,7 @@ var DropdownMenu = /* @__PURE__ */ __name22((props) => {
38340
38434
  onChange: onOpenChange,
38341
38435
  caller: DROPDOWN_MENU_NAME
38342
38436
  });
38343
- return /* @__PURE__ */ jsx35(
38437
+ return /* @__PURE__ */ jsx36(
38344
38438
  DropdownMenuProvider,
38345
38439
  {
38346
38440
  scope: __scopeDropdownMenu,
@@ -38351,7 +38445,7 @@ var DropdownMenu = /* @__PURE__ */ __name22((props) => {
38351
38445
  onOpenChange: setOpen,
38352
38446
  onOpenToggle: React42.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
38353
38447
  modal,
38354
- children: /* @__PURE__ */ jsx35(Menu, { ...menuScope, open, onOpenChange: setOpen, dir, modal, children })
38448
+ children: /* @__PURE__ */ jsx36(Menu, { ...menuScope, open, onOpenChange: setOpen, dir, modal, children })
38355
38449
  }
38356
38450
  );
38357
38451
  }, "DropdownMenu");
@@ -38363,7 +38457,7 @@ var DropdownMenuTrigger = /* @__PURE__ */ React42.forwardRef(
38363
38457
  const context = useDropdownMenuContext(TRIGGER_NAME, __scopeDropdownMenu);
38364
38458
  const menuScope = useMenuScope(__scopeDropdownMenu);
38365
38459
  const composedRefs = useComposedRefs(forwardedRef, context.triggerRef);
38366
- return /* @__PURE__ */ jsx35(MenuAnchor, { asChild: true, ...menuScope, children: /* @__PURE__ */ jsx35(
38460
+ return /* @__PURE__ */ jsx36(MenuAnchor, { asChild: true, ...menuScope, children: /* @__PURE__ */ jsx36(
38367
38461
  Primitive.button,
38368
38462
  {
38369
38463
  type: "button",
@@ -38395,7 +38489,7 @@ var DropdownMenuTrigger = /* @__PURE__ */ React42.forwardRef(
38395
38489
  var DropdownMenuPortal = /* @__PURE__ */ __name22((props) => {
38396
38490
  const { __scopeDropdownMenu, ...portalProps } = props;
38397
38491
  const menuScope = useMenuScope(__scopeDropdownMenu);
38398
- return /* @__PURE__ */ jsx35(MenuPortal, { ...menuScope, ...portalProps });
38492
+ return /* @__PURE__ */ jsx36(MenuPortal, { ...menuScope, ...portalProps });
38399
38493
  }, "DropdownMenuPortal");
38400
38494
  var CONTENT_NAME3 = "DropdownMenuContent";
38401
38495
  var DropdownMenuContent = /* @__PURE__ */ React42.forwardRef(
@@ -38405,7 +38499,7 @@ var DropdownMenuContent = /* @__PURE__ */ React42.forwardRef(
38405
38499
  const context = useDropdownMenuContext(CONTENT_NAME3, __scopeDropdownMenu);
38406
38500
  const menuScope = useMenuScope(__scopeDropdownMenu);
38407
38501
  const hasInteractedOutsideRef = React42.useRef(false);
38408
- return /* @__PURE__ */ jsx35(
38502
+ return /* @__PURE__ */ jsx36(
38409
38503
  MenuContent,
38410
38504
  {
38411
38505
  id: context.contentId,
@@ -38444,18 +38538,18 @@ var DropdownMenuItem = /* @__PURE__ */ React42.forwardRef(
38444
38538
  /* @__PURE__ */ __name22(function DropdownMenuItem2(props, forwardedRef) {
38445
38539
  const { __scopeDropdownMenu, ...itemProps } = props;
38446
38540
  const menuScope = useMenuScope(__scopeDropdownMenu);
38447
- return /* @__PURE__ */ jsx35(MenuItem, { ...menuScope, ...itemProps, ref: forwardedRef });
38541
+ return /* @__PURE__ */ jsx36(MenuItem, { ...menuScope, ...itemProps, ref: forwardedRef });
38448
38542
  }, "DropdownMenuItem")
38449
38543
  );
38450
38544
  var DropdownMenuCheckboxItem = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuCheckboxItem2(props, forwardedRef) {
38451
38545
  const { __scopeDropdownMenu, ...checkboxItemProps } = props;
38452
38546
  const menuScope = useMenuScope(__scopeDropdownMenu);
38453
- return /* @__PURE__ */ jsx35(MenuCheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
38547
+ return /* @__PURE__ */ jsx36(MenuCheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
38454
38548
  }, "DropdownMenuCheckboxItem"));
38455
38549
  var DropdownMenuSeparator = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuSeparator2(props, forwardedRef) {
38456
38550
  const { __scopeDropdownMenu, ...separatorProps } = props;
38457
38551
  const menuScope = useMenuScope(__scopeDropdownMenu);
38458
- return /* @__PURE__ */ jsx35(MenuSeparator, { ...menuScope, ...separatorProps, ref: forwardedRef });
38552
+ return /* @__PURE__ */ jsx36(MenuSeparator, { ...menuScope, ...separatorProps, ref: forwardedRef });
38459
38553
  }, "DropdownMenuSeparator"));
38460
38554
  var DropdownMenuSub = /* @__PURE__ */ __name22((props) => {
38461
38555
  const { __scopeDropdownMenu, children, open: openProp, onOpenChange, defaultOpen } = props;
@@ -38466,17 +38560,17 @@ var DropdownMenuSub = /* @__PURE__ */ __name22((props) => {
38466
38560
  onChange: onOpenChange,
38467
38561
  caller: "DropdownMenuSub"
38468
38562
  });
38469
- return /* @__PURE__ */ jsx35(MenuSub, { ...menuScope, open, onOpenChange: setOpen, children });
38563
+ return /* @__PURE__ */ jsx36(MenuSub, { ...menuScope, open, onOpenChange: setOpen, children });
38470
38564
  }, "DropdownMenuSub");
38471
38565
  var DropdownMenuSubTrigger = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuSubTrigger2(props, forwardedRef) {
38472
38566
  const { __scopeDropdownMenu, ...subTriggerProps } = props;
38473
38567
  const menuScope = useMenuScope(__scopeDropdownMenu);
38474
- return /* @__PURE__ */ jsx35(MenuSubTrigger, { ...menuScope, ...subTriggerProps, ref: forwardedRef });
38568
+ return /* @__PURE__ */ jsx36(MenuSubTrigger, { ...menuScope, ...subTriggerProps, ref: forwardedRef });
38475
38569
  }, "DropdownMenuSubTrigger"));
38476
38570
  var DropdownMenuSubContent = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuSubContent2(props, forwardedRef) {
38477
38571
  const { __scopeDropdownMenu, ...subContentProps } = props;
38478
38572
  const menuScope = useMenuScope(__scopeDropdownMenu);
38479
- return /* @__PURE__ */ jsx35(
38573
+ return /* @__PURE__ */ jsx36(
38480
38574
  MenuSubContent,
38481
38575
  {
38482
38576
  ...menuScope,
@@ -38499,7 +38593,7 @@ var DropdownMenuSubContent = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */
38499
38593
 
38500
38594
  // src/components/ViewportSubContent.tsx
38501
38595
  import { useLayoutEffect as useLayoutEffect5, useState as useState40 } from "react";
38502
- import { jsx as jsx36 } from "react/jsx-runtime";
38596
+ import { jsx as jsx37 } from "react/jsx-runtime";
38503
38597
  var ViewportSubContent = (props) => {
38504
38598
  const [content, setContent] = useState40(null);
38505
38599
  const [overlapWidth, setOverlapWidth] = useState40();
@@ -38530,7 +38624,7 @@ var ViewportSubContent = (props) => {
38530
38624
  window.removeEventListener("resize", update);
38531
38625
  };
38532
38626
  }, [content]);
38533
- return /* @__PURE__ */ jsx36(
38627
+ return /* @__PURE__ */ jsx37(
38534
38628
  DropdownMenuSubContent,
38535
38629
  {
38536
38630
  ...props,
@@ -38563,8 +38657,8 @@ import { useState as useState42 } from "react";
38563
38657
  import { useState as useState41 } from "react";
38564
38658
 
38565
38659
  // src/components/Icons.tsx
38566
- import { jsx as jsx37 } from "react/jsx-runtime";
38567
- var CheckIcon = () => /* @__PURE__ */ jsx37(
38660
+ import { jsx as jsx38 } from "react/jsx-runtime";
38661
+ var CheckIcon = () => /* @__PURE__ */ jsx38(
38568
38662
  "svg",
38569
38663
  {
38570
38664
  xmlns: "http://www.w3.org/2000/svg",
@@ -38576,10 +38670,10 @@ var CheckIcon = () => /* @__PURE__ */ jsx37(
38576
38670
  strokeWidth: "2",
38577
38671
  strokeLinecap: "round",
38578
38672
  strokeLinejoin: "round",
38579
- children: /* @__PURE__ */ jsx37("path", { d: "M20 6 9 17l-5-5" })
38673
+ children: /* @__PURE__ */ jsx38("path", { d: "M20 6 9 17l-5-5" })
38580
38674
  }
38581
38675
  );
38582
- var ChevronRightIcon = ({ isOpen }) => /* @__PURE__ */ jsx37(
38676
+ var ChevronRightIcon = ({ isOpen }) => /* @__PURE__ */ jsx38(
38583
38677
  "svg",
38584
38678
  {
38585
38679
  xmlns: "http://www.w3.org/2000/svg",
@@ -38596,10 +38690,10 @@ var ChevronRightIcon = ({ isOpen }) => /* @__PURE__ */ jsx37(
38596
38690
  transform: isOpen ? "rotate(90deg)" : "rotate(0deg)",
38597
38691
  opacity: 0.6
38598
38692
  },
38599
- children: /* @__PURE__ */ jsx37("path", { d: "m9 18 6-6-6-6" })
38693
+ children: /* @__PURE__ */ jsx38("path", { d: "m9 18 6-6-6-6" })
38600
38694
  }
38601
38695
  );
38602
- var CheckMinusIcon = () => /* @__PURE__ */ jsx37(
38696
+ var CheckMinusIcon = () => /* @__PURE__ */ jsx38(
38603
38697
  "svg",
38604
38698
  {
38605
38699
  xmlns: "http://www.w3.org/2000/svg",
@@ -38611,10 +38705,10 @@ var CheckMinusIcon = () => /* @__PURE__ */ jsx37(
38611
38705
  strokeWidth: "2",
38612
38706
  strokeLinecap: "round",
38613
38707
  strokeLinejoin: "round",
38614
- children: /* @__PURE__ */ jsx37("path", { d: "M5 12h14" })
38708
+ children: /* @__PURE__ */ jsx38("path", { d: "M5 12h14" })
38615
38709
  }
38616
38710
  );
38617
- var DotIcon = () => /* @__PURE__ */ jsx37(
38711
+ var DotIcon = () => /* @__PURE__ */ jsx38(
38618
38712
  "svg",
38619
38713
  {
38620
38714
  xmlns: "http://www.w3.org/2000/svg",
@@ -38627,12 +38721,12 @@ var DotIcon = () => /* @__PURE__ */ jsx37(
38627
38721
  strokeLinecap: "round",
38628
38722
  strokeLinejoin: "round",
38629
38723
  className: "lucide lucide-dot-icon lucide-dot",
38630
- children: /* @__PURE__ */ jsx37("circle", { cx: "12.1", cy: "12.1", r: "4.5", fill: "white" })
38724
+ children: /* @__PURE__ */ jsx38("circle", { cx: "12.1", cy: "12.1", r: "4.5", fill: "white" })
38631
38725
  }
38632
38726
  );
38633
38727
 
38634
38728
  // src/components/AppearanceMenu.tsx
38635
- import { Fragment as Fragment10, jsx as jsx38, jsxs as jsxs9 } from "react/jsx-runtime";
38729
+ import { Fragment as Fragment10, jsx as jsx39, jsxs as jsxs9 } from "react/jsx-runtime";
38636
38730
  var itemStyles = {
38637
38731
  padding: "6px 8px",
38638
38732
  borderRadius: 6,
@@ -38695,7 +38789,7 @@ var AppearanceMenu = ({
38695
38789
  const assemblyStyles = { ...itemStyles };
38696
38790
  if (hoveredItem === "assembly") assemblyStyles.backgroundColor = "#404040";
38697
38791
  return /* @__PURE__ */ jsxs9(Fragment10, { children: [
38698
- /* @__PURE__ */ jsx38(DropdownMenuSeparator, { style: separatorStyles }),
38792
+ /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles }),
38699
38793
  /* @__PURE__ */ jsxs9(DropdownMenuSub, { onOpenChange: setAppearanceSubOpen, children: [
38700
38794
  /* @__PURE__ */ jsxs9(
38701
38795
  DropdownMenuSubTrigger,
@@ -38709,8 +38803,8 @@ var AppearanceMenu = ({
38709
38803
  onMouseLeave: () => setHoveredItem(null),
38710
38804
  onTouchStart: () => setHoveredItem("appearance"),
38711
38805
  children: [
38712
- /* @__PURE__ */ jsx38("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Appearance" }),
38713
- /* @__PURE__ */ jsx38(
38806
+ /* @__PURE__ */ jsx39("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Appearance" }),
38807
+ /* @__PURE__ */ jsx39(
38714
38808
  "div",
38715
38809
  {
38716
38810
  style: {
@@ -38719,13 +38813,13 @@ var AppearanceMenu = ({
38719
38813
  alignItems: "flex-end",
38720
38814
  marginBottom: "-5px"
38721
38815
  },
38722
- children: /* @__PURE__ */ jsx38(ChevronRightIcon, { isOpen: appearanceSubOpen })
38816
+ children: /* @__PURE__ */ jsx39(ChevronRightIcon, { isOpen: appearanceSubOpen })
38723
38817
  }
38724
38818
  )
38725
38819
  ]
38726
38820
  }
38727
38821
  ),
38728
- /* @__PURE__ */ jsx38(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs9(
38822
+ /* @__PURE__ */ jsx39(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs9(
38729
38823
  ViewportSubContent,
38730
38824
  {
38731
38825
  style: { ...contentStyles, marginLeft: -2 },
@@ -38748,8 +38842,8 @@ var AppearanceMenu = ({
38748
38842
  onMouseLeave: () => setHoveredItem(null),
38749
38843
  onTouchStart: () => setHoveredItem("darkBackground"),
38750
38844
  children: [
38751
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: darkBackgroundEnabled && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38752
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Dark Background" })
38845
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: darkBackgroundEnabled && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38846
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Dark Background" })
38753
38847
  ]
38754
38848
  }
38755
38849
  ),
@@ -38769,13 +38863,13 @@ var AppearanceMenu = ({
38769
38863
  onMouseLeave: () => setHoveredItem(null),
38770
38864
  onTouchStart: () => setHoveredItem("lighting"),
38771
38865
  children: [
38772
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: lightingEnabled && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38773
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Lighting" })
38866
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: lightingEnabled && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38867
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Lighting" })
38774
38868
  ]
38775
38869
  }
38776
38870
  ),
38777
38871
  showLayerControls && /* @__PURE__ */ jsxs9(Fragment10, { children: [
38778
- /* @__PURE__ */ jsx38(DropdownMenuSeparator, { style: separatorStyles }),
38872
+ /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles }),
38779
38873
  /* @__PURE__ */ jsxs9(
38780
38874
  DropdownMenuItem,
38781
38875
  {
@@ -38792,8 +38886,8 @@ var AppearanceMenu = ({
38792
38886
  onMouseLeave: () => setHoveredItem(null),
38793
38887
  onTouchStart: () => setHoveredItem("boardBody"),
38794
38888
  children: [
38795
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.boardBody && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38796
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Board Body" })
38889
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.boardBody && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38890
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Board Body" })
38797
38891
  ]
38798
38892
  }
38799
38893
  ),
@@ -38813,8 +38907,8 @@ var AppearanceMenu = ({
38813
38907
  onMouseLeave: () => setHoveredItem(null),
38814
38908
  onTouchStart: () => setHoveredItem("topCopper"),
38815
38909
  children: [
38816
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.topCopper && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38817
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Top Copper" })
38910
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.topCopper && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38911
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Top Copper" })
38818
38912
  ]
38819
38913
  }
38820
38914
  ),
@@ -38834,8 +38928,8 @@ var AppearanceMenu = ({
38834
38928
  onMouseLeave: () => setHoveredItem(null),
38835
38929
  onTouchStart: () => setHoveredItem("bottomCopper"),
38836
38930
  children: [
38837
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.bottomCopper && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38838
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Copper" })
38931
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.bottomCopper && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38932
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Copper" })
38839
38933
  ]
38840
38934
  }
38841
38935
  ),
@@ -38855,8 +38949,8 @@ var AppearanceMenu = ({
38855
38949
  onMouseLeave: () => setHoveredItem(null),
38856
38950
  onTouchStart: () => setHoveredItem("keepout"),
38857
38951
  children: [
38858
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.keepout && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38859
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Keepout" })
38952
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.keepout && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38953
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Keepout" })
38860
38954
  ]
38861
38955
  }
38862
38956
  ),
@@ -38879,8 +38973,8 @@ var AppearanceMenu = ({
38879
38973
  onMouseLeave: () => setHoveredItem(null),
38880
38974
  onTouchStart: () => setHoveredItem("topSilkscreen"),
38881
38975
  children: [
38882
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.topSilkscreen && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38883
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Top Silkscreen" })
38976
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.topSilkscreen && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38977
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Top Silkscreen" })
38884
38978
  ]
38885
38979
  }
38886
38980
  ),
@@ -38903,8 +38997,8 @@ var AppearanceMenu = ({
38903
38997
  onMouseLeave: () => setHoveredItem(null),
38904
38998
  onTouchStart: () => setHoveredItem("bottomSilkscreen"),
38905
38999
  children: [
38906
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.bottomSilkscreen && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38907
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Silkscreen" })
39000
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.bottomSilkscreen && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39001
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Silkscreen" })
38908
39002
  ]
38909
39003
  }
38910
39004
  ),
@@ -38924,8 +39018,8 @@ var AppearanceMenu = ({
38924
39018
  onMouseLeave: () => setHoveredItem(null),
38925
39019
  onTouchStart: () => setHoveredItem("topMask"),
38926
39020
  children: [
38927
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.topMask && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38928
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Top Soldermask" })
39021
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.topMask && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39022
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Top Soldermask" })
38929
39023
  ]
38930
39024
  }
38931
39025
  ),
@@ -38945,8 +39039,8 @@ var AppearanceMenu = ({
38945
39039
  onMouseLeave: () => setHoveredItem(null),
38946
39040
  onTouchStart: () => setHoveredItem("bottomMask"),
38947
39041
  children: [
38948
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.bottomMask && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38949
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Soldermask" })
39042
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.bottomMask && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39043
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Soldermask" })
38950
39044
  ]
38951
39045
  }
38952
39046
  ),
@@ -38966,8 +39060,8 @@ var AppearanceMenu = ({
38966
39060
  onMouseLeave: () => setHoveredItem(null),
38967
39061
  onTouchStart: () => setHoveredItem("pcbNotes"),
38968
39062
  children: [
38969
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.pcbNotes && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38970
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "PCB Notes" })
39063
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.pcbNotes && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39064
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "PCB Notes" })
38971
39065
  ]
38972
39066
  }
38973
39067
  ),
@@ -38987,8 +39081,8 @@ var AppearanceMenu = ({
38987
39081
  onMouseLeave: () => setHoveredItem(null),
38988
39082
  onTouchStart: () => setHoveredItem("smtModels"),
38989
39083
  children: [
38990
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.smtModels && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38991
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Surface Mount Components" })
39084
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.smtModels && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39085
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Surface Mount Components" })
38992
39086
  ]
38993
39087
  }
38994
39088
  ),
@@ -39011,12 +39105,12 @@ var AppearanceMenu = ({
39011
39105
  onMouseLeave: () => setHoveredItem(null),
39012
39106
  onTouchStart: () => setHoveredItem("throughHoleModels"),
39013
39107
  children: [
39014
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.throughHoleModels && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
39015
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Through-Hole Components" })
39108
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.throughHoleModels && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39109
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Through-Hole Components" })
39016
39110
  ]
39017
39111
  }
39018
39112
  ),
39019
- /* @__PURE__ */ jsx38(DropdownMenuSeparator, { style: separatorStyles }),
39113
+ /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles }),
39020
39114
  /* @__PURE__ */ jsxs9(
39021
39115
  DropdownMenuItem,
39022
39116
  {
@@ -39038,10 +39132,10 @@ var AppearanceMenu = ({
39038
39132
  title: `Enclosure: ${visibility.enclosure}`,
39039
39133
  children: [
39040
39134
  /* @__PURE__ */ jsxs9("span", { style: iconContainerStyles, children: [
39041
- visibility.enclosure === "opaque" && /* @__PURE__ */ jsx38(CheckIcon, {}),
39042
- visibility.enclosure === "translucent" && /* @__PURE__ */ jsx38(CheckMinusIcon, {})
39135
+ visibility.enclosure === "opaque" && /* @__PURE__ */ jsx39(CheckIcon, {}),
39136
+ visibility.enclosure === "translucent" && /* @__PURE__ */ jsx39(CheckMinusIcon, {})
39043
39137
  ] }),
39044
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Enclosure" })
39138
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Enclosure" })
39045
39139
  ]
39046
39140
  }
39047
39141
  ),
@@ -39058,8 +39152,8 @@ var AppearanceMenu = ({
39058
39152
  onMouseLeave: () => setHoveredItem(null),
39059
39153
  onTouchStart: () => setHoveredItem("assembly"),
39060
39154
  children: [
39061
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.assembly && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
39062
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Assembly" })
39155
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.assembly && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39156
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Assembly" })
39063
39157
  ]
39064
39158
  }
39065
39159
  )
@@ -39072,7 +39166,7 @@ var AppearanceMenu = ({
39072
39166
  };
39073
39167
 
39074
39168
  // src/components/ContextMenu.tsx
39075
- import { Fragment as Fragment11, jsx as jsx39, jsxs as jsxs10 } from "react/jsx-runtime";
39169
+ import { Fragment as Fragment11, jsx as jsx40, jsxs as jsxs10 } from "react/jsx-runtime";
39076
39170
  var cameraOptions = [
39077
39171
  "Custom",
39078
39172
  "Top Center Angled",
@@ -39159,12 +39253,14 @@ var ContextMenu = ({
39159
39253
  onReferenceObjectSelect = () => {
39160
39254
  },
39161
39255
  onViewSchematicComponent,
39162
- componentName,
39163
- onHideComponent,
39164
- onUnhideAllComponents,
39256
+ objectName,
39257
+ onHideObject,
39258
+ onIsolateObject,
39259
+ onUnhideAll,
39165
39260
  onSectionView,
39166
39261
  onExplosionView,
39167
39262
  explosionAvailable = false,
39263
+ downloadModelName,
39168
39264
  onDownloadGltf,
39169
39265
  onOpenKeyboardShortcuts
39170
39266
  }) => {
@@ -39174,7 +39270,7 @@ var ContextMenu = ({
39174
39270
  const [advancedSubOpen, setAdvancedSubOpen] = useState42(false);
39175
39271
  const [referenceObjectSubOpen, setReferenceObjectSubOpen] = useState42(false);
39176
39272
  const [hoveredItem, setHoveredItem] = useState42(null);
39177
- return /* @__PURE__ */ jsx39(
39273
+ return /* @__PURE__ */ jsx40(
39178
39274
  "div",
39179
39275
  {
39180
39276
  ref: menuRef,
@@ -39186,8 +39282,8 @@ var ContextMenu = ({
39186
39282
  height: 0
39187
39283
  },
39188
39284
  children: /* @__PURE__ */ jsxs10(DropdownMenu, { open: true, modal: false, children: [
39189
- /* @__PURE__ */ jsx39(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx39("div", { style: { position: "absolute", width: 1, height: 1 } }) }),
39190
- /* @__PURE__ */ jsx39(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs10(
39285
+ /* @__PURE__ */ jsx40(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx40("div", { style: { position: "absolute", width: 1, height: 1 } }) }),
39286
+ /* @__PURE__ */ jsx40(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs10(
39191
39287
  DropdownMenuContent,
39192
39288
  {
39193
39289
  style: contentStyles2,
@@ -39196,7 +39292,7 @@ var ContextMenu = ({
39196
39292
  sideOffset: 0,
39197
39293
  align: "start",
39198
39294
  children: [
39199
- onHideComponent && /* @__PURE__ */ jsx39(
39295
+ onHideObject && /* @__PURE__ */ jsx40(
39200
39296
  DropdownMenuItem,
39201
39297
  {
39202
39298
  style: {
@@ -39204,13 +39300,27 @@ var ContextMenu = ({
39204
39300
  ...itemPaddingStyles2,
39205
39301
  backgroundColor: hoveredItem === "hide" ? "#404040" : "transparent"
39206
39302
  },
39207
- onSelect: onHideComponent,
39303
+ onSelect: onHideObject,
39208
39304
  onMouseEnter: () => setHoveredItem("hide"),
39209
39305
  onMouseLeave: () => setHoveredItem(null),
39210
- children: `Hide "${componentName}"`
39306
+ children: `Hide "${objectName}"`
39307
+ }
39308
+ ),
39309
+ onIsolateObject && /* @__PURE__ */ jsx40(
39310
+ DropdownMenuItem,
39311
+ {
39312
+ style: {
39313
+ ...itemStyles2,
39314
+ ...itemPaddingStyles2,
39315
+ backgroundColor: hoveredItem === "isolate" ? "#404040" : "transparent"
39316
+ },
39317
+ onSelect: onIsolateObject,
39318
+ onMouseEnter: () => setHoveredItem("isolate"),
39319
+ onMouseLeave: () => setHoveredItem(null),
39320
+ children: `Isolate "${objectName}"`
39211
39321
  }
39212
39322
  ),
39213
- onViewSchematicComponent && /* @__PURE__ */ jsx39(Fragment11, { children: /* @__PURE__ */ jsx39(
39323
+ onViewSchematicComponent && /* @__PURE__ */ jsx40(Fragment11, { children: /* @__PURE__ */ jsx40(
39214
39324
  DropdownMenuItem,
39215
39325
  {
39216
39326
  style: {
@@ -39224,7 +39334,7 @@ var ContextMenu = ({
39224
39334
  children: "Show on schematic"
39225
39335
  }
39226
39336
  ) }),
39227
- onUnhideAllComponents && /* @__PURE__ */ jsx39(
39337
+ onUnhideAll && /* @__PURE__ */ jsx40(
39228
39338
  DropdownMenuItem,
39229
39339
  {
39230
39340
  style: {
@@ -39232,13 +39342,13 @@ var ContextMenu = ({
39232
39342
  ...itemPaddingStyles2,
39233
39343
  backgroundColor: hoveredItem === "unhide" ? "#404040" : "transparent"
39234
39344
  },
39235
- onSelect: onUnhideAllComponents,
39345
+ onSelect: onUnhideAll,
39236
39346
  onMouseEnter: () => setHoveredItem("unhide"),
39237
39347
  onMouseLeave: () => setHoveredItem(null),
39238
- children: "Unhide All Components"
39348
+ children: "Unhide All"
39239
39349
  }
39240
39350
  ),
39241
- (onViewSchematicComponent || onHideComponent || onUnhideAllComponents) && /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles2 }),
39351
+ (onViewSchematicComponent || onHideObject || onIsolateObject || onUnhideAll) && /* @__PURE__ */ jsx40(DropdownMenuSeparator, { style: separatorStyles2 }),
39242
39352
  /* @__PURE__ */ jsxs10(DropdownMenuSub, { onOpenChange: setCameraSubOpen, children: [
39243
39353
  /* @__PURE__ */ jsxs10(
39244
39354
  DropdownMenuSubTrigger,
@@ -39252,7 +39362,7 @@ var ContextMenu = ({
39252
39362
  onMouseLeave: () => setHoveredItem(null),
39253
39363
  onTouchStart: () => setHoveredItem("camera"),
39254
39364
  children: [
39255
- /* @__PURE__ */ jsx39(
39365
+ /* @__PURE__ */ jsx40(
39256
39366
  "span",
39257
39367
  {
39258
39368
  style: { flex: 1, display: "flex", alignItems: "center" },
@@ -39269,15 +39379,15 @@ var ContextMenu = ({
39269
39379
  marginLeft: "auto"
39270
39380
  },
39271
39381
  children: [
39272
- /* @__PURE__ */ jsx39("span", { style: { opacity: 0.55, fontSize: 13 }, children: cameraPreset }),
39273
- /* @__PURE__ */ jsx39(ChevronRightIcon, { isOpen: cameraSubOpen })
39382
+ /* @__PURE__ */ jsx40("span", { style: { opacity: 0.55, fontSize: 13 }, children: cameraPreset }),
39383
+ /* @__PURE__ */ jsx40(ChevronRightIcon, { isOpen: cameraSubOpen })
39274
39384
  ]
39275
39385
  }
39276
39386
  )
39277
39387
  ]
39278
39388
  }
39279
39389
  ),
39280
- /* @__PURE__ */ jsx39(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs10(
39390
+ /* @__PURE__ */ jsx40(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs10(
39281
39391
  ViewportSubContent,
39282
39392
  {
39283
39393
  style: { ...contentStyles2, marginLeft: -2 },
@@ -39296,13 +39406,13 @@ var ContextMenu = ({
39296
39406
  onMouseLeave: () => setHoveredItem(null),
39297
39407
  onTouchStart: () => setHoveredItem(option),
39298
39408
  children: [
39299
- /* @__PURE__ */ jsx39("span", { style: iconContainerStyles2, children: cameraPreset === option && /* @__PURE__ */ jsx39(DotIcon, {}) }),
39300
- /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: option })
39409
+ /* @__PURE__ */ jsx40("span", { style: iconContainerStyles2, children: cameraPreset === option && /* @__PURE__ */ jsx40(DotIcon, {}) }),
39410
+ /* @__PURE__ */ jsx40("span", { style: { display: "flex", alignItems: "center" }, children: option })
39301
39411
  ]
39302
39412
  },
39303
39413
  option
39304
39414
  )),
39305
- /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles2 }),
39415
+ /* @__PURE__ */ jsx40(DropdownMenuSeparator, { style: separatorStyles2 }),
39306
39416
  /* @__PURE__ */ jsxs10(
39307
39417
  DropdownMenuItem,
39308
39418
  {
@@ -39315,8 +39425,8 @@ var ContextMenu = ({
39315
39425
  onMouseLeave: () => setHoveredItem(null),
39316
39426
  onTouchStart: () => setHoveredItem("autorotate"),
39317
39427
  children: [
39318
- /* @__PURE__ */ jsx39("span", { style: iconContainerStyles2, children: autoRotate && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39319
- /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Auto rotate" })
39428
+ /* @__PURE__ */ jsx40("span", { style: iconContainerStyles2, children: autoRotate && /* @__PURE__ */ jsx40(CheckIcon, {}) }),
39429
+ /* @__PURE__ */ jsx40("span", { style: { display: "flex", alignItems: "center" }, children: "Auto rotate" })
39320
39430
  ]
39321
39431
  }
39322
39432
  ),
@@ -39337,8 +39447,8 @@ var ContextMenu = ({
39337
39447
  onMouseLeave: () => setHoveredItem(null),
39338
39448
  onTouchStart: () => setHoveredItem("cameratype"),
39339
39449
  children: [
39340
- /* @__PURE__ */ jsx39("span", { style: iconContainerStyles2, children: cameraType === "orthographic" && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39341
- /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Orthographic Camera" })
39450
+ /* @__PURE__ */ jsx40("span", { style: iconContainerStyles2, children: cameraType === "orthographic" && /* @__PURE__ */ jsx40(CheckIcon, {}) }),
39451
+ /* @__PURE__ */ jsx40("span", { style: { display: "flex", alignItems: "center" }, children: "Orthographic Camera" })
39342
39452
  ]
39343
39453
  }
39344
39454
  )
@@ -39359,14 +39469,14 @@ var ContextMenu = ({
39359
39469
  onMouseLeave: () => setHoveredItem(null),
39360
39470
  onTouchStart: () => setHoveredItem("reference-object"),
39361
39471
  children: [
39362
- /* @__PURE__ */ jsx39(
39472
+ /* @__PURE__ */ jsx40(
39363
39473
  "span",
39364
39474
  {
39365
39475
  style: { flex: 1, display: "flex", alignItems: "center" },
39366
39476
  children: "Show Reference Object"
39367
39477
  }
39368
39478
  ),
39369
- /* @__PURE__ */ jsx39(
39479
+ /* @__PURE__ */ jsx40(
39370
39480
  "div",
39371
39481
  {
39372
39482
  style: {
@@ -39375,13 +39485,13 @@ var ContextMenu = ({
39375
39485
  gap: 6,
39376
39486
  marginLeft: "auto"
39377
39487
  },
39378
- children: /* @__PURE__ */ jsx39(ChevronRightIcon, { isOpen: referenceObjectSubOpen })
39488
+ children: /* @__PURE__ */ jsx40(ChevronRightIcon, { isOpen: referenceObjectSubOpen })
39379
39489
  }
39380
39490
  )
39381
39491
  ]
39382
39492
  }
39383
39493
  ),
39384
- /* @__PURE__ */ jsx39(DropdownMenuPortal, { children: /* @__PURE__ */ jsx39(
39494
+ /* @__PURE__ */ jsx40(DropdownMenuPortal, { children: /* @__PURE__ */ jsx40(
39385
39495
  ViewportSubContent,
39386
39496
  {
39387
39497
  style: { ...contentStyles2, marginLeft: -2 },
@@ -39405,8 +39515,8 @@ var ContextMenu = ({
39405
39515
  onMouseLeave: () => setHoveredItem(null),
39406
39516
  onTouchStart: () => setHoveredItem(optionKey),
39407
39517
  children: [
39408
- /* @__PURE__ */ jsx39("span", { style: iconContainerStyles2, children: referenceObject === option.type && /* @__PURE__ */ jsx39(DotIcon, {}) }),
39409
- /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: option.label })
39518
+ /* @__PURE__ */ jsx40("span", { style: iconContainerStyles2, children: referenceObject === option.type && /* @__PURE__ */ jsx40(DotIcon, {}) }),
39519
+ /* @__PURE__ */ jsx40("span", { style: { display: "flex", alignItems: "center" }, children: option.label })
39410
39520
  ]
39411
39521
  },
39412
39522
  optionKey
@@ -39427,8 +39537,8 @@ var ContextMenu = ({
39427
39537
  onMouseEnter: () => setHoveredItem("fold"),
39428
39538
  onMouseLeave: () => setHoveredItem(null),
39429
39539
  children: [
39430
- /* @__PURE__ */ jsx39("span", { style: iconContainerStyles2, children: foldPcbs && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39431
- /* @__PURE__ */ jsx39("span", { children: "Fold PCBs" })
39540
+ /* @__PURE__ */ jsx40("span", { style: iconContainerStyles2, children: foldPcbs && /* @__PURE__ */ jsx40(CheckIcon, {}) }),
39541
+ /* @__PURE__ */ jsx40("span", { children: "Fold PCBs" })
39432
39542
  ]
39433
39543
  }
39434
39544
  ),
@@ -39448,20 +39558,20 @@ var ContextMenu = ({
39448
39558
  onMouseLeave: () => setHoveredItem(null),
39449
39559
  onTouchStart: () => setHoveredItem("grid"),
39450
39560
  children: [
39451
- /* @__PURE__ */ jsx39("span", { style: iconContainerStyles2, children: gridEnabled && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39452
- /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Show Grid" })
39561
+ /* @__PURE__ */ jsx40("span", { style: iconContainerStyles2, children: gridEnabled && /* @__PURE__ */ jsx40(CheckIcon, {}) }),
39562
+ /* @__PURE__ */ jsx40("span", { style: { display: "flex", alignItems: "center" }, children: "Show Grid" })
39453
39563
  ]
39454
39564
  }
39455
39565
  ),
39456
- /* @__PURE__ */ jsx39(
39566
+ /* @__PURE__ */ jsx40(
39457
39567
  AppearanceMenu,
39458
39568
  {
39459
39569
  hasAssembly,
39460
39570
  showLayerControls: !preRendered
39461
39571
  }
39462
39572
  ),
39463
- /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles2 }),
39464
- /* @__PURE__ */ jsx39(
39573
+ /* @__PURE__ */ jsx40(DropdownMenuSeparator, { style: separatorStyles2 }),
39574
+ /* @__PURE__ */ jsxs10(
39465
39575
  DropdownMenuItem,
39466
39576
  {
39467
39577
  style: {
@@ -39473,10 +39583,13 @@ var ContextMenu = ({
39473
39583
  onMouseEnter: () => setHoveredItem("download"),
39474
39584
  onMouseLeave: () => setHoveredItem(null),
39475
39585
  onTouchStart: () => setHoveredItem("download"),
39476
- children: /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Download GLTF" })
39586
+ children: [
39587
+ /* @__PURE__ */ jsx40("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Download GLTF" }),
39588
+ downloadModelName && /* @__PURE__ */ jsx40("span", { style: { opacity: 0.55, fontSize: 13 }, children: downloadModelName })
39589
+ ]
39477
39590
  }
39478
39591
  ),
39479
- /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles2 }),
39592
+ /* @__PURE__ */ jsx40(DropdownMenuSeparator, { style: separatorStyles2 }),
39480
39593
  (onSectionView || onExplosionView || !flexScene && !preRendered) && /* @__PURE__ */ jsxs10(Fragment11, { children: [
39481
39594
  /* @__PURE__ */ jsxs10(DropdownMenuSub, { onOpenChange: setAdvancedSubOpen, children: [
39482
39595
  /* @__PURE__ */ jsxs10(
@@ -39491,12 +39604,12 @@ var ContextMenu = ({
39491
39604
  onMouseLeave: () => setHoveredItem(null),
39492
39605
  onTouchStart: () => setHoveredItem("advanced"),
39493
39606
  children: [
39494
- /* @__PURE__ */ jsx39("span", { style: { flex: 1 }, children: "Advanced" }),
39495
- /* @__PURE__ */ jsx39(ChevronRightIcon, { isOpen: advancedSubOpen })
39607
+ /* @__PURE__ */ jsx40("span", { style: { flex: 1 }, children: "Advanced" }),
39608
+ /* @__PURE__ */ jsx40(ChevronRightIcon, { isOpen: advancedSubOpen })
39496
39609
  ]
39497
39610
  }
39498
39611
  ),
39499
- /* @__PURE__ */ jsx39(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs10(
39612
+ /* @__PURE__ */ jsx40(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs10(
39500
39613
  ViewportSubContent,
39501
39614
  {
39502
39615
  style: { ...contentStyles2, marginLeft: -2 },
@@ -39524,7 +39637,7 @@ var ContextMenu = ({
39524
39637
  ]
39525
39638
  }
39526
39639
  ),
39527
- onExplosionView && /* @__PURE__ */ jsx39(
39640
+ onExplosionView && /* @__PURE__ */ jsx40(
39528
39641
  DropdownMenuItem,
39529
39642
  {
39530
39643
  disabled: !explosionAvailable,
@@ -39540,7 +39653,7 @@ var ContextMenu = ({
39540
39653
  children: "Exploded view\u2026"
39541
39654
  }
39542
39655
  ),
39543
- onSectionView && /* @__PURE__ */ jsx39(
39656
+ onSectionView && /* @__PURE__ */ jsx40(
39544
39657
  DropdownMenuItem,
39545
39658
  {
39546
39659
  style: {
@@ -39558,7 +39671,7 @@ var ContextMenu = ({
39558
39671
  }
39559
39672
  ) })
39560
39673
  ] }),
39561
- /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles2 })
39674
+ /* @__PURE__ */ jsx40(DropdownMenuSeparator, { style: separatorStyles2 })
39562
39675
  ] }),
39563
39676
  /* @__PURE__ */ jsxs10(
39564
39677
  DropdownMenuItem,
@@ -39573,8 +39686,8 @@ var ContextMenu = ({
39573
39686
  onMouseLeave: () => setHoveredItem(null),
39574
39687
  onTouchStart: () => setHoveredItem("shortcuts"),
39575
39688
  children: [
39576
- /* @__PURE__ */ jsx39("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Keyboard Shortcuts" }),
39577
- /* @__PURE__ */ jsx39(
39689
+ /* @__PURE__ */ jsx40("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Keyboard Shortcuts" }),
39690
+ /* @__PURE__ */ jsx40(
39578
39691
  "div",
39579
39692
  {
39580
39693
  style: {
@@ -39588,8 +39701,8 @@ var ContextMenu = ({
39588
39701
  ]
39589
39702
  }
39590
39703
  ),
39591
- /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles2 }),
39592
- /* @__PURE__ */ jsx39(
39704
+ /* @__PURE__ */ jsx40(DropdownMenuSeparator, { style: separatorStyles2 }),
39705
+ /* @__PURE__ */ jsx40(
39593
39706
  "div",
39594
39707
  {
39595
39708
  style: {
@@ -39627,10 +39740,10 @@ var ContextMenu = ({
39627
39740
  };
39628
39741
 
39629
39742
  // src/components/KeyboardShortcutsDialog.tsx
39630
- import { useEffect as useEffect54, useMemo as useMemo40, useRef as useRef28, useState as useState44 } from "react";
39743
+ import { useEffect as useEffect55, useMemo as useMemo41, useRef as useRef28, useState as useState44 } from "react";
39631
39744
 
39632
39745
  // src/hooks/useRegisteredHotkey.ts
39633
- import { useEffect as useEffect53, useMemo as useMemo39, useRef as useRef27, useState as useState43 } from "react";
39746
+ import { useEffect as useEffect54, useMemo as useMemo40, useRef as useRef27, useState as useState43 } from "react";
39634
39747
  var hotkeyRegistry = /* @__PURE__ */ new Map();
39635
39748
  var subscribers = /* @__PURE__ */ new Set();
39636
39749
  var isListenerAttached = false;
@@ -39754,14 +39867,14 @@ var subscribeToRegistry = (subscriber) => {
39754
39867
  var useRegisteredHotkey = (id, handler, metadata) => {
39755
39868
  const handlerRef = useRef27(handler);
39756
39869
  handlerRef.current = handler;
39757
- const normalizedMetadata = useMemo39(
39870
+ const normalizedMetadata = useMemo40(
39758
39871
  () => ({
39759
39872
  shortcut: metadata.shortcut,
39760
39873
  description: metadata.description
39761
39874
  }),
39762
39875
  [metadata.shortcut, metadata.description]
39763
39876
  );
39764
- useEffect53(() => {
39877
+ useEffect54(() => {
39765
39878
  const registration = {
39766
39879
  id,
39767
39880
  ...normalizedMetadata,
@@ -39777,7 +39890,7 @@ var useHotkeyRegistry = () => {
39777
39890
  const [entries, setEntries] = useState43(
39778
39891
  () => Array.from(hotkeyRegistry.values())
39779
39892
  );
39780
- useEffect53(() => subscribeToRegistry(setEntries), []);
39893
+ useEffect54(() => subscribeToRegistry(setEntries), []);
39781
39894
  return entries;
39782
39895
  };
39783
39896
  var registerHotkeyViewer = (element) => {
@@ -39786,7 +39899,7 @@ var registerHotkeyViewer = (element) => {
39786
39899
  };
39787
39900
 
39788
39901
  // src/components/KeyboardShortcutsDialog.tsx
39789
- import { jsx as jsx40, jsxs as jsxs11 } from "react/jsx-runtime";
39902
+ import { jsx as jsx41, jsxs as jsxs11 } from "react/jsx-runtime";
39790
39903
  var KeyboardShortcutsDialog = ({
39791
39904
  open,
39792
39905
  onClose
@@ -39794,7 +39907,7 @@ var KeyboardShortcutsDialog = ({
39794
39907
  const [query, setQuery] = useState44("");
39795
39908
  const inputRef = useRef28(null);
39796
39909
  const hotkeys = useHotkeyRegistry();
39797
- useEffect54(() => {
39910
+ useEffect55(() => {
39798
39911
  if (!open) return void 0;
39799
39912
  const handleKeyDown = (event) => {
39800
39913
  if (event.key === "Escape") {
@@ -39805,14 +39918,14 @@ var KeyboardShortcutsDialog = ({
39805
39918
  window.addEventListener("keydown", handleKeyDown);
39806
39919
  return () => window.removeEventListener("keydown", handleKeyDown);
39807
39920
  }, [open, onClose]);
39808
- useEffect54(() => {
39921
+ useEffect55(() => {
39809
39922
  if (open) {
39810
39923
  setTimeout(() => {
39811
39924
  inputRef.current?.focus();
39812
39925
  }, 0);
39813
39926
  }
39814
39927
  }, [open]);
39815
- const filteredHotkeys = useMemo40(() => {
39928
+ const filteredHotkeys = useMemo41(() => {
39816
39929
  const normalizedQuery = query.trim().toLowerCase();
39817
39930
  if (!normalizedQuery) {
39818
39931
  return hotkeys;
@@ -39825,7 +39938,7 @@ var KeyboardShortcutsDialog = ({
39825
39938
  if (!open) {
39826
39939
  return null;
39827
39940
  }
39828
- return /* @__PURE__ */ jsx40(
39941
+ return /* @__PURE__ */ jsx41(
39829
39942
  "div",
39830
39943
  {
39831
39944
  role: "dialog",
@@ -39865,7 +39978,7 @@ var KeyboardShortcutsDialog = ({
39865
39978
  },
39866
39979
  children: [
39867
39980
  /* @__PURE__ */ jsxs11("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
39868
- /* @__PURE__ */ jsx40(
39981
+ /* @__PURE__ */ jsx41(
39869
39982
  "h2",
39870
39983
  {
39871
39984
  style: {
@@ -39877,7 +39990,7 @@ var KeyboardShortcutsDialog = ({
39877
39990
  children: "Keyboard Shortcuts"
39878
39991
  }
39879
39992
  ),
39880
- /* @__PURE__ */ jsx40(
39993
+ /* @__PURE__ */ jsx41(
39881
39994
  "button",
39882
39995
  {
39883
39996
  type: "button",
@@ -39893,7 +40006,7 @@ var KeyboardShortcutsDialog = ({
39893
40006
  }
39894
40007
  )
39895
40008
  ] }),
39896
- /* @__PURE__ */ jsx40(
40009
+ /* @__PURE__ */ jsx41(
39897
40010
  "input",
39898
40011
  {
39899
40012
  ref: inputRef,
@@ -39916,7 +40029,7 @@ var KeyboardShortcutsDialog = ({
39916
40029
  ]
39917
40030
  }
39918
40031
  ),
39919
- /* @__PURE__ */ jsx40("div", { style: { overflowY: "auto" }, children: /* @__PURE__ */ jsxs11(
40032
+ /* @__PURE__ */ jsx41("div", { style: { overflowY: "auto" }, children: /* @__PURE__ */ jsxs11(
39920
40033
  "table",
39921
40034
  {
39922
40035
  style: {
@@ -39925,11 +40038,11 @@ var KeyboardShortcutsDialog = ({
39925
40038
  fontSize: "0.95rem"
39926
40039
  },
39927
40040
  children: [
39928
- /* @__PURE__ */ jsx40("thead", { children: /* @__PURE__ */ jsxs11("tr", { style: { textAlign: "left", color: "#a1a1b5" }, children: [
39929
- /* @__PURE__ */ jsx40("th", { style: { padding: "12px 24px", width: "25%" }, children: "Key" }),
39930
- /* @__PURE__ */ jsx40("th", { style: { padding: "12px 24px" }, children: "Description" })
40041
+ /* @__PURE__ */ jsx41("thead", { children: /* @__PURE__ */ jsxs11("tr", { style: { textAlign: "left", color: "#a1a1b5" }, children: [
40042
+ /* @__PURE__ */ jsx41("th", { style: { padding: "12px 24px", width: "25%" }, children: "Key" }),
40043
+ /* @__PURE__ */ jsx41("th", { style: { padding: "12px 24px" }, children: "Description" })
39931
40044
  ] }) }),
39932
- /* @__PURE__ */ jsx40("tbody", { children: filteredHotkeys.length === 0 ? /* @__PURE__ */ jsx40("tr", { children: /* @__PURE__ */ jsx40(
40045
+ /* @__PURE__ */ jsx41("tbody", { children: filteredHotkeys.length === 0 ? /* @__PURE__ */ jsx41("tr", { children: /* @__PURE__ */ jsx41(
39933
40046
  "td",
39934
40047
  {
39935
40048
  colSpan: 2,
@@ -39941,7 +40054,7 @@ var KeyboardShortcutsDialog = ({
39941
40054
  {
39942
40055
  style: { borderTop: "1px solid rgba(255, 255, 255, 0.05)" },
39943
40056
  children: [
39944
- /* @__PURE__ */ jsx40("td", { style: { padding: "12px 24px" }, children: /* @__PURE__ */ jsx40(
40057
+ /* @__PURE__ */ jsx41("td", { style: { padding: "12px 24px" }, children: /* @__PURE__ */ jsx41(
39945
40058
  "span",
39946
40059
  {
39947
40060
  style: {
@@ -39959,7 +40072,7 @@ var KeyboardShortcutsDialog = ({
39959
40072
  children: hotkey.shortcut
39960
40073
  }
39961
40074
  ) }),
39962
- /* @__PURE__ */ jsx40("td", { style: { padding: "12px 24px" }, children: hotkey.description })
40075
+ /* @__PURE__ */ jsx41("td", { style: { padding: "12px 24px" }, children: hotkey.description })
39963
40076
  ]
39964
40077
  },
39965
40078
  hotkey.id
@@ -39976,7 +40089,7 @@ var KeyboardShortcutsDialog = ({
39976
40089
 
39977
40090
  // src/contexts/ToastContext.tsx
39978
40091
  import { Toaster, toast as hotToast } from "react-hot-toast";
39979
- import { Fragment as Fragment12, jsx as jsx41, jsxs as jsxs12 } from "react/jsx-runtime";
40092
+ import { Fragment as Fragment12, jsx as jsx42, jsxs as jsxs12 } from "react/jsx-runtime";
39980
40093
  var useToast = () => {
39981
40094
  return {
39982
40095
  showToast: (message, duration = 2e3) => {
@@ -39989,7 +40102,7 @@ var ToastProvider = ({
39989
40102
  }) => {
39990
40103
  return /* @__PURE__ */ jsxs12(Fragment12, { children: [
39991
40104
  children,
39992
- /* @__PURE__ */ jsx41(Toaster, { position: "bottom-right" })
40105
+ /* @__PURE__ */ jsx42(Toaster, { position: "bottom-right" })
39993
40106
  ] });
39994
40107
  };
39995
40108
 
@@ -40034,7 +40147,7 @@ function useCameraPreset({
40034
40147
  }
40035
40148
 
40036
40149
  // src/hooks/useContextMenu.ts
40037
- import { useState as useState45, useCallback as useCallback23, useRef as useRef29, useEffect as useEffect55 } from "react";
40150
+ import { useState as useState45, useCallback as useCallback23, useRef as useRef29, useEffect as useEffect56 } from "react";
40038
40151
  var useContextMenu = ({ containerRef, onOpen }) => {
40039
40152
  const [menuVisible, setMenuVisible] = useState45(false);
40040
40153
  const [menuPos, setMenuPos] = useState45({
@@ -40151,7 +40264,7 @@ var useContextMenu = ({ containerRef, onOpen }) => {
40151
40264
  }
40152
40265
  setMenuVisible(false);
40153
40266
  }, []);
40154
- useEffect55(() => {
40267
+ useEffect56(() => {
40155
40268
  if (menuVisible) {
40156
40269
  document.addEventListener("mousedown", handleClickAway);
40157
40270
  document.addEventListener("touchstart", handleClickAway);
@@ -40185,33 +40298,33 @@ var useContextMenu = ({ containerRef, onOpen }) => {
40185
40298
  };
40186
40299
 
40187
40300
  // src/sections/section-export.ts
40188
- import * as THREE62 from "three";
40301
+ import * as THREE63 from "three";
40189
40302
  function createSectionExport(root, spec) {
40190
40303
  root.updateWorldMatrix(true, true);
40191
40304
  const output = root.clone(true);
40192
40305
  output.updateWorldMatrix(true, true);
40193
40306
  const plane = sectionPlane(spec);
40194
40307
  const hatch = createSectionHatch();
40195
- const capMaterial = new THREE62.MeshBasicMaterial({
40308
+ const capMaterial = new THREE63.MeshBasicMaterial({
40196
40309
  map: hatch,
40197
- side: THREE62.DoubleSide
40310
+ side: THREE63.DoubleSide
40198
40311
  });
40199
40312
  const ownedGeometries = [];
40200
40313
  const ownedMaterials = [capMaterial];
40201
40314
  output.traverse((object) => {
40202
- if (!(object instanceof THREE62.Mesh)) return;
40315
+ if (!(object instanceof THREE63.Mesh)) return;
40203
40316
  const indexed = Boolean(object.geometry.index);
40204
40317
  const source = object.geometry.index ? object.geometry.toNonIndexed() : object.geometry;
40205
40318
  const p = source.getAttribute("position");
40206
40319
  if (!p) return;
40207
40320
  const worldPositions = new Float32Array(p.count * 3);
40208
- const world = new THREE62.Vector3();
40321
+ const world = new THREE63.Vector3();
40209
40322
  for (let i = 0; i < p.count; i++)
40210
40323
  world.fromBufferAttribute(p, i).applyMatrix4(object.matrixWorld).toArray(worldPositions, i * 3);
40211
40324
  const attributes = Object.entries(source.attributes);
40212
40325
  const values = new Map(attributes.map(([name]) => [name, []]));
40213
- const geometry = new THREE62.BufferGeometry();
40214
- const point = (i) => new THREE62.Vector3().fromArray(worldPositions, i * 3);
40326
+ const geometry = new THREE63.BufferGeometry();
40327
+ const point = (i) => new THREE63.Vector3().fromArray(worldPositions, i * 3);
40215
40328
  for (let i = 0; i < p.count; i += 3) {
40216
40329
  let polygon2 = [
40217
40330
  [1, 0, 0],
@@ -40260,7 +40373,7 @@ function createSectionExport(root, spec) {
40260
40373
  for (const [name, attribute] of attributes)
40261
40374
  geometry.setAttribute(
40262
40375
  name,
40263
- new THREE62.Float32BufferAttribute(values.get(name), attribute.itemSize)
40376
+ new THREE63.Float32BufferAttribute(values.get(name), attribute.itemSize)
40264
40377
  );
40265
40378
  if (geometry.getAttribute("normal")) geometry.normalizeNormals();
40266
40379
  ownedGeometries.push(geometry);
@@ -40274,18 +40387,18 @@ function createSectionExport(root, spec) {
40274
40387
  object.material = Array.isArray(object.material) ? object.material.map(cloneMaterial) : cloneMaterial(object.material);
40275
40388
  const { loops } = findSectionLoops({ positions: worldPositions, ...spec });
40276
40389
  const cap = buildSectionCap(loops, spec);
40277
- cap.applyMatrix4(new THREE62.Matrix4().copy(object.matrixWorld).invert());
40390
+ cap.applyMatrix4(new THREE63.Matrix4().copy(object.matrixWorld).invert());
40278
40391
  ownedGeometries.push(cap);
40279
40392
  object.userData.sectionExportCap = cap;
40280
40393
  if (indexed) source.dispose();
40281
40394
  });
40282
40395
  const pending = [];
40283
40396
  output.traverse((object) => {
40284
- if (object instanceof THREE62.Mesh && object.userData.sectionExportCap)
40397
+ if (object instanceof THREE63.Mesh && object.userData.sectionExportCap)
40285
40398
  pending.push(object);
40286
40399
  });
40287
40400
  for (const mesh of pending) {
40288
- mesh.add(new THREE62.Mesh(mesh.userData.sectionExportCap, capMaterial));
40401
+ mesh.add(new THREE63.Mesh(mesh.userData.sectionExportCap, capMaterial));
40289
40402
  delete mesh.userData.sectionExportCap;
40290
40403
  }
40291
40404
  delete output.userData.sectionView;
@@ -40302,39 +40415,56 @@ function createSectionExport(root, spec) {
40302
40415
  // src/hooks/useGlobalDownloadGltf.ts
40303
40416
  import { useCallback as useCallback24 } from "react";
40304
40417
  import { GLTFExporter as GLTFExporter2 } from "three/examples/jsm/exporters/GLTFExporter.js";
40418
+
40419
+ // src/utils/clone-model-for-export.ts
40420
+ var cloneModelForExport = (root, objectId) => {
40421
+ const source = findModelObject(root, objectId);
40422
+ if (!source) return;
40423
+ source.updateWorldMatrix(true, true);
40424
+ const output = source.clone(true);
40425
+ source.matrixWorld.decompose(output.position, output.quaternion, output.scale);
40426
+ return output;
40427
+ };
40428
+
40429
+ // src/hooks/useGlobalDownloadGltf.ts
40305
40430
  var useGlobalDownloadGltf = () => {
40306
- return useCallback24(() => {
40307
- const root = window.__TSCIRCUIT_THREE_OBJECT;
40308
- if (!root) return;
40309
- const section = root.userData.sectionView;
40310
- const sectionExport = section ? createSectionExport(root, section) : void 0;
40311
- const exporter = new GLTFExporter2();
40312
- exporter.parse(
40313
- sectionExport?.root ?? root,
40314
- (gltf) => {
40315
- sectionExport?.dispose();
40316
- const blob = new Blob(
40317
- [gltf instanceof ArrayBuffer ? gltf : JSON.stringify(gltf)],
40318
- { type: "model/gltf+json" }
40319
- );
40320
- const url = URL.createObjectURL(blob);
40321
- const link = document.createElement("a");
40322
- link.href = url;
40323
- link.download = "scene.gltf";
40324
- link.click();
40325
- URL.revokeObjectURL(url);
40326
- },
40327
- (err) => {
40328
- sectionExport?.dispose();
40329
- console.error("Failed to export GLTF", err);
40330
- }
40331
- );
40332
- }, []);
40431
+ return useCallback24(
40432
+ (model, root = window.__TSCIRCUIT_THREE_OBJECT) => {
40433
+ if (!root) return;
40434
+ const target = model ? cloneModelForExport(root, model.objectId) : root;
40435
+ if (!target) return;
40436
+ if (model) target.name = model.name;
40437
+ const section = root.userData.sectionView;
40438
+ const sectionExport = section ? createSectionExport(target, section) : void 0;
40439
+ const exporter = new GLTFExporter2();
40440
+ exporter.parse(
40441
+ sectionExport?.root ?? target,
40442
+ (gltf) => {
40443
+ sectionExport?.dispose();
40444
+ const blob = new Blob(
40445
+ [gltf instanceof ArrayBuffer ? gltf : JSON.stringify(gltf)],
40446
+ { type: "model/gltf+json" }
40447
+ );
40448
+ const url = URL.createObjectURL(blob);
40449
+ const link = document.createElement("a");
40450
+ link.href = url;
40451
+ link.download = model ? `${model.name}.gltf` : "scene.gltf";
40452
+ link.click();
40453
+ URL.revokeObjectURL(url);
40454
+ },
40455
+ (err) => {
40456
+ sectionExport?.dispose();
40457
+ console.error("Failed to export GLTF", err);
40458
+ }
40459
+ );
40460
+ },
40461
+ []
40462
+ );
40333
40463
  };
40334
40464
 
40335
40465
  // src/CadViewer.tsx
40336
- import { jsx as jsx42, jsxs as jsxs13 } from "react/jsx-runtime";
40337
- var DEFAULT_TARGET = new THREE63.Vector3(0, 0, 0);
40466
+ import { jsx as jsx43, jsxs as jsxs13 } from "react/jsx-runtime";
40467
+ var DEFAULT_TARGET = new THREE64.Vector3(0, 0, 0);
40338
40468
  var INITIAL_CAMERA_POSITION = [5, -5, 5];
40339
40469
  var readStoredCameraType = () => {
40340
40470
  if (typeof window === "undefined") return void 0;
@@ -40364,12 +40494,12 @@ var CadViewerInner = (props) => {
40364
40494
  const resolvedFoldPcbs = resolveFoldPcbs(circuitJson, foldPcbs);
40365
40495
  const circuitJsonKey = glbSource === void 0 ? JSON.stringify(circuitJson) : void 0;
40366
40496
  const circuitKey = glbSource ?? circuitJsonKey;
40367
- const { hiddenCadComponentIds, hideComponent, unhideAllComponents } = useHiddenCadComponents(circuitKey);
40497
+ const { objectVisibility, hideObject, isolateObject, unhideAllObjects } = useObjectVisibility(circuitKey);
40368
40498
  const resolvedProps = {
40369
40499
  ...props,
40370
40500
  circuitJson,
40371
40501
  children: void 0,
40372
- hiddenCadComponentIds
40502
+ objectVisibility
40373
40503
  };
40374
40504
  const [engine, setEngine] = useState46(() => {
40375
40505
  const stored = window.localStorage.getItem("cadViewerEngine");
@@ -40394,11 +40524,14 @@ var CadViewerInner = (props) => {
40394
40524
  const externalCameraControllerReady = props.onCameraControllerReady;
40395
40525
  const sceneRef = useContext13(SchematicNavigationContext);
40396
40526
  const [selectedComponent, setSelectedComponent] = useState46();
40397
- const [selectedCadComponent, setSelectedCadComponent] = useState46();
40527
+ const [selectedObject, setSelectedObject] = useState46();
40528
+ const [selectedModel, setSelectedModel] = useState46();
40398
40529
  const handleMenuOpen = useCallback25(
40399
40530
  (position) => {
40400
- setSelectedCadComponent(
40401
- pickCadComponent(sceneRef.current, position, circuitJson)
40531
+ const picked = pickSceneObject(sceneRef.current, position, circuitJson);
40532
+ setSelectedObject(picked);
40533
+ setSelectedModel(
40534
+ picked && sceneRef.current && findModelObject(sceneRef.current.rootObject, picked.objectId) ? picked : void 0
40402
40535
  );
40403
40536
  setSelectedComponent(
40404
40537
  props.onViewSchematicComponent ? pickSchematicComponent(sceneRef.current, position, circuitJson) : void 0
@@ -40511,28 +40644,28 @@ var CadViewerInner = (props) => {
40511
40644
  description: "Toggle translucent components"
40512
40645
  }
40513
40646
  );
40514
- useEffect56(() => {
40647
+ useEffect57(() => {
40515
40648
  if (containerRef.current) {
40516
40649
  registerHotkeyViewer(containerRef.current);
40517
40650
  }
40518
40651
  }, []);
40519
- useEffect56(() => {
40652
+ useEffect57(() => {
40520
40653
  window.localStorage.setItem("cadViewerEngine", engine);
40521
40654
  }, [engine]);
40522
- useEffect56(() => {
40655
+ useEffect57(() => {
40523
40656
  window.localStorage.setItem("cadViewerAutoRotate", String(autoRotate));
40524
40657
  }, [autoRotate]);
40525
- useEffect56(() => {
40658
+ useEffect57(() => {
40526
40659
  window.localStorage.setItem(
40527
40660
  "cadViewerAutoRotateUserToggled",
40528
40661
  String(autoRotateUserToggled)
40529
40662
  );
40530
40663
  }, [autoRotateUserToggled]);
40531
- useEffect56(() => {
40664
+ useEffect57(() => {
40532
40665
  window.localStorage.setItem("cadViewerCameraType", cameraType);
40533
40666
  }, [cameraType]);
40534
40667
  const viewerKey = props.circuitJson ? circuitJsonKey : void 0;
40535
- return /* @__PURE__ */ jsx42(AssemblyExplosionContext.Provider, { value: explosion, children: /* @__PURE__ */ jsxs13(
40668
+ return /* @__PURE__ */ jsx43(AssemblyExplosionContext.Provider, { value: explosion, children: /* @__PURE__ */ jsxs13(
40536
40669
  "div",
40537
40670
  {
40538
40671
  ref: containerRef,
@@ -40548,7 +40681,7 @@ var CadViewerInner = (props) => {
40548
40681
  },
40549
40682
  ...contextMenuEventHandlers,
40550
40683
  children: [
40551
- explosionPanelOpen && /* @__PURE__ */ jsx42(
40684
+ explosionPanelOpen && /* @__PURE__ */ jsx43(
40552
40685
  AssemblyExplosionControl,
40553
40686
  {
40554
40687
  stages: explosion.stages,
@@ -40561,18 +40694,18 @@ var CadViewerInner = (props) => {
40561
40694
  }
40562
40695
  }
40563
40696
  ),
40564
- glbSource !== void 0 ? /* @__PURE__ */ jsx42(
40697
+ glbSource !== void 0 ? /* @__PURE__ */ jsx43(
40565
40698
  CadViewerGlb,
40566
40699
  {
40567
40700
  source: glbSource,
40568
- hiddenCadComponentIds,
40701
+ objectVisibility,
40569
40702
  autoRotateDisabled: props.autoRotateDisabled || !autoRotate,
40570
40703
  clickToInteractEnabled: props.clickToInteractEnabled,
40571
40704
  onUserInteraction: handleUserInteraction,
40572
40705
  onCameraControllerReady: handleCameraControllerReady,
40573
40706
  referenceObject
40574
40707
  }
40575
- ) : hasFlexGeometry ? /* @__PURE__ */ jsx42(
40708
+ ) : hasFlexGeometry ? /* @__PURE__ */ jsx43(
40576
40709
  CadViewerManifold_default,
40577
40710
  {
40578
40711
  ...resolvedProps,
@@ -40582,7 +40715,7 @@ var CadViewerInner = (props) => {
40582
40715
  onCameraControllerReady: handleCameraControllerReady,
40583
40716
  referenceObject
40584
40717
  }
40585
- ) : engine === "jscad" ? /* @__PURE__ */ jsx42(
40718
+ ) : engine === "jscad" ? /* @__PURE__ */ jsx43(
40586
40719
  CadViewerJscad,
40587
40720
  {
40588
40721
  ...resolvedProps,
@@ -40592,7 +40725,7 @@ var CadViewerInner = (props) => {
40592
40725
  onCameraControllerReady: handleCameraControllerReady,
40593
40726
  referenceObject
40594
40727
  }
40595
- ) : /* @__PURE__ */ jsx42(
40728
+ ) : /* @__PURE__ */ jsx43(
40596
40729
  CadViewerManifold_default,
40597
40730
  {
40598
40731
  ...resolvedProps,
@@ -40603,18 +40736,22 @@ var CadViewerInner = (props) => {
40603
40736
  referenceObject
40604
40737
  }
40605
40738
  ),
40606
- /* @__PURE__ */ jsx42(SectionPanel, {}),
40607
- menuVisible && /* @__PURE__ */ jsx42(
40739
+ /* @__PURE__ */ jsx43(SectionPanel, {}),
40740
+ menuVisible && /* @__PURE__ */ jsx43(
40608
40741
  ContextMenu,
40609
40742
  {
40610
40743
  hasAssembly,
40611
- componentName: selectedCadComponent?.componentName,
40612
- onHideComponent: selectedCadComponent ? () => {
40613
- hideComponent(selectedCadComponent.cad_component_id);
40744
+ objectName: selectedObject?.name,
40745
+ onHideObject: selectedObject ? () => {
40746
+ hideObject(selectedObject.objectId);
40747
+ closeMenu();
40748
+ } : void 0,
40749
+ onIsolateObject: selectedObject && objectVisibility.isolatedId !== selectedObject.objectId ? () => {
40750
+ isolateObject(selectedObject.objectId);
40614
40751
  closeMenu();
40615
40752
  } : void 0,
40616
- onUnhideAllComponents: hiddenCadComponentIds.size > 0 ? () => {
40617
- unhideAllComponents();
40753
+ onUnhideAll: hasHiddenObjects(objectVisibility) ? () => {
40754
+ unhideAllObjects();
40618
40755
  closeMenu();
40619
40756
  } : void 0,
40620
40757
  onViewSchematicComponent: selectedComponent && props.onViewSchematicComponent ? () => {
@@ -40673,8 +40810,9 @@ var CadViewerInner = (props) => {
40673
40810
  setCameraPreset("Custom");
40674
40811
  closeMenu();
40675
40812
  },
40813
+ downloadModelName: selectedModel?.name,
40676
40814
  onDownloadGltf: () => {
40677
- downloadGltf();
40815
+ downloadGltf(selectedModel, sceneRef.current?.rootObject);
40678
40816
  closeMenu();
40679
40817
  },
40680
40818
  onOpenKeyboardShortcuts: () => {
@@ -40683,7 +40821,7 @@ var CadViewerInner = (props) => {
40683
40821
  }
40684
40822
  }
40685
40823
  ),
40686
- /* @__PURE__ */ jsx42(
40824
+ /* @__PURE__ */ jsx43(
40687
40825
  KeyboardShortcutsDialog,
40688
40826
  {
40689
40827
  open: isKeyboardShortcutsDialogOpen,
@@ -40698,13 +40836,13 @@ var CadViewerInner = (props) => {
40698
40836
  var CadViewer = (props) => {
40699
40837
  configureRuntimeFont();
40700
40838
  const sceneRef = useRef30(null);
40701
- return /* @__PURE__ */ jsx42(SchematicNavigationContext.Provider, { value: sceneRef, children: /* @__PURE__ */ jsx42(
40839
+ return /* @__PURE__ */ jsx43(SchematicNavigationContext.Provider, { value: sceneRef, children: /* @__PURE__ */ jsx43(
40702
40840
  CameraControllerProvider,
40703
40841
  {
40704
40842
  defaultTarget: DEFAULT_TARGET,
40705
40843
  initialCameraPosition: INITIAL_CAMERA_POSITION,
40706
40844
  initialCameraType: readStoredCameraType(),
40707
- children: /* @__PURE__ */ jsx42(LayerVisibilityProvider, { children: /* @__PURE__ */ jsx42(AppearanceProvider, { children: /* @__PURE__ */ jsx42(ToastProvider, { children: /* @__PURE__ */ jsx42(SectionProvider, { children: /* @__PURE__ */ jsx42(CadViewerInner, { ...props }) }) }) }) })
40845
+ children: /* @__PURE__ */ jsx43(LayerVisibilityProvider, { children: /* @__PURE__ */ jsx43(AppearanceProvider, { children: /* @__PURE__ */ jsx43(ToastProvider, { children: /* @__PURE__ */ jsx43(SectionProvider, { children: /* @__PURE__ */ jsx43(CadViewerInner, { ...props }) }) }) }) })
40708
40846
  }
40709
40847
  ) });
40710
40848
  };
@@ -40712,11 +40850,11 @@ var CadViewer = (props) => {
40712
40850
  // src/convert-circuit-json-to-3d-svg.ts
40713
40851
  var import_debug = __toESM(require_browser(), 1);
40714
40852
  import { su as su18 } from "@tscircuit/circuit-json-util";
40715
- import * as THREE67 from "three";
40853
+ import * as THREE68 from "three";
40716
40854
  import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
40717
40855
 
40718
40856
  // src/utils/create-geometry-from-polygons.ts
40719
- import * as THREE64 from "three";
40857
+ import * as THREE65 from "three";
40720
40858
  import { BufferGeometry as BufferGeometry9, Float32BufferAttribute as Float32BufferAttribute8 } from "three";
40721
40859
  function createGeometryFromPolygons(polygons) {
40722
40860
  const geometry = new BufferGeometry9();
@@ -40730,12 +40868,12 @@ function createGeometryFromPolygons(polygons) {
40730
40868
  ...polygon2.vertices[i + 1]
40731
40869
  // Third vertex
40732
40870
  );
40733
- const v1 = new THREE64.Vector3(...polygon2.vertices[0]);
40734
- const v2 = new THREE64.Vector3(...polygon2.vertices[i]);
40735
- const v3 = new THREE64.Vector3(...polygon2.vertices[i + 1]);
40736
- const normal = new THREE64.Vector3().crossVectors(
40737
- new THREE64.Vector3().subVectors(v2, v1),
40738
- new THREE64.Vector3().subVectors(v3, v1)
40871
+ const v1 = new THREE65.Vector3(...polygon2.vertices[0]);
40872
+ const v2 = new THREE65.Vector3(...polygon2.vertices[i]);
40873
+ const v3 = new THREE65.Vector3(...polygon2.vertices[i + 1]);
40874
+ const normal = new THREE65.Vector3().crossVectors(
40875
+ new THREE65.Vector3().subVectors(v2, v1),
40876
+ new THREE65.Vector3().subVectors(v3, v1)
40739
40877
  ).normalize();
40740
40878
  normals.push(
40741
40879
  normal.x,
@@ -40763,10 +40901,10 @@ import {
40763
40901
  convertCSGToThreeGeom as convertCSGToThreeGeom3,
40764
40902
  getJscadModelForFootprint as getJscadModelForFootprint2
40765
40903
  } from "jscad-electronics/vanilla";
40766
- import * as THREE66 from "three";
40904
+ import * as THREE67 from "three";
40767
40905
 
40768
40906
  // src/utils/load-model.ts
40769
- import * as THREE65 from "three";
40907
+ import * as THREE66 from "three";
40770
40908
  import { GLTFLoader as GLTFLoader3 } from "three/examples/jsm/loaders/GLTFLoader.js";
40771
40909
  import { OBJLoader as OBJLoader2 } from "three/examples/jsm/loaders/OBJLoader.js";
40772
40910
  import { STLLoader as STLLoader3 } from "three/examples/jsm/loaders/STLLoader.js";
@@ -40774,12 +40912,12 @@ async function load3DModel(url) {
40774
40912
  if (url.endsWith(".stl")) {
40775
40913
  const loader = new STLLoader3();
40776
40914
  const geometry = await loader.loadAsync(url);
40777
- const material = new THREE65.MeshStandardMaterial({
40915
+ const material = new THREE66.MeshStandardMaterial({
40778
40916
  color: 8947848,
40779
40917
  metalness: 0.5,
40780
40918
  roughness: 0.5
40781
40919
  });
40782
- return new THREE65.Mesh(geometry, material);
40920
+ return new THREE66.Mesh(geometry, material);
40783
40921
  }
40784
40922
  if (url.endsWith(".obj")) {
40785
40923
  const loader = new OBJLoader2();
@@ -40812,9 +40950,9 @@ async function renderComponent(component, scene) {
40812
40950
  }
40813
40951
  if (component.rotation) {
40814
40952
  model.rotation.set(
40815
- THREE66.MathUtils.degToRad(component.rotation.x ?? 0),
40816
- THREE66.MathUtils.degToRad(component.rotation.y ?? 0),
40817
- THREE66.MathUtils.degToRad(component.rotation.z ?? 0)
40953
+ THREE67.MathUtils.degToRad(component.rotation.x ?? 0),
40954
+ THREE67.MathUtils.degToRad(component.rotation.y ?? 0),
40955
+ THREE67.MathUtils.degToRad(component.rotation.z ?? 0)
40818
40956
  );
40819
40957
  }
40820
40958
  scene.add(model);
@@ -40828,13 +40966,13 @@ async function renderComponent(component, scene) {
40828
40966
  );
40829
40967
  if (jscadObject && (jscadObject.polygons || jscadObject.sides)) {
40830
40968
  const threeGeom = convertCSGToThreeGeom3(jscadObject);
40831
- const material2 = new THREE66.MeshStandardMaterial({
40969
+ const material2 = new THREE67.MeshStandardMaterial({
40832
40970
  color: 8947848,
40833
40971
  metalness: 0.5,
40834
40972
  roughness: 0.5,
40835
- side: THREE66.DoubleSide
40973
+ side: THREE67.DoubleSide
40836
40974
  });
40837
- const mesh2 = new THREE66.Mesh(threeGeom, material2);
40975
+ const mesh2 = new THREE67.Mesh(threeGeom, material2);
40838
40976
  if (component.position) {
40839
40977
  mesh2.position.set(
40840
40978
  component.position.x ?? 0,
@@ -40844,9 +40982,9 @@ async function renderComponent(component, scene) {
40844
40982
  }
40845
40983
  if (component.rotation) {
40846
40984
  mesh2.rotation.set(
40847
- THREE66.MathUtils.degToRad(component.rotation.x ?? 0),
40848
- THREE66.MathUtils.degToRad(component.rotation.y ?? 0),
40849
- THREE66.MathUtils.degToRad(component.rotation.z ?? 0)
40985
+ THREE67.MathUtils.degToRad(component.rotation.x ?? 0),
40986
+ THREE67.MathUtils.degToRad(component.rotation.y ?? 0),
40987
+ THREE67.MathUtils.degToRad(component.rotation.z ?? 0)
40850
40988
  );
40851
40989
  }
40852
40990
  scene.add(mesh2);
@@ -40863,17 +41001,17 @@ async function renderComponent(component, scene) {
40863
41001
  if (!geom || !geom.polygons && !geom.sides) {
40864
41002
  continue;
40865
41003
  }
40866
- const color = new THREE66.Color(geomInfo.color);
41004
+ const color = new THREE67.Color(geomInfo.color);
40867
41005
  color.convertLinearToSRGB();
40868
41006
  const geomWithColor = { ...geom, color: [color.r, color.g, color.b] };
40869
41007
  const threeGeom = convertCSGToThreeGeom3(geomWithColor);
40870
- const material2 = new THREE66.MeshStandardMaterial({
41008
+ const material2 = new THREE67.MeshStandardMaterial({
40871
41009
  vertexColors: true,
40872
41010
  metalness: 0.2,
40873
41011
  roughness: 0.8,
40874
- side: THREE66.DoubleSide
41012
+ side: THREE67.DoubleSide
40875
41013
  });
40876
- const mesh2 = new THREE66.Mesh(threeGeom, material2);
41014
+ const mesh2 = new THREE67.Mesh(threeGeom, material2);
40877
41015
  if (component.position) {
40878
41016
  mesh2.position.set(
40879
41017
  component.position.x ?? 0,
@@ -40883,22 +41021,22 @@ async function renderComponent(component, scene) {
40883
41021
  }
40884
41022
  if (component.rotation) {
40885
41023
  mesh2.rotation.set(
40886
- THREE66.MathUtils.degToRad(component.rotation.x ?? 0),
40887
- THREE66.MathUtils.degToRad(component.rotation.y ?? 0),
40888
- THREE66.MathUtils.degToRad(component.rotation.z ?? 0)
41024
+ THREE67.MathUtils.degToRad(component.rotation.x ?? 0),
41025
+ THREE67.MathUtils.degToRad(component.rotation.y ?? 0),
41026
+ THREE67.MathUtils.degToRad(component.rotation.z ?? 0)
40889
41027
  );
40890
41028
  }
40891
41029
  scene.add(mesh2);
40892
41030
  }
40893
41031
  return;
40894
41032
  }
40895
- const geometry = new THREE66.BoxGeometry(0.5, 0.5, 0.5);
40896
- const material = new THREE66.MeshStandardMaterial({
41033
+ const geometry = new THREE67.BoxGeometry(0.5, 0.5, 0.5);
41034
+ const material = new THREE67.MeshStandardMaterial({
40897
41035
  color: 16711680,
40898
41036
  transparent: true,
40899
41037
  opacity: 0.25
40900
41038
  });
40901
- const mesh = new THREE66.Mesh(geometry, material);
41039
+ const mesh = new THREE67.Mesh(geometry, material);
40902
41040
  if (component.position) {
40903
41041
  mesh.position.set(
40904
41042
  component.position.x ?? 0,
@@ -40919,11 +41057,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
40919
41057
  padding = 20,
40920
41058
  zoom = 1.5
40921
41059
  } = options;
40922
- const scene = new THREE67.Scene();
41060
+ const scene = new THREE68.Scene();
40923
41061
  const renderer = new SVGRenderer();
40924
41062
  renderer.setSize(width, height);
40925
- renderer.setClearColor(new THREE67.Color(backgroundColor), 1);
40926
- const camera = new THREE67.OrthographicCamera();
41063
+ renderer.setClearColor(new THREE68.Color(backgroundColor), 1);
41064
+ const camera = new THREE68.OrthographicCamera();
40927
41065
  const aspect = width / height;
40928
41066
  const frustumSize = 100;
40929
41067
  const halfFrustumSize = frustumSize / 2 / zoom;
@@ -40937,11 +41075,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
40937
41075
  camera.position.set(position.x, position.y, position.z);
40938
41076
  camera.up.set(0, 1, 0);
40939
41077
  const lookAt2 = options.camera?.lookAt ?? { x: 0, y: 0, z: 0 };
40940
- camera.lookAt(new THREE67.Vector3(lookAt2.x, lookAt2.y, lookAt2.z));
41078
+ camera.lookAt(new THREE68.Vector3(lookAt2.x, lookAt2.y, lookAt2.z));
40941
41079
  camera.updateProjectionMatrix();
40942
- const ambientLight = new THREE67.AmbientLight(16777215, Math.PI / 2);
41080
+ const ambientLight = new THREE68.AmbientLight(16777215, Math.PI / 2);
40943
41081
  scene.add(ambientLight);
40944
- const pointLight = new THREE67.PointLight(16777215, Math.PI / 4);
41082
+ const pointLight = new THREE68.PointLight(16777215, Math.PI / 4);
40945
41083
  pointLight.position.set(-10, -10, 10);
40946
41084
  scene.add(pointLight);
40947
41085
  const components = su18(circuitJson).cad_component.list();
@@ -40973,28 +41111,28 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
40973
41111
  const material = createBoardMaterial({
40974
41112
  material: boardData?.material,
40975
41113
  color: edgeColor,
40976
- side: THREE67.DoubleSide
41114
+ side: THREE68.DoubleSide
40977
41115
  });
40978
- const mesh = new THREE67.Mesh(geometry, material);
41116
+ const mesh = new THREE68.Mesh(geometry, material);
40979
41117
  scene.add(mesh);
40980
41118
  }
40981
41119
  }
40982
- const gridColor = new THREE67.Color(8947848);
40983
- const gridHelper = new THREE67.GridHelper(100, 100, gridColor, gridColor);
41120
+ const gridColor = new THREE68.Color(8947848);
41121
+ const gridHelper = new THREE68.GridHelper(100, 100, gridColor, gridColor);
40984
41122
  gridHelper.rotation.x = Math.PI / 2;
40985
41123
  const materials2 = Array.isArray(gridHelper.material) ? gridHelper.material : [gridHelper.material];
40986
41124
  for (const mat of materials2) {
40987
41125
  mat.transparent = true;
40988
41126
  mat.opacity = 0.3;
40989
- if (mat instanceof THREE67.LineBasicMaterial) {
41127
+ if (mat instanceof THREE68.LineBasicMaterial) {
40990
41128
  mat.color = gridColor;
40991
41129
  mat.vertexColors = false;
40992
41130
  }
40993
41131
  }
40994
41132
  scene.add(gridHelper);
40995
- const box = new THREE67.Box3().setFromObject(scene);
40996
- const center = box.getCenter(new THREE67.Vector3());
40997
- const size4 = box.getSize(new THREE67.Vector3());
41133
+ const box = new THREE68.Box3().setFromObject(scene);
41134
+ const center = box.getCenter(new THREE68.Vector3());
41135
+ const size4 = box.getSize(new THREE68.Vector3());
40998
41136
  scene.position.sub(center);
40999
41137
  const maxDim = Math.max(size4.x, size4.y, size4.z);
41000
41138
  if (maxDim > 0) {
@@ -41014,10 +41152,10 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
41014
41152
  import {
41015
41153
  GLTFExporter as GLTFExporter3
41016
41154
  } from "three/examples/jsm/exporters/GLTFExporter.js";
41017
- import { useEffect as useEffect57, useState as useState47, useMemo as useMemo41, useCallback as useCallback26 } from "react";
41155
+ import { useEffect as useEffect58, useState as useState47, useMemo as useMemo42, useCallback as useCallback26 } from "react";
41018
41156
  function useSaveGltfAs(options = {}) {
41019
41157
  const parse2 = useParser(options);
41020
- const link = useMemo41(() => document.createElement("a"), []);
41158
+ const link = useMemo42(() => document.createElement("a"), []);
41021
41159
  const saveAs = async (filename) => {
41022
41160
  const name = filename ?? options.filename ?? "";
41023
41161
  if (options.binary == null) options.binary = name.endsWith(".glb");
@@ -41027,7 +41165,7 @@ function useSaveGltfAs(options = {}) {
41027
41165
  link.dispatchEvent(new MouseEvent("click"));
41028
41166
  URL.revokeObjectURL(url);
41029
41167
  };
41030
- useEffect57(
41168
+ useEffect58(
41031
41169
  () => () => {
41032
41170
  link.remove();
41033
41171
  instance = null;
@@ -41048,11 +41186,11 @@ function useExportGltfUrl(options = {}) {
41048
41186
  (instance) => parse2(instance).then(setUrl).catch(setError),
41049
41187
  []
41050
41188
  );
41051
- useEffect57(() => () => URL.revokeObjectURL(url), [url]);
41189
+ useEffect58(() => () => URL.revokeObjectURL(url), [url]);
41052
41190
  return [ref, url, error];
41053
41191
  }
41054
41192
  function useParser(options = {}) {
41055
- const exporter = useMemo41(() => new GLTFExporter3(), []);
41193
+ const exporter = useMemo42(() => new GLTFExporter3(), []);
41056
41194
  return (instance) => {
41057
41195
  const { promise, resolve, reject } = Promise.withResolvers();
41058
41196
  exporter.parse(