circuit-to-svg 0.0.193 → 0.0.195

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
@@ -485,11 +485,19 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
485
485
  ];
486
486
  }
487
487
  if (hole.shape === "pill_hole_with_rect_pad") {
488
- const scaledRectPadWidth = hole.rect_pad_width * Math.abs(transform.a);
489
- const scaledRectPadHeight = hole.rect_pad_height * Math.abs(transform.a);
490
- const scaledRectBorderRadius = (hole.rect_border_radius ?? 0) * Math.abs(transform.a);
491
- const scaledHoleHeight = hole.hole_height * Math.abs(transform.a);
492
- const scaledHoleWidth = hole.hole_width * Math.abs(transform.a);
488
+ const pillHole = hole;
489
+ const scaledRectPadWidth = pillHole.rect_pad_width * Math.abs(transform.a);
490
+ const scaledRectPadHeight = pillHole.rect_pad_height * Math.abs(transform.a);
491
+ const scaledRectBorderRadius = (pillHole.rect_border_radius ?? 0) * Math.abs(transform.a);
492
+ const scaledHoleHeight = pillHole.hole_height * Math.abs(transform.a);
493
+ const scaledHoleWidth = pillHole.hole_width * Math.abs(transform.a);
494
+ const pillHoleWithOffsets = pillHole;
495
+ const holeOffsetX = pillHoleWithOffsets.hole_offset_x ?? 0;
496
+ const holeOffsetY = pillHoleWithOffsets.hole_offset_y ?? 0;
497
+ const [holeCenterX, holeCenterY] = applyToPoint4(transform, [
498
+ pillHole.x + holeOffsetX,
499
+ pillHole.y + holeOffsetY
500
+ ]);
493
501
  const holeRadius = Math.min(scaledHoleHeight, scaledHoleWidth) / 2;
494
502
  return [
495
503
  {
@@ -522,8 +530,8 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
522
530
  attributes: {
523
531
  class: "pcb-hole-inner",
524
532
  fill: colorMap2.drill,
525
- x: (x - scaledHoleWidth / 2).toString(),
526
- y: (y - scaledHoleHeight / 2).toString(),
533
+ x: (holeCenterX - scaledHoleWidth / 2).toString(),
534
+ y: (holeCenterY - scaledHoleHeight / 2).toString(),
527
535
  width: scaledHoleWidth.toString(),
528
536
  height: scaledHoleHeight.toString(),
529
537
  rx: holeRadius.toString(),
@@ -539,11 +547,19 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
539
547
  ];
540
548
  }
541
549
  if (hole.shape === "rotated_pill_hole_with_rect_pad") {
542
- const scaledRectPadWidth = hole.rect_pad_width * Math.abs(transform.a);
543
- const scaledRectPadHeight = hole.rect_pad_height * Math.abs(transform.a);
544
- const scaledRectBorderRadius = (hole.rect_border_radius ?? 0) * Math.abs(transform.a);
545
- const scaledHoleHeight = hole.hole_height * Math.abs(transform.a);
546
- const scaledHoleWidth = hole.hole_width * Math.abs(transform.a);
550
+ const rotatedHole = hole;
551
+ const scaledRectPadWidth = rotatedHole.rect_pad_width * Math.abs(transform.a);
552
+ const scaledRectPadHeight = rotatedHole.rect_pad_height * Math.abs(transform.a);
553
+ const scaledRectBorderRadius = (rotatedHole.rect_border_radius ?? 0) * Math.abs(transform.a);
554
+ const scaledHoleHeight = rotatedHole.hole_height * Math.abs(transform.a);
555
+ const scaledHoleWidth = rotatedHole.hole_width * Math.abs(transform.a);
556
+ const rotatedHoleWithOffsets = rotatedHole;
557
+ const holeOffsetX = rotatedHoleWithOffsets.hole_offset_x ?? 0;
558
+ const holeOffsetY = rotatedHoleWithOffsets.hole_offset_y ?? 0;
559
+ const [holeCenterX, holeCenterY] = applyToPoint4(transform, [
560
+ rotatedHole.x + holeOffsetX,
561
+ rotatedHole.y + holeOffsetY
562
+ ]);
547
563
  const holeRadius = Math.min(scaledHoleHeight, scaledHoleWidth) / 2;
548
564
  return [
549
565
  {
@@ -560,7 +576,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
560
576
  y: (-scaledRectPadHeight / 2).toString(),
561
577
  width: scaledRectPadWidth.toString(),
562
578
  height: scaledRectPadHeight.toString(),
563
- transform: `translate(${x} ${y}) rotate(${-hole.rect_ccw_rotation})`,
579
+ transform: `translate(${x} ${y}) rotate(${-rotatedHole.rect_ccw_rotation})`,
564
580
  ...scaledRectBorderRadius ? {
565
581
  rx: scaledRectBorderRadius.toString(),
566
582
  ry: scaledRectBorderRadius.toString()
@@ -581,7 +597,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
581
597
  height: scaledHoleHeight.toString(),
582
598
  rx: holeRadius.toString(),
583
599
  ry: holeRadius.toString(),
584
- transform: `translate(${x} ${y}) rotate(${-hole.hole_ccw_rotation})`
600
+ transform: `translate(${holeCenterX} ${holeCenterY}) rotate(${-rotatedHole.hole_ccw_rotation})`
585
601
  },
586
602
  value: "",
587
603
  children: []
@@ -1015,110 +1031,187 @@ import { applyToPoint as applyToPoint11 } from "transformation-matrix";
1015
1031
  function createSvgObjectsFromSmtPad(pad, ctx) {
1016
1032
  const { transform, layer: layerFilter, colorMap: colorMap2 } = ctx;
1017
1033
  if (layerFilter && pad.layer !== layerFilter) return [];
1034
+ const isCoveredWithSolderMask = Boolean(pad?.is_covered_with_solder_mask);
1035
+ const solderMaskColor = colorMap2.soldermask[pad.layer] ?? colorMap2.soldermask.top;
1018
1036
  if (pad.shape === "rect" || pad.shape === "rotated_rect") {
1019
1037
  const width = pad.width * Math.abs(transform.a);
1020
1038
  const height = pad.height * Math.abs(transform.d);
1021
1039
  const [x, y] = applyToPoint11(transform, [pad.x, pad.y]);
1022
1040
  const scaledBorderRadius = (pad.rect_border_radius ?? 0) * Math.abs(transform.a);
1023
1041
  if (pad.shape === "rotated_rect" && pad.ccw_rotation) {
1024
- return [
1025
- {
1026
- name: "rect",
1027
- type: "element",
1028
- attributes: {
1029
- class: "pcb-pad",
1030
- fill: layerNameToColor(pad.layer, colorMap2),
1031
- x: (-width / 2).toString(),
1032
- y: (-height / 2).toString(),
1033
- width: width.toString(),
1034
- height: height.toString(),
1035
- transform: `translate(${x} ${y}) rotate(${-pad.ccw_rotation})`,
1036
- "data-layer": pad.layer,
1037
- ...scaledBorderRadius ? {
1038
- rx: scaledBorderRadius.toString(),
1039
- ry: scaledBorderRadius.toString()
1040
- } : {}
1041
- }
1042
- }
1043
- ];
1044
- }
1045
- return [
1046
- {
1042
+ const padElement2 = {
1047
1043
  name: "rect",
1048
1044
  type: "element",
1045
+ value: "",
1046
+ children: [],
1049
1047
  attributes: {
1050
1048
  class: "pcb-pad",
1051
1049
  fill: layerNameToColor(pad.layer, colorMap2),
1052
- x: (x - width / 2).toString(),
1053
- y: (y - height / 2).toString(),
1050
+ x: (-width / 2).toString(),
1051
+ y: (-height / 2).toString(),
1054
1052
  width: width.toString(),
1055
1053
  height: height.toString(),
1054
+ transform: `translate(${x} ${y}) rotate(${-pad.ccw_rotation})`,
1056
1055
  "data-layer": pad.layer,
1057
1056
  ...scaledBorderRadius ? {
1058
1057
  rx: scaledBorderRadius.toString(),
1059
1058
  ry: scaledBorderRadius.toString()
1060
1059
  } : {}
1061
1060
  }
1061
+ };
1062
+ if (!isCoveredWithSolderMask) {
1063
+ return [padElement2];
1062
1064
  }
1063
- ];
1065
+ const maskElement2 = {
1066
+ name: padElement2.name,
1067
+ type: padElement2.type,
1068
+ value: "",
1069
+ children: [],
1070
+ attributes: {
1071
+ ...padElement2.attributes,
1072
+ class: "pcb-solder-mask",
1073
+ fill: solderMaskColor
1074
+ }
1075
+ };
1076
+ return [padElement2, maskElement2];
1077
+ }
1078
+ const padElement = {
1079
+ name: "rect",
1080
+ type: "element",
1081
+ value: "",
1082
+ children: [],
1083
+ attributes: {
1084
+ class: "pcb-pad",
1085
+ fill: layerNameToColor(pad.layer, colorMap2),
1086
+ x: (x - width / 2).toString(),
1087
+ y: (y - height / 2).toString(),
1088
+ width: width.toString(),
1089
+ height: height.toString(),
1090
+ "data-layer": pad.layer,
1091
+ ...scaledBorderRadius ? {
1092
+ rx: scaledBorderRadius.toString(),
1093
+ ry: scaledBorderRadius.toString()
1094
+ } : {}
1095
+ }
1096
+ };
1097
+ if (!isCoveredWithSolderMask) {
1098
+ return [padElement];
1099
+ }
1100
+ const maskElement = {
1101
+ name: padElement.name,
1102
+ type: padElement.type,
1103
+ value: "",
1104
+ children: [],
1105
+ attributes: {
1106
+ ...padElement.attributes,
1107
+ class: "pcb-solder-mask",
1108
+ fill: solderMaskColor
1109
+ }
1110
+ };
1111
+ return [padElement, maskElement];
1064
1112
  }
1065
1113
  if (pad.shape === "pill") {
1066
1114
  const width = pad.width * Math.abs(transform.a);
1067
1115
  const height = pad.height * Math.abs(transform.d);
1068
1116
  const radius = pad.radius * Math.abs(transform.a);
1069
1117
  const [x, y] = applyToPoint11(transform, [pad.x, pad.y]);
1070
- return [
1071
- {
1072
- name: "rect",
1073
- type: "element",
1074
- attributes: {
1075
- class: "pcb-pad",
1076
- fill: layerNameToColor(pad.layer, colorMap2),
1077
- x: (x - width / 2).toString(),
1078
- y: (y - height / 2).toString(),
1079
- width: width.toString(),
1080
- height: height.toString(),
1081
- rx: radius.toString(),
1082
- ry: radius.toString(),
1083
- "data-layer": pad.layer
1084
- }
1118
+ const padElement = {
1119
+ name: "rect",
1120
+ type: "element",
1121
+ value: "",
1122
+ children: [],
1123
+ attributes: {
1124
+ class: "pcb-pad",
1125
+ fill: layerNameToColor(pad.layer, colorMap2),
1126
+ x: (x - width / 2).toString(),
1127
+ y: (y - height / 2).toString(),
1128
+ width: width.toString(),
1129
+ height: height.toString(),
1130
+ rx: radius.toString(),
1131
+ ry: radius.toString(),
1132
+ "data-layer": pad.layer
1085
1133
  }
1086
- ];
1134
+ };
1135
+ if (!isCoveredWithSolderMask) {
1136
+ return [padElement];
1137
+ }
1138
+ const maskElement = {
1139
+ name: padElement.name,
1140
+ type: padElement.type,
1141
+ value: "",
1142
+ children: [],
1143
+ attributes: {
1144
+ ...padElement.attributes,
1145
+ class: "pcb-solder-mask",
1146
+ fill: solderMaskColor
1147
+ }
1148
+ };
1149
+ return [padElement, maskElement];
1087
1150
  }
1088
1151
  if (pad.shape === "circle") {
1089
1152
  const radius = pad.radius * Math.abs(transform.a);
1090
1153
  const [x, y] = applyToPoint11(transform, [pad.x, pad.y]);
1091
- return [
1092
- {
1093
- name: "circle",
1094
- type: "element",
1095
- attributes: {
1096
- class: "pcb-pad",
1097
- fill: layerNameToColor(pad.layer, colorMap2),
1098
- cx: x.toString(),
1099
- cy: y.toString(),
1100
- r: radius.toString(),
1101
- "data-layer": pad.layer
1102
- }
1154
+ const padElement = {
1155
+ name: "circle",
1156
+ type: "element",
1157
+ value: "",
1158
+ children: [],
1159
+ attributes: {
1160
+ class: "pcb-pad",
1161
+ fill: layerNameToColor(pad.layer, colorMap2),
1162
+ cx: x.toString(),
1163
+ cy: y.toString(),
1164
+ r: radius.toString(),
1165
+ "data-layer": pad.layer
1103
1166
  }
1104
- ];
1167
+ };
1168
+ if (!isCoveredWithSolderMask) {
1169
+ return [padElement];
1170
+ }
1171
+ const maskElement = {
1172
+ name: padElement.name,
1173
+ type: padElement.type,
1174
+ value: "",
1175
+ children: [],
1176
+ attributes: {
1177
+ ...padElement.attributes,
1178
+ class: "pcb-solder-mask",
1179
+ fill: solderMaskColor
1180
+ }
1181
+ };
1182
+ return [padElement, maskElement];
1105
1183
  }
1106
1184
  if (pad.shape === "polygon") {
1107
1185
  const points = (pad.points ?? []).map(
1108
1186
  (point) => applyToPoint11(transform, [point.x, point.y])
1109
1187
  );
1110
- return [
1111
- {
1112
- name: "polygon",
1113
- type: "element",
1114
- attributes: {
1115
- class: "pcb-pad",
1116
- fill: layerNameToColor(pad.layer),
1117
- points: points.map((p) => p.join(",")).join(" "),
1118
- "data-layer": pad.layer
1119
- }
1188
+ const padElement = {
1189
+ name: "polygon",
1190
+ type: "element",
1191
+ value: "",
1192
+ children: [],
1193
+ attributes: {
1194
+ class: "pcb-pad",
1195
+ fill: layerNameToColor(pad.layer, colorMap2),
1196
+ points: points.map((p) => p.join(",")).join(" "),
1197
+ "data-layer": pad.layer
1120
1198
  }
1121
- ];
1199
+ };
1200
+ if (!isCoveredWithSolderMask) {
1201
+ return [padElement];
1202
+ }
1203
+ const maskElement = {
1204
+ name: padElement.name,
1205
+ type: padElement.type,
1206
+ value: "",
1207
+ children: [],
1208
+ attributes: {
1209
+ ...padElement.attributes,
1210
+ class: "pcb-solder-mask",
1211
+ fill: solderMaskColor
1212
+ }
1213
+ };
1214
+ return [padElement, maskElement];
1122
1215
  }
1123
1216
  return [];
1124
1217
  }
@@ -1650,7 +1743,7 @@ function getSoftwareUsedString(circuitJson) {
1650
1743
  var package_default = {
1651
1744
  name: "circuit-to-svg",
1652
1745
  type: "module",
1653
- version: "0.0.192",
1746
+ version: "0.0.194",
1654
1747
  description: "Convert Circuit JSON to SVG",
1655
1748
  main: "dist/index.js",
1656
1749
  files: [
@@ -1674,6 +1767,7 @@ var package_default = {
1674
1767
  "bun-match-svg": "^0.0.12",
1675
1768
  esbuild: "^0.20.2",
1676
1769
  "performance-now": "^2.1.0",
1770
+ "circuit-json": "^0.0.257",
1677
1771
  react: "19.1.0",
1678
1772
  "react-cosmos": "7.0.0",
1679
1773
  "react-cosmos-plugin-vite": "7.0.0",
@@ -2494,10 +2588,16 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
2494
2588
  ];
2495
2589
  }
2496
2590
  if (hole.shape === "circular_hole_with_rect_pad") {
2497
- const scaledHoleDiameter = hole.hole_diameter * Math.abs(transform.a);
2498
- const scaledRectPadWidth = hole.rect_pad_width * Math.abs(transform.a);
2499
- const scaledRectPadHeight = hole.rect_pad_height * Math.abs(transform.a);
2591
+ const circularHole = hole;
2592
+ const scaledHoleDiameter = circularHole.hole_diameter * Math.abs(transform.a);
2593
+ const scaledRectPadWidth = circularHole.rect_pad_width * Math.abs(transform.a);
2594
+ const scaledRectPadHeight = circularHole.rect_pad_height * Math.abs(transform.a);
2595
+ const scaledRectBorderRadius = (circularHole.rect_border_radius ?? 0) * Math.abs(transform.a);
2500
2596
  const holeRadius = scaledHoleDiameter / 2;
2597
+ const [holeCx, holeCy] = applyToPoint25(transform, [
2598
+ circularHole.x + circularHole.hole_offset_x,
2599
+ circularHole.y + circularHole.hole_offset_y
2600
+ ]);
2501
2601
  return [
2502
2602
  {
2503
2603
  name: "g",
@@ -2513,7 +2613,11 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
2513
2613
  x: (x - scaledRectPadWidth / 2).toString(),
2514
2614
  y: (y - scaledRectPadHeight / 2).toString(),
2515
2615
  width: scaledRectPadWidth.toString(),
2516
- height: scaledRectPadHeight.toString()
2616
+ height: scaledRectPadHeight.toString(),
2617
+ ...scaledRectBorderRadius ? {
2618
+ rx: scaledRectBorderRadius.toString(),
2619
+ ry: scaledRectBorderRadius.toString()
2620
+ } : {}
2517
2621
  },
2518
2622
  value: "",
2519
2623
  children: []
@@ -2525,8 +2629,8 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
2525
2629
  attributes: {
2526
2630
  class: "assembly-hole-inner",
2527
2631
  fill: HOLE_COLOR3,
2528
- cx: x.toString(),
2529
- cy: y.toString(),
2632
+ cx: holeCx.toString(),
2633
+ cy: holeCy.toString(),
2530
2634
  r: holeRadius.toString()
2531
2635
  },
2532
2636
  value: "",
@@ -2539,10 +2643,19 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
2539
2643
  ];
2540
2644
  }
2541
2645
  if (hole.shape === "pill_hole_with_rect_pad") {
2542
- const scaledRectPadWidth = hole.rect_pad_width * Math.abs(transform.a);
2543
- const scaledRectPadHeight = hole.rect_pad_height * Math.abs(transform.a);
2544
- const scaledHoleHeight = hole.hole_height * Math.abs(transform.a);
2545
- const scaledHoleWidth = hole.hole_width * Math.abs(transform.a);
2646
+ const pillHole = hole;
2647
+ const scaledRectPadWidth = pillHole.rect_pad_width * Math.abs(transform.a);
2648
+ const scaledRectPadHeight = pillHole.rect_pad_height * Math.abs(transform.a);
2649
+ const scaledRectBorderRadius = (pillHole.rect_border_radius ?? 0) * Math.abs(transform.a);
2650
+ const scaledHoleHeight = pillHole.hole_height * Math.abs(transform.a);
2651
+ const scaledHoleWidth = pillHole.hole_width * Math.abs(transform.a);
2652
+ const pillHoleWithOffsets = pillHole;
2653
+ const holeOffsetX = pillHoleWithOffsets.hole_offset_x ?? 0;
2654
+ const holeOffsetY = pillHoleWithOffsets.hole_offset_y ?? 0;
2655
+ const [holeCenterX, holeCenterY] = applyToPoint25(transform, [
2656
+ pillHole.x + holeOffsetX,
2657
+ pillHole.y + holeOffsetY
2658
+ ]);
2546
2659
  const holeRadius = Math.min(scaledHoleHeight, scaledHoleWidth) / 2;
2547
2660
  return [
2548
2661
  {
@@ -2559,7 +2672,11 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
2559
2672
  x: (x - scaledRectPadWidth / 2).toString(),
2560
2673
  y: (y - scaledRectPadHeight / 2).toString(),
2561
2674
  width: scaledRectPadWidth.toString(),
2562
- height: scaledRectPadHeight.toString()
2675
+ height: scaledRectPadHeight.toString(),
2676
+ ...scaledRectBorderRadius ? {
2677
+ rx: scaledRectBorderRadius.toString(),
2678
+ ry: scaledRectBorderRadius.toString()
2679
+ } : {}
2563
2680
  },
2564
2681
  value: "",
2565
2682
  children: []
@@ -2571,8 +2688,8 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
2571
2688
  attributes: {
2572
2689
  class: "assembly-hole-inner",
2573
2690
  fill: HOLE_COLOR3,
2574
- x: (x - scaledHoleWidth / 2).toString(),
2575
- y: (y - scaledHoleHeight / 2).toString(),
2691
+ x: (holeCenterX - scaledHoleWidth / 2).toString(),
2692
+ y: (holeCenterY - scaledHoleHeight / 2).toString(),
2576
2693
  width: scaledHoleWidth.toString(),
2577
2694
  height: scaledHoleHeight.toString(),
2578
2695
  rx: holeRadius.toString(),
@@ -2588,10 +2705,19 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
2588
2705
  ];
2589
2706
  }
2590
2707
  if (hole.shape === "rotated_pill_hole_with_rect_pad") {
2591
- const scaledRectPadWidth = hole.rect_pad_width * Math.abs(transform.a);
2592
- const scaledRectPadHeight = hole.rect_pad_height * Math.abs(transform.a);
2593
- const scaledHoleHeight = hole.hole_height * Math.abs(transform.a);
2594
- const scaledHoleWidth = hole.hole_width * Math.abs(transform.a);
2708
+ const rotatedHole = hole;
2709
+ const scaledRectPadWidth = rotatedHole.rect_pad_width * Math.abs(transform.a);
2710
+ const scaledRectPadHeight = rotatedHole.rect_pad_height * Math.abs(transform.a);
2711
+ const scaledRectBorderRadius = (rotatedHole.rect_border_radius ?? 0) * Math.abs(transform.a);
2712
+ const scaledHoleHeight = rotatedHole.hole_height * Math.abs(transform.a);
2713
+ const scaledHoleWidth = rotatedHole.hole_width * Math.abs(transform.a);
2714
+ const rotatedHoleWithOffsets = rotatedHole;
2715
+ const holeOffsetX = rotatedHoleWithOffsets.hole_offset_x ?? 0;
2716
+ const holeOffsetY = rotatedHoleWithOffsets.hole_offset_y ?? 0;
2717
+ const [holeCenterX, holeCenterY] = applyToPoint25(transform, [
2718
+ rotatedHole.x + holeOffsetX,
2719
+ rotatedHole.y + holeOffsetY
2720
+ ]);
2595
2721
  const holeRadius = Math.min(scaledHoleHeight, scaledHoleWidth) / 2;
2596
2722
  return [
2597
2723
  {
@@ -2608,7 +2734,11 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
2608
2734
  y: (-scaledRectPadHeight / 2).toString(),
2609
2735
  width: scaledRectPadWidth.toString(),
2610
2736
  height: scaledRectPadHeight.toString(),
2611
- transform: `translate(${x} ${y}) rotate(${-hole.rect_ccw_rotation})`
2737
+ transform: `translate(${x} ${y}) rotate(${-rotatedHole.rect_ccw_rotation})`,
2738
+ ...scaledRectBorderRadius ? {
2739
+ rx: scaledRectBorderRadius.toString(),
2740
+ ry: scaledRectBorderRadius.toString()
2741
+ } : {}
2612
2742
  },
2613
2743
  value: "",
2614
2744
  children: []
@@ -2625,7 +2755,7 @@ function createSvgObjectsFromAssemblyPlatedHole(hole, ctx) {
2625
2755
  height: scaledHoleHeight.toString(),
2626
2756
  rx: holeRadius.toString(),
2627
2757
  ry: holeRadius.toString(),
2628
- transform: `translate(${x} ${y}) rotate(${-hole.hole_ccw_rotation})`
2758
+ transform: `translate(${holeCenterX} ${holeCenterY}) rotate(${-rotatedHole.hole_ccw_rotation})`
2629
2759
  },
2630
2760
  value: "",
2631
2761
  children: []