circuit-to-svg 0.0.126 → 0.0.127

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,10 +1,10 @@
1
1
  // lib/pcb/convert-circuit-json-to-pcb-svg.ts
2
2
  import { stringify } from "svgson";
3
3
  import {
4
- applyToPoint as applyToPoint16,
5
- compose as compose3,
4
+ applyToPoint as applyToPoint17,
5
+ compose as compose4,
6
6
  scale as scale2,
7
- translate as translate3
7
+ translate as translate4
8
8
  } from "transformation-matrix";
9
9
 
10
10
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-trace-error.ts
@@ -1187,6 +1187,91 @@ function createSvgObjectsForRatsNest(circuitJson, transform) {
1187
1187
  return svgObjects;
1188
1188
  }
1189
1189
 
1190
+ // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-cutout.ts
1191
+ import {
1192
+ applyToPoint as applyToPoint16,
1193
+ compose as compose3,
1194
+ rotate as rotate3,
1195
+ translate as translate3,
1196
+ toString as matrixToString6
1197
+ } from "transformation-matrix";
1198
+ function createSvgObjectsFromPcbCutout(cutout, transform) {
1199
+ if (cutout.shape === "rect") {
1200
+ const rectCutout = cutout;
1201
+ const [cx, cy] = applyToPoint16(transform, [
1202
+ rectCutout.center.x,
1203
+ rectCutout.center.y
1204
+ ]);
1205
+ const scaledWidth = rectCutout.width * Math.abs(transform.a);
1206
+ const scaledHeight = rectCutout.height * Math.abs(transform.d);
1207
+ const svgRotation = -(rectCutout.rotation ?? 0);
1208
+ return [
1209
+ {
1210
+ name: "rect",
1211
+ type: "element",
1212
+ attributes: {
1213
+ class: "pcb-cutout pcb-cutout-rect",
1214
+ x: (-scaledWidth / 2).toString(),
1215
+ y: (-scaledHeight / 2).toString(),
1216
+ width: scaledWidth.toString(),
1217
+ height: scaledHeight.toString(),
1218
+ fill: HOLE_COLOR,
1219
+ transform: matrixToString6(
1220
+ compose3(translate3(cx, cy), rotate3(svgRotation * Math.PI / 180))
1221
+ )
1222
+ },
1223
+ children: [],
1224
+ value: ""
1225
+ }
1226
+ ];
1227
+ }
1228
+ if (cutout.shape === "circle") {
1229
+ const circleCutout = cutout;
1230
+ const [cx, cy] = applyToPoint16(transform, [
1231
+ circleCutout.center.x,
1232
+ circleCutout.center.y
1233
+ ]);
1234
+ const scaledRadius = circleCutout.radius * Math.abs(transform.a);
1235
+ return [
1236
+ {
1237
+ name: "circle",
1238
+ type: "element",
1239
+ attributes: {
1240
+ class: "pcb-cutout pcb-cutout-circle",
1241
+ cx: cx.toString(),
1242
+ cy: cy.toString(),
1243
+ r: scaledRadius.toString(),
1244
+ fill: HOLE_COLOR
1245
+ },
1246
+ children: [],
1247
+ value: ""
1248
+ }
1249
+ ];
1250
+ }
1251
+ if (cutout.shape === "polygon") {
1252
+ const polygonCutout = cutout;
1253
+ if (!polygonCutout.points || polygonCutout.points.length === 0) return [];
1254
+ const transformedPoints = polygonCutout.points.map(
1255
+ (p) => applyToPoint16(transform, [p.x, p.y])
1256
+ );
1257
+ const pointsString = transformedPoints.map((p) => `${p[0]},${p[1]}`).join(" ");
1258
+ return [
1259
+ {
1260
+ name: "polygon",
1261
+ type: "element",
1262
+ attributes: {
1263
+ class: "pcb-cutout pcb-cutout-polygon",
1264
+ points: pointsString,
1265
+ fill: HOLE_COLOR
1266
+ },
1267
+ children: [],
1268
+ value: ""
1269
+ }
1270
+ ];
1271
+ }
1272
+ return [];
1273
+ }
1274
+
1190
1275
  // lib/pcb/convert-circuit-json-to-pcb-svg.ts
1191
1276
  var OBJECT_ORDER = [
1192
1277
  "pcb_trace_error",
@@ -1196,6 +1281,7 @@ var OBJECT_ORDER = [
1196
1281
  "pcb_silkscreen_text",
1197
1282
  "pcb_silkscreen_path",
1198
1283
  "pcb_via",
1284
+ "pcb_cutout",
1199
1285
  "pcb_trace",
1200
1286
  "pcb_smtpad",
1201
1287
  "pcb_component",
@@ -1236,8 +1322,8 @@ function convertCircuitJsonToPcbSvg(soup, options) {
1236
1322
  const scaleFactor = Math.min(scaleX, scaleY);
1237
1323
  const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2;
1238
1324
  const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2;
1239
- const transform = compose3(
1240
- translate3(
1325
+ const transform = compose4(
1326
+ translate4(
1241
1327
  offsetX - minX * scaleFactor + padding * scaleFactor,
1242
1328
  svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
1243
1329
  ),
@@ -1338,6 +1424,15 @@ function convertCircuitJsonToPcbSvg(soup, options) {
1338
1424
  } else if (item.type === "pcb_silkscreen_line") {
1339
1425
  updateBounds({ x: item.x1, y: item.y1 }, 0, 0);
1340
1426
  updateBounds({ x: item.x2, y: item.y2 }, 0, 0);
1427
+ } else if (item.type === "pcb_cutout") {
1428
+ const cutout = item;
1429
+ if (cutout.shape === "rect") {
1430
+ updateBounds(cutout.center, cutout.width, cutout.height);
1431
+ } else if (cutout.shape === "circle") {
1432
+ updateBounds(cutout.center, cutout.radius * 2, cutout.radius * 2);
1433
+ } else if (cutout.shape === "polygon") {
1434
+ updateTraceBounds(cutout.points);
1435
+ }
1341
1436
  }
1342
1437
  }
1343
1438
  }
@@ -1378,13 +1473,15 @@ function createSvgObjects(elm, transform, soup, shouldDrawErrors) {
1378
1473
  return createSvgObjectsFromPcbBoard(elm, transform);
1379
1474
  case "pcb_via":
1380
1475
  return createSvgObjectsFromPcbVia(elm, transform);
1476
+ case "pcb_cutout":
1477
+ return createSvgObjectsFromPcbCutout(elm, transform);
1381
1478
  default:
1382
1479
  return [];
1383
1480
  }
1384
1481
  }
1385
1482
  function createSvgObjectsFromPcbComponent(component, transform) {
1386
1483
  const { center, width, height, rotation = 0 } = component;
1387
- const [x, y] = applyToPoint16(transform, [center.x, center.y]);
1484
+ const [x, y] = applyToPoint17(transform, [center.x, center.y]);
1388
1485
  const scaledWidth = width * Math.abs(transform.a);
1389
1486
  const scaledHeight = height * Math.abs(transform.d);
1390
1487
  const transformStr = `translate(${x}, ${y}) rotate(${-rotation}) scale(1, -1)`;
@@ -1419,8 +1516,8 @@ function createSvgObjectsFromPcbComponent(component, transform) {
1419
1516
  };
1420
1517
  }
1421
1518
  function createSvgObjectFromPcbBoundary(transform, minX, minY, maxX, maxY) {
1422
- const [x1, y1] = applyToPoint16(transform, [minX, minY]);
1423
- const [x2, y2] = applyToPoint16(transform, [maxX, maxY]);
1519
+ const [x1, y1] = applyToPoint17(transform, [minX, minY]);
1520
+ const [x2, y2] = applyToPoint17(transform, [maxX, maxY]);
1424
1521
  const width = Math.abs(x2 - x1);
1425
1522
  const height = Math.abs(y2 - y1);
1426
1523
  const x = Math.min(x1, x2);
@@ -1448,14 +1545,14 @@ var circuitJsonToPcbSvg = convertCircuitJsonToPcbSvg;
1448
1545
  import { stringify as stringify2 } from "svgson";
1449
1546
  import { su as su3 } from "@tscircuit/circuit-json-util";
1450
1547
  import {
1451
- applyToPoint as applyToPoint20,
1452
- compose as compose4,
1548
+ applyToPoint as applyToPoint21,
1549
+ compose as compose5,
1453
1550
  scale as scale3,
1454
- translate as translate4
1551
+ translate as translate5
1455
1552
  } from "transformation-matrix";
1456
1553
 
1457
1554
  // lib/assembly/svg-object-fns/create-svg-objects-from-assembly-board.ts
1458
- import { applyToPoint as applyToPoint17 } from "transformation-matrix";
1555
+ import { applyToPoint as applyToPoint18 } from "transformation-matrix";
1459
1556
  var DEFAULT_BOARD_STYLE = {
1460
1557
  fill: "none",
1461
1558
  stroke: "rgb(0,0,0)",
@@ -1467,25 +1564,25 @@ function createSvgObjectsFromAssemblyBoard(pcbBoard, transform, style = {}) {
1467
1564
  let path;
1468
1565
  if (outline && Array.isArray(outline) && outline.length >= 3) {
1469
1566
  path = outline.map((point, index) => {
1470
- const [x, y] = applyToPoint17(transform, [point.x, point.y]);
1567
+ const [x, y] = applyToPoint18(transform, [point.x, point.y]);
1471
1568
  return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
1472
1569
  }).join(" ");
1473
1570
  } else {
1474
1571
  const halfWidth = width / 2;
1475
1572
  const halfHeight = height / 2;
1476
- const topLeft = applyToPoint17(transform, [
1573
+ const topLeft = applyToPoint18(transform, [
1477
1574
  center.x - halfWidth,
1478
1575
  center.y - halfHeight
1479
1576
  ]);
1480
- const topRight = applyToPoint17(transform, [
1577
+ const topRight = applyToPoint18(transform, [
1481
1578
  center.x + halfWidth,
1482
1579
  center.y - halfHeight
1483
1580
  ]);
1484
- const bottomRight = applyToPoint17(transform, [
1581
+ const bottomRight = applyToPoint18(transform, [
1485
1582
  center.x + halfWidth,
1486
1583
  center.y + halfHeight
1487
1584
  ]);
1488
- const bottomLeft = applyToPoint17(transform, [
1585
+ const bottomLeft = applyToPoint18(transform, [
1489
1586
  center.x - halfWidth,
1490
1587
  center.y + halfHeight
1491
1588
  ]);
@@ -1511,7 +1608,7 @@ function createSvgObjectsFromAssemblyBoard(pcbBoard, transform, style = {}) {
1511
1608
  }
1512
1609
 
1513
1610
  // lib/assembly/svg-object-fns/create-svg-objects-from-assembly-component.ts
1514
- import { applyToPoint as applyToPoint19 } from "transformation-matrix";
1611
+ import { applyToPoint as applyToPoint20 } from "transformation-matrix";
1515
1612
 
1516
1613
  // lib/utils/get-sch-font-size.ts
1517
1614
  import "transformation-matrix";
@@ -1529,8 +1626,8 @@ function createSvgObjectsFromAssemblyComponent(params, ctx) {
1529
1626
  const { center, width, height, rotation = 0, layer = "top" } = elm;
1530
1627
  if (!center || typeof width !== "number" || typeof height !== "number")
1531
1628
  return null;
1532
- const [x, y] = applyToPoint19(transform, [center.x, center.y]);
1533
- const [pinX, pinY] = applyToPoint19(transform, [portPosition.x, portPosition.y]);
1629
+ const [x, y] = applyToPoint20(transform, [center.x, center.y]);
1630
+ const [pinX, pinY] = applyToPoint20(transform, [portPosition.x, portPosition.y]);
1534
1631
  const scaledWidth = width * Math.abs(transform.a);
1535
1632
  const scaledHeight = height * Math.abs(transform.d);
1536
1633
  const isTopLayer = layer === "top";
@@ -1719,8 +1816,8 @@ function convertCircuitJsonToAssemblySvg(soup, options) {
1719
1816
  const scaleFactor = Math.min(scaleX, scaleY);
1720
1817
  const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2;
1721
1818
  const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2;
1722
- const transform = compose4(
1723
- translate4(
1819
+ const transform = compose5(
1820
+ translate5(
1724
1821
  offsetX - minX * scaleFactor + padding * scaleFactor,
1725
1822
  svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
1726
1823
  ),
@@ -1827,8 +1924,8 @@ function createSvgObjects2(elm, transform, soup) {
1827
1924
  }
1828
1925
  }
1829
1926
  function createSvgObjectFromAssemblyBoundary(transform, minX, minY, maxX, maxY) {
1830
- const [x1, y1] = applyToPoint20(transform, [minX, minY]);
1831
- const [x2, y2] = applyToPoint20(transform, [maxX, maxY]);
1927
+ const [x1, y1] = applyToPoint21(transform, [minX, minY]);
1928
+ const [x2, y2] = applyToPoint21(transform, [maxX, maxY]);
1832
1929
  const width = Math.abs(x2 - x1);
1833
1930
  const height = Math.abs(y2 - y1);
1834
1931
  const x = Math.min(x1, x2);
@@ -2094,14 +2191,14 @@ import {
2094
2191
  } from "transformation-matrix";
2095
2192
 
2096
2193
  // lib/sch/draw-schematic-grid.ts
2097
- import { applyToPoint as applyToPoint21 } from "transformation-matrix";
2194
+ import { applyToPoint as applyToPoint22 } from "transformation-matrix";
2098
2195
  function drawSchematicGrid(params) {
2099
2196
  const { minX, minY, maxX, maxY } = params.bounds;
2100
2197
  const cellSize = params.cellSize ?? 1;
2101
2198
  const labelCells = params.labelCells ?? false;
2102
2199
  const gridLines = [];
2103
2200
  const transformPoint = (x, y) => {
2104
- const [transformedX, transformedY] = applyToPoint21(params.transform, [x, y]);
2201
+ const [transformedX, transformedY] = applyToPoint22(params.transform, [x, y]);
2105
2202
  return { x: transformedX, y: transformedY };
2106
2203
  };
2107
2204
  for (let x = Math.floor(minX); x <= Math.ceil(maxX); x += cellSize) {
@@ -2182,15 +2279,15 @@ function drawSchematicGrid(params) {
2182
2279
  }
2183
2280
 
2184
2281
  // lib/sch/draw-schematic-labeled-points.ts
2185
- import { applyToPoint as applyToPoint22 } from "transformation-matrix";
2282
+ import { applyToPoint as applyToPoint23 } from "transformation-matrix";
2186
2283
  function drawSchematicLabeledPoints(params) {
2187
2284
  const { points, transform } = params;
2188
2285
  const labeledPointsGroup = [];
2189
2286
  for (const point of points) {
2190
- const [x1, y1] = applyToPoint22(transform, [point.x - 0.1, point.y - 0.1]);
2191
- const [x2, y2] = applyToPoint22(transform, [point.x + 0.1, point.y + 0.1]);
2192
- const [x3, y3] = applyToPoint22(transform, [point.x - 0.1, point.y + 0.1]);
2193
- const [x4, y4] = applyToPoint22(transform, [point.x + 0.1, point.y - 0.1]);
2287
+ const [x1, y1] = applyToPoint23(transform, [point.x - 0.1, point.y - 0.1]);
2288
+ const [x2, y2] = applyToPoint23(transform, [point.x + 0.1, point.y + 0.1]);
2289
+ const [x3, y3] = applyToPoint23(transform, [point.x - 0.1, point.y + 0.1]);
2290
+ const [x4, y4] = applyToPoint23(transform, [point.x + 0.1, point.y - 0.1]);
2194
2291
  labeledPointsGroup.push({
2195
2292
  name: "path",
2196
2293
  type: "element",
@@ -2201,7 +2298,7 @@ function drawSchematicLabeledPoints(params) {
2201
2298
  "stroke-opacity": "0.7"
2202
2299
  }
2203
2300
  });
2204
- const [labelX, labelY] = applyToPoint22(transform, [
2301
+ const [labelX, labelY] = applyToPoint23(transform, [
2205
2302
  point.x + 0.15,
2206
2303
  point.y - 0.15
2207
2304
  ]);
@@ -2304,8 +2401,8 @@ import { su as su4 } from "@tscircuit/circuit-json-util";
2304
2401
  import { symbols } from "schematic-symbols";
2305
2402
  import "svgson";
2306
2403
  import {
2307
- applyToPoint as applyToPoint24,
2308
- compose as compose6
2404
+ applyToPoint as applyToPoint25,
2405
+ compose as compose7
2309
2406
  } from "transformation-matrix";
2310
2407
 
2311
2408
  // lib/utils/get-sch-stroke-size.ts
@@ -2375,26 +2472,26 @@ var matchSchPortsToSymbolPorts = ({
2375
2472
  };
2376
2473
 
2377
2474
  // lib/utils/point-pairs-to-matrix.ts
2378
- import { compose as compose5, scale as scale4, translate as translate5 } from "transformation-matrix";
2475
+ import { compose as compose6, scale as scale4, translate as translate6 } from "transformation-matrix";
2379
2476
  function pointPairsToMatrix(a1, a2, b1, b2) {
2380
2477
  const tx = a2.x - a1.x;
2381
2478
  const ty = a2.y - a1.y;
2382
2479
  const originalDistance = Math.sqrt((b1.x - a1.x) ** 2 + (b1.y - a1.y) ** 2);
2383
2480
  const transformedDistance = Math.sqrt((b2.x - a2.x) ** 2 + (b2.y - a2.y) ** 2);
2384
2481
  const a = transformedDistance / originalDistance;
2385
- const translateMatrix = translate5(tx, ty);
2482
+ const translateMatrix = translate6(tx, ty);
2386
2483
  const scaleMatrix = scale4(a, a);
2387
- return compose5(translateMatrix, scaleMatrix);
2484
+ return compose6(translateMatrix, scaleMatrix);
2388
2485
  }
2389
2486
 
2390
2487
  // lib/sch/svg-object-fns/create-svg-error-text.ts
2391
- import { applyToPoint as applyToPoint23 } from "transformation-matrix";
2488
+ import { applyToPoint as applyToPoint24 } from "transformation-matrix";
2392
2489
  var createSvgSchErrorText = ({
2393
2490
  text,
2394
2491
  realCenter,
2395
2492
  realToScreenTransform
2396
2493
  }) => {
2397
- const screenCenter = applyToPoint23(realToScreenTransform, realCenter);
2494
+ const screenCenter = applyToPoint24(realToScreenTransform, realCenter);
2398
2495
  return {
2399
2496
  type: "element",
2400
2497
  name: "text",
@@ -2485,12 +2582,12 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
2485
2582
  minY: Math.min(...paths.flatMap((p) => p.points.map((pt) => pt.y))),
2486
2583
  maxY: Math.max(...paths.flatMap((p) => p.points.map((pt) => pt.y)))
2487
2584
  };
2488
- const [screenMinX, screenMinY] = applyToPoint24(
2489
- compose6(realToScreenTransform, transformFromSymbolToReal),
2585
+ const [screenMinX, screenMinY] = applyToPoint25(
2586
+ compose7(realToScreenTransform, transformFromSymbolToReal),
2490
2587
  [bounds.minX, bounds.minY]
2491
2588
  );
2492
- const [screenMaxX, screenMaxY] = applyToPoint24(
2493
- compose6(realToScreenTransform, transformFromSymbolToReal),
2589
+ const [screenMaxX, screenMaxY] = applyToPoint25(
2590
+ compose7(realToScreenTransform, transformFromSymbolToReal),
2494
2591
  [bounds.maxX, bounds.maxY]
2495
2592
  );
2496
2593
  const rectHeight = Math.abs(screenMaxY - screenMinY);
@@ -2518,8 +2615,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
2518
2615
  name: "path",
2519
2616
  attributes: {
2520
2617
  d: points.map((p, i) => {
2521
- const [x, y] = applyToPoint24(
2522
- compose6(realToScreenTransform, transformFromSymbolToReal),
2618
+ const [x, y] = applyToPoint25(
2619
+ compose7(realToScreenTransform, transformFromSymbolToReal),
2523
2620
  [p.x, p.y]
2524
2621
  );
2525
2622
  return `${i === 0 ? "M" : "L"} ${x} ${y}`;
@@ -2533,8 +2630,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
2533
2630
  });
2534
2631
  }
2535
2632
  for (const text of texts) {
2536
- const screenTextPos = applyToPoint24(
2537
- compose6(realToScreenTransform, transformFromSymbolToReal),
2633
+ const screenTextPos = applyToPoint25(
2634
+ compose7(realToScreenTransform, transformFromSymbolToReal),
2538
2635
  text
2539
2636
  );
2540
2637
  let textValue = "";
@@ -2579,11 +2676,11 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
2579
2676
  });
2580
2677
  }
2581
2678
  for (const box of boxes) {
2582
- const screenBoxPos = applyToPoint24(
2583
- compose6(realToScreenTransform, transformFromSymbolToReal),
2679
+ const screenBoxPos = applyToPoint25(
2680
+ compose7(realToScreenTransform, transformFromSymbolToReal),
2584
2681
  box
2585
2682
  );
2586
- const symbolToScreenScale = compose6(
2683
+ const symbolToScreenScale = compose7(
2587
2684
  realToScreenTransform,
2588
2685
  transformFromSymbolToReal
2589
2686
  ).a;
@@ -2602,8 +2699,8 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
2602
2699
  });
2603
2700
  }
2604
2701
  for (const port of symbol.ports) {
2605
- const screenPortPos = applyToPoint24(
2606
- compose6(realToScreenTransform, transformFromSymbolToReal),
2702
+ const screenPortPos = applyToPoint25(
2703
+ compose7(realToScreenTransform, transformFromSymbolToReal),
2607
2704
  port
2608
2705
  );
2609
2706
  svgObjects.push({
@@ -2628,14 +2725,14 @@ var createSvgObjectsFromSchematicComponentWithSymbol = ({
2628
2725
  import { su as su7 } from "@tscircuit/circuit-json-util";
2629
2726
  import "schematic-symbols";
2630
2727
  import "svgson";
2631
- import { applyToPoint as applyToPoint30 } from "transformation-matrix";
2728
+ import { applyToPoint as applyToPoint31 } from "transformation-matrix";
2632
2729
 
2633
2730
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-port-on-box.ts
2634
2731
  import "transformation-matrix";
2635
2732
  import "@tscircuit/circuit-json-util";
2636
2733
 
2637
2734
  // lib/sch/svg-object-fns/create-svg-objects-for-sch-port-box-line.ts
2638
- import { applyToPoint as applyToPoint25 } from "transformation-matrix";
2735
+ import { applyToPoint as applyToPoint26 } from "transformation-matrix";
2639
2736
  import { su as su5 } from "@tscircuit/circuit-json-util";
2640
2737
  var PIN_CIRCLE_RADIUS_MM = 0.02;
2641
2738
  var createSvgObjectsForSchPortBoxLine = ({
@@ -2665,8 +2762,8 @@ var createSvgObjectsForSchPortBoxLine = ({
2665
2762
  realEdgePos.y += realPinLineLength;
2666
2763
  break;
2667
2764
  }
2668
- const screenSchPortPos = applyToPoint25(transform, schPort.center);
2669
- const screenRealEdgePos = applyToPoint25(transform, realEdgePos);
2765
+ const screenSchPortPos = applyToPoint26(transform, schPort.center);
2766
+ const screenRealEdgePos = applyToPoint26(transform, realEdgePos);
2670
2767
  const realLineEnd = { ...schPort.center };
2671
2768
  switch (schPort.side_of_component) {
2672
2769
  case "left":
@@ -2682,7 +2779,7 @@ var createSvgObjectsForSchPortBoxLine = ({
2682
2779
  realLineEnd.y += PIN_CIRCLE_RADIUS_MM;
2683
2780
  break;
2684
2781
  }
2685
- const screenLineEnd = applyToPoint25(transform, realLineEnd);
2782
+ const screenLineEnd = applyToPoint26(transform, realLineEnd);
2686
2783
  svgObjects.push({
2687
2784
  name: "line",
2688
2785
  type: "element",
@@ -2729,7 +2826,7 @@ var getUnitVectorFromOutsideToEdge = (side) => {
2729
2826
  };
2730
2827
 
2731
2828
  // lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-number-text.ts
2732
- import { applyToPoint as applyToPoint26 } from "transformation-matrix";
2829
+ import { applyToPoint as applyToPoint27 } from "transformation-matrix";
2733
2830
  var createSvgObjectsForSchPortPinNumberText = (params) => {
2734
2831
  const svgObjects = [];
2735
2832
  const { schPort, schComponent, transform, circuitJson } = params;
@@ -2747,7 +2844,7 @@ var createSvgObjectsForSchPortPinNumberText = (params) => {
2747
2844
  } else {
2748
2845
  realPinNumberPos.y += 0.02;
2749
2846
  }
2750
- const screenPinNumberTextPos = applyToPoint26(transform, realPinNumberPos);
2847
+ const screenPinNumberTextPos = applyToPoint27(transform, realPinNumberPos);
2751
2848
  svgObjects.push({
2752
2849
  name: "text",
2753
2850
  type: "element",
@@ -2777,7 +2874,7 @@ var createSvgObjectsForSchPortPinNumberText = (params) => {
2777
2874
  };
2778
2875
 
2779
2876
  // lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-label.ts
2780
- import { applyToPoint as applyToPoint27 } from "transformation-matrix";
2877
+ import { applyToPoint as applyToPoint28 } from "transformation-matrix";
2781
2878
  var LABEL_DIST_FROM_EDGE_MM = 0.1;
2782
2879
  var createSvgObjectsForSchPortPinLabel = (params) => {
2783
2880
  const svgObjects = [];
@@ -2791,7 +2888,7 @@ var createSvgObjectsForSchPortPinLabel = (params) => {
2791
2888
  const realPinEdgeDistance = schPort.distance_from_component_edge ?? 0.4;
2792
2889
  realPinNumberPos.x += vecToEdge.x * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
2793
2890
  realPinNumberPos.y += vecToEdge.y * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
2794
- const screenPinNumberTextPos = applyToPoint27(transform, realPinNumberPos);
2891
+ const screenPinNumberTextPos = applyToPoint28(transform, realPinNumberPos);
2795
2892
  const label = schPort.display_pin_label ?? schComponent.port_labels?.[`${schPort.pin_number}`];
2796
2893
  if (!label) return [];
2797
2894
  svgObjects.push({
@@ -2833,26 +2930,42 @@ var createSvgObjectsFromSchPortOnBox = (params) => {
2833
2930
  };
2834
2931
 
2835
2932
  // lib/sch/svg-object-fns/create-svg-objects-for-sch-text.ts
2836
- import { applyToPoint as applyToPoint29 } from "transformation-matrix";
2933
+ import { applyToPoint as applyToPoint30 } from "transformation-matrix";
2837
2934
  var createSvgSchText = ({
2838
2935
  elm,
2839
2936
  transform,
2840
2937
  colorMap: colorMap2
2841
2938
  }) => {
2842
- const center = applyToPoint29(transform, elm.position);
2939
+ const center = applyToPoint30(transform, elm.position);
2843
2940
  const textAnchorMap = {
2844
2941
  center: "middle",
2845
2942
  left: "start",
2846
2943
  right: "end",
2847
2944
  top: "middle",
2848
- bottom: "middle"
2945
+ bottom: "middle",
2946
+ top_left: "start",
2947
+ top_center: "middle",
2948
+ top_right: "end",
2949
+ center_left: "start",
2950
+ center_right: "end",
2951
+ bottom_left: "start",
2952
+ bottom_center: "middle",
2953
+ bottom_right: "end"
2849
2954
  };
2850
2955
  const dominantBaselineMap = {
2851
2956
  center: "middle",
2852
2957
  left: "middle",
2853
2958
  right: "middle",
2854
2959
  top: "hanging",
2855
- bottom: "ideographic"
2960
+ bottom: "ideographic",
2961
+ top_left: "hanging",
2962
+ top_center: "hanging",
2963
+ top_right: "hanging",
2964
+ center_left: "middle",
2965
+ center_right: "middle",
2966
+ bottom_left: "ideographic",
2967
+ bottom_center: "ideographic",
2968
+ bottom_right: "ideographic"
2856
2969
  };
2857
2970
  return {
2858
2971
  type: "element",
@@ -2888,11 +3001,11 @@ var createSvgObjectsFromSchematicComponentWithBox = ({
2888
3001
  colorMap: colorMap2
2889
3002
  }) => {
2890
3003
  const svgObjects = [];
2891
- const componentScreenTopLeft = applyToPoint30(transform, {
3004
+ const componentScreenTopLeft = applyToPoint31(transform, {
2892
3005
  x: schComponent.center.x - schComponent.size.width / 2,
2893
3006
  y: schComponent.center.y + schComponent.size.height / 2
2894
3007
  });
2895
- const componentScreenBottomRight = applyToPoint30(transform, {
3008
+ const componentScreenBottomRight = applyToPoint31(transform, {
2896
3009
  x: schComponent.center.x + schComponent.size.width / 2,
2897
3010
  y: schComponent.center.y - schComponent.size.height / 2
2898
3011
  });
@@ -2975,13 +3088,13 @@ function createSvgObjectsFromSchematicComponent(params) {
2975
3088
  }
2976
3089
 
2977
3090
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-voltage-probe.ts
2978
- import { applyToPoint as applyToPoint31 } from "transformation-matrix";
3091
+ import { applyToPoint as applyToPoint32 } from "transformation-matrix";
2979
3092
  function createSvgObjectsFromSchVoltageProbe({
2980
3093
  probe,
2981
3094
  transform,
2982
3095
  colorMap: colorMap2
2983
3096
  }) {
2984
- const [screenX, screenY] = applyToPoint31(transform, [
3097
+ const [screenX, screenY] = applyToPoint32(transform, [
2985
3098
  probe.position.x,
2986
3099
  probe.position.y
2987
3100
  ]);
@@ -3041,17 +3154,17 @@ function createSvgObjectsFromSchVoltageProbe({
3041
3154
  }
3042
3155
 
3043
3156
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-debug-object.ts
3044
- import { applyToPoint as applyToPoint32 } from "transformation-matrix";
3157
+ import { applyToPoint as applyToPoint33 } from "transformation-matrix";
3045
3158
  function createSvgObjectsFromSchDebugObject({
3046
3159
  debugObject,
3047
3160
  transform
3048
3161
  }) {
3049
3162
  if (debugObject.shape === "rect") {
3050
- let [screenLeft, screenTop] = applyToPoint32(transform, [
3163
+ let [screenLeft, screenTop] = applyToPoint33(transform, [
3051
3164
  debugObject.center.x - debugObject.size.width / 2,
3052
3165
  debugObject.center.y - debugObject.size.height / 2
3053
3166
  ]);
3054
- let [screenRight, screenBottom] = applyToPoint32(transform, [
3167
+ let [screenRight, screenBottom] = applyToPoint33(transform, [
3055
3168
  debugObject.center.x + debugObject.size.width / 2,
3056
3169
  debugObject.center.y + debugObject.size.height / 2
3057
3170
  ]);
@@ -3061,7 +3174,7 @@ function createSvgObjectsFromSchDebugObject({
3061
3174
  ];
3062
3175
  const width = Math.abs(screenRight - screenLeft);
3063
3176
  const height = Math.abs(screenBottom - screenTop);
3064
- const [screenCenterX, screenCenterY] = applyToPoint32(transform, [
3177
+ const [screenCenterX, screenCenterY] = applyToPoint33(transform, [
3065
3178
  debugObject.center.x,
3066
3179
  debugObject.center.y
3067
3180
  ]);
@@ -3107,11 +3220,11 @@ function createSvgObjectsFromSchDebugObject({
3107
3220
  ];
3108
3221
  }
3109
3222
  if (debugObject.shape === "line") {
3110
- const [screenStartX, screenStartY] = applyToPoint32(transform, [
3223
+ const [screenStartX, screenStartY] = applyToPoint33(transform, [
3111
3224
  debugObject.start.x,
3112
3225
  debugObject.start.y
3113
3226
  ]);
3114
- const [screenEndX, screenEndY] = applyToPoint32(transform, [
3227
+ const [screenEndX, screenEndY] = applyToPoint33(transform, [
3115
3228
  debugObject.end.x,
3116
3229
  debugObject.end.y
3117
3230
  ]);
@@ -3161,7 +3274,7 @@ function createSvgObjectsFromSchDebugObject({
3161
3274
  }
3162
3275
 
3163
3276
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-trace.ts
3164
- import { applyToPoint as applyToPoint33 } from "transformation-matrix";
3277
+ import { applyToPoint as applyToPoint34 } from "transformation-matrix";
3165
3278
  function createSchematicTrace({
3166
3279
  trace,
3167
3280
  transform,
@@ -3174,11 +3287,11 @@ function createSchematicTrace({
3174
3287
  for (let edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
3175
3288
  const edge = edges[edgeIndex];
3176
3289
  if (edge.is_crossing) continue;
3177
- const [screenFromX, screenFromY] = applyToPoint33(transform, [
3290
+ const [screenFromX, screenFromY] = applyToPoint34(transform, [
3178
3291
  edge.from.x,
3179
3292
  edge.from.y
3180
3293
  ]);
3181
- const [screenToX, screenToY] = applyToPoint33(transform, [
3294
+ const [screenToX, screenToY] = applyToPoint34(transform, [
3182
3295
  edge.to.x,
3183
3296
  edge.to.y
3184
3297
  ]);
@@ -3190,11 +3303,11 @@ function createSchematicTrace({
3190
3303
  }
3191
3304
  for (const edge of edges) {
3192
3305
  if (!edge.is_crossing) continue;
3193
- const [screenFromX, screenFromY] = applyToPoint33(transform, [
3306
+ const [screenFromX, screenFromY] = applyToPoint34(transform, [
3194
3307
  edge.from.x,
3195
3308
  edge.from.y
3196
3309
  ]);
3197
- const [screenToX, screenToY] = applyToPoint33(transform, [
3310
+ const [screenToX, screenToY] = applyToPoint34(transform, [
3198
3311
  edge.to.x,
3199
3312
  edge.to.y
3200
3313
  ]);
@@ -3270,7 +3383,7 @@ function createSchematicTrace({
3270
3383
  }
3271
3384
  if (trace.junctions) {
3272
3385
  for (const junction of trace.junctions) {
3273
- const [screenX, screenY] = applyToPoint33(transform, [
3386
+ const [screenX, screenY] = applyToPoint34(transform, [
3274
3387
  junction.x,
3275
3388
  junction.y
3276
3389
  ]);
@@ -3305,11 +3418,11 @@ function createSchematicTrace({
3305
3418
 
3306
3419
  // lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label.ts
3307
3420
  import {
3308
- applyToPoint as applyToPoint35,
3309
- compose as compose8,
3310
- rotate as rotate4,
3421
+ applyToPoint as applyToPoint36,
3422
+ compose as compose9,
3423
+ rotate as rotate5,
3311
3424
  scale as scale6,
3312
- translate as translate8
3425
+ translate as translate9
3313
3426
  } from "transformation-matrix";
3314
3427
 
3315
3428
  // lib/sch/arial-text-metrics.ts
@@ -4093,11 +4206,11 @@ var estimateTextWidth = (text) => {
4093
4206
 
4094
4207
  // lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label-with-symbol.ts
4095
4208
  import {
4096
- applyToPoint as applyToPoint34,
4097
- compose as compose7,
4098
- rotate as rotate3,
4209
+ applyToPoint as applyToPoint35,
4210
+ compose as compose8,
4211
+ rotate as rotate4,
4099
4212
  scale as scale5,
4100
- translate as translate7
4213
+ translate as translate8
4101
4214
  } from "transformation-matrix";
4102
4215
  import { symbols as symbols3 } from "schematic-symbols";
4103
4216
 
@@ -4190,7 +4303,7 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
4190
4303
  bottom: 90,
4191
4304
  right: 180
4192
4305
  }[schNetLabel.anchor_side];
4193
- const rotationMatrix = rotate3(pathRotation / 180 * Math.PI);
4306
+ const rotationMatrix = rotate4(pathRotation / 180 * Math.PI);
4194
4307
  const symbolBounds = {
4195
4308
  minX: Math.min(
4196
4309
  ...symbol.primitives.flatMap(
@@ -4217,9 +4330,9 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
4217
4330
  x: symbolBounds.minX,
4218
4331
  y: (symbolBounds.minY + symbolBounds.maxY) / 2
4219
4332
  };
4220
- const rotatedSymbolEnd = applyToPoint34(rotationMatrix, symbolEndPoint);
4221
- const symbolToRealTransform = compose7(
4222
- translate7(
4333
+ const rotatedSymbolEnd = applyToPoint35(rotationMatrix, symbolEndPoint);
4334
+ const symbolToRealTransform = compose8(
4335
+ translate8(
4223
4336
  realAnchorPosition.x - rotatedSymbolEnd.x,
4224
4337
  realAnchorPosition.y - rotatedSymbolEnd.y
4225
4338
  ),
@@ -4227,12 +4340,12 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
4227
4340
  scale5(1)
4228
4341
  // Use full symbol size
4229
4342
  );
4230
- const [screenMinX, screenMinY] = applyToPoint34(
4231
- compose7(realToScreenTransform, symbolToRealTransform),
4343
+ const [screenMinX, screenMinY] = applyToPoint35(
4344
+ compose8(realToScreenTransform, symbolToRealTransform),
4232
4345
  [bounds.minX, bounds.minY]
4233
4346
  );
4234
- const [screenMaxX, screenMaxY] = applyToPoint34(
4235
- compose7(realToScreenTransform, symbolToRealTransform),
4347
+ const [screenMaxX, screenMaxY] = applyToPoint35(
4348
+ compose8(realToScreenTransform, symbolToRealTransform),
4236
4349
  [bounds.maxX, bounds.maxY]
4237
4350
  );
4238
4351
  const rectHeight = Math.abs(screenMaxY - screenMinY);
@@ -4255,8 +4368,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
4255
4368
  });
4256
4369
  for (const path of symbolPaths) {
4257
4370
  const symbolPath = path.points.map((p, i) => {
4258
- const [x, y] = applyToPoint34(
4259
- compose7(realToScreenTransform, symbolToRealTransform),
4371
+ const [x, y] = applyToPoint35(
4372
+ compose8(realToScreenTransform, symbolToRealTransform),
4260
4373
  [p.x, p.y]
4261
4374
  );
4262
4375
  return `${i === 0 ? "M" : "L"} ${x} ${y}`;
@@ -4275,8 +4388,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
4275
4388
  });
4276
4389
  }
4277
4390
  for (const text of symbolTexts) {
4278
- const screenTextPos = applyToPoint34(
4279
- compose7(realToScreenTransform, symbolToRealTransform),
4391
+ const screenTextPos = applyToPoint35(
4392
+ compose8(realToScreenTransform, symbolToRealTransform),
4280
4393
  text
4281
4394
  );
4282
4395
  let textValue = text.text;
@@ -4317,11 +4430,11 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
4317
4430
  });
4318
4431
  }
4319
4432
  for (const box of symbolBoxes) {
4320
- const screenBoxPos = applyToPoint34(
4321
- compose7(realToScreenTransform, symbolToRealTransform),
4433
+ const screenBoxPos = applyToPoint35(
4434
+ compose8(realToScreenTransform, symbolToRealTransform),
4322
4435
  box
4323
4436
  );
4324
- const symbolToScreenScale = compose7(
4437
+ const symbolToScreenScale = compose8(
4325
4438
  realToScreenTransform,
4326
4439
  symbolToRealTransform
4327
4440
  ).a;
@@ -4340,11 +4453,11 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
4340
4453
  });
4341
4454
  }
4342
4455
  for (const circle of symbolCircles) {
4343
- const screenCirclePos = applyToPoint34(
4344
- compose7(realToScreenTransform, symbolToRealTransform),
4456
+ const screenCirclePos = applyToPoint35(
4457
+ compose8(realToScreenTransform, symbolToRealTransform),
4345
4458
  circle
4346
4459
  );
4347
- const symbolToScreenScale = compose7(
4460
+ const symbolToScreenScale = compose8(
4348
4461
  realToScreenTransform,
4349
4462
  symbolToRealTransform
4350
4463
  ).a;
@@ -4384,14 +4497,14 @@ var createSvgObjectsForSchNetLabel = ({
4384
4497
  const fontSizePx = getSchScreenFontSize(realToScreenTransform, "net_label");
4385
4498
  const fontSizeMm = getSchMmFontSize("net_label");
4386
4499
  const textWidthFSR = estimateTextWidth(schNetLabel.text || "");
4387
- const screenCenter = applyToPoint35(realToScreenTransform, schNetLabel.center);
4500
+ const screenCenter = applyToPoint36(realToScreenTransform, schNetLabel.center);
4388
4501
  const realTextGrowthVec = getUnitVectorFromOutsideToEdge(
4389
4502
  schNetLabel.anchor_side
4390
4503
  );
4391
4504
  const screenTextGrowthVec = { ...realTextGrowthVec };
4392
4505
  screenTextGrowthVec.y *= -1;
4393
4506
  const fullWidthFsr = textWidthFSR + ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + END_PADDING_FSR;
4394
- const screenAnchorPosition = schNetLabel.anchor_position ? applyToPoint35(realToScreenTransform, schNetLabel.anchor_position) : {
4507
+ const screenAnchorPosition = schNetLabel.anchor_position ? applyToPoint36(realToScreenTransform, schNetLabel.anchor_position) : {
4395
4508
  x: screenCenter.x - screenTextGrowthVec.x * fullWidthFsr * fontSizePx / 2,
4396
4509
  y: screenCenter.y - screenTextGrowthVec.y * fullWidthFsr * fontSizePx / 2
4397
4510
  };
@@ -4432,12 +4545,12 @@ var createSvgObjectsForSchNetLabel = ({
4432
4545
  y: -0.6
4433
4546
  }
4434
4547
  ].map(
4435
- (fontRelativePoint) => applyToPoint35(
4436
- compose8(
4548
+ (fontRelativePoint) => applyToPoint36(
4549
+ compose9(
4437
4550
  realToScreenTransform,
4438
- translate8(realAnchorPosition.x, realAnchorPosition.y),
4551
+ translate9(realAnchorPosition.x, realAnchorPosition.y),
4439
4552
  scale6(fontSizeMm),
4440
- rotate4(pathRotation / 180 * Math.PI)
4553
+ rotate5(pathRotation / 180 * Math.PI)
4441
4554
  ),
4442
4555
  fontRelativePoint
4443
4556
  )
@@ -4700,16 +4813,16 @@ var circuitJsonToSchematicSvg = convertCircuitJsonToSchematicSvg;
4700
4813
  // lib/pcb/convert-circuit-json-to-solder-paste-mask.ts
4701
4814
  import { stringify as stringify4 } from "svgson";
4702
4815
  import {
4703
- applyToPoint as applyToPoint38,
4704
- compose as compose10,
4816
+ applyToPoint as applyToPoint39,
4817
+ compose as compose11,
4705
4818
  scale as scale8,
4706
- translate as translate10
4819
+ translate as translate11
4707
4820
  } from "transformation-matrix";
4708
4821
 
4709
4822
  // lib/pcb/svg-object-fns/convert-circuit-json-to-solder-paste-mask.ts
4710
- import { applyToPoint as applyToPoint37 } from "transformation-matrix";
4823
+ import { applyToPoint as applyToPoint38 } from "transformation-matrix";
4711
4824
  function createSvgObjectsFromSolderPaste(solderPaste, transform) {
4712
- const [x, y] = applyToPoint37(transform, [solderPaste.x, solderPaste.y]);
4825
+ const [x, y] = applyToPoint38(transform, [solderPaste.x, solderPaste.y]);
4713
4826
  if (solderPaste.shape === "rect" || solderPaste.shape === "rotated_rect") {
4714
4827
  const width = solderPaste.width * Math.abs(transform.a);
4715
4828
  const height = solderPaste.height * Math.abs(transform.d);
@@ -4817,8 +4930,8 @@ function convertCircuitJsonToSolderPasteMask(soup, options) {
4817
4930
  const scaleFactor = Math.min(scaleX, scaleY);
4818
4931
  const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2;
4819
4932
  const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2;
4820
- const transform = compose10(
4821
- translate10(
4933
+ const transform = compose11(
4934
+ translate11(
4822
4935
  offsetX - minX * scaleFactor + padding * scaleFactor,
4823
4936
  svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
4824
4937
  ),
@@ -4898,8 +5011,8 @@ function createSvgObjects3(elm, transform) {
4898
5011
  }
4899
5012
  }
4900
5013
  function createSvgObjectFromPcbBoundary2(transform, minX, minY, maxX, maxY) {
4901
- const [x1, y1] = applyToPoint38(transform, [minX, minY]);
4902
- const [x2, y2] = applyToPoint38(transform, [maxX, maxY]);
5014
+ const [x1, y1] = applyToPoint39(transform, [minX, minY]);
5015
+ const [x2, y2] = applyToPoint39(transform, [maxX, maxY]);
4903
5016
  const width = Math.abs(x2 - x1);
4904
5017
  const height = Math.abs(y2 - y1);
4905
5018
  const x = Math.min(x1, x2);