@tscircuit/pcb-viewer 1.11.412 → 1.11.413

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/README.md CHANGED
@@ -98,27 +98,30 @@ continuously. The main thread handles React, interaction, and view messages.
98
98
  There is no bitmap zoom-settle delay or pool of raster workers.
99
99
 
100
100
  Pass `renderer="canvas"` to explicitly use the existing Canvas renderer. WebGPU
101
- also falls back to Canvas when WebGPU/OffscreenCanvas is unavailable, initialization
102
- fails, the GPU device is lost, or the scene includes unsupported geometry (such
103
- as dimension annotations or interpolated trace routes). The initial GPU geometry compile
101
+ stays selected when WebGPU/OffscreenCanvas is unavailable, initialization fails,
102
+ the GPU device is lost, or the scene includes unsupported geometry (such as
103
+ dimension annotations or interpolated trace routes). These failures display an
104
+ error in the viewer and release the worker; they never start the Canvas renderer.
105
+ If the installed WebGPU renderer does not support X-Ray, the viewer displays a
106
+ notice and keeps the GPU view visible. The initial GPU geometry compile
104
107
  still takes time on large boards, but runs in the worker. Curves use fixed
105
108
  triangle tessellation and can show facets at extreme zoom.
106
109
 
107
110
  Right-click the board and choose **Rendering Engine → Canvas** or
108
111
  **WebGPU (experimental)** to switch without resetting pan, zoom, or layer visibility.
109
112
  The `renderer` prop sets the initial selection; changing that prop updates the selection.
110
- Selecting WebGPU still permits automatic Canvas fallback on unsupported devices or scenes.
113
+ Switching to Canvas always requires an explicit engine selection.
111
114
 
112
115
  Run `bun run test:webgpu` after `bunx playwright install chromium` to test the built
113
116
  viewer bundle, AM3352 wheel zoom, resize, StrictMode cleanup, context-menu switching,
114
- and fallbacks. The Cosmos `WebGpuAm3352` fixture also switches between backends.
117
+ and failure handling. The Cosmos `WebGpuAm3352` fixture also switches between backends.
115
118
 
116
119
  The WebGPU integration is still experimental. The complete imported Canvas suite
117
120
  currently exposes substantial non-text parity gaps, including soldermask, trace
118
121
  clipping, and keepouts. See the renderer's
119
122
  [full parity report](https://github.com/tscircuit/circuit-json-webgpu/blob/main/tests/parity/latest-report.json).
120
123
  The integration PR remains draft until these are resolved; existing diagnostics
121
- and Canvas fallback do not yet detect every visual mismatch.
124
+ do not yet detect every visual mismatch.
122
125
 
123
126
  The WebGPU renderer is installed as a bundled devDependency from
124
127
  `https://jscdn.tscircuit.com/@tscircuit/circuit-json-webgpu/0.0.3.tgz`.
package/dist/index.d.ts CHANGED
@@ -82,7 +82,7 @@ type Props = {
82
82
  circuitJson?: AnyCircuitElement[];
83
83
  height?: number;
84
84
  /** Initial engine; users can switch via the context menu. Prop changes reset it.
85
- * WebGPU runs in a worker and falls back to Canvas when unavailable. */
85
+ * WebGPU runs in a worker and reports failures without changing engines. */
86
86
  renderer?: "webgpu" | "canvas";
87
87
  allowEditing?: boolean;
88
88
  editEvents?: ManualEditEvent[];
package/dist/index.js CHANGED
@@ -11633,8 +11633,229 @@ var createWebGpuWorker = async () => {
11633
11633
  };
11634
11634
 
11635
11635
  // src/components/WebGpuElementsRenderer.tsx
11636
- import { useEffect as useEffect6, useMemo as useMemo3, useRef as useRef4, useState as useState4 } from "react";
11637
- import { SuperGrid as SuperGrid2, toMMSI as toMMSI2 } from "react-supergrid";
11636
+ import { useEffect as useEffect5, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
11637
+ import { SuperGrid, toMMSI } from "react-supergrid";
11638
+ import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
11639
+ function WebGpuElementsRenderer(props) {
11640
+ const { elements, primitives, transform, width = 500, height = 500 } = props;
11641
+ const holder = useRef3(null);
11642
+ const workerRef = useRef3(void 0);
11643
+ const ready = useRef3(false);
11644
+ const [supportsXRayNet, setSupportsXRayNet] = useState4(null);
11645
+ const [failure, setFailure] = useState4();
11646
+ const selectedLayer = useGlobalStore((s) => s.selected_layer);
11647
+ const hiddenLayerOpacity = useGlobalStore((s) => s.hidden_layer_opacity);
11648
+ const showCopperPours = useGlobalStore((s) => s.is_showing_copper_pours);
11649
+ const showSolderMask = useGlobalStore((s) => s.is_showing_solder_mask);
11650
+ const showSilkscreen = useGlobalStore((s) => s.is_showing_silkscreen);
11651
+ const showFabricationNotes = useGlobalStore(
11652
+ (s) => s.is_showing_fabrication_notes
11653
+ );
11654
+ const showPcbNotes = useGlobalStore((s) => s.is_showing_pcb_notes);
11655
+ const showCourtyards = useGlobalStore((s) => s.is_showing_courtyards);
11656
+ const highlightedElementIds = useMemo3(
11657
+ () => [
11658
+ ...new Set(
11659
+ primitives.flatMap((p) => {
11660
+ if (!p.is_mouse_over && !p.is_in_highlighted_net) return [];
11661
+ const element = p._element;
11662
+ const id = element?.[`${element.type}_id`];
11663
+ return id ? [id] : [];
11664
+ })
11665
+ )
11666
+ ],
11667
+ [primitives]
11668
+ );
11669
+ const xRayElementIds = useMemo3(
11670
+ () => (props.xRayElements ?? []).map(
11671
+ (element) => element[`${element.type}_id`]
11672
+ ),
11673
+ [props.xRayElements]
11674
+ );
11675
+ const options = useMemo3(
11676
+ () => ({
11677
+ selectedLayer,
11678
+ hiddenLayerOpacity,
11679
+ showCopperPours,
11680
+ showSolderMask,
11681
+ showSilkscreen,
11682
+ showFabricationNotes,
11683
+ showPcbNotes,
11684
+ showCourtyards,
11685
+ highlightedElementIds,
11686
+ xRayElementIds
11687
+ }),
11688
+ [
11689
+ selectedLayer,
11690
+ hiddenLayerOpacity,
11691
+ showCopperPours,
11692
+ showSolderMask,
11693
+ showSilkscreen,
11694
+ showFabricationNotes,
11695
+ showPcbNotes,
11696
+ showCourtyards,
11697
+ highlightedElementIds,
11698
+ xRayElementIds
11699
+ ]
11700
+ );
11701
+ const sceneRef = useRef3(elements);
11702
+ const viewRef = useRef3(void 0);
11703
+ sceneRef.current = elements;
11704
+ if (transform) {
11705
+ const ratio = typeof window === "undefined" ? 1 : window.devicePixelRatio || 1;
11706
+ viewRef.current = {
11707
+ type: "view",
11708
+ width: Math.max(1, Math.round(width * ratio)),
11709
+ height: Math.max(1, Math.round(height * ratio)),
11710
+ transform: {
11711
+ a: transform.a * ratio,
11712
+ b: transform.b * ratio,
11713
+ c: transform.c * ratio,
11714
+ d: transform.d * ratio,
11715
+ e: transform.e * ratio,
11716
+ f: transform.f * ratio
11717
+ },
11718
+ options
11719
+ };
11720
+ }
11721
+ useEffect5(() => {
11722
+ let disposed = false, failed = false, worker;
11723
+ const canvas = document.createElement("canvas");
11724
+ canvas.className = "pcb-webgpu-canvas";
11725
+ canvas.style.cssText = "position:absolute;inset:0;width:100%;height:100%;pointer-events:none";
11726
+ holder.current?.append(canvas);
11727
+ const fail = (message) => {
11728
+ if (disposed || failed) return;
11729
+ failed = true;
11730
+ clearTimeout(timeout);
11731
+ canvas.remove();
11732
+ ready.current = false;
11733
+ worker?.terminate();
11734
+ worker = void 0;
11735
+ workerRef.current = void 0;
11736
+ if (holder.current) holder.current.dataset.xRayNetActive = "false";
11737
+ setFailure(message);
11738
+ };
11739
+ const timeout = setTimeout(
11740
+ () => fail("WebGPU worker startup timed out"),
11741
+ 15e3
11742
+ );
11743
+ void (async () => {
11744
+ try {
11745
+ if (!navigator.gpu || typeof Worker === "undefined" || !canvas.transferControlToOffscreen)
11746
+ throw new Error("WebGPU workers are unavailable");
11747
+ worker = await createWebGpuWorker();
11748
+ if (disposed || failed) {
11749
+ worker.terminate();
11750
+ return;
11751
+ }
11752
+ workerRef.current = worker;
11753
+ worker.onmessage = ({ data }) => {
11754
+ if (disposed || failed) return;
11755
+ if (data.type === "rendered") {
11756
+ if (holder.current)
11757
+ holder.current.dataset.xRayNetActive = String(data.xRayActive);
11758
+ } else if (data.type === "error") {
11759
+ fail(data.message);
11760
+ } else if (data.type === "ready") {
11761
+ clearTimeout(timeout);
11762
+ setSupportsXRayNet(data.supportsXRayNet);
11763
+ ready.current = true;
11764
+ worker.postMessage({
11765
+ type: "scene",
11766
+ elements: sceneRef.current
11767
+ });
11768
+ if (viewRef.current) worker.postMessage(viewRef.current);
11769
+ }
11770
+ };
11771
+ worker.onerror = (event) => {
11772
+ event.preventDefault();
11773
+ fail(event.message || "WebGPU worker failed");
11774
+ };
11775
+ worker.addEventListener("messageerror", () => {
11776
+ fail("WebGPU worker communication failed");
11777
+ });
11778
+ const offscreen = canvas.transferControlToOffscreen();
11779
+ worker.postMessage(
11780
+ { type: "init", canvas: offscreen },
11781
+ [offscreen]
11782
+ );
11783
+ } catch (error) {
11784
+ fail(String(error));
11785
+ }
11786
+ })();
11787
+ return () => {
11788
+ disposed = true;
11789
+ clearTimeout(timeout);
11790
+ ready.current = false;
11791
+ workerRef.current = void 0;
11792
+ worker?.terminate();
11793
+ canvas.remove();
11794
+ };
11795
+ }, []);
11796
+ useEffect5(() => {
11797
+ if (ready.current)
11798
+ workerRef.current?.postMessage({
11799
+ type: "scene",
11800
+ elements
11801
+ });
11802
+ }, [elements]);
11803
+ useEffect5(() => {
11804
+ if (ready.current && viewRef.current)
11805
+ workerRef.current?.postMessage(viewRef.current);
11806
+ }, [transform, width, height, options]);
11807
+ const xRayUnavailable = Boolean(
11808
+ props.xRayElements && supportsXRayNet === false
11809
+ );
11810
+ return /* @__PURE__ */ jsx3(
11811
+ "div",
11812
+ {
11813
+ ref: holder,
11814
+ "data-pcb-renderer": "webgpu",
11815
+ "data-webgpu-error": failure,
11816
+ style: {
11817
+ width,
11818
+ height,
11819
+ background: "black",
11820
+ position: "relative",
11821
+ overflow: "hidden"
11822
+ },
11823
+ children: failure ? /* @__PURE__ */ jsxs(
11824
+ "div",
11825
+ {
11826
+ role: "alert",
11827
+ style: { padding: 16, color: "white", position: "relative" },
11828
+ children: [
11829
+ /* @__PURE__ */ jsx3("strong", { children: "WebGPU rendering failed" }),
11830
+ /* @__PURE__ */ jsx3("div", { children: failure })
11831
+ ]
11832
+ }
11833
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
11834
+ /* @__PURE__ */ jsx3(
11835
+ SuperGrid,
11836
+ {
11837
+ textColor: "rgba(0,255,0,0.8)",
11838
+ majorColor: "rgba(0,255,0,0.4)",
11839
+ minorColor: "rgba(0,255,0,0.2)",
11840
+ screenSpaceCellSize: 200,
11841
+ width,
11842
+ height,
11843
+ transform,
11844
+ stringifyCoord: (x, y, z) => `${toMMSI(x, z)}, ${toMMSI(y, z)}`
11845
+ }
11846
+ ),
11847
+ xRayUnavailable && /* @__PURE__ */ jsx3(
11848
+ "div",
11849
+ {
11850
+ role: "status",
11851
+ style: { padding: 16, color: "white", position: "relative" },
11852
+ children: "X-Ray is unavailable in this WebGPU renderer."
11853
+ }
11854
+ )
11855
+ ] })
11856
+ }
11857
+ );
11858
+ }
11638
11859
 
11639
11860
  // src/components/CanvasPrimitiveRenderer.tsx
11640
11861
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer17 } from "circuit-to-canvas";
@@ -13577,9 +13798,9 @@ var getPrimitivesForDrawer = ({
13577
13798
  ).filter((primitive) => primitive._element?.type !== "pcb_via").filter((primitive) => primitive._element?.type !== "pcb_trace").filter((primitive) => primitive._element?.type !== "pcb_copper_text");
13578
13799
 
13579
13800
  // src/components/CanvasPrimitiveRenderer.tsx
13580
- import { useEffect as useEffect5, useRef as useRef3 } from "react";
13581
- import { SuperGrid, toMMSI } from "react-supergrid";
13582
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
13801
+ import { useEffect as useEffect6, useRef as useRef4 } from "react";
13802
+ import { SuperGrid as SuperGrid2, toMMSI as toMMSI2 } from "react-supergrid";
13803
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
13583
13804
  var CanvasPrimitiveRenderer = ({
13584
13805
  primitives,
13585
13806
  elements,
@@ -13589,8 +13810,8 @@ var CanvasPrimitiveRenderer = ({
13589
13810
  width = 500,
13590
13811
  height = 500
13591
13812
  }) => {
13592
- const xRayCanvasRef = useRef3(null);
13593
- const canvasRefs = useRef3({});
13813
+ const xRayCanvasRef = useRef4(null);
13814
+ const canvasRefs = useRef4({});
13594
13815
  const hiddenLayerOpacity = useGlobalStore((s) => s.hidden_layer_opacity);
13595
13816
  const selectedLayer = useGlobalStore((s) => s.selected_layer);
13596
13817
  const isShowingCopperPours = useGlobalStore((s) => s.is_showing_copper_pours);
@@ -13601,7 +13822,7 @@ var CanvasPrimitiveRenderer = ({
13601
13822
  const isShowingPcbNotes = useGlobalStore((s) => s.is_showing_pcb_notes);
13602
13823
  const isShowingCourtyards = useGlobalStore((s) => s.is_showing_courtyards);
13603
13824
  const isShowingSilkscreen = useGlobalStore((s) => s.is_showing_silkscreen);
13604
- useEffect5(() => {
13825
+ useEffect6(() => {
13605
13826
  if (!canvasRefs.current) return;
13606
13827
  if (Object.keys(canvasRefs.current).length === 0) return;
13607
13828
  const availableCanvasRefs = Object.fromEntries(
@@ -13898,7 +14119,7 @@ var CanvasPrimitiveRenderer = ({
13898
14119
  isShowingCourtyards,
13899
14120
  isShowingSilkscreen
13900
14121
  ]);
13901
- return /* @__PURE__ */ jsxs(
14122
+ return /* @__PURE__ */ jsxs2(
13902
14123
  "div",
13903
14124
  {
13904
14125
  style: {
@@ -13908,8 +14129,8 @@ var CanvasPrimitiveRenderer = ({
13908
14129
  position: "relative"
13909
14130
  },
13910
14131
  children: [
13911
- /* @__PURE__ */ jsx3(
13912
- SuperGrid,
14132
+ /* @__PURE__ */ jsx4(
14133
+ SuperGrid2,
13913
14134
  {
13914
14135
  textColor: "rgba(0,255,0,0.8)",
13915
14136
  majorColor: "rgba(0,255,0,0.4)",
@@ -13918,10 +14139,10 @@ var CanvasPrimitiveRenderer = ({
13918
14139
  width,
13919
14140
  height,
13920
14141
  transform,
13921
- stringifyCoord: (x, y, z) => `${toMMSI(x, z)}, ${toMMSI(y, z)}`
14142
+ stringifyCoord: (x, y, z) => `${toMMSI2(x, z)}, ${toMMSI2(y, z)}`
13922
14143
  }
13923
14144
  ),
13924
- xRayElements && /* @__PURE__ */ jsx3(
14145
+ xRayElements && /* @__PURE__ */ jsx4(
13925
14146
  "canvas",
13926
14147
  {
13927
14148
  ref: xRayCanvasRef,
@@ -13941,7 +14162,7 @@ var CanvasPrimitiveRenderer = ({
13941
14162
  if (!isShowingSolderMask && layer.includes("soldermask")) return false;
13942
14163
  if (!isShowingSilkscreen && layer.includes("silkscreen")) return false;
13943
14164
  return true;
13944
- }).map((l) => l.replace(/-/g, "")).map((layer, i) => /* @__PURE__ */ jsx3(
14165
+ }).map((l) => l.replace(/-/g, "")).map((layer, i) => /* @__PURE__ */ jsx4(
13945
14166
  "canvas",
13946
14167
  {
13947
14168
  className: `pcb-layer-${layer}`,
@@ -13970,217 +14191,6 @@ var CanvasPrimitiveRenderer = ({
13970
14191
  );
13971
14192
  };
13972
14193
 
13973
- // src/components/WebGpuElementsRenderer.tsx
13974
- import { Fragment, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
13975
- function WebGpuElementsRenderer(props) {
13976
- const { elements, primitives, transform, width = 500, height = 500 } = props;
13977
- const holder = useRef4(null);
13978
- const workerRef = useRef4(void 0);
13979
- const ready = useRef4(false);
13980
- const [supportsXRayNet, setSupportsXRayNet] = useState4(false);
13981
- const [failure, setFailure] = useState4();
13982
- const selectedLayer = useGlobalStore((s) => s.selected_layer);
13983
- const hiddenLayerOpacity = useGlobalStore((s) => s.hidden_layer_opacity);
13984
- const showCopperPours = useGlobalStore((s) => s.is_showing_copper_pours);
13985
- const showSolderMask = useGlobalStore((s) => s.is_showing_solder_mask);
13986
- const showSilkscreen = useGlobalStore((s) => s.is_showing_silkscreen);
13987
- const showFabricationNotes = useGlobalStore(
13988
- (s) => s.is_showing_fabrication_notes
13989
- );
13990
- const showPcbNotes = useGlobalStore((s) => s.is_showing_pcb_notes);
13991
- const showCourtyards = useGlobalStore((s) => s.is_showing_courtyards);
13992
- const highlightedElementIds = useMemo3(
13993
- () => [
13994
- ...new Set(
13995
- primitives.flatMap((p) => {
13996
- if (!p.is_mouse_over && !p.is_in_highlighted_net) return [];
13997
- const element = p._element;
13998
- const id = element?.[`${element.type}_id`];
13999
- return id ? [id] : [];
14000
- })
14001
- )
14002
- ],
14003
- [primitives]
14004
- );
14005
- const xRayElementIds = useMemo3(
14006
- () => (props.xRayElements ?? []).map(
14007
- (element) => element[`${element.type}_id`]
14008
- ),
14009
- [props.xRayElements]
14010
- );
14011
- const options = useMemo3(
14012
- () => ({
14013
- selectedLayer,
14014
- hiddenLayerOpacity,
14015
- showCopperPours,
14016
- showSolderMask,
14017
- showSilkscreen,
14018
- showFabricationNotes,
14019
- showPcbNotes,
14020
- showCourtyards,
14021
- highlightedElementIds,
14022
- xRayElementIds
14023
- }),
14024
- [
14025
- selectedLayer,
14026
- hiddenLayerOpacity,
14027
- showCopperPours,
14028
- showSolderMask,
14029
- showSilkscreen,
14030
- showFabricationNotes,
14031
- showPcbNotes,
14032
- showCourtyards,
14033
- highlightedElementIds,
14034
- xRayElementIds
14035
- ]
14036
- );
14037
- const sceneRef = useRef4(elements);
14038
- const viewRef = useRef4(void 0);
14039
- sceneRef.current = elements;
14040
- if (transform) {
14041
- const ratio = typeof window === "undefined" ? 1 : window.devicePixelRatio || 1;
14042
- viewRef.current = {
14043
- type: "view",
14044
- width: Math.max(1, Math.round(width * ratio)),
14045
- height: Math.max(1, Math.round(height * ratio)),
14046
- transform: {
14047
- a: transform.a * ratio,
14048
- b: transform.b * ratio,
14049
- c: transform.c * ratio,
14050
- d: transform.d * ratio,
14051
- e: transform.e * ratio,
14052
- f: transform.f * ratio
14053
- },
14054
- options
14055
- };
14056
- }
14057
- useEffect6(() => {
14058
- let disposed = false, failed = false, worker;
14059
- const canvas = document.createElement("canvas");
14060
- canvas.className = "pcb-webgpu-canvas";
14061
- canvas.style.cssText = "position:absolute;inset:0;width:100%;height:100%;pointer-events:none";
14062
- holder.current?.append(canvas);
14063
- const fallback = (message) => {
14064
- if (disposed || failed) return;
14065
- failed = true;
14066
- canvas.remove();
14067
- ready.current = false;
14068
- worker?.terminate();
14069
- workerRef.current = void 0;
14070
- setFailure(message);
14071
- };
14072
- const timeout = setTimeout(
14073
- () => fallback("WebGPU worker startup timed out"),
14074
- 15e3
14075
- );
14076
- void (async () => {
14077
- try {
14078
- if (!navigator.gpu || typeof Worker === "undefined" || !canvas.transferControlToOffscreen)
14079
- throw new Error("WebGPU workers are unavailable");
14080
- worker = await createWebGpuWorker();
14081
- if (disposed || failed) {
14082
- worker.terminate();
14083
- return;
14084
- }
14085
- workerRef.current = worker;
14086
- worker.onmessage = ({ data }) => {
14087
- if (disposed || failed) return;
14088
- if (data.type === "rendered") {
14089
- if (holder.current)
14090
- holder.current.dataset.xRayNetActive = String(data.xRayActive);
14091
- } else if (data.type === "error") {
14092
- clearTimeout(timeout);
14093
- fallback(data.message);
14094
- } else if (data.type === "ready") {
14095
- clearTimeout(timeout);
14096
- setSupportsXRayNet(data.supportsXRayNet);
14097
- ready.current = true;
14098
- worker.postMessage({
14099
- type: "scene",
14100
- elements: sceneRef.current
14101
- });
14102
- if (viewRef.current) worker.postMessage(viewRef.current);
14103
- }
14104
- };
14105
- worker.onerror = (event) => {
14106
- event.preventDefault();
14107
- clearTimeout(timeout);
14108
- fallback(event.message || "WebGPU worker failed");
14109
- };
14110
- worker.onmessageerror = () => {
14111
- clearTimeout(timeout);
14112
- fallback("WebGPU worker communication failed");
14113
- };
14114
- const offscreen = canvas.transferControlToOffscreen();
14115
- worker.postMessage(
14116
- { type: "init", canvas: offscreen },
14117
- [offscreen]
14118
- );
14119
- } catch (error) {
14120
- clearTimeout(timeout);
14121
- fallback(String(error));
14122
- }
14123
- })();
14124
- return () => {
14125
- disposed = true;
14126
- clearTimeout(timeout);
14127
- ready.current = false;
14128
- workerRef.current = void 0;
14129
- worker?.terminate();
14130
- canvas.remove();
14131
- };
14132
- }, []);
14133
- useEffect6(() => {
14134
- if (ready.current)
14135
- workerRef.current?.postMessage({
14136
- type: "scene",
14137
- elements
14138
- });
14139
- }, [elements]);
14140
- useEffect6(() => {
14141
- if (ready.current && viewRef.current)
14142
- workerRef.current?.postMessage(viewRef.current);
14143
- }, [transform, width, height, options]);
14144
- const fallbackElements = useMemo3(
14145
- () => showCopperPours ? elements : elements.filter((e) => e.type !== "pcb_copper_pour"),
14146
- [elements, showCopperPours]
14147
- );
14148
- if (failure)
14149
- return /* @__PURE__ */ jsx4("div", { "data-pcb-renderer": "canvas", "data-webgpu-fallback": failure, children: /* @__PURE__ */ jsx4(CanvasPrimitiveRenderer, { ...props, elements: fallbackElements }) });
14150
- const useXRayFallback = Boolean(props.xRayElements && !supportsXRayNet);
14151
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
14152
- useXRayFallback && /* @__PURE__ */ jsx4("div", { "data-x-ray-fallback": "unsupported-webgpu-version", children: /* @__PURE__ */ jsx4(CanvasPrimitiveRenderer, { ...props, elements: fallbackElements }) }),
14153
- /* @__PURE__ */ jsx4(
14154
- "div",
14155
- {
14156
- ref: holder,
14157
- "data-pcb-renderer": "webgpu",
14158
- style: {
14159
- width,
14160
- height,
14161
- background: "black",
14162
- position: "relative",
14163
- overflow: "hidden",
14164
- display: useXRayFallback ? "none" : void 0
14165
- },
14166
- children: /* @__PURE__ */ jsx4(
14167
- SuperGrid2,
14168
- {
14169
- textColor: "rgba(0,255,0,0.8)",
14170
- majorColor: "rgba(0,255,0,0.4)",
14171
- minorColor: "rgba(0,255,0,0.2)",
14172
- screenSpaceCellSize: 200,
14173
- width,
14174
- height,
14175
- transform,
14176
- stringifyCoord: (x, y, z) => `${toMMSI2(x, z)}, ${toMMSI2(y, z)}`
14177
- }
14178
- )
14179
- }
14180
- )
14181
- ] });
14182
- }
14183
-
14184
14194
  // node_modules/graphics-debug/dist/chunk-OHVOYMJ4.js
14185
14195
  import {
14186
14196
  glyphAdvanceRatio,
@@ -18359,7 +18369,7 @@ import { css as css3 } from "@emotion/css";
18359
18369
  // package.json
18360
18370
  var package_default = {
18361
18371
  name: "@tscircuit/pcb-viewer",
18362
- version: "1.11.411",
18372
+ version: "1.11.412",
18363
18373
  main: "dist/index.js",
18364
18374
  type: "module",
18365
18375
  repository: {