@tscircuit/3d-viewer 0.0.80 → 0.0.82

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.d.ts CHANGED
@@ -1,10 +1,26 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
1
+ import * as React from 'react';
2
+ import * as THREE from 'three';
3
+ import { GLTFExporterOptions } from 'three-stdlib';
2
4
  import { AnySoupElement } from '@tscircuit/soup';
3
5
 
6
+ type Options = Omit<GLTFExporterOptions, "animations" | "includeCustomExtensions">;
7
+ declare function useSaveGltfAs(options?: Options & {
8
+ filename?: string;
9
+ }): [
10
+ ref3D: React.ForwardedRef<THREE.Object3D>,
11
+ saveAs: (filename?: string) => Promise<void>
12
+ ];
13
+ declare function useExportGltfUrl(options?: Options): [
14
+ ref3D: React.ForwardedRef<THREE.Object3D>,
15
+ url: string | undefined,
16
+ error: ErrorEvent | undefined
17
+ ];
18
+
4
19
  interface Props {
5
20
  soup?: AnySoupElement[];
6
- children?: any;
7
21
  }
8
- declare const CadViewer: ({ soup, children }: Props) => react_jsx_runtime.JSX.Element | null;
22
+ declare const CadViewer: React.ForwardRefExoticComponent<Props & {
23
+ children?: React.ReactNode | undefined;
24
+ } & React.RefAttributes<THREE.Object3D<THREE.Object3DEventMap>>>;
9
25
 
10
- export { CadViewer };
26
+ export { CadViewer, useExportGltfUrl, useSaveGltfAs };
package/dist/index.js CHANGED
@@ -30,15 +30,77 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.tsx
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
- CadViewer: () => CadViewer
33
+ CadViewer: () => CadViewer,
34
+ useExportGltfUrl: () => useExportGltfUrl,
35
+ useSaveGltfAs: () => useSaveGltfAs
34
36
  });
35
37
  module.exports = __toCommonJS(src_exports);
36
38
 
39
+ // src/hooks/exporter/gltf.ts
40
+ var import_three_stdlib = require("three-stdlib");
41
+ var import_react = require("react");
42
+ function useSaveGltfAs(options = {}) {
43
+ const parse = useParser(options);
44
+ const link = (0, import_react.useMemo)(() => document.createElement("a"), []);
45
+ const saveAs = async (filename) => {
46
+ const name = filename ?? options.filename ?? "";
47
+ if (options.binary == null) options.binary = name.endsWith(".glb");
48
+ const url = await parse(instance);
49
+ link.download = name;
50
+ link.href = url;
51
+ link.dispatchEvent(new MouseEvent("click"));
52
+ URL.revokeObjectURL(url);
53
+ };
54
+ (0, import_react.useEffect)(
55
+ () => () => {
56
+ link.remove();
57
+ instance = null;
58
+ },
59
+ []
60
+ );
61
+ let instance;
62
+ const ref = (0, import_react.useCallback)((obj3D) => {
63
+ instance = obj3D;
64
+ }, []);
65
+ return [ref, saveAs];
66
+ }
67
+ function useExportGltfUrl(options = {}) {
68
+ const parse = useParser(options);
69
+ const [url, setUrl] = (0, import_react.useState)();
70
+ const [error, setError] = (0, import_react.useState)();
71
+ const ref = (0, import_react.useCallback)(
72
+ (instance) => parse(instance).then(setUrl).catch(setError),
73
+ []
74
+ );
75
+ (0, import_react.useEffect)(() => () => URL.revokeObjectURL(url), [url]);
76
+ return [ref, url, error];
77
+ }
78
+ function useParser(options = {}) {
79
+ const exporter = (0, import_react.useMemo)(() => new import_three_stdlib.GLTFExporter(), []);
80
+ return (instance) => {
81
+ const { promise, resolve, reject } = Promise.withResolvers();
82
+ exporter.parse(
83
+ instance,
84
+ (gltf) => {
85
+ const type = options.binary ? "gltf-binary" : "gltf+json";
86
+ const blob = new Blob(
87
+ [gltf instanceof ArrayBuffer ? gltf : JSON.stringify(gltf)],
88
+ { type: `model/${type}` }
89
+ );
90
+ resolve(URL.createObjectURL(blob));
91
+ },
92
+ reject,
93
+ options
94
+ );
95
+ return promise;
96
+ };
97
+ }
98
+
37
99
  // src/hooks/use-convert-children-to-soup.ts
38
100
  var import_core = require("@tscircuit/core");
39
- var import_react = require("react");
101
+ var import_react2 = require("react");
40
102
  var useConvertChildrenToSoup = (children, defaultSoup) => {
41
- return (0, import_react.useMemo)(() => {
103
+ return (0, import_react2.useMemo)(() => {
42
104
  if (!children) return;
43
105
  const circuit = new import_core.Circuit();
44
106
  circuit.add(children);
@@ -49,7 +111,7 @@ var useConvertChildrenToSoup = (children, defaultSoup) => {
49
111
 
50
112
  // src/CadViewer.tsx
51
113
  var import_soup_util2 = require("@tscircuit/soup-util");
52
- var import_react10 = require("react");
114
+ var import_react12 = require("react");
53
115
 
54
116
  // src/soup-to-3d/index.ts
55
117
  var import_soup_util = require("@tscircuit/soup-util");
@@ -477,7 +539,7 @@ var createBoardGeomFromSoup = (soup) => {
477
539
  };
478
540
 
479
541
  // src/hooks/use-stls-from-geom.ts
480
- var import_react2 = require("react");
542
+ var import_react3 = require("react");
481
543
  var import_stl_serializer = __toESM(require("@jscad/stl-serializer"));
482
544
  function blobToBase64Url(blob) {
483
545
  return new Promise((resolve, reject) => {
@@ -490,9 +552,9 @@ function blobToBase64Url(blob) {
490
552
  });
491
553
  }
492
554
  var useStlsFromGeom = (geom) => {
493
- const [stls, setStls] = (0, import_react2.useState)([]);
494
- const [loading, setLoading] = (0, import_react2.useState)(true);
495
- (0, import_react2.useEffect)(() => {
555
+ const [stls, setStls] = (0, import_react3.useState)([]);
556
+ const [loading, setLoading] = (0, import_react3.useState)(true);
557
+ (0, import_react3.useEffect)(() => {
496
558
  if (!geom) return;
497
559
  const generateStls = async () => {
498
560
  setLoading(true);
@@ -520,8 +582,8 @@ var useStlsFromGeom = (geom) => {
520
582
 
521
583
  // src/three-components/STLModel.tsx
522
584
  var import_fiber = require("@react-three/fiber");
523
- var import_react3 = require("react");
524
- var import_three_stdlib = require("three-stdlib");
585
+ var import_react4 = require("react");
586
+ var import_three_stdlib2 = require("three-stdlib");
525
587
  var import_jsx_runtime = require("react/jsx-runtime");
526
588
  function STLModel({
527
589
  stlUrl,
@@ -529,8 +591,8 @@ function STLModel({
529
591
  color,
530
592
  opacity = 1
531
593
  }) {
532
- const geom = (0, import_fiber.useLoader)(import_three_stdlib.STLLoader, stlUrl);
533
- const mesh = (0, import_react3.useRef)();
594
+ const geom = (0, import_fiber.useLoader)(import_three_stdlib2.STLLoader, stlUrl);
595
+ const mesh = (0, import_react4.useRef)();
534
596
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("mesh", { ref: mesh, children: [
535
597
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("primitive", { object: geom, attach: "geometry" }),
536
598
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -551,7 +613,7 @@ var import_fiber3 = require("@react-three/fiber");
551
613
  // package.json
552
614
  var package_default = {
553
615
  name: "@tscircuit/3d-viewer",
554
- version: "0.0.79",
616
+ version: "0.0.81",
555
617
  main: "./dist/index.js",
556
618
  files: [
557
619
  "dist"
@@ -575,7 +637,7 @@ var package_default = {
575
637
  "@react-three/drei": "^9.115.0",
576
638
  "@react-three/fiber": "^8.16.8",
577
639
  "@tscircuit/core": "^0.0.251",
578
- "@tscircuit/props": "^0.0.124",
640
+ "@tscircuit/props": "^0.0.125",
579
641
  "@tscircuit/react-fiber": "^1.1.29",
580
642
  "@tscircuit/soup": "^0.0.69",
581
643
  "@tscircuit/soup-util": "^0.0.26",
@@ -592,25 +654,25 @@ var package_default = {
592
654
  devDependencies: {
593
655
  "@biomejs/biome": "^1.8.3",
594
656
  "@chromatic-com/storybook": "^1.5.0",
595
- "@storybook/addon-essentials": "^8.1.10",
596
- "@storybook/addon-interactions": "^8.1.10",
597
- "@storybook/addon-links": "^8.1.10",
598
- "@storybook/addon-onboarding": "^8.1.10",
599
- "@storybook/blocks": "^8.1.10",
600
- "@storybook/builder-vite": "^8.1.10",
601
- "@storybook/react": "^8.1.10",
602
- "@storybook/react-vite": "^8.1.10",
603
- "@storybook/test": "^8.1.10",
657
+ "@storybook/addon-essentials": "^8.4.7",
658
+ "@storybook/addon-interactions": "^8.4.7",
659
+ "@storybook/addon-links": "^8.4.7",
660
+ "@storybook/addon-onboarding": "^8.4.7",
661
+ "@storybook/blocks": "^8.4.7",
662
+ "@storybook/builder-vite": "^8.4.7",
663
+ "@storybook/react": "^8.4.7",
664
+ "@storybook/react-vite": "^8.4.7",
665
+ "@storybook/test": "^8.4.7",
604
666
  "@types/react": "^18.3.3",
605
667
  "@types/react-dom": "^18.3.0",
606
- "@vitejs/plugin-react": "^4.3.1",
668
+ "@vitejs/plugin-react": "^4.3.4",
607
669
  "circuit-json": "^0.0.116",
608
670
  "circuit-to-svg": "^0.0.91",
609
- storybook: "^8.1.10",
671
+ storybook: "^8.4.7",
610
672
  "strip-ansi": "^7.1.0",
611
673
  tsup: "^8.1.0",
612
- typescript: "^5.5.3",
613
- vite: "^5.3.1",
674
+ typescript: "^5.7.2",
675
+ vite: "^5.4.11",
614
676
  "vite-tsconfig-paths": "^4.3.2"
615
677
  }
616
678
  };
@@ -618,7 +680,7 @@ var package_default = {
618
680
  // src/three-components/cube-with-labeled-sides.tsx
619
681
  var import_drei = require("@react-three/drei");
620
682
  var import_fiber2 = require("@react-three/fiber");
621
- var import_react4 = require("react");
683
+ var import_react5 = require("react");
622
684
  var THREE = __toESM(require("three"));
623
685
  var import_jsx_runtime2 = require("react/jsx-runtime");
624
686
  if (typeof window !== "undefined") {
@@ -634,8 +696,8 @@ function computePointInFront(rotationVector, distance) {
634
696
  return result;
635
697
  }
636
698
  var CubeWithLabeledSides = ({}) => {
637
- const ref = (0, import_react4.useRef)();
638
- const rotationTrackingRef = (0, import_react4.useRef)({ lastRotation: new THREE.Euler() });
699
+ const ref = (0, import_react5.useRef)();
700
+ const rotationTrackingRef = (0, import_react5.useRef)({ lastRotation: new THREE.Euler() });
639
701
  (0, import_fiber2.useFrame)((state, delta) => {
640
702
  if (!ref.current) return;
641
703
  const mainRot = window.TSCI_MAIN_CAMERA_ROTATION;
@@ -711,6 +773,7 @@ var CubeWithLabeledSides = ({}) => {
711
773
  };
712
774
 
713
775
  // src/CadViewerContainer.tsx
776
+ var import_react6 = require("react");
714
777
  var import_drei3 = require("@react-three/drei");
715
778
  var import_jsx_runtime3 = require("react/jsx-runtime");
716
779
  var RotationTracker = () => {
@@ -719,10 +782,7 @@ var RotationTracker = () => {
719
782
  });
720
783
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, {});
721
784
  };
722
- var CadViewerContainer = ({
723
- children,
724
- hoveredComponent
725
- }) => {
785
+ var CadViewerContainer = (0, import_react6.forwardRef)(({ children, hoveredComponent }, ref) => {
726
786
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { position: "relative", width: "100%", height: "100%" }, children: [
727
787
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
728
788
  "div",
@@ -776,7 +836,7 @@ var CadViewerContainer = ({
776
836
  sectionSize: 10
777
837
  }
778
838
  ),
779
- children,
839
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("object3D", { ref, children }),
780
840
  hoveredComponent && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
781
841
  import_drei3.Html,
782
842
  {
@@ -818,10 +878,10 @@ var CadViewerContainer = ({
818
878
  }
819
879
  )
820
880
  ] });
821
- };
881
+ });
822
882
 
823
883
  // src/ContainerWithTooltip.tsx
824
- var import_react5 = require("react");
884
+ var import_react7 = require("react");
825
885
  var THREE2 = __toESM(require("three"));
826
886
  var import_jsx_runtime4 = require("react/jsx-runtime");
827
887
  var Group = (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("group", { ...props });
@@ -831,8 +891,8 @@ var ContainerWithTooltip = ({
831
891
  onHover,
832
892
  position
833
893
  }) => {
834
- const lastValidPointRef = (0, import_react5.useRef)(null);
835
- const handlePointerEnter = (0, import_react5.useCallback)(
894
+ const lastValidPointRef = (0, import_react7.useRef)(null);
895
+ const handlePointerEnter = (0, import_react7.useCallback)(
836
896
  (e) => {
837
897
  e.stopPropagation();
838
898
  try {
@@ -850,7 +910,7 @@ var ContainerWithTooltip = ({
850
910
  },
851
911
  [position]
852
912
  );
853
- const handlePointerLeave = (0, import_react5.useCallback)(
913
+ const handlePointerLeave = (0, import_react7.useCallback)(
854
914
  (e) => {
855
915
  e.stopPropagation();
856
916
  lastValidPointRef.current = null;
@@ -871,14 +931,14 @@ var ContainerWithTooltip = ({
871
931
  var ContainerWithTooltip_default = ContainerWithTooltip;
872
932
 
873
933
  // src/hooks/use-global-obj-loader.ts
874
- var import_react6 = require("react");
875
- var import_three_stdlib2 = require("three-stdlib");
934
+ var import_react8 = require("react");
935
+ var import_three_stdlib3 = require("three-stdlib");
876
936
  if (typeof window !== "undefined" && !window.TSCIRCUIT_OBJ_LOADER_CACHE) {
877
937
  window.TSCIRCUIT_OBJ_LOADER_CACHE = /* @__PURE__ */ new Map();
878
938
  }
879
939
  function useGlobalObjLoader(url) {
880
- const [obj, setObj] = (0, import_react6.useState)(null);
881
- (0, import_react6.useEffect)(() => {
940
+ const [obj, setObj] = (0, import_react8.useState)(null);
941
+ (0, import_react8.useEffect)(() => {
882
942
  if (!url) return;
883
943
  const cache = window.TSCIRCUIT_OBJ_LOADER_CACHE;
884
944
  let hasUrlChanged = false;
@@ -888,7 +948,7 @@ function useGlobalObjLoader(url) {
888
948
  const text = await response.text();
889
949
  const mtlContent = text.match(/newmtl[\s\S]*?endmtl/g)?.join("\n").replace(/d 0\./g, "d 1.");
890
950
  const objContent = text.replace(/newmtl[\s\S]*?endmtl/g, "");
891
- const mtlLoader = new import_three_stdlib2.MTLLoader();
951
+ const mtlLoader = new import_three_stdlib3.MTLLoader();
892
952
  mtlLoader.setMaterialOptions({
893
953
  invertTrProperty: true
894
954
  });
@@ -899,7 +959,7 @@ function useGlobalObjLoader(url) {
899
959
  ),
900
960
  "test.mtl"
901
961
  );
902
- const objLoader = new import_three_stdlib2.OBJLoader();
962
+ const objLoader = new import_three_stdlib3.OBJLoader();
903
963
  objLoader.setMaterials(materials);
904
964
  return objLoader.parse(objContent);
905
965
  } catch (error) {
@@ -968,7 +1028,7 @@ var import_jscad_planner = require("jscad-planner");
968
1028
  var import_modeling = __toESM(require("@jscad/modeling"));
969
1029
  var import_jscad_fiber = require("jscad-fiber");
970
1030
  var THREE3 = __toESM(require("three"));
971
- var import_react7 = require("react");
1031
+ var import_react9 = require("react");
972
1032
  var import_jsx_runtime6 = require("react/jsx-runtime");
973
1033
  var JscadModel = ({
974
1034
  jscadPlan,
@@ -977,7 +1037,7 @@ var JscadModel = ({
977
1037
  onHover,
978
1038
  isHovered
979
1039
  }) => {
980
- const { threeGeom, material } = (0, import_react7.useMemo)(() => {
1040
+ const { threeGeom, material } = (0, import_react9.useMemo)(() => {
981
1041
  const jscadObject = (0, import_jscad_planner.executeJscadOperations)(import_modeling.default, jscadPlan);
982
1042
  const threeGeom2 = (0, import_jscad_fiber.convertCSGToThreeGeom)(jscadObject);
983
1043
  const material2 = new THREE3.MeshStandardMaterial({
@@ -987,7 +1047,7 @@ var JscadModel = ({
987
1047
  });
988
1048
  return { threeGeom: threeGeom2, material: material2 };
989
1049
  }, [jscadPlan]);
990
- (0, import_react7.useMemo)(() => {
1050
+ (0, import_react9.useMemo)(() => {
991
1051
  if (isHovered) {
992
1052
  const color = new THREE3.Color(material.color.getHex());
993
1053
  material.emissive.copy(color);
@@ -1021,7 +1081,7 @@ var JscadModel = ({
1021
1081
  var import_jscad_electronics = require("jscad-electronics");
1022
1082
  var import_jscad_fiber2 = require("jscad-fiber");
1023
1083
  var import_jscad_planner2 = require("jscad-planner");
1024
- var import_react8 = require("react");
1084
+ var import_react10 = require("react");
1025
1085
  var import_jsx_runtime7 = require("react/jsx-runtime");
1026
1086
  var { createJSCADRoot } = (0, import_jscad_fiber2.createJSCADRenderer)(import_jscad_planner2.jscadPlanner);
1027
1087
  var FootprinterModel = ({
@@ -1031,7 +1091,7 @@ var FootprinterModel = ({
1031
1091
  onHover,
1032
1092
  isHovered
1033
1093
  }) => {
1034
- const jscadOperations = (0, import_react8.useMemo)(() => {
1094
+ const jscadOperations = (0, import_react10.useMemo)(() => {
1035
1095
  if (!footprint) return null;
1036
1096
  const jscadOperations2 = [];
1037
1097
  const root = createJSCADRoot(jscadOperations2);
@@ -1117,8 +1177,8 @@ var AnyCadComponent = ({
1117
1177
  };
1118
1178
 
1119
1179
  // src/three-components/ThreeErrorBoundary.tsx
1120
- var import_react9 = __toESM(require("react"));
1121
- var ThreeErrorBoundary = class extends import_react9.default.Component {
1180
+ var import_react11 = __toESM(require("react"));
1181
+ var ThreeErrorBoundary = class extends import_react11.default.Component {
1122
1182
  constructor(props) {
1123
1183
  super(props);
1124
1184
  this.state = { hasError: false, error: null };
@@ -1200,17 +1260,17 @@ var Error3d = ({
1200
1260
 
1201
1261
  // src/CadViewer.tsx
1202
1262
  var import_jsx_runtime10 = require("react/jsx-runtime");
1203
- var CadViewer = ({ soup, children }) => {
1204
- const [hoveredComponent, setHoveredComponent] = (0, import_react10.useState)(null);
1263
+ var CadViewer = (0, import_react12.forwardRef)(({ soup, children }, ref) => {
1264
+ const [hoveredComponent, setHoveredComponent] = (0, import_react12.useState)(null);
1205
1265
  soup ??= useConvertChildrenToSoup(children, soup);
1206
1266
  if (!soup) return null;
1207
- const boardGeom = (0, import_react10.useMemo)(() => {
1267
+ const boardGeom = (0, import_react12.useMemo)(() => {
1208
1268
  if (!soup.some((e) => e.type === "pcb_board")) return null;
1209
1269
  return createBoardGeomFromSoup(soup);
1210
1270
  }, [soup]);
1211
1271
  const { stls: boardStls, loading } = useStlsFromGeom(boardGeom);
1212
1272
  const cad_components = (0, import_soup_util2.su)(soup).cad_component.list();
1213
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(CadViewerContainer, { hoveredComponent, children: [
1273
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(CadViewerContainer, { ref, hoveredComponent, children: [
1214
1274
  boardStls.map(({ stlUrl, color }, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1215
1275
  STLModel,
1216
1276
  {
@@ -1250,9 +1310,11 @@ var CadViewer = ({ soup, children }) => {
1250
1310
  cad_component.cad_component_id
1251
1311
  ))
1252
1312
  ] });
1253
- };
1313
+ });
1254
1314
  // Annotate the CommonJS export names for ESM import in node:
1255
1315
  0 && (module.exports = {
1256
- CadViewer
1316
+ CadViewer,
1317
+ useExportGltfUrl,
1318
+ useSaveGltfAs
1257
1319
  });
1258
1320
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx","../src/hooks/use-convert-children-to-soup.ts","../src/CadViewer.tsx","../src/soup-to-3d/index.ts","../src/geoms/plated-hole.ts","../src/geoms/constants.ts","../src/geoms/create-board-with-outline.ts","../src/geoms/create-geoms-for-silkscreen-text.ts","../src/hooks/use-stls-from-geom.ts","../src/three-components/STLModel.tsx","../src/CadViewerContainer.tsx","../package.json","../src/three-components/cube-with-labeled-sides.tsx","../src/ContainerWithTooltip.tsx","../src/hooks/use-global-obj-loader.ts","../src/three-components/MixedStlModel.tsx","../src/three-components/JscadModel.tsx","../src/three-components/FootprinterModel.tsx","../src/utils/tuple.ts","../src/AnyCadComponent.tsx","../src/three-components/ThreeErrorBoundary.tsx","../src/three-components/Error3d.tsx"],"sourcesContent":["export { CadViewer } from \"./CadViewer\"\n","import { Circuit } from \"@tscircuit/core\"\nimport { useMemo } from \"react\"\nimport type { AnyCircuitElement } from \"circuit-json\"\n\nexport const useConvertChildrenToSoup = (\n children?: any,\n defaultSoup?: AnyCircuitElement[],\n): AnyCircuitElement[] => {\n return useMemo(() => {\n if (!children) return\n const circuit = new Circuit()\n circuit.add(children)\n circuit.render()\n return circuit.getCircuitJson() as any\n }, [children])\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport { useConvertChildrenToSoup } from \"./hooks/use-convert-children-to-soup\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { useEffect, useMemo, useState } from \"react\"\nimport { createBoardGeomFromSoup } from \"./soup-to-3d\"\nimport { useStlsFromGeom } from \"./hooks/use-stls-from-geom\"\nimport { STLModel } from \"./three-components/STLModel\"\nimport { CadViewerContainer } from \"./CadViewerContainer\"\nimport { MixedStlModel } from \"./three-components/MixedStlModel\"\nimport { Euler } from \"three\"\nimport { JscadModel } from \"./three-components/JscadModel\"\nimport { Footprinter3d } from \"jscad-electronics\"\nimport { FootprinterModel } from \"./three-components/FootprinterModel\"\nimport { tuple } from \"./utils/tuple\"\nimport { AnyCadComponent } from \"./AnyCadComponent\"\nimport { Text } from \"@react-three/drei\"\nimport { ThreeErrorBoundary } from \"./three-components/ThreeErrorBoundary\"\nimport { Error3d } from \"./three-components/Error3d\"\n\ninterface Props {\n soup?: AnySoupElement[]\n children?: any\n}\n\nexport const CadViewer = ({ soup, children }: Props) => {\n const [hoveredComponent, setHoveredComponent] = useState<null | {\n cad_component_id: string\n name: string\n mousePosition: [number, number, number]\n }>(null)\n soup ??= useConvertChildrenToSoup(children, soup) as any\n\n if (!soup) return null\n\n const boardGeom = useMemo(() => {\n if (!soup.some((e) => e.type === \"pcb_board\")) return null\n return createBoardGeomFromSoup(soup)\n }, [soup])\n\n const { stls: boardStls, loading } = useStlsFromGeom(boardGeom)\n\n const cad_components = su(soup).cad_component.list()\n\n return (\n <CadViewerContainer hoveredComponent={hoveredComponent}>\n {boardStls.map(({ stlUrl, color }, index) => (\n <STLModel\n key={stlUrl}\n stlUrl={stlUrl}\n color={color}\n opacity={index === 0 ? 0.95 : 1}\n />\n ))}\n {cad_components.map((cad_component) => (\n <ThreeErrorBoundary\n key={cad_component.cad_component_id}\n fallback={({ error }) => (\n <Error3d cad_component={cad_component} error={error} />\n )}\n >\n <AnyCadComponent\n key={cad_component.cad_component_id}\n onHover={(e) => {\n // TODO this should be done by onUnhover\n if (!e) {\n setHoveredComponent(null)\n }\n if (!e.mousePosition) return\n\n const componentName = su(soup as any).source_component.getUsing({\n source_component_id: cad_component.source_component_id,\n })?.name\n setHoveredComponent({\n cad_component_id: cad_component.cad_component_id,\n name: componentName ?? \"<unknown>\",\n mousePosition: e.mousePosition,\n })\n }}\n cad_component={cad_component}\n isHovered={\n hoveredComponent?.cad_component_id ===\n cad_component.cad_component_id\n }\n />\n </ThreeErrorBoundary>\n ))}\n </CadViewerContainer>\n )\n}\n","import type { Geom3 } from \"@jscad/modeling/src/geometries/types\"\nimport type { AnySoupElement, PCBPlatedHole } from \"@tscircuit/soup\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { translate } from \"@jscad/modeling/src/operations/transforms\"\nimport { cuboid, cylinder, line } from \"@jscad/modeling/src/primitives\"\nimport { colorize } from \"@jscad/modeling/src/colors\"\nimport { subtract, union } from \"@jscad/modeling/src/operations/booleans\"\nimport { platedHole } from \"../geoms/plated-hole\"\nimport { M, colors } from \"../geoms/constants\"\nimport { extrudeLinear } from \"@jscad/modeling/src/operations/extrusions\"\nimport { expand } from \"@jscad/modeling/src/operations/expansions\"\nimport { createBoardWithOutline } from \"src/geoms/create-board-with-outline\"\nimport { Vec2 } from \"@jscad/modeling/src/maths/types\"\nimport { createSilkscreenTextGeoms } from \"src/geoms/create-geoms-for-silkscreen-text\"\nimport { PcbSilkscreenText } from \"circuit-json\"\nexport const createBoardGeomFromSoup = (soup: AnySoupElement[]): Geom3[] => {\n const board = su(soup).pcb_board.list()[0]\n if (!board) {\n throw new Error(\"No pcb_board found\")\n }\n const plated_holes = su(soup).pcb_plated_hole.list()\n const holes = su(soup).pcb_hole.list()\n const pads = su(soup).pcb_smtpad.list()\n const traces = su(soup).pcb_trace.list()\n const pcb_vias = su(soup).pcb_via.list()\n const silkscreenTexts = su(soup).pcb_silkscreen_text.list()\n\n // PCB Board\n let boardGeom: Geom3\n if (board.outline && board.outline.length > 0)\n boardGeom = createBoardWithOutline(board.outline, 1.2)\n else boardGeom = cuboid({ size: [board.width, board.height, 1.2] })\n\n const platedHoleGeoms: Geom3[] = []\n const holeGeoms: Geom3[] = []\n const padGeoms: Geom3[] = []\n const traceGeoms: Geom3[] = []\n const ctx = {\n pcbThickness: 1.2,\n }\n\n const addPlatedHole = (plated_hole: PCBPlatedHole) => {\n if (plated_hole.shape === \"circle\") {\n const cyGeom = cylinder({\n center: [plated_hole.x, plated_hole.y, 0],\n radius: plated_hole.hole_diameter / 2 + M,\n })\n\n boardGeom = subtract(boardGeom, cyGeom)\n\n const platedHoleGeom = platedHole(plated_hole, ctx)\n platedHoleGeoms.push(platedHoleGeom)\n } else if (plated_hole.shape === \"pill\") {\n const shouldRotate = plated_hole.hole_height! > plated_hole.hole_width!\n\n const holeWidth = shouldRotate\n ? plated_hole.hole_height!\n : plated_hole.hole_width!\n const holeHeight = shouldRotate\n ? plated_hole.hole_width!\n : plated_hole.hole_height!\n\n const holeRadius = holeHeight / 2\n const rectLength = Math.abs(holeWidth - holeHeight)\n\n const pillHole = union(\n cuboid({\n center: [plated_hole.x, plated_hole.y, 0],\n size: shouldRotate\n ? [holeHeight, rectLength, 1.5]\n : [rectLength, holeHeight, 1.5],\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 0]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.5,\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 0]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.5,\n }),\n )\n boardGeom = subtract(boardGeom, pillHole)\n\n const platedHoleGeom = platedHole(plated_hole, ctx)\n platedHoleGeoms.push(platedHoleGeom)\n }\n }\n\n for (const plated_hole of plated_holes) {\n addPlatedHole(plated_hole)\n }\n\n for (const hole of holes) {\n // @ts-expect-error\n if (hole.hole_shape === \"round\" || hole.hole_shape === \"circle\") {\n const cyGeom = cylinder({\n center: [hole.x, hole.y, 0],\n radius: hole.hole_diameter / 2 + M,\n })\n boardGeom = subtract(boardGeom, cyGeom)\n }\n }\n\n for (const pad of pads) {\n const layerSign = pad.layer === \"bottom\" ? -1 : 1\n if (pad.shape === \"rect\") {\n const padGeom = colorize(\n colors.copper,\n cuboid({\n center: [pad.x, pad.y, (layerSign * 1.2) / 2 + layerSign * M],\n size: [pad.width, pad.height, M],\n }),\n )\n padGeoms.push(padGeom)\n } else if (pad.shape === \"circle\") {\n const padGeom = colorize(\n colors.copper,\n cylinder({\n center: [pad.x, pad.y, (layerSign * 1.2) / 2 + layerSign * M],\n radius: pad.radius,\n height: M,\n }),\n )\n padGeoms.push(padGeom)\n }\n }\n\n for (const { route: mixedRoute } of traces) {\n if (mixedRoute.length < 2) continue\n\n // Group routes by continuous segments\n const routeSegments: (typeof mixedRoute)[] = []\n let currentSegment: typeof mixedRoute = [mixedRoute[0]!]\n let currentLayer =\n mixedRoute[0]!.route_type === \"wire\" ? mixedRoute[0]!.layer : \"top\"\n\n for (let i = 1; i < mixedRoute.length; i++) {\n const point = mixedRoute[i]!\n\n if (point.route_type === \"via\") {\n // Complete current segment and start a new one\n routeSegments.push(currentSegment)\n currentSegment = [point]\n } else if (point.route_type === \"wire\" && point.layer !== currentLayer) {\n // Complete current segment and start a new one on a different layer\n routeSegments.push(currentSegment)\n currentLayer = point.layer\n currentSegment = [point]\n } else {\n currentSegment.push(point)\n }\n }\n\n // Add the last segment\n routeSegments.push(currentSegment)\n\n // Render each route segment\n for (const route of routeSegments) {\n if (route.length < 2) continue\n\n const linePath = line(route.map((p) => [p.x, p.y]))\n const layerSign =\n route[0]!.route_type === \"via\"\n ? route[0]!.to_layer === \"top\"\n ? 1\n : -1\n : route[0]!.layer === \"top\"\n ? 1\n : -1\n\n let traceGeom = translate(\n [0, 0, (layerSign * 1.2) / 2],\n extrudeLinear(\n { height: M * layerSign },\n expand({ delta: 0.1, corners: \"edge\" }, linePath),\n ),\n )\n\n // Modify via subtraction to preserve trace geometry\n const viaSubtractions = pcb_vias.map((via) =>\n cylinder({\n center: [via.x, via.y, 0],\n radius: via.outer_diameter / 2,\n height: 5,\n }),\n )\n\n const holeSubtractions = plated_holes\n .filter((ph) => ph.shape === \"circle\")\n .map((ph) =>\n cylinder({\n center: [ph.x, ph.y, 0],\n radius: ph.outer_diameter / 2,\n height: 5,\n }),\n )\n\n // Subtract vias and holes without removing entire trace\n traceGeom = subtract(traceGeom, ...viaSubtractions, ...holeSubtractions)\n\n traceGeom = colorize(colors.fr4GreenSolderWithMask, traceGeom)\n\n traceGeoms.push(traceGeom)\n }\n }\n\n for (const via of pcb_vias) {\n addPlatedHole({\n x: via.x,\n y: via.y,\n hole_diameter: via.hole_diameter,\n outer_diameter: via.outer_diameter,\n shape: \"circle\",\n layers: [\"top\", \"bottom\"],\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: \"\",\n })\n }\n // Add silkscreen text\n const silkscreenGeoms: Geom3[] = []\n for (const silkscreenText of silkscreenTexts) {\n const { textOutlines, xOffset, yOffset } = createSilkscreenTextGeoms(\n silkscreenText as PcbSilkscreenText,\n )\n\n for (let outline of textOutlines) {\n // Create path from outline points with alignment offset\n\n const alignedOutline = outline.map((point) => [\n point[0] + xOffset + silkscreenText.anchor_position.x,\n point[1] + yOffset + silkscreenText.anchor_position.y,\n ]) as Vec2[]\n const textPath = line(alignedOutline)\n\n // Scale expansion delta with font size\n const fontSize = silkscreenText.font_size || 0.25\n const expansionDelta = Math.min(\n Math.max(0.01, fontSize * 0.1),\n fontSize * 0.2, // Maximum cap scales with font size\n )\n const expandedPath = expand(\n {\n delta: expansionDelta,\n corners: \"round\",\n },\n textPath,\n )\n\n // Extrude and position the text with smaller height\n let textGeom = translate(\n [0, 0, 0.6], // Position above board\n extrudeLinear(\n { height: 0.012 }, // Thinner extrusion\n expandedPath,\n ),\n )\n\n // Color white like silkscreen\n textGeom = colorize([256, 256, 256], textGeom)\n\n silkscreenGeoms.push(textGeom)\n }\n }\n\n // Colorize to a PCB green color: #05A32E\n boardGeom = colorize(colors.fr4Green, boardGeom)\n\n return [\n boardGeom,\n ...platedHoleGeoms,\n ...padGeoms,\n ...traceGeoms,\n ...silkscreenGeoms,\n ]\n}\n","import type { PCBPlatedHole } from \"@tscircuit/soup\"\nimport type { Geom3 } from \"@jscad/modeling/src/geometries/types\"\nimport { cuboid, cylinder } from \"@jscad/modeling/src/primitives\"\nimport { colorize } from \"@jscad/modeling/src/colors\"\nimport { subtract, union } from \"@jscad/modeling/src/operations/booleans\"\nimport { M, colors } from \"./constants\"\nimport type { GeomContext } from \"../GeomContext\"\n\nexport const platedHole = (\n plated_hole: PCBPlatedHole,\n ctx: GeomContext,\n): Geom3 => {\n if (!(plated_hole as PCBPlatedHole).shape) plated_hole.shape = \"circle\"\n if (plated_hole.shape === \"circle\") {\n return colorize(\n colors.copper,\n subtract(\n union(\n cylinder({\n center: [plated_hole.x, plated_hole.y, 0],\n radius: plated_hole.hole_diameter / 2,\n height: 1.2,\n }),\n cylinder({\n center: [plated_hole.x, plated_hole.y, 1.2 / 2],\n radius: plated_hole.outer_diameter / 2,\n height: M,\n }),\n cylinder({\n center: [plated_hole.x, plated_hole.y, -1.2 / 2],\n radius: plated_hole.outer_diameter / 2,\n height: M,\n }),\n ),\n cylinder({\n center: [plated_hole.x, plated_hole.y, 0],\n radius: plated_hole.hole_diameter / 2 - M,\n height: 1.5,\n }),\n ),\n )\n }\n if (plated_hole.shape === \"pill\") {\n const shouldRotate = plated_hole.hole_height! > plated_hole.hole_width!\n\n const holeWidth = shouldRotate\n ? plated_hole.hole_height!\n : plated_hole.hole_width!\n const holeHeight = shouldRotate\n ? plated_hole.hole_width!\n : plated_hole.hole_height!\n const outerHeight = shouldRotate\n ? plated_hole.outer_width || holeWidth + 0.2\n : plated_hole.outer_height || holeHeight + 0.2\n\n const holeRadius = holeHeight / 2\n const rectLength = Math.abs(holeWidth - holeHeight)\n\n const mainRect = cuboid({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y, 0]\n : [plated_hole.x, plated_hole.y, 0],\n size: shouldRotate\n ? [holeHeight, rectLength, 1.2]\n : [rectLength, holeHeight, 1.2],\n })\n\n const leftCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 0]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.2,\n })\n\n const rightCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 0]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.2,\n })\n\n const outerMainRect = cuboid({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y, 1.2 / 2]\n : [plated_hole.x, plated_hole.y, 1.2 / 2],\n size: shouldRotate\n ? [outerHeight, rectLength, M]\n : [rectLength, outerHeight, M],\n })\n\n const outerLeftCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 1.2 / 2]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n\n const outerRightCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 1.2 / 2]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n\n const bottomMainRect = cuboid({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y, -1.2 / 2]\n : [plated_hole.x, plated_hole.y, -1.2 / 2],\n size: shouldRotate\n ? [outerHeight, rectLength, M]\n : [rectLength, outerHeight, M],\n })\n\n const bottomLeftCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, -1.2 / 2]\n : [plated_hole.x - rectLength / 2, plated_hole.y, -1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n\n const bottomRightCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, -1.2 / 2]\n : [plated_hole.x + rectLength / 2, plated_hole.y, -1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n return colorize(\n colors.copper,\n subtract(\n union(\n mainRect,\n leftCap,\n rightCap,\n outerMainRect,\n outerLeftCap,\n outerRightCap,\n bottomMainRect,\n bottomLeftCap,\n bottomRightCap,\n ),\n union(\n cuboid({\n center: [plated_hole.x, plated_hole.y, 0],\n size: shouldRotate\n ? [holeHeight - M, rectLength, 1.5]\n : [rectLength, holeHeight - M, 1.5],\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 0]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 0],\n radius: holeRadius - M,\n height: 1.5,\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 0]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 0],\n radius: holeRadius - M,\n height: 1.5,\n }),\n ),\n ),\n )\n // biome-ignore lint/style/noUselessElse: <explanation>\n } else {\n throw new Error(`Unsupported plated hole shape: ${plated_hole.shape}`)\n }\n}\n","import type { RGB } from \"@jscad/modeling/src/colors\"\n\nexport const M = 0.01\n\nexport const colors = {\n copper: [0.9, 0.6, 0.2],\n fr4Green: [0x05 / 255, 0xa3 / 255, 0x2e / 255],\n fr4GreenSolderWithMask: [0x00 / 255, 0x98 / 255, 0x13 / 255],\n} satisfies Record<string, RGB>\n","import { extrudeLinear } from \"@jscad/modeling/src/operations/extrusions\"\nimport { polygon } from \"@jscad/modeling/src/primitives\"\nimport type { Geom2, Geom3 } from \"@jscad/modeling/src/geometries/types\"\nimport type { Vec2 } from \"@jscad/modeling/src/maths/types\"\nimport type { Point } from \"@tscircuit/soup\"\nimport { translate } from \"@jscad/modeling/src/operations/transforms\"\n\nconst arePointsClockwise = (points: Vec2[]): boolean => {\n let area = 0\n for (let i = 0; i < points.length; i++) {\n const j = (i + 1) % points.length\n area += points[i]![0] * points[j]![1]\n area -= points[j]![0] * points[i]![1]\n }\n const signedArea = area / 2\n return signedArea <= 0\n}\n\nexport const createBoardWithOutline = (points: Point[], depth = 1.2): Geom3 => {\n let outline: Vec2[] = points.map((point) => [point.x, point.y])\n\n if (arePointsClockwise(outline)) {\n outline = outline.reverse()\n }\n\n const shape: Geom2 = polygon({ points: outline })\n\n let board: Geom3 = extrudeLinear({ height: depth }, shape)\n\n board = translate([0, 0, -depth / 2], board)\n\n return board\n}\n","import { vectorText } from \"@jscad/modeling/src/text\"\nimport { PcbSilkscreenText } from \"circuit-json\"\n\n// Generate 2D text outlines\nexport function createSilkscreenTextGeoms(silkscreenText: PcbSilkscreenText) {\n // Generate 2D text outlines\n const textOutlines = vectorText({\n height: silkscreenText.font_size,\n input: silkscreenText.text,\n })\n // Split number 8 and small e into two parts to fix visual issues\n textOutlines.forEach((outline) => {\n if (outline.length === 29) {\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 1,\n outline.slice(0, 15),\n )\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 0,\n outline.slice(14, 29),\n )\n } else if (outline.length === 17) {\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 1,\n outline.slice(0, 10),\n )\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 0,\n outline.slice(9, 17),\n )\n }\n })\n // Calculate text bounds and center point\n const points = textOutlines.flatMap((o) => o)\n const textBounds = {\n minX: Math.min(...points.map((p) => p[0])),\n maxX: Math.max(...points.map((p) => p[0])),\n minY: Math.min(...points.map((p) => p[1])),\n maxY: Math.max(...points.map((p) => p[1])),\n }\n const centerX = (textBounds.minX + textBounds.maxX) / 2\n const centerY = (textBounds.minY + textBounds.maxY) / 2\n\n // Calculate offset based on anchor alignment\n let xOffset = -centerX\n let yOffset = -centerY\n\n // Adjust for specific alignments\n if (silkscreenText.anchor_alignment?.includes(\"right\")) {\n xOffset = -textBounds.maxX\n } else if (silkscreenText.anchor_alignment?.includes(\"left\")) {\n xOffset = -textBounds.minX\n }\n\n if (silkscreenText.anchor_alignment?.includes(\"top\")) {\n yOffset = -textBounds.maxY\n } else if (silkscreenText.anchor_alignment?.includes(\"bottom\")) {\n yOffset = -textBounds.minY\n }\n\n return { textOutlines, xOffset, yOffset }\n}\n","import { useState, useEffect } from \"react\"\nimport stlSerializer from \"@jscad/stl-serializer\"\nimport { Geom3 } from \"@jscad/modeling/src/geometries/types\"\n\nfunction blobToBase64Url(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => {\n resolve(reader.result as string)\n }\n reader.onerror = reject\n reader.readAsDataURL(blob)\n })\n}\n\ntype StlObj = { stlUrl: string; color: number[] }\n\nexport const useStlsFromGeom = (\n geom: Geom3[] | Geom3 | null,\n): {\n stls: StlObj[]\n loading: boolean\n} => {\n const [stls, setStls] = useState<StlObj[]>([])\n const [loading, setLoading] = useState(true)\n\n useEffect(() => {\n if (!geom) return\n const generateStls = async () => {\n setLoading(true)\n const geometries = Array.isArray(geom) ? geom : [geom]\n\n const stlPromises = geometries.map(async (g) => {\n const rawData = stlSerializer.serialize({ binary: true }, [g])\n const blobData = new Blob(rawData)\n const stlUrl = await blobToBase64Url(blobData)\n return { stlUrl, color: g.color! }\n })\n\n try {\n const generatedStls = await Promise.all(stlPromises)\n setStls(generatedStls)\n } catch (error) {\n console.error(\"Error generating STLs:\", error)\n setStls([])\n } finally {\n setLoading(false)\n }\n }\n\n generateStls()\n }, [geom])\n\n return { stls, loading }\n}\n","import { useLoader } from \"@react-three/fiber\"\nimport { useRef } from \"react\"\nimport * as THREE from \"three\"\nimport { MTLLoader, OBJLoader, STLLoader } from \"three-stdlib\"\n\nexport function STLModel({\n stlUrl,\n mtlUrl,\n color,\n opacity = 1,\n}: {\n stlUrl: string\n color?: any\n mtlUrl?: string\n opacity?: number\n}) {\n const geom = useLoader(STLLoader, stlUrl)\n const mesh = useRef<THREE.Mesh>()\n\n // TODO handle mtl url\n\n return (\n <mesh ref={mesh as any}>\n <primitive object={geom} attach=\"geometry\" />\n <meshStandardMaterial\n color={color}\n transparent={opacity !== 1}\n opacity={opacity}\n />\n {/* <Outlines thickness={0.05} color=\"black\" opacity={0.25} /> */}\n </mesh>\n )\n}\n","import { Grid, OrbitControls } from \"@react-three/drei\"\nimport { Canvas, useFrame } from \"@react-three/fiber\"\nimport packageJson from \"../package.json\"\nimport { CubeWithLabeledSides } from \"./three-components/cube-with-labeled-sides\"\n\nexport const RotationTracker = () => {\n useFrame(({ camera }) => {\n window.TSCI_MAIN_CAMERA_ROTATION = camera.rotation\n })\n\n return <></>\n}\n\nimport { Html } from \"@react-three/drei\"\n\nexport const CadViewerContainer = ({\n children,\n hoveredComponent,\n}: {\n children: any\n hoveredComponent: {\n cad_component_id: string\n name: string\n mousePosition: [number, number, number]\n } | null\n}) => {\n return (\n <div style={{ position: \"relative\", width: \"100%\", height: \"100%\" }}>\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: 120,\n height: 120,\n }}\n >\n <Canvas\n camera={{\n up: [0, 0, 1],\n position: [1, 1, 1],\n }}\n style={{ zIndex: 10 }}\n >\n <ambientLight intensity={Math.PI / 2} />\n <CubeWithLabeledSides />\n </Canvas>\n </div>\n <Canvas\n scene={{ up: [0, 0, 1] }}\n camera={{ up: [0, 0, 1], position: [5, 5, 5] }}\n >\n <RotationTracker />\n <OrbitControls autoRotate autoRotateSpeed={1} />\n <ambientLight intensity={Math.PI / 2} />\n <pointLight\n position={[-10, -10, 10]}\n decay={0}\n intensity={Math.PI / 4}\n />\n <Grid\n rotation={[Math.PI / 2, 0, 0]}\n infiniteGrid={true}\n cellSize={1}\n sectionSize={10}\n />\n {children}\n {hoveredComponent && (\n <Html\n position={hoveredComponent.mousePosition}\n style={{\n fontFamily: \"sans-serif\",\n transform: \"translate3d(50%, 50%, 0)\",\n backgroundColor: \"white\",\n padding: \"5px\",\n borderRadius: \"3px\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n WebkitUserSelect: \"none\",\n MozUserSelect: \"none\",\n msUserSelect: \"none\",\n }}\n >\n {hoveredComponent.name}\n </Html>\n )}\n </Canvas>\n <div\n style={{\n position: \"absolute\",\n right: 24,\n bottom: 24,\n fontFamily: \"sans-serif\",\n color: \"white\",\n WebkitTextStroke: \"0.5px rgba(0, 0, 0, 0.5)\",\n fontSize: 11,\n }}\n >\n @{packageJson.version}\n </div>\n </div>\n )\n}\n","{\n \"name\": \"@tscircuit/3d-viewer\",\n \"version\": \"0.0.79\",\n \"main\": \"./dist/index.js\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"start\": \"bun run storybook\",\n \"dev:old\": \"bunx --bun vite\",\n \"build\": \"tsup ./src/index.tsx --dts --sourcemap\",\n \"prepublish\": \"npm run build\",\n \"preview\": \"vite preview\",\n \"storybook\": \"storybook dev -p 6006\",\n \"build-storybook\": \"storybook build\",\n \"vercel-build\": \"bun run build-storybook\",\n \"format\": \"biome format . --write\",\n \"format:check\": \"biome format .\"\n },\n \"dependencies\": {\n \"@jscad/modeling\": \"^2.12.2\",\n \"@jscad/regl-renderer\": \"^2.6.9\",\n \"@jscad/stl-serializer\": \"^2.1.17\",\n \"@react-three/drei\": \"^9.115.0\",\n \"@react-three/fiber\": \"^8.16.8\",\n \"@tscircuit/core\": \"^0.0.251\",\n \"@tscircuit/props\": \"^0.0.124\",\n \"@tscircuit/react-fiber\": \"^1.1.29\",\n \"@tscircuit/soup\": \"^0.0.69\",\n \"@tscircuit/soup-util\": \"^0.0.26\",\n \"@types/three\": \"^0.165.0\",\n \"jscad-electronics\": \"^0.0.23\",\n \"jscad-fiber\": \"^0.0.76\",\n \"jscad-planner\": \"^0.0.11\",\n \"react\": \"^18.3.1\",\n \"react-dom\": \"^18.3.1\",\n \"react-use-gesture\": \"^9.1.3\",\n \"three\": \"^0.165.0\",\n \"three-stdlib\": \"^2.30.3\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^1.8.3\",\n \"@chromatic-com/storybook\": \"^1.5.0\",\n \"@storybook/addon-essentials\": \"^8.1.10\",\n \"@storybook/addon-interactions\": \"^8.1.10\",\n \"@storybook/addon-links\": \"^8.1.10\",\n \"@storybook/addon-onboarding\": \"^8.1.10\",\n \"@storybook/blocks\": \"^8.1.10\",\n \"@storybook/builder-vite\": \"^8.1.10\",\n \"@storybook/react\": \"^8.1.10\",\n \"@storybook/react-vite\": \"^8.1.10\",\n \"@storybook/test\": \"^8.1.10\",\n \"@types/react\": \"^18.3.3\",\n \"@types/react-dom\": \"^18.3.0\",\n \"@vitejs/plugin-react\": \"^4.3.1\",\n \"circuit-json\": \"^0.0.116\",\n \"circuit-to-svg\": \"^0.0.91\",\n \"storybook\": \"^8.1.10\",\n \"strip-ansi\": \"^7.1.0\",\n \"tsup\": \"^8.1.0\",\n \"typescript\": \"^5.5.3\",\n \"vite\": \"^5.3.1\",\n \"vite-tsconfig-paths\": \"^4.3.2\"\n }\n}\n","import { Text } from \"@react-three/drei\"\nimport { useFrame } from \"@react-three/fiber\"\nimport { useRef } from \"react\"\nimport * as THREE from \"three\"\n\ndeclare global {\n interface Window {\n TSCI_MAIN_CAMERA_ROTATION: THREE.Euler\n }\n}\nif (typeof window !== \"undefined\") {\n window.TSCI_MAIN_CAMERA_ROTATION = new THREE.Euler(0, 0, 0)\n}\n\nfunction computePointInFront(rotationVector, distance) {\n // Create a quaternion from the rotation vector\n const quaternion = new THREE.Quaternion().setFromEuler(\n new THREE.Euler(rotationVector.x, rotationVector.y, rotationVector.z),\n )\n\n // Create a vector pointing forward (along the negative z-axis)\n const forwardVector = new THREE.Vector3(0, 0, 1)\n\n // Apply the rotation to the forward vector\n forwardVector.applyQuaternion(quaternion)\n\n // Scale the rotated vector by the distance\n const result = forwardVector.multiplyScalar(distance)\n\n return result\n}\n\nexport const CubeWithLabeledSides = ({}: any) => {\n const ref = useRef<THREE.Mesh>()\n const rotationTrackingRef = useRef({ lastRotation: new THREE.Euler() })\n useFrame((state, delta) => {\n if (!ref.current) return\n\n const mainRot = window.TSCI_MAIN_CAMERA_ROTATION\n\n // Use window.TSCI_CAMERA_ROTATION to compute the position of the camera\n const cameraPosition = computePointInFront(mainRot, 2)\n\n state.camera.position.copy(cameraPosition)\n state.camera.lookAt(0, 0, 0)\n })\n return (\n <mesh ref={ref as any} rotation={[Math.PI / 2, 0, 0]}>\n <boxGeometry args={[1, 1, 1]} />\n <meshStandardMaterial color=\"white\" />\n <Text position={[0, 0, 0.51]} fontSize={0.25} color=\"black\">\n Front\n </Text>\n <Text\n position={[0, 0, -0.51]}\n fontSize={0.25}\n color=\"black\"\n rotation={[0, Math.PI, 0]}\n >\n Back\n </Text>\n <Text\n position={[0.51, 0, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[0, Math.PI / 2, 0]}\n >\n Right\n </Text>\n <Text\n position={[-0.51, 0, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[0, -Math.PI / 2, 0]}\n >\n Left\n </Text>\n <Text\n position={[0, 0.51, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[-Math.PI / 2, 0, 0]}\n >\n Top\n </Text>\n <Text\n position={[0, -0.51, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[Math.PI / 2, 0, 0]}\n >\n Bottom\n </Text>\n <lineSegments\n args={[new THREE.EdgesGeometry(new THREE.BoxGeometry(1, 1, 1))]}\n material={\n new THREE.LineBasicMaterial({\n color: 0x000000,\n linewidth: 2,\n })\n }\n />\n </mesh>\n )\n}\n","import { Html } from \"@react-three/drei\"\nimport { GroupProps, useThree } from \"@react-three/fiber\"\nimport { useRef, useCallback } from \"react\"\nimport type { Vector3 } from \"three\"\nimport * as THREE from \"three\"\n\nconst Group = (props: GroupProps) => <group {...props} />\n\nconst ContainerWithTooltip = ({\n children,\n isHovered,\n onHover,\n position,\n}: {\n children: React.ReactNode\n position?: Vector3 | [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) => {\n const lastValidPointRef = useRef<THREE.Vector3 | null>(null)\n\n const handlePointerEnter = useCallback(\n (e: any) => {\n e.stopPropagation()\n\n try {\n // Fallback to event position if raycaster fails\n const point =\n e.point ||\n (e.intersections && e.intersections.length > 0\n ? e.intersections[0].point\n : null) ||\n (position\n ? new THREE.Vector3(...(position as [number, number, number]))\n : null)\n\n if (point) {\n lastValidPointRef.current = point\n onHover({ mousePosition: [point.x, point.y, point.z] })\n } else {\n onHover({})\n }\n } catch (error) {\n console.warn(\"Hover event error:\", error)\n onHover({})\n }\n },\n [position],\n )\n\n const handlePointerLeave = useCallback(\n (e: any) => {\n e.stopPropagation()\n lastValidPointRef.current = null\n\n // TODO REPLACE WITH onUnhover\n onHover(null)\n },\n [onHover],\n )\n\n return (\n <Group\n onPointerEnter={handlePointerEnter}\n onPointerMove={handlePointerEnter}\n onPointerLeave={handlePointerLeave}\n >\n {children}\n </Group>\n )\n}\n\nexport default ContainerWithTooltip\n","import { useState, useEffect } from \"react\"\nimport type { Group } from \"three\"\nimport { MTLLoader, OBJLoader } from \"three-stdlib\"\n\n// Define the type for our cache\ninterface CacheItem {\n promise: Promise<any>\n result: Group | null\n}\n\ndeclare global {\n interface Window {\n TSCIRCUIT_OBJ_LOADER_CACHE: Map<string, CacheItem>\n }\n}\n\n// Ensure the global cache exists\nif (typeof window !== \"undefined\" && !window.TSCIRCUIT_OBJ_LOADER_CACHE) {\n window.TSCIRCUIT_OBJ_LOADER_CACHE = new Map<string, CacheItem>()\n}\n\nexport function useGlobalObjLoader(url: string | null): Group | null | Error {\n const [obj, setObj] = useState<Group | null | Error>(null)\n\n useEffect(() => {\n if (!url) return\n\n const cache = window.TSCIRCUIT_OBJ_LOADER_CACHE\n let hasUrlChanged = false\n\n async function loadAndParseObj() {\n try {\n const response = await fetch(url!)\n const text = await response.text()\n\n const mtlContent = text\n .match(/newmtl[\\s\\S]*?endmtl/g)\n ?.join(\"\\n\")!\n .replace(/d 0\\./g, \"d 1.\")!\n const objContent = text.replace(/newmtl[\\s\\S]*?endmtl/g, \"\")\n\n const mtlLoader = new MTLLoader()\n mtlLoader.setMaterialOptions({\n invertTrProperty: true,\n })\n const materials = mtlLoader.parse(\n mtlContent.replace(\n /Kd\\s+([\\d.]+)\\s+([\\d.]+)\\s+([\\d.]+)/g,\n \"Kd $2 $2 $2\",\n ),\n \"test.mtl\",\n )\n\n const objLoader = new OBJLoader()\n objLoader.setMaterials(materials)\n return objLoader.parse(objContent)\n } catch (error) {\n return error as Error\n }\n }\n\n function loadUrl() {\n if (cache.has(url!)) {\n const cacheItem = cache.get(url!)!\n if (cacheItem.result) {\n // If we have a result, clone it\n return Promise.resolve(cacheItem.result.clone())\n }\n // If we're still loading, return the existing promise\n return cacheItem.promise.then((result) => result.clone())\n }\n // If it's not in the cache, create a new promise and cache it\n const promise = loadAndParseObj().then((result) => {\n if (result instanceof Error) {\n // If the result is an Error, return it\n return result\n }\n cache.set(url!, { ...cache.get(url!)!, result })\n return result\n })\n cache.set(url!, { promise, result: null })\n return promise\n }\n\n loadUrl()\n .then((result) => {\n if (hasUrlChanged) return\n setObj(result)\n })\n .catch((error) => {\n console.error(error)\n })\n\n return () => {\n hasUrlChanged = true\n }\n }, [url])\n\n return obj\n}\n","import ContainerWithTooltip from \"src/ContainerWithTooltip\"\nimport { useGlobalObjLoader } from \"src/hooks/use-global-obj-loader\"\nimport type { Euler, Vector3 } from \"three\"\n\nexport function MixedStlModel({\n url,\n position,\n rotation,\n onHover,\n isHovered,\n}: {\n url: string\n position?: Vector3 | [number, number, number]\n rotation?: Euler | [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) {\n const obj = useGlobalObjLoader(url)\n\n if (!obj) {\n return (\n <ContainerWithTooltip isHovered={isHovered} onHover={onHover}>\n <mesh position={position}>\n <boxGeometry args={[0.5, 0.5, 0.5]} />\n <meshStandardMaterial transparent color=\"red\" opacity={0.25} />\n </mesh>\n </ContainerWithTooltip>\n )\n }\n\n // Check if obj is valid before rendering\n if (obj instanceof Error) {\n return (\n <ContainerWithTooltip isHovered={isHovered} onHover={onHover}>\n <mesh position={position}>\n <boxGeometry args={[0.5, 0.5, 0.5]} />\n <meshStandardMaterial transparent color=\"red\" opacity={0.5} />\n <meshBasicMaterial color=\"red\" />\n </mesh>\n </ContainerWithTooltip>\n )\n }\n return (\n <ContainerWithTooltip isHovered={isHovered} onHover={onHover}>\n <primitive rotation={rotation} position={position} object={obj} />\n </ContainerWithTooltip>\n )\n}\n","import type { JscadOperation } from \"jscad-planner\"\nimport { executeJscadOperations } from \"jscad-planner\"\nimport jscad from \"@jscad/modeling\"\nimport { convertCSGToThreeGeom } from \"jscad-fiber\"\nimport * as THREE from \"three\"\nimport { useMemo } from \"react\"\nimport ContainerWithTooltip from \"src/ContainerWithTooltip\"\n\nexport const JscadModel = ({\n jscadPlan,\n positionOffset,\n rotationOffset,\n onHover,\n isHovered,\n}: {\n jscadPlan: JscadOperation\n positionOffset?: [number, number, number]\n rotationOffset?: [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) => {\n const { threeGeom, material } = useMemo(() => {\n const jscadObject = executeJscadOperations(jscad as any, jscadPlan)\n\n const threeGeom = convertCSGToThreeGeom(jscadObject)\n\n const material = new THREE.MeshStandardMaterial({\n vertexColors: true,\n side: THREE.DoubleSide, // Ensure both sides are visible\n })\n return { threeGeom, material }\n }, [jscadPlan])\n\n useMemo(() => {\n if (isHovered) {\n const color = new THREE.Color(material.color.getHex())\n material.emissive.copy(color)\n material.emissive.setRGB(0, 0, 1)\n material.emissiveIntensity = 0.2\n } else {\n material.emissiveIntensity = 0\n }\n }, [isHovered, material])\n if (!threeGeom) return null\n\n return (\n <ContainerWithTooltip\n isHovered={isHovered}\n onHover={onHover}\n position={positionOffset}\n >\n <mesh\n geometry={threeGeom}\n material={material}\n position={positionOffset}\n rotation={rotationOffset}\n />\n </ContainerWithTooltip>\n )\n}\n","import { Footprinter3d } from \"jscad-electronics\"\nimport { createJSCADRenderer } from \"jscad-fiber\"\nimport { jscadPlanner } from \"jscad-planner\"\nimport { useMemo } from \"react\"\nimport { JscadModel } from \"./JscadModel\"\n\nconst { createJSCADRoot } = createJSCADRenderer(jscadPlanner as any)\n\nexport const FootprinterModel = ({\n positionOffset,\n footprint,\n rotationOffset,\n onHover,\n isHovered,\n}: {\n positionOffset: any\n footprint: string\n rotationOffset?: [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) => {\n const jscadOperations = useMemo(() => {\n if (!footprint) return null\n const jscadOperations: any[] = []\n const root = createJSCADRoot(jscadOperations)\n root.render(<Footprinter3d footprint={footprint} />)\n return jscadOperations\n }, [footprint])\n\n if (!jscadOperations) return null\n\n return (\n <>\n {jscadOperations.map((operation, index) => (\n <JscadModel\n // biome-ignore lint/suspicious/noArrayIndexKey: <explanation>\n key={index}\n positionOffset={positionOffset}\n rotationOffset={rotationOffset}\n jscadPlan={operation}\n onHover={onHover}\n isHovered={isHovered}\n />\n ))}\n </>\n )\n}\n","export const tuple = <T extends any[]>(...args: T): T => args\n","import type { AnyCircuitElement, CadComponent } from \"circuit-json\"\nimport { useConvertChildrenToSoup } from \"./hooks/use-convert-children-to-soup\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { useMemo, useState } from \"react\"\nimport { createBoardGeomFromSoup } from \"./soup-to-3d\"\nimport { useStlsFromGeom } from \"./hooks/use-stls-from-geom\"\nimport { STLModel } from \"./three-components/STLModel\"\nimport { CadViewerContainer } from \"./CadViewerContainer\"\nimport { MixedStlModel } from \"./three-components/MixedStlModel\"\nimport { Euler } from \"three\"\nimport { JscadModel } from \"./three-components/JscadModel\"\nimport { Footprinter3d } from \"jscad-electronics\"\nimport { FootprinterModel } from \"./three-components/FootprinterModel\"\nimport { tuple } from \"./utils/tuple\"\n\nexport const AnyCadComponent = ({\n cad_component,\n onHover = () => {},\n isHovered = false,\n}: {\n cad_component: CadComponent\n onHover?: (e: any) => void\n isHovered?: boolean\n}) => {\n const url = cad_component.model_obj_url ?? cad_component.model_stl_url\n const rotationOffset = cad_component.rotation\n ? tuple(\n (cad_component.rotation.x * Math.PI) / 180,\n (cad_component.rotation.y * Math.PI) / 180,\n (cad_component.rotation.z * Math.PI) / 180,\n )\n : undefined\n\n if (url) {\n return (\n <MixedStlModel\n key={cad_component.cad_component_id}\n url={url}\n position={\n cad_component.position\n ? [\n cad_component.position.x,\n cad_component.position.y,\n cad_component.position.z,\n ]\n : undefined\n }\n rotation={rotationOffset}\n onHover={onHover}\n isHovered={isHovered}\n />\n )\n }\n\n if (cad_component.model_jscad) {\n return (\n <JscadModel\n key={cad_component.cad_component_id}\n jscadPlan={cad_component.model_jscad as any}\n rotationOffset={rotationOffset}\n onHover={onHover}\n isHovered={isHovered}\n />\n )\n }\n\n if (cad_component.footprinter_string) {\n return (\n <FootprinterModel\n positionOffset={\n cad_component.position\n ? [\n cad_component.position.x,\n cad_component.position.y,\n cad_component.position.z,\n ]\n : undefined\n }\n rotationOffset={rotationOffset}\n footprint={cad_component.footprinter_string}\n onHover={onHover}\n isHovered={isHovered}\n />\n )\n }\n}\n","import React from \"react\"\n\ninterface Props {\n children: React.ReactNode\n fallback: (props: { error: Error }) => any\n}\n\ninterface State {\n hasError: boolean\n error: Error | null\n}\n\nexport class ThreeErrorBoundary extends React.Component<Props, State> {\n constructor(props: Props) {\n super(props)\n this.state = { hasError: false, error: null }\n }\n\n static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error }\n }\n\n override render() {\n if (this.state.hasError && this.state.error) {\n return this.props.fallback({ error: this.state.error })\n }\n\n return this.props.children\n }\n}\n","import { Text } from \"@react-three/drei\"\nimport type { CadComponent } from \"circuit-json\"\n\nexport const Error3d = ({\n error,\n cad_component,\n}: { error: any; cad_component?: CadComponent }) => {\n let position = [0, 0, 0]\n if (cad_component?.position) {\n position = [\n cad_component.position.x,\n cad_component.position.y,\n cad_component.position.z,\n ]\n // make sure the position doesn't have any NaN values\n position = position.map((p) => (Number.isNaN(p) ? 0 : p))\n }\n return (\n <group\n // @ts-expect-error\n position={position}\n >\n <mesh\n renderOrder={-99999}\n rotation={[Math.PI / 4, Math.PI / 4, 0]}\n ref={(mesh) => {\n if (mesh) {\n mesh.renderOrder = 999999\n }\n }}\n >\n <boxGeometry args={[0.5, 0.5, 0.5]} />\n <meshStandardMaterial\n depthTest={false}\n transparent\n color=\"red\"\n opacity={0.5}\n />\n </mesh>\n <Text\n scale={[0.1, 0.1, 0.1]}\n color=\"red\" // default\n anchorX=\"center\" // default\n anchorY=\"middle\" // default\n depthOffset={-99999}\n >\n {error.toString().slice(0, 50)}...\n </Text>\n </group>\n ) as any\n}\n"],"mappings":"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","names":["import_soup_util","import_react","import_transforms","import_primitives","import_colors","import_booleans","import_extrusions","import_primitives","import_react","stlSerializer","import_react","import_drei","import_fiber","import_fiber","import_react","import_jsx_runtime","import_drei","import_jsx_runtime","import_react","THREE","import_jsx_runtime","import_react","import_three_stdlib","import_jsx_runtime","THREE","import_react","import_jsx_runtime","jscad","threeGeom","material","import_jscad_fiber","import_jscad_planner","import_react","import_jsx_runtime","jscadOperations","import_jsx_runtime","import_react","React","import_drei","import_jsx_runtime","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.tsx","../src/hooks/exporter/gltf.ts","../src/hooks/use-convert-children-to-soup.ts","../src/CadViewer.tsx","../src/soup-to-3d/index.ts","../src/geoms/plated-hole.ts","../src/geoms/constants.ts","../src/geoms/create-board-with-outline.ts","../src/geoms/create-geoms-for-silkscreen-text.ts","../src/hooks/use-stls-from-geom.ts","../src/three-components/STLModel.tsx","../src/CadViewerContainer.tsx","../package.json","../src/three-components/cube-with-labeled-sides.tsx","../src/ContainerWithTooltip.tsx","../src/hooks/use-global-obj-loader.ts","../src/three-components/MixedStlModel.tsx","../src/three-components/JscadModel.tsx","../src/three-components/FootprinterModel.tsx","../src/utils/tuple.ts","../src/AnyCadComponent.tsx","../src/three-components/ThreeErrorBoundary.tsx","../src/three-components/Error3d.tsx"],"sourcesContent":["export * from \"./hooks/index.ts\"\nexport { CadViewer } from \"./CadViewer.tsx\"\n","import type * as React from \"react\"\nimport type * as THREE from \"three\"\nimport { GLTFExporter, type GLTFExporterOptions } from \"three-stdlib\"\nimport { useEffect, useState, useMemo, useCallback } from \"react\"\n\ntype Options = Omit<\n GLTFExporterOptions,\n \"animations\" | \"includeCustomExtensions\"\n>\n\nexport function useSaveGltfAs(\n options = {} as Options & { filename?: string },\n): [\n ref3D: React.ForwardedRef<THREE.Object3D>,\n saveAs: (filename?: string) => Promise<void>,\n] {\n const parse = useParser(options)\n const link = useMemo(() => document.createElement(\"a\"), [])\n const saveAs = async (filename?: string) => {\n const name = filename ?? options.filename ?? \"\"\n if (options.binary == null) options.binary = name.endsWith(\".glb\")\n const url = await parse(instance!)\n link.download = name\n link.href = url\n link.dispatchEvent(new MouseEvent(\"click\"))\n URL.revokeObjectURL(url)\n }\n\n useEffect(\n () => () => {\n link.remove()\n instance = null\n },\n [],\n )\n\n let instance: THREE.Object3D | null\n const ref = useCallback((obj3D: THREE.Object3D | null) => {\n instance = obj3D!\n }, [])\n\n return [ref, saveAs]\n}\n\nexport function useExportGltfUrl(\n options = {} as Options,\n): [\n ref3D: React.ForwardedRef<THREE.Object3D>,\n url: string | undefined,\n error: ErrorEvent | undefined,\n] {\n const parse = useParser(options)\n const [url, setUrl] = useState<string>()\n const [error, setError] = useState<ErrorEvent>()\n const ref = useCallback(\n (instance: THREE.Object3D | null) =>\n parse(instance!).then(setUrl).catch(setError),\n [],\n )\n useEffect(() => () => URL.revokeObjectURL(url!), [url])\n return [ref, url, error]\n}\n\nfunction useParser(options = {} as Options) {\n const exporter = useMemo(() => new GLTFExporter(), [])\n return (instance: THREE.Object3D) => {\n const { promise, resolve, reject } = Promise.withResolvers<string>()\n exporter.parse(\n instance,\n (gltf) => {\n const type = options.binary ? \"gltf-binary\" : \"gltf+json\"\n const blob = new Blob(\n [gltf instanceof ArrayBuffer ? gltf : JSON.stringify(gltf)],\n { type: `model/${type}` },\n )\n resolve(URL.createObjectURL(blob))\n },\n reject,\n options,\n )\n return promise\n }\n}\n","import { Circuit } from \"@tscircuit/core\"\nimport { useMemo } from \"react\"\nimport type { AnyCircuitElement } from \"circuit-json\"\n\nexport const useConvertChildrenToSoup = (\n children?: any,\n defaultSoup?: AnyCircuitElement[],\n): AnyCircuitElement[] => {\n return useMemo(() => {\n if (!children) return\n const circuit = new Circuit()\n circuit.add(children)\n circuit.render()\n return circuit.getCircuitJson() as any\n }, [children])\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport type * as React from \"react\"\nimport type * as THREE from \"three\"\nimport { useConvertChildrenToSoup } from \"./hooks/use-convert-children-to-soup\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { useEffect, useMemo, useState, forwardRef } from \"react\"\nimport { createBoardGeomFromSoup } from \"./soup-to-3d\"\nimport { useStlsFromGeom } from \"./hooks/use-stls-from-geom\"\nimport { STLModel } from \"./three-components/STLModel\"\nimport { CadViewerContainer } from \"./CadViewerContainer\"\nimport { MixedStlModel } from \"./three-components/MixedStlModel\"\nimport { Euler } from \"three\"\nimport { JscadModel } from \"./three-components/JscadModel\"\nimport { Footprinter3d } from \"jscad-electronics\"\nimport { FootprinterModel } from \"./three-components/FootprinterModel\"\nimport { tuple } from \"./utils/tuple\"\nimport { AnyCadComponent } from \"./AnyCadComponent\"\nimport { Text } from \"@react-three/drei\"\nimport { ThreeErrorBoundary } from \"./three-components/ThreeErrorBoundary\"\nimport { Error3d } from \"./three-components/Error3d\"\n\ninterface Props {\n soup?: AnySoupElement[]\n}\n\nexport const CadViewer = forwardRef<\n THREE.Object3D,\n React.PropsWithChildren<Props>\n>(({ soup, children }, ref) => {\n const [hoveredComponent, setHoveredComponent] = useState<null | {\n cad_component_id: string\n name: string\n mousePosition: [number, number, number]\n }>(null)\n soup ??= useConvertChildrenToSoup(children, soup) as any\n\n if (!soup) return null\n\n const boardGeom = useMemo(() => {\n if (!soup.some((e) => e.type === \"pcb_board\")) return null\n return createBoardGeomFromSoup(soup)\n }, [soup])\n\n const { stls: boardStls, loading } = useStlsFromGeom(boardGeom)\n\n const cad_components = su(soup).cad_component.list()\n\n return (\n <CadViewerContainer ref={ref} hoveredComponent={hoveredComponent}>\n {boardStls.map(({ stlUrl, color }, index) => (\n <STLModel\n key={stlUrl}\n stlUrl={stlUrl}\n color={color}\n opacity={index === 0 ? 0.95 : 1}\n />\n ))}\n {cad_components.map((cad_component) => (\n <ThreeErrorBoundary\n key={cad_component.cad_component_id}\n fallback={({ error }) => (\n <Error3d cad_component={cad_component} error={error} />\n )}\n >\n <AnyCadComponent\n key={cad_component.cad_component_id}\n onHover={(e) => {\n // TODO this should be done by onUnhover\n if (!e) {\n setHoveredComponent(null)\n }\n if (!e.mousePosition) return\n\n const componentName = su(soup as any).source_component.getUsing({\n source_component_id: cad_component.source_component_id,\n })?.name\n setHoveredComponent({\n cad_component_id: cad_component.cad_component_id,\n name: componentName ?? \"<unknown>\",\n mousePosition: e.mousePosition,\n })\n }}\n cad_component={cad_component}\n isHovered={\n hoveredComponent?.cad_component_id ===\n cad_component.cad_component_id\n }\n />\n </ThreeErrorBoundary>\n ))}\n </CadViewerContainer>\n )\n})\n","import type { Geom3 } from \"@jscad/modeling/src/geometries/types\"\nimport type { AnySoupElement, PCBPlatedHole } from \"@tscircuit/soup\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { translate } from \"@jscad/modeling/src/operations/transforms\"\nimport { cuboid, cylinder, line } from \"@jscad/modeling/src/primitives\"\nimport { colorize } from \"@jscad/modeling/src/colors\"\nimport { subtract, union } from \"@jscad/modeling/src/operations/booleans\"\nimport { platedHole } from \"../geoms/plated-hole\"\nimport { M, colors } from \"../geoms/constants\"\nimport { extrudeLinear } from \"@jscad/modeling/src/operations/extrusions\"\nimport { expand } from \"@jscad/modeling/src/operations/expansions\"\nimport { createBoardWithOutline } from \"src/geoms/create-board-with-outline\"\nimport { Vec2 } from \"@jscad/modeling/src/maths/types\"\nimport { createSilkscreenTextGeoms } from \"src/geoms/create-geoms-for-silkscreen-text\"\nimport { PcbSilkscreenText } from \"circuit-json\"\nexport const createBoardGeomFromSoup = (soup: AnySoupElement[]): Geom3[] => {\n const board = su(soup).pcb_board.list()[0]\n if (!board) {\n throw new Error(\"No pcb_board found\")\n }\n const plated_holes = su(soup).pcb_plated_hole.list()\n const holes = su(soup).pcb_hole.list()\n const pads = su(soup).pcb_smtpad.list()\n const traces = su(soup).pcb_trace.list()\n const pcb_vias = su(soup).pcb_via.list()\n const silkscreenTexts = su(soup).pcb_silkscreen_text.list()\n\n // PCB Board\n let boardGeom: Geom3\n if (board.outline && board.outline.length > 0)\n boardGeom = createBoardWithOutline(board.outline, 1.2)\n else boardGeom = cuboid({ size: [board.width, board.height, 1.2] })\n\n const platedHoleGeoms: Geom3[] = []\n const holeGeoms: Geom3[] = []\n const padGeoms: Geom3[] = []\n const traceGeoms: Geom3[] = []\n const ctx = {\n pcbThickness: 1.2,\n }\n\n const addPlatedHole = (plated_hole: PCBPlatedHole) => {\n if (plated_hole.shape === \"circle\") {\n const cyGeom = cylinder({\n center: [plated_hole.x, plated_hole.y, 0],\n radius: plated_hole.hole_diameter / 2 + M,\n })\n\n boardGeom = subtract(boardGeom, cyGeom)\n\n const platedHoleGeom = platedHole(plated_hole, ctx)\n platedHoleGeoms.push(platedHoleGeom)\n } else if (plated_hole.shape === \"pill\") {\n const shouldRotate = plated_hole.hole_height! > plated_hole.hole_width!\n\n const holeWidth = shouldRotate\n ? plated_hole.hole_height!\n : plated_hole.hole_width!\n const holeHeight = shouldRotate\n ? plated_hole.hole_width!\n : plated_hole.hole_height!\n\n const holeRadius = holeHeight / 2\n const rectLength = Math.abs(holeWidth - holeHeight)\n\n const pillHole = union(\n cuboid({\n center: [plated_hole.x, plated_hole.y, 0],\n size: shouldRotate\n ? [holeHeight, rectLength, 1.5]\n : [rectLength, holeHeight, 1.5],\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 0]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.5,\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 0]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.5,\n }),\n )\n boardGeom = subtract(boardGeom, pillHole)\n\n const platedHoleGeom = platedHole(plated_hole, ctx)\n platedHoleGeoms.push(platedHoleGeom)\n }\n }\n\n for (const plated_hole of plated_holes) {\n addPlatedHole(plated_hole)\n }\n\n for (const hole of holes) {\n // @ts-expect-error\n if (hole.hole_shape === \"round\" || hole.hole_shape === \"circle\") {\n const cyGeom = cylinder({\n center: [hole.x, hole.y, 0],\n radius: hole.hole_diameter / 2 + M,\n })\n boardGeom = subtract(boardGeom, cyGeom)\n }\n }\n\n for (const pad of pads) {\n const layerSign = pad.layer === \"bottom\" ? -1 : 1\n if (pad.shape === \"rect\") {\n const padGeom = colorize(\n colors.copper,\n cuboid({\n center: [pad.x, pad.y, (layerSign * 1.2) / 2 + layerSign * M],\n size: [pad.width, pad.height, M],\n }),\n )\n padGeoms.push(padGeom)\n } else if (pad.shape === \"circle\") {\n const padGeom = colorize(\n colors.copper,\n cylinder({\n center: [pad.x, pad.y, (layerSign * 1.2) / 2 + layerSign * M],\n radius: pad.radius,\n height: M,\n }),\n )\n padGeoms.push(padGeom)\n }\n }\n\n for (const { route: mixedRoute } of traces) {\n if (mixedRoute.length < 2) continue\n\n // Group routes by continuous segments\n const routeSegments: (typeof mixedRoute)[] = []\n let currentSegment: typeof mixedRoute = [mixedRoute[0]!]\n let currentLayer =\n mixedRoute[0]!.route_type === \"wire\" ? mixedRoute[0]!.layer : \"top\"\n\n for (let i = 1; i < mixedRoute.length; i++) {\n const point = mixedRoute[i]!\n\n if (point.route_type === \"via\") {\n // Complete current segment and start a new one\n routeSegments.push(currentSegment)\n currentSegment = [point]\n } else if (point.route_type === \"wire\" && point.layer !== currentLayer) {\n // Complete current segment and start a new one on a different layer\n routeSegments.push(currentSegment)\n currentLayer = point.layer\n currentSegment = [point]\n } else {\n currentSegment.push(point)\n }\n }\n\n // Add the last segment\n routeSegments.push(currentSegment)\n\n // Render each route segment\n for (const route of routeSegments) {\n if (route.length < 2) continue\n\n const linePath = line(route.map((p) => [p.x, p.y]))\n const layerSign =\n route[0]!.route_type === \"via\"\n ? route[0]!.to_layer === \"top\"\n ? 1\n : -1\n : route[0]!.layer === \"top\"\n ? 1\n : -1\n\n let traceGeom = translate(\n [0, 0, (layerSign * 1.2) / 2],\n extrudeLinear(\n { height: M * layerSign },\n expand({ delta: 0.1, corners: \"edge\" }, linePath),\n ),\n )\n\n // Modify via subtraction to preserve trace geometry\n const viaSubtractions = pcb_vias.map((via) =>\n cylinder({\n center: [via.x, via.y, 0],\n radius: via.outer_diameter / 2,\n height: 5,\n }),\n )\n\n const holeSubtractions = plated_holes\n .filter((ph) => ph.shape === \"circle\")\n .map((ph) =>\n cylinder({\n center: [ph.x, ph.y, 0],\n radius: ph.outer_diameter / 2,\n height: 5,\n }),\n )\n\n // Subtract vias and holes without removing entire trace\n traceGeom = subtract(traceGeom, ...viaSubtractions, ...holeSubtractions)\n\n traceGeom = colorize(colors.fr4GreenSolderWithMask, traceGeom)\n\n traceGeoms.push(traceGeom)\n }\n }\n\n for (const via of pcb_vias) {\n addPlatedHole({\n x: via.x,\n y: via.y,\n hole_diameter: via.hole_diameter,\n outer_diameter: via.outer_diameter,\n shape: \"circle\",\n layers: [\"top\", \"bottom\"],\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: \"\",\n })\n }\n // Add silkscreen text\n const silkscreenGeoms: Geom3[] = []\n for (const silkscreenText of silkscreenTexts) {\n const { textOutlines, xOffset, yOffset } = createSilkscreenTextGeoms(\n silkscreenText as PcbSilkscreenText,\n )\n\n for (let outline of textOutlines) {\n // Create path from outline points with alignment offset\n\n const alignedOutline = outline.map((point) => [\n point[0] + xOffset + silkscreenText.anchor_position.x,\n point[1] + yOffset + silkscreenText.anchor_position.y,\n ]) as Vec2[]\n const textPath = line(alignedOutline)\n\n // Scale expansion delta with font size\n const fontSize = silkscreenText.font_size || 0.25\n const expansionDelta = Math.min(\n Math.max(0.01, fontSize * 0.1),\n fontSize * 0.2, // Maximum cap scales with font size\n )\n const expandedPath = expand(\n {\n delta: expansionDelta,\n corners: \"round\",\n },\n textPath,\n )\n\n // Extrude and position the text with smaller height\n let textGeom = translate(\n [0, 0, 0.6], // Position above board\n extrudeLinear(\n { height: 0.012 }, // Thinner extrusion\n expandedPath,\n ),\n )\n\n // Color white like silkscreen\n textGeom = colorize([256, 256, 256], textGeom)\n\n silkscreenGeoms.push(textGeom)\n }\n }\n\n // Colorize to a PCB green color: #05A32E\n boardGeom = colorize(colors.fr4Green, boardGeom)\n\n return [\n boardGeom,\n ...platedHoleGeoms,\n ...padGeoms,\n ...traceGeoms,\n ...silkscreenGeoms,\n ]\n}\n","import type { PCBPlatedHole } from \"@tscircuit/soup\"\nimport type { Geom3 } from \"@jscad/modeling/src/geometries/types\"\nimport { cuboid, cylinder } from \"@jscad/modeling/src/primitives\"\nimport { colorize } from \"@jscad/modeling/src/colors\"\nimport { subtract, union } from \"@jscad/modeling/src/operations/booleans\"\nimport { M, colors } from \"./constants\"\nimport type { GeomContext } from \"../GeomContext\"\n\nexport const platedHole = (\n plated_hole: PCBPlatedHole,\n ctx: GeomContext,\n): Geom3 => {\n if (!(plated_hole as PCBPlatedHole).shape) plated_hole.shape = \"circle\"\n if (plated_hole.shape === \"circle\") {\n return colorize(\n colors.copper,\n subtract(\n union(\n cylinder({\n center: [plated_hole.x, plated_hole.y, 0],\n radius: plated_hole.hole_diameter / 2,\n height: 1.2,\n }),\n cylinder({\n center: [plated_hole.x, plated_hole.y, 1.2 / 2],\n radius: plated_hole.outer_diameter / 2,\n height: M,\n }),\n cylinder({\n center: [plated_hole.x, plated_hole.y, -1.2 / 2],\n radius: plated_hole.outer_diameter / 2,\n height: M,\n }),\n ),\n cylinder({\n center: [plated_hole.x, plated_hole.y, 0],\n radius: plated_hole.hole_diameter / 2 - M,\n height: 1.5,\n }),\n ),\n )\n }\n if (plated_hole.shape === \"pill\") {\n const shouldRotate = plated_hole.hole_height! > plated_hole.hole_width!\n\n const holeWidth = shouldRotate\n ? plated_hole.hole_height!\n : plated_hole.hole_width!\n const holeHeight = shouldRotate\n ? plated_hole.hole_width!\n : plated_hole.hole_height!\n const outerHeight = shouldRotate\n ? plated_hole.outer_width || holeWidth + 0.2\n : plated_hole.outer_height || holeHeight + 0.2\n\n const holeRadius = holeHeight / 2\n const rectLength = Math.abs(holeWidth - holeHeight)\n\n const mainRect = cuboid({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y, 0]\n : [plated_hole.x, plated_hole.y, 0],\n size: shouldRotate\n ? [holeHeight, rectLength, 1.2]\n : [rectLength, holeHeight, 1.2],\n })\n\n const leftCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 0]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.2,\n })\n\n const rightCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 0]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.2,\n })\n\n const outerMainRect = cuboid({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y, 1.2 / 2]\n : [plated_hole.x, plated_hole.y, 1.2 / 2],\n size: shouldRotate\n ? [outerHeight, rectLength, M]\n : [rectLength, outerHeight, M],\n })\n\n const outerLeftCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 1.2 / 2]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n\n const outerRightCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 1.2 / 2]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n\n const bottomMainRect = cuboid({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y, -1.2 / 2]\n : [plated_hole.x, plated_hole.y, -1.2 / 2],\n size: shouldRotate\n ? [outerHeight, rectLength, M]\n : [rectLength, outerHeight, M],\n })\n\n const bottomLeftCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, -1.2 / 2]\n : [plated_hole.x - rectLength / 2, plated_hole.y, -1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n\n const bottomRightCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, -1.2 / 2]\n : [plated_hole.x + rectLength / 2, plated_hole.y, -1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n return colorize(\n colors.copper,\n subtract(\n union(\n mainRect,\n leftCap,\n rightCap,\n outerMainRect,\n outerLeftCap,\n outerRightCap,\n bottomMainRect,\n bottomLeftCap,\n bottomRightCap,\n ),\n union(\n cuboid({\n center: [plated_hole.x, plated_hole.y, 0],\n size: shouldRotate\n ? [holeHeight - M, rectLength, 1.5]\n : [rectLength, holeHeight - M, 1.5],\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 0]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 0],\n radius: holeRadius - M,\n height: 1.5,\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 0]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 0],\n radius: holeRadius - M,\n height: 1.5,\n }),\n ),\n ),\n )\n // biome-ignore lint/style/noUselessElse: <explanation>\n } else {\n throw new Error(`Unsupported plated hole shape: ${plated_hole.shape}`)\n }\n}\n","import type { RGB } from \"@jscad/modeling/src/colors\"\n\nexport const M = 0.01\n\nexport const colors = {\n copper: [0.9, 0.6, 0.2],\n fr4Green: [0x05 / 255, 0xa3 / 255, 0x2e / 255],\n fr4GreenSolderWithMask: [0x00 / 255, 0x98 / 255, 0x13 / 255],\n} satisfies Record<string, RGB>\n","import { extrudeLinear } from \"@jscad/modeling/src/operations/extrusions\"\nimport { polygon } from \"@jscad/modeling/src/primitives\"\nimport type { Geom2, Geom3 } from \"@jscad/modeling/src/geometries/types\"\nimport type { Vec2 } from \"@jscad/modeling/src/maths/types\"\nimport type { Point } from \"@tscircuit/soup\"\nimport { translate } from \"@jscad/modeling/src/operations/transforms\"\n\nconst arePointsClockwise = (points: Vec2[]): boolean => {\n let area = 0\n for (let i = 0; i < points.length; i++) {\n const j = (i + 1) % points.length\n area += points[i]![0] * points[j]![1]\n area -= points[j]![0] * points[i]![1]\n }\n const signedArea = area / 2\n return signedArea <= 0\n}\n\nexport const createBoardWithOutline = (points: Point[], depth = 1.2): Geom3 => {\n let outline: Vec2[] = points.map((point) => [point.x, point.y])\n\n if (arePointsClockwise(outline)) {\n outline = outline.reverse()\n }\n\n const shape: Geom2 = polygon({ points: outline })\n\n let board: Geom3 = extrudeLinear({ height: depth }, shape)\n\n board = translate([0, 0, -depth / 2], board)\n\n return board\n}\n","import { vectorText } from \"@jscad/modeling/src/text\"\nimport { PcbSilkscreenText } from \"circuit-json\"\n\n// Generate 2D text outlines\nexport function createSilkscreenTextGeoms(silkscreenText: PcbSilkscreenText) {\n // Generate 2D text outlines\n const textOutlines = vectorText({\n height: silkscreenText.font_size,\n input: silkscreenText.text,\n })\n // Split number 8 and small e into two parts to fix visual issues\n textOutlines.forEach((outline) => {\n if (outline.length === 29) {\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 1,\n outline.slice(0, 15),\n )\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 0,\n outline.slice(14, 29),\n )\n } else if (outline.length === 17) {\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 1,\n outline.slice(0, 10),\n )\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 0,\n outline.slice(9, 17),\n )\n }\n })\n // Calculate text bounds and center point\n const points = textOutlines.flatMap((o) => o)\n const textBounds = {\n minX: Math.min(...points.map((p) => p[0])),\n maxX: Math.max(...points.map((p) => p[0])),\n minY: Math.min(...points.map((p) => p[1])),\n maxY: Math.max(...points.map((p) => p[1])),\n }\n const centerX = (textBounds.minX + textBounds.maxX) / 2\n const centerY = (textBounds.minY + textBounds.maxY) / 2\n\n // Calculate offset based on anchor alignment\n let xOffset = -centerX\n let yOffset = -centerY\n\n // Adjust for specific alignments\n if (silkscreenText.anchor_alignment?.includes(\"right\")) {\n xOffset = -textBounds.maxX\n } else if (silkscreenText.anchor_alignment?.includes(\"left\")) {\n xOffset = -textBounds.minX\n }\n\n if (silkscreenText.anchor_alignment?.includes(\"top\")) {\n yOffset = -textBounds.maxY\n } else if (silkscreenText.anchor_alignment?.includes(\"bottom\")) {\n yOffset = -textBounds.minY\n }\n\n return { textOutlines, xOffset, yOffset }\n}\n","import { useState, useEffect } from \"react\"\nimport stlSerializer from \"@jscad/stl-serializer\"\nimport { Geom3 } from \"@jscad/modeling/src/geometries/types\"\n\nfunction blobToBase64Url(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => {\n resolve(reader.result as string)\n }\n reader.onerror = reject\n reader.readAsDataURL(blob)\n })\n}\n\ntype StlObj = { stlUrl: string; color: number[] }\n\nexport const useStlsFromGeom = (\n geom: Geom3[] | Geom3 | null,\n): {\n stls: StlObj[]\n loading: boolean\n} => {\n const [stls, setStls] = useState<StlObj[]>([])\n const [loading, setLoading] = useState(true)\n\n useEffect(() => {\n if (!geom) return\n const generateStls = async () => {\n setLoading(true)\n const geometries = Array.isArray(geom) ? geom : [geom]\n\n const stlPromises = geometries.map(async (g) => {\n const rawData = stlSerializer.serialize({ binary: true }, [g])\n const blobData = new Blob(rawData)\n const stlUrl = await blobToBase64Url(blobData)\n return { stlUrl, color: g.color! }\n })\n\n try {\n const generatedStls = await Promise.all(stlPromises)\n setStls(generatedStls)\n } catch (error) {\n console.error(\"Error generating STLs:\", error)\n setStls([])\n } finally {\n setLoading(false)\n }\n }\n\n generateStls()\n }, [geom])\n\n return { stls, loading }\n}\n","import { useLoader } from \"@react-three/fiber\"\nimport { useRef } from \"react\"\nimport * as THREE from \"three\"\nimport { MTLLoader, OBJLoader, STLLoader } from \"three-stdlib\"\n\nexport function STLModel({\n stlUrl,\n mtlUrl,\n color,\n opacity = 1,\n}: {\n stlUrl: string\n color?: any\n mtlUrl?: string\n opacity?: number\n}) {\n const geom = useLoader(STLLoader, stlUrl)\n const mesh = useRef<THREE.Mesh>()\n\n // TODO handle mtl url\n\n return (\n <mesh ref={mesh as any}>\n <primitive object={geom} attach=\"geometry\" />\n <meshStandardMaterial\n color={color}\n transparent={opacity !== 1}\n opacity={opacity}\n />\n {/* <Outlines thickness={0.05} color=\"black\" opacity={0.25} /> */}\n </mesh>\n )\n}\n","import type * as React from \"react\"\nimport type * as THREE from \"three\"\nimport { useHelper, Grid, OrbitControls } from \"@react-three/drei\"\nimport { Canvas, useFrame } from \"@react-three/fiber\"\nimport packageJson from \"../package.json\"\nimport { CubeWithLabeledSides } from \"./three-components/cube-with-labeled-sides\"\nimport { forwardRef, Suspense, useEffect, useRef } from \"react\"\n\nexport const RotationTracker = () => {\n useFrame(({ camera }) => {\n window.TSCI_MAIN_CAMERA_ROTATION = camera.rotation\n })\n\n return <></>\n}\n\nimport { Html } from \"@react-three/drei\"\n\ninterface Props {\n hoveredComponent: {\n cad_component_id: string\n name: string\n mousePosition: [number, number, number]\n } | null\n}\n\nexport const CadViewerContainer = forwardRef<\n THREE.Object3D,\n React.PropsWithChildren<Props>\n>(({ children, hoveredComponent }, ref) => {\n return (\n <div style={{ position: \"relative\", width: \"100%\", height: \"100%\" }}>\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: 120,\n height: 120,\n }}\n >\n <Canvas\n camera={{\n up: [0, 0, 1],\n position: [1, 1, 1],\n }}\n style={{ zIndex: 10 }}\n >\n <ambientLight intensity={Math.PI / 2} />\n <CubeWithLabeledSides />\n </Canvas>\n </div>\n <Canvas\n scene={{ up: [0, 0, 1] }}\n camera={{ up: [0, 0, 1], position: [5, 5, 5] }}\n >\n <RotationTracker />\n <OrbitControls autoRotate autoRotateSpeed={1} />\n <ambientLight intensity={Math.PI / 2} />\n <pointLight\n position={[-10, -10, 10]}\n decay={0}\n intensity={Math.PI / 4}\n />\n <Grid\n rotation={[Math.PI / 2, 0, 0]}\n infiniteGrid={true}\n cellSize={1}\n sectionSize={10}\n />\n <object3D ref={ref}>{children}</object3D>\n {hoveredComponent && (\n <Html\n position={hoveredComponent.mousePosition}\n style={{\n fontFamily: \"sans-serif\",\n transform: \"translate3d(50%, 50%, 0)\",\n backgroundColor: \"white\",\n padding: \"5px\",\n borderRadius: \"3px\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n WebkitUserSelect: \"none\",\n MozUserSelect: \"none\",\n msUserSelect: \"none\",\n }}\n >\n {hoveredComponent.name}\n </Html>\n )}\n </Canvas>\n <div\n style={{\n position: \"absolute\",\n right: 24,\n bottom: 24,\n fontFamily: \"sans-serif\",\n color: \"white\",\n WebkitTextStroke: \"0.5px rgba(0, 0, 0, 0.5)\",\n fontSize: 11,\n }}\n >\n @{packageJson.version}\n </div>\n </div>\n )\n})\n","{\n \"name\": \"@tscircuit/3d-viewer\",\n \"version\": \"0.0.81\",\n \"main\": \"./dist/index.js\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"start\": \"bun run storybook\",\n \"dev:old\": \"bunx --bun vite\",\n \"build\": \"tsup ./src/index.tsx --dts --sourcemap\",\n \"prepublish\": \"npm run build\",\n \"preview\": \"vite preview\",\n \"storybook\": \"storybook dev -p 6006\",\n \"build-storybook\": \"storybook build\",\n \"vercel-build\": \"bun run build-storybook\",\n \"format\": \"biome format . --write\",\n \"format:check\": \"biome format .\"\n },\n \"dependencies\": {\n \"@jscad/modeling\": \"^2.12.2\",\n \"@jscad/regl-renderer\": \"^2.6.9\",\n \"@jscad/stl-serializer\": \"^2.1.17\",\n \"@react-three/drei\": \"^9.115.0\",\n \"@react-three/fiber\": \"^8.16.8\",\n \"@tscircuit/core\": \"^0.0.251\",\n \"@tscircuit/props\": \"^0.0.125\",\n \"@tscircuit/react-fiber\": \"^1.1.29\",\n \"@tscircuit/soup\": \"^0.0.69\",\n \"@tscircuit/soup-util\": \"^0.0.26\",\n \"@types/three\": \"^0.165.0\",\n \"jscad-electronics\": \"^0.0.23\",\n \"jscad-fiber\": \"^0.0.76\",\n \"jscad-planner\": \"^0.0.11\",\n \"react\": \"^18.3.1\",\n \"react-dom\": \"^18.3.1\",\n \"react-use-gesture\": \"^9.1.3\",\n \"three\": \"^0.165.0\",\n \"three-stdlib\": \"^2.30.3\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^1.8.3\",\n \"@chromatic-com/storybook\": \"^1.5.0\",\n \"@storybook/addon-essentials\": \"^8.4.7\",\n \"@storybook/addon-interactions\": \"^8.4.7\",\n \"@storybook/addon-links\": \"^8.4.7\",\n \"@storybook/addon-onboarding\": \"^8.4.7\",\n \"@storybook/blocks\": \"^8.4.7\",\n \"@storybook/builder-vite\": \"^8.4.7\",\n \"@storybook/react\": \"^8.4.7\",\n \"@storybook/react-vite\": \"^8.4.7\",\n \"@storybook/test\": \"^8.4.7\",\n \"@types/react\": \"^18.3.3\",\n \"@types/react-dom\": \"^18.3.0\",\n \"@vitejs/plugin-react\": \"^4.3.4\",\n \"circuit-json\": \"^0.0.116\",\n \"circuit-to-svg\": \"^0.0.91\",\n \"storybook\": \"^8.4.7\",\n \"strip-ansi\": \"^7.1.0\",\n \"tsup\": \"^8.1.0\",\n \"typescript\": \"^5.7.2\",\n \"vite\": \"^5.4.11\",\n \"vite-tsconfig-paths\": \"^4.3.2\"\n }\n}\n","import { Text } from \"@react-three/drei\"\nimport { useFrame } from \"@react-three/fiber\"\nimport { useRef } from \"react\"\nimport * as THREE from \"three\"\n\ndeclare global {\n interface Window {\n TSCI_MAIN_CAMERA_ROTATION: THREE.Euler\n }\n}\nif (typeof window !== \"undefined\") {\n window.TSCI_MAIN_CAMERA_ROTATION = new THREE.Euler(0, 0, 0)\n}\n\nfunction computePointInFront(rotationVector, distance) {\n // Create a quaternion from the rotation vector\n const quaternion = new THREE.Quaternion().setFromEuler(\n new THREE.Euler(rotationVector.x, rotationVector.y, rotationVector.z),\n )\n\n // Create a vector pointing forward (along the negative z-axis)\n const forwardVector = new THREE.Vector3(0, 0, 1)\n\n // Apply the rotation to the forward vector\n forwardVector.applyQuaternion(quaternion)\n\n // Scale the rotated vector by the distance\n const result = forwardVector.multiplyScalar(distance)\n\n return result\n}\n\nexport const CubeWithLabeledSides = ({}: any) => {\n const ref = useRef<THREE.Mesh>()\n const rotationTrackingRef = useRef({ lastRotation: new THREE.Euler() })\n useFrame((state, delta) => {\n if (!ref.current) return\n\n const mainRot = window.TSCI_MAIN_CAMERA_ROTATION\n\n // Use window.TSCI_CAMERA_ROTATION to compute the position of the camera\n const cameraPosition = computePointInFront(mainRot, 2)\n\n state.camera.position.copy(cameraPosition)\n state.camera.lookAt(0, 0, 0)\n })\n return (\n <mesh ref={ref as any} rotation={[Math.PI / 2, 0, 0]}>\n <boxGeometry args={[1, 1, 1]} />\n <meshStandardMaterial color=\"white\" />\n <Text position={[0, 0, 0.51]} fontSize={0.25} color=\"black\">\n Front\n </Text>\n <Text\n position={[0, 0, -0.51]}\n fontSize={0.25}\n color=\"black\"\n rotation={[0, Math.PI, 0]}\n >\n Back\n </Text>\n <Text\n position={[0.51, 0, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[0, Math.PI / 2, 0]}\n >\n Right\n </Text>\n <Text\n position={[-0.51, 0, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[0, -Math.PI / 2, 0]}\n >\n Left\n </Text>\n <Text\n position={[0, 0.51, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[-Math.PI / 2, 0, 0]}\n >\n Top\n </Text>\n <Text\n position={[0, -0.51, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[Math.PI / 2, 0, 0]}\n >\n Bottom\n </Text>\n <lineSegments\n args={[new THREE.EdgesGeometry(new THREE.BoxGeometry(1, 1, 1))]}\n material={\n new THREE.LineBasicMaterial({\n color: 0x000000,\n linewidth: 2,\n })\n }\n />\n </mesh>\n )\n}\n","import { Html } from \"@react-three/drei\"\nimport { GroupProps, useThree } from \"@react-three/fiber\"\nimport { useRef, useCallback } from \"react\"\nimport type { Vector3 } from \"three\"\nimport * as THREE from \"three\"\n\nconst Group = (props: GroupProps) => <group {...props} />\n\nconst ContainerWithTooltip = ({\n children,\n isHovered,\n onHover,\n position,\n}: {\n children: React.ReactNode\n position?: Vector3 | [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) => {\n const lastValidPointRef = useRef<THREE.Vector3 | null>(null)\n\n const handlePointerEnter = useCallback(\n (e: any) => {\n e.stopPropagation()\n\n try {\n // Fallback to event position if raycaster fails\n const point =\n e.point ||\n (e.intersections && e.intersections.length > 0\n ? e.intersections[0].point\n : null) ||\n (position\n ? new THREE.Vector3(...(position as [number, number, number]))\n : null)\n\n if (point) {\n lastValidPointRef.current = point\n onHover({ mousePosition: [point.x, point.y, point.z] })\n } else {\n onHover({})\n }\n } catch (error) {\n console.warn(\"Hover event error:\", error)\n onHover({})\n }\n },\n [position],\n )\n\n const handlePointerLeave = useCallback(\n (e: any) => {\n e.stopPropagation()\n lastValidPointRef.current = null\n\n // TODO REPLACE WITH onUnhover\n onHover(null)\n },\n [onHover],\n )\n\n return (\n <Group\n onPointerEnter={handlePointerEnter}\n onPointerMove={handlePointerEnter}\n onPointerLeave={handlePointerLeave}\n >\n {children}\n </Group>\n )\n}\n\nexport default ContainerWithTooltip\n","import { useState, useEffect } from \"react\"\nimport type { Group } from \"three\"\nimport { MTLLoader, OBJLoader } from \"three-stdlib\"\n\n// Define the type for our cache\ninterface CacheItem {\n promise: Promise<any>\n result: Group | null\n}\n\ndeclare global {\n interface Window {\n TSCIRCUIT_OBJ_LOADER_CACHE: Map<string, CacheItem>\n }\n}\n\n// Ensure the global cache exists\nif (typeof window !== \"undefined\" && !window.TSCIRCUIT_OBJ_LOADER_CACHE) {\n window.TSCIRCUIT_OBJ_LOADER_CACHE = new Map<string, CacheItem>()\n}\n\nexport function useGlobalObjLoader(url: string | null): Group | null | Error {\n const [obj, setObj] = useState<Group | null | Error>(null)\n\n useEffect(() => {\n if (!url) return\n\n const cache = window.TSCIRCUIT_OBJ_LOADER_CACHE\n let hasUrlChanged = false\n\n async function loadAndParseObj() {\n try {\n const response = await fetch(url!)\n const text = await response.text()\n\n const mtlContent = text\n .match(/newmtl[\\s\\S]*?endmtl/g)\n ?.join(\"\\n\")!\n .replace(/d 0\\./g, \"d 1.\")!\n const objContent = text.replace(/newmtl[\\s\\S]*?endmtl/g, \"\")\n\n const mtlLoader = new MTLLoader()\n mtlLoader.setMaterialOptions({\n invertTrProperty: true,\n })\n const materials = mtlLoader.parse(\n mtlContent.replace(\n /Kd\\s+([\\d.]+)\\s+([\\d.]+)\\s+([\\d.]+)/g,\n \"Kd $2 $2 $2\",\n ),\n \"test.mtl\",\n )\n\n const objLoader = new OBJLoader()\n objLoader.setMaterials(materials)\n return objLoader.parse(objContent)\n } catch (error) {\n return error as Error\n }\n }\n\n function loadUrl() {\n if (cache.has(url!)) {\n const cacheItem = cache.get(url!)!\n if (cacheItem.result) {\n // If we have a result, clone it\n return Promise.resolve(cacheItem.result.clone())\n }\n // If we're still loading, return the existing promise\n return cacheItem.promise.then((result) => result.clone())\n }\n // If it's not in the cache, create a new promise and cache it\n const promise = loadAndParseObj().then((result) => {\n if (result instanceof Error) {\n // If the result is an Error, return it\n return result\n }\n cache.set(url!, { ...cache.get(url!)!, result })\n return result\n })\n cache.set(url!, { promise, result: null })\n return promise\n }\n\n loadUrl()\n .then((result) => {\n if (hasUrlChanged) return\n setObj(result)\n })\n .catch((error) => {\n console.error(error)\n })\n\n return () => {\n hasUrlChanged = true\n }\n }, [url])\n\n return obj\n}\n","import ContainerWithTooltip from \"src/ContainerWithTooltip\"\nimport { useGlobalObjLoader } from \"src/hooks/use-global-obj-loader\"\nimport type { Euler, Vector3 } from \"three\"\n\nexport function MixedStlModel({\n url,\n position,\n rotation,\n onHover,\n isHovered,\n}: {\n url: string\n position?: Vector3 | [number, number, number]\n rotation?: Euler | [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) {\n const obj = useGlobalObjLoader(url)\n\n if (!obj) {\n return (\n <ContainerWithTooltip isHovered={isHovered} onHover={onHover}>\n <mesh position={position}>\n <boxGeometry args={[0.5, 0.5, 0.5]} />\n <meshStandardMaterial transparent color=\"red\" opacity={0.25} />\n </mesh>\n </ContainerWithTooltip>\n )\n }\n\n // Check if obj is valid before rendering\n if (obj instanceof Error) {\n return (\n <ContainerWithTooltip isHovered={isHovered} onHover={onHover}>\n <mesh position={position}>\n <boxGeometry args={[0.5, 0.5, 0.5]} />\n <meshStandardMaterial transparent color=\"red\" opacity={0.5} />\n <meshBasicMaterial color=\"red\" />\n </mesh>\n </ContainerWithTooltip>\n )\n }\n return (\n <ContainerWithTooltip isHovered={isHovered} onHover={onHover}>\n <primitive rotation={rotation} position={position} object={obj} />\n </ContainerWithTooltip>\n )\n}\n","import type { JscadOperation } from \"jscad-planner\"\nimport { executeJscadOperations } from \"jscad-planner\"\nimport jscad from \"@jscad/modeling\"\nimport { convertCSGToThreeGeom } from \"jscad-fiber\"\nimport * as THREE from \"three\"\nimport { useMemo } from \"react\"\nimport ContainerWithTooltip from \"src/ContainerWithTooltip\"\n\nexport const JscadModel = ({\n jscadPlan,\n positionOffset,\n rotationOffset,\n onHover,\n isHovered,\n}: {\n jscadPlan: JscadOperation\n positionOffset?: [number, number, number]\n rotationOffset?: [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) => {\n const { threeGeom, material } = useMemo(() => {\n const jscadObject = executeJscadOperations(jscad as any, jscadPlan)\n\n const threeGeom = convertCSGToThreeGeom(jscadObject)\n\n const material = new THREE.MeshStandardMaterial({\n vertexColors: true,\n side: THREE.DoubleSide, // Ensure both sides are visible\n })\n return { threeGeom, material }\n }, [jscadPlan])\n\n useMemo(() => {\n if (isHovered) {\n const color = new THREE.Color(material.color.getHex())\n material.emissive.copy(color)\n material.emissive.setRGB(0, 0, 1)\n material.emissiveIntensity = 0.2\n } else {\n material.emissiveIntensity = 0\n }\n }, [isHovered, material])\n if (!threeGeom) return null\n\n return (\n <ContainerWithTooltip\n isHovered={isHovered}\n onHover={onHover}\n position={positionOffset}\n >\n <mesh\n geometry={threeGeom}\n material={material}\n position={positionOffset}\n rotation={rotationOffset}\n />\n </ContainerWithTooltip>\n )\n}\n","import { Footprinter3d } from \"jscad-electronics\"\nimport { createJSCADRenderer } from \"jscad-fiber\"\nimport { jscadPlanner } from \"jscad-planner\"\nimport { useMemo } from \"react\"\nimport { JscadModel } from \"./JscadModel\"\n\nconst { createJSCADRoot } = createJSCADRenderer(jscadPlanner as any)\n\nexport const FootprinterModel = ({\n positionOffset,\n footprint,\n rotationOffset,\n onHover,\n isHovered,\n}: {\n positionOffset: any\n footprint: string\n rotationOffset?: [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) => {\n const jscadOperations = useMemo(() => {\n if (!footprint) return null\n const jscadOperations: any[] = []\n const root = createJSCADRoot(jscadOperations)\n root.render(<Footprinter3d footprint={footprint} />)\n return jscadOperations\n }, [footprint])\n\n if (!jscadOperations) return null\n\n return (\n <>\n {jscadOperations.map((operation, index) => (\n <JscadModel\n // biome-ignore lint/suspicious/noArrayIndexKey: <explanation>\n key={index}\n positionOffset={positionOffset}\n rotationOffset={rotationOffset}\n jscadPlan={operation}\n onHover={onHover}\n isHovered={isHovered}\n />\n ))}\n </>\n )\n}\n","export const tuple = <T extends any[]>(...args: T): T => args\n","import type { AnyCircuitElement, CadComponent } from \"circuit-json\"\nimport { useConvertChildrenToSoup } from \"./hooks/use-convert-children-to-soup\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { useMemo, useState } from \"react\"\nimport { createBoardGeomFromSoup } from \"./soup-to-3d\"\nimport { useStlsFromGeom } from \"./hooks/use-stls-from-geom\"\nimport { STLModel } from \"./three-components/STLModel\"\nimport { CadViewerContainer } from \"./CadViewerContainer\"\nimport { MixedStlModel } from \"./three-components/MixedStlModel\"\nimport { Euler } from \"three\"\nimport { JscadModel } from \"./three-components/JscadModel\"\nimport { Footprinter3d } from \"jscad-electronics\"\nimport { FootprinterModel } from \"./three-components/FootprinterModel\"\nimport { tuple } from \"./utils/tuple\"\n\nexport const AnyCadComponent = ({\n cad_component,\n onHover = () => {},\n isHovered = false,\n}: {\n cad_component: CadComponent\n onHover?: (e: any) => void\n isHovered?: boolean\n}) => {\n const url = cad_component.model_obj_url ?? cad_component.model_stl_url\n const rotationOffset = cad_component.rotation\n ? tuple(\n (cad_component.rotation.x * Math.PI) / 180,\n (cad_component.rotation.y * Math.PI) / 180,\n (cad_component.rotation.z * Math.PI) / 180,\n )\n : undefined\n\n if (url) {\n return (\n <MixedStlModel\n key={cad_component.cad_component_id}\n url={url}\n position={\n cad_component.position\n ? [\n cad_component.position.x,\n cad_component.position.y,\n cad_component.position.z,\n ]\n : undefined\n }\n rotation={rotationOffset}\n onHover={onHover}\n isHovered={isHovered}\n />\n )\n }\n\n if (cad_component.model_jscad) {\n return (\n <JscadModel\n key={cad_component.cad_component_id}\n jscadPlan={cad_component.model_jscad as any}\n rotationOffset={rotationOffset}\n onHover={onHover}\n isHovered={isHovered}\n />\n )\n }\n\n if (cad_component.footprinter_string) {\n return (\n <FootprinterModel\n positionOffset={\n cad_component.position\n ? [\n cad_component.position.x,\n cad_component.position.y,\n cad_component.position.z,\n ]\n : undefined\n }\n rotationOffset={rotationOffset}\n footprint={cad_component.footprinter_string}\n onHover={onHover}\n isHovered={isHovered}\n />\n )\n }\n}\n","import React from \"react\"\n\ninterface Props {\n children: React.ReactNode\n fallback: (props: { error: Error }) => any\n}\n\ninterface State {\n hasError: boolean\n error: Error | null\n}\n\nexport class ThreeErrorBoundary extends React.Component<Props, State> {\n constructor(props: Props) {\n super(props)\n this.state = { hasError: false, error: null }\n }\n\n static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error }\n }\n\n override render() {\n if (this.state.hasError && this.state.error) {\n return this.props.fallback({ error: this.state.error })\n }\n\n return this.props.children\n }\n}\n","import { Text } from \"@react-three/drei\"\nimport type { CadComponent } from \"circuit-json\"\n\nexport const Error3d = ({\n error,\n cad_component,\n}: { error: any; cad_component?: CadComponent }) => {\n let position = [0, 0, 0]\n if (cad_component?.position) {\n position = [\n cad_component.position.x,\n cad_component.position.y,\n cad_component.position.z,\n ]\n // make sure the position doesn't have any NaN values\n position = position.map((p) => (Number.isNaN(p) ? 0 : p))\n }\n return (\n <group\n // @ts-expect-error\n position={position}\n >\n <mesh\n renderOrder={-99999}\n rotation={[Math.PI / 4, Math.PI / 4, 0]}\n ref={(mesh) => {\n if (mesh) {\n mesh.renderOrder = 999999\n }\n }}\n >\n <boxGeometry args={[0.5, 0.5, 0.5]} />\n <meshStandardMaterial\n depthTest={false}\n transparent\n color=\"red\"\n opacity={0.5}\n />\n </mesh>\n <Text\n scale={[0.1, 0.1, 0.1]}\n color=\"red\" // default\n anchorX=\"center\" // default\n anchorY=\"middle\" // default\n depthOffset={-99999}\n >\n {error.toString().slice(0, 50)}...\n </Text>\n </group>\n ) as any\n}\n"],"mappings":"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","names":["import_react","import_soup_util","import_react","import_transforms","import_primitives","import_colors","import_booleans","import_extrusions","import_primitives","import_react","stlSerializer","import_react","import_three_stdlib","import_drei","import_fiber","import_fiber","import_react","import_jsx_runtime","import_react","import_drei","import_jsx_runtime","import_react","THREE","import_jsx_runtime","import_react","import_three_stdlib","import_jsx_runtime","THREE","import_react","import_jsx_runtime","jscad","threeGeom","material","import_jscad_fiber","import_jscad_planner","import_react","import_jsx_runtime","jscadOperations","import_jsx_runtime","import_react","React","import_drei","import_jsx_runtime","import_jsx_runtime"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/3d-viewer",
3
- "version": "0.0.80",
3
+ "version": "0.0.82",
4
4
  "main": "./dist/index.js",
5
5
  "files": [
6
6
  "dist"
@@ -24,7 +24,7 @@
24
24
  "@react-three/drei": "^9.115.0",
25
25
  "@react-three/fiber": "^8.16.8",
26
26
  "@tscircuit/core": "^0.0.251",
27
- "@tscircuit/props": "^0.0.124",
27
+ "@tscircuit/props": "^0.0.125",
28
28
  "@tscircuit/react-fiber": "^1.1.29",
29
29
  "@tscircuit/soup": "^0.0.69",
30
30
  "@tscircuit/soup-util": "^0.0.26",
@@ -41,25 +41,25 @@
41
41
  "devDependencies": {
42
42
  "@biomejs/biome": "^1.8.3",
43
43
  "@chromatic-com/storybook": "^1.5.0",
44
- "@storybook/addon-essentials": "^8.1.10",
45
- "@storybook/addon-interactions": "^8.1.10",
46
- "@storybook/addon-links": "^8.1.10",
47
- "@storybook/addon-onboarding": "^8.1.10",
48
- "@storybook/blocks": "^8.1.10",
49
- "@storybook/builder-vite": "^8.1.10",
50
- "@storybook/react": "^8.1.10",
51
- "@storybook/react-vite": "^8.1.10",
52
- "@storybook/test": "^8.1.10",
44
+ "@storybook/addon-essentials": "^8.4.7",
45
+ "@storybook/addon-interactions": "^8.4.7",
46
+ "@storybook/addon-links": "^8.4.7",
47
+ "@storybook/addon-onboarding": "^8.4.7",
48
+ "@storybook/blocks": "^8.4.7",
49
+ "@storybook/builder-vite": "^8.4.7",
50
+ "@storybook/react": "^8.4.7",
51
+ "@storybook/react-vite": "^8.4.7",
52
+ "@storybook/test": "^8.4.7",
53
53
  "@types/react": "^18.3.3",
54
54
  "@types/react-dom": "^18.3.0",
55
- "@vitejs/plugin-react": "^4.3.1",
55
+ "@vitejs/plugin-react": "^4.3.4",
56
56
  "circuit-json": "^0.0.116",
57
57
  "circuit-to-svg": "^0.0.91",
58
- "storybook": "^8.1.10",
58
+ "storybook": "^8.4.7",
59
59
  "strip-ansi": "^7.1.0",
60
60
  "tsup": "^8.1.0",
61
- "typescript": "^5.5.3",
62
- "vite": "^5.3.1",
61
+ "typescript": "^5.7.2",
62
+ "vite": "^5.4.11",
63
63
  "vite-tsconfig-paths": "^4.3.2"
64
64
  }
65
65
  }