@tscircuit/3d-viewer 0.0.619 → 0.0.621

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.
Files changed (2) hide show
  1. package/dist/index.js +326 -284
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -18980,7 +18980,7 @@ var useHiddenCadComponents = (circuitKey) => {
18980
18980
 
18981
18981
  // src/CadViewer.tsx
18982
18982
  import { useCallback as useCallback24, useContext as useContext11, useEffect as useEffect51, useRef as useRef29, useState as useState42 } from "react";
18983
- import * as THREE55 from "three";
18983
+ import * as THREE56 from "three";
18984
18984
 
18985
18985
  // src/hooks/use-convert-children-to-soup.ts
18986
18986
  import { Circuit } from "@tscircuit/core";
@@ -20946,12 +20946,12 @@ var AnyCadComponent = ({
20946
20946
 
20947
20947
  // src/CadViewerContainer.tsx
20948
20948
  import { forwardRef as forwardRef2, useEffect as useEffect21, useMemo as useMemo17, useState as useState13 } from "react";
20949
- import * as THREE25 from "three";
20949
+ import * as THREE26 from "three";
20950
20950
 
20951
20951
  // package.json
20952
20952
  var package_default = {
20953
20953
  name: "@tscircuit/3d-viewer",
20954
- version: "0.0.618",
20954
+ version: "0.0.620",
20955
20955
  repository: {
20956
20956
  type: "git",
20957
20957
  url: "https://github.com/tscircuit/3d-viewer"
@@ -21879,8 +21879,36 @@ var Lights = ({
21879
21879
 
21880
21880
  // src/react-three/OrbitControls.tsx
21881
21881
  import { useEffect as useEffect18, useMemo as useMemo15 } from "react";
21882
- import * as THREE21 from "three";
21882
+ import * as THREE22 from "three";
21883
21883
  import { OrbitControls as ThreeOrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
21884
+
21885
+ // src/react-three/infinite-dolly.ts
21886
+ import * as THREE21 from "three";
21887
+ var MINIMUM_DOLLY_DISTANCE_RATIO = 0.05;
21888
+ var getMinimumDollyDistance = ({
21889
+ camera,
21890
+ initialOrbitDistance
21891
+ }) => {
21892
+ const scaledInitialOrbitDistance = Number.isFinite(initialOrbitDistance) ? initialOrbitDistance * MINIMUM_DOLLY_DISTANCE_RATIO : 0;
21893
+ return Math.max(scaledInitialOrbitDistance, camera.near, Number.EPSILON);
21894
+ };
21895
+ var applyInfiniteDolly = ({
21896
+ camera,
21897
+ controls,
21898
+ minimumDollyDistance
21899
+ }) => {
21900
+ if (!(camera instanceof THREE21.PerspectiveCamera)) return false;
21901
+ const orbitDistance = controls.getDistance();
21902
+ if (Number.isFinite(orbitDistance) && orbitDistance >= minimumDollyDistance) {
21903
+ return false;
21904
+ }
21905
+ const viewDirection = new THREE21.Vector3();
21906
+ camera.getWorldDirection(viewDirection);
21907
+ controls.target.copy(camera.position).addScaledVector(viewDirection, minimumDollyDistance);
21908
+ return true;
21909
+ };
21910
+
21911
+ // src/react-three/OrbitControls.tsx
21884
21912
  var OrbitControls = ({
21885
21913
  autoRotate,
21886
21914
  autoRotateSpeed,
@@ -21898,6 +21926,17 @@ var OrbitControls = ({
21898
21926
  if (!camera || !renderer) return null;
21899
21927
  return new ThreeOrbitControls(camera, renderer.domElement);
21900
21928
  }, [camera, renderer]);
21929
+ const minimumDollyDistance = useMemo15(() => {
21930
+ if (!controls || !(camera instanceof THREE22.PerspectiveCamera)) {
21931
+ return Number.EPSILON;
21932
+ }
21933
+ const initialOrbitDistance = target ? Math.hypot(
21934
+ camera.position.x - target[0],
21935
+ camera.position.y - target[1],
21936
+ camera.position.z - target[2]
21937
+ ) : controls.getDistance();
21938
+ return getMinimumDollyDistance({ camera, initialOrbitDistance });
21939
+ }, [camera, controls, target]);
21901
21940
  useEffect18(() => {
21902
21941
  onControlsChange?.(controls ?? null);
21903
21942
  return () => onControlsChange?.(null);
@@ -21923,9 +21962,9 @@ var OrbitControls = ({
21923
21962
  if (dampingFactor !== void 0) controls.dampingFactor = dampingFactor;
21924
21963
  controls.zoomToCursor = true;
21925
21964
  controls.mouseButtons = {
21926
- LEFT: THREE21.MOUSE.ROTATE,
21965
+ LEFT: THREE22.MOUSE.ROTATE,
21927
21966
  // Left click to rotate
21928
- MIDDLE: THREE21.MOUSE.PAN,
21967
+ MIDDLE: THREE22.MOUSE.PAN,
21929
21968
  // Middle click to pan
21930
21969
  RIGHT: null
21931
21970
  // Right-click always disabled - only context menu
@@ -21959,8 +21998,10 @@ var OrbitControls = ({
21959
21998
  };
21960
21999
  }, [controls]);
21961
22000
  useFrame(() => {
21962
- controls?.update();
21963
- }, [controls]);
22001
+ if (!controls) return;
22002
+ applyInfiniteDolly({ camera, controls, minimumDollyDistance });
22003
+ controls.update();
22004
+ }, [camera, controls, minimumDollyDistance]);
21964
22005
  return null;
21965
22006
  };
21966
22007
 
@@ -22047,14 +22088,14 @@ var getComparisonBounds = (type, boardDimensions, boardCenter) => {
22047
22088
 
22048
22089
  // src/three-components/OrientationCubeCanvas.tsx
22049
22090
  import { useEffect as useEffect19, useRef as useRef7 } from "react";
22050
- import * as THREE22 from "three";
22091
+ import * as THREE23 from "three";
22051
22092
  import { Text as TroikaText } from "troika-three-text";
22052
22093
  import { jsx as jsx14 } from "react/jsx-runtime";
22053
22094
  function computePointInFront(rotationVector, distance5) {
22054
- const quaternion = new THREE22.Quaternion().setFromEuler(
22055
- new THREE22.Euler(rotationVector.x, rotationVector.y, rotationVector.z)
22095
+ const quaternion = new THREE23.Quaternion().setFromEuler(
22096
+ new THREE23.Euler(rotationVector.x, rotationVector.y, rotationVector.z)
22056
22097
  );
22057
- const forwardVector = new THREE22.Vector3(0, 0, 1);
22098
+ const forwardVector = new THREE23.Vector3(0, 0, 1);
22058
22099
  forwardVector.applyQuaternion(quaternion);
22059
22100
  const result = forwardVector.multiplyScalar(distance5);
22060
22101
  return result;
@@ -22067,31 +22108,31 @@ var OrientationCubeCanvas = () => {
22067
22108
  const container = containerRef.current;
22068
22109
  const canvas = document.createElement("canvas");
22069
22110
  container.appendChild(canvas);
22070
- const renderer = new THREE22.WebGLRenderer({
22111
+ const renderer = new THREE23.WebGLRenderer({
22071
22112
  canvas,
22072
22113
  antialias: true,
22073
22114
  alpha: true
22074
22115
  });
22075
22116
  renderer.setSize(120, 120);
22076
22117
  renderer.setPixelRatio(window.devicePixelRatio);
22077
- const scene = new THREE22.Scene();
22078
- const camera = new THREE22.PerspectiveCamera(75, 1, 0.1, 1e3);
22118
+ const scene = new THREE23.Scene();
22119
+ const camera = new THREE23.PerspectiveCamera(75, 1, 0.1, 1e3);
22079
22120
  camera.up.set(0, 0, 1);
22080
- const ambientLight = new THREE22.AmbientLight(16777215, Math.PI / 2);
22121
+ const ambientLight = new THREE23.AmbientLight(16777215, Math.PI / 2);
22081
22122
  scene.add(ambientLight);
22082
- const group = new THREE22.Group();
22123
+ const group = new THREE23.Group();
22083
22124
  group.rotation.fromArray([Math.PI / 2, 0, 0]);
22084
22125
  const cubeSize = 1;
22085
- const box = new THREE22.Mesh(
22086
- new THREE22.BoxGeometry(cubeSize, cubeSize, cubeSize),
22087
- new THREE22.MeshStandardMaterial({ color: "white" })
22126
+ const box = new THREE23.Mesh(
22127
+ new THREE23.BoxGeometry(cubeSize, cubeSize, cubeSize),
22128
+ new THREE23.MeshStandardMaterial({ color: "white" })
22088
22129
  );
22089
22130
  group.add(box);
22090
- const edges = new THREE22.LineSegments(
22091
- new THREE22.EdgesGeometry(
22092
- new THREE22.BoxGeometry(cubeSize, cubeSize, cubeSize)
22131
+ const edges = new THREE23.LineSegments(
22132
+ new THREE23.EdgesGeometry(
22133
+ new THREE23.BoxGeometry(cubeSize, cubeSize, cubeSize)
22093
22134
  ),
22094
- new THREE22.LineBasicMaterial({ color: 0, linewidth: 2 })
22135
+ new THREE23.LineBasicMaterial({ color: 0, linewidth: 2 })
22095
22136
  );
22096
22137
  group.add(edges);
22097
22138
  scene.add(group);
@@ -22153,7 +22194,7 @@ var OrientationCubeCanvas = () => {
22153
22194
  if (!isVisible) return;
22154
22195
  if (mainCameraRef.current) {
22155
22196
  const cameraPosition = computePointInFront(
22156
- mainCameraRef.current.rotation ?? new THREE22.Euler(0, 0, 0),
22197
+ mainCameraRef.current.rotation ?? new THREE23.Euler(0, 0, 0),
22157
22198
  2
22158
22199
  );
22159
22200
  if (!cameraPosition.equals(camera.position)) {
@@ -22205,12 +22246,12 @@ var OrientationCubeCanvas = () => {
22205
22246
  import { useEffect as useEffect20, useMemo as useMemo16 } from "react";
22206
22247
 
22207
22248
  // src/reference-objects/create-reference-object.ts
22208
- import * as THREE23 from "three";
22249
+ import * as THREE24 from "three";
22209
22250
  var createRoundedRectangleShape = (width, height, radius) => {
22210
22251
  const halfWidth = width / 2;
22211
22252
  const halfHeight = height / 2;
22212
22253
  const safeRadius = Math.min(radius, halfWidth, halfHeight);
22213
- const shape = new THREE23.Shape();
22254
+ const shape = new THREE24.Shape();
22214
22255
  shape.moveTo(-halfWidth + safeRadius, -halfHeight);
22215
22256
  shape.lineTo(halfWidth - safeRadius, -halfHeight);
22216
22257
  shape.quadraticCurveTo(
@@ -22249,7 +22290,7 @@ var createRoundedPrismGeometry = (width, height, depth, radius) => {
22249
22290
  );
22250
22291
  };
22251
22292
  var createPrismGeometryFromShape = (shape, depth) => {
22252
- const geometry = new THREE23.ExtrudeGeometry(shape, {
22293
+ const geometry = new THREE24.ExtrudeGeometry(shape, {
22253
22294
  depth,
22254
22295
  bevelEnabled: false,
22255
22296
  curveSegments: 24
@@ -22261,16 +22302,16 @@ var createPrismGeometryFromShape = (shape, depth) => {
22261
22302
  var normalizeObjectToSpec = (object, type) => {
22262
22303
  const spec = REFERENCE_OBJECT_SPECS[type];
22263
22304
  object.updateMatrixWorld(true);
22264
- const initialBounds = new THREE23.Box3().setFromObject(object);
22265
- const initialSize = initialBounds.getSize(new THREE23.Vector3());
22305
+ const initialBounds = new THREE24.Box3().setFromObject(object);
22306
+ const initialSize = initialBounds.getSize(new THREE24.Vector3());
22266
22307
  object.scale.set(
22267
22308
  spec.width / initialSize.x,
22268
22309
  spec.height / initialSize.y,
22269
22310
  spec.depth / initialSize.z
22270
22311
  );
22271
22312
  object.updateMatrixWorld(true);
22272
- const scaledBounds = new THREE23.Box3().setFromObject(object);
22273
- const scaledCenter = scaledBounds.getCenter(new THREE23.Vector3());
22313
+ const scaledBounds = new THREE24.Box3().setFromObject(object);
22314
+ const scaledCenter = scaledBounds.getCenter(new THREE24.Vector3());
22274
22315
  object.position.set(
22275
22316
  -scaledCenter.x,
22276
22317
  -scaledCenter.y,
@@ -22279,15 +22320,15 @@ var normalizeObjectToSpec = (object, type) => {
22279
22320
  object.updateMatrixWorld(true);
22280
22321
  };
22281
22322
  var createBananaGeometry = () => {
22282
- const curve = new THREE23.CatmullRomCurve3([
22283
- new THREE23.Vector3(-82, 18, 16),
22284
- new THREE23.Vector3(-67, 7, 15),
22285
- new THREE23.Vector3(-43, -9, 14),
22286
- new THREE23.Vector3(-15, -18, 14),
22287
- new THREE23.Vector3(16, -18, 14),
22288
- new THREE23.Vector3(47, -8, 14.5),
22289
- new THREE23.Vector3(72, 8, 16),
22290
- new THREE23.Vector3(84, 19, 17)
22323
+ const curve = new THREE24.CatmullRomCurve3([
22324
+ new THREE24.Vector3(-82, 18, 16),
22325
+ new THREE24.Vector3(-67, 7, 15),
22326
+ new THREE24.Vector3(-43, -9, 14),
22327
+ new THREE24.Vector3(-15, -18, 14),
22328
+ new THREE24.Vector3(16, -18, 14),
22329
+ new THREE24.Vector3(47, -8, 14.5),
22330
+ new THREE24.Vector3(72, 8, 16),
22331
+ new THREE24.Vector3(84, 19, 17)
22291
22332
  ]);
22292
22333
  const tubularSegments = 84;
22293
22334
  const radialSegments = 30;
@@ -22297,8 +22338,8 @@ var createBananaGeometry = () => {
22297
22338
  const colors2 = [];
22298
22339
  const uvs = [];
22299
22340
  const indices = [];
22300
- const ripeYellow = new THREE23.Color(16766023);
22301
- const stemGreen = new THREE23.Color(12038965);
22341
+ const ripeYellow = new THREE24.Color(16766023);
22342
+ const stemGreen = new THREE24.Color(12038965);
22302
22343
  for (let segment = 0; segment <= tubularSegments; segment++) {
22303
22344
  const t = segment / tubularSegments;
22304
22345
  const point = curve.getPointAt(t);
@@ -22313,7 +22354,7 @@ var createBananaGeometry = () => {
22313
22354
  const sin = Math.sin(angle3);
22314
22355
  const cos = Math.cos(angle3);
22315
22356
  const ridgeScale = 1 + Math.cos(angle3 * 5 + 0.35) * 0.035;
22316
- const radialNormal = new THREE23.Vector3().addScaledVector(normal, cos).addScaledVector(binormal, sin * 0.9).normalize();
22357
+ const radialNormal = new THREE24.Vector3().addScaledVector(normal, cos).addScaledVector(binormal, sin * 0.9).normalize();
22317
22358
  const vertex = point.clone().addScaledVector(normal, cos * radius * ridgeScale).addScaledVector(binormal, sin * radius * 0.9 * ridgeScale);
22318
22359
  positions.push(vertex.x, vertex.y, vertex.z);
22319
22360
  normals.push(radialNormal.x, radialNormal.y, radialNormal.z);
@@ -22331,26 +22372,26 @@ var createBananaGeometry = () => {
22331
22372
  indices.push(a, d, b, b, d, c);
22332
22373
  }
22333
22374
  }
22334
- const geometry = new THREE23.BufferGeometry();
22375
+ const geometry = new THREE24.BufferGeometry();
22335
22376
  geometry.setIndex(indices);
22336
22377
  geometry.setAttribute(
22337
22378
  "position",
22338
- new THREE23.Float32BufferAttribute(positions, 3)
22379
+ new THREE24.Float32BufferAttribute(positions, 3)
22339
22380
  );
22340
- geometry.setAttribute("normal", new THREE23.Float32BufferAttribute(normals, 3));
22341
- geometry.setAttribute("color", new THREE23.Float32BufferAttribute(colors2, 3));
22342
- geometry.setAttribute("uv", new THREE23.Float32BufferAttribute(uvs, 2));
22381
+ geometry.setAttribute("normal", new THREE24.Float32BufferAttribute(normals, 3));
22382
+ geometry.setAttribute("color", new THREE24.Float32BufferAttribute(colors2, 3));
22383
+ geometry.setAttribute("uv", new THREE24.Float32BufferAttribute(uvs, 2));
22343
22384
  geometry.computeBoundingBox();
22344
22385
  geometry.computeBoundingSphere();
22345
22386
  return { geometry, curve };
22346
22387
  };
22347
22388
  var createBanana = () => {
22348
- const group = new THREE23.Group();
22349
- const banana = new THREE23.Group();
22389
+ const group = new THREE24.Group();
22390
+ const banana = new THREE24.Group();
22350
22391
  const { geometry, curve } = createBananaGeometry();
22351
- const peel = new THREE23.Mesh(
22392
+ const peel = new THREE24.Mesh(
22352
22393
  geometry,
22353
- new THREE23.MeshStandardMaterial({
22394
+ new THREE24.MeshStandardMaterial({
22354
22395
  color: 16777215,
22355
22396
  roughness: 0.72,
22356
22397
  metalness: 0,
@@ -22359,9 +22400,9 @@ var createBanana = () => {
22359
22400
  );
22360
22401
  peel.name = "banana-peel";
22361
22402
  banana.add(peel);
22362
- const blossomTip = new THREE23.Mesh(
22363
- new THREE23.SphereGeometry(3.4, 20, 12),
22364
- new THREE23.MeshStandardMaterial({
22403
+ const blossomTip = new THREE24.Mesh(
22404
+ new THREE24.SphereGeometry(3.4, 20, 12),
22405
+ new THREE24.MeshStandardMaterial({
22365
22406
  color: 6242844,
22366
22407
  roughness: 0.92
22367
22408
  })
@@ -22372,20 +22413,20 @@ var createBanana = () => {
22372
22413
  banana.add(blossomTip);
22373
22414
  const stemLength = 11;
22374
22415
  const stemTangent = curve.getTangentAt(1).normalize();
22375
- const stem = new THREE23.Mesh(
22376
- new THREE23.CylinderGeometry(2.5, 4.1, stemLength, 18),
22377
- new THREE23.MeshStandardMaterial({
22416
+ const stem = new THREE24.Mesh(
22417
+ new THREE24.CylinderGeometry(2.5, 4.1, stemLength, 18),
22418
+ new THREE24.MeshStandardMaterial({
22378
22419
  color: 8483625,
22379
22420
  roughness: 0.82
22380
22421
  })
22381
22422
  );
22382
- stem.quaternion.setFromUnitVectors(new THREE23.Vector3(0, 1, 0), stemTangent);
22423
+ stem.quaternion.setFromUnitVectors(new THREE24.Vector3(0, 1, 0), stemTangent);
22383
22424
  stem.position.copy(curve.getPointAt(1)).addScaledVector(stemTangent, stemLength / 2);
22384
22425
  stem.name = "banana-stem";
22385
22426
  banana.add(stem);
22386
- const stemTip = new THREE23.Mesh(
22387
- new THREE23.SphereGeometry(2.55, 18, 10),
22388
- new THREE23.MeshStandardMaterial({
22427
+ const stemTip = new THREE24.Mesh(
22428
+ new THREE24.SphereGeometry(2.55, 18, 10),
22429
+ new THREE24.MeshStandardMaterial({
22389
22430
  color: 5981470,
22390
22431
  roughness: 0.9
22391
22432
  })
@@ -22399,7 +22440,7 @@ var createBanana = () => {
22399
22440
  };
22400
22441
  var createMacbookLidGeometry = (width, height, depth, radius, indentRadius) => {
22401
22442
  const lidShape = createRoundedRectangleShape(width, height, radius);
22402
- const indent = new THREE23.Path();
22443
+ const indent = new THREE24.Path();
22403
22444
  indent.absarc(0, 0, indentRadius, 0, Math.PI * 2, true);
22404
22445
  lidShape.holes.push(indent);
22405
22446
  return createPrismGeometryFromShape(lidShape, depth);
@@ -22407,9 +22448,9 @@ var createMacbookLidGeometry = (width, height, depth, radius, indentRadius) => {
22407
22448
  var createMacbookIndent = (topZ, radius) => {
22408
22449
  const indentDepth = 0.35;
22409
22450
  const diskDepth = 0.25;
22410
- const disk = new THREE23.Mesh(
22411
- new THREE23.CylinderGeometry(radius - 0.15, radius - 0.15, diskDepth, 48),
22412
- new THREE23.MeshStandardMaterial({
22451
+ const disk = new THREE24.Mesh(
22452
+ new THREE24.CylinderGeometry(radius - 0.15, radius - 0.15, diskDepth, 48),
22453
+ new THREE24.MeshStandardMaterial({
22413
22454
  color: 10199202,
22414
22455
  roughness: 0.48,
22415
22456
  metalness: 0.28
@@ -22422,10 +22463,10 @@ var createMacbookIndent = (topZ, radius) => {
22422
22463
  };
22423
22464
  var createCreditCard = () => {
22424
22465
  const spec = REFERENCE_OBJECT_SPECS["credit-card"];
22425
- const group = new THREE23.Group();
22426
- const body = new THREE23.Mesh(
22466
+ const group = new THREE24.Group();
22467
+ const body = new THREE24.Mesh(
22427
22468
  createRoundedPrismGeometry(spec.width, spec.height, spec.depth, 3.18),
22428
- new THREE23.MeshStandardMaterial({
22469
+ new THREE24.MeshStandardMaterial({
22429
22470
  color: 2383272,
22430
22471
  roughness: 0.38,
22431
22472
  metalness: 0.08
@@ -22434,9 +22475,9 @@ var createCreditCard = () => {
22434
22475
  body.name = "credit-card-body";
22435
22476
  group.add(body);
22436
22477
  const surfaceZ = spec.depth / 2 + 0.08;
22437
- const chip = new THREE23.Mesh(
22478
+ const chip = new THREE24.Mesh(
22438
22479
  createRoundedPrismGeometry(12, 9, 0.14, 1.2),
22439
- new THREE23.MeshStandardMaterial({
22480
+ new THREE24.MeshStandardMaterial({
22440
22481
  color: 14003525,
22441
22482
  roughness: 0.3,
22442
22483
  metalness: 0.62
@@ -22445,14 +22486,14 @@ var createCreditCard = () => {
22445
22486
  chip.position.set(-21, 3, surfaceZ);
22446
22487
  chip.name = "credit-card-chip";
22447
22488
  group.add(chip);
22448
- const stripeMaterial = new THREE23.MeshStandardMaterial({
22489
+ const stripeMaterial = new THREE24.MeshStandardMaterial({
22449
22490
  color: 15331061,
22450
22491
  roughness: 0.45,
22451
22492
  metalness: 0.05
22452
22493
  });
22453
22494
  for (let index2 = 0; index2 < 4; index2++) {
22454
- const stripe = new THREE23.Mesh(
22455
- new THREE23.BoxGeometry(index2 === 3 ? 8 : 12, 0.8, 0.1),
22495
+ const stripe = new THREE24.Mesh(
22496
+ new THREE24.BoxGeometry(index2 === 3 ? 8 : 12, 0.8, 0.1),
22456
22497
  stripeMaterial
22457
22498
  );
22458
22499
  stripe.position.set(-20 + index2 * 14, -14, surfaceZ + 0.08);
@@ -22463,13 +22504,13 @@ var createCreditCard = () => {
22463
22504
  };
22464
22505
  var createMacbook = () => {
22465
22506
  const spec = REFERENCE_OBJECT_SPECS["14in-macbook"];
22466
- const group = new THREE23.Group();
22467
- const aluminumMaterial = new THREE23.MeshStandardMaterial({
22507
+ const group = new THREE24.Group();
22508
+ const aluminumMaterial = new THREE24.MeshStandardMaterial({
22468
22509
  color: 12896201,
22469
22510
  roughness: 0.3,
22470
22511
  metalness: 0.38
22471
22512
  });
22472
- const body = new THREE23.Mesh(
22513
+ const body = new THREE24.Mesh(
22473
22514
  createRoundedPrismGeometry(spec.width, spec.height, 13.5, 9),
22474
22515
  aluminumMaterial
22475
22516
  );
@@ -22480,7 +22521,7 @@ var createMacbook = () => {
22480
22521
  const lidCenterZ = 6.75;
22481
22522
  const lidTopZ = lidCenterZ + lidDepth / 2;
22482
22523
  const indentRadius = 12;
22483
- const lid = new THREE23.Mesh(
22524
+ const lid = new THREE24.Mesh(
22484
22525
  createMacbookLidGeometry(
22485
22526
  spec.width - 1.8,
22486
22527
  spec.height - 1.8,
@@ -22493,9 +22534,9 @@ var createMacbook = () => {
22493
22534
  lid.position.z = lidCenterZ;
22494
22535
  lid.name = "macbook-lid";
22495
22536
  group.add(lid);
22496
- const hinge = new THREE23.Mesh(
22497
- new THREE23.BoxGeometry(spec.width - 42, 3.2, 1.2),
22498
- new THREE23.MeshStandardMaterial({
22537
+ const hinge = new THREE24.Mesh(
22538
+ new THREE24.BoxGeometry(spec.width - 42, 3.2, 1.2),
22539
+ new THREE24.MeshStandardMaterial({
22499
22540
  color: 3158838,
22500
22541
  roughness: 0.55,
22501
22542
  metalness: 0.45
@@ -22505,9 +22546,9 @@ var createMacbook = () => {
22505
22546
  hinge.name = "macbook-hinge";
22506
22547
  group.add(hinge);
22507
22548
  group.add(createMacbookIndent(lidTopZ, indentRadius));
22508
- const frontNotch = new THREE23.Mesh(
22509
- new THREE23.BoxGeometry(54, 1.2, 0.8),
22510
- new THREE23.MeshStandardMaterial({
22549
+ const frontNotch = new THREE24.Mesh(
22550
+ new THREE24.BoxGeometry(54, 1.2, 0.8),
22551
+ new THREE24.MeshStandardMaterial({
22511
22552
  color: 6712174,
22512
22553
  roughness: 0.45,
22513
22554
  metalness: 0.5
@@ -22530,7 +22571,7 @@ var disposeReferenceObject = (object) => {
22530
22571
  const geometries = /* @__PURE__ */ new Set();
22531
22572
  const materials = /* @__PURE__ */ new Set();
22532
22573
  object.traverse((child) => {
22533
- if (!(child instanceof THREE23.Mesh)) return;
22574
+ if (!(child instanceof THREE24.Mesh)) return;
22534
22575
  geometries.add(child.geometry);
22535
22576
  const childMaterials = Array.isArray(child.material) ? child.material : [child.material];
22536
22577
  for (const material of childMaterials) materials.add(material);
@@ -22540,28 +22581,28 @@ var disposeReferenceObject = (object) => {
22540
22581
  };
22541
22582
 
22542
22583
  // src/reference-objects/fit-camera-to-bounds.ts
22543
- import * as THREE24 from "three";
22584
+ import * as THREE25 from "three";
22544
22585
  var fitCameraToBounds = (camera, controls, bounds, padding = 1.18) => {
22545
22586
  const width = Math.max(bounds.maxX - bounds.minX, 0);
22546
22587
  const height = Math.max(bounds.maxY - bounds.minY, 0);
22547
22588
  const depth = Math.max(bounds.maxZ - bounds.minZ, 0);
22548
- const center = new THREE24.Vector3(
22589
+ const center = new THREE25.Vector3(
22549
22590
  (bounds.minX + bounds.maxX) / 2,
22550
22591
  (bounds.minY + bounds.maxY) / 2,
22551
22592
  (bounds.minZ + bounds.maxZ) / 2
22552
22593
  );
22553
22594
  const radius = Math.max(Math.hypot(width, height, depth) / 2, 1);
22554
- const previousTarget = controls?.target ?? new THREE24.Vector3();
22555
- const direction = new THREE24.Vector3(0, -0.75, 0.9).normalize();
22595
+ const previousTarget = controls?.target ?? new THREE25.Vector3();
22596
+ const direction = new THREE25.Vector3(0, -0.75, 0.9).normalize();
22556
22597
  let distance5 = Math.max(camera.position.distanceTo(previousTarget), 5);
22557
- if (camera instanceof THREE24.PerspectiveCamera) {
22558
- const verticalFov = THREE24.MathUtils.degToRad(camera.fov);
22598
+ if (camera instanceof THREE25.PerspectiveCamera) {
22599
+ const verticalFov = THREE25.MathUtils.degToRad(camera.fov);
22559
22600
  const horizontalFov = 2 * Math.atan(Math.tan(verticalFov / 2) * camera.aspect);
22560
22601
  const limitingFov = Math.min(verticalFov, horizontalFov);
22561
22602
  distance5 = radius * padding / Math.sin(limitingFov / 2);
22562
22603
  camera.far = Math.max(camera.far, distance5 + radius * padding * 3);
22563
22604
  camera.updateProjectionMatrix();
22564
- } else if (camera instanceof THREE24.OrthographicCamera) {
22605
+ } else if (camera instanceof THREE25.OrthographicCamera) {
22565
22606
  const halfViewWidth = Math.abs(camera.right - camera.left) / 2;
22566
22607
  const halfViewHeight = Math.abs(camera.top - camera.bottom) / 2;
22567
22608
  camera.zoom = Math.min(
@@ -22681,7 +22722,7 @@ var CadViewerContainer = forwardRef2(
22681
22722
  Canvas,
22682
22723
  {
22683
22724
  ref,
22684
- scene: { up: new THREE25.Vector3(0, 0, 1) },
22725
+ scene: { up: new THREE26.Vector3(0, 0, 1) },
22685
22726
  camera: { up: [0, 0, 1], position: initialCameraPosition },
22686
22727
  onCreated: ({ camera }) => {
22687
22728
  mainCameraRef.current = camera;
@@ -22872,7 +22913,7 @@ var createBoardGeomWithOutline = (board, depth = 1.2, options = {}) => {
22872
22913
  };
22873
22914
 
22874
22915
  // src/utils/get-board-edge-color.ts
22875
- import * as THREE27 from "three";
22916
+ import * as THREE28 from "three";
22876
22917
 
22877
22918
  // src/geoms/constants.ts
22878
22919
  var M = 0.01;
@@ -22905,7 +22946,7 @@ var soldermaskColors = {
22905
22946
  };
22906
22947
 
22907
22948
  // src/utils/soldermask-color.ts
22908
- import * as THREE26 from "three";
22949
+ import * as THREE27 from "three";
22909
22950
  var SOLDERMASK_PRESET_HEX = {
22910
22951
  red: "#650202",
22911
22952
  blue: "#003f7d",
@@ -22936,9 +22977,9 @@ var resolveSoldermaskColor = (requestedColor) => {
22936
22977
  }
22937
22978
  const presetName = lowercaseColor;
22938
22979
  const presetColor = SOLDERMASK_PRESET_HEX[presetName];
22939
- if (presetColor) return new THREE26.Color(presetColor);
22940
- const isCssColor = Object.hasOwn(THREE26.Color.NAMES, lowercaseColor) || CSS_HEX_COLOR_PATTERN.test(normalizedColor) || CSS_RGB_INTEGER_PATTERN.test(normalizedColor) || CSS_RGB_PERCENT_PATTERN.test(normalizedColor) || CSS_HSL_PATTERN.test(normalizedColor);
22941
- return isCssColor ? new THREE26.Color(lowercaseColor) : null;
22980
+ if (presetColor) return new THREE27.Color(presetColor);
22981
+ const isCssColor = Object.hasOwn(THREE27.Color.NAMES, lowercaseColor) || CSS_HEX_COLOR_PATTERN.test(normalizedColor) || CSS_RGB_INTEGER_PATTERN.test(normalizedColor) || CSS_RGB_PERCENT_PATTERN.test(normalizedColor) || CSS_HSL_PATTERN.test(normalizedColor);
22982
+ return isCssColor ? new THREE27.Color(lowercaseColor) : null;
22942
22983
  };
22943
22984
  var resolveSoldermaskOpacity = (requestedColor) => {
22944
22985
  const presetName = requestedColor?.trim().toLowerCase();
@@ -22965,7 +23006,7 @@ var soldermaskColorToCss = (color) => {
22965
23006
  };
22966
23007
 
22967
23008
  // src/utils/get-board-edge-color.ts
22968
- var LEGACY_FR4_EDGE_COLOR = new THREE27.Color(1063462);
23009
+ var LEGACY_FR4_EDGE_COLOR = new THREE28.Color(1063462);
22969
23010
  var getBoardEdgeColor = ({
22970
23011
  material,
22971
23012
  solder_mask_color
@@ -22974,7 +23015,7 @@ var getBoardEdgeColor = ({
22974
23015
  if (soldermaskColor) return soldermaskColor;
22975
23016
  if (material === "fr4") return LEGACY_FR4_EDGE_COLOR.clone();
22976
23017
  const materialColor = boardMaterialColors[material] ?? colors.fr4Tan;
22977
- return new THREE27.Color(materialColor[0], materialColor[1], materialColor[2]);
23018
+ return new THREE28.Color(materialColor[0], materialColor[1], materialColor[2]);
22978
23019
  };
22979
23020
 
22980
23021
  // src/soup-to-3d/index.ts
@@ -24379,7 +24420,7 @@ var Text = ({
24379
24420
  };
24380
24421
 
24381
24422
  // src/three-components/Error3d.tsx
24382
- import * as THREE28 from "three";
24423
+ import * as THREE29 from "three";
24383
24424
  import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs3 } from "react/jsx-runtime";
24384
24425
  var Error3d = ({
24385
24426
  error,
@@ -24413,7 +24454,7 @@ var Error3d = ({
24413
24454
  return [0, 0, 0];
24414
24455
  }, [cad_component]);
24415
24456
  const group = useMemo19(() => {
24416
- const g = new THREE28.Group();
24457
+ const g = new THREE29.Group();
24417
24458
  g.position.fromArray(position);
24418
24459
  return g;
24419
24460
  }, [position]);
@@ -24475,9 +24516,9 @@ var Error3d = ({
24475
24516
  };
24476
24517
  var ErrorBox = ({ parent }) => {
24477
24518
  const mesh = useMemo19(() => {
24478
- const m = new THREE28.Mesh(
24479
- new THREE28.BoxGeometry(0.5, 0.5, 0.5),
24480
- new THREE28.MeshStandardMaterial({
24519
+ const m = new THREE29.Mesh(
24520
+ new THREE29.BoxGeometry(0.5, 0.5, 0.5),
24521
+ new THREE29.MeshStandardMaterial({
24481
24522
  depthTest: false,
24482
24523
  transparent: true,
24483
24524
  color: "red",
@@ -24502,7 +24543,7 @@ import { su as su9 } from "@tscircuit/circuit-json-util";
24502
24543
  import { useEffect as useEffect26, useMemo as useMemo21 } from "react";
24503
24544
 
24504
24545
  // src/textures/create-combined-board-textures.ts
24505
- import * as THREE41 from "three";
24546
+ import * as THREE42 from "three";
24506
24547
 
24507
24548
  // node_modules/@tscircuit/math-utils/dist/chunk-5N7UJNVK.js
24508
24549
  var getBoundsFromPoints = (points) => {
@@ -24557,7 +24598,7 @@ function calculateOutlineBounds(boardData) {
24557
24598
  // src/utils/pad-texture.ts
24558
24599
  import { su as su6 } from "@tscircuit/circuit-json-util";
24559
24600
  import { CircuitToCanvasDrawer } from "circuit-to-canvas";
24560
- import * as THREE29 from "three";
24601
+ import * as THREE30 from "three";
24561
24602
  function createPadTextureForLayer({
24562
24603
  layer,
24563
24604
  circuitJson,
@@ -24637,10 +24678,10 @@ function createPadTextureForLayer({
24637
24678
  drawSoldermaskTop: false,
24638
24679
  drawSoldermaskBottom: false
24639
24680
  });
24640
- const texture = new THREE29.CanvasTexture(canvas);
24681
+ const texture = new THREE30.CanvasTexture(canvas);
24641
24682
  texture.generateMipmaps = true;
24642
- texture.minFilter = THREE29.LinearMipmapLinearFilter;
24643
- texture.magFilter = THREE29.LinearFilter;
24683
+ texture.minFilter = THREE30.LinearMipmapLinearFilter;
24684
+ texture.magFilter = THREE30.LinearFilter;
24644
24685
  texture.anisotropy = 16;
24645
24686
  texture.needsUpdate = true;
24646
24687
  return texture;
@@ -24648,7 +24689,7 @@ function createPadTextureForLayer({
24648
24689
 
24649
24690
  // src/utils/panel-outline-texture.ts
24650
24691
  import { su as su7 } from "@tscircuit/circuit-json-util";
24651
- import * as THREE30 from "three";
24692
+ import * as THREE31 from "three";
24652
24693
  var resolvePanelIdForTexture = (circuitJson) => {
24653
24694
  const panels = circuitJson.filter(
24654
24695
  (e) => e.type === "pcb_panel"
@@ -24716,17 +24757,17 @@ function createPanelOutlineTextureForLayer({
24716
24757
  );
24717
24758
  }
24718
24759
  });
24719
- const texture = new THREE30.CanvasTexture(canvas);
24760
+ const texture = new THREE31.CanvasTexture(canvas);
24720
24761
  texture.generateMipmaps = true;
24721
- texture.minFilter = THREE30.LinearMipmapLinearFilter;
24722
- texture.magFilter = THREE30.LinearFilter;
24762
+ texture.minFilter = THREE31.LinearMipmapLinearFilter;
24763
+ texture.magFilter = THREE31.LinearFilter;
24723
24764
  texture.anisotropy = 16;
24724
24765
  texture.needsUpdate = true;
24725
24766
  return texture;
24726
24767
  }
24727
24768
 
24728
24769
  // src/utils/trace-texture.ts
24729
- import * as THREE31 from "three";
24770
+ import * as THREE32 from "three";
24730
24771
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer2 } from "circuit-to-canvas";
24731
24772
  import { getElementRenderLayers, su as su8 } from "@tscircuit/circuit-json-util";
24732
24773
  function createTraceTextureForLayer({
@@ -24812,10 +24853,10 @@ function createTraceTextureForLayer({
24812
24853
  drawSoldermaskTop: false,
24813
24854
  drawSoldermaskBottom: false
24814
24855
  });
24815
- const texture = new THREE31.CanvasTexture(canvas);
24856
+ const texture = new THREE32.CanvasTexture(canvas);
24816
24857
  texture.generateMipmaps = true;
24817
- texture.minFilter = THREE31.LinearMipmapLinearFilter;
24818
- texture.magFilter = THREE31.LinearFilter;
24858
+ texture.minFilter = THREE32.LinearMipmapLinearFilter;
24859
+ texture.magFilter = THREE32.LinearFilter;
24819
24860
  texture.anisotropy = 16;
24820
24861
  texture.needsUpdate = true;
24821
24862
  return texture;
@@ -24823,7 +24864,7 @@ function createTraceTextureForLayer({
24823
24864
 
24824
24865
  // src/textures/create-copper-pour-texture-for-layer.ts
24825
24866
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer3 } from "circuit-to-canvas";
24826
- import * as THREE32 from "three";
24867
+ import * as THREE33 from "three";
24827
24868
  var toRgb = (colorArr) => {
24828
24869
  const [r = 0, g = 0, b = 0] = colorArr;
24829
24870
  return `rgb(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(
@@ -24947,17 +24988,17 @@ function createCopperPourTextureForLayer({
24947
24988
  if (!onlyCoveredBySoldermask) {
24948
24989
  setColorAndDraw(uncoveredPours, uncoveredColor);
24949
24990
  }
24950
- const texture = new THREE32.CanvasTexture(canvas);
24991
+ const texture = new THREE33.CanvasTexture(canvas);
24951
24992
  texture.generateMipmaps = true;
24952
- texture.minFilter = THREE32.LinearMipmapLinearFilter;
24953
- texture.magFilter = THREE32.LinearFilter;
24993
+ texture.minFilter = THREE33.LinearMipmapLinearFilter;
24994
+ texture.magFilter = THREE33.LinearFilter;
24954
24995
  texture.anisotropy = 16;
24955
24996
  texture.needsUpdate = true;
24956
24997
  return texture;
24957
24998
  }
24958
24999
 
24959
25000
  // src/textures/create-copper-text-texture-for-layer.ts
24960
- import * as THREE33 from "three";
25001
+ import * as THREE34 from "three";
24961
25002
 
24962
25003
  // src/textures/copper-text/copper-text-drawing.ts
24963
25004
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer4 } from "circuit-to-canvas";
@@ -25072,17 +25113,17 @@ function createCopperTextTextureForLayer({
25072
25113
  elements,
25073
25114
  copperColor
25074
25115
  });
25075
- const texture = new THREE33.CanvasTexture(canvas);
25116
+ const texture = new THREE34.CanvasTexture(canvas);
25076
25117
  texture.generateMipmaps = true;
25077
- texture.minFilter = THREE33.LinearMipmapLinearFilter;
25078
- texture.magFilter = THREE33.LinearFilter;
25118
+ texture.minFilter = THREE34.LinearMipmapLinearFilter;
25119
+ texture.magFilter = THREE34.LinearFilter;
25079
25120
  texture.anisotropy = 16;
25080
25121
  texture.needsUpdate = true;
25081
25122
  return texture;
25082
25123
  }
25083
25124
 
25084
25125
  // src/textures/create-fabrication-note-texture-for-layer.ts
25085
- import * as THREE34 from "three";
25126
+ import * as THREE35 from "three";
25086
25127
 
25087
25128
  // src/textures/fabrication-note/fabrication-note-drawing.ts
25088
25129
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer5 } from "circuit-to-canvas";
@@ -25281,7 +25322,7 @@ var getSoldermaskRenderBounds = (circuitJson, boardData) => {
25281
25322
  var isFabricationNoteElement = (element, layer) => {
25282
25323
  if (!("layer" in element) || element.layer !== layer) return false;
25283
25324
  const elementType = element.type;
25284
- return elementType.startsWith("pcb_fabrication_note_") && elementType !== "pcb_fabrication_note_text";
25325
+ return elementType.startsWith("pcb_fabrication_note_") && elementType !== "pcb_fabrication_note_text" && elementType !== "pcb_fabrication_note_dimension";
25285
25326
  };
25286
25327
  function createFabricationNoteTextureForLayer({
25287
25328
  layer,
@@ -25312,17 +25353,17 @@ function createFabricationNoteTextureForLayer({
25312
25353
  bounds,
25313
25354
  elements
25314
25355
  });
25315
- const texture = new THREE34.CanvasTexture(canvas);
25356
+ const texture = new THREE35.CanvasTexture(canvas);
25316
25357
  texture.generateMipmaps = true;
25317
- texture.minFilter = THREE34.LinearMipmapLinearFilter;
25318
- texture.magFilter = THREE34.LinearFilter;
25358
+ texture.minFilter = THREE35.LinearMipmapLinearFilter;
25359
+ texture.magFilter = THREE35.LinearFilter;
25319
25360
  texture.anisotropy = 16;
25320
25361
  texture.needsUpdate = true;
25321
25362
  return texture;
25322
25363
  }
25323
25364
 
25324
25365
  // src/textures/create-keepout-texture-for-layer.ts
25325
- import * as THREE35 from "three";
25366
+ import * as THREE36 from "three";
25326
25367
 
25327
25368
  // src/textures/keepout/keepout-drawing.ts
25328
25369
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer6 } from "circuit-to-canvas";
@@ -25397,17 +25438,17 @@ function createKeepoutTextureForLayer({
25397
25438
  elements,
25398
25439
  keepoutColor
25399
25440
  });
25400
- const texture = new THREE35.CanvasTexture(canvas);
25441
+ const texture = new THREE36.CanvasTexture(canvas);
25401
25442
  texture.generateMipmaps = true;
25402
- texture.minFilter = THREE35.LinearMipmapLinearFilter;
25403
- texture.magFilter = THREE35.LinearFilter;
25443
+ texture.minFilter = THREE36.LinearMipmapLinearFilter;
25444
+ texture.magFilter = THREE36.LinearFilter;
25404
25445
  texture.anisotropy = 16;
25405
25446
  texture.needsUpdate = true;
25406
25447
  return texture;
25407
25448
  }
25408
25449
 
25409
25450
  // src/textures/create-pcb-note-texture-for-layer.ts
25410
- import * as THREE36 from "three";
25451
+ import * as THREE37 from "three";
25411
25452
 
25412
25453
  // src/textures/pcb-note/pcb-note-drawing.ts
25413
25454
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer7 } from "circuit-to-canvas";
@@ -25561,17 +25602,17 @@ function createPcbNoteTextureForLayer({
25561
25602
  bounds,
25562
25603
  elements
25563
25604
  });
25564
- const texture = new THREE36.CanvasTexture(canvas);
25605
+ const texture = new THREE37.CanvasTexture(canvas);
25565
25606
  texture.generateMipmaps = true;
25566
- texture.minFilter = THREE36.LinearMipmapLinearFilter;
25567
- texture.magFilter = THREE36.LinearFilter;
25607
+ texture.minFilter = THREE37.LinearMipmapLinearFilter;
25608
+ texture.magFilter = THREE37.LinearFilter;
25568
25609
  texture.anisotropy = 16;
25569
25610
  texture.needsUpdate = true;
25570
25611
  return texture;
25571
25612
  }
25572
25613
 
25573
25614
  // src/textures/create-silkscreen-texture-for-layer.ts
25574
- import * as THREE37 from "three";
25615
+ import * as THREE38 from "three";
25575
25616
 
25576
25617
  // src/textures/silkscreen/silkscreen-drawing.ts
25577
25618
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer8 } from "circuit-to-canvas";
@@ -25722,21 +25763,21 @@ function createSilkscreenTextureForLayer({
25722
25763
  silkscreenColor,
25723
25764
  soldermaskVisible
25724
25765
  });
25725
- const texture = new THREE37.CanvasTexture(canvas);
25766
+ const texture = new THREE38.CanvasTexture(canvas);
25726
25767
  texture.generateMipmaps = true;
25727
- texture.minFilter = THREE37.LinearMipmapLinearFilter;
25728
- texture.magFilter = THREE37.LinearFilter;
25768
+ texture.minFilter = THREE38.LinearMipmapLinearFilter;
25769
+ texture.magFilter = THREE38.LinearFilter;
25729
25770
  texture.anisotropy = 16;
25730
25771
  texture.needsUpdate = true;
25731
25772
  return texture;
25732
25773
  }
25733
25774
 
25734
25775
  // src/textures/create-soldermask-texture-for-layer.ts
25735
- import * as THREE39 from "three";
25776
+ import * as THREE40 from "three";
25736
25777
 
25737
25778
  // src/textures/soldermask/soldermask-drawing.ts
25738
25779
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer9 } from "circuit-to-canvas";
25739
- import * as THREE38 from "three";
25780
+ import * as THREE39 from "three";
25740
25781
  var toRgb2 = (colorArr) => {
25741
25782
  const [r = 0, g = 0, b = 0] = colorArr;
25742
25783
  return `rgb(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(
@@ -25759,11 +25800,11 @@ var getSoldermaskPalette = (boardData) => {
25759
25800
  transparent: "rgba(0,0,0,0)"
25760
25801
  };
25761
25802
  }
25762
- const copperColor = new THREE38.Color().setRGB(
25803
+ const copperColor = new THREE39.Color().setRGB(
25763
25804
  colors.copper[0],
25764
25805
  colors.copper[1],
25765
25806
  colors.copper[2],
25766
- THREE38.SRGBColorSpace
25807
+ THREE39.SRGBColorSpace
25767
25808
  );
25768
25809
  return {
25769
25810
  soldermask: soldermaskColorToCss(requestedSoldermaskColor),
@@ -25788,6 +25829,7 @@ var setDrawerBounds6 = (drawer, bounds) => {
25788
25829
  maxY: bounds.maxY
25789
25830
  });
25790
25831
  };
25832
+ var isPcbAnnotation = (element) => element.type.startsWith("pcb_note_") || element.type.startsWith("pcb_fabrication_note_");
25791
25833
  var drawSoldermaskLayer = ({
25792
25834
  ctx,
25793
25835
  layer,
@@ -25831,16 +25873,16 @@ var drawSoldermaskLayer = ({
25831
25873
  }
25832
25874
  });
25833
25875
  setDrawerBounds6(drawer, bounds);
25834
- const elementsWithoutKeepouts = elements.filter(
25835
- (element) => element.type !== "pcb_keepout"
25876
+ const elementsWithoutAnnotationsOrKeepouts = elements.filter(
25877
+ (element) => element.type !== "pcb_keepout" && !isPcbAnnotation(element)
25836
25878
  );
25837
- drawer.drawElements(elementsWithoutKeepouts, {
25879
+ drawer.drawElements(elementsWithoutAnnotationsOrKeepouts, {
25838
25880
  layers: [copperRenderLayer],
25839
25881
  drawSoldermask: true,
25840
25882
  drawSoldermaskTop: layer === "top",
25841
25883
  drawSoldermaskBottom: layer === "bottom"
25842
25884
  });
25843
- const uncoveredPours = elementsWithoutKeepouts.filter(
25885
+ const uncoveredPours = elementsWithoutAnnotationsOrKeepouts.filter(
25844
25886
  (e) => e.type === "pcb_copper_pour" && e.layer === layer && e.covered_with_solder_mask === false
25845
25887
  );
25846
25888
  if (uncoveredPours.length > 0) {
@@ -25897,17 +25939,17 @@ function createSoldermaskTextureForLayer({
25897
25939
  elements,
25898
25940
  boardData
25899
25941
  });
25900
- const texture = new THREE39.CanvasTexture(canvas);
25942
+ const texture = new THREE40.CanvasTexture(canvas);
25901
25943
  texture.generateMipmaps = true;
25902
- texture.minFilter = THREE39.LinearMipmapLinearFilter;
25903
- texture.magFilter = THREE39.LinearFilter;
25944
+ texture.minFilter = THREE40.LinearMipmapLinearFilter;
25945
+ texture.magFilter = THREE40.LinearFilter;
25904
25946
  texture.anisotropy = 16;
25905
25947
  texture.needsUpdate = true;
25906
25948
  return texture;
25907
25949
  }
25908
25950
 
25909
25951
  // src/textures/create-through-hole-texture-for-layer.ts
25910
- import * as THREE40 from "three";
25952
+ import * as THREE41 from "three";
25911
25953
 
25912
25954
  // src/textures/through-hole/through-hole-drawing.ts
25913
25955
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer10 } from "circuit-to-canvas";
@@ -26002,10 +26044,10 @@ function createThroughHoleTextureForLayer({
26002
26044
  elements,
26003
26045
  copperColor
26004
26046
  });
26005
- const texture = new THREE40.CanvasTexture(canvas);
26047
+ const texture = new THREE41.CanvasTexture(canvas);
26006
26048
  texture.generateMipmaps = true;
26007
- texture.minFilter = THREE40.LinearMipmapLinearFilter;
26008
- texture.magFilter = THREE40.LinearFilter;
26049
+ texture.minFilter = THREE41.LinearMipmapLinearFilter;
26050
+ texture.magFilter = THREE41.LinearFilter;
26009
26051
  texture.anisotropy = 16;
26010
26052
  texture.needsUpdate = true;
26011
26053
  return texture;
@@ -26093,10 +26135,10 @@ var createCombinedTexture = ({
26093
26135
  applySoldermaskSurfaceFilter(ctx, canvasWidth, canvasHeight, {
26094
26136
  includeReflection: layer === "top"
26095
26137
  });
26096
- const combinedTexture = new THREE41.CanvasTexture(canvas);
26138
+ const combinedTexture = new THREE42.CanvasTexture(canvas);
26097
26139
  combinedTexture.generateMipmaps = false;
26098
- combinedTexture.minFilter = THREE41.LinearFilter;
26099
- combinedTexture.magFilter = THREE41.LinearFilter;
26140
+ combinedTexture.minFilter = THREE42.LinearFilter;
26141
+ combinedTexture.magFilter = THREE42.LinearFilter;
26100
26142
  combinedTexture.premultiplyAlpha = true;
26101
26143
  combinedTexture.anisotropy = 16;
26102
26144
  combinedTexture.needsUpdate = true;
@@ -26132,11 +26174,11 @@ var createMaskedCopperMask = ({
26132
26174
  height
26133
26175
  );
26134
26176
  ctx.globalCompositeOperation = "source-over";
26135
- const maskTexture = new THREE41.CanvasTexture(canvas);
26136
- maskTexture.colorSpace = THREE41.NoColorSpace;
26177
+ const maskTexture = new THREE42.CanvasTexture(canvas);
26178
+ maskTexture.colorSpace = THREE42.NoColorSpace;
26137
26179
  maskTexture.generateMipmaps = false;
26138
- maskTexture.minFilter = THREE41.LinearFilter;
26139
- maskTexture.magFilter = THREE41.LinearFilter;
26180
+ maskTexture.minFilter = THREE42.LinearFilter;
26181
+ maskTexture.magFilter = THREE42.LinearFilter;
26140
26182
  maskTexture.premultiplyAlpha = false;
26141
26183
  maskTexture.needsUpdate = true;
26142
26184
  return maskTexture;
@@ -26276,7 +26318,7 @@ function createCombinedBoardTextures({
26276
26318
  }
26277
26319
 
26278
26320
  // src/textures/create-three-texture-meshes.ts
26279
- import * as THREE43 from "three";
26321
+ import * as THREE44 from "three";
26280
26322
 
26281
26323
  // src/board-surface-textures.ts
26282
26324
  var REALISTIC_BOARD_SURFACE_MATERIAL = {
@@ -26299,7 +26341,7 @@ var PAD_COPPER_TEXTURE_MATERIAL = {
26299
26341
  };
26300
26342
 
26301
26343
  // src/utils/create-board-relief-textures.ts
26302
- import * as THREE42 from "three";
26344
+ import * as THREE43 from "three";
26303
26345
  var PLAIN_SOLDERMASK_HEIGHT = 0.22;
26304
26346
  var MASKED_COPPER_HEIGHT = 0.7;
26305
26347
  var EXPOSED_COPPER_HEIGHT = 0.86;
@@ -26394,13 +26436,13 @@ var getBoardSurfaceProfile = (r, g, b, hasMaskedCopper) => {
26394
26436
  return PLAIN_SOLDERMASK_PROFILE;
26395
26437
  };
26396
26438
  var createDataTexture = (canvas) => {
26397
- const texture = new THREE42.CanvasTexture(canvas);
26398
- texture.colorSpace = THREE42.NoColorSpace;
26439
+ const texture = new THREE43.CanvasTexture(canvas);
26440
+ texture.colorSpace = THREE43.NoColorSpace;
26399
26441
  texture.generateMipmaps = false;
26400
- texture.minFilter = THREE42.LinearFilter;
26401
- texture.magFilter = THREE42.LinearFilter;
26402
- texture.wrapS = THREE42.ClampToEdgeWrapping;
26403
- texture.wrapT = THREE42.ClampToEdgeWrapping;
26442
+ texture.minFilter = THREE43.LinearFilter;
26443
+ texture.magFilter = THREE43.LinearFilter;
26444
+ texture.wrapS = THREE43.ClampToEdgeWrapping;
26445
+ texture.wrapT = THREE43.ClampToEdgeWrapping;
26404
26446
  texture.needsUpdate = true;
26405
26447
  return texture;
26406
26448
  };
@@ -26524,16 +26566,16 @@ function createTexturePlane(config, boardData) {
26524
26566
  } = config;
26525
26567
  if (!texture) return null;
26526
26568
  const boardOutlineBounds = calculateOutlineBounds(boardData);
26527
- const planeGeom = new THREE43.PlaneGeometry(
26569
+ const planeGeom = new THREE44.PlaneGeometry(
26528
26570
  boardOutlineBounds.width,
26529
26571
  boardOutlineBounds.height
26530
26572
  );
26531
- texture.colorSpace = THREE43.SRGBColorSpace;
26573
+ texture.colorSpace = THREE44.SRGBColorSpace;
26532
26574
  const sharedMaterialOptions = {
26533
26575
  map: texture,
26534
26576
  transparent: true,
26535
26577
  alphaTest: 0.08,
26536
- side: THREE43.FrontSide,
26578
+ side: THREE44.FrontSide,
26537
26579
  depthWrite: true,
26538
26580
  polygonOffset: usePolygonOffset,
26539
26581
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
@@ -26542,12 +26584,12 @@ function createTexturePlane(config, boardData) {
26542
26584
  opacity: isFaux ? FAUX_BOARD_OPACITY : 1
26543
26585
  };
26544
26586
  const reliefTextures = createBoardReliefTextures(texture, maskedCopperMask);
26545
- const material = new THREE43.MeshPhysicalMaterial({
26587
+ const material = new THREE44.MeshPhysicalMaterial({
26546
26588
  ...sharedMaterialOptions,
26547
26589
  bumpMap: reliefTextures?.bumpMap ?? null,
26548
26590
  bumpScale: REALISTIC_BOARD_SURFACE_MATERIAL.bumpScale,
26549
26591
  normalMap: reliefTextures?.normalMap ?? null,
26550
- normalScale: new THREE43.Vector2(
26592
+ normalScale: new THREE44.Vector2(
26551
26593
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale,
26552
26594
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale
26553
26595
  ),
@@ -26561,7 +26603,7 @@ function createTexturePlane(config, boardData) {
26561
26603
  clearcoatRoughness: REALISTIC_BOARD_SURFACE_MATERIAL.clearcoatRoughness,
26562
26604
  envMapIntensity: 0.18
26563
26605
  });
26564
- const mesh = new THREE43.Mesh(planeGeom, material);
26606
+ const mesh = new THREE44.Mesh(planeGeom, material);
26565
26607
  mesh.position.set(
26566
26608
  boardOutlineBounds.centerX,
26567
26609
  boardOutlineBounds.centerY,
@@ -26609,7 +26651,7 @@ function createTextureMeshes(textures, boardData, pcbThickness, isFaux = false)
26609
26651
  }
26610
26652
 
26611
26653
  // src/three-components/JscadBoardTextures.tsx
26612
- import * as THREE44 from "three";
26654
+ import * as THREE45 from "three";
26613
26655
 
26614
26656
  // src/hooks/useBoardTextureVisibility.ts
26615
26657
  import { useMemo as useMemo20 } from "react";
@@ -26747,7 +26789,7 @@ function JscadBoardTextures({
26747
26789
  const typedMaterial = material;
26748
26790
  for (const prop of textureProps) {
26749
26791
  const texture = typedMaterial[prop];
26750
- if (texture && texture instanceof THREE44.Texture) {
26792
+ if (texture && texture instanceof THREE45.Texture) {
26751
26793
  texture.dispose();
26752
26794
  typedMaterial[prop] = null;
26753
26795
  }
@@ -26766,16 +26808,16 @@ function JscadBoardTextures({
26766
26808
  }) => {
26767
26809
  if (!texture) return null;
26768
26810
  const boardOutlineBounds = calculateOutlineBounds(boardData);
26769
- const planeGeom = new THREE44.PlaneGeometry(
26811
+ const planeGeom = new THREE45.PlaneGeometry(
26770
26812
  boardOutlineBounds.width,
26771
26813
  boardOutlineBounds.height
26772
26814
  );
26773
- texture.colorSpace = THREE44.SRGBColorSpace;
26815
+ texture.colorSpace = THREE45.SRGBColorSpace;
26774
26816
  const sharedMaterialOptions = {
26775
26817
  map: texture,
26776
26818
  transparent: true,
26777
26819
  alphaTest: 0.08,
26778
- side: THREE44.FrontSide,
26820
+ side: THREE45.FrontSide,
26779
26821
  depthWrite,
26780
26822
  polygonOffset: usePolygonOffset,
26781
26823
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
@@ -26786,12 +26828,12 @@ function JscadBoardTextures({
26786
26828
  texture,
26787
26829
  maskedCopperMask
26788
26830
  );
26789
- const material = new THREE44.MeshPhysicalMaterial({
26831
+ const material = new THREE45.MeshPhysicalMaterial({
26790
26832
  ...sharedMaterialOptions,
26791
26833
  bumpMap: reliefTextures?.bumpMap ?? null,
26792
26834
  bumpScale: REALISTIC_BOARD_SURFACE_MATERIAL.bumpScale,
26793
26835
  normalMap: reliefTextures?.normalMap ?? null,
26794
- normalScale: new THREE44.Vector2(
26836
+ normalScale: new THREE45.Vector2(
26795
26837
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale,
26796
26838
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale
26797
26839
  ),
@@ -26803,7 +26845,7 @@ function JscadBoardTextures({
26803
26845
  clearcoatRoughness: REALISTIC_BOARD_SURFACE_MATERIAL.clearcoatRoughness,
26804
26846
  envMapIntensity: 0.18
26805
26847
  });
26806
- const mesh = new THREE44.Mesh(planeGeom, material);
26848
+ const mesh = new THREE45.Mesh(planeGeom, material);
26807
26849
  mesh.position.set(
26808
26850
  boardOutlineBounds.centerX,
26809
26851
  boardOutlineBounds.centerY,
@@ -26853,7 +26895,7 @@ function JscadBoardTextures({
26853
26895
  for (const material of mesh.material) {
26854
26896
  disposeTextureMaterial(material);
26855
26897
  }
26856
- } else if (mesh.material instanceof THREE44.Material) {
26898
+ } else if (mesh.material instanceof THREE45.Material) {
26857
26899
  disposeTextureMaterial(mesh.material);
26858
26900
  }
26859
26901
  }
@@ -26866,7 +26908,7 @@ function JscadBoardTextures({
26866
26908
 
26867
26909
  // src/three-components/STLModel.tsx
26868
26910
  import { useState as useState17, useEffect as useEffect27, useMemo as useMemo22 } from "react";
26869
- import * as THREE45 from "three";
26911
+ import * as THREE46 from "three";
26870
26912
  import { STLLoader } from "three-stdlib";
26871
26913
  function STLModel({
26872
26914
  stlUrl,
@@ -26899,15 +26941,15 @@ function STLModel({
26899
26941
  const mesh = useMemo22(() => {
26900
26942
  if (!geom) return null;
26901
26943
  const isBoardLayer = layerType === "board";
26902
- const material = new THREE45.MeshStandardMaterial({
26903
- color: Array.isArray(color) ? new THREE45.Color(color[0], color[1], color[2]) : color,
26944
+ const material = new THREE46.MeshStandardMaterial({
26945
+ color: Array.isArray(color) ? new THREE46.Color(color[0], color[1], color[2]) : color,
26904
26946
  transparent: opacity !== 1,
26905
26947
  opacity,
26906
26948
  polygonOffset: isBoardLayer,
26907
26949
  polygonOffsetFactor: isBoardLayer ? 6 : 0,
26908
26950
  polygonOffsetUnits: isBoardLayer ? 6 : 0
26909
26951
  });
26910
- const createdMesh = new THREE45.Mesh(geom, material);
26952
+ const createdMesh = new THREE46.Mesh(geom, material);
26911
26953
  createdMesh.renderOrder = isBoardLayer ? -1 : 1;
26912
26954
  configureObjectShadows(createdMesh, {
26913
26955
  castShadow: !isBoardLayer && opacity === 1,
@@ -26970,7 +27012,7 @@ function VisibleSTLModel({
26970
27012
  import { parseCableString } from "@tscircuit/cableprinter";
26971
27013
  import { createCableMeshes } from "jscad-electronics/cables";
26972
27014
  import { useEffect as useEffect28, useMemo as useMemo23 } from "react";
26973
- import * as THREE46 from "three";
27015
+ import * as THREE47 from "three";
26974
27016
  var isCadCableElement = (element) => {
26975
27017
  if (!element || typeof element !== "object") return false;
26976
27018
  const candidate = element;
@@ -26987,14 +27029,14 @@ var getConnectorPin1Side = ({
26987
27029
  const endpoint = end === "start" ? path[0] : path[path.length - 1];
26988
27030
  const adjacent = end === "start" ? path[1] : path[path.length - 2];
26989
27031
  if (!endpoint || !adjacent) return void 0;
26990
- const cableAxis = new THREE46.Vector3(
27032
+ const cableAxis = new THREE47.Vector3(
26991
27033
  adjacent.x - endpoint.x,
26992
27034
  adjacent.y - endpoint.y,
26993
27035
  adjacent.z - endpoint.z
26994
27036
  );
26995
27037
  if (cableAxis.lengthSq() < 1e-12) return void 0;
26996
27038
  cableAxis.normalize();
26997
- const pin1Side = new THREE46.Vector3(
27039
+ const pin1Side = new THREE47.Vector3(
26998
27040
  pin1Position.x - endpoint.x,
26999
27041
  pin1Position.y - endpoint.y,
27000
27042
  pin1Position.z - endpoint.z
@@ -27020,28 +27062,28 @@ var createCadCableObject = (cable) => {
27020
27062
  end: "end"
27021
27063
  })
27022
27064
  });
27023
- const group = new THREE46.Group();
27065
+ const group = new THREE47.Group();
27024
27066
  group.name = `cad-cable-${cable.cad_cable_id}`;
27025
27067
  group.userData = { cadCableId: cable.cad_cable_id, name: cable.name };
27026
27068
  for (const cableMesh of cableMeshes) {
27027
- let geometry = new THREE46.BufferGeometry();
27069
+ let geometry = new THREE47.BufferGeometry();
27028
27070
  geometry.setAttribute(
27029
27071
  "position",
27030
- new THREE46.Float32BufferAttribute(cableMesh.positions, 3)
27072
+ new THREE47.Float32BufferAttribute(cableMesh.positions, 3)
27031
27073
  );
27032
27074
  geometry.setIndex(cableMesh.indices);
27033
27075
  if (!cableMesh.smooth) geometry = geometry.toNonIndexed();
27034
27076
  geometry.computeVertexNormals();
27035
27077
  const [red, green, blue, alpha] = cableMesh.color;
27036
- const material = new THREE46.MeshStandardMaterial({
27037
- color: new THREE46.Color(red, green, blue),
27078
+ const material = new THREE47.MeshStandardMaterial({
27079
+ color: new THREE47.Color(red, green, blue),
27038
27080
  metalness: cableMesh.material?.metalness ?? 0,
27039
27081
  roughness: cableMesh.material?.roughness ?? 0.7,
27040
27082
  opacity: alpha,
27041
27083
  transparent: alpha < 1,
27042
- side: THREE46.DoubleSide
27084
+ side: THREE47.DoubleSide
27043
27085
  });
27044
- const mesh = new THREE46.Mesh(geometry, material);
27086
+ const mesh = new THREE47.Mesh(geometry, material);
27045
27087
  mesh.name = `${group.name}:${cableMesh.name}`;
27046
27088
  configureObjectShadows(mesh, { castShadow: true, receiveShadow: true });
27047
27089
  group.add(mesh);
@@ -27050,7 +27092,7 @@ var createCadCableObject = (cable) => {
27050
27092
  };
27051
27093
  var disposeCadCableObject = (group) => {
27052
27094
  group.traverse((object) => {
27053
- if (!(object instanceof THREE46.Mesh)) return;
27095
+ if (!(object instanceof THREE47.Mesh)) return;
27054
27096
  object.geometry.dispose();
27055
27097
  const materials = Array.isArray(object.material) ? object.material : [object.material];
27056
27098
  for (const material of materials) material.dispose();
@@ -28290,7 +28332,7 @@ function createStiffenerMesh({
28290
28332
  }
28291
28333
 
28292
28334
  // src/utils/flex-meshes.ts
28293
- import * as THREE47 from "three";
28335
+ import * as THREE48 from "three";
28294
28336
  function meshToSurface(mesh, center) {
28295
28337
  mesh.updateMatrix();
28296
28338
  const geometry = mesh.geometry.index ? mesh.geometry.toNonIndexed() : mesh.geometry;
@@ -28298,11 +28340,11 @@ function meshToSurface(mesh, center) {
28298
28340
  const triangles = [];
28299
28341
  for (let i = 0; i < position.count; i += 3) {
28300
28342
  const vertices = [0, 1, 2].map((j) => {
28301
- const v = new THREE47.Vector3().fromBufferAttribute(position, i + j).applyMatrix4(mesh.matrix);
28343
+ const v = new THREE48.Vector3().fromBufferAttribute(position, i + j).applyMatrix4(mesh.matrix);
28302
28344
  return { x: v.x - center.x, y: v.y - center.y, z: v.z };
28303
28345
  });
28304
28346
  const [a, b, c] = vertices;
28305
- const n = new THREE47.Vector3(b.x - a.x, b.y - a.y, b.z - a.z).cross(new THREE47.Vector3(c.x - a.x, c.y - a.y, c.z - a.z)).normalize();
28347
+ const n = new THREE48.Vector3(b.x - a.x, b.y - a.y, b.z - a.z).cross(new THREE48.Vector3(c.x - a.x, c.y - a.y, c.z - a.z)).normalize();
28306
28348
  triangles.push({
28307
28349
  vertices,
28308
28350
  normal: { x: n.x, y: n.y, z: n.z },
@@ -28325,13 +28367,13 @@ function surfaceToGeometry(surface, center) {
28325
28367
  normals.push(triangle.normal.x, triangle.normal.y, triangle.normal.z);
28326
28368
  uvs.push(triangle.uvs?.[i]?.u ?? 0, triangle.uvs?.[i]?.v ?? 0);
28327
28369
  });
28328
- const geometry = new THREE47.BufferGeometry();
28370
+ const geometry = new THREE48.BufferGeometry();
28329
28371
  geometry.setAttribute(
28330
28372
  "position",
28331
- new THREE47.Float32BufferAttribute(positions, 3)
28373
+ new THREE48.Float32BufferAttribute(positions, 3)
28332
28374
  );
28333
- geometry.setAttribute("normal", new THREE47.Float32BufferAttribute(normals, 3));
28334
- geometry.setAttribute("uv", new THREE47.Float32BufferAttribute(uvs, 2));
28375
+ geometry.setAttribute("normal", new THREE48.Float32BufferAttribute(normals, 3));
28376
+ geometry.setAttribute("uv", new THREE48.Float32BufferAttribute(uvs, 2));
28335
28377
  geometry.computeBoundingBox();
28336
28378
  geometry.computeBoundingSphere();
28337
28379
  return geometry;
@@ -28376,7 +28418,7 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
28376
28418
  z: mesh.position.z
28377
28419
  }));
28378
28420
  const uvs = vertices.map((p) => {
28379
- const local = new THREE47.Vector3(
28421
+ const local = new THREE48.Vector3(
28380
28422
  p.x + board.center.x,
28381
28423
  p.y + board.center.y,
28382
28424
  p.z
@@ -28400,7 +28442,7 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
28400
28442
  return result;
28401
28443
  }) : textureMeshes;
28402
28444
  for (const stiffener of stiffeners) {
28403
- const mesh = new THREE47.Mesh(
28445
+ const mesh = new THREE48.Mesh(
28404
28446
  surfaceToGeometry(
28405
28447
  createStiffenerMesh({
28406
28448
  stiffener,
@@ -28409,16 +28451,16 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
28409
28451
  }),
28410
28452
  board.center
28411
28453
  ),
28412
- new THREE47.MeshStandardMaterial({
28454
+ new THREE48.MeshStandardMaterial({
28413
28455
  color: stiffener.material === "fr4" ? "#879568" : stiffener.material === "polyimide" ? "#bd7f27" : "#b8bdc4",
28414
- side: THREE47.DoubleSide
28456
+ side: THREE48.DoubleSide
28415
28457
  })
28416
28458
  );
28417
28459
  mesh.name = "board-stiffener";
28418
28460
  configureObjectShadows(mesh);
28419
28461
  geometry.push(mesh);
28420
28462
  }
28421
- const bounds = new THREE47.Box3();
28463
+ const bounds = new THREE48.Box3();
28422
28464
  for (const mesh of [...geometry, ...textures]) bounds.expandByObject(mesh);
28423
28465
  return {
28424
28466
  geometryMeshes: geometry,
@@ -28437,12 +28479,12 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
28437
28479
  // src/CadViewerManifold.tsx
28438
28480
  import { su as su17 } from "@tscircuit/circuit-json-util";
28439
28481
  import { useEffect as useEffect30, useMemo as useMemo26, useState as useState19 } from "react";
28440
- import * as THREE54 from "three";
28482
+ import * as THREE55 from "three";
28441
28483
 
28442
28484
  // src/hooks/useManifoldBoardBuilder.ts
28443
28485
  import { su as su16 } from "@tscircuit/circuit-json-util";
28444
28486
  import { useEffect as useEffect29, useMemo as useMemo25, useRef as useRef9, useState as useState18 } from "react";
28445
- import * as THREE51 from "three";
28487
+ import * as THREE52 from "three";
28446
28488
 
28447
28489
  // src/utils/manifold/create-manifold-board.ts
28448
28490
  var arePointsClockwise2 = (points) => {
@@ -28791,17 +28833,17 @@ function processNonPlatedHolesForManifold(Manifold, CrossSection, circuitJson, p
28791
28833
 
28792
28834
  // src/utils/manifold/process-plated-holes.ts
28793
28835
  import { su as su15 } from "@tscircuit/circuit-json-util";
28794
- import * as THREE49 from "three";
28836
+ import * as THREE50 from "three";
28795
28837
 
28796
28838
  // src/utils/manifold-mesh-to-three-geometry.ts
28797
- import * as THREE48 from "three";
28839
+ import * as THREE49 from "three";
28798
28840
  function manifoldMeshToThreeGeometry(manifoldMesh) {
28799
- const geometry = new THREE48.BufferGeometry();
28841
+ const geometry = new THREE49.BufferGeometry();
28800
28842
  geometry.setAttribute(
28801
28843
  "position",
28802
- new THREE48.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
28844
+ new THREE49.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
28803
28845
  );
28804
- geometry.setIndex(new THREE48.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
28846
+ geometry.setIndex(new THREE49.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
28805
28847
  if (manifoldMesh.runIndex && manifoldMesh.runIndex.length > 1 && manifoldMesh.runOriginalID) {
28806
28848
  for (let i = 0; i < manifoldMesh.runIndex.length - 1; i++) {
28807
28849
  const start = manifoldMesh.runIndex[i];
@@ -28835,7 +28877,7 @@ var createEllipsePoints = (width, height, segments) => {
28835
28877
  }
28836
28878
  return points;
28837
28879
  };
28838
- var COPPER_COLOR = new THREE49.Color(...colors.copper);
28880
+ var COPPER_COLOR = new THREE50.Color(...colors.copper);
28839
28881
  var PLATED_HOLE_LIP_HEIGHT = 0.05;
28840
28882
  var PLATED_HOLE_PAD_THICKNESS = 3e-3;
28841
28883
  var PLATED_HOLE_SURFACE_CLEARANCE = 5e-4;
@@ -29465,7 +29507,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
29465
29507
  }
29466
29508
 
29467
29509
  // src/utils/manifold/process-vias.ts
29468
- import * as THREE50 from "three";
29510
+ import * as THREE51 from "three";
29469
29511
 
29470
29512
  // src/utils/via-geoms.ts
29471
29513
  function createViaCopper2({
@@ -29503,7 +29545,7 @@ function createViaCopper2({
29503
29545
  }
29504
29546
 
29505
29547
  // src/utils/manifold/process-vias.ts
29506
- var COPPER_COLOR2 = new THREE50.Color(...colors.copper);
29548
+ var COPPER_COLOR2 = new THREE51.Color(...colors.copper);
29507
29549
  function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume) {
29508
29550
  const viaBoardDrills = [];
29509
29551
  const pcbVias = getPcbVias(circuitJson);
@@ -29725,7 +29767,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
29725
29767
  {
29726
29768
  key: "plated-holes-union",
29727
29769
  geometry: cutPlatedGeom,
29728
- color: new THREE51.Color(
29770
+ color: new THREE52.Color(
29729
29771
  colors.copper[0],
29730
29772
  colors.copper[1],
29731
29773
  colors.copper[2]
@@ -29795,11 +29837,11 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
29795
29837
  };
29796
29838
 
29797
29839
  // src/utils/manifold/create-three-geometry-meshes.ts
29798
- import * as THREE53 from "three";
29840
+ import * as THREE54 from "three";
29799
29841
 
29800
29842
  // src/utils/create-board-material.ts
29801
- import * as THREE52 from "three";
29802
- var DEFAULT_SIDE = THREE52.DoubleSide;
29843
+ import * as THREE53 from "three";
29844
+ var DEFAULT_SIDE = THREE53.DoubleSide;
29803
29845
  var createBoardMaterial = ({
29804
29846
  material,
29805
29847
  color,
@@ -29807,7 +29849,7 @@ var createBoardMaterial = ({
29807
29849
  isFaux = false
29808
29850
  }) => {
29809
29851
  if (material === "fr4") {
29810
- return new THREE52.MeshPhysicalMaterial({
29852
+ return new THREE53.MeshPhysicalMaterial({
29811
29853
  color,
29812
29854
  side,
29813
29855
  metalness: 0,
@@ -29825,7 +29867,7 @@ var createBoardMaterial = ({
29825
29867
  polygonOffsetUnits: 1
29826
29868
  });
29827
29869
  }
29828
- return new THREE52.MeshStandardMaterial({
29870
+ return new THREE53.MeshStandardMaterial({
29829
29871
  color,
29830
29872
  side,
29831
29873
  flatShading: true,
@@ -29844,12 +29886,12 @@ function createGeometryMeshes(geoms) {
29844
29886
  const meshes = [];
29845
29887
  if (!geoms) return meshes;
29846
29888
  if (geoms.board?.geometry) {
29847
- const mesh = new THREE53.Mesh(
29889
+ const mesh = new THREE54.Mesh(
29848
29890
  geoms.board.geometry,
29849
29891
  createBoardMaterial({
29850
29892
  material: geoms.board.material,
29851
29893
  color: geoms.board.color,
29852
- side: THREE53.DoubleSide,
29894
+ side: THREE54.DoubleSide,
29853
29895
  isFaux: geoms.board.isFaux
29854
29896
  })
29855
29897
  );
@@ -29860,11 +29902,11 @@ function createGeometryMeshes(geoms) {
29860
29902
  const createMeshesFromArray = (geomArray) => {
29861
29903
  if (geomArray) {
29862
29904
  for (const comp of geomArray) {
29863
- const mesh = new THREE53.Mesh(
29905
+ const mesh = new THREE54.Mesh(
29864
29906
  comp.geometry,
29865
- new THREE53.MeshStandardMaterial({
29907
+ new THREE54.MeshStandardMaterial({
29866
29908
  color: comp.color,
29867
- side: THREE53.DoubleSide,
29909
+ side: THREE54.DoubleSide,
29868
29910
  flatShading: true
29869
29911
  // Consistent with board
29870
29912
  })
@@ -29909,7 +29951,7 @@ var BoardMeshes = ({
29909
29951
  const typedMaterial = material;
29910
29952
  for (const prop of textureProps) {
29911
29953
  const texture = typedMaterial[prop];
29912
- if (texture && texture instanceof THREE54.Texture) {
29954
+ if (texture && texture instanceof THREE55.Texture) {
29913
29955
  texture.dispose();
29914
29956
  }
29915
29957
  }
@@ -38116,7 +38158,7 @@ var useGlobalDownloadGltf = () => {
38116
38158
 
38117
38159
  // src/CadViewer.tsx
38118
38160
  import { jsx as jsx38, jsxs as jsxs10 } from "react/jsx-runtime";
38119
- var DEFAULT_TARGET = new THREE55.Vector3(0, 0, 0);
38161
+ var DEFAULT_TARGET = new THREE56.Vector3(0, 0, 0);
38120
38162
  var INITIAL_CAMERA_POSITION = [5, -5, 5];
38121
38163
  var readStoredCameraType = () => {
38122
38164
  if (typeof window === "undefined") return void 0;
@@ -38439,11 +38481,11 @@ var CadViewer = (props) => {
38439
38481
  // src/convert-circuit-json-to-3d-svg.ts
38440
38482
  var import_debug = __toESM(require_browser(), 1);
38441
38483
  import { su as su18 } from "@tscircuit/circuit-json-util";
38442
- import * as THREE59 from "three";
38484
+ import * as THREE60 from "three";
38443
38485
  import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
38444
38486
 
38445
38487
  // src/utils/create-geometry-from-polygons.ts
38446
- import * as THREE56 from "three";
38488
+ import * as THREE57 from "three";
38447
38489
  import { BufferGeometry as BufferGeometry6, Float32BufferAttribute as Float32BufferAttribute6 } from "three";
38448
38490
  function createGeometryFromPolygons(polygons) {
38449
38491
  const geometry = new BufferGeometry6();
@@ -38457,12 +38499,12 @@ function createGeometryFromPolygons(polygons) {
38457
38499
  ...polygon2.vertices[i + 1]
38458
38500
  // Third vertex
38459
38501
  );
38460
- const v1 = new THREE56.Vector3(...polygon2.vertices[0]);
38461
- const v2 = new THREE56.Vector3(...polygon2.vertices[i]);
38462
- const v3 = new THREE56.Vector3(...polygon2.vertices[i + 1]);
38463
- const normal = new THREE56.Vector3().crossVectors(
38464
- new THREE56.Vector3().subVectors(v2, v1),
38465
- new THREE56.Vector3().subVectors(v3, v1)
38502
+ const v1 = new THREE57.Vector3(...polygon2.vertices[0]);
38503
+ const v2 = new THREE57.Vector3(...polygon2.vertices[i]);
38504
+ const v3 = new THREE57.Vector3(...polygon2.vertices[i + 1]);
38505
+ const normal = new THREE57.Vector3().crossVectors(
38506
+ new THREE57.Vector3().subVectors(v2, v1),
38507
+ new THREE57.Vector3().subVectors(v3, v1)
38466
38508
  ).normalize();
38467
38509
  normals.push(
38468
38510
  normal.x,
@@ -38490,10 +38532,10 @@ import {
38490
38532
  convertCSGToThreeGeom as convertCSGToThreeGeom3,
38491
38533
  getJscadModelForFootprint as getJscadModelForFootprint2
38492
38534
  } from "jscad-electronics/vanilla";
38493
- import * as THREE58 from "three";
38535
+ import * as THREE59 from "three";
38494
38536
 
38495
38537
  // src/utils/load-model.ts
38496
- import * as THREE57 from "three";
38538
+ import * as THREE58 from "three";
38497
38539
  import { GLTFLoader as GLTFLoader2 } from "three/examples/jsm/loaders/GLTFLoader.js";
38498
38540
  import { OBJLoader as OBJLoader2 } from "three/examples/jsm/loaders/OBJLoader.js";
38499
38541
  import { STLLoader as STLLoader2 } from "three/examples/jsm/loaders/STLLoader.js";
@@ -38501,12 +38543,12 @@ async function load3DModel(url) {
38501
38543
  if (url.endsWith(".stl")) {
38502
38544
  const loader = new STLLoader2();
38503
38545
  const geometry = await loader.loadAsync(url);
38504
- const material = new THREE57.MeshStandardMaterial({
38546
+ const material = new THREE58.MeshStandardMaterial({
38505
38547
  color: 8947848,
38506
38548
  metalness: 0.5,
38507
38549
  roughness: 0.5
38508
38550
  });
38509
- return new THREE57.Mesh(geometry, material);
38551
+ return new THREE58.Mesh(geometry, material);
38510
38552
  }
38511
38553
  if (url.endsWith(".obj")) {
38512
38554
  const loader = new OBJLoader2();
@@ -38539,9 +38581,9 @@ async function renderComponent(component, scene) {
38539
38581
  }
38540
38582
  if (component.rotation) {
38541
38583
  model.rotation.set(
38542
- THREE58.MathUtils.degToRad(component.rotation.x ?? 0),
38543
- THREE58.MathUtils.degToRad(component.rotation.y ?? 0),
38544
- THREE58.MathUtils.degToRad(component.rotation.z ?? 0)
38584
+ THREE59.MathUtils.degToRad(component.rotation.x ?? 0),
38585
+ THREE59.MathUtils.degToRad(component.rotation.y ?? 0),
38586
+ THREE59.MathUtils.degToRad(component.rotation.z ?? 0)
38545
38587
  );
38546
38588
  }
38547
38589
  scene.add(model);
@@ -38555,13 +38597,13 @@ async function renderComponent(component, scene) {
38555
38597
  );
38556
38598
  if (jscadObject && (jscadObject.polygons || jscadObject.sides)) {
38557
38599
  const threeGeom = convertCSGToThreeGeom3(jscadObject);
38558
- const material2 = new THREE58.MeshStandardMaterial({
38600
+ const material2 = new THREE59.MeshStandardMaterial({
38559
38601
  color: 8947848,
38560
38602
  metalness: 0.5,
38561
38603
  roughness: 0.5,
38562
- side: THREE58.DoubleSide
38604
+ side: THREE59.DoubleSide
38563
38605
  });
38564
- const mesh2 = new THREE58.Mesh(threeGeom, material2);
38606
+ const mesh2 = new THREE59.Mesh(threeGeom, material2);
38565
38607
  if (component.position) {
38566
38608
  mesh2.position.set(
38567
38609
  component.position.x ?? 0,
@@ -38571,9 +38613,9 @@ async function renderComponent(component, scene) {
38571
38613
  }
38572
38614
  if (component.rotation) {
38573
38615
  mesh2.rotation.set(
38574
- THREE58.MathUtils.degToRad(component.rotation.x ?? 0),
38575
- THREE58.MathUtils.degToRad(component.rotation.y ?? 0),
38576
- THREE58.MathUtils.degToRad(component.rotation.z ?? 0)
38616
+ THREE59.MathUtils.degToRad(component.rotation.x ?? 0),
38617
+ THREE59.MathUtils.degToRad(component.rotation.y ?? 0),
38618
+ THREE59.MathUtils.degToRad(component.rotation.z ?? 0)
38577
38619
  );
38578
38620
  }
38579
38621
  scene.add(mesh2);
@@ -38590,17 +38632,17 @@ async function renderComponent(component, scene) {
38590
38632
  if (!geom || !geom.polygons && !geom.sides) {
38591
38633
  continue;
38592
38634
  }
38593
- const color = new THREE58.Color(geomInfo.color);
38635
+ const color = new THREE59.Color(geomInfo.color);
38594
38636
  color.convertLinearToSRGB();
38595
38637
  const geomWithColor = { ...geom, color: [color.r, color.g, color.b] };
38596
38638
  const threeGeom = convertCSGToThreeGeom3(geomWithColor);
38597
- const material2 = new THREE58.MeshStandardMaterial({
38639
+ const material2 = new THREE59.MeshStandardMaterial({
38598
38640
  vertexColors: true,
38599
38641
  metalness: 0.2,
38600
38642
  roughness: 0.8,
38601
- side: THREE58.DoubleSide
38643
+ side: THREE59.DoubleSide
38602
38644
  });
38603
- const mesh2 = new THREE58.Mesh(threeGeom, material2);
38645
+ const mesh2 = new THREE59.Mesh(threeGeom, material2);
38604
38646
  if (component.position) {
38605
38647
  mesh2.position.set(
38606
38648
  component.position.x ?? 0,
@@ -38610,22 +38652,22 @@ async function renderComponent(component, scene) {
38610
38652
  }
38611
38653
  if (component.rotation) {
38612
38654
  mesh2.rotation.set(
38613
- THREE58.MathUtils.degToRad(component.rotation.x ?? 0),
38614
- THREE58.MathUtils.degToRad(component.rotation.y ?? 0),
38615
- THREE58.MathUtils.degToRad(component.rotation.z ?? 0)
38655
+ THREE59.MathUtils.degToRad(component.rotation.x ?? 0),
38656
+ THREE59.MathUtils.degToRad(component.rotation.y ?? 0),
38657
+ THREE59.MathUtils.degToRad(component.rotation.z ?? 0)
38616
38658
  );
38617
38659
  }
38618
38660
  scene.add(mesh2);
38619
38661
  }
38620
38662
  return;
38621
38663
  }
38622
- const geometry = new THREE58.BoxGeometry(0.5, 0.5, 0.5);
38623
- const material = new THREE58.MeshStandardMaterial({
38664
+ const geometry = new THREE59.BoxGeometry(0.5, 0.5, 0.5);
38665
+ const material = new THREE59.MeshStandardMaterial({
38624
38666
  color: 16711680,
38625
38667
  transparent: true,
38626
38668
  opacity: 0.25
38627
38669
  });
38628
- const mesh = new THREE58.Mesh(geometry, material);
38670
+ const mesh = new THREE59.Mesh(geometry, material);
38629
38671
  if (component.position) {
38630
38672
  mesh.position.set(
38631
38673
  component.position.x ?? 0,
@@ -38646,11 +38688,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
38646
38688
  padding = 20,
38647
38689
  zoom = 1.5
38648
38690
  } = options;
38649
- const scene = new THREE59.Scene();
38691
+ const scene = new THREE60.Scene();
38650
38692
  const renderer = new SVGRenderer();
38651
38693
  renderer.setSize(width, height);
38652
- renderer.setClearColor(new THREE59.Color(backgroundColor), 1);
38653
- const camera = new THREE59.OrthographicCamera();
38694
+ renderer.setClearColor(new THREE60.Color(backgroundColor), 1);
38695
+ const camera = new THREE60.OrthographicCamera();
38654
38696
  const aspect = width / height;
38655
38697
  const frustumSize = 100;
38656
38698
  const halfFrustumSize = frustumSize / 2 / zoom;
@@ -38664,11 +38706,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
38664
38706
  camera.position.set(position.x, position.y, position.z);
38665
38707
  camera.up.set(0, 1, 0);
38666
38708
  const lookAt2 = options.camera?.lookAt ?? { x: 0, y: 0, z: 0 };
38667
- camera.lookAt(new THREE59.Vector3(lookAt2.x, lookAt2.y, lookAt2.z));
38709
+ camera.lookAt(new THREE60.Vector3(lookAt2.x, lookAt2.y, lookAt2.z));
38668
38710
  camera.updateProjectionMatrix();
38669
- const ambientLight = new THREE59.AmbientLight(16777215, Math.PI / 2);
38711
+ const ambientLight = new THREE60.AmbientLight(16777215, Math.PI / 2);
38670
38712
  scene.add(ambientLight);
38671
- const pointLight = new THREE59.PointLight(16777215, Math.PI / 4);
38713
+ const pointLight = new THREE60.PointLight(16777215, Math.PI / 4);
38672
38714
  pointLight.position.set(-10, -10, 10);
38673
38715
  scene.add(pointLight);
38674
38716
  const components = su18(circuitJson).cad_component.list();
@@ -38700,28 +38742,28 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
38700
38742
  const material = createBoardMaterial({
38701
38743
  material: boardData?.material,
38702
38744
  color: edgeColor,
38703
- side: THREE59.DoubleSide
38745
+ side: THREE60.DoubleSide
38704
38746
  });
38705
- const mesh = new THREE59.Mesh(geometry, material);
38747
+ const mesh = new THREE60.Mesh(geometry, material);
38706
38748
  scene.add(mesh);
38707
38749
  }
38708
38750
  }
38709
- const gridColor = new THREE59.Color(8947848);
38710
- const gridHelper = new THREE59.GridHelper(100, 100, gridColor, gridColor);
38751
+ const gridColor = new THREE60.Color(8947848);
38752
+ const gridHelper = new THREE60.GridHelper(100, 100, gridColor, gridColor);
38711
38753
  gridHelper.rotation.x = Math.PI / 2;
38712
38754
  const materials = Array.isArray(gridHelper.material) ? gridHelper.material : [gridHelper.material];
38713
38755
  for (const mat of materials) {
38714
38756
  mat.transparent = true;
38715
38757
  mat.opacity = 0.3;
38716
- if (mat instanceof THREE59.LineBasicMaterial) {
38758
+ if (mat instanceof THREE60.LineBasicMaterial) {
38717
38759
  mat.color = gridColor;
38718
38760
  mat.vertexColors = false;
38719
38761
  }
38720
38762
  }
38721
38763
  scene.add(gridHelper);
38722
- const box = new THREE59.Box3().setFromObject(scene);
38723
- const center = box.getCenter(new THREE59.Vector3());
38724
- const size4 = box.getSize(new THREE59.Vector3());
38764
+ const box = new THREE60.Box3().setFromObject(scene);
38765
+ const center = box.getCenter(new THREE60.Vector3());
38766
+ const size4 = box.getSize(new THREE60.Vector3());
38725
38767
  scene.position.sub(center);
38726
38768
  const maxDim = Math.max(size4.x, size4.y, size4.z);
38727
38769
  if (maxDim > 0) {