circuit-to-svg 0.0.283 → 0.0.285

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  // lib/pcb/convert-circuit-json-to-pcb-svg.ts
2
- import { distance } from "circuit-json";
2
+ import { distance as distance2 } from "circuit-json";
3
3
  import { stringify } from "svgson";
4
4
  import {
5
- applyToPoint as applyToPoint32,
6
- compose as compose5,
7
- scale as scale2,
8
- translate as translate5
5
+ applyToPoint as applyToPoint33,
6
+ compose as compose6,
7
+ scale as scale3,
8
+ translate as translate6
9
9
  } from "transformation-matrix";
10
10
 
11
11
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-trace-error.ts
@@ -2677,8 +2677,326 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
2677
2677
  return [svgObject];
2678
2678
  }
2679
2679
 
2680
+ // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-copper-text.ts
2681
+ import {
2682
+ applyToPoint as applyToPoint16,
2683
+ compose as compose3,
2684
+ rotate as rotate3,
2685
+ translate as translate3,
2686
+ scale as scale2,
2687
+ toString as matrixToString4
2688
+ } from "transformation-matrix";
2689
+
2690
+ // lib/pcb/colors.ts
2691
+ var DEFAULT_PCB_COLOR_MAP = {
2692
+ copper: {
2693
+ top: "rgb(200, 52, 52)",
2694
+ inner1: "rgb(255, 140, 0)",
2695
+ inner2: "rgb(255, 215, 0)",
2696
+ inner3: "rgb(50, 205, 50)",
2697
+ inner4: "rgb(64, 224, 208)",
2698
+ inner5: "rgb(138, 43, 226)",
2699
+ inner6: "rgb(255, 105, 180)",
2700
+ bottom: "rgb(77, 127, 196)"
2701
+ },
2702
+ soldermaskWithCopperUnderneath: {
2703
+ top: "rgb(18, 82, 50)",
2704
+ bottom: "rgb(77, 127, 196)"
2705
+ },
2706
+ soldermask: {
2707
+ top: "rgb(12, 55, 33)",
2708
+ bottom: "rgb(12, 55, 33)"
2709
+ },
2710
+ soldermaskOverCopper: {
2711
+ top: "rgb(52, 135, 73)",
2712
+ bottom: "rgb(52, 135, 73)"
2713
+ },
2714
+ substrate: "rgb(201, 162, 110)",
2715
+ // FR4 substrate color (tan/beige)
2716
+ drill: "#FF26E2",
2717
+ silkscreen: {
2718
+ top: "#f2eda1",
2719
+ bottom: "#5da9e9"
2720
+ },
2721
+ boardOutline: "rgba(255, 255, 255, 0.5)",
2722
+ courtyard: "#FF00FF",
2723
+ debugComponent: {
2724
+ fill: null,
2725
+ stroke: null
2726
+ }
2727
+ };
2728
+ var HOLE_COLOR = DEFAULT_PCB_COLOR_MAP.drill;
2729
+ var SILKSCREEN_TOP_COLOR = DEFAULT_PCB_COLOR_MAP.silkscreen.top;
2730
+ var SILKSCREEN_BOTTOM_COLOR = DEFAULT_PCB_COLOR_MAP.silkscreen.bottom;
2731
+
2732
+ // lib/pcb/layer-name-to-color.ts
2733
+ var LAYER_NAME_TO_COLOR = {
2734
+ ...DEFAULT_PCB_COLOR_MAP.copper
2735
+ };
2736
+ function layerNameToColor(layerName, colorMap2 = DEFAULT_PCB_COLOR_MAP) {
2737
+ return colorMap2.copper[layerName] ?? "white";
2738
+ }
2739
+ var SOLDER_PASTE_LAYER_NAME_TO_COLOR = {
2740
+ bottom: "rgb(105, 105, 105)",
2741
+ top: "rgb(105, 105, 105)"
2742
+ };
2743
+ function solderPasteLayerNameToColor(layerName) {
2744
+ return SOLDER_PASTE_LAYER_NAME_TO_COLOR[layerName] ?? "rgb(105, 105, 105)";
2745
+ }
2746
+
2747
+ // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-copper-text.ts
2748
+ import { distance } from "circuit-json";
2749
+ import { lineAlphabet } from "@tscircuit/alphabet";
2750
+ var CHAR_WIDTH = 1;
2751
+ var CHAR_SPACING = 0.2;
2752
+ var LINE_HEIGHT = 1.4;
2753
+ function linesToPathData(lines, offsetX, offsetY, charScale) {
2754
+ return lines.map((line) => {
2755
+ const x1 = offsetX + line.x1 * charScale;
2756
+ const y1 = offsetY + (1 - line.y1) * charScale;
2757
+ const x2 = offsetX + line.x2 * charScale;
2758
+ const y2 = offsetY + (1 - line.y2) * charScale;
2759
+ return `M${x1} ${y1}L${x2} ${y2}`;
2760
+ }).join(" ");
2761
+ }
2762
+ function textToAlphabetPath(text, fontSize) {
2763
+ const paths = [];
2764
+ const charAdvance = (CHAR_WIDTH + CHAR_SPACING) * fontSize;
2765
+ let x = 0;
2766
+ for (const char of text) {
2767
+ if (char === " ") {
2768
+ x += charAdvance * 0.6;
2769
+ continue;
2770
+ }
2771
+ const lines = lineAlphabet[char];
2772
+ if (lines) {
2773
+ paths.push(linesToPathData(lines, x, 0, fontSize));
2774
+ }
2775
+ x += charAdvance;
2776
+ }
2777
+ const width = x > 0 ? x - CHAR_SPACING * fontSize : 0;
2778
+ return { pathData: paths.join(" "), width };
2779
+ }
2780
+ var maskIdCounter = 0;
2781
+ function textToCenteredAlphabetPaths(text, fontSize) {
2782
+ const textLines = text.split("\n");
2783
+ const lineHeight = fontSize * LINE_HEIGHT;
2784
+ const totalHeight = textLines.length * lineHeight;
2785
+ const lineWidths = [];
2786
+ let maxWidth = 0;
2787
+ for (const line of textLines) {
2788
+ const { width } = textToAlphabetPath(line, fontSize);
2789
+ lineWidths.push(width);
2790
+ if (width > maxWidth) maxWidth = width;
2791
+ }
2792
+ const paths = [];
2793
+ let y = -totalHeight / 2;
2794
+ for (let i = 0; i < textLines.length; i++) {
2795
+ const line = textLines[i];
2796
+ const lineWidth = lineWidths[i];
2797
+ const charAdvance = (CHAR_WIDTH + CHAR_SPACING) * fontSize;
2798
+ let x = -lineWidth / 2;
2799
+ for (const char of line) {
2800
+ if (char === " ") {
2801
+ x += charAdvance * 0.6;
2802
+ continue;
2803
+ }
2804
+ const charLines = lineAlphabet[char];
2805
+ if (charLines) {
2806
+ paths.push(linesToPathData(charLines, x, y, fontSize));
2807
+ }
2808
+ x += charAdvance;
2809
+ }
2810
+ y += lineHeight;
2811
+ }
2812
+ return {
2813
+ pathData: paths.join(" "),
2814
+ width: maxWidth,
2815
+ height: totalHeight
2816
+ };
2817
+ }
2818
+ function createSvgObjectsFromPcbCopperText(pcbCopperText, ctx) {
2819
+ const { transform, layer: filterLayer, colorMap: colorMap2 } = ctx;
2820
+ const {
2821
+ anchor_position,
2822
+ text,
2823
+ font_size = "0.2mm",
2824
+ layer,
2825
+ ccw_rotation = 0,
2826
+ anchor_alignment = "center",
2827
+ is_knockout = false,
2828
+ knockout_padding,
2829
+ is_mirrored = false
2830
+ } = pcbCopperText;
2831
+ const layerName = layer ?? "top";
2832
+ if (filterLayer && filterLayer !== layerName) return [];
2833
+ if (!anchor_position) return [];
2834
+ const [ax, ay] = applyToPoint16(transform, [
2835
+ anchor_position.x,
2836
+ anchor_position.y
2837
+ ]);
2838
+ const fontSizeNum = distance.parse(font_size) ?? 0.2;
2839
+ const scaleFactor = Math.abs(transform.a);
2840
+ const copperColor = layerNameToColor(layerName, colorMap2);
2841
+ const isBottom = layerName === "bottom";
2842
+ const applyMirror = isBottom ? true : is_mirrored === true;
2843
+ if (is_knockout) {
2844
+ const { pathData: pathData2, width: width2, height: height2 } = textToCenteredAlphabetPaths(
2845
+ text,
2846
+ fontSizeNum
2847
+ );
2848
+ const padX = knockout_padding?.left ?? fontSizeNum * 0.5;
2849
+ const padY = knockout_padding?.top ?? fontSizeNum * 0.3;
2850
+ const rectW = width2 + padX * 2;
2851
+ const rectH = height2 + padY * 2;
2852
+ const strokeWidth2 = fontSizeNum * 0.15;
2853
+ const knockoutTransform = matrixToString4(
2854
+ compose3(
2855
+ translate3(ax, ay),
2856
+ rotate3(-ccw_rotation * Math.PI / 180),
2857
+ ...applyMirror ? [scale2(-1, 1)] : [],
2858
+ scale2(scaleFactor, scaleFactor)
2859
+ )
2860
+ );
2861
+ const maskId = `knockout-mask-${pcbCopperText.pcb_copper_text_id}-${maskIdCounter++}`;
2862
+ return [
2863
+ {
2864
+ name: "defs",
2865
+ type: "element",
2866
+ value: "",
2867
+ children: [
2868
+ {
2869
+ name: "mask",
2870
+ type: "element",
2871
+ value: "",
2872
+ attributes: {
2873
+ id: maskId
2874
+ },
2875
+ children: [
2876
+ // White background - area that will show copper
2877
+ {
2878
+ name: "rect",
2879
+ type: "element",
2880
+ value: "",
2881
+ attributes: {
2882
+ x: (-rectW / 2).toString(),
2883
+ y: (-rectH / 2).toString(),
2884
+ width: rectW.toString(),
2885
+ height: rectH.toString(),
2886
+ fill: "white"
2887
+ },
2888
+ children: []
2889
+ },
2890
+ // Black text strokes - area that will be cut out
2891
+ {
2892
+ name: "path",
2893
+ type: "element",
2894
+ value: "",
2895
+ attributes: {
2896
+ d: pathData2,
2897
+ fill: "none",
2898
+ stroke: "black",
2899
+ "stroke-width": strokeWidth2.toString(),
2900
+ "stroke-linecap": "round",
2901
+ "stroke-linejoin": "round"
2902
+ },
2903
+ children: []
2904
+ }
2905
+ ]
2906
+ }
2907
+ ],
2908
+ attributes: {}
2909
+ },
2910
+ {
2911
+ name: "rect",
2912
+ type: "element",
2913
+ value: "",
2914
+ children: [],
2915
+ attributes: {
2916
+ x: (-rectW / 2).toString(),
2917
+ y: (-rectH / 2).toString(),
2918
+ width: rectW.toString(),
2919
+ height: rectH.toString(),
2920
+ fill: copperColor,
2921
+ mask: `url(#${maskId})`,
2922
+ transform: knockoutTransform,
2923
+ class: `pcb-copper-text-knockout pcb-copper-${layerName}`,
2924
+ "data-type": "pcb_copper_text",
2925
+ "data-pcb-copper-text-id": pcbCopperText.pcb_copper_text_id
2926
+ }
2927
+ }
2928
+ ];
2929
+ }
2930
+ const { pathData, width, height } = textToCenteredAlphabetPaths(
2931
+ text,
2932
+ fontSizeNum
2933
+ );
2934
+ let offsetX = 0;
2935
+ let offsetY = 0;
2936
+ switch (anchor_alignment) {
2937
+ case "top_left":
2938
+ offsetX = width / 2;
2939
+ offsetY = height / 2;
2940
+ break;
2941
+ case "top_center":
2942
+ offsetY = height / 2;
2943
+ break;
2944
+ case "top_right":
2945
+ offsetX = -width / 2;
2946
+ offsetY = height / 2;
2947
+ break;
2948
+ case "center_left":
2949
+ offsetX = width / 2;
2950
+ break;
2951
+ case "center_right":
2952
+ offsetX = -width / 2;
2953
+ break;
2954
+ case "bottom_left":
2955
+ offsetX = width / 2;
2956
+ offsetY = -height / 2;
2957
+ break;
2958
+ case "bottom_center":
2959
+ offsetY = -height / 2;
2960
+ break;
2961
+ case "bottom_right":
2962
+ offsetX = -width / 2;
2963
+ offsetY = -height / 2;
2964
+ break;
2965
+ }
2966
+ const textTransform = matrixToString4(
2967
+ compose3(
2968
+ translate3(ax, ay),
2969
+ rotate3(-ccw_rotation * Math.PI / 180),
2970
+ ...applyMirror ? [scale2(-1, 1)] : [],
2971
+ translate3(offsetX, offsetY),
2972
+ scale2(scaleFactor, scaleFactor)
2973
+ )
2974
+ );
2975
+ const strokeWidth = fontSizeNum * 0.15;
2976
+ return [
2977
+ {
2978
+ name: "path",
2979
+ type: "element",
2980
+ attributes: {
2981
+ d: pathData,
2982
+ fill: "none",
2983
+ stroke: copperColor,
2984
+ "stroke-width": strokeWidth.toString(),
2985
+ "stroke-linecap": "round",
2986
+ "stroke-linejoin": "round",
2987
+ transform: textTransform,
2988
+ class: `pcb-copper-text pcb-copper-${layerName}`,
2989
+ "data-type": "pcb_copper_text",
2990
+ "data-pcb-copper-text-id": pcbCopperText.pcb_copper_text_id
2991
+ },
2992
+ children: [],
2993
+ value: ""
2994
+ }
2995
+ ];
2996
+ }
2997
+
2680
2998
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-circle.ts
2681
- import { applyToPoint as applyToPoint16 } from "transformation-matrix";
2999
+ import { applyToPoint as applyToPoint17 } from "transformation-matrix";
2682
3000
  function createSvgObjectsFromPcbSilkscreenCircle(pcbSilkscreenCircle, ctx) {
2683
3001
  const { transform, layer: layerFilter, colorMap: colorMap2 } = ctx;
2684
3002
  const {
@@ -2693,7 +3011,7 @@ function createSvgObjectsFromPcbSilkscreenCircle(pcbSilkscreenCircle, ctx) {
2693
3011
  console.error("Invalid PCB Silkscreen Circle data:", { center, radius });
2694
3012
  return [];
2695
3013
  }
2696
- const [transformedX, transformedY] = applyToPoint16(transform, [
3014
+ const [transformedX, transformedY] = applyToPoint17(transform, [
2697
3015
  center.x,
2698
3016
  center.y
2699
3017
  ]);
@@ -2721,7 +3039,7 @@ function createSvgObjectsFromPcbSilkscreenCircle(pcbSilkscreenCircle, ctx) {
2721
3039
  }
2722
3040
 
2723
3041
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-line.ts
2724
- import { applyToPoint as applyToPoint17 } from "transformation-matrix";
3042
+ import { applyToPoint as applyToPoint18 } from "transformation-matrix";
2725
3043
  function createSvgObjectsFromPcbSilkscreenLine(pcbSilkscreenLine, ctx) {
2726
3044
  const { transform, layer: layerFilter, colorMap: colorMap2 } = ctx;
2727
3045
  const {
@@ -2738,8 +3056,8 @@ function createSvgObjectsFromPcbSilkscreenLine(pcbSilkscreenLine, ctx) {
2738
3056
  console.error("Invalid coordinates:", { x1, y1, x2, y2 });
2739
3057
  return [];
2740
3058
  }
2741
- const [transformedX1, transformedY1] = applyToPoint17(transform, [x1, y1]);
2742
- const [transformedX2, transformedY2] = applyToPoint17(transform, [x2, y2]);
3059
+ const [transformedX1, transformedY1] = applyToPoint18(transform, [x1, y1]);
3060
+ const [transformedX2, transformedY2] = applyToPoint18(transform, [x2, y2]);
2743
3061
  const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
2744
3062
  const color = layer === "bottom" ? colorMap2.silkscreen.bottom : colorMap2.silkscreen.top;
2745
3063
  return [
@@ -2765,7 +3083,7 @@ function createSvgObjectsFromPcbSilkscreenLine(pcbSilkscreenLine, ctx) {
2765
3083
  }
2766
3084
 
2767
3085
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-courtyard-rect.ts
2768
- import { applyToPoint as applyToPoint18 } from "transformation-matrix";
3086
+ import { applyToPoint as applyToPoint19 } from "transformation-matrix";
2769
3087
  function createSvgObjectsFromPcbCourtyardRect(pcbCourtyardRect, ctx) {
2770
3088
  const { transform, layer: layerFilter, colorMap: colorMap2 } = ctx;
2771
3089
  const {
@@ -2784,7 +3102,7 @@ function createSvgObjectsFromPcbCourtyardRect(pcbCourtyardRect, ctx) {
2784
3102
  });
2785
3103
  return [];
2786
3104
  }
2787
- const [transformedX, transformedY] = applyToPoint18(transform, [
3105
+ const [transformedX, transformedY] = applyToPoint19(transform, [
2788
3106
  center.x,
2789
3107
  center.y
2790
3108
  ]);
@@ -2825,66 +3143,7 @@ function pairs(arr) {
2825
3143
  }
2826
3144
 
2827
3145
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-trace.ts
2828
- import { applyToPoint as applyToPoint19 } from "transformation-matrix";
2829
-
2830
- // lib/pcb/colors.ts
2831
- var DEFAULT_PCB_COLOR_MAP = {
2832
- copper: {
2833
- top: "rgb(200, 52, 52)",
2834
- inner1: "rgb(255, 140, 0)",
2835
- inner2: "rgb(255, 215, 0)",
2836
- inner3: "rgb(50, 205, 50)",
2837
- inner4: "rgb(64, 224, 208)",
2838
- inner5: "rgb(138, 43, 226)",
2839
- inner6: "rgb(255, 105, 180)",
2840
- bottom: "rgb(77, 127, 196)"
2841
- },
2842
- soldermaskWithCopperUnderneath: {
2843
- top: "rgb(18, 82, 50)",
2844
- bottom: "rgb(77, 127, 196)"
2845
- },
2846
- soldermask: {
2847
- top: "rgb(12, 55, 33)",
2848
- bottom: "rgb(12, 55, 33)"
2849
- },
2850
- soldermaskOverCopper: {
2851
- top: "rgb(52, 135, 73)",
2852
- bottom: "rgb(52, 135, 73)"
2853
- },
2854
- substrate: "rgb(201, 162, 110)",
2855
- // FR4 substrate color (tan/beige)
2856
- drill: "#FF26E2",
2857
- silkscreen: {
2858
- top: "#f2eda1",
2859
- bottom: "#5da9e9"
2860
- },
2861
- boardOutline: "rgba(255, 255, 255, 0.5)",
2862
- courtyard: "#FF00FF",
2863
- debugComponent: {
2864
- fill: null,
2865
- stroke: null
2866
- }
2867
- };
2868
- var HOLE_COLOR = DEFAULT_PCB_COLOR_MAP.drill;
2869
- var SILKSCREEN_TOP_COLOR = DEFAULT_PCB_COLOR_MAP.silkscreen.top;
2870
- var SILKSCREEN_BOTTOM_COLOR = DEFAULT_PCB_COLOR_MAP.silkscreen.bottom;
2871
-
2872
- // lib/pcb/layer-name-to-color.ts
2873
- var LAYER_NAME_TO_COLOR = {
2874
- ...DEFAULT_PCB_COLOR_MAP.copper
2875
- };
2876
- function layerNameToColor(layerName, colorMap2 = DEFAULT_PCB_COLOR_MAP) {
2877
- return colorMap2.copper[layerName] ?? "white";
2878
- }
2879
- var SOLDER_PASTE_LAYER_NAME_TO_COLOR = {
2880
- bottom: "rgb(105, 105, 105)",
2881
- top: "rgb(105, 105, 105)"
2882
- };
2883
- function solderPasteLayerNameToColor(layerName) {
2884
- return SOLDER_PASTE_LAYER_NAME_TO_COLOR[layerName] ?? "rgb(105, 105, 105)";
2885
- }
2886
-
2887
- // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-trace.ts
3146
+ import { applyToPoint as applyToPoint20 } from "transformation-matrix";
2888
3147
  function createSvgObjectsFromPcbTrace(trace, ctx) {
2889
3148
  const { transform, layer: layerFilter, colorMap: colorMap2, showSolderMask } = ctx;
2890
3149
  if (!trace.route || !Array.isArray(trace.route) || trace.route.length < 2)
@@ -2892,8 +3151,8 @@ function createSvgObjectsFromPcbTrace(trace, ctx) {
2892
3151
  const segments = pairs(trace.route);
2893
3152
  const svgObjects = [];
2894
3153
  for (const [start, end] of segments) {
2895
- const startPoint = applyToPoint19(transform, [start.x, start.y]);
2896
- const endPoint = applyToPoint19(transform, [end.x, end.y]);
3154
+ const startPoint = applyToPoint20(transform, [start.x, start.y]);
3155
+ const endPoint = applyToPoint20(transform, [end.x, end.y]);
2897
3156
  const layer = "layer" in start ? start.layer : "layer" in end ? end.layer : null;
2898
3157
  if (!layer) continue;
2899
3158
  if (layerFilter && layer !== layerFilter) continue;
@@ -2948,7 +3207,7 @@ function createSvgObjectsFromPcbTrace(trace, ctx) {
2948
3207
  }
2949
3208
 
2950
3209
  // lib/pcb/svg-object-fns/create-svg-objects-from-smt-pads.ts
2951
- import { applyToPoint as applyToPoint20 } from "transformation-matrix";
3210
+ import { applyToPoint as applyToPoint21 } from "transformation-matrix";
2952
3211
  function createSvgObjectsFromSmtPad(pad, ctx) {
2953
3212
  const { transform, layer: layerFilter, colorMap: colorMap2, showSolderMask } = ctx;
2954
3213
  if (layerFilter && pad.layer !== layerFilter) return [];
@@ -2959,7 +3218,7 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
2959
3218
  if (pad.shape === "rect" || pad.shape === "rotated_rect") {
2960
3219
  const width = pad.width * Math.abs(transform.a);
2961
3220
  const height = pad.height * Math.abs(transform.d);
2962
- const [x, y] = applyToPoint20(transform, [pad.x, pad.y]);
3221
+ const [x, y] = applyToPoint21(transform, [pad.x, pad.y]);
2963
3222
  const cornerRadiusValue = pad.corner_radius ?? pad.rect_border_radius ?? 0;
2964
3223
  const scaledBorderRadius = cornerRadiusValue * Math.abs(transform.a);
2965
3224
  if (pad.shape === "rotated_rect" && pad.ccw_rotation) {
@@ -3201,7 +3460,7 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
3201
3460
  const width = pad.width * Math.abs(transform.a);
3202
3461
  const height = pad.height * Math.abs(transform.d);
3203
3462
  const radius = pad.radius * Math.abs(transform.a);
3204
- const [x, y] = applyToPoint20(transform, [pad.x, pad.y]);
3463
+ const [x, y] = applyToPoint21(transform, [pad.x, pad.y]);
3205
3464
  const rotationTransformAttributes = isRotated ? {
3206
3465
  transform: `translate(${x} ${y}) rotate(${-(pad.ccw_rotation ?? 0)})`
3207
3466
  } : void 0;
@@ -3319,7 +3578,7 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
3319
3578
  }
3320
3579
  if (pad.shape === "circle") {
3321
3580
  const radius = pad.radius * Math.abs(transform.a);
3322
- const [x, y] = applyToPoint20(transform, [pad.x, pad.y]);
3581
+ const [x, y] = applyToPoint21(transform, [pad.x, pad.y]);
3323
3582
  const padElement = {
3324
3583
  name: "circle",
3325
3584
  type: "element",
@@ -3409,7 +3668,7 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
3409
3668
  }
3410
3669
  if (pad.shape === "polygon") {
3411
3670
  const points = (pad.points ?? []).map(
3412
- (point) => applyToPoint20(transform, [point.x, point.y])
3671
+ (point) => applyToPoint21(transform, [point.x, point.y])
3413
3672
  );
3414
3673
  const padElement = {
3415
3674
  name: "polygon",
@@ -3434,10 +3693,10 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
3434
3693
  maskPoints = points.map(([px, py]) => {
3435
3694
  const dx = px - centroidX;
3436
3695
  const dy = py - centroidY;
3437
- const distance3 = Math.sqrt(dx * dx + dy * dy);
3438
- if (distance3 === 0) return [px, py];
3439
- const normalizedDx = dx / distance3;
3440
- const normalizedDy = dy / distance3;
3696
+ const distance4 = Math.sqrt(dx * dx + dy * dy);
3697
+ if (distance4 === 0) return [px, py];
3698
+ const normalizedDx = dx / distance4;
3699
+ const normalizedDy = dy / distance4;
3441
3700
  return [
3442
3701
  px + normalizedDx * soldermaskMargin,
3443
3702
  py + normalizedDy * soldermaskMargin
@@ -3508,190 +3767,513 @@ function createSvgObjectsFromSmtPad(pad, ctx) {
3508
3767
  }
3509
3768
 
3510
3769
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-board.ts
3511
- import { applyToPoint as applyToPoint21 } from "transformation-matrix";
3512
- function createSvgObjectsFromPcbBoard(pcbBoard, ctx) {
3513
- const { transform, colorMap: colorMap2, showSolderMask } = ctx;
3514
- const { width, height, center, outline } = pcbBoard;
3515
- let path;
3516
- if (outline && Array.isArray(outline) && outline.length >= 3) {
3517
- path = outline.map((point, index) => {
3518
- const [x, y] = applyToPoint21(transform, [point.x, point.y]);
3519
- return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
3520
- }).join(" ");
3521
- } else {
3522
- const halfWidth = width / 2;
3523
- const halfHeight = height / 2;
3524
- const topLeft = applyToPoint21(transform, [
3525
- center.x - halfWidth,
3526
- center.y - halfHeight
3527
- ]);
3528
- const topRight = applyToPoint21(transform, [
3529
- center.x + halfWidth,
3530
- center.y - halfHeight
3531
- ]);
3532
- const bottomRight = applyToPoint21(transform, [
3533
- center.x + halfWidth,
3534
- center.y + halfHeight
3535
- ]);
3536
- const bottomLeft = applyToPoint21(transform, [
3537
- center.x - halfWidth,
3538
- center.y + halfHeight
3539
- ]);
3540
- path = `M ${topLeft[0]} ${topLeft[1]} L ${topRight[0]} ${topRight[1]} L ${bottomRight[0]} ${bottomRight[1]} L ${bottomLeft[0]} ${bottomLeft[1]}`;
3541
- }
3542
- path += " Z";
3543
- const svgObjects = [];
3544
- if (showSolderMask) {
3545
- const layer = ctx.layer ?? "top";
3546
- const maskLayer = layer === "bottom" ? "soldermask-bottom" : "soldermask-top";
3547
- svgObjects.push({
3548
- name: "path",
3549
- type: "element",
3550
- value: "",
3551
- children: [],
3552
- attributes: {
3553
- class: "pcb-board-soldermask",
3554
- d: path,
3555
- fill: colorMap2.soldermask.top,
3556
- "fill-opacity": "0.8",
3557
- stroke: "none",
3558
- "data-type": "pcb_soldermask",
3559
- "data-pcb-layer": maskLayer
3560
- }
3561
- });
3562
- }
3563
- svgObjects.push({
3564
- name: "path",
3565
- type: "element",
3566
- value: "",
3567
- children: [],
3568
- attributes: {
3569
- class: "pcb-board",
3570
- d: path,
3571
- fill: "none",
3572
- stroke: colorMap2.boardOutline,
3573
- "stroke-width": (0.1 * Math.abs(transform.a)).toString(),
3574
- "data-type": "pcb_board",
3575
- "data-pcb-layer": "board"
3576
- }
3577
- });
3578
- return svgObjects;
3579
- }
3770
+ import { applyToPoint as applyToPoint23 } from "transformation-matrix";
3580
3771
 
3581
- // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-panel.ts
3772
+ // lib/utils/create-pcb-component-anchor-offset-indicators.ts
3582
3773
  import { applyToPoint as applyToPoint22 } from "transformation-matrix";
3583
- function createSvgObjectsFromPcbPanel(pcbPanel, ctx) {
3584
- const { transform, colorMap: colorMap2, showSolderMask } = ctx;
3585
- const width = Number(pcbPanel.width);
3586
- const height = Number(pcbPanel.height);
3587
- const center = pcbPanel.center ?? { x: width / 2, y: height / 2 };
3588
- const halfWidth = width / 2;
3589
- const halfHeight = height / 2;
3590
- const topLeft = applyToPoint22(transform, [
3591
- center.x - halfWidth,
3592
- center.y - halfHeight
3593
- ]);
3594
- const topRight = applyToPoint22(transform, [
3595
- center.x + halfWidth,
3596
- center.y - halfHeight
3597
- ]);
3598
- const bottomRight = applyToPoint22(transform, [
3599
- center.x + halfWidth,
3600
- center.y + halfHeight
3774
+ var OFFSET_THRESHOLD_MM = 0.01;
3775
+ var TICK_SIZE_PX = 4;
3776
+ var LABEL_GAP_PX = 8;
3777
+ var LABEL_FONT_SIZE_PX = 11;
3778
+ var STROKE_WIDTH_PX = 1;
3779
+ var ANCHOR_MARKER_SIZE_PX = 5;
3780
+ var ANCHOR_MARKER_STROKE_WIDTH_PX = 1.5;
3781
+ var COMPONENT_GAP_PX = 15;
3782
+ var COMPONENT_SIDE_GAP_PX = 10;
3783
+ var DISTANCE_MULTIPLIER = 0.2;
3784
+ var MAX_OFFSET_PX = 50;
3785
+ function createAnchorOffsetIndicators(params) {
3786
+ const {
3787
+ groupAnchorPosition,
3788
+ componentPosition,
3789
+ transform,
3790
+ componentWidth = 0,
3791
+ componentHeight = 0
3792
+ } = params;
3793
+ const objects = [];
3794
+ const [screenGroupAnchorX, screenGroupAnchorY] = applyToPoint22(transform, [
3795
+ groupAnchorPosition.x,
3796
+ groupAnchorPosition.y
3601
3797
  ]);
3602
- const bottomLeft = applyToPoint22(transform, [
3603
- center.x - halfWidth,
3604
- center.y + halfHeight
3798
+ const [screenComponentX, screenComponentY] = applyToPoint22(transform, [
3799
+ componentPosition.x,
3800
+ componentPosition.y
3605
3801
  ]);
3606
- const path = `M ${topLeft[0]} ${topLeft[1]} L ${topRight[0]} ${topRight[1]} L ${bottomRight[0]} ${bottomRight[1]} L ${bottomLeft[0]} ${bottomLeft[1]} Z`;
3607
- const isCoveredWithSolderMask = pcbPanel.covered_with_solder_mask !== false;
3608
- const shouldShowSolderMask = Boolean(
3609
- showSolderMask && isCoveredWithSolderMask
3802
+ const offsetX = componentPosition.x - groupAnchorPosition.x;
3803
+ const offsetY = componentPosition.y - groupAnchorPosition.y;
3804
+ const scale10 = Math.abs(transform.a);
3805
+ const screenComponentWidth = componentWidth * scale10;
3806
+ const screenComponentHeight = componentHeight * scale10;
3807
+ objects.push(createAnchorMarker(screenGroupAnchorX, screenGroupAnchorY));
3808
+ objects.push({
3809
+ name: "line",
3810
+ type: "element",
3811
+ attributes: {
3812
+ x1: screenGroupAnchorX.toString(),
3813
+ y1: screenGroupAnchorY.toString(),
3814
+ x2: screenComponentX.toString(),
3815
+ y2: screenComponentY.toString(),
3816
+ stroke: "#ffffff",
3817
+ "stroke-width": "0.5",
3818
+ "stroke-dasharray": "3,3",
3819
+ opacity: "0.5",
3820
+ class: "anchor-offset-connector"
3821
+ },
3822
+ children: [],
3823
+ value: ""
3824
+ });
3825
+ objects.push({
3826
+ name: "circle",
3827
+ type: "element",
3828
+ attributes: {
3829
+ cx: screenComponentX.toString(),
3830
+ cy: screenComponentY.toString(),
3831
+ r: "2",
3832
+ fill: "#ffffff",
3833
+ opacity: "0.7",
3834
+ class: "anchor-offset-component-marker"
3835
+ },
3836
+ children: [],
3837
+ value: ""
3838
+ });
3839
+ const yDistance = Math.abs(screenComponentY - screenGroupAnchorY);
3840
+ const xDistance = Math.abs(screenComponentX - screenGroupAnchorX);
3841
+ const totalDistance = Math.sqrt(xDistance * xDistance + yDistance * yDistance);
3842
+ const componentHeightOffset = screenComponentHeight / 2 + COMPONENT_GAP_PX;
3843
+ const dynamicOffset = Math.max(
3844
+ componentHeightOffset,
3845
+ Math.min(MAX_OFFSET_PX, totalDistance * DISTANCE_MULTIPLIER)
3610
3846
  );
3611
- return [
3612
- {
3613
- name: "path",
3614
- type: "element",
3615
- value: "",
3616
- children: [],
3617
- attributes: {
3618
- class: "pcb-panel",
3619
- d: path,
3620
- fill: "none",
3621
- stroke: colorMap2.boardOutline,
3622
- "stroke-width": (0.1 * Math.abs(transform.a)).toString(),
3623
- "data-type": "pcb_panel",
3624
- "data-pcb-layer": "board"
3625
- }
3626
- }
3627
- ];
3847
+ const horizontalLineY = offsetY > 0 ? screenComponentY - dynamicOffset : screenComponentY + dynamicOffset;
3848
+ const componentWidthOffset = screenComponentWidth / 2 + COMPONENT_SIDE_GAP_PX;
3849
+ const verticalLineX = offsetX > 0 ? screenComponentX + componentWidthOffset : screenComponentX - componentWidthOffset;
3850
+ if (Math.abs(offsetX) > OFFSET_THRESHOLD_MM) {
3851
+ objects.push(
3852
+ ...createHorizontalDimension({
3853
+ startX: screenGroupAnchorX,
3854
+ endX: screenComponentX,
3855
+ y: horizontalLineY,
3856
+ offsetMm: offsetX,
3857
+ offsetY
3858
+ })
3859
+ );
3860
+ }
3861
+ if (Math.abs(offsetY) > OFFSET_THRESHOLD_MM) {
3862
+ objects.push(
3863
+ ...createVerticalDimension({
3864
+ x: verticalLineX,
3865
+ startY: screenGroupAnchorY,
3866
+ endY: screenComponentY,
3867
+ offsetMm: offsetY,
3868
+ offsetX
3869
+ })
3870
+ );
3871
+ }
3872
+ return objects;
3628
3873
  }
3629
-
3630
- // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-via.ts
3631
- import { applyToPoint as applyToPoint23 } from "transformation-matrix";
3632
- function createSvgObjectsFromPcbVia(hole, ctx) {
3633
- const { transform, colorMap: colorMap2 } = ctx;
3634
- const [x, y] = applyToPoint23(transform, [hole.x, hole.y]);
3635
- const scaledOuterWidth = hole.outer_diameter * Math.abs(transform.a);
3636
- const scaledOuterHeight = hole.outer_diameter * Math.abs(transform.a);
3637
- const scaledHoleWidth = hole.hole_diameter * Math.abs(transform.a);
3638
- const scaledHoleHeight = hole.hole_diameter * Math.abs(transform.a);
3639
- const outerRadius = Math.min(scaledOuterWidth, scaledOuterHeight) / 2;
3640
- const innerRadius = Math.min(scaledHoleWidth, scaledHoleHeight) / 2;
3874
+ function createAnchorMarker(x, y) {
3641
3875
  return {
3642
3876
  name: "g",
3643
3877
  type: "element",
3644
3878
  attributes: {
3645
- "data-type": "pcb_via",
3646
- "data-pcb-layer": "through"
3879
+ class: "anchor-offset-marker",
3880
+ "data-type": "anchor_offset_marker"
3647
3881
  },
3648
3882
  children: [
3649
3883
  {
3650
- name: "circle",
3884
+ name: "line",
3651
3885
  type: "element",
3652
3886
  attributes: {
3653
- class: "pcb-hole-outer",
3654
- fill: colorMap2.copper.top,
3655
- cx: x.toString(),
3656
- cy: y.toString(),
3657
- r: outerRadius.toString(),
3658
- "data-type": "pcb_via",
3659
- "data-pcb-layer": "top"
3660
- }
3887
+ x1: x.toString(),
3888
+ y1: (y - ANCHOR_MARKER_SIZE_PX).toString(),
3889
+ x2: x.toString(),
3890
+ y2: (y + ANCHOR_MARKER_SIZE_PX).toString(),
3891
+ stroke: "#ffffff",
3892
+ "stroke-width": ANCHOR_MARKER_STROKE_WIDTH_PX.toString(),
3893
+ "stroke-linecap": "round"
3894
+ },
3895
+ children: [],
3896
+ value: ""
3661
3897
  },
3662
3898
  {
3663
- name: "circle",
3899
+ name: "line",
3664
3900
  type: "element",
3665
3901
  attributes: {
3666
- class: "pcb-hole-inner",
3667
- fill: colorMap2.drill,
3668
- cx: x.toString(),
3669
- cy: y.toString(),
3670
- r: innerRadius.toString(),
3671
- "data-type": "pcb_via",
3672
- "data-pcb-layer": "drill"
3673
- }
3902
+ x1: (x - ANCHOR_MARKER_SIZE_PX).toString(),
3903
+ y1: y.toString(),
3904
+ x2: (x + ANCHOR_MARKER_SIZE_PX).toString(),
3905
+ y2: y.toString(),
3906
+ stroke: "#ffffff",
3907
+ "stroke-width": ANCHOR_MARKER_STROKE_WIDTH_PX.toString(),
3908
+ "stroke-linecap": "round"
3909
+ },
3910
+ children: [],
3911
+ value: ""
3674
3912
  }
3675
- ]
3913
+ ],
3914
+ value: ""
3676
3915
  };
3677
3916
  }
3678
-
3679
- // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-hole.ts
3680
- import { applyToPoint as applyToPoint24 } from "transformation-matrix";
3681
- function createSvgObjectsFromPcbHole(hole, ctx) {
3682
- const { transform, colorMap: colorMap2, showSolderMask } = ctx;
3683
- const layer = ctx.layer ?? "top";
3684
- const [x, y] = applyToPoint24(transform, [hole.x, hole.y]);
3685
- const isCoveredWithSolderMask = Boolean(hole.is_covered_with_solder_mask);
3686
- const soldermaskMargin = (hole.soldermask_margin ?? 0) * Math.abs(transform.a);
3687
- const shouldShowSolderMask = showSolderMask && isCoveredWithSolderMask && soldermaskMargin !== 0;
3688
- const solderMaskColor = colorMap2.soldermask.top;
3689
- if (hole.hole_shape === "circle" || hole.hole_shape === "square") {
3690
- const scaledDiameter = hole.hole_diameter * Math.abs(transform.a);
3691
- const radius = scaledDiameter / 2;
3692
- if (hole.hole_shape === "circle") {
3693
- const holeElement2 = {
3694
- name: "circle",
3917
+ function createHorizontalDimension({
3918
+ startX,
3919
+ endX,
3920
+ y,
3921
+ offsetMm,
3922
+ offsetY
3923
+ }) {
3924
+ const objects = [];
3925
+ objects.push({
3926
+ name: "line",
3927
+ type: "element",
3928
+ attributes: {
3929
+ x1: startX.toString(),
3930
+ y1: y.toString(),
3931
+ x2: endX.toString(),
3932
+ y2: y.toString(),
3933
+ stroke: "#ffffff",
3934
+ "stroke-width": STROKE_WIDTH_PX.toString(),
3935
+ class: "anchor-offset-dimension-x"
3936
+ },
3937
+ children: [],
3938
+ value: ""
3939
+ });
3940
+ objects.push({
3941
+ name: "line",
3942
+ type: "element",
3943
+ attributes: {
3944
+ x1: startX.toString(),
3945
+ y1: (y - TICK_SIZE_PX).toString(),
3946
+ x2: startX.toString(),
3947
+ y2: (y + TICK_SIZE_PX).toString(),
3948
+ stroke: "#ffffff",
3949
+ "stroke-width": STROKE_WIDTH_PX.toString()
3950
+ },
3951
+ children: [],
3952
+ value: ""
3953
+ });
3954
+ objects.push({
3955
+ name: "line",
3956
+ type: "element",
3957
+ attributes: {
3958
+ x1: endX.toString(),
3959
+ y1: (y - TICK_SIZE_PX).toString(),
3960
+ x2: endX.toString(),
3961
+ y2: (y + TICK_SIZE_PX).toString(),
3962
+ stroke: "#ffffff",
3963
+ "stroke-width": STROKE_WIDTH_PX.toString()
3964
+ },
3965
+ children: [],
3966
+ value: ""
3967
+ });
3968
+ const midX = (startX + endX) / 2;
3969
+ const labelY = offsetY > 0 ? y - TICK_SIZE_PX - LABEL_GAP_PX : y + TICK_SIZE_PX + LABEL_GAP_PX;
3970
+ objects.push({
3971
+ name: "text",
3972
+ type: "element",
3973
+ attributes: {
3974
+ x: midX.toString(),
3975
+ y: labelY.toString(),
3976
+ fill: "#ffffff",
3977
+ "font-size": LABEL_FONT_SIZE_PX.toString(),
3978
+ "font-family": "Arial, sans-serif",
3979
+ "text-anchor": "middle",
3980
+ "dominant-baseline": offsetY > 0 ? "baseline" : "hanging",
3981
+ class: "anchor-offset-label"
3982
+ },
3983
+ children: [
3984
+ {
3985
+ type: "text",
3986
+ value: `X: ${offsetMm.toFixed(2)}mm`,
3987
+ name: "",
3988
+ attributes: {},
3989
+ children: []
3990
+ }
3991
+ ],
3992
+ value: ""
3993
+ });
3994
+ return objects;
3995
+ }
3996
+ function createVerticalDimension({
3997
+ x,
3998
+ startY,
3999
+ endY,
4000
+ offsetMm,
4001
+ offsetX
4002
+ }) {
4003
+ const objects = [];
4004
+ objects.push({
4005
+ name: "line",
4006
+ type: "element",
4007
+ attributes: {
4008
+ x1: x.toString(),
4009
+ y1: startY.toString(),
4010
+ x2: x.toString(),
4011
+ y2: endY.toString(),
4012
+ stroke: "#ffffff",
4013
+ "stroke-width": STROKE_WIDTH_PX.toString(),
4014
+ class: "anchor-offset-dimension-y"
4015
+ },
4016
+ children: [],
4017
+ value: ""
4018
+ });
4019
+ objects.push({
4020
+ name: "line",
4021
+ type: "element",
4022
+ attributes: {
4023
+ x1: (x - TICK_SIZE_PX).toString(),
4024
+ y1: startY.toString(),
4025
+ x2: (x + TICK_SIZE_PX).toString(),
4026
+ y2: startY.toString(),
4027
+ stroke: "#ffffff",
4028
+ "stroke-width": STROKE_WIDTH_PX.toString()
4029
+ },
4030
+ children: [],
4031
+ value: ""
4032
+ });
4033
+ objects.push({
4034
+ name: "line",
4035
+ type: "element",
4036
+ attributes: {
4037
+ x1: (x - TICK_SIZE_PX).toString(),
4038
+ y1: endY.toString(),
4039
+ x2: (x + TICK_SIZE_PX).toString(),
4040
+ y2: endY.toString(),
4041
+ stroke: "#ffffff",
4042
+ "stroke-width": STROKE_WIDTH_PX.toString()
4043
+ },
4044
+ children: [],
4045
+ value: ""
4046
+ });
4047
+ const midY = (startY + endY) / 2;
4048
+ const labelX = offsetX < 0 ? x - TICK_SIZE_PX - 4 : x + TICK_SIZE_PX + 4;
4049
+ objects.push({
4050
+ name: "text",
4051
+ type: "element",
4052
+ attributes: {
4053
+ x: labelX.toString(),
4054
+ y: midY.toString(),
4055
+ fill: "#ffffff",
4056
+ "font-size": LABEL_FONT_SIZE_PX.toString(),
4057
+ "font-family": "Arial, sans-serif",
4058
+ "text-anchor": offsetX < 0 ? "end" : "start",
4059
+ "dominant-baseline": "middle",
4060
+ class: "anchor-offset-label"
4061
+ },
4062
+ children: [
4063
+ {
4064
+ type: "text",
4065
+ value: `Y: ${offsetMm.toFixed(2)}mm`,
4066
+ name: "",
4067
+ attributes: {},
4068
+ children: []
4069
+ }
4070
+ ],
4071
+ value: ""
4072
+ });
4073
+ return objects;
4074
+ }
4075
+
4076
+ // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-board.ts
4077
+ function createSvgObjectsFromPcbBoard(pcbBoard, ctx) {
4078
+ const { transform, colorMap: colorMap2, showSolderMask, circuitJson } = ctx;
4079
+ const { width, height, center, outline } = pcbBoard;
4080
+ let path;
4081
+ if (outline && Array.isArray(outline) && outline.length >= 3) {
4082
+ path = outline.map((point, index) => {
4083
+ const [x, y] = applyToPoint23(transform, [point.x, point.y]);
4084
+ return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
4085
+ }).join(" ");
4086
+ } else {
4087
+ const halfWidth = width / 2;
4088
+ const halfHeight = height / 2;
4089
+ const topLeft = applyToPoint23(transform, [
4090
+ center.x - halfWidth,
4091
+ center.y - halfHeight
4092
+ ]);
4093
+ const topRight = applyToPoint23(transform, [
4094
+ center.x + halfWidth,
4095
+ center.y - halfHeight
4096
+ ]);
4097
+ const bottomRight = applyToPoint23(transform, [
4098
+ center.x + halfWidth,
4099
+ center.y + halfHeight
4100
+ ]);
4101
+ const bottomLeft = applyToPoint23(transform, [
4102
+ center.x - halfWidth,
4103
+ center.y + halfHeight
4104
+ ]);
4105
+ path = `M ${topLeft[0]} ${topLeft[1]} L ${topRight[0]} ${topRight[1]} L ${bottomRight[0]} ${bottomRight[1]} L ${bottomLeft[0]} ${bottomLeft[1]}`;
4106
+ }
4107
+ path += " Z";
4108
+ const svgObjects = [];
4109
+ if (showSolderMask) {
4110
+ const layer = ctx.layer ?? "top";
4111
+ const maskLayer = layer === "bottom" ? "soldermask-bottom" : "soldermask-top";
4112
+ svgObjects.push({
4113
+ name: "path",
4114
+ type: "element",
4115
+ value: "",
4116
+ children: [],
4117
+ attributes: {
4118
+ class: "pcb-board-soldermask",
4119
+ d: path,
4120
+ fill: colorMap2.soldermask.top,
4121
+ "fill-opacity": "0.8",
4122
+ stroke: "none",
4123
+ "data-type": "pcb_soldermask",
4124
+ "data-pcb-layer": maskLayer
4125
+ }
4126
+ });
4127
+ }
4128
+ svgObjects.push({
4129
+ name: "path",
4130
+ type: "element",
4131
+ value: "",
4132
+ children: [],
4133
+ attributes: {
4134
+ class: "pcb-board",
4135
+ d: path,
4136
+ fill: "none",
4137
+ stroke: colorMap2.boardOutline,
4138
+ "stroke-width": (0.1 * Math.abs(transform.a)).toString(),
4139
+ "data-type": "pcb_board",
4140
+ "data-pcb-layer": "board"
4141
+ }
4142
+ });
4143
+ if (ctx.showAnchorOffsets && circuitJson) {
4144
+ const panel = circuitJson.find(
4145
+ (elm) => elm.type === "pcb_panel"
4146
+ );
4147
+ if (panel) {
4148
+ const panelCenter = panel.center ?? { x: 0, y: 0 };
4149
+ svgObjects.push(
4150
+ ...createAnchorOffsetIndicators({
4151
+ groupAnchorPosition: panelCenter,
4152
+ componentPosition: center,
4153
+ transform,
4154
+ componentWidth: width,
4155
+ componentHeight: height
4156
+ })
4157
+ );
4158
+ }
4159
+ }
4160
+ return svgObjects;
4161
+ }
4162
+
4163
+ // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-panel.ts
4164
+ import { applyToPoint as applyToPoint24 } from "transformation-matrix";
4165
+ function createSvgObjectsFromPcbPanel(pcbPanel, ctx) {
4166
+ const { transform, colorMap: colorMap2, showSolderMask } = ctx;
4167
+ const width = Number(pcbPanel.width);
4168
+ const height = Number(pcbPanel.height);
4169
+ const center = pcbPanel.center ?? { x: width / 2, y: height / 2 };
4170
+ const halfWidth = width / 2;
4171
+ const halfHeight = height / 2;
4172
+ const topLeft = applyToPoint24(transform, [
4173
+ center.x - halfWidth,
4174
+ center.y - halfHeight
4175
+ ]);
4176
+ const topRight = applyToPoint24(transform, [
4177
+ center.x + halfWidth,
4178
+ center.y - halfHeight
4179
+ ]);
4180
+ const bottomRight = applyToPoint24(transform, [
4181
+ center.x + halfWidth,
4182
+ center.y + halfHeight
4183
+ ]);
4184
+ const bottomLeft = applyToPoint24(transform, [
4185
+ center.x - halfWidth,
4186
+ center.y + halfHeight
4187
+ ]);
4188
+ const path = `M ${topLeft[0]} ${topLeft[1]} L ${topRight[0]} ${topRight[1]} L ${bottomRight[0]} ${bottomRight[1]} L ${bottomLeft[0]} ${bottomLeft[1]} Z`;
4189
+ const isCoveredWithSolderMask = pcbPanel.covered_with_solder_mask !== false;
4190
+ const shouldShowSolderMask = Boolean(
4191
+ showSolderMask && isCoveredWithSolderMask
4192
+ );
4193
+ return [
4194
+ {
4195
+ name: "path",
4196
+ type: "element",
4197
+ value: "",
4198
+ children: [],
4199
+ attributes: {
4200
+ class: "pcb-panel",
4201
+ d: path,
4202
+ fill: "none",
4203
+ stroke: colorMap2.boardOutline,
4204
+ "stroke-width": (0.1 * Math.abs(transform.a)).toString(),
4205
+ "data-type": "pcb_panel",
4206
+ "data-pcb-layer": "board"
4207
+ }
4208
+ }
4209
+ ];
4210
+ }
4211
+
4212
+ // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-via.ts
4213
+ import { applyToPoint as applyToPoint25 } from "transformation-matrix";
4214
+ function createSvgObjectsFromPcbVia(hole, ctx) {
4215
+ const { transform, colorMap: colorMap2 } = ctx;
4216
+ const [x, y] = applyToPoint25(transform, [hole.x, hole.y]);
4217
+ const scaledOuterWidth = hole.outer_diameter * Math.abs(transform.a);
4218
+ const scaledOuterHeight = hole.outer_diameter * Math.abs(transform.a);
4219
+ const scaledHoleWidth = hole.hole_diameter * Math.abs(transform.a);
4220
+ const scaledHoleHeight = hole.hole_diameter * Math.abs(transform.a);
4221
+ const outerRadius = Math.min(scaledOuterWidth, scaledOuterHeight) / 2;
4222
+ const innerRadius = Math.min(scaledHoleWidth, scaledHoleHeight) / 2;
4223
+ return {
4224
+ name: "g",
4225
+ type: "element",
4226
+ attributes: {
4227
+ "data-type": "pcb_via",
4228
+ "data-pcb-layer": "through"
4229
+ },
4230
+ children: [
4231
+ {
4232
+ name: "circle",
4233
+ type: "element",
4234
+ attributes: {
4235
+ class: "pcb-hole-outer",
4236
+ fill: colorMap2.copper.top,
4237
+ cx: x.toString(),
4238
+ cy: y.toString(),
4239
+ r: outerRadius.toString(),
4240
+ "data-type": "pcb_via",
4241
+ "data-pcb-layer": "top"
4242
+ }
4243
+ },
4244
+ {
4245
+ name: "circle",
4246
+ type: "element",
4247
+ attributes: {
4248
+ class: "pcb-hole-inner",
4249
+ fill: colorMap2.drill,
4250
+ cx: x.toString(),
4251
+ cy: y.toString(),
4252
+ r: innerRadius.toString(),
4253
+ "data-type": "pcb_via",
4254
+ "data-pcb-layer": "drill"
4255
+ }
4256
+ }
4257
+ ]
4258
+ };
4259
+ }
4260
+
4261
+ // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-hole.ts
4262
+ import { applyToPoint as applyToPoint26 } from "transformation-matrix";
4263
+ function createSvgObjectsFromPcbHole(hole, ctx) {
4264
+ const { transform, colorMap: colorMap2, showSolderMask } = ctx;
4265
+ const layer = ctx.layer ?? "top";
4266
+ const [x, y] = applyToPoint26(transform, [hole.x, hole.y]);
4267
+ const isCoveredWithSolderMask = Boolean(hole.is_covered_with_solder_mask);
4268
+ const soldermaskMargin = (hole.soldermask_margin ?? 0) * Math.abs(transform.a);
4269
+ const shouldShowSolderMask = showSolderMask && isCoveredWithSolderMask && soldermaskMargin !== 0;
4270
+ const solderMaskColor = colorMap2.soldermask.top;
4271
+ if (hole.hole_shape === "circle" || hole.hole_shape === "square") {
4272
+ const scaledDiameter = hole.hole_diameter * Math.abs(transform.a);
4273
+ const radius = scaledDiameter / 2;
4274
+ if (hole.hole_shape === "circle") {
4275
+ const holeElement2 = {
4276
+ name: "circle",
3695
4277
  type: "element",
3696
4278
  attributes: {
3697
4279
  class: "pcb-hole",
@@ -4178,7 +4760,7 @@ import {
4178
4760
  getFullConnectivityMapFromCircuitJson
4179
4761
  } from "circuit-json-to-connectivity-map";
4180
4762
  import "svgson";
4181
- import { applyToPoint as applyToPoint25 } from "transformation-matrix";
4763
+ import { applyToPoint as applyToPoint27 } from "transformation-matrix";
4182
4764
 
4183
4765
  // lib/pcb/create-svg-objects-from-pcb-rats-nest/get-element-position.ts
4184
4766
  import { su } from "@tscircuit/circuit-json-util";
@@ -4205,9 +4787,9 @@ var findNearestPointInNet = (sourcePoint, netId, connectivity, circuitJson) => {
4205
4787
  if (pos) {
4206
4788
  const dx = sourcePoint.x - pos.x;
4207
4789
  const dy = sourcePoint.y - pos.y;
4208
- const distance3 = Math.sqrt(dx * dx + dy * dy);
4209
- if (distance3 > 0 && distance3 < minDistance) {
4210
- minDistance = distance3;
4790
+ const distance4 = Math.sqrt(dx * dx + dy * dy);
4791
+ if (distance4 > 0 && distance4 < minDistance) {
4792
+ minDistance = distance4;
4211
4793
  nearestPoint = pos;
4212
4794
  }
4213
4795
  }
@@ -4258,11 +4840,11 @@ function createSvgObjectsForRatsNest(circuitJson, ctx) {
4258
4840
  });
4259
4841
  const svgObjects = [];
4260
4842
  for (const line of ratsNestLines) {
4261
- const transformedStart = applyToPoint25(transform, [
4843
+ const transformedStart = applyToPoint27(transform, [
4262
4844
  line.startPoint.x,
4263
4845
  line.startPoint.y
4264
4846
  ]);
4265
- const transformedEnd = applyToPoint25(transform, [
4847
+ const transformedEnd = applyToPoint27(transform, [
4266
4848
  line.endPoint.x,
4267
4849
  line.endPoint.y
4268
4850
  ]);
@@ -4290,17 +4872,17 @@ function createSvgObjectsForRatsNest(circuitJson, ctx) {
4290
4872
 
4291
4873
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-cutout.ts
4292
4874
  import {
4293
- applyToPoint as applyToPoint26,
4294
- compose as compose3,
4295
- rotate as rotate3,
4296
- translate as translate3,
4297
- toString as matrixToString6
4875
+ applyToPoint as applyToPoint28,
4876
+ compose as compose4,
4877
+ rotate as rotate4,
4878
+ translate as translate4,
4879
+ toString as matrixToString7
4298
4880
  } from "transformation-matrix";
4299
4881
  function createSvgObjectsFromPcbCutout(cutout, ctx) {
4300
4882
  const { transform, colorMap: colorMap2 } = ctx;
4301
4883
  if (cutout.shape === "rect") {
4302
4884
  const rectCutout = cutout;
4303
- const [cx, cy] = applyToPoint26(transform, [
4885
+ const [cx, cy] = applyToPoint28(transform, [
4304
4886
  rectCutout.center.x,
4305
4887
  rectCutout.center.y
4306
4888
  ]);
@@ -4318,8 +4900,8 @@ function createSvgObjectsFromPcbCutout(cutout, ctx) {
4318
4900
  width: scaledWidth.toString(),
4319
4901
  height: scaledHeight.toString(),
4320
4902
  fill: colorMap2.drill,
4321
- transform: matrixToString6(
4322
- compose3(translate3(cx, cy), rotate3(svgRotation * Math.PI / 180))
4903
+ transform: matrixToString7(
4904
+ compose4(translate4(cx, cy), rotate4(svgRotation * Math.PI / 180))
4323
4905
  ),
4324
4906
  "data-type": "pcb_cutout",
4325
4907
  "data-pcb-layer": "drill"
@@ -4342,7 +4924,7 @@ function createSvgObjectsFromPcbCutout(cutout, ctx) {
4342
4924
  }
4343
4925
  if (cutout.shape === "circle") {
4344
4926
  const circleCutout = cutout;
4345
- const [cx, cy] = applyToPoint26(transform, [
4927
+ const [cx, cy] = applyToPoint28(transform, [
4346
4928
  circleCutout.center.x,
4347
4929
  circleCutout.center.y
4348
4930
  ]);
@@ -4369,7 +4951,7 @@ function createSvgObjectsFromPcbCutout(cutout, ctx) {
4369
4951
  const polygonCutout = cutout;
4370
4952
  if (!polygonCutout.points || polygonCutout.points.length === 0) return [];
4371
4953
  const transformedPoints = polygonCutout.points.map(
4372
- (p) => applyToPoint26(transform, [p.x, p.y])
4954
+ (p) => applyToPoint28(transform, [p.x, p.y])
4373
4955
  );
4374
4956
  const pointsString = transformedPoints.map((p) => `${p[0]},${p[1]}`).join(" ");
4375
4957
  return [
@@ -4393,19 +4975,19 @@ function createSvgObjectsFromPcbCutout(cutout, ctx) {
4393
4975
 
4394
4976
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-copper-pour.ts
4395
4977
  import {
4396
- applyToPoint as applyToPoint28,
4397
- compose as compose4,
4398
- rotate as rotate4,
4399
- toString as matrixToString7,
4400
- translate as translate4
4978
+ applyToPoint as applyToPoint30,
4979
+ compose as compose5,
4980
+ rotate as rotate5,
4981
+ toString as matrixToString8,
4982
+ translate as translate5
4401
4983
  } from "transformation-matrix";
4402
4984
 
4403
4985
  // lib/utils/ring-to-path-d.ts
4404
- import { applyToPoint as applyToPoint27 } from "transformation-matrix";
4986
+ import { applyToPoint as applyToPoint29 } from "transformation-matrix";
4405
4987
  function ringToPathD(vertices, transform) {
4406
4988
  if (vertices.length === 0) return "";
4407
4989
  const transformedVertices = vertices.map((v) => {
4408
- const [x, y] = applyToPoint27(transform, [v.x, v.y]);
4990
+ const [x, y] = applyToPoint29(transform, [v.x, v.y]);
4409
4991
  return { ...v, x, y };
4410
4992
  });
4411
4993
  let d = `M ${transformedVertices[0].x} ${transformedVertices[0].y}`;
@@ -4494,7 +5076,7 @@ function createSvgObjectsFromPcbCopperPour(pour, ctx) {
4494
5076
  const maskOverlayColor = layer === "bottom" ? colorMap2.soldermaskOverCopper.bottom : colorMap2.soldermaskOverCopper.top;
4495
5077
  const maskOverlayOpacity = "0.9";
4496
5078
  if (pour.shape === "rect") {
4497
- const [cx, cy] = applyToPoint28(transform, [pour.center.x, pour.center.y]);
5079
+ const [cx, cy] = applyToPoint30(transform, [pour.center.x, pour.center.y]);
4498
5080
  const scaledWidth = pour.width * Math.abs(transform.a);
4499
5081
  const scaledHeight = pour.height * Math.abs(transform.d);
4500
5082
  const svgRotation = -(pour.rotation ?? 0);
@@ -4503,8 +5085,8 @@ function createSvgObjectsFromPcbCopperPour(pour, ctx) {
4503
5085
  y: (-scaledHeight / 2).toString(),
4504
5086
  width: scaledWidth.toString(),
4505
5087
  height: scaledHeight.toString(),
4506
- transform: matrixToString7(
4507
- compose4(translate4(cx, cy), rotate4(svgRotation * Math.PI / 180))
5088
+ transform: matrixToString8(
5089
+ compose5(translate5(cx, cy), rotate5(svgRotation * Math.PI / 180))
4508
5090
  )
4509
5091
  };
4510
5092
  const copperRect = {
@@ -4546,7 +5128,7 @@ function createSvgObjectsFromPcbCopperPour(pour, ctx) {
4546
5128
  if (pour.shape === "polygon") {
4547
5129
  if (!pour.points || pour.points.length === 0) return [];
4548
5130
  const transformedPoints = pour.points.map(
4549
- (p) => applyToPoint28(transform, [p.x, p.y])
5131
+ (p) => applyToPoint30(transform, [p.x, p.y])
4550
5132
  );
4551
5133
  const pointsString = transformedPoints.map((p) => `${p[0]},${p[1]}`).join(" ");
4552
5134
  const copperPolygon = {
@@ -4632,454 +5214,148 @@ function createSvgObjectsFromPcbCopperPour(pour, ctx) {
4632
5214
  }
4633
5215
 
4634
5216
  // lib/pcb/svg-object-fns/create-svg-objects-for-pcb-grid.ts
4635
- import "svgson";
4636
- var DEFAULT_GRID_LINE_COLOR = "rgba(255, 255, 255, 0.5)";
4637
- var GRID_PATTERN_ID = "pcb-grid-pattern";
4638
- function createSvgObjectsForPcbGrid({
4639
- grid,
4640
- svgWidth,
4641
- svgHeight
4642
- }) {
4643
- if (!grid) {
4644
- return {};
4645
- }
4646
- const gridLineColor = grid.lineColor ?? DEFAULT_GRID_LINE_COLOR;
4647
- const gridCellSize = grid.cellSize;
4648
- const majorCellSize = grid.majorCellSize;
4649
- const majorLineColor = grid.majorLineColor ?? gridLineColor;
4650
- if (majorCellSize !== void 0) {
4651
- if (!gridCellSize || gridCellSize <= 0) {
4652
- throw new Error("grid.majorCellSize requires a positive grid.cellSize");
4653
- }
4654
- if (majorCellSize <= 0) {
4655
- throw new Error(
4656
- "grid.majorCellSize must be a positive multiple of grid.cellSize"
4657
- );
4658
- }
4659
- const ratio = majorCellSize / gridCellSize;
4660
- const nearestInteger = Math.round(ratio);
4661
- if (!Number.isFinite(ratio) || Math.abs(ratio - nearestInteger) > 1e-6) {
4662
- throw new Error(
4663
- "grid.majorCellSize must be a positive multiple of grid.cellSize"
4664
- );
4665
- }
4666
- }
4667
- if (!gridCellSize || gridCellSize <= 0) {
4668
- return {};
4669
- }
4670
- const hasMajorGrid = majorCellSize !== void 0;
4671
- const patternChildren = hasMajorGrid ? createMajorGridPatternChildren(
4672
- gridCellSize,
4673
- majorCellSize,
4674
- gridLineColor,
4675
- majorLineColor
4676
- ) : [
4677
- {
4678
- name: "path",
4679
- type: "element",
4680
- value: "",
4681
- attributes: {
4682
- d: `M ${gridCellSize} 0 L 0 0 0 ${gridCellSize}`,
4683
- fill: "none",
4684
- stroke: gridLineColor,
4685
- "stroke-width": "1",
4686
- "shape-rendering": "crispEdges"
4687
- },
4688
- children: []
4689
- }
4690
- ];
4691
- const defs = {
4692
- name: "defs",
4693
- type: "element",
4694
- value: "",
4695
- attributes: {},
4696
- children: [
4697
- {
4698
- name: "pattern",
4699
- type: "element",
4700
- value: "",
4701
- attributes: {
4702
- id: GRID_PATTERN_ID,
4703
- width: hasMajorGrid ? majorCellSize.toString() : gridCellSize.toString(),
4704
- height: hasMajorGrid ? majorCellSize.toString() : gridCellSize.toString(),
4705
- patternUnits: "userSpaceOnUse"
4706
- },
4707
- children: patternChildren
4708
- }
4709
- ]
4710
- };
4711
- const rect = {
4712
- name: "rect",
4713
- type: "element",
4714
- value: "",
4715
- attributes: {
4716
- x: "0",
4717
- y: "0",
4718
- width: svgWidth.toString(),
4719
- height: svgHeight.toString(),
4720
- fill: `url(#${GRID_PATTERN_ID})`,
4721
- "pointer-events": "none",
4722
- "data-type": "pcb_grid",
4723
- "data-pcb-layer": "global"
4724
- },
4725
- children: []
4726
- };
4727
- return { defs, rect };
4728
- }
4729
- function createMajorGridPatternChildren(cellSize, majorCellSize, lineColor, majorLineColor) {
4730
- const children = [];
4731
- const steps = Math.round(majorCellSize / cellSize);
4732
- for (let step = 0; step < steps; step += 1) {
4733
- const offset = Number((step * cellSize).toFixed(6));
4734
- const offsetString = offset.toString();
4735
- const color = step === 0 ? majorLineColor : lineColor;
4736
- const majorSizeString = majorCellSize.toString();
4737
- children.push({
4738
- name: "line",
4739
- type: "element",
4740
- value: "",
4741
- attributes: {
4742
- x1: offsetString,
4743
- y1: "0",
4744
- x2: offsetString,
4745
- y2: majorSizeString,
4746
- stroke: color,
4747
- "stroke-width": "1",
4748
- "shape-rendering": "crispEdges"
4749
- },
4750
- children: []
4751
- });
4752
- children.push({
4753
- name: "line",
5217
+ import "svgson";
5218
+ var DEFAULT_GRID_LINE_COLOR = "rgba(255, 255, 255, 0.5)";
5219
+ var GRID_PATTERN_ID = "pcb-grid-pattern";
5220
+ function createSvgObjectsForPcbGrid({
5221
+ grid,
5222
+ svgWidth,
5223
+ svgHeight
5224
+ }) {
5225
+ if (!grid) {
5226
+ return {};
5227
+ }
5228
+ const gridLineColor = grid.lineColor ?? DEFAULT_GRID_LINE_COLOR;
5229
+ const gridCellSize = grid.cellSize;
5230
+ const majorCellSize = grid.majorCellSize;
5231
+ const majorLineColor = grid.majorLineColor ?? gridLineColor;
5232
+ if (majorCellSize !== void 0) {
5233
+ if (!gridCellSize || gridCellSize <= 0) {
5234
+ throw new Error("grid.majorCellSize requires a positive grid.cellSize");
5235
+ }
5236
+ if (majorCellSize <= 0) {
5237
+ throw new Error(
5238
+ "grid.majorCellSize must be a positive multiple of grid.cellSize"
5239
+ );
5240
+ }
5241
+ const ratio = majorCellSize / gridCellSize;
5242
+ const nearestInteger = Math.round(ratio);
5243
+ if (!Number.isFinite(ratio) || Math.abs(ratio - nearestInteger) > 1e-6) {
5244
+ throw new Error(
5245
+ "grid.majorCellSize must be a positive multiple of grid.cellSize"
5246
+ );
5247
+ }
5248
+ }
5249
+ if (!gridCellSize || gridCellSize <= 0) {
5250
+ return {};
5251
+ }
5252
+ const hasMajorGrid = majorCellSize !== void 0;
5253
+ const patternChildren = hasMajorGrid ? createMajorGridPatternChildren(
5254
+ gridCellSize,
5255
+ majorCellSize,
5256
+ gridLineColor,
5257
+ majorLineColor
5258
+ ) : [
5259
+ {
5260
+ name: "path",
4754
5261
  type: "element",
4755
5262
  value: "",
4756
5263
  attributes: {
4757
- x1: "0",
4758
- y1: offsetString,
4759
- x2: majorSizeString,
4760
- y2: offsetString,
4761
- stroke: color,
5264
+ d: `M ${gridCellSize} 0 L 0 0 0 ${gridCellSize}`,
5265
+ fill: "none",
5266
+ stroke: gridLineColor,
4762
5267
  "stroke-width": "1",
4763
5268
  "shape-rendering": "crispEdges"
4764
5269
  },
4765
5270
  children: []
4766
- });
4767
- }
4768
- return children;
4769
- }
4770
-
4771
- // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-component.ts
4772
- import { applyToPoint as applyToPoint30 } from "transformation-matrix";
4773
-
4774
- // lib/utils/create-pcb-component-anchor-offset-indicators.ts
4775
- import { applyToPoint as applyToPoint29 } from "transformation-matrix";
4776
- var OFFSET_THRESHOLD_MM = 0.01;
4777
- var TICK_SIZE_PX = 4;
4778
- var LABEL_GAP_PX = 8;
4779
- var LABEL_FONT_SIZE_PX = 11;
4780
- var STROKE_WIDTH_PX = 1;
4781
- var ANCHOR_MARKER_SIZE_PX = 5;
4782
- var ANCHOR_MARKER_STROKE_WIDTH_PX = 1.5;
4783
- var COMPONENT_GAP_PX = 15;
4784
- var COMPONENT_SIDE_GAP_PX = 10;
4785
- var DISTANCE_MULTIPLIER = 0.2;
4786
- var MAX_OFFSET_PX = 50;
4787
- function createAnchorOffsetIndicators(params) {
4788
- const {
4789
- groupAnchorPosition,
4790
- componentPosition,
4791
- transform,
4792
- componentWidth = 0,
4793
- componentHeight = 0
4794
- } = params;
4795
- const objects = [];
4796
- const [screenGroupAnchorX, screenGroupAnchorY] = applyToPoint29(transform, [
4797
- groupAnchorPosition.x,
4798
- groupAnchorPosition.y
4799
- ]);
4800
- const [screenComponentX, screenComponentY] = applyToPoint29(transform, [
4801
- componentPosition.x,
4802
- componentPosition.y
4803
- ]);
4804
- const offsetX = componentPosition.x - groupAnchorPosition.x;
4805
- const offsetY = componentPosition.y - groupAnchorPosition.y;
4806
- const scale9 = Math.abs(transform.a);
4807
- const screenComponentWidth = componentWidth * scale9;
4808
- const screenComponentHeight = componentHeight * scale9;
4809
- objects.push(createAnchorMarker(screenGroupAnchorX, screenGroupAnchorY));
4810
- objects.push({
4811
- name: "line",
4812
- type: "element",
4813
- attributes: {
4814
- x1: screenGroupAnchorX.toString(),
4815
- y1: screenGroupAnchorY.toString(),
4816
- x2: screenComponentX.toString(),
4817
- y2: screenComponentY.toString(),
4818
- stroke: "#ffffff",
4819
- "stroke-width": "0.5",
4820
- "stroke-dasharray": "3,3",
4821
- opacity: "0.5",
4822
- class: "anchor-offset-connector"
4823
- },
4824
- children: [],
4825
- value: ""
4826
- });
4827
- objects.push({
4828
- name: "circle",
4829
- type: "element",
4830
- attributes: {
4831
- cx: screenComponentX.toString(),
4832
- cy: screenComponentY.toString(),
4833
- r: "2",
4834
- fill: "#ffffff",
4835
- opacity: "0.7",
4836
- class: "anchor-offset-component-marker"
4837
- },
4838
- children: [],
4839
- value: ""
4840
- });
4841
- const yDistance = Math.abs(screenComponentY - screenGroupAnchorY);
4842
- const xDistance = Math.abs(screenComponentX - screenGroupAnchorX);
4843
- const totalDistance = Math.sqrt(xDistance * xDistance + yDistance * yDistance);
4844
- const componentHeightOffset = screenComponentHeight / 2 + COMPONENT_GAP_PX;
4845
- const dynamicOffset = Math.max(
4846
- componentHeightOffset,
4847
- Math.min(MAX_OFFSET_PX, totalDistance * DISTANCE_MULTIPLIER)
4848
- );
4849
- const horizontalLineY = offsetY > 0 ? screenComponentY - dynamicOffset : screenComponentY + dynamicOffset;
4850
- const componentWidthOffset = screenComponentWidth / 2 + COMPONENT_SIDE_GAP_PX;
4851
- const verticalLineX = offsetX > 0 ? screenComponentX + componentWidthOffset : screenComponentX - componentWidthOffset;
4852
- if (Math.abs(offsetX) > OFFSET_THRESHOLD_MM) {
4853
- objects.push(
4854
- ...createHorizontalDimension({
4855
- startX: screenGroupAnchorX,
4856
- endX: screenComponentX,
4857
- y: horizontalLineY,
4858
- offsetMm: offsetX,
4859
- offsetY
4860
- })
4861
- );
4862
- }
4863
- if (Math.abs(offsetY) > OFFSET_THRESHOLD_MM) {
4864
- objects.push(
4865
- ...createVerticalDimension({
4866
- x: verticalLineX,
4867
- startY: screenGroupAnchorY,
4868
- endY: screenComponentY,
4869
- offsetMm: -offsetY,
4870
- offsetX
4871
- })
4872
- );
4873
- }
4874
- return objects;
4875
- }
4876
- function createAnchorMarker(x, y) {
4877
- return {
4878
- name: "g",
4879
- type: "element",
4880
- attributes: {
4881
- class: "anchor-offset-marker",
4882
- "data-type": "anchor_offset_marker"
4883
- },
4884
- children: [
4885
- {
4886
- name: "line",
4887
- type: "element",
4888
- attributes: {
4889
- x1: x.toString(),
4890
- y1: (y - ANCHOR_MARKER_SIZE_PX).toString(),
4891
- x2: x.toString(),
4892
- y2: (y + ANCHOR_MARKER_SIZE_PX).toString(),
4893
- stroke: "#ffffff",
4894
- "stroke-width": ANCHOR_MARKER_STROKE_WIDTH_PX.toString(),
4895
- "stroke-linecap": "round"
4896
- },
4897
- children: [],
4898
- value: ""
4899
- },
4900
- {
4901
- name: "line",
4902
- type: "element",
4903
- attributes: {
4904
- x1: (x - ANCHOR_MARKER_SIZE_PX).toString(),
4905
- y1: y.toString(),
4906
- x2: (x + ANCHOR_MARKER_SIZE_PX).toString(),
4907
- y2: y.toString(),
4908
- stroke: "#ffffff",
4909
- "stroke-width": ANCHOR_MARKER_STROKE_WIDTH_PX.toString(),
4910
- "stroke-linecap": "round"
4911
- },
4912
- children: [],
4913
- value: ""
4914
- }
4915
- ],
4916
- value: ""
4917
- };
4918
- }
4919
- function createHorizontalDimension({
4920
- startX,
4921
- endX,
4922
- y,
4923
- offsetMm,
4924
- offsetY
4925
- }) {
4926
- const objects = [];
4927
- objects.push({
4928
- name: "line",
4929
- type: "element",
4930
- attributes: {
4931
- x1: startX.toString(),
4932
- y1: y.toString(),
4933
- x2: endX.toString(),
4934
- y2: y.toString(),
4935
- stroke: "#ffffff",
4936
- "stroke-width": STROKE_WIDTH_PX.toString(),
4937
- class: "anchor-offset-dimension-x"
4938
- },
4939
- children: [],
4940
- value: ""
4941
- });
4942
- objects.push({
4943
- name: "line",
4944
- type: "element",
4945
- attributes: {
4946
- x1: startX.toString(),
4947
- y1: (y - TICK_SIZE_PX).toString(),
4948
- x2: startX.toString(),
4949
- y2: (y + TICK_SIZE_PX).toString(),
4950
- stroke: "#ffffff",
4951
- "stroke-width": STROKE_WIDTH_PX.toString()
4952
- },
4953
- children: [],
4954
- value: ""
4955
- });
4956
- objects.push({
4957
- name: "line",
4958
- type: "element",
4959
- attributes: {
4960
- x1: endX.toString(),
4961
- y1: (y - TICK_SIZE_PX).toString(),
4962
- x2: endX.toString(),
4963
- y2: (y + TICK_SIZE_PX).toString(),
4964
- stroke: "#ffffff",
4965
- "stroke-width": STROKE_WIDTH_PX.toString()
4966
- },
4967
- children: [],
4968
- value: ""
4969
- });
4970
- const midX = (startX + endX) / 2;
4971
- const labelY = offsetY > 0 ? y - TICK_SIZE_PX - LABEL_GAP_PX : y + TICK_SIZE_PX + LABEL_GAP_PX;
4972
- objects.push({
4973
- name: "text",
5271
+ }
5272
+ ];
5273
+ const defs = {
5274
+ name: "defs",
4974
5275
  type: "element",
4975
- attributes: {
4976
- x: midX.toString(),
4977
- y: labelY.toString(),
4978
- fill: "#ffffff",
4979
- "font-size": LABEL_FONT_SIZE_PX.toString(),
4980
- "font-family": "Arial, sans-serif",
4981
- "text-anchor": "middle",
4982
- "dominant-baseline": offsetY > 0 ? "baseline" : "hanging",
4983
- class: "anchor-offset-label"
4984
- },
5276
+ value: "",
5277
+ attributes: {},
4985
5278
  children: [
4986
5279
  {
4987
- type: "text",
4988
- value: `X: ${offsetMm.toFixed(2)}mm`,
4989
- name: "",
4990
- attributes: {},
4991
- children: []
5280
+ name: "pattern",
5281
+ type: "element",
5282
+ value: "",
5283
+ attributes: {
5284
+ id: GRID_PATTERN_ID,
5285
+ width: hasMajorGrid ? majorCellSize.toString() : gridCellSize.toString(),
5286
+ height: hasMajorGrid ? majorCellSize.toString() : gridCellSize.toString(),
5287
+ patternUnits: "userSpaceOnUse"
5288
+ },
5289
+ children: patternChildren
4992
5290
  }
4993
- ],
4994
- value: ""
4995
- });
4996
- return objects;
4997
- }
4998
- function createVerticalDimension({
4999
- x,
5000
- startY,
5001
- endY,
5002
- offsetMm,
5003
- offsetX
5004
- }) {
5005
- const objects = [];
5006
- objects.push({
5007
- name: "line",
5008
- type: "element",
5009
- attributes: {
5010
- x1: x.toString(),
5011
- y1: startY.toString(),
5012
- x2: x.toString(),
5013
- y2: endY.toString(),
5014
- stroke: "#ffffff",
5015
- "stroke-width": STROKE_WIDTH_PX.toString(),
5016
- class: "anchor-offset-dimension-y"
5017
- },
5018
- children: [],
5019
- value: ""
5020
- });
5021
- objects.push({
5022
- name: "line",
5023
- type: "element",
5024
- attributes: {
5025
- x1: (x - TICK_SIZE_PX).toString(),
5026
- y1: startY.toString(),
5027
- x2: (x + TICK_SIZE_PX).toString(),
5028
- y2: startY.toString(),
5029
- stroke: "#ffffff",
5030
- "stroke-width": STROKE_WIDTH_PX.toString()
5031
- },
5032
- children: [],
5033
- value: ""
5034
- });
5035
- objects.push({
5036
- name: "line",
5037
- type: "element",
5038
- attributes: {
5039
- x1: (x - TICK_SIZE_PX).toString(),
5040
- y1: endY.toString(),
5041
- x2: (x + TICK_SIZE_PX).toString(),
5042
- y2: endY.toString(),
5043
- stroke: "#ffffff",
5044
- "stroke-width": STROKE_WIDTH_PX.toString()
5045
- },
5046
- children: [],
5047
- value: ""
5048
- });
5049
- const midY = (startY + endY) / 2;
5050
- const labelX = offsetX < 0 ? x - TICK_SIZE_PX - 4 : x + TICK_SIZE_PX + 4;
5051
- objects.push({
5052
- name: "text",
5291
+ ]
5292
+ };
5293
+ const rect = {
5294
+ name: "rect",
5053
5295
  type: "element",
5296
+ value: "",
5054
5297
  attributes: {
5055
- x: labelX.toString(),
5056
- y: midY.toString(),
5057
- fill: "#ffffff",
5058
- "font-size": LABEL_FONT_SIZE_PX.toString(),
5059
- "font-family": "Arial, sans-serif",
5060
- "text-anchor": offsetX < 0 ? "end" : "start",
5061
- "dominant-baseline": "middle",
5062
- class: "anchor-offset-label"
5298
+ x: "0",
5299
+ y: "0",
5300
+ width: svgWidth.toString(),
5301
+ height: svgHeight.toString(),
5302
+ fill: `url(#${GRID_PATTERN_ID})`,
5303
+ "pointer-events": "none",
5304
+ "data-type": "pcb_grid",
5305
+ "data-pcb-layer": "global"
5063
5306
  },
5064
- children: [
5065
- {
5066
- type: "text",
5067
- value: `Y: ${offsetMm.toFixed(2)}mm`,
5068
- name: "",
5069
- attributes: {},
5070
- children: []
5071
- }
5072
- ],
5073
- value: ""
5074
- });
5075
- return objects;
5307
+ children: []
5308
+ };
5309
+ return { defs, rect };
5310
+ }
5311
+ function createMajorGridPatternChildren(cellSize, majorCellSize, lineColor, majorLineColor) {
5312
+ const children = [];
5313
+ const steps = Math.round(majorCellSize / cellSize);
5314
+ for (let step = 0; step < steps; step += 1) {
5315
+ const offset = Number((step * cellSize).toFixed(6));
5316
+ const offsetString = offset.toString();
5317
+ const color = step === 0 ? majorLineColor : lineColor;
5318
+ const majorSizeString = majorCellSize.toString();
5319
+ children.push({
5320
+ name: "line",
5321
+ type: "element",
5322
+ value: "",
5323
+ attributes: {
5324
+ x1: offsetString,
5325
+ y1: "0",
5326
+ x2: offsetString,
5327
+ y2: majorSizeString,
5328
+ stroke: color,
5329
+ "stroke-width": "1",
5330
+ "shape-rendering": "crispEdges"
5331
+ },
5332
+ children: []
5333
+ });
5334
+ children.push({
5335
+ name: "line",
5336
+ type: "element",
5337
+ value: "",
5338
+ attributes: {
5339
+ x1: "0",
5340
+ y1: offsetString,
5341
+ x2: majorSizeString,
5342
+ y2: offsetString,
5343
+ stroke: color,
5344
+ "stroke-width": "1",
5345
+ "shape-rendering": "crispEdges"
5346
+ },
5347
+ children: []
5348
+ });
5349
+ }
5350
+ return children;
5076
5351
  }
5077
5352
 
5078
5353
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-component.ts
5354
+ import { applyToPoint as applyToPoint31 } from "transformation-matrix";
5079
5355
  function createSvgObjectsFromPcbComponent(component, ctx) {
5080
5356
  const { transform, circuitJson } = ctx;
5081
5357
  const { center, width, height, rotation = 0 } = component;
5082
- const [x, y] = applyToPoint30(transform, [center.x, center.y]);
5358
+ const [x, y] = applyToPoint31(transform, [center.x, center.y]);
5083
5359
  const scaledWidth = width * Math.abs(transform.a);
5084
5360
  const scaledHeight = height * Math.abs(transform.d);
5085
5361
  const transformStr = `translate(${x}, ${y}) rotate(${-rotation}) scale(1, -1)`;
@@ -5134,7 +5410,7 @@ function createSvgObjectsFromPcbComponent(component, ctx) {
5134
5410
  }
5135
5411
 
5136
5412
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-group.ts
5137
- import { applyToPoint as applyToPoint31 } from "transformation-matrix";
5413
+ import { applyToPoint as applyToPoint32 } from "transformation-matrix";
5138
5414
  var DEFAULT_GROUP_COLOR = "rgba(100, 200, 255, 0.6)";
5139
5415
  var DEFAULT_STROKE_WIDTH = 0.1;
5140
5416
  function createSvgObjectsFromPcbGroup(pcbGroup, ctx) {
@@ -5161,7 +5437,7 @@ function createSvgObjectsFromPcbGroup(pcbGroup, ctx) {
5161
5437
  (point) => point && typeof point.x === "number" && typeof point.y === "number"
5162
5438
  )) {
5163
5439
  const path = outline.map((point, index) => {
5164
- const [x, y] = applyToPoint31(transform, [point.x, point.y]);
5440
+ const [x, y] = applyToPoint32(transform, [point.x, point.y]);
5165
5441
  return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
5166
5442
  }).join(" ");
5167
5443
  return [
@@ -5183,11 +5459,11 @@ function createSvgObjectsFromPcbGroup(pcbGroup, ctx) {
5183
5459
  }
5184
5460
  const halfWidth = width / 2;
5185
5461
  const halfHeight = height / 2;
5186
- const [topLeftX, topLeftY] = applyToPoint31(transform, [
5462
+ const [topLeftX, topLeftY] = applyToPoint32(transform, [
5187
5463
  center.x - halfWidth,
5188
5464
  center.y + halfHeight
5189
5465
  ]);
5190
- const [bottomRightX, bottomRightY] = applyToPoint31(transform, [
5466
+ const [bottomRightX, bottomRightY] = applyToPoint32(transform, [
5191
5467
  center.x + halfWidth,
5192
5468
  center.y - halfHeight
5193
5469
  ]);
@@ -5223,7 +5499,7 @@ function getSoftwareUsedString(circuitJson) {
5223
5499
  var package_default = {
5224
5500
  name: "circuit-to-svg",
5225
5501
  type: "module",
5226
- version: "0.0.282",
5502
+ version: "0.0.284",
5227
5503
  description: "Convert Circuit JSON to SVG",
5228
5504
  main: "dist/index.js",
5229
5505
  files: [
@@ -5241,22 +5517,26 @@ var package_default = {
5241
5517
  license: "ISC",
5242
5518
  devDependencies: {
5243
5519
  "@biomejs/biome": "^1.9.4",
5520
+ "@tscircuit/alphabet": "^0.0.8",
5244
5521
  "@types/bun": "^1.2.8",
5245
5522
  "@vitejs/plugin-react": "5.0.0",
5246
5523
  biome: "^0.3.3",
5247
5524
  "bun-match-svg": "^0.0.12",
5525
+ "circuit-json": "^0.0.327",
5248
5526
  esbuild: "^0.20.2",
5249
5527
  "performance-now": "^2.1.0",
5250
- "circuit-json": "^0.0.319",
5251
5528
  react: "19.1.0",
5252
5529
  "react-cosmos": "7.0.0",
5253
5530
  "react-cosmos-plugin-vite": "7.0.0",
5254
5531
  "react-dom": "19.1.0",
5255
- tscircuit: "^0.0.937",
5532
+ tscircuit: "^0.0.1018",
5256
5533
  tsup: "^8.0.2",
5257
5534
  typescript: "^5.4.5",
5258
5535
  "vite-tsconfig-paths": "^5.0.1"
5259
5536
  },
5537
+ peerDependencies: {
5538
+ "@tscircuit/alphabet": "*"
5539
+ },
5260
5540
  dependencies: {
5261
5541
  "@types/node": "^22.5.5",
5262
5542
  "bun-types": "^1.1.40",
@@ -5452,8 +5732,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
5452
5732
  for (const circuitJsonElm of circuitJson) {
5453
5733
  if (circuitJsonElm.type === "pcb_panel") {
5454
5734
  const panel = circuitJsonElm;
5455
- const width = distance.parse(panel.width);
5456
- const height = distance.parse(panel.height);
5735
+ const width = distance2.parse(panel.width);
5736
+ const height = distance2.parse(panel.height);
5457
5737
  if (width === void 0 || height === void 0) {
5458
5738
  continue;
5459
5739
  }
@@ -5480,7 +5760,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
5480
5760
  if (pad.shape === "rect" || pad.shape === "rotated_rect" || pad.shape === "pill") {
5481
5761
  updateBounds({ x: pad.x, y: pad.y }, pad.width, pad.height);
5482
5762
  } else if (pad.shape === "circle") {
5483
- const radius = distance.parse(pad.radius);
5763
+ const radius = distance2.parse(pad.radius);
5484
5764
  if (radius !== void 0) {
5485
5765
  updateBounds({ x: pad.x, y: pad.y }, radius * 2, radius * 2);
5486
5766
  }
@@ -5502,7 +5782,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
5502
5782
  if (cutout.shape === "rect") {
5503
5783
  updateBounds(cutout.center, cutout.width, cutout.height);
5504
5784
  } else if (cutout.shape === "circle") {
5505
- const radius = distance.parse(cutout.radius);
5785
+ const radius = distance2.parse(cutout.radius);
5506
5786
  if (radius !== void 0) {
5507
5787
  updateBounds(cutout.center, radius * 2, radius * 2);
5508
5788
  }
@@ -5511,6 +5791,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
5511
5791
  }
5512
5792
  } else if (circuitJsonElm.type === "pcb_silkscreen_text" || circuitJsonElm.type === "pcb_silkscreen_rect" || circuitJsonElm.type === "pcb_silkscreen_circle" || circuitJsonElm.type === "pcb_silkscreen_line") {
5513
5793
  updateSilkscreenBounds(circuitJsonElm);
5794
+ } else if (circuitJsonElm.type === "pcb_copper_text") {
5795
+ updateBounds(circuitJsonElm.anchor_position, 0, 0);
5514
5796
  } else if (circuitJsonElm.type === "pcb_copper_pour") {
5515
5797
  if (circuitJsonElm.shape === "rect") {
5516
5798
  updateBounds(
@@ -5557,12 +5839,12 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
5557
5839
  const scaleFactor = Math.min(scaleX, scaleY);
5558
5840
  const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2;
5559
5841
  const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2;
5560
- const transform = compose5(
5561
- translate5(
5842
+ const transform = compose6(
5843
+ translate6(
5562
5844
  offsetX - boundsMinX * scaleFactor + padding * scaleFactor,
5563
5845
  svgHeight - offsetY + boundsMinY * scaleFactor - padding * scaleFactor
5564
5846
  ),
5565
- scale2(scaleFactor, -scaleFactor)
5847
+ scale3(scaleFactor, -scaleFactor)
5566
5848
  // Flip in y-direction
5567
5849
  );
5568
5850
  const ctx = {
@@ -5678,11 +5960,11 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
5678
5960
  }
5679
5961
  function updateBounds(center, width, height) {
5680
5962
  if (!center) return;
5681
- const centerX = distance.parse(center.x);
5682
- const centerY = distance.parse(center.y);
5963
+ const centerX = distance2.parse(center.x);
5964
+ const centerY = distance2.parse(center.y);
5683
5965
  if (centerX === void 0 || centerY === void 0) return;
5684
- const numericWidth = distance.parse(width) ?? 0;
5685
- const numericHeight = distance.parse(height) ?? 0;
5966
+ const numericWidth = distance2.parse(width) ?? 0;
5967
+ const numericHeight = distance2.parse(height) ?? 0;
5686
5968
  const halfWidth = numericWidth / 2;
5687
5969
  const halfHeight = numericHeight / 2;
5688
5970
  minX = Math.min(minX, centerX - halfWidth);
@@ -5693,11 +5975,11 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
5693
5975
  }
5694
5976
  function updateBoardBounds(center, width, height) {
5695
5977
  if (!center) return;
5696
- const centerX = distance.parse(center.x);
5697
- const centerY = distance.parse(center.y);
5978
+ const centerX = distance2.parse(center.x);
5979
+ const centerY = distance2.parse(center.y);
5698
5980
  if (centerX === void 0 || centerY === void 0) return;
5699
- const numericWidth = distance.parse(width) ?? 0;
5700
- const numericHeight = distance.parse(height) ?? 0;
5981
+ const numericWidth = distance2.parse(width) ?? 0;
5982
+ const numericHeight = distance2.parse(height) ?? 0;
5701
5983
  const halfWidth = numericWidth / 2;
5702
5984
  const halfHeight = numericHeight / 2;
5703
5985
  boardMinX = Math.min(boardMinX, centerX - halfWidth);
@@ -5710,8 +5992,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
5710
5992
  function updateBoundsToIncludeOutline(outline) {
5711
5993
  let updated = false;
5712
5994
  for (const point of outline) {
5713
- const x = distance.parse(point.x);
5714
- const y = distance.parse(point.y);
5995
+ const x = distance2.parse(point.x);
5996
+ const y = distance2.parse(point.y);
5715
5997
  if (x === void 0 || y === void 0) continue;
5716
5998
  minX = Math.min(minX, x);
5717
5999
  minY = Math.min(minY, y);
@@ -5726,8 +6008,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
5726
6008
  function updateBoardBoundsToIncludeOutline(outline) {
5727
6009
  let updated = false;
5728
6010
  for (const point of outline) {
5729
- const x = distance.parse(point.x);
5730
- const y = distance.parse(point.y);
6011
+ const x = distance2.parse(point.x);
6012
+ const y = distance2.parse(point.y);
5731
6013
  if (x === void 0 || y === void 0) continue;
5732
6014
  boardMinX = Math.min(boardMinX, x);
5733
6015
  boardMinY = Math.min(boardMinY, y);
@@ -5743,8 +6025,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
5743
6025
  function updateTraceBounds(route) {
5744
6026
  let updated = false;
5745
6027
  for (const point of route) {
5746
- const x = distance.parse(point?.x);
5747
- const y = distance.parse(point?.y);
6028
+ const x = distance2.parse(point?.x);
6029
+ const y = distance2.parse(point?.y);
5748
6030
  if (x === void 0 || y === void 0) continue;
5749
6031
  minX = Math.min(minX, x);
5750
6032
  minY = Math.min(minY, y);
@@ -5764,7 +6046,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
5764
6046
  } else if (item.type === "pcb_silkscreen_rect") {
5765
6047
  updateBounds(item.center, item.width, item.height);
5766
6048
  } else if (item.type === "pcb_silkscreen_circle") {
5767
- const radius = distance.parse(item.radius);
6049
+ const radius = distance2.parse(item.radius);
5768
6050
  if (radius !== void 0) {
5769
6051
  updateBounds(item.center, radius * 2, radius * 2);
5770
6052
  }
@@ -5776,7 +6058,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
5776
6058
  if (cutout.shape === "rect") {
5777
6059
  updateBounds(cutout.center, cutout.width, cutout.height);
5778
6060
  } else if (cutout.shape === "circle") {
5779
- const radius = distance.parse(cutout.radius);
6061
+ const radius = distance2.parse(cutout.radius);
5780
6062
  if (radius !== void 0) {
5781
6063
  updateBounds(cutout.center, radius * 2, radius * 2);
5782
6064
  }
@@ -5822,6 +6104,8 @@ function createSvgObjects({
5822
6104
  return createSvgObjectsFromPcbSilkscreenCircle(elm, ctx);
5823
6105
  case "pcb_silkscreen_line":
5824
6106
  return createSvgObjectsFromPcbSilkscreenLine(elm, ctx);
6107
+ case "pcb_copper_text":
6108
+ return createSvgObjectsFromPcbCopperText(elm, ctx);
5825
6109
  case "pcb_courtyard_rect":
5826
6110
  if (!ctx.showCourtyards) return [];
5827
6111
  return createSvgObjectsFromPcbCourtyardRect(elm, ctx);
@@ -5860,8 +6144,8 @@ function createSvgObjects({
5860
6144
  }
5861
6145
  }
5862
6146
  function createSvgObjectFromPcbBoundary(transform, minX, minY, maxX, maxY) {
5863
- const [x1, y1] = applyToPoint32(transform, [minX, minY]);
5864
- const [x2, y2] = applyToPoint32(transform, [maxX, maxY]);
6147
+ const [x1, y1] = applyToPoint33(transform, [minX, minY]);
6148
+ const [x2, y2] = applyToPoint33(transform, [maxX, maxY]);
5865
6149
  const width = Math.abs(x2 - x1);
5866
6150
  const height = Math.abs(y2 - y1);
5867
6151
  const x = Math.min(x1, x2);
@@ -5891,14 +6175,14 @@ var circuitJsonToPcbSvg = convertCircuitJsonToPcbSvg;
5891
6175
  import { stringify as stringify2 } from "svgson";
5892
6176
  import { su as su3 } from "@tscircuit/circuit-json-util";
5893
6177
  import {
5894
- applyToPoint as applyToPoint39,
5895
- compose as compose6,
5896
- scale as scale3,
5897
- translate as translate6
6178
+ applyToPoint as applyToPoint40,
6179
+ compose as compose7,
6180
+ scale as scale4,
6181
+ translate as translate7
5898
6182
  } from "transformation-matrix";
5899
6183
 
5900
6184
  // lib/assembly/svg-object-fns/create-svg-objects-from-assembly-board.ts
5901
- import { applyToPoint as applyToPoint33 } from "transformation-matrix";
6185
+ import { applyToPoint as applyToPoint34 } from "transformation-matrix";
5902
6186
  var DEFAULT_BOARD_STYLE = {
5903
6187
  fill: "none",
5904
6188
  stroke: "rgb(0,0,0)",
@@ -5910,25 +6194,25 @@ function createSvgObjectsFromAssemblyBoard(pcbBoard, transform, style = {}) {
5910
6194
  let path;
5911
6195
  if (outline && Array.isArray(outline) && outline.length >= 3) {
5912
6196
  path = outline.map((point, index) => {
5913
- const [x, y] = applyToPoint33(transform, [point.x, point.y]);
6197
+ const [x, y] = applyToPoint34(transform, [point.x, point.y]);
5914
6198
  return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
5915
6199
  }).join(" ");
5916
6200
  } else {
5917
6201
  const halfWidth = width / 2;
5918
6202
  const halfHeight = height / 2;
5919
- const topLeft = applyToPoint33(transform, [
6203
+ const topLeft = applyToPoint34(transform, [
5920
6204
  center.x - halfWidth,
5921
6205
  center.y - halfHeight
5922
6206
  ]);
5923
- const topRight = applyToPoint33(transform, [
6207
+ const topRight = applyToPoint34(transform, [
5924
6208
  center.x + halfWidth,
5925
6209
  center.y - halfHeight
5926
6210
  ]);
5927
- const bottomRight = applyToPoint33(transform, [
6211
+ const bottomRight = applyToPoint34(transform, [
5928
6212
  center.x + halfWidth,
5929
6213
  center.y + halfHeight
5930
6214
  ]);
5931
- const bottomLeft = applyToPoint33(transform, [
6215
+ const bottomLeft = applyToPoint34(transform, [
5932
6216
  center.x - halfWidth,
5933
6217
  center.y + halfHeight
5934
6218
  ]);
@@ -5954,7 +6238,7 @@ function createSvgObjectsFromAssemblyBoard(pcbBoard, transform, style = {}) {
5954
6238
  }
5955
6239
 
5956
6240
  // lib/assembly/svg-object-fns/create-svg-objects-from-assembly-component.ts
5957
- import { applyToPoint as applyToPoint35 } from "transformation-matrix";
6241
+ import { applyToPoint as applyToPoint36 } from "transformation-matrix";
5958
6242
 
5959
6243
  // lib/utils/get-sch-font-size.ts
5960
6244
  import "transformation-matrix";
@@ -5980,8 +6264,8 @@ function createSvgObjectsFromAssemblyComponent(params, ctx) {
5980
6264
  const { center, width, height, rotation = 0, layer = "top" } = elm;
5981
6265
  if (!center || typeof width !== "number" || typeof height !== "number")
5982
6266
  return null;
5983
- const [x, y] = applyToPoint35(transform, [center.x, center.y]);
5984
- const [pinX, pinY] = applyToPoint35(transform, [portPosition.x, portPosition.y]);
6267
+ const [x, y] = applyToPoint36(transform, [center.x, center.y]);
6268
+ const [pinX, pinY] = applyToPoint36(transform, [portPosition.x, portPosition.y]);
5985
6269
  const scaledWidth = width * Math.abs(transform.a);
5986
6270
  const scaledHeight = height * Math.abs(transform.d);
5987
6271
  const isTopLayer = layer === "top";
@@ -6143,11 +6427,11 @@ function getRectPathData(w, h, rotation) {
6143
6427
  }
6144
6428
 
6145
6429
  // lib/assembly/svg-object-fns/create-svg-objects-from-assembly-hole.ts
6146
- import { applyToPoint as applyToPoint36 } from "transformation-matrix";
6430
+ import { applyToPoint as applyToPoint37 } from "transformation-matrix";
6147
6431
  var HOLE_COLOR2 = "rgb(190, 190, 190)";
6148
6432
  function createSvgObjectsFromAssemblyHole(hole, ctx) {
6149
6433
  const { transform } = ctx;
6150
- const [x, y] = applyToPoint36(transform, [hole.x, hole.y]);
6434
+ const [x, y] = applyToPoint37(transform, [hole.x, hole.y]);
6151
6435
  if (hole.hole_shape === "circle" || hole.hole_shape === "square") {
6152
6436
  const scaledDiameter = hole.hole_diameter * Math.abs(transform.a);
6153
6437
  const radius = scaledDiameter / 2;
@@ -6211,12 +6495,12 @@ function createSvgObjectsFromAssemblyHole(hole, ctx) {
6211
6495
  }
6212
6496
 
6213
6497
  // lib/assembly/svg-object-fns/create-svg-objects-from-assembly-plated-hole.ts
6214
- import { applyToPoint as applyToPoint37 } from "transformation-matrix";
6498
+ import { applyToPoint as applyToPoint38 } from "transformation-matrix";
6215
6499
  var PAD_COLOR = "rgb(210, 210, 210)";
6216
6500
  var HOLE_COLOR3 = "rgb(190, 190, 190)";
6217
6501
  function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
6218
6502
  const { transform } = ctx;
6219
- const [x, y] = applyToPoint37(transform, [hole.x, hole.y]);
6503
+ const [x, y] = applyToPoint38(transform, [hole.x, hole.y]);
6220
6504
  if (hole.shape === "pill") {
6221
6505
  const scaledOuterWidth = hole.outer_width * Math.abs(transform.a);
6222
6506
  const scaledOuterHeight = hole.outer_height * Math.abs(transform.a);
@@ -6311,7 +6595,7 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
6311
6595
  const scaledRectPadHeight = circularHole.rect_pad_height * Math.abs(transform.a);
6312
6596
  const scaledRectBorderRadius = (circularHole.rect_border_radius ?? 0) * Math.abs(transform.a);
6313
6597
  const holeRadius = scaledHoleDiameter / 2;
6314
- const [holeCx, holeCy] = applyToPoint37(transform, [
6598
+ const [holeCx, holeCy] = applyToPoint38(transform, [
6315
6599
  circularHole.x + circularHole.hole_offset_x,
6316
6600
  circularHole.y + circularHole.hole_offset_y
6317
6601
  ]);
@@ -6369,7 +6653,7 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
6369
6653
  const pillHoleWithOffsets = pillHole;
6370
6654
  const holeOffsetX = pillHoleWithOffsets.hole_offset_x ?? 0;
6371
6655
  const holeOffsetY = pillHoleWithOffsets.hole_offset_y ?? 0;
6372
- const [holeCenterX, holeCenterY] = applyToPoint37(transform, [
6656
+ const [holeCenterX, holeCenterY] = applyToPoint38(transform, [
6373
6657
  pillHole.x + holeOffsetX,
6374
6658
  pillHole.y + holeOffsetY
6375
6659
  ]);
@@ -6431,7 +6715,7 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
6431
6715
  const rotatedHoleWithOffsets = rotatedHole;
6432
6716
  const holeOffsetX = rotatedHoleWithOffsets.hole_offset_x ?? 0;
6433
6717
  const holeOffsetY = rotatedHoleWithOffsets.hole_offset_y ?? 0;
6434
- const [holeCenterX, holeCenterY] = applyToPoint37(transform, [
6718
+ const [holeCenterX, holeCenterY] = applyToPoint38(transform, [
6435
6719
  rotatedHole.x + holeOffsetX,
6436
6720
  rotatedHole.y + holeOffsetY
6437
6721
  ]);
@@ -6487,14 +6771,14 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
6487
6771
  }
6488
6772
 
6489
6773
  // lib/assembly/svg-object-fns/create-svg-objects-from-assembly-smt-pad.ts
6490
- import { applyToPoint as applyToPoint38 } from "transformation-matrix";
6774
+ import { applyToPoint as applyToPoint39 } from "transformation-matrix";
6491
6775
  var PAD_COLOR2 = "rgb(210, 210, 210)";
6492
6776
  function createSvgObjectsFromAssemblySmtPad(pad, ctx) {
6493
6777
  const { transform } = ctx;
6494
6778
  if (pad.shape === "rect" || pad.shape === "rotated_rect") {
6495
6779
  const width = pad.width * Math.abs(transform.a);
6496
6780
  const height = pad.height * Math.abs(transform.d);
6497
- const [x, y] = applyToPoint38(transform, [pad.x, pad.y]);
6781
+ const [x, y] = applyToPoint39(transform, [pad.x, pad.y]);
6498
6782
  const scaledBorderRadius = (pad.rect_border_radius ?? 0) * Math.abs(transform.a);
6499
6783
  if (pad.shape === "rotated_rect" && pad.ccw_rotation) {
6500
6784
  return [
@@ -6546,7 +6830,7 @@ function createSvgObjectsFromAssemblySmtPad(pad, ctx) {
6546
6830
  const width = pad.width * Math.abs(transform.a);
6547
6831
  const height = pad.height * Math.abs(transform.d);
6548
6832
  const radius = pad.radius * Math.abs(transform.a);
6549
- const [x, y] = applyToPoint38(transform, [pad.x, pad.y]);
6833
+ const [x, y] = applyToPoint39(transform, [pad.x, pad.y]);
6550
6834
  return [
6551
6835
  {
6552
6836
  name: "rect",
@@ -6569,7 +6853,7 @@ function createSvgObjectsFromAssemblySmtPad(pad, ctx) {
6569
6853
  }
6570
6854
  if (pad.shape === "circle") {
6571
6855
  const radius = pad.radius * Math.abs(transform.a);
6572
- const [x, y] = applyToPoint38(transform, [pad.x, pad.y]);
6856
+ const [x, y] = applyToPoint39(transform, [pad.x, pad.y]);
6573
6857
  return [
6574
6858
  {
6575
6859
  name: "circle",
@@ -6589,7 +6873,7 @@ function createSvgObjectsFromAssemblySmtPad(pad, ctx) {
6589
6873
  }
6590
6874
  if (pad.shape === "polygon") {
6591
6875
  const points = (pad.points ?? []).map(
6592
- (point) => applyToPoint38(transform, [point.x, point.y])
6876
+ (point) => applyToPoint39(transform, [point.x, point.y])
6593
6877
  );
6594
6878
  return [
6595
6879
  {
@@ -6643,12 +6927,12 @@ function convertCircuitJsonToAssemblySvg(soup, options) {
6643
6927
  const scaleFactor = Math.min(scaleX, scaleY);
6644
6928
  const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2;
6645
6929
  const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2;
6646
- const transform = compose6(
6647
- translate6(
6930
+ const transform = compose7(
6931
+ translate7(
6648
6932
  offsetX - minX * scaleFactor + padding * scaleFactor,
6649
6933
  svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
6650
6934
  ),
6651
- scale3(scaleFactor, -scaleFactor)
6935
+ scale4(scaleFactor, -scaleFactor)
6652
6936
  // Flip in y-direction
6653
6937
  );
6654
6938
  const ctx = { transform };
@@ -6773,8 +7057,8 @@ function createSvgObjects2(elm, ctx, soup) {
6773
7057
  }
6774
7058
  }
6775
7059
  function createSvgObjectFromAssemblyBoundary(transform, minX, minY, maxX, maxY) {
6776
- const [x1, y1] = applyToPoint39(transform, [minX, minY]);
6777
- const [x2, y2] = applyToPoint39(transform, [maxX, maxY]);
7060
+ const [x1, y1] = applyToPoint40(transform, [minX, minY]);
7061
+ const [x2, y2] = applyToPoint40(transform, [maxX, maxY]);
6778
7062
  const width = Math.abs(x2 - x1);
6779
7063
  const height = Math.abs(y2 - y1);
6780
7064
  const x = Math.min(x1, x2);
@@ -6797,13 +7081,13 @@ function createSvgObjectFromAssemblyBoundary(transform, minX, minY, maxX, maxY)
6797
7081
  // lib/pinout/convert-circuit-json-to-pinout-svg.ts
6798
7082
  import { stringify as stringify3 } from "svgson";
6799
7083
  import {
6800
- compose as compose7,
7084
+ compose as compose8,
6801
7085
  scale as matrixScale,
6802
- translate as translate7
7086
+ translate as translate8
6803
7087
  } from "transformation-matrix";
6804
7088
 
6805
7089
  // lib/pinout/svg-object-fns/create-svg-objects-from-pinout-board.ts
6806
- import { applyToPoint as applyToPoint40 } from "transformation-matrix";
7090
+ import { applyToPoint as applyToPoint41 } from "transformation-matrix";
6807
7091
  import { su as su4 } from "@tscircuit/circuit-json-util";
6808
7092
  var BOARD_FILL_COLOR = "rgb(26, 115, 143)";
6809
7093
  var BOARD_STROKE_COLOR = "rgba(0,0,0,0.9)";
@@ -6817,25 +7101,25 @@ function createSvgObjectsFromPinoutBoard(pcbBoard, ctx) {
6817
7101
  let path;
6818
7102
  if (outline && Array.isArray(outline) && outline.length >= 3) {
6819
7103
  path = outline.map((point, index) => {
6820
- const [x, y] = applyToPoint40(transform, [point.x, point.y]);
7104
+ const [x, y] = applyToPoint41(transform, [point.x, point.y]);
6821
7105
  return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
6822
7106
  }).join(" ");
6823
7107
  } else {
6824
7108
  const halfWidth = width / 2;
6825
7109
  const halfHeight = height / 2;
6826
- const topLeft = applyToPoint40(transform, [
7110
+ const topLeft = applyToPoint41(transform, [
6827
7111
  center.x - halfWidth,
6828
7112
  center.y - halfHeight
6829
7113
  ]);
6830
- const topRight = applyToPoint40(transform, [
7114
+ const topRight = applyToPoint41(transform, [
6831
7115
  center.x + halfWidth,
6832
7116
  center.y - halfHeight
6833
7117
  ]);
6834
- const bottomRight = applyToPoint40(transform, [
7118
+ const bottomRight = applyToPoint41(transform, [
6835
7119
  center.x + halfWidth,
6836
7120
  center.y + halfHeight
6837
7121
  ]);
6838
- const bottomLeft = applyToPoint40(transform, [
7122
+ const bottomLeft = applyToPoint41(transform, [
6839
7123
  center.x - halfWidth,
6840
7124
  center.y + halfHeight
6841
7125
  ]);
@@ -6853,10 +7137,10 @@ function createSvgObjectsFromPinoutBoard(pcbBoard, ctx) {
6853
7137
  const halfWidth = width2 / 2;
6854
7138
  const halfHeight = height2 / 2;
6855
7139
  const [tl, tr, br, bl] = [
6856
- applyToPoint40(transform, [x - halfWidth, y - halfHeight]),
6857
- applyToPoint40(transform, [x + halfWidth, y - halfHeight]),
6858
- applyToPoint40(transform, [x + halfWidth, y + halfHeight]),
6859
- applyToPoint40(transform, [x - halfWidth, y + halfHeight])
7140
+ applyToPoint41(transform, [x - halfWidth, y - halfHeight]),
7141
+ applyToPoint41(transform, [x + halfWidth, y - halfHeight]),
7142
+ applyToPoint41(transform, [x + halfWidth, y + halfHeight]),
7143
+ applyToPoint41(transform, [x - halfWidth, y + halfHeight])
6860
7144
  ];
6861
7145
  path += ` M ${tl[0]} ${tl[1]} L ${tr[0]} ${tr[1]} L ${br[0]} ${br[1]} L ${bl[0]} ${bl[1]} Z`;
6862
7146
  } else if (cutout.shape === "circle") {
@@ -6906,7 +7190,7 @@ function createSvgObjectsFromPinoutBoard(pcbBoard, ctx) {
6906
7190
 
6907
7191
  // lib/pinout/svg-object-fns/create-svg-objects-from-pinout-component.ts
6908
7192
  import { su as su5 } from "@tscircuit/circuit-json-util";
6909
- import { applyToPoint as applyToPoint41 } from "transformation-matrix";
7193
+ import { applyToPoint as applyToPoint42 } from "transformation-matrix";
6910
7194
  var COMPONENT_FILL_COLOR = "rgba(120, 120, 120, 0.6)";
6911
7195
  var COMPONENT_LABEL_COLOR = "rgba(255, 255, 255, 0.9)";
6912
7196
  function createSvgObjectsFromPinoutComponent(elm, ctx) {
@@ -6916,7 +7200,7 @@ function createSvgObjectsFromPinoutComponent(elm, ctx) {
6916
7200
  if (!center || typeof width !== "number" || typeof height !== "number" || width === 0 || height === 0) {
6917
7201
  return [];
6918
7202
  }
6919
- const [x, y] = applyToPoint41(transform, [center.x, center.y]);
7203
+ const [x, y] = applyToPoint42(transform, [center.x, center.y]);
6920
7204
  const scaledWidth = width * Math.abs(transform.a);
6921
7205
  const scaledHeight = height * Math.abs(transform.d);
6922
7206
  const transformStr = `translate(${x}, ${y})`;
@@ -6977,11 +7261,11 @@ function createSvgObjectsFromPinoutComponent(elm, ctx) {
6977
7261
  }
6978
7262
 
6979
7263
  // lib/pinout/svg-object-fns/create-svg-objects-from-pinout-hole.ts
6980
- import { applyToPoint as applyToPoint42 } from "transformation-matrix";
7264
+ import { applyToPoint as applyToPoint43 } from "transformation-matrix";
6981
7265
  var HOLE_COLOR4 = "rgb(50, 50, 50)";
6982
7266
  function createSvgObjectsFromPinoutHole(hole, ctx) {
6983
7267
  const { transform } = ctx;
6984
- const [x, y] = applyToPoint42(transform, [hole.x, hole.y]);
7268
+ const [x, y] = applyToPoint43(transform, [hole.x, hole.y]);
6985
7269
  if (hole.hole_shape === "circle" || hole.hole_shape === "square") {
6986
7270
  const scaledDiameter = hole.hole_diameter * Math.abs(transform.a);
6987
7271
  const radius = scaledDiameter / 2;
@@ -7045,12 +7329,12 @@ function createSvgObjectsFromPinoutHole(hole, ctx) {
7045
7329
  }
7046
7330
 
7047
7331
  // lib/pinout/svg-object-fns/create-svg-objects-from-pinout-plated-hole.ts
7048
- import { applyToPoint as applyToPoint43 } from "transformation-matrix";
7332
+ import { applyToPoint as applyToPoint44 } from "transformation-matrix";
7049
7333
  var PAD_COLOR3 = "rgb(218, 165, 32)";
7050
7334
  var HOLE_COLOR5 = "rgb(40, 40, 40)";
7051
7335
  function createSvgObjectsFromPinoutPlatedHole(hole, ctx) {
7052
7336
  const { transform } = ctx;
7053
- const [x, y] = applyToPoint43(transform, [hole.x, hole.y]);
7337
+ const [x, y] = applyToPoint44(transform, [hole.x, hole.y]);
7054
7338
  if (hole.shape === "pill") {
7055
7339
  const scaledOuterWidth = hole.outer_width * Math.abs(transform.a);
7056
7340
  const scaledOuterHeight = hole.outer_height * Math.abs(transform.a);
@@ -7285,14 +7569,14 @@ function createSvgObjectsFromPinoutPlatedHole(hole, ctx) {
7285
7569
  }
7286
7570
 
7287
7571
  // lib/pinout/svg-object-fns/create-svg-objects-from-pinout-smt-pad.ts
7288
- import { applyToPoint as applyToPoint44 } from "transformation-matrix";
7572
+ import { applyToPoint as applyToPoint45 } from "transformation-matrix";
7289
7573
  var PAD_COLOR4 = "rgb(218, 165, 32)";
7290
7574
  function createSvgObjectsFromPinoutSmtPad(pad, ctx) {
7291
7575
  const { transform } = ctx;
7292
7576
  if (pad.shape === "rect" || pad.shape === "rotated_rect") {
7293
7577
  const width = pad.width * Math.abs(transform.a);
7294
7578
  const height = pad.height * Math.abs(transform.d);
7295
- const [x, y] = applyToPoint44(transform, [pad.x, pad.y]);
7579
+ const [x, y] = applyToPoint45(transform, [pad.x, pad.y]);
7296
7580
  if (pad.shape === "rotated_rect" && pad.ccw_rotation) {
7297
7581
  return [
7298
7582
  {
@@ -7335,7 +7619,7 @@ function createSvgObjectsFromPinoutSmtPad(pad, ctx) {
7335
7619
  const width = pad.width * Math.abs(transform.a);
7336
7620
  const height = pad.height * Math.abs(transform.d);
7337
7621
  const radius = pad.radius * Math.abs(transform.a);
7338
- const [x, y] = applyToPoint44(transform, [pad.x, pad.y]);
7622
+ const [x, y] = applyToPoint45(transform, [pad.x, pad.y]);
7339
7623
  return [
7340
7624
  {
7341
7625
  name: "rect",
@@ -7358,7 +7642,7 @@ function createSvgObjectsFromPinoutSmtPad(pad, ctx) {
7358
7642
  }
7359
7643
  if (pad.shape === "circle") {
7360
7644
  const radius = pad.radius * Math.abs(transform.a);
7361
- const [x, y] = applyToPoint44(transform, [pad.x, pad.y]);
7645
+ const [x, y] = applyToPoint45(transform, [pad.x, pad.y]);
7362
7646
  return [
7363
7647
  {
7364
7648
  name: "circle",
@@ -7378,7 +7662,7 @@ function createSvgObjectsFromPinoutSmtPad(pad, ctx) {
7378
7662
  }
7379
7663
  if (pad.shape === "polygon") {
7380
7664
  const points = (pad.points ?? []).map(
7381
- (point) => applyToPoint44(transform, [point.x, point.y])
7665
+ (point) => applyToPoint45(transform, [point.x, point.y])
7382
7666
  );
7383
7667
  return [
7384
7668
  {
@@ -7399,7 +7683,7 @@ function createSvgObjectsFromPinoutSmtPad(pad, ctx) {
7399
7683
  }
7400
7684
 
7401
7685
  // lib/pinout/svg-object-fns/create-svg-objects-from-pinout-port.ts
7402
- import { applyToPoint as applyToPoint45 } from "transformation-matrix";
7686
+ import { applyToPoint as applyToPoint46 } from "transformation-matrix";
7403
7687
  import { calculateElbow } from "calculate-elbow";
7404
7688
 
7405
7689
  // lib/pinout/svg-object-fns/pinout-label-box.ts
@@ -7476,7 +7760,7 @@ function createSvgObjectsFromPinoutPort(pcb_port, ctx) {
7476
7760
  const label_info = ctx.label_positions.get(pcb_port.pcb_port_id);
7477
7761
  if (!label_info) return [];
7478
7762
  const { text: label, aliases, elbow_end, label_pos, edge } = label_info;
7479
- const [port_x, port_y] = applyToPoint45(ctx.transform, [pcb_port.x, pcb_port.y]);
7763
+ const [port_x, port_y] = applyToPoint46(ctx.transform, [pcb_port.x, pcb_port.y]);
7480
7764
  const start_facing_direction = edge === "left" ? "x-" : edge === "right" ? "x+" : edge === "top" ? "y-" : "y+";
7481
7765
  const end_facing_direction = edge === "left" ? "x+" : edge === "right" ? "x-" : edge === "top" ? "y+" : "y-";
7482
7766
  const elbow_path = calculateElbow(
@@ -7617,7 +7901,7 @@ function createSvgObjectsFromPinoutPort(pcb_port, ctx) {
7617
7901
  }
7618
7902
 
7619
7903
  // lib/pinout/calculate-label-positions.ts
7620
- import { applyToPoint as applyToPoint46 } from "transformation-matrix";
7904
+ import { applyToPoint as applyToPoint47 } from "transformation-matrix";
7621
7905
 
7622
7906
  // lib/pinout/constants.ts
7623
7907
  var LABEL_RECT_HEIGHT_BASE_MM = 1.6;
@@ -7655,7 +7939,7 @@ function calculateVerticalEdgeLabels(edge, pinout_labels, {
7655
7939
  );
7656
7940
  const mapToEdgePort = (pinout_label) => ({
7657
7941
  pcb_port: pinout_label.pcb_port,
7658
- y: applyToPoint46(transform, [
7942
+ y: applyToPoint47(transform, [
7659
7943
  pinout_label.pcb_port.x,
7660
7944
  pinout_label.pcb_port.y
7661
7945
  ])[1],
@@ -7670,7 +7954,7 @@ function calculateVerticalEdgeLabels(edge, pinout_labels, {
7670
7954
  } else {
7671
7955
  edge_ports = pinout_labels.map((pinout_label) => ({
7672
7956
  pcb_port: pinout_label.pcb_port,
7673
- y: applyToPoint46(transform, [
7957
+ y: applyToPoint47(transform, [
7674
7958
  pinout_label.pcb_port.x,
7675
7959
  pinout_label.pcb_port.y
7676
7960
  ])[1],
@@ -7678,7 +7962,7 @@ function calculateVerticalEdgeLabels(edge, pinout_labels, {
7678
7962
  })).sort((a, b) => a.y - b.y);
7679
7963
  }
7680
7964
  if (edge_ports.length === 0) return;
7681
- const board_edge_x = applyToPoint46(transform, [
7965
+ const board_edge_x = applyToPoint47(transform, [
7682
7966
  edge === "left" ? board_bounds.minX : board_bounds.maxX,
7683
7967
  0
7684
7968
  ])[0];
@@ -7998,8 +8282,8 @@ function convertCircuitJsonToPinoutSvg(soup, options) {
7998
8282
  const pxPerMm = Math.min(pxPerMmX, pxPerMmY);
7999
8283
  const offsetX = (svgWidth - circuitWidth * pxPerMm) / 2;
8000
8284
  const offsetY = (svgHeight - circuitHeight * pxPerMm) / 2;
8001
- const transform = compose7(
8002
- translate7(
8285
+ const transform = compose8(
8286
+ translate8(
8003
8287
  offsetX - expandedMinX * pxPerMm + paddingMm * pxPerMm,
8004
8288
  svgHeight - offsetY + minY * pxPerMm - paddingMm * pxPerMm
8005
8289
  ),
@@ -8100,14 +8384,14 @@ import {
8100
8384
  } from "transformation-matrix";
8101
8385
 
8102
8386
  // lib/sch/draw-schematic-grid.ts
8103
- import { applyToPoint as applyToPoint47 } from "transformation-matrix";
8387
+ import { applyToPoint as applyToPoint48 } from "transformation-matrix";
8104
8388
  function drawSchematicGrid(params) {
8105
8389
  const { minX, minY, maxX, maxY } = params.bounds;
8106
8390
  const cellSize = params.cellSize ?? 1;
8107
8391
  const labelCells = params.labelCells ?? false;
8108
8392
  const gridLines = [];
8109
8393
  const transformPoint = (x, y) => {
8110
- const [transformedX, transformedY] = applyToPoint47(params.transform, [x, y]);
8394
+ const [transformedX, transformedY] = applyToPoint48(params.transform, [x, y]);
8111
8395
  return { x: transformedX, y: transformedY };
8112
8396
  };
8113
8397
  for (let x = Math.floor(minX); x <= Math.ceil(maxX); x += cellSize) {
@@ -8188,15 +8472,15 @@ function drawSchematicGrid(params) {
8188
8472
  }
8189
8473
 
8190
8474
  // lib/sch/draw-schematic-labeled-points.ts
8191
- import { applyToPoint as applyToPoint48 } from "transformation-matrix";
8475
+ import { applyToPoint as applyToPoint49 } from "transformation-matrix";
8192
8476
  function drawSchematicLabeledPoints(params) {
8193
8477
  const { points, transform } = params;
8194
8478
  const labeledPointsGroup = [];
8195
8479
  for (const point of points) {
8196
- const [x1, y1] = applyToPoint48(transform, [point.x - 0.1, point.y - 0.1]);
8197
- const [x2, y2] = applyToPoint48(transform, [point.x + 0.1, point.y + 0.1]);
8198
- const [x3, y3] = applyToPoint48(transform, [point.x - 0.1, point.y + 0.1]);
8199
- const [x4, y4] = applyToPoint48(transform, [point.x + 0.1, point.y - 0.1]);
8480
+ const [x1, y1] = applyToPoint49(transform, [point.x - 0.1, point.y - 0.1]);
8481
+ const [x2, y2] = applyToPoint49(transform, [point.x + 0.1, point.y + 0.1]);
8482
+ const [x3, y3] = applyToPoint49(transform, [point.x - 0.1, point.y + 0.1]);
8483
+ const [x4, y4] = applyToPoint49(transform, [point.x + 0.1, point.y - 0.1]);
8200
8484
  labeledPointsGroup.push({
8201
8485
  name: "path",
8202
8486
  type: "element",
@@ -8207,7 +8491,7 @@ function drawSchematicLabeledPoints(params) {
8207
8491
  "stroke-opacity": "0.7"
8208
8492
  }
8209
8493
  });
8210
- const [labelX, labelY] = applyToPoint48(transform, [
8494
+ const [labelX, labelY] = applyToPoint49(transform, [
8211
8495
  point.x + 0.15,
8212
8496
  point.y - 0.15
8213
8497
  ]);
@@ -9301,8 +9585,8 @@ import { su as su7 } from "@tscircuit/circuit-json-util";
9301
9585
  import { symbols } from "schematic-symbols";
9302
9586
  import "svgson";
9303
9587
  import {
9304
- applyToPoint as applyToPoint50,
9305
- compose as compose9
9588
+ applyToPoint as applyToPoint51,
9589
+ compose as compose10
9306
9590
  } from "transformation-matrix";
9307
9591
 
9308
9592
  // lib/utils/get-sch-stroke-size.ts
@@ -9372,26 +9656,26 @@ var matchSchPortsToSymbolPorts = ({
9372
9656
  };
9373
9657
 
9374
9658
  // lib/utils/point-pairs-to-matrix.ts
9375
- import { compose as compose8, scale as scale4, translate as translate8 } from "transformation-matrix";
9659
+ import { compose as compose9, scale as scale5, translate as translate9 } from "transformation-matrix";
9376
9660
  function pointPairsToMatrix(a1, a2, b1, b2) {
9377
9661
  const tx = a2.x - a1.x;
9378
9662
  const ty = a2.y - a1.y;
9379
9663
  const originalDistance = Math.sqrt((b1.x - a1.x) ** 2 + (b1.y - a1.y) ** 2);
9380
9664
  const transformedDistance = Math.sqrt((b2.x - a2.x) ** 2 + (b2.y - a2.y) ** 2);
9381
9665
  const a = transformedDistance / originalDistance;
9382
- const translateMatrix = translate8(tx, ty);
9383
- const scaleMatrix = scale4(a, a);
9384
- return compose8(translateMatrix, scaleMatrix);
9666
+ const translateMatrix = translate9(tx, ty);
9667
+ const scaleMatrix = scale5(a, a);
9668
+ return compose9(translateMatrix, scaleMatrix);
9385
9669
  }
9386
9670
 
9387
9671
  // lib/sch/svg-object-fns/create-svg-error-text.ts
9388
- import { applyToPoint as applyToPoint49 } from "transformation-matrix";
9672
+ import { applyToPoint as applyToPoint50 } from "transformation-matrix";
9389
9673
  var createSvgSchErrorText = ({
9390
9674
  text,
9391
9675
  realCenter,
9392
9676
  realToScreenTransform
9393
9677
  }) => {
9394
- const screenCenter = applyToPoint49(realToScreenTransform, realCenter);
9678
+ const screenCenter = applyToPoint50(realToScreenTransform, realCenter);
9395
9679
  return {
9396
9680
  type: "element",
9397
9681
  name: "text",
@@ -9500,12 +9784,12 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
9500
9784
  minY: Math.min(...paths.flatMap((p) => p.points.map((pt) => pt.y))),
9501
9785
  maxY: Math.max(...paths.flatMap((p) => p.points.map((pt) => pt.y)))
9502
9786
  };
9503
- const [screenMinX, screenMinY] = applyToPoint50(
9504
- compose9(realToScreenTransform, transformFromSymbolToReal),
9787
+ const [screenMinX, screenMinY] = applyToPoint51(
9788
+ compose10(realToScreenTransform, transformFromSymbolToReal),
9505
9789
  [bounds.minX, bounds.minY]
9506
9790
  );
9507
- const [screenMaxX, screenMaxY] = applyToPoint50(
9508
- compose9(realToScreenTransform, transformFromSymbolToReal),
9791
+ const [screenMaxX, screenMaxY] = applyToPoint51(
9792
+ compose10(realToScreenTransform, transformFromSymbolToReal),
9509
9793
  [bounds.maxX, bounds.maxY]
9510
9794
  );
9511
9795
  const rectHeight = Math.abs(screenMaxY - screenMinY);
@@ -9533,8 +9817,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
9533
9817
  name: "path",
9534
9818
  attributes: {
9535
9819
  d: points.map((p, i) => {
9536
- const [x, y] = applyToPoint50(
9537
- compose9(realToScreenTransform, transformFromSymbolToReal),
9820
+ const [x, y] = applyToPoint51(
9821
+ compose10(realToScreenTransform, transformFromSymbolToReal),
9538
9822
  [p.x, p.y]
9539
9823
  );
9540
9824
  return `${i === 0 ? "M" : "L"} ${x} ${y}`;
@@ -9549,8 +9833,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
9549
9833
  });
9550
9834
  }
9551
9835
  for (const text of texts) {
9552
- const screenTextPos = applyToPoint50(
9553
- compose9(realToScreenTransform, transformFromSymbolToReal),
9836
+ const screenTextPos = applyToPoint51(
9837
+ compose10(realToScreenTransform, transformFromSymbolToReal),
9554
9838
  text
9555
9839
  );
9556
9840
  let textValue = "";
@@ -9601,11 +9885,11 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
9601
9885
  });
9602
9886
  }
9603
9887
  for (const box of boxes) {
9604
- const screenBoxPos = applyToPoint50(
9605
- compose9(realToScreenTransform, transformFromSymbolToReal),
9888
+ const screenBoxPos = applyToPoint51(
9889
+ compose10(realToScreenTransform, transformFromSymbolToReal),
9606
9890
  box
9607
9891
  );
9608
- const symbolToScreenScale = compose9(
9892
+ const symbolToScreenScale = compose10(
9609
9893
  realToScreenTransform,
9610
9894
  transformFromSymbolToReal
9611
9895
  ).a;
@@ -9625,8 +9909,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
9625
9909
  }
9626
9910
  for (const port of symbol.ports) {
9627
9911
  if (connectedSymbolPorts.has(port)) continue;
9628
- const screenPortPos = applyToPoint50(
9629
- compose9(realToScreenTransform, transformFromSymbolToReal),
9912
+ const screenPortPos = applyToPoint51(
9913
+ compose10(realToScreenTransform, transformFromSymbolToReal),
9630
9914
  port
9631
9915
  );
9632
9916
  svgObjects.push({
@@ -9645,8 +9929,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
9645
9929
  });
9646
9930
  }
9647
9931
  for (const circle of circles) {
9648
- const screenCirclePos = applyToPoint50(
9649
- compose9(realToScreenTransform, transformFromSymbolToReal),
9932
+ const screenCirclePos = applyToPoint51(
9933
+ compose10(realToScreenTransform, transformFromSymbolToReal),
9650
9934
  circle
9651
9935
  );
9652
9936
  const screenRadius = Math.abs(circle.radius * realToScreenTransform.a);
@@ -9672,14 +9956,14 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
9672
9956
  import { su as su10 } from "@tscircuit/circuit-json-util";
9673
9957
  import "schematic-symbols";
9674
9958
  import "svgson";
9675
- import { applyToPoint as applyToPoint56 } from "transformation-matrix";
9959
+ import { applyToPoint as applyToPoint57 } from "transformation-matrix";
9676
9960
 
9677
9961
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-port-on-box.ts
9678
9962
  import "transformation-matrix";
9679
9963
  import "@tscircuit/circuit-json-util";
9680
9964
 
9681
9965
  // lib/sch/svg-object-fns/create-svg-objects-for-sch-port-box-line.ts
9682
- import { applyToPoint as applyToPoint51 } from "transformation-matrix";
9966
+ import { applyToPoint as applyToPoint52 } from "transformation-matrix";
9683
9967
  import { su as su8 } from "@tscircuit/circuit-json-util";
9684
9968
  var PIN_CIRCLE_RADIUS_MM = 0.02;
9685
9969
  var createArrow = (tip, angle, size, color, strokeWidth) => {
@@ -9732,8 +10016,8 @@ var createSvgObjectsForSchPortBoxLine = ({
9732
10016
  realEdgePos.y += realPinLineLength;
9733
10017
  break;
9734
10018
  }
9735
- const screenSchPortPos = applyToPoint51(transform, schPort.center);
9736
- const screenRealEdgePos = applyToPoint51(transform, realEdgePos);
10019
+ const screenSchPortPos = applyToPoint52(transform, schPort.center);
10020
+ const screenRealEdgePos = applyToPoint52(transform, realEdgePos);
9737
10021
  const isConnected = isSourcePortConnected(circuitJson, schPort.source_port_id);
9738
10022
  const realLineEnd = { ...schPort.center };
9739
10023
  if (!isConnected) {
@@ -9752,7 +10036,7 @@ var createSvgObjectsForSchPortBoxLine = ({
9752
10036
  break;
9753
10037
  }
9754
10038
  }
9755
- const screenLineEnd = applyToPoint51(transform, realLineEnd);
10039
+ const screenLineEnd = applyToPoint52(transform, realLineEnd);
9756
10040
  svgObjects.push({
9757
10041
  name: "line",
9758
10042
  type: "element",
@@ -9873,7 +10157,7 @@ var createSvgObjectsForSchPortBoxLine = ({
9873
10157
  };
9874
10158
 
9875
10159
  // lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-number-text.ts
9876
- import { applyToPoint as applyToPoint52 } from "transformation-matrix";
10160
+ import { applyToPoint as applyToPoint53 } from "transformation-matrix";
9877
10161
  var createSvgObjectsForSchPortPinNumberText = (params) => {
9878
10162
  const svgObjects = [];
9879
10163
  const { schPort, schComponent, transform, circuitJson } = params;
@@ -9891,7 +10175,7 @@ var createSvgObjectsForSchPortPinNumberText = (params) => {
9891
10175
  } else {
9892
10176
  realPinNumberPos.y += 0.02;
9893
10177
  }
9894
- const screenPinNumberTextPos = applyToPoint52(transform, realPinNumberPos);
10178
+ const screenPinNumberTextPos = applyToPoint53(transform, realPinNumberPos);
9895
10179
  svgObjects.push({
9896
10180
  name: "text",
9897
10181
  type: "element",
@@ -9921,7 +10205,7 @@ var createSvgObjectsForSchPortPinNumberText = (params) => {
9921
10205
  };
9922
10206
 
9923
10207
  // lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-label.ts
9924
- import { applyToPoint as applyToPoint53 } from "transformation-matrix";
10208
+ import { applyToPoint as applyToPoint54 } from "transformation-matrix";
9925
10209
  var LABEL_DIST_FROM_EDGE_MM = 0.1;
9926
10210
  var createSvgObjectsForSchPortPinLabel = (params) => {
9927
10211
  const svgObjects = [];
@@ -9935,7 +10219,7 @@ var createSvgObjectsForSchPortPinLabel = (params) => {
9935
10219
  const realPinEdgeDistance = schPort.distance_from_component_edge ?? 0.4;
9936
10220
  realPinNumberPos.x += vecToEdge.x * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
9937
10221
  realPinNumberPos.y += vecToEdge.y * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
9938
- const screenPinNumberTextPos = applyToPoint53(transform, realPinNumberPos);
10222
+ const screenPinNumberTextPos = applyToPoint54(transform, realPinNumberPos);
9939
10223
  const label = schPort.display_pin_label ?? schComponent.port_labels?.[`${schPort.pin_number}`];
9940
10224
  if (!label) return [];
9941
10225
  const isNegated = label.startsWith("N_");
@@ -9983,13 +10267,13 @@ var createSvgObjectsFromSchPortOnBox = (params) => {
9983
10267
  };
9984
10268
 
9985
10269
  // lib/sch/svg-object-fns/create-svg-objects-for-sch-text.ts
9986
- import { applyToPoint as applyToPoint55 } from "transformation-matrix";
10270
+ import { applyToPoint as applyToPoint56 } from "transformation-matrix";
9987
10271
  var createSvgSchText = ({
9988
10272
  elm,
9989
10273
  transform,
9990
10274
  colorMap: colorMap2
9991
10275
  }) => {
9992
- const center = applyToPoint55(transform, elm.position);
10276
+ const center = applyToPoint56(transform, elm.position);
9993
10277
  const textAnchorMap = {
9994
10278
  center: "middle",
9995
10279
  center_right: "end",
@@ -10073,11 +10357,11 @@ var createSvgObjectsFromSchematicComponentWithBox = ({
10073
10357
  colorMap: colorMap2
10074
10358
  }) => {
10075
10359
  const svgObjects = [];
10076
- const componentScreenTopLeft = applyToPoint56(transform, {
10360
+ const componentScreenTopLeft = applyToPoint57(transform, {
10077
10361
  x: schComponent.center.x - schComponent.size.width / 2,
10078
10362
  y: schComponent.center.y + schComponent.size.height / 2
10079
10363
  });
10080
- const componentScreenBottomRight = applyToPoint56(transform, {
10364
+ const componentScreenBottomRight = applyToPoint57(transform, {
10081
10365
  x: schComponent.center.x + schComponent.size.width / 2,
10082
10366
  y: schComponent.center.y - schComponent.size.height / 2
10083
10367
  });
@@ -10163,13 +10447,13 @@ function createSvgObjectsFromSchematicComponent(params) {
10163
10447
  }
10164
10448
 
10165
10449
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-voltage-probe.ts
10166
- import { applyToPoint as applyToPoint57 } from "transformation-matrix";
10450
+ import { applyToPoint as applyToPoint58 } from "transformation-matrix";
10167
10451
  function createSvgObjectsFromSchVoltageProbe({
10168
10452
  probe,
10169
10453
  transform,
10170
10454
  colorMap: colorMap2
10171
10455
  }) {
10172
- const [screenX, screenY] = applyToPoint57(transform, [
10456
+ const [screenX, screenY] = applyToPoint58(transform, [
10173
10457
  probe.position.x,
10174
10458
  probe.position.y
10175
10459
  ]);
@@ -10276,17 +10560,17 @@ function createSvgObjectsFromSchVoltageProbe({
10276
10560
  }
10277
10561
 
10278
10562
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-debug-object.ts
10279
- import { applyToPoint as applyToPoint58 } from "transformation-matrix";
10563
+ import { applyToPoint as applyToPoint59 } from "transformation-matrix";
10280
10564
  function createSvgObjectsFromSchDebugObject({
10281
10565
  debugObject,
10282
10566
  transform
10283
10567
  }) {
10284
10568
  if (debugObject.shape === "rect") {
10285
- let [screenLeft, screenTop] = applyToPoint58(transform, [
10569
+ let [screenLeft, screenTop] = applyToPoint59(transform, [
10286
10570
  debugObject.center.x - debugObject.size.width / 2,
10287
10571
  debugObject.center.y - debugObject.size.height / 2
10288
10572
  ]);
10289
- let [screenRight, screenBottom] = applyToPoint58(transform, [
10573
+ let [screenRight, screenBottom] = applyToPoint59(transform, [
10290
10574
  debugObject.center.x + debugObject.size.width / 2,
10291
10575
  debugObject.center.y + debugObject.size.height / 2
10292
10576
  ]);
@@ -10296,7 +10580,7 @@ function createSvgObjectsFromSchDebugObject({
10296
10580
  ];
10297
10581
  const width = Math.abs(screenRight - screenLeft);
10298
10582
  const height = Math.abs(screenBottom - screenTop);
10299
- const [screenCenterX, screenCenterY] = applyToPoint58(transform, [
10583
+ const [screenCenterX, screenCenterY] = applyToPoint59(transform, [
10300
10584
  debugObject.center.x,
10301
10585
  debugObject.center.y
10302
10586
  ]);
@@ -10342,11 +10626,11 @@ function createSvgObjectsFromSchDebugObject({
10342
10626
  ];
10343
10627
  }
10344
10628
  if (debugObject.shape === "line") {
10345
- const [screenStartX, screenStartY] = applyToPoint58(transform, [
10629
+ const [screenStartX, screenStartY] = applyToPoint59(transform, [
10346
10630
  debugObject.start.x,
10347
10631
  debugObject.start.y
10348
10632
  ]);
10349
- const [screenEndX, screenEndY] = applyToPoint58(transform, [
10633
+ const [screenEndX, screenEndY] = applyToPoint59(transform, [
10350
10634
  debugObject.end.x,
10351
10635
  debugObject.end.y
10352
10636
  ]);
@@ -10396,7 +10680,7 @@ function createSvgObjectsFromSchDebugObject({
10396
10680
  }
10397
10681
 
10398
10682
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-trace.ts
10399
- import { applyToPoint as applyToPoint59 } from "transformation-matrix";
10683
+ import { applyToPoint as applyToPoint60 } from "transformation-matrix";
10400
10684
  function createSchematicTrace({
10401
10685
  trace,
10402
10686
  transform,
@@ -10410,11 +10694,11 @@ function createSchematicTrace({
10410
10694
  for (let edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
10411
10695
  const edge = edges[edgeIndex];
10412
10696
  if (edge.is_crossing) continue;
10413
- const [screenFromX, screenFromY] = applyToPoint59(transform, [
10697
+ const [screenFromX, screenFromY] = applyToPoint60(transform, [
10414
10698
  edge.from.x,
10415
10699
  edge.from.y
10416
10700
  ]);
10417
- const [screenToX, screenToY] = applyToPoint59(transform, [
10701
+ const [screenToX, screenToY] = applyToPoint60(transform, [
10418
10702
  edge.to.x,
10419
10703
  edge.to.y
10420
10704
  ]);
@@ -10458,11 +10742,11 @@ function createSchematicTrace({
10458
10742
  }
10459
10743
  for (const edge of edges) {
10460
10744
  if (!edge.is_crossing) continue;
10461
- const [screenFromX, screenFromY] = applyToPoint59(transform, [
10745
+ const [screenFromX, screenFromY] = applyToPoint60(transform, [
10462
10746
  edge.from.x,
10463
10747
  edge.from.y
10464
10748
  ]);
10465
- const [screenToX, screenToY] = applyToPoint59(transform, [
10749
+ const [screenToX, screenToY] = applyToPoint60(transform, [
10466
10750
  edge.to.x,
10467
10751
  edge.to.y
10468
10752
  ]);
@@ -10506,7 +10790,7 @@ function createSchematicTrace({
10506
10790
  }
10507
10791
  if (trace.junctions) {
10508
10792
  for (const junction of trace.junctions) {
10509
- const [screenX, screenY] = applyToPoint59(transform, [
10793
+ const [screenX, screenY] = applyToPoint60(transform, [
10510
10794
  junction.x,
10511
10795
  junction.y
10512
10796
  ]);
@@ -10560,6 +10844,15 @@ function createSchematicTrace({
10560
10844
  }
10561
10845
 
10562
10846
  // lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label.ts
10847
+ import {
10848
+ applyToPoint as applyToPoint62,
10849
+ compose as compose12,
10850
+ rotate as rotate7,
10851
+ scale as scale7,
10852
+ translate as translate12
10853
+ } from "transformation-matrix";
10854
+
10855
+ // lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label-with-symbol.ts
10563
10856
  import {
10564
10857
  applyToPoint as applyToPoint61,
10565
10858
  compose as compose11,
@@ -10567,15 +10860,6 @@ import {
10567
10860
  scale as scale6,
10568
10861
  translate as translate11
10569
10862
  } from "transformation-matrix";
10570
-
10571
- // lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label-with-symbol.ts
10572
- import {
10573
- applyToPoint as applyToPoint60,
10574
- compose as compose10,
10575
- rotate as rotate5,
10576
- scale as scale5,
10577
- translate as translate10
10578
- } from "transformation-matrix";
10579
10863
  import { symbols as symbols3 } from "schematic-symbols";
10580
10864
  var createSvgObjectsForSchNetLabelWithSymbol = ({
10581
10865
  schNetLabel,
@@ -10618,7 +10902,7 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
10618
10902
  y: schNetLabel.center.y - realTextGrowthVec.y * fullWidthFsr * fontSizeMm / 2
10619
10903
  };
10620
10904
  const pathRotation = 0;
10621
- const rotationMatrix = rotate5(pathRotation / 180 * Math.PI);
10905
+ const rotationMatrix = rotate6(pathRotation / 180 * Math.PI);
10622
10906
  const symbolBounds = {
10623
10907
  minX: Math.min(
10624
10908
  ...symbol.primitives.flatMap(
@@ -10645,22 +10929,22 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
10645
10929
  x: symbolBounds.minX,
10646
10930
  y: (symbolBounds.minY + symbolBounds.maxY) / 2
10647
10931
  };
10648
- const rotatedSymbolEnd = applyToPoint60(rotationMatrix, symbolEndPoint);
10649
- const symbolToRealTransform = compose10(
10650
- translate10(
10932
+ const rotatedSymbolEnd = applyToPoint61(rotationMatrix, symbolEndPoint);
10933
+ const symbolToRealTransform = compose11(
10934
+ translate11(
10651
10935
  realAnchorPosition.x - rotatedSymbolEnd.x,
10652
10936
  realAnchorPosition.y - rotatedSymbolEnd.y
10653
10937
  ),
10654
10938
  rotationMatrix,
10655
- scale5(1)
10939
+ scale6(1)
10656
10940
  // Use full symbol size
10657
10941
  );
10658
- const [screenMinX, screenMinY] = applyToPoint60(
10659
- compose10(realToScreenTransform, symbolToRealTransform),
10942
+ const [screenMinX, screenMinY] = applyToPoint61(
10943
+ compose11(realToScreenTransform, symbolToRealTransform),
10660
10944
  [bounds.minX, bounds.minY]
10661
10945
  );
10662
- const [screenMaxX, screenMaxY] = applyToPoint60(
10663
- compose10(realToScreenTransform, symbolToRealTransform),
10946
+ const [screenMaxX, screenMaxY] = applyToPoint61(
10947
+ compose11(realToScreenTransform, symbolToRealTransform),
10664
10948
  [bounds.maxX, bounds.maxY]
10665
10949
  );
10666
10950
  const rectHeight = Math.abs(screenMaxY - screenMinY);
@@ -10683,8 +10967,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
10683
10967
  });
10684
10968
  for (const path of symbolPaths) {
10685
10969
  const symbolPath = path.points.map((p, i) => {
10686
- const [x, y] = applyToPoint60(
10687
- compose10(realToScreenTransform, symbolToRealTransform),
10970
+ const [x, y] = applyToPoint61(
10971
+ compose11(realToScreenTransform, symbolToRealTransform),
10688
10972
  [p.x, p.y]
10689
10973
  );
10690
10974
  return `${i === 0 ? "M" : "L"} ${x} ${y}`;
@@ -10704,8 +10988,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
10704
10988
  });
10705
10989
  }
10706
10990
  for (const text of symbolTexts) {
10707
- const screenTextPos = applyToPoint60(
10708
- compose10(realToScreenTransform, symbolToRealTransform),
10991
+ const screenTextPos = applyToPoint61(
10992
+ compose11(realToScreenTransform, symbolToRealTransform),
10709
10993
  text
10710
10994
  );
10711
10995
  let textValue = text.text;
@@ -10714,8 +10998,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
10714
10998
  } else if (textValue === "{VAL}") {
10715
10999
  textValue = "";
10716
11000
  }
10717
- const scale9 = Math.abs(realToScreenTransform.a);
10718
- const baseOffset = scale9 * 0.1;
11001
+ const scale10 = Math.abs(realToScreenTransform.a);
11002
+ const baseOffset = scale10 * 0.1;
10719
11003
  const offsetScreenPos = {
10720
11004
  x: screenTextPos.x,
10721
11005
  y: screenTextPos.y
@@ -10746,11 +11030,11 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
10746
11030
  });
10747
11031
  }
10748
11032
  for (const box of symbolBoxes) {
10749
- const screenBoxPos = applyToPoint60(
10750
- compose10(realToScreenTransform, symbolToRealTransform),
11033
+ const screenBoxPos = applyToPoint61(
11034
+ compose11(realToScreenTransform, symbolToRealTransform),
10751
11035
  box
10752
11036
  );
10753
- const symbolToScreenScale = compose10(
11037
+ const symbolToScreenScale = compose11(
10754
11038
  realToScreenTransform,
10755
11039
  symbolToRealTransform
10756
11040
  ).a;
@@ -10769,11 +11053,11 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
10769
11053
  });
10770
11054
  }
10771
11055
  for (const circle of symbolCircles) {
10772
- const screenCirclePos = applyToPoint60(
10773
- compose10(realToScreenTransform, symbolToRealTransform),
11056
+ const screenCirclePos = applyToPoint61(
11057
+ compose11(realToScreenTransform, symbolToRealTransform),
10774
11058
  circle
10775
11059
  );
10776
- const symbolToScreenScale = compose10(
11060
+ const symbolToScreenScale = compose11(
10777
11061
  realToScreenTransform,
10778
11062
  symbolToRealTransform
10779
11063
  ).a;
@@ -10814,14 +11098,14 @@ var createSvgObjectsForSchNetLabel = ({
10814
11098
  const fontSizePx = getSchScreenFontSize(realToScreenTransform, "net_label");
10815
11099
  const fontSizeMm = getSchMmFontSize("net_label");
10816
11100
  const textWidthFSR = estimateTextWidth(labelText || "");
10817
- const screenCenter = applyToPoint61(realToScreenTransform, schNetLabel.center);
11101
+ const screenCenter = applyToPoint62(realToScreenTransform, schNetLabel.center);
10818
11102
  const realTextGrowthVec = getUnitVectorFromOutsideToEdge(
10819
11103
  schNetLabel.anchor_side
10820
11104
  );
10821
11105
  const screenTextGrowthVec = { ...realTextGrowthVec };
10822
11106
  screenTextGrowthVec.y *= -1;
10823
11107
  const fullWidthFsr = textWidthFSR + ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_EXTRA_PER_CHARACTER_FSR * labelText.length + END_PADDING_FSR;
10824
- const screenAnchorPosition = schNetLabel.anchor_position ? applyToPoint61(realToScreenTransform, schNetLabel.anchor_position) : {
11108
+ const screenAnchorPosition = schNetLabel.anchor_position ? applyToPoint62(realToScreenTransform, schNetLabel.anchor_position) : {
10825
11109
  x: screenCenter.x - screenTextGrowthVec.x * fullWidthFsr * fontSizePx / 2,
10826
11110
  y: screenCenter.y - screenTextGrowthVec.y * fullWidthFsr * fontSizePx / 2
10827
11111
  };
@@ -10862,12 +11146,12 @@ var createSvgObjectsForSchNetLabel = ({
10862
11146
  y: -0.6
10863
11147
  }
10864
11148
  ].map(
10865
- (fontRelativePoint) => applyToPoint61(
10866
- compose11(
11149
+ (fontRelativePoint) => applyToPoint62(
11150
+ compose12(
10867
11151
  realToScreenTransform,
10868
- translate11(realAnchorPosition.x, realAnchorPosition.y),
10869
- scale6(fontSizeMm),
10870
- rotate6(pathRotation / 180 * Math.PI)
11152
+ translate12(realAnchorPosition.x, realAnchorPosition.y),
11153
+ scale7(fontSizeMm),
11154
+ rotate7(pathRotation / 180 * Math.PI)
10871
11155
  ),
10872
11156
  fontRelativePoint
10873
11157
  )
@@ -10939,17 +11223,17 @@ var createSvgObjectsForSchNetLabel = ({
10939
11223
  };
10940
11224
 
10941
11225
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-box.ts
10942
- import { applyToPoint as applyToPoint62 } from "transformation-matrix";
11226
+ import { applyToPoint as applyToPoint63 } from "transformation-matrix";
10943
11227
  var createSvgObjectsFromSchematicBox = ({
10944
11228
  schematicBox,
10945
11229
  transform,
10946
11230
  colorMap: colorMap2
10947
11231
  }) => {
10948
- const topLeft = applyToPoint62(transform, {
11232
+ const topLeft = applyToPoint63(transform, {
10949
11233
  x: schematicBox.x,
10950
11234
  y: schematicBox.y
10951
11235
  });
10952
- const bottomRight = applyToPoint62(transform, {
11236
+ const bottomRight = applyToPoint63(transform, {
10953
11237
  x: schematicBox.x + schematicBox.width,
10954
11238
  y: schematicBox.y + schematicBox.height
10955
11239
  });
@@ -10985,7 +11269,7 @@ var createSvgObjectsFromSchematicBox = ({
10985
11269
  };
10986
11270
 
10987
11271
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-table.ts
10988
- import { applyToPoint as applyToPoint63 } from "transformation-matrix";
11272
+ import { applyToPoint as applyToPoint64 } from "transformation-matrix";
10989
11273
  var createSvgObjectsFromSchematicTable = ({
10990
11274
  schematicTable,
10991
11275
  transform,
@@ -11018,11 +11302,11 @@ var createSvgObjectsFromSchematicTable = ({
11018
11302
  const svgObjects = [];
11019
11303
  const borderStrokeWidth = border_width * Math.abs(transform.a);
11020
11304
  const gridStrokeWidth = getSchStrokeSize(transform);
11021
- const [screenTopLeftX, screenTopLeftY] = applyToPoint63(transform, [
11305
+ const [screenTopLeftX, screenTopLeftY] = applyToPoint64(transform, [
11022
11306
  topLeftX,
11023
11307
  topLeftY
11024
11308
  ]);
11025
- const [screenBottomRightX, screenBottomRightY] = applyToPoint63(transform, [
11309
+ const [screenBottomRightX, screenBottomRightY] = applyToPoint64(transform, [
11026
11310
  topLeftX + totalWidth,
11027
11311
  topLeftY - totalHeight
11028
11312
  ]);
@@ -11054,8 +11338,8 @@ var createSvgObjectsFromSchematicTable = ({
11054
11338
  (cell) => cell.start_column_index <= i && cell.end_column_index > i && cell.start_row_index <= j && cell.end_row_index >= j
11055
11339
  );
11056
11340
  if (!isMerged) {
11057
- const start = applyToPoint63(transform, { x: currentX, y: segmentStartY });
11058
- const end = applyToPoint63(transform, { x: currentX, y: segmentEndY });
11341
+ const start = applyToPoint64(transform, { x: currentX, y: segmentStartY });
11342
+ const end = applyToPoint64(transform, { x: currentX, y: segmentEndY });
11059
11343
  svgObjects.push({
11060
11344
  name: "line",
11061
11345
  type: "element",
@@ -11084,11 +11368,11 @@ var createSvgObjectsFromSchematicTable = ({
11084
11368
  (cell) => cell.start_row_index <= i && cell.end_row_index > i && cell.start_column_index <= j && cell.end_column_index >= j
11085
11369
  );
11086
11370
  if (!isMerged) {
11087
- const start = applyToPoint63(transform, {
11371
+ const start = applyToPoint64(transform, {
11088
11372
  x: segmentStartX,
11089
11373
  y: currentY
11090
11374
  });
11091
- const end = applyToPoint63(transform, { x: segmentEndX, y: currentY });
11375
+ const end = applyToPoint64(transform, { x: segmentEndX, y: currentY });
11092
11376
  svgObjects.push({
11093
11377
  name: "line",
11094
11378
  type: "element",
@@ -11130,7 +11414,7 @@ var createSvgObjectsFromSchematicTable = ({
11130
11414
  } else if (vertical_align === "bottom") {
11131
11415
  realTextAnchorPos.y = cellTopLeftY - cellHeight + cell_padding;
11132
11416
  }
11133
- const screenTextAnchorPos = applyToPoint63(transform, realTextAnchorPos);
11417
+ const screenTextAnchorPos = applyToPoint64(transform, realTextAnchorPos);
11134
11418
  const fontSize = getSchScreenFontSize(
11135
11419
  transform,
11136
11420
  "reference_designator",
@@ -11186,13 +11470,13 @@ var createSvgObjectsFromSchematicTable = ({
11186
11470
 
11187
11471
  // lib/sch/svg-object-fns/create-svg-objects-for-sch-port-hover.ts
11188
11472
  import { su as su11 } from "@tscircuit/circuit-json-util";
11189
- import { applyToPoint as applyToPoint64 } from "transformation-matrix";
11473
+ import { applyToPoint as applyToPoint65 } from "transformation-matrix";
11190
11474
  var PIN_CIRCLE_RADIUS_MM2 = 0.02;
11191
11475
  var createSvgObjectsForSchPortHover = ({
11192
11476
  schPort,
11193
11477
  transform
11194
11478
  }) => {
11195
- const screenSchPortPos = applyToPoint64(transform, schPort.center);
11479
+ const screenSchPortPos = applyToPoint65(transform, schPort.center);
11196
11480
  const pinRadiusPx = Math.abs(transform.a) * PIN_CIRCLE_RADIUS_MM2 * 2;
11197
11481
  return [
11198
11482
  {
@@ -11237,14 +11521,14 @@ var createSvgObjectsForSchComponentPortHovers = ({
11237
11521
  };
11238
11522
 
11239
11523
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-line.ts
11240
- import { applyToPoint as applyToPoint65 } from "transformation-matrix";
11524
+ import { applyToPoint as applyToPoint66 } from "transformation-matrix";
11241
11525
  function createSvgObjectsFromSchematicLine({
11242
11526
  schLine,
11243
11527
  transform,
11244
11528
  colorMap: colorMap2
11245
11529
  }) {
11246
- const p1 = applyToPoint65(transform, { x: schLine.x1, y: schLine.y1 });
11247
- const p2 = applyToPoint65(transform, { x: schLine.x2, y: schLine.y2 });
11530
+ const p1 = applyToPoint66(transform, { x: schLine.x1, y: schLine.y1 });
11531
+ const p2 = applyToPoint66(transform, { x: schLine.x2, y: schLine.y2 });
11248
11532
  const strokeWidth = schLine.stroke_width ?? 0.02;
11249
11533
  const transformedStrokeWidth = Math.abs(transform.a) * strokeWidth;
11250
11534
  return [
@@ -11273,13 +11557,13 @@ function createSvgObjectsFromSchematicLine({
11273
11557
  }
11274
11558
 
11275
11559
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-circle.ts
11276
- import { applyToPoint as applyToPoint66 } from "transformation-matrix";
11560
+ import { applyToPoint as applyToPoint67 } from "transformation-matrix";
11277
11561
  function createSvgObjectsFromSchematicCircle({
11278
11562
  schCircle,
11279
11563
  transform,
11280
11564
  colorMap: colorMap2
11281
11565
  }) {
11282
- const center = applyToPoint66(transform, schCircle.center);
11566
+ const center = applyToPoint67(transform, schCircle.center);
11283
11567
  const transformedRadius = Math.abs(transform.a) * schCircle.radius;
11284
11568
  const strokeWidth = schCircle.stroke_width ?? 0.02;
11285
11569
  const transformedStrokeWidth = Math.abs(transform.a) * strokeWidth;
@@ -11309,13 +11593,13 @@ function createSvgObjectsFromSchematicCircle({
11309
11593
  }
11310
11594
 
11311
11595
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-rect.ts
11312
- import { applyToPoint as applyToPoint67 } from "transformation-matrix";
11596
+ import { applyToPoint as applyToPoint68 } from "transformation-matrix";
11313
11597
  function createSvgObjectsFromSchematicRect({
11314
11598
  schRect,
11315
11599
  transform,
11316
11600
  colorMap: colorMap2
11317
11601
  }) {
11318
- const center = applyToPoint67(transform, schRect.center);
11602
+ const center = applyToPoint68(transform, schRect.center);
11319
11603
  const transformedWidth = Math.abs(transform.a) * schRect.width;
11320
11604
  const transformedHeight = Math.abs(transform.d) * schRect.height;
11321
11605
  const strokeWidth = schRect.stroke_width ?? 0.02;
@@ -11351,13 +11635,13 @@ function createSvgObjectsFromSchematicRect({
11351
11635
  }
11352
11636
 
11353
11637
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-arc.ts
11354
- import { applyToPoint as applyToPoint68 } from "transformation-matrix";
11638
+ import { applyToPoint as applyToPoint69 } from "transformation-matrix";
11355
11639
  function createSvgObjectsFromSchematicArc({
11356
11640
  schArc,
11357
11641
  transform,
11358
11642
  colorMap: colorMap2
11359
11643
  }) {
11360
- const center = applyToPoint68(transform, schArc.center);
11644
+ const center = applyToPoint69(transform, schArc.center);
11361
11645
  const transformedRadius = Math.abs(transform.a) * schArc.radius;
11362
11646
  const strokeWidth = schArc.stroke_width ?? 0.02;
11363
11647
  const transformedStrokeWidth = Math.abs(transform.a) * strokeWidth;
@@ -12364,9 +12648,9 @@ function convertCircuitJsonToSchematicSimulationSvg({
12364
12648
  const rawSchematicHeight = Math.max(1, height * clampedRatio);
12365
12649
  const rawSimulationHeight = Math.max(1, height - rawSchematicHeight);
12366
12650
  const totalRawHeight = rawSchematicHeight + rawSimulationHeight;
12367
- const scale9 = totalRawHeight === 0 ? 1 : height / totalRawHeight;
12368
- const schematicHeight = rawSchematicHeight * scale9;
12369
- const simulationHeight = rawSimulationHeight * scale9;
12651
+ const scale10 = totalRawHeight === 0 ? 1 : height / totalRawHeight;
12652
+ const schematicHeight = rawSchematicHeight * scale10;
12653
+ const simulationHeight = rawSimulationHeight * scale10;
12370
12654
  const schematicSvg = convertCircuitJsonToSchematicSvg(schematicElements, {
12371
12655
  ...schematicOptions,
12372
12656
  width,
@@ -12458,21 +12742,21 @@ function formatNumber2(value) {
12458
12742
  }
12459
12743
 
12460
12744
  // lib/pcb/convert-circuit-json-to-solder-paste-mask.ts
12461
- import { distance as distance2 } from "circuit-json";
12745
+ import { distance as distance3 } from "circuit-json";
12462
12746
  import { stringify as stringify7 } from "svgson";
12463
12747
  import {
12464
- applyToPoint as applyToPoint71,
12465
- compose as compose14,
12466
- scale as scale8,
12467
- translate as translate14
12748
+ applyToPoint as applyToPoint72,
12749
+ compose as compose15,
12750
+ scale as scale9,
12751
+ translate as translate15
12468
12752
  } from "transformation-matrix";
12469
12753
 
12470
12754
  // lib/pcb/svg-object-fns/convert-circuit-json-to-solder-paste-mask.ts
12471
- import { applyToPoint as applyToPoint70 } from "transformation-matrix";
12755
+ import { applyToPoint as applyToPoint71 } from "transformation-matrix";
12472
12756
  function createSvgObjectsFromSolderPaste(solderPaste, ctx) {
12473
12757
  const { transform, layer: layerFilter } = ctx;
12474
12758
  if (layerFilter && solderPaste.layer !== layerFilter) return [];
12475
- const [x, y] = applyToPoint70(transform, [solderPaste.x, solderPaste.y]);
12759
+ const [x, y] = applyToPoint71(transform, [solderPaste.x, solderPaste.y]);
12476
12760
  if (solderPaste.shape === "rect" || solderPaste.shape === "rotated_rect") {
12477
12761
  const width = solderPaste.width * Math.abs(transform.a);
12478
12762
  const height = solderPaste.height * Math.abs(transform.d);
@@ -12576,8 +12860,8 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
12576
12860
  }
12577
12861
  } else if (item.type === "pcb_panel") {
12578
12862
  const panel = item;
12579
- const width = distance2.parse(panel.width);
12580
- const height = distance2.parse(panel.height);
12863
+ const width = distance3.parse(panel.width);
12864
+ const height = distance3.parse(panel.height);
12581
12865
  if (width !== void 0 && height !== void 0) {
12582
12866
  const center = panel.center ?? { x: width / 2, y: height / 2 };
12583
12867
  updateBounds(center, width, height);
@@ -12596,12 +12880,12 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
12596
12880
  const scaleFactor = Math.min(scaleX, scaleY);
12597
12881
  const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2;
12598
12882
  const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2;
12599
- const transform = compose14(
12600
- translate14(
12883
+ const transform = compose15(
12884
+ translate15(
12601
12885
  offsetX - minX * scaleFactor + padding * scaleFactor,
12602
12886
  svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
12603
12887
  ),
12604
- scale8(scaleFactor, -scaleFactor)
12888
+ scale9(scaleFactor, -scaleFactor)
12605
12889
  // Flip in y-direction
12606
12890
  );
12607
12891
  const ctx = {
@@ -12698,8 +12982,8 @@ function createSvgObjects4({ elm, ctx }) {
12698
12982
  }
12699
12983
  }
12700
12984
  function createSvgObjectFromPcbBoundary2(transform, minX, minY, maxX, maxY) {
12701
- const [x1, y1] = applyToPoint71(transform, [minX, minY]);
12702
- const [x2, y2] = applyToPoint71(transform, [maxX, maxY]);
12985
+ const [x1, y1] = applyToPoint72(transform, [minX, minY]);
12986
+ const [x2, y2] = applyToPoint72(transform, [maxX, maxY]);
12703
12987
  const width = Math.abs(x2 - x1);
12704
12988
  const height = Math.abs(y2 - y1);
12705
12989
  const x = Math.min(x1, x2);